diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f1dbf744dc4..081d0136be9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,16 +4,20 @@ updates: - package-ecosystem: "npm" directory: "/website" schedule: - interval: "daily" + interval: "weekly" commit-message: prefix: "chore" - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" + interval: "weekly" commit-message: prefix: "chore" + groups: + all: + patterns: + - "*" - package-ecosystem: "gomod" directory: "/" @@ -26,3 +30,36 @@ updates: update-types: - "version-update:semver-major" - "version-update:semver-minor" + groups: + k8s: + patterns: + - "k8s.io/*" + - "sigs.k8s.io/*" + + - package-ecosystem: "docker" + directory: / + schedule: + interval: "weekly" + commit-message: + prefix: "chore" + + - package-ecosystem: "docker" + directory: "/build/tooling" + schedule: + interval: "weekly" + commit-message: + prefix: "chore" + + - package-ecosystem: "docker" + directory: "/test/externaldata/dummy-provider" + schedule: + interval: "weekly" + commit-message: + prefix: "chore" + + - package-ecosystem: "docker" + directory: "/test/image" + schedule: + interval: "weekly" + commit-message: + prefix: "chore" diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 8b9fcbd76aa..40203bff4ce 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -3,47 +3,47 @@ on: issue_comment: types: [created] -jobs: +permissions: + contents: read + +jobs: benchmark: name: "Benchmark" if: github.event.issue.pull_request && github.event.comment.body == '/benchmark' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 60 permissions: contents: write pull-requests: write steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - uses: izhangzhihao/delete-comment@98aa1ea5c6304048edf951c20b3114e03c785c79 - with: + with: github_token: ${{ secrets.GITHUB_TOKEN }} delete_user_name: github-actions[bot] issue_number: ${{ github.event.issue.number }} - - name: install kubebuilder - run: | - curl -L -O "https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${KUBEBUILDER_VERSION}/kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64.tar.gz" &&\ - tar -zxvf kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64.tar.gz &&\ - sudo mv kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64 /usr/local/kubebuilder - env: - KUBEBUILDER_VERSION: 2.3.1 - - name: Update status - uses: peter-evans/create-or-update-comment@v2 + uses: peter-evans/create-or-update-comment@c6c9a1a66007646a28c153e2a8580a5bad27bcfa # v3.0.2 with: issue-number: ${{ github.event.issue.number }} body: | [Running benchmark here...](${{ github.server.url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - name: Check out base code into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3.5.2 with: ref: ${{ github.base_ref }} - name: Run benchmarks on base ref run: make benchmark-test BENCHMARK_FILE_NAME="../base_benchmarks.txt" - + - name: Check out code into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3.5.2 - name: Run benchmark with incoming changes run: make benchmark-test BENCHMARK_FILE_NAME="pr_benchmarks.txt" @@ -61,11 +61,11 @@ jobs: echo '$delimiter' >> $GITHUB_OUTPUT - name: Create commit comment - uses: peter-evans/create-or-update-comment@v2 + uses: peter-evans/create-or-update-comment@c6c9a1a66007646a28c153e2a8580a5bad27bcfa # v3.0.2 with: issue-number: ${{ github.event.issue.number }} body: | This PR compares its performance to the latest released version. If it performs significantly lower, consider optimizing your changes to improve the performance. - ``` + ``` ${{ steps.get-comment-body.outputs.msg }} ``` diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 8d56a47bed3..4b410e173dd 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -11,21 +11,26 @@ permissions: read-all jobs: analyze: name: Analyze - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 permissions: security-events: write steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Checkout repository - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Initialize CodeQL - uses: github/codeql-action/init@a34ca99b4610d924e04c68db79e503e1f79f9f02 + uses: github/codeql-action/init@fdcae64e1484d349b3366718cdfef3d404390e85 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@a34ca99b4610d924e04c68db79e503e1f79f9f02 + uses: github/codeql-action/autobuild@fdcae64e1484d349b3366718cdfef3d404390e85 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a34ca99b4610d924e04c68db79e503e1f79f9f02 + uses: github/codeql-action/analyze@fdcae64e1484d349b3366718cdfef3d404390e85 diff --git a/.github/workflows/dapr-pubsub.yaml b/.github/workflows/dapr-pubsub.yaml new file mode 100644 index 00000000000..5f74ffd9cb7 --- /dev/null +++ b/.github/workflows/dapr-pubsub.yaml @@ -0,0 +1,64 @@ +name: dapr-pubsub +on: + push: + paths: + - "pkg/pubsub/dapr" + - "test/pubsub/**" + pull_request: + paths: + - "pkg/pubsub/dapr" + - "test/pubsub/**" +permissions: read-all + +jobs: + dapr_test: + name: "Dapr pubsub test" + runs-on: ubuntu-22.04 + timeout-minutes: 15 + strategy: + matrix: + DAPR_VERSION: ["1.10"] + steps: + - name: Check out code into the Go module directory + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + + - name: Bootstrap e2e + run: | + mkdir -p $GITHUB_WORKSPACE/bin + mkdir .tmp + echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH + make e2e-bootstrap + make e2e-helm-install + helm repo add dapr https://dapr.github.io/helm-charts/ + helm repo add bitnami https://charts.bitnami.com/bitnami + helm repo update + helm upgrade --install dapr dapr/dapr --version=${{ matrix.DAPR_VERSION }} --namespace dapr-system --create-namespace --wait --debug + helm upgrade --install redis bitnami/redis --namespace default --set image.tag=7.0-debian-11 --wait --debug + make e2e-subscriber-build-load-image + make e2e-subscriber-deploy + + - name: Run e2e + run: | + make docker-buildx IMG=gatekeeper-e2e:latest + make e2e-build-load-externaldata-image + make docker-buildx-crds CRD_IMG=gatekeeper-crds:latest + kind load docker-image --name kind gatekeeper-e2e:latest gatekeeper-crds:latest + kubectl create ns gatekeeper-system + make e2e-publisher-deploy + make e2e-helm-deploy HELM_REPO=gatekeeper-e2e HELM_CRD_REPO=gatekeeper-crds HELM_RELEASE=latest ENABLE_PUBSUB=true + make test-e2e ENABLE_PUBSUB_TESTS=1 + + - name: Save logs + if: ${{ always() }} + run: | + kubectl logs -n fake-subscriber -l app=sub --tail=-1 > logs-audit-subscribe.json + kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=-1 > logs-audit-publish.json + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + if: ${{ always() }} + with: + name: pubsub-logs + path: | + logs-*.json + diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000000..48a9079fa9b --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,27 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, +# PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: 'Checkout Repository' + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3.5.2 + - name: 'Dependency Review' + uses: actions/dependency-review-action@6c5ccdad469c9f8a2996bfecaec55a631a347034 # v3.1.0 diff --git a/.github/workflows/license-lint.yaml b/.github/workflows/license-lint.yaml new file mode 100644 index 00000000000..5a9dcd8b463 --- /dev/null +++ b/.github/workflows/license-lint.yaml @@ -0,0 +1,42 @@ +name: license-lint +on: + push: + paths: + - "go.mod" + - "go.sum" + - "vendor/**" + pull_request: + paths: + - "go.mod" + - "go.sum" + - "vendor/**" + +permissions: + contents: read + +jobs: + license-lint: + name: "license-lint" + runs-on: ubuntu-22.04 + timeout-minutes: 5 + permissions: + contents: read + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 + with: + go-version: "1.21" + + - name: Check out code into the Go module directory + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3.5.2 + + - name: license-lint + run: | + export GOPATH="$HOME/go" + PATH="$GOPATH/bin:$PATH" + ./third_party/k8s.io/kubernetes/hack/verify-licenses.sh diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml new file mode 100644 index 00000000000..3b6852fc171 --- /dev/null +++ b/.github/workflows/pre-release.yaml @@ -0,0 +1,73 @@ +name: pre-release +on: + push: + branches: + - master + +permissions: read-all + +env: + IMAGE_REPO: openpolicyagent/gatekeeper + CRD_IMAGE_REPO: openpolicyagent/gatekeeper-crds + GATOR_IMAGE_REPO: openpolicyagent/gator + +jobs: + pre-release: + name: "Pre Release" + runs-on: "ubuntu-22.04" + if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'open-policy-agent/gatekeeper' + timeout-minutes: 30 + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Check out code into the Go module directory + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + + - name: Publish development + run: | + make docker-login + + tokenUri="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${{ env.IMAGE_REPO }}:pull&scope=repository:${{ env.CRD_IMAGE_REPO }}:pull&scope=repository:${{ env.GATOR_IMAGE_REPO }}:pull" + bearerToken="$(curl --silent --get $tokenUri | jq --raw-output '.token')" + listUri="https://registry-1.docker.io/v2/${{ env.IMAGE_REPO }}/tags/list" + authz="Authorization: Bearer $bearerToken" + version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-dev \ + DEV_TAG=${GITHUB_SHA::7} \ + PLATFORM="linux/amd64,linux/arm64,linux/arm/v7" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + + listUri="https://registry-1.docker.io/v2/${{ env.CRD_IMAGE_REPO }}/tags/list" + version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-crds-dev \ + DEV_TAG=${GITHUB_SHA::7} \ + PLATFORM="linux/amd64,linux/arm64" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + + listUri="https://registry-1.docker.io/v2/${{ env.GATOR_IMAGE_REPO }}/tags/list" + version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-gator-dev \ + DEV_TAG=${GITHUB_SHA::7} \ + PLATFORM="linux/amd64,linux/arm64,linux/arm/v7" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + env: + DOCKER_USER: ${{ secrets.DOCKER_USER }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/release-pr.yaml b/.github/workflows/release-pr.yaml index c9dc9b577a0..6024bff084b 100644 --- a/.github/workflows/release-pr.yaml +++ b/.github/workflows/release-pr.yaml @@ -15,12 +15,17 @@ permissions: jobs: create-release-pull-request: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: - go-version: 1.19 + egress-policy: audit + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 + with: + go-version: "1.21" - name: Set release version and target branch for vNext if: github.event_name == 'push' @@ -54,7 +59,7 @@ jobs: echo "TARGET_BRANCH=master" >> ${GITHUB_ENV} fi - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 with: fetch-depth: 0 @@ -72,7 +77,7 @@ jobs: run: make version-docs NEWVERSION=v${MAJOR_VERSION}.${MINOR_VERSION}.x - name: Create release pull request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2 with: commit-message: "chore: Prepare ${{ env.NEWVERSION }} release" title: "chore: Prepare ${{ env.NEWVERSION }} release" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000000..ff777f95381 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,157 @@ +name: release +on: + push: + tags: + - 'v*' + +env: + IMAGE_REPO: openpolicyagent/gatekeeper + CRD_IMAGE_REPO: openpolicyagent/gatekeeper-crds + GATOR_IMAGE_REPO: openpolicyagent/gator + +permissions: + contents: read + +jobs: + tagged-release: + name: "Tagged Release" + runs-on: "ubuntu-22.04" + permissions: + contents: write + if: startsWith(github.ref, 'refs/tags/v') && github.repository == 'open-policy-agent/gatekeeper' + timeout-minutes: 45 + steps: + - name: Cleanup disk + run: | + # Filter out local helm-gh-pages image so we don't delete it + docker system prune -a -f --filter "label!=org.opencontainers.image.source=https://github.com/stefanprodan/alpine-base" + + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Check out code into the Go module directory + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 + with: + go-version: "1.21" + + - name: Get tag + id: get_version + run: | + echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + + - name: Publish release + run: | + make docker-login + + tokenUri="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${{ env.IMAGE_REPO }}:pull&scope=repository:${{ env.CRD_IMAGE_REPO }}:pull&scope=repository:${{ env.GATOR_IMAGE_REPO }}:pull" + bearerToken="$(curl --silent --get $tokenUri | jq --raw-output '.token')" + listUri="https://registry-1.docker.io/v2/${{ env.IMAGE_REPO }}/tags/list" + authz="Authorization: Bearer $bearerToken" + version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-release \ + VERSION=${TAG} \ + PLATFORM="linux/amd64,linux/arm64,linux/arm/v7" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + + listUri="https://registry-1.docker.io/v2/${{ env.CRD_IMAGE_REPO }}/tags/list" + version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-crds-release \ + VERSION=${TAG} \ + PLATFORM="linux/amd64,linux/arm64" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + + listUri="https://registry-1.docker.io/v2/${{ env.GATOR_IMAGE_REPO }}/tags/list" + version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" + exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') + if [[ $exists == null ]] + then + make docker-buildx-gator-release \ + VERSION=${TAG} \ + PLATFORM="linux/amd64,linux/arm64,linux/arm/v7" \ + OUTPUT_TYPE=type=registry \ + GENERATE_ATTESTATIONS=true + fi + env: + DOCKER_USER: ${{ secrets.DOCKER_USER }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + + - name: Bootstrap e2e + run: | + mkdir -p $GITHUB_WORKSPACE/bin + echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH + make e2e-bootstrap + + - name: Verify release + run: | + make e2e-verify-release IMG=${{ env.IMAGE_REPO }}:${TAG} USE_LOCAL_IMG=false + + - name: Build gator-cli + shell: bash + run: | + set -e + build() { + export GOOS="$(echo ${1} | cut -d '-' -f 1)" + export GOARCH="$(echo ${1} | cut -d '-' -f 2)" + FILENAME=${GITHUB_WORKSPACE}/_dist/gator-${TAG}-${GOOS}-${GOARCH} + # build the binary + make bin/gator-${GOOS}-${GOARCH} + # rename the binary to gator + tmp_dir=$(mktemp -d) + cp bin/gator-${GOOS}-${GOARCH} ${tmp_dir}/gator + pushd ${tmp_dir} + tar -czf ${FILENAME}.tar.gz gator* + popd + } + + mkdir -p _dist + + i=0 + for os_arch_extension in $PLATFORMS; do + build ${os_arch_extension} & + pids[${i}]=$! + ((i=i+1)) + done + + # wait for all pids + for pid in ${pids[*]}; do + wait $pid + done + + pushd _dist + # consolidate tar's sha256sum into a single file + find . -type f -name '*.tar.gz' | sort | xargs sha256sum >> sha256sums.txt + popd + env: + PLATFORMS: "linux-amd64 linux-arm64 darwin-amd64 darwin-arm64" + + - name: Create GitHub release + uses: marvinpinto/action-automatic-releases@919008cf3f741b179569b7a6fb4d8860689ab7f0 # v1.2.1 + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: false + files: | + _dist/sha256sums.txt + _dist/*.tar.gz + + - name: Publish Helm chart + uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + charts_dir: charts + target_dir: charts + linting: off diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 00000000000..303791cfb9e --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,76 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '20 7 * * 2' + push: + branches: ["master"] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + contents: read + actions: read + + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: "Checkout code" + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v3.5.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecards on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1 + with: + sarif_file: results.sarif diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml index cb34c4657e0..1e0f5bcbbca 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/upgrade.yaml @@ -18,14 +18,19 @@ env: jobs: helm_upgrade: name: "[Helm] Upgrade test" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 15 strategy: matrix: HELM_VERSION: ["3.7.2"] steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Bootstrap e2e run: | @@ -61,12 +66,26 @@ jobs: - name: Upgrade Helm version run: | - make e2e-build-load-image IMG=gatekeeper-e2e-helm:latest CRD_IMG=gatekeeper-crds:latest - make e2e-helm-upgrade HELM_VERSION=${{ matrix.HELM_VERSION }} HELM_REPO=gatekeeper-e2e-helm HELM_CRD_REPO=gatekeeper-crds HELM_RELEASE=latest + make docker-buildx \ + IMG=gatekeeper-e2e:latest \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} - - name: Manually apply the CRDs. Helm will not update CRDs. - run: | - kustomize build config/crd | kubectl apply -f - + make docker-buildx-crds \ + CRD_IMG=gatekeeper-crds:latest \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + make e2e-build-load-externaldata-image \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + kind load docker-image --name kind \ + gatekeeper-e2e:latest \ + gatekeeper-crds:latest + + make e2e-helm-upgrade \ + HELM_VERSION=${{ matrix.HELM_VERSION }} \ + HELM_REPO=gatekeeper-e2e \ + HELM_CRD_REPO=gatekeeper-crds \ + HELM_RELEASE=latest - name: Run e2e after upgrade run: | @@ -80,7 +99,7 @@ jobs: kubectl logs -n gatekeeper-system -l run=dummy-provider --tail=-1 > logs-${{ matrix.HELM_VERSION }}-dummy-provider-post-upgrade.json - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: ${{ always() }} with: name: logs diff --git a/.github/workflows/website.yaml b/.github/workflows/website.yaml index d9d0d8e996b..90b8f5d7b45 100644 --- a/.github/workflows/website.yaml +++ b/.github/workflows/website.yaml @@ -7,21 +7,32 @@ on: paths: - ".github/workflows/website.yaml" - "website/**" + pull_request: + branches: + - master + paths: + - ".github/workflows/website.yaml" + - "website/**" permissions: contents: write jobs: deploy: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 defaults: run: working-directory: website steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1 with: node-version: "16" @@ -30,7 +41,7 @@ jobs: run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ${{ steps.yarn-cache.outputs.dir }} key: ${{ runner.os }}-website-${{ hashFiles('**/yarn.lock') }} @@ -40,8 +51,10 @@ jobs: - run: yarn install --frozen-lockfile - run: yarn build + # deploy only after PR is merged to master - name: Deploy - uses: peaceiris/actions-gh-pages@v3.9.2 + if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'open-policy-agent/gatekeeper' + uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./website/build diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index b0e6ddacd9a..31981dcb799 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -1,4 +1,4 @@ -name: build_test_release +name: build_test on: push: paths-ignore: @@ -23,80 +23,103 @@ on: - "**.md" - "!cmd/build/helmify/static/README.md" -env: - GITHUB_REPO: open-policy-agent/gatekeeper - IMAGE_REPO: openpolicyagent/gatekeeper - CRD_IMAGE_REPO: openpolicyagent/gatekeeper-crds - GATOR_IMAGE_REPO: openpolicyagent/gator +permissions: read-all jobs: lint: name: "Lint" - runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - contents: read + runs-on: ubuntu-22.04 + timeout-minutes: 7 steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 with: - go-version: 1.19 + go-version: "1.21" - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # source: https://github.com/golangci/golangci-lint-action - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 with: # version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.48.0 + version: v1.51.2 test: name: "Unit test" - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read + runs-on: ubuntu-22.04 + timeout-minutes: 20 steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 with: - go-version: 1.19 + go-version: "1.21" - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Unit test - run: | - curl -L -O "https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${KUBEBUILDER_VERSION}/kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64.tar.gz" &&\ - tar -zxvf kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64.tar.gz &&\ - sudo mv kubebuilder_${KUBEBUILDER_VERSION}_linux_amd64 /usr/local/kubebuilder - make native-test - env: - KUBEBUILDER_VERSION: 2.3.1 + run: make native-test - name: Codecov Upload - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 with: flags: unittests file: ./cover.out fail_ci_if_error: false + check_manifest: + name: "Check codegen and manifest" + runs-on: ubuntu-22.04 + timeout-minutes: 10 + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + + - name: Check out code into the Go module directory + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.2 + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 + with: + go-version: "1.21" + - name: Check go.mod and manifests + run: | + # there should be no additional manifest or go.mod changes + go mod tidy + git diff --exit-code + make generate manifests + git diff --exit-code + gator_test: name: "Test Gator" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 5 - permissions: - contents: read steps: - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: - go-version: 1.19 + egress-policy: audit + + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 + with: + go-version: "1.21" - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Download e2e dependencies run: | @@ -109,21 +132,24 @@ jobs: build_test: name: "Build and Test" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 15 - permissions: - contents: read strategy: matrix: - KUBERNETES_VERSION: ["1.23.13", "1.24.7", "1.25.3", "1.26.0"] + KUBERNETES_VERSION: ["1.25.8", "1.26.3", "1.27.1", "1.28.0"] steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 with: - go-version: 1.19 + go-version: "1.21" - name: Bootstrap e2e run: | @@ -133,11 +159,18 @@ jobs: - name: Run e2e run: | - make e2e-build-load-image IMG=gatekeeper-e2e:latest CRD_IMG=gatekeeper-crds:latest - make deploy IMG=gatekeeper-e2e:latest USE_LOCAL_IMG=true - go mod tidy - # there should be no additional manifest or go.mod changes - git diff --exit-code + make docker-buildx \ + IMG=gatekeeper-e2e:latest + + make e2e-build-load-externaldata-image + + kind load docker-image --name kind \ + gatekeeper-e2e:latest + + make deploy \ + IMG=gatekeeper-e2e:latest \ + USE_LOCAL_IMG=true + make test-e2e - name: Save logs @@ -147,7 +180,7 @@ jobs: kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=-1 > logs-audit.json - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: ${{ always() }} with: name: logs @@ -156,17 +189,20 @@ jobs: helm_build_test: name: "[Helm] Build and Test" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 15 - permissions: - contents: read strategy: matrix: HELM_VERSION: ["3.7.2"] GATEKEEPER_NAMESPACE: ["gatekeeper-system", "custom-namespace"] steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Bootstrap e2e run: | @@ -176,9 +212,30 @@ jobs: - name: Run e2e run: | - make e2e-build-load-image IMG=gatekeeper-e2e-helm:latest CRD_IMG=gatekeeper-crds:latest GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} - make e2e-helm-deploy HELM_REPO=gatekeeper-e2e-helm HELM_CRD_REPO=gatekeeper-crds HELM_RELEASE=latest HELM_VERSION=${{ matrix.HELM_VERSION }} GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} - make test-e2e GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + make docker-buildx \ + IMG=gatekeeper-e2e:latest \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + make docker-buildx-crds \ + CRD_IMG=gatekeeper-crds:latest \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + make e2e-build-load-externaldata-image \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + kind load docker-image --name kind \ + gatekeeper-e2e:latest \ + gatekeeper-crds:latest + + make e2e-helm-deploy \ + HELM_REPO=gatekeeper-e2e \ + HELM_CRD_REPO=gatekeeper-crds \ + HELM_RELEASE=latest \ + HELM_VERSION=${{ matrix.HELM_VERSION }} \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} + + make test-e2e \ + GATEKEEPER_NAMESPACE=${{ matrix.GATEKEEPER_NAMESPACE }} - name: Save logs if: ${{ always() }} @@ -188,7 +245,7 @@ jobs: kubectl logs -n ${{ matrix.GATEKEEPER_NAMESPACE }} -l run=dummy-provider --tail=-1 > logs-helm-${{ matrix.HELM_VERSION }}-${{ matrix.GATEKEEPER_NAMESPACE }}-dummy-provider.json - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: ${{ always() }} with: name: helm-logs @@ -197,18 +254,22 @@ jobs: build_test_generator_expansion: name: "[Generator Resource Expansion] Build and Test" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 15 - permissions: - contents: read + steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - name: Set up Go 1.19 - uses: actions/setup-go@v3 + - name: Set up Go + uses: actions/setup-go@v4 # v4.0.1 with: - go-version: 1.19 + go-version: "1.21" - name: Bootstrap e2e run: | @@ -218,11 +279,19 @@ jobs: - name: Run e2e run: | - make e2e-build-load-image IMG=gatekeeper-e2e:latest CRD_IMG=gatekeeper-crds:latest - make deploy IMG=gatekeeper-e2e:latest USE_LOCAL_IMG=true ENABLE_GENERATOR_EXPANSION=true - go mod tidy - # there should be no additional manifest or go.mod changes - git diff --exit-code + make docker-buildx \ + IMG=gatekeeper-e2e:latest + + make e2e-build-load-externaldata-image + + kind load docker-image --name kind \ + gatekeeper-e2e:latest + + make deploy \ + IMG=gatekeeper-e2e:latest \ + USE_LOCAL_IMG=true \ + ENABLE_GENERATOR_EXPANSION=true + make test-e2e ENABLE_GENERATOR_EXPANSION_TESTS=1 - name: Save logs @@ -232,7 +301,7 @@ jobs: kubectl logs -n gatekeeper-system -l control-plane=audit-controller --tail=-1 > logs-generatorexpansion-audit.json - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: ${{ always() }} with: name: generatorexpansion-logs @@ -241,13 +310,16 @@ jobs: scan_vulnerabilities: name: "[Trivy] Scan for vulnerabilities" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 15 - permissions: - contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + with: + egress-policy: audit + - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Download trivy run: | @@ -256,177 +328,22 @@ jobs: tar zxvf trivy_${{ env.TRIVY_VERSION }}_Linux-64bit.tar.gz echo "$(pwd)" >> $GITHUB_PATH env: - TRIVY_VERSION: "0.32.1" + TRIVY_VERSION: "0.41.0" - name: Run trivy on git repository run: | - trivy fs --format table --ignore-unfixed --skip-dirs website --security-checks vuln . + trivy fs --format table --ignore-unfixed --skip-dirs website --scanners vuln . - name: Build docker images - run: make docker-build - - - name: Run trivy on images - run: | - for img in "openpolicyagent/gatekeeper:latest" "openpolicyagent/gatekeeper-crds:latest"; do - for vuln_type in "os" "library"; do - trivy image --ignore-unfixed --vuln-type="${vuln_type}" "${img}" - done - done - - pre-release: - name: "Pre Release" - runs-on: "ubuntu-latest" - if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'open-policy-agent/gatekeeper' - needs: [lint, test, build_test, helm_build_test, scan_vulnerabilities] - timeout-minutes: 30 - permissions: - contents: read - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - - name: make docker-push-dev - run: | - tokenUri="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${{ env.IMAGE_REPO }}:pull&scope=repository:${{ env.CRD_IMAGE_REPO }}:pull&scope=repository:${{ env.GATOR_IMAGE_REPO }}:pull" - bearerToken="$(curl --silent --get $tokenUri | jq --raw-output '.token')" - listUri="https://registry-1.docker.io/v2/${{ env.IMAGE_REPO }}/tags/list" - authz="Authorization: Bearer $bearerToken" - version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-dev DEV_TAG=${GITHUB_SHA::7} - fi - - listUri="https://registry-1.docker.io/v2/${{ env.CRD_IMAGE_REPO }}/tags/list" - version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-crds-dev DEV_TAG=${GITHUB_SHA::7} - fi - - listUri="https://registry-1.docker.io/v2/${{ env.GATOR_IMAGE_REPO }}/tags/list" - version_list="$(curl --silent --get -H "Accept: application/json" -H "$authz" $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${GITHUB_SHA::7} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-gator-dev DEV_TAG=${GITHUB_SHA::7} - fi - env: - DOCKER_USER: ${{ secrets.DOCKER_USER }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - tagged-release: - name: "Tagged Release" - runs-on: "ubuntu-latest" - permissions: - contents: write - if: startsWith(github.ref, 'refs/tags/v') && github.repository == 'open-policy-agent/gatekeeper' - needs: [lint, test, build_test, helm_build_test, scan_vulnerabilities] - timeout-minutes: 45 - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - - name: Set up Go 1.19 - uses: actions/setup-go@v3 - with: - go-version: 1.19 - - - name: Get tag - id: get_version run: | - echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + make docker-buildx \ + IMG=gatekeeper-e2e:latest - - name: Publish release - run: | - tokenUri="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${{ env.IMAGE_REPO }}:pull&scope=repository:${{ env.CRD_IMAGE_REPO }}:pull&scope=repository:${{ env.GATOR_IMAGE_REPO }}:pull" - bearerToken="$(curl --silent --get $tokenUri | jq --raw-output '.token')" - listUri="https://registry-1.docker.io/v2/${{ env.IMAGE_REPO }}/tags/list" - authz="Authorization: Bearer $bearerToken" - version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-release VERSION=${TAG} - fi - - listUri="https://registry-1.docker.io/v2/${{ env.CRD_IMAGE_REPO }}/tags/list" - version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-crds-release VERSION=${TAG} - fi - - listUri="https://registry-1.docker.io/v2/${{ env.GATOR_IMAGE_REPO }}/tags/list" - version_list="$(curl --silent --get -H "Accept: application/json" -H $authz $listUri | jq --raw-output '.')" - exists=$(echo $version_list | jq --arg t ${TAG} '.tags | index($t)') - if [[ $exists == null ]] - then - make docker-login - make docker-buildx-gator-release VERSION=${TAG} - fi - env: - DOCKER_USER: ${{ secrets.DOCKER_USER }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + make docker-buildx-crds \ + CRD_IMG=gatekeeper-crds:latest - - name: Bootstrap e2e - run: | - mkdir -p $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - make e2e-bootstrap - - - name: Verify release - run: | - make e2e-verify-release IMG=${{ env.IMAGE_REPO }}:${TAG} USE_LOCAL_IMG=false - - - name: Build gator-cli + - name: Run trivy on images run: | - build() { - export GOOS="$(echo ${1} | cut -d '-' -f 1)" - export GOARCH="$(echo ${1} | cut -d '-' -f 2)" - FILENAME=${GITHUB_WORKSPACE}/_dist/gator-${TAG}-${GOOS}-${GOARCH} - # build the binary - make bin/gator-${GOOS}-${GOARCH} - # rename the binary to gator - tmp_dir=$(mktemp -d) - cp bin/gator-${GOOS}-${GOARCH} ${tmp_dir}/gator - pushd ${tmp_dir} - tar -czf ${FILENAME}.tar.gz gator* - popd - } - mkdir -p _dist - for os_arch_extension in $PLATFORMS; do - build ${os_arch_extension} & + for img in "gatekeeper-e2e:latest" "gatekeeper-crds:latest"; do + trivy image --ignore-unfixed --vuln-type="os,library" "${img}" done - wait - pushd _dist - # consolidate tar's sha256sum into a single file - find . -type f -name '*.tar.gz' | sort | xargs sha256sum >> sha256sums.txt - popd - env: - PLATFORMS: "linux-amd64 linux-arm64 darwin-amd64 darwin-arm64" - - - name: Create GitHub release - uses: "marvinpinto/action-automatic-releases@v1.2.1" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - prerelease: false - files: | - _dist/sha256sums.txt - _dist/*.tar.gz - - - name: Publish Helm chart - uses: stefanprodan/helm-gh-pages@v1.7.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - charts_dir: charts - target_dir: charts - linting: off diff --git a/.gitignore b/.gitignore index 128e3756cde..329c0880ded 100644 --- a/.gitignore +++ b/.gitignore @@ -362,3 +362,6 @@ tilt-settings.json # dummy provider's certificate directory test/externaldata/dummy-provider/certs/ + +# annotations for dapr +annotations.yaml diff --git a/.go-version b/.go-version index 815d5ca06d5..3500250a4b0 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.19.0 +1.21.0 diff --git a/.golangci.yaml b/.golangci.yaml index c25c0889316..45f97871159 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,5 +1,7 @@ run: timeout: 5m + skip-files: + - pkg/target/matchcrd_constant.go linters-settings: gocritic: @@ -20,15 +22,16 @@ linters-settings: locale: US staticcheck: # Select the Go version to target. The default is '1.13'. - go: "1.19" + go: "1.21" linters: disable-all: true enable: - - deadcode - errcheck + - errorlint - exportloopref - forcetypeassert + - gci - gocritic - goconst - godot @@ -43,8 +46,7 @@ linters: - misspell - revive # replacement for golint - staticcheck - - structcheck - typecheck + - unconvert - unused - - varcheck - whitespace diff --git a/.trivyignore b/.trivyignore new file mode 100644 index 00000000000..b583a1d2c18 --- /dev/null +++ b/.trivyignore @@ -0,0 +1,3 @@ +# false positive due to prometheus versioning +# https://github.com/aquasecurity/trivy/issues/2992 +CVE-2019-3826 diff --git a/Dockerfile b/Dockerfile index 442ab2c731e..0e26d65ff5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG BUILDPLATFORM="linux/amd64" -ARG BUILDERIMAGE="golang:1.19-bullseye" +ARG BUILDERIMAGE="golang:1.21-bullseye" # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details ARG BASEIMAGE="gcr.io/distroless/static:nonroot" @@ -11,30 +11,22 @@ ARG TARGETOS ARG TARGETARCH ARG TARGETVARIANT="" ARG LDFLAGS +ARG BUILDKIT_SBOM_SCAN_STAGE=true ENV GO111MODULE=on \ - CGO_ENABLED=0 \ + CGO_ENABLED=1 \ GOOS=${TARGETOS} \ GOARCH=${TARGETARCH} \ GOARM=${TARGETVARIANT} WORKDIR /go/src/github.com/open-policy-agent/gatekeeper +COPY . . -COPY pkg/ pkg/ -COPY third_party/ third_party/ -COPY vendor/ vendor/ -COPY main.go main.go -COPY apis/ apis/ -COPY go.mod . - -RUN go build -mod vendor -a -ldflags "${LDFLAGS:--X github.com/open-policy-agent/gatekeeper/pkg/version.Version=latest}" -o manager main.go +RUN go build -mod vendor -a -ldflags "${LDFLAGS}" -o manager FROM $BASEIMAGE WORKDIR / - COPY --from=builder /go/src/github.com/open-policy-agent/gatekeeper/manager . - USER 65532:65532 - ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index ca2010e7f7d..5062b80c201 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,15 @@ GATOR_IMG := $(GATOR_REPOSITORY):latest DEV_TAG ?= dev USE_LOCAL_IMG ?= false ENABLE_GENERATOR_EXPANSION ?= false +ENABLE_PUBSUB ?= false +AUDIT_CONNECTION ?= "audit" +AUDIT_CHANNEL ?= "audit" -VERSION := v3.12.0-beta.0 +VERSION := v3.14.0 KIND_VERSION ?= 0.17.0 # note: k8s version pinned since KIND image availability lags k8s releases -KUBERNETES_VERSION ?= 1.26.0 -KUBEBUILDER_VERSION ?= 3.8.0 +KUBERNETES_VERSION ?= 1.28.0 KUSTOMIZE_VERSION ?= 3.8.9 BATS_VERSION ?= 1.8.2 ORAS_VERSION ?= 0.16.0 @@ -23,34 +25,27 @@ BATS_TESTS_FILE ?= test/bats/test.bats HELM_VERSION ?= 3.7.2 NODE_VERSION ?= 16-bullseye-slim YQ_VERSION ?= 4.30.6 -FRAMEWORKS_VERSION ?= $(shell go list -f '{{ .Version }}' -m github.com/open-policy-agent/frameworks/constraint) -OPA_VERSION ?= $(shell go list -f '{{ .Version }}' -m github.com/open-policy-agent/opa) HELM_ARGS ?= GATEKEEPER_NAMESPACE ?= gatekeeper-system # When updating this, make sure to update the corresponding action in # workflow.yaml -GOLANGCI_LINT_VERSION := v1.45.2 +GOLANGCI_LINT_VERSION := v1.51.2 # Detects the location of the user golangci-lint cache. GOLANGCI_LINT_CACHE := $(shell pwd)/.tmp/golangci-lint BENCHMARK_FILE_NAME ?= benchmarks.txt +FAKE_SUBSCRIBER_IMAGE ?= fake-subscriber:latest ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) BIN_DIR := $(abspath $(ROOT_DIR)/bin) -BUILD_COMMIT := $(shell ./build/get-build-commit.sh) -BUILD_TIMESTAMP := $(shell ./build/get-build-timestamp.sh) -BUILD_HOSTNAME := $(shell ./build/get-build-hostname.sh) +LDFLAGS := "-X github.com/open-policy-agent/gatekeeper/v3/pkg/version.Version=$(VERSION)" -LDFLAGS := "-X github.com/open-policy-agent/gatekeeper/pkg/version.Version=$(VERSION) \ - -X github.com/open-policy-agent/gatekeeper/pkg/version.Vcs=$(BUILD_COMMIT) \ - -X github.com/open-policy-agent/gatekeeper/pkg/version.Timestamp=$(BUILD_TIMESTAMP) \ - -X github.com/open-policy-agent/gatekeeper/pkg/version.Hostname=$(BUILD_HOSTNAME) \ - -X main.frameworksVersion=$(FRAMEWORKS_VERSION) \ - -X main.opaVersion=$(OPA_VERSION)" +PLATFORM ?= linux/amd64 +OUTPUT_TYPE ?= type=docker MANAGER_IMAGE_PATCH := "apiVersion: apps/v1\ \nkind: Deployment\ @@ -67,6 +62,7 @@ MANAGER_IMAGE_PATCH := "apiVersion: apps/v1\ \n - --port=8443\ \n - --logtostderr\ \n - --emit-admission-events\ +\n - --admission-events-involved-namespace\ \n - --exempt-namespace=${GATEKEEPER_NAMESPACE}\ \n - --operation=webhook\ \n - --operation=mutation-webhook\ @@ -87,6 +83,7 @@ MANAGER_IMAGE_PATCH := "apiVersion: apps/v1\ \n name: manager\ \n args:\ \n - --emit-audit-events\ +\n - --audit-events-involved-namespace\ \n - --operation=audit\ \n - --operation=status\ \n - --operation=mutation-status\ @@ -100,11 +97,17 @@ else GOBIN=$(shell go env GOBIN) endif +ifdef GENERATE_ATTESTATIONS +_ATTESTATIONS := --attest type=sbom --attest type=provenance,mode=max +endif + all: lint test manager # Run tests -native-test: - GO111MODULE=on go test -mod vendor ./pkg/... ./apis/... ./cmd/gator/... -race -bench . -coverprofile cover.out +native-test: envtest + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(KUBERNETES_VERSION) --bin-dir $(LOCALBIN) -p path)" \ + GO111MODULE=on \ + go test -mod vendor ./pkg/... ./apis/... ./cmd/gator/... -race -bench . -coverprofile cover.out .PHONY: benchmark-test benchmark-test: @@ -144,7 +147,7 @@ e2e-dependencies: # Download and install kind curl -L https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-linux-amd64 --output ${GITHUB_WORKSPACE}/bin/kind && chmod +x ${GITHUB_WORKSPACE}/bin/kind # Download and install kubectl - curl -L https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl -o ${GITHUB_WORKSPACE}/bin/kubectl && chmod +x ${GITHUB_WORKSPACE}/bin/kubectl + curl -L https://dl.k8s.io/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl -o ${GITHUB_WORKSPACE}/bin/kubectl && chmod +x ${GITHUB_WORKSPACE}/bin/kubectl # Download and install kustomize curl -L https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz -o kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz && tar -zxvf kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz && chmod +x kustomize && mv kustomize ${GITHUB_WORKSPACE}/bin/kustomize # Download and install bats @@ -164,7 +167,11 @@ e2e-build-load-image: docker-buildx e2e-build-load-externaldata-image e2e-build-load-externaldata-image: docker-buildx-builder ./test/externaldata/dummy-provider/scripts/generate-tls-certificate.sh - docker buildx build --platform="linux/amd64" -t dummy-provider:test --load -f test/externaldata/dummy-provider/Dockerfile test/externaldata/dummy-provider + docker buildx build \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ + -t dummy-provider:test \ + -f test/externaldata/dummy-provider/Dockerfile test/externaldata/dummy-provider kind load docker-image --name kind dummy-provider:test e2e-verify-release: e2e-build-load-externaldata-image patch-image deploy test-e2e @@ -178,6 +185,30 @@ e2e-helm-install: ./.staging/helm/linux-amd64/helm version --client e2e-helm-deploy: e2e-helm-install +ifeq ($(ENABLE_PUBSUB),true) + @echo 'auditPodAnnotations: {dapr.io/enabled: "true", dapr.io/app-id: "audit", dapr.io/metrics-port: "9999"}' > .tmp/annotations.yaml + ./.staging/helm/linux-amd64/helm install manifest_staging/charts/gatekeeper --name-template=gatekeeper \ + --namespace ${GATEKEEPER_NAMESPACE} \ + --debug --wait \ + --set image.repository=${HELM_REPO} \ + --set image.crdRepository=${HELM_CRD_REPO} \ + --set image.release=${HELM_RELEASE} \ + --set postInstall.labelNamespace.image.repository=${HELM_CRD_REPO} \ + --set postInstall.labelNamespace.image.tag=${HELM_RELEASE} \ + --set postInstall.labelNamespace.enabled=true \ + --set postInstall.probeWebhook.enabled=true \ + --set emitAdmissionEvents=true \ + --set emitAuditEvents=true \ + --set admissionEventsInvolvedNamespace=true \ + --set auditEventsInvolvedNamespace=true \ + --set disabledBuiltins={http.send} \ + --set logMutations=true \ + --set audit.enablePubsub=${ENABLE_PUBSUB} \ + --set audit.connection=${AUDIT_CONNECTION} \ + --set audit.channel=${AUDIT_CHANNEL} \ + --values .tmp/annotations.yaml \ + --set mutationAnnotations=true; +else ./.staging/helm/linux-amd64/helm install manifest_staging/charts/gatekeeper --name-template=gatekeeper \ --namespace ${GATEKEEPER_NAMESPACE} --create-namespace \ --debug --wait \ @@ -190,9 +221,12 @@ e2e-helm-deploy: e2e-helm-install --set postInstall.probeWebhook.enabled=true \ --set emitAdmissionEvents=true \ --set emitAuditEvents=true \ + --set admissionEventsInvolvedNamespace=true \ + --set auditEventsInvolvedNamespace=true \ --set disabledBuiltins={http.send} \ --set logMutations=true \ - --set mutationAnnotations=true;\ + --set mutationAnnotations=true +endif e2e-helm-upgrade-init: e2e-helm-install ./.staging/helm/linux-amd64/helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts;\ @@ -201,6 +235,8 @@ e2e-helm-upgrade-init: e2e-helm-install --debug --wait \ --set emitAdmissionEvents=true \ --set emitAuditEvents=true \ + --set admissionEventsInvolvedNamespace=true \ + --set auditEventsInvolvedNamespace=true \ --set postInstall.labelNamespace.enabled=true \ --set postInstall.probeWebhook.enabled=true \ --set disabledBuiltins={http.send} \ @@ -222,17 +258,32 @@ e2e-helm-upgrade: --set postInstall.probeWebhook.enabled=true \ --set emitAdmissionEvents=true \ --set emitAuditEvents=true \ + --set admissionEventsInvolvedNamespace=true \ + --set auditEventsInvolvedNamespace=true \ --set disabledBuiltins={http.send} \ --set logMutations=true \ --set mutationAnnotations=true;\ +e2e-subscriber-build-load-image: + docker buildx build --platform="linux/amd64" -t ${FAKE_SUBSCRIBER_IMAGE} --load -f test/pubsub/fake-subscriber/Dockerfile test/pubsub/fake-subscriber + kind load docker-image --name kind ${FAKE_SUBSCRIBER_IMAGE} + +e2e-subscriber-deploy: + kubectl create ns fake-subscriber + kubectl get secret redis --namespace=default -o yaml | sed 's/namespace: .*/namespace: fake-subscriber/' | kubectl apply -f - + kubectl apply -f test/pubsub/fake-subscriber/manifest/subscriber.yaml + +e2e-publisher-deploy: + kubectl get secret redis --namespace=default -o yaml | sed 's/namespace: .*/namespace: gatekeeper-system/' | kubectl apply -f - + kubectl apply -f test/pubsub/publish-components.yaml + # Build manager binary manager: generate - GO111MODULE=on go build -mod vendor -o bin/manager -ldflags $(LDFLAGS) main.go + GO111MODULE=on go build -mod vendor -o bin/manager -ldflags $(LDFLAGS) # Build manager binary manager-osx: generate - GO111MODULE=on go build -mod vendor -o bin/manager GOOS=darwin -ldflags $(LDFLAGS) main.go + GO111MODULE=on go build -mod vendor -o bin/manager GOOS=darwin -ldflags $(LDFLAGS) # Run against the configured Kubernetes cluster in ~/.kube/config run: generate manifests @@ -241,7 +292,7 @@ run: generate manifests # Install CRDs into a cluster install: manifests docker run -v $(shell pwd)/config:/config -v $(shell pwd)/vendor:/vendor \ - k8s.gcr.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ + registry.k8s.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ /config/crd | kubectl apply -f - # Deploy controller in the configured Kubernetes cluster in ~/.kube/config @@ -250,8 +301,10 @@ ifeq ($(ENABLE_GENERATOR_EXPANSION),true) @grep -q -v 'enable-generator-resource-expansion' ./config/overlays/dev/manager_image_patch.yaml && sed -i '/- --operation=webhook/a \ \ \ \ \ \ \ \ - --enable-generator-resource-expansion=true' ./config/overlays/dev/manager_image_patch.yaml @grep -q -v 'enable-generator-resource-expansion' ./config/overlays/dev/manager_image_patch.yaml && sed -i '/- --operation=audit/a \ \ \ \ \ \ \ \ - --enable-generator-resource-expansion=true' ./config/overlays/dev/manager_image_patch.yaml endif - docker run -v $(shell pwd)/config:/config -v $(shell pwd)/vendor:/vendor \ - k8s.gcr.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ + docker run \ + -v $(shell pwd)/config:/config \ + -v $(shell pwd)/vendor:/vendor \ + registry.k8s.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ /config/overlays/dev | kubectl apply -f - # Generate manifests e.g. CRD, RBAC etc. @@ -263,14 +316,15 @@ manifests: __controller-gen paths="./apis/..." \ paths="./pkg/..." \ output:crd:artifacts:config=config/crd/bases + ./build/update-match-schema.sh rm -rf manifest_staging mkdir -p manifest_staging/deploy/experimental mkdir -p manifest_staging/charts/gatekeeper docker run --rm -v $(shell pwd):/gatekeeper \ - k8s.gcr.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ + registry.k8s.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ /gatekeeper/config/default -o /gatekeeper/manifest_staging/deploy/gatekeeper.yaml docker run --rm -v $(shell pwd):/gatekeeper \ - k8s.gcr.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ + registry.k8s.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ --load_restrictor LoadRestrictionsNone /gatekeeper/cmd/build/helmify | go run cmd/build/helmify/*.go # lint runs a dockerized golangci-lint, and should give consistent results @@ -287,7 +341,7 @@ generate: __conversion-gen __controller-gen $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths="./apis/..." paths="./pkg/..." $(CONVERSION_GEN) \ --output-base=/gatekeeper \ - --input-dirs=./apis/mutations/v1,./apis/mutations/v1beta1,./apis/mutations/v1alpha1,./apis/expansion/v1alpha1 \ + --input-dirs=./apis/mutations/v1,./apis/mutations/v1beta1,./apis/mutations/v1alpha1,./apis/expansion/v1alpha1,./apis/syncset/v1alpha1 \ --go-header-file=./hack/boilerplate.go.txt \ --output-file-base=zz_generated.conversion @@ -307,90 +361,88 @@ endif docker-login: @docker login -u $(DOCKER_USER) -p $(DOCKER_PASSWORD) $(REGISTRY) -# Tag for Dev -docker-tag-dev: - @docker tag $(IMG) $(REPOSITORY):$(DEV_TAG) - @docker tag $(IMG) $(REPOSITORY):dev - @docker tag $(CRD_IMG) $(CRD_REPOSITORY):$(DEV_TAG) - @docker tag $(CRD_IMG) $(CRD_REPOSITORY):dev - @docker tag $(GATOR_IMG) $(GATOR_REPOSITORY):$(DEV_TAG) - @docker tag $(GATOR_IMG) $(GATOR_REPOSITORY):dev - -# Tag for Dev -docker-tag-release: - @docker tag $(IMG) $(REPOSITORY):$(VERSION) - @docker tag $(CRD_IMG) $(CRD_REPOSITORY):$(VERSION) - @docker tag $(GATOR_IMG) $(GATOR_REPOSITORY):$(VERSION) - -# Push for Dev -docker-push-dev: docker-tag-dev - @docker push $(REPOSITORY):$(DEV_TAG) - @docker push $(REPOSITORY):dev - @docker push $(CRD_REPOSITORY):$(DEV_TAG) - @docker push $(CRD_REPOSITORY):dev - @docker push $(GATOR_REPOSITORY):$(DEV_TAG) - @docker push $(GATOR_REPOSITORY):dev - -# Push for Release -docker-push-release: docker-tag-release - @docker push $(REPOSITORY):$(VERSION) - @docker push $(CRD_REPOSITORY):$(VERSION) - @docker push $(GATOR_REPOSITORY):$(VERSION) - -# Add crds to gatekeeper-crds image -# Build gatekeeper image -docker-build: build-crds - docker build --pull -f crd.Dockerfile .staging/crds/ --build-arg LDFLAGS=${LDFLAGS} --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --build-arg TARGETOS="linux" --build-arg TARGETARCH="amd64" -t ${CRD_IMG} - docker build --pull . --build-arg LDFLAGS=${LDFLAGS} -t ${IMG} +docker-build: docker-buildx docker-buildx-builder: if ! docker buildx ls | grep -q container-builder; then\ - docker buildx create --name container-builder --use;\ + docker buildx create --name container-builder --use --bootstrap;\ + docker buildx inspect;\ fi # Build image with buildx to build cross platform multi-architecture docker images # https://docs.docker.com/buildx/working-with-buildx/ -docker-buildx: build-crds docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --platform "linux/amd64" \ - -t $(IMG) \ - . --load - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --platform "linux/amd64" \ +docker-buildx: docker-buildx-builder + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ + -t $(IMG) . + +docker-buildx-crds: build-crds docker-buildx-builder + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t $(CRD_IMG) \ - -f crd.Dockerfile .staging/crds/ --load + -f crd.Dockerfile .staging/crds/ docker-buildx-dev: docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --platform "linux/amd64,linux/arm64,linux/arm/v7" \ + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t $(REPOSITORY):$(DEV_TAG) \ - -t $(REPOSITORY):dev \ - . --push + -t $(REPOSITORY):dev . docker-buildx-crds-dev: build-crds docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --platform "linux/amd64,linux/arm64,linux/arm/v7" \ + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t $(CRD_REPOSITORY):$(DEV_TAG) \ -t $(CRD_REPOSITORY):dev \ - -f crd.Dockerfile .staging/crds/ --push + -f crd.Dockerfile .staging/crds/ docker-buildx-release: docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --platform "linux/amd64,linux/arm64,linux/arm/v7" \ - -t $(REPOSITORY):$(VERSION) \ - . --push + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ + -t $(REPOSITORY):$(VERSION) . docker-buildx-crds-release: build-crds docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --platform "linux/amd64,linux/arm64,linux/arm/v7" \ + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS}\ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t $(CRD_REPOSITORY):$(VERSION) \ - -f crd.Dockerfile .staging/crds/ --push + -f crd.Dockerfile .staging/crds/ # Build gator image docker-buildx-gator-dev: docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --platform "linux/amd64,linux/arm64,linux/arm/v6"\ + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t ${GATOR_REPOSITORY}:${DEV_TAG} \ -t ${GATOR_REPOSITORY}:dev \ - -f gator.Dockerfile . --push + -f gator.Dockerfile . docker-buildx-gator-release: docker-buildx-builder - docker buildx build --build-arg LDFLAGS=${LDFLAGS} --platform "linux/amd64,linux/arm64,linux/arm/v6"\ + docker buildx build \ + $(_ATTESTATIONS) \ + --build-arg LDFLAGS=${LDFLAGS} \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t ${GATOR_REPOSITORY}:${VERSION} \ - -f gator.Dockerfile . --push + -f gator.Dockerfile . # Update manager_image_patch.yaml with image tag patch-image: @@ -401,11 +453,6 @@ ifeq ($(USE_LOCAL_IMG),true) endif @sed -i'' -e 's@image: .*@image: '"${IMG}"'@' ./config/overlays/dev/manager_image_patch.yaml -# Push the docker image -docker-push: - docker push ${IMG} - docker push ${CRD_IMG} - release-manifest: @sed -i'' -e 's@image: $(REPOSITORY):$(VERSION)@image: $(REPOSITORY):'"$(NEWVERSION)"'@' ./config/manager/manager.yaml @sed -i "s/appVersion: $(VERSION)/appVersion: ${NEWVERSION}/" ./cmd/build/helmify/static/Chart.yaml @@ -436,7 +483,7 @@ promote-staging-manifest: # Delete gatekeeper from a cluster. Note this is not a complete uninstall, just a dev convenience uninstall: docker run -v $(shell pwd)/config:/config -v $(shell pwd)/vendor:/vendor \ - k8s.gcr.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ + registry.k8s.io/kustomize/kustomize:v${KUSTOMIZE_VERSION} build \ /config/overlays/dev | kubectl delete -f - __controller-gen: __tooling-image @@ -446,18 +493,32 @@ __conversion-gen: __tooling-image CONVERSION_GEN=docker run --rm -v $(shell pwd):/gatekeeper gatekeeper-tooling conversion-gen __tooling-image: - docker build build/tooling \ + docker buildx build build/tooling \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ -t gatekeeper-tooling __test-image: docker buildx build test/image \ - -t gatekeeper-test \ - --load \ + --platform="$(PLATFORM)" \ + --output=$(OUTPUT_TYPE) \ --build-arg YQ_VERSION=$(YQ_VERSION) \ --build-arg BATS_VERSION=$(BATS_VERSION) \ --build-arg ORAS_VERSION=$(ORAS_VERSION) \ --build-arg KUSTOMIZE_VERSION=$(KUSTOMIZE_VERSION) \ - --build-arg KUBEBUILDER_VERSION=$(KUBEBUILDER_VERSION) + -t gatekeeper-test + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/.tmp/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +ENVTEST ?= $(LOCALBIN)/setup-envtest + +.PHONY: envtest +envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +$(ENVTEST): $(LOCALBIN) + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20230118154835-9241bceb3098 .PHONY: vendor vendor: @@ -469,7 +530,7 @@ gator: bin/gator-$(GOOS)-$(GOARCH) mv bin/gator-$(GOOS)-$(GOARCH) bin/gator bin/gator-$(GOOS)-$(GOARCH): - GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BIN_DIR)/gator-$(GOOS)-$(GOARCH) -ldflags $(LDFLAGS) ./cmd/gator + GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 GO111MODULE=on go build -o $(BIN_DIR)/gator-$(GOOS)-$(GOARCH) -ldflags $(LDFLAGS) ./cmd/gator tilt-prepare: mkdir -p .tiltbuild/charts diff --git a/OWNERS b/OWNERS new file mode 100644 index 00000000000..e9dcaed4090 --- /dev/null +++ b/OWNERS @@ -0,0 +1,12 @@ +approvers: +- dhaiducek +- gparvin +- JustinKuli +- mprahl +- yiraeChristineKim +reviewers: +- dhaiducek +- gparvin +- JustinKuli +- mprahl +- yiraeChristineKim diff --git a/README.md b/README.md index 80d7982a031..24d48f2d355 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Gatekeeper +![Static Badge](https://img.shields.io/badge/OPA%20Version-v0.54.0-blue) + ## How is Gatekeeper different from OPA? Compared to using [OPA with its sidecar kube-mgmt](https://www.openpolicyagent.org/docs/kubernetes-admission-control.html) (aka Gatekeeper v1.0), Gatekeeper introduces the following functionality: diff --git a/Tiltfile b/Tiltfile index 90dbbd45d94..6ec4cc7e97f 100644 --- a/Tiltfile +++ b/Tiltfile @@ -16,10 +16,8 @@ allow_k8s_contexts(settings.get("allowed_contexts", [])) if settings.get("trigger_mode", "auto").lower() == "manual": trigger_mode(TRIGGER_MODE_MANUAL) -LDFLAGS = "-X github.com/open-policy-agent/gatekeeper/pkg/version.Version=latest" - TILT_DOCKERFILE = """ -FROM golang:1.19-bullseye as tilt-helper +FROM golang:1.21-bullseye as tilt-helper # Support live reloading with Tilt RUN wget --output-document /restart.sh --quiet https://raw.githubusercontent.com/tilt-dev/rerun-process-wrapper/60eaa572cdf825c646008e1ea28b635f83cefb38/restart.sh && \ wget --output-document /start.sh --quiet https://raw.githubusercontent.com/tilt-dev/rerun-process-wrapper/60eaa572cdf825c646008e1ea28b635f83cefb38/start.sh && \ @@ -36,7 +34,7 @@ COPY bin/manager . def build_manager(): cmd = [ "make tilt-prepare", - "GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -mod vendor -a -ldflags \"" + + "GO111MODULE=on CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -mod vendor -a -ldflags \"" + LDFLAGS + "\" -o .tiltbuild/bin/manager", ] local_resource( @@ -74,7 +72,7 @@ def build_crds(): context=".staging/crds/", target="build", only="crds", - build_args={"KUBE_VERSION": "1.23.0"}, + build_args={"KUBE_VERSION": "1.28.0"}, live_update=[ sync(".staging/crds/", "/crds"), ], @@ -90,7 +88,8 @@ def deploy_gatekeeper(): name="gatekeeper", namespace="gatekeeper-system", values=[".tiltbuild/charts/gatekeeper/values.yaml"], - set=["{}={}".format(k, str(v).lower()) for k, v in helm_values.items()], + set=["{}={}".format(k, str(v).lower()) + for k, v in helm_values.items()], )) # add label to resources @@ -102,16 +101,19 @@ def deploy_gatekeeper(): port = int(helm_values["audit.metricsPort"]) k8s_resource( workload="gatekeeper-audit", - port_forwards=[port_forward(port, name="View metrics", link_path="/metrics")], + port_forwards=[port_forward( + port, name="View metrics", link_path="/metrics")], ) if "controllerManager.metricsPort" in helm_values: port = int(helm_values["controllerManager.metricsPort"]) k8s_resource( workload="gatekeeper-controller-manager", - port_forwards=[port_forward(port, name="View metrics", link_path="/metrics")], + port_forwards=[port_forward( + port, name="View metrics", link_path="/metrics")], ) + build_manager() build_crds() diff --git a/apis/addtoscheme_config_v1alpha1.go b/apis/addtoscheme_config_v1alpha1.go index 94f5a13b20a..2489ece65ff 100644 --- a/apis/addtoscheme_config_v1alpha1.go +++ b/apis/addtoscheme_config_v1alpha1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" ) func init() { diff --git a/apis/addtoscheme_expansion_v1alpha1.go b/apis/addtoscheme_expansion_v1alpha1.go index 9ee067684e1..8ceb6f96fad 100644 --- a/apis/addtoscheme_expansion_v1alpha1.go +++ b/apis/addtoscheme_expansion_v1alpha1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - "github.com/open-policy-agent/gatekeeper/apis/expansion/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1" ) func init() { diff --git a/apis/addtoscheme_expansion_v1beta1.go b/apis/addtoscheme_expansion_v1beta1.go new file mode 100644 index 00000000000..2c6a1b569f2 --- /dev/null +++ b/apis/addtoscheme_expansion_v1beta1.go @@ -0,0 +1,25 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apis + +import ( + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1" +) + +func init() { + // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, v1beta1.AddToScheme) +} diff --git a/apis/addtoscheme_mutations_v1.go b/apis/addtoscheme_mutations_v1.go index 481ce040ef2..5526bbce219 100644 --- a/apis/addtoscheme_mutations_v1.go +++ b/apis/addtoscheme_mutations_v1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - v1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" + v1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" ) func init() { diff --git a/apis/addtoscheme_mutations_v1alpha1.go b/apis/addtoscheme_mutations_v1alpha1.go index 66941f5952c..66ee0290a14 100644 --- a/apis/addtoscheme_mutations_v1alpha1.go +++ b/apis/addtoscheme_mutations_v1alpha1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" ) func init() { diff --git a/apis/addtoscheme_mutations_v1beta1.go b/apis/addtoscheme_mutations_v1beta1.go index fb23cd2115a..fd99a4b3b0a 100644 --- a/apis/addtoscheme_mutations_v1beta1.go +++ b/apis/addtoscheme_mutations_v1beta1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - "github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" ) func init() { diff --git a/apis/addtoscheme_status_v1beta1.go b/apis/addtoscheme_status_v1beta1.go index 8510a869921..596bd73945a 100644 --- a/apis/addtoscheme_status_v1beta1.go +++ b/apis/addtoscheme_status_v1beta1.go @@ -16,7 +16,7 @@ limitations under the License. package apis import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" ) func init() { diff --git a/apis/addtoscheme_syncset_v1alpha1.go b/apis/addtoscheme_syncset_v1alpha1.go new file mode 100644 index 00000000000..a389152b0fe --- /dev/null +++ b/apis/addtoscheme_syncset_v1alpha1.go @@ -0,0 +1,10 @@ +package apis + +import ( + "github.com/open-policy-agent/gatekeeper/v3/apis/syncset/v1alpha1" +) + +func init() { + // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, v1alpha1.AddToScheme) +} diff --git a/apis/config/v1alpha1/config_types.go b/apis/config/v1alpha1/config_types.go index fc74bddbd68..d3a5b7da3d2 100644 --- a/apis/config/v1alpha1/config_types.go +++ b/apis/config/v1alpha1/config_types.go @@ -16,7 +16,7 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -63,8 +63,8 @@ type SyncOnlyEntry struct { } type MatchEntry struct { - Processes []string `json:"processes,omitempty"` - ExcludedNamespaces []util.Wildcard `json:"excludedNamespaces,omitempty"` + Processes []string `json:"processes,omitempty"` + ExcludedNamespaces []wildcard.Wildcard `json:"excludedNamespaces,omitempty"` } type ReadinessSpec struct { diff --git a/apis/config/v1alpha1/zz_generated.deepcopy.go b/apis/config/v1alpha1/zz_generated.deepcopy.go index c7b1a2b5ca6..2df3903752c 100644 --- a/apis/config/v1alpha1/zz_generated.deepcopy.go +++ b/apis/config/v1alpha1/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -149,7 +149,7 @@ func (in *MatchEntry) DeepCopyInto(out *MatchEntry) { } if in.ExcludedNamespaces != nil { in, out := &in.ExcludedNamespaces, &out.ExcludedNamespaces - *out = make([]util.Wildcard, len(*in)) + *out = make([]wildcard.Wildcard, len(*in)) copy(*out, *in) } } diff --git a/apis/expansion/unversioned/expansiontemplate_types.go b/apis/expansion/unversioned/expansiontemplate_types.go index 74d3385a895..050eceec6e1 100644 --- a/apis/expansion/unversioned/expansiontemplate_types.go +++ b/apis/expansion/unversioned/expansiontemplate_types.go @@ -16,7 +16,8 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + statusv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -63,7 +64,13 @@ type ExpansionTemplate struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec ExpansionTemplateSpec `json:"spec,omitempty"` + Spec ExpansionTemplateSpec `json:"spec,omitempty"` + Status ExpansionTemplateStatus `json:"status,omitempty"` +} + +// ExpansionTemplateStatus defines the observed state of ExpansionTemplate. +type ExpansionTemplateStatus struct { + ByPod []statusv1alpha1.ExpansionTemplatePodStatusStatus `json:"byPod,omitempty"` } // +kubebuilder:object:root=true diff --git a/apis/expansion/unversioned/zz_generated.deepcopy.go b/apis/expansion/unversioned/zz_generated.deepcopy.go index c3b73060f42..3cd1633496d 100644 --- a/apis/expansion/unversioned/zz_generated.deepcopy.go +++ b/apis/expansion/unversioned/zz_generated.deepcopy.go @@ -21,7 +21,8 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -31,6 +32,7 @@ func (in *ExpansionTemplate) DeepCopyInto(out *ExpansionTemplate) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplate. @@ -106,6 +108,28 @@ func (in *ExpansionTemplateSpec) DeepCopy() *ExpansionTemplateSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateStatus) DeepCopyInto(out *ExpansionTemplateStatus) { + *out = *in + if in.ByPod != nil { + in, out := &in.ByPod, &out.ByPod + *out = make([]v1beta1.ExpansionTemplatePodStatusStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateStatus. +func (in *ExpansionTemplateStatus) DeepCopy() *ExpansionTemplateStatus { + if in == nil { + return nil + } + out := new(ExpansionTemplateStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GeneratedGVK) DeepCopyInto(out *GeneratedGVK) { *out = *in diff --git a/apis/expansion/v1alpha1/doc.go b/apis/expansion/v1alpha1/doc.go index 30787b738c9..d6fccb77cc6 100644 --- a/apis/expansion/v1alpha1/doc.go +++ b/apis/expansion/v1alpha1/doc.go @@ -1,5 +1,5 @@ // Package v1alpha1 includes v1alpha1 expansion -// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned -// -external-types=github.com/open-policy-agent/gatekeeper/apis/expansion/v1alpha1 +// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned +// -external-types=github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1 package v1alpha1 diff --git a/apis/expansion/v1alpha1/expansion_template_types.go b/apis/expansion/v1alpha1/expansion_template_types.go deleted file mode 100644 index 3b710013f56..00000000000 --- a/apis/expansion/v1alpha1/expansion_template_types.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// ExpansionTemplateSpec defines the desired state of ExpansionTemplate. -type ExpansionTemplateSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // ApplyTo lists the specific groups, versions and kinds of generator resources - // which will be expanded. - ApplyTo []match.ApplyTo `json:"applyTo,omitempty"` - - // TemplateSource specifies the source field on the generator resource to - // use as the base for expanded resource. For Pod-creating generators, this - // is usually spec.template - TemplateSource string `json:"templateSource,omitempty"` - - // GeneratedGVK specifies the GVK of the resources which the generator - // resource creates. - GeneratedGVK GeneratedGVK `json:"generatedGVK,omitempty"` - - // EnforcementAction specifies the enforcement action to be used for resources - // matching the ExpansionTemplate. Specifying an empty value will use the - // enforcement action specified by the Constraint in violation. - EnforcementAction string `json:"enforcementAction,omitempty"` -} - -type GeneratedGVK struct { - Group string `json:"group,omitempty"` - Version string `json:"version,omitempty"` - Kind string `json:"kind,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:resource:path="expansiontemplate" -// +kubebuilder:resource:scope="Cluster" - -// ExpansionTemplate is the Schema for the ExpansionTemplate API. -type ExpansionTemplate struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ExpansionTemplateSpec `json:"spec,omitempty"` -} - -// +kubebuilder:object:root=true - -// ExpansionTemplateList contains a list of ExpansionTemplate. -type ExpansionTemplateList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ExpansionTemplate `json:"items"` -} - -func init() { - SchemeBuilder.Register(&ExpansionTemplate{}, &ExpansionTemplateList{}) -} diff --git a/apis/expansion/v1alpha1/expansiontemplate_types.go b/apis/expansion/v1alpha1/expansiontemplate_types.go new file mode 100644 index 00000000000..e693f08dfcf --- /dev/null +++ b/apis/expansion/v1alpha1/expansiontemplate_types.go @@ -0,0 +1,88 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + status "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ExpansionTemplateSpec defines the desired state of ExpansionTemplate. +type ExpansionTemplateSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ApplyTo lists the specific groups, versions and kinds of generator resources + // which will be expanded. + ApplyTo []match.ApplyTo `json:"applyTo,omitempty"` + + // TemplateSource specifies the source field on the generator resource to + // use as the base for expanded resource. For Pod-creating generators, this + // is usually spec.template + TemplateSource string `json:"templateSource,omitempty"` + + // GeneratedGVK specifies the GVK of the resources which the generator + // resource creates. + GeneratedGVK GeneratedGVK `json:"generatedGVK,omitempty"` + + // EnforcementAction specifies the enforcement action to be used for resources + // matching the ExpansionTemplate. Specifying an empty value will use the + // enforcement action specified by the Constraint in violation. + EnforcementAction string `json:"enforcementAction,omitempty"` +} + +type GeneratedGVK struct { + Group string `json:"group,omitempty"` + Version string `json:"version,omitempty"` + Kind string `json:"kind,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:resource:path="expansiontemplate" +// +kubebuilder:resource:scope="Cluster" +// +kubebuilder:subresource:status +// +kubebuilder:storageversion + +// ExpansionTemplate is the Schema for the ExpansionTemplate API. +type ExpansionTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExpansionTemplateSpec `json:"spec,omitempty"` + Status ExpansionTemplateStatus `json:"status,omitempty"` +} + +// ExpansionTemplateStatus defines the observed state of ExpansionTemplate. +type ExpansionTemplateStatus struct { + ByPod []status.ExpansionTemplatePodStatusStatus `json:"byPod,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExpansionTemplateList contains a list of ExpansionTemplate. +type ExpansionTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExpansionTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExpansionTemplate{}, &ExpansionTemplateList{}) +} diff --git a/apis/expansion/v1alpha1/zz_generated.conversion.go b/apis/expansion/v1alpha1/zz_generated.conversion.go index 16c04fddadb..be5e5e654d5 100644 --- a/apis/expansion/v1alpha1/zz_generated.conversion.go +++ b/apis/expansion/v1alpha1/zz_generated.conversion.go @@ -22,8 +22,9 @@ package v1alpha1 import ( unsafe "unsafe" - unversioned "github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned" - match "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + unversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + v1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + match "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -65,6 +66,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ExpansionTemplateStatus)(nil), (*unversioned.ExpansionTemplateStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(a.(*ExpansionTemplateStatus), b.(*unversioned.ExpansionTemplateStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.ExpansionTemplateStatus)(nil), (*ExpansionTemplateStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus(a.(*unversioned.ExpansionTemplateStatus), b.(*ExpansionTemplateStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*GeneratedGVK)(nil), (*unversioned.GeneratedGVK)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_GeneratedGVK_To_unversioned_GeneratedGVK(a.(*GeneratedGVK), b.(*unversioned.GeneratedGVK), scope) }); err != nil { @@ -83,6 +94,9 @@ func autoConvert_v1alpha1_ExpansionTemplate_To_unversioned_ExpansionTemplate(in if err := Convert_v1alpha1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(&in.Spec, &out.Spec, s); err != nil { return err } + if err := Convert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(&in.Status, &out.Status, s); err != nil { + return err + } return nil } @@ -96,6 +110,9 @@ func autoConvert_unversioned_ExpansionTemplate_To_v1alpha1_ExpansionTemplate(in if err := Convert_unversioned_ExpansionTemplateSpec_To_v1alpha1_ExpansionTemplateSpec(&in.Spec, &out.Spec, s); err != nil { return err } + if err := Convert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus(&in.Status, &out.Status, s); err != nil { + return err + } return nil } @@ -156,6 +173,26 @@ func Convert_unversioned_ExpansionTemplateSpec_To_v1alpha1_ExpansionTemplateSpec return autoConvert_unversioned_ExpansionTemplateSpec_To_v1alpha1_ExpansionTemplateSpec(in, out, s) } +func autoConvert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in *ExpansionTemplateStatus, out *unversioned.ExpansionTemplateStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.ExpansionTemplatePodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus is an autogenerated conversion function. +func Convert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in *ExpansionTemplateStatus, out *unversioned.ExpansionTemplateStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in, out, s) +} + +func autoConvert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus(in *unversioned.ExpansionTemplateStatus, out *ExpansionTemplateStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.ExpansionTemplatePodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus is an autogenerated conversion function. +func Convert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus(in *unversioned.ExpansionTemplateStatus, out *ExpansionTemplateStatus, s conversion.Scope) error { + return autoConvert_unversioned_ExpansionTemplateStatus_To_v1alpha1_ExpansionTemplateStatus(in, out, s) +} + func autoConvert_v1alpha1_GeneratedGVK_To_unversioned_GeneratedGVK(in *GeneratedGVK, out *unversioned.GeneratedGVK, s conversion.Scope) error { out.Group = in.Group out.Version = in.Version diff --git a/apis/expansion/v1alpha1/zz_generated.deepcopy.go b/apis/expansion/v1alpha1/zz_generated.deepcopy.go index 8b08913b818..d44b368c3a1 100644 --- a/apis/expansion/v1alpha1/zz_generated.deepcopy.go +++ b/apis/expansion/v1alpha1/zz_generated.deepcopy.go @@ -21,7 +21,8 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "k8s.io/apimachinery/pkg/runtime" ) @@ -31,6 +32,7 @@ func (in *ExpansionTemplate) DeepCopyInto(out *ExpansionTemplate) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplate. @@ -106,6 +108,28 @@ func (in *ExpansionTemplateSpec) DeepCopy() *ExpansionTemplateSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateStatus) DeepCopyInto(out *ExpansionTemplateStatus) { + *out = *in + if in.ByPod != nil { + in, out := &in.ByPod, &out.ByPod + *out = make([]v1beta1.ExpansionTemplatePodStatusStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateStatus. +func (in *ExpansionTemplateStatus) DeepCopy() *ExpansionTemplateStatus { + if in == nil { + return nil + } + out := new(ExpansionTemplateStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GeneratedGVK) DeepCopyInto(out *GeneratedGVK) { *out = *in diff --git a/apis/expansion/v1beta1/doc.go b/apis/expansion/v1beta1/doc.go new file mode 100644 index 00000000000..50225e0afde --- /dev/null +++ b/apis/expansion/v1beta1/doc.go @@ -0,0 +1,5 @@ +// Package v1beta1 includes v1beta1 expansion + +// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned +// -external-types=github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1 +package v1beta1 diff --git a/apis/expansion/v1beta1/expansiontemplate_types.go b/apis/expansion/v1beta1/expansiontemplate_types.go new file mode 100644 index 00000000000..7a3bd77e946 --- /dev/null +++ b/apis/expansion/v1beta1/expansiontemplate_types.go @@ -0,0 +1,87 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + status "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ExpansionTemplateSpec defines the desired state of ExpansionTemplate. +type ExpansionTemplateSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ApplyTo lists the specific groups, versions and kinds of generator resources + // which will be expanded. + ApplyTo []match.ApplyTo `json:"applyTo,omitempty"` + + // TemplateSource specifies the source field on the generator resource to + // use as the base for expanded resource. For Pod-creating generators, this + // is usually spec.template + TemplateSource string `json:"templateSource,omitempty"` + + // GeneratedGVK specifies the GVK of the resources which the generator + // resource creates. + GeneratedGVK GeneratedGVK `json:"generatedGVK,omitempty"` + + // EnforcementAction specifies the enforcement action to be used for resources + // matching the ExpansionTemplate. Specifying an empty value will use the + // enforcement action specified by the Constraint in violation. + EnforcementAction string `json:"enforcementAction,omitempty"` +} + +type GeneratedGVK struct { + Group string `json:"group,omitempty"` + Version string `json:"version,omitempty"` + Kind string `json:"kind,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:resource:path="expansiontemplate" +// +kubebuilder:resource:scope="Cluster" +// +kubebuilder:subresource:status + +// ExpansionTemplate is the Schema for the ExpansionTemplate API. +type ExpansionTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExpansionTemplateSpec `json:"spec,omitempty"` + Status ExpansionTemplateStatus `json:"status,omitempty"` +} + +// ExpansionTemplateStatus defines the observed state of ExpansionTemplate. +type ExpansionTemplateStatus struct { + ByPod []status.ExpansionTemplatePodStatusStatus `json:"byPod,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExpansionTemplateList contains a list of ExpansionTemplate. +type ExpansionTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExpansionTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExpansionTemplate{}, &ExpansionTemplateList{}) +} diff --git a/apis/expansion/v1beta1/groupversion_info.go b/apis/expansion/v1beta1/groupversion_info.go new file mode 100644 index 00000000000..843f98e7ecf --- /dev/null +++ b/apis/expansion/v1beta1/groupversion_info.go @@ -0,0 +1,38 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains API Schema definitions for the expansion v1beta1 API group +// +kubebuilder:object:generate=true +// +groupName=expansion.gatekeeper.sh +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "expansion.gatekeeper.sh", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + localSchemeBuilder = runtime.NewSchemeBuilder(SchemeBuilder.AddToScheme) + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/apis/expansion/v1beta1/zz_generated.conversion.go b/apis/expansion/v1beta1/zz_generated.conversion.go new file mode 100644 index 00000000000..ae75d025441 --- /dev/null +++ b/apis/expansion/v1beta1/zz_generated.conversion.go @@ -0,0 +1,218 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by conversion-gen. DO NOT EDIT. + +package v1beta1 + +import ( + unsafe "unsafe" + + unversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + v1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + match "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ExpansionTemplate)(nil), (*unversioned.ExpansionTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExpansionTemplate_To_unversioned_ExpansionTemplate(a.(*ExpansionTemplate), b.(*unversioned.ExpansionTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.ExpansionTemplate)(nil), (*ExpansionTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_ExpansionTemplate_To_v1beta1_ExpansionTemplate(a.(*unversioned.ExpansionTemplate), b.(*ExpansionTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExpansionTemplateList)(nil), (*unversioned.ExpansionTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExpansionTemplateList_To_unversioned_ExpansionTemplateList(a.(*ExpansionTemplateList), b.(*unversioned.ExpansionTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.ExpansionTemplateList)(nil), (*ExpansionTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_ExpansionTemplateList_To_v1beta1_ExpansionTemplateList(a.(*unversioned.ExpansionTemplateList), b.(*ExpansionTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExpansionTemplateSpec)(nil), (*unversioned.ExpansionTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(a.(*ExpansionTemplateSpec), b.(*unversioned.ExpansionTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.ExpansionTemplateSpec)(nil), (*ExpansionTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec(a.(*unversioned.ExpansionTemplateSpec), b.(*ExpansionTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExpansionTemplateStatus)(nil), (*unversioned.ExpansionTemplateStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(a.(*ExpansionTemplateStatus), b.(*unversioned.ExpansionTemplateStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.ExpansionTemplateStatus)(nil), (*ExpansionTemplateStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus(a.(*unversioned.ExpansionTemplateStatus), b.(*ExpansionTemplateStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*GeneratedGVK)(nil), (*unversioned.GeneratedGVK)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK(a.(*GeneratedGVK), b.(*unversioned.GeneratedGVK), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.GeneratedGVK)(nil), (*GeneratedGVK)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK(a.(*unversioned.GeneratedGVK), b.(*GeneratedGVK), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_ExpansionTemplate_To_unversioned_ExpansionTemplate(in *ExpansionTemplate, out *unversioned.ExpansionTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_ExpansionTemplate_To_unversioned_ExpansionTemplate is an autogenerated conversion function. +func Convert_v1beta1_ExpansionTemplate_To_unversioned_ExpansionTemplate(in *ExpansionTemplate, out *unversioned.ExpansionTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_ExpansionTemplate_To_unversioned_ExpansionTemplate(in, out, s) +} + +func autoConvert_unversioned_ExpansionTemplate_To_v1beta1_ExpansionTemplate(in *unversioned.ExpansionTemplate, out *ExpansionTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_unversioned_ExpansionTemplate_To_v1beta1_ExpansionTemplate is an autogenerated conversion function. +func Convert_unversioned_ExpansionTemplate_To_v1beta1_ExpansionTemplate(in *unversioned.ExpansionTemplate, out *ExpansionTemplate, s conversion.Scope) error { + return autoConvert_unversioned_ExpansionTemplate_To_v1beta1_ExpansionTemplate(in, out, s) +} + +func autoConvert_v1beta1_ExpansionTemplateList_To_unversioned_ExpansionTemplateList(in *ExpansionTemplateList, out *unversioned.ExpansionTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]unversioned.ExpansionTemplate)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1beta1_ExpansionTemplateList_To_unversioned_ExpansionTemplateList is an autogenerated conversion function. +func Convert_v1beta1_ExpansionTemplateList_To_unversioned_ExpansionTemplateList(in *ExpansionTemplateList, out *unversioned.ExpansionTemplateList, s conversion.Scope) error { + return autoConvert_v1beta1_ExpansionTemplateList_To_unversioned_ExpansionTemplateList(in, out, s) +} + +func autoConvert_unversioned_ExpansionTemplateList_To_v1beta1_ExpansionTemplateList(in *unversioned.ExpansionTemplateList, out *ExpansionTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]ExpansionTemplate)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_unversioned_ExpansionTemplateList_To_v1beta1_ExpansionTemplateList is an autogenerated conversion function. +func Convert_unversioned_ExpansionTemplateList_To_v1beta1_ExpansionTemplateList(in *unversioned.ExpansionTemplateList, out *ExpansionTemplateList, s conversion.Scope) error { + return autoConvert_unversioned_ExpansionTemplateList_To_v1beta1_ExpansionTemplateList(in, out, s) +} + +func autoConvert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(in *ExpansionTemplateSpec, out *unversioned.ExpansionTemplateSpec, s conversion.Scope) error { + out.ApplyTo = *(*[]match.ApplyTo)(unsafe.Pointer(&in.ApplyTo)) + out.TemplateSource = in.TemplateSource + if err := Convert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK(&in.GeneratedGVK, &out.GeneratedGVK, s); err != nil { + return err + } + out.EnforcementAction = in.EnforcementAction + return nil +} + +// Convert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(in *ExpansionTemplateSpec, out *unversioned.ExpansionTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_ExpansionTemplateSpec_To_unversioned_ExpansionTemplateSpec(in, out, s) +} + +func autoConvert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec(in *unversioned.ExpansionTemplateSpec, out *ExpansionTemplateSpec, s conversion.Scope) error { + out.ApplyTo = *(*[]match.ApplyTo)(unsafe.Pointer(&in.ApplyTo)) + out.TemplateSource = in.TemplateSource + if err := Convert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK(&in.GeneratedGVK, &out.GeneratedGVK, s); err != nil { + return err + } + out.EnforcementAction = in.EnforcementAction + return nil +} + +// Convert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec is an autogenerated conversion function. +func Convert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec(in *unversioned.ExpansionTemplateSpec, out *ExpansionTemplateSpec, s conversion.Scope) error { + return autoConvert_unversioned_ExpansionTemplateSpec_To_v1beta1_ExpansionTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in *ExpansionTemplateStatus, out *unversioned.ExpansionTemplateStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.ExpansionTemplatePodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus is an autogenerated conversion function. +func Convert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in *ExpansionTemplateStatus, out *unversioned.ExpansionTemplateStatus, s conversion.Scope) error { + return autoConvert_v1beta1_ExpansionTemplateStatus_To_unversioned_ExpansionTemplateStatus(in, out, s) +} + +func autoConvert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus(in *unversioned.ExpansionTemplateStatus, out *ExpansionTemplateStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.ExpansionTemplatePodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus is an autogenerated conversion function. +func Convert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus(in *unversioned.ExpansionTemplateStatus, out *ExpansionTemplateStatus, s conversion.Scope) error { + return autoConvert_unversioned_ExpansionTemplateStatus_To_v1beta1_ExpansionTemplateStatus(in, out, s) +} + +func autoConvert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK(in *GeneratedGVK, out *unversioned.GeneratedGVK, s conversion.Scope) error { + out.Group = in.Group + out.Version = in.Version + out.Kind = in.Kind + return nil +} + +// Convert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK is an autogenerated conversion function. +func Convert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK(in *GeneratedGVK, out *unversioned.GeneratedGVK, s conversion.Scope) error { + return autoConvert_v1beta1_GeneratedGVK_To_unversioned_GeneratedGVK(in, out, s) +} + +func autoConvert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK(in *unversioned.GeneratedGVK, out *GeneratedGVK, s conversion.Scope) error { + out.Group = in.Group + out.Version = in.Version + out.Kind = in.Kind + return nil +} + +// Convert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK is an autogenerated conversion function. +func Convert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK(in *unversioned.GeneratedGVK, out *GeneratedGVK, s conversion.Scope) error { + return autoConvert_unversioned_GeneratedGVK_To_v1beta1_GeneratedGVK(in, out, s) +} diff --git a/apis/expansion/v1beta1/zz_generated.deepcopy.go b/apis/expansion/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..6ae018f2d27 --- /dev/null +++ b/apis/expansion/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,146 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplate) DeepCopyInto(out *ExpansionTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplate. +func (in *ExpansionTemplate) DeepCopy() *ExpansionTemplate { + if in == nil { + return nil + } + out := new(ExpansionTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExpansionTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateList) DeepCopyInto(out *ExpansionTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExpansionTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateList. +func (in *ExpansionTemplateList) DeepCopy() *ExpansionTemplateList { + if in == nil { + return nil + } + out := new(ExpansionTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExpansionTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateSpec) DeepCopyInto(out *ExpansionTemplateSpec) { + *out = *in + if in.ApplyTo != nil { + in, out := &in.ApplyTo, &out.ApplyTo + *out = make([]match.ApplyTo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.GeneratedGVK = in.GeneratedGVK +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateSpec. +func (in *ExpansionTemplateSpec) DeepCopy() *ExpansionTemplateSpec { + if in == nil { + return nil + } + out := new(ExpansionTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateStatus) DeepCopyInto(out *ExpansionTemplateStatus) { + *out = *in + if in.ByPod != nil { + in, out := &in.ByPod, &out.ByPod + *out = make([]statusv1beta1.ExpansionTemplatePodStatusStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateStatus. +func (in *ExpansionTemplateStatus) DeepCopy() *ExpansionTemplateStatus { + if in == nil { + return nil + } + out := new(ExpansionTemplateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GeneratedGVK) DeepCopyInto(out *GeneratedGVK) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratedGVK. +func (in *GeneratedGVK) DeepCopy() *GeneratedGVK { + if in == nil { + return nil + } + out := new(GeneratedGVK) + in.DeepCopyInto(out) + return out +} diff --git a/apis/mutations/unversioned/assign_types.go b/apis/mutations/unversioned/assign_types.go index 6068544eea6..f8a4b15df15 100644 --- a/apis/mutations/unversioned/assign_types.go +++ b/apis/mutations/unversioned/assign_types.go @@ -16,9 +16,9 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/unversioned/assignimage_types.go b/apis/mutations/unversioned/assignimage_types.go new file mode 100644 index 00000000000..a02ad637d41 --- /dev/null +++ b/apis/mutations/unversioned/assignimage_types.go @@ -0,0 +1,90 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package unversioned + +import ( + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// AssignImageSpec defines the desired state of AssignImage. +type AssignImageSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. + // This is necessary because every mutation implies part of an object schema and object + // schemas are associated with specific GVKs. + ApplyTo []match.ApplyTo `json:"applyTo,omitempty"` + + // Match allows the user to limit which resources get mutated. + // Individual match criteria are AND-ed together. An undefined + // match criteria matches everything. + Match match.Match `json:"match,omitempty"` + + // Location describes the path to be mutated, for example: `spec.containers[name: main].image`. + Location string `json:"location,omitempty"` + + // Parameters define the behavior of the mutator. + Parameters AssignImageParameters `json:"parameters,omitempty"` +} + +type AssignImageParameters struct { + PathTests []PathTest `json:"pathTests,omitempty"` + + // AssignDomain sets the domain component on an image string. The trailing + // slash should not be included. + AssignDomain string `json:"assignDomain,omitempty"` + + // AssignPath sets the domain component on an image string. + AssignPath string `json:"assignPath,omitempty"` + + // AssignImage sets the image component on an image string. It must start + // with a `:` or `@`. + AssignTag string `json:"assignTag,omitempty"` +} + +// AssignImageStatus defines the observed state of AssignImage. +type AssignImageStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + ByPod []v1beta1.MutatorPodStatusStatus `json:"byPod,omitempty"` +} + +// +kubebuilder:object:root=true + +// AssignImage is the Schema for the assign API. +type AssignImage struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AssignImageSpec `json:"spec,omitempty"` + Status AssignImageStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// AssignImageList contains a list of AssignImage. +type AssignImageList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AssignImage `json:"items"` +} diff --git a/apis/mutations/unversioned/assignmetadata_types.go b/apis/mutations/unversioned/assignmetadata_types.go index 6a93bbcdb9d..04273454390 100644 --- a/apis/mutations/unversioned/assignmetadata_types.go +++ b/apis/mutations/unversioned/assignmetadata_types.go @@ -16,8 +16,8 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/unversioned/externaldata_types.go b/apis/mutations/unversioned/externaldata_types.go index bab01ee8e5e..78c29c4179f 100644 --- a/apis/mutations/unversioned/externaldata_types.go +++ b/apis/mutations/unversioned/externaldata_types.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/apis/mutations/unversioned/modifyset_types.go b/apis/mutations/unversioned/modifyset_types.go index 356981cf790..755164aad27 100644 --- a/apis/mutations/unversioned/modifyset_types.go +++ b/apis/mutations/unversioned/modifyset_types.go @@ -16,8 +16,8 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/unversioned/value.go b/apis/mutations/unversioned/value.go index d90f1434acf..52652a7c82a 100644 --- a/apis/mutations/unversioned/value.go +++ b/apis/mutations/unversioned/value.go @@ -5,7 +5,7 @@ import ( "fmt" "reflect" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) var ( diff --git a/apis/mutations/unversioned/value_test.go b/apis/mutations/unversioned/value_test.go index 30991da2652..65d85279bb8 100644 --- a/apis/mutations/unversioned/value_test.go +++ b/apis/mutations/unversioned/value_test.go @@ -5,8 +5,8 @@ import ( "reflect" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/apis/mutations/unversioned/zz_generated.deepcopy.go b/apis/mutations/unversioned/zz_generated.deepcopy.go index 14832664613..0b0c3a9bb23 100644 --- a/apis/mutations/unversioned/zz_generated.deepcopy.go +++ b/apis/mutations/unversioned/zz_generated.deepcopy.go @@ -21,8 +21,8 @@ limitations under the License. package unversioned import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "k8s.io/apimachinery/pkg/runtime" ) @@ -82,6 +82,131 @@ func (in *AssignField) DeepCopy() *AssignField { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImage) DeepCopyInto(out *AssignImage) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImage. +func (in *AssignImage) DeepCopy() *AssignImage { + if in == nil { + return nil + } + out := new(AssignImage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AssignImage) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageList) DeepCopyInto(out *AssignImageList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AssignImage, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageList. +func (in *AssignImageList) DeepCopy() *AssignImageList { + if in == nil { + return nil + } + out := new(AssignImageList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AssignImageList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageParameters) DeepCopyInto(out *AssignImageParameters) { + *out = *in + if in.PathTests != nil { + in, out := &in.PathTests, &out.PathTests + *out = make([]PathTest, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageParameters. +func (in *AssignImageParameters) DeepCopy() *AssignImageParameters { + if in == nil { + return nil + } + out := new(AssignImageParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageSpec) DeepCopyInto(out *AssignImageSpec) { + *out = *in + if in.ApplyTo != nil { + in, out := &in.ApplyTo, &out.ApplyTo + *out = make([]match.ApplyTo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Match.DeepCopyInto(&out.Match) + in.Parameters.DeepCopyInto(&out.Parameters) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageSpec. +func (in *AssignImageSpec) DeepCopy() *AssignImageSpec { + if in == nil { + return nil + } + out := new(AssignImageSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageStatus) DeepCopyInto(out *AssignImageStatus) { + *out = *in + if in.ByPod != nil { + in, out := &in.ByPod, &out.ByPod + *out = make([]v1beta1.MutatorPodStatusStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageStatus. +func (in *AssignImageStatus) DeepCopy() *AssignImageStatus { + if in == nil { + return nil + } + out := new(AssignImageStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AssignList) DeepCopyInto(out *AssignList) { *out = *in diff --git a/apis/mutations/v1/assign_types.go b/apis/mutations/v1/assign_types.go index 7df489dec80..a771f0b94e8 100644 --- a/apis/mutations/v1/assign_types.go +++ b/apis/mutations/v1/assign_types.go @@ -16,9 +16,9 @@ limitations under the License. package v1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1/assignmetadata_types.go b/apis/mutations/v1/assignmetadata_types.go index 3e623c1b582..641767c2948 100644 --- a/apis/mutations/v1/assignmetadata_types.go +++ b/apis/mutations/v1/assignmetadata_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1/doc.go b/apis/mutations/v1/doc.go index bd3e26d94be..d6c413b2c7e 100644 --- a/apis/mutations/v1/doc.go +++ b/apis/mutations/v1/doc.go @@ -1,5 +1,5 @@ // Package v1 includes v1 mutators -// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned -// -external-types=github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1 +// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned +// -external-types=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1 package v1 diff --git a/apis/mutations/v1/externaldata_types.go b/apis/mutations/v1/externaldata_types.go index b88bc1ea055..20a9c662471 100644 --- a/apis/mutations/v1/externaldata_types.go +++ b/apis/mutations/v1/externaldata_types.go @@ -1,7 +1,7 @@ package v1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) // ExternalData describes the external data source to use for the mutation. diff --git a/apis/mutations/v1/modifyset_types.go b/apis/mutations/v1/modifyset_types.go index b2a768fa579..5efcede93ab 100644 --- a/apis/mutations/v1/modifyset_types.go +++ b/apis/mutations/v1/modifyset_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1/value.go b/apis/mutations/v1/value.go index 877d80d4a69..0786d60a201 100644 --- a/apis/mutations/v1/value.go +++ b/apis/mutations/v1/value.go @@ -1,8 +1,8 @@ package v1 import ( - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type AssignField struct { diff --git a/apis/mutations/v1/zz_generated.conversion.go b/apis/mutations/v1/zz_generated.conversion.go index 71689e6d74a..07c30314620 100644 --- a/apis/mutations/v1/zz_generated.conversion.go +++ b/apis/mutations/v1/zz_generated.conversion.go @@ -22,11 +22,11 @@ package v1 import ( unsafe "unsafe" - unversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - v1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - match "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - tester "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - types "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + unversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + v1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + match "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + tester "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + types "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1/zz_generated.deepcopy.go b/apis/mutations/v1/zz_generated.deepcopy.go index bf207418367..fc732100f53 100644 --- a/apis/mutations/v1/zz_generated.deepcopy.go +++ b/apis/mutations/v1/zz_generated.deepcopy.go @@ -21,8 +21,8 @@ limitations under the License. package v1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1alpha1/assign_types.go b/apis/mutations/v1alpha1/assign_types.go index 2c673877bba..9ad9f23fa1f 100644 --- a/apis/mutations/v1alpha1/assign_types.go +++ b/apis/mutations/v1alpha1/assign_types.go @@ -16,9 +16,9 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1alpha1/assignimage_types.go b/apis/mutations/v1alpha1/assignimage_types.go new file mode 100644 index 00000000000..77d7abdd63e --- /dev/null +++ b/apis/mutations/v1alpha1/assignimage_types.go @@ -0,0 +1,97 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// AssignImageSpec defines the desired state of AssignImage. +type AssignImageSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. + // This is necessary because every mutation implies part of an object schema and object + // schemas are associated with specific GVKs. + ApplyTo []match.ApplyTo `json:"applyTo,omitempty"` + + // Match allows the user to limit which resources get mutated. + // Individual match criteria are AND-ed together. An undefined + // match criteria matches everything. + Match match.Match `json:"match,omitempty"` + + // Location describes the path to be mutated, for example: `spec.containers[name: main].image`. + Location string `json:"location,omitempty"` + + // Parameters define the behavior of the mutator. + Parameters AssignImageParameters `json:"parameters,omitempty"` +} + +type AssignImageParameters struct { + PathTests []PathTest `json:"pathTests,omitempty"` + + // AssignDomain sets the domain component on an image string. The trailing + // slash should not be included. + AssignDomain string `json:"assignDomain,omitempty"` + + // AssignPath sets the domain component on an image string. + AssignPath string `json:"assignPath,omitempty"` + + // AssignImage sets the image component on an image string. It must start + // with a `:` or `@`. + AssignTag string `json:"assignTag,omitempty"` +} + +// AssignImageStatus defines the observed state of AssignImage. +type AssignImageStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + ByPod []v1beta1.MutatorPodStatusStatus `json:"byPod,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:resource:path="assignimage" +// +kubebuilder:resource:scope="Cluster" +// +kubebuilder:subresource:status + +// AssignImage is the Schema for the assignimage API. +type AssignImage struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AssignImageSpec `json:"spec,omitempty"` + Status AssignImageStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// AssignImageList contains a list of AssignImage. +type AssignImageList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AssignImage `json:"items"` +} + +func init() { + SchemeBuilder.Register(&AssignImage{}, &AssignImageList{}) +} diff --git a/apis/mutations/v1alpha1/assignmetadata_types.go b/apis/mutations/v1alpha1/assignmetadata_types.go index 5516f7bb663..db3c5e90005 100644 --- a/apis/mutations/v1alpha1/assignmetadata_types.go +++ b/apis/mutations/v1alpha1/assignmetadata_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1alpha1/doc.go b/apis/mutations/v1alpha1/doc.go index 06f0502febf..14d2c346c74 100644 --- a/apis/mutations/v1alpha1/doc.go +++ b/apis/mutations/v1alpha1/doc.go @@ -1,5 +1,5 @@ // Package v1alpha1 includes v1alpha1 mutators -// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned -// -external-types=github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1 +// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned +// -external-types=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1 package v1alpha1 diff --git a/apis/mutations/v1alpha1/externaldata_types.go b/apis/mutations/v1alpha1/externaldata_types.go index d37d7717977..b9a65e39ab5 100644 --- a/apis/mutations/v1alpha1/externaldata_types.go +++ b/apis/mutations/v1alpha1/externaldata_types.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) // ExternalData describes the external data source to use for the mutation. diff --git a/apis/mutations/v1alpha1/modifyset_types.go b/apis/mutations/v1alpha1/modifyset_types.go index 0c084cc071f..d98c6a196fa 100644 --- a/apis/mutations/v1alpha1/modifyset_types.go +++ b/apis/mutations/v1alpha1/modifyset_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1alpha1/value.go b/apis/mutations/v1alpha1/value.go index 422daa82408..c91693b7561 100644 --- a/apis/mutations/v1alpha1/value.go +++ b/apis/mutations/v1alpha1/value.go @@ -1,8 +1,8 @@ package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type AssignField struct { diff --git a/apis/mutations/v1alpha1/zz_generated.conversion.go b/apis/mutations/v1alpha1/zz_generated.conversion.go index 8e4eb5e6ad6..c31ff7e8264 100644 --- a/apis/mutations/v1alpha1/zz_generated.conversion.go +++ b/apis/mutations/v1alpha1/zz_generated.conversion.go @@ -22,11 +22,11 @@ package v1alpha1 import ( unsafe "unsafe" - unversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - v1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - match "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - tester "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - types "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + unversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + v1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + match "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + tester "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + types "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -58,6 +58,56 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*AssignImage)(nil), (*unversioned.AssignImage)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssignImage_To_unversioned_AssignImage(a.(*AssignImage), b.(*unversioned.AssignImage), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.AssignImage)(nil), (*AssignImage)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_AssignImage_To_v1alpha1_AssignImage(a.(*unversioned.AssignImage), b.(*AssignImage), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AssignImageList)(nil), (*unversioned.AssignImageList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssignImageList_To_unversioned_AssignImageList(a.(*AssignImageList), b.(*unversioned.AssignImageList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.AssignImageList)(nil), (*AssignImageList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_AssignImageList_To_v1alpha1_AssignImageList(a.(*unversioned.AssignImageList), b.(*AssignImageList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AssignImageParameters)(nil), (*unversioned.AssignImageParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters(a.(*AssignImageParameters), b.(*unversioned.AssignImageParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.AssignImageParameters)(nil), (*AssignImageParameters)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters(a.(*unversioned.AssignImageParameters), b.(*AssignImageParameters), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AssignImageSpec)(nil), (*unversioned.AssignImageSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec(a.(*AssignImageSpec), b.(*unversioned.AssignImageSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.AssignImageSpec)(nil), (*AssignImageSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec(a.(*unversioned.AssignImageSpec), b.(*AssignImageSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AssignImageStatus)(nil), (*unversioned.AssignImageStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus(a.(*AssignImageStatus), b.(*unversioned.AssignImageStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*unversioned.AssignImageStatus)(nil), (*AssignImageStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus(a.(*unversioned.AssignImageStatus), b.(*AssignImageStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*AssignList)(nil), (*unversioned.AssignList)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_AssignList_To_unversioned_AssignList(a.(*AssignList), b.(*unversioned.AssignList), scope) }); err != nil { @@ -297,6 +347,136 @@ func Convert_unversioned_AssignField_To_v1alpha1_AssignField(in *unversioned.Ass return autoConvert_unversioned_AssignField_To_v1alpha1_AssignField(in, out, s) } +func autoConvert_v1alpha1_AssignImage_To_unversioned_AssignImage(in *AssignImage, out *unversioned.AssignImage, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_AssignImage_To_unversioned_AssignImage is an autogenerated conversion function. +func Convert_v1alpha1_AssignImage_To_unversioned_AssignImage(in *AssignImage, out *unversioned.AssignImage, s conversion.Scope) error { + return autoConvert_v1alpha1_AssignImage_To_unversioned_AssignImage(in, out, s) +} + +func autoConvert_unversioned_AssignImage_To_v1alpha1_AssignImage(in *unversioned.AssignImage, out *AssignImage, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_unversioned_AssignImage_To_v1alpha1_AssignImage is an autogenerated conversion function. +func Convert_unversioned_AssignImage_To_v1alpha1_AssignImage(in *unversioned.AssignImage, out *AssignImage, s conversion.Scope) error { + return autoConvert_unversioned_AssignImage_To_v1alpha1_AssignImage(in, out, s) +} + +func autoConvert_v1alpha1_AssignImageList_To_unversioned_AssignImageList(in *AssignImageList, out *unversioned.AssignImageList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]unversioned.AssignImage)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha1_AssignImageList_To_unversioned_AssignImageList is an autogenerated conversion function. +func Convert_v1alpha1_AssignImageList_To_unversioned_AssignImageList(in *AssignImageList, out *unversioned.AssignImageList, s conversion.Scope) error { + return autoConvert_v1alpha1_AssignImageList_To_unversioned_AssignImageList(in, out, s) +} + +func autoConvert_unversioned_AssignImageList_To_v1alpha1_AssignImageList(in *unversioned.AssignImageList, out *AssignImageList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]AssignImage)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_unversioned_AssignImageList_To_v1alpha1_AssignImageList is an autogenerated conversion function. +func Convert_unversioned_AssignImageList_To_v1alpha1_AssignImageList(in *unversioned.AssignImageList, out *AssignImageList, s conversion.Scope) error { + return autoConvert_unversioned_AssignImageList_To_v1alpha1_AssignImageList(in, out, s) +} + +func autoConvert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters(in *AssignImageParameters, out *unversioned.AssignImageParameters, s conversion.Scope) error { + out.PathTests = *(*[]unversioned.PathTest)(unsafe.Pointer(&in.PathTests)) + out.AssignDomain = in.AssignDomain + out.AssignPath = in.AssignPath + out.AssignTag = in.AssignTag + return nil +} + +// Convert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters is an autogenerated conversion function. +func Convert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters(in *AssignImageParameters, out *unversioned.AssignImageParameters, s conversion.Scope) error { + return autoConvert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters(in, out, s) +} + +func autoConvert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters(in *unversioned.AssignImageParameters, out *AssignImageParameters, s conversion.Scope) error { + out.PathTests = *(*[]PathTest)(unsafe.Pointer(&in.PathTests)) + out.AssignDomain = in.AssignDomain + out.AssignPath = in.AssignPath + out.AssignTag = in.AssignTag + return nil +} + +// Convert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters is an autogenerated conversion function. +func Convert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters(in *unversioned.AssignImageParameters, out *AssignImageParameters, s conversion.Scope) error { + return autoConvert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters(in, out, s) +} + +func autoConvert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec(in *AssignImageSpec, out *unversioned.AssignImageSpec, s conversion.Scope) error { + out.ApplyTo = *(*[]match.ApplyTo)(unsafe.Pointer(&in.ApplyTo)) + out.Match = in.Match + out.Location = in.Location + if err := Convert_v1alpha1_AssignImageParameters_To_unversioned_AssignImageParameters(&in.Parameters, &out.Parameters, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec is an autogenerated conversion function. +func Convert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec(in *AssignImageSpec, out *unversioned.AssignImageSpec, s conversion.Scope) error { + return autoConvert_v1alpha1_AssignImageSpec_To_unversioned_AssignImageSpec(in, out, s) +} + +func autoConvert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec(in *unversioned.AssignImageSpec, out *AssignImageSpec, s conversion.Scope) error { + out.ApplyTo = *(*[]match.ApplyTo)(unsafe.Pointer(&in.ApplyTo)) + out.Match = in.Match + out.Location = in.Location + if err := Convert_unversioned_AssignImageParameters_To_v1alpha1_AssignImageParameters(&in.Parameters, &out.Parameters, s); err != nil { + return err + } + return nil +} + +// Convert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec is an autogenerated conversion function. +func Convert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec(in *unversioned.AssignImageSpec, out *AssignImageSpec, s conversion.Scope) error { + return autoConvert_unversioned_AssignImageSpec_To_v1alpha1_AssignImageSpec(in, out, s) +} + +func autoConvert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus(in *AssignImageStatus, out *unversioned.AssignImageStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.MutatorPodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus is an autogenerated conversion function. +func Convert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus(in *AssignImageStatus, out *unversioned.AssignImageStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_AssignImageStatus_To_unversioned_AssignImageStatus(in, out, s) +} + +func autoConvert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus(in *unversioned.AssignImageStatus, out *AssignImageStatus, s conversion.Scope) error { + out.ByPod = *(*[]v1beta1.MutatorPodStatusStatus)(unsafe.Pointer(&in.ByPod)) + return nil +} + +// Convert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus is an autogenerated conversion function. +func Convert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus(in *unversioned.AssignImageStatus, out *AssignImageStatus, s conversion.Scope) error { + return autoConvert_unversioned_AssignImageStatus_To_v1alpha1_AssignImageStatus(in, out, s) +} + func autoConvert_v1alpha1_AssignList_To_unversioned_AssignList(in *AssignList, out *unversioned.AssignList, s conversion.Scope) error { out.ListMeta = in.ListMeta out.Items = *(*[]unversioned.Assign)(unsafe.Pointer(&in.Items)) diff --git a/apis/mutations/v1alpha1/zz_generated.deepcopy.go b/apis/mutations/v1alpha1/zz_generated.deepcopy.go index 4ac3428f126..274942c8825 100644 --- a/apis/mutations/v1alpha1/zz_generated.deepcopy.go +++ b/apis/mutations/v1alpha1/zz_generated.deepcopy.go @@ -21,8 +21,8 @@ limitations under the License. package v1alpha1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "k8s.io/apimachinery/pkg/runtime" ) @@ -82,6 +82,131 @@ func (in *AssignField) DeepCopy() *AssignField { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImage) DeepCopyInto(out *AssignImage) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImage. +func (in *AssignImage) DeepCopy() *AssignImage { + if in == nil { + return nil + } + out := new(AssignImage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AssignImage) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageList) DeepCopyInto(out *AssignImageList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AssignImage, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageList. +func (in *AssignImageList) DeepCopy() *AssignImageList { + if in == nil { + return nil + } + out := new(AssignImageList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AssignImageList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageParameters) DeepCopyInto(out *AssignImageParameters) { + *out = *in + if in.PathTests != nil { + in, out := &in.PathTests, &out.PathTests + *out = make([]PathTest, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageParameters. +func (in *AssignImageParameters) DeepCopy() *AssignImageParameters { + if in == nil { + return nil + } + out := new(AssignImageParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageSpec) DeepCopyInto(out *AssignImageSpec) { + *out = *in + if in.ApplyTo != nil { + in, out := &in.ApplyTo, &out.ApplyTo + *out = make([]match.ApplyTo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Match.DeepCopyInto(&out.Match) + in.Parameters.DeepCopyInto(&out.Parameters) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageSpec. +func (in *AssignImageSpec) DeepCopy() *AssignImageSpec { + if in == nil { + return nil + } + out := new(AssignImageSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssignImageStatus) DeepCopyInto(out *AssignImageStatus) { + *out = *in + if in.ByPod != nil { + in, out := &in.ByPod, &out.ByPod + *out = make([]v1beta1.MutatorPodStatusStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssignImageStatus. +func (in *AssignImageStatus) DeepCopy() *AssignImageStatus { + if in == nil { + return nil + } + out := new(AssignImageStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AssignList) DeepCopyInto(out *AssignList) { *out = *in diff --git a/apis/mutations/v1beta1/assign_types.go b/apis/mutations/v1beta1/assign_types.go index db4e6fdd2c9..582055271cf 100644 --- a/apis/mutations/v1beta1/assign_types.go +++ b/apis/mutations/v1beta1/assign_types.go @@ -16,9 +16,9 @@ limitations under the License. package v1beta1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1beta1/assignmetadata_types.go b/apis/mutations/v1beta1/assignmetadata_types.go index e4616db8e69..66275960e29 100644 --- a/apis/mutations/v1beta1/assignmetadata_types.go +++ b/apis/mutations/v1beta1/assignmetadata_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1beta1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/mutations/v1beta1/doc.go b/apis/mutations/v1beta1/doc.go index 1c9681af2ce..9e9820159be 100644 --- a/apis/mutations/v1beta1/doc.go +++ b/apis/mutations/v1beta1/doc.go @@ -1,5 +1,5 @@ // Package v1beta1 includes v1beta1 mutators -// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned -// -external-types=github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1 +// +k8s:conversion-gen=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned +// -external-types=github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1 package v1beta1 diff --git a/apis/mutations/v1beta1/externaldata_types.go b/apis/mutations/v1beta1/externaldata_types.go index 80ed4815f79..bcf42999ccf 100644 --- a/apis/mutations/v1beta1/externaldata_types.go +++ b/apis/mutations/v1beta1/externaldata_types.go @@ -1,7 +1,7 @@ package v1beta1 import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) // ExternalData describes the external data source to use for the mutation. diff --git a/apis/mutations/v1beta1/modifyset_types.go b/apis/mutations/v1beta1/modifyset_types.go index 81a72f0f72e..621fc591b57 100644 --- a/apis/mutations/v1beta1/modifyset_types.go +++ b/apis/mutations/v1beta1/modifyset_types.go @@ -16,8 +16,8 @@ limitations under the License. package v1beta1 import ( - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1beta1/value.go b/apis/mutations/v1beta1/value.go index 3b63b610a65..b14ffd0edb7 100644 --- a/apis/mutations/v1beta1/value.go +++ b/apis/mutations/v1beta1/value.go @@ -1,8 +1,8 @@ package v1beta1 import ( - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type AssignField struct { diff --git a/apis/mutations/v1beta1/zz_generated.conversion.go b/apis/mutations/v1beta1/zz_generated.conversion.go index 6e6963f0e3c..ef91907c361 100644 --- a/apis/mutations/v1beta1/zz_generated.conversion.go +++ b/apis/mutations/v1beta1/zz_generated.conversion.go @@ -22,11 +22,11 @@ package v1beta1 import ( unsafe "unsafe" - unversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - match "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - tester "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - types "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + unversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + match "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + tester "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + types "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/mutations/v1beta1/zz_generated.deepcopy.go b/apis/mutations/v1beta1/zz_generated.deepcopy.go index 071b5f3873e..50ef1e24539 100644 --- a/apis/mutations/v1beta1/zz_generated.deepcopy.go +++ b/apis/mutations/v1beta1/zz_generated.deepcopy.go @@ -21,8 +21,8 @@ limitations under the License. package v1beta1 import ( - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/status/v1beta1/constraintpodstatus_types.go b/apis/status/v1beta1/constraintpodstatus_types.go index e91fca1dfeb..250886b29a4 100644 --- a/apis/status/v1beta1/constraintpodstatus_types.go +++ b/apis/status/v1beta1/constraintpodstatus_types.go @@ -18,8 +18,8 @@ package v1beta1 import ( "strings" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -113,5 +113,5 @@ func KeyForConstraint(id string, constraint *unstructured.Unstructured) (string, // because K8s requires all lowercase letters for resource names kind := strings.ToLower(constraint.GetObjectKind().GroupVersionKind().Kind) name := constraint.GetName() - return dashPacker(id, kind, name) + return DashPacker(id, kind, name) } diff --git a/apis/status/v1beta1/constraintpodstatus_types_test.go b/apis/status/v1beta1/constraintpodstatus_types_test.go index ca7f6be1633..db88a672f71 100644 --- a/apis/status/v1beta1/constraintpodstatus_types_test.go +++ b/apis/status/v1beta1/constraintpodstatus_types_test.go @@ -1,14 +1,13 @@ package v1beta1_test import ( - "strings" "testing" "github.com/google/go-cmp/cmp" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/test/testutils" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -53,7 +52,7 @@ func TestNewConstraintStatusForPod(t *testing.T) { v1beta1.ConstraintNameLabel: "a-constraint", v1beta1.ConstraintKindLabel: "AConstraintKind", v1beta1.PodLabel: podName, - v1beta1.ConstraintTemplateNameLabel: strings.ToLower(cstrKind), + v1beta1.ConstraintTemplateNameLabel: "aconstraintkind", }) err = controllerutil.SetOwnerReference(pod, wantStatus, scheme) diff --git a/apis/status/v1beta1/constrainttemplatepodstatus_types.go b/apis/status/v1beta1/constrainttemplatepodstatus_types.go index 1b9e0e77399..1850ec7de60 100644 --- a/apis/status/v1beta1/constrainttemplatepodstatus_types.go +++ b/apis/status/v1beta1/constrainttemplatepodstatus_types.go @@ -17,8 +17,8 @@ package v1beta1 import ( templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -88,5 +88,5 @@ func NewConstraintTemplateStatusForPod(pod *corev1.Pod, templateName string, sch // KeyForConstraintTemplate returns a unique status object name given the Pod ID and // a template object. func KeyForConstraintTemplate(id string, templateName string) (string, error) { - return dashPacker(id, templateName) + return DashPacker(id, templateName) } diff --git a/apis/status/v1beta1/constrainttemplatepodstatus_types_test.go b/apis/status/v1beta1/constrainttemplatepodstatus_types_test.go index 9a96178cb8a..beff7cf95ce 100644 --- a/apis/status/v1beta1/constrainttemplatepodstatus_types_test.go +++ b/apis/status/v1beta1/constrainttemplatepodstatus_types_test.go @@ -4,10 +4,10 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/test/testutils" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" diff --git a/apis/status/v1beta1/expansiontemplatepodstatus_types.go b/apis/status/v1beta1/expansiontemplatepodstatus_types.go new file mode 100644 index 00000000000..1d7cad6829b --- /dev/null +++ b/apis/status/v1beta1/expansiontemplatepodstatus_types.go @@ -0,0 +1,83 @@ +package v1beta1 + +import ( + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. +type ExpansionTemplatePodStatusStatus struct { + // Important: Run "make" to regenerate code after modifying this file + ID string `json:"id,omitempty"` + TemplateUID types.UID `json:"templateUID,omitempty"` + Operations []string `json:"operations,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + Errors []*ExpansionTemplateError `json:"errors,omitempty"` +} + +// +kubebuilder:object:generate=true + +type ExpansionTemplateError struct { + Type string `json:"type,omitempty"` + Message string `json:"message"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Namespaced + +// ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses API. +type ExpansionTemplatePodStatus struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Status ExpansionTemplatePodStatusStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExpansionTemplatePodStatusList contains a list of ExpansionTemplatePodStatus. +type ExpansionTemplatePodStatusList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExpansionTemplatePodStatus `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExpansionTemplatePodStatus{}, &ExpansionTemplatePodStatusList{}) +} + +// NewExpansionTemplateStatusForPod returns an expansion template status object +// that has been initialized with the bare minimum of fields to make it functional +// with the expansion template status controller. +func NewExpansionTemplateStatusForPod(pod *corev1.Pod, templateName string, scheme *runtime.Scheme) (*ExpansionTemplatePodStatus, error) { + obj := &ExpansionTemplatePodStatus{} + name, err := KeyForExpansionTemplate(pod.Name, templateName) + if err != nil { + return nil, err + } + obj.SetName(name) + obj.SetNamespace(util.GetNamespace()) + obj.Status.ID = pod.Name + obj.Status.Operations = operations.AssignedStringList() + obj.SetLabels(map[string]string{ + ExpansionTemplateNameLabel: templateName, + PodLabel: pod.Name, + }) + + if err := controllerutil.SetOwnerReference(pod, obj, scheme); err != nil { + return nil, err + } + + return obj, nil +} + +// KeyForExpansionTemplate returns a unique status object name given the Pod ID and +// a template object. +func KeyForExpansionTemplate(id string, templateName string) (string, error) { + return DashPacker(id, templateName) +} diff --git a/apis/status/v1beta1/labels.go b/apis/status/v1beta1/labels.go index 9456c8f948f..0f0caca91ce 100644 --- a/apis/status/v1beta1/labels.go +++ b/apis/status/v1beta1/labels.go @@ -2,6 +2,7 @@ package v1beta1 // Label keys used for internal gatekeeper operations. const ( + ExpansionTemplateNameLabel = "internal.gatekeeper.sh/expansiontemplate-name" ConstraintNameLabel = "internal.gatekeeper.sh/constraint-name" ConstraintKindLabel = "internal.gatekeeper.sh/constraint-kind" ConstraintTemplateNameLabel = "internal.gatekeeper.sh/constrainttemplate-name" diff --git a/apis/status/v1beta1/mutatorpodstatus_types.go b/apis/status/v1beta1/mutatorpodstatus_types.go index 83ed175d931..fa13849eee2 100644 --- a/apis/status/v1beta1/mutatorpodstatus_types.go +++ b/apis/status/v1beta1/mutatorpodstatus_types.go @@ -18,9 +18,9 @@ package v1beta1 import ( "strings" - mtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/util" + mtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -113,5 +113,5 @@ func KeyForMutatorID(id string, mID mtypes.ID) (string, error) { // We must do this because K8s requires all lowercase letters for resource names kind := strings.ToLower(mID.Kind) name := mID.Name - return dashPacker(id, kind, name) + return DashPacker(id, kind, name) } diff --git a/apis/status/v1beta1/mutatorpodstatus_types_test.go b/apis/status/v1beta1/mutatorpodstatus_types_test.go index 2a9ab785f27..496a9a7744f 100644 --- a/apis/status/v1beta1/mutatorpodstatus_types_test.go +++ b/apis/status/v1beta1/mutatorpodstatus_types_test.go @@ -4,11 +4,11 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/testhelpers" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/test/testutils" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/testhelpers" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" diff --git a/apis/status/v1beta1/util.go b/apis/status/v1beta1/util.go index 58f1cbd117b..decb0905526 100644 --- a/apis/status/v1beta1/util.go +++ b/apis/status/v1beta1/util.go @@ -32,7 +32,7 @@ func dashExtractor(val string) []string { return tokens } -// dashPacker puts a list of strings into a dash-separated format. Note that +// DashPacker puts a list of strings into a dash-separated format. Note that // it cannot handle empty strings, as that makes the dash separator for the empty // string reduce to an escaped dash. This is fine because none of the packed strings // are allowed to be empty. If this changes in the future, we could create a placeholder @@ -43,17 +43,17 @@ func dashExtractor(val string) []string { // which is also disallowed by the schema (and would require an additional placeholder // character to fix). Finally, note that it is impossible to distinguish between // a nil list of strings and a list of one empty string. -func dashPacker(vals ...string) (string, error) { +func DashPacker(vals ...string) (string, error) { if len(vals) == 0 { - return "", fmt.Errorf("dashPacker cannot pack an empty list of strings") + return "", fmt.Errorf("DashPacker cannot pack an empty list of strings") } b := strings.Builder{} for i, val := range vals { if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") { - return "", fmt.Errorf("dashPacker cannot pack strings that begin or end with a dash: %+v", vals) + return "", fmt.Errorf("DashPacker cannot pack strings that begin or end with a dash: %+v", vals) } if len(val) == 0 { - return "", fmt.Errorf("dashPacker cannot pack empty strings: %v", vals) + return "", fmt.Errorf("DashPacker cannot pack empty strings: %v", vals) } if i != 0 { b.WriteString("-") diff --git a/apis/status/v1beta1/util_test.go b/apis/status/v1beta1/util_test.go index 592b9bd1226..47e4a58db20 100644 --- a/apis/status/v1beta1/util_test.go +++ b/apis/status/v1beta1/util_test.go @@ -91,12 +91,12 @@ var dashingTestCases = []struct { func TestDashPacker(t *testing.T) { for _, tc := range dashingTestCases { t.Run(tc.name, func(t *testing.T) { - gotPacked, err := dashPacker(tc.extracted...) + gotPacked, err := DashPacker(tc.extracted...) if err != nil { t.Fatal(err) } if diff := cmp.Diff(tc.packed, gotPacked); diff != "" { - t.Fatal("got dashPacker(tc.extracted...) != tc.packed, want equal") + t.Fatal("got DashPacker(tc.extracted...) != tc.packed, want equal") } }) } diff --git a/apis/status/v1beta1/zz_generated.deepcopy.go b/apis/status/v1beta1/zz_generated.deepcopy.go index dddc9496679..5a42224d349 100644 --- a/apis/status/v1beta1/zz_generated.deepcopy.go +++ b/apis/status/v1beta1/zz_generated.deepcopy.go @@ -212,6 +212,110 @@ func (in *Error) DeepCopy() *Error { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplateError) DeepCopyInto(out *ExpansionTemplateError) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplateError. +func (in *ExpansionTemplateError) DeepCopy() *ExpansionTemplateError { + if in == nil { + return nil + } + out := new(ExpansionTemplateError) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplatePodStatus) DeepCopyInto(out *ExpansionTemplatePodStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplatePodStatus. +func (in *ExpansionTemplatePodStatus) DeepCopy() *ExpansionTemplatePodStatus { + if in == nil { + return nil + } + out := new(ExpansionTemplatePodStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExpansionTemplatePodStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplatePodStatusList) DeepCopyInto(out *ExpansionTemplatePodStatusList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExpansionTemplatePodStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplatePodStatusList. +func (in *ExpansionTemplatePodStatusList) DeepCopy() *ExpansionTemplatePodStatusList { + if in == nil { + return nil + } + out := new(ExpansionTemplatePodStatusList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExpansionTemplatePodStatusList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpansionTemplatePodStatusStatus) DeepCopyInto(out *ExpansionTemplatePodStatusStatus) { + *out = *in + if in.Operations != nil { + in, out := &in.Operations, &out.Operations + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Errors != nil { + in, out := &in.Errors, &out.Errors + *out = make([]*ExpansionTemplateError, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ExpansionTemplateError) + **out = **in + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpansionTemplatePodStatusStatus. +func (in *ExpansionTemplatePodStatusStatus) DeepCopy() *ExpansionTemplatePodStatusStatus { + if in == nil { + return nil + } + out := new(ExpansionTemplatePodStatusStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatorError) DeepCopyInto(out *MutatorError) { *out = *in diff --git a/apis/syncset/v1alpha1/groupversion_info.go b/apis/syncset/v1alpha1/groupversion_info.go new file mode 100644 index 00000000000..0763852909e --- /dev/null +++ b/apis/syncset/v1alpha1/groupversion_info.go @@ -0,0 +1,20 @@ +// Package v1alpha1 contains API Schema definitions for the SyncSet v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=syncset.gatekeeper.sh +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "syncset.gatekeeper.sh", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/syncset/v1alpha1/syncset_types.go b/apis/syncset/v1alpha1/syncset_types.go new file mode 100644 index 00000000000..d03b53c5bff --- /dev/null +++ b/apis/syncset/v1alpha1/syncset_types.go @@ -0,0 +1,39 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type SyncSetSpec struct { + GVKs []GVKEntry `json:"gvks,omitempty"` +} + +type GVKEntry struct { + Group string `json:"group,omitempty"` + Version string `json:"version,omitempty"` + Kind string `json:"kind,omitempty"` +} + +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:object:root=true + +// SyncSet is the Schema for the SyncSet API. +type SyncSet struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SyncSetSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true + +// SyncSetList contains a list of SyncSet. +type SyncSetList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SyncSet `json:"items"` +} + +func init() { + SchemeBuilder.Register(&SyncSet{}, &SyncSetList{}) +} diff --git a/apis/syncset/v1alpha1/zz_generated.deepcopy.go b/apis/syncset/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..f3e663e93e0 --- /dev/null +++ b/apis/syncset/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,118 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GVKEntry) DeepCopyInto(out *GVKEntry) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GVKEntry. +func (in *GVKEntry) DeepCopy() *GVKEntry { + if in == nil { + return nil + } + out := new(GVKEntry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SyncSet) DeepCopyInto(out *SyncSet) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncSet. +func (in *SyncSet) DeepCopy() *SyncSet { + if in == nil { + return nil + } + out := new(SyncSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SyncSet) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SyncSetList) DeepCopyInto(out *SyncSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SyncSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncSetList. +func (in *SyncSetList) DeepCopy() *SyncSetList { + if in == nil { + return nil + } + out := new(SyncSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SyncSetList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SyncSetSpec) DeepCopyInto(out *SyncSetSpec) { + *out = *in + if in.GVKs != nil { + in, out := &in.GVKs, &out.GVKs + *out = make([]GVKEntry, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncSetSpec. +func (in *SyncSetSpec) DeepCopy() *SyncSetSpec { + if in == nil { + return nil + } + out := new(SyncSetSpec) + in.DeepCopyInto(out) + return out +} diff --git a/build/get-build-commit.sh b/build/get-build-commit.sh deleted file mode 100755 index 5c386553cf3..00000000000 --- a/build/get-build-commit.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -GIT_SHA=$(git rev-parse --short HEAD) - -if [ -z "$(git status --porcelain 2>/dev/null)" ]; then - echo $GIT_SHA -else - echo "$GIT_SHA-dirty" -fi diff --git a/build/get-build-hostname.sh b/build/get-build-hostname.sh deleted file mode 100755 index 0ed5c926ced..00000000000 --- a/build/get-build-hostname.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -hostname -f diff --git a/build/get-build-timestamp.sh b/build/get-build-timestamp.sh deleted file mode 100755 index 8ba5567b6d1..00000000000 --- a/build/get-build-timestamp.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -date -u +"%Y-%m-%dT%H:%M:%SZ" diff --git a/build/tooling/Dockerfile b/build/tooling/Dockerfile index c9815eb6c77..0a8251a4f1f 100644 --- a/build/tooling/Dockerfile +++ b/build/tooling/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19-bullseye +FROM golang:1.21-bullseye@sha256:26c7537d6ac3827eb4638034d16edc64de57bb011c8cc8fe301ac13a6568f6f4 RUN GO111MODULE=on go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.10.0 RUN GO111MODULE=on go install k8s.io/code-generator/cmd/conversion-gen@v0.25.4 diff --git a/build/tooling/vendormanifests.go b/build/tooling/vendormanifests.go new file mode 100644 index 00000000000..9dc075b235f --- /dev/null +++ b/build/tooling/vendormanifests.go @@ -0,0 +1,9 @@ +// This is used for vendoring frameworks to Gatekeeper. + +//go:build tools + +package build + +import ( + _ "github.com/open-policy-agent/frameworks/constraint/deploy" +) diff --git a/build/update-match-schema.sh b/build/update-match-schema.sh new file mode 100755 index 00000000000..14c55a6577a --- /dev/null +++ b/build/update-match-schema.sh @@ -0,0 +1,21 @@ +# This script builds a golang string constant containing the YAML code for the +# Match CRD. This is needed to auto generate the JSONSchemaProps for Match. It +# will parse the YAML for the Match CRD, found in $CRD_FILE, and output to +# $GO_FILE. + +GO_FILE="./pkg/target/matchcrd_constant.go" +SRC_FILE="./pkg/mutation/match/match_types.go" +CRD_FILE="./config/crd/bases/match.gatekeeper.sh_matchcrd.yaml" + +cat << EOF > ${GO_FILE} +package target + +// DO NOT MODIFY THIS FILE DIRECTLY! +// This file is generated from $SRC_FILE via "make manifests". + +const matchYAML = \` +EOF + +# Escape backticks in the yaml, add terminating backtick +cat ${CRD_FILE} | sed "s/\`/\`+\"\`\"+\`/g" >> ${GO_FILE} +echo "\`" >> ${GO_FILE} diff --git a/build/vendormanifests.go b/build/vendormanifests.go deleted file mode 100644 index a5a216e1fcd..00000000000 --- a/build/vendormanifests.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build tools - -package build - -import ( - _ "github.com/open-policy-agent/frameworks/constraint/deploy" -) - diff --git a/charts/gatekeeper/Chart.yaml b/charts/gatekeeper/Chart.yaml index 38a5497d03d..695bff1ac0d 100644 --- a/charts/gatekeeper/Chart.yaml +++ b/charts/gatekeeper/Chart.yaml @@ -4,8 +4,8 @@ name: gatekeeper icon: https://open-policy-agent.github.io/gatekeeper/website/img/logo.svg keywords: - open policy agent -version: 3.12.0-beta.0 +version: 3.14.0 home: https://github.com/open-policy-agent/gatekeeper sources: - https://github.com/open-policy-agent/gatekeeper.git -appVersion: v3.12.0-beta.0 +appVersion: v3.14.0 diff --git a/charts/gatekeeper/README.md b/charts/gatekeeper/README.md index 4278419da1c..fe841a46a52 100644 --- a/charts/gatekeeper/README.md +++ b/charts/gatekeeper/README.md @@ -27,7 +27,8 @@ _See [helm install](https://helm.sh/docs/helm/helm_install/) for command documen ## Upgrade Chart **Upgrading from < v3.4.0** -Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within the chart. This follows Helm 3 Best Practices. +Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within +the chart. This follows Helm 3 Best Practices. Option 1: A simple way to upgrade is to uninstall first and re-install with 3.4.0 or greater. @@ -39,7 +40,9 @@ $ helm install -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper --creat ``` Option 2: -Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the original release, while keeping all of the resources. It then updates the annotations of the resources so that the new chart can import and manage them. +Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the +original release, while keeping all of the resources. It then updates the annotations of the resources so that the new +chart can import and manage them. ```console $ helm_migrate.sh @@ -47,153 +50,178 @@ $ helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper ``` **Upgrading from >= v3.4.0** + ```console $ helm upgrade -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper ``` _See [helm 2 to 3](https://helm.sh/docs/topics/v2_v3_migration/) for Helm 2 migration documentation._ - ## Exempting Namespace -The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during a post-install hook. +The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt +the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during +a post-install hook. -_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more information._ +_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more +information._ ## Parameters -| Parameter | Description | Default | -| :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | -| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | -| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | -| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | -| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | -| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | -| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | -| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | -| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | -| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | -| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | -| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | -| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | -| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | -| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | -| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | -| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | -| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | -| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` -| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | -| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | -| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | -| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | -| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| preUninstall.deleteWebhooks.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | -| preUninstall.deleteWebhooks.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | -| preUninstall.deleteWebhooks.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| preUninstall.deleteWebhooks.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| preUninstall.deleteWebhooks.image.pullSecrets | Image pullSecrets | `[]` | -| preUninstall.deleteWebhooks.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | -| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | -| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | -| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | -| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | -| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| psp.enabled | Enabled PodSecurityPolicy | `true` | -| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | -| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | -| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | -| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | -| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | -| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | -| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | -| auditInterval | The frequency with which audit is run | `60` | -| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | -| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | -| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | -| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | -| disableValidatingWebhook | Disable the validating webhook | `false` | -| disableMutation | Disable mutation | `false` | -| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | -| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | -| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | -| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | -| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | -| enableExternalData | Enable external data | `true` | -| enableGeneratorResourceExpansion | Enable generator resource expansion (alpha feature) | `false` | -| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | -| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | -| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | -| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | -| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | -| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | -| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | -| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| emitAdmissionEvents | Emit K8s events in gatekeeper namespace for admission violations (alpha feature) | `false` | -| emitAuditEvents | Emit K8s events in gatekeeper namespace for audit violations (alpha feature) | `false` | -| logDenies | Log detailed info on each deny | `false` | -| logLevel | Minimum log level | `INFO` | -| image.pullPolicy | The image pull policy | `IfNotPresent` | -| image.repository | Image repository | `openpolicyagent/gatekeeper` | -| image.release | The image release tag to use | Current release version: `v3.12.0-beta.0` | -| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | -| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | -| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | -| affinity | The node affinity to use for pod scheduling | `{}` | -| topologySpreadConstraints | The topology spread constraints to use for pod scheduling | `[]` | -| tolerations | The tolerations to use for pod scheduling | `[]` | -| controllerManager.healthPort | Health port for controller manager | `9090` | -| controllerManager.port | Webhook-server port for controller manager | `8443` | -| controllerManager.metricsPort | Metrics port for controller manager | `8888` | -| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | -| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | -| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` -| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | -| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | -| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | -| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | -| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | -| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | -| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | -| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | -| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | -| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | -| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | -| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | -| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| audit.healthPort | Health port for audit | `9090` | -| audit.metricsPort | Metrics port for audit | `8888` | -| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | -| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | -| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` -| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | -| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | -| podLabels | The labels to add to the Gatekeeper pods | `{}` | -| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | -| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | -| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | -| service.type | Service type | `ClusterIP` | -| service.loadBalancerIP | The IP address of LoadBalancer service | `` | -| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | -| rbac.create | Enable the creation of RBAC resources | `true` | -| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | -| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| Parameter | Description | Default | +|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | +| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | +| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | +| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | +| postInstall.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label Job | `` | +| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | +| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | +| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | +| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | +| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | +| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | +| postInstall.probeWebhook.priorityClassName | Priority class name for gatekeeper-probe-webhook-post-install Job | `` | +| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | +| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | +| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | +| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | +| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | +| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | +| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | +| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postUpgrade.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label-post-upgrade Job | `` | +| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | +| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | +| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | +| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | +| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| preInstall.crdRepository.image.repository | Image with kubectl to update the CRDs. If not set, the `image.crdRepository` is used instead. | `null` | +| preInstall.crdRepository.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | +| preUninstall.deleteWebhookConfigurations.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | +| preUninstall.deleteWebhookConfigurations.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| preUninstall.deleteWebhookConfigurations.image.pullSecrets | Image pullSecrets | `[]` | +| preUninstall.deleteWebhookConfigurations.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | +| preUninstall.deleteWebhookConfigurations.priorityClassName | Priority class name for gatekeeper-delete-webhook-configs Job | `` | +| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | +| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | +| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | +| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | +| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| psp.enabled | Enabled PodSecurityPolicy | `true` | +| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | +| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | +| upgradeCRDs.priorityClassName | Priority class name for gatekeeper-update-crds-hook Job | `` | +| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | +| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | +| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | +| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | +| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | +| auditInterval | The frequency with which audit is run | `60` | +| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | +| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | +| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | +| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | +| disableValidatingWebhook | Disable the validating webhook | `false` | +| disableMutation | Disable mutation | `false` | +| validatingWebhookName | The name of the `ValidatingWebhookConfiguration` | `gatekeeper-validating-webhook-configuration` | +| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | +| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | +| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | +| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | +| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| validatingWebhookURL | Custom URL for Kubernetes API server to use to reach the validating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | +| enableExternalData | Enable external data | `true` | +| enableGeneratorResourceExpansion | Enable generator resource expansion (beta feature) | `true` | +| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | +| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | +| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | +| mutatingWebhookName | The name of the `MutatingWebhookConfiguration` | `gatekeeper-mutating-webhook-configuration` | +| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | +| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | +| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | +| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | +| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| mutatingWebhookURL | Custom URL for Kubernetes API server to use to reach the mutating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| emitAdmissionEvents | Emit K8s events in configurable namespace for admission violations (alpha feature) | `false` | +| emitAuditEvents | Emit K8s events in configurable namespace for audit violations (alpha feature) | `false` | +| auditEventsInvolvedNamespace | Emit audit events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Audit events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| admissionEventsInvolvedNamespace | Emit admission events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Admission events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| logDenies | Log detailed info on each deny | `false` | +| logLevel | Minimum log level | `INFO` | +| image.pullPolicy | The image pull policy | `IfNotPresent` | +| image.repository | Image repository | `openpolicyagent/gatekeeper` | +| image.release | The image release tag to use | Current release version: `v3.14.0` | +| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | +| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | +| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | +| controllerManager.affinity | The node affinity to use for controller manager pod scheduling | `{}` | +| controllerManager.topologySpreadConstraints | The topology spread constraints to use for controller manager pod scheduling | `[]` | +| controllerManager.tolerations | The tolerations to use for controller manager pod scheduling | `[]` | +| controllerManager.healthPort | Health port for controller manager | `9090` | +| controllerManager.port | Webhook-server port for controller manager | `8443` | +| controllerManager.metricsPort | Metrics port for controller manager | `8888` | +| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | +| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | +| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` | +| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | +| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | +| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | +| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | +| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | +| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | +| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | +| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | +| controllerManager.networkPolicy.enabled | Should a network policy for the controller manager be created | `false` | +| controllerManager.networkPolicy.ingress | Additional ingress rules to be added to the controller manager network policy | `{}` | +| controllerManager.strategyType | The strategy type to use for Controller Manager deployment | `RollingUpdate` | +| audit.affinity | The node affinity to use for audit pod scheduling | `{}` | +| audit.topologySpreadConstraints | The topology spread constraints to use for audit pod scheduling | `[]` | +| audit.tolerations | The tolerations to use for audit pod scheduling | `[]` | +| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | +| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | +| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | +| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | +| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| audit.healthPort | Health port for audit | `9090` | +| audit.metricsPort | Metrics port for audit | `8888` | +| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | +| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | +| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` | +| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | +| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | +| podLabels | The labels to add to the Gatekeeper pods | `{}` | +| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | +| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | +| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | +| service.type | Service type | `ClusterIP` | +| service.loadBalancerIP | The IP address of LoadBalancer service | `` | +| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | +| rbac.create | Enable the creation of RBAC resources | `true` | +| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | +| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| externaldataProviderResponseCacheTTL | TTL for the external data provider response cache. Specify the duration in 'h', 'm', or 's' for hours, minutes, or seconds respectively. | `3m` | ## Contributing Changes -Please refer to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) for modifying the Helm chart. +Please refer +to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) +for modifying the Helm chart. diff --git a/charts/gatekeeper/crds/assign-customresourcedefinition.yaml b/charts/gatekeeper/crds/assign-customresourcedefinition.yaml index ce98648baff..0221a194812 100644 --- a/charts/gatekeeper/crds/assign-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/assign-customresourcedefinition.yaml @@ -65,7 +65,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -115,7 +115,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -151,7 +151,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -310,7 +310,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -360,7 +360,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -396,7 +396,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -555,7 +555,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -605,7 +605,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -641,7 +641,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml b/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml new file mode 100644 index 00000000000..197f2f17933 --- /dev/null +++ b/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml @@ -0,0 +1,237 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: assignimage.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignImage + listKind: AssignImageList + plural: assignimage + singular: assignimage + preserveUnknownFields: false + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignImage is the Schema for the assignimage API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + properties: + name: + maxLength: 63 + type: string + type: object + spec: + description: AssignImageSpec defines the desired state of AssignImage. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. This is necessary because every mutation implies part of an object schema and object schemas are associated with specific GVKs. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + description: 'Location describes the path to be mutated, for example: `spec.containers[name: main].image`.' + type: string + match: + description: Match allows the user to limit which resources get mutated. Individual match criteria are AND-ed together. An undefined match criteria matches everything. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and kinds fields that list the groups/kinds of objects to which the mutation will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions from both sections are ANDed to determine if an object meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources are matched. Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of `Generated` will only match generated resources, while `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + parameters: + description: Parameters define the behavior of the mutator. + properties: + assignDomain: + description: AssignDomain sets the domain component on an image string. The trailing slash should not be included. + type: string + assignPath: + description: AssignPath sets the domain component on an image string. + type: string + assignTag: + description: AssignImage sets the image component on an image string. It must start with a `:` or `@`. + type: string + pathTests: + items: + description: "PathTest allows the user to customize how the mutation works if parent paths are missing. It traverses the list in order. All sub paths are tested against the provided condition, if the test fails, the mutation is not applied. All `subPath` entries must be a prefix of `location`. Any glob characters will take on the same value as was used to expand the matching glob in `location`. \n Available Tests: * MustExist - the path must exist or do not mutate * MustNotExist - the path must not exist or do not mutate." + properties: + condition: + description: Condition describes whether the path either MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignImageStatus defines the observed state of AssignImage. + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus. + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while adding a mutator to a system. + properties: + message: + type: string + type: + description: Type indicates a specific class of error for use by controller code. If not present, the error should be treated as not matching any known type. + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such as when a mutator has been recreated after its CRD was deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml b/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml index 3a63eef3cb3..65c17ed3ae1 100644 --- a/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml @@ -39,13 +39,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -95,7 +95,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -131,7 +131,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -250,13 +250,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -306,7 +306,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -342,7 +342,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -461,13 +461,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -517,7 +517,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -553,7 +553,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/charts/gatekeeper/crds/config-customresourcedefinition.yaml b/charts/gatekeeper/crds/config-customresourcedefinition.yaml index 57826ac09aa..269ca95f9a2 100644 --- a/charts/gatekeeper/crds/config-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/config-customresourcedefinition.yaml @@ -39,7 +39,7 @@ spec: excludedNamespaces: items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array processes: diff --git a/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml b/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml index a4da4e9e90f..737e3aff15b 100644 --- a/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: constrainttemplates.templates.gatekeeper.sh @@ -61,6 +61,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -156,6 +174,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -251,6 +287,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string diff --git a/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml b/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml index 042249cf102..9d248f2ccd2 100644 --- a/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml @@ -68,6 +68,133 @@ spec: description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template type: string type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object type: object served: true storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplate is the Schema for the ExpansionTemplate API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExpansionTemplateSpec defines the desired state of ExpansionTemplate. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds of generator resources which will be expanded. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + enforcementAction: + description: EnforcementAction specifies the enforcement action to be used for resources matching the ExpansionTemplate. Specifying an empty value will use the enforcement action specified by the Constraint in violation. + type: string + generatedGVK: + description: GeneratedGVK specifies the GVK of the resources which the generator resource creates. + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + templateSource: + description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template + type: string + type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} diff --git a/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml b/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml new file mode 100644 index 00000000000..8f49b4c5f7f --- /dev/null +++ b/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml @@ -0,0 +1,62 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: expansiontemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ExpansionTemplatePodStatus + listKind: ExpansionTemplatePodStatusList + plural: expansiontemplatepodstatuses + singular: expansiontemplatepodstatus + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: object + served: true + storage: true diff --git a/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml b/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml index 1bb1933366d..46574fd369f 100644 --- a/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml @@ -65,7 +65,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -115,7 +115,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -151,7 +151,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -283,7 +283,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -333,7 +333,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -369,7 +369,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -501,7 +501,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -551,7 +551,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -587,7 +587,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/charts/gatekeeper/crds/provider-customresourcedefinition.yaml b/charts/gatekeeper/crds/provider-customresourcedefinition.yaml index 0deb6f630b1..95e66a8b8aa 100644 --- a/charts/gatekeeper/crds/provider-customresourcedefinition.yaml +++ b/charts/gatekeeper/crds/provider-customresourcedefinition.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: providers.externaldata.gatekeeper.sh @@ -41,12 +41,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: true + storage: false - name: v1beta1 schema: openAPIV3Schema: @@ -70,9 +70,9 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: false + storage: true diff --git a/charts/gatekeeper/templates/_helpers.tpl b/charts/gatekeeper/templates/_helpers.tpl index 5ab6fe2b456..785d9912656 100644 --- a/charts/gatekeeper/templates/_helpers.tpl +++ b/charts/gatekeeper/templates/_helpers.tpl @@ -36,10 +36,44 @@ Adds additional pod labels to the common ones */}} {{- define "gatekeeper.podLabels" -}} {{- if .Values.podLabels }} -{{- toYaml .Values.podLabels | nindent 8 }} +{{- toYaml .Values.podLabels }} {{- end }} {{- end -}} +{{/* +Mandatory labels +*/}} +{{- define "gatekeeper.mandatoryLabels" -}} +app: {{ include "gatekeeper.name" . }} +chart: {{ include "gatekeeper.name" . }} +gatekeeper.sh/system: "yes" +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "gatekeeper.commonLabels" -}} +helm.sh/chart: {{ include "gatekeeper.chart" . }} +{{ include "gatekeeper.selectorLabels" . }} +{{- if .Chart.Version }} +app.kubernetes.io/version: {{ .Chart.Version | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels }} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "gatekeeper.selectorLabels" -}} +app.kubernetes.io/name: {{ include "gatekeeper.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + {{/* Output post install webhook probe container entry */}} @@ -47,10 +81,12 @@ Output post install webhook probe container entry - name: webhook-probe-post image: "{{ .Values.postInstall.probeWebhook.image.repository }}:{{ .Values.postInstall.probeWebhook.image.tag }}" imagePullPolicy: {{ .Values.postInstall.probeWebhook.image.pullPolicy }} - args: + command: - "curl" + args: - "--retry" - "99999" + - "--retry-connrefused" - "--retry-max-time" - "{{ .Values.postInstall.probeWebhook.waitTimeout }}" - "--retry-delay" diff --git a/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml b/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml index 398b1460077..8c02264b024 100644 --- a/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml +++ b/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml @@ -5,11 +5,8 @@ metadata: annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} name: gatekeeper-admin spec: allowPrivilegeEscalation: false diff --git a/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml b/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml index 3409d2f588e..1dc1ebac29c 100644 --- a/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml +++ b/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml @@ -13,6 +13,7 @@ metadata: namespace: '{{ .Release.Namespace }}' spec: replicas: 1 + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} selector: matchLabels: app: '{{ template "gatekeeper.name" . }}' @@ -28,6 +29,9 @@ spec: {{- if .Values.podAnnotations }} {{- toYaml .Values.podAnnotations | trim | nindent 8 }} {{- end }} + {{- if .Values.auditPodAnnotations }} + {{- toYaml .Values.auditPodAnnotations | trim | nindent 8 }} + {{- end }} labels: {{- include "gatekeeper.podLabels" . }} app: '{{ template "gatekeeper.name" . }}' @@ -51,12 +55,20 @@ spec: - --audit-interval={{ .Values.auditInterval }} - --log-level={{ (.Values.audit.logLevel | empty | not) | ternary .Values.audit.logLevel .Values.logLevel }} - --constraint-violations-limit={{ .Values.constraintViolationsLimit }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} - --audit-from-cache={{ .Values.auditFromCache }} - --audit-chunk-size={{ .Values.auditChunkSize }} - --audit-match-kind-only={{ .Values.auditMatchKindOnly }} - --emit-audit-events={{ .Values.emitAuditEvents }} + - --audit-events-involved-namespace={{ .Values.auditEventsInvolvedNamespace }} - --operation=audit - --operation=status + {{ if .Values.audit.enablePubsub}} + - --enable-pub-sub={{ .Values.audit.enablePubsub }} + - --audit-connection={{ .Values.audit.connection }} + - --audit-channel={{ .Values.audit.channel }} + {{- end }} {{ if not .Values.disableMutation}}- --operation=mutation-status{{- end }} - --logtostderr - --health-addr=:{{ .Values.audit.healthPort }} @@ -67,7 +79,12 @@ spec: {{- range .Values.metricsBackends}} - --metrics-backend={{ . }} {{- end }} + + {{- if .Values.audit.logFile}} + - --log-file={{ .Values.audit.logFile }} + {{- end }} - --disable-cert-rotation={{ or .Values.audit.disableCertRotation .Values.externalCertInjection.enabled }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} command: - /manager env: diff --git a/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml b/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml index ebb1d2559e9..70c7571c2ce 100644 --- a/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml +++ b/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml @@ -13,6 +13,7 @@ metadata: namespace: '{{ .Release.Namespace }}' spec: replicas: {{ .Values.replicas }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} selector: matchLabels: app: '{{ template "gatekeeper.name" . }}' @@ -22,6 +23,8 @@ spec: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' + strategy: + type: {{ .Values.controllerManager.strategyType }} template: metadata: annotations: @@ -54,6 +57,7 @@ spec: - --logtostderr - --log-denies={{ .Values.logDenies }} - --emit-admission-events={{ .Values.emitAdmissionEvents }} + - --admission-events-involved-namespace={{ .Values.admissionEventsInvolvedNamespace }} - --log-level={{ (.Values.controllerManager.logLevel | empty | not) | ternary .Values.controllerManager.logLevel .Values.logLevel }} - --exempt-namespace={{ .Release.Namespace }} - --operation=webhook @@ -64,6 +68,9 @@ spec: - --disable-cert-rotation={{ .Values.controllerManager.disableCertRotation }} - --max-serving-threads={{ .Values.maxServingThreads }} - --tls-min-version={{ .Values.controllerManager.tlsMinVersion }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} {{ if ne .Values.controllerManager.clientCertName "" }}- --client-cert-name={{ .Values.controllerManager.clientCertName }}{{- end }} {{- range .Values.metricsBackends}} @@ -83,6 +90,14 @@ spec: {{- range .Values.controllerManager.exemptNamespacePrefixes}} - --exempt-namespace-prefix={{ . }} {{- end }} + + {{- range .Values.controllerManager.exemptNamespaceSuffixes}} + - --exempt-namespace-suffix={{ . }} + {{- end }} + + {{- if .Values.controllerManager.logFile}} + - --log-file={{ .Values.controllerManager.logFile }} + {{- end }} command: - /manager env: diff --git a/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml b/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml new file mode 100644 index 00000000000..5ac3ca6c2c6 --- /dev/null +++ b/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml @@ -0,0 +1,26 @@ +{{- if .Values.controllerManager.networkPolicy.enabled -}} +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + labels: + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} + name: gatekeeper-controller-manager +spec: + ingress: + - from: + - podSelector: + matchLabels: + {{- include "gatekeeper.commonLabels" . | nindent 14 }} + app: '{{ template "gatekeeper.name" . }}' + release: '{{ .Release.Name }}' + {{- with .Values.controllerManager.networkPolicy.ingress }} + {{- toYaml . | nindent 4 }} + {{- end }} + podSelector: + matchLabels: + {{- include "gatekeeper.mandatoryLabels" . | nindent 6 }} + {{- include "gatekeeper.commonLabels" . | nindent 6 }} + control-plane: controller-manager + gatekeeper.sh/operation: webhook +{{- end -}} diff --git a/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml b/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml index 8b32f96014b..3e55923360c 100644 --- a/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml +++ b/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml @@ -11,6 +11,13 @@ metadata: release: '{{ .Release.Name }}' name: gatekeeper-manager-role rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - '*' resources: @@ -22,7 +29,7 @@ rules: - apiGroups: - admissionregistration.k8s.io resourceNames: - - gatekeeper-mutating-webhook-configuration + - {{ .Values.mutatingWebhookName }} resources: - mutatingwebhookconfigurations verbs: @@ -75,6 +82,18 @@ rules: - patch - update - watch +- apiGroups: + - expansion.gatekeeper.sh + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - externaldata.gatekeeper.sh resources: @@ -153,7 +172,7 @@ rules: - apiGroups: - admissionregistration.k8s.io resourceNames: - - gatekeeper-validating-webhook-configuration + - {{ .Values.validatingWebhookName }} resources: - validatingwebhookconfigurations verbs: diff --git a/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml b/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml index 30a23b4fb9d..ae85f8d08d3 100644 --- a/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml +++ b/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml @@ -9,16 +9,20 @@ metadata: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' - name: gatekeeper-mutating-webhook-configuration + name: '{{ .Values.mutatingWebhookName }}' webhooks: - admissionReviewVersions: - v1 - v1beta1 clientConfig: + {{- if .Values.mutatingWebhookURL }} + url: https://{{ .Values.mutatingWebhookURL }}/v1/mutate + {{- else }} service: name: gatekeeper-webhook-service namespace: '{{ .Release.Namespace }}' path: /v1/mutate + {{- end }} failurePolicy: {{ .Values.mutatingWebhookFailurePolicy }} matchPolicy: Exact name: mutation.gatekeeper.sh diff --git a/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml b/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml index a51dcef6bd6..933fbbd3c3e 100644 --- a/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml +++ b/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml @@ -9,16 +9,20 @@ metadata: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' - name: gatekeeper-validating-webhook-configuration + name: '{{ .Values.validatingWebhookName }}' webhooks: - admissionReviewVersions: - v1 - v1beta1 clientConfig: + {{- if .Values.validatingWebhookURL }} + url: https://{{ .Values.validatingWebhookURL }}/v1/admit + {{- else }} service: name: gatekeeper-webhook-service namespace: '{{ .Release.Namespace }}' path: /v1/admit + {{- end }} failurePolicy: {{ .Values.validatingWebhookFailurePolicy }} matchPolicy: Exact name: validation.gatekeeper.sh diff --git a/charts/gatekeeper/templates/namespace-post-install.yaml b/charts/gatekeeper/templates/namespace-post-install.yaml index 4f84b52b409..41232de4267 100644 --- a/charts/gatekeeper/templates/namespace-post-install.yaml +++ b/charts/gatekeeper/templates/namespace-post-install.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -22,14 +20,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure + {{- if .Values.postInstall.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postInstall.labelNamespace.priorityClassName }} + {{- end }} {{- if .Values.postInstall.labelNamespace.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} @@ -96,7 +94,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -110,6 +110,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -141,6 +142,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/charts/gatekeeper/templates/namespace-post-upgrade.yaml b/charts/gatekeeper/templates/namespace-post-upgrade.yaml index 43a1dadd9fa..b26abab34e0 100644 --- a/charts/gatekeeper/templates/namespace-post-upgrade.yaml +++ b/charts/gatekeeper/templates/namespace-post-upgrade.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label-post-upgrade + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-upgrade "helm.sh/hook-weight": "-5" @@ -20,12 +18,9 @@ spec: template: metadata: labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.postUpgrade.labelNamespace.image.pullSecrets }} @@ -33,6 +28,9 @@ spec: {{- .Values.postUpgrade.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-update-namespace-label-post-upgrade + {{- if .Values.postUpgrade.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postUpgrade.labelNamespace.priorityClassName }} + {{- end }} containers: - name: kubectl-label image: "{{ .Values.postUpgrade.labelNamespace.image.repository }}:{{ .Values.postUpgrade.labelNamespace.image.tag }}" @@ -89,6 +87,7 @@ kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -102,6 +101,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -130,6 +130,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/charts/gatekeeper/templates/probe-webhook-post-install.yaml b/charts/gatekeeper/templates/probe-webhook-post-install.yaml index 5a140d31ce0..e6ef25b594c 100644 --- a/charts/gatekeeper/templates/probe-webhook-post-install.yaml +++ b/charts/gatekeeper/templates/probe-webhook-post-install.yaml @@ -5,11 +5,8 @@ kind: Job metadata: name: gatekeeper-probe-webhook-post-install labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -20,14 +17,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: Never + {{- if .Values.postInstall.probeWebhook.priorityClassName }} + priorityClassName: {{ .Values.postInstall.probeWebhook.priorityClassName }} + {{- end }} {{- if .Values.postInstall.probeWebhook.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.probeWebhook.image.pullSecrets | toYaml | nindent 12 }} @@ -44,5 +41,6 @@ spec: nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} {{- end }} + backoffLimit: 3 {{- end }} {{- end }} diff --git a/charts/gatekeeper/templates/upgrade-crds-hook.yaml b/charts/gatekeeper/templates/upgrade-crds-hook.yaml index cd57573f37a..f9347ad9c7b 100644 --- a/charts/gatekeeper/templates/upgrade-crds-hook.yaml +++ b/charts/gatekeeper/templates/upgrade-crds-hook.yaml @@ -5,6 +5,7 @@ kind: ClusterRole metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -26,6 +27,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -46,6 +48,7 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} name: gatekeeper-admin-upgrade-crds @@ -61,29 +64,23 @@ metadata: name: gatekeeper-update-crds-hook namespace: {{ .Release.Namespace }} labels: - app: {{ template "gatekeeper.name" . }} - chart: {{ template "gatekeeper.name" . }} - gatekeeper.sh/system: "yes" - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: helm.sh/hook: pre-install,pre-upgrade helm.sh/hook-weight: "1" helm.sh/hook-delete-policy: "hook-succeeded,before-hook-creation" spec: - backoffLimit: 0 + backoffLimit: 3 template: metadata: name: gatekeeper-update-crds-hook annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: serviceAccountName: gatekeeper-admin-upgrade-crds restartPolicy: Never @@ -91,12 +88,23 @@ spec: imagePullSecrets: {{- toYaml .Values.image.pullSecrets | nindent 8 }} {{- end }} + {{- if .Values.upgradeCRDs.priorityClassName }} + priorityClassName: {{ .Values.upgradeCRDs.priorityClassName }} + {{- end }} containers: - name: crds-upgrade - {{- if not .Values.image.release }} - image: '{{ .Values.image.crdRepository }}' + {{- if .Values.preInstall.crdRepository.image.repository }} + {{- if not .Values.preInstall.crdRepository.image.tag }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}' + {{- else }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}:{{ .Values.preInstall.crdRepository.image.tag }}' + {{- end }} {{- else }} + {{- if not .Values.image.release }} + image: '{{ .Values.image.crdRepository }}' + {{- else }} image: '{{ .Values.image.crdRepository }}:{{ .Values.image.release }}' + {{- end }} {{- end }} imagePullPolicy: '{{ .Values.image.pullPolicy }}' args: diff --git a/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml b/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml index d610394de36..fb359b87e16 100644 --- a/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml +++ b/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": pre-delete "helm.sh/hook-weight": "-5" @@ -19,12 +17,9 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets }} @@ -32,6 +27,9 @@ spec: {{- .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-delete-webhook-configs + {{- if .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + priorityClassName: {{ .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + {{- end }} containers: - name: kubectl-delete image: "{{ .Values.preUninstall.deleteWebhookConfigurations.image.repository }}:{{ .Values.preUninstall.deleteWebhookConfigurations.image.tag }}" @@ -39,19 +37,19 @@ spec: args: - delete {{- if not .Values.disableValidatingWebhook }} - - validatingwebhookconfiguration/gatekeeper-validating-webhook-configuration + - validatingwebhookconfiguration/{{ .Values.validatingWebhookName }} {{- end }} {{- if not .Values.disableMutation }} - - mutatingwebhookconfiguration/gatekeeper-mutating-webhook-configuration + - mutatingwebhookconfiguration/{{ .Values.mutatingWebhookName }} {{- end }} resources: - {{- toYaml .Values.preUninstall.resources | nindent 10 }} + {{- toYaml .Values.preUninstall.resources | nindent 12 }} securityContext: {{- if .Values.enableRuntimeDefaultSeccompProfile }} seccompProfile: type: RuntimeDefault {{- end }} - {{- toYaml .Values.preUninstall.securityContext | nindent 10 }} + {{- toYaml .Values.preUninstall.securityContext | nindent 12 }} {{- with .Values.preUninstall }} nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} @@ -65,7 +63,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -79,6 +79,7 @@ kind: ClusterRole metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -92,7 +93,7 @@ rules: resources: - validatingwebhookconfigurations resourceNames: - - gatekeeper-validating-webhook-configuration + - {{ .Values.validatingWebhookName }} verbs: - delete {{- end }} @@ -102,7 +103,7 @@ rules: resources: - mutatingwebhookconfigurations resourceNames: - - gatekeeper-mutating-webhook-configuration + - {{ .Values.mutatingWebhookName }} verbs: - delete {{- end }} @@ -117,6 +118,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/charts/gatekeeper/values.yaml b/charts/gatekeeper/values.yaml index 823dc06f364..2e4c3a8666f 100644 --- a/charts/gatekeeper/values.yaml +++ b/charts/gatekeeper/values.yaml @@ -1,4 +1,5 @@ replicas: 3 +revisionHistoryLimit: 10 auditInterval: 60 metricsBackends: ["prometheus"] auditMatchKindOnly: false @@ -6,6 +7,7 @@ constraintViolationsLimit: 20 auditFromCache: false disableMutation: false disableValidatingWebhook: false +validatingWebhookName: gatekeeper-validating-webhook-configuration validatingWebhookTimeoutSeconds: 3 validatingWebhookFailurePolicy: Ignore validatingWebhookAnnotations: {} @@ -13,11 +15,13 @@ validatingWebhookExemptNamespacesLabels: {} validatingWebhookObjectSelector: {} validatingWebhookCheckIgnoreFailurePolicy: Fail validatingWebhookCustomRules: {} +validatingWebhookURL: null enableDeleteOperations: false enableExternalData: true -enableGeneratorResourceExpansion: false +enableGeneratorResourceExpansion: true enableTLSHealthcheck: false maxServingThreads: -1 +mutatingWebhookName: gatekeeper-mutating-webhook-configuration mutatingWebhookFailurePolicy: Ignore mutatingWebhookReinvocationPolicy: Never mutatingWebhookAnnotations: {} @@ -25,6 +29,7 @@ mutatingWebhookExemptNamespacesLabels: {} mutatingWebhookObjectSelector: {} mutatingWebhookTimeoutSeconds: 1 mutatingWebhookCustomRules: {} +mutatingWebhookURL: null mutationAnnotations: false auditChunkSize: 500 logLevel: INFO @@ -32,13 +37,27 @@ logDenies: false logMutations: false emitAdmissionEvents: false emitAuditEvents: false +admissionEventsInvolvedNamespace: false +auditEventsInvolvedNamespace: false resourceQuota: true +externaldataProviderResponseCacheTTL: 3m +image: + repository: openpolicyagent/gatekeeper + crdRepository: openpolicyagent/gatekeeper-crds + release: v3.14.0 + pullPolicy: IfNotPresent + pullSecrets: [] +preInstall: + crdRepository: + image: + repository: null + tag: v3.14.0 postUpgrade: labelNamespace: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -49,6 +68,7 @@ postUpgrade: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -68,7 +88,7 @@ postInstall: extraRules: [] image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -79,6 +99,7 @@ postInstall: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" probeWebhook: enabled: true image: @@ -89,6 +110,7 @@ postInstall: waitTimeout: 60 httpTimeout: 2 insecureHTTPS: false + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -107,9 +129,10 @@ preUninstall: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -123,13 +146,8 @@ preUninstall: runAsGroup: 999 runAsNonRoot: true runAsUser: 1000 -image: - repository: openpolicyagent/gatekeeper - crdRepository: openpolicyagent/gatekeeper-crds - release: v3.12.0-beta.0 - pullPolicy: IfNotPresent - pullSecrets: [] podAnnotations: {} +auditPodAnnotations: {} podLabels: {} podCountLimit: "100" secretAnnotations: {} @@ -146,8 +164,9 @@ controllerManager: livenessTimeout: 1 priorityClassName: system-cluster-critical disableCertRotation: false - tlsMinVersion: 1.3 + tlsMinVersion: 1.2 clientCertName: "" + strategyType: RollingUpdate affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -183,7 +202,14 @@ controllerManager: supplementalGroups: - 999 extraRules: [] + networkPolicy: + enabled: false + ingress: { } + # - from: + # - ipBlock: + # cidr: 0.0.0.0/0 audit: + enablePubsub: false hostNetwork: false dnsPolicy: ClusterFirst metricsPort: 8888 @@ -191,7 +217,7 @@ audit: readinessTimeout: 1 livenessTimeout: 1 priorityClassName: system-cluster-critical - disableCertRotation: true + disableCertRotation: false affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -240,6 +266,7 @@ psp: upgradeCRDs: enabled: true extraRules: [] + priorityClassName: "" rbac: create: true externalCertInjection: diff --git a/cmd/build/helmify/kustomization.yaml b/cmd/build/helmify/kustomization.yaml index 2d94aad7994..1c1943f2874 100644 --- a/cmd/build/helmify/kustomization.yaml +++ b/cmd/build/helmify/kustomization.yaml @@ -34,18 +34,36 @@ patchesJson6902: kind: CustomResourceDefinition name: mutatorpodstatuses.status.gatekeeper.sh path: labels_patch.yaml + - target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: expansiontemplatepodstatuses.status.gatekeeper.sh + path: labels_patch.yaml - target: group: apiextensions.k8s.io version: v1 kind: CustomResourceDefinition name: configs.config.gatekeeper.sh path: labels_patch.yaml + - target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: syncsets.syncset.gatekeeper.sh + path: labels_patch.yaml - target: group: apiextensions.k8s.io version: v1 kind: CustomResourceDefinition name: assignmetadata.mutations.gatekeeper.sh path: labels_patch.yaml + - target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: assignimage.mutations.gatekeeper.sh + path: labels_patch.yaml - target: group: apiextensions.k8s.io version: v1 @@ -131,3 +149,24 @@ patchesJson6902: patch: |- - op: remove path: /spec/ports + - target: + kind: ValidatingWebhookConfiguration + name: gatekeeper-validating-webhook-configuration + patch: |- + - op: replace + path: /metadata/name + value: "{{ .Values.validatingWebhookName }}" + - op: replace + path: /webhooks/0/clientConfig + value: { "HELMSUBST_VALIDATING_WEBHOOK_CLIENT_CONFIG": "" } + - target: + kind: MutatingWebhookConfiguration + name: gatekeeper-mutating-webhook-configuration + patch: |- + - op: replace + path: /metadata/name + value: "{{ .Values.mutatingWebhookName }}" + - op: replace + path: /webhooks/0/clientConfig + value: { "HELMSUBST_MUTATING_WEBHOOK_CLIENT_CONFIG": "" } + diff --git a/cmd/build/helmify/kustomize-for-helm.yaml b/cmd/build/helmify/kustomize-for-helm.yaml index 25ae92cf597..bd8847ac979 100644 --- a/cmd/build/helmify/kustomize-for-helm.yaml +++ b/cmd/build/helmify/kustomize-for-helm.yaml @@ -62,6 +62,9 @@ metadata: namespace: gatekeeper-system spec: replicas: HELMSUBST_DEPLOYMENT_REPLICAS + revisionHistoryLimit: HELMSUBST_DEPLOYMENT_REVISION_HISTORY_LIMIT + strategy: + type: HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_STRATEGY_TYPE template: metadata: annotations: @@ -76,6 +79,7 @@ spec: - --logtostderr - --log-denies={{ .Values.logDenies }} - --emit-admission-events={{ .Values.emitAdmissionEvents }} + - --admission-events-involved-namespace={{ .Values.admissionEventsInvolvedNamespace }} - --log-level={{ (.Values.controllerManager.logLevel | empty | not) | ternary .Values.controllerManager.logLevel .Values.logLevel }} - --exempt-namespace={{ .Release.Namespace }} - --operation=webhook @@ -86,6 +90,9 @@ spec: - --disable-cert-rotation={{ .Values.controllerManager.disableCertRotation }} - --max-serving-threads={{ .Values.maxServingThreads }} - --tls-min-version={{ .Values.controllerManager.tlsMinVersion }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} - HELMBUST_ENABLE_TLS_APISERVER_AUTHENTICATION - HELMSUBST_METRICS_BACKEND_ARG - HELMSUBST_TLS_HEALTHCHECK_ENABLED_ARG @@ -93,6 +100,7 @@ spec: - HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_DISABLED_BUILTIN - HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_EXEMPT_NAMESPACES - HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_EXEMPT_NAMESPACE_PREFIXES + - HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_EXEMPT_NAMESPACE_SUFFIXES - HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_LOGFILE imagePullPolicy: "{{ .Values.image.pullPolicy }}" HELMSUBST_AUDIT_CONTROLLER_MANAGER_DEPLOYMENT_IMAGE_RELEASE: "" @@ -141,10 +149,12 @@ metadata: name: gatekeeper-audit namespace: gatekeeper-system spec: + revisionHistoryLimit: HELMSUBST_DEPLOYMENT_REVISION_HISTORY_LIMIT template: metadata: annotations: HELMSUBST_ANNOTATIONS: "" + HELMSUBST_AUDIT_POD_ANNOTATIONS: "" spec: containers: - name: manager @@ -152,12 +162,16 @@ spec: - --audit-interval={{ .Values.auditInterval }} - --log-level={{ (.Values.audit.logLevel | empty | not) | ternary .Values.audit.logLevel .Values.logLevel }} - --constraint-violations-limit={{ .Values.constraintViolationsLimit }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} - --audit-from-cache={{ .Values.auditFromCache }} - --audit-chunk-size={{ .Values.auditChunkSize }} - --audit-match-kind-only={{ .Values.auditMatchKindOnly }} - --emit-audit-events={{ .Values.emitAuditEvents }} + - --audit-events-involved-namespace={{ .Values.auditEventsInvolvedNamespace }} - --operation=audit - --operation=status + - HELMSUBST_PUBSUB_ARGS - HELMSUBST_MUTATION_STATUS_ENABLED_ARG - --logtostderr - --health-addr=:HELMSUBST_DEPLOYMENT_AUDIT_HEALTH_PORT @@ -167,6 +181,7 @@ spec: - HELMSUBST_METRICS_BACKEND_ARG - HELMSUBST_DEPLOYMENT_AUDIT_LOGFILE - --disable-cert-rotation={{ or .Values.audit.disableCertRotation .Values.externalCertInjection.enabled }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} imagePullPolicy: "{{ .Values.image.pullPolicy }}" HELMSUBST_AUDIT_CONTROLLER_MANAGER_DEPLOYMENT_IMAGE_RELEASE: "" ports: diff --git a/cmd/build/helmify/main.go b/cmd/build/helmify/main.go index 0a65cb53b8a..34f0d087026 100644 --- a/cmd/build/helmify/main.go +++ b/cmd/build/helmify/main.go @@ -101,18 +101,21 @@ func (ks *kindSet) Write() error { if err != nil { return err } + fileName := fmt.Sprintf("%s-%s.yaml", strings.ToLower(name), strings.ToLower(kind)) - destFile := path.Join(*outputDir, subPath, fileName) - fmt.Printf("Writing %s\n", destFile) - if name == "gatekeeper-validating-webhook-configuration" { + if name == "validation.gatekeeper.sh" { obj = "{{- if not .Values.disableValidatingWebhook }}\n" + obj + "{{- end }}\n" + fileName = fmt.Sprintf("gatekeeper-validating-webhook-configuration-%s.yaml", strings.ToLower(kind)) } - if name == "gatekeeper-mutating-webhook-configuration" { + if name == "mutation.gatekeeper.sh" { obj = "{{- if not .Values.disableMutation }}\n" + obj + "{{- end }}\n" + fileName = fmt.Sprintf("gatekeeper-mutating-webhook-configuration-%s.yaml", strings.ToLower(kind)) } + destFile := path.Join(*outputDir, subPath, fileName) + if name == "gatekeeper-webhook-server-cert" && kind == "Secret" { obj = "{{- if not .Values.externalCertInjection.enabled }}\n" + obj + "{{- end }}\n" } @@ -151,8 +154,12 @@ func (ks *kindSet) Write() error { if name == "gatekeeper-manager-role" && kind == "ClusterRole" { obj = strings.Replace(obj, "- apiGroups:\n - policy\n resourceNames:\n - gatekeeper-admin\n resources:\n - podsecuritypolicies\n verbs:\n - use\n", "{{- if and .Values.psp.enabled (.Capabilities.APIVersions.Has \"policy/v1beta1/PodSecurityPolicy\") }}\n- apiGroups:\n - policy\n resourceNames:\n - gatekeeper-admin\n resources:\n - podsecuritypolicies\n verbs:\n - use\n{{- end }}\n", 1) + obj = strings.Replace(obj, "- gatekeeper-validating-webhook-configuration\n", "- {{ .Values.validatingWebhookName }}\n", 1) + obj = strings.Replace(obj, "- gatekeeper-mutating-webhook-configuration\n", "- {{ .Values.mutatingWebhookName }}\n", 1) } + fmt.Printf("Writing %s\n", destFile) + if err := os.WriteFile(destFile, []byte(obj), 0o600); err != nil { return err } diff --git a/cmd/build/helmify/replacements.go b/cmd/build/helmify/replacements.go index e73c5359770..b849fb7352c 100644 --- a/cmd/build/helmify/replacements.go +++ b/cmd/build/helmify/replacements.go @@ -55,6 +55,8 @@ var replacements = map[string]string{ `HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_AFFINITY: ""`: `{{- toYaml .Values.controllerManager.affinity | nindent 8 }}`, + "HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_STRATEGY_TYPE": `{{ .Values.controllerManager.strategyType }}`, + `HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_SECURITY_CONTEXT: ""`: `{{- if .Values.enableRuntimeDefaultSeccompProfile }} seccompProfile: type: RuntimeDefault @@ -71,10 +73,16 @@ var replacements = map[string]string{ "HELMSUBST_DEPLOYMENT_REPLICAS": `{{ .Values.replicas }}`, + "HELMSUBST_DEPLOYMENT_REVISION_HISTORY_LIMIT": `{{ .Values.revisionHistoryLimit }}`, + `HELMSUBST_ANNOTATIONS: ""`: `{{- if .Values.podAnnotations }} {{- toYaml .Values.podAnnotations | trim | nindent 8 }} {{- end }}`, + `HELMSUBST_AUDIT_POD_ANNOTATIONS: ""`: `{{- if .Values.auditPodAnnotations }} + {{- toYaml .Values.auditPodAnnotations | trim | nindent 8 }} + {{- end }}`, + "HELMSUBST_SECRET_ANNOTATIONS": `{{- toYaml .Values.secretAnnotations | trim | nindent 4 }}`, "- HELMSUBST_TLS_HEALTHCHECK_ENABLED_ARG": `{{ if .Values.enableTLSHealthcheck}}- --enable-tls-healthcheck{{- end }}`, @@ -85,6 +93,12 @@ var replacements = map[string]string{ "- HELMSUBST_MUTATION_STATUS_ENABLED_ARG": `{{ if not .Values.disableMutation}}- --operation=mutation-status{{- end }}`, + "- HELMSUBST_PUBSUB_ARGS": `{{ if .Values.audit.enablePubsub}} + - --enable-pub-sub={{ .Values.audit.enablePubsub }} + - --audit-connection={{ .Values.audit.connection }} + - --audit-channel={{ .Values.audit.channel }} + {{- end }}`, + "HELMSUBST_MUTATING_WEBHOOK_FAILURE_POLICY": `{{ .Values.mutatingWebhookFailurePolicy }}`, "HELMSUBST_MUTATING_WEBHOOK_REINVOCATION_POLICY": `{{ .Values.mutatingWebhookReinvocationPolicy }}`, @@ -123,6 +137,15 @@ var replacements = map[string]string{ - '*' {{- end }}`, + "HELMSUBST_MUTATING_WEBHOOK_CLIENT_CONFIG: \"\"": `{{- if .Values.mutatingWebhookURL }} + url: https://{{ .Values.mutatingWebhookURL }}/v1/mutate + {{- else }} + service: + name: gatekeeper-webhook-service + namespace: '{{ .Release.Namespace }}' + path: /v1/mutate + {{- end }}`, + "HELMSUBST_VALIDATING_WEBHOOK_TIMEOUT": `{{ .Values.validatingWebhookTimeoutSeconds }}`, "HELMSUBST_VALIDATING_WEBHOOK_FAILURE_POLICY": `{{ .Values.validatingWebhookFailurePolicy }}`, @@ -148,6 +171,15 @@ var replacements = map[string]string{ "HELMSUBST_VALIDATING_WEBHOOK_CHECK_IGNORE_FAILURE_POLICY": `{{ .Values.validatingWebhookCheckIgnoreFailurePolicy }}`, + "HELMSUBST_VALIDATING_WEBHOOK_CLIENT_CONFIG: \"\"": `{{- if .Values.validatingWebhookURL }} + url: https://{{ .Values.validatingWebhookURL }}/v1/admit + {{- else }} + service: + name: gatekeeper-webhook-service + namespace: '{{ .Release.Namespace }}' + path: /v1/admit + {{- end }}`, + "HELMSUBST_RESOURCEQUOTA_POD_LIMIT": `{{ .Values.podCountLimit }}`, "- HELMSUBST_VALIDATING_WEBHOOK_OPERATION_RULES": `{{- if .Values.validatingWebhookCustomRules }} @@ -232,6 +264,11 @@ var replacements = map[string]string{ - --exempt-namespace-prefix={{ . }} {{- end }}`, + "- HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_EXEMPT_NAMESPACE_SUFFIXES": ` + {{- range .Values.controllerManager.exemptNamespaceSuffixes}} + - --exempt-namespace-suffix={{ . }} + {{- end }}`, + "- HELMSUBST_DEPLOYMENT_CONTROLLER_MANAGER_LOGFILE": ` {{- if .Values.controllerManager.logFile}} - --log-file={{ .Values.controllerManager.logFile }} diff --git a/cmd/build/helmify/static/Chart.yaml b/cmd/build/helmify/static/Chart.yaml index 38a5497d03d..695bff1ac0d 100644 --- a/cmd/build/helmify/static/Chart.yaml +++ b/cmd/build/helmify/static/Chart.yaml @@ -4,8 +4,8 @@ name: gatekeeper icon: https://open-policy-agent.github.io/gatekeeper/website/img/logo.svg keywords: - open policy agent -version: 3.12.0-beta.0 +version: 3.14.0 home: https://github.com/open-policy-agent/gatekeeper sources: - https://github.com/open-policy-agent/gatekeeper.git -appVersion: v3.12.0-beta.0 +appVersion: v3.14.0 diff --git a/cmd/build/helmify/static/README.md b/cmd/build/helmify/static/README.md index 6e13a55b341..fe841a46a52 100644 --- a/cmd/build/helmify/static/README.md +++ b/cmd/build/helmify/static/README.md @@ -27,7 +27,8 @@ _See [helm install](https://helm.sh/docs/helm/helm_install/) for command documen ## Upgrade Chart **Upgrading from < v3.4.0** -Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within the chart. This follows Helm 3 Best Practices. +Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within +the chart. This follows Helm 3 Best Practices. Option 1: A simple way to upgrade is to uninstall first and re-install with 3.4.0 or greater. @@ -39,7 +40,9 @@ $ helm install -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper --creat ``` Option 2: -Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the original release, while keeping all of the resources. It then updates the annotations of the resources so that the new chart can import and manage them. +Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the +original release, while keeping all of the resources. It then updates the annotations of the resources so that the new +chart can import and manage them. ```console $ helm_migrate.sh @@ -47,155 +50,178 @@ $ helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper ``` **Upgrading from >= v3.4.0** + ```console $ helm upgrade -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper ``` _See [helm 2 to 3](https://helm.sh/docs/topics/v2_v3_migration/) for Helm 2 migration documentation._ - ## Exempting Namespace -The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during a post-install hook. +The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt +the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during +a post-install hook. -_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more information._ +_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more +information._ ## Parameters -| Parameter | Description | Default | -| :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | -| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | -| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | -| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | -| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | -| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | -| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | -| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | -| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | -| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | -| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | -| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | -| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | -| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | -| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | -| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | -| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | -| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | -| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` -| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | -| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | -| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | -| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | -| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| preUninstall.deleteWebhooks.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | -| preUninstall.deleteWebhooks.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | -| preUninstall.deleteWebhooks.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| preUninstall.deleteWebhooks.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| preUninstall.deleteWebhooks.image.pullSecrets | Image pullSecrets | `[]` | -| preUninstall.deleteWebhooks.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | -| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | -| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | -| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | -| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | -| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| psp.enabled | Enabled PodSecurityPolicy | `true` | -| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | -| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | -| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | -| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | -| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | -| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | -| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | -| auditInterval | The frequency with which audit is run | `60` | -| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | -| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | -| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | -| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | -| disableValidatingWebhook | Disable the validating webhook | `false` | -| disableMutation | Disable mutation | `false` | -| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | -| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | -| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | -| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | -| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | -| enableExternalData | Enable external data | `true` | -| enableGeneratorResourceExpansion | Enable generator resource expansion (alpha feature) | `false` | -| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | -| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | -| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | -| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | -| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | -| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | -| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | -| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| emitAdmissionEvents | Emit K8s events in gatekeeper namespace for admission violations (alpha feature) | `false` | -| emitAuditEvents | Emit K8s events in gatekeeper namespace for audit violations (alpha feature) | `false` | -| logDenies | Log detailed info on each deny | `false` | -| logLevel | Minimum log level | `INFO` | -| image.pullPolicy | The image pull policy | `IfNotPresent` | -| image.repository | Image repository | `openpolicyagent/gatekeeper` | -| image.release | The image release tag to use | Current release version: `v3.12.0-beta.0` | -| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | -| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | -| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | -| affinity | The node affinity to use for pod scheduling | `{}` | -| topologySpreadConstraints | The topology spread constraints to use for pod scheduling | `[]` | -| tolerations | The tolerations to use for pod scheduling | `[]` | -| controllerManager.healthPort | Health port for controller manager | `9090` | -| controllerManager.port | Webhook-server port for controller manager | `8443` | -| controllerManager.metricsPort | Metrics port for controller manager | `8888` | -| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | -| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | -| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` -| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | -| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | -| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | -| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | -| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | -| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | -| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | -| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | -| controllerManager.networkPolicy.enabled | Should a network policy for the controller manager be created | `false` | -| controllerManager.networkPolicy.ingress | Additional ingress rules to be added to the controller manager network policy | `{}` | -| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | -| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | -| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | -| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | -| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| audit.healthPort | Health port for audit | `9090` | -| audit.metricsPort | Metrics port for audit | `8888` | -| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | -| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | -| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` -| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | -| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | -| podLabels | The labels to add to the Gatekeeper pods | `{}` | -| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | -| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | -| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | -| service.type | Service type | `ClusterIP` | -| service.loadBalancerIP | The IP address of LoadBalancer service | `` | -| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | -| rbac.create | Enable the creation of RBAC resources | `true` | -| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | -| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| Parameter | Description | Default | +|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | +| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | +| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | +| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | +| postInstall.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label Job | `` | +| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | +| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | +| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | +| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | +| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | +| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | +| postInstall.probeWebhook.priorityClassName | Priority class name for gatekeeper-probe-webhook-post-install Job | `` | +| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | +| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | +| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | +| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | +| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | +| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | +| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | +| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postUpgrade.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label-post-upgrade Job | `` | +| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | +| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | +| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | +| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | +| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| preInstall.crdRepository.image.repository | Image with kubectl to update the CRDs. If not set, the `image.crdRepository` is used instead. | `null` | +| preInstall.crdRepository.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | +| preUninstall.deleteWebhookConfigurations.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | +| preUninstall.deleteWebhookConfigurations.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| preUninstall.deleteWebhookConfigurations.image.pullSecrets | Image pullSecrets | `[]` | +| preUninstall.deleteWebhookConfigurations.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | +| preUninstall.deleteWebhookConfigurations.priorityClassName | Priority class name for gatekeeper-delete-webhook-configs Job | `` | +| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | +| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | +| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | +| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | +| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| psp.enabled | Enabled PodSecurityPolicy | `true` | +| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | +| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | +| upgradeCRDs.priorityClassName | Priority class name for gatekeeper-update-crds-hook Job | `` | +| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | +| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | +| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | +| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | +| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | +| auditInterval | The frequency with which audit is run | `60` | +| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | +| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | +| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | +| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | +| disableValidatingWebhook | Disable the validating webhook | `false` | +| disableMutation | Disable mutation | `false` | +| validatingWebhookName | The name of the `ValidatingWebhookConfiguration` | `gatekeeper-validating-webhook-configuration` | +| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | +| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | +| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | +| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | +| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| validatingWebhookURL | Custom URL for Kubernetes API server to use to reach the validating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | +| enableExternalData | Enable external data | `true` | +| enableGeneratorResourceExpansion | Enable generator resource expansion (beta feature) | `true` | +| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | +| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | +| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | +| mutatingWebhookName | The name of the `MutatingWebhookConfiguration` | `gatekeeper-mutating-webhook-configuration` | +| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | +| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | +| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | +| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | +| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| mutatingWebhookURL | Custom URL for Kubernetes API server to use to reach the mutating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| emitAdmissionEvents | Emit K8s events in configurable namespace for admission violations (alpha feature) | `false` | +| emitAuditEvents | Emit K8s events in configurable namespace for audit violations (alpha feature) | `false` | +| auditEventsInvolvedNamespace | Emit audit events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Audit events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| admissionEventsInvolvedNamespace | Emit admission events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Admission events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| logDenies | Log detailed info on each deny | `false` | +| logLevel | Minimum log level | `INFO` | +| image.pullPolicy | The image pull policy | `IfNotPresent` | +| image.repository | Image repository | `openpolicyagent/gatekeeper` | +| image.release | The image release tag to use | Current release version: `v3.14.0` | +| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | +| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | +| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | +| controllerManager.affinity | The node affinity to use for controller manager pod scheduling | `{}` | +| controllerManager.topologySpreadConstraints | The topology spread constraints to use for controller manager pod scheduling | `[]` | +| controllerManager.tolerations | The tolerations to use for controller manager pod scheduling | `[]` | +| controllerManager.healthPort | Health port for controller manager | `9090` | +| controllerManager.port | Webhook-server port for controller manager | `8443` | +| controllerManager.metricsPort | Metrics port for controller manager | `8888` | +| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | +| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | +| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` | +| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | +| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | +| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | +| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | +| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | +| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | +| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | +| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | +| controllerManager.networkPolicy.enabled | Should a network policy for the controller manager be created | `false` | +| controllerManager.networkPolicy.ingress | Additional ingress rules to be added to the controller manager network policy | `{}` | +| controllerManager.strategyType | The strategy type to use for Controller Manager deployment | `RollingUpdate` | +| audit.affinity | The node affinity to use for audit pod scheduling | `{}` | +| audit.topologySpreadConstraints | The topology spread constraints to use for audit pod scheduling | `[]` | +| audit.tolerations | The tolerations to use for audit pod scheduling | `[]` | +| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | +| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | +| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | +| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | +| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| audit.healthPort | Health port for audit | `9090` | +| audit.metricsPort | Metrics port for audit | `8888` | +| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | +| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | +| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` | +| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | +| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | +| podLabels | The labels to add to the Gatekeeper pods | `{}` | +| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | +| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | +| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | +| service.type | Service type | `ClusterIP` | +| service.loadBalancerIP | The IP address of LoadBalancer service | `` | +| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | +| rbac.create | Enable the creation of RBAC resources | `true` | +| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | +| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| externaldataProviderResponseCacheTTL | TTL for the external data provider response cache. Specify the duration in 'h', 'm', or 's' for hours, minutes, or seconds respectively. | `3m` | ## Contributing Changes -Please refer to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) for modifying the Helm chart. +Please refer +to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) +for modifying the Helm chart. diff --git a/cmd/build/helmify/static/templates/_helpers.tpl b/cmd/build/helmify/static/templates/_helpers.tpl index 5ab6fe2b456..785d9912656 100644 --- a/cmd/build/helmify/static/templates/_helpers.tpl +++ b/cmd/build/helmify/static/templates/_helpers.tpl @@ -36,10 +36,44 @@ Adds additional pod labels to the common ones */}} {{- define "gatekeeper.podLabels" -}} {{- if .Values.podLabels }} -{{- toYaml .Values.podLabels | nindent 8 }} +{{- toYaml .Values.podLabels }} {{- end }} {{- end -}} +{{/* +Mandatory labels +*/}} +{{- define "gatekeeper.mandatoryLabels" -}} +app: {{ include "gatekeeper.name" . }} +chart: {{ include "gatekeeper.name" . }} +gatekeeper.sh/system: "yes" +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "gatekeeper.commonLabels" -}} +helm.sh/chart: {{ include "gatekeeper.chart" . }} +{{ include "gatekeeper.selectorLabels" . }} +{{- if .Chart.Version }} +app.kubernetes.io/version: {{ .Chart.Version | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels }} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "gatekeeper.selectorLabels" -}} +app.kubernetes.io/name: {{ include "gatekeeper.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + {{/* Output post install webhook probe container entry */}} @@ -47,10 +81,12 @@ Output post install webhook probe container entry - name: webhook-probe-post image: "{{ .Values.postInstall.probeWebhook.image.repository }}:{{ .Values.postInstall.probeWebhook.image.tag }}" imagePullPolicy: {{ .Values.postInstall.probeWebhook.image.pullPolicy }} - args: + command: - "curl" + args: - "--retry" - "99999" + - "--retry-connrefused" - "--retry-max-time" - "{{ .Values.postInstall.probeWebhook.waitTimeout }}" - "--retry-delay" diff --git a/cmd/build/helmify/static/templates/gatekeeper-admin-podsecuritypolicy.yaml b/cmd/build/helmify/static/templates/gatekeeper-admin-podsecuritypolicy.yaml index 398b1460077..8c02264b024 100644 --- a/cmd/build/helmify/static/templates/gatekeeper-admin-podsecuritypolicy.yaml +++ b/cmd/build/helmify/static/templates/gatekeeper-admin-podsecuritypolicy.yaml @@ -5,11 +5,8 @@ metadata: annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} name: gatekeeper-admin spec: allowPrivilegeEscalation: false diff --git a/cmd/build/helmify/static/templates/gatekeeper-controller-manager-network-policy.yaml b/cmd/build/helmify/static/templates/gatekeeper-controller-manager-network-policy.yaml index e05213feb46..5ac3ca6c2c6 100644 --- a/cmd/build/helmify/static/templates/gatekeeper-controller-manager-network-policy.yaml +++ b/cmd/build/helmify/static/templates/gatekeeper-controller-manager-network-policy.yaml @@ -3,16 +3,15 @@ kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} name: gatekeeper-controller-manager spec: ingress: - from: - podSelector: matchLabels: + {{- include "gatekeeper.commonLabels" . | nindent 14 }} app: '{{ template "gatekeeper.name" . }}' release: '{{ .Release.Name }}' {{- with .Values.controllerManager.networkPolicy.ingress }} @@ -20,11 +19,8 @@ spec: {{- end }} podSelector: matchLabels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 6 }} + {{- include "gatekeeper.commonLabels" . | nindent 6 }} control-plane: controller-manager gatekeeper.sh/operation: webhook - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' {{- end -}} diff --git a/cmd/build/helmify/static/templates/namespace-post-install.yaml b/cmd/build/helmify/static/templates/namespace-post-install.yaml index 4f84b52b409..41232de4267 100644 --- a/cmd/build/helmify/static/templates/namespace-post-install.yaml +++ b/cmd/build/helmify/static/templates/namespace-post-install.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -22,14 +20,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure + {{- if .Values.postInstall.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postInstall.labelNamespace.priorityClassName }} + {{- end }} {{- if .Values.postInstall.labelNamespace.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} @@ -96,7 +94,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -110,6 +110,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -141,6 +142,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/cmd/build/helmify/static/templates/namespace-post-upgrade.yaml b/cmd/build/helmify/static/templates/namespace-post-upgrade.yaml index 43a1dadd9fa..b26abab34e0 100644 --- a/cmd/build/helmify/static/templates/namespace-post-upgrade.yaml +++ b/cmd/build/helmify/static/templates/namespace-post-upgrade.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label-post-upgrade + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-upgrade "helm.sh/hook-weight": "-5" @@ -20,12 +18,9 @@ spec: template: metadata: labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.postUpgrade.labelNamespace.image.pullSecrets }} @@ -33,6 +28,9 @@ spec: {{- .Values.postUpgrade.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-update-namespace-label-post-upgrade + {{- if .Values.postUpgrade.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postUpgrade.labelNamespace.priorityClassName }} + {{- end }} containers: - name: kubectl-label image: "{{ .Values.postUpgrade.labelNamespace.image.repository }}:{{ .Values.postUpgrade.labelNamespace.image.tag }}" @@ -89,6 +87,7 @@ kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -102,6 +101,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -130,6 +130,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/cmd/build/helmify/static/templates/probe-webhook-post-install.yaml b/cmd/build/helmify/static/templates/probe-webhook-post-install.yaml index 5a140d31ce0..e6ef25b594c 100644 --- a/cmd/build/helmify/static/templates/probe-webhook-post-install.yaml +++ b/cmd/build/helmify/static/templates/probe-webhook-post-install.yaml @@ -5,11 +5,8 @@ kind: Job metadata: name: gatekeeper-probe-webhook-post-install labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -20,14 +17,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: Never + {{- if .Values.postInstall.probeWebhook.priorityClassName }} + priorityClassName: {{ .Values.postInstall.probeWebhook.priorityClassName }} + {{- end }} {{- if .Values.postInstall.probeWebhook.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.probeWebhook.image.pullSecrets | toYaml | nindent 12 }} @@ -44,5 +41,6 @@ spec: nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} {{- end }} + backoffLimit: 3 {{- end }} {{- end }} diff --git a/cmd/build/helmify/static/templates/upgrade-crds-hook.yaml b/cmd/build/helmify/static/templates/upgrade-crds-hook.yaml index cd57573f37a..f9347ad9c7b 100644 --- a/cmd/build/helmify/static/templates/upgrade-crds-hook.yaml +++ b/cmd/build/helmify/static/templates/upgrade-crds-hook.yaml @@ -5,6 +5,7 @@ kind: ClusterRole metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -26,6 +27,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -46,6 +48,7 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} name: gatekeeper-admin-upgrade-crds @@ -61,29 +64,23 @@ metadata: name: gatekeeper-update-crds-hook namespace: {{ .Release.Namespace }} labels: - app: {{ template "gatekeeper.name" . }} - chart: {{ template "gatekeeper.name" . }} - gatekeeper.sh/system: "yes" - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: helm.sh/hook: pre-install,pre-upgrade helm.sh/hook-weight: "1" helm.sh/hook-delete-policy: "hook-succeeded,before-hook-creation" spec: - backoffLimit: 0 + backoffLimit: 3 template: metadata: name: gatekeeper-update-crds-hook annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: serviceAccountName: gatekeeper-admin-upgrade-crds restartPolicy: Never @@ -91,12 +88,23 @@ spec: imagePullSecrets: {{- toYaml .Values.image.pullSecrets | nindent 8 }} {{- end }} + {{- if .Values.upgradeCRDs.priorityClassName }} + priorityClassName: {{ .Values.upgradeCRDs.priorityClassName }} + {{- end }} containers: - name: crds-upgrade - {{- if not .Values.image.release }} - image: '{{ .Values.image.crdRepository }}' + {{- if .Values.preInstall.crdRepository.image.repository }} + {{- if not .Values.preInstall.crdRepository.image.tag }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}' + {{- else }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}:{{ .Values.preInstall.crdRepository.image.tag }}' + {{- end }} {{- else }} + {{- if not .Values.image.release }} + image: '{{ .Values.image.crdRepository }}' + {{- else }} image: '{{ .Values.image.crdRepository }}:{{ .Values.image.release }}' + {{- end }} {{- end }} imagePullPolicy: '{{ .Values.image.pullPolicy }}' args: diff --git a/cmd/build/helmify/static/templates/webhook-configs-pre-delete.yaml b/cmd/build/helmify/static/templates/webhook-configs-pre-delete.yaml index d610394de36..fb359b87e16 100644 --- a/cmd/build/helmify/static/templates/webhook-configs-pre-delete.yaml +++ b/cmd/build/helmify/static/templates/webhook-configs-pre-delete.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": pre-delete "helm.sh/hook-weight": "-5" @@ -19,12 +17,9 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets }} @@ -32,6 +27,9 @@ spec: {{- .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-delete-webhook-configs + {{- if .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + priorityClassName: {{ .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + {{- end }} containers: - name: kubectl-delete image: "{{ .Values.preUninstall.deleteWebhookConfigurations.image.repository }}:{{ .Values.preUninstall.deleteWebhookConfigurations.image.tag }}" @@ -39,19 +37,19 @@ spec: args: - delete {{- if not .Values.disableValidatingWebhook }} - - validatingwebhookconfiguration/gatekeeper-validating-webhook-configuration + - validatingwebhookconfiguration/{{ .Values.validatingWebhookName }} {{- end }} {{- if not .Values.disableMutation }} - - mutatingwebhookconfiguration/gatekeeper-mutating-webhook-configuration + - mutatingwebhookconfiguration/{{ .Values.mutatingWebhookName }} {{- end }} resources: - {{- toYaml .Values.preUninstall.resources | nindent 10 }} + {{- toYaml .Values.preUninstall.resources | nindent 12 }} securityContext: {{- if .Values.enableRuntimeDefaultSeccompProfile }} seccompProfile: type: RuntimeDefault {{- end }} - {{- toYaml .Values.preUninstall.securityContext | nindent 10 }} + {{- toYaml .Values.preUninstall.securityContext | nindent 12 }} {{- with .Values.preUninstall }} nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} @@ -65,7 +63,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -79,6 +79,7 @@ kind: ClusterRole metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -92,7 +93,7 @@ rules: resources: - validatingwebhookconfigurations resourceNames: - - gatekeeper-validating-webhook-configuration + - {{ .Values.validatingWebhookName }} verbs: - delete {{- end }} @@ -102,7 +103,7 @@ rules: resources: - mutatingwebhookconfigurations resourceNames: - - gatekeeper-mutating-webhook-configuration + - {{ .Values.mutatingWebhookName }} verbs: - delete {{- end }} @@ -117,6 +118,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/cmd/build/helmify/static/values.yaml b/cmd/build/helmify/static/values.yaml index 364f5ed4794..2e4c3a8666f 100644 --- a/cmd/build/helmify/static/values.yaml +++ b/cmd/build/helmify/static/values.yaml @@ -1,4 +1,5 @@ replicas: 3 +revisionHistoryLimit: 10 auditInterval: 60 metricsBackends: ["prometheus"] auditMatchKindOnly: false @@ -6,6 +7,7 @@ constraintViolationsLimit: 20 auditFromCache: false disableMutation: false disableValidatingWebhook: false +validatingWebhookName: gatekeeper-validating-webhook-configuration validatingWebhookTimeoutSeconds: 3 validatingWebhookFailurePolicy: Ignore validatingWebhookAnnotations: {} @@ -13,11 +15,13 @@ validatingWebhookExemptNamespacesLabels: {} validatingWebhookObjectSelector: {} validatingWebhookCheckIgnoreFailurePolicy: Fail validatingWebhookCustomRules: {} +validatingWebhookURL: null enableDeleteOperations: false enableExternalData: true -enableGeneratorResourceExpansion: false +enableGeneratorResourceExpansion: true enableTLSHealthcheck: false maxServingThreads: -1 +mutatingWebhookName: gatekeeper-mutating-webhook-configuration mutatingWebhookFailurePolicy: Ignore mutatingWebhookReinvocationPolicy: Never mutatingWebhookAnnotations: {} @@ -25,6 +29,7 @@ mutatingWebhookExemptNamespacesLabels: {} mutatingWebhookObjectSelector: {} mutatingWebhookTimeoutSeconds: 1 mutatingWebhookCustomRules: {} +mutatingWebhookURL: null mutationAnnotations: false auditChunkSize: 500 logLevel: INFO @@ -32,13 +37,27 @@ logDenies: false logMutations: false emitAdmissionEvents: false emitAuditEvents: false +admissionEventsInvolvedNamespace: false +auditEventsInvolvedNamespace: false resourceQuota: true +externaldataProviderResponseCacheTTL: 3m +image: + repository: openpolicyagent/gatekeeper + crdRepository: openpolicyagent/gatekeeper-crds + release: v3.14.0 + pullPolicy: IfNotPresent + pullSecrets: [] +preInstall: + crdRepository: + image: + repository: null + tag: v3.14.0 postUpgrade: labelNamespace: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -49,6 +68,7 @@ postUpgrade: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -68,7 +88,7 @@ postInstall: extraRules: [] image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -79,6 +99,7 @@ postInstall: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" probeWebhook: enabled: true image: @@ -89,6 +110,7 @@ postInstall: waitTimeout: 60 httpTimeout: 2 insecureHTTPS: false + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -107,9 +129,10 @@ preUninstall: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -123,13 +146,8 @@ preUninstall: runAsGroup: 999 runAsNonRoot: true runAsUser: 1000 -image: - repository: openpolicyagent/gatekeeper - crdRepository: openpolicyagent/gatekeeper-crds - release: v3.12.0-beta.0 - pullPolicy: IfNotPresent - pullSecrets: [] podAnnotations: {} +auditPodAnnotations: {} podLabels: {} podCountLimit: "100" secretAnnotations: {} @@ -146,8 +164,9 @@ controllerManager: livenessTimeout: 1 priorityClassName: system-cluster-critical disableCertRotation: false - tlsMinVersion: 1.3 + tlsMinVersion: 1.2 clientCertName: "" + strategyType: RollingUpdate affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -190,6 +209,7 @@ controllerManager: # - ipBlock: # cidr: 0.0.0.0/0 audit: + enablePubsub: false hostNetwork: false dnsPolicy: ClusterFirst metricsPort: 8888 @@ -197,7 +217,7 @@ audit: readinessTimeout: 1 livenessTimeout: 1 priorityClassName: system-cluster-critical - disableCertRotation: true + disableCertRotation: false affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -246,6 +266,7 @@ psp: upgradeCRDs: enabled: true extraRules: [] + priorityClassName: "" rbac: create: true externalCertInjection: diff --git a/cmd/gator/expand/expand.go b/cmd/gator/expand/expand.go index 502abe0759e..feab47aa116 100644 --- a/cmd/gator/expand/expand.go +++ b/cmd/gator/expand/expand.go @@ -7,28 +7,26 @@ import ( "os" "sort" - "github.com/open-policy-agent/gatekeeper/pkg/gator/expand" - "github.com/open-policy-agent/gatekeeper/pkg/gator/reader" + "github.com/open-policy-agent/gatekeeper/v3/cmd/gator/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/expand" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/reader" "github.com/spf13/cobra" - - // yaml.v3 inserts a space before '-', which is inconsistent with standard - // kubernetes and kubebuilder format. yaml.v2 does not insert these spaces. - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v2" // yaml.v3 inserts a space before '-', which is inconsistent with standard, kubernetes and kubebuilder format. yaml.v2 does not insert these spaces. "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) const ( - examples = ` # expand resources in a manifest - gator expand --filename="manifest.yaml" + examples = `# expand resources in a manifest +gator expand --filename="manifest.yaml" - # expand a directory - gator expand --filename="config-and-policies/" +# expand a directory +gator expand --filename="config-and-policies/" - # Use multiple inputs - gator expand --filename="manifest.yaml" --filename="templates-and-constraints/" +# Use multiple inputs +gator expand --filename="manifest.yaml" --filename="templates-and-constraints/" - # Output JSON to file - gator expand --filename="manifest.yaml" --format=json --outputfile=results.yaml ` +# Output JSON to file +gator expand --filename="manifest.yaml" --format=json --outputfile=results.yaml` ) var Cmd = &cobra.Command{ @@ -71,15 +69,15 @@ func init() { func run(cmd *cobra.Command, args []string) { unstrucs, err := reader.ReadSources(flagFilenames, flagImages, flagTempDir) if err != nil { - errFatalf("reading: %v\n", err) + util.ErrFatalf("reading: %v", err) } if len(unstrucs) == 0 { - errFatalf("no input data identified\n") + util.ErrFatalf("no input data identified") } resultants, err := expand.Expand(unstrucs) if err != nil { - errFatalf("error expanding resources: %v", err) + util.ErrFatalf("error expanding resources: %v", err) } // Sort resultants for deterministic output sortUnstructs(resultants) @@ -89,7 +87,7 @@ func run(cmd *cobra.Command, args []string) { fmt.Println(output) } else { fmt.Printf("Writing output to file: %s\n", flagOutput) - stringToFile(output, flagOutput) + util.WriteToFile(output, flagOutput) } os.Exit(0) @@ -98,19 +96,19 @@ func run(cmd *cobra.Command, args []string) { func resourcetoYAMLString(resource *unstructured.Unstructured) string { jsonb, err := json.Marshal(resource) if err != nil { - errFatalf("pre-marshaling results to json: %v", err) + util.ErrFatalf("pre-marshaling results to json: %v", err) } unmarshalled := map[string]interface{}{} err = json.Unmarshal(jsonb, &unmarshalled) if err != nil { - errFatalf("pre-unmarshaling results from json: %v", err) + util.ErrFatalf("pre-unmarshaling results from json: %v", err) } var b bytes.Buffer yamlEncoder := yaml.NewEncoder(&b) if err := yamlEncoder.Encode(unmarshalled); err != nil { - errFatalf("marshaling validation yaml results: %v", err) + util.ErrFatalf("marshaling validation yaml results: %v", err) } return b.String() } @@ -118,7 +116,7 @@ func resourcetoYAMLString(resource *unstructured.Unstructured) string { func resourceToJSONString(resource *unstructured.Unstructured) string { b, err := json.MarshalIndent(resource, "", " ") if err != nil { - errFatalf("marshaling validation json results: %v", err) + util.ErrFatalf("marshaling validation json results: %v", err) } return string(b) } @@ -131,7 +129,7 @@ func resourcesToString(resources []*unstructured.Unstructured, format string) st case stringJSON: conversionFunc = resourceToJSONString default: - errFatalf("unrecognized value for %s flag: %s", flagNameFormat, format) + util.ErrFatalf("unrecognized value for %s flag: %s", flagNameFormat, format) } output := "" @@ -144,17 +142,6 @@ func resourcesToString(resources []*unstructured.Unstructured, format string) st return output } -func stringToFile(s string, path string) { - file, err := os.Create(path) - if err != nil { - errFatalf("error creating file at path %s: %v", path, err) - } - - if _, err = fmt.Fprint(file, s); err != nil { - errFatalf("error writing to file at path %s: %s", path, err) - } -} - func sortUnstructs(objs []*unstructured.Unstructured) { sortKey := func(o *unstructured.Unstructured) string { return o.GetName() + o.GetAPIVersion() + o.GetKind() @@ -163,8 +150,3 @@ func sortUnstructs(objs []*unstructured.Unstructured) { return sortKey(objs[i]) > sortKey(objs[j]) }) } - -func errFatalf(format string, a ...interface{}) { - fmt.Fprintf(os.Stderr, format+"\n", a...) - os.Exit(1) -} diff --git a/cmd/gator/gator.go b/cmd/gator/gator.go index 079727820e0..be611a9713c 100644 --- a/cmd/gator/gator.go +++ b/cmd/gator/gator.go @@ -1,41 +1,31 @@ package main import ( - "fmt" "os" - "github.com/open-policy-agent/gatekeeper/cmd/gator/expand" - "github.com/open-policy-agent/gatekeeper/cmd/gator/test" - "github.com/open-policy-agent/gatekeeper/cmd/gator/verify" - "github.com/open-policy-agent/gatekeeper/pkg/version" + "github.com/open-policy-agent/gatekeeper/v3/cmd/gator/expand" + "github.com/open-policy-agent/gatekeeper/v3/cmd/gator/test" + "github.com/open-policy-agent/gatekeeper/v3/cmd/gator/verify" + "github.com/open-policy-agent/gatekeeper/v3/pkg/version" "github.com/spf13/cobra" -) - -const state = "beta" - -var ( - frameworksVersion string - - opaVersion string + k8sVersion "sigs.k8s.io/release-utils/version" ) var commands = []*cobra.Command{ verify.Cmd, test.Cmd, expand.Cmd, + k8sVersion.WithFont("alligator2"), } func init() { rootCmd.AddCommand(commands...) + rootCmd.Version = version.GetUserAgent("gator") } var rootCmd = &cobra.Command{ - Use: "gator subcommand", - Short: "gator is a suite of authorship tools for Gatekeeper", - Version: fmt.Sprintf("\nGator version: %s (Feature State: %s), OPA version: %s, Framework version: %s", version.Version, state, opaVersion, frameworksVersion), - RunE: func(cmd *cobra.Command, args []string) error { - return nil - }, + Use: "gator subcommand", + Short: "gator is a suite of authorship tools for Gatekeeper", } func main() { diff --git a/cmd/gator/test/gatortest_test.go b/cmd/gator/test/gatortest_test.go index d56b4531236..f2e573f1293 100644 --- a/cmd/gator/test/gatortest_test.go +++ b/cmd/gator/test/gatortest_test.go @@ -5,7 +5,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/gator/test" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/test" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -41,7 +41,7 @@ func Test_formatOutput(t *testing.T) { ViolatingObject: barObject, Trace: nil, }}, - expectedOutput: `[""] Message: "" + expectedOutput: `/ : [""] Message: "" `, }, { @@ -60,7 +60,6 @@ func Test_formatOutput(t *testing.T) { object: kind: kind enforcementaction: "" - evaluationmeta: null violatingObject: bar: xyz trace: xyz @@ -90,7 +89,7 @@ func Test_formatOutput(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - output := formatOutput(tc.inputFormat, tc.input) + output := formatOutput(tc.inputFormat, tc.input, nil) if diff := cmp.Diff(tc.expectedOutput, output); diff != "" { t.Fatal(diff) } diff --git a/cmd/gator/test/test.go b/cmd/gator/test/test.go index 87dc4f769e4..6f3aae26954 100644 --- a/cmd/gator/test/test.go +++ b/cmd/gator/test/test.go @@ -7,32 +7,34 @@ import ( "os" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/gator/reader" - "github.com/open-policy-agent/gatekeeper/pkg/gator/test" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + cmdutils "github.com/open-policy-agent/gatekeeper/v3/cmd/gator/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/reader" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/test" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "github.com/spf13/cobra" "gopkg.in/yaml.v3" ) const ( - examples = ` # test a manifest containing Kubernetes objects, Constraint Templates, and Constraints - gator test --filename="manifest.yaml" + examples = `# test a manifest containing Kubernetes objects, Constraint Templates, and Constraints +gator test --filename="manifest.yaml" - # test a directory - gator test --filename="config-and-policies/" +# test a directory +gator test --filename="config-and-policies/" - # Use multiple inputs - gator test --filename="manifest.yaml" --filename="templates-and-constraints/" +# Use multiple inputs +gator test --filename="manifest.yaml" --filename="templates-and-constraints/" - # Receive input from stdin - cat manifest.yaml | gator test +# Receive input from stdin +cat manifest.yaml | gator test - # Output structured violations data - gator test --filename="manifest.yaml" --output=json +# Output structured violations data +gator test --filename="manifest.yaml" --output=json - Note: The alpha "gator test" has been renamed to "gator verify". "gator - verify" verifies individual Constraint Templates against suites of tests, where "gator - test" evaluates sets of resources against sets of Constraints and Templates.` +Note: The alpha "gator test" has been renamed to "gator verify". "gator +verify" verifies individual Constraint Templates against suites of tests, where "gator +test" evaluates sets of resources against sets of Constraints and Templates.` ) var Cmd = &cobra.Command{ @@ -47,8 +49,10 @@ var ( flagFilenames []string flagOutput string flagIncludeTrace bool + flagGatherStats bool flagImages []string flagTempDir string + flagEnableK8sCel bool ) const ( @@ -60,12 +64,16 @@ const ( stringJSON = "json" stringYAML = "yaml" stringHumanFriendly = "default" + + fourSpaceTab = " " ) func init() { Cmd.Flags().StringArrayVarP(&flagFilenames, flagNameFilename, "f", []string{}, "a file or directory containing Kubernetes resources. Can be specified multiple times.") Cmd.Flags().StringVarP(&flagOutput, flagNameOutput, "o", "", fmt.Sprintf("Output format. One of: %s|%s.", stringJSON, stringYAML)) - Cmd.Flags().BoolVarP(&flagIncludeTrace, "trace", "t", false, `include a trace for the underlying constraint framework evaluation`) + Cmd.Flags().BoolVarP(&flagIncludeTrace, "trace", "t", false, "include a trace for the underlying Constraint Framework evaluation.") + Cmd.Flags().BoolVarP(&flagGatherStats, "stats", "", false, "include performance stats returned from the Constraint Framework.") + Cmd.Flags().BoolVarP(&flagEnableK8sCel, "experimental-enable-k8s-native-validation", "", false, "PROTOTYPE (not stable): enable the validating admission policy driver") Cmd.Flags().StringArrayVarP(&flagImages, flagNameImage, "i", []string{}, "a URL to an OCI image containing policies. Can be specified multiple times.") Cmd.Flags().StringVarP(&flagTempDir, flagNameTempDir, "d", "", fmt.Sprintf("Specifies the temporary directory to download and unpack images to, if using the --%s flag. Optional.", flagNameImage)) } @@ -73,19 +81,19 @@ func init() { func run(cmd *cobra.Command, args []string) { unstrucs, err := reader.ReadSources(flagFilenames, flagImages, flagTempDir) if err != nil { - errFatalf("reading: %v", err) + cmdutils.ErrFatalf("reading: %v", err) } if len(unstrucs) == 0 { - errFatalf("no input data identified") + cmdutils.ErrFatalf("no input data identified") } - responses, err := test.Test(unstrucs, flagIncludeTrace) + responses, err := test.Test(unstrucs, test.Opts{IncludeTrace: flagIncludeTrace, GatherStats: flagGatherStats, UseK8sCEL: flagEnableK8sCel}) if err != nil { - errFatalf("auditing objects: %v\n", err) + cmdutils.ErrFatalf("auditing objects: %v", err) } results := responses.Results() - fmt.Print(formatOutput(flagOutput, results)) + fmt.Print(formatOutput(flagOutput, results, responses.StatsEntries)) // Whether or not we return non-zero depends on whether we have a `deny` // enforcementAction on one of the violated constraints @@ -96,38 +104,94 @@ func run(cmd *cobra.Command, args []string) { os.Exit(exitCode) } -func formatOutput(flagOutput string, results []*test.GatorResult) string { +func formatOutput(flagOutput string, results []*test.GatorResult, stats []*instrumentation.StatsEntry) string { switch strings.ToLower(flagOutput) { case stringJSON: - b, err := json.MarshalIndent(results, "", " ") - if err != nil { - errFatalf("marshaling validation json results: %v", err) + var jsonB []byte + var err error + + if stats != nil { + statsAndResults := map[string]interface{}{"results": results, "stats": stats} + jsonB, err = json.MarshalIndent(statsAndResults, "", fourSpaceTab) + if err != nil { + cmdutils.ErrFatalf("marshaling validation json results and stats: %v", err) + } + } else { + jsonB, err = json.MarshalIndent(results, "", fourSpaceTab) + if err != nil { + cmdutils.ErrFatalf("marshaling validation json results: %v", err) + } } - return string(b) + + return string(jsonB) case stringYAML: yamlResults := test.GetYamlFriendlyResults(results) - jsonb, err := json.Marshal(yamlResults) - if err != nil { - errFatalf("pre-marshaling results to json: %v", err) - } + var yamlb []byte - unmarshalled := []*test.YamlGatorResult{} - err = json.Unmarshal(jsonb, &unmarshalled) - if err != nil { - errFatalf("pre-unmarshaling results from json: %v", err) - } + if stats != nil { + statsAndResults := map[string]interface{}{"results": yamlResults, "stats": stats} + + statsJSONB, err := json.Marshal(statsAndResults) + if err != nil { + cmdutils.ErrFatalf("pre-marshaling stats to json: %v", err) + } + + statsAndResultsUnmarshalled := struct { + Results []*test.YamlGatorResult + Stats []*instrumentation.StatsEntry + }{} + + err = json.Unmarshal(statsJSONB, &statsAndResultsUnmarshalled) + if err != nil { + cmdutils.ErrFatalf("pre-unmarshaling stats from json: %v", err) + } - yamlb, err := yaml.Marshal(unmarshalled) - if err != nil { - errFatalf("marshaling validation yaml results: %v", err) + yamlb, err = yaml.Marshal(statsAndResultsUnmarshalled) + if err != nil { + cmdutils.ErrFatalf("marshaling validation yaml results and stats: %v", err) + } + } else { + jsonb, err := json.Marshal(yamlResults) + if err != nil { + cmdutils.ErrFatalf("pre-marshaling results to json: %v", err) + } + + unmarshalled := []*test.YamlGatorResult{} + err = json.Unmarshal(jsonb, &unmarshalled) + if err != nil { + cmdutils.ErrFatalf("pre-unmarshaling results from json: %v", err) + } + + yamlb, err = yaml.Marshal(unmarshalled) + if err != nil { + cmdutils.ErrFatalf("marshaling validation yaml results: %v", err) + } } + return string(yamlb) case stringHumanFriendly: default: var buf bytes.Buffer if len(results) > 0 { for _, result := range results { - buf.WriteString(fmt.Sprintf("[%q] Message: %q \n", result.Constraint.GetName(), result.Msg)) + obj := fmt.Sprintf("%s/%s %s", + result.ViolatingObject.GetAPIVersion(), + result.ViolatingObject.GetKind(), + result.ViolatingObject.GetName(), + ) + if result.ViolatingObject.GetNamespace() != "" { + obj = fmt.Sprintf("%s/%s %s/%s", + result.ViolatingObject.GetAPIVersion(), + result.ViolatingObject.GetKind(), + result.ViolatingObject.GetNamespace(), + result.ViolatingObject.GetName(), + ) + } + buf.WriteString(fmt.Sprintf("%s: [%q] Message: %q\n", + obj, + result.Constraint.GetName(), + result.Msg, + )) if result.Trace != nil { buf.WriteString(fmt.Sprintf("Trace: %v", *result.Trace)) @@ -149,8 +213,3 @@ func enforceableFailure(results []*test.GatorResult) bool { return false } - -func errFatalf(format string, a ...interface{}) { - fmt.Fprintf(os.Stderr, format, a...) - os.Exit(1) -} diff --git a/cmd/gator/util/util.go b/cmd/gator/util/util.go new file mode 100644 index 00000000000..a87ab72f978 --- /dev/null +++ b/cmd/gator/util/util.go @@ -0,0 +1,22 @@ +package util + +import ( + "fmt" + "os" +) + +func ErrFatalf(format string, a ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", a...) + os.Exit(1) +} + +func WriteToFile(s string, path string) { + file, err := os.Create(path) + if err != nil { + ErrFatalf("error creating file at path %s: %v", path, err) + } + + if _, err = fmt.Fprint(file, s); err != nil { + ErrFatalf("error writing to file at path %s: %s", path, err) + } +} diff --git a/cmd/gator/verify/verify.go b/cmd/gator/verify/verify.go index 3b4ab49b39d..74c4b243911 100644 --- a/cmd/gator/verify/verify.go +++ b/cmd/gator/verify/verify.go @@ -10,33 +10,34 @@ import ( "runtime" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/gator" - "github.com/open-policy-agent/gatekeeper/pkg/gator/verify" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/verify" "github.com/spf13/cobra" ) const ( - examples = ` # Run all tests in label-tests.yaml - gator verify label-tests.yaml + examples = `# Run all tests in label-tests.yaml +gator verify label-tests.yaml - # Run all tests whose names contain "forbid-labels". - gator verify tests/... --run forbid-labels// +# Run all tests whose names contain "forbid-labels". +gator verify tests/... --run forbid-labels// - # Run all cases whose names contain "nginx-deployment". - gator verify tests/... --run //nginx-deployment +# Run all cases whose names contain "nginx-deployment". +gator verify tests/... --run //nginx-deployment - # Run all cases whose names exactly match "nginx-deployment". - gator verify tests/... --run '//^nginx-deployment$' +# Run all cases whose names exactly match "nginx-deployment". +gator verify tests/... --run '//^nginx-deployment$' - # Run all cases that are either named "forbid-labels" or are - # in tests named "forbid-labels". - gator verify tests/... --run '^forbid-labels$'` +# Run all cases that are either named "forbid-labels" or are +# in tests named "forbid-labels". +gator verify tests/... --run '^forbid-labels$'` ) var ( - run string - verbose bool - includeTrace bool + run string + verbose bool + includeTrace bool + flagEnableK8sCel bool ) func init() { @@ -46,6 +47,8 @@ func init() { `print extended test output`) Cmd.Flags().BoolVarP(&includeTrace, "trace", "t", false, `include a trace for the underlying constraint framework evaluation`) + Cmd.Flags().BoolVarP(&flagEnableK8sCel, "experimental-enable-k8s-native-validation", "", false, + `PROTOTYPE (not stable): enable the validating admission policy driver`) } // Cmd is the gator verify subcommand. @@ -109,7 +112,7 @@ func runE(cmd *cobra.Command, args []string) error { func runSuites(ctx context.Context, fileSystem fs.FS, suites []*verify.Suite, filter verify.Filter) error { isFailure := false - runner, err := verify.NewRunner(fileSystem, gator.NewOPAClient, verify.IncludeTrace(includeTrace)) + runner, err := verify.NewRunner(fileSystem, gator.NewOPAClient, verify.IncludeTrace(includeTrace), verify.UseK8sCEL(flagEnableK8sCel)) if err != nil { return err } diff --git a/config/crd/bases/config.gatekeeper.sh_configs.yaml b/config/crd/bases/config.gatekeeper.sh_configs.yaml index 94c33b6ebbb..f9207c4dbab 100644 --- a/config/crd/bases/config.gatekeeper.sh_configs.yaml +++ b/config/crd/bases/config.gatekeeper.sh_configs.yaml @@ -45,7 +45,7 @@ spec: or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array processes: diff --git a/config/crd/bases/expansion.gatekeeper.sh_expansiontemplate.yaml b/config/crd/bases/expansion.gatekeeper.sh_expansiontemplate.yaml index 12f7f40d95e..e9a9298cb20 100644 --- a/config/crd/bases/expansion.gatekeeper.sh_expansiontemplate.yaml +++ b/config/crd/bases/expansion.gatekeeper.sh_expansiontemplate.yaml @@ -79,6 +79,155 @@ spec: generators, this is usually spec.template type: string type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed + state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after + modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including + UUIDs. Because we don't ONLY use UUIDs, this is an alias + to string. Being a type captures intent and helps make sure + that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object type: object served: true storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplate is the Schema for the ExpansionTemplate API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExpansionTemplateSpec defines the desired state of ExpansionTemplate. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds + of generator resources which will be expanded. + items: + description: ApplyTo determines what GVKs items the mutation should + apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + enforcementAction: + description: EnforcementAction specifies the enforcement action to + be used for resources matching the ExpansionTemplate. Specifying + an empty value will use the enforcement action specified by the + Constraint in violation. + type: string + generatedGVK: + description: GeneratedGVK specifies the GVK of the resources which + the generator resource creates. + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + templateSource: + description: TemplateSource specifies the source field on the generator + resource to use as the base for expanded resource. For Pod-creating + generators, this is usually spec.template + type: string + type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed + state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after + modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including + UUIDs. Because we don't ONLY use UUIDs, this is an alias + to string. Being a type captures intent and helps make sure + that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} diff --git a/config/crd/bases/match.gatekeeper.sh_matchcrd.yaml b/config/crd/bases/match.gatekeeper.sh_matchcrd.yaml new file mode 100644 index 00000000000..1fd9983a63b --- /dev/null +++ b/config/crd/bases/match.gatekeeper.sh_matchcrd.yaml @@ -0,0 +1,209 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: matchcrd.match.gatekeeper.sh +spec: + group: match.gatekeeper.sh + names: + kind: DummyCRD + listKind: DummyCRDList + plural: matchcrd + singular: dummycrd + scope: Namespaced + versions: + - name: match + schema: + openAPIV3Schema: + description: DummyCRD is a "dummy" CRD to hold the Match object, which we + ultimately need to generate JSONSchemaProps. The TypeMeta and ObjectMeta + fields are required for controller-gen to generate the CRD. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + embeddedMatch: + description: Match selects which objects are in scope. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If + defined, a constraint only applies to resources not in a listed + namespace. ExcludedNamespaces also supports a prefix or suffix based + glob. For example, `excludedNamespaces: [kube-*]` matches both + `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` + matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. + Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" + will match "kube-system" or "gatekeeper-system". The asterisk + is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and + kinds fields that list the groups/kinds of objects to which the + mutation will apply. If multiple groups/kinds objects are specified, + only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of the + slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: + `matchLabels` and `matchExpressions`. These two fields provide + different methods of selecting or excluding k8s objects based on + the label keys and values included in object metadata. All selection + expressions from both sections are ANDed to determine if an object + meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will + match against objects with the specified name. Name also supports + a prefix or suffix glob. For example, `name: pod-*` would match + both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` + and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's + containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, + a constraint only applies to resources in a listed namespace. Namespaces + also supports a prefix or suffix based glob. For example, `namespaces: + [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: + [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. + Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" + will match "kube-system" or "gatekeeper-system". The asterisk + is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped + resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. + (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources + are matched. Accepts `Generated`|`Original`|`All` (defaults to `All`). + A value of `Generated` will only match generated resources, while + `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadataDummy: + type: object + type: object + served: true + storage: true diff --git a/config/crd/bases/mutations.gatekeeper.sh_assign.yaml b/config/crd/bases/mutations.gatekeeper.sh_assign.yaml index 51ab6d565ac..42d3c1bc386 100644 --- a/config/crd/bases/mutations.gatekeeper.sh_assign.yaml +++ b/config/crd/bases/mutations.gatekeeper.sh_assign.yaml @@ -79,7 +79,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -158,7 +158,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -217,7 +217,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -426,7 +426,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -505,7 +505,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -564,7 +564,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -773,7 +773,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -852,7 +852,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -911,7 +911,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/config/crd/bases/mutations.gatekeeper.sh_assignimage.yaml b/config/crd/bases/mutations.gatekeeper.sh_assignimage.yaml new file mode 100644 index 00000000000..b472e067181 --- /dev/null +++ b/config/crd/bases/mutations.gatekeeper.sh_assignimage.yaml @@ -0,0 +1,326 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: assignimage.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignImage + listKind: AssignImageList + plural: assignimage + singular: assignimage + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignImage is the Schema for the assignimage API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AssignImageSpec defines the desired state of AssignImage. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds + a mutation will be applied to. This is necessary because every mutation + implies part of an object schema and object schemas are associated + with specific GVKs. + items: + description: ApplyTo determines what GVKs items the mutation should + apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + description: 'Location describes the path to be mutated, for example: + `spec.containers[name: main].image`.' + type: string + match: + description: Match allows the user to limit which resources get mutated. + Individual match criteria are AND-ed together. An undefined match + criteria matches everything. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. + If defined, a constraint only applies to resources not in a + listed namespace. ExcludedNamespaces also supports a prefix + or suffix based glob. For example, `excludedNamespaces: [kube-*]` + matches both `kube-system` and `kube-public`, and `excludedNamespaces: + [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or + end. Ex: "kube-*" will match "kube-system" or "kube-public", + "*-system" will match "kube-system" or "gatekeeper-system". The + asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups + and kinds fields that list the groups/kinds of objects to + which the mutation will apply. If multiple groups/kinds objects + are specified, only one match is needed for the resource to + be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of + the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional + fields: `matchLabels` and `matchExpressions`. These two fields + provide different methods of selecting or excluding k8s objects + based on the label keys and values included in object metadata. All + selection expressions from both sections are ANDed to determine + if an object meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will + match against objects with the specified name. Name also supports + a prefix or suffix glob. For example, `name: pod-*` would match + both `pod-a` and `pod-b`, and `name: *-pod` would match both + `a-pod` and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an + object's containing namespace or the object itself, if the object + is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, + a constraint only applies to resources in a listed namespace. Namespaces + also supports a prefix or suffix based glob. For example, `namespaces: + [kube-*]` matches both `kube-system` and `kube-public`, and + `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or + end. Ex: "kube-*" will match "kube-system" or "kube-public", + "*-system" will match "kube-system" or "gatekeeper-system". The + asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped + resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. + (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources + are matched. Accepts `Generated`|`Original`|`All` (defaults + to `All`). A value of `Generated` will only match generated + resources, while `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + parameters: + description: Parameters define the behavior of the mutator. + properties: + assignDomain: + description: AssignDomain sets the domain component on an image + string. The trailing slash should not be included. + type: string + assignPath: + description: AssignPath sets the domain component on an image + string. + type: string + assignTag: + description: AssignImage sets the image component on an image + string. It must start with a `:` or `@`. + type: string + pathTests: + items: + description: "PathTest allows the user to customize how the + mutation works if parent paths are missing. It traverses the + list in order. All sub paths are tested against the provided + condition, if the test fails, the mutation is not applied. + All `subPath` entries must be a prefix of `location`. Any + glob characters will take on the same value as was used to + expand the matching glob in `location`. \n Available Tests: + * MustExist - the path must exist or do not mutate * MustNotExist + - the path must not exist or do not mutate." + properties: + condition: + description: Condition describes whether the path either + MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignImageStatus defines the observed state of AssignImage. + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of + MutatorPodStatus. + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught + while adding a mutator to a system. + properties: + message: + type: string + type: + description: Type indicates a specific class of error + for use by controller code. If not present, the error + should be treated as not matching any known type. + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, + such as when a mutator has been recreated after its CRD was + deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/mutations.gatekeeper.sh_assignmetadata.yaml b/config/crd/bases/mutations.gatekeeper.sh_assignmetadata.yaml index 895f3c44790..902aba1db61 100644 --- a/config/crd/bases/mutations.gatekeeper.sh_assignmetadata.yaml +++ b/config/crd/bases/mutations.gatekeeper.sh_assignmetadata.yaml @@ -38,7 +38,7 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. @@ -52,7 +52,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -131,7 +131,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -190,7 +190,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -337,7 +337,7 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. @@ -351,7 +351,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -430,7 +430,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -489,7 +489,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -636,7 +636,7 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. @@ -650,7 +650,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -729,7 +729,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -788,7 +788,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/config/crd/bases/mutations.gatekeeper.sh_modifyset.yaml b/config/crd/bases/mutations.gatekeeper.sh_modifyset.yaml index 44f24d1ef09..7e95583fb54 100644 --- a/config/crd/bases/mutations.gatekeeper.sh_modifyset.yaml +++ b/config/crd/bases/mutations.gatekeeper.sh_modifyset.yaml @@ -80,7 +80,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -159,7 +159,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -218,7 +218,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -393,7 +393,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -472,7 +472,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -531,7 +531,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -706,7 +706,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -785,7 +785,7 @@ spec: a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an @@ -844,7 +844,7 @@ spec: end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/config/crd/bases/status.gatekeeper.sh_expansiontemplatepodstatuses.yaml b/config/crd/bases/status.gatekeeper.sh_expansiontemplatepodstatuses.yaml new file mode 100644 index 00000000000..4335d45f5ca --- /dev/null +++ b/config/crd/bases/status.gatekeeper.sh_expansiontemplatepodstatuses.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: expansiontemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ExpansionTemplatePodStatus + listKind: ExpansionTemplatePodStatusList + plural: expansiontemplatepodstatuses + singular: expansiontemplatepodstatus + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses + API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ExpansionTemplatePodStatusStatus defines the observed state + of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying + this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including + UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being + a type captures intent and helps make sure that UIDs and names do + not get conflated. + type: string + type: object + type: object + served: true + storage: true diff --git a/config/crd/bases/syncset.gatekeeper.sh_syncsets.yaml b/config/crd/bases/syncset.gatekeeper.sh_syncsets.yaml new file mode 100644 index 00000000000..790fb2a7436 --- /dev/null +++ b/config/crd/bases/syncset.gatekeeper.sh_syncsets.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: syncsets.syncset.gatekeeper.sh +spec: + group: syncset.gatekeeper.sh + names: + kind: SyncSet + listKind: SyncSetList + plural: syncsets + singular: syncset + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SyncSet is the Schema for the SyncSet API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + gvks: + items: + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 2d096889dd6..9d6344716ec 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -3,10 +3,13 @@ # It should be run by config/default resources: - bases/config.gatekeeper.sh_configs.yaml +#- bases/syncset.gatekeeper.sh_syncsets.yaml - bases/status.gatekeeper.sh_constraintpodstatuses.yaml - bases/status.gatekeeper.sh_constrainttemplatepodstatuses.yaml - bases/status.gatekeeper.sh_mutatorpodstatuses.yaml +- bases/status.gatekeeper.sh_expansiontemplatepodstatuses.yaml - bases/mutations.gatekeeper.sh_assign.yaml +- bases/mutations.gatekeeper.sh_assignimage.yaml - bases/mutations.gatekeeper.sh_assignmetadata.yaml - bases/mutations.gatekeeper.sh_modifyset.yaml - bases/expansion.gatekeeper.sh_expansiontemplate.yaml @@ -41,11 +44,18 @@ patchesJson6902: kind: CustomResourceDefinition name: modifyset.mutations.gatekeeper.sh path: patches/max_name_size.yaml +- target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: assignimage.mutations.gatekeeper.sh + path: patches/max_name_size.yaml patchesStrategicMerge: #- patches/max_name_size_for_modifyset.yaml #- patches/max_name_size_for_assign.yaml #- patches/max_name_size_for_assignmetadata.yaml +#- patches/max_name_size_for_assignimage.yaml # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD #- patches/webhook_in_configs.yaml diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 5eeeee9022c..fb035f19865 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -56,7 +56,7 @@ spec: - "--operation=webhook" - "--operation=mutation-webhook" - "--disable-opa-builtin={http.send}" - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 imagePullPolicy: Always name: manager ports: @@ -148,7 +148,7 @@ spec: - --disable-cert-rotation command: - /manager - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 env: # used by Gatekeeper - name: POD_NAMESPACE diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index a7a893f5933..cb1aaf143ae 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -5,6 +5,13 @@ metadata: creationTimestamp: null name: manager-role rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - '*' resources: @@ -69,6 +76,18 @@ rules: - patch - update - watch +- apiGroups: + - expansion.gatekeeper.sh + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - externaldata.gatekeeper.sh resources: diff --git a/crd.Dockerfile b/crd.Dockerfile index 1abb6516972..c16bf18e4e3 100644 --- a/crd.Dockerfile +++ b/crd.Dockerfile @@ -1,15 +1,11 @@ -FROM alpine as builder +FROM --platform=$TARGETPLATFORM registry.k8s.io/kubectl:v1.28.2 as builder +ARG TARGETPLATFORM ARG TARGETOS ARG TARGETARCH -ARG KUBE_VERSION - -RUN apk add --no-cache curl && \ - curl -LO https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/${TARGETOS}/${TARGETARCH}/kubectl && \ - chmod +x kubectl FROM scratch as build USER 65532:65532 COPY --chown=65532:65532 * /crds/ -COPY --from=builder /kubectl /kubectl +COPY --from=builder /bin/kubectl /kubectl ENTRYPOINT ["/kubectl"] diff --git a/demo/k8s-validating-admission-policy/README.md b/demo/k8s-validating-admission-policy/README.md new file mode 100644 index 00000000000..63a65e98488 --- /dev/null +++ b/demo/k8s-validating-admission-policy/README.md @@ -0,0 +1,10 @@ +This is a demo of a prototype-stage feature and is subject to change. + +The demo will not work unless the `--experimental-enable-k8s-native-validation`` is +set. Please set `--validate-template-rego` to `false` if using Gatekeeper version 3.13.1+ but before 3.16.0. + +Note that the contents of the constraint template have changed since cutting +Gatekeeper's v3.13.0 release. To try this with the development build of +Gatekeeper, use a [dev image](https://open-policy-agent.github.io/gatekeeper/website/docs/install/#deploying-a-release-using-development-image). + +cel demo \ No newline at end of file diff --git a/demo/k8s-validating-admission-policy/bad_namespace.yaml b/demo/k8s-validating-admission-policy/bad_namespace.yaml new file mode 100644 index 00000000000..878ae205d71 --- /dev/null +++ b/demo/k8s-validating-admission-policy/bad_namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bad-production diff --git a/demo/k8s-validating-admission-policy/demo.gif b/demo/k8s-validating-admission-policy/demo.gif new file mode 100644 index 00000000000..0656b750138 Binary files /dev/null and b/demo/k8s-validating-admission-policy/demo.gif differ diff --git a/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml b/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml new file mode 100644 index 00000000000..01f7644f5ef --- /dev/null +++ b/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml @@ -0,0 +1,35 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabels +spec: + crd: + spec: + names: + kind: K8sRequiredLabels + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + properties: + message: + type: string + labels: + type: array + items: + type: object + properties: + key: + type: string + allowedRegex: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + validations: + - expression: "variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels)" + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: "!variables.params.labels.exists(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex)))" + message: "regex mismatch" diff --git a/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml b/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml new file mode 100644 index 00000000000..806e9862ffc --- /dev/null +++ b/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabels +metadata: + name: all-must-have-owner +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Namespace"] + parameters: + message: "All namespaces must have an `owner` label that points to your company username" + labels: + - key: owner + allowedRegex: "^[a-zA-Z]+.agilebank.demo$" diff --git a/demo/mutation/assignimagedemo.yaml b/demo/mutation/assignimagedemo.yaml new file mode 100644 index 00000000000..2f6e3c8162d --- /dev/null +++ b/demo/mutation/assignimagedemo.yaml @@ -0,0 +1,18 @@ +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: assign-container-image-registry +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:*].image" + parameters: + assignDomain: "mycompany.registry.io" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] diff --git a/demo/mutation/pod.yaml b/demo/mutation/pod.yaml new file mode 100644 index 00000000000..5dc4087838b --- /dev/null +++ b/demo/mutation/pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent diff --git a/deploy/gatekeeper.yaml b/deploy/gatekeeper.yaml index 5b7d55b4d62..2bcb6b94eda 100644 --- a/deploy/gatekeeper.yaml +++ b/deploy/gatekeeper.yaml @@ -97,7 +97,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -147,7 +147,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -183,7 +183,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -342,7 +342,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -392,7 +392,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -428,7 +428,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -587,7 +587,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -637,7 +637,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -673,7 +673,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -790,6 +790,244 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: assignimage.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignImage + listKind: AssignImageList + plural: assignimage + singular: assignimage + preserveUnknownFields: false + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignImage is the Schema for the assignimage API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + properties: + name: + maxLength: 63 + type: string + type: object + spec: + description: AssignImageSpec defines the desired state of AssignImage. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. This is necessary because every mutation implies part of an object schema and object schemas are associated with specific GVKs. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + description: 'Location describes the path to be mutated, for example: `spec.containers[name: main].image`.' + type: string + match: + description: Match allows the user to limit which resources get mutated. Individual match criteria are AND-ed together. An undefined match criteria matches everything. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and kinds fields that list the groups/kinds of objects to which the mutation will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions from both sections are ANDed to determine if an object meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources are matched. Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of `Generated` will only match generated resources, while `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + parameters: + description: Parameters define the behavior of the mutator. + properties: + assignDomain: + description: AssignDomain sets the domain component on an image string. The trailing slash should not be included. + type: string + assignPath: + description: AssignPath sets the domain component on an image string. + type: string + assignTag: + description: AssignImage sets the image component on an image string. It must start with a `:` or `@`. + type: string + pathTests: + items: + description: "PathTest allows the user to customize how the mutation works if parent paths are missing. It traverses the list in order. All sub paths are tested against the provided condition, if the test fails, the mutation is not applied. All `subPath` entries must be a prefix of `location`. Any glob characters will take on the same value as was used to expand the matching glob in `location`. \n Available Tests: * MustExist - the path must exist or do not mutate * MustNotExist - the path must not exist or do not mutate." + properties: + condition: + description: Condition describes whether the path either MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignImageStatus defines the observed state of AssignImage. + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus. + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while adding a mutator to a system. + properties: + message: + type: string + type: + description: Type indicates a specific class of error for use by controller code. If not present, the error should be treated as not matching any known type. + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such as when a mutator has been recreated after its CRD was deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 @@ -829,13 +1067,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -885,7 +1123,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -921,7 +1159,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1040,13 +1278,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -1096,7 +1334,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -1132,7 +1370,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1251,13 +1489,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -1307,7 +1545,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -1343,7 +1581,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1485,7 +1723,7 @@ spec: excludedNamespaces: items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array processes: @@ -1689,7 +1927,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: constrainttemplates.templates.gatekeeper.sh @@ -1748,6 +1986,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -1843,6 +2099,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -1938,6 +2212,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -2059,6 +2351,196 @@ spec: description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template type: string type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplate is the Schema for the ExpansionTemplate API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExpansionTemplateSpec defines the desired state of ExpansionTemplate. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds of generator resources which will be expanded. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + enforcementAction: + description: EnforcementAction specifies the enforcement action to be used for resources matching the ExpansionTemplate. Specifying an empty value will use the enforcement action specified by the Constraint in violation. + type: string + generatedGVK: + description: GeneratedGVK specifies the GVK of the resources which the generator resource creates. + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + templateSource: + description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template + type: string + type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: expansiontemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ExpansionTemplatePodStatus + listKind: ExpansionTemplatePodStatusList + plural: expansiontemplatepodstatuses + singular: expansiontemplatepodstatus + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object type: object served: true storage: true @@ -2130,7 +2612,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2180,7 +2662,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2216,7 +2698,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2348,7 +2830,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2398,7 +2880,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2434,7 +2916,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2566,7 +3048,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2616,7 +3098,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2652,7 +3134,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2810,7 +3292,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: providers.externaldata.gatekeeper.sh @@ -2849,12 +3331,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: true + storage: false - name: v1beta1 schema: openAPIV3Schema: @@ -2878,12 +3360,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: false + storage: true --- apiVersion: v1 kind: ServiceAccount @@ -2930,6 +3412,13 @@ metadata: gatekeeper.sh/system: "yes" name: gatekeeper-manager-role rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - '*' resources: @@ -2994,6 +3483,18 @@ rules: - patch - update - watch +- apiGroups: + - expansion.gatekeeper.sh + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - externaldata.gatekeeper.sh resources: @@ -3189,7 +3690,7 @@ spec: fieldPath: metadata.namespace - name: CONTAINER_NAME value: manager - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 imagePullPolicy: Always livenessProbe: httpGet: @@ -3306,7 +3807,7 @@ spec: fieldPath: metadata.namespace - name: CONTAINER_NAME value: manager - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 imagePullPolicy: Always livenessProbe: httpGet: diff --git a/docs/Release_Management.md b/docs/Release_Management.md index e5f35fd8b3e..85e23daf984 100644 --- a/docs/Release_Management.md +++ b/docs/Release_Management.md @@ -36,7 +36,7 @@ No plan to move to 4.0.0 unless there is a major design change like an incompati - soak for ~ 2 weeks before cutting a stable release - Release candidate release, cut from master branch - X.Y.0 (Branch: master) - - Released every ~ 2 months + - Released every ~ 3 months - Stable release, cut from master when X.Y milestone is complete **Patch Releases** diff --git a/docs/design/README.md b/docs/design/README.md index e846a5b1f44..b3dabf924c0 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1,61 +1,65 @@ # Design Docs Generally, design docs are on Google docs: -## Conventions -* [Versioning of Constraint Templates](https://docs.google.com/document/d/1vB_2wm60WCVLXoegMrupqwqKAuW6gbwEIxg3vBQj6cs/edit) - ## In Development ## Proposed -* [Template e2e Testing Design](https://docs.google.com/document/d/15nWc9TH97LF9o58CTVxYxFM9tYk8-seB5erIa2gouPo/edit) -* [ByPod Status Design](https://docs.google.com/document/d/13xmVQuE9Q8CFDpL9pzpoAyH1nIzHndP0OfccXVShiPo/edit) * [Namespace-Scoped Constraints](https://docs.google.com/document/d/1-pY7B5C6R0fjUbDu8izlcP7MSUDVDHv5XK16BFyTGRc/edit#heading=h.w8j68o8vjdts) -* [Mutation Design - 4th Edition (current approach)](https://docs.google.com/document/d/1MdchNFz9guycX__QMGxpJviPaT_MZs8iXaAFqCvoXYQ/edit?ts=5f73fb77# -) - * [Mutation Interfaces (for the current approach)](https://docs.google.com/document/d/1c5Z3g6Zsfmga7xod4--t6RrXamdAaMaqYzPNujtZb10/edit) - * [OPA Gatekeeper Mutation (alternate proposal)](https://docs.google.com/document/d/1LtNIxd-Y3oh0HPgPYdaVV7t2c6vBSwzYAFcTyxQYZjE/edit) - * [Mutation Revised Design Doc (June 2019)](https://docs.google.com/document/d/1G7WgZKx1Y3VOTUjrqn7DjDaZgSKCIZowILm_I6psrw0/edit#heading=h.mtvdjag5uj9) - * [Mutation Initial Design Doc (April 2019)](https://docs.google.com/document/d/1qTHwqoUX8AL2jodyWKB_2szrGDwhi14Ra_LlQ-ogtck/edit#heading=h.iu1ppjy7g7j) -* [External Data](https://docs.google.com/document/d/1hPi86jdsCKg8puYT5_s_73mPGExUJeZfyKmvG-XWtPc/edit#) -* [gator validate](https://docs.google.com/document/d/1B0hXDia8SExOkCVAEbPVHFJmnWeJgHziGvMxnzrENa0/edit) +* [Sync Resource](https://docs.google.com/document/d/1ZbXaEh7v_HcgrRu7N-kEucU2pXyq1Rt7cSmmFOBN2q8/edit) +* [External Data Response Cache](https://docs.google.com/document/d/1nl6iWMmh9CRT0A6cr-Nkfofv9wp210Bkf6ilLq9LLBo/edit) +* [Gator SyncSet Support](https://docs.google.com/document/d/1mBvy6Y7TDyZswdYlFBHB3Mi2irLVqga_7ZoZvfPIU0A/edit) ## Implemented -* [V3 Accepted Design](https://docs.google.com/document/d/1yC4wgpVoJj6ngYnSTtO-HeaIBl05gla562sD7qKPy3M/edit#heading=h.z0bjqzl81dpe) - * [Initial v3 Design Proposal](https://docs.google.com/document/d/1S4C5BHZDoAqw5m5aVWrr8b8fe4H3I2jymmKitoTia2Y/edit#heading=h.p63jc1w6w88d) - * [Initial v3 Design Proposal -- Detailed Design](https://docs.google.com/document/d/1oZR9b52z_EQkhit9A-ApFvz3tqsn9ckzvPyxKw1pBTo/edit) -* [Dynamic Watch Design for OPA/Gatekeeper](https://docs.google.com/document/d/1Wi3LM3sG6Qgfzm--bWb6R0SEKCkQCCt-ene6cO62FlM/edit) -* [Architecture Diagram](https://docs.google.com/document/d/1It-Mpz36ygqrElmh2hZ3DvDIqKYyKUZN6V4d7UTlEG8/edit#heading=h.rzuko1admjwd) -* [Audit Design Doc](https://docs.google.com/document/d/1EnVOOaLZ_fWxo02ZmgnvTE2PtTRbyyhKjioPe-_In28/edit) -* [Dry-Run Design Doc](https://docs.google.com/document/d/17nJDJxjY_XHV8zrMNdOi2hFgfm6XKGJi0QyznsbhQ70/edit#heading=h.z0bjqzl81dpe) -* [Constraint Framework Client Interface](https://docs.google.com/document/d/1NDOgu8F_yQqrxRRVTDiCXGXMsajA3Jtp-lwGrZsDFcI/edit#) -* [Logging Design Doc](https://docs.google.com/document/d/1ap7AKOupNcR_42s8mkSh5FV9eteXTd4VCqelKst73VY/edit) -* [Namespace Exclusion Design doc](https://docs.google.com/document/d/1yHuXFs_HQL5N9yT9QVi6AMyflWPtZS4Pg-uXczdqgZ8/edit) +* [Gatekeeper V3 Accepted Design](https://docs.google.com/document/d/1qsfeCx-Rx61Xm6JqJK-i67Gk_y__lNebdakmnhCdM7w/edit) + * [Initial v3 Design Proposal](https://docs.google.com/document/d/1GgebCUkQ6WiS_DFk24jAnS51hQz6kpIRjfkzVW3J2Cs/edit) + * [Initial v3 Design Proposal -- Detailed Design](https://docs.google.com/document/d/1VykioikDtcEtGIMQ_jsgCPEQDt5pecbEaDgA-hGryMo/edit) +* [Dynamic Watch Design for OPA/Gatekeeper](https://docs.google.com/document/d/1WWtYajE-Vfr1TDetWktjpYeMarx2PTogmIr_2Gmhkt0/edit) +* [Architecture Diagram](https://docs.google.com/document/d/1-0J8XV3Yavb7LiMkNIoyBp9MY021TrtKyu_GlpCNBU8/edit) +* [Audit Design Doc](https://docs.google.com/document/d/1VGXXb9i3-CETJvuiskLMahGceFQZh1wUffMXHdqRtck/edit) +* [Dry-Run Design Doc](https://docs.google.com/document/d/1H-JS4pJZvN_zpdfrwnu5Drsq8_qhHvk0El2s5a_SrWI/edit) +* [Constraint Framework Client Interface](https://docs.google.com/document/d/1QwqRO0D5MQsNM1D6SuH8yWACa5nSZKjI7PGzl7F0a_g/edit) +* [Logging Design Doc](https://docs.google.com/document/d/1jPl8sqZU2AEE-lxEQ-8Q2kKFS5OD93CuMm9y-htzUf8/edit) +* [Namespace Exclusion Design doc](https://docs.google.com/document/d/1PjpFrhiQu2DNl3wFS5Ts-z8yx9EwQnafhNIp1PJvFQQ/edit) * [Metrics Design Issue](https://github.com/open-policy-agent/gatekeeper/issues/157#issuecomment-553015292) -* [Gatekeeper v1beta1 CRD Deprecation](https://docs.google.com/document/d/12TD9vk79X3y0RgNxURamW4tQOyd6YjA6WrwDAqcplwg/edit#) -* [Compiler Sharding Design](https://docs.google.com/document/d/1ibCxaI-7HyWyDjQNL4iDRMHnrauufIMJ1D6LwIKdlsI/edit) -* [External Data TLS Support](https://docs.google.com/document/d/1GjV3WeC2bgQ3j37_mMpY9hr7YOAqzSJ6jDSu-DVrcmU/edit) +* [Gatekeeper v1beta1 CRD Deprecation](https://docs.google.com/document/d/1quP6ScoPiKDJrykOaReP8xRFdl66LO0586P_v5lfnQY/edit) +* [Compiler Sharding Design](https://docs.google.com/document/d/1CV9HCp8TG-q_B6TltufHIkXcTrb03LTPWzD2Vr4R_ec/edit) +* [Template e2e Testing Design](https://docs.google.com/document/d/1_DDhxDYjVxyZk090F-GznHTeT5jFMpwjEXLLhzR3AoU/edit) +* [ByPod Status Design](https://docs.google.com/document/d/1kPb3B1I6FBsthpR6hp0Q3SEB11iXoSSuWbj9t1q-_58/edit) +* [Mutation Design - 4th Edition (current approach)](https://docs.google.com/document/d/1FGJ8A9_JnGJu-pU0u6hh37JKWw7j7GhMfrvTFL9sfUA/edit) + * [Mutation Interfaces (for the current approach)](https://docs.google.com/document/d/1ihhUKly1YFJfvmTKjJLAOkQlrM1Oexr147IJbSHu5Ao/edit) + * [OPA Gatekeeper Mutation (alternate proposal)](https://docs.google.com/document/d/11V3zfQ75ugxUy_I2o6AqjWbhw1PKcMh8v3Cf8_uuwdU/edit) + * [Mutation Revised Design Doc (June 2019)](https://docs.google.com/document/d/1jluk3xL3dLxsE_9C69XWVOrSyLqzsySY0W7r9Yl0i68/edit&resourcekey=0-A4jzI3xwwxfggM9uvwctAw) + * [Mutation Initial Design Doc (April 2019)](https://docs.google.com/document/d/1-TRvdND3Q-HPzIg8pe2ZtYNkOBDnQ2CxC7SWhA0lP6g/edit) +* [External Data](https://docs.google.com/document/d/1tXsoXWFzoCdWY8BqxXCNr5qXkTbGgEf2-sEpvGSE4ZQ/edit) +* [gator validate](https://docs.google.com/document/d/1LG-GfOlXjWzz0wNCb8jdzIMplZqkyrkMmTLYx05CKY4/edit) +* [External Data TLS Support](https://docs.google.com/document/d/1z43LI38twxPiUHPuktWPB1xMnsYr7SaVgczq-WsBhck/edit) +* [Export violations using pub-sub](https://docs.google.com/document/d/1xu6c99m_qBOpztAc8uUnoY6ST8UiXyyJzrXOmMmJQ9I/edit) +* [Versioning of Constraint Templates](https://docs.google.com/document/d/1Sg4HrNl9EYkNbn6wSGcyxULELrIrNbqS28djvNtHYoY/edit) ## Roadmap (in development) * See [milestones](https://github.com/open-policy-agent/gatekeeper/milestones?direction=asc&sort=due_date) ## Roadmap (complete) -* [GA Development Path](https://docs.google.com/document/d/1Lolr_jUkVlGSyk4iGhajx1LXWsWRXhLeu3L7s3lLDGY/edit#heading=h.9aae3wnhx5k3) -* [Post-MVP Features Doc](https://docs.google.com/document/d/1t61-fcFdbNA0o1kTQd-oS2rkaUsouN4Kg6ImW8agfbk/edit#heading=h.57n2tr53h5l) -* [MVP for Alpha](https://docs.google.com/document/d/1EPb3zg-hknAK7WqYh96XIXCEXG9mQqr_Cqn8VuEGoLI/edit#heading=h.vu8n6esi249) +* [GA Development Path](https://docs.google.com/document/d/19iMT3CQ_DFKfSy9Ypxty4QEFyNH5U_ZO3RF056NtL00/edit) +* [Post-MVP Features Doc](https://docs.google.com/document/d/1xtfrEGcA7MxRlMox-WSOQEpZ58gXWUU4S-Jeg47fQ6s/edit) +* [MVP for Alpha](https://docs.google.com/document/d/18xonIGw5iM_U4wbgl18O6G4xSpShnZA3rM8vyRPGLfg/edit) ## Discussions These docs may not be design docs in themselves, but seek to influence design decisions -* [Mutation Dynamics](https://docs.google.com/document/d/1WKj-9xYYVO9IckQVZHYVFCziRVS6zxCfvJxWbkbLcOM/view#) +* [Mutation Convergence Proof](https://docs.google.com/document/d/1ZGV9H0xpafogtpMy_GnZVSHygwa01VsBtxyD3nWd_BA/edit) + * This looks at the elements of mutation that allow us to assert that any combination of mutators should converge + and should serve as a guide when considering changes in behavior to mutation. +* [Mutation Dynamics](https://docs.google.com/document/d/1VkNIWPrHnaPbMRfkjyhyAPWoloiOq0lpTIHbTvBhVUA/edit) * A dissection of the mutation problem space, attempting to break down the salient behavioral elements and figure out what's needed for a user-friendly set of mutation primitives. -* [Mutation Transience](https://docs.google.com/document/d/1pyM3h5c8gh5W2eKP37qpge9jtEtRAs6Uv_sTyJttm3c/edit?ts=606f8bbf#) +* [Mutation Transience](https://docs.google.com/document/d/1cKK1LQDm5LYu3Iqbi0HXrK5nacjEB88xGEJF8qwH708/edit) * Looking at how a mutation webhook may behave during configuration changes and discussing what that might mean in terms of necessary status fields and best practices for writing mutators. -* [Finalizers in OPA Gatekeeper](https://docs.google.com/document/d/1lZZsHACi4LnPF4bBvjfg0qpbYGChkZd6mhaaRnvkx6M/view#) +* [Finalizers in OPA Gatekeeper](https://docs.google.com/document/d/179uwLOU_t8TjUyxRagDN6qKJsJqJirIS7HDvg2ft1yw/edit) * This doc discusses the impact the existence of finalizers has on running OPA Gatekeeper. Its points have either been addressed or are on track to being addressed. diff --git a/gator.Dockerfile b/gator.Dockerfile index a931d288ffe..20f9d66419c 100644 --- a/gator.Dockerfile +++ b/gator.Dockerfile @@ -1,5 +1,5 @@ ARG BUILDPLATFORM="linux/amd64" -ARG BUILDERIMAGE="golang:1.19-bullseye" +ARG BUILDERIMAGE="golang:1.21-bullseye" # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details ARG BASEIMAGE="gcr.io/distroless/static:nonroot" @@ -13,16 +13,15 @@ ARG TARGETVARIANT="" ARG LDFLAGS ENV GO111MODULE=on \ - CGO_ENABLED=0 \ + CGO_ENABLED=1 \ GOOS=${TARGETOS} \ GOARCH=${TARGETARCH} \ GOARM=${TARGETVARIANT} -COPY . /tmp/gatekeeper +COPY . /go/src/github.com/open-policy-agent/gatekeeper +WORKDIR /go/src/github.com/open-policy-agent/gatekeeper/cmd/gator -WORKDIR /tmp/gatekeeper/cmd/gator - -RUN go build -mod vendor -a -ldflags "${LDFLAGS:--X github.com/open-policy-agent/gatekeeper/pkg/version.Version=latest -X main.frameworksVersion=latest -X main.opaVersion=latest}" -o /gator +RUN go build -mod vendor -a -ldflags "${LDFLAGS}" -o /gator FROM --platform=$BUILDPLATFORM $BASEIMAGE as build USER 65532:65532 diff --git a/go.mod b/go.mod index f4986218657..239c5123756 100644 --- a/go.mod +++ b/go.mod @@ -1,103 +1,110 @@ -module github.com/open-policy-agent/gatekeeper +module github.com/open-policy-agent/gatekeeper/v3 -go 1.18 +go 1.20 -// Prevent otel dependencies from getting out of sync. -replace ( - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 - go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v0.20.0 - go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0 - go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v0.20.0 - go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v0.7.0 -) +// We are forking from commit 116a1b831fffe7ccc3c8145306c3e1a3b1b14ffa (tag: v0.15.0) to enable dynamic informer caching +replace sigs.k8s.io/controller-runtime => ./third_party/sigs.k8s.io/controller-runtime require ( - cloud.google.com/go/trace v1.2.0 + cloud.google.com/go/trace v1.10.1 contrib.go.opencensus.io/exporter/ocagent v0.7.0 contrib.go.opencensus.io/exporter/prometheus v0.4.2 contrib.go.opencensus.io/exporter/stackdriver v0.13.14 + github.com/dapr/go-sdk v1.8.0 github.com/davecgh/go-spew v1.1.1 - github.com/ghodss/yaml v1.0.0 - github.com/go-logr/logr v1.2.3 - github.com/go-logr/zapr v1.2.3 + github.com/dominikbraun/graph v0.16.2 + github.com/go-logr/logr v1.2.4 + github.com/go-logr/zapr v1.2.4 + github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.5.9 - github.com/google/uuid v1.3.0 - github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.19.0 - github.com/open-policy-agent/cert-controller v0.4.0 - github.com/open-policy-agent/frameworks/constraint v0.0.0-20221214024800-b745745c4118 + github.com/google/uuid v1.3.1 + github.com/onsi/gomega v1.27.7 + github.com/open-policy-agent/cert-controller v0.8.0 + github.com/open-policy-agent/frameworks/constraint v0.0.0-20231030230613-2e0cb3d68575 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.14.0 - github.com/spf13/cobra v1.6.1 - github.com/stretchr/testify v1.8.1 - go.opencensus.io v0.23.0 - go.uber.org/automaxprocs v1.5.1 - go.uber.org/zap v1.21.0 - golang.org/x/net v0.4.0 - golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 - golang.org/x/sync v0.1.0 - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 + github.com/prometheus/client_golang v1.16.0 + github.com/spf13/cobra v1.7.0 + github.com/stretchr/testify v1.8.4 + go.opencensus.io v0.24.0 + go.uber.org/automaxprocs v1.5.3 + go.uber.org/zap v1.24.0 + golang.org/x/net v0.17.0 + golang.org/x/oauth2 v0.10.0 + golang.org/x/sync v0.3.0 + golang.org/x/time v0.3.0 + google.golang.org/grpc v1.58.2 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.24.9 - k8s.io/apiextensions-apiserver v0.24.7 - k8s.io/apimachinery v0.24.9 - k8s.io/client-go v0.24.9 - k8s.io/klog/v2 v2.70.1 - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 - oras.land/oras-go v1.2.2 - sigs.k8s.io/controller-runtime v0.12.3 + k8s.io/api v0.27.4 + k8s.io/apiextensions-apiserver v0.27.4 + k8s.io/apimachinery v0.27.4 + k8s.io/client-go v0.27.4 + k8s.io/klog/v2 v2.90.1 + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 + oras.land/oras-go v1.2.4 + sigs.k8s.io/controller-runtime v0.15.0 + sigs.k8s.io/release-utils v0.7.3 sigs.k8s.io/yaml v1.3.0 ) require ( - cloud.google.com/go/compute v1.6.1 // indirect - cloud.google.com/go/monitoring v1.5.0 // indirect + cloud.google.com/go/compute v1.21.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/monitoring v1.15.1 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/hcsshim v0.11.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect - github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e // indirect + github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/aws/aws-sdk-go v1.44.23 // indirect + github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/containerd v1.6.12 // indirect - github.com/docker/cli v20.10.21+incompatible // indirect - github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.21+incompatible // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect + github.com/containerd/containerd v1.7.6 // indirect + github.com/docker/cli v24.0.6+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.6+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect - github.com/docker/go-units v0.4.0 // indirect - github.com/emicklei/go-restful v2.16.0+incompatible // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-chi/chi/v5 v5.0.8 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/swag v0.21.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.0.0 // indirect + github.com/golang/glog v1.1.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/cel-go v0.10.2 // indirect - github.com/google/gnostic v0.6.9 // indirect + github.com/google/cel-go v0.12.6 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/google/s2a-go v0.1.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/imdario/mergo v0.3.13 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/compress v1.16.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect @@ -107,51 +114,49 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/open-policy-agent/opa v0.47.2 // indirect + github.com/open-policy-agent/opa v0.57.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc2 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/prometheus/prometheus v0.35.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/yashtewari/glob-intersection v0.1.0 // indirect - go.opentelemetry.io/contrib v0.20.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 // indirect - go.opentelemetry.io/otel v1.7.0 // indirect - go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect - go.opentelemetry.io/otel/metric v0.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.7.0 // indirect - go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect - go.opentelemetry.io/otel/trace v1.7.0 // indirect - go.opentelemetry.io/proto/otlp v0.16.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.8.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect - google.golang.org/api v0.81.0 // indirect + github.com/yashtewari/glob-intersection v0.2.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/sdk v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect + google.golang.org/api v0.126.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 // indirect - google.golang.org/grpc v1.51.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - k8s.io/apiserver v0.24.7 // indirect - k8s.io/component-base v0.24.7 // indirect - k8s.io/kube-openapi v0.0.0-20220413171646-5e7f5fdc6da6 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 // indirect - sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + k8s.io/apiserver v0.27.4 // indirect + k8s.io/component-base v0.27.4 // indirect + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) diff --git a/go.sum b/go.sum index 1a71e6e1ebf..d6dd4aefda2 100644 --- a/go.sum +++ b/go.sum @@ -28,7 +28,6 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= 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= @@ -39,14 +38,15 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk= +cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= 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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/monitoring v1.5.0 h1:ZltYv8e69fJVga7RTthUBGdx4+Pwz6GRF1V3zylERl4= -cloud.google.com/go/monitoring v1.5.0/go.mod h1:/o9y8NYX5j91JjD/JvGLYbi86kL11OjyJXq2XziLJu4= +cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58= +cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= 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= @@ -56,8 +56,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo 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= -cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= -cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= +cloud.google.com/go/trace v1.10.1 h1:EwGdOLCNfYOOPtgqo+D2sDLZmRCEO1AagRTJCU6ztdg= +cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= contrib.go.opencensus.io/exporter/ocagent v0.7.0 h1:BEfdCTXfMV30tLZD8c9n64V/tIZX5+9sXiuFLnrr1k8= contrib.go.opencensus.io/exporter/ocagent v0.7.0/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= @@ -66,6 +66,8 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.14 h1:zBakwHardp9Jcb8sQHcHpX contrib.go.opencensus.io/exporter/stackdriver v0.13.14/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -102,7 +104,7 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= @@ -114,7 +116,8 @@ github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwT github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.5 h1:AbV+VPfTrIVffukazHcpxmz/sRiE6YaMDzHWR9BXZHo= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= +github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -139,8 +142,8 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e h1:GCzyKMDDjSGnlpl3clrdAK7I1AaVoaiKDOYkUzChZzg= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -149,7 +152,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= @@ -157,9 +159,8 @@ github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:W github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.23 h1:oFvpKJk5qdprnCcuCWk2/CADdvfYtyduQ392bMXjlYI= -github.com/aws/aws-sdk-go v1.44.23/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -190,16 +191,19 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= @@ -228,6 +232,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -242,8 +248,8 @@ github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4S github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= @@ -267,8 +273,8 @@ github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTV github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= -github.com/containerd/containerd v1.6.12 h1:kJ9b3mOFKf8yqo05Ob+tMoxvt1pbVWhnB0re9Y+k+8c= -github.com/containerd/containerd v1.6.12/go.mod h1:K4Bw7gjgh4TnkmQY+py/PYQGp4e7xgnHAeg87VeWb3A= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -277,6 +283,7 @@ github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -346,7 +353,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -358,12 +364,14 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= +github.com/dapr/go-sdk v1.8.0 h1:OEleeL3zUTqXxIZ7Vkk3PClAeCh1g8sZ1yR2JFZKfXM= +github.com/dapr/go-sdk v1.8.0/go.mod h1:MBcTKXg8PmBc8A968tVWQg1Xt+DZtmeVR6zVVVGcmeA= 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/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgraph-io/badger/v3 v3.2103.4 h1:WE1B07YNTTJTtG9xjBcSW2wn0RJLyiV99h959RKZqM4= +github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -376,17 +384,17 @@ github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aB github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= -github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY= +github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= -github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= -github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= +github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= @@ -398,12 +406,15 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6Uezg github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dominikbraun/graph v0.16.2 h1:EUndsCgHNQDHBdT4Q4M9GBePH3Tt0sV7DDPVWzfbEh4= +github.com/dominikbraun/graph v0.16.2/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -411,8 +422,8 @@ github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8E github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= -github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -422,27 +433,26 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -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/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/foxcpp/go-mockdns v0.0.0-20210729171921-fb145fc6f897 h1:E52jfcE64UG42SwLmrW0QByONfGynWuzBvm86BoB9z8= +github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -454,12 +464,15 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= +github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= 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-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= 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= @@ -475,13 +488,16 @@ github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7 github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= -github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= @@ -489,15 +505,16 @@ github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= github.com/go-openapi/runtime v0.23.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= @@ -511,8 +528,9 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -522,6 +540,7 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= @@ -569,8 +588,9 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= +github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -586,6 +606,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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= @@ -603,8 +624,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw 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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -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/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -613,13 +635,11 @@ github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.10.2 h1:fJtfqBC/zg/+M0W32IemohwB6u5oFWv1iVGNpgUxan0= -github.com/google/cel-go v0.10.2/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= -github.com/google/flatbuffers v2.0.6+incompatible h1:XHFReMv7nFFusa+CEokzWbzaYocKXI6C7hdU5Kgh9Lw= +github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M= +github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= 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= @@ -660,22 +680,26 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20220318212150-b2ab0324ddda h1:KdHPvlgeNEDs8rae032MqFG8LVwcSEivcCjNdVOXRmg= github.com/google/pprof v0.0.0-20220318212150-b2ab0324ddda/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= @@ -699,8 +723,10 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -755,8 +781,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= @@ -796,8 +822,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -806,8 +832,8 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -879,8 +905,8 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= @@ -910,7 +936,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -926,10 +951,9 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -939,14 +963,14 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/open-policy-agent/cert-controller v0.4.0 h1:AQntgNq7fsoHgnoKrOk0lpRyab1na09vibeJCX4YBCs= -github.com/open-policy-agent/cert-controller v0.4.0/go.mod h1:uOQW+2tMU51vSxy1Yt162oVUTMdqLuotC0aObQxrh6k= -github.com/open-policy-agent/frameworks/constraint v0.0.0-20221214024800-b745745c4118 h1:2i9k9I69KX48JTWxp+u4kfMRNgoP50A6uPPqo93uhow= -github.com/open-policy-agent/frameworks/constraint v0.0.0-20221214024800-b745745c4118/go.mod h1:sN/YfAskVfaDy234+bETlOymFLDoLdJZvMdACwenxc8= -github.com/open-policy-agent/opa v0.47.2 h1:9QmIumL6MRPYoXboBDSU/c1fG2PN5J4lo800RK36jrc= -github.com/open-policy-agent/opa v0.47.2/go.mod h1:I5DbT677OGqfk9gvu5i54oIt0rrVf4B5pedpqDquAXo= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= +github.com/open-policy-agent/cert-controller v0.8.0 h1:pao3WCLsKGz5dSWSlNUFrNFQdXtVTQ3lVDgk2IelH34= +github.com/open-policy-agent/cert-controller v0.8.0/go.mod h1:alotCQRwX4M6VEwEgO53FB6nGLSlvah6L0pWxSRslIk= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20231030230613-2e0cb3d68575 h1:rhln22JjTgsJGL8gDK4qEM372Ei1PPQk4ZTIOKM9WvY= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20231030230613-2e0cb3d68575/go.mod h1:AaCd/gbQ31R7btHO450Kdp18/Zmvn7hjEt7Qbp+MfJM= +github.com/open-policy-agent/opa v0.57.1 h1:LAa4Z0UkpjV94nRLy6XCvgOacQ6N1jf8TJLMUIzFRqc= +github.com/open-policy-agent/opa v0.57.1/go.mod h1:YYcVsWcdOW47owR0zElx8HPYZK60vL0MOPsEmh13us4= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -957,8 +981,8 @@ github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -1012,15 +1036,15 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1034,8 +1058,9 @@ github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common/assets v0.1.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= @@ -1051,8 +1076,9 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/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/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/prometheus v0.35.0 h1:N93oX6BrJ2iP3UuE2Uz4Lt+5BkUpaFer3L9CbADzesc= github.com/prometheus/prometheus v0.35.0/go.mod h1:7HaLx5kEPKJ0GDgbODG0fZgXbQ8K/XjZNJXQmbmgQlY= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= @@ -1065,6 +1091,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1091,8 +1118,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -1102,7 +1129,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1110,9 +1136,8 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1140,8 +1165,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1180,12 +1206,11 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yashtewari/glob-intersection v0.1.0 h1:6gJvMYQlTDOL3dMsPF6J0+26vwX9MB8/1q3uAdhmTrg= -github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= +github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= +github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1193,6 +1218,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= @@ -1205,12 +1231,9 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= @@ -1224,61 +1247,78 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 h1:Q3C9yzW6I9jqEc8sawxzxZmY48fs9u220KXq6d5s3XU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0/go.mod h1:PFmBsWbldL1kiWZk9+0LBZz2brhByaGsvp6pRICMlPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= +go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= +go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= +go.opentelemetry.io/otel v1.6.1/go.mod h1:blzUabWHkX6LJewxvadmzafgh/wnvBSDBdOuwkAtrWQ= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.1/go.mod h1:NEu79Xo32iVb+0gVNV8PMd7GoWqnyDXRlj04yFjqz40= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.1/go.mod h1:YJ/JbY5ag/tSQFXzH3mtDmHqzF3aFn3DI/aB1n7pt4w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.1/go.mod h1:UJJXJj0rltNIemDMwkOJyggsvyMG9QHfJeFH0HS5JjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.1/go.mod h1:DAKwdo06hFLc0U88O10x4xnb5sc7dDRDqRuiN+io8JE= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= +go.opentelemetry.io/otel/metric v0.28.0/go.mod h1:TrzsfQAmQaB1PDcdhBauLMk7nyyg9hm+GoQq/ekE9Iw= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g= +go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= +go.opentelemetry.io/otel/sdk v1.6.1/go.mod h1:IVYrddmFZ+eJqu2k38qD3WezFR2pymCzm8tdxyh3R4E= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= +go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE= +go.opentelemetry.io/otel/trace v1.6.1/go.mod h1:RkFRM1m0puWIq10oxImnGEduNBzxiN7TXluRBtE+5j0= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= +go.opentelemetry.io/proto/otlp v0.12.1/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.1 h1:e1YG66Lrk73dn4qhg8WFSvhF0JuFQF0ERIp4rpuV8Qk= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1304,8 +1344,9 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= 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= @@ -1344,7 +1385,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1404,7 +1447,6 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1414,11 +1456,9 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx 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-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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= @@ -1437,9 +1477,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= 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= @@ -1452,10 +1491,10 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-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-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1549,6 +1588,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1578,21 +1618,20 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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= @@ -1602,8 +1641,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -1612,10 +1652,9 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1689,17 +1728,15 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= 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-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= +gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= 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= @@ -1737,10 +1774,8 @@ google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQ google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= -google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= +google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= 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= @@ -1786,7 +1821,6 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1817,7 +1851,6 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= @@ -1825,15 +1858,12 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 h1:a221mAAEAzq4Lz6ZWRkcS8ptb2mxoxYSt4N68aRyQHM= -google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1868,10 +1898,8 @@ google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -1887,8 +1915,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 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= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1911,7 +1940,6 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1933,8 +1961,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= 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= @@ -1947,42 +1975,38 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= -k8s.io/api v0.24.7/go.mod h1:tt+TFsvj8um6tsywVsTdwGdPvQ4IDCMLZXFH5C2BRlU= -k8s.io/api v0.24.9 h1:KKFyOydOohfc7EZrQ4u3kPUV14DgN4b2O85KxWV+yz0= -k8s.io/api v0.24.9/go.mod h1:qQOu7t0mNvyvT5NE5rngeVHpBovp8Fd/FEI7CFZrlYY= -k8s.io/apiextensions-apiserver v0.24.7 h1:bq8kg5Q1eR6/1OaZeE6R4Cj4lBwLRyP8Lsbdrwvys1s= -k8s.io/apiextensions-apiserver v0.24.7/go.mod h1:BayNIvxdL4Fr78kGoy+nQYscNWaW4bJz8YTRvm9IqrA= +k8s.io/api v0.27.4 h1:0pCo/AN9hONazBKlNUdhQymmnfLRbSZjd5H5H3f0bSs= +k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y= +k8s.io/apiextensions-apiserver v0.27.4 h1:ie1yZG4nY/wvFMIR2hXBeSVq+HfNzib60FjnBYtPGSs= +k8s.io/apiextensions-apiserver v0.27.4/go.mod h1:KHZaDr5H9IbGEnSskEUp/DsdXe1hMQ7uzpQcYUFt2bM= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.24.7/go.mod h1:WR5z9Lpw2mOAeDg20iSSrEBRQMY0p2YXVdYpUIgSr4o= -k8s.io/apimachinery v0.24.9 h1:/oZ2GmA681mpKdt1WlLDIj0YzFRofIDZQZgSEPm7i7A= -k8s.io/apimachinery v0.24.9/go.mod h1:f8XxPIMUqMHz3z8gD6dsTYIjg1Sy02y2YNaTYY2HEjk= +k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs= +k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= -k8s.io/apiserver v0.24.7 h1:J5X1BxF0hQ7Ssu5B1P5JikBA633LXsY98oshFSxSqek= -k8s.io/apiserver v0.24.7/go.mod h1:0VDfpwku0fDEJGSGfmZN0CRy0YJ/3JG/qlNdd6aSc+w= +k8s.io/apiserver v0.27.4 h1:ncZ0MBR9yQ/Gf34rtu1EK+HqT8In1YpfAUINu/Akvho= +k8s.io/apiserver v0.27.4/go.mod h1:GDEFRfFZ4/l+pAvwYRnoSfz0K4j3TWiN4WsG2KnRteE= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= -k8s.io/client-go v0.24.7/go.mod h1:UoQaKAGHRRE77THP0jGUehwqt5javBlv1AoKdpfz3JA= -k8s.io/client-go v0.24.9 h1:iOTws1W4aUBbC6OROIQmx5qiRWgeyyqUITVQnPOEP4A= -k8s.io/client-go v0.24.9/go.mod h1:be0fCcgenPyCTGJSFtexn+dMr4jJoUX36Y5UAb1vmls= +k8s.io/client-go v0.27.4 h1:vj2YTtSJ6J4KxaC88P4pMPEQECWMY8gqPqsTgUKzvjk= +k8s.io/client-go v0.27.4/go.mod h1:ragcly7lUlN0SRPk5/ZkGnDjPknzb37TICq07WhI6Xc= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= -k8s.io/code-generator v0.24.7/go.mod h1:1B92gyaTHWnignKkQzbHIyV3hiyRlZ+prNqD6nbajPA= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= -k8s.io/component-base v0.24.7 h1:zQ3SiqZucS1thDB/5UnRV3DQ71eXvmHaLY9GPB9YJYk= -k8s.io/component-base v0.24.7/go.mod h1:ce5M3pIoOY3DoFbcQ+Y8BMEsRFd3KcrAEjrZIZf0xqw= +k8s.io/component-base v0.27.4 h1:Wqc0jMKEDGjKXdae8hBXeskRP//vu1m6ypC+gwErj4c= +k8s.io/component-base v0.27.4/go.mod h1:hoiEETnLc0ioLv6WPeDt8vD34DDeB35MfQnxCARq3kY= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -1992,7 +2016,6 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= @@ -2000,48 +2023,46 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= -k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.23.2 h1:6CoZZqNdFc9benrgSJJ0GQGgFtKjI0y3UwlBbioXtc8= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-aggregator v0.27.2 h1:jfHoPip+qN/fn3OcrYs8/xMuVYvkJHKo0H0DYciqdns= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220413171646-5e7f5fdc6da6 h1:nBQrWPlrNIiw0BsX6a6MKr1itkm0ZS0Nl97kNLitFfI= -k8s.io/kube-openapi v0.0.0-20220413171646-5e7f5fdc6da6/go.mod h1:daOouuuwd9JXpv1L7Y34iV3yf6nxzipkKMWWlqlvK9M= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -oras.land/oras-go v1.2.2 h1:0E9tOHUfrNH7TCDk5KU0jVBEzCqbfdyuVfGmJ7ZeRPE= -oras.land/oras-go v1.2.2/go.mod h1:Apa81sKoZPpP7CDciE006tSZ0x3Q3+dOoBcMZ/aNxvw= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= +oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 h1:LYqFq+6Cj2D0gFfrJvL7iElD4ET6ir3VDdhDdTK7rgc= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33/go.mod h1:soWkSNf2tZC7aMibXEqVhCd73GOY5fJikn8qbdzemB0= -sigs.k8s.io/controller-runtime v0.12.3 h1:FCM8xeY/FI8hoAfh/V4XbbYMY20gElh9yh+A98usMio= -sigs.k8s.io/controller-runtime v0.12.3/go.mod h1:qKsk4WE6zW2Hfj0G4v10EnNB2jMG1C+NTb8h+DwCoU0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 h1:2sgAQQcY0dEW2SsQwTXhQV4vO6+rSslYx8K3XmM5hqQ= -sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/release-utils v0.7.3 h1:6pS8x6c5RmdUgR9qcg1LO6hjUzuE4Yo9TGZ3DemrZdM= +sigs.k8s.io/release-utils v0.7.3/go.mod h1:n0mVez/1PZYZaZUTJmxewxH3RJ/Lf7JUDh7TG1CASOE= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/main.go b/main.go index a94d0066007..18834fa4ed6 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,8 @@ limitations under the License. package main import ( + "context" + "crypto/tls" "crypto/x509" "errors" "flag" @@ -27,50 +29,52 @@ import ( "path/filepath" "time" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - // set GOMAXPROCS to the number of container cores, if known. - _ "go.uber.org/automaxprocs" - "github.com/go-logr/zapr" "github.com/open-policy-agent/cert-controller/pkg/rotator" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" frameworksexternaldata "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - api "github.com/open-policy-agent/gatekeeper/apis" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1" - mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/audit" - "github.com/open-policy-agent/gatekeeper/pkg/controller" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/upgrade" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/version" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - "github.com/open-policy-agent/gatekeeper/pkg/webhook" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" + api "github.com/open-policy-agent/gatekeeper/v3/apis" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + expansionv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1" + expansionv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1" + mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/audit" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/upgrade" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/version" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/pkg/webhook" + _ "go.uber.org/automaxprocs" // set GOMAXPROCS to the number of container cores, if known. "go.uber.org/zap" "go.uber.org/zap/zapcore" - "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" clientgoscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "k8s.io/client-go/rest" "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/certwatcher" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/healthz" crzap "sigs.k8s.io/controller-runtime/pkg/log/zap" - // +kubebuilder:scaffold:imports + crWebhook "sigs.k8s.io/controller-runtime/pkg/webhook" ) const ( @@ -93,21 +97,23 @@ var ( ) var ( - logFile = flag.String("log-file", "", "Log to file, if specified. Default is to log to stderr.") - logLevel = flag.String("log-level", "INFO", "Minimum log level. For example, DEBUG, INFO, WARNING, ERROR. Defaulted to INFO if unspecified.") - logLevelKey = flag.String("log-level-key", "level", "JSON key for the log level field, defaults to `level`") - logLevelEncoder = flag.String("log-level-encoder", "lower", "Encoder for the value of the log level field. Valid values: [`lower`, `capital`, `color`, `capitalcolor`], default: `lower`") - healthAddr = flag.String("health-addr", ":9090", "The address to which the health endpoint binds.") - metricsAddr = flag.String("metrics-addr", "0", "The address the metric endpoint binds to.") - port = flag.Int("port", 443, "port for the server. defaulted to 443 if unspecified ") - host = flag.String("host", "", "the host address the webhook server listens on. defaults to all addresses.") - certDir = flag.String("cert-dir", "/certs", "The directory where certs are stored, defaults to /certs") - disableCertRotation = flag.Bool("disable-cert-rotation", false, "disable automatic generation and rotation of webhook TLS certificates/keys") - enableProfile = flag.Bool("enable-pprof", false, "enable pprof profiling") - profilePort = flag.Int("pprof-port", 6060, "port for pprof profiling. defaulted to 6060 if unspecified") - certServiceName = flag.String("cert-service-name", "gatekeeper-webhook-service", "The service name used to generate the TLS cert's hostname. Defaults to gatekeeper-webhook-service") - enableTLSHealthcheck = flag.Bool("enable-tls-healthcheck", false, "enable probing webhook API with certificate stored in certDir") - disabledBuiltins = util.NewFlagSet() + logFile = flag.String("log-file", "", "Log to file, if specified. Default is to log to stderr.") + logLevel = flag.String("log-level", "INFO", "Minimum log level. For example, DEBUG, INFO, WARNING, ERROR. Defaulted to INFO if unspecified.") + logLevelKey = flag.String("log-level-key", "level", "JSON key for the log level field, defaults to `level`") + logLevelEncoder = flag.String("log-level-encoder", "lower", "Encoder for the value of the log level field. Valid values: [`lower`, `capital`, `color`, `capitalcolor`], default: `lower`") + healthAddr = flag.String("health-addr", ":9090", "The address to which the health endpoint binds.") + metricsAddr = flag.String("metrics-addr", "0", "The address the metric endpoint binds to.") + port = flag.Int("port", 443, "port for the server. defaulted to 443 if unspecified ") + host = flag.String("host", "", "the host address the webhook server listens on. defaults to all addresses.") + certDir = flag.String("cert-dir", "/certs", "The directory where certs are stored, defaults to /certs") + disableCertRotation = flag.Bool("disable-cert-rotation", false, "disable automatic generation and rotation of webhook TLS certificates/keys") + enableProfile = flag.Bool("enable-pprof", false, "enable pprof profiling") + profilePort = flag.Int("pprof-port", 6060, "port for pprof profiling. defaulted to 6060 if unspecified") + certServiceName = flag.String("cert-service-name", "gatekeeper-webhook-service", "The service name used to generate the TLS cert's hostname. Defaults to gatekeeper-webhook-service") + enableTLSHealthcheck = flag.Bool("enable-tls-healthcheck", false, "enable probing webhook API with certificate stored in certDir") + disabledBuiltins = util.NewFlagSet() + enableK8sCel = flag.Bool("experimental-enable-k8s-native-validation", false, "PROTOTYPE (not stable): enable the validating admission policy driver") + externaldataProviderResponseCacheTTL = flag.Duration("external-data-provider-response-cache-ttl", 3*time.Minute, "TTL for the external data provider response cache. Specify the duration in 'h', 'm', or 's' for hours, minutes, or seconds respectively. Defaults to 3 minutes if unspecified. Setting the TTL to 0 disables the cache.") ) func init() { @@ -119,6 +125,8 @@ func init() { _ = statusv1beta1.AddToScheme(scheme) _ = mutationsv1alpha1.AddToScheme(scheme) _ = mutationsv1beta1.AddToScheme(scheme) + _ = expansionv1alpha1.AddToScheme(scheme) + _ = expansionv1beta1.AddToScheme(scheme) // +kubebuilder:scaffold:scheme flag.Var(disabledBuiltins, "disable-opa-builtin", "disable opa built-in function, this flag can be declared more than once.") @@ -140,7 +148,11 @@ func innerMain() int { setupLog.Info(fmt.Sprintf("Starting profiling on port %d", *profilePort)) go func() { addr := fmt.Sprintf("%s:%d", "localhost", *profilePort) - setupLog.Error(http.ListenAndServe(addr, nil), "unable to start profiling server") + server := http.Server{ + Addr: addr, + ReadTimeout: 5 * time.Second, + } + setupLog.Error(server.ListenAndServe(), "unable to start profiling server") }() } @@ -195,7 +207,8 @@ func innerMain() int { } config := ctrl.GetConfigOrDie() - config.UserAgent = version.GetUserAgent() + config.UserAgent = version.GetUserAgent("gatekeeper") + setupLog.Info("setting up manager", "user agent", config.UserAgent) var webhooks []rotator.WebhookInfo webhooks = webhook.AppendValidationWebhookIfEnabled(webhooks) @@ -205,18 +218,30 @@ func innerMain() int { // Must be called before ctrl.NewManager! metrics.DisableRESTClientMetrics() + serverOpts := crWebhook.Options{ + Host: *host, + Port: *port, + CertDir: *certDir, + TLSMinVersion: *webhook.TLSMinVersion, + } + if *webhook.ClientCAName != "" { + serverOpts.ClientCAName = *webhook.ClientCAName + serverOpts.TLSOpts = []func(*tls.Config){ + func(cfg *tls.Config) { + cfg.VerifyConnection = webhook.GetCertNameVerifier() + }, + } + } mgr, err := ctrl.NewManager(config, ctrl.Options{ - NewCache: dynamiccache.New, Scheme: scheme, MetricsBindAddress: *metricsAddr, LeaderElection: false, Port: *port, Host: *host, + WebhookServer: crWebhook.NewServer(serverOpts), CertDir: *certDir, HealthProbeBindAddress: *healthAddr, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, + MapperProvider: apiutil.NewDynamicRESTMapper, }) if err != nil { setupLog.Error(err, "unable to start manager") @@ -258,7 +283,7 @@ func innerMain() int { sw := watch.NewSwitch() // Setup tracker and register readiness probe. - tracker, err := readiness.SetupTracker(mgr, mutation.Enabled(), *externaldata.ExternalDataEnabled) + tracker, err := readiness.SetupTracker(mgr, mutation.Enabled(), *externaldata.ExternalDataEnabled, *expansion.ExpansionEnabled) if err != nil { setupLog.Error(err, "unable to register readiness tracker") return 1 @@ -283,17 +308,19 @@ func innerMain() int { // Setup controllers asynchronously, they will block for certificate generation if needed. setupErr := make(chan error) + ctx := ctrl.SetupSignalHandler() go func() { - setupErr <- setupControllers(mgr, sw, tracker, setupFinished) + setupErr <- setupControllers(ctx, mgr, sw, tracker, setupFinished) }() setupLog.Info("starting manager") mgrErr := make(chan error) go func() { - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error(err, "problem running manager") mgrErr <- err } + close(mgrErr) }() // block until either setupControllers or mgr has an error, or mgr exits. @@ -328,18 +355,30 @@ blockingLoop: return 0 } -func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *readiness.Tracker, setupFinished chan struct{}) error { +func setupControllers(ctx context.Context, mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *readiness.Tracker, setupFinished chan struct{}) error { // Block until the setup (certificate generation) finishes. <-setupFinished var providerCache *frameworksexternaldata.ProviderCache - args := []local.Arg{local.Tracing(false), local.DisableBuiltins(disabledBuiltins.ToSlice()...)} + args := []rego.Arg{rego.Tracing(false), rego.DisableBuiltins(disabledBuiltins.ToSlice()...)} mutationOpts := mutation.SystemOpts{Reporter: mutation.NewStatsReporter()} if *externaldata.ExternalDataEnabled { providerCache = frameworksexternaldata.NewCache() - args = append(args, local.AddExternalDataProviderCache(providerCache)) + args = append(args, rego.AddExternalDataProviderCache(providerCache)) mutationOpts.ProviderCache = providerCache + switch { + case *externaldataProviderResponseCacheTTL > 0: + providerResponseCache := frameworksexternaldata.NewProviderResponseCache(ctx, *externaldataProviderResponseCacheTTL) + args = append(args, rego.AddExternalDataProviderResponseCache(providerResponseCache)) + case *externaldataProviderResponseCacheTTL == 0: + setupLog.Info("external data provider response cache is disabled") + default: + err := fmt.Errorf("invalid value for external-data-provider-response-cache-ttl: %d", *externaldataProviderResponseCacheTTL) + setupLog.Error(err, "unable to create external data provider response cache") + return err + } + certFile := filepath.Join(*certDir, certName) keyFile := filepath.Join(*certDir, keyName) @@ -357,19 +396,38 @@ func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *rea } // register the client cert watcher to the driver - args = append(args, local.EnableExternalDataClientAuth(), local.AddExternalDataClientCertWatcher(certWatcher)) + args = append(args, rego.EnableExternalDataClientAuth(), rego.AddExternalDataClientCertWatcher(certWatcher)) // register the client cert watcher to the mutation system mutationOpts.ClientCertWatcher = certWatcher } - // initialize OPA - driver, err := local.New(args...) + + cfArgs := []constraintclient.Opt{constraintclient.Targets(&target.K8sValidationTarget{})} + + if *webhook.ValidateTemplateRego && *enableK8sCel { + err := fmt.Errorf("cannot validate template rego when K8s cel is enabled. Please disable K8s cel by setting --experimental-enable-k8s-native-validation=false or disable template rego validation by setting --validate-template-rego=false") + setupLog.Error(err, "unable to set up OPA and K8s native drivers") + return err + } + + if *enableK8sCel { + // initialize K8sValidation + k8sDriver, err := k8scel.New() + if err != nil { + setupLog.Error(err, "unable to set up K8s native driver") + return err + } + cfArgs = append(cfArgs, constraintclient.Driver(k8sDriver)) + } + + driver, err := rego.New(args...) if err != nil { setupLog.Error(err, "unable to set up Driver") return err } + cfArgs = append(cfArgs, constraintclient.Driver(driver)) - client, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + client, err := constraintclient.NewClient(cfArgs...) if err != nil { setupLog.Error(err, "unable to set up OPA client") return err @@ -377,6 +435,7 @@ func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *rea mutationSystem := mutation.NewSystem(mutationOpts) expansionSystem := expansion.NewSystem(mutationSystem) + pubsubSystem := pubsub.NewSystem() c := mgr.GetCache() dc, ok := c.(watch.RemovableCache) @@ -401,17 +460,44 @@ func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *rea // Setup all Controllers setupLog.Info("setting up controllers") - watchSet := watch.NewSet() + + // Events ch will be used to receive events from dynamic watches registered + // via the registrar below. + events := make(chan event.GenericEvent, 1024) + reg, err := wm.NewRegistrar( + cachemanager.RegistrarName, + events) + if err != nil { + setupLog.Error(err, "unable to set up watch registrar for cache manager") + return err + } + + syncMetricsCache := syncutil.NewMetricsCache() + cm, err := cachemanager.NewCacheManager(&cachemanager.Config{ + CfClient: client, + SyncMetricsCache: syncMetricsCache, + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: mgr.GetCache(), + }) + if err != nil { + setupLog.Error(err, "unable to create cache manager") + return err + } + opts := controller.Dependencies{ - Opa: client, + CFClient: client, WatchManger: wm, + SyncEventsCh: events, + CacheMgr: cm, ControllerSwitch: sw, Tracker: tracker, ProcessExcluder: processExcluder, MutationSystem: mutationSystem, ExpansionSystem: expansionSystem, ProviderCache: providerCache, - WatchSet: watchSet, + PubsubSystem: pubsubSystem, } if err := controller.AddToManager(mgr, &opts); err != nil { @@ -435,12 +521,13 @@ func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *rea if operations.IsAssigned(operations.Audit) { setupLog.Info("setting up audit") - auditCache := audit.NewAuditCacheLister(mgr.GetCache(), watchSet) + auditCache := audit.NewAuditCacheLister(mgr.GetCache(), cm) auditDeps := audit.Dependencies{ Client: client, ProcessExcluder: processExcluder, CacheLister: auditCache, ExpansionSystem: expansionSystem, + PubSubSystem: pubsubSystem, } if err := audit.AddToManager(mgr, &auditDeps); err != nil { setupLog.Error(err, "unable to register audit with the manager") @@ -459,6 +546,7 @@ func setupControllers(mgr ctrl.Manager, sw *watch.ControllerSwitch, tracker *rea setupLog.Error(err, "unable to register metrics with the manager") return err } + return nil } diff --git a/manifest_staging/charts/gatekeeper/Chart.yaml b/manifest_staging/charts/gatekeeper/Chart.yaml index 38a5497d03d..695bff1ac0d 100644 --- a/manifest_staging/charts/gatekeeper/Chart.yaml +++ b/manifest_staging/charts/gatekeeper/Chart.yaml @@ -4,8 +4,8 @@ name: gatekeeper icon: https://open-policy-agent.github.io/gatekeeper/website/img/logo.svg keywords: - open policy agent -version: 3.12.0-beta.0 +version: 3.14.0 home: https://github.com/open-policy-agent/gatekeeper sources: - https://github.com/open-policy-agent/gatekeeper.git -appVersion: v3.12.0-beta.0 +appVersion: v3.14.0 diff --git a/manifest_staging/charts/gatekeeper/README.md b/manifest_staging/charts/gatekeeper/README.md index 6e13a55b341..fe841a46a52 100644 --- a/manifest_staging/charts/gatekeeper/README.md +++ b/manifest_staging/charts/gatekeeper/README.md @@ -27,7 +27,8 @@ _See [helm install](https://helm.sh/docs/helm/helm_install/) for command documen ## Upgrade Chart **Upgrading from < v3.4.0** -Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within the chart. This follows Helm 3 Best Practices. +Chart 3.4.0 deprecates support for Helm 2 and also removes the creation of the `gatekeeper-system` Namespace from within +the chart. This follows Helm 3 Best Practices. Option 1: A simple way to upgrade is to uninstall first and re-install with 3.4.0 or greater. @@ -39,7 +40,9 @@ $ helm install -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper --creat ``` Option 2: -Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the original release, while keeping all of the resources. It then updates the annotations of the resources so that the new chart can import and manage them. +Run the `helm_migrate.sh` script before installing the 3.4.0 or greater chart. This will remove the Helm secret for the +original release, while keeping all of the resources. It then updates the annotations of the resources so that the new +chart can import and manage them. ```console $ helm_migrate.sh @@ -47,155 +50,178 @@ $ helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper ``` **Upgrading from >= v3.4.0** + ```console $ helm upgrade -n gatekeeper-system [RELEASE_NAME] gatekeeper/gatekeeper ``` _See [helm 2 to 3](https://helm.sh/docs/topics/v2_v3_migration/) for Helm 2 migration documentation._ - ## Exempting Namespace -The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during a post-install hook. +The Helm chart automatically sets the Gatekeeper flag `--exempt-namespace={{ .Release.Namespace }}` in order to exempt +the namespace where the chart is installed, and adds the `admission.gatekeeper.sh/ignore` label to the namespace during +a post-install hook. -_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more information._ +_See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/website/docs/exempt-namespaces) for more +information._ ## Parameters -| Parameter | Description | Default | -| :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | -| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | -| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | -| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | -| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | -| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | -| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | -| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | -| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | -| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | -| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | -| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | -| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | -| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | -| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | -| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | -| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | -| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | -| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | -| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | -| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` -| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | -| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | -| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | -| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | -| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| preUninstall.deleteWebhooks.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | -| preUninstall.deleteWebhooks.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | -| preUninstall.deleteWebhooks.image.tag | Image tag | Current release version: `v3.12.0-beta.0` | -| preUninstall.deleteWebhooks.image.pullPolicy | Image pullPolicy | `IfNotPresent` | -| preUninstall.deleteWebhooks.image.pullSecrets | Image pullSecrets | `[]` | -| preUninstall.deleteWebhooks.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | -| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | -| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | -| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | -| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | -| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| psp.enabled | Enabled PodSecurityPolicy | `true` | -| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | -| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | -| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | -| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | -| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | -| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | -| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | -| auditInterval | The frequency with which audit is run | `60` | -| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | -| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | -| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | -| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | -| disableValidatingWebhook | Disable the validating webhook | `false` | -| disableMutation | Disable mutation | `false` | -| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | -| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | -| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | -| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | -| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | -| enableExternalData | Enable external data | `true` | -| enableGeneratorResourceExpansion | Enable generator resource expansion (alpha feature) | `false` | -| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | -| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | -| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | -| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | -| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | -| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | -| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | -| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | -| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | -| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | -| emitAdmissionEvents | Emit K8s events in gatekeeper namespace for admission violations (alpha feature) | `false` | -| emitAuditEvents | Emit K8s events in gatekeeper namespace for audit violations (alpha feature) | `false` | -| logDenies | Log detailed info on each deny | `false` | -| logLevel | Minimum log level | `INFO` | -| image.pullPolicy | The image pull policy | `IfNotPresent` | -| image.repository | Image repository | `openpolicyagent/gatekeeper` | -| image.release | The image release tag to use | Current release version: `v3.12.0-beta.0` | -| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | -| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | -| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | -| affinity | The node affinity to use for pod scheduling | `{}` | -| topologySpreadConstraints | The topology spread constraints to use for pod scheduling | `[]` | -| tolerations | The tolerations to use for pod scheduling | `[]` | -| controllerManager.healthPort | Health port for controller manager | `9090` | -| controllerManager.port | Webhook-server port for controller manager | `8443` | -| controllerManager.metricsPort | Metrics port for controller manager | `8888` | -| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | -| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | -| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` -| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | -| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | -| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | -| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | -| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | -| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | -| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | -| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | -| controllerManager.networkPolicy.enabled | Should a network policy for the controller manager be created | `false` | -| controllerManager.networkPolicy.ingress | Additional ingress rules to be added to the controller manager network policy | `{}` | -| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | -| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | -| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | -| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | -| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | -| audit.healthPort | Health port for audit | `9090` | -| audit.metricsPort | Metrics port for audit | `8888` | -| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | -| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | -| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` -| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | -| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | -| podLabels | The labels to add to the Gatekeeper pods | `{}` | -| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | -| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | -| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | -| service.type | Service type | `ClusterIP` | -| service.loadBalancerIP | The IP address of LoadBalancer service | `` | -| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | -| rbac.create | Enable the creation of RBAC resources | `true` | -| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | -| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| Parameter | Description | Default | +|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| postInstall.labelNamespace.enabled | Add labels to the namespace during post install hooks | `true` | +| postInstall.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post install hooks | `[]` | +| postInstall.labelNamespace.extraAnnotations | Extra annotations added to the post install Job | `{}` | +| postInstall.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postInstall.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postInstall.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.labelNamespace.extraRules | Extra rules for the gatekeeper-update-namespace-label Role | `[]` | +| postInstall.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label Job | `` | +| postInstall.probeWebhook.enabled | Probe webhook API post install. When enabled along with `postInstall.labelNamespace.enabled`, this probe will run as part of `postInstall.labelNamespace` Job as an initContainer | `true` | +| postInstall.probeWebhook.image.repository | Image with curl to probe the webhook API | `curlimages/curl` | +| postInstall.probeWebhook.image.tag | Image tag | `7.83.1` | +| postInstall.probeWebhook.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postInstall.probeWebhook.image.pullSecrets | Image pullSecrets | `[]` | +| postInstall.probeWebhook.waitTimeout | Total time to wait for the webhook API to become available | `60` | +| postInstall.probeWebhook.httpTimeout | HTTP client timeout | `2` | +| postInstall.probeWebhook.insecureHTTPS | Ignore server SSL certificate | `false` | +| postInstall.probeWebhook.priorityClassName | Priority class name for gatekeeper-probe-webhook-post-install Job | `` | +| postInstall.affinity | The affinity to use for pod scheduling in postInstall hook jobs | `{}` | +| postInstall.tolerations | The tolerations to use for pod scheduling in postInstall hook jobs | `[]` | +| postInstall.nodeSelector | The node selector to use for pod scheduling in postInstall hook jobs | `kubernetes.io/os: linux` | +| postInstall.resources | The resource request/limits for the container image in postInstall hook jobs | `{}` | +| postInstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| postUpgrade.labelNamespace.enabled | Add labels to the namespace during post upgrade hooks | `false` | +| postUpgrade.labelNamespace.extraNamespaces | The extra namespaces that need to have the label during post upgrade hooks | `[]` | +| postUpgrade.labelNamespace.extraAnnotations | Extra annotations added to the post upgrade Job | `{}` | +| postUpgrade.labelNamespace.image.repository | Image with kubectl to label the namespace | `openpolicyagent/gatekeeper-crds` | +| postUpgrade.labelNamespace.image.tag | Image tag | Current release version: `v3.14.0` | +| postUpgrade.labelNamespace.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| postUpgrade.labelNamespace.image.pullSecrets | Image pullSecrets | `[]` | +| postUpgrade.labelNamespace.priorityClassName | Priority class name for gatekeeper-update-namespace-label-post-upgrade Job | `` | +| postUpgrade.affinity | The affinity to use for pod scheduling in postUpgrade hook jobs | `{}` | +| postUpgrade.tolerations | The tolerations to use for pod scheduling in postUpgrade hook jobs | `[]` | +| postUpgrade.nodeSelector | The node selector to use for pod scheduling in postUpgrade hook jobs | `kubernetes.io/os: linux` | +| postUpgrade.resources | The resource request/limits for the container image in postUpgrade hook jobs | `{}` | +| postUpgrade.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| preInstall.crdRepository.image.repository | Image with kubectl to update the CRDs. If not set, the `image.crdRepository` is used instead. | `null` | +| preInstall.crdRepository.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.enabled | Delete webhooks before gatekeeper itself is uninstalled | `false` | +| preUninstall.deleteWebhookConfigurations.image.repository | Image with kubectl to delete the webhooks | `openpolicyagent/gatekeeper-crds` | +| preUninstall.deleteWebhookConfigurations.image.tag | Image tag | Current release version: `v3.14.0` | +| preUninstall.deleteWebhookConfigurations.image.pullPolicy | Image pullPolicy | `IfNotPresent` | +| preUninstall.deleteWebhookConfigurations.image.pullSecrets | Image pullSecrets | `[]` | +| preUninstall.deleteWebhookConfigurations.extraRules | Extra rules for the gatekeeper-delete-webhook-configs Role | `[]` | +| preUninstall.deleteWebhookConfigurations.priorityClassName | Priority class name for gatekeeper-delete-webhook-configs Job | `` | +| preUninstall.affinity | The affinity to use for pod scheduling in preUninstall hook jobs | `{}` | +| preUninstall.tolerations | The tolerations to use for pod scheduling in preUninstall hook jobs | `[]` | +| preUninstall.nodeSelector | The node selector to use for pod scheduling in preUninstall hook jobs | `kubernetes.io/os: linux` | +| preUninstall.resources | The resource request/limits for the container image in preUninstall hook jobs | `{}` | +| preUninstall.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| psp.enabled | Enabled PodSecurityPolicy | `true` | +| upgradeCRDs.enabled | Upgrade CRDs using pre-install/pre-upgrade hooks | `true` | +| upgradeCRDs.extraRules | Extra rules for the gatekeeper-admin-upgrade-crds ClusterRole | `[]` | +| upgradeCRDs.priorityClassName | Priority class name for gatekeeper-update-crds-hook Job | `` | +| crds.affinity | The affinity to use for pod scheduling in crds hook jobs | `{}` | +| crds.tolerations | The tolerations to use for pod scheduling in crds hook jobs | `[]` | +| crds.nodeSelector | The node selector to use for pod scheduling in crds hook jobs | `kubernetes.io/os: linux` | +| crds.resources | The resource request/limits for the container image in crds hook jobs | `{}` | +| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` | +| auditInterval | The frequency with which audit is run | `60` | +| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` | +| auditFromCache | Take the roster of resources to audit from the audit cache | `false` | +| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` | +| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` | +| disableValidatingWebhook | Disable the validating webhook | `false` | +| disableMutation | Disable mutation | `false` | +| validatingWebhookName | The name of the `ValidatingWebhookConfiguration` | `gatekeeper-validating-webhook-configuration` | +| validatingWebhookTimeoutSeconds | The timeout for the validating webhook in seconds | `3` | +| validatingWebhookFailurePolicy | The failurePolicy for the validating webhook | `Ignore` | +| validatingWebhookAnnotations | The annotations to add to the ValidatingWebhookConfiguration | `{}` | +| validatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's validation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| validatingWebhookCheckIgnoreFailurePolicy | The failurePolicy for the check-ignore-label validating webhook | `Fail` | +| validatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the validating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| validatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. Mutually exclusive with `enableDeleteOperations`. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| validatingWebhookURL | Custom URL for Kubernetes API server to use to reach the validating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| enableDeleteOperations | Enable validating webhook for delete operations. Does not work with `validatingWebhookCustomRules` | `false` | +| enableExternalData | Enable external data | `true` | +| enableGeneratorResourceExpansion | Enable generator resource expansion (beta feature) | `true` | +| enableTLSHealthcheck | Enable probing webhook API with certificate stored in certDir | `false` | +| maxServingThreads | Limit the number of concurrent calls the validation backend made by the validation webhook. -1 limits this value to GOMAXPROCS. Configuring this value may lower max RAM usage and limit CPU throttling, Tuning it can optimize serving capacity. | `-1` | +| metricsBackends | Metrics exporters to use. Valid exporters are: `prometheus`, `stackdriver`, and `opencensus` | `["prometheus"]` | +| mutatingWebhookName | The name of the `MutatingWebhookConfiguration` | `gatekeeper-mutating-webhook-configuration` | +| mutatingWebhookFailurePolicy | The failurePolicy for the mutating webhook | `Ignore` | +| mutatingWebhookReinvocationPolicy | The reinvocationPolicy for the mutating webhook | `Never` | +| mutatingWebhookAnnotations | The annotations to add to the MutatingWebhookConfiguration | `{}` | +| mutatingWebhookExemptNamespacesLabels | Additional namespace labels that will be exempt from the mutating webhook. Please note that anyone in the cluster capable to manage namespaces will be able to skip all Gatekeeper validation by setting one of these labels for their namespace. | `{}` | +| mutatingWebhookObjectSelector | The label selector to further refine which namespaced resources will be selected by the webhook. Please note that an exemption label means users can circumvent Gatekeeper's mutation webhook unless measures are taken to control how exemption labels can be set. | `{}` | +| mutatingWebhookTimeoutSeconds | The timeout for the mutating webhook in seconds | `3` | +| mutatingWebhookCustomRules | Custom rules for selecting which API resources trigger the webhook. NOTE: If you change this, ensure all your constraints are still being enforced. | `{}` | +| mutatingWebhookURL | Custom URL for Kubernetes API server to use to reach the mutating webhook pod. If not set, the default of connecting via the kubernetes service endpoint is used. | `null` | +| emitAdmissionEvents | Emit K8s events in configurable namespace for admission violations (alpha feature) | `false` | +| emitAuditEvents | Emit K8s events in configurable namespace for audit violations (alpha feature) | `false` | +| auditEventsInvolvedNamespace | Emit audit events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Audit events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| admissionEventsInvolvedNamespace | Emit admission events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Admission events from cluster-scoped resources will continue to generate events in the namespace that Gatekeeper is installed in | `false` | +| logDenies | Log detailed info on each deny | `false` | +| logLevel | Minimum log level | `INFO` | +| image.pullPolicy | The image pull policy | `IfNotPresent` | +| image.repository | Image repository | `openpolicyagent/gatekeeper` | +| image.release | The image release tag to use | Current release version: `v3.14.0` | +| image.pullSecrets | Specify an array of imagePullSecrets | `[]` | +| resources | The resource request/limits for the container image | limits: 1 CPU, 512Mi, requests: 100mCPU, 256Mi | +| nodeSelector | The node selector to use for pod scheduling | `kubernetes.io/os: linux` | +| controllerManager.affinity | The node affinity to use for controller manager pod scheduling | `{}` | +| controllerManager.topologySpreadConstraints | The topology spread constraints to use for controller manager pod scheduling | `[]` | +| controllerManager.tolerations | The tolerations to use for controller manager pod scheduling | `[]` | +| controllerManager.healthPort | Health port for controller manager | `9090` | +| controllerManager.port | Webhook-server port for controller manager | `8443` | +| controllerManager.metricsPort | Metrics port for controller manager | `8888` | +| controllerManager.readinessTimeout | Timeout in seconds for the controller manager's readiness probe | `1` | +| controllerManager.livenessTimeout | Timeout in seconds for the controller manager's liveness probe | `1` | +| controllerManager.logLevel | The minimum log level for the controller manager, takes precedence over `logLevel` when specified | `null` | +| controllerManager.priorityClassName | Priority class name for controller manager | `system-cluster-critical` | +| controllerManager.podSecurityContext | Security context on pod level for controller manager | {fsGroup: 999, suplementalGroups: [999]} | +| controllerManager.exemptNamespaces | The exact namespaces to exempt by the admission webhook | `[]` | +| controllerManager.exemptNamespacePrefixes | The namespace prefixes to exempt by the admission webhook | `[]` | +| controllerManager.hostNetwork | Enables controllerManager to be deployed on hostNetwork | `false` | +| controllerManager.dnsPolicy | Set the dnsPolicy for controllerManager pods | `ClusterFirst` | +| controllerManager.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| controllerManager.tlsMinVersion | Set the minimum supported TLS version for validating and mutating webhook servers | `1.3` | +| controllerManager.extraRules | Extra rules for the gatekeeper-manager-role Role | `[]` | +| controllerManager.networkPolicy.enabled | Should a network policy for the controller manager be created | `false` | +| controllerManager.networkPolicy.ingress | Additional ingress rules to be added to the controller manager network policy | `{}` | +| controllerManager.strategyType | The strategy type to use for Controller Manager deployment | `RollingUpdate` | +| audit.affinity | The node affinity to use for audit pod scheduling | `{}` | +| audit.topologySpreadConstraints | The topology spread constraints to use for audit pod scheduling | `[]` | +| audit.tolerations | The tolerations to use for audit pod scheduling | `[]` | +| audit.priorityClassName | Priority class name for audit controller | `system-cluster-critical` | +| audit.podSecurityContext | Security context for audit on pod level | {fsGroup: 999, suplementalGroups: [999]} | +| audit.hostNetwork | Enables audit to be deployed on hostNetwork | `false` | +| audit.dnsPolicy | Set the dnsPolicy for audit pods | `ClusterFirst` | +| audit.securityContext | Security context applied on the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 999, "runAsNonRoot": true, "runAsUser": 1000 }` | +| audit.healthPort | Health port for audit | `9090` | +| audit.metricsPort | Metrics port for audit | `8888` | +| audit.readinessTimeout | Timeout in seconds for audit's readiness probe | `1` | +| audit.livenessTimeout | Timeout in seconds for the audit's liveness probe | `1` | +| audit.logLevel | The minimum log level for audit, takes precedence over `logLevel` when specified | `null` | +| replicas | The number of Gatekeeper replicas to deploy for the webhook | `3` | +| podAnnotations | The annotations to add to the Gatekeeper pods | `container.seccomp.security.alpha.kubernetes.io/manager: runtime/default` | +| podLabels | The labels to add to the Gatekeeper pods | `{}` | +| podCountLimit | The maximum number of Gatekeeper pods to run | `100` | +| secretAnnotations | The annotations to add to the Gatekeeper secrets | `{}` | +| pdb.controllerManager.minAvailable | The number of controller manager pods that must still be available after an eviction | `1` | +| service.type | Service type | `ClusterIP` | +| service.loadBalancerIP | The IP address of LoadBalancer service | `` | +| service.healthzPort | Service port to gatekeeper Webhook health port | `9090` | +| rbac.create | Enable the creation of RBAC resources | `true` | +| externalCertInjection.enabled | Enable the injection of an external certificate. This disables automatic certificate generation and rotation | `false` | +| externalCertInjection.secretName | Name of secret for injected certificate | `gatekeeper-webhook-server-cert` | +| externaldataProviderResponseCacheTTL | TTL for the external data provider response cache. Specify the duration in 'h', 'm', or 's' for hours, minutes, or seconds respectively. | `3m` | ## Contributing Changes -Please refer to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) for modifying the Helm chart. +Please refer +to [Contributing to Helm Chart](https://open-policy-agent.github.io/gatekeeper/website/docs/help#contributing-to-helm-chart) +for modifying the Helm chart. diff --git a/manifest_staging/charts/gatekeeper/crds/assign-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/assign-customresourcedefinition.yaml index ce98648baff..0221a194812 100644 --- a/manifest_staging/charts/gatekeeper/crds/assign-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/assign-customresourcedefinition.yaml @@ -65,7 +65,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -115,7 +115,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -151,7 +151,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -310,7 +310,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -360,7 +360,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -396,7 +396,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -555,7 +555,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -605,7 +605,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -641,7 +641,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/manifest_staging/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml new file mode 100644 index 00000000000..197f2f17933 --- /dev/null +++ b/manifest_staging/charts/gatekeeper/crds/assignimage-customresourcedefinition.yaml @@ -0,0 +1,237 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: assignimage.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignImage + listKind: AssignImageList + plural: assignimage + singular: assignimage + preserveUnknownFields: false + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignImage is the Schema for the assignimage API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + properties: + name: + maxLength: 63 + type: string + type: object + spec: + description: AssignImageSpec defines the desired state of AssignImage. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. This is necessary because every mutation implies part of an object schema and object schemas are associated with specific GVKs. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + description: 'Location describes the path to be mutated, for example: `spec.containers[name: main].image`.' + type: string + match: + description: Match allows the user to limit which resources get mutated. Individual match criteria are AND-ed together. An undefined match criteria matches everything. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and kinds fields that list the groups/kinds of objects to which the mutation will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions from both sections are ANDed to determine if an object meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources are matched. Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of `Generated` will only match generated resources, while `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + parameters: + description: Parameters define the behavior of the mutator. + properties: + assignDomain: + description: AssignDomain sets the domain component on an image string. The trailing slash should not be included. + type: string + assignPath: + description: AssignPath sets the domain component on an image string. + type: string + assignTag: + description: AssignImage sets the image component on an image string. It must start with a `:` or `@`. + type: string + pathTests: + items: + description: "PathTest allows the user to customize how the mutation works if parent paths are missing. It traverses the list in order. All sub paths are tested against the provided condition, if the test fails, the mutation is not applied. All `subPath` entries must be a prefix of `location`. Any glob characters will take on the same value as was used to expand the matching glob in `location`. \n Available Tests: * MustExist - the path must exist or do not mutate * MustNotExist - the path must not exist or do not mutate." + properties: + condition: + description: Condition describes whether the path either MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignImageStatus defines the observed state of AssignImage. + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus. + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while adding a mutator to a system. + properties: + message: + type: string + type: + description: Type indicates a specific class of error for use by controller code. If not present, the error should be treated as not matching any known type. + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such as when a mutator has been recreated after its CRD was deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/manifest_staging/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml index 3a63eef3cb3..65c17ed3ae1 100644 --- a/manifest_staging/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/assignmetadata-customresourcedefinition.yaml @@ -39,13 +39,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -95,7 +95,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -131,7 +131,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -250,13 +250,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -306,7 +306,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -342,7 +342,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -461,13 +461,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -517,7 +517,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -553,7 +553,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/manifest_staging/charts/gatekeeper/crds/config-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/config-customresourcedefinition.yaml index 57826ac09aa..269ca95f9a2 100644 --- a/manifest_staging/charts/gatekeeper/crds/config-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/config-customresourcedefinition.yaml @@ -39,7 +39,7 @@ spec: excludedNamespaces: items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array processes: diff --git a/manifest_staging/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml index a4da4e9e90f..737e3aff15b 100644 --- a/manifest_staging/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/constrainttemplate-customresourcedefinition.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: constrainttemplates.templates.gatekeeper.sh @@ -61,6 +61,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -156,6 +174,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -251,6 +287,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string diff --git a/manifest_staging/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml index 042249cf102..9d248f2ccd2 100644 --- a/manifest_staging/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/expansiontemplate-customresourcedefinition.yaml @@ -68,6 +68,133 @@ spec: description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template type: string type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object type: object served: true storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplate is the Schema for the ExpansionTemplate API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExpansionTemplateSpec defines the desired state of ExpansionTemplate. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds of generator resources which will be expanded. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + enforcementAction: + description: EnforcementAction specifies the enforcement action to be used for resources matching the ExpansionTemplate. Specifying an empty value will use the enforcement action specified by the Constraint in violation. + type: string + generatedGVK: + description: GeneratedGVK specifies the GVK of the resources which the generator resource creates. + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + templateSource: + description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template + type: string + type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} diff --git a/manifest_staging/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml new file mode 100644 index 00000000000..8f49b4c5f7f --- /dev/null +++ b/manifest_staging/charts/gatekeeper/crds/expansiontemplatepodstatus-customresourcedefinition.yaml @@ -0,0 +1,62 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: expansiontemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ExpansionTemplatePodStatus + listKind: ExpansionTemplatePodStatusList + plural: expansiontemplatepodstatuses + singular: expansiontemplatepodstatus + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: object + served: true + storage: true diff --git a/manifest_staging/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml index 1bb1933366d..46574fd369f 100644 --- a/manifest_staging/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/modifyset-customresourcedefinition.yaml @@ -65,7 +65,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -115,7 +115,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -151,7 +151,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -283,7 +283,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -333,7 +333,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -369,7 +369,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -501,7 +501,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -551,7 +551,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -587,7 +587,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: diff --git a/manifest_staging/charts/gatekeeper/crds/provider-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/provider-customresourcedefinition.yaml index 0deb6f630b1..95e66a8b8aa 100644 --- a/manifest_staging/charts/gatekeeper/crds/provider-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/provider-customresourcedefinition.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: providers.externaldata.gatekeeper.sh @@ -41,12 +41,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: true + storage: false - name: v1beta1 schema: openAPIV3Schema: @@ -70,9 +70,9 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: false + storage: true diff --git a/manifest_staging/charts/gatekeeper/templates/_helpers.tpl b/manifest_staging/charts/gatekeeper/templates/_helpers.tpl index 5ab6fe2b456..785d9912656 100644 --- a/manifest_staging/charts/gatekeeper/templates/_helpers.tpl +++ b/manifest_staging/charts/gatekeeper/templates/_helpers.tpl @@ -36,10 +36,44 @@ Adds additional pod labels to the common ones */}} {{- define "gatekeeper.podLabels" -}} {{- if .Values.podLabels }} -{{- toYaml .Values.podLabels | nindent 8 }} +{{- toYaml .Values.podLabels }} {{- end }} {{- end -}} +{{/* +Mandatory labels +*/}} +{{- define "gatekeeper.mandatoryLabels" -}} +app: {{ include "gatekeeper.name" . }} +chart: {{ include "gatekeeper.name" . }} +gatekeeper.sh/system: "yes" +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "gatekeeper.commonLabels" -}} +helm.sh/chart: {{ include "gatekeeper.chart" . }} +{{ include "gatekeeper.selectorLabels" . }} +{{- if .Chart.Version }} +app.kubernetes.io/version: {{ .Chart.Version | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels }} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "gatekeeper.selectorLabels" -}} +app.kubernetes.io/name: {{ include "gatekeeper.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + {{/* Output post install webhook probe container entry */}} @@ -47,10 +81,12 @@ Output post install webhook probe container entry - name: webhook-probe-post image: "{{ .Values.postInstall.probeWebhook.image.repository }}:{{ .Values.postInstall.probeWebhook.image.tag }}" imagePullPolicy: {{ .Values.postInstall.probeWebhook.image.pullPolicy }} - args: + command: - "curl" + args: - "--retry" - "99999" + - "--retry-connrefused" - "--retry-max-time" - "{{ .Values.postInstall.probeWebhook.waitTimeout }}" - "--retry-delay" diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml index 398b1460077..8c02264b024 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-admin-podsecuritypolicy.yaml @@ -5,11 +5,8 @@ metadata: annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} name: gatekeeper-admin spec: allowPrivilegeEscalation: false diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml index 6088a432a3a..1dc1ebac29c 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-audit-deployment.yaml @@ -13,6 +13,7 @@ metadata: namespace: '{{ .Release.Namespace }}' spec: replicas: 1 + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} selector: matchLabels: app: '{{ template "gatekeeper.name" . }}' @@ -28,6 +29,9 @@ spec: {{- if .Values.podAnnotations }} {{- toYaml .Values.podAnnotations | trim | nindent 8 }} {{- end }} + {{- if .Values.auditPodAnnotations }} + {{- toYaml .Values.auditPodAnnotations | trim | nindent 8 }} + {{- end }} labels: {{- include "gatekeeper.podLabels" . }} app: '{{ template "gatekeeper.name" . }}' @@ -51,12 +55,20 @@ spec: - --audit-interval={{ .Values.auditInterval }} - --log-level={{ (.Values.audit.logLevel | empty | not) | ternary .Values.audit.logLevel .Values.logLevel }} - --constraint-violations-limit={{ .Values.constraintViolationsLimit }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} - --audit-from-cache={{ .Values.auditFromCache }} - --audit-chunk-size={{ .Values.auditChunkSize }} - --audit-match-kind-only={{ .Values.auditMatchKindOnly }} - --emit-audit-events={{ .Values.emitAuditEvents }} + - --audit-events-involved-namespace={{ .Values.auditEventsInvolvedNamespace }} - --operation=audit - --operation=status + {{ if .Values.audit.enablePubsub}} + - --enable-pub-sub={{ .Values.audit.enablePubsub }} + - --audit-connection={{ .Values.audit.connection }} + - --audit-channel={{ .Values.audit.channel }} + {{- end }} {{ if not .Values.disableMutation}}- --operation=mutation-status{{- end }} - --logtostderr - --health-addr=:{{ .Values.audit.healthPort }} @@ -72,6 +84,7 @@ spec: - --log-file={{ .Values.audit.logFile }} {{- end }} - --disable-cert-rotation={{ or .Values.audit.disableCertRotation .Values.externalCertInjection.enabled }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} command: - /manager env: diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml index b1e5ea7f737..70c7571c2ce 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-deployment.yaml @@ -13,6 +13,7 @@ metadata: namespace: '{{ .Release.Namespace }}' spec: replicas: {{ .Values.replicas }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} selector: matchLabels: app: '{{ template "gatekeeper.name" . }}' @@ -22,6 +23,8 @@ spec: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' + strategy: + type: {{ .Values.controllerManager.strategyType }} template: metadata: annotations: @@ -54,6 +57,7 @@ spec: - --logtostderr - --log-denies={{ .Values.logDenies }} - --emit-admission-events={{ .Values.emitAdmissionEvents }} + - --admission-events-involved-namespace={{ .Values.admissionEventsInvolvedNamespace }} - --log-level={{ (.Values.controllerManager.logLevel | empty | not) | ternary .Values.controllerManager.logLevel .Values.logLevel }} - --exempt-namespace={{ .Release.Namespace }} - --operation=webhook @@ -64,6 +68,9 @@ spec: - --disable-cert-rotation={{ .Values.controllerManager.disableCertRotation }} - --max-serving-threads={{ .Values.maxServingThreads }} - --tls-min-version={{ .Values.controllerManager.tlsMinVersion }} + - --validating-webhook-configuration-name={{ .Values.validatingWebhookName }} + - --mutating-webhook-configuration-name={{ .Values.mutatingWebhookName }} + - --external-data-provider-response-cache-ttl={{ .Values.externaldataProviderResponseCacheTTL }} {{ if ne .Values.controllerManager.clientCertName "" }}- --client-cert-name={{ .Values.controllerManager.clientCertName }}{{- end }} {{- range .Values.metricsBackends}} @@ -84,6 +91,10 @@ spec: - --exempt-namespace-prefix={{ . }} {{- end }} + {{- range .Values.controllerManager.exemptNamespaceSuffixes}} + - --exempt-namespace-suffix={{ . }} + {{- end }} + {{- if .Values.controllerManager.logFile}} - --log-file={{ .Values.controllerManager.logFile }} {{- end }} diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml index e05213feb46..5ac3ca6c2c6 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-controller-manager-network-policy.yaml @@ -3,16 +3,15 @@ kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} name: gatekeeper-controller-manager spec: ingress: - from: - podSelector: matchLabels: + {{- include "gatekeeper.commonLabels" . | nindent 14 }} app: '{{ template "gatekeeper.name" . }}' release: '{{ .Release.Name }}' {{- with .Values.controllerManager.networkPolicy.ingress }} @@ -20,11 +19,8 @@ spec: {{- end }} podSelector: matchLabels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 6 }} + {{- include "gatekeeper.commonLabels" . | nindent 6 }} control-plane: controller-manager gatekeeper.sh/operation: webhook - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' {{- end -}} diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml index 8b32f96014b..3e55923360c 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml @@ -11,6 +11,13 @@ metadata: release: '{{ .Release.Name }}' name: gatekeeper-manager-role rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - '*' resources: @@ -22,7 +29,7 @@ rules: - apiGroups: - admissionregistration.k8s.io resourceNames: - - gatekeeper-mutating-webhook-configuration + - {{ .Values.mutatingWebhookName }} resources: - mutatingwebhookconfigurations verbs: @@ -75,6 +82,18 @@ rules: - patch - update - watch +- apiGroups: + - expansion.gatekeeper.sh + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - externaldata.gatekeeper.sh resources: @@ -153,7 +172,7 @@ rules: - apiGroups: - admissionregistration.k8s.io resourceNames: - - gatekeeper-validating-webhook-configuration + - {{ .Values.validatingWebhookName }} resources: - validatingwebhookconfigurations verbs: diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml index 30a23b4fb9d..ae85f8d08d3 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-mutating-webhook-configuration-mutatingwebhookconfiguration.yaml @@ -9,16 +9,20 @@ metadata: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' - name: gatekeeper-mutating-webhook-configuration + name: '{{ .Values.mutatingWebhookName }}' webhooks: - admissionReviewVersions: - v1 - v1beta1 clientConfig: + {{- if .Values.mutatingWebhookURL }} + url: https://{{ .Values.mutatingWebhookURL }}/v1/mutate + {{- else }} service: name: gatekeeper-webhook-service namespace: '{{ .Release.Namespace }}' path: /v1/mutate + {{- end }} failurePolicy: {{ .Values.mutatingWebhookFailurePolicy }} matchPolicy: Exact name: mutation.gatekeeper.sh diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml index a51dcef6bd6..933fbbd3c3e 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-validating-webhook-configuration-validatingwebhookconfiguration.yaml @@ -9,16 +9,20 @@ metadata: gatekeeper.sh/system: "yes" heritage: '{{ .Release.Service }}' release: '{{ .Release.Name }}' - name: gatekeeper-validating-webhook-configuration + name: '{{ .Values.validatingWebhookName }}' webhooks: - admissionReviewVersions: - v1 - v1beta1 clientConfig: + {{- if .Values.validatingWebhookURL }} + url: https://{{ .Values.validatingWebhookURL }}/v1/admit + {{- else }} service: name: gatekeeper-webhook-service namespace: '{{ .Release.Namespace }}' path: /v1/admit + {{- end }} failurePolicy: {{ .Values.validatingWebhookFailurePolicy }} matchPolicy: Exact name: validation.gatekeeper.sh diff --git a/manifest_staging/charts/gatekeeper/templates/namespace-post-install.yaml b/manifest_staging/charts/gatekeeper/templates/namespace-post-install.yaml index 4f84b52b409..41232de4267 100644 --- a/manifest_staging/charts/gatekeeper/templates/namespace-post-install.yaml +++ b/manifest_staging/charts/gatekeeper/templates/namespace-post-install.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -22,14 +20,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure + {{- if .Values.postInstall.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postInstall.labelNamespace.priorityClassName }} + {{- end }} {{- if .Values.postInstall.labelNamespace.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} @@ -96,7 +94,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -110,6 +110,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -141,6 +142,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/manifest_staging/charts/gatekeeper/templates/namespace-post-upgrade.yaml b/manifest_staging/charts/gatekeeper/templates/namespace-post-upgrade.yaml index 43a1dadd9fa..b26abab34e0 100644 --- a/manifest_staging/charts/gatekeeper/templates/namespace-post-upgrade.yaml +++ b/manifest_staging/charts/gatekeeper/templates/namespace-post-upgrade.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-update-namespace-label-post-upgrade + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-upgrade "helm.sh/hook-weight": "-5" @@ -20,12 +18,9 @@ spec: template: metadata: labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.postUpgrade.labelNamespace.image.pullSecrets }} @@ -33,6 +28,9 @@ spec: {{- .Values.postUpgrade.labelNamespace.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-update-namespace-label-post-upgrade + {{- if .Values.postUpgrade.labelNamespace.priorityClassName }} + priorityClassName: {{ .Values.postUpgrade.labelNamespace.priorityClassName }} + {{- end }} containers: - name: kubectl-label image: "{{ .Values.postUpgrade.labelNamespace.image.repository }}:{{ .Values.postUpgrade.labelNamespace.image.tag }}" @@ -89,6 +87,7 @@ kind: ServiceAccount metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -102,6 +101,7 @@ kind: ClusterRole metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -130,6 +130,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-update-namespace-label-post-upgrade labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/manifest_staging/charts/gatekeeper/templates/probe-webhook-post-install.yaml b/manifest_staging/charts/gatekeeper/templates/probe-webhook-post-install.yaml index 5a140d31ce0..e6ef25b594c 100644 --- a/manifest_staging/charts/gatekeeper/templates/probe-webhook-post-install.yaml +++ b/manifest_staging/charts/gatekeeper/templates/probe-webhook-post-install.yaml @@ -5,11 +5,8 @@ kind: Job metadata: name: gatekeeper-probe-webhook-post-install labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" @@ -20,14 +17,14 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: Never + {{- if .Values.postInstall.probeWebhook.priorityClassName }} + priorityClassName: {{ .Values.postInstall.probeWebhook.priorityClassName }} + {{- end }} {{- if .Values.postInstall.probeWebhook.image.pullSecrets }} imagePullSecrets: {{- .Values.postInstall.probeWebhook.image.pullSecrets | toYaml | nindent 12 }} @@ -44,5 +41,6 @@ spec: nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} {{- end }} + backoffLimit: 3 {{- end }} {{- end }} diff --git a/manifest_staging/charts/gatekeeper/templates/upgrade-crds-hook.yaml b/manifest_staging/charts/gatekeeper/templates/upgrade-crds-hook.yaml index cd57573f37a..f9347ad9c7b 100644 --- a/manifest_staging/charts/gatekeeper/templates/upgrade-crds-hook.yaml +++ b/manifest_staging/charts/gatekeeper/templates/upgrade-crds-hook.yaml @@ -5,6 +5,7 @@ kind: ClusterRole metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -26,6 +27,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-admin-upgrade-crds labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -46,6 +48,7 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} name: gatekeeper-admin-upgrade-crds @@ -61,29 +64,23 @@ metadata: name: gatekeeper-update-crds-hook namespace: {{ .Release.Namespace }} labels: - app: {{ template "gatekeeper.name" . }} - chart: {{ template "gatekeeper.name" . }} - gatekeeper.sh/system: "yes" - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: helm.sh/hook: pre-install,pre-upgrade helm.sh/hook-weight: "1" helm.sh/hook-delete-policy: "hook-succeeded,before-hook-creation" spec: - backoffLimit: 0 + backoffLimit: 3 template: metadata: name: gatekeeper-update-crds-hook annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: serviceAccountName: gatekeeper-admin-upgrade-crds restartPolicy: Never @@ -91,12 +88,23 @@ spec: imagePullSecrets: {{- toYaml .Values.image.pullSecrets | nindent 8 }} {{- end }} + {{- if .Values.upgradeCRDs.priorityClassName }} + priorityClassName: {{ .Values.upgradeCRDs.priorityClassName }} + {{- end }} containers: - name: crds-upgrade - {{- if not .Values.image.release }} - image: '{{ .Values.image.crdRepository }}' + {{- if .Values.preInstall.crdRepository.image.repository }} + {{- if not .Values.preInstall.crdRepository.image.tag }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}' + {{- else }} + image: '{{ .Values.preInstall.crdRepository.image.repository }}:{{ .Values.preInstall.crdRepository.image.tag }}' + {{- end }} {{- else }} + {{- if not .Values.image.release }} + image: '{{ .Values.image.crdRepository }}' + {{- else }} image: '{{ .Values.image.crdRepository }}:{{ .Values.image.release }}' + {{- end }} {{- end }} imagePullPolicy: '{{ .Values.image.pullPolicy }}' args: diff --git a/manifest_staging/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml b/manifest_staging/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml index d610394de36..fb359b87e16 100644 --- a/manifest_staging/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml +++ b/manifest_staging/charts/gatekeeper/templates/webhook-configs-pre-delete.yaml @@ -3,12 +3,10 @@ apiVersion: batch/v1 kind: Job metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.mandatoryLabels" . | nindent 4 }} + {{- include "gatekeeper.commonLabels" . | nindent 4 }} annotations: "helm.sh/hook": pre-delete "helm.sh/hook-weight": "-5" @@ -19,12 +17,9 @@ spec: annotations: {{- toYaml .Values.podAnnotations | trim | nindent 8 }} labels: - {{- include "gatekeeper.podLabels" . }} - app: '{{ template "gatekeeper.name" . }}' - chart: '{{ template "gatekeeper.name" . }}' - gatekeeper.sh/system: "yes" - heritage: '{{ .Release.Service }}' - release: '{{ .Release.Name }}' + {{- include "gatekeeper.podLabels" . | nindent 8 }} + {{- include "gatekeeper.mandatoryLabels" . | nindent 8 }} + {{- include "gatekeeper.commonLabels" . | nindent 8 }} spec: restartPolicy: OnFailure {{- if .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets }} @@ -32,6 +27,9 @@ spec: {{- .Values.preUninstall.deleteWebhookConfigurations.image.pullSecrets | toYaml | nindent 12 }} {{- end }} serviceAccount: gatekeeper-delete-webhook-configs + {{- if .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + priorityClassName: {{ .Values.preUninstall.deleteWebhookConfigurations.priorityClassName }} + {{- end }} containers: - name: kubectl-delete image: "{{ .Values.preUninstall.deleteWebhookConfigurations.image.repository }}:{{ .Values.preUninstall.deleteWebhookConfigurations.image.tag }}" @@ -39,19 +37,19 @@ spec: args: - delete {{- if not .Values.disableValidatingWebhook }} - - validatingwebhookconfiguration/gatekeeper-validating-webhook-configuration + - validatingwebhookconfiguration/{{ .Values.validatingWebhookName }} {{- end }} {{- if not .Values.disableMutation }} - - mutatingwebhookconfiguration/gatekeeper-mutating-webhook-configuration + - mutatingwebhookconfiguration/{{ .Values.mutatingWebhookName }} {{- end }} resources: - {{- toYaml .Values.preUninstall.resources | nindent 10 }} + {{- toYaml .Values.preUninstall.resources | nindent 12 }} securityContext: {{- if .Values.enableRuntimeDefaultSeccompProfile }} seccompProfile: type: RuntimeDefault {{- end }} - {{- toYaml .Values.preUninstall.securityContext | nindent 10 }} + {{- toYaml .Values.preUninstall.securityContext | nindent 12 }} {{- with .Values.preUninstall }} nodeSelector: {{- toYaml .nodeSelector | nindent 8 }} @@ -65,7 +63,9 @@ apiVersion: v1 kind: ServiceAccount metadata: name: gatekeeper-delete-webhook-configs + namespace: {{ .Release.Namespace | quote }} labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -79,6 +79,7 @@ kind: ClusterRole metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: @@ -92,7 +93,7 @@ rules: resources: - validatingwebhookconfigurations resourceNames: - - gatekeeper-validating-webhook-configuration + - {{ .Values.validatingWebhookName }} verbs: - delete {{- end }} @@ -102,7 +103,7 @@ rules: resources: - mutatingwebhookconfigurations resourceNames: - - gatekeeper-mutating-webhook-configuration + - {{ .Values.mutatingWebhookName }} verbs: - delete {{- end }} @@ -117,6 +118,7 @@ kind: ClusterRoleBinding metadata: name: gatekeeper-delete-webhook-configs labels: + {{- include "gatekeeper.commonLabels" . | nindent 4 }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: diff --git a/manifest_staging/charts/gatekeeper/values.yaml b/manifest_staging/charts/gatekeeper/values.yaml index 364f5ed4794..2e4c3a8666f 100644 --- a/manifest_staging/charts/gatekeeper/values.yaml +++ b/manifest_staging/charts/gatekeeper/values.yaml @@ -1,4 +1,5 @@ replicas: 3 +revisionHistoryLimit: 10 auditInterval: 60 metricsBackends: ["prometheus"] auditMatchKindOnly: false @@ -6,6 +7,7 @@ constraintViolationsLimit: 20 auditFromCache: false disableMutation: false disableValidatingWebhook: false +validatingWebhookName: gatekeeper-validating-webhook-configuration validatingWebhookTimeoutSeconds: 3 validatingWebhookFailurePolicy: Ignore validatingWebhookAnnotations: {} @@ -13,11 +15,13 @@ validatingWebhookExemptNamespacesLabels: {} validatingWebhookObjectSelector: {} validatingWebhookCheckIgnoreFailurePolicy: Fail validatingWebhookCustomRules: {} +validatingWebhookURL: null enableDeleteOperations: false enableExternalData: true -enableGeneratorResourceExpansion: false +enableGeneratorResourceExpansion: true enableTLSHealthcheck: false maxServingThreads: -1 +mutatingWebhookName: gatekeeper-mutating-webhook-configuration mutatingWebhookFailurePolicy: Ignore mutatingWebhookReinvocationPolicy: Never mutatingWebhookAnnotations: {} @@ -25,6 +29,7 @@ mutatingWebhookExemptNamespacesLabels: {} mutatingWebhookObjectSelector: {} mutatingWebhookTimeoutSeconds: 1 mutatingWebhookCustomRules: {} +mutatingWebhookURL: null mutationAnnotations: false auditChunkSize: 500 logLevel: INFO @@ -32,13 +37,27 @@ logDenies: false logMutations: false emitAdmissionEvents: false emitAuditEvents: false +admissionEventsInvolvedNamespace: false +auditEventsInvolvedNamespace: false resourceQuota: true +externaldataProviderResponseCacheTTL: 3m +image: + repository: openpolicyagent/gatekeeper + crdRepository: openpolicyagent/gatekeeper-crds + release: v3.14.0 + pullPolicy: IfNotPresent + pullSecrets: [] +preInstall: + crdRepository: + image: + repository: null + tag: v3.14.0 postUpgrade: labelNamespace: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -49,6 +68,7 @@ postUpgrade: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -68,7 +88,7 @@ postInstall: extraRules: [] image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] extraNamespaces: [] @@ -79,6 +99,7 @@ postInstall: "pod-security.kubernetes.io/enforce=restricted", "pod-security.kubernetes.io/enforce-version=v1.24"] extraAnnotations: {} + priorityClassName: "" probeWebhook: enabled: true image: @@ -89,6 +110,7 @@ postInstall: waitTimeout: 60 httpTimeout: 2 insecureHTTPS: false + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -107,9 +129,10 @@ preUninstall: enabled: false image: repository: openpolicyagent/gatekeeper-crds - tag: v3.12.0-beta.0 + tag: v3.14.0 pullPolicy: IfNotPresent pullSecrets: [] + priorityClassName: "" affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -123,13 +146,8 @@ preUninstall: runAsGroup: 999 runAsNonRoot: true runAsUser: 1000 -image: - repository: openpolicyagent/gatekeeper - crdRepository: openpolicyagent/gatekeeper-crds - release: v3.12.0-beta.0 - pullPolicy: IfNotPresent - pullSecrets: [] podAnnotations: {} +auditPodAnnotations: {} podLabels: {} podCountLimit: "100" secretAnnotations: {} @@ -146,8 +164,9 @@ controllerManager: livenessTimeout: 1 priorityClassName: system-cluster-critical disableCertRotation: false - tlsMinVersion: 1.3 + tlsMinVersion: 1.2 clientCertName: "" + strategyType: RollingUpdate affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: @@ -190,6 +209,7 @@ controllerManager: # - ipBlock: # cidr: 0.0.0.0/0 audit: + enablePubsub: false hostNetwork: false dnsPolicy: ClusterFirst metricsPort: 8888 @@ -197,7 +217,7 @@ audit: readinessTimeout: 1 livenessTimeout: 1 priorityClassName: system-cluster-critical - disableCertRotation: true + disableCertRotation: false affinity: {} tolerations: [] nodeSelector: {kubernetes.io/os: linux} @@ -246,6 +266,7 @@ psp: upgradeCRDs: enabled: true extraRules: [] + priorityClassName: "" rbac: create: true externalCertInjection: diff --git a/manifest_staging/deploy/gatekeeper.yaml b/manifest_staging/deploy/gatekeeper.yaml index 5b7d55b4d62..2bcb6b94eda 100644 --- a/manifest_staging/deploy/gatekeeper.yaml +++ b/manifest_staging/deploy/gatekeeper.yaml @@ -97,7 +97,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -147,7 +147,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -183,7 +183,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -342,7 +342,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -392,7 +392,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -428,7 +428,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -587,7 +587,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -637,7 +637,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -673,7 +673,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -790,6 +790,244 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: assignimage.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignImage + listKind: AssignImageList + plural: assignimage + singular: assignimage + preserveUnknownFields: false + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignImage is the Schema for the assignimage API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + properties: + name: + maxLength: 63 + type: string + type: object + spec: + description: AssignImageSpec defines the desired state of AssignImage. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds a mutation will be applied to. This is necessary because every mutation implies part of an object schema and object schemas are associated with specific GVKs. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + description: 'Location describes the path to be mutated, for example: `spec.containers[name: main].image`.' + type: string + match: + description: Match allows the user to limit which resources get mutated. Individual match criteria are AND-ed together. An undefined match criteria matches everything. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and kinds fields that list the groups/kinds of objects to which the mutation will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions from both sections are ANDed to determine if an object meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' + items: + description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) + type: string + source: + description: Source determines whether generated or original resources are matched. Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of `Generated` will only match generated resources, while `Original` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + parameters: + description: Parameters define the behavior of the mutator. + properties: + assignDomain: + description: AssignDomain sets the domain component on an image string. The trailing slash should not be included. + type: string + assignPath: + description: AssignPath sets the domain component on an image string. + type: string + assignTag: + description: AssignImage sets the image component on an image string. It must start with a `:` or `@`. + type: string + pathTests: + items: + description: "PathTest allows the user to customize how the mutation works if parent paths are missing. It traverses the list in order. All sub paths are tested against the provided condition, if the test fails, the mutation is not applied. All `subPath` entries must be a prefix of `location`. Any glob characters will take on the same value as was used to expand the matching glob in `location`. \n Available Tests: * MustExist - the path must exist or do not mutate * MustNotExist - the path must not exist or do not mutate." + properties: + condition: + description: Condition describes whether the path either MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignImageStatus defines the observed state of AssignImage. + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus. + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while adding a mutator to a system. + properties: + message: + type: string + type: + description: Type indicates a specific class of error for use by controller code. If not present, the error should be treated as not matching any known type. + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such as when a mutator has been recreated after its CRD was deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 @@ -829,13 +1067,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -885,7 +1123,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -921,7 +1159,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1040,13 +1278,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -1096,7 +1334,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -1132,7 +1370,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1251,13 +1489,13 @@ spec: location: type: string match: - description: Match selects objects to apply mutations to. + description: Match selects which objects are in scope. properties: excludedNamespaces: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -1307,7 +1545,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -1343,7 +1581,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -1485,7 +1723,7 @@ spec: excludedNamespaces: items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array processes: @@ -1689,7 +1927,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: constrainttemplates.templates.gatekeeper.sh @@ -1748,6 +1986,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -1843,6 +2099,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -1938,6 +2212,24 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. "Rego" can only be specified in one place (either here or in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -2059,6 +2351,196 @@ spec: description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template type: string type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplate is the Schema for the ExpansionTemplate API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExpansionTemplateSpec defines the desired state of ExpansionTemplate. + properties: + applyTo: + description: ApplyTo lists the specific groups, versions and kinds of generator resources which will be expanded. + items: + description: ApplyTo determines what GVKs items the mutation should apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + enforcementAction: + description: EnforcementAction specifies the enforcement action to be used for resources matching the ExpansionTemplate. Specifying an empty value will use the enforcement action specified by the Constraint in violation. + type: string + generatedGVK: + description: GeneratedGVK specifies the GVK of the resources which the generator resource creates. + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + templateSource: + description: TemplateSource specifies the source field on the generator resource to use as the base for expanded resource. For Pod-creating generators, this is usually spec.template + type: string + type: object + status: + description: ExpansionTemplateStatus defines the observed state of ExpansionTemplate. + properties: + byPod: + items: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + labels: + gatekeeper.sh/system: "yes" + name: expansiontemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ExpansionTemplatePodStatus + listKind: ExpansionTemplatePodStatusList + plural: expansiontemplatepodstatuses + singular: expansiontemplatepodstatus + preserveUnknownFields: false + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ExpansionTemplatePodStatus is the Schema for the expansiontemplatepodstatuses API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ExpansionTemplatePodStatusStatus defines the observed state of ExpansionTemplatePodStatus. + properties: + errors: + items: + properties: + message: + type: string + type: + type: string + required: + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated. + type: string + type: object type: object served: true storage: true @@ -2130,7 +2612,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2180,7 +2662,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2216,7 +2698,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2348,7 +2830,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2398,7 +2880,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2434,7 +2916,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2566,7 +3048,7 @@ spec: description: 'ExcludedNamespaces is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix or suffix based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array kinds: @@ -2616,7 +3098,7 @@ spec: type: object name: description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string namespaceSelector: description: NamespaceSelector is a label selector against an object's containing namespace or the object itself, if the object is a namespace. @@ -2652,7 +3134,7 @@ spec: description: 'Namespaces is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both `kube-system` and `gatekeeper-system`.' items: description: 'A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is required for wildcard matching.' - pattern: ^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$ + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ type: string type: array scope: @@ -2810,7 +3292,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 labels: gatekeeper.sh/system: "yes" name: providers.externaldata.gatekeeper.sh @@ -2849,12 +3331,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: true + storage: false - name: v1beta1 schema: openAPIV3Schema: @@ -2878,12 +3360,12 @@ spec: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with https://. type: string type: object type: object served: true - storage: false + storage: true --- apiVersion: v1 kind: ServiceAccount @@ -2930,6 +3412,13 @@ metadata: gatekeeper.sh/system: "yes" name: gatekeeper-manager-role rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch - apiGroups: - '*' resources: @@ -2994,6 +3483,18 @@ rules: - patch - update - watch +- apiGroups: + - expansion.gatekeeper.sh + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - externaldata.gatekeeper.sh resources: @@ -3189,7 +3690,7 @@ spec: fieldPath: metadata.namespace - name: CONTAINER_NAME value: manager - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 imagePullPolicy: Always livenessProbe: httpGet: @@ -3306,7 +3807,7 @@ spec: fieldPath: metadata.namespace - name: CONTAINER_NAME value: manager - image: openpolicyagent/gatekeeper:v3.12.0-beta.0 + image: openpolicyagent/gatekeeper:v3.14.0 imagePullPolicy: Always livenessProbe: httpGet: diff --git a/pkg/audit/audit_cache_lister.go b/pkg/audit/audit_cache_lister.go index 64e53b11891..89220128e37 100644 --- a/pkg/audit/audit_cache_lister.go +++ b/pkg/audit/audit_cache_lister.go @@ -3,7 +3,6 @@ package audit import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/watch" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" @@ -11,10 +10,10 @@ import ( // NewAuditCacheLister instantiates a new AuditCache which will read objects in // watched from auditCache. -func NewAuditCacheLister(auditCache client.Reader, watched *watch.Set) *CacheLister { +func NewAuditCacheLister(auditCache client.Reader, lister WatchIterator) *CacheLister { return &CacheLister{ - auditCache: auditCache, - watched: watched, + auditCache: auditCache, + watchIterator: lister, } } @@ -25,14 +24,22 @@ type CacheLister struct { // Caution: only to be read from while watched is locked, such as through // DoForEach. auditCache client.Reader - // watched is the set of objects watched by the audit cache. - watched *watch.Set + // watchIterator is a delegate like CacheManager that we can use to query a watched set of GKVs. + // Passing our logic as a callback to a watched.Set allows us to take actions while + // holding the lock on the watched.Set. This prevents us from querying the API server + // for kinds that aren't currently being watched by the CacheManager. + watchIterator WatchIterator +} + +// wraps DoForEach from a watch.Set. +type WatchIterator interface { + DoForEach(listFunc func(gvk schema.GroupVersionKind) error) error } // ListObjects lists all objects from the audit cache. func (l *CacheLister) ListObjects(ctx context.Context) ([]unstructured.Unstructured, error) { var objs []unstructured.Unstructured - err := l.watched.DoForEach(func(gvk schema.GroupVersionKind) error { + err := l.watchIterator.DoForEach(func(gvk schema.GroupVersionKind) error { gvkObjects, err := listObjects(ctx, l.auditCache, gvk) if err != nil { return err diff --git a/pkg/audit/controller.go b/pkg/audit/controller.go index b0c76aa04e8..97f1bba7692 100644 --- a/pkg/audit/controller.go +++ b/pkg/audit/controller.go @@ -14,8 +14,9 @@ package audit import ( constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub" "sigs.k8s.io/controller-runtime/pkg/manager" ) @@ -24,6 +25,7 @@ type Dependencies struct { ProcessExcluder *process.Excluder CacheLister *CacheLister ExpansionSystem *expansion.System + PubSubSystem *pubsub.System } // AddToManager adds audit manager to the Manager. diff --git a/pkg/audit/manager.go b/pkg/audit/manager.go index 0b3d8d9dbfa..3b12cadc55c 100644 --- a/pkg/audit/manager.go +++ b/pkg/audit/manager.go @@ -3,6 +3,7 @@ package audit import ( "context" "encoding/json" + "errors" "flag" "fmt" "io" @@ -14,13 +15,15 @@ import ( "github.com/go-logr/logr" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/pkg/errors" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + pubsubController "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/pubsub" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -50,17 +53,23 @@ const ( defaultConstraintViolationsLimit = 20 defaultListLimit = 500 defaultAPICacheDir = "/tmp/audit" + defaultConnection = "audit-connection" + defaultChannel = "audit-channel" ) var ( - auditInterval = flag.Uint("audit-interval", defaultAuditInterval, "interval to run audit in seconds. defaulted to 60 secs if unspecified, 0 to disable") - constraintViolationsLimit = flag.Uint("constraint-violations-limit", defaultConstraintViolationsLimit, "limit of number of violations per constraint. defaulted to 20 violations if unspecified") - auditChunkSize = flag.Uint64("audit-chunk-size", defaultListLimit, "(alpha) Kubernetes API chunking List results when retrieving cluster resources using discovery client. defaulted to 500 if unspecified") - auditFromCache = flag.Bool("audit-from-cache", false, "pull resources from audit cache when auditing") - emitAuditEvents = flag.Bool("emit-audit-events", false, "(alpha) emit Kubernetes events in gatekeeper namespace with detailed info for each violation from an audit") - auditMatchKindOnly = flag.Bool("audit-match-kind-only", false, "only use kinds specified in all constraints for auditing cluster resources. if kind is not specified in any of the constraints, it will audit all resources (same as setting this flag to false)") - apiCacheDir = flag.String("api-cache-dir", defaultAPICacheDir, "The directory where audit from api server cache are stored, defaults to /tmp/audit") - emptyAuditResults []updateListEntry + auditInterval = flag.Uint("audit-interval", defaultAuditInterval, "interval to run audit in seconds. defaulted to 60 secs if unspecified, 0 to disable") + constraintViolationsLimit = flag.Uint("constraint-violations-limit", defaultConstraintViolationsLimit, "limit of number of violations per constraint. defaulted to 20 violations if unspecified") + auditChunkSize = flag.Uint64("audit-chunk-size", defaultListLimit, "(alpha) Kubernetes API chunking List results when retrieving cluster resources using discovery client. defaulted to 500 if unspecified") + auditFromCache = flag.Bool("audit-from-cache", false, "audit synced resources from internal cache, bypassing direct queries to Kubernetes API server") + emitAuditEvents = flag.Bool("emit-audit-events", false, "(alpha) emit Kubernetes events with detailed info for each violation from an audit") + auditEventsInvolvedNamespace = flag.Bool("audit-events-involved-namespace", false, "emit audit events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Audit events from cluster-scoped resources will still follow the default behavior") + auditMatchKindOnly = flag.Bool("audit-match-kind-only", false, "only use kinds specified in all constraints for auditing cluster resources. if kind is not specified in any of the constraints, it will audit all resources (same as setting this flag to false)") + apiCacheDir = flag.String("api-cache-dir", defaultAPICacheDir, "The directory where audit from api server cache are stored, defaults to /tmp/audit") + auditConnection = flag.String("audit-connection", defaultConnection, "Connection name for publishing audit violation messages") + auditChannel = flag.String("audit-channel", defaultChannel, "Channel name for publishing audit violation messages") + emptyAuditResults []updateListEntry + logStatsAudit = flag.Bool("log-stats-audit", false, "(alpha) log stats metrics for the audit run") ) // Manager allows us to audit resources periodically. @@ -81,6 +90,7 @@ type Manager struct { auditCache *CacheLister expansionSystem *expansion.System + pubsubSystem *pubsub.System } // StatusViolation represents each violation under status. @@ -94,6 +104,27 @@ type StatusViolation struct { EnforcementAction string `json:"enforcementAction"` } +// ConstraintMsg represents publish message for each constraint. +type PubsubMsg struct { + ID string `json:"id,omitempty"` + Details interface{} `json:"details,omitempty"` + EventType string `json:"eventType,omitempty"` + Group string `json:"group,omitempty"` + Version string `json:"version,omitempty"` + Kind string `json:"kind,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + Message string `json:"message,omitempty"` + EnforcementAction string `json:"enforcementAction,omitempty"` + ConstraintAnnotations map[string]string `json:"constraintAnnotations,omitempty"` + ResourceGroup string `json:"resourceGroup,omitempty"` + ResourceAPIVersion string `json:"resourceAPIVersion,omitempty"` + ResourceKind string `json:"resourceKind,omitempty"` + ResourceNamespace string `json:"resourceNamespace,omitempty"` + ResourceName string `json:"resourceName,omitempty"` + ResourceLabels map[string]string `json:"resourceLabels,omitempty"` +} + // updateListEntry holds the information necessary to update the // audit results in the `status` field of the constraint template. // Adding data to this struct has a large impact on memory usage. @@ -154,6 +185,7 @@ func New(mgr manager.Manager, deps *Dependencies) (*Manager, error) { gkNamespace: util.GetNamespace(), auditCache: deps.CacheLister, expansionSystem: deps.ExpansionSystem, + pubsubSystem: deps.PubSubSystem, } return am, nil } @@ -213,16 +245,12 @@ func (am *Manager) audit(ctx context.Context) error { var res []Result am.log.Info("Auditing from cache") res, errs := am.auditFromCache(ctx) - am.log.Info("Audit from cache results", "violations", len(res)) for _, err := range errs { am.log.Error(err, "Auditing") } - err := am.addAuditResponsesToUpdateLists(updateLists, res, totalViolationsPerConstraint, totalViolationsPerEnforcementAction, timestamp) - if errs != nil { - return err - } + am.addAuditResponsesToUpdateLists(updateLists, res, totalViolationsPerConstraint, totalViolationsPerEnforcementAction, timestamp) } else { am.log.Info("Auditing via discovery client") err := am.auditResources(ctx, constraintsGVKs, updateLists, totalViolationsPerConstraint, totalViolationsPerEnforcementAction, timestamp) @@ -480,16 +508,36 @@ func (am *Manager) auditFromCache(ctx context.Context) ([]Result, []error) { ns = nil } + excluded, err := am.skipExcludedNamespace(&obj) + if err != nil { + am.log.Error(err, "Unable to exclude object namespace for audit from cache %v %s/%s", obj.GroupVersionKind().String(), obj.GetNamespace(), obj.GetName()) + continue + } + + if excluded { + am.log.V(logging.DebugLevel).Info("excluding object from audit from cache %v %s/%s", obj.GroupVersionKind().String(), obj.GetNamespace(), obj.GetName()) + continue + } + au := &target.AugmentedUnstructured{ Object: obj, Namespace: ns, } - resp, err := am.opa.Review(ctx, au) + resp, err := am.opa.Review(ctx, au, drivers.Stats(*logStatsAudit)) if err != nil { am.log.Error(err, "Unable to review object from audit cache %v %s/%s", obj.GroupVersionKind().String(), obj.GetNamespace(), obj.GetName()) continue } + if *logStatsAudit { + logging.LogStatsEntries( + am.opa, + am.log.WithValues(logging.EventType, "audit_cache_stats"), + resp.StatsEntries, + "audit from cache review request stats", + ) + } + for _, r := range resp.Results() { results = append(results, Result{ Result: r, @@ -527,7 +575,6 @@ func (am *Manager) reviewObjects(ctx context.Context, kind string, folderCount i totalViolationsPerEnforcementAction map[util.EnforcementAction]int64, timestamp string, ) error { - var errs []error for i := 0; i < folderCount; i++ { // cache directory structure: // apiCacheDir/kind_folderIndex/fileIndex @@ -565,7 +612,8 @@ func (am *Manager) reviewObjects(ctx context.Context, kind string, folderCount i Namespace: ns, Source: mutationtypes.SourceTypeOriginal, } - resp, err := am.opa.Review(ctx, augmentedObj) + + resp, err := am.opa.Review(ctx, augmentedObj, drivers.Stats(*logStatsAudit)) if err != nil { am.log.Error(err, "Unable to review object from file", "fileName", fileName, "objNs", objNs) continue @@ -589,29 +637,31 @@ func (am *Manager) reviewObjects(ctx context.Context, kind string, folderCount i Namespace: ns, Source: mutationtypes.SourceTypeGenerated, } - resultantResp, err := am.opa.Review(ctx, au) + resultantResp, err := am.opa.Review(ctx, au, drivers.Stats(*logStatsAudit)) if err != nil { am.log.Error(err, "Unable to review expanded object", "objName", (*resultant.Obj).GetName(), "objNs", ns) continue } expansion.OverrideEnforcementAction(resultant.EnforcementAction, resultantResp) expansion.AggregateResponses(resultant.TemplateName, resp, resultantResp) + expansion.AggregateStats(resultant.TemplateName, resp, resultantResp) + } + + if *logStatsAudit { + logging.LogStatsEntries( + am.opa, + am.log.WithValues(logging.EventType, "audit_stats"), + resp.StatsEntries, + "audit review request stats", + ) } if len(resp.Results()) > 0 { results := ToResults(&augmentedObj.Object, resp) - err = am.addAuditResponsesToUpdateLists(updateLists, results, totalViolationsPerConstraint, totalViolationsPerEnforcementAction, timestamp) - if err != nil { - // updated to not return err immediately - errs = append(errs, err) - continue - } + am.addAuditResponsesToUpdateLists(updateLists, results, totalViolationsPerConstraint, totalViolationsPerEnforcementAction, timestamp) } } } - if len(errs) > 0 { - return mergeErrors(errs) - } return nil } @@ -728,7 +778,7 @@ func (am *Manager) addAuditResponsesToUpdateLists( totalViolationsPerConstraint map[util.KindVersionName]int64, totalViolationsPerEnforcementAction map[util.EnforcementAction]int64, timestamp string, -) error { +) { for _, r := range res { key := util.GetUniqueKey(*r.Constraint) totalViolationsPerConstraint[key]++ @@ -737,6 +787,8 @@ func (am *Manager) addAuditResponsesToUpdateLists( gvk := r.obj.GroupVersionKind() namespace := r.obj.GetNamespace() name := r.obj.GetName() + uid := r.obj.GetUID() + rv := r.obj.GetResourceVersion() ea := util.EnforcementAction(r.EnforcementAction) // append audit results only if it is below violations limit @@ -759,11 +811,16 @@ func (am *Manager) addAuditResponsesToUpdateLists( totalViolationsPerEnforcementAction[ea]++ logViolation(am.log, r.Constraint, ea, gvk, namespace, name, r.Msg, details, r.obj.GetLabels()) + if *pubsubController.PubsubEnabled { + err := am.pubsubSystem.Publish(context.Background(), *auditConnection, *auditChannel, violationMsg(r.Constraint, ea, gvk, namespace, name, r.Msg, details, r.obj.GetLabels(), timestamp)) + if err != nil { + am.log.Error(err, "pubsub audit Publishing") + } + } if *emitAuditEvents { - emitEvent(r.Constraint, timestamp, ea, gvk, namespace, name, r.Msg, am.gkNamespace, am.eventRecorder) + emitEvent(r.Constraint, timestamp, ea, gvk, namespace, name, rv, r.Msg, am.gkNamespace, uid, am.eventRecorder) } } - return nil } func (am *Manager) writeAuditResults(ctx context.Context, constraintsGVKs []schema.GroupVersionKind, updateLists map[util.KindVersionName][]updateListEntry, timestamp string, totalViolations map[util.KindVersionName]int64) { @@ -1014,6 +1071,31 @@ func logConstraint(l logr.Logger, gvknn *util.KindVersionName, enforcementAction ) } +func violationMsg(constraint *unstructured.Unstructured, enforcementAction util.EnforcementAction, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string, timestamp string) interface{} { + userConstraintAnnotations := constraint.GetAnnotations() + delete(userConstraintAnnotations, "kubectl.kubernetes.io/last-applied-configuration") + + return PubsubMsg{ + Message: message, + Details: details, + ID: timestamp, + EventType: "violation_audited", + Group: constraint.GroupVersionKind().Group, + Version: constraint.GroupVersionKind().Version, + Kind: constraint.GetKind(), + Name: constraint.GetName(), + Namespace: constraint.GetNamespace(), + EnforcementAction: string(enforcementAction), + ConstraintAnnotations: userConstraintAnnotations, + ResourceGroup: resourceGroupVersionKind.Group, + ResourceAPIVersion: resourceGroupVersionKind.Version, + ResourceKind: resourceGroupVersionKind.Kind, + ResourceNamespace: rnamespace, + ResourceName: rname, + ResourceLabels: rlabels, + } +} + func logViolation(l logr.Logger, constraint *unstructured.Unstructured, enforcementAction util.EnforcementAction, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message string, details interface{}, rlabels map[string]string, @@ -1042,7 +1124,7 @@ func logViolation(l logr.Logger, } func emitEvent(constraint *unstructured.Unstructured, - timestamp string, enforcementAction util.EnforcementAction, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, message, gkNamespace string, + timestamp string, enforcementAction util.EnforcementAction, resourceGroupVersionKind schema.GroupVersionKind, rnamespace, rname, rrv, message, gkNamespace string, ruid types.UID, eventRecorder record.EventRecorder, ) { annotations := map[string]string{ @@ -1061,19 +1143,34 @@ func emitEvent(constraint *unstructured.Unstructured, logging.ResourceNamespace: rnamespace, logging.ResourceName: rname, } + reason := "AuditViolation" - ref := getViolationRef(gkNamespace, resourceGroupVersionKind.Kind, rname, rnamespace, constraint.GetKind(), constraint.GetName(), constraint.GetNamespace()) + ref := getViolationRef(gkNamespace, resourceGroupVersionKind.Kind, rname, rnamespace, rrv, ruid, constraint.GetKind(), constraint.GetName(), constraint.GetNamespace(), *auditEventsInvolvedNamespace) - eventRecorder.AnnotatedEventf(ref, annotations, corev1.EventTypeWarning, reason, "Timestamp: %s, Resource Namespace: %s, Constraint: %s, Message: %s", timestamp, rnamespace, constraint.GetName(), message) + if *auditEventsInvolvedNamespace { + eventRecorder.AnnotatedEventf(ref, annotations, corev1.EventTypeWarning, reason, "Constraint: %s, Message: %s", constraint.GetName(), message) + } else { + eventRecorder.AnnotatedEventf(ref, annotations, corev1.EventTypeWarning, reason, "Resource Namespace: %s, Constraint: %s, Message: %s", rnamespace, constraint.GetName(), message) + } } -func getViolationRef(gkNamespace, rkind, rname, rnamespace, ckind, cname, cnamespace string) *corev1.ObjectReference { - return &corev1.ObjectReference{ +func getViolationRef(gkNamespace, rkind, rname, rnamespace, rrv string, ruid types.UID, ckind, cname, cnamespace string, emitInvolvedNamespace bool) *corev1.ObjectReference { + enamespace := gkNamespace + if emitInvolvedNamespace && len(rnamespace) > 0 { + enamespace = rnamespace + } + ref := &corev1.ObjectReference{ Kind: rkind, Name: rname, - UID: types.UID(rkind + "/" + rnamespace + "/" + rname + "/" + ckind + "/" + cnamespace + "/" + cname), - Namespace: gkNamespace, + Namespace: enamespace, + } + if emitInvolvedNamespace && len(ruid) > 0 && len(rrv) > 0 { + ref.UID = ruid + ref.ResourceVersion = rrv + } else if !emitInvolvedNamespace { + ref.UID = types.UID(rkind + "/" + rnamespace + "/" + rname + "/" + ckind + "/" + cnamespace + "/" + cname) } + return ref } // mergeErrors concatenates errs into a single error. None of the original errors diff --git a/pkg/audit/manager_test.go b/pkg/audit/manager_test.go index 38733e7d1d5..6ab50afc5b3 100644 --- a/pkg/audit/manager_test.go +++ b/pkg/audit/manager_test.go @@ -1,16 +1,115 @@ package audit import ( + "context" "os" "reflect" "testing" + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" "github.com/pkg/errors" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" ) +func Test_auditFromCache(t *testing.T) { + podToReview := fakes.Pod(fakes.WithNamespace("test-namespace-1")) + podGVK := podToReview.GroupVersionKind() + testAuditCache := fakeCacheListerFor([]schema.GroupVersionKind{podGVK}, []client.Object{podToReview}) + + driver, err := rego.New() + require.NoError(t, err) + client, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + require.NoError(t, err) + + _, err = client.AddTemplate(context.Background(), fakes.DenyAllRegoTemplate()) + require.NoError(t, err, "adding denyall constraint template") + _, err = client.AddConstraint(context.Background(), fakes.DenyAllConstraint()) + require.NoError(t, err, "adding denyall constraint") + + tests := []struct { + name string + processExcluder *process.Excluder + wantViolation bool + }{ + { + name: "obj excluded from audit", + processExcluder: processExcluderFor([]string{"test-namespace-1"}), + }, + { + name: "obj not excluded from audit", + processExcluder: processExcluderFor([]string{}), + wantViolation: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + am := &Manager{ + processExcluder: tc.processExcluder, + auditCache: testAuditCache, + opa: client, + } + + results, errs := am.auditFromCache(context.Background()) + require.Len(t, errs, 0) + + if tc.wantViolation { + require.Len(t, results, 1) + } else { + require.Len(t, results, 0) + } + }) + } +} + +func fakeCacheListerFor(gvks []schema.GroupVersionKind, objsToList []client.Object) *CacheLister { + k8sclient := fake.NewClientBuilder().WithObjects(objsToList...).Build() + fakeLister := fakeWatchIterator{gvksToList: gvks} + + return NewAuditCacheLister(k8sclient, &fakeLister) +} + +type fakeWatchIterator struct { + gvksToList []schema.GroupVersionKind +} + +func (f *fakeWatchIterator) DoForEach(listFunc func(gvk schema.GroupVersionKind) error) error { + for _, gvk := range f.gvksToList { + if err := listFunc(gvk); err != nil { + return err + } + } + + return nil +} + +func processExcluderFor(ns []string) *process.Excluder { + processExcluder := process.New() + for _, n := range ns { + processExcluder.Add([]configv1alpha1.MatchEntry{ + { + ExcludedNamespaces: []wildcard.Wildcard{wildcard.Wildcard(n)}, + Processes: []string{"audit"}, + }, + }) + } + + return processExcluder +} + func Test_newNSCache(t *testing.T) { tests := []struct { name string @@ -187,9 +286,12 @@ func Test_getViolationRef(t *testing.T) { rkind string rname string rnamespace string + rrv string ckind string cname string cnamespace string + ruid types.UID + einvolved bool } tests := []struct { name string @@ -197,7 +299,7 @@ func Test_getViolationRef(t *testing.T) { want *corev1.ObjectReference }{ { - name: "Test case 1", + name: "Test case 1 - Gatekeeper Namespace", args: args{ gkNamespace: "default", rkind: "Pod", @@ -206,6 +308,7 @@ func Test_getViolationRef(t *testing.T) { ckind: "LimitRange", cname: "my-limit-range", cnamespace: "default", + einvolved: false, }, want: &corev1.ObjectReference{ Kind: "Pod", @@ -215,7 +318,7 @@ func Test_getViolationRef(t *testing.T) { }, }, { - name: "Test case 2", + name: "Test case 2 - GK Namespace", args: args{ gkNamespace: "kube-system", rkind: "Service", @@ -224,6 +327,7 @@ func Test_getViolationRef(t *testing.T) { ckind: "PodSecurityPolicy", cname: "my-pod-security-policy", cnamespace: "kube-system", + einvolved: false, }, want: &corev1.ObjectReference{ Kind: "Service", @@ -232,10 +336,75 @@ func Test_getViolationRef(t *testing.T) { Namespace: "kube-system", }, }, + { + name: "Test case 3 - Involved Namespace", + args: args{ + gkNamespace: "kube-system", + rkind: "Pod", + rname: "my-pod", + rrv: "123456", + ruid: "abcde-123456", + rnamespace: "default", + ckind: "LimitRange", + cname: "my-limit-range", + cnamespace: "default", + einvolved: true, + }, + want: &corev1.ObjectReference{ + Kind: "Pod", + Name: "my-pod", + Namespace: "default", + ResourceVersion: "123456", + UID: "abcde-123456", + }, + }, + { + name: "Test case 4 - Involved Namespace Cluster Scoped", + args: args{ + gkNamespace: "kube-system", + rkind: "Service", + rname: "my-service", + rrv: "123456", + ruid: "abcde-123456", + ckind: "PodSecurityPolicy", + cname: "my-pod-security-policy", + cnamespace: "kube-system", + einvolved: true, + }, + want: &corev1.ObjectReference{ + Kind: "Service", + Name: "my-service", + Namespace: "kube-system", + ResourceVersion: "123456", + UID: "abcde-123456", + }, + }, + { + name: "Test case 5 - Involved Namespace RV/UID", + args: args{ + gkNamespace: "kube-system", + rkind: "Service", + rname: "my-service", + rrv: "", + ruid: "", + rnamespace: "default", + ckind: "PodSecurityPolicy", + cname: "my-pod-security-policy", + cnamespace: "kube-system", + einvolved: true, + }, + want: &corev1.ObjectReference{ + Kind: "Service", + Name: "my-service", + Namespace: "default", + ResourceVersion: "", + UID: "", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getViolationRef(tt.args.gkNamespace, tt.args.rkind, tt.args.rname, tt.args.rnamespace, tt.args.ckind, tt.args.cname, tt.args.cnamespace); !reflect.DeepEqual(got, tt.want) { + if got := getViolationRef(tt.args.gkNamespace, tt.args.rkind, tt.args.rname, tt.args.rnamespace, tt.args.rrv, tt.args.ruid, tt.args.ckind, tt.args.cname, tt.args.cnamespace, tt.args.einvolved); !reflect.DeepEqual(got, tt.want) { t.Errorf("getViolationRef() = %v, want %v", got, tt.want) } }) diff --git a/pkg/audit/stats_reporter.go b/pkg/audit/stats_reporter.go index 8cfe9cd1645..43f2e32158a 100644 --- a/pkg/audit/stats_reporter.go +++ b/pkg/audit/stats_reporter.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/cachemanager/aggregator/aggregator.go b/pkg/cachemanager/aggregator/aggregator.go new file mode 100644 index 00000000000..b36b3cada13 --- /dev/null +++ b/pkg/cachemanager/aggregator/aggregator.go @@ -0,0 +1,178 @@ +package aggregator + +import ( + "fmt" + gosync "sync" + + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// Key defines a type, identifier tuple to store +// in the GVKAggregator. +type Key struct { + // Source specifies the type or where this Key comes from. + Source string + // ID specifies the name of the type that this Key is. + ID string +} + +func NewGVKAggregator() *GVKAgreggator { + return &GVKAgreggator{ + store: make(map[Key]map[schema.GroupVersionKind]struct{}), + reverseStore: make(map[schema.GroupVersionKind]map[Key]struct{}), + } +} + +// GVKAgreggator is an implementation of a bi directional map +// that stores associations between Key K and GVKs and reverse associations +// between GVK g and Keys. +type GVKAgreggator struct { + mu gosync.RWMutex + + // store keeps track of associations between a Key type and a set of GVKs. + store map[Key]map[schema.GroupVersionKind]struct{} + // reverseStore keeps track of associations between a GVK and the set of Key types + // that references the GVK in the store map above. It is useful to have reverseStore + // in order for IsPresent() and ListGVKs() to run in optimal time. + reverseStore map[schema.GroupVersionKind]map[Key]struct{} +} + +// IsPresent returns true if the given gvk is present in the GVKAggregator. +func (b *GVKAgreggator) IsPresent(gvk schema.GroupVersionKind) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, found := b.reverseStore[gvk] + return found +} + +// Remove deletes any associations that Key k has in the GVKAggregator. +// For any GVK in the association k --> [GVKs], we also delete any associations +// between the GVK and the Key k stored in the reverse map. +func (b *GVKAgreggator) Remove(k Key) error { + b.mu.Lock() + defer b.mu.Unlock() + + gvks, found := b.store[k] + if !found { + return nil + } + + if err := b.pruneReverseStore(gvks, k); err != nil { + return err + } + + delete(b.store, k) + return nil +} + +// Upsert stores an association between Key k and the list of GVKs +// and also the reverse associatoin between each GVK passed in and Key k. +// Any old associations are dropped, unless they are included in the new list of +// GVKs. +// It errors out if there is an internal issue with remove the reverse Key links +// for any GVKs that are being dropped as part of this Upsert call. +func (b *GVKAgreggator) Upsert(k Key, gvks []schema.GroupVersionKind) error { + b.mu.Lock() + defer b.mu.Unlock() + + oldGVKs, found := b.store[k] + if found { + // gvksToRemove contains old GKVs that are not included in the new gvks list + gvksToRemove := unreferencedOldGVKsToPrune(gvks, oldGVKs) + if err := b.pruneReverseStore(gvksToRemove, k); err != nil { + return fmt.Errorf("failed to prune entries on upsert: %w", err) + } + } + + // protect against empty inputs + gvksSet := makeSet(gvks) + if len(gvksSet) == 0 { + return nil + } + + b.store[k] = gvksSet + // add reverse links + for gvk := range gvksSet { + if _, found := b.reverseStore[gvk]; !found { + b.reverseStore[gvk] = make(map[Key]struct{}) + } + b.reverseStore[gvk][k] = struct{}{} + } + + return nil +} + +// List returnes the gvk set for a given Key. +func (b *GVKAgreggator) List(k Key) map[schema.GroupVersionKind]struct{} { + b.mu.RLock() + defer b.mu.RUnlock() + + v := b.store[k] + cpy := make(map[schema.GroupVersionKind]struct{}, len(v)) + for key, value := range v { + cpy[key] = value + } + return cpy +} + +// GVKs returns a list of all of the schema.GroupVersionKind that are aggregated. +func (b *GVKAgreggator) GVKs() []schema.GroupVersionKind { + b.mu.RLock() + defer b.mu.RUnlock() + + allGVKs := []schema.GroupVersionKind{} + for gvk := range b.reverseStore { + allGVKs = append(allGVKs, gvk) + } + return allGVKs +} + +func (b *GVKAgreggator) pruneReverseStore(gvks map[schema.GroupVersionKind]struct{}, k Key) error { + for gvk := range gvks { + keySet, found := b.reverseStore[gvk] + if !found || len(keySet) == 0 { + // this should not happen if we keep the two maps well defined + // but let's be defensive nonetheless. + return fmt.Errorf("internal aggregator error: gvks stores are corrupted for key: %s", k) + } + + delete(keySet, k) + + // remove GVK from reverseStore if it's not referenced by any Key anymore. + if len(keySet) == 0 { + delete(b.reverseStore, gvk) + } else { + b.reverseStore[gvk] = keySet + } + } + + return nil +} + +func makeSet(gvks []schema.GroupVersionKind) map[schema.GroupVersionKind]struct{} { + gvkSet := make(map[schema.GroupVersionKind]struct{}) + for _, gvk := range gvks { + if !gvk.Empty() { + gvkSet[gvk] = struct{}{} + } + } + + return gvkSet +} + +func unreferencedOldGVKsToPrune(newGVKs []schema.GroupVersionKind, oldGVKs map[schema.GroupVersionKind]struct{}) map[schema.GroupVersionKind]struct{} { + // deep copy oldGVKs + oldGVKsCpy := make(map[schema.GroupVersionKind]struct{}, len(oldGVKs)) + for k, v := range oldGVKs { + oldGVKsCpy[k] = v + } + + // intersection: exclude the oldGVKs that are present in the new GVKs as well. + for _, newGVK := range newGVKs { + // don't prune what is being already added + delete(oldGVKsCpy, newGVK) + } + + return oldGVKsCpy +} diff --git a/pkg/cachemanager/aggregator/aggregator_test.go b/pkg/cachemanager/aggregator/aggregator_test.go new file mode 100644 index 00000000000..22dec711065 --- /dev/null +++ b/pkg/cachemanager/aggregator/aggregator_test.go @@ -0,0 +1,362 @@ +package aggregator + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + // common test keys. + syncset = "TODOa" + configsync = "TODOb" +) + +var ( + // test gvks. + emptyGVK = schema.GroupVersionKind{Group: "", Version: "", Kind: ""} + + g1v1k1 = schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "Kind1"} + g1v1k2 = schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "Kind2"} + + g2v1k1 = schema.GroupVersionKind{Group: "group2", Version: "v1", Kind: "Kind1"} + g2v1k2 = schema.GroupVersionKind{Group: "group2", Version: "v1", Kind: "Kind2"} + + g1v2k1 = schema.GroupVersionKind{Group: "group1", Version: "v2", Kind: "Kind1"} + g1v2k2 = schema.GroupVersionKind{Group: "group1", Version: "v2", Kind: "Kind2"} + + g2v2k1 = schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "Kind1"} + g2v2k2 = schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "Kind2"} + + g3v1k1 = schema.GroupVersionKind{Group: "group3", Version: "v1", Kind: "Kind1"} + g3v1k2 = schema.GroupVersionKind{Group: "group3", Version: "v1", Kind: "Kind2"} +) + +type upsertKeyGVKs struct { + key Key + gvks []schema.GroupVersionKind +} + +func Test_GVKAggregator_Upsert(t *testing.T) { + tests := []struct { + name string + // each entry in the list is a new Upsert call + keyGVKs []upsertKeyGVKs + + expectData map[Key]map[schema.GroupVersionKind]struct{} + expectRev map[schema.GroupVersionKind]map[Key]struct{} + }{ + { + name: "empty GVKs", + keyGVKs: []upsertKeyGVKs{ + { + key: Key{ + Source: syncset, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{emptyGVK, emptyGVK}, + }, + }, + expectData: map[Key]map[schema.GroupVersionKind]struct{}{}, + expectRev: map[schema.GroupVersionKind]map[Key]struct{}{}, + }, + { + name: "add one key and GVKs", + keyGVKs: []upsertKeyGVKs{ + { + key: Key{ + Source: syncset, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{g1v1k1, g1v1k2, emptyGVK}, + }, + }, + expectData: map[Key]map[schema.GroupVersionKind]struct{}{ + { + Source: syncset, + ID: "foo", + }: { + g1v1k1: {}, + g1v1k2: {}, + }, + }, + expectRev: map[schema.GroupVersionKind]map[Key]struct{}{ + g1v1k1: { + { + Source: syncset, + ID: "foo", + }: {}, + }, + g1v1k2: { + { + Source: syncset, + ID: "foo", + }: {}, + }, + }, + }, + { + name: "add two keys and GVKs", + keyGVKs: []upsertKeyGVKs{ + { + key: Key{ + Source: syncset, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{g1v1k1, g1v1k2}, + }, + { + key: Key{ + Source: configsync, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{g1v1k1, g1v1k2}, + }, + }, + expectData: map[Key]map[schema.GroupVersionKind]struct{}{ + { + Source: syncset, + ID: "foo", + }: { + g1v1k1: {}, + g1v1k2: {}, + }, + { + Source: configsync, + ID: "foo", + }: { + g1v1k1: {}, + g1v1k2: {}, + }, + }, + expectRev: map[schema.GroupVersionKind]map[Key]struct{}{ + g1v1k1: { + { + Source: syncset, + ID: "foo", + }: {}, + { + Source: configsync, + ID: "foo", + }: {}, + }, + g1v1k2: { + { + Source: syncset, + ID: "foo", + }: {}, + { + Source: configsync, + ID: "foo", + }: {}, + }, + }, + }, + { + name: "add one key and overwrite it", + keyGVKs: []upsertKeyGVKs{ + { + key: Key{ + Source: syncset, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{g1v1k1, g1v1k2}, + }, + { + key: Key{ + Source: syncset, + ID: "foo", + }, + gvks: []schema.GroupVersionKind{g3v1k1, g3v1k2}, + }, + }, + expectData: map[Key]map[schema.GroupVersionKind]struct{}{ + { + Source: syncset, + ID: "foo", + }: { + g3v1k1: {}, + g3v1k2: {}, + }, + }, + expectRev: map[schema.GroupVersionKind]map[Key]struct{}{ + g3v1k1: { + { + Source: syncset, + ID: "foo", + }: {}, + }, + g3v1k2: { + { + Source: syncset, + ID: "foo", + }: {}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt := tt + agg := NewGVKAggregator() + + for _, keyGVKs := range tt.keyGVKs { + require.NoError(t, agg.Upsert(keyGVKs.key, keyGVKs.gvks)) + } + + // require all gvks added to be present in the aggregator + require.Equal(t, tt.expectData, agg.store, "data map did not match expected") + require.Equal(t, tt.expectRev, agg.reverseStore, "reverse store did not match expected") + }) + } +} + +func Test_GVKAgreggator_Remove(t *testing.T) { + t.Run("Remove on empty aggregator", func(t *testing.T) { + b := NewGVKAggregator() + key := Key{Source: "testSource", ID: "testID"} + + require.NoError(t, b.Remove(key)) + }) + + t.Run("Remove non-existing key", func(t *testing.T) { + b := NewGVKAggregator() + key1 := Key{Source: syncset, ID: "testID1"} + key2 := Key{Source: configsync, ID: "testID2"} + gvks := []schema.GroupVersionKind{g1v1k1, g1v1k2} + require.NoError(t, b.Upsert(key1, gvks)) + + require.NoError(t, b.Remove(key2)) + }) + + t.Run("Remove existing key and verify reverseStore", func(t *testing.T) { + b := NewGVKAggregator() + key1 := Key{Source: syncset, ID: "testID"} + gvks := []schema.GroupVersionKind{g1v1k1, g1v1k2} + require.NoError(t, b.Upsert(key1, gvks)) + + require.NoError(t, b.Remove(key1)) + + for _, gvk := range gvks { + require.False(t, b.IsPresent(gvk)) + } + }) + + t.Run("Remove existing 1 of existing keys referencing GVKs", func(t *testing.T) { + b := NewGVKAggregator() + key1 := Key{Source: syncset, ID: "testID"} + key2 := Key{Source: configsync, ID: "testID"} + gvks := []schema.GroupVersionKind{g1v1k1, g1v1k2} + require.NoError(t, b.Upsert(key1, gvks)) + require.NoError(t, b.Upsert(key2, gvks)) + + require.NoError(t, b.Remove(key1)) + + for _, gvk := range gvks { + require.True(t, b.IsPresent(gvk)) + } + }) + + t.Run("corrupted GVKAggregator error", func(t *testing.T) { + b := NewGVKAggregator() + key := Key{Source: syncset, ID: "testID"} + + // simulate a corrupted aggreagator + require.NoError(t, b.Upsert(key, []schema.GroupVersionKind{g1v1k1})) + b.reverseStore[g1v1k1] = map[Key]struct{}{} + + err2 := b.Remove(key) + require.EqualError(t, err2, fmt.Sprintf("internal aggregator error: gvks stores are corrupted for key: {%s %s}", key.Source, key.ID)) + }) +} + +// Test_GVKAggreggator_E2E is a test that: +// - Upserts two sources with different GVKs +// - Upserts the two sources with some overlapping GVKs +// - Remove one key, tests for correct output +// - Overwrite an existing key with new data, and confirms correct re-calculation. +func Test_GVKAggreggator_E2E(t *testing.T) { + b := NewGVKAggregator() + + key1 := Key{Source: syncset, ID: "testID"} + key2 := Key{Source: configsync, ID: "testID"} + + gvksKind1 := []schema.GroupVersionKind{g1v1k1, g2v1k1, g2v2k1} + gvksKind2 := []schema.GroupVersionKind{g1v1k2, g2v1k2, g2v2k2} + + require.NoError(t, b.Upsert(key1, gvksKind1)) // key1 now has: g1v1k1, g2v1k1, g2v2k1 + require.NoError(t, b.Upsert(key2, gvksKind2)) // key2 now has: g1v1k2, g2v1k2, g2v2k2 + + // require that every gvk that was just added to be present + gvksThatShouldBeTracked := map[schema.GroupVersionKind]interface{}{ + g1v1k1: struct{}{}, g2v1k1: struct{}{}, g2v2k1: struct{}{}, + g1v1k2: struct{}{}, g2v1k2: struct{}{}, g2v2k2: struct{}{}, + } + for gvk := range gvksThatShouldBeTracked { + require.True(t, b.IsPresent(gvk)) + } + + // notice the overlap of with gvksKind1, gvksKind2 + gvksVersion1 := []schema.GroupVersionKind{g1v1k1, g1v1k2, g2v1k1, g2v1k2} // overlaps key2 with g1v1k2, g1v1k2 + gvksVersion2 := []schema.GroupVersionKind{g1v2k1, g1v2k2, g2v2k1, g2v2k2} // overlaps key1 with g2v2k1; overlaps key2 with g2v2k2 + + // new upserts + require.NoError(t, b.Upsert(key1, gvksVersion1)) // key1 no longer associates g2v2k1, but key2 does + require.NoError(t, b.Upsert(key2, gvksVersion2)) // key2 no longer associaates g1v1k2, but key1 does + + // require that every gvk that was just added now and before to be present + for _, gvk := range append(append([]schema.GroupVersionKind{}, gvksVersion1...), gvksVersion2...) { + gvksThatShouldBeTracked[gvk] = struct{}{} + + require.True(t, b.IsPresent(gvk), fmt.Sprintf("gvk %s should be present", gvk)) + } + + // At this point + // key1 has: g1v1k1, g2v1k1, g1v1k2, g2v1k2 + // key2 has: g2v2k2, g1v2k1, g1v2k2, g2v2k1 + // now remove key1 + require.NoError(t, b.Remove(key1)) + + // untrack gvks that shouldn't exist in the + for _, gvk := range []schema.GroupVersionKind{g1v1k1, g2v1k1, g1v1k2, g2v1k2} { + delete(gvksThatShouldBeTracked, gvk) + + // also require that this gvk not be present since it was removed + require.False(t, b.IsPresent(gvk), fmt.Sprintf("gvk %s shouldn't be present", gvk)) + } + + // require GVKs from un-removed keys that have GVK associations to still be present + for gvk := range gvksThatShouldBeTracked { + require.True(t, b.IsPresent(gvk), fmt.Sprintf("gvk %s should be present", gvk)) + } + + // overwrite key2 + gvksGroup3 := []schema.GroupVersionKind{g3v1k1, g3v1k2} + require.NoError(t, b.Upsert(key2, gvksGroup3)) + + // require all previously added gvks to not be present: + testPresenceForGVK(t, false, b, gvksKind1...) + testPresenceForGVK(t, false, b, gvksKind2...) + testPresenceForGVK(t, false, b, gvksVersion1...) + testPresenceForGVK(t, false, b, gvksVersion2...) + + // require newly added gvks to be present + testPresenceForGVK(t, true, b, gvksGroup3...) +} + +func testPresenceForGVK(t *testing.T, requireTrue bool, b *GVKAgreggator, gvks ...schema.GroupVersionKind) { + t.Helper() + + var msg string + if requireTrue { + msg = "%s should be present" + } else { + msg = "%s shouldn't be present" + } + for _, gvk := range gvks { + require.Equal(t, requireTrue, b.IsPresent(gvk), fmt.Sprintf(msg, gvk)) + } +} diff --git a/pkg/cachemanager/cachemanager.go b/pkg/cachemanager/cachemanager.go new file mode 100644 index 00000000000..00b1691d26a --- /dev/null +++ b/pkg/cachemanager/cachemanager.go @@ -0,0 +1,442 @@ +package cachemanager + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/open-policy-agent/frameworks/constraint/pkg/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager/aggregator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/client" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +const RegistrarName = "cachemanager" + +var ( + log = logf.Log.WithName("cache-manager") + backoff = wait.Backoff{ + Duration: time.Second, + Factor: 2, + Jitter: 0.1, + Steps: 3, + } +) + +type Config struct { + CfClient CFDataClient + SyncMetricsCache *syncutil.MetricsCache + Tracker *readiness.Tracker + ProcessExcluder *process.Excluder + Registrar *watch.Registrar + GVKAggregator *aggregator.GVKAgreggator + Reader client.Reader +} + +type CacheManager struct { + watchedSet *watch.Set + processExcluder *process.Excluder + gvksToSync *aggregator.GVKAgreggator + needToList bool + gvksToDeleteFromCache *watch.Set + excluderChanged bool + // mu guards access to any of the fields above + mu sync.RWMutex + + cfClient CFDataClient + syncMetricsCache *syncutil.MetricsCache + tracker *readiness.Tracker + registrar *watch.Registrar + backgroundManagementTicker time.Ticker + reader client.Reader +} + +// CFDataClient is an interface for caching data. +type CFDataClient interface { + AddData(ctx context.Context, data interface{}) (*types.Responses, error) + RemoveData(ctx context.Context, data interface{}) (*types.Responses, error) +} + +func NewCacheManager(config *Config) (*CacheManager, error) { + if config.Registrar == nil { + return nil, fmt.Errorf("registrar must be non-nil") + } + if config.ProcessExcluder == nil { + return nil, fmt.Errorf("processExcluder must be non-nil") + } + if config.Tracker == nil { + return nil, fmt.Errorf("tracker must be non-nil") + } + if config.Reader == nil { + return nil, fmt.Errorf("reader must be non-nil") + } + + if config.GVKAggregator == nil { + config.GVKAggregator = aggregator.NewGVKAggregator() + } + + cm := &CacheManager{ + cfClient: config.CfClient, + syncMetricsCache: config.SyncMetricsCache, + tracker: config.Tracker, + processExcluder: config.ProcessExcluder, + registrar: config.Registrar, + watchedSet: watch.NewSet(), + reader: config.Reader, + gvksToSync: config.GVKAggregator, + backgroundManagementTicker: *time.NewTicker(3 * time.Second), + gvksToDeleteFromCache: watch.NewSet(), + } + + return cm, nil +} + +func (c *CacheManager) Start(ctx context.Context) error { + go c.manageCache(ctx) + + <-ctx.Done() + return nil +} + +// UpsertSource adjusts the watched set of gvks according to the newGVKs passed in +// for a given sourceKey. Callers are responsible for retrying on error. +func (c *CacheManager) UpsertSource(ctx context.Context, sourceKey aggregator.Key, newGVKs []schema.GroupVersionKind) error { + c.mu.Lock() + defer c.mu.Unlock() + + if len(newGVKs) > 0 { + if err := c.gvksToSync.Upsert(sourceKey, newGVKs); err != nil { + return fmt.Errorf("internal error adding source: %w", err) + } + } else { + if err := c.gvksToSync.Remove(sourceKey); err != nil { + return fmt.Errorf("internal error removing source: %w", err) + } + } + + // as a result of upserting the new gvks for the source key, some gvks + // may become unreferenced and need to be deleted; this will be handled async + // in the manageCache loop. + + if err := c.replaceWatchSet(ctx); err != nil { + return fmt.Errorf("error watching new gvks: %w", err) + } + + return nil +} + +// replaceWatchSet looks at the gvksToSync and makes changes to the registrar's watch set. +// Assumes caller has lock. On error, actual watch state may not align with intended watch state. +func (c *CacheManager) replaceWatchSet(ctx context.Context) error { + newWatchSet := watch.NewSet() + newWatchSet.Add(c.gvksToSync.GVKs()...) + + diff := c.watchedSet.Difference(newWatchSet) + c.removeStaleExpectations(diff) + + c.gvksToDeleteFromCache.AddSet(diff) + + var innerError error + c.watchedSet.Replace(newWatchSet, func() { + // *Note the following steps are not transactional with respect to admission control + + // Important: dynamic watches update must happen *after* updating our watchSet. + // Otherwise, the sync controller will drop events for the newly watched kinds. + innerError = c.registrar.ReplaceWatch(ctx, newWatchSet.Items()) + }) + + return innerError +} + +// removeStaleExpectations stops tracking data for any resources that are no longer watched. +func (c *CacheManager) removeStaleExpectations(stale *watch.Set) { + for _, gvk := range stale.Items() { + c.tracker.CancelData(gvk) + } +} + +// RemoveSource removes the watches of the GVKs for a given aggregator.Key. Callers are responsible for retrying on error. +func (c *CacheManager) RemoveSource(ctx context.Context, sourceKey aggregator.Key) error { + c.mu.Lock() + defer c.mu.Unlock() + + if err := c.gvksToSync.Remove(sourceKey); err != nil { + return fmt.Errorf("internal error removing source: %w", err) + } + + if err := c.replaceWatchSet(ctx); err != nil { + return fmt.Errorf("error removing watches for source %v: %w", sourceKey, err) + } + + return nil +} + +// ExcludeProcesses swaps the current process excluder with the new *process.Excluder. +// It's a no-op if the two excluders are equal. +func (c *CacheManager) ExcludeProcesses(newExcluder *process.Excluder) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.processExcluder.Equals(newExcluder) { + return + } + + c.processExcluder.Replace(newExcluder) + // there is a new excluder which means we need to schedule a wipe for any + // previously watched GVKs to be re-added to get a chance to be evaluated + // for this new process excluder. + c.excluderChanged = true +} + +// DoForEach runs fn for each GVK that is being watched by the cache manager. +// This is handy when we want to take actions while holding the lock on the watched.Set. +func (c *CacheManager) DoForEach(fn func(gvk schema.GroupVersionKind) error) error { + c.mu.RLock() + defer c.mu.RUnlock() + + err := c.watchedSet.DoForEach(fn) + return err +} + +func (c *CacheManager) watchesGVK(gvk schema.GroupVersionKind) bool { + c.mu.RLock() + defer c.mu.RUnlock() + + return c.watchedSet.Contains(gvk) +} + +func (c *CacheManager) AddObject(ctx context.Context, instance *unstructured.Unstructured) error { + gvk := instance.GroupVersionKind() + + isNamespaceExcluded, err := c.processExcluder.IsNamespaceExcluded(process.Sync, instance) + if err != nil { + return fmt.Errorf("error while excluding namespaces for gvk: %+v: %w", gvk, err) + } + + if isNamespaceExcluded { + c.tracker.ForData(instance.GroupVersionKind()).CancelExpect(instance) + return nil + } + + syncKey := syncutil.GetKeyForSyncMetrics(instance.GetNamespace(), instance.GetName()) + if c.watchesGVK(gvk) { + _, err = c.cfClient.AddData(ctx, instance) + if err != nil { + c.syncMetricsCache.AddObject( + syncKey, + syncutil.Tags{ + Kind: instance.GetKind(), + Status: metrics.ErrorStatus, + }, + ) + + return err + } + + c.syncMetricsCache.AddObject(syncKey, syncutil.Tags{ + Kind: instance.GetKind(), + Status: metrics.ActiveStatus, + }) + c.syncMetricsCache.AddKind(instance.GetKind()) + } + + c.tracker.ForData(instance.GroupVersionKind()).Observe(instance) + + return nil +} + +func (c *CacheManager) RemoveObject(ctx context.Context, instance *unstructured.Unstructured) error { + if _, err := c.cfClient.RemoveData(ctx, instance); err != nil { + return err + } + + // only delete from metrics map if the data removal was successful + c.syncMetricsCache.DeleteObject(syncutil.GetKeyForSyncMetrics(instance.GetNamespace(), instance.GetName())) + c.tracker.ForData(instance.GroupVersionKind()).CancelExpect(instance) + + return nil +} + +func (c *CacheManager) wipeData(ctx context.Context) error { + if _, err := c.cfClient.RemoveData(ctx, target.WipeData()); err != nil { + return err + } + + // reset sync cache before sending the metric + c.syncMetricsCache.ResetCache() + c.syncMetricsCache.ReportSync() + + return nil +} + +func (c *CacheManager) ReportSyncMetrics() { + c.syncMetricsCache.ReportSync() +} + +func (c *CacheManager) syncGVK(ctx context.Context, gvk schema.GroupVersionKind) error { + u := &unstructured.UnstructuredList{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind + "List", + }) + + var err error + func() { + c.mu.RLock() + defer c.mu.RUnlock() + + // only call List if we are still watching the gvk. + if c.watchedSet.Contains(gvk) { + err = c.reader.List(ctx, u) + } + }() + + if err != nil { + return fmt.Errorf("listing data for %+v: %w", gvk, err) + } + + for i := range u.Items { + if err := c.AddObject(ctx, &u.Items[i]); err != nil { + return fmt.Errorf("adding data for %+v: %w", gvk, err) + } + } + + return nil +} + +func (c *CacheManager) manageCache(ctx context.Context) { + // relistStopChan is used to stop any list operations still in progress + relistStopChan := make(chan struct{}) + // waitToCloseChan is used to wait on the relist goroutine to end + // when needing to create another one. This ensures that we are essentially + // only using a singleton routine to relist gvks. + waitToCloseChan := make(chan struct{}) + + // edge case: the 0th relist goroutine is "stopped", by definition, so we close the wait channel + // but it's also "running" so we don't close the kill channel in order to do so in the for loop below. + close(waitToCloseChan) + + for { + select { + case <-ctx.Done(): + return + case <-c.backgroundManagementTicker.C: + func() { + c.mu.Lock() + defer c.mu.Unlock() + + c.wipeCacheIfNeeded(ctx) + + if !c.needToList { + // this means that there are no changes needed + // such that any gvks need to be relisted. + // any in flight goroutines can finish relisiting. + return + } + + // otherwise, spin up new goroutines to relist gvks as there has been a wipe + + // stop any goroutines that were relisting before + // as we may no longer be interested in those gvks + // and wait with a timeout for the child gorountine to stop. + close(relistStopChan) + select { + case <-waitToCloseChan: + // child goroutine exited gracefully + break + case <-time.After(time.Second * 10): + log.Error(fmt.Errorf("internal: background relist did not exit gracefully"), "possible goroutine leak") + // do not close waitToCloseChan as the goroutine may eventually exit and call close on the channel + break + } + + // assume all gvks need to be relisted + // and while under lock, make a copy of + // all gvks so we can pass it in the goroutine + // without needing to read lock this data + gvksToRelist := c.gvksToSync.GVKs() + + // clean state + c.needToList = false + relistStopChan = make(chan struct{}) + waitToCloseChan = make(chan struct{}) + + go func() { + c.replayGVKs(ctx, gvksToRelist, relistStopChan) + close(waitToCloseChan) + }() + }() + } + } +} + +func (c *CacheManager) replayGVKs(ctx context.Context, gvksToRelist []schema.GroupVersionKind, stopCh <-chan struct{}) { + gvksSet := watch.NewSet() + gvksSet.Add(gvksToRelist...) + + for gvksSet.Size() != 0 { + gvkItems := gvksSet.Items() + + for _, gvk := range gvkItems { + select { + case <-ctx.Done(): + return + case <-stopCh: + return + default: + operation := func(ctx context.Context) (bool, error) { + select { + // make sure that the stop channel hasn't closed yet in order to stop + // the operation in the backoff retry-er earlier so we don't sync GVKs + // that we may not want to sync anymore. This also ensures that we exit + // the func as soon as possible. + case <-stopCh: + return true, nil + default: + if err := c.syncGVK(ctx, gvk); err != nil { + return false, err + } + return true, nil + } + } + + if err := wait.ExponentialBackoffWithContext(ctx, backoff, operation); err != nil { + log.Error(err, "internal: error listings gvk cache data", "gvk", gvk) + } else { + gvksSet.Remove(gvk) + } + } + } + + c.ReportSyncMetrics() + } +} + +// wipeCacheIfNeeded performs a cache wipe if there are any gvks needing to be removed +// from the cache or if the excluder has changed. It also marks which gvks need to be +// re listed again in the cf data cache after the wipe. Assumes the caller has lock. +func (c *CacheManager) wipeCacheIfNeeded(ctx context.Context) { + // remove any gvks not needing to be synced anymore + // or re evaluate all if the excluder changed. + if c.gvksToDeleteFromCache.Size() > 0 || c.excluderChanged { + if err := c.wipeData(ctx); err != nil { + log.Error(err, "internal: error wiping cache") + return + } + + c.gvksToDeleteFromCache = watch.NewSet() + c.excluderChanged = false + c.needToList = true + } +} diff --git a/pkg/cachemanager/cachemanager_test.go b/pkg/cachemanager/cachemanager_test.go new file mode 100644 index 00000000000..3e7fa9bbeec --- /dev/null +++ b/pkg/cachemanager/cachemanager_test.go @@ -0,0 +1,539 @@ +package cachemanager + +import ( + "context" + "testing" + + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager/aggregator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/event" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + testutils.StartControlPlane(m, &cfg, 2) +} + +func makeCacheManager(t *testing.T) (*CacheManager, context.Context) { + mgr, wm := testutils.SetupManager(t, cfg) + c := testclient.NewRetryClient(mgr.GetClient()) + + ctx, cancelFunc := context.WithCancel(context.Background()) + + cfClient := &fakes.FakeCfClient{} + tracker, err := readiness.SetupTracker(mgr, false, false, false) + require.NoError(t, err) + processExcluder := process.Get() + processExcluder.Add([]configv1alpha1.MatchEntry{ + { + ExcludedNamespaces: []wildcard.Wildcard{"kube-system"}, + Processes: []string{"sync"}, + }, + }) + events := make(chan event.GenericEvent, 1024) + reg, err := wm.NewRegistrar( + "test-cache-manager", + events) + require.NoError(t, err) + + cacheManager, err := NewCacheManager(&Config{ + CfClient: cfClient, + SyncMetricsCache: syncutil.NewMetricsCache(), + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: c, + GVKAggregator: aggregator.NewGVKAggregator(), + }) + require.NoError(t, err) + + t.Cleanup(func() { + cancelFunc() + }) + + testutils.StartManager(ctx, t, mgr) + + return cacheManager, ctx +} + +func TestCacheManager_wipeCacheIfNeeded(t *testing.T) { + configMapGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} + dataClientForTest := func() CFDataClient { + cfdc := &fakes.FakeCfClient{} + + cm := unstructuredFor(configMapGVK, "config-test-1") + _, err := cfdc.AddData(context.Background(), cm) + + require.NoError(t, err, "adding ConfigMap config-test-1 in cfClient") + + return cfdc + } + + tcs := []struct { + name string + cm *CacheManager + expectedData map[fakes.CfDataKey]interface{} + }{ + { + name: "wipe cache if there are gvks to remove", + cm: &CacheManager{ + cfClient: dataClientForTest(), + gvksToDeleteFromCache: func() *watch.Set { + gvksToDelete := watch.NewSet() + gvksToDelete.Add(configMapGVK) + return gvksToDelete + }(), + syncMetricsCache: syncutil.NewMetricsCache(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + }, + { + name: "wipe cache if there are excluder changes", + cm: &CacheManager{ + cfClient: dataClientForTest(), + excluderChanged: true, + syncMetricsCache: syncutil.NewMetricsCache(), + gvksToDeleteFromCache: watch.NewSet(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + }, + { + name: "don't wipe cache if no excluder changes or no gvks to delete", + cm: &CacheManager{ + cfClient: dataClientForTest(), + syncMetricsCache: syncutil.NewMetricsCache(), + gvksToDeleteFromCache: watch.NewSet(), + }, + expectedData: map[fakes.CfDataKey]interface{}{{Gvk: configMapGVK, Key: "default/config-test-1"}: nil}, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + cfClient, ok := tc.cm.cfClient.(*fakes.FakeCfClient) + require.True(t, ok) + + tc.cm.wipeCacheIfNeeded(context.Background()) + require.True(t, cfClient.Contains(tc.expectedData)) + }) + } +} + +// TestCacheManager_AddObject tests that we can add objects in the cache. +func TestCacheManager_AddObject(t *testing.T) { + pod := fakes.Pod( + fakes.WithNamespace("test-ns"), + fakes.WithName("test-name"), + ) + unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pod) + require.NoError(t, err) + + mgr, _ := testutils.SetupManager(t, cfg) + + tcs := []struct { + name string + cm *CacheManager + expectSyncMetric bool + expectedMetricStatus metrics.Status + expectedData map[fakes.CfDataKey]interface{} + }{ + { + name: "AddObject happy path", + cm: &CacheManager{ + cfClient: &fakes.FakeCfClient{}, + watchedSet: func() *watch.Set { + ws := watch.NewSet() + ws.Add(pod.GroupVersionKind()) + + return ws + }(), + tracker: readiness.NewTracker(mgr.GetAPIReader(), false, false, false), + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: process.Get(), + }, + expectedData: map[fakes.CfDataKey]interface{}{{Gvk: pod.GroupVersionKind(), Key: "test-ns/test-name"}: nil}, + expectSyncMetric: true, + expectedMetricStatus: metrics.ActiveStatus, + }, + { + name: "AddObject has no effect if GVK is not watched", + cm: &CacheManager{ + cfClient: &fakes.FakeCfClient{}, + watchedSet: watch.NewSet(), + tracker: readiness.NewTracker(mgr.GetAPIReader(), false, false, false), + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: process.Get(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: false, + }, + { + name: "AddObject has no effect if GVK is process excluded", + cm: &CacheManager{ + cfClient: &fakes.FakeCfClient{}, + watchedSet: func() *watch.Set { + ws := watch.NewSet() + ws.Add(pod.GroupVersionKind()) + + return ws + }(), + tracker: readiness.NewTracker(mgr.GetAPIReader(), false, false, false), + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: func() *process.Excluder { + processExcluder := process.New() + processExcluder.Add([]configv1alpha1.MatchEntry{ + { + ExcludedNamespaces: []wildcard.Wildcard{"test-ns"}, + Processes: []string{"sync"}, + }, + }) + return processExcluder + }(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: false, + }, + { + name: "AddObject sets metrics on error from cfdataclient", + cm: &CacheManager{ + cfClient: func() CFDataClient { + c := &fakes.FakeCfClient{} + c.SetErroring(true) + return c + }(), + watchedSet: func() *watch.Set { + ws := watch.NewSet() + ws.Add(pod.GroupVersionKind()) + + return ws + }(), + tracker: readiness.NewTracker(mgr.GetAPIReader(), false, false, false), + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: process.Get(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: true, + expectedMetricStatus: metrics.ErrorStatus, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + err := tc.cm.AddObject(context.Background(), &unstructured.Unstructured{Object: unstructuredPod}) + if tc.expectedMetricStatus == metrics.ActiveStatus { + require.NoError(t, err) + } + + assertExpecations(t, tc.cm, &unstructured.Unstructured{Object: unstructuredPod}, tc.expectedData, tc.expectSyncMetric, &tc.expectedMetricStatus) + }) + } +} + +func assertExpecations(t *testing.T, cm *CacheManager, instance *unstructured.Unstructured, expectedData map[fakes.CfDataKey]interface{}, expectSyncMetric bool, expectedMetricStatus *metrics.Status) { + t.Helper() + + cfClient, ok := cm.cfClient.(*fakes.FakeCfClient) + require.True(t, ok) + + require.True(t, cfClient.Contains(expectedData)) + + syncKey := syncutil.GetKeyForSyncMetrics(instance.GetNamespace(), instance.GetName()) + + require.Equal(t, expectSyncMetric, cm.syncMetricsCache.HasObject(syncKey)) + + if expectSyncMetric { + require.Equal(t, *expectedMetricStatus, cm.syncMetricsCache.GetTags(syncKey).Status) + } +} + +// TestCacheManager_RemoveObject tests that we can remove objects from the cache. +func TestCacheManager_RemoveObject(t *testing.T) { + pod := fakes.Pod( + fakes.WithNamespace("test-ns"), + fakes.WithName("test-name"), + ) + unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pod) + require.NoError(t, err) + + mgr, _ := testutils.SetupManager(t, cfg) + tracker := readiness.NewTracker(mgr.GetAPIReader(), false, false, false) + makeDataClient := func() *fakes.FakeCfClient { + c := &fakes.FakeCfClient{} + _, err := c.AddData(context.Background(), &unstructured.Unstructured{Object: unstructuredPod}) + require.NoError(t, err) + + return c + } + + tcs := []struct { + name string + cm *CacheManager + expectSyncMetric bool + expectedData map[fakes.CfDataKey]interface{} + }{ + { + name: "RemoveObject happy path", + cm: &CacheManager{ + cfClient: makeDataClient(), + watchedSet: func() *watch.Set { + ws := watch.NewSet() + ws.Add(pod.GroupVersionKind()) + + return ws + }(), + tracker: tracker, + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: process.Get(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: false, + }, + { + name: "RemoveObject succeeds even if GVK is not watched", + cm: &CacheManager{ + cfClient: makeDataClient(), + watchedSet: watch.NewSet(), + tracker: tracker, + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: process.Get(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: false, + }, + { + name: "RemoveObject succeeds even if process excluded", + cm: &CacheManager{ + cfClient: makeDataClient(), + watchedSet: func() *watch.Set { + ws := watch.NewSet() + ws.Add(pod.GroupVersionKind()) + + return ws + }(), + tracker: tracker, + syncMetricsCache: syncutil.NewMetricsCache(), + processExcluder: func() *process.Excluder { + processExcluder := process.New() + processExcluder.Add([]configv1alpha1.MatchEntry{ + { + ExcludedNamespaces: []wildcard.Wildcard{"test-ns"}, + Processes: []string{"sync"}, + }, + }) + return processExcluder + }(), + }, + expectedData: map[fakes.CfDataKey]interface{}{}, + expectSyncMetric: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + require.NoError(t, tc.cm.RemoveObject(context.Background(), &unstructured.Unstructured{Object: unstructuredPod})) + + assertExpecations(t, tc.cm, &unstructured.Unstructured{Object: unstructuredPod}, tc.expectedData, tc.expectSyncMetric, nil) + }) + } +} + +// TestCacheManager_UpsertSource tests that we can modify the gvk aggregator and watched set when adding a new source. +func TestCacheManager_UpsertSource(t *testing.T) { + configMapGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} + podGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} + sourceA := aggregator.Key{Source: "a", ID: "source"} + sourceB := aggregator.Key{Source: "b", ID: "source"} + + type sourcesAndGvk struct { + source aggregator.Key + gvks []schema.GroupVersionKind + } + + tcs := []struct { + name string + sourcesAndGvks []sourcesAndGvk + expectedGVKs []schema.GroupVersionKind + }{ + { + name: "add one source", + sourcesAndGvks: []sourcesAndGvk{ + { + source: sourceA, + gvks: []schema.GroupVersionKind{configMapGVK}, + }, + }, + expectedGVKs: []schema.GroupVersionKind{configMapGVK}, + }, + { + name: "overwrite source", + sourcesAndGvks: []sourcesAndGvk{ + { + source: sourceA, + gvks: []schema.GroupVersionKind{configMapGVK}, + }, + { + source: sourceA, + gvks: []schema.GroupVersionKind{podGVK}, + }, + }, + expectedGVKs: []schema.GroupVersionKind{podGVK}, + }, + { + name: "remove source by not specifying any gvk", + sourcesAndGvks: []sourcesAndGvk{ + { + source: sourceA, + gvks: []schema.GroupVersionKind{configMapGVK}, + }, + { + source: sourceA, + gvks: []schema.GroupVersionKind{}, + }, + }, + expectedGVKs: []schema.GroupVersionKind{}, + }, + { + name: "add two disjoing sources", + sourcesAndGvks: []sourcesAndGvk{ + { + source: sourceA, + gvks: []schema.GroupVersionKind{configMapGVK}, + }, + { + source: sourceB, + gvks: []schema.GroupVersionKind{podGVK}, + }, + }, + expectedGVKs: []schema.GroupVersionKind{configMapGVK, podGVK}, + }, + { + name: "add two sources with overlapping gvks", + sourcesAndGvks: []sourcesAndGvk{ + { + source: sourceA, + gvks: []schema.GroupVersionKind{configMapGVK, podGVK}, + }, + { + source: sourceB, + gvks: []schema.GroupVersionKind{podGVK}, + }, + }, + expectedGVKs: []schema.GroupVersionKind{configMapGVK, podGVK}, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + cacheManager, ctx := makeCacheManager(t) + + for _, sourceAndGVK := range tc.sourcesAndGvks { + require.NoError(t, cacheManager.UpsertSource(ctx, sourceAndGVK.source, sourceAndGVK.gvks)) + } + + require.ElementsMatch(t, cacheManager.watchedSet.Items(), tc.expectedGVKs) + require.ElementsMatch(t, cacheManager.gvksToSync.GVKs(), tc.expectedGVKs) + }) + } +} + +// TestCacheManager_RemoveSource tests that we can modify the gvk aggregator when removing a source. +func TestCacheManager_RemoveSource(t *testing.T) { + configMapGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} + podGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} + sourceA := aggregator.Key{Source: "a", ID: "source"} + sourceB := aggregator.Key{Source: "b", ID: "source"} + + tcs := []struct { + name string + seed func(c *CacheManager) + sourcesToRemove []aggregator.Key + expectedGVKs []schema.GroupVersionKind + }{ + { + name: "remove disjoint source", + seed: func(c *CacheManager) { + require.NoError(t, c.gvksToSync.Upsert(sourceA, []schema.GroupVersionKind{podGVK})) + require.NoError(t, c.gvksToSync.Upsert(sourceB, []schema.GroupVersionKind{configMapGVK})) + }, + sourcesToRemove: []aggregator.Key{sourceB}, + expectedGVKs: []schema.GroupVersionKind{podGVK}, + }, + { + name: "remove overlapping source", + seed: func(c *CacheManager) { + require.NoError(t, c.gvksToSync.Upsert(sourceA, []schema.GroupVersionKind{podGVK})) + require.NoError(t, c.gvksToSync.Upsert(sourceB, []schema.GroupVersionKind{podGVK})) + }, + sourcesToRemove: []aggregator.Key{sourceB}, + expectedGVKs: []schema.GroupVersionKind{podGVK}, + }, + { + name: "remove non existing source", + seed: func(c *CacheManager) { + require.NoError(t, c.gvksToSync.Upsert(sourceA, []schema.GroupVersionKind{podGVK})) + }, + sourcesToRemove: []aggregator.Key{sourceB}, + expectedGVKs: []schema.GroupVersionKind{podGVK}, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + cm, ctx := makeCacheManager(t) + tc.seed(cm) + + for _, source := range tc.sourcesToRemove { + require.NoError(t, cm.RemoveSource(ctx, source)) + } + + require.ElementsMatch(t, cm.gvksToSync.GVKs(), tc.expectedGVKs) + }) + } + cacheManager, ctx := makeCacheManager(t) + + // seed the gvk aggregator + require.NoError(t, cacheManager.gvksToSync.Upsert(sourceA, []schema.GroupVersionKind{podGVK})) + require.NoError(t, cacheManager.gvksToSync.Upsert(sourceB, []schema.GroupVersionKind{podGVK, configMapGVK})) + + // removing a source that is not the only one referencing a gvk ... + require.NoError(t, cacheManager.RemoveSource(ctx, sourceB)) + // ... should not remove any gvks that are still referenced by other sources + require.True(t, cacheManager.gvksToSync.IsPresent(podGVK)) + require.False(t, cacheManager.gvksToSync.IsPresent(configMapGVK)) + + require.NoError(t, cacheManager.RemoveSource(ctx, sourceA)) + require.False(t, cacheManager.gvksToSync.IsPresent(podGVK)) +} + +func unstructuredFor(gvk schema.GroupVersionKind, name string) *unstructured.Unstructured { + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(gvk) + u.SetName(name) + u.SetNamespace("default") + if gvk.Kind == "Pod" { + u.Object["spec"] = map[string]interface{}{ + "containers": []map[string]interface{}{ + { + "name": "foo-container", + "image": "foo-image", + }, + }, + } + } + return u +} diff --git a/pkg/cachemanager/cachemanager_test/cachemanager_integration_test.go b/pkg/cachemanager/cachemanager_test/cachemanager_integration_test.go new file mode 100644 index 00000000000..7618c62bf45 --- /dev/null +++ b/pkg/cachemanager/cachemanager_test/cachemanager_integration_test.go @@ -0,0 +1,369 @@ +package cachemanager_test + +import ( + "context" + "fmt" + "math/rand" + "sync" + "testing" + "time" + + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager/aggregator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + syncc "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/sync" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +const ( + eventuallyTimeout = 10 * time.Second + eventuallyTicker = 2 * time.Second + + jitterUpperBound = 100 +) + +var cfg *rest.Config + +var ( + configMapGVK = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} + podGVK = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} + + cm1Name = "config-test-1" + cm2Name = "config-test-2" + + pod1Name = "pod-test-1" +) + +func TestMain(m *testing.M) { + testutils.StartControlPlane(m, &cfg, 3) +} + +// TestCacheManager_replay_retries tests that we can retry GVKs that error out in the replay goroutine. +func TestCacheManager_replay_retries(t *testing.T) { + mgr, wm := testutils.SetupManager(t, cfg) + c := testclient.NewRetryClient(mgr.GetClient()) + + fi := fakes.NewFailureInjector() + reader := fakes.SpyReader{ + Reader: c, + ListFunc: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + // return as many syntenthic failures as there are registered for this kind + if fi.CheckFailures(list.GetObjectKind().GroupVersionKind().Kind) { + return fmt.Errorf("synthetic failure") + } + + return c.List(ctx, list, opts...) + }, + } + + testResources, ctx := makeTestResources(t, mgr, wm, reader) + cacheManager := testResources.CacheManager + dataStore := testResources.CFDataClient + + cfClient, ok := dataStore.(*fakes.FakeCfClient) + require.True(t, ok) + + cm := unstructuredFor(configMapGVK, cm1Name) + require.NoError(t, c.Create(ctx, cm), fmt.Sprintf("creating ConfigMap %s", cm1Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm), fmt.Sprintf("deleting resource %s", cm1Name)) + }) + cmKey, err := fakes.KeyFor(cm) + require.NoError(t, err) + + pod := unstructuredFor(podGVK, pod1Name) + require.NoError(t, c.Create(ctx, pod), fmt.Sprintf("creating Pod %s", pod1Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, pod), fmt.Sprintf("deleting resource %s", pod1Name)) + }) + podKey, err := fakes.KeyFor(pod) + require.NoError(t, err) + + syncSourceOne := aggregator.Key{Source: "source_a", ID: "ID_a"} + require.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{configMapGVK, podGVK})) + + expected := map[fakes.CfDataKey]interface{}{ + cmKey: nil, + podKey: nil, + } + + require.Eventually(t, expectedCheck(cfClient, expected), eventuallyTimeout, eventuallyTicker) + + fi.SetFailures("ConfigMapList", 5) + + // this call should schedule a cache wipe and a replay for the configMapGVK + require.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{configMapGVK})) + + expected2 := map[fakes.CfDataKey]interface{}{ + cmKey: nil, + } + require.Eventually(t, expectedCheck(cfClient, expected2), eventuallyTimeout, eventuallyTicker) +} + +// TestCacheManager_concurrent makes sure that we can add and remove multiple sources +// from separate go routines and changes to the underlying cache are reflected. +func TestCacheManager_concurrent(t *testing.T) { + r := rand.New(rand.NewSource(12345)) // #nosec G404: Using weak random number generator for determinism between calls + + mgr, wm := testutils.SetupManager(t, cfg) + c := testclient.NewRetryClient(mgr.GetClient()) + testResources, ctx := makeTestResources(t, mgr, wm, c) + + cacheManager := testResources.CacheManager + dataStore := testResources.CFDataClient + agg := testResources.GVKAgreggator + + // Create configMaps to test for + cm := unstructuredFor(configMapGVK, cm1Name) + require.NoError(t, c.Create(ctx, cm), fmt.Sprintf("creating ConfigMap %s", cm1Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm), fmt.Sprintf("deleting resource %s", cm1Name)) + }) + cmKey, err := fakes.KeyFor(cm) + require.NoError(t, err) + + cm2 := unstructuredFor(configMapGVK, cm2Name) + require.NoError(t, c.Create(ctx, cm2), fmt.Sprintf("creating ConfigMap %s", cm2Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm2), fmt.Sprintf("deleting resource %s", cm2Name)) + }) + cm2Key, err := fakes.KeyFor(cm2) + require.NoError(t, err) + + pod := unstructuredFor(podGVK, pod1Name) + require.NoError(t, c.Create(ctx, pod), fmt.Sprintf("creating Pod %s", pod1Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, pod), fmt.Sprintf("deleting resource %s", pod1Name)) + }) + podKey, err := fakes.KeyFor(pod) + require.NoError(t, err) + + cfClient, ok := dataStore.(*fakes.FakeCfClient) + require.True(t, ok) + + syncSourceOne := aggregator.Key{Source: "source_a", ID: "ID_a"} + syncSourceTwo := aggregator.Key{Source: "source_b", ID: "ID_b"} + + wg := &sync.WaitGroup{} + + // simulate a churn-y concurrent access by swapping the gvks for the sync sources repeatedly + // and removing sync sources, all from different go routines. + for i := 1; i < 100; i++ { + wg.Add(3) + + // add some jitter between go func calls + time.Sleep(time.Duration(r.Intn(jitterUpperBound)) * time.Millisecond) + go func() { + defer wg.Done() + + assert.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{configMapGVK})) + assert.NoError(t, cacheManager.UpsertSource(ctx, syncSourceTwo, []schema.GroupVersionKind{podGVK})) + }() + + time.Sleep(time.Duration(r.Intn(jitterUpperBound)) * time.Millisecond) + go func() { + defer wg.Done() + + assert.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{podGVK})) + assert.NoError(t, cacheManager.UpsertSource(ctx, syncSourceTwo, []schema.GroupVersionKind{configMapGVK})) + }() + + time.Sleep(time.Duration(r.Intn(jitterUpperBound)) * time.Millisecond) + go func() { + defer wg.Done() + + assert.NoError(t, cacheManager.RemoveSource(ctx, syncSourceTwo)) + assert.NoError(t, cacheManager.RemoveSource(ctx, syncSourceOne)) + }() + } + + wg.Wait() + + // final upsert for determinism + require.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{configMapGVK})) + require.NoError(t, cacheManager.UpsertSource(ctx, syncSourceTwo, []schema.GroupVersionKind{podGVK})) + + expected := map[fakes.CfDataKey]interface{}{ + cmKey: nil, + cm2Key: nil, + podKey: nil, + } + + require.Eventually(t, expectedCheck(cfClient, expected), eventuallyTimeout, eventuallyTicker) + // now assert that the gvkAggregator looks as expected + agg.IsPresent(configMapGVK) + gvks := agg.List(syncSourceOne) + require.Len(t, gvks, 1) + _, foundConfigMap := gvks[configMapGVK] + require.True(t, foundConfigMap) + gvks = agg.List(syncSourceTwo) + require.Len(t, gvks, 1) + _, foundPod := gvks[podGVK] + require.True(t, foundPod) + + // do a final remove and expect the cache to clear + require.NoError(t, cacheManager.RemoveSource(ctx, syncSourceOne)) + require.NoError(t, cacheManager.RemoveSource(ctx, syncSourceTwo)) + + require.Eventually(t, expectedCheck(cfClient, map[fakes.CfDataKey]interface{}{}), eventuallyTimeout, eventuallyTicker) + require.True(t, len(agg.GVKs()) == 0) +} + +// TestCacheManager_instance_updates tests that cache manager wires up dependencies correctly +// such that updates to an instance of a watched gvks are reconciled in the sync_controller. +func TestCacheManager_instance_updates(t *testing.T) { + mgr, wm := testutils.SetupManager(t, cfg) + c := testclient.NewRetryClient(mgr.GetClient()) + + testResources, ctx := makeTestResources(t, mgr, wm, c) + + cacheManager := testResources.CacheManager + dataStore := testResources.CFDataClient + + cfClient, ok := dataStore.(*fakes.FakeCfClient) + require.True(t, ok) + + cm := unstructuredFor(configMapGVK, cm1Name) + require.NoError(t, c.Create(ctx, cm), fmt.Sprintf("creating ConfigMap %s", cm1Name)) + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm), fmt.Sprintf("deleting resource %s", cm1Name)) + }) + cmKey, err := fakes.KeyFor(cm) + require.NoError(t, err) + + syncSourceOne := aggregator.Key{Source: "source_a", ID: "ID_a"} + require.NoError(t, cacheManager.UpsertSource(ctx, syncSourceOne, []schema.GroupVersionKind{configMapGVK})) + + expected := map[fakes.CfDataKey]interface{}{ + cmKey: nil, + } + + require.Eventually(t, expectedCheck(cfClient, expected), eventuallyTimeout, eventuallyTicker) + + cmUpdate := unstructuredFor(configMapGVK, cm1Name) + cmUpdate.SetLabels(map[string]string{"testlabel": "test"}) // trigger an instance update + require.NoError(t, c.Update(ctx, cmUpdate)) + + require.Eventually(t, func() bool { + instance := cfClient.GetData(cmKey) + unInstance, ok := instance.(*unstructured.Unstructured) + require.True(t, ok) + + value, found, err := unstructured.NestedString(unInstance.Object, "metadata", "labels", "testlabel") + require.NoError(t, err) + + return found && "test" == value + }, eventuallyTimeout, eventuallyTicker) +} + +func deleteResource(ctx context.Context, c client.Client, resounce *unstructured.Unstructured) error { + err := c.Delete(ctx, resounce) + if apierrors.IsNotFound(err) { + // resource does not exist, this is good + return nil + } + + return err +} + +func expectedCheck(cfClient *fakes.FakeCfClient, expected map[fakes.CfDataKey]interface{}) func() bool { + return func() bool { + if cfClient.Len() != len(expected) { + return false + } + if cfClient.Contains(expected) { + return true + } + + return false + } +} + +func unstructuredFor(gvk schema.GroupVersionKind, name string) *unstructured.Unstructured { + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(gvk) + u.SetName(name) + u.SetNamespace("default") + if gvk.Kind == "Pod" { + u.Object["spec"] = map[string]interface{}{ + "containers": []map[string]interface{}{ + { + "name": "foo-container", + "image": "foo-image", + }, + }, + } + } + return u +} + +type testResources struct { + *cachemanager.CacheManager + cachemanager.CFDataClient + *aggregator.GVKAgreggator +} + +func makeTestResources(t *testing.T, mgr manager.Manager, wm *watch.Manager, reader client.Reader) (testResources, context.Context) { + ctx, cancelFunc := context.WithCancel(context.Background()) + t.Cleanup(func() { + cancelFunc() + }) + + cfClient := &fakes.FakeCfClient{} + tracker, err := readiness.SetupTracker(mgr, false, false, false) + require.NoError(t, err) + processExcluder := process.Get() + processExcluder.Add([]configv1alpha1.MatchEntry{ + { + ExcludedNamespaces: []wildcard.Wildcard{"kube-system"}, + Processes: []string{"sync"}, + }, + }) + events := make(chan event.GenericEvent, 1024) + reg, err := wm.NewRegistrar( + "test-cache-manager", + events) + require.NoError(t, err) + + aggregator := aggregator.NewGVKAggregator() + config := &cachemanager.Config{ + CfClient: cfClient, + SyncMetricsCache: syncutil.NewMetricsCache(), + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: reader, + GVKAggregator: aggregator, + } + cacheManager, err := cachemanager.NewCacheManager(config) + require.NoError(t, err) + + syncAdder := syncc.Adder{ + Events: events, + CacheManager: cacheManager, + } + require.NoError(t, syncAdder.Add(mgr), "registering sync controller") + go func() { + assert.NoError(t, cacheManager.Start(ctx)) + }() + + testutils.StartManager(ctx, t, mgr) + + return testResources{cacheManager, cfClient, aggregator}, ctx +} diff --git a/pkg/cachemanager/parser/syncannotationreader.go b/pkg/cachemanager/parser/syncannotationreader.go new file mode 100644 index 00000000000..ae22dac98d8 --- /dev/null +++ b/pkg/cachemanager/parser/syncannotationreader.go @@ -0,0 +1,87 @@ +package parser + +import ( + "encoding/json" + "strings" + + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// syncAnnotationName is the name of the annotation that stores +// GVKS that are required to be synced. +const SyncAnnotationName = "metadata.gatekeeper.sh/requires-sync-data" + +// SyncRequirements contains a list of ANDed requirements, each of which +// contains an expanded set of equivalent (ORed) GVKs. +type SyncRequirements []GVKEquivalenceSet + +// GVKEquivalenceSet is a set of GVKs that a template can use +// interchangeably in its referential policy implementation. +type GVKEquivalenceSet map[schema.GroupVersionKind]struct{} + +// CompactSyncRequirements contains a list of ANDed requirements, each of +// which contains a list of equivalent (ORed) GVKs in compact form. +type CompactSyncRequirements [][]CompactGVKEquivalenceSet + +// compactGVKEquivalenceSet contains a set of equivalent GVKs, expressed +// in the compact form [groups, versions, kinds] where any combination of +// items from these three fields can be considered a valid equivalent. +// Used for unmarshalling as this is the form used in requiressync annotations. +type CompactGVKEquivalenceSet struct { + Groups []string `json:"groups"` + Versions []string `json:"versions"` + Kinds []string `json:"kinds"` +} + +// ReadSyncRequirements parses the sync requirements from a +// constraint template. +func ReadSyncRequirements(t *templates.ConstraintTemplate) (SyncRequirements, error) { + if t.ObjectMeta.Annotations != nil { + if annotation, exists := t.ObjectMeta.Annotations[SyncAnnotationName]; exists { + annotation = strings.Trim(annotation, "\n\"") + compactSyncRequirements := CompactSyncRequirements{} + decoder := json.NewDecoder(strings.NewReader(annotation)) + decoder.DisallowUnknownFields() + err := decoder.Decode(&compactSyncRequirements) + if err != nil { + return nil, err + } + requirements, err := ExpandCompactRequirements(compactSyncRequirements) + if err != nil { + return nil, err + } + return requirements, nil + } + } + return SyncRequirements{}, nil +} + +// Takes a compactGVKSet and expands it into a GVKEquivalenceSet. +func ExpandCompactEquivalenceSet(compactEquivalenceSet CompactGVKEquivalenceSet) GVKEquivalenceSet { + equivalenceSet := GVKEquivalenceSet{} + for _, group := range compactEquivalenceSet.Groups { + for _, version := range compactEquivalenceSet.Versions { + for _, kind := range compactEquivalenceSet.Kinds { + equivalenceSet[schema.GroupVersionKind{Group: group, Version: version, Kind: kind}] = struct{}{} + } + } + } + return equivalenceSet +} + +// Takes a CompactSyncRequirements (the json form provided in the template +// annotation) and expands it into a SyncRequirements. +func ExpandCompactRequirements(compactSyncRequirements CompactSyncRequirements) (SyncRequirements, error) { + syncRequirements := SyncRequirements{} + for _, compactRequirement := range compactSyncRequirements { + requirement := GVKEquivalenceSet{} + for _, compactEquivalenceSet := range compactRequirement { + for equivalentGVK := range ExpandCompactEquivalenceSet(compactEquivalenceSet) { + requirement[equivalentGVK] = struct{}{} + } + } + syncRequirements = append(syncRequirements, requirement) + } + return syncRequirements, nil +} diff --git a/pkg/cachemanager/parser/syncannotationreader_test.go b/pkg/cachemanager/parser/syncannotationreader_test.go new file mode 100644 index 00000000000..aa26b076eaa --- /dev/null +++ b/pkg/cachemanager/parser/syncannotationreader_test.go @@ -0,0 +1,196 @@ +package parser + +import ( + "reflect" + "testing" + + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestReadSyncRequirements(t *testing.T) { + tests := []struct { + name string + template *templates.ConstraintTemplate + want SyncRequirements + wantErr bool + }{ + { + name: "test with basic valid annotation", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "\n\"[[{\"groups\": [\"group1\"], \"versions\": [\"version1\"], \"kinds\": [\"kind1\"]}]]\"", + }, + }, + }, + want: SyncRequirements{ + { + { + Group: "group1", + Version: "version1", + Kind: "kind1", + }: struct{}{}, + }, + }, + }, + { + name: "test with valid annotation with multiple groups, versions, and kinds", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "\n\"[[{\"groups\": [\"group1\", \"group2\"], \"versions\": [\"version1\", \"version2\"], \"kinds\": [\"kind1\", \"kind2\"]}]]\"", + }, + }, + }, + want: SyncRequirements{ + { + { + Group: "group1", + Version: "version1", + Kind: "kind1", + }: struct{}{}, + { + Group: "group1", + Version: "version1", + Kind: "kind2", + }: struct{}{}, + { + Group: "group1", + Version: "version2", + Kind: "kind1", + }: struct{}{}, + { + Group: "group1", + Version: "version2", + Kind: "kind2", + }: struct{}{}, + { + Group: "group2", + Version: "version1", + Kind: "kind1", + }: struct{}{}, + { + Group: "group2", + Version: "version1", + Kind: "kind2", + }: struct{}{}, + { + Group: "group2", + Version: "version2", + Kind: "kind1", + }: struct{}{}, + { + Group: "group2", + Version: "version2", + Kind: "kind2", + }: struct{}{}, + }, + }, + }, + { + name: "test with valid annotation with multiple equivalence sets", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "\n\"[[{\"groups\": [\"group1\"], \"versions\": [\"version1\"], \"kinds\": [\"kind1\"]}, {\"groups\": [\"group2\"], \"versions\": [\"version2\"], \"kinds\": [\"kind2\"]}]]\"", + }, + }, + }, + want: SyncRequirements{ + { + { + Group: "group1", + Version: "version1", + Kind: "kind1", + }: struct{}{}, + { + Group: "group2", + Version: "version2", + Kind: "kind2", + }: struct{}{}, + }, + }, + }, + { + name: "test with valid annotation with multiple requirements", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "\n\"[[{\"groups\": [\"group1\"], \"versions\": [\"version1\"], \"kinds\": [\"kind1\"]}], [{\"groups\": [\"group2\"], \"versions\": [\"version2\"], \"kinds\": [\"kind2\"]}]]\"", + }, + }, + }, + want: SyncRequirements{ + { + { + Group: "group1", + Version: "version1", + Kind: "kind1", + }: struct{}{}, + }, + { + { + Group: "group2", + Version: "version2", + Kind: "kind2", + }: struct{}{}, + }, + }, + }, + { + name: "test with no requires-sync-data annotation", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + }, + }, + want: SyncRequirements{}, + }, + { + name: "test with empty requires-sync-data annotation", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "", + }, + }, + }, + wantErr: true, + }, + { + name: "test with invalid requires-sync-data annotation", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "invalid", + }, + }, + }, + wantErr: true, + }, + { + name: "test with requires-sync-data annotation with invalid keys", + template: &templates.ConstraintTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "metadata.gatekeeper.sh/requires-sync-data": "\n\"[[{\"group\": [\"group1\"], \"version\": [\"version1\"], \"kind\": [\"kind1\"]}]]\"", + }, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ReadSyncRequirements(tt.template) + if (err != nil) != tt.wantErr { + t.Errorf("ReadSyncRequirements() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ReadSyncRequirements() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/controller/add_config.go b/pkg/controller/add_config.go index 650118903ae..1672a205f0d 100644 --- a/pkg/controller/add_config.go +++ b/pkg/controller/add_config.go @@ -16,7 +16,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/config" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config" ) func init() { diff --git a/pkg/controller/add_constrainttemplate.go b/pkg/controller/add_constrainttemplate.go index ccd01bc9199..837bdf0f3f1 100644 --- a/pkg/controller/add_constrainttemplate.go +++ b/pkg/controller/add_constrainttemplate.go @@ -16,7 +16,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/constrainttemplate" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplate" ) func init() { diff --git a/pkg/controller/add_expansionstatus.go b/pkg/controller/add_expansionstatus.go new file mode 100644 index 00000000000..288375d0429 --- /dev/null +++ b/pkg/controller/add_expansionstatus.go @@ -0,0 +1,24 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/expansionstatus" +) + +func init() { + Injectors = append(Injectors, &expansionstatus.Adder{}) +} diff --git a/pkg/controller/add_expansiontemplate.go b/pkg/controller/add_expansiontemplate.go index 6abdf4340ac..f917bb73472 100644 --- a/pkg/controller/add_expansiontemplate.go +++ b/pkg/controller/add_expansiontemplate.go @@ -16,7 +16,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/expansion" ) func init() { diff --git a/pkg/controller/add_externaldata.go b/pkg/controller/add_externaldata.go index 2a637230498..425365c0b27 100644 --- a/pkg/controller/add_externaldata.go +++ b/pkg/controller/add_externaldata.go @@ -13,7 +13,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/externaldata" ) func init() { diff --git a/pkg/controller/add_mutators.go b/pkg/controller/add_mutators.go index b030cf82c86..5e6eef76e2c 100644 --- a/pkg/controller/add_mutators.go +++ b/pkg/controller/add_mutators.go @@ -16,7 +16,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutators/instances" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutators/instances" ) func init() { diff --git a/pkg/controller/add_mutatorstatus.go b/pkg/controller/add_mutatorstatus.go index f47d4d7db1e..91b1a374b0a 100644 --- a/pkg/controller/add_mutatorstatus.go +++ b/pkg/controller/add_mutatorstatus.go @@ -16,7 +16,7 @@ limitations under the License. package controller import ( - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutatorstatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutatorstatus" ) func init() { diff --git a/pkg/controller/add_pubsub.go b/pkg/controller/add_pubsub.go new file mode 100644 index 00000000000..52904f36d50 --- /dev/null +++ b/pkg/controller/add_pubsub.go @@ -0,0 +1,24 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/pubsub" +) + +func init() { + Injectors = append(Injectors, &pubsub.Adder{}) +} diff --git a/pkg/controller/config/config_controller.go b/pkg/controller/config/config_controller.go index 81baf0c6876..59c2d9db3a4 100644 --- a/pkg/controller/config/config_controller.go +++ b/pkg/controller/config/config_controller.go @@ -19,25 +19,18 @@ import ( "context" "fmt" - constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - syncc "github.com/open-policy-agent/gatekeeper/pkg/controller/sync" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/keys" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + cm "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager/aggregator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/keys" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -53,21 +46,15 @@ const ( var log = logf.Log.WithName("controller").WithValues("kind", "Config") type Adder struct { - Opa *constraintclient.Client - WatchManager *watch.Manager ControllerSwitch *watch.ControllerSwitch Tracker *readiness.Tracker - ProcessExcluder *process.Excluder - WatchSet *watch.Set + CacheManager *cm.CacheManager } // Add creates a new ConfigController and adds it to the Manager with default RBAC. The Manager will set fields on the Controller // and Start it when the Manager is Started. func (a *Adder) Add(mgr manager.Manager) error { - // Events will be used to receive events from dynamic watches registered - // via the registrar below. - events := make(chan event.GenericEvent, 1024) - r, err := newReconciler(mgr, a.Opa, a.WatchManager, a.ControllerSwitch, a.Tracker, a.ProcessExcluder, events, a.WatchSet, events) + r, err := newReconciler(mgr, a.CacheManager, a.ControllerSwitch, a.Tracker) if err != nil { return err } @@ -75,14 +62,6 @@ func (a *Adder) Add(mgr manager.Manager) error { return add(mgr, r) } -func (a *Adder) InjectOpa(o *constraintclient.Client) { - a.Opa = o -} - -func (a *Adder) InjectWatchManager(wm *watch.Manager) { - a.WatchManager = wm -} - func (a *Adder) InjectControllerSwitch(cs *watch.ControllerSwitch) { a.ControllerSwitch = cs } @@ -91,62 +70,24 @@ func (a *Adder) InjectTracker(t *readiness.Tracker) { a.Tracker = t } -func (a *Adder) InjectProcessExcluder(m *process.Excluder) { - a.ProcessExcluder = m +func (a *Adder) InjectCacheManager(cm *cm.CacheManager) { + a.CacheManager = cm } -func (a *Adder) InjectMutationSystem(mutationSystem *mutation.System) {} - -func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) {} - -func (a *Adder) InjectProviderCache(providerCache *externaldata.ProviderCache) {} - -func (a *Adder) InjectWatchSet(watchSet *watch.Set) { - a.WatchSet = watchSet -} - -// newReconciler returns a new reconcile.Reconciler -// events is the channel from which sync controller will receive the events -// regEvents is the channel registered by Registrar to put the events in -// events and regEvents point to same event channel except for testing. -func newReconciler(mgr manager.Manager, opa syncc.OpaDataClient, wm *watch.Manager, cs *watch.ControllerSwitch, tracker *readiness.Tracker, processExcluder *process.Excluder, events <-chan event.GenericEvent, watchSet *watch.Set, regEvents chan<- event.GenericEvent) (*ReconcileConfig, error) { - filteredOpa := syncc.NewFilteredOpaDataClient(opa, watchSet) - syncMetricsCache := syncc.NewMetricsCache() - - syncAdder := syncc.Adder{ - Opa: filteredOpa, - Events: events, - MetricsCache: syncMetricsCache, - Tracker: tracker, - ProcessExcluder: processExcluder, - } - // Create subordinate controller - we will feed it events dynamically via watch - if err := syncAdder.Add(mgr); err != nil { - return nil, fmt.Errorf("registering sync controller: %w", err) - } - - if watchSet == nil { - return nil, fmt.Errorf("watchSet must be non-nil") +// newReconciler returns a new reconcile.Reconciler. +func newReconciler(mgr manager.Manager, cm *cm.CacheManager, cs *watch.ControllerSwitch, tracker *readiness.Tracker) (*ReconcileConfig, error) { + if cm == nil { + return nil, fmt.Errorf("cacheManager must be non-nil") } - w, err := wm.NewRegistrar( - ctrlName, - regEvents) - if err != nil { - return nil, err - } return &ReconcileConfig{ - reader: mgr.GetCache(), - writer: mgr.GetClient(), - statusClient: mgr.GetClient(), - scheme: mgr.GetScheme(), - opa: filteredOpa, - cs: cs, - watcher: w, - watched: watchSet, - syncMetricsCache: syncMetricsCache, - tracker: tracker, - processExcluder: processExcluder, + reader: mgr.GetCache(), + writer: mgr.GetClient(), + statusClient: mgr.GetClient(), + scheme: mgr.GetScheme(), + cs: cs, + cacheManager: cm, + tracker: tracker, }, nil } @@ -159,7 +100,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { } // Watch for changes to Config - err = c.Watch(&source.Kind{Type: &configv1alpha1.Config{}}, &handler.EnqueueRequestForObject{}) + err = c.Watch(source.Kind(mgr.GetCache(), &configv1alpha1.Config{}), &handler.EnqueueRequestForObject{}) if err != nil { return err } @@ -175,24 +116,18 @@ type ReconcileConfig struct { writer client.Writer statusClient client.StatusClient - scheme *runtime.Scheme - opa syncc.OpaDataClient - syncMetricsCache *syncc.MetricsCache - cs *watch.ControllerSwitch - watcher *watch.Registrar - - watched *watch.Set + scheme *runtime.Scheme + cacheManager *cm.CacheManager + cs *watch.ControllerSwitch - needsReplay *watch.Set - needsWipe bool - tracker *readiness.Tracker - processExcluder *process.Excluder + tracker *readiness.Tracker } // +kubebuilder:rbac:groups=*,resources=*,verbs=get;list;watch // +kubebuilder:rbac:groups=policy,resources=podsecuritypolicies,resourceNames=gatekeeper-admin,verbs=use // +kubebuilder:rbac:groups=config.gatekeeper.sh,resources=configs,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=config.gatekeeper.sh,resources=configs/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch; // Reconcile reads that state of the cluster for a Config object and makes changes based on the state read // and what is in the Config.Spec @@ -236,15 +171,15 @@ func (r *ReconcileConfig) Reconcile(ctx context.Context, request reconcile.Reque } } - newSyncOnly := watch.NewSet() newExcluder := process.New() var statsEnabled bool // If the config is being deleted the user is saying they don't want to // sync anything + gvksToSync := []schema.GroupVersionKind{} if exists && instance.GetDeletionTimestamp().IsZero() { for _, entry := range instance.Spec.Sync.SyncOnly { gvk := schema.GroupVersionKind{Group: entry.Group, Version: entry.Version, Kind: entry.Kind} - newSyncOnly.Add(gvk) + gvksToSync = append(gvksToSync, gvk) } newExcluder.Add(instance.Spec.Match) @@ -260,146 +195,15 @@ func (r *ReconcileConfig) Reconcile(ctx context.Context, request reconcile.Reque r.tracker.DisableStats() } - // Remove expectations for resources we no longer watch. - diff := r.watched.Difference(newSyncOnly) - r.removeStaleExpectations(diff) - - // If the watch set has not changed, we're done here. - if r.watched.Equals(newSyncOnly) && r.processExcluder.Equals(newExcluder) { - // ...unless we have pending wipe / replay operations from a previous reconcile. - if !(r.needsWipe || r.needsReplay != nil) { - return reconcile.Result{}, nil - } - - // If we reach here, the watch set hasn't changed since last reconcile, but we - // have unfinished wipe/replay business from the last change. - } else { - // The watch set _has_ changed, so recalculate the replay set. - r.needsReplay = nil - r.needsWipe = true - } - - // --- Start watching the new set --- - - // This must happen first - signals to the opa client in the sync controller - // to drop events from no-longer-watched resources that may be in its queue. - if r.needsReplay == nil { - r.needsReplay = r.watched.Intersection(newSyncOnly) - } - - // Wipe all data to avoid stale state if needed. Happens once per watch-set-change. - if err := r.wipeCacheIfNeeded(ctx); err != nil { - return reconcile.Result{}, fmt.Errorf("wiping opa data cache: %w", err) - } - - r.watched.Replace(newSyncOnly, func() { - // swapping with the new excluder - r.processExcluder.Replace(newExcluder) - - // *Note the following steps are not transactional with respect to admission control* - - // Important: dynamic watches update must happen *after* updating our watchSet. - // Otherwise, the sync controller will drop events for the newly watched kinds. - // Defer error handling so object re-sync happens even if the watch is hard - // errored due to a missing GVK in the watch set. - err = r.watcher.ReplaceWatch(newSyncOnly.Items()) - }) - if err != nil { - return reconcile.Result{}, err - } - - // Replay cached data for any resources that were previously watched and still in the watch set. - // This is necessary because we wipe their data from Opa above. - // TODO(OREN): Improve later by selectively removing subtrees of data instead of a full wipe. - if err := r.replayData(ctx); err != nil { - return reconcile.Result{}, fmt.Errorf("replaying data: %w", err) + r.cacheManager.ExcludeProcesses(newExcluder) + configSourceKey := aggregator.Key{Source: "config", ID: request.NamespacedName.String()} + if err := r.cacheManager.UpsertSource(ctx, configSourceKey, gvksToSync); err != nil { + return reconcile.Result{Requeue: true}, fmt.Errorf("config-controller: error establishing watches for new syncOny: %w", err) } return reconcile.Result{}, nil } -func (r *ReconcileConfig) wipeCacheIfNeeded(ctx context.Context) error { - if r.needsWipe { - if _, err := r.opa.RemoveData(ctx, target.WipeData()); err != nil { - return err - } - - // reset sync cache before sending the metric - r.syncMetricsCache.ResetCache() - r.syncMetricsCache.ReportSync(&syncc.Reporter{}) - - r.needsWipe = false - } - return nil -} - -// replayData replays all watched and cached data into Opa following a config set change. -// In the future we can rework this to avoid the full opa data cache wipe. -func (r *ReconcileConfig) replayData(ctx context.Context) error { - if r.needsReplay == nil { - return nil - } - for _, gvk := range r.needsReplay.Items() { - u := &unstructured.UnstructuredList{} - u.SetGroupVersionKind(schema.GroupVersionKind{ - Group: gvk.Group, - Version: gvk.Version, - Kind: gvk.Kind + "List", - }) - err := r.reader.List(ctx, u) - if err != nil { - return fmt.Errorf("replaying data for %+v: %w", gvk, err) - } - - defer r.syncMetricsCache.ReportSync(&syncc.Reporter{}) - - for i := range u.Items { - syncKey := r.syncMetricsCache.GetSyncKey(u.Items[i].GetNamespace(), u.Items[i].GetName()) - - isExcludedNamespace, err := r.skipExcludedNamespace(&u.Items[i]) - if err != nil { - log.Error(err, "error while excluding namespaces") - } - - if isExcludedNamespace { - continue - } - - if _, err := r.opa.AddData(ctx, &u.Items[i]); err != nil { - r.syncMetricsCache.AddObject(syncKey, syncc.Tags{ - Kind: u.Items[i].GetKind(), - Status: metrics.ErrorStatus, - }) - return fmt.Errorf("adding data for %+v: %w", gvk, err) - } - - r.syncMetricsCache.AddObject(syncKey, syncc.Tags{ - Kind: u.Items[i].GetKind(), - Status: metrics.ActiveStatus, - }) - } - r.needsReplay.Remove(gvk) - } - r.needsReplay = nil - return nil -} - -// removeStaleExpectations stops tracking data for any resources that are no longer watched. -func (r *ReconcileConfig) removeStaleExpectations(stale *watch.Set) { - for _, gvk := range stale.Items() { - r.tracker.CancelData(gvk) - } -} - -func (r *ReconcileConfig) skipExcludedNamespace(obj *unstructured.Unstructured) (bool, error) { - isNamespaceExcluded, err := r.processExcluder.IsNamespaceExcluded(process.Sync, obj) - if err != nil { - return false, err - } - - return isNamespaceExcluded, err -} - func containsString(s string, items []string) bool { for _, item := range items { if item == s { diff --git a/pkg/controller/config/config_controller_suite_test.go b/pkg/controller/config/config_controller_suite_test.go index 7cc043985cf..3932f427015 100644 --- a/pkg/controller/config/config_controller_suite_test.go +++ b/pkg/controller/config/config_controller_suite_test.go @@ -20,18 +20,15 @@ import ( stdlog "log" "os" "path/filepath" + "sync" "testing" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/open-policy-agent/gatekeeper/v3/apis" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/envtest" "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/open-policy-agent/gatekeeper/apis" ) var cfg *rest.Config @@ -53,7 +50,7 @@ func TestMain(m *testing.M) { stdlog.Fatal(err) } - if err := createGatekeeperNamespace(cfg); err != nil { + if err := testutils.CreateGatekeeperNamespace(cfg); err != nil { stdlog.Printf("creating namespace: %v", err) } @@ -66,31 +63,12 @@ func TestMain(m *testing.M) { // SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and // writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, *sync.Map) { + var requests sync.Map fn := reconcile.Func(func(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { result, err := inner.Reconcile(ctx, req) - requests <- req + requests.Store(req, struct{}{}) return result, err }) - return fn, requests -} - -// Bootstrap the gatekeeper-system namespace for use in tests. -func createGatekeeperNamespace(cfg *rest.Config) error { - c, err := client.New(cfg, client.Options{}) - if err != nil { - return err - } - - // Create gatekeeper namespace - ns := &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "gatekeeper-system", - }, - } - - ctx := context.Background() - _, err = controllerutil.CreateOrUpdate(ctx, c, ns, func() error { return nil }) - return err + return fn, &requests } diff --git a/pkg/controller/config/config_controller_test.go b/pkg/controller/config/config_controller_test.go index c2161eee819..ce6538ac2dc 100644 --- a/pkg/controller/config/config_controller_test.go +++ b/pkg/controller/config/config_controller_test.go @@ -17,34 +17,36 @@ package config import ( "fmt" - gosync "sync" "testing" "time" "github.com/google/go-cmp/cmp" "github.com/onsi/gomega" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" - "github.com/open-policy-agent/gatekeeper/test/testutils" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + syncc "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/sync" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/net/context" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" @@ -56,11 +58,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{ - Name: "config", - Namespace: "gatekeeper-system", -}} - const timeout = time.Second * 20 // setupManager sets up a controller-runtime manager with registered watch manager. @@ -71,10 +68,7 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { metrics.Registry = prometheus.NewRegistry() mgr, err := manager.New(cfg, manager.Options{ MetricsBindAddress: "0", - NewCache: dynamiccache.New, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, + MapperProvider: apiutil.NewDynamicRESTMapper, }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -95,7 +89,11 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { } func TestReconcile(t *testing.T) { + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + g := gomega.NewGomegaWithT(t) + instance := &configv1alpha1.Config{ ObjectMeta: metav1.ObjectMeta{ Name: "config", @@ -110,60 +108,57 @@ func TestReconcile(t *testing.T) { }, Match: []configv1alpha1.MatchEntry{ { - ExcludedNamespaces: []util.Wildcard{"foo"}, + ExcludedNamespaces: []wildcard.Wildcard{"foo"}, Processes: []string{"*"}, }, { - ExcludedNamespaces: []util.Wildcard{"bar"}, + ExcludedNamespaces: []wildcard.Wildcard{"bar"}, Processes: []string{"audit", "webhook"}, }, }, }, } - - // Set up the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. mgr, wm := setupManager(t) c := testclient.NewRetryClient(mgr.GetClient()) - // initialize OPA - driver, err := local.New(local.Tracing(true)) - if err != nil { - t.Fatalf("unable to set up Driver: %v", err) - } - - opaClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) - if err != nil { - t.Fatalf("unable to set up OPA client: %s", err) - } + dataClient := &fakes.FakeCfClient{} cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTracker(mgr, false, false, false) if err != nil { t.Fatal(err) } processExcluder := process.Get() processExcluder.Add(instance.Spec.Match) events := make(chan event.GenericEvent, 1024) - watchSet := watch.NewSet() - rec, _ := newReconciler(mgr, opaClient, wm, cs, tracker, processExcluder, events, watchSet, events) + syncMetricsCache := syncutil.NewMetricsCache() + reg, err := wm.NewRegistrar( + cachemanager.RegistrarName, + events) + require.NoError(t, err) + cacheManager, err := cachemanager.NewCacheManager(&cachemanager.Config{ + CfClient: dataClient, + SyncMetricsCache: syncMetricsCache, + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: c, + }) + require.NoError(t, err) + + // start the cache manager + go func() { + assert.NoError(t, cacheManager.Start(ctx)) + }() + + rec, err := newReconciler(mgr, cacheManager, cs, tracker) + require.NoError(t, err) + // Wrap the Controller Reconcile function so it writes each request to a map when it is finished reconciling. recFn, requests := SetupTestReconcile(rec) - err = add(mgr, recFn) - if err != nil { - t.Fatal(err) - } + require.NoError(t, add(mgr, recFn)) - ctx, cancelFunc := context.WithCancel(context.Background()) testutils.StartManager(ctx, t, mgr) - once := gosync.Once{} - testMgrStopped := func() { - once.Do(func() { - cancelFunc() - }) - } - - defer testMgrStopped() // Create the Config object and expect the Reconcile to be created err = c.Create(ctx, instance) @@ -178,10 +173,20 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } }() - g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() bool { + expectedReq := reconcile.Request{NamespacedName: types.NamespacedName{ + Name: "config", + Namespace: "gatekeeper-system", + }} + _, ok := requests.Load(expectedReq) + return ok + }).WithTimeout(timeout).Should(gomega.BeTrue()) + + g.Eventually(func() int { + return len(wm.GetManagedGVK()) + }).WithTimeout(timeout).ShouldNot(gomega.Equal(0)) gvks := wm.GetManagedGVK() - g.Eventually(len(gvks), timeout).ShouldNot(gomega.Equal(0)) wantGVKs := []schema.GroupVersionKind{ {Group: "", Version: "v1", Kind: "Namespace"}, @@ -257,7 +262,28 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } - testMgrStopped() + fooNs := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + } + require.NoError(t, c.Create(ctx, fooNs)) + fooPod.Object["spec"] = map[string]interface{}{ + "containers": []map[string]interface{}{ + { + "name": "foo-container", + "image": "foo-image", + }, + }, + } + + // directly call cacheManager to avoid any race condition + // between adding the pod and the sync_controller calling AddObject + require.NoError(t, cacheManager.AddObject(ctx, fooPod)) + + // fooPod should be namespace excluded, hence not added to the cache + require.False(t, dataClient.Contains(map[fakes.CfDataKey]interface{}{{Gvk: fooPod.GroupVersionKind(), Key: "default"}: struct{}{}})) + cs.Stop() } @@ -287,7 +313,10 @@ func TestConfig_DeleteSyncResources(t *testing.T) { }, }, } - ctx := context.Background() + + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + err := c.Create(ctx, instance) if err != nil { t.Fatal(err) @@ -321,7 +350,7 @@ func TestConfig_DeleteSyncResources(t *testing.T) { } // set up tracker - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTracker(mgr, false, false, false) if err != nil { t.Fatal(err) } @@ -330,20 +359,12 @@ func TestConfig_DeleteSyncResources(t *testing.T) { events := make(chan event.GenericEvent, 1024) // set up controller and add it to the manager - err = setupController(mgr, wm, tracker, events) - if err != nil { - t.Fatal(err) - } + _, err = setupController(ctx, mgr, wm, tracker, events, c, false) + require.NoError(t, err, "failed to set up controller") // start manager that will start tracker and controller - ctx, cancelFunc := context.WithCancel(context.Background()) testutils.StartManager(ctx, t, mgr) - once := gosync.Once{} - defer func() { - once.Do(func() { - cancelFunc() - }) - }() + gvk := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} // get the object tracker for the synconly pod resource @@ -380,35 +401,77 @@ func TestConfig_DeleteSyncResources(t *testing.T) { }, timeout).Should(gomega.BeTrue()) } -func setupController(mgr manager.Manager, wm *watch.Manager, tracker *readiness.Tracker, events <-chan event.GenericEvent) error { - // initialize OPA - driver, err := local.New(local.Tracing(true)) - if err != nil { - return fmt.Errorf("unable to set up Driver: %v", err) - } +func setupController(ctx context.Context, mgr manager.Manager, wm *watch.Manager, tracker *readiness.Tracker, events chan event.GenericEvent, reader client.Reader, useFakeClient bool) (cachemanager.CFDataClient, error) { + // initialize constraint framework data client + var client cachemanager.CFDataClient + if useFakeClient { + client = &fakes.FakeCfClient{} + } else { + driver, err := rego.New(rego.Tracing(true)) + if err != nil { + return nil, fmt.Errorf("unable to set up Driver: %w", err) + } - opaClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) - if err != nil { - return fmt.Errorf("unable to set up OPA backend client: %w", err) + client, err = constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + if err != nil { + return nil, fmt.Errorf("unable to set up constraint framework data client: %w", err) + } } // ControllerSwitch will be used to disable controllers during our teardown process, // avoiding conflicts in finalizer cleanup. cs := watch.NewSwitch() - processExcluder := process.Get() + syncMetricsCache := syncutil.NewMetricsCache() + reg, err := wm.NewRegistrar( + cachemanager.RegistrarName, + events) + if err != nil { + return nil, fmt.Errorf("cannot create registrar: %w", err) + } + cacheManager, err := cachemanager.NewCacheManager(&cachemanager.Config{ + CfClient: client, + SyncMetricsCache: syncMetricsCache, + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: reader, + }) + if err != nil { + return nil, fmt.Errorf("error creating cache manager: %w", err) + } + go func() { + _ = cacheManager.Start(ctx) + }() - watchSet := watch.NewSet() - rec, _ := newReconciler(mgr, opaClient, wm, cs, tracker, processExcluder, events, watchSet, nil) + rec, err := newReconciler(mgr, cacheManager, cs, tracker) + if err != nil { + return nil, fmt.Errorf("creating reconciler: %w", err) + } err = add(mgr, rec) if err != nil { - return fmt.Errorf("adding reconciler to manager: %w", err) + return nil, fmt.Errorf("adding reconciler to manager: %w", err) } - return nil + + syncAdder := syncc.Adder{ + Events: events, + CacheManager: cacheManager, + } + err = syncAdder.Add(mgr) + if err != nil { + return nil, fmt.Errorf("registering sync controller: %w", err) + } + return client, nil } -// Verify the Opa cache is populated based on the config resource. +// Verify the constraint framework cache is populated based on the config resource. func TestConfig_CacheContents(t *testing.T) { + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + + // Setup the Manager and Controller. + mgr, wm := setupManager(t) + c := testclient.NewRetryClient(mgr.GetClient()) g := gomega.NewGomegaWithT(t) nsGVK := schema.GroupVersionKind{ Group: "", @@ -420,157 +483,96 @@ func TestConfig_CacheContents(t *testing.T) { Version: "v1", Kind: "ConfigMap", } - instance := configFor([]schema.GroupVersionKind{ - nsGVK, - configMapGVK, + // Create a configMap to test for + cm := unstructuredFor(configMapGVK, "config-test-1") + cm.SetNamespace("default") + require.NoError(t, c.Create(ctx, cm), "creating configMap config-test-1") + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm), "deleting configMap config-test-1") }) + cmKey, err := fakes.KeyFor(cm) + require.NoError(t, err) - // Setup the Manager and Controller. - mgr, wm := setupManager(t) - c := testclient.NewRetryClient(mgr.GetClient()) + cm2 := unstructuredFor(configMapGVK, "config-test-2") + cm2.SetNamespace("kube-system") + require.NoError(t, c.Create(ctx, cm2), "creating configMap config-test-2") + t.Cleanup(func() { + assert.NoError(t, deleteResource(ctx, c, cm2), "deleting configMap config-test-2") + }) + cm2Key, err := fakes.KeyFor(cm2) + require.NoError(t, err) - opaClient := &fakeOpa{} - cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, false) - if err != nil { - t.Fatal(err) - } - processExcluder := process.Get() - processExcluder.Add(instance.Spec.Match) + tracker, err := readiness.SetupTracker(mgr, false, false, false) + require.NoError(t, err) events := make(chan event.GenericEvent, 1024) - watchSet := watch.NewSet() - rec, _ := newReconciler(mgr, opaClient, wm, cs, tracker, processExcluder, events, watchSet, events) - err = add(mgr, rec) - if err != nil { - t.Fatal(err) - } + dataClient, err := setupController(ctx, mgr, wm, tracker, events, c, true) + require.NoError(t, err, "failed to set up controller") - ctx, cancelFunc := context.WithCancel(context.Background()) - testutils.StartManager(ctx, t, mgr) - once := gosync.Once{} - testMgrStopped := func() { - once.Do(func() { - cancelFunc() - }) - } + fakeClient, ok := dataClient.(*fakes.FakeCfClient) + require.True(t, ok) - defer testMgrStopped() + testutils.StartManager(ctx, t, mgr) // Create the Config object and expect the Reconcile to be created - ctx = context.Background() - - instance = configFor([]schema.GroupVersionKind{nsGVK, configMapGVK}) + config := configFor([]schema.GroupVersionKind{nsGVK, configMapGVK}) + require.NoError(t, c.Create(ctx, config), "creating Config config") - // Since we're reusing instance between tests, we must wait for it to be fully - // deleted. We also can't reuse the same instance without introducing - // flakiness as client.Client methods modify their input. - g.Eventually(ensureDeleted(ctx, c, instance), timeout). - ShouldNot(gomega.HaveOccurred()) - g.Eventually(ensureCreated(ctx, c, instance), timeout). - ShouldNot(gomega.HaveOccurred()) - - t.Cleanup(func() { - err = c.Delete(ctx, instance) - if !apierrors.IsNotFound(err) { - t.Errorf("got Delete(instance) error %v, want IsNotFound", err) - } - }) - - // Create a configMap to test for - cm := unstructuredFor(configMapGVK, "config-test-1") - cm.SetNamespace("default") - err = c.Create(ctx, cm) - if err != nil { - t.Fatalf("creating configMap config-test-1: %v", err) - } - - cm2 := unstructuredFor(configMapGVK, "config-test-2") - cm2.SetNamespace("kube-system") - err = c.Create(ctx, cm2) - if err != nil { - t.Fatalf("creating configMap config-test-2: %v", err) - } - - defer func() { - err = c.Delete(ctx, cm) - if err != nil { - t.Fatal(err) - } - err = c.Delete(ctx, cm2) - if err != nil { - t.Fatal(err) - } - }() - - expected := map[opaKey]interface{}{ - {gvk: nsGVK, key: "default"}: nil, - {gvk: configMapGVK, key: "default/config-test-1"}: nil, - // kube-system namespace is being excluded, it should not be in opa cache + expected := map[fakes.CfDataKey]interface{}{ + {Gvk: nsGVK, Key: "default"}: nil, + cmKey: nil, + // kube-system namespace is being excluded, it should not be in the cache } g.Eventually(func() bool { - return opaClient.Contains(expected) - }, 10*time.Second).Should(gomega.BeTrue(), "checking initial opa cache contents") - - // Sanity - if !opaClient.HasGVK(nsGVK) { - t.Fatal("want opaClient.HasGVK(nsGVK) to be true but got false") - } + return fakeClient.Contains(expected) + }, 10*time.Second).Should(gomega.BeTrue(), "checking initial cache contents") + require.True(t, fakeClient.HasGVK(nsGVK), "want fakeClient.HasGVK(nsGVK) to be true but got false") // Reconfigure to drop the namespace watches - instance = configFor([]schema.GroupVersionKind{configMapGVK}) - forUpdate := instance.DeepCopy() - _, err = controllerutil.CreateOrUpdate(ctx, c, forUpdate, func() error { - forUpdate.Spec = instance.Spec - return nil - }) - if err != nil { - t.Fatalf("updating Config resource: %v", err) - } + config = configFor([]schema.GroupVersionKind{configMapGVK}) + configUpdate := config.DeepCopy() + + require.NoError(t, c.Get(ctx, client.ObjectKeyFromObject(configUpdate), configUpdate)) + configUpdate.Spec = config.Spec + require.NoError(t, c.Update(ctx, configUpdate), "updating Config config") // Expect namespaces to go away from cache g.Eventually(func() bool { - return opaClient.HasGVK(nsGVK) + return fakeClient.HasGVK(nsGVK) }, 10*time.Second).Should(gomega.BeFalse()) // Expect our configMap to return at some point // TODO: In the future it will remain instead of having to repopulate. - expected = map[opaKey]interface{}{ - { - gvk: configMapGVK, - key: "default/config-test-1", - }: nil, + expected = map[fakes.CfDataKey]interface{}{ + cmKey: nil, } g.Eventually(func() bool { - return opaClient.Contains(expected) + return fakeClient.Contains(expected) }, 10*time.Second).Should(gomega.BeTrue(), "waiting for ConfigMap to repopulate in cache") - expected = map[opaKey]interface{}{ - { - gvk: configMapGVK, - key: "kube-system/config-test-2", - }: nil, + expected = map[fakes.CfDataKey]interface{}{ + cm2Key: nil, } g.Eventually(func() bool { - return !opaClient.Contains(expected) - }, 10*time.Second).Should(gomega.BeTrue(), "kube-system namespace is excluded. kube-system/config-test-2 should not be in opa cache") + return !fakeClient.Contains(expected) + }, 10*time.Second).Should(gomega.BeTrue(), "kube-system namespace is excluded. kube-system/config-test-2 should not be in the cache") - // Delete the config resource - expect opa to empty out. - if opaClient.Len() == 0 { + // Delete the config resource - expect cache to empty out. + if fakeClient.Len() == 0 { t.Fatal("sanity") } - err = c.Delete(ctx, instance) - if err != nil { - t.Fatalf("deleting Config resource: %v", err) - } + require.NoError(t, c.Delete(ctx, config), "deleting Config resource") // The cache will be cleared out. g.Eventually(func() int { - return opaClient.Len() + return fakeClient.Len() }, 10*time.Second).Should(gomega.BeZero(), "waiting for cache to empty") } func TestConfig_Retries(t *testing.T) { + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + g := gomega.NewGomegaWithT(t) nsGVK := schema.GroupVersionKind{ Group: "", @@ -582,17 +584,15 @@ func TestConfig_Retries(t *testing.T) { Version: "v1", Kind: "ConfigMap", } - instance := configFor([]schema.GroupVersionKind{ - configMapGVK, - }) + instance := configFor([]schema.GroupVersionKind{nsGVK, configMapGVK}) // Setup the Manager and Controller. mgr, wm := setupManager(t) c := testclient.NewRetryClient(mgr.GetClient()) - opaClient := &fakeOpa{} + dataClient := &fakes.FakeCfClient{} cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTracker(mgr, false, false, false) if err != nil { t.Fatal(err) } @@ -600,44 +600,52 @@ func TestConfig_Retries(t *testing.T) { processExcluder.Add(instance.Spec.Match) events := make(chan event.GenericEvent, 1024) - watchSet := watch.NewSet() - rec, _ := newReconciler(mgr, opaClient, wm, cs, tracker, processExcluder, events, watchSet, events) + syncMetricsCache := syncutil.NewMetricsCache() + reg, err := wm.NewRegistrar( + cachemanager.RegistrarName, + events) + require.NoError(t, err) + cacheManager, err := cachemanager.NewCacheManager(&cachemanager.Config{ + CfClient: dataClient, + SyncMetricsCache: syncMetricsCache, + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: c, + }) + require.NoError(t, err) + go func() { + assert.NoError(t, cacheManager.Start(ctx)) + }() + + rec, _ := newReconciler(mgr, cacheManager, cs, tracker) err = add(mgr, rec) if err != nil { t.Fatal(err) } + syncAdder := syncc.Adder{ + Events: events, + CacheManager: cacheManager, + } + require.NoError(t, syncAdder.Add(mgr), "registering sync controller") - // Use our special hookReader to inject controlled failures - failPlease := make(chan string, 1) - rec.reader = hookReader{ + // Use our special reader interceptor to inject controlled failures + fi := fakes.NewFailureInjector() + rec.reader = fakes.SpyReader{ Reader: mgr.GetCache(), ListFunc: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { - // Return an error the first go-around. - var failKind string - select { - case failKind = <-failPlease: - default: - } - if failKind != "" && list.GetObjectKind().GroupVersionKind().Kind == failKind { + // return as many syntenthic failures as there are registered for this kind + if fi.CheckFailures(list.GetObjectKind().GroupVersionKind().Kind) { return fmt.Errorf("synthetic failure") } + return mgr.GetCache().List(ctx, list, opts...) }, } - ctx, cancelFunc := context.WithCancel(context.Background()) testutils.StartManager(ctx, t, mgr) - once := gosync.Once{} - testMgrStopped := func() { - once.Do(func() { - cancelFunc() - }) - } - - defer testMgrStopped() // Create the Config object and expect the Reconcile to be created - ctx = context.Background() g.Eventually(func() error { return c.Create(ctx, instance.DeepCopy()) }, timeout).Should(gomega.BeNil()) @@ -664,28 +672,20 @@ func TestConfig_Retries(t *testing.T) { t.Error(err) } }() + cmKey, err := fakes.KeyFor(cm) + require.NoError(t, err) - expected := map[opaKey]interface{}{ - {gvk: configMapGVK, key: "default/config-test-1"}: nil, + expected := map[fakes.CfDataKey]interface{}{ + cmKey: nil, } g.Eventually(func() bool { - return opaClient.Contains(expected) - }, 10*time.Second).Should(gomega.BeTrue(), "checking initial opa cache contents") + return dataClient.Contains(expected) + }, 10*time.Second).Should(gomega.BeTrue(), "checking initial cache contents") - // Wipe the opa cache, we want to see it repopulate despite transient replay errors below. - _, err = opaClient.RemoveData(ctx, target.WipeData()) - if err != nil { - t.Fatalf("wiping opa cache: %v", err) - } - if opaClient.Contains(expected) { - t.Fatal("wipe failed") - } + fi.SetFailures("ConfigMapList", 2) - // Make List fail once for ConfigMaps as the replay occurs following the reconfig below. - failPlease <- "ConfigMapList" - - // Reconfigure to add a namespace watch. - instance = configFor([]schema.GroupVersionKind{nsGVK, configMapGVK}) + // Reconfigure to force an internal replay. + instance = configFor([]schema.GroupVersionKind{configMapGVK}) forUpdate := instance.DeepCopy() _, err = controllerutil.CreateOrUpdate(ctx, c, forUpdate, func() error { forUpdate.Spec = instance.Spec @@ -697,8 +697,8 @@ func TestConfig_Retries(t *testing.T) { // Despite the transient error, we expect the cache to eventually be repopulated. g.Eventually(func() bool { - return opaClient.Contains(expected) - }, 10*time.Second).Should(gomega.BeTrue(), "checking final opa cache contents") + return dataClient.Contains(expected) + }, 10*time.Second).Should(gomega.BeTrue(), "checking final cache contents") } // configFor returns a config resource that watches the requested set of resources. @@ -725,7 +725,7 @@ func configFor(kinds []schema.GroupVersionKind) *configv1alpha1.Config { }, Match: []configv1alpha1.MatchEntry{ { - ExcludedNamespaces: []util.Wildcard{"kube-system"}, + ExcludedNamespaces: []wildcard.Wildcard{"kube-system"}, Processes: []string{"sync"}, }, }, @@ -746,65 +746,15 @@ type testExpectations interface { IsExpecting(gvk schema.GroupVersionKind, nsName types.NamespacedName) bool } -// ensureDeleted -// -// This package uses the same API server process across multiple test functions. -// The residual state from a previous test function can cause flakes. -// -// To ensure a clean slate, we must verify that any previously applied Config object -// has been fully removed before applying our new object. -func ensureDeleted(ctx context.Context, c client.Client, toDelete client.Object) func() error { - gvk := toDelete.GetObjectKind().GroupVersionKind() - key := client.ObjectKeyFromObject(toDelete) - - return func() error { - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(gvk) - - err := c.Get(ctx, key, u) - if apierrors.IsNotFound(err) { - return nil - } else if err != nil { - return err - } - - if !u.GetDeletionTimestamp().IsZero() { - return fmt.Errorf("waiting for deletion: %v %v", gvk, key) - } - - err = c.Delete(ctx, u) - if err != nil { - return fmt.Errorf("deleting %v %v: %w", gvk, key, err) - } - - return fmt.Errorf("queued %v %v for deletion", gvk, key) +func deleteResource(ctx context.Context, c client.Client, resounce *unstructured.Unstructured) error { + if ctx.Err() != nil { + ctx = context.Background() } -} - -// ensureCreated attempts to create toCreate in Client c as toCreate existed when ensureCreated was called. -func ensureCreated(ctx context.Context, c client.Client, toCreate client.Object) func() error { - gvk := toCreate.GetObjectKind().GroupVersionKind() - key := client.ObjectKeyFromObject(toCreate) - - // As ensureCreated returns a closure, it is possible that the value toCreate will be modified after ensureCreated - // is called but before the closure is called. Creating a copy here ensures the object to be created is consistent - // with the way it existed when ensureCreated was called. - toCreateCopy := toCreate.DeepCopyObject() - - return func() error { - instance, ok := toCreateCopy.(client.Object) - if !ok { - return fmt.Errorf("instance was %T which is not a client.Object", instance) - } - - err := c.Create(ctx, instance) - if apierrors.IsAlreadyExists(err) { - return fmt.Errorf("a copy of %v %v already exists - run ensureDeleted to ensure a fresh copy exists for testing", - gvk, key) - } else if err != nil { - return fmt.Errorf("creating %v %v: %v", gvk, key, err) - } - + err := c.Delete(ctx, resounce) + if apierrors.IsNotFound(err) { + // resource does not exist, this is good return nil } + + return err } diff --git a/pkg/controller/config/fakes_test.go b/pkg/controller/config/fakes_test.go deleted file mode 100644 index d1bda58deb3..00000000000 --- a/pkg/controller/config/fakes_test.go +++ /dev/null @@ -1,135 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "context" - "fmt" - gosync "sync" - - constraintTypes "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type opaKey struct { - gvk schema.GroupVersionKind - key string -} - -// fakeOpa is an OpaDataClient for testing. -type fakeOpa struct { - mu gosync.Mutex - data map[opaKey]interface{} -} - -// keyFor returns an opaKey for the provided resource. -// Returns error if the resource is not a runtime.Object w/ metadata. -func (f *fakeOpa) keyFor(obj interface{}) (opaKey, error) { - o, ok := obj.(client.Object) - if !ok { - return opaKey{}, fmt.Errorf("expected runtime.Object, got: %T", obj) - } - gvk := o.GetObjectKind().GroupVersionKind() - ns := o.GetNamespace() - if ns == "" { - return opaKey{gvk: gvk, key: o.GetName()}, nil - } - - return opaKey{gvk: gvk, key: fmt.Sprintf("%s/%s", ns, o.GetName())}, nil -} - -func (f *fakeOpa) AddData(ctx context.Context, data interface{}) (*constraintTypes.Responses, error) { - f.mu.Lock() - defer f.mu.Unlock() - - key, err := f.keyFor(data) - if err != nil { - return nil, err - } - - if f.data == nil { - f.data = make(map[opaKey]interface{}) - } - - f.data[key] = data - return &constraintTypes.Responses{}, nil -} - -func (f *fakeOpa) RemoveData(ctx context.Context, data interface{}) (*constraintTypes.Responses, error) { - f.mu.Lock() - defer f.mu.Unlock() - - if target.IsWipeData(data) { - f.data = make(map[opaKey]interface{}) - return &constraintTypes.Responses{}, nil - } - - key, err := f.keyFor(data) - if err != nil { - return nil, err - } - - delete(f.data, key) - return &constraintTypes.Responses{}, nil -} - -// Contains returns true if all expected resources are in the cache. -func (f *fakeOpa) Contains(expected map[opaKey]interface{}) bool { - f.mu.Lock() - defer f.mu.Unlock() - - for k := range expected { - if _, ok := f.data[k]; !ok { - return false - } - } - return true -} - -// HasGVK returns true if the cache has any data of the requested kind. -func (f *fakeOpa) HasGVK(gvk schema.GroupVersionKind) bool { - f.mu.Lock() - defer f.mu.Unlock() - - for k := range f.data { - if k.gvk == gvk { - return true - } - } - return false -} - -// Len returns the number of items in the cache. -func (f *fakeOpa) Len() int { - f.mu.Lock() - defer f.mu.Unlock() - return len(f.data) -} - -// hookReader is a client.Reader with overrideable methods. -type hookReader struct { - client.Reader - ListFunc func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error -} - -func (r hookReader) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { - if r.ListFunc != nil { - return r.ListFunc(ctx, list, opts...) - } - return r.Reader.List(ctx, list, opts...) -} diff --git a/pkg/controller/config/process/excluder.go b/pkg/controller/config/process/excluder.go index c5ee340e82d..60e3f3c0cd2 100644 --- a/pkg/controller/config/process/excluder.go +++ b/pkg/controller/config/process/excluder.go @@ -4,8 +4,8 @@ import ( "reflect" "sync" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/util" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -23,7 +23,7 @@ const ( type Excluder struct { mux sync.RWMutex - excludedNamespaces map[Process]map[util.Wildcard]bool + excludedNamespaces map[Process]map[wildcard.Wildcard]bool } var allProcesses = []Process{ @@ -34,7 +34,7 @@ var allProcesses = []Process{ } var processExcluder = &Excluder{ - excludedNamespaces: make(map[Process]map[util.Wildcard]bool), + excludedNamespaces: make(map[Process]map[wildcard.Wildcard]bool), } func Get() *Excluder { @@ -43,7 +43,7 @@ func Get() *Excluder { func New() *Excluder { return &Excluder{ - excludedNamespaces: make(map[Process]map[util.Wildcard]bool), + excludedNamespaces: make(map[Process]map[wildcard.Wildcard]bool), } } @@ -58,13 +58,13 @@ func (s *Excluder) Add(entry []configv1alpha1.MatchEntry) { if Process(op) == Star { for _, o := range allProcesses { if s.excludedNamespaces[o] == nil { - s.excludedNamespaces[o] = make(map[util.Wildcard]bool) + s.excludedNamespaces[o] = make(map[wildcard.Wildcard]bool) } s.excludedNamespaces[o][ns] = true } } else { if s.excludedNamespaces[Process(op)] == nil { - s.excludedNamespaces[Process(op)] = make(map[util.Wildcard]bool) + s.excludedNamespaces[Process(op)] = make(map[wildcard.Wildcard]bool) } s.excludedNamespaces[Process(op)][ns] = true } @@ -96,7 +96,7 @@ func (s *Excluder) IsNamespaceExcluded(process Process, obj client.Object) (bool return exactOrWildcardMatch(s.excludedNamespaces[process], obj.GetNamespace()), nil } -func exactOrWildcardMatch(boolMap map[util.Wildcard]bool, ns string) bool { +func exactOrWildcardMatch(boolMap map[wildcard.Wildcard]bool, ns string) bool { for k := range boolMap { if k.Matches(ns) { return true diff --git a/pkg/controller/config/process/excluder_test.go b/pkg/controller/config/process/excluder_test.go index 40015179ebe..b2fbbf68eac 100644 --- a/pkg/controller/config/process/excluder_test.go +++ b/pkg/controller/config/process/excluder_test.go @@ -3,19 +3,19 @@ package process import ( "testing" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" ) func TestExactOrWildcardMatch(t *testing.T) { tcs := []struct { name string - nsMap map[util.Wildcard]bool + nsMap map[wildcard.Wildcard]bool ns string excluded bool }{ { name: "exact text match", - nsMap: map[util.Wildcard]bool{ + nsMap: map[wildcard.Wildcard]bool{ "kube-system": true, "foobar": true, }, @@ -24,7 +24,7 @@ func TestExactOrWildcardMatch(t *testing.T) { }, { name: "wildcard prefix match", - nsMap: map[util.Wildcard]bool{ + nsMap: map[wildcard.Wildcard]bool{ "kube-*": true, "foobar": true, }, @@ -33,7 +33,7 @@ func TestExactOrWildcardMatch(t *testing.T) { }, { name: "wildcard suffix match", - nsMap: map[util.Wildcard]bool{ + nsMap: map[wildcard.Wildcard]bool{ "*-system": true, "foobar": true, }, @@ -42,7 +42,7 @@ func TestExactOrWildcardMatch(t *testing.T) { }, { name: "lack of asterisk prevents globbing", - nsMap: map[util.Wildcard]bool{ + nsMap: map[wildcard.Wildcard]bool{ "kube-": true, }, ns: "kube-system", diff --git a/pkg/controller/constraint/constraint_controller.go b/pkg/controller/constraint/constraint_controller.go index 706005c04ac..95443753d4d 100644 --- a/pkg/controller/constraint/constraint_controller.go +++ b/pkg/controller/constraint/constraint_controller.go @@ -24,17 +24,15 @@ import ( "github.com/go-logr/logr" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" - constraintstatusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/controller/constraintstatus" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + constraintstatusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraintstatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -59,7 +57,7 @@ const ( ) type Adder struct { - Opa *constraintclient.Client + CFClient *constraintclient.Client ConstraintsCache *ConstraintsCache WatchManager *watch.Manager ControllerSwitch *watch.ControllerSwitch @@ -74,8 +72,8 @@ type Adder struct { IfWatching func(schema.GroupVersionKind, func() error) (bool, error) } -func (a *Adder) InjectOpa(o *constraintclient.Client) { - a.Opa = o +func (a *Adder) InjectCFClient(c *constraintclient.Client) { + a.CFClient = c } func (a *Adder) InjectWatchManager(w *watch.Manager) { @@ -90,10 +88,6 @@ func (a *Adder) InjectTracker(t *readiness.Tracker) { a.Tracker = t } -func (a *Adder) InjectMutationSystem(mutationSystem *mutation.System) {} - -func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) {} - // Add creates a new Constraint Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func (a *Adder) Add(mgr manager.Manager) error { @@ -106,7 +100,7 @@ func (a *Adder) Add(mgr manager.Manager) error { return err } - r := newReconciler(mgr, a.Opa, a.ControllerSwitch, reporter, a.ConstraintsCache, a.Tracker) + r := newReconciler(mgr, a.CFClient, a.ControllerSwitch, reporter, a.ConstraintsCache, a.Tracker) if a.GetPod != nil { r.getPod = a.GetPod } @@ -129,7 +123,7 @@ type tags struct { // newReconciler returns a new reconcile.Reconciler. func newReconciler( mgr manager.Manager, - opa *constraintclient.Client, + cfClient *constraintclient.Client, cs *watch.ControllerSwitch, reporter StatsReporter, constraintsCache *ConstraintsCache, @@ -143,7 +137,7 @@ func newReconciler( cs: cs, scheme: mgr.GetScheme(), - opa: opa, + cfClient: cfClient, log: log, reporter: reporter, constraintsCache: constraintsCache, @@ -177,7 +171,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler, events <-chan event.Generi // Watch for changes to ConstraintStatus err = c.Watch( - &source.Kind{Type: &constraintstatusv1beta1.ConstraintPodStatus{}}, + source.Kind(mgr.GetCache(), &constraintstatusv1beta1.ConstraintPodStatus{}), handler.EnqueueRequestsFromMapFunc(constraintstatus.PodStatusToConstraintMapper(true, util.EventPackerMapFunc())), ) if err != nil { @@ -196,7 +190,7 @@ type ReconcileConstraint struct { cs *watch.ControllerSwitch scheme *runtime.Scheme - opa *constraintclient.Client + cfClient *constraintclient.Client log logr.Logger reporter StatsReporter constraintsCache *ConstraintsCache @@ -291,7 +285,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R status.Status.ConstraintUID = instance.GetUID() status.Status.ObservedGeneration = instance.GetGeneration() status.Status.Errors = nil - if c, err := r.opa.GetConstraint(instance); err != nil || !constraints.SemanticEqual(instance, c) { + if c, err := r.cfClient.GetConstraint(instance); err != nil || !constraints.SemanticEqual(instance, c) { if err := r.cacheConstraint(ctx, instance); err != nil { r.constraintsCache.addConstraintKey(constraintKey, tags{ enforcementAction: enforcementAction, @@ -320,7 +314,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R reportMetrics = true } else { r.log.Info("handling constraint delete", "instance", instance) - if _, err := r.opa.RemoveConstraint(ctx, instance); err != nil { + if _, err := r.cfClient.RemoveConstraint(ctx, instance); err != nil { if errors.Is(err, constraintclient.ErrMissingConstraint) { return reconcile.Result{}, err } @@ -414,9 +408,9 @@ func (r *ReconcileConstraint) cacheConstraint(ctx context.Context, instance *uns t := r.tracker.For(instance.GroupVersionKind()) obj := instance.DeepCopy() - // Remove the status field since we do not need it for OPA + // Remove the status field since we do not need it unstructured.RemoveNestedField(obj.Object, "status") - _, err := r.opa.AddConstraint(ctx, obj) + _, err := r.cfClient.AddConstraint(ctx, obj) if err != nil { t.TryCancelExpect(obj) return err @@ -424,7 +418,6 @@ func (r *ReconcileConstraint) cacheConstraint(ctx context.Context, instance *uns // Track for readiness t.Observe(instance) - log.Info("[readiness] observed Constraint", "name", instance.GetName()) return nil } diff --git a/pkg/controller/constraint/constraint_controller_test.go b/pkg/controller/constraint/constraint_controller_test.go index 6d81dc6e210..b50e3e7beef 100644 --- a/pkg/controller/constraint/constraint_controller_test.go +++ b/pkg/controller/constraint/constraint_controller_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/davecgh/go-spew/spew" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" ) func TestTotalConstraintsCache(t *testing.T) { diff --git a/pkg/controller/constraint/stats_reporter.go b/pkg/controller/constraint/stats_reporter.go index 37e180a3de6..b5cdd629a85 100644 --- a/pkg/controller/constraint/stats_reporter.go +++ b/pkg/controller/constraint/stats_reporter.go @@ -3,7 +3,7 @@ package constraint import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/controller/constraint/stats_reporter_test.go b/pkg/controller/constraint/stats_reporter_test.go index 8583c43a902..debe186b205 100644 --- a/pkg/controller/constraint/stats_reporter_test.go +++ b/pkg/controller/constraint/stats_reporter_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "go.opencensus.io/stats/view" ) diff --git a/pkg/controller/constraintstatus/constraintstatus_controller.go b/pkg/controller/constraintstatus/constraintstatus_controller.go index 5bfcb664c64..3095cccb95e 100644 --- a/pkg/controller/constraintstatus/constraintstatus_controller.go +++ b/pkg/controller/constraintstatus/constraintstatus_controller.go @@ -23,10 +23,10 @@ import ( "github.com/go-logr/logr" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -44,7 +44,7 @@ import ( var log = logf.Log.WithName("controller").WithValues(logging.Process, "constraint_status_controller") type Adder struct { - Opa *constraintclient.Client + CFClient *constraintclient.Client WatchManager *watch.Manager ControllerSwitch *watch.ControllerSwitch Events <-chan event.GenericEvent @@ -84,7 +84,7 @@ type PackerMap func(obj client.Object) []reconcile.Request // PodStatusToConstraintMapper correlates a ConstraintPodStatus with its corresponding constraint // `selfOnly` tells the mapper to only map statuses corresponding to the current pod. func PodStatusToConstraintMapper(selfOnly bool, packerMap handler.MapFunc) handler.MapFunc { - return func(obj client.Object) []reconcile.Request { + return func(ctx context.Context, obj client.Object) []reconcile.Request { labels := obj.GetLabels() name, ok := labels[v1beta1.ConstraintNameLabel] if !ok { @@ -109,7 +109,7 @@ func PodStatusToConstraintMapper(selfOnly bool, packerMap handler.MapFunc) handl u := &unstructured.Unstructured{} u.SetGroupVersionKind(schema.GroupVersionKind{Group: v1beta1.ConstraintsGroup, Version: "v1beta1", Kind: kind}) u.SetName(name) - return packerMap(u) + return packerMap(ctx, u) } } @@ -123,7 +123,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler, events <-chan event.Generi // Watch for changes to ConstraintStatus err = c.Watch( - &source.Kind{Type: &v1beta1.ConstraintPodStatus{}}, + source.Kind(mgr.GetCache(), &v1beta1.ConstraintPodStatus{}), handler.EnqueueRequestsFromMapFunc(PodStatusToConstraintMapper(false, util.EventPackerMapFunc())), ) if err != nil { diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller.go b/pkg/controller/constrainttemplate/constrainttemplate_controller.go index 00f69467840..a8c23c559c6 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller.go @@ -24,19 +24,16 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/constraint" - "github.com/open-policy-agent/gatekeeper/pkg/controller/constraintstatus" - "github.com/open-policy-agent/gatekeeper/pkg/controller/constrainttemplatestatus" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraint" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraintstatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplatestatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" errorpkg "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -69,7 +66,7 @@ var gvkConstraintTemplate = schema.GroupVersionKind{ } type Adder struct { - Opa *constraintclient.Client + CFClient *constraintclient.Client WatchManager *watch.Manager ControllerSwitch *watch.ControllerSwitch Tracker *readiness.Tracker @@ -84,15 +81,15 @@ func (a *Adder) Add(mgr manager.Manager) error { } // events will be used to receive events from dynamic watches registered events := make(chan event.GenericEvent, 1024) - r, err := newReconciler(mgr, a.Opa, a.WatchManager, a.ControllerSwitch, a.Tracker, events, events, a.GetPod) + r, err := newReconciler(mgr, a.CFClient, a.WatchManager, a.ControllerSwitch, a.Tracker, events, events, a.GetPod) if err != nil { return err } return add(mgr, r) } -func (a *Adder) InjectOpa(o *constraintclient.Client) { - a.Opa = o +func (a *Adder) InjectCFClient(c *constraintclient.Client) { + a.CFClient = c } func (a *Adder) InjectWatchManager(wm *watch.Manager) { @@ -111,17 +108,11 @@ func (a *Adder) InjectGetPod(getPod func(context.Context) (*corev1.Pod, error)) a.GetPod = getPod } -func (a *Adder) InjectMutationSystem(_ *mutation.System) {} - -func (a *Adder) InjectExpansionSystem(_ *expansion.System) {} - -func (a *Adder) InjectProviderCache(_ *externaldata.ProviderCache) {} - // newReconciler returns a new reconcile.Reconciler // cstrEvents is the channel from which constraint controller will receive the events // regEvents is the channel registered by Registrar to put the events in // cstrEvents and regEvents point to same event channel except for testing. -func newReconciler(mgr manager.Manager, opa *constraintclient.Client, wm *watch.Manager, cs *watch.ControllerSwitch, tracker *readiness.Tracker, cstrEvents <-chan event.GenericEvent, regEvents chan<- event.GenericEvent, getPod func(context.Context) (*corev1.Pod, error)) (*ReconcileConstraintTemplate, error) { +func newReconciler(mgr manager.Manager, cfClient *constraintclient.Client, wm *watch.Manager, cs *watch.ControllerSwitch, tracker *readiness.Tracker, cstrEvents <-chan event.GenericEvent, regEvents chan<- event.GenericEvent, getPod func(context.Context) (*corev1.Pod, error)) (*ReconcileConstraintTemplate, error) { // constraintsCache contains total number of constraints and shared mutex constraintsCache := constraint.NewConstraintsCache() @@ -136,7 +127,7 @@ func newReconciler(mgr manager.Manager, opa *constraintclient.Client, wm *watch. // via the registrar below. constraintAdder := constraint.Adder{ - Opa: opa, + CFClient: cfClient, ConstraintsCache: constraintsCache, WatchManager: wm, ControllerSwitch: cs, @@ -155,7 +146,7 @@ func newReconciler(mgr manager.Manager, opa *constraintclient.Client, wm *watch. // via the registrar below. statusEvents := make(chan event.GenericEvent, 1024) csAdder := constraintstatus.Adder{ - Opa: opa, + CFClient: cfClient, WatchManager: wm, ControllerSwitch: cs, Events: statusEvents, @@ -166,7 +157,7 @@ func newReconciler(mgr manager.Manager, opa *constraintclient.Client, wm *watch. } ctsAdder := constrainttemplatestatus.Adder{ - Opa: opa, + CfClient: cfClient, WatchManager: wm, ControllerSwitch: cs, } @@ -179,7 +170,7 @@ func newReconciler(mgr manager.Manager, opa *constraintclient.Client, wm *watch. reconciler := &ReconcileConstraintTemplate{ Client: mgr.GetClient(), scheme: mgr.GetScheme(), - opa: opa, + cfClient: cfClient, watcher: w, statusWatcher: statusW, cs: cs, @@ -203,14 +194,14 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { } // Watch for changes to ConstraintTemplate - err = c.Watch(&source.Kind{Type: &v1beta1.ConstraintTemplate{}}, &handler.EnqueueRequestForObject{}) + err = c.Watch(source.Kind(mgr.GetCache(), &v1beta1.ConstraintTemplate{}), &handler.EnqueueRequestForObject{}) if err != nil { return err } // Watch for changes to ConstraintTemplateStatus err = c.Watch( - &source.Kind{Type: &statusv1beta1.ConstraintTemplatePodStatus{}}, + source.Kind(mgr.GetCache(), &statusv1beta1.ConstraintTemplatePodStatus{}), handler.EnqueueRequestsFromMapFunc(constrainttemplatestatus.PodStatusToConstraintTemplateMapper(true)), ) if err != nil { @@ -219,11 +210,13 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to Constraint CRDs err = c.Watch( - &source.Kind{Type: &apiextensionsv1.CustomResourceDefinition{}}, - &handler.EnqueueRequestForOwner{ - OwnerType: &v1beta1.ConstraintTemplate{}, - IsController: true, - }, + source.Kind(mgr.GetCache(), &apiextensionsv1.CustomResourceDefinition{}), + handler.EnqueueRequestForOwner( + mgr.GetScheme(), + mgr.GetRESTMapper(), + &v1beta1.ConstraintTemplate{}, + handler.OnlyControllerOwner(), + ), ) if err != nil { return err @@ -240,7 +233,7 @@ type ReconcileConstraintTemplate struct { scheme *runtime.Scheme watcher *watch.Registrar statusWatcher *watch.Registrar - opa *constraintclient.Client + cfClient *constraintclient.Client cs *watch.ControllerSwitch metrics *reporter tracker *readiness.Tracker @@ -297,7 +290,7 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec ctRef := &templates.ConstraintTemplate{} ctRef.SetNamespace(request.Namespace) ctRef.SetName(request.Name) - ctUnversioned, err := r.opa.GetTemplate(ctRef) + ctUnversioned, err := r.cfClient.GetTemplate(ctRef) result := reconcile.Result{} if err != nil { logger.Info("missing constraint template in OPA cache, no deletion necessary") @@ -336,7 +329,7 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec return reconcile.Result{}, err } - unversionedProposedCRD, err := r.opa.CreateCRD(ctx, unversionedCT) + unversionedProposedCRD, err := r.cfClient.CreateCRD(ctx, unversionedCT) if err != nil { logger.Error(err, "CRD creation error") r.tracker.TryCancelTemplate(unversionedCT) // Don't track templates that failed compilation @@ -422,10 +415,10 @@ func (r *ReconcileConstraintTemplate) handleUpdate( logger.Info("loading code into OPA") beginCompile := time.Now() - // It's important that opa.AddTemplate() is called first. That way we can + // It's important that cfClient.AddTemplate() is called first. That way we can // rely on a template's existence in OPA to know whether a watch needs // to be removed - if _, err := r.opa.AddTemplate(ctx, unversionedCT); err != nil { + if _, err := r.cfClient.AddTemplate(ctx, unversionedCT); err != nil { if err := r.metrics.reportIngestDuration(ctx, metrics.ErrorStatus, time.Since(beginCompile)); err != nil { logger.Error(err, "failed to report constraint template ingestion duration") } @@ -441,7 +434,6 @@ func (r *ReconcileConstraintTemplate) handleUpdate( // Mark for readiness tracking t := r.tracker.For(gvkConstraintTemplate) t.Observe(unversionedCT) - logger.Info("[readiness] observed ConstraintTemplate", "name", unversionedCT.GetName()) var newCRD *apiextensionsv1.CustomResourceDefinition if currentCRD == nil { @@ -470,7 +462,7 @@ func (r *ReconcileConstraintTemplate) handleUpdate( } // This must go after CRD creation/update as otherwise AddWatch will always fail logger.Info("making sure constraint is in watcher registry") - if err := r.addWatch(makeGvk(ct.Spec.CRD.Spec.Names.Kind)); err != nil { + if err := r.addWatch(ctx, makeGvk(ct.Spec.CRD.Spec.Names.Kind)); err != nil { logger.Error(err, "error adding template to watch registry") return reconcile.Result{}, err } @@ -488,14 +480,14 @@ func (r *ReconcileConstraintTemplate) handleDelete( logger := logger.WithValues("name", ct.GetName()) logger.Info("removing from watcher registry") gvk := makeGvk(ct.Spec.CRD.Spec.Names.Kind) - if err := r.removeWatch(gvk); err != nil { + if err := r.removeWatch(ctx, gvk); err != nil { return reconcile.Result{}, err } r.tracker.CancelTemplate(ct) // removing the template from the OPA cache must go last as we are relying // on that cache to derive the Kind to remove from the watch - if _, err := r.opa.RemoveTemplate(ctx, ct); err != nil { + if _, err := r.cfClient.RemoveTemplate(ctx, ct); err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil @@ -567,18 +559,18 @@ func (r *ReconcileConstraintTemplate) getOrCreatePodStatus(ctx context.Context, return statusObj, nil } -func (r *ReconcileConstraintTemplate) addWatch(kind schema.GroupVersionKind) error { - if err := r.watcher.AddWatch(kind); err != nil { +func (r *ReconcileConstraintTemplate) addWatch(ctx context.Context, kind schema.GroupVersionKind) error { + if err := r.watcher.AddWatch(ctx, kind); err != nil { return err } - return r.statusWatcher.AddWatch(kind) + return r.statusWatcher.AddWatch(ctx, kind) } -func (r *ReconcileConstraintTemplate) removeWatch(kind schema.GroupVersionKind) error { - if err := r.watcher.RemoveWatch(kind); err != nil { +func (r *ReconcileConstraintTemplate) removeWatch(ctx context.Context, kind schema.GroupVersionKind) error { + if err := r.watcher.RemoveWatch(ctx, kind); err != nil { return err } - return r.statusWatcher.RemoveWatch(kind) + return r.statusWatcher.RemoveWatch(ctx, kind) } type action string diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller_suite_test.go b/pkg/controller/constrainttemplate/constrainttemplate_controller_suite_test.go index b61197fd038..d3dfad6b28e 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller_suite_test.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller_suite_test.go @@ -16,64 +16,14 @@ limitations under the License. package constrainttemplate import ( - "context" - "log" - "os" - "path/filepath" "testing" - "github.com/open-policy-agent/gatekeeper/apis" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/envtest" ) var cfg *rest.Config func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"), - filepath.Join("..", "..", "..", "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - } - if err := apis.AddToScheme(scheme.Scheme); err != nil { - log.Fatal(err) - } - - var err error - if cfg, err = t.Start(); err != nil { - log.Fatal(err) - } - log.Print("STARTED") - - code := m.Run() - if err = t.Stop(); err != nil { - log.Printf("error while trying to stop server: %v", err) - } - os.Exit(code) -} - -// Bootstrap the gatekeeper-system namespace for use in tests. -func createGatekeeperNamespace(cfg *rest.Config) error { - c, err := client.New(cfg, client.Options{}) - if err != nil { - return err - } - - // Create gatekeeper namespace - ns := &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "gatekeeper-system", - }, - } - - ctx := context.Background() - _, err = controllerutil.CreateOrUpdate(ctx, c, ns, func() error { return nil }) - return err + testutils.StartControlPlane(m, &cfg, 3) } diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go b/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go index a6724c98f2e..e9abc8dbd76 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go @@ -21,84 +21,36 @@ import ( "fmt" "strings" "testing" - "time" templatesv1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" - "github.com/open-policy-agent/gatekeeper/test/testutils" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" - "github.com/prometheus/client_golang/prometheus" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "golang.org/x/net/context" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/metrics" ) -// constantRetry makes 3,000 attempts at a rate of 100 per second. Since this -// is a test instance and not a "real" cluster, this is fine and there's no need -// to increase the wait time each iteration. -var constantRetry = wait.Backoff{ - Steps: 3000, - Duration: 10 * time.Millisecond, -} - -// setupManager sets up a controller-runtime manager with registered watch manager. -func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { - t.Helper() - - metrics.Registry = prometheus.NewRegistry() - mgr, err := manager.New(cfg, manager.Options{ - MetricsBindAddress: "0", - NewCache: dynamiccache.New, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, - Logger: testutils.NewLogger(t), - }) - if err != nil { - t.Fatalf("setting up controller manager: %s", err) - } - c := mgr.GetCache() - dc, ok := c.(watch.RemovableCache) - if !ok { - t.Fatalf("expected dynamic cache, got: %T", c) - } - wm, err := watch.New(dc) - if err != nil { - t.Fatalf("could not create watch manager: %s", err) - } - if err := mgr.Add(wm); err != nil { - t.Fatalf("could not add watch manager to manager: %s", err) - } - return mgr, wm -} - func makeReconcileConstraintTemplate(suffix string) *v1beta1.ConstraintTemplate { return &v1beta1.ConstraintTemplate{ TypeMeta: metav1.TypeMeta{ @@ -151,31 +103,30 @@ func TestReconcile(t *testing.T) { // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a // channel when it is finished. - mgr, wm := setupManager(t) + mgr, wm := testutils.SetupManager(t, cfg) c := testclient.NewRetryClient(mgr.GetClient()) // creating the gatekeeper-system namespace is necessary because that's where // status resources live by default - err := createGatekeeperNamespace(mgr.GetConfig()) + err := testutils.CreateGatekeeperNamespace(mgr.GetConfig()) if err != nil { t.Fatal(err) } - // initialize OPA - driver, err := local.New(local.Tracing(true)) + driver, err := rego.New(rego.Tracing(true)) if err != nil { t.Fatalf("unable to set up Driver: %v", err) } - opaClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) if err != nil { - t.Fatalf("unable to set up OPA client: %s", err) + t.Fatalf("unable to set up constraint framework client: %s", err) } testutils.Setenv(t, "POD_NAME", "no-pod") cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTracker(mgr, false, false, false) if err != nil { t.Fatal(err) } @@ -187,7 +138,7 @@ func TestReconcile(t *testing.T) { // events will be used to receive events from dynamic watches registered events := make(chan event.GenericEvent, 1024) - rec, err := newReconciler(mgr, opaClient, wm, cs, tracker, events, events, func(context.Context) (*corev1.Pod, error) { return pod, nil }) + rec, err := newReconciler(mgr, cfClient, wm, cs, tracker, events, events, func(context.Context) (*corev1.Pod, error) { return pod, nil }) if err != nil { t.Fatal(err) } @@ -205,11 +156,11 @@ func TestReconcile(t *testing.T) { logger.Info("Running test: CRD Gets Created") constraintTemplate := makeReconcileConstraintTemplate(suffix) - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) - createThenCleanup(ctx, t, c, constraintTemplate) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) clientset := kubernetes.NewForConfigOrDie(cfg) - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { crd := &apiextensionsv1.CustomResourceDefinition{} @@ -239,11 +190,11 @@ func TestReconcile(t *testing.T) { constraintTemplate := makeReconcileConstraintTemplate(suffix) cstr := newDenyAllCstr(suffix) - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, cstr)) - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) - createThenCleanup(ctx, t, c, constraintTemplate) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, cstr)) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) - err = retry.OnError(constantRetry, func(error) bool { + err = retry.OnError(testutils.ConstantRetry, func(error) bool { return true }, func() error { return c.Create(ctx, cstr) @@ -272,7 +223,7 @@ func TestReconcile(t *testing.T) { Name: "FooNamespace", Object: runtime.RawExtension{Object: ns}, } - resp, err := opaClient.Review(ctx, req) + resp, err := cfClient.Review(ctx, req) if err != nil { t.Fatal(err) } @@ -280,7 +231,7 @@ func TestReconcile(t *testing.T) { gotResults := resp.Results() if len(gotResults) != 1 { t.Log(resp.TraceDump()) - t.Log(opaClient.Dump(ctx)) + t.Log(cfClient.Dump(ctx)) t.Fatalf("want 1 result, got %v", gotResults) } }) @@ -293,12 +244,12 @@ func TestReconcile(t *testing.T) { constraintTemplate := makeReconcileConstraintTemplate(suffix) cstr := newDenyAllCstr(suffix) - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, cstr)) - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) - createThenCleanup(ctx, t, c, constraintTemplate) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, cstr)) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) var crd *apiextensionsv1.CustomResourceDefinition - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { crd = &apiextensionsv1.CustomResourceDefinition{} @@ -315,7 +266,7 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { crd := &apiextensionsv1.CustomResourceDefinition{} @@ -339,7 +290,7 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { sList := &statusv1beta1.ConstraintPodStatusList{} @@ -355,7 +306,7 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { return c.Create(ctx, newDenyAllCstr(suffix)) @@ -409,7 +360,7 @@ func TestReconcile(t *testing.T) { // https://github.com/open-policy-agent/gatekeeper/pull/1595#discussion_r722819552 t.Cleanup(testutils.DeleteObject(t, c, instanceInvalidRego)) - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { ct := &v1beta1.ConstraintTemplate{} @@ -466,7 +417,7 @@ func TestReconcile(t *testing.T) { Name: "FooNamespace", Object: runtime.RawExtension{Object: ns}, } - resp, err := opaClient.Review(ctx, req) + resp, err := cfClient.Review(ctx, req) if err != nil { t.Fatal(err) } @@ -474,7 +425,7 @@ func TestReconcile(t *testing.T) { gotResults := resp.Results() if len(resp.Results()) != 0 { t.Log(resp.TraceDump()) - t.Log(opaClient.Dump(ctx)) + t.Log(cfClient.Dump(ctx)) t.Fatalf("did not get 0 results: %v", gotResults) } @@ -484,16 +435,16 @@ func TestReconcile(t *testing.T) { t.Fatal(err) } - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { - resp, err := opaClient.Review(ctx, req) + resp, err := cfClient.Review(ctx, req) if err != nil { return err } if len(resp.Results()) != 0 { - dump, _ := opaClient.Dump(ctx) - return fmt.Errorf("Results not yet zero\nOPA DUMP:\n%s", dump) + dump, _ := cfClient.Dump(ctx) + return fmt.Errorf("Results not yet zero\nDUMP:\n%s", dump) } return nil }) @@ -508,7 +459,7 @@ func TestReconcile_DeleteConstraintResources(t *testing.T) { logger.Info("Running test: Cancel the expectations when constraint gets deleted") // Setup the Manager - mgr, wm := setupManager(t) + mgr, wm := testutils.SetupManager(t, cfg) c := testclient.NewRetryClient(mgr.GetClient()) // start manager that will start tracker and controller @@ -573,26 +524,25 @@ violation[{"msg": "denied!"}] { // creating the gatekeeper-system namespace is necessary because that's where // status resources live by default - err = createGatekeeperNamespace(mgr.GetConfig()) + err = testutils.CreateGatekeeperNamespace(mgr.GetConfig()) if err != nil { t.Fatal(err) } // Set up tracker - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTrackerNoReadyz(mgr, false, false, false) if err != nil { t.Fatal(err) } - // initialize OPA - driver, err := local.New(local.Tracing(true)) + driver, err := rego.New(rego.Tracing(true)) if err != nil { t.Fatalf("unable to set up Driver: %v", err) } - opaClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) if err != nil { - t.Fatalf("unable to set up OPA client: %s", err) + t.Fatalf("unable to set up constraint framework client: %s", err) } testutils.Setenv(t, "POD_NAME", "no-pod") @@ -605,7 +555,7 @@ violation[{"msg": "denied!"}] { // events will be used to receive events from dynamic watches registered events := make(chan event.GenericEvent, 1024) - rec, err := newReconciler(mgr, opaClient, wm, cs, tracker, events, nil, func(context.Context) (*corev1.Pod, error) { return pod, nil }) + rec, err := newReconciler(mgr, cfClient, wm, cs, tracker, events, nil, func(context.Context) (*corev1.Pod, error) { return pod, nil }) if err != nil { t.Fatal(err) } @@ -622,7 +572,7 @@ violation[{"msg": "denied!"}] { t.Fatalf("unexpected tracker, got %T", ot) } // ensure that expectations are set for the constraint gvk - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { gotExpected := tr.IsExpecting(gvk, types.NamespacedName{Name: "denyallconstraint"}) @@ -648,7 +598,7 @@ violation[{"msg": "denied!"}] { } // Check readiness tracker is satisfied post-reconcile - err = retry.OnError(constantRetry, func(err error) bool { + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { satisfied := tracker.For(gvk).Satisfied() @@ -663,7 +613,7 @@ violation[{"msg": "denied!"}] { } func constraintEnforced(ctx context.Context, c client.Client, suffix string) error { - return retry.OnError(constantRetry, func(err error) bool { + return retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { cstr := newDenyAllCstr(suffix) @@ -778,7 +728,7 @@ func applyCRD(ctx context.Context, client client.Client, gvk schema.GroupVersion u := &unstructured.UnstructuredList{} u.SetGroupVersionKind(gvk) - return retry.OnError(constantRetry, func(err error) bool { + return retry.OnError(testutils.ConstantRetry, func(err error) bool { return true }, func() error { if ctx.Err() != nil { @@ -788,99 +738,7 @@ func applyCRD(ctx context.Context, client client.Client, gvk schema.GroupVersion }) } -// deleteObjectAndConfirm returns a callback which deletes obj from the passed -// Client. Does result in mutations to obj. The callback includes a cached copy -// of all information required to delete obj in the callback, so it is safe to -// mutate obj afterwards. Similarly - client.Delete mutates its input, but -// the callback does not call client.Delete on obj. Instead, it creates a -// single-purpose Unstructured for this purpose. Thus, obj is not mutated after -// the callback is run. -func deleteObjectAndConfirm(ctx context.Context, t *testing.T, c client.Client, obj client.Object) func() { - t.Helper() - - // Cache the identifying information from obj. We refer to this cached - // information in the callback, and not obj itself. - gvk := obj.GetObjectKind().GroupVersionKind() - namespace := obj.GetNamespace() - name := obj.GetName() - - if gvk.Empty() { - // We can't send a proper delete request with an Unstructured without - // filling in GVK. The alternative would be to require tests to construct - // a valid Scheme or provide a factory method for the type to delete - this - // is easier. - t.Fatalf("gvk for %v/%v %T is empty", - namespace, name, obj) - } - - return func() { - t.Helper() - - // Construct a single-use Unstructured to send the Delete request. - toDelete := makeUnstructured(gvk, namespace, name) - err := c.Delete(ctx, toDelete) - if apierrors.IsNotFound(err) { - return - } else if err != nil { - t.Fatal(err) - } - - err = retry.OnError(constantRetry, func(err error) bool { - return true - }, func() error { - // Construct a single-use Unstructured to send the Get request. It isn't - // safe to reuse Unstructureds for each retry as Get modifies its input. - toGet := makeUnstructured(gvk, namespace, name) - key := client.ObjectKey{Namespace: namespace, Name: name} - err2 := c.Get(ctx, key, toGet) - if apierrors.IsGone(err2) || apierrors.IsNotFound(err2) { - return nil - } - - // Marshal the currently-gotten object, so it can be printed in test - // failure output. - s, _ := json.MarshalIndent(toGet, "", " ") - return fmt.Errorf("found %v %v:\n%s", gvk, key, string(s)) - }) - - if err != nil { - t.Fatal(err) - } - } -} - // This interface is getting used by tests to check the private objects of objectTracker. type testExpectations interface { IsExpecting(gvk schema.GroupVersionKind, nsName types.NamespacedName) bool } - -// createThenCleanup creates obj in Client, and then registers obj to be deleted -// at the end of the test. The passed obj is safely deepcopied before being -// passed to client.Create, so it is not mutated by this call. -func createThenCleanup(ctx context.Context, t *testing.T, c client.Client, obj client.Object) { - t.Helper() - cpy := obj.DeepCopyObject() - cpyObj, ok := cpy.(client.Object) - if !ok { - t.Fatalf("got obj.DeepCopyObject() type = %T, want %T", cpy, client.Object(nil)) - } - - err := c.Create(ctx, cpyObj) - if err != nil { - t.Fatal(err) - } - - // It is unnecessary to deepcopy obj as deleteObjectAndConfirm does not pass - // obj to any Client calls. - t.Cleanup(deleteObjectAndConfirm(ctx, t, c, obj)) -} - -func makeUnstructured(gvk schema.GroupVersionKind, namespace, name string) *unstructured.Unstructured { - u := &unstructured.Unstructured{ - Object: make(map[string]interface{}), - } - u.SetGroupVersionKind(gvk) - u.SetNamespace(namespace) - u.SetName(name) - return u -} diff --git a/pkg/controller/constrainttemplate/stats_reporter.go b/pkg/controller/constrainttemplate/stats_reporter.go index 20a90d5b285..3d451694ae2 100644 --- a/pkg/controller/constrainttemplate/stats_reporter.go +++ b/pkg/controller/constrainttemplate/stats_reporter.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/controller/constrainttemplate/stats_reporter_test.go b/pkg/controller/constrainttemplate/stats_reporter_test.go index 86e43efe0d3..0f0f9615fce 100644 --- a/pkg/controller/constrainttemplate/stats_reporter_test.go +++ b/pkg/controller/constrainttemplate/stats_reporter_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats/view" ) diff --git a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller.go b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller.go index ab66940d6db..c1d44bf196b 100644 --- a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller.go +++ b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller.go @@ -24,10 +24,10 @@ import ( "github.com/go-logr/logr" constrainttemplatev1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -44,7 +44,7 @@ import ( var log = logf.Log.WithName("controller").WithValues(logging.Process, "constraint_template_status_controller") type Adder struct { - Opa *constraintclient.Client + CfClient *constraintclient.Client WatchManager *watch.Manager ControllerSwitch *watch.ControllerSwitch } @@ -76,7 +76,7 @@ func newReconciler( // PodStatusToConstraintTemplateMapper correlates a ConstraintTemplatePodStatus with its corresponding constraint template // `selfOnly` tells the mapper to only map statuses corresponding to the current pod. func PodStatusToConstraintTemplateMapper(selfOnly bool) handler.MapFunc { - return func(obj client.Object) []reconcile.Request { + return func(ctx context.Context, obj client.Object) []reconcile.Request { labels := obj.GetLabels() name, ok := labels[v1beta1.ConstraintTemplateNameLabel] if !ok { @@ -107,7 +107,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to ConstraintTemplateStatus err = c.Watch( - &source.Kind{Type: &v1beta1.ConstraintTemplatePodStatus{}}, + source.Kind(mgr.GetCache(), &v1beta1.ConstraintTemplatePodStatus{}), handler.EnqueueRequestsFromMapFunc(PodStatusToConstraintTemplateMapper(false)), ) if err != nil { @@ -116,7 +116,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to the provided constraint // Watch for changes to ConstraintTemplate - err = c.Watch(&source.Kind{Type: &constrainttemplatev1beta1.ConstraintTemplate{}}, &handler.EnqueueRequestForObject{}) + err = c.Watch(source.Kind(mgr.GetCache(), &constrainttemplatev1beta1.ConstraintTemplate{}), &handler.EnqueueRequestForObject{}) if err != nil { return err } diff --git a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_suite_test.go b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_suite_test.go index 64ea69a73ef..67772d2cdd1 100644 --- a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_suite_test.go +++ b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_suite_test.go @@ -16,65 +16,14 @@ limitations under the License. package constrainttemplatestatus_test import ( - "context" - stdlog "log" - "os" - "path/filepath" "testing" - "github.com/open-policy-agent/gatekeeper/apis" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/envtest" ) var cfg *rest.Config func TestMain(m *testing.M) { - var err error - - t := &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"), - filepath.Join("..", "..", "..", "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - } - if err := apis.AddToScheme(scheme.Scheme); err != nil { - stdlog.Fatal(err) - } - - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - stdlog.Print("STARTED") - - code := m.Run() - if err = t.Stop(); err != nil { - stdlog.Printf("error while trying to stop server: %v", err) - } - os.Exit(code) -} - -// Bootstrap the gatekeeper-system namespace for use in tests. -func createGatekeeperNamespace(cfg *rest.Config) error { - c, err := client.New(cfg, client.Options{}) - if err != nil { - return err - } - - // Create gatekeeper namespace - ns := &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "gatekeeper-system", - }, - } - - ctx := context.Background() - _, err = controllerutil.CreateOrUpdate(ctx, c, ns, func() error { return nil }) - return err + testutils.StartControlPlane(m, &cfg, 3) } diff --git a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_test.go b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_test.go index cd8944f09b1..58ac3be5d7b 100644 --- a/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_test.go +++ b/pkg/controller/constrainttemplatestatus/constrainttemplatestatus_controller_test.go @@ -9,23 +9,20 @@ import ( "github.com/onsi/gomega" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" - podstatus "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/constrainttemplate" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" - "github.com/open-policy-agent/gatekeeper/test/testutils" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + podstatus "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constrainttemplate" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -44,11 +41,8 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { mgr, err := manager.New(cfg, manager.Options{ MetricsBindAddress: "0", - NewCache: dynamiccache.New, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, - Logger: testutils.NewLogger(t), + MapperProvider: apiutil.NewDynamicRESTMapper, + Logger: testutils.NewLogger(t), }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -108,25 +102,24 @@ violation[{"msg": "denied!"}] { // creating the gatekeeper-system namespace is necessary because that's where // status resources live by default - if err := createGatekeeperNamespace(mgr.GetConfig()); err != nil { + if err := testutils.CreateGatekeeperNamespace(mgr.GetConfig()); err != nil { t.Fatalf("want createGatekeeperNamespace(mgr.GetConfig()) error = nil, got %v", err) } - // initialize OPA - driver, err := local.New(local.Tracing(true)) + driver, err := rego.New(rego.Tracing(true)) if err != nil { t.Fatalf("unable to set up Driver: %v", err) } - opaClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) if err != nil { - t.Fatalf("unable to set up OPA client: %s", err) + t.Fatalf("unable to set up constraint framework client: %s", err) } testutils.Setenv(t, "POD_NAME", "no-pod") cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, false) + tracker, err := readiness.SetupTracker(mgr, false, false, false) if err != nil { t.Fatal(err) } @@ -136,7 +129,7 @@ violation[{"msg": "denied!"}] { ) adder := constrainttemplate.Adder{ - Opa: opaClient, + CFClient: cfClient, WatchManager: wm, ControllerSwitch: cs, Tracker: tracker, diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 002d0625ee1..3076b5fba02 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -18,37 +18,38 @@ package controller import ( "context" "flag" + "fmt" "os" "sync" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + cm "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + syncc "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/sync" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/manager" ) var debugUseFakePod = flag.Bool("debug-use-fake-pod", false, "Use a fake pod name so the Gatekeeper executable can be run outside of Kubernetes") type Injector interface { - InjectOpa(*constraintclient.Client) - InjectWatchManager(*watch.Manager) InjectControllerSwitch(*watch.ControllerSwitch) InjectTracker(tracker *readiness.Tracker) - InjectMutationSystem(mutationSystem *mutation.System) - InjectExpansionSystem(expansionSystem *expansion.System) - InjectProviderCache(providerCache *externaldata.ProviderCache) + Add(mgr manager.Manager) error } @@ -56,12 +57,32 @@ type GetPodInjector interface { InjectGetPod(func(context.Context) (*corev1.Pod, error)) } -type GetProcessExcluderInjector interface { - InjectProcessExcluder(processExcluder *process.Excluder) +type PubsubInjector interface { + InjectPubsubSystem(pubsubSystem *pubsub.System) +} + +type DataClientInjector interface { + InjectCFClient(*constraintclient.Client) +} + +type WatchManagerInjector interface { + InjectWatchManager(*watch.Manager) +} + +type MutationSystemInjector interface { + InjectMutationSystem(mutationSystem *mutation.System) +} + +type ExpansionSystemInjector interface { + InjectExpansionSystem(expansionSystem *expansion.System) +} + +type ProviderCacheInjector interface { + InjectProviderCache(providerCache *externaldata.ProviderCache) } -type WatchSetInjector interface { - InjectWatchSet(watchSet *watch.Set) +type CacheManagerInjector interface { + InjectCacheManager(cm *cm.CacheManager) } // Injectors is a list of adder structs that need injection. We can convert this @@ -73,7 +94,7 @@ var AddToManagerFuncs []func(manager.Manager) error // Dependencies are dependencies that can be injected into controllers. type Dependencies struct { - Opa *constraintclient.Client + CFClient *constraintclient.Client WatchManger *watch.Manager ControllerSwitch *watch.ControllerSwitch Tracker *readiness.Tracker @@ -82,7 +103,9 @@ type Dependencies struct { MutationSystem *mutation.System ExpansionSystem *expansion.System ProviderCache *externaldata.ProviderCache - WatchSet *watch.Set + PubsubSystem *pubsub.System + SyncEventsCh chan event.GenericEvent + CacheMgr *cm.CacheManager } type defaultPodGetter struct { @@ -154,23 +177,52 @@ func AddToManager(m manager.Manager, deps *Dependencies) error { } deps.GetPod = fakePodGetter } + + // Adding the CacheManager as a runnable; + // manager will start CacheManager. + if err := m.Add(deps.CacheMgr); err != nil { + return fmt.Errorf("error adding cache manager as a runnable: %w", err) + } + + syncAdder := syncc.Adder{ + Events: deps.SyncEventsCh, + CacheManager: deps.CacheMgr, + } + // Create subordinate controller - we will feed it events dynamically via watch + if err := syncAdder.Add(m); err != nil { + return fmt.Errorf("registering sync controller: %w", err) + } + for _, a := range Injectors { - a.InjectOpa(deps.Opa) - a.InjectWatchManager(deps.WatchManger) a.InjectControllerSwitch(deps.ControllerSwitch) a.InjectTracker(deps.Tracker) - a.InjectMutationSystem(deps.MutationSystem) - a.InjectExpansionSystem(deps.ExpansionSystem) - a.InjectProviderCache(deps.ProviderCache) + + if a2, ok := a.(DataClientInjector); ok { + a2.InjectCFClient(deps.CFClient) + } + if a2, ok := a.(WatchManagerInjector); ok { + a2.InjectWatchManager(deps.WatchManger) + } + if a2, ok := a.(MutationSystemInjector); ok { + a2.InjectMutationSystem(deps.MutationSystem) + } + if a2, ok := a.(ExpansionSystemInjector); ok { + a2.InjectExpansionSystem(deps.ExpansionSystem) + } + if a2, ok := a.(ProviderCacheInjector); ok { + a2.InjectProviderCache(deps.ProviderCache) + } if a2, ok := a.(GetPodInjector); ok { a2.InjectGetPod(deps.GetPod) } - if a2, ok := a.(GetProcessExcluderInjector); ok { - a2.InjectProcessExcluder(deps.ProcessExcluder) + if a2, ok := a.(PubsubInjector); ok { + a2.InjectPubsubSystem(deps.PubsubSystem) } - if a2, ok := a.(WatchSetInjector); ok { - a2.InjectWatchSet(deps.WatchSet) + if a2, ok := a.(CacheManagerInjector); ok { + // this is used by the config controller to sync + a2.InjectCacheManager(deps.CacheMgr) } + if err := a.Add(m); err != nil { return err } diff --git a/pkg/controller/expansion/expansion_controller.go b/pkg/controller/expansion/expansion_controller.go index 6a1d0cf6aa0..08b73ca2608 100644 --- a/pkg/controller/expansion/expansion_controller.go +++ b/pkg/controller/expansion/expansion_controller.go @@ -2,22 +2,25 @@ package expansion import ( "context" - "flag" - - constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned" - "github.com/open-policy-agent/gatekeeper/apis/expansion/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - "k8s.io/apimachinery/pkg/api/errors" + "fmt" + + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + expansionv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -25,109 +28,250 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" ) -var ( - expansionEnabled = flag.Bool("enable-generator-resource-expansion", false, "(alpha) Enable the expansion of generator resources") +var log = logf.Log.WithName("controller").WithValues("kind", "ExpansionTemplate", logging.Process, "template_expansion_controller") - log = logf.Log.WithName("controller").WithValues("kind", "ExpansionTemplate", logging.Process, "template_expansion_controller") -) +// eventQueueSize is how many events to queue before blocking. +const eventQueueSize = 1024 type Adder struct { WatchManager *watch.Manager ExpansionSystem *expansion.System + Tracker *readiness.Tracker + // GetPod returns an instance of the currently running Gatekeeper pod + GetPod func(context.Context) (*corev1.Pod, error) } func (a *Adder) Add(mgr manager.Manager) error { - if !*expansionEnabled { + if !*expansion.ExpansionEnabled { return nil } - r := newReconciler(mgr, a.ExpansionSystem) + r := newReconciler(mgr, a.ExpansionSystem, a.GetPod, a.Tracker) return add(mgr, r) } -func (a *Adder) InjectOpa(_ *constraintclient.Client) {} - -func (a *Adder) InjectWatchManager(_ *watch.Manager) {} - func (a *Adder) InjectControllerSwitch(_ *watch.ControllerSwitch) {} -func (a *Adder) InjectTracker(_ *readiness.Tracker) {} - -func (a *Adder) InjectMutationSystem(_ *mutation.System) {} +func (a *Adder) InjectTracker(tracker *readiness.Tracker) { + a.Tracker = tracker +} func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) { a.ExpansionSystem = expansionSystem } -func (a *Adder) InjectProviderCache(_ *externaldata.ProviderCache) {} +func (a *Adder) InjectGetPod(getPod func(ctx context.Context) (*corev1.Pod, error)) { + a.GetPod = getPod +} type Reconciler struct { client.Client - system *expansion.System - scheme *runtime.Scheme - registry *etRegistry + system *expansion.System + scheme *runtime.Scheme + registry *etRegistry + statusClient client.StatusClient + tracker *readiness.Tracker + events chan event.GenericEvent + eventSource source.Source + + getPod func(context.Context) (*corev1.Pod, error) } -func newReconciler(mgr manager.Manager, system *expansion.System) *Reconciler { +func newReconciler(mgr manager.Manager, + system *expansion.System, + getPod func(ctx context.Context) (*corev1.Pod, error), + tracker *readiness.Tracker, +) *Reconciler { + ev := make(chan event.GenericEvent, eventQueueSize) return &Reconciler{ - Client: mgr.GetClient(), - system: system, - scheme: mgr.GetScheme(), - registry: newRegistry(), + Client: mgr.GetClient(), + system: system, + scheme: mgr.GetScheme(), + registry: newRegistry(), + statusClient: mgr.GetClient(), + getPod: getPod, + tracker: tracker, + events: ev, + eventSource: &source.Channel{Source: ev, DestBufferSize: 1024}, } } -func add(mgr manager.Manager, r reconcile.Reconciler) error { +func add(mgr manager.Manager, r *Reconciler) error { c, err := controller.New("expansion-template-controller", mgr, controller.Options{Reconciler: r}) if err != nil { return err } + // Watch for enqueued events + if r.eventSource != nil { + err = c.Watch( + r.eventSource, + &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + } + + // Watch for changes to ExpansionTemplates return c.Watch( - &source.Kind{Type: &v1alpha1.ExpansionTemplate{}}, + source.Kind(mgr.GetCache(), &expansionv1beta1.ExpansionTemplate{}), &handler.EnqueueRequestForObject{}) } func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - log.Info("Reconcile", "request", request, "namespace", request.Namespace, "name", request.Name) + defer r.registry.report(ctx) + log.V(logging.DebugLevel).Info("Reconcile", "request", request, "namespace", request.Namespace, "name", request.Name) deleted := false - te := &v1alpha1.ExpansionTemplate{} - err := r.Get(ctx, request.NamespacedName, te) + versionedET := &expansionv1beta1.ExpansionTemplate{} + err := r.Get(ctx, request.NamespacedName, versionedET) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { return reconcile.Result{}, err } deleted = true } - unversionedTE := &unversioned.ExpansionTemplate{} - if err := r.scheme.Convert(te, unversionedTE, nil); err != nil { + et := &unversioned.ExpansionTemplate{} + if err := r.scheme.Convert(versionedET, et, nil); err != nil { return reconcile.Result{}, err } - nsName := types.NamespacedName{ - Namespace: unversionedTE.GetNamespace(), - Name: unversionedTE.GetName(), + oldConflicts := r.system.GetConflicts() + + if !et.GetDeletionTimestamp().IsZero() { + deleted = true } + if deleted { - // unversionedTE will be an empty struct. We set the metadata name, which is + // et will be an empty struct. We set the metadata name, which is // used as a key to delete it from the expansion system - unversionedTE.ObjectMeta.Name = request.Name - if err := r.system.RemoveTemplate(unversionedTE); err != nil { + et.Name = request.Name + if err := r.system.RemoveTemplate(et); err != nil { + r.getTracker().TryCancelExpect(versionedET) return reconcile.Result{}, err } - log.Info("removed template expansion", "template name", unversionedTE.ObjectMeta.Name) - r.registry.remove(nsName) + log.V(logging.DebugLevel).Info("removed expansion template", "template name", et.GetName()) + r.registry.remove(request.NamespacedName) + r.getTracker().CancelExpect(versionedET) + r.queueConflicts(oldConflicts) + return reconcile.Result{}, r.deleteStatus(ctx, request.NamespacedName.Name) + } + + upsertErr := r.system.UpsertTemplate(et) + if upsertErr == nil { + r.getTracker().Observe(versionedET) + r.registry.add(request.NamespacedName, metrics.ActiveStatus) } else { - if err := r.system.UpsertTemplate(unversionedTE); err != nil { - return reconcile.Result{}, err + r.getTracker().TryCancelExpect(versionedET) + r.registry.add(request.NamespacedName, metrics.ErrorStatus) + log.Error(upsertErr, "upserting template", "template_name", et.GetName()) + } + + r.queueConflicts(oldConflicts) + return reconcile.Result{}, r.updateOrCreatePodStatus(ctx, et, upsertErr) +} + +func (r *Reconciler) queueConflicts(old expansion.IDSet) { + for tID := range symmetricDiff(old, r.system.GetConflicts()) { + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(expansionv1beta1.GroupVersion.WithKind("ExpansionTemplate")) + // ExpansionTemplate is cluster-scoped, so we do not set namespace + u.SetName(string(tID)) + + r.events <- event.GenericEvent{Object: u} + } +} + +func symmetricDiff(x, y expansion.IDSet) expansion.IDSet { + sDiff := make(expansion.IDSet) + + for id := range x { + if _, exists := y[id]; !exists { + sDiff[id] = true + } + } + for id := range y { + if _, exists := x[id]; !exists { + sDiff[id] = true + } + } + + return sDiff +} + +func (r *Reconciler) deleteStatus(ctx context.Context, etName string) error { + status := &statusv1beta1.ExpansionTemplatePodStatus{} + pod, err := r.getPod(ctx) + if err != nil { + return fmt.Errorf("getting reconciler pod: %w", err) + } + sName, err := statusv1beta1.KeyForExpansionTemplate(pod.Name, etName) + if err != nil { + return fmt.Errorf("getting key for expansiontemplate: %w", err) + } + status.SetName(sName) + status.SetNamespace(util.GetNamespace()) + if err := r.Delete(ctx, status); err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil +} + +func (r *Reconciler) updateOrCreatePodStatus(ctx context.Context, et *unversioned.ExpansionTemplate, etErr error) error { + pod, err := r.getPod(ctx) + if err != nil { + return fmt.Errorf("getting reconciler pod: %w", err) + } + + // Check if it exists already + sNS := pod.Namespace + sName, err := statusv1beta1.KeyForExpansionTemplate(pod.Name, et.GetName()) + if err != nil { + return fmt.Errorf("getting key for expansiontemplate: %w", err) + } + shouldCreate := true + status := &statusv1beta1.ExpansionTemplatePodStatus{} + + err = r.Get(ctx, types.NamespacedName{Namespace: sNS, Name: sName}, status) + switch { + case err == nil: + shouldCreate = false + case apierrors.IsNotFound(err): + if status, err = r.newETStatus(pod, et); err != nil { + return fmt.Errorf("creating new expansiontemplate status: %w", err) } - log.Info("upserted template expansion", "template name", unversionedTE.ObjectMeta.Name) - r.registry.add(nsName) + default: + return fmt.Errorf("getting expansion status in name %s, namespace %s: %w", et.GetName(), et.GetNamespace(), err) + } + + setStatusError(status, etErr) + status.Status.ObservedGeneration = et.GetGeneration() + + if shouldCreate { + return r.Create(ctx, status) + } + return r.Update(ctx, status) +} + +func (r *Reconciler) newETStatus(pod *corev1.Pod, et *unversioned.ExpansionTemplate) (*statusv1beta1.ExpansionTemplatePodStatus, error) { + status, err := statusv1beta1.NewExpansionTemplateStatusForPod(pod, et.GetName(), r.scheme) + if err != nil { + return nil, fmt.Errorf("creating status for pod: %w", err) } + status.Status.TemplateUID = et.GetUID() + + return status, nil +} + +func (r *Reconciler) getTracker() readiness.Expectations { + return r.tracker.For(expansionv1beta1.GroupVersion.WithKind("ExpansionTemplate")) +} - if err := r.registry.report(ctx); err != nil { - log.Error(err, "error reporting template expansion metrics", "namespacedName", nsName) +func setStatusError(status *statusv1beta1.ExpansionTemplatePodStatus, etErr error) { + if etErr == nil { + status.Status.Errors = nil + return } - return reconcile.Result{}, nil + e := &statusv1beta1.ExpansionTemplateError{Message: etErr.Error()} + status.Status.Errors = []*statusv1beta1.ExpansionTemplateError{e} } diff --git a/pkg/controller/expansion/expansion_controller_test.go b/pkg/controller/expansion/expansion_controller_test.go new file mode 100644 index 00000000000..8b7c1311d0a --- /dev/null +++ b/pkg/controller/expansion/expansion_controller_test.go @@ -0,0 +1,204 @@ +package expansion + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/retry" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + testutils.StartControlPlane(m, &cfg, 3) +} + +func TestReconcile(t *testing.T) { + // Uncommenting the below enables logging of K8s internals like watch. + // fs := flag.NewFlagSet("", flag.PanicOnError) + // klog.InitFlags(fs) + // fs.Parse([]string{"--alsologtostderr", "-v=10"}) + // klog.SetOutput(os.Stderr) + + mgr, _ := testutils.SetupManager(t, cfg) + c := testclient.NewRetryClient(mgr.GetClient()) + + // creating the gatekeeper-system namespace is necessary because that's where + // status resources live by default + err := testutils.CreateGatekeeperNamespace(mgr.GetConfig()) + if err != nil { + t.Fatal(err) + } + + mutSystem := mutation.NewSystem(mutation.SystemOpts{}) + expSystem := expansion.NewSystem(mutSystem) + + testutils.Setenv(t, "POD_NAME", "no-pod") + + tracker, err := readiness.SetupTracker(mgr, false, false, true) + if err != nil { + t.Fatal(err) + } + + pod := fakes.Pod( + fakes.WithNamespace("gatekeeper-system"), + fakes.WithName("no-pod"), + ) + + r := newReconciler(mgr, expSystem, func(context.Context) (*corev1.Pod, error) { return pod, nil }, tracker) + if err != nil { + t.Fatal(err) + } + + err = add(mgr, r) + if err != nil { + t.Fatal(err) + } + + ctx := context.Background() + testutils.StartManager(ctx, t, mgr) + + t.Run("creating ET creates status obj, deleting ET deletes status", func(t *testing.T) { + t.Log("running test: creating ET creates ETPodStatus, deleting ET deletes status") + + etName := "default-et" + et := newET(etName) + + sName, err := statusv1beta1.KeyForExpansionTemplate("no-pod", etName) + if err != nil { + t.Fatal(err) + } + + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, et)) + testutils.CreateThenCleanup(ctx, t, c, et) + + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + return true + }, func() error { + // First, get the ET + et := &v1beta1.ExpansionTemplate{} + nsName := types.NamespacedName{Name: etName} + if err := c.Get(ctx, nsName, et); err != nil { + return err + } + if err != nil { + return fmt.Errorf("error fetching ET: %w", err) + } + + // Get the ETPodStatus + status := &statusv1beta1.ExpansionTemplatePodStatus{} + nsName = types.NamespacedName{ + Name: sName, + Namespace: "gatekeeper-system", + } + if err := c.Get(ctx, nsName, status); err != nil { + return err + } + if err != nil { + return fmt.Errorf("error fetching ET status: %w", err) + } + if status.Status.TemplateUID == et.GetUID() { + return nil + } + return fmt.Errorf("ExpansionTemplatePodStatus.Status.TemplateUID %q does not match ExpansionTemplate.GetUID() %q", status.Status.TemplateUID, et.GetUID()) + }) + if err != nil { + t.Fatal(err) + } + + if err := c.Delete(ctx, et); err != nil { + t.Fatalf("error deleting ET: %s", err) + } + + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + return true + }, func() error { + // Get the ETPodStatus + status := &statusv1beta1.ExpansionTemplatePodStatus{} + nsName := types.NamespacedName{ + Name: sName, + Namespace: "gatekeeper-system", + } + if err := c.Get(ctx, nsName, status); err != nil && apierrors.IsNotFound(err) { + return nil + } + return fmt.Errorf("expected IsNotFound when fetching status, but got: %w", err) + }) + if err != nil { + t.Fatal(err) + } + }) +} + +func TestAddStatusError(t *testing.T) { + tests := []struct { + name string + inputStatus statusv1beta1.ExpansionTemplatePodStatus + etErr error + wantStatus statusv1beta1.ExpansionTemplatePodStatus + }{ + { + name: "no err", + inputStatus: statusv1beta1.ExpansionTemplatePodStatus{}, + etErr: nil, + wantStatus: statusv1beta1.ExpansionTemplatePodStatus{Status: statusv1beta1.ExpansionTemplatePodStatusStatus{}}, + }, + { + name: "with err", + inputStatus: statusv1beta1.ExpansionTemplatePodStatus{}, + etErr: errors.New("big problem"), + wantStatus: statusv1beta1.ExpansionTemplatePodStatus{ + Status: statusv1beta1.ExpansionTemplatePodStatusStatus{ + Errors: []*statusv1beta1.ExpansionTemplateError{{Message: "big problem"}}, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + setStatusError(&tc.inputStatus, tc.etErr) + if diff := cmp.Diff(tc.inputStatus, tc.wantStatus); diff != "" { + t.Errorf("got: %v\nwant: %v\ndiff: %s", tc.inputStatus, tc.wantStatus, diff) + } + }) + } +} + +func newET(name string) *v1beta1.ExpansionTemplate { + et := &v1beta1.ExpansionTemplate{ + ObjectMeta: v1.ObjectMeta{Name: name}, + Spec: v1beta1.ExpansionTemplateSpec{ + ApplyTo: []match.ApplyTo{{ + Groups: []string{"apps"}, + Kinds: []string{"Deployment"}, + Versions: []string{"v1"}, + }}, + TemplateSource: "spec.template", + GeneratedGVK: v1beta1.GeneratedGVK{ + Kind: "Pod", + Version: "v1", + }, + }, + } + et.SetGroupVersionKind(v1alpha1.GroupVersion.WithKind("ExpansionTemplate")) + return et +} diff --git a/pkg/controller/expansion/stats_reporter.go b/pkg/controller/expansion/stats_reporter.go index 91bf1c45076..623886c174e 100644 --- a/pkg/controller/expansion/stats_reporter.go +++ b/pkg/controller/expansion/stats_reporter.go @@ -3,9 +3,10 @@ package expansion import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" + "go.opencensus.io/tag" "k8s.io/apimachinery/pkg/types" ) @@ -15,7 +16,8 @@ const ( ) var ( - etM = stats.Int64(etMetricName, etDesc, stats.UnitDimensionless) + etM = stats.Int64(etMetricName, etDesc, stats.UnitDimensionless) + statusKey = tag.MustNewKey("status") views = []*view.View{ { @@ -23,6 +25,7 @@ var ( Measure: etM, Description: etDesc, Aggregation: view.LastValue(), + TagKeys: []tag.Key{statusKey}, }, } ) @@ -38,33 +41,50 @@ func register() error { } func newRegistry() *etRegistry { - return &etRegistry{cache: make(map[types.NamespacedName]bool)} + return &etRegistry{cache: make(map[types.NamespacedName]metrics.Status)} } type etRegistry struct { - cache map[types.NamespacedName]bool + cache map[types.NamespacedName]metrics.Status dirty bool } -func (r *etRegistry) add(key types.NamespacedName) { - r.cache[key] = true +func (r *etRegistry) add(key types.NamespacedName, status metrics.Status) { + v, ok := r.cache[key] + if ok && v == status { + return + } + r.cache[key] = status r.dirty = true } func (r *etRegistry) remove(key types.NamespacedName) { + if _, exists := r.cache[key]; !exists { + return + } delete(r.cache, key) r.dirty = true } -func (r *etRegistry) report(ctx context.Context) error { +func (r *etRegistry) report(ctx context.Context) { if !r.dirty { - return nil + return } - if err := metrics.Record(ctx, etM.M(int64(len(r.cache)))); err != nil { - r.dirty = false - return err + totals := make(map[metrics.Status]int64) + for _, status := range r.cache { + totals[status]++ } - return nil + for _, s := range metrics.AllStatuses { + ctx, err := tag.New(ctx, tag.Insert(statusKey, string(s))) + if err != nil { + log.Error(err, "failed to create status tag for expansion templates") + continue + } + err = metrics.Record(ctx, etM.M(totals[s])) + if err != nil { + log.Error(err, "failed to record total expansion templates") + } + } } diff --git a/pkg/controller/expansionstatus/expansionstatus_controller.go b/pkg/controller/expansionstatus/expansionstatus_controller.go new file mode 100644 index 00000000000..1cd19b67ea0 --- /dev/null +++ b/pkg/controller/expansionstatus/expansionstatus_controller.go @@ -0,0 +1,201 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package expansionstatus + +import ( + "context" + "fmt" + "sort" + + "github.com/go-logr/logr" + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + expansionv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller").WithValues(logging.Process, "expansion_template_status_controller") + +type Adder struct { + CFClient *constraintclient.Client + WatchManager *watch.Manager +} + +func (a *Adder) InjectControllerSwitch(cs *watch.ControllerSwitch) {} + +func (a *Adder) InjectTracker(t *readiness.Tracker) {} + +// Add creates a new Constraint Status Controller and adds it to the Manager. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func (a *Adder) Add(mgr manager.Manager) error { + if !*expansion.ExpansionEnabled { + return nil + } + r := newReconciler(mgr) + return add(mgr, r) +} + +// newReconciler returns a new reconcile.Reconciler. +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileExpansionStatus{ + // Separate reader and writer because manager's default client bypasses the cache for unstructured resources. + writer: mgr.GetClient(), + statusClient: mgr.GetClient(), + reader: mgr.GetCache(), + + scheme: mgr.GetScheme(), + log: log, + } +} + +// PodStatusToExpansionTemplateMapper correlates a ExpansionTemplatePodStatus with its corresponding expansion template. +// `selfOnly` tells the mapper to only map statuses corresponding to the current pod. +func PodStatusToExpansionTemplateMapper(selfOnly bool) handler.MapFunc { + return func(ctx context.Context, obj client.Object) []reconcile.Request { + labels := obj.GetLabels() + name, ok := labels[v1beta1.ExpansionTemplateNameLabel] + if !ok { + log.Error(fmt.Errorf("expansion template status resource with no mapping label: %s", obj.GetName()), "missing label while attempting to map a expansion template status resource") + return nil + } + if selfOnly { + pod, ok := labels[v1beta1.PodLabel] + if !ok { + log.Error(fmt.Errorf("expansion template status resource with no pod label: %s", obj.GetName()), "missing label while attempting to map a expansion template status resource") + } + // Do not attempt to reconcile the resource when other pods have changed their status + if pod != util.GetPodName() { + return nil + } + } + return []reconcile.Request{{NamespacedName: types.NamespacedName{Name: name}}} + } +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler. +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("expansion-template-status-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to ExpansionTemplateStatus + err = c.Watch( + source.Kind(mgr.GetCache(), &v1beta1.ExpansionTemplatePodStatus{}), + handler.EnqueueRequestsFromMapFunc(PodStatusToExpansionTemplateMapper(false)), + ) + if err != nil { + return err + } + + // Watch for changes to ExpansionTemplate + err = c.Watch(source.Kind(mgr.GetCache(), &expansionv1beta1.ExpansionTemplate{}), &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + return nil +} + +var _ reconcile.Reconciler = &ReconcileExpansionStatus{} + +// ReconcileExpansionStatus reconciles an arbitrary constraint object described by Kind. +type ReconcileExpansionStatus struct { + reader client.Reader + writer client.Writer + statusClient client.StatusClient + + scheme *runtime.Scheme + log logr.Logger +} + +// +kubebuilder:rbac:groups=expansion.gatekeeper.sh,resources=*,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=status.gatekeeper.sh,resources=*,verbs=get;list;watch;create;update;patch;delete + +// Reconcile reads that state of the cluster for a constraint object and makes changes based on the state read +// and what is in the constraint.Spec. +func (r *ReconcileExpansionStatus) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + et := &expansionv1beta1.ExpansionTemplate{} + err := r.reader.Get(ctx, request.NamespacedName, et) + if err != nil { + // If the ExpansionTemplate does not exist then we are done + if errors.IsNotFound(err) { + return reconcile.Result{}, nil + } + return reconcile.Result{}, err + } + + sObjs := &v1beta1.ExpansionTemplatePodStatusList{} + if err := r.reader.List( + ctx, + sObjs, + client.MatchingLabels{v1beta1.ExpansionTemplateNameLabel: request.Name}, + client.InNamespace(util.GetNamespace()), + ); err != nil { + return reconcile.Result{}, err + } + statusObjs := make(sortableStatuses, len(sObjs.Items)) + copy(statusObjs, sObjs.Items) + sort.Sort(statusObjs) + + var s []v1beta1.ExpansionTemplatePodStatusStatus + // created is true if at least one Pod hasn't reported any errors + + for i := range statusObjs { + // Don't report status if it's not for the correct object. This can happen + // if a watch gets interrupted, causing the constraint status to be deleted + // out from underneath it + if statusObjs[i].Status.TemplateUID != et.GetUID() { + continue + } + s = append(s, statusObjs[i].Status) + } + + et.Status.ByPod = s + + if err := r.statusClient.Status().Update(ctx, et); err != nil { + return reconcile.Result{Requeue: true}, nil + } + return reconcile.Result{}, nil +} + +type sortableStatuses []v1beta1.ExpansionTemplatePodStatus + +func (s sortableStatuses) Len() int { + return len(s) +} + +func (s sortableStatuses) Less(i, j int) bool { + return s[i].Status.ID < s[j].Status.ID +} + +func (s sortableStatuses) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} diff --git a/pkg/controller/externaldata/externaldata_controller.go b/pkg/controller/externaldata/externaldata_controller.go index 42180ed7613..941965bd72b 100644 --- a/pkg/controller/externaldata/externaldata_controller.go +++ b/pkg/controller/externaldata/externaldata_controller.go @@ -7,12 +7,10 @@ import ( externaldatav1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" frameworksexternaldata "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -38,23 +36,17 @@ var ( ) type Adder struct { - Opa *constraintclient.Client + CFClient *constraintclient.Client ProviderCache *frameworksexternaldata.ProviderCache Tracker *readiness.Tracker } -func (a *Adder) InjectOpa(o *constraintclient.Client) { - a.Opa = o +func (a *Adder) InjectCFClient(c *constraintclient.Client) { + a.CFClient = c } -func (a *Adder) InjectWatchManager(w *watch.Manager) {} - func (a *Adder) InjectControllerSwitch(cs *watch.ControllerSwitch) {} -func (a *Adder) InjectMutationSystem(mutationSystem *mutation.System) {} - -func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) {} - func (a *Adder) InjectTracker(t *readiness.Tracker) { a.Tracker = t } @@ -66,23 +58,23 @@ func (a *Adder) InjectProviderCache(providerCache *frameworksexternaldata.Provid // Add creates a new ExternalData Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func (a *Adder) Add(mgr manager.Manager) error { - r := newReconciler(mgr, a.Opa, a.ProviderCache, a.Tracker) + r := newReconciler(mgr, a.CFClient, a.ProviderCache, a.Tracker) return add(mgr, r) } // Reconciler reconciles a ExternalData object. type Reconciler struct { client.Client - opa *constraintclient.Client + cfClient *constraintclient.Client providerCache *frameworksexternaldata.ProviderCache tracker *readiness.Tracker scheme *runtime.Scheme } // newReconciler returns a new reconcile.Reconciler. -func newReconciler(mgr manager.Manager, opa *constraintclient.Client, providerCache *frameworksexternaldata.ProviderCache, tracker *readiness.Tracker) *Reconciler { +func newReconciler(mgr manager.Manager, client *constraintclient.Client, providerCache *frameworksexternaldata.ProviderCache, tracker *readiness.Tracker) *Reconciler { r := &Reconciler{ - opa: opa, + cfClient: client, providerCache: providerCache, Client: mgr.GetClient(), scheme: mgr.GetScheme(), @@ -105,7 +97,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to Provider return c.Watch( - &source.Kind{Type: &externaldatav1beta1.Provider{}}, + source.Kind(mgr.GetCache(), &externaldatav1beta1.Provider{}), &handler.EnqueueRequestForObject{}) } diff --git a/pkg/controller/externaldata/externaldata_controller_suite_test.go b/pkg/controller/externaldata/externaldata_controller_suite_test.go index 35169bc3357..5fc5c39ca45 100644 --- a/pkg/controller/externaldata/externaldata_controller_suite_test.go +++ b/pkg/controller/externaldata/externaldata_controller_suite_test.go @@ -17,44 +17,17 @@ package externaldata import ( "context" - stdlog "log" - "os" - "path/filepath" "testing" - "github.com/open-policy-agent/gatekeeper/apis" - "k8s.io/client-go/kubernetes/scheme" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) var cfg *rest.Config func TestMain(m *testing.M) { - var err error - - t := &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"), - filepath.Join("..", "..", "..", "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - } - if err := apis.AddToScheme(scheme.Scheme); err != nil { - stdlog.Fatal(err) - } - - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - stdlog.Print("STARTED") - - code := m.Run() - if err = t.Stop(); err != nil { - stdlog.Printf("error while trying to stop server: %v", err) - } - os.Exit(code) + testutils.StartControlPlane(m, &cfg, 3) } // SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and diff --git a/pkg/controller/externaldata/externaldata_controller_test.go b/pkg/controller/externaldata/externaldata_controller_test.go index 1347a2b099c..88e2a036b8b 100644 --- a/pkg/controller/externaldata/externaldata_controller_test.go +++ b/pkg/controller/externaldata/externaldata_controller_test.go @@ -11,20 +11,18 @@ import ( externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" externaldatav1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" frameworksexternaldata "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" - "github.com/open-policy-agent/gatekeeper/test/testutils" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "github.com/prometheus/client_golang/prometheus" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -47,9 +45,7 @@ func setupManager(t *testing.T) manager.Manager { metrics.Registry = prometheus.NewRegistry() mgr, err := manager.New(cfg, manager.Options{ MetricsBindAddress: "0", - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, + MapperProvider: apiutil.NewDynamicRESTMapper, }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -83,25 +79,24 @@ func TestReconcile(t *testing.T) { *externaldata.ExternalDataEnabled = true pc := frameworksexternaldata.NewCache() - // initialize OPA - args := []local.Arg{local.Tracing(false), local.AddExternalDataProviderCache(pc)} - driver, err := local.New(args...) + args := []rego.Arg{rego.Tracing(false), rego.AddExternalDataProviderCache(pc)} + driver, err := rego.New(args...) if err != nil { t.Fatalf("unable to set up Driver: %v", err) } - opa, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) if err != nil { - t.Fatalf("unable to set up OPA client: %s", err) + t.Fatalf("unable to set up constraint framework client: %s", err) } cs := watch.NewSwitch() - tracker, err := readiness.SetupTracker(mgr, false, true) + tracker, err := readiness.SetupTracker(mgr, false, true, false) if err != nil { t.Fatal(err) } - rec := newReconciler(mgr, opa, pc, tracker) + rec := newReconciler(mgr, cfClient, pc, tracker) recFn, requests := SetupTestReconcile(rec) err = add(mgr, recFn) diff --git a/pkg/controller/mutators/cache.go b/pkg/controller/mutators/cache.go index f6274bb2cce..d853ccc3d25 100644 --- a/pkg/controller/mutators/cache.go +++ b/pkg/controller/mutators/cache.go @@ -3,7 +3,7 @@ package mutators import ( "sync" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type mutatorStatus struct { diff --git a/pkg/controller/mutators/cache_test.go b/pkg/controller/mutators/cache_test.go index de7c6a3ff07..ce48276a975 100644 --- a/pkg/controller/mutators/cache_test.go +++ b/pkg/controller/mutators/cache_test.go @@ -5,7 +5,7 @@ import ( "sync" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) func TestCache_TallyStatus(t *testing.T) { diff --git a/pkg/controller/mutators/core/adder.go b/pkg/controller/mutators/core/adder.go index fe55c99a2dc..6dbb2dd3e3f 100644 --- a/pkg/controller/mutators/core/adder.go +++ b/pkg/controller/mutators/core/adder.go @@ -5,11 +5,11 @@ import ( "fmt" "strings" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutatorstatus" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutatorstatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" corev1 "k8s.io/api/core/v1" apitypes "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -67,7 +67,7 @@ func (a *Adder) add(mgr manager.Manager, r *Reconciler) error { // Watch for changes to Mutators. err = c.Watch( - &source.Kind{Type: r.newMutationObj()}, + source.Kind(mgr.GetCache(), r.newMutationObj()), &handler.EnqueueRequestForObject{}) if err != nil { return err @@ -75,8 +75,8 @@ func (a *Adder) add(mgr manager.Manager, r *Reconciler) error { // Watch for changes to MutatorPodStatuses. err = c.Watch( - &source.Kind{Type: &statusv1beta1.MutatorPodStatus{}}, - handler.EnqueueRequestsFromMapFunc(mutatorstatus.PodStatusToMutatorMapper(true, r.gvk.Kind, func(obj client.Object) []reconcile.Request { + source.Kind(mgr.GetCache(), &statusv1beta1.MutatorPodStatus{}), + handler.EnqueueRequestsFromMapFunc(mutatorstatus.PodStatusToMutatorMapper(true, r.gvk.Kind, func(ctx context.Context, obj client.Object) []reconcile.Request { return []reconcile.Request{{ NamespacedName: apitypes.NamespacedName{ Namespace: obj.GetNamespace(), @@ -93,7 +93,7 @@ func (a *Adder) add(mgr manager.Manager, r *Reconciler) error { // Watch for enqueued events. err = c.Watch( a.EventsSource, - handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request { + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { if obj.GetObjectKind().GroupVersionKind().Kind != r.gvk.Kind { return nil } diff --git a/pkg/controller/mutators/core/controller_suite_test.go b/pkg/controller/mutators/core/controller_suite_test.go index 510170ad405..0600f80994e 100644 --- a/pkg/controller/mutators/core/controller_suite_test.go +++ b/pkg/controller/mutators/core/controller_suite_test.go @@ -16,19 +16,14 @@ limitations under the License. package core import ( - "context" "log" "os" "path/filepath" "testing" - "github.com/open-policy-agent/gatekeeper/apis" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/open-policy-agent/gatekeeper/v3/apis" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/envtest" ) @@ -57,22 +52,3 @@ func TestMain(m *testing.M) { } os.Exit(code) } - -// Bootstrap the gatekeeper-system namespace for use in tests. -func createGatekeeperNamespace(cfg *rest.Config) error { - c, err := client.New(cfg, client.Options{}) - if err != nil { - return err - } - - // Create gatekeeper namespace - ns := &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "gatekeeper-system", - }, - } - - ctx := context.Background() - _, err = controllerutil.CreateOrUpdate(ctx, c, ns, func() error { return nil }) - return err -} diff --git a/pkg/controller/mutators/core/controller_test.go b/pkg/controller/mutators/core/controller_test.go index 6e9985715f8..de7755a8c28 100644 --- a/pkg/controller/mutators/core/controller_test.go +++ b/pkg/controller/mutators/core/controller_test.go @@ -23,28 +23,26 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/onsi/gomega" - mutationsinternal "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - podstatus "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutatorstatus" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators" - mutationschema "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/test/testutils" + mutationsinternal "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + podstatus "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutatorstatus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators" + mutationschema "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" apiTypes "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/event" @@ -66,10 +64,8 @@ func setupManager(t *testing.T) manager.Manager { metrics.Registry = prometheus.NewRegistry() mgr, err := manager.New(cfg, manager.Options{ MetricsBindAddress: "0", - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, - Logger: testutils.NewLogger(t), + MapperProvider: apiutil.NewDynamicRESTMapper, + Logger: testutils.NewLogger(t), }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -117,13 +113,13 @@ func TestReconcile(t *testing.T) { // creating the gatekeeper-system namespace is necessary because that's where // status resources live by default - if err := createGatekeeperNamespace(mgr.GetConfig()); err != nil { + if err := testutils.CreateGatekeeperNamespace(mgr.GetConfig()); err != nil { t.Fatalf("want createGatekeeperNamespace(mgr.GetConfig()) error = nil, got %v", err) } mSys := mutation.NewSystem(mutation.SystemOpts{}) - tracker, err := readiness.SetupTracker(mgr, true, false) + tracker, err := readiness.SetupTracker(mgr, true, false, false) if err != nil { t.Fatal(err) } diff --git a/pkg/controller/mutators/core/reconciler.go b/pkg/controller/mutators/core/reconciler.go index d3490c71817..cfc2d6aae21 100644 --- a/pkg/controller/mutators/core/reconciler.go +++ b/pkg/controller/mutators/core/reconciler.go @@ -23,14 +23,14 @@ import ( "time" "github.com/go-logr/logr" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - ctrlmutators "github.com/open-policy-agent/gatekeeper/pkg/controller/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - mutationschema "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" + mutationsv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + ctrlmutators "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + mutationschema "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/controller/mutators/core/reconciler_test.go b/pkg/controller/mutators/core/reconciler_test.go index 1cdc07cd59a..7430f1aabaf 100644 --- a/pkg/controller/mutators/core/reconciler_test.go +++ b/pkg/controller/mutators/core/reconciler_test.go @@ -11,14 +11,14 @@ import ( "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - mutationschema "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + mutationschema "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -92,7 +92,7 @@ func newFakeClient() *fakeClient { var _ client.Client = &fakeClient{} -func (c *fakeClient) Get(_ context.Context, key client.ObjectKey, obj client.Object) error { +func (c *fakeClient) Get(_ context.Context, key client.ObjectKey, obj client.Object, _ ...client.GetOption) error { got, found := c.objects[key] if !found { return apierrors.NewNotFound(schema.GroupResource{}, key.Name) @@ -254,7 +254,7 @@ func (m *fakeMutator) HasDiff(right mutationtypes.Mutator) bool { m.path.String() != other.path.String() } -func (m *fakeMutator) UsesExternalData() bool { +func (m *fakeMutator) MustTerminate() bool { return false } @@ -263,7 +263,8 @@ type errSome struct{ id int } func newErrSome(id int) error { return &errSome{id: id} } func (e *errSome) Is(target error) bool { - if t, ok := target.(*errSome); ok { + var t *errSome + if errors.As(target, &t) { return t.id == e.id } @@ -401,7 +402,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: true, Errors: nil, }, @@ -433,7 +434,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: true, Errors: nil, }, @@ -493,7 +494,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: false, Errors: []statusv1beta1.MutatorError{{Message: newErrSome(1).Error()}}, }, @@ -534,7 +535,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: false, Errors: []statusv1beta1.MutatorError{ { @@ -633,7 +634,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: false, Errors: []statusv1beta1.MutatorError{ { @@ -684,7 +685,7 @@ func TestReconciler_Reconcile(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: true, Errors: nil, }, @@ -939,7 +940,7 @@ func TestReconciler_Reconcile_DeletePodStatus(t *testing.T) { }, Status: statusv1beta1.MutatorPodStatusStatus{ ID: "no-pod", - Operations: []string{"audit", "mutation-status", "mutation-webhook", "status", "webhook"}, + Operations: []string{"audit", "mutation-controller", "mutation-status", "mutation-webhook", "status", "webhook"}, Enforced: true, }, } diff --git a/pkg/controller/mutators/core/status.go b/pkg/controller/mutators/core/status.go index 72cd841b219..2472bb91032 100644 --- a/pkg/controller/mutators/core/status.go +++ b/pkg/controller/mutators/core/status.go @@ -1,8 +1,10 @@ package core import ( - statusv1beta1 "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" + "errors" + + statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" apiTypes "k8s.io/apimachinery/pkg/types" ) @@ -23,15 +25,16 @@ func setGeneration(generation int64) statusUpdate { func setErrors(err error) statusUpdate { return func(status *statusv1beta1.MutatorPodStatus) { // Replaces any existing errors, if there was one. - switch err.(type) { - case nil: + if err == nil { status.Status.Errors = nil - case schema.ErrConflictingSchema: + return + } + if errors.As(err, &schema.ErrConflictingSchema{}) { status.Status.Errors = []statusv1beta1.MutatorError{{ Type: schema.ErrConflictingSchemaType, Message: err.Error(), }} - default: + } else { status.Status.Errors = []statusv1beta1.MutatorError{{Message: err.Error()}} } } diff --git a/pkg/controller/mutators/instances/mutator_controllers.go b/pkg/controller/mutators/instances/mutator_controllers.go index b5074ea380c..f790cd83d93 100644 --- a/pkg/controller/mutators/instances/mutator_controllers.go +++ b/pkg/controller/mutators/instances/mutator_controllers.go @@ -3,17 +3,15 @@ package instances import ( "context" - constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/mutators/core" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" @@ -82,11 +80,34 @@ func (a *Adder) Add(mgr manager.Manager) error { Events: events, EventsSource: eventsSource, } - if err := modifySet.Add(mgr); err != nil { return err } + assignImage := core.Adder{ + Tracker: a.Tracker, + GetPod: a.GetPod, + MutationSystem: a.MutationSystem, + Kind: "AssignImage", + NewMutationObj: func() client.Object { return &v1alpha1.AssignImage{} }, + MutatorFor: func(obj client.Object) (types.Mutator, error) { + // The type is provided by the `NewObj` function above. If we + // are fed the wrong type, this is a non-recoverable error and we + // may as well crash for visibility + assignImage := obj.(*v1alpha1.AssignImage) // nolint:forcetypeassert + unversioned := &mutationsunversioned.AssignImage{} + if err := scheme.Convert(assignImage, unversioned, nil); err != nil { + return nil, err + } + return mutators.MutatorForAssignImage(unversioned) + }, + Events: events, + EventsSource: eventsSource, + } + if err := assignImage.Add(mgr); err != nil { + return err + } + assignMetadata := core.Adder{ Tracker: a.Tracker, GetPod: a.GetPod, @@ -108,10 +129,6 @@ func (a *Adder) Add(mgr manager.Manager) error { return assignMetadata.Add(mgr) } -func (a *Adder) InjectOpa(o *constraintclient.Client) {} - -func (a *Adder) InjectWatchManager(w *watch.Manager) {} - func (a *Adder) InjectControllerSwitch(cs *watch.ControllerSwitch) {} func (a *Adder) InjectTracker(t *readiness.Tracker) { @@ -125,7 +142,3 @@ func (a *Adder) InjectGetPod(getPod func(ctx context.Context) (*corev1.Pod, erro func (a *Adder) InjectMutationSystem(mutationSystem *mutation.System) { a.MutationSystem = mutationSystem } - -func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) {} - -func (a *Adder) InjectProviderCache(providerCache *externaldata.ProviderCache) {} diff --git a/pkg/controller/mutators/stats_reporter.go b/pkg/controller/mutators/stats_reporter.go index c279a8cbf3b..63603a0d037 100644 --- a/pkg/controller/mutators/stats_reporter.go +++ b/pkg/controller/mutators/stats_reporter.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/controller/mutators/stats_reporter_test.go b/pkg/controller/mutators/stats_reporter_test.go index 39111cbd6d5..5d08d6c06e8 100644 --- a/pkg/controller/mutators/stats_reporter_test.go +++ b/pkg/controller/mutators/stats_reporter_test.go @@ -181,7 +181,7 @@ func getRow(rows []*view.Row, tagValue string) (*view.Row, error) { func checkData(name string, rowLength int) ([]*view.Row, error) { rows, err := view.RetrieveData(name) if err != nil { - return nil, fmt.Errorf("got RetrieveData error %v from %v, want nil", err, name) + return nil, fmt.Errorf("got RetrieveData error %w from %v, want nil", err, name) } if len(rows) != rowLength { return nil, fmt.Errorf("got %q row length %v, want %v", name, len(rows), rowLength) diff --git a/pkg/controller/mutatorstatus/mutatorstatus_controller.go b/pkg/controller/mutatorstatus/mutatorstatus_controller.go index bb1b422fc16..824cc097b2d 100644 --- a/pkg/controller/mutatorstatus/mutatorstatus_controller.go +++ b/pkg/controller/mutatorstatus/mutatorstatus_controller.go @@ -22,17 +22,14 @@ import ( "sort" "github.com/go-logr/logr" - constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - "github.com/open-policy-agent/gatekeeper/apis/status/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" + mutationsv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -53,20 +50,10 @@ type Adder struct { ControllerSwitch *watch.ControllerSwitch } -func (a *Adder) InjectOpa(o *constraintclient.Client) {} - -func (a *Adder) InjectWatchManager(w *watch.Manager) {} - func (a *Adder) InjectControllerSwitch(cs *watch.ControllerSwitch) {} func (a *Adder) InjectTracker(t *readiness.Tracker) {} -func (a *Adder) InjectMutationSystem(mutationSystem *mutation.System) {} - -func (a *Adder) InjectExpansionSystem(expansionSystem *expansion.System) {} - -func (a *Adder) InjectProviderCache(providerCache *externaldata.ProviderCache) {} - // Add creates a new Mutator Status Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func (a *Adder) Add(mgr manager.Manager) error { @@ -98,7 +85,7 @@ type PackerMap func(obj client.Object) []reconcile.Request // PodStatusToMutatorMapper correlates a MutatorPodStatus with its corresponding mutator. func PodStatusToMutatorMapper(selfOnly bool, kindMatch string, packerMap handler.MapFunc) handler.MapFunc { - return func(obj client.Object) []reconcile.Request { + return func(ctx context.Context, obj client.Object) []reconcile.Request { labels := obj.GetLabels() name, ok := labels[v1beta1.MutatorNameLabel] if !ok { @@ -124,9 +111,14 @@ func PodStatusToMutatorMapper(selfOnly bool, kindMatch string, packerMap handler } } u := &unstructured.Unstructured{} - u.SetGroupVersionKind(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: "v1", Kind: kind}) + // AssignImage is the only mutator in v1alpha1 still + v := "v1" + if kind == "AssignImage" { + v = "v1alpha1" + } + u.SetGroupVersionKind(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: v, Kind: kind}) u.SetName(name) - return packerMap(u) + return packerMap(ctx, u) } } @@ -140,7 +132,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to MutatorStatus err = c.Watch( - &source.Kind{Type: &v1beta1.MutatorPodStatus{}}, + source.Kind(mgr.GetCache(), &v1beta1.MutatorPodStatus{}), handler.EnqueueRequestsFromMapFunc(PodStatusToMutatorMapper(false, "", util.EventPackerMapFunc())), ) if err != nil { @@ -149,21 +141,28 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { // Watch for changes to mutators err = c.Watch( - &source.Kind{Type: &mutationsv1.Assign{}}, + source.Kind(mgr.GetCache(), &mutationsv1.Assign{}), handler.EnqueueRequestsFromMapFunc(util.EventPackerMapFuncHardcodeGVK(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: "v1", Kind: "Assign"})), ) if err != nil { return err } err = c.Watch( - &source.Kind{Type: &mutationsv1.AssignMetadata{}}, + source.Kind(mgr.GetCache(), &mutationsv1.AssignMetadata{}), handler.EnqueueRequestsFromMapFunc(util.EventPackerMapFuncHardcodeGVK(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: "v1", Kind: "AssignMetadata"})), ) if err != nil { return err } + err = c.Watch( + source.Kind(mgr.GetCache(), &mutationsv1alpha1.AssignImage{}), + handler.EnqueueRequestsFromMapFunc(util.EventPackerMapFuncHardcodeGVK(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: "v1alpha1", Kind: "AssignImage"})), + ) + if err != nil { + return err + } return c.Watch( - &source.Kind{Type: &mutationsv1.ModifySet{}}, + source.Kind(mgr.GetCache(), &mutationsv1.ModifySet{}), handler.EnqueueRequestsFromMapFunc(util.EventPackerMapFuncHardcodeGVK(schema.GroupVersionKind{Group: v1beta1.MutationsGroup, Version: "v1", Kind: "ModifySet"})), ) } diff --git a/pkg/controller/pubsub/pubsub_config_controller.go b/pkg/controller/pubsub/pubsub_config_controller.go new file mode 100644 index 00000000000..e70ac499587 --- /dev/null +++ b/pkg/controller/pubsub/pubsub_config_controller.go @@ -0,0 +1,134 @@ +package pubsub + +import ( + "context" + "encoding/json" + "flag" + "fmt" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var ( + PubsubEnabled = flag.Bool("enable-pub-sub", false, "Enabled pubsub to publish messages") + log = logf.Log.WithName("controller").WithValues(logging.Process, "pubsub_controller") +) + +type Adder struct { + PubsubSystem *pubsub.System +} + +func (a *Adder) Add(mgr manager.Manager) error { + if !*PubsubEnabled { + return nil + } + r := newReconciler(mgr, a.PubsubSystem) + return add(mgr, r) +} + +func (a *Adder) InjectControllerSwitch(_ *watch.ControllerSwitch) {} + +func (a *Adder) InjectTracker(_ *readiness.Tracker) {} + +func (a *Adder) InjectPubsubSystem(pubsubSystem *pubsub.System) { + a.PubsubSystem = pubsubSystem +} + +type Reconciler struct { + client.Client + scheme *runtime.Scheme + system *pubsub.System +} + +func newReconciler(mgr manager.Manager, system *pubsub.System) *Reconciler { + return &Reconciler{ + Client: mgr.GetClient(), + scheme: mgr.GetScheme(), + system: system, + } +} + +func add(mgr manager.Manager, r reconcile.Reconciler) error { + c, err := controller.New("pubsub-config-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + return c.Watch( + source.Kind(mgr.GetCache(), &corev1.ConfigMap{}), + &handler.EnqueueRequestForObject{}, + predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return e.Object.GetNamespace() == util.GetNamespace() + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return e.ObjectNew.GetNamespace() == util.GetNamespace() + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return e.Object.GetNamespace() == util.GetNamespace() + }, + GenericFunc: func(e event.GenericEvent) bool { + return e.Object.GetNamespace() == util.GetNamespace() + }, + }, + ) +} + +func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + log.Info("Reconcile", "request", request, "namespace", request.Namespace, "name", request.Name) + + deleted := false + cfg := &corev1.ConfigMap{} + err := r.Get(ctx, request.NamespacedName, cfg) + if err != nil { + if !errors.IsNotFound(err) { + return reconcile.Result{}, err + } + deleted = true + } + + if deleted { + err := r.system.CloseConnection(request.Name) + if err != nil { + return reconcile.Result{Requeue: true}, err + } + log.Info("removed connection", "name", request.Name) + return reconcile.Result{}, nil + } + + if len(cfg.Data) == 0 { + return reconcile.Result{}, fmt.Errorf(fmt.Sprintf("data missing in configmap %s, unable to configure respective pubsub", request.NamespacedName)) + } + if _, ok := cfg.Data["provider"]; !ok { + return reconcile.Result{}, fmt.Errorf(fmt.Sprintf("missing provider field in configmap %s, unable to configure respective pubsub", request.NamespacedName)) + } + var config interface{} + err = json.Unmarshal([]byte(cfg.Data["config"]), &config) + if err != nil { + return reconcile.Result{}, err + } + + err = r.system.UpsertConnection(ctx, config, request.Name, cfg.Data["provider"]) + if err != nil { + return reconcile.Result{}, err + } + + log.Info("Connection upsert successful", "name", request.Name, "provider", cfg.Data["provider"]) + return reconcile.Result{}, nil +} diff --git a/pkg/controller/pubsub/pubsub_config_controller_test.go b/pkg/controller/pubsub/pubsub_config_controller_test.go new file mode 100644 index 00000000000..258b092c309 --- /dev/null +++ b/pkg/controller/pubsub/pubsub_config_controller_test.go @@ -0,0 +1,68 @@ +package pubsub + +import ( + "context" + "flag" + "fmt" + "testing" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/dapr" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +func TestReconcile(t *testing.T) { + // Create a fake client with some data + scheme := runtime.NewScheme() + err := corev1.AddToScheme(scheme) + if err != nil { + t.Fatalf("Unexpected error parsing flag: %v", err) + } + + err = flag.CommandLine.Parse([]string{"--enable-pub-sub", "true"}) + if err != nil { + t.Fatalf("Unexpected error parsing flag: %v", err) + } + + request := reconcile.Request{NamespacedName: types.NamespacedName{Namespace: util.GetNamespace(), Name: dapr.Name}} + + ctx := context.Background() + testCases := []struct { + name string + config *corev1.ConfigMap + wantErr bool + errorMsg string + }{ + { + name: "invalid configmap", + config: &corev1.ConfigMap{ + ObjectMeta: v1.ObjectMeta{ + Name: dapr.Name, + Namespace: util.GetNamespace(), + }, + }, + wantErr: true, + errorMsg: fmt.Sprintf("data missing in configmap %s, unable to configure respective pubsub", request.NamespacedName), + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(tc.config).Build() + r := &Reconciler{ + Client: client, + scheme: scheme, + } + + _, err := r.Reconcile(ctx, request) + if tc.wantErr { + assert.Equal(t, err.Error(), tc.errorMsg) + } + }) + } +} diff --git a/pkg/controller/sync/opadataclient.go b/pkg/controller/sync/opadataclient.go deleted file mode 100644 index 76120e4ad5e..00000000000 --- a/pkg/controller/sync/opadataclient.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sync - -import ( - "context" - - "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// OpaDataClient is an interface for caching data. -type OpaDataClient interface { - AddData(ctx context.Context, data interface{}) (*types.Responses, error) - RemoveData(ctx context.Context, data interface{}) (*types.Responses, error) -} - -// FilteredDataClient is an OpaDataClient which drops any unwatched resources. -type FilteredDataClient struct { - watched *watch.Set - opa OpaDataClient -} - -func NewFilteredOpaDataClient(opa OpaDataClient, watchSet *watch.Set) *FilteredDataClient { - return &FilteredDataClient{ - watched: watchSet, - opa: opa, - } -} - -// AddData adds data to the opa cache if that data is currently being watched. -// Unwatched data is silently dropped with no error. -func (f *FilteredDataClient) AddData(ctx context.Context, data interface{}) (*types.Responses, error) { - if obj, ok := data.(client.Object); ok { - gvk := obj.GetObjectKind().GroupVersionKind() - if !f.watched.Contains(gvk) { - return &types.Responses{}, nil - } - } - - return f.opa.AddData(ctx, data) -} - -// RemoveData removes data from the opa cache if that data is currently being watched. -// Unwatched data is silently dropped with no error. -func (f *FilteredDataClient) RemoveData(ctx context.Context, data interface{}) (*types.Responses, error) { - if obj, ok := data.(client.Object); ok { - gvk := obj.GetObjectKind().GroupVersionKind() - if !f.watched.Contains(gvk) { - return &types.Responses{}, nil - } - } - - return f.opa.RemoveData(ctx, data) -} diff --git a/pkg/controller/sync/stats_reporter.go b/pkg/controller/sync/stats_reporter.go deleted file mode 100644 index 9d8f3262c3f..00000000000 --- a/pkg/controller/sync/stats_reporter.go +++ /dev/null @@ -1,94 +0,0 @@ -package sync - -import ( - "context" - "time" - - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -const ( - syncMetricName = "sync" - syncDurationMetricName = "sync_duration_seconds" - lastRunTimeMetricName = "sync_last_run_time" -) - -var ( - syncM = stats.Int64(syncMetricName, "Total number of resources of each kind being cached", stats.UnitDimensionless) - syncDurationM = stats.Float64(syncDurationMetricName, "Latency of sync operation in seconds", stats.UnitSeconds) - lastRunSyncM = stats.Float64(lastRunTimeMetricName, "Timestamp of last sync operation", stats.UnitSeconds) - - kindKey = tag.MustNewKey("kind") - statusKey = tag.MustNewKey("status") - - views = []*view.View{ - { - Name: syncM.Name(), - Measure: syncM, - Description: syncM.Description(), - Aggregation: view.LastValue(), - TagKeys: []tag.Key{kindKey, statusKey}, - }, - { - Name: syncDurationM.Name(), - Measure: syncDurationM, - Description: syncDurationM.Description(), - Aggregation: view.Distribution(0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008, 0.0009, 0.001, 0.002, 0.003, 0.004, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05), - }, - { - Name: lastRunSyncM.Name(), - Measure: lastRunSyncM, - Description: lastRunSyncM.Description(), - Aggregation: view.LastValue(), - }, - } -) - -func init() { - if err := register(); err != nil { - panic(err) - } -} - -func register() error { - return view.Register(views...) -} - -type Reporter struct { - now func() float64 -} - -// NewStatsReporter creates a reporter for sync metrics. -func NewStatsReporter() (*Reporter, error) { - return &Reporter{now: now}, nil -} - -func (r *Reporter) reportSyncDuration(d time.Duration) error { - ctx := context.Background() - return metrics.Record(ctx, syncDurationM.M(d.Seconds())) -} - -func (r *Reporter) reportLastSync() error { - ctx := context.Background() - return metrics.Record(ctx, lastRunSyncM.M(r.now())) -} - -func (r *Reporter) reportSync(t Tags, v int64) error { - ctx, err := tag.New( - context.Background(), - tag.Insert(kindKey, t.Kind), - tag.Insert(statusKey, string(t.Status))) - if err != nil { - return err - } - - return metrics.Record(ctx, syncM.M(v)) -} - -// now returns the timestamp as a second-denominated float. -func now() float64 { - return float64(time.Now().UnixNano()) / 1e9 -} diff --git a/pkg/controller/sync/sync_controller.go b/pkg/controller/sync/sync_controller.go index 2d792caa24e..a74655c2135 100644 --- a/pkg/controller/sync/sync_controller.go +++ b/pkg/controller/sync/sync_controller.go @@ -17,17 +17,14 @@ package sync import ( "context" - "strings" - "sync" "time" "github.com/go-logr/logr" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -44,11 +41,8 @@ import ( var log = logf.Log.WithName("controller").WithValues("metaKind", "Sync") type Adder struct { - Opa OpaDataClient - Events <-chan event.GenericEvent - MetricsCache *MetricsCache - Tracker *readiness.Tracker - ProcessExcluder *process.Excluder + CacheManager *cachemanager.CacheManager + Events <-chan event.GenericEvent } // Add creates a new Sync Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller @@ -57,34 +51,28 @@ func (a *Adder) Add(mgr manager.Manager) error { if !operations.HasValidationOperations() { return nil } - reporter, err := NewStatsReporter() + reporter, err := syncutil.NewStatsReporter() if err != nil { log.Error(err, "Sync metrics reporter could not start") return err } - r := newReconciler(mgr, a.Opa, *reporter, a.MetricsCache, a.Tracker, a.ProcessExcluder) + r := newReconciler(mgr, *reporter, a.CacheManager) return add(mgr, r, a.Events) } // newReconciler returns a new reconcile.Reconciler. func newReconciler( mgr manager.Manager, - opa OpaDataClient, - reporter Reporter, - metricsCache *MetricsCache, - tracker *readiness.Tracker, - processExcluder *process.Excluder, + reporter syncutil.Reporter, + cm *cachemanager.CacheManager, ) reconcile.Reconciler { return &ReconcileSync{ - reader: mgr.GetCache(), - scheme: mgr.GetScheme(), - opa: opa, - log: log, - reporter: reporter, - metricsCache: metricsCache, - tracker: tracker, - processExcluder: processExcluder, + reader: mgr.GetCache(), + scheme: mgr.GetScheme(), + log: log, + reporter: reporter, + cm: cm, } } @@ -108,28 +96,14 @@ func add(mgr manager.Manager, r reconcile.Reconciler, events <-chan event.Generi var _ reconcile.Reconciler = &ReconcileSync{} -type MetricsCache struct { - mux sync.RWMutex - Cache map[string]Tags - KnownKinds map[string]bool -} - -type Tags struct { - Kind string - Status metrics.Status -} - // ReconcileSync reconciles an arbitrary object described by Kind. type ReconcileSync struct { reader client.Reader - scheme *runtime.Scheme - opa OpaDataClient - log logr.Logger - reporter Reporter - metricsCache *MetricsCache - tracker *readiness.Tracker - processExcluder *process.Excluder + scheme *runtime.Scheme + log logr.Logger + reporter syncutil.Reporter + cm *cachemanager.CacheManager } // +kubebuilder:rbac:groups=constraints.gatekeeper.sh,resources=*,verbs=get;list;watch;create;update;patch;delete @@ -147,17 +121,16 @@ func (r *ReconcileSync) Reconcile(ctx context.Context, request reconcile.Request return reconcile.Result{}, nil } - syncKey := r.metricsCache.GetSyncKey(unpackedRequest.Namespace, unpackedRequest.Name) reportMetrics := false defer func() { if reportMetrics { - if err := r.reporter.reportSyncDuration(time.Since(timeStart)); err != nil { + if err := r.reporter.ReportSyncDuration(time.Since(timeStart)); err != nil { log.Error(err, "failed to report sync duration") } - r.metricsCache.ReportSync(&r.reporter) + r.cm.ReportSyncMetrics() - if err := r.reporter.reportLastSync(); err != nil { + if err := r.reporter.ReportLastSync(); err != nil { log.Error(err, "failed to report last sync timestamp") } } @@ -171,15 +144,10 @@ func (r *ReconcileSync) Reconcile(ctx context.Context, request reconcile.Request // This is a deletion; remove the data instance.SetNamespace(unpackedRequest.Namespace) instance.SetName(unpackedRequest.Name) - if _, err := r.opa.RemoveData(ctx, instance); err != nil { + if err := r.cm.RemoveObject(ctx, instance); err != nil { return reconcile.Result{}, err } - // cancel expectations - t := r.tracker.ForData(instance.GroupVersionKind()) - t.CancelExpect(instance) - - r.metricsCache.DeleteObject(syncKey) reportMetrics = true return reconcile.Result{}, nil } @@ -187,29 +155,11 @@ func (r *ReconcileSync) Reconcile(ctx context.Context, request reconcile.Request return reconcile.Result{}, err } - // namespace is excluded from sync - isExcludedNamespace, err := r.skipExcludedNamespace(instance) - if err != nil { - log.Error(err, "error while excluding namespaces") - } - - if isExcludedNamespace { - // cancel expectations - t := r.tracker.ForData(instance.GroupVersionKind()) - t.CancelExpect(instance) - return reconcile.Result{}, nil - } - if !instance.GetDeletionTimestamp().IsZero() { - if _, err := r.opa.RemoveData(ctx, instance); err != nil { + if err := r.cm.RemoveObject(ctx, instance); err != nil { return reconcile.Result{}, err } - // cancel expectations - t := r.tracker.ForData(instance.GroupVersionKind()) - t.CancelExpect(instance) - - r.metricsCache.DeleteObject(syncKey) reportMetrics = true return reconcile.Result{}, nil } @@ -222,106 +172,10 @@ func (r *ReconcileSync) Reconcile(ctx context.Context, request reconcile.Request logging.ResourceName, instance.GetName(), ) - if _, err := r.opa.AddData(ctx, instance); err != nil { - r.metricsCache.AddObject(syncKey, Tags{ - Kind: instance.GetKind(), - Status: metrics.ErrorStatus, - }) - reportMetrics = true - + reportMetrics = true + if err := r.cm.AddObject(ctx, instance); err != nil { return reconcile.Result{}, err } - r.tracker.ForData(gvk).Observe(instance) - log.V(1).Info("[readiness] observed data", "gvk", gvk, "namespace", instance.GetNamespace(), "name", instance.GetName()) - - r.metricsCache.AddObject(syncKey, Tags{ - Kind: instance.GetKind(), - Status: metrics.ActiveStatus, - }) - - r.metricsCache.addKind(instance.GetKind()) - - reportMetrics = true return reconcile.Result{}, nil } - -func (r *ReconcileSync) skipExcludedNamespace(obj *unstructured.Unstructured) (bool, error) { - isNamespaceExcluded, err := r.processExcluder.IsNamespaceExcluded(process.Sync, obj) - if err != nil { - return false, err - } - - return isNamespaceExcluded, err -} - -func NewMetricsCache() *MetricsCache { - return &MetricsCache{ - Cache: make(map[string]Tags), - KnownKinds: make(map[string]bool), - } -} - -func (c *MetricsCache) GetSyncKey(namespace string, name string) string { - return strings.Join([]string{namespace, name}, "/") -} - -// need to know encountered kinds to reset metrics for that kind -// this is a known memory leak -// footprint should naturally reset on Pod upgrade b/c the container restarts. -func (c *MetricsCache) addKind(key string) { - c.mux.Lock() - defer c.mux.Unlock() - - c.KnownKinds[key] = true -} - -func (c *MetricsCache) ResetCache() { - c.mux.Lock() - defer c.mux.Unlock() - - c.Cache = make(map[string]Tags) -} - -func (c *MetricsCache) AddObject(key string, t Tags) { - c.mux.Lock() - defer c.mux.Unlock() - - c.Cache[key] = Tags{ - Kind: t.Kind, - Status: t.Status, - } -} - -func (c *MetricsCache) DeleteObject(key string) { - c.mux.Lock() - defer c.mux.Unlock() - - delete(c.Cache, key) -} - -func (c *MetricsCache) ReportSync(reporter *Reporter) { - c.mux.RLock() - defer c.mux.RUnlock() - - totals := make(map[Tags]int) - for _, v := range c.Cache { - totals[v]++ - } - - for kind := range c.KnownKinds { - for _, status := range metrics.AllStatuses { - if err := reporter.reportSync( - Tags{ - Kind: kind, - Status: status, - }, - int64(totals[Tags{ - Kind: kind, - Status: status, - }])); err != nil { - log.Error(err, "failed to report sync") - } - } - } -} diff --git a/pkg/expansion/aggregate.go b/pkg/expansion/aggregate.go index 2e95f8c389b..2967a08ef17 100644 --- a/pkg/expansion/aggregate.go +++ b/pkg/expansion/aggregate.go @@ -3,10 +3,15 @@ package expansion import ( "fmt" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "github.com/open-policy-agent/frameworks/constraint/pkg/types" ) -const childMsgPrefix = "[Implied by %s]" +const ( + childMsgPrefix = "[Implied by %s]" + + ChildStatLabel = "Implied by" +) // AggregateResponses aggregates all responses from children into the parent. // Child result messages will be prefixed with a string to indicate the msg @@ -22,6 +27,22 @@ func AggregateResponses(templateName string, parent *types.Responses, child *typ } } +// AggregateStats aggregates all stats from the child Responses.StatsEntry +// into the parent Responses.StatsEntry. Child Stats will have a label to +// indicate that they come from an ExpansionTemplate usage. +func AggregateStats(templateName string, parent *types.Responses, child *types.Responses) { + childStatsEntries := child.StatsEntries + + for _, se := range childStatsEntries { + se.Labels = append(se.Labels, []*instrumentation.Label{{ + Name: ChildStatLabel, + Value: templateName, + }}...) + } + + parent.StatsEntries = append(parent.StatsEntries, child.StatsEntries...) +} + func OverrideEnforcementAction(action string, resps *types.Responses) { // If the enforcement action is empty, do not override if action == "" { diff --git a/pkg/expansion/aggregate_test.go b/pkg/expansion/aggregate_test.go index 8278a39db6c..549a420ce65 100644 --- a/pkg/expansion/aggregate_test.go +++ b/pkg/expansion/aggregate_test.go @@ -5,7 +5,9 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "github.com/open-policy-agent/frameworks/constraint/pkg/types" + "github.com/stretchr/testify/require" ) // addFn is used to easily build types.Responses within the tests. @@ -91,6 +93,82 @@ func TestAggregateResponses(t *testing.T) { } } +// Test_AggregateStats is meant to show that StatsEntry objects are properly added +// fron child to parent when using the AggregateStats function. IT IS NOT meant to +// test StatsEntry objects themselves. +func Test_AggregateStats(t *testing.T) { + tests := []struct { + name string + templateName string + parent *types.Responses + child *types.Responses + expectedStats int + }{ + { + name: "empty parent and child", + templateName: "testTemplate1", + parent: &types.Responses{}, + child: &types.Responses{}, + expectedStats: 0, + }, + { + name: "empty parent, single child", + templateName: "testTemplate2", + parent: &types.Responses{}, + child: &types.Responses{ + StatsEntries: []*instrumentation.StatsEntry{ + {Labels: []*instrumentation.Label{}}, + }, + }, + expectedStats: 1, + }, + { + name: "multiple children", + templateName: "testTemplate3", + parent: &types.Responses{ + StatsEntries: []*instrumentation.StatsEntry{ + {Labels: []*instrumentation.Label{}}, + }, + }, + child: &types.Responses{ + StatsEntries: []*instrumentation.StatsEntry{ + {Labels: []*instrumentation.Label{}}, + {Labels: []*instrumentation.Label{}}, + }, + }, + expectedStats: 3, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + parent := tc.parent + child := tc.child + AggregateStats(tc.templateName, parent, child) + + require.Len(t, parent.StatsEntries, tc.expectedStats) + + for _, se := range tc.parent.StatsEntries { + labelFound := false + for _, label := range se.Labels { + if label.Name == ChildStatLabel && label.Value == tc.templateName { + labelFound = true + break + } + } + + // note that, in practice, we shouldn't care for the len of se.Labels + // we only add the check in here to distinguish between the parent labels, + // which are 0, and the child labels which should have at least one element, + // the label that is added thru AggregateStats + if !labelFound && len(se.Labels) > 0 { + t.Errorf("expected label %s not found", ChildStatLabel) + } + } + }) + } +} + func TestOverrideEnforcementAction(t *testing.T) { tests := []struct { name string diff --git a/pkg/expansion/db.go b/pkg/expansion/db.go new file mode 100644 index 00000000000..b8eab62b98d --- /dev/null +++ b/pkg/expansion/db.go @@ -0,0 +1,290 @@ +package expansion + +import ( + "errors" + "fmt" + + "github.com/dominikbraun/graph" + expansionunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type templateDB interface { + upsert(*expansionunversioned.ExpansionTemplate) error + remove(*expansionunversioned.ExpansionTemplate) + templatesForGVK(gvk schema.GroupVersionKind) []*expansionunversioned.ExpansionTemplate + getConflicts() IDSet +} + +var _ templateDB = &db{} + +type adjList map[schema.GroupVersionKind]IDSet + +// hashID is passed to the graphing package. +var hashID = func(id TemplateID) string { + return string(id) +} + +type templateState struct { + template *expansionunversioned.ExpansionTemplate + hasConflicts bool +} + +type edge struct { + x TemplateID + y TemplateID +} + +type db struct { + store map[TemplateID]*templateState + + // graph stores a graph of ExpansionTemplate. A directed edge from template A + // to B means that the template A's `generatedGVK` matches template B's `applyTo`. + graph graph.Graph[string, TemplateID] + + // `matchers` and `generators` creates the necessary mappings to be able to + // determine the inbound and outbound edges of a given template in O(1). + // matchers is a mapping of GVKs to templates that match (applyTo) that GVK. + matchers adjList + // generators is a mapping of GVKs to templates that generate that GVK. + generators adjList +} + +func newDB() *db { + return &db{ + store: make(map[TemplateID]*templateState), + graph: graph.New(hashID, graph.Directed()), + matchers: make(adjList), + generators: make(adjList), + } +} + +func (d *db) getConflicts() IDSet { + confs := make(IDSet) + for tID, tState := range d.store { + if tState.hasConflicts { + confs[tID] = true + } + } + return confs +} + +// handleAdd adds the template to the DB, returning true if a cycle was created. +// The template is added even if a cycle was found. +func (d *db) handleAdd(template *expansionunversioned.ExpansionTemplate) (bool, error) { + id := keyForTemplate(template) + + // We should always remove the old template before handleAdd. If we + // didn't, that's a bug. + if _, exists := d.store[id]; exists { + panic(fmt.Errorf("tried to add template %q that already exists", id)) + } + + // Update storage + d.store[id] = &templateState{template: template.DeepCopy(), hasConflicts: false} + + // Update generators + genGVK := genGVKToSchemaGVK(template.Spec.GeneratedGVK) + if _, exists := d.generators[genGVK]; !exists { + d.generators[genGVK] = make(map[TemplateID]bool) + } + d.generators[genGVK][id] = true + + // Update matchers + matches := applyToGVKs(template) + for _, m := range matches { + if _, exists := d.matchers[m]; !exists { + d.matchers[m] = make(map[TemplateID]bool) + } + d.matchers[m][id] = true + } + + // Add vertex if DNE + if _, err := d.graph.Vertex(hashID(id)); err != nil { + if errors.Is(err, graph.ErrVertexNotFound) { + if err := d.graph.AddVertex(id); err != nil { + return false, fmt.Errorf("adding vertex to graph: %w", err) + } + } else { + return false, fmt.Errorf("unexpected error getting vertex for template %s: %w", id, err) + } + } + + // Add edges + edges := d.edgesForTemplate(template) + cycle := false + for _, e := range edges { + from := hashID(e.x) + to := hashID(e.y) + + createsCycle, err := graph.CreatesCycle(d.graph, from, to) + if err != nil { + return false, fmt.Errorf("checking cycle for template %s: %w", id, err) + } + cycle = createsCycle || cycle + + if err = d.graph.AddEdge(from, to); err != nil { + return false, fmt.Errorf("adding edge for template %s: %w", id, err) + } + } + + return cycle, nil +} + +func (d *db) edgesForTemplate(template *expansionunversioned.ExpansionTemplate) []edge { + var edges []edge + id := keyForTemplate(template) + genGVK := genGVKToSchemaGVK(template.Spec.GeneratedGVK) + + // Add out-bound edges (from this template's generated GVK to other + // templates' matched GVKs) + for t := range d.matchers[genGVK] { + edges = append(edges, edge{id, t}) + } + + // Add in-bound edges (from other templates' generated GVK to this template's + // matched GVK) + for _, gen := range applyToGVKs(template) { + for t := range d.generators[gen] { + edges = append(edges, edge{t, id}) + } + } + + return edges +} + +func (d *db) handleRemove(id TemplateID) { + // The template must exist. Existence checks should be done upstream. + if _, exists := d.store[id]; !exists { + panic(fmt.Errorf("called handleRemove for template %q, but template DNE in store", id)) + } + template := d.store[id].template + + // Update storage + delete(d.store, id) + + // Update generators + genGVK := genGVKToSchemaGVK(template.Spec.GeneratedGVK) + if _, exists := d.generators[genGVK]; exists { + delete(d.generators[genGVK], id) + if len(d.generators[genGVK]) == 0 { + delete(d.generators, genGVK) + } + } else { + panic(fmt.Errorf("[template %q] inconsistent db - expected key %s to exist in generators", id, genGVK)) + } + + // Update matchers + matches := applyToGVKs(template) + for _, m := range matches { + if _, exists := d.matchers[m]; exists { + delete(d.matchers[m], id) + if len(d.matchers[m]) == 0 { + delete(d.matchers, m) + } + } else { + panic(fmt.Errorf("[template %q] inconsistent db - expected key %s to exist in matches", id, m)) + } + } + + // Remove edges + edges := d.edgesForTemplate(template) + for _, e := range edges { + from := hashID(e.x) + to := hashID(e.y) + if err := d.graph.RemoveEdge(from, to); err != nil { + panic(fmt.Errorf("[template %q] unexpected error removing edge: %w", id, err)) + } + } +} + +func (d *db) updateCycles() { + // First reset all conflicts + for _, ts := range d.store { + ts.hasConflicts = false + } + + conflicts, err := graph.StronglyConnectedComponents(d.graph) + if err != nil { + panic(fmt.Errorf("error getting SCCs: %w", err)) + } + // All strongly connect components containing more than 1 vertex are a cycle + for _, scc := range conflicts { + if len(scc) <= 1 { + continue + } + for _, id := range scc { + d.store[TemplateID(id)].hasConflicts = true + } + } +} + +func (d *db) upsert(template *expansionunversioned.ExpansionTemplate) error { + id := keyForTemplate(template) + old, hasOld := d.store[id] + if hasOld { + d.handleRemove(id) + } + + newCycle, err := d.handleAdd(template) + if err != nil { + return fmt.Errorf("adding template to db: %w", err) + } + // If the new/updated template caused a cycle, or the previous template belonged + // to a cycle, then we need to re-check the graph for cycles + if newCycle || (hasOld && old.hasConflicts) { + d.updateCycles() + } + + if newCycle { + return fmt.Errorf("template forms expansion cycle") + } + return nil +} + +func (d *db) remove(template *expansionunversioned.ExpansionTemplate) { + id := keyForTemplate(template) + old, exists := d.store[id] + if !exists { + return + } + + d.handleRemove(id) + // If the removed template was part of a cycle, we need to recheck the graph + // in case that cycle was resolved + if old.hasConflicts { + d.updateCycles() + } +} + +func (d *db) templatesForGVK(gvk schema.GroupVersionKind) []*expansionunversioned.ExpansionTemplate { + var tset []*expansionunversioned.ExpansionTemplate + for tID := range d.matchers[gvk] { + // Sanity check. In theory, this should never happen, but if it does, we + // can't recover. + if _, exists := d.store[tID]; !exists { + panic(fmt.Errorf("inconsistent db - key %s exists in matchers but not cache", tID)) + } + + tState := d.store[tID] + if !tState.hasConflicts { + tset = append(tset, tState.template) + } + } + + return tset +} + +func applyToGVKs(template *expansionunversioned.ExpansionTemplate) []schema.GroupVersionKind { + var gvks []schema.GroupVersionKind + for _, apply := range template.Spec.ApplyTo { + for _, g := range apply.Groups { + for _, v := range apply.Versions { + for _, k := range apply.Kinds { + gvks = append(gvks, schema.GroupVersionKind{Group: g, Version: v, Kind: k}) + } + } + } + } + return gvks +} diff --git a/pkg/expansion/db_test.go b/pkg/expansion/db_test.go new file mode 100644 index 00000000000..0ea713f6eca --- /dev/null +++ b/pkg/expansion/db_test.go @@ -0,0 +1,799 @@ +package expansion + +import ( + "sort" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion/fixtures" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + addOp = "UPSERT" + rmOp = "REMOVE" +) + +type templateOperation struct { + op string + template unversioned.ExpansionTemplate + + // wantErr is only relevant for add operations. + wantErr bool +} + +func TestDB(t *testing.T) { + tests := []struct { + name string + ops []templateOperation + wantMatchers adjList + wantGenerators adjList + wantStore map[TemplateID]*templateState + }{ + { + name: "add 1 template", + ops: []templateOperation{ + { + op: addOp, + template: *fixtures.TestTemplate("foo", 1, 2), + wantErr: false, + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): { + template: fixtures.TestTemplate("foo", 1, 2), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{ + Group: "group1", + Version: "v1", + Kind: "kind1", + }: { + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{ + Group: "group2", + Version: "v2", + Kind: "kind2", + }: { + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): true, + }, + }, + }, + { + name: "add 1 template that has many applyTo", + ops: []templateOperation{ + { + op: addOp, + template: *fixtures.TempMultApply(), + wantErr: false, + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TempMultApply()): { + template: fixtures.TempMultApply(), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TempMultApply()): true, + }, + schema.GroupVersionKind{Group: "group11", Version: "v11", Kind: "kind11"}: { + keyForTemplate(fixtures.TempMultApply()): true, + }, + schema.GroupVersionKind{Group: "group11", Version: "v22", Kind: "kind11"}: { + keyForTemplate(fixtures.TempMultApply()): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TempMultApply()): true, + }, + }, + }, + { + name: "add 2 templates with same applyTo and genGVK", + ops: []templateOperation{ + { + op: addOp, + template: *fixtures.TestTemplate("t1", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2", 1, 2), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t1", 1, 2)): { + template: fixtures.TestTemplate("t1", 1, 2), + hasConflicts: false, + }, + keyForTemplate(fixtures.TestTemplate("t2", 1, 2)): { + template: fixtures.TestTemplate("t2", 1, 2), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{ + Group: "group1", + Version: "v1", + Kind: "kind1", + }: { + keyForTemplate(fixtures.TestTemplate("t1", 1, 2)): true, + keyForTemplate(fixtures.TestTemplate("t2", 1, 2)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{ + Group: "group2", + Version: "v2", + Kind: "kind2", + }: { + keyForTemplate(fixtures.TestTemplate("t1", 1, 2)): true, + keyForTemplate(fixtures.TestTemplate("t2", 1, 2)): true, + }, + }, + }, + { + name: "removing non-existing template does nothing", + ops: []templateOperation{ + { + op: addOp, + template: *fixtures.TestTemplate("foo", 1, 2), + }, + { + op: rmOp, + template: *fixtures.TestTemplate("DNE", 1, 2), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): { + template: fixtures.TestTemplate("foo", 1, 2), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("foo", 1, 2)): true, + }, + }, + }, + { + name: "update existing template", + ops: []templateOperation{ + { + op: addOp, + template: *fixtures.TestTemplate("foo", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("foo", 3, 4), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("foo", 3, 4)): { + template: fixtures.TestTemplate("foo", 3, 4), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("foo", 3, 4)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group4", Version: "v4", Kind: "kind4"}: { + keyForTemplate(fixtures.TestTemplate("foo", 3, 4)): true, + }, + }, + }, + { + name: "adding cycle disables cyclic templates and leaves non-cyclic enabled", + ops: []templateOperation{ + // t1 -> t2 -> t3 -> t1 -> ... forms cycle + { + op: addOp, + template: *fixtures.TestTemplate("t1-2", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2-3", 2, 3), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + wantErr: true, + }, + // t2-8 is "touching" the cycle, but not part of it + { + op: addOp, + template: *fixtures.TestTemplate("t2-8", 2, 8), + }, + // t5 is completely disjoint from rest of graph + { + op: addOp, + template: *fixtures.TestTemplate("t5", 5, 6), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): { + template: fixtures.TestTemplate("t1-2", 1, 2), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): { + template: fixtures.TestTemplate("t2-3", 2, 3), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 1)): { + template: fixtures.TestTemplate("t3-1", 3, 1), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t2-8", 2, 8)): { + template: fixtures.TestTemplate("t2-8", 2, 8), + hasConflicts: false, + }, + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): { + template: fixtures.TestTemplate("t5", 5, 6), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + keyForTemplate(fixtures.TestTemplate("t2-8", 2, 8)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 1)): true, + }, + schema.GroupVersionKind{Group: "group5", Version: "v5", Kind: "kind5"}: { + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 1)): true, + }, + schema.GroupVersionKind{Group: "group6", Version: "v6", Kind: "kind6"}: { + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): true, + }, + schema.GroupVersionKind{Group: "group8", Version: "v8", Kind: "kind8"}: { + keyForTemplate(fixtures.TestTemplate("t2-8", 2, 8)): true, + }, + }, + }, + { + name: "update template to produce cycle", + ops: []templateOperation{ + // t5 is completely disjoint from rest of graph + { + op: addOp, + template: *fixtures.TestTemplate("t5", 5, 6), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t3-4", 3, 4), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t1-2", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2-3", 2, 3), + }, + // update 3-4 to form a cycle + { + op: addOp, + template: *fixtures.TestTemplate("t3-4", 3, 1), + wantErr: true, + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): { + template: fixtures.TestTemplate("t1-2", 1, 2), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): { + template: fixtures.TestTemplate("t2-3", 2, 3), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t3-4", 1, 1)): { + template: fixtures.TestTemplate("t3-4", 3, 1), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): { + template: fixtures.TestTemplate("t5", 5, 6), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t3-4", 3, 4)): true, + }, + schema.GroupVersionKind{Group: "group5", Version: "v5", Kind: "kind5"}: { + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t3-4", 3, 1)): true, + }, + schema.GroupVersionKind{Group: "group6", Version: "v6", Kind: "kind6"}: { + keyForTemplate(fixtures.TestTemplate("t5", 5, 6)): true, + }, + }, + }, + { + name: "fixing cycle re-enables templates but existing cycles still disabled", + ops: []templateOperation{ + // t7-8 and t8-7 form a cycle unconnected to the t1-t2-t3 cycle + { + op: addOp, + template: *fixtures.TestTemplate("t7-8", 7, 8), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t8-7", 8, 7), + wantErr: true, + }, + // t1 -> t2 -> t3 -> t1 -> ... forms cycle + { + op: addOp, + template: *fixtures.TestTemplate("t1-2", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2-3", 2, 3), + }, + // t3-1 produces cycle + { + op: addOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + wantErr: true, + }, + // fix t3-1 to behavior like t3-4, thus fixing cycle + { + op: addOp, + template: *fixtures.TestTemplate("t3-1", 3, 4), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): { + template: fixtures.TestTemplate("t7-8", 7, 8), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): { + template: fixtures.TestTemplate("t8-7", 8, 7), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): { + template: fixtures.TestTemplate("t1-2", 1, 2), + hasConflicts: false, + }, + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): { + template: fixtures.TestTemplate("t2-3", 2, 3), + hasConflicts: false, + }, + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 4)): { + template: fixtures.TestTemplate("t3-1", 3, 4), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 1)): true, + }, + schema.GroupVersionKind{Group: "group7", Version: "v7", Kind: "kind7"}: { + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): true, + }, + schema.GroupVersionKind{Group: "group8", Version: "v8", Kind: "kind8"}: { + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group4", Version: "v4", Kind: "kind4"}: { + keyForTemplate(fixtures.TestTemplate("t3-1", 3, 4)): true, + }, + schema.GroupVersionKind{Group: "group8", Version: "v8", Kind: "kind8"}: { + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): true, + }, + schema.GroupVersionKind{Group: "group7", Version: "v7", Kind: "kind7"}: { + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): true, + }, + }, + }, + { + name: "removing cycle re-enables templates but existing cycles still disabled", + ops: []templateOperation{ + // t7-8 and t8-7 form a cycle unconnected to the t1-t2-t3 cycle + { + op: addOp, + template: *fixtures.TestTemplate("t7-8", 7, 8), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t8-7", 8, 7), + wantErr: true, + }, + // t1 -> t2 -> t3 -> t1 -> ... forms cycle + { + op: addOp, + template: *fixtures.TestTemplate("t1-2", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2-3", 2, 3), + }, + // t3-1 produces cycle + { + op: addOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + wantErr: true, + }, + // remove t3-1 to fix cycle + { + op: rmOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): { + template: fixtures.TestTemplate("t7-8", 7, 8), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): { + template: fixtures.TestTemplate("t8-7", 8, 7), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): { + template: fixtures.TestTemplate("t1-2", 1, 2), + hasConflicts: false, + }, + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): { + template: fixtures.TestTemplate("t2-3", 2, 3), + hasConflicts: false, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group7", Version: "v7", Kind: "kind7"}: { + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): true, + }, + schema.GroupVersionKind{Group: "group8", Version: "v8", Kind: "kind8"}: { + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group8", Version: "v8", Kind: "kind8"}: { + keyForTemplate(fixtures.TestTemplate("t7-8", 7, 8)): true, + }, + schema.GroupVersionKind{Group: "group7", Version: "v7", Kind: "kind7"}: { + keyForTemplate(fixtures.TestTemplate("t8-7", 8, 7)): true, + }, + }, + }, + { + name: "removing 1 edge from double-edged cycle does not re-enable templates", + ops: []templateOperation{ + // t1 -> t2 -> t3 -> t1 -> ... forms cycle + { + op: addOp, + template: *fixtures.TestTemplate("t1-2", 1, 2), + }, + { + op: addOp, + template: *fixtures.TestTemplate("t2-3", 2, 3), + }, + // t3-1 produces cycle + { + op: addOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + wantErr: true, + }, + // ta3-1 produces double-edged cycle + { + op: addOp, + template: *fixtures.TestTemplate("ta3-1", 3, 1), + wantErr: true, + }, + // remove t3-1, but cycle still exists with ta3-1 + { + op: rmOp, + template: *fixtures.TestTemplate("t3-1", 3, 1), + }, + }, + wantStore: map[TemplateID]*templateState{ + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): { + template: fixtures.TestTemplate("t1-2", 1, 2), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): { + template: fixtures.TestTemplate("t2-3", 2, 3), + hasConflicts: true, + }, + keyForTemplate(fixtures.TestTemplate("ta3-1", 3, 1)): { + template: fixtures.TestTemplate("ta3-1", 3, 1), + hasConflicts: true, + }, + }, + wantMatchers: adjList{ + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("ta3-1", 3, 1)): true, + }, + }, + wantGenerators: adjList{ + schema.GroupVersionKind{Group: "group2", Version: "v2", Kind: "kind2"}: { + keyForTemplate(fixtures.TestTemplate("t1-2", 1, 2)): true, + }, + schema.GroupVersionKind{Group: "group3", Version: "v3", Kind: "kind3"}: { + keyForTemplate(fixtures.TestTemplate("t2-3", 2, 3)): true, + }, + schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}: { + keyForTemplate(fixtures.TestTemplate("ta3-1", 3, 1)): true, + }, + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDB() + + // Execute all the upsert/remove calls + executeOps(d, tc.ops, t) + + if df := cmp.Diff(d.matchers, tc.wantMatchers); df != "" { + t.Errorf("got matchers: %v\nbut want: %v\ndiff: %s", d.matchers, tc.wantMatchers, df) + } + + if df := cmp.Diff(d.generators, tc.wantGenerators); df != "" { + t.Errorf("got generators: %v\nbut want: %v\ndiff: %s", d.generators, tc.wantGenerators, df) + } + + if df := cmp.Diff(d.store, tc.wantStore, cmp.AllowUnexported(templateState{})); df != "" { + t.Errorf("got store: %v\nbut want: %v\ndiff: %s", d.generators, tc.wantGenerators, df) + } + }) + } +} + +func executeOps(db templateDB, ops []templateOperation, t *testing.T) { + for i := 0; i < len(ops); i++ { + op := ops[i] + switch op.op { + case addOp: + gotErr := db.upsert(&op.template) + if op.wantErr { + require.Error(t, gotErr, "want err: %t, got: %s", op.wantErr, gotErr) + } else if gotErr != nil { + t.Errorf("unexpected err upserting: %v", gotErr) + } + case rmOp: + if op.wantErr { + t.Fatalf("cannot set errFn for remove operation") + } + db.remove(&op.template) + default: + t.Fatalf("unrecognized operation: %s", op.op) + } + } +} + +func sortTemplates(temps []*unversioned.ExpansionTemplate) { + sort.Slice(temps, func(i, j int) bool { + return keyForTemplate(temps[i]) > keyForTemplate(temps[j]) + }) +} + +func TestTemplatesForGVK(t *testing.T) { + tests := []struct { + name string + add []*unversioned.ExpansionTemplate + gvk schema.GroupVersionKind + want []*unversioned.ExpansionTemplate + }{ + { + name: "no templates in db returns nothing", + gvk: schema.GroupVersionKind{Group: "a", Version: "b", Kind: "c"}, + }, + { + name: "2 templates no cycles", + gvk: schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}, + add: []*unversioned.ExpansionTemplate{ + fixtures.TestTemplate("t1-2", 1, 2), + fixtures.TestTemplate("t2-3", 2, 3), + }, + want: []*unversioned.ExpansionTemplate{ + fixtures.TestTemplate("t1-2", 1, 2), + }, + }, + { + name: "cycle not returned", + gvk: schema.GroupVersionKind{Group: "group1", Version: "v1", Kind: "kind1"}, + add: []*unversioned.ExpansionTemplate{ + fixtures.TestTemplate("t1-2", 1, 2), + fixtures.TestTemplate("t2-3", 2, 3), + fixtures.TestTemplate("t3-1", 3, 1), + }, + }, + { + name: "cycle not returned but non-cyclics are", + gvk: schema.GroupVersionKind{Group: "group4", Version: "v4", Kind: "kind4"}, + add: []*unversioned.ExpansionTemplate{ + fixtures.TestTemplate("t1-2", 1, 2), + fixtures.TestTemplate("t2-3", 2, 3), + fixtures.TestTemplate("t3-1", 3, 1), + fixtures.TestTemplate("t4-5", 4, 5), + fixtures.TestTemplate("t4-6", 4, 6), + }, + want: []*unversioned.ExpansionTemplate{ + fixtures.TestTemplate("t4-5", 4, 5), + fixtures.TestTemplate("t4-6", 4, 6), + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDB() + for _, t := range tc.add { + _ = d.upsert(t) + } + + got := d.templatesForGVK(tc.gvk) + sortTemplates(got) + sortTemplates(tc.want) + + require.Len(t, got, len(tc.want)) + for i := 0; i < len(got); i++ { + if diff := cmp.Diff(got[i], tc.want[i]); diff != "" { + t.Errorf("got template %v\nwanted: %v\ndiff: %s", got[i], tc.want[i], diff) + } + } + }) + } +} + +func TestGetConflicts(t *testing.T) { + tests := []struct { + name string + seed []templateState + want map[TemplateID]bool + }{ + { + name: "empty db, empty conflicts", + }, + { + name: "2 conflicts", + seed: []templateState{ + { + hasConflicts: true, + template: fixtures.TestTemplate("t1-2", 1, 2), + }, + { + hasConflicts: true, + template: fixtures.TestTemplate("t2-1", 2, 1), + }, + }, + want: map[TemplateID]bool{ + "t1-2": true, + "t2-1": true, + }, + }, + { + name: "2 conflicts, 1 non", + seed: []templateState{ + { + hasConflicts: true, + template: fixtures.TestTemplate("t1-2", 1, 2), + }, + { + hasConflicts: true, + template: fixtures.TestTemplate("t2-1", 2, 1), + }, + { + hasConflicts: false, + template: fixtures.TestTemplate("t4-5", 4, 5), + }, + }, + want: map[TemplateID]bool{ + "t1-2": true, + "t2-1": true, + }, + }, + { + name: "no conflicts", + seed: []templateState{ + { + hasConflicts: false, + template: fixtures.TestTemplate("t1-2", 1, 2), + }, + { + hasConflicts: false, + template: fixtures.TestTemplate("t2-3", 2, 3), + }, + { + hasConflicts: false, + template: fixtures.TestTemplate("t4-5", 4, 5), + }, + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDB() + for i := range tc.seed { + d.store[keyForTemplate(tc.seed[i].template)] = &tc.seed[i] + } + + got := d.getConflicts() + + require.Len(t, got, len(tc.want)) + for k := range tc.want { + if _, exists := got[k]; !exists { + t.Errorf("wanted template ID %s, but not returned", k) + } + } + }) + } +} diff --git a/pkg/expansion/fixtures/fixtures.go b/pkg/expansion/fixtures/fixtures.go index 94dbafb6649..088f4a1a18d 100644 --- a/pkg/expansion/fixtures/fixtures.go +++ b/pkg/expansion/fixtures/fixtures.go @@ -2,7 +2,7 @@ package fixtures const ( TempExpDeploymentExpandsPods = ` -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-deployments @@ -18,8 +18,79 @@ spec: version: "v1" ` + TempExpReplicaDeploymentExpandsPods = ` +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-deployments-replicas +spec: + applyTo: + - groups: ["apps"] + kinds: ["Deployment", "ReplicaSet"] + versions: ["v1"] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" +` + + TempExpMultipleApplyTo = ` +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-many-things +spec: + applyTo: + - groups: ["apps", "traps"] + kinds: ["Deployment", "ReplicaSet"] + versions: ["v1", "v1beta1"] + - groups: [""] + kinds: ["CoreKind"] + versions: ["v1"] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" +` + + TempExpCronJob = ` +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-cronjobs +spec: + applyTo: + - groups: ["batch"] + kinds: ["CronJob"] + versions: ["v1"] + templateSource: "spec.jobTemplate" + generatedGVK: + kind: "Job" + group: "batch" + version: "v1" +` + + TempExpJob = ` +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-jobs +spec: + applyTo: + - groups: ["batch"] + kinds: ["Job"] + versions: ["v1"] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" +` + TempExpDeploymentExpandsPodsEnforceDryrun = ` -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-deployments @@ -62,6 +133,33 @@ spec: - "/bin/sh" ` + DeploymentNginxWithNs = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx + namespace: not-default +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: '80' + args: + - "/bin/sh" +` + DeploymentNoGVK = ` metadata: name: nginx-deployment @@ -91,6 +189,7 @@ kind: Pod metadata: labels: app: nginx + name: nginx-deployment-pod namespace: default spec: containers: @@ -108,6 +207,7 @@ kind: Pod metadata: labels: app: nginx + name: nginx-deployment-pod namespace: default spec: containers: @@ -120,6 +220,43 @@ spec: - containerPort: '80' ` + PodImagePullMutateWithNs = ` +apiVersion: v1 +kind: Pod +metadata: + labels: + app: nginx + name: nginx-deployment-pod + namespace: not-default +spec: + containers: + - args: + - "/bin/sh" + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: '80' +` + + PodMutateImage = ` +apiVersion: v1 +kind: Pod +metadata: + labels: + app: nginx + name: nginx-deployment-pod + namespace: default +spec: + containers: + - args: + - "/bin/sh" + image: nginx:v2 + name: nginx + ports: + - containerPort: '80' +` + PodImagePullMutateAnnotated = ` apiVersion: v1 kind: Pod @@ -128,6 +265,7 @@ metadata: app: nginx annotations: owner: admin + name: nginx-deployment-pod namespace: default spec: containers: @@ -160,6 +298,33 @@ spec: kinds: - apiGroups: [] kinds: [] +` + + AssignPullImageWithNsSelector = ` +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: Assign +metadata: + name: always-pull-image +spec: + applyTo: + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + location: "spec.containers[name: *].imagePullPolicy" + parameters: + assign: + value: "Always" + match: + source: "Generated" + scope: Namespaced + kinds: + - apiGroups: [] + kinds: [] + namespaceSelector: + matchExpressions: + - key: admission.gatekeeper.sh/ignore + operator: DoesNotExist + ` AssignPullImageSourceAll = ` @@ -205,6 +370,21 @@ spec: kinds: [] ` + AssignImage = ` +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: tag-v2 +spec: + applyTo: + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + location: "spec.containers[name:nginx].image" + parameters: + assignTag: ":v2" +` + AssignHostnameSourceOriginal = ` apiVersion: mutations.gatekeeper.sh/v1alpha1 kind: Assign @@ -263,7 +443,7 @@ spec: ` TemplateCatExpandsKitten = ` -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-cats-kitten @@ -281,7 +461,7 @@ spec: ` TemplateCatExpandsPurr = ` -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-cats-purr @@ -364,6 +544,7 @@ metadata: sound: meow labels: fluffy: extremely + name: big-chungus-kitten namespace: default spec: breed: calico @@ -377,8 +558,68 @@ kind: Purr metadata: annotations: shouldPet: manytimes + name: big-chungus-purr namespace: default spec: loud: very ` + + GeneratorCronJob = ` +apiVersion: batch/v1 +kind: CronJob +metadata: + name: my-cronjob +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - args: + - "/bin/sh" + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: '80' +` + + ResultantJob = ` +apiVersion: batch/v1 +kind: Job +metadata: + name: my-cronjob-job + namespace: default +spec: + template: + spec: + containers: + - args: + - "/bin/sh" + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: '80' +` + + ResultantRecursivePod = ` +apiVersion: v1 +kind: Pod +metadata: + annotations: + owner: admin + name: my-cronjob-job-pod + namespace: default +spec: + containers: + - args: + - "/bin/sh" + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: '80' +` ) diff --git a/pkg/expansion/fixtures/load.go b/pkg/expansion/fixtures/load.go new file mode 100644 index 00000000000..672986e2991 --- /dev/null +++ b/pkg/expansion/fixtures/load.go @@ -0,0 +1,166 @@ +package fixtures + +import ( + "encoding/json" + "fmt" + "testing" + + expansionunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignimage" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignmeta" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "gopkg.in/yaml.v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +type TemplateData struct { + Name string + Apply []match.ApplyTo + Source string + GenGVK expansionunversioned.GeneratedGVK + EnforcementAction string +} + +func NewTemplate(data *TemplateData) *expansionunversioned.ExpansionTemplate { + return &expansionunversioned.ExpansionTemplate{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExpansionTemplate", + APIVersion: "expansiontemplates.gatekeeper.sh/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: data.Name, + }, + Spec: expansionunversioned.ExpansionTemplateSpec{ + ApplyTo: data.Apply, + TemplateSource: data.Source, + GeneratedGVK: data.GenGVK, + EnforcementAction: data.EnforcementAction, + }, + } +} + +func LoadFixture(f string, t *testing.T) *unstructured.Unstructured { + obj := make(map[string]interface{}) + if err := yaml.Unmarshal([]byte(f), obj); err != nil { + t.Fatalf("error unmarshaling yaml for fixture: %s\n%s", err, f) + } + + jsonBytes, err := json.Marshal(obj) + if err != nil { + t.Fatalf("error marshaling json for fixture: %s", err) + } + + if err = json.Unmarshal(jsonBytes, &obj); err != nil { + t.Fatalf("error unmarshaling json for fixture: %s", err) + } + + u := unstructured.Unstructured{} + u.SetUnstructuredContent(obj) + return &u +} + +func LoadTemplate(f string, t *testing.T) *expansionunversioned.ExpansionTemplate { + u := LoadFixture(f, t) + te := &expansionunversioned.ExpansionTemplate{} + err := convertUnstructuredToTyped(u, te) + if err != nil { + t.Fatalf("error converting template expansion: %s", err) + } + return te +} + +func LoadAssign(f string, t *testing.T) types.Mutator { + u := LoadFixture(f, t) + a := &mutationsunversioned.Assign{} + err := convertUnstructuredToTyped(u, a) + if err != nil { + t.Fatalf("error converting assign: %s", err) + } + mut, err := assign.MutatorForAssign(a) + if err != nil { + t.Fatalf("error creating assign: %s", err) + } + return mut +} + +func LoadAssignImage(f string, t *testing.T) types.Mutator { + u := LoadFixture(f, t) + a := &mutationsunversioned.AssignImage{} + err := convertUnstructuredToTyped(u, a) + if err != nil { + t.Fatalf("error converting assignImage: %s", err) + } + mut, err := assignimage.MutatorForAssignImage(a) + if err != nil { + t.Fatalf("error creating assignimage: %s", err) + } + return mut +} + +func LoadAssignMeta(f string, t *testing.T) types.Mutator { + u := LoadFixture(f, t) + a := &mutationsunversioned.AssignMetadata{} + err := convertUnstructuredToTyped(u, a) + if err != nil { + t.Fatalf("error converting assignmeta: %s", err) + } + mut, err := assignmeta.MutatorForAssignMetadata(a) + if err != nil { + t.Fatalf("error creating assignmeta: %s", err) + } + return mut +} + +func convertUnstructuredToTyped(u *unstructured.Unstructured, obj interface{}) error { + if u == nil { + return fmt.Errorf("cannot convert nil unstructured to type") + } + err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), obj) + return err +} + +func TestTemplate(name string, applyID, genID int) *expansionunversioned.ExpansionTemplate { + return NewTemplate(&TemplateData{ + Name: name, + Apply: []match.ApplyTo{{ + Groups: []string{fmt.Sprintf("group%d", applyID)}, + Versions: []string{fmt.Sprintf("v%d", applyID)}, + Kinds: []string{fmt.Sprintf("kind%d", applyID)}, + }}, + Source: "spec.template", + GenGVK: expansionunversioned.GeneratedGVK{ + Group: fmt.Sprintf("group%d", genID), + Version: fmt.Sprintf("v%d", genID), + Kind: fmt.Sprintf("kind%d", genID), + }, + }) +} + +func TempMultApply() *expansionunversioned.ExpansionTemplate { + return NewTemplate(&TemplateData{ + Name: "t2", + Apply: []match.ApplyTo{ + { + Groups: []string{"group1"}, + Versions: []string{"v1"}, + Kinds: []string{"kind1"}, + }, + { + Groups: []string{"group11"}, + Versions: []string{"v11", "v22"}, + Kinds: []string{"kind11"}, + }, + }, + Source: "spec.template", + GenGVK: expansionunversioned.GeneratedGVK{ + Group: "group2", + Version: "v2", + Kind: "kind2", + }, + }) +} diff --git a/pkg/expansion/system.go b/pkg/expansion/system.go index 59818172fd9..5287b159726 100644 --- a/pkg/expansion/system.go +++ b/pkg/expansion/system.go @@ -2,22 +2,39 @@ package expansion import ( "encoding/json" + "flag" "fmt" "strings" "sync" - expansionunversioned "github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + expansionunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + logf "sigs.k8s.io/controller-runtime/pkg/log" ) +var ( + ExpansionEnabled *bool + log = logf.Log.WithName("expansion").WithValues(logging.Process, "expansion") +) + +// maxRecursionDepth specifies the maximum call depth for recursive expansion. +// Theoretically, it should be impossible for a cycle to be created but this +// measure is put in place as a safeguard. +const maxRecursionDepth = 30 + +func init() { + ExpansionEnabled = flag.Bool("enable-generator-resource-expansion", true, "(beta) Enable the expansion of generator resources") +} + type System struct { lock sync.RWMutex - templates map[string]*expansionunversioned.ExpansionTemplate mutationSystem *mutation.System + db templateDB } type Resultant struct { @@ -26,20 +43,24 @@ type Resultant struct { EnforcementAction string } -func keyForTemplate(template *expansionunversioned.ExpansionTemplate) string { - return template.ObjectMeta.Name +type TemplateID string + +type IDSet map[TemplateID]bool + +func keyForTemplate(template *expansionunversioned.ExpansionTemplate) TemplateID { + return TemplateID(template.ObjectMeta.Name) } func (s *System) UpsertTemplate(template *expansionunversioned.ExpansionTemplate) error { s.lock.Lock() defer s.lock.Unlock() + log.V(1).Info("upserting ExpansionTemplate", "template name", template.GetName()) - if err := validateTemplate(template); err != nil { + if err := ValidateTemplate(template); err != nil { return err } - s.templates[keyForTemplate(template)] = template.DeepCopy() - return nil + return s.db.upsert(template) } func (s *System) RemoveTemplate(template *expansionunversioned.ExpansionTemplate) error { @@ -51,11 +72,15 @@ func (s *System) RemoveTemplate(template *expansionunversioned.ExpansionTemplate return fmt.Errorf("cannot remove template with empty name") } - delete(s.templates, k) + s.db.remove(template) return nil } -func validateTemplate(template *expansionunversioned.ExpansionTemplate) error { +func (s *System) GetConflicts() IDSet { + return s.db.getConflicts() +} + +func ValidateTemplate(template *expansionunversioned.ExpansionTemplate) error { k := keyForTemplate(template) if k == "" { return fmt.Errorf("ExpansionTemplate has empty name field") @@ -66,6 +91,18 @@ func validateTemplate(template *expansionunversioned.ExpansionTemplate) error { if template.Spec.GeneratedGVK == (expansionunversioned.GeneratedGVK{}) { return fmt.Errorf("ExpansionTemplate %s has empty generatedGVK field", k) } + if len(template.Spec.ApplyTo) == 0 { + return fmt.Errorf("ExpansionTemplate %s must specify ApplyTo", k) + } + // Make sure template does not form a self-edge (i.e. a template configured + // to expand its own output) + genGVK := genGVKToSchemaGVK(template.Spec.GeneratedGVK) + for _, apply := range template.Spec.ApplyTo { + if apply.Matches(genGVK) { + return fmt.Errorf("ExpansionTemplate %s generates GVK %v, but also applies to that same GVK", k, genGVK) + } + } + return nil } @@ -89,34 +126,54 @@ func genGVKToSchemaGVK(gvk expansionunversioned.GeneratedGVK) schema.GroupVersio } } -// templatesForGVK returns a slice of ExpansionTemplates that match a given gvk. -func (s *System) templatesForGVK(gvk schema.GroupVersionKind) []*expansionunversioned.ExpansionTemplate { +// Expand expands `base` into resultant resources, and applies any applicable +// mutators. If no ExpansionTemplates match `base`, an empty slice +// will be returned. If `s.mutationSystem` is nil, no mutations will be applied. +func (s *System) Expand(base *mutationtypes.Mutable) ([]*Resultant, error) { s.lock.RLock() defer s.lock.RUnlock() - var templates []*expansionunversioned.ExpansionTemplate - for _, t := range s.templates { - for _, apply := range t.Spec.ApplyTo { - if apply.Matches(gvk) { - templates = append(templates, t) - } + var res []*Resultant + if err := s.expandRecursive(base, &res, 0); err != nil { + return nil, err + } + return res, nil +} + +func (s *System) expandRecursive(base *mutationtypes.Mutable, resultants *[]*Resultant, depth int) error { + if depth >= maxRecursionDepth { + return fmt.Errorf("maximum recursion depth of %d reached", maxRecursionDepth) + } + + res, err := s.expand(base) + if err != nil { + return err + } + + for _, r := range res { + mut := &mutationtypes.Mutable{ + Object: r.Obj, + Namespace: base.Namespace, + Username: base.Username, + Source: base.Source, + } + if err := s.expandRecursive(mut, resultants, depth+1); err != nil { + return err } } - return templates + *resultants = append(*resultants, res...) + return nil } -// Expand expands `base` into resultant resources, and applies any applicable -// mutators. If no ExpansionTemplates match `base`, an empty slice -// will be returned. If `s.mutationSystem` is nil, no mutations will be applied. -func (s *System) Expand(base *mutationtypes.Mutable) ([]*Resultant, error) { +func (s *System) expand(base *mutationtypes.Mutable) ([]*Resultant, error) { gvk := base.Object.GroupVersionKind() if gvk == (schema.GroupVersionKind{}) { return nil, fmt.Errorf("cannot expand resource %s with empty GVK", base.Object.GetName()) } var resultants []*Resultant - templates := s.templatesForGVK(gvk) + templates := s.db.templatesForGVK(gvk) for _, te := range templates { res, err := expandResource(base.Object, base.Namespace, te) @@ -143,7 +200,7 @@ func (s *System) Expand(base *mutationtypes.Mutable) ([]*Resultant, error) { } _, err := s.mutationSystem.Mutate(mutable) if err != nil { - return nil, fmt.Errorf("failed to mutate resultant resource %s: %s", res.Obj.GetName(), err) + return nil, fmt.Errorf("failed to mutate resultant resource %s: %w", res.Obj.GetName(), err) } } @@ -151,10 +208,6 @@ func (s *System) Expand(base *mutationtypes.Mutable) ([]*Resultant, error) { } func expandResource(obj *unstructured.Unstructured, ns *corev1.Namespace, template *expansionunversioned.ExpansionTemplate) (*unstructured.Unstructured, error) { - if ns == nil { - return nil, fmt.Errorf("cannot expand resource with nil namespace") - } - srcPath := template.Spec.TemplateSource if srcPath == "" { return nil, fmt.Errorf("cannot expand resource using a template with no source") @@ -166,24 +219,52 @@ func expandResource(obj *unstructured.Unstructured, ns *corev1.Namespace, templa src, ok, err := unstructured.NestedMap(obj.Object, sourcePath(srcPath)...) if err != nil { - return nil, fmt.Errorf("could not extract source field from unstructured: %s", err) + return nil, fmt.Errorf("could not extract source field from unstructured: %w", err) } if !ok { - return nil, fmt.Errorf("could not find source field %q in Obj", srcPath) + return nil, fmt.Errorf("could not find source field %q in resource %s", srcPath, obj.GetName()) } resource := &unstructured.Unstructured{} resource.SetUnstructuredContent(src) resource.SetGroupVersionKind(resultantGVK) - resource.SetNamespace(ns.Name) + if ns != nil { + resource.SetNamespace(ns.Name) + } else { + nsFromUn, found, err := unstructured.NestedString(obj.Object, "metadata", "namespace") + if err != nil { + return nil, fmt.Errorf("could not extract namespace field %q in parent resource %s", srcPath, obj.GetName()) + } + + if found { + resource.SetNamespace(nsFromUn) + } + // if not found, then the resulting resource may be cluster scoped. + } + + resource.SetName(mockNameForResource(obj, resultantGVK)) return resource, nil } +// mockNameForResource returns a mock name for a resultant resource created +// from expanding `gen`. The name will be of the form: +// "-". For example, a deployment named +// `nginx-deployment` will produce a resultant named `nginx-deployment-pod`. +func mockNameForResource(gen *unstructured.Unstructured, gvk schema.GroupVersionKind) string { + name := gen.GetName() + if gvk.Kind != "" { + name += "-" + } + name += gvk.Kind + + return strings.ToLower(name) +} + func NewSystem(mutationSystem *mutation.System) *System { return &System{ lock: sync.RWMutex{}, - templates: map[string]*expansionunversioned.ExpansionTemplate{}, mutationSystem: mutationSystem, + db: newDB(), } } diff --git a/pkg/expansion/system_test.go b/pkg/expansion/system_test.go index 92696217f04..9eaf394b6e6 100644 --- a/pkg/expansion/system_test.go +++ b/pkg/expansion/system_test.go @@ -1,588 +1,21 @@ package expansion import ( - "encoding/json" - "fmt" "sort" + "strings" "testing" "github.com/google/go-cmp/cmp" - expansionunversioned "github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/expansion/fixtures" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assign" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assignmeta" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "gopkg.in/yaml.v3" + expansionunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion/fixtures" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" ) -type templateData struct { - name string - apply []match.ApplyTo - source string - generatedGVK expansionunversioned.GeneratedGVK - enforcementAction string -} - -func newTemplate(data *templateData) *expansionunversioned.ExpansionTemplate { - return &expansionunversioned.ExpansionTemplate{ - TypeMeta: metav1.TypeMeta{ - Kind: "ExpansionTemplate", - APIVersion: "expansiontemplates.gatekeeper.sh/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: data.name, - }, - Spec: expansionunversioned.ExpansionTemplateSpec{ - ApplyTo: data.apply, - TemplateSource: data.source, - GeneratedGVK: data.generatedGVK, - EnforcementAction: data.enforcementAction, - }, - } -} - -func TestUpsertRemoveTemplate(t *testing.T) { - tests := []struct { - name string - add []*expansionunversioned.ExpansionTemplate - remove []*expansionunversioned.ExpansionTemplate - check []*expansionunversioned.ExpansionTemplate - wantAddErr bool - wantRemoveErr bool - }{ - { - name: "adding 2 valid templates", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Foo"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Bar", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Foo"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Bar", - }, - }), - }, - wantAddErr: false, - }, - { - name: "adding template with empty name returns error", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{}, - wantAddErr: true, - }, - { - name: "adding template with empty source returns error", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "hello", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{}, - wantAddErr: true, - }, - { - name: "adding template with empty GVK returns error", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "hello", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{}, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{}, - wantAddErr: true, - }, - { - name: "removing a template with empty name returns error", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - remove: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - wantAddErr: false, - wantRemoveErr: true, - }, - { - name: "adding 2 templates, removing 1", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - remove: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - wantAddErr: false, - wantRemoveErr: false, - }, - { - name: "updating an existing template", - add: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"Baz"}, - Kinds: []string{"Foo"}, - Versions: []string{"v9000"}, - }}, - source: "spec.something", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v9000", - Kind: "Bar", - }, - }), - }, - check: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"Baz"}, - Kinds: []string{"Foo"}, - Versions: []string{"v9000"}, - }}, - source: "spec.something", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v9000", - Kind: "Bar", - }, - }), - }, - wantAddErr: false, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - ec := NewSystem(mutation.NewSystem(mutation.SystemOpts{})) - - for _, templ := range tc.add { - err := ec.UpsertTemplate(templ) - if tc.wantAddErr && err == nil { - t.Errorf("expected error, got nil") - } else if !tc.wantAddErr && err != nil { - t.Errorf("failed to add template: %s", err) - } - } - - for _, templ := range tc.remove { - err := ec.RemoveTemplate(templ) - if tc.wantRemoveErr && err == nil { - t.Errorf("expected error, got nil") - } else if !tc.wantRemoveErr && err != nil { - t.Errorf("failed to remove template: %s", err) - } - } - - if len(ec.templates) != len(tc.check) { - t.Errorf("incorrect number of templates in cache, got %d, want %d", len(ec.templates), len(tc.check)) - } - for _, templ := range tc.check { - k := templ.ObjectMeta.Name - got, exists := ec.templates[k] - if !exists { - t.Errorf("could not find template with key %q", k) - } - if cmp.Diff(got, templ) != "" { - t.Errorf("got value: \n%s\n, wanted: \n%s\n\n diff: \n%s", prettyResource(got), prettyResource(templ), cmp.Diff(got, templ)) - } - } - }) - } -} - -func TestTemplatesForGVK(t *testing.T) { - tests := []struct { - name string - gvk expansionunversioned.GeneratedGVK - addTemplates []*expansionunversioned.ExpansionTemplate - want []*expansionunversioned.ExpansionTemplate - }{ - { - name: "adding 2 templates, 1 match", - gvk: expansionunversioned.GeneratedGVK{ - Group: "apps", - Version: "v1", - Kind: "Deployment", - }, - addTemplates: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Foo"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Bar", - }, - }), - }, - want: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - }, - { - name: "adding 2 templates, 2 matches", - gvk: expansionunversioned.GeneratedGVK{ - Group: "apps", - Version: "v1", - Kind: "Deployment", - }, - addTemplates: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Bar", - }, - }), - }, - want: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - newTemplate(&templateData{ - name: "test2", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Bar", - }, - }), - }, - }, - { - name: "adding 1 templates, 0 match", - addTemplates: []*expansionunversioned.ExpansionTemplate{ - newTemplate(&templateData{ - name: "test1", - apply: []match.ApplyTo{{ - Groups: []string{"apps"}, - Kinds: []string{"Deployment"}, - Versions: []string{"v1"}, - }}, - source: "spec.template", - generatedGVK: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }), - }, - want: []*expansionunversioned.ExpansionTemplate{}, - gvk: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v9000", - Kind: "CronJob", - }, - }, - { - name: "no templates, no matches", - addTemplates: []*expansionunversioned.ExpansionTemplate{}, - want: []*expansionunversioned.ExpansionTemplate{}, - gvk: expansionunversioned.GeneratedGVK{ - Group: "", - Version: "v1", - Kind: "Pod", - }, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - ec := NewSystem(mutation.NewSystem(mutation.SystemOpts{})) - for _, te := range tc.addTemplates { - if err := ec.UpsertTemplate(te); err != nil { - t.Fatalf("error upserting template: %s", err) - } - } - - got := ec.templatesForGVK(genGVKToSchemaGVK(tc.gvk)) - sortTemplates(got) - wantSorted := make([]*expansionunversioned.ExpansionTemplate, len(tc.want)) - copy(wantSorted, tc.want) - sortTemplates(wantSorted) - - if len(got) != len(wantSorted) { - t.Errorf("want %d templates, got %d", len(wantSorted), len(got)) - } - for i := 0; i < len(got); i++ { - diff := cmp.Diff(got[i], wantSorted[i]) - if diff != "" { - t.Errorf("got = \n%s\n, want = \n%s\n\n diff \n%s", prettyResource(got[i]), prettyResource(wantSorted[i]), diff) - } - } - }) - } -} - func TestExpand(t *testing.T) { tests := []struct { name string @@ -595,179 +28,224 @@ func TestExpand(t *testing.T) { }{ { name: "generator with no templates or mutators", - generator: loadFixture(fixtures.GeneratorCat, t), + generator: fixtures.LoadFixture(fixtures.GeneratorCat, t), }, { name: "generator with no gvk returns error", - generator: loadFixture(fixtures.DeploymentNoGVK, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNoGVK, t), expectErr: true, }, { name: "generator with non-matching template", - generator: loadFixture(fixtures.GeneratorCat, t), + generator: fixtures.LoadFixture(fixtures.GeneratorCat, t), templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{}, }, { name: "no mutators basic deployment expands pod", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{}, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodNoMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodNoMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "deployment expands pod with enforcement action override", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{}, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPodsEnforceDryrun, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPodsEnforceDryrun, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodNoMutate, t), EnforcementAction: "dryrun", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodNoMutate, t), EnforcementAction: "dryrun", TemplateName: "expand-deployments"}, }, }, { name: "1 mutator basic deployment expands pod", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImage, t), + fixtures.LoadAssign(fixtures.AssignPullImage, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { - name: "expand with nil namespace returns error", - generator: loadFixture(fixtures.DeploymentNginx, t), + name: "expand with nil namespace returns error bc the namespace selector errs out", + generator: fixtures.LoadFixture(fixtures.DeploymentNginxWithNs, t), ns: nil, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImage, t), + fixtures.LoadAssign(fixtures.AssignPullImageWithNsSelector, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, expectErr: true, }, + { + name: "expand with nil namespace does not error out if no namespace selectors", + generator: fixtures.LoadFixture(fixtures.DeploymentNginxWithNs, t), + ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "not-default"}}, + mutators: []types.Mutator{ + fixtures.LoadAssign(fixtures.AssignPullImage, t), + }, + templates: []*expansionunversioned.ExpansionTemplate{ + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + }, + expectErr: false, + want: []*Resultant{ + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutateWithNs, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + }, + }, { name: "1 mutator source All deployment expands pod and mutates", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImageSourceAll, t), + fixtures.LoadAssign(fixtures.AssignPullImageSourceAll, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "1 mutator source empty deployment expands pod and mutates", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImageSourceEmpty, t), + fixtures.LoadAssign(fixtures.AssignPullImageSourceEmpty, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "1 mutator source Original deployment expands pod but does not mutate", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignHostnameSourceOriginal, t), + fixtures.LoadAssign(fixtures.AssignHostnameSourceOriginal, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodNoMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodNoMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "2 mutators, only 1 match, basic deployment expands pod", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImage, t), - loadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), // should not match + fixtures.LoadAssign(fixtures.AssignPullImage, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), // should not match }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutate, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "2 mutators, 2 matches, basic deployment expands pod", - generator: loadFixture(fixtures.DeploymentNginx, t), + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignPullImage, t), - loadAssignMeta(fixtures.AssignMetaAnnotatePod, t), + fixtures.LoadAssign(fixtures.AssignPullImage, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotatePod, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.PodImagePullMutateAnnotated, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + {Obj: fixtures.LoadFixture(fixtures.PodImagePullMutateAnnotated, t), EnforcementAction: "", TemplateName: "expand-deployments"}, }, }, { name: "custom CR with 2 different resultant kinds, with mutators", - generator: loadFixture(fixtures.GeneratorCat, t), + generator: fixtures.LoadFixture(fixtures.GeneratorCat, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignKittenAge, t), - loadAssignMeta(fixtures.AssignMetaAnnotatePurr, t), - loadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), + fixtures.LoadAssign(fixtures.AssignKittenAge, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotatePurr, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TemplateCatExpandsKitten, t), - loadTemplate(fixtures.TemplateCatExpandsPurr, t), + fixtures.LoadTemplate(fixtures.TemplateCatExpandsKitten, t), + fixtures.LoadTemplate(fixtures.TemplateCatExpandsPurr, t), }, want: []*Resultant{ - {Obj: loadFixture(fixtures.ResultantKitten, t), EnforcementAction: "dryrun", TemplateName: "expand-cats-kitten"}, - {Obj: loadFixture(fixtures.ResultantPurr, t), EnforcementAction: "warn", TemplateName: "expand-cats-purr"}, + {Obj: fixtures.LoadFixture(fixtures.ResultantKitten, t), EnforcementAction: "dryrun", TemplateName: "expand-cats-kitten"}, + {Obj: fixtures.LoadFixture(fixtures.ResultantPurr, t), EnforcementAction: "warn", TemplateName: "expand-cats-purr"}, }, }, { name: "custom CR with 2 different resultant kinds, with mutators and non-matching configs", - generator: loadFixture(fixtures.GeneratorCat, t), + generator: fixtures.LoadFixture(fixtures.GeneratorCat, t), ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, mutators: []types.Mutator{ - loadAssign(fixtures.AssignKittenAge, t), - loadAssignMeta(fixtures.AssignMetaAnnotatePurr, t), - loadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), - loadAssign(fixtures.AssignPullImage, t), // should not match + fixtures.LoadAssign(fixtures.AssignKittenAge, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotatePurr, t), + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotateKitten, t), + fixtures.LoadAssign(fixtures.AssignPullImage, t), // should not match }, templates: []*expansionunversioned.ExpansionTemplate{ - loadTemplate(fixtures.TemplateCatExpandsKitten, t), - loadTemplate(fixtures.TemplateCatExpandsPurr, t), - loadTemplate(fixtures.TempExpDeploymentExpandsPods, t), // should not match + fixtures.LoadTemplate(fixtures.TemplateCatExpandsKitten, t), + fixtures.LoadTemplate(fixtures.TemplateCatExpandsPurr, t), + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), // should not match }, want: []*Resultant{ - {Obj: loadFixture(fixtures.ResultantKitten, t), EnforcementAction: "dryrun", TemplateName: "expand-cats-kitten"}, - {Obj: loadFixture(fixtures.ResultantPurr, t), EnforcementAction: "warn", TemplateName: "expand-cats-purr"}, + {Obj: fixtures.LoadFixture(fixtures.ResultantKitten, t), EnforcementAction: "dryrun", TemplateName: "expand-cats-kitten"}, + {Obj: fixtures.LoadFixture(fixtures.ResultantPurr, t), EnforcementAction: "warn", TemplateName: "expand-cats-purr"}, + }, + }, + { + name: "1 mutator deployment expands pod with AssignImage", + generator: fixtures.LoadFixture(fixtures.DeploymentNginx, t), + ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, + mutators: []types.Mutator{ + fixtures.LoadAssignImage(fixtures.AssignImage, t), + }, + templates: []*expansionunversioned.ExpansionTemplate{ + fixtures.LoadTemplate(fixtures.TempExpDeploymentExpandsPods, t), + }, + want: []*Resultant{ + {Obj: fixtures.LoadFixture(fixtures.PodMutateImage, t), EnforcementAction: "", TemplateName: "expand-deployments"}, + }, + }, + { + name: "recursive expansion with mutators", + generator: fixtures.LoadFixture(fixtures.GeneratorCronJob, t), + ns: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, + mutators: []types.Mutator{ + fixtures.LoadAssignMeta(fixtures.AssignMetaAnnotatePod, t), + }, + templates: []*expansionunversioned.ExpansionTemplate{ + fixtures.LoadTemplate(fixtures.TempExpCronJob, t), + fixtures.LoadTemplate(fixtures.TempExpJob, t), + }, + want: []*Resultant{ + {Obj: fixtures.LoadFixture(fixtures.ResultantJob, t), EnforcementAction: "", TemplateName: "expand-cronjobs"}, + {Obj: fixtures.LoadFixture(fixtures.ResultantRecursivePod, t), EnforcementAction: "", TemplateName: "expand-jobs"}, }, }, } @@ -811,8 +289,8 @@ func compareResults(got []*Resultant, want []*Resultant, t *testing.T) { return } - sortReusultants(got) - sortReusultants(want) + sortResultants(got) + sortResultants(want) for i := 0; i < len(got); i++ { if diff := cmp.Diff(got[i], want[i]); diff != "" { @@ -821,7 +299,7 @@ func compareResults(got []*Resultant, want []*Resultant, t *testing.T) { } } -func sortReusultants(objs []*Resultant) { +func sortResultants(objs []*Resultant) { sortKey := func(r *Resultant) string { return r.Obj.GetName() + r.Obj.GetAPIVersion() } @@ -830,74 +308,118 @@ func sortReusultants(objs []*Resultant) { }) } -func loadFixture(f string, t *testing.T) *unstructured.Unstructured { - obj := make(map[string]interface{}) - if err := yaml.Unmarshal([]byte(f), obj); err != nil { - t.Fatalf("error unmarshaling yaml for fixture: %s", err) - } - - jsonBytes, err := json.Marshal(obj) - if err != nil { - t.Fatalf("error marshaling json for fixture: %s", err) - } - - if err = json.Unmarshal(jsonBytes, &obj); err != nil { - t.Fatalf("error unmarshaling json for fixture: %s", err) +func TestValidateTemplate(t *testing.T) { + tests := []struct { + name string + errFn func(e error, t *testing.T) + temp expansionunversioned.ExpansionTemplate + }{ + { + name: "valid expansion template", + errFn: noError, + temp: *fixtures.TestTemplate("foo", 1, 2), + }, + { + name: "missing name", + temp: *fixtures.NewTemplate(&fixtures.TemplateData{ + Apply: []match.ApplyTo{{ + Groups: []string{"apps"}, + Kinds: []string{"Deployment"}, + Versions: []string{"v1"}, + }}, + Source: "spec.template", + GenGVK: expansionunversioned.GeneratedGVK{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + }), + errFn: matchErr("empty name"), + }, + { + name: "missing source", + temp: *fixtures.NewTemplate(&fixtures.TemplateData{ + Name: "test1", + Apply: []match.ApplyTo{{ + Groups: []string{"apps"}, + Kinds: []string{"Deployment"}, + Versions: []string{"v1"}, + }}, + GenGVK: expansionunversioned.GeneratedGVK{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + }), + errFn: matchErr("empty source"), + }, + { + name: "missing generated GVK", + temp: *fixtures.NewTemplate(&fixtures.TemplateData{ + Name: "test1", + Apply: []match.ApplyTo{{ + Groups: []string{"apps"}, + Kinds: []string{"Deployment"}, + Versions: []string{"v1"}, + }}, + Source: "spec.template", + }), + errFn: matchErr("empty generatedGVK"), + }, + { + name: "missing applyTo", + temp: *fixtures.NewTemplate(&fixtures.TemplateData{ + Name: "test1", + Source: "spec.template", + GenGVK: expansionunversioned.GeneratedGVK{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + }), + errFn: matchErr("specify ApplyTo"), + }, + { + name: "loop", + temp: *fixtures.NewTemplate(&fixtures.TemplateData{ + Name: "test1", + Apply: []match.ApplyTo{{ + Groups: []string{""}, + Kinds: []string{"Pod"}, + Versions: []string{"v1"}, + }}, + Source: "spec.template", + GenGVK: expansionunversioned.GeneratedGVK{ + Group: "", + Version: "v1", + Kind: "Pod", + }, + }), + errFn: matchErr("also applies to that same GVK"), + }, } - - u := unstructured.Unstructured{} - u.SetUnstructuredContent(obj) - return &u -} - -func loadTemplate(f string, t *testing.T) *expansionunversioned.ExpansionTemplate { - u := loadFixture(f, t) - te := &expansionunversioned.ExpansionTemplate{} - err := convertUnstructuredToTyped(u, te) - if err != nil { - t.Fatalf("error converting template expansion: %s", err) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + tc.errFn(ValidateTemplate(&tc.temp), t) + }) } - return te } -func loadAssign(f string, t *testing.T) types.Mutator { - u := loadFixture(f, t) - a := &mutationsunversioned.Assign{} - err := convertUnstructuredToTyped(u, a) - if err != nil { - t.Fatalf("error converting assign: %s", err) - } - mut, err := assign.MutatorForAssign(a) - if err != nil { - t.Fatalf("error creating assign: %s", err) +func noError(e error, t *testing.T) { + if e != nil { + t.Errorf("did want want error, but got %s", e) } - return mut } -func loadAssignMeta(f string, t *testing.T) types.Mutator { - u := loadFixture(f, t) - a := &mutationsunversioned.AssignMetadata{} - err := convertUnstructuredToTyped(u, a) - if err != nil { - t.Fatalf("error converting assignmeta: %s", err) - } - mut, err := assignmeta.MutatorForAssignMetadata(a) - if err != nil { - t.Fatalf("error creating assignmeta: %s", err) - } - return mut -} +func matchErr(substr string) func(error, *testing.T) { + return func(err error, t *testing.T) { + if err == nil { + t.Error("expected err but got nil") + return + } -func convertUnstructuredToTyped(u *unstructured.Unstructured, obj interface{}) error { - if u == nil { - return fmt.Errorf("cannot convert nil unstructured to type") + if !strings.Contains(err.Error(), substr) { + t.Errorf("expected error to contain %q, but got %q", substr, err.Error()) + } } - err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), obj) - return err -} - -func sortTemplates(templates []*expansionunversioned.ExpansionTemplate) { - sort.SliceStable(templates, func(x, y int) bool { - return templates[x].Name < templates[y].Name - }) } diff --git a/pkg/fakes/fakecfdataclient.go b/pkg/fakes/fakecfdataclient.go new file mode 100644 index 00000000000..ba81b4fe255 --- /dev/null +++ b/pkg/fakes/fakecfdataclient.go @@ -0,0 +1,146 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package fakes + +import ( + "context" + "fmt" + gosync "sync" + + constraintTypes "github.com/open-policy-agent/frameworks/constraint/pkg/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type CfDataKey struct { + Gvk schema.GroupVersionKind + Key string +} + +// FakeCfClient is an CfDataClient for testing. +type FakeCfClient struct { + mu gosync.Mutex + data map[CfDataKey]interface{} + needsToError bool +} + +// KeyFor returns a CfDataKey for the provided resource. +// Returns error if the resource is not a runtime.Object w/ metadata. +func KeyFor(obj interface{}) (CfDataKey, error) { + o, ok := obj.(client.Object) + if !ok { + return CfDataKey{}, fmt.Errorf("expected runtime.Object, got: %T", obj) + } + gvk := o.GetObjectKind().GroupVersionKind() + ns := o.GetNamespace() + if ns == "" { + return CfDataKey{Gvk: gvk, Key: o.GetName()}, nil + } + + return CfDataKey{Gvk: gvk, Key: fmt.Sprintf("%s/%s", ns, o.GetName())}, nil +} + +func (f *FakeCfClient) AddData(ctx context.Context, data interface{}) (*constraintTypes.Responses, error) { + f.mu.Lock() + defer f.mu.Unlock() + + if f.needsToError { + return nil, fmt.Errorf("test error") + } + + key, err := KeyFor(data) + if err != nil { + return nil, err + } + + if f.data == nil { + f.data = make(map[CfDataKey]interface{}) + } + + f.data[key] = data + return &constraintTypes.Responses{}, nil +} + +func (f *FakeCfClient) RemoveData(ctx context.Context, data interface{}) (*constraintTypes.Responses, error) { + f.mu.Lock() + defer f.mu.Unlock() + + if f.needsToError { + return nil, fmt.Errorf("test error") + } + + if target.IsWipeData(data) { + f.data = make(map[CfDataKey]interface{}) + return &constraintTypes.Responses{}, nil + } + + key, err := KeyFor(data) + if err != nil { + return nil, err + } + + delete(f.data, key) + return &constraintTypes.Responses{}, nil +} + +// GetData returns data for a CfDataKey. It assumes that the +// key is present in the FakeCfClient. Also the data returned is not copied +// and it's meant only for assertions not modifications. +func (f *FakeCfClient) GetData(key CfDataKey) interface{} { + f.mu.Lock() + defer f.mu.Unlock() + + return f.data[key] +} + +// Contains returns true if all expected resources are in the cache. +func (f *FakeCfClient) Contains(expected map[CfDataKey]interface{}) bool { + f.mu.Lock() + defer f.mu.Unlock() + + for k := range expected { + if _, ok := f.data[k]; !ok { + return false + } + } + return true +} + +// HasGVK returns true if the cache has any data of the requested kind. +func (f *FakeCfClient) HasGVK(gvk schema.GroupVersionKind) bool { + f.mu.Lock() + defer f.mu.Unlock() + + for k := range f.data { + if k.Gvk == gvk { + return true + } + } + return false +} + +// Len returns the number of items in the cache. +func (f *FakeCfClient) Len() int { + f.mu.Lock() + defer f.mu.Unlock() + return len(f.data) +} + +// SetErroring will error out on AddObject or RemoveObject. +func (f *FakeCfClient) SetErroring(enabled bool) { + f.mu.Lock() + defer f.mu.Unlock() + f.needsToError = enabled +} diff --git a/pkg/fakes/fixtures.go b/pkg/fakes/fixtures.go new file mode 100644 index 00000000000..29f5cff9ed1 --- /dev/null +++ b/pkg/fakes/fixtures.go @@ -0,0 +1,63 @@ +package fakes + +import ( + "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" + templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func DenyAllRegoTemplate() *templates.ConstraintTemplate { + return &templates.ConstraintTemplate{ + TypeMeta: metav1.TypeMeta{ + APIVersion: templatesv1beta1.SchemeGroupVersion.String(), + Kind: "ConstraintTemplate", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "denyall", + }, + Spec: templates.ConstraintTemplateSpec{ + CRD: templates.CRD{ + Spec: templates.CRDSpec{ + Names: templates.Names{ + Kind: "denyall", + }, + }, + }, + Targets: []templates.Target{{ + Target: target.Name, + Code: []templates.Code{{ + Engine: "Rego", + Source: &templates.Anything{ + Value: map[string]interface{}{"rego": ` +package goodrego + +violation[{"msg": msg}] { + msg := "denyall" +}`}, + }, + }}, + }}, + }, + } +} + +func DenyAllConstraint() *unstructured.Unstructured { + return ConstraintFor("denyall") +} + +func ConstraintFor(kind string) *unstructured.Unstructured { + u := &unstructured.Unstructured{} + + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: constraints.Group, + Version: "v1beta1", + Kind: kind, + }) + u.SetName("constraint") + + return u +} diff --git a/pkg/fakes/provider_cache.go b/pkg/fakes/provider_cache.go index 7d795ef23ea..236395a0fba 100644 --- a/pkg/fakes/provider_cache.go +++ b/pkg/fakes/provider_cache.go @@ -3,7 +3,7 @@ package fakes import ( externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" frameworksexternaldata "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/fakes/reader.go b/pkg/fakes/reader.go new file mode 100644 index 00000000000..2acd81d19da --- /dev/null +++ b/pkg/fakes/reader.go @@ -0,0 +1,60 @@ +package fakes + +import ( + "context" + "sync" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type SpyReader struct { + client.Reader + ListFunc func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error +} + +func (r SpyReader) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + if r.ListFunc != nil { + return r.ListFunc(ctx, list, opts...) + } + return r.Reader.List(ctx, list, opts...) +} + +// FailureInjector can be used in combination with the SpyReader to simulate transient +// failures for network calls. +type FailureInjector struct { + mu sync.Mutex + failures map[string]int // registers GVK.Kind and how many times to fail +} + +func (f *FailureInjector) SetFailures(kind string, failures int) { + f.mu.Lock() + defer f.mu.Unlock() + + f.failures[kind] = failures +} + +// CheckFailures looks at the count of failures and returns true +// if there are still failures for the kind to consume, false otherwise. +func (f *FailureInjector) CheckFailures(kind string) bool { + f.mu.Lock() + defer f.mu.Unlock() + + v, ok := f.failures[kind] + if !ok { + return false + } + + if v == 0 { + return false + } + + f.failures[kind] = v - 1 + + return true +} + +func NewFailureInjector() *FailureInjector { + return &FailureInjector{ + failures: make(map[string]int), + } +} diff --git a/pkg/gator/expand/expand.go b/pkg/gator/expand/expand.go index 74084b9ae99..7d372506b8c 100644 --- a/pkg/gator/expand/expand.go +++ b/pkg/gator/expand/expand.go @@ -3,16 +3,17 @@ package expand import ( "fmt" - "github.com/open-policy-agent/gatekeeper/apis/expansion/unversioned" - expansionv1 "github.com/open-policy-agent/gatekeeper/apis/expansion/v1alpha1" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assign" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assignmeta" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/modifyset" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + expansionv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignimage" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignmeta" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/modifyset" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -23,6 +24,7 @@ var mutatorKinds = map[string]bool{ "Assign": true, "AssignMetadata": true, "ModifySet": true, + "AssignImage": true, } type Expander struct { @@ -63,18 +65,18 @@ func NewExpander(resources []*unstructured.Unstructured) (*Expander, error) { } if err := er.addResources(resources); err != nil { - return nil, fmt.Errorf("error parsing resources: %s", err) + return nil, fmt.Errorf("error parsing resources: %w", err) } for _, te := range er.templateExpansions { if err := er.expSystem.UpsertTemplate(te); err != nil { - return nil, fmt.Errorf("error upserting template %s: %s", te.Name, err) + return nil, fmt.Errorf("error upserting template %s: %w", te.Name, err) } } for _, m := range er.mutators { if err := er.mutSystem.Upsert(m); err != nil { - return nil, fmt.Errorf("error upserting mutator: %s", err) + return nil, fmt.Errorf("error upserting mutator: %w", err) } } @@ -92,12 +94,12 @@ func (er *Expander) Expand(resource *unstructured.Unstructured) ([]*expansion.Re Source: types.SourceTypeOriginal, } if _, err := er.mutSystem.Mutate(base); err != nil { - return nil, fmt.Errorf("error mutating base resource %s: %s", resource.GetName(), err) + return nil, fmt.Errorf("error mutating base resource %s: %w", resource.GetName(), err) } resultants, err := er.expSystem.Expand(base) if err != nil { - return nil, fmt.Errorf("error expanding resource %s: %s", resource.GetName(), err) + return nil, fmt.Errorf("error expanding resource %s: %w", resource.GetName(), err) } return resultants, nil @@ -151,6 +153,12 @@ func (er *Expander) addMutator(mut *unstructured.Unstructured) error { return err } m, mutErr = modifyset.MutatorForModifySet(ms) + case "AssignImage": + a, err := convertAssignImage(mut) + if err != nil { + return err + } + m, mutErr = assignimage.MutatorForAssignImage(a) default: return fmt.Errorf("cannot convert mutator of kind %q", mut.GetKind()) } @@ -172,7 +180,6 @@ func (er *Expander) add(u *unstructured.Unstructured) error { case isNamespace(u): err = er.addNamespace(u) } - if err == nil { // Any resource can technically be a generator er.objects = append(er.objects, u) @@ -200,14 +207,14 @@ func (er *Expander) addNamespace(u *unstructured.Unstructured) error { } func isExpansion(u *unstructured.Unstructured) bool { - return u.GroupVersionKind().Group == expansionv1.GroupVersion.Group && u.GetKind() == "ExpansionTemplate" + return u.GroupVersionKind().Group == expansionv1alpha1.GroupVersion.Group && u.GetKind() == "ExpansionTemplate" } func isMutator(obj *unstructured.Unstructured) bool { if _, exists := mutatorKinds[obj.GetKind()]; !exists { return false } - return obj.GroupVersionKind().Group == mutationsv1.GroupVersion.Group + return obj.GroupVersionKind().Group == mutationsv1alpha1.GroupVersion.Group } func isNamespace(obj *unstructured.Unstructured) bool { @@ -246,6 +253,12 @@ func convertModifySet(u *unstructured.Unstructured) (*mutationsunversioned.Modif return ms, err } +func convertAssignImage(u *unstructured.Unstructured) (*mutationsunversioned.AssignImage, error) { + ai := &mutationsunversioned.AssignImage{} + err := convertUnstructuredToTyped(u, ai) + return ai, err +} + func convertNamespace(u *unstructured.Unstructured) (*corev1.Namespace, error) { ns := &corev1.Namespace{} err := convertUnstructuredToTyped(u, ns) diff --git a/pkg/gator/opa.go b/pkg/gator/opa.go index 952dce8931f..3871e131ce7 100644 --- a/pkg/gator/opa.go +++ b/pkg/gator/opa.go @@ -2,17 +2,30 @@ package gator import ( constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" - "github.com/open-policy-agent/gatekeeper/pkg/target" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" ) -func NewOPAClient(includeTrace bool) (Client, error) { - driver, err := local.New(local.Tracing(includeTrace)) +func NewOPAClient(includeTrace bool, k8sCEL bool) (Client, error) { + args := []constraintclient.Opt{constraintclient.Targets(&target.K8sValidationTarget{})} + + if k8sCEL { + k8sDriver, err := k8scel.New() + if err != nil { + return nil, err + } + args = append(args, constraintclient.Driver(k8sDriver)) + } + + driver, err := rego.New(rego.Tracing(includeTrace)) if err != nil { return nil, err } - c, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + args = append(args, constraintclient.Driver(driver)) + + c, err := constraintclient.NewClient(args...) if err != nil { return nil, err } diff --git a/pkg/gator/reader/filereader.go b/pkg/gator/reader/filereader.go index 867bd211e52..6c1f1a7d78e 100644 --- a/pkg/gator/reader/filereader.go +++ b/pkg/gator/reader/filereader.go @@ -6,7 +6,7 @@ import ( "os" "path/filepath" - "github.com/open-policy-agent/gatekeeper/pkg/oci" + "github.com/open-policy-agent/gatekeeper/v3/pkg/oci" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -148,7 +148,8 @@ func readStdin() ([]*unstructured.Unstructured, error) { return nil, fmt.Errorf("getting stdin info: %w", err) } - if stdinfo.Size() == 0 { + // check if data is being piped or redirected to stdin + if (stdinfo.Mode() & os.ModeCharDevice) != 0 { return nil, nil } diff --git a/pkg/gator/reader/read_constraints.go b/pkg/gator/reader/read_constraints.go index 33963dfcff8..09623dbc695 100644 --- a/pkg/gator/reader/read_constraints.go +++ b/pkg/gator/reader/read_constraints.go @@ -10,7 +10,7 @@ import ( templatesv1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/yaml" @@ -60,7 +60,7 @@ func ReadUnstructureds(bytes []byte) ([]*unstructured.Unstructured, error) { u, err := readUnstructured([]byte(split)) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidYAML, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidYAML, err) } result = append(result, u) @@ -91,7 +91,7 @@ func ReadTemplate(scheme *runtime.Scheme, f fs.FS, path string) (*templates.Cons u, err := readUnstructured(bytes) if err != nil { - return nil, fmt.Errorf("%w: parsing ConstraintTemplate YAML from %q: %v", gator.ErrAddingTemplate, path, err) + return nil, fmt.Errorf("%w: parsing ConstraintTemplate YAML from %q: %w", gator.ErrAddingTemplate, path, err) } template, err := ToTemplate(scheme, u) @@ -115,7 +115,7 @@ func ToTemplate(scheme *runtime.Scheme, u *unstructured.Unstructured) (*template t, err := scheme.New(gvk) if err != nil { // The type isn't registered in the scheme. - return nil, fmt.Errorf("%w: %v", gator.ErrAddingTemplate, err) + return nil, fmt.Errorf("%w: %w", gator.ErrAddingTemplate, err) } // YAML parsing doesn't properly handle ObjectMeta, so we must @@ -128,7 +128,7 @@ func ToTemplate(scheme *runtime.Scheme, u *unstructured.Unstructured) (*template } err = json.Unmarshal(jsonBytes, t) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrAddingTemplate, err) + return nil, fmt.Errorf("%w: %w", gator.ErrAddingTemplate, err) } v, isVersionless := t.(versionless) @@ -140,7 +140,7 @@ func ToTemplate(scheme *runtime.Scheme, u *unstructured.Unstructured) (*template if err != nil { // This shouldn't happen unless there's a bug in the conversion functions. // Most likely it means the conversion functions weren't generated. - return nil, fmt.Errorf("%w: %v", gator.ErrConvertingTemplate, err) + return nil, fmt.Errorf("%w: %w", gator.ErrConvertingTemplate, err) } return template, nil @@ -157,7 +157,7 @@ func ReadObject(f fs.FS, path string) (*unstructured.Unstructured, error) { u, err := readUnstructured(bytes) if err != nil { - return nil, fmt.Errorf("%w: parsing Constraint from %q: %v", gator.ErrAddingConstraint, path, err) + return nil, fmt.Errorf("%w: parsing Constraint from %q: %w", gator.ErrAddingConstraint, path, err) } return u, nil diff --git a/pkg/gator/test/test.go b/pkg/gator/test/test.go index df1b084f4f5..d09aafcb616 100644 --- a/pkg/gator/test/test.go +++ b/pkg/gator/test/test.go @@ -7,12 +7,13 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/apis" templatesv1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/gator/expand" - "github.com/open-policy-agent/gatekeeper/pkg/gator/reader" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/target" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/expand" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/reader" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) @@ -27,15 +28,29 @@ func init() { } } -func Test(objs []*unstructured.Unstructured, includeTrace bool) (*GatorResponses, error) { - // create the client +// options for the Test func. +type Opts struct { + // Driver specific options + IncludeTrace bool + GatherStats bool + UseK8sCEL bool +} + +func Test(objs []*unstructured.Unstructured, tOpts Opts) (*GatorResponses, error) { + args := []constraintclient.Opt{constraintclient.Targets(&target.K8sValidationTarget{})} + k8sDriver, err := k8scel.New() + if err != nil { + return nil, fmt.Errorf("creating K8s native driver: %w", err) + } + args = append(args, constraintclient.Driver(k8sDriver)) - driver, err := local.New(local.Tracing(includeTrace)) + driver, err := makeRegoDriver(tOpts) if err != nil { - return nil, err + return nil, fmt.Errorf("creating Rego driver: %w", err) } + args = append(args, constraintclient.Driver(driver)) - client, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + client, err := constraintclient.NewClient(args...) if err != nil { return nil, fmt.Errorf("creating OPA client: %w", err) } @@ -82,7 +97,7 @@ func Test(objs []*unstructured.Unstructured, includeTrace bool) (*GatorResponses // create the expander er, err := expand.NewExpander(objs) if err != nil { - return nil, fmt.Errorf("error creating expander: %s", err) + return nil, fmt.Errorf("error creating expander: %w", err) } // now audit all objects @@ -100,14 +115,14 @@ func Test(objs []*unstructured.Unstructured, includeTrace bool) (*GatorResponses review, err := client.Review(ctx, au) if err != nil { - return nil, fmt.Errorf("reviewing %v %s/%s: %v", + return nil, fmt.Errorf("reviewing %v %s/%s: %w", obj.GroupVersionKind(), obj.GetNamespace(), obj.GetName(), err) } // Attempt to expand the obj and review resultant resources (if any) resultants, err := er.Expand(obj) if err != nil { - return nil, fmt.Errorf("expanding resource %s: %s", obj.GetName(), err) + return nil, fmt.Errorf("expanding resource %s: %w", obj.GetName(), err) } for _, resultant := range resultants { au := target.AugmentedUnstructured{ @@ -117,11 +132,12 @@ func Test(objs []*unstructured.Unstructured, includeTrace bool) (*GatorResponses } resultantReview, err := client.Review(ctx, au) if err != nil { - return nil, fmt.Errorf("reviewing expanded resource %v %s/%s: %v", + return nil, fmt.Errorf("reviewing expanded resource %v %s/%s: %w", resultant.Obj.GroupVersionKind(), resultant.Obj.GetNamespace(), resultant.Obj.GetName(), err) } expansion.OverrideEnforcementAction(resultant.EnforcementAction, resultantReview) expansion.AggregateResponses(resultant.TemplateName, review, resultantReview) + expansion.AggregateStats(resultant.TemplateName, review, resultantReview) } for targetName, r := range review.ByTarget { @@ -148,9 +164,10 @@ func Test(objs []*unstructured.Unstructured, includeTrace bool) (*GatorResponses trace = trace + "\n\n" + *r.Trace targetResponse.Trace = &trace } - responses.ByTarget[targetName] = targetResponse } + + responses.StatsEntries = append(responses.StatsEntries, review.StatsEntries...) } return responses, nil @@ -165,3 +182,15 @@ func isConstraint(u *unstructured.Unstructured) bool { gvk := u.GroupVersionKind() return gvk.Group == "constraints.gatekeeper.sh" } + +func makeRegoDriver(tOpts Opts) (*rego.Driver, error) { + var args []rego.Arg + if tOpts.GatherStats { + args = append(args, rego.GatherStats()) + } + if tOpts.IncludeTrace { + args = append(args, rego.Tracing(tOpts.IncludeTrace)) + } + + return rego.New(args...) +} diff --git a/pkg/gator/test/test_test.go b/pkg/gator/test/test_test.go index 0fd4ec900b4..95a0d18ac39 100644 --- a/pkg/gator/test/test_test.go +++ b/pkg/gator/test/test_test.go @@ -1,15 +1,17 @@ package test import ( - "errors" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/gator/fixtures" - "github.com/open-policy-agent/gatekeeper/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/fixtures" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/yaml" ) @@ -56,12 +58,27 @@ func init() { } } +func ignoreGatorResultFields() cmp.Option { + return cmp.FilterPath( + func(p cmp.Path) bool { + switch p.String() { + // ignore these fields + case "Result.Metadata", "Result.EvaluationMeta", "Result.EnforcementAction", "ViolatingObject": + return true + default: + return false + } + }, + cmp.Ignore()) +} + func TestTest(t *testing.T) { tcs := []struct { - name string - inputs []string - want []*GatorResult - err error + name string + inputs []string + want []*GatorResult + cmpOption cmp.Option + err error }{ { name: "basic no violation", @@ -70,6 +87,7 @@ func TestTest(t *testing.T) { fixtures.ConstraintAlwaysValidate, fixtures.Object, }, + cmpOption: ignoreGatorResultFields(), }, { name: "basic violation", @@ -101,6 +119,7 @@ func TestTest(t *testing.T) { }, }, }, + cmpOption: ignoreGatorResultFields(), }, { name: "referential constraint with violation", @@ -126,6 +145,7 @@ func TestTest(t *testing.T) { }, }, }, + cmpOption: ignoreGatorResultFields(), }, { name: "referential constraint without violation", @@ -168,27 +188,26 @@ func TestTest(t *testing.T) { var objs []*unstructured.Unstructured for _, input := range tc.inputs { u, err := readUnstructured([]byte(input)) - if err != nil { - t.Fatalf("readUnstructured for input %q: %v", input, err) - } + require.NoError(t, err) objs = append(objs, u) } - resps, err := Test(objs, false) + resps, err := Test(objs, Opts{}) if tc.err != nil { - if err == nil { - t.Errorf("got nil err, want %v", tc.err) - } - if !errors.Is(err, tc.err) { - t.Errorf("got err %q, want %q", err, tc.err) - } + require.ErrorIs(t, err, tc.err) } else if err != nil { - t.Errorf("got err '%v', want nil", err) + require.NoError(t, err) } got := resps.Results() - diff := cmp.Diff(tc.want, got, cmpopts.IgnoreFields(GatorResult{}, "Metadata", "EvaluationMeta", "EnforcementAction", "ViolatingObject")) + var diff string + if tc.cmpOption != nil { + diff = cmp.Diff(tc.want, got, tc.cmpOption) + } else { + diff = cmp.Diff(tc.want, got) + } + if diff != "" { t.Errorf("diff in GatorResult objects (-want +got):\n%s", diff) } @@ -213,7 +232,7 @@ func Test_Test_withTrace(t *testing.T) { objs = append(objs, u) } - resps, err := Test(objs, true) + resps, err := Test(objs, Opts{IncludeTrace: true}) if err != nil { t.Errorf("got err '%v', want nil", err) } @@ -244,12 +263,8 @@ func Test_Test_withTrace(t *testing.T) { }, } - diff := cmp.Diff(want, got, cmpopts.IgnoreFields( + diff := cmp.Diff(want, got, ignoreGatorResultFields(), cmpopts.IgnoreFields( GatorResult{}, - "Metadata", - "EvaluationMeta", - "EnforcementAction", - "ViolatingObject", "Trace", // ignore Trace for now, we will assert non nil further down )) if diff != "" { @@ -263,6 +278,87 @@ func Test_Test_withTrace(t *testing.T) { } } +// Test_Test_withStats proves that we can get a stats populated when we ask for it. +func Test_Test_withStats(t *testing.T) { + inputs := []string{ + fixtures.TemplateNeverValidate, + fixtures.ConstraintNeverValidate, + fixtures.Object, + } + + var objs []*unstructured.Unstructured + for _, input := range inputs { + u, err := readUnstructured([]byte(input)) + assert.NoErrorf(t, err, "readUnstructured for input %q: %v", input, err) + objs = append(objs, u) + } + + resps, err := Test(objs, Opts{GatherStats: true}) + assert.NoError(t, err) + + actualStats := resps.StatsEntries + expectesSE := &instrumentation.StatsEntry{ + Scope: "template", + StatsFor: "NeverValidate", + Stats: []*instrumentation.Stat{ + { + Name: "templateRunTimeNS", + // Value: 0, // will be checked later + Source: instrumentation.Source{ + Type: "engine", + Value: "Rego", + }, + }, + { + Name: "constraintCount", + Value: 1, + Source: instrumentation.Source{ + Type: "engine", + Value: "Rego", + }, + }, + }, + Labels: []*instrumentation.Label{ + { + Name: "TracingEnabled", + Value: false, + }, + { + Name: "PrintEnabled", + Value: false, + }, + { + Name: "target", + Value: "admission.k8s.gatekeeper.sh", + }, + }, + } + + // test.go calls review on all 3 objects (template, constraint, objToReview) + // so we need 3 "almost" copies of the stat entry above. + expectedStats := []*instrumentation.StatsEntry{} + expectedStats = append(expectedStats, expectesSE, expectesSE, expectesSE) + + diff := cmp.Diff(actualStats, expectedStats, cmpopts.IgnoreFields( + instrumentation.Stat{}, "Value", + )) + if diff != "" { + t.Errorf("diff in StatsEntries (-want +got):\n%s", diff) + } + + // there should be at least 3 stats entry with two stats each + assert.Len(t, actualStats, len(expectedStats)) + assert.Len(t, actualStats[0].Stats, 2) + for _, stat := range actualStats[0].Stats { + if stat.Name == "templateRunTimeNS" { + require.NotZero(t, stat.Value) + } + if stat.Name == "constraintCount" { + require.Equal(t, stat.Value, 1) + } + } +} + func readUnstructured(bytes []byte) (*unstructured.Unstructured, error) { u := &unstructured.Unstructured{ Object: make(map[string]interface{}), diff --git a/pkg/gator/test/types.go b/pkg/gator/test/types.go index 36f98ab90cf..33db9b4451b 100644 --- a/pkg/gator/test/types.go +++ b/pkg/gator/test/types.go @@ -3,6 +3,7 @@ package test import ( "sort" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "github.com/open-policy-agent/frameworks/constraint/pkg/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -41,8 +42,9 @@ type GatorResponse struct { } type GatorResponses struct { - ByTarget map[string]*GatorResponse - Handled map[string]bool + ByTarget map[string]*GatorResponse + Handled map[string]bool + StatsEntries []*instrumentation.StatsEntry } func (r *GatorResponses) Results() []*GatorResult { diff --git a/pkg/gator/verify/assertion.go b/pkg/gator/verify/assertion.go index ce8314e038e..9d050d17a12 100644 --- a/pkg/gator/verify/assertion.go +++ b/pkg/gator/verify/assertion.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -150,7 +150,7 @@ func (a *Assertion) getMsgRegex() (*regexp.Regexp, error) { a.msgRegex, err = regexp.Compile(*a.Message) }) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidRegex, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidRegex, err) } return a.msgRegex, nil diff --git a/pkg/gator/verify/assertion_test.go b/pkg/gator/verify/assertion_test.go index 20257f48628..974ad7314be 100644 --- a/pkg/gator/verify/assertion_test.go +++ b/pkg/gator/verify/assertion_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" "k8s.io/utils/pointer" ) @@ -38,7 +38,7 @@ func TestAssertion_Run(t *testing.T) { name: "violation with message", assertion: &Assertion{ Violations: gator.IntStrFromInt(1), - Message: pointer.StringPtr("message"), + Message: pointer.String("message"), }, results: nil, wantErr: gator.ErrNumViolations, @@ -46,7 +46,7 @@ func TestAssertion_Run(t *testing.T) { name: "no violations with message", assertion: &Assertion{ Violations: gator.IntStrFromStr("no"), - Message: pointer.StringPtr("message"), + Message: pointer.String("message"), }, results: nil, wantErr: nil, @@ -54,7 +54,7 @@ func TestAssertion_Run(t *testing.T) { name: "fail no violations with message", assertion: &Assertion{ Violations: gator.IntStrFromStr("no"), - Message: pointer.StringPtr("message"), + Message: pointer.String("message"), }, results: []*types.Result{{ Msg: "message", diff --git a/pkg/gator/verify/filter.go b/pkg/gator/verify/filter.go index d98d4fb5bff..e1b6ad138ec 100644 --- a/pkg/gator/verify/filter.go +++ b/pkg/gator/verify/filter.go @@ -5,7 +5,7 @@ import ( "regexp" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" ) type Filter interface { @@ -87,7 +87,7 @@ type orFilter struct { func newOrFilter(filter string) (Filter, error) { regex, err := regexp.Compile(filter) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidFilter, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidFilter, err) } return &orFilter{regex: regex}, nil @@ -123,12 +123,12 @@ var _ Filter = &andFilter{} func newAndFilter(testFilter, caseFilter string) (Filter, error) { testRegex, err := regexp.Compile(testFilter) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidFilter, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidFilter, err) } caseRegex, err := regexp.Compile(caseFilter) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidFilter, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidFilter, err) } return &andFilter{testRegex: testRegex, caseRegex: caseRegex}, nil diff --git a/pkg/gator/verify/filter_test.go b/pkg/gator/verify/filter_test.go index b25f8a603ee..7d251dceddf 100644 --- a/pkg/gator/verify/filter_test.go +++ b/pkg/gator/verify/filter_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" ) func TestFilter_Error(t *testing.T) { diff --git a/pkg/gator/verify/printer_go.go b/pkg/gator/verify/printer_go.go index 41e6ccb7f35..35cc4cabe84 100644 --- a/pkg/gator/verify/printer_go.go +++ b/pkg/gator/verify/printer_go.go @@ -53,18 +53,18 @@ func (p PrinterGo) PrintSuite(w StringWriter, r *SuiteResult, verbose bool) erro if r.IsFailure() { _, err := w.WriteString(fmt.Sprintf("FAIL\t%s\t%v\n", r.Path, r.Runtime)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } if r.Error != nil { _, err = w.WriteString(fmt.Sprintf(" %v\n", r.Error)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } } else { _, err := w.WriteString(fmt.Sprintf("ok\t%s\t%v\n", r.Path, r.Runtime)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } return nil @@ -75,39 +75,39 @@ func (p PrinterGo) PrintTest(w StringWriter, r *TestResult, verbose bool) error if r.Skipped { _, err := w.WriteString(fmt.Sprintf("=== SKIP %s\n", r.Name)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } return nil } _, err := w.WriteString(fmt.Sprintf("=== RUN %s\n", r.Name)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } for i := range r.CaseResults { err := p.PrintCase(w, &r.CaseResults[i], verbose) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } if r.IsFailure() { _, err := w.WriteString(fmt.Sprintf("--- FAIL: %s\t(%v)\n", r.Name, r.Runtime)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } if r.Error != nil { _, err = w.WriteString(fmt.Sprintf(" %v\n", r.Error)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } } else if verbose { _, err := w.WriteString(fmt.Sprintf("--- PASS: %s\t(%v)\n", r.Name, r.Runtime)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } return nil @@ -118,26 +118,26 @@ func (p PrinterGo) PrintCase(w StringWriter, r *CaseResult, verbose bool) error if r.Skipped { _, err := w.WriteString(fmt.Sprintf(" === SKIP %s\n", r.Name)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } return nil } _, err := w.WriteString(fmt.Sprintf(" === RUN %s\n", r.Name)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } if r.Error != nil { _, err := w.WriteString(fmt.Sprintf(" --- FAIL: %s\t(%v)\n %v\n", r.Name, r.Runtime, r.Error)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } else if verbose { _, err := w.WriteString(fmt.Sprintf(" --- PASS: %s\t(%v)\n", r.Name, r.Runtime)) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } @@ -149,7 +149,7 @@ func (p PrinterGo) PrintCase(w StringWriter, r *CaseResult, verbose bool) error } _, err := w.WriteString(fmt.Sprintf("%sTRACE: %s\t%s\n", prefix, r.Name, strings.ReplaceAll(*r.Trace, "\n", "\n"+prefix))) if err != nil { - return fmt.Errorf("%w: %v", ErrWritingString, err) + return fmt.Errorf("%w: %w", ErrWritingString, err) } } diff --git a/pkg/gator/verify/printer_go_test.go b/pkg/gator/verify/printer_go_test.go index d49ae0f67d3..0be62381696 100644 --- a/pkg/gator/verify/printer_go_test.go +++ b/pkg/gator/verify/printer_go_test.go @@ -282,7 +282,7 @@ PASS CaseResults: []CaseResult{{ Name: "case name", Runtime: Duration(100 * time.Millisecond), - Trace: pointer.StringPtr("this is a trace"), + Trace: pointer.String("this is a trace"), }}, }, }, diff --git a/pkg/gator/verify/read_suites.go b/pkg/gator/verify/read_suites.go index bdbaf8a1c6d..684d7ecc359 100644 --- a/pkg/gator/verify/read_suites.go +++ b/pkg/gator/verify/read_suites.go @@ -8,7 +8,7 @@ import ( "sort" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -186,7 +186,7 @@ func readSuite(f fs.FS, path string) (*Suite, error) { } err = yaml.Unmarshal(bytes, u.Object) if err != nil { - return nil, fmt.Errorf("%w: parsing yaml file %q: %v", gator.ErrInvalidYAML, path, err) + return nil, fmt.Errorf("%w: parsing yaml file %q: %w", gator.ErrInvalidYAML, path, err) } gvk := u.GroupVersionKind() if gvk.Group != Group || gvk.Kind != Kind { @@ -198,7 +198,7 @@ func readSuite(f fs.FS, path string) (*Suite, error) { err = gator.ParseYaml(bytes, &suite) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrInvalidYAML, err) + return nil, fmt.Errorf("%w: %w", gator.ErrInvalidYAML, err) } return &suite, nil diff --git a/pkg/gator/verify/read_suites_test.go b/pkg/gator/verify/read_suites_test.go index e0943932034..95784ddd947 100644 --- a/pkg/gator/verify/read_suites_test.go +++ b/pkg/gator/verify/read_suites_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" "k8s.io/utils/pointer" ) @@ -369,7 +369,7 @@ tests: Object: "deny.yaml", Assertions: []Assertion{{ Violations: gator.IntStrFromInt(2), - Message: pointer.StringPtr("some message"), + Message: pointer.String("some message"), }}, }}, }}, @@ -410,7 +410,7 @@ tests: Object: "deny.yaml", Assertions: []Assertion{{ Violations: gator.IntStrFromInt(2), - Message: pointer.StringPtr("some message"), + Message: pointer.String("some message"), }}, }}, }}, @@ -451,7 +451,7 @@ tests: Object: "deny.yaml", Assertions: []Assertion{{ Violations: gator.IntStrFromInt(2), - Message: pointer.StringPtr("some message"), + Message: pointer.String("some message"), }}, }}, }}, @@ -492,7 +492,7 @@ tests: Object: "deny.yaml", Assertions: []Assertion{{ Violations: gator.IntStrFromInt(2), - Message: pointer.StringPtr("some message"), + Message: pointer.String("some message"), }}, }}, }}, diff --git a/pkg/gator/verify/runner.go b/pkg/gator/verify/runner.go index 3a240adbcdd..64255204036 100644 --- a/pkg/gator/verify/runner.go +++ b/pkg/gator/verify/runner.go @@ -10,12 +10,12 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/apis" - "github.com/open-policy-agent/gatekeeper/pkg/gator" - "github.com/open-policy-agent/gatekeeper/pkg/gator/reader" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/apis" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/reader" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -31,14 +31,16 @@ type Runner struct { // newClient instantiates a Client for compiling Templates/Constraints, and // validating objects against them. - newClient func(includeTrace bool) (gator.Client, error) + newClient func(includeTrace bool, useK8sCEL bool) (gator.Client, error) scheme *runtime.Scheme includeTrace bool + + useK8sCEL bool } -func NewRunner(filesystem fs.FS, newClient func(includeTrace bool) (gator.Client, error), opts ...RunnerOptions) (*Runner, error) { +func NewRunner(filesystem fs.FS, newClient func(includeTrace bool, useK8sCEL bool) (gator.Client, error), opts ...RunnerOptions) (*Runner, error) { s := runtime.NewScheme() err := apis.AddToScheme(s) if err != nil { @@ -66,6 +68,12 @@ func IncludeTrace(includeTrace bool) RunnerOptions { } } +func UseK8sCEL(useK8sCEL bool) RunnerOptions { + return func(r *Runner) { + r.useK8sCEL = useK8sCEL + } +} + // Run executes all Tests in the Suite and returns the results. func (r *Runner) Run(ctx context.Context, filter Filter, s *Suite) SuiteResult { start := time.Now() @@ -118,7 +126,7 @@ func (r *Runner) runTest(ctx context.Context, suiteDir string, filter Filter, t if errors.Is(err, constraints.ErrSchema) { err = nil } else { - err = fmt.Errorf("%w: got error %v but want %v", gator.ErrValidConstraint, err, constraints.ErrSchema) + err = fmt.Errorf("%w: got error %w but want %w", gator.ErrValidConstraint, err, constraints.ErrSchema) } } else if err == nil { results, err = r.runCases(ctx, suiteDir, filter, t) @@ -133,9 +141,9 @@ func (r *Runner) runTest(ctx context.Context, suiteDir string, filter Filter, t } func (r *Runner) tryAddConstraint(ctx context.Context, suiteDir string, t Test) error { - client, err := r.newClient(r.includeTrace) + client, err := r.newClient(r.includeTrace, r.useK8sCEL) if err != nil { - return fmt.Errorf("%w: %v", gator.ErrCreatingClient, err) + return fmt.Errorf("%w: %w", gator.ErrCreatingClient, err) } err = r.addTemplate(suiteDir, t.Template, client) @@ -188,9 +196,9 @@ func (r *Runner) skipCase(tc *Case) CaseResult { } func (r *Runner) makeTestClient(ctx context.Context, suiteDir string, t Test) (gator.Client, error) { - client, err := r.newClient(r.includeTrace) + client, err := r.newClient(r.includeTrace, r.useK8sCEL) if err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrCreatingClient, err) + return nil, fmt.Errorf("%w: %w", gator.ErrCreatingClient, err) } err = r.addTemplate(suiteDir, t.Template, client) @@ -218,7 +226,7 @@ func (r *Runner) addConstraint(ctx context.Context, suiteDir, constraintPath str _, err = client.AddConstraint(ctx, cObj) if err != nil { - return fmt.Errorf("%w: %v", gator.ErrAddingConstraint, err) + return fmt.Errorf("%w: %w", gator.ErrAddingConstraint, err) } return nil } @@ -235,7 +243,7 @@ func (r *Runner) addTemplate(suiteDir, templatePath string, client gator.Client) _, err = client.AddTemplate(context.Background(), template) if err != nil { - return fmt.Errorf("%w: %v", gator.ErrAddingTemplate, err) + return fmt.Errorf("%w: %w", gator.ErrAddingTemplate, err) } return nil @@ -271,7 +279,7 @@ func (r *Runner) checkCase(ctx context.Context, newClient func() (gator.Client, results := review.Results() if r.includeTrace { - trace = pointer.StringPtr(review.TraceDump()) + trace = pointer.String(review.TraceDump()) } for i := range tc.Assertions { err = tc.Assertions[i].Run(results) @@ -324,7 +332,7 @@ func (r *Runner) validateAndReviewAdmissionReviewRequest(ctx context.Context, c // convert unstructured into AdmissionReview, don't allow unknown fields var ar admissionv1.AdmissionReview if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(toReview.UnstructuredContent(), &ar, true); err != nil { - return nil, fmt.Errorf("%w: unable to convert to an AdmissionReview object, error: %v", gator.ErrInvalidK8sAdmissionReview, err) + return nil, fmt.Errorf("%w: unable to convert to an AdmissionReview object, error: %w", gator.ErrInvalidK8sAdmissionReview, err) } if ar.Request == nil { // then this admission review did not actually pass in an AdmissionRequest @@ -341,19 +349,19 @@ func (r *Runner) validateAndReviewAdmissionReviewRequest(ctx context.Context, c obj := &unstructured.Unstructured{} if ar.Request.Object.Raw != nil { if err := obj.UnmarshalJSON(ar.Request.Object.Raw); err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrUnmarshallObject, err.Error()) + return nil, fmt.Errorf("%w: %w", gator.ErrUnmarshallObject, err) } } if ar.Request.OldObject.Raw != nil { if err := obj.UnmarshalJSON(ar.Request.OldObject.Raw); err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrUnmarshallObject, err.Error()) + return nil, fmt.Errorf("%w: %w", gator.ErrUnmarshallObject, err) } } // parse into webhook/admission type req := &admission.Request{AdmissionRequest: *ar.Request} if err := util.SetObjectOnDelete(req); err != nil { - return nil, fmt.Errorf("%w: %v", gator.ErrNilOldObject, err.Error()) + return nil, fmt.Errorf("%w: %w", gator.ErrNilOldObject, err) } arr := target.AugmentedReview{ @@ -375,7 +383,7 @@ func (r *Runner) addInventory(ctx context.Context, c gator.Client, suiteDir, inv for _, obj := range inventory { _, err = c.AddData(ctx, obj) if err != nil { - return fmt.Errorf("%w: %v %v/%v: %v", + return fmt.Errorf("%w: %v %v/%v: %w", gator.ErrAddInventory, obj.GroupVersionKind(), obj.GetNamespace(), obj.GetName(), err) } } diff --git a/pkg/gator/verify/runner_integer_test.go b/pkg/gator/verify/runner_integer_test.go index b3915b64a3b..9868b984f34 100644 --- a/pkg/gator/verify/runner_integer_test.go +++ b/pkg/gator/verify/runner_integer_test.go @@ -6,7 +6,7 @@ import ( "testing" "testing/fstest" - "github.com/open-policy-agent/gatekeeper/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" ) const templateV1Beta1Integer = ` diff --git a/pkg/gator/verify/runner_test.go b/pkg/gator/verify/runner_test.go index c2d232660ad..ca55fb8e74a 100644 --- a/pkg/gator/verify/runner_test.go +++ b/pkg/gator/verify/runner_test.go @@ -10,8 +10,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/pkg/gator" - "github.com/open-policy-agent/gatekeeper/pkg/gator/fixtures" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator" + "github.com/open-policy-agent/gatekeeper/v3/pkg/gator/fixtures" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/pointer" ) @@ -983,7 +983,7 @@ func TestRunner_Run(t *testing.T) { }, { Name: "missing-namespace", Object: "object.yaml", - Assertions: []Assertion{{Violations: gator.IntStrFromStr("yes"), Message: pointer.StringPtr("missing Namespace")}}, + Assertions: []Assertion{{Violations: gator.IntStrFromStr("yes"), Message: pointer.String("missing Namespace")}}, }}, }}, }, @@ -1034,7 +1034,7 @@ func TestRunner_Run(t *testing.T) { { Name: "user doesn't begin with \"system:\"", Object: "non-system-ar.yaml", - Assertions: []Assertion{{Violations: gator.IntStrFromStr("yes"), Message: pointer.StringPtr("username is not allowed to perform this operation")}}, + Assertions: []Assertion{{Violations: gator.IntStrFromStr("yes"), Message: pointer.String("username is not allowed to perform this operation")}}, }, }, }, @@ -1207,7 +1207,7 @@ func TestRunner_Run_ClientError(t *testing.T) { TestResults: []TestResult{{Error: gator.ErrCreatingClient}}, } - runner, err := NewRunner(fstest.MapFS{}, func(includeTrace bool) (gator.Client, error) { + runner, err := NewRunner(fstest.MapFS{}, func(includeTrace bool, useK8sCEL bool) (gator.Client, error) { return nil, errors.New("error") }) if err != nil { @@ -1306,7 +1306,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintAlwaysValidate, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("first message"), + Message: pointer.String("first message"), }}, want: CaseResult{ Error: gator.ErrNumViolations, @@ -1381,7 +1381,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintAlwaysValidate, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("never validate"), + Message: pointer.String("never validate"), }}, want: CaseResult{ Error: gator.ErrNumViolations, @@ -1393,7 +1393,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidate, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("[enrv]+ [adeiltv]+"), + Message: pointer.String("[enrv]+ [adeiltv]+"), }}, want: CaseResult{}, }, @@ -1403,7 +1403,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidate, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("never validate [("), + Message: pointer.String("never validate [("), }}, want: CaseResult{ Error: gator.ErrInvalidRegex, @@ -1415,7 +1415,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidate, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("[enrv]+x [adeiltv]+"), + Message: pointer.String("[enrv]+x [adeiltv]+"), }}, want: CaseResult{ Error: gator.ErrNumViolations, @@ -1438,9 +1438,9 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidateTwice, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("first message"), + Message: pointer.String("first message"), }, { - Message: pointer.StringPtr("second message"), + Message: pointer.String("second message"), }}, want: CaseResult{}, }, @@ -1451,10 +1451,10 @@ func TestRunner_RunCase(t *testing.T) { object: fixtures.Object, assertions: []Assertion{{ Violations: gator.IntStrFromInt(1), - Message: pointer.StringPtr("first message"), + Message: pointer.String("first message"), }, { Violations: gator.IntStrFromInt(1), - Message: pointer.StringPtr("second message"), + Message: pointer.String("second message"), }}, want: CaseResult{}, }, @@ -1464,7 +1464,7 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidateTwice, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("[cdefinorst]+ [aegms]+"), + Message: pointer.String("[cdefinorst]+ [aegms]+"), }}, want: CaseResult{}, }, @@ -1475,7 +1475,7 @@ func TestRunner_RunCase(t *testing.T) { object: fixtures.Object, assertions: []Assertion{{ Violations: gator.IntStrFromInt(2), - Message: pointer.StringPtr("[cdefinorst]+ [aegms]+"), + Message: pointer.String("[cdefinorst]+ [aegms]+"), }}, want: CaseResult{}, }, @@ -1485,9 +1485,9 @@ func TestRunner_RunCase(t *testing.T) { constraint: fixtures.ConstraintNeverValidateTwice, object: fixtures.Object, assertions: []Assertion{{ - Message: pointer.StringPtr("first message"), + Message: pointer.String("first message"), }, { - Message: pointer.StringPtr("third message"), + Message: pointer.String("third message"), }}, want: CaseResult{ Error: gator.ErrNumViolations, diff --git a/pkg/instrumentation/types.go b/pkg/instrumentation/types.go new file mode 100644 index 00000000000..a9ca3103ac4 --- /dev/null +++ b/pkg/instrumentation/types.go @@ -0,0 +1,59 @@ +package instrumentation + +import ( + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + cfinstr "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" +) + +// StatWithDesc mirrors constraint framework instrumentation.Stat. +type StatWithDesc struct { + cfinstr.Stat + Description string `json:"description"` +} + +// StatsEntryWithDesc mirrors constraint framework instrumentation.StatsEntry. +type StatsEntryWithDesc struct { + // Scope is the level of granularity that the Stats + // were created at. + Scope string `json:"scope"` + // StatsFor is the specific kind of Scope type that Stats + // were created for. + StatsFor string `json:"statsFor"` + Stats []*StatWithDesc `json:"stats"` + Labels []*cfinstr.Label `json:"labels,omitempty"` +} + +// ToStatsEntriesWithDesc will use the client passed in to adorn constraint framework instrumentation.StatsEntry structs +// with a description and returns an array of StatsEntryWithDesc. +func ToStatsEntriesWithDesc(client *constraintclient.Client, cfentries []*cfinstr.StatsEntry) []*StatsEntryWithDesc { + var entriesWithDesc []*StatsEntryWithDesc + for _, se := range cfentries { + sewd := &StatsEntryWithDesc{ + Scope: se.Scope, + StatsFor: se.StatsFor, + Labels: se.Labels, + } + + var stats []*StatWithDesc + for _, stat := range se.Stats { + swd := &StatWithDesc{ + Stat: *stat, + } + + var desc string + if client != nil { + desc = client.GetDescriptionForStat(stat.Source, stat.Name) + } else { + desc = cfinstr.UnknownDescription + } + + swd.Description = desc + stats = append(stats, swd) + } + + sewd.Stats = stats + entriesWithDesc = append(entriesWithDesc, sewd) + } + + return entriesWithDesc +} diff --git a/pkg/instrumentation/types_test.go b/pkg/instrumentation/types_test.go new file mode 100644 index 00000000000..b5b9bea7bd0 --- /dev/null +++ b/pkg/instrumentation/types_test.go @@ -0,0 +1,154 @@ +package instrumentation + +import ( + "testing" + + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + cfinstr "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_ToStatsEntriesWithDesc(t *testing.T) { + driver, err := rego.New() + assert.NoError(t, err) + + actualClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + assert.NoError(t, err) + + testCases := []struct { + name string + client *constraintclient.Client + cfentries []*cfinstr.StatsEntry + expected []*StatsEntryWithDesc + }{ + { + name: "Empty input", + client: nil, + cfentries: []*cfinstr.StatsEntry{}, + expected: nil, + }, + { + name: "Single entry with one stat, unknown description", + client: nil, + cfentries: []*cfinstr.StatsEntry{ + { + Scope: "scope1", + StatsFor: "statsFor1", + Stats: []*cfinstr.Stat{ + { + Name: "stat1", + Value: "value1", + }, + }, + Labels: []*cfinstr.Label{ + { + Name: "label1", + Value: "lvalue1", + }, + }, + }, + }, + expected: []*StatsEntryWithDesc{ + { + Scope: "scope1", + StatsFor: "statsFor1", + Stats: []*StatWithDesc{ + { + Stat: cfinstr.Stat{ + Name: "stat1", + Value: "value1", + }, + Description: cfinstr.UnknownDescription, + }, + }, + Labels: []*cfinstr.Label{ + { + Name: "label1", + Value: "lvalue1", + }, + }, + }, + }, + }, + { + name: "actual client, stat", + client: actualClient, + cfentries: []*cfinstr.StatsEntry{ + { + Scope: "scope1", + StatsFor: "statsFor1", + Stats: []*cfinstr.Stat{ + { + Name: "templateRunTimeNS", + Value: "value1", + Source: cfinstr.Source{ + Type: cfinstr.EngineSourceType, + Value: "Rego", + }, + }, + { + Name: "constraintCount", + Value: "value1", + Source: cfinstr.Source{ + Type: cfinstr.EngineSourceType, + Value: "Rego", + }, + }, + }, + Labels: []*cfinstr.Label{ + { + Name: "label1", + Value: "lvalue1", + }, + }, + }, + }, + expected: []*StatsEntryWithDesc{ + { + Scope: "scope1", + StatsFor: "statsFor1", + Stats: []*StatWithDesc{ + { + Stat: cfinstr.Stat{ + Name: "templateRunTimeNS", + Value: "value1", + Source: cfinstr.Source{ + Type: cfinstr.EngineSourceType, + Value: "Rego", + }, + }, + Description: "the number of nanoseconds it took to evaluate all constraints for a template", + }, + { + Stat: cfinstr.Stat{ + Name: "constraintCount", + Value: "value1", + Source: cfinstr.Source{ + Type: cfinstr.EngineSourceType, + Value: "Rego", + }, + }, + Description: "the number of constraints that were evaluated for the given constraint kind", + }, + }, + Labels: []*cfinstr.Label{ + { + Name: "label1", + Value: "lvalue1", + }, + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := ToStatsEntriesWithDesc(tc.client, tc.cfentries) + require.Equal(t, tc.expected, result) + }) + } +} diff --git a/pkg/keys/config.go b/pkg/keys/config.go index 2959ccd5aa3..015f57ad3ef 100644 --- a/pkg/keys/config.go +++ b/pkg/keys/config.go @@ -16,7 +16,7 @@ limitations under the License. package keys import ( - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "k8s.io/apimachinery/pkg/types" ) diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index 48040680896..d9f4ec81b13 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -1,5 +1,12 @@ package logging +import ( + "github.com/go-logr/logr" + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + gkinstr "github.com/open-policy-agent/gatekeeper/v3/pkg/instrumentation" +) + // Log keys. const ( Process = "process" @@ -22,8 +29,18 @@ const ( ResourceAPIVersion = "resource_api_version" ResourceNamespace = "resource_namespace" ResourceName = "resource_name" + ResourceSourceType = "resource_source_type" RequestUsername = "request_username" MutationApplied = "mutation_applied" Mutator = "mutator" - DebugLevel = 2 // r.log.Debug(foo) == r.log.V(logging.DebugLevel).Info(foo) + DebugLevel = 1 // r.log.Debug(foo) == r.log.V(logging.DebugLevel).Info(foo) + ExecutionStats = "execution_stats" ) + +func LogStatsEntries(client *constraintclient.Client, logger logr.Logger, entries []*instrumentation.StatsEntry, msg string) { + if len(entries) == 0 { + return + } + + logger.WithValues(ExecutionStats, gkinstr.ToStatsEntriesWithDesc(client, entries)).Info(msg) +} diff --git a/pkg/logging/logging_test.go b/pkg/logging/logging_test.go new file mode 100644 index 00000000000..17ea7f3b120 --- /dev/null +++ b/pkg/logging/logging_test.go @@ -0,0 +1,128 @@ +package logging + +import ( + "bytes" + "fmt" + "testing" + + "github.com/go-logr/zapr" + constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func Test_LogStatsEntries(t *testing.T) { + testBuf := &bytes.Buffer{} + + encCfg := zap.NewProductionEncoderConfig() + enc := zapcore.NewJSONEncoder(encCfg) + + core := &fakeCore{ + LevelEnabler: zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { + return lvl >= zapcore.InfoLevel + }), + enc: enc, + buffer: testBuf, + } + + zapLogger := zap.New(core) + defer require.NoError(t, zapLogger.Sync()) + testLogger := zapr.NewLogger(zapLogger) + + // test log lines show up + LogStatsEntries( + &constraintclient.Client{}, + testLogger, + []*instrumentation.StatsEntry{ + { + Scope: "someScope", + StatsFor: "someConstranint", + Stats: []*instrumentation.Stat{ + { + Name: "someStat", + Value: "someValue", + Source: instrumentation.Source{ + Type: "someType", + Value: "someValue", + }, + }, + }, + Labels: []*instrumentation.Label{ + { + Name: "someLabel", + Value: "someLabelValue", + }, + }, + }, + }, + "test message", + ) + + expectedLogLine := fmt.Sprintf("\"msg\":\"test message\",\"execution_stats\":[{\"scope\":\"someScope\","+ + "\"statsFor\":\"someConstranint\",\"stats\":[{\"name\":\"someStat\",\"value\":\"someValue\","+ + "\"source\":{\"type\":\"someType\",\"value\":\"someValue\"},\"description\":\"%s\"}],"+ + "\"labels\":[{\"name\":\"someLabel\",\"value\":\"someLabelValue\"}]}]}\n", instrumentation.UnknownDescription) + require.Contains(t, testBuf.String(), expectedLogLine) + + // test that empty stats don't log + LogStatsEntries( + &constraintclient.Client{}, + testLogger, + []*instrumentation.StatsEntry{}, + "this message should not be logged", + ) + require.NotContains(t, testBuf.String(), "this message should not be logged") +} + +//// logging utilities for testing below ///// + +// Testing zapcore.Core implementation to intercept log entries in a buffer by choice. +// Consumers can inspect contents of the buffer to see if it matches expectations. +// Reusing buffers or loggers not encouraged since this implementation is not focused +// on thread safety, concurrency or reusability. +type fakeCore struct { + zapcore.LevelEnabler + enc zapcore.Encoder + buffer *bytes.Buffer +} + +func (c *fakeCore) With(fields []zapcore.Field) zapcore.Core { + clone := c.clone() + for _, f := range fields { + f.AddTo(clone.enc) + } + return clone +} + +func (c *fakeCore) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { //nolint:gocritic + if c.Enabled(e.Level) { + return ce.AddCore(e, c) + } + return ce +} + +func (c *fakeCore) Write(e zapcore.Entry, fields []zapcore.Field) error { //nolint:gocritic + for _, f := range fields { + f.AddTo(c.enc) + } + buf, err := c.enc.EncodeEntry(e, fields) + if err != nil { + return err + } + _, err = c.buffer.Write(buf.Bytes()) + return err +} + +func (c *fakeCore) Sync() error { + return nil // TODO(acpana): revisit implementation for GC / https://github.com/open-policy-agent/gatekeeper/issues/2748 +} + +func (c *fakeCore) clone() *fakeCore { + return &fakeCore{ + LevelEnabler: c.LevelEnabler, + enc: c.enc.Clone(), + buffer: c.buffer, + } +} diff --git a/pkg/metrics/exporter.go b/pkg/metrics/exporter.go index 79fd8e44234..d85691272d1 100644 --- a/pkg/metrics/exporter.go +++ b/pkg/metrics/exporter.go @@ -3,7 +3,7 @@ package metrics import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/metrics/registry" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics/registry" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" ) diff --git a/pkg/metrics/registry/registry.go b/pkg/metrics/registry/registry.go index 002806b5950..cd43aeb64fe 100644 --- a/pkg/metrics/registry/registry.go +++ b/pkg/metrics/registry/registry.go @@ -9,9 +9,9 @@ import ( "strings" // register exporters with the registry. - "github.com/open-policy-agent/gatekeeper/pkg/metrics/exporters/opencensus" - "github.com/open-policy-agent/gatekeeper/pkg/metrics/exporters/prometheus" - "github.com/open-policy-agent/gatekeeper/pkg/metrics/exporters/stackdriver" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics/exporters/opencensus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics/exporters/prometheus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics/exporters/stackdriver" ) func init() { @@ -60,7 +60,7 @@ func newExporterSet(exporters map[string]StartExporter) *exporterSet { func (es *exporterSet) String() string { contents := make([]string, 0) for k := range es.assignedExporters { - contents = append(contents, string(k)) + contents = append(contents, k) } return fmt.Sprintf("%s", contents) } diff --git a/pkg/metrics/registry/registry_test.go b/pkg/metrics/registry/registry_test.go index ea1812f76fa..392dadf2295 100644 --- a/pkg/metrics/registry/registry_test.go +++ b/pkg/metrics/registry/registry_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/open-policy-agent/gatekeeper/pkg/metrics/exporters/prometheus" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics/exporters/prometheus" ) // Validates flags parsing for metrics reporters. diff --git a/pkg/mutation/annotations.go b/pkg/mutation/annotations.go index 72b88156339..cba9b919624 100644 --- a/pkg/mutation/annotations.go +++ b/pkg/mutation/annotations.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/google/uuid" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/mutation/logging.go b/pkg/mutation/logging.go index 64dc0e02b1c..f95e4b8cf41 100644 --- a/pkg/mutation/logging.go +++ b/pkg/mutation/logging.go @@ -5,12 +5,12 @@ import ( "strings" "github.com/google/uuid" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -func logAppliedMutations(message string, mutationUUID uuid.UUID, obj *unstructured.Unstructured, allAppliedMutations [][]types.Mutator) { +func logAppliedMutations(message string, mutationUUID uuid.UUID, obj *unstructured.Unstructured, allAppliedMutations [][]types.Mutator, source types.SourceType) { iterations := make([]interface{}, 0, 2*len(allAppliedMutations)) for i, appliedMutations := range allAppliedMutations { if len(appliedMutations) == 0 { @@ -33,9 +33,22 @@ func logAppliedMutations(message string, mutationUUID uuid.UUID, obj *unstructur logging.ResourceKind, obj.GroupVersionKind().Kind, logging.ResourceAPIVersion, obj.GroupVersionKind().Version, logging.ResourceNamespace, obj.GetNamespace(), - logging.ResourceName, obj.GetName(), + logging.ResourceName, getNameOrGenerateName(obj), + logging.ResourceSourceType, source, + logging.ResourceLabels, obj.GetLabels(), } logDetails = append(logDetails, iterations...) log.Info(message, logDetails...) } } + +func getNameOrGenerateName(obj *unstructured.Unstructured) string { + resourceName := obj.GetName() + // for generated resources on CREATE, like a pod from a deployment, + // the name has not been populated yet, so we use the GeneratedName instead. + if resourceName == "" { + resourceName = obj.GetGenerateName() + } + + return resourceName +} diff --git a/pkg/mutation/match/match.go b/pkg/mutation/match/match.go index a65af53fc18..f0f935479a6 100644 --- a/pkg/mutation/match/match.go +++ b/pkg/mutation/match/match.go @@ -5,8 +5,7 @@ import ( "fmt" "reflect" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -20,62 +19,8 @@ var ErrMatch = errors.New("failed to run Match criteria") // Only for use in Match, not ApplyTo. const Wildcard = "*" -// Match selects objects to apply mutations to. -// +kubebuilder:object:generate=true -type Match struct { - // Source determines whether generated or original resources are matched. - // Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of - // `Generated` will only match generated resources, while `Original` will only - // match regular resources. - // +kubebuilder:validation:Enum=All;Generated;Original - Source string `json:"source,omitempty"` - Kinds []Kinds `json:"kinds,omitempty"` - // Scope determines if cluster-scoped and/or namespaced-scoped resources - // are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) - Scope apiextensionsv1.ResourceScope `json:"scope,omitempty"` - // Namespaces is a list of namespace names. If defined, a constraint only - // applies to resources in a listed namespace. Namespaces also supports a - // prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both - // `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both - // `kube-system` and `gatekeeper-system`. - Namespaces []util.Wildcard `json:"namespaces,omitempty"` - // ExcludedNamespaces is a list of namespace names. If defined, a - // constraint only applies to resources not in a listed namespace. - // ExcludedNamespaces also supports a prefix or suffix based glob. For example, - // `excludedNamespaces: [kube-*]` matches both `kube-system` and - // `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and - // `gatekeeper-system`. - ExcludedNamespaces []util.Wildcard `json:"excludedNamespaces,omitempty"` - // LabelSelector is the combination of two optional fields: `matchLabels` - // and `matchExpressions`. These two fields provide different methods of - // selecting or excluding k8s objects based on the label keys and values - // included in object metadata. All selection expressions from both - // sections are ANDed to determine if an object meets the cumulative - // requirements of the selector. - LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` - // NamespaceSelector is a label selector against an object's containing - // namespace or the object itself, if the object is a namespace. - NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"` - // Name is the name of an object. If defined, it will match against objects with the specified - // name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match - // both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`. - Name util.Wildcard `json:"name,omitempty"` -} - -// Kinds accepts a list of objects with apiGroups and kinds fields -// that list the groups/kinds of objects to which the mutation will apply. -// If multiple groups/kinds objects are specified, -// only one match is needed for the resource to be in scope. -// +kubebuilder:object:generate=true -type Kinds struct { - // APIGroups is the API groups the resources belong to. '*' is all groups. - // If '*' is present, the length of the slice must be one. - // Required. - APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"` - Kinds []string `json:"kinds,omitempty"` -} - // Matchable represent an object to be matched along with its metadata. +// +kubebuilder:object:generate=false type Matchable struct { Object client.Object Namespace *corev1.Namespace @@ -107,7 +52,7 @@ func Matches(match *Match, target *Matchable) (bool, error) { for _, fn := range topLevelMatchers { matches, err := fn(match, target) if err != nil { - return false, fmt.Errorf("%w: %v", ErrMatch, err) + return false, fmt.Errorf("%w: %w", ErrMatch, err) } if !matches { @@ -263,7 +208,7 @@ func namesMatch(match *Match, target *Matchable) (bool, error) { return true, nil } - return match.Name.Matches(target.Object.GetName()), nil + return match.Name.Matches(target.Object.GetName()) || match.Name.MatchesGenerateName(target.Object.GetGenerateName()), nil } func scopeMatch(match *Match, target *Matchable) (bool, error) { diff --git a/pkg/mutation/match/match_test.go b/pkg/mutation/match/match_test.go index 71b586d0d7d..5a5382fb4f2 100644 --- a/pkg/mutation/match/match_test.go +++ b/pkg/mutation/match/match_test.go @@ -4,8 +4,8 @@ import ( "errors" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -188,7 +188,7 @@ func TestMatch(t *testing.T) { name: "namespace matches", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name"), matcher: Match{ - Namespaces: []util.Wildcard{"nonmatching", "namespace"}, + Namespaces: []wildcard.Wildcard{"nonmatching", "namespace"}, }, namespace: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "namespace"}}, source: types.SourceTypeOriginal, @@ -198,7 +198,7 @@ func TestMatch(t *testing.T) { name: "is a matching Namespace", object: makeNamespace("matching"), matcher: Match{ - Namespaces: []util.Wildcard{"matching"}, + Namespaces: []wildcard.Wildcard{"matching"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -208,7 +208,7 @@ func TestMatch(t *testing.T) { name: "is not a matching Namespace", object: makeNamespace("non-matching"), matcher: Match{ - Namespaces: []util.Wildcard{"matching"}, + Namespaces: []wildcard.Wildcard{"matching"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -219,7 +219,7 @@ func TestMatch(t *testing.T) { name: "namespaces configured, but cluster scoped", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "", "name"), matcher: Match{ - Namespaces: []util.Wildcard{"nonmatching", "namespace"}, + Namespaces: []wildcard.Wildcard{"nonmatching", "namespace"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -229,7 +229,7 @@ func TestMatch(t *testing.T) { name: "namespace prefix matches", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "kube-system", "name"), matcher: Match{ - Namespaces: []util.Wildcard{"nonmatching", "kube-*"}, + Namespaces: []wildcard.Wildcard{"nonmatching", "kube-*"}, }, namespace: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "kube-system"}}, source: types.SourceTypeOriginal, @@ -239,7 +239,7 @@ func TestMatch(t *testing.T) { name: "namespace is not in the matches list", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace2", "name"), matcher: Match{ - Namespaces: []util.Wildcard{"nonmatching", "notmatchingeither"}, + Namespaces: []wildcard.Wildcard{"nonmatching", "notmatchingeither"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -319,7 +319,7 @@ func TestMatch(t *testing.T) { name: "object's namespace is excluded", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name"), matcher: Match{ - ExcludedNamespaces: []util.Wildcard{"namespace"}, + ExcludedNamespaces: []wildcard.Wildcard{"namespace"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -329,7 +329,7 @@ func TestMatch(t *testing.T) { name: "object is an excluded Namespace", object: makeNamespace("excluded"), matcher: Match{ - ExcludedNamespaces: []util.Wildcard{"excluded"}, + ExcludedNamespaces: []wildcard.Wildcard{"excluded"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -339,7 +339,7 @@ func TestMatch(t *testing.T) { name: "object is not an excluded Namespace", object: makeNamespace("not-excluded"), matcher: Match{ - ExcludedNamespaces: []util.Wildcard{"excluded"}, + ExcludedNamespaces: []wildcard.Wildcard{"excluded"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -350,7 +350,7 @@ func TestMatch(t *testing.T) { name: "a namespace is excluded, but object is cluster scoped", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "", "name"), matcher: Match{ - ExcludedNamespaces: []util.Wildcard{"namespace"}, + ExcludedNamespaces: []wildcard.Wildcard{"namespace"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -360,7 +360,7 @@ func TestMatch(t *testing.T) { name: "namespace is excluded by wildcard match", object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "kube-system", "name"), matcher: Match{ - ExcludedNamespaces: []util.Wildcard{"kube-*"}, + ExcludedNamespaces: []wildcard.Wildcard{"kube-*"}, }, namespace: &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "kube-system"}}, source: types.SourceTypeOriginal, @@ -598,7 +598,7 @@ func TestMatch(t *testing.T) { object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name-foo"), matcher: Match{ Name: "name-foo", - Namespaces: []util.Wildcard{"other-namespace"}, + Namespaces: []wildcard.Wildcard{"other-namespace"}, }, namespace: nil, source: types.SourceTypeOriginal, @@ -609,7 +609,7 @@ func TestMatch(t *testing.T) { object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name-foo"), matcher: Match{ Name: "name-foo", - Namespaces: []util.Wildcard{"my-ns"}, + Namespaces: []wildcard.Wildcard{"my-ns"}, Source: string(types.SourceTypeGenerated), }, source: types.SourceTypeGenerated, @@ -625,7 +625,7 @@ func TestMatch(t *testing.T) { object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name-foo"), matcher: Match{ Name: "name-foo", - Namespaces: []util.Wildcard{"my-ns"}, + Namespaces: []wildcard.Wildcard{"my-ns"}, }, source: types.SourceTypeGenerated, namespace: &corev1.Namespace{ @@ -640,7 +640,7 @@ func TestMatch(t *testing.T) { object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name-foo"), matcher: Match{ Name: "name-foo", - Namespaces: []util.Wildcard{"my-ns"}, + Namespaces: []wildcard.Wildcard{"my-ns"}, Source: string(types.SourceTypeOriginal), }, source: types.SourceTypeGenerated, @@ -656,7 +656,7 @@ func TestMatch(t *testing.T) { object: makeObject(schema.GroupVersionKind{Kind: "kind", Group: "group"}, "namespace", "name-foo"), matcher: Match{ Name: "name-foo", - Namespaces: []util.Wildcard{"my-ns"}, + Namespaces: []wildcard.Wildcard{"my-ns"}, Source: string(types.SourceTypeOriginal), }, namespace: &corev1.Namespace{ @@ -831,3 +831,210 @@ func TestApplyTo(t *testing.T) { }) } } + +func makeObjectWithGenerateName(gvk schema.GroupVersionKind, namespace, name string, options ...func(*unstructured.Unstructured)) *unstructured.Unstructured { + obj := &unstructured.Unstructured{Object: make(map[string]interface{})} + obj.SetGroupVersionKind(gvk) + obj.SetNamespace(namespace) + obj.SetGenerateName(name) + + for _, o := range options { + o(obj) + } + return obj +} + +func Test_namesMatch(t *testing.T) { + type args struct { + match *Match + target *Matchable + } + + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "match name with wild card", + args: args{ + match: &Match{ + Name: "foo*", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObject(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "foo-bar"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: true, + wantErr: false, + }, + { + name: "match generate name with wild card", + args: args{ + match: &Match{ + Name: "foo*", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObjectWithGenerateName(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "foo-bar-"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: true, + wantErr: false, + }, + { + name: "match different name with wild card", + args: args{ + match: &Match{ + Name: "foo*", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObject(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "fob"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "match different generate name with wild card", + args: args{ + match: &Match{ + Name: "foo*", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObjectWithGenerateName(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "fob-bar-"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "match whole name with generate name", + args: args{ + match: &Match{ + Name: "foo", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObjectWithGenerateName(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "foo"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "match prefix wildcard with generate name", + args: args{ + match: &Match{ + Name: "*foo", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObjectWithGenerateName(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "foo"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: false, + wantErr: false, + }, + { + name: "match later half of the name with wild card with generate name", + args: args{ + match: &Match{ + Name: "*-bar*", + Kinds: []Kinds{ + { + Kinds: []string{"Pod"}, + APIGroups: []string{"*"}, + }, + }, + }, + target: &Matchable{ + Object: makeObjectWithGenerateName(schema.GroupVersionKind{Kind: "Pod", Group: "*"}, "my-ns", "fob-bar"), + Namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ns", + }, + }, + }, + }, + want: true, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := namesMatch(tt.args.match, tt.args.target) + if (err != nil) != tt.wantErr { + t.Errorf("namesMatch() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("namesMatch() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/mutation/match/match_types.go b/pkg/mutation/match/match_types.go new file mode 100644 index 00000000000..9bc66540d16 --- /dev/null +++ b/pkg/mutation/match/match_types.go @@ -0,0 +1,75 @@ +// +kubebuilder:object:generate=true +// +groupName=match.gatekeeper.sh +package match + +import ( + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Match selects which objects are in scope. +// +kubebuilder:object:generate=true +type Match struct { + // Source determines whether generated or original resources are matched. + // Accepts `Generated`|`Original`|`All` (defaults to `All`). A value of + // `Generated` will only match generated resources, while `Original` will only + // match regular resources. + // +kubebuilder:validation:Enum=All;Generated;Original + Source string `json:"source,omitempty"` + Kinds []Kinds `json:"kinds,omitempty"` + // Scope determines if cluster-scoped and/or namespaced-scoped resources + // are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) + Scope apiextensionsv1.ResourceScope `json:"scope,omitempty"` + // Namespaces is a list of namespace names. If defined, a constraint only + // applies to resources in a listed namespace. Namespaces also supports a + // prefix or suffix based glob. For example, `namespaces: [kube-*]` matches both + // `kube-system` and `kube-public`, and `namespaces: [*-system]` matches both + // `kube-system` and `gatekeeper-system`. + Namespaces []wildcard.Wildcard `json:"namespaces,omitempty"` + // ExcludedNamespaces is a list of namespace names. If defined, a + // constraint only applies to resources not in a listed namespace. + // ExcludedNamespaces also supports a prefix or suffix based glob. For example, + // `excludedNamespaces: [kube-*]` matches both `kube-system` and + // `kube-public`, and `excludedNamespaces: [*-system]` matches both `kube-system` and + // `gatekeeper-system`. + ExcludedNamespaces []wildcard.Wildcard `json:"excludedNamespaces,omitempty"` + // LabelSelector is the combination of two optional fields: `matchLabels` + // and `matchExpressions`. These two fields provide different methods of + // selecting or excluding k8s objects based on the label keys and values + // included in object metadata. All selection expressions from both + // sections are ANDed to determine if an object meets the cumulative + // requirements of the selector. + LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` + // NamespaceSelector is a label selector against an object's containing + // namespace or the object itself, if the object is a namespace. + NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"` + // Name is the name of an object. If defined, it will match against objects with the specified + // name. Name also supports a prefix or suffix glob. For example, `name: pod-*` would match + // both `pod-a` and `pod-b`, and `name: *-pod` would match both `a-pod` and `b-pod`. + Name wildcard.Wildcard `json:"name,omitempty"` +} + +// Kinds accepts a list of objects with apiGroups and kinds fields +// that list the groups/kinds of objects to which the mutation will apply. +// If multiple groups/kinds objects are specified, +// only one match is needed for the resource to be in scope. +// +kubebuilder:object:generate=true +type Kinds struct { + // APIGroups is the API groups the resources belong to. '*' is all groups. + // If '*' is present, the length of the slice must be one. + // Required. + APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"` + Kinds []string `json:"kinds,omitempty"` +} + +// DummyCRD is a "dummy" CRD to hold the Match object, which we ultimately +// need to generate JSONSchemaProps. The TypeMeta and ObjectMeta fields are +// required for controller-gen to generate the CRD. +// +kubebuilder:resource:path="matchcrd" +type DummyCRD struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadataDummy,omitempty"` + + Match `json:"embeddedMatch,omitempty"` +} diff --git a/pkg/mutation/match/zz_generated.deepcopy.go b/pkg/mutation/match/zz_generated.deepcopy.go index 88cf2894ff7..26213f1e2d5 100644 --- a/pkg/mutation/match/zz_generated.deepcopy.go +++ b/pkg/mutation/match/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ limitations under the License. package match import ( - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -55,6 +55,24 @@ func (in *ApplyTo) DeepCopy() *ApplyTo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DummyCRD) DeepCopyInto(out *DummyCRD) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Match.DeepCopyInto(&out.Match) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DummyCRD. +func (in *DummyCRD) DeepCopy() *DummyCRD { + if in == nil { + return nil + } + out := new(DummyCRD) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Kinds) DeepCopyInto(out *Kinds) { *out = *in @@ -92,12 +110,12 @@ func (in *Match) DeepCopyInto(out *Match) { } if in.Namespaces != nil { in, out := &in.Namespaces, &out.Namespaces - *out = make([]util.Wildcard, len(*in)) + *out = make([]wildcard.Wildcard, len(*in)) copy(*out, *in) } if in.ExcludedNamespaces != nil { in, out := &in.ExcludedNamespaces, &out.ExcludedNamespaces - *out = make([]util.Wildcard, len(*in)) + *out = make([]wildcard.Wildcard, len(*in)) copy(*out, *in) } if in.LabelSelector != nil { diff --git a/pkg/mutation/mutation.go b/pkg/mutation/mutation.go index f2997c1594a..ad468b9afa2 100644 --- a/pkg/mutation/mutation.go +++ b/pkg/mutation/mutation.go @@ -15,8 +15,8 @@ package mutation import ( "flag" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -34,5 +34,5 @@ func init() { // Enabled indicates if the mutation feature is enabled. func Enabled() bool { - return operations.IsAssigned(operations.MutationStatus) || operations.IsAssigned(operations.MutationWebhook) + return operations.IsAssigned(operations.MutationStatus) || operations.IsAssigned(operations.MutationWebhook) || operations.IsAssigned(operations.MutationController) } diff --git a/pkg/mutation/mutators/assign/assign_mutator.go b/pkg/mutation/mutators/assign/assign_mutator.go index e06fee11cea..4315deb3ee3 100644 --- a/pkg/mutation/mutators/assign/assign_mutator.go +++ b/pkg/mutation/mutators/assign/assign_mutator.go @@ -3,18 +3,16 @@ package assign import ( "fmt" "reflect" - "sort" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/core" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - patht "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + patht "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "github.com/pkg/errors" runtimeschema "k8s.io/apimachinery/pkg/runtime/schema" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -38,22 +36,12 @@ type Mutator struct { // Mutator implements mutatorWithSchema. var _ schema.MutatorWithSchema = &Mutator{} -func (m *Mutator) Matches(mutable *types.Mutable) bool { - gvk := mutable.Object.GetObjectKind().GroupVersionKind() - if !match.AppliesTo(m.assign.Spec.ApplyTo, gvk) { - return false - } - target := &match.Matchable{ - Object: mutable.Object, - Namespace: mutable.Namespace, - Source: mutable.Source, - } - matches, err := match.Matches(&m.assign.Spec.Match, target) +func (m *Mutator) Matches(mutable *types.Mutable) (bool, error) { + res, err := core.MatchWithApplyTo(mutable, m.assign.Spec.ApplyTo, &m.assign.Spec.Match) if err != nil { log.Error(err, "Matches failed for assign", "assign", m.assign.Name) - return false } - return matches + return res, err } func (m *Mutator) TerminalType() parser.NodeType { @@ -68,7 +56,7 @@ func (m *Mutator) Mutate(mutable *types.Mutable) (bool, error) { return core.Mutate(m.Path(), m.tester, core.NewDefaultSetter(value), mutable.Object) } -func (m *Mutator) UsesExternalData() bool { +func (m *Mutator) MustTerminate() bool { return m.assign.Spec.Parameters.Assign.ExternalData != nil } @@ -128,8 +116,7 @@ func (m *Mutator) String() string { return fmt.Sprintf("%s/%s/%s:%d", m.id.Kind, m.id.Namespace, m.id.Name, m.assign.GetGeneration()) } -// MutatorForAssign returns an mutator built from -// the given assign instance. +// MutatorForAssign returns a mutator built from the given assign instance. func MutatorForAssign(assign *mutationsunversioned.Assign) (*Mutator, error) { // This is not always set by the kubernetes API server assign.SetGroupVersionKind(runtimeschema.GroupVersionKind{Group: mutationsv1beta1.GroupVersion.Group, Kind: "Assign"}) @@ -143,7 +130,7 @@ func MutatorForAssign(assign *mutationsunversioned.Assign) (*Mutator, error) { return nil, fmt.Errorf("assign %s can't change metadata", assign.GetName()) } - err = checkKeyNotChanged(path) + err = core.CheckKeyNotChanged(path) if err != nil { return nil, err } @@ -168,29 +155,17 @@ func MutatorForAssign(assign *mutationsunversioned.Assign) (*Mutator, error) { } } - id := types.MakeID(assign) - - pathTests, err := gatherPathTests(assign) + tester, err := core.NewTester(assign.GetName(), "Assign", path, assign.Spec.Parameters.PathTests) if err != nil { return nil, err } - tester, err := patht.New(path, pathTests) + gvks, err := core.NewValidatedBindings(assign.GetName(), "Assign", assign.Spec.ApplyTo) if err != nil { return nil, err } - for _, applyTo := range assign.Spec.ApplyTo { - if len(applyTo.Groups) == 0 || len(applyTo.Versions) == 0 || len(applyTo.Kinds) == 0 { - return nil, fmt.Errorf("invalid applyTo for Assign mutator %s, all of group, version and kind must be specified", assign.GetName()) - } - } - - gvks := getSortedGVKs(assign.Spec.ApplyTo) - if len(gvks) == 0 { - return nil, fmt.Errorf("applyTo required for Assign mutator %s", assign.GetName()) - } return &Mutator{ - id: id, + id: types.MakeID(assign), assign: assign.DeepCopy(), bindings: gvks, path: path, @@ -198,19 +173,6 @@ func MutatorForAssign(assign *mutationsunversioned.Assign) (*Mutator, error) { }, nil } -func gatherPathTests(assign *mutationsunversioned.Assign) ([]patht.Test, error) { - pts := assign.Spec.Parameters.PathTests - var pathTests []patht.Test - for _, pt := range pts { - p, err := parser.Parse(pt.SubPath) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf("problem parsing sub path `%s` for Assign %s", pt.SubPath, assign.GetName())) - } - pathTests = append(pathTests, patht.Test{SubPath: p, Condition: pt.Condition}) - } - return pathTests, nil -} - // IsValidAssign returns an error if the given assign object is not // semantically valid. func IsValidAssign(assign *mutationsunversioned.Assign) error { @@ -231,39 +193,6 @@ func hasMetadataRoot(path parser.Path) bool { return false } -// checkKeyNotChanged does not allow to change the key field of -// a list element. A path like foo[name: bar].name is rejected. -func checkKeyNotChanged(p parser.Path) error { - if len(p.Nodes) == 0 { - return errors.New("empty path") - } - if len(p.Nodes) < 2 { - return nil - } - lastNode := p.Nodes[len(p.Nodes)-1] - secondLastNode := p.Nodes[len(p.Nodes)-2] - - if secondLastNode.Type() != parser.ListNode { - return nil - } - if lastNode.Type() != parser.ObjectNode { - return fmt.Errorf("invalid path format: child of a list can't be a list") - } - addedObject, ok := lastNode.(*parser.Object) - if !ok { - return errors.New("failed converting an ObjectNodeType to Object") - } - listNode, ok := secondLastNode.(*parser.List) - if !ok { - return errors.New("failed converting a ListNodeType to List") - } - - if addedObject.Reference == listNode.KeyField { - return fmt.Errorf("invalid path format: changing the item key is not allowed") - } - return nil -} - func validateObjectAssignedToList(p parser.Path, value interface{}) error { if len(p.Nodes) == 0 { return errors.New("empty path") @@ -291,24 +220,3 @@ func validateObjectAssignedToList(p parser.Path, value interface{}) error { return nil } - -func getSortedGVKs(bindings []match.ApplyTo) []runtimeschema.GroupVersionKind { - // deduplicate GVKs - gvksMap := map[runtimeschema.GroupVersionKind]struct{}{} - for _, binding := range bindings { - for _, gvk := range binding.Flatten() { - gvksMap[gvk] = struct{}{} - } - } - - var gvks []runtimeschema.GroupVersionKind - for gvk := range gvksMap { - gvks = append(gvks, gvk) - } - - // we iterate over the map in a stable order so that - // unit tests won't be flaky. - sort.Slice(gvks, func(i, j int) bool { return gvks[i].String() < gvks[j].String() }) - - return gvks -} diff --git a/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go b/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go index d113862afd5..74deef1c5d6 100644 --- a/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/mutation/mutators/assign/assign_mutator_test.go b/pkg/mutation/mutators/assign/assign_mutator_test.go index a9d460ba50f..af4a19ef071 100644 --- a/pkg/mutation/mutators/assign/assign_mutator_test.go +++ b/pkg/mutation/mutators/assign/assign_mutator_test.go @@ -8,11 +8,12 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - path "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + path "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -91,7 +92,7 @@ func newPod(pod *corev1.Pod) *unstructured.Unstructured { func ensureObj(u *unstructured.Unstructured, expected interface{}, path ...string) error { v, exists, err := unstructured.NestedFieldNoCopy(u.Object, path...) if err != nil { - return fmt.Errorf("could not retrieve value: %v", err) + return fmt.Errorf("could not retrieve value: %w", err) } if !exists { return fmt.Errorf("value does not exist at %+v: %s", path, spew.Sdump(u.Object)) @@ -105,7 +106,7 @@ func ensureObj(u *unstructured.Unstructured, expected interface{}, path ...strin func ensureMissing(u *unstructured.Unstructured, path ...string) error { v, exists, err := unstructured.NestedFieldNoCopy(u.Object, path...) if err != nil { - return fmt.Errorf("could not retrieve value: %v", err) + return fmt.Errorf("could not retrieve value: %w", err) } if exists { return fmt.Errorf("value exists at %+v as %v, expected missing: %s", path, v, spew.Sdump(u.Object)) @@ -774,7 +775,8 @@ func TestApplyTo(t *testing.T) { Version: test.version, Kind: test.kind, }) - matches := mutator.Matches(&types.Mutable{Object: obj, Source: types.SourceTypeDefault}) + matches, err := mutator.Matches(&types.Mutable{Object: obj, Source: types.SourceTypeDefault}) + require.NoError(t, err) if matches != test.matchExpected { t.Errorf("Matches() = %t, expected %t", matches, test.matchExpected) } @@ -1070,3 +1072,12 @@ func nestedMapSlice(u map[string]interface{}, fields ...string) ([]map[string]in } return out, nil } + +// Tests the Assign mutator MutatorForAssign call with an empty spec for graceful handling. +func Test_Assign_emptySpec(t *testing.T) { + assign := &mutationsunversioned.Assign{} + mutator, err := MutatorForAssign(assign) + + require.ErrorContains(t, err, "empty path") + require.Nil(t, mutator) +} diff --git a/pkg/mutation/mutators/assignimage/assignimage_mutator.go b/pkg/mutation/mutators/assignimage/assignimage_mutator.go new file mode 100644 index 00000000000..d0862538a15 --- /dev/null +++ b/pkg/mutation/mutators/assignimage/assignimage_mutator.go @@ -0,0 +1,206 @@ +package assignimage + +import ( + "fmt" + + "github.com/google/go-cmp/cmp" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + patht "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/pkg/errors" + runtimeschema "k8s.io/apimachinery/pkg/runtime/schema" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var log = logf.Log.WithName("mutation").WithValues(logging.Process, "mutation", logging.Mutator, "assignimage") + +// Mutator is a mutator object built out of an AssignImage instance. +type Mutator struct { + id types.ID + assignImage *mutationsunversioned.AssignImage + + path parser.Path + + // bindings are the set of GVKs this Mutator applies to. + bindings []runtimeschema.GroupVersionKind + tester *patht.Tester +} + +// Mutator implements mutatorWithSchema. +var _ schema.MutatorWithSchema = &Mutator{} + +func (m *Mutator) Matches(mutable *types.Mutable) (bool, error) { + res, err := core.MatchWithApplyTo(mutable, m.assignImage.Spec.ApplyTo, &m.assignImage.Spec.Match) + if err != nil { + log.Error(err, "Matches failed for assign image", "assignImage", m.assignImage.Name) + } + return res, err +} + +func (m *Mutator) TerminalType() parser.NodeType { + return schema.String +} + +func (m *Mutator) Mutate(mutable *types.Mutable) (bool, error) { + p := m.assignImage.Spec.Parameters + s := setter{tag: p.AssignTag, domain: p.AssignDomain, path: p.AssignPath} + return core.Mutate(m.Path(), m.tester, s, mutable.Object) +} + +func (m *Mutator) MustTerminate() bool { + return true +} + +func (m *Mutator) ID() types.ID { + return m.id +} + +func (m *Mutator) SchemaBindings() []runtimeschema.GroupVersionKind { + return m.bindings +} + +func (m *Mutator) HasDiff(mutator types.Mutator) bool { + toCheck, ok := mutator.(*Mutator) + if !ok { // different types, different + return true + } + + if !cmp.Equal(toCheck.id, m.id) { + return true + } + if !cmp.Equal(toCheck.path, m.path) { + return true + } + if !cmp.Equal(toCheck.bindings, m.bindings) { + return true + } + + // any difference in spec may be enough + if !cmp.Equal(toCheck.assignImage.Spec, m.assignImage.Spec) { + return true + } + + return false +} + +func (m *Mutator) Path() parser.Path { + return m.path +} + +func (m *Mutator) DeepCopy() types.Mutator { + res := &Mutator{ + id: m.id, + assignImage: m.assignImage.DeepCopy(), + path: parser.Path{ + Nodes: make([]parser.Node, len(m.path.Nodes)), + }, + bindings: make([]runtimeschema.GroupVersionKind, len(m.bindings)), + } + + copy(res.path.Nodes, m.path.Nodes) + copy(res.bindings, m.bindings) + res.tester = m.tester.DeepCopy() + return res +} + +func (m *Mutator) String() string { + return fmt.Sprintf("%s/%s/%s:%d", m.id.Kind, m.id.Namespace, m.id.Name, m.assignImage.GetGeneration()) +} + +// MutatorForAssignImage returns a mutator built from +// the given assignImage instance. +func MutatorForAssignImage(assignImage *mutationsunversioned.AssignImage) (*Mutator, error) { + // This is not always set by the kubernetes API server + assignImage.SetGroupVersionKind(runtimeschema.GroupVersionKind{Group: mutationsv1beta1.GroupVersion.Group, Kind: "AssignImage"}) + + path, err := parser.Parse(assignImage.Spec.Location) + if err != nil { + return nil, errors.Wrapf(err, "invalid location format `%s` for assignImage %s", assignImage.Spec.Location, assignImage.GetName()) + } + + if core.HasMetadataRoot(path) { + return nil, newMetadataRootError(assignImage.GetName()) + } + + if hasListTerminal(path) { + return nil, newListTerminalError(assignImage.GetName()) + } + + err = core.CheckKeyNotChanged(path) + if err != nil { + return nil, err + } + + p := assignImage.Spec.Parameters + if err := validateImageParts(p.AssignDomain, p.AssignPath, p.AssignTag); err != nil { + return nil, fmt.Errorf("assignImage %s has invalid parameters: %w", assignImage.GetName(), err) + } + + tester, err := core.NewTester(assignImage.GetName(), "AssignImage", path, p.PathTests) + if err != nil { + return nil, err + } + + gvks, err := core.NewValidatedBindings(assignImage.GetName(), "AssignImage", assignImage.Spec.ApplyTo) + if err != nil { + return nil, err + } + + return &Mutator{ + id: types.MakeID(assignImage), + assignImage: assignImage.DeepCopy(), + bindings: gvks, + path: path, + tester: tester, + }, nil +} + +func hasListTerminal(path parser.Path) bool { + if len(path.Nodes) == 0 { + return false + } + return path.Nodes[len(path.Nodes)-1].Type() == parser.ListNode +} + +var _ core.Setter = setter{} + +type setter struct { + tag string + domain string + path string +} + +func (s setter) KeyedListOkay() bool { return false } + +func (s setter) KeyedListValue() (map[string]interface{}, error) { + panic("assignimage setter does not handle keyed lists") +} + +func (s setter) SetValue(obj map[string]interface{}, key string) error { + val, exists := obj[key] + strVal := "" + if exists { + val, ok := val.(string) + if !ok { + return fmt.Errorf("expected value at AssignImage location to be a string, got %v of type %T", val, val) + } + strVal = val + } + + obj[key] = mutateImage(s.domain, s.path, s.tag, strVal) + return nil +} + +// IsValidAssignImage returns an error if the given assignImage object is not +// semantically valid. +func IsValidAssignImage(assignImage *mutationsunversioned.AssignImage) error { + if _, err := MutatorForAssignImage(assignImage); err != nil { + return err + } + return nil +} diff --git a/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go b/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go new file mode 100644 index 00000000000..80a47cb1fba --- /dev/null +++ b/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go @@ -0,0 +1,104 @@ +package assignimage + +import ( + "fmt" + "strings" + "testing" + + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func assignImage(domain, path, tag, location string) *unversioned.AssignImage { + result := &unversioned.AssignImage{ + Spec: unversioned.AssignImageSpec{ + ApplyTo: []match.ApplyTo{{ + Groups: []string{"*"}, + Versions: []string{"*"}, + Kinds: []string{"*"}, + }}, + Location: location, + Parameters: unversioned.AssignImageParameters{ + AssignDomain: domain, + AssignPath: path, + AssignTag: tag, + }, + }, + } + + return result +} + +func benchmarkAssignImageMutator(b *testing.B, n int) { + ai := assignImage("a.b.c", "lib/repo", ":latest", "spec"+strings.Repeat(".spec", n-1)) + mutator, err := MutatorForAssignImage(ai) + if err != nil { + b.Fatal(err) + } + + obj := &unstructured.Unstructured{ + Object: make(map[string]interface{}), + } + p := make([]string, n) + for i := 0; i < n; i++ { + p[i] = "spec" + } + _, err = mutator.Mutate(&types.Mutable{Object: obj}) + if err != nil { + b.Fatal(err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = mutator.Mutate(&types.Mutable{Object: obj}) + } +} + +func benchmarkNoAssignImageMutator(b *testing.B, n int) { + location := "spec" + strings.Repeat(".spec", n-1) + a := assignImage("a.b.c", "lib/repo", ":latest", location) + a.Spec.Parameters.PathTests = []unversioned.PathTest{{ + SubPath: location, + Condition: tester.MustNotExist, + }} + mutator, err := MutatorForAssignImage(a) + if err != nil { + b.Fatal(err) + } + + obj := &unstructured.Unstructured{ + Object: make(map[string]interface{}), + } + p := make([]string, n) + for i := 0; i < n; i++ { + p[i] = "spec" + } + _, err = mutator.Mutate(&types.Mutable{Object: obj}) + if err != nil { + b.Fatal(err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = mutator.Mutate(&types.Mutable{Object: obj}) + } +} + +func BenchmarkAssignImageMutator_Mutate(b *testing.B) { + ns := []int{1, 2, 5, 10, 20} + + for _, n := range ns { + b.Run(fmt.Sprintf("always mutate %d-depth", n), func(b *testing.B) { + benchmarkAssignImageMutator(b, n) + }) + } + + for _, n := range ns { + b.Run(fmt.Sprintf("never mutate %d-depth", n), func(b *testing.B) { + benchmarkNoAssignImageMutator(b, n) + }) + } +} diff --git a/pkg/mutation/mutators/assignimage/assignimage_mutator_test.go b/pkg/mutation/mutators/assignimage/assignimage_mutator_test.go new file mode 100644 index 00000000000..854637146a8 --- /dev/null +++ b/pkg/mutation/mutators/assignimage/assignimage_mutator_test.go @@ -0,0 +1,394 @@ +package assignimage + +import ( + "errors" + "fmt" + "strings" + "testing" + + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +type aiTestConfig struct { + domain string + path string + tag string + + location string + pathTests []mutationsunversioned.PathTest + applyTo []match.ApplyTo +} + +func newAIMutator(cfg *aiTestConfig) *Mutator { + m := newAI(cfg) + m2, err := MutatorForAssignImage(m) + if err != nil { + panic(err) + } + return m2 +} + +func newAI(cfg *aiTestConfig) *mutationsunversioned.AssignImage { + m := &mutationsunversioned.AssignImage{ + ObjectMeta: metav1.ObjectMeta{ + Name: "Foo", + }, + } + m.Spec.Parameters.AssignDomain = cfg.domain + m.Spec.Parameters.AssignPath = cfg.path + m.Spec.Parameters.AssignTag = cfg.tag + m.Spec.Location = cfg.location + m.Spec.Parameters.PathTests = cfg.pathTests + m.Spec.ApplyTo = cfg.applyTo + return m +} + +func newPod(imageVal, name string) *unstructured.Unstructured { + pod := &corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Pod", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: name, + Image: imageVal, + }, + }, + }, + } + + u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pod) + if err != nil { + panic(fmt.Sprintf("converting pod to unstructured: %v", err)) + } + return &unstructured.Unstructured{Object: u} +} + +func newPodNoImage() *unstructured.Unstructured { + pod := &corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Pod", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "foo", + }, + }, + }, + } + + u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pod) + if err != nil { + panic(fmt.Sprintf("converting pod to unstructured: %v", err)) + } + return &unstructured.Unstructured{Object: u} +} + +func podTest(wantImage string) func(*unstructured.Unstructured) error { + return func(u *unstructured.Unstructured) error { + var pod corev1.Pod + err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &pod) + if err != nil { + return err + } + + if len(pod.Spec.Containers) != 1 { + return fmt.Errorf("incorrect number of containers: %d", len(pod.Spec.Containers)) + } + + c := pod.Spec.Containers[0] + if c.Image != wantImage { + return fmt.Errorf("image incorrect, got: %q wanted %v", c.Image, wantImage) + } + + return nil + } +} + +func TestMutate(t *testing.T) { + tests := []struct { + name string + obj *unstructured.Unstructured + cfg *aiTestConfig + fn func(*unstructured.Unstructured) error + }{ + { + name: "mutate tag", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + tag: ":new", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("library/busybox:new"), + }, + { + name: "mutate path and tag with empty image", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "library/busybox", + tag: ":new", + }, + obj: newPod("", "foo"), + fn: podTest("library/busybox:new"), + }, + { + name: "mutate path and tag with missing image", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "library/busybox", + tag: ":new", + }, + obj: newPodNoImage(), + fn: podTest("library/busybox:new"), + }, + { + name: "mutate path", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "new/repo", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("new/repo:v1"), + }, + { + name: "mutate domain", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + }, + obj: newPod("docker.io/library/busybox:v1", "foo"), + fn: podTest("myreg.io/library/busybox:v1"), + }, + { + name: "add domain", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("myreg.io/library/busybox:v1"), + }, + { + name: "add tag", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + tag: ":latest", + }, + obj: newPod("myreg.io/library/busybox", "foo"), + fn: podTest("myreg.io/library/busybox:latest"), + }, + { + name: "add digest", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + tag: "@sha256:12345678901234567890123456789012", + }, + obj: newPod("myreg.io/library/busybox", "foo"), + fn: podTest("myreg.io/library/busybox@sha256:12345678901234567890123456789012"), + }, + { + name: "mutate all field", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + path: "newlib/newbox", + tag: ":v2", + }, + obj: newPod("docker.io/library/busybox:v1", "foo"), + fn: podTest("myreg.io/newlib/newbox:v2"), + }, + { + name: "mutate path, domain not set", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "newlib/newbox", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("newlib/newbox:v1"), + }, + { + name: "mutate path and tag, no domain set", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "newlib/newbox", + tag: ":latest", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("newlib/newbox:latest"), + }, + { + name: "mutate tag to digest", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + tag: "@sha256:12345678901234567890123456789012", + }, + obj: newPod("library/busybox:v1", "foo"), + fn: podTest("library/busybox@sha256:12345678901234567890123456789012"), + }, + { + name: "mutate domain with bad imageref with no domain still converges", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + }, + obj: newPod("this/not.good:ABC123_//lib.com.repo//localhost@blah101", "foo"), + fn: podTest("myreg.io/this/not.good:ABC123_//lib.com.repo//localhost@blah101"), + }, + { + name: "mutate domain with bad imageref with domain still converges", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + }, + obj: newPod("a.b.c:5000//not.good:ABC123_//lib.com.repo//localhost@blah101", "foo"), + fn: podTest("myreg.io//not.good:ABC123_//lib.com.repo//localhost@blah101"), + }, + { + name: "mutate path and tag colon in imageref's domain still converges", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + path: "repo/app", + tag: ":latest", + }, + obj: newPod("a.b.c:/not.good:ABC123_//lib.com.repo//localhost@blah101", "foo"), + fn: podTest("a.b.c:/repo/app:latest"), + }, + { + name: "mutate path to domain-like string with domain set", + cfg: &aiTestConfig{ + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + location: `spec.containers[name:foo].image`, + domain: "myreg.io", + path: "my.special.repo/a.b/c", + }, + obj: newPod("a.b:latest", "foo"), + fn: podTest("myreg.io/my.special.repo/a.b/c:latest"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + mutator := newAIMutator(test.cfg) + obj := test.obj.DeepCopy() + _, err := mutator.Mutate(&types.Mutable{Object: obj}) + if err != nil { + t.Fatalf("failed mutation: %s", err) + } + if err := test.fn(obj); err != nil { + t.Errorf("failed test: %v", err) + } + }) + } +} + +func TestMutatorForAssignImage(t *testing.T) { + tests := []struct { + name string + cfg *aiTestConfig + errFn func(error) bool + }{ + { + name: "valid assignImage", + cfg: &aiTestConfig{ + domain: "a.b.c", + path: "new/app", + tag: ":latest", + location: "spec.containers[name:foo].image", + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + }, + }, + { + name: "metadata root returns err", + cfg: &aiTestConfig{ + domain: "a.b.c", + path: "new/app", + tag: ":latest", + location: "metadata.labels.image", + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + }, + errFn: func(err error) bool { + return errors.As(err, &metadataRootError{}) + }, + }, + { + name: "terminal list returns err", + cfg: &aiTestConfig{ + domain: "a.b.c", + path: "new/app", + tag: ":latest", + location: "spec.containers[name:foo]", + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + }, + errFn: func(err error) bool { + return errors.As(err, &listTerminalError{}) + }, + }, + { + name: "syntactically invalid location returns err", + cfg: &aiTestConfig{ + domain: "a.b.c", + path: "new/app", + tag: ":latest", + location: "/x/y/zx[)", + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + }, + errFn: func(err error) bool { + return strings.Contains(err.Error(), "invalid location format") + }, + }, + { + name: "bad assigns return err", + cfg: &aiTestConfig{ + domain: "", + path: "a.b.c/repo", + tag: ":latest", + location: "spec.containers[name:foo].image", + applyTo: []match.ApplyTo{{Groups: []string{""}, Versions: []string{"v1"}, Kinds: []string{"Foo"}}}, + }, + errFn: func(err error) bool { + return errors.As(err, &domainLikePathError{}) + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + mut, err := MutatorForAssignImage(newAI(tc.cfg)) + if err != nil && mut != nil { + t.Errorf("returned non-nil mutator but got err: %s", err) + } + if tc.errFn != nil { + if err == nil { + t.Errorf("wanted err but got nil") + } else if !tc.errFn(err) { + t.Errorf("got error of unexpected type: %s", err) + } + } + }) + } +} diff --git a/pkg/mutation/mutators/assignimage/errors.go b/pkg/mutation/mutators/assignimage/errors.go new file mode 100644 index 00000000000..7418d62b024 --- /dev/null +++ b/pkg/mutation/mutators/assignimage/errors.go @@ -0,0 +1,83 @@ +package assignimage + +import "fmt" + +type baseError struct { + s string +} + +func (e baseError) Error() string { + return e.s +} + +// Component field (domain|path|tag) errors. +type invalidDomainError struct{ baseError } + +type ( + invalidPathError struct{ baseError } + invalidTagError struct{ baseError } + missingComponentsError struct{ baseError } + domainLikePathError struct{ baseError } +) + +// Location field errors. +type ( + listTerminalError struct{ baseError } + metadataRootError struct{ baseError } +) + +func newInvalidDomainError(domain string) invalidDomainError { + return invalidDomainError{ + baseError{ + fmt.Sprintf("assignDomain %q must be a fully-qualified domain name or localhost", domain), + }, + } +} + +func newInvalidPathError(path string) invalidPathError { + return invalidPathError{ + baseError{ + fmt.Sprintf("assignPath %q must be a valid docker image path", path), + }, + } +} + +func newInvalidTagError(tag string) invalidTagError { + return invalidTagError{ + baseError{ + fmt.Sprintf("assignTag %q must be a valid docker image tag or digest starting with ':' or '@'", tag), + }, + } +} + +func newMissingComponentsError() missingComponentsError { + return missingComponentsError{ + baseError{ + "at least one of [assignDomain, assignPath, assignTag] must be set", + }, + } +} + +func newDomainLikePathError(path string) domainLikePathError { + return domainLikePathError{ + baseError{ + fmt.Sprintf("assignDomain must be set if the first part of assignPath %q can be interpretted as part of a domain", path), + }, + } +} + +func newListTerminalError(name string) listTerminalError { + return listTerminalError{ + baseError{ + fmt.Sprintf("assignImage %s cannot mutate list-type fields", name), + }, + } +} + +func newMetadataRootError(name string) metadataRootError { + return metadataRootError{ + baseError{ + fmt.Sprintf("assignImage %s can't change metadata", name), + }, + } +} diff --git a/pkg/mutation/mutators/assignimage/imageparser.go b/pkg/mutation/mutators/assignimage/imageparser.go new file mode 100644 index 00000000000..df00f15718d --- /dev/null +++ b/pkg/mutation/mutators/assignimage/imageparser.go @@ -0,0 +1,165 @@ +package assignimage + +import ( + "fmt" + "regexp" + "strings" +) + +var ( + // We perform validation on the components of an image string to ensure that + // the user cannot define a mutator which does not converge. This would + // otherwise be possible by injecting tokens we use to split an image string, + // [@:/], into components that would cause that component to be split the next + // time the mutation is applied and "leak" to its neighbor. Some validation is + // done as regex on individual components, and other validation which looks at + // multiple components together is done in code. All validation for domain and + // tag must be put in validateDomain and validateTag respectively. + + // domainRegexp defines a schema for a domain component. + domainRegexp = regexp.MustCompile(`(^\w[\w\-_]*\.[\w\-_\.]*[\w](:\d+)?$)|(^localhost(:\d+)?$)`) + + // pathRegexp defines a schema for a location component. It follows the convention + // specified in the docker distribution reference. The regex restricts + // location-components to start with an alphanumeric character, with following + // parts able to be separated by a separator (one period, one or two + // underscore and multiple dashes). + pathRegexp = regexp.MustCompile(`^[a-z0-9]+(?:(?:(?:[._/]|__|[-]*)[a-z0-9]+)+)?`) + + // tagRegexp defines a schema for a tag component. It must start with `:` or `@`. + tagRegexp = regexp.MustCompile(`(^:[\w][\w.-]{0,127}$)|(^@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,}$)`) +) + +type image struct { + domain string + path string + tag string +} + +func mutateImage(domain, path, tag, mutableImgRef string) string { + oldImg := newImage(mutableImgRef) + newImg := oldImg.newMutatedImage(domain, path, tag) + return newImg.fullRef() +} + +func newImage(imageRef string) image { + domain, remainder := splitDomain(imageRef) + path, tag := splitTag(remainder) + return image{domain: domain, path: path, tag: tag} +} + +// splitTag separates the path and tag components from a string. +func splitTag(remainder string) (string, string) { + var path string + tag := "" + if tagSep := strings.IndexAny(remainder, ":@"); tagSep > -1 { + path = remainder[:tagSep] + tag = remainder[tagSep:] + } else { + path = remainder + } + + return path, tag +} + +func (img image) newMutatedImage(domain, path, tag string) image { + return image{ + domain: ignoreUnset(img.domain, domain), + path: ignoreUnset(img.path, path), + tag: ignoreUnset(img.tag, tag), + } +} + +// ignoreUnset returns `new` if `new` is set, otherwise it returns `old`. +func ignoreUnset(old, new string) string { + if new != "" { + return new + } + return old +} + +func (img image) fullRef() string { + domain := img.domain + if domain != "" { + domain += "/" + } + return domain + img.path + img.tag +} + +func splitDomain(name string) (domain, remainder string) { + i := strings.IndexRune(name, '/') + if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") { + return "", name + } + return name[:i], name[i+1:] +} + +func validateDomain(domain string) error { + if domain == "" { + return nil + } + + if !domainRegexp.MatchString(domain) { + return newInvalidDomainError(domain) + } + + // The error below should theoretically be unreachable, as the regex + // validation should preclude this from happening. This check is included + // anyway to prevent code drift, and ensure that if a domain is validated + // it can also be recognized as a domain. + if d, r := splitDomain(domain + "/"); d != domain || r != "" { + return fmt.Errorf("domain %q could not be recognized as a valid domain", domain) + } + + return nil +} + +func validateTag(tag string) error { + if tag == "" { + return nil + } + + if !tagRegexp.MatchString(tag) { + return newInvalidTagError(tag) + } + + // This error should never happen because the regex above prevents it, but the + // check is included to prevent drift. Splitting the tag should return itself, + // and splitting a valid tag should never return a path. + if p, t := splitTag(tag); t != tag || p != "" { + return fmt.Errorf("tag %q could not be recognized as a valid tag or digest", tag) + } + + return nil +} + +func validateImageParts(domain, path, tag string) error { + if domain == "" && path == "" && tag == "" { + return newMissingComponentsError() + } + if err := validateDomain(domain); err != nil { + return err + } + // match the whole string for path (anchoring with `$` is tricky here) + if path != "" && path != pathRegexp.FindString(path) { + return newInvalidPathError(path) + } + if err := validateTag(tag); err != nil { + return err + } + + // Check if the path looks like a domain string, and the domain is not set. + // This prevents part of the path field from "leaking" to the domain, causing + // non convergent behavior. + // For example, suppose: domain="", path="gcr.io/repo", tag="" + // Suppose no value is currently set on the mutable, so the result is + // just "gcr.io/repo". When this value mutated again, "gcr.io" is parsed into + // the domain component, so the result would be "gcr.io/gcr.io/repo" and so on. + if domain == "" { + if d, _ := splitDomain(path); d != "" { + return newDomainLikePathError(path) + } + } + + return nil +} diff --git a/pkg/mutation/mutators/assignimage/imageparser_test.go b/pkg/mutation/mutators/assignimage/imageparser_test.go new file mode 100644 index 00000000000..22d63c9e971 --- /dev/null +++ b/pkg/mutation/mutators/assignimage/imageparser_test.go @@ -0,0 +1,468 @@ +package assignimage + +import ( + "errors" + "strings" + "testing" +) + +func TestNewImage(t *testing.T) { + tests := []struct { + name string + imageRef string + want image + }{ + { + name: "full image with tag", + imageRef: "gcr.io/some-image/hello:latest", + want: image{ + domain: "gcr.io", + path: "some-image/hello", + tag: ":latest", + }, + }, + { + name: "all empty components", + imageRef: "", + want: image{ + domain: "", + path: "", + tag: "", + }, + }, + { + name: "full image with hash", + imageRef: "some-image/hello@sha256:abcde", + want: image{ + domain: "", + path: "some-image/hello", + tag: "@sha256:abcde", + }, + }, + { + name: "slash in location with tag", + imageRef: "some-image/hello:latest", + want: image{ + domain: "", + path: "some-image/hello", + tag: ":latest", + }, + }, + { + name: "only location", + imageRef: "some-image/hello", + want: image{ + domain: "", + path: "some-image/hello", + tag: "", + }, + }, + { + name: "no slash in location", + imageRef: "some-image:tag123", + want: image{ + domain: "", + path: "some-image", + tag: ":tag123", + }, + }, + { + name: "just location", + imageRef: "alpine", + want: image{ + domain: "", + path: "alpine", + tag: "", + }, + }, + { + name: "leading underscore", + imageRef: "_/alpine", + want: image{ + domain: "", + path: "_/alpine", + tag: "", + }, + }, + { + name: "leading underscore with tag", + imageRef: "_/alpine:latest", + want: image{ + domain: "", + path: "_/alpine", + tag: ":latest", + }, + }, + { + name: "no domain, location has /", + imageRef: "library/busybox:v9", + want: image{ + domain: "", + path: "library/busybox", + tag: ":v9", + }, + }, + { + name: "dots in domain", + imageRef: "this.that.com/repo/alpine:1.23", + want: image{ + domain: "this.that.com", + path: "repo/alpine", + tag: ":1.23", + }, + }, + { + name: "port and dots in domain", + imageRef: "this.that.com:5000/repo/alpine:latest", + want: image{ + domain: "this.that.com:5000", + path: "repo/alpine", + tag: ":latest", + }, + }, + { + name: "localhost with port", + imageRef: "localhost:5000/repo/alpine:latest", + want: image{ + domain: "localhost:5000", + path: "repo/alpine", + tag: ":latest", + }, + }, + { + name: "dots in location", + imageRef: "x.y.z/gcr.io/repo:latest", + want: image{ + domain: "x.y.z", + path: "gcr.io/repo", + tag: ":latest", + }, + }, + { + name: "dot in domain", + imageRef: "gcr.io/repo:latest", + want: image{ + domain: "gcr.io", + path: "repo", + tag: ":latest", + }, + }, + { + name: "invalid ref still parses", + imageRef: "x.io/get/ready4.//this/not.good:404@yikes/bad/string", + want: image{ + domain: "x.io", + path: "get/ready4.//this/not.good", + tag: ":404@yikes/bad/string", + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := newImage(tc.imageRef) + if got != tc.want { + t.Errorf("got: %v, want %v", got, tc.want) + } + }) + } +} + +func isDomainError(domain string) func(error) bool { + return func(err error) bool { + return errors.As(err, &invalidDomainError{}) && strings.Contains(err.Error(), domain) + } +} + +func isPathError(path string) func(error) bool { + return func(err error) bool { + return errors.As(err, &invalidPathError{}) && strings.Contains(err.Error(), path) + } +} + +func isTagError(tag string) func(error) bool { + return func(err error) bool { + return errors.As(err, &invalidTagError{}) && strings.Contains(err.Error(), tag) + } +} + +func isEmptyArgsError() func(error) bool { + return func(err error) bool { + return errors.As(err, &missingComponentsError{}) + } +} + +func isPathlikeDomainError() func(error) bool { + return func(err error) bool { + return errors.As(err, &domainLikePathError{}) + } +} + +func TestValidateImageParts(t *testing.T) { + tests := []struct { + name string + domain string + path string + tag string + errFn func(error) bool + }{ + { + name: "all valid components", + domain: "my.register.io:5000", + path: "lib/stuff/app", + tag: ":latest", + }, + { + name: "no fields set returns err", + errFn: isEmptyArgsError(), + }, + { + name: "valid domain with port", + domain: "localhost:5000", + }, + { + name: "valid domain no port", + domain: "localhost", + }, + { + name: "valid domain with .", + domain: "a.b.c", + }, + { + name: "valid domain with - . and port", + domain: "a-b-c.com:5000", + }, + { + name: "valid domain with . and port", + domain: "a.b.c:123", + }, + { + name: "invalid domain no .", + domain: "foobar", + errFn: isDomainError("foobar"), + }, + { + name: "invalid domain leading .", + domain: ".foobar", + errFn: isDomainError(".foobar"), + }, + { + name: "invalid domain trailing .", + domain: "foobar.", + errFn: isDomainError("foobar."), + }, + { + name: "invalid domain . before port", + domain: "foobar.:5000", + errFn: isDomainError("foobar.:5000"), + }, + { + name: "invalid domain / before port", + domain: "foobar/:5000", + errFn: isDomainError("foobar/:5000"), + }, + { + name: "invalid domain leading and trailing .", + domain: ".foobar.", + errFn: isDomainError(".foobar."), + }, + { + name: "invalid domain with _ and port but no .", + domain: "a_b_c:123", + errFn: isDomainError("a_b_c:123"), + }, + { + name: "invalid domain with leading /", + domain: "/not.ok.io:2000", + errFn: isDomainError("/not.ok.io:2000"), + }, + { + name: "invalid domain with trailing /", + domain: "not.ok.io:2000/", + errFn: isDomainError("not.ok.io:2000/"), + }, + { + name: "invalid domain with middle /", + domain: "not/ok/io", + errFn: isDomainError("not/ok/io"), + }, + { + name: "invalid domain port start with alpha", + domain: "my.reg.io:abc2000", + errFn: isDomainError("my.reg.io:abc2000"), + }, + { + name: "invalid domain with multiple :", + domain: "my.reg.io:2000:", + errFn: isDomainError("my.reg.io:2000:"), + }, + { + name: "invalid domain with repeat :", + domain: "my.reg.io::2000", + errFn: isDomainError("my.reg.io::2000"), + }, + { + name: "invalid domain with tag", + domain: "my.reg.io:latest", + errFn: isDomainError("my.reg.io:latest"), + }, + { + name: "invalid domain with digest", + domain: "my.reg.io@sha256:abcde123456789", + errFn: isDomainError("my.reg.io@sha256:abcde123456789"), + }, + { + name: "invalid domain with bad character", + domain: ";!234.com", + errFn: isDomainError(";!234.com"), + }, + { + name: "valid path", + path: "lib/stuff", + }, + { + name: "domain-like path with domain", + domain: "my.reg.io:5000", + path: "a.b.c/stuff", + }, + { + name: "domain-like path without domain returns err", + path: "a.b.c/stuff", + tag: ":latest", + errFn: isPathlikeDomainError(), + }, + { + name: "valid path . and -", + path: "lib/stuff-app__thing/a/b--c/e", + }, + { + name: "invalid path ending / returns err", + path: "lib/stuff/app/", + errFn: isPathError("lib/stuff/app/"), + }, + { + name: "invalid path with leading / returns err", + path: "/lib/stuff/app", + errFn: isPathError("/lib/stuff/app"), + }, + { + name: "invalid path with leading : returns err", + domain: "my.register.io:5000", + path: ":lib/stuff/app", + errFn: isPathError(":lib/stuff/app"), + }, + { + name: "invalid path with leading @ returns err", + domain: "my.register.io:5000", + path: "@lib/stuff/app", + errFn: isPathError("@lib/stuff/app"), + }, + { + name: "invalid path with trailing : returns err", + domain: "my.register.io:5000", + path: "lib/stuff/app:", + errFn: isPathError("lib/stuff/app:"), + }, + { + name: "invalid path with trailing @ returns err", + domain: "my.register.io:5000", + path: "lib/stuff/app@", + errFn: isPathError("lib/stuff/app@"), + }, + { + name: "invalid path : in middle returns err", + domain: "my.register.io:5000", + path: "lib/stuff:things/app", + errFn: isPathError("lib/stuff:things/app"), + }, + { + name: "test valid tag", + tag: ":latest", + }, + { + name: "test valid digest", + tag: "@sha256:12345678901234567890123456789012", + }, + { + name: "invalid tag no leading :", + tag: "latest", + errFn: isTagError("latest"), + }, + { + name: "invalid digest no leading @", + tag: "sha256:12345678901234567890123456789012", + errFn: isTagError("sha256:12345678901234567890123456789012"), + }, + { + name: "invalid digest hash too short", + tag: "@sha256:123456", + errFn: isTagError("@sha256:123456"), + }, + { + name: "invalid digest not base 16", + tag: "@sha256:1XYZ5678901234567890123456789012", + errFn: isTagError("@sha256:1XYZ5678901234567890123456789012"), + }, + { + name: "invalid tag leading /", + tag: "/:latest", + errFn: isTagError("/:latest"), + }, + { + name: "invalid tag trailing /", + tag: ":latest/", + errFn: isTagError(":latest/"), + }, + { + name: "invalid tag trailing :", + tag: ":latest:", + errFn: isTagError(":latest:"), + }, + { + name: "invalid tag trailing @", + tag: ":latest@", + errFn: isTagError(":latest@"), + }, + { + name: "invalid tag : inside", + tag: ":lat:est", + errFn: isTagError(":lat:est"), + }, + { + name: "invalid tag @ inside", + tag: "@sha256:12345678901234567890123456789012@sha256:12345678901234567890123456789012", + errFn: isTagError("@sha256:12345678901234567890123456789012@sha256:12345678901234567890123456789012"), + }, + { + name: "invalid tag double :", + tag: "::latest", + errFn: isTagError("::latest"), + }, + { + name: "invalid digest double @", + tag: "@@sha256:1XYZ5678901234567890123456789012", + errFn: isTagError("@@sha256:1XYZ5678901234567890123456789012"), + }, + { + name: "invalid tag @ and :", + tag: "@:latest", + errFn: isTagError("@:latest"), + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := validateImageParts(tc.domain, tc.path, tc.tag) + if tc.errFn == nil && err != nil { + t.Errorf("(domain=%s, path=%s, tag=%s) did not want error but got: %v", tc.domain, tc.path, tc.tag, err) + } + if tc.errFn != nil { + if err == nil { + t.Errorf("(domain=%s, path=%s, tag=%s) wanted error but got nil", tc.domain, tc.path, tc.tag) + } else if !tc.errFn(err) { + t.Errorf("got error of unexpected type: %s", err) + } + } + }) + } +} diff --git a/pkg/mutation/mutators/assignmeta/assignmeta_mutator.go b/pkg/mutation/mutators/assignmeta/assignmeta_mutator.go index 21ee16902aa..634ec643231 100644 --- a/pkg/mutation/mutators/assignmeta/assignmeta_mutator.go +++ b/pkg/mutation/mutators/assignmeta/assignmeta_mutator.go @@ -5,14 +5,14 @@ import ( "reflect" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/core" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "github.com/pkg/errors" runtimeschema "k8s.io/apimachinery/pkg/runtime/schema" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -54,7 +54,7 @@ type Mutator struct { // Mutator implements mutator. var _ types.Mutator = &Mutator{} -func (m *Mutator) Matches(mutable *types.Mutable) bool { +func (m *Mutator) Matches(mutable *types.Mutable) (bool, error) { target := &match.Matchable{ Object: mutable.Object, Namespace: mutable.Namespace, @@ -63,9 +63,8 @@ func (m *Mutator) Matches(mutable *types.Mutable) bool { matches, err := match.Matches(&m.assignMetadata.Spec.Match, target) if err != nil { log.Error(err, "Matches failed for assign metadata", "assignMeta", m.assignMetadata.Name) - return false } - return matches + return matches, err } func (m *Mutator) Mutate(mutable *types.Mutable) (bool, error) { @@ -80,7 +79,7 @@ func (m *Mutator) Mutate(mutable *types.Mutable) (bool, error) { return core.Mutate(m.path, m.tester, core.NewDefaultSetter(value), mutable.Object) } -func (m *Mutator) UsesExternalData() bool { +func (m *Mutator) MustTerminate() bool { return m.assignMetadata.Spec.Parameters.Assign.ExternalData != nil } @@ -123,7 +122,7 @@ func (m *Mutator) String() string { return fmt.Sprintf("%s/%s/%s:%d", m.id.Kind, m.id.Namespace, m.id.Name, m.assignMetadata.GetGeneration()) } -// MutatorForAssignMetadata builds an Mutator from the given AssignMetadata object. +// MutatorForAssignMetadata builds a Mutator from the given AssignMetadata object. func MutatorForAssignMetadata(assignMeta *mutationsunversioned.AssignMetadata) (*Mutator, error) { // This is not always set by the kubernetes API server assignMeta.SetGroupVersionKind(runtimeschema.GroupVersionKind{Group: mutationsv1beta1.GroupVersion.Group, Kind: "AssignMetadata"}) diff --git a/pkg/mutation/mutators/assignmeta/assignmeta_mutator_benchmark_test.go b/pkg/mutation/mutators/assignmeta/assignmeta_mutator_benchmark_test.go index c9261d4afda..fe7f0b242ef 100644 --- a/pkg/mutation/mutators/assignmeta/assignmeta_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/assignmeta/assignmeta_mutator_benchmark_test.go @@ -3,8 +3,8 @@ package assignmeta import ( "testing" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/mutation/mutators/assignmeta/assignmeta_mutator_test.go b/pkg/mutation/mutators/assignmeta/assignmeta_mutator_test.go index 6fca949d1ad..5ab99f73be6 100644 --- a/pkg/mutation/mutators/assignmeta/assignmeta_mutator_test.go +++ b/pkg/mutation/mutators/assignmeta/assignmeta_mutator_test.go @@ -4,10 +4,10 @@ import ( "reflect" "testing" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -26,8 +26,8 @@ func newFoo(spec map[string]interface{}) *unstructured.Unstructured { return &unstructured.Unstructured{Object: data} } -func newAssignMetadataMutator(t *testing.T, path string, value mutationsunversioned.AssignField) *Mutator { - m := &mutationsunversioned.AssignMetadata{ +func newAssignMetadataMutator(t *testing.T, path string, value unversioned.AssignField) *Mutator { + m := &unversioned.AssignMetadata{ ObjectMeta: metav1.ObjectMeta{ Name: "Foo", }, @@ -47,13 +47,13 @@ func TestAssignMetadata(t *testing.T) { name string obj *unstructured.Unstructured path string - value mutationsunversioned.AssignField + value unversioned.AssignField expected interface{} }{ { name: "metadata value", path: "metadata.labels.foo", - value: mutationsunversioned.AssignField{FromMetadata: &mutationsunversioned.FromMetadata{Field: mutationsunversioned.ObjName}}, + value: unversioned.AssignField{FromMetadata: &unversioned.FromMetadata{Field: unversioned.ObjName}}, obj: newFoo(map[string]interface{}{}), expected: map[string]interface{}{ "name": "my-foo", @@ -65,7 +65,7 @@ func TestAssignMetadata(t *testing.T) { { name: "external data placeholder", path: "metadata.labels.foo", - value: mutationsunversioned.AssignField{ + value: unversioned.AssignField{ ExternalData: &unversioned.ExternalData{ Provider: "some-provider", DataSource: types.DataSourceUsername, @@ -108,3 +108,12 @@ func TestAssignMetadata(t *testing.T) { }) } } + +// Tests the AssignMeta mutator MutatorForAssignMetadata call with an empty spec for graceful handling. +func Test_AssignMeta_emptySpec(t *testing.T) { + assignMeta := &unversioned.AssignMetadata{} + mutator, err := MutatorForAssignMetadata(assignMeta) + + require.ErrorContains(t, err, "invalid location for assignmetadat") + require.Nil(t, mutator) +} diff --git a/pkg/mutation/mutators/conversion.go b/pkg/mutation/mutators/conversion.go index b421c06e15f..8e57f9a99d5 100644 --- a/pkg/mutation/mutators/conversion.go +++ b/pkg/mutation/mutators/conversion.go @@ -1,10 +1,11 @@ package mutators import ( - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assign" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assignmeta" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/modifyset" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignimage" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignmeta" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/modifyset" ) // MutatorForAssign returns an AssignMutator built from @@ -18,7 +19,13 @@ func MutatorForAssignMetadata(assignMeta *mutationsunversioned.AssignMetadata) ( return assignmeta.MutatorForAssignMetadata(assignMeta) } -// MutatorForModifySet builds an AssignMetadataMutator from the given ModifySet object. +// MutatorForModifySet builds a ModifySetMutator from the given ModifySet object. func MutatorForModifySet(modifySet *mutationsunversioned.ModifySet) (*modifyset.Mutator, error) { return modifyset.MutatorForModifySet(modifySet) } + +// MutatorForAssignImage builds an AssignImageMutator from the given AssignImage +// object. +func MutatorForAssignImage(assignImage *mutationsunversioned.AssignImage) (*assignimage.Mutator, error) { + return assignimage.MutatorForAssignImage(assignImage) +} diff --git a/pkg/mutation/mutators/conversion_test.go b/pkg/mutation/mutators/conversion_test.go index 514923279c8..46006f389f9 100644 --- a/pkg/mutation/mutators/conversion_test.go +++ b/pkg/mutation/mutators/conversion_test.go @@ -5,11 +5,11 @@ import ( "testing" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/util" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -241,7 +241,7 @@ func TestAssignMetadataHasDiff(t *testing.T) { { "differentMatch", func(a *mutationsunversioned.AssignMetadata) { - a.Spec.Match.Namespaces = []util.Wildcard{"foo", "bar"} + a.Spec.Match.Namespaces = []wildcard.Wildcard{"foo", "bar"} }, true, }, diff --git a/pkg/mutation/mutators/core/mutation_function.go b/pkg/mutation/mutators/core/mutation_function.go index 12b98834ffb..dbc67efaacc 100644 --- a/pkg/mutation/mutators/core/mutation_function.go +++ b/pkg/mutation/mutators/core/mutation_function.go @@ -4,9 +4,9 @@ import ( "errors" "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - path "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + path "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/pkg/mutation/mutators/core/mutation_function_setter_test.go b/pkg/mutation/mutators/core/mutation_function_setter_test.go index 443adb1ee35..8ee1aba2ebe 100644 --- a/pkg/mutation/mutators/core/mutation_function_setter_test.go +++ b/pkg/mutation/mutators/core/mutation_function_setter_test.go @@ -1,10 +1,11 @@ package core import ( + "errors" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -27,7 +28,7 @@ func TestKeyedListIncompatible(t *testing.T) { } obj := &unstructured.Unstructured{Object: map[string]interface{}{}} m, err := Mutate(path, &tester.Tester{}, ¬KeyedSetter{}, obj) - if err != ErrNonKeyedSetter { + if !errors.Is(err, ErrNonKeyedSetter) { t.Errorf("wanted err = %+v, got %+v", ErrNonKeyedSetter, err) } if m != false { diff --git a/pkg/mutation/mutators/core/mutation_function_test.go b/pkg/mutation/mutators/core/mutation_function_test.go index 62c157f2093..6295fdb17a4 100644 --- a/pkg/mutation/mutators/core/mutation_function_test.go +++ b/pkg/mutation/mutators/core/mutation_function_test.go @@ -4,12 +4,12 @@ import ( "encoding/json" "testing" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/testhelpers" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/testhelpers" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/mutation/mutators/core/mutator.go b/pkg/mutation/mutators/core/mutator.go new file mode 100644 index 00000000000..507448d28c5 --- /dev/null +++ b/pkg/mutation/mutators/core/mutator.go @@ -0,0 +1,143 @@ +package core + +import ( + "fmt" + "reflect" + "sort" + + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + patht "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NewTester returns a patht.Tester for the given object name, kind path and +// pathtests. +func NewTester(name string, kind string, path parser.Path, ptests []unversioned.PathTest) (*patht.Tester, error) { + pathTests, err := gatherPathTests(name, kind, ptests) + if err != nil { + return nil, err + } + tester, err := patht.New(path, pathTests) + if err != nil { + return nil, err + } + + return tester, nil +} + +// NewValidatedBindings returns a slice of gvks from the given applies, or an +// error if the applies are invalid. +func NewValidatedBindings(name string, kind string, applies []match.ApplyTo) ([]schema.GroupVersionKind, error) { + for _, applyTo := range applies { + if len(applyTo.Groups) == 0 || len(applyTo.Versions) == 0 || len(applyTo.Kinds) == 0 { + return nil, fmt.Errorf("invalid applyTo for %s mutator %s, all of group, version and kind must be specified", kind, name) + } + } + + gvks := getSortedGVKs(applies) + if len(gvks) == 0 { + return nil, fmt.Errorf("applyTo required for %s mutator %s", kind, name) + } + + return gvks, nil +} + +func gatherPathTests(mutName string, mutKind string, pts []unversioned.PathTest) ([]patht.Test, error) { + var pathTests []patht.Test + for _, pt := range pts { + p, err := parser.Parse(pt.SubPath) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("problem parsing sub path `%s` for %s %s", pt.SubPath, mutKind, mutName)) + } + pathTests = append(pathTests, patht.Test{SubPath: p, Condition: pt.Condition}) + } + + return pathTests, nil +} + +func getSortedGVKs(bindings []match.ApplyTo) []schema.GroupVersionKind { + // deduplicate GVKs + gvksMap := map[schema.GroupVersionKind]struct{}{} + for _, binding := range bindings { + for _, gvk := range binding.Flatten() { + gvksMap[gvk] = struct{}{} + } + } + + var gvks []schema.GroupVersionKind + for gvk := range gvksMap { + gvks = append(gvks, gvk) + } + + // we iterate over the map in a stable order so that + // unit tests won't be flaky. + sort.Slice(gvks, func(i, j int) bool { return gvks[i].String() < gvks[j].String() }) + + return gvks +} + +// HasMetadataRoot returns true if the root node at given path references the +// metadata field. +func HasMetadataRoot(path parser.Path) bool { + if len(path.Nodes) == 0 { + return false + } + return reflect.DeepEqual(path.Nodes[0], &parser.Object{Reference: "metadata"}) +} + +// CheckKeyNotChanged does not allow to change the key field of +// a list element. A path like foo[name: bar].name is rejected. +func CheckKeyNotChanged(p parser.Path) error { + if len(p.Nodes) == 0 { + return errors.New("empty path") + } + if len(p.Nodes) < 2 { + return nil + } + lastNode := p.Nodes[len(p.Nodes)-1] + secondLastNode := p.Nodes[len(p.Nodes)-2] + + if secondLastNode.Type() != parser.ListNode { + return nil + } + if lastNode.Type() != parser.ObjectNode { + return fmt.Errorf("invalid path format: child of a list can't be a list") + } + addedObject, ok := lastNode.(*parser.Object) + if !ok { + return errors.New("failed converting an ObjectNodeType to Object") + } + listNode, ok := secondLastNode.(*parser.List) + if !ok { + return errors.New("failed converting a ListNodeType to List") + } + + if addedObject.Reference == listNode.KeyField { + return fmt.Errorf("invalid path format: changing the item key is not allowed") + } + + return nil +} + +func MatchWithApplyTo(mut *types.Mutable, applies []match.ApplyTo, mat *match.Match) (bool, error) { + gvk := mut.Object.GetObjectKind().GroupVersionKind() + if !match.AppliesTo(applies, gvk) { + return false, nil + } + + target := &match.Matchable{ + Object: mut.Object, + Namespace: mut.Namespace, + Source: mut.Source, + } + matches, err := match.Matches(mat, target) + if err != nil { + return false, err + } + + return matches, nil +} diff --git a/pkg/mutation/mutators/core/setter.go b/pkg/mutation/mutators/core/setter.go index a5e183d6e08..b264ca0d88c 100644 --- a/pkg/mutation/mutators/core/setter.go +++ b/pkg/mutation/mutators/core/setter.go @@ -3,7 +3,7 @@ package core import ( "fmt" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" ) // Setter tells the mutate function what to do once we have found the diff --git a/pkg/mutation/mutators/modifyset/modify_set_mutator.go b/pkg/mutation/mutators/modifyset/modify_set_mutator.go index ee7aa845c26..590d1920ea4 100644 --- a/pkg/mutation/mutators/modifyset/modify_set_mutator.go +++ b/pkg/mutation/mutators/modifyset/modify_set_mutator.go @@ -2,19 +2,16 @@ package modifyset import ( "fmt" - "reflect" - "sort" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1beta1" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/core" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - patht "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + mutationsv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1beta1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + patht "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" runtimeschema "k8s.io/apimachinery/pkg/runtime/schema" @@ -39,22 +36,12 @@ type Mutator struct { // Mutator implements mutatorWithSchema. var _ schema.MutatorWithSchema = &Mutator{} -func (m *Mutator) Matches(mutable *types.Mutable) bool { - gvk := mutable.Object.GetObjectKind().GroupVersionKind() - if !match.AppliesTo(m.modifySet.Spec.ApplyTo, gvk) { - return false - } - target := &match.Matchable{ - Object: mutable.Object, - Namespace: mutable.Namespace, - Source: mutable.Source, - } - matches, err := match.Matches(&m.modifySet.Spec.Match, target) +func (m *Mutator) Matches(mutable *types.Mutable) (bool, error) { + res, err := core.MatchWithApplyTo(mutable, m.modifySet.Spec.ApplyTo, &m.modifySet.Spec.Match) if err != nil { log.Error(err, "Matches failed for modify set", "modifyset", m.modifySet.Name) - return false } - return matches + return res, err } func (m *Mutator) TerminalType() parser.NodeType { @@ -75,7 +62,7 @@ func (m *Mutator) Mutate(mutable *types.Mutable) (bool, error) { ) } -func (m *Mutator) UsesExternalData() bool { +func (m *Mutator) MustTerminate() bool { // modify set doesn't use external data return false } @@ -147,37 +134,25 @@ func MutatorForModifySet(modifySet *mutationsunversioned.ModifySet) (*Mutator, e return nil, errors.Wrapf(err, "invalid location format `%s` for ModifySet %s", modifySet.Spec.Location, modifySet.GetName()) } - if hasMetadataRoot(path) { + if core.HasMetadataRoot(path) { return nil, fmt.Errorf("modifyset %s can't change metadata", modifySet.GetName()) } - if path.Nodes[len(path.Nodes)-1].Type() == parser.ListNode { + if len(path.Nodes) > 0 && path.Nodes[len(path.Nodes)-1].Type() == parser.ListNode { return nil, fmt.Errorf("final node in a modifyset location cannot be a keyed list") } - id := types.MakeID(modifySet) - - pathTests, err := gatherPathTests(modifySet) + tester, err := core.NewTester(modifySet.GetName(), "ModifySet", path, modifySet.Spec.Parameters.PathTests) if err != nil { return nil, err } - tester, err := patht.New(path, pathTests) + gvks, err := core.NewValidatedBindings(modifySet.GetName(), "ModifySet", modifySet.Spec.ApplyTo) if err != nil { return nil, err } - for _, applyTo := range modifySet.Spec.ApplyTo { - if len(applyTo.Groups) == 0 || len(applyTo.Versions) == 0 || len(applyTo.Kinds) == 0 { - return nil, fmt.Errorf("invalid applyTo for ModifySet mutator %s, all of group, version and kind must be specified", modifySet.GetName()) - } - } - - gvks := getSortedGVKs(modifySet.Spec.ApplyTo) - if len(gvks) == 0 { - return nil, fmt.Errorf("applyTo required for ModifySet mutator %s", modifySet.GetName()) - } return &Mutator{ - id: id, + id: types.MakeID(modifySet), modifySet: modifySet.DeepCopy(), bindings: gvks, path: path, @@ -185,19 +160,6 @@ func MutatorForModifySet(modifySet *mutationsunversioned.ModifySet) (*Mutator, e }, nil } -func gatherPathTests(modifySet *mutationsunversioned.ModifySet) ([]patht.Test, error) { - pts := modifySet.Spec.Parameters.PathTests - var pathTests []patht.Test - for _, pt := range pts { - p, err := parser.Parse(pt.SubPath) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf("problem parsing sub path `%s` for ModifySet %s", pt.SubPath, modifySet.GetName())) - } - pathTests = append(pathTests, patht.Test{SubPath: p, Condition: pt.Condition}) - } - return pathTests, nil -} - // IsValidModifySet returns an error if the given modifyset object is not // semantically valid. func IsValidModifySet(modifySet *mutationsunversioned.ModifySet) error { @@ -207,38 +169,6 @@ func IsValidModifySet(modifySet *mutationsunversioned.ModifySet) error { return nil } -func hasMetadataRoot(path parser.Path) bool { - if len(path.Nodes) == 0 { - return false - } - - if reflect.DeepEqual(path.Nodes[0], &parser.Object{Reference: "metadata"}) { - return true - } - return false -} - -func getSortedGVKs(bindings []match.ApplyTo) []runtimeschema.GroupVersionKind { - // deduplicate GVKs - gvksMap := map[runtimeschema.GroupVersionKind]struct{}{} - for _, binding := range bindings { - for _, gvk := range binding.Flatten() { - gvksMap[gvk] = struct{}{} - } - } - - var gvks []runtimeschema.GroupVersionKind - for gvk := range gvksMap { - gvks = append(gvks, gvk) - } - - // we iterate over the map in a stable order so that - // unit tests won't be flaky. - sort.Slice(gvks, func(i, j int) bool { return gvks[i].String() < gvks[j].String() }) - - return gvks -} - var _ core.Setter = setter{} type setter struct { diff --git a/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go b/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go index bb15d688017..c4793833556 100644 --- a/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go @@ -5,15 +5,15 @@ import ( "strings" "testing" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) func modifyset(value interface{}, location string) *unversioned.ModifySet { - result := &unversioned.ModifySet{ + return &unversioned.ModifySet{ Spec: unversioned.ModifySetSpec{ ApplyTo: []match.ApplyTo{{ Groups: []string{"*"}, @@ -29,8 +29,6 @@ func modifyset(value interface{}, location string) *unversioned.ModifySet { }, }, } - - return result } func benchmarkModifySetMutator(b *testing.B, n int) { diff --git a/pkg/mutation/mutators/modifyset/modify_set_mutator_test.go b/pkg/mutation/mutators/modifyset/modify_set_mutator_test.go new file mode 100644 index 00000000000..473e214e241 --- /dev/null +++ b/pkg/mutation/mutators/modifyset/modify_set_mutator_test.go @@ -0,0 +1,17 @@ +package modifyset + +import ( + "testing" + + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/stretchr/testify/require" +) + +// Tests the ModifySet mutator MutatorForModifySet call with an empty spec for graceful handling. +func Test_ModifySet_emptySpec(t *testing.T) { + modifySet := &mutationsunversioned.ModifySet{} + mutator, err := MutatorForModifySet(modifySet) + + require.ErrorContains(t, err, "applyTo required for ModifySet mutator") + require.Nil(t, mutator) +} diff --git a/pkg/mutation/mutators/modifyset/modify_set_test.go b/pkg/mutation/mutators/modifyset/modify_set_test.go index 2938eba269e..30c18ae6ecf 100644 --- a/pkg/mutation/mutators/modifyset/modify_set_test.go +++ b/pkg/mutation/mutators/modifyset/modify_set_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" ) func TestSetterMerge(t *testing.T) { diff --git a/pkg/mutation/mutators/testhelpers/dummy_mutator.go b/pkg/mutation/mutators/testhelpers/dummy_mutator.go index 12cc4b79745..bd5c0219205 100644 --- a/pkg/mutation/mutators/testhelpers/dummy_mutator.go +++ b/pkg/mutation/mutators/testhelpers/dummy_mutator.go @@ -3,11 +3,11 @@ package testhelpers import ( "reflect" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/core" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - path "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/tester" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/core" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + path "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/tester" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) var _ types.Mutator = &DummyMutator{} @@ -36,13 +36,13 @@ func (d *DummyMutator) Path() parser.Path { return d.path } -func (d *DummyMutator) Matches(mutable *types.Mutable) bool { +func (d *DummyMutator) Matches(mutable *types.Mutable) (bool, error) { m := &match.Matchable{Object: mutable.Object, Namespace: mutable.Namespace} matches, err := match.Matches(&d.match, m) if err != nil { - return false + return false, err } - return matches + return matches, nil } func (d *DummyMutator) Mutate(mutable *types.Mutable) (bool, error) { @@ -50,7 +50,7 @@ func (d *DummyMutator) Mutate(mutable *types.Mutable) (bool, error) { return core.Mutate(d.Path(), t, core.NewDefaultSetter(d.value), mutable.Object) } -func (d *DummyMutator) UsesExternalData() bool { +func (d *DummyMutator) MustTerminate() bool { return false } diff --git a/pkg/mutation/ordered_ids.go b/pkg/mutation/ordered_ids.go index 5e38cd6d1ae..4902481f9e3 100644 --- a/pkg/mutation/ordered_ids.go +++ b/pkg/mutation/ordered_ids.go @@ -3,7 +3,7 @@ package mutation import ( "sort" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type orderedIDs struct { diff --git a/pkg/mutation/ordered_ids_test.go b/pkg/mutation/ordered_ids_test.go index b01af2348cf..813135e3a80 100644 --- a/pkg/mutation/ordered_ids_test.go +++ b/pkg/mutation/ordered_ids_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) func fake(id types.ID) types.Mutator { diff --git a/pkg/mutation/path/parser/errors.go b/pkg/mutation/path/parser/errors.go index e4ae81ffce5..65924e7e35c 100644 --- a/pkg/mutation/path/parser/errors.go +++ b/pkg/mutation/path/parser/errors.go @@ -38,6 +38,5 @@ func (e invalidIntegerError) Error() string { } func (e invalidIntegerError) Is(target error) bool { - _, ok := target.(invalidIntegerError) - return ok + return errors.As(target, &invalidIntegerError{}) } diff --git a/pkg/mutation/path/parser/parser.go b/pkg/mutation/path/parser/parser.go index 580fd46d51c..b39f1a5fefa 100644 --- a/pkg/mutation/path/parser/parser.go +++ b/pkg/mutation/path/parser/parser.go @@ -18,7 +18,7 @@ package parser import ( "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/token" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/token" ) type parser struct { diff --git a/pkg/mutation/path/tester/tester.go b/pkg/mutation/path/tester/tester.go index e1de460e0f5..512219ec234 100644 --- a/pkg/mutation/path/tester/tester.go +++ b/pkg/mutation/path/tester/tester.go @@ -6,7 +6,7 @@ import ( "math" "reflect" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" ) // Condition describes whether the path either MustExist or MustNotExist in the original object diff --git a/pkg/mutation/path/tester/tester_test.go b/pkg/mutation/path/tester/tester_test.go index 74b01fc9edc..ce27a92e378 100644 --- a/pkg/mutation/path/tester/tester_test.go +++ b/pkg/mutation/path/tester/tester_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" ) func TestPrefix(t *testing.T) { diff --git a/pkg/mutation/schema/errors.go b/pkg/mutation/schema/errors.go index 699ce314f6a..242762349d3 100644 --- a/pkg/mutation/schema/errors.go +++ b/pkg/mutation/schema/errors.go @@ -1,9 +1,10 @@ package schema import ( + "errors" "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" ) // ErrNilMutator reports that a method which expected an actual Mutator was @@ -28,8 +29,8 @@ func (e ErrConflictingSchema) Error() string { } func (e ErrConflictingSchema) Is(other error) bool { - o, ok := other.(ErrConflictingSchema) - if !ok { + var o ErrConflictingSchema + if !errors.As(other, &o) { return false } diff --git a/pkg/mutation/schema/id_set.go b/pkg/mutation/schema/id_set.go index b283fdbbc7f..67236159c1b 100644 --- a/pkg/mutation/schema/id_set.go +++ b/pkg/mutation/schema/id_set.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" ) type IDSet map[types.ID]bool diff --git a/pkg/mutation/schema/node.go b/pkg/mutation/schema/node.go index b68515b7982..ba05b1a6838 100644 --- a/pkg/mutation/schema/node.go +++ b/pkg/mutation/schema/node.go @@ -3,9 +3,9 @@ package schema import ( "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" ) // node is an element of an implicit schema. @@ -14,7 +14,7 @@ type node struct { // ReferencedBy tracks the Mutations which reference this part of the schema tree. ReferencedBy IDSet - // Children is the set of child Nodes a this location in the schema. + // Children is the set of child Nodes at this location in the schema. // Each node defines a distinct child definition. If multiple Nodes are defined // for the same child, then there is a schema conflict. Children map[string]map[parser.NodeType]node diff --git a/pkg/mutation/schema/node_test.go b/pkg/mutation/schema/node_test.go index 2ddcd0f38e6..cbb6dd8666f 100644 --- a/pkg/mutation/schema/node_test.go +++ b/pkg/mutation/schema/node_test.go @@ -6,8 +6,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -132,6 +132,28 @@ func TestNode_Add(t *testing.T) { id("set"): true, }, }, + { + name: "string vs. set conflict", + before: []idPath{ + ipt("set", "spec.containers[name: foo].images", Set), + }, + add: ipt("string", "spec.containers[name: foo].images", String), + want: IDSet{ + id("set"): true, + id("string"): true, + }, + }, + { + name: "string vs. set conflict at nonterminal node", + before: []idPath{ + ipt("string", "spec.containers.image", String), + }, + add: ipt("set", "spec.containers", Set), + want: IDSet{ + id("set"): true, + id("string"): true, + }, + }, { name: "obj vs. set conflict", before: []idPath{ diff --git a/pkg/mutation/schema/schema.go b/pkg/mutation/schema/schema.go index bb1b5b130ac..f0a6b227c71 100644 --- a/pkg/mutation/schema/schema.go +++ b/pkg/mutation/schema/schema.go @@ -4,8 +4,8 @@ import ( "fmt" "sync" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/runtime/schema" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -106,7 +106,7 @@ func (db *DB) upsert(mutator MutatorWithSchema) error { s = &node{} db.schemas[gvk] = s } - newConflicts := s.Add(id, path.Nodes, mutator.TerminalType(), mutator.UsesExternalData()) + newConflicts := s.Add(id, path.Nodes, mutator.TerminalType(), mutator.MustTerminate()) conflicts = merge(conflicts, newConflicts) } @@ -143,7 +143,7 @@ func (db *DB) remove(id types.ID) { log.Error(nil, "mutator associated with missing schema", "mutator", id, "schema", gvk) panic(fmt.Sprintf("mutator %v associated with missing schema %v", id, gvk)) } - s.Remove(id, cachedMutator.Path().Nodes, cachedMutator.TerminalType(), cachedMutator.UsesExternalData()) + s.Remove(id, cachedMutator.Path().Nodes, cachedMutator.TerminalType(), cachedMutator.MustTerminate()) db.schemas[gvk] = s if len(s.ReferencedBy) == 0 { diff --git a/pkg/mutation/schema/schema_test.go b/pkg/mutation/schema/schema_test.go index 82063d7d575..c10a4bd227c 100644 --- a/pkg/mutation/schema/schema_test.go +++ b/pkg/mutation/schema/schema_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -34,7 +34,7 @@ func newFakeMutator(id types.ID, pathStr string, usesExternalData bool, bindings } } -func (m *fakeMutator) Matches(*types.Mutable) bool { +func (m *fakeMutator) Matches(*types.Mutable) (bool, error) { panic("should not be called") } @@ -42,7 +42,7 @@ func (m *fakeMutator) Mutate(*types.Mutable) (bool, error) { panic("should not be called") } -func (m *fakeMutator) UsesExternalData() bool { +func (m *fakeMutator) MustTerminate() bool { return m.usesExternalData } diff --git a/pkg/mutation/schema/terminal_types.go b/pkg/mutation/schema/terminal_types.go index c535af4cf00..f161089d065 100644 --- a/pkg/mutation/schema/terminal_types.go +++ b/pkg/mutation/schema/terminal_types.go @@ -1,6 +1,6 @@ package schema -import "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" +import "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" // Unknown represents a path element we do not know the type of. // Elements of type unknown do not conflict with path elements of known types. @@ -8,3 +8,6 @@ const Unknown = parser.NodeType("Unknown") // Set represents a list populated by unique values. const Set = parser.NodeType("Set") + +// String represents a string element. +const String = parser.NodeType("String") diff --git a/pkg/mutation/stats_reporter.go b/pkg/mutation/stats_reporter.go index d12f2e00e5f..661b70cf739 100644 --- a/pkg/mutation/stats_reporter.go +++ b/pkg/mutation/stats_reporter.go @@ -3,7 +3,7 @@ package mutation import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/mutation/system.go b/pkg/mutation/system.go index d24da2c06d8..da5dbfe1c01 100644 --- a/pkg/mutation/system.go +++ b/pkg/mutation/system.go @@ -7,9 +7,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/controller-runtime/pkg/certwatcher" @@ -183,7 +183,12 @@ func (s *System) mutate(mutable *types.Mutable) (int, error) { } mutator := s.mutatorsMap[id] - if mutator.Matches(mutable) { + matches, err := mutator.Matches(mutable) + if err != nil { + return iteration, matchesErr(err, mutator.ID(), mutable.Object) + } + + if matches { mutated, err := mutator.Mutate(mutable) if mutated { appliedMutations = append(appliedMutations, mutator) @@ -207,7 +212,7 @@ func (s *System) mutate(mutable *types.Mutable) (int, error) { } if *MutationLoggingEnabled { - logAppliedMutations("Mutation applied", mutationUUID, original, allAppliedMutations) + logAppliedMutations("Mutation applied", mutationUUID, original, allAppliedMutations, mutable.Source) } if *MutationAnnotationsEnabled { @@ -223,7 +228,7 @@ func (s *System) mutate(mutable *types.Mutable) (int, error) { } if *MutationLoggingEnabled { - logAppliedMutations("Mutation not converging", mutationUUID, original, allAppliedMutations) + logAppliedMutations("Mutation not converging", mutationUUID, original, allAppliedMutations, mutable.Source) } return maxIterations, fmt.Errorf("%w: mutation %s not converging for %s %s %s %s", @@ -232,7 +237,7 @@ func (s *System) mutate(mutable *types.Mutable) (int, error) { mutable.Object.GroupVersionKind().Group, mutable.Object.GroupVersionKind().Kind, mutable.Object.GetNamespace(), - mutable.Object.GetName()) + getNameOrGenerateName(mutable.Object)) } func mutateErr(err error, uid uuid.UUID, mID types.ID, obj *unstructured.Unstructured) error { @@ -242,5 +247,14 @@ func mutateErr(err error, uid uuid.UUID, mID types.ID, obj *unstructured.Unstruc obj.GroupVersionKind().Group, obj.GroupVersionKind().Kind, obj.GetNamespace(), - obj.GetName()) + getNameOrGenerateName(obj)) +} + +func matchesErr(err error, mID types.ID, obj *unstructured.Unstructured) error { + return errors.Wrapf(err, "matching for mutator %v failed for %s %s %s %s", + mID, + obj.GroupVersionKind().Group, + obj.GroupVersionKind().Kind, + obj.GetNamespace(), + getNameOrGenerateName(obj)) } diff --git a/pkg/mutation/system_annotations_test.go b/pkg/mutation/system_annotations_test.go index 80097d6929c..261831b0724 100644 --- a/pkg/mutation/system_annotations_test.go +++ b/pkg/mutation/system_annotations_test.go @@ -5,15 +5,15 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/utils/pointer" ) func TestSystem_Mutate_Annotations(t *testing.T) { - MutationAnnotationsEnabled = pointer.BoolPtr(true) + MutationAnnotationsEnabled = pointer.Bool(true) t.Cleanup(func() { - MutationAnnotationsEnabled = pointer.BoolPtr(false) + MutationAnnotationsEnabled = pointer.Bool(false) }) m := &fakeMutator{ diff --git a/pkg/mutation/system_benchmark_test.go b/pkg/mutation/system_benchmark_test.go index a6ac9858cfd..8e8bb998095 100644 --- a/pkg/mutation/system_benchmark_test.go +++ b/pkg/mutation/system_benchmark_test.go @@ -3,10 +3,10 @@ package mutation import ( "testing" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/mutation/system_errors_test.go b/pkg/mutation/system_errors_test.go index ce50a2e4847..a541a00eb5f 100644 --- a/pkg/mutation/system_errors_test.go +++ b/pkg/mutation/system_errors_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -38,15 +38,15 @@ type errorMutator struct { var _ types.Mutator = &errorMutator{} -func (e errorMutator) Matches(*types.Mutable) bool { - return true +func (e errorMutator) Matches(*types.Mutable) (bool, error) { + return true, nil } func (e errorMutator) Mutate(*types.Mutable) (bool, error) { return false, e.err } -func (e errorMutator) UsesExternalData() bool { +func (e errorMutator) MustTerminate() bool { return false } diff --git a/pkg/mutation/system_external_data.go b/pkg/mutation/system_external_data.go index 3f537f2e204..ea906f337dd 100644 --- a/pkg/mutation/system_external_data.go +++ b/pkg/mutation/system_external_data.go @@ -9,8 +9,8 @@ import ( externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" errorsutil "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" @@ -18,7 +18,7 @@ import ( // resolvePlaceholders resolves all external data placeholders in the given object. func (s *System) resolvePlaceholders(obj *unstructured.Unstructured) error { - providerKeys := make(map[string]sets.String) + providerKeys := make(map[string]sets.Set[string]) // recurse object to find all existing external data placeholders var recurse func(object interface{}) @@ -26,7 +26,7 @@ func (s *System) resolvePlaceholders(obj *unstructured.Unstructured) error { switch obj := object.(type) { case *unversioned.ExternalDataPlaceholder: if _, ok := providerKeys[obj.Ref.Provider]; !ok { - providerKeys[obj.Ref.Provider] = sets.NewString() + providerKeys[obj.Ref.Provider] = sets.New[string]() } // gather and de-duplicate all keys for this // provider so we can resolve them in batch @@ -62,7 +62,7 @@ func (s *System) resolvePlaceholders(obj *unstructured.Unstructured) error { } // sendRequests sends requests to all providers in parallel. -func (s *System) sendRequests(providerKeys map[string]sets.String, clientCert *tls.Certificate) (map[string]map[string]*externaldata.Item, map[string]error) { +func (s *System) sendRequests(providerKeys map[string]sets.Set[string], clientCert *tls.Certificate) (map[string]map[string]*externaldata.Item, map[string]error) { var ( wg sync.WaitGroup mutex sync.RWMutex @@ -108,7 +108,7 @@ func (s *System) sendRequests(providerKeys map[string]sets.String, clientCert *t item := item // for scoping responses[provider.Name][item.Key] = &item } - }(&provider, keys.List()) + }(&provider, keys.UnsortedList()) wg.Wait() } diff --git a/pkg/mutation/system_external_data_test.go b/pkg/mutation/system_external_data_test.go index 77b83d1b427..4bf374f904d 100644 --- a/pkg/mutation/system_external_data_test.go +++ b/pkg/mutation/system_external_data_test.go @@ -11,9 +11,9 @@ import ( externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/controller-runtime/pkg/certwatcher" ) diff --git a/pkg/mutation/system_test.go b/pkg/mutation/system_test.go index 438977e1735..5f7db49fa0d 100644 --- a/pkg/mutation/system_test.go +++ b/pkg/mutation/system_test.go @@ -7,10 +7,10 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" - mutationschema "github.com/open-policy-agent/gatekeeper/pkg/mutation/schema" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" + mutationschema "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/schema" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -36,8 +36,8 @@ type fakeMutator struct { Default *types.Anything } -func (m *fakeMutator) Matches(*types.Mutable) bool { - return true // always matches +func (m *fakeMutator) Matches(*types.Mutable) (bool, error) { + return true, nil // always matches } func (m *fakeMutator) Mutate(mutable *types.Mutable) (bool, error) { @@ -65,7 +65,7 @@ func (m *fakeMutator) Mutate(mutable *types.Mutable) (bool, error) { return true, nil } -func (m *fakeMutator) UsesExternalData() bool { +func (m *fakeMutator) MustTerminate() bool { return false } diff --git a/pkg/mutation/types/mutator.go b/pkg/mutation/types/mutator.go index 0bfaafd69b4..c3fc665b82e 100644 --- a/pkg/mutation/types/mutator.go +++ b/pkg/mutation/types/mutator.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/path/parser" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/path/parser" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" @@ -48,11 +48,11 @@ func IsValidSource(src SourceType) bool { // Mutator represent a mutation object. type Mutator interface { // Matches tells if the given object is eligible for this mutation. - Matches(mutable *Mutable) bool + Matches(mutable *Mutable) (bool, error) // Mutate applies the mutation to the given object Mutate(mutable *Mutable) (bool, error) - // UsesExternalData returns true if the mutation uses external data. - UsesExternalData() bool + // MustTerminate returns true if the mutator requires its path to terminate + MustTerminate() bool // ID returns the id of the current mutator. ID() ID // HasDiff tells if the mutator has meaningful differences diff --git a/pkg/mutation/types/mutator_test.go b/pkg/mutation/types/mutator_test.go index af08ed779fb..d6ced6e904d 100644 --- a/pkg/mutation/types/mutator_test.go +++ b/pkg/mutation/types/mutator_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" ) diff --git a/pkg/operations/operations.go b/pkg/operations/operations.go index 1de48cf9cb6..d51496d2c50 100644 --- a/pkg/operations/operations.go +++ b/pkg/operations/operations.go @@ -15,22 +15,23 @@ type Operation string // All defined Operations. const ( - Audit = Operation("audit") - Status = Operation("status") - MutationStatus = Operation("mutation-status") - MutationWebhook = Operation("mutation-webhook") - Webhook = Operation("webhook") + Audit = Operation("audit") + MutationController = Operation("mutation-controller") + MutationStatus = Operation("mutation-status") + MutationWebhook = Operation("mutation-webhook") + Status = Operation("status") + Webhook = Operation("webhook") ) var ( // allOperations is a list of all possible Operations that can be assigned to - // a pod. It is NOT intended to be mutated. It should be kept in alphabetical - // order so that it can be readily compared to the results from AssignedOperations. + // a pod. It is NOT intended to be mutated. allOperations = []Operation{ Audit, - Status, + MutationController, MutationStatus, MutationWebhook, + Status, Webhook, } @@ -85,18 +86,6 @@ func init() { flag.Var(operations, "operation", "The operation to be performed by this instance. e.g. audit, webhook. This flag can be declared more than once. Omitting will default to supporting all operations.") } -// AssignedOperations returns a map of operations assigned to the pod. -func AssignedOperations() map[Operation]bool { - ret := make(map[Operation]bool) - operationsMtx.RLock() - defer operationsMtx.RUnlock() - - for k, v := range operations.assignedOperations { - ret[k] = v - } - return ret -} - // IsAssigned returns true when the provided operation is assigned to the pod. func IsAssigned(op Operation) bool { operationsMtx.RLock() diff --git a/pkg/operations/operations_test.go b/pkg/operations/operations_test.go index 07da739ae9e..1865a6c630e 100644 --- a/pkg/operations/operations_test.go +++ b/pkg/operations/operations_test.go @@ -15,7 +15,7 @@ func Test_Flags(t *testing.T) { }{ "default": { input: []string{}, - expected: map[Operation]bool{Audit: true, Webhook: true, Status: true, MutationStatus: true, MutationWebhook: true}, + expected: map[Operation]bool{Audit: true, Webhook: true, Status: true, MutationStatus: true, MutationWebhook: true, MutationController: true}, }, "multiple": { input: []string{"-operation", "audit", "-operation", "webhook"}, diff --git a/pkg/pubsub/connection/connection.go b/pkg/pubsub/connection/connection.go new file mode 100644 index 00000000000..0edb6a74daf --- /dev/null +++ b/pkg/pubsub/connection/connection.go @@ -0,0 +1,17 @@ +package connection + +import ( + "context" +) + +// PubSub is the interface that wraps pubsub methods. +type Connection interface { + // Publish single message over a specific topic/channel + Publish(ctx context.Context, data interface{}, topic string) error + + // Close connections + CloseConnection() error + + // Update connection + UpdateConnection(ctx context.Context, data interface{}) error +} diff --git a/pkg/pubsub/dapr/dapr.go b/pkg/pubsub/dapr/dapr.go new file mode 100644 index 00000000000..ae20be72c64 --- /dev/null +++ b/pkg/pubsub/dapr/dapr.go @@ -0,0 +1,83 @@ +package dapr + +import ( + "context" + "encoding/json" + "fmt" + + daprClient "github.com/dapr/go-sdk/client" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" +) + +type ClientConfig struct { + // Name of the component to be used for pub sub messaging + Component string `json:"component"` +} + +// Dapr represents driver for interacting with pub sub using dapr. +type Dapr struct { + // Array of clients to talk to different endpoints + client daprClient.Client + + // Name of the pubsub component + pubSubComponent string +} + +const ( + Name = "dapr" +) + +func (r *Dapr) Publish(ctx context.Context, data interface{}, topic string) error { + jsonData, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("error marshaling data: %w", err) + } + + err = r.client.PublishEvent(context.Background(), r.pubSubComponent, topic, jsonData) + if err != nil { + return fmt.Errorf("error publishing message to dapr: %w", err) + } + + return nil +} + +func (r *Dapr) CloseConnection() error { + return nil +} + +func (r *Dapr) UpdateConnection(_ context.Context, config interface{}) error { + var cfg ClientConfig + m, ok := config.(map[string]interface{}) + if !ok { + return fmt.Errorf("invalid type assertion, config is not in expected format") + } + cfg.Component, ok = m["component"].(string) + if !ok { + return fmt.Errorf("failed to get value of component") + } + r.pubSubComponent = cfg.Component + return nil +} + +// Returns a new client for dapr. +func NewConnection(_ context.Context, config interface{}) (connection.Connection, error) { + var cfg ClientConfig + m, ok := config.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("invalid type assertion, config is not in expected format") + } + cfg.Component, ok = m["component"].(string) + if !ok { + return nil, fmt.Errorf("failed to get value of component") + } + + tmp, err := daprClient.NewClient() + if err != nil { + return nil, err + } + + return &Dapr{ + client: tmp, + pubSubComponent: cfg.Component, + }, nil +} diff --git a/pkg/pubsub/dapr/dapr_test.go b/pkg/pubsub/dapr/dapr_test.go new file mode 100644 index 00000000000..5a2e72615b1 --- /dev/null +++ b/pkg/pubsub/dapr/dapr_test.go @@ -0,0 +1,151 @@ +package dapr + +import ( + "context" + "os" + "testing" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" + "github.com/stretchr/testify/assert" +) + +var testClient connection.Connection + +func TestMain(m *testing.M) { + c, f := FakeConnection() + testClient = c + r := m.Run() + f() + + if r != 0 { + os.Exit(r) + } +} + +func TestNewConnection(t *testing.T) { + tests := []struct { + name string + config interface{} + expected connection.Connection + errorMsg string + }{ + { + name: "invalid config", + config: "test", + expected: nil, + errorMsg: "invalid type assertion, config is not in expected format", + }, + { + name: "config with missing component", + config: map[string]interface{}{"enableBatching": true}, + expected: nil, + errorMsg: "failed to get value of component", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ret, err := NewConnection(context.TODO(), tc.config) + assert.Equal(t, ret, tc.expected) + assert.EqualError(t, err, tc.errorMsg) + }) + } +} + +func TestDapr_Publish(t *testing.T) { + ctx := context.Background() + + type args struct { + ctx context.Context + data interface{} + topic string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "test publish", + args: args{ + ctx: ctx, + data: map[string]interface{}{ + "test": "test", + }, + topic: "test", + }, + wantErr: false, + }, + { + name: "test publish without data", + args: args{ + ctx: ctx, + data: nil, + topic: "test", + }, + wantErr: false, + }, + { + name: "test publish without topic", + args: args{ + ctx: ctx, + data: map[string]interface{}{ + "test": "test", + }, + topic: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := testClient + if err := r.Publish(tt.args.ctx, tt.args.data, tt.args.topic); (err != nil) != tt.wantErr { + t.Errorf("Dapr.Publish() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDapr_UpdateConnection(t *testing.T) { + tests := []struct { + name string + config interface{} + wantErr bool + }{ + { + name: "test update connection", + config: map[string]interface{}{ + "component": "foo", + }, + wantErr: false, + }, + { + name: "test update connection with invalid config", + config: map[string]interface{}{ + "foo": "bar", + }, + wantErr: true, + }, + { + name: "test update connection with nil config", + config: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := testClient + if err := r.UpdateConnection(context.Background(), tt.config); (err != nil) != tt.wantErr { + t.Errorf("Dapr.UpdateConnection() error = %v, wantErr %v", err, tt.wantErr) + } + if !tt.wantErr { + cmp, ok := tt.config.(map[string]interface{})["component"].(string) + assert.True(t, ok) + tmp, ok := r.(*Dapr) + assert.True(t, ok) + assert.Equal(t, cmp, tmp.pubSubComponent) + } + }) + } +} diff --git a/pkg/pubsub/dapr/fake_dapr_client.go b/pkg/pubsub/dapr/fake_dapr_client.go new file mode 100644 index 00000000000..322fccd269f --- /dev/null +++ b/pkg/pubsub/dapr/fake_dapr_client.go @@ -0,0 +1,387 @@ +package dapr + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "log" + "net" + "os" + "sync" + "time" + + daprClient "github.com/dapr/go-sdk/client" + commonv1pb "github.com/dapr/go-sdk/dapr/proto/common/v1" + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" + "github.com/golang/protobuf/ptypes/empty" + "github.com/google/uuid" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/bufconn" + "google.golang.org/protobuf/types/known/anypb" +) + +const ( + testBufSize = 1024 * 1024 + testSocket = "/tmp/dapr.socket" + valueSuffix = "_value" +) + +var logger = log.New(os.Stdout, "", 0) + +func getTestClient(ctx context.Context) (client daprClient.Client, closer func()) { + s := grpc.NewServer() + pb.RegisterDaprServer(s, &testDaprServer{ + state: make(map[string][]byte), + configurationSubscriptionID: map[string]chan struct{}{}, + }) + + l := bufconn.Listen(testBufSize) + go func() { + if err := s.Serve(l); err != nil && err.Error() != "closed" { + logger.Fatalf("test server exited with error: %v", err) + } + }() + + d := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { + return l.Dial() + }) + + c, err := grpc.DialContext(ctx, "", d, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + logger.Fatalf("failed to dial test context: %v", err) + } + + closer = func() { + l.Close() + s.Stop() + } + + client = daprClient.NewClientWithConnection(c) + return +} + +type testDaprServer struct { + pb.UnimplementedDaprServer + state map[string][]byte + configurationSubscriptionIDMapLoc sync.Mutex + configurationSubscriptionID map[string]chan struct{} +} + +func (s *testDaprServer) TryLockAlpha1(ctx context.Context, req *pb.TryLockRequest) (*pb.TryLockResponse, error) { + return &pb.TryLockResponse{ + Success: true, + }, nil +} + +func (s *testDaprServer) UnlockAlpha1(ctx context.Context, req *pb.UnlockRequest) (*pb.UnlockResponse, error) { + return &pb.UnlockResponse{ + Status: pb.UnlockResponse_SUCCESS, + }, nil +} + +func (s *testDaprServer) InvokeService(ctx context.Context, req *pb.InvokeServiceRequest) (*commonv1pb.InvokeResponse, error) { + if req.Message == nil { + return &commonv1pb.InvokeResponse{ + ContentType: "text/plain", + Data: &anypb.Any{ + Value: []byte("pong"), + }, + }, nil + } + return &commonv1pb.InvokeResponse{ + ContentType: req.Message.ContentType, + Data: req.Message.Data, + }, nil +} + +func (s *testDaprServer) GetState(ctx context.Context, req *pb.GetStateRequest) (*pb.GetStateResponse, error) { + return &pb.GetStateResponse{ + Data: s.state[req.Key], + Etag: "1", + }, nil +} + +func (s *testDaprServer) GetBulkState(ctx context.Context, in *pb.GetBulkStateRequest) (*pb.GetBulkStateResponse, error) { + items := make([]*pb.BulkStateItem, 0) + for _, k := range in.GetKeys() { + if v, found := s.state[k]; found { + item := &pb.BulkStateItem{ + Key: k, + Etag: "1", + Data: v, + } + items = append(items, item) + } + } + return &pb.GetBulkStateResponse{ + Items: items, + }, nil +} + +func (s *testDaprServer) SaveState(ctx context.Context, req *pb.SaveStateRequest) (*empty.Empty, error) { + for _, item := range req.States { + s.state[item.Key] = item.Value + } + return &empty.Empty{}, nil +} + +func (s *testDaprServer) QueryStateAlpha1(ctx context.Context, req *pb.QueryStateRequest) (*pb.QueryStateResponse, error) { + var v map[string]interface{} + if err := json.Unmarshal([]byte(req.Query), &v); err != nil { + return nil, err + } + + ret := &pb.QueryStateResponse{ + Results: make([]*pb.QueryStateItem, 0, len(s.state)), + } + for key, value := range s.state { + ret.Results = append(ret.Results, &pb.QueryStateItem{Key: key, Data: value}) + } + return ret, nil +} + +func (s *testDaprServer) DeleteState(ctx context.Context, req *pb.DeleteStateRequest) (*empty.Empty, error) { + delete(s.state, req.Key) + return &empty.Empty{}, nil +} + +func (s *testDaprServer) DeleteBulkState(ctx context.Context, req *pb.DeleteBulkStateRequest) (*empty.Empty, error) { + for _, item := range req.States { + delete(s.state, item.Key) + } + return &empty.Empty{}, nil +} + +func (s *testDaprServer) ExecuteStateTransaction(ctx context.Context, in *pb.ExecuteStateTransactionRequest) (*empty.Empty, error) { + for _, op := range in.GetOperations() { + item := op.GetRequest() + switch opType := op.GetOperationType(); opType { + case "upsert": + s.state[item.Key] = item.Value + case "delete": + delete(s.state, item.Key) + default: + return &empty.Empty{}, fmt.Errorf("invalid operation type: %s", opType) + } + } + return &empty.Empty{}, nil +} + +func (s *testDaprServer) PublishEvent(ctx context.Context, req *pb.PublishEventRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) InvokeBinding(ctx context.Context, req *pb.InvokeBindingRequest) (*pb.InvokeBindingResponse, error) { + if req.Data == nil { + return &pb.InvokeBindingResponse{ + Data: []byte("test"), + Metadata: map[string]string{"k1": "v1", "k2": "v2"}, + }, nil + } + return &pb.InvokeBindingResponse{ + Data: req.Data, + Metadata: req.Metadata, + }, nil +} + +func (s *testDaprServer) GetSecret(ctx context.Context, req *pb.GetSecretRequest) (*pb.GetSecretResponse, error) { + d := make(map[string]string) + d["test"] = "value" + return &pb.GetSecretResponse{ + Data: d, + }, nil +} + +func (s *testDaprServer) GetBulkSecret(ctx context.Context, req *pb.GetBulkSecretRequest) (*pb.GetBulkSecretResponse, error) { + d := make(map[string]*pb.SecretResponse) + d["test"] = &pb.SecretResponse{ + Secrets: map[string]string{ + "test": "value", + }, + } + return &pb.GetBulkSecretResponse{ + Data: d, + }, nil +} + +func (s *testDaprServer) RegisterActorReminder(ctx context.Context, req *pb.RegisterActorReminderRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) UnregisterActorReminder(ctx context.Context, req *pb.UnregisterActorReminderRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) RenameActorReminder(ctx context.Context, req *pb.RenameActorReminderRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) InvokeActor(context.Context, *pb.InvokeActorRequest) (*pb.InvokeActorResponse, error) { + return &pb.InvokeActorResponse{ + Data: []byte("mockValue"), + }, nil +} + +func (s *testDaprServer) RegisterActorTimer(context.Context, *pb.RegisterActorTimerRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) UnregisterActorTimer(context.Context, *pb.UnregisterActorTimerRequest) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) Shutdown(ctx context.Context, req *empty.Empty) (*empty.Empty, error) { + return &empty.Empty{}, nil +} + +func (s *testDaprServer) GetConfiguration(ctx context.Context, in *pb.GetConfigurationRequest) (*pb.GetConfigurationResponse, error) { + if in.GetStoreName() == "" { + return &pb.GetConfigurationResponse{}, errors.New("store name notfound") + } + items := make(map[string]*commonv1pb.ConfigurationItem) + for _, v := range in.GetKeys() { + items[v] = &commonv1pb.ConfigurationItem{ + Value: v + valueSuffix, + } + } + return &pb.GetConfigurationResponse{ + Items: items, + }, nil +} + +func (s *testDaprServer) SubscribeConfiguration(in *pb.SubscribeConfigurationRequest, server pb.Dapr_SubscribeConfigurationServer) error { + stopCh := make(chan struct{}) + id, _ := uuid.NewUUID() + s.configurationSubscriptionIDMapLoc.Lock() + s.configurationSubscriptionID[id.String()] = stopCh + s.configurationSubscriptionIDMapLoc.Unlock() + + // Send subscription ID in the first response. + if err := server.Send(&pb.SubscribeConfigurationResponse{ + Id: id.String(), + }); err != nil { + return err + } + + for i := 0; i < 5; i++ { + select { + case <-stopCh: + return nil + default: + } + items := make(map[string]*commonv1pb.ConfigurationItem) + for _, v := range in.GetKeys() { + items[v] = &commonv1pb.ConfigurationItem{ + Value: v + valueSuffix, + } + } + if err := server.Send(&pb.SubscribeConfigurationResponse{ + Id: id.String(), + Items: items, + }); err != nil { + return err + } + time.Sleep(time.Second) + } + return nil +} + +func (s *testDaprServer) UnsubscribeConfiguration(ctx context.Context, in *pb.UnsubscribeConfigurationRequest) (*pb.UnsubscribeConfigurationResponse, error) { + s.configurationSubscriptionIDMapLoc.Lock() + defer s.configurationSubscriptionIDMapLoc.Unlock() + ch, ok := s.configurationSubscriptionID[in.Id] + if !ok { + return &pb.UnsubscribeConfigurationResponse{Ok: true}, nil + } + close(ch) + delete(s.configurationSubscriptionID, in.Id) + return &pb.UnsubscribeConfigurationResponse{Ok: true}, nil +} + +// BulkPublishEventAlpha1 mocks the BulkPublishEventAlpha1 API. +// It will fail to publish events that start with "fail". +// It will fail the entire request if an event starts with "failall". +func (s *testDaprServer) BulkPublishEventAlpha1(ctx context.Context, req *pb.BulkPublishRequest) (*pb.BulkPublishResponse, error) { + failedEntries := make([]*pb.BulkPublishResponseFailedEntry, 0) + for _, entry := range req.Entries { + if bytes.HasPrefix(entry.Event, []byte("failall")) { + // fail the entire request + return nil, errors.New("failed to publish events") + } else if bytes.HasPrefix(entry.Event, []byte("fail")) { + // fail this entry + failedEntries = append(failedEntries, &pb.BulkPublishResponseFailedEntry{ + EntryId: entry.EntryId, + Error: "failed to publish events", + }) + } + } + return &pb.BulkPublishResponse{FailedEntries: failedEntries}, nil +} + +func FakeConnection() (connection.Connection, func()) { + ctx := context.Background() + c, f := getTestClient(ctx) + return &Dapr{ + client: c, + pubSubComponent: "test", + }, f +} + +type FakeDapr struct { + // Array of clients to talk to different endpoints + client daprClient.Client + + // Name of the pubsub component + pubSubComponent string + + // closing function + f func() +} + +func (r *FakeDapr) Publish(ctx context.Context, data interface{}, topic string) error { + return nil +} + +func (r *FakeDapr) CloseConnection() error { + r.f() + return nil +} + +func (r *FakeDapr) UpdateConnection(_ context.Context, config interface{}) error { + var cfg ClientConfig + m, ok := config.(map[string]interface{}) + if !ok { + return fmt.Errorf("invalid type assertion, config is not in expected format") + } + cfg.Component, ok = m["component"].(string) + if !ok { + return fmt.Errorf("failed to get value of component") + } + r.pubSubComponent = cfg.Component + return nil +} + +// Returns a fake client for dapr. +func FakeNewConnection(ctx context.Context, config interface{}) (connection.Connection, error) { + var cfg ClientConfig + m, ok := config.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("invalid type assertion, config is not in expected format") + } + cfg.Component, ok = m["component"].(string) + if !ok { + return nil, fmt.Errorf("failed to get value of component") + } + + c, f := getTestClient(ctx) + + return &FakeDapr{ + client: c, + pubSubComponent: cfg.Component, + f: f, + }, nil +} diff --git a/pkg/pubsub/provider/fake_provider.go b/pkg/pubsub/provider/fake_provider.go new file mode 100644 index 00000000000..6e1173eb9b7 --- /dev/null +++ b/pkg/pubsub/provider/fake_provider.go @@ -0,0 +1,11 @@ +package provider + +import ( + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/dapr" +) + +func FakeProviders() { + pubSubs = newPubSubSet(map[string]InitiateConnection{ + dapr.Name: dapr.FakeNewConnection, + }) +} diff --git a/pkg/pubsub/provider/provider.go b/pkg/pubsub/provider/provider.go new file mode 100644 index 00000000000..5e1d0601014 --- /dev/null +++ b/pkg/pubsub/provider/provider.go @@ -0,0 +1,39 @@ +package provider + +import ( + "context" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/dapr" +) + +var pubSubs = newPubSubSet(map[string]InitiateConnection{ + dapr.Name: dapr.NewConnection, +}, +) + +type pubSubSet struct { + supportedPubSub map[string]InitiateConnection +} + +// returns new client for pub sub tool. +type InitiateConnection func(ctx context.Context, config interface{}) (connection.Connection, error) + +func newPubSubSet(pubSubs map[string]InitiateConnection) *pubSubSet { + supported := make(map[string]InitiateConnection) + set := &pubSubSet{ + supportedPubSub: supported, + } + for name := range pubSubs { + set.supportedPubSub[name] = pubSubs[name] + } + return set +} + +func List() map[string]InitiateConnection { + ret := make(map[string]InitiateConnection) + for name, new := range pubSubs.supportedPubSub { + ret[name] = new + } + return ret +} diff --git a/pkg/pubsub/provider/provider_test.go b/pkg/pubsub/provider/provider_test.go new file mode 100644 index 00000000000..c81602525ac --- /dev/null +++ b/pkg/pubsub/provider/provider_test.go @@ -0,0 +1,51 @@ +package provider + +import ( + "testing" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/dapr" +) + +func Test_newPubSubSet(t *testing.T) { + tests := []struct { + name string + pubSubs map[string]InitiateConnection + wantKey string + }{ + { + name: "only one provider is available", + pubSubs: map[string]InitiateConnection{ + dapr.Name: dapr.NewConnection, + }, + wantKey: dapr.Name, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := newPubSubSet(tt.pubSubs) + if _, ok := got.supportedPubSub[tt.wantKey]; !ok { + t.Errorf("newPubSubSet() = %#v, want key %#v", got.supportedPubSub, tt.wantKey) + } + }) + } +} + +func TestList(t *testing.T) { + tests := []struct { + name string + wantKey string + }{ + { + name: "only one provider is available", + wantKey: dapr.Name, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := List() + if _, ok := got[tt.wantKey]; !ok { + t.Errorf("List() = %#v, want key %#v", got, tt.wantKey) + } + }) + } +} diff --git a/pkg/pubsub/system.go b/pkg/pubsub/system.go new file mode 100644 index 00000000000..48216735cd9 --- /dev/null +++ b/pkg/pubsub/system.go @@ -0,0 +1,87 @@ +package pubsub + +import ( + "context" + "fmt" + "sync" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" + prvd "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/provider" +) + +type System struct { + mux sync.RWMutex + connections map[string]connection.Connection + providers map[string]string +} + +func NewSystem() *System { + return &System{} +} + +func (s *System) Publish(ctx context.Context, connection string, topic string, msg interface{}) error { + s.mux.RLock() + defer s.mux.RUnlock() + if len(s.connections) > 0 { + if c, ok := s.connections[connection]; ok { + return c.Publish(context.Background(), msg, topic) + } + return fmt.Errorf("connection is not initialized, name: %s ", connection) + } + return fmt.Errorf("No connections are established") +} + +func (s *System) UpsertConnection(ctx context.Context, config interface{}, name string, provider string) error { + s.mux.Lock() + defer s.mux.Unlock() + // Check if the connection already exists. + if conn, ok := s.connections[name]; ok { + // If the provider is the same, update the existing connection. + if s.providers[name] == provider { + return conn.UpdateConnection(ctx, config) + } + } + // Check if the provider is supported. + if newConnFunc, ok := prvd.List()[provider]; ok { + newConn, err := newConnFunc(ctx, config) + if err != nil { + return err + } + + // Close the existing connection after successfully creating the new one. + if err := s.closeConnection(name); err != nil { + return err + } + // Add the new connection and provider to the maps. + if s.connections == nil { + s.connections = map[string]connection.Connection{} + } + if s.providers == nil { + s.providers = map[string]string{} + } + s.connections[name] = newConn + s.providers[name] = provider + return nil + } + return fmt.Errorf("pub-sub provider %s is not supported", provider) +} + +func (s *System) CloseConnection(connection string) error { + s.mux.Lock() + defer s.mux.Unlock() + return s.closeConnection(connection) +} + +func (s *System) closeConnection(connection string) error { + if len(s.connections) > 0 { + if c, ok := s.connections[connection]; ok { + err := c.CloseConnection() + if err != nil { + return err + } + delete(s.connections, connection) + delete(s.providers, connection) + } + } + return nil +} diff --git a/pkg/pubsub/system_test.go b/pkg/pubsub/system_test.go new file mode 100644 index 00000000000..a58e43c8cb7 --- /dev/null +++ b/pkg/pubsub/system_test.go @@ -0,0 +1,256 @@ +package pubsub + +import ( + "context" + "os" + "sync" + "testing" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/connection" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/dapr" + "github.com/open-policy-agent/gatekeeper/v3/pkg/pubsub/provider" + "github.com/stretchr/testify/assert" +) + +var testSystem *System + +func TestMain(m *testing.M) { + ctx := context.Background() + provider.FakeProviders() + tmp := provider.List() + testSystem = NewSystem() + testSystem.connections = make(map[string]connection.Connection) + testSystem.providers = make(map[string]string) + cfg := map[string]interface{}{ + dapr.Name: map[string]interface{}{ + "component": "pubsub", + }, + } + for name, fakeConn := range tmp { + testSystem.providers[name] = name + testSystem.connections[name], _ = fakeConn(ctx, cfg[name]) + } + r := m.Run() + for _, fakeConn := range testSystem.connections { + _ = fakeConn.CloseConnection() + } + + if r != 0 { + os.Exit(r) + } +} + +func TestNewSystem(t *testing.T) { + tests := []struct { + name string + input string + want *System + }{ + { + name: "requesting system", + want: &System{}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ret := NewSystem() + assert.Equal(t, ret, tc.want) + }) + } +} + +func TestSystem_UpsertConnection(t *testing.T) { + type fields struct { + connections map[string]connection.Connection + providers map[string]string + s *System + } + type args struct { + ctx context.Context + config interface{} + name string + provider string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + match bool + }{ + { + name: "Create a new connection with dapr provider", + fields: fields{ + connections: testSystem.connections, + providers: testSystem.providers, + s: &System{}, + }, + args: args{ + ctx: context.Background(), + config: map[string]interface{}{ + "component": "pubsub", + }, + name: "dapr", + provider: "dapr", + }, + wantErr: false, + match: true, + }, + { + name: "Update a connection to use test provider", + fields: fields{ + connections: nil, + providers: map[string]string{"audit": "dapr"}, + s: &System{ + mux: sync.RWMutex{}, + providers: map[string]string{"audit": "dapr"}, + }, + }, + args: args{ + ctx: context.Background(), + config: map[string]interface{}{ + "component": "pubsub", + }, + name: "audit", + provider: "test", + }, + wantErr: true, + match: true, + }, + { + name: "Update a connection using same provider", + fields: fields{ + connections: testSystem.connections, + providers: map[string]string{"dapr": "dapr"}, + s: &System{ + mux: sync.RWMutex{}, + providers: testSystem.providers, + connections: testSystem.connections, + }, + }, + args: args{ + ctx: context.Background(), + config: map[string]interface{}{ + "component": "test", + }, + name: "audit", + provider: "dapr", + }, + wantErr: false, + match: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.fields.s.UpsertConnection(tt.args.ctx, tt.args.config, tt.args.name, tt.args.provider); (err != nil) != tt.wantErr { + t.Errorf("System.UpsertConnection() error = %v, wantErr %v", err, tt.wantErr) + } + assert.NotEqual(t, nil, tt.fields.s.connections) + if tt.match { + assert.Equal(t, tt.fields.providers, tt.fields.s.providers) + } else { + assert.NotEqual(t, tt.fields.providers, tt.fields.s.providers) + } + }) + } +} + +func TestSystem_CloseConnection(t *testing.T) { + type fields struct { + connections map[string]connection.Connection + providers map[string]string + } + type args struct { + connection string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "closing connection", + fields: fields{ + connections: map[string]connection.Connection{"audit": &dapr.Dapr{}}, + providers: map[string]string{"audit": "dapr"}, + }, + args: args{connection: "audit"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &System{ + mux: sync.RWMutex{}, + connections: tt.fields.connections, + providers: tt.fields.providers, + } + if err := s.CloseConnection(tt.args.connection); (err != nil) != tt.wantErr { + t.Errorf("System.CloseConnection() error = %v, wantErr %v", err, tt.wantErr) + _, ok := s.connections[tt.args.connection] + assert.False(t, ok) + } + }) + } +} + +func TestSystem_Publish(t *testing.T) { + type fields struct { + connections map[string]connection.Connection + providers map[string]string + } + type args struct { + ctx context.Context + connection string + topic string + msg interface{} + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "There are no connections established", + fields: fields{ + connections: nil, + providers: nil, + }, + args: args{ctx: context.Background(), connection: "audit", topic: "test", msg: nil}, + wantErr: true, + }, + { + name: "Publishing to a connection that does not exist", + fields: fields{ + connections: map[string]connection.Connection{"audit": &dapr.Dapr{}}, + providers: map[string]string{"audit": "dapr"}, + }, + args: args{ctx: context.Background(), connection: "test", topic: "test", msg: nil}, + wantErr: true, + }, + { + name: "Publishing to a connection that does exist", + fields: fields{ + connections: testSystem.connections, + providers: testSystem.providers, + }, + args: args{ctx: context.Background(), connection: "dapr", topic: "test", msg: nil}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &System{ + mux: sync.RWMutex{}, + connections: tt.fields.connections, + providers: tt.fields.providers, + } + if err := s.Publish(tt.args.ctx, tt.args.connection, tt.args.topic, tt.args.msg); (err != nil) != tt.wantErr { + t.Errorf("System.Publish() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/readiness/integration_suite_test.go b/pkg/readiness/integration_suite_test.go index ae3aff5767e..1fedd4961b4 100644 --- a/pkg/readiness/integration_suite_test.go +++ b/pkg/readiness/integration_suite_test.go @@ -22,7 +22,7 @@ import ( "path/filepath" "testing" - "github.com/open-policy-agent/gatekeeper/apis" + "github.com/open-policy-agent/gatekeeper/v3/apis" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" diff --git a/pkg/readiness/list.go b/pkg/readiness/list.go index 38d754aadb4..514c8692eba 100644 --- a/pkg/readiness/list.go +++ b/pkg/readiness/list.go @@ -20,7 +20,7 @@ import ( "errors" "time" - "github.com/open-policy-agent/gatekeeper/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/readiness/object_tracker.go b/pkg/readiness/object_tracker.go index 4ec9cf39fde..674824106a5 100644 --- a/pkg/readiness/object_tracker.go +++ b/pkg/readiness/object_tracker.go @@ -22,6 +22,7 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -107,6 +108,11 @@ func (t *objectTracker) Expect(o runtime.Object) { return } + // Satisfied objects cannot be expected again. + if _, ok := t.satisfied[k]; ok { + return + } + // We may have seen it before starting to expect it if _, ok := t.seen[k]; ok { delete(t.seen, k) @@ -250,6 +256,8 @@ func (t *objectTracker) Observe(o runtime.Object) { // Track for future expectation. t.seen[k] = struct{}{} + + log.V(logging.DebugLevel).Info("[readiness] observed data", "gvk", o.GetObjectKind().GroupVersionKind()) } func (t *objectTracker) Populated() bool { diff --git a/pkg/readiness/object_tracker_test.go b/pkg/readiness/object_tracker_test.go index 951f3151307..e6e601cd417 100644 --- a/pkg/readiness/object_tracker_test.go +++ b/pkg/readiness/object_tracker_test.go @@ -178,6 +178,28 @@ func Test_ObjectTracker_Duplicate_Expectations(t *testing.T) { } } +// Verify that that satisfied expectations cannot be re-established. +func Test_ObjectTracker_Satisfaction_Final(t *testing.T) { + ot := newObjTracker(schema.GroupVersionKind{}, nil) + + const count = 10 + ct := makeCTSlice("ct-", count) + for i := 0; i < len(ct); i++ { + ot.Expect(ct[i]) + ot.Observe(ct[i]) + ot.Expect(ct[i]) + } + if ot.Satisfied() { + t.Fatal("should not be satisfied before ExpectationsDone") + } + + ot.ExpectationsDone() + + if !ot.Satisfied() { + t.Fatal("should be satisfied") + } +} + // Verify that an expectation can be canceled before it's first expected. func Test_ObjectTracker_CancelBeforeExpect(t *testing.T) { ot := newObjTracker(schema.GroupVersionKind{}, nil) diff --git a/pkg/readiness/ready_tracker.go b/pkg/readiness/ready_tracker.go index 184ac1b0bc1..a2eeab4658b 100644 --- a/pkg/readiness/ready_tracker.go +++ b/pkg/readiness/ready_tracker.go @@ -25,11 +25,13 @@ import ( externaldatav1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - mutationv1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1" - "github.com/open-policy-agent/gatekeeper/pkg/keys" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/syncutil" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + expansionv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/v1alpha1" + mutationv1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1" + mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/keys" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" "github.com/pkg/errors" "golang.org/x/sync/errgroup" "k8s.io/apimachinery/pkg/api/meta" @@ -64,7 +66,9 @@ type Tracker struct { assignMetadata *objectTracker assign *objectTracker modifySet *objectTracker + assignImage *objectTracker externalDataProvider *objectTracker + expansions *objectTracker constraints *trackerMap data *trackerMap @@ -73,14 +77,15 @@ type Tracker struct { statsEnabled syncutil.SyncBool mutationEnabled bool externalDataEnabled bool + expansionEnabled bool } // NewTracker creates a new Tracker and initializes the internal trackers. -func NewTracker(lister Lister, mutationEnabled bool, externalDataEnabled bool) *Tracker { - return newTracker(lister, mutationEnabled, externalDataEnabled, nil) +func NewTracker(lister Lister, mutationEnabled, externalDataEnabled, expansionEnabled bool) *Tracker { + return newTracker(lister, mutationEnabled, externalDataEnabled, expansionEnabled, nil) } -func newTracker(lister Lister, mutationEnabled bool, externalDataEnabled bool, fn objDataFactory) *Tracker { +func newTracker(lister Lister, mutationEnabled, externalDataEnabled, expansionEnabled bool, fn objDataFactory) *Tracker { tracker := Tracker{ lister: lister, templates: newObjTracker(v1beta1.SchemeGroupVersion.WithKind("ConstraintTemplate"), fn), @@ -92,15 +97,20 @@ func newTracker(lister Lister, mutationEnabled bool, externalDataEnabled bool, f mutationEnabled: mutationEnabled, externalDataEnabled: externalDataEnabled, + expansionEnabled: expansionEnabled, } if mutationEnabled { tracker.assignMetadata = newObjTracker(mutationv1.GroupVersion.WithKind("AssignMetadata"), fn) tracker.assign = newObjTracker(mutationv1.GroupVersion.WithKind("Assign"), fn) tracker.modifySet = newObjTracker(mutationv1.GroupVersion.WithKind("ModifySet"), fn) + tracker.assignImage = newObjTracker(mutationsv1alpha1.GroupVersion.WithKind("AssignImage"), fn) } if externalDataEnabled { tracker.externalDataProvider = newObjTracker(externaldatav1beta1.SchemeGroupVersion.WithKind("Provider"), fn) } + if expansionEnabled { + tracker.expansions = newObjTracker(expansionv1alpha1.GroupVersion.WithKind("ExpansionTemplate"), fn) + } return &tracker } @@ -119,31 +129,42 @@ func (t *Tracker) For(gvk schema.GroupVersionKind) Expectations { return noopExpectations{} } + // Do not compare versions. Internally, we index trackers by GroupKind switch { - case gvk.GroupVersion() == v1beta1.SchemeGroupVersion && gvk.Kind == "ConstraintTemplate": + case gvk.Group == v1beta1.SchemeGroupVersion.Group && gvk.Kind == "ConstraintTemplate": if operations.HasValidationOperations() { return t.templates } return noopExpectations{} - case gvk.GroupVersion() == configv1alpha1.GroupVersion && gvk.Kind == "Config": + case gvk.Group == configv1alpha1.GroupVersion.Group && gvk.Kind == "Config": return t.config - case gvk.GroupVersion() == externaldatav1beta1.SchemeGroupVersion && gvk.Kind == "Provider": + case gvk.Group == externaldatav1beta1.SchemeGroupVersion.Group && gvk.Kind == "Provider": return t.externalDataProvider - case gvk.GroupVersion() == mutationv1.GroupVersion && gvk.Kind == "AssignMetadata": + case gvk.Group == mutationv1.GroupVersion.Group && gvk.Kind == "AssignMetadata": if t.mutationEnabled { return t.assignMetadata } return noopExpectations{} - case gvk.GroupVersion() == mutationv1.GroupVersion && gvk.Kind == "Assign": + case gvk.Group == mutationv1.GroupVersion.Group && gvk.Kind == "Assign": if t.mutationEnabled { return t.assign } return noopExpectations{} - case gvk.GroupVersion() == mutationv1.GroupVersion && gvk.Kind == "ModifySet": + case gvk.Group == mutationv1.GroupVersion.Group && gvk.Kind == "ModifySet": if t.mutationEnabled { return t.modifySet } return noopExpectations{} + case gvk.Group == mutationsv1alpha1.GroupVersion.Group && gvk.Kind == "AssignImage": + if t.mutationEnabled { + return t.assignImage + } + return noopExpectations{} + case gvk.Group == expansionv1alpha1.GroupVersion.Group && gvk.Kind == "ExpansionTemplate": + if t.expansionEnabled { + return t.expansions + } + return noopExpectations{} } // Avoid new constraint trackers after templates have been populated. @@ -207,12 +228,13 @@ func (t *Tracker) Satisfied() bool { } if t.mutationEnabled { - if !t.assignMetadata.Satisfied() || !t.assign.Satisfied() || !t.modifySet.Satisfied() { + if !t.assignMetadata.Satisfied() || !t.assign.Satisfied() || !t.modifySet.Satisfied() || !t.assignImage.Satisfied() { return false } log.V(1).Info("all expectations satisfied", "tracker", "assignMetadata") log.V(1).Info("all expectations satisfied", "tracker", "assign") log.V(1).Info("all expectations satisfied", "tracker", "modifySet") + log.V(1).Info("all expectations satisfied", "tracker", "assignImage") } if t.externalDataEnabled { @@ -222,6 +244,13 @@ func (t *Tracker) Satisfied() bool { log.V(1).Info("all expectations satisfied", "tracker", "provider") } + if t.expansionEnabled { + if !t.expansions.Satisfied() { + return false + } + log.V(1).Info("all expectations satisfied", "tracker", "expansiontemplates") + } + if operations.HasValidationOperations() { if !t.templates.Satisfied() { return false @@ -275,12 +304,20 @@ func (t *Tracker) Run(ctx context.Context) error { grp.Go(func() error { return t.trackModifySet(gctx) }) + grp.Go(func() error { + return t.trackAssignImage(gctx) + }) } if t.externalDataEnabled { grp.Go(func() error { return t.trackExternalDataProvider(gctx) }) } + if t.expansionEnabled { + grp.Go(func() error { + return t.trackExpansionTemplates(gctx) + }) + } if operations.HasValidationOperations() { grp.Go(func() error { return t.trackConstraintTemplates(gctx) @@ -331,7 +368,7 @@ func (t *Tracker) Populated() bool { mutationPopulated := true if t.mutationEnabled { // If !t.mutationEnabled and we call this, it yields a null pointer exception - mutationPopulated = t.assignMetadata.Populated() && t.assign.Populated() && t.modifySet.Populated() + mutationPopulated = t.assignMetadata.Populated() && t.assign.Populated() && t.modifySet.Populated() && t.assignImage.Populated() } externalDataProviderPopulated := true if t.externalDataEnabled { @@ -529,6 +566,56 @@ func (t *Tracker) trackModifySet(ctx context.Context) error { return nil } +func (t *Tracker) trackAssignImage(ctx context.Context) error { + defer func() { + t.assignImage.ExpectationsDone() + log.V(1).Info("AssignImage expectations populated") + _ = t.constraintTrackers.Wait() + }() + + if !t.mutationEnabled { + return nil + } + + assignImageList := &mutationsv1alpha1.AssignImageList{} + lister := retryLister(t.lister, retryAll) + if err := lister.List(ctx, assignImageList); err != nil { + return fmt.Errorf("listing AssignImage: %w", err) + } + log.V(1).Info("setting expectations for AssignImage", "AssignImage Count", len(assignImageList.Items)) + + for index := range assignImageList.Items { + log.V(1).Info("expecting AssignImage", "name", assignImageList.Items[index].GetName()) + t.assignImage.Expect(&assignImageList.Items[index]) + } + return nil +} + +func (t *Tracker) trackExpansionTemplates(ctx context.Context) error { + defer func() { + t.expansions.ExpectationsDone() + log.V(1).Info("ExpansionTemplate expectations populated") + _ = t.constraintTrackers.Wait() + }() + + if !t.expansionEnabled { + return nil + } + + expansionList := &expansionv1alpha1.ExpansionTemplateList{} + lister := retryLister(t.lister, retryAll) + if err := lister.List(ctx, expansionList); err != nil { + return fmt.Errorf("listing ExpansionTemplate: %w", err) + } + log.V(1).Info("setting expectations for ExpansionTemplate", "ExpansionTemplate Count", len(expansionList.Items)) + + for index := range expansionList.Items { + log.V(1).Info("expecting ExpansionTemplate", "name", expansionList.Items[index].GetName()) + t.expansions.Expect(&expansionList.Items[index]) + } + return nil +} + func (t *Tracker) trackExternalDataProvider(ctx context.Context) error { defer func() { t.externalDataProvider.ExpectationsDone() @@ -815,10 +902,14 @@ func (t *Tracker) statsPrinter(ctx context.Context) { logUnsatisfiedAssignMetadata(t) logUnsatisfiedAssign(t) logUnsatisfiedModifySet(t) + logUnsatisfiedAssignImage(t) } if t.externalDataEnabled { logUnsatisfiedExternalDataProvider(t) } + if t.expansionEnabled { + logUnsatisfiedExpansions(t) + } } } @@ -840,6 +931,18 @@ func logUnsatisfiedModifySet(t *Tracker) { } } +func logUnsatisfiedAssignImage(t *Tracker) { + for _, amKey := range t.assignImage.unsatisfied() { + log.Info("unsatisfied AssignImage", "name", amKey.namespacedName) + } +} + +func logUnsatisfiedExpansions(t *Tracker) { + for _, et := range t.expansions.unsatisfied() { + log.Info("unsatisfied ExpansionTemplate", "name", et.namespacedName) + } +} + func logUnsatisfiedExternalDataProvider(t *Tracker) { for _, amKey := range t.externalDataProvider.unsatisfied() { log.Info("unsatisfied Provider", "name", amKey.namespacedName) diff --git a/pkg/readiness/ready_tracker_test.go b/pkg/readiness/ready_tracker_test.go index 3bcff8e9f63..a31e47d2f74 100644 --- a/pkg/readiness/ready_tracker_test.go +++ b/pkg/readiness/ready_tracker_test.go @@ -28,27 +28,30 @@ import ( externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" frameworksexternaldata "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/gatekeeper/pkg/controller" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/readiness" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - "github.com/open-policy-agent/gatekeeper/test/testutils" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" + "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "github.com/prometheus/client_golang/prometheus" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/metrics" @@ -59,15 +62,13 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { t.Helper() logger := zap.New(zap.UseDevMode(true), zap.WriteTo(testutils.NewTestWriter(t))) + ctrl.SetLogger(logger) metrics.Registry = prometheus.NewRegistry() mgr, err := manager.New(cfg, manager.Options{ HealthProbeBindAddress: "127.0.0.1:29090", MetricsBindAddress: "0", - NewCache: dynamiccache.New, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, - Logger: logger, + MapperProvider: apiutil.NewDynamicRESTMapper, + Logger: logger, }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -87,16 +88,15 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { return mgr, wm } -func setupOpa(t *testing.T) *constraintclient.Client { - // initialize OPA - driver, err := local.New(local.Tracing(false)) +func setupDataClient(t *testing.T) *constraintclient.Client { + driver, err := rego.New(rego.Tracing(false)) if err != nil { t.Fatalf("setting up Driver: %v", err) } client, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) if err != nil { - t.Fatalf("setting up OPA client: %v", err) + t.Fatalf("setting up constraint framework client: %v", err) } return client } @@ -104,11 +104,14 @@ func setupOpa(t *testing.T) *constraintclient.Client { func setupController( mgr manager.Manager, wm *watch.Manager, - opa *constraintclient.Client, + cfClient *constraintclient.Client, mutationSystem *mutation.System, + expansionSystem *expansion.System, providerCache *frameworksexternaldata.ProviderCache, ) error { - tracker, err := readiness.SetupTracker(mgr, mutationSystem != nil, providerCache != nil) + *expansion.ExpansionEnabled = expansionSystem != nil + + tracker, err := readiness.SetupTracker(mgr, mutationSystem != nil, providerCache != nil, expansionSystem != nil) if err != nil { return fmt.Errorf("setting up tracker: %w", err) } @@ -124,17 +127,39 @@ func setupController( processExcluder := process.Get() + events := make(chan event.GenericEvent, 1024) + syncMetricsCache := syncutil.NewMetricsCache() + reg, err := wm.NewRegistrar( + cachemanager.RegistrarName, + events) + if err != nil { + return fmt.Errorf("setting up watch manager: %w", err) + } + cacheManager, err := cachemanager.NewCacheManager(&cachemanager.Config{ + CfClient: cfClient, + SyncMetricsCache: syncMetricsCache, + Tracker: tracker, + ProcessExcluder: processExcluder, + Registrar: reg, + Reader: mgr.GetCache(), + }) + if err != nil { + return fmt.Errorf("setting up cache manager: %w", err) + } + // Setup all Controllers opts := controller.Dependencies{ - Opa: opa, + CFClient: cfClient, WatchManger: wm, ControllerSwitch: sw, Tracker: tracker, GetPod: func(ctx context.Context) (*corev1.Pod, error) { return pod, nil }, ProcessExcluder: processExcluder, MutationSystem: mutationSystem, + ExpansionSystem: expansionSystem, ProviderCache: providerCache, - WatchSet: watch.NewSet(), + CacheMgr: cacheManager, + SyncEventsCh: events, } if err := controller.AddToManager(mgr, &opts); err != nil { return fmt.Errorf("registering controllers: %w", err) @@ -153,12 +178,13 @@ func Test_AssignMetadata(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) mutationSystem := mutation.NewSystem(mutation.SystemOpts{}) + expansionSystem := expansion.NewSystem(mutationSystem) providerCache := frameworksexternaldata.NewCache() - if err := setupController(mgr, wm, opaClient, mutationSystem, providerCache); err != nil { + if err := setupController(mgr, wm, cfClient, mutationSystem, expansionSystem, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -196,12 +222,13 @@ func Test_ModifySet(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) mutationSystem := mutation.NewSystem(mutation.SystemOpts{}) + expansionSystem := expansion.NewSystem(mutationSystem) providerCache := frameworksexternaldata.NewCache() - if err := setupController(mgr, wm, opaClient, mutationSystem, providerCache); err != nil { + if err := setupController(mgr, wm, cfClient, mutationSystem, expansionSystem, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -224,6 +251,48 @@ func Test_ModifySet(t *testing.T) { } } +func Test_AssignImage(t *testing.T) { + g := gomega.NewWithT(t) + + testutils.Setenv(t, "POD_NAME", "no-pod") + + // Apply fixtures *before* the controllers are set up. + err := applyFixtures("testdata") + if err != nil { + t.Fatalf("applying fixtures: %v", err) + } + + // Wire up the rest. + mgr, wm := setupManager(t) + cfClient := setupDataClient(t) + + mutationSystem := mutation.NewSystem(mutation.SystemOpts{}) + expansionSystem := expansion.NewSystem(mutationSystem) + providerCache := frameworksexternaldata.NewCache() + + if err := setupController(mgr, wm, cfClient, mutationSystem, expansionSystem, providerCache); err != nil { + t.Fatalf("setupControllers: %v", err) + } + + ctx := context.Background() + testutils.StartManager(ctx, t, mgr) + + g.Eventually(func() (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + return probeIsReady(ctx) + }, 20*time.Second, 1*time.Second).Should(gomega.BeTrue()) + + // Verify that the AssignImage is present in the cache + for _, am := range testAssignImage { + id := mutationtypes.MakeID(am) + expectedMutator := mutationSystem.Get(id) + if expectedMutator == nil { + t.Fatal("want expectedMutator != nil but got nil") + } + } +} + func Test_Assign(t *testing.T) { g := gomega.NewWithT(t) @@ -237,12 +306,13 @@ func Test_Assign(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) mutationSystem := mutation.NewSystem(mutation.SystemOpts{}) + expansionSystem := expansion.NewSystem(mutationSystem) providerCache := frameworksexternaldata.NewCache() - if err := setupController(mgr, wm, opaClient, mutationSystem, providerCache); err != nil { + if err := setupController(mgr, wm, cfClient, mutationSystem, expansionSystem, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -265,6 +335,61 @@ func Test_Assign(t *testing.T) { } } +func Test_ExpansionTemplate(t *testing.T) { + g := gomega.NewWithT(t) + + testutils.Setenv(t, "POD_NAME", "no-pod") + + // Apply fixtures *before* the controllers are setup. + err := applyFixtures("testdata") + if err != nil { + t.Fatalf("applying fixtures: %v", err) + } + + // Wire up the rest. + mgr, wm := setupManager(t) + cfClient := setupDataClient(t) + + mutationSystem := mutation.NewSystem(mutation.SystemOpts{}) + expansionSystem := expansion.NewSystem(mutationSystem) + providerCache := frameworksexternaldata.NewCache() + + if err := setupController(mgr, wm, cfClient, mutationSystem, expansionSystem, providerCache); err != nil { + t.Fatalf("setupControllers: %v", err) + } + + ctx := context.Background() + testutils.StartManager(ctx, t, mgr) + + g.Eventually(func() (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + return probeIsReady(ctx) + }, 20*time.Second, 1*time.Second).Should(gomega.BeTrue()) + + // Verify that the ExpansionTemplate is registered by expanding a demo deployment + // and checking that the resulting Pod is non-nil + deployment := makeDeployment("demo-deployment") + o, err := runtime.DefaultUnstructuredConverter.ToUnstructured(deployment) + if err != nil { + panic(fmt.Errorf("error converting deployment to unstructured: %w", err)) + } + u := unstructured.Unstructured{Object: o} + m := mutationtypes.Mutable{ + Object: &u, + Namespace: testNS, + Username: "", + Source: "All", + } + res, err := expansionSystem.Expand(&m) + if err != nil { + panic(fmt.Errorf("error expanding: %w", err)) + } + if len(res) != 1 { + t.Fatal("expected generator to expand into 1 pod, but got 0 resultants") + } +} + func Test_Provider(t *testing.T) { g := gomega.NewWithT(t) @@ -282,12 +407,13 @@ func Test_Provider(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) if err := setupController(mgr, wm, - opaClient, + cfClient, mutation.NewSystem(mutation.SystemOpts{}), + nil, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -339,10 +465,10 @@ func Test_Tracker(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) providerCache := frameworksexternaldata.NewCache() - if err := setupController(mgr, wm, opaClient, mutation.NewSystem(mutation.SystemOpts{}), providerCache); err != nil { + if err := setupController(mgr, wm, cfClient, mutation.NewSystem(mutation.SystemOpts{}), nil, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -363,20 +489,20 @@ func Test_Tracker(t *testing.T) { // Verify cache (tracks testdata fixtures) for _, ct := range testTemplates { - _, err := opaClient.GetTemplate(ct) + _, err := cfClient.GetTemplate(ct) if err != nil { t.Fatalf("checking cache for template: %v", err) } } for _, c := range testConstraints { - _, err := opaClient.GetConstraint(c) + _, err := cfClient.GetConstraint(c) if err != nil { t.Fatalf("checking cache for constraint: %v", err) } } - // TODO: Verify data if we add the corresponding API to opa.Client. + // TODO: Verify data if we add the corresponding API to cf.Client. // for _, d := range testData { - // _, err := opaClient.GetData(ctx, c) + // _, err := cfClient.GetData(ctx, c) // if err != nil { // t.Fatalf("checking cache for constraint: %v", err) // } @@ -390,13 +516,13 @@ func Test_Tracker(t *testing.T) { g.Eventually(func() (bool, error) { // Verify cache (tracks testdata/post fixtures) for _, ct := range postTemplates { - _, err := opaClient.GetTemplate(ct) + _, err := cfClient.GetTemplate(ct) if err != nil { return false, err } } for _, c := range postConstraints { - _, err := opaClient.GetConstraint(c) + _, err := cfClient.GetConstraint(c) if err != nil { return false, err } @@ -437,10 +563,10 @@ func Test_Tracker_UnregisteredCachedData(t *testing.T) { // Wire up the rest. mgr, wm := setupManager(t) - opaClient := setupOpa(t) + cfClient := setupDataClient(t) providerCache := frameworksexternaldata.NewCache() - if err := setupController(mgr, wm, opaClient, mutation.NewSystem(mutation.SystemOpts{}), providerCache); err != nil { + if err := setupController(mgr, wm, cfClient, mutation.NewSystem(mutation.SystemOpts{}), nil, providerCache); err != nil { t.Fatalf("setupControllers: %v", err) } @@ -463,7 +589,7 @@ func Test_CollectDeleted(t *testing.T) { type test struct { description string gvk schema.GroupVersionKind - tracker readiness.Expectations + tracker *readiness.Expectations } g := gomega.NewWithT(t) @@ -480,7 +606,7 @@ func Test_CollectDeleted(t *testing.T) { lister: mgr.GetAPIReader(), namespace: "gatekeeper-system", } - tracker := readiness.NewTracker(lister, false, false) + tracker := readiness.NewTracker(lister, false, false, false) err = mgr.Add(manager.RunnableFunc(func(ctx context.Context) error { return tracker.Run(ctx) })) @@ -521,7 +647,7 @@ func Test_CollectDeleted(t *testing.T) { // between them to keep the test short. Trackers are mostly independent per GVK. tests := []test{ {description: "constraints", gvk: cgvk}, - {description: "data (configmaps)", gvk: cmgvk, tracker: cmtracker}, + {description: "data (configmaps)", gvk: cmgvk, tracker: &cmtracker}, {description: "templates", gvk: ctgvk}, // no need to check Config here since it is not actually Expected for readiness // (the objects identified in a Config's syncOnly are Expected, tested in data case above) @@ -531,7 +657,7 @@ func Test_CollectDeleted(t *testing.T) { t.Run(tc.description, func(t *testing.T) { var tt readiness.Expectations if tc.tracker != nil { - tt = tc.tracker + tt = *tc.tracker } else { tt = tracker.For(tc.gvk) } diff --git a/pkg/readiness/ready_tracker_unit_test.go b/pkg/readiness/ready_tracker_unit_test.go index b732400f321..bfdc38fc1e5 100644 --- a/pkg/readiness/ready_tracker_unit_test.go +++ b/pkg/readiness/ready_tracker_unit_test.go @@ -72,7 +72,7 @@ func Test_ReadyTracker_TryCancelTemplate_No_Retries(t *testing.T) { g := gomega.NewWithT(t) l := dummyLister{} - rt := newTracker(l, false, false, func() objData { + rt := newTracker(l, false, false, false, func() objData { return objData{retries: 0} }) @@ -114,7 +114,7 @@ func Test_ReadyTracker_TryCancelTemplate_Retries(t *testing.T) { g := gomega.NewWithT(t) l := dummyLister{} - rt := newTracker(l, false, false, func() objData { + rt := newTracker(l, false, false, false, func() objData { return objData{retries: 2} }) diff --git a/pkg/readiness/setup.go b/pkg/readiness/setup.go index 8882959ac91..47e2b3721ce 100644 --- a/pkg/readiness/setup.go +++ b/pkg/readiness/setup.go @@ -25,8 +25,23 @@ import ( // SetupTracker sets up a readiness tracker and registers it to run under control of the // provided Manager object. // NOTE: Must be called _before_ the manager is started. -func SetupTracker(mgr manager.Manager, mutationEnabled bool, externalDataEnabled bool) (*Tracker, error) { - tracker := NewTracker(mgr.GetAPIReader(), mutationEnabled, externalDataEnabled) +func SetupTracker(mgr manager.Manager, mutationEnabled, externalDataEnabled, expansionEnabled bool) (*Tracker, error) { + tracker, err := SetupTrackerNoReadyz(mgr, mutationEnabled, externalDataEnabled, expansionEnabled) + if err != nil { + return nil, err + } + + if err := mgr.AddReadyzCheck("tracker", tracker.CheckSatisfied); err != nil { + return nil, fmt.Errorf("registering readiness check: %w", err) + } + + return tracker, nil +} + +// SetupTrackerNoReadyz sets up a readiness tracker and registers it to run under control of the +// provided Manager object without instantiating /readyz (used for testing). +func SetupTrackerNoReadyz(mgr manager.Manager, mutationEnabled, externalDataEnabled, expansionEnabled bool) (*Tracker, error) { + tracker := NewTracker(mgr.GetAPIReader(), mutationEnabled, externalDataEnabled, expansionEnabled) err := mgr.Add(manager.RunnableFunc(func(ctx context.Context) error { return tracker.Run(ctx) @@ -35,9 +50,5 @@ func SetupTracker(mgr manager.Manager, mutationEnabled bool, externalDataEnabled return nil, fmt.Errorf("adding tracker to manager: %w", err) } - if err := mgr.AddReadyzCheck("tracker", tracker.CheckSatisfied); err != nil { - return nil, fmt.Errorf("registering readiness check: %w", err) - } - return tracker, nil } diff --git a/pkg/readiness/testdata/99-assignimage.yaml b/pkg/readiness/testdata/99-assignimage.yaml new file mode 100644 index 00000000000..54b65084178 --- /dev/null +++ b/pkg/readiness/testdata/99-assignimage.yaml @@ -0,0 +1,21 @@ +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: demo +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:*].image" + parameters: + assignDomain: "barcorp.org" + assignTag: ":latest" + assignPath: "newpath/newrepo" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] + diff --git a/pkg/readiness/testdata/99-expansion-template.yaml b/pkg/readiness/testdata/99-expansion-template.yaml new file mode 100644 index 00000000000..716a48456d4 --- /dev/null +++ b/pkg/readiness/testdata/99-expansion-template.yaml @@ -0,0 +1,15 @@ +apiVersion: expansion.gatekeeper.sh/v1alpha1 +kind: ExpansionTemplate +metadata: + name: demo +spec: + applyTo: + - groups: [ "apps" ] + kinds: [ "Deployment", "ReplicaSet" ] + versions: [ "v1" ] + templateSource: "spec.template" + enforcementAction: "deny" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" diff --git a/pkg/readiness/testdata_test.go b/pkg/readiness/testdata_test.go index 845e1feac36..5439cc4f547 100644 --- a/pkg/readiness/testdata_test.go +++ b/pkg/readiness/testdata_test.go @@ -18,7 +18,9 @@ package readiness_test import ( externaldatav1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/mutations/v1alpha1" + mutationsv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/v1alpha1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -51,6 +53,10 @@ var testModifySet = []*mutationsv1alpha1.ModifySet{ makeModifySet("demo"), } +var testAssignImage = []*mutationsv1alpha1.AssignImage{ + makeAssignImage("demo"), +} + var testAssign = []*mutationsv1alpha1.Assign{ makeAssign("demo"), } @@ -59,6 +65,8 @@ var testProvider = []*externaldatav1beta1.Provider{ makeProvider("demo"), } +var testNS = makeNS("demo") + func makeTemplate(name string) *templates.ConstraintTemplate { return &templates.ConstraintTemplate{ ObjectMeta: metav1.ObjectMeta{ @@ -105,6 +113,21 @@ func makeModifySet(name string) *mutationsv1alpha1.ModifySet { } } +func makeAssignImage(name string) *mutationsv1alpha1.AssignImage { + return &mutationsv1alpha1.AssignImage{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "mutations.gatekeeper.sh/v1alpha1", + Kind: "AssignImage", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: mutationsv1alpha1.AssignImageSpec{ + Location: "spec.containers[name:*].image", + }, + } +} + func makeAssign(name string) *mutationsv1alpha1.Assign { return &mutationsv1alpha1.Assign{ TypeMeta: metav1.TypeMeta{ @@ -135,3 +158,39 @@ func makeProvider(name string) *externaldatav1beta1.Provider { }, } } + +func makeDeployment(name string) *appsv1.Deployment { + return &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx:latest", + }, + }, + }, + }, + }, + } +} + +func makeNS(name string) *corev1.Namespace { + return &corev1.Namespace{ + TypeMeta: metav1.TypeMeta{ + Kind: "Namespace", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } +} diff --git a/pkg/readiness/tracker_map.go b/pkg/readiness/tracker_map.go index f18fb86b932..57a596eaae1 100644 --- a/pkg/readiness/tracker_map.go +++ b/pkg/readiness/tracker_map.go @@ -66,6 +66,10 @@ func (t *trackerMap) Get(gvk schema.GroupVersionKind) Expectations { t.mu.Lock() defer t.mu.Unlock() + // re-retrieve map entry in case it was added after releasing the read lock. + if e, ok := t.m[gvk]; ok { + return e + } entry := newObjTracker(gvk, t.fn) t.m[gvk] = entry return entry diff --git a/pkg/syncutil/backoff.go b/pkg/syncutil/backoff.go index c9898d12f1e..44f34f55e25 100644 --- a/pkg/syncutil/backoff.go +++ b/pkg/syncutil/backoff.go @@ -17,6 +17,7 @@ package syncutil import ( "context" + "errors" "time" "k8s.io/apimachinery/pkg/util/wait" @@ -31,7 +32,7 @@ import ( // 1. the condition check returns true or an error, or // 2. the context is canceled. // In case (1) the returned error is what the condition function returned. -// In all other cases, ErrWaitTimeout is returned. +// In all other cases, wait.ErrorInterrupted is returned. // // Adapted from wait.ExponentialBackoff in https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/util/wait/wait.go func BackoffWithContext(ctx context.Context, backoff wait.Backoff, condition wait.ConditionFunc) error { @@ -42,8 +43,8 @@ func BackoffWithContext(ctx context.Context, backoff wait.Backoff, condition wai select { case <-time.After(backoff.Step()): case <-ctx.Done(): - return wait.ErrWaitTimeout + return wait.ErrorInterrupted(errors.New("context canceled during backoff")) } } - return wait.ErrWaitTimeout + return wait.ErrorInterrupted(errors.New("maximum backoff retries exceeded")) } diff --git a/pkg/syncutil/stats_reporter.go b/pkg/syncutil/stats_reporter.go new file mode 100644 index 00000000000..42a1b8f2f32 --- /dev/null +++ b/pkg/syncutil/stats_reporter.go @@ -0,0 +1,209 @@ +package syncutil + +import ( + "context" + "strings" + "sync" + "time" + + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var log = logf.Log.WithName("reporter").WithValues("metaKind", "Sync") + +const ( + syncMetricName = "sync" + syncDurationMetricName = "sync_duration_seconds" + lastRunTimeMetricName = "sync_last_run_time" +) + +var ( + syncM = stats.Int64(syncMetricName, "Total number of resources of each kind being cached", stats.UnitDimensionless) + syncDurationM = stats.Float64(syncDurationMetricName, "Latency of sync operation in seconds", stats.UnitSeconds) + lastRunSyncM = stats.Float64(lastRunTimeMetricName, "Timestamp of last sync operation", stats.UnitSeconds) + + kindKey = tag.MustNewKey("kind") + statusKey = tag.MustNewKey("status") + + views = []*view.View{ + { + Name: syncM.Name(), + Measure: syncM, + Description: syncM.Description(), + Aggregation: view.LastValue(), + TagKeys: []tag.Key{kindKey, statusKey}, + }, + { + Name: syncDurationM.Name(), + Measure: syncDurationM, + Description: syncDurationM.Description(), + Aggregation: view.Distribution(0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008, 0.0009, 0.001, 0.002, 0.003, 0.004, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05), + }, + { + Name: lastRunSyncM.Name(), + Measure: lastRunSyncM, + Description: lastRunSyncM.Description(), + Aggregation: view.LastValue(), + }, + } +) + +type MetricsCache struct { + mux sync.RWMutex + Cache map[string]Tags + KnownKinds map[string]bool +} + +type Tags struct { + Kind string + Status metrics.Status +} + +func NewMetricsCache() *MetricsCache { + return &MetricsCache{ + Cache: make(map[string]Tags), + KnownKinds: make(map[string]bool), + } +} + +func GetKeyForSyncMetrics(namespace string, name string) string { + return strings.Join([]string{namespace, name}, "/") +} + +// need to know encountered kinds to reset metrics for that kind +// this is a known memory leak +// footprint should naturally reset on Pod upgrade b/c the container restarts. +func (c *MetricsCache) AddKind(key string) { + c.mux.Lock() + defer c.mux.Unlock() + + c.KnownKinds[key] = true +} + +func (c *MetricsCache) ResetCache() { + c.mux.Lock() + defer c.mux.Unlock() + + c.Cache = make(map[string]Tags) +} + +func (c *MetricsCache) AddObject(key string, t Tags) { + c.mux.Lock() + defer c.mux.Unlock() + + c.Cache[key] = Tags{ + Kind: t.Kind, + Status: t.Status, + } +} + +func (c *MetricsCache) DeleteObject(key string) { + c.mux.Lock() + defer c.mux.Unlock() + + delete(c.Cache, key) +} + +func (c *MetricsCache) GetTags(key string) *Tags { + c.mux.RLock() + defer c.mux.RUnlock() + + cpy := &Tags{} + v, ok := c.Cache[key] + if ok { + cpy.Kind = v.Kind + cpy.Status = v.Status + } + + return cpy +} + +func (c *MetricsCache) HasObject(key string) bool { + c.mux.RLock() + defer c.mux.RUnlock() + + _, ok := c.Cache[key] + return ok +} + +func (c *MetricsCache) ReportSync() { + c.mux.RLock() + defer c.mux.RUnlock() + + reporter, err := NewStatsReporter() + if err != nil { + log.Error(err, "failed to initialize reporter") + return + } + + totals := make(map[Tags]int) + for _, v := range c.Cache { + totals[v]++ + } + + for kind := range c.KnownKinds { + for _, status := range metrics.AllStatuses { + if err := reporter.ReportSync( + Tags{ + Kind: kind, + Status: status, + }, + int64(totals[Tags{ + Kind: kind, + Status: status, + }])); err != nil { + log.Error(err, "failed to report sync") + } + } + } +} + +func init() { + if err := register(); err != nil { + panic(err) + } +} + +func register() error { + return view.Register(views...) +} + +type Reporter struct { + now func() float64 +} + +// NewStatsReporter creates a reporter for sync metrics. +func NewStatsReporter() (*Reporter, error) { + return &Reporter{now: now}, nil +} + +func (r *Reporter) ReportSyncDuration(d time.Duration) error { + ctx := context.Background() + return metrics.Record(ctx, syncDurationM.M(d.Seconds())) +} + +func (r *Reporter) ReportLastSync() error { + ctx := context.Background() + return metrics.Record(ctx, lastRunSyncM.M(r.now())) +} + +func (r *Reporter) ReportSync(t Tags, v int64) error { + ctx, err := tag.New( + context.Background(), + tag.Insert(kindKey, t.Kind), + tag.Insert(statusKey, string(t.Status))) + if err != nil { + return err + } + + return metrics.Record(ctx, syncM.M(v)) +} + +// now returns the timestamp as a second-denominated float. +func now() float64 { + return float64(time.Now().UnixNano()) / 1e9 +} diff --git a/pkg/controller/sync/stats_reporter_test.go b/pkg/syncutil/stats_reporter_test.go similarity index 94% rename from pkg/controller/sync/stats_reporter_test.go rename to pkg/syncutil/stats_reporter_test.go index 252f84849b1..828c5856ced 100644 --- a/pkg/controller/sync/stats_reporter_test.go +++ b/pkg/syncutil/stats_reporter_test.go @@ -1,10 +1,10 @@ -package sync +package syncutil import ( "testing" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats/view" "go.opencensus.io/tag" ) @@ -22,7 +22,7 @@ func TestReportSync(t *testing.T) { t.Errorf("newStatsReporter() error %v", err) } - err = r.reportSync(wantTags, wantValue) + err = r.ReportSync(wantTags, wantValue) if err != nil { t.Fatalf("got reportSync() error %v", err) } @@ -62,12 +62,12 @@ func TestReportSyncLatency(t *testing.T) { t.Fatalf("got newStatsReporter() error %v, want nil", err) } - err = r.reportSyncDuration(minLatency) + err = r.ReportSyncDuration(minLatency) if err != nil { t.Fatalf("got reportSyncDuration() error %v, want nil", err) } - err = r.reportSyncDuration(maxLatency) + err = r.ReportSyncDuration(maxLatency) if err != nil { t.Fatalf("got reportSyncDuration error %v, want nil", err) } @@ -105,7 +105,7 @@ func TestLastRunSync(t *testing.T) { } r.now = fakeNow - err = r.reportLastSync() + err = r.ReportLastSync() if err != nil { t.Fatalf("got reportLastSync() error %v, want nil", err) } diff --git a/pkg/syncutil/syncbool_test.go b/pkg/syncutil/syncbool_test.go index f5e5931efe3..75606c50233 100644 --- a/pkg/syncutil/syncbool_test.go +++ b/pkg/syncutil/syncbool_test.go @@ -16,10 +16,11 @@ limitations under the License. package syncutil_test import ( + "context" "testing" "time" - "github.com/open-policy-agent/gatekeeper/pkg/syncutil" + "github.com/open-policy-agent/gatekeeper/v3/pkg/syncutil" "k8s.io/apimachinery/pkg/util/wait" ) @@ -36,7 +37,7 @@ func Test_SyncBool(t *testing.T) { b.Set(true) }() - waitErr := wait.Poll(10*time.Millisecond, 5*time.Second, func() (done bool, err error) { + waitErr := wait.PollUntilContextTimeout(context.Background(), 10*time.Millisecond, 5*time.Second, false, func(ctx context.Context) (done bool, err error) { return b.Get(), nil }) diff --git a/pkg/target/data.go b/pkg/target/data.go index 35fa7df9574..de9af6ece8d 100644 --- a/pkg/target/data.go +++ b/pkg/target/data.go @@ -1,7 +1,7 @@ package target import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/target/match_schema.go b/pkg/target/match_schema.go index 314815e5e76..e3ed2e7b876 100644 --- a/pkg/target/match_schema.go +++ b/pkg/target/match_schema.go @@ -1,130 +1,49 @@ package target -import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" +import ( + "fmt" -// This pattern is meant to match: -// -// REGULAR NAMESPACES -// - These are defined by this pattern: [a-z0-9]([-a-z0-9]*[a-z0-9])? -// - You'll see that this is the first two-thirds or so of the pattern below -// -// PREFIX OR SUFFIX BASED WILDCARDS -// - A typical namespace must end in an alphanumeric character. A prefixed wildcard -// can end in "*" (like `kube*`) or "-*" (like `kube-*`), and a suffixed wildcard -// can start with "*" (like `*system`) or "*-" (like `*-system`). -// - To implement this, we add either (\*|\*-)? as a prefix or (\*|-\*)? as a suffix. -// Using both prefixed wildcards and suffixed wildcards at once is not supported. Therefore, -// this _does not_ allow the value to start _and_ end in a wildcard (like `*-*`). -// - Crucially, this _does not_ allow the value to start or end in a dash (like `-system` or `kube-`). -// That is not a valid namespace and not a wildcard, so it's disallowed. -// -// Notably, this disallows other uses of the "*" character like: -// - * -// - k*-system -// -// See the following regexr to test this regex: https://regexr.com/6dgdj -const wildcardNSPattern = `^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$` + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/yaml" +) -func matchSchema() apiextensions.JSONSchemaProps { - // Define some repeatedly used sections - wildcardNSList := apiextensions.JSONSchemaProps{ - Type: "array", - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{Type: "string", Pattern: wildcardNSPattern}, - }, +var matchJSONSchemaProps apiextensions.JSONSchemaProps + +func init() { + matchCRD := &apiextensionsv1.CustomResourceDefinition{} + if err := yaml.Unmarshal([]byte(matchYAML), matchCRD); err != nil { + panic(fmt.Errorf("failed to unmarshal match yaml: %w", err)) } - nullableStringList := apiextensions.JSONSchemaProps{ - Type: "array", - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{Type: "string", Nullable: true}, - }, + // Sanity checks to ensure the CRD was generated properly + if len(matchCRD.Spec.Versions) != 1 { + panic(fmt.Errorf("generated match CRD does not contain any versions")) + } + if matchCRD.Spec.Versions[0].Schema.OpenAPIV3Schema == nil { + panic(fmt.Errorf("generated match CRD has nil OpenAPIV3Schema")) } - trueBool := true - labelSelectorSchema := apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "matchLabels": { - Type: "object", - Description: "A mapping of label keys to sets of allowed label values for those keys. A selected resource will match all of these expressions.", - AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{ - Allows: true, - Schema: &apiextensions.JSONSchemaProps{Type: "string"}, - }, - XPreserveUnknownFields: &trueBool, - }, - "matchExpressions": { - Type: "array", - Description: "a list of label selection expressions. A selected resource will match all of these expressions.", - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Description: "a selector that specifies a label key, a set of label values, an operator that defines the relationship between the two that will match the selector.", - Properties: map[string]apiextensions.JSONSchemaProps{ - "key": { - Description: "the label key that the selector applies to.", - Type: "string", - }, - "operator": { - Type: "string", - Description: "the relationship between the label and value set that defines a matching selection.", - Enum: []apiextensions.JSON{ - "In", - "NotIn", - "Exists", - "DoesNotExist", - }, - }, - "values": { - Type: "array", - Description: "a set of label values.", - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{Type: "string"}, - }, - }, - }, - }, - }, - }, - }, + // Convert v1 JSONSchemaProps to versionless + rt := runtime.NewScheme() + if err := apiextensions.AddToScheme(rt); err != nil { + panic(fmt.Errorf("could not add apiextensions to scheme: %w", err)) + } + if err := apiextensionsv1.AddToScheme(rt); err != nil { + panic(fmt.Errorf("could not add apiextensionsv1 to scheme: %w", err)) + } + embedded := matchCRD.Spec.Versions[0].Schema.OpenAPIV3Schema.Properties["embeddedMatch"] + if err := rt.Convert(&embedded, &matchJSONSchemaProps, nil); err != nil { + panic(fmt.Errorf("could not convert match JSONSchemaProps from v1 to versionless: %w", err)) } - // Make sure to copy description changes into pkg/mutation/match/match.go's `Match` struct. - return apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "kinds": { - Type: "array", - Items: &apiextensions.JSONSchemaPropsOrArray{ - Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Description: "The Group and Kind of objects that should be matched. If multiple groups/kinds combinations are specified, an incoming resource need only match one to be in scope.", - Properties: map[string]apiextensions.JSONSchemaProps{ - "apiGroups": nullableStringList, - "kinds": nullableStringList, - }, - }, - }, - }, - "namespaces": *propsWithDescription(&wildcardNSList, "`namespaces` is a list of namespace names. If defined, a constraint only applies to resources in a listed namespace. Namespaces also supports a prefix-based glob. For example, `namespaces: [kube-*]` matches both `kube-system` and `kube-public`."), - "excludedNamespaces": *propsWithDescription(&wildcardNSList, "`excludedNamespaces` is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix-based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`."), - "labelSelector": *propsWithDescription(&labelSelectorSchema, "`labelSelector` is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions from both sections are ANDed to determine if an object meets the cumulative requirements of the selector."), - "namespaceSelector": *propsWithDescription(&labelSelectorSchema, "`namespaceSelector` is a label selector against an object's containing namespace or the object itself, if the object is a namespace."), - "scope": { - Type: "string", - Description: "`scope` determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`)", - Enum: []apiextensions.JSON{ - "*", - "Cluster", - "Namespaced", - }, - }, - "name": { - Type: "string", - Description: "`name` is the name of an object. If defined, it matches against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` matches both `pod-a` and `pod-b`.", - Pattern: wildcardNSPattern, - }, - }, + // Verify conversion worked by checking properties field + if _, exists := matchJSONSchemaProps.Properties["kinds"]; !exists { + panic("converted match schema does not have 'kinds' field") } } + +func matchSchema() apiextensions.JSONSchemaProps { + return *matchJSONSchemaProps.DeepCopy() +} diff --git a/pkg/target/matchcrd_constant.go b/pkg/target/matchcrd_constant.go new file mode 100644 index 00000000000..fd454258514 --- /dev/null +++ b/pkg/target/matchcrd_constant.go @@ -0,0 +1,216 @@ +package target + +// DO NOT MODIFY THIS FILE DIRECTLY! +// This file is generated from ./pkg/mutation/match/match_types.go via "make manifests". + +const matchYAML = ` +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: matchcrd.match.gatekeeper.sh +spec: + group: match.gatekeeper.sh + names: + kind: DummyCRD + listKind: DummyCRDList + plural: matchcrd + singular: dummycrd + scope: Namespaced + versions: + - name: match + schema: + openAPIV3Schema: + description: DummyCRD is a "dummy" CRD to hold the Match object, which we + ultimately need to generate JSONSchemaProps. The TypeMeta and ObjectMeta + fields are required for controller-gen to generate the CRD. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + embeddedMatch: + description: Match selects which objects are in scope. + properties: + excludedNamespaces: + description: 'ExcludedNamespaces is a list of namespace names. If + defined, a constraint only applies to resources not in a listed + namespace. ExcludedNamespaces also supports a prefix or suffix based + glob. For example, `+"`"+`excludedNamespaces: [kube-*]`+"`"+` matches both + `+"`"+`kube-system`+"`"+` and `+"`"+`kube-public`+"`"+`, and `+"`"+`excludedNamespaces: [*-system]`+"`"+` + matches both `+"`"+`kube-system`+"`"+` and `+"`"+`gatekeeper-system`+"`"+`.' + items: + description: 'A string that supports globbing at its front or end. + Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" + will match "kube-system" or "gatekeeper-system". The asterisk + is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups and + kinds fields that list the groups/kinds of objects to which the + mutation will apply. If multiple groups/kinds objects are specified, + only one match is needed for the resource to be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of the + slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: 'LabelSelector is the combination of two optional fields: + `+"`"+`matchLabels`+"`"+` and `+"`"+`matchExpressions`+"`"+`. These two fields provide + different methods of selecting or excluding k8s objects based on + the label keys and values included in object metadata. All selection + expressions from both sections are ANDed to determine if an object + meets the cumulative requirements of the selector.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + name: + description: 'Name is the name of an object. If defined, it will + match against objects with the specified name. Name also supports + a prefix or suffix glob. For example, `+"`"+`name: pod-*`+"`"+` would match + both `+"`"+`pod-a`+"`"+` and `+"`"+`pod-b`+"`"+`, and `+"`"+`name: *-pod`+"`"+` would match both `+"`"+`a-pod`+"`"+` + and `+"`"+`b-pod`+"`"+`.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + namespaceSelector: + description: NamespaceSelector is a label selector against an object's + containing namespace or the object itself, if the object is a namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + namespaces: + description: 'Namespaces is a list of namespace names. If defined, + a constraint only applies to resources in a listed namespace. Namespaces + also supports a prefix or suffix based glob. For example, `+"`"+`namespaces: + [kube-*]`+"`"+` matches both `+"`"+`kube-system`+"`"+` and `+"`"+`kube-public`+"`"+`, and `+"`"+`namespaces: + [*-system]`+"`"+` matches both `+"`"+`kube-system`+"`"+` and `+"`"+`gatekeeper-system`+"`"+`.' + items: + description: 'A string that supports globbing at its front or end. + Ex: "kube-*" will match "kube-system" or "kube-public", "*-system" + will match "kube-system" or "gatekeeper-system". The asterisk + is required for wildcard matching.' + pattern: ^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$ + type: string + type: array + scope: + description: Scope determines if cluster-scoped and/or namespaced-scoped + resources are matched. Accepts `+"`"+`*`+"`"+`, `+"`"+`Cluster`+"`"+`, or `+"`"+`Namespaced`+"`"+`. + (defaults to `+"`"+`*`+"`"+`) + type: string + source: + description: Source determines whether generated or original resources + are matched. Accepts `+"`"+`Generated`+"`"+`|`+"`"+`Original`+"`"+`|`+"`"+`All`+"`"+` (defaults to `+"`"+`All`+"`"+`). + A value of `+"`"+`Generated`+"`"+` will only match generated resources, while + `+"`"+`Original`+"`"+` will only match regular resources. + enum: + - All + - Generated + - Original + type: string + type: object + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadataDummy: + type: object + type: object + served: true + storage: true +` diff --git a/pkg/target/matcher.go b/pkg/target/matcher.go index eaa7591ff11..ad199713fe9 100644 --- a/pkg/target/matcher.go +++ b/pkg/target/matcher.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -56,7 +56,7 @@ func matchAny(m *Matcher, ns *corev1.Namespace, source types.SourceType, objs .. } matched, err := match.Matches(m.match, t) if err != nil { - return false, fmt.Errorf("%w: %v", ErrMatching, err) + return false, fmt.Errorf("%w: %v :%w", ErrMatching, obj.GetName(), err) } if matched { diff --git a/pkg/target/review.go b/pkg/target/review.go index f814c337efb..f2fbe1fa60b 100644 --- a/pkg/target/review.go +++ b/pkg/target/review.go @@ -1,7 +1,7 @@ package target import ( - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" ) @@ -17,3 +17,7 @@ type gkReview struct { namespace *corev1.Namespace source types.SourceType } + +func (g *gkReview) GetAdmissionRequest() *admissionv1.AdmissionRequest { + return &g.AdmissionRequest +} diff --git a/pkg/target/target.go b/pkg/target/target.go index c93c16d5c3e..e6c14c7ca1d 100644 --- a/pkg/target/target.go +++ b/pkg/target/target.go @@ -6,7 +6,7 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" "github.com/open-policy-agent/frameworks/constraint/pkg/handler" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" "github.com/pkg/errors" admissionv1 "k8s.io/api/admission/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -162,12 +162,6 @@ func unstructuredToAdmissionRequest(obj *unstructured.Unstructured) (*gkReview, return &gkReview{AdmissionRequest: req}, nil } -func propsWithDescription(props *apiextensions.JSONSchemaProps, description string) *apiextensions.JSONSchemaProps { - propCopy := props.DeepCopy() - propCopy.Description = description - return propCopy -} - func (h *K8sValidationTarget) MatchSchema() apiextensions.JSONSchemaProps { return matchSchema() } @@ -183,7 +177,7 @@ func (h *K8sValidationTarget) ValidateConstraint(u *unstructured.Unstructured) e if err != nil { return err } - errorList := validation.ValidateLabelSelector(labelSelectorObj, field.NewPath("spec", "labelSelector")) + errorList := validation.ValidateLabelSelector(labelSelectorObj, validation.LabelSelectorValidationOptions{}, field.NewPath("spec", "labelSelector")) if len(errorList) > 0 { return errorList.ToAggregate() } @@ -199,7 +193,7 @@ func (h *K8sValidationTarget) ValidateConstraint(u *unstructured.Unstructured) e if err != nil { return err } - errorList := validation.ValidateLabelSelector(namespaceSelectorObj, field.NewPath("spec", "labelSelector")) + errorList := validation.ValidateLabelSelector(namespaceSelectorObj, validation.LabelSelectorValidationOptions{}, field.NewPath("spec", "labelSelector")) if len(errorList) > 0 { return errorList.ToAggregate() } @@ -236,13 +230,13 @@ func convertToMatch(object map[string]interface{}) (*match.Match, error) { func (h *K8sValidationTarget) ToMatcher(u *unstructured.Unstructured) (constraints.Matcher, error) { obj, found, err := unstructured.NestedMap(u.Object, "spec", "match") if err != nil { - return nil, fmt.Errorf("%w: %v", ErrCreatingMatcher, err) + return nil, fmt.Errorf("%w: %w", ErrCreatingMatcher, err) } if found && obj != nil { m, err := convertToMatch(obj) if err != nil { - return nil, fmt.Errorf("%w: %v", ErrCreatingMatcher, err) + return nil, fmt.Errorf("%w: %w", ErrCreatingMatcher, err) } return &Matcher{match: m, cache: &h.cache}, nil } diff --git a/pkg/target/target_integration_test.go b/pkg/target/target_integration_test.go index 20f8b189d8d..dee7d32558e 100644 --- a/pkg/target/target_integration_test.go +++ b/pkg/target/target_integration_test.go @@ -5,17 +5,19 @@ import ( "encoding/json" "testing" - "github.com/ghodss/yaml" + templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + api "github.com/open-policy-agent/gatekeeper/v3/apis" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/yaml" ) const ( @@ -412,10 +414,15 @@ func TestConstraintEnforcement(t *testing.T) { }, } + scheme := runtime.NewScheme() + if err := api.AddToScheme(scheme); err != nil { + t.Fatalf("could not initialize scheme: %s", err) + } + for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { target := &K8sValidationTarget{} - driver, err := local.New(local.Tracing(true)) + driver, err := rego.New(rego.Tracing(true)) if err != nil { t.Fatalf("unable to set up Driver: %v", err) } @@ -425,10 +432,14 @@ func TestConstraintEnforcement(t *testing.T) { t.Fatalf("unable to set up OPA client: %s", err) } - tmpl := &templates.ConstraintTemplate{} - if err := yaml.Unmarshal([]byte(testTemplate), tmpl); err != nil { + versionedTmpl := &templatesv1beta1.ConstraintTemplate{} + if err := yaml.Unmarshal([]byte(testTemplate), versionedTmpl); err != nil { t.Fatalf("unable to unmarshal template: %s", err) } + tmpl := &templates.ConstraintTemplate{} + if err := scheme.Convert(versionedTmpl, tmpl, nil); err != nil { + t.Fatalf("could not convert template: %s", err) + } ctx := context.Background() if _, err := c.AddTemplate(ctx, tmpl); err != nil { t.Fatalf("unable to add template: %s", err) diff --git a/pkg/target/target_test.go b/pkg/target/target_test.go index 33fececaeee..83f507465bd 100644 --- a/pkg/target/target_test.go +++ b/pkg/target/target_test.go @@ -10,12 +10,12 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" - "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,7 +26,7 @@ import ( func TestFrameworkInjection(t *testing.T) { target := &K8sValidationTarget{} - driver, err := local.New(local.Tracing(true)) + driver, err := rego.New(rego.Tracing(true)) if err != nil { t.Fatal(err) } @@ -54,6 +54,7 @@ func TestValidateConstraint(t *testing.T) { }, "spec": { "match": { + "source": "All", "kinds": [ { "apiGroups": [""], @@ -80,6 +81,7 @@ func TestValidateConstraint(t *testing.T) { }, "spec": { "match": { + "source": "Original", "kinds": [ { "apiGroups": [""], @@ -90,7 +92,7 @@ func TestValidateConstraint(t *testing.T) { "matchExpressions": [{ "key": "someKey", "operator": "NotIn", - "values": ["some value"] + "values": ["some-value"] }] } }, @@ -130,7 +132,7 @@ func TestValidateConstraint(t *testing.T) { ErrorExpected: true, }, { - Name: "Invalid LabelSelector MatchLels", + Name: "Invalid LabelSelector MatchLabels", Constraint: ` { "apiVersion": "constraints.gatekeeper.sh/v1beta1", @@ -202,6 +204,7 @@ func TestValidateConstraint(t *testing.T) { }, "spec": { "match": { + "source": "Generated", "kinds": [ { "apiGroups": [""], @@ -212,7 +215,7 @@ func TestValidateConstraint(t *testing.T) { "matchExpressions": [{ "key": "someKey", "operator": "In", - "values": ["some value"] + "values": ["some-value"] }] } }, @@ -245,7 +248,7 @@ func TestValidateConstraint(t *testing.T) { "matchExpressions": [{ "key": "someKey", "operator": "In", - "values": ["some value"] + "values": ["some-value"] }] } }, @@ -509,7 +512,7 @@ func fooMatch() *match.Match { }, }, Scope: "Namespaced", - Namespaces: []util.Wildcard{"my-ns"}, + Namespaces: []wildcard.Wildcard{"my-ns"}, ExcludedNamespaces: nil, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ diff --git a/pkg/upgrade/manager.go b/pkg/upgrade/manager.go index b50e4a14a3e..6b4f1eccf55 100644 --- a/pkg/upgrade/manager.go +++ b/pkg/upgrade/manager.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/util/enforcement_action.go b/pkg/util/enforcement_action.go index 39c49781bb6..555fbe2d2e4 100644 --- a/pkg/util/enforcement_action.go +++ b/pkg/util/enforcement_action.go @@ -43,7 +43,7 @@ func ValidateEnforcementAction(input EnforcementAction) error { func GetEnforcementAction(item map[string]interface{}) (EnforcementAction, error) { enforcementActionSpec, _, err := unstructured.NestedString(item, "spec", "enforcementAction") if err != nil { - return "", fmt.Errorf("%w: %v", ErrInvalidSpecEnforcementAction, err) + return "", fmt.Errorf("%w: %w", ErrInvalidSpecEnforcementAction, err) } enforcementAction := EnforcementAction(enforcementActionSpec) // default enforcementAction is deny diff --git a/pkg/util/pack.go b/pkg/util/pack.go index fdb7ba85747..720a9be71c0 100644 --- a/pkg/util/pack.go +++ b/pkg/util/pack.go @@ -1,6 +1,7 @@ package util import ( + "context" "errors" "fmt" "strings" @@ -41,7 +42,7 @@ func UnpackRequest(r reconcile.Request) (schema.GroupVersionKind, reconcile.Requ // EventPackerMapFunc maps an event into a reconcile.Request with embedded GVK information. Must // be unpacked with UnpackRequest() before use. func EventPackerMapFunc() handler.MapFunc { - return func(obj client.Object) []reconcile.Request { + return func(_ context.Context, obj client.Object) []reconcile.Request { if obj == nil { return nil } @@ -67,11 +68,11 @@ func EventPackerMapFunc() handler.MapFunc { // no GVK associated with them by allowing the caller to set the expected GVK. func EventPackerMapFuncHardcodeGVK(gvk schema.GroupVersionKind) handler.MapFunc { mf := EventPackerMapFunc() - return func(obj client.Object) []reconcile.Request { + return func(ctx context.Context, obj client.Object) []reconcile.Request { u := &unstructured.Unstructured{} u.SetGroupVersionKind(gvk) u.SetNamespace(obj.GetNamespace()) u.SetName(obj.GetName()) - return mf(u) + return mf(ctx, u) } } diff --git a/pkg/util/pack_test.go b/pkg/util/pack_test.go index 61aec95286b..e623b30f8b9 100644 --- a/pkg/util/pack_test.go +++ b/pkg/util/pack_test.go @@ -1,6 +1,7 @@ package util import ( + "context" "errors" "testing" @@ -91,7 +92,7 @@ func TestEventPackerMapFunc(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - got := EventPackerMapFunc()(tc.obj) + got := EventPackerMapFunc()(context.Background(), tc.obj) if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("got EventPackerMapFunc()(obj) diff: %v", diff) } diff --git a/pkg/util/wildcard.go b/pkg/util/wildcard.go deleted file mode 100644 index 5235ee66f34..00000000000 --- a/pkg/util/wildcard.go +++ /dev/null @@ -1,29 +0,0 @@ -package util - -import "strings" - -// +kubebuilder:validation:Pattern=`^(\*|\*-)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$` - -// A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or -// "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is -// required for wildcard matching. -// -//nolint:revive -type Wildcard string - -// Matches returns true if the candidate parameter is either an exact match of the Wildcard, -// or if the Wildcard is a valid glob-match for the candidate. The Wildcard must start or end -// in a "*" to be considered a glob. -func (w Wildcard) Matches(candidate string) bool { - wStr := string(w) - switch { - case strings.HasPrefix(wStr, "*") && strings.HasSuffix(wStr, "*"): - return strings.Contains(candidate, strings.TrimSuffix(strings.TrimPrefix(wStr, "*"), "*")) - case strings.HasPrefix(wStr, "*"): - return strings.HasSuffix(candidate, strings.TrimPrefix(wStr, "*")) - case strings.HasSuffix(wStr, "*"): - return strings.HasPrefix(candidate, strings.TrimSuffix(wStr, "*")) - default: - return wStr == candidate - } -} diff --git a/pkg/util/wildcard_test.go b/pkg/util/wildcard_test.go deleted file mode 100644 index 695260c4ed8..00000000000 --- a/pkg/util/wildcard_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package util - -import "testing" - -func TestMatches(t *testing.T) { - tcs := []struct { - name string - w Wildcard - candidate string - matches bool - }{ - { - name: "exact text match", - w: Wildcard("kube-system"), - candidate: "kube-system", - matches: true, - }, - { - name: "no glob, wrong text", - w: Wildcard("kube-system"), - candidate: "gatekeeper-system", - matches: false, - }, - { - name: "wildcard prefix match", - w: Wildcard("kube-*"), - candidate: "kube-system", - matches: true, - }, - { - name: "wildcard prefix doesn't match", - w: Wildcard("kube-*"), - candidate: "gatekeeper-system", - matches: false, - }, - { - name: "wildcard suffix match", - w: Wildcard("*-system"), - candidate: "kube-system", - matches: true, - }, - { - name: "wildcard suffix doesn't match", - w: Wildcard("*-system"), - candidate: "kube-public", - matches: false, - }, - { - name: "missing asterisk yields no wildcard support", - w: Wildcard("kube-"), - candidate: "kube-system", - matches: false, - }, - { - name: "wildcard suffix and prefix match", - w: Wildcard("*-kube-*"), - candidate: "test-kube-test", - matches: true, - }, - { - name: "no wildcard, only hypens at suffix and prefix", - w: Wildcard("-kube-"), - candidate: "test-kube-test", - matches: false, - }, - { - name: "wild card at suffix and prefix, multiple hyphens", - w: Wildcard("*-kube-*"), - candidate: "test-dev-kube-dev-test", - matches: true, - }, - { - name: "wild card at suffid and end, multiple hypens, no match", - w: Wildcard("*-kube-*"), - candidate: "my-kub-controller", - matches: false, - }, - { - name: "wild card at suffix and prefix, multiple hyphens, no match", - w: Wildcard("*-kube-*"), - candidate: "my-controller-manager", - matches: false, - }, - } - - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { - if tc.w.Matches(tc.candidate) != tc.matches { - if tc.matches { - t.Errorf("Expected candidate '%v' to match wildcard '%v'", tc.candidate, tc.w) - } else { - t.Errorf("Candidate '%v' unexpectedly matched wildcard '%v'", tc.candidate, tc.w) - } - } - }) - } -} diff --git a/pkg/version/version.go b/pkg/version/version.go index 52531b3049d..4907d50cb9b 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -3,18 +3,60 @@ package version import ( "fmt" "runtime" + "runtime/debug" ) -// Vcs is is the commit hash for the binary build. -var Vcs string - -// Timestamp is the date for the binary build. -var Timestamp string +const ( + gatorState = "beta" + unknown = "unknown" +) // Version is the gatekeeper version. var Version string -// GetUserAgent returns a user agent of the format: gatekeeper/ (/) /. -func GetUserAgent() string { - return fmt.Sprintf("gatekeeper/%s (%s/%s) %s/%s", Version, runtime.GOOS, runtime.GOARCH, Vcs, Timestamp) +// GetUserAgent returns Gatekeeper and Gator version information. +func GetUserAgent(name string) string { + vcsrevision := unknown + vcstimestamp := unknown + vcsdirty := "" + opaVersion := unknown + frameworksVersion := unknown + + if info, ok := debug.ReadBuildInfo(); ok { + for _, v := range info.Settings { + switch v.Key { + case "vcs.revision": + vcsrevision = v.Value + case "vcs.modified": + if v.Value == "true" { + vcsdirty = "-dirty" + } + case "vcs.time": + vcstimestamp = v.Value + } + } + + for _, v := range info.Deps { + switch v.Path { + case "github.com/open-policy-agent/opa": + opaVersion = v.Version + case "github.com/open-policy-agent/frameworks/constraint": + frameworksVersion = v.Version + } + } + } + + // OPA and Frameworks version used by Gatekeeper and Gator + opaFrameworksVersion := fmt.Sprintf("opa/%s, frameworks/%s", opaVersion, frameworksVersion) + + // if LDFLAGS are not set, use revision info + if Version == "" { + Version = fmt.Sprintf("devel (%s)", vcsrevision) + } + + if name == "gator" { + return fmt.Sprintf("%s (Feature State: %s), %s", Version, gatorState, opaFrameworksVersion) + } + + return fmt.Sprintf("%s/%s (%s/%s) %s%s/%s, %s", name, Version, runtime.GOOS, runtime.GOARCH, vcsrevision, vcsdirty, vcstimestamp, opaFrameworksVersion) } diff --git a/pkg/watch/manager.go b/pkg/watch/manager.go index cd8a7a0e60c..7858fa42d78 100644 --- a/pkg/watch/manager.go +++ b/pkg/watch/manager.go @@ -62,7 +62,7 @@ type AddFunction func(manager.Manager) error // It supports non-blocking calls to get informers, as well as the // ability to remove an informer dynamically. type RemovableCache interface { - GetInformerNonBlocking(obj client.Object) (cache.Informer, error) + GetInformer(_ context.Context, obj client.Object, opts ...cache.InformerGetOption) (cache.Informer, error) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error Remove(obj client.Object) error } @@ -138,13 +138,13 @@ func (wm *Manager) GetManagedGVK() []schema.GroupVersionKind { return wm.managedKinds.GetGVK() } -func (wm *Manager) addWatch(r *Registrar, gvk schema.GroupVersionKind) error { +func (wm *Manager) addWatch(ctx context.Context, r *Registrar, gvk schema.GroupVersionKind) error { wm.watchedMux.Lock() defer wm.watchedMux.Unlock() - return wm.doAddWatch(r, gvk) + return wm.doAddWatch(ctx, r, gvk) } -func (wm *Manager) doAddWatch(r *Registrar, gvk schema.GroupVersionKind) error { +func (wm *Manager) doAddWatch(ctx context.Context, r *Registrar, gvk schema.GroupVersionKind) error { // lock acquired by caller if r == nil { @@ -177,14 +177,16 @@ func (wm *Manager) doAddWatch(r *Registrar, gvk schema.GroupVersionKind) error { default: u := &unstructured.Unstructured{} u.SetGroupVersionKind(gvk) - informer, err := wm.cache.GetInformerNonBlocking(u) + informer, err := wm.cache.GetInformer(ctx, u, cache.InformerGetOption(cache.BlockUntilSynced(false))) if err != nil || informer == nil { // This is expected to fail if a CRD is unregistered. return fmt.Errorf("getting informer for kind: %+v %w", gvk, err) } // First watcher gets a fresh informer, register for events. - informer.AddEventHandler(wm) + if _, err := informer.AddEventHandler(wm); err != nil { + return err + } } // Mark it as watched. @@ -199,13 +201,13 @@ func (wm *Manager) doAddWatch(r *Registrar, gvk schema.GroupVersionKind) error { return nil } -func (wm *Manager) removeWatch(r *Registrar, gvk schema.GroupVersionKind) error { +func (wm *Manager) removeWatch(ctx context.Context, r *Registrar, gvk schema.GroupVersionKind) error { wm.watchedMux.Lock() defer wm.watchedMux.Unlock() - return wm.doRemoveWatch(r, gvk) + return wm.doRemoveWatch(ctx, r, gvk) } -func (wm *Manager) doRemoveWatch(r *Registrar, gvk schema.GroupVersionKind) error { +func (wm *Manager) doRemoveWatch(ctx context.Context, r *Registrar, gvk schema.GroupVersionKind) error { // lock acquired by caller v, ok := wm.watchedKinds[gvk] @@ -248,7 +250,7 @@ func (wm *Manager) doRemoveWatch(r *Registrar, gvk schema.GroupVersionKind) erro } // replaceWatches ensures all and only desired watches are running. -func (wm *Manager) replaceWatches(r *Registrar) error { +func (wm *Manager) replaceWatches(ctx context.Context, r *Registrar) error { wm.watchedMux.Lock() defer wm.watchedMux.Unlock() @@ -260,7 +262,7 @@ func (wm *Manager) replaceWatches(r *Registrar) error { // This registrar still desires this gvk, skip. continue } - if err := wm.doRemoveWatch(r, gvk); err != nil { + if err := wm.doRemoveWatch(ctx, r, gvk); err != nil { errlist = append(errlist, fmt.Errorf("removing watch for %+v %w", gvk, err)) } } @@ -270,7 +272,7 @@ func (wm *Manager) replaceWatches(r *Registrar) error { if !v.registrars[r] { continue } - if err := wm.doAddWatch(r, gvk); err != nil { + if err := wm.doAddWatch(ctx, r, gvk); err != nil { errlist = append(errlist, fmt.Errorf("adding watch for %+v %w", gvk, err)) } } @@ -286,7 +288,7 @@ func (wm *Manager) replaceWatches(r *Registrar) error { } // OnAdd implements cache.ResourceEventHandler. Called by informers. -func (wm *Manager) OnAdd(obj interface{}) { +func (wm *Manager) OnAdd(obj interface{}, _ bool) { // Send event to eventLoop() for processing select { case wm.events <- obj: diff --git a/pkg/watch/manager_integration_test.go b/pkg/watch/manager_integration_test.go index 1c8ea1d3983..582f1b2085f 100644 --- a/pkg/watch/manager_integration_test.go +++ b/pkg/watch/manager_integration_test.go @@ -25,19 +25,17 @@ import ( "github.com/go-logr/logr" "github.com/onsi/gomega" - "github.com/open-policy-agent/gatekeeper/pkg/fakes" - "github.com/open-policy-agent/gatekeeper/pkg/util" - "github.com/open-policy-agent/gatekeeper/pkg/watch" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" - "github.com/open-policy-agent/gatekeeper/test/testutils" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" + "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "github.com/prometheus/client_golang/prometheus" "golang.org/x/sync/errgroup" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -62,11 +60,8 @@ func setupManager(t *testing.T) (manager.Manager, *watch.Manager) { metrics.Registry = prometheus.NewRegistry() mgr, err := manager.New(cfg, manager.Options{ MetricsBindAddress: "0", - NewCache: dynamiccache.New, - MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - }, - Logger: testutils.NewLogger(t), + MapperProvider: apiutil.NewDynamicRESTMapper, + Logger: testutils.NewLogger(t), }) if err != nil { t.Fatalf("setting up controller manager: %s", err) @@ -121,7 +116,7 @@ func TestRegistrar_AddUnknown(t *testing.T) { t.Fatalf("creating registrar: %v", err) } - err = r.AddWatch(schema.GroupVersionKind{ + err = r.AddWatch(ctx, schema.GroupVersionKind{ Group: "i", Version: "donot", Kind: "exist", @@ -197,7 +192,7 @@ func Test_ReconcileErrorDoesNotBlockController(t *testing.T) { // Setup another watch. Show that both the error resource (in a backoff-requeue loop) // and other resources can reconcile in an interleaving fashion. err = c.Watch( - &source.Kind{Type: &corev1.Namespace{}}, + source.Kind(mgr.GetCache(), &corev1.Namespace{}), &handler.EnqueueRequestForObject{}, ) if err != nil { @@ -273,7 +268,7 @@ func TestRegistrar_Reconnect(t *testing.T) { t.Fatalf("applying CRD: %v", err) } - err = r.AddWatch(gvk) + err = r.AddWatch(ctx, gvk) if err != nil { t.Fatalf("adding watch: %v", err) } @@ -371,7 +366,7 @@ func Test_Registrar_Replay(t *testing.T) { t.Fatal(err) } - err = r.AddWatch(gvk) + err = r.AddWatch(ctx, gvk) if err != nil { t.Fatal(err) } diff --git a/pkg/watch/manager_suite_test.go b/pkg/watch/manager_suite_test.go index f1771820643..e70d09f0ab7 100644 --- a/pkg/watch/manager_suite_test.go +++ b/pkg/watch/manager_suite_test.go @@ -20,7 +20,7 @@ import ( "os" "testing" - "github.com/open-policy-agent/gatekeeper/apis" + "github.com/open-policy-agent/gatekeeper/v3/apis" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/envtest" diff --git a/pkg/watch/manager_test.go b/pkg/watch/manager_test.go index 713dcc2009b..35b6d8c543b 100644 --- a/pkg/watch/manager_test.go +++ b/pkg/watch/manager_test.go @@ -40,17 +40,22 @@ type fakeCacheInformer struct { handlers map[kcache.ResourceEventHandler]int } -func (f *fakeCacheInformer) AddEventHandler(h kcache.ResourceEventHandler) { +func (f *fakeCacheInformer) AddEventHandler(h kcache.ResourceEventHandler) (kcache.ResourceEventHandlerRegistration, error) { f.mu.Lock() defer f.mu.Unlock() if f.handlers == nil { f.handlers = make(map[kcache.ResourceEventHandler]int) } f.handlers[h]++ + return nil, nil } -func (f *fakeCacheInformer) AddEventHandlerWithResyncPeriod(h kcache.ResourceEventHandler, resyncPeriod time.Duration) { - f.AddEventHandler(h) +func (f *fakeCacheInformer) RemoveEventHandler(handle kcache.ResourceEventHandlerRegistration) error { + return nil +} + +func (f *fakeCacheInformer) AddEventHandlerWithResyncPeriod(h kcache.ResourceEventHandler, resyncPeriod time.Duration) (kcache.ResourceEventHandlerRegistration, error) { + return f.AddEventHandler(h) } func (f *fakeCacheInformer) AddIndexers(indexers kcache.Indexers) error { @@ -80,7 +85,7 @@ type fakeRemovableCache struct { removeCounter int } -func (f *fakeRemovableCache) GetInformerNonBlocking(obj client.Object) (cache.Informer, error) { +func (f *fakeRemovableCache) GetInformer(_ context.Context, obj client.Object, opts ...cache.InformerGetOption) (cache.Informer, error) { return f.informer, nil } @@ -109,12 +114,12 @@ func (f *fakeRemovableCache) removeCount() int { type funcCache struct { ListFunc func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error - GetInformerNonBlockingFunc func(obj client.Object) (cache.Informer, error) + GetInformerNonBlockingFunc func(ctx context.Context, obj client.Object) (cache.Informer, error) } -func (f *funcCache) GetInformerNonBlocking(obj client.Object) (cache.Informer, error) { +func (f *funcCache) GetInformer(ctx context.Context, obj client.Object, opts ...cache.InformerGetOption) (cache.Informer, error) { if f.GetInformerNonBlockingFunc != nil { - return f.GetInformerNonBlockingFunc(obj) + return f.GetInformerNonBlockingFunc(ctx, obj) } return &fakeCacheInformer{}, nil } @@ -152,6 +157,7 @@ func setupWatchManager(c RemovableCache) (*Manager, context.CancelFunc, error) { // Verifies that redundant calls to AddWatch (even across registrars) will be idempotent // and only register a single event handler on the respective informer. func TestRegistrar_AddWatch_Idempotent(t *testing.T) { + ctx := context.Background() informer := &fakeCacheInformer{} c := &fakeRemovableCache{informer: informer} wm, cancel, err := setupWatchManager(c) @@ -178,11 +184,11 @@ func TestRegistrar_AddWatch_Idempotent(t *testing.T) { } for _, r := range []*Registrar{r1, r2} { - if err := r.AddWatch(gvk); err != nil { + if err := r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting initial watch: %v", err) return } - if err := r.AddWatch(gvk); err != nil { + if err := r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting redundant watch: %v", err) return } @@ -204,6 +210,7 @@ func TestRegistrar_AddWatch_Idempotent(t *testing.T) { } func TestRegistrar_RemoveWatch_Idempotent(t *testing.T) { + ctx := context.Background() informer := &fakeCacheInformer{} c := &fakeRemovableCache{informer: informer} wm, cancel, err := setupWatchManager(c) @@ -230,7 +237,7 @@ func TestRegistrar_RemoveWatch_Idempotent(t *testing.T) { } for _, r := range []*Registrar{r1, r2} { - if err := r.AddWatch(gvk); err != nil { + if err := r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting initial watch: %v", err) return } @@ -242,7 +249,7 @@ func TestRegistrar_RemoveWatch_Idempotent(t *testing.T) { return } - if err := r1.RemoveWatch(gvk); err != nil { + if err := r1.RemoveWatch(ctx, gvk); err != nil { t.Errorf("removing first watch: %v", err) return } @@ -259,7 +266,7 @@ func TestRegistrar_RemoveWatch_Idempotent(t *testing.T) { return } - if err := r2.RemoveWatch(gvk); err != nil { + if err := r2.RemoveWatch(ctx, gvk); err != nil { t.Errorf("removing second watch: %v", err) return } @@ -278,7 +285,7 @@ func TestRegistrar_RemoveWatch_Idempotent(t *testing.T) { } // Extra removes are fine. - if err := r2.RemoveWatch(gvk); err != nil { + if err := r2.RemoveWatch(ctx, gvk); err != nil { t.Errorf("redundant remove: %v", err) return } @@ -324,7 +331,7 @@ func TestRegistrar_Replay(t *testing.T) { } for _, entry := range registrars { - if err := entry.r.AddWatch(gvk); err != nil { + if err := entry.r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting initial watch: %v", err) return } @@ -392,7 +399,7 @@ func TestRegistrar_Replay_Retry(t *testing.T) { } return nil }, - GetInformerNonBlockingFunc: func(obj client.Object) (cache.Informer, error) { + GetInformerNonBlockingFunc: func(_ context.Context, obj client.Object) (cache.Informer, error) { return informer, nil }, } @@ -417,7 +424,7 @@ func TestRegistrar_Replay_Retry(t *testing.T) { } for _, r := range []*Registrar{r1, r2} { - if err := r.AddWatch(gvk); err != nil { + if err := r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting initial watch: %v", err) return } @@ -502,7 +509,7 @@ func TestRegistrar_Replay_Async(t *testing.T) { Kind: "Pod", } for _, r := range []*Registrar{r1, r2} { - if err := r.AddWatch(gvk); err != nil { + if err := r.AddWatch(ctx, gvk); err != nil { t.Errorf("setting initial watch: %v", err) return } @@ -517,7 +524,7 @@ func TestRegistrar_Replay_Async(t *testing.T) { } // Ensure we can cancel a pending replay - if err := r2.RemoveWatch(gvk); err != nil { + if err := r2.RemoveWatch(ctx, gvk); err != nil { t.Errorf("removing watch: %v", err) } @@ -529,7 +536,7 @@ func TestRegistrar_Replay_Async(t *testing.T) { } // [Scenario 2] - Verify that pending replays are canceled during watch manager shutdown. - if err := r2.AddWatch(gvk); err != nil { + if err := r2.AddWatch(ctx, gvk); err != nil { t.Errorf("adding watch: %v", err) } select { @@ -575,6 +582,7 @@ func TestRegistrar_Duplicates_Rejected(t *testing.T) { // Verify ReplaceWatch replaces the set of watched resources for a registrar. New watches will be added, // unneeded watches will be removed, and watches that haven't changed will remain unchanged. func TestRegistrar_ReplaceWatch(t *testing.T) { + ctx := context.Background() g := gomega.NewWithT(t) var mu sync.Mutex listCalls := make(map[schema.GroupVersionKind]int) @@ -588,7 +596,7 @@ func TestRegistrar_ReplaceWatch(t *testing.T) { listCalls[gvk]++ return nil }, - GetInformerNonBlockingFunc: func(obj client.Object) (cache.Informer, error) { + GetInformerNonBlockingFunc: func(_ context.Context, obj client.Object) (cache.Informer, error) { mu.Lock() defer mu.Unlock() gvk := obj.GetObjectKind().GroupVersionKind() @@ -619,28 +627,28 @@ func TestRegistrar_ReplaceWatch(t *testing.T) { service := schema.GroupVersionKind{Version: "v1", Kind: "Service"} secret := schema.GroupVersionKind{Version: "v1", Kind: "Secret"} - err = r1.AddWatch(pod) + err = r1.AddWatch(ctx, pod) if err != nil { t.Fatalf("initial pod watch: %v", err) } - err = r1.AddWatch(volume) + err = r1.AddWatch(ctx, volume) if err != nil { t.Fatalf("initial volume watch: %v", err) } - err = r1.AddWatch(deploy) + err = r1.AddWatch(ctx, deploy) if err != nil { t.Fatalf("initial deployment watch: %v", err) } - err = r2.AddWatch(volume) + err = r2.AddWatch(ctx, volume) if err != nil { t.Fatalf("initial volume watch: %v", err) } - err = r2.AddWatch(configMap) + err = r2.AddWatch(ctx, configMap) if err != nil { t.Fatalf("initial configmap watch: %v", err) } - err = r2.AddWatch(secret) + err = r2.AddWatch(ctx, secret) if err != nil { t.Fatalf("initial secret watch: %v", err) } @@ -677,7 +685,7 @@ func TestRegistrar_ReplaceWatch(t *testing.T) { // Pod overlaps between r1 and r2. Secret is retained. ConfigMap is swapped for Service. // Volume originally overlapped between r1 and r2, but will be removed from r2. - err = r2.ReplaceWatch([]schema.GroupVersionKind{pod, service, secret}) + err = r2.ReplaceWatch(ctx, []schema.GroupVersionKind{pod, service, secret}) if err != nil { t.Fatalf("calling replaceWatch: %v", err) } diff --git a/pkg/watch/registrar.go b/pkg/watch/registrar.go index 79b080ac967..c1f90c4cd22 100644 --- a/pkg/watch/registrar.go +++ b/pkg/watch/registrar.go @@ -16,6 +16,7 @@ limitations under the License. package watch import ( + "context" "fmt" "sort" "sync" @@ -84,7 +85,7 @@ func (r *recordKeeper) RemoveRegistrar(parentName string) error { if registrar == nil { return nil } - if err := registrar.ReplaceWatch(nil); err != nil { + if err := registrar.ReplaceWatch(context.Background(), nil); err != nil { return err } @@ -227,7 +228,7 @@ type Registrar struct { // - The consumer of the channel does not receive any unbuffered events. // // XXXX also may block if the watch manager has not been started. -func (r *Registrar) AddWatch(gvk schema.GroupVersionKind) error { +func (r *Registrar) AddWatch(ctx context.Context, gvk schema.GroupVersionKind) error { r.mux.Lock() defer r.mux.Unlock() wv := vitals{ @@ -235,11 +236,11 @@ func (r *Registrar) AddWatch(gvk schema.GroupVersionKind) error { registrars: map[*Registrar]bool{r: true}, } r.managedKinds.Update(r.parentName, vitalsByGVK{gvk: wv}) - return r.mgr.addWatch(r, gvk) + return r.mgr.addWatch(ctx, r, gvk) } // ReplaceWatch replaces the set of watched resources. -func (r *Registrar) ReplaceWatch(gvks []schema.GroupVersionKind) error { +func (r *Registrar) ReplaceWatch(ctx context.Context, gvks []schema.GroupVersionKind) error { r.mux.Lock() defer r.mux.Unlock() roster := make(vitalsByGVK) @@ -251,16 +252,16 @@ func (r *Registrar) ReplaceWatch(gvks []schema.GroupVersionKind) error { roster[gvk] = wv } r.managedKinds.ReplaceRegistrarRoster(r, roster) - return r.mgr.replaceWatches(r) + return r.mgr.replaceWatches(ctx, r) } // RemoveWatch removes a watch for the given kind. // Ignores the request if the kind was not previously watched. -func (r *Registrar) RemoveWatch(gvk schema.GroupVersionKind) error { +func (r *Registrar) RemoveWatch(ctx context.Context, gvk schema.GroupVersionKind) error { r.mux.Lock() defer r.mux.Unlock() r.managedKinds.Remove(r.parentName, gvk) - return r.mgr.removeWatch(r, gvk) + return r.mgr.removeWatch(ctx, r, gvk) } // IfWatching executes the passed function if the provided GVK is being watched diff --git a/pkg/watch/stats_reporter.go b/pkg/watch/stats_reporter.go index be4c25fe3b8..baa60da2526 100644 --- a/pkg/watch/stats_reporter.go +++ b/pkg/watch/stats_reporter.go @@ -3,7 +3,7 @@ package watch import ( "context" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/webhook/common.go b/pkg/webhook/common.go index 63f255b1519..0d7dc24b272 100644 --- a/pkg/webhook/common.go +++ b/pkg/webhook/common.go @@ -8,11 +8,11 @@ import ( "fmt" "strings" - "github.com/open-policy-agent/gatekeeper/apis" - "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/keys" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/apis" + "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/keys" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -21,7 +21,6 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -38,13 +37,6 @@ const ( var log = logf.Log.WithName("webhook") -var ( - // VwhName is the metadata.name of the Gatekeeper ValidatingWebhookConfiguration. - VwhName = "gatekeeper-validating-webhook-configuration" - // MwhName is the metadata.name of the Gatekeeper MutatingWebhookConfiguration. - MwhName = "gatekeeper-mutating-webhook-configuration" -) - const ( serviceAccountName = "gatekeeper-admin" mutationsGroup = "mutations.gatekeeper.sh" @@ -58,12 +50,16 @@ var ( deserializer = codecs.UniversalDeserializer() disableEnforcementActionValidation = flag.Bool("disable-enforcementaction-validation", false, "disable validation of the enforcementAction field of a constraint") logDenies = flag.Bool("log-denies", false, "log detailed info on each deny") - emitAdmissionEvents = flag.Bool("emit-admission-events", false, "(alpha) emit Kubernetes events in gatekeeper namespace for each admission violation") - tlsMinVersion = flag.String("tls-min-version", "1.3", "minimum version of TLS supported") + emitAdmissionEvents = flag.Bool("emit-admission-events", false, "(alpha) emit Kubernetes events for each admission violation") + admissionEventsInvolvedNamespace = flag.Bool("admission-events-involved-namespace", false, "emit admission events for each violation in the involved objects namespace, the default (false) generates events in the namespace Gatekeeper is installed in. Admission events from cluster-scoped resources will still follow the default behavior") + logStatsAdmission = flag.Bool("log-stats-admission", false, "(alpha) log stats for admission webhook") + tlsMinVersion = flag.String("tls-min-version", "1.2", "minimum version of TLS supported") serviceaccount = fmt.Sprintf("system:serviceaccount:%s:%s", util.GetNamespace(), serviceAccountName) - clientCAName = flag.String("client-ca-name", "", "name of the certificate authority bundle to authenticate the Kubernetes API server requests against") - certCNName = flag.String("client-cn-name", "kube-apiserver", "expected CN name on the client certificate attached by apiserver in requests to the webhook") - // webhookName is deprecated, set this on the manifest YAML if needed". + VwhName = flag.String("validating-webhook-configuration-name", "gatekeeper-validating-webhook-configuration", "name of the ValidatingWebhookConfiguration") + MwhName = flag.String("mutating-webhook-configuration-name", "gatekeeper-mutating-webhook-configuration", "name of the MutatingWebhookConfiguration") + TLSMinVersion = flag.String("tls-min-version", "1.3", "minimum version of TLS supported") + ClientCAName = flag.String("client-ca-name", "", "name of the certificate authority bundle to authenticate the Kubernetes API server requests against") + CertCNName = flag.String("client-cn-name", "kube-apiserver", "expected CN name on the client certificate attached by apiserver in requests to the webhook") ) func init() { @@ -149,24 +145,11 @@ func (h *webhookHandler) skipExcludedNamespace(req *admissionv1.AdmissionRequest return isNamespaceExcluded, err } -func congifureWebhookServer(server *webhook.Server) *webhook.Server { - server.TLSMinVersion = *tlsMinVersion - if *clientCAName != "" { - server.ClientCAName = *clientCAName - server.TLSOpts = []func(*tls.Config){ - func(cfg *tls.Config) { - cfg.VerifyConnection = getCertNameVerifier() - }, - } - } - return server -} - -func getCertNameVerifier() func(cs tls.ConnectionState) error { +func GetCertNameVerifier() func(cs tls.ConnectionState) error { return func(cs tls.ConnectionState) error { if len(cs.PeerCertificates) > 0 { - if cs.PeerCertificates[0].Subject.CommonName != *certCNName { - return fmt.Errorf("x509: subject with cn=%s do not identify as %s", cs.PeerCertificates[0].Subject.CommonName, *certCNName) + if cs.PeerCertificates[0].Subject.CommonName != *CertCNName { + return fmt.Errorf("x509: subject with cn=%s do not identify as %s", cs.PeerCertificates[0].Subject.CommonName, *CertCNName) } return nil } diff --git a/pkg/webhook/common_test.go b/pkg/webhook/common_test.go index c80e21e93cf..1d7ebc5b2ca 100644 --- a/pkg/webhook/common_test.go +++ b/pkg/webhook/common_test.go @@ -33,7 +33,7 @@ func (w chanWriter) Write(p []byte) (n int, err error) { func TestCongifureWebhookServer(t *testing.T) { expectedServer := &webhook.Server{ - TLSMinVersion: "1.3", + TLSMinVersion: "1.2", } if *clientCAName != "" { @@ -65,7 +65,7 @@ func TestCongifureWebhookServer(t *testing.T) { } func TestTLSConfig(t *testing.T) { - ca, caPEM, caPrivKey, err := getCA(*certCNName) + ca, caPEM, caPrivKey, err := getCA(*CertCNName) if err != nil { t.Fatal(err) } @@ -73,7 +73,7 @@ func TestTLSConfig(t *testing.T) { certpool := x509.NewCertPool() certpool.AppendCertsFromPEM(caPEM.Bytes()) - serverTLSConf, err := serverCertSetup(*certCNName, ca, caPrivKey, certpool) + serverTLSConf, err := serverCertSetup(*CertCNName, ca, caPrivKey, certpool) if err != nil { t.Fatal(err) } @@ -87,7 +87,7 @@ func TestTLSConfig(t *testing.T) { ts.StartTLS() defer ts.Close() - goodHTTPClient, err := getClient(*certCNName, ca, caPrivKey, certpool) + goodHTTPClient, err := getClient(*CertCNName, ca, caPrivKey, certpool) if err != nil { t.Fatal(err) } @@ -97,7 +97,7 @@ func TestTLSConfig(t *testing.T) { t.Fatal(err) } - diffCa, diffCaPEM, diffCaPrivKey, err := getCA(*certCNName) + diffCa, diffCaPEM, diffCaPrivKey, err := getCA(*CertCNName) if err != nil { t.Fatal(err) } @@ -105,7 +105,7 @@ func TestTLSConfig(t *testing.T) { diffCertpool := x509.NewCertPool() diffCertpool.AppendCertsFromPEM(diffCaPEM.Bytes()) - diffHTTPClient, err := getClient(*certCNName, diffCa, diffCaPrivKey, diffCertpool) + diffHTTPClient, err := getClient(*CertCNName, diffCa, diffCaPrivKey, diffCertpool) if err != nil { t.Fatal(err) } @@ -160,8 +160,8 @@ func TestTLSConfig(t *testing.T) { select { case v := <-errc: - if !strings.Contains(v, fmt.Sprintf("x509: subject with cn=test do not identify as %s", *certCNName)) { - t.Errorf("expected an error log message containing '%s'; got %q", fmt.Sprintf("x509: subject with cn=test do not identify as %s", *certCNName), v) + if !strings.Contains(v, fmt.Sprintf("x509: subject with cn=test do not identify as %s", *CertCNName)) { + t.Errorf("expected an error log message containing '%s'; got %q", fmt.Sprintf("x509: subject with cn=test do not identify as %s", *CertCNName), v) } case <-time.After(5 * time.Second): t.Errorf("timeout waiting for logged error") @@ -269,7 +269,7 @@ func serverCertSetup(s string, ca *x509.Certificate, caPrivKey *rsa.PrivateKey, serverTLSConf = &tls.Config{ Certificates: []tls.Certificate{serverCert}, - VerifyConnection: getCertNameVerifier(), + VerifyConnection: GetCertNameVerifier(), ClientCAs: certPool, ClientAuth: tls.RequireAndVerifyClientCert, MinVersion: tls.VersionTLS13, diff --git a/pkg/webhook/health_check.go b/pkg/webhook/health_check.go index b0dd29f2c71..e0960f681dd 100644 --- a/pkg/webhook/health_check.go +++ b/pkg/webhook/health_check.go @@ -4,23 +4,27 @@ import ( "bytes" "crypto/tls" "fmt" + "io" "net/http" "path/filepath" logf "sigs.k8s.io/controller-runtime/pkg/log" ) -// disabling gosec linting here as the http client used in this checking is intended to skip CA verification -// -//nolint:gosec -var tr = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, -} -var insecureClient = &http.Client{Transport: tr} - var tlsCheckerLog = logf.Log.WithName("webhook-tls-checker") func NewTLSChecker(certDir string, port int) func(*http.Request) error { + //nolint:forcetypeassert + tr := http.DefaultTransport.(*http.Transport).Clone() + // disabling gosec linting here as the http client used in this checking is intended to skip CA verification + // + //nolint:gosec + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + // disable keep alives to ensure that http connection aren't reused, otherwise the check may + // fail if the cert was rotated in between + tr.DisableKeepAlives = true + insecureClient := &http.Client{Transport: tr} + returnFunc := func(_ *http.Request) error { resp, err := insecureClient.Get(fmt.Sprintf("https://127.0.0.1:%d", port)) if err != nil { @@ -28,6 +32,10 @@ func NewTLSChecker(certDir string, port int) func(*http.Request) error { tlsCheckerLog.Error(newErr, "error in connecting to webhook server with https") return newErr } + defer resp.Body.Close() + // explicitly discard the body to avoid any memory leak + _, _ = io.Copy(io.Discard, resp.Body) + if len(resp.TLS.PeerCertificates) == 0 { newErr := fmt.Errorf("webhook does not serve TLS certificate") tlsCheckerLog.Error(newErr, "error in connecting to webhook server with https") diff --git a/pkg/webhook/mutation.go b/pkg/webhook/mutation.go index f1ead452a6d..91a07fb6973 100644 --- a/pkg/webhook/mutation.go +++ b/pkg/webhook/mutation.go @@ -18,13 +18,14 @@ import ( "net/http" "time" + "github.com/go-logr/logr" "github.com/open-policy-agent/cert-controller/pkg/rotator" - "github.com/open-policy-agent/gatekeeper/apis" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/apis" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -63,6 +64,7 @@ func AddMutatingWebhook(mgr manager.Manager, deps Dependencies) error { eventBroadcaster := record.NewBroadcaster() kubeClient := kubernetes.NewForConfigOrDie(mgr.GetConfig()) + log := log.WithValues("hookType", "mutation") eventBroadcaster.StartRecordingToSink(&clientcorev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")}) recorder := eventBroadcaster.NewRecorder( scheme.Scheme, @@ -80,15 +82,11 @@ func AddMutatingWebhook(mgr manager.Manager, deps Dependencies) error { }, mutationSystem: deps.MutationSystem, deserializer: codecs.UniversalDeserializer(), + log: log, }, } - // TODO(https://github.com/open-policy-agent/gatekeeper/issues/661): remove log injection if the race condition in the cited bug is eliminated. - // Otherwise we risk having unstable logger names for the webhook. - if err := wh.InjectLogger(log); err != nil { - return err - } - congifureWebhookServer(mgr.GetWebhookServer()).Register("/v1/mutate", wh) + mgr.GetWebhookServer().Register("/v1/mutate", wh) return nil } @@ -99,12 +97,12 @@ type mutationHandler struct { webhookHandler mutationSystem *mutation.System deserializer runtime.Decoder + log logr.Logger } // Handle the mutation request // nolint: gocritic // Must accept admission.Request to satisfy interface. func (h *mutationHandler) Handle(ctx context.Context, req admission.Request) admission.Response { - log := log.WithValues("hookType", "mutation") timeStart := time.Now() if isGkServiceAccount(req.AdmissionRequest.UserInfo) { @@ -124,7 +122,7 @@ func (h *mutationHandler) Handle(ctx context.Context, req admission.Request) adm defer func() { if h.reporter != nil { if err := h.reporter.ReportMutationRequest(ctx, requestResponse, time.Since(timeStart)); err != nil { - log.Error(err, "failed to report request") + h.log.Error(err, "failed to report request") } } }() @@ -132,7 +130,7 @@ func (h *mutationHandler) Handle(ctx context.Context, req admission.Request) adm // namespace is excluded from webhook using config isExcludedNamespace, err := h.skipExcludedNamespace(&req.AdmissionRequest, process.Mutation) if err != nil { - log.Error(err, "error while excluding namespace") + h.log.Error(err, "error while excluding namespace") } if isExcludedNamespace { @@ -164,13 +162,13 @@ func (h *mutationHandler) mutateRequest(ctx context.Context, req *admission.Requ case req.AdmissionRequest.Namespace != "": if err := h.client.Get(ctx, types.NamespacedName{Name: req.AdmissionRequest.Namespace}, ns); err != nil { if !k8serrors.IsNotFound(err) { - log.Error(err, "error retrieving namespace", "name", req.AdmissionRequest.Namespace) + h.log.Error(err, "error retrieving namespace", "name", req.AdmissionRequest.Namespace) return admission.Errored(int32(http.StatusInternalServerError), err) } // bypass cached client and ask api-server directly err = h.reader.Get(ctx, types.NamespacedName{Name: req.AdmissionRequest.Namespace}, ns) if err != nil { - log.Error(err, "error retrieving namespace from API server", "name", req.AdmissionRequest.Namespace) + h.log.Error(err, "error retrieving namespace from API server", "name", req.AdmissionRequest.Namespace) return admission.Errored(int32(http.StatusInternalServerError), err) } } @@ -180,7 +178,7 @@ func (h *mutationHandler) mutateRequest(ctx context.Context, req *admission.Requ obj := unstructured.Unstructured{} err := obj.UnmarshalJSON(req.Object.Raw) if err != nil { - log.Error(err, "failed to unmarshal", "object", string(req.Object.Raw)) + h.log.Error(err, "failed to unmarshal", "object", string(req.Object.Raw)) return admission.Errored(int32(http.StatusInternalServerError), err) } @@ -198,7 +196,7 @@ func (h *mutationHandler) mutateRequest(ctx context.Context, req *admission.Requ } mutated, err := h.mutationSystem.Mutate(mutable) if err != nil { - log.Error(err, "failed to mutate object", "object", string(req.Object.Raw)) + h.log.Error(err, "failed to mutate object", "object", string(req.Object.Raw)) return admission.Errored(int32(http.StatusInternalServerError), err) } if !mutated { @@ -209,7 +207,7 @@ func (h *mutationHandler) mutateRequest(ctx context.Context, req *admission.Requ newJSON, err := mutable.Object.MarshalJSON() if err != nil { - log.Error(err, "failed to marshal mutated object", "object", obj) + h.log.Error(err, "failed to marshal mutated object", "object", obj) return admission.Errored(int32(http.StatusInternalServerError), err) } resp := admission.PatchResponseFromRaw(req.Object.Raw, newJSON) @@ -219,7 +217,7 @@ func (h *mutationHandler) mutateRequest(ctx context.Context, req *admission.Requ func AppendMutationWebhookIfEnabled(webhooks []rotator.WebhookInfo) []rotator.WebhookInfo { if operations.IsAssigned(operations.MutationWebhook) { return append(webhooks, rotator.WebhookInfo{ - Name: MwhName, + Name: *MwhName, Type: rotator.Mutating, }) } diff --git a/pkg/webhook/mutation_test.go b/pkg/webhook/mutation_test.go index 86a0ef9ad9d..de25e294478 100644 --- a/pkg/webhook/mutation_test.go +++ b/pkg/webhook/mutation_test.go @@ -5,15 +5,15 @@ import ( "reflect" "testing" - configv1alpha1 "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/match" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assign" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assignmeta" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" + configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/match" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignmeta" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -64,6 +64,7 @@ func TestWebhookAssign(t *testing.T) { }, mutationSystem: sys, deserializer: codecs.UniversalDeserializer(), + log: log, } raw := []byte(`{"apiVersion": "v1", "kind": "Pod", "metadata": {"name": "acbd","namespace": "ns1"}}`) @@ -130,6 +131,7 @@ func TestWebhookAssignMetadata(t *testing.T) { }, mutationSystem: sys, deserializer: codecs.UniversalDeserializer(), + log: log, } raw := []byte(`{"apiVersion": "v1", "kind": "Pod", "metadata": {"name": "acbd","namespace": "ns1"}}`) diff --git a/pkg/webhook/mutator_validation_test.go b/pkg/webhook/mutator_validation_test.go index 7a4a4cf3724..ac222cf8402 100644 --- a/pkg/webhook/mutator_validation_test.go +++ b/pkg/webhook/mutator_validation_test.go @@ -4,11 +4,11 @@ import ( "context" "testing" - "github.com/ghodss/yaml" admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" atypes "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/yaml" ) func TestAssignMetaValidation(t *testing.T) { @@ -97,7 +97,7 @@ spec: } for _, tt := range tc { t.Run(tt.Name, func(t *testing.T) { - handler := validationHandler{webhookHandler: webhookHandler{}} + handler := validationHandler{webhookHandler: webhookHandler{}, log: log} b, err := yaml.YAMLToJSON([]byte(tt.AssignMeta)) if err != nil { t.Fatalf("Error parsing yaml: %s", err) @@ -348,7 +348,7 @@ spec: } for _, tt := range tc { t.Run(tt.Name, func(t *testing.T) { - handler := validationHandler{webhookHandler: webhookHandler{}} + handler := validationHandler{webhookHandler: webhookHandler{}, log: log} b, err := yaml.YAMLToJSON([]byte(tt.Assign)) if err != nil { t.Fatalf("Error parsing yaml: %s", err) diff --git a/pkg/webhook/namespacelabel.go b/pkg/webhook/namespacelabel.go index 20d5d2fc13b..e63745b1ab8 100644 --- a/pkg/webhook/namespacelabel.go +++ b/pkg/webhook/namespacelabel.go @@ -8,7 +8,7 @@ import ( "net/http" "strings" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "github.com/pkg/errors" admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -19,12 +19,14 @@ import ( var ( exemptNamespace = util.NewFlagSet() exemptNamespacePrefix = util.NewFlagSet() + exemptNamespaceSuffix = util.NewFlagSet() ) func init() { AddToManagerFuncs = append(AddToManagerFuncs, AddLabelWebhook) flag.Var(exemptNamespace, "exempt-namespace", "The specified namespace is allowed to set the admission.gatekeeper.sh/ignore label. To exempt multiple namespaces, this flag can be declared more than once.") flag.Var(exemptNamespacePrefix, "exempt-namespace-prefix", "A namespace with the specified prefix is allowed to set the admission.gatekeeper.sh/ignore label. To exempt multiple prefixes, this flag can be declared more than once.") + flag.Var(exemptNamespaceSuffix, "exempt-namespace-suffix", "A namespace with the specified suffix is allowed to set the admission.gatekeeper.sh/ignore label. To exempt multiple suffixes, this flag can be declared more than once.") } const ignoreLabel = "admission.gatekeeper.sh/ignore" @@ -34,12 +36,7 @@ const ignoreLabel = "admission.gatekeeper.sh/ignore" // AddLabelWebhook registers the label webhook server with the manager. func AddLabelWebhook(mgr manager.Manager, _ Dependencies) error { wh := &admission.Webhook{Handler: &namespaceLabelHandler{}} - // TODO(https://github.com/open-policy-agent/gatekeeper/issues/661): remove log injection if the race condition in the cited bug is eliminated. - // Otherwise we risk having unstable logger names for the webhook. - if err := wh.InjectLogger(log); err != nil { - return err - } - congifureWebhookServer(mgr.GetWebhookServer()).Register("/v1/admitlabel", wh) + mgr.GetWebhookServer().Register("/v1/admitlabel", wh) return nil } @@ -47,7 +44,7 @@ var _ admission.Handler = &namespaceLabelHandler{} type namespaceLabelHandler struct{} -// nolint: gocritic // Must accept admission.Request as a struct to satisfy Handler interface. +//nolint:gocritic // Must accept admission.Request as a struct to satisfy Handler interface. func (h *namespaceLabelHandler) Handle(ctx context.Context, req admission.Request) admission.Response { if req.Operation == admissionv1.Delete { return admission.Allowed("Delete is always allowed") @@ -61,7 +58,7 @@ func (h *namespaceLabelHandler) Handle(ctx context.Context, req admission.Reques r.Result.Code = http.StatusInternalServerError return r } - if exemptNamespace[obj.GetName()] || matchesPrefix(obj.GetName()) { + if exemptNamespace[obj.GetName()] || matchesPrefix(obj.GetName()) || matchesSuffix(obj.GetName()) { return admission.Allowed(fmt.Sprintf("Namespace %s is allowed to set %s", obj.GetName(), ignoreLabel)) } for label := range obj.GetLabels() { @@ -80,3 +77,12 @@ func matchesPrefix(s string) bool { } return false } + +func matchesSuffix(s string) bool { + for p := range exemptNamespaceSuffix { + if strings.HasSuffix(s, p) { + return true + } + } + return false +} diff --git a/pkg/webhook/namespacelabel_test.go b/pkg/webhook/namespacelabel_test.go index 967804b4d83..75381516c2e 100644 --- a/pkg/webhook/namespacelabel_test.go +++ b/pkg/webhook/namespacelabel_test.go @@ -139,6 +139,10 @@ func TestAdmission(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Cleanup(func() { + exemptNamespace = nil + }) + exemptNamespace = map[string]bool{"random-allowed-ns": true} gvk := tt.obj.GetObjectKind() gvk.SetGroupVersionKind(schema.GroupVersionKind{Group: tt.kind.Group, Version: tt.kind.Version, Kind: tt.kind.Kind}) @@ -226,6 +230,10 @@ func TestAdmissionPrefix(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Cleanup(func() { + exemptNamespacePrefix = nil + }) + exemptNamespacePrefix = map[string]bool{} for _, p := range tt.prefixes { exemptNamespacePrefix[p] = true @@ -252,6 +260,100 @@ func TestAdmissionPrefix(t *testing.T) { } } +func TestAdmissionSuffix(t *testing.T) { + tests := []struct { + name string + suffixes []string + kind metav1.GroupVersionKind + obj client.Object + op admissionv1.Operation + expectAllowed bool + }{ + { + name: "Exempt Namespace create allowed", + suffixes: []string{"-random"}, + kind: gvk("", "v1", "Namespace"), + obj: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allowed-ns-random", + Labels: map[string]string{ignoreLabel: "true"}, + }, + }, + op: admissionv1.Create, + expectAllowed: true, + }, + { + name: "Exempt Namespace update allowed", + suffixes: []string{"-random"}, + kind: gvk("", "v1", "Namespace"), + obj: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allowed-ns-random", + Labels: map[string]string{ignoreLabel: "true"}, + }, + }, + op: admissionv1.Update, + expectAllowed: true, + }, + { + name: "Exempt Namespace delete allowed", + suffixes: []string{"-random"}, + kind: gvk("", "v1", "Namespace"), + obj: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allowed-ns-random", + Labels: map[string]string{ignoreLabel: "true"}, + }, + }, + op: admissionv1.Delete, + expectAllowed: true, + }, + { + name: "Bad Namespace create rejected", + suffixes: []string{"-random"}, + kind: gvk("", "v1", "Namespace"), + obj: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "random-namespace-wrongsuffix", + Labels: map[string]string{ignoreLabel: "true"}, + }, + }, + op: admissionv1.Create, + expectAllowed: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Cleanup(func() { + exemptNamespaceSuffix = nil + }) + + exemptNamespaceSuffix = map[string]bool{} + for _, p := range tt.suffixes { + exemptNamespaceSuffix[p] = true + } + gvk := tt.obj.GetObjectKind() + gvk.SetGroupVersionKind(schema.GroupVersionKind{Group: tt.kind.Group, Version: tt.kind.Version, Kind: tt.kind.Kind}) + bytes, err := json.Marshal(tt.obj) + if err != nil { + t.Fatal(err) + } + req := admission.Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Kind: tt.kind, + Object: runtime.RawExtension{Raw: bytes}, + Operation: tt.op, + }, + } + handler := &namespaceLabelHandler{} + resp := handler.Handle(context.Background(), req) + if resp.Allowed != tt.expectAllowed { + t.Errorf("resp.Allowed = %v, expected %v. Reason: %s", resp.Allowed, tt.expectAllowed, resp.Result.Reason) + } + }) + } +} + func TestBadSerialization(t *testing.T) { req := admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ diff --git a/pkg/webhook/policy.go b/pkg/webhook/policy.go index 95663e692e1..be6830957a2 100644 --- a/pkg/webhook/policy.go +++ b/pkg/webhook/policy.go @@ -25,28 +25,31 @@ import ( "strings" "time" + "github.com/go-logr/logr" "github.com/open-policy-agent/cert-controller/pkg/rotator" externaldataUnversioned "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" rtypes "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/apis" - mutationsunversioned "github.com/open-policy-agent/gatekeeper/apis/mutations/unversioned" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/keys" - "github.com/open-policy-agent/gatekeeper/pkg/logging" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assign" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/assignmeta" - "github.com/open-policy-agent/gatekeeper/pkg/mutation/mutators/modifyset" - mutationtypes "github.com/open-policy-agent/gatekeeper/pkg/mutation/types" - "github.com/open-policy-agent/gatekeeper/pkg/operations" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" + "github.com/open-policy-agent/gatekeeper/v3/apis" + expansionunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/expansion/unversioned" + mutationsunversioned "github.com/open-policy-agent/gatekeeper/v3/apis/mutations/unversioned" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/keys" + "github.com/open-policy-agent/gatekeeper/v3/pkg/logging" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignimage" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignmeta" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/modifyset" + mutationtypes "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/types" + "github.com/open-policy-agent/gatekeeper/v3/pkg/operations" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/util" admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -66,7 +69,10 @@ import ( // https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#response const httpStatusWarning = 299 -var maxServingThreads = flag.Int("max-serving-threads", -1, "cap the number of threads handling non-trivial requests, -1 caps the number of threads to GOMAXPROCS. Defaults to -1.") +var ( + ValidateTemplateRego = flag.Bool("validate-template-rego", true, "validate Rego code for constraint templates. Defaults to true. This flag will be removed in Gatekeeper v3.16 and cannot be used if `experimental-enable-k8s-native-validation` flag is set. Use Gator to validate in shift left manner to avoid impact with this behavior change.). Use Gator to validate in shift left manner to avoid impact with this behavior change.") + maxServingThreads = flag.Int("max-serving-threads", -1, "cap the number of threads handling non-trivial requests, -1 caps the number of threads to GOMAXPROCS. Defaults to -1.") +) func init() { AddToManagerFuncs = append(AddToManagerFuncs, AddPolicyWebhook) @@ -90,6 +96,7 @@ func AddPolicyWebhook(mgr manager.Manager, deps Dependencies) error { if err != nil { return err } + log := log.WithValues("hookType", "validation") eventBroadcaster := record.NewBroadcaster() kubeClient := kubernetes.NewForConfigOrDie(mgr.GetConfig()) eventBroadcaster.StartRecordingToSink(&clientcorev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")}) @@ -108,6 +115,7 @@ func AddPolicyWebhook(mgr manager.Manager, deps Dependencies) error { eventRecorder: recorder, gkNamespace: util.GetNamespace(), }, + log: log, } threadCount := *maxServingThreads if threadCount < 1 { @@ -115,12 +123,7 @@ func AddPolicyWebhook(mgr manager.Manager, deps Dependencies) error { } handler.semaphore = make(chan struct{}, threadCount) wh := &admission.Webhook{Handler: handler} - // TODO(https://github.com/open-policy-agent/gatekeeper/issues/661): remove log injection if the race condition in the cited bug is eliminated. - // Otherwise we risk having unstable logger names for the webhook. - if err := wh.InjectLogger(log); err != nil { - return err - } - congifureWebhookServer(mgr.GetWebhookServer()).Register("/v1/admit", wh) + mgr.GetWebhookServer().Register("/v1/admit", wh) return nil } @@ -132,13 +135,12 @@ type validationHandler struct { mutationSystem *mutation.System expansionSystem *expansion.System semaphore chan struct{} + log logr.Logger } // Handle the validation request // nolint: gocritic // Must accept admission.Request as a struct to satisfy Handler interface. func (h *validationHandler) Handle(ctx context.Context, req admission.Request) admission.Response { - log := log.WithValues("hookType", "validation") - timeStart := time.Now() if isGkServiceAccount(req.AdmissionRequest.UserInfo) { @@ -169,7 +171,7 @@ func (h *validationHandler) Handle(ctx context.Context, req admission.Request) a isDryRun = "true" } if err := h.reporter.ReportValidationRequest(ctx, requestResponse, isDryRun, time.Since(timeStart)); err != nil { - log.Error(err, "failed to report request") + h.log.Error(err, "failed to report request") } } }() @@ -177,7 +179,7 @@ func (h *validationHandler) Handle(ctx context.Context, req admission.Request) a // namespace is excluded from webhook using config isExcludedNamespace, err := h.skipExcludedNamespace(&req.AdmissionRequest, process.Webhook) if err != nil { - log.Error(err, "error while excluding namespace") + h.log.Error(err, "error while excluding namespace") } if isExcludedNamespace { @@ -187,11 +189,27 @@ func (h *validationHandler) Handle(ctx context.Context, req admission.Request) a resp, err := h.reviewRequest(ctx, &req) if err != nil { - log.Error(err, "error executing query") + h.log.Error(err, "error executing query") requestResponse = errorResponse return admission.Errored(http.StatusInternalServerError, err) } + if *logStatsAdmission { + logging.LogStatsEntries( + h.opa, + h.log.WithValues( + logging.Process, "admission", + logging.EventType, "review_response_stats", + logging.ResourceGroup, req.AdmissionRequest.Kind.Group, + logging.ResourceAPIVersion, req.AdmissionRequest.Kind.Version, + logging.ResourceKind, req.AdmissionRequest.Kind.Kind, + logging.ResourceNamespace, req.AdmissionRequest.Namespace, + logging.RequestUsername, req.AdmissionRequest.UserInfo.Username, + ), + resp.StatsEntries, "admission review request stats", + ) + } + res := resp.Results() denyMsgs, warnMsgs := h.getValidationMessages(res, &req) @@ -229,14 +247,17 @@ func (h *validationHandler) Handle(ctx context.Context, req admission.Request) a func (h *validationHandler) getValidationMessages(res []*rtypes.Result, req *admission.Request) ([]string, []string) { var denyMsgs, warnMsgs []string var resourceName string + obj := &unstructured.Unstructured{} + if len(res) > 0 && (*logDenies || *emitAdmissionEvents) { resourceName = req.AdmissionRequest.Name - if len(resourceName) == 0 && req.AdmissionRequest.Object.Raw != nil { - // On a CREATE operation, the client may omit name and - // rely on the server to generate the name. - obj := &unstructured.Unstructured{} + if req.AdmissionRequest.Object.Raw != nil { if _, _, err := deserializer.Decode(req.AdmissionRequest.Object.Raw, nil, obj); err == nil { - resourceName = obj.GetName() + // On a CREATE operation, the client may omit name and + // rely on the server to generate the name. + if len(resourceName) == 0 { + resourceName = obj.GetName() + } } } } @@ -245,8 +266,9 @@ func (h *validationHandler) getValidationMessages(res []*rtypes.Result, req *adm continue } if *logDenies { - log.WithValues( + h.log.WithValues( logging.Process, "admission", + logging.Details, r.Metadata["details"], logging.EventType, "violation", logging.ConstraintName, r.Constraint.GetName(), logging.ConstraintGroup, r.Constraint.GroupVersionKind().Group, @@ -259,7 +281,8 @@ func (h *validationHandler) getValidationMessages(res []*rtypes.Result, req *adm logging.ResourceNamespace, req.AdmissionRequest.Namespace, logging.ResourceName, resourceName, logging.RequestUsername, req.AdmissionRequest.UserInfo.Username, - ).Info(fmt.Sprintf("denied admission: %s", r.Msg)) + ).Info( + fmt.Sprintf("denied admission: %s", r.Msg)) } if *emitAdmissionEvents { annotations := map[string]string{ @@ -289,24 +312,14 @@ func (h *validationHandler) getValidationMessages(res []*rtypes.Result, req *adm eventMsg = "Admission webhook \"validation.gatekeeper.sh\" denied request" reason = "FailedAdmission" } - ref := getViolationRef( - h.gkNamespace, - req.AdmissionRequest.Kind.Kind, - resourceName, - req.AdmissionRequest.Namespace, - r.Constraint.GetKind(), - r.Constraint.GetName(), - r.Constraint.GetNamespace()) - h.eventRecorder.AnnotatedEventf( - ref, - annotations, - corev1.EventTypeWarning, - reason, - "%s, Resource Namespace: %s, Constraint: %s, Message: %s", - eventMsg, - req.AdmissionRequest.Namespace, - r.Constraint.GetName(), - r.Msg) + + ref := getViolationRef(h.gkNamespace, req.AdmissionRequest.Kind.Kind, resourceName, obj.GetNamespace(), obj.GetResourceVersion(), obj.GetUID(), r.Constraint.GetKind(), r.Constraint.GetName(), r.Constraint.GetNamespace(), *admissionEventsInvolvedNamespace) + + if *admissionEventsInvolvedNamespace { + h.eventRecorder.AnnotatedEventf(ref, annotations, corev1.EventTypeWarning, reason, "%s, Constraint: %s, Message: %s", eventMsg, r.Constraint.GetName(), r.Msg) + } else { + h.eventRecorder.AnnotatedEventf(ref, annotations, corev1.EventTypeWarning, reason, "%s, Resource Namespace: %s, Constraint: %s, Message: %s", eventMsg, req.AdmissionRequest.Namespace, r.Constraint.GetName(), r.Msg) + } } if r.EnforcementAction == string(util.Deny) { @@ -328,6 +341,8 @@ func (h *validationHandler) validateGatekeeperResources(ctx context.Context, req switch { case gvk.Group == "templates.gatekeeper.sh" && gvk.Kind == "ConstraintTemplate": return h.validateTemplate(ctx, req) + case gvk.Group == "expansion.gatekeeper.sh" && gvk.Kind == "ExpansionTemplate": + return h.validateExpansionTemplate(req) case gvk.Group == "constraints.gatekeeper.sh": return h.validateConstraint(req) case gvk.Group == "config.gatekeeper.sh" && gvk.Kind == "Config": @@ -340,6 +355,8 @@ func (h *validationHandler) validateGatekeeperResources(ctx context.Context, req return h.validateAssign(req) case req.AdmissionRequest.Kind.Group == mutationsGroup && req.AdmissionRequest.Kind.Kind == "ModifySet": return h.validateModifySet(req) + case req.AdmissionRequest.Kind.Group == mutationsGroup && req.AdmissionRequest.Kind.Kind == "AssignImage": + return h.validateAssignImage(req) case req.AdmissionRequest.Kind.Group == externalDataGroup && req.AdmissionRequest.Kind.Kind == "Provider": return h.validateProvider(req) } @@ -369,16 +386,19 @@ func (h *validationHandler) validateTemplate(ctx context.Context, req *admission return true, err } - // Create a temporary Driver and attempt to add the Template to it. This - // ensures the Rego code both parses and compiles. - d, err := local.New() - if err != nil { - return false, fmt.Errorf("unable to create Driver: %v", err) - } + // TODO: This is a temporary check for rego to give enough time to users to migrate to gator for validation. To be removed before 3.16. + if *ValidateTemplateRego { + // Create a temporary Driver and attempt to add the Template to it. This + // ensures the Rego code both parses and compiles. + d, err := rego.New() + if err != nil { + return false, fmt.Errorf("unable to create Driver: %w", err) + } - err = d.AddTemplate(ctx, unversioned) - if err != nil { - return true, err + err = d.AddTemplate(ctx, unversioned) + if err != nil { + return true, err + } } return false, nil @@ -411,6 +431,23 @@ func (h *validationHandler) validateConstraint(req *admission.Request) (bool, er return false, nil } +func (h *validationHandler) validateExpansionTemplate(req *admission.Request) (bool, error) { + obj, _, err := deserializer.Decode(req.AdmissionRequest.Object.Raw, nil, nil) + if err != nil { + return false, err + } + unversioned := &expansionunversioned.ExpansionTemplate{} + if err := runtimeScheme.Convert(obj, unversioned, nil); err != nil { + return false, err + } + err = expansion.ValidateTemplate(unversioned) + if err != nil { + return true, err + } + + return false, nil +} + func (h *validationHandler) validateConfigResource(req *admission.Request) error { if req.Name != keys.Config.Name { return fmt.Errorf("config resource must have name 'config'") @@ -452,6 +489,23 @@ func (h *validationHandler) validateAssign(req *admission.Request) (bool, error) return false, nil } +func (h *validationHandler) validateAssignImage(req *admission.Request) (bool, error) { + obj, _, err := deserializer.Decode(req.AdmissionRequest.Object.Raw, nil, nil) + if err != nil { + return false, err + } + unversioned := &mutationsunversioned.AssignImage{} + if err := runtimeScheme.Convert(obj, unversioned, nil); err != nil { + return false, err + } + err = assignimage.IsValidAssignImage(unversioned) + if err != nil { + return true, err + } + + return false, nil +} + func (h *validationHandler) validateModifySet(req *admission.Request) (bool, error) { obj, _, err := deserializer.Decode(req.AdmissionRequest.Object.Raw, nil, nil) if err != nil { @@ -504,13 +558,13 @@ func (h *validationHandler) reviewRequest(ctx context.Context, req *admission.Re review, err := h.createReviewForRequest(ctx, req) if err != nil { - return nil, fmt.Errorf("failed to create augmentedReview: %s", err) + return nil, fmt.Errorf("failed to create augmentedReview: %w", err) } // Convert the request's generator resource to unstructured for expansion obj := &unstructured.Unstructured{} if _, _, err := deserializer.Decode(req.Object.Raw, nil, obj); err != nil { - return nil, fmt.Errorf("error decoding generator resource %s: %v", req.Name, err) + return nil, fmt.Errorf("error decoding generator resource %s: %w", req.Name, err) } obj.SetNamespace(req.Namespace) obj.SetGroupVersionKind( @@ -529,38 +583,39 @@ func (h *validationHandler) reviewRequest(ctx context.Context, req *admission.Re } resultants, err := h.expansionSystem.Expand(base) if err != nil { - return nil, fmt.Errorf("unable to expand object: %s", err) + return nil, fmt.Errorf("unable to expand object: %w", err) } trace, dump := h.tracingLevel(ctx, req) resp, err := h.review(ctx, review, trace, dump) if err != nil { - return nil, fmt.Errorf("error reviewing resource %s: %s", req.Name, err) + return nil, fmt.Errorf("error reviewing resource %s: %w", req.Name, err) } for _, res := range resultants { resultantResp, err := h.review(ctx, createReviewForResultant(res.Obj, review.Namespace), trace, dump) if err != nil { - return nil, fmt.Errorf("error reviewing resultant resource: %s", err) + return nil, fmt.Errorf("error reviewing resultant resource: %w", err) } expansion.OverrideEnforcementAction(res.EnforcementAction, resultantResp) expansion.AggregateResponses(res.TemplateName, resp, resultantResp) + expansion.AggregateStats(res.TemplateName, resp, resultantResp) } return resp, nil } func (h *validationHandler) review(ctx context.Context, review interface{}, trace bool, dump bool) (*rtypes.Responses, error) { - resp, err := h.opa.Review(ctx, review, drivers.Tracing(trace)) + resp, err := h.opa.Review(ctx, review, drivers.Tracing(trace), drivers.Stats(*logStatsAdmission)) if resp != nil && trace { - log.Info(resp.TraceDump()) + h.log.Info(resp.TraceDump()) } if dump { dump, err := h.opa.Dump(ctx) if err != nil { - log.Error(err, "dump error") + h.log.Error(err, "dump error") } else { - log.Info(dump) + h.log.Info(dump) } } @@ -604,19 +659,29 @@ func createReviewForResultant(obj *unstructured.Unstructured, ns *corev1.Namespa } } -func getViolationRef(gkNamespace, rkind, rname, rnamespace, ckind, cname, cnamespace string) *corev1.ObjectReference { - return &corev1.ObjectReference{ +func getViolationRef(gkNamespace, rkind, rname, rnamespace, rrv string, ruid types.UID, ckind, cname, cnamespace string, emitInvolvedNamespace bool) *corev1.ObjectReference { + enamespace := gkNamespace + if emitInvolvedNamespace && len(rnamespace) > 0 { + enamespace = rnamespace + } + ref := &corev1.ObjectReference{ Kind: rkind, Name: rname, - UID: types.UID(rkind + "/" + rnamespace + "/" + rname + "/" + ckind + "/" + cnamespace + "/" + cname), - Namespace: gkNamespace, + Namespace: enamespace, + } + if emitInvolvedNamespace && len(ruid) > 0 && len(rrv) > 0 { + ref.UID = ruid + ref.ResourceVersion = rrv + } else if !emitInvolvedNamespace { + ref.UID = types.UID(rkind + "/" + rnamespace + "/" + rname + "/" + ckind + "/" + cnamespace + "/" + cname) } + return ref } func AppendValidationWebhookIfEnabled(webhooks []rotator.WebhookInfo) []rotator.WebhookInfo { if operations.IsAssigned(operations.Webhook) { return append(webhooks, rotator.WebhookInfo{ - Name: VwhName, + Name: *VwhName, Type: rotator.Validating, }) } diff --git a/pkg/webhook/policy_benchmark_test.go b/pkg/webhook/policy_benchmark_test.go index d96ac3a4cdd..4100e8f1f1a 100644 --- a/pkg/webhook/policy_benchmark_test.go +++ b/pkg/webhook/policy_benchmark_test.go @@ -24,16 +24,15 @@ import ( "path/filepath" "strconv" "testing" - "time" templv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - testclient "github.com/open-policy-agent/gatekeeper/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + testclient "github.com/open-policy-agent/gatekeeper/v3/test/clients" "github.com/pkg/errors" admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" @@ -42,6 +41,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/uuid" "sigs.k8s.io/controller-runtime/pkg/client" @@ -77,7 +77,19 @@ func getFiles(dir string) ([]string, error) { return filePaths, nil } -func (f *fakeNsGetter) Get(_ context.Context, key client.ObjectKey, obj client.Object) error { +func (f *fakeNsGetter) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return false, nil +} + +func (f *fakeNsGetter) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return schema.GroupVersionKind{}, nil +} + +func (f *fakeNsGetter) SubResource(_ string) client.SubResourceClient { + return nil +} + +func (f *fakeNsGetter) Get(_ context.Context, key client.ObjectKey, obj client.Object, _ ...client.GetOption) error { if ns, ok := obj.(*corev1.Namespace); ok { ns.ObjectMeta = metav1.ObjectMeta{ Name: key.Name, @@ -305,11 +317,9 @@ func BenchmarkValidationHandler(b *testing.B) { client: c, injectedConfig: cfg, }, + log: log, } - // seed random generator - rand.Seed(time.Now().UnixNano()) - // create T templates err = addTemplates(ctx, opaClient, ctList) if err != nil { diff --git a/pkg/webhook/policy_test.go b/pkg/webhook/policy_test.go index 5798554d3d0..d3c87f8ede7 100644 --- a/pkg/webhook/policy_test.go +++ b/pkg/webhook/policy_test.go @@ -2,23 +2,21 @@ package webhook import ( "context" - "encoding/json" "testing" - "github.com/ghodss/yaml" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" rtypes "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/gatekeeper/apis/config/v1alpha1" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" - "github.com/open-policy-agent/gatekeeper/pkg/target" - "github.com/open-policy-agent/gatekeeper/pkg/util" - testclients "github.com/open-policy-agent/gatekeeper/test/clients" + "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + "github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard" + testclients "github.com/open-policy-agent/gatekeeper/v3/test/clients" admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" corev1 "k8s.io/api/core/v1" @@ -29,7 +27,7 @@ import ( k8schema "k8s.io/apimachinery/pkg/runtime/schema" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - atypes "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/yaml" ) const ( @@ -166,12 +164,17 @@ func validRegoTemplate() *templates.ConstraintTemplate { }, Targets: []templates.Target{{ Target: target.Name, - Rego: ` + Code: []templates.Code{{ + Engine: "Rego", + Source: &templates.Anything{ + Value: map[string]interface{}{"rego": ` package goodrego - violation[{"msg": msg}] { - msg := "Maybe this will work?" - }`, +violation[{"msg": msg}] { + msg := "Maybe this will work?" +}`}, + }, + }}, }}, }, } @@ -190,20 +193,9 @@ func validRegoTemplateConstraint() *unstructured.Unstructured { return u } -func invalidRegoTemplate() *templates.ConstraintTemplate { - template := validRegoTemplate() - - template.Spec.Targets[0].Rego = `package badrego - - violation[{"msg": msg}] { - msg := "I'm sure this will work"` - - return template -} - func makeOpaClient() (*constraintclient.Client, error) { t := &target.K8sValidationTarget{} - driver, err := local.New(local.Tracing(false)) + driver, err := rego.New(rego.Tracing(false)) if err != nil { return nil, err } @@ -215,67 +207,23 @@ func makeOpaClient() (*constraintclient.Client, error) { return c, nil } -func TestTemplateValidation(t *testing.T) { - tc := []struct { - Name string - Template *templates.ConstraintTemplate - ErrorExpected bool - }{ - { - Name: "Valid Template", - Template: validRegoTemplate(), - ErrorExpected: false, - }, - { - Name: "Invalid Template", - Template: invalidRegoTemplate(), - ErrorExpected: true, - }, - } - for _, tt := range tc { - t.Run(tt.Name, func(t *testing.T) { - opa, err := makeOpaClient() - if err != nil { - t.Fatalf("Could not initialize OPA: %s", err) - } - handler := validationHandler{opa: opa, webhookHandler: webhookHandler{}} - - b, err := json.Marshal(tt.Template) - if err != nil { - t.Fatalf("Error parsing yaml: %s", err) - } - - review := &atypes.Request{ - AdmissionRequest: admissionv1.AdmissionRequest{ - Kind: metav1.GroupVersionKind{ - Group: "templates.gatekeeper.sh", - Version: "v1beta1", - Kind: "ConstraintTemplate", - }, - Object: runtime.RawExtension{ - Raw: b, - }, - }, - } +type nsGetter struct { + testclients.NoopClient +} - ctx := context.Background() - _, err = handler.validateGatekeeperResources(ctx, review) - if err != nil && !tt.ErrorExpected { - t.Errorf("err = %s; want nil", err) - } +func (f *nsGetter) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return false, nil +} - if err == nil && tt.ErrorExpected { - t.Error("err = nil; want non-nil") - } - }) - } +func (f *nsGetter) GroupVersionKindFor(obj runtime.Object) (k8schema.GroupVersionKind, error) { + return k8schema.GroupVersionKind{}, nil } -type nsGetter struct { - testclients.NoopClient +func (f *nsGetter) SubResource(_ string) ctrlclient.SubResourceClient { + return nil } -func (f *nsGetter) Get(_ context.Context, key ctrlclient.ObjectKey, obj ctrlclient.Object) error { +func (f *nsGetter) Get(_ context.Context, key ctrlclient.ObjectKey, obj ctrlclient.Object, _ ...ctrlclient.GetOption) error { if ns, ok := obj.(*corev1.Namespace); ok { ns.ObjectMeta = metav1.ObjectMeta{ Name: key.Name, @@ -290,7 +238,19 @@ type errorNSGetter struct { testclients.NoopClient } -func (f *errorNSGetter) Get(_ context.Context, key ctrlclient.ObjectKey, _ ctrlclient.Object) error { +func (f *errorNSGetter) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return false, nil +} + +func (f *errorNSGetter) GroupVersionKindFor(obj runtime.Object) (k8schema.GroupVersionKind, error) { + return k8schema.GroupVersionKind{}, nil +} + +func (f *errorNSGetter) SubResource(_ string) ctrlclient.SubResourceClient { + return nil +} + +func (f *errorNSGetter) Get(_ context.Context, key ctrlclient.ObjectKey, _ ctrlclient.Object, _ ...ctrlclient.GetOption) error { return k8serrors.NewNotFound(k8schema.GroupResource{Resource: "namespaces"}, key.Name) } @@ -347,11 +307,12 @@ func TestReviewRequest(t *testing.T) { client: tt.CachedClient, reader: tt.APIReader, }, + log: log, } if maxThreads > 0 { handler.semaphore = make(chan struct{}, maxThreads) } - review := &atypes.Request{ + review := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Kind: metav1.GroupVersionKind{ Group: "", @@ -385,7 +346,7 @@ func TestReviewDefaultNS(t *testing.T) { Spec: v1alpha1.ConfigSpec{ Match: []v1alpha1.MatchEntry{ { - ExcludedNamespaces: []util.Wildcard{"default"}, + ExcludedNamespaces: []wildcard.Wildcard{"default"}, Processes: []string{"*"}, }, }, @@ -419,6 +380,7 @@ func TestReviewDefaultNS(t *testing.T) { reader: &nsGetter{}, processExcluder: pe, }, + log: log, } if maxThreads > 0 { handler.semaphore = make(chan struct{}, maxThreads) @@ -510,12 +472,13 @@ func TestConstraintValidation(t *testing.T) { opa: opa, expansionSystem: expansion.NewSystem(mutation.NewSystem(mutation.SystemOpts{})), webhookHandler: webhookHandler{}, + log: log, } b, err := yaml.YAMLToJSON([]byte(tt.Constraint)) if err != nil { t.Fatalf("Error parsing yaml: %s", err) } - review := &atypes.Request{ + review := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Kind: metav1.GroupVersionKind{ Group: "constraints.gatekeeper.sh", @@ -637,12 +600,13 @@ func TestTracing(t *testing.T) { opa: opa, expansionSystem: expansion.NewSystem(mutation.NewSystem(mutation.SystemOpts{})), webhookHandler: webhookHandler{injectedConfig: tt.Cfg}, + log: log, } if maxThreads > 0 { handler.semaphore = make(chan struct{}, maxThreads) } - review := &atypes.Request{ + review := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Kind: metav1.GroupVersionKind{ Group: "", @@ -813,11 +777,12 @@ func TestGetValidationMessages(t *testing.T) { opa: opa, expansionSystem: expansion.NewSystem(mutation.NewSystem(mutation.SystemOpts{})), webhookHandler: webhookHandler{}, + log: log, } if maxThreads > 0 { handler.semaphore = make(chan struct{}, maxThreads) } - review := &atypes.Request{ + review := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Kind: metav1.GroupVersionKind{ Group: "", @@ -863,8 +828,8 @@ func TestValidateConfigResource(t *testing.T) { for _, tt := range tc { t.Run(tt.TestName, func(t *testing.T) { - handler := validationHandler{} - req := &atypes.Request{ + handler := validationHandler{log: log} + req := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Name: tt.Name, }, @@ -910,13 +875,13 @@ func TestValidateProvider(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := &validationHandler{} + h := &validationHandler{log: log} b, err := yaml.YAMLToJSON([]byte(tt.provider)) if err != nil { t.Fatalf("Error parsing yaml: %s", err) } - req := &atypes.Request{ + req := &admission.Request{ AdmissionRequest: admissionv1.AdmissionRequest{ Object: runtime.RawExtension{ Raw: b, diff --git a/pkg/webhook/stats_reporter.go b/pkg/webhook/stats_reporter.go index ce727dfb3b6..ea0b2b77e58 100644 --- a/pkg/webhook/stats_reporter.go +++ b/pkg/webhook/stats_reporter.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/open-policy-agent/gatekeeper/pkg/metrics" + "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go index ef651e0fa5a..bc1367cb64c 100644 --- a/pkg/webhook/webhook.go +++ b/pkg/webhook/webhook.go @@ -17,9 +17,9 @@ package webhook import ( constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/gatekeeper/pkg/controller/config/process" - "github.com/open-policy-agent/gatekeeper/pkg/expansion" - "github.com/open-policy-agent/gatekeeper/pkg/mutation" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" + "github.com/open-policy-agent/gatekeeper/v3/pkg/mutation" "sigs.k8s.io/controller-runtime/pkg/manager" ) diff --git a/pkg/wildcard/wildcard.go b/pkg/wildcard/wildcard.go new file mode 100644 index 00000000000..36df10bfa7c --- /dev/null +++ b/pkg/wildcard/wildcard.go @@ -0,0 +1,41 @@ +package wildcard + +import "strings" + +// +kubebuilder:validation:Pattern=`^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$` + +// A string that supports globbing at its front or end. Ex: "kube-*" will match "kube-system" or +// "kube-public", "*-system" will match "kube-system" or "gatekeeper-system". The asterisk is +// required for wildcard matching. +// +//nolint:revive +type Wildcard string + +// Matches returns true if the candidate parameter is either an exact match of the Wildcard, +// or if the Wildcard is a valid glob-match for the candidate. The Wildcard must start or end +// in a "*" to be considered a glob. +func (w Wildcard) Matches(candidate string) bool { + wStr := string(w) + switch { + case strings.HasPrefix(wStr, "*") && strings.HasSuffix(wStr, "*"): + return strings.Contains(candidate, strings.TrimSuffix(strings.TrimPrefix(wStr, "*"), "*")) + case strings.HasPrefix(wStr, "*"): + return strings.HasSuffix(candidate, strings.TrimPrefix(wStr, "*")) + case strings.HasSuffix(wStr, "*"): + return strings.HasPrefix(candidate, strings.TrimSuffix(wStr, "*")) + default: + return wStr == candidate + } +} + +func (w Wildcard) MatchesGenerateName(candidate string) bool { + wStr := string(w) + switch { + case strings.HasPrefix(wStr, "*") && strings.HasSuffix(wStr, "*"): + return strings.Contains(candidate, strings.TrimSuffix(strings.TrimPrefix(wStr, "*"), "*")) + case strings.HasSuffix(wStr, "*"): + return strings.HasPrefix(candidate, strings.TrimSuffix(wStr, "*")) + default: + return false + } +} diff --git a/pkg/wildcard/wildcard_test.go b/pkg/wildcard/wildcard_test.go new file mode 100644 index 00000000000..d3853eebae8 --- /dev/null +++ b/pkg/wildcard/wildcard_test.go @@ -0,0 +1,193 @@ +package wildcard + +import ( + "testing" +) + +func TestMatches(t *testing.T) { + tcs := []struct { + name string + w Wildcard + candidate string + matches bool + }{ + { + name: "exact text match", + w: Wildcard("kube-system"), + candidate: "kube-system", + matches: true, + }, + { + name: "no glob, wrong text", + w: Wildcard("kube-system"), + candidate: "gatekeeper-system", + matches: false, + }, + { + name: "wildcard prefix match", + w: Wildcard("kube-*"), + candidate: "kube-system", + matches: true, + }, + { + name: "wildcard prefix doesn't match", + w: Wildcard("kube-*"), + candidate: "gatekeeper-system", + matches: false, + }, + { + name: "wildcard suffix match", + w: Wildcard("*-system"), + candidate: "kube-system", + matches: true, + }, + { + name: "wildcard suffix doesn't match", + w: Wildcard("*-system"), + candidate: "kube-public", + matches: false, + }, + { + name: "missing asterisk yields no wildcard support", + w: Wildcard("kube-"), + candidate: "kube-system", + matches: false, + }, + { + name: "wildcard suffix and prefix match", + w: Wildcard("*-kube-*"), + candidate: "test-kube-test", + matches: true, + }, + { + name: "no wildcard, only hypens at suffix and prefix", + w: Wildcard("-kube-"), + candidate: "test-kube-test", + matches: false, + }, + { + name: "wild card at suffix and prefix, multiple hyphens", + w: Wildcard("*-kube-*"), + candidate: "test-dev-kube-dev-test", + matches: true, + }, + { + name: "wild card at suffid and end, multiple hypens, no match", + w: Wildcard("*-kube-*"), + candidate: "my-kub-controller", + matches: false, + }, + { + name: "wild card at suffix and prefix, multiple hyphens, no match", + w: Wildcard("*-kube-*"), + candidate: "my-controller-manager", + matches: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + if tc.w.Matches(tc.candidate) != tc.matches { + if tc.matches { + t.Errorf("Expected candidate '%v' to match wildcard '%v'", tc.candidate, tc.w) + } else { + t.Errorf("Candidate '%v' unexpectedly matched wildcard '%v'", tc.candidate, tc.w) + } + } + }) + } +} + +func TestWildcard_MatchesGenerateName(t *testing.T) { + tcs := []struct { + name string + w Wildcard + candidate string + matches bool + }{ + { + name: "exact text match", + w: Wildcard("kube-system"), + candidate: "kube-system", + matches: false, + }, + { + name: "no glob, wrong text", + w: Wildcard("kube-system"), + candidate: "gatekeeper-system", + matches: false, + }, + { + name: "wildcard prefix match", + w: Wildcard("kube-*"), + candidate: "kube-system", + matches: true, + }, + { + name: "wildcard prefix doesn't match", + w: Wildcard("kube-*"), + candidate: "gatekeeper-system", + matches: false, + }, + { + name: "wildcard suffix match", + w: Wildcard("*-system"), + candidate: "kube-system", + matches: false, + }, + { + name: "wildcard suffix doesn't match", + w: Wildcard("*-system"), + candidate: "kube-public", + matches: false, + }, + { + name: "missing asterisk yields no wildcard support", + w: Wildcard("kube-"), + candidate: "kube-system", + matches: false, + }, + { + name: "wildcard suffix and prefix match", + w: Wildcard("*-kube-*"), + candidate: "test-kube-test", + matches: true, + }, + { + name: "no wildcard, only hypens at suffix and prefix", + w: Wildcard("-kube-"), + candidate: "test-kube-test", + matches: false, + }, + { + name: "wild card at suffix and prefix, multiple hyphens", + w: Wildcard("*-kube-*"), + candidate: "test-dev-kube-dev-test", + matches: true, + }, + { + name: "wild card at suffid and end, multiple hypens, no match", + w: Wildcard("*-kube-*"), + candidate: "my-kub-controller", + matches: false, + }, + { + name: "wild card at suffix and prefix, multiple hyphens, no match", + w: Wildcard("*-kube-*"), + candidate: "my-controller-manager", + matches: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + if tc.w.MatchesGenerateName(tc.candidate) != tc.matches { + if tc.matches { + t.Errorf("Expected candidate '%v' to match wildcard '%v'", tc.candidate, tc.w) + } else { + t.Errorf("Candidate '%v' unexpectedly matched wildcard '%v'", tc.candidate, tc.w) + } + } + }) + } +} diff --git a/test/bats/helpers.bash b/test/bats/helpers.bash index 75535abca06..e2acb9e1205 100644 --- a/test/bats/helpers.bash +++ b/test/bats/helpers.bash @@ -137,4 +137,11 @@ mutator_enforced() { local ready_count=$(echo "${cstr}" | jq '.metadata.generation as $generation | [.status.byPod[] | select( .operations[] == "mutation-webhook" and .observedGeneration == $generation)] | length') echo "ready: ${ready_count}, expected: ${pod_count}" [[ "${ready_count}" -eq "${pod_count}" ]] -} \ No newline at end of file +} + +total_violations() { + ct_total_violations="$(kubectl get k8srequiredlabels pod-must-have-test -n gatekeeper-system -ojson | jq '.status.totalViolations')" + audit_id="$(kubectl get k8srequiredlabels pod-must-have-test -n gatekeeper-system -ojson | jq '.status.auditTimestamp')" + violations="$(kubectl logs -n fake-subscriber -l app=sub -c go-sub --tail=-1 | grep $audit_id | grep violation_audited | wc -l)" + [[ "${ct_total_violations}" -eq "${violations}" ]] +} diff --git a/test/bats/test.bats b/test/bats/test.bats index 24bf49a8720..dc7ef017afa 100644 --- a/test/bats/test.bats +++ b/test/bats/test.bats @@ -52,6 +52,8 @@ teardown_file() { @test "mutation crds are established" { wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/assign.mutations.gatekeeper.sh" wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/assignmetadata.mutations.gatekeeper.sh" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/modifyset.mutations.gatekeeper.sh" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/assignimage.mutations.gatekeeper.sh" } @test "waiting for validating webhook" { @@ -82,9 +84,25 @@ teardown_file() { run kubectl get svc mutate-svc -o jsonpath="{.metadata.annotations.gatekeeper\.sh\/mutations}" assert_equal 'Assign//k8sexternalip:1' "${output}" + # Test AssignImage + kubectl apply -f ${BATS_TESTS_DIR}/mutations/assign_image.yaml + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "mutator_enforced AssignImage add-domain-digest" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/nginx_pod.yaml" + run kubectl get pod nginx-test-pod -o jsonpath="{.spec.containers[0].image}" + assert_equal "foocorp.org/nginx@sha256:abcde67890123456789abc345678901a" "${output}" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl delete pod nginx-test-pod" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl delete assignimage add-domain-digest" + + # Test removing the AssignImage does not apply mutation + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/nginx_pod.yaml" + run kubectl get pod nginx-test-pod -o jsonpath="{.spec.containers[0].image}" + assert_equal "nginx:latest" "${output}" + kubectl delete --ignore-not-found svc mutate-svc kubectl delete --ignore-not-found assignmetadata k8sownerlabel kubectl delete --ignore-not-found assign k8sexternalip + kubectl delete --ignore-not-found assignimage add-domain-digest + kubectl delete --ignore-not-found pod nginx-test-pod } @test "applying sync config" { @@ -210,14 +228,14 @@ __required_labels_audit_test() { @test "emit events test" { # list events for easy debugging - kubectl get events -n ${GATEKEEPER_NAMESPACE} - events=$(kubectl get events -n ${GATEKEEPER_NAMESPACE} --field-selector reason=FailedAdmission -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') + kubectl get events -n gatekeeper-test-playground + events=$(kubectl get events -n gatekeeper-test-playground --field-selector reason=FailedAdmission -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') [[ "$events" -ge 1 ]] - events=$(kubectl get events -n ${GATEKEEPER_NAMESPACE} --field-selector reason=DryrunViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') + events=$(kubectl get events -n gatekeeper-test-playground --field-selector reason=DryrunViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') [[ "$events" -ge 1 ]] - events=$(kubectl get events -n ${GATEKEEPER_NAMESPACE} --field-selector reason=AuditViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') + events=$(kubectl get events -n gatekeeper-test-playground --field-selector reason=AuditViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') [[ "$events" -ge 1 ]] } @@ -399,6 +417,12 @@ __expansion_audit_test() { run kubectl apply -f test/expansion/loadbalancers_must_have_env.yaml wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels loadbalancers-must-have-env" + # check status resource on expansion template + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get -f test/expansion/expand_deployments.yaml -ojson | jq -r -e '.status.byPod[0]'" + local temp_uid=$(kubectl get -f test/expansion/expand_deployments.yaml -o jsonpath='{.metadata.uid}') + local byPod_uid=$(kubectl get -f test/expansion/expand_deployments.yaml -o jsonpath='{.status.byPod[0].templateUID}') + assert_match ${temp_uid} ${byPod_uid} + # assert that creating deployment without 'env' label is rejected run kubectl apply -f test/expansion/deployment_no_label.yaml assert_failure @@ -426,6 +450,38 @@ __expansion_audit_test() { assert_success # with a violating deployment on cluster, test that audit produces expansion violations wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "__expansion_audit_test" + run kubectl delete -f test/expansion/warn_expand_deployments + run kubectl delete -f test/expansion/deployment_no_label.yaml + + # test source field on Constraints + run kubectl apply -f test/expansion/expand_deployments.yaml + run kubectl delete --ignore-not-found -f test/expansion/loadbalancers_must_have_env.yaml + run kubectl apply -f test/expansion/loadbalancers_must_have_env_source_gen.yaml + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels loadbalancers-must-have-env-gen" + # a generated pod should be denied + run kubectl apply -f test/expansion/deployment_no_label.yaml + assert_failure + # an original pod should be accepted, as the constraint only matches generated pods + run kubectl run nginx --image=nginx --dry-run=server --output json + assert_success + + # test recursive expansion cronjob->job->pod triggers pod violation when creating cronjob + run kubectl apply -f test/expansion/expand_cronjob_job_pod.yaml + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get expansiontemplate expand-cronjobs -ojson | jq -r -e '.status.byPod[0]'" + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get expansiontemplate expand-jobs -ojson | jq -r -e '.status.byPod[0]'" + run kubectl apply -f test/expansion/cronjob.yaml + assert_failure + + # test adding a ExpansionTemplate that creates a cycle updates template's status + run kubectl apply -f test/expansion/expand_pod_cronjob.yaml + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get -f test/expansion/expand_pod_cronjob.yaml -ojson | jq -r -e '.status.byPod[0]'" + # expand-cronjobs, expand-jobs, and expand_pod_cronjob should each have an error set in their status + local status_err=$(kubectl get -f test/expansion/expand_pod_cronjob.yaml -o jsonpath='{.status.byPod[0].errors}' | grep "template forms expansion cycle" | wc -l) + assert_match "${status_err}" "1" + local status_err2=$(kubectl get expansiontemplate expand-cronjobs -o jsonpath='{.status.byPod[0].errors}' | grep "template forms expansion cycle" | wc -l) + assert_match "${status_err2}" "1" + local status_err3=$(kubectl get expansiontemplate expand-jobs -o jsonpath='{.status.byPod[0].errors}' | grep "template forms expansion cycle" | wc -l) + assert_match "${status_err3}" "1" # cleanup run kubectl delete --ignore-not-found namespace loadbalancers @@ -433,7 +489,32 @@ __expansion_audit_test() { run kubectl delete --ignore-not-found -f test/expansion/warn_expand_deployments.yaml run kubectl delete --ignore-not-found -f test/expansion/k8srequiredlabels_ct.yaml run kubectl delete --ignore-not-found -f test/expansion/loadbalancers_must_have_env.yaml + run kubectl delete --ignore-not-found -f test/expansion/loadbalancers_must_have_env_source_gen.yaml run kubectl delete --ignore-not-found -f test/expansion/assignmeta_env.yaml run kubectl delete --ignore-not-found -f test/expansion/deployment_no_label.yaml run kubectl delete --ignore-not-found -f test/expansion/deployment_with_label.yaml + run kubectl delete --ignore-not-found -f test/expansion/cronjob.yaml + run kubectl delete --ignore-not-found -f test/expansion/expand_cronjob_job_pod.yaml + run kubectl delete --ignore-not-found -f test/expansion/expand_pod_cronjob.yaml +} + +@test "gatekeeper pubsub test" { + if [ -z $ENABLE_PUBSUB_TESTS ]; then + skip "skipping pubsub tests" + fi + + run kubectl create ns nginx + run kubectl create -f test/pubsub/nginx_deployment.yaml + + run kubectl apply -f test/pubsub/k8srequiredlabels_ct.yaml + run kubectl apply -f test/pubsub/pod_must_have_test.yaml + + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels pod-must-have-test" + + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "total_violations" + + run kubectl delete -f test/pubsub/k8srequiredlabels_ct.yaml --ignore-not-found + run kubectl delete -f test/pubsub/pod_must_have_test.yaml --ignore-not-found + run kubectl delete -f test/pubsub/nginx_deployment.yaml --ignore-not-found + run kubectl delete ns nginx --ignore-not-found } diff --git a/test/bats/tests/mutations/assign_image.yaml b/test/bats/tests/mutations/assign_image.yaml new file mode 100644 index 00000000000..c2d2af4ef23 --- /dev/null +++ b/test/bats/tests/mutations/assign_image.yaml @@ -0,0 +1,19 @@ +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: add-domain-digest +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:*].image" + parameters: + assignDomain: "foocorp.org" + assignTag: "@sha256:abcde67890123456789abc345678901a" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] diff --git a/test/bats/tests/mutations/nginx_pod.yaml b/test/bats/tests/mutations/nginx_pod.yaml new file mode 100644 index 00000000000..b90135fdc97 --- /dev/null +++ b/test/bats/tests/mutations/nginx_pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-test-pod + labels: + role: myrole +spec: + containers: + - name: test + image: nginx:latest diff --git a/test/clients/noop_client.go b/test/clients/noop_client.go index d9950a9294d..6cff301cba1 100644 --- a/test/clients/noop_client.go +++ b/test/clients/noop_client.go @@ -54,7 +54,7 @@ func (f *NoopClient) DeleteAllOf(ctx context.Context, obj client.Object, opts .. } func (f *NoopClient) Status() client.StatusWriter { - return f + return &SubResourceNoopClient{} } func (f *NoopClient) RESTMapper() meta.RESTMapper { @@ -64,3 +64,17 @@ func (f *NoopClient) RESTMapper() meta.RESTMapper { func (f *NoopClient) Scheme() *runtime.Scheme { return nil } + +type SubResourceNoopClient struct{} + +func (f *SubResourceNoopClient) Create(ctx context.Context, obj, subResource client.Object, opts ...client.SubResourceCreateOption) error { + return nil +} + +func (f *SubResourceNoopClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + return nil +} + +func (f *SubResourceNoopClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + return nil +} diff --git a/test/clients/retry_client.go b/test/clients/retry_client.go index 67200ce9bcb..743a8ee5db4 100644 --- a/test/clients/retry_client.go +++ b/test/clients/retry_client.go @@ -68,7 +68,7 @@ func retry(ctx context.Context, limiter *rate.Limiter, f func() error) error { } } -func (c *RetryClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error { +func (c *RetryClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { return retry(ctx, c.Limiter, func() error { return c.Client.Get(ctx, key, obj) }) @@ -119,13 +119,13 @@ type RetryStatusWriter struct { Limiter *rate.Limiter } -func (c *RetryStatusWriter) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { +func (c *RetryStatusWriter) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { return retry(ctx, c.Limiter, func() error { return c.StatusWriter.Update(ctx, obj, opts...) }) } -func (c *RetryStatusWriter) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { +func (c *RetryStatusWriter) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { return retry(ctx, c.Limiter, func() error { return c.StatusWriter.Patch(ctx, obj, patch, opts...) }) diff --git a/test/expansion/cronjob.yaml b/test/expansion/cronjob.yaml new file mode 100644 index 00000000000..4f7db934506 --- /dev/null +++ b/test/expansion/cronjob.yaml @@ -0,0 +1,23 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: my-cronjob + namespace: "loadbalancers" +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + metadata: + namespace: "loadbalancers" + spec: + containers: + - args: + - "/bin/sh" + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: 80 + restartPolicy: OnFailure + diff --git a/test/expansion/expand_cronjob_job_pod.yaml b/test/expansion/expand_cronjob_job_pod.yaml new file mode 100644 index 00000000000..b8b3b7e3381 --- /dev/null +++ b/test/expansion/expand_cronjob_job_pod.yaml @@ -0,0 +1,29 @@ +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-cronjobs +spec: + applyTo: + - groups: [ "batch" ] + kinds: [ "CronJob" ] + versions: [ "v1" ] + templateSource: "spec.jobTemplate" + generatedGVK: + kind: "Job" + group: "batch" + version: "v1" +--- +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-jobs +spec: + applyTo: + - groups: [ "batch" ] + kinds: [ "Job" ] + versions: [ "v1" ] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" diff --git a/test/expansion/expand_deployments.yaml b/test/expansion/expand_deployments.yaml index e6447220471..dd04af0366a 100644 --- a/test/expansion/expand_deployments.yaml +++ b/test/expansion/expand_deployments.yaml @@ -1,4 +1,4 @@ -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-deployments diff --git a/test/expansion/expand_pod_cronjob.yaml b/test/expansion/expand_pod_cronjob.yaml new file mode 100644 index 00000000000..123a5ce57a6 --- /dev/null +++ b/test/expansion/expand_pod_cronjob.yaml @@ -0,0 +1,14 @@ +apiVersion: expansion.gatekeeper.sh/v1beta1 +kind: ExpansionTemplate +metadata: + name: expand-pods +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + templateSource: "spec.foo" + generatedGVK: + kind: "CronJob" + group: "batch" + version: "v1" diff --git a/test/expansion/loadbalancers_must_have_env_source_gen.yaml b/test/expansion/loadbalancers_must_have_env_source_gen.yaml new file mode 100644 index 00000000000..5d9060b8586 --- /dev/null +++ b/test/expansion/loadbalancers_must_have_env_source_gen.yaml @@ -0,0 +1,14 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabels +metadata: + name: loadbalancers-must-have-env-gen +spec: + match: + scope: "Namespaced" + namespaces: [ "loadbalancers" ] + kinds: + - apiGroups: [ "" ] + kinds: [ "Pod" ] + source: "Generated" + parameters: + labels: [ "env" ] diff --git a/test/expansion/warn_expand_deployments.yaml b/test/expansion/warn_expand_deployments.yaml index 3b9cf7a3672..e61a29988b0 100644 --- a/test/expansion/warn_expand_deployments.yaml +++ b/test/expansion/warn_expand_deployments.yaml @@ -1,4 +1,4 @@ -apiVersion: expansion.gatekeeper.sh/v1alpha1 +apiVersion: expansion.gatekeeper.sh/v1beta1 kind: ExpansionTemplate metadata: name: expand-deployments diff --git a/test/externaldata/dummy-provider/Dockerfile b/test/externaldata/dummy-provider/Dockerfile index ef1521e67cc..001880610c9 100644 --- a/test/externaldata/dummy-provider/Dockerfile +++ b/test/externaldata/dummy-provider/Dockerfile @@ -1,5 +1,5 @@ ARG BUILDPLATFORM="linux/amd64" -ARG BUILDERIMAGE="golang:1.19-bullseye" +ARG BUILDERIMAGE="golang:1.21-bullseye" ARG BASEIMAGE="gcr.io/distroless/static:nonroot" FROM --platform=$BUILDPLATFORM $BUILDERIMAGE as builder diff --git a/test/gator/expand/fixtures/basic-expansion-nonmatching-configs/output/output.yaml b/test/gator/expand/fixtures/basic-expansion-nonmatching-configs/output/output.yaml index daa0fc09b9f..e2151b5fe47 100644 --- a/test/gator/expand/fixtures/basic-expansion-nonmatching-configs/output/output.yaml +++ b/test/gator/expand/fixtures/basic-expansion-nonmatching-configs/output/output.yaml @@ -3,6 +3,7 @@ kind: Pod metadata: labels: app: nginx + name: nginx-deployment-pod spec: containers: - args: diff --git a/test/gator/expand/fixtures/basic-expansion/input/assignimage_mutator.yaml b/test/gator/expand/fixtures/basic-expansion/input/assignimage_mutator.yaml new file mode 100644 index 00000000000..8043daf3485 --- /dev/null +++ b/test/gator/expand/fixtures/basic-expansion/input/assignimage_mutator.yaml @@ -0,0 +1,18 @@ +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: add-tag-latest +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:*].image" + parameters: + assignTag: ":latest" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] diff --git a/test/gator/expand/fixtures/basic-expansion/output/output.yaml b/test/gator/expand/fixtures/basic-expansion/output/output.yaml index 676c973a671..58941d6ba97 100644 --- a/test/gator/expand/fixtures/basic-expansion/output/output.yaml +++ b/test/gator/expand/fixtures/basic-expansion/output/output.yaml @@ -5,11 +5,12 @@ metadata: owner: admin labels: app: nginx + name: nginx-deployment-pod spec: containers: - args: - /bin/sh - image: nginx:1.14.2 + image: nginx:latest imagePullPolicy: Always name: nginx ports: diff --git a/test/gator/expand/fixtures/expand-cr/output/output.yaml b/test/gator/expand/fixtures/expand-cr/output/output.yaml index fefe29f02aa..aabede74d33 100644 --- a/test/gator/expand/fixtures/expand-cr/output/output.yaml +++ b/test/gator/expand/fixtures/expand-cr/output/output.yaml @@ -3,6 +3,7 @@ kind: Purr metadata: annotations: shouldPet: manytimes + name: big-chungus-purr spec: loud: very --- @@ -13,6 +14,7 @@ metadata: sound: meow labels: fluffy: extremely + name: big-chungus-kitten spec: age: 10 breed: calico diff --git a/test/gator/expand/fixtures/expand-with-missing-ns/input/manifest.yaml b/test/gator/expand/fixtures/expand-with-missing-ns/input/manifest.yaml index b0144e715de..30b53f025d9 100644 --- a/test/gator/expand/fixtures/expand-with-missing-ns/input/manifest.yaml +++ b/test/gator/expand/fixtures/expand-with-missing-ns/input/manifest.yaml @@ -38,3 +38,6 @@ spec: args: - "/bin/sh" --- +# while this is missing the "my-ns" namespace +# since there are no namespace selectors +# this test will pass. diff --git a/test/gator/expand/fixtures/expand-with-ns/output/output.yaml b/test/gator/expand/fixtures/expand-with-ns/output/output.yaml index 1a0fc80a699..d4cf89ebb9a 100644 --- a/test/gator/expand/fixtures/expand-with-ns/output/output.yaml +++ b/test/gator/expand/fixtures/expand-with-ns/output/output.yaml @@ -3,6 +3,7 @@ kind: Pod metadata: labels: app: nginx + name: nginx-deployment-pod namespace: my-ns spec: containers: diff --git a/test/gator/expand/test.bats b/test/gator/expand/test.bats index 363815578f1..9475f635a01 100644 --- a/test/gator/expand/test.bats +++ b/test/gator/expand/test.bats @@ -12,9 +12,9 @@ match_yaml_in_dir () { want=$(cat "${BATS_TEST_DIRNAME}"/fixtures/"${match_dir}"/output/output.yaml) if [[ ${yaml_output} != *"$want"* ]]; then - printf "ERROR: resource not found in output\n" - printf "WANT:\n%s\n\n" "$want" - printf "GOT:\n%s\n" "$yaml_output" + echo "ERROR: resource not found in output" + echo "WANT: ${want}" + echo "GOT: ${yaml_output}" echo "DIFF: " diff <( echo "$want" ) <( echo "$yaml_output" ) exit 1 @@ -52,8 +52,10 @@ test_dir () { test_dir "expand-with-ns" 0 } +# the matching system will not err out when the namespace for +# a resource is not defined but we DON'T use a namespace selector. @test "generator with a custom namespace but namespace config missing" { - test_dir "expand-with-missing-ns" 1 + test_dir "expand-with-missing-ns" 0 } @test "expand into 2 resultants and write to file" { diff --git a/test/gator/test/fixtures/manifests/expansion/expansion-w-ns-selector.yaml b/test/gator/test/fixtures/manifests/expansion/expansion-w-ns-selector.yaml new file mode 100644 index 00000000000..3c9c3942d68 --- /dev/null +++ b/test/gator/test/fixtures/manifests/expansion/expansion-w-ns-selector.yaml @@ -0,0 +1,128 @@ +apiVersion: expansion.gatekeeper.sh/v1alpha1 +kind: ExpansionTemplate +metadata: + name: expand-deployments +spec: + applyTo: + - groups: [ "apps" ] + kinds: [ "Deployment" ] + versions: [ "v1" ] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: my-ns + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + args: + - "/bin/sh" +--- +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabels +metadata: + name: all-must-have-owner +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + namespaceSelector: + matchExpressions: + - key: admission.gatekeeper.sh/ignore + operator: DoesNotExist + parameters: + message: "All pods must have an `owner` label that points to your company username" + labels: + - key: owner + allowedRegex: "^[a-zA-Z]+.agilebank.demo$" +--- +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabels + annotations: + description: >- + Requires resources to contain specified labels, with values matching + provided regular expressions. +spec: + crd: + spec: + names: + kind: K8sRequiredLabels + validation: + openAPIV3Schema: + type: object + properties: + message: + type: string + labels: + type: array + description: >- + A list of labels and values the object must specify. + items: + type: object + properties: + key: + type: string + description: >- + The required label. + allowedRegex: + type: string + description: >- + If specified, a regular expression the annotation's value + must match. The value must contain at least one match for + the regular expression. + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8srequiredlabels + + get_message(parameters, _default) = msg { + not parameters.message + msg := _default + } + + get_message(parameters, _default) = msg { + msg := parameters.message + } + + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + def_msg := sprintf("you must provide labels: %v", [missing]) + msg := get_message(input.parameters, def_msg) + } + + violation[{"msg": msg}] { + value := input.review.object.metadata.labels[key] + expected := input.parameters.labels[_] + expected.key == key + # do not match if allowedRegex is not defined, or is an empty string + expected.allowedRegex != "" + not re_match(expected.allowedRegex, value) + def_msg := sprintf("Label <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) + msg := get_message(input.parameters, def_msg) + } diff --git a/test/gator/test/fixtures/manifests/expansion/ns.yaml b/test/gator/test/fixtures/manifests/expansion/ns.yaml new file mode 100644 index 00000000000..fe784865e8f --- /dev/null +++ b/test/gator/test/fixtures/manifests/expansion/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: my-ns diff --git a/test/gator/test/fixtures/manifests/with-policies/with-violations-and-defaults.yaml b/test/gator/test/fixtures/manifests/with-policies/with-violations-and-defaults.yaml new file mode 100644 index 00000000000..c7a087b8c7f --- /dev/null +++ b/test/gator/test/fixtures/manifests/with-policies/with-violations-and-defaults.yaml @@ -0,0 +1,75 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabelsdefault +spec: + crd: + spec: + names: + kind: K8sRequiredLabelsDefault + validation: + legacySchema: false + openAPIV3Schema: + properties: + labels: + description: A list of labels and values the object must specify. + default: + - key: "aRequiredLabel" + items: + properties: + key: + description: The required label. + type: string + type: object + type: array + message: + default: "aRequiredMessage" + type: string + placeholder: # needed to showcase defaulting of the other two props above. + type: string + type: object + targets: + - rego: | + package k8srequiredlabels + + get_message(parameters, _default) = msg { + not parameters.message + msg := _default + } + + get_message(parameters, _default) = msg { + msg := parameters.message + } + + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_].key} + missing := required - provided + count(missing) > 0 + + msg := input.parameters.message + } + + target: admission.k8s.gatekeeper.sh +--- +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabelsDefault +metadata: + name: all-must-have-owner +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Namespace"] + parameters: + placeholder: "placeholder" +# notice no parameters that are used in the validaiton code are defined, +# the defaults are applied from the ConstraintTemplate's open api v3 schema definition +--- +apiVersion: v1 +kind: Namespace +metadata: + name: my-ns +# Missing owner label +# labels: +# owner: user.agilebank.demo diff --git a/test/gator/test/test.bats b/test/gator/test/test.bats index d03ae84736a..fd19c308eae 100755 --- a/test/gator/test/test.bats +++ b/test/gator/test/test.bats @@ -46,6 +46,11 @@ match_yaml_msg () { # END OF HELPER FUNCTIONS #################################################################################################### +@test "gator test doesn't wait on stdin input" { + # this should fail with "no input data identified" + ! bin/gator test +} + @test "manifest with no violations piped to stdin returns 0 exit status" { bin/gator test < "$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/no-violations.yaml" if [ "$?" -ne 0 ]; then @@ -54,10 +59,20 @@ match_yaml_msg () { fi } -@test "manifest with violations piped to stdin returns 1 exit status" { +@test "manifest with violations redirected to stdin returns 1 exit status" { ! bin/gator test < "$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/with-violations.yaml" } +@test "manifest with violations piped to stdin returns 1 exit status" { + # first test that we fail the command + ! cat "$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/with-violations.yaml" | bin/gator test + + output=$(! cat "$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/with-violations.yaml" | bin/gator test) + + # now test that the failure reason is a violation + match_substring "${output[*]}" "Container in your has no " +} + @test "manifest with no violations included as flag returns 0 exit status" { bin/gator test --filename="$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/no-violations.yaml" if [ "$?" -ne 0 ]; then @@ -230,3 +245,41 @@ match_yaml_msg () { want_msg="you must provide labels: {\"geo\"}" match_yaml_msg "${output[*]}" "${want_msg}" } + +@test "observe open api v3 defaults being applied" { + run bin/gator test \ + -f="$BATS_TEST_DIRNAME/fixtures/manifests/with-policies/with-violations-and-defaults.yaml" \ + -o=yaml + + [ "$status" -eq 1 ] + + # these are defined in the template's default fields for the parameters + want_msg_1="aRequiredLabel" + want_msg_2="aRequiredMessage" + + match_substring "${output[*]}" "${want_msg_1}" + match_substring "${output[*]}" "${want_msg_2}" +} + +@test "expansion with namespace selector" { + # First run without the namespace and expect an err + run bin/gator test \ + -f="$BATS_TEST_DIRNAME/fixtures/manifests/expansion/expansion-w-ns-selector.yaml" \ + -o=yaml + + [ "$status" -eq 1 ] + + want_msg="Implied by expand-deployments] unable to match constraints: error matching the requested object: nginx-deployment-pod :failed to run Match criteria: namespace selector for namespace-scoped object but missing Namespace" + match_substring "${output[*]}" "${want_msg}" + + # Now expect a violation + run bin/gator test \ + -f="$BATS_TEST_DIRNAME/fixtures/manifests/expansion/expansion-w-ns-selector.yaml" \ + -f="$BATS_TEST_DIRNAME/fixtures/manifests/expansion/ns.yaml" \ + -o=yaml + + [ "$status" -eq 1 ] + + want_msg="[Implied by expand-deployments] All pods must have an \`owner\` label that points to your company username" + match_substring "${output[*]}" "${want_msg}" +} diff --git a/test/image/Dockerfile b/test/image/Dockerfile index 86f791fad22..7db376df488 100644 --- a/test/image/Dockerfile +++ b/test/image/Dockerfile @@ -1,21 +1,16 @@ -# Build the manager binary -FROM golang:1.19-bullseye as builder +FROM golang:1.21-bullseye@sha256:26c7537d6ac3827eb4638034d16edc64de57bb011c8cc8fe301ac13a6568f6f4 as builder ARG BATS_VERSION ARG ORAS_VERSION ARG YQ_VERSION ARG KUSTOMIZE_VERSION -ARG KUBEBUILDER_VERSION + ARG TARGETARCH -RUN apt-get update &&\ - apt-get install -y apt-utils make +RUN git config --global --add safe.directory "*" -# Install kubebuilder -WORKDIR /scratch -RUN curl -L -O "https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${KUBEBUILDER_VERSION}/kubebuilder_linux_${TARGETARCH}" &&\ - mv kubebuilder_linux_${TARGETARCH} /usr/local/kubebuilder -ENV PATH=$PATH:/usr/local/kubebuilder/bin:/usr/bin +RUN apt-get update && \ + apt-get install -y make jq apt-utils # Install kustomize RUN curl -L -O "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_${TARGETARCH}.tar.gz" &&\ @@ -37,9 +32,6 @@ RUN curl -SsLO https://github.com/oras-project/oras/releases/download/v${ORAS_VE RUN curl -LsS https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_${TARGETARCH} -o /usr/local/bin/yq \ && chmod +x /usr/local/bin/yq -# Install jq -RUN apt-get update && yes | apt-get install jq - # Install docker RUN curl -fsSL https://get.docker.com | sh diff --git a/test/pubsub/fake-subscriber/Dockerfile b/test/pubsub/fake-subscriber/Dockerfile new file mode 100644 index 00000000000..fa389e7c05d --- /dev/null +++ b/test/pubsub/fake-subscriber/Dockerfile @@ -0,0 +1,35 @@ +ARG BUILDPLATFORM="linux/amd64" +ARG BUILDERIMAGE="golang:1.21-bullseye" +ARG BASEIMAGE="gcr.io/distroless/static:nonroot" + +FROM --platform=$BUILDPLATFORM $BUILDERIMAGE as builder + +ARG TARGETPLATFORM +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT="" +ARG LDFLAGS + +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=${TARGETOS} \ + GOARCH=${TARGETARCH} \ + GOARM=${TARGETVARIANT} + +WORKDIR /go/src/github.com/open-policy-agent/gatekeeper/test/pubsub/fake-subscriber + +COPY . . + +RUN go mod init && go mod tidy && go mod vendor + +RUN go build -o main + +FROM $BASEIMAGE + +WORKDIR / + +COPY --from=builder /go/src/github.com/open-policy-agent/gatekeeper/test/pubsub/fake-subscriber/main . + +USER 65532:65532 + +ENTRYPOINT ["/main"] diff --git a/test/pubsub/fake-subscriber/main.go b/test/pubsub/fake-subscriber/main.go new file mode 100644 index 00000000000..9831cbe2b2b --- /dev/null +++ b/test/pubsub/fake-subscriber/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "encoding/json" + "log" + "strconv" + + "github.com/dapr/go-sdk/service/common" + daprd "github.com/dapr/go-sdk/service/http" +) + +type PubsubMsg struct { + ID string `json:"id,omitempty"` + Details interface{} `json:"details,omitempty"` + EventType string `json:"eventType,omitempty"` + Group string `json:"group,omitempty"` + Version string `json:"version,omitempty"` + Kind string `json:"kind,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + Message string `json:"message,omitempty"` + EnforcementAction string `json:"enforcementAction,omitempty"` + ConstraintAnnotations map[string]string `json:"constraintAnnotations,omitempty"` + ResourceGroup string `json:"resourceGroup,omitempty"` + ResourceAPIVersion string `json:"resourceAPIVersion,omitempty"` + ResourceKind string `json:"resourceKind,omitempty"` + ResourceNamespace string `json:"resourceNamespace,omitempty"` + ResourceName string `json:"resourceName,omitempty"` + ResourceLabels map[string]string `json:"resourceLabels,omitempty"` +} + +var sub = &common.Subscription{ + PubsubName: "pubsub", + Topic: "audit", + Route: "/checkout", +} + +func main() { + s := daprd.NewService(":6002") + log.Printf("Listening...") + if err := s.AddTopicEventHandler(sub, eventHandler); err != nil { + log.Fatalf("error adding topic subscription: %v", err) + } + if err := s.Start(); err != nil { + log.Fatalf("error listening: %v", err) + } +} + +func eventHandler(_ context.Context, e *common.TopicEvent) (retry bool, err error) { + var msg PubsubMsg + jsonInput, err := strconv.Unquote(string(e.RawData)) + if err != nil { + log.Fatalf("error unquoting %v", err) + } + if err := json.Unmarshal([]byte(jsonInput), &msg); err != nil { + log.Fatalf("error %v", err) + } + + log.Printf("%#v", msg) + return false, nil +} diff --git a/test/pubsub/fake-subscriber/manifest/subscriber.yaml b/test/pubsub/fake-subscriber/manifest/subscriber.yaml new file mode 100644 index 00000000000..d0372ed6350 --- /dev/null +++ b/test/pubsub/fake-subscriber/manifest/subscriber.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: pubsub + namespace: fake-subscriber +spec: + type: pubsub.redis + version: v1 + metadata: + - name: redisHost + value: redis-master.default.svc.cluster.local:6379 + - name: redisPassword + secretKeyRef: + name: redis + key: redis-password +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sub + namespace: fake-subscriber + labels: + app: sub +spec: + replicas: 1 + selector: + matchLabels: + app: sub + template: + metadata: + labels: + app: sub + annotations: + dapr.io/enabled: "true" + dapr.io/app-id: "subscriber" + dapr.io/enable-api-logging: "true" + dapr.io/app-port: "6002" + spec: + containers: + - name: go-sub + image: fake-subscriber:latest + imagePullPolicy: Never diff --git a/test/pubsub/k8srequiredlabels_ct.yaml b/test/pubsub/k8srequiredlabels_ct.yaml new file mode 100644 index 00000000000..4437a1a19cb --- /dev/null +++ b/test/pubsub/k8srequiredlabels_ct.yaml @@ -0,0 +1,29 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabels +spec: + crd: + spec: + names: + kind: K8sRequiredLabels + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + properties: + labels: + type: array + items: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8srequiredlabels + violation[{"msg": msg, "details": {"missing_labels": missing}}] { + provided := {label | input.review.object.metadata.labels[label]} + required := {label | label := input.parameters.labels[_]} + missing := required - provided + count(missing) > 0 + msg := sprintf("you must provide labels: %v", [missing]) + } diff --git a/test/pubsub/nginx_deployment.yaml b/test/pubsub/nginx_deployment.yaml new file mode 100644 index 00000000000..f3bdc4befc4 --- /dev/null +++ b/test/pubsub/nginx_deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: nginx + labels: + app: nginx +spec: + replicas: 4 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:latest + ports: + - containerPort: 80 diff --git a/test/pubsub/pod_must_have_test.yaml b/test/pubsub/pod_must_have_test.yaml new file mode 100644 index 00000000000..3143283304a --- /dev/null +++ b/test/pubsub/pod_must_have_test.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabels +metadata: + name: pod-must-have-test +spec: + match: + scope: "Namespaced" + namespaces: [ "nginx" ] + kinds: + - apiGroups: [ "" ] + kinds: [ "Pod" ] + parameters: + labels: [ "test" ] diff --git a/test/pubsub/publish-components.yaml b/test/pubsub/publish-components.yaml new file mode 100644 index 00000000000..9686935dd01 --- /dev/null +++ b/test/pubsub/publish-components.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: pubsub + namespace: gatekeeper-system +spec: + type: pubsub.redis + version: v1 + metadata: + - name: redisHost + value: redis-master.default.svc.cluster.local:6379 + - name: redisPassword + secretKeyRef: + name: redis + key: redis-password +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: audit + namespace: gatekeeper-system +data: + provider: "dapr" + config: | + { + "component": "pubsub" + } diff --git a/test/testutils/controller.go b/test/testutils/controller.go new file mode 100644 index 00000000000..ddcd9f8c9a7 --- /dev/null +++ b/test/testutils/controller.go @@ -0,0 +1,179 @@ +package testutils + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + "path/filepath" + "testing" + "time" + + "github.com/open-policy-agent/gatekeeper/v3/apis" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/retry" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +var ( + vendorCRDPath = []string{"vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"} + gkCRDPath = []string{"config", "crd", "bases"} +) + +// ConstantRetry makes 3,000 attempts at a rate of 100 per second. Since this +// is a test instance and not a "real" cluster, this is fine and there's no need +// to increase the wait time each iteration. +var ConstantRetry = wait.Backoff{ + Steps: 3000, + Duration: 10 * time.Millisecond, +} + +// CreateGatekeeperNamespace bootstraps the gatekeeper-system namespace for use in tests. +func CreateGatekeeperNamespace(cfg *rest.Config) error { + c, err := client.New(cfg, client.Options{}) + if err != nil { + return err + } + + // Create gatekeeper namespace + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "gatekeeper-system", + }, + } + + ctx := context.Background() + _, err = controllerutil.CreateOrUpdate(ctx, c, ns, func() error { return nil }) + return err +} + +// DeleteObjectAndConfirm returns a callback which deletes obj from the passed +// Client. Does result in mutations to obj. The callback includes a cached copy +// of all information required to delete obj in the callback, so it is safe to +// mutate obj afterwards. Similarly - client.Delete mutates its input, but +// the callback does not call client.Delete on obj. Instead, it creates a +// single-purpose Unstructured for this purpose. Thus, obj is not mutated after +// the callback is run. +func DeleteObjectAndConfirm(ctx context.Context, t *testing.T, c client.Client, obj client.Object) func() { + t.Helper() + + // Cache the identifying information from obj. We refer to this cached + // information in the callback, and not obj itself. + gvk := obj.GetObjectKind().GroupVersionKind() + namespace := obj.GetNamespace() + name := obj.GetName() + + if gvk.Empty() { + // We can't send a proper delete request with an Unstructured without + // filling in GVK. The alternative would be to require tests to construct + // a valid Scheme or provide a factory method for the type to delete - this + // is easier. + t.Fatalf("gvk for %v/%v %T is empty", + namespace, name, obj) + } + + return func() { + t.Helper() + + // Construct a single-use Unstructured to send the Delete request. + toDelete := makeUnstructured(gvk, namespace, name) + err := c.Delete(ctx, toDelete) + if apierrors.IsNotFound(err) { + return + } else if err != nil { + t.Fatal(err) + } + + err = retry.OnError(ConstantRetry, func(err error) bool { + return true + }, func() error { + // Construct a single-use Unstructured to send the Get request. It isn't + // safe to reuse Unstructureds for each retry as Get modifies its input. + toGet := makeUnstructured(gvk, namespace, name) + key := client.ObjectKey{Namespace: namespace, Name: name} + err2 := c.Get(ctx, key, toGet) + if apierrors.IsGone(err2) || apierrors.IsNotFound(err2) { + return nil + } + + // Marshal the currently-gotten object, so it can be printed in test + // failure output. + s, _ := json.MarshalIndent(toGet, "", " ") + return fmt.Errorf("found %v %v:\n%s", gvk, key, string(s)) + }) + + if err != nil { + t.Fatal(err) + } + } +} + +func StartControlPlane(m *testing.M, cfg **rest.Config, testerDepth int) { + walkbacks := make([]string, testerDepth) + for i := 0; i < testerDepth; i++ { + walkbacks[i] = ".." + } + t := &envtest.Environment{ + CRDDirectoryPaths: []string{ + filepath.Join(append(walkbacks, vendorCRDPath...)...), + filepath.Join(append(walkbacks, gkCRDPath...)...), + }, + ErrorIfCRDPathMissing: true, + } + if err := apis.AddToScheme(scheme.Scheme); err != nil { + log.Fatal(err) + } + + var err error + if *cfg, err = t.Start(); err != nil { + log.Fatal(err) + } + log.Print("STARTED") + + code := m.Run() + if err = t.Stop(); err != nil { + log.Printf("error while trying to stop server: %v", err) + } + os.Exit(code) +} + +// CreateThenCleanup creates obj in Client, and then registers obj to be deleted +// at the end of the test. The passed obj is safely deepcopied before being +// passed to client.Create, so it is not mutated by this call. +func CreateThenCleanup(ctx context.Context, t *testing.T, c client.Client, obj client.Object) { + t.Helper() + cpy := obj.DeepCopyObject() + cpyObj, ok := cpy.(client.Object) + if !ok { + t.Fatalf("got obj.DeepCopyObject() type = %T, want %T", cpy, client.Object(nil)) + } + + err := c.Create(ctx, cpyObj) + if err != nil { + t.Fatal(err) + } + + // It is unnecessary to deepcopy obj as deleteObjectAndConfirm does not pass + // obj to any Client calls. + t.Cleanup(DeleteObjectAndConfirm(ctx, t, c, obj)) +} + +func makeUnstructured(gvk schema.GroupVersionKind, namespace, name string) *unstructured.Unstructured { + u := &unstructured.Unstructured{ + Object: make(map[string]interface{}), + } + u.SetGroupVersionKind(gvk) + u.SetNamespace(namespace) + u.SetName(name) + return u +} diff --git a/test/testutils/manager.go b/test/testutils/manager.go index bc5ded5b27a..8bfb377ea06 100644 --- a/test/testutils/manager.go +++ b/test/testutils/manager.go @@ -5,7 +5,14 @@ import ( "sync" "testing" + "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/metrics" ) // StartManager starts mgr. Registers a cleanup function to stop the manager at the completion of the test. @@ -30,3 +37,32 @@ func StartManager(ctx context.Context, t *testing.T, mgr manager.Manager) { } }) } + +// SetupManager sets up a controller-runtime manager with registered watch manager. +func SetupManager(t *testing.T, cfg *rest.Config) (manager.Manager, *watch.Manager) { + t.Helper() + + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + metrics.Registry = prometheus.NewRegistry() + mgr, err := manager.New(cfg, manager.Options{ + MetricsBindAddress: "0", + MapperProvider: apiutil.NewDynamicRESTMapper, + Logger: NewLogger(t), + }) + if err != nil { + t.Fatalf("setting up controller manager: %s", err) + } + c := mgr.GetCache() + dc, ok := c.(watch.RemovableCache) + if !ok { + t.Fatalf("expected dynamic cache, got: %T", c) + } + wm, err := watch.New(dc) + if err != nil { + t.Fatalf("could not create watch manager: %s", err) + } + if err := mgr.Add(wm); err != nil { + t.Fatalf("could not add watch manager to manager: %s", err) + } + return mgr, wm +} diff --git a/third_party/k8s.io/README.md b/third_party/k8s.io/README.md new file mode 100644 index 00000000000..d1ddd4c7802 --- /dev/null +++ b/third_party/k8s.io/README.md @@ -0,0 +1,7 @@ +# k8s.io/kubernetes + +Forked from k8s.io/kubernetes@124fd62ad253f8362d78d5710d8d363aa1b376df + +This is a light fork to use scripts from kubernetes/kubernetes for gatekeeper's use cases. + +The original code can be found at https://github.com/kubernetes/kubernetes/tree/124fd62ad253f8362d78d5710d8d363aa1b376df . diff --git a/third_party/k8s.io/kubernetes/hack/verify-licenses.sh b/third_party/k8s.io/kubernetes/hack/verify-licenses.sh new file mode 100755 index 00000000000..7aec68fd5f2 --- /dev/null +++ b/third_party/k8s.io/kubernetes/hack/verify-licenses.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +# Copyright 2016 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: `hack/verify-licenses.sh`. + + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t kubernetes.XXXXXX) + + +# Creating a new repository tree +# Deleting vendor directory to make go-licenses fetch license URLs from go-packages source repository +git worktree add -f "${KUBE_TEMP}"/tmp_test_licenses/gatekeeper HEAD >/dev/null 2>&1 || true +cd "${KUBE_TEMP}"/tmp_test_licenses/gatekeeper && rm -rf vendor + + +# Explicitly opt into go modules, even though we're inside a GOPATH directory +export GO111MODULE=on + + +allowed_licenses=() +packages_flagged=() +packages_url_missing=() +exit_code=0 + +# Install go-licenses +echo '[INFO] Installing go-licenses...' +go install github.com/google/go-licenses@latest + +# Fetching CNCF Approved List Of Licenses +# Refer: https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md +curl -s 'https://spdx.org/licenses/licenses.json' -o "${KUBE_TEMP}"/licenses.json + +number_of_licenses=$(jq '.licenses | length' "${KUBE_TEMP}"/licenses.json) +loop_index_length=$(( number_of_licenses - 1 )) + + +echo '[INFO] Fetching current list of CNCF approved licenses...' +for index in $(seq 0 $loop_index_length); +do + licenseID=$(jq ".licenses[$index] .licenseId" "${KUBE_TEMP}"/licenses.json) + if [[ $(jq ".licenses[$index] .isDeprecatedLicenseId" "${KUBE_TEMP}"/licenses.json) == false ]] + then + allowed_licenses+=("${licenseID}") + fi +done + + +# Scanning go-packages under the project & verifying against the CNCF approved list of licenses +echo '[INFO] Starting license scan on go-packages...' +go-licenses report ./... --include_tests >> "${KUBE_TEMP}"/licenses.csv + +echo -e 'PACKAGE_NAME LICENSE_NAME LICENSE_URL\n' >> "${KUBE_TEMP}"/approved_licenses.dump +while IFS=, read -r GO_PACKAGE LICENSE_URL LICENSE_NAME +do + FORMATTED_LICENSE_URL= + if [[ " ${allowed_licenses[*]} " == *"${LICENSE_NAME}"* ]]; + then + if [[ "${LICENSE_URL}" == 'Unknown' ]]; + then + if [[ "${GO_PACKAGE}" != k8s.io/* ]]; + then + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses_with_missing_urls.dump + packages_url_missing+=("${GO_PACKAGE}") + else + LICENSE_URL='https://github.com/kubernetes/kubernetes/blob/master/LICENSE' + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses.dump + fi + elif curl -Is "${LICENSE_URL}" | head -1 | grep -q 404; + then + # For gatekeeper, the script won't find the constraint frameworks's license atm. + if [[ "${GO_PACKAGE}" == github.com/open-policy-agent/frameworks/* ]]; + then + LICENSE_URL='https://github.com/open-policy-agent/frameworks/blob/master/LICENSE' + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses.dump + continue + fi + + # Check whether the License URL is incorrectly formed + # TODO: Remove this workaround check once PR https://github.com/google/go-licenses/pull/110 is merged + IFS='/' read -r -a split_license_url <<< ${LICENSE_URL} + for part_of_url in "${split_license_url[@]}" + do + if [[ ${part_of_url} == '' ]] + then + continue + elif [[ ${part_of_url} == 'https:' ]] + then + FORMATTED_LICENSE_URL+='https://' + else + if [[ ${part_of_url} =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]] + then + FORMATTED_LICENSE_URL+="${part_of_url}/${split_license_url[-1]}" + break + else + FORMATTED_LICENSE_URL+="${part_of_url}/" + fi + fi + done + if curl -Is "${FORMATTED_LICENSE_URL}" | head -1 | grep -q 404; + then + packages_url_missing+=("${GO_PACKAGE}") + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses_with_missing_urls.dump + else + echo "${GO_PACKAGE} ${LICENSE_NAME} ${FORMATTED_LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses.dump + fi + else + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses.dump + fi + else + # Not all packages at this point should go to the not approved dump. + # there are a few exceptions approved by CNCF as per: https://github.com/cncf/foundation/tree/main/license-exceptions + # Currently gatekeeper uses just one of those so we are not going to do a general solution. + + if [[ "${GO_PACKAGE}" == "github.com/rcrowley/go-metrics" ]] && [[ "${LICENSE_NAME}" == "BSD-2-Clause-FreeBSD" ]]; + then + # as per https://github.com/cncf/foundation/blob/main/license-exceptions/cncf-exceptions-2019-11-01.json#L723-L726 + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/approved_licenses.dump + else + echo "${GO_PACKAGE} ${LICENSE_NAME} ${LICENSE_URL}" >> "${KUBE_TEMP}"/notapproved_licenses.dump + packages_flagged+=("${GO_PACKAGE}") + fi + fi +done < "${KUBE_TEMP}"/licenses.csv +awk '{ printf "%-100s : %-20s : %s\n", $1, $2, $3 }' "${KUBE_TEMP}"/approved_licenses.dump + + +if [[ ${#packages_url_missing[@]} -gt 0 ]]; then + echo -e '\n[ERROR] The following go-packages in the project have unknown or unreachable license URL:' + awk '{ printf "%-100s : %-20s : %s\n", $1, $2, $3 }' "${KUBE_TEMP}"/approved_licenses_with_missing_urls.dump + exit_code=1 +fi + + +if [[ ${#packages_flagged[@]} -gt 0 ]]; then + echo "[ERROR] The following go-packages in the project are using non-CNCF approved licenses. Please refer to the CNCF's approved licence list for further information: https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md" + awk '{ printf "%-100s : %-20s : %s\n", $1, $2, $3 }' "${KUBE_TEMP}"/notapproved_licenses.dump + exit_code=1 +elif [[ "${exit_code}" -eq 1 ]]; then + echo "[ERROR] Project is using go-packages with unknown or unreachable license URLs. Please refer to the CNCF's approved licence list for further information: https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md" +else + echo "[SUCCESS] Scan complete! All go-packages under the project are using current CNCF approved licenses!" +fi + +exit "${exit_code}" diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/breaking_change.md b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/breaking_change.md new file mode 100644 index 00000000000..b15c979a173 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/breaking_change.md @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/bug_fix.md b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/bug_fix.md new file mode 100644 index 00000000000..84c58c71e16 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/bug_fix.md @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/compat_feature.md b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/compat_feature.md new file mode 100644 index 00000000000..3ad61bba834 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/compat_feature.md @@ -0,0 +1,3 @@ + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/docs.md b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/docs.md new file mode 100644 index 00000000000..c99ec61c2d4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/docs.md @@ -0,0 +1,3 @@ + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/other.md b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/other.md new file mode 100644 index 00000000000..eec7cbf6ee6 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/PULL_REQUEST_TEMPLATE/other.md @@ -0,0 +1,3 @@ + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/dependabot.yml b/third_party/sigs.k8s.io/controller-runtime/.github/dependabot.yml new file mode 100644 index 00000000000..f3eba9f073f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/dependabot.yml @@ -0,0 +1,36 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: ":seedling:" + labels: + - "ok-to-test" + + # Maintain dependencies for go + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: ":seedling:" + # Ignore K8 packages as these are done manually + ignore: + - dependency-name: "k8s.io/api" + - dependency-name: "k8s.io/apiextensions-apiserver" + - dependency-name: "k8s.io/apimachinery" + - dependency-name: "k8s.io/client-go" + - dependency-name: "k8s.io/component-base" + labels: + - "ok-to-test" diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/pull_request_template.md b/third_party/sigs.k8s.io/controller-runtime/.github/pull_request_template.md new file mode 100644 index 00000000000..f6b8370e57f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/pull_request_template.md @@ -0,0 +1,4 @@ + + + + diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/workflows/golangci-lint.yml b/third_party/sigs.k8s.io/controller-runtime/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000000..bcc3b26eb9e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/workflows/golangci-lint.yml @@ -0,0 +1,26 @@ +name: golangci-lint +on: + pull_request: + types: [opened, edited, synchronize, reopened] + branches: + - main +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + strategy: + matrix: + working-directory: + - "" + - tools/setup-envtest + steps: + - uses: actions/setup-go@v4 + with: + go-version: '1.20' + cache: false + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.1 + working-directory: ${{matrix.working-directory}} diff --git a/third_party/sigs.k8s.io/controller-runtime/.github/workflows/verify.yml b/third_party/sigs.k8s.io/controller-runtime/.github/workflows/verify.yml new file mode 100644 index 00000000000..51bb083ed5a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.github/workflows/verify.yml @@ -0,0 +1,14 @@ +on: + pull_request_target: + types: [opened, edited, reopened, synchronize] + +jobs: + verify: + runs-on: ubuntu-latest + name: verify PR contents + steps: + - name: Verifier action + id: verifier + uses: kubernetes-sigs/kubebuilder-release-tools@v0.3.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/third_party/sigs.k8s.io/controller-runtime/.gitignore b/third_party/sigs.k8s.io/controller-runtime/.gitignore new file mode 100644 index 00000000000..294685952b8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.gitignore @@ -0,0 +1,27 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ + +# Vscode files +.vscode + +# Tools binaries. +hack/tools/bin + +junit-report.xml +/artifacts \ No newline at end of file diff --git a/third_party/sigs.k8s.io/controller-runtime/.golangci.yml b/third_party/sigs.k8s.io/controller-runtime/.golangci.yml new file mode 100644 index 00000000000..817c2c723bd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/.golangci.yml @@ -0,0 +1,174 @@ +linters: + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - depguard + - dogsled + - dupl + - errcheck + - errchkjson + - errorlint + - exhaustive + - exportloopref + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - importas + - ineffassign + - makezero + - misspell + - nakedret + - nilerr + - nolintlint + - prealloc + - revive + - staticcheck + - stylecheck + - tagliatelle + - typecheck + - unconvert + - unparam + - unused + - whitespace + +linters-settings: + importas: + no-unaliased: true + alias: + # Kubernetes + - pkg: k8s.io/api/core/v1 + alias: corev1 + - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 + alias: apiextensionsv1 + - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 + alias: metav1 + - pkg: k8s.io/apimachinery/pkg/api/errors + alias: apierrors + - pkg: k8s.io/apimachinery/pkg/util/errors + alias: kerrors + # Controller Runtime + - pkg: sigs.k8s.io/controller-runtime + alias: ctrl + staticcheck: + go: "1.20" + stylecheck: + go: "1.20" + depguard: + include-go-root: true + packages: + - io/ioutil # https://go.dev/doc/go1.16#ioutil + revive: + rules: + # The following rules are recommended https://github.com/mgechev/revive#recommended-configuration + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + - name: if-return + - name: increment-decrement + - name: var-naming + - name: var-declaration + - name: range + - name: receiver-naming + - name: time-naming + - name: unexported-return + - name: indent-error-flow + - name: errorf + - name: superfluous-else + - name: unreachable-code + - name: redefines-builtin-id + # + # Rules in addition to the recommended configuration above. + # + - name: bool-literal-in-expr + - name: constant-logical-expr + +issues: + max-same-issues: 0 + max-issues-per-linter: 0 + # We are disabling default golangci exclusions because we want to help reviewers to focus on reviewing the most relevant + # changes in PRs and avoid nitpicking. + exclude-use-default: false + # List of regexps of issue texts to exclude, empty list by default. + exclude: + # The following are being worked on to remove their exclusion. This list should be reduced or go away all together over time. + # If it is decided they will not be addressed they should be moved above this comment. + - Subprocess launch(ed with variable|ing should be audited) + - (G204|G104|G307) + - "ST1000: at least one file in a package should have a package comment" + exclude-rules: + - linters: + - gosec + text: "G108: Profiling endpoint is automatically exposed on /debug/pprof" + - linters: + - revive + text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported" + - linters: + - errcheck + text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked + - linters: + - staticcheck + text: "SA1019: .*The component config package has been deprecated and will be removed in a future release." + # With Go 1.16, the new embed directive can be used with an un-named import, + # revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us. + # This directive allows the embed package to be imported with an underscore everywhere. + - linters: + - revive + source: _ "embed" + # Exclude some packages or code to require comments, for example test code, or fake clients. + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + source: (func|type).*Fake.* + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + path: fake_\.go + # Disable unparam "always receives" which might not be really + # useful when building libraries. + - linters: + - unparam + text: always receives + # Dot imports for gomega and ginkgo are allowed + # within test files. + - path: _test\.go + text: should not use dot imports + - path: _test\.go + text: cyclomatic complexity + - path: _test\.go + text: "G107: Potential HTTP request made with variable url" + # Append should be able to assign to a different var/slice. + - linters: + - gocritic + text: "appendAssign: append result not assigned to the same slice" + - linters: + - gocritic + text: "singleCaseSwitch: should rewrite switch statement to if statement" + # It considers all file access to a filename that comes from a variable problematic, + # which is naiv at best. + - linters: + - gosec + text: "G304: Potential file inclusion via variable" + - linters: + - dupl + path: _test\.go + +run: + timeout: 10m + skip-files: + - "zz_generated.*\\.go$" + - ".*conversion.*\\.go$" + allow-parallel-runners: true diff --git a/third_party/sigs.k8s.io/controller-runtime/CONTRIBUTING.md b/third_party/sigs.k8s.io/controller-runtime/CONTRIBUTING.md new file mode 100644 index 00000000000..2c0ea1f6674 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contributing guidelines + +## Sign the CLA + +Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests. + +Please see https://git.k8s.io/community/CLA.md for more info + +## Contributing steps + +1. Submit an issue describing your proposed change to the repo in question. +1. The [repo owners](OWNERS) will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Submit a pull request. + +## Test locally + +Run the command `make test` to test the changes locally. diff --git a/third_party/sigs.k8s.io/controller-runtime/FAQ.md b/third_party/sigs.k8s.io/controller-runtime/FAQ.md new file mode 100644 index 00000000000..c21b29e287a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/FAQ.md @@ -0,0 +1,81 @@ +# FAQ + +### Q: How do I know which type of object a controller references? + +**A**: Each controller should only reconcile one object type. Other +affected objects should be mapped to a single type of root object, using +the `EnqueueRequestForOwner` or `EnqueueRequestsFromMapFunc` event +handlers, and potentially indices. Then, your Reconcile method should +attempt to reconcile *all* state for that given root objects. + +### Q: How do I have different logic in my reconciler for different types of events (e.g. create, update, delete)? + +**A**: You should not. Reconcile functions should be idempotent, and +should always reconcile state by reading all the state it needs, then +writing updates. This allows your reconciler to correctly respond to +generic events, adjust to skipped or coalesced events, and easily deal +with application startup. The controller will enqueue reconcile requests +for both old and new objects if a mapping changes, but it's your +responsibility to make sure you have enough information to be able clean +up state that's no longer referenced. + +### Q: My cache might be stale if I read from a cache! How should I deal with that? + +**A**: There are several different approaches that can be taken, depending +on your situation. + +- When you can, take advantage of optimistic locking: use deterministic + names for objects you create, so that the Kubernetes API server will + warn you if the object already exists. Many controllers in Kubernetes + take this approach: the StatefulSet controller appends a specific number + to each pod that it creates, while the Deployment controller hashes the + pod template spec and appends that. + +- In the few cases when you cannot take advantage of deterministic names + (e.g. when using generateName), it may be useful in to track which + actions you took, and assume that they need to be repeated if they don't + occur after a given time (e.g. using a requeue result). This is what + the ReplicaSet controller does. + +In general, write your controller with the assumption that information +will eventually be correct, but may be slightly out of date. Make sure +that your reconcile function enforces the entire state of the world each +time it runs. If none of this works for you, you can always construct +a client that reads directly from the API server, but this is generally +considered to be a last resort, and the two approaches above should +generally cover most circumstances. + +### Q: Where's the fake client? How do I use it? + +**A**: The fake client +[exists](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client/fake), +but we generally recommend using +[envtest.Environment](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#Environment) +to test against a real API server. In our experience, tests using fake +clients gradually re-implement poorly-written impressions of a real API +server, which leads to hard-to-maintain, complex test code. + +### Q: How should I write tests? Any suggestions for getting started? + +- Use the aforementioned + [envtest.Environment](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#Environment) + to spin up a real API server instead of trying to mock one out. + +- Structure your tests to check that the state of the world is as you + expect it, *not* that a particular set of API calls were made, when + working with Kubernetes APIs. This will allow you to more easily + refactor and improve the internals of your controllers without changing + your tests. + +- Remember that any time you're interacting with the API server, changes + may have some delay between write time and reconcile time. + +### Q: What are these errors about no Kind being registered for a type? + +**A**: You're probably missing a fully-set-up Scheme. Schemes record the +mapping between Go types and group-version-kinds in Kubernetes. In +general, your application should have its own Scheme containing the types +from the API groups that it needs (be they Kubernetes types or your own). +See the [scheme builder +docs](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/scheme) for +more information. diff --git a/third_party/sigs.k8s.io/controller-runtime/FORK_INFO.md b/third_party/sigs.k8s.io/controller-runtime/FORK_INFO.md new file mode 100644 index 00000000000..d6f185c930f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/FORK_INFO.md @@ -0,0 +1,3 @@ +This is a fork of controller runtime made from the following commit: + +commit 116a1b831fffe7ccc3c8145306c3e1a3b1b14ffa (HEAD, tag: v0.15.0) diff --git a/third_party/sigs.k8s.io/controller-runtime/Makefile b/third_party/sigs.k8s.io/controller-runtime/Makefile new file mode 100644 index 00000000000..71ec644de02 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/Makefile @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +# Copyright 2020 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# If you update this file, please follow +# https://suva.sh/posts/well-documented-makefiles + +## -------------------------------------- +## General +## -------------------------------------- + +SHELL:=/usr/bin/env bash +.DEFAULT_GOAL:=help + +# Use GOPROXY environment variable if set +GOPROXY := $(shell go env GOPROXY) +ifeq ($(GOPROXY),) +GOPROXY := https://proxy.golang.org +endif +export GOPROXY + +# Active module mode, as we use go modules to manage dependencies +export GO111MODULE=on + +# Tools. +TOOLS_DIR := hack/tools +TOOLS_BIN_DIR := $(TOOLS_DIR)/bin +GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/golangci-lint) +GO_APIDIFF := $(TOOLS_BIN_DIR)/go-apidiff +CONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen +ENVTEST_DIR := $(abspath tools/setup-envtest) + +# The help will print out all targets with their descriptions organized bellow their categories. The categories are represented by `##@` and the target descriptions by `##`. +# The awk commands is responsible to read the entire set of makefiles included in this invocation, looking for lines of the file as xyz: ## something, and then pretty-format the target and help. Then, if there's a line with ##@ something, that gets pretty-printed as a category. +# More info over the usage of ANSI control characters for terminal formatting: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info over awk command: http://linuxcommand.org/lc3_adv_awk.php +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +## -------------------------------------- +## Testing +## -------------------------------------- + +.PHONY: test +test: test-tools ## Run the script check-everything.sh which will check all. + TRACE=1 ./hack/check-everything.sh + +.PHONY: test-tools +test-tools: ## tests the tools codebase (setup-envtest) + cd tools/setup-envtest && go test ./... + +## -------------------------------------- +## Binaries +## -------------------------------------- + +$(GO_APIDIFF): $(TOOLS_DIR)/go.mod # Build go-apidiff from tools folder. + cd $(TOOLS_DIR) && go build -tags=tools -o bin/go-apidiff github.com/joelanford/go-apidiff + +$(CONTROLLER_GEN): $(TOOLS_DIR)/go.mod # Build controller-gen from tools folder. + cd $(TOOLS_DIR) && go build -tags=tools -o bin/controller-gen sigs.k8s.io/controller-tools/cmd/controller-gen + +$(GOLANGCI_LINT): .github/workflows/golangci-lint.yml # Download golanci-lint using hack script into tools folder. + hack/ensure-golangci-lint.sh \ + -b $(TOOLS_BIN_DIR) \ + $(shell cat .github/workflows/golangci-lint.yml | grep "version: v" | sed 's/.*version: //') + +## -------------------------------------- +## Linting +## -------------------------------------- + +.PHONY: lint +lint: $(GOLANGCI_LINT) ## Lint codebase + $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS) + cd tools/setup-envtest; $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS) + +.PHONY: lint-fix +lint-fix: $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linter. + GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint + +## -------------------------------------- +## Generate +## -------------------------------------- + +.PHONY: modules +modules: ## Runs go mod to ensure modules are up to date. + go mod tidy + cd $(TOOLS_DIR); go mod tidy + cd $(ENVTEST_DIR); go mod tidy + +.PHONY: generate +generate: $(CONTROLLER_GEN) ## Runs controller-gen for internal types for config file + $(CONTROLLER_GEN) object paths="./pkg/config/v1alpha1/...;./examples/configfile/custom/v1alpha1/..." + +## -------------------------------------- +## Cleanup / Verification +## -------------------------------------- + +.PHONY: clean +clean: ## Cleanup. + $(MAKE) clean-bin + +.PHONY: clean-bin +clean-bin: ## Remove all generated binaries. + rm -rf hack/tools/bin + +.PHONY: verify-modules +verify-modules: modules ## Verify go modules are up to date + @if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum $(ENVTEST_DIR)/go.mod $(ENVTEST_DIR)/go.sum); then \ + git diff; \ + echo "go module files are out of date, please run 'make modules'"; exit 1; \ + fi + +.PHONY: verify-generate +verify-generate: generate ## Verify generated files are up to date + @if !(git diff --quiet HEAD); then \ + git diff; \ + echo "generated files are out of date, run make generate"; exit 1; \ + fi diff --git a/third_party/sigs.k8s.io/controller-runtime/OWNERS b/third_party/sigs.k8s.io/controller-runtime/OWNERS new file mode 100644 index 00000000000..4b1fa044bf7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +approvers: + - controller-runtime-admins + - controller-runtime-maintainers + - controller-runtime-approvers +reviewers: + - controller-runtime-admins + - controller-runtime-reviewers + - controller-runtime-approvers diff --git a/third_party/sigs.k8s.io/controller-runtime/OWNERS_ALIASES b/third_party/sigs.k8s.io/controller-runtime/OWNERS_ALIASES new file mode 100644 index 00000000000..7848941d534 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/OWNERS_ALIASES @@ -0,0 +1,41 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +aliases: + # active folks who can be contacted to perform admin-related + # tasks on the repo, or otherwise approve any PRS. + controller-runtime-admins: + - vincepri + - joelanford + + # non-admin folks who have write-access and can approve any PRs in the repo + controller-runtime-maintainers: + - alvaroaleman + - joelanford + - sbueringer + - vincepri + + # non-admin folks who can approve any PRs in the repo + controller-runtime-approvers: + - fillzpp + + # folks who can review and LGTM any PRs in the repo (doesn't + # include approvers & admins -- those count too via the OWNERS + # file) + controller-runtime-reviewers: + - varshaprasad96 + - inteon + + # folks to can approve things in the directly-ported + # testing_frameworks portions of the codebase + testing-integration-approvers: + - apelisse + - hoegaarden + + # folks who may have context on ancient history, + # but are no longer directly involved + controller-runtime-emeritus-maintainers: + - directxman12 + controller-runtime-emeritus-admins: + - droot + - mengqiy + - pwittrock diff --git a/third_party/sigs.k8s.io/controller-runtime/README.md b/third_party/sigs.k8s.io/controller-runtime/README.md index 1e6f62398f3..e785abdd77b 100644 --- a/third_party/sigs.k8s.io/controller-runtime/README.md +++ b/third_party/sigs.k8s.io/controller-runtime/README.md @@ -1,10 +1,66 @@ -# sigs.k8s.io/controller-runtime +[![Go Report Card](https://goreportcard.com/badge/sigs.k8s.io/controller-runtime)](https://goreportcard.com/report/sigs.k8s.io/controller-runtime) +[![godoc](https://pkg.go.dev/badge/sigs.k8s.io/controller-runtime)](https://pkg.go.dev/sigs.k8s.io/controller-runtime) -Forked from sigs.k8s.io/controller-runtime@a8c19c49e49cfba2aa486ff322cbe5222d6da533 (v0.8.2). +# Kubernetes controller-runtime Project -This fork adds the ability to dynamically -remove informers from the informer cache. Additionally, non-blocking APIs were added to fetch informers -without waiting for cache sync. `pkg/cache` was renamed to `pkg/dynamiccache` for clarity. +The Kubernetes controller-runtime Project is a set of go libraries for building +Controllers. It is leveraged by [Kubebuilder](https://book.kubebuilder.io/) and +[Operator SDK](https://github.com/operator-framework/operator-sdk). Both are +a great place to start for new projects. See +[Kubebuilder's Quick Start](https://book.kubebuilder.io/quick-start.html) to +see how it can be used. -The original code can be found at https://github.com/kubernetes-sigs/controller-runtime/tree/v0.8.2/pkg/cache. +Documentation: +- [Package overview](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg) +- [Basic controller using builder](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder#example-Builder) +- [Creating a manager](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#example-New) +- [Creating a controller](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller#example-New) +- [Examples](https://github.com/kubernetes-sigs/controller-runtime/blob/main/examples) +- [Designs](https://github.com/kubernetes-sigs/controller-runtime/blob/main/designs) + +# Versioning, Maintenance, and Compatibility + +The full documentation can be found at [VERSIONING.md](VERSIONING.md), but TL;DR: + +Users: + +- We follow [Semantic Versioning (semver)](https://semver.org) +- Use releases with your dependency management to ensure that you get compatible code +- The main branch contains all the latest code, some of which may break compatibility (so "normal" `go get` is not recommended) + +Contributors: + +- All code PR must be labeled with :bug: (patch fixes), :sparkles: (backwards-compatible features), or :warning: (breaking changes) +- Breaking changes will find their way into the next major release, other changes will go into an semi-immediate patch or minor release +- For a quick PR template suggesting the right information, use one of these PR templates: + * [Breaking Changes/Features](/.github/PULL_REQUEST_TEMPLATE/breaking_change.md) + * [Backwards-Compatible Features](/.github/PULL_REQUEST_TEMPLATE/compat_feature.md) + * [Bug fixes](/.github/PULL_REQUEST_TEMPLATE/bug_fix.md) + * [Documentation Changes](/.github/PULL_REQUEST_TEMPLATE/docs.md) + * [Test/Build/Other Changes](/.github/PULL_REQUEST_TEMPLATE/other.md) + +## FAQ + +See [FAQ.md](FAQ.md) + +## Community, discussion, contribution, and support + +Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). + +controller-runtime is a subproject of the [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) project +in sig apimachinery. + +You can reach the maintainers of this project at: + +- Slack channel: [#controller-runtime](https://kubernetes.slack.com/archives/C02MRBMN00Z) +- Google Group: [kubebuilder@googlegroups.com](https://groups.google.com/forum/#!forum/kubebuilder) + +## Contributing +Contributions are greatly appreciated. The maintainers actively manage the issues list, and try to highlight issues suitable for newcomers. +The project follows the typical GitHub pull request model. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. +Before starting any work, please either comment on an existing issue, or file a new one. + +## Code of conduct + +Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). diff --git a/third_party/sigs.k8s.io/controller-runtime/RELEASE.md b/third_party/sigs.k8s.io/controller-runtime/RELEASE.md new file mode 100644 index 00000000000..f234494fe1c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/RELEASE.md @@ -0,0 +1,47 @@ +# Release Process + +The Kubernetes controller-runtime Project is released on an as-needed basis. The process is as follows: + +**Note:** Releases are done from the `release-MAJOR.MINOR` branches. For PATCH releases is not required +to create a new branch you will just need to ensure that all big fixes are cherry-picked into the respective +`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/. + +## How to do a release + +### Create the new branch and the release tag + +1. Create a new branch `git checkout -b release-` from main +2. Push the new branch to the remote repository + +### Now, let's generate the changelog + +1. Create the changelog from the new branch `release-` (`git checkout release-`). +You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools] to generate the notes. See [here][release-notes-generation] + +> **Note** +> - You will need to have checkout locally from the remote repository the previous branch +> - Also, ensure that you fetch all tags from the remote `git fetch --all --tags` + +### Draft a new release from GitHub + +1. Create a new tag with the correct version from the new `release-` branch +2. Add the changelog on it and publish. Now, the code source is released ! + +### Add a new Prow test the for the new branch release + +1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime) +for the new `release-` branch. (i.e. for the `0.11.0` release see the PR: https://github.com/kubernetes/test-infra/pull/25205) +2. Ping the infra PR in the controller-runtime slack channel for reviews. + +### Announce the new release: + +1. Publish on the Slack channel the new release, i.e: + +```` +:announce: Controller-Runtime v0.12.0 has been released! +This release includes a Kubernetes dependency bump to v1.24. +For more info, see the release page: https://github.com/kubernetes-sigs/controller-runtime/releases. + :tada: Thanks to all our contributors! +```` + +2. An announcement email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Controller-Runtime $VERSION is released` diff --git a/third_party/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS b/third_party/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS new file mode 100644 index 00000000000..9c5241c6b42 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS @@ -0,0 +1,15 @@ +# Defined below are the security contacts for this repo. +# +# They are the contact point for the Product Security Team to reach out +# to for triaging and handling of incoming issues. +# +# The below names agree to abide by the +# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy) +# and will be removed and replaced if they violate that agreement. +# +# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE +# INSTRUCTIONS AT https://kubernetes.io/security/ + +alvaroaleman +sbueringer +vincepri diff --git a/third_party/sigs.k8s.io/controller-runtime/TMP-LOGGING.md b/third_party/sigs.k8s.io/controller-runtime/TMP-LOGGING.md new file mode 100644 index 00000000000..97e091fd48a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/TMP-LOGGING.md @@ -0,0 +1,169 @@ +Logging Guidelines +================== + +controller-runtime uses a kind of logging called *structured logging*. If +you've used a library like Zap or logrus before, you'll be familiar with +the concepts we use. If you've only used a logging library like the "log" +package (in the Go standard library) or "glog" (in Kubernetes), you'll +need to adjust how you think about logging a bit. + +### Getting Started With Structured Logging + +With structured logging, we associate a *constant* log message with some +variable key-value pairs. For instance, suppose we wanted to log that we +were starting reconciliation on a pod. In the Go standard library logger, +we might write: + +```go +log.Printf("starting reconciliation for pod %s/%s", podNamespace, podName) +``` + +In controller-runtime, we'd instead write: + +```go +logger.Info("starting reconciliation", "pod", req.NamespacedName) +``` + +or even write + +```go +func (r *Reconciler) Reconcile(req reconcile.Request) (reconcile.Response, error) { + logger := logger.WithValues("pod", req.NamespacedName) + // do some stuff + logger.Info("starting reconciliation") +} +``` + +Notice how we've broken out the information that we want to convey into +a constant message (`"starting reconciliation"`) and some key-value pairs +that convey variable information (`"pod", req.NamespacedName`). We've +there-by added "structure" to our logs, which makes them easier to save +and search later, as well as correlate with metrics and events. + +All of controller-runtime's logging is done via +[logr](https://github.com/go-logr/logr), a generic interface for +structured logging. You can use whichever logging library you want to +implement the actual mechanics of the logging. controller-runtime +provides some helpers to make it easy to use +[Zap](https://go.uber.org/zap) as the implementation. + +You can configure the logging implementation using +`"sigs.k8s.io/controller-runtime/pkg/log".SetLogger`. That +package also contains the convenience functions for setting up Zap. + +You can get a handle to the "root" logger using +`"sigs.k8s.io/controller-runtime/pkg/log".Log`, and can then call +`WithName` to create individual named loggers. You can call `WithName` +repeatedly to chain names together: + +```go +logger := log.Log.WithName("controller").WithName("replicaset") +// in reconcile... +logger = logger.WithValues("replicaset", req.NamespacedName) +// later on in reconcile... +logger.Info("doing things with pods", "pod", newPod) +``` + +As seen above, you can also call `WithValue` to create a new sub-logger +that always attaches some key-value pairs to a logger. + +Finally, you can use `V(1)` to mark a particular log line as "debug" logs: + +```go +logger.V(1).Info("this is particularly verbose!", "state of the world", +allKubernetesObjectsEverywhere) +``` + +While it's possible to use higher log levels, it's recommended that you +stick with `V(1)` or `V(0)` (which is equivalent to not specifying `V`), +and then filter later based on key-value pairs or messages; different +numbers tend to lose meaning easily over time, and you'll be left +wondering why particular logs lines are at `V(5)` instead of `V(7)`. + +## Logging errors + +Errors should *always* be logged with `log.Error`, which allows logr +implementations to provide special handling of errors (for instance, +providing stack traces in debug mode). + +It's acceptable to log call `log.Error` with a nil error object. This +conveys that an error occurred in some capacity, but that no actual +`error` object was involved. + +Errors returned by the `Reconcile` implementation of the `Reconciler` interface are commonly logged as a `Reconciler error`. +It's a developer choice to create an additional error log in the `Reconcile` implementation so a more specific file name and line for the error are returned. + +## Logging messages + +- Don't put variable content in your messages -- use key-value pairs for + that. Never use `fmt.Sprintf` in your message. + +- Try to match the terminology in your messages with your key-value pairs + -- for instance, if you have a key-value pairs `api version`, use the + term `APIVersion` instead of `GroupVersion` in your message. + +## Logging Kubernetes Objects + +Kubernetes objects should be logged directly, like `log.Info("this is +a Kubernetes object", "pod", somePod)`. controller-runtime provides +a special encoder for Zap that will transform Kubernetes objects into +`name, namespace, apiVersion, kind` objects, when available and not in +development mode. Other logr implementations should implement similar +logic. + +## Logging Structured Values (Key-Value pairs) + +- Use lower-case, space separated keys. For example `object` for objects, + `api version` for `APIVersion` + +- Be consistent across your application, and with controller-runtime when + possible. + +- Try to be brief but descriptive. + +- Match terminology in keys with terminology in the message. + +- Be careful logging non-Kubernetes objects verbatim if they're very + large. + +### Groups, Versions, and Kinds + +- Kinds should not be logged alone (they're meaningless alone). Use + a `GroupKind` object to log them instead, or a `GroupVersionKind` when + version is relevant. + +- If you need to log an API version string, use `api version` as the key + (formatted as with a `GroupVersion`, or as received directly from API + discovery). + +### Objects and Types + +- If code works with a generic Kubernetes `runtime.Object`, use the + `object` key. For specific objects, prefer the resource name as the key + (e.g. `pod` for `v1.Pod` objects). + +- For non-Kubernetes objects, the `object` key may also be used, if you + accept a generic interface. + +- When logging a raw type, log it using the `type` key, with a value of + `fmt.Sprintf("%T", typ)` + +- If there's specific context around a type, the key may be more specific, + but should end with `type` -- for instance, `OwnerType` should be logged + as `owner` in the context of `log.Error(err, "Could not get ObjectKinds + for OwnerType", `owner type`, fmt.Sprintf("%T"))`. When possible, favor + communicating kind instead. + +### Multiple things + +- When logging multiple things, simply pluralize the key. + +### controller-runtime Specifics + +- Reconcile requests should be logged as `request`, although normal code + should favor logging the key. + +- Reconcile keys should be logged as with the same key as if you were + logging the object directly (e.g. `log.Info("reconciling pod", "pod", + req.NamespacedName)`). This ends up having a similar effect to logging + the object directly. diff --git a/third_party/sigs.k8s.io/controller-runtime/VERSIONING.md b/third_party/sigs.k8s.io/controller-runtime/VERSIONING.md new file mode 100644 index 00000000000..18779000ec2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/VERSIONING.md @@ -0,0 +1,30 @@ +# Versioning and Branching in controller-runtime + +We follow the [common KubeBuilder versioning guidelines][guidelines], and +use the corresponding tooling. + +For the purposes of the aforementioned guidelines, controller-runtime +counts as a "library project", but otherwise follows the guidelines +exactly. + +[guidelines]: https://sigs.k8s.io/kubebuilder-release-tools/VERSIONING.md + +## Compatiblity and Release Support + +For release branches, we generally tend to support backporting one (1) +major release (`release-{X-1}` or `release-0.{Y-1}`), but may go back +further if the need arises and is very pressing (e.g. security updates). + +### Dependency Support + +Note the [guidelines on dependency versions][dep-versions]. Particularly: + +- We **DO** guarantee Kubernetes REST API compability -- if a given + version of controller-runtime stops working with what should be + a supported version of Kubernetes, this is almost certainly a bug. + +- We **DO NOT** guarantee any particular compability matrix between + kubernetes library dependencies (client-go, apimachinery, etc); Such + compability is infeasible due to the way those libraries are versioned. + +[dep-versions]: https://sigs.k8s.io/kubebuilder-release-tools/VERSIONING.md#kubernetes-version-compatibility diff --git a/third_party/sigs.k8s.io/controller-runtime/alias.go b/third_party/sigs.k8s.io/controller-runtime/alias.go new file mode 100644 index 00000000000..237963889c7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/alias.go @@ -0,0 +1,156 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerruntime + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client/config" + cfg "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +// Builder builds an Application ControllerManagedBy (e.g. Operator) and returns a manager.Manager to start it. +type Builder = builder.Builder + +// Request contains the information necessary to reconcile a Kubernetes object. This includes the +// information to uniquely identify the object - its Name and Namespace. It does NOT contain information about +// any specific Event or the object contents itself. +type Request = reconcile.Request + +// Result contains the result of a Reconciler invocation. +type Result = reconcile.Result + +// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables. +// A Manager is required to create Controllers. +type Manager = manager.Manager + +// Options are the arguments for creating a new Manager. +type Options = manager.Options + +// SchemeBuilder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds. +type SchemeBuilder = scheme.Builder + +// GroupVersion contains the "group" and the "version", which uniquely identifies the API. +type GroupVersion = schema.GroupVersion + +// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying +// concepts during lookup stages without having partially valid types. +type GroupResource = schema.GroupResource + +// TypeMeta describes an individual object in an API response or request +// with strings representing the type of the object and its API schema version. +// Structures that are versioned or persisted should inline TypeMeta. +// +// +k8s:deepcopy-gen=false +type TypeMeta = metav1.TypeMeta + +// ObjectMeta is metadata that all persisted resources must have, which includes all objects +// users must create. +type ObjectMeta = metav1.ObjectMeta + +var ( + // RegisterFlags registers flag variables to the given FlagSet if not already registered. + // It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. + RegisterFlags = config.RegisterFlags + + // GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. + // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running + // in cluster and use the cluster provided kubeconfig. + // + // Will log an error and exit if there is an error creating the rest.Config. + GetConfigOrDie = config.GetConfigOrDie + + // GetConfig creates a *rest.Config for talking to a Kubernetes apiserver. + // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running + // in cluster and use the cluster provided kubeconfig. + // + // Config precedence + // + // * --kubeconfig flag pointing at a file + // + // * KUBECONFIG environment variable pointing at a file + // + // * In-cluster config if running in cluster + // + // * $HOME/.kube/config if exists. + GetConfig = config.GetConfig + + // ConfigFile returns the cfg.File function for deferred config file loading, + // this is passed into Options{}.From() to populate the Options fields for + // the manager. + // + // Deprecated: This is deprecated in favor of using Options directly. + ConfigFile = cfg.File + + // NewControllerManagedBy returns a new controller builder that will be started by the provided Manager. + NewControllerManagedBy = builder.ControllerManagedBy + + // NewWebhookManagedBy returns a new webhook builder that will be started by the provided Manager. + NewWebhookManagedBy = builder.WebhookManagedBy + + // NewManager returns a new Manager for creating Controllers. + NewManager = manager.New + + // CreateOrUpdate creates or updates the given object obj in the Kubernetes + // cluster. The object's desired state should be reconciled with the existing + // state using the passed in ReconcileFn. obj must be a struct pointer so that + // obj can be updated with the content returned by the Server. + // + // It returns the executed operation and an error. + CreateOrUpdate = controllerutil.CreateOrUpdate + + // SetControllerReference sets owner as a Controller OwnerReference on owned. + // This is used for garbage collection of the owned object and for + // reconciling the owner object on changes to owned (with a Watch + EnqueueRequestForOwner). + // Since only one OwnerReference can be a controller, it returns an error if + // there is another OwnerReference with Controller flag set. + SetControllerReference = controllerutil.SetControllerReference + + // SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned + // which is closed on one of these signals. If a second signal is caught, the program + // is terminated with exit code 1. + SetupSignalHandler = signals.SetupSignalHandler + + // Log is the base logger used by controller-runtime. It delegates + // to another logr.Logger. You *must* call SetLogger to + // get any actual logging. + Log = log.Log + + // LoggerFrom returns a logger with predefined values from a context.Context. + // The logger, when used with controllers, can be expected to contain basic information about the object + // that's being reconciled like: + // - `reconciler group` and `reconciler kind` coming from the For(...) object passed in when building a controller. + // - `name` and `namespace` from the reconciliation request. + // + // This is meant to be used with the context supplied in a struct that satisfies the Reconciler interface. + LoggerFrom = log.FromContext + + // LoggerInto takes a context and sets the logger as one of its keys. + // + // This is meant to be used in reconcilers to enrich the logger within a context with additional values. + LoggerInto = log.IntoContext + + // SetLogger sets a concrete logging implementation for all deferred Loggers. + SetLogger = log.SetLogger +) diff --git a/third_party/sigs.k8s.io/controller-runtime/code-of-conduct.md b/third_party/sigs.k8s.io/controller-runtime/code-of-conduct.md new file mode 100644 index 00000000000..0d15c00cf32 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/README.md b/third_party/sigs.k8s.io/controller-runtime/designs/README.md new file mode 100644 index 00000000000..bf8b5000a9a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/designs/README.md @@ -0,0 +1,36 @@ +Designs +======= + +These are the design documents for changes to Controller Runtime. They +exist to help document the design processes that go into writing +Controller Runtime, but may not be up-to-date (more below). + +Not all changes to Controller Runtime need a design document -- only major +ones. Use your best judgement. + +When submitting a design document, we encourage having written +a proof-of-concept, and it's perfectly acceptable to submit the +proof-of-concept PR simultaneously with the design document, as the +proof-of-concept process can help iron out wrinkles and can help with the +`Example` section of the template. + +## Out-of-Date Designs + +**Controller Runtime documentation +[GoDoc](https://pkg.go.dev/sigs.k8s.io/controller-runtime) should be +considered the canonical, update-to-date reference and architectural +documentation** for Controller Runtime. + +However, if you see an out-of-date design document, feel free to submit +a PR marking it as such, and add an addendum linking to issues documenting +why things changed. For example: + +```markdown + +# Out of Date + +This change is out of date. It turns out curly braces are frustrating to +type, so we had to abandon functions entirely, and have users specify +custom functionality using strings of Common LISP instead. See #000 for +more information. +``` diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/component-config.md b/third_party/sigs.k8s.io/controller-runtime/designs/component-config.md new file mode 100644 index 00000000000..8aebec4f960 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/designs/component-config.md @@ -0,0 +1,320 @@ +# ComponentConfig Controller Runtime Support +Author: @christopherhein + +Last Updated on: 03/02/2020 + +## Table of Contents + + + * [ComponentConfig Controller Runtime Support](#componentconfig-controller-runtime-support) + * [Table of Contents](#table-of-contents) + * [Summary](#summary) + * [Motivation](#motivation) + * [Links to Open Issues](#links-to-open-issues) + * [Goals](#goals) + * [Non-Goals/Future Work](#non-goalsfuture-work) + * [Proposal](#proposal) + * [ComponentConfig Load Order](#componentconfig-load-order) + * [Embeddable ComponentConfig Type](#embeddable-componentconfig-type) + * [Default ComponentConfig Type](#default-componentconfig-type) + * [Using Flags w/ ComponentConfig](#using-flags-w-componentconfig) + * [Kubebuilder Scaffolding Example](#kubebuilder-scaffolding-example) + * [User Stories](#user-stories) + * [Controller Author with controller-runtime and default type](#controller-author-with-controller-runtime-and-default-type) + * [Controller Author with controller-runtime and custom type](#controller-author-with-controller-runtime-and-custom-type) + * [Controller Author with kubebuilder (tbd proposal for kubebuilder)](#controller-author-with-kubebuilder-tbd-proposal-for-kubebuilder) + * [Controller User without modifications to config](#controller-user-without-modifications-to-config) + * [Controller User with modifications to config](#controller-user-with-modifications-to-config) + * [Risks and Mitigations](#risks-and-mitigations) + * [Alternatives](#alternatives) + * [Implementation History](#implementation-history) + + + +## Summary + +Currently controllers that use `controller-runtime` need to configure the `ctrl.Manager` by using flags or hardcoding values into the initialization methods. Core Kubernetes has started to move away from using flags as a mechanism for configuring components and standardized on [`ComponentConfig` or Versioned Component Configuration Files](https://docs.google.com/document/d/1FdaEJUEh091qf5B98HM6_8MS764iXrxxigNIdwHYW9c/edit). This proposal is to bring `ComponentConfig` to `controller-runtime` to allow controller authors to make `go` types backed by `apimachinery` to unmarshal and configure the `ctrl.Manager{}` reducing the flags and allowing code based tools to easily configure controllers instead of requiring them to mutate CLI args. + +## Motivation + +This change is important because: +- it will help make it easier for controllers to be configured by other machine processes +- it will reduce the required flags required to start a controller +- allow for configuration types which aren't natively supported by flags +- allow using and upgrading older configurations avoiding breaking changes in flags + +### Links to Open Issues + +- [#518 Provide a ComponentConfig to tweak the Manager](https://github.com/kubernetes-sigs/controller-runtime/issues/518) +- [#207 Reduce command line flag boilerplate](https://github.com/kubernetes-sigs/controller-runtime/issues/207) +- [#722 Implement ComponentConfig by default & stop using (most) flags](https://github.com/kubernetes-sigs/kubebuilder/issues/722) + +### Goals + +- Provide an interface for pulling configuration data out of exposed `ComponentConfig` types (see below for implementation) +- Provide a new `ctrl.NewFromComponentConfig()` function for initializing a manager +- Provide an embeddable `ControllerManagerConfiguration` type for easily authoring `ComponentConfig` types +- Provide an `DefaultControllerConfig` to make the switching easier for clients + +### Non-Goals/Future Work + +- `kubebuilder` implementation and design in another PR +- Changing the default `controller-runtime` implementation +- Dynamically reloading `ComponentConfig` object +- Providing `flags` interface and overrides + +## Proposal + +The `ctrl.Manager` _SHOULD_ support loading configurations from `ComponentConfig` like objects. +An interface for that object with getters for the specific configuration parameters is created to bridge existing patterns. + +Without breaking the current `ctrl.NewManager` which uses an exported `ctrl.Options{}` the `manager.go` can expose a new func, `NewFromComponentConfig()` this would be able to loop through the getters to populate an internal `ctrl.Options{}` and pass that into `New()`. + +```golang +//pkg/manager/manager.go + +// ManagerConfiguration defines what the ComponentConfig object for ControllerRuntime needs to support +type ManagerConfiguration interface { + GetSyncPeriod() *time.Duration + + GetLeaderElection() bool + GetLeaderElectionNamespace() string + GetLeaderElectionID() string + + GetLeaseDuration() *time.Duration + GetRenewDeadline() *time.Duration + GetRetryPeriod() *time.Duration + + GetNamespace() string + GetMetricsBindAddress() string + GetHealthProbeBindAddress() string + + GetReadinessEndpointName() string + GetLivenessEndpointName() string + + GetPort() int + GetHost() string + + GetCertDir() string +} + +func NewFromComponentConfig(config *rest.Config, scheme *runtime.Scheme, filename string, managerconfig ManagerConfiguration) (Manager, error) { + codecs := serializer.NewCodecFactory(scheme) + if err := decodeComponentConfigFileInto(codecs, filename, managerconfig); err != nil { + + } + options := Options{} + + if scheme != nil { + options.Scheme = scheme + } + + // Loop through getters + if managerconfig.GetLeaderElection() { + options.LeaderElection = managerconfig.GetLeaderElection() + } + // ... + + return New(config, options) +} +``` + +#### ComponentConfig Load Order + +![ComponentConfig Load Order](/designs/images/component-config-load.png) + +#### Embeddable ComponentConfig Type + +To make this easier for Controller authors `controller-runtime` can expose a set of `config.ControllerConfiguration` type that can be embedded similar to the way that `k8s.io/apimachinery/pkg/apis/meta/v1` works for `TypeMeta` and `ObjectMeta` these could live in `pkg/api/config/v1alpha1/types.go`. See the `DefaultComponentConfig` type below for and example implementation. + +```golang +// pkg/api/config/v1alpha1/types.go +package v1alpha1 + +import ( + "time" + + configv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// ControllerManagerConfiguration defines the embedded RuntimeConfiguration for controller-runtime clients. +type ControllerManagerConfiguration struct { + Namespace string `json:"namespace,omitempty"` + + SyncPeriod *time.Duration `json:"syncPeriod,omitempty"` + + LeaderElection configv1alpha1.LeaderElectionConfiguration `json:"leaderElection,omitempty"` + + MetricsBindAddress string `json:"metricsBindAddress,omitempty"` + + Health ControllerManagerConfigurationHealth `json:"health,omitempty"` + + Port *int `json:"port,omitempty"` + Host string `json:"host,omitempty"` + + CertDir string `json:"certDir,omitempty"` +} + +// ControllerManagerConfigurationHealth defines the health configs +type ControllerManagerConfigurationHealth struct { + HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` + + ReadinessEndpointName string `json:"readinessEndpointName,omitempty"` + LivenessEndpointName string `json:"livenessEndpointName,omitempty"` +} +``` + + + +#### Default ComponentConfig Type + +To enable `controller-runtime` to have a default `ComponentConfig` struct which can be used instead of requiring each controller or extension to build its own `ComponentConfig` type, we can create a `DefaultControllerConfiguration` type which can exist in `pkg/api/config/v1alpha1/types.go`. This will allow the controller authors to use this before needing to implement their own type with additional configs. + +```golang +// pkg/api/config/v1alpha1/types.go +package v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + configv1alpha1 "sigs.k8s.io/controller-runtime/pkg/apis/config/v1alpha1" +) + +// DefaultControllerManagerConfiguration is the Schema for the DefaultControllerManagerConfigurations API +type DefaultControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + Spec configv1alpha1.ControllerManagerConfiguration `json:"spec,omitempty"` +} +``` + +This would allow a controller author to use this struct with any config that supports the json/yaml structure. For example a controller author could define their `Kind` as `FoobarControllerConfiguration` and have it defined as the following. + +```yaml +# config.yaml +apiVersion: config.somedomain.io/v1alpha1 +kind: FoobarControllerManagerConfiguration +spec: + port: 9443 + metricsBindAddress: ":8080" + leaderElection: + leaderElect: false +``` + +Given the following config and `DefaultControllerManagerConfiguration` we'd be able to initialize the controller using the following. + + +```golang +mgr, err := ctrl.NewManagerFromComponentConfig(ctrl.GetConfigOrDie(), scheme, configname, &defaultv1alpha1.DefaultControllerManagerConfiguration{}) +if err != nil { + // ... +} +``` + +The above example uses `configname` which is the name of the file to load the configuration from and uses `scheme` to get the specific serializer, eg `serializer.NewCodecFactory(scheme)`. This will allow the configuration to be unmarshalled into the `runtime.Object` type and passed into the +`ctrl.NewManagerFromComponentConfig()` as a `ManagerConfiguration` interface. + +#### Using Flags w/ ComponentConfig + +Since this design still requires setting up the initial `ComponentConfig` type and passing in a pointer to `ctrl.NewFromComponentConfig()` if you want to allow for the use of flags, your controller can use any of the different flagging interfaces. eg [`flag`](https://golang.org/pkg/flag/), [`pflag`](https://pkg.go.dev/github.com/spf13/pflag), [`flagnum`](https://pkg.go.dev/github.com/luci/luci-go/common/flag/flagenum) and set values on the `ComponentConfig` type prior to passing the pointer into the `ctrl.NewFromComponentConfig()`, example below. + +```golang +leaderElect := true + +config := &defaultv1alpha1.DefaultControllerManagerConfiguration{ + Spec: configv1alpha1.ControllerManagerConfiguration{ + LeaderElection: configv1alpha1.LeaderElectionConfiguration{ + LeaderElect: &leaderElect, + }, + }, +} +mgr, err := ctrl.NewManagerFromComponentConfig(ctrl.GetConfigOrDie(), scheme, configname, config) +if err != nil { + // ... +} +``` + +#### Kubebuilder Scaffolding Example + +Within expanded in a separate design _(link once created)_ this will allow controller authors to generate a type that implements the `ManagerConfiguration` interface. The following is a sample of what this looks like: + +```golang +package config + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + configv1alpha1 "sigs.k8s.io/controller-runtime/pkg/apis/config/v1alpha1" +) + +type ControllerNameConfigurationSpec struct { + configv1alpha1.ControllerManagerConfiguration `json:",inline"` +} + +type ControllerNameConfiguration struct { + metav1.TypeMeta + + Spec ControllerNameConfigurationSpec `json:"spec"` +} +``` + +Usage of this custom `ComponentConfig` type would require then changing the `ctrl.NewFromComponentConfig()` to use the new struct vs the `DefaultControllerManagerConfiguration`. + +## User Stories + +### Controller Author with `controller-runtime` and default type + +- Mount `ConfigMap` +- Initialize `ctrl.Manager` with `NewFromComponentConfig` with config name and `DefaultControllerManagerConfiguration` type +- Build custom controller as usual + +### Controller Author with `controller-runtime` and custom type + +- Implement `ComponentConfig` type +- Embed `ControllerManagerConfiguration` type +- Mount `ConfigMap` +- Initialize `ctrl.Manager` with `NewFromComponentConfig` with config name and `ComponentConfig` type +- Build custom controller as usual + +### Controller Author with `kubebuilder` (tbd proposal for `kubebuilder`) + +- Initialize `kubebuilder` project using `--component-config-name=XYZConfiguration` +- Build custom controller as usual + +### Controller User without modifications to config + +_Provided that the controller provides manifests_ + +- Apply the controller to the cluster +- Deploy custom resources + +### Controller User with modifications to config + +- _Following from previous example without changes_ +- Create a new `ConfigMap` for changes +- Modify the `controller-runtime` pod to use the new `ConfigMap` +- Apply the controller to the cluster +- Deploy custom resources + + +## Risks and Mitigations + +- Given that this isn't changing the core Manager initialization for `controller-runtime` it's fairly low risk + +## Alternatives + +* `NewFromComponentConfig()` could load the object from disk based on the file name and hydrate the `ComponentConfig` type. + +## Implementation History + +- [x] 02/19/2020: Proposed idea in an issue or [community meeting] +- [x] 02/24/2020: Proposal submitted to `controller-runtime` +- [x] 03/02/2020: Updated with default `DefaultControllerManagerConfiguration` +- [x] 03/04/2020: Updated with embeddable `RuntimeConfig` +- [x] 03/10/2020: Updated embeddable name to `ControllerManagerConfiguration` + + + +[community meeting]: https://docs.google.com/document/d/1Ih-2cgg1bUrLwLVTB9tADlPcVdgnuMNBGbUl4D-0TIk diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/images/component-config-load.png b/third_party/sigs.k8s.io/controller-runtime/designs/images/component-config-load.png new file mode 100644 index 00000000000..04619779dad Binary files /dev/null and b/third_party/sigs.k8s.io/controller-runtime/designs/images/component-config-load.png differ diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/move-cluster-specific-code-out-of-manager.md b/third_party/sigs.k8s.io/controller-runtime/designs/move-cluster-specific-code-out-of-manager.md new file mode 100644 index 00000000000..67b7a419a54 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/designs/move-cluster-specific-code-out-of-manager.md @@ -0,0 +1,228 @@ +Move cluster-specific code out of the manager +=================== + +## Motivation + +Today, it is already possible to use controller-runtime to build controllers that act on +more than one cluster. However, this is undocumented and not straight-forward, requiring +users to look into the implementation details to figure out how to make this work. + +## Goals + +* Provide an easy-to-discover way to build controllers that act on multiple clusters +* Decouple the management of `Runnables` from the construction of "things that require a kubeconfig" +* Do not introduce changes for users that build controllers that act on one cluster only + +## Non-Goals + +## Proposal + +Currently, the `./pkg/manager.Manager` has two purposes: + +* Handle running controllers/other runnables and managing their lifecycle +* Setting up various things to interact with the Kubernetes cluster, + for example a `Client` and a `Cache` + +This works very well when building controllers that talk to a single cluster, +however some use-cases require controllers that interact with more than +one cluster. This multi-cluster usecase is very awkward today, because it +requires to construct one manager per cluster and adding all subsequent +managers to the first one. + +This document proposes to move all cluster-specific code out of the manager +and into a new package and interface, that then gets embedded into the manager. +This allows to keep the usage for single-cluster cases the same and introduce +this change in a backwards-compatible manner. + +Furthermore, the manager gets extended to start all caches before any other +`runnables` are started. + + +The new `Cluster` interface will look like this: + +```go +type Cluster interface { + // SetFields will set cluster-specific dependencies on an object for which the object has implemented the inject + // interface, specifically inject.Client, inject.Cache, inject.Scheme, inject.Config and inject.APIReader + SetFields(interface{}) error + + // GetConfig returns an initialized Config + GetConfig() *rest.Config + + // GetClient returns a client configured with the Config. This client may + // not be a fully "direct" client -- it may read from a cache, for + // instance. See Options.NewClient for more information on how the default + // implementation works. + GetClient() client.Client + + // GetFieldIndexer returns a client.FieldIndexer configured with the client + GetFieldIndexer() client.FieldIndexer + + // GetCache returns a cache.Cache + GetCache() cache.Cache + + // GetEventRecorderFor returns a new EventRecorder for the provided name + GetEventRecorderFor(name string) record.EventRecorder + + // GetRESTMapper returns a RESTMapper + GetRESTMapper() meta.RESTMapper + + // GetAPIReader returns a reader that will be configured to use the API server. + // This should be used sparingly and only when the client does not fit your + // use case. + GetAPIReader() client.Reader + + // GetScheme returns an initialized Scheme + GetScheme() *runtime.Scheme + + // Start starts the connection tothe Cluster + Start(<-chan struct{}) error +} +``` + +And the current `Manager` interface will change to look like this: + +```go +type Manager interface { + // Cluster holds objects to connect to a cluster + cluser.Cluster + + // Add will set requested dependencies on the component, and cause the component to be + // started when Start is called. Add will inject any dependencies for which the argument + // implements the inject interface - e.g. inject.Client. + // Depending on if a Runnable implements LeaderElectionRunnable interface, a Runnable can be run in either + // non-leaderelection mode (always running) or leader election mode (managed by leader election if enabled). + Add(Runnable) error + + // Elected is closed when this manager is elected leader of a group of + // managers, either because it won a leader election or because no leader + // election was configured. + Elected() <-chan struct{} + + // SetFields will set any dependencies on an object for which the object has implemented the inject + // interface - e.g. inject.Client. + SetFields(interface{}) error + + // AddMetricsExtraHandler adds an extra handler served on path to the http server that serves metrics. + // Might be useful to register some diagnostic endpoints e.g. pprof. Note that these endpoints meant to be + // sensitive and shouldn't be exposed publicly. + // If the simple path -> handler mapping offered here is not enough, a new http server/listener should be added as + // Runnable to the manager via Add method. + AddMetricsExtraHandler(path string, handler http.Handler) error + + // AddHealthzCheck allows you to add Healthz checker + AddHealthzCheck(name string, check healthz.Checker) error + + // AddReadyzCheck allows you to add Readyz checker + AddReadyzCheck(name string, check healthz.Checker) error + + // Start starts all registered Controllers and blocks until the Stop channel is closed. + // Returns an error if there is an error starting any controller. + // If LeaderElection is used, the binary must be exited immediately after this returns, + // otherwise components that need leader election might continue to run after the leader + // lock was lost. + Start(<-chan struct{}) error + + // GetWebhookServer returns a webhook.Server + GetWebhookServer() *webhook.Server +} +``` + +Furthermore, during startup, the `Manager` will use type assertion to find `Cluster`s +to be able to start their caches before anything else: + +```go +type HasCaches interface { + GetCache() +} +if getter, hasCaches := runnable.(HasCaches); hasCaches { + m.caches = append(m.caches, getter()) +} +``` + +```go +for idx := range cm.caches { + go func(idx int) {cm.caches[idx].Start(cm.internalStop)} +} + +for _, cache := range cm.caches { + cache.WaitForCacheSync(cm.internalStop) +} + +// Start all other runnables +``` + +## Example + +Below is a sample `reconciler` that will create a secret in a `mirrorCluster` for each +secret found in `referenceCluster` if none of that name already exists. To keep the sample +short, it won't compare the contents of the secrets. + +```go +type secretMirrorReconciler struct { + referenceClusterClient, mirrorClusterClient client.Client +} + +func (r *secretMirrorReconciler) Reconcile(r reconcile.Request)(reconcile.Result, error){ + s := &corev1.Secret{} + if err := r.referenceClusterClient.Get(context.TODO(), r.NamespacedName, s); err != nil { + if kerrors.IsNotFound{ return reconcile.Result{}, nil } + return reconcile.Result, err + } + + if err := r.mirrorClusterClient.Get(context.TODO(), r.NamespacedName, &corev1.Secret); err != nil { + if !kerrors.IsNotFound(err) { + return reconcile.Result{}, err + } + + mirrorSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Namespace: s.Namespace, Name: s.Name}, + Data: s.Data, + } + return reconcile.Result{}, r.mirrorClusterClient.Create(context.TODO(), mirrorSecret) + } + + return nil +} + +func NewSecretMirrorReconciler(mgr manager.Manager, mirrorCluster cluster.Cluster) error { + return ctrl.NewControllerManagedBy(mgr). + // Watch Secrets in the reference cluster + For(&corev1.Secret{}). + // Watch Secrets in the mirror cluster + Watches( + source.NewKindWithCache(&corev1.Secret{}, mirrorCluster.GetCache()), + &handler.EnqueueRequestForObject{}, + ). + Complete(&secretMirrorReconciler{ + referenceClusterClient: mgr.GetClient(), + mirrorClusterClient: mirrorCluster.GetClient(), + }) + } +} + +func main(){ + + mgr, err := manager.New( cfg1, manager.Options{}) + if err != nil { + panic(err) + } + + mirrorCluster, err := cluster.New(cfg2) + if err != nil { + panic(err) + } + + if err := mgr.Add(mirrorCluster); err != nil { + panic(err) + } + + if err := NewSecretMirrorReconciler(mgr, mirrorCluster); err != nil { + panic(err) + } + + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + panic(err) + } +} +``` diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/template.md b/third_party/sigs.k8s.io/controller-runtime/designs/template.md new file mode 100644 index 00000000000..c04d6e0c71d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/designs/template.md @@ -0,0 +1,21 @@ +Title of the Design +=================== + + + +## Example + + \ No newline at end of file diff --git a/third_party/sigs.k8s.io/controller-runtime/designs/use-selectors-at-cache.md b/third_party/sigs.k8s.io/controller-runtime/designs/use-selectors-at-cache.md new file mode 100644 index 00000000000..1d7ec6ecfb5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/designs/use-selectors-at-cache.md @@ -0,0 +1,122 @@ +# Filter cache ListWatch using selectors + +## Motivation + +Controller-Runtime controllers use a cache to subscribe to events from +Kubernetes objects and to read those objects more efficiently by avoiding +to call out to the API. This cache is backed by Kubernetes informers. + +The only way to filter this cache is by namespace and resource type. +In cases where a controller is only interested in a small subset of objects +(for example all pods on a node), this might end up not being efficient enough. + +Requests to a client backed by a filtered cache for objects that do not match +the filter will never return anything, so we need to make sure that we properly +warn users to only use this when they are sure they know what they are doing. + +This proposal sidesteps the issue of "How to we plug this into the cache-backed +client so that users get feedback when they request something that is +not matching the caches filter" by only implementing the filter logic in the +cache package. This allows advanced users to combine a filtered cache with the +already existing `NewCacheFunc` option in the manager and cluster package, +while simultaneously hiding it from newer users that might not be aware of the +implications and the associated foot-shoot potential. + +The only alternative today to get a filtered cache with controller-runtime is +to build it out-of tree. Because such a cache would mostly copy the existing +cache and add just some options, this is not great for consumers. + +This proposal is related to the following issue [2] + +## Proposal + +Add a new selector code at `pkg/cache/internal/selector.go` with common structs +and helpers + +```golang +package internal + +... + +// SelectorsByObject associate a runtime.Object to a field/label selector +type SelectorsByObject map[client.Object]Selector + +// SelectorsByGVK associate a GroupVersionResource to a field/label selector +type SelectorsByGVK map[schema.GroupVersionKind]Selector + +// Selector specify the label/field selector to fill in ListOptions +type Selector struct { + Label labels.Selector + Field fields.Selector +} + +// ApplyToList fill in ListOptions LabelSelector and FieldSelector if needed +func (s Selector) ApplyToList(listOpts *metav1.ListOptions) { +... +} +``` + +Add a type alias to `pkg/cache/cache.go` to internal + +```golang +type SelectorsByObject internal.SelectorsByObject +``` + +Extend `cache.Options` as follows: + +```golang +type Options struct { + Scheme *runtime.Scheme + Mapper meta.RESTMapper + Resync *time.Duration + Namespace string + SelectorsByObject SelectorsByObject +} +``` + +Add new builder function that will return a cache constructor using the passed +cache.Options, users can set SelectorsByObject there to filter out cache, it +will convert SelectorByObject to SelectorsByGVK + +```golang +func BuilderWithOptions(options cache.Options) NewCacheFunc { +... +} +``` + +is passed to informer's ListWatch and add the filtering option: + +```golang + +# At pkg/cache/internal/informers_map.go + +ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + ip.selectors[gvk].ApplyToList(&opts) +... +``` + +Here is a PR with the implementatin at the `pkg/cache` part [3] + +## Example + +User will override `NewCache` function to make clear that they know exactly the +implications of using a different cache than the default one + +```golang + ctrl.Options.NewCache = cache.BuilderWithOptions(cache.Options{ + SelectorsByObject: cache.SelectorsByObject{ + &corev1.Node{}: { + Field: fields.SelectorFromSet(fields.Set{"metadata.name": "node01"}), + } + &v1beta1.NodeNetworkState{}: { + Field: fields.SelectorFromSet(fields.Set{"metadata.name": "node01"}), + Label: labels.SelectorFromSet(labels.Set{"app": "kubernetes-nmstate})", + } + } + } + ) +``` + +[1] https://github.com/nmstate/kubernetes-nmstate/pull/687 +[2] https://github.com/kubernetes-sigs/controller-runtime/issues/244 +[3] https://github.com/kubernetes-sigs/controller-runtime/pull/1404 diff --git a/third_party/sigs.k8s.io/controller-runtime/doc.go b/third_party/sigs.k8s.io/controller-runtime/doc.go new file mode 100644 index 00000000000..0319bc3ff86 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/doc.go @@ -0,0 +1,128 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package controllerruntime provides tools to construct Kubernetes-style +// controllers that manipulate both Kubernetes CRDs and aggregated/built-in +// Kubernetes APIs. +// +// It defines easy helpers for the common use cases when building CRDs, built +// on top of customizable layers of abstraction. Common cases should be easy, +// and uncommon cases should be possible. In general, controller-runtime tries +// to guide users towards Kubernetes controller best-practices. +// +// # Getting Started +// +// The main entrypoint for controller-runtime is this root package, which +// contains all of the common types needed to get started building controllers: +// +// import ( +// ctrl "sigs.k8s.io/controller-runtime" +// ) +// +// The examples in this package walk through a basic controller setup. The +// kubebuilder book (https://book.kubebuilder.io) has some more in-depth +// walkthroughs. +// +// controller-runtime favors structs with sane defaults over constructors, so +// it's fairly common to see structs being used directly in controller-runtime. +// +// # Organization +// +// A brief-ish walkthrough of the layout of this library can be found below. Each +// package contains more information about how to use it. +// +// Frequently asked questions about using controller-runtime and designing +// controllers can be found at +// https://github.com/kubernetes-sigs/controller-runtime/blob/main/FAQ.md. +// +// # Managers +// +// Every controller and webhook is ultimately run by a Manager (pkg/manager). A +// manager is responsible for running controllers and webhooks, and setting up +// common dependencies, like shared caches and clients, as +// well as managing leader election (pkg/leaderelection). Managers are +// generally configured to gracefully shut down controllers on pod termination +// by wiring up a signal handler (pkg/manager/signals). +// +// # Controllers +// +// Controllers (pkg/controller) use events (pkg/event) to eventually trigger +// reconcile requests. They may be constructed manually, but are often +// constructed with a Builder (pkg/builder), which eases the wiring of event +// sources (pkg/source), like Kubernetes API object changes, to event handlers +// (pkg/handler), like "enqueue a reconcile request for the object owner". +// Predicates (pkg/predicate) can be used to filter which events actually +// trigger reconciles. There are pre-written utilities for the common cases, and +// interfaces and helpers for advanced cases. +// +// # Reconcilers +// +// Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A +// Reconciler implements a function which takes a reconcile Request containing +// the name and namespace of the object to reconcile, reconciles the object, +// and returns a Response or an error indicating whether to requeue for a +// second round of processing. +// +// # Clients and Caches +// +// Reconcilers use Clients (pkg/client) to access API objects. The default +// client provided by the manager reads from a local shared cache (pkg/cache) +// and writes directly to the API server, but clients can be constructed that +// only talk to the API server, without a cache. The Cache will auto-populate +// with watched objects, as well as when other structured objects are +// requested. The default split client does not promise to invalidate the cache +// during writes (nor does it promise sequential create/get coherence), and code +// should not assume a get immediately following a create/update will return +// the updated resource. Caches may also have indexes, which can be created via +// a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to +// quickly and easily look up all objects with certain fields set. Reconcilers +// may retrieve event recorders (pkg/recorder) to emit events using the +// manager. +// +// # Schemes +// +// Clients, Caches, and many other things in Kubernetes use Schemes +// (pkg/scheme) to associate Go types to Kubernetes API Kinds +// (Group-Version-Kinds, to be specific). +// +// # Webhooks +// +// Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but +// are often constructed using a builder (pkg/webhook/admission/builder). They +// are run via a server (pkg/webhook) which is managed by a Manager. +// +// # Logging and Metrics +// +// Logging (pkg/log) in controller-runtime is done via structured logs, using a +// log set of interfaces called logr +// (https://pkg.go.dev/github.com/go-logr/logr). While controller-runtime +// provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), +// you can provide any implementation of logr as the base logger for +// controller-runtime. +// +// Metrics (pkg/metrics) provided by controller-runtime are registered into a +// controller-runtime-specific Prometheus metrics registry. The manager can +// serve these by an HTTP endpoint, and additional metrics may be registered to +// this Registry as normal. +// +// # Testing +// +// You can easily build integration and unit tests for your controllers and +// webhooks using the test Environment (pkg/envtest). This will automatically +// stand up a copy of etcd and kube-apiserver, and provide the correct options +// to connect to the API server. It's designed to work well with the Ginkgo +// testing framework, but should work with any testing setup. +package controllerruntime diff --git a/third_party/sigs.k8s.io/controller-runtime/example_test.go b/third_party/sigs.k8s.io/controller-runtime/example_test.go new file mode 100644 index 00000000000..381959d5bb5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/example_test.go @@ -0,0 +1,145 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerruntime_test + +import ( + "context" + "fmt" + "os" + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + // since we invoke tests with -ginkgo.junit-report we need to import ginkgo. + _ "github.com/onsi/ginkgo/v2" +) + +// This example creates a simple application Controller that is configured for ReplicaSets and Pods. +// +// * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into +// ReplicaSetReconciler. +// +// * Start the application. +func Example() { + var log = ctrl.Log.WithName("builder-examples") + + manager, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) + if err != nil { + log.Error(err, "could not create manager") + os.Exit(1) + } + + err = ctrl. + NewControllerManagedBy(manager). // Create the Controller + For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API + Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it + Complete(&ReplicaSetReconciler{Client: manager.GetClient()}) + if err != nil { + log.Error(err, "could not create controller") + os.Exit(1) + } + + if err := manager.Start(ctrl.SetupSignalHandler()); err != nil { + log.Error(err, "could not start manager") + os.Exit(1) + } +} + +// This example creates a simple application Controller that is configured for ReplicaSets and Pods. +// This application controller will be running leader election with the provided configuration in the manager options. +// If leader election configuration is not provided, controller runs leader election with default values. +// Default values taken from: https://github.com/kubernetes/component-base/blob/master/config/v1alpha1/defaults.go +// * defaultLeaseDuration = 15 * time.Second +// * defaultRenewDeadline = 10 * time.Second +// * defaultRetryPeriod = 2 * time.Second +// +// * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into +// ReplicaSetReconciler. +// +// * Start the application. +func Example_updateLeaderElectionDurations() { + var log = ctrl.Log.WithName("builder-examples") + leaseDuration := 100 * time.Second + renewDeadline := 80 * time.Second + retryPeriod := 20 * time.Second + manager, err := ctrl.NewManager( + ctrl.GetConfigOrDie(), + ctrl.Options{ + LeaseDuration: &leaseDuration, + RenewDeadline: &renewDeadline, + RetryPeriod: &retryPeriod, + }) + if err != nil { + log.Error(err, "could not create manager") + os.Exit(1) + } + + err = ctrl. + NewControllerManagedBy(manager). // Create the Controller + For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API + Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it + Complete(&ReplicaSetReconciler{Client: manager.GetClient()}) + if err != nil { + log.Error(err, "could not create controller") + os.Exit(1) + } + + if err := manager.Start(ctrl.SetupSignalHandler()); err != nil { + log.Error(err, "could not start manager") + os.Exit(1) + } +} + +// ReplicaSetReconciler is a simple Controller example implementation. +type ReplicaSetReconciler struct { + client.Client +} + +// Implement the business logic: +// This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference +// to a ReplicaSet. +// +// * Read the ReplicaSet +// * Read the Pods +// * Set a Label on the ReplicaSet with the Pod count. +func (a *ReplicaSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + // Read the ReplicaSet + rs := &appsv1.ReplicaSet{} + err := a.Get(ctx, req.NamespacedName, rs) + if err != nil { + return ctrl.Result{}, err + } + + // List the Pods matching the PodTemplate Labels + pods := &corev1.PodList{} + err = a.List(ctx, pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) + if err != nil { + return ctrl.Result{}, err + } + + // Update the ReplicaSet + rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items)) + err = a.Update(ctx, rs) + if err != nil { + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/README.md b/third_party/sigs.k8s.io/controller-runtime/examples/README.md new file mode 100644 index 00000000000..2110ae214ea --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/README.md @@ -0,0 +1,36 @@ +# Examples + +These two examples represent the usage of `controller-runtime` libraries for built-in Kubernetes resources as well as custom resources. + +### builtins/ + +This example implements a custom controller and webhooks for the *existing* ReplicaSet resource. + +* `controller.go`: implements a reconciler for ReplicaSets +* `mutatingwebhook.go`: implements a mutating webhook that adds an annotation to every incoming Pod ("example-mutating-admission-webhook" = "foo") +* `validatingwebhook.go`: implements a validating webhook that checks to see if a Pod has the aforementioned annotation +* `main.go` + 1. Creates a new manager + 2. Creates a new controller that watches both ReplicaSets and Pods and reconciles the objects with the implemented reconciler + 3. Registers the mutating and validating webhooks with the manager + 4. Starts the manager + +### crd/ + +This example implements a *new* Kubernetes resource, ChaosPod, and creates a custom controller that watches it and webhooks that mutate and validate. + +* `pkg/` + * `resource.go`: defines the schema for the ChaosPod API and implements validate and mutate webhooks + * `groupversion_info.go`: specifies the Group and Version for the ChaosPod API + * `zz_generated.deepcopy.go`: deep copy functions generated by kubebuilder +* `main.go` + 1. Creates a new manager + 2. Adds ChaosPod resource to the manager's schema + 3. Implements a reconciler to execute the desired behavior of the ChaosPod API + 4. Creates a new controller that watches ChaosPods and reconciles the objects with the implemented reconciler + 5. Adds ChaosPod webhooks to manager + 6. Starts the manager + +## Deploying and Running + +To install and run the provided examples, see the Kubebuilder [Quick Start](https://book.kubebuilder.io/quick-start.html). \ No newline at end of file diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/builtins/controller.go b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/controller.go new file mode 100644 index 00000000000..6c8c5d935ff --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/controller.go @@ -0,0 +1,74 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// reconcileReplicaSet reconciles ReplicaSets +type reconcileReplicaSet struct { + // client can be used to retrieve objects from the APIServer. + client client.Client +} + +// Implement reconcile.Reconciler so the controller can reconcile objects +var _ reconcile.Reconciler = &reconcileReplicaSet{} + +func (r *reconcileReplicaSet) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + // set up a convenient log object so we don't have to type request over and over again + log := log.FromContext(ctx) + + // Fetch the ReplicaSet from the cache + rs := &appsv1.ReplicaSet{} + err := r.client.Get(ctx, request.NamespacedName, rs) + if errors.IsNotFound(err) { + log.Error(nil, "Could not find ReplicaSet") + return reconcile.Result{}, nil + } + + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not fetch ReplicaSet: %+v", err) + } + + // Print the ReplicaSet + log.Info("Reconciling ReplicaSet", "container name", rs.Spec.Template.Spec.Containers[0].Name) + + // Set the label if it is missing + if rs.Labels == nil { + rs.Labels = map[string]string{} + } + if rs.Labels["hello"] == "world" { + return reconcile.Result{}, nil + } + + // Update the ReplicaSet + rs.Labels["hello"] = "world" + err = r.client.Update(ctx, rs) + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not write ReplicaSet: %+v", err) + } + + return reconcile.Result{}, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/builtins/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/main.go new file mode 100644 index 00000000000..8ea173b2486 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/main.go @@ -0,0 +1,88 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "os" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +func init() { + log.SetLogger(zap.New()) +} + +func main() { + entryLog := log.Log.WithName("entrypoint") + + // Setup a Manager + entryLog.Info("setting up manager") + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) + if err != nil { + entryLog.Error(err, "unable to set up overall controller manager") + os.Exit(1) + } + + // Setup a new controller to reconcile ReplicaSets + entryLog.Info("Setting up controller") + c, err := controller.New("foo-controller", mgr, controller.Options{ + Reconciler: &reconcileReplicaSet{client: mgr.GetClient()}, + }) + if err != nil { + entryLog.Error(err, "unable to set up individual controller") + os.Exit(1) + } + + // Watch ReplicaSets and enqueue ReplicaSet object key + if err := c.Watch(source.Kind(mgr.GetCache(), &appsv1.ReplicaSet{}), &handler.EnqueueRequestForObject{}); err != nil { + entryLog.Error(err, "unable to watch ReplicaSets") + os.Exit(1) + } + + // Watch Pods and enqueue owning ReplicaSet key + if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}), + handler.EnqueueRequestForOwner(mgr.GetScheme(), mgr.GetRESTMapper(), &appsv1.ReplicaSet{}, handler.OnlyControllerOwner())); err != nil { + entryLog.Error(err, "unable to watch Pods") + os.Exit(1) + } + + if err := builder.WebhookManagedBy(mgr). + For(&corev1.Pod{}). + WithDefaulter(&podAnnotator{}). + WithValidator(&podValidator{}). + Complete(); err != nil { + entryLog.Error(err, "unable to create webhook", "webhook", "Pod") + os.Exit(1) + } + + entryLog.Info("starting manager") + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + entryLog.Error(err, "unable to run manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/builtins/mutatingwebhook.go b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/mutatingwebhook.go new file mode 100644 index 00000000000..a588eba8f9c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/mutatingwebhook.go @@ -0,0 +1,48 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// +kubebuilder:webhook:path=/mutate--v1-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create;update,versions=v1,name=mpod.kb.io + +// podAnnotator annotates Pods +type podAnnotator struct{} + +func (a *podAnnotator) Default(ctx context.Context, obj runtime.Object) error { + log := logf.FromContext(ctx) + pod, ok := obj.(*corev1.Pod) + if !ok { + return fmt.Errorf("expected a Pod but got a %T", obj) + } + + if pod.Annotations == nil { + pod.Annotations = map[string]string{} + } + pod.Annotations["example-mutating-admission-webhook"] = "foo" + log.Info("Annotated Pod") + + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/builtins/validatingwebhook.go b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/validatingwebhook.go new file mode 100644 index 00000000000..1bee7f7c848 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/builtins/validatingwebhook.go @@ -0,0 +1,66 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// +kubebuilder:webhook:path=/validate--v1-pod,mutating=false,failurePolicy=fail,groups="",resources=pods,verbs=create;update,versions=v1,name=vpod.kb.io + +// podValidator validates Pods +type podValidator struct{} + +// validate admits a pod if a specific annotation exists. +func (v *podValidator) validate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + log := logf.FromContext(ctx) + pod, ok := obj.(*corev1.Pod) + if !ok { + return nil, fmt.Errorf("expected a Pod but got a %T", obj) + } + + log.Info("Validating Pod") + key := "example-mutating-admission-webhook" + anno, found := pod.Annotations[key] + if !found { + return nil, fmt.Errorf("missing annotation %s", key) + } + if anno != "foo" { + return nil, fmt.Errorf("annotation %s did not have value %q", key, "foo") + } + + return nil, nil +} + +func (v *podValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + return v.validate(ctx, obj) +} + +func (v *podValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + return v.validate(ctx, newObj) +} + +func (v *podValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + return v.validate(ctx, obj) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/config.yaml b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/config.yaml new file mode 100644 index 00000000000..39ac86ce60e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/config.yaml @@ -0,0 +1,7 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfiguration +cacheNamespace: default +metrics: + bindAddress: :9091 +leaderElection: + leaderElect: false diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/controller.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/controller.go new file mode 100644 index 00000000000..8349bcd5aa8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/controller.go @@ -0,0 +1,74 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// reconcileReplicaSet reconciles ReplicaSets +type reconcileReplicaSet struct { + // client can be used to retrieve objects from the APIServer. + client client.Client +} + +// Implement reconcile.Reconciler so the controller can reconcile objects +var _ reconcile.Reconciler = &reconcileReplicaSet{} + +func (r *reconcileReplicaSet) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + // set up a convenient log object so we don't have to type request over and over again + log := log.FromContext(ctx) + + // Fetch the ReplicaSet from the cache + rs := &appsv1.ReplicaSet{} + err := r.client.Get(context.TODO(), request.NamespacedName, rs) + if errors.IsNotFound(err) { + log.Error(nil, "Could not find ReplicaSet") + return reconcile.Result{}, nil + } + + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not fetch ReplicaSet: %+v", err) + } + + // Print the ReplicaSet + log.Info("Reconciling ReplicaSet", "container name", rs.Spec.Template.Spec.Containers[0].Name) + + // Set the label if it is missing + if rs.Labels == nil { + rs.Labels = map[string]string{} + } + if rs.Labels["hello"] == "world" { + return reconcile.Result{}, nil + } + + // Update the ReplicaSet + rs.Labels["hello"] = "world" + err = r.client.Update(context.TODO(), rs) + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not write ReplicaSet: %+v", err) + } + + return reconcile.Result{}, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/main.go new file mode 100644 index 00000000000..abd6180d191 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/builtin/main.go @@ -0,0 +1,72 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "os" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client/config" + cfg "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" +) + +var scheme = runtime.NewScheme() + +func init() { + log.SetLogger(zap.New()) + clientgoscheme.AddToScheme(scheme) +} + +func main() { + entryLog := log.Log.WithName("entrypoint") + + // Setup a Manager + entryLog.Info("setting up manager") + mgr, err := ctrl.NewManager(config.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + }.AndFromOrDie(cfg.File())) + if err != nil { + entryLog.Error(err, "unable to set up overall controller manager") + os.Exit(1) + } + + // Setup a new controller to reconcile ReplicaSets + err = ctrl.NewControllerManagedBy(mgr). + For(&appsv1.ReplicaSet{}). + Owns(&corev1.Pod{}). + Complete(&reconcileReplicaSet{ + client: mgr.GetClient(), + }) + if err != nil { + entryLog.Error(err, "unable to create controller") + os.Exit(1) + } + + entryLog.Info("starting manager") + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + entryLog.Error(err, "unable to run manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/config.yaml b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/config.yaml new file mode 100644 index 00000000000..bf9ac044b4d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/config.yaml @@ -0,0 +1,8 @@ +apiVersion: examples.x-k8s.io/v1alpha1 +kind: CustomControllerManagerConfiguration +clusterName: example-test +cacheNamespace: default +metrics: + bindAddress: :8081 +leaderElection: + leaderElect: false diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/controller.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/controller.go new file mode 100644 index 00000000000..8349bcd5aa8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/controller.go @@ -0,0 +1,74 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "fmt" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// reconcileReplicaSet reconciles ReplicaSets +type reconcileReplicaSet struct { + // client can be used to retrieve objects from the APIServer. + client client.Client +} + +// Implement reconcile.Reconciler so the controller can reconcile objects +var _ reconcile.Reconciler = &reconcileReplicaSet{} + +func (r *reconcileReplicaSet) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + // set up a convenient log object so we don't have to type request over and over again + log := log.FromContext(ctx) + + // Fetch the ReplicaSet from the cache + rs := &appsv1.ReplicaSet{} + err := r.client.Get(context.TODO(), request.NamespacedName, rs) + if errors.IsNotFound(err) { + log.Error(nil, "Could not find ReplicaSet") + return reconcile.Result{}, nil + } + + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not fetch ReplicaSet: %+v", err) + } + + // Print the ReplicaSet + log.Info("Reconciling ReplicaSet", "container name", rs.Spec.Template.Spec.Containers[0].Name) + + // Set the label if it is missing + if rs.Labels == nil { + rs.Labels = map[string]string{} + } + if rs.Labels["hello"] == "world" { + return reconcile.Result{}, nil + } + + // Update the ReplicaSet + rs.Labels["hello"] = "world" + err = r.client.Update(context.TODO(), rs) + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not write ReplicaSet: %+v", err) + } + + return reconcile.Result{}, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/main.go new file mode 100644 index 00000000000..e0fc95e3378 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/main.go @@ -0,0 +1,78 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "os" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client/config" + cfg "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" +) + +var scheme = runtime.NewScheme() + +func init() { + log.SetLogger(zap.New()) + clientgoscheme.AddToScheme(scheme) + v1alpha1.AddToScheme(scheme) +} + +func main() { + entryLog := log.Log.WithName("entrypoint") + + // Setup a Manager + entryLog.Info("setting up manager") + ctrlConfig := v1alpha1.CustomControllerManagerConfiguration{} + + mgr, err := ctrl.NewManager(config.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + }.AndFromOrDie(cfg.File().OfKind(&ctrlConfig))) + if err != nil { + entryLog.Error(err, "unable to set up overall controller manager") + os.Exit(1) + } + + entryLog.Info("setting up cluster", "name", ctrlConfig.ClusterName) + + // Watch ReplicaSets and enqueue ReplicaSet object key + err = ctrl.NewControllerManagedBy(mgr). + For(&appsv1.ReplicaSet{}). + Owns(&corev1.Pod{}). + Complete(&reconcileReplicaSet{ + client: mgr.GetClient(), + }) + if err != nil { + entryLog.Error(err, "unable to create controller") + os.Exit(1) + } + + entryLog.Info("starting manager") + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + entryLog.Error(err, "unable to run manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/types.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/types.go new file mode 100644 index 00000000000..79e8422c5c9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/types.go @@ -0,0 +1,54 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 provides the CustomControllerManagerConfiguration used for +// demoing componentconfig +// +kubebuilder:object:generate=true +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + cfg "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "examples.x-k8s.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +// +kubebuilder:object:root=true + +// CustomControllerManagerConfiguration is the Schema for the CustomControllerManagerConfigurations API +type CustomControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // ControllerManagerConfigurationSpec returns the contfigurations for controllers + cfg.ControllerManagerConfigurationSpec `json:",inline"` + + ClusterName string `json:"clusterName,omitempty"` +} + +func init() { + SchemeBuilder.Register(&CustomControllerManagerConfiguration{}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..b9d3b6b4b94 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,35 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomControllerManagerConfiguration) DeepCopyInto(out *CustomControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ControllerManagerConfigurationSpec.DeepCopyInto(&out.ControllerManagerConfigurationSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomControllerManagerConfiguration. +func (in *CustomControllerManagerConfiguration) DeepCopy() *CustomControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(CustomControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CustomControllerManagerConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/crd/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/crd/main.go new file mode 100644 index 00000000000..1f6cd5fac2e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/crd/main.go @@ -0,0 +1,145 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "math/rand" + "os" + "time" + + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + api "sigs.k8s.io/controller-runtime/examples/crd/pkg" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + setupLog = ctrl.Log.WithName("setup") +) + +type reconciler struct { + client.Client + scheme *runtime.Scheme +} + +func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := log.FromContext(ctx).WithValues("chaospod", req.NamespacedName) + log.V(1).Info("reconciling chaos pod") + + var chaospod api.ChaosPod + if err := r.Get(ctx, req.NamespacedName, &chaospod); err != nil { + log.Error(err, "unable to get chaosctl") + return ctrl.Result{}, err + } + + var pod corev1.Pod + podFound := true + if err := r.Get(ctx, req.NamespacedName, &pod); err != nil { + if !apierrors.IsNotFound(err) { + log.Error(err, "unable to get pod") + return ctrl.Result{}, err + } + podFound = false + } + + if podFound { + shouldStop := chaospod.Spec.NextStop.Time.Before(time.Now()) + if !shouldStop { + return ctrl.Result{RequeueAfter: chaospod.Spec.NextStop.Sub(time.Now()) + 1*time.Second}, nil + } + + if err := r.Delete(ctx, &pod); err != nil { + log.Error(err, "unable to delete pod") + return ctrl.Result{}, err + } + + return ctrl.Result{Requeue: true}, nil + } + + templ := chaospod.Spec.Template.DeepCopy() + pod.ObjectMeta = templ.ObjectMeta + pod.Name = req.Name + pod.Namespace = req.Namespace + pod.Spec = templ.Spec + + if err := ctrl.SetControllerReference(&chaospod, &pod, r.scheme); err != nil { + log.Error(err, "unable to set pod's owner reference") + return ctrl.Result{}, err + } + + if err := r.Create(ctx, &pod); err != nil { + log.Error(err, "unable to create pod") + return ctrl.Result{}, err + } + + chaospod.Spec.NextStop.Time = time.Now().Add(time.Duration(10*(rand.Int63n(2)+1)) * time.Second) + chaospod.Status.LastRun = pod.CreationTimestamp + if err := r.Update(ctx, &chaospod); err != nil { + log.Error(err, "unable to update chaosctl status") + return ctrl.Result{}, err + } + return ctrl.Result{}, nil +} + +func main() { + ctrl.SetLogger(zap.New()) + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + // in a real controller, we'd create a new scheme for this + err = api.AddToScheme(mgr.GetScheme()) + if err != nil { + setupLog.Error(err, "unable to add scheme") + os.Exit(1) + } + + err = ctrl.NewControllerManagedBy(mgr). + For(&api.ChaosPod{}). + Owns(&corev1.Pod{}). + Complete(&reconciler{ + Client: mgr.GetClient(), + scheme: mgr.GetScheme(), + }) + if err != nil { + setupLog.Error(err, "unable to create controller") + os.Exit(1) + } + + err = ctrl.NewWebhookManagedBy(mgr). + For(&api.ChaosPod{}). + Complete() + if err != nil { + setupLog.Error(err, "unable to create webhook") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/groupversion_info.go b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/groupversion_info.go new file mode 100644 index 00000000000..04953dd9398 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +kubebuilder:object:generate=true +// +groupName=chaosapps.metamagical.io +package pkg + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + log = logf.Log.WithName("chaospod-resource") + + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "chaosapps.metamagical.io", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme is required by pkg/client/... + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/resource.go b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/resource.go new file mode 100644 index 00000000000..555029f5de7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/resource.go @@ -0,0 +1,122 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pkg + +import ( + "fmt" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// ChaosPodSpec defines the desired state of ChaosPod +type ChaosPodSpec struct { + Template corev1.PodTemplateSpec `json:"template"` + // +optional + NextStop metav1.Time `json:"nextStop,omitempty"` +} + +// ChaosPodStatus defines the observed state of ChaosPod. +// It should always be reconstructable from the state of the cluster and/or outside world. +type ChaosPodStatus struct { + LastRun metav1.Time `json:"lastRun,omitempty"` +} + +// +kubebuilder:object:root=true + +// ChaosPod is the Schema for the randomjobs API +// +kubebuilder:printcolumn:name="next stop",type="string",JSONPath=".spec.nextStop",format="date" +// +kubebuilder:printcolumn:name="last run",type="string",JSONPath=".status.lastRun",format="date" +type ChaosPod struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ChaosPodSpec `json:"spec,omitempty"` + Status ChaosPodStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ChaosPodList contains a list of ChaosPod +type ChaosPodList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ChaosPod `json:"items"` +} + +// +kubebuilder:webhook:path=/validate-chaosapps-metamagical-io-v1-chaospod,mutating=false,failurePolicy=fail,groups=chaosapps.metamagical.io,resources=chaospods,verbs=create;update,versions=v1,name=vchaospod.kb.io + +var _ webhook.Validator = &ChaosPod{} + +// ValidateCreate implements webhookutil.validator so a webhook will be registered for the type +func (c *ChaosPod) ValidateCreate() (admission.Warnings, error) { + log.Info("validate create", "name", c.Name) + + if c.Spec.NextStop.Before(&metav1.Time{Time: time.Now()}) { + return nil, fmt.Errorf(".spec.nextStop must be later than current time") + } + return nil, nil +} + +// ValidateUpdate implements webhookutil.validator so a webhook will be registered for the type +func (c *ChaosPod) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + log.Info("validate update", "name", c.Name) + + if c.Spec.NextStop.Before(&metav1.Time{Time: time.Now()}) { + return nil, fmt.Errorf(".spec.nextStop must be later than current time") + } + + oldC, ok := old.(*ChaosPod) + if !ok { + return nil, fmt.Errorf("expect old object to be a %T instead of %T", oldC, old) + } + if c.Spec.NextStop.After(oldC.Spec.NextStop.Add(time.Hour)) { + return nil, fmt.Errorf("it is not allowed to delay.spec.nextStop for more than 1 hour") + } + return nil, nil +} + +// ValidateDelete implements webhookutil.validator so a webhook will be registered for the type +func (c *ChaosPod) ValidateDelete() (admission.Warnings, error) { + log.Info("validate delete", "name", c.Name) + + if c.Spec.NextStop.Before(&metav1.Time{Time: time.Now()}) { + return nil, fmt.Errorf(".spec.nextStop must be later than current time") + } + return nil, nil +} + +// +kubebuilder:webhook:path=/mutate-chaosapps-metamagical-io-v1-chaospod,mutating=true,failurePolicy=fail,groups=chaosapps.metamagical.io,resources=chaospods,verbs=create;update,versions=v1,name=mchaospod.kb.io + +var _ webhook.Defaulter = &ChaosPod{} + +// Default implements webhookutil.defaulter so a webhook will be registered for the type +func (c *ChaosPod) Default() { + log.Info("default", "name", c.Name) + + if c.Spec.NextStop.Before(&metav1.Time{Time: time.Now()}) { + c.Spec.NextStop = metav1.Time{Time: time.Now().Add(time.Minute)} + } +} + +func init() { + SchemeBuilder.Register(&ChaosPod{}, &ChaosPodList{}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/zz_generated.deepcopy.go new file mode 100644 index 00000000000..cd506a87c07 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/crd/pkg/zz_generated.deepcopy.go @@ -0,0 +1,121 @@ +// +build !ignore_autogenerated + +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package pkg + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (c *ChaosPod) DeepCopyInto(out *ChaosPod) { + *out = *c + out.TypeMeta = c.TypeMeta + c.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + c.Spec.DeepCopyInto(&out.Spec) + c.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChaosPod. +func (c *ChaosPod) DeepCopy() *ChaosPod { + if c == nil { + return nil + } + out := new(ChaosPod) + c.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (c *ChaosPod) DeepCopyObject() runtime.Object { + if c := c.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChaosPodList) DeepCopyInto(out *ChaosPodList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ChaosPod, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChaosPodList. +func (in *ChaosPodList) DeepCopy() *ChaosPodList { + if in == nil { + return nil + } + out := new(ChaosPodList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ChaosPodList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChaosPodSpec) DeepCopyInto(out *ChaosPodSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) + in.NextStop.DeepCopyInto(&out.NextStop) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChaosPodSpec. +func (in *ChaosPodSpec) DeepCopy() *ChaosPodSpec { + if in == nil { + return nil + } + out := new(ChaosPodSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChaosPodStatus) DeepCopyInto(out *ChaosPodStatus) { + *out = *in + in.LastRun.DeepCopyInto(&out.LastRun) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChaosPodStatus. +func (in *ChaosPodStatus) DeepCopy() *ChaosPodStatus { + if in == nil { + return nil + } + out := new(ChaosPodStatus) + in.DeepCopyInto(out) + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.mod b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.mod new file mode 100644 index 00000000000..59da6b3d9ec --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.mod @@ -0,0 +1,10 @@ +module sigs.k8s.io/controller-runtime/examples/scratch-env + +go 1.15 + +require ( + github.com/spf13/pflag v1.0.5 + sigs.k8s.io/controller-runtime v0.0.0-00010101000000-000000000000 +) + +replace sigs.k8s.io/controller-runtime => ../.. diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.sum b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.sum new file mode 100644 index 00000000000..ffafe857816 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/go.sum @@ -0,0 +1,840 @@ +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/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/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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +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/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= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +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/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/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/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM= +github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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 h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +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/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.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/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +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/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= +github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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.1.0/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.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +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.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/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-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-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-20200520004742-59133d7f0dd7/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20181122145206-62eef0e2fa9b/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-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-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-20200831180312-196b9ba8737a/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/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-20200103221440-774c71fcf114/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-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +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.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +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.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/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-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +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-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +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/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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= +k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= +k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo= +k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= +k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= +k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= +k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= +k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= +k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= +k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= +k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw= +k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210517184530-5a248b5acedc h1:cIS13bDBZaWqngldgGuDypv4z+zjcYgTKv72k6bMAn0= +k8s.io/utils v0.0.0-20210517184530-5a248b5acedc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/main.go new file mode 100644 index 00000000000..b8305ffed39 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/scratch-env/main.go @@ -0,0 +1,132 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + goflag "flag" + "os" + + flag "github.com/spf13/pflag" + "go.uber.org/zap" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logzap "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + crdPaths = flag.StringSlice("crd-paths", nil, "paths to files or directories containing CRDs to install on start") + webhookPaths = flag.StringSlice("webhook-paths", nil, "paths to files or directories containing webhook configurations to install on start") + attachControlPlaneOut = flag.Bool("debug-env", false, "attach to test env (apiserver & etcd) output -- just a convinience flag to force KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT=true") +) + +// have a separate function so we can return an exit code w/o skipping defers +func runMain() int { + loggerOpts := &logzap.Options{ + Development: true, // a sane default + ZapOpts: []zap.Option{zap.AddCaller()}, + } + { + var goFlagSet goflag.FlagSet + loggerOpts.BindFlags(&goFlagSet) + flag.CommandLine.AddGoFlagSet(&goFlagSet) + } + flag.Parse() + ctrl.SetLogger(logzap.New(logzap.UseFlagOptions(loggerOpts))) + ctrl.Log.Info("Starting...") + + log := ctrl.Log.WithName("main") + + env := &envtest.Environment{} + env.CRDInstallOptions.Paths = *crdPaths + env.WebhookInstallOptions.Paths = *webhookPaths + + if *attachControlPlaneOut { + os.Setenv("KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT", "true") + } + + log.Info("Starting apiserver & etcd") + cfg, err := env.Start() + if err != nil { + log.Error(err, "unable to start the test environment") + // shut down the environment in case we started it and failed while + // installing CRDs or provisioning users. + if err := env.Stop(); err != nil { + log.Error(err, "unable to stop the test environment after an error (this might be expected, but just though you should know)") + } + return 1 + } + + log.Info("apiserver running", "host", cfg.Host) + + // NB(directxman12): this group is unfortunately named, but various + // kubernetes versions require us to use it to get "admin" access. + user, err := env.ControlPlane.AddUser(envtest.User{ + Name: "envtest-admin", + Groups: []string{"system:masters"}, + }, nil) + if err != nil { + log.Error(err, "unable to provision admin user, continuing on without it") + return 1 + } + + // TODO(directxman12): add support for writing to a new context in an existing file + kubeconfigFile, err := os.CreateTemp("", "scratch-env-kubeconfig-") + if err != nil { + log.Error(err, "unable to create kubeconfig file, continuing on without it") + return 1 + } + defer os.Remove(kubeconfigFile.Name()) + + { + log := log.WithValues("path", kubeconfigFile.Name()) + log.V(1).Info("Writing kubeconfig") + + kubeConfig, err := user.KubeConfig() + if err != nil { + log.Error(err, "unable to create kubeconfig") + } + + if _, err := kubeconfigFile.Write(kubeConfig); err != nil { + log.Error(err, "unable to save kubeconfig") + return 1 + } + + log.Info("Wrote kubeconfig") + } + + if opts := env.WebhookInstallOptions; opts.LocalServingPort != 0 { + log.Info("webhooks configured for", "host", opts.LocalServingHost, "port", opts.LocalServingPort, "dir", opts.LocalServingCertDir) + } + + ctx := ctrl.SetupSignalHandler() + <-ctx.Done() + + log.Info("Shutting down apiserver & etcd") + err = env.Stop() + if err != nil { + log.Error(err, "unable to stop the test environment") + return 1 + } + + log.Info("Shutdown successful") + return 0 +} + +func main() { + os.Exit(runMain()) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/main.go b/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/main.go new file mode 100644 index 00000000000..d018956f960 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/main.go @@ -0,0 +1,58 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "os" + + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/webhook/authentication" +) + +func init() { + log.SetLogger(zap.New()) +} + +func main() { + entryLog := log.Log.WithName("entrypoint") + + // Setup a Manager + entryLog.Info("setting up manager") + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) + if err != nil { + entryLog.Error(err, "unable to set up overall controller manager") + os.Exit(1) + } + + // Setup webhooks + entryLog.Info("setting up webhook server") + hookServer := mgr.GetWebhookServer() + + entryLog.Info("registering webhooks to the webhook server") + hookServer.Register("/validate-v1-tokenreview", &authentication.Webhook{Handler: &authenticator{}}) + + entryLog.Info("starting manager") + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + entryLog.Error(err, "unable to run manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/tokenreview.go b/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/tokenreview.go new file mode 100644 index 00000000000..cc64545e160 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/examples/tokenreview/tokenreview.go @@ -0,0 +1,37 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + + v1 "k8s.io/api/authentication/v1" + + "sigs.k8s.io/controller-runtime/pkg/webhook/authentication" +) + +// authenticator validates tokenreviews +type authenticator struct { +} + +// authenticator admits a request by the token. +func (a *authenticator) Handle(ctx context.Context, req authentication.Request) authentication.Response { + if req.Spec.Token == "invalid" { + return authentication.Unauthenticated("invalid is an invalid token", v1.UserInfo{}) + } + return authentication.Authenticated("", v1.UserInfo{}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/go.mod b/third_party/sigs.k8s.io/controller-runtime/go.mod new file mode 100644 index 00000000000..d5deefaa598 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/go.mod @@ -0,0 +1,74 @@ +module sigs.k8s.io/controller-runtime + +go 1.20 + +require ( + github.com/evanphx/json-patch v4.12.0+incompatible + github.com/evanphx/json-patch/v5 v5.6.0 + github.com/fsnotify/fsnotify v1.6.0 + github.com/go-logr/logr v1.2.4 + github.com/go-logr/zapr v1.2.4 + github.com/google/go-cmp v0.5.9 + github.com/onsi/ginkgo/v2 v2.9.5 + github.com/onsi/gomega v1.27.7 + github.com/prometheus/client_golang v1.15.1 + github.com/prometheus/client_model v0.4.0 + go.uber.org/goleak v1.2.1 + go.uber.org/zap v1.24.0 + golang.org/x/sys v0.8.0 + gomodules.xyz/jsonpatch/v2 v2.3.0 + k8s.io/api v0.27.2 + k8s.io/apiextensions-apiserver v0.27.2 + k8s.io/apimachinery v0.27.2 + k8s.io/client-go v0.27.2 + k8s.io/component-base v0.27.2 + k8s.io/klog/v2 v2.90.1 + k8s.io/utils v0.0.0-20230209194617-a36077c30491 + sigs.k8s.io/yaml v1.3.0 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.1 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect +) diff --git a/third_party/sigs.k8s.io/controller-runtime/go.sum b/third_party/sigs.k8s.io/controller-runtime/go.sum new file mode 100644 index 00000000000..fd1d80d30e9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/go.sum @@ -0,0 +1,284 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/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/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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.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.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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +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= +gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= +gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +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.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/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-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +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.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.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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= +k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= +k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= +k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= +k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= +k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= +k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= +k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= +k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= +k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/third_party/sigs.k8s.io/controller-runtime/hack/apidiff.sh b/third_party/sigs.k8s.io/controller-runtime/hack/apidiff.sh new file mode 100755 index 00000000000..0167486da1d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/hack/apidiff.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Copyright 2018 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +source $(dirname ${BASH_SOURCE})/common.sh + +REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +cd "${REPO_ROOT}" + +APIDIFF="hack/tools/bin/go-apidiff" + +header_text "fetching and building go-apidiff" +make "${APIDIFF}" + +git status + +header_text "verifying api diff" +header_text "invoking: '${APIDIFF} ${PULL_BASE_SHA} --print-compatible'" +"${APIDIFF}" "${PULL_BASE_SHA}" --print-compatible diff --git a/third_party/sigs.k8s.io/controller-runtime/hack/check-everything.sh b/third_party/sigs.k8s.io/controller-runtime/hack/check-everything.sh new file mode 100755 index 00000000000..09f2a901d4a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/hack/check-everything.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright 2018 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +hack_dir=$(dirname ${BASH_SOURCE}) +source ${hack_dir}/common.sh + +tmp_root=/tmp +kb_root_dir=$tmp_root/kubebuilder + +# Run verification scripts. +${hack_dir}/verify.sh + +# Envtest. +ENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION:-"1.24.2"} + +header_text "installing envtest tools@${ENVTEST_K8S_VERSION} with setup-envtest if necessary" +tmp_bin=/tmp/cr-tests-bin +( + # don't presume to install for the user + cd ${hack_dir}/../tools/setup-envtest + GOBIN=${tmp_bin} go install . +) +export KUBEBUILDER_ASSETS="$(${tmp_bin}/setup-envtest use --use-env -p path "${ENVTEST_K8S_VERSION}")" + +# Run tests. +${hack_dir}/test-all.sh + +header_text "confirming examples compile (via go install)" +go install ${MOD_OPT} ./examples/builtins +go install ${MOD_OPT} ./examples/crd +go install ${MOD_OPT} ./examples/configfile/builtin +go install ${MOD_OPT} ./examples/configfile/custom + +echo "passed" +exit 0 diff --git a/third_party/sigs.k8s.io/controller-runtime/hack/ci-check-everything.sh b/third_party/sigs.k8s.io/controller-runtime/hack/ci-check-everything.sh new file mode 100755 index 00000000000..39b85e91d81 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/hack/ci-check-everything.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Copyright 2018 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +export TRACE=1 + +# Not included or existing by default in Prow +export PATH=$(go env GOPATH)/bin:$PATH +mkdir -p $(go env GOPATH)/bin + +$(dirname ${BASH_SOURCE})/check-everything.sh diff --git a/third_party/sigs.k8s.io/controller-runtime/hack/common.sh b/third_party/sigs.k8s.io/controller-runtime/hack/common.sh new file mode 100755 index 00000000000..eff91ba7b76 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/hack/common.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Copyright 2018 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# Enable tracing in this script off by setting the TRACE variable in your +# environment to any value: +# +# $ TRACE=1 test.sh +TRACE=${TRACE:-""} +if [ -n "$TRACE" ]; then + set -x +fi + +# check if modules are enabled +(go mod edit -json &>/dev/null) +MODULES_ENABLED=$? + +MOD_OPT="" +MODULES_OPT=${MODULES_OPT:-""} +if [[ -n "${MODULES_OPT}" && $MODULES_ENABLED ]]; then + MOD_OPT="-mod=${MODULES_OPT}" +fi + +# Turn colors in this script off by setting the NO_COLOR variable in your +# environment to any value: +# +# $ NO_COLOR=1 test.sh +NO_COLOR=${NO_COLOR:-""} +if [ -z "$NO_COLOR" ]; then + header=$'\e[1;33m' + reset=$'\e[0m' +else + header='' + reset='' +fi + +function header_text { + echo "$header$*$reset" +} diff --git a/third_party/sigs.k8s.io/controller-runtime/hack/ensure-golangci-lint.sh b/third_party/sigs.k8s.io/controller-runtime/hack/ensure-golangci-lint.sh new file mode 100755 index 00000000000..9210f959b00 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/hack/ensure-golangci-lint.sh @@ -0,0 +1,432 @@ +#!/usr/bin/env bash + +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: This script is copied from from https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh. + +set -e + +usage() { + this=$1 + cat </dev/null +} +echoerr() { + echo "$@" 1>&2 +} +log_prefix() { + echo "$0" +} +_logp=6 +log_set_priority() { + _logp="$1" +} +log_priority() { + if test -z "$1"; then + echo "$_logp" + return + fi + [ "$1" -le "$_logp" ] +} +log_tag() { + case $1 in + 0) echo "emerg" ;; + 1) echo "alert" ;; + 2) echo "crit" ;; + 3) echo "err" ;; + 4) echo "warning" ;; + 5) echo "notice" ;; + 6) echo "info" ;; + 7) echo "debug" ;; + *) echo "$1" ;; + esac +} +log_debug() { + log_priority 7 || return 0 + echoerr "$(log_prefix)" "$(log_tag 7)" "$@" +} +log_info() { + log_priority 6 || return 0 + echoerr "$(log_prefix)" "$(log_tag 6)" "$@" +} +log_err() { + log_priority 3 || return 0 + echoerr "$(log_prefix)" "$(log_tag 3)" "$@" +} +log_crit() { + log_priority 2 || return 0 + echoerr "$(log_prefix)" "$(log_tag 2)" "$@" +} +uname_os() { + os=$(uname -s | tr '[:upper:]' '[:lower:]') + case "$os" in + msys*) os="windows" ;; + mingw*) os="windows" ;; + cygwin*) os="windows" ;; + win*) os="windows" ;; + esac + echo "$os" +} +uname_arch() { + arch=$(uname -m) + case $arch in + x86_64) arch="amd64" ;; + x86) arch="386" ;; + i686) arch="386" ;; + i386) arch="386" ;; + aarch64) arch="arm64" ;; + armv5*) arch="armv5" ;; + armv6*) arch="armv6" ;; + armv7*) arch="armv7" ;; + esac + echo ${arch} +} +uname_os_check() { + os=$(uname_os) + case "$os" in + darwin) return 0 ;; + dragonfly) return 0 ;; + freebsd) return 0 ;; + linux) return 0 ;; + android) return 0 ;; + nacl) return 0 ;; + netbsd) return 0 ;; + openbsd) return 0 ;; + plan9) return 0 ;; + solaris) return 0 ;; + windows) return 0 ;; + esac + log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value." + return 1 +} +uname_arch_check() { + arch=$(uname_arch) + case "$arch" in + 386) return 0 ;; + amd64) return 0 ;; + arm64) return 0 ;; + armv5) return 0 ;; + armv6) return 0 ;; + armv7) return 0 ;; + ppc64) return 0 ;; + ppc64le) return 0 ;; + mips) return 0 ;; + mipsle) return 0 ;; + mips64) return 0 ;; + mips64le) return 0 ;; + s390x) return 0 ;; + riscv64) return 0 ;; + amd64p32) return 0 ;; + esac + log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value." + return 1 +} +untar() { + tarball=$1 + case "${tarball}" in + *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;; + *.tar) tar --no-same-owner -xf "${tarball}" ;; + *.zip) unzip "${tarball}" ;; + *) + log_err "untar unknown archive format for ${tarball}" + return 1 + ;; + esac +} +http_download_curl() { + local_file=$1 + source_url=$2 + header=$3 + if [ -z "$header" ]; then + code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url") + else + code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url") + fi + if [ "$code" != "200" ]; then + log_debug "http_download_curl received HTTP status $code" + return 1 + fi + return 0 +} +http_download_wget() { + local_file=$1 + source_url=$2 + header=$3 + if [ -z "$header" ]; then + wget -q -O "$local_file" "$source_url" + else + wget -q --header "$header" -O "$local_file" "$source_url" + fi +} +http_download() { + log_debug "http_download $2" + if is_command curl; then + http_download_curl "$@" + return + elif is_command wget; then + http_download_wget "$@" + return + fi + log_crit "http_download unable to find wget or curl" + return 1 +} +http_copy() { + tmp=$(mktemp) + http_download "${tmp}" "$1" "$2" || return 1 + body=$(cat "$tmp") + rm -f "${tmp}" + echo "$body" +} +github_release() { + owner_repo=$1 + version=$2 + if [ -z "$version" ]; then + giturl="https://api.github.com/repos/${owner_repo}/releases/latest" + else + giturl="https://api.github.com/repos/${owner_repo}/releases/tags/${version}" + fi + json=$(http_copy "$giturl" "Accept:application/json") + test -z "$json" && return 1 + version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name": "//' | sed 's/".*//') + test -z "$version" && return 1 + echo "$version" +} +hash_sha256() { + TARGET=${1:-/dev/stdin} + if is_command gsha256sum; then + hash=$(gsha256sum "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command sha256sum; then + hash=$(sha256sum "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command shasum; then + hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command openssl; then + hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f a + else + log_crit "hash_sha256 unable to find command to compute sha-256 hash" + return 1 + fi +} +hash_sha256_verify() { + TARGET=$1 + checksums=$2 + if [ -z "$checksums" ]; then + log_err "hash_sha256_verify checksum file not specified in arg2" + return 1 + fi + BASENAME=${TARGET##*/} + want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) + if [ -z "$want" ]; then + log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" + return 1 + fi + got=$(hash_sha256 "$TARGET") + if [ "$want" != "$got" ]; then + log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" + return 1 + fi +} +cat /dev/null < 0 && blder.forInput.object == nil { + return errors.New("Owns() can only be used together with For()") + } + for _, own := range blder.ownsInput { + obj, err := blder.project(own.object, own.objectProjection) + if err != nil { + return err + } + src := source.Kind(blder.mgr.GetCache(), obj) + opts := []handler.OwnerOption{} + if !own.matchEveryOwner { + opts = append(opts, handler.OnlyControllerOwner()) + } + hdler := handler.EnqueueRequestForOwner( + blder.mgr.GetScheme(), blder.mgr.GetRESTMapper(), + blder.forInput.object, + opts..., + ) + allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) + allPredicates = append(allPredicates, own.predicates...) + if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { + return err + } + } + + // Do the watch requests + if len(blder.watchesInput) == 0 && blder.forInput.object == nil { + return errors.New("there are no watches configured, controller will never get triggered. Use For(), Owns() or Watches() to set them up") + } + for _, w := range blder.watchesInput { + allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) + allPredicates = append(allPredicates, w.predicates...) + + // If the source of this watch is of type Kind, project it. + if srckind, ok := w.src.(*internalsource.Kind); ok { + typeForSrc, err := blder.project(srckind.Type, w.objectProjection) + if err != nil { + return err + } + srckind.Type = typeForSrc + } + + if err := blder.ctrl.Watch(w.src, w.eventhandler, allPredicates...); err != nil { + return err + } + } + return nil +} + +func (blder *Builder) getControllerName(gvk schema.GroupVersionKind, hasGVK bool) (string, error) { + if blder.name != "" { + return blder.name, nil + } + if !hasGVK { + return "", errors.New("one of For() or Named() must be called") + } + return strings.ToLower(gvk.Kind), nil +} + +func (blder *Builder) doController(r reconcile.Reconciler) error { + globalOpts := blder.mgr.GetControllerOptions() + + ctrlOptions := blder.ctrlOptions + if ctrlOptions.Reconciler == nil { + ctrlOptions.Reconciler = r + } + + // Retrieve the GVK from the object we're reconciling + // to prepopulate logger information, and to optionally generate a default name. + var gvk schema.GroupVersionKind + hasGVK := blder.forInput.object != nil + if hasGVK { + var err error + gvk, err = getGvk(blder.forInput.object, blder.mgr.GetScheme()) + if err != nil { + return err + } + } + + // Setup concurrency. + if ctrlOptions.MaxConcurrentReconciles == 0 && hasGVK { + groupKind := gvk.GroupKind().String() + + if concurrency, ok := globalOpts.GroupKindConcurrency[groupKind]; ok && concurrency > 0 { + ctrlOptions.MaxConcurrentReconciles = concurrency + } + } + + // Setup cache sync timeout. + if ctrlOptions.CacheSyncTimeout == 0 && globalOpts.CacheSyncTimeout > 0 { + ctrlOptions.CacheSyncTimeout = globalOpts.CacheSyncTimeout + } + + controllerName, err := blder.getControllerName(gvk, hasGVK) + if err != nil { + return err + } + + // Setup the logger. + if ctrlOptions.LogConstructor == nil { + log := blder.mgr.GetLogger().WithValues( + "controller", controllerName, + ) + if hasGVK { + log = log.WithValues( + "controllerGroup", gvk.Group, + "controllerKind", gvk.Kind, + ) + } + + ctrlOptions.LogConstructor = func(req *reconcile.Request) logr.Logger { + log := log + if req != nil { + if hasGVK { + log = log.WithValues(gvk.Kind, klog.KRef(req.Namespace, req.Name)) + } + log = log.WithValues( + "namespace", req.Namespace, "name", req.Name, + ) + } + return log + } + } + + // Build the controller and return. + blder.ctrl, err = newController(controllerName, blder.mgr, ctrlOptions) + return err +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/controller_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/controller_test.go new file mode 100644 index 00000000000..dd98c2e5657 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/controller_test.go @@ -0,0 +1,697 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "context" + "fmt" + "strings" + "sync/atomic" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/workqueue" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +type typedNoop struct{} + +func (typedNoop) Reconcile(context.Context, reconcile.Request) (reconcile.Result, error) { + return reconcile.Result{}, nil +} + +type testLogger struct { + logr.Logger +} + +func (l *testLogger) Init(logr.RuntimeInfo) { +} + +func (l *testLogger) Enabled(int) bool { + return true +} + +func (l *testLogger) Info(level int, msg string, keysAndValues ...interface{}) { +} + +func (l *testLogger) WithValues(keysAndValues ...interface{}) logr.LogSink { + return l +} + +func (l *testLogger) WithName(name string) logr.LogSink { + return l +} + +var _ = Describe("application", func() { + BeforeEach(func() { + newController = controller.New + }) + + noop := reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + return reconcile.Result{}, nil + }) + + Describe("New", func() { + It("should return success if given valid objects", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should return error if given two apiType objects in For function", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + For(&appsv1.Deployment{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).To(MatchError(ContainSubstring("For(...) should only be called once, could not assign multiple objects for reconciliation"))) + Expect(instance).To(BeNil()) + }) + + It("should return an error if For and Named function are not called", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + Watches(&appsv1.ReplicaSet{}, &handler.EnqueueRequestForObject{}). + Build(noop) + Expect(err).To(MatchError(ContainSubstring("one of For() or Named() must be called"))) + Expect(instance).To(BeNil()) + }) + + It("should return an error when using Owns without For", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + Named("my_controller"). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).To(MatchError(ContainSubstring("Owns() can only be used together with For()"))) + Expect(instance).To(BeNil()) + + }) + + It("should return an error when there are no watches", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + Named("my_controller"). + Build(noop) + Expect(err).To(MatchError(ContainSubstring("there are no watches configured, controller will never get triggered. Use For(), Owns() or Watches() to set them up"))) + Expect(instance).To(BeNil()) + }) + + It("should allow creating a controllerw without calling For", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + Named("my_controller"). + Watches(&appsv1.ReplicaSet{}, &handler.EnqueueRequestForObject{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should return an error if there is no GVK for an object, and thus we can't default the controller name", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a controller with a bad For type") + instance, err := ControllerManagedBy(m). + For(&fakeType{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).To(MatchError(ContainSubstring("no kind is registered for the type builder.fakeType"))) + Expect(instance).To(BeNil()) + + // NB(directxman12): we don't test non-for types, since errors for + // them now manifest on controller.Start, not controller.Watch. Errors on the For type + // manifest when we try to default the controller name, which is good to double check. + }) + + It("should return an error if it cannot create the controller", func() { + newController = func(name string, mgr manager.Manager, options controller.Options) ( + controller.Controller, error) { + return nil, fmt.Errorf("expected error") + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + Expect(instance).To(BeNil()) + }) + + It("should override max concurrent reconcilers during creation of controller", func() { + const maxConcurrentReconciles = 5 + newController = func(name string, mgr manager.Manager, options controller.Options) ( + controller.Controller, error) { + if options.MaxConcurrentReconciles == maxConcurrentReconciles { + return controller.New(name, mgr, options) + } + return nil, fmt.Errorf("max concurrent reconcilers expected %d but found %d", maxConcurrentReconciles, options.MaxConcurrentReconciles) + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + WithOptions(controller.Options{MaxConcurrentReconciles: maxConcurrentReconciles}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should override max concurrent reconcilers during creation of controller, when using", func() { + const maxConcurrentReconciles = 10 + newController = func(name string, mgr manager.Manager, options controller.Options) ( + controller.Controller, error) { + if options.MaxConcurrentReconciles == maxConcurrentReconciles { + return controller.New(name, mgr, options) + } + return nil, fmt.Errorf("max concurrent reconcilers expected %d but found %d", maxConcurrentReconciles, options.MaxConcurrentReconciles) + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{ + Controller: config.Controller{ + GroupKindConcurrency: map[string]int{ + "ReplicaSet.apps": maxConcurrentReconciles, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should override rate limiter during creation of controller", func() { + rateLimiter := workqueue.DefaultItemBasedRateLimiter() + newController = func(name string, mgr manager.Manager, options controller.Options) (controller.Controller, error) { + if options.RateLimiter == rateLimiter { + return controller.New(name, mgr, options) + } + return nil, fmt.Errorf("rate limiter expected %T but found %T", rateLimiter, options.RateLimiter) + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + WithOptions(controller.Options{RateLimiter: rateLimiter}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should override logger during creation of controller", func() { + + logger := &testLogger{} + newController = func(name string, mgr manager.Manager, options controller.Options) (controller.Controller, error) { + if options.LogConstructor(nil).GetSink() == logger { + return controller.New(name, mgr, options) + } + return nil, fmt.Errorf("logger expected %T but found %T", logger, options.LogConstructor) + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + WithLogConstructor(func(request *reconcile.Request) logr.Logger { + return logr.New(logger) + }). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should prefer reconciler from options during creation of controller", func() { + newController = func(name string, mgr manager.Manager, options controller.Options) (controller.Controller, error) { + if options.Reconciler != (typedNoop{}) { + return nil, fmt.Errorf("Custom reconciler expected %T but found %T", typedNoop{}, options.Reconciler) + } + return controller.New(name, mgr, options) + } + + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + instance, err := ControllerManagedBy(m). + For(&appsv1.ReplicaSet{}). + Owns(&appsv1.ReplicaSet{}). + WithOptions(controller.Options{Reconciler: typedNoop{}}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(instance).NotTo(BeNil()) + }) + + It("should allow multiple controllers for the same kind", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaultValidatorGVK.GroupVersion()} + builder.Register(&TestDefaultValidator{}, &TestDefaultValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + Expect(err).NotTo(HaveOccurred()) + + By("creating the 1st controller") + ctrl1, err := ControllerManagedBy(m). + For(&TestDefaultValidator{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(ctrl1).NotTo(BeNil()) + + By("creating the 2nd controller") + ctrl2, err := ControllerManagedBy(m). + For(&TestDefaultValidator{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(ctrl2).NotTo(BeNil()) + }) + }) + + Describe("Start with ControllerManagedBy", func() { + It("should Reconcile Owns objects", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + bldr := ControllerManagedBy(m). + For(&appsv1.Deployment{}). + Owns(&appsv1.ReplicaSet{}) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "3", m, false, bldr) + }) + + It("should Reconcile Owns objects for every owner", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + bldr := ControllerManagedBy(m). + For(&appsv1.Deployment{}). + Owns(&appsv1.ReplicaSet{}, MatchEveryOwner) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "12", m, false, bldr) + }) + + It("should Reconcile Watches objects", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + bldr := ControllerManagedBy(m). + For(&appsv1.Deployment{}). + Watches( // Equivalent of Owns + &appsv1.ReplicaSet{}, + handler.EnqueueRequestForOwner(m.GetScheme(), m.GetRESTMapper(), &appsv1.Deployment{}, handler.OnlyControllerOwner()), + ) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "4", m, true, bldr) + }) + + It("should Reconcile without For", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + bldr := ControllerManagedBy(m). + Named("Deployment"). + Watches( // Equivalent of For + &appsv1.Deployment{}, &handler.EnqueueRequestForObject{}). + Watches( // Equivalent of Owns + &appsv1.ReplicaSet{}, + handler.EnqueueRequestForOwner(m.GetScheme(), m.GetRESTMapper(), &appsv1.Deployment{}, handler.OnlyControllerOwner()), + ) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "9", m, true, bldr) + }) + }) + + Describe("Set custom predicates", func() { + It("should execute registered predicates only for assigned kind", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + var ( + deployPrctExecuted = false + replicaSetPrctExecuted = false + allPrctExecuted = int64(0) + ) + + deployPrct := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + defer GinkgoRecover() + // check that it was called only for deployment + Expect(e.Object).To(BeAssignableToTypeOf(&appsv1.Deployment{})) + deployPrctExecuted = true + return true + }, + } + + replicaSetPrct := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + defer GinkgoRecover() + // check that it was called only for replicaset + Expect(e.Object).To(BeAssignableToTypeOf(&appsv1.ReplicaSet{})) + replicaSetPrctExecuted = true + return true + }, + } + + allPrct := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + defer GinkgoRecover() + // check that it was called for all registered kinds + Expect(e.Object).Should(Or( + BeAssignableToTypeOf(&appsv1.Deployment{}), + BeAssignableToTypeOf(&appsv1.ReplicaSet{}), + )) + + atomic.AddInt64(&allPrctExecuted, 1) + return true + }, + } + + bldr := ControllerManagedBy(m). + For(&appsv1.Deployment{}, WithPredicates(deployPrct)). + Owns(&appsv1.ReplicaSet{}, WithPredicates(replicaSetPrct)). + WithEventFilter(allPrct) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "5", m, true, bldr) + + Expect(deployPrctExecuted).To(BeTrue(), "Deploy predicated should be called at least once") + Expect(replicaSetPrctExecuted).To(BeTrue(), "ReplicaSet predicated should be called at least once") + Expect(allPrctExecuted).To(BeNumerically(">=", 2), "Global Predicated should be called at least twice") + }) + }) + + Describe("watching with projections", func() { + var mgr manager.Manager + BeforeEach(func() { + // use a cache that intercepts requests for fully typed objects to + // ensure we use the projected versions + var err error + mgr, err = manager.New(cfg, manager.Options{NewCache: newNonTypedOnlyCache}) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should support multiple controllers watching the same metadata kind", func() { + bldr1 := ControllerManagedBy(mgr).For(&appsv1.Deployment{}, OnlyMetadata) + bldr2 := ControllerManagedBy(mgr).For(&appsv1.Deployment{}, OnlyMetadata) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + doReconcileTest(ctx, "6", mgr, true, bldr1, bldr2) + }) + + It("should support watching For, Owns, and Watch as metadata", func() { + statefulSetMaps := make(chan *metav1.PartialObjectMetadata) + + bldr := ControllerManagedBy(mgr). + For(&appsv1.Deployment{}, OnlyMetadata). + Owns(&appsv1.ReplicaSet{}, OnlyMetadata). + Watches(&appsv1.StatefulSet{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) []reconcile.Request { + defer GinkgoRecover() + + ometa := o.(*metav1.PartialObjectMetadata) + statefulSetMaps <- ometa + + // Validate that the GVK is not empty when dealing with PartialObjectMetadata objects. + Expect(o.GetObjectKind().GroupVersionKind()).To(Equal(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "StatefulSet", + })) + return nil + }), + OnlyMetadata) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + doReconcileTest(ctx, "8", mgr, true, bldr) + + By("Creating a new stateful set") + set := &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test1", + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + err := mgr.GetClient().Create(context.TODO(), set) + Expect(err).NotTo(HaveOccurred()) + + By("Checking that the mapping function has been called") + Eventually(func() bool { + metaSet := <-statefulSetMaps + Expect(metaSet.Name).To(Equal(set.Name)) + Expect(metaSet.Namespace).To(Equal(set.Namespace)) + Expect(metaSet.Labels).To(Equal(set.Labels)) + return true + }).Should(BeTrue()) + }) + }) +}) + +// newNonTypedOnlyCache returns a new cache that wraps the normal cache, +// returning an error if normal, typed objects have informers requested. +func newNonTypedOnlyCache(config *rest.Config, opts cache.Options) (cache.Cache, error) { + normalCache, err := cache.New(config, opts) + if err != nil { + return nil, err + } + return &nonTypedOnlyCache{ + Cache: normalCache, + }, nil +} + +// nonTypedOnlyCache is a cache.Cache that only provides metadata & +// unstructured informers. +type nonTypedOnlyCache struct { + cache.Cache +} + +func (c *nonTypedOnlyCache) GetInformer(ctx context.Context, obj client.Object) (cache.Informer, error) { + switch obj.(type) { + case (*metav1.PartialObjectMetadata): + return c.Cache.GetInformer(ctx, obj) + default: + return nil, fmt.Errorf("did not want to provide an informer for normal type %T", obj) + } +} +func (c *nonTypedOnlyCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (cache.Informer, error) { + return nil, fmt.Errorf("don't try to sidestep the restriction on informer types by calling GetInformerForKind") +} + +// TODO(directxman12): this function has too many arguments, and the whole +// "nameSuffix" think is a bit of a hack It should be cleaned up significantly by someone with a bit of time. +func doReconcileTest(ctx context.Context, nameSuffix string, mgr manager.Manager, complete bool, blders ...*Builder) { + deployName := "deploy-name-" + nameSuffix + rsName := "rs-name-" + nameSuffix + + By("Creating the application") + ch := make(chan reconcile.Request) + fn := reconcile.Func(func(_ context.Context, req reconcile.Request) (reconcile.Result, error) { + defer GinkgoRecover() + if !strings.HasSuffix(req.Name, nameSuffix) { + // From different test, ignore this request. Etcd is shared across tests. + return reconcile.Result{}, nil + } + ch <- req + return reconcile.Result{}, nil + }) + + for _, blder := range blders { + if complete { + err := blder.Complete(fn) + Expect(err).NotTo(HaveOccurred()) + } else { + var err error + var c controller.Controller + c, err = blder.Build(fn) + Expect(err).NotTo(HaveOccurred()) + Expect(c).NotTo(BeNil()) + } + } + + By("Starting the application") + go func() { + defer GinkgoRecover() + Expect(mgr.Start(ctx)).NotTo(HaveOccurred()) + }() + + By("Creating a Deployment") + // Expect a Reconcile when the Deployment is managedObjects. + dep := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: deployName, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + err := mgr.GetClient().Create(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for the Deployment Reconcile") + Eventually(ch).Should(Receive(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "default", Name: deployName}}))) + + By("Creating a ReplicaSet") + // Expect a Reconcile when an Owned object is managedObjects. + rs := &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: rsName, + Labels: dep.Spec.Selector.MatchLabels, + OwnerReferences: []metav1.OwnerReference{ + { + Name: deployName, + Kind: "Deployment", + APIVersion: "apps/v1", + Controller: pointer.Bool(true), + UID: dep.UID, + }, + }, + }, + Spec: appsv1.ReplicaSetSpec{ + Selector: dep.Spec.Selector, + Template: dep.Spec.Template, + }, + } + err = mgr.GetClient().Create(ctx, rs) + Expect(err).NotTo(HaveOccurred()) + + By("Waiting for the ReplicaSet Reconcile") + Eventually(ch).Should(Receive(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "default", Name: deployName}}))) +} + +var _ runtime.Object = &fakeType{} + +type fakeType struct { + metav1.TypeMeta + metav1.ObjectMeta +} + +func (*fakeType) GetObjectKind() schema.ObjectKind { return nil } +func (*fakeType) DeepCopyObject() runtime.Object { return nil } diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/doc.go new file mode 100644 index 00000000000..e4df1b709f2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package builder wraps other controller-runtime libraries and exposes simple +// patterns for building common Controllers. +// +// Projects built with the builder package can trivially be rebased on top of the underlying +// packages if the project requires more customized behavior in the future. +package builder + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("builder") diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_test.go new file mode 100644 index 00000000000..652c9b58334 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_test.go @@ -0,0 +1,159 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder_test + +import ( + "context" + "fmt" + "os" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/config" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +func ExampleBuilder_metadata_only() { + logf.SetLogger(zap.New()) + + var log = logf.Log.WithName("builder-examples") + + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) + if err != nil { + log.Error(err, "could not create manager") + os.Exit(1) + } + + cl := mgr.GetClient() + err = builder. + ControllerManagedBy(mgr). // Create the ControllerManagedBy + For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API + Owns(&corev1.Pod{}, builder.OnlyMetadata). // ReplicaSet owns Pods created by it, and caches them as metadata only + Complete(reconcile.Func(func(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { + // Read the ReplicaSet + rs := &appsv1.ReplicaSet{} + err := cl.Get(ctx, req.NamespacedName, rs) + if err != nil { + return reconcile.Result{}, client.IgnoreNotFound(err) + } + + // List the Pods matching the PodTemplate Labels, but only their metadata + var podsMeta metav1.PartialObjectMetadataList + err = cl.List(ctx, &podsMeta, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) + if err != nil { + return reconcile.Result{}, client.IgnoreNotFound(err) + } + + // Update the ReplicaSet + rs.Labels["pod-count"] = fmt.Sprintf("%v", len(podsMeta.Items)) + err = cl.Update(ctx, rs) + if err != nil { + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil + })) + if err != nil { + log.Error(err, "could not create controller") + os.Exit(1) + } + + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "could not start manager") + os.Exit(1) + } +} + +// This example creates a simple application ControllerManagedBy that is configured for ReplicaSets and Pods. +// +// * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into +// ReplicaSetReconciler. +// +// * Start the application. +func ExampleBuilder() { + logf.SetLogger(zap.New()) + + var log = logf.Log.WithName("builder-examples") + + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) + if err != nil { + log.Error(err, "could not create manager") + os.Exit(1) + } + + err = builder. + ControllerManagedBy(mgr). // Create the ControllerManagedBy + For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API + Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it + Complete(&ReplicaSetReconciler{ + Client: mgr.GetClient(), + }) + if err != nil { + log.Error(err, "could not create controller") + os.Exit(1) + } + + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "could not start manager") + os.Exit(1) + } +} + +// ReplicaSetReconciler is a simple ControllerManagedBy example implementation. +type ReplicaSetReconciler struct { + client.Client +} + +// Implement the business logic: +// This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference +// to a ReplicaSet. +// +// * Read the ReplicaSet +// * Read the Pods +// * Set a Label on the ReplicaSet with the Pod count. +func (a *ReplicaSetReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { + // Read the ReplicaSet + rs := &appsv1.ReplicaSet{} + err := a.Get(ctx, req.NamespacedName, rs) + if err != nil { + return reconcile.Result{}, err + } + + // List the Pods matching the PodTemplate Labels + pods := &corev1.PodList{} + err = a.List(ctx, pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) + if err != nil { + return reconcile.Result{}, err + } + + // Update the ReplicaSet + rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items)) + err = a.Update(ctx, rs) + if err != nil { + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_webhook_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_webhook_test.go new file mode 100644 index 00000000000..63333a24782 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/example_webhook_test.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder_test + +import ( + "os" + + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client/config" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + examplegroup "sigs.k8s.io/controller-runtime/examples/crd/pkg" +) + +// examplegroup.ChaosPod has implemented both admission.Defaulter and +// admission.Validator interfaces. +var _ admission.Defaulter = &examplegroup.ChaosPod{} +var _ admission.Validator = &examplegroup.ChaosPod{} + +// This example use webhook builder to create a simple webhook that is managed +// by a manager for CRD ChaosPod. And then start the manager. +func ExampleWebhookBuilder() { + var log = logf.Log.WithName("webhookbuilder-example") + + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) + if err != nil { + log.Error(err, "could not create manager") + os.Exit(1) + } + + err = builder. + WebhookManagedBy(mgr). // Create the WebhookManagedBy + For(&examplegroup.ChaosPod{}). // ChaosPod is a CRD. + Complete() + if err != nil { + log.Error(err, "could not create webhook") + os.Exit(1) + } + + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "could not start manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/options.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/options.go new file mode 100644 index 00000000000..bce2065efaf --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/options.go @@ -0,0 +1,156 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// {{{ "Functional" Option Interfaces + +// ForOption is some configuration that modifies options for a For request. +type ForOption interface { + // ApplyToFor applies this configuration to the given for input. + ApplyToFor(*ForInput) +} + +// OwnsOption is some configuration that modifies options for a owns request. +type OwnsOption interface { + // ApplyToOwns applies this configuration to the given owns input. + ApplyToOwns(*OwnsInput) +} + +// WatchesOption is some configuration that modifies options for a watches request. +type WatchesOption interface { + // ApplyToWatches applies this configuration to the given watches options. + ApplyToWatches(*WatchesInput) +} + +// }}} + +// {{{ Multi-Type Options + +// WithPredicates sets the given predicates list. +func WithPredicates(predicates ...predicate.Predicate) Predicates { + return Predicates{ + predicates: predicates, + } +} + +// Predicates filters events before enqueuing the keys. +type Predicates struct { + predicates []predicate.Predicate +} + +// ApplyToFor applies this configuration to the given ForInput options. +func (w Predicates) ApplyToFor(opts *ForInput) { + opts.predicates = w.predicates +} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (w Predicates) ApplyToOwns(opts *OwnsInput) { + opts.predicates = w.predicates +} + +// ApplyToWatches applies this configuration to the given WatchesInput options. +func (w Predicates) ApplyToWatches(opts *WatchesInput) { + opts.predicates = w.predicates +} + +var _ ForOption = &Predicates{} +var _ OwnsOption = &Predicates{} +var _ WatchesOption = &Predicates{} + +// }}} + +// {{{ For & Owns Dual-Type options + +// asProjection configures the projection (currently only metadata) on the input. +// Currently only metadata is supported. We might want to expand +// this to arbitrary non-special local projections in the future. +type projectAs objectProjection + +// ApplyToFor applies this configuration to the given ForInput options. +func (p projectAs) ApplyToFor(opts *ForInput) { + opts.objectProjection = objectProjection(p) +} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (p projectAs) ApplyToOwns(opts *OwnsInput) { + opts.objectProjection = objectProjection(p) +} + +// ApplyToWatches applies this configuration to the given WatchesInput options. +func (p projectAs) ApplyToWatches(opts *WatchesInput) { + opts.objectProjection = objectProjection(p) +} + +var ( + // OnlyMetadata tells the controller to *only* cache metadata, and to watch + // the API server in metadata-only form. This is useful when watching + // lots of objects, really big objects, or objects for which you only know + // the GVK, but not the structure. You'll need to pass + // metav1.PartialObjectMetadata to the client when fetching objects in your + // reconciler, otherwise you'll end up with a duplicate structured or + // unstructured cache. + // + // When watching a resource with OnlyMetadata, for example the v1.Pod, you + // should not Get and List using the v1.Pod type. Instead, you should use + // the special metav1.PartialObjectMetadata type. + // + // ❌ Incorrect: + // + // pod := &v1.Pod{} + // mgr.GetClient().Get(ctx, nsAndName, pod) + // + // ✅ Correct: + // + // pod := &metav1.PartialObjectMetadata{} + // pod.SetGroupVersionKind(schema.GroupVersionKind{ + // Group: "", + // Version: "v1", + // Kind: "Pod", + // }) + // mgr.GetClient().Get(ctx, nsAndName, pod) + // + // In the first case, controller-runtime will create another cache for the + // concrete type on top of the metadata cache; this increases memory + // consumption and leads to race conditions as caches are not in sync. + OnlyMetadata = projectAs(projectAsMetadata) + + _ ForOption = OnlyMetadata + _ OwnsOption = OnlyMetadata + _ WatchesOption = OnlyMetadata +) + +// }}} + +// MatchEveryOwner determines whether the watch should be filtered based on +// controller ownership. As in, when the OwnerReference.Controller field is set. +// +// If passed as an option, +// the handler receives notification for every owner of the object with the given type. +// If unset (default), the handler receives notification only for the first +// OwnerReference with `Controller: true`. +var MatchEveryOwner = &matchEveryOwner{} + +type matchEveryOwner struct{} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (o matchEveryOwner) ApplyToOwns(opts *OwnsInput) { + opts.matchEveryOwner = true +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go new file mode 100644 index 00000000000..82fac4d8fa6 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go @@ -0,0 +1,251 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "errors" + "net/http" + "net/url" + "strings" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" + + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/controller-runtime/pkg/webhook/conversion" +) + +// WebhookBuilder builds a Webhook. +type WebhookBuilder struct { + apiType runtime.Object + withDefaulter admission.CustomDefaulter + withValidator admission.CustomValidator + gvk schema.GroupVersionKind + mgr manager.Manager + config *rest.Config + recoverPanic bool + logConstructor func(base logr.Logger, req *admission.Request) logr.Logger +} + +// WebhookManagedBy allows inform its manager.Manager. +func WebhookManagedBy(m manager.Manager) *WebhookBuilder { + return &WebhookBuilder{mgr: m} +} + +// TODO(droot): update the GoDoc for conversion. + +// For takes a runtime.Object which should be a CR. +// If the given object implements the admission.Defaulter interface, a MutatingWebhook will be wired for this type. +// If the given object implements the admission.Validator interface, a ValidatingWebhook will be wired for this type. +func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder { + blder.apiType = apiType + return blder +} + +// WithDefaulter takes a admission.WithDefaulter interface, a MutatingWebhook will be wired for this type. +func (blder *WebhookBuilder) WithDefaulter(defaulter admission.CustomDefaulter) *WebhookBuilder { + blder.withDefaulter = defaulter + return blder +} + +// WithValidator takes a admission.WithValidator interface, a ValidatingWebhook will be wired for this type. +func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) *WebhookBuilder { + blder.withValidator = validator + return blder +} + +// WithLogConstructor overrides the webhook's LogConstructor. +func (blder *WebhookBuilder) WithLogConstructor(logConstructor func(base logr.Logger, req *admission.Request) logr.Logger) *WebhookBuilder { + blder.logConstructor = logConstructor + return blder +} + +// RecoverPanic indicates whether the panic caused by webhook should be recovered. +func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder { + blder.recoverPanic = true + return blder +} + +// Complete builds the webhook. +func (blder *WebhookBuilder) Complete() error { + // Set the Config + blder.loadRestConfig() + + // Configure the default LogConstructor + blder.setLogConstructor() + + // Set the Webhook if needed + return blder.registerWebhooks() +} + +func (blder *WebhookBuilder) loadRestConfig() { + if blder.config == nil { + blder.config = blder.mgr.GetConfig() + } +} + +func (blder *WebhookBuilder) setLogConstructor() { + if blder.logConstructor == nil { + blder.logConstructor = func(base logr.Logger, req *admission.Request) logr.Logger { + log := base.WithValues( + "webhookGroup", blder.gvk.Group, + "webhookKind", blder.gvk.Kind, + ) + if req != nil { + return log.WithValues( + blder.gvk.Kind, klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) + } + return log + } + } +} + +func (blder *WebhookBuilder) registerWebhooks() error { + typ, err := blder.getType() + if err != nil { + return err + } + + // Create webhook(s) for each type + blder.gvk, err = apiutil.GVKForObject(typ, blder.mgr.GetScheme()) + if err != nil { + return err + } + + blder.registerDefaultingWebhook() + blder.registerValidatingWebhook() + + err = blder.registerConversionWebhook() + if err != nil { + return err + } + return nil +} + +// registerDefaultingWebhook registers a defaulting webhook if th. +func (blder *WebhookBuilder) registerDefaultingWebhook() { + mwh := blder.getDefaultingWebhook() + if mwh != nil { + mwh.LogConstructor = blder.logConstructor + path := generateMutatePath(blder.gvk) + + // Checking if the path is already registered. + // If so, just skip it. + if !blder.isAlreadyHandled(path) { + log.Info("Registering a mutating webhook", + "GVK", blder.gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, mwh) + } + } +} + +func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook { + if defaulter := blder.withDefaulter; defaulter != nil { + return admission.WithCustomDefaulter(blder.mgr.GetScheme(), blder.apiType, defaulter).WithRecoverPanic(blder.recoverPanic) + } + if defaulter, ok := blder.apiType.(admission.Defaulter); ok { + return admission.DefaultingWebhookFor(blder.mgr.GetScheme(), defaulter).WithRecoverPanic(blder.recoverPanic) + } + log.Info( + "skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called", + "GVK", blder.gvk) + return nil +} + +func (blder *WebhookBuilder) registerValidatingWebhook() { + vwh := blder.getValidatingWebhook() + if vwh != nil { + vwh.LogConstructor = blder.logConstructor + path := generateValidatePath(blder.gvk) + + // Checking if the path is already registered. + // If so, just skip it. + if !blder.isAlreadyHandled(path) { + log.Info("Registering a validating webhook", + "GVK", blder.gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, vwh) + } + } +} + +func (blder *WebhookBuilder) getValidatingWebhook() *admission.Webhook { + if validator := blder.withValidator; validator != nil { + return admission.WithCustomValidator(blder.mgr.GetScheme(), blder.apiType, validator).WithRecoverPanic(blder.recoverPanic) + } + if validator, ok := blder.apiType.(admission.Validator); ok { + return admission.ValidatingWebhookFor(blder.mgr.GetScheme(), validator).WithRecoverPanic(blder.recoverPanic) + } + log.Info( + "skip registering a validating webhook, object does not implement admission.Validator or WithValidator wasn't called", + "GVK", blder.gvk) + return nil +} + +func (blder *WebhookBuilder) registerConversionWebhook() error { + ok, err := conversion.IsConvertible(blder.mgr.GetScheme(), blder.apiType) + if err != nil { + log.Error(err, "conversion check failed", "GVK", blder.gvk) + return err + } + if ok { + if !blder.isAlreadyHandled("/convert") { + blder.mgr.GetWebhookServer().Register("/convert", conversion.NewWebhookHandler(blder.mgr.GetScheme())) + } + log.Info("Conversion webhook enabled", "GVK", blder.gvk) + } + + return nil +} + +func (blder *WebhookBuilder) getType() (runtime.Object, error) { + if blder.apiType != nil { + return blder.apiType, nil + } + return nil, errors.New("For() must be called with a valid object") +} + +func (blder *WebhookBuilder) isAlreadyHandled(path string) bool { + if blder.mgr.GetWebhookServer().WebhookMux() == nil { + return false + } + h, p := blder.mgr.GetWebhookServer().WebhookMux().Handler(&http.Request{URL: &url.URL{Path: path}}) + if p == path && h != nil { + return true + } + return false +} + +func generateMutatePath(gvk schema.GroupVersionKind) string { + return "/mutate-" + strings.ReplaceAll(gvk.Group, ".", "-") + "-" + + gvk.Version + "-" + strings.ToLower(gvk.Kind) +} + +func generateValidatePath(gvk schema.GroupVersionKind) string { + return "/validate-" + strings.ReplaceAll(gvk.Group, ".", "-") + "-" + + gvk.Version + "-" + strings.ToLower(gvk.Kind) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook_test.go new file mode 100644 index 00000000000..54df3919cc0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/builder/webhook_test.go @@ -0,0 +1,930 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "net/http/httptest" + "os" + "strings" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "sigs.k8s.io/controller-runtime/pkg/controller" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/scheme" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +var _ = Describe("webhook", func() { + Describe("New", func() { + Context("v1 AdmissionReview", func() { + runTests("v1") + }) + Context("v1beta1 AdmissionReview", func() { + runTests("v1beta1") + }) + }) +}) + +func runTests(admissionReviewVersion string) { + var ( + stop chan struct{} + logBuffer *gbytes.Buffer + testingLogger logr.Logger + ) + + BeforeEach(func() { + stop = make(chan struct{}) + newController = controller.New + logBuffer = gbytes.NewBuffer() + testingLogger = zap.New(zap.JSONEncoder(), zap.WriteTo(io.MultiWriter(logBuffer, GinkgoWriter))) + }) + + AfterEach(func() { + close(stop) + }) + + It("should scaffold a defaulting webhook if the type implements the Defaulter interface", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaulterGVK.GroupVersion()} + builder.Register(&TestDefaulter{}, &TestDefaulterList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestDefaulter{}). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestDefaulter" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testdefaulter" + }, + "namespace":"default", + "operation":"CREATE", + "object":{ + "replica":1 + }, + "oldObject":null + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path") + path := generateMutatePath(testDefaulterGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable fields") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"patch":`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`)) + + By("sending a request to a validating webhook path that doesn't exist") + path = generateValidatePath(testDefaulterGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusNotFound)) + }) + + It("should scaffold a defaulting webhook which recovers from panics", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaulterGVK.GroupVersion()} + builder.Register(&TestDefaulter{}, &TestDefaulterList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestDefaulter{Panic: true}). + RecoverPanic(). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestDefaulter" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testdefaulter" + }, + "namespace":"default", + "operation":"CREATE", + "object":{ + "replica":1, + "panic":true + }, + "oldObject":null + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path") + path := generateMutatePath(testDefaulterGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable fields") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":500`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"message":"panic: fake panic test [recovered]`)) + }) + + It("should scaffold a defaulting webhook with a custom defaulter", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaulterGVK.GroupVersion()} + builder.Register(&TestDefaulter{}, &TestDefaulterList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + WithDefaulter(&TestCustomDefaulter{}). + For(&TestDefaulter{}). + WithLogConstructor(func(base logr.Logger, req *admission.Request) logr.Logger { + return admission.DefaultLogConstructor(testingLogger, req) + }). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"foo.test.org", + "version":"v1", + "kind":"TestDefaulter" + }, + "resource":{ + "group":"foo.test.org", + "version":"v1", + "resource":"testdefaulter" + }, + "namespace":"default", + "name":"foo", + "operation":"CREATE", + "object":{ + "replica":1 + }, + "oldObject":null + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path") + path := generateMutatePath(testDefaulterGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable fields") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"patch":`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`)) + EventuallyWithOffset(1, logBuffer).Should(gbytes.Say(`"msg":"Defaulting object","object":{"name":"foo","namespace":"default"},"namespace":"default","name":"foo","resource":{"group":"foo.test.org","version":"v1","resource":"testdefaulter"},"user":"","requestID":"07e52e8d-4513-11e9-a716-42010a800270"`)) + + By("sending a request to a validating webhook path that doesn't exist") + path = generateValidatePath(testDefaulterGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusNotFound)) + }) + + It("should scaffold a validating webhook if the type implements the Validator interface", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testValidatorGVK.GroupVersion()} + builder.Register(&TestValidator{}, &TestValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestValidator{}). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestValidator" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testvalidator" + }, + "namespace":"default", + "operation":"UPDATE", + "object":{ + "replica":1 + }, + "oldObject":{ + "replica":2 + } + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path that doesn't exist") + path := generateMutatePath(testValidatorGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusNotFound)) + + By("sending a request to a validating webhook path") + path = generateValidatePath(testValidatorGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":403`)) + }) + + It("should scaffold a validating webhook which recovers from panics", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testValidatorGVK.GroupVersion()} + builder.Register(&TestValidator{}, &TestValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestValidator{Panic: true}). + RecoverPanic(). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestValidator" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testvalidator" + }, + "namespace":"default", + "operation":"CREATE", + "object":{ + "replica":2, + "panic":true + } + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a validating webhook path") + path := generateValidatePath(testValidatorGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":500`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"message":"panic: fake panic test [recovered]`)) + }) + + It("should scaffold a validating webhook with a custom validator", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testValidatorGVK.GroupVersion()} + builder.Register(&TestValidator{}, &TestValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + WithValidator(&TestCustomValidator{}). + For(&TestValidator{}). + WithLogConstructor(func(base logr.Logger, req *admission.Request) logr.Logger { + return admission.DefaultLogConstructor(testingLogger, req) + }). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"foo.test.org", + "version":"v1", + "kind":"TestValidator" + }, + "resource":{ + "group":"foo.test.org", + "version":"v1", + "resource":"testvalidator" + }, + "namespace":"default", + "name":"foo", + "operation":"UPDATE", + "object":{ + "replica":1 + }, + "oldObject":{ + "replica":2 + } + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path that doesn't exist") + path := generateMutatePath(testValidatorGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusNotFound)) + + By("sending a request to a validating webhook path") + path = generateValidatePath(testValidatorGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":403`)) + EventuallyWithOffset(1, logBuffer).Should(gbytes.Say(`"msg":"Validating object","object":{"name":"foo","namespace":"default"},"namespace":"default","name":"foo","resource":{"group":"foo.test.org","version":"v1","resource":"testvalidator"},"user":"","requestID":"07e52e8d-4513-11e9-a716-42010a800270"`)) + }) + + It("should scaffold defaulting and validating webhooks if the type implements both Defaulter and Validator interfaces", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaultValidatorGVK.GroupVersion()} + builder.Register(&TestDefaultValidator{}, &TestDefaultValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestDefaultValidator{}). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestDefaultValidator" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testdefaultvalidator" + }, + "namespace":"default", + "operation":"CREATE", + "object":{ + "replica":1 + }, + "oldObject":null + } +}`) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a mutating webhook path") + path := generateMutatePath(testDefaultValidatorGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"patch":`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`)) + + By("sending a request to a validating webhook path") + path = generateValidatePath(testDefaultValidatorGVK) + _, err = reader.Seek(0, 0) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`)) + }) + + It("should scaffold a validating webhook if the type implements the Validator interface to validate deletes", func() { + By("creating a controller manager") + ctx, cancel := context.WithCancel(context.Background()) + + m, err := manager.New(cfg, manager.Options{}) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testValidatorGVK.GroupVersion()} + builder.Register(&TestValidator{}, &TestValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + err = WebhookManagedBy(m). + For(&TestValidator{}). + Complete() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + svr := m.GetWebhookServer() + ExpectWithOffset(1, svr).NotTo(BeNil()) + + reader := strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestValidator" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testvalidator" + }, + "namespace":"default", + "operation":"DELETE", + "object":null, + "oldObject":{ + "replica":1 + } + } +}`) + + cancel() + err = svr.Start(ctx) + if err != nil && !os.IsNotExist(err) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + } + + By("sending a request to a validating webhook path to check for failed delete") + path := generateValidatePath(testValidatorGVK) + req := httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w := httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":403`)) + + reader = strings.NewReader(`{ + "kind":"AdmissionReview", + "apiVersion":"admission.k8s.io/` + admissionReviewVersion + `", + "request":{ + "uid":"07e52e8d-4513-11e9-a716-42010a800270", + "kind":{ + "group":"", + "version":"v1", + "kind":"TestValidator" + }, + "resource":{ + "group":"", + "version":"v1", + "resource":"testvalidator" + }, + "namespace":"default", + "operation":"DELETE", + "object":null, + "oldObject":{ + "replica":0 + } + } +}`) + By("sending a request to a validating webhook path with correct request") + path = generateValidatePath(testValidatorGVK) + req = httptest.NewRequest("POST", "http://svc-name.svc-ns.svc"+path, reader) + req.Header.Add("Content-Type", "application/json") + w = httptest.NewRecorder() + svr.WebhookMux().ServeHTTP(w, req) + ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK)) + By("sanity checking the response contains reasonable field") + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`)) + ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`)) + }) +} + +// TestDefaulter. +var _ runtime.Object = &TestDefaulter{} + +const testDefaulterKind = "TestDefaulter" + +type TestDefaulter struct { + Replica int `json:"replica,omitempty"` + Panic bool `json:"panic,omitempty"` +} + +var testDefaulterGVK = schema.GroupVersionKind{Group: "foo.test.org", Version: "v1", Kind: testDefaulterKind} + +func (d *TestDefaulter) GetObjectKind() schema.ObjectKind { return d } +func (d *TestDefaulter) DeepCopyObject() runtime.Object { + return &TestDefaulter{ + Replica: d.Replica, + } +} + +func (d *TestDefaulter) GroupVersionKind() schema.GroupVersionKind { + return testDefaulterGVK +} + +func (d *TestDefaulter) SetGroupVersionKind(gvk schema.GroupVersionKind) {} + +var _ runtime.Object = &TestDefaulterList{} + +type TestDefaulterList struct{} + +func (*TestDefaulterList) GetObjectKind() schema.ObjectKind { return nil } +func (*TestDefaulterList) DeepCopyObject() runtime.Object { return nil } + +func (d *TestDefaulter) Default() { + if d.Panic { + panic("fake panic test") + } + if d.Replica < 2 { + d.Replica = 2 + } +} + +// TestValidator. +var _ runtime.Object = &TestValidator{} + +const testValidatorKind = "TestValidator" + +type TestValidator struct { + Replica int `json:"replica,omitempty"` + Panic bool `json:"panic,omitempty"` +} + +var testValidatorGVK = schema.GroupVersionKind{Group: "foo.test.org", Version: "v1", Kind: testValidatorKind} + +func (v *TestValidator) GetObjectKind() schema.ObjectKind { return v } +func (v *TestValidator) DeepCopyObject() runtime.Object { + return &TestValidator{ + Replica: v.Replica, + } +} + +func (v *TestValidator) GroupVersionKind() schema.GroupVersionKind { + return testValidatorGVK +} + +func (v *TestValidator) SetGroupVersionKind(gvk schema.GroupVersionKind) {} + +var _ runtime.Object = &TestValidatorList{} + +type TestValidatorList struct{} + +func (*TestValidatorList) GetObjectKind() schema.ObjectKind { return nil } +func (*TestValidatorList) DeepCopyObject() runtime.Object { return nil } + +var _ admission.Validator = &TestValidator{} + +func (v *TestValidator) ValidateCreate() (admission.Warnings, error) { + if v.Panic { + panic("fake panic test") + } + if v.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + return nil, nil +} + +func (v *TestValidator) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + if v.Panic { + panic("fake panic test") + } + if v.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + if oldObj, ok := old.(*TestValidator); !ok { + return nil, fmt.Errorf("the old object is expected to be %T", oldObj) + } else if v.Replica < oldObj.Replica { + return nil, fmt.Errorf("new replica %v should not be fewer than old replica %v", v.Replica, oldObj.Replica) + } + return nil, nil +} + +func (v *TestValidator) ValidateDelete() (admission.Warnings, error) { + if v.Panic { + panic("fake panic test") + } + if v.Replica > 0 { + return nil, errors.New("number of replica should be less than or equal to 0 to delete") + } + return nil, nil +} + +// TestDefaultValidator. +var _ runtime.Object = &TestDefaultValidator{} + +type TestDefaultValidator struct { + metav1.TypeMeta + metav1.ObjectMeta + + Replica int `json:"replica,omitempty"` +} + +var testDefaultValidatorGVK = schema.GroupVersionKind{Group: "foo.test.org", Version: "v1", Kind: "TestDefaultValidator"} + +func (dv *TestDefaultValidator) GetObjectKind() schema.ObjectKind { return dv } +func (dv *TestDefaultValidator) DeepCopyObject() runtime.Object { + return &TestDefaultValidator{ + Replica: dv.Replica, + } +} + +func (dv *TestDefaultValidator) GroupVersionKind() schema.GroupVersionKind { + return testDefaultValidatorGVK +} + +func (dv *TestDefaultValidator) SetGroupVersionKind(gvk schema.GroupVersionKind) {} + +var _ runtime.Object = &TestDefaultValidatorList{} + +type TestDefaultValidatorList struct{} + +func (*TestDefaultValidatorList) GetObjectKind() schema.ObjectKind { return nil } +func (*TestDefaultValidatorList) DeepCopyObject() runtime.Object { return nil } + +func (dv *TestDefaultValidator) Default() { + if dv.Replica < 2 { + dv.Replica = 2 + } +} + +var _ admission.Validator = &TestDefaultValidator{} + +func (dv *TestDefaultValidator) ValidateCreate() (admission.Warnings, error) { + if dv.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + return nil, nil +} + +func (dv *TestDefaultValidator) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + if dv.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + return nil, nil +} + +func (dv *TestDefaultValidator) ValidateDelete() (admission.Warnings, error) { + if dv.Replica > 0 { + return nil, errors.New("number of replica should be less than or equal to 0 to delete") + } + return nil, nil +} + +// TestCustomDefaulter. + +type TestCustomDefaulter struct{} + +func (*TestCustomDefaulter) Default(ctx context.Context, obj runtime.Object) error { + logf.FromContext(ctx).Info("Defaulting object") + req, err := admission.RequestFromContext(ctx) + if err != nil { + return fmt.Errorf("expected admission.Request in ctx: %w", err) + } + if req.Kind.Kind != testDefaulterKind { + return fmt.Errorf("expected Kind TestDefaulter got %q", req.Kind.Kind) + } + + d := obj.(*TestDefaulter) //nolint:ifshort + if d.Replica < 2 { + d.Replica = 2 + } + return nil +} + +var _ admission.CustomDefaulter = &TestCustomDefaulter{} + +// TestCustomValidator. + +type TestCustomValidator struct{} + +func (*TestCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + logf.FromContext(ctx).Info("Validating object") + req, err := admission.RequestFromContext(ctx) + if err != nil { + return nil, fmt.Errorf("expected admission.Request in ctx: %w", err) + } + if req.Kind.Kind != testValidatorKind { + return nil, fmt.Errorf("expected Kind TestValidator got %q", req.Kind.Kind) + } + + v := obj.(*TestValidator) //nolint:ifshort + if v.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + return nil, nil +} + +func (*TestCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + logf.FromContext(ctx).Info("Validating object") + req, err := admission.RequestFromContext(ctx) + if err != nil { + return nil, fmt.Errorf("expected admission.Request in ctx: %w", err) + } + if req.Kind.Kind != testValidatorKind { + return nil, fmt.Errorf("expected Kind TestValidator got %q", req.Kind.Kind) + } + + v := newObj.(*TestValidator) + old := oldObj.(*TestValidator) + if v.Replica < 0 { + return nil, errors.New("number of replica should be greater than or equal to 0") + } + if v.Replica < old.Replica { + return nil, fmt.Errorf("new replica %v should not be fewer than old replica %v", v.Replica, old.Replica) + } + return nil, nil +} + +func (*TestCustomValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { + logf.FromContext(ctx).Info("Validating object") + req, err := admission.RequestFromContext(ctx) + if err != nil { + return nil, fmt.Errorf("expected admission.Request in ctx: %w", err) + } + if req.Kind.Kind != testValidatorKind { + return nil, fmt.Errorf("expected Kind TestValidator got %q", req.Kind.Kind) + } + + v := obj.(*TestValidator) //nolint:ifshort + if v.Replica > 0 { + return nil, errors.New("number of replica should be less than or equal to 0 to delete") + } + return nil, nil +} + +var _ admission.CustomValidator = &TestCustomValidator{} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache.go new file mode 100644 index 00000000000..57e6eb61883 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache.go @@ -0,0 +1,308 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache + +import ( + "context" + "fmt" + "net/http" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + toolscache "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/controller-runtime/pkg/cache/internal" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var ( + log = logf.RuntimeLog.WithName("object-cache") + defaultSyncPeriod = 10 * time.Hour + + // BlockUntilSynced determines whether a get request for an informer should block + // until the informer's cache has synced. + BlockUntilSynced = internal.BlockUntilSynced +) + +// InformerGetOption defines an option that alters the behavior of how informers are retrieved. +type InformerGetOption internal.InformerGetOption + +func castInformerGetOptions(opts []InformerGetOption) []internal.InformerGetOption { + out := make([]internal.InformerGetOption, len(opts)) + for i := range opts { + out[i] = internal.InformerGetOption(opts[i]) + } + return out +} + +// Cache knows how to load Kubernetes objects, fetch informers to request +// to receive events for Kubernetes objects (at a low-level), +// and add indices to fields on the objects stored in the cache. +type Cache interface { + // Cache acts as a client to objects stored in the cache. + client.Reader + + // Cache loads informers and adds field indices. + Informers +} + +// Informers knows how to create or fetch informers for different +// group-version-kinds, and add indices to those informers. It's safe to call +// GetInformer from multiple threads. +type Informers interface { + // GetInformer fetches or constructs an informer for the given object that corresponds to a single + // API kind and resource. + GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) + + // GetInformerForKind is similar to GetInformer, except that it takes a group-version-kind, instead + // of the underlying object. + GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) + + // Start runs all the informers known to this cache until the context is closed. + // It blocks. + Start(ctx context.Context) error + + // WaitForCacheSync waits for all the caches to sync. Returns false if it could not sync a cache. + WaitForCacheSync(ctx context.Context) bool + + // Informers knows how to add indices to the caches (informers) that it manages. + client.FieldIndexer +} + +// Informer - informer allows you interact with the underlying informer. +type Informer interface { + // AddEventHandler adds an event handler to the shared informer using the shared informer's resync + // period. Events to a single handler are delivered sequentially, but there is no coordination + // between different handlers. + // It returns a registration handle for the handler that can be used to remove + // the handler again. + AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) + // AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the + // specified resync period. Events to a single handler are delivered sequentially, but there is + // no coordination between different handlers. + // It returns a registration handle for the handler that can be used to remove + // the handler again and an error if the handler cannot be added. + AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) + // RemoveEventHandler removes a formerly added event handler given by + // its registration handle. + // This function is guaranteed to be idempotent, and thread-safe. + RemoveEventHandler(handle toolscache.ResourceEventHandlerRegistration) error + // AddIndexers adds more indexers to this store. If you call this after you already have data + // in the store, the results are undefined. + AddIndexers(indexers toolscache.Indexers) error + // HasSynced return true if the informers underlying store has synced. + HasSynced() bool +} + +// Options are the optional arguments for creating a new InformersMap object. +type Options struct { + // HTTPClient is the http client to use for the REST client + HTTPClient *http.Client + + // Scheme is the scheme to use for mapping objects to GroupVersionKinds + Scheme *runtime.Scheme + + // Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources + Mapper meta.RESTMapper + + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // + // This applies to all controllers. + // + // A period sync happens for two reasons: + // 1. To insure against a bug in the controller that causes an object to not + // be requeued, when it otherwise should be requeued. + // 2. To insure against an unknown bug in controller-runtime, or its dependencies, + // that causes an object to not be requeued, when it otherwise should be + // requeued, or to be removed from the queue, when it otherwise should not + // be removed. + // + // If you want + // 1. to insure against missed watch events, or + // 2. to poll services that cannot be watched, + // then we recommend that, instead of changing the default period, the + // controller requeue, with a constant duration `t`, whenever the controller + // is "done" with an object, and would otherwise not requeue it, i.e., we + // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, + // instead of `reconcile.Result{}`. + SyncPeriod *time.Duration + + // Namespaces restricts the cache's ListWatch to the desired namespaces + // Default watches all namespaces + Namespaces []string + + // DefaultLabelSelector will be used as a label selectors for all object types + // unless they have a more specific selector set in ByObject. + DefaultLabelSelector labels.Selector + + // DefaultFieldSelector will be used as a field selectors for all object types + // unless they have a more specific selector set in ByObject. + DefaultFieldSelector fields.Selector + + // DefaultTransform will be used as transform for all object types + // unless they have a more specific transform set in ByObject. + DefaultTransform toolscache.TransformFunc + + // ByObject restricts the cache's ListWatch to the desired fields per GVK at the specified object. + ByObject map[client.Object]ByObject + + // UnsafeDisableDeepCopy indicates not to deep copy objects during get or + // list objects for EVERY object. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + // + // This is a global setting for all objects, and can be overridden by the ByObject setting. + UnsafeDisableDeepCopy *bool +} + +// ByObject offers more fine-grained control over the cache's ListWatch by object. +type ByObject struct { + // Label represents a label selector for the object. + Label labels.Selector + + // Field represents a field selector for the object. + Field fields.Selector + + // Transform is a map from objects to transformer functions which + // get applied when objects of the transformation are about to be committed + // to cache. + // + // This function is called both for new objects to enter the cache, + // and for updated objects. + Transform toolscache.TransformFunc + + // UnsafeDisableDeepCopy indicates not to deep copy objects during get or + // list objects per GVK at the specified object. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + UnsafeDisableDeepCopy *bool +} + +// NewCacheFunc - Function for creating a new cache from the options and a rest config. +type NewCacheFunc func(config *rest.Config, opts Options) (Cache, error) + +// New initializes and returns a new Cache. +func New(config *rest.Config, opts Options) (Cache, error) { + if len(opts.Namespaces) == 0 { + opts.Namespaces = []string{metav1.NamespaceAll} + } + if len(opts.Namespaces) > 1 { + return newMultiNamespaceCache(config, opts) + } + + opts, err := defaultOpts(config, opts) + if err != nil { + return nil, err + } + + byGVK, err := convertToInformerOptsByGVK(opts.ByObject, opts.Scheme) + if err != nil { + return nil, err + } + // Set the default selector and transform. + byGVK[schema.GroupVersionKind{}] = internal.InformersOptsByGVK{ + Selector: internal.Selector{ + Label: opts.DefaultLabelSelector, + Field: opts.DefaultFieldSelector, + }, + Transform: opts.DefaultTransform, + UnsafeDisableDeepCopy: opts.UnsafeDisableDeepCopy, + } + + return &informerCache{ + scheme: opts.Scheme, + Informers: internal.NewInformers(config, &internal.InformersOpts{ + HTTPClient: opts.HTTPClient, + Scheme: opts.Scheme, + Mapper: opts.Mapper, + ResyncPeriod: *opts.SyncPeriod, + Namespace: opts.Namespaces[0], + ByGVK: byGVK, + }), + }, nil +} + +func defaultOpts(config *rest.Config, opts Options) (Options, error) { + logger := log.WithName("setup") + + // Use the rest HTTP client for the provided config if unset + if opts.HTTPClient == nil { + var err error + opts.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + logger.Error(err, "Failed to get HTTP client") + return opts, fmt.Errorf("could not create HTTP client from config: %w", err) + } + } + + // Use the default Kubernetes Scheme if unset + if opts.Scheme == nil { + opts.Scheme = scheme.Scheme + } + + // Construct a new Mapper if unset + if opts.Mapper == nil { + var err error + opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config, opts.HTTPClient) + if err != nil { + logger.Error(err, "Failed to get API Group-Resources") + return opts, fmt.Errorf("could not create RESTMapper from config: %w", err) + } + } + + // Default the resync period to 10 hours if unset + if opts.SyncPeriod == nil { + opts.SyncPeriod = &defaultSyncPeriod + } + return opts, nil +} + +func convertToInformerOptsByGVK(in map[client.Object]ByObject, scheme *runtime.Scheme) (map[schema.GroupVersionKind]internal.InformersOptsByGVK, error) { + out := map[schema.GroupVersionKind]internal.InformersOptsByGVK{} + for object, byObject := range in { + gvk, err := apiutil.GVKForObject(object, scheme) + if err != nil { + return nil, err + } + if _, ok := out[gvk]; ok { + return nil, fmt.Errorf("duplicate cache options for GVK %v, cache.Options.ByObject has multiple types with the same GroupVersionKind", gvk) + } + out[gvk] = internal.InformersOptsByGVK{ + Selector: internal.Selector{ + Field: byObject.Field, + Label: byObject.Label, + }, + Transform: byObject.Transform, + UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy, + } + } + return out, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_suite_test.go similarity index 76% rename from third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_suite_test.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_suite_test.go index 0f603cb2e61..a9a5152ce85 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_suite_test.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_suite_test.go @@ -14,28 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache_test +package cache_test import ( "testing" - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/envtest/printer" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" ) func TestSource(t *testing.T) { RegisterFailHandler(Fail) - suiteName := "Cache Suite" - RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)}) + RunSpecs(t, "Cache Suite") } var testenv *envtest.Environment @@ -53,7 +48,7 @@ var _ = BeforeSuite(func() { clientset, err = kubernetes.NewForConfig(cfg) Expect(err).NotTo(HaveOccurred()) -}, 60) +}) var _ = AfterSuite(func() { Expect(testenv.Stop()).To(Succeed()) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_test.go new file mode 100644 index 00000000000..7f9ed975d6d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/cache_test.go @@ -0,0 +1,1817 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache_test + +import ( + "context" + "fmt" + "reflect" + "sort" + "strconv" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + kscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + kcache "k8s.io/client-go/tools/cache" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const testNodeOne = "test-node-1" +const testNamespaceOne = "test-namespace-1" +const testNamespaceTwo = "test-namespace-2" +const testNamespaceThree = "test-namespace-3" + +// TODO(community): Pull these helper functions into testenv. +// Restart policy is included to allow indexing on that field. +func createPodWithLabels(name, namespace string, restartPolicy corev1.RestartPolicy, labels map[string]string) client.Object { + three := int64(3) + if labels == nil { + labels = map[string]string{} + } + labels["test-label"] = name + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: labels, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}, + RestartPolicy: restartPolicy, + ActiveDeadlineSeconds: &three, + }, + } + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + err = cl.Create(context.Background(), pod) + Expect(err).NotTo(HaveOccurred()) + return pod +} + +func createSvc(name, namespace string, cl client.Client) client.Object { + svc := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 1}}, + }, + } + err := cl.Create(context.Background(), svc) + Expect(err).NotTo(HaveOccurred()) + return svc +} + +func createSA(name, namespace string, cl client.Client) client.Object { + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + err := cl.Create(context.Background(), sa) + Expect(err).NotTo(HaveOccurred()) + return sa +} + +func createPod(name, namespace string, restartPolicy corev1.RestartPolicy) client.Object { + return createPodWithLabels(name, namespace, restartPolicy, nil) +} + +func deletePod(pod client.Object) { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + err = cl.Delete(context.Background(), pod) + Expect(err).NotTo(HaveOccurred()) +} + +var _ = Describe("Informer Cache", func() { + CacheTest(cache.New, cache.Options{}) +}) +var _ = Describe("Multi-Namespace Informer Cache", func() { + CacheTest(cache.MultiNamespacedCacheBuilder([]string{testNamespaceOne, testNamespaceTwo, "default"}), cache.Options{}) +}) + +var _ = Describe("Informer Cache without global DeepCopy", func() { + CacheTest(cache.New, cache.Options{ + UnsafeDisableDeepCopy: pointer.Bool(true), + }) +}) + +var _ = Describe("Cache with transformers", func() { + var ( + informerCache cache.Cache + informerCacheCtx context.Context + informerCacheCancel context.CancelFunc + knownPod1 client.Object + knownPod2 client.Object + knownPod3 client.Object + knownPod4 client.Object + knownPod5 client.Object + knownPod6 client.Object + ) + + getTransformValue := func(obj client.Object) string { + accessor, err := meta.Accessor(obj) + if err == nil { + annotations := accessor.GetAnnotations() + if val, exists := annotations["transformed"]; exists { + return val + } + } + return "" + } + + BeforeEach(func() { + informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background()) + Expect(cfg).NotTo(BeNil()) + + By("creating three pods") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + err = ensureNode(testNodeOne, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceOne, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceTwo, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceThree, cl) + Expect(err).NotTo(HaveOccurred()) + // Includes restart policy since these objects are indexed on this field. + knownPod1 = createPod("test-pod-1", testNamespaceOne, corev1.RestartPolicyNever) + knownPod2 = createPod("test-pod-2", testNamespaceTwo, corev1.RestartPolicyAlways) + knownPod3 = createPodWithLabels("test-pod-3", testNamespaceTwo, corev1.RestartPolicyOnFailure, map[string]string{"common-label": "common"}) + knownPod4 = createPodWithLabels("test-pod-4", testNamespaceThree, corev1.RestartPolicyNever, map[string]string{"common-label": "common"}) + knownPod5 = createPod("test-pod-5", testNamespaceOne, corev1.RestartPolicyNever) + knownPod6 = createPod("test-pod-6", testNamespaceTwo, corev1.RestartPolicyAlways) + + podGVK := schema.GroupVersionKind{ + Kind: "Pod", + Version: "v1", + } + + knownPod1.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod2.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod3.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod4.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod5.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod6.GetObjectKind().SetGroupVersionKind(podGVK) + + By("creating the informer cache") + informerCache, err = cache.New(cfg, cache.Options{ + DefaultTransform: func(i interface{}) (interface{}, error) { + obj := i.(runtime.Object) + Expect(obj).NotTo(BeNil()) + + accessor, err := meta.Accessor(obj) + Expect(err).To(BeNil()) + annotations := accessor.GetAnnotations() + + if _, exists := annotations["transformed"]; exists { + // Avoid performing transformation multiple times. + return i, nil + } + + if annotations == nil { + annotations = make(map[string]string) + } + annotations["transformed"] = "default" + accessor.SetAnnotations(annotations) + return i, nil + }, + ByObject: map[client.Object]cache.ByObject{ + &corev1.Pod{}: { + Transform: func(i interface{}) (interface{}, error) { + obj := i.(runtime.Object) + Expect(obj).NotTo(BeNil()) + accessor, err := meta.Accessor(obj) + Expect(err).To(BeNil()) + + annotations := accessor.GetAnnotations() + if _, exists := annotations["transformed"]; exists { + // Avoid performing transformation multiple times. + return i, nil + } + + if annotations == nil { + annotations = make(map[string]string) + } + annotations["transformed"] = "explicit" + accessor.SetAnnotations(annotations) + return i, nil + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + By("running the cache and waiting for it to sync") + // pass as an arg so that we don't race between close and re-assign + go func(ctx context.Context) { + defer GinkgoRecover() + Expect(informerCache.Start(ctx)).To(Succeed()) + }(informerCacheCtx) + Expect(informerCache.WaitForCacheSync(informerCacheCtx)).To(BeTrue()) + }) + + AfterEach(func() { + By("cleaning up created pods") + deletePod(knownPod1) + deletePod(knownPod2) + deletePod(knownPod3) + deletePod(knownPod4) + deletePod(knownPod5) + deletePod(knownPod6) + + informerCacheCancel() + }) + + Context("with structured objects", func() { + It("should apply transformers to explicitly specified GVKS", func() { + By("listing pods") + out := corev1.PodList{} + Expect(informerCache.List(context.Background(), &out)).To(Succeed()) + + By("verifying that the returned pods were transformed") + for i := 0; i < len(out.Items); i++ { + Expect(getTransformValue(&out.Items[i])).To(BeIdenticalTo("explicit")) + } + }) + + It("should apply default transformer to objects when none is specified", func() { + By("getting the Kubernetes service") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service was transformed") + Expect(getTransformValue(svc)).To(BeIdenticalTo("default")) + }) + }) + + Context("with unstructured objects", func() { + It("should apply transformers to explicitly specified GVKS", func() { + By("listing pods") + out := unstructured.UnstructuredList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + Expect(informerCache.List(context.Background(), &out)).To(Succeed()) + + By("verifying that the returned pods were transformed") + for i := 0; i < len(out.Items); i++ { + Expect(getTransformValue(&out.Items[i])).To(BeIdenticalTo("explicit")) + } + }) + + It("should apply default transformer to objects when none is specified", func() { + By("getting the Kubernetes service") + svc := &unstructured.Unstructured{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service was transformed") + Expect(getTransformValue(svc)).To(BeIdenticalTo("default")) + }) + }) + + Context("with metadata-only objects", func() { + It("should apply transformers to explicitly specified GVKS", func() { + By("listing pods") + out := metav1.PartialObjectMetadataList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + Expect(informerCache.List(context.Background(), &out)).To(Succeed()) + + By("verifying that the returned pods were transformed") + for i := 0; i < len(out.Items); i++ { + Expect(getTransformValue(&out.Items[i])).To(BeIdenticalTo("explicit")) + } + }) + It("should apply default transformer to objects when none is specified", func() { + By("getting the Kubernetes service") + svc := &metav1.PartialObjectMetadata{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service was transformed") + Expect(getTransformValue(svc)).To(BeIdenticalTo("default")) + }) + }) +}) + +var _ = Describe("Cache with selectors", func() { + defer GinkgoRecover() + var ( + informerCache cache.Cache + informerCacheCtx context.Context + informerCacheCancel context.CancelFunc + ) + + BeforeEach(func() { + informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background()) + Expect(cfg).NotTo(BeNil()) + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceOne, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceTwo, cl) + Expect(err).NotTo(HaveOccurred()) + for idx, namespace := range []string{testNamespaceOne, testNamespaceTwo} { + _ = createSA("test-sa-"+strconv.Itoa(idx), namespace, cl) + _ = createSvc("test-svc-"+strconv.Itoa(idx), namespace, cl) + } + + opts := cache.Options{ + DefaultFieldSelector: fields.OneTermEqualSelector("metadata.namespace", testNamespaceTwo), + ByObject: map[client.Object]cache.ByObject{ + &corev1.ServiceAccount{}: {Field: fields.OneTermEqualSelector("metadata.namespace", testNamespaceOne)}, + }, + } + + By("creating the informer cache") + informerCache, err = cache.New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + By("running the cache and waiting for it to sync") + // pass as an arg so that we don't race between close and re-assign + go func(ctx context.Context) { + defer GinkgoRecover() + Expect(informerCache.Start(ctx)).To(Succeed()) + }(informerCacheCtx) + Expect(informerCache.WaitForCacheSync(informerCacheCtx)).To(BeTrue()) + }) + + AfterEach(func() { + ctx := context.Background() + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + for idx, namespace := range []string{testNamespaceOne, testNamespaceTwo} { + err = cl.Delete(ctx, &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "test-sa-" + strconv.Itoa(idx)}}) + Expect(err).NotTo(HaveOccurred()) + err = cl.Delete(ctx, &corev1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "test-svc-" + strconv.Itoa(idx)}}) + Expect(err).NotTo(HaveOccurred()) + } + informerCacheCancel() + }) + + It("Should list serviceaccounts and find exactly one in namespace "+testNamespaceOne, func() { + var sas corev1.ServiceAccountList + err := informerCache.List(informerCacheCtx, &sas) + Expect(err).NotTo(HaveOccurred()) + Expect(len(sas.Items)).To(Equal(1)) + Expect(sas.Items[0].Namespace).To(Equal(testNamespaceOne)) + }) + + It("Should list services and find exactly one in namespace "+testNamespaceTwo, func() { + var svcs corev1.ServiceList + err := informerCache.List(informerCacheCtx, &svcs) + Expect(err).NotTo(HaveOccurred()) + Expect(len(svcs.Items)).To(Equal(1)) + Expect(svcs.Items[0].Namespace).To(Equal(testNamespaceTwo)) + }) +}) + +func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (cache.Cache, error), opts cache.Options) { + Describe("Cache test", func() { + var ( + informerCache cache.Cache + informerCacheCtx context.Context + informerCacheCancel context.CancelFunc + knownPod1 client.Object + knownPod2 client.Object + knownPod3 client.Object + knownPod4 client.Object + knownPod5 client.Object + knownPod6 client.Object + ) + + BeforeEach(func() { + informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background()) + Expect(cfg).NotTo(BeNil()) + + By("creating three pods") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + err = ensureNode(testNodeOne, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceOne, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceTwo, cl) + Expect(err).NotTo(HaveOccurred()) + err = ensureNamespace(testNamespaceThree, cl) + Expect(err).NotTo(HaveOccurred()) + // Includes restart policy since these objects are indexed on this field. + knownPod1 = createPod("test-pod-1", testNamespaceOne, corev1.RestartPolicyNever) + knownPod2 = createPod("test-pod-2", testNamespaceTwo, corev1.RestartPolicyAlways) + knownPod3 = createPodWithLabels("test-pod-3", testNamespaceTwo, corev1.RestartPolicyOnFailure, map[string]string{"common-label": "common"}) + knownPod4 = createPodWithLabels("test-pod-4", testNamespaceThree, corev1.RestartPolicyNever, map[string]string{"common-label": "common"}) + knownPod5 = createPod("test-pod-5", testNamespaceOne, corev1.RestartPolicyNever) + knownPod6 = createPod("test-pod-6", testNamespaceTwo, corev1.RestartPolicyAlways) + + podGVK := schema.GroupVersionKind{ + Kind: "Pod", + Version: "v1", + } + + knownPod1.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod2.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod3.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod4.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod5.GetObjectKind().SetGroupVersionKind(podGVK) + knownPod6.GetObjectKind().SetGroupVersionKind(podGVK) + + By("creating the informer cache") + informerCache, err = createCacheFunc(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + By("running the cache and waiting for it to sync") + // pass as an arg so that we don't race between close and re-assign + go func(ctx context.Context) { + defer GinkgoRecover() + Expect(informerCache.Start(ctx)).To(Succeed()) + }(informerCacheCtx) + Expect(informerCache.WaitForCacheSync(informerCacheCtx)).To(BeTrue()) + }) + + AfterEach(func() { + By("cleaning up created pods") + deletePod(knownPod1) + deletePod(knownPod2) + deletePod(knownPod3) + deletePod(knownPod4) + deletePod(knownPod5) + deletePod(knownPod6) + + informerCacheCancel() + }) + + Describe("as a Reader", func() { + Context("with structured objects", func() { + It("should be able to list objects that haven't been watched previously", func() { + By("listing all services in the cluster") + listObj := &corev1.ServiceList{} + Expect(informerCache.List(context.Background(), listObj)).To(Succeed()) + + By("verifying that the returned list contains the Kubernetes service") + // NB: kubernetes default service is automatically created in testenv. + Expect(listObj.Items).NotTo(BeEmpty()) + hasKubeService := false + for i := range listObj.Items { + svc := &listObj.Items[i] + if isKubeService(svc) { + hasKubeService = true + break + } + } + Expect(hasKubeService).To(BeTrue()) + }) + + It("should be able to get objects that haven't been watched previously", func() { + By("getting the Kubernetes service") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service looks reasonable") + Expect(svc.Name).To(Equal("kubernetes")) + Expect(svc.Namespace).To(Equal("default")) + }) + + It("should support filtering by labels in a single namespace", func() { + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := corev1.PodList{} + Expect(informerCache.List(context.Background(), &out, + client.InNamespace(testNamespaceTwo), + client.MatchingLabels(map[string]string{"test-label": "test-pod-2"}))).To(Succeed()) + + By("verifying the returned pods have the correct label") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(1)) + actual := out.Items[0] + Expect(actual.Labels["test-label"]).To(Equal("test-pod-2")) + }) + + It("should support filtering by labels from multiple namespaces", func() { + By("creating another pod with the same label but different namespace") + anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) + defer deletePod(anotherPod) + + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := corev1.PodList{} + labels := map[string]string{"test-label": "test-pod-2"} + Expect(informerCache.List(context.Background(), &out, client.MatchingLabels(labels))).To(Succeed()) + + By("verifying multiple pods with the same label in different namespaces are returned") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(2)) + for _, actual := range out.Items { + Expect(actual.Labels["test-label"]).To(Equal("test-pod-2")) + } + }) + + if !isPodDisableDeepCopy(opts) { + It("should be able to list objects with GVK populated", func() { + By("listing pods") + out := &corev1.PodList{} + Expect(informerCache.List(context.Background(), out)).To(Succeed()) + + By("verifying that the returned pods have GVK populated") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(SatisfyAny(HaveLen(5), HaveLen(6))) + for _, p := range out.Items { + Expect(p.GroupVersionKind()).To(Equal(corev1.SchemeGroupVersion.WithKind("Pod"))) + } + }) + } + + It("should be able to list objects by namespace", func() { + By("listing pods in test-namespace-1") + listObj := &corev1.PodList{} + Expect(informerCache.List(context.Background(), listObj, + client.InNamespace(testNamespaceOne))).To(Succeed()) + + By("verifying that the returned pods are in test-namespace-1") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(2)) + for _, item := range listObj.Items { + Expect(item.Namespace).To(Equal(testNamespaceOne)) + } + }) + + if !isPodDisableDeepCopy(opts) { + It("should deep copy the object unless told otherwise", func() { + By("retrieving a specific pod from the cache") + out := &corev1.Pod{} + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) + + By("verifying the retrieved pod is equal to a known pod") + Expect(out).To(Equal(knownPod2)) + + By("altering a field in the retrieved pod") + *out.Spec.ActiveDeadlineSeconds = 4 + + By("verifying the pods are no longer equal") + Expect(out).NotTo(Equal(knownPod2)) + }) + } else { + It("should not deep copy the object if UnsafeDisableDeepCopy is enabled", func() { + By("getting a specific pod from the cache twice") + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + out1 := &corev1.Pod{} + Expect(informerCache.Get(context.Background(), podKey, out1)).To(Succeed()) + out2 := &corev1.Pod{} + Expect(informerCache.Get(context.Background(), podKey, out2)).To(Succeed()) + + By("verifying the pointer fields in pod have the same addresses") + Expect(out1).To(Equal(out2)) + Expect(reflect.ValueOf(out1.Labels).Pointer()).To(BeIdenticalTo(reflect.ValueOf(out2.Labels).Pointer())) + + By("listing pods from the cache twice") + outList1 := &corev1.PodList{} + Expect(informerCache.List(context.Background(), outList1, client.InNamespace(testNamespaceOne))).To(Succeed()) + outList2 := &corev1.PodList{} + Expect(informerCache.List(context.Background(), outList2, client.InNamespace(testNamespaceOne))).To(Succeed()) + + By("verifying the pointer fields in pod have the same addresses") + Expect(len(outList1.Items)).To(Equal(len(outList2.Items))) + sort.SliceStable(outList1.Items, func(i, j int) bool { return outList1.Items[i].Name <= outList1.Items[j].Name }) + sort.SliceStable(outList2.Items, func(i, j int) bool { return outList2.Items[i].Name <= outList2.Items[j].Name }) + for i := range outList1.Items { + a := &outList1.Items[i] + b := &outList2.Items[i] + Expect(a).To(Equal(b)) + Expect(reflect.ValueOf(a.Labels).Pointer()).To(BeIdenticalTo(reflect.ValueOf(b.Labels).Pointer())) + } + }) + } + + It("should return an error if the object is not found", func() { + By("getting a service that does not exists") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should return an error if getting object in unwatched namespace", func() { + By("getting a service that does not exists") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + }) + + It("should return an error when context is cancelled", func() { + By("cancelling the context") + informerCacheCancel() + + By("listing pods in test-namespace-1 with a cancelled context") + listObj := &corev1.PodList{} + err := informerCache.List(informerCacheCtx, listObj, client.InNamespace(testNamespaceOne)) + + By("verifying that an error is returned") + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsTimeout(err)).To(BeTrue()) + }) + + It("should set the Limit option and limit number of objects to Limit when List is called", func() { + opts := &client.ListOptions{Limit: int64(3)} + By("verifying that only Limit (3) number of objects are retrieved from the cache") + listObj := &corev1.PodList{} + Expect(informerCache.List(context.Background(), listObj, opts)).To(Succeed()) + Expect(listObj.Items).Should(HaveLen(3)) + }) + + It("should return a limited result set matching the correct label", func() { + listObj := &corev1.PodList{} + labelOpt := client.MatchingLabels(map[string]string{"common-label": "common"}) + limitOpt := client.Limit(1) + By("verifying that only Limit (1) number of objects are retrieved from the cache") + Expect(informerCache.List(context.Background(), listObj, labelOpt, limitOpt)).To(Succeed()) + Expect(listObj.Items).Should(HaveLen(1)) + }) + }) + + Context("with unstructured objects", func() { + It("should be able to list objects that haven't been watched previously", func() { + By("listing all services in the cluster") + listObj := &unstructured.UnstructuredList{} + listObj.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "ServiceList", + }) + err := informerCache.List(context.Background(), listObj) + Expect(err).To(Succeed()) + + By("verifying that the returned list contains the Kubernetes service") + // NB: kubernetes default service is automatically created in testenv. + Expect(listObj.Items).NotTo(BeEmpty()) + hasKubeService := false + for i := range listObj.Items { + svc := &listObj.Items[i] + if isKubeService(svc) { + hasKubeService = true + break + } + } + Expect(hasKubeService).To(BeTrue()) + }) + It("should be able to get objects that haven't been watched previously", func() { + By("getting the Kubernetes service") + svc := &unstructured.Unstructured{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service looks reasonable") + Expect(svc.GetName()).To(Equal("kubernetes")) + Expect(svc.GetNamespace()).To(Equal("default")) + }) + + It("should support filtering by labels in a single namespace", func() { + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := unstructured.UnstructuredList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err := informerCache.List(context.Background(), &out, + client.InNamespace(testNamespaceTwo), + client.MatchingLabels(map[string]string{"test-label": "test-pod-2"})) + Expect(err).To(Succeed()) + + By("verifying the returned pods have the correct label") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(1)) + actual := out.Items[0] + Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) + }) + + It("should support filtering by labels from multiple namespaces", func() { + By("creating another pod with the same label but different namespace") + anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) + defer deletePod(anotherPod) + + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := unstructured.UnstructuredList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + labels := map[string]string{"test-label": "test-pod-2"} + err := informerCache.List(context.Background(), &out, client.MatchingLabels(labels)) + Expect(err).To(Succeed()) + + By("verifying multiple pods with the same label in different namespaces are returned") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(2)) + for _, actual := range out.Items { + Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) + } + }) + + It("should be able to list objects by namespace", func() { + By("listing pods in test-namespace-1") + listObj := &unstructured.UnstructuredList{} + listObj.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err := informerCache.List(context.Background(), listObj, client.InNamespace(testNamespaceOne)) + Expect(err).To(Succeed()) + + By("verifying that the returned pods are in test-namespace-1") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(2)) + for _, item := range listObj.Items { + Expect(item.GetNamespace()).To(Equal(testNamespaceOne)) + } + }) + + It("should be able to restrict cache to a namespace", func() { + By("creating a namespaced cache") + namespacedCache, err := cache.New(cfg, cache.Options{Namespaces: []string{testNamespaceOne}}) + Expect(err).NotTo(HaveOccurred()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(namespacedCache.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(namespacedCache.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing pods in all namespaces") + out := &unstructured.UnstructuredList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + Expect(namespacedCache.List(context.Background(), out)).To(Succeed()) + + By("verifying the returned pod is from the watched namespace") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(2)) + for _, item := range out.Items { + Expect(item.GetNamespace()).To(Equal(testNamespaceOne)) + } + By("listing all nodes - should still be able to list a cluster-scoped resource") + nodeList := &unstructured.UnstructuredList{} + nodeList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "NodeList", + }) + Expect(namespacedCache.List(context.Background(), nodeList)).To(Succeed()) + + By("verifying the node list is not empty") + Expect(nodeList.Items).NotTo(BeEmpty()) + + By("getting a node - should still be able to get a cluster-scoped resource") + node := &unstructured.Unstructured{} + node.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Node", + }) + + By("verifying that getting the node works with an empty namespace") + key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} + Expect(namespacedCache.Get(context.Background(), key1, node)).To(Succeed()) + + By("verifying that the namespace is ignored when getting a cluster-scoped resource") + key2 := client.ObjectKey{Namespace: "random", Name: testNodeOne} + Expect(namespacedCache.Get(context.Background(), key2, node)).To(Succeed()) + }) + + if !isPodDisableDeepCopy(opts) { + It("should deep copy the object unless told otherwise", func() { + By("retrieving a specific pod from the cache") + out := &unstructured.Unstructured{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + uKnownPod2 := &unstructured.Unstructured{} + Expect(kscheme.Scheme.Convert(knownPod2, uKnownPod2, nil)).To(Succeed()) + + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) + + By("verifying the retrieved pod is equal to a known pod") + Expect(out).To(Equal(uKnownPod2)) + + By("altering a field in the retrieved pod") + m, _ := out.Object["spec"].(map[string]interface{}) + m["activeDeadlineSeconds"] = 4 + + By("verifying the pods are no longer equal") + Expect(out).NotTo(Equal(knownPod2)) + }) + } else { + It("should not deep copy the object if UnsafeDisableDeepCopy is enabled", func() { + By("getting a specific pod from the cache twice") + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + out1 := &unstructured.Unstructured{} + out1.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}) + Expect(informerCache.Get(context.Background(), podKey, out1)).To(Succeed()) + out2 := &unstructured.Unstructured{} + out2.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}) + Expect(informerCache.Get(context.Background(), podKey, out2)).To(Succeed()) + + By("verifying the pointer fields in pod have the same addresses") + Expect(out1).To(Equal(out2)) + Expect(reflect.ValueOf(out1.Object).Pointer()).To(BeIdenticalTo(reflect.ValueOf(out2.Object).Pointer())) + + By("listing pods from the cache twice") + outList1 := &unstructured.UnstructuredList{} + outList1.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodList"}) + Expect(informerCache.List(context.Background(), outList1, client.InNamespace(testNamespaceOne))).To(Succeed()) + outList2 := &unstructured.UnstructuredList{} + outList2.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodList"}) + Expect(informerCache.List(context.Background(), outList2, client.InNamespace(testNamespaceOne))).To(Succeed()) + + By("verifying the pointer fields in pod have the same addresses") + Expect(len(outList1.Items)).To(Equal(len(outList2.Items))) + sort.SliceStable(outList1.Items, func(i, j int) bool { return outList1.Items[i].GetName() <= outList1.Items[j].GetName() }) + sort.SliceStable(outList2.Items, func(i, j int) bool { return outList2.Items[i].GetName() <= outList2.Items[j].GetName() }) + for i := range outList1.Items { + a := &outList1.Items[i] + b := &outList2.Items[i] + Expect(a).To(Equal(b)) + Expect(reflect.ValueOf(a.Object).Pointer()).To(BeIdenticalTo(reflect.ValueOf(b.Object).Pointer())) + } + }) + } + + It("should return an error if the object is not found", func() { + By("getting a service that does not exists") + svc := &unstructured.Unstructured{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + It("should return an error if getting object in unwatched namespace", func() { + By("getting a service that does not exists") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + }) + It("test multinamespaced cache for cluster scoped resources", func() { + By("creating a multinamespaced cache to watch specific namespaces") + multi := cache.MultiNamespacedCacheBuilder([]string{"default", testNamespaceOne}) + m, err := multi(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("running the cache and waiting it for sync") + go func() { + defer GinkgoRecover() + Expect(m.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(m.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("should be able to fetch cluster scoped resource") + node := &corev1.Node{} + + By("verifying that getting the node works with an empty namespace") + key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} + Expect(m.Get(context.Background(), key1, node)).To(Succeed()) + + By("verifying if the cluster scoped resources are not duplicated") + nodeList := &unstructured.UnstructuredList{} + nodeList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "NodeList", + }) + Expect(m.List(context.Background(), nodeList)).To(Succeed()) + + By("verifying the node list is not empty") + Expect(nodeList.Items).NotTo(BeEmpty()) + Expect(len(nodeList.Items)).To(BeEquivalentTo(1)) + }) + }) + Context("with metadata-only objects", func() { + It("should be able to list objects that haven't been watched previously", func() { + By("listing all services in the cluster") + listObj := &metav1.PartialObjectMetadataList{} + listObj.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "ServiceList", + }) + err := informerCache.List(context.Background(), listObj) + Expect(err).To(Succeed()) + + By("verifying that the returned list contains the Kubernetes service") + // NB: kubernetes default service is automatically created in testenv. + Expect(listObj.Items).NotTo(BeEmpty()) + hasKubeService := false + for i := range listObj.Items { + svc := &listObj.Items[i] + if isKubeService(svc) { + hasKubeService = true + break + } + } + Expect(hasKubeService).To(BeTrue()) + }) + It("should be able to get objects that haven't been watched previously", func() { + By("getting the Kubernetes service") + svc := &metav1.PartialObjectMetadata{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} + Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) + + By("verifying that the returned service looks reasonable") + Expect(svc.GetName()).To(Equal("kubernetes")) + Expect(svc.GetNamespace()).To(Equal("default")) + }) + + It("should support filtering by labels in a single namespace", func() { + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := metav1.PartialObjectMetadataList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err := informerCache.List(context.Background(), &out, + client.InNamespace(testNamespaceTwo), + client.MatchingLabels(map[string]string{"test-label": "test-pod-2"})) + Expect(err).To(Succeed()) + + By("verifying the returned pods have the correct label") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(1)) + actual := out.Items[0] + Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) + }) + + It("should support filtering by labels from multiple namespaces", func() { + By("creating another pod with the same label but different namespace") + anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) + defer deletePod(anotherPod) + + By("listing pods with a particular label") + // NB: each pod has a "test-label": + out := metav1.PartialObjectMetadataList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + labels := map[string]string{"test-label": "test-pod-2"} + err := informerCache.List(context.Background(), &out, client.MatchingLabels(labels)) + Expect(err).To(Succeed()) + + By("verifying multiple pods with the same label in different namespaces are returned") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(2)) + for _, actual := range out.Items { + Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) + } + }) + + It("should be able to list objects by namespace", func() { + By("listing pods in test-namespace-1") + listObj := &metav1.PartialObjectMetadataList{} + listObj.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err := informerCache.List(context.Background(), listObj, client.InNamespace(testNamespaceOne)) + Expect(err).To(Succeed()) + + By("verifying that the returned pods are in test-namespace-1") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(2)) + for _, item := range listObj.Items { + Expect(item.Namespace).To(Equal(testNamespaceOne)) + } + }) + + It("should be able to restrict cache to a namespace", func() { + By("creating a namespaced cache") + namespacedCache, err := cache.New(cfg, cache.Options{Namespaces: []string{testNamespaceOne}}) + Expect(err).NotTo(HaveOccurred()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(namespacedCache.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(namespacedCache.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing pods in all namespaces") + out := &metav1.PartialObjectMetadataList{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + Expect(namespacedCache.List(context.Background(), out)).To(Succeed()) + + By("verifying the returned pod is from the watched namespace") + Expect(out.Items).NotTo(BeEmpty()) + Expect(out.Items).Should(HaveLen(2)) + for _, item := range out.Items { + Expect(item.Namespace).To(Equal(testNamespaceOne)) + } + By("listing all nodes - should still be able to list a cluster-scoped resource") + nodeList := &metav1.PartialObjectMetadataList{} + nodeList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "NodeList", + }) + Expect(namespacedCache.List(context.Background(), nodeList)).To(Succeed()) + + By("verifying the node list is not empty") + Expect(nodeList.Items).NotTo(BeEmpty()) + + By("getting a node - should still be able to get a cluster-scoped resource") + node := &metav1.PartialObjectMetadata{} + node.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Node", + }) + + By("verifying that getting the node works with an empty namespace") + key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} + Expect(namespacedCache.Get(context.Background(), key1, node)).To(Succeed()) + + By("verifying that the namespace is ignored when getting a cluster-scoped resource") + key2 := client.ObjectKey{Namespace: "random", Name: testNodeOne} + Expect(namespacedCache.Get(context.Background(), key2, node)).To(Succeed()) + }) + + if !isPodDisableDeepCopy(opts) { + It("should deep copy the object unless told otherwise", func() { + By("retrieving a specific pod from the cache") + out := &metav1.PartialObjectMetadata{} + out.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + uKnownPod2 := &metav1.PartialObjectMetadata{} + knownPod2.(*corev1.Pod).ObjectMeta.DeepCopyInto(&uKnownPod2.ObjectMeta) + uKnownPod2.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) + + By("verifying the retrieved pod is equal to a known pod") + Expect(out).To(Equal(uKnownPod2)) + + By("altering a field in the retrieved pod") + out.Labels["foo"] = "bar" + + By("verifying the pods are no longer equal") + Expect(out).NotTo(Equal(knownPod2)) + }) + } else { + It("should not deep copy the object if UnsafeDisableDeepCopy is enabled", func() { + By("getting a specific pod from the cache twice") + podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} + out1 := &metav1.PartialObjectMetadata{} + out1.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}) + Expect(informerCache.Get(context.Background(), podKey, out1)).To(Succeed()) + out2 := &metav1.PartialObjectMetadata{} + out2.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}) + Expect(informerCache.Get(context.Background(), podKey, out2)).To(Succeed()) + + By("verifying the pods have the same pointer addresses") + By("verifying the pointer fields in pod have the same addresses") + Expect(out1).To(Equal(out2)) + Expect(reflect.ValueOf(out1.Labels).Pointer()).To(BeIdenticalTo(reflect.ValueOf(out2.Labels).Pointer())) + + By("listing pods from the cache twice") + outList1 := &metav1.PartialObjectMetadataList{} + outList1.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodList"}) + Expect(informerCache.List(context.Background(), outList1, client.InNamespace(testNamespaceOne))).To(Succeed()) + outList2 := &metav1.PartialObjectMetadataList{} + outList2.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodList"}) + Expect(informerCache.List(context.Background(), outList2, client.InNamespace(testNamespaceOne))).To(Succeed()) + + By("verifying the pointer fields in pod have the same addresses") + Expect(len(outList1.Items)).To(Equal(len(outList2.Items))) + sort.SliceStable(outList1.Items, func(i, j int) bool { return outList1.Items[i].Name <= outList1.Items[j].Name }) + sort.SliceStable(outList2.Items, func(i, j int) bool { return outList2.Items[i].Name <= outList2.Items[j].Name }) + for i := range outList1.Items { + a := &outList1.Items[i] + b := &outList2.Items[i] + Expect(a).To(Equal(b)) + Expect(reflect.ValueOf(a.Labels).Pointer()).To(BeIdenticalTo(reflect.ValueOf(b.Labels).Pointer())) + } + }) + } + + It("should return an error if the object is not found", func() { + By("getting a service that does not exists") + svc := &metav1.PartialObjectMetadata{} + svc.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Service", + }) + svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + It("should return an error if getting object in unwatched namespace", func() { + By("getting a service that does not exists") + svc := &corev1.Service{} + svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} + + By("verifying that an error is returned") + err := informerCache.Get(context.Background(), svcKey, svc) + Expect(err).To(HaveOccurred()) + }) + }) + type selectorsTestCase struct { + fieldSelectors map[string]string + labelSelectors map[string]string + expectedPods []string + } + DescribeTable(" and cache with selectors", func(tc selectorsTestCase) { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{ + ByObject: map[client.Object]cache.ByObject{ + &corev1.Pod{}: { + Label: labels.Set(tc.labelSelectors).AsSelector(), + Field: fields.Set(tc.fieldSelectors).AsSelector(), + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("Checking with structured") + obtainedStructuredPodList := corev1.PodList{} + Expect(informer.List(context.Background(), &obtainedStructuredPodList)).To(Succeed()) + Expect(obtainedStructuredPodList.Items).Should(WithTransform(func(pods []corev1.Pod) []string { + obtainedPodNames := []string{} + for _, pod := range pods { + obtainedPodNames = append(obtainedPodNames, pod.Name) + } + return obtainedPodNames + }, ConsistOf(tc.expectedPods))) + + By("Checking with unstructured") + obtainedUnstructuredPodList := unstructured.UnstructuredList{} + obtainedUnstructuredPodList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err = informer.List(context.Background(), &obtainedUnstructuredPodList) + Expect(err).To(Succeed()) + Expect(obtainedUnstructuredPodList.Items).Should(WithTransform(func(pods []unstructured.Unstructured) []string { + obtainedPodNames := []string{} + for _, pod := range pods { + obtainedPodNames = append(obtainedPodNames, pod.GetName()) + } + return obtainedPodNames + }, ConsistOf(tc.expectedPods))) + + By("Checking with metadata") + obtainedMetadataPodList := metav1.PartialObjectMetadataList{} + obtainedMetadataPodList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err = informer.List(context.Background(), &obtainedMetadataPodList) + Expect(err).To(Succeed()) + Expect(obtainedMetadataPodList.Items).Should(WithTransform(func(pods []metav1.PartialObjectMetadata) []string { + obtainedPodNames := []string{} + for _, pod := range pods { + obtainedPodNames = append(obtainedPodNames, pod.Name) + } + return obtainedPodNames + }, ConsistOf(tc.expectedPods))) + }, + Entry("when selectors are empty it has to inform about all the pods", selectorsTestCase{ + fieldSelectors: map[string]string{}, + labelSelectors: map[string]string{}, + expectedPods: []string{"test-pod-1", "test-pod-2", "test-pod-3", "test-pod-4", "test-pod-5", "test-pod-6"}, + }), + Entry("when field matches one pod it has to inform about it", selectorsTestCase{ + fieldSelectors: map[string]string{"metadata.name": "test-pod-2"}, + expectedPods: []string{"test-pod-2"}, + }), + Entry("when field matches multiple pods it has to inform about all of them", selectorsTestCase{ + fieldSelectors: map[string]string{"metadata.namespace": testNamespaceTwo}, + expectedPods: []string{"test-pod-2", "test-pod-3", "test-pod-6"}, + }), + Entry("when label matches one pod it has to inform about it", selectorsTestCase{ + labelSelectors: map[string]string{"test-label": "test-pod-4"}, + expectedPods: []string{"test-pod-4"}, + }), + Entry("when label matches multiple pods it has to inform about all of them", selectorsTestCase{ + labelSelectors: map[string]string{"common-label": "common"}, + expectedPods: []string{"test-pod-3", "test-pod-4"}, + }), + Entry("when label and field matches one pod it has to inform about about it", selectorsTestCase{ + labelSelectors: map[string]string{"common-label": "common"}, + fieldSelectors: map[string]string{"metadata.namespace": testNamespaceTwo}, + expectedPods: []string{"test-pod-3"}, + }), + Entry("when label does not match it does not has to inform", selectorsTestCase{ + labelSelectors: map[string]string{"new-label": "new"}, + expectedPods: []string{}, + }), + Entry("when field does not match it does not has to inform", selectorsTestCase{ + fieldSelectors: map[string]string{"metadata.namespace": "new"}, + expectedPods: []string{}, + }), + ) + }) + Describe("as an Informer", func() { + Context("with structured objects", func() { + It("should be able to get informer for the object", func() { + By("getting a shared index informer for a pod") + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "informer-obj", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + } + sii, err := informerCache.GetInformer(context.TODO(), pod) + Expect(err).NotTo(HaveOccurred()) + Expect(sii).NotTo(BeNil()) + Expect(sii.HasSynced()).To(BeTrue()) + + By("adding an event handler listening for object creation which sends the object to a channel") + out := make(chan interface{}) + addFunc := func(obj interface{}) { + out <- obj + } + _, _ = sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) + + By("adding an object") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl.Create(context.Background(), pod)).To(Succeed()) + defer deletePod(pod) + + By("verifying the object is received on the channel") + Eventually(out).Should(Receive(Equal(pod))) + }) + It("should be able to get an informer by group/version/kind", func() { + By("getting an shared index informer for gvk = core/v1/pod") + gvk := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} + sii, err := informerCache.GetInformerForKind(context.TODO(), gvk) + Expect(err).NotTo(HaveOccurred()) + Expect(sii).NotTo(BeNil()) + Expect(sii.HasSynced()).To(BeTrue()) + + By("adding an event handler listening for object creation which sends the object to a channel") + out := make(chan interface{}) + addFunc := func(obj interface{}) { + out <- obj + } + _, _ = sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) + + By("adding an object") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "informer-gvk", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + } + Expect(cl.Create(context.Background(), pod)).To(Succeed()) + defer deletePod(pod) + + By("verifying the object is received on the channel") + Eventually(out).Should(Receive(Equal(pod))) + }) + It("should be able to index an object field then retrieve objects by that field", func() { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("indexing the restartPolicy field of the Pod object before starting") + pod := &corev1.Pod{} + indexFunc := func(obj client.Object) []string { + return []string{string(obj.(*corev1.Pod).Spec.RestartPolicy)} + } + Expect(informer.IndexField(context.TODO(), pod, "spec.restartPolicy", indexFunc)).To(Succeed()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing Pods with restartPolicyOnFailure") + listObj := &corev1.PodList{} + Expect(informer.List(context.Background(), listObj, + client.MatchingFields{"spec.restartPolicy": "OnFailure"})).To(Succeed()) + By("verifying that the returned pods have correct restart policy") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(1)) + actual := listObj.Items[0] + Expect(actual.Name).To(Equal("test-pod-3")) + }) + + It("should allow for get informer to be cancelled", func() { + By("creating a context and cancelling it") + informerCacheCancel() + + By("getting a shared index informer for a pod with a cancelled context") + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "informer-obj", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + } + sii, err := informerCache.GetInformer(informerCacheCtx, pod) + Expect(err).To(HaveOccurred()) + Expect(sii).To(BeNil()) + Expect(apierrors.IsTimeout(err)).To(BeTrue()) + }) + + It("should allow getting an informer by group/version/kind to be cancelled", func() { + By("creating a context and cancelling it") + informerCacheCancel() + + By("getting an shared index informer for gvk = core/v1/pod with a cancelled context") + gvk := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} + sii, err := informerCache.GetInformerForKind(informerCacheCtx, gvk) + Expect(err).To(HaveOccurred()) + Expect(sii).To(BeNil()) + Expect(apierrors.IsTimeout(err)).To(BeTrue()) + }) + + It("should be able not to change indexer values after indexing cluster-scope objects", func() { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("indexing the Namespace objects with fixed values before starting") + pod := &corev1.Namespace{} + indexerValues := []string{"a", "b", "c"} + fieldName := "fixedValues" + indexFunc := func(obj client.Object) []string { + return indexerValues + } + Expect(informer.IndexField(context.TODO(), pod, fieldName, indexFunc)).To(Succeed()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing Namespaces with fixed indexer") + listObj := &corev1.NamespaceList{} + Expect(informer.List(context.Background(), listObj, + client.MatchingFields{fieldName: "a"})).To(Succeed()) + Expect(listObj.Items).NotTo(BeZero()) + + By("verifying the indexing does not change fixed returned values") + Expect(indexerValues).Should(HaveLen(3)) + Expect(indexerValues[0]).To(Equal("a")) + Expect(indexerValues[1]).To(Equal("b")) + Expect(indexerValues[2]).To(Equal("c")) + }) + }) + Context("with unstructured objects", func() { + It("should be able to get informer for the object", func() { + By("getting a shared index informer for a pod") + + pod := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "containers": []map[string]interface{}{ + { + "name": "nginx", + "image": "nginx", + }, + }, + }, + }, + } + pod.SetName("informer-obj2") + pod.SetNamespace("default") + pod.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + sii, err := informerCache.GetInformer(context.TODO(), pod) + Expect(err).NotTo(HaveOccurred()) + Expect(sii).NotTo(BeNil()) + Expect(sii.HasSynced()).To(BeTrue()) + + By("adding an event handler listening for object creation which sends the object to a channel") + out := make(chan interface{}) + addFunc := func(obj interface{}) { + out <- obj + } + _, _ = sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) + + By("adding an object") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl.Create(context.Background(), pod)).To(Succeed()) + defer deletePod(pod) + + By("verifying the object is received on the channel") + Eventually(out).Should(Receive(Equal(pod))) + }) + + It("should be able to index an object field then retrieve objects by that field", func() { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("indexing the restartPolicy field of the Pod object before starting") + pod := &unstructured.Unstructured{} + pod.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + indexFunc := func(obj client.Object) []string { + s, ok := obj.(*unstructured.Unstructured).Object["spec"] + if !ok { + return []string{} + } + m, ok := s.(map[string]interface{}) + if !ok { + return []string{} + } + return []string{fmt.Sprintf("%v", m["restartPolicy"])} + } + Expect(informer.IndexField(context.TODO(), pod, "spec.restartPolicy", indexFunc)).To(Succeed()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing Pods with restartPolicyOnFailure") + listObj := &unstructured.UnstructuredList{} + listObj.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + }) + err = informer.List(context.Background(), listObj, + client.MatchingFields{"spec.restartPolicy": "OnFailure"}) + Expect(err).To(Succeed()) + + By("verifying that the returned pods have correct restart policy") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(1)) + actual := listObj.Items[0] + Expect(actual.GetName()).To(Equal("test-pod-3")) + }) + + It("should allow for get informer to be cancelled", func() { + By("cancelling the context") + informerCacheCancel() + + By("getting a shared index informer for a pod with a cancelled context") + pod := &unstructured.Unstructured{} + pod.SetName("informer-obj2") + pod.SetNamespace("default") + pod.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + sii, err := informerCache.GetInformer(informerCacheCtx, pod) + Expect(err).To(HaveOccurred()) + Expect(sii).To(BeNil()) + Expect(apierrors.IsTimeout(err)).To(BeTrue()) + }) + }) + Context("with metadata-only objects", func() { + It("should be able to get informer for the object", func() { + By("getting a shared index informer for a pod") + + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "informer-obj", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + } + + podMeta := &metav1.PartialObjectMetadata{} + pod.ObjectMeta.DeepCopyInto(&podMeta.ObjectMeta) + podMeta.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + + sii, err := informerCache.GetInformer(context.TODO(), podMeta) + Expect(err).NotTo(HaveOccurred()) + Expect(sii).NotTo(BeNil()) + Expect(sii.HasSynced()).To(BeTrue()) + + By("adding an event handler listening for object creation which sends the object to a channel") + out := make(chan interface{}) + addFunc := func(obj interface{}) { + out <- obj + } + _, _ = sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) + + By("adding an object") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl.Create(context.Background(), pod)).To(Succeed()) + defer deletePod(pod) + // re-copy the result in so that we can match on it properly + pod.ObjectMeta.DeepCopyInto(&podMeta.ObjectMeta) + + By("verifying the object's metadata is received on the channel") + Eventually(out).Should(Receive(Equal(podMeta))) + }) + + It("should be able to index an object field then retrieve objects by that field", func() { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("indexing the restartPolicy field of the Pod object before starting") + pod := &metav1.PartialObjectMetadata{} + pod.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + indexFunc := func(obj client.Object) []string { + metadata := obj.(*metav1.PartialObjectMetadata) + return []string{metadata.Labels["test-label"]} + } + Expect(informer.IndexField(context.TODO(), pod, "metadata.labels.test-label", indexFunc)).To(Succeed()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing Pods with restartPolicyOnFailure") + listObj := &metav1.PartialObjectMetadataList{} + gvk := schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "PodList", + } + listObj.SetGroupVersionKind(gvk) + err = informer.List(context.Background(), listObj, + client.MatchingFields{"metadata.labels.test-label": "test-pod-3"}) + Expect(err).To(Succeed()) + + By("verifying that the GVK has been preserved for the list object") + Expect(listObj.GroupVersionKind()).To(Equal(gvk)) + + By("verifying that the returned pods have correct restart policy") + Expect(listObj.Items).NotTo(BeEmpty()) + Expect(listObj.Items).Should(HaveLen(1)) + actual := listObj.Items[0] + Expect(actual.GetName()).To(Equal("test-pod-3")) + + By("verifying that the GVK has been preserved for the item in the list") + Expect(actual.GroupVersionKind()).To(Equal(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + })) + }) + + It("should allow for get informer to be cancelled", func() { + By("creating a context and cancelling it") + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + By("getting a shared index informer for a pod with a cancelled context") + pod := &metav1.PartialObjectMetadata{} + pod.SetName("informer-obj2") + pod.SetNamespace("default") + pod.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + sii, err := informerCache.GetInformer(ctx, pod) + Expect(err).To(HaveOccurred()) + Expect(sii).To(BeNil()) + Expect(apierrors.IsTimeout(err)).To(BeTrue()) + }) + }) + }) + Describe("use UnsafeDisableDeepCopy list options", func() { + It("should be able to change object in informer cache", func() { + By("listing pods") + out := corev1.PodList{} + Expect(informerCache.List(context.Background(), &out, client.UnsafeDisableDeepCopy)).To(Succeed()) + for _, item := range out.Items { + if strings.Compare(item.Name, "test-pod-3") == 0 { // test-pod-3 has labels + item.Labels["UnsafeDisableDeepCopy"] = "true" + break + } + } + + By("verifying that the returned pods were changed") + out2 := corev1.PodList{} + Expect(informerCache.List(context.Background(), &out, client.UnsafeDisableDeepCopy)).To(Succeed()) + for _, item := range out2.Items { + if strings.Compare(item.Name, "test-pod-3") == 0 { + Expect(item.Labels["UnsafeDisableDeepCopy"]).To(Equal("true")) + break + } + } + }) + }) + }) +} + +// ensureNamespace installs namespace of a given name if not exists. +func ensureNamespace(namespace string, client client.Client) error { + ns := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Namespace", + APIVersion: "v1", + }, + } + err := client.Create(context.TODO(), &ns) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err +} + +func ensureNode(name string, client client.Client) error { + node := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Node", + APIVersion: "v1", + }, + } + err := client.Create(context.TODO(), &node) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err +} + +//nolint:interfacer +func isKubeService(svc metav1.Object) bool { + // grumble grumble linters grumble grumble + return svc.GetNamespace() == "default" && svc.GetName() == "kubernetes" +} + +func isPodDisableDeepCopy(opts cache.Options) bool { + if opts.ByObject[&corev1.Pod{}].UnsafeDisableDeepCopy != nil { + return *opts.ByObject[&corev1.Pod{}].UnsafeDisableDeepCopy + } + if opts.UnsafeDisableDeepCopy != nil { + return *opts.UnsafeDisableDeepCopy + } + return false +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/doc.go new file mode 100644 index 00000000000..e1742ac0f32 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package cache provides object caches that act as caching client.Reader +// instances and help drive Kubernetes-object-based event handlers. +package cache diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go new file mode 100644 index 00000000000..e070dbeb606 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go @@ -0,0 +1,222 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache + +import ( + "context" + "fmt" + "strings" + + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/cache/internal" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +var ( + _ Informers = &informerCache{} + _ client.Reader = &informerCache{} + _ Cache = &informerCache{} +) + +// ErrCacheNotStarted is returned when trying to read from the cache that wasn't started. +type ErrCacheNotStarted struct{} + +func (*ErrCacheNotStarted) Error() string { + return "the cache is not started, can not read objects" +} + +// informerCache is a Kubernetes Object cache populated from internal.Informers. +// informerCache wraps internal.Informers. +type informerCache struct { + scheme *runtime.Scheme + *internal.Informers +} + +// Get implements Reader. +func (ic *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error { + gvk, err := apiutil.GVKForObject(out, ic.scheme) + if err != nil { + return err + } + + started, cache, err := ic.Informers.Get(ctx, gvk, out) + if err != nil { + return err + } + + if !started { + return &ErrCacheNotStarted{} + } + return cache.Reader.Get(ctx, key, out) +} + +// List implements Reader. +func (ic *informerCache) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error { + gvk, cacheTypeObj, err := ic.objectTypeForListObject(out) + if err != nil { + return err + } + + started, cache, err := ic.Informers.Get(ctx, *gvk, cacheTypeObj) + if err != nil { + return err + } + + if !started { + return &ErrCacheNotStarted{} + } + + return cache.Reader.List(ctx, out, opts...) +} + +// objectTypeForListObject tries to find the runtime.Object and associated GVK +// for a single object corresponding to the passed-in list type. We need them +// because they are used as cache map key. +func (ic *informerCache) objectTypeForListObject(list client.ObjectList) (*schema.GroupVersionKind, runtime.Object, error) { + gvk, err := apiutil.GVKForObject(list, ic.scheme) + if err != nil { + return nil, nil, err + } + + // We need the non-list GVK, so chop off the "List" from the end of the kind. + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + // Handle unstructured.UnstructuredList. + if _, isUnstructured := list.(runtime.Unstructured); isUnstructured { + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(gvk) + return &gvk, u, nil + } + // Handle metav1.PartialObjectMetadataList. + if _, isPartialObjectMetadata := list.(*metav1.PartialObjectMetadataList); isPartialObjectMetadata { + pom := &metav1.PartialObjectMetadata{} + pom.SetGroupVersionKind(gvk) + return &gvk, pom, nil + } + + // Any other list type should have a corresponding non-list type registered + // in the scheme. Use that to create a new instance of the non-list type. + cacheTypeObj, err := ic.scheme.New(gvk) + if err != nil { + return nil, nil, err + } + return &gvk, cacheTypeObj, nil +} + +// GetInformerForKind returns the informer for the GroupVersionKind. +func (ic *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { + // Map the gvk to an object + obj, err := ic.scheme.New(gvk) + if err != nil { + return nil, err + } + + _, i, err := ic.Informers.Get(ctx, gvk, obj, castInformerGetOptions(opts)...) + if err != nil { + return nil, err + } + return i.Informer, err +} + +// GetInformer returns the informer for the obj. +func (ic *informerCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) + if err != nil { + return nil, err + } + + _, i, err := ic.Informers.Get(ctx, gvk, obj, castInformerGetOptions(opts)...) + if err != nil { + return nil, err + } + return i.Informer, err +} + +// NeedLeaderElection implements the LeaderElectionRunnable interface +// to indicate that this can be started without requiring the leader lock. +func (ic *informerCache) NeedLeaderElection() bool { + return false +} + +// IndexField adds an indexer to the underlying cache, using extraction function to get +// value(s) from the given field. This index can then be used by passing a field selector +// to List. For one-to-one compatibility with "normal" field selectors, only return one value. +// The values may be anything. They will automatically be prefixed with the namespace of the +// given object, if present. The objects passed are guaranteed to be objects of the correct type. +func (ic *informerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + informer, err := ic.GetInformer(ctx, obj) + if err != nil { + return err + } + return indexByField(informer, field, extractValue) +} + +// Remove removes an informer specified by the obj argument from the cache and stops it if it existed. +func (ic *informerCache) Remove(obj client.Object) error { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) + if err != nil { + return err + } + + ic.Informers.Remove(gvk, obj) + return nil +} + +func indexByField(indexer Informer, field string, extractor client.IndexerFunc) error { + indexFunc := func(objRaw interface{}) ([]string, error) { + // TODO(directxman12): check if this is the correct type? + obj, isObj := objRaw.(client.Object) + if !isObj { + return nil, fmt.Errorf("object of type %T is not an Object", objRaw) + } + meta, err := apimeta.Accessor(obj) + if err != nil { + return nil, err + } + ns := meta.GetNamespace() + + rawVals := extractor(obj) + var vals []string + if ns == "" { + // if we're not doubling the keys for the namespaced case, just create a new slice with same length + vals = make([]string, len(rawVals)) + } else { + // if we need to add non-namespaced versions too, double the length + vals = make([]string, len(rawVals)*2) + } + for i, rawVal := range rawVals { + // save a namespaced variant, so that we can ask + // "what are all the object matching a given index *in a given namespace*" + vals[i] = internal.KeyToNamespacedKey(ns, rawVal) + if ns != "" { + // if we have a namespace, also inject a special index key for listing + // regardless of the object namespace + vals[i+len(rawVals)] = internal.KeyToNamespacedKey("", rawVal) + } + } + + return vals, nil + } + + return indexer.AddIndexers(cache.Indexers{internal.FieldIndexName(field): indexFunc}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_test.go new file mode 100644 index 00000000000..617e74c4e50 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_test.go @@ -0,0 +1,46 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +var _ = Describe("informerCache", func() { + It("should not require LeaderElection", func() { + cfg := &rest.Config{} + + httpClient, err := rest.HTTPClientFor(cfg) + Expect(err).ToNot(HaveOccurred()) + mapper, err := apiutil.NewDynamicRESTMapper(cfg, httpClient) + Expect(err).ToNot(HaveOccurred()) + + c, err := cache.New(cfg, cache.Options{Mapper: mapper}) + Expect(err).ToNot(HaveOccurred()) + + leaderElectionRunnable, ok := c.(manager.LeaderElectionRunnable) + Expect(ok).To(BeTrue()) + Expect(leaderElectionRunnable.NeedLeaderElection()).To(BeFalse()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_unit_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_unit_test.go similarity index 75% rename from third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_unit_test.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_unit_test.go index d0f7470d648..130059bc409 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_unit_test.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache_unit_test.go @@ -14,22 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache +package cache import ( - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes/scheme" - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal" + "sigs.k8s.io/controller-runtime/pkg/cache/internal" "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" crscheme "sigs.k8s.io/controller-runtime/pkg/scheme" ) @@ -40,8 +38,9 @@ const ( ) var _ = Describe("ip.objectTypeForListObject", func() { - ip := &dynamicInformerCache{ - InformersMap: &internal.InformersMap{Scheme: scheme.Scheme}, + ip := &informerCache{ + scheme: scheme.Scheme, + Informers: &internal.Informers{}, } It("should find the object type for unstructured lists", func() { @@ -57,7 +56,21 @@ var _ = Describe("ip.objectTypeForListObject", func() { referenceUnstructured := &unstructured.Unstructured{} referenceUnstructured.SetGroupVersionKind(*gvk) Expect(obj).To(Equal(referenceUnstructured)) + }) + It("should find the object type for partial object metadata lists", func() { + partialList := &metav1.PartialObjectMetadataList{} + partialList.APIVersion = ("v1") + partialList.Kind = "PodList" + + gvk, obj, err := ip.objectTypeForListObject(partialList) + Expect(err).ToNot(HaveOccurred()) + Expect(gvk.Group).To(Equal("")) + Expect(gvk.Version).To(Equal("v1")) + Expect(gvk.Kind).To(Equal("Pod")) + referencePartial := &metav1.PartialObjectMetadata{} + referencePartial.SetGroupVersionKind(*gvk) + Expect(obj).To(Equal(referencePartial)) }) It("should find the object type of a list with a slice of literals items field", func() { @@ -66,21 +79,20 @@ var _ = Describe("ip.objectTypeForListObject", func() { Expect(gvk.Group).To(Equal("")) Expect(gvk.Version).To(Equal("v1")) Expect(gvk.Kind).To(Equal("Pod")) - var referencePod *corev1.Pod + referencePod := &corev1.Pod{} Expect(obj).To(Equal(referencePod)) - }) It("should find the object type of a list with a slice of pointers items field", func() { By("registering the type", func() { - ip.Scheme = runtime.NewScheme() + ip.scheme = runtime.NewScheme() err := (&crscheme.Builder{ GroupVersion: schema.GroupVersion{Group: itemPointerSliceTypeGroupName, Version: itemPointerSliceTypeVersion}, }). Register( &controllertest.UnconventionalListType{}, &controllertest.UnconventionalListTypeList{}, - ).AddToScheme(ip.Scheme) + ).AddToScheme(ip.scheme) Expect(err).To(BeNil()) }) @@ -90,7 +102,7 @@ var _ = Describe("ip.objectTypeForListObject", func() { Expect(gvk.Group).To(Equal(itemPointerSliceTypeGroupName)) Expect(gvk.Version).To(Equal(itemPointerSliceTypeVersion)) Expect(gvk.Kind).To(Equal("UnconventionalListType")) - var referenceObject *controllertest.UnconventionalListType + referenceObject := &controllertest.UnconventionalListType{} Expect(obj).To(Equal(referenceObject)) }) }) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informertest/fake_cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informertest/fake_cache.go similarity index 95% rename from third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informertest/fake_cache.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/cache/informertest/fake_cache.go index 6124a08d032..da3bf8e0d42 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informertest/fake_cache.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/informertest/fake_cache.go @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - package informertest import ( @@ -134,7 +131,7 @@ func (c *FakeInformers) IndexField(ctx context.Context, obj client.Object, field } // Get implements Cache. -func (c *FakeInformers) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error { +func (c *FakeInformers) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { return nil } diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/cache_reader.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go similarity index 81% rename from third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/cache_reader.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go index 6bb23bd493e..3c8355bbde5 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/cache_reader.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - package internal import ( @@ -26,14 +23,13 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/selection" "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" ) // CacheReader is a client.Reader. @@ -49,10 +45,15 @@ type CacheReader struct { // scopeName is the scope of the resource (namespaced or cluster-scoped). scopeName apimeta.RESTScopeName + + // disableDeepCopy indicates not to deep copy objects during get or list objects. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + disableDeepCopy bool } // Get checks the indexer for the object and writes a copy of it if found. -func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object) error { +func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error { if c.scopeName == apimeta.RESTScopeNameRoot { key.Namespace = "" } @@ -79,9 +80,13 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob return fmt.Errorf("cache contained %T, which is not an Object", obj) } - // deep copy to avoid mutating cache - // TODO(directxman12): revisit the decision to always deepcopy - obj = obj.(runtime.Object).DeepCopyObject() + if c.disableDeepCopy { + // skip deep copy which might be unsafe + // you must DeepCopy any object before mutating it outside + } else { + // deep copy to avoid mutating cache + obj = obj.(runtime.Object).DeepCopyObject() + } // Copy the value of the item in the cache to the returned value // TODO(directxman12): this is a terrible hack, pls fix (we should have deepcopyinto) @@ -91,7 +96,9 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob return fmt.Errorf("cache had type %s, but %s was asked for", objVal.Type(), outVal.Type()) } reflect.Indirect(outVal).Set(reflect.Indirect(objVal)) - out.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + if !c.disableDeepCopy { + out.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + } return nil } @@ -108,7 +115,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli case listOpts.FieldSelector != nil: // TODO(directxman12): support more complicated field selectors by // combining multiple indices, GetIndexers, etc - field, val, requiresExact := requiresExactMatch(listOpts.FieldSelector) + field, val, requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector) if !requiresExact { return fmt.Errorf("non-exact field matches are not supported by the cache") } @@ -132,15 +139,15 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli limitSet := listOpts.Limit > 0 runtimeObjs := make([]runtime.Object, 0, len(objs)) - for i, item := range objs { + for _, item := range objs { // if the Limit option is set and the number of items // listed exceeds this limit, then stop reading. - if limitSet && int64(i) >= listOpts.Limit { + if limitSet && int64(len(runtimeObjs)) >= listOpts.Limit { break } obj, isObj := item.(runtime.Object) if !isObj { - return fmt.Errorf("cache contained %T, which is not an Object", obj) + return fmt.Errorf("cache contained %T, which is not an Object", item) } meta, err := apimeta.Accessor(obj) if err != nil { @@ -153,8 +160,15 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli } } - outObj := obj.DeepCopyObject() - outObj.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + var outObj runtime.Object + if c.disableDeepCopy || (listOpts.UnsafeDisableDeepCopy != nil && *listOpts.UnsafeDisableDeepCopy) { + // skip deep copy which might be unsafe + // you must DeepCopy any object before mutating it outside + outObj = obj + } else { + outObj = obj.DeepCopyObject() + outObj.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + } runtimeObjs = append(runtimeObjs, outObj) } return apimeta.SetList(out, runtimeObjs) @@ -171,19 +185,6 @@ func objectKeyToStoreKey(k client.ObjectKey) string { return k.Namespace + "/" + k.Name } -// requiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`. -func requiresExactMatch(sel fields.Selector) (field, val string, required bool) { - reqs := sel.Requirements() - if len(reqs) != 1 { - return "", "", false - } - req := reqs[0] - if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals { - return "", "", false - } - return req.Field, req.Value, true -} - // FieldIndexName constructs the name of the index over the given field, // for use with an indexer. func FieldIndexName(field string) string { diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go new file mode 100644 index 00000000000..bb3a454f1c4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go @@ -0,0 +1,615 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" + "fmt" + "math/rand" + "net/http" + "sync" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/metadata" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/internal/syncs" +) + +// InformersOpts configures an InformerMap. +type InformersOpts struct { + HTTPClient *http.Client + Scheme *runtime.Scheme + Mapper meta.RESTMapper + ResyncPeriod time.Duration + Namespace string + ByGVK map[schema.GroupVersionKind]InformersOptsByGVK +} + +// InformersOptsByGVK configured additional by group version kind (or object) +// in an InformerMap. +type InformersOptsByGVK struct { + Selector Selector + Transform cache.TransformFunc + UnsafeDisableDeepCopy *bool +} + +// NewInformers creates a new InformersMap that can create informers under the hood. +func NewInformers(config *rest.Config, options *InformersOpts) *Informers { + return &Informers{ + config: config, + httpClient: options.HTTPClient, + scheme: options.Scheme, + mapper: options.Mapper, + tracker: tracker{ + Structured: make(map[schema.GroupVersionKind]*Cache), + Unstructured: make(map[schema.GroupVersionKind]*Cache), + Metadata: make(map[schema.GroupVersionKind]*Cache), + }, + codecs: serializer.NewCodecFactory(options.Scheme), + paramCodec: runtime.NewParameterCodec(options.Scheme), + resync: options.ResyncPeriod, + startWait: make(chan struct{}), + namespace: options.Namespace, + byGVK: options.ByGVK, + } +} + +// Cache contains the cached data for an Cache. +type Cache struct { + // Informer is the cached informer + Informer cache.SharedIndexInformer + + // CacheReader wraps Informer and implements the CacheReader interface for a single type + Reader CacheReader + + // Stop can be used to stop this individual informer. + stop chan struct{} +} + +// Start starts the informer managed by a MapEntry. +// Blocks until the informer stops. The informer can be stopped +// either individually (via the entry's stop channel) or globally +// via the provided stop argument. +func (c *Cache) Start(stop <-chan struct{}) { + // Stop on either the whole map stopping or just this informer being removed. + internalStop, cancel := syncs.MergeChans(stop, c.stop) + defer cancel() + c.Informer.Run(internalStop) +} + +type tracker struct { + Structured map[schema.GroupVersionKind]*Cache + Unstructured map[schema.GroupVersionKind]*Cache + Metadata map[schema.GroupVersionKind]*Cache +} + +// GetOptions provides configuration to customize the behavior when +// getting an informer. +type GetOptions struct { + // DoNotBlockUntilSynced tells Get() to return the informer immediately, + // without waiting for its cache to sync. + DoNotBlockUntilSynced bool +} + +// InformerGetOption defines an option that alters the behavior of how informers are retrieved. +type InformerGetOption func(*GetOptions) + +// BlockUntilSynced determines whether a get request for an informer should block +// until the informer's cache has synced. +func BlockUntilSynced(shouldBlock bool) InformerGetOption { + return func(opts *GetOptions) { + opts.DoNotBlockUntilSynced = !shouldBlock + } +} + +// Informers create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. +// It uses a standard parameter codec constructed based on the given generated Scheme. +type Informers struct { + // httpClient is used to create a new REST client + httpClient *http.Client + + // scheme maps runtime.Objects to GroupVersionKinds + scheme *runtime.Scheme + + // config is used to talk to the apiserver + config *rest.Config + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper + + // tracker tracks informers keyed by their type and groupVersionKind + tracker tracker + + // codecs is used to create a new REST client + codecs serializer.CodecFactory + + // paramCodec is used by list and watch + paramCodec runtime.ParameterCodec + + // resync is the base frequency the informers are resynced + // a 10 percent jitter will be added to the resync period between informers + // so that all informers will not send list requests simultaneously. + resync time.Duration + + // mu guards access to the map + mu sync.RWMutex + + // started is true if the informers have been started + started bool + + // startWait is a channel that is closed after the + // informer has been started. + startWait chan struct{} + + // waitGroup is the wait group that is used to wait for all informers to stop + waitGroup sync.WaitGroup + + // stopped is true if the informers have been stopped + stopped bool + + // ctx is the context to stop informers + ctx context.Context + + // namespace is the namespace that all ListWatches are restricted to + // default or empty string means all namespaces + namespace string + + byGVK map[schema.GroupVersionKind]InformersOptsByGVK +} + +func (ip *Informers) getSelector(gvk schema.GroupVersionKind) Selector { + if ip.byGVK == nil { + return Selector{} + } + if res, ok := ip.byGVK[gvk]; ok { + return res.Selector + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok { + return res.Selector + } + return Selector{} +} + +func (ip *Informers) getTransform(gvk schema.GroupVersionKind) cache.TransformFunc { + if ip.byGVK == nil { + return nil + } + if res, ok := ip.byGVK[gvk]; ok { + return res.Transform + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok { + return res.Transform + } + return nil +} + +func (ip *Informers) getDisableDeepCopy(gvk schema.GroupVersionKind) bool { + if ip.byGVK == nil { + return false + } + if res, ok := ip.byGVK[gvk]; ok && res.UnsafeDisableDeepCopy != nil { + return *res.UnsafeDisableDeepCopy + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok && res.UnsafeDisableDeepCopy != nil { + return *res.UnsafeDisableDeepCopy + } + return false +} + +// Start calls Run on each of the informers and sets started to true. Blocks on the context. +// It doesn't return start because it can't return an error, and it's not a runnable directly. +func (ip *Informers) Start(ctx context.Context) error { + func() { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Set the context so it can be passed to informers that are added later + ip.ctx = ctx + + // Start each informer + for _, i := range ip.tracker.Structured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Unstructured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Metadata { + ip.startInformerLocked(i) + } + + // Set started to true so we immediately start any informers added later. + ip.started = true + close(ip.startWait) + }() + <-ctx.Done() // Block until the context is done + ip.mu.Lock() + ip.stopped = true // Set stopped to true so we don't start any new informers + ip.mu.Unlock() + ip.waitGroup.Wait() // Block until all informers have stopped + return nil +} + +func (ip *Informers) startInformerLocked(cacheEntry *Cache) { + // Don't start the informer in case we are already waiting for the items in + // the waitGroup to finish, since waitGroups don't support waiting and adding + // at the same time. + if ip.stopped { + return + } + + ip.waitGroup.Add(1) + go func() { + defer ip.waitGroup.Done() + cacheEntry.Start(ip.ctx.Done()) + }() +} + +func (ip *Informers) waitForStarted(ctx context.Context) bool { + select { + case <-ip.startWait: + return true + case <-ctx.Done(): + return false + } +} + +// getHasSyncedFuncs returns all the HasSynced functions for the informers in this map. +func (ip *Informers) getHasSyncedFuncs() []cache.InformerSynced { + ip.mu.RLock() + defer ip.mu.RUnlock() + + res := make([]cache.InformerSynced, 0, + len(ip.tracker.Structured)+len(ip.tracker.Unstructured)+len(ip.tracker.Metadata), + ) + for _, i := range ip.tracker.Structured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Unstructured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Metadata { + res = append(res, i.Informer.HasSynced) + } + return res +} + +// WaitForCacheSync waits until all the caches have been started and synced. +func (ip *Informers) WaitForCacheSync(ctx context.Context) bool { + if !ip.waitForStarted(ctx) { + return false + } + return cache.WaitForCacheSync(ctx.Done(), ip.getHasSyncedFuncs()...) +} + +func (ip *Informers) get(gvk schema.GroupVersionKind, obj runtime.Object) (res *Cache, started bool, ok bool) { + ip.mu.RLock() + defer ip.mu.RUnlock() + i, ok := ip.informersByType(obj)[gvk] + return i, ip.started, ok +} + +// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns +// the Informer from the map. +func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object, opts ...InformerGetOption) (bool, *Cache, error) { + // Return the informer if it is found + i, started, ok := ip.get(gvk, obj) + if !ok { + var err error + if i, started, err = ip.addInformerToMap(gvk, obj); err != nil { + return started, nil, err + } + } + + cfg := &GetOptions{} + for _, opt := range opts { + opt(cfg) + } + + if started && !i.Informer.HasSynced() && !cfg.DoNotBlockUntilSynced { + // Wait for it to sync before returning the Informer so that folks don't read from a stale cache. + if !cache.WaitForCacheSync(ctx.Done(), i.Informer.HasSynced) { + return started, nil, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0) + } + } + + return started, i, nil +} + +// Remove removes an informer entry and stops it if it was running. +func (ip *Informers) Remove(gvk schema.GroupVersionKind, obj runtime.Object) { + ip.mu.Lock() + defer ip.mu.Unlock() + + informerMap := ip.informersByType(obj) + + entry, ok := informerMap[gvk] + if !ok { + return + } + close(entry.stop) + delete(informerMap, gvk) +} + +func (ip *Informers) informersByType(obj runtime.Object) map[schema.GroupVersionKind]*Cache { + switch obj.(type) { + case runtime.Unstructured: + return ip.tracker.Unstructured + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + return ip.tracker.Metadata + default: + return ip.tracker.Structured + } +} + +func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*Cache, bool, error) { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Check the cache to see if we already have an Informer. If we do, return the Informer. + // This is for the case where 2 routines tried to get the informer when it wasn't in the map + // so neither returned early, but the first one created it. + if i, ok := ip.informersByType(obj)[gvk]; ok { + return i, ip.started, nil + } + + // Create a NewSharedIndexInformer and add it to the map. + listWatcher, err := ip.makeListWatcher(gvk, obj) + if err != nil { + return nil, false, err + } + sharedIndexInformer := cache.NewSharedIndexInformer(&cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + ip.getSelector(gvk).ApplyToList(&opts) + return listWatcher.ListFunc(opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + ip.getSelector(gvk).ApplyToList(&opts) + opts.Watch = true // Watch needs to be set to true separately + return listWatcher.WatchFunc(opts) + }, + }, obj, calculateResyncPeriod(ip.resync), cache.Indexers{ + cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, + }) + + // Check to see if there is a transformer for this gvk + if err := sharedIndexInformer.SetTransform(ip.getTransform(gvk)); err != nil { + return nil, false, err + } + + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, false, err + } + + // Create the new entry and set it in the map. + i := &Cache{ + Informer: sharedIndexInformer, + Reader: CacheReader{ + indexer: sharedIndexInformer.GetIndexer(), + groupVersionKind: gvk, + scopeName: mapping.Scope.Name(), + disableDeepCopy: ip.getDisableDeepCopy(gvk), + }, + stop: make(chan struct{}), + } + ip.informersByType(obj)[gvk] = i + + // Start the informer in case the InformersMap has started, otherwise it will be + // started when the InformersMap starts. + if ip.started { + ip.startInformerLocked(i) + } + return i, ip.started, nil +} + +func (ip *Informers) makeListWatcher(gvk schema.GroupVersionKind, obj runtime.Object) (*cache.ListWatch, error) { + // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the + // groupVersionKind to the Resource API we will use. + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + + // Figure out if the GVK we're dealing with is global, or namespace scoped. + var namespace string + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + namespace = restrictNamespaceBySelector(ip.namespace, ip.getSelector(gvk)) + } + + switch obj.(type) { + // + // Unstructured + // + case runtime.Unstructured: + // If the rest configuration has a negotiated serializer passed in, + // we should remove it and use the one that the dynamic client sets for us. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + dynamicClient, err := dynamic.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := dynamicClient.Resource(mapping.Resource) + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + if namespace != "" { + return resources.Namespace(namespace).List(ip.ctx, opts) + } + return resources.List(ip.ctx, opts) + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + if namespace != "" { + return resources.Namespace(namespace).Watch(ip.ctx, opts) + } + return resources.Watch(ip.ctx, opts) + }, + }, nil + // + // Metadata + // + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + // Always clear the negotiated serializer and use the one + // set from the metadata client. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + + // Grab the metadata metadataClient. + metadataClient, err := metadata.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := metadataClient.Resource(mapping.Resource) + + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + var ( + list *metav1.PartialObjectMetadataList + err error + ) + if namespace != "" { + list, err = resources.Namespace(namespace).List(ip.ctx, opts) + } else { + list, err = resources.List(ip.ctx, opts) + } + if list != nil { + for i := range list.Items { + list.Items[i].SetGroupVersionKind(gvk) + } + } + return list, err + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watcher watch.Interface, err error) { + if namespace != "" { + watcher, err = resources.Namespace(namespace).Watch(ip.ctx, opts) + } else { + watcher, err = resources.Watch(ip.ctx, opts) + } + if err != nil { + return nil, err + } + return newGVKFixupWatcher(gvk, watcher), nil + }, + }, nil + // + // Structured. + // + default: + client, err := apiutil.RESTClientForGVK(gvk, false, ip.config, ip.codecs, ip.httpClient) + if err != nil { + return nil, err + } + listGVK := gvk.GroupVersion().WithKind(gvk.Kind + "List") + listObj, err := ip.scheme.New(listGVK) + if err != nil { + return nil, err + } + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + + // Create the resulting object, and execute the request. + res := listObj.DeepCopyObject() + if err := req.Do(ip.ctx).Into(res); err != nil { + return nil, err + } + return res, nil + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + // Call the watch. + return req.Watch(ip.ctx) + }, + }, nil + } +} + +// newGVKFixupWatcher adds a wrapper that preserves the GVK information when +// events come in. +// +// This works around a bug where GVK information is not passed into mapping +// functions when using the OnlyMetadata option in the builder. +// This issue is most likely caused by kubernetes/kubernetes#80609. +// See kubernetes-sigs/controller-runtime#1484. +// +// This was originally implemented as a cache.ResourceEventHandler wrapper but +// that contained a data race which was resolved by setting the GVK in a watch +// wrapper, before the objects are written to the cache. +// See kubernetes-sigs/controller-runtime#1650. +// +// The original watch wrapper was found to be incompatible with +// k8s.io/client-go/tools/cache.Reflector so it has been re-implemented as a +// watch.Filter which is compatible. +// See kubernetes-sigs/controller-runtime#1789. +func newGVKFixupWatcher(gvk schema.GroupVersionKind, watcher watch.Interface) watch.Interface { + return watch.Filter( + watcher, + func(in watch.Event) (watch.Event, bool) { + in.Object.GetObjectKind().SetGroupVersionKind(gvk) + return in, true + }, + ) +} + +// calculateResyncPeriod returns a duration based on the desired input +// this is so that multiple controllers don't get into lock-step and all +// hammer the apiserver with list requests simultaneously. +func calculateResyncPeriod(resync time.Duration) time.Duration { + // the factor will fall into [0.9, 1.1) + factor := rand.Float64()/5.0 + 0.9 //nolint:gosec + return time.Duration(float64(resync.Nanoseconds()) * factor) +} + +// restrictNamespaceBySelector returns either a global restriction for all ListWatches +// if not default/empty, or the namespace that a ListWatch for the specific resource +// is restricted to, based on a specified field selector for metadata.namespace field. +func restrictNamespaceBySelector(namespaceOpt string, s Selector) string { + if namespaceOpt != "" { + // namespace is already restricted + return namespaceOpt + } + fieldSelector := s.Field + if fieldSelector == nil || fieldSelector.Empty() { + return "" + } + // check whether a selector includes the namespace field + value, found := fieldSelector.RequiresExactMatch("metadata.namespace") + if found { + return value + } + return "" +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_test.go new file mode 100644 index 00000000000..854a39c1f1c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_test.go @@ -0,0 +1,94 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" +) + +// Test that gvkFixupWatcher behaves like watch.FakeWatcher +// and that it overrides the GVK. +// These tests are adapted from the watch.FakeWatcher tests in: +// https://github.com/kubernetes/kubernetes/blob/adbda068c1808fcc8a64a94269e0766b5c46ec41/staging/src/k8s.io/apimachinery/pkg/watch/watch_test.go#L33-L78 +var _ = Describe("gvkFixupWatcher", func() { + It("behaves like watch.FakeWatcher", func() { + newTestType := func(name string) runtime.Object { + return &metav1.PartialObjectMetadata{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } + } + + f := watch.NewFake() + // This is the GVK which we expect the wrapper to set on all the events + expectedGVK := schema.GroupVersionKind{ + Group: "testgroup", + Version: "v1test2", + Kind: "TestKind", + } + gvkfw := newGVKFixupWatcher(expectedGVK, f) + + table := []struct { + t watch.EventType + s runtime.Object + }{ + {watch.Added, newTestType("foo")}, + {watch.Modified, newTestType("qux")}, + {watch.Modified, newTestType("bar")}, + {watch.Deleted, newTestType("bar")}, + {watch.Error, newTestType("error: blah")}, + } + + consumer := func(w watch.Interface) { + for _, expect := range table { + By(fmt.Sprintf("Fixing up watch.EventType: %v and passing it on", expect.t)) + got, ok := <-w.ResultChan() + Expect(ok).To(BeTrue(), "closed early") + Expect(expect.t).To(Equal(got.Type), "unexpected Event.Type or out-of-order Event") + Expect(got.Object).To(BeAssignableToTypeOf(&metav1.PartialObjectMetadata{}), "unexpected Event.Object type") + a := got.Object.(*metav1.PartialObjectMetadata) + Expect(got.Object.GetObjectKind().GroupVersionKind()).To(Equal(expectedGVK), "GVK was not fixed up") + expected := expect.s.DeepCopyObject() + expected.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) + actual := a.DeepCopyObject() + actual.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) + Expect(actual).To(Equal(expected), "unexpected change to the Object") + } + Eventually(w.ResultChan()).Should(BeClosed()) + } + + sender := func() { + f.Add(newTestType("foo")) + f.Action(watch.Modified, newTestType("qux")) + f.Modify(newTestType("bar")) + f.Delete(newTestType("bar")) + f.Error(newTestType("error: blah")) + f.Stop() + } + + go sender() + consumer(gvkfw) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/internal_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/internal_suite_test.go new file mode 100644 index 00000000000..25ec0f1dbce --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/internal_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Cache Internal Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/selector.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go similarity index 86% rename from third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/selector.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go index cd9c5800080..c674379b992 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/selector.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go @@ -20,12 +20,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime/schema" ) -// SelectorsByGVK associate a GroupVersionKind to a field/label selector. -type SelectorsByGVK map[schema.GroupVersionKind]Selector - // Selector specify the label/field selector to fill in ListOptions. type Selector struct { Label labels.Selector diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go new file mode 100644 index 00000000000..0725f550c5e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go @@ -0,0 +1,55 @@ +package internal + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// TransformFuncByGVK provides access to the correct transform function for +// any given GVK. +type TransformFuncByGVK interface { + Set(runtime.Object, *runtime.Scheme, cache.TransformFunc) error + Get(schema.GroupVersionKind) cache.TransformFunc + SetDefault(transformer cache.TransformFunc) +} + +type transformFuncByGVK struct { + defaultTransform cache.TransformFunc + transformers map[schema.GroupVersionKind]cache.TransformFunc +} + +// TransformFuncByGVKFromMap creates a TransformFuncByGVK from a map that +// maps GVKs to TransformFuncs. +func TransformFuncByGVKFromMap(in map[schema.GroupVersionKind]cache.TransformFunc) TransformFuncByGVK { + byGVK := &transformFuncByGVK{} + if defaultFunc, hasDefault := in[schema.GroupVersionKind{}]; hasDefault { + byGVK.defaultTransform = defaultFunc + } + delete(in, schema.GroupVersionKind{}) + byGVK.transformers = in + return byGVK +} + +func (t *transformFuncByGVK) SetDefault(transformer cache.TransformFunc) { + t.defaultTransform = transformer +} + +func (t *transformFuncByGVK) Set(obj runtime.Object, scheme *runtime.Scheme, transformer cache.TransformFunc) error { + gvk, err := apiutil.GVKForObject(obj, scheme) + if err != nil { + return err + } + + t.transformers[gvk] = transformer + return nil +} + +func (t transformFuncByGVK) Get(gvk schema.GroupVersionKind) cache.TransformFunc { + if val, ok := t.transformers[gvk]; ok { + return val + } + return t.defaultTransform +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go new file mode 100644 index 00000000000..ff617beab0c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go @@ -0,0 +1,391 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache + +import ( + "context" + "fmt" + "time" + + corev1 "k8s.io/api/core/v1" + apimeta "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + toolscache "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// a new global namespaced cache to handle cluster scoped resources. +const globalCache = "_cluster-scope" + +// MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache. +// This will scope the cache to a list of namespaces. Listing for all namespaces +// will list for all the namespaces that this knows about. By default this will create +// a global cache for cluster scoped resource. Note that this is not intended +// to be used for excluding namespaces, this is better done via a Predicate. Also note that +// you may face performance issues when using this with a high number of namespaces. +// +// Deprecated: Use cache.Options.Namespaces instead. +func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { + return func(config *rest.Config, opts Options) (Cache, error) { + opts.Namespaces = namespaces + return newMultiNamespaceCache(config, opts) + } +} + +func newMultiNamespaceCache(config *rest.Config, opts Options) (Cache, error) { + if len(opts.Namespaces) < 2 { + return nil, fmt.Errorf("must specify more than one namespace to use multi-namespace cache") + } + opts, err := defaultOpts(config, opts) + if err != nil { + return nil, err + } + + // Create every namespace cache. + caches := map[string]Cache{} + for _, ns := range opts.Namespaces { + opts.Namespaces = []string{ns} + c, err := New(config, opts) + if err != nil { + return nil, err + } + caches[ns] = c + } + + // Create a cache for cluster scoped resources. + opts.Namespaces = []string{} + gCache, err := New(config, opts) + if err != nil { + return nil, fmt.Errorf("error creating global cache: %w", err) + } + + return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil +} + +// multiNamespaceCache knows how to handle multiple namespaced caches +// Use this feature when scoping permissions for your +// operator to a list of namespaces instead of watching every namespace +// in the cluster. +type multiNamespaceCache struct { + namespaceToCache map[string]Cache + Scheme *runtime.Scheme + RESTMapper apimeta.RESTMapper + clusterCache Cache +} + +var _ Cache = &multiNamespaceCache{} + +// Methods for multiNamespaceCache to conform to the Informers interface. +func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + informers := map[string]Informer{} + + // If the object is clusterscoped, get the informer from clusterCache, + // if not use the namespaced caches. + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return nil, err + } + if !isNamespaced { + clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj, opts...) + if err != nil { + return nil, err + } + informers[globalCache] = clusterCacheInf + + return &multiNamespaceInformer{namespaceToInformer: informers}, nil + } + + for ns, cache := range c.namespaceToCache { + informer, err := cache.GetInformer(ctx, obj) + if err != nil { + return nil, err + } + informers[ns] = informer + } + + return &multiNamespaceInformer{namespaceToInformer: informers}, nil +} + +func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { + informers := map[string]Informer{} + + // If the object is clusterscoped, get the informer from clusterCache, + // if not use the namespaced caches. + isNamespaced, err := apiutil.IsGVKNamespaced(gvk, c.RESTMapper) + if err != nil { + return nil, err + } + if !isNamespaced { + clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk, opts...) + if err != nil { + return nil, err + } + informers[globalCache] = clusterCacheInf + + return &multiNamespaceInformer{namespaceToInformer: informers}, nil + } + + for ns, cache := range c.namespaceToCache { + informer, err := cache.GetInformerForKind(ctx, gvk, opts...) + if err != nil { + return nil, err + } + informers[ns] = informer + } + + return &multiNamespaceInformer{namespaceToInformer: informers}, nil +} + +func (c *multiNamespaceCache) Start(ctx context.Context) error { + // start global cache + go func() { + err := c.clusterCache.Start(ctx) + if err != nil { + log.Error(err, "cluster scoped cache failed to start") + } + }() + + // start namespaced caches + for ns, cache := range c.namespaceToCache { + go func(ns string, cache Cache) { + err := cache.Start(ctx) + if err != nil { + log.Error(err, "multinamespace cache failed to start namespaced informer", "namespace", ns) + } + }(ns, cache) + } + + <-ctx.Done() + return nil +} + +func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool { + synced := true + for _, cache := range c.namespaceToCache { + if s := cache.WaitForCacheSync(ctx); !s { + synced = s + } + } + + // check if cluster scoped cache has synced + if !c.clusterCache.WaitForCacheSync(ctx) { + synced = false + } + return synced +} + +func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + return c.clusterCache.IndexField(ctx, obj, field, extractValue) + } + + for _, cache := range c.namespaceToCache { + if err := cache.IndexField(ctx, obj, field, extractValue); err != nil { + return err + } + } + return nil +} + +func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + // Look into the global cache to fetch the object + return c.clusterCache.Get(ctx, key, obj) + } + + cache, ok := c.namespaceToCache[key.Namespace] + if !ok { + return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", key) + } + return cache.Get(ctx, key, obj) +} + +// List multi namespace cache will get all the objects in the namespaces that the cache is watching if asked for all namespaces. +func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + isNamespaced, err := apiutil.IsObjectNamespaced(list, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + // Look at the global cache to get the objects with the specified GVK + return c.clusterCache.List(ctx, list, opts...) + } + + if listOpts.Namespace != corev1.NamespaceAll { + cache, ok := c.namespaceToCache[listOpts.Namespace] + if !ok { + return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", listOpts.Namespace) + } + return cache.List(ctx, list, opts...) + } + + listAccessor, err := apimeta.ListAccessor(list) + if err != nil { + return err + } + + allItems, err := apimeta.ExtractList(list) + if err != nil { + return err + } + + limitSet := listOpts.Limit > 0 + + var resourceVersion string + for _, cache := range c.namespaceToCache { + listObj := list.DeepCopyObject().(client.ObjectList) + err = cache.List(ctx, listObj, &listOpts) + if err != nil { + return err + } + items, err := apimeta.ExtractList(listObj) + if err != nil { + return err + } + accessor, err := apimeta.ListAccessor(listObj) + if err != nil { + return fmt.Errorf("object: %T must be a list type", list) + } + allItems = append(allItems, items...) + // The last list call should have the most correct resource version. + resourceVersion = accessor.GetResourceVersion() + if limitSet { + // decrement Limit by the number of items + // fetched from the current namespace. + listOpts.Limit -= int64(len(items)) + // if a Limit was set and the number of + // items read has reached this set limit, + // then stop reading. + if listOpts.Limit == 0 { + break + } + } + } + listAccessor.SetResourceVersion(resourceVersion) + + return apimeta.SetList(list, allItems) +} + +// multiNamespaceInformer knows how to handle interacting with the underlying informer across multiple namespaces. +type multiNamespaceInformer struct { + namespaceToInformer map[string]Informer +} + +type handlerRegistration struct { + handles map[string]toolscache.ResourceEventHandlerRegistration +} + +type syncer interface { + HasSynced() bool +} + +// HasSynced asserts that the handler has been called for the full initial state of the informer. +// This uses syncer to be compatible between client-go 1.27+ and older versions when the interface changed. +func (h handlerRegistration) HasSynced() bool { + for _, reg := range h.handles { + if s, ok := reg.(syncer); ok { + if !s.HasSynced() { + return false + } + } + } + return true +} + +var _ Informer = &multiNamespaceInformer{} + +// AddEventHandler adds the handler to each namespaced informer. +func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))} + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandler(handler) + if err != nil { + return nil, err + } + handles.handles[ns] = registration + } + return handles, nil +} + +// AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer. +func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))} + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod) + if err != nil { + return nil, err + } + handles.handles[ns] = registration + } + return handles, nil +} + +// RemoveEventHandler removes a formerly added event handler given by its registration handle. +func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error { + handles, ok := h.(handlerRegistration) + if !ok { + return fmt.Errorf("it is not the registration returned by multiNamespaceInformer") + } + for ns, informer := range i.namespaceToInformer { + registration, ok := handles.handles[ns] + if !ok { + continue + } + if err := informer.RemoveEventHandler(registration); err != nil { + return err + } + } + return nil +} + +// AddIndexers adds the indexer for each namespaced informer. +func (i *multiNamespaceInformer) AddIndexers(indexers toolscache.Indexers) error { + for _, informer := range i.namespaceToInformer { + err := informer.AddIndexers(indexers) + if err != nil { + return err + } + } + return nil +} + +// HasSynced checks if each namespaced informer has synced. +func (i *multiNamespaceInformer) HasSynced() bool { + for _, informer := range i.namespaceToInformer { + if ok := informer.HasSynced(); !ok { + return ok + } + } + return true +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go new file mode 100644 index 00000000000..2b9b60d8d77 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go @@ -0,0 +1,204 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certwatcher + +import ( + "context" + "crypto/tls" + "fmt" + "sync" + "time" + + "github.com/fsnotify/fsnotify" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("certwatcher") + +// CertWatcher watches certificate and key files for changes. When either file +// changes, it reads and parses both and calls an optional callback with the new +// certificate. +type CertWatcher struct { + sync.RWMutex + + currentCert *tls.Certificate + watcher *fsnotify.Watcher + + certPath string + keyPath string + + // callback is a function to be invoked when the certificate changes. + callback func(tls.Certificate) +} + +// New returns a new CertWatcher watching the given certificate and key. +func New(certPath, keyPath string) (*CertWatcher, error) { + var err error + + cw := &CertWatcher{ + certPath: certPath, + keyPath: keyPath, + } + + // Initial read of certificate and key. + if err := cw.ReadCertificate(); err != nil { + return nil, err + } + + cw.watcher, err = fsnotify.NewWatcher() + if err != nil { + return nil, err + } + + return cw, nil +} + +// RegisterCallback registers a callback to be invoked when the certificate changes. +func (cw *CertWatcher) RegisterCallback(callback func(tls.Certificate)) { + cw.Lock() + defer cw.Unlock() + // If the current certificate is not nil, invoke the callback immediately. + if cw.currentCert != nil { + callback(*cw.currentCert) + } + cw.callback = callback +} + +// GetCertificate fetches the currently loaded certificate, which may be nil. +func (cw *CertWatcher) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { + cw.RLock() + defer cw.RUnlock() + return cw.currentCert, nil +} + +// Start starts the watch on the certificate and key files. +func (cw *CertWatcher) Start(ctx context.Context) error { + files := sets.New(cw.certPath, cw.keyPath) + + { + var watchErr error + if err := wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, func(ctx context.Context) (done bool, err error) { + for _, f := range files.UnsortedList() { + if err := cw.watcher.Add(f); err != nil { + watchErr = err + return false, nil //nolint:nilerr // We want to keep trying. + } + // We've added the watch, remove it from the set. + files.Delete(f) + } + return true, nil + }); err != nil { + return fmt.Errorf("failed to add watches: %w", kerrors.NewAggregate([]error{err, watchErr})) + } + } + + go cw.Watch() + + log.Info("Starting certificate watcher") + + // Block until the context is done. + <-ctx.Done() + + return cw.watcher.Close() +} + +// Watch reads events from the watcher's channel and reacts to changes. +func (cw *CertWatcher) Watch() { + for { + select { + case event, ok := <-cw.watcher.Events: + // Channel is closed. + if !ok { + return + } + + cw.handleEvent(event) + + case err, ok := <-cw.watcher.Errors: + // Channel is closed. + if !ok { + return + } + + log.Error(err, "certificate watch error") + } + } +} + +// ReadCertificate reads the certificate and key files from disk, parses them, +// and updates the current certificate on the watcher. If a callback is set, it +// is invoked with the new certificate. +func (cw *CertWatcher) ReadCertificate() error { + metrics.ReadCertificateTotal.Inc() + cert, err := tls.LoadX509KeyPair(cw.certPath, cw.keyPath) + if err != nil { + metrics.ReadCertificateErrors.Inc() + return err + } + + cw.Lock() + cw.currentCert = &cert + cw.Unlock() + + log.Info("Updated current TLS certificate") + + // If a callback is registered, invoke it with the new certificate. + cw.RLock() + defer cw.RUnlock() + if cw.callback != nil { + go func() { + cw.callback(cert) + }() + } + return nil +} + +func (cw *CertWatcher) handleEvent(event fsnotify.Event) { + // Only care about events which may modify the contents of the file. + if !(isWrite(event) || isRemove(event) || isCreate(event)) { + return + } + + log.V(1).Info("certificate event", "event", event) + + // If the file was removed, re-add the watch. + if isRemove(event) { + if err := cw.watcher.Add(event.Name); err != nil { + log.Error(err, "error re-watching file") + } + } + + if err := cw.ReadCertificate(); err != nil { + log.Error(err, "error re-reading certificate") + } +} + +func isWrite(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Write) +} + +func isCreate(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Create) +} + +func isRemove(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Remove) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_suite_test.go new file mode 100644 index 00000000000..a44a968c895 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_suite_test.go @@ -0,0 +1,47 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certwatcher_test + +import ( + "os" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + certPath = "testdata/tls.crt" + keyPath = "testdata/tls.key" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "CertWatcher Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) + +var _ = AfterSuite(func() { + for _, file := range []string{certPath, keyPath} { + _ = os.Remove(file) + } +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_test.go new file mode 100644 index 00000000000..7eef9d8b0e8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher_test.go @@ -0,0 +1,251 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certwatcher_test + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "net" + "os" + "sync/atomic" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus/testutil" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" + "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics" +) + +var _ = Describe("CertWatcher", func() { + var _ = Describe("certwatcher New", func() { + It("should errors without cert/key", func() { + _, err := certwatcher.New("", "") + Expect(err).ToNot(BeNil()) + }) + }) + + var _ = Describe("certwatcher Start", func() { + var ( + ctx context.Context + ctxCancel context.CancelFunc + watcher *certwatcher.CertWatcher + ) + + BeforeEach(func() { + ctx, ctxCancel = context.WithCancel(context.Background()) + + err := writeCerts(certPath, keyPath, "127.0.0.1") + Expect(err).To(BeNil()) + + Eventually(func() error { + for _, file := range []string{certPath, keyPath} { + _, err := os.ReadFile(file) + if err != nil { + return err + } + continue + } + + return nil + }).Should(Succeed()) + + watcher, err = certwatcher.New(certPath, keyPath) + Expect(err).To(BeNil()) + }) + + startWatcher := func() (done <-chan struct{}) { + doneCh := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(doneCh) + Expect(watcher.Start(ctx)).To(Succeed()) + }() + // wait till we read first cert + Eventually(func() error { + err := watcher.ReadCertificate() + return err + }).Should(Succeed()) + return doneCh + } + + It("should read the initial cert/key", func() { + doneCh := startWatcher() + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + + It("should reload currentCert when changed", func() { + doneCh := startWatcher() + called := atomic.Int64{} + watcher.RegisterCallback(func(crt tls.Certificate) { + called.Add(1) + Expect(crt.Certificate).ToNot(BeEmpty()) + }) + + firstcert, _ := watcher.GetCertificate(nil) + + err := writeCerts(certPath, keyPath, "192.168.0.1") + Expect(err).To(BeNil()) + + Eventually(func() bool { + secondcert, _ := watcher.GetCertificate(nil) + first := firstcert.PrivateKey.(*rsa.PrivateKey) + return first.Equal(secondcert.PrivateKey) + }).ShouldNot(BeTrue()) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + Expect(called.Load()).To(BeNumerically(">=", 1)) + }) + + Context("prometheus metric read_certificate_total", func() { + var readCertificateTotalBefore float64 + var readCertificateErrorsBefore float64 + + BeforeEach(func() { + readCertificateTotalBefore = testutil.ToFloat64(metrics.ReadCertificateTotal) + readCertificateErrorsBefore = testutil.ToFloat64(metrics.ReadCertificateErrors) + }) + + It("should get updated on successful certificate read", func() { + doneCh := startWatcher() + + Eventually(func() error { + readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal) + if readCertificateTotalAfter != readCertificateTotalBefore+1.0 { + return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter) + } + return nil + }, "4s").Should(Succeed()) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + + It("should get updated on read certificate errors", func() { + doneCh := startWatcher() + + Eventually(func() error { + readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal) + if readCertificateTotalAfter != readCertificateTotalBefore+1.0 { + return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter) + } + readCertificateTotalBefore = readCertificateTotalAfter + return nil + }, "4s").Should(Succeed()) + + Expect(os.Remove(keyPath)).To(BeNil()) + + Eventually(func() error { + readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal) + if readCertificateTotalAfter != readCertificateTotalBefore+1.0 { + return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter) + } + return nil + }, "4s").Should(Succeed()) + Eventually(func() error { + readCertificateErrorsAfter := testutil.ToFloat64(metrics.ReadCertificateErrors) + if readCertificateErrorsAfter != readCertificateErrorsBefore+1.0 { + return fmt.Errorf("metric read certificate errors expected: %v and got: %v", readCertificateErrorsBefore+1.0, readCertificateErrorsAfter) + } + return nil + }, "4s").Should(Succeed()) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + }) + }) +}) + +func writeCerts(certPath, keyPath, ip string) error { + var priv interface{} + var err error + priv, err = rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return err + } + + keyUsage := x509.KeyUsageDigitalSignature + if _, isRSA := priv.(*rsa.PrivateKey); isRSA { + keyUsage |= x509.KeyUsageKeyEncipherment + } + + notBefore := time.Now() + notAfter := notBefore.Add(1 * time.Hour) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return err + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Kubernetes"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: keyUsage, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + template.IPAddresses = append(template.IPAddresses, net.ParseIP(ip)) + + privkey := priv.(*rsa.PrivateKey) + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privkey.PublicKey, priv) + if err != nil { + return err + } + + certOut, err := os.Create(certPath) + if err != nil { + return err + } + if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { + return err + } + if err := certOut.Close(); err != nil { + return err + } + + keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + privBytes, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + return err + } + if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { + return err + } + return keyOut.Close() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go new file mode 100644 index 00000000000..40c2fc0bfbf --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package certwatcher is a helper for reloading Certificates from disk to be used +with tls servers. It provides a helper func `GetCertificate` which can be +called from `tls.Config` and passed into your tls.Listener. For a detailed +example server view pkg/webhook/server.go. +*/ +package certwatcher diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/example_test.go new file mode 100644 index 00000000000..e322aeebfc8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/example_test.go @@ -0,0 +1,81 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certwatcher_test + +import ( + "context" + "crypto/tls" + "net/http" + "time" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" +) + +type sampleServer struct { +} + +func Example() { + // Setup Context + ctx := ctrl.SetupSignalHandler() + + // Initialize a new cert watcher with cert/key pair + watcher, err := certwatcher.New("ssl/tls.crt", "ssl/tls.key") + if err != nil { + panic(err) + } + + // Start goroutine with certwatcher running fsnotify against supplied certdir + go func() { + if err := watcher.Start(ctx); err != nil { + panic(err) + } + }() + + // Setup TLS listener using GetCertficate for fetching the cert when changes + listener, err := tls.Listen("tcp", "localhost:9443", &tls.Config{ + GetCertificate: watcher.GetCertificate, + MinVersion: tls.VersionTLS12, + }) + if err != nil { + panic(err) + } + + // Initialize your tls server + srv := &http.Server{ + Handler: &sampleServer{}, + ReadHeaderTimeout: 5 * time.Second, + } + + // Start goroutine for handling server shutdown. + go func() { + <-ctx.Done() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + panic(err) + } + }() + + // Serve t + if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed { + panic(err) + } +} + +func (s *sampleServer) ServeHTTP(http.ResponseWriter, *http.Request) { +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go new file mode 100644 index 00000000000..05869eff030 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // ReadCertificateTotal is a prometheus counter metrics which holds the total + // number of certificate reads. + ReadCertificateTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "certwatcher_read_certificate_total", + Help: "Total number of certificate reads", + }) + + // ReadCertificateErrors is a prometheus counter metrics which holds the total + // number of errors from certificate read. + ReadCertificateErrors = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "certwatcher_read_certificate_errors_total", + Help: "Total number of certificate read errors", + }) +) + +func init() { + metrics.Registry.MustRegister( + ReadCertificateTotal, + ReadCertificateErrors, + ) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/testdata/.gitkeep b/third_party/sigs.k8s.io/controller-runtime/pkg/certwatcher/testdata/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go new file mode 100644 index 00000000000..6a1bfb546ea --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go @@ -0,0 +1,246 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package apiutil contains utilities for working with raw Kubernetes +// API machinery, such as creating RESTMappers and raw REST clients, +// and extracting the GVK of an object. +package apiutil + +import ( + "errors" + "fmt" + "net/http" + "reflect" + "sync" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" +) + +var ( + protobufScheme = runtime.NewScheme() + protobufSchemeLock sync.RWMutex +) + +func init() { + // Currently only enabled for built-in resources which are guaranteed to implement Protocol Buffers. + // For custom resources, CRDs can not support Protocol Buffers but Aggregated API can. + // See doc: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#advanced-features-and-flexibility + if err := clientgoscheme.AddToScheme(protobufScheme); err != nil { + panic(err) + } +} + +// AddToProtobufScheme add the given SchemeBuilder into protobufScheme, which should +// be additional types that do support protobuf. +func AddToProtobufScheme(addToScheme func(*runtime.Scheme) error) error { + protobufSchemeLock.Lock() + defer protobufSchemeLock.Unlock() + return addToScheme(protobufScheme) +} + +// NewDiscoveryRESTMapper constructs a new RESTMapper based on discovery +// information fetched by a new client with the given config. +func NewDiscoveryRESTMapper(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + + // Get a mapper + dc, err := discovery.NewDiscoveryClientForConfigAndClient(c, httpClient) + if err != nil { + return nil, err + } + gr, err := restmapper.GetAPIGroupResources(dc) + if err != nil { + return nil, err + } + return restmapper.NewDiscoveryRESTMapper(gr), nil +} + +// IsObjectNamespaced returns true if the object is namespace scoped. +// For unstructured objects the gvk is found from the object itself. +func IsObjectNamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper meta.RESTMapper) (bool, error) { + gvk, err := GVKForObject(obj, scheme) + if err != nil { + return false, err + } + + return IsGVKNamespaced(gvk, restmapper) +} + +// IsGVKNamespaced returns true if the object having the provided +// GVK is namespace scoped. +func IsGVKNamespaced(gvk schema.GroupVersionKind, restmapper meta.RESTMapper) (bool, error) { + restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}) + if err != nil { + return false, fmt.Errorf("failed to get restmapping: %w", err) + } + + scope := restmapping.Scope.Name() + if scope == "" { + return false, errors.New("scope cannot be identified, empty scope returned") + } + + if scope != meta.RESTScopeNameRoot { + return true, nil + } + return false, nil +} + +// GVKForObject finds the GroupVersionKind associated with the given object, if there is only a single such GVK. +func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersionKind, error) { + // TODO(directxman12): do we want to generalize this to arbitrary container types? + // I think we'd need a generalized form of scheme or something. It's a + // shame there's not a reliable "GetGVK" interface that works by default + // for unpopulated static types and populated "dynamic" types + // (unstructured, partial, etc) + + // check for PartialObjectMetadata, which is analogous to unstructured, but isn't handled by ObjectKinds + _, isPartial := obj.(*metav1.PartialObjectMetadata) + _, isPartialList := obj.(*metav1.PartialObjectMetadataList) + if isPartial || isPartialList { + // we require that the GVK be populated in order to recognize the object + gvk := obj.GetObjectKind().GroupVersionKind() + if len(gvk.Kind) == 0 { + return schema.GroupVersionKind{}, runtime.NewMissingKindErr("unstructured object has no kind") + } + if len(gvk.Version) == 0 { + return schema.GroupVersionKind{}, runtime.NewMissingVersionErr("unstructured object has no version") + } + return gvk, nil + } + + // Use the given scheme to retrieve all the GVKs for the object. + gvks, isUnversioned, err := scheme.ObjectKinds(obj) + if err != nil { + return schema.GroupVersionKind{}, err + } + if isUnversioned { + return schema.GroupVersionKind{}, fmt.Errorf("cannot create group-version-kind for unversioned type %T", obj) + } + + switch { + case len(gvks) < 1: + // If the object has no GVK, the object might not have been registered with the scheme. + // or it's not a valid object. + return schema.GroupVersionKind{}, fmt.Errorf("no GroupVersionKind associated with Go type %T, was the type registered with the Scheme?", obj) + case len(gvks) > 1: + err := fmt.Errorf("multiple GroupVersionKinds associated with Go type %T within the Scheme, this can happen when a type is registered for multiple GVKs at the same time", obj) + + // We've found multiple GVKs for the object. + currentGVK := obj.GetObjectKind().GroupVersionKind() + if !currentGVK.Empty() { + // If the base object has a GVK, check if it's in the list of GVKs before using it. + for _, gvk := range gvks { + if gvk == currentGVK { + return gvk, nil + } + } + + return schema.GroupVersionKind{}, fmt.Errorf( + "%w: the object's supplied GroupVersionKind %q was not found in the Scheme's list; refusing to guess at one: %q", err, currentGVK, gvks) + } + + // This should only trigger for things like metav1.XYZ -- + // normal versioned types should be fine. + // + // See https://github.com/kubernetes-sigs/controller-runtime/issues/362 + // for more information. + return schema.GroupVersionKind{}, fmt.Errorf( + "%w: callers can either fix their type registration to only register it once, or specify the GroupVersionKind to use for object passed in; refusing to guess at one: %q", err, gvks) + default: + // In any other case, we've found a single GVK for the object. + return gvks[0], nil + } +} + +// RESTClientForGVK constructs a new rest.Interface capable of accessing the resource associated +// with the given GroupVersionKind. The REST client will be configured to use the negotiated serializer from +// baseConfig, if set, otherwise a default serializer will be set. +func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory, httpClient *http.Client) (rest.Interface, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + return rest.RESTClientForConfigAndClient(createRestConfig(gvk, isUnstructured, baseConfig, codecs), httpClient) +} + +// createRestConfig copies the base config and updates needed fields for a new rest config. +func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) *rest.Config { + gv := gvk.GroupVersion() + + cfg := rest.CopyConfig(baseConfig) + cfg.GroupVersion = &gv + if gvk.Group == "" { + cfg.APIPath = "/api" + } else { + cfg.APIPath = "/apis" + } + if cfg.UserAgent == "" { + cfg.UserAgent = rest.DefaultKubernetesUserAgent() + } + // TODO(FillZpp): In the long run, we want to check discovery or something to make sure that this is actually true. + if cfg.ContentType == "" && !isUnstructured { + protobufSchemeLock.RLock() + if protobufScheme.Recognizes(gvk) { + cfg.ContentType = runtime.ContentTypeProtobuf + } + protobufSchemeLock.RUnlock() + } + + if isUnstructured { + // If the object is unstructured, we use the client-go dynamic serializer. + cfg = dynamic.ConfigFor(cfg) + } else { + cfg.NegotiatedSerializer = serializerWithTargetZeroingDecode{NegotiatedSerializer: serializer.WithoutConversionCodecFactory{CodecFactory: codecs}} + } + + return cfg +} + +type serializerWithTargetZeroingDecode struct { + runtime.NegotiatedSerializer +} + +func (s serializerWithTargetZeroingDecode) DecoderToVersion(serializer runtime.Decoder, r runtime.GroupVersioner) runtime.Decoder { + return targetZeroingDecoder{upstream: s.NegotiatedSerializer.DecoderToVersion(serializer, r)} +} + +type targetZeroingDecoder struct { + upstream runtime.Decoder +} + +func (t targetZeroingDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { + zero(into) + return t.upstream.Decode(data, defaults, into) +} + +// zero zeros the value of a pointer. +func zero(x interface{}) { + if x == nil { + return + } + res := reflect.ValueOf(x).Elem() + res.Set(reflect.Zero(res.Type())) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apiutil_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apiutil_suite_test.go new file mode 100644 index 00000000000..7fe960b9179 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apiutil_suite_test.go @@ -0,0 +1,42 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiutil + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "API Utilities Test Suite") +} + +var cfg *rest.Config + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + // for things that technically need a rest.Config for defaulting, but don't actually use them + cfg = &rest.Config{} +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go new file mode 100644 index 00000000000..f14f8a9f598 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go @@ -0,0 +1,287 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiutil + +import ( + "fmt" + "net/http" + "sync" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" +) + +// NewDynamicRESTMapper returns a dynamic RESTMapper for cfg. The dynamic +// RESTMapper dynamically discovers resource types at runtime. +func NewDynamicRESTMapper(cfg *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + + client, err := discovery.NewDiscoveryClientForConfigAndClient(cfg, httpClient) + if err != nil { + return nil, err + } + return &mapper{ + mapper: restmapper.NewDiscoveryRESTMapper([]*restmapper.APIGroupResources{}), + client: client, + knownGroups: map[string]*restmapper.APIGroupResources{}, + apiGroups: map[string]*metav1.APIGroup{}, + }, nil +} + +// mapper is a RESTMapper that will lazily query the provided +// client for discovery information to do REST mappings. +type mapper struct { + mapper meta.RESTMapper + client *discovery.DiscoveryClient + knownGroups map[string]*restmapper.APIGroupResources + apiGroups map[string]*metav1.APIGroup + + // mutex to provide thread-safe mapper reloading. + mu sync.RWMutex +} + +// KindFor implements Mapper.KindFor. +func (m *mapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + res, err := m.getMapper().KindFor(resource) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil { + return schema.GroupVersionKind{}, err + } + res, err = m.getMapper().KindFor(resource) + } + + return res, err +} + +// KindsFor implements Mapper.KindsFor. +func (m *mapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { + res, err := m.getMapper().KindsFor(resource) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil { + return nil, err + } + res, err = m.getMapper().KindsFor(resource) + } + + return res, err +} + +// ResourceFor implements Mapper.ResourceFor. +func (m *mapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) { + res, err := m.getMapper().ResourceFor(input) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(input.Group, input.Version); err != nil { + return schema.GroupVersionResource{}, err + } + res, err = m.getMapper().ResourceFor(input) + } + + return res, err +} + +// ResourcesFor implements Mapper.ResourcesFor. +func (m *mapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + res, err := m.getMapper().ResourcesFor(input) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(input.Group, input.Version); err != nil { + return nil, err + } + res, err = m.getMapper().ResourcesFor(input) + } + + return res, err +} + +// RESTMapping implements Mapper.RESTMapping. +func (m *mapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) { + res, err := m.getMapper().RESTMapping(gk, versions...) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(gk.Group, versions...); err != nil { + return nil, err + } + res, err = m.getMapper().RESTMapping(gk, versions...) + } + + return res, err +} + +// RESTMappings implements Mapper.RESTMappings. +func (m *mapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) { + res, err := m.getMapper().RESTMappings(gk, versions...) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(gk.Group, versions...); err != nil { + return nil, err + } + res, err = m.getMapper().RESTMappings(gk, versions...) + } + + return res, err +} + +// ResourceSingularizer implements Mapper.ResourceSingularizer. +func (m *mapper) ResourceSingularizer(resource string) (string, error) { + return m.getMapper().ResourceSingularizer(resource) +} + +func (m *mapper) getMapper() meta.RESTMapper { + m.mu.RLock() + defer m.mu.RUnlock() + return m.mapper +} + +// addKnownGroupAndReload reloads the mapper with updated information about missing API group. +// versions can be specified for partial updates, for instance for v1beta1 version only. +func (m *mapper) addKnownGroupAndReload(groupName string, versions ...string) error { + // If no specific versions are set by user, we will scan all available ones for the API group. + // This operation requires 2 requests: /api and /apis, but only once. For all subsequent calls + // this data will be taken from cache. + if len(versions) == 0 { + apiGroup, err := m.findAPIGroupByName(groupName) + if err != nil { + return err + } + for _, version := range apiGroup.Versions { + versions = append(versions, version.Version) + } + } + + m.mu.Lock() + defer m.mu.Unlock() + + // Create or fetch group resources from cache. + groupResources := &restmapper.APIGroupResources{ + Group: metav1.APIGroup{Name: groupName}, + VersionedResources: make(map[string][]metav1.APIResource), + } + if _, ok := m.knownGroups[groupName]; ok { + groupResources = m.knownGroups[groupName] + } + + // Update information for group resources about versioned resources. + // The number of API calls is equal to the number of versions: /apis//. + groupVersionResources, err := m.fetchGroupVersionResources(groupName, versions...) + if err != nil { + return fmt.Errorf("failed to get API group resources: %w", err) + } + for version, resources := range groupVersionResources { + groupResources.VersionedResources[version.Version] = resources.APIResources + } + + // Update information for group resources about the API group by adding new versions. + // Ignore the versions that are already registered. + for _, version := range versions { + found := false + for _, v := range groupResources.Group.Versions { + if v.Version == version { + found = true + break + } + } + + if !found { + groupResources.Group.Versions = append(groupResources.Group.Versions, metav1.GroupVersionForDiscovery{ + GroupVersion: metav1.GroupVersion{Group: groupName, Version: version}.String(), + Version: version, + }) + } + } + + // Update data in the cache. + m.knownGroups[groupName] = groupResources + + // Finally, update the group with received information and regenerate the mapper. + updatedGroupResources := make([]*restmapper.APIGroupResources, 0, len(m.knownGroups)) + for _, agr := range m.knownGroups { + updatedGroupResources = append(updatedGroupResources, agr) + } + + m.mapper = restmapper.NewDiscoveryRESTMapper(updatedGroupResources) + return nil +} + +// findAPIGroupByNameLocked returns API group by its name. +func (m *mapper) findAPIGroupByName(groupName string) (*metav1.APIGroup, error) { + // Looking in the cache first. + { + m.mu.RLock() + group, ok := m.apiGroups[groupName] + m.mu.RUnlock() + if ok { + return group, nil + } + } + + // Update the cache if nothing was found. + apiGroups, err := m.client.ServerGroups() + if err != nil { + return nil, fmt.Errorf("failed to get server groups: %w", err) + } + if len(apiGroups.Groups) == 0 { + return nil, fmt.Errorf("received an empty API groups list") + } + + m.mu.Lock() + for i := range apiGroups.Groups { + group := &apiGroups.Groups[i] + m.apiGroups[group.Name] = group + } + m.mu.Unlock() + + // Looking in the cache again. + { + m.mu.RLock() + group, ok := m.apiGroups[groupName] + m.mu.RUnlock() + if ok { + return group, nil + } + } + + // If there is still nothing, return an error. + return nil, fmt.Errorf("failed to find API group %q", groupName) +} + +// fetchGroupVersionResources fetches the resources for the specified group and its versions. +func (m *mapper) fetchGroupVersionResources(groupName string, versions ...string) (map[schema.GroupVersion]*metav1.APIResourceList, error) { + groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList) + failedGroups := make(map[schema.GroupVersion]error) + + for _, version := range versions { + groupVersion := schema.GroupVersion{Group: groupName, Version: version} + + apiResourceList, err := m.client.ServerResourcesForGroupVersion(groupVersion.String()) + if err != nil { + failedGroups[groupVersion] = err + } + if apiResourceList != nil { + // even in case of error, some fallback might have been returned. + groupVersionResources[groupVersion] = apiResourceList + } + } + + if len(failedGroups) > 0 { + return nil, &discovery.ErrGroupDiscoveryFailed{Groups: failedGroups} + } + + return groupVersionResources, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper_test.go new file mode 100644 index 00000000000..99ea5a79d8d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper_test.go @@ -0,0 +1,483 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiutil_test + +import ( + "context" + "net/http" + "testing" + + _ "github.com/onsi/ginkgo/v2" + gmg "github.com/onsi/gomega" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +// countingRoundTripper is used to count HTTP requests. +type countingRoundTripper struct { + roundTripper http.RoundTripper + requestCount int +} + +func newCountingRoundTripper(rt http.RoundTripper) *countingRoundTripper { + return &countingRoundTripper{roundTripper: rt} +} + +// RoundTrip implements http.RoundTripper.RoundTrip that additionally counts requests. +func (crt *countingRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + crt.requestCount++ + + return crt.roundTripper.RoundTrip(r) +} + +// GetRequestCount returns how many requests have been made. +func (crt *countingRoundTripper) GetRequestCount() int { + return crt.requestCount +} + +// Reset sets the counter to 0. +func (crt *countingRoundTripper) Reset() { + crt.requestCount = 0 +} + +func setupEnvtest(t *testing.T) (*rest.Config, func(t *testing.T)) { + t.Log("Setup envtest") + + g := gmg.NewWithT(t) + testEnv := &envtest.Environment{ + CRDDirectoryPaths: []string{"testdata"}, + } + + cfg, err := testEnv.Start() + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(cfg).NotTo(gmg.BeNil()) + + teardownFunc := func(t *testing.T) { + t.Log("Stop envtest") + g.Expect(testEnv.Stop()).To(gmg.Succeed()) + } + + return cfg, teardownFunc +} + +func TestLazyRestMapperProvider(t *testing.T) { + restCfg, tearDownFn := setupEnvtest(t) + defer tearDownFn(t) + + t.Run("LazyRESTMapper should fetch data based on the request", func(t *testing.T) { + g := gmg.NewWithT(t) + + // For each new group it performs just one request to the API server: + // GET https://host/apis// + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + // There are no requests before any call + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "apps", Kind: "deployment"}, "v1") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("deployment")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(1)) + + mappings, err := lazyRestMapper.RESTMappings(schema.GroupKind{Group: "", Kind: "pod"}, "v1") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(len(mappings)).To(gmg.Equal(1)) + g.Expect(mappings[0].GroupVersionKind.Kind).To(gmg.Equal("pod")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + kind, err := lazyRestMapper.KindFor(schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingresses"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(kind.Kind).To(gmg.Equal("Ingress")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + kinds, err := lazyRestMapper.KindsFor(schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1", Resource: "tokenreviews"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(len(kinds)).To(gmg.Equal(1)) + g.Expect(kinds[0].Kind).To(gmg.Equal("TokenReview")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + resource, err := lazyRestMapper.ResourceFor(schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1", Resource: "priorityclasses"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(resource.Resource).To(gmg.Equal("priorityclasses")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(5)) + + resources, err := lazyRestMapper.ResourcesFor(schema.GroupVersionResource{Group: "policy", Version: "v1", Resource: "poddisruptionbudgets"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(len(resources)).To(gmg.Equal(1)) + g.Expect(resources[0].Resource).To(gmg.Equal("poddisruptionbudgets")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(6)) + }) + + t.Run("LazyRESTMapper should cache fetched data and doesn't perform any additional requests", func(t *testing.T) { + g := gmg.NewWithT(t) + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "apps", Kind: "deployment"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("deployment")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + // Data taken from cache - there are no more additional requests. + + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "apps", Kind: "deployment"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("deployment")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + kind, err := lazyRestMapper.KindFor((schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployment"})) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(kind.Kind).To(gmg.Equal("Deployment")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + resource, err := lazyRestMapper.ResourceFor((schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployment"})) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(resource.Resource).To(gmg.Equal("deployments")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + }) + + t.Run("LazyRESTMapper should work correctly with empty versions list", func(t *testing.T) { + g := gmg.NewWithT(t) + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + // crew.example.com has 2 versions: v1 and v2 + + // If no versions were provided by user, we fetch all of them. + // Here we expect 4 calls. + // To initialize: + // #1: GET https://host/api + // #2: GET https://host/apis + // Then, for each version it performs one request to the API server: + // #3: GET https://host/apis/crew.example.com/v1 + // #4: GET https://host/apis/crew.example.com/v2 + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + // All subsequent calls won't send requests to the server. + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + }) + + t.Run("LazyRESTMapper should work correctly with multiple API group versions", func(t *testing.T) { + g := gmg.NewWithT(t) + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + // We explicitly ask for 2 versions: v1 and v2. + // For each version it performs one request to the API server: + // #1: GET https://host/apis/crew.example.com/v1 + // #2: GET https://host/apis/crew.example.com/v2 + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v1", "v2") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + // All subsequent calls won't send requests to the server as everything is stored in the cache. + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v1") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + }) + + t.Run("LazyRESTMapper should work correctly with different API group versions", func(t *testing.T) { + g := gmg.NewWithT(t) + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + // Now we want resources for crew.example.com/v1 version only. + // Here we expect 1 call: + // #1: GET https://host/apis/crew.example.com/v1 + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v1") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(1)) + + // Get additional resources from v2. + // It sends another request: + // #2: GET https://host/apis/crew.example.com/v2 + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v2") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + // No subsequent calls require additional API requests. + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v1") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}, "v1", "v2") + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + }) + + t.Run("LazyRESTMapper should return an error if the group doesn't exist", func(t *testing.T) { + g := gmg.NewWithT(t) + + // After initialization for each invalid group the mapper performs just 1 request to the API server. + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + _, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "INVALID1"}, "v1") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(1)) + + _, err = lazyRestMapper.RESTMappings(schema.GroupKind{Group: "INVALID2"}, "v1") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + _, err = lazyRestMapper.KindFor(schema.GroupVersionResource{Group: "INVALID3", Version: "v1"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + _, err = lazyRestMapper.KindsFor(schema.GroupVersionResource{Group: "INVALID4", Version: "v1"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + _, err = lazyRestMapper.ResourceFor(schema.GroupVersionResource{Group: "INVALID5", Version: "v1"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(5)) + + _, err = lazyRestMapper.ResourcesFor(schema.GroupVersionResource{Group: "INVALID6", Version: "v1"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(6)) + }) + + t.Run("LazyRESTMapper should return an error if a resource doesn't exist", func(t *testing.T) { + g := gmg.NewWithT(t) + + // For each invalid resource the mapper performs just 1 request to the API server. + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + _, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "apps", Kind: "INVALID"}, "v1") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(1)) + + _, err = lazyRestMapper.RESTMappings(schema.GroupKind{Group: "", Kind: "INVALID"}, "v1") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + _, err = lazyRestMapper.KindFor(schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "INVALID"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + _, err = lazyRestMapper.KindsFor(schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1", Resource: "INVALID"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + _, err = lazyRestMapper.ResourceFor(schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1", Resource: "INVALID"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(5)) + + _, err = lazyRestMapper.ResourcesFor(schema.GroupVersionResource{Group: "policy", Version: "v1", Resource: "INVALID"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(6)) + }) + + t.Run("LazyRESTMapper should return an error if the version doesn't exist", func(t *testing.T) { + g := gmg.NewWithT(t) + + // After initialization, for each invalid resource mapper performs 1 requests to the API server. + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + _, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "apps", Kind: "deployment"}, "INVALID") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(1)) + + _, err = lazyRestMapper.RESTMappings(schema.GroupKind{Group: "", Kind: "pod"}, "INVALID") + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(2)) + + _, err = lazyRestMapper.KindFor(schema.GroupVersionResource{Group: "networking.k8s.io", Version: "INVALID", Resource: "ingresses"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(3)) + + _, err = lazyRestMapper.KindsFor(schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "INVALID", Resource: "tokenreviews"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + _, err = lazyRestMapper.ResourceFor(schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "INVALID", Resource: "priorityclasses"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(5)) + + _, err = lazyRestMapper.ResourcesFor(schema.GroupVersionResource{Group: "policy", Version: "INVALID", Resource: "poddisruptionbudgets"}) + g.Expect(err).To(gmg.HaveOccurred()) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(6)) + }) + + t.Run("LazyRESTMapper can fetch CRDs if they were created at runtime", func(t *testing.T) { + g := gmg.NewWithT(t) + + // To fetch all versions mapper does 2 requests: + // GET https://host/api + // GET https://host/apis + // Then, for each version it performs just one request to the API server as usual: + // GET https://host/apis// + + httpClient, err := rest.HTTPClientFor(restCfg) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + crt := newCountingRoundTripper(httpClient.Transport) + httpClient.Transport = crt + + lazyRestMapper, err := apiutil.NewDynamicRESTMapper(restCfg, httpClient) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + // There are no requests before any call + g.Expect(crt.GetRequestCount()).To(gmg.Equal(0)) + + // Since we don't specify what version we expect, restmapper will fetch them all and search there. + // To fetch a list of available versions + // #1: GET https://host/api + // #2: GET https://host/apis + // Then, for each currently registered version: + // #3: GET https://host/apis/crew.example.com/v1 + // #4: GET https://host/apis/crew.example.com/v2 + mapping, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "driver"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("driver")) + g.Expect(crt.GetRequestCount()).To(gmg.Equal(4)) + + s := scheme.Scheme + err = apiextensionsv1.AddToScheme(s) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + c, err := client.New(restCfg, client.Options{Scheme: s}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + + // Register another CRD in runtime - "riders.crew.example.com". + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(crd.Spec.Names.Kind).To(gmg.Equal("Driver")) + + newCRD := &apiextensionsv1.CustomResourceDefinition{} + crd.DeepCopyInto(newCRD) + newCRD.Name = "riders.crew.example.com" + newCRD.Spec.Names = apiextensionsv1.CustomResourceDefinitionNames{ + Kind: "Rider", + Plural: "riders", + } + newCRD.ResourceVersion = "" + + // Create the new CRD. + g.Expect(c.Create(context.TODO(), newCRD)).To(gmg.Succeed()) + + // Wait a bit until the CRD is registered. + g.Eventually(func() error { + _, err := lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "rider"}) + return err + }).Should(gmg.Succeed()) + + // Since we don't specify what version we expect, restmapper will fetch them all and search there. + // To fetch a list of available versions + // #1: GET https://host/api + // #2: GET https://host/apis + // Then, for each currently registered version: + // #3: GET https://host/apis/crew.example.com/v1 + // #4: GET https://host/apis/crew.example.com/v2 + mapping, err = lazyRestMapper.RESTMapping(schema.GroupKind{Group: "crew.example.com", Kind: "rider"}) + g.Expect(err).NotTo(gmg.HaveOccurred()) + g.Expect(mapping.GroupVersionKind.Kind).To(gmg.Equal("rider")) + }) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/testdata/crd.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/testdata/crd.yaml new file mode 100644 index 00000000000..5bb2d73f698 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/apiutil/testdata/crd.yaml @@ -0,0 +1,62 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: drivers.crew.example.com +spec: + group: crew.example.com + names: + kind: Driver + plural: drivers + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object + - name: v2 + served: true + storage: false + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client.go new file mode 100644 index 00000000000..21067b6f8fc --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client.go @@ -0,0 +1,587 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/metadata" + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +// Options are creation options for a Client. +type Options struct { + // HTTPClient is the HTTP client to use for requests. + HTTPClient *http.Client + + // Scheme, if provided, will be used to map go structs to GroupVersionKinds + Scheme *runtime.Scheme + + // Mapper, if provided, will be used to map GroupVersionKinds to Resources + Mapper meta.RESTMapper + + // Cache, if provided, is used to read objects from the cache. + Cache *CacheOptions + + // WarningHandler is used to configure the warning handler responsible for + // surfacing and handling warnings messages sent by the API server. + WarningHandler WarningHandlerOptions + + // DryRun instructs the client to only perform dry run requests. + DryRun *bool +} + +// WarningHandlerOptions are options for configuring a +// warning handler for the client which is responsible +// for surfacing API Server warnings. +type WarningHandlerOptions struct { + // SuppressWarnings decides if the warnings from the + // API server are suppressed or surfaced in the client. + SuppressWarnings bool + // AllowDuplicateLogs does not deduplicate the to-be + // logged surfaced warnings messages. See + // log.WarningHandlerOptions for considerations + // regarding deduplication + AllowDuplicateLogs bool +} + +// CacheOptions are options for creating a cache-backed client. +type CacheOptions struct { + // Reader is a cache-backed reader that will be used to read objects from the cache. + // +required + Reader Reader + // DisableFor is a list of objects that should not be read from the cache. + DisableFor []Object + // Unstructured is a flag that indicates whether the cache-backed client should + // read unstructured objects or lists from the cache. + Unstructured bool +} + +// NewClientFunc allows a user to define how to create a client. +type NewClientFunc func(config *rest.Config, options Options) (Client, error) + +// New returns a new Client using the provided config and Options. +// The returned client reads *and* writes directly from the server +// (it doesn't use object caches). It understands how to work with +// normal types (both custom resources and aggregated/built-in resources), +// as well as unstructured types. +// +// In the case of normal types, the scheme will be used to look up the +// corresponding group, version, and kind for the given type. In the +// case of unstructured types, the group, version, and kind will be extracted +// from the corresponding fields on the object. +func New(config *rest.Config, options Options) (c Client, err error) { + c, err = newClient(config, options) + if err == nil && options.DryRun != nil && *options.DryRun { + c = NewDryRunClient(c) + } + return c, err +} + +func newClient(config *rest.Config, options Options) (*client, error) { + if config == nil { + return nil, fmt.Errorf("must provide non-nil rest.Config to client.New") + } + + if !options.WarningHandler.SuppressWarnings { + // surface warnings + logger := log.Log.WithName("KubeAPIWarningLogger") + // Set a WarningHandler, the default WarningHandler + // is log.KubeAPIWarningLogger with deduplication enabled. + // See log.KubeAPIWarningLoggerOptions for considerations + // regarding deduplication. + config = rest.CopyConfig(config) + config.WarningHandler = log.NewKubeAPIWarningLogger( + logger, + log.KubeAPIWarningLoggerOptions{ + Deduplicate: !options.WarningHandler.AllowDuplicateLogs, + }, + ) + } + + // Use the rest HTTP client for the provided config if unset + if options.HTTPClient == nil { + var err error + options.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return nil, err + } + } + + // Init a scheme if none provided + if options.Scheme == nil { + options.Scheme = scheme.Scheme + } + + // Init a Mapper if none provided + if options.Mapper == nil { + var err error + options.Mapper, err = apiutil.NewDynamicRESTMapper(config, options.HTTPClient) + if err != nil { + return nil, err + } + } + + resources := &clientRestResources{ + httpClient: options.HTTPClient, + config: config, + scheme: options.Scheme, + mapper: options.Mapper, + codecs: serializer.NewCodecFactory(options.Scheme), + + structuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta), + unstructuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta), + } + + rawMetaClient, err := metadata.NewForConfigAndClient(config, options.HTTPClient) + if err != nil { + return nil, fmt.Errorf("unable to construct metadata-only client for use as part of client: %w", err) + } + + c := &client{ + typedClient: typedClient{ + resources: resources, + paramCodec: runtime.NewParameterCodec(options.Scheme), + }, + unstructuredClient: unstructuredClient{ + resources: resources, + paramCodec: noConversionParamCodec{}, + }, + metadataClient: metadataClient{ + client: rawMetaClient, + restMapper: options.Mapper, + }, + scheme: options.Scheme, + mapper: options.Mapper, + } + if options.Cache == nil || options.Cache.Reader == nil { + return c, nil + } + + // We want a cache if we're here. + // Set the cache. + c.cache = options.Cache.Reader + + // Load uncached GVKs. + c.cacheUnstructured = options.Cache.Unstructured + c.uncachedGVKs = map[schema.GroupVersionKind]struct{}{} + for _, obj := range options.Cache.DisableFor { + gvk, err := c.GroupVersionKindFor(obj) + if err != nil { + return nil, err + } + c.uncachedGVKs[gvk] = struct{}{} + } + return c, nil +} + +var _ Client = &client{} + +// client is a client.Client that reads and writes directly from/to an API server. +// It lazily initializes new clients at the time they are used. +type client struct { + typedClient typedClient + unstructuredClient unstructuredClient + metadataClient metadataClient + scheme *runtime.Scheme + mapper meta.RESTMapper + + cache Reader + uncachedGVKs map[schema.GroupVersionKind]struct{} + cacheUnstructured bool +} + +func (c *client) shouldBypassCache(obj runtime.Object) (bool, error) { + if c.cache == nil { + return true, nil + } + + gvk, err := c.GroupVersionKindFor(obj) + if err != nil { + return false, err + } + // TODO: this is producing unsafe guesses that don't actually work, + // but it matches ~99% of the cases out there. + if meta.IsListType(obj) { + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + } + if _, isUncached := c.uncachedGVKs[gvk]; isUncached { + return true, nil + } + if !c.cacheUnstructured { + _, isUnstructured := obj.(runtime.Unstructured) + return isUnstructured, nil + } + return false, nil +} + +// resetGroupVersionKind is a helper function to restore and preserve GroupVersionKind on an object. +func (c *client) resetGroupVersionKind(obj runtime.Object, gvk schema.GroupVersionKind) { + if gvk != schema.EmptyObjectKind.GroupVersionKind() { + if v, ok := obj.(schema.ObjectKind); ok { + v.SetGroupVersionKind(gvk) + } + } +} + +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *client) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return apiutil.GVKForObject(obj, c.scheme) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *client) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return apiutil.IsObjectNamespaced(obj, c.scheme, c.mapper) +} + +// Scheme returns the scheme this client is using. +func (c *client) Scheme() *runtime.Scheme { + return c.scheme +} + +// RESTMapper returns the scheme this client is using. +func (c *client) RESTMapper() meta.RESTMapper { + return c.mapper +} + +// Create implements client.Client. +func (c *client) Create(ctx context.Context, obj Object, opts ...CreateOption) error { + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.Create(ctx, obj, opts...) + case *metav1.PartialObjectMetadata: + return fmt.Errorf("cannot create using only metadata") + default: + return c.typedClient.Create(ctx, obj, opts...) + } +} + +// Update implements client.Client. +func (c *client) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { + defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.Update(ctx, obj, opts...) + case *metav1.PartialObjectMetadata: + return fmt.Errorf("cannot update using only metadata -- did you mean to patch?") + default: + return c.typedClient.Update(ctx, obj, opts...) + } +} + +// Delete implements client.Client. +func (c *client) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.Delete(ctx, obj, opts...) + case *metav1.PartialObjectMetadata: + return c.metadataClient.Delete(ctx, obj, opts...) + default: + return c.typedClient.Delete(ctx, obj, opts...) + } +} + +// DeleteAllOf implements client.Client. +func (c *client) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.DeleteAllOf(ctx, obj, opts...) + case *metav1.PartialObjectMetadata: + return c.metadataClient.DeleteAllOf(ctx, obj, opts...) + default: + return c.typedClient.DeleteAllOf(ctx, obj, opts...) + } +} + +// Patch implements client.Client. +func (c *client) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.Patch(ctx, obj, patch, opts...) + case *metav1.PartialObjectMetadata: + return c.metadataClient.Patch(ctx, obj, patch, opts...) + default: + return c.typedClient.Patch(ctx, obj, patch, opts...) + } +} + +// Get implements client.Client. +func (c *client) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + if isUncached, err := c.shouldBypassCache(obj); err != nil { + return err + } else if !isUncached { + return c.cache.Get(ctx, key, obj, opts...) + } + + switch obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.Get(ctx, key, obj, opts...) + case *metav1.PartialObjectMetadata: + // Metadata only object should always preserve the GVK coming in from the caller. + defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + return c.metadataClient.Get(ctx, key, obj, opts...) + default: + return c.typedClient.Get(ctx, key, obj, opts...) + } +} + +// List implements client.Client. +func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + if isUncached, err := c.shouldBypassCache(obj); err != nil { + return err + } else if !isUncached { + return c.cache.List(ctx, obj, opts...) + } + + switch x := obj.(type) { + case runtime.Unstructured: + return c.unstructuredClient.List(ctx, obj, opts...) + case *metav1.PartialObjectMetadataList: + // Metadata only object should always preserve the GVK. + gvk := obj.GetObjectKind().GroupVersionKind() + defer c.resetGroupVersionKind(obj, gvk) + + // Call the list client. + if err := c.metadataClient.List(ctx, obj, opts...); err != nil { + return err + } + + // Restore the GVK for each item in the list. + itemGVK := schema.GroupVersionKind{ + Group: gvk.Group, + Version: gvk.Version, + // TODO: this is producing unsafe guesses that don't actually work, + // but it matches ~99% of the cases out there. + Kind: strings.TrimSuffix(gvk.Kind, "List"), + } + for i := range x.Items { + item := &x.Items[i] + item.SetGroupVersionKind(itemGVK) + } + + return nil + default: + return c.typedClient.List(ctx, obj, opts...) + } +} + +// Status implements client.StatusClient. +func (c *client) Status() SubResourceWriter { + return c.SubResource("status") +} + +func (c *client) SubResource(subResource string) SubResourceClient { + return &subResourceClient{client: c, subResource: subResource} +} + +// subResourceClient is client.SubResourceWriter that writes to subresources. +type subResourceClient struct { + client *client + subResource string +} + +// ensure subResourceClient implements client.SubResourceClient. +var _ SubResourceClient = &subResourceClient{} + +// SubResourceGetOptions holds all the possible configuration +// for a subresource Get request. +type SubResourceGetOptions struct { + Raw *metav1.GetOptions +} + +// ApplyToSubResourceGet updates the configuaration to the given get options. +func (getOpt *SubResourceGetOptions) ApplyToSubResourceGet(o *SubResourceGetOptions) { + if getOpt.Raw != nil { + o.Raw = getOpt.Raw + } +} + +// ApplyOptions applues the given options. +func (getOpt *SubResourceGetOptions) ApplyOptions(opts []SubResourceGetOption) *SubResourceGetOptions { + for _, o := range opts { + o.ApplyToSubResourceGet(getOpt) + } + + return getOpt +} + +// AsGetOptions returns the configured options as *metav1.GetOptions. +func (getOpt *SubResourceGetOptions) AsGetOptions() *metav1.GetOptions { + if getOpt.Raw == nil { + return &metav1.GetOptions{} + } + return getOpt.Raw +} + +// SubResourceUpdateOptions holds all the possible configuration +// for a subresource update request. +type SubResourceUpdateOptions struct { + UpdateOptions + SubResourceBody Object +} + +// ApplyToSubResourceUpdate updates the configuration on the given create options +func (uo *SubResourceUpdateOptions) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) { + uo.UpdateOptions.ApplyToUpdate(&o.UpdateOptions) + if uo.SubResourceBody != nil { + o.SubResourceBody = uo.SubResourceBody + } +} + +// ApplyOptions applies the given options. +func (uo *SubResourceUpdateOptions) ApplyOptions(opts []SubResourceUpdateOption) *SubResourceUpdateOptions { + for _, o := range opts { + o.ApplyToSubResourceUpdate(uo) + } + + return uo +} + +// SubResourceUpdateAndPatchOption is an option that can be used for either +// a subresource update or patch request. +type SubResourceUpdateAndPatchOption interface { + SubResourceUpdateOption + SubResourcePatchOption +} + +// WithSubResourceBody returns an option that uses the given body +// for a subresource Update or Patch operation. +func WithSubResourceBody(body Object) SubResourceUpdateAndPatchOption { + return &withSubresourceBody{body: body} +} + +type withSubresourceBody struct { + body Object +} + +func (wsr *withSubresourceBody) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) { + o.SubResourceBody = wsr.body +} + +func (wsr *withSubresourceBody) ApplyToSubResourcePatch(o *SubResourcePatchOptions) { + o.SubResourceBody = wsr.body +} + +// SubResourceCreateOptions are all the possible configurations for a subresource +// create request. +type SubResourceCreateOptions struct { + CreateOptions +} + +// ApplyOptions applies the given options. +func (co *SubResourceCreateOptions) ApplyOptions(opts []SubResourceCreateOption) *SubResourceCreateOptions { + for _, o := range opts { + o.ApplyToSubResourceCreate(co) + } + + return co +} + +// ApplyToSubresourceCreate applies the the configuration on the given create options. +func (co *SubResourceCreateOptions) ApplyToSubresourceCreate(o *SubResourceCreateOptions) { + co.CreateOptions.ApplyToCreate(&co.CreateOptions) +} + +// SubResourcePatchOptions holds all possible configurations for a subresource patch +// request. +type SubResourcePatchOptions struct { + PatchOptions + SubResourceBody Object +} + +// ApplyOptions applies the given options. +func (po *SubResourcePatchOptions) ApplyOptions(opts []SubResourcePatchOption) *SubResourcePatchOptions { + for _, o := range opts { + o.ApplyToSubResourcePatch(po) + } + + return po +} + +// ApplyToSubResourcePatch applies the configuration on the given patch options. +func (po *SubResourcePatchOptions) ApplyToSubResourcePatch(o *SubResourcePatchOptions) { + po.PatchOptions.ApplyToPatch(&o.PatchOptions) + if po.SubResourceBody != nil { + o.SubResourceBody = po.SubResourceBody + } +} + +func (sc *subResourceClient) Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error { + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...) + case *metav1.PartialObjectMetadata: + return errors.New("can not get subresource using only metadata") + default: + return sc.client.typedClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...) + } +} + +// Create implements client.SubResourceClient +func (sc *subResourceClient) Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + defer sc.client.resetGroupVersionKind(subResource, subResource.GetObjectKind().GroupVersionKind()) + + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...) + case *metav1.PartialObjectMetadata: + return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?") + default: + return sc.client.typedClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...) + } +} + +// Update implements client.SubResourceClient +func (sc *subResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.UpdateSubResource(ctx, obj, sc.subResource, opts...) + case *metav1.PartialObjectMetadata: + return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?") + default: + return sc.client.typedClient.UpdateSubResource(ctx, obj, sc.subResource, opts...) + } +} + +// Patch implements client.SubResourceWriter. +func (sc *subResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) + case *metav1.PartialObjectMetadata: + return sc.client.metadataClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) + default: + return sc.client.typedClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go new file mode 100644 index 00000000000..2d07879520b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go @@ -0,0 +1,151 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "net/http" + "strings" + "sync" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// clientRestResources creates and stores rest clients and metadata for Kubernetes types. +type clientRestResources struct { + // httpClient is the http client to use for requests + httpClient *http.Client + + // config is the rest.Config to talk to an apiserver + config *rest.Config + + // scheme maps go structs to GroupVersionKinds + scheme *runtime.Scheme + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper + + // codecs are used to create a REST client for a gvk + codecs serializer.CodecFactory + + // structuredResourceByType stores structured type metadata + structuredResourceByType map[schema.GroupVersionKind]*resourceMeta + // unstructuredResourceByType stores unstructured type metadata + unstructuredResourceByType map[schema.GroupVersionKind]*resourceMeta + mu sync.RWMutex +} + +// newResource maps obj to a Kubernetes Resource and constructs a client for that Resource. +// If the object is a list, the resource represents the item's type instead. +func (c *clientRestResources) newResource(gvk schema.GroupVersionKind, isList, isUnstructured bool) (*resourceMeta, error) { + if strings.HasSuffix(gvk.Kind, "List") && isList { + // if this was a list, treat it as a request for the item's resource + gvk.Kind = gvk.Kind[:len(gvk.Kind)-4] + } + + client, err := apiutil.RESTClientForGVK(gvk, isUnstructured, c.config, c.codecs, c.httpClient) + if err != nil { + return nil, err + } + mapping, err := c.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + return &resourceMeta{Interface: client, mapping: mapping, gvk: gvk}, nil +} + +// getResource returns the resource meta information for the given type of object. +// If the object is a list, the resource represents the item's type instead. +func (c *clientRestResources) getResource(obj runtime.Object) (*resourceMeta, error) { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return nil, err + } + + _, isUnstructured := obj.(runtime.Unstructured) + + // It's better to do creation work twice than to not let multiple + // people make requests at once + c.mu.RLock() + resourceByType := c.structuredResourceByType + if isUnstructured { + resourceByType = c.unstructuredResourceByType + } + r, known := resourceByType[gvk] + c.mu.RUnlock() + + if known { + return r, nil + } + + // Initialize a new Client + c.mu.Lock() + defer c.mu.Unlock() + r, err = c.newResource(gvk, meta.IsListType(obj), isUnstructured) + if err != nil { + return nil, err + } + resourceByType[gvk] = r + return r, err +} + +// getObjMeta returns objMeta containing both type and object metadata and state. +func (c *clientRestResources) getObjMeta(obj runtime.Object) (*objMeta, error) { + r, err := c.getResource(obj) + if err != nil { + return nil, err + } + m, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + return &objMeta{resourceMeta: r, Object: m}, err +} + +// resourceMeta stores state for a Kubernetes type. +type resourceMeta struct { + // client is the rest client used to talk to the apiserver + rest.Interface + // gvk is the GroupVersionKind of the resourceMeta + gvk schema.GroupVersionKind + // mapping is the rest mapping + mapping *meta.RESTMapping +} + +// isNamespaced returns true if the type is namespaced. +func (r *resourceMeta) isNamespaced() bool { + return r.mapping.Scope.Name() != meta.RESTScopeNameRoot +} + +// resource returns the resource name of the type. +func (r *resourceMeta) resource() string { + return r.mapping.Resource.Resource +} + +// objMeta stores type and object information about a Kubernetes type. +type objMeta struct { + // resourceMeta contains type information for the object + *resourceMeta + + // Object contains meta data for the object instance + metav1.Object +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_suite_test.go new file mode 100644 index 00000000000..f3942502d3f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_suite_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/examples/crd/pkg" + "sigs.k8s.io/controller-runtime/pkg/envtest" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestClient(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Client Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var clientset *kubernetes.Clientset + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{CRDDirectoryPaths: []string{"./testdata"}} + + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) + + Expect(pkg.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_test.go new file mode 100644 index 00000000000..bd368e7a3fd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/client_test.go @@ -0,0 +1,3952 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "sync/atomic" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + authenticationv1 "k8s.io/api/authentication/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + certificatesv1 "k8s.io/api/certificates/v1" + corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + kscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/examples/crd/pkg" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func deleteDeployment(ctx context.Context, dep *appsv1.Deployment, ns string) { + _, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + if err == nil { + err = clientset.AppsV1().Deployments(ns).Delete(ctx, dep.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + } +} + +func deleteNamespace(ctx context.Context, ns *corev1.Namespace) { + ns, err := clientset.CoreV1().Namespaces().Get(ctx, ns.Name, metav1.GetOptions{}) + if err != nil { + return + } + + err = clientset.CoreV1().Namespaces().Delete(ctx, ns.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + + // finalize if necessary + pos := -1 + finalizers := ns.Spec.Finalizers + for i, fin := range finalizers { + if fin == "kubernetes" { + pos = i + break + } + } + if pos == -1 { + // no need to finalize + return + } + + // re-get in order to finalize + ns, err = clientset.CoreV1().Namespaces().Get(ctx, ns.Name, metav1.GetOptions{}) + if err != nil { + return + } + + ns.Spec.Finalizers = append(finalizers[:pos], finalizers[pos+1:]...) + _, err = clientset.CoreV1().Namespaces().Finalize(ctx, ns, metav1.UpdateOptions{}) + Expect(err).NotTo(HaveOccurred()) + +WAIT_LOOP: + for i := 0; i < 10; i++ { + ns, err = clientset.CoreV1().Namespaces().Get(ctx, ns.Name, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + // success! + return + } + select { + case <-ctx.Done(): + break WAIT_LOOP + // failed to delete in time, see failure below + case <-time.After(100 * time.Millisecond): + // do nothing, try again + } + } + Fail(fmt.Sprintf("timed out waiting for namespace %q to be deleted", ns.Name)) +} + +type mockPatchOption struct { + applied bool +} + +func (o *mockPatchOption) ApplyToPatch(_ *client.PatchOptions) { + o.applied = true +} + +// metaOnlyFromObj returns PartialObjectMetadata from a concrete Go struct that +// returns a concrete *metav1.ObjectMeta from GetObjectMeta (yes, that plays a +// bit fast and loose, but the only other options are serializing and then +// deserializing, or manually calling all the accessor funcs, which are both a bit annoying). +func metaOnlyFromObj(obj interface { + runtime.Object + metav1.ObjectMetaAccessor +}, scheme *runtime.Scheme) *metav1.PartialObjectMetadata { + metaObj := metav1.PartialObjectMetadata{} + obj.GetObjectMeta().(*metav1.ObjectMeta).DeepCopyInto(&metaObj.ObjectMeta) + kinds, _, err := scheme.ObjectKinds(obj) + if err != nil { + panic(err) + } + metaObj.SetGroupVersionKind(kinds[0]) + return &metaObj +} + +var _ = Describe("Client", func() { + + var scheme *runtime.Scheme + var depGvk schema.GroupVersionKind + var dep *appsv1.Deployment + var pod *corev1.Pod + var node *corev1.Node + var serviceAccount *corev1.ServiceAccount + var csr *certificatesv1.CertificateSigningRequest + var count uint64 = 0 + var replicaCount int32 = 2 + var ns = "default" + ctx := context.TODO() + + BeforeEach(func() { + atomic.AddUint64(&count, 1) + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("deployment-name-%v", count), Namespace: ns, Labels: map[string]string{"app": fmt.Sprintf("bar-%v", count)}}, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depGvk = schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + } + // Pod is invalid without a container field in the PodSpec + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("pod-%v", count), Namespace: ns}, + Spec: corev1.PodSpec{}, + } + node = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("node-name-%v", count)}, + Spec: corev1.NodeSpec{}, + } + serviceAccount = &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("sa-%v", count), Namespace: ns}} + csr = &certificatesv1.CertificateSigningRequest{ + ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("csr-%v", count)}, + Spec: certificatesv1.CertificateSigningRequestSpec{ + SignerName: "org.io/my-signer", + Request: []byte(`-----BEGIN CERTIFICATE REQUEST----- +MIIChzCCAW8CAQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0 +eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANe06dLX/bDNm6mVEnKdJexcJM6WKMFSt5o6BEdD1+Ki +WyUcvfNgIBbwAZjkF9U1r7+KuDcc6XYFnb6ky1wPo4C+XwcIIx7Nnbf8IdWJukPb +2BCsqO4NCsG6kKFavmH9J3q//nwKUvlQE+AJ2MPuOAZTwZ4KskghiGuS8hyk6/PZ +XH9QhV7Jma43bDzQozd2C7OujRBhLsuP94KSu839RRFWd9ms3XHgTxLxb7nxwZDx +9l7/ZVAObJoQYlHENqs12NCVP4gpJfbcY8/rd+IG4ftcZEmpeO4kKO+d2TpRKQqw +bjCMoAdD5Y43iLTtyql4qRnbMe3nxYG2+1inEryuV/cCAwEAAaAAMA0GCSqGSIb3 +DQEBCwUAA4IBAQDH5hDByRN7wERQtC/o6uc8Y+yhjq9YcBJjjbnD6Vwru5pOdWtx +qfKkkXI5KNOdEhWzLnJyOcWHjj8UoHqI3AjxGC7dTM95eGjxQGUpsUOX8JSd4MiZ +cct4g4BKBj02AGqZLiEgN+PLCYAmEaYU7oZc4OAh6WzMrljNRsj66awMQpw8O1eY +YuBa8vwz8ko8vn/pn7IrFu8cZ+EA3rluJ+budX/QrEGi1hijg27q7/Qr0wNI9f1v +086mLKdqaBTkblXWEvF3WP4CcLNyrSNi4eu+G0fcAgGp1F/Nqh0MuWKSOLprv5Om +U5wwSivyi7vmegHKmblOzNVKA5qPO8zWzqBC +-----END CERTIFICATE REQUEST-----`), + Usages: []certificatesv1.KeyUsage{certificatesv1.UsageClientAuth}, + }, + } + scheme = kscheme.Scheme + }) + + var delOptions *metav1.DeleteOptions + AfterEach(func() { + // Cleanup + var zero int64 = 0 + policy := metav1.DeletePropagationForeground + delOptions = &metav1.DeleteOptions{ + GracePeriodSeconds: &zero, + PropagationPolicy: &policy, + } + deleteDeployment(ctx, dep, ns) + _, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + if err == nil { + err = clientset.CoreV1().Nodes().Delete(ctx, node.Name, *delOptions) + Expect(err).NotTo(HaveOccurred()) + } + err = clientset.CoreV1().ServiceAccounts(ns).Delete(ctx, serviceAccount.Name, *delOptions) + Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred()) + + err = clientset.CertificatesV1().CertificateSigningRequests().Delete(ctx, csr.Name, *delOptions) + Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred()) + }) + + Describe("New", func() { + It("should return a new Client", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + }) + + It("should fail if the config is nil", func() { + cl, err := client.New(nil, client.Options{}) + Expect(err).To(HaveOccurred()) + Expect(cl).To(BeNil()) + }) + + It("should use the provided Scheme if provided", func() { + cl, err := client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.Scheme()).ToNot(BeNil()) + Expect(cl.Scheme()).To(Equal(scheme)) + }) + + It("should default the Scheme if not provided", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.Scheme()).ToNot(BeNil()) + Expect(cl.Scheme()).To(Equal(kscheme.Scheme)) + }) + + It("should use the provided Mapper if provided", func() { + mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{}) + cl, err := client.New(cfg, client.Options{Mapper: mapper}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.RESTMapper()).ToNot(BeNil()) + Expect(cl.RESTMapper()).To(Equal(mapper)) + }) + + It("should create a Mapper if not provided", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.RESTMapper()).ToNot(BeNil()) + }) + + It("should use the provided reader cache if provided, on get and list", func() { + cache := &fakeReader{} + cl, err := client.New(cfg, client.Options{Cache: &client.CacheOptions{Reader: cache}}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.Get(ctx, client.ObjectKey{Name: "test"}, &appsv1.Deployment{})).To(Succeed()) + Expect(cl.List(ctx, &appsv1.DeploymentList{})).To(Succeed()) + Expect(cache.Called).To(Equal(2)) + }) + + It("should not use the provided reader cache if provided, on get and list for uncached GVKs", func() { + cache := &fakeReader{} + cl, err := client.New(cfg, client.Options{Cache: &client.CacheOptions{Reader: cache, DisableFor: []client.Object{&corev1.Namespace{}}}}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + Expect(cl.Get(ctx, client.ObjectKey{Name: "default"}, &corev1.Namespace{})).To(Succeed()) + Expect(cl.List(ctx, &corev1.NamespaceList{})).To(Succeed()) + Expect(cache.Called).To(Equal(0)) + }) + }) + + Describe("Create", func() { + Context("with structured objects", func() { + It("should create a new object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the object") + err = cl.Create(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("writing the result back to the go struct") + Expect(dep).To(Equal(actual)) + }) + + It("should create a new object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the object") + err = cl.Create(context.TODO(), node) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("writing the result back to the go struct") + Expect(node).To(Equal(actual)) + }) + + It("should fail if the object already exists", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + old := dep.DeepCopy() + + By("creating the object") + err = cl.Create(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("creating the object a second time") + err = cl.Create(context.TODO(), old) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsAlreadyExists(err)).To(BeTrue()) + }) + + It("should fail if the object does not pass server-side validation", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the pod, since required field Containers is empty") + err = cl.Create(context.TODO(), pod) + Expect(err).To(HaveOccurred()) + // TODO(seans): Add test to validate the returned error. Problems currently with + // different returned error locally versus travis. + }) + + It("should fail if the object cannot be mapped to a GVK", func() { + By("creating client with empty Scheme") + emptyScheme := runtime.NewScheme() + cl, err := client.New(cfg, client.Options{Scheme: emptyScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the object fails") + err = cl.Create(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no kind is registered for the type")) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + // TODO(seans3): implement these + // Example: ListOptions + }) + + Context("with the DryRun option", func() { + It("should not create a new object, global option", func() { + cl, err := client.New(cfg, client.Options{DryRun: pointer.Bool(true)}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the object (with DryRun)") + err = cl.Create(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + Expect(actual).To(Equal(&appsv1.Deployment{})) + }) + + It("should not create a new object, inline option", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the object (with DryRun)") + err = cl.Create(context.TODO(), dep, client.DryRunAll) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + Expect(actual).To(Equal(&appsv1.Deployment{})) + }) + }) + }) + + Context("with unstructured objects", func() { + It("should create a new object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("encoding the deployment as unstructured") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + + By("creating the object") + err = cl.Create(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + }) + + It("should create a new non-namespace object ", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("encoding the deployment as unstructured") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Kind: "Node", + Version: "v1", + }) + + By("creating the object") + err = cl.Create(context.TODO(), node) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + au := &unstructured.Unstructured{} + Expect(scheme.Convert(actual, au, nil)).To(Succeed()) + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + By("writing the result back to the go struct") + + Expect(u).To(Equal(au)) + }) + + It("should fail if the object already exists", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + old := dep.DeepCopy() + + By("creating the object") + err = cl.Create(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("encoding the deployment as unstructured") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(old, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + + By("creating the object a second time") + err = cl.Create(context.TODO(), u) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsAlreadyExists(err)).To(BeTrue()) + }) + + It("should fail if the object does not pass server-side validation", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("creating the pod, since required field Containers is empty") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(pod, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + }) + err = cl.Create(context.TODO(), u) + Expect(err).To(HaveOccurred()) + // TODO(seans): Add test to validate the returned error. Problems currently with + // different returned error locally versus travis. + }) + + }) + + Context("with metadata objects", func() { + It("should fail with an error", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + obj := metaOnlyFromObj(dep, scheme) + Expect(cl.Create(context.TODO(), obj)).NotTo(Succeed()) + }) + }) + + Context("with the DryRun option", func() { + It("should not create a new object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("encoding the deployment as unstructured") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + + By("creating the object") + err = cl.Create(context.TODO(), u, client.DryRunAll) + Expect(err).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + Expect(actual).To(Equal(&appsv1.Deployment{})) + }) + }) + }) + + Describe("Update", func() { + Context("with structured objects", func() { + It("should update an existing object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the Deployment") + dep.Annotations = map[string]string{"foo": "bar"} + err = cl.Update(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new annotation") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + + It("should update and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the Deployment") + dep.SetGroupVersionKind(depGvk) + err = cl.Update(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(dep.GroupVersionKind()).To(Equal(depGvk)) + }) + + It("should update an existing object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the object") + node.Annotations = map[string]string{"foo": "bar"} + err = cl.Update(context.TODO(), node) + Expect(err).NotTo(HaveOccurred()) + + By("validate updated Node had new annotation") + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("updating non-existent object") + err = cl.Update(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + }) + + PIt("should fail if the object does not pass server-side validation", func() { + + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + It("should fail if the object cannot be mapped to a GVK", func() { + By("creating client with empty Scheme") + emptyScheme := runtime.NewScheme() + cl, err := client.New(cfg, client.Options{Scheme: emptyScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the Deployment") + dep.Annotations = map[string]string{"foo": "bar"} + err = cl.Update(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no kind is registered for the type")) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + }) + Context("with unstructured objects", func() { + It("should update an existing object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the Deployment") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + u.SetAnnotations(map[string]string{"foo": "bar"}) + err = cl.Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new annotation") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + + It("should update and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the Deployment") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(depGvk) + u.SetAnnotations(map[string]string{"foo": "bar"}) + err = cl.Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(u.GroupVersionKind()).To(Equal(depGvk)) + }) + + It("should update an existing object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the object") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Kind: "Node", + Version: "v1", + }) + u.SetAnnotations(map[string]string{"foo": "bar"}) + err = cl.Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validate updated Node had new annotation") + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("updating non-existent object") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(depGvk) + err = cl.Update(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + }) + }) + Context("with metadata objects", func() { + It("should fail with an error", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + obj := metaOnlyFromObj(dep, scheme) + + Expect(cl.Update(context.TODO(), obj)).NotTo(Succeed()) + }) + }) + }) + + Describe("Patch", func() { + Context("Metadata Client", func() { + It("should merge patch with options", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + metadata := metaOnlyFromObj(dep, scheme) + if metadata.Labels == nil { + metadata.Labels = make(map[string]string) + } + metadata.Labels["foo"] = "bar" + + testOption := &mockPatchOption{} + Expect(cl.Patch(context.TODO(), metadata, client.Merge, testOption)).To(Succeed()) + + By("validating that patched metadata has new labels") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Labels["foo"]).To(Equal("bar")) + + By("validating patch options were applied") + Expect(testOption.applied).To(Equal(true)) + }) + }) + }) + + Describe("SubResourceClient", func() { + Context("with structured objects", func() { + It("should be able to read the Scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("reading the scale subresource") + scale := &autoscalingv1.Scale{} + err = cl.SubResource("scale").Get(ctx, dep, scale) + Expect(err).NotTo(HaveOccurred()) + Expect(scale.Spec.Replicas).To(Equal(*dep.Spec.Replicas)) + }) + It("should be able to create ServiceAccount tokens", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the serviceAccount") + _, err = clientset.CoreV1().ServiceAccounts(serviceAccount.Namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) + Expect((err)).NotTo(HaveOccurred()) + + token := &authenticationv1.TokenRequest{} + err = cl.SubResource("token").Create(ctx, serviceAccount, token) + Expect(err).NotTo(HaveOccurred()) + + Expect(token.Status.Token).NotTo(Equal("")) + }) + + It("should be able to create Pod evictions", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + // Make the pod valid + pod.Spec.Containers = []corev1.Container{{Name: "foo", Image: "busybox"}} + + By("Creating the pod") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the eviction") + eviction := &policyv1.Eviction{ + DeleteOptions: &metav1.DeleteOptions{GracePeriodSeconds: ptr(int64(0))}, + } + err = cl.SubResource("eviction").Create(ctx, pod, eviction) + Expect((err)).NotTo(HaveOccurred()) + + By("Asserting the pod is gone") + _, err = clientset.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should be able to create Pod bindings", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + // Make the pod valid + pod.Spec.Containers = []corev1.Container{{Name: "foo", Image: "busybox"}} + + By("Creating the pod") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the binding") + binding := &corev1.Binding{ + Target: corev1.ObjectReference{Name: node.Name}, + } + err = cl.SubResource("binding").Create(ctx, pod, binding) + Expect((err)).NotTo(HaveOccurred()) + + By("Asserting the pod is bound") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(pod.Spec.NodeName).To(Equal(node.Name)) + }) + + It("should be able to approve CSRs", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the CSR") + csr, err := clientset.CertificatesV1().CertificateSigningRequests().Create(ctx, csr, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Approving the CSR") + csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1.CertificateSigningRequestCondition{ + Type: certificatesv1.CertificateApproved, + Status: corev1.ConditionTrue, + }) + err = cl.SubResource("approval").Update(ctx, csr) + Expect(err).NotTo(HaveOccurred()) + + By("Asserting the CSR is approved") + csr, err = clientset.CertificatesV1().CertificateSigningRequests().Get(ctx, csr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(csr.Status.Conditions[0].Type).To(Equal(certificatesv1.CertificateApproved)) + Expect(csr.Status.Conditions[0].Status).To(Equal(corev1.ConditionTrue)) + }) + + It("should be able to approve CSRs using Patch", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the CSR") + csr, err := clientset.CertificatesV1().CertificateSigningRequests().Create(ctx, csr, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Approving the CSR") + patch := client.MergeFrom(csr.DeepCopy()) + csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1.CertificateSigningRequestCondition{ + Type: certificatesv1.CertificateApproved, + Status: corev1.ConditionTrue, + }) + err = cl.SubResource("approval").Patch(ctx, csr, patch) + Expect(err).NotTo(HaveOccurred()) + + By("Asserting the CSR is approved") + csr, err = clientset.CertificatesV1().CertificateSigningRequests().Get(ctx, csr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(csr.Status.Conditions[0].Type).To(Equal(certificatesv1.CertificateApproved)) + Expect(csr.Status.Conditions[0].Status).To(Equal(corev1.ConditionTrue)) + }) + + It("should be able to update the scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Updating the scale subresurce") + replicaCount := *dep.Spec.Replicas + scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: replicaCount}} + err = cl.SubResource("scale").Update(ctx, dep, client.WithSubResourceBody(scale)) + Expect(err).NotTo(HaveOccurred()) + + By("Asserting replicas got updated") + dep, err = clientset.AppsV1().Deployments(dep.Namespace).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(*dep.Spec.Replicas).To(Equal(replicaCount)) + }) + + It("should be able to patch the scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Updating the scale subresurce") + replicaCount := *dep.Spec.Replicas + patch := client.MergeFrom(&autoscalingv1.Scale{}) + scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: replicaCount}} + err = cl.SubResource("scale").Patch(ctx, dep, patch, client.WithSubResourceBody(scale)) + Expect(err).NotTo(HaveOccurred()) + + By("Asserting replicas got updated") + dep, err = clientset.AppsV1().Deployments(dep.Namespace).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(*dep.Spec.Replicas).To(Equal(replicaCount)) + }) + }) + + Context("with unstructured objects", func() { + It("should be able to read the Scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep.APIVersion = appsv1.SchemeGroupVersion.String() + dep.Kind = reflect.TypeOf(dep).Elem().Name() + depUnstructured, err := toUnstructured(dep) + Expect(err).NotTo(HaveOccurred()) + + By("reading the scale subresource") + scale := &unstructured.Unstructured{} + scale.SetAPIVersion("autoscaling/v1") + scale.SetKind("Scale") + err = cl.SubResource("scale").Get(ctx, depUnstructured, scale) + Expect(err).NotTo(HaveOccurred()) + + val, found, err := unstructured.NestedInt64(scale.UnstructuredContent(), "spec", "replicas") + Expect(err).NotTo(HaveOccurred()) + Expect(found).To(BeTrue()) + Expect(int32(val)).To(Equal(*dep.Spec.Replicas)) + }) + It("should be able to create ServiceAccount tokens", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the serviceAccount") + _, err = clientset.CoreV1().ServiceAccounts(serviceAccount.Namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) + Expect((err)).NotTo(HaveOccurred()) + + serviceAccount.APIVersion = "v1" + serviceAccount.Kind = "ServiceAccount" + serviceAccountUnstructured, err := toUnstructured(serviceAccount) + Expect(err).NotTo(HaveOccurred()) + + token := &unstructured.Unstructured{} + token.SetAPIVersion("authentication.k8s.io/v1") + token.SetKind("TokenRequest") + err = cl.SubResource("token").Create(ctx, serviceAccountUnstructured, token) + Expect(err).NotTo(HaveOccurred()) + Expect(token.GetAPIVersion()).To(Equal("authentication.k8s.io/v1")) + Expect(token.GetKind()).To(Equal("TokenRequest")) + + val, found, err := unstructured.NestedString(token.UnstructuredContent(), "status", "token") + Expect(err).NotTo(HaveOccurred()) + Expect(found).To(BeTrue()) + Expect(val).NotTo(Equal("")) + }) + + It("should be able to create Pod evictions", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + // Make the pod valid + pod.Spec.Containers = []corev1.Container{{Name: "foo", Image: "busybox"}} + + By("Creating the pod") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + pod.APIVersion = "v1" + pod.Kind = "Pod" + podUnstructured, err := toUnstructured(pod) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the eviction") + eviction := &unstructured.Unstructured{} + eviction.SetAPIVersion("policy/v1") + eviction.SetKind("Eviction") + err = unstructured.SetNestedField(eviction.UnstructuredContent(), int64(0), "deleteOptions", "gracePeriodSeconds") + Expect(err).NotTo(HaveOccurred()) + err = cl.SubResource("eviction").Create(ctx, podUnstructured, eviction) + Expect(err).NotTo(HaveOccurred()) + Expect(eviction.GetAPIVersion()).To(Equal("policy/v1")) + Expect(eviction.GetKind()).To(Equal("Eviction")) + + By("Asserting the pod is gone") + _, err = clientset.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should be able to create Pod bindings", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + // Make the pod valid + pod.Spec.Containers = []corev1.Container{{Name: "foo", Image: "busybox"}} + + By("Creating the pod") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + pod.APIVersion = "v1" + pod.Kind = "Pod" + podUnstructured, err := toUnstructured(pod) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the binding") + binding := &unstructured.Unstructured{} + binding.SetAPIVersion("v1") + binding.SetKind("Binding") + err = unstructured.SetNestedField(binding.UnstructuredContent(), node.Name, "target", "name") + Expect(err).NotTo(HaveOccurred()) + + err = cl.SubResource("binding").Create(ctx, podUnstructured, binding) + Expect((err)).NotTo(HaveOccurred()) + Expect(binding.GetAPIVersion()).To(Equal("v1")) + Expect(binding.GetKind()).To(Equal("Binding")) + + By("Asserting the pod is bound") + pod, err = clientset.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(pod.Spec.NodeName).To(Equal(node.Name)) + }) + + It("should be able to approve CSRs", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the CSR") + csr, err := clientset.CertificatesV1().CertificateSigningRequests().Create(ctx, csr, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Approving the CSR") + csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1.CertificateSigningRequestCondition{ + Type: certificatesv1.CertificateApproved, + Status: corev1.ConditionTrue, + }) + csr.APIVersion = "certificates.k8s.io/v1" + csr.Kind = "CertificateSigningRequest" + csrUnstructured, err := toUnstructured(csr) + Expect(err).NotTo(HaveOccurred()) + + err = cl.SubResource("approval").Update(ctx, csrUnstructured) + Expect(err).NotTo(HaveOccurred()) + Expect(csrUnstructured.GetAPIVersion()).To(Equal("certificates.k8s.io/v1")) + Expect(csrUnstructured.GetKind()).To(Equal("CertificateSigningRequest")) + + By("Asserting the CSR is approved") + csr, err = clientset.CertificatesV1().CertificateSigningRequests().Get(ctx, csr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(csr.Status.Conditions[0].Type).To(Equal(certificatesv1.CertificateApproved)) + Expect(csr.Status.Conditions[0].Status).To(Equal(corev1.ConditionTrue)) + }) + + It("should be able to approve CSRs using Patch", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating the CSR") + csr, err := clientset.CertificatesV1().CertificateSigningRequests().Create(ctx, csr, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Approving the CSR") + patch := client.MergeFrom(csr.DeepCopy()) + csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1.CertificateSigningRequestCondition{ + Type: certificatesv1.CertificateApproved, + Status: corev1.ConditionTrue, + }) + csr.APIVersion = "certificates.k8s.io/v1" + csr.Kind = "CertificateSigningRequest" + csrUnstructured, err := toUnstructured(csr) + Expect(err).NotTo(HaveOccurred()) + + err = cl.SubResource("approval").Patch(ctx, csrUnstructured, patch) + Expect(err).NotTo(HaveOccurred()) + Expect(csrUnstructured.GetAPIVersion()).To(Equal("certificates.k8s.io/v1")) + Expect(csrUnstructured.GetKind()).To(Equal("CertificateSigningRequest")) + + By("Asserting the CSR is approved") + csr, err = clientset.CertificatesV1().CertificateSigningRequests().Get(ctx, csr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(csr.Status.Conditions[0].Type).To(Equal(certificatesv1.CertificateApproved)) + Expect(csr.Status.Conditions[0].Status).To(Equal(corev1.ConditionTrue)) + }) + + It("should be able to update the scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep.APIVersion = "apps/v1" + dep.Kind = "Deployment" + depUnstructured, err := toUnstructured(dep) + Expect(err).NotTo(HaveOccurred()) + + By("Updating the scale subresurce") + replicaCount := *dep.Spec.Replicas + scale := &unstructured.Unstructured{} + scale.SetAPIVersion("autoscaling/v1") + scale.SetKind("Scale") + Expect(unstructured.SetNestedField(scale.Object, int64(replicaCount), "spec", "replicas")).NotTo(HaveOccurred()) + err = cl.SubResource("scale").Update(ctx, depUnstructured, client.WithSubResourceBody(scale)) + Expect(err).NotTo(HaveOccurred()) + Expect(scale.GetAPIVersion()).To(Equal("autoscaling/v1")) + Expect(scale.GetKind()).To(Equal("Scale")) + + By("Asserting replicas got updated") + dep, err = clientset.AppsV1().Deployments(dep.Namespace).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(*dep.Spec.Replicas).To(Equal(replicaCount)) + }) + + It("should be able to patch the scale subresource", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Creating a deployment") + dep, err := clientset.AppsV1().Deployments(dep.Namespace).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep.APIVersion = "apps/v1" + dep.Kind = "Deployment" + depUnstructured, err := toUnstructured(dep) + Expect(err).NotTo(HaveOccurred()) + + By("Updating the scale subresurce") + replicaCount := *dep.Spec.Replicas + scale := &unstructured.Unstructured{} + scale.SetAPIVersion("autoscaling/v1") + scale.SetKind("Scale") + patch := client.MergeFrom(scale.DeepCopy()) + Expect(unstructured.SetNestedField(scale.Object, int64(replicaCount), "spec", "replicas")).NotTo(HaveOccurred()) + err = cl.SubResource("scale").Patch(ctx, depUnstructured, patch, client.WithSubResourceBody(scale)) + Expect(err).NotTo(HaveOccurred()) + Expect(scale.GetAPIVersion()).To(Equal("autoscaling/v1")) + Expect(scale.GetKind()).To(Equal("Scale")) + + By("Asserting replicas got updated") + dep, err = clientset.AppsV1().Deployments(dep.Namespace).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(*dep.Spec.Replicas).To(Equal(replicaCount)) + }) + }) + + }) + + Describe("StatusClient", func() { + Context("with structured objects", func() { + It("should update status of an existing object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the status of Deployment") + dep.Status.Replicas = 1 + err = cl.Status().Update(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new status") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Replicas).To(BeEquivalentTo(1)) + }) + + It("should update status and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the status of Deployment") + dep.SetGroupVersionKind(depGvk) + dep.Status.Replicas = 1 + err = cl.Status().Update(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(dep.GroupVersionKind()).To(Equal(depGvk)) + }) + + It("should patch status and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("patching the status of Deployment") + dep.SetGroupVersionKind(depGvk) + depPatch := client.MergeFrom(dep.DeepCopy()) + dep.Status.Replicas = 1 + err = cl.Status().Patch(context.TODO(), dep, depPatch) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(dep.GroupVersionKind()).To(Equal(depGvk)) + }) + + It("should not update spec of an existing object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the spec and status of Deployment") + var rc int32 = 1 + dep.Status.Replicas = 1 + dep.Spec.Replicas = &rc + err = cl.Status().Update(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new status and unchanged spec") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Replicas).To(BeEquivalentTo(1)) + Expect(*actual.Spec.Replicas).To(BeEquivalentTo(replicaCount)) + }) + + It("should update an existing object non-namespace object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating status of the object") + node.Status.Phase = corev1.NodeRunning + err = cl.Status().Update(context.TODO(), node) + Expect(err).NotTo(HaveOccurred()) + + By("validate updated Node had new annotation") + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Phase).To(Equal(corev1.NodeRunning)) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("updating status of a non-existent object") + err = cl.Status().Update(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + }) + + It("should fail if the object cannot be mapped to a GVK", func() { + By("creating client with empty Scheme") + emptyScheme := runtime.NewScheme() + cl, err := client.New(cfg, client.Options{Scheme: emptyScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating status of the Deployment") + dep.Status.Replicas = 1 + err = cl.Status().Update(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no kind is registered for the type")) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + + PIt("should fail if an API does not implement Status subresource", func() { + + }) + }) + + Context("with unstructured objects", func() { + It("should update status of an existing object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the status of Deployment") + u := &unstructured.Unstructured{} + dep.Status.Replicas = 1 + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + err = cl.Status().Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new status") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Replicas).To(BeEquivalentTo(1)) + }) + + It("should update status and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the status of Deployment") + u := &unstructured.Unstructured{} + dep.Status.Replicas = 1 + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + err = cl.Status().Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(u.GroupVersionKind()).To(Equal(depGvk)) + }) + + It("should patch status and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("patching the status of Deployment") + u := &unstructured.Unstructured{} + depPatch := client.MergeFrom(dep.DeepCopy()) + dep.Status.Replicas = 1 + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + err = cl.Status().Patch(context.TODO(), u, depPatch) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(u.GroupVersionKind()).To(Equal(depGvk)) + + By("validating patched Deployment has new status") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Replicas).To(BeEquivalentTo(1)) + }) + + It("should not update spec of an existing object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the spec and status of Deployment") + u := &unstructured.Unstructured{} + var rc int32 = 1 + dep.Status.Replicas = 1 + dep.Spec.Replicas = &rc + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + err = cl.Status().Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has new status and unchanged spec") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Replicas).To(BeEquivalentTo(1)) + Expect(*actual.Spec.Replicas).To(BeEquivalentTo(replicaCount)) + }) + + It("should update an existing object non-namespace object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating status of the object") + u := &unstructured.Unstructured{} + node.Status.Phase = corev1.NodeRunning + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + err = cl.Status().Update(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validate updated Node had new annotation") + actual, err := clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Status.Phase).To(Equal(corev1.NodeRunning)) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("updating status of a non-existent object") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + err = cl.Status().Update(context.TODO(), u) + Expect(err).To(HaveOccurred()) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + + PIt("should fail if an API does not implement Status subresource", func() { + + }) + + }) + + Context("with metadata objects", func() { + It("should fail to update with an error", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + obj := metaOnlyFromObj(dep, scheme) + Expect(cl.Status().Update(context.TODO(), obj)).NotTo(Succeed()) + }) + + It("should patch status and preserve type information", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("patching the status of Deployment") + objPatch := client.MergeFrom(metaOnlyFromObj(dep, scheme)) + dep.Annotations = map[string]string{"some-new-annotation": "some-new-value"} + obj := metaOnlyFromObj(dep, scheme) + err = cl.Status().Patch(context.TODO(), obj, objPatch) + Expect(err).NotTo(HaveOccurred()) + + By("validating updated Deployment has type information") + Expect(obj.GroupVersionKind()).To(Equal(depGvk)) + + By("validating patched Deployment has new status") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations).To(HaveKeyWithValue("some-new-annotation", "some-new-value")) + }) + }) + }) + + Describe("Delete", func() { + Context("with structured objects", func() { + It("should delete an existing object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Deployment") + depName := dep.Name + err = cl.Delete(context.TODO(), dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, depName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should delete an existing object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Node") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Node") + nodeName := node.Name + err = cl.Delete(context.TODO(), node) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Node no longer exists") + _, err = clientset.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Deleting node before it is ever created") + err = cl.Delete(context.TODO(), node) + Expect(err).To(HaveOccurred()) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + It("should fail if the object cannot be mapped to a GVK", func() { + By("creating client with empty Scheme") + emptyScheme := runtime.NewScheme() + cl, err := client.New(cfg, client.Options{Scheme: emptyScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Deployment fails") + err = cl.Delete(context.TODO(), dep) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no kind is registered for the type")) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + + It("should delete a collection of objects", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating two Deployments") + + dep2 := dep.DeepCopy() + dep2.Name += "-2" + + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep2, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + depName := dep.Name + dep2Name := dep2.Name + + By("deleting Deployments") + err = cl.DeleteAllOf(context.TODO(), dep, client.InNamespace(ns), client.MatchingLabels(dep.ObjectMeta.Labels)) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, depName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep2Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + }) + Context("with unstructured objects", func() { + It("should delete an existing object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Deployment") + depName := dep.Name + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + err = cl.Delete(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, depName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should delete an existing object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Node") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Node") + nodeName := node.Name + u := &unstructured.Unstructured{} + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Kind: "Node", + Version: "v1", + }) + err = cl.Delete(context.TODO(), u) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Node no longer exists") + _, err = clientset.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Deleting node before it is ever created") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Kind: "Node", + Version: "v1", + }) + err = cl.Delete(context.TODO(), node) + Expect(err).To(HaveOccurred()) + }) + + It("should delete a collection of object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating two Deployments") + + dep2 := dep.DeepCopy() + dep2.Name += "-2" + + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep2, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + depName := dep.Name + dep2Name := dep2.Name + + By("deleting Deployments") + u := &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + err = cl.DeleteAllOf(context.TODO(), u, client.InNamespace(ns), client.MatchingLabels(dep.ObjectMeta.Labels)) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, depName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep2Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + }) + Context("with metadata objects", func() { + It("should delete an existing object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Deployment") + metaObj := metaOnlyFromObj(dep, scheme) + err = cl.Delete(context.TODO(), metaObj) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should delete an existing object non-namespace object from a go struct", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating a Node") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("deleting the Node") + metaObj := metaOnlyFromObj(node, scheme) + err = cl.Delete(context.TODO(), metaObj) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Node no longer exists") + _, err = clientset.CoreV1().Nodes().Get(ctx, node.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("Deleting node before it is ever created") + metaObj := metaOnlyFromObj(node, scheme) + err = cl.Delete(context.TODO(), metaObj) + Expect(err).To(HaveOccurred()) + }) + + It("should delete a collection of object", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("initially creating two Deployments") + + dep2 := dep.DeepCopy() + dep2.Name += "-2" + + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + dep2, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + depName := dep.Name + dep2Name := dep2.Name + + By("deleting Deployments") + metaObj := metaOnlyFromObj(dep, scheme) + err = cl.DeleteAllOf(context.TODO(), metaObj, client.InNamespace(ns), client.MatchingLabels(dep.ObjectMeta.Labels)) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, depName, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep2Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + }) + }) + + Describe("Get", func() { + Context("with structured objects", func() { + It("should fetch an existing object for a go struct", func() { + By("first creating the Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching the created Deployment") + var actual appsv1.Deployment + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("validating the fetched deployment equals the created one") + Expect(dep).To(Equal(&actual)) + }) + + It("should fetch an existing non-namespace object for a go struct", func() { + By("first creating the object") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("retrieving node through client") + var actual corev1.Node + key := client.ObjectKey{Namespace: ns, Name: node.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + Expect(node).To(Equal(&actual)) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching object that has not been created yet") + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + var actual appsv1.Deployment + err = cl.Get(context.TODO(), key, &actual) + Expect(err).To(HaveOccurred()) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + It("should fail if the object cannot be mapped to a GVK", func() { + By("first creating the Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a client with an empty Scheme") + emptyScheme := runtime.NewScheme() + cl, err := client.New(cfg, client.Options{Scheme: emptyScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching the created Deployment fails") + var actual appsv1.Deployment + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("no kind is registered for the type")) + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + + // Test this with an integrated type and a CRD to make sure it covers both proto + // and json deserialization. + for idx, object := range []client.Object{&corev1.ConfigMap{}, &pkg.ChaosPod{}} { + idx, object := idx, object + It(fmt.Sprintf("should not retain any data in the obj variable that is not on the server for %T", object), func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + object.SetName(fmt.Sprintf("retain-test-%d", idx)) + object.SetNamespace(ns) + + By("First creating the object") + toCreate := object.DeepCopyObject().(client.Object) + Expect(cl.Create(ctx, toCreate)).NotTo(HaveOccurred()) + + By("Fetching it into a variable that has finalizers set") + toGetInto := object.DeepCopyObject().(client.Object) + toGetInto.SetFinalizers([]string{"some-finalizer"}) + Expect(cl.Get(ctx, client.ObjectKeyFromObject(object), toGetInto)).NotTo(HaveOccurred()) + + By("Ensuring the created and the received object are equal") + Expect(toCreate).Should(Equal(toGetInto)) + }) + } + + }) + + Context("with unstructured objects", func() { + It("should fetch an existing object", func() { + By("first creating the Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("encoding the Deployment as unstructured") + var u runtime.Unstructured = &unstructured.Unstructured{} + Expect(scheme.Convert(dep, u, nil)).To(Succeed()) + + By("fetching the created Deployment") + var actual unstructured.Unstructured + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("validating the fetched Deployment equals the created one") + Expect(u).To(Equal(&actual)) + }) + + It("should fetch an existing non-namespace object", func() { + By("first creating the Node") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("encoding the Node as unstructured") + var u runtime.Unstructured = &unstructured.Unstructured{} + Expect(scheme.Convert(node, u, nil)).To(Succeed()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching the created Node") + var actual unstructured.Unstructured + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Kind: "Node", + Version: "v1", + }) + key := client.ObjectKey{Namespace: ns, Name: node.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("validating the fetched Node equals the created one") + Expect(u).To(Equal(&actual)) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching object that has not been created yet") + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + u := &unstructured.Unstructured{} + err = cl.Get(context.TODO(), key, u) + Expect(err).To(HaveOccurred()) + }) + + It("should not retain any data in the obj variable that is not on the server", func() { + object := &unstructured.Unstructured{} + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + object.SetName("retain-unstructured") + object.SetNamespace(ns) + object.SetAPIVersion("chaosapps.metamagical.io/v1") + object.SetKind("ChaosPod") + + By("First creating the object") + toCreate := object.DeepCopyObject().(client.Object) + Expect(cl.Create(ctx, toCreate)).NotTo(HaveOccurred()) + + By("Fetching it into a variable that has finalizers set") + toGetInto := object.DeepCopyObject().(client.Object) + toGetInto.SetFinalizers([]string{"some-finalizer"}) + Expect(cl.Get(ctx, client.ObjectKeyFromObject(object), toGetInto)).NotTo(HaveOccurred()) + + By("Ensuring the created and the received object are equal") + Expect(toCreate).Should(Equal(toGetInto)) + }) + }) + Context("with metadata objects", func() { + It("should fetch an existing object for a go struct", func() { + By("first creating the Deployment") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching the created Deployment") + var actual metav1.PartialObjectMetadata + gvk := schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + } + actual.SetGroupVersionKind(gvk) + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + By("validating that the GVK has been preserved") + Expect(actual.GroupVersionKind()).To(Equal(gvk)) + + By("validating the fetched deployment equals the created one") + Expect(metaOnlyFromObj(dep, scheme)).To(Equal(&actual)) + }) + + It("should fetch an existing non-namespace object for a go struct", func() { + By("first creating the object") + node, err := clientset.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("retrieving node through client") + var actual metav1.PartialObjectMetadata + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Version: "v1", + Kind: "Node", + }) + key := client.ObjectKey{Namespace: ns, Name: node.Name} + err = cl.Get(context.TODO(), key, &actual) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + + Expect(metaOnlyFromObj(node, scheme)).To(Equal(&actual)) + }) + + It("should fail if the object does not exist", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("fetching object that has not been created yet") + key := client.ObjectKey{Namespace: ns, Name: dep.Name} + var actual metav1.PartialObjectMetadata + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + }) + err = cl.Get(context.TODO(), key, &actual) + Expect(err).To(HaveOccurred()) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + + It("should not retain any data in the obj variable that is not on the server", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + By("First creating the object") + toCreate := &pkg.ChaosPod{ObjectMeta: metav1.ObjectMeta{Name: "retain-metadata", Namespace: ns}} + Expect(cl.Create(ctx, toCreate)).NotTo(HaveOccurred()) + + By("Fetching it into a variable that has finalizers set") + toGetInto := &metav1.PartialObjectMetadata{ + TypeMeta: metav1.TypeMeta{APIVersion: "chaosapps.metamagical.io/v1", Kind: "ChaosPod"}, + ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: "retain-metadata"}, + } + toGetInto.SetFinalizers([]string{"some-finalizer"}) + Expect(cl.Get(ctx, client.ObjectKeyFromObject(toGetInto), toGetInto)).NotTo(HaveOccurred()) + + By("Ensuring the created and the received objects metadata are equal") + Expect(toCreate.ObjectMeta).Should(Equal(toGetInto.ObjectMeta)) + }) + }) + }) + + Describe("List", func() { + Context("with structured objects", func() { + It("should fetch collection of objects", func() { + By("creating an initial object") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all objects of that type in the cluster") + deps := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), deps)).NotTo(HaveOccurred()) + + Expect(deps.Items).NotTo(BeEmpty()) + hasDep := false + for _, item := range deps.Items { + if item.Name == dep.Name && item.Namespace == dep.Namespace { + hasDep = true + break + } + } + Expect(hasDep).To(BeTrue()) + }) + + It("should fetch unstructured collection of objects", func() { + By("create an initial object") + _, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all objects of that type in the cluster") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + err = cl.List(context.Background(), deps) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).NotTo(BeEmpty()) + hasDep := false + for _, item := range deps.Items { + Expect(item.GroupVersionKind()).To(Equal(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + })) + if item.GetName() == dep.Name && item.GetNamespace() == dep.Namespace { + hasDep = true + break + } + } + Expect(hasDep).To(BeTrue()) + }) + + It("should fetch unstructured collection of objects, even if scheme is empty", func() { + By("create an initial object") + _, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{Scheme: runtime.NewScheme()}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all objects of that type in the cluster") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + err = cl.List(context.Background(), deps) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).NotTo(BeEmpty()) + hasDep := false + for _, item := range deps.Items { + if item.GetName() == dep.Name && item.GetNamespace() == dep.Namespace { + hasDep = true + break + } + } + Expect(hasDep).To(BeTrue()) + }) + + It("should return an empty list if there are no matching objects", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in the cluster") + deps := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), deps)).NotTo(HaveOccurred()) + + By("validating no Deployments are returned") + Expect(deps.Items).To(BeEmpty()) + }) + + // TODO(seans): get label selector test working + It("should filter results by label selector", func() { + By("creating a Deployment with the app=frontend label") + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: ns, + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err := clientset.AppsV1().Deployments(ns).Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment with the app=backend label") + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-backend", + Namespace: ns, + Labels: map[string]string{"app": "backend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments(ns).Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments with label app=backend") + deps := &appsv1.DeploymentList{} + labels := map[string]string{"app": "backend"} + err = cl.List(context.Background(), deps, client.MatchingLabels(labels)) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment with the backend label is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.Name).To(Equal("deployment-backend")) + + deleteDeployment(ctx, depFrontend, ns) + deleteDeployment(ctx, depBackend, ns) + }) + + It("should filter results by namespace selector", func() { + By("creating a Deployment in test-namespace-1") + tns1 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-1"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns1, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: "test-namespace-1"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err = clientset.AppsV1().Deployments("test-namespace-1").Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-2") + tns2 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-2"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: "test-namespace-2"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments("test-namespace-2").Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-1") + deps := &appsv1.DeploymentList{} + err = cl.List(context.Background(), deps, client.InNamespace("test-namespace-1")) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-1 is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.Name).To(Equal("deployment-frontend")) + + deleteDeployment(ctx, depFrontend, "test-namespace-1") + deleteDeployment(ctx, depBackend, "test-namespace-2") + deleteNamespace(ctx, tns1) + deleteNamespace(ctx, tns2) + }) + + It("should filter results by field selector", func() { + By("creating a Deployment with name deployment-frontend") + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err := clientset.AppsV1().Deployments(ns).Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment with name deployment-backend") + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments(ns).Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments with field metadata.name=deployment-backend") + deps := &appsv1.DeploymentList{} + err = cl.List(context.Background(), deps, + client.MatchingFields{"metadata.name": "deployment-backend"}) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment with the backend field is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.Name).To(Equal("deployment-backend")) + + deleteDeployment(ctx, depFrontend, ns) + deleteDeployment(ctx, depBackend, ns) + }) + + It("should filter results by namespace selector and label selector", func() { + By("creating a Deployment in test-namespace-3 with the app=frontend label") + tns3 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-3"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-3", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend3, err = clientset.AppsV1().Deployments("test-namespace-3").Create(ctx, depFrontend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-3 with the app=backend label") + depBackend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-backend", + Namespace: "test-namespace-3", + Labels: map[string]string{"app": "backend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend3, err = clientset.AppsV1().Deployments("test-namespace-3").Create(ctx, depBackend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-4 with the app=frontend label") + tns4 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-4"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend4 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-4", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend4, err = clientset.AppsV1().Deployments("test-namespace-4").Create(ctx, depFrontend4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-3 with label app=frontend") + deps := &appsv1.DeploymentList{} + labels := map[string]string{"app": "frontend"} + err = cl.List(context.Background(), deps, + client.InNamespace("test-namespace-3"), + client.MatchingLabels(labels), + ) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-3 with label app=frontend is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.Name).To(Equal("deployment-frontend")) + Expect(actual.Namespace).To(Equal("test-namespace-3")) + + deleteDeployment(ctx, depFrontend3, "test-namespace-3") + deleteDeployment(ctx, depBackend3, "test-namespace-3") + deleteDeployment(ctx, depFrontend4, "test-namespace-4") + deleteNamespace(ctx, tns3) + deleteNamespace(ctx, tns4) + }) + + It("should filter results using limit and continue options", func() { + + makeDeployment := func(suffix string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("deployment-%s", suffix), + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + } + + By("creating 4 deployments") + dep1 := makeDeployment("1") + dep1, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep1, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep1, ns) + + dep2 := makeDeployment("2") + dep2, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep2, ns) + + dep3 := makeDeployment("3") + dep3, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep3, ns) + + dep4 := makeDeployment("4") + dep4, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep4, ns) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing 1 deployment when limit=1 is used") + deps := &appsv1.DeploymentList{} + err = cl.List(context.Background(), deps, + client.Limit(1), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).To(HaveLen(1)) + Expect(deps.Continue).NotTo(BeEmpty()) + Expect(deps.Items[0].Name).To(Equal(dep1.Name)) + + continueToken := deps.Continue + + By("listing the next deployment when previous continuation token is used and limit=1") + deps = &appsv1.DeploymentList{} + err = cl.List(context.Background(), deps, + client.Limit(1), + client.Continue(continueToken), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).To(HaveLen(1)) + Expect(deps.Continue).NotTo(BeEmpty()) + Expect(deps.Items[0].Name).To(Equal(dep2.Name)) + + continueToken = deps.Continue + + By("listing the 2 remaining deployments when previous continuation token is used without a limit") + deps = &appsv1.DeploymentList{} + err = cl.List(context.Background(), deps, + client.Continue(continueToken), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).To(HaveLen(2)) + Expect(deps.Continue).To(BeEmpty()) + Expect(deps.Items[0].Name).To(Equal(dep3.Name)) + Expect(deps.Items[1].Name).To(Equal(dep4.Name)) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + PIt("should fail if the object cannot be mapped to a GVK", func() { + + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + }) + + Context("with unstructured objects", func() { + It("should fetch collection of objects", func() { + By("create an initial object") + _, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all objects of that type in the cluster") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + err = cl.List(context.Background(), deps) + Expect(err).NotTo(HaveOccurred()) + + Expect(deps.Items).NotTo(BeEmpty()) + hasDep := false + for _, item := range deps.Items { + if item.GetName() == dep.Name && item.GetNamespace() == dep.Namespace { + hasDep = true + break + } + } + Expect(hasDep).To(BeTrue()) + }) + + It("should return an empty list if there are no matching objects", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in the cluster") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + Expect(cl.List(context.Background(), deps)).NotTo(HaveOccurred()) + + By("validating no Deployments are returned") + Expect(deps.Items).To(BeEmpty()) + }) + + It("should filter results by namespace selector", func() { + By("creating a Deployment in test-namespace-5") + tns1 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-5"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns1, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: "test-namespace-5"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err = clientset.AppsV1().Deployments("test-namespace-5").Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-6") + tns2 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-6"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: "test-namespace-6"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments("test-namespace-6").Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-5") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + err = cl.List(context.Background(), deps, client.InNamespace("test-namespace-5")) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-5 is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.GetName()).To(Equal("deployment-frontend")) + + deleteDeployment(ctx, depFrontend, "test-namespace-5") + deleteDeployment(ctx, depBackend, "test-namespace-6") + deleteNamespace(ctx, tns1) + deleteNamespace(ctx, tns2) + }) + + It("should filter results by field selector", func() { + By("creating a Deployment with name deployment-frontend") + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err := clientset.AppsV1().Deployments(ns).Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment with name deployment-backend") + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments(ns).Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments with field metadata.name=deployment-backend") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + err = cl.List(context.Background(), deps, + client.MatchingFields{"metadata.name": "deployment-backend"}) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment with the backend field is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.GetName()).To(Equal("deployment-backend")) + + deleteDeployment(ctx, depFrontend, ns) + deleteDeployment(ctx, depBackend, ns) + }) + + It("should filter results by namespace selector and label selector", func() { + By("creating a Deployment in test-namespace-7 with the app=frontend label") + tns3 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-7"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-7", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend3, err = clientset.AppsV1().Deployments("test-namespace-7").Create(ctx, depFrontend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-7 with the app=backend label") + depBackend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-backend", + Namespace: "test-namespace-7", + Labels: map[string]string{"app": "backend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend3, err = clientset.AppsV1().Deployments("test-namespace-7").Create(ctx, depBackend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-8 with the app=frontend label") + tns4 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-8"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend4 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-8", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend4, err = clientset.AppsV1().Deployments("test-namespace-8").Create(ctx, depFrontend4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-8 with label app=frontend") + deps := &unstructured.UnstructuredList{} + deps.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + labels := map[string]string{"app": "frontend"} + err = cl.List(context.Background(), deps, + client.InNamespace("test-namespace-7"), client.MatchingLabels(labels)) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-7 with label app=frontend is returned") + Expect(deps.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(deps.Items))) + actual := deps.Items[0] + Expect(actual.GetName()).To(Equal("deployment-frontend")) + Expect(actual.GetNamespace()).To(Equal("test-namespace-7")) + + deleteDeployment(ctx, depFrontend3, "test-namespace-7") + deleteDeployment(ctx, depBackend3, "test-namespace-7") + deleteDeployment(ctx, depFrontend4, "test-namespace-8") + deleteNamespace(ctx, tns3) + deleteNamespace(ctx, tns4) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + PIt("should filter results by namespace selector", func() { + + }) + }) + Context("with metadata objects", func() { + It("should fetch collection of objects", func() { + By("creating an initial object") + dep, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all objects of that type in the cluster") + gvk := schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + } + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(gvk) + Expect(cl.List(context.Background(), metaList)).NotTo(HaveOccurred()) + + By("validating that the list GVK has been preserved") + Expect(metaList.GroupVersionKind()).To(Equal(gvk)) + + By("validating that the list has the expected deployment") + Expect(metaList.Items).NotTo(BeEmpty()) + hasDep := false + for _, item := range metaList.Items { + Expect(item.GroupVersionKind()).To(Equal(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + })) + + if item.Name == dep.Name && item.Namespace == dep.Namespace { + hasDep = true + break + } + } + Expect(hasDep).To(BeTrue()) + }) + + It("should return an empty list if there are no matching objects", func() { + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in the cluster") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + Expect(cl.List(context.Background(), metaList)).NotTo(HaveOccurred()) + + By("validating no Deployments are returned") + Expect(metaList.Items).To(BeEmpty()) + }) + + // TODO(seans): get label selector test working + It("should filter results by label selector", func() { + By("creating a Deployment with the app=frontend label") + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: ns, + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err := clientset.AppsV1().Deployments(ns).Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment with the app=backend label") + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-backend", + Namespace: ns, + Labels: map[string]string{"app": "backend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments(ns).Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments with label app=backend") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + labels := map[string]string{"app": "backend"} + err = cl.List(context.Background(), metaList, client.MatchingLabels(labels)) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment with the backend label is returned") + Expect(metaList.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(metaList.Items))) + actual := metaList.Items[0] + Expect(actual.Name).To(Equal("deployment-backend")) + + deleteDeployment(ctx, depFrontend, ns) + deleteDeployment(ctx, depBackend, ns) + }) + + It("should filter results by namespace selector", func() { + By("creating a Deployment in test-namespace-1") + tns1 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-1"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns1, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: "test-namespace-1"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err = clientset.AppsV1().Deployments("test-namespace-1").Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-2") + tns2 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-2"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: "test-namespace-2"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments("test-namespace-2").Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-1") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + err = cl.List(context.Background(), metaList, client.InNamespace("test-namespace-1")) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-1 is returned") + Expect(metaList.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(metaList.Items))) + actual := metaList.Items[0] + Expect(actual.Name).To(Equal("deployment-frontend")) + + deleteDeployment(ctx, depFrontend, "test-namespace-1") + deleteDeployment(ctx, depBackend, "test-namespace-2") + deleteNamespace(ctx, tns1) + deleteNamespace(ctx, tns2) + }) + + It("should filter results by field selector", func() { + By("creating a Deployment with name deployment-frontend") + depFrontend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-frontend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend, err := clientset.AppsV1().Deployments(ns).Create(ctx, depFrontend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment with name deployment-backend") + depBackend := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-backend", Namespace: ns}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend, err = clientset.AppsV1().Deployments(ns).Create(ctx, depBackend, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments with field metadata.name=deployment-backend") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + err = cl.List(context.Background(), metaList, + client.MatchingFields{"metadata.name": "deployment-backend"}) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment with the backend field is returned") + Expect(metaList.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(metaList.Items))) + actual := metaList.Items[0] + Expect(actual.Name).To(Equal("deployment-backend")) + + deleteDeployment(ctx, depFrontend, ns) + deleteDeployment(ctx, depBackend, ns) + }) + + It("should filter results by namespace selector and label selector", func() { + By("creating a Deployment in test-namespace-3 with the app=frontend label") + tns3 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-3"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-3", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend3, err = clientset.AppsV1().Deployments("test-namespace-3").Create(ctx, depFrontend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-3 with the app=backend label") + depBackend3 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-backend", + Namespace: "test-namespace-3", + Labels: map[string]string{"app": "backend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "backend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "backend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depBackend3, err = clientset.AppsV1().Deployments("test-namespace-3").Create(ctx, depBackend3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("creating a Deployment in test-namespace-4 with the app=frontend label") + tns4 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace-4"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + depFrontend4 := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-frontend", + Namespace: "test-namespace-4", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + depFrontend4, err = clientset.AppsV1().Deployments("test-namespace-4").Create(ctx, depFrontend4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing all Deployments in test-namespace-3 with label app=frontend") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + labels := map[string]string{"app": "frontend"} + err = cl.List(context.Background(), metaList, + client.InNamespace("test-namespace-3"), + client.MatchingLabels(labels), + ) + Expect(err).NotTo(HaveOccurred()) + + By("only the Deployment in test-namespace-3 with label app=frontend is returned") + Expect(metaList.Items).NotTo(BeEmpty()) + Expect(1).To(Equal(len(metaList.Items))) + actual := metaList.Items[0] + Expect(actual.Name).To(Equal("deployment-frontend")) + Expect(actual.Namespace).To(Equal("test-namespace-3")) + + deleteDeployment(ctx, depFrontend3, "test-namespace-3") + deleteDeployment(ctx, depBackend3, "test-namespace-3") + deleteDeployment(ctx, depFrontend4, "test-namespace-4") + deleteNamespace(ctx, tns3) + deleteNamespace(ctx, tns4) + }) + + It("should filter results using limit and continue options", func() { + + makeDeployment := func(suffix string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("deployment-%s", suffix), + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + } + + By("creating 4 deployments") + dep1 := makeDeployment("1") + dep1, err := clientset.AppsV1().Deployments(ns).Create(ctx, dep1, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep1, ns) + + dep2 := makeDeployment("2") + dep2, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep2, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep2, ns) + + dep3 := makeDeployment("3") + dep3, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep3, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep3, ns) + + dep4 := makeDeployment("4") + dep4, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep4, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + defer deleteDeployment(ctx, dep4, ns) + + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("listing 1 deployment when limit=1 is used") + metaList := &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + err = cl.List(context.Background(), metaList, + client.Limit(1), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(metaList.Items).To(HaveLen(1)) + Expect(metaList.Continue).NotTo(BeEmpty()) + Expect(metaList.Items[0].Name).To(Equal(dep1.Name)) + + continueToken := metaList.Continue + + By("listing the next deployment when previous continuation token is used and limit=1") + metaList = &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + err = cl.List(context.Background(), metaList, + client.Limit(1), + client.Continue(continueToken), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(metaList.Items).To(HaveLen(1)) + Expect(metaList.Continue).NotTo(BeEmpty()) + Expect(metaList.Items[0].Name).To(Equal(dep2.Name)) + + continueToken = metaList.Continue + + By("listing the 2 remaining deployments when previous continuation token is used without a limit") + metaList = &metav1.PartialObjectMetadataList{} + metaList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "DeploymentList", + }) + err = cl.List(context.Background(), metaList, + client.Continue(continueToken), + ) + Expect(err).NotTo(HaveOccurred()) + + Expect(metaList.Items).To(HaveLen(2)) + Expect(metaList.Continue).To(BeEmpty()) + Expect(metaList.Items[0].Name).To(Equal(dep3.Name)) + Expect(metaList.Items[1].Name).To(Equal(dep4.Name)) + }) + + PIt("should fail if the object doesn't have meta", func() { + + }) + + PIt("should fail if the object cannot be mapped to a GVK", func() { + + }) + + PIt("should fail if the GVK cannot be mapped to a Resource", func() { + + }) + }) + }) + + Describe("CreateOptions", func() { + It("should allow setting DryRun to 'all'", func() { + co := &client.CreateOptions{} + client.DryRunAll.ApplyToCreate(co) + all := []string{metav1.DryRunAll} + Expect(co.AsCreateOptions().DryRun).To(Equal(all)) + }) + + It("should allow setting the field manager", func() { + po := &client.CreateOptions{} + client.FieldOwner("some-owner").ApplyToCreate(po) + Expect(po.AsCreateOptions().FieldManager).To(Equal("some-owner")) + }) + + It("should produce empty metav1.CreateOptions if nil", func() { + var co *client.CreateOptions + Expect(co.AsCreateOptions()).To(Equal(&metav1.CreateOptions{})) + co = &client.CreateOptions{} + Expect(co.AsCreateOptions()).To(Equal(&metav1.CreateOptions{})) + }) + }) + + Describe("DeleteOptions", func() { + It("should allow setting GracePeriodSeconds", func() { + do := &client.DeleteOptions{} + client.GracePeriodSeconds(1).ApplyToDelete(do) + gp := int64(1) + Expect(do.AsDeleteOptions().GracePeriodSeconds).To(Equal(&gp)) + }) + + It("should allow setting Precondition", func() { + do := &client.DeleteOptions{} + pc := metav1.NewUIDPreconditions("uid") + client.Preconditions(*pc).ApplyToDelete(do) + Expect(do.AsDeleteOptions().Preconditions).To(Equal(pc)) + Expect(do.Preconditions).To(Equal(pc)) + }) + + It("should allow setting PropagationPolicy", func() { + do := &client.DeleteOptions{} + client.PropagationPolicy(metav1.DeletePropagationForeground).ApplyToDelete(do) + dp := metav1.DeletePropagationForeground + Expect(do.AsDeleteOptions().PropagationPolicy).To(Equal(&dp)) + }) + + It("should allow setting DryRun", func() { + do := &client.DeleteOptions{} + client.DryRunAll.ApplyToDelete(do) + all := []string{metav1.DryRunAll} + Expect(do.AsDeleteOptions().DryRun).To(Equal(all)) + }) + + It("should produce empty metav1.DeleteOptions if nil", func() { + var do *client.DeleteOptions + Expect(do.AsDeleteOptions()).To(Equal(&metav1.DeleteOptions{})) + do = &client.DeleteOptions{} + Expect(do.AsDeleteOptions()).To(Equal(&metav1.DeleteOptions{})) + }) + + It("should merge multiple options together", func() { + gp := int64(1) + pc := metav1.NewUIDPreconditions("uid") + dp := metav1.DeletePropagationForeground + do := &client.DeleteOptions{} + do.ApplyOptions([]client.DeleteOption{ + client.GracePeriodSeconds(gp), + client.Preconditions(*pc), + client.PropagationPolicy(dp), + }) + Expect(do.GracePeriodSeconds).To(Equal(&gp)) + Expect(do.Preconditions).To(Equal(pc)) + Expect(do.PropagationPolicy).To(Equal(&dp)) + }) + }) + + Describe("DeleteCollectionOptions", func() { + It("should be convertable to list options", func() { + gp := int64(1) + do := &client.DeleteAllOfOptions{} + do.ApplyOptions([]client.DeleteAllOfOption{ + client.GracePeriodSeconds(gp), + client.MatchingLabels{"foo": "bar"}, + }) + + listOpts := do.AsListOptions() + Expect(listOpts).NotTo(BeNil()) + Expect(listOpts.LabelSelector).To(Equal("foo=bar")) + }) + + It("should be convertable to delete options", func() { + gp := int64(1) + do := &client.DeleteAllOfOptions{} + do.ApplyOptions([]client.DeleteAllOfOption{ + client.GracePeriodSeconds(gp), + client.MatchingLabels{"foo": "bar"}, + }) + + deleteOpts := do.AsDeleteOptions() + Expect(deleteOpts).NotTo(BeNil()) + Expect(deleteOpts.GracePeriodSeconds).To(Equal(&gp)) + }) + }) + + Describe("GetOptions", func() { + It("should be convertable to metav1.GetOptions", func() { + o := (&client.GetOptions{}).ApplyOptions([]client.GetOption{ + &client.GetOptions{Raw: &metav1.GetOptions{ResourceVersion: "RV0"}}, + }) + mo := o.AsGetOptions() + Expect(mo).NotTo(BeNil()) + Expect(mo.ResourceVersion).To(Equal("RV0")) + }) + + It("should produce empty metav1.GetOptions if nil", func() { + var o *client.GetOptions + Expect(o.AsGetOptions()).To(Equal(&metav1.GetOptions{})) + o = &client.GetOptions{} + Expect(o.AsGetOptions()).To(Equal(&metav1.GetOptions{})) + }) + }) + + Describe("ListOptions", func() { + It("should be convertable to metav1.ListOptions", func() { + lo := (&client.ListOptions{}).ApplyOptions([]client.ListOption{ + client.MatchingFields{"field1": "bar"}, + client.InNamespace("test-namespace"), + client.MatchingLabels{"foo": "bar"}, + client.Limit(1), + client.Continue("foo"), + }) + mlo := lo.AsListOptions() + Expect(mlo).NotTo(BeNil()) + Expect(mlo.LabelSelector).To(Equal("foo=bar")) + Expect(mlo.FieldSelector).To(Equal("field1=bar")) + Expect(mlo.Limit).To(Equal(int64(1))) + Expect(mlo.Continue).To(Equal("foo")) + }) + + It("should be populated by MatchingLabels", func() { + lo := &client.ListOptions{} + client.MatchingLabels{"foo": "bar"}.ApplyToList(lo) + Expect(lo).NotTo(BeNil()) + Expect(lo.LabelSelector.String()).To(Equal("foo=bar")) + }) + + It("should be populated by MatchingField", func() { + lo := &client.ListOptions{} + client.MatchingFields{"field1": "bar"}.ApplyToList(lo) + Expect(lo).NotTo(BeNil()) + Expect(lo.FieldSelector.String()).To(Equal("field1=bar")) + }) + + It("should be populated by InNamespace", func() { + lo := &client.ListOptions{} + client.InNamespace("test").ApplyToList(lo) + Expect(lo).NotTo(BeNil()) + Expect(lo.Namespace).To(Equal("test")) + }) + + It("should produce empty metav1.ListOptions if nil", func() { + var do *client.ListOptions + Expect(do.AsListOptions()).To(Equal(&metav1.ListOptions{})) + do = &client.ListOptions{} + Expect(do.AsListOptions()).To(Equal(&metav1.ListOptions{})) + }) + + It("should be populated by Limit", func() { + lo := &client.ListOptions{} + client.Limit(1).ApplyToList(lo) + Expect(lo).NotTo(BeNil()) + Expect(lo.Limit).To(Equal(int64(1))) + }) + + It("should ignore Limit when converted to metav1.ListOptions and watch is true", func() { + lo := &client.ListOptions{ + Raw: &metav1.ListOptions{Watch: true}, + } + lo.ApplyOptions([]client.ListOption{ + client.Limit(1), + }) + mlo := lo.AsListOptions() + Expect(mlo).NotTo(BeNil()) + Expect(mlo.Limit).To(BeZero()) + }) + + It("should be populated by Continue", func() { + lo := &client.ListOptions{} + client.Continue("foo").ApplyToList(lo) + Expect(lo).NotTo(BeNil()) + Expect(lo.Continue).To(Equal("foo")) + }) + + It("should ignore Continue token when converted to metav1.ListOptions and watch is true", func() { + lo := &client.ListOptions{ + Raw: &metav1.ListOptions{Watch: true}, + } + lo.ApplyOptions([]client.ListOption{ + client.Continue("foo"), + }) + mlo := lo.AsListOptions() + Expect(mlo).NotTo(BeNil()) + Expect(mlo.Continue).To(BeEmpty()) + }) + + It("should ignore both Limit and Continue token when converted to metav1.ListOptions and watch is true", func() { + lo := &client.ListOptions{ + Raw: &metav1.ListOptions{Watch: true}, + } + lo.ApplyOptions([]client.ListOption{ + client.Limit(1), + client.Continue("foo"), + }) + mlo := lo.AsListOptions() + Expect(mlo).NotTo(BeNil()) + Expect(mlo.Limit).To(BeZero()) + Expect(mlo.Continue).To(BeEmpty()) + }) + }) + + Describe("UpdateOptions", func() { + It("should allow setting DryRun to 'all'", func() { + uo := &client.UpdateOptions{} + client.DryRunAll.ApplyToUpdate(uo) + all := []string{metav1.DryRunAll} + Expect(uo.AsUpdateOptions().DryRun).To(Equal(all)) + }) + + It("should allow setting the field manager", func() { + po := &client.UpdateOptions{} + client.FieldOwner("some-owner").ApplyToUpdate(po) + Expect(po.AsUpdateOptions().FieldManager).To(Equal("some-owner")) + }) + + It("should produce empty metav1.UpdateOptions if nil", func() { + var co *client.UpdateOptions + Expect(co.AsUpdateOptions()).To(Equal(&metav1.UpdateOptions{})) + co = &client.UpdateOptions{} + Expect(co.AsUpdateOptions()).To(Equal(&metav1.UpdateOptions{})) + }) + }) + + Describe("PatchOptions", func() { + It("should allow setting DryRun to 'all'", func() { + po := &client.PatchOptions{} + client.DryRunAll.ApplyToPatch(po) + all := []string{metav1.DryRunAll} + Expect(po.AsPatchOptions().DryRun).To(Equal(all)) + }) + + It("should allow setting Force to 'true'", func() { + po := &client.PatchOptions{} + client.ForceOwnership.ApplyToPatch(po) + mpo := po.AsPatchOptions() + Expect(mpo.Force).NotTo(BeNil()) + Expect(*mpo.Force).To(BeTrue()) + }) + + It("should allow setting the field manager", func() { + po := &client.PatchOptions{} + client.FieldOwner("some-owner").ApplyToPatch(po) + Expect(po.AsPatchOptions().FieldManager).To(Equal("some-owner")) + }) + + It("should produce empty metav1.PatchOptions if nil", func() { + var po *client.PatchOptions + Expect(po.AsPatchOptions()).To(Equal(&metav1.PatchOptions{})) + po = &client.PatchOptions{} + Expect(po.AsPatchOptions()).To(Equal(&metav1.PatchOptions{})) + }) + }) +}) + +var _ = Describe("ClientWithCache", func() { + Describe("Get", func() { + It("should call cache reader when structured object", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + }, + }) + Expect(err).NotTo(HaveOccurred()) + var actual appsv1.Deployment + key := client.ObjectKey{Namespace: "ns", Name: "name"} + Expect(cl.Get(context.TODO(), key, &actual)).To(Succeed()) + Expect(1).To(Equal(cachedReader.Called)) + }) + + When("getting unstructured objects", func() { + var dep *appsv1.Deployment + + BeforeEach(func() { + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment1", + Labels: map[string]string{"app": "frontend"}, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "frontend"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "frontend"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "x", Image: "x"}}}, + }, + }, + } + var err error + dep, err = clientset.AppsV1().Deployments("default").Create(context.Background(), dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + AfterEach(func() { + Expect(clientset.AppsV1().Deployments("default").Delete( + context.Background(), + dep.Name, + metav1.DeleteOptions{}, + )).To(Succeed()) + }) + It("should call client reader when not cached", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + actual := &unstructured.Unstructured{} + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + actual.SetName(dep.Name) + key := client.ObjectKey{Namespace: dep.Namespace, Name: dep.Name} + Expect(cl.Get(context.TODO(), key, actual)).To(Succeed()) + Expect(0).To(Equal(cachedReader.Called)) + }) + It("should call cache reader when cached", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + Unstructured: true, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + actual := &unstructured.Unstructured{} + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + actual.SetName(dep.Name) + key := client.ObjectKey{Namespace: dep.Namespace, Name: dep.Name} + Expect(cl.Get(context.TODO(), key, actual)).To(Succeed()) + Expect(1).To(Equal(cachedReader.Called)) + }) + }) + }) + Describe("List", func() { + It("should call cache reader when structured object", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + }, + }) + Expect(err).NotTo(HaveOccurred()) + var actual appsv1.DeploymentList + Expect(cl.List(context.Background(), &actual)).To(Succeed()) + Expect(1).To(Equal(cachedReader.Called)) + }) + + When("listing unstructured objects", func() { + It("should call client reader when not cached", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + actual := &unstructured.UnstructuredList{} + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + Expect(cl.List(context.Background(), actual)).To(Succeed()) + Expect(0).To(Equal(cachedReader.Called)) + }) + It("should call cache reader when cached", func() { + cachedReader := &fakeReader{} + cl, err := client.New(cfg, client.Options{ + Cache: &client.CacheOptions{ + Reader: cachedReader, + Unstructured: true, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + actual := &unstructured.UnstructuredList{} + actual.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + Expect(cl.List(context.Background(), actual)).To(Succeed()) + Expect(1).To(Equal(cachedReader.Called)) + }) + }) + }) +}) + +var _ = Describe("Patch", func() { + Describe("MergeFrom", func() { + var cm *corev1.ConfigMap + + BeforeEach(func() { + cm = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: metav1.NamespaceDefault, + Name: "cm", + ResourceVersion: "10", + }, + } + }) + + It("creates a merge patch with the modifications applied during the mutation", func() { + const ( + annotationKey = "test" + annotationValue = "foo" + ) + + By("creating a merge patch") + patch := client.MergeFrom(cm.DeepCopy()) + + By("returning a patch with type MergePatch") + Expect(patch.Type()).To(Equal(types.MergePatchType)) + + By("retrieving modifying the config map") + metav1.SetMetaDataAnnotation(&cm.ObjectMeta, annotationKey, annotationValue) + + By("computing the patch data") + data, err := patch.Data(cm) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning a patch with data only containing the annotation change") + Expect(data).To(Equal([]byte(fmt.Sprintf(`{"metadata":{"annotations":{"%s":"%s"}}}`, annotationKey, annotationValue)))) + }) + + It("creates a merge patch with the modifications applied during the mutation, using optimistic locking", func() { + const ( + annotationKey = "test" + annotationValue = "foo" + ) + + By("creating a merge patch") + patch := client.MergeFromWithOptions(cm.DeepCopy(), client.MergeFromWithOptimisticLock{}) + + By("returning a patch with type MergePatch") + Expect(patch.Type()).To(Equal(types.MergePatchType)) + + By("retrieving modifying the config map") + metav1.SetMetaDataAnnotation(&cm.ObjectMeta, annotationKey, annotationValue) + + By("computing the patch data") + data, err := patch.Data(cm) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning a patch with data containing the annotation change and the resourceVersion change") + Expect(data).To(Equal([]byte(fmt.Sprintf(`{"metadata":{"annotations":{"%s":"%s"},"resourceVersion":"%s"}}`, annotationKey, annotationValue, cm.ResourceVersion)))) + }) + }) + + Describe("StrategicMergeFrom", func() { + var dep *appsv1.Deployment + + BeforeEach(func() { + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: metav1.NamespaceDefault, + Name: "dep", + ResourceVersion: "10", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{Containers: []corev1.Container{{ + Name: "main", + Image: "foo:v1", + }, { + Name: "sidecar", + Image: "bar:v1", + }}}, + }, + }, + } + }) + + It("creates a strategic merge patch with the modifications applied during the mutation", func() { + By("creating a strategic merge patch") + patch := client.StrategicMergeFrom(dep.DeepCopy()) + + By("returning a patch with type StrategicMergePatchType") + Expect(patch.Type()).To(Equal(types.StrategicMergePatchType)) + + By("updating the main container's image") + for i, c := range dep.Spec.Template.Spec.Containers { + if c.Name == "main" { + c.Image = "foo:v2" + } + dep.Spec.Template.Spec.Containers[i] = c + } + + By("computing the patch data") + data, err := patch.Data(dep) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning a patch with data only containing the image change") + Expect(data).To(Equal([]byte(`{"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"main"},` + + `{"name":"sidecar"}],"containers":[{"image":"foo:v2","name":"main"}]}}}}`))) + }) + + It("creates a strategic merge patch with the modifications applied during the mutation, using optimistic locking", func() { + By("creating a strategic merge patch") + patch := client.StrategicMergeFrom(dep.DeepCopy(), client.MergeFromWithOptimisticLock{}) + + By("returning a patch with type StrategicMergePatchType") + Expect(patch.Type()).To(Equal(types.StrategicMergePatchType)) + + By("updating the main container's image") + for i, c := range dep.Spec.Template.Spec.Containers { + if c.Name == "main" { + c.Image = "foo:v2" + } + dep.Spec.Template.Spec.Containers[i] = c + } + + By("computing the patch data") + data, err := patch.Data(dep) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning a patch with data containing the image change and the resourceVersion change") + Expect(data).To(Equal([]byte(fmt.Sprintf(`{"metadata":{"resourceVersion":"%s"},`+ + `"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"main"},{"name":"sidecar"}],"containers":[{"image":"foo:v2","name":"main"}]}}}}`, + dep.ResourceVersion)))) + }) + }) +}) + +var _ = Describe("IgnoreNotFound", func() { + It("should return nil on a 'NotFound' error", func() { + By("creating a NotFound error") + err := apierrors.NewNotFound(schema.GroupResource{}, "") + + By("returning no error") + Expect(client.IgnoreNotFound(err)).To(Succeed()) + }) + + It("should return the error on a status other than not found", func() { + By("creating a BadRequest error") + err := apierrors.NewBadRequest("") + + By("returning an error") + Expect(client.IgnoreNotFound(err)).To(HaveOccurred()) + }) + + It("should return the error on a non-status error", func() { + By("creating an fmt error") + err := fmt.Errorf("arbitrary error") + + By("returning an error") + Expect(client.IgnoreNotFound(err)).To(HaveOccurred()) + }) +}) + +var _ = Describe("IgnoreAlreadyExists", func() { + It("should return nil on a 'AlreadyExists' error", func() { + By("creating a AlreadyExists error") + err := apierrors.NewAlreadyExists(schema.GroupResource{}, "") + + By("returning no error") + Expect(client.IgnoreAlreadyExists(err)).To(Succeed()) + }) + + It("should return the error on a status other than already exists", func() { + By("creating a BadRequest error") + err := apierrors.NewBadRequest("") + + By("returning an error") + Expect(client.IgnoreAlreadyExists(err)).To(HaveOccurred()) + }) + + It("should return the error on a non-status error", func() { + By("creating an fmt error") + err := fmt.Errorf("arbitrary error") + + By("returning an error") + Expect(client.IgnoreAlreadyExists(err)).To(HaveOccurred()) + }) +}) + +type fakeReader struct { + Called int +} + +func (f *fakeReader) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + f.Called++ + return nil +} + +func (f *fakeReader) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + f.Called++ + return nil +} + +func ptr[T any](to T) *T { + return &to +} + +func toUnstructured(o client.Object) (*unstructured.Unstructured, error) { + serialized, err := json.Marshal(o) + if err != nil { + return nil, err + } + u := &unstructured.Unstructured{} + return u, json.Unmarshal(serialized, u) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/codec.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/codec.go new file mode 100644 index 00000000000..9c2923106c9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/codec.go @@ -0,0 +1,40 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "errors" + "net/url" + + "k8s.io/apimachinery/pkg/conversion/queryparams" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var _ runtime.ParameterCodec = noConversionParamCodec{} + +// noConversionParamCodec is a no-conversion codec for serializing parameters into URL query strings. +// it's useful in scenarios with the unstructured client and arbitrary resources. +type noConversionParamCodec struct{} + +func (noConversionParamCodec) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) { + return queryparams.Convert(obj) +} + +func (noConversionParamCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error { + return errors.New("DecodeParameters not implemented on noConversionParamCodec") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config.go new file mode 100644 index 00000000000..5f0a6d4b1dd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config.go @@ -0,0 +1,181 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "flag" + "fmt" + "os" + "os/user" + "path/filepath" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +// KubeconfigFlagName is the name of the kubeconfig flag +const KubeconfigFlagName = "kubeconfig" + +var ( + kubeconfig string + log = logf.RuntimeLog.WithName("client").WithName("config") +) + +// init registers the "kubeconfig" flag to the default command line FlagSet. +// TODO: This should be removed, as it potentially leads to redefined flag errors for users, if they already +// have registered the "kubeconfig" flag to the command line FlagSet in other parts of their code. +func init() { + RegisterFlags(flag.CommandLine) +} + +// RegisterFlags registers flag variables to the given FlagSet if not already registered. +// It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. +func RegisterFlags(fs *flag.FlagSet) { + if fs == nil { + fs = flag.CommandLine + } + if f := fs.Lookup(KubeconfigFlagName); f != nil { + kubeconfig = f.Value.String() + } else { + fs.StringVar(&kubeconfig, KubeconfigFlagName, "", "Paths to a kubeconfig. Only required if out-of-cluster.") + } +} + +// GetConfig creates a *rest.Config for talking to a Kubernetes API server. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// It also applies saner defaults for QPS and burst based on the Kubernetes +// controller manager defaults (20 QPS, 30 burst) +// +// Config precedence: +// +// * --kubeconfig flag pointing at a file +// +// * KUBECONFIG environment variable pointing at a file +// +// * In-cluster config if running in cluster +// +// * $HOME/.kube/config if exists. +func GetConfig() (*rest.Config, error) { + return GetConfigWithContext("") +} + +// GetConfigWithContext creates a *rest.Config for talking to a Kubernetes API server with a specific context. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// It also applies saner defaults for QPS and burst based on the Kubernetes +// controller manager defaults (20 QPS, 30 burst) +// +// Config precedence: +// +// * --kubeconfig flag pointing at a file +// +// * KUBECONFIG environment variable pointing at a file +// +// * In-cluster config if running in cluster +// +// * $HOME/.kube/config if exists. +func GetConfigWithContext(context string) (*rest.Config, error) { + cfg, err := loadConfig(context) + if err != nil { + return nil, err + } + if cfg.QPS == 0.0 { + cfg.QPS = 20.0 + } + if cfg.Burst == 0 { + cfg.Burst = 30 + } + return cfg, nil +} + +// loadInClusterConfig is a function used to load the in-cluster +// Kubernetes client config. This variable makes is possible to +// test the precedence of loading the config. +var loadInClusterConfig = rest.InClusterConfig + +// loadConfig loads a REST Config as per the rules specified in GetConfig. +func loadConfig(context string) (config *rest.Config, configErr error) { + // If a flag is specified with the config location, use that + if len(kubeconfig) > 0 { + return loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, context) + } + + // If the recommended kubeconfig env variable is not specified, + // try the in-cluster config. + kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar) + if len(kubeconfigPath) == 0 { + c, err := loadInClusterConfig() + if err == nil { + return c, nil + } + + defer func() { + if configErr != nil { + log.Error(err, "unable to load in-cluster config") + } + }() + } + + // If the recommended kubeconfig env variable is set, or there + // is no in-cluster config, try the default recommended locations. + // + // NOTE: For default config file locations, upstream only checks + // $HOME for the user's home directory, but we can also try + // os/user.HomeDir when $HOME is unset. + // + // TODO(jlanford): could this be done upstream? + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + if _, ok := os.LookupEnv("HOME"); !ok { + u, err := user.Current() + if err != nil { + return nil, fmt.Errorf("could not get current user: %w", err) + } + loadingRules.Precedence = append(loadingRules.Precedence, filepath.Join(u.HomeDir, clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName)) + } + + return loadConfigWithContext("", loadingRules, context) +} + +func loadConfigWithContext(apiServerURL string, loader clientcmd.ClientConfigLoader, context string) (*rest.Config, error) { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + loader, + &clientcmd.ConfigOverrides{ + ClusterInfo: clientcmdapi.Cluster{ + Server: apiServerURL, + }, + CurrentContext: context, + }).ClientConfig() +} + +// GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// Will log an error and exit if there is an error creating the rest.Config. +func GetConfigOrDie() *rest.Config { + config, err := GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + return config +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_suite_test.go new file mode 100644 index 00000000000..626613cef4f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_suite_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Client Config Test Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_test.go new file mode 100644 index 00000000000..058ff33c1ff --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/config_test.go @@ -0,0 +1,234 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "os" + "path/filepath" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +type testCase struct { + text string + context string + kubeconfigFlag string + kubeconfigEnv []string + wantHost string +} + +var _ = Describe("Config", func() { + + var dir string + + origRecommendedHomeFile := clientcmd.RecommendedHomeFile + + BeforeEach(func() { + // create temporary directory for test case + var err error + dir, err = os.MkdirTemp("", "cr-test") + Expect(err).NotTo(HaveOccurred()) + + // override $HOME/.kube/config + clientcmd.RecommendedHomeFile = filepath.Join(dir, ".kubeconfig") + }) + + AfterEach(func() { + os.Unsetenv(clientcmd.RecommendedConfigPathEnvVar) + kubeconfig = "" + clientcmd.RecommendedHomeFile = origRecommendedHomeFile + + err := os.RemoveAll(dir) + Expect(err).NotTo(HaveOccurred()) + }) + + Describe("GetConfigWithContext", func() { + defineTests := func(testCases []testCase) { + for _, testCase := range testCases { + tc := testCase + It(tc.text, func() { + // set global and environment configs + setConfigs(tc, dir) + + // run the test + cfg, err := GetConfigWithContext(tc.context) + Expect(err).NotTo(HaveOccurred()) + Expect(cfg.Host).To(Equal(tc.wantHost)) + }) + } + } + + Context("when kubeconfig files don't exist", func() { + It("should fail", func() { + err := os.Unsetenv(clientcmd.RecommendedConfigPathEnvVar) + Expect(err).NotTo(HaveOccurred()) + + cfg, err := GetConfigWithContext("") + Expect(cfg).To(BeNil()) + Expect(err).To(HaveOccurred()) + }) + }) + + Context("when in-cluster", func() { + kubeconfigFiles := map[string]string{ + "kubeconfig-multi-context": genKubeconfig("from-multi-env-1", "from-multi-env-2"), + ".kubeconfig": genKubeconfig("from-home"), + } + BeforeEach(func() { + err := createFiles(kubeconfigFiles, dir) + Expect(err).NotTo(HaveOccurred()) + + // override in-cluster config loader + loadInClusterConfig = func() (*rest.Config, error) { + return &rest.Config{Host: "from-in-cluster"}, nil + } + }) + AfterEach(func() { loadInClusterConfig = rest.InClusterConfig }) + + testCases := []testCase{ + { + text: "should prefer the envvar over the in-cluster config", + kubeconfigEnv: []string{"kubeconfig-multi-context"}, + wantHost: "from-multi-env-1", + }, + { + text: "should prefer in-cluster over the recommended home file", + wantHost: "from-in-cluster", + }, + } + defineTests(testCases) + }) + + Context("when outside the cluster", func() { + kubeconfigFiles := map[string]string{ + "kubeconfig-flag": genKubeconfig("from-flag"), + "kubeconfig-multi-context": genKubeconfig("from-multi-env-1", "from-multi-env-2"), + "kubeconfig-env-1": genKubeconfig("from-env-1"), + "kubeconfig-env-2": genKubeconfig("from-env-2"), + ".kubeconfig": genKubeconfig("from-home"), + } + BeforeEach(func() { + err := createFiles(kubeconfigFiles, dir) + Expect(err).NotTo(HaveOccurred()) + }) + testCases := []testCase{ + { + text: "should use the --kubeconfig flag", + kubeconfigFlag: "kubeconfig-flag", + wantHost: "from-flag", + }, + { + text: "should use the envvar", + kubeconfigEnv: []string{"kubeconfig-multi-context"}, + wantHost: "from-multi-env-1", + }, + { + text: "should use the recommended home file", + wantHost: "from-home", + }, + { + text: "should prefer the flag over the envvar", + kubeconfigFlag: "kubeconfig-flag", + kubeconfigEnv: []string{"kubeconfig-multi-context"}, + wantHost: "from-flag", + }, + { + text: "should prefer the envvar over the recommended home file", + kubeconfigEnv: []string{"kubeconfig-multi-context"}, + wantHost: "from-multi-env-1", + }, + { + text: "should allow overriding the context", + context: "from-multi-env-2", + kubeconfigEnv: []string{"kubeconfig-multi-context"}, + wantHost: "from-multi-env-2", + }, + { + text: "should support a multi-value envvar", + context: "from-env-2", + kubeconfigEnv: []string{"kubeconfig-env-1", "kubeconfig-env-2"}, + wantHost: "from-env-2", + }, + } + defineTests(testCases) + }) + }) +}) + +func setConfigs(tc testCase, dir string) { + // Set kubeconfig flag value + if len(tc.kubeconfigFlag) > 0 { + kubeconfig = filepath.Join(dir, tc.kubeconfigFlag) + } + + // Set KUBECONFIG env value + if len(tc.kubeconfigEnv) > 0 { + kubeconfigEnvPaths := []string{} + for _, k := range tc.kubeconfigEnv { + kubeconfigEnvPaths = append(kubeconfigEnvPaths, filepath.Join(dir, k)) + } + os.Setenv(clientcmd.RecommendedConfigPathEnvVar, strings.Join(kubeconfigEnvPaths, ":")) + } +} + +func createFiles(files map[string]string, dir string) error { + for path, data := range files { + if err := os.WriteFile(filepath.Join(dir, path), []byte(data), 0644); err != nil { //nolint:gosec + return err + } + } + return nil +} + +func genKubeconfig(contexts ...string) string { + var sb strings.Builder + sb.WriteString(`--- +apiVersion: v1 +kind: Config +clusters: +`) + for _, ctx := range contexts { + sb.WriteString(`- cluster: + server: ` + ctx + ` + name: ` + ctx + ` +`) + } + sb.WriteString("contexts:\n") + for _, ctx := range contexts { + sb.WriteString(`- context: + cluster: ` + ctx + ` + user: ` + ctx + ` + name: ` + ctx + ` +`) + } + + sb.WriteString("users:\n") + for _, ctx := range contexts { + sb.WriteString(`- name: ` + ctx + ` +`) + } + sb.WriteString("preferences: {}\n") + if len(contexts) > 0 { + sb.WriteString("current-context: " + contexts[0] + "\n") + } + + return sb.String() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go new file mode 100644 index 00000000000..796c9cf590b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package config contains libraries for initializing REST configs for talking to the Kubernetes API +package config diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/doc.go new file mode 100644 index 00000000000..b2e20249428 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/doc.go @@ -0,0 +1,49 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package client contains functionality for interacting with Kubernetes API +// servers. +// +// # Clients +// +// Clients are split into two interfaces -- Readers and Writers. Readers +// get and list, while writers create, update, and delete. +// +// The New function can be used to create a new client that talks directly +// to the API server. +// +// It is a common pattern in Kubernetes to read from a cache and write to the API +// server. This pattern is covered by the creating the Client with a Cache. +// +// # Options +// +// Many client operations in Kubernetes support options. These options are +// represented as variadic arguments at the end of a given method call. +// For instance, to use a label selector on list, you can call +// +// err := someReader.List(context.Background(), &podList, client.MatchingLabels{"somelabel": "someval"}) +// +// # Indexing +// +// Indexes may be added to caches using a FieldIndexer. This allows you to easily +// and efficiently look up objects with certain properties. You can then make +// use of the index by specifying a field selector on calls to List on the Reader +// corresponding to the given Cache. +// +// For instance, a Secret controller might have an index on the +// `.spec.volumes.secret.secretName` field in Pod objects, so that it could +// easily look up all pods that reference a given secret. +package client diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go new file mode 100644 index 00000000000..bbcdd383215 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go @@ -0,0 +1,130 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NewDryRunClient wraps an existing client and enforces DryRun mode +// on all mutating api calls. +func NewDryRunClient(c Client) Client { + return &dryRunClient{client: c} +} + +var _ Client = &dryRunClient{} + +// dryRunClient is a Client that wraps another Client in order to enforce DryRun mode. +type dryRunClient struct { + client Client +} + +// Scheme returns the scheme this client is using. +func (c *dryRunClient) Scheme() *runtime.Scheme { + return c.client.Scheme() +} + +// RESTMapper returns the rest mapper this client is using. +func (c *dryRunClient) RESTMapper() meta.RESTMapper { + return c.client.RESTMapper() +} + +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *dryRunClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return c.client.GroupVersionKindFor(obj) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *dryRunClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return c.client.IsObjectNamespaced(obj) +} + +// Create implements client.Client. +func (c *dryRunClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { + return c.client.Create(ctx, obj, append(opts, DryRunAll)...) +} + +// Update implements client.Client. +func (c *dryRunClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { + return c.client.Update(ctx, obj, append(opts, DryRunAll)...) +} + +// Delete implements client.Client. +func (c *dryRunClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + return c.client.Delete(ctx, obj, append(opts, DryRunAll)...) +} + +// DeleteAllOf implements client.Client. +func (c *dryRunClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + return c.client.DeleteAllOf(ctx, obj, append(opts, DryRunAll)...) +} + +// Patch implements client.Client. +func (c *dryRunClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + return c.client.Patch(ctx, obj, patch, append(opts, DryRunAll)...) +} + +// Get implements client.Client. +func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + return c.client.Get(ctx, key, obj, opts...) +} + +// List implements client.Client. +func (c *dryRunClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + return c.client.List(ctx, obj, opts...) +} + +// Status implements client.StatusClient. +func (c *dryRunClient) Status() SubResourceWriter { + return c.SubResource("status") +} + +// SubResource implements client.SubResourceClient. +func (c *dryRunClient) SubResource(subResource string) SubResourceClient { + return &dryRunSubResourceClient{client: c.client.SubResource(subResource)} +} + +// ensure dryRunSubResourceWriter implements client.SubResourceWriter. +var _ SubResourceWriter = &dryRunSubResourceClient{} + +// dryRunSubResourceClient is client.SubResourceWriter that writes status subresource with dryRun mode +// enforced. +type dryRunSubResourceClient struct { + client SubResourceClient +} + +func (sw *dryRunSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error { + return sw.client.Get(ctx, obj, subResource, opts...) +} + +func (sw *dryRunSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error { + return sw.client.Create(ctx, obj, subResource, append(opts, DryRunAll)...) +} + +// Update implements client.SubResourceWriter. +func (sw *dryRunSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { + return sw.client.Update(ctx, obj, append(opts, DryRunAll)...) +} + +// Patch implements client.SubResourceWriter. +func (sw *dryRunSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { + return sw.client.Patch(ctx, obj, patch, append(opts, DryRunAll)...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun_test.go new file mode 100644 index 00000000000..72907fefabe --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/dryrun_test.go @@ -0,0 +1,265 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "context" + "fmt" + "sync/atomic" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("DryRunClient", func() { + var dep *appsv1.Deployment + var count uint64 = 0 + var replicaCount int32 = 2 + var ns = "default" + ctx := context.Background() + + getClient := func() client.Client { + cl, err := client.New(cfg, client.Options{DryRun: pointer.Bool(true)}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + return cl + } + + BeforeEach(func() { + atomic.AddUint64(&count, 1) + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("dry-run-deployment-%v", count), + Namespace: ns, + Labels: map[string]string{"name": fmt.Sprintf("dry-run-deployment-%v", count)}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + + var err error + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should successfully Get an object", func() { + name := types.NamespacedName{Namespace: ns, Name: dep.Name} + result := &appsv1.Deployment{} + + Expect(getClient().Get(ctx, name, result)).NotTo(HaveOccurred()) + Expect(result).To(BeEquivalentTo(dep)) + }) + + It("should successfully List objects", func() { + result := &appsv1.DeploymentList{} + opts := client.MatchingLabels(dep.Labels) + + Expect(getClient().List(ctx, result, opts)).NotTo(HaveOccurred()) + + Expect(len(result.Items)).To(BeEquivalentTo(1)) + Expect(result.Items[0]).To(BeEquivalentTo(*dep)) + }) + + It("should not create an object", func() { + newDep := dep.DeepCopy() + newDep.Name = "new-deployment" + + Expect(getClient().Create(ctx, newDep)).ToNot(HaveOccurred()) + + _, err := clientset.AppsV1().Deployments(ns).Get(ctx, newDep.Name, metav1.GetOptions{}) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should not create an object with opts", func() { + newDep := dep.DeepCopy() + newDep.Name = "new-deployment" + opts := &client.CreateOptions{DryRun: []string{"Bye", "Pippa"}} + + Expect(getClient().Create(ctx, newDep, opts)).ToNot(HaveOccurred()) + + _, err := clientset.AppsV1().Deployments(ns).Get(ctx, newDep.Name, metav1.GetOptions{}) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should refuse a create request for an invalid object", func() { + changedDep := dep.DeepCopy() + changedDep.Spec.Template.Spec.Containers = nil + + err := getClient().Create(ctx, changedDep) + Expect(apierrors.IsInvalid(err)).To(BeTrue()) + }) + + It("should not change objects via update", func() { + changedDep := dep.DeepCopy() + *changedDep.Spec.Replicas = 2 + + Expect(getClient().Update(ctx, changedDep)).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via update with opts", func() { + changedDep := dep.DeepCopy() + *changedDep.Spec.Replicas = 2 + opts := &client.UpdateOptions{DryRun: []string{"Bye", "Pippa"}} + + Expect(getClient().Update(ctx, changedDep, opts)).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should refuse an update request for an invalid change", func() { + changedDep := dep.DeepCopy() + changedDep.Spec.Template.Spec.Containers = nil + + err := getClient().Update(ctx, changedDep) + Expect(apierrors.IsInvalid(err)).To(BeTrue()) + }) + + It("should not change objects via patch", func() { + changedDep := dep.DeepCopy() + *changedDep.Spec.Replicas = 2 + + Expect(getClient().Patch(ctx, changedDep, client.MergeFrom(dep))).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via patch with opts", func() { + changedDep := dep.DeepCopy() + *changedDep.Spec.Replicas = 2 + opts := &client.PatchOptions{DryRun: []string{"Bye", "Pippa"}} + + Expect(getClient().Patch(ctx, changedDep, client.MergeFrom(dep), opts)).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not delete objects", func() { + Expect(getClient().Delete(ctx, dep)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not delete objects with opts", func() { + opts := &client.DeleteOptions{DryRun: []string{"Bye", "Pippa"}} + + Expect(getClient().Delete(ctx, dep, opts)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not delete objects via deleteAllOf", func() { + opts := []client.DeleteAllOfOption{client.InNamespace(ns), client.MatchingLabels(dep.Labels)} + + Expect(getClient().DeleteAllOf(ctx, dep, opts...)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via update status", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + + Expect(getClient().Status().Update(ctx, changedDep)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via update status with opts", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + opts := &client.SubResourceUpdateOptions{UpdateOptions: client.UpdateOptions{DryRun: []string{"Bye", "Pippa"}}} + + Expect(getClient().Status().Update(ctx, changedDep, opts)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via status patch", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + + Expect(getClient().Status().Patch(ctx, changedDep, client.MergeFrom(dep))).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) + + It("should not change objects via status patch with opts", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + + opts := &client.SubResourcePatchOptions{PatchOptions: client.PatchOptions{DryRun: []string{"Bye", "Pippa"}}} + + Expect(getClient().Status().Patch(ctx, changedDep, client.MergeFrom(dep), opts)).ToNot(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual).To(BeEquivalentTo(dep)) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/example_test.go new file mode 100644 index 00000000000..7d4cb8c6163 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/example_test.go @@ -0,0 +1,268 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "context" + "fmt" + "os" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/config" +) + +var ( + c client.Client + someIndexer client.FieldIndexer +) + +func ExampleNew() { + cl, err := client.New(config.GetConfigOrDie(), client.Options{}) + if err != nil { + fmt.Println("failed to create client") + os.Exit(1) + } + + podList := &corev1.PodList{} + + err = cl.List(context.Background(), podList, client.InNamespace("default")) + if err != nil { + fmt.Printf("failed to list pods in namespace default: %v\n", err) + os.Exit(1) + } +} + +// This example shows how to use the client with typed and unstructured objects to retrieve an object. +func ExampleClient_get() { + // Using a typed object. + pod := &corev1.Pod{} + // c is a created client. + _ = c.Get(context.Background(), client.ObjectKey{ + Namespace: "namespace", + Name: "name", + }, pod) + + // Using a unstructured object. + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + _ = c.Get(context.Background(), client.ObjectKey{ + Namespace: "namespace", + Name: "name", + }, u) +} + +// This example shows how to use the client with typed and unstructured objects to create objects. +func ExampleClient_create() { + // Using a typed object. + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "namespace", + Name: "name", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Image: "nginx", + Name: "nginx", + }, + }, + }, + } + // c is a created client. + _ = c.Create(context.Background(), pod) + + // Using a unstructured object. + u := &unstructured.Unstructured{} + u.Object = map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "name", + "namespace": "namespace", + }, + "spec": map[string]interface{}{ + "replicas": 2, + "selector": map[string]interface{}{ + "matchLabels": map[string]interface{}{ + "foo": "bar", + }, + }, + "template": map[string]interface{}{ + "labels": map[string]interface{}{ + "foo": "bar", + }, + "spec": map[string]interface{}{ + "containers": []map[string]interface{}{ + { + "name": "nginx", + "image": "nginx", + }, + }, + }, + }, + }, + } + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + _ = c.Create(context.Background(), u) +} + +// This example shows how to use the client with typed and unstructured objects to list objects. +func ExampleClient_list() { + // Using a typed object. + pod := &corev1.PodList{} + // c is a created client. + _ = c.List(context.Background(), pod) + + // Using a unstructured object. + u := &unstructured.UnstructuredList{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "DeploymentList", + Version: "v1", + }) + _ = c.List(context.Background(), u) +} + +// This example shows how to use the client with typed and unstructured objects to update objects. +func ExampleClient_update() { + // Using a typed object. + pod := &corev1.Pod{} + // c is a created client. + _ = c.Get(context.Background(), client.ObjectKey{ + Namespace: "namespace", + Name: "name", + }, pod) + pod.SetFinalizers(append(pod.GetFinalizers(), "new-finalizer")) + _ = c.Update(context.Background(), pod) + + // Using a unstructured object. + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + _ = c.Get(context.Background(), client.ObjectKey{ + Namespace: "namespace", + Name: "name", + }, u) + u.SetFinalizers(append(u.GetFinalizers(), "new-finalizer")) + _ = c.Update(context.Background(), u) +} + +// This example shows how to use the client with typed and unstructured objects to patch objects. +func ExampleClient_patch() { + patch := []byte(`{"metadata":{"annotations":{"version": "v2"}}}`) + _ = c.Patch(context.Background(), &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "namespace", + Name: "name", + }, + }, client.RawPatch(types.StrategicMergePatchType, patch)) +} + +// This example shows how to use the client with typed and unstructured objects to patch objects' status. +func ExampleClient_patchStatus() { + u := &unstructured.Unstructured{} + u.Object = map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "foo", + "namespace": "namespace", + }, + } + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "batch", + Version: "v1beta1", + Kind: "CronJob", + }) + patch := []byte(fmt.Sprintf(`{"status":{"lastScheduleTime":"%s"}}`, time.Now().Format(time.RFC3339))) + _ = c.Status().Patch(context.Background(), u, client.RawPatch(types.MergePatchType, patch)) +} + +// This example shows how to use the client with typed and unstructured objects to delete objects. +func ExampleClient_delete() { + // Using a typed object. + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "namespace", + Name: "name", + }, + } + // c is a created client. + _ = c.Delete(context.Background(), pod) + + // Using a unstructured object. + u := &unstructured.Unstructured{} + u.SetName("name") + u.SetNamespace("namespace") + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + _ = c.Delete(context.Background(), u) +} + +// This example shows how to use the client with typed and unstructured objects to delete collections of objects. +func ExampleClient_deleteAllOf() { + // Using a typed object. + // c is a created client. + _ = c.DeleteAllOf(context.Background(), &corev1.Pod{}, client.InNamespace("foo"), client.MatchingLabels{"app": "foo"}) + + // Using an unstructured Object + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + _ = c.DeleteAllOf(context.Background(), u, client.InNamespace("foo"), client.MatchingLabels{"app": "foo"}) +} + +// This example shows how to set up and consume a field selector over a pod's volumes' secretName field. +func ExampleFieldIndexer_secretName() { + // someIndexer is a FieldIndexer over a Cache + _ = someIndexer.IndexField(context.TODO(), &corev1.Pod{}, "spec.volumes.secret.secretName", func(o client.Object) []string { + var res []string + for _, vol := range o.(*corev1.Pod).Spec.Volumes { + if vol.Secret == nil { + continue + } + // just return the raw field value -- the indexer will take care of dealing with namespaces for us + res = append(res, vol.Secret.SecretName) + } + return res + }) + + // elsewhere (e.g. in your reconciler) + mySecretName := "someSecret" // derived from the reconcile.Request, for instance + var podsWithSecrets corev1.PodList + _ = c.List(context.Background(), &podsWithSecrets, client.MatchingFields{"spec.volumes.secret.secretName": mySecretName}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go new file mode 100644 index 00000000000..7167c5505ec --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go @@ -0,0 +1,1283 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "reflect" + "runtime/debug" + "strconv" + "strings" + "sync" + "time" + + // Using v4 to match upstream + jsonpatch "github.com/evanphx/json-patch" + "sigs.k8s.io/controller-runtime/pkg/client/interceptor" + + corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + utilrand "k8s.io/apimachinery/pkg/util/rand" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/testing" + "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/internal/objectutil" +) + +type versionedTracker struct { + testing.ObjectTracker + scheme *runtime.Scheme + withStatusSubresource sets.Set[schema.GroupVersionKind] +} + +type fakeClient struct { + tracker versionedTracker + scheme *runtime.Scheme + restMapper meta.RESTMapper + withStatusSubresource sets.Set[schema.GroupVersionKind] + + // indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK. + // The inner map maps from index name to IndexerFunc. + indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc + + schemeWriteLock sync.Mutex +} + +var _ client.WithWatch = &fakeClient{} + +const ( + maxNameLength = 63 + randomLength = 5 + maxGeneratedNameLength = maxNameLength - randomLength +) + +// NewFakeClient creates a new fake client for testing. +// You can choose to initialize it with a slice of runtime.Object. +// +// Deprecated: Please use NewClientBuilder instead. +func NewFakeClient(initObjs ...runtime.Object) client.WithWatch { + return NewClientBuilder().WithRuntimeObjects(initObjs...).Build() +} + +// NewFakeClientWithScheme creates a new fake client with the given scheme +// for testing. +// You can choose to initialize it with a slice of runtime.Object. +// +// Deprecated: Please use NewClientBuilder instead. +func NewFakeClientWithScheme(clientScheme *runtime.Scheme, initObjs ...runtime.Object) client.WithWatch { + return NewClientBuilder().WithScheme(clientScheme).WithRuntimeObjects(initObjs...).Build() +} + +// NewClientBuilder returns a new builder to create a fake client. +func NewClientBuilder() *ClientBuilder { + return &ClientBuilder{} +} + +// ClientBuilder builds a fake client. +type ClientBuilder struct { + scheme *runtime.Scheme + restMapper meta.RESTMapper + initObject []client.Object + initLists []client.ObjectList + initRuntimeObjects []runtime.Object + withStatusSubresource []client.Object + objectTracker testing.ObjectTracker + interceptorFuncs *interceptor.Funcs + + // indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK. + // The inner map maps from index name to IndexerFunc. + indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc +} + +// WithScheme sets this builder's internal scheme. +// If not set, defaults to client-go's global scheme.Scheme. +func (f *ClientBuilder) WithScheme(scheme *runtime.Scheme) *ClientBuilder { + f.scheme = scheme + return f +} + +// WithRESTMapper sets this builder's restMapper. +// The restMapper is directly set as mapper in the Client. This can be used for example +// with a meta.DefaultRESTMapper to provide a static rest mapping. +// If not set, defaults to an empty meta.DefaultRESTMapper. +func (f *ClientBuilder) WithRESTMapper(restMapper meta.RESTMapper) *ClientBuilder { + f.restMapper = restMapper + return f +} + +// WithObjects can be optionally used to initialize this fake client with client.Object(s). +func (f *ClientBuilder) WithObjects(initObjs ...client.Object) *ClientBuilder { + f.initObject = append(f.initObject, initObjs...) + return f +} + +// WithLists can be optionally used to initialize this fake client with client.ObjectList(s). +func (f *ClientBuilder) WithLists(initLists ...client.ObjectList) *ClientBuilder { + f.initLists = append(f.initLists, initLists...) + return f +} + +// WithRuntimeObjects can be optionally used to initialize this fake client with runtime.Object(s). +func (f *ClientBuilder) WithRuntimeObjects(initRuntimeObjs ...runtime.Object) *ClientBuilder { + f.initRuntimeObjects = append(f.initRuntimeObjects, initRuntimeObjs...) + return f +} + +// WithObjectTracker can be optionally used to initialize this fake client with testing.ObjectTracker. +func (f *ClientBuilder) WithObjectTracker(ot testing.ObjectTracker) *ClientBuilder { + f.objectTracker = ot + return f +} + +// WithIndex can be optionally used to register an index with name `field` and indexer `extractValue` +// for API objects of the same GroupVersionKind (GVK) as `obj` in the fake client. +// It can be invoked multiple times, both with objects of the same GVK or different ones. +// Invoking WithIndex twice with the same `field` and GVK (via `obj`) arguments will panic. +// WithIndex retrieves the GVK of `obj` using the scheme registered via WithScheme if +// WithScheme was previously invoked, the default scheme otherwise. +func (f *ClientBuilder) WithIndex(obj runtime.Object, field string, extractValue client.IndexerFunc) *ClientBuilder { + objScheme := f.scheme + if objScheme == nil { + objScheme = scheme.Scheme + } + + gvk, err := apiutil.GVKForObject(obj, objScheme) + if err != nil { + panic(err) + } + + // If this is the first index being registered, we initialize the map storing all the indexes. + if f.indexes == nil { + f.indexes = make(map[schema.GroupVersionKind]map[string]client.IndexerFunc) + } + + // If this is the first index being registered for the GroupVersionKind of `obj`, we initialize + // the map storing the indexes for that GroupVersionKind. + if f.indexes[gvk] == nil { + f.indexes[gvk] = make(map[string]client.IndexerFunc) + } + + if _, fieldAlreadyIndexed := f.indexes[gvk][field]; fieldAlreadyIndexed { + panic(fmt.Errorf("indexer conflict: field %s for GroupVersionKind %v is already indexed", + field, gvk)) + } + + f.indexes[gvk][field] = extractValue + + return f +} + +// WithStatusSubresource configures the passed object with a status subresource, which means +// calls to Update and Patch will not alter its status. +func (f *ClientBuilder) WithStatusSubresource(o ...client.Object) *ClientBuilder { + f.withStatusSubresource = append(f.withStatusSubresource, o...) + return f +} + +// WithInterceptorFuncs configures the client methods to be intercepted using the provided interceptor.Funcs. +func (f *ClientBuilder) WithInterceptorFuncs(interceptorFuncs interceptor.Funcs) *ClientBuilder { + f.interceptorFuncs = &interceptorFuncs + return f +} + +// Build builds and returns a new fake client. +func (f *ClientBuilder) Build() client.WithWatch { + if f.scheme == nil { + f.scheme = scheme.Scheme + } + if f.restMapper == nil { + f.restMapper = meta.NewDefaultRESTMapper([]schema.GroupVersion{}) + } + + var tracker versionedTracker + + withStatusSubResource := sets.New(inTreeResourcesWithStatus()...) + for _, o := range f.withStatusSubresource { + gvk, err := apiutil.GVKForObject(o, f.scheme) + if err != nil { + panic(fmt.Errorf("failed to get gvk for object %T: %w", withStatusSubResource, err)) + } + withStatusSubResource.Insert(gvk) + } + + if f.objectTracker == nil { + tracker = versionedTracker{ObjectTracker: testing.NewObjectTracker(f.scheme, scheme.Codecs.UniversalDecoder()), scheme: f.scheme, withStatusSubresource: withStatusSubResource} + } else { + tracker = versionedTracker{ObjectTracker: f.objectTracker, scheme: f.scheme, withStatusSubresource: withStatusSubResource} + } + + for _, obj := range f.initObject { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add object %v to fake client: %w", obj, err)) + } + } + for _, obj := range f.initLists { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add list %v to fake client: %w", obj, err)) + } + } + for _, obj := range f.initRuntimeObjects { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add runtime object %v to fake client: %w", obj, err)) + } + } + + var result client.WithWatch = &fakeClient{ + tracker: tracker, + scheme: f.scheme, + restMapper: f.restMapper, + indexes: f.indexes, + withStatusSubresource: withStatusSubResource, + } + + if f.interceptorFuncs != nil { + result = interceptor.NewClient(result, *f.interceptorFuncs) + } + + return result +} + +const trackerAddResourceVersion = "999" + +func (t versionedTracker) Add(obj runtime.Object) error { + var objects []runtime.Object + if meta.IsListType(obj) { + var err error + objects, err = meta.ExtractList(obj) + if err != nil { + return err + } + } else { + objects = []runtime.Object{obj} + } + for _, obj := range objects { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + if accessor.GetDeletionTimestamp() != nil && len(accessor.GetFinalizers()) == 0 { + return fmt.Errorf("refusing to create obj %s with metadata.deletionTimestamp but no finalizers", accessor.GetName()) + } + if accessor.GetResourceVersion() == "" { + // We use a "magic" value of 999 here because this field + // is parsed as uint and and 0 is already used in Update. + // As we can't go lower, go very high instead so this can + // be recognized + accessor.SetResourceVersion(trackerAddResourceVersion) + } + + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + if err := t.ObjectTracker.Add(obj); err != nil { + return err + } + } + + return nil +} + +func (t versionedTracker) Create(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + if accessor.GetName() == "" { + return apierrors.NewInvalid( + obj.GetObjectKind().GroupVersionKind().GroupKind(), + accessor.GetName(), + field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")}) + } + if accessor.GetResourceVersion() != "" { + return apierrors.NewBadRequest("resourceVersion can not be set for Create requests") + } + accessor.SetResourceVersion("1") + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + if err := t.ObjectTracker.Create(gvr, obj, ns); err != nil { + accessor.SetResourceVersion("") + return err + } + + return nil +} + +// convertFromUnstructuredIfNecessary will convert runtime.Unstructured for a GVK that is recognized +// by the schema into the whatever the schema produces with New() for said GVK. +// This is required because the tracker unconditionally saves on manipulations, but its List() implementation +// tries to assign whatever it finds into a ListType it gets from schema.New() - Thus we have to ensure +// we save as the very same type, otherwise subsequent List requests will fail. +func convertFromUnstructuredIfNecessary(s *runtime.Scheme, o runtime.Object) (runtime.Object, error) { + gvk := o.GetObjectKind().GroupVersionKind() + + u, isUnstructured := o.(runtime.Unstructured) + if !isUnstructured || !s.Recognizes(gvk) { + return o, nil + } + + typed, err := s.New(gvk) + if err != nil { + return nil, fmt.Errorf("scheme recognizes %s but failed to produce an object for it: %w", gvk, err) + } + + unstructuredSerialized, err := json.Marshal(u) + if err != nil { + return nil, fmt.Errorf("failed to serialize %T: %w", unstructuredSerialized, err) + } + if err := json.Unmarshal(unstructuredSerialized, typed); err != nil { + return nil, fmt.Errorf("failed to unmarshal the content of %T into %T: %w", u, typed, err) + } + + return typed, nil +} + +func (t versionedTracker) Update(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + isStatus := false + // We apply patches using a client-go reaction that ends up calling the trackers Update. As we can't change + // that reaction, we use the callstack to figure out if this originated from the status client. + if bytes.Contains(debug.Stack(), []byte("sigs.k8s.io/controller-runtime/pkg/client/fake.(*fakeSubResourceClient).Patch")) { + isStatus = true + } + return t.update(gvr, obj, ns, isStatus, false) +} + +func (t versionedTracker) update(gvr schema.GroupVersionResource, obj runtime.Object, ns string, isStatus bool, deleting bool) error { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + + if accessor.GetName() == "" { + return apierrors.NewInvalid( + obj.GetObjectKind().GroupVersionKind().GroupKind(), + accessor.GetName(), + field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")}) + } + + gvk := obj.GetObjectKind().GroupVersionKind() + if gvk.Empty() { + gvk, err = apiutil.GVKForObject(obj, t.scheme) + if err != nil { + return err + } + } + + oldObject, err := t.ObjectTracker.Get(gvr, ns, accessor.GetName()) + if err != nil { + // If the resource is not found and the resource allows create on update, issue a + // create instead. + if apierrors.IsNotFound(err) && allowsCreateOnUpdate(gvk) { + return t.Create(gvr, obj, ns) + } + return err + } + + if t.withStatusSubresource.Has(gvk) { + if isStatus { // copy everything but status and metadata.ResourceVersion from original object + if err := copyNonStatusFrom(oldObject, obj); err != nil { + return fmt.Errorf("failed to copy non-status field for object with status subresouce: %w", err) + } + } else { // copy status from original object + if err := copyStatusFrom(oldObject, obj); err != nil { + return fmt.Errorf("failed to copy the status for object with status subresource: %w", err) + } + } + } else if isStatus { + return apierrors.NewNotFound(gvr.GroupResource(), accessor.GetName()) + } + + oldAccessor, err := meta.Accessor(oldObject) + if err != nil { + return err + } + + // If the new object does not have the resource version set and it allows unconditional update, + // default it to the resource version of the existing resource + if accessor.GetResourceVersion() == "" && allowsUnconditionalUpdate(gvk) { + accessor.SetResourceVersion(oldAccessor.GetResourceVersion()) + } + if accessor.GetResourceVersion() != oldAccessor.GetResourceVersion() { + return apierrors.NewConflict(gvr.GroupResource(), accessor.GetName(), errors.New("object was modified")) + } + if oldAccessor.GetResourceVersion() == "" { + oldAccessor.SetResourceVersion("0") + } + intResourceVersion, err := strconv.ParseUint(oldAccessor.GetResourceVersion(), 10, 64) + if err != nil { + return fmt.Errorf("can not convert resourceVersion %q to int: %w", oldAccessor.GetResourceVersion(), err) + } + intResourceVersion++ + accessor.SetResourceVersion(strconv.FormatUint(intResourceVersion, 10)) + + if !deleting && !deletionTimestampEqual(accessor, oldAccessor) { + return fmt.Errorf("error: Unable to edit %s: metadata.deletionTimestamp field is immutable", accessor.GetName()) + } + + if !accessor.GetDeletionTimestamp().IsZero() && len(accessor.GetFinalizers()) == 0 { + return t.ObjectTracker.Delete(gvr, accessor.GetNamespace(), accessor.GetName()) + } + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + return t.ObjectTracker.Update(gvr, obj, ns) +} + +func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + o, err := c.tracker.Get(gvr, key.Namespace, key.Name) + if err != nil { + return err + } + + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(gvk.Kind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + return err +} + +func (c *fakeClient) Watch(ctx context.Context, list client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + gvk, err := apiutil.GVKForObject(list, c.scheme) + if err != nil { + return nil, err + } + + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + return c.tracker.Watch(gvr, listOpts.Namespace) +} + +func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + originalKind := gvk.Kind + + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + if _, isUnstructuredList := obj.(runtime.Unstructured); isUnstructuredList && !c.scheme.Recognizes(gvk) { + // We need to register the ListKind with UnstructuredList: + // https://github.com/kubernetes/kubernetes/blob/7b2776b89fb1be28d4e9203bdeec079be903c103/staging/src/k8s.io/client-go/dynamic/fake/simple.go#L44-L51 + c.schemeWriteLock.Lock() + c.scheme.AddKnownTypeWithName(gvk.GroupVersion().WithKind(gvk.Kind+"List"), &unstructured.UnstructuredList{}) + c.schemeWriteLock.Unlock() + } + + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + o, err := c.tracker.List(gvr, gvk, listOpts.Namespace) + if err != nil { + return err + } + + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(originalKind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + if err != nil { + return err + } + + if listOpts.LabelSelector == nil && listOpts.FieldSelector == nil { + return nil + } + + // If we're here, either a label or field selector are specified (or both), so before we return + // the list we must filter it. If both selectors are set, they are ANDed. + objs, err := meta.ExtractList(obj) + if err != nil { + return err + } + + filteredList, err := c.filterList(objs, gvk, listOpts.LabelSelector, listOpts.FieldSelector) + if err != nil { + return err + } + + return meta.SetList(obj, filteredList) +} + +func (c *fakeClient) filterList(list []runtime.Object, gvk schema.GroupVersionKind, ls labels.Selector, fs fields.Selector) ([]runtime.Object, error) { + // Filter the objects with the label selector + filteredList := list + if ls != nil { + objsFilteredByLabel, err := objectutil.FilterWithLabels(list, ls) + if err != nil { + return nil, err + } + filteredList = objsFilteredByLabel + } + + // Filter the result of the previous pass with the field selector + if fs != nil { + objsFilteredByField, err := c.filterWithFields(filteredList, gvk, fs) + if err != nil { + return nil, err + } + filteredList = objsFilteredByField + } + + return filteredList, nil +} + +func (c *fakeClient) filterWithFields(list []runtime.Object, gvk schema.GroupVersionKind, fs fields.Selector) ([]runtime.Object, error) { + // We only allow filtering on the basis of a single field to ensure consistency with the + // behavior of the cache reader (which we're faking here). + fieldKey, fieldVal, requiresExact := selector.RequiresExactMatch(fs) + if !requiresExact { + return nil, fmt.Errorf("field selector %s is not in one of the two supported forms \"key==val\" or \"key=val\"", + fs) + } + + // Field selection is mimicked via indexes, so there's no sane answer this function can give + // if there are no indexes registered for the GroupVersionKind of the objects in the list. + indexes := c.indexes[gvk] + if len(indexes) == 0 || indexes[fieldKey] == nil { + return nil, fmt.Errorf("List on GroupVersionKind %v specifies selector on field %s, but no "+ + "index with name %s has been registered for GroupVersionKind %v", gvk, fieldKey, fieldKey, gvk) + } + + indexExtractor := indexes[fieldKey] + filteredList := make([]runtime.Object, 0, len(list)) + for _, obj := range list { + if c.objMatchesFieldSelector(obj, indexExtractor, fieldVal) { + filteredList = append(filteredList, obj) + } + } + return filteredList, nil +} + +func (c *fakeClient) objMatchesFieldSelector(o runtime.Object, extractIndex client.IndexerFunc, val string) bool { + obj, isClientObject := o.(client.Object) + if !isClientObject { + panic(fmt.Errorf("expected object %v to be of type client.Object, but it's not", o)) + } + + for _, extractedVal := range extractIndex(obj) { + if extractedVal == val { + return true + } + } + + return false +} + +func (c *fakeClient) Scheme() *runtime.Scheme { + return c.scheme +} + +func (c *fakeClient) RESTMapper() meta.RESTMapper { + return c.restMapper +} + +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *fakeClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return apiutil.GVKForObject(obj, c.scheme) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *fakeClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return apiutil.IsObjectNamespaced(obj, c.scheme, c.restMapper) +} + +func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { + createOptions := &client.CreateOptions{} + createOptions.ApplyOptions(opts) + + for _, dryRunOpt := range createOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + + if accessor.GetName() == "" && accessor.GetGenerateName() != "" { + base := accessor.GetGenerateName() + if len(base) > maxGeneratedNameLength { + base = base[:maxGeneratedNameLength] + } + accessor.SetName(fmt.Sprintf("%s%s", base, utilrand.String(randomLength))) + } + // Ignore attempts to set deletion timestamp + if !accessor.GetDeletionTimestamp().IsZero() { + accessor.SetDeletionTimestamp(nil) + } + + return c.tracker.Create(gvr, obj, accessor.GetNamespace()) +} + +func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + delOptions := client.DeleteOptions{} + delOptions.ApplyOptions(opts) + + for _, dryRunOpt := range delOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + // Check the ResourceVersion if that Precondition was specified. + if delOptions.Preconditions != nil && delOptions.Preconditions.ResourceVersion != nil { + name := accessor.GetName() + dbObj, err := c.tracker.Get(gvr, accessor.GetNamespace(), name) + if err != nil { + return err + } + oldAccessor, err := meta.Accessor(dbObj) + if err != nil { + return err + } + actualRV := oldAccessor.GetResourceVersion() + expectRV := *delOptions.Preconditions.ResourceVersion + if actualRV != expectRV { + msg := fmt.Sprintf( + "the ResourceVersion in the precondition (%s) does not match the ResourceVersion in record (%s). "+ + "The object might have been modified", + expectRV, actualRV) + return apierrors.NewConflict(gvr.GroupResource(), name, errors.New(msg)) + } + } + + return c.deleteObject(gvr, accessor) +} + +func (c *fakeClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + dcOptions := client.DeleteAllOfOptions{} + dcOptions.ApplyOptions(opts) + + for _, dryRunOpt := range dcOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + o, err := c.tracker.List(gvr, gvk, dcOptions.Namespace) + if err != nil { + return err + } + + objs, err := meta.ExtractList(o) + if err != nil { + return err + } + filteredObjs, err := objectutil.FilterWithLabels(objs, dcOptions.LabelSelector) + if err != nil { + return err + } + for _, o := range filteredObjs { + accessor, err := meta.Accessor(o) + if err != nil { + return err + } + err = c.deleteObject(gvr, accessor) + if err != nil { + return err + } + } + return nil +} + +func (c *fakeClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { + return c.update(obj, false, opts...) +} + +func (c *fakeClient) update(obj client.Object, isStatus bool, opts ...client.UpdateOption) error { + updateOptions := &client.UpdateOptions{} + updateOptions.ApplyOptions(opts) + + for _, dryRunOpt := range updateOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + return c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false) +} + +func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + return c.patch(obj, patch, opts...) +} + +func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + patchOptions := &client.PatchOptions{} + patchOptions.ApplyOptions(opts) + + for _, dryRunOpt := range patchOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + data, err := patch.Data(obj) + if err != nil { + return err + } + + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + oldObj, err := c.tracker.Get(gvr, accessor.GetNamespace(), accessor.GetName()) + if err != nil { + return err + } + oldAccessor, err := meta.Accessor(oldObj) + if err != nil { + return err + } + + // Apply patch without updating object. + // To remain in accordance with the behavior of k8s api behavior, + // a patch must not allow for changes to the deletionTimestamp of an object. + // The reaction() function applies the patch to the object and calls Update(), + // whereas dryPatch() replicates this behavior but skips the call to Update(). + // This ensures that the patch may be rejected if a deletionTimestamp is modified, prior + // to updating the object. + action := testing.NewPatchAction(gvr, accessor.GetNamespace(), accessor.GetName(), patch.Type(), data) + o, err := dryPatch(action, c.tracker) + if err != nil { + return err + } + newObj, err := meta.Accessor(o) + if err != nil { + return err + } + + // Validate that deletionTimestamp has not been changed + if !deletionTimestampEqual(newObj, oldAccessor) { + return fmt.Errorf("rejected patch, metadata.deletionTimestamp immutable") + } + + reaction := testing.ObjectReaction(c.tracker) + handled, o, err := reaction(action) + if err != nil { + return err + } + if !handled { + panic("tracker could not handle patch method") + } + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(gvk.Kind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + return err +} + +// Applying a patch results in a deletionTimestamp that is truncated to the nearest second. +// Check that the diff between a new and old deletion timestamp is within a reasonable threshold +// to be considered unchanged. +func deletionTimestampEqual(newObj metav1.Object, obj metav1.Object) bool { + newTime := newObj.GetDeletionTimestamp() + oldTime := obj.GetDeletionTimestamp() + + if newTime == nil || oldTime == nil { + return newTime == oldTime + } + return newTime.Time.Sub(oldTime.Time).Abs() < time.Second +} + +// The behavior of applying the patch is pulled out into dryPatch(), +// which applies the patch and returns an object, but does not Update() the object. +// This function returns a patched runtime object that may then be validated before a call to Update() is executed. +// This results in some code duplication, but was found to be a cleaner alternative than unmarshalling and introspecting the patch data +// and easier than refactoring the k8s client-go method upstream. +// Duplicate of upstream: https://github.com/kubernetes/client-go/blob/783d0d33626e59d55d52bfd7696b775851f92107/testing/fixture.go#L146-L194 +func dryPatch(action testing.PatchActionImpl, tracker testing.ObjectTracker) (runtime.Object, error) { + ns := action.GetNamespace() + gvr := action.GetResource() + + obj, err := tracker.Get(gvr, ns, action.GetName()) + if err != nil { + return nil, err + } + + old, err := json.Marshal(obj) + if err != nil { + return nil, err + } + + // reset the object in preparation to unmarshal, since unmarshal does not guarantee that fields + // in obj that are removed by patch are cleared + value := reflect.ValueOf(obj) + value.Elem().Set(reflect.New(value.Type().Elem()).Elem()) + + switch action.GetPatchType() { + case types.JSONPatchType: + patch, err := jsonpatch.DecodePatch(action.GetPatch()) + if err != nil { + return nil, err + } + modified, err := patch.Apply(old) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(modified, obj); err != nil { + return nil, err + } + case types.MergePatchType: + modified, err := jsonpatch.MergePatch(old, action.GetPatch()) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(modified, obj); err != nil { + return nil, err + } + case types.StrategicMergePatchType, types.ApplyPatchType: + mergedByte, err := strategicpatch.StrategicMergePatch(old, action.GetPatch(), obj) + if err != nil { + return nil, err + } + if err = json.Unmarshal(mergedByte, obj); err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("PatchType is not supported") + } + return obj, nil +} + +func copyNonStatusFrom(old, new runtime.Object) error { + newClientObject, ok := new.(client.Object) + if !ok { + return fmt.Errorf("%T is not a client.Object", new) + } + // The only thing other than status we have to retain + rv := newClientObject.GetResourceVersion() + + oldMapStringAny, err := toMapStringAny(old) + if err != nil { + return fmt.Errorf("failed to convert old to *unstructured.Unstructured: %w", err) + } + newMapStringAny, err := toMapStringAny(new) + if err != nil { + return fmt.Errorf("failed to convert new to *unststructured.Unstructured: %w", err) + } + + // delete everything other than status in case it has fields that were not present in + // the old object + for k := range newMapStringAny { + if k != "status" { + delete(newMapStringAny, k) + } + } + // copy everything other than status from the old object + for k := range oldMapStringAny { + if k != "status" { + newMapStringAny[k] = oldMapStringAny[k] + } + } + + newClientObject.SetResourceVersion(rv) + + if err := fromMapStringAny(newMapStringAny, new); err != nil { + return fmt.Errorf("failed to convert back from map[string]any: %w", err) + } + return nil +} + +// copyStatusFrom copies the status from old into new +func copyStatusFrom(old, new runtime.Object) error { + oldMapStringAny, err := toMapStringAny(old) + if err != nil { + return fmt.Errorf("failed to convert old to *unstructured.Unstructured: %w", err) + } + newMapStringAny, err := toMapStringAny(new) + if err != nil { + return fmt.Errorf("failed to convert new to *unststructured.Unstructured: %w", err) + } + + newMapStringAny["status"] = oldMapStringAny["status"] + + if err := fromMapStringAny(newMapStringAny, new); err != nil { + return fmt.Errorf("failed to convert back from map[string]any: %w", err) + } + + return nil +} + +func toMapStringAny(obj runtime.Object) (map[string]any, error) { + if unstructured, isUnstructured := obj.(*unstructured.Unstructured); isUnstructured { + return unstructured.Object, nil + } + + serialized, err := json.Marshal(obj) + if err != nil { + return nil, err + } + + u := map[string]any{} + return u, json.Unmarshal(serialized, &u) +} + +func fromMapStringAny(u map[string]any, target runtime.Object) error { + if targetUnstructured, isUnstructured := target.(*unstructured.Unstructured); isUnstructured { + targetUnstructured.Object = u + return nil + } + + serialized, err := json.Marshal(u) + if err != nil { + return fmt.Errorf("failed to serialize: %w", err) + } + + if err := json.Unmarshal(serialized, &target); err != nil { + return fmt.Errorf("failed to deserialize: %w", err) + } + + return nil +} + +func (c *fakeClient) Status() client.SubResourceWriter { + return c.SubResource("status") +} + +func (c *fakeClient) SubResource(subResource string) client.SubResourceClient { + return &fakeSubResourceClient{client: c, subResource: subResource} +} + +func (c *fakeClient) deleteObject(gvr schema.GroupVersionResource, accessor metav1.Object) error { + old, err := c.tracker.Get(gvr, accessor.GetNamespace(), accessor.GetName()) + if err == nil { + oldAccessor, err := meta.Accessor(old) + if err == nil { + if len(oldAccessor.GetFinalizers()) > 0 { + now := metav1.Now() + oldAccessor.SetDeletionTimestamp(&now) + // Call update directly with mutability parameter set to true to allow + // changes to deletionTimestamp + return c.tracker.update(gvr, old, accessor.GetNamespace(), false, true) + } + } + } + + //TODO: implement propagation + return c.tracker.Delete(gvr, accessor.GetNamespace(), accessor.GetName()) +} + +func getGVRFromObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersionResource, error) { + gvk, err := apiutil.GVKForObject(obj, scheme) + if err != nil { + return schema.GroupVersionResource{}, err + } + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + return gvr, nil +} + +type fakeSubResourceClient struct { + client *fakeClient + subResource string +} + +func (sw *fakeSubResourceClient) Get(ctx context.Context, obj, subResource client.Object, opts ...client.SubResourceGetOption) error { + panic("fakeSubResourceClient does not support get") +} + +func (sw *fakeSubResourceClient) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error { + switch sw.subResource { + case "eviction": + _, isEviction := subResource.(*policyv1beta1.Eviction) + if !isEviction { + _, isEviction = subResource.(*policyv1.Eviction) + } + if !isEviction { + return apierrors.NewBadRequest(fmt.Sprintf("got invalid type %t, expected Eviction", subResource)) + } + if _, isPod := obj.(*corev1.Pod); !isPod { + return apierrors.NewNotFound(schema.GroupResource{}, "") + } + + return sw.client.Delete(ctx, obj) + default: + return fmt.Errorf("fakeSubResourceWriter does not support create for %s", sw.subResource) + } +} + +func (sw *fakeSubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + updateOptions := client.SubResourceUpdateOptions{} + updateOptions.ApplyOptions(opts) + + body := obj + if updateOptions.SubResourceBody != nil { + body = updateOptions.SubResourceBody + } + return sw.client.update(body, true, &updateOptions.UpdateOptions) +} + +func (sw *fakeSubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + patchOptions := client.SubResourcePatchOptions{} + patchOptions.ApplyOptions(opts) + + body := obj + if patchOptions.SubResourceBody != nil { + body = patchOptions.SubResourceBody + } + + return sw.client.patch(body, patch, &patchOptions.PatchOptions) +} + +func allowsUnconditionalUpdate(gvk schema.GroupVersionKind) bool { + switch gvk.Group { + case "apps": + switch gvk.Kind { + case "ControllerRevision", "DaemonSet", "Deployment", "ReplicaSet", "StatefulSet": + return true + } + case "autoscaling": + switch gvk.Kind { + case "HorizontalPodAutoscaler": + return true + } + case "batch": + switch gvk.Kind { + case "CronJob", "Job": + return true + } + case "certificates": + switch gvk.Kind { + case "Certificates": + return true + } + case "flowcontrol": + switch gvk.Kind { + case "FlowSchema", "PriorityLevelConfiguration": + return true + } + case "networking": + switch gvk.Kind { + case "Ingress", "IngressClass", "NetworkPolicy": + return true + } + case "policy": + switch gvk.Kind { + case "PodSecurityPolicy": + return true + } + case "rbac": + switch gvk.Kind { + case "ClusterRole", "ClusterRoleBinding", "Role", "RoleBinding": + return true + } + case "scheduling": + switch gvk.Kind { + case "PriorityClass": + return true + } + case "settings": + switch gvk.Kind { + case "PodPreset": + return true + } + case "storage": + switch gvk.Kind { + case "StorageClass": + return true + } + case "": + switch gvk.Kind { + case "ConfigMap", "Endpoint", "Event", "LimitRange", "Namespace", "Node", + "PersistentVolume", "PersistentVolumeClaim", "Pod", "PodTemplate", + "ReplicationController", "ResourceQuota", "Secret", "Service", + "ServiceAccount", "EndpointSlice": + return true + } + } + + return false +} + +func allowsCreateOnUpdate(gvk schema.GroupVersionKind) bool { + switch gvk.Group { + case "coordination": + switch gvk.Kind { + case "Lease": + return true + } + case "node": + switch gvk.Kind { + case "RuntimeClass": + return true + } + case "rbac": + switch gvk.Kind { + case "ClusterRole", "ClusterRoleBinding", "Role", "RoleBinding": + return true + } + case "": + switch gvk.Kind { + case "Endpoint", "Event", "LimitRange", "Service": + return true + } + } + + return false +} + +func inTreeResourcesWithStatus() []schema.GroupVersionKind { + return []schema.GroupVersionKind{ + {Version: "v1", Kind: "Namespace"}, + {Version: "v1", Kind: "Node"}, + {Version: "v1", Kind: "PersistentVolumeClaim"}, + {Version: "v1", Kind: "PersistentVolume"}, + {Version: "v1", Kind: "Pod"}, + {Version: "v1", Kind: "ReplicationController"}, + {Version: "v1", Kind: "Service"}, + + {Group: "apps", Version: "v1", Kind: "Deployment"}, + {Group: "apps", Version: "v1", Kind: "DaemonSet"}, + {Group: "apps", Version: "v1", Kind: "ReplicaSet"}, + {Group: "apps", Version: "v1", Kind: "StatefulSet"}, + + {Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}, + + {Group: "batch", Version: "v1", Kind: "CronJob"}, + {Group: "batch", Version: "v1", Kind: "Job"}, + + {Group: "certificates.k8s.io", Version: "v1", Kind: "CertificateSigningRequest"}, + + {Group: "networking.k8s.io", Version: "v1", Kind: "Ingress"}, + {Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}, + + {Group: "policy", Version: "v1", Kind: "PodDisruptionBudget"}, + + {Group: "storage.k8s.io", Version: "v1", Kind: "VolumeAttachment"}, + + {Group: "apiextensions.k8s.io", Version: "v1", Kind: "CustomResourceDefinition"}, + + {Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchema"}, + {Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"}, + } +} + +// zero zeros the value of a pointer. +func zero(x interface{}) { + if x == nil { + return + } + res := reflect.ValueOf(x).Elem() + res.Set(reflect.Zero(res.Type())) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_suite_test.go new file mode 100644 index 00000000000..66590f0b58b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_suite_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Fake client Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_test.go new file mode 100644 index 00000000000..a4e807a5269 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/client_test.go @@ -0,0 +1,1699 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "time" + + "sigs.k8s.io/controller-runtime/pkg/client/interceptor" + + "github.com/google/go-cmp/cmp" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes/fake" + + appsv1 "k8s.io/api/apps/v1" + coordinationv1 "k8s.io/api/coordination/v1" + corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("Fake client", func() { + var dep *appsv1.Deployment + var dep2 *appsv1.Deployment + var cm *corev1.ConfigMap + var cl client.WithWatch + + BeforeEach(func() { + replicas := int32(1) + dep = &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment", + Namespace: "ns1", + ResourceVersion: trackerAddResourceVersion, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + Strategy: appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + }, + }, + } + dep2 = &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment-2", + Namespace: "ns1", + Labels: map[string]string{ + "test-label": "label-value", + }, + ResourceVersion: trackerAddResourceVersion, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + }, + } + cm = &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + Namespace: "ns2", + ResourceVersion: trackerAddResourceVersion, + }, + Data: map[string]string{ + "test-key": "test-value", + }, + } + }) + + AssertClientWithoutIndexBehavior := func() { + It("should be able to Get", func() { + By("Getting a deployment") + namespacedName := types.NamespacedName{ + Name: "test-deployment", + Namespace: "ns1", + } + obj := &appsv1.Deployment{} + err := cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(dep)) + }) + + It("should be able to Get using unstructured", func() { + By("Getting a deployment") + namespacedName := types.NamespacedName{ + Name: "test-deployment", + Namespace: "ns1", + } + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("apps/v1") + obj.SetKind("Deployment") + err := cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + }) + + It("should be able to List", func() { + By("Listing all deployments in a namespace") + list := &appsv1.DeploymentList{} + err := cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(2)) + Expect(list.Items).To(ConsistOf(*dep, *dep2)) + }) + + It("should be able to List using unstructured list", func() { + By("Listing all deployments in a namespace") + list := &unstructured.UnstructuredList{} + list.SetAPIVersion("apps/v1") + list.SetKind("DeploymentList") + err := cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(2)) + }) + + It("should be able to List using unstructured list when setting a non-list kind", func() { + By("Listing all deployments in a namespace") + list := &unstructured.UnstructuredList{} + list.SetAPIVersion("apps/v1") + list.SetKind("Deployment") + err := cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(2)) + }) + + It("should be able to retrieve registered objects that got manipulated as unstructured", func() { + list := func() { + By("Listing all endpoints in a namespace") + list := &unstructured.UnstructuredList{} + list.SetAPIVersion("v1") + list.SetKind("EndpointsList") + err := cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + } + + unstructuredEndpoint := func() *unstructured.Unstructured { + item := &unstructured.Unstructured{} + item.SetAPIVersion("v1") + item.SetKind("Endpoints") + item.SetName("test-endpoint") + item.SetNamespace("ns1") + return item + } + + By("Adding the object during client initialization") + cl = NewFakeClient(unstructuredEndpoint()) + list() + Expect(cl.Delete(context.Background(), unstructuredEndpoint())).To(BeNil()) + + By("Creating an object") + item := unstructuredEndpoint() + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + list() + + By("Updating the object") + item.SetAnnotations(map[string]string{"foo": "bar"}) + err = cl.Update(context.Background(), item) + Expect(err).To(BeNil()) + list() + + By("Patching the object") + old := item.DeepCopy() + item.SetAnnotations(map[string]string{"bar": "baz"}) + err = cl.Patch(context.Background(), item, client.MergeFrom(old)) + Expect(err).To(BeNil()) + list() + }) + + It("should be able to Create an unregistered type using unstructured", func() { + item := &unstructured.Unstructured{} + item.SetAPIVersion("custom/v1") + item.SetKind("Image") + item.SetName("my-item") + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + }) + + It("should be able to Get an unregisted type using unstructured", func() { + By("Creating an object of an unregistered type") + item := &unstructured.Unstructured{} + item.SetAPIVersion("custom/v2") + item.SetKind("Image") + item.SetName("my-item") + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + + By("Getting and the object") + item = &unstructured.Unstructured{} + item.SetAPIVersion("custom/v2") + item.SetKind("Image") + item.SetName("my-item") + err = cl.Get(context.Background(), client.ObjectKeyFromObject(item), item) + Expect(err).To(BeNil()) + }) + + It("should be able to List an unregistered type using unstructured", func() { + list := &unstructured.UnstructuredList{} + list.SetAPIVersion("custom/v3") + list.SetKind("ImageList") + err := cl.List(context.Background(), list) + Expect(err).To(BeNil()) + }) + + It("should be able to List an unregistered type using unstructured", func() { + list := &unstructured.UnstructuredList{} + list.SetAPIVersion("custom/v4") + list.SetKind("Image") + err := cl.List(context.Background(), list) + Expect(err).To(BeNil()) + }) + + It("should be able to Update an unregistered type using unstructured", func() { + By("Creating an object of an unregistered type") + item := &unstructured.Unstructured{} + item.SetAPIVersion("custom/v5") + item.SetKind("Image") + item.SetName("my-item") + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + + By("Updating the object") + err = unstructured.SetNestedField(item.Object, int64(2), "spec", "replicas") + Expect(err).To(BeNil()) + err = cl.Update(context.Background(), item) + Expect(err).To(BeNil()) + + By("Getting the object") + item = &unstructured.Unstructured{} + item.SetAPIVersion("custom/v5") + item.SetKind("Image") + item.SetName("my-item") + err = cl.Get(context.Background(), client.ObjectKeyFromObject(item), item) + Expect(err).To(BeNil()) + + By("Inspecting the object") + value, found, err := unstructured.NestedInt64(item.Object, "spec", "replicas") + Expect(err).To(BeNil()) + Expect(found).To(BeTrue()) + Expect(value).To(Equal(int64(2))) + }) + + It("should be able to Patch an unregistered type using unstructured", func() { + By("Creating an object of an unregistered type") + item := &unstructured.Unstructured{} + item.SetAPIVersion("custom/v6") + item.SetKind("Image") + item.SetName("my-item") + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + + By("Updating the object") + original := item.DeepCopy() + err = unstructured.SetNestedField(item.Object, int64(2), "spec", "replicas") + Expect(err).To(BeNil()) + err = cl.Patch(context.Background(), item, client.MergeFrom(original)) + Expect(err).To(BeNil()) + + By("Getting the object") + item = &unstructured.Unstructured{} + item.SetAPIVersion("custom/v6") + item.SetKind("Image") + item.SetName("my-item") + err = cl.Get(context.Background(), client.ObjectKeyFromObject(item), item) + Expect(err).To(BeNil()) + + By("Inspecting the object") + value, found, err := unstructured.NestedInt64(item.Object, "spec", "replicas") + Expect(err).To(BeNil()) + Expect(found).To(BeTrue()) + Expect(value).To(Equal(int64(2))) + }) + + It("should be able to Delete an unregistered type using unstructured", func() { + By("Creating an object of an unregistered type") + item := &unstructured.Unstructured{} + item.SetAPIVersion("custom/v7") + item.SetKind("Image") + item.SetName("my-item") + err := cl.Create(context.Background(), item) + Expect(err).To(BeNil()) + + By("Deleting the object") + err = cl.Delete(context.Background(), item) + Expect(err).To(BeNil()) + + By("Getting the object") + item = &unstructured.Unstructured{} + item.SetAPIVersion("custom/v7") + item.SetKind("Image") + item.SetName("my-item") + err = cl.Get(context.Background(), client.ObjectKeyFromObject(item), item) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should support filtering by labels and their values", func() { + By("Listing deployments with a particular label and value") + list := &appsv1.DeploymentList{} + err := cl.List(context.Background(), list, client.InNamespace("ns1"), + client.MatchingLabels(map[string]string{ + "test-label": "label-value", + })) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("should support filtering by label existence", func() { + By("Listing deployments with a particular label") + list := &appsv1.DeploymentList{} + err := cl.List(context.Background(), list, client.InNamespace("ns1"), + client.HasLabels{"test-label"}) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("should be able to Create", func() { + By("Creating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "new-test-cm", + Namespace: "ns2", + }, + } + err := cl.Create(context.Background(), newcm) + Expect(err).To(BeNil()) + + By("Getting the new configmap") + namespacedName := types.NamespacedName{ + Name: "new-test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(newcm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1")) + }) + + It("should error on create with set resourceVersion", func() { + By("Creating a new configmap") + newcm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "new-test-cm", + Namespace: "ns2", + ResourceVersion: "1", + }, + } + err := cl.Create(context.Background(), newcm) + Expect(apierrors.IsBadRequest(err)).To(BeTrue()) + }) + + It("should not change the submitted object if Create failed", func() { + By("Trying to create an existing configmap") + submitted := cm.DeepCopy() + submitted.ResourceVersion = "" + submittedReference := submitted.DeepCopy() + err := cl.Create(context.Background(), submitted) + Expect(err).ToNot(BeNil()) + Expect(apierrors.IsAlreadyExists(err)).To(BeTrue()) + Expect(submitted).To(Equal(submittedReference)) + }) + + It("should error on Create with empty Name", func() { + By("Creating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns2", + }, + } + err := cl.Create(context.Background(), newcm) + Expect(err.Error()).To(Equal("ConfigMap \"\" is invalid: metadata.name: Required value: name is required")) + }) + + It("should error on Update with empty Name", func() { + By("Creating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns2", + }, + } + err := cl.Update(context.Background(), newcm) + Expect(err.Error()).To(Equal("ConfigMap \"\" is invalid: metadata.name: Required value: name is required")) + }) + + It("should be able to Create with GenerateName", func() { + By("Creating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "new-test-cm", + Namespace: "ns2", + Labels: map[string]string{ + "test-label": "label-value", + }, + }, + } + err := cl.Create(context.Background(), newcm) + Expect(err).To(BeNil()) + + By("Listing configmaps with a particular label") + list := &corev1.ConfigMapList{} + err = cl.List(context.Background(), list, client.InNamespace("ns2"), + client.MatchingLabels(map[string]string{ + "test-label": "label-value", + })) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items[0].Name).NotTo(BeEmpty()) + }) + + It("should be able to Update", func() { + By("Updating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + Namespace: "ns2", + ResourceVersion: "", + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Update(context.Background(), newcm) + Expect(err).To(BeNil()) + + By("Getting the new configmap") + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(newcm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1000")) + }) + + It("should allow updates with non-set ResourceVersion for a resource that allows unconditional updates", func() { + By("Updating a new configmap") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + Namespace: "ns2", + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Update(context.Background(), newcm) + Expect(err).To(BeNil()) + + By("Getting the configmap") + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(newcm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1000")) + }) + + It("should reject updates with non-set ResourceVersion for a resource that doesn't allow unconditional updates", func() { + By("Creating a new binding") + binding := &corev1.Binding{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Binding", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-binding", + Namespace: "ns2", + }, + Target: corev1.ObjectReference{ + Kind: "ConfigMap", + APIVersion: "v1", + Namespace: cm.Namespace, + Name: cm.Name, + }, + } + Expect(cl.Create(context.Background(), binding)).To(Succeed()) + + By("Updating the binding with a new resource lacking resource version") + newBinding := &corev1.Binding{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Binding", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: binding.Name, + Namespace: binding.Namespace, + }, + Target: corev1.ObjectReference{ + Namespace: binding.Namespace, + Name: "blue", + }, + } + Expect(cl.Update(context.Background(), newBinding)).NotTo(Succeed()) + }) + + It("should allow create on update for a resource that allows create on update", func() { + By("Creating a new lease with update") + lease := &coordinationv1.Lease{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "coordination.k8s.io/v1", + Kind: "Lease", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-lease", + Namespace: "ns2", + }, + Spec: coordinationv1.LeaseSpec{}, + } + Expect(cl.Create(context.Background(), lease)).To(Succeed()) + + By("Getting the lease") + namespacedName := types.NamespacedName{ + Name: lease.Name, + Namespace: lease.Namespace, + } + obj := &coordinationv1.Lease{} + Expect(cl.Get(context.Background(), namespacedName, obj)).To(Succeed()) + Expect(obj).To(Equal(lease)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1")) + }) + + It("should reject create on update for a resource that does not allow create on update", func() { + By("Attemping to create a new configmap with update") + newcm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "different-test-cm", + Namespace: "ns2", + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + Expect(cl.Update(context.Background(), newcm)).NotTo(Succeed()) + }) + + It("should reject updates with non-matching ResourceVersion", func() { + By("Updating a new configmap") + newcm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + Namespace: "ns2", + ResourceVersion: "1", + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Update(context.Background(), newcm) + Expect(apierrors.IsConflict(err)).To(BeTrue()) + + By("Getting the configmap") + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(cm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal(trackerAddResourceVersion)) + }) + + It("should reject Delete with a mismatched ResourceVersion", func() { + bogusRV := "bogus" + By("Deleting with a mismatched ResourceVersion Precondition") + err := cl.Delete(context.Background(), dep, client.Preconditions{ResourceVersion: &bogusRV}) + Expect(apierrors.IsConflict(err)).To(BeTrue()) + + list := &appsv1.DeploymentList{} + err = cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(2)) + Expect(list.Items).To(ConsistOf(*dep, *dep2)) + }) + + It("should successfully Delete with a matching ResourceVersion", func() { + goodRV := trackerAddResourceVersion + By("Deleting with a matching ResourceVersion Precondition") + err := cl.Delete(context.Background(), dep, client.Preconditions{ResourceVersion: &goodRV}) + Expect(err).To(BeNil()) + + list := &appsv1.DeploymentList{} + err = cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("should be able to Delete with no ResourceVersion Precondition", func() { + By("Deleting a deployment") + err := cl.Delete(context.Background(), dep) + Expect(err).To(BeNil()) + + By("Listing all deployments in the namespace") + list := &appsv1.DeploymentList{} + err = cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("should be able to Delete with no opts even if object's ResourceVersion doesn't match server", func() { + By("Deleting a deployment") + depCopy := dep.DeepCopy() + depCopy.ResourceVersion = "bogus" + err := cl.Delete(context.Background(), depCopy) + Expect(err).To(BeNil()) + + By("Listing all deployments in the namespace") + list := &appsv1.DeploymentList{} + err = cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(HaveLen(1)) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("should handle finalizers on Update", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "delete-with-finalizers", + } + By("Updating a new object") + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Deleting the object") + err = cl.Delete(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Getting the object") + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj.DeletionTimestamp).NotTo(BeNil()) + + By("Removing the finalizer") + obj.Finalizers = []string{} + err = cl.Update(context.Background(), obj) + Expect(err).To(BeNil()) + + By("Getting the object") + obj = &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should reject changes to deletionTimestamp on Update", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "reject-with-deletiontimestamp", + } + By("Updating a new object") + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Getting the object") + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj.DeletionTimestamp).To(BeNil()) + + By("Adding deletionTimestamp") + now := metav1.Now() + obj.DeletionTimestamp = &now + err = cl.Update(context.Background(), obj) + Expect(err).NotTo(BeNil()) + + By("Deleting the object") + err = cl.Delete(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Changing the deletionTimestamp to new value") + obj = &corev1.ConfigMap{} + t := metav1.NewTime(time.Now().Add(time.Second)) + obj.DeletionTimestamp = &t + err = cl.Update(context.Background(), obj) + Expect(err).NotTo(BeNil()) + + By("Removing deletionTimestamp") + obj.DeletionTimestamp = nil + err = cl.Update(context.Background(), obj) + Expect(err).NotTo(BeNil()) + + }) + + It("should be able to Delete a Collection", func() { + By("Deleting a deploymentList") + err := cl.DeleteAllOf(context.Background(), &appsv1.Deployment{}, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + + By("Listing all deployments in the namespace") + list := &appsv1.DeploymentList{} + err = cl.List(context.Background(), list, client.InNamespace("ns1")) + Expect(err).To(BeNil()) + Expect(list.Items).To(BeEmpty()) + }) + + It("should handle finalizers deleting a collection", func() { + for i := 0; i < 5; i++ { + namespacedName := types.NamespacedName{ + Name: fmt.Sprintf("test-cm-%d", i), + Namespace: "delete-collection-with-finalizers", + } + By("Creating a new object") + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + } + + By("Deleting the object") + err := cl.DeleteAllOf(context.Background(), &corev1.ConfigMap{}, client.InNamespace("delete-collection-with-finalizers")) + Expect(err).To(BeNil()) + + configmaps := corev1.ConfigMapList{} + err = cl.List(context.Background(), &configmaps, client.InNamespace("delete-collection-with-finalizers")) + Expect(err).To(BeNil()) + + Expect(len(configmaps.Items)).To(Equal(5)) + for _, cm := range configmaps.Items { + Expect(cm.DeletionTimestamp).NotTo(BeNil()) + } + }) + + It("should be able to watch", func() { + By("Creating a watch") + objWatch, err := cl.Watch(context.Background(), &corev1.ServiceList{}) + Expect(err).NotTo(HaveOccurred()) + + defer objWatch.Stop() + + go func() { + defer GinkgoRecover() + // It is likely starting a new goroutine is slower than progressing + // in the outer routine, sleep to make sure this is always true + time.Sleep(100 * time.Millisecond) + + err := cl.Create(context.Background(), &corev1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "for-watch"}}) + Expect(err).ToNot(HaveOccurred()) + }() + + event, ok := <-objWatch.ResultChan() + Expect(ok).To(BeTrue()) + Expect(event.Type).To(Equal(watch.Added)) + + service, ok := event.Object.(*corev1.Service) + Expect(ok).To(BeTrue()) + Expect(service.Name).To(Equal("for-watch")) + }) + + Context("with the DryRun option", func() { + It("should not create a new object", func() { + By("Creating a new configmap with DryRun") + newcm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "new-test-cm", + Namespace: "ns2", + }, + } + err := cl.Create(context.Background(), newcm, client.DryRunAll) + Expect(err).To(BeNil()) + + By("Getting the new configmap") + namespacedName := types.NamespacedName{ + Name: "new-test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(HaveOccurred()) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + Expect(obj).NotTo(Equal(newcm)) + }) + + It("should not Update the object", func() { + By("Updating a new configmap with DryRun") + newcm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cm", + Namespace: "ns2", + ResourceVersion: "1", + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Update(context.Background(), newcm, client.DryRunAll) + Expect(err).To(BeNil()) + + By("Getting the new configmap") + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(cm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal(trackerAddResourceVersion)) + }) + + It("Should not Delete the object", func() { + By("Deleting a configmap with DryRun with Delete()") + err := cl.Delete(context.Background(), cm, client.DryRunAll) + Expect(err).To(BeNil()) + + By("Deleting a configmap with DryRun with DeleteAllOf()") + err = cl.DeleteAllOf(context.Background(), cm, client.DryRunAll) + Expect(err).To(BeNil()) + + By("Getting the configmap") + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ns2", + } + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(cm)) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal(trackerAddResourceVersion)) + }) + }) + + It("should be able to Patch", func() { + By("Patching a deployment") + mergePatch, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{ + "foo": "bar", + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + err = cl.Patch(context.Background(), dep, client.RawPatch(types.StrategicMergePatchType, mergePatch)) + Expect(err).NotTo(HaveOccurred()) + + By("Getting the patched deployment") + namespacedName := types.NamespacedName{ + Name: "test-deployment", + Namespace: "ns1", + } + obj := &appsv1.Deployment{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).NotTo(HaveOccurred()) + Expect(obj.Annotations["foo"]).To(Equal("bar")) + Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1000")) + }) + + It("should ignore deletionTimestamp without finalizer on Create", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "ignore-deletiontimestamp", + } + By("Creating a new object") + now := metav1.Now() + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + DeletionTimestamp: &now, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Getting the object") + obj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj.DeletionTimestamp).To(BeNil()) + + }) + + It("should reject deletionTimestamp without finalizers on Build", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "reject-deletiontimestamp-no-finalizers", + } + By("Build with a new object without finalizer") + now := metav1.Now() + obj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + DeletionTimestamp: &now, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + + Expect(func() { NewClientBuilder().WithObjects(obj).Build() }).To(Panic()) + + By("Build with a new object with finalizer") + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + DeletionTimestamp: &now, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + + cl := NewClientBuilder().WithObjects(newObj).Build() + + By("Getting the object") + obj = &corev1.ConfigMap{} + err := cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + + }) + + It("should reject changes to deletionTimestamp on Patch", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "reject-deletiontimestamp", + } + By("Creating a new object") + now := metav1.Now() + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Add a deletionTimestamp") + obj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{}, + DeletionTimestamp: &now, + }, + } + err = cl.Patch(context.Background(), obj, client.MergeFrom(newObj)) + Expect(err).NotTo(BeNil()) + + By("Deleting the object") + err = cl.Delete(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Getting the object") + obj = &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj.DeletionTimestamp).NotTo(BeNil()) + + By("Changing the deletionTimestamp to new value") + newObj = &corev1.ConfigMap{} + t := metav1.NewTime(time.Now().Add(time.Second)) + newObj.DeletionTimestamp = &t + err = cl.Patch(context.Background(), newObj, client.MergeFrom(obj)) + Expect(err).NotTo(BeNil()) + + By("Removing deletionTimestamp") + newObj = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + DeletionTimestamp: nil, + }, + } + err = cl.Patch(context.Background(), newObj, client.MergeFrom(obj)) + Expect(err).NotTo(BeNil()) + + }) + + It("should handle finalizers on Patch", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "delete-with-finalizers", + } + By("Creating a new object") + newObj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Deleting the object") + err = cl.Delete(context.Background(), newObj) + Expect(err).To(BeNil()) + + By("Removing the finalizer") + obj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{}, + }, + } + err = cl.Patch(context.Background(), obj, client.MergeFrom(newObj)) + Expect(err).To(BeNil()) + + By("Getting the object") + obj = &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, obj) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should remove finalizers of the object on Patch", func() { + namespacedName := types.NamespacedName{ + Name: "test-cm", + Namespace: "patch-finalizers-in-obj", + } + By("Creating a new object") + obj := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Finalizers: []string{"finalizers.sigs.k8s.io/test"}, + }, + Data: map[string]string{ + "test-key": "new-value", + }, + } + err := cl.Create(context.Background(), obj) + Expect(err).To(BeNil()) + + By("Removing the finalizer") + mergePatch, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "$deleteFromPrimitiveList/finalizers": []string{ + "finalizers.sigs.k8s.io/test", + }, + }, + }) + Expect(err).To(BeNil()) + err = cl.Patch(context.Background(), obj, client.RawPatch(types.StrategicMergePatchType, mergePatch)) + Expect(err).To(BeNil()) + + By("Check the finalizer has been removed in the object") + Expect(len(obj.Finalizers)).To(Equal(0)) + + By("Check the finalizer has been removed in client") + newObj := &corev1.ConfigMap{} + err = cl.Get(context.Background(), namespacedName, newObj) + Expect(err).To(BeNil()) + Expect(len(newObj.Finalizers)).To(Equal(0)) + }) + + } + + Context("with default scheme.Scheme", func() { + BeforeEach(func() { + cl = NewClientBuilder(). + WithObjects(dep, dep2, cm). + Build() + }) + AssertClientWithoutIndexBehavior() + }) + + Context("with given scheme", func() { + BeforeEach(func() { + scheme := runtime.NewScheme() + Expect(corev1.AddToScheme(scheme)).To(Succeed()) + Expect(appsv1.AddToScheme(scheme)).To(Succeed()) + Expect(coordinationv1.AddToScheme(scheme)).To(Succeed()) + cl = NewClientBuilder(). + WithScheme(scheme). + WithObjects(cm). + WithLists(&appsv1.DeploymentList{Items: []appsv1.Deployment{*dep, *dep2}}). + Build() + }) + AssertClientWithoutIndexBehavior() + }) + + Context("with Indexes", func() { + depReplicasIndexer := func(obj client.Object) []string { + dep, ok := obj.(*appsv1.Deployment) + if !ok { + panic(fmt.Errorf("indexer function for type %T's spec.replicas field received"+ + " object of type %T, this should never happen", appsv1.Deployment{}, obj)) + } + indexVal := "" + if dep.Spec.Replicas != nil { + indexVal = strconv.Itoa(int(*dep.Spec.Replicas)) + } + return []string{indexVal} + } + + depStrategyTypeIndexer := func(obj client.Object) []string { + dep, ok := obj.(*appsv1.Deployment) + if !ok { + panic(fmt.Errorf("indexer function for type %T's spec.strategy.type field received"+ + " object of type %T, this should never happen", appsv1.Deployment{}, obj)) + } + return []string{string(dep.Spec.Strategy.Type)} + } + + var cb *ClientBuilder + BeforeEach(func() { + cb = NewClientBuilder(). + WithObjects(dep, dep2, cm). + WithIndex(&appsv1.Deployment{}, "spec.replicas", depReplicasIndexer) + }) + + Context("client has just one Index", func() { + BeforeEach(func() { cl = cb.Build() }) + + Context("behavior that doesn't use an Index", func() { + AssertClientWithoutIndexBehavior() + }) + + Context("filtered List using field selector", func() { + It("errors when there's no Index for the GroupVersionResource", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("key", "val"), + } + err := cl.List(context.Background(), &corev1.ConfigMapList{}, listOpts) + Expect(err).NotTo(BeNil()) + }) + + It("errors when there's no Index matching the field name", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.paused", "false"), + } + err := cl.List(context.Background(), &appsv1.DeploymentList{}, listOpts) + Expect(err).NotTo(BeNil()) + }) + + It("errors when field selector uses two requirements", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.AndSelectors( + fields.OneTermEqualSelector("spec.replicas", "1"), + fields.OneTermEqualSelector("spec.strategy.type", string(appsv1.RecreateDeploymentStrategyType)), + )} + err := cl.List(context.Background(), &appsv1.DeploymentList{}, listOpts) + Expect(err).NotTo(BeNil()) + }) + + It("returns two deployments that match the only field selector requirement", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.replicas", "1"), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(ConsistOf(*dep, *dep2)) + }) + + It("returns no object because no object matches the only field selector requirement", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.replicas", "2"), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(BeEmpty()) + }) + + It("returns deployment that matches both the field and label selectors", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.replicas", "1"), + LabelSelector: labels.SelectorFromSet(dep2.Labels), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(ConsistOf(*dep2)) + }) + + It("returns no object even if field selector matches because label selector doesn't", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.replicas", "1"), + LabelSelector: labels.Nothing(), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(BeEmpty()) + }) + + It("returns no object even if label selector matches because field selector doesn't", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.replicas", "2"), + LabelSelector: labels.Everything(), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(BeEmpty()) + }) + }) + }) + + Context("client has two Indexes", func() { + BeforeEach(func() { + cl = cb.WithIndex(&appsv1.Deployment{}, "spec.strategy.type", depStrategyTypeIndexer).Build() + }) + + Context("behavior that doesn't use an Index", func() { + AssertClientWithoutIndexBehavior() + }) + + Context("filtered List using field selector", func() { + It("uses the second index to retrieve the indexed objects when there are matches", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.strategy.type", string(appsv1.RecreateDeploymentStrategyType)), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(ConsistOf(*dep)) + }) + + It("uses the second index to retrieve the indexed objects when there are no matches", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.strategy.type", string(appsv1.RollingUpdateDeploymentStrategyType)), + } + list := &appsv1.DeploymentList{} + Expect(cl.List(context.Background(), list, listOpts)).To(Succeed()) + Expect(list.Items).To(BeEmpty()) + }) + + It("errors when field selector uses two requirements", func() { + listOpts := &client.ListOptions{ + FieldSelector: fields.AndSelectors( + fields.OneTermEqualSelector("spec.replicas", "1"), + fields.OneTermEqualSelector("spec.strategy.type", string(appsv1.RecreateDeploymentStrategyType)), + )} + err := cl.List(context.Background(), &appsv1.DeploymentList{}, listOpts) + Expect(err).NotTo(BeNil()) + }) + }) + }) + }) + + It("should set the ResourceVersion to 999 when adding an object to the tracker", func() { + cl := NewClientBuilder().WithObjects(&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "cm"}}).Build() + + retrieved := &corev1.Secret{} + Expect(cl.Get(context.Background(), types.NamespacedName{Name: "cm"}, retrieved)).To(Succeed()) + + reference := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "cm", + ResourceVersion: "999", + }, + } + Expect(retrieved).To(Equal(reference)) + }) + + It("should be able to build with given tracker and get resource", func() { + clientSet := fake.NewSimpleClientset(dep) + cl := NewClientBuilder().WithRuntimeObjects(dep2).WithObjectTracker(clientSet.Tracker()).Build() + + By("Getting a deployment") + namespacedName := types.NamespacedName{ + Name: "test-deployment", + Namespace: "ns1", + } + obj := &appsv1.Deployment{} + err := cl.Get(context.Background(), namespacedName, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(dep)) + + By("Getting a deployment from clientSet") + csDep2, err := clientSet.AppsV1().Deployments("ns1").Get(context.Background(), "test-deployment-2", metav1.GetOptions{}) + Expect(err).To(BeNil()) + Expect(csDep2).To(Equal(dep2)) + + By("Getting a new deployment") + namespacedName3 := types.NamespacedName{ + Name: "test-deployment-3", + Namespace: "ns1", + } + + dep3 := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment-3", + Namespace: "ns1", + Labels: map[string]string{ + "test-label": "label-value", + }, + ResourceVersion: trackerAddResourceVersion, + }, + } + + _, err = clientSet.AppsV1().Deployments("ns1").Create(context.Background(), dep3, metav1.CreateOptions{}) + Expect(err).To(BeNil()) + + obj = &appsv1.Deployment{} + err = cl.Get(context.Background(), namespacedName3, obj) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(dep3)) + }) + + It("should not change the status of typed objects that have a status subresource on update", func() { + obj := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + }, + Status: corev1.NodeStatus{ + NodeInfo: corev1.NodeSystemInfo{MachineID: "machine-id"}, + }, + } + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + + obj.Status.NodeInfo.MachineID = "updated-machine-id" + Expect(cl.Update(context.Background(), obj)).To(BeNil()) + + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Status).To(BeEquivalentTo(corev1.NodeStatus{NodeInfo: corev1.NodeSystemInfo{MachineID: "machine-id"}})) + }) + + It("should return a conflict error when an incorrect RV is used on status update", func() { + obj := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + }, + } + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + + obj.Status.Phase = corev1.NodeRunning + obj.ResourceVersion = "invalid" + err := cl.Update(context.Background(), obj) + Expect(apierrors.IsConflict(err)).To(BeTrue()) + }) + + It("should not change non-status field of typed objects that have a status subresource on status update", func() { + obj := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + }, + Spec: corev1.NodeSpec{ + PodCIDR: "old-cidr", + }, + Status: corev1.NodeStatus{ + NodeInfo: corev1.NodeSystemInfo{ + MachineID: "machine-id", + }, + }, + } + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + objOriginal := obj.DeepCopy() + + obj.Spec.PodCIDR = "cidr-from-status-update" + obj.Status.NodeInfo.MachineID = "machine-id-from-status-update" + Expect(cl.Status().Update(context.Background(), obj)).NotTo(HaveOccurred()) + + actual := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: obj.Name}} + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(actual), actual)).NotTo(HaveOccurred()) + + objOriginal.APIVersion = actual.APIVersion + objOriginal.Kind = actual.Kind + objOriginal.ResourceVersion = actual.ResourceVersion + objOriginal.Status.NodeInfo.MachineID = "machine-id-from-status-update" + Expect(cmp.Diff(objOriginal, actual)).To(BeEmpty()) + }) + + It("should not change the status of typed objects that have a status subresource on patch", func() { + obj := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + }, + Status: corev1.NodeStatus{ + NodeInfo: corev1.NodeSystemInfo{ + MachineID: "machine-id", + }, + }, + } + Expect(cl.Create(context.Background(), obj)).To(BeNil()) + original := obj.DeepCopy() + + obj.Status.NodeInfo.MachineID = "machine-id-from-patch" + Expect(cl.Patch(context.Background(), obj, client.MergeFrom(original))).To(BeNil()) + + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Status).To(BeEquivalentTo(corev1.NodeStatus{NodeInfo: corev1.NodeSystemInfo{MachineID: "machine-id"}})) + }) + + It("should not change non-status field of typed objects that have a status subresource on status patch", func() { + obj := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + }, + Spec: corev1.NodeSpec{ + PodCIDR: "old-cidr", + }, + } + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + objOriginal := obj.DeepCopy() + + obj.Spec.PodCIDR = "cidr-from-status-update" + obj.Status.NodeInfo.MachineID = "machine-id" + Expect(cl.Status().Patch(context.Background(), obj, client.MergeFrom(objOriginal))).NotTo(HaveOccurred()) + + actual := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: obj.Name}} + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(actual), actual)).NotTo(HaveOccurred()) + + objOriginal.APIVersion = actual.APIVersion + objOriginal.Kind = actual.Kind + objOriginal.ResourceVersion = actual.ResourceVersion + objOriginal.Status.NodeInfo.MachineID = "machine-id" + Expect(cmp.Diff(objOriginal, actual)).To(BeEmpty()) + }) + + It("should not change the status of unstructured objects that are configured to have a status subresource on update", func() { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("foo/v1") + obj.SetKind("Foo") + obj.SetName("a-foo") + + err := unstructured.SetNestedField(obj.Object, map[string]any{"state": "old"}, "status") + Expect(err).NotTo(HaveOccurred()) + + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + + err = unstructured.SetNestedField(obj.Object, map[string]any{"state": "new"}, "status") + Expect(err).To(BeNil()) + + Expect(cl.Update(context.Background(), obj)).To(BeNil()) + + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Object["status"]).To(BeEquivalentTo(map[string]any{"state": "old"})) + }) + + It("should not change non-status fields of unstructured objects that are configured to have a status subresource on status update", func() { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("foo/v1") + obj.SetKind("Foo") + obj.SetName("a-foo") + + err := unstructured.SetNestedField(obj.Object, "original", "spec") + Expect(err).NotTo(HaveOccurred()) + + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + + err = unstructured.SetNestedField(obj.Object, "from-status-update", "spec") + Expect(err).NotTo(HaveOccurred()) + err = unstructured.SetNestedField(obj.Object, map[string]any{"state": "new"}, "status") + Expect(err).To(BeNil()) + + Expect(cl.Status().Update(context.Background(), obj)).To(BeNil()) + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Object["status"]).To(BeEquivalentTo(map[string]any{"state": "new"})) + Expect(obj.Object["spec"]).To(BeEquivalentTo("original")) + }) + + It("should not change the status of unstructured objects that are configured to have a status subresource on patch", func() { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("foo/v1") + obj.SetKind("Foo") + obj.SetName("a-foo") + cl := NewClientBuilder().WithStatusSubresource(obj).Build() + + Expect(cl.Create(context.Background(), obj)).To(BeNil()) + original := obj.DeepCopy() + + err := unstructured.SetNestedField(obj.Object, map[string]interface{}{"count": int64(2)}, "status") + Expect(err).To(BeNil()) + Expect(cl.Patch(context.Background(), obj, client.MergeFrom(original))).To(BeNil()) + + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Object["status"]).To(BeNil()) + + }) + + It("should not change non-status fields of unstructured objects that are configured to have a status subresource on status patch", func() { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("foo/v1") + obj.SetKind("Foo") + obj.SetName("a-foo") + + err := unstructured.SetNestedField(obj.Object, "original", "spec") + Expect(err).NotTo(HaveOccurred()) + + cl := NewClientBuilder().WithStatusSubresource(obj).WithObjects(obj).Build() + original := obj.DeepCopy() + + err = unstructured.SetNestedField(obj.Object, "from-status-update", "spec") + Expect(err).NotTo(HaveOccurred()) + err = unstructured.SetNestedField(obj.Object, map[string]any{"state": "new"}, "status") + Expect(err).To(BeNil()) + + Expect(cl.Status().Patch(context.Background(), obj, client.MergeFrom(original))).To(BeNil()) + Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), obj)).To(BeNil()) + + Expect(obj.Object["status"]).To(BeEquivalentTo(map[string]any{"state": "new"})) + Expect(obj.Object["spec"]).To(BeEquivalentTo("original")) + }) + + It("should return not found on status update of resources that don't have a status subresource", func() { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("foo/v1") + obj.SetKind("Foo") + obj.SetName("a-foo") + + cl := NewClientBuilder().WithObjects(obj).Build() + + err := cl.Status().Update(context.Background(), obj) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + evictionTypes := []client.Object{ + &policyv1beta1.Eviction{}, + &policyv1.Eviction{}, + } + for _, tp := range evictionTypes { + It("should delete a pod through the eviction subresource", func() { + pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} + + cl := NewClientBuilder().WithObjects(pod).Build() + + err := cl.SubResource("eviction").Create(context.Background(), pod, tp) + Expect(err).NotTo(HaveOccurred()) + + err = cl.Get(context.Background(), client.ObjectKeyFromObject(pod), pod) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should return not found when attempting to evict a pod that doesn't exist", func() { + cl := NewClientBuilder().Build() + + pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} + err := cl.SubResource("eviction").Create(context.Background(), pod, tp) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should return not found when attempting to evict something other than a pod", func() { + ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} + cl := NewClientBuilder().WithObjects(ns).Build() + + err := cl.SubResource("eviction").Create(context.Background(), ns, tp) + Expect(apierrors.IsNotFound(err)).To(BeTrue()) + }) + + It("should return an error when using the wrong subresource", func() { + cl := NewClientBuilder().Build() + + err := cl.SubResource("eviction-subresource").Create(context.Background(), &corev1.Namespace{}, tp) + Expect(err).NotTo(BeNil()) + }) + } + + It("should error when creating an eviction with the wrong type", func() { + + cl := NewClientBuilder().Build() + err := cl.SubResource("eviction").Create(context.Background(), &corev1.Pod{}, &corev1.Namespace{}) + Expect(apierrors.IsBadRequest(err)).To(BeTrue()) + }) +}) + +var _ = Describe("Fake client builder", func() { + It("panics when an index with the same name and GroupVersionKind is registered twice", func() { + // We need any realistic GroupVersionKind, the choice of apps/v1 Deployment is arbitrary. + cb := NewClientBuilder().WithIndex(&appsv1.Deployment{}, + "test-name", + func(client.Object) []string { return nil }) + + Expect(func() { + cb.WithIndex(&appsv1.Deployment{}, + "test-name", + func(client.Object) []string { return []string{"foo"} }) + }).To(Panic()) + }) + + It("should wrap the fake client with an interceptor when WithInterceptorFuncs is called", func() { + var called bool + cli := NewClientBuilder().WithInterceptorFuncs(interceptor.Funcs{ + Get: func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + called = true + return nil + }, + }).Build() + err := cli.Get(context.Background(), client.ObjectKey{}, &corev1.Pod{}) + Expect(err).NotTo(HaveOccurred()) + Expect(called).To(BeTrue()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go new file mode 100644 index 00000000000..d0614666e37 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package fake provides a fake client for testing. + +A fake client is backed by its simple object store indexed by GroupVersionResource. +You can create a fake client with optional objects. + + client := NewFakeClientWithScheme(scheme, initObjs...) // initObjs is a slice of runtime.Object + +You can invoke the methods defined in the Client interface. + +When in doubt, it's almost always better not to use this package and instead use +envtest.Environment with a real client and API server. + +WARNING: ⚠️ Current Limitations / Known Issues with the fake Client ⚠️ + - This client does not have a way to inject specific errors to test handled vs. unhandled errors. + - There is some support for sub resources which can cause issues with tests if you're trying to update + e.g. metadata and status in the same reconcile. + - No OpenAPI validation is performed when creating or updating objects. + - ObjectMeta's `Generation` and `ResourceVersion` don't behave properly, Patch or Update + operations that rely on these fields will fail, or give false positives. +*/ +package fake diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go new file mode 100644 index 00000000000..3d3f3cb0118 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go @@ -0,0 +1,166 @@ +package interceptor + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Funcs contains functions that are called instead of the underlying client's methods. +type Funcs struct { + Get func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error + List func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error + Create func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error + Delete func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error + DeleteAllOf func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error + Update func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error + Patch func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error + Watch func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) + SubResource func(client client.WithWatch, subResource string) client.SubResourceClient + SubResourceGet func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error + SubResourceCreate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error + SubResourceUpdate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error + SubResourcePatch func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error +} + +// NewClient returns a new interceptor client that calls the functions in funcs instead of the underlying client's methods, if they are not nil. +func NewClient(interceptedClient client.WithWatch, funcs Funcs) client.WithWatch { + return interceptor{ + client: interceptedClient, + funcs: funcs, + } +} + +type interceptor struct { + client client.WithWatch + funcs Funcs +} + +var _ client.WithWatch = &interceptor{} + +func (c interceptor) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return c.client.GroupVersionKindFor(obj) +} + +func (c interceptor) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return c.client.IsObjectNamespaced(obj) +} + +func (c interceptor) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + if c.funcs.Get != nil { + return c.funcs.Get(ctx, c.client, key, obj, opts...) + } + return c.client.Get(ctx, key, obj, opts...) +} + +func (c interceptor) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + if c.funcs.List != nil { + return c.funcs.List(ctx, c.client, list, opts...) + } + return c.client.List(ctx, list, opts...) +} + +func (c interceptor) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { + if c.funcs.Create != nil { + return c.funcs.Create(ctx, c.client, obj, opts...) + } + return c.client.Create(ctx, obj, opts...) +} + +func (c interceptor) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { + if c.funcs.Delete != nil { + return c.funcs.Delete(ctx, c.client, obj, opts...) + } + return c.client.Delete(ctx, obj, opts...) +} + +func (c interceptor) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { + if c.funcs.Update != nil { + return c.funcs.Update(ctx, c.client, obj, opts...) + } + return c.client.Update(ctx, obj, opts...) +} + +func (c interceptor) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + if c.funcs.Patch != nil { + return c.funcs.Patch(ctx, c.client, obj, patch, opts...) + } + return c.client.Patch(ctx, obj, patch, opts...) +} + +func (c interceptor) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { + if c.funcs.DeleteAllOf != nil { + return c.funcs.DeleteAllOf(ctx, c.client, obj, opts...) + } + return c.client.DeleteAllOf(ctx, obj, opts...) +} + +func (c interceptor) Status() client.SubResourceWriter { + return c.SubResource("status") +} + +func (c interceptor) SubResource(subResource string) client.SubResourceClient { + if c.funcs.SubResource != nil { + return c.funcs.SubResource(c.client, subResource) + } + return subResourceInterceptor{ + subResourceName: subResource, + client: c.client, + funcs: c.funcs, + } +} + +func (c interceptor) Scheme() *runtime.Scheme { + return c.client.Scheme() +} + +func (c interceptor) RESTMapper() meta.RESTMapper { + return c.client.RESTMapper() +} + +func (c interceptor) Watch(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + if c.funcs.Watch != nil { + return c.funcs.Watch(ctx, c.client, obj, opts...) + } + return c.client.Watch(ctx, obj, opts...) +} + +type subResourceInterceptor struct { + subResourceName string + client client.Client + funcs Funcs +} + +var _ client.SubResourceClient = &subResourceInterceptor{} + +func (s subResourceInterceptor) Get(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error { + if s.funcs.SubResourceGet != nil { + return s.funcs.SubResourceGet(ctx, s.client, s.subResourceName, obj, subResource, opts...) + } + return s.client.SubResource(s.subResourceName).Get(ctx, obj, subResource, opts...) +} + +func (s subResourceInterceptor) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error { + if s.funcs.SubResourceCreate != nil { + return s.funcs.SubResourceCreate(ctx, s.client, s.subResourceName, obj, subResource, opts...) + } + return s.client.SubResource(s.subResourceName).Create(ctx, obj, subResource, opts...) +} + +func (s subResourceInterceptor) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + if s.funcs.SubResourceUpdate != nil { + return s.funcs.SubResourceUpdate(ctx, s.client, s.subResourceName, obj, opts...) + } + return s.client.SubResource(s.subResourceName).Update(ctx, obj, opts...) +} + +func (s subResourceInterceptor) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + if s.funcs.SubResourcePatch != nil { + return s.funcs.SubResourcePatch(ctx, s.client, s.subResourceName, obj, patch, opts...) + } + return s.client.SubResource(s.subResourceName).Patch(ctx, obj, patch, opts...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept_test.go new file mode 100644 index 00000000000..a0536789b17 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept_test.go @@ -0,0 +1,393 @@ +package interceptor + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("NewClient", func() { + wrappedClient := dummyClient{} + ctx := context.Background() + It("should call the provided Get function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Get: func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + called = true + return nil + }, + }) + _ = client.Get(ctx, types.NamespacedName{}, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Get function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Get: func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.Get(ctx, types.NamespacedName{}, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided List function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + List: func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error { + called = true + return nil + }, + }) + _ = client.List(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided List function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + List: func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.List(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Create function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Create: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error { + called = true + return nil + }, + }) + _ = client.Create(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Create function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Create: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.Create(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Delete function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Delete: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error { + called = true + return nil + }, + }) + _ = client.Delete(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Delete function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Delete: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.Delete(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided DeleteAllOf function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + DeleteAllOf: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error { + called = true + return nil + }, + }) + _ = client.DeleteAllOf(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided DeleteAllOf function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + DeleteAllOf: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.DeleteAllOf(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Update function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Update: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error { + called = true + return nil + }, + }) + _ = client.Update(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Update function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Update: func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.Update(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Patch function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Patch: func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + called = true + return nil + }, + }) + _ = client.Patch(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Patch function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Patch: func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + called = true + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.Patch(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Watch function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + Watch: func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + called = true + return nil, nil + }, + }) + _, _ = client.Watch(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Watch function is nil", func() { + var called bool + client1 := NewClient(wrappedClient, Funcs{ + Watch: func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + called = true + return nil, nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _, _ = client2.Watch(ctx, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided SubResource function", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + SubResource: func(client client.WithWatch, subResource string) client.SubResourceClient { + called = true + return nil + }, + }) + _ = client.SubResource("") + Expect(called).To(BeTrue()) + }) + It("should call the provided SubResource function with 'status' when calling Status()", func() { + var called bool + client := NewClient(wrappedClient, Funcs{ + SubResource: func(client client.WithWatch, subResource string) client.SubResourceClient { + if subResource == "status" { + called = true + } + return nil + }, + }) + _ = client.Status() + Expect(called).To(BeTrue()) + }) +}) + +var _ = Describe("NewSubResourceClient", func() { + c := dummyClient{} + ctx := context.Background() + It("should call the provided Get function", func() { + var called bool + c := NewClient(c, Funcs{ + SubResourceGet: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceGetOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + _ = c.SubResource("foo").Get(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Get function is nil", func() { + var called bool + client1 := NewClient(c, Funcs{ + SubResourceGet: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceGetOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.SubResource("foo").Get(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Update function", func() { + var called bool + client := NewClient(c, Funcs{ + SubResourceUpdate: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + _ = client.SubResource("foo").Update(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Update function is nil", func() { + var called bool + client1 := NewClient(c, Funcs{ + SubResourceUpdate: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.SubResource("foo").Update(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Patch function", func() { + var called bool + client := NewClient(c, Funcs{ + SubResourcePatch: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + _ = client.SubResource("foo").Patch(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Patch function is nil", func() { + var called bool + client1 := NewClient(c, Funcs{ + SubResourcePatch: func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.SubResource("foo").Patch(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the provided Create function", func() { + var called bool + client := NewClient(c, Funcs{ + SubResourceCreate: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceCreateOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + _ = client.SubResource("foo").Create(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) + It("should call the underlying client if the provided Create function is nil", func() { + var called bool + client1 := NewClient(c, Funcs{ + SubResourceCreate: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceCreateOption) error { + called = true + Expect(subResourceName).To(BeEquivalentTo("foo")) + return nil + }, + }) + client2 := NewClient(client1, Funcs{}) + _ = client2.SubResource("foo").Create(ctx, nil, nil) + Expect(called).To(BeTrue()) + }) +}) + +type dummyClient struct{} + +var _ client.WithWatch = &dummyClient{} + +func (d dummyClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + return nil +} + +func (d dummyClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + return nil +} + +func (d dummyClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { + return nil +} + +func (d dummyClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { + return nil +} + +func (d dummyClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { + return nil +} + +func (d dummyClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + return nil +} + +func (d dummyClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { + return nil +} + +func (d dummyClient) Status() client.SubResourceWriter { + return d.SubResource("status") +} + +func (d dummyClient) SubResource(subResource string) client.SubResourceClient { + return nil +} + +func (d dummyClient) Scheme() *runtime.Scheme { + return nil +} + +func (d dummyClient) RESTMapper() meta.RESTMapper { + return nil +} + +func (d dummyClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return schema.GroupVersionKind{}, nil +} + +func (d dummyClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return false, nil +} + +func (d dummyClient) Watch(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + return nil, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/interceptor_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/interceptor_suite_test.go new file mode 100644 index 00000000000..08d9fe22812 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interceptor/interceptor_suite_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package interceptor + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestInterceptor(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Fake client Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go new file mode 100644 index 00000000000..0ddda3163d8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go @@ -0,0 +1,222 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +// ObjectKey identifies a Kubernetes Object. +type ObjectKey = types.NamespacedName + +// ObjectKeyFromObject returns the ObjectKey given a runtime.Object. +func ObjectKeyFromObject(obj Object) ObjectKey { + return ObjectKey{Namespace: obj.GetNamespace(), Name: obj.GetName()} +} + +// Patch is a patch that can be applied to a Kubernetes object. +type Patch interface { + // Type is the PatchType of the patch. + Type() types.PatchType + // Data is the raw data representing the patch. + Data(obj Object) ([]byte, error) +} + +// TODO(directxman12): is there a sane way to deal with get/delete options? + +// Reader knows how to read and list Kubernetes objects. +type Reader interface { + // Get retrieves an obj for the given object key from the Kubernetes Cluster. + // obj must be a struct pointer so that obj can be updated with the response + // returned by the Server. + Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error + + // List retrieves list of objects for a given namespace and list options. On a + // successful call, Items field in the list will be populated with the + // result returned from the server. + List(ctx context.Context, list ObjectList, opts ...ListOption) error +} + +// Writer knows how to create, delete, and update Kubernetes objects. +type Writer interface { + // Create saves the object obj in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. + Create(ctx context.Context, obj Object, opts ...CreateOption) error + + // Delete deletes the given obj from Kubernetes cluster. + Delete(ctx context.Context, obj Object, opts ...DeleteOption) error + + // Update updates the given obj in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. + Update(ctx context.Context, obj Object, opts ...UpdateOption) error + + // Patch patches the given obj in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. + Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error + + // DeleteAllOf deletes all objects of the given type matching the given options. + DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error +} + +// StatusClient knows how to create a client which can update status subresource +// for kubernetes objects. +type StatusClient interface { + Status() SubResourceWriter +} + +// SubResourceClientConstructor knows how to create a client which can update subresource +// for kubernetes objects. +type SubResourceClientConstructor interface { + // SubResourceClientConstructor returns a subresource client for the named subResource. Known + // upstream subResources usages are: + // - ServiceAccount token creation: + // sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // token := &authenticationv1.TokenRequest{} + // c.SubResourceClient("token").Create(ctx, sa, token) + // + // - Pod eviction creation: + // pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // c.SubResourceClient("eviction").Create(ctx, pod, &policyv1.Eviction{}) + // + // - Pod binding creation: + // pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // binding := &corev1.Binding{Target: corev1.ObjectReference{Name: "my-node"}} + // c.SubResourceClient("binding").Create(ctx, pod, binding) + // + // - CertificateSigningRequest approval: + // csr := &certificatesv1.CertificateSigningRequest{ + // ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}, + // Status: certificatesv1.CertificateSigningRequestStatus{ + // Conditions: []certificatesv1.[]CertificateSigningRequestCondition{{ + // Type: certificatesv1.CertificateApproved, + // Status: corev1.ConditionTrue, + // }}, + // }, + // } + // c.SubResourceClient("approval").Update(ctx, csr) + // + // - Scale retrieval: + // dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // scale := &autoscalingv1.Scale{} + // c.SubResourceClient("scale").Get(ctx, dep, scale) + // + // - Scale update: + // dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: 2}} + // c.SubResourceClient("scale").Update(ctx, dep, client.WithSubResourceBody(scale)) + SubResource(subResource string) SubResourceClient +} + +// StatusWriter is kept for backward compatibility. +type StatusWriter = SubResourceWriter + +// SubResourceReader knows how to read SubResources +type SubResourceReader interface { + Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error +} + +// SubResourceWriter knows how to update subresource of a Kubernetes object. +type SubResourceWriter interface { + // Create saves the subResource object in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. + Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error + // Update updates the fields corresponding to the status subresource for the + // given obj. obj must be a struct pointer so that obj can be updated + // with the content returned by the Server. + Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error + + // Patch patches the given object's subresource. obj must be a struct + // pointer so that obj can be updated with the content returned by the + // Server. + Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error +} + +// SubResourceClient knows how to perform CRU operations on Kubernetes objects. +type SubResourceClient interface { + SubResourceReader + SubResourceWriter +} + +// Client knows how to perform CRUD operations on Kubernetes objects. +type Client interface { + Reader + Writer + StatusClient + SubResourceClientConstructor + + // Scheme returns the scheme this client is using. + Scheme() *runtime.Scheme + // RESTMapper returns the rest this client is using. + RESTMapper() meta.RESTMapper + // GroupVersionKindFor returns the GroupVersionKind for the given object. + GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) + // IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. + IsObjectNamespaced(obj runtime.Object) (bool, error) +} + +// WithWatch supports Watch on top of the CRUD operations supported by +// the normal Client. Its intended use-case are CLI apps that need to wait for +// events. +type WithWatch interface { + Client + Watch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error) +} + +// IndexerFunc knows how to take an object and turn it into a series +// of non-namespaced keys. Namespaced objects are automatically given +// namespaced and non-spaced variants, so keys do not need to include namespace. +type IndexerFunc func(Object) []string + +// FieldIndexer knows how to index over a particular "field" such that it +// can later be used by a field selector. +type FieldIndexer interface { + // IndexFields adds an index with the given field name on the given object type + // by using the given function to extract the value for that field. If you want + // compatibility with the Kubernetes API server, only return one key, and only use + // fields that the API server supports. Otherwise, you can return multiple keys, + // and "equality" in the field selector means that at least one key matches the value. + // The FieldIndexer will automatically take care of indexing over namespace + // and supporting efficient all-namespace queries. + IndexField(ctx context.Context, obj Object, field string, extractValue IndexerFunc) error +} + +// IgnoreNotFound returns nil on NotFound errors. +// All other values that are not NotFound errors or nil are returned unmodified. +func IgnoreNotFound(err error) error { + if apierrors.IsNotFound(err) { + return nil + } + return err +} + +// IgnoreAlreadyExists returns nil on AlreadyExists errors. +// All other values that are not AlreadyExists errors or nil are returned unmodified. +func IgnoreAlreadyExists(err error) error { + if apierrors.IsAlreadyExists(err) { + return nil + } + + return err +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go new file mode 100644 index 00000000000..d0c6b8e13ae --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go @@ -0,0 +1,204 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/metadata" +) + +// TODO(directxman12): we could rewrite this on top of the low-level REST +// client to avoid the extra shallow copy at the end, but I'm not sure it's +// worth it -- the metadata client deals with falling back to loading the whole +// object on older API servers, etc, and we'd have to reproduce that. + +// metadataClient is a client that reads & writes metadata-only requests to/from the API server. +type metadataClient struct { + client metadata.Interface + restMapper meta.RESTMapper +} + +func (mc *metadataClient) getResourceInterface(gvk schema.GroupVersionKind, ns string) (metadata.ResourceInterface, error) { + mapping, err := mc.restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + if mapping.Scope.Name() == meta.RESTScopeNameRoot { + return mc.client.Resource(mapping.Resource), nil + } + return mc.client.Resource(mapping.Resource).Namespace(ns), nil +} + +// Delete implements client.Client. +func (mc *metadataClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadata) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + resInt, err := mc.getResourceInterface(metadata.GroupVersionKind(), metadata.Namespace) + if err != nil { + return err + } + + deleteOpts := DeleteOptions{} + deleteOpts.ApplyOptions(opts) + + return resInt.Delete(ctx, metadata.Name, *deleteOpts.AsDeleteOptions()) +} + +// DeleteAllOf implements client.Client. +func (mc *metadataClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadata) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + deleteAllOfOpts := DeleteAllOfOptions{} + deleteAllOfOpts.ApplyOptions(opts) + + resInt, err := mc.getResourceInterface(metadata.GroupVersionKind(), deleteAllOfOpts.ListOptions.Namespace) + if err != nil { + return err + } + + return resInt.DeleteCollection(ctx, *deleteAllOfOpts.AsDeleteOptions(), *deleteAllOfOpts.AsListOptions()) +} + +// Patch implements client.Client. +func (mc *metadataClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadata) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + gvk := metadata.GroupVersionKind() + resInt, err := mc.getResourceInterface(gvk, metadata.Namespace) + if err != nil { + return err + } + + data, err := patch.Data(obj) + if err != nil { + return err + } + + patchOpts := &PatchOptions{} + patchOpts.ApplyOptions(opts) + + res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions()) + if err != nil { + return err + } + *metadata = *res + metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata + return nil +} + +// Get implements client.Client. +func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadata) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + gvk := metadata.GroupVersionKind() + + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) + + resInt, err := mc.getResourceInterface(gvk, key.Namespace) + if err != nil { + return err + } + + res, err := resInt.Get(ctx, key.Name, *getOpts.AsGetOptions()) + if err != nil { + return err + } + *metadata = *res + metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata + return nil +} + +// List implements client.Client. +func (mc *metadataClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadataList) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + gvk := metadata.GroupVersionKind() + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + listOpts := ListOptions{} + listOpts.ApplyOptions(opts) + + resInt, err := mc.getResourceInterface(gvk, listOpts.Namespace) + if err != nil { + return err + } + + res, err := resInt.List(ctx, *listOpts.AsListOptions()) + if err != nil { + return err + } + *metadata = *res + metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata + return nil +} + +func (mc *metadataClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { + metadata, ok := obj.(*metav1.PartialObjectMetadata) + if !ok { + return fmt.Errorf("metadata client did not understand object: %T", obj) + } + + gvk := metadata.GroupVersionKind() + resInt, err := mc.getResourceInterface(gvk, metadata.Namespace) + if err != nil { + return err + } + + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) + if err != nil { + return err + } + + res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions(), subResource) + if err != nil { + return err + } + + *metadata = *res + metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go new file mode 100644 index 00000000000..222dc795793 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go @@ -0,0 +1,262 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NewNamespacedClient wraps an existing client enforcing the namespace value. +// All functions using this client will have the same namespace declared here. +func NewNamespacedClient(c Client, ns string) Client { + return &namespacedClient{ + client: c, + namespace: ns, + } +} + +var _ Client = &namespacedClient{} + +// namespacedClient is a Client that wraps another Client in order to enforce the specified namespace value. +type namespacedClient struct { + namespace string + client Client +} + +// Scheme returns the scheme this client is using. +func (n *namespacedClient) Scheme() *runtime.Scheme { + return n.client.Scheme() +} + +// RESTMapper returns the scheme this client is using. +func (n *namespacedClient) RESTMapper() meta.RESTMapper { + return n.client.RESTMapper() +} + +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (n *namespacedClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return n.client.GroupVersionKindFor(obj) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (n *namespacedClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return n.client.IsObjectNamespaced(obj) +} + +// Create implements client.Client. +func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != n.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), n.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(n.namespace) + } + return n.client.Create(ctx, obj, opts...) +} + +// Update implements client.Client. +func (n *namespacedClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != n.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), n.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(n.namespace) + } + return n.client.Update(ctx, obj, opts...) +} + +// Delete implements client.Client. +func (n *namespacedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != n.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), n.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(n.namespace) + } + return n.client.Delete(ctx, obj, opts...) +} + +// DeleteAllOf implements client.Client. +func (n *namespacedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + if isNamespaceScoped { + opts = append(opts, InNamespace(n.namespace)) + } + return n.client.DeleteAllOf(ctx, obj, opts...) +} + +// Patch implements client.Client. +func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != n.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), n.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(n.namespace) + } + return n.client.Patch(ctx, obj, patch, opts...) +} + +// Get implements client.Client. +func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + if isNamespaceScoped { + if key.Namespace != "" && key.Namespace != n.namespace { + return fmt.Errorf("namespace %s provided for the object %s does not match the namespace %s on the client", key.Namespace, obj.GetName(), n.namespace) + } + key.Namespace = n.namespace + } + return n.client.Get(ctx, key, obj, opts...) +} + +// List implements client.Client. +func (n *namespacedClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + if n.namespace != "" { + opts = append(opts, InNamespace(n.namespace)) + } + return n.client.List(ctx, obj, opts...) +} + +// Status implements client.StatusClient. +func (n *namespacedClient) Status() SubResourceWriter { + return n.SubResource("status") +} + +// SubResource implements client.SubResourceClient. +func (n *namespacedClient) SubResource(subResource string) SubResourceClient { + return &namespacedClientSubResourceClient{client: n.client.SubResource(subResource), namespace: n.namespace, namespacedclient: n} +} + +// ensure namespacedClientSubResourceClient implements client.SubResourceClient. +var _ SubResourceClient = &namespacedClientSubResourceClient{} + +type namespacedClientSubResourceClient struct { + client SubResourceClient + namespace string + namespacedclient Client +} + +func (nsw *namespacedClientSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + + return nsw.client.Get(ctx, obj, subResource, opts...) +} + +func (nsw *namespacedClientSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + + return nsw.client.Create(ctx, obj, subResource, opts...) +} + +// Update implements client.SubResourceWriter. +func (nsw *namespacedClientSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + return nsw.client.Update(ctx, obj, opts...) +} + +// Patch implements client.SubResourceWriter. +func (nsw *namespacedClientSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + return nsw.client.Patch(ctx, obj, patch, opts...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client_test.go new file mode 100644 index 00000000000..1692b7fcd9b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client_test.go @@ -0,0 +1,583 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "context" + "encoding/json" + "fmt" + "sync/atomic" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + rbacv1 "k8s.io/api/rbac/v1" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("NamespacedClient", func() { + var dep *appsv1.Deployment + var ns = "default" + ctx := context.Background() + var count uint64 = 0 + var replicaCount int32 = 2 + + getClient := func() client.Client { + var sch = runtime.NewScheme() + + err := rbacv1.AddToScheme(sch) + Expect(err).To(BeNil()) + err = appsv1.AddToScheme(sch) + Expect(err).To(BeNil()) + + nonNamespacedClient, err := client.New(cfg, client.Options{Scheme: sch}) + Expect(err).NotTo(HaveOccurred()) + Expect(nonNamespacedClient).NotTo(BeNil()) + return client.NewNamespacedClient(nonNamespacedClient, ns) + } + + BeforeEach(func() { + atomic.AddUint64(&count, 1) + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("namespaced-deployment-%v", count), + Labels: map[string]string{"name": fmt.Sprintf("namespaced-deployment-%v", count)}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + }) + + Describe("Get", func() { + + BeforeEach(func() { + var err error + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + It("should successfully Get a namespace-scoped object", func() { + name := types.NamespacedName{Name: dep.Name} + result := &appsv1.Deployment{} + + Expect(getClient().Get(ctx, name, result)).NotTo(HaveOccurred()) + Expect(result).To(BeEquivalentTo(dep)) + }) + + It("should error when namespace provided in the object is different than the one "+ + "specified in client", func() { + name := types.NamespacedName{Name: dep.Name, Namespace: "non-default"} + result := &appsv1.Deployment{} + + Expect(getClient().Get(ctx, name, result)).To(HaveOccurred()) + }) + }) + + Describe("List", func() { + BeforeEach(func() { + var err error + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should successfully List objects when namespace is not specified with the object", func() { + result := &appsv1.DeploymentList{} + opts := client.MatchingLabels(dep.Labels) + + Expect(getClient().List(ctx, result, opts)).NotTo(HaveOccurred()) + Expect(len(result.Items)).To(BeEquivalentTo(1)) + Expect(result.Items[0]).To(BeEquivalentTo(*dep)) + }) + + It("should List objects from the namespace specified in the client", func() { + result := &appsv1.DeploymentList{} + opts := client.InNamespace("non-default") + + Expect(getClient().List(ctx, result, opts)).NotTo(HaveOccurred()) + Expect(len(result.Items)).To(BeEquivalentTo(1)) + Expect(result.Items[0]).To(BeEquivalentTo(*dep)) + }) + }) + + Describe("Create", func() { + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should successfully create object in the right namespace", func() { + By("creating the object initially") + err := getClient().Create(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("checking if the object was created in the right namespace") + res, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(res.GetNamespace()).To(BeEquivalentTo(ns)) + }) + + It("should not create object if the namespace of the object is different", func() { + By("creating the object initially") + dep.SetNamespace("non-default") + err := getClient().Create(ctx, dep) + Expect(err).To(HaveOccurred()) + }) + It("should create a cluster scoped object", func() { + cr := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("clusterRole-%v", count), + Labels: map[string]string{"name": fmt.Sprintf("clusterRole-%v", count)}, + }, + } + cr.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + }) + + By("creating the object initially") + err := getClient().Create(ctx, cr) + Expect(err).NotTo(HaveOccurred()) + + By("checking if the object was created") + res, err := clientset.RbacV1().ClusterRoles().Get(ctx, cr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(res).NotTo(BeNil()) + + // Delete the clusterRole Resource + deleteClusterRole(ctx, cr) + }) + }) + + Describe("Update", func() { + var err error + BeforeEach(func() { + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + dep.Annotations = map[string]string{"foo": "bar"} + Expect(err).NotTo(HaveOccurred()) + }) + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should successfully update the provided object", func() { + By("updating the Deployment") + err = getClient().Update(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating if the updated Deployment has new annotation") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.GetNamespace()).To(Equal(ns)) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + + It("should successfully update the provided object when namespace is not provided", func() { + By("updating the Deployment") + dep.SetNamespace("") + err = getClient().Update(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating if the updated Deployment has new annotation") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.GetNamespace()).To(Equal(ns)) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + }) + + It("should not update when object namespace is different", func() { + By("updating the Deployment") + dep.SetNamespace("non-default") + err = getClient().Update(ctx, dep) + Expect(err).To(HaveOccurred()) + }) + + It("should not update any object from other namespace", func() { + By("creating a new namespace") + tns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "non-default-1"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + changedDep := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "changed-dep", + Namespace: tns.Name, + Labels: map[string]string{"name": "changed-dep"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + changedDep.Annotations = map[string]string{"foo": "bar"} + + By("creating the object initially") + _, err = clientset.AppsV1().Deployments(tns.Name).Create(ctx, changedDep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the object") + err = getClient().Update(ctx, changedDep) + Expect(err).To(HaveOccurred()) + + deleteDeployment(ctx, changedDep, tns.Name) + deleteNamespace(ctx, tns) + }) + + It("should update a cluster scoped resource", func() { + changedCR := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("clusterRole-%v", count), + Labels: map[string]string{"name": fmt.Sprintf("clusterRole-%v", count)}, + }, + } + + changedCR.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + }) + + By("Setting annotations and creating the resource") + changedCR.Annotations = map[string]string{"foo": "bar"} + changedCR, err = clientset.RbacV1().ClusterRoles().Create(ctx, changedCR, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("updating the deployment") + err = getClient().Update(ctx, changedCR) + + By("validating if the cluster role was update") + actual, err := clientset.RbacV1().ClusterRoles().Get(ctx, changedCR.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + + // delete cluster role resource + deleteClusterRole(ctx, changedCR) + }) + + }) + + Describe("Patch", func() { + var err error + BeforeEach(func() { + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should successfully modify the object using Patch", func() { + By("Applying Patch") + err = getClient().Patch(ctx, dep, client.RawPatch(types.MergePatchType, generatePatch())) + Expect(err).NotTo(HaveOccurred()) + + By("validating patched Deployment has new annotations") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + Expect(actual.GetNamespace()).To(Equal(ns)) + }) + + It("should successfully modify the object using Patch when namespace is not provided", func() { + By("Applying Patch") + dep.SetNamespace("") + err = getClient().Patch(ctx, dep, client.RawPatch(types.MergePatchType, generatePatch())) + Expect(err).NotTo(HaveOccurred()) + + By("validating patched Deployment has new annotations") + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + Expect(actual.GetNamespace()).To(Equal(ns)) + }) + + It("should not modify the object when namespace of the object is different", func() { + dep.SetNamespace("non-default") + err = getClient().Patch(ctx, dep, client.RawPatch(types.MergePatchType, generatePatch())) + Expect(err).To(HaveOccurred()) + }) + + It("should not modify an object from a different namespace", func() { + By("creating a new namespace") + tns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "non-default-2"}} + _, err := clientset.CoreV1().Namespaces().Create(ctx, tns, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + changedDep := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "changed-dep", + Namespace: tns.Name, + Labels: map[string]string{"name": "changed-dep"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + + By("creating the object initially") + changedDep, err = clientset.AppsV1().Deployments(tns.Name).Create(ctx, changedDep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + err = getClient().Patch(ctx, changedDep, client.RawPatch(types.MergePatchType, generatePatch())) + Expect(err).To(HaveOccurred()) + + deleteDeployment(ctx, changedDep, tns.Name) + deleteNamespace(ctx, tns) + }) + + It("should successfully modify cluster scoped resource", func() { + cr := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("clusterRole-%v", count), + Labels: map[string]string{"name": fmt.Sprintf("clusterRole-%v", count)}, + }, + } + + cr.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + }) + + By("creating the resource") + cr, err = clientset.RbacV1().ClusterRoles().Create(ctx, cr, metav1.CreateOptions{}) + Expect(err).ToNot(HaveOccurred()) + + By("Applying Patch") + err = getClient().Patch(ctx, cr, client.RawPatch(types.MergePatchType, generatePatch())) + Expect(err).NotTo(HaveOccurred()) + + By("Validating the patch") + actual, err := clientset.RbacV1().ClusterRoles().Get(ctx, cr.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual.Annotations["foo"]).To(Equal("bar")) + + // delete the resource + deleteClusterRole(ctx, cr) + }) + }) + + Describe("Delete and DeleteAllOf", func() { + var err error + BeforeEach(func() { + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + It("should successfully delete an object when namespace is not specified", func() { + By("deleting the object") + dep.SetNamespace("") + err = getClient().Delete(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should successfully delete all of the deployments in the given namespace", func() { + By("Deleting all objects in the namespace") + err = getClient().DeleteAllOf(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment no longer exists") + _, err = clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).To(HaveOccurred()) + }) + + It("should not delete deployments in other namespaces", func() { + tns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "non-default-3"}} + _, err = clientset.CoreV1().Namespaces().Create(ctx, tns, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + changedDep := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "changed-dep", + Namespace: tns.Name, + Labels: map[string]string{"name": "changed-dep"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + + By("creating the object initially in other namespace") + changedDep, err = clientset.AppsV1().Deployments(tns.Name).Create(ctx, changedDep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + err = getClient().DeleteAllOf(ctx, dep) + Expect(err).NotTo(HaveOccurred()) + + By("validating the Deployment exists") + actual, err := clientset.AppsV1().Deployments(tns.Name).Get(ctx, changedDep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).To(BeEquivalentTo(changedDep)) + + deleteDeployment(ctx, changedDep, tns.Name) + deleteNamespace(ctx, tns) + }) + }) + + Describe("SubResourceWriter", func() { + var err error + BeforeEach(func() { + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + It("should change objects via update status", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + + Expect(getClient().SubResource("status").Update(ctx, changedDep)).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.GetNamespace()).To(BeEquivalentTo(ns)) + Expect(actual.Status.Replicas).To(BeEquivalentTo(99)) + }) + + It("should not change objects via update status when object namespace is different", func() { + changedDep := dep.DeepCopy() + changedDep.SetNamespace("test") + changedDep.Status.Replicas = 99 + + Expect(getClient().SubResource("status").Update(ctx, changedDep)).To(HaveOccurred()) + }) + + It("should change objects via status patch", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + + Expect(getClient().SubResource("status").Patch(ctx, changedDep, client.MergeFrom(dep))).NotTo(HaveOccurred()) + + actual, err := clientset.AppsV1().Deployments(ns).Get(ctx, dep.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(actual).NotTo(BeNil()) + Expect(actual.GetNamespace()).To(BeEquivalentTo(ns)) + Expect(actual.Status.Replicas).To(BeEquivalentTo(99)) + }) + + It("should not change objects via status patch when object namespace is different", func() { + changedDep := dep.DeepCopy() + changedDep.Status.Replicas = 99 + changedDep.SetNamespace("test") + + Expect(getClient().SubResource("status").Patch(ctx, changedDep, client.MergeFrom(dep))).To(HaveOccurred()) + }) + }) + + Describe("Test on invalid objects", func() { + It("should refuse to perform operations on invalid object", func() { + err := getClient().Create(ctx, nil) + Expect(err).To(HaveOccurred()) + + err = getClient().List(ctx, nil) + Expect(err).To(HaveOccurred()) + + err = getClient().Patch(ctx, nil, client.MergeFrom(dep)) + Expect(err).To(HaveOccurred()) + + err = getClient().Update(ctx, nil) + Expect(err).To(HaveOccurred()) + + err = getClient().Delete(ctx, nil) + Expect(err).To(HaveOccurred()) + + err = getClient().Status().Patch(ctx, nil, client.MergeFrom(dep)) + Expect(err).To(HaveOccurred()) + + err = getClient().Status().Update(ctx, nil) + Expect(err).To(HaveOccurred()) + + }) + + }) +}) + +func generatePatch() []byte { + mergePatch, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{ + "foo": "bar", + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + return mergePatch +} + +func deleteClusterRole(ctx context.Context, cr *rbacv1.ClusterRole) { + _, err := clientset.RbacV1().ClusterRoles().Get(ctx, cr.Name, metav1.GetOptions{}) + if err == nil { + err = clientset.RbacV1().ClusterRoles().Delete(ctx, cr.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/object.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/object.go new file mode 100644 index 00000000000..31e334d6c2d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/object.go @@ -0,0 +1,77 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Object is a Kubernetes object, allows functions to work indistinctly with +// any resource that implements both Object interfaces. +// +// Semantically, these are objects which are both serializable (runtime.Object) +// and identifiable (metav1.Object) -- think any object which you could write +// as YAML or JSON, and then `kubectl create`. +// +// Code-wise, this means that any object which embeds both ObjectMeta (which +// provides metav1.Object) and TypeMeta (which provides half of runtime.Object) +// and has a `DeepCopyObject` implementation (the other half of runtime.Object) +// will implement this by default. +// +// For example, nearly all the built-in types are Objects, as well as all +// KubeBuilder-generated CRDs (unless you do something real funky to them). +// +// By and large, most things that implement runtime.Object also implement +// Object -- it's very rare to have *just* a runtime.Object implementation (the +// cases tend to be funky built-in types like Webhook payloads that don't have +// a `metadata` field). +// +// Notice that XYZList types are distinct: they implement ObjectList instead. +type Object interface { + metav1.Object + runtime.Object +} + +// ObjectList is a Kubernetes object list, allows functions to work +// indistinctly with any resource that implements both runtime.Object and +// metav1.ListInterface interfaces. +// +// Semantically, this is any object which may be serialized (ObjectMeta), and +// is a kubernetes list wrapper (has items, pagination fields, etc) -- think +// the wrapper used in a response from a `kubectl list --output yaml` call. +// +// Code-wise, this means that any object which embedds both ListMeta (which +// provides metav1.ListInterface) and TypeMeta (which provides half of +// runtime.Object) and has a `DeepCopyObject` implementation (the other half of +// runtime.Object) will implement this by default. +// +// For example, nearly all the built-in XYZList types are ObjectLists, as well +// as the XYZList types for all KubeBuilder-generated CRDs (unless you do +// something real funky to them). +// +// By and large, most things that are XYZList and implement runtime.Object also +// implement ObjectList -- it's very rare to have *just* a runtime.Object +// implementation (the cases tend to be funky built-in types like Webhook +// payloads that don't have a `metadata` field). +// +// This is similar to Object, which is almost always implemented by the items +// in the list themselves. +type ObjectList interface { + metav1.ListInterface + runtime.Object +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/options.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/options.go new file mode 100644 index 00000000000..50a461f1cc6 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/options.go @@ -0,0 +1,831 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" +) + +// {{{ "Functional" Option Interfaces + +// CreateOption is some configuration that modifies options for a create request. +type CreateOption interface { + // ApplyToCreate applies this configuration to the given create options. + ApplyToCreate(*CreateOptions) +} + +// DeleteOption is some configuration that modifies options for a delete request. +type DeleteOption interface { + // ApplyToDelete applies this configuration to the given delete options. + ApplyToDelete(*DeleteOptions) +} + +// GetOption is some configuration that modifies options for a get request. +type GetOption interface { + // ApplyToGet applies this configuration to the given get options. + ApplyToGet(*GetOptions) +} + +// ListOption is some configuration that modifies options for a list request. +type ListOption interface { + // ApplyToList applies this configuration to the given list options. + ApplyToList(*ListOptions) +} + +// UpdateOption is some configuration that modifies options for a update request. +type UpdateOption interface { + // ApplyToUpdate applies this configuration to the given update options. + ApplyToUpdate(*UpdateOptions) +} + +// PatchOption is some configuration that modifies options for a patch request. +type PatchOption interface { + // ApplyToPatch applies this configuration to the given patch options. + ApplyToPatch(*PatchOptions) +} + +// DeleteAllOfOption is some configuration that modifies options for a delete request. +type DeleteAllOfOption interface { + // ApplyToDeleteAllOf applies this configuration to the given deletecollection options. + ApplyToDeleteAllOf(*DeleteAllOfOptions) +} + +// SubResourceGetOption modifies options for a SubResource Get request. +type SubResourceGetOption interface { + ApplyToSubResourceGet(*SubResourceGetOptions) +} + +// SubResourceUpdateOption is some configuration that modifies options for a update request. +type SubResourceUpdateOption interface { + // ApplyToSubResourceUpdate applies this configuration to the given update options. + ApplyToSubResourceUpdate(*SubResourceUpdateOptions) +} + +// SubResourceCreateOption is some configuration that modifies options for a create request. +type SubResourceCreateOption interface { + // ApplyToSubResourceCreate applies this configuration to the given create options. + ApplyToSubResourceCreate(*SubResourceCreateOptions) +} + +// SubResourcePatchOption configures a subresource patch request. +type SubResourcePatchOption interface { + // ApplyToSubResourcePatch applies the configuration on the given patch options. + ApplyToSubResourcePatch(*SubResourcePatchOptions) +} + +// }}} + +// {{{ Multi-Type Options + +// DryRunAll sets the "dry run" option to "all", executing all +// validation, etc without persisting the change to storage. +var DryRunAll = dryRunAll{} + +type dryRunAll struct{} + +// ApplyToCreate applies this configuration to the given create options. +func (dryRunAll) ApplyToCreate(opts *CreateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +// ApplyToUpdate applies this configuration to the given update options. +func (dryRunAll) ApplyToUpdate(opts *UpdateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +// ApplyToPatch applies this configuration to the given patch options. +func (dryRunAll) ApplyToPatch(opts *PatchOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +// ApplyToPatch applies this configuration to the given delete options. +func (dryRunAll) ApplyToDelete(opts *DeleteOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +// FieldOwner set the field manager name for the given server-side apply patch. +type FieldOwner string + +// ApplyToPatch applies this configuration to the given patch options. +func (f FieldOwner) ApplyToPatch(opts *PatchOptions) { + opts.FieldManager = string(f) +} + +// ApplyToCreate applies this configuration to the given create options. +func (f FieldOwner) ApplyToCreate(opts *CreateOptions) { + opts.FieldManager = string(f) +} + +// ApplyToUpdate applies this configuration to the given update options. +func (f FieldOwner) ApplyToUpdate(opts *UpdateOptions) { + opts.FieldManager = string(f) +} + +// ApplyToSubResourcePatch applies this configuration to the given patch options. +func (f FieldOwner) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + opts.FieldManager = string(f) +} + +// ApplyToSubResourceCreate applies this configuration to the given create options. +func (f FieldOwner) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) { + opts.FieldManager = string(f) +} + +// ApplyToSubResourceUpdate applies this configuration to the given update options. +func (f FieldOwner) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) { + opts.FieldManager = string(f) +} + +// }}} + +// {{{ Create Options + +// CreateOptions contains options for create requests. It's generally a subset +// of metav1.CreateOptions. +type CreateOptions struct { + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in an error response and no further processing of the + // request. Valid values are: + // - All: all dry run stages will be processed + DryRun []string + + // FieldManager is the name of the user or component submitting + // this request. It must be set with server-side apply. + FieldManager string + + // Raw represents raw CreateOptions, as passed to the API server. + Raw *metav1.CreateOptions +} + +// AsCreateOptions returns these options as a metav1.CreateOptions. +// This may mutate the Raw field. +func (o *CreateOptions) AsCreateOptions() *metav1.CreateOptions { + if o == nil { + return &metav1.CreateOptions{} + } + if o.Raw == nil { + o.Raw = &metav1.CreateOptions{} + } + + o.Raw.DryRun = o.DryRun + o.Raw.FieldManager = o.FieldManager + return o.Raw +} + +// ApplyOptions applies the given create options on these options, +// and then returns itself (for convenient chaining). +func (o *CreateOptions) ApplyOptions(opts []CreateOption) *CreateOptions { + for _, opt := range opts { + opt.ApplyToCreate(o) + } + return o +} + +// ApplyToCreate implements CreateOption. +func (o *CreateOptions) ApplyToCreate(co *CreateOptions) { + if o.DryRun != nil { + co.DryRun = o.DryRun + } + if o.FieldManager != "" { + co.FieldManager = o.FieldManager + } + if o.Raw != nil { + co.Raw = o.Raw + } +} + +var _ CreateOption = &CreateOptions{} + +// }}} + +// {{{ Delete Options + +// DeleteOptions contains options for delete requests. It's generally a subset +// of metav1.DeleteOptions. +type DeleteOptions struct { + // GracePeriodSeconds is the duration in seconds before the object should be + // deleted. Value must be non-negative integer. The value zero indicates + // delete immediately. If this value is nil, the default grace period for the + // specified type will be used. + GracePeriodSeconds *int64 + + // Preconditions must be fulfilled before a deletion is carried out. If not + // possible, a 409 Conflict status will be returned. + Preconditions *metav1.Preconditions + + // PropagationPolicy determined whether and how garbage collection will be + // performed. Either this field or OrphanDependents may be set, but not both. + // The default policy is decided by the existing finalizer set in the + // metadata.finalizers and the resource-specific default policy. + // Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - + // allow the garbage collector to delete the dependents in the background; + // 'Foreground' - a cascading policy that deletes all dependents in the + // foreground. + PropagationPolicy *metav1.DeletionPropagation + + // Raw represents raw DeleteOptions, as passed to the API server. + Raw *metav1.DeleteOptions + + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in an error response and no further processing of the + // request. Valid values are: + // - All: all dry run stages will be processed + DryRun []string +} + +// AsDeleteOptions returns these options as a metav1.DeleteOptions. +// This may mutate the Raw field. +func (o *DeleteOptions) AsDeleteOptions() *metav1.DeleteOptions { + if o == nil { + return &metav1.DeleteOptions{} + } + if o.Raw == nil { + o.Raw = &metav1.DeleteOptions{} + } + + o.Raw.GracePeriodSeconds = o.GracePeriodSeconds + o.Raw.Preconditions = o.Preconditions + o.Raw.PropagationPolicy = o.PropagationPolicy + o.Raw.DryRun = o.DryRun + return o.Raw +} + +// ApplyOptions applies the given delete options on these options, +// and then returns itself (for convenient chaining). +func (o *DeleteOptions) ApplyOptions(opts []DeleteOption) *DeleteOptions { + for _, opt := range opts { + opt.ApplyToDelete(o) + } + return o +} + +var _ DeleteOption = &DeleteOptions{} + +// ApplyToDelete implements DeleteOption. +func (o *DeleteOptions) ApplyToDelete(do *DeleteOptions) { + if o.GracePeriodSeconds != nil { + do.GracePeriodSeconds = o.GracePeriodSeconds + } + if o.Preconditions != nil { + do.Preconditions = o.Preconditions + } + if o.PropagationPolicy != nil { + do.PropagationPolicy = o.PropagationPolicy + } + if o.Raw != nil { + do.Raw = o.Raw + } + if o.DryRun != nil { + do.DryRun = o.DryRun + } +} + +// GracePeriodSeconds sets the grace period for the deletion +// to the given number of seconds. +type GracePeriodSeconds int64 + +// ApplyToDelete applies this configuration to the given delete options. +func (s GracePeriodSeconds) ApplyToDelete(opts *DeleteOptions) { + secs := int64(s) + opts.GracePeriodSeconds = &secs +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (s GracePeriodSeconds) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + s.ApplyToDelete(&opts.DeleteOptions) +} + +// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out. +type Preconditions metav1.Preconditions + +// ApplyToDelete applies this configuration to the given delete options. +func (p Preconditions) ApplyToDelete(opts *DeleteOptions) { + preconds := metav1.Preconditions(p) + opts.Preconditions = &preconds +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (p Preconditions) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + p.ApplyToDelete(&opts.DeleteOptions) +} + +// PropagationPolicy determined whether and how garbage collection will be +// performed. Either this field or OrphanDependents may be set, but not both. +// The default policy is decided by the existing finalizer set in the +// metadata.finalizers and the resource-specific default policy. +// Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - +// allow the garbage collector to delete the dependents in the background; +// 'Foreground' - a cascading policy that deletes all dependents in the +// foreground. +type PropagationPolicy metav1.DeletionPropagation + +// ApplyToDelete applies the given delete options on these options. +// It will propagate to the dependents of the object to let the garbage collector handle it. +func (p PropagationPolicy) ApplyToDelete(opts *DeleteOptions) { + policy := metav1.DeletionPropagation(p) + opts.PropagationPolicy = &policy +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (p PropagationPolicy) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + p.ApplyToDelete(&opts.DeleteOptions) +} + +// }}} + +// {{{ Get Options + +// GetOptions contains options for get operation. +// Now it only has a Raw field, with support for specific resourceVersion. +type GetOptions struct { + // Raw represents raw GetOptions, as passed to the API server. Note + // that these may not be respected by all implementations of interface. + Raw *metav1.GetOptions +} + +var _ GetOption = &GetOptions{} + +// ApplyToGet implements GetOption for GetOptions. +func (o *GetOptions) ApplyToGet(lo *GetOptions) { + if o.Raw != nil { + lo.Raw = o.Raw + } +} + +// AsGetOptions returns these options as a flattened metav1.GetOptions. +// This may mutate the Raw field. +func (o *GetOptions) AsGetOptions() *metav1.GetOptions { + if o == nil || o.Raw == nil { + return &metav1.GetOptions{} + } + return o.Raw +} + +// ApplyOptions applies the given get options on these options, +// and then returns itself (for convenient chaining). +func (o *GetOptions) ApplyOptions(opts []GetOption) *GetOptions { + for _, opt := range opts { + opt.ApplyToGet(o) + } + return o +} + +// }}} + +// {{{ List Options + +// ListOptions contains options for limiting or filtering results. +// It's generally a subset of metav1.ListOptions, with support for +// pre-parsed selectors (since generally, selectors will be executed +// against the cache). +type ListOptions struct { + // LabelSelector filters results by label. Use labels.Parse() to + // set from raw string form. + LabelSelector labels.Selector + // FieldSelector filters results by a particular field. In order + // to use this with cache-based implementations, restrict usage to + // a single field-value pair that's been added to the indexers. + FieldSelector fields.Selector + + // Namespace represents the namespace to list for, or empty for + // non-namespaced objects, or to list across all namespaces. + Namespace string + + // Limit specifies the maximum number of results to return from the server. The server may + // not support this field on all resource types, but if it does and more results remain it + // will set the continue field on the returned list object. This field is not supported if watch + // is true in the Raw ListOptions. + Limit int64 + // Continue is a token returned by the server that lets a client retrieve chunks of results + // from the server by specifying limit. The server may reject requests for continuation tokens + // it does not recognize and will return a 410 error if the token can no longer be used because + // it has expired. This field is not supported if watch is true in the Raw ListOptions. + Continue string + + // UnsafeDisableDeepCopy indicates not to deep copy objects during list objects. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + // +optional + UnsafeDisableDeepCopy *bool + + // Raw represents raw ListOptions, as passed to the API server. Note + // that these may not be respected by all implementations of interface, + // and the LabelSelector, FieldSelector, Limit and Continue fields are ignored. + Raw *metav1.ListOptions +} + +var _ ListOption = &ListOptions{} + +// ApplyToList implements ListOption for ListOptions. +func (o *ListOptions) ApplyToList(lo *ListOptions) { + if o.LabelSelector != nil { + lo.LabelSelector = o.LabelSelector + } + if o.FieldSelector != nil { + lo.FieldSelector = o.FieldSelector + } + if o.Namespace != "" { + lo.Namespace = o.Namespace + } + if o.Raw != nil { + lo.Raw = o.Raw + } + if o.Limit > 0 { + lo.Limit = o.Limit + } + if o.Continue != "" { + lo.Continue = o.Continue + } + if o.UnsafeDisableDeepCopy != nil { + lo.UnsafeDisableDeepCopy = o.UnsafeDisableDeepCopy + } +} + +// AsListOptions returns these options as a flattened metav1.ListOptions. +// This may mutate the Raw field. +func (o *ListOptions) AsListOptions() *metav1.ListOptions { + if o == nil { + return &metav1.ListOptions{} + } + if o.Raw == nil { + o.Raw = &metav1.ListOptions{} + } + if o.LabelSelector != nil { + o.Raw.LabelSelector = o.LabelSelector.String() + } + if o.FieldSelector != nil { + o.Raw.FieldSelector = o.FieldSelector.String() + } + if !o.Raw.Watch { + o.Raw.Limit = o.Limit + o.Raw.Continue = o.Continue + } + return o.Raw +} + +// ApplyOptions applies the given list options on these options, +// and then returns itself (for convenient chaining). +func (o *ListOptions) ApplyOptions(opts []ListOption) *ListOptions { + for _, opt := range opts { + opt.ApplyToList(o) + } + return o +} + +// MatchingLabels filters the list/delete operation on the given set of labels. +type MatchingLabels map[string]string + +// ApplyToList applies this configuration to the given list options. +func (m MatchingLabels) ApplyToList(opts *ListOptions) { + // TODO(directxman12): can we avoid reserializing this over and over? + sel := labels.SelectorFromValidatedSet(map[string]string(m)) + opts.LabelSelector = sel +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (m MatchingLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + m.ApplyToList(&opts.ListOptions) +} + +// HasLabels filters the list/delete operation checking if the set of labels exists +// without checking their values. +type HasLabels []string + +// ApplyToList applies this configuration to the given list options. +func (m HasLabels) ApplyToList(opts *ListOptions) { + sel := labels.NewSelector() + for _, label := range m { + r, err := labels.NewRequirement(label, selection.Exists, nil) + if err == nil { + sel = sel.Add(*r) + } + } + opts.LabelSelector = sel +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (m HasLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + m.ApplyToList(&opts.ListOptions) +} + +// MatchingLabelsSelector filters the list/delete operation on the given label +// selector (or index in the case of cached lists). A struct is used because +// labels.Selector is an interface, which cannot be aliased. +type MatchingLabelsSelector struct { + labels.Selector +} + +// ApplyToList applies this configuration to the given list options. +func (m MatchingLabelsSelector) ApplyToList(opts *ListOptions) { + opts.LabelSelector = m +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (m MatchingLabelsSelector) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + m.ApplyToList(&opts.ListOptions) +} + +// MatchingFields filters the list/delete operation on the given field Set +// (or index in the case of cached lists). +type MatchingFields fields.Set + +// ApplyToList applies this configuration to the given list options. +func (m MatchingFields) ApplyToList(opts *ListOptions) { + // TODO(directxman12): can we avoid re-serializing this? + sel := fields.Set(m).AsSelector() + opts.FieldSelector = sel +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (m MatchingFields) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + m.ApplyToList(&opts.ListOptions) +} + +// MatchingFieldsSelector filters the list/delete operation on the given field +// selector (or index in the case of cached lists). A struct is used because +// fields.Selector is an interface, which cannot be aliased. +type MatchingFieldsSelector struct { + fields.Selector +} + +// ApplyToList applies this configuration to the given list options. +func (m MatchingFieldsSelector) ApplyToList(opts *ListOptions) { + opts.FieldSelector = m +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (m MatchingFieldsSelector) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + m.ApplyToList(&opts.ListOptions) +} + +// InNamespace restricts the list/delete operation to the given namespace. +type InNamespace string + +// ApplyToList applies this configuration to the given list options. +func (n InNamespace) ApplyToList(opts *ListOptions) { + opts.Namespace = string(n) +} + +// ApplyToDeleteAllOf applies this configuration to the given an List options. +func (n InNamespace) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { + n.ApplyToList(&opts.ListOptions) +} + +// AsSelector returns a selector that matches objects in the given namespace. +func (n InNamespace) AsSelector() fields.Selector { + return fields.SelectorFromSet(fields.Set{"metadata.namespace": string(n)}) +} + +// Limit specifies the maximum number of results to return from the server. +// Limit does not implement DeleteAllOfOption interface because the server +// does not support setting it for deletecollection operations. +type Limit int64 + +// ApplyToList applies this configuration to the given an list options. +func (l Limit) ApplyToList(opts *ListOptions) { + opts.Limit = int64(l) +} + +// UnsafeDisableDeepCopyOption indicates not to deep copy objects during list objects. +// Be very careful with this, when enabled you must DeepCopy any object before mutating it, +// otherwise you will mutate the object in the cache. +type UnsafeDisableDeepCopyOption bool + +// ApplyToList applies this configuration to the given an List options. +func (d UnsafeDisableDeepCopyOption) ApplyToList(opts *ListOptions) { + definitelyTrue := true + definitelyFalse := false + if d { + opts.UnsafeDisableDeepCopy = &definitelyTrue + } else { + opts.UnsafeDisableDeepCopy = &definitelyFalse + } +} + +// UnsafeDisableDeepCopy indicates not to deep copy objects during list objects. +const UnsafeDisableDeepCopy = UnsafeDisableDeepCopyOption(true) + +// Continue sets a continuation token to retrieve chunks of results when using limit. +// Continue does not implement DeleteAllOfOption interface because the server +// does not support setting it for deletecollection operations. +type Continue string + +// ApplyToList applies this configuration to the given an List options. +func (c Continue) ApplyToList(opts *ListOptions) { + opts.Continue = string(c) +} + +// }}} + +// {{{ Update Options + +// UpdateOptions contains options for create requests. It's generally a subset +// of metav1.UpdateOptions. +type UpdateOptions struct { + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in an error response and no further processing of the + // request. Valid values are: + // - All: all dry run stages will be processed + DryRun []string + + // FieldManager is the name of the user or component submitting + // this request. It must be set with server-side apply. + FieldManager string + + // Raw represents raw UpdateOptions, as passed to the API server. + Raw *metav1.UpdateOptions +} + +// AsUpdateOptions returns these options as a metav1.UpdateOptions. +// This may mutate the Raw field. +func (o *UpdateOptions) AsUpdateOptions() *metav1.UpdateOptions { + if o == nil { + return &metav1.UpdateOptions{} + } + if o.Raw == nil { + o.Raw = &metav1.UpdateOptions{} + } + + o.Raw.DryRun = o.DryRun + o.Raw.FieldManager = o.FieldManager + return o.Raw +} + +// ApplyOptions applies the given update options on these options, +// and then returns itself (for convenient chaining). +func (o *UpdateOptions) ApplyOptions(opts []UpdateOption) *UpdateOptions { + for _, opt := range opts { + opt.ApplyToUpdate(o) + } + return o +} + +var _ UpdateOption = &UpdateOptions{} + +// ApplyToUpdate implements UpdateOption. +func (o *UpdateOptions) ApplyToUpdate(uo *UpdateOptions) { + if o.DryRun != nil { + uo.DryRun = o.DryRun + } + if o.FieldManager != "" { + uo.FieldManager = o.FieldManager + } + if o.Raw != nil { + uo.Raw = o.Raw + } +} + +// }}} + +// {{{ Patch Options + +// PatchOptions contains options for patch requests. +type PatchOptions struct { + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in an error response and no further processing of the + // request. Valid values are: + // - All: all dry run stages will be processed + DryRun []string + + // Force is going to "force" Apply requests. It means user will + // re-acquire conflicting fields owned by other people. Force + // flag must be unset for non-apply patch requests. + // +optional + Force *bool + + // FieldManager is the name of the user or component submitting + // this request. It must be set with server-side apply. + FieldManager string + + // Raw represents raw PatchOptions, as passed to the API server. + Raw *metav1.PatchOptions +} + +// ApplyOptions applies the given patch options on these options, +// and then returns itself (for convenient chaining). +func (o *PatchOptions) ApplyOptions(opts []PatchOption) *PatchOptions { + for _, opt := range opts { + opt.ApplyToPatch(o) + } + return o +} + +// AsPatchOptions returns these options as a metav1.PatchOptions. +// This may mutate the Raw field. +func (o *PatchOptions) AsPatchOptions() *metav1.PatchOptions { + if o == nil { + return &metav1.PatchOptions{} + } + if o.Raw == nil { + o.Raw = &metav1.PatchOptions{} + } + + o.Raw.DryRun = o.DryRun + o.Raw.Force = o.Force + o.Raw.FieldManager = o.FieldManager + return o.Raw +} + +var _ PatchOption = &PatchOptions{} + +// ApplyToPatch implements PatchOptions. +func (o *PatchOptions) ApplyToPatch(po *PatchOptions) { + if o.DryRun != nil { + po.DryRun = o.DryRun + } + if o.Force != nil { + po.Force = o.Force + } + if o.FieldManager != "" { + po.FieldManager = o.FieldManager + } + if o.Raw != nil { + po.Raw = o.Raw + } +} + +// ForceOwnership indicates that in case of conflicts with server-side apply, +// the client should acquire ownership of the conflicting field. Most +// controllers should use this. +var ForceOwnership = forceOwnership{} + +type forceOwnership struct{} + +func (forceOwnership) ApplyToPatch(opts *PatchOptions) { + definitelyTrue := true + opts.Force = &definitelyTrue +} + +func (forceOwnership) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + definitelyTrue := true + opts.Force = &definitelyTrue +} + +// }}} + +// {{{ DeleteAllOf Options + +// these are all just delete options and list options + +// DeleteAllOfOptions contains options for deletecollection (deleteallof) requests. +// It's just list and delete options smooshed together. +type DeleteAllOfOptions struct { + ListOptions + DeleteOptions +} + +// ApplyOptions applies the given deleteallof options on these options, +// and then returns itself (for convenient chaining). +func (o *DeleteAllOfOptions) ApplyOptions(opts []DeleteAllOfOption) *DeleteAllOfOptions { + for _, opt := range opts { + opt.ApplyToDeleteAllOf(o) + } + return o +} + +var _ DeleteAllOfOption = &DeleteAllOfOptions{} + +// ApplyToDeleteAllOf implements DeleteAllOfOption. +func (o *DeleteAllOfOptions) ApplyToDeleteAllOf(do *DeleteAllOfOptions) { + o.ApplyToList(&do.ListOptions) + o.ApplyToDelete(&do.DeleteOptions) +} + +// }}} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/options_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/options_test.go new file mode 100644 index 00000000000..efba976c4f8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/options_test.go @@ -0,0 +1,294 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + utilpointer "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("ListOptions", func() { + It("Should set LabelSelector", func() { + labelSelector, err := labels.Parse("a=b") + Expect(err).NotTo(HaveOccurred()) + o := &client.ListOptions{LabelSelector: labelSelector} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should set FieldSelector", func() { + o := &client.ListOptions{FieldSelector: fields.Nothing()} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should set Namespace", func() { + o := &client.ListOptions{Namespace: "my-ns"} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should set Raw", func() { + o := &client.ListOptions{Raw: &metav1.ListOptions{FieldSelector: "Hans"}} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should set Limit", func() { + o := &client.ListOptions{Limit: int64(1)} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should set Continue", func() { + o := &client.ListOptions{Continue: "foo"} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) + It("Should not set anything", func() { + o := &client.ListOptions{} + newListOpts := &client.ListOptions{} + o.ApplyToList(newListOpts) + Expect(newListOpts).To(Equal(o)) + }) +}) + +var _ = Describe("GetOptions", func() { + It("Should set Raw", func() { + o := &client.GetOptions{Raw: &metav1.GetOptions{ResourceVersion: "RV0"}} + newGetOpts := &client.GetOptions{} + o.ApplyToGet(newGetOpts) + Expect(newGetOpts).To(Equal(o)) + }) +}) + +var _ = Describe("CreateOptions", func() { + It("Should set DryRun", func() { + o := &client.CreateOptions{DryRun: []string{"Hello", "Theodore"}} + newCreateOpts := &client.CreateOptions{} + o.ApplyToCreate(newCreateOpts) + Expect(newCreateOpts).To(Equal(o)) + }) + It("Should set FieldManager", func() { + o := &client.CreateOptions{FieldManager: "FieldManager"} + newCreateOpts := &client.CreateOptions{} + o.ApplyToCreate(newCreateOpts) + Expect(newCreateOpts).To(Equal(o)) + }) + It("Should set Raw", func() { + o := &client.CreateOptions{Raw: &metav1.CreateOptions{DryRun: []string{"Bye", "Theodore"}}} + newCreateOpts := &client.CreateOptions{} + o.ApplyToCreate(newCreateOpts) + Expect(newCreateOpts).To(Equal(o)) + }) + It("Should not set anything", func() { + o := &client.CreateOptions{} + newCreateOpts := &client.CreateOptions{} + o.ApplyToCreate(newCreateOpts) + Expect(newCreateOpts).To(Equal(o)) + }) +}) + +var _ = Describe("DeleteOptions", func() { + It("Should set GracePeriodSeconds", func() { + o := &client.DeleteOptions{GracePeriodSeconds: utilpointer.Int64(42)} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) + It("Should set Preconditions", func() { + o := &client.DeleteOptions{Preconditions: &metav1.Preconditions{}} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) + It("Should set PropagationPolicy", func() { + policy := metav1.DeletePropagationBackground + o := &client.DeleteOptions{PropagationPolicy: &policy} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) + It("Should set Raw", func() { + o := &client.DeleteOptions{Raw: &metav1.DeleteOptions{}} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) + It("Should set DryRun", func() { + o := &client.DeleteOptions{DryRun: []string{"Hello", "Pippa"}} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) + It("Should not set anything", func() { + o := &client.DeleteOptions{} + newDeleteOpts := &client.DeleteOptions{} + o.ApplyToDelete(newDeleteOpts) + Expect(newDeleteOpts).To(Equal(o)) + }) +}) + +var _ = Describe("UpdateOptions", func() { + It("Should set DryRun", func() { + o := &client.UpdateOptions{DryRun: []string{"Bye", "Pippa"}} + newUpdateOpts := &client.UpdateOptions{} + o.ApplyToUpdate(newUpdateOpts) + Expect(newUpdateOpts).To(Equal(o)) + }) + It("Should set FieldManager", func() { + o := &client.UpdateOptions{FieldManager: "Hello Boris"} + newUpdateOpts := &client.UpdateOptions{} + o.ApplyToUpdate(newUpdateOpts) + Expect(newUpdateOpts).To(Equal(o)) + }) + It("Should set Raw", func() { + o := &client.UpdateOptions{Raw: &metav1.UpdateOptions{}} + newUpdateOpts := &client.UpdateOptions{} + o.ApplyToUpdate(newUpdateOpts) + Expect(newUpdateOpts).To(Equal(o)) + }) + It("Should not set anything", func() { + o := &client.UpdateOptions{} + newUpdateOpts := &client.UpdateOptions{} + o.ApplyToUpdate(newUpdateOpts) + Expect(newUpdateOpts).To(Equal(o)) + }) +}) + +var _ = Describe("PatchOptions", func() { + It("Should set DryRun", func() { + o := &client.PatchOptions{DryRun: []string{"Bye", "Boris"}} + newPatchOpts := &client.PatchOptions{} + o.ApplyToPatch(newPatchOpts) + Expect(newPatchOpts).To(Equal(o)) + }) + It("Should set Force", func() { + o := &client.PatchOptions{Force: utilpointer.Bool(true)} + newPatchOpts := &client.PatchOptions{} + o.ApplyToPatch(newPatchOpts) + Expect(newPatchOpts).To(Equal(o)) + }) + It("Should set FieldManager", func() { + o := &client.PatchOptions{FieldManager: "Hello Julian"} + newPatchOpts := &client.PatchOptions{} + o.ApplyToPatch(newPatchOpts) + Expect(newPatchOpts).To(Equal(o)) + }) + It("Should set Raw", func() { + o := &client.PatchOptions{Raw: &metav1.PatchOptions{}} + newPatchOpts := &client.PatchOptions{} + o.ApplyToPatch(newPatchOpts) + Expect(newPatchOpts).To(Equal(o)) + }) + It("Should not set anything", func() { + o := &client.PatchOptions{} + newPatchOpts := &client.PatchOptions{} + o.ApplyToPatch(newPatchOpts) + Expect(newPatchOpts).To(Equal(o)) + }) +}) + +var _ = Describe("DeleteAllOfOptions", func() { + It("Should set ListOptions", func() { + o := &client.DeleteAllOfOptions{ListOptions: client.ListOptions{Raw: &metav1.ListOptions{}}} + newDeleteAllOfOpts := &client.DeleteAllOfOptions{} + o.ApplyToDeleteAllOf(newDeleteAllOfOpts) + Expect(newDeleteAllOfOpts).To(Equal(o)) + }) + It("Should set DeleleteOptions", func() { + o := &client.DeleteAllOfOptions{DeleteOptions: client.DeleteOptions{GracePeriodSeconds: utilpointer.Int64(44)}} + newDeleteAllOfOpts := &client.DeleteAllOfOptions{} + o.ApplyToDeleteAllOf(newDeleteAllOfOpts) + Expect(newDeleteAllOfOpts).To(Equal(o)) + }) +}) + +var _ = Describe("MatchingLabels", func() { + It("Should produce an invalid selector when given invalid input", func() { + matchingLabels := client.MatchingLabels(map[string]string{"k": "axahm2EJ8Phiephe2eixohbee9eGeiyees1thuozi1xoh0GiuH3diewi8iem7Nui"}) + listOpts := &client.ListOptions{} + matchingLabels.ApplyToList(listOpts) + + r, _ := listOpts.LabelSelector.Requirements() + _, err := labels.NewRequirement(r[0].Key(), r[0].Operator(), r[0].Values().List()) + Expect(err).ToNot(BeNil()) + expectedErrMsg := `values[0][k]: Invalid value: "axahm2EJ8Phiephe2eixohbee9eGeiyees1thuozi1xoh0GiuH3diewi8iem7Nui": must be no more than 63 characters` + Expect(err.Error()).To(Equal(expectedErrMsg)) + }) +}) + +var _ = Describe("FieldOwner", func() { + It("Should apply to PatchOptions", func() { + o := &client.PatchOptions{FieldManager: "bar"} + t := client.FieldOwner("foo") + t.ApplyToPatch(o) + Expect(o.FieldManager).To(Equal("foo")) + }) + It("Should apply to CreateOptions", func() { + o := &client.CreateOptions{FieldManager: "bar"} + t := client.FieldOwner("foo") + t.ApplyToCreate(o) + Expect(o.FieldManager).To(Equal("foo")) + }) + It("Should apply to UpdateOptions", func() { + o := &client.UpdateOptions{FieldManager: "bar"} + t := client.FieldOwner("foo") + t.ApplyToUpdate(o) + Expect(o.FieldManager).To(Equal("foo")) + }) + It("Should apply to SubResourcePatchOptions", func() { + o := &client.SubResourcePatchOptions{PatchOptions: client.PatchOptions{FieldManager: "bar"}} + t := client.FieldOwner("foo") + t.ApplyToSubResourcePatch(o) + Expect(o.FieldManager).To(Equal("foo")) + }) + It("Should apply to SubResourceCreateOptions", func() { + o := &client.SubResourceCreateOptions{CreateOptions: client.CreateOptions{FieldManager: "bar"}} + t := client.FieldOwner("foo") + t.ApplyToSubResourceCreate(o) + Expect(o.FieldManager).To(Equal("foo")) + }) + It("Should apply to SubResourceUpdateOptions", func() { + o := &client.SubResourceUpdateOptions{UpdateOptions: client.UpdateOptions{FieldManager: "bar"}} + t := client.FieldOwner("foo") + t.ApplyToSubResourceUpdate(o) + Expect(o.FieldManager).To(Equal("foo")) + }) +}) + +var _ = Describe("ForceOwnership", func() { + It("Should apply to PatchOptions", func() { + o := &client.PatchOptions{} + t := client.ForceOwnership + t.ApplyToPatch(o) + Expect(*o.Force).To(Equal(true)) + }) + It("Should apply to SubResourcePatchOptions", func() { + o := &client.SubResourcePatchOptions{PatchOptions: client.PatchOptions{}} + t := client.ForceOwnership + t.ApplyToSubResourcePatch(o) + Expect(*o.Force).To(Equal(true)) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch.go new file mode 100644 index 00000000000..11d60838856 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch.go @@ -0,0 +1,213 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "fmt" + + jsonpatch "github.com/evanphx/json-patch/v5" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/json" + "k8s.io/apimachinery/pkg/util/strategicpatch" +) + +var ( + // Apply uses server-side apply to patch the given object. + Apply Patch = applyPatch{} + + // Merge uses the raw object as a merge patch, without modifications. + // Use MergeFrom if you wish to compute a diff instead. + Merge Patch = mergePatch{} +) + +type patch struct { + patchType types.PatchType + data []byte +} + +// Type implements Patch. +func (s *patch) Type() types.PatchType { + return s.patchType +} + +// Data implements Patch. +func (s *patch) Data(obj Object) ([]byte, error) { + return s.data, nil +} + +// RawPatch constructs a new Patch with the given PatchType and data. +func RawPatch(patchType types.PatchType, data []byte) Patch { + return &patch{patchType, data} +} + +// MergeFromWithOptimisticLock can be used if clients want to make sure a patch +// is being applied to the latest resource version of an object. +// +// The behavior is similar to what an Update would do, without the need to send the +// whole object. Usually this method is useful if you might have multiple clients +// acting on the same object and the same API version, but with different versions of the Go structs. +// +// For example, an "older" copy of a Widget that has fields A and B, and a "newer" copy with A, B, and C. +// Sending an update using the older struct definition results in C being dropped, whereas using a patch does not. +type MergeFromWithOptimisticLock struct{} + +// ApplyToMergeFrom applies this configuration to the given patch options. +func (m MergeFromWithOptimisticLock) ApplyToMergeFrom(in *MergeFromOptions) { + in.OptimisticLock = true +} + +// MergeFromOption is some configuration that modifies options for a merge-from patch data. +type MergeFromOption interface { + // ApplyToMergeFrom applies this configuration to the given patch options. + ApplyToMergeFrom(*MergeFromOptions) +} + +// MergeFromOptions contains options to generate a merge-from patch data. +type MergeFromOptions struct { + // OptimisticLock, when true, includes `metadata.resourceVersion` into the final + // patch data. If the `resourceVersion` field doesn't match what's stored, + // the operation results in a conflict and clients will need to try again. + OptimisticLock bool +} + +type mergeFromPatch struct { + patchType types.PatchType + createPatch func(originalJSON, modifiedJSON []byte, dataStruct interface{}) ([]byte, error) + from Object + opts MergeFromOptions +} + +// Type implements Patch. +func (s *mergeFromPatch) Type() types.PatchType { + return s.patchType +} + +// Data implements Patch. +func (s *mergeFromPatch) Data(obj Object) ([]byte, error) { + original := s.from + modified := obj + + if s.opts.OptimisticLock { + version := original.GetResourceVersion() + if len(version) == 0 { + return nil, fmt.Errorf("cannot use OptimisticLock, object %q does not have any resource version we can use", original) + } + + original = original.DeepCopyObject().(Object) + original.SetResourceVersion("") + + modified = modified.DeepCopyObject().(Object) + modified.SetResourceVersion(version) + } + + originalJSON, err := json.Marshal(original) + if err != nil { + return nil, err + } + + modifiedJSON, err := json.Marshal(modified) + if err != nil { + return nil, err + } + + data, err := s.createPatch(originalJSON, modifiedJSON, obj) + if err != nil { + return nil, err + } + + return data, nil +} + +func createMergePatch(originalJSON, modifiedJSON []byte, _ interface{}) ([]byte, error) { + return jsonpatch.CreateMergePatch(originalJSON, modifiedJSON) +} + +func createStrategicMergePatch(originalJSON, modifiedJSON []byte, dataStruct interface{}) ([]byte, error) { + return strategicpatch.CreateTwoWayMergePatch(originalJSON, modifiedJSON, dataStruct) +} + +// MergeFrom creates a Patch that patches using the merge-patch strategy with the given object as base. +// The difference between MergeFrom and StrategicMergeFrom lays in the handling of modified list fields. +// When using MergeFrom, existing lists will be completely replaced by new lists. +// When using StrategicMergeFrom, the list field's `patchStrategy` is respected if specified in the API type, +// e.g. the existing list is not replaced completely but rather merged with the new one using the list's `patchMergeKey`. +// See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ for more details on +// the difference between merge-patch and strategic-merge-patch. +func MergeFrom(obj Object) Patch { + return &mergeFromPatch{patchType: types.MergePatchType, createPatch: createMergePatch, from: obj} +} + +// MergeFromWithOptions creates a Patch that patches using the merge-patch strategy with the given object as base. +// See MergeFrom for more details. +func MergeFromWithOptions(obj Object, opts ...MergeFromOption) Patch { + options := &MergeFromOptions{} + for _, opt := range opts { + opt.ApplyToMergeFrom(options) + } + return &mergeFromPatch{patchType: types.MergePatchType, createPatch: createMergePatch, from: obj, opts: *options} +} + +// StrategicMergeFrom creates a Patch that patches using the strategic-merge-patch strategy with the given object as base. +// The difference between MergeFrom and StrategicMergeFrom lays in the handling of modified list fields. +// When using MergeFrom, existing lists will be completely replaced by new lists. +// When using StrategicMergeFrom, the list field's `patchStrategy` is respected if specified in the API type, +// e.g. the existing list is not replaced completely but rather merged with the new one using the list's `patchMergeKey`. +// See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ for more details on +// the difference between merge-patch and strategic-merge-patch. +// Please note, that CRDs don't support strategic-merge-patch, see +// https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#advanced-features-and-flexibility +func StrategicMergeFrom(obj Object, opts ...MergeFromOption) Patch { + options := &MergeFromOptions{} + for _, opt := range opts { + opt.ApplyToMergeFrom(options) + } + return &mergeFromPatch{patchType: types.StrategicMergePatchType, createPatch: createStrategicMergePatch, from: obj, opts: *options} +} + +// mergePatch uses a raw merge strategy to patch the object. +type mergePatch struct{} + +// Type implements Patch. +func (p mergePatch) Type() types.PatchType { + return types.MergePatchType +} + +// Data implements Patch. +func (p mergePatch) Data(obj Object) ([]byte, error) { + // NB(directxman12): we might technically want to be using an actual encoder + // here (in case some more performant encoder is introduced) but this is + // correct and sufficient for our uses (it's what the JSON serializer in + // client-go does, more-or-less). + return json.Marshal(obj) +} + +// applyPatch uses server-side apply to patch the object. +type applyPatch struct{} + +// Type implements Patch. +func (p applyPatch) Type() types.PatchType { + return types.ApplyPatchType +} + +// Data implements Patch. +func (p applyPatch) Data(obj Object) ([]byte, error) { + // NB(directxman12): we might technically want to be using an actual encoder + // here (in case some more performant encoder is introduced) but this is + // correct and sufficient for our uses (it's what the JSON serializer in + // client-go does, more-or-less). + return json.Marshal(obj) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch_test.go new file mode 100644 index 00000000000..2910ef56bf2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/patch_test.go @@ -0,0 +1,95 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "testing" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" +) + +func BenchmarkMergeFrom(b *testing.B) { + cm1 := &corev1.ConfigMap{} + cm1.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("ConfigMap")) + cm1.ResourceVersion = "anything" + + cm2 := cm1.DeepCopy() + cm2.Data = map[string]string{"key": "value"} + + sts1 := &appsv1.StatefulSet{} + sts1.SetGroupVersionKind(appsv1.SchemeGroupVersion.WithKind("StatefulSet")) + sts1.ResourceVersion = "somesuch" + + sts2 := sts1.DeepCopy() + sts2.Spec.Template.Spec.Containers = []corev1.Container{{ + Resources: corev1.ResourceRequirements{ + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceCPU: resource.MustParse("1m"), + corev1.ResourceMemory: resource.MustParse("1M"), + }, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{}, + }, + }, + Lifecycle: &corev1.Lifecycle{ + PreStop: &corev1.LifecycleHandler{ + HTTPGet: &corev1.HTTPGetAction{}, + }, + }, + SecurityContext: &corev1.SecurityContext{}, + }} + + b.Run("NoOptions", func(b *testing.B) { + cmPatch := MergeFrom(cm1) + if _, err := cmPatch.Data(cm2); err != nil { + b.Fatalf("expected no error, got %v", err) + } + + stsPatch := MergeFrom(sts1) + if _, err := stsPatch.Data(sts2); err != nil { + b.Fatalf("expected no error, got %v", err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = cmPatch.Data(cm2) + _, _ = stsPatch.Data(sts2) + } + }) + + b.Run("WithOptimisticLock", func(b *testing.B) { + cmPatch := MergeFromWithOptions(cm1, MergeFromWithOptimisticLock{}) + if _, err := cmPatch.Data(cm2); err != nil { + b.Fatalf("expected no error, got %v", err) + } + + stsPatch := MergeFromWithOptions(sts1, MergeFromWithOptimisticLock{}) + if _, err := stsPatch.Data(sts2); err != nil { + b.Fatalf("expected no error, got %v", err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = cmPatch.Data(cm2) + _, _ = stsPatch.Data(sts2) + } + }) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/testdata/examplecrd.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/client/testdata/examplecrd.yaml new file mode 100644 index 00000000000..5409ee97898 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/testdata/examplecrd.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: chaospods.chaosapps.metamagical.io +spec: + group: chaosapps.metamagical.io + names: + kind: ChaosPod + plural: chaospods + scope: Namespaced + versions: + - name: "v1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go new file mode 100644 index 00000000000..92afd9a9c25 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go @@ -0,0 +1,279 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" +) + +var _ Reader = &typedClient{} +var _ Writer = &typedClient{} + +type typedClient struct { + resources *clientRestResources + paramCodec runtime.ParameterCodec +} + +// Create implements client.Client. +func (c *typedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + createOpts := &CreateOptions{} + createOpts.ApplyOptions(opts) + + return o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Body(obj). + VersionedParams(createOpts.AsCreateOptions(), c.paramCodec). + Do(ctx). + Into(obj) +} + +// Update implements client.Client. +func (c *typedClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + updateOpts := &UpdateOptions{} + updateOpts.ApplyOptions(opts) + + return o.Put(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + Body(obj). + VersionedParams(updateOpts.AsUpdateOptions(), c.paramCodec). + Do(ctx). + Into(obj) +} + +// Delete implements client.Client. +func (c *typedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + deleteOpts := DeleteOptions{} + deleteOpts.ApplyOptions(opts) + + return o.Delete(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + Body(deleteOpts.AsDeleteOptions()). + Do(ctx). + Error() +} + +// DeleteAllOf implements client.Client. +func (c *typedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + deleteAllOfOpts := DeleteAllOfOptions{} + deleteAllOfOpts.ApplyOptions(opts) + + return o.Delete(). + NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.isNamespaced()). + Resource(o.resource()). + VersionedParams(deleteAllOfOpts.AsListOptions(), c.paramCodec). + Body(deleteAllOfOpts.AsDeleteOptions()). + Do(ctx). + Error() +} + +// Patch implements client.Client. +func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + data, err := patch.Data(obj) + if err != nil { + return err + } + + patchOpts := &PatchOptions{} + patchOpts.ApplyOptions(opts) + + return o.Patch(patch.Type()). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec). + Body(data). + Do(ctx). + Into(obj) +} + +// Get implements client.Client. +func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + r, err := c.resources.getResource(obj) + if err != nil { + return err + } + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) + return r.Get(). + NamespaceIfScoped(key.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(getOpts.AsGetOptions(), c.paramCodec). + Name(key.Name).Do(ctx).Into(obj) +} + +// List implements client.Client. +func (c *typedClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + r, err := c.resources.getResource(obj) + if err != nil { + return err + } + + listOpts := ListOptions{} + listOpts.ApplyOptions(opts) + + return r.Get(). + NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(listOpts.AsListOptions(), c.paramCodec). + Do(ctx). + Into(obj) +} + +func (c *typedClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + getOpts := &SubResourceGetOptions{} + getOpts.ApplyOptions(opts) + + return o.Get(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + VersionedParams(getOpts.AsGetOptions(), c.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (c *typedClient) CreateSubResource(ctx context.Context, obj Object, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + createOpts := &SubResourceCreateOptions{} + createOpts.ApplyOptions(opts) + + return o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(subResourceObj). + VersionedParams(createOpts.AsCreateOptions(), c.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +// UpdateSubResource used by SubResourceWriter to write status. +func (c *typedClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + // TODO(droot): examine the returned error and check if it error needs to be + // wrapped to improve the UX ? + // It will be nice to receive an error saying the object doesn't implement + // status subresource and check CRD definition + updateOpts := &SubResourceUpdateOptions{} + updateOpts.ApplyOptions(opts) + + body := obj + if updateOpts.SubResourceBody != nil { + body = updateOpts.SubResourceBody + } + if body.GetName() == "" { + body.SetName(obj.GetName()) + } + if body.GetNamespace() == "" { + body.SetNamespace(obj.GetNamespace()) + } + + return o.Put(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(body). + VersionedParams(updateOpts.AsUpdateOptions(), c.paramCodec). + Do(ctx). + Into(body) +} + +// PatchSubResource used by SubResourceWriter to write subresource. +func (c *typedClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) + if err != nil { + return err + } + + return o.Patch(patch.Type()). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(data). + VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec). + Do(ctx). + Into(body) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go new file mode 100644 index 00000000000..b8d4146c9f3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go @@ -0,0 +1,361 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" +) + +var _ Reader = &unstructuredClient{} +var _ Writer = &unstructuredClient{} + +type unstructuredClient struct { + resources *clientRestResources + paramCodec runtime.ParameterCodec +} + +// Create implements client.Client. +func (uc *unstructuredClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { + u, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + gvk := u.GetObjectKind().GroupVersionKind() + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + createOpts := &CreateOptions{} + createOpts.ApplyOptions(opts) + + result := o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Body(obj). + VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec). + Do(ctx). + Into(obj) + + u.GetObjectKind().SetGroupVersionKind(gvk) + return result +} + +// Update implements client.Client. +func (uc *unstructuredClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { + u, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + gvk := u.GetObjectKind().GroupVersionKind() + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + updateOpts := UpdateOptions{} + updateOpts.ApplyOptions(opts) + + result := o.Put(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + Body(obj). + VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec). + Do(ctx). + Into(obj) + + u.GetObjectKind().SetGroupVersionKind(gvk) + return result +} + +// Delete implements client.Client. +func (uc *unstructuredClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + deleteOpts := DeleteOptions{} + deleteOpts.ApplyOptions(opts) + + return o.Delete(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + Body(deleteOpts.AsDeleteOptions()). + Do(ctx). + Error() +} + +// DeleteAllOf implements client.Client. +func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + deleteAllOfOpts := DeleteAllOfOptions{} + deleteAllOfOpts.ApplyOptions(opts) + + return o.Delete(). + NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.isNamespaced()). + Resource(o.resource()). + VersionedParams(deleteAllOfOpts.AsListOptions(), uc.paramCodec). + Body(deleteAllOfOpts.AsDeleteOptions()). + Do(ctx). + Error() +} + +// Patch implements client.Client. +func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + data, err := patch.Data(obj) + if err != nil { + return err + } + + patchOpts := &PatchOptions{} + patchOpts.ApplyOptions(opts) + + return o.Patch(patch.Type()). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec). + Body(data). + Do(ctx). + Into(obj) +} + +// Get implements client.Client. +func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + u, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + gvk := u.GetObjectKind().GroupVersionKind() + + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) + + r, err := uc.resources.getResource(obj) + if err != nil { + return err + } + + result := r.Get(). + NamespaceIfScoped(key.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(getOpts.AsGetOptions(), uc.paramCodec). + Name(key.Name). + Do(ctx). + Into(obj) + + u.GetObjectKind().SetGroupVersionKind(gvk) + + return result +} + +// List implements client.Client. +func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + u, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + gvk := u.GetObjectKind().GroupVersionKind() + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + r, err := uc.resources.getResource(obj) + if err != nil { + return err + } + + listOpts := ListOptions{} + listOpts.ApplyOptions(opts) + + return r.Get(). + NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(listOpts.AsListOptions(), uc.paramCodec). + Do(ctx). + Into(obj) +} + +func (uc *unstructuredClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", subResource) + } + + if _, ok := subResourceObj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + getOpts := &SubResourceGetOptions{} + getOpts.ApplyOptions(opts) + + return o.Get(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + VersionedParams(getOpts.AsGetOptions(), uc.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (uc *unstructuredClient) CreateSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", subResourceObj) + } + + if _, ok := subResourceObj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + createOpts := &SubResourceCreateOptions{} + createOpts.ApplyOptions(opts) + + return o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(subResourceObj). + VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (uc *unstructuredClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + updateOpts := SubResourceUpdateOptions{} + updateOpts.ApplyOptions(opts) + + body := obj + if updateOpts.SubResourceBody != nil { + body = updateOpts.SubResourceBody + } + if body.GetName() == "" { + body.SetName(obj.GetName()) + } + if body.GetNamespace() == "" { + body.SetNamespace(obj.GetNamespace()) + } + + return o.Put(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(body). + VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec). + Do(ctx). + Into(body) +} + +func (uc *unstructuredClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { + u, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + gvk := u.GetObjectKind().GroupVersionKind() + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) + if err != nil { + return err + } + + result := o.Patch(patch.Type()). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(data). + VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec). + Do(ctx). + Into(body) + + u.GetObjectKind().SetGroupVersionKind(gvk) + return result +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch.go new file mode 100644 index 00000000000..181b22a6732 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch.go @@ -0,0 +1,106 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +// NewWithWatch returns a new WithWatch. +func NewWithWatch(config *rest.Config, options Options) (WithWatch, error) { + client, err := newClient(config, options) + if err != nil { + return nil, err + } + return &watchingClient{client: client}, nil +} + +type watchingClient struct { + *client +} + +func (w *watchingClient) Watch(ctx context.Context, list ObjectList, opts ...ListOption) (watch.Interface, error) { + switch l := list.(type) { + case runtime.Unstructured: + return w.unstructuredWatch(ctx, l, opts...) + case *metav1.PartialObjectMetadataList: + return w.metadataWatch(ctx, l, opts...) + default: + return w.typedWatch(ctx, l, opts...) + } +} + +func (w *watchingClient) listOpts(opts ...ListOption) ListOptions { + listOpts := ListOptions{} + listOpts.ApplyOptions(opts) + if listOpts.Raw == nil { + listOpts.Raw = &metav1.ListOptions{} + } + listOpts.Raw.Watch = true + + return listOpts +} + +func (w *watchingClient) metadataWatch(ctx context.Context, obj *metav1.PartialObjectMetadataList, opts ...ListOption) (watch.Interface, error) { + gvk := obj.GroupVersionKind() + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + listOpts := w.listOpts(opts...) + + resInt, err := w.client.metadataClient.getResourceInterface(gvk, listOpts.Namespace) + if err != nil { + return nil, err + } + + return resInt.Watch(ctx, *listOpts.AsListOptions()) +} + +func (w *watchingClient) unstructuredWatch(ctx context.Context, obj runtime.Unstructured, opts ...ListOption) (watch.Interface, error) { + r, err := w.client.unstructuredClient.resources.getResource(obj) + if err != nil { + return nil, err + } + + listOpts := w.listOpts(opts...) + + return r.Get(). + NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(listOpts.AsListOptions(), w.client.unstructuredClient.paramCodec). + Watch(ctx) +} + +func (w *watchingClient) typedWatch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error) { + r, err := w.client.typedClient.resources.getResource(obj) + if err != nil { + return nil, err + } + + listOpts := w.listOpts(opts...) + + return r.Get(). + NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(listOpts.AsListOptions(), w.client.typedClient.paramCodec). + Watch(ctx) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch_test.go new file mode 100644 index 00000000000..26d90f65501 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/client/watch_test.go @@ -0,0 +1,133 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client_test + +import ( + "context" + "fmt" + "sync/atomic" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("ClientWithWatch", func() { + var dep *appsv1.Deployment + var count uint64 = 0 + var replicaCount int32 = 2 + var ns = "kube-public" + ctx := context.TODO() + + BeforeEach(func() { + atomic.AddUint64(&count, 1) + dep = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("watch-deployment-name-%v", count), Namespace: ns, Labels: map[string]string{"app": fmt.Sprintf("bar-%v", count)}}, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicaCount, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}}, + }, + }, + } + + var err error + dep, err = clientset.AppsV1().Deployments(ns).Create(ctx, dep, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + deleteDeployment(ctx, dep, ns) + }) + + Describe("NewWithWatch", func() { + It("should return a new Client", func() { + cl, err := client.NewWithWatch(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + }) + + watchSuite := func(through client.ObjectList, expectedType client.Object, checkGvk bool) { + cl, err := client.NewWithWatch(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cl).NotTo(BeNil()) + + watchInterface, err := cl.Watch(ctx, through, &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("metadata.name", dep.Name), + Namespace: dep.Namespace, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(watchInterface).NotTo(BeNil()) + + defer watchInterface.Stop() + + event, ok := <-watchInterface.ResultChan() + Expect(ok).To(BeTrue()) + Expect(event.Type).To(BeIdenticalTo(watch.Added)) + Expect(event.Object).To(BeAssignableToTypeOf(expectedType)) + + // The metadata client doesn't set GVK so we just use the + // name and UID as a proxy to confirm that we got the right + // object. + metaObject, ok := event.Object.(metav1.Object) + Expect(ok).To(BeTrue()) + Expect(metaObject.GetName()).To(Equal(dep.Name)) + Expect(metaObject.GetUID()).To(Equal(dep.UID)) + + if checkGvk { + runtimeObject := event.Object + gvk := runtimeObject.GetObjectKind().GroupVersionKind() + Expect(gvk).To(Equal(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + })) + } + } + + It("should receive a create event when watching the typed object", func() { + watchSuite(&appsv1.DeploymentList{}, &appsv1.Deployment{}, false) + }) + + It("should receive a create event when watching the unstructured object", func() { + u := &unstructured.UnstructuredList{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "apps", + Kind: "Deployment", + Version: "v1", + }) + watchSuite(u, &unstructured.Unstructured{}, true) + }) + + It("should receive a create event when watching the metadata object", func() { + m := &metav1.PartialObjectMetadataList{TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: "apps/v1"}} + watchSuite(m, &metav1.PartialObjectMetadata{}, false) + }) + }) + +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go new file mode 100644 index 00000000000..7d00c3c4b0e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go @@ -0,0 +1,343 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "context" + "errors" + "net/http" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +// Cluster provides various methods to interact with a cluster. +type Cluster interface { + // GetHTTPClient returns an HTTP client that can be used to talk to the apiserver + GetHTTPClient() *http.Client + + // GetConfig returns an initialized Config + GetConfig() *rest.Config + + // GetCache returns a cache.Cache + GetCache() cache.Cache + + // GetScheme returns an initialized Scheme + GetScheme() *runtime.Scheme + + // GetClient returns a client configured with the Config. This client may + // not be a fully "direct" client -- it may read from a cache, for + // instance. See Options.NewClient for more information on how the default + // implementation works. + GetClient() client.Client + + // GetFieldIndexer returns a client.FieldIndexer configured with the client + GetFieldIndexer() client.FieldIndexer + + // GetEventRecorderFor returns a new EventRecorder for the provided name + GetEventRecorderFor(name string) record.EventRecorder + + // GetRESTMapper returns a RESTMapper + GetRESTMapper() meta.RESTMapper + + // GetAPIReader returns a reader that will be configured to use the API server. + // This should be used sparingly and only when the client does not fit your + // use case. + GetAPIReader() client.Reader + + // Start starts the cluster + Start(ctx context.Context) error +} + +// Options are the possible options that can be configured for a Cluster. +type Options struct { + // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources + // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better + // idea to pass your own scheme in. See the documentation in pkg/scheme for more information. + Scheme *runtime.Scheme + + // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) + + // Logger is the logger that should be used by this Cluster. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + SyncPeriod *time.Duration + + // Namespace if specified restricts the manager's cache to watch objects in + // the desired namespace Defaults to all namespaces + // + // Note: If a namespace is specified, controllers can still Watch for a + // cluster-scoped resource (e.g Node). For namespaced resources the cache + // will only hold objects from the desired namespace. + // + // Deprecated: Use Cache.Namespaces instead. + Namespace string + + // HTTPClient is the http client that will be used to create the default + // Cache and Client. If not set the rest.HTTPClientFor function will be used + // to create the http client. + HTTPClient *http.Client + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + + // NewCache is the function that will create the cache to be used + // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. + NewCache cache.NewCacheFunc + + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + + // NewClient is the func that creates the client to be used by the manager. + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc + + // ClientDisableCacheFor tells the client that, if any cache is used, to bypass it + // for the given objects. + // + // Deprecated: Use Client.Cache.DisableFor instead. + ClientDisableCacheFor []client.Object + + // DryRunClient specifies whether the client should be configured to enforce + // dryRun mode. + // + // Deprecated: Use Client.DryRun instead. + DryRunClient bool + + // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API + // Use this to customize the event correlator and spam filter + // + // Deprecated: using this may cause goroutine leaks if the lifetime of your manager or controllers + // is shorter than the lifetime of your process. + EventBroadcaster record.EventBroadcaster + + // makeBroadcaster allows deferring the creation of the broadcaster to + // avoid leaking goroutines if we never call Start on this manager. It also + // returns whether or not this is a "owned" broadcaster, and as such should be + // stopped with the manager. + makeBroadcaster intrec.EventBroadcasterProducer + + // Dependency injection for testing + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) +} + +// Option can be used to manipulate Options. +type Option func(*Options) + +// New constructs a brand new cluster. +func New(config *rest.Config, opts ...Option) (Cluster, error) { + if config == nil { + return nil, errors.New("must specify Config") + } + + options := Options{} + for _, opt := range opts { + opt(&options) + } + options, err := setOptionsDefaults(options, config) + if err != nil { + options.Logger.Error(err, "Failed to set defaults") + return nil, err + } + + // Create the mapper provider + mapper, err := options.MapperProvider(config, options.HTTPClient) + if err != nil { + options.Logger.Error(err, "Failed to get API Group-Resources") + return nil, err + } + + // Create the cache for the cached read client and registering informers + cacheOpts := options.Cache + { + if cacheOpts.Scheme == nil { + cacheOpts.Scheme = options.Scheme + } + if cacheOpts.Mapper == nil { + cacheOpts.Mapper = mapper + } + if cacheOpts.HTTPClient == nil { + cacheOpts.HTTPClient = options.HTTPClient + } + if cacheOpts.SyncPeriod == nil { + cacheOpts.SyncPeriod = options.SyncPeriod + } + if len(cacheOpts.Namespaces) == 0 && options.Namespace != "" { + cacheOpts.Namespaces = []string{options.Namespace} + } + } + cache, err := options.NewCache(config, cacheOpts) + if err != nil { + return nil, err + } + + // Create the client, and default its options. + clientOpts := options.Client + { + if clientOpts.Scheme == nil { + clientOpts.Scheme = options.Scheme + } + if clientOpts.Mapper == nil { + clientOpts.Mapper = mapper + } + if clientOpts.HTTPClient == nil { + clientOpts.HTTPClient = options.HTTPClient + } + if clientOpts.Cache == nil { + clientOpts.Cache = &client.CacheOptions{ + Unstructured: false, + } + } + if clientOpts.Cache.Reader == nil { + clientOpts.Cache.Reader = cache + } + + // For backward compatibility, the ClientDisableCacheFor option should + // be appended to the DisableFor option in the client. + clientOpts.Cache.DisableFor = append(clientOpts.Cache.DisableFor, options.ClientDisableCacheFor...) + + if clientOpts.DryRun == nil && options.DryRunClient { + // For backward compatibility, the DryRunClient (if set) option should override + // the DryRun option in the client (if unset). + clientOpts.DryRun = pointer.Bool(true) + } + } + clientWriter, err := options.NewClient(config, clientOpts) + if err != nil { + return nil, err + } + + // Create the API Reader, a client with no cache. + clientReader, err := client.New(config, client.Options{ + HTTPClient: options.HTTPClient, + Scheme: options.Scheme, + Mapper: mapper, + }) + if err != nil { + return nil, err + } + + // Create the recorder provider to inject event recorders for the components. + // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific + // to the particular controller that it's being injected into, rather than a generic one like is here. + recorderProvider, err := options.newRecorderProvider(config, options.HTTPClient, options.Scheme, options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + + return &cluster{ + config: config, + httpClient: options.HTTPClient, + scheme: options.Scheme, + cache: cache, + fieldIndexes: cache, + client: clientWriter, + apiReader: clientReader, + recorderProvider: recorderProvider, + mapper: mapper, + logger: options.Logger, + }, nil +} + +// setOptionsDefaults set default values for Options fields. +func setOptionsDefaults(options Options, config *rest.Config) (Options, error) { + if options.HTTPClient == nil { + var err error + options.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return options, err + } + } + + // Use the Kubernetes client-go scheme if none is specified + if options.Scheme == nil { + options.Scheme = scheme.Scheme + } + + if options.MapperProvider == nil { + options.MapperProvider = apiutil.NewDynamicRESTMapper + } + + // Allow users to define how to create a new client + if options.NewClient == nil { + options.NewClient = client.New + } + + // Allow newCache to be mocked + if options.NewCache == nil { + options.NewCache = cache.New + } + + // Allow newRecorderProvider to be mocked + if options.newRecorderProvider == nil { + options.newRecorderProvider = intrec.NewProvider + } + + // This is duplicated with pkg/manager, we need it here to provide + // the user with an EventBroadcaster and there for the Leader election + if options.EventBroadcaster == nil { + // defer initialization to avoid leaking by default + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return record.NewBroadcaster(), true + } + } else { + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return options.EventBroadcaster, false + } + } + + if options.Logger.GetSink() == nil { + options.Logger = logf.RuntimeLog.WithName("cluster") + } + + return options, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_suite_test.go new file mode 100644 index 00000000000..dc1f9ac7786 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_suite_test.go @@ -0,0 +1,68 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "net/http" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Cluster Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var clientset *kubernetes.Clientset + +// clientTransport is used to force-close keep-alives in tests that check for leaks. +var clientTransport *http.Transport + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + // NB(directxman12): we can't set Transport *and* use TLS options, + // so we grab the transport right after it gets created so that we can + // type-assert on it (hopefully)? + // hopefully this doesn't break 🤞 + clientTransport = rt.(*http.Transport) + return rt + } + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_test.go new file mode 100644 index 00000000000..dc52b2d9b31 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/cluster_test.go @@ -0,0 +1,170 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "context" + "errors" + "fmt" + "net/http" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "go.uber.org/goleak" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +var _ = Describe("cluster.Cluster", func() { + Describe("New", func() { + It("should return an error if there is no Config", func() { + c, err := New(nil) + Expect(c).To(BeNil()) + Expect(err.Error()).To(ContainSubstring("must specify Config")) + + }) + + It("should return an error if it can't create a RestMapper", func() { + expected := fmt.Errorf("expected error: RestMapper") + c, err := New(cfg, func(o *Options) { + o.MapperProvider = func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { return nil, expected } + }) + Expect(c).To(BeNil()) + Expect(err).To(Equal(expected)) + + }) + + It("should return an error it can't create a client.Client", func() { + c, err := New(cfg, func(o *Options) { + o.NewClient = func(config *rest.Config, options client.Options) (client.Client, error) { + return nil, errors.New("expected error") + } + }) + Expect(c).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + It("should return an error it can't create a cache.Cache", func() { + c, err := New(cfg, func(o *Options) { + o.NewCache = func(config *rest.Config, opts cache.Options) (cache.Cache, error) { + return nil, fmt.Errorf("expected error") + } + }) + Expect(c).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + It("should create a client defined in by the new client function", func() { + c, err := New(cfg, func(o *Options) { + o.NewClient = func(config *rest.Config, options client.Options) (client.Client, error) { + return nil, nil + } + }) + Expect(c).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + Expect(c.GetClient()).To(BeNil()) + }) + + It("should return an error it can't create a recorder.Provider", func() { + c, err := New(cfg, func(o *Options) { + o.newRecorderProvider = func(_ *rest.Config, _ *http.Client, _ *runtime.Scheme, _ logr.Logger, _ intrec.EventBroadcasterProducer) (*intrec.Provider, error) { + return nil, fmt.Errorf("expected error") + } + }) + Expect(c).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + }) + + Describe("Start", func() { + It("should stop when context is cancelled", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(c.Start(ctx)).NotTo(HaveOccurred()) + }) + }) + + It("should not leak goroutines when stopped", func() { + currentGRs := goleak.IgnoreCurrent() + + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(c.Start(ctx)).NotTo(HaveOccurred()) + + // force-close keep-alive connections. These'll time anyway (after + // like 30s or so) but force it to speed up the tests. + clientTransport.CloseIdleConnections() + Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) + }) + + It("should provide a function to get the Config", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + cluster, ok := c.(*cluster) + Expect(ok).To(BeTrue()) + Expect(c.GetConfig()).To(Equal(cluster.config)) + }) + + It("should provide a function to get the Client", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + cluster, ok := c.(*cluster) + Expect(ok).To(BeTrue()) + Expect(c.GetClient()).To(Equal(cluster.client)) + }) + + It("should provide a function to get the Scheme", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + cluster, ok := c.(*cluster) + Expect(ok).To(BeTrue()) + Expect(c.GetScheme()).To(Equal(cluster.scheme)) + }) + + It("should provide a function to get the FieldIndexer", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + cluster, ok := c.(*cluster) + Expect(ok).To(BeTrue()) + Expect(c.GetFieldIndexer()).To(Equal(cluster.cache)) + }) + + It("should provide a function to get the EventRecorder", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + Expect(c.GetEventRecorderFor("test")).NotTo(BeNil()) + }) + It("should provide a function to get the APIReader", func() { + c, err := New(cfg) + Expect(err).NotTo(HaveOccurred()) + Expect(c.GetAPIReader()).NotTo(BeNil()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go new file mode 100644 index 00000000000..2742764231b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go @@ -0,0 +1,105 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "context" + "net/http" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +type cluster struct { + // config is the rest.config used to talk to the apiserver. Required. + config *rest.Config + + httpClient *http.Client + scheme *runtime.Scheme + cache cache.Cache + client client.Client + + // apiReader is the reader that will make requests to the api server and not the cache. + apiReader client.Reader + + // fieldIndexes knows how to add field indexes over the Cache used by this controller, + // which can later be consumed via field selectors from the injected client. + fieldIndexes client.FieldIndexer + + // recorderProvider is used to generate event recorders that will be injected into Controllers + // (and EventHandlers, Sources and Predicates). + recorderProvider *intrec.Provider + + // mapper is used to map resources to kind, and map kind and version. + mapper meta.RESTMapper + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + logger logr.Logger +} + +func (c *cluster) GetConfig() *rest.Config { + return c.config +} + +func (c *cluster) GetHTTPClient() *http.Client { + return c.httpClient +} + +func (c *cluster) GetClient() client.Client { + return c.client +} + +func (c *cluster) GetScheme() *runtime.Scheme { + return c.scheme +} + +func (c *cluster) GetFieldIndexer() client.FieldIndexer { + return c.fieldIndexes +} + +func (c *cluster) GetCache() cache.Cache { + return c.cache +} + +func (c *cluster) GetEventRecorderFor(name string) record.EventRecorder { + return c.recorderProvider.GetEventRecorderFor(name) +} + +func (c *cluster) GetRESTMapper() meta.RESTMapper { + return c.mapper +} + +func (c *cluster) GetAPIReader() client.Reader { + return c.apiReader +} + +func (c *cluster) GetLogger() logr.Logger { + return c.logger +} + +func (c *cluster) Start(ctx context.Context) error { + defer c.recorderProvider.Stop(ctx) + return c.cache.Start(ctx) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/config.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config.go new file mode 100644 index 00000000000..9c7b875a860 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config.go @@ -0,0 +1,112 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "fmt" + "os" + "sync" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" +) + +// ControllerManagerConfiguration defines the functions necessary to parse a config file +// and to configure the Options struct for the ctrl.Manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfiguration interface { + runtime.Object + + // Complete returns the versioned configuration + Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) +} + +// DeferredFileLoader is used to configure the decoder for loading controller +// runtime component config types. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type DeferredFileLoader struct { + ControllerManagerConfiguration + path string + scheme *runtime.Scheme + once sync.Once + err error +} + +// File will set up the deferred file loader for the configuration +// this will also configure the defaults for the loader if nothing is +// +// Defaults: +// * Path: "./config.yaml" +// * Kind: GenericControllerManagerConfiguration +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +func File() *DeferredFileLoader { + scheme := runtime.NewScheme() + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + return &DeferredFileLoader{ + path: "./config.yaml", + ControllerManagerConfiguration: &v1alpha1.ControllerManagerConfiguration{}, + scheme: scheme, + } +} + +// Complete will use sync.Once to set the scheme. +func (d *DeferredFileLoader) Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) { + d.once.Do(d.loadFile) + if d.err != nil { + return v1alpha1.ControllerManagerConfigurationSpec{}, d.err + } + return d.ControllerManagerConfiguration.Complete() +} + +// AtPath will set the path to load the file for the decoder. +func (d *DeferredFileLoader) AtPath(path string) *DeferredFileLoader { + d.path = path + return d +} + +// OfKind will set the type to be used for decoding the file into. +func (d *DeferredFileLoader) OfKind(obj ControllerManagerConfiguration) *DeferredFileLoader { + d.ControllerManagerConfiguration = obj + return d +} + +// loadFile is used from the mutex.Once to load the file. +func (d *DeferredFileLoader) loadFile() { + if d.scheme == nil { + d.err = fmt.Errorf("scheme not supplied to controller configuration loader") + return + } + + content, err := os.ReadFile(d.path) + if err != nil { + d.err = fmt.Errorf("could not read file at %s", d.path) + return + } + + codecs := serializer.NewCodecFactory(d.scheme) + + // Regardless of if the bytes are of any external version, + // it will be read successfully and converted into the internal version + if err = runtime.DecodeInto(codecs.UniversalDecoder(), content, d.ControllerManagerConfiguration); err != nil { + d.err = fmt.Errorf("could not decode file into runtime.Object") + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_suite_test.go new file mode 100644 index 00000000000..8df933ba9db --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_suite_test.go @@ -0,0 +1,26 @@ +/* +Copyright 2018 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestScheme(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Config Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_test.go new file mode 100644 index 00000000000..329c0296c5a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/config_test.go @@ -0,0 +1,45 @@ +/* +Copyright 2020 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" +) + +var _ = Describe("config", func() { + Describe("File", func() { + + It("should error loading from non existent file", func() { + loader := config.File() + _, err := loader.Complete() + Expect(err).ToNot(BeNil()) + }) + + It("should load a config from file", func() { + conf := v1alpha1.ControllerManagerConfiguration{} + loader := config.File().AtPath("./testdata/config.yaml").OfKind(&conf) + Expect(conf.CacheNamespace).To(Equal("")) + + _, err := loader.Complete() + Expect(err).To(BeNil()) + + Expect(*conf.LeaderElection.LeaderElect).To(Equal(true)) + Expect(conf.CacheNamespace).To(Equal("default")) + Expect(conf.Metrics.BindAddress).To(Equal(":8081")) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/controller.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/controller.go new file mode 100644 index 00000000000..b37dffaeea4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/controller.go @@ -0,0 +1,49 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import "time" + +// Controller contains configuration options for a controller. +type Controller struct { + // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation + // allowed for that controller. + // + // When a controller is registered within this manager using the builder utilities, + // users have to specify the type the controller reconciles in the For(...) call. + // If the object's kind passed matches one of the keys in this map, the concurrency + // for that controller is set to the number specified. + // + // The key is expected to be consistent in form with GroupKind.String(), + // e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`. + GroupKindConcurrency map[string]int + + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/doc.go new file mode 100644 index 00000000000..47a5a2f1d73 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package config contains functionality for interacting with +// configuration for controller-runtime components. +package config diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/example_test.go new file mode 100644 index 00000000000..3d80d68effb --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/example_test.go @@ -0,0 +1,50 @@ +/* +Copyright 2020 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config_test + +import ( + "fmt" + "os" + + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/config" + + "sigs.k8s.io/controller-runtime/examples/configfile/custom/v1alpha1" +) + +var scheme = runtime.NewScheme() + +func init() { + _ = v1alpha1.AddToScheme(scheme) +} + +// This example will load a file using Complete with only +// defaults set. +func ExampleFile() { + // This will load a config file from ./config.yaml + loader := config.File() + if _, err := loader.Complete(); err != nil { + fmt.Println("failed to load config") + os.Exit(1) + } +} + +// This example will load the file from a custom path. +func ExampleFile_atPath() { + loader := config.File().AtPath("/var/run/controller-runtime/config.yaml") + if _, err := loader.Complete(); err != nil { + fmt.Println("failed to load config") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/testdata/config.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/config/testdata/config.yaml new file mode 100644 index 00000000000..d88da3a65b4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/testdata/config.yaml @@ -0,0 +1,7 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfiguration +cacheNamespace: default +metrics: + bindAddress: :8081 +leaderElection: + leaderElect: true diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go new file mode 100644 index 00000000000..8fdf14d39ad --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 provides the ControllerManagerConfiguration used for +// configuring ctrl.Manager +// +kubebuilder:object:generate=true +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +package v1alpha1 diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go new file mode 100644 index 00000000000..ca854bcf300 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go @@ -0,0 +1,43 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + GroupVersion = schema.GroupVersion{Group: "controller-runtime.sigs.k8s.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + AddToScheme = SchemeBuilder.AddToScheme +) + +func init() { + SchemeBuilder.Register(&ControllerManagerConfiguration{}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go new file mode 100644 index 00000000000..52c8ab300f2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go @@ -0,0 +1,179 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + configv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// ControllerManagerConfigurationSpec defines the desired state of GenericControllerManagerConfiguration. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfigurationSpec struct { + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // +optional + SyncPeriod *metav1.Duration `json:"syncPeriod,omitempty"` + + // LeaderElection is the LeaderElection config to be used when configuring + // the manager.Manager leader election + // +optional + LeaderElection *configv1alpha1.LeaderElectionConfiguration `json:"leaderElection,omitempty"` + + // CacheNamespace if specified restricts the manager's cache to watch objects in + // the desired namespace Defaults to all namespaces + // + // Note: If a namespace is specified, controllers can still Watch for a + // cluster-scoped resource (e.g Node). For namespaced resources the cache + // will only hold objects from the desired namespace. + // +optional + CacheNamespace string `json:"cacheNamespace,omitempty"` + + // GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop. + // To disable graceful shutdown, set to time.Duration(0) + // To use graceful shutdown without timeout, set to a negative duration, e.G. time.Duration(-1) + // The graceful shutdown is skipped for safety reasons in case the leader election lease is lost. + GracefulShutdownTimeout *metav1.Duration `json:"gracefulShutDown,omitempty"` + + // Controller contains global configuration options for controllers + // registered within this manager. + // +optional + Controller *ControllerConfigurationSpec `json:"controller,omitempty"` + + // Metrics contains the controller metrics configuration + // +optional + Metrics ControllerMetrics `json:"metrics,omitempty"` + + // Health contains the controller health configuration + // +optional + Health ControllerHealth `json:"health,omitempty"` + + // Webhook contains the controllers webhook configuration + // +optional + Webhook ControllerWebhook `json:"webhook,omitempty"` +} + +// ControllerConfigurationSpec defines the global configuration for +// controllers registered with the manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +// +// Deprecated: Controller global configuration can now be set at the manager level, +// using the manager.Options.Controller field. +type ControllerConfigurationSpec struct { + // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation + // allowed for that controller. + // + // When a controller is registered within this manager using the builder utilities, + // users have to specify the type the controller reconciles in the For(...) call. + // If the object's kind passed matches one of the keys in this map, the concurrency + // for that controller is set to the number specified. + // + // The key is expected to be consistent in form with GroupKind.String(), + // e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`. + // + // +optional + GroupKindConcurrency map[string]int `json:"groupKindConcurrency,omitempty"` + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + // +optional + CacheSyncTimeout *time.Duration `json:"cacheSyncTimeout,omitempty"` + + // RecoverPanic indicates if panics should be recovered. + // +optional + RecoverPanic *bool `json:"recoverPanic,omitempty"` +} + +// ControllerMetrics defines the metrics configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerMetrics struct { + // BindAddress is the TCP address that the controller should bind to + // for serving prometheus metrics. + // It can be set to "0" to disable the metrics serving. + // +optional + BindAddress string `json:"bindAddress,omitempty"` +} + +// ControllerHealth defines the health configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerHealth struct { + // HealthProbeBindAddress is the TCP address that the controller should bind to + // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. + // +optional + HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` + + // ReadinessEndpointName, defaults to "readyz" + // +optional + ReadinessEndpointName string `json:"readinessEndpointName,omitempty"` + + // LivenessEndpointName, defaults to "healthz" + // +optional + LivenessEndpointName string `json:"livenessEndpointName,omitempty"` +} + +// ControllerWebhook defines the webhook server for the controller. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerWebhook struct { + // Port is the port that the webhook server serves at. + // It is used to set webhook.Server.Port. + // +optional + Port *int `json:"port,omitempty"` + + // Host is the hostname that the webhook server binds to. + // It is used to set webhook.Server.Host. + // +optional + Host string `json:"host,omitempty"` + + // CertDir is the directory that contains the server key and certificate. + // if not set, webhook server would look up the server key and certificate in + // {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate + // must be named tls.key and tls.crt, respectively. + // +optional + CertDir string `json:"certDir,omitempty"` +} + +// +kubebuilder:object:root=true + +// ControllerManagerConfiguration is the Schema for the GenericControllerManagerConfigurations API. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // ControllerManagerConfiguration returns the contfigurations for controllers + ControllerManagerConfigurationSpec `json:",inline"` +} + +// Complete returns the configuration for controller-runtime. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +func (c *ControllerManagerConfigurationSpec) Complete() (ControllerManagerConfigurationSpec, error) { + return *c, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..cdc7c334bef --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,158 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "k8s.io/component-base/config/v1alpha1" + timex "time" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerConfigurationSpec) DeepCopyInto(out *ControllerConfigurationSpec) { + *out = *in + if in.GroupKindConcurrency != nil { + in, out := &in.GroupKindConcurrency, &out.GroupKindConcurrency + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CacheSyncTimeout != nil { + in, out := &in.CacheSyncTimeout, &out.CacheSyncTimeout + *out = new(timex.Duration) + **out = **in + } + if in.RecoverPanic != nil { + in, out := &in.RecoverPanic, &out.RecoverPanic + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerConfigurationSpec. +func (in *ControllerConfigurationSpec) DeepCopy() *ControllerConfigurationSpec { + if in == nil { + return nil + } + out := new(ControllerConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerHealth) DeepCopyInto(out *ControllerHealth) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerHealth. +func (in *ControllerHealth) DeepCopy() *ControllerHealth { + if in == nil { + return nil + } + out := new(ControllerHealth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerManagerConfiguration) DeepCopyInto(out *ControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ControllerManagerConfigurationSpec.DeepCopyInto(&out.ControllerManagerConfigurationSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerManagerConfiguration. +func (in *ControllerManagerConfiguration) DeepCopy() *ControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(ControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ControllerManagerConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerManagerConfigurationSpec) DeepCopyInto(out *ControllerManagerConfigurationSpec) { + *out = *in + if in.SyncPeriod != nil { + in, out := &in.SyncPeriod, &out.SyncPeriod + *out = new(v1.Duration) + **out = **in + } + if in.LeaderElection != nil { + in, out := &in.LeaderElection, &out.LeaderElection + *out = new(configv1alpha1.LeaderElectionConfiguration) + (*in).DeepCopyInto(*out) + } + if in.GracefulShutdownTimeout != nil { + in, out := &in.GracefulShutdownTimeout, &out.GracefulShutdownTimeout + *out = new(v1.Duration) + **out = **in + } + if in.Controller != nil { + in, out := &in.Controller, &out.Controller + *out = new(ControllerConfigurationSpec) + (*in).DeepCopyInto(*out) + } + out.Metrics = in.Metrics + out.Health = in.Health + in.Webhook.DeepCopyInto(&out.Webhook) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerManagerConfigurationSpec. +func (in *ControllerManagerConfigurationSpec) DeepCopy() *ControllerManagerConfigurationSpec { + if in == nil { + return nil + } + out := new(ControllerManagerConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerMetrics) DeepCopyInto(out *ControllerMetrics) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerMetrics. +func (in *ControllerMetrics) DeepCopy() *ControllerMetrics { + if in == nil { + return nil + } + out := new(ControllerMetrics) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerWebhook) DeepCopyInto(out *ControllerWebhook) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerWebhook. +func (in *ControllerWebhook) DeepCopy() *ControllerWebhook { + if in == nil { + return nil + } + out := new(ControllerWebhook) + in.DeepCopyInto(out) + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller.go new file mode 100644 index 00000000000..6732b6f709d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller.go @@ -0,0 +1,174 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "fmt" + "time" + + "github.com/go-logr/logr" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/internal/controller" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/ratelimiter" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Options are the arguments for creating a new Controller. +type Options struct { + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool + + // Reconciler reconciles an object + Reconciler reconcile.Reconciler + + // RateLimiter is used to limit how frequently requests may be queued. + // Defaults to MaxOfRateLimiter which has both overall and per-item rate limiting. + // The overall is a token bucket and the per-item is exponential. + RateLimiter ratelimiter.RateLimiter + + // LogConstructor is used to construct a logger used for this controller and passed + // to each reconciliation via the context field. + LogConstructor func(request *reconcile.Request) logr.Logger +} + +// Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests +// from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item. +// Work typically is reads and writes Kubernetes objects to make the system state match the state specified +// in the object Spec. +type Controller interface { + // Reconciler is called to reconcile an object by Namespace/Name + reconcile.Reconciler + + // Watch takes events provided by a Source and uses the EventHandler to + // enqueue reconcile.Requests in response to the events. + // + // Watch may be provided one or more Predicates to filter events before + // they are given to the EventHandler. Events will be passed to the + // EventHandler if all provided Predicates evaluate to true. + Watch(src source.Source, eventhandler handler.EventHandler, predicates ...predicate.Predicate) error + + // Start starts the controller. Start blocks until the context is closed or a + // controller has an error starting. + Start(ctx context.Context) error + + // GetLogger returns this controller logger prefilled with basic information. + GetLogger() logr.Logger +} + +// New returns a new Controller registered with the Manager. The Manager will ensure that shared Caches have +// been synced before the Controller is Started. +func New(name string, mgr manager.Manager, options Options) (Controller, error) { + c, err := NewUnmanaged(name, mgr, options) + if err != nil { + return nil, err + } + + // Add the controller as a Manager components + return c, mgr.Add(c) +} + +// NewUnmanaged returns a new controller without adding it to the manager. The +// caller is responsible for starting the returned controller. +func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller, error) { + if options.Reconciler == nil { + return nil, fmt.Errorf("must specify Reconciler") + } + + if len(name) == 0 { + return nil, fmt.Errorf("must specify Name for Controller") + } + + if options.LogConstructor == nil { + log := mgr.GetLogger().WithValues( + "controller", name, + ) + options.LogConstructor = func(req *reconcile.Request) logr.Logger { + log := log + if req != nil { + log = log.WithValues( + "object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + ) + } + return log + } + } + + if options.MaxConcurrentReconciles <= 0 { + if mgr.GetControllerOptions().MaxConcurrentReconciles > 0 { + options.MaxConcurrentReconciles = mgr.GetControllerOptions().MaxConcurrentReconciles + } else { + options.MaxConcurrentReconciles = 1 + } + } + + if options.CacheSyncTimeout == 0 { + if mgr.GetControllerOptions().CacheSyncTimeout != 0 { + options.CacheSyncTimeout = mgr.GetControllerOptions().CacheSyncTimeout + } else { + options.CacheSyncTimeout = 2 * time.Minute + } + } + + if options.RateLimiter == nil { + options.RateLimiter = workqueue.DefaultControllerRateLimiter() + } + + if options.RecoverPanic == nil { + options.RecoverPanic = mgr.GetControllerOptions().RecoverPanic + } + + if options.NeedLeaderElection == nil { + options.NeedLeaderElection = mgr.GetControllerOptions().NeedLeaderElection + } + + // Create controller with dependencies set + return &controller.Controller{ + Do: options.Reconciler, + MakeQueue: func() workqueue.RateLimitingInterface { + return workqueue.NewNamedRateLimitingQueue(options.RateLimiter, name) + }, + MaxConcurrentReconciles: options.MaxConcurrentReconciles, + CacheSyncTimeout: options.CacheSyncTimeout, + Name: name, + LogConstructor: options.LogConstructor, + RecoverPanic: options.RecoverPanic, + LeaderElected: options.NeedLeaderElection, + }, nil +} + +// ReconcileIDFromContext gets the reconcileID from the current context. +var ReconcileIDFromContext = controller.ReconcileIDFromContext diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_integration_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_integration_test.go new file mode 100644 index 00000000000..48facf1e947 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_integration_test.go @@ -0,0 +1,180 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller_test + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +var _ = Describe("controller", func() { + var reconciled chan reconcile.Request + ctx := context.Background() + + BeforeEach(func() { + reconciled = make(chan reconcile.Request) + Expect(cfg).NotTo(BeNil()) + }) + + Describe("controller", func() { + // TODO(directxman12): write a whole suite of controller-client interaction tests + + It("should reconcile", func() { + By("Creating the Manager") + cm, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the Controller") + instance, err := controller.New("foo-controller", cm, controller.Options{ + Reconciler: reconcile.Func( + func(_ context.Context, request reconcile.Request) (reconcile.Result, error) { + reconciled <- request + return reconcile.Result{}, nil + }), + }) + Expect(err).NotTo(HaveOccurred()) + + By("Watching Resources") + err = instance.Watch( + source.Kind(cm.GetCache(), &appsv1.ReplicaSet{}), + handler.EnqueueRequestForOwner(cm.GetScheme(), cm.GetRESTMapper(), &appsv1.Deployment{}), + ) + Expect(err).NotTo(HaveOccurred()) + + err = instance.Watch(source.Kind(cm.GetCache(), &appsv1.Deployment{}), &handler.EnqueueRequestForObject{}) + Expect(err).NotTo(HaveOccurred()) + + err = cm.GetClient().Get(ctx, types.NamespacedName{Name: "foo"}, &corev1.Namespace{}) + Expect(err).To(Equal(&cache.ErrCacheNotStarted{})) + err = cm.GetClient().List(ctx, &corev1.NamespaceList{}) + Expect(err).To(Equal(&cache.ErrCacheNotStarted{})) + + By("Starting the Manager") + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(cm.Start(ctx)).NotTo(HaveOccurred()) + }() + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-name"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + SecurityContext: &corev1.SecurityContext{ + Privileged: truePtr(), + }, + }, + }, + }, + }, + }, + } + expectedReconcileRequest := reconcile.Request{NamespacedName: types.NamespacedName{ + Namespace: "default", + Name: "deployment-name", + }} + + By("Invoking Reconciling for Create") + deployment, err = clientset.AppsV1().Deployments("default").Create(ctx, deployment, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Invoking Reconciling for Update") + newDeployment := deployment.DeepCopy() + newDeployment.Labels = map[string]string{"foo": "bar"} + _, err = clientset.AppsV1().Deployments("default").Update(ctx, newDeployment, metav1.UpdateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Invoking Reconciling for an OwnedObject when it is created") + replicaset := &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rs-name", + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(deployment, schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + }), + }, + }, + Spec: appsv1.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: deployment.Spec.Template, + }, + } + replicaset, err = clientset.AppsV1().ReplicaSets("default").Create(ctx, replicaset, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Invoking Reconciling for an OwnedObject when it is updated") + newReplicaset := replicaset.DeepCopy() + newReplicaset.Labels = map[string]string{"foo": "bar"} + _, err = clientset.AppsV1().ReplicaSets("default").Update(ctx, newReplicaset, metav1.UpdateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Invoking Reconciling for an OwnedObject when it is deleted") + err = clientset.AppsV1().ReplicaSets("default").Delete(ctx, replicaset.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Invoking Reconciling for Delete") + err = clientset.AppsV1().Deployments("default"). + Delete(ctx, "deployment-name", metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(<-reconciled).To(Equal(expectedReconcileRequest)) + + By("Listing a type with a slice of pointers as items field") + err = cm.GetClient(). + List(context.Background(), &controllertest.UnconventionalListTypeList{}) + Expect(err).NotTo(HaveOccurred()) + }) + }) +}) + +func truePtr() *bool { + t := true + return &t +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_suite_test.go new file mode 100644 index 00000000000..af818d12cdd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller_test + +import ( + "net/http" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics" + crscheme "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Controller Integration Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var clientset *kubernetes.Clientset + +// clientTransport is used to force-close keep-alives in tests that check for leaks. +var clientTransport *http.Transport + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + err := (&crscheme.Builder{ + GroupVersion: schema.GroupVersion{Group: "chaosapps.metamagical.io", Version: "v1"}, + }). + Register( + &controllertest.UnconventionalListType{}, + &controllertest.UnconventionalListTypeList{}, + ).AddToScheme(scheme.Scheme) + Expect(err).To(BeNil()) + + testenv = &envtest.Environment{ + CRDDirectoryPaths: []string{"testdata/crds"}, + } + + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + // NB(directxman12): we can't set Transport *and* use TLS options, + // so we grab the transport right after it gets created so that we can + // type-assert on it (hopefully)? + // hopefully this doesn't break 🤞 + clientTransport = rt.(*http.Transport) + return rt + } + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) + + // Prevent the metrics listener being created + metrics.DefaultBindAddress = "0" +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) + + // Put the DefaultBindAddress back + metrics.DefaultBindAddress = ":8080" +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_test.go new file mode 100644 index 00000000000..b75ed1a4e4f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controller_test.go @@ -0,0 +1,336 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller_test + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "go.uber.org/goleak" + corev1 "k8s.io/api/core/v1" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + internalcontroller "sigs.k8s.io/controller-runtime/pkg/internal/controller" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var _ = Describe("controller.Controller", func() { + rec := reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + return reconcile.Result{}, nil + }) + + Describe("New", func() { + It("should return an error if Name is not Specified", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + c, err := controller.New("", m, controller.Options{Reconciler: rec}) + Expect(c).To(BeNil()) + Expect(err.Error()).To(ContainSubstring("must specify Name for Controller")) + }) + + It("should return an error if Reconciler is not Specified", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("foo", m, controller.Options{}) + Expect(c).To(BeNil()) + Expect(err.Error()).To(ContainSubstring("must specify Reconciler")) + }) + + It("should not return an error if two controllers are registered with different names", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c1, err := controller.New("c1", m, controller.Options{Reconciler: rec}) + Expect(err).NotTo(HaveOccurred()) + Expect(c1).ToNot(BeNil()) + + c2, err := controller.New("c2", m, controller.Options{Reconciler: rec}) + Expect(err).NotTo(HaveOccurred()) + Expect(c2).ToNot(BeNil()) + }) + + It("should not leak goroutines when stopped", func() { + currentGRs := goleak.IgnoreCurrent() + + ctx, cancel := context.WithCancel(context.Background()) + watchChan := make(chan event.GenericEvent, 1) + watch := &source.Channel{Source: watchChan} + watchChan <- event.GenericEvent{Object: &corev1.Pod{}} + + reconcileStarted := make(chan struct{}) + controllerFinished := make(chan struct{}) + rec := reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + defer GinkgoRecover() + close(reconcileStarted) + // Make sure reconciliation takes a moment and is not quicker than the controllers + // shutdown. + time.Sleep(50 * time.Millisecond) + // Explicitly test this on top of the leakdetection, as the latter uses Eventually + // so might succeed even when the controller does not wait for all reconciliations + // to finish. + Expect(controllerFinished).NotTo(BeClosed()) + return reconcile.Result{}, nil + }) + + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{Reconciler: rec}) + Expect(c.Watch(watch, &handler.EnqueueRequestForObject{})).To(Succeed()) + Expect(err).NotTo(HaveOccurred()) + + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).To(Succeed()) + close(controllerFinished) + }() + + <-reconcileStarted + cancel() + <-controllerFinished + + // force-close keep-alive connections. These'll time anyway (after + // like 30s or so) but force it to speed up the tests. + clientTransport.CloseIdleConnections() + Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) + }) + + It("should not create goroutines if never started", func() { + currentGRs := goleak.IgnoreCurrent() + + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + _, err = controller.New("new-controller", m, controller.Options{Reconciler: rec}) + Expect(err).NotTo(HaveOccurred()) + + // force-close keep-alive connections. These'll time anyway (after + // like 30s or so) but force it to speed up the tests. + clientTransport.CloseIdleConnections() + Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) + }) + + It("should default RecoverPanic from the manager", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{RecoverPanic: pointer.Bool(true)}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.RecoverPanic).NotTo(BeNil()) + Expect(*ctrl.RecoverPanic).To(BeTrue()) + }) + + It("should not override RecoverPanic on the controller", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{RecoverPanic: pointer.Bool(true)}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + RecoverPanic: pointer.Bool(false), + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.RecoverPanic).NotTo(BeNil()) + Expect(*ctrl.RecoverPanic).To(BeFalse()) + }) + + It("should default NeedLeaderElection from the manager", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{NeedLeaderElection: pointer.Bool(true)}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.NeedLeaderElection()).To(BeTrue()) + }) + + It("should not override NeedLeaderElection on the controller", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{NeedLeaderElection: pointer.Bool(true)}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + NeedLeaderElection: pointer.Bool(false), + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.NeedLeaderElection()).To(BeFalse()) + }) + + It("Should default MaxConcurrentReconciles from the manager if set", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{MaxConcurrentReconciles: 5}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.MaxConcurrentReconciles).To(BeEquivalentTo(5)) + }) + + It("Should default MaxConcurrentReconciles to 1 if unset", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.MaxConcurrentReconciles).To(BeEquivalentTo(1)) + }) + + It("Should leave MaxConcurrentReconciles if set", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + MaxConcurrentReconciles: 5, + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.MaxConcurrentReconciles).To(BeEquivalentTo(5)) + }) + + It("Should default CacheSyncTimeout from the manager if set", func() { + m, err := manager.New(cfg, manager.Options{Controller: config.Controller{CacheSyncTimeout: 5}}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.CacheSyncTimeout).To(BeEquivalentTo(5)) + }) + + It("Should default CacheSyncTimeout to 2 minutes if unset", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.CacheSyncTimeout).To(BeEquivalentTo(2 * time.Minute)) + }) + + It("Should leave CacheSyncTimeout if set", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: reconcile.Func(nil), + CacheSyncTimeout: 5, + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.CacheSyncTimeout).To(BeEquivalentTo(5)) + }) + + It("should default NeedLeaderElection on the controller to true", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: rec, + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.NeedLeaderElection()).To(BeTrue()) + }) + + It("should allow for setting leaderElected to false", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + NeedLeaderElection: pointer.Bool(false), + Reconciler: rec, + }) + Expect(err).NotTo(HaveOccurred()) + + ctrl, ok := c.(*internalcontroller.Controller) + Expect(ok).To(BeTrue()) + + Expect(ctrl.NeedLeaderElection()).To(BeFalse()) + }) + + It("should implement manager.LeaderElectionRunnable", func() { + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + c, err := controller.New("new-controller", m, controller.Options{ + Reconciler: rec, + }) + Expect(err).NotTo(HaveOccurred()) + + _, ok := c.(manager.LeaderElectionRunnable) + Expect(ok).To(BeTrue()) + }) + }) +}) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/doc.go similarity index 100% rename from vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/doc.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/doc.go diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go similarity index 79% rename from vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go index b9f97d52893..627915f94bf 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/testing.go @@ -17,6 +17,7 @@ limitations under the License. package controllertest import ( + "sync" "time" "k8s.io/apimachinery/pkg/runtime" @@ -35,28 +36,33 @@ func (ErrorType) GetObjectKind() schema.ObjectKind { return nil } // DeepCopyObject implements runtime.Object. func (ErrorType) DeepCopyObject() runtime.Object { return nil } -var _ workqueue.RateLimitingInterface = Queue{} +var _ workqueue.RateLimitingInterface = &Queue{} // Queue implements a RateLimiting queue as a non-ratelimited queue for testing. // This helps testing by having functions that use a RateLimiting queue synchronously add items to the queue. type Queue struct { workqueue.Interface + AddedRateLimitedLock sync.Mutex + AddedRatelimited []any } // AddAfter implements RateLimitingInterface. -func (q Queue) AddAfter(item interface{}, duration time.Duration) { +func (q *Queue) AddAfter(item interface{}, duration time.Duration) { q.Add(item) } // AddRateLimited implements RateLimitingInterface. TODO(community): Implement this. -func (q Queue) AddRateLimited(item interface{}) { +func (q *Queue) AddRateLimited(item interface{}) { + q.AddedRateLimitedLock.Lock() + q.AddedRatelimited = append(q.AddedRatelimited, item) + q.AddedRateLimitedLock.Unlock() q.Add(item) } // Forget implements RateLimitingInterface. TODO(community): Implement this. -func (q Queue) Forget(item interface{}) {} +func (q *Queue) Forget(item interface{}) {} // NumRequeues implements RateLimitingInterface. TODO(community): Implement this. -func (q Queue) NumRequeues(item interface{}) int { +func (q *Queue) NumRequeues(item interface{}) int { return 0 } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/unconventionallisttypecrd.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/unconventionallisttypecrd.go similarity index 100% rename from vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/unconventionallisttypecrd.go rename to third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/unconventionallisttypecrd.go diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go new file mode 100644 index 00000000000..60ec61edec7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go @@ -0,0 +1,171 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllertest + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +var _ cache.SharedIndexInformer = &FakeInformer{} + +// FakeInformer provides fake Informer functionality for testing. +type FakeInformer struct { + // Synced is returned by the HasSynced functions to implement the Informer interface + Synced bool + + // RunCount is incremented each time RunInformersAndControllers is called + RunCount int + + handlers []eventHandlerWrapper +} + +type modernResourceEventHandler interface { + OnAdd(obj interface{}, isInInitialList bool) + OnUpdate(oldObj, newObj interface{}) + OnDelete(obj interface{}) +} + +type legacyResourceEventHandler interface { + OnAdd(obj interface{}) + OnUpdate(oldObj, newObj interface{}) + OnDelete(obj interface{}) +} + +// eventHandlerWrapper wraps a ResourceEventHandler in a manner that is compatible with client-go 1.27+ and older. +// The interface was changed in these versions. +type eventHandlerWrapper struct { + handler any +} + +func (e eventHandlerWrapper) OnAdd(obj interface{}) { + if m, ok := e.handler.(modernResourceEventHandler); ok { + m.OnAdd(obj, false) + return + } + e.handler.(legacyResourceEventHandler).OnAdd(obj) +} + +func (e eventHandlerWrapper) OnUpdate(oldObj, newObj interface{}) { + if m, ok := e.handler.(modernResourceEventHandler); ok { + m.OnUpdate(oldObj, newObj) + return + } + e.handler.(legacyResourceEventHandler).OnUpdate(oldObj, newObj) +} + +func (e eventHandlerWrapper) OnDelete(obj interface{}) { + if m, ok := e.handler.(modernResourceEventHandler); ok { + m.OnDelete(obj) + return + } + e.handler.(legacyResourceEventHandler).OnDelete(obj) +} + +// AddIndexers does nothing. TODO(community): Implement this. +func (f *FakeInformer) AddIndexers(indexers cache.Indexers) error { + return nil +} + +// GetIndexer does nothing. TODO(community): Implement this. +func (f *FakeInformer) GetIndexer() cache.Indexer { + return nil +} + +// Informer returns the fake Informer. +func (f *FakeInformer) Informer() cache.SharedIndexInformer { + return f +} + +// HasSynced implements the Informer interface. Returns f.Synced. +func (f *FakeInformer) HasSynced() bool { + return f.Synced +} + +// AddEventHandler implements the Informer interface. Adds an EventHandler to the fake Informers. TODO(community): Implement Registration. +func (f *FakeInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) { + f.handlers = append(f.handlers, eventHandlerWrapper{handler}) + return nil, nil +} + +// Run implements the Informer interface. Increments f.RunCount. +func (f *FakeInformer) Run(<-chan struct{}) { + f.RunCount++ +} + +// Add fakes an Add event for obj. +func (f *FakeInformer) Add(obj metav1.Object) { + for _, h := range f.handlers { + h.OnAdd(obj) + } +} + +// Update fakes an Update event for obj. +func (f *FakeInformer) Update(oldObj, newObj metav1.Object) { + for _, h := range f.handlers { + h.OnUpdate(oldObj, newObj) + } +} + +// Delete fakes an Delete event for obj. +func (f *FakeInformer) Delete(obj metav1.Object) { + for _, h := range f.handlers { + h.OnDelete(obj) + } +} + +// AddEventHandlerWithResyncPeriod does nothing. TODO(community): Implement this. +func (f *FakeInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) (cache.ResourceEventHandlerRegistration, error) { + return nil, nil +} + +// RemoveEventHandler does nothing. TODO(community): Implement this. +func (f *FakeInformer) RemoveEventHandler(handle cache.ResourceEventHandlerRegistration) error { + return nil +} + +// GetStore does nothing. TODO(community): Implement this. +func (f *FakeInformer) GetStore() cache.Store { + return nil +} + +// GetController does nothing. TODO(community): Implement this. +func (f *FakeInformer) GetController() cache.Controller { + return nil +} + +// LastSyncResourceVersion does nothing. TODO(community): Implement this. +func (f *FakeInformer) LastSyncResourceVersion() string { + return "" +} + +// SetWatchErrorHandler does nothing. TODO(community): Implement this. +func (f *FakeInformer) SetWatchErrorHandler(cache.WatchErrorHandler) error { + return nil +} + +// SetTransform does nothing. TODO(community): Implement this. +func (f *FakeInformer) SetTransform(t cache.TransformFunc) error { + return nil +} + +// IsStopped does nothing. TODO(community): Implement this. +func (f *FakeInformer) IsStopped() bool { + return false +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go new file mode 100644 index 00000000000..344abcd288c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go @@ -0,0 +1,394 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerutil + +import ( + "context" + "fmt" + "reflect" + + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// AlreadyOwnedError is an error returned if the object you are trying to assign +// a controller reference is already owned by another controller Object is the +// subject and Owner is the reference for the current owner. +type AlreadyOwnedError struct { + Object metav1.Object + Owner metav1.OwnerReference +} + +func (e *AlreadyOwnedError) Error() string { + return fmt.Sprintf("Object %s/%s is already owned by another %s controller %s", e.Object.GetNamespace(), e.Object.GetName(), e.Owner.Kind, e.Owner.Name) +} + +func newAlreadyOwnedError(obj metav1.Object, owner metav1.OwnerReference) *AlreadyOwnedError { + return &AlreadyOwnedError{ + Object: obj, + Owner: owner, + } +} + +// SetControllerReference sets owner as a Controller OwnerReference on controlled. +// This is used for garbage collection of the controlled object and for +// reconciling the owner object on changes to controlled (with a Watch + EnqueueRequestForOwner). +// Since only one OwnerReference can be a controller, it returns an error if +// there is another OwnerReference with Controller flag set. +func SetControllerReference(owner, controlled metav1.Object, scheme *runtime.Scheme) error { + // Validate the owner. + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call SetControllerReference", owner) + } + if err := validateOwner(owner, controlled); err != nil { + return err + } + + // Create a new controller ref. + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + ref := metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + Name: owner.GetName(), + UID: owner.GetUID(), + BlockOwnerDeletion: pointer.Bool(true), + Controller: pointer.Bool(true), + } + + // Return early with an error if the object is already controlled. + if existing := metav1.GetControllerOf(controlled); existing != nil && !referSameObject(*existing, ref) { + return newAlreadyOwnedError(controlled, *existing) + } + + // Update owner references and return. + upsertOwnerRef(ref, controlled) + return nil +} + +// SetOwnerReference is a helper method to make sure the given object contains an object reference to the object provided. +// This allows you to declare that owner has a dependency on the object without specifying it as a controller. +// If a reference to the same object already exists, it'll be overwritten with the newly provided version. +func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error { + // Validate the owner. + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call SetOwnerReference", owner) + } + if err := validateOwner(owner, object); err != nil { + return err + } + + // Create a new owner ref. + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + ref := metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + UID: owner.GetUID(), + Name: owner.GetName(), + } + + // Update owner references and return. + upsertOwnerRef(ref, object) + return nil +} + +func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) { + owners := object.GetOwnerReferences() + if idx := indexOwnerRef(owners, ref); idx == -1 { + owners = append(owners, ref) + } else { + owners[idx] = ref + } + object.SetOwnerReferences(owners) +} + +// indexOwnerRef returns the index of the owner reference in the slice if found, or -1. +func indexOwnerRef(ownerReferences []metav1.OwnerReference, ref metav1.OwnerReference) int { + for index, r := range ownerReferences { + if referSameObject(r, ref) { + return index + } + } + return -1 +} + +func validateOwner(owner, object metav1.Object) error { + ownerNs := owner.GetNamespace() + if ownerNs != "" { + objNs := object.GetNamespace() + if objNs == "" { + return fmt.Errorf("cluster-scoped resource must not have a namespace-scoped owner, owner's namespace %s", ownerNs) + } + if ownerNs != objNs { + return fmt.Errorf("cross-namespace owner references are disallowed, owner's namespace %s, obj's namespace %s", owner.GetNamespace(), object.GetNamespace()) + } + } + return nil +} + +// Returns true if a and b point to the same object. +func referSameObject(a, b metav1.OwnerReference) bool { + aGV, err := schema.ParseGroupVersion(a.APIVersion) + if err != nil { + return false + } + + bGV, err := schema.ParseGroupVersion(b.APIVersion) + if err != nil { + return false + } + + return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name +} + +// OperationResult is the action result of a CreateOrUpdate call. +type OperationResult string + +const ( // They should complete the sentence "Deployment default/foo has been ..." + // OperationResultNone means that the resource has not been changed. + OperationResultNone OperationResult = "unchanged" + // OperationResultCreated means that a new resource is created. + OperationResultCreated OperationResult = "created" + // OperationResultUpdated means that an existing resource is updated. + OperationResultUpdated OperationResult = "updated" + // OperationResultUpdatedStatus means that an existing resource and its status is updated. + OperationResultUpdatedStatus OperationResult = "updatedStatus" + // OperationResultUpdatedStatusOnly means that only an existing status is updated. + OperationResultUpdatedStatusOnly OperationResult = "updatedStatusOnly" +) + +// CreateOrUpdate creates or updates the given object in the Kubernetes +// cluster. The object's desired state must be reconciled with the existing +// state inside the passed in callback MutateFn. +// +// The MutateFn is called regardless of creating or updating an object. +// +// It returns the executed operation and an error. +func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) { + key := client.ObjectKeyFromObject(obj) + if err := c.Get(ctx, key, obj); err != nil { + if !apierrors.IsNotFound(err) { + return OperationResultNone, err + } + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + if err := c.Create(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultCreated, nil + } + + existing := obj.DeepCopyObject() + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + + if equality.Semantic.DeepEqual(existing, obj) { + return OperationResultNone, nil + } + + if err := c.Update(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultUpdated, nil +} + +// CreateOrPatch creates or patches the given object in the Kubernetes +// cluster. The object's desired state must be reconciled with the before +// state inside the passed in callback MutateFn. +// +// The MutateFn is called regardless of creating or updating an object. +// +// It returns the executed operation and an error. +func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) { + key := client.ObjectKeyFromObject(obj) + if err := c.Get(ctx, key, obj); err != nil { + if !apierrors.IsNotFound(err) { + return OperationResultNone, err + } + if f != nil { + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + } + if err := c.Create(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultCreated, nil + } + + // Create patches for the object and its possible status. + objPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object)) + statusPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object)) + + // Create a copy of the original object as well as converting that copy to + // unstructured data. + before, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj.DeepCopyObject()) + if err != nil { + return OperationResultNone, err + } + + // Attempt to extract the status from the resource for easier comparison later + beforeStatus, hasBeforeStatus, err := unstructured.NestedFieldCopy(before, "status") + if err != nil { + return OperationResultNone, err + } + + // If the resource contains a status then remove it from the unstructured + // copy to avoid unnecessary patching later. + if hasBeforeStatus { + unstructured.RemoveNestedField(before, "status") + } + + // Mutate the original object. + if f != nil { + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + } + + // Convert the resource to unstructured to compare against our before copy. + after, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return OperationResultNone, err + } + + // Attempt to extract the status from the resource for easier comparison later + afterStatus, hasAfterStatus, err := unstructured.NestedFieldCopy(after, "status") + if err != nil { + return OperationResultNone, err + } + + // If the resource contains a status then remove it from the unstructured + // copy to avoid unnecessary patching later. + if hasAfterStatus { + unstructured.RemoveNestedField(after, "status") + } + + result := OperationResultNone + + if !reflect.DeepEqual(before, after) { + // Only issue a Patch if the before and after resources (minus status) differ + if err := c.Patch(ctx, obj, objPatch); err != nil { + return result, err + } + result = OperationResultUpdated + } + + if (hasBeforeStatus || hasAfterStatus) && !reflect.DeepEqual(beforeStatus, afterStatus) { + // Only issue a Status Patch if the resource has a status and the beforeStatus + // and afterStatus copies differ + if result == OperationResultUpdated { + // If Status was replaced by Patch before, set it to afterStatus + objectAfterPatch, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return result, err + } + if err = unstructured.SetNestedField(objectAfterPatch, afterStatus, "status"); err != nil { + return result, err + } + // If Status was replaced by Patch before, restore patched structure to the obj + if err = runtime.DefaultUnstructuredConverter.FromUnstructured(objectAfterPatch, obj); err != nil { + return result, err + } + } + if err := c.Status().Patch(ctx, obj, statusPatch); err != nil { + return result, err + } + if result == OperationResultUpdated { + result = OperationResultUpdatedStatus + } else { + result = OperationResultUpdatedStatusOnly + } + } + + return result, nil +} + +// mutate wraps a MutateFn and applies validation to its result. +func mutate(f MutateFn, key client.ObjectKey, obj client.Object) error { + if err := f(); err != nil { + return err + } + if newKey := client.ObjectKeyFromObject(obj); key != newKey { + return fmt.Errorf("MutateFn cannot mutate object name and/or object namespace") + } + return nil +} + +// MutateFn is a function which mutates the existing object into its desired state. +type MutateFn func() error + +// AddFinalizer accepts an Object and adds the provided finalizer if not present. +// It returns an indication of whether it updated the object's list of finalizers. +func AddFinalizer(o client.Object, finalizer string) (finalizersUpdated bool) { + f := o.GetFinalizers() + for _, e := range f { + if e == finalizer { + return false + } + } + o.SetFinalizers(append(f, finalizer)) + return true +} + +// RemoveFinalizer accepts an Object and removes the provided finalizer if present. +// It returns an indication of whether it updated the object's list of finalizers. +func RemoveFinalizer(o client.Object, finalizer string) (finalizersUpdated bool) { + f := o.GetFinalizers() + for i := 0; i < len(f); i++ { + if f[i] == finalizer { + f = append(f[:i], f[i+1:]...) + i-- + finalizersUpdated = true + } + } + o.SetFinalizers(f) + return +} + +// ContainsFinalizer checks an Object that the provided finalizer is present. +func ContainsFinalizer(o client.Object, finalizer string) bool { + f := o.GetFinalizers() + for _, e := range f { + if e == finalizer { + return true + } + } + return false +} + +// Object allows functions to work indistinctly with any resource that +// implements both Object interfaces. +// +// Deprecated: Use client.Object instead. +type Object = client.Object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_suite_test.go new file mode 100644 index 00000000000..a4ac5cc746a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_suite_test.go @@ -0,0 +1,53 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerutil_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +func TestControllerutil(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Controllerutil Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var c client.Client + +var _ = BeforeSuite(func() { + var err error + + testenv = &envtest.Environment{} + + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + c, err = client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_test.go new file mode 100644 index 00000000000..d176c4fb6a1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil_test.go @@ -0,0 +1,840 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerutil_test + +import ( + "context" + "fmt" + "math/rand" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +var _ = Describe("Controllerutil", func() { + Describe("SetOwnerReference", func() { + It("should set ownerRef on an empty list", func() { + rs := &appsv1.ReplicaSet{} + dep := &extensionsv1beta1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid"}, + } + Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + })) + }) + + It("should not duplicate owner references", func() { + rs := &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + }, + }, + }, + } + dep := &extensionsv1beta1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid"}, + } + + Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + })) + }) + + It("should update the reference", func() { + rs := &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1alpha1", + UID: "foo-uid-1", + }, + }, + }, + } + dep := &extensionsv1beta1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid-2"}, + } + + Expect(controllerutil.SetOwnerReference(dep, rs, scheme.Scheme)).ToNot(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid-2", + })) + }) + }) + + Describe("SetControllerReference", func() { + It("should set the OwnerReference if it can find the group version kind", func() { + rs := &appsv1.ReplicaSet{} + dep := &extensionsv1beta1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: "foo-uid"}, + } + + Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred()) + t := true + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + Controller: &t, + BlockOwnerDeletion: &t, + })) + }) + + It("should return an error if it can't find the group version kind of the owner", func() { + rs := &appsv1.ReplicaSet{} + dep := &extensionsv1beta1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + } + Expect(controllerutil.SetControllerReference(dep, rs, runtime.NewScheme())).To(HaveOccurred()) + }) + + It("should return an error if the owner isn't a runtime.Object", func() { + rs := &appsv1.ReplicaSet{} + Expect(controllerutil.SetControllerReference(&errMetaObj{}, rs, scheme.Scheme)).To(HaveOccurred()) + }) + + It("should return an error if object is already owned by another controller", func() { + t := true + rsOwners := []metav1.OwnerReference{ + { + Name: "bar", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "bar-uid", + Controller: &t, + BlockOwnerDeletion: &t, + }, + } + rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}} + dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}} + + err := controllerutil.SetControllerReference(dep, rs, scheme.Scheme) + + Expect(err).To(HaveOccurred()) + Expect(err).To(BeAssignableToTypeOf(&controllerutil.AlreadyOwnedError{})) + }) + + It("should not duplicate existing owner reference", func() { + f := false + t := true + rsOwners := []metav1.OwnerReference{ + { + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + Controller: &f, + BlockOwnerDeletion: &t, + }, + } + rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}} + dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}} + + Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + Controller: &t, + BlockOwnerDeletion: &t, + })) + }) + + It("should replace the owner reference if it's already present", func() { + t := true + rsOwners := []metav1.OwnerReference{ + { + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1alpha1", + UID: "foo-uid", + Controller: &t, + BlockOwnerDeletion: &t, + }, + } + rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}} + dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}} + + Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + Controller: &t, + BlockOwnerDeletion: &t, + })) + }) + + It("should return an error if it's setting a cross-namespace owner reference", func() { + rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "namespace1"}} + dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "namespace2", UID: "foo-uid"}} + + err := controllerutil.SetControllerReference(dep, rs, scheme.Scheme) + + Expect(err).To(HaveOccurred()) + }) + + It("should return an error if it's owner is namespaced resource but dependant is cluster-scoped resource", func() { + pv := &corev1.PersistentVolume{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} + pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}} + + err := controllerutil.SetControllerReference(pod, pv, scheme.Scheme) + + Expect(err).To(HaveOccurred()) + }) + + It("should not return any error if the existing owner has a different version", func() { + f := false + t := true + rsOwners := []metav1.OwnerReference{ + { + Name: "foo", + Kind: "Deployment", + APIVersion: "extensions/v1alpha1", + UID: "foo-uid", + Controller: &f, + BlockOwnerDeletion: &t, + }, + } + rs := &appsv1.ReplicaSet{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", OwnerReferences: rsOwners}} + dep := &extensionsv1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default", UID: "foo-uid"}} + + Expect(controllerutil.SetControllerReference(dep, rs, scheme.Scheme)).NotTo(HaveOccurred()) + Expect(rs.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ + Name: "foo", + Kind: "Deployment", + // APIVersion is the new owner's one + APIVersion: "extensions/v1beta1", + UID: "foo-uid", + Controller: &t, + BlockOwnerDeletion: &t, + })) + }) + }) + + Describe("CreateOrUpdate", func() { + var deploy *appsv1.Deployment + var deplSpec appsv1.DeploymentSpec + var deplKey types.NamespacedName + var specr controllerutil.MutateFn + + BeforeEach(func() { + deploy = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("deploy-%d", rand.Int31()), //nolint:gosec + Namespace: "default", + }, + } + + deplSpec = appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "busybox", + Image: "busybox", + }, + }, + }, + }, + } + + deplKey = types.NamespacedName{ + Name: deploy.Name, + Namespace: deploy.Namespace, + } + + specr = deploymentSpecr(deploy, deplSpec) + }) + + It("creates a new object if one doesn't exists", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, specr) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultCreated") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + + By("actually having the deployment created") + fetched := &appsv1.Deployment{} + Expect(c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + + By("being mutated by MutateFn") + Expect(fetched.Spec.Template.Spec.Containers).To(HaveLen(1)) + Expect(fetched.Spec.Template.Spec.Containers[0].Name).To(Equal(deplSpec.Template.Spec.Containers[0].Name)) + Expect(fetched.Spec.Template.Spec.Containers[0].Image).To(Equal(deplSpec.Template.Spec.Containers[0].Image)) + }) + + It("updates existing object", func() { + var scale int32 = 2 + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, specr) + Expect(err).NotTo(HaveOccurred()) + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentScaler(deploy, scale)) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdated") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdated)) + + By("actually having the deployment scaled") + fetched := &appsv1.Deployment{} + Expect(c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + Expect(*fetched.Spec.Replicas).To(Equal(scale)) + }) + + It("updates only changed objects", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentIdentity) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("errors when MutateFn changes object name on creation", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, func() error { + Expect(specr()).To(Succeed()) + return deploymentRenamer(deploy)() + }) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("errors when MutateFn renames an object", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentRenamer(deploy)) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("errors when object namespace changes", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), c, deploy, deploymentNamespaceChanger(deploy)) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("aborts immediately if there was an error initially retrieving the object", func() { + op, err := controllerutil.CreateOrUpdate(context.TODO(), errorReader{c}, deploy, func() error { + Fail("Mutation method should not run") + return nil + }) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("CreateOrPatch", func() { + var deploy *appsv1.Deployment + var deplSpec appsv1.DeploymentSpec + var deplKey types.NamespacedName + var specr controllerutil.MutateFn + + BeforeEach(func() { + deploy = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("deploy-%d", rand.Int31()), //nolint:gosec + Namespace: "default", + }, + } + + deplSpec = appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "busybox", + Image: "busybox", + }, + }, + }, + }, + } + + deplKey = types.NamespacedName{ + Name: deploy.Name, + Namespace: deploy.Namespace, + } + + specr = deploymentSpecr(deploy, deplSpec) + }) + + assertLocalDeployWasUpdated := func(fetched *appsv1.Deployment) { + By("local deploy object was updated during patch & has same spec, status, resource version as fetched") + if fetched == nil { + fetched = &appsv1.Deployment{} + ExpectWithOffset(1, c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + } + ExpectWithOffset(1, fetched.ResourceVersion).To(Equal(deploy.ResourceVersion)) + ExpectWithOffset(1, fetched.Spec).To(BeEquivalentTo(deploy.Spec)) + ExpectWithOffset(1, fetched.Status).To(BeEquivalentTo(deploy.Status)) + } + + assertLocalDeployStatusWasUpdated := func(fetched *appsv1.Deployment) { + By("local deploy object was updated during patch & has same spec, status, resource version as fetched") + if fetched == nil { + fetched = &appsv1.Deployment{} + ExpectWithOffset(1, c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + } + ExpectWithOffset(1, fetched.ResourceVersion).To(Equal(deploy.ResourceVersion)) + ExpectWithOffset(1, *fetched.Spec.Replicas).To(BeEquivalentTo(int32(5))) + ExpectWithOffset(1, fetched.Status).To(BeEquivalentTo(deploy.Status)) + ExpectWithOffset(1, len(fetched.Status.Conditions)).To(BeEquivalentTo(1)) + } + + It("creates a new object if one doesn't exists", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultCreated") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + + By("actually having the deployment created") + fetched := &appsv1.Deployment{} + Expect(c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + + By("being mutated by MutateFn") + Expect(fetched.Spec.Template.Spec.Containers).To(HaveLen(1)) + Expect(fetched.Spec.Template.Spec.Containers[0].Name).To(Equal(deplSpec.Template.Spec.Containers[0].Name)) + Expect(fetched.Spec.Template.Spec.Containers[0].Image).To(Equal(deplSpec.Template.Spec.Containers[0].Image)) + }) + + It("patches existing object", func() { + var scale int32 = 2 + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + Expect(err).NotTo(HaveOccurred()) + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, deploymentScaler(deploy, scale)) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdated") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdated)) + + By("actually having the deployment scaled") + fetched := &appsv1.Deployment{} + Expect(c.Get(context.TODO(), deplKey, fetched)).To(Succeed()) + Expect(*fetched.Spec.Replicas).To(Equal(scale)) + assertLocalDeployWasUpdated(fetched) + }) + + It("patches only changed objects", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, deploymentIdentity) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + + assertLocalDeployWasUpdated(nil) + }) + + It("patches only changed status", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + deployStatus := appsv1.DeploymentStatus{ + ReadyReplicas: 1, + Replicas: 3, + } + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, deploymentStatusr(deploy, deployStatus)) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdatedStatusOnly") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdatedStatusOnly)) + + assertLocalDeployWasUpdated(nil) + }) + + It("patches resource and status", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + replicas := int32(3) + deployStatus := appsv1.DeploymentStatus{ + ReadyReplicas: 1, + Replicas: replicas, + } + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, func() error { + Expect(deploymentScaler(deploy, replicas)()).To(Succeed()) + return deploymentStatusr(deploy, deployStatus)() + }) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdatedStatus") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdatedStatus)) + + assertLocalDeployWasUpdated(nil) + }) + + It("patches resource and not empty status", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + replicas := int32(3) + deployStatus := appsv1.DeploymentStatus{ + ReadyReplicas: 1, + Replicas: replicas, + } + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, func() error { + Expect(deploymentScaler(deploy, replicas)()).To(Succeed()) + return deploymentStatusr(deploy, deployStatus)() + }) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdatedStatus") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdatedStatus)) + + assertLocalDeployWasUpdated(nil) + + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, func() error { + deploy.Spec.Replicas = pointer.Int32(5) + deploy.Status.Conditions = []appsv1.DeploymentCondition{{ + Type: appsv1.DeploymentProgressing, + Status: corev1.ConditionTrue, + }} + return nil + }) + By("returning no error") + Expect(err).NotTo(HaveOccurred()) + + By("returning OperationResultUpdatedStatus") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultUpdatedStatus)) + + assertLocalDeployStatusWasUpdated(nil) + }) + + It("errors when MutateFn changes object name on creation", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, func() error { + Expect(specr()).To(Succeed()) + return deploymentRenamer(deploy)() + }) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("errors when MutateFn renames an object", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, deploymentRenamer(deploy)) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("errors when object namespace changes", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), c, deploy, specr) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultCreated)) + Expect(err).NotTo(HaveOccurred()) + + op, err = controllerutil.CreateOrPatch(context.TODO(), c, deploy, deploymentNamespaceChanger(deploy)) + + By("returning error") + Expect(err).To(HaveOccurred()) + + By("returning OperationResultNone") + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + }) + + It("aborts immediately if there was an error initially retrieving the object", func() { + op, err := controllerutil.CreateOrPatch(context.TODO(), errorReader{c}, deploy, func() error { + Fail("Mutation method should not run") + return nil + }) + + Expect(op).To(BeEquivalentTo(controllerutil.OperationResultNone)) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("Finalizers", func() { + var deploy *appsv1.Deployment + + Describe("AddFinalizer", func() { + deploy = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{}, + }, + } + + It("should add the finalizer when not present", func() { + controllerutil.AddFinalizer(deploy, testFinalizer) + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer})) + }) + + It("should not add the finalizer when already present", func() { + controllerutil.AddFinalizer(deploy, testFinalizer) + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer})) + }) + }) + + Describe("RemoveFinalizer", func() { + It("should remove finalizer if present", func() { + controllerutil.RemoveFinalizer(deploy, testFinalizer) + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{})) + }) + + It("should remove all equal finalizers if present", func() { + deploy.SetFinalizers(append(deploy.Finalizers, testFinalizer, testFinalizer)) + controllerutil.RemoveFinalizer(deploy, testFinalizer) + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{})) + }) + }) + + Describe("AddFinalizer, which returns an indication of whether it modified the object's list of finalizers,", func() { + deploy = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{}, + }, + } + + When("the object's list of finalizers has no instances of the input finalizer", func() { + It("should return true", func() { + Expect(controllerutil.AddFinalizer(deploy, testFinalizer)).To(BeTrue()) + }) + It("should add the input finalizer to the object's list of finalizers", func() { + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer})) + }) + }) + + When("the object's list of finalizers has an instance of the input finalizer", func() { + It("should return false", func() { + Expect(controllerutil.AddFinalizer(deploy, testFinalizer)).To(BeFalse()) + }) + It("should not modify the object's list of finalizers", func() { + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer})) + }) + }) + }) + + Describe("RemoveFinalizer, which returns an indication of whether it modified the object's list of finalizers,", func() { + When("the object's list of finalizers has no instances of the input finalizer", func() { + It("should return false", func() { + Expect(controllerutil.RemoveFinalizer(deploy, testFinalizer1)).To(BeFalse()) + }) + It("should not modify the object's list of finalizers", func() { + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{testFinalizer})) + }) + }) + + When("the object's list of finalizers has one instance of the input finalizer", func() { + It("should return true", func() { + Expect(controllerutil.RemoveFinalizer(deploy, testFinalizer)).To(BeTrue()) + }) + It("should remove the instance of the input finalizer from the object's list of finalizers", func() { + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{})) + }) + }) + + When("the object's list of finalizers has multiple instances of the input finalizer", func() { + It("should return true", func() { + deploy.SetFinalizers(append(deploy.Finalizers, testFinalizer, testFinalizer)) + Expect(controllerutil.RemoveFinalizer(deploy, testFinalizer)).To(BeTrue()) + }) + It("should remove each instance of the input finalizer from the object's list of finalizers", func() { + Expect(deploy.ObjectMeta.GetFinalizers()).To(Equal([]string{})) + }) + }) + }) + + Describe("ContainsFinalizer", func() { + It("should check that finalizer is present", func() { + controllerutil.AddFinalizer(deploy, testFinalizer) + Expect(controllerutil.ContainsFinalizer(deploy, testFinalizer)).To(Equal(true)) + }) + + It("should check that finalizer is not present after RemoveFinalizer call", func() { + controllerutil.RemoveFinalizer(deploy, testFinalizer) + Expect(controllerutil.ContainsFinalizer(deploy, testFinalizer)).To(Equal(false)) + }) + }) + }) +}) + +const ( + testFinalizer = "foo.bar.baz" + testFinalizer1 = testFinalizer + "1" +) + +var ( + _ runtime.Object = &errRuntimeObj{} + _ metav1.Object = &errMetaObj{} +) + +type errRuntimeObj struct { + runtime.TypeMeta +} + +func (o *errRuntimeObj) DeepCopyObject() runtime.Object { + return &errRuntimeObj{} +} + +type errMetaObj struct { + metav1.ObjectMeta +} + +func deploymentSpecr(deploy *appsv1.Deployment, spec appsv1.DeploymentSpec) controllerutil.MutateFn { + return func() error { + deploy.Spec = spec + return nil + } +} + +func deploymentStatusr(deploy *appsv1.Deployment, status appsv1.DeploymentStatus) controllerutil.MutateFn { + return func() error { + deploy.Status = status + return nil + } +} + +var deploymentIdentity controllerutil.MutateFn = func() error { + return nil +} + +func deploymentRenamer(deploy *appsv1.Deployment) controllerutil.MutateFn { + return func() error { + deploy.Name = fmt.Sprintf("%s-1", deploy.Name) + return nil + } +} + +func deploymentNamespaceChanger(deploy *appsv1.Deployment) controllerutil.MutateFn { + return func() error { + deploy.Namespace = fmt.Sprintf("%s-1", deploy.Namespace) + return nil + } +} + +func deploymentScaler(deploy *appsv1.Deployment, replicas int32) controllerutil.MutateFn { + fn := func() error { + deploy.Spec.Replicas = &replicas + return nil + } + return fn +} + +type errorReader struct { + client.Client +} + +func (e errorReader) Get(ctx context.Context, key client.ObjectKey, into client.Object, opts ...client.GetOption) error { + return fmt.Errorf("unexpected error") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go new file mode 100644 index 00000000000..ab386b29cdb --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package controllerutil contains utility functions for working with and implementing Controllers. +*/ +package controllerutil diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/example_test.go new file mode 100644 index 00000000000..b2d6f71a5c6 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/example_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllerutil_test + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + log = logf.Log.WithName("controllerutil-examples") +) + +// This example creates or updates an existing deployment. +func ExampleCreateOrUpdate() { + // c is client.Client + + // Create or Update the deployment default/foo + deploy := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + op, err := controllerutil.CreateOrUpdate(context.TODO(), c, deploy, func() error { + // Deployment selector is immutable so we set this value only if + // a new object is going to be created + if deploy.ObjectMeta.CreationTimestamp.IsZero() { + deploy.Spec.Selector = &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + } + } + + // update the Deployment pod template + deploy.Spec.Template = corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "busybox", + Image: "busybox", + }, + }, + }, + } + + return nil + }) + + if err != nil { + log.Error(err, "Deployment reconcile failed") + } else { + log.Info("Deployment successfully reconciled", "operation", op) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/doc.go new file mode 100644 index 00000000000..228335e9293 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/doc.go @@ -0,0 +1,25 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package controller provides types and functions for building Controllers. Controllers implement Kubernetes APIs. + +# Creation + +To create a new Controller, first create a manager.Manager and pass it to the controller.New function. +The Controller MUST be started by calling Manager.Start. +*/ +package controller diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/example_test.go new file mode 100644 index 00000000000..d4fa1aef0be --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/example_test.go @@ -0,0 +1,165 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller_test + +import ( + "context" + "os" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var ( + mgr manager.Manager + // NB: don't call SetLogger in init(), or else you'll mess up logging in the main suite. + log = logf.Log.WithName("controller-examples") +) + +// This example creates a new Controller named "pod-controller" with a no-op reconcile function. The +// manager.Manager will be used to Start the Controller, and will provide it a shared Cache and Client. +func ExampleNew() { + _, err := controller.New("pod-controller", mgr, controller.Options{ + Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + // Your business logic to implement the API by creating, updating, deleting objects goes here. + return reconcile.Result{}, nil + }), + }) + if err != nil { + log.Error(err, "unable to create pod-controller") + os.Exit(1) + } +} + +// This example starts a new Controller named "pod-controller" to Watch Pods and call a no-op Reconciler. +func ExampleController() { + // mgr is a manager.Manager + + // Create a new Controller that will call the provided Reconciler function in response + // to events. + c, err := controller.New("pod-controller", mgr, controller.Options{ + Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + // Your business logic to implement the API by creating, updating, deleting objects goes here. + return reconcile.Result{}, nil + }), + }) + if err != nil { + log.Error(err, "unable to create pod-controller") + os.Exit(1) + } + + // Watch for Pod create / update / delete events and call Reconcile + err = c.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}), &handler.EnqueueRequestForObject{}) + if err != nil { + log.Error(err, "unable to watch pods") + os.Exit(1) + } + + // Start the Controller through the manager. + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "unable to continue running manager") + os.Exit(1) + } +} + +// This example starts a new Controller named "pod-controller" to Watch Pods with the unstructured object and call a no-op Reconciler. +func ExampleController_unstructured() { + // mgr is a manager.Manager + + // Create a new Controller that will call the provided Reconciler function in response + // to events. + c, err := controller.New("pod-controller", mgr, controller.Options{ + Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + // Your business logic to implement the API by creating, updating, deleting objects goes here. + return reconcile.Result{}, nil + }), + }) + if err != nil { + log.Error(err, "unable to create pod-controller") + os.Exit(1) + } + + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(schema.GroupVersionKind{ + Kind: "Pod", + Group: "", + Version: "v1", + }) + // Watch for Pod create / update / delete events and call Reconcile + err = c.Watch(source.Kind(mgr.GetCache(), u), &handler.EnqueueRequestForObject{}) + if err != nil { + log.Error(err, "unable to watch pods") + os.Exit(1) + } + + // Start the Controller through the manager. + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "unable to continue running manager") + os.Exit(1) + } +} + +// This example creates a new controller named "pod-controller" to watch Pods +// and call a no-op reconciler. The controller is not added to the provided +// manager, and must thus be started and stopped by the caller. +func ExampleNewUnmanaged() { + // mgr is a manager.Manager + + // Configure creates a new controller but does not add it to the supplied + // manager. + c, err := controller.NewUnmanaged("pod-controller", mgr, controller.Options{ + Reconciler: reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + return reconcile.Result{}, nil + }), + }) + if err != nil { + log.Error(err, "unable to create pod-controller") + os.Exit(1) + } + + if err := c.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}), &handler.EnqueueRequestForObject{}); err != nil { + log.Error(err, "unable to watch pods") + os.Exit(1) + } + + ctx, cancel := context.WithCancel(context.Background()) + + // Start our controller in a goroutine so that we do not block. + go func() { + // Block until our controller manager is elected leader. We presume our + // entire process will terminate if we lose leadership, so we don't need + // to handle that. + <-mgr.Elected() + + // Start our controller. This will block until the context is + // closed, or the controller returns an error. + if err := c.Start(ctx); err != nil { + log.Error(err, "cannot run experiment controller") + } + }() + + // Stop our controller. + cancel() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/controller/testdata/crds/unconventionallisttype.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/testdata/crds/unconventionallisttype.yaml new file mode 100644 index 00000000000..3069c473e54 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/controller/testdata/crds/unconventionallisttype.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: unconventionallisttypes.chaosapps.metamagical.io +spec: + group: chaosapps.metamagical.io + names: + kind: UnconventionalListType + plural: unconventionallisttypes + scope: Namespaced + versions: + - name: "v1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go b/third_party/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go new file mode 100644 index 00000000000..da32ab48e4b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package conversion provides interface definitions that an API Type needs to +implement for it to be supported by the generic conversion webhook handler +defined under pkg/webhook/conversion. +*/ +package conversion + +import "k8s.io/apimachinery/pkg/runtime" + +// Convertible defines capability of a type to convertible i.e. it can be converted to/from a hub type. +type Convertible interface { + runtime.Object + ConvertTo(dst Hub) error + ConvertFrom(src Hub) error +} + +// Hub marks that a given type is the hub type for conversion. This means that +// all conversions will first convert to the hub type, then convert from the hub +// type to the destination type. All types besides the hub type should implement +// Convertible. +type Hub interface { + runtime.Object + Hub() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/doc.go new file mode 100644 index 00000000000..89b380c1084 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/doc.go @@ -0,0 +1,207 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package pkg provides libraries for building Controllers. Controllers implement Kubernetes APIs +and are foundational to building Operators, Workload APIs, Configuration APIs, Autoscalers, and more. + +# Client + +Client provides a Read + Write client for reading and writing Kubernetes objects. + +# Cache + +Cache provides a Read client for reading objects from a local cache. +A cache may register handlers to respond to events that update the cache. + +# Manager + +Manager is required for creating a Controller and provides the Controller shared dependencies such as +clients, caches, schemes, etc. Controllers should be Started through the Manager by calling Manager.Start. + +# Controller + +Controller implements a Kubernetes API by responding to events (object Create, Update, Delete) and ensuring that +the state specified in the Spec of the object matches the state of the system. This is called a reconcile. +If they do not match, the Controller will create / update / delete objects as needed to make them match. + +Controllers are implemented as worker queues that process reconcile.Requests (requests to reconcile the +state for a specific object). + +Unlike http handlers, Controllers DO NOT handle events directly, but enqueue Requests to eventually reconcile +the object. This means the handling of multiple events may be batched together and the full state of the +system must be read for each reconcile. + +* Controllers require a Reconciler to be provided to perform the work pulled from the work queue. + +* Controllers require Watches to be configured to enqueue reconcile.Requests in response to events. + +# Webhook + +Admission Webhooks are a mechanism for extending kubernetes APIs. Webhooks can be configured with target +event type (object Create, Update, Delete), the API server will send AdmissionRequests to them +when certain events happen. The webhooks may mutate and (or) validate the object embedded in +the AdmissionReview requests and send back the response to the API server. + +There are 2 types of admission webhook: mutating and validating admission webhook. +Mutating webhook is used to mutate a core API object or a CRD instance before the API server admits it. +Validating webhook is used to validate if an object meets certain requirements. + +* Admission Webhooks require Handler(s) to be provided to process the received AdmissionReview requests. + +# Reconciler + +Reconciler is a function provided to a Controller that may be called at anytime with the Name and Namespace of an object. +When called, the Reconciler will ensure that the state of the system matches what is specified in the object at the +time the Reconciler is called. + +Example: Reconciler invoked for a ReplicaSet object. The ReplicaSet specifies 5 replicas but only +3 Pods exist in the system. The Reconciler creates 2 more Pods and sets their OwnerReference to point at the +ReplicaSet with controller=true. + +* Reconciler contains all of the business logic of a Controller. + +* Reconciler typically works on a single object type. - e.g. it will only reconcile ReplicaSets. For separate +types use separate Controllers. If you wish to trigger reconciles from other objects, you can provide +a mapping (e.g. owner references) that maps the object that triggers the reconcile to the object being reconciled. + +* Reconciler is provided the Name / Namespace of the object to reconcile. + +* Reconciler does not care about the event contents or event type responsible for triggering the reconcile. +- e.g. it doesn't matter whether a ReplicaSet was created or updated, Reconciler will always compare the number of +Pods in the system against what is specified in the object at the time it is called. + +# Source + +resource.Source is an argument to Controller.Watch that provides a stream of events. +Events typically come from watching Kubernetes APIs (e.g. Pod Create, Update, Delete). + +Example: source.Kind uses the Kubernetes API Watch endpoint for a GroupVersionKind to provide +Create, Update, Delete events. + +* Source provides a stream of events (e.g. object Create, Update, Delete) for Kubernetes objects typically +through the Watch API. + +* Users SHOULD only use the provided Source implementations instead of implementing their own for nearly all cases. + +# EventHandler + +handler.EventHandler is an argument to Controller.Watch that enqueues reconcile.Requests in response to events. + +Example: a Pod Create event from a Source is provided to the eventhandler.EnqueueHandler, which enqueues a +reconcile.Request containing the name / Namespace of the Pod. + +* EventHandlers handle events by enqueueing reconcile.Requests for one or more objects. + +* EventHandlers MAY map an event for an object to a reconcile.Request for an object of the same type. + +* EventHandlers MAY map an event for an object to a reconcile.Request for an object of a different type - e.g. +map a Pod event to a reconcile.Request for the owning ReplicaSet. + +* EventHandlers MAY map an event for an object to multiple reconcile.Requests for objects of the same or a different +type - e.g. map a Node event to objects that respond to cluster resize events. + +* Users SHOULD only use the provided EventHandler implementations instead of implementing their own for almost +all cases. + +# Predicate + +predicate.Predicate is an optional argument to Controller.Watch that filters events. This allows common filters to be +reused and composed. + +* Predicate takes an event and returns a bool (true to enqueue) + +* Predicates are optional arguments + +* Users SHOULD use the provided Predicate implementations, but MAY implement additional +Predicates e.g. generation changed, label selectors changed etc. + +# PodController Diagram + +Source provides event: + +* &source.KindSource{&v1.Pod{}} -> (Pod foo/bar Create Event) + +EventHandler enqueues Request: + +* &handler.EnqueueRequestForObject{} -> (reconcile.Request{types.NamespaceName{Name: "foo", Namespace: "bar"}}) + +Reconciler is called with the Request: + +* Reconciler(reconcile.Request{types.NamespaceName{Name: "foo", Namespace: "bar"}}) + +# Usage + +The following example shows creating a new Controller program which Reconciles ReplicaSet objects in response +to Pod or ReplicaSet events. The Reconciler function simply adds a label to the ReplicaSet. + +See the examples/builtins/main.go for a usage example. + +Controller Example: + +1. Watch ReplicaSet and Pods Sources + +1.1 ReplicaSet -> handler.EnqueueRequestForObject - enqueue a Request with the ReplicaSet Namespace and Name. + +1.2 Pod (created by ReplicaSet) -> handler.EnqueueRequestForOwnerHandler - enqueue a Request with the +Owning ReplicaSet Namespace and Name. + +2. Reconcile ReplicaSet in response to an event + +2.1 ReplicaSet object created -> Read ReplicaSet, try to read Pods -> if is missing create Pods. + +2.2 Reconciler triggered by creation of Pods -> Read ReplicaSet and Pods, do nothing. + +2.3 Reconciler triggered by deletion of Pods from some other actor -> Read ReplicaSet and Pods, create replacement Pods. + +# Watching and EventHandling + +Controllers may Watch multiple Kinds of objects (e.g. Pods, ReplicaSets and Deployments), but they reconcile +only a single Type. When one Type of object must be updated in response to changes in another Type of object, +an EnqueueRequestsFromMapFunc may be used to map events from one type to another. e.g. Respond to a cluster resize +event (add / delete Node) by re-reconciling all instances of some API. + +A Deployment Controller might use an EnqueueRequestForObject and EnqueueRequestForOwner to: + +* Watch for Deployment Events - enqueue the Namespace and Name of the Deployment. + +* Watch for ReplicaSet Events - enqueue the Namespace and Name of the Deployment that created the ReplicaSet +(e.g the Owner) + +Note: reconcile.Requests are deduplicated when they are enqueued. Many Pod Events for the same ReplicaSet +may trigger only 1 reconcile invocation as each Event results in the Handler trying to enqueue +the same reconcile.Request for the ReplicaSet. + +# Controller Writing Tips + +Reconciler Runtime Complexity: + +* It is better to write Controllers to perform an O(1) reconcile N times (e.g. on N different objects) instead of +performing an O(N) reconcile 1 time (e.g. on a single object which manages N other objects). + +* Example: If you need to update all Services in response to a Node being added - reconcile Services but Watch +Nodes (transformed to Service object name / Namespaces) instead of Reconciling Nodes and updating Services + +Event Multiplexing: + +* reconcile.Requests for the same Name / Namespace are batched and deduplicated when they are enqueued. This allows +Controllers to gracefully handle a high volume of events for a single object. Multiplexing multiple event Sources to +a single object Type will batch requests across events for different object types. + +* Example: Pod events for a ReplicaSet are transformed to a ReplicaSet Name / Namespace, so the ReplicaSet +will be Reconciled only 1 time for multiple events from multiple Pods. +*/ +package pkg diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache.go deleted file mode 100644 index 57427a1ebfd..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache - -import ( - "fmt" - "time" - - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - logf "sigs.k8s.io/controller-runtime/pkg/log" -) - -var log = logf.Log.WithName("object-cache") - -var defaultResyncTime = 10 * time.Hour - -// New initializes and returns a new Cache. -func New(config *rest.Config, opts cache.Options) (cache.Cache, error) { - opts, err := defaultOpts(config, opts) - if err != nil { - return nil, err - } - selectorsByGVK, err := convertToSelectorsByGVK(opts.SelectorsByObject, opts.Scheme) - if err != nil { - return nil, err - } - im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK) - return &dynamicInformerCache{InformersMap: im}, nil -} - -// BuilderWithOptions returns a Cache constructor that will build the a cache -// honoring the options argument, this is useful to specify options like -// SelectorsByObject -// WARNING: if SelectorsByObject is specified. filtered out resources are not -// returned. -func BuilderWithOptions(options cache.Options) cache.NewCacheFunc { - return func(config *rest.Config, opts cache.Options) (cache.Cache, error) { - if opts.Scheme == nil { - opts.Scheme = options.Scheme - } - if opts.Mapper == nil { - opts.Mapper = options.Mapper - } - if opts.Resync == nil { - opts.Resync = options.Resync - } - if opts.Namespace == "" { - opts.Namespace = options.Namespace - } - opts.SelectorsByObject = options.SelectorsByObject - return New(config, opts) - } -} - -func defaultOpts(config *rest.Config, opts cache.Options) (cache.Options, error) { - // Use the default Kubernetes Scheme if unset - if opts.Scheme == nil { - opts.Scheme = scheme.Scheme - } - - // Construct a new Mapper if unset - if opts.Mapper == nil { - var err error - opts.Mapper, err = apiutil.NewDynamicRESTMapper(config) - if err != nil { - log.WithName("setup").Error(err, "Failed to get API Group-Resources") - return opts, fmt.Errorf("could not create RESTMapper from config") - } - } - - // Default the resync period to 10 hours if unset - if opts.Resync == nil { - opts.Resync = &defaultResyncTime - } - return opts, nil -} - -func convertToSelectorsByGVK(selectorsByObject cache.SelectorsByObject, scheme *runtime.Scheme) (internal.SelectorsByGVK, error) { - selectorsByGVK := internal.SelectorsByGVK{} - for object, selector := range selectorsByObject { - gvk, err := apiutil.GVKForObject(object, scheme) - if err != nil { - return nil, err - } - selectorsByGVK[gvk] = internal.Selector{ - Label: selector.Label, - Field: selector.Field, - } - } - return selectorsByGVK, nil -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_test.go deleted file mode 100644 index 607ab88e8f3..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/cache_test.go +++ /dev/null @@ -1,1317 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache_test - -import ( - "context" - "fmt" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime/schema" - kscheme "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - kcache "k8s.io/client-go/tools/cache" - - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" -) - -const testNodeOne = "test-node-1" -const testNamespaceOne = "test-namespace-1" -const testNamespaceTwo = "test-namespace-2" -const testNamespaceThree = "test-namespace-3" - -// TODO(community): Pull these helper functions into testenv. -// Restart policy is included to allow indexing on that field. -func createPodWithLabels(name, namespace string, restartPolicy corev1.RestartPolicy, labels map[string]string) client.Object { - three := int64(3) - if labels == nil { - labels = map[string]string{} - } - labels["test-label"] = name - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: labels, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{{Name: "nginx", Image: "nginx"}}, - RestartPolicy: restartPolicy, - ActiveDeadlineSeconds: &three, - }, - } - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - err = cl.Create(context.Background(), pod) - Expect(err).NotTo(HaveOccurred()) - return pod -} - -func createPod(name, namespace string, restartPolicy corev1.RestartPolicy) client.Object { - return createPodWithLabels(name, namespace, restartPolicy, nil) -} - -func deletePod(pod client.Object) { - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - err = cl.Delete(context.Background(), pod) - Expect(err).NotTo(HaveOccurred()) -} - -var _ = Describe("Informer Cache", func() { - CacheTest(dynamiccache.New) -}) -var _ = Describe("Multi-Namespace Informer Cache", func() { - CacheTest(dynamiccache.MultiNamespacedCacheBuilder([]string{testNamespaceOne, testNamespaceTwo, "default"})) -}) - -func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (cache.Cache, error)) { - Describe("Cache test", func() { - var ( - informerCache cache.Cache - informerCacheCtx context.Context - informerCacheCancel context.CancelFunc - knownPod1 client.Object - knownPod2 client.Object - knownPod3 client.Object - knownPod4 client.Object - knownPod5 client.Object - knownPod6 client.Object - ) - - BeforeEach(func() { - informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background()) - Expect(cfg).NotTo(BeNil()) - - By("creating three pods") - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - err = ensureNode(testNodeOne, cl) - Expect(err).NotTo(HaveOccurred()) - err = ensureNamespace(testNamespaceOne, cl) - Expect(err).NotTo(HaveOccurred()) - err = ensureNamespace(testNamespaceTwo, cl) - Expect(err).NotTo(HaveOccurred()) - err = ensureNamespace(testNamespaceThree, cl) - Expect(err).NotTo(HaveOccurred()) - // Includes restart policy since these objects are indexed on this field. - knownPod1 = createPod("test-pod-1", testNamespaceOne, corev1.RestartPolicyNever) - knownPod2 = createPod("test-pod-2", testNamespaceTwo, corev1.RestartPolicyAlways) - knownPod3 = createPodWithLabels("test-pod-3", testNamespaceTwo, corev1.RestartPolicyOnFailure, map[string]string{"common-label": "common"}) - knownPod4 = createPodWithLabels("test-pod-4", testNamespaceThree, corev1.RestartPolicyNever, map[string]string{"common-label": "common"}) - knownPod5 = createPod("test-pod-5", testNamespaceOne, corev1.RestartPolicyNever) - knownPod6 = createPod("test-pod-6", testNamespaceTwo, corev1.RestartPolicyAlways) - - podGVK := schema.GroupVersionKind{ - Kind: "Pod", - Version: "v1", - } - - knownPod1.GetObjectKind().SetGroupVersionKind(podGVK) - knownPod2.GetObjectKind().SetGroupVersionKind(podGVK) - knownPod3.GetObjectKind().SetGroupVersionKind(podGVK) - knownPod4.GetObjectKind().SetGroupVersionKind(podGVK) - knownPod5.GetObjectKind().SetGroupVersionKind(podGVK) - knownPod6.GetObjectKind().SetGroupVersionKind(podGVK) - - By("creating the informer cache") - informerCache, err = createCacheFunc(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - By("running the cache and waiting for it to sync") - // pass as an arg so that we don't race between close and re-assign - go func(ctx context.Context) { - defer GinkgoRecover() - Expect(informerCache.Start(ctx)).To(Succeed()) - }(informerCacheCtx) - Expect(informerCache.WaitForCacheSync(informerCacheCtx)).To(BeTrue()) - }) - - AfterEach(func() { - By("cleaning up created pods") - deletePod(knownPod1) - deletePod(knownPod2) - deletePod(knownPod3) - deletePod(knownPod4) - deletePod(knownPod5) - deletePod(knownPod6) - - informerCacheCancel() - }) - - Describe("as a Reader", func() { - Context("with structured objects", func() { - It("should be able to list objects that haven't been watched previously", func() { - By("listing all services in the cluster") - listObj := &corev1.ServiceList{} - Expect(informerCache.List(context.Background(), listObj)).To(Succeed()) - - By("verifying that the returned list contains the Kubernetes service") - // NB: kubernetes default service is automatically created in testenv. - Expect(listObj.Items).NotTo(BeEmpty()) - hasKubeService := false - for i := range listObj.Items { - svc := &listObj.Items[i] - if isKubeService(svc) { - hasKubeService = true - break - } - } - Expect(hasKubeService).To(BeTrue()) - }) - - It("should be able to get objects that haven't been watched previously", func() { - By("getting the Kubernetes service") - svc := &corev1.Service{} - svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} - Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) - - By("verifying that the returned service looks reasonable") - Expect(svc.Name).To(Equal("kubernetes")) - Expect(svc.Namespace).To(Equal("default")) - }) - - It("should support filtering by labels in a single namespace", func() { - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := corev1.PodList{} - Expect(informerCache.List(context.Background(), &out, - client.InNamespace(testNamespaceTwo), - client.MatchingLabels(map[string]string{"test-label": "test-pod-2"}))).To(Succeed()) - - By("verifying the returned pods have the correct label") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(1)) - actual := out.Items[0] - Expect(actual.Labels["test-label"]).To(Equal("test-pod-2")) - }) - - It("should support filtering by labels from multiple namespaces", func() { - By("creating another pod with the same label but different namespace") - anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) - defer deletePod(anotherPod) - - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := corev1.PodList{} - labels := map[string]string{"test-label": "test-pod-2"} - Expect(informerCache.List(context.Background(), &out, client.MatchingLabels(labels))).To(Succeed()) - - By("verifying multiple pods with the same label in different namespaces are returned") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(2)) - for _, actual := range out.Items { - Expect(actual.Labels["test-label"]).To(Equal("test-pod-2")) - } - }) - - It("should be able to list objects with GVK populated", func() { - By("listing pods") - out := &corev1.PodList{} - Expect(informerCache.List(context.Background(), out)).To(Succeed()) - - By("verifying that the returned pods have GVK populated") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(SatisfyAny(HaveLen(5), HaveLen(6))) - for _, p := range out.Items { - Expect(p.GroupVersionKind()).To(Equal(corev1.SchemeGroupVersion.WithKind("Pod"))) - } - }) - - It("should be able to list objects by namespace", func() { - By("listing pods in test-namespace-1") - listObj := &corev1.PodList{} - Expect(informerCache.List(context.Background(), listObj, - client.InNamespace(testNamespaceOne))).To(Succeed()) - - By("verifying that the returned pods are in test-namespace-1") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(2)) - for _, item := range listObj.Items { - Expect(item.Namespace).To(Equal(testNamespaceOne)) - } - }) - - It("should deep copy the object unless told otherwise", func() { - By("retrieving a specific pod from the cache") - out := &corev1.Pod{} - podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} - Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) - - By("verifying the retrieved pod is equal to a known pod") - Expect(out).To(Equal(knownPod2)) - - By("altering a field in the retrieved pod") - *out.Spec.ActiveDeadlineSeconds = 4 - - By("verifying the pods are no longer equal") - Expect(out).NotTo(Equal(knownPod2)) - }) - - It("should return an error if the object is not found", func() { - By("getting a service that does not exists") - svc := &corev1.Service{} - svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) - }) - - It("should return an error if getting object in unwatched namespace", func() { - By("getting a service that does not exists") - svc := &corev1.Service{} - svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - }) - - It("should return an error when context is cancelled", func() { - By("cancelling the context") - informerCacheCancel() - - By("listing pods in test-namespace-1 with a cancelled context") - listObj := &corev1.PodList{} - err := informerCache.List(informerCacheCtx, listObj, client.InNamespace(testNamespaceOne)) - - By("verifying that an error is returned") - Expect(err).To(HaveOccurred()) - Expect(apierrors.IsTimeout(err)).To(BeTrue()) - }) - - It("should set the Limit option and limit number of objects to Limit when List is called", func() { - opts := &client.ListOptions{Limit: int64(3)} - By("verifying that only Limit (3) number of objects are retrieved from the cache") - listObj := &corev1.PodList{} - Expect(informerCache.List(context.Background(), listObj, opts)).To(Succeed()) - Expect(listObj.Items).Should(HaveLen(3)) - }) - }) - - Context("with unstructured objects", func() { - It("should be able to list objects that haven't been watched previously", func() { - By("listing all services in the cluster") - listObj := &unstructured.UnstructuredList{} - listObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "ServiceList", - }) - err := informerCache.List(context.Background(), listObj) - Expect(err).To(Succeed()) - - By("verifying that the returned list contains the Kubernetes service") - // NB: kubernetes default service is automatically created in testenv. - Expect(listObj.Items).NotTo(BeEmpty()) - hasKubeService := false - for i := range listObj.Items { - svc := &listObj.Items[i] - if isKubeService(svc) { - hasKubeService = true - break - } - } - Expect(hasKubeService).To(BeTrue()) - }) - It("should be able to get objects that haven't been watched previously", func() { - By("getting the Kubernetes service") - svc := &unstructured.Unstructured{} - svc.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Service", - }) - svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} - Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) - - By("verifying that the returned service looks reasonable") - Expect(svc.GetName()).To(Equal("kubernetes")) - Expect(svc.GetNamespace()).To(Equal("default")) - }) - - It("should support filtering by labels in a single namespace", func() { - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := unstructured.UnstructuredList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err := informerCache.List(context.Background(), &out, - client.InNamespace(testNamespaceTwo), - client.MatchingLabels(map[string]string{"test-label": "test-pod-2"})) - Expect(err).To(Succeed()) - - By("verifying the returned pods have the correct label") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(1)) - actual := out.Items[0] - Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) - }) - - It("should support filtering by labels from multiple namespaces", func() { - By("creating another pod with the same label but different namespace") - anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) - defer deletePod(anotherPod) - - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := unstructured.UnstructuredList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - labels := map[string]string{"test-label": "test-pod-2"} - err := informerCache.List(context.Background(), &out, client.MatchingLabels(labels)) - Expect(err).To(Succeed()) - - By("verifying multiple pods with the same label in different namespaces are returned") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(2)) - for _, actual := range out.Items { - Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) - } - }) - - It("should be able to list objects by namespace", func() { - By("listing pods in test-namespace-1") - listObj := &unstructured.UnstructuredList{} - listObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err := informerCache.List(context.Background(), listObj, client.InNamespace(testNamespaceOne)) - Expect(err).To(Succeed()) - - By("verifying that the returned pods are in test-namespace-1") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(2)) - for _, item := range listObj.Items { - Expect(item.GetNamespace()).To(Equal(testNamespaceOne)) - } - }) - - It("should be able to restrict cache to a namespace", func() { - By("creating a namespaced cache") - namespacedCache, err := dynamiccache.New(cfg, cache.Options{Namespace: testNamespaceOne}) - Expect(err).NotTo(HaveOccurred()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(namespacedCache.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(namespacedCache.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("listing pods in all namespaces") - out := &unstructured.UnstructuredList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - Expect(namespacedCache.List(context.Background(), out)).To(Succeed()) - - By("verifying the returned pod is from the watched namespace") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(2)) - for _, item := range out.Items { - Expect(item.GetNamespace()).To(Equal(testNamespaceOne)) - } - By("listing all nodes - should still be able to list a cluster-scoped resource") - nodeList := &unstructured.UnstructuredList{} - nodeList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "NodeList", - }) - Expect(namespacedCache.List(context.Background(), nodeList)).To(Succeed()) - - By("verifying the node list is not empty") - Expect(nodeList.Items).NotTo(BeEmpty()) - - By("getting a node - should still be able to get a cluster-scoped resource") - node := &unstructured.Unstructured{} - node.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Node", - }) - - By("verifying that getting the node works with an empty namespace") - key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} - Expect(namespacedCache.Get(context.Background(), key1, node)).To(Succeed()) - - By("verifying that the namespace is ignored when getting a cluster-scoped resource") - key2 := client.ObjectKey{Namespace: "random", Name: testNodeOne} - Expect(namespacedCache.Get(context.Background(), key2, node)).To(Succeed()) - }) - - It("should deep copy the object unless told otherwise", func() { - By("retrieving a specific pod from the cache") - out := &unstructured.Unstructured{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - uKnownPod2 := &unstructured.Unstructured{} - Expect(kscheme.Scheme.Convert(knownPod2, uKnownPod2, nil)).To(Succeed()) - - podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} - Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) - - By("verifying the retrieved pod is equal to a known pod") - Expect(out).To(Equal(uKnownPod2)) - - By("altering a field in the retrieved pod") - m, _ := out.Object["spec"].(map[string]interface{}) - m["activeDeadlineSeconds"] = 4 - - By("verifying the pods are no longer equal") - Expect(out).NotTo(Equal(knownPod2)) - }) - - It("should return an error if the object is not found", func() { - By("getting a service that does not exists") - svc := &unstructured.Unstructured{} - svc.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Service", - }) - svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) - }) - It("should return an error if getting object in unwatched namespace", func() { - By("getting a service that does not exists") - svc := &corev1.Service{} - svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - }) - It("test multinamespaced cache for cluster scoped resources", func() { - By("creating a multinamespaced cache to watch specific namespaces") - multi := cache.MultiNamespacedCacheBuilder([]string{"default", testNamespaceOne}) - m, err := multi(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - By("running the cache and waiting it for sync") - go func() { - defer GinkgoRecover() - Expect(m.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(m.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("should be able to fetch cluster scoped resource") - node := &corev1.Node{} - - By("verifying that getting the node works with an empty namespace") - key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} - Expect(m.Get(context.Background(), key1, node)).To(Succeed()) - - By("verifying if the cluster scoped resources are not duplicated") - nodeList := &unstructured.UnstructuredList{} - nodeList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "NodeList", - }) - Expect(m.List(context.Background(), nodeList)).To(Succeed()) - - By("verifying the node list is not empty") - Expect(nodeList.Items).NotTo(BeEmpty()) - Expect(len(nodeList.Items)).To(BeEquivalentTo(1)) - }) - }) - Context("with metadata-only objects", func() { - It("should be able to list objects that haven't been watched previously", func() { - By("listing all services in the cluster") - listObj := &metav1.PartialObjectMetadataList{} - listObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "ServiceList", - }) - err := informerCache.List(context.Background(), listObj) - Expect(err).To(Succeed()) - - By("verifying that the returned list contains the Kubernetes service") - // NB: kubernetes default service is automatically created in testenv. - Expect(listObj.Items).NotTo(BeEmpty()) - hasKubeService := false - for i := range listObj.Items { - svc := &listObj.Items[i] - if isKubeService(svc) { - hasKubeService = true - break - } - } - Expect(hasKubeService).To(BeTrue()) - }) - It("should be able to get objects that haven't been watched previously", func() { - By("getting the Kubernetes service") - svc := &metav1.PartialObjectMetadata{} - svc.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Service", - }) - svcKey := client.ObjectKey{Namespace: "default", Name: "kubernetes"} - Expect(informerCache.Get(context.Background(), svcKey, svc)).To(Succeed()) - - By("verifying that the returned service looks reasonable") - Expect(svc.GetName()).To(Equal("kubernetes")) - Expect(svc.GetNamespace()).To(Equal("default")) - }) - - It("should support filtering by labels in a single namespace", func() { - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := metav1.PartialObjectMetadataList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err := informerCache.List(context.Background(), &out, - client.InNamespace(testNamespaceTwo), - client.MatchingLabels(map[string]string{"test-label": "test-pod-2"})) - Expect(err).To(Succeed()) - - By("verifying the returned pods have the correct label") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(1)) - actual := out.Items[0] - Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) - }) - - It("should support filtering by labels from multiple namespaces", func() { - By("creating another pod with the same label but different namespace") - anotherPod := createPod("test-pod-2", testNamespaceOne, corev1.RestartPolicyAlways) - defer deletePod(anotherPod) - - By("listing pods with a particular label") - // NB: each pod has a "test-label": - out := metav1.PartialObjectMetadataList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - labels := map[string]string{"test-label": "test-pod-2"} - err := informerCache.List(context.Background(), &out, client.MatchingLabels(labels)) - Expect(err).To(Succeed()) - - By("verifying multiple pods with the same label in different namespaces are returned") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(2)) - for _, actual := range out.Items { - Expect(actual.GetLabels()["test-label"]).To(Equal("test-pod-2")) - } - }) - - It("should be able to list objects by namespace", func() { - By("listing pods in test-namespace-1") - listObj := &metav1.PartialObjectMetadataList{} - listObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err := informerCache.List(context.Background(), listObj, client.InNamespace(testNamespaceOne)) - Expect(err).To(Succeed()) - - By("verifying that the returned pods are in test-namespace-1") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(2)) - for _, item := range listObj.Items { - Expect(item.Namespace).To(Equal(testNamespaceOne)) - } - }) - - It("should be able to restrict cache to a namespace", func() { - By("creating a namespaced cache") - namespacedCache, err := dynamiccache.New(cfg, cache.Options{Namespace: testNamespaceOne}) - Expect(err).NotTo(HaveOccurred()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(namespacedCache.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(namespacedCache.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("listing pods in all namespaces") - out := &metav1.PartialObjectMetadataList{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - Expect(namespacedCache.List(context.Background(), out)).To(Succeed()) - - By("verifying the returned pod is from the watched namespace") - Expect(out.Items).NotTo(BeEmpty()) - Expect(out.Items).Should(HaveLen(2)) - for _, item := range out.Items { - Expect(item.Namespace).To(Equal(testNamespaceOne)) - } - By("listing all nodes - should still be able to list a cluster-scoped resource") - nodeList := &metav1.PartialObjectMetadataList{} - nodeList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "NodeList", - }) - Expect(namespacedCache.List(context.Background(), nodeList)).To(Succeed()) - - By("verifying the node list is not empty") - Expect(nodeList.Items).NotTo(BeEmpty()) - - By("getting a node - should still be able to get a cluster-scoped resource") - node := &metav1.PartialObjectMetadata{} - node.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Node", - }) - - By("verifying that getting the node works with an empty namespace") - key1 := client.ObjectKey{Namespace: "", Name: testNodeOne} - Expect(namespacedCache.Get(context.Background(), key1, node)).To(Succeed()) - - By("verifying that the namespace is ignored when getting a cluster-scoped resource") - key2 := client.ObjectKey{Namespace: "random", Name: testNodeOne} - Expect(namespacedCache.Get(context.Background(), key2, node)).To(Succeed()) - }) - - It("should deep copy the object unless told otherwise", func() { - By("retrieving a specific pod from the cache") - out := &metav1.PartialObjectMetadata{} - out.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - uKnownPod2 := &metav1.PartialObjectMetadata{} - knownPod2.(*corev1.Pod).ObjectMeta.DeepCopyInto(&uKnownPod2.ObjectMeta) - uKnownPod2.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - - podKey := client.ObjectKey{Name: "test-pod-2", Namespace: testNamespaceTwo} - Expect(informerCache.Get(context.Background(), podKey, out)).To(Succeed()) - - By("verifying the retrieved pod is equal to a known pod") - Expect(out).To(Equal(uKnownPod2)) - - By("altering a field in the retrieved pod") - out.Labels["foo"] = "bar" - - By("verifying the pods are no longer equal") - Expect(out).NotTo(Equal(knownPod2)) - }) - - It("should return an error if the object is not found", func() { - By("getting a service that does not exists") - svc := &metav1.PartialObjectMetadata{} - svc.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Service", - }) - svcKey := client.ObjectKey{Namespace: testNamespaceOne, Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - Expect(apierrors.IsNotFound(err)).To(BeTrue()) - }) - It("should return an error if getting object in unwatched namespace", func() { - By("getting a service that does not exists") - svc := &corev1.Service{} - svcKey := client.ObjectKey{Namespace: "unknown", Name: "unknown"} - - By("verifying that an error is returned") - err := informerCache.Get(context.Background(), svcKey, svc) - Expect(err).To(HaveOccurred()) - }) - }) - type selectorsTestCase struct { - fieldSelectors map[string]string - labelSelectors map[string]string - expectedPods []string - } - DescribeTable(" and cache with selectors", func(tc selectorsTestCase) { - By("creating the cache") - builder := cache.BuilderWithOptions( - cache.Options{ - SelectorsByObject: cache.SelectorsByObject{ - &corev1.Pod{}: { - Label: labels.Set(tc.labelSelectors).AsSelector(), - Field: fields.Set(tc.fieldSelectors).AsSelector(), - }, - }, - }, - ) - informer, err := builder(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(informer.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("Checking with structured") - obtainedStructuredPodList := corev1.PodList{} - Expect(informer.List(context.Background(), &obtainedStructuredPodList)).To(Succeed()) - Expect(obtainedStructuredPodList.Items).Should(WithTransform(func(pods []corev1.Pod) []string { - obtainedPodNames := []string{} - for _, pod := range pods { - obtainedPodNames = append(obtainedPodNames, pod.Name) - } - return obtainedPodNames - }, ConsistOf(tc.expectedPods))) - - By("Checking with unstructured") - obtainedUnstructuredPodList := unstructured.UnstructuredList{} - obtainedUnstructuredPodList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err = informer.List(context.Background(), &obtainedUnstructuredPodList) - Expect(err).To(Succeed()) - Expect(obtainedUnstructuredPodList.Items).Should(WithTransform(func(pods []unstructured.Unstructured) []string { - obtainedPodNames := []string{} - for _, pod := range pods { - obtainedPodNames = append(obtainedPodNames, pod.GetName()) - } - return obtainedPodNames - }, ConsistOf(tc.expectedPods))) - - By("Checking with metadata") - obtainedMetadataPodList := metav1.PartialObjectMetadataList{} - obtainedMetadataPodList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err = informer.List(context.Background(), &obtainedMetadataPodList) - Expect(err).To(Succeed()) - Expect(obtainedMetadataPodList.Items).Should(WithTransform(func(pods []metav1.PartialObjectMetadata) []string { - obtainedPodNames := []string{} - for _, pod := range pods { - obtainedPodNames = append(obtainedPodNames, pod.Name) - } - return obtainedPodNames - }, ConsistOf(tc.expectedPods))) - }, - Entry("when selectors are empty it has to inform about all the pods", selectorsTestCase{ - fieldSelectors: map[string]string{}, - labelSelectors: map[string]string{}, - expectedPods: []string{"test-pod-1", "test-pod-2", "test-pod-3", "test-pod-4", "test-pod-5", "test-pod-6"}, - }), - Entry("when field matches one pod it has to inform about it", selectorsTestCase{ - fieldSelectors: map[string]string{"metadata.name": "test-pod-2"}, - expectedPods: []string{"test-pod-2"}, - }), - Entry("when field matches multiple pods it has to inform about all of them", selectorsTestCase{ - fieldSelectors: map[string]string{"metadata.namespace": testNamespaceTwo}, - expectedPods: []string{"test-pod-2", "test-pod-3", "test-pod-6"}, - }), - Entry("when label matches one pod it has to inform about it", selectorsTestCase{ - labelSelectors: map[string]string{"test-label": "test-pod-4"}, - expectedPods: []string{"test-pod-4"}, - }), - Entry("when label matches multiple pods it has to inform about all of them", selectorsTestCase{ - labelSelectors: map[string]string{"common-label": "common"}, - expectedPods: []string{"test-pod-3", "test-pod-4"}, - }), - Entry("when label and field matches one pod it has to inform about about it", selectorsTestCase{ - labelSelectors: map[string]string{"common-label": "common"}, - fieldSelectors: map[string]string{"metadata.namespace": testNamespaceTwo}, - expectedPods: []string{"test-pod-3"}, - }), - Entry("when label does not match it does not has to inform", selectorsTestCase{ - labelSelectors: map[string]string{"new-label": "new"}, - expectedPods: []string{}, - }), - Entry("when field does not match it does not has to inform", selectorsTestCase{ - fieldSelectors: map[string]string{"metadata.namespace": "new"}, - expectedPods: []string{}, - }), - ) - }) - Describe("as an Informer", func() { - Context("with structured objects", func() { - It("should be able to get informer for the object", func() { - By("getting a shared index informer for a pod") - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "informer-obj", - Namespace: "default", - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - } - sii, err := informerCache.GetInformer(context.TODO(), pod) - Expect(err).NotTo(HaveOccurred()) - Expect(sii).NotTo(BeNil()) - Expect(sii.HasSynced()).To(BeTrue()) - - By("adding an event handler listening for object creation which sends the object to a channel") - out := make(chan interface{}) - addFunc := func(obj interface{}) { - out <- obj - } - sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) - - By("adding an object") - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - Expect(cl.Create(context.Background(), pod)).To(Succeed()) - defer deletePod(pod) - - By("verifying the object is received on the channel") - Eventually(out).Should(Receive(Equal(pod))) - }) - It("should be able to get an informer by group/version/kind", func() { - By("getting an shared index informer for gvk = core/v1/pod") - gvk := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} - sii, err := informerCache.GetInformerForKind(context.TODO(), gvk) - Expect(err).NotTo(HaveOccurred()) - Expect(sii).NotTo(BeNil()) - Expect(sii.HasSynced()).To(BeTrue()) - - By("adding an event handler listening for object creation which sends the object to a channel") - out := make(chan interface{}) - addFunc := func(obj interface{}) { - out <- obj - } - sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) - - By("adding an object") - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "informer-gvk", - Namespace: "default", - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - } - Expect(cl.Create(context.Background(), pod)).To(Succeed()) - defer deletePod(pod) - - By("verifying the object is received on the channel") - Eventually(out).Should(Receive(Equal(pod))) - }) - It("should be able to index an object field then retrieve objects by that field", func() { - By("creating the cache") - informer, err := dynamiccache.New(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - By("indexing the restartPolicy field of the Pod object before starting") - pod := &corev1.Pod{} - indexFunc := func(obj client.Object) []string { - return []string{string(obj.(*corev1.Pod).Spec.RestartPolicy)} - } - Expect(informer.IndexField(context.TODO(), pod, "spec.restartPolicy", indexFunc)).To(Succeed()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(informer.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("listing Pods with restartPolicyOnFailure") - listObj := &corev1.PodList{} - Expect(informer.List(context.Background(), listObj, - client.MatchingFields{"spec.restartPolicy": "OnFailure"})).To(Succeed()) - By("verifying that the returned pods have correct restart policy") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(1)) - actual := listObj.Items[0] - Expect(actual.Name).To(Equal("test-pod-3")) - }) - - It("should allow for get informer to be cancelled", func() { - By("creating a context and cancelling it") - informerCacheCancel() - - By("getting a shared index informer for a pod with a cancelled context") - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "informer-obj", - Namespace: "default", - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - } - sii, err := informerCache.GetInformer(informerCacheCtx, pod) - Expect(err).To(HaveOccurred()) - Expect(sii).To(BeNil()) - Expect(apierrors.IsTimeout(err)).To(BeTrue()) - }) - - It("should allow getting an informer by group/version/kind to be cancelled", func() { - By("creating a context and cancelling it") - informerCacheCancel() - - By("getting an shared index informer for gvk = core/v1/pod with a cancelled context") - gvk := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} - sii, err := informerCache.GetInformerForKind(informerCacheCtx, gvk) - Expect(err).To(HaveOccurred()) - Expect(sii).To(BeNil()) - Expect(apierrors.IsTimeout(err)).To(BeTrue()) - }) - }) - Context("with unstructured objects", func() { - It("should be able to get informer for the object", func() { - By("getting a shared index informer for a pod") - - pod := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []map[string]interface{}{ - { - "name": "nginx", - "image": "nginx", - }, - }, - }, - }, - } - pod.SetName("informer-obj2") - pod.SetNamespace("default") - pod.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - sii, err := informerCache.GetInformer(context.TODO(), pod) - Expect(err).NotTo(HaveOccurred()) - Expect(sii).NotTo(BeNil()) - Expect(sii.HasSynced()).To(BeTrue()) - - By("adding an event handler listening for object creation which sends the object to a channel") - out := make(chan interface{}) - addFunc := func(obj interface{}) { - out <- obj - } - sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) - - By("adding an object") - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - Expect(cl.Create(context.Background(), pod)).To(Succeed()) - defer deletePod(pod) - - By("verifying the object is received on the channel") - Eventually(out).Should(Receive(Equal(pod))) - }, 3) - - It("should be able to index an object field then retrieve objects by that field", func() { - By("creating the cache") - informer, err := dynamiccache.New(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - By("indexing the restartPolicy field of the Pod object before starting") - pod := &unstructured.Unstructured{} - pod.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - indexFunc := func(obj client.Object) []string { - s, ok := obj.(*unstructured.Unstructured).Object["spec"] - if !ok { - return []string{} - } - m, ok := s.(map[string]interface{}) - if !ok { - return []string{} - } - return []string{fmt.Sprintf("%v", m["restartPolicy"])} - } - Expect(informer.IndexField(context.TODO(), pod, "spec.restartPolicy", indexFunc)).To(Succeed()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(informer.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("listing Pods with restartPolicyOnFailure") - listObj := &unstructured.UnstructuredList{} - listObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - }) - err = informer.List(context.Background(), listObj, - client.MatchingFields{"spec.restartPolicy": "OnFailure"}) - Expect(err).To(Succeed()) - - By("verifying that the returned pods have correct restart policy") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(1)) - actual := listObj.Items[0] - Expect(actual.GetName()).To(Equal("test-pod-3")) - }, 3) - - It("should allow for get informer to be cancelled", func() { - By("cancelling the context") - informerCacheCancel() - - By("getting a shared index informer for a pod with a cancelled context") - pod := &unstructured.Unstructured{} - pod.SetName("informer-obj2") - pod.SetNamespace("default") - pod.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - sii, err := informerCache.GetInformer(informerCacheCtx, pod) - Expect(err).To(HaveOccurred()) - Expect(sii).To(BeNil()) - Expect(apierrors.IsTimeout(err)).To(BeTrue()) - }) - }) - Context("with metadata-only objects", func() { - It("should be able to get informer for the object", func() { - By("getting a shared index informer for a pod") - - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "informer-obj", - Namespace: "default", - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - } - - podMeta := &metav1.PartialObjectMetadata{} - pod.ObjectMeta.DeepCopyInto(&podMeta.ObjectMeta) - podMeta.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - - sii, err := informerCache.GetInformer(context.TODO(), podMeta) - Expect(err).NotTo(HaveOccurred()) - Expect(sii).NotTo(BeNil()) - Expect(sii.HasSynced()).To(BeTrue()) - - By("adding an event handler listening for object creation which sends the object to a channel") - out := make(chan interface{}) - addFunc := func(obj interface{}) { - out <- obj - } - sii.AddEventHandler(kcache.ResourceEventHandlerFuncs{AddFunc: addFunc}) - - By("adding an object") - cl, err := client.New(cfg, client.Options{}) - Expect(err).NotTo(HaveOccurred()) - Expect(cl.Create(context.Background(), pod)).To(Succeed()) - defer deletePod(pod) - // re-copy the result in so that we can match on it properly - pod.ObjectMeta.DeepCopyInto(&podMeta.ObjectMeta) - - By("verifying the object's metadata is received on the channel") - Eventually(out).Should(Receive(Equal(podMeta))) - }, 3) - - It("should be able to index an object field then retrieve objects by that field", func() { - By("creating the cache") - informer, err := dynamiccache.New(cfg, cache.Options{}) - Expect(err).NotTo(HaveOccurred()) - - By("indexing the restartPolicy field of the Pod object before starting") - pod := &metav1.PartialObjectMetadata{} - pod.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - indexFunc := func(obj client.Object) []string { - metadata := obj.(*metav1.PartialObjectMetadata) - return []string{metadata.Labels["test-label"]} - } - Expect(informer.IndexField(context.TODO(), pod, "metadata.labels.test-label", indexFunc)).To(Succeed()) - - By("running the cache and waiting for it to sync") - go func() { - defer GinkgoRecover() - Expect(informer.Start(informerCacheCtx)).To(Succeed()) - }() - Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) - - By("listing Pods with restartPolicyOnFailure") - listObj := &metav1.PartialObjectMetadataList{} - gvk := schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "PodList", - } - listObj.SetGroupVersionKind(gvk) - err = informer.List(context.Background(), listObj, - client.MatchingFields{"metadata.labels.test-label": "test-pod-3"}) - Expect(err).To(Succeed()) - - By("verifying that the GVK has been preserved for the list object") - Expect(listObj.GroupVersionKind()).To(Equal(gvk)) - - By("verifying that the returned pods have correct restart policy") - Expect(listObj.Items).NotTo(BeEmpty()) - Expect(listObj.Items).Should(HaveLen(1)) - actual := listObj.Items[0] - Expect(actual.GetName()).To(Equal("test-pod-3")) - - By("verifying that the GVK has been preserved for the item in the list") - Expect(actual.GroupVersionKind()).To(Equal(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - })) - }, 3) - - It("should allow for get informer to be cancelled", func() { - By("creating a context and cancelling it") - ctx, cancel := context.WithCancel(context.Background()) - cancel() - - By("getting a shared index informer for a pod with a cancelled context") - pod := &metav1.PartialObjectMetadata{} - pod.SetName("informer-obj2") - pod.SetNamespace("default") - pod.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "", - Version: "v1", - Kind: "Pod", - }) - sii, err := informerCache.GetInformer(ctx, pod) - Expect(err).To(HaveOccurred()) - Expect(sii).To(BeNil()) - Expect(apierrors.IsTimeout(err)).To(BeTrue()) - }) - }) - }) - }) -} - -// ensureNamespace installs namespace of a given name if not exists. -func ensureNamespace(namespace string, client client.Client) error { - ns := corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - TypeMeta: metav1.TypeMeta{ - Kind: "Namespace", - APIVersion: "v1", - }, - } - err := client.Create(context.TODO(), &ns) - if apierrors.IsAlreadyExists(err) { - return nil - } - return err -} - -func ensureNode(name string, client client.Client) error { - node := corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - } - err := client.Create(context.TODO(), &node) - if apierrors.IsAlreadyExists(err) { - return nil - } - return err -} - -//nolint:interfacer -func isKubeService(svc metav1.Object) bool { - // grumble grumble linters grumble grumble - return svc.GetNamespace() == "default" && svc.GetName() == "kubernetes" -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/doc.go deleted file mode 100644 index 89413c04cd8..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -// Package cache provides object caches that act as caching client.Reader -// instances and help drive Kubernetes-object-based event handlers. -// The code is forked from controller-runtime's cache package and has been -// modified to support dynamic addition and removal of informers. -package dynamiccache diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache.go deleted file mode 100644 index 2360cfbdbcd..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache.go +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal" - apierrors "k8s.io/apimachinery/pkg/api/errors" - apimeta "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - toolscache "k8s.io/client-go/tools/cache" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -var ( - _ cache.Informers = &dynamicInformerCache{} - _ client.Reader = &dynamicInformerCache{} - _ cache.Cache = &dynamicInformerCache{} -) - -// ErrCacheNotStarted is returned when trying to read from the cache that wasn't started. -type ErrCacheNotStarted struct{} - -func (*ErrCacheNotStarted) Error() string { - return "the cache is not started, can not read objects" -} - -// dynamicInformerCache is a Kubernetes Object cache populated from InformersMap. dynamicInformerCache wraps an InformersMap. -type dynamicInformerCache struct { - *internal.InformersMap -} - -// Get implements Reader. -func (ip *dynamicInformerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object) error { - gvk, err := apiutil.GVKForObject(out, ip.Scheme) - if err != nil { - return err - } - - started, cache, err := ip.InformersMap.Get(ctx, gvk, out) - if err != nil { - return err - } - - if !started { - return &ErrCacheNotStarted{} - } - return cache.Reader.Get(ctx, key, out) -} - -// List implements Reader. -func (ip *dynamicInformerCache) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error { - gvk, cacheTypeObj, err := ip.objectTypeForListObject(out) - if err != nil { - return err - } - - started, cache, err := ip.InformersMap.Get(ctx, *gvk, cacheTypeObj) - if err != nil { - return err - } - - if !started { - return &ErrCacheNotStarted{} - } - - return cache.Reader.List(ctx, out, opts...) -} - -// objectTypeForListObject tries to find the runtime.Object and associated GVK -// for a single object corresponding to the passed-in list type. We need them -// because they are used as cache map key. -func (ip *dynamicInformerCache) objectTypeForListObject(list client.ObjectList) (*schema.GroupVersionKind, runtime.Object, error) { - gvk, err := apiutil.GVKForObject(list, ip.Scheme) - if err != nil { - return nil, nil, err - } - - if !strings.HasSuffix(gvk.Kind, "List") { - return nil, nil, fmt.Errorf("non-list type %T (kind %q) passed as output", list, gvk) - } - // we need the non-list GVK, so chop off the "List" from the end of the kind - gvk.Kind = gvk.Kind[:len(gvk.Kind)-4] - _, isUnstructured := list.(*unstructured.UnstructuredList) - var cacheTypeObj runtime.Object - if isUnstructured { - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(gvk) - cacheTypeObj = u - } else { - itemsPtr, err := apimeta.GetItemsPtr(list) - if err != nil { - return nil, nil, err - } - // http://knowyourmeme.com/memes/this-is-fine - elemType := reflect.Indirect(reflect.ValueOf(itemsPtr)).Type().Elem() - if elemType.Kind() != reflect.Ptr { - elemType = reflect.PtrTo(elemType) - } - - cacheTypeValue := reflect.Zero(elemType) - var ok bool - cacheTypeObj, ok = cacheTypeValue.Interface().(runtime.Object) - if !ok { - return nil, nil, fmt.Errorf("cannot get cache for %T, its element %T is not a runtime.Object", list, cacheTypeValue.Interface()) - } - } - - return &gvk, cacheTypeObj, nil -} - -// GetInformerForKind returns the informer for the GroupVersionKind. -func (ip *dynamicInformerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (cache.Informer, error) { - // Map the gvk to an object - obj, err := ip.Scheme.New(gvk) - if err != nil { - return nil, err - } - - _, i, err := ip.InformersMap.Get(ctx, gvk, obj) - if err != nil { - return nil, err - } - return i.Informer, err -} - -// GetInformer returns the informer for the obj. -func (ip *dynamicInformerCache) GetInformer(ctx context.Context, obj client.Object) (cache.Informer, error) { - gvk, err := apiutil.GVKForObject(obj, ip.Scheme) - if err != nil { - return nil, err - } - - _, i, err := ip.InformersMap.Get(ctx, gvk, obj) - if err != nil { - return nil, err - } - return i.Informer, err -} - -// GetInformerNonBlocking returns the informer for the obj without waiting for its cache to sync. -func (ip *dynamicInformerCache) GetInformerNonBlocking(obj client.Object) (cache.Informer, error) { - gvk, err := apiutil.GVKForObject(obj, ip.Scheme) - if err != nil { - return nil, err - } - - // Use a canceled context to signal non-blocking - ctx, cancel := context.WithCancel(context.Background()) - cancel() - - _, i, err := ip.InformersMap.Get(ctx, gvk, obj) - if err != nil && !apierrors.IsTimeout(err) { - return nil, err - } - return i.Informer, nil -} - -// NeedLeaderElection implements the LeaderElectionRunnable interface -// to indicate that this can be started without requiring the leader lock. -func (ip *dynamicInformerCache) NeedLeaderElection() bool { - return false -} - -// IndexField adds an indexer to the underlying cache, using extraction function to get -// value(s) from the given field. This index can then be used by passing a field selector -// to List. For one-to-one compatibility with "normal" field selectors, only return one value. -// The values may be anything. They will automatically be prefixed with the namespace of the -// given object, if present. The objects passed are guaranteed to be objects of the correct type. -func (ip *dynamicInformerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { - informer, err := ip.GetInformer(ctx, obj) - if err != nil { - return err - } - return indexByField(informer, field, extractValue) -} - -func indexByField(indexer cache.Informer, field string, extractor client.IndexerFunc) error { - indexFunc := func(objRaw interface{}) ([]string, error) { - // TODO(directxman12): check if this is the correct type? - obj, isObj := objRaw.(client.Object) - if !isObj { - return nil, fmt.Errorf("object of type %T is not an Object", objRaw) - } - meta, err := apimeta.Accessor(obj) - if err != nil { - return nil, err - } - ns := meta.GetNamespace() - - rawVals := extractor(obj) - var vals []string - if ns == "" { - // if we're not doubling the keys for the namespaced case, just re-use what was returned to us - vals = rawVals - } else { - // if we need to add non-namespaced versions too, double the length - vals = make([]string, len(rawVals)*2) - } - for i, rawVal := range rawVals { - // save a namespaced variant, so that we can ask - // "what are all the object matching a given index *in a given namespace*" - vals[i] = internal.KeyToNamespacedKey(ns, rawVal) - if ns != "" { - // if we have a namespace, also inject a special index key for listing - // regardless of the object namespace - vals[i+len(rawVals)] = internal.KeyToNamespacedKey("", rawVal) - } - } - - return vals, nil - } - - return indexer.AddIndexers(toolscache.Indexers{internal.FieldIndexName(field): indexFunc}) -} - -// Remove removes an informer specified by the obj argument from the cache and stops it if it existed. -func (ip *dynamicInformerCache) Remove(obj client.Object) error { - gvk, err := apiutil.GVKForObject(obj, ip.Scheme) - if err != nil { - return err - } - - ip.InformersMap.Remove(gvk, obj) - return nil -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_test.go deleted file mode 100644 index d9d2de872e8..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/informer_cache_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "k8s.io/client-go/rest" - - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -var _ = Describe("dynamicInformerCache", func() { - It("should not require LeaderElection", func() { - cfg := &rest.Config{} - - mapper, err := apiutil.NewDynamicRESTMapper(cfg, apiutil.WithLazyDiscovery) - Expect(err).ToNot(HaveOccurred()) - - c, err := dynamiccache.New(cfg, cache.Options{Mapper: mapper}) - Expect(err).ToNot(HaveOccurred()) - - leaderElectionRunnable, ok := c.(manager.LeaderElectionRunnable) - Expect(ok).To(BeTrue()) - Expect(leaderElectionRunnable.NeedLeaderElection()).To(BeFalse()) - }) -}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/deleg_map.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/deleg_map.go deleted file mode 100644 index 1f1a01f0596..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/deleg_map.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package internal - -import ( - "context" - "time" - - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" -) - -// InformersMap create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. -// It uses a standard parameter codec constructed based on the given generated Scheme. -type InformersMap struct { - // we abstract over the details of structured/unstructured/metadata with the specificInformerMaps - // TODO(directxman12): genericize this over different projections now that we have 3 different maps - - structured *specificInformersMap - unstructured *specificInformersMap - metadata *specificInformersMap - - // Scheme maps runtime.Objects to GroupVersionKinds - Scheme *runtime.Scheme -} - -// NewInformersMap creates a new InformersMap that can create informers for -// both structured and unstructured objects. -func NewInformersMap(config *rest.Config, - scheme *runtime.Scheme, - mapper meta.RESTMapper, - resync time.Duration, - namespace string, - selectors SelectorsByGVK, -) *InformersMap { - return &InformersMap{ - structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors), - unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors), - metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors), - - Scheme: scheme, - } -} - -// Start calls Run on each of the informers and sets started to true. Blocks on the context. -func (m *InformersMap) Start(ctx context.Context) error { - go m.structured.Start(ctx) - go m.unstructured.Start(ctx) - go m.metadata.Start(ctx) - <-ctx.Done() - return nil -} - -// WaitForCacheSync waits until all the caches have been started and synced. -func (m *InformersMap) WaitForCacheSync(ctx context.Context) bool { - syncedFuncs := append([]cache.InformerSynced(nil), m.structured.HasSyncedFuncs()...) - syncedFuncs = append(syncedFuncs, m.unstructured.HasSyncedFuncs()...) - syncedFuncs = append(syncedFuncs, m.metadata.HasSyncedFuncs()...) - - if !m.structured.waitForStarted(ctx) { - return false - } - if !m.unstructured.waitForStarted(ctx) { - return false - } - if !m.metadata.waitForStarted(ctx) { - return false - } - return cache.WaitForCacheSync(ctx.Done(), syncedFuncs...) -} - -// Get will create a new Informer and add it to the map of InformersMap if none exists. Returns -// the Informer from the map. -func (m *InformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *MapEntry, error) { - switch obj.(type) { - case *unstructured.Unstructured: - return m.unstructured.Get(ctx, gvk, obj) - case *unstructured.UnstructuredList: - return m.unstructured.Get(ctx, gvk, obj) - case *metav1.PartialObjectMetadata: - return m.metadata.Get(ctx, gvk, obj) - case *metav1.PartialObjectMetadataList: - return m.metadata.Get(ctx, gvk, obj) - default: - return m.structured.Get(ctx, gvk, obj) - } -} - -// Remove will remove an new Informer from the InformersMap and stop it if it exists. -func (m *InformersMap) Remove(gvk schema.GroupVersionKind, obj runtime.Object) { - switch obj.(type) { - case *unstructured.Unstructured: - m.unstructured.Remove(gvk) - case *unstructured.UnstructuredList: - m.unstructured.Remove(gvk) - case *metav1.PartialObjectMetadata: - m.metadata.Remove(gvk) - case *metav1.PartialObjectMetadataList: - m.metadata.Remove(gvk) - default: - m.structured.Remove(gvk) - } -} - -// newStructuredInformersMap creates a new InformersMap for structured objects. -func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createStructuredListWatch) -} - -// newUnstructuredInformersMap creates a new InformersMap for unstructured objects. -func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createUnstructuredListWatch) -} - -// newMetadataInformersMap creates a new InformersMap for metadata-only objects. -func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, createMetadataListWatch) -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/informers_map.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/informers_map.go deleted file mode 100644 index 3a3fd53e5b8..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/informers_map.go +++ /dev/null @@ -1,472 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package internal - -import ( - "context" - "fmt" - "math/rand" - "sync" - "time" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/metadata" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -// clientListWatcherFunc knows how to create a ListWatcher. -type createListWatcherFunc func(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) - -// newSpecificInformersMap returns a new specificInformersMap (like -// the generical InformersMap, except that it doesn't implement WaitForCacheSync). -func newSpecificInformersMap(config *rest.Config, - scheme *runtime.Scheme, - mapper meta.RESTMapper, - resync time.Duration, - namespace string, - selectors SelectorsByGVK, - createListWatcher createListWatcherFunc) *specificInformersMap { - ip := &specificInformersMap{ - config: config, - Scheme: scheme, - mapper: mapper, - informersByGVK: make(map[schema.GroupVersionKind]*MapEntry), - codecs: serializer.NewCodecFactory(scheme), - paramCodec: runtime.NewParameterCodec(scheme), - resync: resync, - startWait: make(chan struct{}), - createListWatcher: createListWatcher, - namespace: namespace, - selectors: selectors, - } - return ip -} - -// MapEntry contains the cached data for an Informer. -type MapEntry struct { - // Informer is the cached informer - Informer cache.SharedIndexInformer - - // CacheReader wraps Informer and implements the CacheReader interface for a single type - Reader CacheReader - - // Stop can be used to stop this individual informer without stopping the entire specificInformersMap. - stop chan struct{} -} - -// specificInformersMap create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. -// It uses a standard parameter codec constructed based on the given generated Scheme. -type specificInformersMap struct { - // Scheme maps runtime.Objects to GroupVersionKinds - Scheme *runtime.Scheme - - // config is used to talk to the apiserver - config *rest.Config - - // mapper maps GroupVersionKinds to Resources - mapper meta.RESTMapper - - // informersByGVK is the cache of informers keyed by groupVersionKind - informersByGVK map[schema.GroupVersionKind]*MapEntry - - // codecs is used to create a new REST client - codecs serializer.CodecFactory - - // paramCodec is used by list and watch - paramCodec runtime.ParameterCodec - - // stop is the stop channel to stop informers - stop <-chan struct{} - - // resync is the base frequency the informers are resynced - // a 10 percent jitter will be added to the resync period between informers - // so that all informers will not send list requests simultaneously. - resync time.Duration - - // mu guards access to the map - mu sync.RWMutex - - // start is true if the informers have been started - started bool - - // startWait is a channel that is closed after the - // informer has been started. - startWait chan struct{} - - // createClient knows how to create a client and a list object, - // and allows for abstracting over the particulars of structured vs - // unstructured objects. - createListWatcher createListWatcherFunc - - // namespace is the namespace that all ListWatches are restricted to - // default or empty string means all namespaces - namespace string - - // selectors are the label or field selectors that will be added to the - // ListWatch ListOptions. - selectors SelectorsByGVK -} - -// Start starts the informer managed by a MapEntry. -// Blocks until the informer stops. The informer can be stopped -// either individually (via the entry's stop channel) or globally -// via the provided stop argument. -func (e *MapEntry) Start(stop <-chan struct{}) { - // Stop on either the whole map stopping or just this informer being removed. - internalStop, cancel := eitherChan(stop, e.stop) - defer cancel() - e.Informer.Run(internalStop) -} - -// Start calls Run on each of the informers and sets started to true. Blocks on the context. -// It doesn't return start because it can't return an error, and it's not a runnable directly. -func (ip *specificInformersMap) Start(ctx context.Context) { - func() { - ip.mu.Lock() - defer ip.mu.Unlock() - - // Set the stop channel so it can be passed to informers that are added later - ip.stop = ctx.Done() - - // Start each informer - for _, entry := range ip.informersByGVK { - go entry.Start(ctx.Done()) - } - - // Set started to true so we immediately start any informers added later. - ip.started = true - close(ip.startWait) - }() - <-ctx.Done() -} - -func (ip *specificInformersMap) waitForStarted(ctx context.Context) bool { - select { - case <-ip.startWait: - return true - case <-ctx.Done(): - return false - } -} - -// HasSyncedFuncs returns all the HasSynced functions for the informers in this map. -func (ip *specificInformersMap) HasSyncedFuncs() []cache.InformerSynced { - ip.mu.RLock() - defer ip.mu.RUnlock() - syncedFuncs := make([]cache.InformerSynced, 0, len(ip.informersByGVK)) - for _, informer := range ip.informersByGVK { - syncedFuncs = append(syncedFuncs, informer.Informer.HasSynced) - } - return syncedFuncs -} - -// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns -// the Informer from the map. -func (ip *specificInformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *MapEntry, error) { - // Return the informer if it is found - i, started, ok := func() (*MapEntry, bool, bool) { - ip.mu.RLock() - defer ip.mu.RUnlock() - i, ok := ip.informersByGVK[gvk] - return i, ip.started, ok - }() - - if !ok { - var err error - if i, started, err = ip.addInformerToMap(gvk, obj); err != nil { - return started, nil, err - } - } - - if started && !i.Informer.HasSynced() { - // Wait for it to sync before returning the Informer so that folks don't read from a stale cache. - // Cancel for context, informer stopping, or entire map stopping. - syncStop, cancel := mergeChan(ctx.Done(), i.stop, ip.stop) - defer cancel() - if !cache.WaitForCacheSync(syncStop, i.Informer.HasSynced) { - // Return entry even on timeout - caller may have intended a non-blocking fetch. - return started, i, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0) - } - } - - return started, i, nil -} - -func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*MapEntry, bool, error) { - ip.mu.Lock() - defer ip.mu.Unlock() - - // Check the cache to see if we already have an Informer. If we do, return the Informer. - // This is for the case where 2 routines tried to get the informer when it wasn't in the map - // so neither returned early, but the first one created it. - if i, ok := ip.informersByGVK[gvk]; ok { - return i, ip.started, nil - } - - // Create a NewSharedIndexInformer and add it to the map. - var lw *cache.ListWatch - lw, err := ip.createListWatcher(gvk, ip) - if err != nil { - return nil, false, err - } - ni := cache.NewSharedIndexInformer(lw, obj, resyncPeriod(ip.resync)(), cache.Indexers{ - cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, - }) - rm, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, false, err - } - - switch obj.(type) { - case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: - ni = metadataSharedIndexInformerPreserveGVK(gvk, ni) - default: - } - - i := &MapEntry{ - Informer: ni, - Reader: CacheReader{indexer: ni.GetIndexer(), groupVersionKind: gvk, scopeName: rm.Scope.Name()}, - stop: make(chan struct{}), - } - ip.informersByGVK[gvk] = i - - // Start the Informer if need by - // TODO(seans): write thorough tests and document what happens here - can you add indexers? - // can you add eventhandlers? - if ip.started { - go i.Start(ip.stop) - } - return i, ip.started, nil -} - -// Remove removes an informer entry and stops it if it was running. -func (ip *specificInformersMap) Remove(gvk schema.GroupVersionKind) { - ip.mu.Lock() - defer ip.mu.Unlock() - - entry, ok := ip.informersByGVK[gvk] - if !ok { - return - } - close(entry.stop) - delete(ip.informersByGVK, gvk) -} - -// newListWatch returns a new ListWatch object that can be used to create a SharedIndexInformer. -func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - client, err := apiutil.RESTClientForGVK(gvk, false, ip.config, ip.codecs) - if err != nil { - return nil, err - } - listGVK := gvk.GroupVersion().WithKind(gvk.Kind + "List") - listObj, err := ip.Scheme.New(listGVK) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - // Create a new ListWatch for the obj - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors[gvk].ApplyToList(&opts) - res := listObj.DeepCopyObject() - isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot - err := client.Get().NamespaceIfScoped(ip.namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Do(ctx).Into(res) - return res, err - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors[gvk].ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - isNamespaceScoped := ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot - return client.Get().NamespaceIfScoped(ip.namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Watch(ctx) - }, - }, nil -} - -func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - // If the rest configuration has a negotiated serializer passed in, - // we should remove it and use the one that the dynamic client sets for us. - cfg := rest.CopyConfig(ip.config) - cfg.NegotiatedSerializer = nil - dynamicClient, err := dynamic.NewForConfig(cfg) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - // Create a new ListWatch for the obj - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors[gvk].ApplyToList(&opts) - if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return dynamicClient.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts) - } - return dynamicClient.Resource(mapping.Resource).List(ctx, opts) - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors[gvk].ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return dynamicClient.Resource(mapping.Resource).Namespace(ip.namespace).Watch(ctx, opts) - } - return dynamicClient.Resource(mapping.Resource).Watch(ctx, opts) - }, - }, nil -} - -func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - // Always clear the negotiated serializer and use the one - // set from the metadata client. - cfg := rest.CopyConfig(ip.config) - cfg.NegotiatedSerializer = nil - - // grab the metadata client - client, err := metadata.NewForConfig(cfg) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - - // create the relevant listwatch - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors[gvk].ApplyToList(&opts) - if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return client.Resource(mapping.Resource).Namespace(ip.namespace).List(ctx, opts) - } - return client.Resource(mapping.Resource).List(ctx, opts) - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors[gvk].ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - if ip.namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return client.Resource(mapping.Resource).Namespace(ip.namespace).Watch(ctx, opts) - } - return client.Resource(mapping.Resource).Watch(ctx, opts) - }, - }, nil -} - -// resyncPeriod returns a function which generates a duration each time it is -// invoked; this is so that multiple controllers don't get into lock-step and all -// hammer the apiserver with list requests simultaneously. -func resyncPeriod(resync time.Duration) func() time.Duration { - return func() time.Duration { - /* #nosec */ - // using math/rand insted of crypto/rand will cause G404 issue while using gosec - // the factor will fall into [0.9, 1.1) - factor := rand.Float64()/5.0 + 0.9 //nolint:gosec - return time.Duration(float64(resync.Nanoseconds()) * factor) - } -} - -// eitherChan returns a channel that is closed when either of the input channels are signaled. -// The caller must call the returned CancelFunc to ensure no resources are leaked. -func eitherChan(a, b <-chan struct{}) (<-chan struct{}, context.CancelFunc) { - var once sync.Once - out := make(chan struct{}) - cancel := make(chan struct{}) - cancelFunc := func() { - once.Do(func() { - close(cancel) - }) - } - go func() { - defer close(out) - select { - case <-a: - case <-b: - case <-cancel: - } - }() - - return out, cancelFunc -} - -// mergeChan returns a channel that is closed when any of the input channels are signaled. -// The caller must call the returned CancelFunc to ensure no resources are leaked. -func mergeChan(a, b, c <-chan struct{}) (<-chan struct{}, context.CancelFunc) { - var once sync.Once - out := make(chan struct{}) - cancel := make(chan struct{}) - cancelFunc := func() { - once.Do(func() { - close(cancel) - }) - } - go func() { - defer close(out) - select { - case <-a: - case <-b: - case <-c: - case <-cancel: - } - }() - - return out, cancelFunc -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/metadata_infomer_wrapper.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/metadata_infomer_wrapper.go deleted file mode 100644 index f7fdb963a1c..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/internal/metadata_infomer_wrapper.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package internal - -import ( - "time" - - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/tools/cache" -) - -func metadataSharedIndexInformerPreserveGVK(gvk schema.GroupVersionKind, si cache.SharedIndexInformer) cache.SharedIndexInformer { - return &sharedInformerWrapper{ - gvk: gvk, - SharedIndexInformer: si, - } -} - -type sharedInformerWrapper struct { - gvk schema.GroupVersionKind - cache.SharedIndexInformer -} - -func (s *sharedInformerWrapper) AddEventHandler(handler cache.ResourceEventHandler) { - s.SharedIndexInformer.AddEventHandler(&handlerPreserveGVK{s.gvk, handler}) -} - -func (s *sharedInformerWrapper) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) { - s.SharedIndexInformer.AddEventHandlerWithResyncPeriod(&handlerPreserveGVK{s.gvk, handler}, resyncPeriod) -} - -type handlerPreserveGVK struct { - gvk schema.GroupVersionKind - cache.ResourceEventHandler -} - -func (h *handlerPreserveGVK) resetGroupVersionKind(obj interface{}) { - if v, ok := obj.(schema.ObjectKind); ok { - v.SetGroupVersionKind(h.gvk) - } -} - -func (h *handlerPreserveGVK) OnAdd(obj interface{}) { - h.resetGroupVersionKind(obj) - h.ResourceEventHandler.OnAdd(obj) -} - -func (h *handlerPreserveGVK) OnUpdate(oldObj, newObj interface{}) { - h.resetGroupVersionKind(oldObj) - h.resetGroupVersionKind(newObj) - h.ResourceEventHandler.OnUpdate(oldObj, newObj) -} - -func (h *handlerPreserveGVK) OnDelete(obj interface{}) { - h.resetGroupVersionKind(obj) - h.ResourceEventHandler.OnDelete(obj) -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/multi_namespace_cache.go b/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/multi_namespace_cache.go deleted file mode 100644 index 3e2f43ad2b8..00000000000 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/dynamiccache/multi_namespace_cache.go +++ /dev/null @@ -1,335 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Modified from the original source (available at -// https://github.com/kubernetes-sigs/controller-runtime/tree/v0.9.2/pkg/cache) - -package dynamiccache - -import ( - "context" - "fmt" - "time" - - "github.com/open-policy-agent/gatekeeper/third_party/sigs.k8s.io/controller-runtime/pkg/internal/objectutil" - corev1 "k8s.io/api/core/v1" - apimeta "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - toolscache "k8s.io/client-go/tools/cache" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// NewCacheFunc - Function for creating a new cache from the options and a rest config. -type NewCacheFunc func(config *rest.Config, opts cache.Options) (cache.Cache, error) - -// a new global namespaced cache to handle cluster scoped resources. -const globalCache = "_cluster-scope" - -// MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache. -// This will scope the cache to a list of namespaces. Listing for all namespaces -// will list for all the namespaces that this knows about. By default this will create -// a global cache for cluster scoped resource. Note that this is not intended -// to be used for excluding namespaces, this is better done via a Predicate. Also note that -// you may face performance issues when using this with a high number of namespaces. -func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { - return func(config *rest.Config, opts cache.Options) (cache.Cache, error) { - opts, err := defaultOpts(config, opts) - if err != nil { - return nil, err - } - - caches := map[string]cache.Cache{} - - // create a cache for cluster scoped resources - gCache, err := New(config, opts) - if err != nil { - return nil, fmt.Errorf("error creating global cache %v", err) - } - - for _, ns := range namespaces { - opts.Namespace = ns - c, err := New(config, opts) - if err != nil { - return nil, err - } - caches[ns] = c - } - return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil - } -} - -// multiNamespaceCache knows how to handle multiple namespaced caches -// Use this feature when scoping permissions for your -// operator to a list of namespaces instead of watching every namespace -// in the cluster. -type multiNamespaceCache struct { - namespaceToCache map[string]cache.Cache - Scheme *runtime.Scheme - RESTMapper apimeta.RESTMapper - clusterCache cache.Cache -} - -var _ cache.Cache = &multiNamespaceCache{} - -// Methods for multiNamespaceCache to conform to the Informers interface. -func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object) (cache.Informer, error) { - informers := map[string]cache.Informer{} - - // If the object is clusterscoped, get the informer from clusterCache, - // if not use the namespaced caches. - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) - if err != nil { - return nil, err - } - if !isNamespaced { - clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj) - if err != nil { - return nil, err - } - informers[globalCache] = clusterCacheInf - - return &multiNamespaceInformer{namespaceToInformer: informers}, nil - } - - for ns, cache := range c.namespaceToCache { - informer, err := cache.GetInformer(ctx, obj) - if err != nil { - return nil, err - } - informers[ns] = informer - } - - return &multiNamespaceInformer{namespaceToInformer: informers}, nil -} - -func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (cache.Informer, error) { - informers := map[string]cache.Informer{} - - // If the object is clusterscoped, get the informer from clusterCache, - // if not use the namespaced caches. - isNamespaced, err := objectutil.IsAPINamespacedWithGVK(gvk, c.Scheme, c.RESTMapper) - if err != nil { - return nil, err - } - if !isNamespaced { - clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk) - if err != nil { - return nil, err - } - informers[globalCache] = clusterCacheInf - - return &multiNamespaceInformer{namespaceToInformer: informers}, nil - } - - for ns, cache := range c.namespaceToCache { - informer, err := cache.GetInformerForKind(ctx, gvk) - if err != nil { - return nil, err - } - informers[ns] = informer - } - - return &multiNamespaceInformer{namespaceToInformer: informers}, nil -} - -func (c *multiNamespaceCache) Start(ctx context.Context) error { - // start global cache - go func() { - err := c.clusterCache.Start(ctx) - if err != nil { - log.Error(err, "cluster scoped cache failed to start") - } - }() - - // start namespaced caches - for ns, entry := range c.namespaceToCache { - go func(ns string, cache cache.Cache) { - err := cache.Start(ctx) - if err != nil { - log.Error(err, "multinamespace cache failed to start namespaced informer", "namespace", ns) - } - }(ns, entry) - } - - <-ctx.Done() - return nil -} - -func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool { - synced := true - for _, cache := range c.namespaceToCache { - if s := cache.WaitForCacheSync(ctx); !s { - synced = s - } - } - - // check if cluster scoped cache has synced - if !c.clusterCache.WaitForCacheSync(ctx) { - synced = false - } - return synced -} - -func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) - if err != nil { - return nil //nolint:nilerr - } - - if !isNamespaced { - return c.clusterCache.IndexField(ctx, obj, field, extractValue) - } - - for _, cache := range c.namespaceToCache { - if err := cache.IndexField(ctx, obj, field, extractValue); err != nil { - return err - } - } - return nil -} - -func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error { - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) - if err != nil { - return err - } - - if !isNamespaced { - // Look into the global cache to fetch the object - return c.clusterCache.Get(ctx, key, obj) - } - - cache, ok := c.namespaceToCache[key.Namespace] - if !ok { - return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", key) - } - return cache.Get(ctx, key, obj) -} - -// List multi namespace cache will get all the objects in the namespaces that the cache is watching if asked for all namespaces. -func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { - listOpts := client.ListOptions{} - listOpts.ApplyOptions(opts) - - isNamespaced, err := objectutil.IsAPINamespaced(list, c.Scheme, c.RESTMapper) - if err != nil { - return err - } - - if !isNamespaced { - // Look at the global cache to get the objects with the specified GVK - return c.clusterCache.List(ctx, list, opts...) - } - - if listOpts.Namespace != corev1.NamespaceAll { - cache, ok := c.namespaceToCache[listOpts.Namespace] - if !ok { - return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", listOpts.Namespace) - } - return cache.List(ctx, list, opts...) - } - - listAccessor, err := apimeta.ListAccessor(list) - if err != nil { - return err - } - - allItems, err := apimeta.ExtractList(list) - if err != nil { - return err - } - - limitSet := listOpts.Limit > 0 - - var resourceVersion string - for _, cache := range c.namespaceToCache { - listObj := list.DeepCopyObject().(client.ObjectList) - err = cache.List(ctx, listObj, &listOpts) - if err != nil { - return err - } - items, err := apimeta.ExtractList(listObj) - if err != nil { - return err - } - accessor, err := apimeta.ListAccessor(listObj) - if err != nil { - return fmt.Errorf("object: %T must be a list type", list) - } - allItems = append(allItems, items...) - // The last list call should have the most correct resource version. - resourceVersion = accessor.GetResourceVersion() - if limitSet { - // decrement Limit by the number of items - // fetched from the current namespace. - listOpts.Limit -= int64(len(items)) - // if a Limit was set and the number of - // items read has reached this set limit, - // then stop reading. - if listOpts.Limit == 0 { - break - } - } - } - listAccessor.SetResourceVersion(resourceVersion) - - return apimeta.SetList(list, allItems) -} - -// multiNamespaceInformer knows how to handle interacting with the underlying informer across multiple namespaces. -type multiNamespaceInformer struct { - namespaceToInformer map[string]cache.Informer -} - -var _ cache.Informer = &multiNamespaceInformer{} - -// AddEventHandler adds the handler to each namespaced informer. -func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) { - for _, informer := range i.namespaceToInformer { - informer.AddEventHandler(handler) - } -} - -// AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer. -func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) { - for _, informer := range i.namespaceToInformer { - informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod) - } -} - -// AddIndexers adds the indexer for each namespaced informer. -func (i *multiNamespaceInformer) AddIndexers(indexers toolscache.Indexers) error { - for _, informer := range i.namespaceToInformer { - err := informer.AddIndexers(indexers) - if err != nil { - return err - } - } - return nil -} - -// HasSynced checks if each namespaced informer has synced. -func (i *multiNamespaceInformer) HasSynced() bool { - for _, informer := range i.namespaceToInformer { - if ok := informer.HasSynced(); !ok { - return ok - } - } - return true -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go new file mode 100644 index 00000000000..f9c58ea26a3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go @@ -0,0 +1,458 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "time" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + k8syaml "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/retry" + "k8s.io/utils/pointer" + "sigs.k8s.io/yaml" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/webhook/conversion" +) + +// CRDInstallOptions are the options for installing CRDs. +type CRDInstallOptions struct { + // Scheme is used to determine if conversion webhooks should be enabled + // for a particular CRD / object. + // + // Conversion webhooks are going to be enabled if an object in the scheme + // implements Hub and Spoke conversions. + // + // If nil, scheme.Scheme is used. + Scheme *runtime.Scheme + + // Paths is a list of paths to the directories or files containing CRDs + Paths []string + + // CRDs is a list of CRDs to install + CRDs []*apiextensionsv1.CustomResourceDefinition + + // ErrorIfPathMissing will cause an error if a Path does not exist + ErrorIfPathMissing bool + + // MaxTime is the max time to wait + MaxTime time.Duration + + // PollInterval is the interval to check + PollInterval time.Duration + + // CleanUpAfterUse will cause the CRDs listed for installation to be + // uninstalled when terminating the test environment. + // Defaults to false. + CleanUpAfterUse bool + + // WebhookOptions contains the conversion webhook information to install + // on the CRDs. This field is usually inherited by the EnvTest options. + // + // If you're passing this field manually, you need to make sure that + // the CA information and host port is filled in properly. + WebhookOptions WebhookInstallOptions +} + +const ( + defaultPollInterval = 100 * time.Millisecond + defaultMaxWait = 10 * time.Second +) + +// InstallCRDs installs a collection of CRDs into a cluster by reading the crd yaml files from a directory. +func InstallCRDs(config *rest.Config, options CRDInstallOptions) ([]*apiextensionsv1.CustomResourceDefinition, error) { + defaultCRDOptions(&options) + + // Read the CRD yamls into options.CRDs + if err := readCRDFiles(&options); err != nil { + return nil, fmt.Errorf("unable to read CRD files: %w", err) + } + + if err := modifyConversionWebhooks(options.CRDs, options.Scheme, options.WebhookOptions); err != nil { + return nil, err + } + + // Create the CRDs in the apiserver + if err := CreateCRDs(config, options.CRDs); err != nil { + return options.CRDs, fmt.Errorf("unable to create CRD instances: %w", err) + } + + // Wait for the CRDs to appear as Resources in the apiserver + if err := WaitForCRDs(config, options.CRDs, options); err != nil { + return options.CRDs, fmt.Errorf("something went wrong waiting for CRDs to appear as API resources: %w", err) + } + + return options.CRDs, nil +} + +// readCRDFiles reads the directories of CRDs in options.Paths and adds the CRD structs to options.CRDs. +func readCRDFiles(options *CRDInstallOptions) error { + if len(options.Paths) > 0 { + crdList, err := renderCRDs(options) + if err != nil { + return err + } + + options.CRDs = append(options.CRDs, crdList...) + } + return nil +} + +// defaultCRDOptions sets the default values for CRDs. +func defaultCRDOptions(o *CRDInstallOptions) { + if o.Scheme == nil { + o.Scheme = scheme.Scheme + } + if o.MaxTime == 0 { + o.MaxTime = defaultMaxWait + } + if o.PollInterval == 0 { + o.PollInterval = defaultPollInterval + } +} + +// WaitForCRDs waits for the CRDs to appear in discovery. +func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefinition, options CRDInstallOptions) error { + // Add each CRD to a map of GroupVersion to Resource + waitingFor := map[schema.GroupVersion]*sets.Set[string]{} + for _, crd := range crds { + gvs := []schema.GroupVersion{} + for _, version := range crd.Spec.Versions { + if version.Served { + gvs = append(gvs, schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name}) + } + } + + for _, gv := range gvs { + log.V(1).Info("adding API in waitlist", "GV", gv) + if _, found := waitingFor[gv]; !found { + // Initialize the set + waitingFor[gv] = &sets.Set[string]{} + } + // Add the Resource + waitingFor[gv].Insert(crd.Spec.Names.Plural) + } + } + + // Poll until all resources are found in discovery + p := &poller{config: config, waitingFor: waitingFor} + return wait.PollUntilContextTimeout(context.TODO(), options.PollInterval, options.MaxTime, true, p.poll) +} + +// poller checks if all the resources have been found in discovery, and returns false if not. +type poller struct { + // config is used to get discovery + config *rest.Config + + // waitingFor is the map of resources keyed by group version that have not yet been found in discovery + waitingFor map[schema.GroupVersion]*sets.Set[string] +} + +// poll checks if all the resources have been found in discovery, and returns false if not. +func (p *poller) poll(ctx context.Context) (done bool, err error) { + // Create a new clientset to avoid any client caching of discovery + cs, err := clientset.NewForConfig(p.config) + if err != nil { + return false, err + } + + allFound := true + for gv, resources := range p.waitingFor { + // All resources found, do nothing + if resources.Len() == 0 { + delete(p.waitingFor, gv) + continue + } + + // Get the Resources for this GroupVersion + // TODO: Maybe the controller-runtime client should be able to do this... + resourceList, err := cs.Discovery().ServerResourcesForGroupVersion(gv.Group + "/" + gv.Version) + if err != nil { + return false, nil //nolint:nilerr + } + + // Remove each found resource from the resources set that we are waiting for + for _, resource := range resourceList.APIResources { + resources.Delete(resource.Name) + } + + // Still waiting on some resources in this group version + if resources.Len() != 0 { + allFound = false + } + } + return allFound, nil +} + +// UninstallCRDs uninstalls a collection of CRDs by reading the crd yaml files from a directory. +func UninstallCRDs(config *rest.Config, options CRDInstallOptions) error { + // Read the CRD yamls into options.CRDs + if err := readCRDFiles(&options); err != nil { + return err + } + + // Delete the CRDs from the apiserver + cs, err := client.New(config, client.Options{}) + if err != nil { + return err + } + + // Uninstall each CRD + for _, crd := range options.CRDs { + crd := crd + log.V(1).Info("uninstalling CRD", "crd", crd.GetName()) + if err := cs.Delete(context.TODO(), crd); err != nil { + // If CRD is not found, we can consider success + if !apierrors.IsNotFound(err) { + return err + } + } + } + + return nil +} + +// CreateCRDs creates the CRDs. +func CreateCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefinition) error { + cs, err := client.New(config, client.Options{}) + if err != nil { + return fmt.Errorf("unable to create client: %w", err) + } + + // Create each CRD + for _, crd := range crds { + crd := crd + log.V(1).Info("installing CRD", "crd", crd.GetName()) + existingCrd := crd.DeepCopy() + err := cs.Get(context.TODO(), client.ObjectKey{Name: crd.GetName()}, existingCrd) + switch { + case apierrors.IsNotFound(err): + if err := cs.Create(context.TODO(), crd); err != nil { + return fmt.Errorf("unable to create CRD %q: %w", crd.GetName(), err) + } + case err != nil: + return fmt.Errorf("unable to get CRD %q to check if it exists: %w", crd.GetName(), err) + default: + log.V(1).Info("CRD already exists, updating", "crd", crd.GetName()) + if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { + if err := cs.Get(context.TODO(), client.ObjectKey{Name: crd.GetName()}, existingCrd); err != nil { + return err + } + crd.SetResourceVersion(existingCrd.GetResourceVersion()) + return cs.Update(context.TODO(), crd) + }); err != nil { + return err + } + } + } + return nil +} + +// renderCRDs iterate through options.Paths and extract all CRD files. +func renderCRDs(options *CRDInstallOptions) ([]*apiextensionsv1.CustomResourceDefinition, error) { + type GVKN struct { + GVK schema.GroupVersionKind + Name string + } + + crds := map[GVKN]*apiextensionsv1.CustomResourceDefinition{} + + for _, path := range options.Paths { + var ( + err error + info os.FileInfo + files []string + filePath = path + ) + + // Return the error if ErrorIfPathMissing exists + if info, err = os.Stat(path); os.IsNotExist(err) { + if options.ErrorIfPathMissing { + return nil, err + } + continue + } + + if !info.IsDir() { + filePath, files = filepath.Dir(path), []string{info.Name()} + } else { + entries, err := os.ReadDir(path) + if err != nil { + return nil, err + } + for _, e := range entries { + files = append(files, e.Name()) + } + } + + log.V(1).Info("reading CRDs from path", "path", path) + crdList, err := readCRDs(filePath, files) + if err != nil { + return nil, err + } + + for i, crd := range crdList { + gvkn := GVKN{GVK: crd.GroupVersionKind(), Name: crd.GetName()} + if _, found := crds[gvkn]; found { + // Currently, we only print a log when there are duplicates. We may want to error out if that makes more sense. + log.Info("there are more than one CRD definitions with the same ", "GVKN", gvkn) + } + // We always use the CRD definition that we found last. + crds[gvkn] = crdList[i] + } + } + + // Converting map to a list to return + res := []*apiextensionsv1.CustomResourceDefinition{} + for _, obj := range crds { + res = append(res, obj) + } + return res, nil +} + +// modifyConversionWebhooks takes all the registered CustomResourceDefinitions and applies modifications +// to conditionally enable webhooks if the type is registered within the scheme. +func modifyConversionWebhooks(crds []*apiextensionsv1.CustomResourceDefinition, scheme *runtime.Scheme, webhookOptions WebhookInstallOptions) error { + if len(webhookOptions.LocalServingCAData) == 0 { + return nil + } + + // Determine all registered convertible types. + convertibles := map[schema.GroupKind]struct{}{} + for gvk := range scheme.AllKnownTypes() { + obj, err := scheme.New(gvk) + if err != nil { + return err + } + if ok, err := conversion.IsConvertible(scheme, obj); ok && err == nil { + convertibles[gvk.GroupKind()] = struct{}{} + } + } + + // generate host port. + hostPort, err := webhookOptions.generateHostPort() + if err != nil { + return err + } + url := pointer.String(fmt.Sprintf("https://%s/convert", hostPort)) + + for i := range crds { + // Continue if we're preserving unknown fields. + if crds[i].Spec.PreserveUnknownFields { + continue + } + // Continue if the GroupKind isn't registered as being convertible. + if _, ok := convertibles[schema.GroupKind{ + Group: crds[i].Spec.Group, + Kind: crds[i].Spec.Names.Kind, + }]; !ok { + continue + } + if crds[i].Spec.Conversion == nil { + crds[i].Spec.Conversion = &apiextensionsv1.CustomResourceConversion{ + Webhook: &apiextensionsv1.WebhookConversion{}, + } + } + crds[i].Spec.Conversion.Strategy = apiextensionsv1.WebhookConverter + crds[i].Spec.Conversion.Webhook.ConversionReviewVersions = []string{"v1", "v1beta1"} + crds[i].Spec.Conversion.Webhook.ClientConfig = &apiextensionsv1.WebhookClientConfig{ + Service: nil, + URL: url, + CABundle: webhookOptions.LocalServingCAData, + } + } + + return nil +} + +// readCRDs reads the CRDs from files and Unmarshals them into structs. +func readCRDs(basePath string, files []string) ([]*apiextensionsv1.CustomResourceDefinition, error) { + var crds []*apiextensionsv1.CustomResourceDefinition + + // White list the file extensions that may contain CRDs + crdExts := sets.NewString(".json", ".yaml", ".yml") + + for _, file := range files { + // Only parse allowlisted file types + if !crdExts.Has(filepath.Ext(file)) { + continue + } + + // Unmarshal CRDs from file into structs + docs, err := readDocuments(filepath.Join(basePath, file)) + if err != nil { + return nil, err + } + + for _, doc := range docs { + crd := &apiextensionsv1.CustomResourceDefinition{} + if err = yaml.Unmarshal(doc, crd); err != nil { + return nil, err + } + + if crd.Kind != "CustomResourceDefinition" || crd.Spec.Names.Kind == "" || crd.Spec.Group == "" { + continue + } + crds = append(crds, crd) + } + + log.V(1).Info("read CRDs from file", "file", file) + } + return crds, nil +} + +// readDocuments reads documents from file. +func readDocuments(fp string) ([][]byte, error) { + b, err := os.ReadFile(fp) + if err != nil { + return nil, err + } + + docs := [][]byte{} + reader := k8syaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(b))) + for { + // Read document + doc, err := reader.Read() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + + return nil, err + } + + docs = append(docs, doc) + } + + return docs, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd_test.go new file mode 100644 index 00000000000..92dc48e9630 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/crd_test.go @@ -0,0 +1,51 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/util/sets" +) + +var _ = Describe("Test", func() { + Describe("readCRDFiles", func() { + It("should not mix up files from different directories", func() { + opt := CRDInstallOptions{ + Paths: []string{ + "testdata/crds", + "testdata/crdv1_original", + }, + } + err := readCRDFiles(&opt) + Expect(err).NotTo(HaveOccurred()) + + expectedCRDs := sets.NewString( + "frigates.ship.example.com", + "configs.foo.example.com", + "drivers.crew.example.com", + ) + + foundCRDs := sets.NewString() + for _, crd := range opt.CRDs { + foundCRDs.Insert(crd.Name) + } + + Expect(expectedCRDs).To(Equal(foundCRDs)) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/doc.go new file mode 100644 index 00000000000..412e794cc8c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/doc.go @@ -0,0 +1,26 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package envtest provides libraries for integration testing by starting a local control plane +// +// Control plane binaries (etcd and kube-apiserver) are loaded by default from +// /usr/local/kubebuilder/bin. This can be overridden by setting the +// KUBEBUILDER_ASSETS environment variable, or by directly creating a +// ControlPlane for the Environment to use. +// +// Environment can also be configured to work with an existing cluster, and +// simply load CRDs and provide client configuration. +package envtest diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_suite_test.go new file mode 100644 index 00000000000..f7788bf0902 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_suite_test.go @@ -0,0 +1,134 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + admissionv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Envtest Suite") +} + +var env *Environment + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + env = &Environment{} + // we're initializing webhook here and not in webhook.go to also test the envtest install code via WebhookOptions + initializeWebhookInEnvironment() + _, err := env.Start() + Expect(err).NotTo(HaveOccurred()) +}) + +func initializeWebhookInEnvironment() { + namespacedScopeV1 := admissionv1.NamespacedScope + failedTypeV1 := admissionv1.Fail + equivalentTypeV1 := admissionv1.Equivalent + noSideEffectsV1 := admissionv1.SideEffectClassNone + webhookPathV1 := "/failing" + + env.WebhookInstallOptions = WebhookInstallOptions{ + ValidatingWebhooks: []*admissionv1.ValidatingWebhookConfiguration{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-validation-webhook-config", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "ValidatingWebhookConfiguration", + APIVersion: "admissionregistration.k8s.io/v1", + }, + Webhooks: []admissionv1.ValidatingWebhook{ + { + Name: "deployment-validation.kubebuilder.io", + Rules: []admissionv1.RuleWithOperations{ + { + Operations: []admissionv1.OperationType{"CREATE", "UPDATE"}, + Rule: admissionv1.Rule{ + APIGroups: []string{"apps"}, + APIVersions: []string{"v1"}, + Resources: []string{"deployments"}, + Scope: &namespacedScopeV1, + }, + }, + }, + FailurePolicy: &failedTypeV1, + MatchPolicy: &equivalentTypeV1, + SideEffects: &noSideEffectsV1, + ClientConfig: admissionv1.WebhookClientConfig{ + Service: &admissionv1.ServiceReference{ + Name: "deployment-validation-service", + Namespace: "default", + Path: &webhookPathV1, + }, + }, + AdmissionReviewVersions: []string{"v1"}, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-validation-webhook-config", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "ValidatingWebhookConfiguration", + APIVersion: "admissionregistration.k8s.io/v1", + }, + Webhooks: []admissionv1.ValidatingWebhook{ + { + Name: "deployment-validation.kubebuilder.io", + Rules: []admissionv1.RuleWithOperations{ + { + Operations: []admissionv1.OperationType{"CREATE", "UPDATE"}, + Rule: admissionv1.Rule{ + APIGroups: []string{"apps"}, + APIVersions: []string{"v1"}, + Resources: []string{"deployments"}, + Scope: &namespacedScopeV1, + }, + }, + }, + FailurePolicy: &failedTypeV1, + MatchPolicy: &equivalentTypeV1, + SideEffects: &noSideEffectsV1, + ClientConfig: admissionv1.WebhookClientConfig{ + Service: &admissionv1.ServiceReference{ + Name: "deployment-validation-service", + Namespace: "default", + Path: &webhookPathV1, + }, + }, + AdmissionReviewVersions: []string{"v1"}, + }, + }, + }, + }, + } +} + +var _ = AfterSuite(func() { + Expect(env.Stop()).NotTo(HaveOccurred()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_test.go new file mode 100644 index 00000000000..21464e10bef --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/envtest_test.go @@ -0,0 +1,961 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "context" + "path/filepath" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("Test", func() { + var crds []*apiextensionsv1.CustomResourceDefinition + var err error + var s *runtime.Scheme + var c client.Client + + var validDirectory = filepath.Join(".", "testdata") + var invalidDirectory = "fake" + + var teardownTimeoutSeconds float64 = 10 + + // Initialize the client + BeforeEach(func() { + crds = []*apiextensionsv1.CustomResourceDefinition{} + s = scheme.Scheme + err = apiextensionsv1.AddToScheme(s) + Expect(err).NotTo(HaveOccurred()) + + c, err = client.New(env.Config, client.Options{Scheme: s}) + Expect(err).NotTo(HaveOccurred()) + }) + + // Cleanup CRDs + AfterEach(func() { + for _, crd := range crds { + crd := crd + // Delete only if CRD exists. + crdObjectKey := client.ObjectKey{ + Name: crd.GetName(), + } + var placeholder apiextensionsv1.CustomResourceDefinition + if err = c.Get(context.TODO(), crdObjectKey, &placeholder); err != nil && + apierrors.IsNotFound(err) { + // CRD doesn't need to be deleted. + continue + } + Expect(err).NotTo(HaveOccurred()) + Expect(c.Delete(context.TODO(), crd)).To(Succeed()) + Eventually(func() bool { + err := c.Get(context.TODO(), crdObjectKey, &placeholder) + return apierrors.IsNotFound(err) + }, 5*time.Second).Should(BeTrue()) + } + }, teardownTimeoutSeconds) + + Describe("InstallCRDs", func() { + It("should install the unserved CRDs into the cluster", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata", "crds", "examplecrd_unserved.yaml")}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "frigates.ship.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Frigate")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "ship.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "frigates", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: false, + }, + { + Name: "v1beta1", + Storage: false, + Served: false, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + It("should install the CRDs into the cluster using directory", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{validDirectory}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Foo")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Baz")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Captain")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foos", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "qux.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "bazs", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "captains", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "firstmates", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should install the CRDs into the cluster using file", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata", "crds", "examplecrd3.yaml")}, + }) + Expect(err).NotTo(HaveOccurred()) + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "configs.foo.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Config")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "foo.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "configs", + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should be able to install CRDs using multiple files", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{ + filepath.Join(".", "testdata", "examplecrd.yaml"), + filepath.Join(".", "testdata", "examplecrd_v1.yaml"), + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(crds).To(HaveLen(2)) + }) + + It("should filter out already existent CRD", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{ + filepath.Join(".", "testdata"), + filepath.Join(".", "testdata", "examplecrd1.yaml"), + }, + }) + Expect(err).NotTo(HaveOccurred()) + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Foo")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foos", + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not return an not error if the directory doesn't exist", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{Paths: []string{invalidDirectory}}) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should return an error if the directory doesn't exist", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{invalidDirectory}, ErrorIfPathMissing: true, + }) + Expect(err).To(HaveOccurred()) + }) + + It("should return an error if the file doesn't exist", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{Paths: []string{ + filepath.Join(".", "testdata", "fake.yaml")}, ErrorIfPathMissing: true, + }) + Expect(err).To(HaveOccurred()) + }) + + It("should return an error if the resource group version isn't found", func() { + // Wait for a CRD where the Group and Version don't exist + err := WaitForCRDs(env.Config, + []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "notfound", + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).To(HaveOccurred()) + }) + + It("should return an error if the resource isn't found in the group version", func() { + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{"."}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Wait for a CRD that doesn't exist, but the Group and Version do + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "qux.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "bazs", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "fake", + }}, + }}, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).To(HaveOccurred()) + }) + + It("should reinstall the CRDs if already present in the cluster", func() { + + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata")}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Foo")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Baz")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Captain")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foos", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "qux.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "bazs", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "captains", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "firstmates", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + + // Try to re-install the CRDs + + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata")}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Foo")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Baz")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Captain")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foos", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "qux.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "bazs", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "captains", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "firstmates", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + }) + + It("should update CRDs if already present in the cluster", func() { + + // Install only the CRDv1 multi-version example + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata")}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(2)) + + // Store resource version for comparison later on + firstRV := crd.ResourceVersion + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + + // Add one more version and update + _, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{filepath.Join(".", "testdata", "crdv1_updated")}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find updated CRD + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + Expect(len(crd.Spec.Versions)).To(BeEquivalentTo(3)) + Expect(crd.ResourceVersion).NotTo(BeEquivalentTo(firstRV)) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + { + Name: "v3", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + }) + + Describe("UninstallCRDs", func() { + It("should uninstall the CRDs from the cluster", func() { + + crds, err = InstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{validDirectory}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to find the CRDs + + crd := &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "foos.bar.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Foo")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "bazs.qux.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Baz")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "captains.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Captain")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "firstmates.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("FirstMate")) + + crd = &apiextensionsv1.CustomResourceDefinition{} + err = c.Get(context.TODO(), types.NamespacedName{Name: "drivers.crew.example.com"}, crd) + Expect(err).NotTo(HaveOccurred()) + Expect(crd.Spec.Names.Kind).To(Equal("Driver")) + + err = WaitForCRDs(env.Config, []*apiextensionsv1.CustomResourceDefinition{ + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "bar.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foos", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "qux.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "bazs", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "captains", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1beta1", + Storage: true, + Served: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{}, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "firstmates", + }}, + }, + { + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "crew.example.com", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "drivers", + }, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "v1", + Storage: true, + Served: true, + }, + { + Name: "v2", + Storage: false, + Served: true, + }, + }}, + }, + }, + CRDInstallOptions{MaxTime: 50 * time.Millisecond, PollInterval: 15 * time.Millisecond}, + ) + Expect(err).NotTo(HaveOccurred()) + + err = UninstallCRDs(env.Config, CRDInstallOptions{ + Paths: []string{validDirectory}, + }) + Expect(err).NotTo(HaveOccurred()) + + // Expect to NOT find the CRDs + + crds := []string{ + "foos.bar.example.com", + "bazs.qux.example.com", + "captains.crew.example.com", + "firstmates.crew.example.com", + "drivers.crew.example.com", + } + placeholder := &apiextensionsv1.CustomResourceDefinition{} + Eventually(func() bool { + for _, crd := range crds { + err = c.Get(context.TODO(), types.NamespacedName{Name: crd}, placeholder) + notFound := err != nil && apierrors.IsNotFound(err) + if !notFound { + return false + } + } + return true + }, 20).Should(BeTrue()) + }) + }) + + Describe("Start", func() { + It("should raise an error on invalid dir when flag is enabled", func() { + env := &Environment{ErrorIfCRDPathMissing: true, CRDDirectoryPaths: []string{invalidDirectory}} + _, err := env.Start() + Expect(err).To(HaveOccurred()) + Expect(env.Stop()).To(Succeed()) + }) + + It("should not raise an error on invalid dir when flag is disabled", func() { + env := &Environment{ErrorIfCRDPathMissing: false, CRDDirectoryPaths: []string{invalidDirectory}} + _, err := env.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(env.Stop()).To(Succeed()) + }) + }) + + Describe("Stop", func() { + It("should cleanup webhook /tmp folder with no error when using existing cluster", func() { + env := &Environment{} + _, err := env.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(env.Stop()).To(Succeed()) + + // check if the /tmp/envtest-serving-certs-* dir doesnt exists any more + Expect(env.WebhookInstallOptions.LocalServingCertDir).ShouldNot(BeADirectory()) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/helper.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/helper.go new file mode 100644 index 00000000000..d3b52017d23 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/helper.go @@ -0,0 +1,69 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/client-go/kubernetes/scheme" +) + +var ( + crdScheme = scheme.Scheme +) + +// init is required to correctly initialize the crdScheme package variable. +func init() { + _ = apiextensionsv1.AddToScheme(crdScheme) +} + +// mergePaths merges two string slices containing paths. +// This function makes no guarantees about order of the merged slice. +func mergePaths(s1, s2 []string) []string { + m := make(map[string]struct{}) + for _, s := range s1 { + m[s] = struct{}{} + } + for _, s := range s2 { + m[s] = struct{}{} + } + merged := make([]string, len(m)) + i := 0 + for key := range m { + merged[i] = key + i++ + } + return merged +} + +// mergeCRDs merges two CRD slices using their names. +// This function makes no guarantees about order of the merged slice. +func mergeCRDs(s1, s2 []*apiextensionsv1.CustomResourceDefinition) []*apiextensionsv1.CustomResourceDefinition { + m := make(map[string]*apiextensionsv1.CustomResourceDefinition) + for _, obj := range s1 { + m[obj.GetName()] = obj + } + for _, obj := range s2 { + m[obj.GetName()] = obj + } + merged := make([]*apiextensionsv1.CustomResourceDefinition, len(m)) + i := 0 + for _, obj := range m { + merged[i] = obj.DeepCopy() + i++ + } + return merged +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/OWNERS b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/OWNERS new file mode 100644 index 00000000000..ba347dae2b5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/OWNERS @@ -0,0 +1,14 @@ +approvers: + - controller-runtime-admins + - controller-runtime-maintainers + - controller-runtime-approvers + - schrej + - JoelSpeed + - sbueringer +reviewers: + - controller-runtime-admins + - controller-runtime-reviewers + - controller-runtime-approvers + - schrej + - JoelSpeed + - sbueringer diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default.go new file mode 100644 index 00000000000..48fb927a200 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default.go @@ -0,0 +1,104 @@ +package komega + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// defaultK is the Komega used by the package global functions. +var defaultK = &komega{ctx: context.Background()} + +// SetClient sets the client used by the package global functions. +func SetClient(c client.Client) { + defaultK.client = c +} + +// SetContext sets the context used by the package global functions. +func SetContext(c context.Context) { + defaultK.ctx = c +} + +func checkDefaultClient() { + if defaultK.client == nil { + panic("Default Komega's client is not set. Use SetClient to set it.") + } +} + +// Get returns a function that fetches a resource and returns the occurring error. +// It can be used with gomega.Eventually() like this +// +// deployment := appsv1.Deployment{ ... } +// gomega.Eventually(komega.Get(&deployment)).To(gomega.Succeed()) +// +// By calling the returned function directly it can also be used with gomega.Expect(komega.Get(...)()).To(...) +func Get(obj client.Object) func() error { + checkDefaultClient() + return defaultK.Get(obj) +} + +// List returns a function that lists resources and returns the occurring error. +// It can be used with gomega.Eventually() like this +// +// deployments := v1.DeploymentList{ ... } +// gomega.Eventually(k.List(&deployments)).To(gomega.Succeed()) +// +// By calling the returned function directly it can also be used as gomega.Expect(k.List(...)()).To(...) +func List(list client.ObjectList, opts ...client.ListOption) func() error { + checkDefaultClient() + return defaultK.List(list, opts...) +} + +// Update returns a function that fetches a resource, applies the provided update function and then updates the resource. +// It can be used with gomega.Eventually() like this: +// +// deployment := appsv1.Deployment{ ... } +// gomega.Eventually(k.Update(&deployment, func (o client.Object) { +// deployment.Spec.Replicas = 3 +// return &deployment +// })).To(gomega.Succeed()) +// +// By calling the returned function directly it can also be used as gomega.Expect(k.Update(...)()).To(...) +func Update(obj client.Object, f func(), opts ...client.UpdateOption) func() error { + checkDefaultClient() + return defaultK.Update(obj, f, opts...) +} + +// UpdateStatus returns a function that fetches a resource, applies the provided update function and then updates the resource's status. +// It can be used with gomega.Eventually() like this: +// +// deployment := appsv1.Deployment{ ... } +// gomega.Eventually(k.UpdateStatus(&deployment, func (o client.Object) { +// deployment.Status.AvailableReplicas = 1 +// return &deployment +// })).To(gomega.Succeed()) +// +// By calling the returned function directly it can also be used as gomega.Expect(k.UpdateStatus(...)()).To(...) +func UpdateStatus(obj client.Object, f func(), opts ...client.SubResourceUpdateOption) func() error { + checkDefaultClient() + return defaultK.UpdateStatus(obj, f, opts...) +} + +// Object returns a function that fetches a resource and returns the object. +// It can be used with gomega.Eventually() like this: +// +// deployment := appsv1.Deployment{ ... } +// gomega.Eventually(k.Object(&deployment)).To(HaveField("Spec.Replicas", gomega.Equal(pointer.Int32(3)))) +// +// By calling the returned function directly it can also be used as gomega.Expect(k.Object(...)()).To(...) +func Object(obj client.Object) func() (client.Object, error) { + checkDefaultClient() + return defaultK.Object(obj) +} + +// ObjectList returns a function that fetches a resource and returns the object. +// It can be used with gomega.Eventually() like this: +// +// deployments := appsv1.DeploymentList{ ... } +// gomega.Eventually(k.ObjectList(&deployments)).To(HaveField("Items", HaveLen(1))) +// +// By calling the returned function directly it can also be used as gomega.Expect(k.ObjectList(...)()).To(...) +func ObjectList(list client.ObjectList, opts ...client.ListOption) func() (client.ObjectList, error) { + checkDefaultClient() + return defaultK.ObjectList(list, opts...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default_test.go new file mode 100644 index 00000000000..238a4abd9e7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/default_test.go @@ -0,0 +1,116 @@ +package komega + +import ( + "testing" + + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" +) + +func TestDefaultGet(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + fetched := appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test", + }, + } + g.Eventually(Get(&fetched)).Should(Succeed()) + + g.Expect(*fetched.Spec.Replicas).To(BeEquivalentTo(5)) +} + +func TestDefaultList(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + list := appsv1.DeploymentList{} + g.Eventually(List(&list)).Should(Succeed()) + + g.Expect(list.Items).To(HaveLen(1)) + depl := exampleDeployment() + g.Expect(list.Items[0]).To(And( + HaveField("ObjectMeta.Name", Equal(depl.ObjectMeta.Name)), + HaveField("ObjectMeta.Namespace", Equal(depl.ObjectMeta.Namespace)), + )) +} + +func TestDefaultUpdate(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + updateDeployment := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Eventually(Update(&updateDeployment, func() { + updateDeployment.Annotations = map[string]string{"updated": "true"} + })).Should(Succeed()) + + fetched := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Expect(Object(&fetched)()).To(HaveField("ObjectMeta.Annotations", HaveKeyWithValue("updated", "true"))) +} + +func TestDefaultUpdateStatus(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + updateDeployment := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Eventually(UpdateStatus(&updateDeployment, func() { + updateDeployment.Status.AvailableReplicas = 1 + })).Should(Succeed()) + + fetched := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Expect(Object(&fetched)()).To(HaveField("Status.AvailableReplicas", BeEquivalentTo(1))) +} + +func TestDefaultObject(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + fetched := appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test", + }, + } + g.Eventually(Object(&fetched)).Should(And( + Not(BeNil()), + HaveField("Spec.Replicas", Equal(pointer.Int32(5))), + )) +} + +func TestDefaultObjectList(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + SetClient(fc) + + list := appsv1.DeploymentList{} + g.Eventually(ObjectList(&list)).Should(And( + Not(BeNil()), + HaveField("Items", And( + HaveLen(1), + ContainElement(HaveField("Spec.Replicas", Equal(pointer.Int32(5)))), + )), + )) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject.go new file mode 100644 index 00000000000..a931c2718a9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject.go @@ -0,0 +1,297 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package komega + +import ( + "fmt" + "reflect" + "strings" + + "github.com/google/go-cmp/cmp" + "github.com/onsi/gomega/format" + "github.com/onsi/gomega/types" + "k8s.io/apimachinery/pkg/runtime" +) + +// These package variables hold pre-created commonly used options that can be used to reduce the manual work involved in +// identifying the paths that need to be compared for testing equality between objects. +var ( + // IgnoreAutogeneratedMetadata contains the paths for all the metadata fields that are commonly set by the + // client and APIServer. This is used as a MatchOption for situations when only user-provided metadata is relevant. + IgnoreAutogeneratedMetadata = IgnorePaths{ + "metadata.uid", + "metadata.generation", + "metadata.creationTimestamp", + "metadata.resourceVersion", + "metadata.managedFields", + "metadata.deletionGracePeriodSeconds", + "metadata.deletionTimestamp", + "metadata.selfLink", + "metadata.generateName", + } +) + +type diffPath struct { + types []string + json []string +} + +// equalObjectMatcher is a Gomega matcher used to establish equality between two Kubernetes runtime.Objects. +type equalObjectMatcher struct { + // original holds the object that will be used to Match. + original runtime.Object + + // diffPaths contains the paths that differ between two objects. + diffPaths []diffPath + + // options holds the options that identify what should and should not be matched. + options *EqualObjectOptions +} + +// EqualObject returns a Matcher for the passed Kubernetes runtime.Object with the passed Options. This function can be +// used as a Gomega Matcher in Gomega Assertions. +func EqualObject(original runtime.Object, opts ...EqualObjectOption) types.GomegaMatcher { + matchOptions := &EqualObjectOptions{} + matchOptions = matchOptions.ApplyOptions(opts) + + return &equalObjectMatcher{ + options: matchOptions, + original: original, + } +} + +// Match compares the current object to the passed object and returns true if the objects are the same according to +// the Matcher and MatchOptions. +func (m *equalObjectMatcher) Match(actual interface{}) (success bool, err error) { + // Nil checks required first here for: + // 1) Nil equality which returns true + // 2) One object nil which returns an error + actualIsNil := reflect.ValueOf(actual).IsNil() + originalIsNil := reflect.ValueOf(m.original).IsNil() + + if actualIsNil && originalIsNil { + return true, nil + } + if actualIsNil || originalIsNil { + return false, fmt.Errorf("can not compare an object with a nil. original %v , actual %v", m.original, actual) + } + + m.diffPaths = m.calculateDiff(actual) + return len(m.diffPaths) == 0, nil +} + +// FailureMessage returns a message comparing the full objects after an unexpected failure to match has occurred. +func (m *equalObjectMatcher) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("the following fields were expected to match but did not:\n%v\n%s", m.diffPaths, + format.Message(actual, "expected to match", m.original)) +} + +// NegatedFailureMessage returns a string stating that all fields matched, even though that was not expected. +func (m *equalObjectMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return "it was expected that some fields do not match, but all of them did" +} + +func (d diffPath) String() string { + return fmt.Sprintf("(%s/%s)", strings.Join(d.types, "."), strings.Join(d.json, ".")) +} + +// diffReporter is a custom recorder for cmp.Diff which records all paths that are +// different between two objects. +type diffReporter struct { + stack []cmp.PathStep + + diffPaths []diffPath +} + +func (r *diffReporter) PushStep(s cmp.PathStep) { + r.stack = append(r.stack, s) +} + +func (r *diffReporter) Report(res cmp.Result) { + if !res.Equal() { + r.diffPaths = append(r.diffPaths, r.currentPath()) + } +} + +// currentPath converts the current stack into string representations that match +// the IgnorePaths and MatchPaths syntax. +func (r *diffReporter) currentPath() diffPath { + p := diffPath{types: []string{""}, json: []string{""}} + for si, s := range r.stack[1:] { + switch s := s.(type) { + case cmp.StructField: + p.types = append(p.types, s.String()[1:]) + // fetch the type information from the parent struct. + // Note: si has an offset of 1 compared to r.stack as we loop over r.stack[1:], so we don't need -1 + field := r.stack[si].Type().Field(s.Index()) + p.json = append(p.json, strings.Split(field.Tag.Get("json"), ",")[0]) + case cmp.SliceIndex: + key := fmt.Sprintf("[%d]", s.Key()) + p.types[len(p.types)-1] += key + p.json[len(p.json)-1] += key + case cmp.MapIndex: + key := fmt.Sprintf("%v", s.Key()) + if strings.ContainsAny(key, ".[]/\\") { + key = fmt.Sprintf("[%s]", key) + p.types[len(p.types)-1] += key + p.json[len(p.json)-1] += key + } else { + p.types = append(p.types, key) + p.json = append(p.json, key) + } + } + } + // Empty strings were added as the first element. If they're still empty, remove them again. + if len(p.json) > 0 && len(p.json[0]) == 0 { + p.json = p.json[1:] + p.types = p.types[1:] + } + return p +} + +func (r *diffReporter) PopStep() { + r.stack = r.stack[:len(r.stack)-1] +} + +// calculateDiff calculates the difference between two objects and returns the +// paths of the fields that do not match. +func (m *equalObjectMatcher) calculateDiff(actual interface{}) []diffPath { + var original interface{} = m.original + // Remove the wrapping Object from unstructured.Unstructured to make comparison behave similar to + // regular objects. + if u, isUnstructured := actual.(runtime.Unstructured); isUnstructured { + actual = u.UnstructuredContent() + } + if u, ok := m.original.(runtime.Unstructured); ok { + original = u.UnstructuredContent() + } + r := diffReporter{} + cmp.Diff(original, actual, cmp.Reporter(&r)) + return filterDiffPaths(*m.options, r.diffPaths) +} + +// filterDiffPaths filters the diff paths using the paths in EqualObjectOptions. +func filterDiffPaths(opts EqualObjectOptions, paths []diffPath) []diffPath { + result := []diffPath{} + + for _, p := range paths { + if len(opts.matchPaths) > 0 && !hasAnyPathPrefix(p, opts.matchPaths) { + continue + } + if hasAnyPathPrefix(p, opts.ignorePaths) { + continue + } + + result = append(result, p) + } + + return result +} + +// hasPathPrefix compares the segments of a path. +func hasPathPrefix(path []string, prefix []string) bool { + for i, p := range prefix { + if i >= len(path) { + return false + } + // return false if a segment doesn't match + if path[i] != p && (i < len(prefix)-1 || !segmentHasPrefix(path[i], p)) { + return false + } + } + return true +} + +func segmentHasPrefix(s, prefix string) bool { + return len(s) >= len(prefix) && s[0:len(prefix)] == prefix && + // if it is a prefix match, make sure the next character is a [ for array/map access + (len(s) == len(prefix) || s[len(prefix)] == '[') +} + +// hasAnyPathPrefix returns true if path matches any of the path prefixes. +// It respects the name boundaries within paths, so 'ObjectMeta.Name' does not +// match 'ObjectMeta.Namespace' for example. +func hasAnyPathPrefix(path diffPath, prefixes [][]string) bool { + for _, prefix := range prefixes { + if hasPathPrefix(path.types, prefix) || hasPathPrefix(path.json, prefix) { + return true + } + } + return false +} + +// EqualObjectOption describes an Option that can be applied to a Matcher. +type EqualObjectOption interface { + // ApplyToEqualObjectMatcher applies this configuration to the given MatchOption. + ApplyToEqualObjectMatcher(options *EqualObjectOptions) +} + +// EqualObjectOptions holds the available types of EqualObjectOptions that can be applied to a Matcher. +type EqualObjectOptions struct { + ignorePaths [][]string + matchPaths [][]string +} + +// ApplyOptions adds the passed MatchOptions to the MatchOptions struct. +func (o *EqualObjectOptions) ApplyOptions(opts []EqualObjectOption) *EqualObjectOptions { + for _, opt := range opts { + opt.ApplyToEqualObjectMatcher(o) + } + return o +} + +// IgnorePaths instructs the Matcher to ignore given paths when computing a diff. +// Paths are written in a syntax similar to Go with a few special cases. Both types and +// json/yaml field names are supported. +// +// Regular Paths: +// * "ObjectMeta.Name" +// * "metadata.name" +// Arrays: +// * "metadata.ownerReferences[0].name" +// Maps, if they do not contain any of .[]/\: +// * "metadata.labels.something" +// Maps, if they contain any of .[]/\: +// * "metadata.labels[kubernetes.io/something]" +type IgnorePaths []string + +// ApplyToEqualObjectMatcher applies this configuration to the given MatchOptions. +func (i IgnorePaths) ApplyToEqualObjectMatcher(opts *EqualObjectOptions) { + for _, p := range i { + opts.ignorePaths = append(opts.ignorePaths, strings.Split(p, ".")) + } +} + +// MatchPaths instructs the Matcher to restrict its diff to the given paths. If empty the Matcher will look at all paths. +// Paths are written in a syntax similar to Go with a few special cases. Both types and +// json/yaml field names are supported. +// +// Regular Paths: +// * "ObjectMeta.Name" +// * "metadata.name" +// Arrays: +// * "metadata.ownerReferences[0].name" +// Maps, if they do not contain any of .[]/\: +// * "metadata.labels.something" +// Maps, if they contain any of .[]/\: +// * "metadata.labels[kubernetes.io/something]" +type MatchPaths []string + +// ApplyToEqualObjectMatcher applies this configuration to the given MatchOptions. +func (i MatchPaths) ApplyToEqualObjectMatcher(opts *EqualObjectOptions) { + for _, p := range i { + opts.matchPaths = append(opts.ignorePaths, strings.Split(p, ".")) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject_test.go new file mode 100644 index 00000000000..9fe10d1779d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/equalobject_test.go @@ -0,0 +1,662 @@ +package komega + +import ( + "testing" + + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func TestEqualObjectMatcher(t *testing.T) { + cases := []struct { + name string + original client.Object + modified client.Object + options []EqualObjectOption + want bool + }{ + { + name: "succeed with equal objects", + original: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + }, + modified: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + }, + want: true, + }, + { + name: "fail with non equal objects", + original: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + }, + modified: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "somethingelse", + }, + }, + want: false, + }, + { + name: "succeeds if ignored fields do not match", + original: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: map[string]string{"somelabel": "somevalue"}, + OwnerReferences: []metav1.OwnerReference{{ + Name: "controller", + }}, + }, + }, + modified: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "somethingelse", + Labels: map[string]string{"somelabel": "anothervalue"}, + OwnerReferences: []metav1.OwnerReference{{ + Name: "another", + }}, + }, + }, + want: true, + options: []EqualObjectOption{ + IgnorePaths{ + "ObjectMeta.Name", + "ObjectMeta.CreationTimestamp", + "ObjectMeta.Labels.somelabel", + "ObjectMeta.OwnerReferences[0].Name", + "Spec.Template.ObjectMeta", + }, + }, + }, + { + name: "succeeds if ignored fields in json notation do not match", + original: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: map[string]string{"somelabel": "somevalue"}, + OwnerReferences: []metav1.OwnerReference{{ + Name: "controller", + }}, + }, + }, + modified: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "somethingelse", + Labels: map[string]string{"somelabel": "anothervalue"}, + OwnerReferences: []metav1.OwnerReference{{ + Name: "another", + }}, + }, + }, + want: true, + options: []EqualObjectOption{ + IgnorePaths{ + "metadata.name", + "metadata.creationTimestamp", + "metadata.labels.somelabel", + "metadata.ownerReferences[0].name", + "spec.template.metadata", + }, + }, + }, + { + name: "succeeds if all allowed fields match, and some others do not", + original: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + modified: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "special", + }, + }, + want: true, + options: []EqualObjectOption{ + MatchPaths{ + "ObjectMeta.Name", + }, + }, + }, + { + name: "works with unstructured.Unstructured", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "something", + "namespace": "test", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "somethingelse", + "namespace": "test", + }, + }, + }, + want: true, + options: []EqualObjectOption{ + IgnorePaths{ + "metadata.name", + }, + }, + }, + + // Test when objects are equal. + { + name: "Equal field (spec) both in original and in modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + want: true, + }, + + { + name: "Equal nested field both in original and in modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + }, + }, + want: true, + }, + + // Test when there is a difference between the objects. + { + name: "Unequal field both in original and in modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar-changed", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + want: false, + }, + { + name: "Unequal nested field both in original and modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A-Changed", + }, + }, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + }, + }, + want: false, + }, + + { + name: "Value of type map with different values", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "map": map[string]string{ + "A": "A-changed", + "B": "B", + // C missing + }, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "map": map[string]string{ + "A": "A", + // B missing + "C": "C", + }, + }, + }, + }, + want: false, + }, + + { + name: "Value of type Array or Slice with same length but different values", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "slice": []string{ + "D", + "C", + "B", + }, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "slice": []string{ + "A", + "B", + "C", + }, + }, + }, + }, + want: false, + }, + + // This tests specific behaviour in how Kubernetes marshals the zero value of metav1.Time{}. + { + name: "Creation timestamp set to empty value on both original and modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + "metadata": map[string]interface{}{ + "selfLink": "foo", + "creationTimestamp": metav1.Time{}, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + "metadata": map[string]interface{}{ + "selfLink": "foo", + "creationTimestamp": metav1.Time{}, + }, + }, + }, + want: true, + }, + + // Cases to test diff when fields exist only in modified object. + { + name: "Field only in modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + want: false, + }, + { + name: "Nested field only in modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + }, + }, + want: false, + }, + { + name: "Creation timestamp exists on modified but not on original", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + "metadata": map[string]interface{}{ + "selfLink": "foo", + "creationTimestamp": "2021-11-03T11:05:17Z", + }, + }, + }, + want: false, + }, + + // Test when fields exists only in the original object. + { + name: "Field only in original", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + want: false, + }, + { + name: "Nested field only in original", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + want: false, + }, + { + name: "Creation timestamp exists on original but not on modified", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + "metadata": map[string]interface{}{ + "selfLink": "foo", + "creationTimestamp": "2021-11-03T11:05:17Z", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + + want: false, + }, + + // Test metadata fields computed by the system or in status are compared. + { + name: "Unequal Metadata fields computed by the system or in status", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "selfLink": "foo", + "uid": "foo", + "resourceVersion": "foo", + "generation": "foo", + "managedFields": "foo", + }, + "status": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + want: false, + }, + { + name: "Unequal labels and annotations", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{}, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "foo": "bar", + }, + "annotations": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + }, + want: false, + }, + + // Ignore fields MatchOption + { + name: "Unequal metadata fields ignored by IgnorePaths MatchOption", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "test", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "test", + "selfLink": "foo", + "uid": "foo", + "resourceVersion": "foo", + "generation": "foo", + "managedFields": "foo", + }, + }, + }, + options: []EqualObjectOption{IgnoreAutogeneratedMetadata}, + want: true, + }, + { + name: "Unequal labels and annotations ignored by IgnorePaths MatchOption", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "test", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "test", + "labels": map[string]interface{}{ + "foo": "bar", + }, + "annotations": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + }, + options: []EqualObjectOption{IgnorePaths{"metadata.labels", "metadata.annotations"}}, + want: true, + }, + { + name: "Ignore fields are not compared", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{}, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "controlPlaneEndpoint": map[string]interface{}{ + "host": "", + "port": 0, + }, + }, + }, + }, + options: []EqualObjectOption{IgnorePaths{"spec.controlPlaneEndpoint"}}, + want: true, + }, + { + name: "Not-ignored fields are still compared", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{}, + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{ + "ignored": "somevalue", + "superflous": "shouldcausefailure", + }, + }, + }, + }, + options: []EqualObjectOption{IgnorePaths{"metadata.annotations.ignored"}}, + want: false, + }, + + // MatchPaths MatchOption + { + name: "Unequal metadata fields not compared by setting MatchPaths MatchOption", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + }, + "metadata": map[string]interface{}{ + "selfLink": "foo", + "uid": "foo", + }, + }, + }, + options: []EqualObjectOption{MatchPaths{"spec"}}, + want: true, + }, + + // More tests + { + name: "No changes", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + "B": "B", + "C": "C", // C only in original + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + "B": "B", + }, + }, + }, + want: false, + }, + { + name: "Many changes", + original: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + // B missing + "C": "C", // C only in original + }, + }, + }, + modified: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "A": "A", + "B": "B", + }, + }, + }, + want: false, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + g := NewWithT(t) + m := EqualObject(c.original, c.options...) + success, _ := m.Match(c.modified) + if !success { + t.Log(m.FailureMessage(c.modified)) + } + g.Expect(success).To(Equal(c.want)) + }) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/interfaces.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/interfaces.go new file mode 100644 index 00000000000..6f7e5db35b2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/interfaces.go @@ -0,0 +1,78 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package komega + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Komega is a collection of utilites for writing tests involving a mocked +// Kubernetes API. +type Komega interface { + // Get returns a function that fetches a resource and returns the occurring error. + // It can be used with gomega.Eventually() like this + // deployment := appsv1.Deployment{ ... } + // gomega.Eventually(k.Get(&deployment)).To(gomega.Succeed()) + // By calling the returned function directly it can also be used with gomega.Expect(k.Get(...)()).To(...) + Get(client.Object) func() error + + // List returns a function that lists resources and returns the occurring error. + // It can be used with gomega.Eventually() like this + // deployments := v1.DeploymentList{ ... } + // gomega.Eventually(k.List(&deployments)).To(gomega.Succeed()) + // By calling the returned function directly it can also be used as gomega.Expect(k.List(...)()).To(...) + List(client.ObjectList, ...client.ListOption) func() error + + // Update returns a function that fetches a resource, applies the provided update function and then updates the resource. + // It can be used with gomega.Eventually() like this: + // deployment := appsv1.Deployment{ ... } + // gomega.Eventually(k.Update(&deployment, func (o client.Object) { + // deployment.Spec.Replicas = 3 + // return &deployment + // })).To(gomega.Succeed()) + // By calling the returned function directly it can also be used as gomega.Expect(k.Update(...)()).To(...) + Update(client.Object, func(), ...client.UpdateOption) func() error + + // UpdateStatus returns a function that fetches a resource, applies the provided update function and then updates the resource's status. + // It can be used with gomega.Eventually() like this: + // deployment := appsv1.Deployment{ ... } + // gomega.Eventually(k.Update(&deployment, func (o client.Object) { + // deployment.Status.AvailableReplicas = 1 + // return &deployment + // })).To(gomega.Succeed()) + // By calling the returned function directly it can also be used as gomega.Expect(k.UpdateStatus(...)()).To(...) + UpdateStatus(client.Object, func(), ...client.SubResourceUpdateOption) func() error + + // Object returns a function that fetches a resource and returns the object. + // It can be used with gomega.Eventually() like this: + // deployment := appsv1.Deployment{ ... } + // gomega.Eventually(k.Object(&deployment)).To(HaveField("Spec.Replicas", gomega.Equal(pointer.Int32(3)))) + // By calling the returned function directly it can also be used as gomega.Expect(k.Object(...)()).To(...) + Object(client.Object) func() (client.Object, error) + + // ObjectList returns a function that fetches a resource and returns the object. + // It can be used with gomega.Eventually() like this: + // deployments := appsv1.DeploymentList{ ... } + // gomega.Eventually(k.ObjectList(&deployments)).To(HaveField("Items", HaveLen(1))) + // By calling the returned function directly it can also be used as gomega.Expect(k.ObjectList(...)()).To(...) + ObjectList(client.ObjectList, ...client.ListOption) func() (client.ObjectList, error) + + // WithContext returns a copy that uses the given context. + WithContext(context.Context) Komega +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega.go new file mode 100644 index 00000000000..e19d9b5f0ba --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega.go @@ -0,0 +1,117 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package komega + +import ( + "context" + + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// komega is a collection of utilites for writing tests involving a mocked +// Kubernetes API. +type komega struct { + ctx context.Context + client client.Client +} + +var _ Komega = &komega{} + +// New creates a new Komega instance with the given client. +func New(c client.Client) Komega { + return &komega{ + client: c, + ctx: context.Background(), + } +} + +// WithContext returns a copy that uses the given context. +func (k komega) WithContext(ctx context.Context) Komega { + k.ctx = ctx + return &k +} + +// Get returns a function that fetches a resource and returns the occurring error. +func (k *komega) Get(obj client.Object) func() error { + key := types.NamespacedName{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + return func() error { + return k.client.Get(k.ctx, key, obj) + } +} + +// List returns a function that lists resources and returns the occurring error. +func (k *komega) List(obj client.ObjectList, opts ...client.ListOption) func() error { + return func() error { + return k.client.List(k.ctx, obj, opts...) + } +} + +// Update returns a function that fetches a resource, applies the provided update function and then updates the resource. +func (k *komega) Update(obj client.Object, updateFunc func(), opts ...client.UpdateOption) func() error { + key := types.NamespacedName{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + return func() error { + err := k.client.Get(k.ctx, key, obj) + if err != nil { + return err + } + updateFunc() + return k.client.Update(k.ctx, obj, opts...) + } +} + +// UpdateStatus returns a function that fetches a resource, applies the provided update function and then updates the resource's status. +func (k *komega) UpdateStatus(obj client.Object, updateFunc func(), opts ...client.SubResourceUpdateOption) func() error { + key := types.NamespacedName{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + return func() error { + err := k.client.Get(k.ctx, key, obj) + if err != nil { + return err + } + updateFunc() + return k.client.Status().Update(k.ctx, obj, opts...) + } +} + +// Object returns a function that fetches a resource and returns the object. +func (k *komega) Object(obj client.Object) func() (client.Object, error) { + key := types.NamespacedName{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + return func() (client.Object, error) { + err := k.client.Get(k.ctx, key, obj) + return obj, err + } +} + +// ObjectList returns a function that fetches a resource and returns the object. +func (k *komega) ObjectList(obj client.ObjectList, opts ...client.ListOption) func() (client.ObjectList, error) { + return func() (client.ObjectList, error) { + err := k.client.List(k.ctx, obj, opts...) + return obj, err + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega_test.go new file mode 100644 index 00000000000..275610c8bb0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/komega/komega_test.go @@ -0,0 +1,138 @@ +package komega + +import ( + "testing" + + _ "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/client" + fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +func exampleDeployment() *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: pointer.Int32(5), + }, + } +} + +func createFakeClient() client.Client { + return fakeclient.NewClientBuilder(). + WithObjects(exampleDeployment()). + Build() +} + +func TestGet(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + fetched := appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test", + }, + } + g.Eventually(k.Get(&fetched)).Should(Succeed()) + + g.Expect(*fetched.Spec.Replicas).To(BeEquivalentTo(5)) +} + +func TestList(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + list := appsv1.DeploymentList{} + g.Eventually(k.List(&list)).Should(Succeed()) + + g.Expect(list.Items).To(HaveLen(1)) + depl := exampleDeployment() + g.Expect(list.Items[0]).To(And( + HaveField("ObjectMeta.Name", Equal(depl.ObjectMeta.Name)), + HaveField("ObjectMeta.Namespace", Equal(depl.ObjectMeta.Namespace)), + )) +} + +func TestUpdate(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + updateDeployment := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Eventually(k.Update(&updateDeployment, func() { + updateDeployment.Annotations = map[string]string{"updated": "true"} + })).Should(Succeed()) + + fetched := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Expect(k.Object(&fetched)()).To(HaveField("ObjectMeta.Annotations", HaveKeyWithValue("updated", "true"))) +} + +func TestUpdateStatus(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + updateDeployment := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Eventually(k.UpdateStatus(&updateDeployment, func() { + updateDeployment.Status.AvailableReplicas = 1 + })).Should(Succeed()) + + fetched := appsv1.Deployment{ + ObjectMeta: exampleDeployment().ObjectMeta, + } + g.Expect(k.Object(&fetched)()).To(HaveField("Status.AvailableReplicas", BeEquivalentTo(1))) +} + +func TestObject(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + fetched := appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test", + }, + } + g.Eventually(k.Object(&fetched)).Should(And( + Not(BeNil()), + HaveField("Spec.Replicas", Equal(pointer.Int32(5))), + )) +} + +func TestObjectList(t *testing.T) { + g := NewWithT(t) + + fc := createFakeClient() + k := New(fc) + + list := appsv1.DeploymentList{} + g.Eventually(k.ObjectList(&list)).Should(And( + Not(BeNil()), + HaveField("Items", And( + HaveLen(1), + ContainElement(HaveField("Spec.Replicas", Equal(pointer.Int32(5)))), + )), + )) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/server.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/server.go new file mode 100644 index 00000000000..4ee440df9c0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/server.go @@ -0,0 +1,376 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "fmt" + "os" + "strings" + "time" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/client/config" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +var log = logf.RuntimeLog.WithName("test-env") + +/* +It's possible to override some defaults, by setting the following environment variables: +* USE_EXISTING_CLUSTER (boolean): if set to true, envtest will use an existing cluster +* TEST_ASSET_KUBE_APISERVER (string): path to the api-server binary to use +* TEST_ASSET_ETCD (string): path to the etcd binary to use +* TEST_ASSET_KUBECTL (string): path to the kubectl binary to use +* KUBEBUILDER_ASSETS (string): directory containing the binaries to use (api-server, etcd and kubectl). Defaults to /usr/local/kubebuilder/bin. +* KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. +* KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. +* KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr +*/ +const ( + envUseExistingCluster = "USE_EXISTING_CLUSTER" + envStartTimeout = "KUBEBUILDER_CONTROLPLANE_START_TIMEOUT" + envStopTimeout = "KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT" + envAttachOutput = "KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT" + StartTimeout = 60 + StopTimeout = 60 + + defaultKubebuilderControlPlaneStartTimeout = 20 * time.Second + defaultKubebuilderControlPlaneStopTimeout = 20 * time.Second +) + +// internal types we expose as part of our public API. +type ( + // ControlPlane is the re-exported ControlPlane type from the internal testing package. + ControlPlane = controlplane.ControlPlane + + // APIServer is the re-exported APIServer from the internal testing package. + APIServer = controlplane.APIServer + + // Etcd is the re-exported Etcd from the internal testing package. + Etcd = controlplane.Etcd + + // User represents a Kubernetes user to provision for auth purposes. + User = controlplane.User + + // AuthenticatedUser represets a Kubernetes user that's been provisioned. + AuthenticatedUser = controlplane.AuthenticatedUser + + // ListenAddr indicates the address and port that the API server should listen on. + ListenAddr = process.ListenAddr + + // SecureServing contains details describing how the API server should serve + // its secure endpoint. + SecureServing = controlplane.SecureServing + + // Authn is an authentication method that can be used with the control plane to + // provision users. + Authn = controlplane.Authn + + // Arguments allows configuring a process's flags. + Arguments = process.Arguments + + // Arg is a single flag with one or more values. + Arg = process.Arg +) + +var ( + // EmptyArguments constructs a new set of flags with nothing set. + // + // This is mostly useful for testing helper methods -- you'll want to call + // Configure on the APIServer (or etcd) to configure their arguments. + EmptyArguments = process.EmptyArguments +) + +// Environment creates a Kubernetes test environment that will start / stop the Kubernetes control plane and +// install extension APIs. +type Environment struct { + // ControlPlane is the ControlPlane including the apiserver and etcd + ControlPlane controlplane.ControlPlane + + // Scheme is used to determine if conversion webhooks should be enabled + // for a particular CRD / object. + // + // Conversion webhooks are going to be enabled if an object in the scheme + // implements Hub and Spoke conversions. + // + // If nil, scheme.Scheme is used. + Scheme *runtime.Scheme + + // Config can be used to talk to the apiserver. It's automatically + // populated if not set using the standard controller-runtime config + // loading. + Config *rest.Config + + // CRDInstallOptions are the options for installing CRDs. + CRDInstallOptions CRDInstallOptions + + // WebhookInstallOptions are the options for installing webhooks. + WebhookInstallOptions WebhookInstallOptions + + // ErrorIfCRDPathMissing provides an interface for the underlying + // CRDInstallOptions.ErrorIfPathMissing. It prevents silent failures + // for missing CRD paths. + ErrorIfCRDPathMissing bool + + // CRDs is a list of CRDs to install. + // If both this field and CRDs field in CRDInstallOptions are specified, the + // values are merged. + CRDs []*apiextensionsv1.CustomResourceDefinition + + // CRDDirectoryPaths is a list of paths containing CRD yaml or json configs. + // If both this field and Paths field in CRDInstallOptions are specified, the + // values are merged. + CRDDirectoryPaths []string + + // BinaryAssetsDirectory is the path where the binaries required for the envtest are + // located in the local environment. This field can be overridden by setting KUBEBUILDER_ASSETS. + BinaryAssetsDirectory string + + // UseExistingCluster indicates that this environments should use an + // existing kubeconfig, instead of trying to stand up a new control plane. + // This is useful in cases that need aggregated API servers and the like. + UseExistingCluster *bool + + // ControlPlaneStartTimeout is the maximum duration each controlplane component + // may take to start. It defaults to the KUBEBUILDER_CONTROLPLANE_START_TIMEOUT + // environment variable or 20 seconds if unspecified + ControlPlaneStartTimeout time.Duration + + // ControlPlaneStopTimeout is the maximum duration each controlplane component + // may take to stop. It defaults to the KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT + // environment variable or 20 seconds if unspecified + ControlPlaneStopTimeout time.Duration + + // KubeAPIServerFlags is the set of flags passed while starting the api server. + // + // Deprecated: use ControlPlane.GetAPIServer().Configure() instead. + KubeAPIServerFlags []string + + // AttachControlPlaneOutput indicates if control plane output will be attached to os.Stdout and os.Stderr. + // Enable this to get more visibility of the testing control plane. + // It respect KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT environment variable. + AttachControlPlaneOutput bool +} + +// Stop stops a running server. +// Previously installed CRDs, as listed in CRDInstallOptions.CRDs, will be uninstalled +// if CRDInstallOptions.CleanUpAfterUse are set to true. +func (te *Environment) Stop() error { + if te.CRDInstallOptions.CleanUpAfterUse { + if err := UninstallCRDs(te.Config, te.CRDInstallOptions); err != nil { + return err + } + } + + if err := te.WebhookInstallOptions.Cleanup(); err != nil { + return err + } + + if te.useExistingCluster() { + return nil + } + + return te.ControlPlane.Stop() +} + +// Start starts a local Kubernetes server and updates te.ApiserverPort with the port it is listening on. +func (te *Environment) Start() (*rest.Config, error) { + if te.useExistingCluster() { + log.V(1).Info("using existing cluster") + if te.Config == nil { + // we want to allow people to pass in their own config, so + // only load a config if it hasn't already been set. + log.V(1).Info("automatically acquiring client configuration") + + var err error + te.Config, err = config.GetConfig() + if err != nil { + return nil, fmt.Errorf("unable to get configuration for existing cluster: %w", err) + } + } + } else { + apiServer := te.ControlPlane.GetAPIServer() + if len(apiServer.Args) == 0 { //nolint:staticcheck + // pass these through separately from above in case something like + // AddUser defaults APIServer. + // + // TODO(directxman12): if/when we feel like making a bigger + // breaking change here, just make APIServer and Etcd non-pointers + // in ControlPlane. + + // NB(directxman12): we still pass these in so that things work if the + // user manually specifies them, but in most cases we expect them to + // be nil so that we use the new .Configure() logic. + apiServer.Args = te.KubeAPIServerFlags //nolint:staticcheck + } + if te.ControlPlane.Etcd == nil { + te.ControlPlane.Etcd = &controlplane.Etcd{} + } + + if os.Getenv(envAttachOutput) == "true" { + te.AttachControlPlaneOutput = true + } + if te.AttachControlPlaneOutput { + if apiServer.Out == nil { + apiServer.Out = os.Stdout + } + if apiServer.Err == nil { + apiServer.Err = os.Stderr + } + if te.ControlPlane.Etcd.Out == nil { + te.ControlPlane.Etcd.Out = os.Stdout + } + if te.ControlPlane.Etcd.Err == nil { + te.ControlPlane.Etcd.Err = os.Stderr + } + } + + apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory) + te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory) + te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory) + + if err := te.defaultTimeouts(); err != nil { + return nil, fmt.Errorf("failed to default controlplane timeouts: %w", err) + } + te.ControlPlane.Etcd.StartTimeout = te.ControlPlaneStartTimeout + te.ControlPlane.Etcd.StopTimeout = te.ControlPlaneStopTimeout + apiServer.StartTimeout = te.ControlPlaneStartTimeout + apiServer.StopTimeout = te.ControlPlaneStopTimeout + + log.V(1).Info("starting control plane") + if err := te.startControlPlane(); err != nil { + return nil, fmt.Errorf("unable to start control plane itself: %w", err) + } + + // Create the *rest.Config for creating new clients + baseConfig := &rest.Config{ + // gotta go fast during tests -- we don't really care about overwhelming our test API server + QPS: 1000.0, + Burst: 2000.0, + } + + adminInfo := User{Name: "admin", Groups: []string{"system:masters"}} + adminUser, err := te.ControlPlane.AddUser(adminInfo, baseConfig) + if err != nil { + return te.Config, fmt.Errorf("unable to provision admin user: %w", err) + } + te.Config = adminUser.Config() + } + + // Set the default scheme if nil. + if te.Scheme == nil { + te.Scheme = scheme.Scheme + } + + // Call PrepWithoutInstalling to setup certificates first + // and have them available to patch CRD conversion webhook as well. + if err := te.WebhookInstallOptions.PrepWithoutInstalling(); err != nil { + return nil, err + } + + log.V(1).Info("installing CRDs") + te.CRDInstallOptions.CRDs = mergeCRDs(te.CRDInstallOptions.CRDs, te.CRDs) + te.CRDInstallOptions.Paths = mergePaths(te.CRDInstallOptions.Paths, te.CRDDirectoryPaths) + te.CRDInstallOptions.ErrorIfPathMissing = te.ErrorIfCRDPathMissing + te.CRDInstallOptions.WebhookOptions = te.WebhookInstallOptions + crds, err := InstallCRDs(te.Config, te.CRDInstallOptions) + if err != nil { + return te.Config, fmt.Errorf("unable to install CRDs onto control plane: %w", err) + } + te.CRDs = crds + + log.V(1).Info("installing webhooks") + if err := te.WebhookInstallOptions.Install(te.Config); err != nil { + return nil, fmt.Errorf("unable to install webhooks onto control plane: %w", err) + } + return te.Config, nil +} + +// AddUser provisions a new user for connecting to this Environment. The user will +// have the specified name & belong to the specified groups. +// +// If you specify a "base" config, the returned REST Config will contain those +// settings as well as any required by the authentication method. You can use +// this to easily specify options like QPS. +// +// This is effectively a convinience alias for ControlPlane.AddUser -- see that +// for more low-level details. +func (te *Environment) AddUser(user User, baseConfig *rest.Config) (*AuthenticatedUser, error) { + return te.ControlPlane.AddUser(user, baseConfig) +} + +func (te *Environment) startControlPlane() error { + numTries, maxRetries := 0, 5 + var err error + for ; numTries < maxRetries; numTries++ { + // Start the control plane - retry if it fails + err = te.ControlPlane.Start() + if err == nil { + break + } + log.Error(err, "unable to start the controlplane", "tries", numTries) + } + if numTries == maxRetries { + return fmt.Errorf("failed to start the controlplane. retried %d times: %w", numTries, err) + } + return nil +} + +func (te *Environment) defaultTimeouts() error { + var err error + if te.ControlPlaneStartTimeout == 0 { + if envVal := os.Getenv(envStartTimeout); envVal != "" { + te.ControlPlaneStartTimeout, err = time.ParseDuration(envVal) + if err != nil { + return err + } + } else { + te.ControlPlaneStartTimeout = defaultKubebuilderControlPlaneStartTimeout + } + } + + if te.ControlPlaneStopTimeout == 0 { + if envVal := os.Getenv(envStopTimeout); envVal != "" { + te.ControlPlaneStopTimeout, err = time.ParseDuration(envVal) + if err != nil { + return err + } + } else { + te.ControlPlaneStopTimeout = defaultKubebuilderControlPlaneStopTimeout + } + } + return nil +} + +func (te *Environment) useExistingCluster() bool { + if te.UseExistingCluster == nil { + return strings.ToLower(os.Getenv(envUseExistingCluster)) == "true" + } + return *te.UseExistingCluster +} + +// DefaultKubeAPIServerFlags exposes the default args for the APIServer so that +// you can use those to append your own additional arguments. +// +// Deprecated: use APIServer.Configure() instead. +var DefaultKubeAPIServerFlags = controlplane.APIServerDefaultArgs //nolint:staticcheck diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd3.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd3.yaml new file mode 100644 index 00000000000..479a6e56458 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd3.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: configs.foo.example.com +spec: + group: foo.example.com + names: + kind: Config + plural: configs + scope: Namespaced + versions: + - name: "v1beta1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd_unserved.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd_unserved.yaml new file mode 100644 index 00000000000..09fac4f0804 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crds/examplecrd_unserved.yaml @@ -0,0 +1,88 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + creationTimestamp: null + name: frigates.ship.example.com +spec: + group: ship.example.com + names: + kind: Frigate + listKind: FrigateList + plural: frigates + singular: frigate + scope: Namespaced + subresources: + status: {} + versions: + - name: v1 + served: false + storage: true + schema: + openAPIV3Schema: + description: Frigate is the Schema for the frigates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: FrigateSpec defines the desired state of Frigate + properties: + foo: + description: Foo is an example field of Frigate. Edit Frigate_types.go + to remove/update + type: string + type: object + status: + description: FrigateStatus defines the observed state of Frigate + type: object + type: object + - name: v1beta1 + served: false + storage: false + schema: + openAPIV3Schema: + description: Frigate is the Schema for the frigates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: FrigateSpec defines the desired state of Frigate + properties: + foo: + description: Foo is an example field of Frigate. Edit Frigate_types.go + to remove/update + type: string + type: object + status: + description: FrigateStatus defines the observed state of Frigate + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_original/example_multiversion_crd1.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_original/example_multiversion_crd1.yaml new file mode 100644 index 00000000000..5dead8186a0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_original/example_multiversion_crd1.yaml @@ -0,0 +1,61 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: drivers.crew.example.com +spec: + group: crew.example.com + names: + kind: Driver + plural: drivers + scope: "" + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object + - name: v2 + served: true + storage: false + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_updated/example_multiversion_crd1_one_more_version.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_updated/example_multiversion_crd1_one_more_version.yaml new file mode 100644 index 00000000000..9eb0ec91a26 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/crdv1_updated/example_multiversion_crd1_one_more_version.yaml @@ -0,0 +1,83 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: drivers.crew.example.com +spec: + group: crew.example.com + names: + kind: Driver + plural: drivers + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object + - name: v2 + served: true + storage: false + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object + - name: v3 + served: true + storage: false + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/example_multiversion_crd1.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/example_multiversion_crd1.yaml new file mode 100644 index 00000000000..5bb2d73f698 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/example_multiversion_crd1.yaml @@ -0,0 +1,62 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: drivers.crew.example.com +spec: + group: crew.example.com + names: + kind: Driver + plural: drivers + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object + - name: v2 + served: true + storage: false + schema: + openAPIV3Schema: + description: Driver is the Schema for the drivers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + spec: + type: object + status: + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd.yaml new file mode 100644 index 00000000000..f1638f83102 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bazs.qux.example.com +spec: + group: qux.example.com + names: + kind: Baz + plural: bazs + scope: Namespaced + versions: + - name: "v1beta1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd_v1.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd_v1.yaml new file mode 100644 index 00000000000..e2bddbc528b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/examplecrd_v1.yaml @@ -0,0 +1,17 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: foos.bar.example.com +spec: + group: bar.example.com + names: + kind: Foo + plural: foos + scope: Namespaced + versions: + - name: "v1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/multiplecrds.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/multiplecrds.yaml new file mode 100644 index 00000000000..a855140ead3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/multiplecrds.yaml @@ -0,0 +1,37 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: captains.crew.example.com +spec: + group: crew.example.com + names: + kind: Captain + plural: captains + scope: Namespaced + versions: + - name: "v1beta1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: firstmates.crew.example.com +spec: + group: crew.example.com + names: + kind: FirstMate + plural: firstmates + scope: Namespaced + versions: + - name: "v1beta1" + storage: true + served: true + schema: + openAPIV3Schema: + type: object +--- diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/notcrd.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/notcrd.yaml new file mode 100644 index 00000000000..a0f1f582c87 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/notcrd.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/webhooks/manifests.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/webhooks/manifests.yaml new file mode 100644 index 00000000000..72437905cdc --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/testdata/webhooks/manifests.yaml @@ -0,0 +1,101 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /mutate-v1 + failurePolicy: Fail + name: mpods.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration2 +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /mutate-v1 + failurePolicy: Fail + name: mpods2.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /validate-v1 + failurePolicy: Fail + name: vpods.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration2 +webhooks: +- clientConfig: + caBundle: Cg== + service: + name: webhook-service + namespace: system + path: /validate-v1 + failurePolicy: Fail + name: vpods2.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods + diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go new file mode 100644 index 00000000000..f7e43a14802 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go @@ -0,0 +1,445 @@ +/* +Copyright 2019 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "context" + "fmt" + "net" + "os" + "path/filepath" + "time" + + admissionv1 "k8s.io/api/admissionregistration/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/yaml" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/addr" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/certs" +) + +// WebhookInstallOptions are the options for installing mutating or validating webhooks. +type WebhookInstallOptions struct { + // Paths is a list of paths to the directories or files containing the mutating or validating webhooks yaml or json configs. + Paths []string + + // MutatingWebhooks is a list of MutatingWebhookConfigurations to install + MutatingWebhooks []*admissionv1.MutatingWebhookConfiguration + + // ValidatingWebhooks is a list of ValidatingWebhookConfigurations to install + ValidatingWebhooks []*admissionv1.ValidatingWebhookConfiguration + + // IgnoreErrorIfPathMissing will ignore an error if a DirectoryPath does not exist when set to true + IgnoreErrorIfPathMissing bool + + // LocalServingHost is the host for serving webhooks on. + // it will be automatically populated + LocalServingHost string + + // LocalServingPort is the allocated port for serving webhooks on. + // it will be automatically populated by a random available local port + LocalServingPort int + + // LocalServingCertDir is the allocated directory for serving certificates. + // it will be automatically populated by the local temp dir + LocalServingCertDir string + + // CAData is the CA that can be used to trust the serving certificates in LocalServingCertDir. + LocalServingCAData []byte + + // LocalServingHostExternalName is the hostname to use to reach the webhook server. + LocalServingHostExternalName string + + // MaxTime is the max time to wait + MaxTime time.Duration + + // PollInterval is the interval to check + PollInterval time.Duration +} + +// ModifyWebhookDefinitions modifies webhook definitions by: +// - applying CABundle based on the provided tinyca +// - if webhook client config uses service spec, it's removed and replaced with direct url. +func (o *WebhookInstallOptions) ModifyWebhookDefinitions() error { + caData := o.LocalServingCAData + + // generate host port. + hostPort, err := o.generateHostPort() + if err != nil { + return err + } + + for i := range o.MutatingWebhooks { + for j := range o.MutatingWebhooks[i].Webhooks { + updateClientConfig(&o.MutatingWebhooks[i].Webhooks[j].ClientConfig, hostPort, caData) + } + } + + for i := range o.ValidatingWebhooks { + for j := range o.ValidatingWebhooks[i].Webhooks { + updateClientConfig(&o.ValidatingWebhooks[i].Webhooks[j].ClientConfig, hostPort, caData) + } + } + return nil +} + +func updateClientConfig(cc *admissionv1.WebhookClientConfig, hostPort string, caData []byte) { + cc.CABundle = caData + if cc.Service != nil && cc.Service.Path != nil { + url := fmt.Sprintf("https://%s/%s", hostPort, *cc.Service.Path) + cc.URL = &url + cc.Service = nil + } +} + +func (o *WebhookInstallOptions) generateHostPort() (string, error) { + if o.LocalServingPort == 0 { + port, host, err := addr.Suggest(o.LocalServingHost) + if err != nil { + return "", fmt.Errorf("unable to grab random port for serving webhooks on: %w", err) + } + o.LocalServingPort = port + o.LocalServingHost = host + } + host := o.LocalServingHostExternalName + if host == "" { + host = o.LocalServingHost + } + return net.JoinHostPort(host, fmt.Sprintf("%d", o.LocalServingPort)), nil +} + +// PrepWithoutInstalling does the setup parts of Install (populating host-port, +// setting up CAs, etc), without actually truing to do anything with webhook +// definitions. This is largely useful for internal testing of +// controller-runtime, where we need a random host-port & caData for webhook +// tests, but may be useful in similar scenarios. +func (o *WebhookInstallOptions) PrepWithoutInstalling() error { + if err := o.setupCA(); err != nil { + return err + } + + if err := parseWebhook(o); err != nil { + return err + } + + return o.ModifyWebhookDefinitions() +} + +// Install installs specified webhooks to the API server. +func (o *WebhookInstallOptions) Install(config *rest.Config) error { + defaultWebhookOptions(o) + + if len(o.LocalServingCAData) == 0 { + if err := o.PrepWithoutInstalling(); err != nil { + return err + } + } + + if err := createWebhooks(config, o.MutatingWebhooks, o.ValidatingWebhooks); err != nil { + return err + } + + return WaitForWebhooks(config, o.MutatingWebhooks, o.ValidatingWebhooks, *o) +} + +// Cleanup cleans up cert directories. +func (o *WebhookInstallOptions) Cleanup() error { + if o.LocalServingCertDir != "" { + return os.RemoveAll(o.LocalServingCertDir) + } + return nil +} + +// defaultWebhookOptions sets the default values for Webhooks. +func defaultWebhookOptions(o *WebhookInstallOptions) { + if o.MaxTime == 0 { + o.MaxTime = defaultMaxWait + } + if o.PollInterval == 0 { + o.PollInterval = defaultPollInterval + } +} + +// WaitForWebhooks waits for the Webhooks to be available through API server. +func WaitForWebhooks(config *rest.Config, + mutatingWebhooks []*admissionv1.MutatingWebhookConfiguration, + validatingWebhooks []*admissionv1.ValidatingWebhookConfiguration, + options WebhookInstallOptions) error { + waitingFor := map[schema.GroupVersionKind]*sets.Set[string]{} + + for _, hook := range mutatingWebhooks { + h := hook + gvk, err := apiutil.GVKForObject(h, scheme.Scheme) + if err != nil { + return fmt.Errorf("unable to get gvk for MutatingWebhookConfiguration %s: %w", hook.GetName(), err) + } + + if _, ok := waitingFor[gvk]; !ok { + waitingFor[gvk] = &sets.Set[string]{} + } + waitingFor[gvk].Insert(h.GetName()) + } + + for _, hook := range validatingWebhooks { + h := hook + gvk, err := apiutil.GVKForObject(h, scheme.Scheme) + if err != nil { + return fmt.Errorf("unable to get gvk for ValidatingWebhookConfiguration %s: %w", hook.GetName(), err) + } + + if _, ok := waitingFor[gvk]; !ok { + waitingFor[gvk] = &sets.Set[string]{} + } + waitingFor[gvk].Insert(hook.GetName()) + } + + // Poll until all resources are found in discovery + p := &webhookPoller{config: config, waitingFor: waitingFor} + return wait.PollUntilContextTimeout(context.TODO(), options.PollInterval, options.MaxTime, true, p.poll) +} + +// poller checks if all the resources have been found in discovery, and returns false if not. +type webhookPoller struct { + // config is used to get discovery + config *rest.Config + + // waitingFor is the map of resources keyed by group version that have not yet been found in discovery + waitingFor map[schema.GroupVersionKind]*sets.Set[string] +} + +// poll checks if all the resources have been found in discovery, and returns false if not. +func (p *webhookPoller) poll(ctx context.Context) (done bool, err error) { + // Create a new clientset to avoid any client caching of discovery + c, err := client.New(p.config, client.Options{}) + if err != nil { + return false, err + } + + allFound := true + for gvk, names := range p.waitingFor { + if names.Len() == 0 { + delete(p.waitingFor, gvk) + continue + } + for _, name := range names.UnsortedList() { + var obj = &unstructured.Unstructured{} + obj.SetGroupVersionKind(gvk) + err := c.Get(context.Background(), client.ObjectKey{ + Namespace: "", + Name: name, + }, obj) + + if err == nil { + names.Delete(name) + } + + if apierrors.IsNotFound(err) { + allFound = false + } + if err != nil { + return false, err + } + } + } + return allFound, nil +} + +// setupCA creates CA for testing and writes them to disk. +func (o *WebhookInstallOptions) setupCA() error { + hookCA, err := certs.NewTinyCA() + if err != nil { + return fmt.Errorf("unable to set up webhook CA: %w", err) + } + + names := []string{"localhost", o.LocalServingHost, o.LocalServingHostExternalName} + hookCert, err := hookCA.NewServingCert(names...) + if err != nil { + return fmt.Errorf("unable to set up webhook serving certs: %w", err) + } + + localServingCertsDir, err := os.MkdirTemp("", "envtest-serving-certs-") + o.LocalServingCertDir = localServingCertsDir + if err != nil { + return fmt.Errorf("unable to create directory for webhook serving certs: %w", err) + } + + certData, keyData, err := hookCert.AsBytes() + if err != nil { + return fmt.Errorf("unable to marshal webhook serving certs: %w", err) + } + + if err := os.WriteFile(filepath.Join(localServingCertsDir, "tls.crt"), certData, 0640); err != nil { //nolint:gosec + return fmt.Errorf("unable to write webhook serving cert to disk: %w", err) + } + if err := os.WriteFile(filepath.Join(localServingCertsDir, "tls.key"), keyData, 0640); err != nil { //nolint:gosec + return fmt.Errorf("unable to write webhook serving key to disk: %w", err) + } + + o.LocalServingCAData = certData + return err +} + +func createWebhooks(config *rest.Config, mutHooks []*admissionv1.MutatingWebhookConfiguration, valHooks []*admissionv1.ValidatingWebhookConfiguration) error { + cs, err := client.New(config, client.Options{}) + if err != nil { + return err + } + + // Create each webhook + for _, hook := range mutHooks { + hook := hook + log.V(1).Info("installing mutating webhook", "webhook", hook.GetName()) + if err := ensureCreated(cs, hook); err != nil { + return err + } + } + for _, hook := range valHooks { + hook := hook + log.V(1).Info("installing validating webhook", "webhook", hook.GetName()) + if err := ensureCreated(cs, hook); err != nil { + return err + } + } + return nil +} + +// ensureCreated creates or update object if already exists in the cluster. +func ensureCreated(cs client.Client, obj client.Object) error { + existing := obj.DeepCopyObject().(client.Object) + err := cs.Get(context.Background(), client.ObjectKey{Name: obj.GetName()}, existing) + switch { + case apierrors.IsNotFound(err): + if err := cs.Create(context.Background(), obj); err != nil { + return err + } + case err != nil: + return err + default: + log.V(1).Info("Webhook configuration already exists, updating", "webhook", obj.GetName()) + obj.SetResourceVersion(existing.GetResourceVersion()) + if err := cs.Update(context.Background(), obj); err != nil { + return err + } + } + return nil +} + +// parseWebhook reads the directories or files of Webhooks in options.Paths and adds the Webhook structs to options. +func parseWebhook(options *WebhookInstallOptions) error { + if len(options.Paths) > 0 { + for _, path := range options.Paths { + _, err := os.Stat(path) + if options.IgnoreErrorIfPathMissing && os.IsNotExist(err) { + continue // skip this path + } + if !options.IgnoreErrorIfPathMissing && os.IsNotExist(err) { + return err // treat missing path as error + } + mutHooks, valHooks, err := readWebhooks(path) + if err != nil { + return err + } + options.MutatingWebhooks = append(options.MutatingWebhooks, mutHooks...) + options.ValidatingWebhooks = append(options.ValidatingWebhooks, valHooks...) + } + } + return nil +} + +// readWebhooks reads the Webhooks from files and Unmarshals them into structs +// returns slice of mutating and validating webhook configurations. +func readWebhooks(path string) ([]*admissionv1.MutatingWebhookConfiguration, []*admissionv1.ValidatingWebhookConfiguration, error) { + // Get the webhook files + var files []string + var err error + log.V(1).Info("reading Webhooks from path", "path", path) + info, err := os.Stat(path) + if err != nil { + return nil, nil, err + } + if !info.IsDir() { + path, files = filepath.Dir(path), []string{info.Name()} + } else { + entries, err := os.ReadDir(path) + if err != nil { + return nil, nil, err + } + for _, e := range entries { + files = append(files, e.Name()) + } + } + + // file extensions that may contain Webhooks + resourceExtensions := sets.NewString(".json", ".yaml", ".yml") + + var mutHooks []*admissionv1.MutatingWebhookConfiguration + var valHooks []*admissionv1.ValidatingWebhookConfiguration + for _, file := range files { + // Only parse allowlisted file types + if !resourceExtensions.Has(filepath.Ext(file)) { + continue + } + + // Unmarshal Webhooks from file into structs + docs, err := readDocuments(filepath.Join(path, file)) + if err != nil { + return nil, nil, err + } + + for _, doc := range docs { + var generic metav1.PartialObjectMetadata + if err = yaml.Unmarshal(doc, &generic); err != nil { + return nil, nil, err + } + + const ( + admissionregv1 = "admissionregistration.k8s.io/v1" + ) + switch { + case generic.Kind == "MutatingWebhookConfiguration": + if generic.APIVersion != admissionregv1 { + return nil, nil, fmt.Errorf("only v1 is supported right now for MutatingWebhookConfiguration (name: %s)", generic.Name) + } + hook := &admissionv1.MutatingWebhookConfiguration{} + if err := yaml.Unmarshal(doc, hook); err != nil { + return nil, nil, err + } + mutHooks = append(mutHooks, hook) + case generic.Kind == "ValidatingWebhookConfiguration": + if generic.APIVersion != admissionregv1 { + return nil, nil, fmt.Errorf("only v1 is supported right now for ValidatingWebhookConfiguration (name: %s)", generic.Name) + } + hook := &admissionv1.ValidatingWebhookConfiguration{} + if err := yaml.Unmarshal(doc, hook); err != nil { + return nil, nil, err + } + valHooks = append(valHooks, hook) + default: + continue + } + } + + log.V(1).Info("read webhooks from file", "file", file) + } + return mutHooks, valHooks, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook_test.go new file mode 100644 index 00000000000..2cbc9ab9c8e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/envtest/webhook_test.go @@ -0,0 +1,124 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package envtest + +import ( + "context" + "crypto/tls" + "path/filepath" + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +var _ = Describe("Test", func() { + + Describe("Webhook", func() { + It("should reject create request for webhook that rejects all requests", func() { + m, err := manager.New(env.Config, manager.Options{ + Port: env.WebhookInstallOptions.LocalServingPort, + Host: env.WebhookInstallOptions.LocalServingHost, + CertDir: env.WebhookInstallOptions.LocalServingCertDir, + TLSOpts: []func(*tls.Config){ + func(config *tls.Config) {}, + }, + }) // we need manager here just to leverage manager.SetFields + Expect(err).NotTo(HaveOccurred()) + server := m.GetWebhookServer() + server.Register("/failing", &webhook.Admission{Handler: &rejectingValidator{}}) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + _ = server.Start(ctx) + }() + + c, err := client.New(env.Config, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + obj := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + + Eventually(func() bool { + err = c.Create(context.TODO(), obj) + return err != nil && strings.HasSuffix(err.Error(), "Always denied") && apierrors.ReasonForError(err) == metav1.StatusReasonForbidden + }, 1*time.Second).Should(BeTrue()) + + cancel() + }) + + It("should load webhooks from directory", func() { + installOptions := WebhookInstallOptions{ + Paths: []string{filepath.Join("testdata", "webhooks")}, + } + err := parseWebhook(&installOptions) + Expect(err).NotTo(HaveOccurred()) + Expect(len(installOptions.MutatingWebhooks)).To(Equal(2)) + Expect(len(installOptions.ValidatingWebhooks)).To(Equal(2)) + }) + + It("should load webhooks from files", func() { + installOptions := WebhookInstallOptions{ + Paths: []string{filepath.Join("testdata", "webhooks", "manifests.yaml")}, + } + err := parseWebhook(&installOptions) + Expect(err).NotTo(HaveOccurred()) + Expect(len(installOptions.MutatingWebhooks)).To(Equal(2)) + Expect(len(installOptions.ValidatingWebhooks)).To(Equal(2)) + }) + }) +}) + +type rejectingValidator struct { +} + +func (v *rejectingValidator) Handle(_ context.Context, _ admission.Request) admission.Response { + return admission.Denied("Always denied") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/event/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/event/doc.go new file mode 100644 index 00000000000..adba3bbc16e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/event/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package event contains the definitions for the Event types produced by source.Sources and transformed into +reconcile.Requests by handler.EventHandler. + +You should rarely need to work with these directly -- instead, use Controller.Watch with +source.Sources and handler.EventHandlers. + +Events generally contain both a full runtime.Object that caused the event, as well +as a direct handle to that object's metadata. This saves a lot of typecasting in +code that works with Events. +*/ +package event diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/event/event.go b/third_party/sigs.k8s.io/controller-runtime/pkg/event/event.go new file mode 100644 index 00000000000..271b3c00fb3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/event/event.go @@ -0,0 +1,55 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package event + +import "sigs.k8s.io/controller-runtime/pkg/client" + +// CreateEvent is an event where a Kubernetes object was created. CreateEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type CreateEvent struct { + // Object is the object from the event + Object client.Object +} + +// UpdateEvent is an event where a Kubernetes object was updated. UpdateEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type UpdateEvent struct { + // ObjectOld is the object from the event + ObjectOld client.Object + + // ObjectNew is the object from the event + ObjectNew client.Object +} + +// DeleteEvent is an event where a Kubernetes object was deleted. DeleteEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type DeleteEvent struct { + // Object is the object from the event + Object client.Object + + // DeleteStateUnknown is true if the Delete event was missed but we identified the object + // as having been deleted. + DeleteStateUnknown bool +} + +// GenericEvent is an event where the operation type is unknown (e.g. polling or event originating outside the cluster). +// GenericEvent should be generated by a source.Source and transformed into a reconcile.Request by an +// handler.EventHandler. +type GenericEvent struct { + // Object is the object from the event + Object client.Object +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer.go b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer.go new file mode 100644 index 00000000000..10c5645dbe3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer.go @@ -0,0 +1,79 @@ +/* +Copyright 2021 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package finalizer + +import ( + "context" + "fmt" + + kerrors "k8s.io/apimachinery/pkg/util/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +type finalizers map[string]Finalizer + +// Result struct holds information about what parts of an object were updated by finalizer(s). +type Result struct { + // Updated will be true if at least one of the object's non-status field + // was updated by some registered finalizer. + Updated bool + // StatusUpdated will be true if at least one of the object's status' fields + // was updated by some registered finalizer. + StatusUpdated bool +} + +// NewFinalizers returns the Finalizers interface. +func NewFinalizers() Finalizers { + return finalizers{} +} + +func (f finalizers) Register(key string, finalizer Finalizer) error { + if _, ok := f[key]; ok { + return fmt.Errorf("finalizer for key %q already registered", key) + } + f[key] = finalizer + return nil +} + +func (f finalizers) Finalize(ctx context.Context, obj client.Object) (Result, error) { + var ( + res Result + errList []error + ) + res.Updated = false + for key, finalizer := range f { + if dt := obj.GetDeletionTimestamp(); dt.IsZero() && !controllerutil.ContainsFinalizer(obj, key) { + controllerutil.AddFinalizer(obj, key) + res.Updated = true + } else if !dt.IsZero() && controllerutil.ContainsFinalizer(obj, key) { + finalizerRes, err := finalizer.Finalize(ctx, obj) + if err != nil { + // Even when the finalizer fails, it may need to signal to update the primary + // object (e.g. it may set a condition and need a status update). + res.Updated = res.Updated || finalizerRes.Updated + res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated + errList = append(errList, fmt.Errorf("finalizer %q failed: %w", key, err)) + } else { + // If the finalizer succeeds, we remove the finalizer from the primary + // object's metadata, so we know it will need an update. + res.Updated = true + controllerutil.RemoveFinalizer(obj, key) + // The finalizer may have updated the status too. + res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated + } + } + } + return res, kerrors.NewAggregate(errList) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer_test.go new file mode 100644 index 00000000000..eb85bd020a2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/finalizer_test.go @@ -0,0 +1,215 @@ +package finalizer + +import ( + "context" + "fmt" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type mockFinalizer struct { + result Result + err error +} + +func (f mockFinalizer) Finalize(context.Context, client.Object) (Result, error) { + return f.result, f.err +} + +func TestFinalizer(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Finalizer Suite") +} + +var _ = Describe("TestFinalizer", func() { + var err error + var pod *corev1.Pod + var finalizers Finalizers + var f mockFinalizer + BeforeEach(func() { + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{}, + } + finalizers = NewFinalizers() + f = mockFinalizer{} + }) + Describe("Register", func() { + It("successfully registers a finalizer", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + }) + + It("should fail when trying to register a finalizer that was already registered", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + // calling Register again with the same key should return an error + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).NotTo(BeNil()) + Expect(err.Error()).To(ContainSubstring("already registered")) + + }) + }) + + Describe("Finalize", func() { + It("successfully finalizes and returns true for Updated when deletion timestamp is nil and finalizer does not exist", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + pod.DeletionTimestamp = nil + pod.Finalizers = []string{} + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeTrue()) + // when deletion timestamp is nil and finalizer is not present, the registered finalizer would be added to the obj + Expect(len(pod.Finalizers)).To(Equal(1)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) + + }) + + It("successfully finalizes and returns true for Updated when deletion timestamp is not nil and the finalizer exists", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeTrue()) + // finalizer will be removed from the obj upon successful finalization + Expect(len(pod.Finalizers)).To(Equal(0)) + }) + + It("should return no error and return false for Updated when deletion timestamp is nil and finalizer doesn't exist", func() { + pod.DeletionTimestamp = nil + pod.Finalizers = []string{} + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(0)) + + }) + + It("should return no error and return false for Updated when deletion timestamp is not nil and the finalizer doesn't exist", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + pod.Finalizers = []string{} + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(0)) + + }) + + It("successfully finalizes multiple finalizers and returns true for Updated when deletion timestamp is not nil and the finalizer exists", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + err = finalizers.Register("finalizers.sigs.k8s.io/newtestfinalizer", f) + Expect(err).To(BeNil()) + + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer", "finalizers.sigs.k8s.io/newtestfinalizer"} + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(0)) + }) + + It("should return result as false and a non-nil error", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} + + f.result.Updated = false + f.result.StatusUpdated = false + f.err = fmt.Errorf("finalizer failed for %q", pod.Finalizers[0]) + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(result.Updated).To(BeFalse()) + Expect(result.StatusUpdated).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(1)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) + }) + + It("should return expected result values and error values when registering multiple finalizers", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + pod.Finalizers = []string{ + "finalizers.sigs.k8s.io/testfinalizer1", + "finalizers.sigs.k8s.io/testfinalizer2", + "finalizers.sigs.k8s.io/testfinalizer3", + } + + // registering multiple finalizers with different return values + // test for Updated as true, and nil error + f.result.Updated = true + f.result.StatusUpdated = false + f.err = nil + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer1", f) + Expect(err).To(BeNil()) + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeFalse()) + // `finalizers.sigs.k8s.io/testfinalizer1` will be removed from the list + // of finalizers, so length will be 2. + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) + + // test for Updated and StatusUpdated as false, and non-nil error + f.result.Updated = false + f.result.StatusUpdated = false + f.err = fmt.Errorf("finalizer failed") + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer2", f) + Expect(err).To(BeNil()) + + result, err = finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(result.Updated).To(BeFalse()) + Expect(result.StatusUpdated).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) + + // test for result as true, and non-nil error + f.result.Updated = true + f.result.StatusUpdated = true + f.err = fmt.Errorf("finalizer failed") + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer3", f) + Expect(err).To(BeNil()) + + result, err = finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeTrue()) + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/types.go b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/types.go new file mode 100644 index 00000000000..e3a002a9358 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/finalizer/types.go @@ -0,0 +1,42 @@ +/* +Copyright 2021 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package finalizer + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Registerer holds Register that will check if a key is already registered +// and error out and it does; and if not registered, it will add the finalizer +// to the finalizers map as the value for the provided key. +type Registerer interface { + Register(key string, f Finalizer) error +} + +// Finalizer holds Finalize that will add/remove a finalizer based on the +// deletion timestamp being set and return an indication of whether the +// obj needs an update or not. +type Finalizer interface { + Finalize(context.Context, client.Object) (Result, error) +} + +// Finalizers implements Registerer and Finalizer to finalize all registered +// finalizers if the provided object has a deletion timestamp or set all +// registered finalizers if it does not. +type Finalizers interface { + Registerer + Finalizer +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/doc.go new file mode 100644 index 00000000000..e5fd177aff8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/doc.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package handler defines EventHandlers that enqueue reconcile.Requests in response to Create, Update, Deletion Events +observed from Watching Kubernetes APIs. Users should provide a source.Source and handler.EventHandler to +Controller.Watch in order to generate and enqueue reconcile.Request work items. + +Generally, following premade event handlers should be sufficient for most use cases: + +EventHandlers: + +EnqueueRequestForObject - Enqueues a reconcile.Request containing the Name and Namespace of the object in the Event. This will +cause the object that was the source of the Event (e.g. the created / deleted / updated object) to be +reconciled. + +EnqueueRequestForOwner - Enqueues a reconcile.Request containing the Name and Namespace of the Owner of the object in the Event. +This will cause owner of the object that was the source of the Event (e.g. the owner object that created the object) +to be reconciled. + +EnqueueRequestsFromMapFunc - Enqueues reconcile.Requests resulting from a user provided transformation function run against the +object in the Event. This will cause an arbitrary collection of objects (defined from a transformation of the +source object) to be reconciled. +*/ +package handler diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go new file mode 100644 index 00000000000..c72b2e1ebb1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go @@ -0,0 +1,92 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler + +import ( + "context" + + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var enqueueLog = logf.RuntimeLog.WithName("eventhandler").WithName("EnqueueRequestForObject") + +type empty struct{} + +var _ EventHandler = &EnqueueRequestForObject{} + +// EnqueueRequestForObject enqueues a Request containing the Name and Namespace of the object that is the source of the Event. +// (e.g. the created / deleted / updated objects Name and Namespace). handler.EnqueueRequestForObject is used by almost all +// Controllers that have associated Resources (e.g. CRDs) to reconcile the associated Resource. +type EnqueueRequestForObject struct{} + +// Create implements EventHandler. +func (e *EnqueueRequestForObject) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "CreateEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} + +// Update implements EventHandler. +func (e *EnqueueRequestForObject) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + switch { + case evt.ObjectNew != nil: + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.ObjectNew.GetName(), + Namespace: evt.ObjectNew.GetNamespace(), + }}) + case evt.ObjectOld != nil: + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.ObjectOld.GetName(), + Namespace: evt.ObjectOld.GetNamespace(), + }}) + default: + enqueueLog.Error(nil, "UpdateEvent received with no metadata", "event", evt) + } +} + +// Delete implements EventHandler. +func (e *EnqueueRequestForObject) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "DeleteEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} + +// Generic implements EventHandler. +func (e *EnqueueRequestForObject) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "GenericEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go new file mode 100644 index 00000000000..b55fdde6ba5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go @@ -0,0 +1,88 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler + +import ( + "context" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// MapFunc is the signature required for enqueueing requests from a generic function. +// This type is usually used with EnqueueRequestsFromMapFunc when registering an event handler. +type MapFunc func(context.Context, client.Object) []reconcile.Request + +// EnqueueRequestsFromMapFunc enqueues Requests by running a transformation function that outputs a collection +// of reconcile.Requests on each Event. The reconcile.Requests may be for an arbitrary set of objects +// defined by some user specified transformation of the source Event. (e.g. trigger Reconciler for a set of objects +// in response to a cluster resize event caused by adding or deleting a Node) +// +// EnqueueRequestsFromMapFunc is frequently used to fan-out updates from one object to one or more other +// objects of a differing type. +// +// For UpdateEvents which contain both a new and old object, the transformation function is run on both +// objects and both sets of Requests are enqueue. +func EnqueueRequestsFromMapFunc(fn MapFunc) EventHandler { + return &enqueueRequestsFromMapFunc{ + toRequests: fn, + } +} + +var _ EventHandler = &enqueueRequestsFromMapFunc{} + +type enqueueRequestsFromMapFunc struct { + // Mapper transforms the argument into a slice of keys to be reconciled + toRequests MapFunc +} + +// Create implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +// Update implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.ObjectOld, reqs) + e.mapAndEnqueue(ctx, q, evt.ObjectNew, reqs) +} + +// Delete implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +// Generic implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(ctx context.Context, q workqueue.RateLimitingInterface, object client.Object, reqs map[reconcile.Request]empty) { + for _, req := range e.toRequests(ctx, object) { + _, ok := reqs[req] + if !ok { + q.Add(req) + reqs[req] = empty{} + } + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go new file mode 100644 index 00000000000..02e7d756f80 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go @@ -0,0 +1,199 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var _ EventHandler = &enqueueRequestForOwner{} + +var log = logf.RuntimeLog.WithName("eventhandler").WithName("enqueueRequestForOwner") + +// OwnerOption modifies an EnqueueRequestForOwner EventHandler. +type OwnerOption func(e *enqueueRequestForOwner) + +// EnqueueRequestForOwner enqueues Requests for the Owners of an object. E.g. the object that created +// the object that was the source of the Event. +// +// If a ReplicaSet creates Pods, users may reconcile the ReplicaSet in response to Pod Events using: +// +// - a source.Kind Source with Type of Pod. +// +// - a handler.enqueueRequestForOwner EventHandler with an OwnerType of ReplicaSet and OnlyControllerOwner set to true. +func EnqueueRequestForOwner(scheme *runtime.Scheme, mapper meta.RESTMapper, ownerType client.Object, opts ...OwnerOption) EventHandler { + e := &enqueueRequestForOwner{ + ownerType: ownerType, + mapper: mapper, + } + if err := e.parseOwnerTypeGroupKind(scheme); err != nil { + panic(err) + } + for _, opt := range opts { + opt(e) + } + return e +} + +// OnlyControllerOwner if provided will only look at the first OwnerReference with Controller: true. +func OnlyControllerOwner() OwnerOption { + return func(e *enqueueRequestForOwner) { + e.isController = true + } +} + +type enqueueRequestForOwner struct { + // ownerType is the type of the Owner object to look for in OwnerReferences. Only Group and Kind are compared. + ownerType runtime.Object + + // isController if set will only look at the first OwnerReference with Controller: true. + isController bool + + // groupKind is the cached Group and Kind from OwnerType + groupKind schema.GroupKind + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper +} + +// Create implements EventHandler. +func (e *enqueueRequestForOwner) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Update implements EventHandler. +func (e *enqueueRequestForOwner) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.ObjectOld, reqs) + e.getOwnerReconcileRequest(evt.ObjectNew, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Delete implements EventHandler. +func (e *enqueueRequestForOwner) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Generic implements EventHandler. +func (e *enqueueRequestForOwner) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// parseOwnerTypeGroupKind parses the OwnerType into a Group and Kind and caches the result. Returns false +// if the OwnerType could not be parsed using the scheme. +func (e *enqueueRequestForOwner) parseOwnerTypeGroupKind(scheme *runtime.Scheme) error { + // Get the kinds of the type + kinds, _, err := scheme.ObjectKinds(e.ownerType) + if err != nil { + log.Error(err, "Could not get ObjectKinds for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType)) + return err + } + // Expect only 1 kind. If there is more than one kind this is probably an edge case such as ListOptions. + if len(kinds) != 1 { + err := fmt.Errorf("expected exactly 1 kind for OwnerType %T, but found %s kinds", e.ownerType, kinds) + log.Error(nil, "expected exactly 1 kind for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType), "kinds", kinds) + return err + } + // Cache the Group and Kind for the OwnerType + e.groupKind = schema.GroupKind{Group: kinds[0].Group, Kind: kinds[0].Kind} + return nil +} + +// getOwnerReconcileRequest looks at object and builds a map of reconcile.Request to reconcile +// owners of object that match e.OwnerType. +func (e *enqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, result map[reconcile.Request]empty) { + // Iterate through the OwnerReferences looking for a match on Group and Kind against what was requested + // by the user + for _, ref := range e.getOwnersReferences(object) { + // Parse the Group out of the OwnerReference to compare it to what was parsed out of the requested OwnerType + refGV, err := schema.ParseGroupVersion(ref.APIVersion) + if err != nil { + log.Error(err, "Could not parse OwnerReference APIVersion", + "api version", ref.APIVersion) + return + } + + // Compare the OwnerReference Group and Kind against the OwnerType Group and Kind specified by the user. + // If the two match, create a Request for the objected referred to by + // the OwnerReference. Use the Name from the OwnerReference and the Namespace from the + // object in the event. + if ref.Kind == e.groupKind.Kind && refGV.Group == e.groupKind.Group { + // Match found - add a Request for the object referred to in the OwnerReference + request := reconcile.Request{NamespacedName: types.NamespacedName{ + Name: ref.Name, + }} + + // if owner is not namespaced then we should not set the namespace + mapping, err := e.mapper.RESTMapping(e.groupKind, refGV.Version) + if err != nil { + log.Error(err, "Could not retrieve rest mapping", "kind", e.groupKind) + return + } + if mapping.Scope.Name() != meta.RESTScopeNameRoot { + request.Namespace = object.GetNamespace() + } + + result[request] = empty{} + } + } +} + +// getOwnersReferences returns the OwnerReferences for an object as specified by the enqueueRequestForOwner +// - if IsController is true: only take the Controller OwnerReference (if found) +// - if IsController is false: take all OwnerReferences. +func (e *enqueueRequestForOwner) getOwnersReferences(object metav1.Object) []metav1.OwnerReference { + if object == nil { + return nil + } + + // If not filtered as Controller only, then use all the OwnerReferences + if !e.isController { + return object.GetOwnerReferences() + } + // If filtered to a Controller, only take the Controller OwnerReference + if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { + return []metav1.OwnerReference{*ownerRef} + } + // No Controller OwnerReference found + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go new file mode 100644 index 00000000000..2f380f4fc4d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go @@ -0,0 +1,106 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler + +import ( + "context" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" +) + +// EventHandler enqueues reconcile.Requests in response to events (e.g. Pod Create). EventHandlers map an Event +// for one object to trigger Reconciles for either the same object or different objects - e.g. if there is an +// Event for object with type Foo (using source.KindSource) then reconcile one or more object(s) with type Bar. +// +// Identical reconcile.Requests will be batched together through the queuing mechanism before reconcile is called. +// +// * Use EnqueueRequestForObject to reconcile the object the event is for +// - do this for events for the type the Controller Reconciles. (e.g. Deployment for a Deployment Controller) +// +// * Use EnqueueRequestForOwner to reconcile the owner of the object the event is for +// - do this for events for the types the Controller creates. (e.g. ReplicaSets created by a Deployment Controller) +// +// * Use EnqueueRequestsFromMapFunc to transform an event for an object to a reconcile of an object +// of a different type - do this for events for types the Controller may be interested in, but doesn't create. +// (e.g. If Foo responds to cluster size events, map Node events to Foo objects.) +// +// Unless you are implementing your own EventHandler, you can ignore the functions on the EventHandler interface. +// Most users shouldn't need to implement their own EventHandler. +type EventHandler interface { + // Create is called in response to an create event - e.g. Pod Creation. + Create(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) + + // Update is called in response to an update event - e.g. Pod Updated. + Update(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) + + // Delete is called in response to a delete event - e.g. Pod Deleted. + Delete(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) + + // Generic is called in response to an event of an unknown type or a synthetic event triggered as a cron or + // external trigger request - e.g. reconcile Autoscaling, or a Webhook. + Generic(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) +} + +var _ EventHandler = Funcs{} + +// Funcs implements EventHandler. +type Funcs struct { + // Create is called in response to an add event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + CreateFunc func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) + + // Update is called in response to an update event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + UpdateFunc func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) + + // Delete is called in response to a delete event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + DeleteFunc func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) + + // GenericFunc is called in response to a generic event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + GenericFunc func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) +} + +// Create implements EventHandler. +func (h Funcs) Create(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { + if h.CreateFunc != nil { + h.CreateFunc(ctx, e, q) + } +} + +// Delete implements EventHandler. +func (h Funcs) Delete(ctx context.Context, e event.DeleteEvent, q workqueue.RateLimitingInterface) { + if h.DeleteFunc != nil { + h.DeleteFunc(ctx, e, q) + } +} + +// Update implements EventHandler. +func (h Funcs) Update(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { + if h.UpdateFunc != nil { + h.UpdateFunc(ctx, e, q) + } +} + +// Generic implements EventHandler. +func (h Funcs) Generic(ctx context.Context, e event.GenericEvent, q workqueue.RateLimitingInterface) { + if h.GenericFunc != nil { + h.GenericFunc(ctx, e, q) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_suite_test.go new file mode 100644 index 00000000000..3f6b17f3377 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_suite_test.go @@ -0,0 +1,49 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestEventhandler(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Eventhandler Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_test.go new file mode 100644 index 00000000000..6ae87b0988a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler_test.go @@ -0,0 +1,794 @@ +/* + Copyright 2018 The Kubernetes Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package handler_test + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/workqueue" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var _ = Describe("Eventhandler", func() { + var ctx = context.Background() + var q workqueue.RateLimitingInterface + var instance handler.EnqueueRequestForObject + var pod *corev1.Pod + var mapper meta.RESTMapper + BeforeEach(func() { + q = &controllertest.Queue{Interface: workqueue.New()} + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "biz", Name: "baz"}, + } + Expect(cfg).NotTo(BeNil()) + + httpClient, err := rest.HTTPClientFor(cfg) + Expect(err).ShouldNot(HaveOccurred()) + mapper, err = apiutil.NewDiscoveryRESTMapper(cfg, httpClient) + Expect(err).ShouldNot(HaveOccurred()) + }) + + Describe("EnqueueRequestForObject", func() { + It("should enqueue a Request with the Name / Namespace of the object in the CreateEvent.", func() { + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).NotTo(BeNil()) + req, ok := i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz", Name: "baz"})) + }) + + It("should enqueue a Request with the Name / Namespace of the object in the DeleteEvent.", func() { + evt := event.DeleteEvent{ + Object: pod, + } + instance.Delete(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).NotTo(BeNil()) + req, ok := i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz", Name: "baz"})) + }) + + It("should enqueue a Request with the Name / Namespace of one object in the UpdateEvent.", + func() { + newPod := pod.DeepCopy() + newPod.Name = "baz2" + newPod.Namespace = "biz2" + + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).NotTo(BeNil()) + req, ok := i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz2", Name: "baz2"})) + }) + + It("should enqueue a Request with the Name / Namespace of the object in the GenericEvent.", func() { + evt := event.GenericEvent{ + Object: pod, + } + instance.Generic(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + i, _ := q.Get() + Expect(i).NotTo(BeNil()) + req, ok := i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz", Name: "baz"})) + }) + + Context("for a runtime.Object without Object", func() { + It("should do nothing if the Object is missing for a CreateEvent.", func() { + evt := event.CreateEvent{ + Object: nil, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should do nothing if the Object is missing for a UpdateEvent.", func() { + newPod := pod.DeepCopy() + newPod.Name = "baz2" + newPod.Namespace = "biz2" + + evt := event.UpdateEvent{ + ObjectNew: newPod, + ObjectOld: nil, + } + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + i, _ := q.Get() + Expect(i).NotTo(BeNil()) + req, ok := i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz2", Name: "baz2"})) + + evt.ObjectNew = nil + evt.ObjectOld = pod + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + i, _ = q.Get() + Expect(i).NotTo(BeNil()) + req, ok = i.(reconcile.Request) + Expect(ok).To(BeTrue()) + Expect(req.NamespacedName).To(Equal(types.NamespacedName{Namespace: "biz", Name: "baz"})) + }) + + It("should do nothing if the Object is missing for a DeleteEvent.", func() { + evt := event.DeleteEvent{ + Object: nil, + } + instance.Delete(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should do nothing if the Object is missing for a GenericEvent.", func() { + evt := event.GenericEvent{ + Object: nil, + } + instance.Generic(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + }) + }) + + Describe("EnqueueRequestsFromMapFunc", func() { + It("should enqueue a Request with the function applied to the CreateEvent.", func() { + req := []reconcile.Request{} + instance := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a client.Object) []reconcile.Request { + defer GinkgoRecover() + Expect(a).To(Equal(pod)) + req = []reconcile.Request{ + { + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}, + }, + { + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}, + }, + } + return req + }) + + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(2)) + + i1, _ := q.Get() + i2, _ := q.Get() + Expect([]interface{}{i1, i2}).To(ConsistOf( + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}}, + )) + }) + + It("should enqueue a Request with the function applied to the DeleteEvent.", func() { + req := []reconcile.Request{} + instance := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a client.Object) []reconcile.Request { + defer GinkgoRecover() + Expect(a).To(Equal(pod)) + req = []reconcile.Request{ + { + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}, + }, + { + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}, + }, + } + return req + }) + + evt := event.DeleteEvent{ + Object: pod, + } + instance.Delete(ctx, evt, q) + Expect(q.Len()).To(Equal(2)) + + i1, _ := q.Get() + i2, _ := q.Get() + Expect([]interface{}{i1, i2}).To(ConsistOf( + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}}, + )) + }) + + It("should enqueue a Request with the function applied to both objects in the UpdateEvent.", + func() { + newPod := pod.DeepCopy() + + req := []reconcile.Request{} + + instance := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a client.Object) []reconcile.Request { + defer GinkgoRecover() + req = []reconcile.Request{ + { + NamespacedName: types.NamespacedName{Namespace: "foo", Name: a.GetName() + "-bar"}, + }, + { + NamespacedName: types.NamespacedName{Namespace: "biz", Name: a.GetName() + "-baz"}, + }, + } + return req + }) + + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(2)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "foo", Name: "baz-bar"}})) + + i, _ = q.Get() + Expect(i).To(Equal(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz-baz"}})) + }) + + It("should enqueue a Request with the function applied to the GenericEvent.", func() { + req := []reconcile.Request{} + instance := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a client.Object) []reconcile.Request { + defer GinkgoRecover() + Expect(a).To(Equal(pod)) + req = []reconcile.Request{ + { + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}, + }, + { + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}, + }, + } + return req + }) + + evt := event.GenericEvent{ + Object: pod, + } + instance.Generic(ctx, evt, q) + Expect(q.Len()).To(Equal(2)) + + i1, _ := q.Get() + i2, _ := q.Get() + Expect([]interface{}{i1, i2}).To(ConsistOf( + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"}}, + )) + }) + }) + + Describe("EnqueueRequestForOwner", func() { + It("should enqueue a Request with the Owner of the object in the CreateEvent.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo-parent"}})) + }) + + It("should enqueue a Request with the Owner of the object in the DeleteEvent.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.DeleteEvent{ + Object: pod, + } + instance.Delete(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo-parent"}})) + }) + + It("should enqueue a Request with the Owners of both objects in the UpdateEvent.", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + newPod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo2-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(2)) + + i1, _ := q.Get() + i2, _ := q.Get() + Expect([]interface{}{i1, i2}).To(ConsistOf( + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo1-parent"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: newPod.GetNamespace(), Name: "foo2-parent"}}, + )) + }) + + It("should enqueue a Request with the one duplicate Owner of both objects in the UpdateEvent.", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + newPod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + instance.Update(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo-parent"}})) + }) + + It("should enqueue a Request with the Owner of the object in the GenericEvent.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.GenericEvent{ + Object: pod, + } + instance.Generic(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo-parent"}})) + }) + + It("should not enqueue a Request if there are no owners matching Group and Kind.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}, handler.OnlyControllerOwner()) + pod.OwnerReferences = []metav1.OwnerReference{ + { // Wrong group + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "extensions/v1", + }, + { // Wrong kind + Name: "foo2-parent", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should enqueue a Request if there are owners matching Group "+ + "and Kind with a different version.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &autoscalingv1.HorizontalPodAutoscaler{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo-parent", + Kind: "HorizontalPodAutoscaler", + APIVersion: "autoscaling/v2beta1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo-parent"}})) + }) + + It("should enqueue a Request for a owner that is cluster scoped", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &corev1.Node{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "node-1", + Kind: "Node", + APIVersion: "v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "", Name: "node-1"}})) + + }) + + It("should not enqueue a Request if there are no owners.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + Context("with the Controller field set to true", func() { + It("should enqueue reconcile.Requests for only the first the Controller if there are "+ + "multiple Controller owners.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}, handler.OnlyControllerOwner()) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo2-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + Controller: pointer.Bool(true), + }, + { + Name: "foo3-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo4-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + Controller: pointer.Bool(true), + }, + { + Name: "foo5-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(1)) + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo2-parent"}})) + }) + + It("should not enqueue reconcile.Requests if there are no Controller owners.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}, handler.OnlyControllerOwner()) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo2-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo3-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should not enqueue reconcile.Requests if there are no owners.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}, handler.OnlyControllerOwner()) + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + }) + + Context("with the Controller field set to false", func() { + It("should enqueue a reconcile.Requests for all owners.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo2-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + { + Name: "foo3-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(3)) + + i1, _ := q.Get() + i2, _ := q.Get() + i3, _ := q.Get() + Expect([]interface{}{i1, i2, i3}).To(ConsistOf( + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo1-parent"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo2-parent"}}, + reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: pod.GetNamespace(), Name: "foo3-parent"}}, + )) + }) + }) + + Context("with a nil object", func() { + It("should do nothing.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + } + evt := event.CreateEvent{ + Object: nil, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + }) + + Context("with a nil OwnerType", func() { + It("should panic", func() { + Expect(func() { + handler.EnqueueRequestForOwner(nil, nil, nil) + }).To(Panic()) + }) + }) + + Context("with an invalid APIVersion in the OwnerReference", func() { + It("should do nothing.", func() { + instance := handler.EnqueueRequestForOwner(scheme.Scheme, mapper, &appsv1.ReplicaSet{}) + pod.OwnerReferences = []metav1.OwnerReference{ + { + Name: "foo1-parent", + Kind: "ReplicaSet", + APIVersion: "apps/v1/fail", + }, + } + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + Expect(q.Len()).To(Equal(0)) + }) + }) + }) + + Describe("Funcs", func() { + failingFuncs := handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect CreateEvent to be called.") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect DeleteEvent to be called.") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect UpdateEvent to be called.") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect GenericEvent to be called.") + }, + } + + It("should call CreateFunc for a CreateEvent if provided.", func() { + instance := failingFuncs + evt := event.CreateEvent{ + Object: pod, + } + instance.CreateFunc = func(ctx context.Context, evt2 event.CreateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt2).To(Equal(evt)) + } + instance.Create(ctx, evt, q) + }) + + It("should NOT call CreateFunc for a CreateEvent if NOT provided.", func() { + instance := failingFuncs + instance.CreateFunc = nil + evt := event.CreateEvent{ + Object: pod, + } + instance.Create(ctx, evt, q) + }) + + It("should call UpdateFunc for an UpdateEvent if provided.", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + + instance := failingFuncs + instance.UpdateFunc = func(ctx context.Context, evt2 event.UpdateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt2).To(Equal(evt)) + } + + instance.Update(ctx, evt, q) + }) + + It("should NOT call UpdateFunc for an UpdateEvent if NOT provided.", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + instance.Update(ctx, evt, q) + }) + + It("should call DeleteFunc for a DeleteEvent if provided.", func() { + instance := failingFuncs + evt := event.DeleteEvent{ + Object: pod, + } + instance.DeleteFunc = func(ctx context.Context, evt2 event.DeleteEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt2).To(Equal(evt)) + } + instance.Delete(ctx, evt, q) + }) + + It("should NOT call DeleteFunc for a DeleteEvent if NOT provided.", func() { + instance := failingFuncs + instance.DeleteFunc = nil + evt := event.DeleteEvent{ + Object: pod, + } + instance.Delete(ctx, evt, q) + }) + + It("should call GenericFunc for a GenericEvent if provided.", func() { + instance := failingFuncs + evt := event.GenericEvent{ + Object: pod, + } + instance.GenericFunc = func(ctx context.Context, evt2 event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt2).To(Equal(evt)) + } + instance.Generic(ctx, evt, q) + }) + + It("should NOT call GenericFunc for a GenericEvent if NOT provided.", func() { + instance := failingFuncs + instance.GenericFunc = nil + evt := event.GenericEvent{ + Object: pod, + } + instance.Generic(ctx, evt, q) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/handler/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/example_test.go new file mode 100644 index 00000000000..ad07e4e31df --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/handler/example_test.go @@ -0,0 +1,123 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler_test + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var mgr manager.Manager +var c controller.Controller + +// This example watches Pods and enqueues Requests with the Name and Namespace of the Pod from +// the Event (i.e. change caused by a Create, Update, Delete). +func ExampleEnqueueRequestForObject() { + // controller is a controller.controller + err := c.Watch( + source.Kind(mgr.GetCache(), &corev1.Pod{}), + &handler.EnqueueRequestForObject{}, + ) + if err != nil { + // handle it + } +} + +// This example watches ReplicaSets and enqueues a Request containing the Name and Namespace of the +// owning (direct) Deployment responsible for the creation of the ReplicaSet. +func ExampleEnqueueRequestForOwner() { + // controller is a controller.controller + err := c.Watch( + source.Kind(mgr.GetCache(), &appsv1.ReplicaSet{}), + handler.EnqueueRequestForOwner(mgr.GetScheme(), mgr.GetRESTMapper(), &appsv1.Deployment{}, handler.OnlyControllerOwner()), + ) + if err != nil { + // handle it + } +} + +// This example watches Deployments and enqueues a Request contain the Name and Namespace of different +// objects (of Type: MyKind) using a mapping function defined by the user. +func ExampleEnqueueRequestsFromMapFunc() { + // controller is a controller.controller + err := c.Watch( + source.Kind(mgr.GetCache(), &appsv1.Deployment{}), + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a client.Object) []reconcile.Request { + return []reconcile.Request{ + {NamespacedName: types.NamespacedName{ + Name: a.GetName() + "-1", + Namespace: a.GetNamespace(), + }}, + {NamespacedName: types.NamespacedName{ + Name: a.GetName() + "-2", + Namespace: a.GetNamespace(), + }}, + } + }), + ) + if err != nil { + // handle it + } +} + +// This example implements handler.EnqueueRequestForObject. +func ExampleFuncs() { + // controller is a controller.controller + err := c.Watch( + source.Kind(mgr.GetCache(), &corev1.Pod{}), + handler.Funcs{ + CreateFunc: func(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: e.Object.GetName(), + Namespace: e.Object.GetNamespace(), + }}) + }, + UpdateFunc: func(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: e.ObjectNew.GetName(), + Namespace: e.ObjectNew.GetNamespace(), + }}) + }, + DeleteFunc: func(ctx context.Context, e event.DeleteEvent, q workqueue.RateLimitingInterface) { + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: e.Object.GetName(), + Namespace: e.Object.GetNamespace(), + }}) + }, + GenericFunc: func(ctx context.Context, e event.GenericEvent, q workqueue.RateLimitingInterface) { + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: e.Object.GetName(), + Namespace: e.Object.GetNamespace(), + }}) + }, + }, + ) + if err != nil { + // handle it + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go new file mode 100644 index 00000000000..9827eeafed3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go @@ -0,0 +1,32 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package healthz contains helpers from supporting liveness and readiness endpoints. +// (often referred to as healthz and readyz, respectively). +// +// This package draws heavily from the apiserver's healthz package +// ( https://github.com/kubernetes/apiserver/tree/master/pkg/server/healthz ) +// but has some changes to bring it in line with controller-runtime's style. +// +// The main entrypoint is the Handler -- this serves both aggregated health status +// and individual health check endpoints. +package healthz + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("healthz") diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go new file mode 100644 index 00000000000..cfb5dc8d02b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go @@ -0,0 +1,206 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthz + +import ( + "fmt" + "net/http" + "path" + "sort" + "strings" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// Handler is an http.Handler that aggregates the results of the given +// checkers to the root path, and supports calling individual checkers on +// subpaths of the name of the checker. +// +// Adding checks on the fly is *not* threadsafe -- use a wrapper. +type Handler struct { + Checks map[string]Checker +} + +// checkStatus holds the output of a particular check. +type checkStatus struct { + name string + healthy bool + excluded bool +} + +func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) { + failed := false + excluded := getExcludedChecks(req) + + parts := make([]checkStatus, 0, len(h.Checks)) + + // calculate the results... + for checkName, check := range h.Checks { + // no-op the check if we've specified we want to exclude the check + if excluded.Has(checkName) { + excluded.Delete(checkName) + parts = append(parts, checkStatus{name: checkName, healthy: true, excluded: true}) + continue + } + if err := check(req); err != nil { + log.V(1).Info("healthz check failed", "checker", checkName, "error", err) + parts = append(parts, checkStatus{name: checkName, healthy: false}) + failed = true + } else { + parts = append(parts, checkStatus{name: checkName, healthy: true}) + } + } + + // ...default a check if none is present... + if len(h.Checks) == 0 { + parts = append(parts, checkStatus{name: "ping", healthy: true}) + } + + for _, c := range excluded.UnsortedList() { + log.V(1).Info("cannot exclude health check, no matches for it", "checker", c) + } + + // ...sort to be consistent... + sort.Slice(parts, func(i, j int) bool { return parts[i].name < parts[j].name }) + + // ...and write out the result + // TODO(directxman12): this should also accept a request for JSON content (via a accept header) + _, forceVerbose := req.URL.Query()["verbose"] + writeStatusesAsText(resp, parts, excluded, failed, forceVerbose) +} + +// writeStatusAsText writes out the given check statuses in some semi-arbitrary +// bespoke text format that we copied from Kubernetes. unknownExcludes lists +// any checks that the user requested to have excluded, but weren't actually +// known checks. writeStatusAsText is always verbose on failure, and can be +// forced to be verbose on success using the given argument. +func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.Set[string], failed, forceVerbose bool) { + resp.Header().Set("Content-Type", "text/plain; charset=utf-8") + resp.Header().Set("X-Content-Type-Options", "nosniff") + + // always write status code first + if failed { + resp.WriteHeader(http.StatusInternalServerError) + } else { + resp.WriteHeader(http.StatusOK) + } + + // shortcut for easy non-verbose success + if !failed && !forceVerbose { + fmt.Fprint(resp, "ok") + return + } + + // we're always verbose on failure, so from this point on we're guaranteed to be verbose + + for _, checkOut := range parts { + switch { + case checkOut.excluded: + fmt.Fprintf(resp, "[+]%s excluded: ok\n", checkOut.name) + case checkOut.healthy: + fmt.Fprintf(resp, "[+]%s ok\n", checkOut.name) + default: + // don't include the error since this endpoint is public. If someone wants more detail + // they should have explicit permission to the detailed checks. + fmt.Fprintf(resp, "[-]%s failed: reason withheld\n", checkOut.name) + } + } + + if unknownExcludes.Len() > 0 { + fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.UnsortedList()...)) + } + + if failed { + log.Info("healthz check failed", "statuses", parts) + fmt.Fprintf(resp, "healthz check failed\n") + } else { + fmt.Fprint(resp, "healthz check passed\n") + } +} + +func (h *Handler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + // clean up the request (duplicating the internal logic of http.ServeMux a bit) + // clean up the path a bit + reqPath := req.URL.Path + if reqPath == "" || reqPath[0] != '/' { + reqPath = "/" + reqPath + } + // path.Clean removes the trailing slash except for root for us + // (which is fine, since we're only serving one layer of sub-paths) + reqPath = path.Clean(reqPath) + + // either serve the root endpoint... + if reqPath == "/" { + h.serveAggregated(resp, req) + return + } + + // ...the default check (if nothing else is present)... + if len(h.Checks) == 0 && reqPath[1:] == "ping" { + CheckHandler{Checker: Ping}.ServeHTTP(resp, req) + return + } + + // ...or an individual checker + checkName := reqPath[1:] // ignore the leading slash + checker, known := h.Checks[checkName] + if !known { + http.NotFoundHandler().ServeHTTP(resp, req) + return + } + + CheckHandler{Checker: checker}.ServeHTTP(resp, req) +} + +// CheckHandler is an http.Handler that serves a health check endpoint at the root path, +// based on its checker. +type CheckHandler struct { + Checker +} + +func (h CheckHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + if err := h.Checker(req); err != nil { + http.Error(resp, fmt.Sprintf("internal server error: %v", err), http.StatusInternalServerError) + } else { + fmt.Fprint(resp, "ok") + } +} + +// Checker knows how to perform a health check. +type Checker func(req *http.Request) error + +// Ping returns true automatically when checked. +var Ping Checker = func(_ *http.Request) error { return nil } + +// getExcludedChecks extracts the health check names to be excluded from the query param. +func getExcludedChecks(r *http.Request) sets.Set[string] { + checks, found := r.URL.Query()["exclude"] + if found { + return sets.New[string](checks...) + } + return sets.New[string]() +} + +// formatQuoted returns a formatted string of the health check names, +// preserving the order passed in. +func formatQuoted(names ...string) string { + quoted := make([]string, 0, len(names)) + for _, name := range names { + quoted = append(quoted, fmt.Sprintf("%q", name)) + } + return strings.Join(quoted, ",") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_suite_test.go new file mode 100644 index 00000000000..8e16a58aa0b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_suite_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthz_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestHealthz(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Healthz Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_test.go new file mode 100644 index 00000000000..639a7575f30 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/healthz/healthz_test.go @@ -0,0 +1,203 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthz_test + +import ( + "errors" + "net/http" + "net/http/httptest" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "sigs.k8s.io/controller-runtime/pkg/healthz" +) + +const ( + contentType = "text/plain; charset=utf-8" +) + +func requestTo(handler http.Handler, dest string) *httptest.ResponseRecorder { + req, err := http.NewRequest("GET", dest, nil) + Expect(err).NotTo(HaveOccurred()) + resp := httptest.NewRecorder() + handler.ServeHTTP(resp, req) + + return resp +} + +var _ = Describe("Healthz Handler", func() { + Describe("the aggregated endpoint", func() { + It("should return healthy if all checks succeed", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "ok2": healthz.Ping, + }} + + resp := requestTo(handler, "/") + Expect(resp.Code).To(Equal(http.StatusOK)) + }) + + It("should return unhealthy if at least one check fails", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "bad1": func(req *http.Request) error { + return errors.New("blech") + }, + }} + + resp := requestTo(handler, "/") + Expect(resp.Code).To(Equal(http.StatusInternalServerError)) + }) + + It("should ingore excluded checks when determining health", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "bad1": func(req *http.Request) error { + return errors.New("blech") + }, + }} + + resp := requestTo(handler, "/?exclude=bad1") + Expect(resp.Code).To(Equal(http.StatusOK)) + }) + + It("should be fine if asked to exclude a check that doesn't exist", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "ok2": healthz.Ping, + }} + + resp := requestTo(handler, "/?exclude=nonexistant") + Expect(resp.Code).To(Equal(http.StatusOK)) + }) + + Context("when verbose output is requested with ?verbose=true", func() { + It("should return verbose output for ok cases", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "ok2": healthz.Ping, + }} + + resp := requestTo(handler, "/?verbose=true") + Expect(resp.Code).To(Equal(http.StatusOK)) + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("[+]ok1 ok\n[+]ok2 ok\nhealthz check passed\n")) + }) + + It("should return verbose output for failures", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "bad1": func(req *http.Request) error { + return errors.New("blech") + }, + }} + + resp := requestTo(handler, "/?verbose=true") + Expect(resp.Code).To(Equal(http.StatusInternalServerError)) + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("[-]bad1 failed: reason withheld\n[+]ok1 ok\nhealthz check failed\n")) + }) + }) + + It("should return non-verbose output when healthy and not specified as verbose", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "ok2": healthz.Ping, + }} + + resp := requestTo(handler, "/") + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("ok")) + + }) + + It("should always be verbose if a check fails", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "ok1": healthz.Ping, + "bad1": func(req *http.Request) error { + return errors.New("blech") + }, + }} + + resp := requestTo(handler, "/") + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("[-]bad1 failed: reason withheld\n[+]ok1 ok\nhealthz check failed\n")) + }) + + It("should always return a ping endpoint if no other ones are present", func() { + resp := requestTo(&healthz.Handler{}, "/?verbose=true") + Expect(resp.Code).To(Equal(http.StatusOK)) + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("[+]ping ok\nhealthz check passed\n")) + }) + }) + + Describe("the per-check endpoints", func() { + It("should return ok if the requested check is healthy", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "okcheck": healthz.Ping, + }} + + resp := requestTo(handler, "/okcheck") + Expect(resp.Code).To(Equal(http.StatusOK)) + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("ok")) + }) + + It("should return an error if the requested check is unhealthy", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "failcheck": func(req *http.Request) error { + return errors.New("blech") + }, + }} + + resp := requestTo(handler, "/failcheck") + Expect(resp.Code).To(Equal(http.StatusInternalServerError)) + Expect(resp.Header().Get("Content-Type")).To(Equal(contentType)) + Expect(resp.Body.String()).To(Equal("internal server error: blech\n")) + }) + + It("shouldn't take other checks into account", func() { + handler := &healthz.Handler{Checks: map[string]healthz.Checker{ + "failcheck": func(req *http.Request) error { + return errors.New("blech") + }, + "okcheck": healthz.Ping, + }} + + By("checking the bad endpoint and expecting it to fail") + resp := requestTo(handler, "/failcheck") + Expect(resp.Code).To(Equal(http.StatusInternalServerError)) + + By("checking the good endpoint and expecting it to succeed") + resp = requestTo(handler, "/okcheck") + Expect(resp.Code).To(Equal(http.StatusOK)) + }) + + It("should return non-found for paths that don't match a checker", func() { + handler := &healthz.Handler{} + + resp := requestTo(handler, "/doesnotexist") + Expect(resp.Code).To(Equal(http.StatusNotFound)) + }) + + It("should always return a ping endpoint if no other ones are present", func() { + resp := requestTo(&healthz.Handler{}, "/ping") + Expect(resp.Code).To(Equal(http.StatusOK)) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go new file mode 100644 index 00000000000..83aba28cb7b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go @@ -0,0 +1,370 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/types" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/handler" + ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Controller implements controller.Controller. +type Controller struct { + // Name is used to uniquely identify a Controller in tracing, logging and monitoring. Name is required. + Name string + + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // Reconciler is a function that can be called at any time with the Name / Namespace of an object and + // ensures that the state of the system matches the state specified in the object. + // Defaults to the DefaultReconcileFunc. + Do reconcile.Reconciler + + // MakeQueue constructs the queue for this controller once the controller is ready to start. + // This exists because the standard Kubernetes workqueues start themselves immediately, which + // leads to goroutine leaks if something calls controller.New repeatedly. + MakeQueue func() workqueue.RateLimitingInterface + + // Queue is an listeningQueue that listens for events from Informers and adds object keys to + // the Queue for processing + Queue workqueue.RateLimitingInterface + + // mu is used to synchronize Controller setup + mu sync.Mutex + + // Started is true if the Controller has been Started + Started bool + + // ctx is the context that was passed to Start() and used when starting watches. + // + // According to the docs, contexts should not be stored in a struct: https://golang.org/pkg/context, + // while we usually always strive to follow best practices, we consider this a legacy case and it should + // undergo a major refactoring and redesign to allow for context to not be stored in a struct. + ctx context.Context + + // CacheSyncTimeout refers to the time limit set on waiting for cache to sync + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // startWatches maintains a list of sources, handlers, and predicates to start when the controller is started. + startWatches []watchDescription + + // LogConstructor is used to construct a logger to then log messages to users during reconciliation, + // or for example when a watch is started. + // Note: LogConstructor has to be able to handle nil requests as we are also using it + // outside the context of a reconciliation. + LogConstructor func(request *reconcile.Request) logr.Logger + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + RecoverPanic *bool + + // LeaderElected indicates whether the controller is leader elected or always running. + LeaderElected *bool +} + +// watchDescription contains all the information necessary to start a watch. +type watchDescription struct { + src source.Source + handler handler.EventHandler + predicates []predicate.Predicate +} + +// Reconcile implements reconcile.Reconciler. +func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) { + defer func() { + if r := recover(); r != nil { + if c.RecoverPanic != nil && *c.RecoverPanic { + for _, fn := range utilruntime.PanicHandlers { + fn(r) + } + err = fmt.Errorf("panic: %v [recovered]", r) + return + } + + log := logf.FromContext(ctx) + log.Info(fmt.Sprintf("Observed a panic in reconciler: %v", r)) + panic(r) + } + }() + return c.Do.Reconcile(ctx, req) +} + +// Watch implements controller.Controller. +func (c *Controller) Watch(src source.Source, evthdler handler.EventHandler, prct ...predicate.Predicate) error { + c.mu.Lock() + defer c.mu.Unlock() + + // Controller hasn't started yet, store the watches locally and return. + // + // These watches are going to be held on the controller struct until the manager or user calls Start(...). + if !c.Started { + c.startWatches = append(c.startWatches, watchDescription{src: src, handler: evthdler, predicates: prct}) + return nil + } + + c.LogConstructor(nil).Info("Starting EventSource", "source", src) + return src.Start(c.ctx, evthdler, c.Queue, prct...) +} + +// NeedLeaderElection implements the manager.LeaderElectionRunnable interface. +func (c *Controller) NeedLeaderElection() bool { + if c.LeaderElected == nil { + return true + } + return *c.LeaderElected +} + +// Start implements controller.Controller. +func (c *Controller) Start(ctx context.Context) error { + // use an IIFE to get proper lock handling + // but lock outside to get proper handling of the queue shutdown + c.mu.Lock() + if c.Started { + return errors.New("controller was started more than once. This is likely to be caused by being added to a manager multiple times") + } + + c.initMetrics() + + // Set the internal context. + c.ctx = ctx + + c.Queue = c.MakeQueue() + go func() { + <-ctx.Done() + c.Queue.ShutDown() + }() + + wg := &sync.WaitGroup{} + err := func() error { + defer c.mu.Unlock() + + // TODO(pwittrock): Reconsider HandleCrash + defer utilruntime.HandleCrash() + + // NB(directxman12): launch the sources *before* trying to wait for the + // caches to sync so that they have a chance to register their intendeded + // caches. + for _, watch := range c.startWatches { + c.LogConstructor(nil).Info("Starting EventSource", "source", fmt.Sprintf("%s", watch.src)) + + if err := watch.src.Start(ctx, watch.handler, c.Queue, watch.predicates...); err != nil { + return err + } + } + + // Start the SharedIndexInformer factories to begin populating the SharedIndexInformer caches + c.LogConstructor(nil).Info("Starting Controller") + + for _, watch := range c.startWatches { + syncingSource, ok := watch.src.(source.SyncingSource) + if !ok { + continue + } + + if err := func() error { + // use a context with timeout for launching sources and syncing caches. + sourceStartCtx, cancel := context.WithTimeout(ctx, c.CacheSyncTimeout) + defer cancel() + + // WaitForSync waits for a definitive timeout, and returns if there + // is an error or a timeout + if err := syncingSource.WaitForSync(sourceStartCtx); err != nil { + err := fmt.Errorf("failed to wait for %s caches to sync: %w", c.Name, err) + c.LogConstructor(nil).Error(err, "Could not wait for Cache to sync") + return err + } + + return nil + }(); err != nil { + return err + } + } + + // All the watches have been started, we can reset the local slice. + // + // We should never hold watches more than necessary, each watch source can hold a backing cache, + // which won't be garbage collected if we hold a reference to it. + c.startWatches = nil + + // Launch workers to process resources + c.LogConstructor(nil).Info("Starting workers", "worker count", c.MaxConcurrentReconciles) + wg.Add(c.MaxConcurrentReconciles) + for i := 0; i < c.MaxConcurrentReconciles; i++ { + go func() { + defer wg.Done() + // Run a worker thread that just dequeues items, processes them, and marks them done. + // It enforces that the reconcileHandler is never invoked concurrently with the same object. + for c.processNextWorkItem(ctx) { + } + }() + } + + c.Started = true + return nil + }() + if err != nil { + return err + } + + <-ctx.Done() + c.LogConstructor(nil).Info("Shutdown signal received, waiting for all workers to finish") + wg.Wait() + c.LogConstructor(nil).Info("All workers finished") + return nil +} + +// processNextWorkItem will read a single work item off the workqueue and +// attempt to process it, by calling the reconcileHandler. +func (c *Controller) processNextWorkItem(ctx context.Context) bool { + obj, shutdown := c.Queue.Get() + if shutdown { + // Stop working + return false + } + + // We call Done here so the workqueue knows we have finished + // processing this item. We also must remember to call Forget if we + // do not want this work item being re-queued. For example, we do + // not call Forget if a transient error occurs, instead the item is + // put back on the workqueue and attempted again after a back-off + // period. + defer c.Queue.Done(obj) + + ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Add(1) + defer ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Add(-1) + + c.reconcileHandler(ctx, obj) + return true +} + +const ( + labelError = "error" + labelRequeueAfter = "requeue_after" + labelRequeue = "requeue" + labelSuccess = "success" +) + +func (c *Controller) initMetrics() { + ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Set(0) + ctrlmetrics.ReconcileErrors.WithLabelValues(c.Name).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelError).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeueAfter).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeue).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelSuccess).Add(0) + ctrlmetrics.WorkerCount.WithLabelValues(c.Name).Set(float64(c.MaxConcurrentReconciles)) +} + +func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) { + // Update metrics after processing each item + reconcileStartTS := time.Now() + defer func() { + c.updateMetrics(time.Since(reconcileStartTS)) + }() + + // Make sure that the object is a valid request. + req, ok := obj.(reconcile.Request) + if !ok { + // As the item in the workqueue is actually invalid, we call + // Forget here else we'd go into a loop of attempting to + // process a work item that is invalid. + c.Queue.Forget(obj) + c.LogConstructor(nil).Error(nil, "Queue item was not a Request", "type", fmt.Sprintf("%T", obj), "value", obj) + // Return true, don't take a break + return + } + + log := c.LogConstructor(&req) + reconcileID := uuid.NewUUID() + + log = log.WithValues("reconcileID", reconcileID) + ctx = logf.IntoContext(ctx, log) + ctx = addReconcileID(ctx, reconcileID) + + // RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the + // resource to be synced. + result, err := c.Reconcile(ctx, req) + switch { + case err != nil: + if errors.Is(err, reconcile.TerminalError(nil)) { + ctrlmetrics.TerminalReconcileErrors.WithLabelValues(c.Name).Inc() + } else { + c.Queue.AddRateLimited(req) + } + ctrlmetrics.ReconcileErrors.WithLabelValues(c.Name).Inc() + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelError).Inc() + log.Error(err, "Reconciler error") + case result.RequeueAfter > 0: + // The result.RequeueAfter request will be lost, if it is returned + // along with a non-nil error. But this is intended as + // We need to drive to stable reconcile loops before queuing due + // to result.RequestAfter + c.Queue.Forget(obj) + c.Queue.AddAfter(req, result.RequeueAfter) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeueAfter).Inc() + case result.Requeue: + c.Queue.AddRateLimited(req) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeue).Inc() + default: + // Finally, if no error occurs we Forget this item so it does not + // get queued again until another change happens. + c.Queue.Forget(obj) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelSuccess).Inc() + } +} + +// GetLogger returns this controller's logger. +func (c *Controller) GetLogger() logr.Logger { + return c.LogConstructor(nil) +} + +// updateMetrics updates prometheus metrics within the controller. +func (c *Controller) updateMetrics(reconcileTime time.Duration) { + ctrlmetrics.ReconcileTime.WithLabelValues(c.Name).Observe(reconcileTime.Seconds()) +} + +// ReconcileIDFromContext gets the reconcileID from the current context. +func ReconcileIDFromContext(ctx context.Context) types.UID { + r, ok := ctx.Value(reconcileIDKey{}).(types.UID) + if !ok { + return "" + } + + return r +} + +// reconcileIDKey is a context.Context Value key. Its associated value should +// be a types.UID. +type reconcileIDKey struct{} + +func addReconcileID(ctx context.Context, reconcileID types.UID) context.Context { + return context.WithValue(ctx, reconcileIDKey{}, reconcileID) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_suite_test.go new file mode 100644 index 00000000000..3143d3dd74b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_suite_test.go @@ -0,0 +1,55 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Controller internal Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var clientset *kubernetes.Clientset + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_test.go new file mode 100644 index 00000000000..d669b1acf0c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller_test.go @@ -0,0 +1,879 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/cache/informertest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics" + "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var _ = Describe("controller", func() { + var fakeReconcile *fakeReconciler + var ctrl *Controller + var queue *controllertest.Queue + var reconciled chan reconcile.Request + var request = reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}, + } + + BeforeEach(func() { + reconciled = make(chan reconcile.Request) + fakeReconcile = &fakeReconciler{ + Requests: reconciled, + results: make(chan fakeReconcileResultPair, 10 /* chosen by the completely scientific approach of guessing */), + } + queue = &controllertest.Queue{ + Interface: workqueue.New(), + } + ctrl = &Controller{ + MaxConcurrentReconciles: 1, + Do: fakeReconcile, + MakeQueue: func() workqueue.RateLimitingInterface { return queue }, + LogConstructor: func(_ *reconcile.Request) logr.Logger { + return log.RuntimeLog.WithName("controller").WithName("test") + }, + } + }) + + Describe("Reconciler", func() { + It("should call the Reconciler function", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ctrl.Do = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + return reconcile.Result{Requeue: true}, nil + }) + result, err := ctrl.Reconcile(ctx, + reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}) + Expect(err).NotTo(HaveOccurred()) + Expect(result).To(Equal(reconcile.Result{Requeue: true})) + }) + + It("should not recover panic if RecoverPanic is false by default", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + defer func() { + Expect(recover()).ShouldNot(BeNil()) + }() + ctrl.Do = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + var res *reconcile.Result + return *res, nil + }) + _, _ = ctrl.Reconcile(ctx, + reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}) + }) + + It("should recover panic if RecoverPanic is true", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + defer func() { + Expect(recover()).To(BeNil()) + }() + ctrl.RecoverPanic = pointer.Bool(true) + ctrl.Do = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + var res *reconcile.Result + return *res, nil + }) + _, err := ctrl.Reconcile(ctx, + reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"}}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("[recovered]")) + }) + }) + + Describe("Start", func() { + It("should return an error if there is an error waiting for the informers", func() { + f := false + ctrl.startWatches = []watchDescription{{ + src: source.Kind(&informertest.FakeInformers{Synced: &f}, &corev1.Pod{}), + }} + ctrl.Name = "foo" + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := ctrl.Start(ctx) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to wait for foo caches to sync")) + }) + + It("should error when cache sync timeout occurs", func() { + ctrl.CacheSyncTimeout = 10 * time.Nanosecond + + c, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + c = &cacheWithIndefinitelyBlockingGetInformer{c} + + ctrl.startWatches = []watchDescription{{ + src: source.Kind(c, &appsv1.Deployment{}), + }} + ctrl.Name = "testcontroller" + + err = ctrl.Start(context.TODO()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to wait for testcontroller caches to sync: timed out waiting for cache to be synced")) + }) + + It("should not error when context cancelled", func() { + ctrl.CacheSyncTimeout = 1 * time.Second + + sourceSynced := make(chan struct{}) + c, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + c = &cacheWithIndefinitelyBlockingGetInformer{c} + ctrl.startWatches = []watchDescription{{ + src: &singnallingSourceWrapper{ + SyncingSource: source.Kind(c, &appsv1.Deployment{}), + cacheSyncDone: sourceSynced, + }, + }} + ctrl.Name = "testcontroller" + + ctx, cancel := context.WithCancel(context.TODO()) + go func() { + defer GinkgoRecover() + err = ctrl.Start(ctx) + Expect(err).To(Succeed()) + }() + + cancel() + <-sourceSynced + }) + + It("should not error when cache sync timeout is of sufficiently high", func() { + ctrl.CacheSyncTimeout = 1 * time.Second + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + sourceSynced := make(chan struct{}) + c, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + ctrl.startWatches = []watchDescription{{ + src: &singnallingSourceWrapper{ + SyncingSource: source.Kind(c, &appsv1.Deployment{}), + cacheSyncDone: sourceSynced, + }, + }} + + go func() { + defer GinkgoRecover() + Expect(c.Start(ctx)).To(Succeed()) + }() + + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).To(Succeed()) + }() + + <-sourceSynced + }) + + It("should process events from source.Channel", func() { + // channel to be closed when event is processed + processed := make(chan struct{}) + // source channel + ch := make(chan event.GenericEvent, 1) + + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + // event to be sent to the channel + p := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, + } + evt := event.GenericEvent{ + Object: p, + } + + ins := &source.Channel{Source: ch} + ins.DestBufferSize = 1 + + // send the event to the channel + ch <- evt + + ctrl.startWatches = []watchDescription{{ + src: ins, + handler: handler.Funcs{ + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + defer GinkgoRecover() + close(processed) + }, + }, + }} + + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).To(Succeed()) + }() + <-processed + }) + + It("should error when channel source is not specified", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ins := &source.Channel{} + ctrl.startWatches = []watchDescription{{ + src: ins, + }} + + e := ctrl.Start(ctx) + Expect(e).NotTo(BeNil()) + Expect(e.Error()).To(ContainSubstring("must specify Channel.Source")) + }) + + It("should call Start on sources with the appropriate EventHandler, Queue, and Predicates", func() { + pr1 := &predicate.Funcs{} + pr2 := &predicate.Funcs{} + evthdl := &handler.EnqueueRequestForObject{} + started := false + src := source.Func(func(ctx context.Context, e handler.EventHandler, q workqueue.RateLimitingInterface, p ...predicate.Predicate) error { + defer GinkgoRecover() + Expect(e).To(Equal(evthdl)) + Expect(q).To(Equal(ctrl.Queue)) + Expect(p).To(ConsistOf(pr1, pr2)) + + started = true + return nil + }) + Expect(ctrl.Watch(src, evthdl, pr1, pr2)).NotTo(HaveOccurred()) + + // Use a cancelled context so Start doesn't block + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(ctrl.Start(ctx)).To(Succeed()) + Expect(started).To(BeTrue()) + }) + + It("should return an error if there is an error starting sources", func() { + err := fmt.Errorf("Expected Error: could not start source") + src := source.Func(func(context.Context, handler.EventHandler, + workqueue.RateLimitingInterface, + ...predicate.Predicate) error { + defer GinkgoRecover() + return err + }) + Expect(ctrl.Watch(src, &handler.EnqueueRequestForObject{})).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + Expect(ctrl.Start(ctx)).To(Equal(err)) + }) + + It("should return an error if it gets started more than once", func() { + // Use a cancelled context so Start doesn't block + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(ctrl.Start(ctx)).To(BeNil()) + err := ctrl.Start(ctx) + Expect(err).NotTo(BeNil()) + Expect(err.Error()).To(Equal("controller was started more than once. This is likely to be caused by being added to a manager multiple times")) + }) + + }) + + Describe("Processing queue items from a Controller", func() { + It("should call Reconciler if an item is enqueued", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + queue.Add(request) + + By("Invoking Reconciler") + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + + By("Removing the item from the queue") + Eventually(queue.Len).Should(Equal(0)) + Eventually(func() int { return queue.NumRequeues(request) }).Should(Equal(0)) + }) + + It("should continue to process additional queue items after the first", func() { + ctrl.Do = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) { + defer GinkgoRecover() + Fail("Reconciler should not have been called") + return reconcile.Result{}, nil + }) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + By("adding two bad items to the queue") + queue.Add("foo/bar1") + queue.Add("foo/bar2") + + By("expecting both of them to be skipped") + Eventually(queue.Len).Should(Equal(0)) + Eventually(func() int { return queue.NumRequeues(request) }).Should(Equal(0)) + }) + + PIt("should forget an item if it is not a Request and continue processing items", func() { + // TODO(community): write this test + }) + + It("should requeue a Request if there is an error and continue processing items", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + queue.Add(request) + + By("Invoking Reconciler which will give an error") + fakeReconcile.AddResult(reconcile.Result{}, fmt.Errorf("expected error: reconcile")) + Expect(<-reconciled).To(Equal(request)) + queue.AddedRateLimitedLock.Lock() + Expect(queue.AddedRatelimited).To(Equal([]any{request})) + queue.AddedRateLimitedLock.Unlock() + + By("Invoking Reconciler a second time without error") + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + + By("Removing the item from the queue") + Eventually(queue.Len).Should(Equal(0)) + Eventually(func() int { return queue.NumRequeues(request) }, 1.0).Should(Equal(0)) + }) + + It("should not requeue a Request if there is a terminal error", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + queue.Add(request) + + By("Invoking Reconciler which will give an error") + fakeReconcile.AddResult(reconcile.Result{}, reconcile.TerminalError(fmt.Errorf("expected error: reconcile"))) + Expect(<-reconciled).To(Equal(request)) + + queue.AddedRateLimitedLock.Lock() + Expect(queue.AddedRatelimited).To(BeEmpty()) + queue.AddedRateLimitedLock.Unlock() + + Expect(queue.Len()).Should(Equal(0)) + }) + + // TODO(directxman12): we should ensure that backoff occurrs with error requeue + + It("should not reset backoff until there's a non-error result", func() { + dq := &DelegatingQueue{RateLimitingInterface: ctrl.MakeQueue()} + ctrl.MakeQueue = func() workqueue.RateLimitingInterface { return dq } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + dq.Add(request) + Expect(dq.getCounts()).To(Equal(countInfo{Trying: 1})) + + By("Invoking Reconciler which returns an error") + fakeReconcile.AddResult(reconcile.Result{}, fmt.Errorf("something's wrong")) + Expect(<-reconciled).To(Equal(request)) + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 1, AddRateLimited: 1})) + + By("Invoking Reconciler a second time with an error") + fakeReconcile.AddResult(reconcile.Result{}, fmt.Errorf("another thing's wrong")) + Expect(<-reconciled).To(Equal(request)) + + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 1, AddRateLimited: 2})) + + By("Invoking Reconciler a third time, where it finally does not return an error") + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 0, AddRateLimited: 2})) + + By("Removing the item from the queue") + Eventually(dq.Len).Should(Equal(0)) + Eventually(func() int { return dq.NumRequeues(request) }).Should(Equal(0)) + }) + + It("should requeue a Request with rate limiting if the Result sets Requeue:true and continue processing items", func() { + dq := &DelegatingQueue{RateLimitingInterface: ctrl.MakeQueue()} + ctrl.MakeQueue = func() workqueue.RateLimitingInterface { return dq } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + dq.Add(request) + Expect(dq.getCounts()).To(Equal(countInfo{Trying: 1})) + + By("Invoking Reconciler which will ask for requeue") + fakeReconcile.AddResult(reconcile.Result{Requeue: true}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 1, AddRateLimited: 1})) + + By("Invoking Reconciler a second time without asking for requeue") + fakeReconcile.AddResult(reconcile.Result{Requeue: false}, nil) + Expect(<-reconciled).To(Equal(request)) + + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 0, AddRateLimited: 1})) + + By("Removing the item from the queue") + Eventually(dq.Len).Should(Equal(0)) + Eventually(func() int { return dq.NumRequeues(request) }).Should(Equal(0)) + }) + + It("should requeue a Request after a duration (but not rate-limitted) if the Result sets RequeueAfter (regardless of Requeue)", func() { + dq := &DelegatingQueue{RateLimitingInterface: ctrl.MakeQueue()} + ctrl.MakeQueue = func() workqueue.RateLimitingInterface { return dq } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + dq.Add(request) + Expect(dq.getCounts()).To(Equal(countInfo{Trying: 1})) + + By("Invoking Reconciler which will ask for requeue & requeueafter") + fakeReconcile.AddResult(reconcile.Result{RequeueAfter: time.Millisecond * 100, Requeue: true}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 0, AddAfter: 1})) + + By("Invoking Reconciler a second time asking for a requeueafter only") + fakeReconcile.AddResult(reconcile.Result{RequeueAfter: time.Millisecond * 100}, nil) + Expect(<-reconciled).To(Equal(request)) + + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: -1 /* we don't increment the count in addafter */, AddAfter: 2})) + + By("Removing the item from the queue") + Eventually(dq.Len).Should(Equal(0)) + Eventually(func() int { return dq.NumRequeues(request) }).Should(Equal(0)) + }) + + It("should perform error behavior if error is not nil, regardless of RequeueAfter", func() { + dq := &DelegatingQueue{RateLimitingInterface: ctrl.MakeQueue()} + ctrl.MakeQueue = func() workqueue.RateLimitingInterface { return dq } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + dq.Add(request) + Expect(dq.getCounts()).To(Equal(countInfo{Trying: 1})) + + By("Invoking Reconciler which will ask for requeueafter with an error") + fakeReconcile.AddResult(reconcile.Result{RequeueAfter: time.Millisecond * 100}, fmt.Errorf("expected error: reconcile")) + Expect(<-reconciled).To(Equal(request)) + Eventually(dq.getCounts).Should(Equal(countInfo{Trying: 1, AddRateLimited: 1})) + + By("Invoking Reconciler a second time asking for requeueafter without errors") + fakeReconcile.AddResult(reconcile.Result{RequeueAfter: time.Millisecond * 100}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(dq.getCounts).Should(Equal(countInfo{AddAfter: 1, AddRateLimited: 1})) + + By("Removing the item from the queue") + Eventually(dq.Len).Should(Equal(0)) + Eventually(func() int { return dq.NumRequeues(request) }).Should(Equal(0)) + }) + + PIt("should return if the queue is shutdown", func() { + // TODO(community): write this test + }) + + PIt("should wait for informers to be synced before processing items", func() { + // TODO(community): write this test + }) + + PIt("should create a new go routine for MaxConcurrentReconciles", func() { + // TODO(community): write this test + }) + + Context("prometheus metric reconcile_total", func() { + var reconcileTotal dto.Metric + + BeforeEach(func() { + ctrlmetrics.ReconcileTotal.Reset() + reconcileTotal.Reset() + }) + + It("should get updated on successful reconciliation", func() { + Expect(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "success").Write(&reconcileTotal)).To(Succeed()) + if reconcileTotal.GetCounter().GetValue() != 0.0 { + return fmt.Errorf("metric reconcile total not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + By("Invoking Reconciler which will succeed") + queue.Add(request) + + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "success").Write(&reconcileTotal)).To(Succeed()) + if actual := reconcileTotal.GetCounter().GetValue(); actual != 1.0 { + return fmt.Errorf("metric reconcile total expected: %v and got: %v", 1.0, actual) + } + return nil + }, 2.0).Should(Succeed()) + }) + + It("should get updated on reconcile errors", func() { + Expect(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "error").Write(&reconcileTotal)).To(Succeed()) + if reconcileTotal.GetCounter().GetValue() != 0.0 { + return fmt.Errorf("metric reconcile total not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + By("Invoking Reconciler which will give an error") + queue.Add(request) + + fakeReconcile.AddResult(reconcile.Result{}, fmt.Errorf("expected error: reconcile")) + Expect(<-reconciled).To(Equal(request)) + Eventually(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "error").Write(&reconcileTotal)).To(Succeed()) + if actual := reconcileTotal.GetCounter().GetValue(); actual != 1.0 { + return fmt.Errorf("metric reconcile total expected: %v and got: %v", 1.0, actual) + } + return nil + }, 2.0).Should(Succeed()) + }) + + It("should get updated when reconcile returns with retry enabled", func() { + Expect(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "retry").Write(&reconcileTotal)).To(Succeed()) + if reconcileTotal.GetCounter().GetValue() != 0.0 { + return fmt.Errorf("metric reconcile total not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + + By("Invoking Reconciler which will return result with Requeue enabled") + queue.Add(request) + + fakeReconcile.AddResult(reconcile.Result{Requeue: true}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "requeue").Write(&reconcileTotal)).To(Succeed()) + if actual := reconcileTotal.GetCounter().GetValue(); actual != 1.0 { + return fmt.Errorf("metric reconcile total expected: %v and got: %v", 1.0, actual) + } + return nil + }, 2.0).Should(Succeed()) + }) + + It("should get updated when reconcile returns with retryAfter enabled", func() { + Expect(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "retry_after").Write(&reconcileTotal)).To(Succeed()) + if reconcileTotal.GetCounter().GetValue() != 0.0 { + return fmt.Errorf("metric reconcile total not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + By("Invoking Reconciler which will return result with requeueAfter enabled") + queue.Add(request) + + fakeReconcile.AddResult(reconcile.Result{RequeueAfter: 5 * time.Hour}, nil) + Expect(<-reconciled).To(Equal(request)) + Eventually(func() error { + Expect(ctrlmetrics.ReconcileTotal.WithLabelValues(ctrl.Name, "requeue_after").Write(&reconcileTotal)).To(Succeed()) + if actual := reconcileTotal.GetCounter().GetValue(); actual != 1.0 { + return fmt.Errorf("metric reconcile total expected: %v and got: %v", 1.0, actual) + } + return nil + }, 2.0).Should(Succeed()) + }) + }) + + Context("should update prometheus metrics", func() { + It("should requeue a Request if there is an error and continue processing items", func() { + var reconcileErrs dto.Metric + ctrlmetrics.ReconcileErrors.Reset() + Expect(func() error { + Expect(ctrlmetrics.ReconcileErrors.WithLabelValues(ctrl.Name).Write(&reconcileErrs)).To(Succeed()) + if reconcileErrs.GetCounter().GetValue() != 0.0 { + return fmt.Errorf("metric reconcile errors not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + queue.Add(request) + + By("Invoking Reconciler which will give an error") + fakeReconcile.AddResult(reconcile.Result{}, fmt.Errorf("expected error: reconcile")) + Expect(<-reconciled).To(Equal(request)) + Eventually(func() error { + Expect(ctrlmetrics.ReconcileErrors.WithLabelValues(ctrl.Name).Write(&reconcileErrs)).To(Succeed()) + if reconcileErrs.GetCounter().GetValue() != 1.0 { + return fmt.Errorf("metrics not updated") + } + return nil + }, 2.0).Should(Succeed()) + + By("Invoking Reconciler a second time without error") + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + + By("Removing the item from the queue") + Eventually(queue.Len).Should(Equal(0)) + Eventually(func() int { return queue.NumRequeues(request) }).Should(Equal(0)) + }) + + It("should add a reconcile time to the reconcile time histogram", func() { + var reconcileTime dto.Metric + ctrlmetrics.ReconcileTime.Reset() + + Expect(func() error { + histObserver := ctrlmetrics.ReconcileTime.WithLabelValues(ctrl.Name) + hist := histObserver.(prometheus.Histogram) + Expect(hist.Write(&reconcileTime)).To(Succeed()) + if reconcileTime.GetHistogram().GetSampleCount() != uint64(0) { + return fmt.Errorf("metrics not reset") + } + return nil + }()).Should(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(ctrl.Start(ctx)).NotTo(HaveOccurred()) + }() + queue.Add(request) + + By("Invoking Reconciler") + fakeReconcile.AddResult(reconcile.Result{}, nil) + Expect(<-reconciled).To(Equal(request)) + + By("Removing the item from the queue") + Eventually(queue.Len).Should(Equal(0)) + Eventually(func() int { return queue.NumRequeues(request) }).Should(Equal(0)) + + Eventually(func() error { + histObserver := ctrlmetrics.ReconcileTime.WithLabelValues(ctrl.Name) + hist := histObserver.(prometheus.Histogram) + Expect(hist.Write(&reconcileTime)).To(Succeed()) + if reconcileTime.GetHistogram().GetSampleCount() == uint64(0) { + return fmt.Errorf("metrics not updated") + } + return nil + }, 2.0).Should(Succeed()) + }) + }) + }) +}) + +var _ = Describe("ReconcileIDFromContext function", func() { + It("should return an empty string if there is nothing in the context", func() { + ctx := context.Background() + reconcileID := ReconcileIDFromContext(ctx) + + Expect(reconcileID).To(Equal(types.UID(""))) + }) + + It("should return the correct reconcileID from context", func() { + const expectedReconcileID = types.UID("uuid") + ctx := addReconcileID(context.Background(), expectedReconcileID) + reconcileID := ReconcileIDFromContext(ctx) + + Expect(reconcileID).To(Equal(expectedReconcileID)) + }) +}) + +type DelegatingQueue struct { + workqueue.RateLimitingInterface + mu sync.Mutex + + countAddRateLimited int + countAdd int + countAddAfter int +} + +func (q *DelegatingQueue) AddRateLimited(item interface{}) { + q.mu.Lock() + defer q.mu.Unlock() + + q.countAddRateLimited++ + q.RateLimitingInterface.AddRateLimited(item) +} + +func (q *DelegatingQueue) AddAfter(item interface{}, d time.Duration) { + q.mu.Lock() + defer q.mu.Unlock() + + q.countAddAfter++ + q.RateLimitingInterface.AddAfter(item, d) +} + +func (q *DelegatingQueue) Add(item interface{}) { + q.mu.Lock() + defer q.mu.Unlock() + q.countAdd++ + + q.RateLimitingInterface.Add(item) +} + +func (q *DelegatingQueue) Forget(item interface{}) { + q.mu.Lock() + defer q.mu.Unlock() + q.countAdd-- + + q.RateLimitingInterface.Forget(item) +} + +type countInfo struct { + Trying, AddAfter, AddRateLimited int +} + +func (q *DelegatingQueue) getCounts() countInfo { + q.mu.Lock() + defer q.mu.Unlock() + + return countInfo{ + Trying: q.countAdd, + AddAfter: q.countAddAfter, + AddRateLimited: q.countAddRateLimited, + } +} + +type fakeReconcileResultPair struct { + Result reconcile.Result + Err error +} + +type fakeReconciler struct { + Requests chan reconcile.Request + results chan fakeReconcileResultPair +} + +func (f *fakeReconciler) AddResult(res reconcile.Result, err error) { + f.results <- fakeReconcileResultPair{Result: res, Err: err} +} + +func (f *fakeReconciler) Reconcile(_ context.Context, r reconcile.Request) (reconcile.Result, error) { + res := <-f.results + if f.Requests != nil { + f.Requests <- r + } + return res.Result, res.Err +} + +type singnallingSourceWrapper struct { + cacheSyncDone chan struct{} + source.SyncingSource +} + +func (s *singnallingSourceWrapper) WaitForSync(ctx context.Context) error { + defer func() { + close(s.cacheSyncDone) + }() + return s.SyncingSource.WaitForSync(ctx) +} + +var _ cache.Cache = &cacheWithIndefinitelyBlockingGetInformer{} + +// cacheWithIndefinitelyBlockingGetInformer has a GetInformer implementation that blocks indefinitely or until its +// context is cancelled. +// We need it as a workaround for testenvs lack of support for a secure apiserver, because the insecure port always +// implies the allow all authorizer, so we can not simulate rbac issues with it. They are the usual cause of the real +// caches GetInformer blocking showing this behavior. +// TODO: Remove this once envtest supports a secure apiserver. +type cacheWithIndefinitelyBlockingGetInformer struct { + cache.Cache +} + +func (c *cacheWithIndefinitelyBlockingGetInformer) GetInformer(ctx context.Context, obj client.Object) (cache.Informer, error) { + <-ctx.Done() + return nil, errors.New("GetInformer timed out") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go new file mode 100644 index 00000000000..b74ce062be7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go @@ -0,0 +1,86 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // ReconcileTotal is a prometheus counter metrics which holds the total + // number of reconciliations per controller. It has two labels. controller label refers + // to the controller name and result label refers to the reconcile result i.e + // success, error, requeue, requeue_after. + ReconcileTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_reconcile_total", + Help: "Total number of reconciliations per controller", + }, []string{"controller", "result"}) + + // ReconcileErrors is a prometheus counter metrics which holds the total + // number of errors from the Reconciler. + ReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_reconcile_errors_total", + Help: "Total number of reconciliation errors per controller", + }, []string{"controller"}) + + // TerminalReconcileErrors is a prometheus counter metrics which holds the total + // number of terminal errors from the Reconciler. + TerminalReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_terminal_reconcile_errors_total", + Help: "Total number of terminal reconciliation errors per controller", + }, []string{"controller"}) + + // ReconcileTime is a prometheus metric which keeps track of the duration + // of reconciliations. + ReconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "controller_runtime_reconcile_time_seconds", + Help: "Length of time per reconciliation per controller", + Buckets: []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60}, + }, []string{"controller"}) + + // WorkerCount is a prometheus metric which holds the number of + // concurrent reconciles per controller. + WorkerCount = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "controller_runtime_max_concurrent_reconciles", + Help: "Maximum number of concurrent reconciles per controller", + }, []string{"controller"}) + + // ActiveWorkers is a prometheus metric which holds the number + // of active workers per controller. + ActiveWorkers = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "controller_runtime_active_workers", + Help: "Number of currently used workers per controller", + }, []string{"controller"}) +) + +func init() { + metrics.Registry.MustRegister( + ReconcileTotal, + ReconcileErrors, + TerminalReconcileErrors, + ReconcileTime, + WorkerCount, + ActiveWorkers, + // expose process metrics like CPU, Memory, file descriptor usage etc. + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + // expose Go runtime metrics like GC stats, memory stats etc. + collectors.NewGoCollector(), + ) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go new file mode 100644 index 00000000000..4f6d0843184 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go @@ -0,0 +1,35 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selector + +import ( + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/selection" +) + +// RequiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`. +func RequiresExactMatch(sel fields.Selector) (field, val string, required bool) { + reqs := sel.Requirements() + if len(reqs) != 1 { + return "", "", false + } + req := reqs[0] + if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals { + return "", "", false + } + return req.Field, req.Value, true +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_suite_test.go new file mode 100644 index 00000000000..dd42f1d1ac1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selector_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Fields Selector Utils Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_test.go new file mode 100644 index 00000000000..fba214ff16c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selector_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/fields" + + . "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" +) + +var _ = Describe("RequiresExactMatch function", func() { + + It("Returns false when the selector matches everything", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.Everything()) + Expect(requiresExactMatch).To(BeFalse()) + }) + + It("Returns false when the selector matches nothing", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.Nothing()) + Expect(requiresExactMatch).To(BeFalse()) + }) + + It("Returns false when the selector has the form key!=val", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.ParseSelectorOrDie("key!=val")) + Expect(requiresExactMatch).To(BeFalse()) + }) + + It("Returns false when the selector has the form key1==val1,key2==val2", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.ParseSelectorOrDie("key1==val1,key2==val2")) + Expect(requiresExactMatch).To(BeFalse()) + }) + + It("Returns true when the selector has the form key==val", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.ParseSelectorOrDie("key==val")) + Expect(requiresExactMatch).To(BeTrue()) + }) + + It("Returns true when the selector has the form key=val", func() { + _, _, requiresExactMatch := RequiresExactMatch(fields.ParseSelectorOrDie("key=val")) + Expect(requiresExactMatch).To(BeTrue()) + }) + + It("Returns empty key and value when the selector matches everything", func() { + key, val, _ := RequiresExactMatch(fields.Everything()) + Expect(key).To(Equal("")) + Expect(val).To(Equal("")) + }) + + It("Returns empty key and value when the selector matches nothing", func() { + key, val, _ := RequiresExactMatch(fields.Nothing()) + Expect(key).To(Equal("")) + Expect(val).To(Equal("")) + }) + + It("Returns empty key and value when the selector has the form key!=val", func() { + key, val, _ := RequiresExactMatch(fields.ParseSelectorOrDie("key!=val")) + Expect(key).To(Equal("")) + Expect(val).To(Equal("")) + }) + + It("Returns key and value when the selector has the form key==val", func() { + key, val, _ := RequiresExactMatch(fields.ParseSelectorOrDie("key==val")) + Expect(key).To(Equal("key")) + Expect(val).To(Equal("val")) + }) + + It("Returns key and value when the selector has the form key=val", func() { + key, val, _ := RequiresExactMatch(fields.ParseSelectorOrDie("key=val")) + Expect(key).To(Equal("key")) + Expect(val).To(Equal("val")) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/doc.go new file mode 100644 index 00000000000..11e39823ede --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package flock is copied from k8s.io/kubernetes/pkg/util/flock to avoid +// importing k8s.io/kubernetes as a dependency. +// +// Provides file locking functionalities on unix systems. +package flock diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/errors.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/errors.go new file mode 100644 index 00000000000..ee7a4343722 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/errors.go @@ -0,0 +1,24 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flock + +import "errors" + +var ( + // ErrAlreadyLocked is returned when the file is already locked. + ErrAlreadyLocked = errors.New("the file is already locked") +) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_other.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_other.go new file mode 100644 index 00000000000..069a5b3a2cb --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_other.go @@ -0,0 +1,24 @@ +// +build !linux,!darwin,!freebsd,!openbsd,!netbsd,!dragonfly + +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flock + +// Acquire is not implemented on non-unix systems. +func Acquire(path string) error { + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_unix.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_unix.go new file mode 100644 index 00000000000..71ec576df23 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/flock/flock_unix.go @@ -0,0 +1,48 @@ +//go:build linux || darwin || freebsd || openbsd || netbsd || dragonfly +// +build linux darwin freebsd openbsd netbsd dragonfly + +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flock + +import ( + "errors" + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +// Acquire acquires a lock on a file for the duration of the process. This method +// is reentrant. +func Acquire(path string) error { + fd, err := unix.Open(path, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0600) + if err != nil { + if errors.Is(err, os.ErrExist) { + return fmt.Errorf("cannot lock file %q: %w", path, ErrAlreadyLocked) + } + return err + } + + // We don't need to close the fd since we should hold + // it until the process exits. + err = unix.Flock(fd, unix.LOCK_NB|unix.LOCK_EX) + if errors.Is(err, unix.EWOULDBLOCK) { // This condition requires LOCK_NB. + return fmt.Errorf("cannot lock file %q: %w", path, ErrAlreadyLocked) + } + return err +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go new file mode 100644 index 00000000000..b5f91f18e07 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go @@ -0,0 +1,16 @@ +package httpserver + +import ( + "net/http" + "time" +) + +// New returns a new server with sane defaults. +func New(handler http.Handler) *http.Server { + return &http.Server{ + Handler: handler, + MaxHeaderBytes: 1 << 20, + IdleTimeout: 90 * time.Second, // matches http.DefaultTransport keep-alive timeout + ReadHeaderTimeout: 32 * time.Second, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go new file mode 100644 index 00000000000..d91a0ca50cf --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go @@ -0,0 +1,32 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "github.com/go-logr/logr" + + "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + // RuntimeLog is a base parent logger for use inside controller-runtime. + RuntimeLog logr.Logger +) + +func init() { + RuntimeLog = log.Log.WithName("controller-runtime") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go index 7057f3dbe43..0189c043233 100644 --- a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go @@ -17,14 +17,9 @@ limitations under the License. package objectutil import ( - "errors" - "fmt" - apimeta "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) // FilterWithLabels returns a copy of the items in objs matching labelSel. @@ -45,34 +40,3 @@ func FilterWithLabels(objs []runtime.Object, labelSel labels.Selector) ([]runtim } return outItems, nil } - -// IsAPINamespaced returns true if the object is namespace scoped. -// For unstructured objects the gvk is found from the object itself. -func IsAPINamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) { - gvk, err := apiutil.GVKForObject(obj, scheme) - if err != nil { - return false, err - } - - return IsAPINamespacedWithGVK(gvk, scheme, restmapper) -} - -// IsAPINamespacedWithGVK returns true if the object having the provided -// GVK is namespace scoped. -func IsAPINamespacedWithGVK(gk schema.GroupVersionKind, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) { - restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gk.Group, Kind: gk.Kind}) - if err != nil { - return false, fmt.Errorf("failed to get restmapping: %w", err) - } - - scope := restmapping.Scope.Name() - - if scope == "" { - return false, errors.New("scope cannot be identified, empty scope returned") - } - - if scope != apimeta.RESTScopeNameRoot { - return true, nil - } - return false, nil -} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go new file mode 100644 index 00000000000..21f0146ba3b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go @@ -0,0 +1,181 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package recorder + +import ( + "context" + "fmt" + "net/http" + "sync" + + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" +) + +// EventBroadcasterProducer makes an event broadcaster, returning +// whether or not the broadcaster should be stopped with the Provider, +// or not (e.g. if it's shared, it shouldn't be stopped with the Provider). +type EventBroadcasterProducer func() (caster record.EventBroadcaster, stopWithProvider bool) + +// Provider is a recorder.Provider that records events to the k8s API server +// and to a logr Logger. +type Provider struct { + lock sync.RWMutex + stopped bool + + // scheme to specify when creating a recorder + scheme *runtime.Scheme + // logger is the logger to use when logging diagnostic event info + logger logr.Logger + evtClient corev1client.EventInterface + makeBroadcaster EventBroadcasterProducer + + broadcasterOnce sync.Once + broadcaster record.EventBroadcaster + stopBroadcaster bool +} + +// NB(directxman12): this manually implements Stop instead of Being a runnable because we need to +// stop it *after* everything else shuts down, otherwise we'll cause panics as the leader election +// code finishes up and tries to continue emitting events. + +// Stop attempts to stop this provider, stopping the underlying broadcaster +// if the broadcaster asked to be stopped. It kinda tries to honor the given +// context, but the underlying broadcaster has an indefinite wait that doesn't +// return until all queued events are flushed, so this may end up just returning +// before the underlying wait has finished instead of cancelling the wait. +// This is Very Frustrating™. +func (p *Provider) Stop(shutdownCtx context.Context) { + doneCh := make(chan struct{}) + + go func() { + // technically, this could start the broadcaster, but practically, it's + // almost certainly already been started (e.g. by leader election). We + // need to invoke this to ensure that we don't inadvertently race with + // an invocation of getBroadcaster. + broadcaster := p.getBroadcaster() + if p.stopBroadcaster { + p.lock.Lock() + broadcaster.Shutdown() + p.stopped = true + p.lock.Unlock() + } + close(doneCh) + }() + + select { + case <-shutdownCtx.Done(): + case <-doneCh: + } +} + +// getBroadcaster ensures that a broadcaster is started for this +// provider, and returns it. It's threadsafe. +func (p *Provider) getBroadcaster() record.EventBroadcaster { + // NB(directxman12): this can technically still leak if something calls + // "getBroadcaster" (i.e. Emits an Event) but never calls Start, but if we + // create the broadcaster in start, we could race with other things that + // are started at the same time & want to emit events. The alternative is + // silently swallowing events and more locking, but that seems suboptimal. + + p.broadcasterOnce.Do(func() { + broadcaster, stop := p.makeBroadcaster() + broadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient}) + broadcaster.StartEventWatcher( + func(e *corev1.Event) { + p.logger.V(1).Info(e.Message, "type", e.Type, "object", e.InvolvedObject, "reason", e.Reason) + }) + p.broadcaster = broadcaster + p.stopBroadcaster = stop + }) + + return p.broadcaster +} + +// NewProvider create a new Provider instance. +func NewProvider(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) { + if httpClient == nil { + panic("httpClient must not be nil") + } + + corev1Client, err := corev1client.NewForConfigAndClient(config, httpClient) + if err != nil { + return nil, fmt.Errorf("failed to init client: %w", err) + } + + p := &Provider{scheme: scheme, logger: logger, makeBroadcaster: makeBroadcaster, evtClient: corev1Client.Events("")} + return p, nil +} + +// GetEventRecorderFor returns an event recorder that broadcasts to this provider's +// broadcaster. All events will be associated with a component of the given name. +func (p *Provider) GetEventRecorderFor(name string) record.EventRecorder { + return &lazyRecorder{ + prov: p, + name: name, + } +} + +// lazyRecorder is a recorder that doesn't actually instantiate any underlying +// recorder until the first event is emitted. +type lazyRecorder struct { + prov *Provider + name string + + recOnce sync.Once + rec record.EventRecorder +} + +// ensureRecording ensures that a concrete recorder is populated for this recorder. +func (l *lazyRecorder) ensureRecording() { + l.recOnce.Do(func() { + broadcaster := l.prov.getBroadcaster() + l.rec = broadcaster.NewRecorder(l.prov.scheme, corev1.EventSource{Component: l.name}) + }) +} + +func (l *lazyRecorder) Event(object runtime.Object, eventtype, reason, message string) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.Event(object, eventtype, reason, message) + } + l.prov.lock.RUnlock() +} +func (l *lazyRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.Eventf(object, eventtype, reason, messageFmt, args...) + } + l.prov.lock.RUnlock() +} +func (l *lazyRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.AnnotatedEventf(object, annotations, eventtype, reason, messageFmt, args...) + } + l.prov.lock.RUnlock() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_integration_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_integration_test.go new file mode 100644 index 00000000000..130a306053b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_integration_test.go @@ -0,0 +1,113 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package recorder_test + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes/scheme" + ref "k8s.io/client-go/tools/reference" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("recorder", func() { + Describe("recorder", func() { + It("should publish events", func() { + By("Creating the Manager") + cm, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("Creating the Controller") + recorder := cm.GetEventRecorderFor("test-recorder") + instance, err := controller.New("foo-controller", cm, controller.Options{ + Reconciler: reconcile.Func( + func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + dp, err := clientset.AppsV1().Deployments(request.Namespace).Get(ctx, request.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + recorder.Event(dp, corev1.EventTypeNormal, "test-reason", "test-msg") + return reconcile.Result{}, nil + }), + }) + Expect(err).NotTo(HaveOccurred()) + + By("Watching Resources") + err = instance.Watch(source.Kind(cm.GetCache(), &appsv1.Deployment{}), &handler.EnqueueRequestForObject{}) + Expect(err).NotTo(HaveOccurred()) + + By("Starting the Manager") + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(cm.Start(ctx)).NotTo(HaveOccurred()) + }() + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-name"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + + By("Invoking Reconciling") + deployment, err = clientset.AppsV1().Deployments("default").Create(ctx, deployment, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + By("Validate event is published as expected") + evtWatcher, err := clientset.CoreV1().Events("default").Watch(ctx, metav1.ListOptions{}) + Expect(err).NotTo(HaveOccurred()) + + resultEvent := <-evtWatcher.ResultChan() + + Expect(resultEvent.Type).To(Equal(watch.Added)) + evt, isEvent := resultEvent.Object.(*corev1.Event) + Expect(isEvent).To(BeTrue()) + + dpRef, err := ref.GetReference(scheme.Scheme, deployment) + Expect(err).NotTo(HaveOccurred()) + + Expect(evt.InvolvedObject).To(Equal(*dpRef)) + Expect(evt.Type).To(Equal(corev1.EventTypeNormal)) + Expect(evt.Reason).To(Equal("test-reason")) + Expect(evt.Message).To(Equal("test-msg")) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_suite_test.go new file mode 100644 index 00000000000..e5b5836d58c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_suite_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package recorder_test + +import ( + "net/http" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestRecorder(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Recorder Integration Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var httpClient *http.Client +var clientset *kubernetes.Clientset + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + httpClient, err = rest.HTTPClientFor(cfg) + Expect(err).ToNot(HaveOccurred()) + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_test.go new file mode 100644 index 00000000000..804bdb3d211 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder_test.go @@ -0,0 +1,55 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package recorder_test + +import ( + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/record" + "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +var _ = Describe("recorder.Provider", func() { + makeBroadcaster := func() (record.EventBroadcaster, bool) { return record.NewBroadcaster(), true } + Describe("NewProvider", func() { + It("should return a provider instance and a nil error.", func() { + provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster) + Expect(provider).NotTo(BeNil()) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should return an error if failed to init client.", func() { + // Invalid the config + cfg1 := *cfg + cfg1.Host = "invalid host" + _, err := recorder.NewProvider(&cfg1, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster) + Expect(err).NotTo(BeNil()) + Expect(err.Error()).To(ContainSubstring("failed to init client")) + }) + }) + Describe("GetEventRecorder", func() { + It("should return a recorder instance.", func() { + provider, err := recorder.NewProvider(cfg, httpClient, scheme.Scheme, logr.Discard(), makeBroadcaster) + Expect(err).NotTo(HaveOccurred()) + + recorder := provider.GetEventRecorderFor("test") + Expect(recorder).NotTo(BeNil()) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go new file mode 100644 index 00000000000..ae8404a1fa4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go @@ -0,0 +1,170 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" + "fmt" + + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var log = logf.RuntimeLog.WithName("source").WithName("EventHandler") + +// NewEventHandler creates a new EventHandler. +func NewEventHandler(ctx context.Context, queue workqueue.RateLimitingInterface, handler handler.EventHandler, predicates []predicate.Predicate) *EventHandler { + return &EventHandler{ + ctx: ctx, + handler: handler, + queue: queue, + predicates: predicates, + } +} + +// EventHandler adapts a handler.EventHandler interface to a cache.ResourceEventHandler interface. +type EventHandler struct { + // ctx stores the context that created the event handler + // that is used to propagate cancellation signals to each handler function. + ctx context.Context + + handler handler.EventHandler + queue workqueue.RateLimitingInterface + predicates []predicate.Predicate +} + +// HandlerFuncs converts EventHandler to a ResourceEventHandlerFuncs +// TODO: switch to ResourceEventHandlerDetailedFuncs with client-go 1.27 +func (e *EventHandler) HandlerFuncs() cache.ResourceEventHandlerFuncs { + return cache.ResourceEventHandlerFuncs{ + AddFunc: e.OnAdd, + UpdateFunc: e.OnUpdate, + DeleteFunc: e.OnDelete, + } +} + +// OnAdd creates CreateEvent and calls Create on EventHandler. +func (e *EventHandler) OnAdd(obj interface{}) { + c := event.CreateEvent{} + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + c.Object = o + } else { + log.Error(nil, "OnAdd missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Create(c) { + return + } + } + + // Invoke create handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Create(ctx, c, e.queue) +} + +// OnUpdate creates UpdateEvent and calls Update on EventHandler. +func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) { + u := event.UpdateEvent{} + + if o, ok := oldObj.(client.Object); ok { + u.ObjectOld = o + } else { + log.Error(nil, "OnUpdate missing ObjectOld", + "object", oldObj, "type", fmt.Sprintf("%T", oldObj)) + return + } + + // Pull Object out of the object + if o, ok := newObj.(client.Object); ok { + u.ObjectNew = o + } else { + log.Error(nil, "OnUpdate missing ObjectNew", + "object", newObj, "type", fmt.Sprintf("%T", newObj)) + return + } + + for _, p := range e.predicates { + if !p.Update(u) { + return + } + } + + // Invoke update handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Update(ctx, u, e.queue) +} + +// OnDelete creates DeleteEvent and calls Delete on EventHandler. +func (e *EventHandler) OnDelete(obj interface{}) { + d := event.DeleteEvent{} + + // Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a + // DeleteFinalStateUnknown struct, so the object needs to be pulled out. + // Copied from sample-controller + // This should never happen if we aren't missing events, which we have concluded that we are not + // and made decisions off of this belief. Maybe this shouldn't be here? + var ok bool + if _, ok = obj.(client.Object); !ok { + // If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown", + "type", fmt.Sprintf("%T", obj), + "object", obj) + return + } + + // Set DeleteStateUnknown to true + d.DeleteStateUnknown = true + + // Set obj to the tombstone obj + obj = tombstone.Obj + } + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + d.Object = o + } else { + log.Error(nil, "OnDelete missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Delete(d) { + return + } + } + + // Invoke delete handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Delete(ctx, d, e.queue) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_suite_test.go new file mode 100644 index 00000000000..eeee8b22cdc --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_suite_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestInternal(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Source Internal Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_test.go new file mode 100644 index 00000000000..0574f7180ed --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/internal_test.go @@ -0,0 +1,297 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal_test + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + internal "sigs.k8s.io/controller-runtime/pkg/internal/source" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var _ = Describe("Internal", func() { + var ctx = context.Background() + var instance *internal.EventHandler + var funcs, setfuncs *handler.Funcs + var set bool + BeforeEach(func() { + funcs = &handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect CreateEvent to be called.") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect DeleteEvent to be called.") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect UpdateEvent to be called.") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Did not expect GenericEvent to be called.") + }, + } + + setfuncs = &handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + set = true + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + set = true + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + set = true + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + set = true + }, + } + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, funcs, nil) + }) + + Describe("EventHandler", func() { + var pod, newPod *corev1.Pod + + BeforeEach(func() { + pod = &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{Name: "test", Image: "test"}}, + }, + } + newPod = pod.DeepCopy() + newPod.Labels = map[string]string{"foo": "bar"} + }) + + It("should create a CreateEvent", func() { + funcs.CreateFunc = func(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + } + instance.OnAdd(pod) + }) + + It("should used Predicates to filter CreateEvents", func() { + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }}, + }) + set = false + instance.OnAdd(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + }) + instance.OnAdd(pod) + Expect(set).To(BeTrue()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }}, + }) + instance.OnAdd(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }}, + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + }) + instance.OnAdd(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + }) + instance.OnAdd(pod) + Expect(set).To(BeTrue()) + }) + + It("should not call Create EventHandler if the object is not a runtime.Object", func() { + instance.OnAdd(&metav1.ObjectMeta{}) + }) + + It("should not call Create EventHandler if the object does not have metadata", func() { + instance.OnAdd(FooRuntimeObject{}) + }) + + It("should create an UpdateEvent", func() { + funcs.UpdateFunc = func(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(evt.ObjectOld).To(Equal(pod)) + Expect(evt.ObjectNew).To(Equal(newPod)) + } + instance.OnUpdate(pod, newPod) + }) + + It("should used Predicates to filter UpdateEvents", func() { + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{UpdateFunc: func(updateEvent event.UpdateEvent) bool { return false }}, + }) + instance.OnUpdate(pod, newPod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }}, + }) + instance.OnUpdate(pod, newPod) + Expect(set).To(BeTrue()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }}, + predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return false }}, + }) + instance.OnUpdate(pod, newPod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return false }}, + predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }}, + }) + instance.OnUpdate(pod, newPod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }}, + }) + instance.OnUpdate(pod, newPod) + Expect(set).To(BeTrue()) + }) + + It("should not call Update EventHandler if the object is not a runtime.Object", func() { + instance.OnUpdate(&metav1.ObjectMeta{}, &corev1.Pod{}) + instance.OnUpdate(&corev1.Pod{}, &metav1.ObjectMeta{}) + }) + + It("should not call Update EventHandler if the object does not have metadata", func() { + instance.OnUpdate(FooRuntimeObject{}, &corev1.Pod{}) + instance.OnUpdate(&corev1.Pod{}, FooRuntimeObject{}) + }) + + It("should create a DeleteEvent", func() { + funcs.DeleteFunc = func(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + } + instance.OnDelete(pod) + }) + + It("should used Predicates to filter DeleteEvents", func() { + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }}, + }) + instance.OnDelete(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }}, + }) + instance.OnDelete(pod) + Expect(set).To(BeTrue()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }}, + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }}, + }) + instance.OnDelete(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }}, + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }}, + }) + instance.OnDelete(pod) + Expect(set).To(BeFalse()) + + set = false + instance = internal.NewEventHandler(ctx, &controllertest.Queue{}, setfuncs, []predicate.Predicate{ + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }}, + predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }}, + }) + instance.OnDelete(pod) + Expect(set).To(BeTrue()) + }) + + It("should not call Delete EventHandler if the object is not a runtime.Object", func() { + instance.OnDelete(&metav1.ObjectMeta{}) + }) + + It("should not call Delete EventHandler if the object does not have metadata", func() { + instance.OnDelete(FooRuntimeObject{}) + }) + + It("should create a DeleteEvent from a tombstone", func() { + + tombstone := cache.DeletedFinalStateUnknown{ + Obj: pod, + } + funcs.DeleteFunc = func(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + Expect(evt.DeleteStateUnknown).Should(BeTrue()) + } + + instance.OnDelete(tombstone) + }) + + It("should ignore tombstone objects without meta", func() { + tombstone := cache.DeletedFinalStateUnknown{Obj: Foo{}} + instance.OnDelete(tombstone) + }) + It("should ignore objects without meta", func() { + instance.OnAdd(Foo{}) + instance.OnUpdate(Foo{}, Foo{}) + instance.OnDelete(Foo{}) + }) + }) +}) + +type Foo struct{} + +var _ runtime.Object = FooRuntimeObject{} + +type FooRuntimeObject struct{} + +func (FooRuntimeObject) GetObjectKind() schema.ObjectKind { return nil } +func (FooRuntimeObject) DeepCopyObject() runtime.Object { return nil } diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go new file mode 100644 index 00000000000..b3a82271256 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go @@ -0,0 +1,117 @@ +package internal + +import ( + "context" + "errors" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). +type Kind struct { + // Type is the type of object to watch. e.g. &v1.Pod{} + Type client.Object + + // Cache used to watch APIs + Cache cache.Cache + + // started may contain an error if one was encountered during startup. If its closed and does not + // contain an error, startup and syncing finished. + started chan error + startCancel func() +} + +// Start is internal and should be called only by the Controller to register an EventHandler with the Informer +// to enqueue reconcile.Requests. +func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + if ks.Type == nil { + return fmt.Errorf("must create Kind with a non-nil object") + } + if ks.Cache == nil { + return fmt.Errorf("must create Kind with a non-nil cache") + } + + // cache.GetInformer will block until its context is cancelled if the cache was already started and it can not + // sync that informer (most commonly due to RBAC issues). + ctx, ks.startCancel = context.WithCancel(ctx) + ks.started = make(chan error) + go func() { + var ( + i cache.Informer + lastErr error + ) + + // Tries to get an informer until it returns true, + // an error or the specified context is cancelled or expired. + if err := wait.PollUntilContextCancel(ctx, 10*time.Second, true, func(ctx context.Context) (bool, error) { + // Lookup the Informer from the Cache and add an EventHandler which populates the Queue + i, lastErr = ks.Cache.GetInformer(ctx, ks.Type) + if lastErr != nil { + kindMatchErr := &meta.NoKindMatchError{} + switch { + case errors.As(lastErr, &kindMatchErr): + log.Error(lastErr, "if kind is a CRD, it should be installed before calling Start", + "kind", kindMatchErr.GroupKind) + case runtime.IsNotRegisteredError(lastErr): + log.Error(lastErr, "kind must be registered to the Scheme") + default: + log.Error(lastErr, "failed to get informer from cache") + } + return false, nil // Retry. + } + return true, nil + }); err != nil { + if lastErr != nil { + ks.started <- fmt.Errorf("failed to get informer from cache: %w", lastErr) + return + } + ks.started <- err + return + } + + _, err := i.AddEventHandler(NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + ks.started <- err + return + } + if !ks.Cache.WaitForCacheSync(ctx) { + // Would be great to return something more informative here + ks.started <- errors.New("cache did not sync") + } + close(ks.started) + }() + + return nil +} + +func (ks *Kind) String() string { + if ks.Type != nil { + return fmt.Sprintf("kind source: %T", ks.Type) + } + return "kind source: unknown type" +} + +// WaitForSync implements SyncingSource to allow controllers to wait with starting +// workers until the cache is synced. +func (ks *Kind) WaitForSync(ctx context.Context) error { + select { + case err := <-ks.started: + return err + case <-ctx.Done(): + ks.startCancel() + if errors.Is(ctx.Err(), context.Canceled) { + return nil + } + return fmt.Errorf("timed out waiting for cache to be synced for Kind %T", ks.Type) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go new file mode 100644 index 00000000000..84beb1b2654 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go @@ -0,0 +1,37 @@ +package syncs + +import ( + "context" + "reflect" + "sync" +) + +// MergeChans returns a channel that is closed when any of the input channels are signaled. +// The caller must call the returned CancelFunc to ensure no resources are leaked. +func MergeChans[T any](chans ...<-chan T) (<-chan T, context.CancelFunc) { + var once sync.Once + out := make(chan T) + cancel := make(chan T) + cancelFunc := func() { + once.Do(func() { + close(cancel) + }) + } + cases := make([]reflect.SelectCase, len(chans)+1) + for i := range chans { + cases[i] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(chans[i]), + } + } + cases[len(cases)-1] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(cancel), + } + go func() { + defer close(out) + _, _, _ = reflect.Select(cases) + }() + + return out, cancelFunc +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/OWNERS b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/OWNERS new file mode 100644 index 00000000000..25fda2ebacd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/devel/owners.md + +approvers: + - testing-integration-approvers diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/addr_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/addr_suite_test.go new file mode 100644 index 00000000000..3869bb02072 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/addr_suite_test.go @@ -0,0 +1,30 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addr_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestAddr(t *testing.T) { + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "Addr Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager.go new file mode 100644 index 00000000000..ffa33a88616 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager.go @@ -0,0 +1,142 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addr + +import ( + "errors" + "fmt" + "io/fs" + "net" + "os" + "path/filepath" + "strings" + "time" + + "sigs.k8s.io/controller-runtime/pkg/internal/flock" +) + +// TODO(directxman12): interface / release functionality for external port managers + +const ( + portReserveTime = 2 * time.Minute + portConflictRetry = 100 + portFilePrefix = "port-" +) + +var ( + cacheDir string +) + +func init() { + baseDir, err := os.UserCacheDir() + if err == nil { + cacheDir = filepath.Join(baseDir, "kubebuilder-envtest") + err = os.MkdirAll(cacheDir, 0o750) + } + if err != nil { + // Either we didn't get a cache directory, or we can't use it + baseDir = os.TempDir() + cacheDir = filepath.Join(baseDir, "kubebuilder-envtest") + err = os.MkdirAll(cacheDir, 0o750) + } + if err != nil { + panic(err) + } +} + +type portCache struct{} + +func (c *portCache) add(port int) (bool, error) { + // Remove outdated ports. + if err := fs.WalkDir(os.DirFS(cacheDir), ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() || !d.Type().IsRegular() || !strings.HasPrefix(path, portFilePrefix) { + return nil + } + info, err := d.Info() + if err != nil { + // No-op if file no longer exists; may have been deleted by another + // process/thread trying to allocate ports. + if errors.Is(err, fs.ErrNotExist) { + return nil + } + return err + } + if time.Since(info.ModTime()) > portReserveTime { + if err := os.Remove(filepath.Join(cacheDir, path)); err != nil { + // No-op if file no longer exists; may have been deleted by another + // process/thread trying to allocate ports. + if os.IsNotExist(err) { + return nil + } + return err + } + } + return nil + }); err != nil { + return false, err + } + // Try allocating new port, by acquiring a file. + path := fmt.Sprintf("%s/%s%d", cacheDir, portFilePrefix, port) + if err := flock.Acquire(path); errors.Is(err, flock.ErrAlreadyLocked) { + return false, nil + } else if err != nil { + return false, err + } + return true, nil +} + +var cache = &portCache{} + +func suggest(listenHost string) (*net.TCPListener, int, string, error) { + if listenHost == "" { + listenHost = "localhost" + } + addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(listenHost, "0")) + if err != nil { + return nil, -1, "", err + } + l, err := net.ListenTCP("tcp", addr) + if err != nil { + return nil, -1, "", err + } + return l, l.Addr().(*net.TCPAddr).Port, + addr.IP.String(), + nil +} + +// Suggest suggests an address a process can listen on. It returns +// a tuple consisting of a free port and the hostname resolved to its IP. +// It makes sure that new port allocated does not conflict with old ports +// allocated within 1 minute. +func Suggest(listenHost string) (int, string, error) { + for i := 0; i < portConflictRetry; i++ { + listener, port, resolvedHost, err := suggest(listenHost) + if err != nil { + return -1, "", err + } + defer listener.Close() + if ok, err := cache.add(port); ok { + return port, resolvedHost, nil + } else if err != nil { + return -1, "", err + } + } + return -1, "", fmt.Errorf("no free ports found after %d retries", portConflictRetry) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager_test.go new file mode 100644 index 00000000000..065e847dc54 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager_test.go @@ -0,0 +1,77 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addr_test + +import ( + "net" + "strconv" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/controller-runtime/pkg/internal/testing/addr" +) + +var _ = Describe("SuggestAddress", func() { + It("returns a free port and an address to bind to", func() { + port, host, err := addr.Suggest("") + + Expect(err).NotTo(HaveOccurred()) + Expect(host).To(Or(Equal("127.0.0.1"), Equal("::1"))) + Expect(port).NotTo(Equal(0)) + + addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, strconv.Itoa(port))) + Expect(err).NotTo(HaveOccurred()) + l, err := net.ListenTCP("tcp", addr) + defer func() { + Expect(l.Close()).To(Succeed()) + }() + Expect(err).NotTo(HaveOccurred()) + }) + + It("supports an explicit listenHost", func() { + port, host, err := addr.Suggest("localhost") + + Expect(err).NotTo(HaveOccurred()) + Expect(host).To(Or(Equal("127.0.0.1"), Equal("::1"))) + Expect(port).NotTo(Equal(0)) + + addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, strconv.Itoa(port))) + Expect(err).NotTo(HaveOccurred()) + l, err := net.ListenTCP("tcp", addr) + defer func() { + Expect(l.Close()).To(Succeed()) + }() + Expect(err).NotTo(HaveOccurred()) + }) + + It("supports a 0.0.0.0 listenHost", func() { + port, host, err := addr.Suggest("0.0.0.0") + + Expect(err).NotTo(HaveOccurred()) + Expect(host).To(Equal("0.0.0.0")) + Expect(port).NotTo(Equal(0)) + + addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, strconv.Itoa(port))) + Expect(err).NotTo(HaveOccurred()) + l, err := net.ListenTCP("tcp", addr) + defer func() { + Expect(l.Close()).To(Succeed()) + }() + Expect(err).NotTo(HaveOccurred()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/certs_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/certs_suite_test.go new file mode 100644 index 00000000000..3b3008c294b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/certs_suite_test.go @@ -0,0 +1,30 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certs_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestInternal(t *testing.T) { + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "TinyCA (Internal Certs) Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca.go new file mode 100644 index 00000000000..b4188237e69 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca.go @@ -0,0 +1,224 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certs + +// NB(directxman12): nothing has verified that this has good settings. In fact, +// the setting generated here are probably terrible, but they're fine for integration +// tests. These ABSOLUTELY SHOULD NOT ever be exposed in the public API. They're +// ONLY for use with envtest's ability to configure webhook testing. +// If I didn't otherwise not want to add a dependency on cfssl, I'd just use that. + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + crand "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "net" + "time" + + certutil "k8s.io/client-go/util/cert" +) + +var ( + ellipticCurve = elliptic.P256() + bigOne = big.NewInt(1) +) + +// CertPair is a private key and certificate for use for client auth, as a CA, or serving. +type CertPair struct { + Key crypto.Signer + Cert *x509.Certificate +} + +// CertBytes returns the PEM-encoded version of the certificate for this pair. +func (k CertPair) CertBytes() []byte { + return pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: k.Cert.Raw, + }) +} + +// AsBytes encodes keypair in the appropriate formats for on-disk storage (PEM and +// PKCS8, respectively). +func (k CertPair) AsBytes() (cert []byte, key []byte, err error) { + cert = k.CertBytes() + + rawKeyData, err := x509.MarshalPKCS8PrivateKey(k.Key) + if err != nil { + return nil, nil, fmt.Errorf("unable to encode private key: %w", err) + } + + key = pem.EncodeToMemory(&pem.Block{ + Type: "PRIVATE KEY", + Bytes: rawKeyData, + }) + + return cert, key, nil +} + +// TinyCA supports signing serving certs and client-certs, +// and can be used as an auth mechanism with envtest. +type TinyCA struct { + CA CertPair + orgName string + + nextSerial *big.Int +} + +// newPrivateKey generates a new private key of a relatively sane size (see +// rsaKeySize). +func newPrivateKey() (crypto.Signer, error) { + return ecdsa.GenerateKey(ellipticCurve, crand.Reader) +} + +// NewTinyCA creates a new a tiny CA utility for provisioning serving certs and client certs FOR TESTING ONLY. +// Don't use this for anything else! +func NewTinyCA() (*TinyCA, error) { + caPrivateKey, err := newPrivateKey() + if err != nil { + return nil, fmt.Errorf("unable to generate private key for CA: %w", err) + } + caCfg := certutil.Config{CommonName: "envtest-environment", Organization: []string{"envtest"}} + caCert, err := certutil.NewSelfSignedCACert(caCfg, caPrivateKey) + if err != nil { + return nil, fmt.Errorf("unable to generate certificate for CA: %w", err) + } + + return &TinyCA{ + CA: CertPair{Key: caPrivateKey, Cert: caCert}, + orgName: "envtest", + nextSerial: big.NewInt(1), + }, nil +} + +func (c *TinyCA) makeCert(cfg certutil.Config) (CertPair, error) { + now := time.Now() + + key, err := newPrivateKey() + if err != nil { + return CertPair{}, fmt.Errorf("unable to create private key: %w", err) + } + + serial := new(big.Int).Set(c.nextSerial) + c.nextSerial.Add(c.nextSerial, bigOne) + + template := x509.Certificate{ + Subject: pkix.Name{CommonName: cfg.CommonName, Organization: cfg.Organization}, + DNSNames: cfg.AltNames.DNSNames, + IPAddresses: cfg.AltNames.IPs, + SerialNumber: serial, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: cfg.Usages, + + // technically not necessary for testing, but let's set anyway just in case. + NotBefore: now.UTC(), + // 1 week -- the default for cfssl, and just long enough for a + // long-term test, but not too long that anyone would try to use this + // seriously. + NotAfter: now.Add(168 * time.Hour).UTC(), + } + + certRaw, err := x509.CreateCertificate(crand.Reader, &template, c.CA.Cert, key.Public(), c.CA.Key) + if err != nil { + return CertPair{}, fmt.Errorf("unable to create certificate: %w", err) + } + + cert, err := x509.ParseCertificate(certRaw) + if err != nil { + return CertPair{}, fmt.Errorf("generated invalid certificate, could not parse: %w", err) + } + + return CertPair{ + Key: key, + Cert: cert, + }, nil +} + +// NewServingCert returns a new CertPair for a serving HTTPS on localhost (or other specified names). +func (c *TinyCA) NewServingCert(names ...string) (CertPair, error) { + if len(names) == 0 { + names = []string{"localhost"} + } + dnsNames, ips, err := resolveNames(names) + if err != nil { + return CertPair{}, err + } + + return c.makeCert(certutil.Config{ + CommonName: "localhost", + Organization: []string{c.orgName}, + AltNames: certutil.AltNames{ + DNSNames: dnsNames, + IPs: ips, + }, + Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + }) +} + +// ClientInfo describes some Kubernetes user for the purposes of creating +// client certificates. +type ClientInfo struct { + // Name is the user name (embedded as the cert's CommonName) + Name string + // Groups are the groups to which this user belongs (embedded as the cert's + // Organization) + Groups []string +} + +// NewClientCert produces a new CertPair suitable for use with Kubernetes +// client cert auth with an API server validating based on this CA. +func (c *TinyCA) NewClientCert(user ClientInfo) (CertPair, error) { + return c.makeCert(certutil.Config{ + CommonName: user.Name, + Organization: user.Groups, + Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + }) +} + +func resolveNames(names []string) ([]string, []net.IP, error) { + dnsNames := []string{} + ips := []net.IP{} + for _, name := range names { + if name == "" { + continue + } + ip := net.ParseIP(name) + if ip == nil { + dnsNames = append(dnsNames, name) + // Also resolve to IPs. + nameIPs, err := net.LookupHost(name) + if err != nil { + return nil, nil, err + } + for _, nameIP := range nameIPs { + ip = net.ParseIP(nameIP) + if ip != nil { + ips = append(ips, ip) + } + } + } else { + ips = append(ips, ip) + } + } + return dnsNames, ips, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca_test.go new file mode 100644 index 00000000000..6e0540ba9f0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/certs/tinyca_test.go @@ -0,0 +1,254 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certs_test + +import ( + "crypto/x509" + "encoding/pem" + "math/big" + "net" + "sort" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + + "sigs.k8s.io/controller-runtime/pkg/internal/testing/certs" +) + +var _ = Describe("TinyCA", func() { + var ca *certs.TinyCA + + BeforeEach(func() { + var err error + ca, err = certs.NewTinyCA() + Expect(err).NotTo(HaveOccurred(), "should be able to initialize the CA") + }) + + Describe("the CA certs themselves", func() { + It("should be retrievable as a cert pair", func() { + Expect(ca.CA.Key).NotTo(BeNil(), "should have a key") + Expect(ca.CA.Cert).NotTo(BeNil(), "should have a cert") + }) + + It("should be usable for signing & verifying", func() { + Expect(ca.CA.Cert.KeyUsage&x509.KeyUsageCertSign).NotTo(Equal(0), "should be usable for cert signing") + Expect(ca.CA.Cert.KeyUsage&x509.KeyUsageDigitalSignature).NotTo(Equal(0), "should be usable for signature verifying") + }) + }) + + It("should produce unique serials among all generated certificates of all types", func() { + By("generating a few cert pairs for both serving and client auth") + firstCerts, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred()) + secondCerts, err := ca.NewClientCert(certs.ClientInfo{Name: "user"}) + Expect(err).NotTo(HaveOccurred()) + thirdCerts, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred()) + + By("checking that they have different serials") + serials := []*big.Int{ + firstCerts.Cert.SerialNumber, + secondCerts.Cert.SerialNumber, + thirdCerts.Cert.SerialNumber, + } + // quick uniqueness check of numbers: sort, then you only have to compare sequential entries + sort.Slice(serials, func(i, j int) bool { + return serials[i].Cmp(serials[j]) == -1 + }) + Expect(serials[1].Cmp(serials[0])).NotTo(Equal(0), "serials shouldn't be equal") + Expect(serials[2].Cmp(serials[1])).NotTo(Equal(0), "serials shouldn't be equal") + }) + + Describe("Generated serving certs", func() { + It("should be valid for short enough to avoid production usage, but long enough for long-running tests", func() { + cert, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred(), "should be able to generate the serving certs") + + duration := time.Until(cert.Cert.NotAfter) + Expect(duration).To(BeNumerically("<=", 168*time.Hour), "not-after should be short-ish (<= 1 week)") + Expect(duration).To(BeNumerically(">=", 2*time.Hour), "not-after should be enough for long tests (couple of hours)") + }) + + Context("when encoding names", func() { + var cert certs.CertPair + BeforeEach(func() { + By("generating a serving cert with IPv4 & IPv6 addresses, and DNS names") + var err error + // IPs are in the "example & docs" blocks for IPv4 (TEST-NET-1) & IPv6 + cert, err = ca.NewServingCert("192.0.2.1", "localhost", "2001:db8::") + Expect(err).NotTo(HaveOccurred(), "should be able to create the serving certs") + }) + + It("should encode all non-IP names as DNS SANs", func() { + Expect(cert.Cert.DNSNames).To(ConsistOf("localhost")) + }) + + It("should encode all IP names as IP SANs", func() { + // NB(directxman12): this is non-exhaustive because we also + // convert DNS SANs to IPs too (see test below) + Expect(cert.Cert.IPAddresses).To(ContainElements( + // normalize the elements with To16 so we can compare them to the output of + // of ParseIP safely (the alternative is a custom matcher that calls Equal, + // but this is easier) + WithTransform(net.IP.To16, Equal(net.ParseIP("192.0.2.1"))), + WithTransform(net.IP.To16, Equal(net.ParseIP("2001:db8::"))), + )) + }) + + It("should add the corresponding IP address(es) (as IP SANs) for DNS names", func() { + // NB(directxman12): we currently fail if the lookup fails. + // I'm not certain this is the best idea (both the bailing on + // error and the actual idea), so if this causes issues, you + // might want to reconsider. + + localhostAddrs, err := net.LookupHost("localhost") + Expect(err).NotTo(HaveOccurred(), "should be able to find IPs for localhost") + localhostIPs := make([]interface{}, len(localhostAddrs)) + for i, addr := range localhostAddrs { + // normalize the elements with To16 so we can compare them to the output of + // of ParseIP safely (the alternative is a custom matcher that calls Equal, + // but this is easier) + localhostIPs[i] = WithTransform(net.IP.To16, Equal(net.ParseIP(addr))) + } + Expect(cert.Cert.IPAddresses).To(ContainElements(localhostIPs...)) + }) + }) + + It("should assume a name of localhost (DNS SAN) if no names are given", func() { + cert, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred(), "should be able to generate a serving cert with the default name") + Expect(cert.Cert.DNSNames).To(ConsistOf("localhost"), "the default DNS name should be localhost") + + }) + + It("should be usable for server auth, verifying, and enciphering", func() { + cert, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred(), "should be able to generate a serving cert") + + Expect(cert.Cert.KeyUsage&x509.KeyUsageKeyEncipherment).NotTo(Equal(0), "should be usable for key enciphering") + Expect(cert.Cert.KeyUsage&x509.KeyUsageDigitalSignature).NotTo(Equal(0), "should be usable for signature verifying") + Expect(cert.Cert.ExtKeyUsage).To(ContainElement(x509.ExtKeyUsageServerAuth), "should be usable for server auth") + + }) + + It("should be signed by the CA", func() { + cert, err := ca.NewServingCert() + Expect(err).NotTo(HaveOccurred(), "should be able to generate a serving cert") + Expect(cert.Cert.CheckSignatureFrom(ca.CA.Cert)).To(Succeed()) + }) + }) + + Describe("Generated client certs", func() { + var cert certs.CertPair + BeforeEach(func() { + var err error + cert, err = ca.NewClientCert(certs.ClientInfo{ + Name: "user", + Groups: []string{"group1", "group2"}, + }) + Expect(err).NotTo(HaveOccurred(), "should be able to create a client cert") + }) + + It("should be valid for short enough to avoid production usage, but long enough for long-running tests", func() { + duration := time.Until(cert.Cert.NotAfter) + Expect(duration).To(BeNumerically("<=", 168*time.Hour), "not-after should be short-ish (<= 1 week)") + Expect(duration).To(BeNumerically(">=", 2*time.Hour), "not-after should be enough for long tests (couple of hours)") + }) + + It("should be usable for client auth, verifying, and enciphering", func() { + Expect(cert.Cert.KeyUsage&x509.KeyUsageKeyEncipherment).NotTo(Equal(0), "should be usable for key enciphering") + Expect(cert.Cert.KeyUsage&x509.KeyUsageDigitalSignature).NotTo(Equal(0), "should be usable for signature verifying") + Expect(cert.Cert.ExtKeyUsage).To(ContainElement(x509.ExtKeyUsageClientAuth), "should be usable for client auth") + }) + + It("should encode the user name as the common name", func() { + Expect(cert.Cert.Subject.CommonName).To(Equal("user")) + }) + + It("should encode the groups as the organization values", func() { + Expect(cert.Cert.Subject.Organization).To(ConsistOf("group1", "group2")) + }) + + It("should be signed by the CA", func() { + Expect(cert.Cert.CheckSignatureFrom(ca.CA.Cert)).To(Succeed()) + }) + }) +}) + +var _ = Describe("Certificate Pairs", func() { + var pair certs.CertPair + BeforeEach(func() { + ca, err := certs.NewTinyCA() + Expect(err).NotTo(HaveOccurred(), "should be able to generate a cert pair") + + pair = ca.CA + }) + + Context("when serializing just the public key", func() { + It("should serialize into a CERTIFICATE PEM block", func() { + bytes := pair.CertBytes() + Expect(bytes).NotTo(BeEmpty(), "should produce some cert bytes") + + block, rest := pem.Decode(bytes) + Expect(rest).To(BeEmpty(), "shouldn't have any data besides the PEM block") + + Expect(block).To(PointTo(MatchAllFields(Fields{ + "Type": Equal("CERTIFICATE"), + "Headers": BeEmpty(), + "Bytes": Equal(pair.Cert.Raw), + }))) + }) + }) + + Context("when serializing both parts", func() { + var certBytes, keyBytes []byte + BeforeEach(func() { + var err error + certBytes, keyBytes, err = pair.AsBytes() + Expect(err).NotTo(HaveOccurred(), "should be able to serialize the pair") + }) + + It("should serialize the private key in PKCS8 form in a PRIVATE KEY PEM block", func() { + Expect(keyBytes).NotTo(BeEmpty(), "should produce some key bytes") + + By("decoding & checking the PEM block") + block, rest := pem.Decode(keyBytes) + Expect(rest).To(BeEmpty(), "shouldn't have any data besides the PEM block") + + Expect(block.Type).To(Equal("PRIVATE KEY")) + + By("decoding & checking the PKCS8 data") + Expect(x509.ParsePKCS8PrivateKey(block.Bytes)).NotTo(BeNil(), "should be able to parse back the private key") + }) + + It("should serialize the public key into a CERTIFICATE PEM block", func() { + Expect(certBytes).NotTo(BeEmpty(), "should produce some cert bytes") + + block, rest := pem.Decode(certBytes) + Expect(rest).To(BeEmpty(), "shouldn't have any data besides the PEM block") + + Expect(block).To(PointTo(MatchAllFields(Fields{ + "Type": Equal("CERTIFICATE"), + "Headers": BeEmpty(), + "Bytes": Equal(pair.Cert.Raw), + }))) + }) + + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver.go new file mode 100644 index 00000000000..c9a1a232ea9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver.go @@ -0,0 +1,468 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane + +import ( + "fmt" + "io" + "net/url" + "os" + "path/filepath" + "strconv" + "time" + + "sigs.k8s.io/controller-runtime/pkg/internal/testing/addr" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/certs" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +const ( + // saKeyFile is the name of the service account signing private key file. + saKeyFile = "sa-signer.key" + // saKeyFile is the name of the service account signing public key (cert) file. + saCertFile = "sa-signer.crt" +) + +// SecureServing provides/configures how the API server serves on the secure port. +type SecureServing struct { + // ListenAddr contains the host & port to serve on. + // + // Configurable. If unset, it will be defaulted. + process.ListenAddr + // CA contains the CA that signed the API server's serving certificates. + // + // Read-only. + CA []byte + // Authn can be used to provision users, and override what type of + // authentication is used to provision users. + // + // Configurable. If unset, it will be defaulted. + Authn +} + +// APIServer knows how to run a kubernetes apiserver. +type APIServer struct { + // URL is the address the ApiServer should listen on for client + // connections. + // + // If set, this will configure the *insecure* serving details. + // If unset, it will contain the insecure port if insecure serving is enabled, + // and otherwise will contain the secure port. + // + // If this is not specified, we default to a random free port on localhost. + // + // Deprecated: use InsecureServing (for the insecure URL) or SecureServing, ideally. + URL *url.URL + + // SecurePort is the additional secure port that the APIServer should listen on. + // + // If set, this will override SecureServing.Port. + // + // Deprecated: use SecureServing. + SecurePort int + + // SecureServing indicates how the API server will serve on the secure port. + // + // Some parts are configurable. Will be defaulted if unset. + SecureServing + + // InsecureServing indicates how the API server will serve on the insecure port. + // + // If unset, the insecure port will be disabled. Set to an empty struct to get + // default values. + // + // Deprecated: does not work with Kubernetes versions 1.20 and above. Use secure + // serving instead. + InsecureServing *process.ListenAddr + + // Path is the path to the apiserver binary. + // + // If this is left as the empty string, we will attempt to locate a binary, + // by checking for the TEST_ASSET_KUBE_APISERVER environment variable, and + // the default test assets directory. See the "Binaries" section above (in + // doc.go) for details. + Path string + + // Args is a list of arguments which will passed to the APIServer binary. + // Before they are passed on, they will be evaluated as go-template strings. + // This means you can use fields which are defined and exported on this + // APIServer struct (e.g. "--cert-dir={{ .Dir }}"). + // Those templates will be evaluated after the defaulting of the APIServer's + // fields has already happened and just before the binary actually gets + // started. Thus you have access to calculated fields like `URL` and others. + // + // If not specified, the minimal set of arguments to run the APIServer will + // be used. + // + // They will be loaded into the same argument set as Configure. Each flag + // will be Append-ed to the configured arguments just before launch. + // + // Deprecated: use Configure instead. + Args []string + + // CertDir is a path to a directory containing whatever certificates the + // APIServer will need. + // + // If left unspecified, then the Start() method will create a fresh temporary + // directory, and the Stop() method will clean it up. + CertDir string + + // EtcdURL is the URL of the Etcd the APIServer should use. + // + // If this is not specified, the Start() method will return an error. + EtcdURL *url.URL + + // StartTimeout, StopTimeout specify the time the APIServer is allowed to + // take when starting and stoppping before an error is emitted. + // + // If not specified, these default to 20 seconds. + StartTimeout time.Duration + StopTimeout time.Duration + + // Out, Err specify where APIServer should write its StdOut, StdErr to. + // + // If not specified, the output will be discarded. + Out io.Writer + Err io.Writer + + processState *process.State + + // args contains the structured arguments to use for running the API server + // Lazily initialized by .Configure(), Defaulted eventually with .defaultArgs() + args *process.Arguments +} + +// Configure returns Arguments that may be used to customize the +// flags used to launch the API server. A set of defaults will +// be applied underneath. +func (s *APIServer) Configure() *process.Arguments { + if s.args == nil { + s.args = process.EmptyArguments() + } + return s.args +} + +// Start starts the apiserver, waits for it to come up, and returns an error, +// if occurred. +func (s *APIServer) Start() error { + if err := s.prepare(); err != nil { + return err + } + return s.processState.Start(s.Out, s.Err) +} + +func (s *APIServer) prepare() error { + if err := s.setProcessState(); err != nil { + return err + } + return s.Authn.Start() +} + +// configurePorts configures the serving ports for this API server. +// +// Most of this method currently deals with making the deprecated fields +// take precedence over the new fields. +func (s *APIServer) configurePorts() error { + // prefer the old fields to the new fields if a user set one, + // otherwise, default the new fields and populate the old ones. + + // Insecure: URL, InsecureServing + if s.URL != nil { + s.InsecureServing = &process.ListenAddr{ + Address: s.URL.Hostname(), + Port: s.URL.Port(), + } + } else if insec := s.InsecureServing; insec != nil { + if insec.Port == "" || insec.Address == "" { + port, host, err := addr.Suggest("") + if err != nil { + return fmt.Errorf("unable to provision unused insecure port: %w", err) + } + s.InsecureServing.Port = strconv.Itoa(port) + s.InsecureServing.Address = host + } + s.URL = s.InsecureServing.URL("http", "") + } + + // Secure: SecurePort, SecureServing + if s.SecurePort != 0 { + s.SecureServing.Port = strconv.Itoa(s.SecurePort) + // if we don't have an address, try the insecure address, and otherwise + // default to loopback. + if s.SecureServing.Address == "" { + if s.InsecureServing != nil { + s.SecureServing.Address = s.InsecureServing.Address + } else { + s.SecureServing.Address = "127.0.0.1" + } + } + } else if s.SecureServing.Port == "" || s.SecureServing.Address == "" { + port, host, err := addr.Suggest("") + if err != nil { + return fmt.Errorf("unable to provision unused secure port: %w", err) + } + s.SecureServing.Port = strconv.Itoa(port) + s.SecureServing.Address = host + s.SecurePort = port + } + + return nil +} + +func (s *APIServer) setProcessState() error { + if s.EtcdURL == nil { + return fmt.Errorf("expected EtcdURL to be configured") + } + + var err error + + // unconditionally re-set this so we can successfully restart + // TODO(directxman12): we supported this in the past, but do we actually + // want to support re-using an API server object to restart? The loss + // of provisioned users is surprising to say the least. + s.processState = &process.State{ + Dir: s.CertDir, + Path: s.Path, + StartTimeout: s.StartTimeout, + StopTimeout: s.StopTimeout, + } + if err := s.processState.Init("kube-apiserver"); err != nil { + return err + } + + if err := s.configurePorts(); err != nil { + return err + } + + // the secure port will always be on, so use that + s.processState.HealthCheck.URL = *s.SecureServing.URL("https", "/healthz") + + s.CertDir = s.processState.Dir + s.Path = s.processState.Path + s.StartTimeout = s.processState.StartTimeout + s.StopTimeout = s.processState.StopTimeout + + if err := s.populateAPIServerCerts(); err != nil { + return err + } + + if s.SecureServing.Authn == nil { + authn, err := NewCertAuthn() + if err != nil { + return err + } + s.SecureServing.Authn = authn + } + + if err := s.Authn.Configure(s.CertDir, s.Configure()); err != nil { + return err + } + + // NB(directxman12): insecure port is a mess: + // - 1.19 and below have the `--insecure-port` flag, and require it to be set to zero to + // disable it, otherwise the default will be used and we'll conflict. + // - 1.20 requires the flag to be unset or set to zero, and yells at you if you configure it + // - 1.24 won't have the flag at all... + // + // In an effort to automatically do the right thing during this mess, we do feature discovery + // on the flags, and hope that we've "parsed" them properly. + // + // TODO(directxman12): once we support 1.20 as the min version (might be when 1.24 comes out, + // might be around 1.25 or 1.26), remove this logic and the corresponding line in API server's + // default args. + if err := s.discoverFlags(); err != nil { + return err + } + + s.processState.Args, s.Args, err = process.TemplateAndArguments(s.Args, s.Configure(), process.TemplateDefaults{ //nolint:staticcheck + Data: s, + Defaults: s.defaultArgs(), + MinimalDefaults: map[string][]string{ + // as per kubernetes-sigs/controller-runtime#641, we need this (we + // probably need other stuff too, but this is the only thing that was + // previously considered a "minimal default") + "service-cluster-ip-range": {"10.0.0.0/24"}, + + // we need *some* authorization mode for health checks on the secure port, + // so default to RBAC unless the user set something else (in which case + // this'll be ignored due to SliceToArguments using AppendNoDefaults). + "authorization-mode": {"RBAC"}, + }, + }) + if err != nil { + return err + } + + return nil +} + +// discoverFlags checks for certain flags that *must* be set in certain +// versions, and *must not* be set in others. +func (s *APIServer) discoverFlags() error { + // Present: <1.24, Absent: >= 1.24 + present, err := s.processState.CheckFlag("insecure-port") + if err != nil { + return err + } + + if !present { + s.Configure().Disable("insecure-port") + } + + return nil +} + +func (s *APIServer) defaultArgs() map[string][]string { + args := map[string][]string{ + "service-cluster-ip-range": {"10.0.0.0/24"}, + "allow-privileged": {"true"}, + // we're keeping this disabled because if enabled, default SA is + // missing which would force all tests to create one in normal + // apiserver operation this SA is created by controller, but that is + // not run in integration environment + "disable-admission-plugins": {"ServiceAccount"}, + "cert-dir": {s.CertDir}, + "authorization-mode": {"RBAC"}, + "secure-port": {s.SecureServing.Port}, + // NB(directxman12): previously we didn't set the bind address for the secure + // port. It *shouldn't* make a difference unless people are doing something really + // funky, but if you start to get bug reports look here ;-) + "bind-address": {s.SecureServing.Address}, + + // required on 1.20+, fine to leave on for <1.20 + "service-account-issuer": {s.SecureServing.URL("https", "/").String()}, + "service-account-key-file": {filepath.Join(s.CertDir, saCertFile)}, + "service-account-signing-key-file": {filepath.Join(s.CertDir, saKeyFile)}, + } + if s.EtcdURL != nil { + args["etcd-servers"] = []string{s.EtcdURL.String()} + } + if s.URL != nil { + args["insecure-port"] = []string{s.URL.Port()} + args["insecure-bind-address"] = []string{s.URL.Hostname()} + } else { + // TODO(directxman12): remove this once 1.21 is the lowest version we support + // (this might be a while, but this line'll break as of 1.24, so see the comment + // in Start + args["insecure-port"] = []string{"0"} + } + return args +} + +func (s *APIServer) populateAPIServerCerts() error { + _, statErr := os.Stat(filepath.Join(s.CertDir, "apiserver.crt")) + if !os.IsNotExist(statErr) { + return statErr + } + + ca, err := certs.NewTinyCA() + if err != nil { + return err + } + + servingCerts, err := ca.NewServingCert() + if err != nil { + return err + } + + certData, keyData, err := servingCerts.AsBytes() + if err != nil { + return err + } + + if err := os.WriteFile(filepath.Join(s.CertDir, "apiserver.crt"), certData, 0640); err != nil { //nolint:gosec + return err + } + if err := os.WriteFile(filepath.Join(s.CertDir, "apiserver.key"), keyData, 0640); err != nil { //nolint:gosec + return err + } + + s.SecureServing.CA = ca.CA.CertBytes() + + // service account signing files too + saCA, err := certs.NewTinyCA() + if err != nil { + return err + } + + saCert, saKey, err := saCA.CA.AsBytes() + if err != nil { + return err + } + + if err := os.WriteFile(filepath.Join(s.CertDir, saCertFile), saCert, 0640); err != nil { //nolint:gosec + return err + } + return os.WriteFile(filepath.Join(s.CertDir, saKeyFile), saKey, 0640) //nolint:gosec +} + +// Stop stops this process gracefully, waits for its termination, and cleans up +// the CertDir if necessary. +func (s *APIServer) Stop() error { + if s.processState != nil { + if s.processState.DirNeedsCleaning { + s.CertDir = "" // reset the directory if it was randomly allocated, so that we can safely restart + } + if err := s.processState.Stop(); err != nil { + return err + } + } + return s.Authn.Stop() +} + +// APIServerDefaultArgs exposes the default args for the APIServer so that you +// can use those to append your own additional arguments. +// +// Note that these arguments don't handle newer API servers well to due the more +// complex feature detection neeeded. It's recommended that you switch to .Configure +// as you upgrade API server versions. +// +// Deprecated: use APIServer.Configure(). +var APIServerDefaultArgs = []string{ + "--advertise-address=127.0.0.1", + "--etcd-servers={{ if .EtcdURL }}{{ .EtcdURL.String }}{{ end }}", + "--cert-dir={{ .CertDir }}", + "--insecure-port={{ if .URL }}{{ .URL.Port }}{{else}}0{{ end }}", + "{{ if .URL }}--insecure-bind-address={{ .URL.Hostname }}{{ end }}", + "--secure-port={{ if .SecurePort }}{{ .SecurePort }}{{ end }}", + // we're keeping this disabled because if enabled, default SA is missing which would force all tests to create one + // in normal apiserver operation this SA is created by controller, but that is not run in integration environment + "--disable-admission-plugins=ServiceAccount", + "--service-cluster-ip-range=10.0.0.0/24", + "--allow-privileged=true", + // NB(directxman12): we also enable RBAC if nothing else was enabled +} + +// PrepareAPIServer is an internal-only (NEVER SHOULD BE EXPOSED) +// function that sets up the API server just before starting it, +// without actually starting it. This saves time on tests. +// +// NB(directxman12): do not expose this outside of internal -- it's unsafe to +// use, because things like port allocation could race even more than they +// currently do if you later call start! +func PrepareAPIServer(s *APIServer) error { + return s.prepare() +} + +// APIServerArguments is an internal-only (NEVER SHOULD BE EXPOSED) +// function that sets up the API server just before starting it, +// without actually starting it. It's public to make testing easier. +// +// NB(directxman12): do not expose this outside of internal. +func APIServerArguments(s *APIServer) []string { + return s.processState.Args +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver_test.go new file mode 100644 index 00000000000..6ce1577d457 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/apiserver_test.go @@ -0,0 +1,295 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + "errors" + "net/url" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +var _ = Describe("APIServer", func() { + var server *APIServer + BeforeEach(func() { + server = &APIServer{ + EtcdURL: &url.URL{}, + } + }) + JustBeforeEach(func() { + Expect(PrepareAPIServer(server)).To(Succeed()) + }) + Describe("setting up serving hosts & ports", func() { + Context("when URL is set", func() { + BeforeEach(func() { + server.URL = &url.URL{Scheme: "http", Host: "localhost:8675", Path: "/some-path"} + }) + + Context("when insecure serving is also set", func() { + BeforeEach(func() { + server.InsecureServing = &process.ListenAddr{ + Address: "localhost", + Port: "1234", + } + }) + + It("should override the existing insecure serving", func() { + Expect(server.InsecureServing).To(Equal(&process.ListenAddr{ + Address: "localhost", + Port: "8675", + })) + }) + }) + + It("should set insecure serving off of that", func() { + Expect(server.InsecureServing).To(Equal(&process.ListenAddr{ + Address: "localhost", + Port: "8675", + })) + }) + + It("should keep URL as-is", func() { + Expect(server.URL.String()).To(Equal("http://localhost:8675/some-path")) + }) + }) + + Context("when URL is not set but InsecureServing is set", func() { + BeforeEach(func() { + server.InsecureServing = &process.ListenAddr{} + }) + + Context("when host and port are set", func() { + BeforeEach(func() { + server.InsecureServing.Address = "localhost" + server.InsecureServing.Port = "8675" + }) + It("should set URL from InsecureServing", func() { + Expect(server.URL.String()).To(Equal("http://localhost:8675")) + }) + + It("should leave InsecureServing as-is if address and port are filled out", func() { + Expect(server.InsecureServing).To(Equal(&process.ListenAddr{ + Address: "localhost", + Port: "8675", + })) + }) + }) + + Context("when address and port are not filled out", func() { + BeforeEach(func() { + server.InsecureServing = &process.ListenAddr{} + }) + It("should default an insecure port", func() { + Expect(server.InsecureServing.Port).NotTo(BeEmpty()) + }) + It("should set URL from InsecureServing", func() { + Expect(server.URL.String()).To(Equal("http://" + server.InsecureServing.Address + ":" + server.InsecureServing.Port)) + }) + }) + }) + + Context("when neither URL or InsecureServing are set", func() { + It("should not default either of them", func() { + Expect(server.URL).To(BeNil(), "no URL should be set") + Expect(server.InsecureServing).To(BeNil(), "no insecure serving details should be set") + }) + }) + + Context("when SecureServing host & port are set", func() { + BeforeEach(func() { + server.Address = "localhost" + server.Port = "8675" + }) + + It("should leave SecureServing as-is", func() { + Expect(server.SecureServing.Address).To(Equal("localhost")) + Expect(server.SecureServing.Port).To(Equal("8675")) + }) + }) + + Context("when SecureServing is not set", func() { + It("should be defaulted with a random port", func() { + Expect(server.Port).NotTo(Equal(0)) + }) + }) + }) + + It("should default authn if not set", func() { + Expect(server.Authn).NotTo(BeNil()) + }) + + Describe("argument defaulting", func() { + // NB(directxman12): most of the templating vs configure logic is tested + // in arguments/arguments_test.go, so just test secure vs insecure port logic here + + Context("when insecure serving is set, on a binary that supports it", func() { + BeforeEach(func() { + server.InsecureServing = &process.ListenAddr{ + Address: "localhost", + Port: "8675", + } + server.Path = "./testdata/fake-1.19-apiserver.sh" + }) + It("should set the insecure-port and insecure-bind-address fields from insecureserving", func() { + Expect(APIServerArguments(server)).To(ContainElements( + "--insecure-port=8675", + "--insecure-bind-address=localhost", + )) + }) + }) + + Context("when insecureserving is disabled, on binaries with no insecure-port flag", func() { + BeforeEach(func() { + server.Path = "./testdata/fake-1.20-apiserver.sh" + }) + It("should not try to explicitly disable the insecure port", func() { + Expect(APIServerArguments(server)).NotTo(ContainElement(HavePrefix("--insecure-port"))) + }) + }) + + Context("when insecureserving is disabled, on binaries with an insecure-port flag", func() { + BeforeEach(func() { + server.Path = "./testdata/fake-1.19-apiserver.sh" + }) + It("should explicitly disable the insecure port", func() { + Expect(APIServerArguments(server)).To(ContainElement("--insecure-port=0")) + }) + }) + + Context("when given legacy-style template arguments", func() { + BeforeEach(func() { + server.Args = []string{"--foo=bar", "--baz={{ .Port }}"} + }) + It("should use the passed in args with the minimal required defaults", func() { + Expect(APIServerArguments(server)).To(ConsistOf( + "--foo=bar", + MatchRegexp(`--baz=\d+`), + "--service-cluster-ip-range=10.0.0.0/24", + MatchRegexp("--client-ca-file=.+"), + "--authorization-mode=RBAC", + )) + }) + }) + }) + + Describe("setting up auth", func() { + var auth *fakeAuthn + BeforeEach(func() { + auth = &fakeAuthn{ + setFlag: true, + } + server.Authn = auth + }) + It("should configure with the cert dir", func() { + Expect(auth.workDir).To(Equal(server.CertDir)) + }) + It("should pass its args to be configured", func() { + Expect(server.Configure().Get("configure-called").Get(nil)).To(ConsistOf("true")) + }) + + Context("when configuring auth errors out", func() { + It("should fail to configure", func() { + server := &APIServer{ + EtcdURL: &url.URL{}, + SecureServing: SecureServing{ + Authn: auth, + }, + } + auth.configureErr = errors.New("Oh no") + Expect(PrepareAPIServer(server)).NotTo(Succeed()) + }) + }) + }) + + Describe("managing", func() { + // some of these tests are combined for speed reasons -- starting the apiserver + // takes a while, relatively speaking + + var ( + auth *fakeAuthn + etcd *Etcd + ) + BeforeEach(func() { + etcd = &Etcd{} + Expect(etcd.Start()).To(Succeed()) + server.EtcdURL = etcd.URL + + auth = &fakeAuthn{} + server.Authn = auth + }) + AfterEach(func() { + Expect(etcd.Stop()).To(Succeed()) + }) + + Context("after starting", func() { + BeforeEach(func() { + Expect(server.Start()).To(Succeed()) + }) + + It("should stop successfully, and stop auth", func() { + Expect(server.Stop()).To(Succeed()) + Expect(auth.stopCalled).To(BeTrue()) + }) + }) + + It("should fail to start when auth fails to start", func() { + auth.startErr = errors.New("Oh no") + Expect(server.Start()).NotTo(Succeed()) + }) + + It("should start successfully & start auth", func() { + Expect(server.Start()).To(Succeed()) + defer func() { Expect(server.Stop()).To(Succeed()) }() + Expect(auth.startCalled).To(BeTrue()) + }) + }) +}) + +type fakeAuthn struct { + workDir string + + startCalled bool + stopCalled bool + setFlag bool + + configureErr error + startErr error +} + +func (f *fakeAuthn) Configure(workDir string, args *process.Arguments) error { + f.workDir = workDir + if f.setFlag { + args.Set("configure-called", "true") + } + return f.configureErr +} +func (f *fakeAuthn) Start() error { + f.startCalled = true + return f.startErr +} +func (f *fakeAuthn) AddUser(user User, baseCfg *rest.Config) (*rest.Config, error) { + return nil, nil +} +func (f *fakeAuthn) Stop() error { + f.stopCalled = true + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth.go new file mode 100644 index 00000000000..16c86a712c1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth.go @@ -0,0 +1,142 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane + +import ( + "fmt" + "os" + "path/filepath" + + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/certs" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +// User represents a Kubernetes user. +type User struct { + // Name is the user's Name. + Name string + // Groups are the groups to which the user belongs. + Groups []string +} + +// Authn knows how to configure an API server for a particular type of authentication, +// and provision users under that authentication scheme. +// +// The methods must be called in the following order (as presented below in the interface +// for a mnemonic): +// +// 1. Configure +// 2. Start +// 3. AddUsers (0+ calls) +// 4. Stop. +type Authn interface { + // Configure provides the working directory to this authenticator, + // and configures the given API server arguments to make use of this authenticator. + // + // Should be called first. + Configure(workDir string, args *process.Arguments) error + // Start runs this authenticator. Will be called just before API server start. + // + // Must be called after Configure. + Start() error + // AddUser provisions a user, returning a copy of the given base rest.Config + // configured to authenticate as that users. + // + // May only be called while the authenticator is "running". + AddUser(user User, baseCfg *rest.Config) (*rest.Config, error) + // Stop shuts down this authenticator. + Stop() error +} + +// CertAuthn is an authenticator (Authn) that makes use of client certificate authn. +type CertAuthn struct { + // ca is the CA used to sign the client certs + ca *certs.TinyCA + // certDir is the directory used to write the CA crt file + // so that the API server can read it. + certDir string +} + +// NewCertAuthn creates a new client-cert-based Authn with a new CA. +func NewCertAuthn() (*CertAuthn, error) { + ca, err := certs.NewTinyCA() + if err != nil { + return nil, fmt.Errorf("unable to provision client certificate auth CA: %w", err) + } + return &CertAuthn{ + ca: ca, + }, nil +} + +// AddUser provisions a new user that's authenticated via certificates, with +// the given uesrname and groups embedded in the certificate as expected by the +// API server. +func (c *CertAuthn) AddUser(user User, baseCfg *rest.Config) (*rest.Config, error) { + certs, err := c.ca.NewClientCert(certs.ClientInfo{ + Name: user.Name, + Groups: user.Groups, + }) + if err != nil { + return nil, fmt.Errorf("unable to create client certificates for %s: %w", user.Name, err) + } + + crt, key, err := certs.AsBytes() + if err != nil { + return nil, fmt.Errorf("unable to serialize client certificates for %s: %w", user.Name, err) + } + + cfg := rest.CopyConfig(baseCfg) + cfg.CertData = crt + cfg.KeyData = key + + return cfg, nil +} + +// caCrtPath returns the path to the on-disk client-cert CA crt file. +func (c *CertAuthn) caCrtPath() string { + return filepath.Join(c.certDir, "client-cert-auth-ca.crt") +} + +// Configure provides the working directory to this authenticator, +// and configures the given API server arguments to make use of this authenticator. +func (c *CertAuthn) Configure(workDir string, args *process.Arguments) error { + c.certDir = workDir + args.Set("client-ca-file", c.caCrtPath()) + return nil +} + +// Start runs this authenticator. Will be called just before API server start. +// +// Must be called after Configure. +func (c *CertAuthn) Start() error { + if len(c.certDir) == 0 { + return fmt.Errorf("start called before configure") + } + caCrt := c.ca.CA.CertBytes() + if err := os.WriteFile(c.caCrtPath(), caCrt, 0640); err != nil { //nolint:gosec + return fmt.Errorf("unable to save the client certificate CA to %s: %w", c.caCrtPath(), err) + } + + return nil +} + +// Stop shuts down this authenticator. +func (c *CertAuthn) Stop() error { + // no-op -- our workdir is cleaned up for us automatically + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth_test.go new file mode 100644 index 00000000000..9891c6f2e26 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/auth_test.go @@ -0,0 +1,175 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + "crypto/tls" + "crypto/x509" + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + kcert "k8s.io/client-go/util/cert" + + cp "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +var _ = Describe("Cert Authentication", func() { + var authn *cp.CertAuthn + BeforeEach(func() { + var err error + authn, err = cp.NewCertAuthn() + Expect(err).NotTo(HaveOccurred(), "should be able to create the cert authn") + }) + Context("when starting", func() { + It("should write the verifying CA to the configured directory", func() { + By("setting up a temp dir") + dir, err := os.MkdirTemp("", "envtest_controlplane_*") + Expect(err).NotTo(HaveOccurred(), "should be able to provision a temp dir") + if dir != "" { + defer os.RemoveAll(dir) + } + + By("configuring to use that dir") + Expect(authn.Configure(dir, process.EmptyArguments())).To(Succeed()) + + By("starting and checking the dir") + Expect(authn.Start()).To(Succeed()) + defer func() { Expect(authn.Stop()).To(Succeed()) }() // not strictly necessary, but future-proof + + _, err = os.Stat(filepath.Join(dir, "client-cert-auth-ca.crt")) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should error out if we haven't been configured yet", func() { + // NB(directxman12): no configure here intentionally + Expect(authn.Start()).NotTo(Succeed()) + }) + }) + Context("when configuring", func() { + It("should have set up the API server to use the written file for client cert auth", func() { + args := process.EmptyArguments() + Expect(authn.Configure("/tmp/____doesnotexist", args)).To(Succeed()) + Expect(args.Get("client-ca-file").Get(nil)).To(ConsistOf("/tmp/____doesnotexist/client-cert-auth-ca.crt")) + }) + }) + + Describe("creating users", func() { + user := cp.User{Name: "someuser", Groups: []string{"group1", "group2"}} + + Context("before starting", func() { + It("should yield a REST config that contains certs valid for the to-be-written CA", func() { + cfg, err := authn.AddUser(user, &rest.Config{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + Expect(cfg.CertData).NotTo(BeEmpty()) + Expect(cfg.KeyData).NotTo(BeEmpty()) + + // double-check the cert (assume the key is fine if it's present + // and the cert is also present, cause it's more annoying to verify + // and we have separate tinyca & integration tests. + By("parsing the config's cert & key data") + certs, err := tls.X509KeyPair(cfg.CertData, cfg.KeyData) + Expect(err).NotTo(HaveOccurred(), "config cert/key data should be valid key pair") + cert, err := x509.ParseCertificate(certs.Certificate[0]) // re-parse cause .Leaf isn't saved + Expect(err).NotTo(HaveOccurred()) + + By("starting and loading the CA cert") + dir, err := os.MkdirTemp("", "envtest_controlplane_*") + Expect(err).NotTo(HaveOccurred(), "should be able to provision a temp dir") + if dir != "" { + defer os.RemoveAll(dir) + } + Expect(authn.Configure(dir, process.EmptyArguments())).To(Succeed()) + Expect(authn.Start()).To(Succeed()) + caCerts, err := kcert.CertsFromFile(filepath.Join(dir, "client-cert-auth-ca.crt")) + Expect(err).NotTo(HaveOccurred(), "should be able to read the CA cert file))))") + Expect(cert.CheckSignatureFrom(caCerts[0])).To(Succeed(), "the config's cert should be signed by the written CA") + }) + + It("should copy the configuration from the base CA without modifying it", func() { + By("creating a user and checking the output config") + base := &rest.Config{Burst: 30} + cfg, err := authn.AddUser(user, base) + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + Expect(cfg.Burst).To(Equal(30)) + + By("mutating the base and verifying the cfg doesn't change") + base.Burst = 8675 + Expect(cfg.Burst).To(Equal(30)) + }) + }) + + Context("after starting", func() { + var dir string + BeforeEach(func() { + By("setting up a temp dir & starting with it") + var err error + dir, err = os.MkdirTemp("", "envtest_controlplane_*") + Expect(err).NotTo(HaveOccurred(), "should be able to provision a temp dir") + Expect(authn.Configure(dir, process.EmptyArguments())).To(Succeed()) + Expect(authn.Start()).To(Succeed()) + }) + AfterEach(func() { + if dir != "" { + defer os.RemoveAll(dir) + } + }) + + It("should yield a REST config that contains certs valid for the written CA", func() { + cfg, err := authn.AddUser(user, &rest.Config{}) + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + Expect(cfg.CertData).NotTo(BeEmpty()) + Expect(cfg.KeyData).NotTo(BeEmpty()) + + // double-check the cert (assume the key is fine if it's present + // and the cert is also present, cause it's more annoying to verify + // and we have separate tinyca & integration tests. + By("parsing the config's cert & key data") + certs, err := tls.X509KeyPair(cfg.CertData, cfg.KeyData) + Expect(err).NotTo(HaveOccurred(), "config cert/key data should be valid key pair") + cert, err := x509.ParseCertificate(certs.Certificate[0]) // re-parse cause .Leaf isn't saved + Expect(err).NotTo(HaveOccurred()) + + By("loading the CA cert") + caCerts, err := kcert.CertsFromFile(filepath.Join(dir, "client-cert-auth-ca.crt")) + Expect(err).NotTo(HaveOccurred(), "should be able to read the CA cert file))))") + Expect(cert.CheckSignatureFrom(caCerts[0])).To(Succeed(), "the config's cert should be signed by the written CA") + }) + + It("should copy the configuration from the base CA without modifying it", func() { + By("creating a user and checking the output config") + base := &rest.Config{Burst: 30} + cfg, err := authn.AddUser(user, base) + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + Expect(cfg.Burst).To(Equal(30)) + + By("mutating the base and verifying the cfg doesn't change") + base.Burst = 8675 + Expect(cfg.Burst).To(Equal(30)) + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/controlplane_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/controlplane_suite_test.go new file mode 100644 index 00000000000..9ac69047f03 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/controlplane_suite_test.go @@ -0,0 +1,30 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestIntegration(t *testing.T) { + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "Control Plane Standup Unit Tests") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd.go new file mode 100644 index 00000000000..c30d2132952 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd.go @@ -0,0 +1,202 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane + +import ( + "io" + "net" + "net/url" + "strconv" + "time" + + "sigs.k8s.io/controller-runtime/pkg/internal/testing/addr" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +// Etcd knows how to run an etcd server. +type Etcd struct { + // URL is the address the Etcd should listen on for client connections. + // + // If this is not specified, we default to a random free port on localhost. + URL *url.URL + + // Path is the path to the etcd binary. + // + // If this is left as the empty string, we will attempt to locate a binary, + // by checking for the TEST_ASSET_ETCD environment variable, and the default + // test assets directory. See the "Binaries" section above (in doc.go) for + // details. + Path string + + // Args is a list of arguments which will passed to the Etcd binary. Before + // they are passed on, the`y will be evaluated as go-template strings. This + // means you can use fields which are defined and exported on this Etcd + // struct (e.g. "--data-dir={{ .Dir }}"). + // Those templates will be evaluated after the defaulting of the Etcd's + // fields has already happened and just before the binary actually gets + // started. Thus you have access to calculated fields like `URL` and others. + // + // If not specified, the minimal set of arguments to run the Etcd will be + // used. + // + // They will be loaded into the same argument set as Configure. Each flag + // will be Append-ed to the configured arguments just before launch. + // + // Deprecated: use Configure instead. + Args []string + + // DataDir is a path to a directory in which etcd can store its state. + // + // If left unspecified, then the Start() method will create a fresh temporary + // directory, and the Stop() method will clean it up. + DataDir string + + // StartTimeout, StopTimeout specify the time the Etcd is allowed to + // take when starting and stopping before an error is emitted. + // + // If not specified, these default to 20 seconds. + StartTimeout time.Duration + StopTimeout time.Duration + + // Out, Err specify where Etcd should write its StdOut, StdErr to. + // + // If not specified, the output will be discarded. + Out io.Writer + Err io.Writer + + // processState contains the actual details about this running process + processState *process.State + + // args contains the structured arguments to use for running etcd. + // Lazily initialized by .Configure(), Defaulted eventually with .defaultArgs() + args *process.Arguments + + // listenPeerURL is the address the Etcd should listen on for peer connections. + // It's automatically generated and a random port is picked during execution. + listenPeerURL *url.URL +} + +// Start starts the etcd, waits for it to come up, and returns an error, if one +// occurred. +func (e *Etcd) Start() error { + if err := e.setProcessState(); err != nil { + return err + } + return e.processState.Start(e.Out, e.Err) +} + +func (e *Etcd) setProcessState() error { + e.processState = &process.State{ + Dir: e.DataDir, + Path: e.Path, + StartTimeout: e.StartTimeout, + StopTimeout: e.StopTimeout, + } + + // unconditionally re-set this so we can successfully restart + // TODO(directxman12): we supported this in the past, but do we actually + // want to support re-using an API server object to restart? The loss + // of provisioned users is surprising to say the least. + if err := e.processState.Init("etcd"); err != nil { + return err + } + + // Set the listen url. + if e.URL == nil { + port, host, err := addr.Suggest("") + if err != nil { + return err + } + e.URL = &url.URL{ + Scheme: "http", + Host: net.JoinHostPort(host, strconv.Itoa(port)), + } + } + + // Set the listen peer URL. + { + port, host, err := addr.Suggest("") + if err != nil { + return err + } + e.listenPeerURL = &url.URL{ + Scheme: "http", + Host: net.JoinHostPort(host, strconv.Itoa(port)), + } + } + + // can use /health as of etcd 3.3.0 + e.processState.HealthCheck.URL = *e.URL + e.processState.HealthCheck.Path = "/health" + + e.DataDir = e.processState.Dir + e.Path = e.processState.Path + e.StartTimeout = e.processState.StartTimeout + e.StopTimeout = e.processState.StopTimeout + + var err error + e.processState.Args, e.Args, err = process.TemplateAndArguments(e.Args, e.Configure(), process.TemplateDefaults{ //nolint:staticcheck + Data: e, + Defaults: e.defaultArgs(), + }) + return err +} + +// Stop stops this process gracefully, waits for its termination, and cleans up +// the DataDir if necessary. +func (e *Etcd) Stop() error { + if e.processState.DirNeedsCleaning { + e.DataDir = "" // reset the directory if it was randomly allocated, so that we can safely restart + } + return e.processState.Stop() +} + +func (e *Etcd) defaultArgs() map[string][]string { + args := map[string][]string{ + "listen-peer-urls": {e.listenPeerURL.String()}, + "data-dir": {e.DataDir}, + } + if e.URL != nil { + args["advertise-client-urls"] = []string{e.URL.String()} + args["listen-client-urls"] = []string{e.URL.String()} + } + + // Add unsafe no fsync, available from etcd 3.5 + if ok, _ := e.processState.CheckFlag("unsafe-no-fsync"); ok { + args["unsafe-no-fsync"] = []string{"true"} + } + return args +} + +// Configure returns Arguments that may be used to customize the +// flags used to launch etcd. A set of defaults will +// be applied underneath. +func (e *Etcd) Configure() *process.Arguments { + if e.args == nil { + e.args = process.EmptyArguments() + } + return e.args +} + +// EtcdDefaultArgs exposes the default args for Etcd so that you +// can use those to append your own additional arguments. +var EtcdDefaultArgs = []string{ + "--listen-peer-urls=http://localhost:0", + "--advertise-client-urls={{ if .URL }}{{ .URL.String }}{{ end }}", + "--listen-client-urls={{ if .URL }}{{ .URL.String }}{{ end }}", + "--data-dir={{ .DataDir }}", +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd_test.go new file mode 100644 index 00000000000..7c7c7561ffd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/etcd_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" +) + +var _ = Describe("etcd", func() { + // basic coherence test + It("should start and stop successfully", func() { + etcd := &Etcd{} + Expect(etcd.Start()).To(Succeed()) + defer func() { + Expect(etcd.Stop()).To(Succeed()) + }() + Expect(etcd.URL).NotTo(BeNil()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go new file mode 100644 index 00000000000..a27b7a0ff88 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl.go @@ -0,0 +1,119 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane + +import ( + "bytes" + "fmt" + "io" + "net/url" + "os/exec" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + kcapi "k8s.io/client-go/tools/clientcmd/api" + + "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +const ( + envtestName = "envtest" +) + +// KubeConfigFromREST reverse-engineers a kubeconfig file from a rest.Config. +// The options are tailored towards the rest.Configs we generate, so they're +// not broadly applicable. +// +// This is not intended to be exposed beyond internal for the above reasons. +func KubeConfigFromREST(cfg *rest.Config) ([]byte, error) { + kubeConfig := kcapi.NewConfig() + protocol := "https" + if !rest.IsConfigTransportTLS(*cfg) { + protocol = "http" + } + + // cfg.Host is a URL, so we need to parse it so we can properly append the API path + baseURL, err := url.Parse(cfg.Host) + if err != nil { + return nil, fmt.Errorf("unable to interpret config's host value as a URL: %w", err) + } + + kubeConfig.Clusters[envtestName] = &kcapi.Cluster{ + // TODO(directxman12): if client-go ever decides to expose defaultServerUrlFor(config), + // we can just use that. Note that this is not the same as the public DefaultServerURL, + // which requires us to pass a bunch of stuff in manually. + Server: (&url.URL{Scheme: protocol, Host: baseURL.Host, Path: cfg.APIPath}).String(), + CertificateAuthorityData: cfg.CAData, + } + kubeConfig.AuthInfos[envtestName] = &kcapi.AuthInfo{ + // try to cover all auth strategies that aren't plugins + ClientCertificateData: cfg.CertData, + ClientKeyData: cfg.KeyData, + Token: cfg.BearerToken, + Username: cfg.Username, + Password: cfg.Password, + } + kcCtx := kcapi.NewContext() + kcCtx.Cluster = envtestName + kcCtx.AuthInfo = envtestName + kubeConfig.Contexts[envtestName] = kcCtx + kubeConfig.CurrentContext = envtestName + + contents, err := clientcmd.Write(*kubeConfig) + if err != nil { + return nil, fmt.Errorf("unable to serialize kubeconfig file: %w", err) + } + return contents, nil +} + +// KubeCtl is a wrapper around the kubectl binary. +type KubeCtl struct { + // Path where the kubectl binary can be found. + // + // If this is left empty, we will attempt to locate a binary, by checking for + // the TEST_ASSET_KUBECTL environment variable, and the default test assets + // directory. See the "Binaries" section above (in doc.go) for details. + Path string + + // Opts can be used to configure additional flags which will be used each + // time the wrapped binary is called. + // + // For example, you might want to use this to set the URL of the APIServer to + // connect to. + Opts []string +} + +// Run executes the wrapped binary with some preconfigured options and the +// arguments given to this method. It returns Readers for the stdout and +// stderr. +func (k *KubeCtl) Run(args ...string) (stdout, stderr io.Reader, err error) { + if k.Path == "" { + k.Path = process.BinPathFinder("kubectl", "") + } + + stdoutBuffer := &bytes.Buffer{} + stderrBuffer := &bytes.Buffer{} + allArgs := append(k.Opts, args...) + + cmd := exec.Command(k.Path, allArgs...) + cmd.Stdout = stdoutBuffer + cmd.Stderr = stderrBuffer + + err = cmd.Run() + + return stdoutBuffer, stderrBuffer, err +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl_test.go new file mode 100644 index 00000000000..5484bc31a1a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/kubectl_test.go @@ -0,0 +1,138 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + "io" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ccapi "k8s.io/client-go/tools/clientcmd/api" + + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" +) + +var _ = Describe("Kubectl", func() { + It("runs kubectl", func() { + k := &KubeCtl{Path: "bash"} + args := []string{"-c", "echo 'something'"} + stdout, stderr, err := k.Run(args...) + Expect(err).NotTo(HaveOccurred()) + Expect(stdout).To(ContainSubstring("something")) + bytes, err := io.ReadAll(stderr) + Expect(err).NotTo(HaveOccurred()) + Expect(bytes).To(BeEmpty()) + }) + + Context("when the command returns a non-zero exit code", func() { + It("returns an error", func() { + k := &KubeCtl{Path: "bash"} + args := []string{ + "-c", "echo 'this is StdErr' >&2; echo 'but this is StdOut' >&1; exit 66", + } + + stdout, stderr, err := k.Run(args...) + + Expect(err).To(MatchError(ContainSubstring("exit status 66"))) + + Expect(stdout).To(ContainSubstring("but this is StdOut")) + Expect(stderr).To(ContainSubstring("this is StdErr")) + }) + }) +}) + +var _ = Describe("KubeConfigFromREST", func() { + var ( + restCfg *rest.Config + rawCfg []byte + cfg *ccapi.Config + ) + + BeforeEach(func() { + restCfg = &rest.Config{ + Host: "https://some-host:8675", + APIPath: "/some-prefix", + TLSClientConfig: rest.TLSClientConfig{ + CertData: []byte("cert"), + KeyData: []byte("key"), + CAData: []byte("ca-cert"), + }, + BearerToken: "some-tok", + Username: "some-user", + Password: "some-password", + } + }) + + JustBeforeEach(func() { + var err error + rawCfg, err = KubeConfigFromREST(restCfg) + Expect(err).NotTo(HaveOccurred(), "should be able to convert & serialize the kubeconfig") + + cfg, err = clientcmd.Load(rawCfg) + Expect(err).NotTo(HaveOccurred(), "should be able to deserialize the generated kubeconfig") + }) + + It("should set up a context, and set it as the current one", func() { + By("checking that the current context exists") + Expect(cfg.CurrentContext).NotTo(BeEmpty(), "should have a current context") + Expect(cfg.Contexts).To(HaveKeyWithValue(cfg.CurrentContext, Not(BeNil())), "the current context should exist as a context") + + By("checking that it points to valid info") + currCtx := cfg.Contexts[cfg.CurrentContext] + Expect(currCtx).To(PointTo(MatchFields(IgnoreExtras, Fields{ + "Cluster": Not(BeEmpty()), + "AuthInfo": Not(BeEmpty()), + }))) + + Expect(cfg.Clusters).To(HaveKeyWithValue(currCtx.Cluster, Not(BeNil())), "should point to a cluster") + Expect(cfg.AuthInfos).To(HaveKeyWithValue(currCtx.AuthInfo, Not(BeNil())), "should point to a user") + }) + + Context("when no TLS is enabled", func() { + BeforeEach(func() { + restCfg.Host = "http://some-host:8675" + restCfg.TLSClientConfig = rest.TLSClientConfig{} + }) + + It("should use http in the server url", func() { + cluster := cfg.Clusters[cfg.Contexts[cfg.CurrentContext].Cluster] + Expect(cluster.Server).To(HavePrefix("http://")) + }) + }) + + It("configure the current context to point to the given REST config's server, with CA data", func() { + cluster := cfg.Clusters[cfg.Contexts[cfg.CurrentContext].Cluster] + Expect(cluster).To(PointTo(MatchFields(IgnoreExtras, Fields{ + "Server": Equal("https://some-host:8675/some-prefix"), + "CertificateAuthorityData": Equal([]byte("ca-cert")), + }))) + }) + + It("should copy all non-plugin auth info over", func() { + user := cfg.AuthInfos[cfg.Contexts[cfg.CurrentContext].AuthInfo] + Expect(user).To(PointTo(MatchFields(IgnoreExtras, Fields{ + "ClientCertificateData": Equal([]byte("cert")), + "ClientKeyData": Equal([]byte("key")), + "Token": Equal("some-tok"), + "Username": Equal("some-user"), + "Password": Equal("some-password"), + }))) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane.go new file mode 100644 index 00000000000..456183a7a32 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane.go @@ -0,0 +1,259 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane + +import ( + "fmt" + "net/url" + "os" + + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/certs" +) + +// NewTinyCA creates a new a tiny CA utility for provisioning serving certs and client certs FOR TESTING ONLY. +// Don't use this for anything else! +var NewTinyCA = certs.NewTinyCA + +// ControlPlane is a struct that knows how to start your test control plane. +// +// Right now, that means Etcd and your APIServer. This is likely to increase in +// future. +type ControlPlane struct { + APIServer *APIServer + Etcd *Etcd + + // Kubectl will override the default asset search path for kubectl + KubectlPath string + + // for the deprecated methods (Kubectl, etc) + defaultUserCfg *rest.Config + defaultUserKubectl *KubeCtl +} + +// Start will start your control plane processes. To stop them, call Stop(). +func (f *ControlPlane) Start() (retErr error) { + if f.Etcd == nil { + f.Etcd = &Etcd{} + } + if err := f.Etcd.Start(); err != nil { + return err + } + defer func() { + if retErr != nil { + _ = f.Etcd.Stop() + } + }() + + if f.APIServer == nil { + f.APIServer = &APIServer{} + } + f.APIServer.EtcdURL = f.Etcd.URL + if err := f.APIServer.Start(); err != nil { + return err + } + defer func() { + if retErr != nil { + _ = f.APIServer.Stop() + } + }() + + // provision the default user -- can be removed when the related + // methods are removed. The default user has admin permissions to + // mimic legacy no-authz setups. + user, err := f.AddUser(User{Name: "default", Groups: []string{"system:masters"}}, &rest.Config{}) + if err != nil { + return fmt.Errorf("unable to provision the default (legacy) user: %w", err) + } + kubectl, err := user.Kubectl() + if err != nil { + return fmt.Errorf("unable to provision the default (legacy) kubeconfig: %w", err) + } + f.defaultUserCfg = user.Config() + f.defaultUserKubectl = kubectl + return nil +} + +// Stop will stop your control plane processes, and clean up their data. +func (f *ControlPlane) Stop() error { + var errList []error + + if f.APIServer != nil { + if err := f.APIServer.Stop(); err != nil { + errList = append(errList, err) + } + } + + if f.Etcd != nil { + if err := f.Etcd.Stop(); err != nil { + errList = append(errList, err) + } + } + + return kerrors.NewAggregate(errList) +} + +// APIURL returns the URL you should connect to to talk to your API server. +// +// If insecure serving is configured, this will contain the insecure port. +// Otherwise, it will contain the secure port. +// +// Deprecated: use AddUser instead, or APIServer.{Ins|S}ecureServing.URL if +// you really want just the URL. +func (f *ControlPlane) APIURL() *url.URL { + return f.APIServer.URL +} + +// KubeCtl returns a pre-configured KubeCtl, ready to connect to this +// ControlPlane. +// +// Deprecated: use AddUser & AuthenticatedUser.Kubectl instead. +func (f *ControlPlane) KubeCtl() *KubeCtl { + return f.defaultUserKubectl +} + +// RESTClientConfig returns a pre-configured restconfig, ready to connect to +// this ControlPlane. +// +// Deprecated: use AddUser & AuthenticatedUser.Config instead. +func (f *ControlPlane) RESTClientConfig() (*rest.Config, error) { + return f.defaultUserCfg, nil +} + +// AuthenticatedUser contains access information for an provisioned user, +// including REST config, kubeconfig contents, and access to a KubeCtl instance. +// +// It's not "safe" to use the methods on this till after the API server has been +// started (due to certificate initialization and such). The various methods will +// panic if this is done. +type AuthenticatedUser struct { + // cfg is the rest.Config for connecting to the API server. It's lazily initialized. + cfg *rest.Config + // cfgIsComplete indicates the cfg has had late-initialized fields (e.g. + // API server CA data) initialized. + cfgIsComplete bool + + // apiServer is a handle to the APIServer that's used when finalizing cfg + // and producing the kubectl instance. + plane *ControlPlane + + // kubectl is our existing, provisioned kubectl. We don't provision one + // till someone actually asks for it. + kubectl *KubeCtl +} + +// Config returns the REST config that can be used to connect to the API server +// as this user. +// +// Will panic if used before the API server is started. +func (u *AuthenticatedUser) Config() *rest.Config { + // NB(directxman12): we choose to panic here for ergonomics sake, and because there's + // not really much you can do to "handle" this error. This machinery is intended to be + // used in tests anyway, so panicing is not a particularly big deal. + if u.cfgIsComplete { + return u.cfg + } + if len(u.plane.APIServer.SecureServing.CA) == 0 { + panic("the API server has not yet been started, please do that before accessing connection details") + } + + u.cfg.CAData = u.plane.APIServer.SecureServing.CA + u.cfg.Host = u.plane.APIServer.SecureServing.URL("https", "/").String() + u.cfgIsComplete = true + return u.cfg +} + +// KubeConfig returns a KubeConfig that's roughly equivalent to this user's REST config. +// +// Will panic if used before the API server is started. +func (u AuthenticatedUser) KubeConfig() ([]byte, error) { + // NB(directxman12): we don't return the actual API object to avoid yet another + // piece of kubernetes API in our public API, and also because generally the thing + // you want to do with this is just write it out to a file for external debugging + // purposes, etc. + return KubeConfigFromREST(u.Config()) +} + +// Kubectl returns a KubeCtl instance for talking to the API server as this user. It uses +// a kubeconfig equivalent to that returned by .KubeConfig. +// +// Will panic if used before the API server is started. +func (u *AuthenticatedUser) Kubectl() (*KubeCtl, error) { + if u.kubectl != nil { + return u.kubectl, nil + } + if len(u.plane.APIServer.CertDir) == 0 { + panic("the API server has not yet been started, please do that before accessing connection details") + } + + // cleaning this up is handled when our tmpDir is deleted + out, err := os.CreateTemp(u.plane.APIServer.CertDir, "*.kubecfg") + if err != nil { + return nil, fmt.Errorf("unable to create file for kubeconfig: %w", err) + } + defer out.Close() + contents, err := KubeConfigFromREST(u.Config()) + if err != nil { + return nil, err + } + if _, err := out.Write(contents); err != nil { + return nil, fmt.Errorf("unable to write kubeconfig to disk at %s: %w", out.Name(), err) + } + k := &KubeCtl{ + Path: u.plane.KubectlPath, + } + k.Opts = append(k.Opts, fmt.Sprintf("--kubeconfig=%s", out.Name())) + u.kubectl = k + return k, nil +} + +// AddUser provisions a new user in the cluster. It uses the APIServer's authentication +// strategy -- see APIServer.SecureServing.Authn. +// +// Unlike AddUser, it's safe to pass a nil rest.Config here if you have no +// particular opinions about the config. +// +// The default authentication strategy is not guaranteed to any specific strategy, but it is +// guaranteed to be callable both before and after Start has been called (but, as noted in the +// AuthenticatedUser docs, the given user objects are only valid after Start has been called). +func (f *ControlPlane) AddUser(user User, baseConfig *rest.Config) (*AuthenticatedUser, error) { + if f.GetAPIServer().SecureServing.Authn == nil { + return nil, fmt.Errorf("no API server authentication is configured yet. The API server defaults one when Start is called, did you mean to use that?") + } + + if baseConfig == nil { + baseConfig = &rest.Config{} + } + cfg, err := f.GetAPIServer().SecureServing.AddUser(user, baseConfig) + if err != nil { + return nil, err + } + + return &AuthenticatedUser{ + cfg: cfg, + plane: f, + }, nil +} + +// GetAPIServer returns this ControlPlane's APIServer, initializing it if necessary. +func (f *ControlPlane) GetAPIServer() *APIServer { + if f.APIServer == nil { + f.APIServer = &APIServer{} + } + return f.APIServer +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane_test.go new file mode 100644 index 00000000000..cd0359dbca8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/plane_test.go @@ -0,0 +1,109 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controlplane_test + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + kauthn "k8s.io/api/authorization/v1" + + "sigs.k8s.io/controller-runtime/pkg/client" + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane" +) + +var _ = Describe("Control Plane", func() { + It("should start and stop successfully with a default etcd & apiserver", func() { + plane := &ControlPlane{} + Expect(plane.Start()).To(Succeed()) + Expect(plane.Stop()).To(Succeed()) + }) + It("should use the given etcd & apiserver when starting, if present", func() { + apiServer := &APIServer{} + etcd := &Etcd{} + plane := &ControlPlane{ + APIServer: apiServer, + Etcd: etcd, + } + Expect(plane.Start()).To(Succeed()) + defer func() { Expect(plane.Stop()).To(Succeed()) }() + + Expect(plane.APIServer).To(BeIdenticalTo(apiServer)) + Expect(plane.Etcd).To(BeIdenticalTo(etcd)) + }) + + It("should be able to restart", func() { + // NB(directxman12): currently restarting invalidates all current users + // when using CertAuthn. We need to support restarting as per our previous + // contract, but it's not clear how much else we actually need to handle, or + // whether or not this is a safe operation. + plane := &ControlPlane{} + Expect(plane.Start()).To(Succeed()) + Expect(plane.Stop()).To(Succeed()) + Expect(plane.Start()).To(Succeed()) + Expect(plane.Stop()).To(Succeed()) + }) + + Context("after having started", func() { + var plane *ControlPlane + BeforeEach(func() { + plane = &ControlPlane{} + Expect(plane.Start()).To(Succeed()) + }) + AfterEach(func() { + Expect(plane.Stop()).To(Succeed()) + }) + + It("should provision a working legacy user and legacy kubectl", func() { + By("grabbing the legacy kubectl") + Expect(plane.KubeCtl()).NotTo(BeNil()) + + By("grabbing the legacy REST config and testing it") + cfg, err := plane.RESTClientConfig() + Expect(err).NotTo(HaveOccurred(), "should be able to grab the legacy REST config") + cl, err := client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred(), "should be able to create a client") + + sar := &kauthn.SelfSubjectAccessReview{ + Spec: kauthn.SelfSubjectAccessReviewSpec{ + ResourceAttributes: &kauthn.ResourceAttributes{ + Verb: "*", + Group: "*", + Version: "*", + Resource: "*", + }, + }, + } + Expect(cl.Create(context.Background(), sar)).To(Succeed(), "should be able to make a Self-SAR") + Expect(sar.Status.Allowed).To(BeTrue(), "admin user should be able to do everything") + }) + + // TODO(directxman12): more explicit tests for AddUser -- it's tested indirectly via the + // legacy user flow, but we should be explicit + + Describe("adding users", func() { + PIt("should be able to provision new users that have a corresponding REST config and & kubectl", func() { + + }) + + PIt("should produce a default base REST config if none is given to add", func() { + + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.19-apiserver.sh b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.19-apiserver.sh new file mode 100755 index 00000000000..8b71661185d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.19-apiserver.sh @@ -0,0 +1,312 @@ +#!/usr/bin/env sh + +cat </=true|false for a specific API group and version (e.g. apps/v1=true) + api/all=true|false controls all API versions + api/ga=true|false controls all API versions of the form v[0-9]+ + api/beta=true|false controls all API versions of the form v[0-9]+beta[0-9]+ + api/alpha=true|false controls all API versions of the form v[0-9]+alpha[0-9]+ + api/legacy is deprecated, and will be removed in a future version + +Egress selector flags: + + --egress-selector-config-file string File with apiserver egress selector configuration. + +Admission flags: + + --admission-control strings Admission is divided into two phases. In the first phase, only mutating admission plugins run. In the second phase, only validating admission plugins run. The names in the below list may represent a validating plugin, a mutating plugin, or both. The order of plugins in which they are passed to this flag does not matter. Comma-delimited list of: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. (DEPRECATED: Use --enable-admission-plugins or --disable-admission-plugins instead. Will be removed in a future version.) + --admission-control-config-file string File with admission control configuration. + --disable-admission-plugins strings admission plugins that should be disabled although they are in the default enabled plugins list (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter. + --enable-admission-plugins strings admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter. + +Metrics flags: + + --show-hidden-metrics-for-version string The previous version for which you want to show hidden metrics. Only the previous minor version is meaningful, other values will not be allowed. The format is ., e.g.: '1.16'. The purpose of this format is make sure you have the opportunity to notice if the next release hides additional metrics, rather than being surprised when they are permanently removed in the release after that. + +Logs flags: + + --logging-format string Sets the log format. Permitted formats: "json", "text". + Non-default formats don't honor these flags: --add_dir_header, --alsologtostderr, --log_backtrace_at, --log_dir, --log_file, --log_file_max_size, --logtostderr, --skip_headers, --skip_log_headers, --stderrthreshold, --vmodule, --log-flush-frequency. + Non-default choices are currently alpha and subject to change without warning. (default "text") + +Misc flags: + + --allow-privileged If true, allow privileged containers. [default=false] + --apiserver-count int The number of apiservers running in the cluster, must be a positive number. (In use when --endpoint-reconciler-type=master-count is enabled.) (default 1) + --enable-aggregator-routing Turns on aggregator routing requests to endpoints IP rather than cluster IP. + --endpoint-reconciler-type string Use an endpoint reconciler (master-count, lease, none) (default "lease") + --event-ttl duration Amount of time to retain events. (default 1h0m0s) + --kubelet-certificate-authority string Path to a cert file for the certificate authority. + --kubelet-client-certificate string Path to a client cert file for TLS. + --kubelet-client-key string Path to a client key file for TLS. + --kubelet-preferred-address-types strings List of the preferred NodeAddressTypes to use for kubelet connections. (default [Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP]) + --kubelet-timeout duration Timeout for kubelet operations. (default 5s) + --kubernetes-service-node-port int If non-zero, the Kubernetes master service (which apiserver creates/maintains) will be of type NodePort, using this as the value of the port. If zero, the Kubernetes master service will be of type ClusterIP. + --max-connection-bytes-per-sec int If non-zero, throttle each user connection to this number of bytes/sec. Currently only applies to long-running requests. + --proxy-client-cert-file string Client certificate used to prove the identity of the aggregator or kube-apiserver when it must call out during a request. This includes proxying requests to a user api-server and calling out to webhook admission plugins. It is expected that this cert includes a signature from the CA in the --requestheader-client-ca-file flag. That CA is published in the 'extension-apiserver-authentication' configmap in the kube-system namespace. Components receiving calls from kube-aggregator should use that CA to perform their half of the mutual TLS verification. + --proxy-client-key-file string Private key for the client certificate used to prove the identity of the aggregator or kube-apiserver when it must call out during a request. This includes proxying requests to a user api-server and calling out to webhook admission plugins. + --service-account-signing-key-file string Path to the file that contains the current private key of the service account token issuer. The issuer will sign issued ID tokens with this private key. (Requires the 'TokenRequest' feature gate.) + --service-cluster-ip-range string A CIDR notation IP range from which to assign service cluster IPs. This must not overlap with any IP ranges assigned to nodes or pods. + --service-node-port-range portRange A port range to reserve for services with NodePort visibility. Example: '30000-32767'. Inclusive at both ends of the range. (default 30000-32767) + +Global flags: + + --add-dir-header If true, adds the file directory to the header of the log messages + --alsologtostderr log to standard error as well as files + -h, --help help for kube-apiserver + --log-backtrace-at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log-dir string If non-empty, write log files in this directory + --log-file string If non-empty, use this log file + --log-file-max-size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logtostderr log to standard error instead of files (default true) + --skip-headers If true, avoid header prefixes in the log messages + --skip-log-headers If true, avoid headers when opening log files + --stderrthreshold severity logs at or above this threshold go to stderr (default 2) + -v, --v Level number for the log level verbosity + --version version[=true] Print version information and quit + --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + +EOF diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.20-apiserver.sh b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.20-apiserver.sh new file mode 100755 index 00000000000..112346cce6b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane/testdata/fake-1.20-apiserver.sh @@ -0,0 +1,318 @@ +#!/usr/bin/env sh + +cat </=true|false for a specific API group and version (e.g. apps/v1=true) + api/all=true|false controls all API versions + api/ga=true|false controls all API versions of the form v[0-9]+ + api/beta=true|false controls all API versions of the form v[0-9]+beta[0-9]+ + api/alpha=true|false controls all API versions of the form v[0-9]+alpha[0-9]+ + api/legacy is deprecated, and will be removed in a future version + +Egress selector flags: + + --egress-selector-config-file string File with apiserver egress selector configuration. + +Admission flags: + + --admission-control strings Admission is divided into two phases. In the first phase, only mutating admission plugins run. In the second phase, only validating admission plugins run. The names in the below list may represent a validating plugin, a mutating plugin, or both. The order of plugins in which they are passed to this flag does not matter. Comma-delimited list of: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. (DEPRECATED: Use --enable-admission-plugins or --disable-admission-plugins instead. Will be removed in a future version.) + --admission-control-config-file string File with admission control configuration. + --disable-admission-plugins strings admission plugins that should be disabled although they are in the default enabled plugins list (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter. + --enable-admission-plugins strings admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter. + +Metrics flags: + + --show-hidden-metrics-for-version string The previous version for which you want to show hidden metrics. Only the previous minor version is meaningful, other values will not be allowed. The format is ., e.g.: '1.16'. The purpose of this format is make sure you have the opportunity to notice if the next release hides additional metrics, rather than being surprised when they are permanently removed in the release after that. + +Logs flags: + + --experimental-logging-sanitization [Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens). + Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production. + --logging-format string Sets the log format. Permitted formats: "json", "text". + Non-default formats don't honor these flags: --add_dir_header, --alsologtostderr, --log_backtrace_at, --log_dir, --log_file, --log_file_max_size, --logtostderr, --one_output, --skip_headers, --skip_log_headers, --stderrthreshold, --vmodule, --log-flush-frequency. + Non-default choices are currently alpha and subject to change without warning. (default "text") + +Misc flags: + + --allow-privileged If true, allow privileged containers. [default=false] + --apiserver-count int The number of apiservers running in the cluster, must be a positive number. (In use when --endpoint-reconciler-type=master-count is enabled.) (default 1) + --enable-aggregator-routing Turns on aggregator routing requests to endpoints IP rather than cluster IP. + --endpoint-reconciler-type string Use an endpoint reconciler (master-count, lease, none) (default "lease") + --event-ttl duration Amount of time to retain events. (default 1h0m0s) + --identity-lease-duration-seconds int The duration of kube-apiserver lease in seconds, must be a positive number. (In use when the APIServerIdentity feature gate is enabled.) (default 3600) + --identity-lease-renew-interval-seconds int The interval of kube-apiserver renewing its lease in seconds, must be a positive number. (In use when the APIServerIdentity feature gate is enabled.) (default 10) + --kubelet-certificate-authority string Path to a cert file for the certificate authority. + --kubelet-client-certificate string Path to a client cert file for TLS. + --kubelet-client-key string Path to a client key file for TLS. + --kubelet-preferred-address-types strings List of the preferred NodeAddressTypes to use for kubelet connections. (default [Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP]) + --kubelet-timeout duration Timeout for kubelet operations. (default 5s) + --kubernetes-service-node-port int If non-zero, the Kubernetes master service (which apiserver creates/maintains) will be of type NodePort, using this as the value of the port. If zero, the Kubernetes master service will be of type ClusterIP. + --max-connection-bytes-per-sec int If non-zero, throttle each user connection to this number of bytes/sec. Currently only applies to long-running requests. + --proxy-client-cert-file string Client certificate used to prove the identity of the aggregator or kube-apiserver when it must call out during a request. This includes proxying requests to a user api-server and calling out to webhook admission plugins. It is expected that this cert includes a signature from the CA in the --requestheader-client-ca-file flag. That CA is published in the 'extension-apiserver-authentication' configmap in the kube-system namespace. Components receiving calls from kube-aggregator should use that CA to perform their half of the mutual TLS verification. + --proxy-client-key-file string Private key for the client certificate used to prove the identity of the aggregator or kube-apiserver when it must call out during a request. This includes proxying requests to a user api-server and calling out to webhook admission plugins. + --service-account-signing-key-file string Path to the file that contains the current private key of the service account token issuer. The issuer will sign issued ID tokens with this private key. + --service-cluster-ip-range string A CIDR notation IP range from which to assign service cluster IPs. This must not overlap with any IP ranges assigned to nodes or pods. + --service-node-port-range portRange A port range to reserve for services with NodePort visibility. Example: '30000-32767'. Inclusive at both ends of the range. (default 30000-32767) + +Global flags: + + --add-dir-header If true, adds the file directory to the header of the log messages + --alsologtostderr log to standard error as well as files + -h, --help help for kube-apiserver + --log-backtrace-at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log-dir string If non-empty, write log files in this directory + --log-file string If non-empty, use this log file + --log-file-max-size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logtostderr log to standard error instead of files (default true) + --one-output If true, only write logs to their native severity level (vs also writing to each lower severity level + --skip-headers If true, avoid header prefixes in the log messages + --skip-log-headers If true, avoid headers when opening log files + --stderrthreshold severity logs at or above this threshold go to stderr (default 2) + -v, --v Level number for the log level verbosity + --version version[=true] Print version information and quit + --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging +EOF diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go new file mode 100644 index 00000000000..391eec1facf --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go @@ -0,0 +1,340 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import ( + "bytes" + "html/template" + "sort" + "strings" +) + +// RenderTemplates returns an []string to render the templates +// +// Deprecated: will be removed in favor of Arguments. +func RenderTemplates(argTemplates []string, data interface{}) (args []string, err error) { + var t *template.Template + + for _, arg := range argTemplates { + t, err = template.New(arg).Parse(arg) + if err != nil { + args = nil + return + } + + buf := &bytes.Buffer{} + err = t.Execute(buf, data) + if err != nil { + args = nil + return + } + args = append(args, buf.String()) + } + + return +} + +// SliceToArguments converts a slice of arguments to structured arguments, +// appending each argument that starts with `--` and contains an `=` to the +// argument set (ignoring defaults), returning the rest. +// +// Deprecated: will be removed when RenderTemplates is removed. +func SliceToArguments(sliceArgs []string, args *Arguments) []string { + var rest []string + for i, arg := range sliceArgs { + if arg == "--" { + rest = append(rest, sliceArgs[i:]...) + return rest + } + // skip non-flag arguments, skip arguments w/o equals because we + // can't tell if the next argument should take a value + if !strings.HasPrefix(arg, "--") || !strings.Contains(arg, "=") { + rest = append(rest, arg) + continue + } + + parts := strings.SplitN(arg[2:], "=", 2) + name := parts[0] + val := parts[1] + + args.AppendNoDefaults(name, val) + } + + return rest +} + +// TemplateDefaults specifies defaults to be used for joining structured arguments with templates. +// +// Deprecated: will be removed when RenderTemplates is removed. +type TemplateDefaults struct { + // Data will be used to render the template. + Data interface{} + // Defaults will be used to default structured arguments if no template is passed. + Defaults map[string][]string + // MinimalDefaults will be used to default structured arguments if a template is passed. + // Use this for flags which *must* be present. + MinimalDefaults map[string][]string // for api server service-cluster-ip-range +} + +// TemplateAndArguments joins structured arguments and non-structured arguments, preserving existing +// behavior. Namely: +// +// 1. if templ has len > 0, it will be rendered against data +// 2. the rendered template values that look like `--foo=bar` will be split +// and appended to args, the rest will be kept around +// 3. the given args will be rendered as string form. If a template is given, +// no defaults will be used, otherwise defaults will be used +// 4. a result of [args..., rest...] will be returned +// +// It returns the resulting rendered arguments, plus the arguments that were +// not transferred to `args` during rendering. +// +// Deprecated: will be removed when RenderTemplates is removed. +func TemplateAndArguments(templ []string, args *Arguments, data TemplateDefaults) (allArgs []string, nonFlagishArgs []string, err error) { + if len(templ) == 0 { // 3 & 4 (no template case) + return args.AsStrings(data.Defaults), nil, nil + } + + // 1: render the template + rendered, err := RenderTemplates(templ, data.Data) + if err != nil { + return nil, nil, err + } + + // 2: filter out structured args and add them to args + rest := SliceToArguments(rendered, args) + + // 3 (template case): render structured args, no defaults (matching the + // legacy case where if Args was specified, no defaults were used) + res := args.AsStrings(data.MinimalDefaults) + + // 4: return the rendered structured args + all non-structured args + return append(res, rest...), rest, nil +} + +// EmptyArguments constructs an empty set of flags with no defaults. +func EmptyArguments() *Arguments { + return &Arguments{ + values: make(map[string]Arg), + } +} + +// Arguments are structured, overridable arguments. +// Each Arguments object contains some set of default arguments, which may +// be appended to, or overridden. +// +// When ready, you can serialize them to pass to exec.Command and friends using +// AsStrings. +// +// All flag-setting methods return the *same* instance of Arguments so that you +// can chain calls. +type Arguments struct { + // values contains the user-set values for the arguments. + // `values[key] = dontPass` means "don't pass this flag" + // `values[key] = passAsName` means "pass this flag without args like --key` + // `values[key] = []string{a, b, c}` means "--key=a --key=b --key=c` + // any values not explicitly set here will be copied from defaults on final rendering. + values map[string]Arg +} + +// Arg is an argument that has one or more values, +// and optionally falls back to default values. +type Arg interface { + // Append adds new values to this argument, returning + // a new instance contain the new value. The intermediate + // argument should generally be assumed to be consumed. + Append(vals ...string) Arg + // Get returns the full set of values, optionally including + // the passed in defaults. If it returns nil, this will be + // skipped. If it returns a non-nil empty slice, it'll be + // assumed that the argument should be passed as name-only. + Get(defaults []string) []string +} + +type userArg []string + +func (a userArg) Append(vals ...string) Arg { + return userArg(append(a, vals...)) //nolint:unconvert +} +func (a userArg) Get(_ []string) []string { + return []string(a) +} + +type defaultedArg []string + +func (a defaultedArg) Append(vals ...string) Arg { + return defaultedArg(append(a, vals...)) //nolint:unconvert +} +func (a defaultedArg) Get(defaults []string) []string { + res := append([]string(nil), defaults...) + return append(res, a...) +} + +type dontPassArg struct{} + +func (a dontPassArg) Append(vals ...string) Arg { + return userArg(vals) +} +func (dontPassArg) Get(_ []string) []string { + return nil +} + +type passAsNameArg struct{} + +func (a passAsNameArg) Append(_ ...string) Arg { + return passAsNameArg{} +} +func (passAsNameArg) Get(_ []string) []string { + return []string{} +} + +var ( + // DontPass indicates that the given argument will not actually be + // rendered. + DontPass Arg = dontPassArg{} + // PassAsName indicates that the given flag will be passed as `--key` + // without any value. + PassAsName Arg = passAsNameArg{} +) + +// AsStrings serializes this set of arguments to a slice of strings appropriate +// for passing to exec.Command and friends, making use of the given defaults +// as indicated for each particular argument. +// +// - Any flag in defaults that's not in Arguments will be present in the output +// - Any flag that's present in Arguments will be passed the corresponding +// defaults to do with as it will (ignore, append-to, suppress, etc). +func (a *Arguments) AsStrings(defaults map[string][]string) []string { + // sort for deterministic ordering + keysInOrder := make([]string, 0, len(defaults)+len(a.values)) + for key := range defaults { + if _, userSet := a.values[key]; userSet { + continue + } + keysInOrder = append(keysInOrder, key) + } + for key := range a.values { + keysInOrder = append(keysInOrder, key) + } + sort.Strings(keysInOrder) + + var res []string + for _, key := range keysInOrder { + vals := a.Get(key).Get(defaults[key]) + switch { + case vals == nil: // don't pass + continue + case len(vals) == 0: // pass as name + res = append(res, "--"+key) + default: + for _, val := range vals { + res = append(res, "--"+key+"="+val) + } + } + } + + return res +} + +// Get returns the value of the given flag. If nil, +// it will not be passed in AsString, otherwise: +// +// len == 0 --> `--key`, len > 0 --> `--key=val1 --key=val2 ...`. +func (a *Arguments) Get(key string) Arg { + if vals, ok := a.values[key]; ok { + return vals + } + return defaultedArg(nil) +} + +// Enable configures the given key to be passed as a "name-only" flag, +// like, `--key`. +func (a *Arguments) Enable(key string) *Arguments { + a.values[key] = PassAsName + return a +} + +// Disable prevents this flag from be passed. +func (a *Arguments) Disable(key string) *Arguments { + a.values[key] = DontPass + return a +} + +// Append adds additional values to this flag. If this flag has +// yet to be set, initial values will include defaults. If you want +// to intentionally ignore defaults/start from scratch, call AppendNoDefaults. +// +// Multiple values will look like `--key=value1 --key=value2 ...`. +func (a *Arguments) Append(key string, values ...string) *Arguments { + vals, present := a.values[key] + if !present { + vals = defaultedArg{} + } + a.values[key] = vals.Append(values...) + return a +} + +// AppendNoDefaults adds additional values to this flag. However, +// unlike Append, it will *not* copy values from defaults. +func (a *Arguments) AppendNoDefaults(key string, values ...string) *Arguments { + vals, present := a.values[key] + if !present { + vals = userArg{} + } + a.values[key] = vals.Append(values...) + return a +} + +// Set resets the given flag to the specified values, ignoring any existing +// values or defaults. +func (a *Arguments) Set(key string, values ...string) *Arguments { + a.values[key] = userArg(values) + return a +} + +// SetRaw sets the given flag to the given Arg value directly. Use this if +// you need to do some complicated deferred logic or something. +// +// Otherwise behaves like Set. +func (a *Arguments) SetRaw(key string, val Arg) *Arguments { + a.values[key] = val + return a +} + +// FuncArg is a basic implementation of Arg that can be used for custom argument logic, +// like pulling values out of APIServer, or dynamically calculating values just before +// launch. +// +// The given function will be mapped directly to Arg#Get, and will generally be +// used in conjunction with SetRaw. For example, to set `--some-flag` to the +// API server's CertDir, you could do: +// +// server.Configure().SetRaw("--some-flag", FuncArg(func(defaults []string) []string { +// return []string{server.CertDir} +// })) +// +// FuncArg ignores Appends; if you need to support appending values too, consider implementing +// Arg directly. +type FuncArg func([]string) []string + +// Append is a no-op for FuncArg, and just returns itself. +func (a FuncArg) Append(vals ...string) Arg { return a } + +// Get delegates functionality to the FuncArg function itself. +func (a FuncArg) Get(defaults []string) []string { + return a(defaults) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments_test.go new file mode 100644 index 00000000000..b513cbdf86a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments_test.go @@ -0,0 +1,346 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process_test + +import ( + "net/url" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +var _ = Describe("Arguments Templates", func() { + It("templates URLs", func() { + templates := []string{ + "plain URL: {{ .SomeURL }}", + "method on URL: {{ .SomeURL.Hostname }}", + "empty URL: {{ .EmptyURL }}", + "handled empty URL: {{- if .EmptyURL }}{{ .EmptyURL }}{{ end }}", + } + data := struct { + SomeURL *url.URL + EmptyURL *url.URL + }{ + &url.URL{Scheme: "https", Host: "the.host.name:3456"}, + nil, + } + + out, err := RenderTemplates(templates, data) + Expect(err).NotTo(HaveOccurred()) + Expect(out).To(BeEquivalentTo([]string{ + "plain URL: https://the.host.name:3456", + "method on URL: the.host.name", + "empty URL: <nil>", + "handled empty URL:", + })) + }) + + It("templates strings", func() { + templates := []string{ + "a string: {{ .SomeString }}", + "empty string: {{- .EmptyString }}", + } + data := struct { + SomeString string + EmptyString string + }{ + "this is some random string", + "", + } + + out, err := RenderTemplates(templates, data) + Expect(err).NotTo(HaveOccurred()) + Expect(out).To(BeEquivalentTo([]string{ + "a string: this is some random string", + "empty string:", + })) + }) + + It("has no access to unexported fields", func() { + templates := []string{ + "this is just a string", + "this blows up {{ .test }}", + } + data := struct{ test string }{"ooops private"} + + out, err := RenderTemplates(templates, data) + Expect(out).To(BeEmpty()) + Expect(err).To(MatchError( + ContainSubstring("is an unexported field of struct"), + )) + }) + + It("errors when field cannot be found", func() { + templates := []string{"this does {{ .NotExist }}"} + data := struct{ Unused string }{"unused"} + + out, err := RenderTemplates(templates, data) + Expect(out).To(BeEmpty()) + Expect(err).To(MatchError( + ContainSubstring("can't evaluate field"), + )) + }) + + Context("when joining with structured Arguments", func() { + var ( + args *Arguments + templ = []string{ + "--cheese=parmesean", + "-om", + "nom nom nom", + "--sharpness={{ .sharpness }}", + } + data = TemplateDefaults{ + Data: map[string]string{"sharpness": "extra"}, + Defaults: map[string][]string{ + "cracker": {"ritz"}, + "pickle": {"kosher-dill"}, + }, + MinimalDefaults: map[string][]string{ + "pickle": {"kosher-dill"}, + }, + } + ) + BeforeEach(func() { + args = EmptyArguments() + }) + + Context("when a template is given", func() { + It("should use minimal defaults", func() { + all, _, err := TemplateAndArguments(templ, args, data) + Expect(err).NotTo(HaveOccurred()) + Expect(all).To(SatisfyAll( + Not(ContainElement("--cracker=ritz")), + ContainElement("--pickle=kosher-dill"), + )) + }) + + It("should render the template against the data", func() { + all, _, err := TemplateAndArguments(templ, args, data) + Expect(err).NotTo(HaveOccurred()) + Expect(all).To(ContainElements( + "--sharpness=extra", + )) + }) + + It("should append the rendered template to structured arguments", func() { + args.Append("cheese", "cheddar") + + all, _, err := TemplateAndArguments(templ, args, data) + Expect(err).NotTo(HaveOccurred()) + Expect(all).To(Equal([]string{ + "--cheese=cheddar", + "--cheese=parmesean", + "--pickle=kosher-dill", + "--sharpness=extra", + "-om", + "nom nom nom", + })) + }) + + It("should indicate which arguments were not able to be converted to structured flags", func() { + _, rest, err := TemplateAndArguments(templ, args, data) + Expect(err).NotTo(HaveOccurred()) + Expect(rest).To(Equal([]string{"-om", "nom nom nom"})) + + }) + }) + + Context("when no template is given", func() { + It("should render the structured arguments with the given defaults", func() { + args. + Append("cheese", "cheddar", "parmesean"). + Append("cracker", "triscuit") + + Expect(TemplateAndArguments(nil, args, data)).To(Equal([]string{ + "--cheese=cheddar", + "--cheese=parmesean", + "--cracker=ritz", + "--cracker=triscuit", + "--pickle=kosher-dill", + })) + }) + }) + }) + + Context("when converting to structured Arguments", func() { + var args *Arguments + BeforeEach(func() { + args = EmptyArguments() + }) + + It("should skip arguments that don't start with `--`", func() { + rest := SliceToArguments([]string{"-first", "second", "--foo=bar"}, args) + Expect(rest).To(Equal([]string{"-first", "second"})) + Expect(args.AsStrings(nil)).To(Equal([]string{"--foo=bar"})) + }) + + It("should skip arguments that don't contain an `=` because they're ambiguous", func() { + rest := SliceToArguments([]string{"--first", "--second", "--foo=bar"}, args) + Expect(rest).To(Equal([]string{"--first", "--second"})) + Expect(args.AsStrings(nil)).To(Equal([]string{"--foo=bar"})) + }) + + It("should stop at the flag terminator (`--`)", func() { + rest := SliceToArguments([]string{"--first", "--second", "--", "--foo=bar"}, args) + Expect(rest).To(Equal([]string{"--first", "--second", "--", "--foo=bar"})) + Expect(args.AsStrings(nil)).To(BeEmpty()) + }) + + It("should split --foo=bar into Append(foo, bar)", func() { + rest := SliceToArguments([]string{"--foo=bar1", "--foo=bar2"}, args) + Expect(rest).To(BeEmpty()) + Expect(args.Get("foo").Get(nil)).To(Equal([]string{"bar1", "bar2"})) + }) + + It("should split --foo=bar=baz into Append(foo, bar=baz)", func() { + rest := SliceToArguments([]string{"--vmodule=file.go=3", "--vmodule=other.go=4"}, args) + Expect(rest).To(BeEmpty()) + Expect(args.Get("vmodule").Get(nil)).To(Equal([]string{"file.go=3", "other.go=4"})) + }) + + It("should append to existing arguments", func() { + args.Append("foo", "barA") + rest := SliceToArguments([]string{"--foo=bar1", "--foo=bar2"}, args) + Expect(rest).To(BeEmpty()) + Expect(args.Get("foo").Get([]string{"barI"})).To(Equal([]string{"barI", "barA", "bar1", "bar2"})) + }) + }) +}) + +var _ = Describe("Arguments", func() { + Context("when appending", func() { + It("should copy from defaults when appending for the first time", func() { + args := EmptyArguments(). + Append("some-key", "val3") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"val1", "val2", "val3"})) + }) + + It("should not copy from defaults if the flag has been disabled previously", func() { + args := EmptyArguments(). + Disable("some-key"). + Append("some-key", "val3") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"val3"})) + }) + + It("should only copy defaults the first time", func() { + args := EmptyArguments(). + Append("some-key", "val3", "val4"). + Append("some-key", "val5") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"val1", "val2", "val3", "val4", "val5"})) + }) + + It("should not copy from defaults if the flag has been previously overridden", func() { + args := EmptyArguments(). + Set("some-key", "vala"). + Append("some-key", "valb", "valc") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"vala", "valb", "valc"})) + }) + + Context("when explicitly overriding defaults", func() { + It("should not copy from defaults, but should append to previous calls", func() { + args := EmptyArguments(). + AppendNoDefaults("some-key", "vala"). + AppendNoDefaults("some-key", "valb", "valc") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"vala", "valb", "valc"})) + }) + + It("should not copy from defaults, but should respect previous appends' copies", func() { + args := EmptyArguments(). + Append("some-key", "vala"). + AppendNoDefaults("some-key", "valb", "valc") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"val1", "val2", "vala", "valb", "valc"})) + }) + + It("should not copy from defaults if the flag has been previously appended to ignoring defaults", func() { + args := EmptyArguments(). + AppendNoDefaults("some-key", "vala"). + Append("some-key", "valb", "valc") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"vala", "valb", "valc"})) + }) + }) + }) + + It("should ignore defaults when overriding", func() { + args := EmptyArguments(). + Set("some-key", "vala") + Expect(args.Get("some-key").Get([]string{"val1", "val2"})).To(Equal([]string{"vala"})) + }) + + It("should allow directly setting the argument value for custom argument types", func() { + args := EmptyArguments(). + SetRaw("custom-key", commaArg{"val3"}). + Append("custom-key", "val4") + Expect(args.Get("custom-key").Get([]string{"val1", "val2"})).To(Equal([]string{"val1,val2,val3,val4"})) + }) + + Context("when rendering flags", func() { + It("should not render defaults for disabled flags", func() { + defs := map[string][]string{ + "some-key": {"val1", "val2"}, + "other-key": {"val"}, + } + args := EmptyArguments(). + Disable("some-key") + Expect(args.AsStrings(defs)).To(ConsistOf("--other-key=val")) + }) + + It("should render name-only flags as --key", func() { + args := EmptyArguments(). + Enable("some-key") + Expect(args.AsStrings(nil)).To(ConsistOf("--some-key")) + }) + + It("should render multiple values as --key=val1, --key=val2", func() { + args := EmptyArguments(). + Append("some-key", "val1", "val2"). + Append("other-key", "vala", "valb") + Expect(args.AsStrings(nil)).To(ConsistOf("--other-key=valb", "--other-key=vala", "--some-key=val1", "--some-key=val2")) + }) + + It("should read from defaults if the user hasn't set a value for a flag", func() { + defs := map[string][]string{ + "some-key": {"val1", "val2"}, + } + args := EmptyArguments(). + Append("other-key", "vala", "valb") + Expect(args.AsStrings(defs)).To(ConsistOf("--other-key=valb", "--other-key=vala", "--some-key=val1", "--some-key=val2")) + }) + + It("should not render defaults if the user has set a value for a flag", func() { + defs := map[string][]string{ + "some-key": {"val1", "val2"}, + } + args := EmptyArguments(). + Set("some-key", "vala") + Expect(args.AsStrings(defs)).To(ConsistOf("--some-key=vala")) + }) + }) +}) + +type commaArg []string + +func (a commaArg) Get(defs []string) []string { + // not quite, but close enough + return []string{strings.Join(defs, ",") + "," + strings.Join(a, ",")} +} +func (a commaArg) Append(vals ...string) Arg { + return commaArg(append(a, vals...)) //nolint:unconvert +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder.go new file mode 100644 index 00000000000..e1428aa6e5a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder.go @@ -0,0 +1,70 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import ( + "os" + "path/filepath" + "regexp" + "strings" +) + +const ( + // EnvAssetsPath is the environment variable that stores the global test + // binary location override. + EnvAssetsPath = "KUBEBUILDER_ASSETS" + // EnvAssetOverridePrefix is the environment variable prefix for per-binary + // location overrides. + EnvAssetOverridePrefix = "TEST_ASSET_" + // AssetsDefaultPath is the default location to look for test binaries in, + // if no override was provided. + AssetsDefaultPath = "/usr/local/kubebuilder/bin" +) + +// BinPathFinder finds the path to the given named binary, using the following locations +// in order of precedence (highest first). Notice that the various env vars only need +// to be set -- the asset is not checked for existence on the filesystem. +// +// 1. TEST_ASSET_{tr/a-z-/A-Z_/} (if set; asset overrides -- EnvAssetOverridePrefix) +// 1. KUBEBUILDER_ASSETS (if set; global asset path -- EnvAssetsPath) +// 3. assetDirectory (if set; per-config asset directory) +// 4. /usr/local/kubebuilder/bin (AssetsDefaultPath). +func BinPathFinder(symbolicName, assetDirectory string) (binPath string) { + punctuationPattern := regexp.MustCompile("[^A-Z0-9]+") + sanitizedName := punctuationPattern.ReplaceAllString(strings.ToUpper(symbolicName), "_") + leadingNumberPattern := regexp.MustCompile("^[0-9]+") + sanitizedName = leadingNumberPattern.ReplaceAllString(sanitizedName, "") + envVar := EnvAssetOverridePrefix + sanitizedName + + // TEST_ASSET_XYZ + if val, ok := os.LookupEnv(envVar); ok { + return val + } + + // KUBEBUILDER_ASSETS + if val, ok := os.LookupEnv(EnvAssetsPath); ok { + return filepath.Join(val, symbolicName) + } + + // assetDirectory + if assetDirectory != "" { + return filepath.Join(assetDirectory, symbolicName) + } + + // default path + return filepath.Join(AssetsDefaultPath, symbolicName) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder_test.go new file mode 100644 index 00000000000..1b159418402 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/bin_path_finder_test.go @@ -0,0 +1,76 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import ( + "os" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("BinPathFinder", func() { + var prevAssetPath string + BeforeEach(func() { + prevAssetPath = os.Getenv(EnvAssetsPath) + Expect(os.Unsetenv(EnvAssetsPath)).To(Succeed()) + Expect(os.Unsetenv(EnvAssetOverridePrefix + "_SOME_FAKE")) + Expect(os.Unsetenv(EnvAssetOverridePrefix + "OTHERFAKE")) + }) + AfterEach(func() { + if prevAssetPath != "" { + Expect(os.Setenv(EnvAssetsPath, prevAssetPath)) + } + }) + Context("when individual overrides are present", func() { + BeforeEach(func() { + Expect(os.Setenv(EnvAssetOverridePrefix+"OTHERFAKE", "/other/path")).To(Succeed()) + Expect(os.Setenv(EnvAssetOverridePrefix+"_SOME_FAKE", "/some/path")).To(Succeed()) + // set the global path to make sure we don't prefer it + Expect(os.Setenv(EnvAssetsPath, "/global/path")).To(Succeed()) + }) + + It("should prefer individual overrides, using them unmodified", func() { + Expect(BinPathFinder("otherfake", "/hardcoded/path")).To(Equal("/other/path")) + }) + + It("should convert lowercase to uppercase, remove leading numbers, and replace punctuation with underscores when resolving the env var name", func() { + Expect(BinPathFinder("123.some-fake", "/hardcoded/path")).To(Equal("/some/path")) + }) + }) + + Context("when individual overrides are missing but the global override is present", func() { + BeforeEach(func() { + Expect(os.Setenv(EnvAssetsPath, "/global/path")).To(Succeed()) + }) + It("should prefer the global override, appending the name to that path", func() { + Expect(BinPathFinder("some-fake", "/hardcoded/path")).To(Equal("/global/path/some-fake")) + }) + }) + + Context("when an asset directory is given and no overrides are present", func() { + It("should use the asset directory, appending the name to that path", func() { + Expect(BinPathFinder("some-fake", "/hardcoded/path")).To(Equal("/hardcoded/path/some-fake")) + }) + }) + + Context("when no path configuration is given", func() { + It("should just use the default path", func() { + Expect(BinPathFinder("some-fake", "")).To(Equal("/usr/local/kubebuilder/bin/some-fake")) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go new file mode 100644 index 00000000000..af83c70a2fa --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go @@ -0,0 +1,272 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process + +import ( + "crypto/tls" + "fmt" + "io" + "net" + "net/http" + "net/url" + "os" + "os/exec" + "path" + "regexp" + "sync" + "syscall" + "time" +) + +// ListenAddr represents some listening address and port. +type ListenAddr struct { + Address string + Port string +} + +// URL returns a URL for this address with the given scheme and subpath. +func (l *ListenAddr) URL(scheme string, path string) *url.URL { + return &url.URL{ + Scheme: scheme, + Host: l.HostPort(), + Path: path, + } +} + +// HostPort returns the joined host-port pair for this address. +func (l *ListenAddr) HostPort() string { + return net.JoinHostPort(l.Address, l.Port) +} + +// HealthCheck describes the information needed to health-check a process via +// some health-check URL. +type HealthCheck struct { + url.URL + + // HealthCheckPollInterval is the interval which will be used for polling the + // endpoint described by Host, Port, and Path. + // + // If left empty it will default to 100 Milliseconds. + PollInterval time.Duration +} + +// State define the state of the process. +type State struct { + Cmd *exec.Cmd + + // HealthCheck describes how to check if this process is up. If we get an http.StatusOK, + // we assume the process is ready to operate. + // + // For example, the /healthz endpoint of the k8s API server, or the /health endpoint of etcd. + HealthCheck HealthCheck + + Args []string + + StopTimeout time.Duration + StartTimeout time.Duration + + Dir string + DirNeedsCleaning bool + Path string + + // ready holds whether the process is currently in ready state (hit the ready condition) or not. + // It will be set to true on a successful `Start()` and set to false on a successful `Stop()` + ready bool + + // waitDone is closed when our call to wait finishes up, and indicates that + // our process has terminated. + waitDone chan struct{} + errMu sync.Mutex + exitErr error + exited bool +} + +// Init sets up this process, configuring binary paths if missing, initializing +// temporary directories, etc. +// +// This defaults all defaultable fields. +func (ps *State) Init(name string) error { + if ps.Path == "" { + if name == "" { + return fmt.Errorf("must have at least one of name or path") + } + ps.Path = BinPathFinder(name, "") + } + + if ps.Dir == "" { + newDir, err := os.MkdirTemp("", "k8s_test_framework_") + if err != nil { + return err + } + ps.Dir = newDir + ps.DirNeedsCleaning = true + } + + if ps.StartTimeout == 0 { + ps.StartTimeout = 20 * time.Second + } + + if ps.StopTimeout == 0 { + ps.StopTimeout = 20 * time.Second + } + return nil +} + +type stopChannel chan struct{} + +// CheckFlag checks the help output of this command for the presence of the given flag, specified +// without the leading `--` (e.g. `CheckFlag("insecure-port")` checks for `--insecure-port`), +// returning true if the flag is present. +func (ps *State) CheckFlag(flag string) (bool, error) { + cmd := exec.Command(ps.Path, "--help") + outContents, err := cmd.CombinedOutput() + if err != nil { + return false, fmt.Errorf("unable to run command %q to check for flag %q: %w", ps.Path, flag, err) + } + pat := `(?m)^\s*--` + flag + `\b` // (m --> multi-line --> ^ matches start of line) + matched, err := regexp.Match(pat, outContents) + if err != nil { + return false, fmt.Errorf("unable to check command %q for flag %q in help output: %w", ps.Path, flag, err) + } + return matched, nil +} + +// Start starts the apiserver, waits for it to come up, and returns an error, +// if occurred. +func (ps *State) Start(stdout, stderr io.Writer) (err error) { + if ps.ready { + return nil + } + + ps.Cmd = exec.Command(ps.Path, ps.Args...) + ps.Cmd.Stdout = stdout + ps.Cmd.Stderr = stderr + + ready := make(chan bool) + timedOut := time.After(ps.StartTimeout) + pollerStopCh := make(stopChannel) + go pollURLUntilOK(ps.HealthCheck.URL, ps.HealthCheck.PollInterval, ready, pollerStopCh) + + ps.waitDone = make(chan struct{}) + + if err := ps.Cmd.Start(); err != nil { + ps.errMu.Lock() + defer ps.errMu.Unlock() + ps.exited = true + return err + } + go func() { + defer close(ps.waitDone) + err := ps.Cmd.Wait() + + ps.errMu.Lock() + defer ps.errMu.Unlock() + ps.exitErr = err + ps.exited = true + }() + + select { + case <-ready: + ps.ready = true + return nil + case <-ps.waitDone: + close(pollerStopCh) + return fmt.Errorf("timeout waiting for process %s to start successfully "+ + "(it may have failed to start, or stopped unexpectedly before becoming ready)", + path.Base(ps.Path)) + case <-timedOut: + close(pollerStopCh) + if ps.Cmd != nil { + // intentionally ignore this -- we might've crashed, failed to start, etc + ps.Cmd.Process.Signal(syscall.SIGTERM) //nolint:errcheck + } + return fmt.Errorf("timeout waiting for process %s to start", path.Base(ps.Path)) + } +} + +// Exited returns true if the process exited, and may also +// return an error (as per Cmd.Wait) if the process did not +// exit with error code 0. +func (ps *State) Exited() (bool, error) { + ps.errMu.Lock() + defer ps.errMu.Unlock() + return ps.exited, ps.exitErr +} + +func pollURLUntilOK(url url.URL, interval time.Duration, ready chan bool, stopCh stopChannel) { + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + // there's probably certs *somewhere*, + // but it's fine to just skip validating + // them for health checks during testing + InsecureSkipVerify: true, //nolint:gosec + }, + }, + } + if interval <= 0 { + interval = 100 * time.Millisecond + } + for { + res, err := client.Get(url.String()) + if err == nil { + res.Body.Close() + if res.StatusCode == http.StatusOK { + ready <- true + return + } + } + + select { + case <-stopCh: + return + default: + time.Sleep(interval) + } + } +} + +// Stop stops this process gracefully, waits for its termination, and cleans up +// the CertDir if necessary. +func (ps *State) Stop() error { + // Always clear the directory if we need to. + defer func() { + if ps.DirNeedsCleaning { + _ = os.RemoveAll(ps.Dir) + } + }() + if ps.Cmd == nil { + return nil + } + if done, _ := ps.Exited(); done { + return nil + } + if err := ps.Cmd.Process.Signal(syscall.SIGTERM); err != nil { + return fmt.Errorf("unable to signal for process %s to stop: %w", ps.Path, err) + } + + timedOut := time.After(ps.StopTimeout) + + select { + case <-ps.waitDone: + break + case <-timedOut: + return fmt.Errorf("timeout waiting for process %s to stop", path.Base(ps.Path)) + } + ps.ready = false + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_suite_test.go new file mode 100644 index 00000000000..5a64e9d2f09 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_suite_test.go @@ -0,0 +1,30 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestInternal(t *testing.T) { + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "Envtest Process Launcher Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_test.go new file mode 100644 index 00000000000..5b0708227a0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process_test.go @@ -0,0 +1,372 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package process_test + +import ( + "bytes" + "net" + "net/http" + "net/url" + "os" + "strconv" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/ghttp" + "sigs.k8s.io/controller-runtime/pkg/internal/testing/addr" + . "sigs.k8s.io/controller-runtime/pkg/internal/testing/process" +) + +const ( + healthURLPath = "/healthz" +) + +var _ = Describe("Start method", func() { + var ( + processState *State + server *ghttp.Server + ) + BeforeEach(func() { + server = ghttp.NewServer() + + processState = &State{ + Path: "bash", + Args: simpleBashScript, + HealthCheck: HealthCheck{ + URL: getServerURL(server), + }, + } + processState.Path = "bash" + processState.Args = simpleBashScript + + }) + AfterEach(func() { + server.Close() + }) + + Context("when process takes too long to start", func() { + BeforeEach(func() { + server.RouteToHandler("GET", healthURLPath, func(resp http.ResponseWriter, _ *http.Request) { + time.Sleep(250 * time.Millisecond) + resp.WriteHeader(http.StatusOK) + }) + }) + It("returns a timeout error", func() { + processState.StartTimeout = 200 * time.Millisecond + + err := processState.Start(nil, nil) + Expect(err).To(MatchError(ContainSubstring("timeout"))) + + Eventually(func() bool { done, _ := processState.Exited(); return done }).Should(BeTrue()) + }) + }) + + Context("when the healthcheck returns ok", func() { + BeforeEach(func() { + + server.RouteToHandler("GET", healthURLPath, ghttp.RespondWith(http.StatusOK, "")) + }) + + It("can start a process", func() { + processState.StartTimeout = 10 * time.Second + + err := processState.Start(nil, nil) + Expect(err).NotTo(HaveOccurred()) + + Consistently(processState.Exited).Should(BeFalse()) + }) + + It("hits the endpoint, and successfully starts", func() { + processState.StartTimeout = 100 * time.Millisecond + + err := processState.Start(nil, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(server.ReceivedRequests()).To(HaveLen(1)) + Consistently(processState.Exited).Should(BeFalse()) + }) + + Context("when the command cannot be started", func() { + var err error + + BeforeEach(func() { + processState = &State{} + processState.Path = "/nonexistent" + + err = processState.Start(nil, nil) + }) + + It("propagates the error", func() { + Expect(os.IsNotExist(err)).To(BeTrue()) + }) + + Context("but Stop() is called on it", func() { + It("does not panic", func() { + stoppingFailedProcess := func() { + Expect(processState.Stop()).To(Succeed()) + } + + Expect(stoppingFailedProcess).NotTo(Panic()) + }) + }) + }) + + Context("when IO is configured", func() { + It("can inspect stdout & stderr", func() { + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + + processState.Args = []string{ + "-c", + ` + echo 'this is stderr' >&2 + echo 'that is stdout' + echo 'i started' >&2 + `, + } + processState.StartTimeout = 5 * time.Second + + Expect(processState.Start(stdout, stderr)).To(Succeed()) + Eventually(processState.Exited).Should(BeTrue()) + + Expect(stdout.String()).To(Equal("that is stdout\n")) + Expect(stderr.String()).To(Equal("this is stderr\ni started\n")) + }) + }) + }) + + Context("when the healthcheck always returns failure", func() { + BeforeEach(func() { + server.RouteToHandler("GET", healthURLPath, ghttp.RespondWith(http.StatusInternalServerError, "")) + }) + It("returns a timeout error and stops health API checker", func() { + processState.HealthCheck.URL = getServerURL(server) + processState.HealthCheck.Path = healthURLPath + processState.StartTimeout = 500 * time.Millisecond + + err := processState.Start(nil, nil) + Expect(err).To(MatchError(ContainSubstring("timeout"))) + + nrReceivedRequests := len(server.ReceivedRequests()) + Expect(nrReceivedRequests).To(Equal(5)) + time.Sleep(200 * time.Millisecond) + Expect(nrReceivedRequests).To(Equal(5)) + }) + }) + + Context("when the healthcheck isn't even listening", func() { + BeforeEach(func() { + server.Close() + }) + + It("returns a timeout error", func() { + processState.HealthCheck.Path = healthURLPath + processState.StartTimeout = 500 * time.Millisecond + + port, host, err := addr.Suggest("") + Expect(err).NotTo(HaveOccurred()) + + processState.HealthCheck.URL = url.URL{ + Scheme: "http", + Host: net.JoinHostPort(host, strconv.Itoa(port)), + } + + err = processState.Start(nil, nil) + Expect(err).To(MatchError(ContainSubstring("timeout"))) + }) + }) + + Context("when the healthcheck fails initially but succeeds eventually", func() { + BeforeEach(func() { + server.AppendHandlers( + ghttp.RespondWith(http.StatusInternalServerError, ""), + ghttp.RespondWith(http.StatusInternalServerError, ""), + ghttp.RespondWith(http.StatusInternalServerError, ""), + ghttp.RespondWith(http.StatusOK, ""), + ) + }) + + It("hits the endpoint repeatedly, and successfully starts", func() { + processState.HealthCheck.URL = getServerURL(server) + processState.HealthCheck.Path = healthURLPath + processState.StartTimeout = 20 * time.Second + + err := processState.Start(nil, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(server.ReceivedRequests()).To(HaveLen(4)) + Consistently(processState.Exited).Should(BeFalse()) + }) + + Context("when the polling interval is not configured", func() { + It("uses the default interval for polling", func() { + processState.HealthCheck.URL = getServerURL(server) + processState.HealthCheck.Path = "/helathz" + processState.StartTimeout = 300 * time.Millisecond + + Expect(processState.Start(nil, nil)).To(MatchError(ContainSubstring("timeout"))) + Expect(server.ReceivedRequests()).To(HaveLen(3)) + }) + }) + + Context("when the polling interval is configured", func() { + BeforeEach(func() { + processState.HealthCheck.URL = getServerURL(server) + processState.HealthCheck.Path = healthURLPath + processState.HealthCheck.PollInterval = time.Millisecond * 150 + }) + + It("hits the endpoint in the configured interval", func() { + processState.StartTimeout = 3 * processState.HealthCheck.PollInterval + + Expect(processState.Start(nil, nil)).To(MatchError(ContainSubstring("timeout"))) + Expect(server.ReceivedRequests()).To(HaveLen(3)) + }) + }) + }) +}) + +var _ = Describe("Stop method", func() { + var ( + server *ghttp.Server + processState *State + ) + BeforeEach(func() { + server = ghttp.NewServer() + server.RouteToHandler("GET", healthURLPath, ghttp.RespondWith(http.StatusOK, "")) + processState = &State{ + Path: "bash", + Args: simpleBashScript, + HealthCheck: HealthCheck{ + URL: getServerURL(server), + }, + } + processState.StartTimeout = 10 * time.Second + }) + + AfterEach(func() { + server.Close() + }) + Context("when Stop() is called", func() { + BeforeEach(func() { + Expect(processState.Start(nil, nil)).To(Succeed()) + processState.StopTimeout = 10 * time.Second + }) + + It("stops the process", func() { + Expect(processState.Stop()).To(Succeed()) + }) + + Context("multiple times", func() { + It("does not error or panic on consecutive calls", func() { + stoppingTheProcess := func() { + Expect(processState.Stop()).To(Succeed()) + } + Expect(stoppingTheProcess).NotTo(Panic()) + Expect(stoppingTheProcess).NotTo(Panic()) + Expect(stoppingTheProcess).NotTo(Panic()) + }) + }) + }) + + Context("when the command cannot be stopped", func() { + It("returns a timeout error", func() { + Expect(processState.Start(nil, nil)).To(Succeed()) + processState.StopTimeout = 1 * time.Nanosecond // much shorter than the sleep in the script + + Expect(processState.Stop()).To(MatchError(ContainSubstring("timeout"))) + }) + }) + + Context("when the directory needs to be cleaned up", func() { + It("removes the directory", func() { + var err error + + Expect(processState.Start(nil, nil)).To(Succeed()) + processState.Dir, err = os.MkdirTemp("", "k8s_test_framework_") + Expect(err).NotTo(HaveOccurred()) + processState.DirNeedsCleaning = true + processState.StopTimeout = 400 * time.Millisecond + + Expect(processState.Stop()).To(Succeed()) + Expect(processState.Dir).NotTo(BeAnExistingFile()) + }) + }) +}) + +var _ = Describe("Init", func() { + Context("when all inputs are provided", func() { + It("passes them through", func() { + ps := &State{ + Dir: "/some/dir", + Path: "/some/path/to/some/bin", + StartTimeout: 20 * time.Hour, + StopTimeout: 65537 * time.Millisecond, + } + + Expect(ps.Init("some name")).To(Succeed()) + + Expect(ps.Dir).To(Equal("/some/dir")) + Expect(ps.DirNeedsCleaning).To(BeFalse()) + Expect(ps.Path).To(Equal("/some/path/to/some/bin")) + Expect(ps.StartTimeout).To(Equal(20 * time.Hour)) + Expect(ps.StopTimeout).To(Equal(65537 * time.Millisecond)) + }) + }) + + Context("when inputs are empty", func() { + It("ps them", func() { + ps := &State{} + Expect(ps.Init("some name")).To(Succeed()) + + Expect(ps.Dir).To(BeADirectory()) + Expect(os.RemoveAll(ps.Dir)).To(Succeed()) + Expect(ps.DirNeedsCleaning).To(BeTrue()) + + Expect(ps.Path).NotTo(BeEmpty()) + + Expect(ps.StartTimeout).NotTo(BeZero()) + Expect(ps.StopTimeout).NotTo(BeZero()) + }) + }) + + Context("when neither name nor path are provided", func() { + It("returns an error", func() { + ps := &State{} + Expect(ps.Init("")).To(MatchError("must have at least one of name or path")) + }) + }) +}) + +var simpleBashScript = []string{ + "-c", + ` + i=0 + while true + do + echo "loop $i" >&2 + let 'i += 1' + sleep 0.2 + done + `, +} + +func getServerURL(server *ghttp.Server) url.URL { + url, err := url.Parse(server.URL()) + Expect(err).NotTo(HaveOccurred()) + url.Path = healthURLPath + return *url +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go new file mode 100644 index 00000000000..37a9aefab58 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package leaderelection contains a constructor for a leader election resource lock. +This is used to ensure that multiple copies of a controller manager can be run with +only one active set of controllers, for active-passive HA. + +It uses built-in Kubernetes leader election APIs. +*/ +package leaderelection diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/doc.go new file mode 100644 index 00000000000..3fff7c7189a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package fake mocks a resource lock for testing purposes. +Always returns leadership. +*/ +package fake diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/leader_election.go b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/leader_election.go new file mode 100644 index 00000000000..5a82cf43b87 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/fake/leader_election.go @@ -0,0 +1,96 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "context" + "encoding/json" + "os" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "sigs.k8s.io/controller-runtime/pkg/leaderelection" + "sigs.k8s.io/controller-runtime/pkg/recorder" +) + +// NewResourceLock creates a new ResourceLock for use in testing +// leader election. +func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) { + // Leader id, needs to be unique + id, err := os.Hostname() + if err != nil { + return nil, err + } + id = id + "_" + string(uuid.NewUUID()) + + return &ResourceLock{ + id: id, + record: resourcelock.LeaderElectionRecord{ + HolderIdentity: id, + LeaseDurationSeconds: 15, + AcquireTime: metav1.NewTime(time.Now()), + RenewTime: metav1.NewTime(time.Now().Add(15 * time.Second)), + LeaderTransitions: 1, + }, + }, nil +} + +// ResourceLock implements the ResourceLockInterface. +// By default returns that the current identity holds the lock. +type ResourceLock struct { + id string + record resourcelock.LeaderElectionRecord +} + +// Get implements the ResourceLockInterface. +func (f *ResourceLock) Get(ctx context.Context) (*resourcelock.LeaderElectionRecord, []byte, error) { + recordBytes, err := json.Marshal(f.record) + if err != nil { + return nil, nil, err + } + return &f.record, recordBytes, nil +} + +// Create implements the ResourceLockInterface. +func (f *ResourceLock) Create(ctx context.Context, ler resourcelock.LeaderElectionRecord) error { + f.record = ler + return nil +} + +// Update implements the ResourceLockInterface. +func (f *ResourceLock) Update(ctx context.Context, ler resourcelock.LeaderElectionRecord) error { + f.record = ler + return nil +} + +// RecordEvent implements the ResourceLockInterface. +func (f *ResourceLock) RecordEvent(s string) { + +} + +// Identity implements the ResourceLockInterface. +func (f *ResourceLock) Identity() string { + return f.id +} + +// Describe implements the ResourceLockInterface. +func (f *ResourceLock) Describe() string { + return f.id +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go new file mode 100644 index 00000000000..ee4fcf4cbe0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go @@ -0,0 +1,127 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package leaderelection + +import ( + "errors" + "fmt" + "os" + + "k8s.io/apimachinery/pkg/util/uuid" + coordinationv1client "k8s.io/client-go/kubernetes/typed/coordination/v1" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + + "sigs.k8s.io/controller-runtime/pkg/recorder" +) + +const inClusterNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" + +// Options provides the required configuration to create a new resource lock. +type Options struct { + // LeaderElection determines whether or not to use leader election when + // starting the manager. + LeaderElection bool + + // LeaderElectionResourceLock determines which resource lock to use for leader election, + // defaults to "leases". + LeaderElectionResourceLock string + + // LeaderElectionNamespace determines the namespace in which the leader + // election resource will be created. + LeaderElectionNamespace string + + // LeaderElectionID determines the name of the resource that leader election + // will use for holding the leader lock. + LeaderElectionID string +} + +// NewResourceLock creates a new resource lock for use in a leader election loop. +func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, options Options) (resourcelock.Interface, error) { + if !options.LeaderElection { + return nil, nil + } + + // Default resource lock to "leases". The previous default (from v0.7.0 to v0.11.x) was configmapsleases, which was + // used to migrate from configmaps to leases. Since the default was "configmapsleases" for over a year, spanning + // five minor releases, any actively maintained operators are very likely to have a released version that uses + // "configmapsleases". Therefore defaulting to "leases" should be safe. + if options.LeaderElectionResourceLock == "" { + options.LeaderElectionResourceLock = resourcelock.LeasesResourceLock + } + + // LeaderElectionID must be provided to prevent clashes + if options.LeaderElectionID == "" { + return nil, errors.New("LeaderElectionID must be configured") + } + + // Default the namespace (if running in cluster) + if options.LeaderElectionNamespace == "" { + var err error + options.LeaderElectionNamespace, err = getInClusterNamespace() + if err != nil { + return nil, fmt.Errorf("unable to find leader election namespace: %w", err) + } + } + + // Leader id, needs to be unique + id, err := os.Hostname() + if err != nil { + return nil, err + } + id = id + "_" + string(uuid.NewUUID()) + + // Construct clients for leader election + rest.AddUserAgent(config, "leader-election") + corev1Client, err := corev1client.NewForConfig(config) + if err != nil { + return nil, err + } + + coordinationClient, err := coordinationv1client.NewForConfig(config) + if err != nil { + return nil, err + } + + return resourcelock.New(options.LeaderElectionResourceLock, + options.LeaderElectionNamespace, + options.LeaderElectionID, + corev1Client, + coordinationClient, + resourcelock.ResourceLockConfig{ + Identity: id, + EventRecorder: recorderProvider.GetEventRecorderFor(id), + }) +} + +func getInClusterNamespace() (string, error) { + // Check whether the namespace file exists. + // If not, we are not running in cluster so can't guess the namespace. + if _, err := os.Stat(inClusterNamespacePath); os.IsNotExist(err) { + return "", fmt.Errorf("not running in-cluster, please specify LeaderElectionNamespace") + } else if err != nil { + return "", fmt.Errorf("error checking namespace file: %w", err) + } + + // Load the namespace file and return its content + namespace, err := os.ReadFile(inClusterNamespacePath) + if err != nil { + return "", fmt.Errorf("error reading namespace file: %w", err) + } + return string(namespace), nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/deleg.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/deleg.go new file mode 100644 index 00000000000..c27b4305f8b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/deleg.go @@ -0,0 +1,205 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "sync" + + "github.com/go-logr/logr" +) + +// loggerPromise knows how to populate a concrete logr.Logger +// with options, given an actual base logger later on down the line. +type loggerPromise struct { + logger *delegatingLogSink + childPromises []*loggerPromise + promisesLock sync.Mutex + + name *string + tags []interface{} +} + +func (p *loggerPromise) WithName(l *delegatingLogSink, name string) *loggerPromise { + res := &loggerPromise{ + logger: l, + name: &name, + promisesLock: sync.Mutex{}, + } + + p.promisesLock.Lock() + defer p.promisesLock.Unlock() + p.childPromises = append(p.childPromises, res) + return res +} + +// WithValues provides a new Logger with the tags appended. +func (p *loggerPromise) WithValues(l *delegatingLogSink, tags ...interface{}) *loggerPromise { + res := &loggerPromise{ + logger: l, + tags: tags, + promisesLock: sync.Mutex{}, + } + + p.promisesLock.Lock() + defer p.promisesLock.Unlock() + p.childPromises = append(p.childPromises, res) + return res +} + +// Fulfill instantiates the Logger with the provided logger. +func (p *loggerPromise) Fulfill(parentLogSink logr.LogSink) { + sink := parentLogSink + if p.name != nil { + sink = sink.WithName(*p.name) + } + + if p.tags != nil { + sink = sink.WithValues(p.tags...) + } + + p.logger.lock.Lock() + p.logger.logger = sink + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + p.logger.logger = withCallDepth.WithCallDepth(1) + } + p.logger.promise = nil + p.logger.lock.Unlock() + + for _, childPromise := range p.childPromises { + childPromise.Fulfill(sink) + } +} + +// delegatingLogSink is a logsink that delegates to another logr.LogSink. +// If the underlying promise is not nil, it registers calls to sub-loggers with +// the logging factory to be populated later, and returns a new delegating +// logger. It expects to have *some* logr.Logger set at all times (generally +// a no-op logger before the promises are fulfilled). +type delegatingLogSink struct { + lock sync.RWMutex + logger logr.LogSink + promise *loggerPromise + info logr.RuntimeInfo +} + +// Init implements logr.LogSink. +func (l *delegatingLogSink) Init(info logr.RuntimeInfo) { + eventuallyFulfillRoot() + l.lock.Lock() + defer l.lock.Unlock() + l.info = info +} + +// Enabled tests whether this Logger is enabled. For example, commandline +// flags might be used to set the logging verbosity and disable some info +// logs. +func (l *delegatingLogSink) Enabled(level int) bool { + eventuallyFulfillRoot() + l.lock.RLock() + defer l.lock.RUnlock() + return l.logger.Enabled(level) +} + +// Info logs a non-error message with the given key/value pairs as context. +// +// The msg argument should be used to add some constant description to +// the log line. The key/value pairs can then be used to add additional +// variable information. The key/value pairs should alternate string +// keys and arbitrary values. +func (l *delegatingLogSink) Info(level int, msg string, keysAndValues ...interface{}) { + eventuallyFulfillRoot() + l.lock.RLock() + defer l.lock.RUnlock() + l.logger.Info(level, msg, keysAndValues...) +} + +// Error logs an error, with the given message and key/value pairs as context. +// It functions similarly to calling Info with the "error" named value, but may +// have unique behavior, and should be preferred for logging errors (see the +// package documentations for more information). +// +// The msg field should be used to add context to any underlying error, +// while the err field should be used to attach the actual error that +// triggered this log line, if present. +func (l *delegatingLogSink) Error(err error, msg string, keysAndValues ...interface{}) { + eventuallyFulfillRoot() + l.lock.RLock() + defer l.lock.RUnlock() + l.logger.Error(err, msg, keysAndValues...) +} + +// WithName provides a new Logger with the name appended. +func (l *delegatingLogSink) WithName(name string) logr.LogSink { + eventuallyFulfillRoot() + l.lock.RLock() + defer l.lock.RUnlock() + + if l.promise == nil { + sink := l.logger.WithName(name) + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + sink = withCallDepth.WithCallDepth(-1) + } + return sink + } + + res := &delegatingLogSink{logger: l.logger} + promise := l.promise.WithName(res, name) + res.promise = promise + + return res +} + +// WithValues provides a new Logger with the tags appended. +func (l *delegatingLogSink) WithValues(tags ...interface{}) logr.LogSink { + eventuallyFulfillRoot() + l.lock.RLock() + defer l.lock.RUnlock() + + if l.promise == nil { + sink := l.logger.WithValues(tags...) + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + sink = withCallDepth.WithCallDepth(-1) + } + return sink + } + + res := &delegatingLogSink{logger: l.logger} + promise := l.promise.WithValues(res, tags...) + res.promise = promise + + return res +} + +// Fulfill switches the logger over to use the actual logger +// provided, instead of the temporary initial one, if this method +// has not been previously called. +func (l *delegatingLogSink) Fulfill(actual logr.LogSink) { + if l.promise != nil { + l.promise.Fulfill(actual) + } +} + +// newDelegatingLogSink constructs a new DelegatingLogSink which uses +// the given logger before its promise is fulfilled. +func newDelegatingLogSink(initial logr.LogSink) *delegatingLogSink { + l := &delegatingLogSink{ + logger: initial, + promise: &loggerPromise{promisesLock: sync.Mutex{}}, + } + l.promise.logger = l + return l +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/log.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log.go new file mode 100644 index 00000000000..a79151c69ed --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log.go @@ -0,0 +1,96 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package log contains utilities for fetching a new logger +// when one is not already available. +// +// # The Log Handle +// +// This package contains a root logr.Logger Log. It may be used to +// get a handle to whatever the root logging implementation is. By +// default, no implementation exists, and the handle returns "promises" +// to loggers. When the implementation is set using SetLogger, these +// "promises" will be converted over to real loggers. +// +// # Logr +// +// All logging in controller-runtime is structured, using a set of interfaces +// defined by a package called logr +// (https://pkg.go.dev/github.com/go-logr/logr). The sub-package zap provides +// helpers for setting up logr backed by Zap (go.uber.org/zap). +package log + +import ( + "context" + "fmt" + "os" + "runtime/debug" + "sync/atomic" + "time" + + "github.com/go-logr/logr" +) + +// SetLogger sets a concrete logging implementation for all deferred Loggers. +func SetLogger(l logr.Logger) { + logFullfilled.Store(true) + rootLog.Fulfill(l.GetSink()) +} + +func eventuallyFulfillRoot() { + if logFullfilled.Load() { + return + } + if time.Since(rootLogCreated).Seconds() >= 30 { + if logFullfilled.CompareAndSwap(false, true) { + fmt.Fprintf(os.Stderr, "[controller-runtime] log.SetLogger(...) was never called, logs will not be displayed:\n%s", debug.Stack()) + SetLogger(logr.New(NullLogSink{})) + } + } +} + +var ( + logFullfilled atomic.Bool +) + +// Log is the base logger used by kubebuilder. It delegates +// to another logr.Logger. You *must* call SetLogger to +// get any actual logging. If SetLogger is not called within +// the first 30 seconds of a binaries lifetime, it will get +// set to a NullLogSink. +var ( + rootLog, rootLogCreated = func() (*delegatingLogSink, time.Time) { + return newDelegatingLogSink(NullLogSink{}), time.Now() + }() + Log = logr.New(rootLog) +) + +// FromContext returns a logger with predefined values from a context.Context. +func FromContext(ctx context.Context, keysAndValues ...interface{}) logr.Logger { + log := Log + if ctx != nil { + if logger, err := logr.FromContext(ctx); err == nil { + log = logger + } + } + return log.WithValues(keysAndValues...) +} + +// IntoContext takes a context and sets the logger as one of its values. +// Use FromContext function to retrieve the logger. +func IntoContext(ctx context.Context, log logr.Logger) context.Context { + return logr.NewContext(ctx, log) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_suite_test.go new file mode 100644 index 00000000000..f0e349aa867 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Log Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_test.go new file mode 100644 index 00000000000..c0ca462369f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/log_test.go @@ -0,0 +1,330 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "context" + "errors" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ logr.LogSink = &delegatingLogSink{} + +// logInfo is the information for a particular fakeLogger message. +type logInfo struct { + name []string + tags []interface{} + msg string +} + +// fakeLoggerRoot is the root object to which all fakeLoggers record their messages. +type fakeLoggerRoot struct { + messages []logInfo +} + +// fakeLogger is a fake implementation of logr.Logger that records +// messages, tags, and names, +// just records the name. +type fakeLogger struct { + name []string + tags []interface{} + + root *fakeLoggerRoot +} + +func (f *fakeLogger) Init(info logr.RuntimeInfo) { +} + +func (f *fakeLogger) WithName(name string) logr.LogSink { + names := append([]string(nil), f.name...) + names = append(names, name) + return &fakeLogger{ + name: names, + tags: f.tags, + root: f.root, + } +} + +func (f *fakeLogger) WithValues(vals ...interface{}) logr.LogSink { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, vals...) + return &fakeLogger{ + name: f.name, + tags: tags, + root: f.root, + } +} + +func (f *fakeLogger) Error(err error, msg string, vals ...interface{}) { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, "error", err) + tags = append(tags, vals...) + f.root.messages = append(f.root.messages, logInfo{ + name: append([]string(nil), f.name...), + tags: tags, + msg: msg, + }) +} + +func (f *fakeLogger) Info(level int, msg string, vals ...interface{}) { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, vals...) + f.root.messages = append(f.root.messages, logInfo{ + name: append([]string(nil), f.name...), + tags: tags, + msg: msg, + }) +} + +func (f *fakeLogger) Enabled(level int) bool { return true } + +var _ = Describe("logging", func() { + + Describe("top-level logger", func() { + It("hold newly created loggers until a logger is set", func() { + By("grabbing a new sub-logger and logging to it") + l1 := Log.WithName("runtimeLog").WithValues("newtag", "newvalue1") + l1.Info("before msg") + + By("actually setting the logger") + logger := &fakeLogger{root: &fakeLoggerRoot{}} + SetLogger(logr.New(logger)) + + By("grabbing another sub-logger and logging to both loggers") + l2 := Log.WithName("runtimeLog").WithValues("newtag", "newvalue2") + l1.Info("after msg 1") + l2.Info("after msg 2") + + By("ensuring that messages after the logger was set were logged") + Expect(logger.root.messages).To(ConsistOf( + logInfo{name: []string{"runtimeLog"}, tags: []interface{}{"newtag", "newvalue1"}, msg: "after msg 1"}, + logInfo{name: []string{"runtimeLog"}, tags: []interface{}{"newtag", "newvalue2"}, msg: "after msg 2"}, + )) + }) + }) + + Describe("lazy logger initialization", func() { + var ( + root *fakeLoggerRoot + baseLog logr.LogSink + delegLog *delegatingLogSink + ) + + BeforeEach(func() { + root = &fakeLoggerRoot{} + baseLog = &fakeLogger{root: root} + delegLog = newDelegatingLogSink(NullLogSink{}) + }) + + It("should delegate with name", func() { + By("asking for a logger with a name before fulfill, and logging") + befFulfill1 := logr.New(delegLog).WithName("before-fulfill") + befFulfill2 := befFulfill1.WithName("two") + befFulfill1.Info("before fulfill") + + By("logging on the base logger before fulfill") + logr.New(delegLog).Info("before fulfill base") + + By("ensuring that no messages were actually recorded") + Expect(root.messages).To(BeEmpty()) + + By("fulfilling the promise") + delegLog.Fulfill(baseLog) + + By("logging with the existing loggers after fulfilling") + befFulfill1.Info("after 1") + befFulfill2.Info("after 2") + + By("grabbing a new sub-logger of a previously constructed logger and logging to it") + befFulfill1.WithName("after-from-before").Info("after 3") + + By("logging with new loggers") + logr.New(delegLog).WithName("after-fulfill").Info("after 4") + + By("ensuring that the messages are appropriately named") + Expect(root.messages).To(ConsistOf( + logInfo{name: []string{"before-fulfill"}, msg: "after 1"}, + logInfo{name: []string{"before-fulfill", "two"}, msg: "after 2"}, + logInfo{name: []string{"before-fulfill", "after-from-before"}, msg: "after 3"}, + logInfo{name: []string{"after-fulfill"}, msg: "after 4"}, + )) + }) + + // This test in itself will always succeed, a failure will be indicated by the + // race detector going off + It("should be threadsafe", func() { + fulfillDone := make(chan struct{}) + withNameDone := make(chan struct{}) + withValuesDone := make(chan struct{}) + grandChildDone := make(chan struct{}) + logEnabledDone := make(chan struct{}) + logInfoDone := make(chan struct{}) + logErrorDone := make(chan struct{}) + logVDone := make(chan struct{}) + + // Constructing the child in the goroutine does not reliably + // trigger the race detector + child := logr.New(delegLog).WithName("child") + go func() { + defer GinkgoRecover() + delegLog.Fulfill(NullLogSink{}) + close(fulfillDone) + }() + go func() { + defer GinkgoRecover() + delegLog.WithName("with-name") + close(withNameDone) + }() + go func() { + defer GinkgoRecover() + delegLog.WithValues("with-value") + close(withValuesDone) + }() + go func() { + defer GinkgoRecover() + child.WithValues("grandchild") + close(grandChildDone) + }() + go func() { + defer GinkgoRecover() + logr.New(delegLog).Enabled() + close(logEnabledDone) + }() + go func() { + defer GinkgoRecover() + logr.New(delegLog).Info("hello world") + close(logInfoDone) + }() + go func() { + defer GinkgoRecover() + delegLog.Error(errors.New("err"), "hello world") + close(logErrorDone) + }() + go func() { + defer GinkgoRecover() + logr.New(delegLog).V(1) + close(logVDone) + }() + + <-fulfillDone + <-withNameDone + <-withValuesDone + <-grandChildDone + <-logEnabledDone + <-logInfoDone + <-logErrorDone + <-logVDone + }) + + It("should delegate with tags", func() { + By("asking for a logger with a name before fulfill, and logging") + befFulfill1 := logr.New(delegLog).WithValues("tag1", "val1") + befFulfill2 := befFulfill1.WithValues("tag2", "val2") + befFulfill1.Info("before fulfill") + + By("logging on the base logger before fulfill") + logr.New(delegLog).Info("before fulfill base") + + By("ensuring that no messages were actually recorded") + Expect(root.messages).To(BeEmpty()) + + By("fulfilling the promise") + delegLog.Fulfill(baseLog) + + By("logging with the existing loggers after fulfilling") + befFulfill1.Info("after 1") + befFulfill2.Info("after 2") + + By("grabbing a new sub-logger of a previously constructed logger and logging to it") + befFulfill1.WithValues("tag3", "val3").Info("after 3") + + By("logging with new loggers") + logr.New(delegLog).WithValues("tag3", "val3").Info("after 4") + + By("ensuring that the messages are appropriately named") + Expect(root.messages).To(ConsistOf( + logInfo{tags: []interface{}{"tag1", "val1"}, msg: "after 1"}, + logInfo{tags: []interface{}{"tag1", "val1", "tag2", "val2"}, msg: "after 2"}, + logInfo{tags: []interface{}{"tag1", "val1", "tag3", "val3"}, msg: "after 3"}, + logInfo{tags: []interface{}{"tag3", "val3"}, msg: "after 4"}, + )) + }) + + It("shouldn't fulfill twice", func() { + By("fulfilling once") + delegLog.Fulfill(baseLog) + + By("logging a bit") + logr.New(delegLog).Info("msg 1") + + By("fulfilling with a new logger") + delegLog.Fulfill(&fakeLogger{}) + + By("logging some more") + logr.New(delegLog).Info("msg 2") + + By("checking that all log messages are present") + Expect(root.messages).To(ConsistOf( + logInfo{msg: "msg 1"}, + logInfo{msg: "msg 2"}, + )) + }) + }) + + Describe("logger from context", func() { + It("should return default logger when context is empty", func() { + gotLog := FromContext(context.Background()) + Expect(gotLog).To(Not(BeNil())) + }) + + It("should return existing logger", func() { + root := &fakeLoggerRoot{} + baseLog := &fakeLogger{root: root} + + wantLog := logr.New(baseLog).WithName("my-logger") + ctx := IntoContext(context.Background(), wantLog) + + gotLog := FromContext(ctx) + Expect(gotLog).To(Not(BeNil())) + + gotLog.Info("test message") + Expect(root.messages).To(ConsistOf( + logInfo{name: []string{"my-logger"}, msg: "test message"}, + )) + }) + + It("should have added key-values", func() { + root := &fakeLoggerRoot{} + baseLog := &fakeLogger{root: root} + + wantLog := logr.New(baseLog).WithName("my-logger") + ctx := IntoContext(context.Background(), wantLog) + + gotLog := FromContext(ctx, "tag1", "value1") + Expect(gotLog).To(Not(BeNil())) + + gotLog.Info("test message") + Expect(root.messages).To(ConsistOf( + logInfo{name: []string{"my-logger"}, tags: []interface{}{"tag1", "value1"}, msg: "test message"}, + )) + }) + }) + +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/null.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/null.go new file mode 100644 index 00000000000..f3e81074fee --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/null.go @@ -0,0 +1,59 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "github.com/go-logr/logr" +) + +// NB: this is the same as the null logger logr/testing, +// but avoids accidentally adding the testing flags to +// all binaries. + +// NullLogSink is a logr.Logger that does nothing. +type NullLogSink struct{} + +var _ logr.LogSink = NullLogSink{} + +// Init implements logr.LogSink. +func (log NullLogSink) Init(logr.RuntimeInfo) { +} + +// Info implements logr.InfoLogger. +func (NullLogSink) Info(_ int, _ string, _ ...interface{}) { + // Do nothing. +} + +// Enabled implements logr.InfoLogger. +func (NullLogSink) Enabled(level int) bool { + return false +} + +// Error implements logr.Logger. +func (NullLogSink) Error(_ error, _ string, _ ...interface{}) { + // Do nothing. +} + +// WithName implements logr.Logger. +func (log NullLogSink) WithName(_ string) logr.LogSink { + return log +} + +// WithValues implements logr.Logger. +func (log NullLogSink) WithValues(_ ...interface{}) logr.LogSink { + return log +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/warning_handler.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/warning_handler.go new file mode 100644 index 00000000000..e9522632d3d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/warning_handler.go @@ -0,0 +1,76 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "sync" + + "github.com/go-logr/logr" +) + +// KubeAPIWarningLoggerOptions controls the behavior +// of a rest.WarningHandler constructed using NewKubeAPIWarningLogger(). +type KubeAPIWarningLoggerOptions struct { + // Deduplicate indicates a given warning message should only be written once. + // Setting this to true in a long-running process handling many warnings can + // result in increased memory use. + Deduplicate bool +} + +// KubeAPIWarningLogger is a wrapper around +// a provided logr.Logger that implements the +// rest.WarningHandler interface. +type KubeAPIWarningLogger struct { + // logger is used to log responses with the warning header + logger logr.Logger + // opts contain options controlling warning output + opts KubeAPIWarningLoggerOptions + // writtenLock gurads written + writtenLock sync.Mutex + // used to keep track of already logged messages + // and help in de-duplication. + written map[string]struct{} +} + +// HandleWarningHeader handles logging for responses from API server that are +// warnings with code being 299 and uses a logr.Logger for its logging purposes. +func (l *KubeAPIWarningLogger) HandleWarningHeader(code int, agent string, message string) { + if code != 299 || len(message) == 0 { + return + } + + if l.opts.Deduplicate { + l.writtenLock.Lock() + defer l.writtenLock.Unlock() + + if _, alreadyLogged := l.written[message]; alreadyLogged { + return + } + l.written[message] = struct{}{} + } + l.logger.Info(message) +} + +// NewKubeAPIWarningLogger returns an implementation of rest.WarningHandler that logs warnings +// with code = 299 to the provided logr.Logger. +func NewKubeAPIWarningLogger(l logr.Logger, opts KubeAPIWarningLoggerOptions) *KubeAPIWarningLogger { + h := &KubeAPIWarningLogger{logger: l, opts: opts} + if opts.Deduplicate { + h.written = map[string]struct{}{} + } + return h +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go new file mode 100644 index 00000000000..fb492b14da8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go @@ -0,0 +1,168 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package zap contains helpers for setting up a new logr.Logger instance +// using the Zap logging framework. +package zap + +import ( + "flag" + "fmt" + "strconv" + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var levelStrings = map[string]zapcore.Level{ + "debug": zap.DebugLevel, + "info": zap.InfoLevel, + "error": zap.ErrorLevel, +} + +var stackLevelStrings = map[string]zapcore.Level{ + "info": zap.InfoLevel, + "error": zap.ErrorLevel, + "panic": zap.PanicLevel, +} + +type encoderFlag struct { + setFunc func(NewEncoderFunc) + value string +} + +var _ flag.Value = &encoderFlag{} + +func (ev *encoderFlag) String() string { + return ev.value +} + +func (ev *encoderFlag) Type() string { + return "encoder" +} + +func (ev *encoderFlag) Set(flagValue string) error { + val := strings.ToLower(flagValue) + switch val { + case "json": + ev.setFunc(newJSONEncoder) + case "console": + ev.setFunc(newConsoleEncoder) + default: + return fmt.Errorf("invalid encoder value \"%s\"", flagValue) + } + ev.value = flagValue + return nil +} + +type levelFlag struct { + setFunc func(zapcore.LevelEnabler) + value string +} + +var _ flag.Value = &levelFlag{} + +func (ev *levelFlag) Set(flagValue string) error { + level, validLevel := levelStrings[strings.ToLower(flagValue)] + if !validLevel { + logLevel, err := strconv.Atoi(flagValue) + if err != nil { + return fmt.Errorf("invalid log level \"%s\"", flagValue) + } + if logLevel > 0 { + intLevel := -1 * logLevel + ev.setFunc(zap.NewAtomicLevelAt(zapcore.Level(int8(intLevel)))) + } else { + return fmt.Errorf("invalid log level \"%s\"", flagValue) + } + } else { + ev.setFunc(zap.NewAtomicLevelAt(level)) + } + ev.value = flagValue + return nil +} + +func (ev *levelFlag) String() string { + return ev.value +} + +func (ev *levelFlag) Type() string { + return "level" +} + +type stackTraceFlag struct { + setFunc func(zapcore.LevelEnabler) + value string +} + +var _ flag.Value = &stackTraceFlag{} + +func (ev *stackTraceFlag) Set(flagValue string) error { + level, validLevel := stackLevelStrings[strings.ToLower(flagValue)] + if !validLevel { + return fmt.Errorf("invalid stacktrace level \"%s\"", flagValue) + } + ev.setFunc(zap.NewAtomicLevelAt(level)) + ev.value = flagValue + return nil +} + +func (ev *stackTraceFlag) String() string { + return ev.value +} + +func (ev *stackTraceFlag) Type() string { + return "level" +} + +type timeEncodingFlag struct { + setFunc func(zapcore.TimeEncoder) + value string +} + +var _ flag.Value = &timeEncodingFlag{} + +func (ev *timeEncodingFlag) String() string { + return ev.value +} + +func (ev *timeEncodingFlag) Type() string { + return "time-encoding" +} + +func (ev *timeEncodingFlag) Set(flagValue string) error { + val := strings.ToLower(flagValue) + switch val { + case "rfc3339nano": + ev.setFunc(zapcore.RFC3339NanoTimeEncoder) + case "rfc3339": + ev.setFunc(zapcore.RFC3339TimeEncoder) + case "iso8601": + ev.setFunc(zapcore.ISO8601TimeEncoder) + case "millis": + ev.setFunc(zapcore.EpochMillisTimeEncoder) + case "nanos": + ev.setFunc(zapcore.EpochNanosTimeEncoder) + case "epoch": + ev.setFunc(zapcore.EpochTimeEncoder) + default: + return fmt.Errorf("invalid time-encoding value \"%s\"", flagValue) + } + + ev.value = flagValue + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go new file mode 100644 index 00000000000..3b4ebfdaa0b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go @@ -0,0 +1,111 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package zap + +import ( + "fmt" + "reflect" + + "go.uber.org/zap/buffer" + "go.uber.org/zap/zapcore" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" +) + +// KubeAwareEncoder is a Kubernetes-aware Zap Encoder. +// Instead of trying to force Kubernetes objects to implement +// ObjectMarshaller, we just implement a wrapper around a normal +// ObjectMarshaller that checks for Kubernetes objects. +type KubeAwareEncoder struct { + // Encoder is the zapcore.Encoder that this encoder delegates to + zapcore.Encoder + + // Verbose controls whether or not the full object is printed. + // If false, only name, namespace, api version, and kind are printed. + // Otherwise, the full object is logged. + Verbose bool +} + +// kubeObjectWrapper is a zapcore.ObjectMarshaler for Kubernetes objects. +type kubeObjectWrapper struct { + obj runtime.Object +} + +// MarshalLogObject implements zapcore.ObjectMarshaler. +func (w kubeObjectWrapper) MarshalLogObject(enc zapcore.ObjectEncoder) error { + // TODO(directxman12): log kind and apiversion if not set explicitly (common case) + // -- needs an a scheme to convert to the GVK. + + if reflect.ValueOf(w.obj).IsNil() { + return fmt.Errorf("got nil for runtime.Object") + } + + if gvk := w.obj.GetObjectKind().GroupVersionKind(); gvk.Version != "" { + enc.AddString("apiVersion", gvk.GroupVersion().String()) + enc.AddString("kind", gvk.Kind) + } + + objMeta, err := meta.Accessor(w.obj) + if err != nil { + return fmt.Errorf("got runtime.Object without object metadata: %v", w.obj) + } + + if ns := objMeta.GetNamespace(); ns != "" { + enc.AddString("namespace", ns) + } + enc.AddString("name", objMeta.GetName()) + + return nil +} + +// NB(directxman12): can't just override AddReflected, since the encoder calls AddReflected on itself directly + +// Clone implements zapcore.Encoder. +func (k *KubeAwareEncoder) Clone() zapcore.Encoder { + return &KubeAwareEncoder{ + Encoder: k.Encoder.Clone(), + } +} + +// EncodeEntry implements zapcore.Encoder. +func (k *KubeAwareEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { + if k.Verbose { + // Kubernetes objects implement fmt.Stringer, so if we + // want verbose output, just delegate to that. + return k.Encoder.EncodeEntry(entry, fields) + } + + for i, field := range fields { + // intercept stringer fields that happen to be Kubernetes runtime.Object or + // types.NamespacedName values (Kubernetes runtime.Objects commonly + // implement String, apparently). + // *unstructured.Unstructured does NOT implement fmt.Striger interface. + // We have handle it specially. + if field.Type == zapcore.StringerType || field.Type == zapcore.ReflectType { + switch val := field.Interface.(type) { + case runtime.Object: + fields[i] = zapcore.Field{ + Type: zapcore.ObjectMarshalerType, + Key: field.Key, + Interface: kubeObjectWrapper{obj: val}, + } + } + } + } + + return k.Encoder.EncodeEntry(entry, fields) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go new file mode 100644 index 00000000000..ee89a7c6a49 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go @@ -0,0 +1,311 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package zap contains helpers for setting up a new logr.Logger instance +// using the Zap logging framework. +package zap + +import ( + "flag" + "io" + "os" + "time" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// EncoderConfigOption is a function that can modify a `zapcore.EncoderConfig`. +type EncoderConfigOption func(*zapcore.EncoderConfig) + +// NewEncoderFunc is a function that creates an Encoder using the provided EncoderConfigOptions. +type NewEncoderFunc func(...EncoderConfigOption) zapcore.Encoder + +// New returns a brand new Logger configured with Opts. It +// uses KubeAwareEncoder which adds Type information and +// Namespace/Name to the log. +func New(opts ...Opts) logr.Logger { + return zapr.NewLogger(NewRaw(opts...)) +} + +// Opts allows to manipulate Options. +type Opts func(*Options) + +// UseDevMode sets the logger to use (or not use) development mode (more +// human-readable output, extra stack traces and logging information, etc). +// See Options.Development. +func UseDevMode(enabled bool) Opts { + return func(o *Options) { + o.Development = enabled + } +} + +// WriteTo configures the logger to write to the given io.Writer, instead of standard error. +// See Options.DestWriter. +func WriteTo(out io.Writer) Opts { + return func(o *Options) { + o.DestWriter = out + } +} + +// Encoder configures how the logger will encode the output e.g JSON or console. +// See Options.Encoder. +func Encoder(encoder zapcore.Encoder) func(o *Options) { + return func(o *Options) { + o.Encoder = encoder + } +} + +// JSONEncoder configures the logger to use a JSON Encoder. +func JSONEncoder(opts ...EncoderConfigOption) func(o *Options) { + return func(o *Options) { + o.Encoder = newJSONEncoder(opts...) + } +} + +func newJSONEncoder(opts ...EncoderConfigOption) zapcore.Encoder { + encoderConfig := zap.NewProductionEncoderConfig() + for _, opt := range opts { + opt(&encoderConfig) + } + return zapcore.NewJSONEncoder(encoderConfig) +} + +// ConsoleEncoder configures the logger to use a Console encoder. +func ConsoleEncoder(opts ...EncoderConfigOption) func(o *Options) { + return func(o *Options) { + o.Encoder = newConsoleEncoder(opts...) + } +} + +func newConsoleEncoder(opts ...EncoderConfigOption) zapcore.Encoder { + encoderConfig := zap.NewDevelopmentEncoderConfig() + for _, opt := range opts { + opt(&encoderConfig) + } + return zapcore.NewConsoleEncoder(encoderConfig) +} + +// Level sets Options.Level, which configures the minimum enabled logging level e.g Debug, Info. +// A zap log level should be multiplied by -1 to get the logr verbosity. +// For example, to get logr verbosity of 3, pass zapcore.Level(-3) to this Opts. +// See https://pkg.go.dev/github.com/go-logr/zapr for how zap level relates to logr verbosity. +func Level(level zapcore.LevelEnabler) func(o *Options) { + return func(o *Options) { + o.Level = level + } +} + +// StacktraceLevel sets Options.StacktraceLevel, which configures the logger to record a stack trace +// for all messages at or above a given level. +// See the Level Opts for the relationship of zap log level to logr verbosity. +func StacktraceLevel(stacktraceLevel zapcore.LevelEnabler) func(o *Options) { + return func(o *Options) { + o.StacktraceLevel = stacktraceLevel + } +} + +// RawZapOpts allows appending arbitrary zap.Options to configure the underlying zap logger. +// See Options.ZapOpts. +func RawZapOpts(zapOpts ...zap.Option) func(o *Options) { + return func(o *Options) { + o.ZapOpts = append(o.ZapOpts, zapOpts...) + } +} + +// Options contains all possible settings. +type Options struct { + // Development configures the logger to use a Zap development config + // (stacktraces on warnings, no sampling), otherwise a Zap production + // config will be used (stacktraces on errors, sampling). + Development bool + // Encoder configures how Zap will encode the output. Defaults to + // console when Development is true and JSON otherwise + Encoder zapcore.Encoder + // EncoderConfigOptions can modify the EncoderConfig needed to initialize an Encoder. + // See https://pkg.go.dev/go.uber.org/zap/zapcore#EncoderConfig for the list of options + // that can be configured. + // Note that the EncoderConfigOptions are not applied when the Encoder option is already set. + EncoderConfigOptions []EncoderConfigOption + // NewEncoder configures Encoder using the provided EncoderConfigOptions. + // Note that the NewEncoder function is not used when the Encoder option is already set. + NewEncoder NewEncoderFunc + // DestWriter controls the destination of the log output. Defaults to + // os.Stderr. + DestWriter io.Writer + // DestWritter controls the destination of the log output. Defaults to + // os.Stderr. + // + // Deprecated: Use DestWriter instead + DestWritter io.Writer + // Level configures the verbosity of the logging. + // Defaults to Debug when Development is true and Info otherwise. + // A zap log level should be multiplied by -1 to get the logr verbosity. + // For example, to get logr verbosity of 3, set this field to zapcore.Level(-3). + // See https://pkg.go.dev/github.com/go-logr/zapr for how zap level relates to logr verbosity. + Level zapcore.LevelEnabler + // StacktraceLevel is the level at and above which stacktraces will + // be recorded for all messages. Defaults to Warn when Development + // is true and Error otherwise. + // See Level for the relationship of zap log level to logr verbosity. + StacktraceLevel zapcore.LevelEnabler + // ZapOpts allows passing arbitrary zap.Options to configure on the + // underlying Zap logger. + ZapOpts []zap.Option + // TimeEncoder specifies the encoder for the timestamps in log messages. + // Defaults to RFC3339TimeEncoder. + TimeEncoder zapcore.TimeEncoder +} + +// addDefaults adds defaults to the Options. +func (o *Options) addDefaults() { + if o.DestWriter == nil && o.DestWritter == nil { + o.DestWriter = os.Stderr + } else if o.DestWriter == nil && o.DestWritter != nil { + // while misspelled DestWritter is deprecated but still not removed + o.DestWriter = o.DestWritter + } + + if o.Development { + if o.NewEncoder == nil { + o.NewEncoder = newConsoleEncoder + } + if o.Level == nil { + lvl := zap.NewAtomicLevelAt(zap.DebugLevel) + o.Level = &lvl + } + if o.StacktraceLevel == nil { + lvl := zap.NewAtomicLevelAt(zap.WarnLevel) + o.StacktraceLevel = &lvl + } + o.ZapOpts = append(o.ZapOpts, zap.Development()) + } else { + if o.NewEncoder == nil { + o.NewEncoder = newJSONEncoder + } + if o.Level == nil { + lvl := zap.NewAtomicLevelAt(zap.InfoLevel) + o.Level = &lvl + } + if o.StacktraceLevel == nil { + lvl := zap.NewAtomicLevelAt(zap.ErrorLevel) + o.StacktraceLevel = &lvl + } + // Disable sampling for increased Debug levels. Otherwise, this will + // cause index out of bounds errors in the sampling code. + if !o.Level.Enabled(zapcore.Level(-2)) { + o.ZapOpts = append(o.ZapOpts, + zap.WrapCore(func(core zapcore.Core) zapcore.Core { + return zapcore.NewSamplerWithOptions(core, time.Second, 100, 100) + })) + } + } + + if o.TimeEncoder == nil { + o.TimeEncoder = zapcore.RFC3339TimeEncoder + } + f := func(ecfg *zapcore.EncoderConfig) { + ecfg.EncodeTime = o.TimeEncoder + } + // prepend instead of append it in case someone adds a time encoder option in it + o.EncoderConfigOptions = append([]EncoderConfigOption{f}, o.EncoderConfigOptions...) + + if o.Encoder == nil { + o.Encoder = o.NewEncoder(o.EncoderConfigOptions...) + } + o.ZapOpts = append(o.ZapOpts, zap.AddStacktrace(o.StacktraceLevel)) +} + +// NewRaw returns a new zap.Logger configured with the passed Opts +// or their defaults. It uses KubeAwareEncoder which adds Type +// information and Namespace/Name to the log. +func NewRaw(opts ...Opts) *zap.Logger { + o := &Options{} + for _, opt := range opts { + opt(o) + } + o.addDefaults() + + // this basically mimics NewConfig, but with a custom sink + sink := zapcore.AddSync(o.DestWriter) + + o.ZapOpts = append(o.ZapOpts, zap.ErrorOutput(sink)) + log := zap.New(zapcore.NewCore(&KubeAwareEncoder{Encoder: o.Encoder, Verbose: o.Development}, sink, o.Level)) + log = log.WithOptions(o.ZapOpts...) + return log +} + +// BindFlags will parse the given flagset for zap option flags and set the log options accordingly: +// - zap-devel: +// Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn) +// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) +// - zap-encoder: Zap log encoding (one of 'json' or 'console') +// - zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', +// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity"). +// - zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'info', 'error' or 'panic') +// - zap-time-encoding: Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano'), +// Defaults to 'epoch'. +func (o *Options) BindFlags(fs *flag.FlagSet) { + // Set Development mode value + fs.BoolVar(&o.Development, "zap-devel", o.Development, + "Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+ + "Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)") + + // Set Encoder value + var encVal encoderFlag + encVal.setFunc = func(fromFlag NewEncoderFunc) { + o.NewEncoder = fromFlag + } + fs.Var(&encVal, "zap-encoder", "Zap log encoding (one of 'json' or 'console')") + + // Set the Log Level + var levelVal levelFlag + levelVal.setFunc = func(fromFlag zapcore.LevelEnabler) { + o.Level = fromFlag + } + fs.Var(&levelVal, "zap-log-level", + "Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', "+ + "or any integer value > 0 which corresponds to custom debug levels of increasing verbosity") + + // Set the StrackTrace Level + var stackVal stackTraceFlag + stackVal.setFunc = func(fromFlag zapcore.LevelEnabler) { + o.StacktraceLevel = fromFlag + } + fs.Var(&stackVal, "zap-stacktrace-level", + "Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic').") + + // Set the time encoding + var timeEncoderVal timeEncodingFlag + timeEncoderVal.setFunc = func(fromFlag zapcore.TimeEncoder) { + o.TimeEncoder = fromFlag + } + fs.Var(&timeEncoderVal, "zap-time-encoding", "Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano'). Defaults to 'epoch'.") +} + +// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI. +// +// opts := zap.Options{} +// opts.BindFlags(flag.CommandLine) +// flag.Parse() +// log := zap.New(zap.UseFlagOptions(&opts)) +func UseFlagOptions(in *Options) Opts { + return func(o *Options) { + *o = *in + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_suite_test.go new file mode 100644 index 00000000000..d7a7f228664 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package zap + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Zap Log Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_test.go new file mode 100644 index 00000000000..f7fad41f061 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/log/zap/zap_test.go @@ -0,0 +1,591 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package zap + +import ( + "bytes" + "encoding/json" + "flag" + "os" + "reflect" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "go.uber.org/zap/zapcore" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" +) + +// testStringer is a fmt.Stringer. +type testStringer struct{} + +func (testStringer) String() string { + return "value" +} + +// fakeSyncWriter is a fake zap.SyncerWriter that lets us test if sync was called. +type fakeSyncWriter bool + +func (w *fakeSyncWriter) Write(p []byte) (int, error) { + return len(p), nil +} + +func (w *fakeSyncWriter) Sync() error { + *w = true + return nil +} + +// logInfo is the information for a particular fakeLogger message. +type logInfo struct { + name []string + tags []interface{} + msg string +} + +// fakeLoggerRoot is the root object to which all fakeLoggers record their messages. +type fakeLoggerRoot struct { + messages []logInfo +} + +var _ logr.LogSink = &fakeLogger{} + +// fakeLogger is a fake implementation of logr.Logger that records +// messages, tags, and names, +// just records the name. +type fakeLogger struct { + name []string + tags []interface{} + + root *fakeLoggerRoot +} + +func (f *fakeLogger) Init(info logr.RuntimeInfo) { +} + +func (f *fakeLogger) WithName(name string) logr.LogSink { + names := append([]string(nil), f.name...) + names = append(names, name) + return &fakeLogger{ + name: names, + tags: f.tags, + root: f.root, + } +} + +func (f *fakeLogger) WithValues(vals ...interface{}) logr.LogSink { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, vals...) + return &fakeLogger{ + name: f.name, + tags: tags, + root: f.root, + } +} + +func (f *fakeLogger) Error(err error, msg string, vals ...interface{}) { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, "error", err) + tags = append(tags, vals...) + f.root.messages = append(f.root.messages, logInfo{ + name: append([]string(nil), f.name...), + tags: tags, + msg: msg, + }) +} + +func (f *fakeLogger) Info(level int, msg string, vals ...interface{}) { + tags := append([]interface{}(nil), f.tags...) + tags = append(tags, vals...) + f.root.messages = append(f.root.messages, logInfo{ + name: append([]string(nil), f.name...), + tags: tags, + msg: msg, + }) +} + +func (f *fakeLogger) Enabled(level int) bool { return true } +func (f *fakeLogger) V(lvl int) logr.LogSink { return f } + +var _ = Describe("Zap options setup", func() { + var opts *Options + + BeforeEach(func() { + opts = &Options{} + }) + + It("should enable development mode", func() { + UseDevMode(true)(opts) + Expect(opts.Development).To(BeTrue()) + }) + + It("should disable development mode", func() { + UseDevMode(false)(opts) + Expect(opts.Development).To(BeFalse()) + }) + + It("should set a custom writer", func() { + var w fakeSyncWriter + WriteTo(&w)(opts) + Expect(opts.DestWriter).To(Equal(&w)) + }) +}) + +var _ = Describe("Zap logger setup", func() { + Context("when logging kubernetes objects", func() { + var logOut *bytes.Buffer + var logger logr.Logger + + defineTests := func() { + It("should log a standard namespaced Kubernetes object name and namespace", func() { + pod := &corev1.Pod{} + pod.Name = "some-pod" + pod.Namespace = "some-ns" + logger.Info("here's a kubernetes object", "thing", pod) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": pod.Name, + "namespace": pod.Namespace, + })) + }) + + It("should work fine with normal stringers", func() { + logger.Info("here's a non-kubernetes stringer", "thing", testStringer{}) + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", "value")) + }) + + It("should log a standard non-namespaced Kubernetes object name", func() { + node := &corev1.Node{} + node.Name = "some-node" + logger.Info("here's a kubernetes object", "thing", node) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": node.Name, + })) + }) + + It("should log a standard Kubernetes object's kind, if set", func() { + node := &corev1.Node{} + node.Name = "some-node" + node.APIVersion = "v1" + node.Kind = "Node" + logger.Info("here's a kubernetes object", "thing", node) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": node.Name, + "apiVersion": "v1", + "kind": "Node", + })) + }) + + It("should log a standard non-namespaced NamespacedName name", func() { + name := types.NamespacedName{Name: "some-node"} + logger.Info("here's a kubernetes object", "thing", name) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": name.Name, + })) + }) + + It("should log an unstructured Kubernetes object", func() { + pod := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": "some-pod", + "namespace": "some-ns", + }, + }, + } + logger.Info("here's a kubernetes object", "thing", pod) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": "some-pod", + "namespace": "some-ns", + })) + }) + + It("should log a standard namespaced NamespacedName name and namespace", func() { + name := types.NamespacedName{Name: "some-pod", Namespace: "some-ns"} + logger.Info("here's a kubernetes object", "thing", name) + + outRaw := logOut.Bytes() + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + + Expect(res).To(HaveKeyWithValue("thing", map[string]interface{}{ + "name": name.Name, + "namespace": name.Namespace, + })) + }) + + It("should not panic with nil obj", func() { + var pod *corev1.Pod + logger.Info("here's a kubernetes object", "thing", pod) + + outRaw := logOut.Bytes() + Expect(string(outRaw)).Should(ContainSubstring("got nil for runtime.Object")) + }) + } + + Context("with logger created using New", func() { + BeforeEach(func() { + logOut = new(bytes.Buffer) + By("setting up the logger") + // use production settings (false) to get just json output + logger = New(WriteTo(logOut), UseDevMode(false)) + }) + defineTests() + }) + }) +}) + +var _ = Describe("Zap log level flag options setup", func() { + var ( + fromFlags Options + fs flag.FlagSet + logInfoLevel0 = "info text" + logDebugLevel1 = "debug 1 text" + logDebugLevel2 = "debug 2 text" + logDebugLevel3 = "debug 3 text" + ) + + BeforeEach(func() { + fromFlags = Options{} + fs = *flag.NewFlagSet(os.Args[0], flag.ExitOnError) + }) + + Context("with zap-log-level options provided", func() { + It("Should output logs for info and debug zap-log-level.", func() { + args := []string{"--zap-log-level=debug"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + + outRaw := logOut.Bytes() + + Expect(string(outRaw)).Should(ContainSubstring(logInfoLevel0)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel1)) + }) + + It("Should output only error logs, otherwise empty logs", func() { + args := []string{"--zap-log-level=error"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + + outRaw := logOut.Bytes() + + Expect(outRaw).To(BeEmpty()) + }) + }) + + Context("with zap-log-level with increased verbosity.", func() { + It("Should output debug and info log, with default production mode.", func() { + args := []string{"--zap-log-level=1"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + + outRaw := logOut.Bytes() + + Expect(string(outRaw)).Should(ContainSubstring(logInfoLevel0)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel1)) + }) + + It("Should output info and debug logs, with development mode.", func() { + args := []string{"--zap-log-level=1", "--zap-devel=true"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + + outRaw := logOut.Bytes() + + Expect(string(outRaw)).Should(ContainSubstring(logInfoLevel0)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel1)) + }) + + It("Should output info, and debug logs with increased verbosity, and with development mode set to true.", func() { + args := []string{"--zap-log-level=3", "--zap-devel=false"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + logger.V(2).Info(logDebugLevel2) + logger.V(3).Info(logDebugLevel3) + + outRaw := logOut.Bytes() + + Expect(string(outRaw)).Should(ContainSubstring(logInfoLevel0)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel1)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel2)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel3)) + }) + It("Should output info, and debug logs with increased verbosity, and with production mode set to true.", func() { + args := []string{"--zap-log-level=3", "--zap-devel=true"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.V(0).Info(logInfoLevel0) + logger.V(1).Info(logDebugLevel1) + logger.V(2).Info(logDebugLevel2) + logger.V(3).Info(logDebugLevel3) + + outRaw := logOut.Bytes() + + Expect(string(outRaw)).Should(ContainSubstring(logInfoLevel0)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel1)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel2)) + Expect(string(outRaw)).Should(ContainSubstring(logDebugLevel3)) + }) + }) + + Context("with zap-stacktrace-level options provided", func() { + It("Should output stacktrace at info level, with development mode set to true.", func() { + args := []string{"--zap-stacktrace-level=info", "--zap-devel=true"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + out := Options{} + UseFlagOptions(&fromFlags)(&out) + + Expect(out.StacktraceLevel.Enabled(zapcore.InfoLevel)).To(BeTrue()) + }) + + It("Should output stacktrace at error level, with development mode set to true.", func() { + args := []string{"--zap-stacktrace-level=error", "--zap-devel=true"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + out := Options{} + UseFlagOptions(&fromFlags)(&out) + + Expect(out.StacktraceLevel.Enabled(zapcore.ErrorLevel)).To(BeTrue()) + }) + + It("Should output stacktrace at panic level, with development mode set to true.", func() { + args := []string{"--zap-stacktrace-level=panic", "--zap-devel=true"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + out := Options{} + UseFlagOptions(&fromFlags)(&out) + + Expect(out.StacktraceLevel.Enabled(zapcore.PanicLevel)).To(BeTrue()) + Expect(out.StacktraceLevel.Enabled(zapcore.ErrorLevel)).To(BeFalse()) + Expect(out.StacktraceLevel.Enabled(zapcore.InfoLevel)).To(BeFalse()) + }) + }) + + Context("with only -zap-devel flag provided", func() { + It("Should set dev=true.", func() { + args := []string{"--zap-devel=true"} + fromFlags.BindFlags(&fs) + if err := fs.Parse(args); err != nil { + Expect(err).ToNot(HaveOccurred()) + } + out := Options{} + UseFlagOptions(&fromFlags)(&out) + + Expect(out.Development).To(BeTrue()) + Expect(out.Encoder).To(BeNil()) + Expect(out.Level).To(BeNil()) + Expect(out.StacktraceLevel).To(BeNil()) + Expect(out.EncoderConfigOptions).To(BeNil()) + }) + It("Should set dev=false", func() { + args := []string{"--zap-devel=false"} + fromFlags.BindFlags(&fs) + if err := fs.Parse(args); err != nil { + Expect(err).ToNot(HaveOccurred()) + } + out := Options{} + UseFlagOptions(&fromFlags)(&out) + + Expect(out.Development).To(BeFalse()) + Expect(out.Encoder).To(BeNil()) + Expect(out.Level).To(BeNil()) + Expect(out.StacktraceLevel).To(BeNil()) + Expect(out.EncoderConfigOptions).To(BeNil()) + }) + }) + + Context("with zap-time-encoding flag provided", func() { + It("Should set time encoder in options", func() { + args := []string{"--zap-time-encoding=rfc3339"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + + opt := Options{} + UseFlagOptions(&fromFlags)(&opt) + opt.addDefaults() + + optVal := reflect.ValueOf(opt.TimeEncoder) + expVal := reflect.ValueOf(zapcore.RFC3339TimeEncoder) + + Expect(optVal.Pointer()).To(Equal(expVal.Pointer())) + }) + + It("Should default to 'rfc3339' time encoding", func() { + args := []string{""} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + + opt := Options{} + UseFlagOptions(&fromFlags)(&opt) + opt.addDefaults() + + optVal := reflect.ValueOf(opt.TimeEncoder) + expVal := reflect.ValueOf(zapcore.RFC3339TimeEncoder) + + Expect(optVal.Pointer()).To(Equal(expVal.Pointer())) + }) + + It("Should return an error message, with unknown time-encoding", func() { + fs = *flag.NewFlagSet(os.Args[0], flag.ContinueOnError) + args := []string{"--zap-time-encoding=foobar"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).To(HaveOccurred()) + }) + + It("Should propagate time encoder to logger", func() { + // zaps ISO8601TimeEncoder uses 2006-01-02T15:04:05.000Z0700 as pattern for iso8601 encoding + iso8601Pattern := `^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}([-+][0-9]{4}|Z)` + + args := []string{"--zap-time-encoding=iso8601"} + fromFlags.BindFlags(&fs) + err := fs.Parse(args) + Expect(err).ToNot(HaveOccurred()) + logOut := new(bytes.Buffer) + + logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut)) + logger.Info("This is a test message") + + outRaw := logOut.Bytes() + + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + Expect(res["ts"]).Should(MatchRegexp(iso8601Pattern)) + }) + }) + + Context("with encoder options provided programmatically", func() { + It("Should set JSON Encoder, with given Millis TimeEncoder option, and MessageKey", func() { + logOut := new(bytes.Buffer) + f := func(ec *zapcore.EncoderConfig) { + ec.MessageKey = "MillisTimeFormat" + } + opts := func(o *Options) { + o.EncoderConfigOptions = append(o.EncoderConfigOptions, f) + } + log := New(UseDevMode(false), WriteTo(logOut), opts) + log.Info("This is a test message") + outRaw := logOut.Bytes() + // Assert for JSON Encoder + res := map[string]interface{}{} + Expect(json.Unmarshal(outRaw, &res)).To(Succeed()) + // Assert for MessageKey + Expect(string(outRaw)).Should(ContainSubstring("MillisTimeFormat")) + }) + + Context("using Level()", func() { + var logOut *bytes.Buffer + + BeforeEach(func() { + logOut = new(bytes.Buffer) + }) + + It("logs with negative logr level", func() { + By("setting up the logger") + logger := New(WriteTo(logOut), Level(zapcore.Level(-3))) + logger.V(3).Info("test 3") // Should be logged + Expect(logOut.String()).To(ContainSubstring(`"msg":"test 3"`)) + logOut.Truncate(0) + logger.V(1).Info("test 1") // Should be logged + Expect(logOut.String()).To(ContainSubstring(`"msg":"test 1"`)) + logOut.Truncate(0) + logger.V(4).Info("test 4") // Should not be logged + Expect(logOut.String()).To(BeEmpty()) + logger.V(-3).Info("test -3") + Expect(logOut.String()).To(ContainSubstring("test -3")) + }) + It("does not log with positive logr level", func() { + By("setting up the logger") + logger := New(WriteTo(logOut), Level(zapcore.Level(1))) + logger.V(1).Info("test 1") + Expect(logOut.String()).To(BeEmpty()) + logger.V(3).Info("test 3") + Expect(logOut.String()).To(BeEmpty()) + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/doc.go new file mode 100644 index 00000000000..f2976c7f754 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes, +etc. Controllers must be started by calling Manager.Start. +*/ +package manager diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/example_test.go new file mode 100644 index 00000000000..06712d71715 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/example_test.go @@ -0,0 +1,133 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager_test + +import ( + "context" + "os" + + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client/config" + conf "sigs.k8s.io/controller-runtime/pkg/config" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" +) + +var ( + mgr manager.Manager + // NB: don't call SetLogger in init(), or else you'll mess up logging in the main suite. + log = logf.Log.WithName("manager-examples") +) + +// This example creates a new Manager that can be used with controller.New to create Controllers. +func ExampleNew() { + cfg, err := config.GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + + mgr, err := manager.New(cfg, manager.Options{}) + if err != nil { + log.Error(err, "unable to set up manager") + os.Exit(1) + } + log.Info("created manager", "manager", mgr) +} + +// This example creates a new Manager that has a cache scoped to a list of namespaces. +func ExampleNew_limitToNamespaces() { + cfg, err := config.GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + + mgr, err := manager.New(cfg, manager.Options{ + NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) { + opts.Namespaces = []string{"namespace1", "namespace2"} + return cache.New(config, opts) + }}, + ) + if err != nil { + log.Error(err, "unable to set up manager") + os.Exit(1) + } + log.Info("created manager", "manager", mgr) +} + +// This example adds a Runnable for the Manager to Start. +func ExampleManager_add() { + err := mgr.Add(manager.RunnableFunc(func(context.Context) error { + // Do something + return nil + })) + if err != nil { + log.Error(err, "unable add a runnable to the manager") + os.Exit(1) + } +} + +// This example starts a Manager that has had Runnables added. +func ExampleManager_start() { + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "unable start the manager") + os.Exit(1) + } +} + +// This example will populate Options from a custom config file +// using defaults. +func ExampleOptions_andFrom() { + opts := manager.Options{} + if _, err := opts.AndFrom(conf.File()); err != nil { + log.Error(err, "unable to load config") + os.Exit(1) + } + + cfg, err := config.GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + + mgr, err := manager.New(cfg, opts) + if err != nil { + log.Error(err, "unable to set up manager") + os.Exit(1) + } + log.Info("created manager", "manager", mgr) +} + +// This example will populate Options from a custom config file +// using defaults and will panic if there are errors. +func ExampleOptions_andFromOrDie() { + cfg, err := config.GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + + mgr, err := manager.New(cfg, manager.Options{}.AndFromOrDie(conf.File())) + if err != nil { + log.Error(err, "unable to set up manager") + os.Exit(1) + } + log.Info("created manager", "manager", mgr) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/internal.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/internal.go new file mode 100644 index 00000000000..f298229e570 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/internal.go @@ -0,0 +1,667 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "net/http/pprof" + "sync" + "sync/atomic" + "time" + + "github.com/go-logr/logr" + "github.com/prometheus/client_golang/prometheus/promhttp" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" + "sigs.k8s.io/controller-runtime/pkg/metrics" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +const ( + // Values taken from: https://github.com/kubernetes/component-base/blob/master/config/v1alpha1/defaults.go + defaultLeaseDuration = 15 * time.Second + defaultRenewDeadline = 10 * time.Second + defaultRetryPeriod = 2 * time.Second + defaultGracefulShutdownPeriod = 30 * time.Second + + defaultReadinessEndpoint = "/readyz" + defaultLivenessEndpoint = "/healthz" + defaultMetricsEndpoint = "/metrics" +) + +var _ Runnable = &controllerManager{} + +type controllerManager struct { + sync.Mutex + started bool + + stopProcedureEngaged *int64 + errChan chan error + runnables *runnables + + // cluster holds a variety of methods to interact with a cluster. Required. + cluster cluster.Cluster + + // recorderProvider is used to generate event recorders that will be injected into Controllers + // (and EventHandlers, Sources and Predicates). + recorderProvider *intrec.Provider + + // resourceLock forms the basis for leader election + resourceLock resourcelock.Interface + + // leaderElectionReleaseOnCancel defines if the manager should step back from the leader lease + // on shutdown + leaderElectionReleaseOnCancel bool + + // metricsListener is used to serve prometheus metrics + metricsListener net.Listener + + // metricsExtraHandlers contains extra handlers to register on http server that serves metrics. + metricsExtraHandlers map[string]http.Handler + + // healthProbeListener is used to serve liveness probe + healthProbeListener net.Listener + + // Readiness probe endpoint name + readinessEndpointName string + + // Liveness probe endpoint name + livenessEndpointName string + + // Readyz probe handler + readyzHandler *healthz.Handler + + // Healthz probe handler + healthzHandler *healthz.Handler + + // pprofListener is used to serve pprof + pprofListener net.Listener + + // controllerConfig are the global controller options. + controllerConfig config.Controller + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + logger logr.Logger + + // leaderElectionStopped is an internal channel used to signal the stopping procedure that the + // LeaderElection.Run(...) function has returned and the shutdown can proceed. + leaderElectionStopped chan struct{} + + // leaderElectionCancel is used to cancel the leader election. It is distinct from internalStopper, + // because for safety reasons we need to os.Exit() when we lose the leader election, meaning that + // it must be deferred until after gracefulShutdown is done. + leaderElectionCancel context.CancelFunc + + // elected is closed when this manager becomes the leader of a group of + // managers, either because it won a leader election or because no leader + // election was configured. + elected chan struct{} + + webhookServer webhook.Server + // webhookServerOnce will be called in GetWebhookServer() to optionally initialize + // webhookServer if unset, and Add() it to controllerManager. + webhookServerOnce sync.Once + + // leaderElectionID is the name of the resource that leader election + // will use for holding the leader lock. + leaderElectionID string + // leaseDuration is the duration that non-leader candidates will + // wait to force acquire leadership. + leaseDuration time.Duration + // renewDeadline is the duration that the acting controlplane will retry + // refreshing leadership before giving up. + renewDeadline time.Duration + // retryPeriod is the duration the LeaderElector clients should wait + // between tries of actions. + retryPeriod time.Duration + + // gracefulShutdownTimeout is the duration given to runnable to stop + // before the manager actually returns on stop. + gracefulShutdownTimeout time.Duration + + // onStoppedLeading is callled when the leader election lease is lost. + // It can be overridden for tests. + onStoppedLeading func() + + // shutdownCtx is the context that can be used during shutdown. It will be cancelled + // after the gracefulShutdownTimeout ended. It must not be accessed before internalStop + // is closed because it will be nil. + shutdownCtx context.Context + + internalCtx context.Context + internalCancel context.CancelFunc + + // internalProceduresStop channel is used internally to the manager when coordinating + // the proper shutdown of servers. This channel is also used for dependency injection. + internalProceduresStop chan struct{} +} + +type hasCache interface { + Runnable + GetCache() cache.Cache +} + +// Add sets dependencies on i, and adds it to the list of Runnables to start. +func (cm *controllerManager) Add(r Runnable) error { + cm.Lock() + defer cm.Unlock() + return cm.add(r) +} + +func (cm *controllerManager) add(r Runnable) error { + return cm.runnables.Add(r) +} + +// AddMetricsExtraHandler adds extra handler served on path to the http server that serves metrics. +func (cm *controllerManager) AddMetricsExtraHandler(path string, handler http.Handler) error { + cm.Lock() + defer cm.Unlock() + + if cm.started { + return fmt.Errorf("unable to add new metrics handler because metrics endpoint has already been created") + } + + if path == defaultMetricsEndpoint { + return fmt.Errorf("overriding builtin %s endpoint is not allowed", defaultMetricsEndpoint) + } + + if _, found := cm.metricsExtraHandlers[path]; found { + return fmt.Errorf("can't register extra handler by duplicate path %q on metrics http server", path) + } + + cm.metricsExtraHandlers[path] = handler + cm.logger.V(2).Info("Registering metrics http server extra handler", "path", path) + return nil +} + +// AddHealthzCheck allows you to add Healthz checker. +func (cm *controllerManager) AddHealthzCheck(name string, check healthz.Checker) error { + cm.Lock() + defer cm.Unlock() + + if cm.started { + return fmt.Errorf("unable to add new checker because healthz endpoint has already been created") + } + + if cm.healthzHandler == nil { + cm.healthzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}} + } + + cm.healthzHandler.Checks[name] = check + return nil +} + +// AddReadyzCheck allows you to add Readyz checker. +func (cm *controllerManager) AddReadyzCheck(name string, check healthz.Checker) error { + cm.Lock() + defer cm.Unlock() + + if cm.started { + return fmt.Errorf("unable to add new checker because healthz endpoint has already been created") + } + + if cm.readyzHandler == nil { + cm.readyzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}} + } + + cm.readyzHandler.Checks[name] = check + return nil +} + +func (cm *controllerManager) GetHTTPClient() *http.Client { + return cm.cluster.GetHTTPClient() +} + +func (cm *controllerManager) GetConfig() *rest.Config { + return cm.cluster.GetConfig() +} + +func (cm *controllerManager) GetClient() client.Client { + return cm.cluster.GetClient() +} + +func (cm *controllerManager) GetScheme() *runtime.Scheme { + return cm.cluster.GetScheme() +} + +func (cm *controllerManager) GetFieldIndexer() client.FieldIndexer { + return cm.cluster.GetFieldIndexer() +} + +func (cm *controllerManager) GetCache() cache.Cache { + return cm.cluster.GetCache() +} + +func (cm *controllerManager) GetEventRecorderFor(name string) record.EventRecorder { + return cm.cluster.GetEventRecorderFor(name) +} + +func (cm *controllerManager) GetRESTMapper() meta.RESTMapper { + return cm.cluster.GetRESTMapper() +} + +func (cm *controllerManager) GetAPIReader() client.Reader { + return cm.cluster.GetAPIReader() +} + +func (cm *controllerManager) GetWebhookServer() webhook.Server { + cm.webhookServerOnce.Do(func() { + if cm.webhookServer == nil { + panic("webhook should not be nil") + } + if err := cm.Add(cm.webhookServer); err != nil { + panic(fmt.Sprintf("unable to add webhook server to the controller manager: %s", err)) + } + }) + return cm.webhookServer +} + +func (cm *controllerManager) GetLogger() logr.Logger { + return cm.logger +} + +func (cm *controllerManager) GetControllerOptions() config.Controller { + return cm.controllerConfig +} + +func (cm *controllerManager) addMetricsServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + + handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{ + ErrorHandling: promhttp.HTTPErrorOnError, + }) + // TODO(JoelSpeed): Use existing Kubernetes machinery for serving metrics + mux.Handle(defaultMetricsEndpoint, handler) + for path, extraHandler := range cm.metricsExtraHandlers { + mux.Handle(path, extraHandler) + } + + return cm.add(&server{ + Kind: "metrics", + Log: cm.logger.WithValues("path", defaultMetricsEndpoint), + Server: srv, + Listener: cm.metricsListener, + }) +} + +func (cm *controllerManager) serveHealthProbes() { + mux := http.NewServeMux() + server := httpserver.New(mux) + + if cm.readyzHandler != nil { + mux.Handle(cm.readinessEndpointName, http.StripPrefix(cm.readinessEndpointName, cm.readyzHandler)) + // Append '/' suffix to handle subpaths + mux.Handle(cm.readinessEndpointName+"/", http.StripPrefix(cm.readinessEndpointName, cm.readyzHandler)) + } + if cm.healthzHandler != nil { + mux.Handle(cm.livenessEndpointName, http.StripPrefix(cm.livenessEndpointName, cm.healthzHandler)) + // Append '/' suffix to handle subpaths + mux.Handle(cm.livenessEndpointName+"/", http.StripPrefix(cm.livenessEndpointName, cm.healthzHandler)) + } + + go cm.httpServe("health probe", cm.logger, server, cm.healthProbeListener) +} + +func (cm *controllerManager) addPprofServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + + return cm.add(&server{ + Kind: "pprof", + Log: cm.logger, + Server: srv, + Listener: cm.pprofListener, + }) +} + +func (cm *controllerManager) httpServe(kind string, log logr.Logger, server *http.Server, ln net.Listener) { + log = log.WithValues("kind", kind, "addr", ln.Addr()) + + go func() { + log.Info("Starting server") + if err := server.Serve(ln); err != nil { + if errors.Is(err, http.ErrServerClosed) { + return + } + if atomic.LoadInt64(cm.stopProcedureEngaged) > 0 { + // There might be cases where connections are still open and we try to shutdown + // but not having enough time to close the connection causes an error in Serve + // + // In that case we want to avoid returning an error to the main error channel. + log.Error(err, "error on Serve after stop has been engaged") + return + } + cm.errChan <- err + } + }() + + // Shutdown the server when stop is closed. + <-cm.internalProceduresStop + if err := server.Shutdown(cm.shutdownCtx); err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + // Avoid logging context related errors. + return + } + if atomic.LoadInt64(cm.stopProcedureEngaged) > 0 { + cm.logger.Error(err, "error on Shutdown after stop has been engaged") + return + } + cm.errChan <- err + } +} + +// Start starts the manager and waits indefinitely. +// There is only two ways to have start return: +// An error has occurred during in one of the internal operations, +// such as leader election, cache start, webhooks, and so on. +// Or, the context is cancelled. +func (cm *controllerManager) Start(ctx context.Context) (err error) { + cm.Lock() + if cm.started { + cm.Unlock() + return errors.New("manager already started") + } + cm.started = true + + var ready bool + defer func() { + // Only unlock the manager if we haven't reached + // the internal readiness condition. + if !ready { + cm.Unlock() + } + }() + + // Initialize the internal context. + cm.internalCtx, cm.internalCancel = context.WithCancel(ctx) + + // This chan indicates that stop is complete, in other words all runnables have returned or timeout on stop request + stopComplete := make(chan struct{}) + defer close(stopComplete) + // This must be deferred after closing stopComplete, otherwise we deadlock. + defer func() { + // https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/gettyimages-459889618-1533579787.jpg + stopErr := cm.engageStopProcedure(stopComplete) + if stopErr != nil { + if err != nil { + // Utilerrors.Aggregate allows to use errors.Is for all contained errors + // whereas fmt.Errorf allows wrapping at most one error which means the + // other one can not be found anymore. + err = kerrors.NewAggregate([]error{err, stopErr}) + } else { + err = stopErr + } + } + }() + + // Add the cluster runnable. + if err := cm.add(cm.cluster); err != nil { + return fmt.Errorf("failed to add cluster to runnables: %w", err) + } + + // Metrics should be served whether the controller is leader or not. + // (If we don't serve metrics for non-leaders, prometheus will still scrape + // the pod but will get a connection refused). + if cm.metricsListener != nil { + if err := cm.addMetricsServer(); err != nil { + return fmt.Errorf("failed to add metrics server: %w", err) + } + } + + // Serve health probes. + if cm.healthProbeListener != nil { + cm.serveHealthProbes() + } + + // Add pprof server + if cm.pprofListener != nil { + if err := cm.addPprofServer(); err != nil { + return fmt.Errorf("failed to add pprof server: %w", err) + } + } + + // First start any webhook servers, which includes conversion, validation, and defaulting + // webhooks that are registered. + // + // WARNING: Webhooks MUST start before any cache is populated, otherwise there is a race condition + // between conversion webhooks and the cache sync (usually initial list) which causes the webhooks + // to never start because no cache can be populated. + if err := cm.runnables.Webhooks.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start webhooks: %w", err) + } + } + + // Start and wait for caches. + if err := cm.runnables.Caches.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start caches: %w", err) + } + } + + // Start the non-leaderelection Runnables after the cache has synced. + if err := cm.runnables.Others.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start other runnables: %w", err) + } + } + + // Start the leader election and all required runnables. + { + ctx, cancel := context.WithCancel(context.Background()) + cm.leaderElectionCancel = cancel + go func() { + if cm.resourceLock != nil { + if err := cm.startLeaderElection(ctx); err != nil { + cm.errChan <- err + } + } else { + // Treat not having leader election enabled the same as being elected. + if err := cm.startLeaderElectionRunnables(); err != nil { + cm.errChan <- err + } + close(cm.elected) + } + }() + } + + ready = true + cm.Unlock() + select { + case <-ctx.Done(): + // We are done + return nil + case err := <-cm.errChan: + // Error starting or running a runnable + return err + } +} + +// engageStopProcedure signals all runnables to stop, reads potential errors +// from the errChan and waits for them to end. It must not be called more than once. +func (cm *controllerManager) engageStopProcedure(stopComplete <-chan struct{}) error { + if !atomic.CompareAndSwapInt64(cm.stopProcedureEngaged, 0, 1) { + return errors.New("stop procedure already engaged") + } + + // Populate the shutdown context, this operation MUST be done before + // closing the internalProceduresStop channel. + // + // The shutdown context immediately expires if the gracefulShutdownTimeout is not set. + var shutdownCancel context.CancelFunc + if cm.gracefulShutdownTimeout < 0 { + // We want to wait forever for the runnables to stop. + cm.shutdownCtx, shutdownCancel = context.WithCancel(context.Background()) + } else { + cm.shutdownCtx, shutdownCancel = context.WithTimeout(context.Background(), cm.gracefulShutdownTimeout) + } + defer shutdownCancel() + + // Start draining the errors before acquiring the lock to make sure we don't deadlock + // if something that has the lock is blocked on trying to write into the unbuffered + // channel after something else already wrote into it. + var closeOnce sync.Once + go func() { + for { + // Closing in the for loop is required to avoid race conditions between + // the closure of all internal procedures and making sure to have a reader off the error channel. + closeOnce.Do(func() { + // Cancel the internal stop channel and wait for the procedures to stop and complete. + close(cm.internalProceduresStop) + cm.internalCancel() + }) + select { + case err, ok := <-cm.errChan: + if ok { + cm.logger.Error(err, "error received after stop sequence was engaged") + } + case <-stopComplete: + return + } + } + }() + + // We want to close this after the other runnables stop, because we don't + // want things like leader election to try and emit events on a closed + // channel + defer cm.recorderProvider.Stop(cm.shutdownCtx) + defer func() { + // Cancel leader election only after we waited. It will os.Exit() the app for safety. + if cm.resourceLock != nil { + // After asking the context to be cancelled, make sure + // we wait for the leader stopped channel to be closed, otherwise + // we might encounter race conditions between this code + // and the event recorder, which is used within leader election code. + cm.leaderElectionCancel() + <-cm.leaderElectionStopped + } + }() + + go func() { + // First stop the non-leader election runnables. + cm.logger.Info("Stopping and waiting for non leader election runnables") + cm.runnables.Others.StopAndWait(cm.shutdownCtx) + + // Stop all the leader election runnables, which includes reconcilers. + cm.logger.Info("Stopping and waiting for leader election runnables") + cm.runnables.LeaderElection.StopAndWait(cm.shutdownCtx) + + // Stop the caches before the leader election runnables, this is an important + // step to make sure that we don't race with the reconcilers by receiving more events + // from the API servers and enqueueing them. + cm.logger.Info("Stopping and waiting for caches") + cm.runnables.Caches.StopAndWait(cm.shutdownCtx) + + // Webhooks should come last, as they might be still serving some requests. + cm.logger.Info("Stopping and waiting for webhooks") + cm.runnables.Webhooks.StopAndWait(cm.shutdownCtx) + + // Proceed to close the manager and overall shutdown context. + cm.logger.Info("Wait completed, proceeding to shutdown the manager") + shutdownCancel() + }() + + <-cm.shutdownCtx.Done() + if err := cm.shutdownCtx.Err(); err != nil && !errors.Is(err, context.Canceled) { + if errors.Is(err, context.DeadlineExceeded) { + if cm.gracefulShutdownTimeout > 0 { + return fmt.Errorf("failed waiting for all runnables to end within grace period of %s: %w", cm.gracefulShutdownTimeout, err) + } + return nil + } + // For any other error, return the error. + return err + } + + return nil +} + +func (cm *controllerManager) startLeaderElectionRunnables() error { + return cm.runnables.LeaderElection.Start(cm.internalCtx) +} + +func (cm *controllerManager) startLeaderElection(ctx context.Context) (err error) { + l, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{ + Lock: cm.resourceLock, + LeaseDuration: cm.leaseDuration, + RenewDeadline: cm.renewDeadline, + RetryPeriod: cm.retryPeriod, + Callbacks: leaderelection.LeaderCallbacks{ + OnStartedLeading: func(_ context.Context) { + if err := cm.startLeaderElectionRunnables(); err != nil { + cm.errChan <- err + return + } + close(cm.elected) + }, + OnStoppedLeading: func() { + if cm.onStoppedLeading != nil { + cm.onStoppedLeading() + } + // Make sure graceful shutdown is skipped if we lost the leader lock without + // intending to. + cm.gracefulShutdownTimeout = time.Duration(0) + // Most implementations of leader election log.Fatal() here. + // Since Start is wrapped in log.Fatal when called, we can just return + // an error here which will cause the program to exit. + cm.errChan <- errors.New("leader election lost") + }, + }, + ReleaseOnCancel: cm.leaderElectionReleaseOnCancel, + Name: cm.leaderElectionID, + }) + if err != nil { + return err + } + + // Start the leader elector process + go func() { + l.Run(ctx) + <-ctx.Done() + close(cm.leaderElectionStopped) + }() + return nil +} + +func (cm *controllerManager) Elected() <-chan struct{} { + return cm.elected +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager.go new file mode 100644 index 00000000000..7e65ef0c3ac --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager.go @@ -0,0 +1,746 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "reflect" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + "k8s.io/utils/pointer" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/healthz" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" + "sigs.k8s.io/controller-runtime/pkg/leaderelection" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/metrics" + "sigs.k8s.io/controller-runtime/pkg/recorder" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables. +// A Manager is required to create Controllers. +type Manager interface { + // Cluster holds a variety of methods to interact with a cluster. + cluster.Cluster + + // Add will set requested dependencies on the component, and cause the component to be + // started when Start is called. + // Depending on if a Runnable implements LeaderElectionRunnable interface, a Runnable can be run in either + // non-leaderelection mode (always running) or leader election mode (managed by leader election if enabled). + Add(Runnable) error + + // Elected is closed when this manager is elected leader of a group of + // managers, either because it won a leader election or because no leader + // election was configured. + Elected() <-chan struct{} + + // AddMetricsExtraHandler adds an extra handler served on path to the http server that serves metrics. + // Might be useful to register some diagnostic endpoints e.g. pprof. Note that these endpoints meant to be + // sensitive and shouldn't be exposed publicly. + // If the simple path -> handler mapping offered here is not enough, a new http server/listener should be added as + // Runnable to the manager via Add method. + AddMetricsExtraHandler(path string, handler http.Handler) error + + // AddHealthzCheck allows you to add Healthz checker + AddHealthzCheck(name string, check healthz.Checker) error + + // AddReadyzCheck allows you to add Readyz checker + AddReadyzCheck(name string, check healthz.Checker) error + + // Start starts all registered Controllers and blocks until the context is cancelled. + // Returns an error if there is an error starting any controller. + // + // If LeaderElection is used, the binary must be exited immediately after this returns, + // otherwise components that need leader election might continue to run after the leader + // lock was lost. + Start(ctx context.Context) error + + // GetWebhookServer returns a webhook.Server + GetWebhookServer() webhook.Server + + // GetLogger returns this manager's logger. + GetLogger() logr.Logger + + // GetControllerOptions returns controller global configuration options. + GetControllerOptions() config.Controller +} + +// Options are the arguments for creating a new Manager. +type Options struct { + // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources. + // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better + // to pass your own scheme in. See the documentation in pkg/scheme for more information. + // + // If set, the Scheme will be used to create the default Client and Cache. + Scheme *runtime.Scheme + + // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs. + // + // If set, the RESTMapper returned by this function is used to create the RESTMapper + // used by the Client and Cache. + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + + // NewCache is the function that will create the cache to be used + // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. + NewCache cache.NewCacheFunc + + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + + // NewClient is the func that creates the client to be used by the manager. + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc + + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // + // This applies to all controllers. + // + // A period sync happens for two reasons: + // 1. To insure against a bug in the controller that causes an object to not + // be requeued, when it otherwise should be requeued. + // 2. To insure against an unknown bug in controller-runtime, or its dependencies, + // that causes an object to not be requeued, when it otherwise should be + // requeued, or to be removed from the queue, when it otherwise should not + // be removed. + // + // If you want + // 1. to insure against missed watch events, or + // 2. to poll services that cannot be watched, + // then we recommend that, instead of changing the default period, the + // controller requeue, with a constant duration `t`, whenever the controller + // is "done" with an object, and would otherwise not requeue it, i.e., we + // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, + // instead of `reconcile.Result{}`. + // + // Deprecated: Use Cache.SyncPeriod instead. + SyncPeriod *time.Duration + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + + // LeaderElection determines whether or not to use leader election when + // starting the manager. + LeaderElection bool + + // LeaderElectionResourceLock determines which resource lock to use for leader election, + // defaults to "leases". Change this value only if you know what you are doing. + // + // If you are using `configmaps`/`endpoints` resource lock and want to migrate to "leases", + // you might do so by migrating to the respective multilock first ("configmapsleases" or "endpointsleases"), + // which will acquire a leader lock on both resources. + // After all your users have migrated to the multilock, you can go ahead and migrate to "leases". + // Please also keep in mind, that users might skip versions of your controller. + // + // Note: before controller-runtime version v0.7, it was set to "configmaps". + // And from v0.7 to v0.11, the default was "configmapsleases", which was + // used to migrate from configmaps to leases. + // Since the default was "configmapsleases" for over a year, spanning five minor releases, + // any actively maintained operators are very likely to have a released version that uses + // "configmapsleases". Therefore defaulting to "leases" should be safe since v0.12. + // + // So, what do you have to do when you are updating your controller-runtime dependency + // from a lower version to v0.12 or newer? + // - If your operator matches at least one of these conditions: + // - the LeaderElectionResourceLock in your operator has already been explicitly set to "leases" + // - the old controller-runtime version is between v0.7.0 and v0.11.x and the + // LeaderElectionResourceLock wasn't set or was set to "leases"/"configmapsleases"/"endpointsleases" + // feel free to update controller-runtime to v0.12 or newer. + // - Otherwise, you may have to take these steps: + // 1. update controller-runtime to v0.12 or newer in your go.mod + // 2. set LeaderElectionResourceLock to "configmapsleases" (or "endpointsleases") + // 3. package your operator and upgrade it in all your clusters + // 4. only if you have finished 3, you can remove the LeaderElectionResourceLock to use the default "leases" + // Otherwise, your operator might end up with multiple running instances that + // each acquired leadership through different resource locks during upgrades and thus + // act on the same resources concurrently. + LeaderElectionResourceLock string + + // LeaderElectionNamespace determines the namespace in which the leader + // election resource will be created. + LeaderElectionNamespace string + + // LeaderElectionID determines the name of the resource that leader election + // will use for holding the leader lock. + LeaderElectionID string + + // LeaderElectionConfig can be specified to override the default configuration + // that is used to build the leader election client. + LeaderElectionConfig *rest.Config + + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader doesn't have to wait + // LeaseDuration time first. + LeaderElectionReleaseOnCancel bool + + // LeaderElectionResourceLockInterface allows to provide a custom resourcelock.Interface that was created outside + // of the controller-runtime. If this value is set the options LeaderElectionID, LeaderElectionNamespace, + // LeaderElectionResourceLock, LeaseDuration, RenewDeadline and RetryPeriod will be ignored. This can be useful if you + // want to use a locking mechanism that is currently not supported, like a MultiLock across two Kubernetes clusters. + LeaderElectionResourceLockInterface resourcelock.Interface + + // LeaseDuration is the duration that non-leader candidates will + // wait to force acquire leadership. This is measured against time of + // last observed ack. Default is 15 seconds. + LeaseDuration *time.Duration + // RenewDeadline is the duration that the acting controlplane will retry + // refreshing leadership before giving up. Default is 10 seconds. + RenewDeadline *time.Duration + // RetryPeriod is the duration the LeaderElector clients should wait + // between tries of actions. Default is 2 seconds. + RetryPeriod *time.Duration + + // Namespace, if specified, restricts the manager's cache to watch objects in + // the desired namespace. Defaults to all namespaces. + // + // Note: If a namespace is specified, controllers can still Watch for a + // cluster-scoped resource (e.g Node). For namespaced resources, the cache + // will only hold objects from the desired namespace. + // + // Deprecated: Use Cache.Namespaces instead. + Namespace string + + // MetricsBindAddress is the TCP address that the controller should bind to + // for serving prometheus metrics. + // It can be set to "0" to disable the metrics serving. + MetricsBindAddress string + + // HealthProbeBindAddress is the TCP address that the controller should bind to + // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. + HealthProbeBindAddress string + + // Readiness probe endpoint name, defaults to "readyz" + ReadinessEndpointName string + + // Liveness probe endpoint name, defaults to "healthz" + LivenessEndpointName string + + // PprofBindAddress is the TCP address that the controller should bind to + // for serving pprof. + // It can be set to "" or "0" to disable the pprof serving. + // Since pprof may contain sensitive information, make sure to protect it + // before exposing it to public. + PprofBindAddress string + + // Port is the port that the webhook server serves at. + // It is used to set webhook.Server.Port if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. + Port int + // Host is the hostname that the webhook server binds to. + // It is used to set webhook.Server.Host if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. + Host string + + // CertDir is the directory that contains the server key and certificate. + // If not set, webhook server would look up the server key and certificate in + // {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate + // must be named tls.key and tls.crt, respectively. + // It is used to set webhook.Server.CertDir if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. + CertDir string + + // TLSOpts is used to allow configuring the TLS config used for the webhook server. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. + TLSOpts []func(*tls.Config) + + // WebhookServer is an externally configured webhook.Server. By default, + // a Manager will create a default server using Port, Host, and CertDir; + // if this is set, the Manager will use this server instead. + WebhookServer webhook.Server + + // BaseContext is the function that provides Context values to Runnables + // managed by the Manager. If a BaseContext function isn't provided, Runnables + // will receive a new Background Context instead. + BaseContext BaseContextFunc + + // ClientDisableCacheFor tells the client that, if any cache is used, to bypass it + // for the given objects. + // + // Deprecated: Use Client.Cache.DisableCacheFor instead. + ClientDisableCacheFor []client.Object + + // DryRunClient specifies whether the client should be configured to enforce + // dryRun mode. + // + // Deprecated: Use Client.DryRun instead. + DryRunClient bool + + // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API + // Use this to customize the event correlator and spam filter + // + // Deprecated: using this may cause goroutine leaks if the lifetime of your manager or controllers + // is shorter than the lifetime of your process. + EventBroadcaster record.EventBroadcaster + + // GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop. + // To disable graceful shutdown, set to time.Duration(0) + // To use graceful shutdown without timeout, set to a negative duration, e.G. time.Duration(-1) + // The graceful shutdown is skipped for safety reasons in case the leader election lease is lost. + GracefulShutdownTimeout *time.Duration + + // Controller contains global configuration options for controllers + // registered within this manager. + // +optional + Controller config.Controller + + // makeBroadcaster allows deferring the creation of the broadcaster to + // avoid leaking goroutines if we never call Start on this manager. It also + // returns whether or not this is a "owned" broadcaster, and as such should be + // stopped with the manager. + makeBroadcaster intrec.EventBroadcasterProducer + + // Dependency injection for testing + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) + newResourceLock func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) + newMetricsListener func(addr string) (net.Listener, error) + newHealthProbeListener func(addr string) (net.Listener, error) + newPprofListener func(addr string) (net.Listener, error) +} + +// BaseContextFunc is a function used to provide a base Context to Runnables +// managed by a Manager. +type BaseContextFunc func() context.Context + +// Runnable allows a component to be started. +// It's very important that Start blocks until +// it's done running. +type Runnable interface { + // Start starts running the component. The component will stop running + // when the context is closed. Start blocks until the context is closed or + // an error occurs. + Start(context.Context) error +} + +// RunnableFunc implements Runnable using a function. +// It's very important that the given function block +// until it's done running. +type RunnableFunc func(context.Context) error + +// Start implements Runnable. +func (r RunnableFunc) Start(ctx context.Context) error { + return r(ctx) +} + +// LeaderElectionRunnable knows if a Runnable needs to be run in the leader election mode. +type LeaderElectionRunnable interface { + // NeedLeaderElection returns true if the Runnable needs to be run in the leader election mode. + // e.g. controllers need to be run in leader election mode, while webhook server doesn't. + NeedLeaderElection() bool +} + +// New returns a new Manager for creating Controllers. +func New(config *rest.Config, options Options) (Manager, error) { + // Set default values for options fields + options = setOptionsDefaults(options) + + cluster, err := cluster.New(config, func(clusterOptions *cluster.Options) { + clusterOptions.Scheme = options.Scheme + clusterOptions.MapperProvider = options.MapperProvider + clusterOptions.Logger = options.Logger + clusterOptions.SyncPeriod = options.SyncPeriod + clusterOptions.NewCache = options.NewCache + clusterOptions.NewClient = options.NewClient + clusterOptions.Cache = options.Cache + clusterOptions.Client = options.Client + clusterOptions.Namespace = options.Namespace //nolint:staticcheck + clusterOptions.ClientDisableCacheFor = options.ClientDisableCacheFor //nolint:staticcheck + clusterOptions.DryRunClient = options.DryRunClient //nolint:staticcheck + clusterOptions.EventBroadcaster = options.EventBroadcaster //nolint:staticcheck + }) + if err != nil { + return nil, err + } + + // Create the recorder provider to inject event recorders for the components. + // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific + // to the particular controller that it's being injected into, rather than a generic one like is here. + recorderProvider, err := options.newRecorderProvider(config, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + + // Create the resource lock to enable leader election) + var leaderConfig *rest.Config + var leaderRecorderProvider *intrec.Provider + + if options.LeaderElectionConfig == nil { + leaderConfig = rest.CopyConfig(config) + leaderRecorderProvider = recorderProvider + } else { + leaderConfig = rest.CopyConfig(options.LeaderElectionConfig) + leaderRecorderProvider, err = options.newRecorderProvider(leaderConfig, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + } + + var resourceLock resourcelock.Interface + if options.LeaderElectionResourceLockInterface != nil && options.LeaderElection { + resourceLock = options.LeaderElectionResourceLockInterface + } else { + resourceLock, err = options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{ + LeaderElection: options.LeaderElection, + LeaderElectionResourceLock: options.LeaderElectionResourceLock, + LeaderElectionID: options.LeaderElectionID, + LeaderElectionNamespace: options.LeaderElectionNamespace, + }) + if err != nil { + return nil, err + } + } + + // Create the metrics listener. This will throw an error if the metrics bind + // address is invalid or already in use. + metricsListener, err := options.newMetricsListener(options.MetricsBindAddress) + if err != nil { + return nil, err + } + + // By default we have no extra endpoints to expose on metrics http server. + metricsExtraHandlers := make(map[string]http.Handler) + + // Create health probes listener. This will throw an error if the bind + // address is invalid or already in use. + healthProbeListener, err := options.newHealthProbeListener(options.HealthProbeBindAddress) + if err != nil { + return nil, err + } + + // Create pprof listener. This will throw an error if the bind + // address is invalid or already in use. + pprofListener, err := options.newPprofListener(options.PprofBindAddress) + if err != nil { + return nil, fmt.Errorf("failed to new pprof listener: %w", err) + } + + errChan := make(chan error) + runnables := newRunnables(options.BaseContext, errChan) + + return &controllerManager{ + stopProcedureEngaged: pointer.Int64(0), + cluster: cluster, + runnables: runnables, + errChan: errChan, + recorderProvider: recorderProvider, + resourceLock: resourceLock, + metricsListener: metricsListener, + metricsExtraHandlers: metricsExtraHandlers, + controllerConfig: options.Controller, + logger: options.Logger, + elected: make(chan struct{}), + webhookServer: options.WebhookServer, + leaderElectionID: options.LeaderElectionID, + leaseDuration: *options.LeaseDuration, + renewDeadline: *options.RenewDeadline, + retryPeriod: *options.RetryPeriod, + healthProbeListener: healthProbeListener, + readinessEndpointName: options.ReadinessEndpointName, + livenessEndpointName: options.LivenessEndpointName, + pprofListener: pprofListener, + gracefulShutdownTimeout: *options.GracefulShutdownTimeout, + internalProceduresStop: make(chan struct{}), + leaderElectionStopped: make(chan struct{}), + leaderElectionReleaseOnCancel: options.LeaderElectionReleaseOnCancel, + }, nil +} + +// AndFrom will use a supplied type and convert to Options +// any options already set on Options will be ignored, this is used to allow +// cli flags to override anything specified in the config file. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. +func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, error) { + newObj, err := loader.Complete() + if err != nil { + return o, err + } + + o = o.setLeaderElectionConfig(newObj) + + if o.SyncPeriod == nil && newObj.SyncPeriod != nil { + o.SyncPeriod = &newObj.SyncPeriod.Duration + } + + if o.Namespace == "" && newObj.CacheNamespace != "" { + o.Namespace = newObj.CacheNamespace + } + + if o.MetricsBindAddress == "" && newObj.Metrics.BindAddress != "" { + o.MetricsBindAddress = newObj.Metrics.BindAddress + } + + if o.HealthProbeBindAddress == "" && newObj.Health.HealthProbeBindAddress != "" { + o.HealthProbeBindAddress = newObj.Health.HealthProbeBindAddress + } + + if o.ReadinessEndpointName == "" && newObj.Health.ReadinessEndpointName != "" { + o.ReadinessEndpointName = newObj.Health.ReadinessEndpointName + } + + if o.LivenessEndpointName == "" && newObj.Health.LivenessEndpointName != "" { + o.LivenessEndpointName = newObj.Health.LivenessEndpointName + } + + if o.Port == 0 && newObj.Webhook.Port != nil { + o.Port = *newObj.Webhook.Port + } + if o.Host == "" && newObj.Webhook.Host != "" { + o.Host = newObj.Webhook.Host + } + if o.CertDir == "" && newObj.Webhook.CertDir != "" { + o.CertDir = newObj.Webhook.CertDir + } + if o.WebhookServer == nil { + o.WebhookServer = webhook.NewServer(webhook.Options{ + Port: o.Port, + Host: o.Host, + CertDir: o.CertDir, + }) + } + + if newObj.Controller != nil { + if o.Controller.CacheSyncTimeout == 0 && newObj.Controller.CacheSyncTimeout != nil { + o.Controller.CacheSyncTimeout = *newObj.Controller.CacheSyncTimeout + } + + if len(o.Controller.GroupKindConcurrency) == 0 && len(newObj.Controller.GroupKindConcurrency) > 0 { + o.Controller.GroupKindConcurrency = newObj.Controller.GroupKindConcurrency + } + } + + return o, nil +} + +// AndFromOrDie will use options.AndFrom() and will panic if there are errors. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. +func (o Options) AndFromOrDie(loader config.ControllerManagerConfiguration) Options { + o, err := o.AndFrom(loader) + if err != nil { + panic(fmt.Sprintf("could not parse config file: %v", err)) + } + return o +} + +func (o Options) setLeaderElectionConfig(obj v1alpha1.ControllerManagerConfigurationSpec) Options { + if obj.LeaderElection == nil { + // The source does not have any configuration; noop + return o + } + + if !o.LeaderElection && obj.LeaderElection.LeaderElect != nil { + o.LeaderElection = *obj.LeaderElection.LeaderElect + } + + if o.LeaderElectionResourceLock == "" && obj.LeaderElection.ResourceLock != "" { + o.LeaderElectionResourceLock = obj.LeaderElection.ResourceLock + } + + if o.LeaderElectionNamespace == "" && obj.LeaderElection.ResourceNamespace != "" { + o.LeaderElectionNamespace = obj.LeaderElection.ResourceNamespace + } + + if o.LeaderElectionID == "" && obj.LeaderElection.ResourceName != "" { + o.LeaderElectionID = obj.LeaderElection.ResourceName + } + + if o.LeaseDuration == nil && !reflect.DeepEqual(obj.LeaderElection.LeaseDuration, metav1.Duration{}) { + o.LeaseDuration = &obj.LeaderElection.LeaseDuration.Duration + } + + if o.RenewDeadline == nil && !reflect.DeepEqual(obj.LeaderElection.RenewDeadline, metav1.Duration{}) { + o.RenewDeadline = &obj.LeaderElection.RenewDeadline.Duration + } + + if o.RetryPeriod == nil && !reflect.DeepEqual(obj.LeaderElection.RetryPeriod, metav1.Duration{}) { + o.RetryPeriod = &obj.LeaderElection.RetryPeriod.Duration + } + + return o +} + +// defaultHealthProbeListener creates the default health probes listener bound to the given address. +func defaultHealthProbeListener(addr string) (net.Listener, error) { + if addr == "" || addr == "0" { + return nil, nil + } + + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("error listening on %s: %w", addr, err) + } + return ln, nil +} + +// defaultPprofListener creates the default pprof listener bound to the given address. +func defaultPprofListener(addr string) (net.Listener, error) { + if addr == "" || addr == "0" { + return nil, nil + } + + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("error listening on %s: %w", addr, err) + } + return ln, nil +} + +// defaultBaseContext is used as the BaseContext value in Options if one +// has not already been set. +func defaultBaseContext() context.Context { + return context.Background() +} + +// setOptionsDefaults set default values for Options fields. +func setOptionsDefaults(options Options) Options { + // Allow newResourceLock to be mocked + if options.newResourceLock == nil { + options.newResourceLock = leaderelection.NewResourceLock + } + + // Allow newRecorderProvider to be mocked + if options.newRecorderProvider == nil { + options.newRecorderProvider = intrec.NewProvider + } + + // This is duplicated with pkg/cluster, we need it here + // for the leader election and there to provide the user with + // an EventBroadcaster + if options.EventBroadcaster == nil { + // defer initialization to avoid leaking by default + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return record.NewBroadcaster(), true + } + } else { + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return options.EventBroadcaster, false + } + } + + if options.newMetricsListener == nil { + options.newMetricsListener = metrics.NewListener + } + leaseDuration, renewDeadline, retryPeriod := defaultLeaseDuration, defaultRenewDeadline, defaultRetryPeriod + if options.LeaseDuration == nil { + options.LeaseDuration = &leaseDuration + } + + if options.RenewDeadline == nil { + options.RenewDeadline = &renewDeadline + } + + if options.RetryPeriod == nil { + options.RetryPeriod = &retryPeriod + } + + if options.ReadinessEndpointName == "" { + options.ReadinessEndpointName = defaultReadinessEndpoint + } + + if options.LivenessEndpointName == "" { + options.LivenessEndpointName = defaultLivenessEndpoint + } + + if options.newHealthProbeListener == nil { + options.newHealthProbeListener = defaultHealthProbeListener + } + + if options.newPprofListener == nil { + options.newPprofListener = defaultPprofListener + } + + if options.GracefulShutdownTimeout == nil { + gracefulShutdownTimeout := defaultGracefulShutdownPeriod + options.GracefulShutdownTimeout = &gracefulShutdownTimeout + } + + if options.Logger.GetSink() == nil { + options.Logger = log.Log + } + + if options.BaseContext == nil { + options.BaseContext = defaultBaseContext + } + + if options.WebhookServer == nil { + options.WebhookServer = webhook.NewServer(webhook.Options{ + Host: options.Host, + Port: options.Port, + CertDir: options.CertDir, + TLSOpts: options.TLSOpts, + }) + } + + return options +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_options_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_options_test.go new file mode 100644 index 00000000000..3718bedcbe9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_options_test.go @@ -0,0 +1,54 @@ +package manager + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/controller-runtime/pkg/config" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" +) + +var _ = Describe("manager.Options", func() { + Describe("AndFrom", func() { + Describe("reading custom type using OfKind", func() { + var ( + o Options + c customConfig + err error + ) + + JustBeforeEach(func() { + s := runtime.NewScheme() + o = Options{Scheme: s} + c = customConfig{} + + _, err = o.AndFrom(config.File().AtPath("./testdata/custom-config.yaml").OfKind(&c)) + }) + + It("should not panic or fail", func() { + Expect(err).To(Succeed()) + }) + It("should set custom properties", func() { + Expect(c.CustomValue).To(Equal("foo")) + }) + }) + }) +}) + +type customConfig struct { + metav1.TypeMeta `json:",inline"` + configv1alpha1.ControllerManagerConfigurationSpec `json:",inline"` + CustomValue string `json:"customValue"` +} + +func (in *customConfig) DeepCopyObject() runtime.Object { + out := &customConfig{} + *out = *in + + in.ControllerManagerConfigurationSpec.DeepCopyInto(&out.ControllerManagerConfigurationSpec) + + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_suite_test.go new file mode 100644 index 00000000000..ab514ef1e95 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_suite_test.go @@ -0,0 +1,80 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "fmt" + "net/http" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Manager Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config +var clientset *kubernetes.Clientset + +// clientTransport is used to force-close keep-alives in tests that check for leaks. +var clientTransport *http.Transport + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { + // NB(directxman12): we can't set Transport *and* use TLS options, + // so we grab the transport right after it gets created so that we can + // type-assert on it (hopefully)? + // hopefully this doesn't break 🤞 + transport, isTransport := rt.(*http.Transport) + if !isTransport { + panic(fmt.Sprintf("wasn't able to grab underlying transport from REST client's RoundTripper, can't figure out how to close keep-alives: expected an *http.Transport, got %#v", rt)) + } + clientTransport = transport + return rt + } + + clientset, err = kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred()) + + // Prevent the metrics listener being created + metrics.DefaultBindAddress = "0" +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) + + // Put the DefaultBindAddress back + metrics.DefaultBindAddress = ":8080" +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_test.go new file mode 100644 index 00000000000..1a7c257c259 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/manager_test.go @@ -0,0 +1,1864 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "io" + "net" + "net/http" + "path" + "reflect" + "sync" + "sync/atomic" + "time" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/goleak" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + + configv1alpha1 "k8s.io/component-base/config/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/cache/informertest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" + "sigs.k8s.io/controller-runtime/pkg/leaderelection" + fakeleaderelection "sigs.k8s.io/controller-runtime/pkg/leaderelection/fake" + "sigs.k8s.io/controller-runtime/pkg/metrics" + "sigs.k8s.io/controller-runtime/pkg/recorder" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var _ = Describe("manger.Manager", func() { + Describe("New", func() { + It("should return an error if there is no Config", func() { + m, err := New(nil, Options{}) + Expect(m).To(BeNil()) + Expect(err.Error()).To(ContainSubstring("must specify Config")) + + }) + + It("should return an error if it can't create a RestMapper", func() { + expected := fmt.Errorf("expected error: RestMapper") + m, err := New(cfg, Options{ + MapperProvider: func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { return nil, expected }, + }) + Expect(m).To(BeNil()) + Expect(err).To(Equal(expected)) + + }) + + It("should return an error it can't create a client.Client", func() { + m, err := New(cfg, Options{ + NewClient: func(config *rest.Config, options client.Options) (client.Client, error) { + return nil, errors.New("expected error") + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + It("should return an error it can't create a cache.Cache", func() { + m, err := New(cfg, Options{ + NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) { + return nil, fmt.Errorf("expected error") + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + It("should create a client defined in by the new client function", func() { + m, err := New(cfg, Options{ + NewClient: func(config *rest.Config, options client.Options) (client.Client, error) { + return nil, nil + }, + }) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + Expect(m.GetClient()).To(BeNil()) + }) + + It("should return an error it can't create a recorder.Provider", func() { + m, err := New(cfg, Options{ + newRecorderProvider: func(_ *rest.Config, _ *http.Client, _ *runtime.Scheme, _ logr.Logger, _ intrec.EventBroadcasterProducer) (*intrec.Provider, error) { + return nil, fmt.Errorf("expected error") + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("expected error")) + }) + + It("should be able to load Options from cfg.ControllerManagerConfiguration type", func() { + duration := metav1.Duration{Duration: 48 * time.Hour} + port := int(6090) + leaderElect := false + + ccfg := &v1alpha1.ControllerManagerConfiguration{ + ControllerManagerConfigurationSpec: v1alpha1.ControllerManagerConfigurationSpec{ + SyncPeriod: &duration, + LeaderElection: &configv1alpha1.LeaderElectionConfiguration{ + LeaderElect: &leaderElect, + ResourceLock: "leases", + ResourceNamespace: "default", + ResourceName: "ctrl-lease", + LeaseDuration: duration, + RenewDeadline: duration, + RetryPeriod: duration, + }, + CacheNamespace: "default", + Metrics: v1alpha1.ControllerMetrics{ + BindAddress: ":6000", + }, + Health: v1alpha1.ControllerHealth{ + HealthProbeBindAddress: "6060", + ReadinessEndpointName: "/readyz", + LivenessEndpointName: "/livez", + }, + Webhook: v1alpha1.ControllerWebhook{ + Port: &port, + Host: "localhost", + CertDir: "/certs", + }, + }, + } + + m, err := Options{}.AndFrom(&fakeDeferredLoader{ccfg}) + Expect(err).To(BeNil()) + + Expect(*m.SyncPeriod).To(Equal(duration.Duration)) + Expect(m.LeaderElection).To(Equal(leaderElect)) + Expect(m.LeaderElectionResourceLock).To(Equal("leases")) + Expect(m.LeaderElectionNamespace).To(Equal("default")) + Expect(m.LeaderElectionID).To(Equal("ctrl-lease")) + Expect(m.LeaseDuration.String()).To(Equal(duration.Duration.String())) + Expect(m.RenewDeadline.String()).To(Equal(duration.Duration.String())) + Expect(m.RetryPeriod.String()).To(Equal(duration.Duration.String())) + Expect(m.Namespace).To(Equal("default")) + Expect(m.MetricsBindAddress).To(Equal(":6000")) + Expect(m.HealthProbeBindAddress).To(Equal("6060")) + Expect(m.ReadinessEndpointName).To(Equal("/readyz")) + Expect(m.LivenessEndpointName).To(Equal("/livez")) + Expect(m.Port).To(Equal(port)) + Expect(m.Host).To(Equal("localhost")) + Expect(m.CertDir).To(Equal("/certs")) + }) + + It("should be able to keep Options when cfg.ControllerManagerConfiguration set", func() { + optDuration := time.Duration(2) + duration := metav1.Duration{Duration: 48 * time.Hour} + port := int(6090) + leaderElect := false + + ccfg := &v1alpha1.ControllerManagerConfiguration{ + ControllerManagerConfigurationSpec: v1alpha1.ControllerManagerConfigurationSpec{ + SyncPeriod: &duration, + LeaderElection: &configv1alpha1.LeaderElectionConfiguration{ + LeaderElect: &leaderElect, + ResourceLock: "leases", + ResourceNamespace: "default", + ResourceName: "ctrl-lease", + LeaseDuration: duration, + RenewDeadline: duration, + RetryPeriod: duration, + }, + CacheNamespace: "default", + Metrics: v1alpha1.ControllerMetrics{ + BindAddress: ":6000", + }, + Health: v1alpha1.ControllerHealth{ + HealthProbeBindAddress: "6060", + ReadinessEndpointName: "/readyz", + LivenessEndpointName: "/livez", + }, + Webhook: v1alpha1.ControllerWebhook{ + Port: &port, + Host: "localhost", + CertDir: "/certs", + }, + }, + } + + optionsTlSOptsFuncs := []func(*tls.Config){ + func(config *tls.Config) {}, + } + m, err := Options{ + SyncPeriod: &optDuration, + LeaderElection: true, + LeaderElectionResourceLock: "configmaps", + LeaderElectionNamespace: "ctrl", + LeaderElectionID: "ctrl-configmap", + LeaseDuration: &optDuration, + RenewDeadline: &optDuration, + RetryPeriod: &optDuration, + Namespace: "ctrl", + MetricsBindAddress: ":7000", + HealthProbeBindAddress: "5000", + ReadinessEndpointName: "/readiness", + LivenessEndpointName: "/liveness", + WebhookServer: webhook.NewServer(webhook.Options{ + Port: 8080, + Host: "example.com", + CertDir: "/pki", + TLSOpts: optionsTlSOptsFuncs, + }), + }.AndFrom(&fakeDeferredLoader{ccfg}) + Expect(err).To(BeNil()) + + Expect(m.SyncPeriod.String()).To(Equal(optDuration.String())) + Expect(m.LeaderElection).To(Equal(true)) + Expect(m.LeaderElectionResourceLock).To(Equal("configmaps")) + Expect(m.LeaderElectionNamespace).To(Equal("ctrl")) + Expect(m.LeaderElectionID).To(Equal("ctrl-configmap")) + Expect(m.LeaseDuration.String()).To(Equal(optDuration.String())) + Expect(m.RenewDeadline.String()).To(Equal(optDuration.String())) + Expect(m.RetryPeriod.String()).To(Equal(optDuration.String())) + Expect(m.Namespace).To(Equal("ctrl")) + Expect(m.MetricsBindAddress).To(Equal(":7000")) + Expect(m.HealthProbeBindAddress).To(Equal("5000")) + Expect(m.ReadinessEndpointName).To(Equal("/readiness")) + Expect(m.LivenessEndpointName).To(Equal("/liveness")) + Expect(m.WebhookServer.(*webhook.DefaultServer).Options.Port).To(Equal(8080)) + Expect(m.WebhookServer.(*webhook.DefaultServer).Options.Host).To(Equal("example.com")) + Expect(m.WebhookServer.(*webhook.DefaultServer).Options.CertDir).To(Equal("/pki")) + Expect(m.WebhookServer.(*webhook.DefaultServer).Options.TLSOpts).To(Equal(optionsTlSOptsFuncs)) + }) + + It("should lazily initialize a webhook server if needed", func() { + By("creating a manager with options") + m, err := New(cfg, Options{WebhookServer: webhook.NewServer(webhook.Options{Port: 9440, Host: "foo.com"})}) + Expect(err).NotTo(HaveOccurred()) + Expect(m).NotTo(BeNil()) + + By("checking options are passed to the webhook server") + svr := m.GetWebhookServer() + Expect(svr).NotTo(BeNil()) + Expect(svr.(*webhook.DefaultServer).Options.Port).To(Equal(9440)) + Expect(svr.(*webhook.DefaultServer).Options.Host).To(Equal("foo.com")) + }) + + It("should lazily initialize a webhook server if needed (deprecated)", func() { + By("creating a manager with options") + m, err := New(cfg, Options{Port: 9440, Host: "foo.com"}) + Expect(err).NotTo(HaveOccurred()) + Expect(m).NotTo(BeNil()) + + By("checking options are passed to the webhook server") + svr := m.GetWebhookServer() + Expect(svr).NotTo(BeNil()) + Expect(svr.(*webhook.DefaultServer).Options.Port).To(Equal(9440)) + Expect(svr.(*webhook.DefaultServer).Options.Host).To(Equal("foo.com")) + }) + + It("should not initialize a webhook server if Options.WebhookServer is set", func() { + By("creating a manager with options") + srv := webhook.NewServer(webhook.Options{Port: 9440}) + m, err := New(cfg, Options{Port: 9441, WebhookServer: srv}) + Expect(err).NotTo(HaveOccurred()) + Expect(m).NotTo(BeNil()) + + By("checking the server contains the Port set on the webhook server and not passed to Options") + svr := m.GetWebhookServer() + Expect(svr).NotTo(BeNil()) + Expect(svr).To(Equal(srv)) + Expect(svr.(*webhook.DefaultServer).Options.Port).To(Equal(9440)) + }) + + It("should allow passing a custom webhook.Server implementation", func() { + type customWebhook struct { + webhook.Server + } + m, err := New(cfg, Options{WebhookServer: customWebhook{}}) + Expect(err).NotTo(HaveOccurred()) + Expect(m).NotTo(BeNil()) + + svr := m.GetWebhookServer() + Expect(svr).NotTo(BeNil()) + + _, isCustomWebhook := svr.(customWebhook) + Expect(isCustomWebhook).To(BeTrue()) + }) + + Context("with leader election enabled", func() { + It("should only cancel the leader election after all runnables are done", func() { + m, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionNamespace: "default", + LeaderElectionID: "test-leader-election-id-2", + HealthProbeBindAddress: "0", + MetricsBindAddress: "0", + PprofBindAddress: "0", + }) + Expect(err).To(BeNil()) + + runnableDone := make(chan struct{}) + slowRunnable := RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(100 * time.Millisecond) + close(runnableDone) + return nil + }) + Expect(m.Add(slowRunnable)).To(BeNil()) + + cm := m.(*controllerManager) + cm.gracefulShutdownTimeout = time.Second + leaderElectionDone := make(chan struct{}) + cm.onStoppedLeading = func() { + close(leaderElectionDone) + } + + ctx, cancel := context.WithCancel(context.Background()) + mgrDone := make(chan struct{}) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).To(BeNil()) + close(mgrDone) + }() + <-cm.Elected() + cancel() + select { + case <-leaderElectionDone: + Expect(errors.New("leader election was cancelled before runnables were done")).ToNot(HaveOccurred()) + case <-runnableDone: + // Success + } + // Don't leak routines + <-mgrDone + + }) + It("should disable gracefulShutdown when stopping to lead", func() { + m, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionNamespace: "default", + LeaderElectionID: "test-leader-election-id-3", + HealthProbeBindAddress: "0", + MetricsBindAddress: "0", + PprofBindAddress: "0", + }) + Expect(err).To(BeNil()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + mgrDone := make(chan struct{}) + go func() { + defer GinkgoRecover() + err := m.Start(ctx) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("leader election lost")) + close(mgrDone) + }() + cm := m.(*controllerManager) + <-cm.elected + + cm.leaderElectionCancel() + <-mgrDone + + Expect(cm.gracefulShutdownTimeout.Nanoseconds()).To(Equal(int64(0))) + }) + It("should default ID to controller-runtime if ID is not set", func() { + var rl resourcelock.Interface + m1, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionNamespace: "default", + LeaderElectionID: "test-leader-election-id", + newResourceLock: func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) { + var err error + rl, err = leaderelection.NewResourceLock(config, recorderProvider, options) + return rl, err + }, + HealthProbeBindAddress: "0", + MetricsBindAddress: "0", + PprofBindAddress: "0", + }) + Expect(err).ToNot(HaveOccurred()) + Expect(m1).ToNot(BeNil()) + Expect(rl.Describe()).To(Equal("default/test-leader-election-id")) + + m1cm, ok := m1.(*controllerManager) + Expect(ok).To(BeTrue()) + m1cm.onStoppedLeading = func() {} + + m2, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionNamespace: "default", + LeaderElectionID: "test-leader-election-id", + newResourceLock: func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) { + var err error + rl, err = leaderelection.NewResourceLock(config, recorderProvider, options) + return rl, err + }, + HealthProbeBindAddress: "0", + MetricsBindAddress: "0", + PprofBindAddress: "0", + }) + Expect(err).ToNot(HaveOccurred()) + Expect(m2).ToNot(BeNil()) + Expect(rl.Describe()).To(Equal("default/test-leader-election-id")) + + m2cm, ok := m2.(*controllerManager) + Expect(ok).To(BeTrue()) + m2cm.onStoppedLeading = func() {} + + c1 := make(chan struct{}) + Expect(m1.Add(RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + close(c1) + return nil + }))).To(Succeed()) + + ctx1, cancel1 := context.WithCancel(context.Background()) + defer cancel1() + go func() { + defer GinkgoRecover() + Expect(m1.Elected()).ShouldNot(BeClosed()) + Expect(m1.Start(ctx1)).NotTo(HaveOccurred()) + }() + <-m1.Elected() + <-c1 + + c2 := make(chan struct{}) + Expect(m2.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + close(c2) + return nil + }))).To(Succeed()) + + ctx2, cancel := context.WithCancel(context.Background()) + m2done := make(chan struct{}) + go func() { + defer GinkgoRecover() + Expect(m2.Start(ctx2)).NotTo(HaveOccurred()) + close(m2done) + }() + Consistently(m2.Elected()).ShouldNot(Receive()) + + Consistently(c2).ShouldNot(Receive()) + cancel() + <-m2done + }) + + It("should return an error if it can't create a ResourceLock", func() { + m, err := New(cfg, Options{ + newResourceLock: func(_ *rest.Config, _ recorder.Provider, _ leaderelection.Options) (resourcelock.Interface, error) { + return nil, fmt.Errorf("expected error") + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(MatchError(ContainSubstring("expected error"))) + }) + + It("should return an error if namespace not set and not running in cluster", func() { + m, err := New(cfg, Options{LeaderElection: true, LeaderElectionID: "controller-runtime"}) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("unable to find leader election namespace: not running in-cluster, please specify LeaderElectionNamespace")) + }) + + // We must keep this default until we are sure all controller-runtime users have upgraded from the original default + // ConfigMap lock to a controller-runtime version that has this new default. Many users of controller-runtime skip + // versions, so we should be extremely conservative here. + It("should default to LeasesResourceLock", func() { + m, err := New(cfg, Options{LeaderElection: true, LeaderElectionID: "controller-runtime", LeaderElectionNamespace: "my-ns"}) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + cm, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + _, isLeaseLock := cm.resourceLock.(*resourcelock.LeaseLock) + Expect(isLeaseLock).To(BeTrue()) + + }) + It("should use the specified ResourceLock", func() { + m, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionResourceLock: resourcelock.ConfigMapsLeasesResourceLock, + LeaderElectionID: "controller-runtime", + LeaderElectionNamespace: "my-ns", + }) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + cm, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + multilock, isMultiLock := cm.resourceLock.(*resourcelock.MultiLock) + Expect(isMultiLock).To(BeTrue()) + primaryLockType := reflect.TypeOf(multilock.Primary) + Expect(primaryLockType.Kind()).To(Equal(reflect.Ptr)) + Expect(primaryLockType.Elem().PkgPath()).To(Equal("k8s.io/client-go/tools/leaderelection/resourcelock")) + Expect(primaryLockType.Elem().Name()).To(Equal("configMapLock")) + _, secondaryIsLeaseLock := multilock.Secondary.(*resourcelock.LeaseLock) + Expect(secondaryIsLeaseLock).To(BeTrue()) + }) + It("should release lease if ElectionReleaseOnCancel is true", func() { + var rl resourcelock.Interface + m, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionResourceLock: resourcelock.LeasesResourceLock, + LeaderElectionID: "controller-runtime", + LeaderElectionNamespace: "my-ns", + LeaderElectionReleaseOnCancel: true, + newResourceLock: func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) { + var err error + rl, err = fakeleaderelection.NewResourceLock(config, recorderProvider, options) + return rl, err + }, + }) + Expect(err).To(BeNil()) + + ctx, cancel := context.WithCancel(context.Background()) + doneCh := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(doneCh) + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.(*controllerManager).elected + cancel() + <-doneCh + + ctx, cancel = context.WithCancel(context.Background()) + defer cancel() + record, _, err := rl.Get(ctx) + Expect(err).To(BeNil()) + Expect(record.HolderIdentity).To(BeEmpty()) + }) + When("using a custom LeaderElectionResourceLockInterface", func() { + It("should use the custom LeaderElectionResourceLockInterface", func() { + rl, err := fakeleaderelection.NewResourceLock(nil, nil, leaderelection.Options{}) + Expect(err).NotTo(HaveOccurred()) + + m, err := New(cfg, Options{ + LeaderElection: true, + LeaderElectionResourceLockInterface: rl, + newResourceLock: func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) { + return nil, fmt.Errorf("this should not be called") + }, + }) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + cm, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(cm.resourceLock).To(Equal(rl)) + }) + }) + }) + + It("should create a listener for the metrics if a valid address is provided", func() { + var listener net.Listener + m, err := New(cfg, Options{ + MetricsBindAddress: ":0", + newMetricsListener: func(addr string) (net.Listener, error) { + var err error + listener, err = metrics.NewListener(addr) + return listener, err + }, + }) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + Expect(listener).ToNot(BeNil()) + Expect(listener.Close()).ToNot(HaveOccurred()) + }) + + It("should return an error if the metrics bind address is already in use", func() { + ln, err := metrics.NewListener(":0") + Expect(err).ShouldNot(HaveOccurred()) + + var listener net.Listener + m, err := New(cfg, Options{ + MetricsBindAddress: ln.Addr().String(), + newMetricsListener: func(addr string) (net.Listener, error) { + var err error + listener, err = metrics.NewListener(addr) + return listener, err + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(listener).To(BeNil()) + + Expect(ln.Close()).ToNot(HaveOccurred()) + }) + + It("should create a listener for the health probes if a valid address is provided", func() { + var listener net.Listener + m, err := New(cfg, Options{ + HealthProbeBindAddress: ":0", + newHealthProbeListener: func(addr string) (net.Listener, error) { + var err error + listener, err = defaultHealthProbeListener(addr) + return listener, err + }, + }) + Expect(m).ToNot(BeNil()) + Expect(err).ToNot(HaveOccurred()) + Expect(listener).ToNot(BeNil()) + Expect(listener.Close()).ToNot(HaveOccurred()) + }) + + It("should return an error if the health probes bind address is already in use", func() { + ln, err := defaultHealthProbeListener(":0") + Expect(err).ShouldNot(HaveOccurred()) + + var listener net.Listener + m, err := New(cfg, Options{ + HealthProbeBindAddress: ln.Addr().String(), + newHealthProbeListener: func(addr string) (net.Listener, error) { + var err error + listener, err = defaultHealthProbeListener(addr) + return listener, err + }, + }) + Expect(m).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(listener).To(BeNil()) + + Expect(ln.Close()).ToNot(HaveOccurred()) + }) + }) + + Describe("Start", func() { + var startSuite = func(options Options, callbacks ...func(Manager)) { + It("should Start each Component", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + var wgRunnableStarted sync.WaitGroup + wgRunnableStarted.Add(2) + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + wgRunnableStarted.Done() + return nil + }))).To(Succeed()) + + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + wgRunnableStarted.Done() + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Elected()).ShouldNot(BeClosed()) + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + + <-m.Elected() + wgRunnableStarted.Wait() + }) + + It("should not manipulate the provided config", func() { + // strip WrapTransport, cause func values are PartialEq, not Eq -- + // specifically, for reflect.DeepEqual, for all functions F, + // F != nil implies F != F, which means no full equivalence relation. + cfg := rest.CopyConfig(cfg) + cfg.WrapTransport = nil + originalCfg := rest.CopyConfig(cfg) + // The options object is shared by multiple tests, copy it + // into our scope so we manipulate it for this testcase only + options := options + options.newResourceLock = nil + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + Expect(m.GetConfig()).To(Equal(originalCfg)) + }) + + It("should stop when context is cancelled", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }) + + It("should return an error if it can't start the cache", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(mgr.Add( + &cacheProvider{cache: &informertest.FakeInformers{Error: fmt.Errorf("expected error")}}, + )).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + Expect(m.Start(ctx)).To(MatchError(ContainSubstring("expected error"))) + }) + + It("should start the cache before starting anything else", func() { + fakeCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}} + options.NewCache = func(_ *rest.Config, _ cache.Options) (cache.Cache, error) { + return fakeCache, nil + } + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + + runnableWasStarted := make(chan struct{}) + runnable := RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + if !fakeCache.wasSynced { + return errors.New("runnable got started before cache was synced") + } + close(runnableWasStarted) + return nil + }) + Expect(m.Add(runnable)).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).ToNot(HaveOccurred()) + }() + + <-runnableWasStarted + }) + + It("should start additional clusters before anything else", func() { + fakeCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}} + options.NewCache = func(_ *rest.Config, _ cache.Options) (cache.Cache, error) { + return fakeCache, nil + } + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + + additionalClusterCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}} + additionalCluster, err := cluster.New(cfg, func(o *cluster.Options) { + o.NewCache = func(_ *rest.Config, _ cache.Options) (cache.Cache, error) { + return additionalClusterCache, nil + } + }) + Expect(err).NotTo(HaveOccurred()) + Expect(m.Add(additionalCluster)).NotTo(HaveOccurred()) + + runnableWasStarted := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + if !fakeCache.wasSynced { + return errors.New("WaitForCacheSyncCalled wasn't called before Runnable got started") + } + if !additionalClusterCache.wasSynced { + return errors.New("the additional clusters WaitForCacheSync wasn't called before Runnable got started") + } + close(runnableWasStarted) + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).ToNot(HaveOccurred()) + }() + + <-runnableWasStarted + }) + + It("should return an error if any Components fail to Start", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + <-ctx.Done() + return nil + }))).To(Succeed()) + + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + return fmt.Errorf("expected error") + }))).To(Succeed()) + + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + return nil + }))).To(Succeed()) + + defer GinkgoRecover() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = m.Start(ctx) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("expected error")) + }) + + It("should start caches added after Manager has started", func() { + fakeCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}} + options.NewCache = func(_ *rest.Config, _ cache.Options) (cache.Cache, error) { + return fakeCache, nil + } + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + + runnableWasStarted := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + if !fakeCache.wasSynced { + return errors.New("WaitForCacheSyncCalled wasn't called before Runnable got started") + } + close(runnableWasStarted) + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).ToNot(HaveOccurred()) + }() + + <-runnableWasStarted + + additionalClusterCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}} + fakeCluster := &startClusterAfterManager{informer: additionalClusterCache} + + Expect(err).NotTo(HaveOccurred()) + Expect(m.Add(fakeCluster)).NotTo(HaveOccurred()) + + Eventually(func() bool { + fakeCluster.informer.mu.Lock() + defer fakeCluster.informer.mu.Unlock() + return fakeCluster.informer.wasStarted && fakeCluster.informer.wasSynced + }).Should(BeTrue()) + }) + + It("should wait for runnables to stop", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + + var lock sync.Mutex + var runnableDoneCount int64 + runnableDoneFunc := func() { + lock.Lock() + defer lock.Unlock() + atomic.AddInt64(&runnableDoneCount, 1) + } + var wgRunnableRunning sync.WaitGroup + wgRunnableRunning.Add(2) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + wgRunnableRunning.Done() + defer GinkgoRecover() + defer runnableDoneFunc() + <-ctx.Done() + return nil + }))).To(Succeed()) + + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + wgRunnableRunning.Done() + defer GinkgoRecover() + defer runnableDoneFunc() + <-ctx.Done() + time.Sleep(300 * time.Millisecond) // slow closure simulation + return nil + }))).To(Succeed()) + + defer GinkgoRecover() + ctx, cancel := context.WithCancel(context.Background()) + + var wgManagerRunning sync.WaitGroup + wgManagerRunning.Add(1) + go func() { + defer GinkgoRecover() + defer wgManagerRunning.Done() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + Eventually(func() int64 { + return atomic.LoadInt64(&runnableDoneCount) + }).Should(BeEquivalentTo(2)) + }() + wgRunnableRunning.Wait() + cancel() + + wgManagerRunning.Wait() + }) + + It("should return an error if any Components fail to Start and wait for runnables to stop", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + defer GinkgoRecover() + var lock sync.Mutex + runnableDoneCount := 0 + runnableDoneFunc := func() { + lock.Lock() + defer lock.Unlock() + runnableDoneCount++ + } + + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + defer runnableDoneFunc() + return fmt.Errorf("expected error") + }))).To(Succeed()) + + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + defer GinkgoRecover() + defer runnableDoneFunc() + <-ctx.Done() + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + Expect(m.Start(ctx)).To(HaveOccurred()) + Expect(runnableDoneCount).To(Equal(2)) + }) + + It("should refuse to add runnable if stop procedure is already engaged", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + defer GinkgoRecover() + + var wgRunnableRunning sync.WaitGroup + wgRunnableRunning.Add(1) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + wgRunnableRunning.Done() + defer GinkgoRecover() + <-ctx.Done() + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + wgRunnableRunning.Wait() + cancel() + time.Sleep(100 * time.Millisecond) // give some time for the stop chan closure to be caught by the manager + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + return nil + }))).NotTo(Succeed()) + }) + + It("should return both runnables and stop errors when both error", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + m.(*controllerManager).gracefulShutdownTimeout = 1 * time.Nanosecond + Expect(m.Add(RunnableFunc(func(context.Context) error { + return runnableError{} + }))) + testDone := make(chan struct{}) + defer close(testDone) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + timer := time.NewTimer(30 * time.Second) + defer timer.Stop() + select { + case <-testDone: + return nil + case <-timer.C: + return nil + } + }))) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = m.Start(ctx) + Expect(err).ToNot(BeNil()) + eMsg := "[not feeling like that, failed waiting for all runnables to end within grace period of 1ns: context deadline exceeded]" + Expect(err.Error()).To(Equal(eMsg)) + Expect(errors.Is(err, context.DeadlineExceeded)).To(BeTrue()) + Expect(errors.Is(err, runnableError{})).To(BeTrue()) + }) + + It("should return only stop errors if runnables dont error", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + m.(*controllerManager).gracefulShutdownTimeout = 1 * time.Nanosecond + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + return nil + }))) + testDone := make(chan struct{}) + defer close(testDone) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + timer := time.NewTimer(30 * time.Second) + defer timer.Stop() + select { + case <-testDone: + return nil + case <-timer.C: + return nil + } + }))).NotTo(HaveOccurred()) + ctx, cancel := context.WithCancel(context.Background()) + managerStopDone := make(chan struct{}) + go func() { err = m.Start(ctx); close(managerStopDone) }() + // Use the 'elected' channel to find out if startup was done, otherwise we stop + // before we started the Runnable and see flakes, mostly in low-CPU envs like CI + <-m.(*controllerManager).elected + cancel() + <-managerStopDone + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("failed waiting for all runnables to end within grace period of 1ns: context deadline exceeded")) + Expect(errors.Is(err, context.DeadlineExceeded)).To(BeTrue()) + Expect(errors.Is(err, runnableError{})).ToNot(BeTrue()) + }) + + It("should return only runnables error if stop doesn't error", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + Expect(m.Add(RunnableFunc(func(context.Context) error { + return runnableError{} + }))) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = m.Start(ctx) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("not feeling like that")) + Expect(errors.Is(err, context.DeadlineExceeded)).ToNot(BeTrue()) + Expect(errors.Is(err, runnableError{})).To(BeTrue()) + }) + + It("should not wait for runnables if gracefulShutdownTimeout is 0", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + m.(*controllerManager).gracefulShutdownTimeout = time.Duration(0) + + runnableStopped := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(100 * time.Millisecond) + close(runnableStopped) + return nil + }))).ToNot(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + managerStopDone := make(chan struct{}) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + close(managerStopDone) + }() + <-m.Elected() + cancel() + + <-managerStopDone + <-runnableStopped + }) + + It("should wait forever for runnables if gracefulShutdownTimeout is <0 (-1)", func() { + m, err := New(cfg, options) + Expect(err).NotTo(HaveOccurred()) + for _, cb := range callbacks { + cb(m) + } + m.(*controllerManager).gracefulShutdownTimeout = time.Duration(-1) + + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(100 * time.Millisecond) + return nil + }))).ToNot(HaveOccurred()) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(200 * time.Millisecond) + return nil + }))).ToNot(HaveOccurred()) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(500 * time.Millisecond) + return nil + }))).ToNot(HaveOccurred()) + Expect(m.Add(RunnableFunc(func(ctx context.Context) error { + <-ctx.Done() + time.Sleep(1500 * time.Millisecond) + return nil + }))).ToNot(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + managerStopDone := make(chan struct{}) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + close(managerStopDone) + }() + <-m.Elected() + cancel() + + beforeDone := time.Now() + <-managerStopDone + Expect(time.Since(beforeDone)).To(BeNumerically(">=", 1500*time.Millisecond)) + }) + + } + + Context("with defaults", func() { + startSuite(Options{}) + }) + + Context("with leaderelection enabled", func() { + startSuite( + Options{ + LeaderElection: true, + LeaderElectionID: "controller-runtime", + LeaderElectionNamespace: "default", + newResourceLock: fakeleaderelection.NewResourceLock, + }, + func(m Manager) { + cm, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + cm.onStoppedLeading = func() {} + }, + ) + }) + + Context("should start serving metrics", func() { + var listener net.Listener + var opts Options + + BeforeEach(func() { + listener = nil + opts = Options{ + newMetricsListener: func(addr string) (net.Listener, error) { + var err error + listener, err = metrics.NewListener(addr) + return listener, err + }, + } + }) + + AfterEach(func() { + if listener != nil { + listener.Close() + } + }) + + It("should stop serving metrics when stop is called", func() { + opts.MetricsBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + + // Check the metrics started + endpoint := fmt.Sprintf("http://%s", listener.Addr().String()) + _, err = http.Get(endpoint) + Expect(err).NotTo(HaveOccurred()) + + // Shutdown the server + cancel() + + // Expect the metrics server to shutdown + Eventually(func() error { + _, err = http.Get(endpoint) + return err + }).ShouldNot(Succeed()) + }) + + It("should serve metrics endpoint", func() { + opts.MetricsBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + metricsEndpoint := fmt.Sprintf("http://%s/metrics", listener.Addr().String()) + resp, err := http.Get(metricsEndpoint) + Expect(err).NotTo(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + }) + + It("should not serve anything other than metrics endpoint by default", func() { + opts.MetricsBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + endpoint := fmt.Sprintf("http://%s/should-not-exist", listener.Addr().String()) + resp, err := http.Get(endpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(404)) + }) + + It("should serve metrics in its registry", func() { + one := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "test_one", + Help: "test metric for testing", + }) + one.Inc() + err := metrics.Registry.Register(one) + Expect(err).NotTo(HaveOccurred()) + + opts.MetricsBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + metricsEndpoint := fmt.Sprintf("http://%s/metrics", listener.Addr().String()) + resp, err := http.Get(metricsEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(200)) + + data, err := io.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(data)).To(ContainSubstring("%s\n%s\n%s\n", + `# HELP test_one test metric for testing`, + `# TYPE test_one counter`, + `test_one 1`, + )) + + // Unregister will return false if the metric was never registered + ok := metrics.Registry.Unregister(one) + Expect(ok).To(BeTrue()) + }) + + It("should serve extra endpoints", func() { + opts.MetricsBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + err = m.AddMetricsExtraHandler("/debug", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + _, _ = w.Write([]byte("Some debug info")) + })) + Expect(err).NotTo(HaveOccurred()) + + // Should error when we add another extra endpoint on the already registered path. + err = m.AddMetricsExtraHandler("/debug", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + _, _ = w.Write([]byte("Another debug info")) + })) + Expect(err).To(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + endpoint := fmt.Sprintf("http://%s/debug", listener.Addr().String()) + resp, err := http.Get(endpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + body, err := io.ReadAll(resp.Body) + Expect(err).NotTo(HaveOccurred()) + Expect(string(body)).To(Equal("Some debug info")) + }) + }) + }) + + Context("should start serving health probes", func() { + var listener net.Listener + var opts Options + + BeforeEach(func() { + listener = nil + opts = Options{ + newHealthProbeListener: func(addr string) (net.Listener, error) { + var err error + listener, err = defaultHealthProbeListener(addr) + return listener, err + }, + } + }) + + AfterEach(func() { + if listener != nil { + listener.Close() + } + }) + + It("should stop serving health probes when stop is called", func() { + opts.HealthProbeBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + // Check the health probes started + endpoint := fmt.Sprintf("http://%s", listener.Addr().String()) + _, err = http.Get(endpoint) + Expect(err).NotTo(HaveOccurred()) + + // Shutdown the server + cancel() + + // Expect the health probes server to shutdown + Eventually(func() error { + _, err = http.Get(endpoint) + return err + }, 10*time.Second).ShouldNot(Succeed()) + }) + + It("should serve readiness endpoint", func() { + opts.HealthProbeBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + res := fmt.Errorf("not ready yet") + namedCheck := "check" + err = m.AddReadyzCheck(namedCheck, func(_ *http.Request) error { return res }) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + readinessEndpoint := fmt.Sprint("http://", listener.Addr().String(), defaultReadinessEndpoint) + + // Controller is not ready + resp, err := http.Get(readinessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusInternalServerError)) + + // Controller is ready + res = nil + resp, err = http.Get(readinessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + // Check readiness path without trailing slash without redirect + readinessEndpoint = fmt.Sprint("http://", listener.Addr().String(), defaultReadinessEndpoint) + res = nil + httpClient := http.Client{ + CheckRedirect: func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse // Do not follow redirect + }, + } + resp, err = httpClient.Get(readinessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + // Check readiness path for individual check + readinessEndpoint = fmt.Sprint("http://", listener.Addr().String(), path.Join(defaultReadinessEndpoint, namedCheck)) + res = nil + resp, err = http.Get(readinessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + }) + + It("should serve liveness endpoint", func() { + opts.HealthProbeBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + res := fmt.Errorf("not alive") + namedCheck := "check" + err = m.AddHealthzCheck(namedCheck, func(_ *http.Request) error { return res }) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + livenessEndpoint := fmt.Sprint("http://", listener.Addr().String(), defaultLivenessEndpoint) + + // Controller is not ready + resp, err := http.Get(livenessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusInternalServerError)) + + // Controller is ready + res = nil + resp, err = http.Get(livenessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + // Check liveness path without trailing slash without redirect + livenessEndpoint = fmt.Sprint("http://", listener.Addr().String(), defaultLivenessEndpoint) + res = nil + httpClient := http.Client{ + CheckRedirect: func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse // Do not follow redirect + }, + } + resp, err = httpClient.Get(livenessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + // Check readiness path for individual check + livenessEndpoint = fmt.Sprint("http://", listener.Addr().String(), path.Join(defaultLivenessEndpoint, namedCheck)) + res = nil + resp, err = http.Get(livenessEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + }) + }) + + Context("should start serving pprof", func() { + var listener net.Listener + var opts Options + + BeforeEach(func() { + listener = nil + opts = Options{ + newPprofListener: func(addr string) (net.Listener, error) { + var err error + listener, err = defaultPprofListener(addr) + return listener, err + }, + } + }) + + AfterEach(func() { + if listener != nil { + listener.Close() + } + }) + + It("should stop serving pprof when stop is called", func() { + opts.PprofBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + // Check the pprof started + endpoint := fmt.Sprintf("http://%s", listener.Addr().String()) + _, err = http.Get(endpoint) + Expect(err).NotTo(HaveOccurred()) + + // Shutdown the server + cancel() + + // Expect the pprof server to shutdown + Eventually(func() error { + _, err = http.Get(endpoint) + return err + }, 10*time.Second).ShouldNot(Succeed()) + }) + + It("should serve pprof endpoints", func() { + opts.PprofBindAddress = ":0" + m, err := New(cfg, opts) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + pprofIndexEndpoint := fmt.Sprintf("http://%s/debug/pprof/", listener.Addr().String()) + resp, err := http.Get(pprofIndexEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + pprofCmdlineEndpoint := fmt.Sprintf("http://%s/debug/pprof/cmdline", listener.Addr().String()) + resp, err = http.Get(pprofCmdlineEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + pprofProfileEndpoint := fmt.Sprintf("http://%s/debug/pprof/profile", listener.Addr().String()) + resp, err = http.Get(pprofProfileEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + pprofSymbolEndpoint := fmt.Sprintf("http://%s/debug/pprof/symbol", listener.Addr().String()) + resp, err = http.Get(pprofSymbolEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + pprofTraceEndpoint := fmt.Sprintf("http://%s/debug/pprof/trace", listener.Addr().String()) + resp, err = http.Get(pprofTraceEndpoint) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + }) + }) + + Describe("Add", func() { + It("should immediately start the Component if the Manager has already Started another Component", + func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + + // Add one component before starting + c1 := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + close(c1) + return nil + }))).To(Succeed()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + <-m.Elected() + + // Wait for the Manager to start + Eventually(func() bool { + return mgr.runnables.Caches.Started() + }).Should(BeTrue()) + + // Add another component after starting + c2 := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + close(c2) + return nil + }))).To(Succeed()) + <-c1 + <-c2 + }) + + It("should immediately start the Component if the Manager has already Started", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + + // Wait for the Manager to start + Eventually(func() bool { + return mgr.runnables.Caches.Started() + }).Should(BeTrue()) + + c1 := make(chan struct{}) + Expect(m.Add(RunnableFunc(func(context.Context) error { + defer GinkgoRecover() + close(c1) + return nil + }))).To(Succeed()) + <-c1 + }) + + It("should fail if attempted to start a second time", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer GinkgoRecover() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + }() + // Wait for the Manager to start + Eventually(func() bool { + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + return mgr.runnables.Caches.Started() + }).Should(BeTrue()) + + err = m.Start(ctx) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("manager already started")) + + }) + }) + + It("should not leak goroutines when stopped", func() { + currentGRs := goleak.IgnoreCurrent() + + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + Expect(m.Start(ctx)).NotTo(HaveOccurred()) + + // force-close keep-alive connections. These'll time anyway (after + // like 30s or so) but force it to speed up the tests. + clientTransport.CloseIdleConnections() + Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) + }) + + It("should not leak goroutines if the default event broadcaster is used & events are emitted", func() { + currentGRs := goleak.IgnoreCurrent() + + m, err := New(cfg, Options{ /* implicit: default setting for EventBroadcaster */ }) + Expect(err).NotTo(HaveOccurred()) + + By("adding a runnable that emits an event") + ns := corev1.Namespace{} + ns.Name = "default" + + recorder := m.GetEventRecorderFor("rock-and-roll") + Expect(m.Add(RunnableFunc(func(_ context.Context) error { + recorder.Event(&ns, "Warning", "BallroomBlitz", "yeah, yeah, yeah-yeah-yeah") + return nil + }))).To(Succeed()) + + By("starting the manager & waiting till we've sent our event") + ctx, cancel := context.WithCancel(context.Background()) + doneCh := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(doneCh) + Expect(m.Start(ctx)).To(Succeed()) + }() + <-m.Elected() + + Eventually(func() *corev1.Event { + evts, err := clientset.CoreV1().Events("").Search(m.GetScheme(), &ns) + Expect(err).NotTo(HaveOccurred()) + + for i, evt := range evts.Items { + if evt.Reason == "BallroomBlitz" { + return &evts.Items[i] + } + } + return nil + }).ShouldNot(BeNil()) + + By("making sure there's no extra go routines still running after we stop") + cancel() + <-doneCh + + // force-close keep-alive connections. These'll time anyway (after + // like 30s or so) but force it to speed up the tests. + clientTransport.CloseIdleConnections() + Eventually(func() error { return goleak.Find(currentGRs) }).Should(Succeed()) + }) + + It("should provide a function to get the Config", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(m.GetConfig()).To(Equal(mgr.cluster.GetConfig())) + }) + + It("should provide a function to get the Client", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(m.GetClient()).To(Equal(mgr.cluster.GetClient())) + }) + + It("should provide a function to get the Scheme", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(m.GetScheme()).To(Equal(mgr.cluster.GetScheme())) + }) + + It("should provide a function to get the FieldIndexer", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + mgr, ok := m.(*controllerManager) + Expect(ok).To(BeTrue()) + Expect(m.GetFieldIndexer()).To(Equal(mgr.cluster.GetFieldIndexer())) + }) + + It("should provide a function to get the EventRecorder", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(m.GetEventRecorderFor("test")).NotTo(BeNil()) + }) + It("should provide a function to get the APIReader", func() { + m, err := New(cfg, Options{}) + Expect(err).NotTo(HaveOccurred()) + Expect(m.GetAPIReader()).NotTo(BeNil()) + }) +}) + +type runnableError struct { +} + +func (runnableError) Error() string { + return "not feeling like that" +} + +var _ Runnable = &cacheProvider{} + +type cacheProvider struct { + cache cache.Cache +} + +func (c *cacheProvider) GetCache() cache.Cache { + return c.cache +} + +func (c *cacheProvider) Start(ctx context.Context) error { + return c.cache.Start(ctx) +} + +type startSignalingInformer struct { + mu sync.Mutex + + // The manager calls Start and WaitForCacheSync in + // parallel, so we have to protect wasStarted with a Mutex + // and block in WaitForCacheSync until it is true. + wasStarted bool + // was synced will be true once Start was called and + // WaitForCacheSync returned, just like a real cache. + wasSynced bool + cache.Cache +} + +func (c *startSignalingInformer) Start(ctx context.Context) error { + c.mu.Lock() + c.wasStarted = true + c.mu.Unlock() + return c.Cache.Start(ctx) +} + +func (c *startSignalingInformer) WaitForCacheSync(ctx context.Context) bool { + defer func() { + c.mu.Lock() + c.wasSynced = true + c.mu.Unlock() + }() + return c.Cache.WaitForCacheSync(ctx) +} + +type startClusterAfterManager struct { + informer *startSignalingInformer +} + +func (c *startClusterAfterManager) Start(ctx context.Context) error { + return c.informer.Start(ctx) +} + +func (c *startClusterAfterManager) GetCache() cache.Cache { + return c.informer +} + +type fakeDeferredLoader struct { + *v1alpha1.ControllerManagerConfiguration +} + +func (f *fakeDeferredLoader) Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) { + return f.ControllerManagerConfiguration.ControllerManagerConfigurationSpec, nil +} + +func (f *fakeDeferredLoader) InjectScheme(scheme *runtime.Scheme) error { + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go new file mode 100644 index 00000000000..549741e6e53 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go @@ -0,0 +1,297 @@ +package manager + +import ( + "context" + "errors" + "sync" + + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var ( + errRunnableGroupStopped = errors.New("can't accept new runnable as stop procedure is already engaged") +) + +// readyRunnable encapsulates a runnable with +// a ready check. +type readyRunnable struct { + Runnable + Check runnableCheck + signalReady bool +} + +// runnableCheck can be passed to Add() to let the runnable group determine that a +// runnable is ready. A runnable check should block until a runnable is ready, +// if the returned result is false, the runnable is considered not ready and failed. +type runnableCheck func(ctx context.Context) bool + +// runnables handles all the runnables for a manager by grouping them accordingly to their +// type (webhooks, caches etc.). +type runnables struct { + Webhooks *runnableGroup + Caches *runnableGroup + LeaderElection *runnableGroup + Others *runnableGroup +} + +// newRunnables creates a new runnables object. +func newRunnables(baseContext BaseContextFunc, errChan chan error) *runnables { + return &runnables{ + Webhooks: newRunnableGroup(baseContext, errChan), + Caches: newRunnableGroup(baseContext, errChan), + LeaderElection: newRunnableGroup(baseContext, errChan), + Others: newRunnableGroup(baseContext, errChan), + } +} + +// Add adds a runnable to closest group of runnable that they belong to. +// +// Add should be able to be called before and after Start, but not after StopAndWait. +// Add should return an error when called during StopAndWait. +// The runnables added before Start are started when Start is called. +// The runnables added after Start are started directly. +func (r *runnables) Add(fn Runnable) error { + switch runnable := fn.(type) { + case hasCache: + return r.Caches.Add(fn, func(ctx context.Context) bool { + return runnable.GetCache().WaitForCacheSync(ctx) + }) + case webhook.Server: + return r.Webhooks.Add(fn, nil) + case LeaderElectionRunnable: + if !runnable.NeedLeaderElection() { + return r.Others.Add(fn, nil) + } + return r.LeaderElection.Add(fn, nil) + default: + return r.LeaderElection.Add(fn, nil) + } +} + +// runnableGroup manages a group of runnables that are +// meant to be running together until StopAndWait is called. +// +// Runnables can be added to a group after the group has started +// but not after it's stopped or while shutting down. +type runnableGroup struct { + ctx context.Context + cancel context.CancelFunc + + start sync.Mutex + startOnce sync.Once + started bool + startQueue []*readyRunnable + startReadyCh chan *readyRunnable + + stop sync.RWMutex + stopOnce sync.Once + stopped bool + + // errChan is the error channel passed by the caller + // when the group is created. + // All errors are forwarded to this channel once they occur. + errChan chan error + + // ch is the internal channel where the runnables are read off from. + ch chan *readyRunnable + + // wg is an internal sync.WaitGroup that allows us to properly stop + // and wait for all the runnables to finish before returning. + wg *sync.WaitGroup +} + +func newRunnableGroup(baseContext BaseContextFunc, errChan chan error) *runnableGroup { + r := &runnableGroup{ + startReadyCh: make(chan *readyRunnable), + errChan: errChan, + ch: make(chan *readyRunnable), + wg: new(sync.WaitGroup), + } + + r.ctx, r.cancel = context.WithCancel(baseContext()) + return r +} + +// Started returns true if the group has started. +func (r *runnableGroup) Started() bool { + r.start.Lock() + defer r.start.Unlock() + return r.started +} + +// Start starts the group and waits for all +// initially registered runnables to start. +// It can only be called once, subsequent calls have no effect. +func (r *runnableGroup) Start(ctx context.Context) error { + var retErr error + + r.startOnce.Do(func() { + defer close(r.startReadyCh) + + // Start the internal reconciler. + go r.reconcile() + + // Start the group and queue up all + // the runnables that were added prior. + r.start.Lock() + r.started = true + for _, rn := range r.startQueue { + rn.signalReady = true + r.ch <- rn + } + r.start.Unlock() + + // If we don't have any queue, return. + if len(r.startQueue) == 0 { + return + } + + // Wait for all runnables to signal. + for { + select { + case <-ctx.Done(): + if err := ctx.Err(); !errors.Is(err, context.Canceled) { + retErr = err + } + case rn := <-r.startReadyCh: + for i, existing := range r.startQueue { + if existing == rn { + // Remove the item from the start queue. + r.startQueue = append(r.startQueue[:i], r.startQueue[i+1:]...) + break + } + } + // We're done waiting if the queue is empty, return. + if len(r.startQueue) == 0 { + return + } + } + } + }) + + return retErr +} + +// reconcile is our main entrypoint for every runnable added +// to this group. Its primary job is to read off the internal channel +// and schedule runnables while tracking their state. +func (r *runnableGroup) reconcile() { + for runnable := range r.ch { + // Handle stop. + // If the shutdown has been called we want to avoid + // adding new goroutines to the WaitGroup because Wait() + // panics if Add() is called after it. + { + r.stop.RLock() + if r.stopped { + // Drop any runnables if we're stopped. + r.errChan <- errRunnableGroupStopped + r.stop.RUnlock() + continue + } + + // Why is this here? + // When StopAndWait is called, if a runnable is in the process + // of being added, we could end up in a situation where + // the WaitGroup is incremented while StopAndWait has called Wait(), + // which would result in a panic. + r.wg.Add(1) + r.stop.RUnlock() + } + + // Start the runnable. + go func(rn *readyRunnable) { + go func() { + if rn.Check(r.ctx) { + if rn.signalReady { + r.startReadyCh <- rn + } + } + }() + + // If we return, the runnable ended cleanly + // or returned an error to the channel. + // + // We should always decrement the WaitGroup here. + defer r.wg.Done() + + // Start the runnable. + if err := rn.Start(r.ctx); err != nil { + r.errChan <- err + } + }(runnable) + } +} + +// Add should be able to be called before and after Start, but not after StopAndWait. +// Add should return an error when called during StopAndWait. +func (r *runnableGroup) Add(rn Runnable, ready runnableCheck) error { + r.stop.RLock() + if r.stopped { + r.stop.RUnlock() + return errRunnableGroupStopped + } + r.stop.RUnlock() + + if ready == nil { + ready = func(_ context.Context) bool { return true } + } + + readyRunnable := &readyRunnable{ + Runnable: rn, + Check: ready, + } + + // Handle start. + // If the overall runnable group isn't started yet + // we want to buffer the runnables and let Start() + // queue them up again later. + { + r.start.Lock() + + // Check if we're already started. + if !r.started { + // Store the runnable in the internal if not. + r.startQueue = append(r.startQueue, readyRunnable) + r.start.Unlock() + return nil + } + r.start.Unlock() + } + + // Enqueue the runnable. + r.ch <- readyRunnable + return nil +} + +// StopAndWait waits for all the runnables to finish before returning. +func (r *runnableGroup) StopAndWait(ctx context.Context) { + r.stopOnce.Do(func() { + // Close the reconciler channel once we're done. + defer close(r.ch) + + _ = r.Start(ctx) + r.stop.Lock() + // Store the stopped variable so we don't accept any new + // runnables for the time being. + r.stopped = true + r.stop.Unlock() + + // Cancel the internal channel. + r.cancel() + + done := make(chan struct{}) + go func() { + defer close(done) + // Wait for all the runnables to finish. + r.wg.Wait() + }() + + select { + case <-done: + // We're done, exit. + case <-ctx.Done(): + // Calling context has expired, exit. + } + }) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group_test.go new file mode 100644 index 00000000000..456b8d7ac06 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group_test.go @@ -0,0 +1,182 @@ +package manager + +import ( + "context" + "errors" + "fmt" + "sync/atomic" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/cache/informertest" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var _ = Describe("runnables", func() { + errCh := make(chan error) + + It("should be able to create a new runnables object", func() { + Expect(newRunnables(defaultBaseContext, errCh)).ToNot(BeNil()) + }) + + It("should add caches to the appropriate group", func() { + cache := &cacheProvider{cache: &informertest.FakeInformers{Error: fmt.Errorf("expected error")}} + r := newRunnables(defaultBaseContext, errCh) + Expect(r.Add(cache)).To(Succeed()) + Expect(r.Caches.startQueue).To(HaveLen(1)) + }) + + It("should add webhooks to the appropriate group", func() { + webhook := webhook.NewServer(webhook.Options{}) + r := newRunnables(defaultBaseContext, errCh) + Expect(r.Add(webhook)).To(Succeed()) + Expect(r.Webhooks.startQueue).To(HaveLen(1)) + }) + + It("should add any runnable to the leader election group", func() { + err := errors.New("runnable func") + runnable := RunnableFunc(func(c context.Context) error { + return err + }) + + r := newRunnables(defaultBaseContext, errCh) + Expect(r.Add(runnable)).To(Succeed()) + Expect(r.LeaderElection.startQueue).To(HaveLen(1)) + }) +}) + +var _ = Describe("runnableGroup", func() { + errCh := make(chan error) + + It("should be able to add new runnables before it starts", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + rg := newRunnableGroup(defaultBaseContext, errCh) + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), nil)).To(Succeed()) + + Expect(rg.Started()).To(BeFalse()) + }) + + It("should be able to add new runnables before and after start", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + rg := newRunnableGroup(defaultBaseContext, errCh) + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), nil)).To(Succeed()) + Expect(rg.Start(ctx)).To(Succeed()) + Expect(rg.Started()).To(BeTrue()) + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), nil)).To(Succeed()) + }) + + It("should be able to add new runnables before and after start concurrently", func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + rg := newRunnableGroup(defaultBaseContext, errCh) + + go func() { + defer GinkgoRecover() + <-time.After(50 * time.Millisecond) + Expect(rg.Start(ctx)).To(Succeed()) + }() + + for i := 0; i < 20; i++ { + go func(i int) { + defer GinkgoRecover() + + <-time.After(time.Duration(i) * 10 * time.Millisecond) + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), nil)).To(Succeed()) + }(i) + } + }) + + It("should be able to close the group and wait for all runnables to finish", func() { + ctx, cancel := context.WithCancel(context.Background()) + + exited := pointer.Int64(0) + rg := newRunnableGroup(defaultBaseContext, errCh) + for i := 0; i < 10; i++ { + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + defer atomic.AddInt64(exited, 1) + <-ctx.Done() + <-time.After(time.Duration(i) * 10 * time.Millisecond) + return nil + }), nil)).To(Succeed()) + } + Expect(rg.Start(ctx)).To(Succeed()) + + // Cancel the context, asking the runnables to exit. + cancel() + rg.StopAndWait(context.Background()) + + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + return nil + }), nil)).ToNot(Succeed()) + + Expect(atomic.LoadInt64(exited)).To(BeNumerically("==", 10)) + }) + + It("should be able to wait for all runnables to be ready at different intervals", func() { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + rg := newRunnableGroup(defaultBaseContext, errCh) + + go func() { + defer GinkgoRecover() + <-time.After(50 * time.Millisecond) + Expect(rg.Start(ctx)).To(Succeed()) + }() + + for i := 0; i < 20; i++ { + go func(i int) { + defer GinkgoRecover() + + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), func(_ context.Context) bool { + <-time.After(time.Duration(i) * 10 * time.Millisecond) + return true + })).To(Succeed()) + }(i) + } + }) + + It("should not turn ready if some readiness check fail", func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + rg := newRunnableGroup(defaultBaseContext, errCh) + + go func() { + defer GinkgoRecover() + <-time.After(50 * time.Millisecond) + Expect(rg.Start(ctx)).To(Succeed()) + }() + + for i := 0; i < 20; i++ { + go func(i int) { + defer GinkgoRecover() + + Expect(rg.Add(RunnableFunc(func(c context.Context) error { + <-ctx.Done() + return nil + }), func(_ context.Context) bool { + <-time.After(time.Duration(i) * 10 * time.Millisecond) + return i%2 == 0 // Return false readiness all uneven indexes. + })).To(Succeed()) + }(i) + } + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/server.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/server.go new file mode 100644 index 00000000000..b6509f48f24 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/server.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "errors" + "net" + "net/http" + + "github.com/go-logr/logr" +) + +// server is a general purpose HTTP server Runnable for a manager +// to serve some internal handlers such as health probes, metrics and profiling. +type server struct { + Kind string + Log logr.Logger + Server *http.Server + Listener net.Listener +} + +func (s *server) Start(ctx context.Context) error { + log := s.Log.WithValues("kind", s.Kind, "addr", s.Listener.Addr()) + + serverShutdown := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("shutting down server") + if err := s.Server.Shutdown(context.Background()); err != nil { + log.Error(err, "error shutting down server") + } + close(serverShutdown) + }() + + log.Info("starting server") + if err := s.Server.Serve(s.Listener); err != nil && !errors.Is(err, http.ErrServerClosed) { + return err + } + + <-serverShutdown + return nil +} + +func (s *server) NeedLeaderElection() bool { + return false +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go new file mode 100644 index 00000000000..737cc7eff28 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package signals contains libraries for handling signals to gracefully +// shutdown the manager in combination with Kubernetes pod graceful termination +// policy. +package signals diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go new file mode 100644 index 00000000000..a79cfb42dfb --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go @@ -0,0 +1,45 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package signals + +import ( + "context" + "os" + "os/signal" +) + +var onlyOneSignalHandler = make(chan struct{}) + +// SetupSignalHandler registers for SIGTERM and SIGINT. A context is returned +// which is canceled on one of these signals. If a second signal is caught, the program +// is terminated with exit code 1. +func SetupSignalHandler() context.Context { + close(onlyOneSignalHandler) // panics when called twice + + ctx, cancel := context.WithCancel(context.Background()) + + c := make(chan os.Signal, 2) + signal.Notify(c, shutdownSignals...) + go func() { + <-c + cancel() + <-c + os.Exit(1) // second signal. Exit directly. + }() + + return ctx +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go new file mode 100644 index 00000000000..a0f00a73213 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go @@ -0,0 +1,27 @@ +//go:build !windows +// +build !windows + +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package signals + +import ( + "os" + "syscall" +) + +var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_test.go new file mode 100644 index 00000000000..134937e012f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_test.go @@ -0,0 +1,83 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package signals + +import ( + "fmt" + "os" + "os/signal" + "sync" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("runtime signal", func() { + + Context("SignalHandler Test", func() { + + It("test signal handler", func() { + ctx := SetupSignalHandler() + task := &Task{ + ticker: time.NewTicker(time.Second * 2), + } + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + task.wg.Add(1) + go func(c chan os.Signal) { + defer task.wg.Done() + task.Run(c) + }(c) + + select { + case sig := <-c: + fmt.Printf("Got %s signal. Aborting...\n", sig) + case _, ok := <-ctx.Done(): + Expect(ok).To(BeFalse()) + } + }) + + }) + +}) + +type Task struct { + wg sync.WaitGroup + ticker *time.Ticker +} + +func (t *Task) Run(c chan os.Signal) { + for { + go sendSignal(c) + handle() + } +} + +func handle() { + for i := 0; i < 5; i++ { + fmt.Print("#") + time.Sleep(time.Millisecond * 100) + } + fmt.Println() +} + +func sendSignal(stopChan chan os.Signal) { + fmt.Printf("...") + time.Sleep(1 * time.Second) + stopChan <- os.Interrupt +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go new file mode 100644 index 00000000000..4907d573fe0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package signals + +import ( + "os" +) + +var shutdownSignals = []os.Signal{os.Interrupt} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signals_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signals_suite_test.go new file mode 100644 index 00000000000..bae6d72ed5d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/signals/signals_suite_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package signals + +import ( + "os/signal" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Runtime Signal Suite") +} + +var _ = BeforeSuite(func() { + signal.Reset() +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/manager/testdata/custom-config.yaml b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/testdata/custom-config.yaml new file mode 100644 index 00000000000..a15c9f8e5c7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/manager/testdata/custom-config.yaml @@ -0,0 +1,3 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: CustomControllerManagerConfiguration +customValue: foo diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go new file mode 100644 index 00000000000..ff28998c44c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go @@ -0,0 +1,71 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + + "github.com/prometheus/client_golang/prometheus" + clientmetrics "k8s.io/client-go/tools/metrics" +) + +// this file contains setup logic to initialize the myriad of places +// that client-go registers metrics. We copy the names and formats +// from Kubernetes so that we match the core controllers. + +var ( + // client metrics. + + requestResult = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "rest_client_requests_total", + Help: "Number of HTTP requests, partitioned by status code, method, and host.", + }, + []string{"code", "method", "host"}, + ) +) + +func init() { + registerClientMetrics() +} + +// registerClientMetrics sets up the client latency metrics from client-go. +func registerClientMetrics() { + // register the metrics with our registry + Registry.MustRegister(requestResult) + + // register the metrics with client-go + clientmetrics.Register(clientmetrics.RegisterOpts{ + RequestResult: &resultAdapter{metric: requestResult}, + }) +} + +// this section contains adapters, implementations, and other sundry organic, artisanally +// hand-crafted syntax trees required to convince client-go that it actually wants to let +// someone use its metrics. + +// Client metrics adapters (method #1 for client-go metrics), +// copied (more-or-less directly) from k8s.io/kubernetes setup code +// (which isn't anywhere in an easily-importable place). + +type resultAdapter struct { + metric *prometheus.CounterVec +} + +func (r *resultAdapter) Increment(_ context.Context, code, method, host string) { + r.metric.WithLabelValues(code, method, host).Inc() +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go new file mode 100644 index 00000000000..6ed9df95140 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package metrics contains controller related metrics utilities +*/ +package metrics diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go new file mode 100644 index 00000000000..a19c099602e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go @@ -0,0 +1,40 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/tools/leaderelection" +) + +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/clientgo/leaderelection +// which registers metrics to the k8s legacy Registry. We require very +// similar functionality, but must register metrics to a different Registry. + +var ( + leaderGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "leader_election_master_status", + Help: "Gauge of if the reporting system is master of the relevant lease, 0 indicates backup, 1 indicates master. 'name' is the string used to identify the lease. Please make sure to group by name.", + }, []string{"name"}) +) + +func init() { + Registry.MustRegister(leaderGauge) + leaderelection.SetProvider(leaderelectionMetricsProvider{}) +} + +type leaderelectionMetricsProvider struct{} + +func (leaderelectionMetricsProvider) NewLeaderMetric() leaderelection.SwitchMetric { + return &switchAdapter{gauge: leaderGauge} +} + +type switchAdapter struct { + gauge *prometheus.GaugeVec +} + +func (s *switchAdapter) On(name string) { + s.gauge.WithLabelValues(name).Set(1.0) +} + +func (s *switchAdapter) Off(name string) { + s.gauge.WithLabelValues(name).Set(0.0) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/listener.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/listener.go new file mode 100644 index 00000000000..123d8c15f92 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/listener.go @@ -0,0 +1,52 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "fmt" + "net" + + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("metrics") + +// DefaultBindAddress sets the default bind address for the metrics listener +// The metrics is on by default. +var DefaultBindAddress = ":8080" + +// NewListener creates a new TCP listener bound to the given address. +func NewListener(addr string) (net.Listener, error) { + if addr == "" { + // If the metrics bind address is empty, default to ":8080" + addr = DefaultBindAddress + } + + // Add a case to disable metrics altogether + if addr == "0" { + return nil, nil + } + + log.Info("Metrics server is starting to listen", "addr", addr) + ln, err := net.Listen("tcp", addr) + if err != nil { + er := fmt.Errorf("error listening on %s: %w", addr, err) + log.Error(er, "metrics server failed to listen. You may want to disable the metrics server or use another port if it is due to conflicts") + return nil, er + } + return ln, nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go new file mode 100644 index 00000000000..ce17124d535 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go @@ -0,0 +1,30 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import "github.com/prometheus/client_golang/prometheus" + +// RegistererGatherer combines both parts of the API of a Prometheus +// registry, both the Registerer and the Gatherer interfaces. +type RegistererGatherer interface { + prometheus.Registerer + prometheus.Gatherer +} + +// Registry is a prometheus registry for storing metrics within the +// controller-runtime. +var Registry RegistererGatherer = prometheus.NewRegistry() diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go new file mode 100644 index 00000000000..277b8788100 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go @@ -0,0 +1,130 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/util/workqueue" +) + +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/workqueue +// which registers metrics to the k8s legacy Registry. We require very +// similar functionality, but must register metrics to a different Registry. + +// Metrics subsystem and all keys used by the workqueue. +const ( + WorkQueueSubsystem = "workqueue" + DepthKey = "depth" + AddsKey = "adds_total" + QueueLatencyKey = "queue_duration_seconds" + WorkDurationKey = "work_duration_seconds" + UnfinishedWorkKey = "unfinished_work_seconds" + LongestRunningProcessorKey = "longest_running_processor_seconds" + RetriesKey = "retries_total" +) + +var ( + depth = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: DepthKey, + Help: "Current depth of workqueue", + }, []string{"name"}) + + adds = prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: AddsKey, + Help: "Total number of adds handled by workqueue", + }, []string{"name"}) + + latency = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: QueueLatencyKey, + Help: "How long in seconds an item stays in workqueue before being requested", + Buckets: prometheus.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + workDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: WorkDurationKey, + Help: "How long in seconds processing an item from workqueue takes.", + Buckets: prometheus.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + unfinished = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: UnfinishedWorkKey, + Help: "How many seconds of work has been done that " + + "is in progress and hasn't been observed by work_duration. Large " + + "values indicate stuck threads. One can deduce the number of stuck " + + "threads by observing the rate at which this increases.", + }, []string{"name"}) + + longestRunningProcessor = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: LongestRunningProcessorKey, + Help: "How many seconds has the longest running " + + "processor for workqueue been running.", + }, []string{"name"}) + + retries = prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: RetriesKey, + Help: "Total number of retries handled by workqueue", + }, []string{"name"}) +) + +func init() { + Registry.MustRegister(depth) + Registry.MustRegister(adds) + Registry.MustRegister(latency) + Registry.MustRegister(workDuration) + Registry.MustRegister(unfinished) + Registry.MustRegister(longestRunningProcessor) + Registry.MustRegister(retries) + + workqueue.SetProvider(workqueueMetricsProvider{}) +} + +type workqueueMetricsProvider struct{} + +func (workqueueMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric { + return depth.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric { + return adds.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric { + return latency.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric { + return workDuration.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric { + return unfinished.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric { + return longestRunningProcessor.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric { + return retries.WithLabelValues(name) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go new file mode 100644 index 00000000000..e498107ef7f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package predicate defines Predicates used by Controllers to filter Events before they are provided to EventHandlers. +*/ +package predicate diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/example_test.go new file mode 100644 index 00000000000..57a1ce77796 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/example_test.go @@ -0,0 +1,33 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package predicate_test + +import ( + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var p predicate.Predicate + +// This example creates a new Predicate to drop Update Events where the Generation has not changed. +func ExampleFuncs() { + p = predicate.Funcs{ + UpdateFunc: func(e event.UpdateEvent) bool { + return e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration() + }, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go new file mode 100644 index 00000000000..314635875e5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go @@ -0,0 +1,360 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package predicate + +import ( + "reflect" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("predicate").WithName("eventFilters") + +// Predicate filters events before enqueuing the keys. +type Predicate interface { + // Create returns true if the Create event should be processed + Create(event.CreateEvent) bool + + // Delete returns true if the Delete event should be processed + Delete(event.DeleteEvent) bool + + // Update returns true if the Update event should be processed + Update(event.UpdateEvent) bool + + // Generic returns true if the Generic event should be processed + Generic(event.GenericEvent) bool +} + +var _ Predicate = Funcs{} +var _ Predicate = ResourceVersionChangedPredicate{} +var _ Predicate = GenerationChangedPredicate{} +var _ Predicate = AnnotationChangedPredicate{} +var _ Predicate = or{} +var _ Predicate = and{} +var _ Predicate = not{} + +// Funcs is a function that implements Predicate. +type Funcs struct { + // Create returns true if the Create event should be processed + CreateFunc func(event.CreateEvent) bool + + // Delete returns true if the Delete event should be processed + DeleteFunc func(event.DeleteEvent) bool + + // Update returns true if the Update event should be processed + UpdateFunc func(event.UpdateEvent) bool + + // Generic returns true if the Generic event should be processed + GenericFunc func(event.GenericEvent) bool +} + +// Create implements Predicate. +func (p Funcs) Create(e event.CreateEvent) bool { + if p.CreateFunc != nil { + return p.CreateFunc(e) + } + return true +} + +// Delete implements Predicate. +func (p Funcs) Delete(e event.DeleteEvent) bool { + if p.DeleteFunc != nil { + return p.DeleteFunc(e) + } + return true +} + +// Update implements Predicate. +func (p Funcs) Update(e event.UpdateEvent) bool { + if p.UpdateFunc != nil { + return p.UpdateFunc(e) + } + return true +} + +// Generic implements Predicate. +func (p Funcs) Generic(e event.GenericEvent) bool { + if p.GenericFunc != nil { + return p.GenericFunc(e) + } + return true +} + +// NewPredicateFuncs returns a predicate funcs that applies the given filter function +// on CREATE, UPDATE, DELETE and GENERIC events. For UPDATE events, the filter is applied +// to the new object. +func NewPredicateFuncs(filter func(object client.Object) bool) Funcs { + return Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return filter(e.Object) + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return filter(e.ObjectNew) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return filter(e.Object) + }, + GenericFunc: func(e event.GenericEvent) bool { + return filter(e.Object) + }, + } +} + +// ResourceVersionChangedPredicate implements a default update predicate function on resource version change. +type ResourceVersionChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating resource version change. +func (ResourceVersionChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object to update", "event", e) + return false + } + + return e.ObjectNew.GetResourceVersion() != e.ObjectOld.GetResourceVersion() +} + +// GenerationChangedPredicate implements a default update predicate function on Generation change. +// +// This predicate will skip update events that have no change in the object's metadata.generation field. +// The metadata.generation field of an object is incremented by the API server when writes are made to the spec field of an object. +// This allows a controller to ignore update events where the spec is unchanged, and only the metadata and/or status fields are changed. +// +// For CustomResource objects the Generation is only incremented when the status subresource is enabled. +// +// Caveats: +// +// * The assumption that the Generation is incremented only on writing to the spec does not hold for all APIs. +// E.g For Deployment objects the Generation is also incremented on writes to the metadata.annotations field. +// For object types other than CustomResources be sure to verify which fields will trigger a Generation increment when they are written to. +// +// * With this predicate, any update events with writes only to the status field will not be reconciled. +// So in the event that the status block is overwritten or wiped by someone else the controller will not self-correct to restore the correct status. +type GenerationChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating generation change. +func (GenerationChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return e.ObjectNew.GetGeneration() != e.ObjectOld.GetGeneration() +} + +// AnnotationChangedPredicate implements a default update predicate function on annotation change. +// +// This predicate will skip update events that have no change in the object's annotation. +// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: +// +// Controller.Watch( +// &source.Kind{Type: v1.MyCustomKind}, +// &handler.EnqueueRequestForObject{}, +// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{})) +// +// This is mostly useful for controllers that needs to trigger both when the resource's generation is incremented +// (i.e., when the resource' .spec changes), or an annotation changes (e.g., for a staging/alpha API). +type AnnotationChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating annotation change. +func (AnnotationChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return !reflect.DeepEqual(e.ObjectNew.GetAnnotations(), e.ObjectOld.GetAnnotations()) +} + +// LabelChangedPredicate implements a default update predicate function on label change. +// +// This predicate will skip update events that have no change in the object's label. +// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: +// +// Controller.Watch( +// +// &source.Kind{Type: v1.MyCustomKind}, +// &handler.EnqueueRequestForObject{}, +// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})) +// +// This will be helpful when object's labels is carrying some extra specification information beyond object's spec, +// and the controller will be triggered if any valid spec change (not only in spec, but also in labels) happens. +type LabelChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for checking label change. +func (LabelChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return !reflect.DeepEqual(e.ObjectNew.GetLabels(), e.ObjectOld.GetLabels()) +} + +// And returns a composite predicate that implements a logical AND of the predicates passed to it. +func And(predicates ...Predicate) Predicate { + return and{predicates} +} + +type and struct { + predicates []Predicate +} + +func (a and) Create(e event.CreateEvent) bool { + for _, p := range a.predicates { + if !p.Create(e) { + return false + } + } + return true +} + +func (a and) Update(e event.UpdateEvent) bool { + for _, p := range a.predicates { + if !p.Update(e) { + return false + } + } + return true +} + +func (a and) Delete(e event.DeleteEvent) bool { + for _, p := range a.predicates { + if !p.Delete(e) { + return false + } + } + return true +} + +func (a and) Generic(e event.GenericEvent) bool { + for _, p := range a.predicates { + if !p.Generic(e) { + return false + } + } + return true +} + +// Or returns a composite predicate that implements a logical OR of the predicates passed to it. +func Or(predicates ...Predicate) Predicate { + return or{predicates} +} + +type or struct { + predicates []Predicate +} + +func (o or) Create(e event.CreateEvent) bool { + for _, p := range o.predicates { + if p.Create(e) { + return true + } + } + return false +} + +func (o or) Update(e event.UpdateEvent) bool { + for _, p := range o.predicates { + if p.Update(e) { + return true + } + } + return false +} + +func (o or) Delete(e event.DeleteEvent) bool { + for _, p := range o.predicates { + if p.Delete(e) { + return true + } + } + return false +} + +func (o or) Generic(e event.GenericEvent) bool { + for _, p := range o.predicates { + if p.Generic(e) { + return true + } + } + return false +} + +// Not returns a predicate that implements a logical NOT of the predicate passed to it. +func Not(predicate Predicate) Predicate { + return not{predicate} +} + +type not struct { + predicate Predicate +} + +func (n not) Create(e event.CreateEvent) bool { + return !n.predicate.Create(e) +} + +func (n not) Update(e event.UpdateEvent) bool { + return !n.predicate.Update(e) +} + +func (n not) Delete(e event.DeleteEvent) bool { + return !n.predicate.Delete(e) +} + +func (n not) Generic(e event.GenericEvent) bool { + return !n.predicate.Generic(e) +} + +// LabelSelectorPredicate constructs a Predicate from a LabelSelector. +// Only objects matching the LabelSelector will be admitted. +func LabelSelectorPredicate(s metav1.LabelSelector) (Predicate, error) { + selector, err := metav1.LabelSelectorAsSelector(&s) + if err != nil { + return Funcs{}, err + } + return NewPredicateFuncs(func(o client.Object) bool { + return selector.Matches(labels.Set(o.GetLabels())) + }), nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_suite_test.go new file mode 100644 index 00000000000..170594ca528 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_suite_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package predicate_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestPredicate(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Predicate Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_test.go new file mode 100644 index 00000000000..f322b7810b9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/predicate/predicate_test.go @@ -0,0 +1,959 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package predicate_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var _ = Describe("Predicate", func() { + var pod *corev1.Pod + BeforeEach(func() { + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Namespace: "biz", Name: "baz"}, + } + }) + + Describe("Funcs", func() { + failingFuncs := predicate.Funcs{ + CreateFunc: func(event.CreateEvent) bool { + defer GinkgoRecover() + Fail("Did not expect CreateFunc to be called.") + return false + }, + DeleteFunc: func(event.DeleteEvent) bool { + defer GinkgoRecover() + Fail("Did not expect DeleteFunc to be called.") + return false + }, + UpdateFunc: func(event.UpdateEvent) bool { + defer GinkgoRecover() + Fail("Did not expect UpdateFunc to be called.") + return false + }, + GenericFunc: func(event.GenericEvent) bool { + defer GinkgoRecover() + Fail("Did not expect GenericFunc to be called.") + return false + }, + } + + It("should call Create", func() { + instance := failingFuncs + instance.CreateFunc = func(evt event.CreateEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return false + } + evt := event.CreateEvent{ + Object: pod, + } + Expect(instance.Create(evt)).To(BeFalse()) + + instance.CreateFunc = func(evt event.CreateEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return true + } + Expect(instance.Create(evt)).To(BeTrue()) + + instance.CreateFunc = nil + Expect(instance.Create(evt)).To(BeTrue()) + }) + + It("should call Update", func() { + newPod := pod.DeepCopy() + newPod.Name = "baz2" + newPod.Namespace = "biz2" + + instance := failingFuncs + instance.UpdateFunc = func(evt event.UpdateEvent) bool { + defer GinkgoRecover() + Expect(evt.ObjectOld).To(Equal(pod)) + Expect(evt.ObjectNew).To(Equal(newPod)) + return false + } + evt := event.UpdateEvent{ + ObjectOld: pod, + ObjectNew: newPod, + } + Expect(instance.Update(evt)).To(BeFalse()) + + instance.UpdateFunc = func(evt event.UpdateEvent) bool { + defer GinkgoRecover() + Expect(evt.ObjectOld).To(Equal(pod)) + Expect(evt.ObjectNew).To(Equal(newPod)) + return true + } + Expect(instance.Update(evt)).To(BeTrue()) + + instance.UpdateFunc = nil + Expect(instance.Update(evt)).To(BeTrue()) + }) + + It("should call Delete", func() { + instance := failingFuncs + instance.DeleteFunc = func(evt event.DeleteEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return false + } + evt := event.DeleteEvent{ + Object: pod, + } + Expect(instance.Delete(evt)).To(BeFalse()) + + instance.DeleteFunc = func(evt event.DeleteEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return true + } + Expect(instance.Delete(evt)).To(BeTrue()) + + instance.DeleteFunc = nil + Expect(instance.Delete(evt)).To(BeTrue()) + }) + + It("should call Generic", func() { + instance := failingFuncs + instance.GenericFunc = func(evt event.GenericEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return false + } + evt := event.GenericEvent{ + Object: pod, + } + Expect(instance.Generic(evt)).To(BeFalse()) + + instance.GenericFunc = func(evt event.GenericEvent) bool { + defer GinkgoRecover() + Expect(evt.Object).To(Equal(pod)) + return true + } + Expect(instance.Generic(evt)).To(BeTrue()) + + instance.GenericFunc = nil + Expect(instance.Generic(evt)).To(BeTrue()) + }) + }) + + Describe("When checking a ResourceVersionChangedPredicate", func() { + instance := predicate.ResourceVersionChangedPredicate{} + + Context("Where the old object doesn't have a ResourceVersion or metadata", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "1", + }} + + failEvnt := event.UpdateEvent{ + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).Should(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue()) + Expect(instance.Update(failEvnt)).Should(BeFalse()) + }) + }) + + Context("Where the new object doesn't have a ResourceVersion or metadata", func() { + It("should return false", func() { + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "1", + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + } + Expect(instance.Create(event.CreateEvent{})).Should(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue()) + Expect(instance.Update(failEvnt)).Should(BeFalse()) + Expect(instance.Update(failEvnt)).Should(BeFalse()) + }) + }) + + Context("Where the ResourceVersion hasn't changed", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v1", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v1", + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).Should(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue()) + Expect(instance.Update(failEvnt)).Should(BeFalse()) + Expect(instance.Update(failEvnt)).Should(BeFalse()) + }) + }) + + Context("Where the ResourceVersion has changed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v1", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v2", + }} + passEvt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).Should(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue()) + Expect(instance.Update(passEvt)).Should(BeTrue()) + }) + }) + + Context("Where the objects or metadata are missing", func() { + + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v1", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + ResourceVersion: "v1", + }} + + failEvt1 := event.UpdateEvent{ObjectOld: oldPod} + failEvt2 := event.UpdateEvent{ObjectNew: newPod} + failEvt3 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod} + Expect(instance.Create(event.CreateEvent{})).Should(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).Should(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).Should(BeTrue()) + Expect(instance.Update(failEvt1)).Should(BeFalse()) + Expect(instance.Update(failEvt2)).Should(BeFalse()) + Expect(instance.Update(failEvt3)).Should(BeFalse()) + }) + }) + + }) + + Describe("When checking a GenerationChangedPredicate", func() { + instance := predicate.GenerationChangedPredicate{} + Context("Where the old object doesn't have a Generation or metadata", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + failEvnt := event.UpdateEvent{ + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the new object doesn't have a Generation or metadata", func() { + It("should return false", func() { + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the Generation hasn't changed", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the Generation has changed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 2, + }} + passEvt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(passEvt)).To(BeTrue()) + }) + }) + + Context("Where the objects or metadata are missing", func() { + + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Generation: 1, + }} + + failEvt1 := event.UpdateEvent{ObjectOld: oldPod} + failEvt2 := event.UpdateEvent{ObjectNew: newPod} + failEvt3 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod} + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvt1)).To(BeFalse()) + Expect(instance.Update(failEvt2)).To(BeFalse()) + Expect(instance.Update(failEvt3)).To(BeFalse()) + }) + }) + + }) + + // AnnotationChangedPredicate has almost identical test cases as LabelChangedPredicates, + // so the duplication linter should be muted on both two test suites. + Describe("When checking an AnnotationChangedPredicate", func() { + instance := predicate.AnnotationChangedPredicate{} + Context("Where the old object is missing", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + failEvnt := event.UpdateEvent{ + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the new object is missing", func() { + It("should return false", func() { + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the annotations are empty", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where the annotations haven't changed", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + failEvnt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(failEvnt)).To(BeFalse()) + }) + }) + + Context("Where an annotation value has changed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "weez", + }, + }} + + passEvt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(passEvt)).To(BeTrue()) + }) + }) + + Context("Where an annotation has been added", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + "zooz": "qooz", + }, + }} + + passEvt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(passEvt)).To(BeTrue()) + }) + }) + + Context("Where an annotation has been removed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + "zooz": "qooz", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Annotations: map[string]string{ + "booz": "wooz", + }, + }} + + passEvt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(passEvt)).To(BeTrue()) + }) + }) + }) + + // LabelChangedPredicates has almost identical test cases as AnnotationChangedPredicates, + // so the duplication linter should be muted on both two test suites. + Describe("When checking a LabelChangedPredicate", func() { + instance := predicate.LabelChangedPredicate{} + Context("Where the old object is missing", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + evt := event.UpdateEvent{ + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeFalse()) + }) + }) + + Context("Where the new object is missing", func() { + It("should return false", func() { + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeFalse()) + }) + }) + + Context("Where the labels are empty", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeFalse()) + }) + }) + + Context("Where the labels haven't changed", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeFalse()) + }) + }) + + Context("Where a label value has changed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bee", + }, + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeTrue()) + }) + }) + + Context("Where a label has been added", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + "faa": "bor", + }, + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeTrue()) + }) + }) + + Context("Where a label has been removed", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + "faa": "bor", + }, + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + Labels: map[string]string{ + "foo": "bar", + }, + }} + + evt := event.UpdateEvent{ + ObjectOld: oldPod, + ObjectNew: newPod, + } + Expect(instance.Create(event.CreateEvent{})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{})).To(BeTrue()) + Expect(instance.Update(evt)).To(BeTrue()) + }) + }) + }) + + Context("With a boolean predicate", func() { + funcs := func(pass bool) predicate.Funcs { + return predicate.Funcs{ + CreateFunc: func(event.CreateEvent) bool { + return pass + }, + DeleteFunc: func(event.DeleteEvent) bool { + return pass + }, + UpdateFunc: func(event.UpdateEvent) bool { + return pass + }, + GenericFunc: func(event.GenericEvent) bool { + return pass + }, + } + } + passFuncs := funcs(true) + failFuncs := funcs(false) + + Describe("When checking an And predicate", func() { + It("should return false when one of its predicates returns false", func() { + a := predicate.And(passFuncs, failFuncs) + Expect(a.Create(event.CreateEvent{})).To(BeFalse()) + Expect(a.Update(event.UpdateEvent{})).To(BeFalse()) + Expect(a.Delete(event.DeleteEvent{})).To(BeFalse()) + Expect(a.Generic(event.GenericEvent{})).To(BeFalse()) + }) + It("should return true when all of its predicates return true", func() { + a := predicate.And(passFuncs, passFuncs) + Expect(a.Create(event.CreateEvent{})).To(BeTrue()) + Expect(a.Update(event.UpdateEvent{})).To(BeTrue()) + Expect(a.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(a.Generic(event.GenericEvent{})).To(BeTrue()) + }) + }) + Describe("When checking an Or predicate", func() { + It("should return true when one of its predicates returns true", func() { + o := predicate.Or(passFuncs, failFuncs) + Expect(o.Create(event.CreateEvent{})).To(BeTrue()) + Expect(o.Update(event.UpdateEvent{})).To(BeTrue()) + Expect(o.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(o.Generic(event.GenericEvent{})).To(BeTrue()) + }) + It("should return false when all of its predicates return false", func() { + o := predicate.Or(failFuncs, failFuncs) + Expect(o.Create(event.CreateEvent{})).To(BeFalse()) + Expect(o.Update(event.UpdateEvent{})).To(BeFalse()) + Expect(o.Delete(event.DeleteEvent{})).To(BeFalse()) + Expect(o.Generic(event.GenericEvent{})).To(BeFalse()) + }) + }) + Describe("When checking a Not predicate", func() { + It("should return false when its predicate returns true", func() { + n := predicate.Not(passFuncs) + Expect(n.Create(event.CreateEvent{})).To(BeFalse()) + Expect(n.Update(event.UpdateEvent{})).To(BeFalse()) + Expect(n.Delete(event.DeleteEvent{})).To(BeFalse()) + Expect(n.Generic(event.GenericEvent{})).To(BeFalse()) + }) + It("should return true when its predicate returns false", func() { + n := predicate.Not(failFuncs) + Expect(n.Create(event.CreateEvent{})).To(BeTrue()) + Expect(n.Update(event.UpdateEvent{})).To(BeTrue()) + Expect(n.Delete(event.DeleteEvent{})).To(BeTrue()) + Expect(n.Generic(event.GenericEvent{})).To(BeTrue()) + }) + }) + }) + + Describe("NewPredicateFuncs with a namespace filter function", func() { + byNamespaceFilter := func(namespace string) func(object client.Object) bool { + return func(object client.Object) bool { + return object.GetNamespace() == namespace + } + } + byNamespaceFuncs := predicate.NewPredicateFuncs(byNamespaceFilter("biz")) + Context("Where the namespace is matching", func() { + It("should return true", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + passEvt1 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod} + Expect(byNamespaceFuncs.Create(event.CreateEvent{Object: newPod})).To(BeTrue()) + Expect(byNamespaceFuncs.Delete(event.DeleteEvent{Object: oldPod})).To(BeTrue()) + Expect(byNamespaceFuncs.Generic(event.GenericEvent{Object: newPod})).To(BeTrue()) + Expect(byNamespaceFuncs.Update(passEvt1)).To(BeTrue()) + }) + }) + + Context("Where the namespace is not matching", func() { + It("should return false", func() { + newPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "bizz", + }} + + oldPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "baz", + Namespace: "biz", + }} + failEvt1 := event.UpdateEvent{ObjectOld: oldPod, ObjectNew: newPod} + Expect(byNamespaceFuncs.Create(event.CreateEvent{Object: newPod})).To(BeFalse()) + Expect(byNamespaceFuncs.Delete(event.DeleteEvent{Object: newPod})).To(BeFalse()) + Expect(byNamespaceFuncs.Generic(event.GenericEvent{Object: newPod})).To(BeFalse()) + Expect(byNamespaceFuncs.Update(failEvt1)).To(BeFalse()) + }) + }) + }) + + Describe("When checking a LabelSelectorPredicate", func() { + instance, err := predicate.LabelSelectorPredicate(metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}) + if err != nil { + Fail("Improper Label Selector passed during predicate instantiation.") + } + + Context("When the Selector does not match the event labels", func() { + It("should return false", func() { + failMatch := &corev1.Pod{} + Expect(instance.Create(event.CreateEvent{Object: failMatch})).To(BeFalse()) + Expect(instance.Delete(event.DeleteEvent{Object: failMatch})).To(BeFalse()) + Expect(instance.Generic(event.GenericEvent{Object: failMatch})).To(BeFalse()) + Expect(instance.Update(event.UpdateEvent{ObjectNew: failMatch})).To(BeFalse()) + }) + }) + + Context("When the Selector matches the event labels", func() { + It("should return true", func() { + successMatch := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"foo": "bar"}, + }, + } + Expect(instance.Create(event.CreateEvent{Object: successMatch})).To(BeTrue()) + Expect(instance.Delete(event.DeleteEvent{Object: successMatch})).To(BeTrue()) + Expect(instance.Generic(event.GenericEvent{Object: successMatch})).To(BeTrue()) + Expect(instance.Update(event.UpdateEvent{ObjectNew: successMatch})).To(BeTrue()) + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go new file mode 100644 index 00000000000..a01d603fe5b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package ratelimiter defines rate limiters used by Controllers to limit how frequently requests may be queued. + +Typical rate limiters that can be used are implemented in client-go's workqueue package. +*/ +package ratelimiter diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go b/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go new file mode 100644 index 00000000000..565a3a227f1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go @@ -0,0 +1,30 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ratelimiter + +import "time" + +// RateLimiter is an identical interface of client-go workqueue RateLimiter. +type RateLimiter interface { + // When gets an item and gets to decide how long that item should wait + When(item interface{}) time.Duration + // Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing + // or for success, we'll stop tracking it + Forget(item interface{}) + // NumRequeues returns back how many failures the item has had + NumRequeues(item interface{}) int +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go new file mode 100644 index 00000000000..d221dd7b3f4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package reconcile defines the Reconciler interface to implement Kubernetes APIs. Reconciler is provided +to Controllers at creation time as the API implementation. +*/ +package reconcile diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/example_test.go new file mode 100644 index 00000000000..2b799df90d7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/example_test.go @@ -0,0 +1,42 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconcile_test + +import ( + "context" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// This example implements a simple no-op reconcile function that prints the object to be Reconciled. +func ExampleFunc() { + r := reconcile.Func(func(_ context.Context, o reconcile.Request) (reconcile.Result, error) { + // Create your business logic to create, update, delete objects here. + fmt.Printf("Name: %s, Namespace: %s", o.Name, o.Namespace) + return reconcile.Result{}, nil + }) + + res, err := r.Reconcile(context.Background(), reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "default", Name: "test"}}) + if err != nil || res.Requeue || res.RequeueAfter != time.Duration(0) { + fmt.Printf("got requeue request: %v, %v\n", err, res) + } + + // Output: Name: test, Namespace: default +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go new file mode 100644 index 00000000000..d51cfc34ab9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go @@ -0,0 +1,126 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconcile + +import ( + "context" + "errors" + "time" + + "k8s.io/apimachinery/pkg/types" +) + +// Result contains the result of a Reconciler invocation. +type Result struct { + // Requeue tells the Controller to requeue the reconcile key. Defaults to false. + Requeue bool + + // RequeueAfter if greater than 0, tells the Controller to requeue the reconcile key after the Duration. + // Implies that Requeue is true, there is no need to set Requeue to true at the same time as RequeueAfter. + RequeueAfter time.Duration +} + +// IsZero returns true if this result is empty. +func (r *Result) IsZero() bool { + if r == nil { + return true + } + return *r == Result{} +} + +// Request contains the information necessary to reconcile a Kubernetes object. This includes the +// information to uniquely identify the object - its Name and Namespace. It does NOT contain information about +// any specific Event or the object contents itself. +type Request struct { + // NamespacedName is the name and namespace of the object to reconcile. + types.NamespacedName +} + +/* +Reconciler implements a Kubernetes API for a specific Resource by Creating, Updating or Deleting Kubernetes +objects, or by making changes to systems external to the cluster (e.g. cloudproviders, github, etc). + +reconcile implementations compare the state specified in an object by a user against the actual cluster state, +and then perform operations to make the actual cluster state reflect the state specified by the user. + +Typically, reconcile is triggered by a Controller in response to cluster Events (e.g. Creating, Updating, +Deleting Kubernetes objects) or external Events (GitHub Webhooks, polling external sources, etc). + +Example reconcile Logic: + +* Read an object and all the Pods it owns. +* Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica. +* Create 4 Pods and set their OwnerReferences to the object. + +reconcile may be implemented as either a type: + + type reconciler struct {} + + func (reconciler) Reconcile(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { + // Implement business logic of reading and writing objects here + return reconcile.Result{}, nil + } + +Or as a function: + + reconcile.Func(func(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { + // Implement business logic of reading and writing objects here + return reconcile.Result{}, nil + }) + +Reconciliation is level-based, meaning action isn't driven off changes in individual Events, but instead is +driven by actual cluster state read from the apiserver or a local cache. +For example if responding to a Pod Delete Event, the Request won't contain that a Pod was deleted, +instead the reconcile function observes this when reading the cluster state and seeing the Pod as missing. +*/ +type Reconciler interface { + // Reconcile performs a full reconciliation for the object referred to by the Request. + // The Controller will requeue the Request to be processed again if an error is non-nil or + // Result.Requeue is true, otherwise upon completion it will remove the work from the queue. + Reconcile(context.Context, Request) (Result, error) +} + +// Func is a function that implements the reconcile interface. +type Func func(context.Context, Request) (Result, error) + +var _ Reconciler = Func(nil) + +// Reconcile implements Reconciler. +func (r Func) Reconcile(ctx context.Context, o Request) (Result, error) { return r(ctx, o) } + +// TerminalError is an error that will not be retried but still be logged +// and recorded in metrics. +func TerminalError(wrapped error) error { + return &terminalError{err: wrapped} +} + +type terminalError struct { + err error +} + +func (te *terminalError) Unwrap() error { + return te.err +} + +func (te *terminalError) Error() string { + return "terminal error: " + te.err.Error() +} + +func (te *terminalError) Is(target error) bool { + tp := &terminalError{} + return errors.As(target, &tp) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_suite_test.go new file mode 100644 index 00000000000..9bab444ebd9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_suite_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconcile_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestReconcile(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Reconcile Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_test.go new file mode 100644 index 00000000000..b5660f1b4fe --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile_test.go @@ -0,0 +1,100 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconcile_test + +import ( + "context" + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var _ = Describe("reconcile", func() { + Describe("Result", func() { + It("IsZero should return true if empty", func() { + var res *reconcile.Result + Expect(res.IsZero()).To(BeTrue()) + res2 := &reconcile.Result{} + Expect(res2.IsZero()).To(BeTrue()) + res3 := reconcile.Result{} + Expect(res3.IsZero()).To(BeTrue()) + }) + + It("IsZero should return false if Requeue is set to true", func() { + res := reconcile.Result{Requeue: true} + Expect(res.IsZero()).To(BeFalse()) + }) + + It("IsZero should return false if RequeueAfter is set to true", func() { + res := reconcile.Result{RequeueAfter: 1 * time.Second} + Expect(res.IsZero()).To(BeFalse()) + }) + }) + + Describe("Func", func() { + It("should call the function with the request and return a nil error.", func() { + request := reconcile.Request{ + NamespacedName: types.NamespacedName{Name: "foo", Namespace: "bar"}, + } + result := reconcile.Result{ + Requeue: true, + } + + instance := reconcile.Func(func(_ context.Context, r reconcile.Request) (reconcile.Result, error) { + defer GinkgoRecover() + Expect(r).To(Equal(request)) + + return result, nil + }) + actualResult, actualErr := instance.Reconcile(context.Background(), request) + Expect(actualResult).To(Equal(result)) + Expect(actualErr).NotTo(HaveOccurred()) + }) + + It("should call the function with the request and return an error.", func() { + request := reconcile.Request{ + NamespacedName: types.NamespacedName{Name: "foo", Namespace: "bar"}, + } + result := reconcile.Result{ + Requeue: false, + } + err := fmt.Errorf("hello world") + + instance := reconcile.Func(func(_ context.Context, r reconcile.Request) (reconcile.Result, error) { + defer GinkgoRecover() + Expect(r).To(Equal(request)) + + return result, err + }) + actualResult, actualErr := instance.Reconcile(context.Background(), request) + Expect(actualResult).To(Equal(result)) + Expect(actualErr).To(Equal(err)) + }) + + It("should allow unwrapping inner error from terminal error", func() { + inner := apierrors.NewGone("") + terminalError := reconcile.TerminalError(inner) + + Expect(apierrors.IsGone(terminalError)).To(BeTrue()) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/example_test.go new file mode 100644 index 00000000000..969420d8170 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/example_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package recorder_test + +import ( + corev1 "k8s.io/api/core/v1" + + _ "github.com/onsi/ginkgo/v2" + "sigs.k8s.io/controller-runtime/pkg/recorder" +) + +var ( + recorderProvider recorder.Provider + somePod *corev1.Pod // the object you're reconciling, for example +) + +func Example_event() { + // recorderProvider is a recorder.Provider + recorder := recorderProvider.GetEventRecorderFor("my-controller") + + // emit an event with a fixed message + recorder.Event(somePod, corev1.EventTypeWarning, + "WrongTrousers", "It's the wrong trousers, Gromit!") +} + +func Example_eventf() { + // recorderProvider is a recorder.Provider + recorder := recorderProvider.GetEventRecorderFor("my-controller") + + // emit an event with a variable message + mildCheese := "Wensleydale" + recorder.Eventf(somePod, corev1.EventTypeNormal, + "DislikesCheese", "Not even %s?", mildCheese) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go b/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go new file mode 100644 index 00000000000..f093f0a7266 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go @@ -0,0 +1,31 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package recorder defines interfaces for working with Kubernetes event recorders. +// +// You can use these to emit Kubernetes events associated with a particular Kubernetes +// object. +package recorder + +import ( + "k8s.io/client-go/tools/record" +) + +// Provider knows how to generate new event recorders with given name. +type Provider interface { + // NewRecorder returns an EventRecorder with given name. + GetEventRecorderFor(name string) record.EventRecorder +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go new file mode 100644 index 00000000000..55ebe217735 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go @@ -0,0 +1,93 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package scheme contains utilities for gradually building Schemes, +// which contain information associating Go types with Kubernetes +// groups, versions, and kinds. +// +// Each API group should define a utility function +// called AddToScheme for adding its types to a Scheme: +// +// // in package myapigroupv1... +// var ( +// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"} +// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} +// AddToScheme = SchemeBuilder.AddToScheme +// ) +// +// func init() { +// SchemeBuilder.Register(&MyType{}, &MyTypeList) +// } +// var ( +// scheme *runtime.Scheme = runtime.NewScheme() +// ) +// +// This also true of the built-in Kubernetes types. Then, in the entrypoint for +// your manager, assemble the scheme containing exactly the types you need, +// panicing if scheme registration failed. For instance, if our controller needs +// types from the core/v1 API group (e.g. Pod), plus types from my.api.group/v1: +// +// func init() { +// utilruntime.Must(myapigroupv1.AddToScheme(scheme)) +// utilruntime.Must(kubernetesscheme.AddToScheme(scheme)) +// } +// +// func main() { +// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{ +// Scheme: scheme, +// }) +// // ... +// } +package scheme + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// Builder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds. +type Builder struct { + GroupVersion schema.GroupVersion + runtime.SchemeBuilder +} + +// Register adds one or more objects to the SchemeBuilder so they can be added to a Scheme. Register mutates bld. +func (bld *Builder) Register(object ...runtime.Object) *Builder { + bld.SchemeBuilder.Register(func(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(bld.GroupVersion, object...) + metav1.AddToGroupVersion(scheme, bld.GroupVersion) + return nil + }) + return bld +} + +// RegisterAll registers all types from the Builder argument. RegisterAll mutates bld. +func (bld *Builder) RegisterAll(b *Builder) *Builder { + bld.SchemeBuilder = append(bld.SchemeBuilder, b.SchemeBuilder...) + return bld +} + +// AddToScheme adds all registered types to s. +func (bld *Builder) AddToScheme(s *runtime.Scheme) error { + return bld.SchemeBuilder.AddToScheme(s) +} + +// Build returns a new Scheme containing the registered types. +func (bld *Builder) Build() (*runtime.Scheme, error) { + s := runtime.NewScheme() + return s, bld.AddToScheme(s) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_suite_test.go new file mode 100644 index 00000000000..36ddd9decc8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scheme_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestScheme(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Scheme Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_test.go new file mode 100644 index 00000000000..37c6766e6f2 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/scheme/scheme_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scheme_test + +import ( + "reflect" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var _ = Describe("Scheme", func() { + Describe("Builder", func() { + It("should provide a Scheme with the types registered", func() { + gv := schema.GroupVersion{Group: "core", Version: "v1"} + + s, err := (&scheme.Builder{GroupVersion: gv}). + Register(&corev1.Pod{}, &corev1.PodList{}). + Build() + Expect(err).NotTo(HaveOccurred()) + + internalGv := schema.GroupVersion{Group: "core", Version: "__internal"} + emptyGv := schema.GroupVersion{Group: "", Version: "v1"} + Expect(s.AllKnownTypes()).To(MatchAllKeys(Keys{ + gv.WithKind("Pod"): Equal(reflect.TypeOf(corev1.Pod{})), + gv.WithKind("PodList"): Equal(reflect.TypeOf(corev1.PodList{})), + + // Base types + gv.WithKind("CreateOptions"): Ignore(), + gv.WithKind("UpdateOptions"): Ignore(), + gv.WithKind("PatchOptions"): Ignore(), + gv.WithKind("DeleteOptions"): Ignore(), + gv.WithKind("GetOptions"): Ignore(), + gv.WithKind("ListOptions"): Ignore(), + gv.WithKind("WatchEvent"): Ignore(), + + internalGv.WithKind("WatchEvent"): Ignore(), + + emptyGv.WithKind("APIGroup"): Ignore(), + emptyGv.WithKind("APIGroupList"): Ignore(), + emptyGv.WithKind("APIResourceList"): Ignore(), + emptyGv.WithKind("APIVersions"): Ignore(), + emptyGv.WithKind("Status"): Ignore(), + })) + }) + + It("should be able to add types from other Builders", func() { + gv1 := schema.GroupVersion{Group: "core", Version: "v1"} + b1 := (&scheme.Builder{GroupVersion: gv1}).Register(&corev1.Pod{}, &corev1.PodList{}) + + gv2 := schema.GroupVersion{Group: "apps", Version: "v1"} + s, err := (&scheme.Builder{GroupVersion: gv2}). + Register(&appsv1.Deployment{}). + Register(&appsv1.DeploymentList{}). + RegisterAll(b1). + Build() + + Expect(err).NotTo(HaveOccurred()) + internalGv1 := schema.GroupVersion{Group: "core", Version: "__internal"} + internalGv2 := schema.GroupVersion{Group: "apps", Version: "__internal"} + emptyGv := schema.GroupVersion{Group: "", Version: "v1"} + Expect(s.AllKnownTypes()).To(MatchAllKeys(Keys{ + // Types from b1 + gv1.WithKind("Pod"): Equal(reflect.TypeOf(corev1.Pod{})), + gv1.WithKind("PodList"): Equal(reflect.TypeOf(corev1.PodList{})), + + // Types from b2 + gv2.WithKind("Deployment"): Equal(reflect.TypeOf(appsv1.Deployment{})), + gv2.WithKind("DeploymentList"): Equal(reflect.TypeOf(appsv1.DeploymentList{})), + + // Base types + gv1.WithKind("CreateOptions"): Ignore(), + gv1.WithKind("UpdateOptions"): Ignore(), + gv1.WithKind("PatchOptions"): Ignore(), + gv1.WithKind("DeleteOptions"): Ignore(), + gv1.WithKind("GetOptions"): Ignore(), + gv1.WithKind("ListOptions"): Ignore(), + gv1.WithKind("WatchEvent"): Ignore(), + + internalGv1.WithKind("WatchEvent"): Ignore(), + + gv2.WithKind("CreateOptions"): Ignore(), + gv2.WithKind("UpdateOptions"): Ignore(), + gv2.WithKind("PatchOptions"): Ignore(), + gv2.WithKind("DeleteOptions"): Ignore(), + gv2.WithKind("GetOptions"): Ignore(), + gv2.WithKind("ListOptions"): Ignore(), + gv2.WithKind("WatchEvent"): Ignore(), + + internalGv2.WithKind("WatchEvent"): Ignore(), + + emptyGv.WithKind("APIGroup"): Ignore(), + emptyGv.WithKind("APIGroupList"): Ignore(), + emptyGv.WithKind("APIResourceList"): Ignore(), + emptyGv.WithKind("APIVersions"): Ignore(), + emptyGv.WithKind("Status"): Ignore(), + })) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/doc.go new file mode 100644 index 00000000000..31935c83c18 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package source provides event streams to hook up to Controllers with Controller.Watch. Events are +used with handler.EventHandlers to enqueue reconcile.Requests and trigger Reconciles for Kubernetes +objects. +*/ +package source diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/example_test.go new file mode 100644 index 00000000000..77857729dec --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/example_test.go @@ -0,0 +1,52 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source_test + +import ( + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var mgr manager.Manager +var ctrl controller.Controller + +// This example Watches for Pod Events (e.g. Create / Update / Delete) and enqueues a reconcile.Request +// with the Name and Namespace of the Pod. +func ExampleKind() { + err := ctrl.Watch(source.Kind(mgr.GetCache(), &corev1.Pod{}), &handler.EnqueueRequestForObject{}) + if err != nil { + // handle it + } +} + +// This example reads GenericEvents from a channel and enqueues a reconcile.Request containing the Name and Namespace +// provided by the event. +func ExampleChannel() { + events := make(chan event.GenericEvent) + + err := ctrl.Watch( + &source.Channel{Source: events}, + &handler.EnqueueRequestForObject{}, + ) + if err != nil { + // handle it + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/source.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source.go new file mode 100644 index 00000000000..099c8d68fa4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source.go @@ -0,0 +1,225 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "context" + "fmt" + "sync" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + internal "sigs.k8s.io/controller-runtime/pkg/internal/source" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +const ( + // defaultBufferSize is the default number of event notifications that can be buffered. + defaultBufferSize = 1024 +) + +// Source is a source of events (eh.g. Create, Update, Delete operations on Kubernetes Objects, Webhook callbacks, etc) +// which should be processed by event.EventHandlers to enqueue reconcile.Requests. +// +// * Use Kind for events originating in the cluster (e.g. Pod Create, Pod Update, Deployment Update). +// +// * Use Channel for events originating outside the cluster (eh.g. GitHub Webhook callback, Polling external urls). +// +// Users may build their own Source implementations. +type Source interface { + // Start is internal and should be called only by the Controller to register an EventHandler with the Informer + // to enqueue reconcile.Requests. + Start(context.Context, handler.EventHandler, workqueue.RateLimitingInterface, ...predicate.Predicate) error +} + +// SyncingSource is a source that needs syncing prior to being usable. The controller +// will call its WaitForSync prior to starting workers. +type SyncingSource interface { + Source + WaitForSync(ctx context.Context) error +} + +// Kind creates a KindSource with the given cache provider. +func Kind(cache cache.Cache, object client.Object) SyncingSource { + return &internal.Kind{Type: object, Cache: cache} +} + +var _ Source = &Channel{} + +// Channel is used to provide a source of events originating outside the cluster +// (e.g. GitHub Webhook callback). Channel requires the user to wire the external +// source (eh.g. http handler) to write GenericEvents to the underlying channel. +type Channel struct { + // once ensures the event distribution goroutine will be performed only once + once sync.Once + + // Source is the source channel to fetch GenericEvents + Source <-chan event.GenericEvent + + // dest is the destination channels of the added event handlers + dest []chan event.GenericEvent + + // DestBufferSize is the specified buffer size of dest channels. + // Default to 1024 if not specified. + DestBufferSize int + + // destLock is to ensure the destination channels are safely added/removed + destLock sync.Mutex +} + +func (cs *Channel) String() string { + return fmt.Sprintf("channel source: %p", cs) +} + +// Start implements Source and should only be called by the Controller. +func (cs *Channel) Start( + ctx context.Context, + handler handler.EventHandler, + queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + // Source should have been specified by the user. + if cs.Source == nil { + return fmt.Errorf("must specify Channel.Source") + } + + // use default value if DestBufferSize not specified + if cs.DestBufferSize == 0 { + cs.DestBufferSize = defaultBufferSize + } + + dst := make(chan event.GenericEvent, cs.DestBufferSize) + + cs.destLock.Lock() + cs.dest = append(cs.dest, dst) + cs.destLock.Unlock() + + cs.once.Do(func() { + // Distribute GenericEvents to all EventHandler / Queue pairs Watching this source + go cs.syncLoop(ctx) + }) + + go func() { + for evt := range dst { + shouldHandle := true + for _, p := range prct { + if !p.Generic(evt) { + shouldHandle = false + break + } + } + + if shouldHandle { + func() { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + handler.Generic(ctx, evt, queue) + }() + } + } + }() + + return nil +} + +func (cs *Channel) doStop() { + cs.destLock.Lock() + defer cs.destLock.Unlock() + + for _, dst := range cs.dest { + close(dst) + } +} + +func (cs *Channel) distribute(evt event.GenericEvent) { + cs.destLock.Lock() + defer cs.destLock.Unlock() + + for _, dst := range cs.dest { + // We cannot make it under goroutine here, or we'll meet the + // race condition of writing message to closed channels. + // To avoid blocking, the dest channels are expected to be of + // proper buffer size. If we still see it blocked, then + // the controller is thought to be in an abnormal state. + dst <- evt + } +} + +func (cs *Channel) syncLoop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + // Close destination channels + cs.doStop() + return + case evt, stillOpen := <-cs.Source: + if !stillOpen { + // if the source channel is closed, we're never gonna get + // anything more on it, so stop & bail + cs.doStop() + return + } + cs.distribute(evt) + } + } +} + +// Informer is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). +type Informer struct { + // Informer is the controller-runtime Informer + Informer cache.Informer +} + +var _ Source = &Informer{} + +// Start is internal and should be called only by the Controller to register an EventHandler with the Informer +// to enqueue reconcile.Requests. +func (is *Informer) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + // Informer should have been specified by the user. + if is.Informer == nil { + return fmt.Errorf("must specify Informer.Informer") + } + + _, err := is.Informer.AddEventHandler(internal.NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + return err + } + return nil +} + +func (is *Informer) String() string { + return fmt.Sprintf("informer source: %p", is.Informer) +} + +var _ Source = Func(nil) + +// Func is a function that implements Source. +type Func func(context.Context, handler.EventHandler, workqueue.RateLimitingInterface, ...predicate.Predicate) error + +// Start implements Source. +func (f Func) Start(ctx context.Context, evt handler.EventHandler, queue workqueue.RateLimitingInterface, + pr ...predicate.Predicate) error { + return f(ctx, evt, queue, pr...) +} + +func (f Func) String() string { + return fmt.Sprintf("func source: %p", f) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_integration_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_integration_test.go new file mode 100644 index 00000000000..594d3c9a9cd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_integration_test.go @@ -0,0 +1,347 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source_test + +import ( + "context" + "fmt" + "time" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/source" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kubeinformers "k8s.io/client-go/informers" + toolscache "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +var _ = Describe("Source", func() { + var instance1, instance2 source.Source + var obj client.Object + var q workqueue.RateLimitingInterface + var c1, c2 chan interface{} + var ns string + count := 0 + + BeforeEach(func() { + // Create the namespace for the test + ns = fmt.Sprintf("controller-source-kindsource-%v", count) + count++ + _, err := clientset.CoreV1().Namespaces().Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{Name: ns}, + }, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + q = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + c1 = make(chan interface{}) + c2 = make(chan interface{}) + }) + + JustBeforeEach(func() { + instance1 = source.Kind(icache, obj) + instance2 = source.Kind(icache, obj) + }) + + AfterEach(func() { + err := clientset.CoreV1().Namespaces().Delete(ctx, ns, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + close(c1) + close(c2) + }) + + Describe("Kind", func() { + Context("for a Deployment resource", func() { + obj = &appsv1.Deployment{} + + It("should provide Deployment Events", func() { + var created, updated, deleted *appsv1.Deployment + var err error + + // Get the client and Deployment used to create events + client := clientset.AppsV1().Deployments(ns) + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "deployment-name"}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + + // Create an event handler to verify the events + newHandler := func(c chan interface{}) handler.Funcs { + return handler.Funcs{ + CreateFunc: func(ctx context.Context, evt event.CreateEvent, rli workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(rli).To(Equal(q)) + c <- evt + }, + UpdateFunc: func(ctx context.Context, evt event.UpdateEvent, rli workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(rli).To(Equal(q)) + c <- evt + }, + DeleteFunc: func(ctx context.Context, evt event.DeleteEvent, rli workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(rli).To(Equal(q)) + c <- evt + }, + } + } + handler1 := newHandler(c1) + handler2 := newHandler(c2) + + // Create 2 instances + Expect(instance1.Start(ctx, handler1, q)).To(Succeed()) + Expect(instance2.Start(ctx, handler2, q)).To(Succeed()) + + By("Creating a Deployment and expecting the CreateEvent.") + created, err = client.Create(ctx, deployment, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + Expect(created).NotTo(BeNil()) + + // Check first CreateEvent + evt := <-c1 + createEvt, ok := evt.(event.CreateEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.CreateEvent{})) + Expect(createEvt.Object).To(Equal(created)) + + // Check second CreateEvent + evt = <-c2 + createEvt, ok = evt.(event.CreateEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.CreateEvent{})) + Expect(createEvt.Object).To(Equal(created)) + + By("Updating a Deployment and expecting the UpdateEvent.") + updated = created.DeepCopy() + updated.Labels = map[string]string{"biz": "buz"} + updated, err = client.Update(ctx, updated, metav1.UpdateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + // Check first UpdateEvent + evt = <-c1 + updateEvt, ok := evt.(event.UpdateEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.UpdateEvent{})) + + Expect(updateEvt.ObjectNew).To(Equal(updated)) + + Expect(updateEvt.ObjectOld).To(Equal(created)) + + // Check second UpdateEvent + evt = <-c2 + updateEvt, ok = evt.(event.UpdateEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.UpdateEvent{})) + + Expect(updateEvt.ObjectNew).To(Equal(updated)) + + Expect(updateEvt.ObjectOld).To(Equal(created)) + + By("Deleting a Deployment and expecting the Delete.") + deleted = updated.DeepCopy() + err = client.Delete(ctx, created.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + + deleted.SetResourceVersion("") + evt = <-c1 + deleteEvt, ok := evt.(event.DeleteEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.DeleteEvent{})) + deleteEvt.Object.SetResourceVersion("") + Expect(deleteEvt.Object).To(Equal(deleted)) + + evt = <-c2 + deleteEvt, ok = evt.(event.DeleteEvent) + Expect(ok).To(BeTrue(), fmt.Sprintf("expect %T to be %T", evt, event.DeleteEvent{})) + deleteEvt.Object.SetResourceVersion("") + Expect(deleteEvt.Object).To(Equal(deleted)) + }) + }) + + // TODO(pwittrock): Write this test + PContext("for a Foo CRD resource", func() { + It("should provide Foo Events", func() { + + }) + }) + }) + + Describe("Informer", func() { + var c chan struct{} + var rs *appsv1.ReplicaSet + var depInformer toolscache.SharedIndexInformer + var informerFactory kubeinformers.SharedInformerFactory + var stopTest chan struct{} + + BeforeEach(func() { + stopTest = make(chan struct{}) + informerFactory = kubeinformers.NewSharedInformerFactory(clientset, time.Second*30) + depInformer = informerFactory.Apps().V1().ReplicaSets().Informer() + informerFactory.Start(stopTest) + Eventually(depInformer.HasSynced).Should(BeTrue()) + + c = make(chan struct{}) + rs = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{Name: "informer-rs-name"}, + Spec: appsv1.ReplicaSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + }) + + AfterEach(func() { + close(stopTest) + }) + + Context("for a ReplicaSet resource", func() { + It("should provide a ReplicaSet CreateEvent", func() { + c := make(chan struct{}) + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Informer{Informer: depInformer} + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(ctx context.Context, evt event.CreateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + var err error + rs, err := clientset.AppsV1().ReplicaSets("default").Get(ctx, rs.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.Object).To(Equal(rs)) + close(c) + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + _, err = clientset.AppsV1().ReplicaSets("default").Create(ctx, rs, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + <-c + }) + + It("should provide a ReplicaSet UpdateEvent", func() { + var err error + rs, err = clientset.AppsV1().ReplicaSets("default").Get(ctx, rs.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + rs2 := rs.DeepCopy() + rs2.SetLabels(map[string]string{"biz": "baz"}) + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Informer{Informer: depInformer} + err = instance.Start(ctx, handler.Funcs{ + CreateFunc: func(ctx context.Context, evt event.CreateEvent, q2 workqueue.RateLimitingInterface) { + }, + UpdateFunc: func(ctx context.Context, evt event.UpdateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + var err error + rs2, err := clientset.AppsV1().ReplicaSets("default").Get(ctx, rs.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + + Expect(q2).To(Equal(q)) + Expect(evt.ObjectOld).To(Equal(rs)) + + Expect(evt.ObjectNew).To(Equal(rs2)) + + close(c) + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + _, err = clientset.AppsV1().ReplicaSets("default").Update(ctx, rs2, metav1.UpdateOptions{}) + Expect(err).NotTo(HaveOccurred()) + <-c + }) + + It("should provide a ReplicaSet DeletedEvent", func() { + c := make(chan struct{}) + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Informer{Informer: depInformer} + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + }, + DeleteFunc: func(ctx context.Context, evt event.DeleteEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt.Object.GetName()).To(Equal(rs.Name)) + close(c) + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + err = clientset.AppsV1().ReplicaSets("default").Delete(ctx, rs.Name, metav1.DeleteOptions{}) + Expect(err).NotTo(HaveOccurred()) + <-c + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_suite_test.go new file mode 100644 index 00000000000..131099f0b9d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_suite_test.go @@ -0,0 +1,70 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source_test + +import ( + "context" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Source Suite") +} + +var testenv *envtest.Environment +var config *rest.Config +var clientset *kubernetes.Clientset +var icache cache.Cache +var ctx context.Context +var cancel context.CancelFunc + +var _ = BeforeSuite(func() { + ctx, cancel = context.WithCancel(context.Background()) + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + + var err error + config, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) + + clientset, err = kubernetes.NewForConfig(config) + Expect(err).NotTo(HaveOccurred()) + + icache, err = cache.New(config, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + go func() { + defer GinkgoRecover() + Expect(icache.Start(ctx)).NotTo(HaveOccurred()) + }() +}) + +var _ = AfterSuite(func() { + cancel() + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_test.go new file mode 100644 index 00000000000..1e0e3afed36 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/source/source_test.go @@ -0,0 +1,532 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source_test + +import ( + "context" + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "sigs.k8s.io/controller-runtime/pkg/cache/informertest" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/source" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/workqueue" +) + +var _ = Describe("Source", func() { + Describe("Kind", func() { + var c chan struct{} + var p *corev1.Pod + var ic *informertest.FakeInformers + + BeforeEach(func() { + ic = &informertest.FakeInformers{} + c = make(chan struct{}) + p = &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Name: "test", Image: "test"}, + }, + }, + } + }) + + Context("for a Pod resource", func() { + It("should provide a Pod CreateEvent", func() { + c := make(chan struct{}) + p := &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Name: "test", Image: "test"}, + }, + }, + } + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := source.Kind(ic, &corev1.Pod{}) + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(ctx context.Context, evt event.CreateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(Equal(q)) + Expect(evt.Object).To(Equal(p)) + close(c) + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + Expect(instance.WaitForSync(context.Background())).NotTo(HaveOccurred()) + + i, err := ic.FakeInformerFor(&corev1.Pod{}) + Expect(err).NotTo(HaveOccurred()) + + i.Add(p) + <-c + }) + + It("should provide a Pod UpdateEvent", func() { + p2 := p.DeepCopy() + p2.SetLabels(map[string]string{"biz": "baz"}) + + ic := &informertest.FakeInformers{} + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := source.Kind(ic, &corev1.Pod{}) + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(ctx context.Context, evt event.CreateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(ctx context.Context, evt event.UpdateEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.ObjectOld).To(Equal(p)) + + Expect(evt.ObjectNew).To(Equal(p2)) + + close(c) + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + Expect(instance.WaitForSync(context.Background())).NotTo(HaveOccurred()) + + i, err := ic.FakeInformerFor(&corev1.Pod{}) + Expect(err).NotTo(HaveOccurred()) + + i.Update(p, p2) + <-c + }) + + It("should provide a Pod DeletedEvent", func() { + c := make(chan struct{}) + p := &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Name: "test", Image: "test"}, + }, + }, + } + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := source.Kind(ic, &corev1.Pod{}) + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(ctx context.Context, evt event.DeleteEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.Object).To(Equal(p)) + close(c) + }, + GenericFunc: func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected GenericEvent") + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + Expect(instance.WaitForSync(context.Background())).NotTo(HaveOccurred()) + + i, err := ic.FakeInformerFor(&corev1.Pod{}) + Expect(err).NotTo(HaveOccurred()) + + i.Delete(p) + <-c + }) + }) + + It("should return an error from Start cache was not provided", func() { + instance := source.Kind(nil, &corev1.Pod{}) + err := instance.Start(ctx, nil, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("must create Kind with a non-nil cache")) + }) + + It("should return an error from Start if a type was not provided", func() { + instance := source.Kind(ic, nil) + err := instance.Start(ctx, nil, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("must create Kind with a non-nil object")) + }) + + It("should return an error if syncing fails", func() { + f := false + instance := source.Kind(&informertest.FakeInformers{Synced: &f}, &corev1.Pod{}) + Expect(instance.Start(context.Background(), nil, nil)).NotTo(HaveOccurred()) + err := instance.WaitForSync(context.Background()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("cache did not sync")) + + }) + + Context("for a Kind not in the cache", func() { + It("should return an error when WaitForSync is called", func() { + ic.Error = fmt.Errorf("test error") + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + + instance := source.Kind(ic, &corev1.Pod{}) + err := instance.Start(ctx, handler.Funcs{}, q) + Expect(err).NotTo(HaveOccurred()) + Eventually(instance.WaitForSync(context.Background())).Should(HaveOccurred()) + }) + }) + + It("should return an error if syncing fails", func() { + f := false + instance := source.Kind(&informertest.FakeInformers{Synced: &f}, &corev1.Pod{}) + Expect(instance.Start(context.Background(), nil, nil)).NotTo(HaveOccurred()) + err := instance.WaitForSync(context.Background()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("cache did not sync")) + + }) + }) + + Describe("Func", func() { + It("should be called from Start", func() { + run := false + instance := source.Func(func( + context.Context, + handler.EventHandler, + workqueue.RateLimitingInterface, ...predicate.Predicate) error { + run = true + return nil + }) + Expect(instance.Start(ctx, nil, nil)).NotTo(HaveOccurred()) + Expect(run).To(BeTrue()) + + expected := fmt.Errorf("expected error: Func") + instance = source.Func(func( + context.Context, + handler.EventHandler, + workqueue.RateLimitingInterface, ...predicate.Predicate) error { + return expected + }) + Expect(instance.Start(ctx, nil, nil)).To(Equal(expected)) + }) + }) + + Describe("Channel", func() { + var ctx context.Context + var cancel context.CancelFunc + var ch chan event.GenericEvent + + BeforeEach(func() { + ctx, cancel = context.WithCancel(context.Background()) + ch = make(chan event.GenericEvent) + }) + + AfterEach(func() { + cancel() + close(ch) + }) + + Context("for a source", func() { + It("should provide a GenericEvent", func() { + ch := make(chan event.GenericEvent) + c := make(chan struct{}) + p := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, + } + evt := event.GenericEvent{ + Object: p, + } + // Event that should be filtered out by predicates + invalidEvt := event.GenericEvent{} + + // Predicate to filter out empty event + prct := predicate.Funcs{ + GenericFunc: func(e event.GenericEvent) bool { + return e.Object != nil + }, + } + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Channel{Source: ch} + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + // The empty event should have been filtered out by the predicates, + // and will not be passed to the handler. + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.Object).To(Equal(p)) + close(c) + }, + }, q, prct) + Expect(err).NotTo(HaveOccurred()) + + ch <- invalidEvt + ch <- evt + <-c + }) + It("should get pending events processed once channel unblocked", func() { + ch := make(chan event.GenericEvent) + unblock := make(chan struct{}) + processed := make(chan struct{}) + evt := event.GenericEvent{} + eventCount := 0 + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + // Add a handler to get distribution blocked + instance := &source.Channel{Source: ch} + instance.DestBufferSize = 1 + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + // Block for the first time + if eventCount == 0 { + <-unblock + } + eventCount++ + + if eventCount == 3 { + close(processed) + } + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + // Write 3 events into the source channel. + // The 1st should be passed into the generic func of the handler; + // The 2nd should be fetched out of the source channel, and waiting to write into dest channel; + // The 3rd should be pending in the source channel. + ch <- evt + ch <- evt + ch <- evt + + // Validate none of the events have been processed. + Expect(eventCount).To(Equal(0)) + + close(unblock) + + <-processed + + // Validate all of the events have been processed. + Expect(eventCount).To(Equal(3)) + }) + It("should be able to cope with events in the channel before the source is started", func() { + ch := make(chan event.GenericEvent, 1) + processed := make(chan struct{}) + evt := event.GenericEvent{} + ch <- evt + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + // Add a handler to get distribution blocked + instance := &source.Channel{Source: ch} + instance.DestBufferSize = 1 + + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + + close(processed) + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + <-processed + }) + It("should stop when the source channel is closed", func() { + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + // if we didn't stop, we'd start spamming the queue with empty + // messages as we "received" a zero-valued GenericEvent from + // the source channel + + By("creating a channel with one element, then closing it") + ch := make(chan event.GenericEvent, 1) + evt := event.GenericEvent{} + ch <- evt + close(ch) + + By("feeding that channel to a channel source") + src := &source.Channel{Source: ch} + + processed := make(chan struct{}) + defer close(processed) + + err := src.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + + processed <- struct{}{} + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + By("expecting to only get one event") + Eventually(processed).Should(Receive()) + Consistently(processed).ShouldNot(Receive()) + }) + It("should get error if no source specified", func() { + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Channel{ /*no source specified*/ } + err := instance.Start(ctx, handler.Funcs{}, q) + Expect(err).To(Equal(fmt.Errorf("must specify Channel.Source"))) + }) + }) + Context("for multi sources (handlers)", func() { + It("should provide GenericEvents for all handlers", func() { + ch := make(chan event.GenericEvent) + p := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, + } + evt := event.GenericEvent{ + Object: p, + } + + var resEvent1, resEvent2 event.GenericEvent + c1 := make(chan struct{}) + c2 := make(chan struct{}) + + q := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "test") + instance := &source.Channel{Source: ch} + err := instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.Object).To(Equal(p)) + resEvent1 = evt + close(c1) + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + err = instance.Start(ctx, handler.Funcs{ + CreateFunc: func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected CreateEvent") + }, + UpdateFunc: func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected UpdateEvent") + }, + DeleteFunc: func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Fail("Unexpected DeleteEvent") + }, + GenericFunc: func(ctx context.Context, evt event.GenericEvent, q2 workqueue.RateLimitingInterface) { + defer GinkgoRecover() + Expect(q2).To(BeIdenticalTo(q)) + Expect(evt.Object).To(Equal(p)) + resEvent2 = evt + close(c2) + }, + }, q) + Expect(err).NotTo(HaveOccurred()) + + ch <- evt + <-c1 + <-c2 + + // Validate the two handlers received same event + Expect(resEvent1).To(Equal(resEvent2)) + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/admission_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/admission_suite_test.go new file mode 100644 index 00000000000..f4e561b1b8c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/admission_suite_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestAdmissionWebhook(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Admission Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go new file mode 100644 index 00000000000..f14f130f7bd --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go @@ -0,0 +1,78 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/json" +) + +// Decoder knows how to decode the contents of an admission +// request into a concrete object. +type Decoder struct { + codecs serializer.CodecFactory +} + +// NewDecoder creates a Decoder given the runtime.Scheme. +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} +} + +// Decode decodes the inlined object in the AdmissionRequest into the passed-in runtime.Object. +// If you want decode the OldObject in the AdmissionRequest, use DecodeRaw. +// It errors out if req.Object.Raw is empty i.e. containing 0 raw bytes. +func (d *Decoder) Decode(req Request, into runtime.Object) error { + // we error out if rawObj is an empty object. + if len(req.Object.Raw) == 0 { + return fmt.Errorf("there is no content to decode") + } + return d.DecodeRaw(req.Object, into) +} + +// DecodeRaw decodes a RawExtension object into the passed-in runtime.Object. +// It errors out if rawObj is empty i.e. containing 0 raw bytes. +func (d *Decoder) DecodeRaw(rawObj runtime.RawExtension, into runtime.Object) error { + // NB(directxman12): there's a bug/weird interaction between decoders and + // the API server where the API server doesn't send a GVK on the embedded + // objects, which means the unstructured decoder refuses to decode. It + // also means we can't pass the unstructured directly in, since it'll try + // and call unstructured's special Unmarshal implementation, which calls + // back into that same decoder :-/ + // See kubernetes/kubernetes#74373. + + // we error out if rawObj is an empty object. + if len(rawObj.Raw) == 0 { + return fmt.Errorf("there is no content to decode") + } + if unstructuredInto, isUnstructured := into.(runtime.Unstructured); isUnstructured { + // unmarshal into unstructured's underlying object to avoid calling the decoder + var object map[string]interface{} + if err := json.Unmarshal(rawObj.Raw, &object); err != nil { + return err + } + unstructuredInto.SetUnstructuredContent(object) + } + + deserializer := d.codecs.UniversalDeserializer() + return runtime.DecodeInto(deserializer, rawObj.Raw, into) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode_test.go new file mode 100644 index 00000000000..66586da7900 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode_test.go @@ -0,0 +1,155 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" +) + +var _ = Describe("Admission Webhook Decoder", func() { + var decoder *Decoder + BeforeEach(func() { + By("creating a new decoder for a scheme") + decoder = NewDecoder(scheme.Scheme) + Expect(decoder).NotTo(BeNil()) + }) + + req := Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Object: runtime.RawExtension{ + Raw: []byte(`{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "foo", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "bar:v2", + "name": "bar" + } + ] + } +}`), + }, + OldObject: runtime.RawExtension{ + Raw: []byte(`{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "foo", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "bar:v1", + "name": "bar" + } + ] + } +}`), + }, + }, + } + + It("should decode a valid admission request", func() { + By("extracting the object from the request") + var actualObj corev1.Pod + Expect(decoder.Decode(req, &actualObj)).To(Succeed()) + + By("verifying that all data is present in the object") + Expect(actualObj).To(Equal(corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Pod", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Image: "bar:v2", Name: "bar"}, + }, + }, + })) + }) + + It("should decode a valid RawExtension object", func() { + By("decoding the RawExtension object") + var actualObj corev1.Pod + Expect(decoder.DecodeRaw(req.OldObject, &actualObj)).To(Succeed()) + + By("verifying that all data is present in the object") + Expect(actualObj).To(Equal(corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Pod", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Image: "bar:v1", Name: "bar"}, + }, + }, + })) + }) + + It("should fail to decode if the object in the request doesn't match the passed-in type", func() { + By("trying to extract a pod from the quest into a node") + Expect(decoder.Decode(req, &corev1.Node{})).NotTo(Succeed()) + + By("trying to extract a pod in RawExtension format into a node") + Expect(decoder.DecodeRaw(req.OldObject, &corev1.Node{})).NotTo(Succeed()) + }) + + It("should be able to decode into an unstructured object", func() { + By("decoding the request into an unstructured object") + var target unstructured.Unstructured + Expect(decoder.Decode(req, &target)).To(Succeed()) + + By("sanity-checking the metadata on the output object") + Expect(target.Object["metadata"]).To(Equal(map[string]interface{}{ + "name": "foo", + "namespace": "default", + })) + + By("decoding the RawExtension object into an unstructured object") + var target2 unstructured.Unstructured + Expect(decoder.DecodeRaw(req.Object, &target2)).To(Succeed()) + + By("sanity-checking the metadata on the output object") + Expect(target2.Object["metadata"]).To(Equal(map[string]interface{}{ + "name": "foo", + "namespace": "default", + })) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go new file mode 100644 index 00000000000..a3b72071687 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go @@ -0,0 +1,82 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "encoding/json" + "net/http" + + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Defaulter defines functions for setting defaults on resources. +type Defaulter interface { + runtime.Object + Default() +} + +// DefaultingWebhookFor creates a new Webhook for Defaulting the provided type. +func DefaultingWebhookFor(scheme *runtime.Scheme, defaulter Defaulter) *Webhook { + return &Webhook{ + Handler: &mutatingHandler{defaulter: defaulter, decoder: NewDecoder(scheme)}, + } +} + +type mutatingHandler struct { + defaulter Defaulter + decoder *Decoder +} + +// Handle handles admission requests. +func (h *mutatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.defaulter == nil { + panic("defaulter should never be nil") + } + + // always skip when a DELETE operation received in mutation handler + // describe in https://github.com/kubernetes-sigs/controller-runtime/issues/1762 + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + + // Get the object in the request + obj := h.defaulter.DeepCopyObject().(Defaulter) + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + // Default the object + obj.Default() + marshalled, err := json.Marshal(obj) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + + // Create the patch + return PatchResponseFromRaw(req.Object.Raw, marshalled) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go new file mode 100644 index 00000000000..5f697e7dce7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go @@ -0,0 +1,94 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "encoding/json" + "errors" + "net/http" + + admissionv1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// CustomDefaulter defines functions for setting defaults on resources. +type CustomDefaulter interface { + Default(ctx context.Context, obj runtime.Object) error +} + +// WithCustomDefaulter creates a new Webhook for a CustomDefaulter interface. +func WithCustomDefaulter(scheme *runtime.Scheme, obj runtime.Object, defaulter CustomDefaulter) *Webhook { + return &Webhook{ + Handler: &defaulterForType{object: obj, defaulter: defaulter, decoder: NewDecoder(scheme)}, + } +} + +type defaulterForType struct { + defaulter CustomDefaulter + object runtime.Object + decoder *Decoder +} + +// Handle handles admission requests. +func (h *defaulterForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.defaulter == nil { + panic("defaulter should never be nil") + } + if h.object == nil { + panic("object should never be nil") + } + + // Always skip when a DELETE operation received in custom mutation handler. + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + + ctx = NewContextWithRequest(ctx, req) + + // Get the object in the request + obj := h.object.DeepCopyObject() + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + // Default the object + if err := h.defaulter.Default(ctx, obj); err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()) + } + return Denied(err.Error()) + } + + // Create the patch + marshalled, err := json.Marshal(obj) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + return PatchResponseFromRaw(req.Object.Raw, marshalled) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_test.go new file mode 100644 index 00000000000..cf7571663c0 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_test.go @@ -0,0 +1,68 @@ +package admission + +import ( + "context" + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var _ = Describe("Defaulter Handler", func() { + + It("should return ok if received delete verb in defaulter handler", func() { + obj := &TestDefaulter{} + handler := DefaultingWebhookFor(admissionScheme, obj) + + resp := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + }, + }, + }) + Expect(resp.Allowed).Should(BeTrue()) + Expect(resp.Result.Code).Should(Equal(int32(http.StatusOK))) + }) + +}) + +// TestDefaulter. +var _ runtime.Object = &TestDefaulter{} + +type TestDefaulter struct { + Replica int `json:"replica,omitempty"` +} + +var testDefaulterGVK = schema.GroupVersionKind{Group: "foo.test.org", Version: "v1", Kind: "TestDefaulter"} + +func (d *TestDefaulter) GetObjectKind() schema.ObjectKind { return d } +func (d *TestDefaulter) DeepCopyObject() runtime.Object { + return &TestDefaulter{ + Replica: d.Replica, + } +} + +func (d *TestDefaulter) GroupVersionKind() schema.GroupVersionKind { + return testDefaulterGVK +} + +func (d *TestDefaulter) SetGroupVersionKind(gvk schema.GroupVersionKind) {} + +var _ runtime.Object = &TestDefaulterList{} + +type TestDefaulterList struct{} + +func (*TestDefaulterList) GetObjectKind() schema.ObjectKind { return nil } +func (*TestDefaulterList) DeepCopyObject() runtime.Object { return nil } + +func (d *TestDefaulter) Default() { + if d.Replica < 2 { + d.Replica = 2 + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go new file mode 100644 index 00000000000..8dc0cbec6f7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package admission provides implementation for admission webhook and methods to implement admission webhook handlers. + +See examples/mutatingwebhook.go and examples/validatingwebhook.go for examples of admission webhooks. +*/ +package admission diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go new file mode 100644 index 00000000000..84ab5e75a4e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go @@ -0,0 +1,153 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + + v1 "k8s.io/api/admission/v1" + "k8s.io/api/admission/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var admissionScheme = runtime.NewScheme() +var admissionCodecs = serializer.NewCodecFactory(admissionScheme) + +func init() { + utilruntime.Must(v1.AddToScheme(admissionScheme)) + utilruntime.Must(v1beta1.AddToScheme(admissionScheme)) +} + +var _ http.Handler = &Webhook{} + +func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var body []byte + var err error + ctx := r.Context() + if wh.WithContextFunc != nil { + ctx = wh.WithContextFunc(ctx, r) + } + + var reviewResponse Response + if r.Body == nil { + err = errors.New("request body is empty") + wh.getLogger(nil).Error(err, "bad request") + reviewResponse = Errored(http.StatusBadRequest, err) + wh.writeResponse(w, reviewResponse) + return + } + + defer r.Body.Close() + if body, err = io.ReadAll(r.Body); err != nil { + wh.getLogger(nil).Error(err, "unable to read the body from the incoming request") + reviewResponse = Errored(http.StatusBadRequest, err) + wh.writeResponse(w, reviewResponse) + return + } + + // verify the content type is accurate + if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { + err = fmt.Errorf("contentType=%s, expected application/json", contentType) + wh.getLogger(nil).Error(err, "unable to process a request with unknown content type") + reviewResponse = Errored(http.StatusBadRequest, err) + wh.writeResponse(w, reviewResponse) + return + } + + // Both v1 and v1beta1 AdmissionReview types are exactly the same, so the v1beta1 type can + // be decoded into the v1 type. However the runtime codec's decoder guesses which type to + // decode into by type name if an Object's TypeMeta isn't set. By setting TypeMeta of an + // unregistered type to the v1 GVK, the decoder will coerce a v1beta1 AdmissionReview to v1. + // The actual AdmissionReview GVK will be used to write a typed response in case the + // webhook config permits multiple versions, otherwise this response will fail. + req := Request{} + ar := unversionedAdmissionReview{} + // avoid an extra copy + ar.Request = &req.AdmissionRequest + ar.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("AdmissionReview")) + _, actualAdmRevGVK, err := admissionCodecs.UniversalDeserializer().Decode(body, nil, &ar) + if err != nil { + wh.getLogger(nil).Error(err, "unable to decode the request") + reviewResponse = Errored(http.StatusBadRequest, err) + wh.writeResponse(w, reviewResponse) + return + } + wh.getLogger(&req).V(4).Info("received request") + + reviewResponse = wh.Handle(ctx, req) + wh.writeResponseTyped(w, reviewResponse, actualAdmRevGVK) +} + +// writeResponse writes response to w generically, i.e. without encoding GVK information. +func (wh *Webhook) writeResponse(w io.Writer, response Response) { + wh.writeAdmissionResponse(w, v1.AdmissionReview{Response: &response.AdmissionResponse}) +} + +// writeResponseTyped writes response to w with GVK set to admRevGVK, which is necessary +// if multiple AdmissionReview versions are permitted by the webhook. +func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, admRevGVK *schema.GroupVersionKind) { + ar := v1.AdmissionReview{ + Response: &response.AdmissionResponse, + } + // Default to a v1 AdmissionReview, otherwise the API server may not recognize the request + // if multiple AdmissionReview versions are permitted by the webhook config. + // TODO(estroz): this should be configurable since older API servers won't know about v1. + if admRevGVK == nil || *admRevGVK == (schema.GroupVersionKind{}) { + ar.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("AdmissionReview")) + } else { + ar.SetGroupVersionKind(*admRevGVK) + } + wh.writeAdmissionResponse(w, ar) +} + +// writeAdmissionResponse writes ar to w. +func (wh *Webhook) writeAdmissionResponse(w io.Writer, ar v1.AdmissionReview) { + if err := json.NewEncoder(w).Encode(ar); err != nil { + wh.getLogger(nil).Error(err, "unable to encode and write the response") + // Since the `ar v1.AdmissionReview` is a clear and legal object, + // it should not have problem to be marshalled into bytes. + // The error here is probably caused by the abnormal HTTP connection, + // e.g., broken pipe, so we can only write the error response once, + // to avoid endless circular calling. + serverError := Errored(http.StatusInternalServerError, err) + if err = json.NewEncoder(w).Encode(v1.AdmissionReview{Response: &serverError.AdmissionResponse}); err != nil { + wh.getLogger(nil).Error(err, "still unable to encode and write the InternalServerError response") + } + } else { + res := ar.Response + if log := wh.getLogger(nil); log.V(4).Enabled() { + if res.Result != nil { + log = log.WithValues("code", res.Result.Code, "reason", res.Result.Reason, "message", res.Result.Message) + } + log.V(4).Info("wrote response", "requestID", res.UID, "allowed", res.Allowed) + } + } +} + +// unversionedAdmissionReview is used to decode both v1 and v1beta1 AdmissionReview types. +type unversionedAdmissionReview struct { + v1.AdmissionReview +} + +var _ runtime.Object = &unversionedAdmissionReview{} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http_test.go new file mode 100644 index 00000000000..be10aea4593 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http_test.go @@ -0,0 +1,231 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "bytes" + "context" + "fmt" + "io" + "net/http" + "net/http/httptest" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" +) + +var _ = Describe("Admission Webhooks", func() { + + const ( + gvkJSONv1 = `"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1"` + gvkJSONv1beta1 = `"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1beta1"` + ) + + Describe("HTTP Handler", func() { + var respRecorder *httptest.ResponseRecorder + webhook := &Webhook{ + Handler: nil, + } + BeforeEach(func() { + respRecorder = &httptest.ResponseRecorder{ + Body: bytes.NewBuffer(nil), + } + }) + + It("should return bad-request when given an empty body", func() { + req := &http.Request{Body: nil} + + expected := `{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"request body is empty","code":400}}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return bad-request when given the wrong content-type", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/foo"}}, + Body: nopCloser{Reader: bytes.NewBuffer(nil)}, + } + + expected := + `{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"contentType=application/foo, expected application/json","code":400}}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return bad-request when given an undecodable body", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString("{")}, + } + + expected := + `{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"couldn't get version/kind; json parse error: unexpected end of JSON input","code":400}}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return the response given by the handler with version defaulted to v1", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(`{"request":{}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + expected := fmt.Sprintf(`{%s,"response":{"uid":"","allowed":true,"status":{"metadata":{},"code":200}}} +`, gvkJSONv1) + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return the v1 response given by the handler", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(fmt.Sprintf(`{%s,"request":{}}`, gvkJSONv1))}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + expected := fmt.Sprintf(`{%s,"response":{"uid":"","allowed":true,"status":{"metadata":{},"code":200}}} +`, gvkJSONv1) + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return the v1beta1 response given by the handler", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(fmt.Sprintf(`{%s,"request":{}}`, gvkJSONv1beta1))}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + expected := fmt.Sprintf(`{%s,"response":{"uid":"","allowed":true,"status":{"metadata":{},"code":200}}} +`, gvkJSONv1beta1) + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should present the Context from the HTTP request, if any", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(`{"request":{}}`)}, + } + type ctxkey int + const key ctxkey = 1 + const value = "from-ctx" + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + <-ctx.Done() + return Allowed(ctx.Value(key).(string)) + }, + }, + } + + expected := fmt.Sprintf(`{%s,"response":{"uid":"","allowed":true,"status":{"metadata":{},"message":%q,"code":200}}} +`, gvkJSONv1, value) + + ctx, cancel := context.WithCancel(context.WithValue(context.Background(), key, value)) + cancel() + webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should mutate the Context from the HTTP request, if func supplied", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(`{"request":{}}`)}, + } + type ctxkey int + const key ctxkey = 1 + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Allowed(ctx.Value(key).(string)) + }, + }, + WithContextFunc: func(ctx context.Context, r *http.Request) context.Context { + return context.WithValue(ctx, key, r.Header["Content-Type"][0]) + }, + } + + expected := fmt.Sprintf(`{%s,"response":{"uid":"","allowed":true,"status":{"metadata":{},"message":%q,"code":200}}} +`, gvkJSONv1, "application/json") + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should never run into circular calling if the writer has broken", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Body: nopCloser{Reader: bytes.NewBufferString(fmt.Sprintf(`{%s,"request":{}}`, gvkJSONv1))}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + bw := &brokenWriter{ResponseWriter: respRecorder} + Eventually(func() int { + // This should not be blocked by the circular calling of writeResponse and writeAdmissionResponse + webhook.ServeHTTP(bw, req) + return respRecorder.Body.Len() + }, time.Second*3).Should(Equal(0)) + }) + }) +}) + +type nopCloser struct { + io.Reader +} + +func (nopCloser) Close() error { return nil } + +type fakeHandler struct { + invoked bool + fn func(context.Context, Request) Response +} + +func (h *fakeHandler) Handle(ctx context.Context, req Request) Response { + h.invoked = true + if h.fn != nil { + return h.fn(ctx, req) + } + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + }} +} + +type brokenWriter struct { + http.ResponseWriter +} + +func (bw *brokenWriter) Write(buf []byte) (int, error) { + return 0, fmt.Errorf("mock: write: broken pipe") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go new file mode 100644 index 00000000000..2f7820d04b4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go @@ -0,0 +1,95 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type multiMutating []Handler + +func (hs multiMutating) Handle(ctx context.Context, req Request) Response { + patches := []jsonpatch.JsonPatchOperation{} + for _, handler := range hs { + resp := handler.Handle(ctx, req) + if !resp.Allowed { + return resp + } + if resp.PatchType != nil && *resp.PatchType != admissionv1.PatchTypeJSONPatch { + return Errored(http.StatusInternalServerError, + fmt.Errorf("unexpected patch type returned by the handler: %v, only allow: %v", + resp.PatchType, admissionv1.PatchTypeJSONPatch)) + } + patches = append(patches, resp.Patches...) + } + var err error + marshaledPatch, err := json.Marshal(patches) + if err != nil { + return Errored(http.StatusBadRequest, fmt.Errorf("error when marshaling the patch: %w", err)) + } + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + Patch: marshaledPatch, + PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(), + }, + } +} + +// MultiMutatingHandler combines multiple mutating webhook handlers into a single +// mutating webhook handler. Handlers are called in sequential order, and the first +// `allowed: false` response may short-circuit the rest. Users must take care to +// ensure patches are disjoint. +func MultiMutatingHandler(handlers ...Handler) Handler { + return multiMutating(handlers) +} + +type multiValidating []Handler + +func (hs multiValidating) Handle(ctx context.Context, req Request) Response { + for _, handler := range hs { + resp := handler.Handle(ctx, req) + if !resp.Allowed { + return resp + } + } + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }, + } +} + +// MultiValidatingHandler combines multiple validating webhook handlers into a single +// validating webhook handler. Handlers are called in sequential order, and the first +// `allowed: false` response may short-circuit the rest. +func MultiValidatingHandler(handlers ...Handler) Handler { + return multiValidating(handlers) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi_test.go new file mode 100644 index 00000000000..da85a52e42a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi_test.go @@ -0,0 +1,132 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" +) + +var _ = Describe("Multi-Handler Admission Webhooks", func() { + alwaysAllow := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + }, + } + }, + } + alwaysDeny := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + }, + } + }, + } + + Context("with validating handlers", func() { + It("should deny the request if any handler denies the request", func() { + By("setting up a handler with accept and deny") + handler := MultiValidatingHandler(alwaysAllow, alwaysDeny) + + By("checking that the handler denies the request") + resp := handler.Handle(context.Background(), Request{}) + Expect(resp.Allowed).To(BeFalse()) + }) + + It("should allow the request if all handlers allow the request", func() { + By("setting up a handler with only accept") + handler := MultiValidatingHandler(alwaysAllow, alwaysAllow) + + By("checking that the handler allows the request") + resp := handler.Handle(context.Background(), Request{}) + Expect(resp.Allowed).To(BeTrue()) + }) + }) + + Context("with mutating handlers", func() { + patcher1 := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + Patches: []jsonpatch.JsonPatchOperation{ + { + Operation: "add", + Path: "/metadata/annotation/new-key", + Value: "new-value", + }, + { + Operation: "replace", + Path: "/spec/replicas", + Value: "2", + }, + }, + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(), + }, + } + }, + } + patcher2 := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + Patches: []jsonpatch.JsonPatchOperation{ + { + Operation: "add", + Path: "/metadata/annotation/hello", + Value: "world", + }, + }, + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(), + }, + } + }, + } + + It("should not return any patches if the request is denied", func() { + By("setting up a webhook with some patches and a deny") + handler := MultiMutatingHandler(patcher1, patcher2, alwaysDeny) + + By("checking that the handler denies the request and produces no patches") + resp := handler.Handle(context.Background(), Request{}) + Expect(resp.Allowed).To(BeFalse()) + Expect(resp.Patches).To(BeEmpty()) + }) + + It("should produce all patches if the requests are all allowed", func() { + By("setting up a webhook with some patches") + handler := MultiMutatingHandler(patcher1, patcher2, alwaysAllow) + + By("checking that the handler accepts the request and returns all patches") + resp := handler.Handle(context.Background(), Request{}) + Expect(resp.Allowed).To(BeTrue()) + Expect(resp.Patch).To(Equal([]byte( + `[{"op":"add","path":"/metadata/annotation/new-key","value":"new-value"},` + + `{"op":"replace","path":"/spec/replicas","value":"2"},{"op":"add","path":"/metadata/annotation/hello","value":"world"}]`))) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go new file mode 100644 index 00000000000..ec1c88c989b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go @@ -0,0 +1,124 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "net/http" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Allowed constructs a response indicating that the given operation +// is allowed (without any patches). +func Allowed(message string) Response { + return ValidationResponse(true, message) +} + +// Denied constructs a response indicating that the given operation +// is not allowed. +func Denied(message string) Response { + return ValidationResponse(false, message) +} + +// Patched constructs a response indicating that the given operation is +// allowed, and that the target object should be modified by the given +// JSONPatch operations. +func Patched(message string, patches ...jsonpatch.JsonPatchOperation) Response { + resp := Allowed(message) + resp.Patches = patches + + return resp +} + +// Errored creates a new Response for error-handling a request. +func Errored(code int32, err error) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: code, + Message: err.Error(), + }, + }, + } +} + +// ValidationResponse returns a response for admitting a request. +func ValidationResponse(allowed bool, message string) Response { + code := http.StatusForbidden + reason := metav1.StatusReasonForbidden + if allowed { + code = http.StatusOK + reason = "" + } + resp := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: allowed, + Result: &metav1.Status{ + Code: int32(code), + Reason: reason, + }, + }, + } + if len(message) > 0 { + resp.Result.Message = message + } + return resp +} + +// PatchResponseFromRaw takes 2 byte arrays and returns a new response with json patch. +// The original object should be passed in as raw bytes to avoid the roundtripping problem +// described in https://github.com/kubernetes-sigs/kubebuilder/issues/510. +func PatchResponseFromRaw(original, current []byte) Response { + patches, err := jsonpatch.CreatePatch(original, current) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + return Response{ + Patches: patches, + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + PatchType: func() *admissionv1.PatchType { + if len(patches) == 0 { + return nil + } + pt := admissionv1.PatchTypeJSONPatch + return &pt + }(), + }, + } +} + +// validationResponseFromStatus returns a response for admitting a request with provided Status object. +func validationResponseFromStatus(allowed bool, status metav1.Status) Response { + resp := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: allowed, + Result: &status, + }, + } + return resp +} + +// WithWarnings adds the given warnings to the Response. +// If any warnings were already given, they will not be overwritten. +func (r Response) WithWarnings(warnings ...string) Response { + r.AdmissionResponse.Warnings = append(r.AdmissionResponse.Warnings, warnings...) + return r +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response_test.go new file mode 100644 index 00000000000..03107c92f51 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response_test.go @@ -0,0 +1,249 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "errors" + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var _ = Describe("Admission Webhook Response Helpers", func() { + Describe("Allowed", func() { + It("should return an 'allowed' response", func() { + Expect(Allowed("")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }, + }, + )) + }) + + It("should populate a status with a reason when a reason is given", func() { + Expect(Allowed("acceptable")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + Message: "acceptable", + }, + }, + }, + )) + }) + }) + + Describe("Denied", func() { + It("should return a 'not allowed' response", func() { + Expect(Denied("")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: http.StatusForbidden, + Reason: metav1.StatusReasonForbidden, + }, + }, + }, + )) + }) + + It("should populate a status with a reason when a reason is given", func() { + Expect(Denied("UNACCEPTABLE!")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: http.StatusForbidden, + Reason: metav1.StatusReasonForbidden, + Message: "UNACCEPTABLE!", + }, + }, + }, + )) + }) + }) + + Describe("Patched", func() { + ops := []jsonpatch.JsonPatchOperation{ + { + Operation: "replace", + Path: "/spec/selector/matchLabels", + Value: map[string]string{"foo": "bar"}, + }, + { + Operation: "delete", + Path: "/spec/replicas", + }, + } + It("should return an 'allowed' response with the given patches", func() { + Expect(Patched("", ops...)).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }, + Patches: ops, + }, + )) + }) + It("should populate a status with a reason when a reason is given", func() { + Expect(Patched("some changes", ops...)).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + Message: "some changes", + }, + }, + Patches: ops, + }, + )) + }) + }) + + Describe("Errored", func() { + It("should return a denied response with an error", func() { + err := errors.New("this is an error") + expected := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: http.StatusBadRequest, + Message: err.Error(), + }, + }, + } + resp := Errored(http.StatusBadRequest, err) + Expect(resp).To(Equal(expected)) + }) + }) + + Describe("ValidationResponse", func() { + It("should populate a status with a message when a message is given", func() { + By("checking that a message is populated for 'allowed' responses") + Expect(ValidationResponse(true, "acceptable")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + Message: "acceptable", + }, + }, + }, + )) + + By("checking that a message is populated for 'denied' responses") + Expect(ValidationResponse(false, "UNACCEPTABLE!")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: http.StatusForbidden, + Reason: metav1.StatusReasonForbidden, + Message: "UNACCEPTABLE!", + }, + }, + }, + )) + }) + + It("should return an admission decision", func() { + By("checking that it returns an 'allowed' response when allowed is true") + Expect(ValidationResponse(true, "")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }, + }, + )) + + By("checking that it returns an 'denied' response when allowed is false") + Expect(ValidationResponse(false, "")).To(Equal( + Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: http.StatusForbidden, + Reason: metav1.StatusReasonForbidden, + }, + }, + }, + )) + }) + }) + + Describe("PatchResponseFromRaw", func() { + It("should return an 'allowed' response with a patch of the diff between two sets of serialized JSON", func() { + expected := Response{ + Patches: []jsonpatch.JsonPatchOperation{ + {Operation: "replace", Path: "/a", Value: "bar"}, + }, + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(), + }, + } + resp := PatchResponseFromRaw([]byte(`{"a": "foo"}`), []byte(`{"a": "bar"}`)) + Expect(resp).To(Equal(expected)) + }) + }) + + Describe("WithWarnings", func() { + It("should add the warnings to the existing response without removing any existing warnings", func() { + initialResponse := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + Warnings: []string{"existing-warning"}, + }, + } + warnings := []string{"additional-warning-1", "additional-warning-2"} + expectedResponse := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + Warnings: []string{"existing-warning", "additional-warning-1", "additional-warning-2"}, + }, + } + + Expect(initialResponse.WithWarnings(warnings...)).To(Equal(expectedResponse)) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go new file mode 100644 index 00000000000..00bda8a4ce5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go @@ -0,0 +1,125 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + + v1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +// Warnings represents warning messages. +type Warnings []string + +// Validator defines functions for validating an operation. +// The custom resource kind which implements this interface can validate itself. +// To validate the custom resource with another specific struct, use CustomValidator instead. +type Validator interface { + runtime.Object + + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate() (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. The oldObj is the object before the update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(old runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete() (warnings Warnings, err error) +} + +// ValidatingWebhookFor creates a new Webhook for validating the provided type. +func ValidatingWebhookFor(scheme *runtime.Scheme, validator Validator) *Webhook { + return &Webhook{ + Handler: &validatingHandler{validator: validator, decoder: NewDecoder(scheme)}, + } +} + +type validatingHandler struct { + validator Validator + decoder *Decoder +} + +// Handle handles admission requests. +func (h *validatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.validator == nil { + panic("validator should never be nil") + } + // Get the object in the request + obj := h.validator.DeepCopyObject().(Validator) + + var err error + var warnings []string + + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? + case v1.Create: + if err = h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateCreate() + case v1.Update: + oldObj := obj.DeepCopyObject() + + err = h.decoder.DecodeRaw(req.Object, obj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + err = h.decoder.DecodeRaw(req.OldObject, oldObj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateUpdate(oldObj) + case v1.Delete: + // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 + // OldObject contains the object being deleted + err = h.decoder.DecodeRaw(req.OldObject, obj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateDelete() + default: + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) + } + + if err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) + } + return Denied(err.Error()).WithWarnings(warnings...) + } + return Allowed("").WithWarnings(warnings...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go new file mode 100644 index 00000000000..e99fbd8a857 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go @@ -0,0 +1,126 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + + v1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +// CustomValidator defines functions for validating an operation. +// The object to be validated is passed into methods as a parameter. +type CustomValidator interface { + + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) +} + +// WithCustomValidator creates a new Webhook for validating the provided type. +func WithCustomValidator(scheme *runtime.Scheme, obj runtime.Object, validator CustomValidator) *Webhook { + return &Webhook{ + Handler: &validatorForType{object: obj, validator: validator, decoder: NewDecoder(scheme)}, + } +} + +type validatorForType struct { + validator CustomValidator + object runtime.Object + decoder *Decoder +} + +// Handle handles admission requests. +func (h *validatorForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.validator == nil { + panic("validator should never be nil") + } + if h.object == nil { + panic("object should never be nil") + } + + ctx = NewContextWithRequest(ctx, req) + + // Get the object in the request + obj := h.object.DeepCopyObject() + + var err error + var warnings []string + + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? + case v1.Create: + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateCreate(ctx, obj) + case v1.Update: + oldObj := obj.DeepCopyObject() + if err := h.decoder.DecodeRaw(req.Object, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + if err := h.decoder.DecodeRaw(req.OldObject, oldObj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateUpdate(ctx, oldObj, obj) + case v1.Delete: + // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 + // OldObject contains the object being deleted + if err := h.decoder.DecodeRaw(req.OldObject, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateDelete(ctx, obj) + default: + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) + } + + // Check the error message first. + if err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) + } + return Denied(err.Error()).WithWarnings(warnings...) + } + + // Return allowed if everything succeeded. + return Allowed("").WithWarnings(warnings...) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_test.go new file mode 100644 index 00000000000..404fad90163 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_test.go @@ -0,0 +1,494 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "errors" + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + admissionv1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes/scheme" +) + +var fakeValidatorVK = schema.GroupVersionKind{Group: "foo.test.org", Version: "v1", Kind: "fakeValidator"} + +var _ = Describe("validatingHandler", func() { + + decoder := NewDecoder(scheme.Scheme) + + Context("when dealing with successful results without warning", func() { + f := &fakeValidator{ErrorToReturn: nil, GVKToReturn: fakeValidatorVK, WarningsToReturn: nil} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should return 200 in response when create succeeds", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + }) + + It("should return 200 in response when update succeeds", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + }) + + It("should return 200 in response when delete succeeds", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + }) + }) + + const warningMessage = "warning message" + const anotherWarningMessage = "another warning message" + Context("when dealing with successful results with warning", func() { + f := &fakeValidator{ErrorToReturn: nil, GVKToReturn: fakeValidatorVK, WarningsToReturn: []string{ + warningMessage, + anotherWarningMessage, + }} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should return 200 in response when create succeeds, with warning messages", func() { + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + }) + + It("should return 200 in response when update succeeds, with warning messages", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + }) + + It("should return 200 in response when delete succeeds, with warning messages", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeTrue()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusOK))) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + }) + }) + + Context("when dealing with Status errors, with warning messages", func() { + // Status error would overwrite the warning messages, so no warning messages should be observed. + expectedError := &apierrors.StatusError{ + ErrStatus: metav1.Status{ + Message: "some message", + Code: http.StatusUnprocessableEntity, + }, + } + f := &fakeValidator{ErrorToReturn: expectedError, GVKToReturn: fakeValidatorVK, WarningsToReturn: []string{warningMessage, anotherWarningMessage}} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should propagate the Status from ValidateCreate's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(anotherWarningMessage)) + + }) + + It("should propagate the Status from ValidateUpdate's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(anotherWarningMessage)) + + }) + + It("should propagate the Status from ValidateDelete's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElements(anotherWarningMessage)) + + }) + + }) + + Context("when dealing with Status errors, without warning messages", func() { + + expectedError := &apierrors.StatusError{ + ErrStatus: metav1.Status{ + Message: "some message", + Code: http.StatusUnprocessableEntity, + }, + } + f := &fakeValidator{ErrorToReturn: expectedError, GVKToReturn: fakeValidatorVK, WarningsToReturn: nil} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should propagate the Status from ValidateCreate's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + + }) + + It("should propagate the Status from ValidateUpdate's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + + }) + + It("should propagate the Status from ValidateDelete's return value to the HTTP response", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(expectedError.Status().Code)) + Expect(*response.Result).Should(Equal(expectedError.Status())) + + }) + + }) + + Context("when dealing with non-status errors, without warning messages", func() { + + expectedError := errors.New("some error") + f := &fakeValidator{ErrorToReturn: expectedError, GVKToReturn: fakeValidatorVK} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should return 403 response when ValidateCreate with error message embedded", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + + }) + + It("should return 403 response when ValidateUpdate returns non-APIStatus error", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + + }) + + It("should return 403 response when ValidateDelete returns non-APIStatus error", func() { + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + }) + }) + + Context("when dealing with non-status errors, with warning messages", func() { + + expectedError := errors.New("some error") + f := &fakeValidator{ErrorToReturn: expectedError, GVKToReturn: fakeValidatorVK, WarningsToReturn: []string{warningMessage, anotherWarningMessage}} + handler := validatingHandler{validator: f, decoder: decoder} + + It("should return 403 response when ValidateCreate with error message embedded", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Create, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + }) + + It("should return 403 response when ValidateUpdate returns non-APIStatus error", func() { + + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Update, + Object: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + + }) + + It("should return 403 response when ValidateDelete returns non-APIStatus error", func() { + response := handler.Handle(context.TODO(), Request{ + AdmissionRequest: admissionv1.AdmissionRequest{ + Operation: admissionv1.Delete, + OldObject: runtime.RawExtension{ + Raw: []byte("{}"), + Object: handler.validator, + }, + }, + }) + Expect(response.Allowed).Should(BeFalse()) + Expect(response.Result.Code).Should(Equal(int32(http.StatusForbidden))) + Expect(response.Result.Reason).Should(Equal(metav1.StatusReasonForbidden)) + Expect(response.Result.Message).Should(Equal(expectedError.Error())) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(warningMessage)) + Expect(response.AdmissionResponse.Warnings).Should(ContainElement(anotherWarningMessage)) + + }) + }) + + PIt("should return 400 in response when create fails on decode", func() {}) + + PIt("should return 400 in response when update fails on decoding new object", func() {}) + + PIt("should return 400 in response when update fails on decoding old object", func() {}) + + PIt("should return 400 in response when delete fails on decode", func() {}) + +}) + +// fakeValidator provides fake validating webhook functionality for testing +// It implements the admission.Validator interface and +// rejects all requests with the same configured error +// or passes if ErrorToReturn is nil. +// And it would always return configured warning messages WarningsToReturn. +type fakeValidator struct { + // ErrorToReturn is the error for which the fakeValidator rejects all requests + ErrorToReturn error `json:"errorToReturn,omitempty"` + // GVKToReturn is the GroupVersionKind that the webhook operates on + GVKToReturn schema.GroupVersionKind + // WarningsToReturn is the warnings for fakeValidator returns to all requests + WarningsToReturn []string +} + +func (v *fakeValidator) ValidateCreate() (warnings Warnings, err error) { + return v.WarningsToReturn, v.ErrorToReturn +} + +func (v *fakeValidator) ValidateUpdate(old runtime.Object) (warnings Warnings, err error) { + return v.WarningsToReturn, v.ErrorToReturn +} + +func (v *fakeValidator) ValidateDelete() (warnings Warnings, err error) { + return v.WarningsToReturn, v.ErrorToReturn +} + +func (v *fakeValidator) SetGroupVersionKind(gvk schema.GroupVersionKind) { + v.GVKToReturn = gvk +} + +func (v *fakeValidator) GroupVersionKind() schema.GroupVersionKind { + return v.GVKToReturn +} + +func (v *fakeValidator) GetObjectKind() schema.ObjectKind { + return v +} + +func (v *fakeValidator) DeepCopyObject() runtime.Object { + return &fakeValidator{ + ErrorToReturn: v.ErrorToReturn, + GVKToReturn: v.GVKToReturn, + WarningsToReturn: v.WarningsToReturn, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go new file mode 100644 index 00000000000..f1767f31b2e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go @@ -0,0 +1,251 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + "sync" + + "github.com/go-logr/logr" + "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/json" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" +) + +var ( + errUnableToEncodeResponse = errors.New("unable to encode response") +) + +// Request defines the input for an admission handler. +// It contains information to identify the object in +// question (group, version, kind, resource, subresource, +// name, namespace), as well as the operation in question +// (e.g. Get, Create, etc), and the object itself. +type Request struct { + admissionv1.AdmissionRequest +} + +// Response is the output of an admission handler. +// It contains a response indicating if a given +// operation is allowed, as well as a set of patches +// to mutate the object in the case of a mutating admission handler. +type Response struct { + // Patches are the JSON patches for mutating webhooks. + // Using this instead of setting Response.Patch to minimize + // overhead of serialization and deserialization. + // Patches set here will override any patches in the response, + // so leave this empty if you want to set the patch response directly. + Patches []jsonpatch.JsonPatchOperation + // AdmissionResponse is the raw admission response. + // The Patch field in it will be overwritten by the listed patches. + admissionv1.AdmissionResponse +} + +// Complete populates any fields that are yet to be set in +// the underlying AdmissionResponse, It mutates the response. +func (r *Response) Complete(req Request) error { + r.UID = req.UID + + // ensure that we have a valid status code + if r.Result == nil { + r.Result = &metav1.Status{} + } + if r.Result.Code == 0 { + r.Result.Code = http.StatusOK + } + // TODO(directxman12): do we need to populate this further, and/or + // is code actually necessary (the same webhook doesn't use it) + + if len(r.Patches) == 0 { + return nil + } + + var err error + r.Patch, err = json.Marshal(r.Patches) + if err != nil { + return err + } + patchType := admissionv1.PatchTypeJSONPatch + r.PatchType = &patchType + + return nil +} + +// Handler can handle an AdmissionRequest. +type Handler interface { + // Handle yields a response to an AdmissionRequest. + // + // The supplied context is extracted from the received http.Request, allowing wrapping + // http.Handlers to inject values into and control cancelation of downstream request processing. + Handle(context.Context, Request) Response +} + +// HandlerFunc implements Handler interface using a single function. +type HandlerFunc func(context.Context, Request) Response + +var _ Handler = HandlerFunc(nil) + +// Handle process the AdmissionRequest by invoking the underlying function. +func (f HandlerFunc) Handle(ctx context.Context, req Request) Response { + return f(ctx, req) +} + +// Webhook represents each individual webhook. +// +// It must be registered with a webhook.Server or +// populated by StandaloneWebhook to be ran on an arbitrary HTTP server. +type Webhook struct { + // Handler actually processes an admission request returning whether it was allowed or denied, + // and potentially patches to apply to the handler. + Handler Handler + + // RecoverPanic indicates whether the panic caused by webhook should be recovered. + RecoverPanic bool + + // WithContextFunc will allow you to take the http.Request.Context() and + // add any additional information such as passing the request path or + // headers thus allowing you to read them from within the handler + WithContextFunc func(context.Context, *http.Request) context.Context + + // LogConstructor is used to construct a logger for logging messages during webhook calls + // based on the given base logger (which might carry more values like the webhook's path). + // Note: LogConstructor has to be able to handle nil requests as we are also using it + // outside the context of requests. + LogConstructor func(base logr.Logger, req *Request) logr.Logger + + setupLogOnce sync.Once + log logr.Logger +} + +// WithRecoverPanic takes a bool flag which indicates whether the panic caused by webhook should be recovered. +func (wh *Webhook) WithRecoverPanic(recoverPanic bool) *Webhook { + wh.RecoverPanic = recoverPanic + return wh +} + +// Handle processes AdmissionRequest. +// If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches. +// If the webhook is validating type, it delegates the AdmissionRequest to each handler and +// deny the request if anyone denies. +func (wh *Webhook) Handle(ctx context.Context, req Request) (response Response) { + if wh.RecoverPanic { + defer func() { + if r := recover(); r != nil { + for _, fn := range utilruntime.PanicHandlers { + fn(r) + } + response = Errored(http.StatusInternalServerError, fmt.Errorf("panic: %v [recovered]", r)) + return + } + }() + } + + reqLog := wh.getLogger(&req) + ctx = logf.IntoContext(ctx, reqLog) + + resp := wh.Handler.Handle(ctx, req) + if err := resp.Complete(req); err != nil { + reqLog.Error(err, "unable to encode response") + return Errored(http.StatusInternalServerError, errUnableToEncodeResponse) + } + + return resp +} + +// getLogger constructs a logger from the injected log and LogConstructor. +func (wh *Webhook) getLogger(req *Request) logr.Logger { + wh.setupLogOnce.Do(func() { + if wh.log.GetSink() == nil { + wh.log = logf.Log.WithName("admission") + } + }) + + logConstructor := wh.LogConstructor + if logConstructor == nil { + logConstructor = DefaultLogConstructor + } + return logConstructor(wh.log, req) +} + +// DefaultLogConstructor adds some commonly interesting fields to the given logger. +func DefaultLogConstructor(base logr.Logger, req *Request) logr.Logger { + if req != nil { + return base.WithValues("object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) + } + return base +} + +// StandaloneOptions let you configure a StandaloneWebhook. +type StandaloneOptions struct { + // Logger to be used by the webhook. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + // MetricsPath is used for labelling prometheus metrics + // by the path is served on. + // If none is set, prometheus metrics will not be generated. + MetricsPath string +} + +// StandaloneWebhook prepares a webhook for use without a webhook.Server, +// passing in the information normally populated by webhook.Server +// and instrumenting the webhook with metrics. +// +// Use this to attach your webhook to an arbitrary HTTP server or mux. +// +// Note that you are responsible for terminating TLS if you use StandaloneWebhook +// in your own server/mux. In order to be accessed by a kubernetes cluster, +// all webhook servers require TLS. +func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, error) { + if opts.Logger.GetSink() != nil { + hook.log = opts.Logger + } + if opts.MetricsPath == "" { + return hook, nil + } + return metrics.InstrumentedHook(opts.MetricsPath, hook), nil +} + +// requestContextKey is how we find the admission.Request in a context.Context. +type requestContextKey struct{} + +// RequestFromContext returns an admission.Request from ctx. +func RequestFromContext(ctx context.Context) (Request, error) { + if v, ok := ctx.Value(requestContextKey{}).(Request); ok { + return v, nil + } + + return Request{}, errors.New("admission.Request not found in context") +} + +// NewContextWithRequest returns a new Context, derived from ctx, which carries the +// provided admission.Request. +func NewContextWithRequest(ctx context.Context, req Request) context.Context { + return context.WithValue(ctx, requestContextKey{}, req) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook_test.go new file mode 100644 index 00000000000..c7fc3b09ace --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook_test.go @@ -0,0 +1,268 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "io" + "net/http" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + machinerytypes "k8s.io/apimachinery/pkg/types" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var _ = Describe("Admission Webhooks", func() { + var ( + logBuffer *gbytes.Buffer + testLogger logr.Logger + ) + + BeforeEach(func() { + logBuffer = gbytes.NewBuffer() + testLogger = zap.New(zap.JSONEncoder(), zap.WriteTo(io.MultiWriter(logBuffer, GinkgoWriter))) + }) + + allowHandler := func() *Webhook { + handler := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + }, + } + }, + } + webhook := &Webhook{ + Handler: handler, + } + + return webhook + } + + It("should invoke the handler to get a response", func() { + By("setting up a webhook with an allow handler") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that it allowed the request") + Expect(resp.Allowed).To(BeTrue()) + }) + + It("should ensure that the response's UID is set to the request's UID", func() { + By("setting up a webhook") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{AdmissionRequest: admissionv1.AdmissionRequest{UID: "foobar"}}) + + By("checking that the response share's the request's UID") + Expect(resp.UID).To(Equal(machinerytypes.UID("foobar"))) + }) + + It("should populate the status on a response if one is not provided", func() { + By("setting up a webhook") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that the response share's the request's UID") + Expect(resp.Result).To(Equal(&metav1.Status{Code: http.StatusOK})) + }) + + It("shouldn't overwrite the status on a response", func() { + By("setting up a webhook that sets a status") + webhook := &Webhook{ + Handler: HandlerFunc(func(ctx context.Context, req Request) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{Message: "Ground Control to Major Tom"}, + }, + } + }), + } + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that the message is intact") + Expect(resp.Result).NotTo(BeNil()) + Expect(resp.Result.Message).To(Equal("Ground Control to Major Tom")) + }) + + It("should serialize patch operations into a single jsonpatch blob", func() { + By("setting up a webhook with a patching handler") + webhook := &Webhook{ + Handler: HandlerFunc(func(ctx context.Context, req Request) Response { + return Patched("", jsonpatch.Operation{Operation: "add", Path: "/a", Value: 2}, jsonpatch.Operation{Operation: "replace", Path: "/b", Value: 4}) + }), + } + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that a JSON patch is populated on the response") + patchType := admissionv1.PatchTypeJSONPatch + Expect(resp.PatchType).To(Equal(&patchType)) + Expect(resp.Patch).To(Equal([]byte(`[{"op":"add","path":"/a","value":2},{"op":"replace","path":"/b","value":4}]`))) + }) + + It("should pass a request logger via the context", func() { + By("setting up a webhook that uses the request logger") + webhook := &Webhook{ + Handler: HandlerFunc(func(ctx context.Context, req Request) Response { + logf.FromContext(ctx).Info("Received request") + + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + }, + } + }), + log: testLogger, + } + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{AdmissionRequest: admissionv1.AdmissionRequest{ + UID: "test123", + Name: "foo", + Namespace: "bar", + Resource: metav1.GroupVersionResource{ + Group: "apps", + Version: "v1", + Resource: "deployments", + }, + UserInfo: authenticationv1.UserInfo{ + Username: "tim", + }, + }}) + Expect(resp.Allowed).To(BeTrue()) + + By("checking that the log message contains the request fields") + Eventually(logBuffer).Should(gbytes.Say(`"msg":"Received request","object":{"name":"foo","namespace":"bar"},"namespace":"bar","name":"foo","resource":{"group":"apps","version":"v1","resource":"deployments"},"user":"tim","requestID":"test123"}`)) + }) + + It("should pass a request logger created by LogConstructor via the context", func() { + By("setting up a webhook that uses the request logger") + webhook := &Webhook{ + Handler: HandlerFunc(func(ctx context.Context, req Request) Response { + logf.FromContext(ctx).Info("Received request") + + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + }, + } + }), + LogConstructor: func(base logr.Logger, req *Request) logr.Logger { + return base.WithValues("operation", req.Operation, "requestID", req.UID) + }, + log: testLogger, + } + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{AdmissionRequest: admissionv1.AdmissionRequest{ + UID: "test123", + Operation: admissionv1.Create, + }}) + Expect(resp.Allowed).To(BeTrue()) + + By("checking that the log message contains the request fields") + Eventually(logBuffer).Should(gbytes.Say(`"msg":"Received request","operation":"CREATE","requestID":"test123"}`)) + }) + + Describe("panic recovery", func() { + It("should recover panic if RecoverPanic is true", func() { + panicHandler := func() *Webhook { + handler := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("fake panic test") + }, + } + webhook := &Webhook{ + Handler: handler, + RecoverPanic: true, + } + + return webhook + } + + By("setting up a webhook with a panicking handler") + webhook := panicHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that it errored the request") + Expect(resp.Allowed).To(BeFalse()) + Expect(resp.Result.Code).To(Equal(int32(http.StatusInternalServerError))) + Expect(resp.Result.Message).To(Equal("panic: fake panic test [recovered]")) + }) + + It("should not recover panic if RecoverPanic is false by default", func() { + panicHandler := func() *Webhook { + handler := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("fake panic test") + }, + } + webhook := &Webhook{ + Handler: handler, + } + + return webhook + } + + By("setting up a webhook with a panicking handler") + defer func() { + Expect(recover()).ShouldNot(BeNil()) + }() + webhook := panicHandler() + + By("invoking the webhook") + webhook.Handle(context.Background(), Request{}) + }) + }) +}) + +var _ = Describe("Should be able to write/read admission.Request to/from context", func() { + ctx := context.Background() + testRequest := Request{ + admissionv1.AdmissionRequest{ + UID: "test-uid", + }, + } + + ctx = NewContextWithRequest(ctx, testRequest) + + gotRequest, err := RequestFromContext(ctx) + Expect(err).To(Not(HaveOccurred())) + Expect(gotRequest).To(Equal(testRequest)) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go new file mode 100644 index 00000000000..293137db498 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go @@ -0,0 +1,79 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook + +import ( + "gomodules.xyz/jsonpatch/v2" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// define some aliases for common bits of the webhook functionality + +// Defaulter defines functions for setting defaults on resources. +type Defaulter = admission.Defaulter + +// Validator defines functions for validating an operation. +type Validator = admission.Validator + +// CustomDefaulter defines functions for setting defaults on resources. +type CustomDefaulter = admission.CustomDefaulter + +// CustomValidator defines functions for validating an operation. +type CustomValidator = admission.CustomValidator + +// AdmissionRequest defines the input for an admission handler. +// It contains information to identify the object in +// question (group, version, kind, resource, subresource, +// name, namespace), as well as the operation in question +// (e.g. Get, Create, etc), and the object itself. +type AdmissionRequest = admission.Request + +// AdmissionResponse is the output of an admission handler. +// It contains a response indicating if a given +// operation is allowed, as well as a set of patches +// to mutate the object in the case of a mutating admission handler. +type AdmissionResponse = admission.Response + +// Admission is webhook suitable for registration with the server +// an admission webhook that validates API operations and potentially +// mutates their contents. +type Admission = admission.Webhook + +// AdmissionHandler knows how to process admission requests, validating them, +// and potentially mutating the objects they contain. +type AdmissionHandler = admission.Handler + +// AdmissionDecoder knows how to decode objects from admission requests. +type AdmissionDecoder = admission.Decoder + +// JSONPatchOp represents a single JSONPatch patch operation. +type JSONPatchOp = jsonpatch.Operation + +var ( + // Allowed indicates that the admission request should be allowed for the given reason. + Allowed = admission.Allowed + + // Denied indicates that the admission request should be denied for the given reason. + Denied = admission.Denied + + // Patched indicates that the admission request should be allowed for the given reason, + // and that the contained object should be mutated using the given patches. + Patched = admission.Patched + + // Errored indicates that an error occurred in the admission request. + Errored = admission.Errored +) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/authentication_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/authentication_suite_test.go new file mode 100644 index 00000000000..29f7b3e17e8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/authentication_suite_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestAuthenticationWebhook(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Authentication Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/doc.go new file mode 100644 index 00000000000..d2b85f378c5 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package authentication provides implementation for authentication webhook and +methods to implement authentication webhook handlers. + +See examples/tokenreview/ for an example of authentication webhooks. +*/ +package authentication diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http.go new file mode 100644 index 00000000000..51bc93ee195 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http.go @@ -0,0 +1,146 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + + authenticationv1 "k8s.io/api/authentication/v1" + authenticationv1beta1 "k8s.io/api/authentication/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var authenticationScheme = runtime.NewScheme() +var authenticationCodecs = serializer.NewCodecFactory(authenticationScheme) + +func init() { + utilruntime.Must(authenticationv1.AddToScheme(authenticationScheme)) + utilruntime.Must(authenticationv1beta1.AddToScheme(authenticationScheme)) +} + +var _ http.Handler = &Webhook{} + +func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var body []byte + var err error + ctx := r.Context() + if wh.WithContextFunc != nil { + ctx = wh.WithContextFunc(ctx, r) + } + + var reviewResponse Response + if r.Body == nil { + err = errors.New("request body is empty") + wh.getLogger(nil).Error(err, "bad request") + reviewResponse = Errored(err) + wh.writeResponse(w, reviewResponse) + return + } + + defer r.Body.Close() + if body, err = io.ReadAll(r.Body); err != nil { + wh.getLogger(nil).Error(err, "unable to read the body from the incoming request") + reviewResponse = Errored(err) + wh.writeResponse(w, reviewResponse) + return + } + + // verify the content type is accurate + if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { + err = fmt.Errorf("contentType=%s, expected application/json", contentType) + wh.getLogger(nil).Error(err, "unable to process a request with unknown content type") + reviewResponse = Errored(err) + wh.writeResponse(w, reviewResponse) + return + } + + // Both v1 and v1beta1 TokenReview types are exactly the same, so the v1beta1 type can + // be decoded into the v1 type. The v1beta1 api is deprecated as of 1.19 and will be + // removed in authenticationv1.22. However the runtime codec's decoder guesses which type to + // decode into by type name if an Object's TypeMeta isn't set. By setting TypeMeta of an + // unregistered type to the v1 GVK, the decoder will coerce a v1beta1 TokenReview to authenticationv1. + // The actual TokenReview GVK will be used to write a typed response in case the + // webhook config permits multiple versions, otherwise this response will fail. + req := Request{} + ar := unversionedTokenReview{} + // avoid an extra copy + ar.TokenReview = &req.TokenReview + ar.SetGroupVersionKind(authenticationv1.SchemeGroupVersion.WithKind("TokenReview")) + _, actualTokRevGVK, err := authenticationCodecs.UniversalDeserializer().Decode(body, nil, &ar) + if err != nil { + wh.getLogger(nil).Error(err, "unable to decode the request") + reviewResponse = Errored(err) + wh.writeResponse(w, reviewResponse) + return + } + wh.getLogger(&req).V(4).Info("received request") + + if req.Spec.Token == "" { + err = errors.New("token is empty") + wh.getLogger(&req).Error(err, "bad request") + reviewResponse = Errored(err) + wh.writeResponse(w, reviewResponse) + return + } + + reviewResponse = wh.Handle(ctx, req) + wh.writeResponseTyped(w, reviewResponse, actualTokRevGVK) +} + +// writeResponse writes response to w generically, i.e. without encoding GVK information. +func (wh *Webhook) writeResponse(w io.Writer, response Response) { + wh.writeTokenResponse(w, response.TokenReview) +} + +// writeResponseTyped writes response to w with GVK set to tokRevGVK, which is necessary +// if multiple TokenReview versions are permitted by the webhook. +func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, tokRevGVK *schema.GroupVersionKind) { + ar := response.TokenReview + + // Default to a v1 TokenReview, otherwise the API server may not recognize the request + // if multiple TokenReview versions are permitted by the webhook config. + if tokRevGVK == nil || *tokRevGVK == (schema.GroupVersionKind{}) { + ar.SetGroupVersionKind(authenticationv1.SchemeGroupVersion.WithKind("TokenReview")) + } else { + ar.SetGroupVersionKind(*tokRevGVK) + } + wh.writeTokenResponse(w, ar) +} + +// writeTokenResponse writes ar to w. +func (wh *Webhook) writeTokenResponse(w io.Writer, ar authenticationv1.TokenReview) { + if err := json.NewEncoder(w).Encode(ar); err != nil { + wh.getLogger(nil).Error(err, "unable to encode the response") + wh.writeResponse(w, Errored(err)) + } + res := ar + wh.getLogger(nil).V(4).Info("wrote response", "requestID", res.UID, "authenticated", res.Status.Authenticated) +} + +// unversionedTokenReview is used to decode both v1 and v1beta1 TokenReview types. +type unversionedTokenReview struct { + *authenticationv1.TokenReview +} + +var _ runtime.Object = &unversionedTokenReview{} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http_test.go new file mode 100644 index 00000000000..86bd5d01532 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/http_test.go @@ -0,0 +1,208 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "bytes" + "context" + "fmt" + "io" + "net/http" + "net/http/httptest" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + authenticationv1 "k8s.io/api/authentication/v1" +) + +var _ = Describe("Authentication Webhooks", func() { + + const ( + gvkJSONv1 = `"kind":"TokenReview","apiVersion":"authentication.k8s.io/v1"` + ) + + Describe("HTTP Handler", func() { + var respRecorder *httptest.ResponseRecorder + webhook := &Webhook{ + Handler: nil, + } + BeforeEach(func() { + respRecorder = &httptest.ResponseRecorder{ + Body: bytes.NewBuffer(nil), + } + }) + + It("should return bad-request when given an empty body", func() { + req := &http.Request{Body: nil} + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"request body is empty"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return bad-request when given the wrong content-type", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/foo"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBuffer(nil)}, + } + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"contentType=application/foo, expected application/json"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return bad-request when given an undecodable body", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString("{")}, + } + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"couldn't get version/kind; json parse error: unexpected end of JSON input"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return bad-request when given an undecodable body", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":""}}`)}, + } + + expected := `{"metadata":{"creationTimestamp":null},"spec":{},"status":{"user":{},"error":"token is empty"}} +` + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return the response given by the handler with version defaulted to v1", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + expected := fmt.Sprintf(`{%s,"metadata":{"creationTimestamp":null},"spec":{},"status":{"authenticated":true,"user":{}}} +`, gvkJSONv1) + + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should return the v1 response given by the handler", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(fmt.Sprintf(`{%s,"spec":{"token":"foobar"}}`, gvkJSONv1))}, + } + webhook := &Webhook{ + Handler: &fakeHandler{}, + } + + expected := fmt.Sprintf(`{%s,"metadata":{"creationTimestamp":null},"spec":{},"status":{"authenticated":true,"user":{}}} +`, gvkJSONv1) + webhook.ServeHTTP(respRecorder, req) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should present the Context from the HTTP request, if any", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + type ctxkey int + const key ctxkey = 1 + const value = "from-ctx" + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + <-ctx.Done() + return Authenticated(ctx.Value(key).(string), authenticationv1.UserInfo{}) + }, + }, + } + + expected := fmt.Sprintf(`{%s,"metadata":{"creationTimestamp":null},"spec":{},"status":{"authenticated":true,"user":{},"error":%q}} +`, gvkJSONv1, value) + + ctx, cancel := context.WithCancel(context.WithValue(context.Background(), key, value)) + cancel() + webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + + It("should mutate the Context from the HTTP request, if func supplied", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + type ctxkey int + const key ctxkey = 1 + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Authenticated(ctx.Value(key).(string), authenticationv1.UserInfo{}) + }, + }, + WithContextFunc: func(ctx context.Context, r *http.Request) context.Context { + return context.WithValue(ctx, key, r.Header["Content-Type"][0]) + }, + } + + expected := fmt.Sprintf(`{%s,"metadata":{"creationTimestamp":null},"spec":{},"status":{"authenticated":true,"user":{},"error":%q}} +`, gvkJSONv1, "application/json") + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) + }) +}) + +type nopCloser struct { + io.Reader +} + +func (nopCloser) Close() error { return nil } + +type fakeHandler struct { + invoked bool + fn func(context.Context, Request) Response +} + +func (h *fakeHandler) Handle(ctx context.Context, req Request) Response { + h.invoked = true + if h.fn != nil { + return h.fn(ctx, req) + } + return Response{TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + }, + }} +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response.go new file mode 100644 index 00000000000..3e1d362049c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response.go @@ -0,0 +1,63 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + authenticationv1 "k8s.io/api/authentication/v1" +) + +// Authenticated constructs a response indicating that the given token +// is valid. +func Authenticated(reason string, user authenticationv1.UserInfo) Response { + return ReviewResponse(true, user, reason) +} + +// Unauthenticated constructs a response indicating that the given token +// is not valid. +func Unauthenticated(reason string, user authenticationv1.UserInfo) Response { + return ReviewResponse(false, authenticationv1.UserInfo{}, reason) +} + +// Errored creates a new Response for error-handling a request. +func Errored(err error) Response { + return Response{ + TokenReview: authenticationv1.TokenReview{ + Spec: authenticationv1.TokenReviewSpec{}, + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + Error: err.Error(), + }, + }, + } +} + +// ReviewResponse returns a response for admitting a request. +func ReviewResponse(authenticated bool, user authenticationv1.UserInfo, err string, audiences ...string) Response { + resp := Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: authenticated, + User: user, + Audiences: audiences, + }, + }, + } + if len(err) > 0 { + resp.TokenReview.Status.Error = err + } + return resp +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response_test.go new file mode 100644 index 00000000000..6eeef87c115 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/response_test.go @@ -0,0 +1,160 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "errors" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + authenticationv1 "k8s.io/api/authentication/v1" +) + +var _ = Describe("Authentication Webhook Response Helpers", func() { + Describe("Authenticated", func() { + It("should return an 'allowed' response", func() { + Expect(Authenticated("", authenticationv1.UserInfo{})).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + User: authenticationv1.UserInfo{}, + }, + }, + }, + )) + }) + + It("should populate a status with a reason when a reason is given", func() { + Expect(Authenticated("acceptable", authenticationv1.UserInfo{})).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + User: authenticationv1.UserInfo{}, + Error: "acceptable", + }, + }, + }, + )) + }) + }) + + Describe("Unauthenticated", func() { + It("should return a 'not allowed' response", func() { + Expect(Unauthenticated("", authenticationv1.UserInfo{})).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + User: authenticationv1.UserInfo{}, + Error: "", + }, + }, + }, + )) + }) + + It("should populate a status with a reason when a reason is given", func() { + Expect(Unauthenticated("UNACCEPTABLE!", authenticationv1.UserInfo{})).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + User: authenticationv1.UserInfo{}, + Error: "UNACCEPTABLE!", + }, + }, + }, + )) + }) + }) + + Describe("Errored", func() { + It("should return a unauthenticated response with an error", func() { + err := errors.New("this is an error") + expected := Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + User: authenticationv1.UserInfo{}, + Error: err.Error(), + }, + }, + } + resp := Errored(err) + Expect(resp).To(Equal(expected)) + }) + }) + + Describe("ReviewResponse", func() { + It("should populate a status with a Error when a reason is given", func() { + By("checking that a message is populated for 'allowed' responses") + Expect(ReviewResponse(true, authenticationv1.UserInfo{}, "acceptable")).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + User: authenticationv1.UserInfo{}, + Error: "acceptable", + }, + }, + }, + )) + + By("checking that a message is populated for 'Unauthenticated' responses") + Expect(ReviewResponse(false, authenticationv1.UserInfo{}, "UNACCEPTABLE!")).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + User: authenticationv1.UserInfo{}, + Error: "UNACCEPTABLE!", + }, + }, + }, + )) + }) + + It("should return an authentication decision", func() { + By("checking that it returns an 'allowed' response when allowed is true") + Expect(ReviewResponse(true, authenticationv1.UserInfo{}, "")).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + User: authenticationv1.UserInfo{}, + }, + }, + }, + )) + + By("checking that it returns an 'Unauthenticated' response when allowed is false") + Expect(ReviewResponse(false, authenticationv1.UserInfo{}, "")).To(Equal( + Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: false, + User: authenticationv1.UserInfo{}, + }, + }, + }, + )) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook.go new file mode 100644 index 00000000000..5a0cd4cd25c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook.go @@ -0,0 +1,126 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "context" + "errors" + "net/http" + "sync" + + "github.com/go-logr/logr" + authenticationv1 "k8s.io/api/authentication/v1" + "k8s.io/klog/v2" + + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + errUnableToEncodeResponse = errors.New("unable to encode response") +) + +// Request defines the input for an authentication handler. +// It contains information to identify the object in +// question (group, version, kind, resource, subresource, +// name, namespace), as well as the operation in question +// (e.g. Get, Create, etc), and the object itself. +type Request struct { + authenticationv1.TokenReview +} + +// Response is the output of an authentication handler. +// It contains a response indicating if a given +// operation is allowed. +type Response struct { + authenticationv1.TokenReview +} + +// Complete populates any fields that are yet to be set in +// the underlying TokenResponse, It mutates the response. +func (r *Response) Complete(req Request) error { + r.UID = req.UID + + return nil +} + +// Handler can handle an TokenReview. +type Handler interface { + // Handle yields a response to an TokenReview. + // + // The supplied context is extracted from the received http.Request, allowing wrapping + // http.Handlers to inject values into and control cancelation of downstream request processing. + Handle(context.Context, Request) Response +} + +// HandlerFunc implements Handler interface using a single function. +type HandlerFunc func(context.Context, Request) Response + +var _ Handler = HandlerFunc(nil) + +// Handle process the TokenReview by invoking the underlying function. +func (f HandlerFunc) Handle(ctx context.Context, req Request) Response { + return f(ctx, req) +} + +// Webhook represents each individual webhook. +type Webhook struct { + // Handler actually processes an authentication request returning whether it was authenticated or unauthenticated, + // and potentially patches to apply to the handler. + Handler Handler + + // WithContextFunc will allow you to take the http.Request.Context() and + // add any additional information such as passing the request path or + // headers thus allowing you to read them from within the handler + WithContextFunc func(context.Context, *http.Request) context.Context + + setupLogOnce sync.Once + log logr.Logger +} + +// Handle processes TokenReview. +func (wh *Webhook) Handle(ctx context.Context, req Request) Response { + resp := wh.Handler.Handle(ctx, req) + if err := resp.Complete(req); err != nil { + wh.getLogger(&req).Error(err, "unable to encode response") + return Errored(errUnableToEncodeResponse) + } + + return resp +} + +// getLogger constructs a logger from the injected log and LogConstructor. +func (wh *Webhook) getLogger(req *Request) logr.Logger { + wh.setupLogOnce.Do(func() { + if wh.log.GetSink() == nil { + wh.log = logf.Log.WithName("authentication") + } + }) + + return logConstructor(wh.log, req) +} + +// logConstructor adds some commonly interesting fields to the given logger. +func logConstructor(base logr.Logger, req *Request) logr.Logger { + if req != nil { + return base.WithValues("object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "user", req.Status.User.Username, + "requestID", req.UID, + ) + } + return base +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook_test.go new file mode 100644 index 00000000000..3df446d898f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/authentication/webhook_test.go @@ -0,0 +1,106 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package authentication + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + machinerytypes "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("Authentication Webhooks", func() { + allowHandler := func() *Webhook { + handler := &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + return Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + }, + }, + } + }, + } + webhook := &Webhook{ + Handler: handler, + } + + return webhook + } + + It("should invoke the handler to get a response", func() { + By("setting up a webhook with an allow handler") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that it allowed the request") + Expect(resp.Status.Authenticated).To(BeTrue()) + }) + + It("should ensure that the response's UID is set to the request's UID", func() { + By("setting up a webhook") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{TokenReview: authenticationv1.TokenReview{ObjectMeta: metav1.ObjectMeta{UID: "foobar"}}}) + + By("checking that the response share's the request's UID") + Expect(resp.UID).To(Equal(machinerytypes.UID("foobar"))) + }) + + It("should populate the status on a response if one is not provided", func() { + By("setting up a webhook") + webhook := allowHandler() + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that the response share's the request's UID") + Expect(resp.Status).To(Equal(authenticationv1.TokenReviewStatus{Authenticated: true})) + }) + + It("shouldn't overwrite the status on a response", func() { + By("setting up a webhook that sets a status") + webhook := &Webhook{ + Handler: HandlerFunc(func(ctx context.Context, req Request) Response { + return Response{ + TokenReview: authenticationv1.TokenReview{ + Status: authenticationv1.TokenReviewStatus{ + Authenticated: true, + Error: "Ground Control to Major Tom", + }, + }, + } + }), + } + + By("invoking the webhook") + resp := webhook.Handle(context.Background(), Request{}) + + By("checking that the message is intact") + Expect(resp.Status).NotTo(BeNil()) + Expect(resp.Status.Authenticated).To(BeTrue()) + Expect(resp.Status.Error).To(Equal("Ground Control to Major Tom")) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go new file mode 100644 index 00000000000..249a364b381 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go @@ -0,0 +1,343 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package conversion provides implementation for CRD conversion webhook that implements handler for version conversion requests for types that are convertible. + +See pkg/conversion for interface definitions required to ensure an API Type is convertible. +*/ +package conversion + +import ( + "encoding/json" + "fmt" + "net/http" + + apix "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/conversion" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + log = logf.Log.WithName("conversion-webhook") +) + +func NewWebhookHandler(scheme *runtime.Scheme) http.Handler { + return &webhook{scheme: scheme, decoder: NewDecoder(scheme)} +} + +// webhook implements a CRD conversion webhook HTTP handler. +type webhook struct { + scheme *runtime.Scheme + decoder *Decoder +} + +// ensure Webhook implements http.Handler +var _ http.Handler = &webhook{} + +func (wh *webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + convertReview := &apix.ConversionReview{} + err := json.NewDecoder(r.Body).Decode(convertReview) + if err != nil { + log.Error(err, "failed to read conversion request") + w.WriteHeader(http.StatusBadRequest) + return + } + + if convertReview.Request == nil { + log.Error(nil, "conversion request is nil") + w.WriteHeader(http.StatusBadRequest) + return + } + + // TODO(droot): may be move the conversion logic to a separate module to + // decouple it from the http layer ? + resp, err := wh.handleConvertRequest(convertReview.Request) + if err != nil { + log.Error(err, "failed to convert", "request", convertReview.Request.UID) + convertReview.Response = errored(err) + } else { + convertReview.Response = resp + } + convertReview.Response.UID = convertReview.Request.UID + convertReview.Request = nil + + err = json.NewEncoder(w).Encode(convertReview) + if err != nil { + log.Error(err, "failed to write response") + return + } +} + +// handles a version conversion request. +func (wh *webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.ConversionResponse, error) { + if req == nil { + return nil, fmt.Errorf("conversion request is nil") + } + var objects []runtime.RawExtension + + for _, obj := range req.Objects { + src, gvk, err := wh.decoder.Decode(obj.Raw) + if err != nil { + return nil, err + } + dst, err := wh.allocateDstObject(req.DesiredAPIVersion, gvk.Kind) + if err != nil { + return nil, err + } + err = wh.convertObject(src, dst) + if err != nil { + return nil, err + } + objects = append(objects, runtime.RawExtension{Object: dst}) + } + return &apix.ConversionResponse{ + UID: req.UID, + ConvertedObjects: objects, + Result: metav1.Status{ + Status: metav1.StatusSuccess, + }, + }, nil +} + +// convertObject will convert given a src object to dst object. +// Note(droot): couldn't find a way to reduce the cyclomatic complexity under 10 +// without compromising readability, so disabling gocyclo linter +func (wh *webhook) convertObject(src, dst runtime.Object) error { + srcGVK := src.GetObjectKind().GroupVersionKind() + dstGVK := dst.GetObjectKind().GroupVersionKind() + + if srcGVK.GroupKind() != dstGVK.GroupKind() { + return fmt.Errorf("src %T and dst %T does not belong to same API Group", src, dst) + } + + if srcGVK == dstGVK { + return fmt.Errorf("conversion is not allowed between same type %T", src) + } + + srcIsHub, dstIsHub := isHub(src), isHub(dst) + srcIsConvertible, dstIsConvertible := isConvertible(src), isConvertible(dst) + + switch { + case srcIsHub && dstIsConvertible: + return dst.(conversion.Convertible).ConvertFrom(src.(conversion.Hub)) + case dstIsHub && srcIsConvertible: + return src.(conversion.Convertible).ConvertTo(dst.(conversion.Hub)) + case srcIsConvertible && dstIsConvertible: + return wh.convertViaHub(src.(conversion.Convertible), dst.(conversion.Convertible)) + default: + return fmt.Errorf("%T is not convertible to %T", src, dst) + } +} + +func (wh *webhook) convertViaHub(src, dst conversion.Convertible) error { + hub, err := wh.getHub(src) + if err != nil { + return err + } + + if hub == nil { + return fmt.Errorf("%s does not have any Hub defined", src) + } + + err = src.ConvertTo(hub) + if err != nil { + return fmt.Errorf("%T failed to convert to hub version %T : %w", src, hub, err) + } + + err = dst.ConvertFrom(hub) + if err != nil { + return fmt.Errorf("%T failed to convert from hub version %T : %w", dst, hub, err) + } + + return nil +} + +// getHub returns an instance of the Hub for passed-in object's group/kind. +func (wh *webhook) getHub(obj runtime.Object) (conversion.Hub, error) { + gvks, err := objectGVKs(wh.scheme, obj) + if err != nil { + return nil, err + } + if len(gvks) == 0 { + return nil, fmt.Errorf("error retrieving gvks for object : %v", obj) + } + + var hub conversion.Hub + var hubFoundAlready bool + for _, gvk := range gvks { + instance, err := wh.scheme.New(gvk) + if err != nil { + return nil, fmt.Errorf("failed to allocate an instance for gvk %v: %w", gvk, err) + } + if val, isHub := instance.(conversion.Hub); isHub { + if hubFoundAlready { + return nil, fmt.Errorf("multiple hub version defined for %T", obj) + } + hubFoundAlready = true + hub = val + } + } + return hub, nil +} + +// allocateDstObject returns an instance for a given GVK. +func (wh *webhook) allocateDstObject(apiVersion, kind string) (runtime.Object, error) { + gvk := schema.FromAPIVersionAndKind(apiVersion, kind) + + obj, err := wh.scheme.New(gvk) + if err != nil { + return obj, err + } + + t, err := meta.TypeAccessor(obj) + if err != nil { + return obj, err + } + + t.SetAPIVersion(apiVersion) + t.SetKind(kind) + + return obj, nil +} + +// IsConvertible determines if given type is convertible or not. For a type +// to be convertible, the group-kind needs to have a Hub type defined and all +// non-hub types must be able to convert to/from Hub. +func IsConvertible(scheme *runtime.Scheme, obj runtime.Object) (bool, error) { + var hubs, spokes, nonSpokes []runtime.Object + + gvks, err := objectGVKs(scheme, obj) + if err != nil { + return false, err + } + if len(gvks) == 0 { + return false, fmt.Errorf("error retrieving gvks for object : %v", obj) + } + + for _, gvk := range gvks { + instance, err := scheme.New(gvk) + if err != nil { + return false, fmt.Errorf("failed to allocate an instance for gvk %v: %w", gvk, err) + } + + if isHub(instance) { + hubs = append(hubs, instance) + continue + } + + if !isConvertible(instance) { + nonSpokes = append(nonSpokes, instance) + continue + } + + spokes = append(spokes, instance) + } + + if len(gvks) == 1 { + return false, nil // single version + } + + if len(hubs) == 0 && len(spokes) == 0 { + // multiple version detected with no conversion implementation. This is + // true for multi-version built-in types. + return false, nil + } + + if len(hubs) == 1 && len(nonSpokes) == 0 { // convertible + return true, nil + } + + return false, PartialImplementationError{ + hubs: hubs, + nonSpokes: nonSpokes, + spokes: spokes, + } +} + +// objectGVKs returns all (Group,Version,Kind) for the Group/Kind of given object. +func objectGVKs(scheme *runtime.Scheme, obj runtime.Object) ([]schema.GroupVersionKind, error) { + // NB: we should not use `obj.GetObjectKind().GroupVersionKind()` to get the + // GVK here, since it is parsed from apiVersion and kind fields and it may + // return empty GVK if obj is an uninitialized object. + objGVKs, _, err := scheme.ObjectKinds(obj) + if err != nil { + return nil, err + } + if len(objGVKs) != 1 { + return nil, fmt.Errorf("expect to get only one GVK for %v", obj) + } + objGVK := objGVKs[0] + knownTypes := scheme.AllKnownTypes() + + var gvks []schema.GroupVersionKind + for gvk := range knownTypes { + if objGVK.GroupKind() == gvk.GroupKind() { + gvks = append(gvks, gvk) + } + } + return gvks, nil +} + +// PartialImplementationError represents an error due to partial conversion +// implementation such as hub without spokes, multiple hubs or spokes without hub. +type PartialImplementationError struct { + gvk schema.GroupVersionKind + hubs []runtime.Object + nonSpokes []runtime.Object + spokes []runtime.Object +} + +func (e PartialImplementationError) Error() string { + if len(e.hubs) == 0 { + return fmt.Sprintf("no hub defined for gvk %s", e.gvk) + } + if len(e.hubs) > 1 { + return fmt.Sprintf("multiple(%d) hubs defined for group-kind '%s' ", + len(e.hubs), e.gvk.GroupKind()) + } + if len(e.nonSpokes) > 0 { + return fmt.Sprintf("%d inconvertible types detected for group-kind '%s'", + len(e.nonSpokes), e.gvk.GroupKind()) + } + return "" +} + +// isHub determines if passed-in object is a Hub or not. +func isHub(obj runtime.Object) bool { + _, yes := obj.(conversion.Hub) + return yes +} + +// isConvertible determines if passed-in object is a convertible. +func isConvertible(obj runtime.Object) bool { + _, yes := obj.(conversion.Convertible) + return yes +} + +// helper to construct error response. +func errored(err error) *apix.ConversionResponse { + return &apix.ConversionResponse{ + Result: metav1.Status{ + Status: metav1.StatusFailure, + Message: err.Error(), + }, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_suite_test.go new file mode 100644 index 00000000000..7ca3c48ba26 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_suite_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package conversion + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestConversionWebhook(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "CRD conversion Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_test.go new file mode 100644 index 00000000000..be984e232bc --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion_test.go @@ -0,0 +1,360 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package conversion_test + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + appsv1beta1 "k8s.io/api/apps/v1beta1" + apix "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + kscheme "k8s.io/client-go/kubernetes/scheme" + + "sigs.k8s.io/controller-runtime/pkg/webhook/conversion" + jobsv1 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1" + jobsv2 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2" + jobsv3 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3" +) + +var _ = Describe("Conversion Webhook", func() { + + var respRecorder *httptest.ResponseRecorder + var decoder *conversion.Decoder + var scheme *runtime.Scheme + var wh http.Handler + + BeforeEach(func() { + respRecorder = &httptest.ResponseRecorder{ + Body: bytes.NewBuffer(nil), + } + + scheme = runtime.NewScheme() + Expect(kscheme.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv1.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv2.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv3.AddToScheme(scheme)).To(Succeed()) + + decoder = conversion.NewDecoder(scheme) + wh = conversion.NewWebhookHandler(scheme) + }) + + doRequest := func(convReq *apix.ConversionReview) *apix.ConversionReview { + var payload bytes.Buffer + + Expect(json.NewEncoder(&payload).Encode(convReq)).Should(Succeed()) + + convReview := &apix.ConversionReview{} + req := &http.Request{ + Body: io.NopCloser(bytes.NewReader(payload.Bytes())), + } + wh.ServeHTTP(respRecorder, req) + Expect(json.NewDecoder(respRecorder.Result().Body).Decode(convReview)).To(Succeed()) + return convReview + } + + makeV1Obj := func() *jobsv1.ExternalJob { + return &jobsv1.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + Spec: jobsv1.ExternalJobSpec{ + RunAt: "every 2 seconds", + }, + } + } + + makeV2Obj := func() *jobsv2.ExternalJob { + return &jobsv2.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v2", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + Spec: jobsv2.ExternalJobSpec{ + ScheduleAt: "every 2 seconds", + }, + } + } + + It("should convert spoke to hub successfully", func() { + + v1Obj := makeV1Obj() + + expected := &jobsv2.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v2", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + Spec: jobsv2.ExternalJobSpec{ + ScheduleAt: "every 2 seconds", + }, + } + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + DesiredAPIVersion: "jobs.testprojects.kb.io/v2", + Objects: []runtime.RawExtension{ + { + Object: v1Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + + Expect(convReview.Response.ConvertedObjects).To(HaveLen(1)) + Expect(convReview.Response.Result.Status).To(Equal(metav1.StatusSuccess)) + got, _, err := decoder.Decode(convReview.Response.ConvertedObjects[0].Raw) + Expect(err).NotTo(HaveOccurred()) + Expect(got).To(Equal(expected)) + }) + + It("should convert hub to spoke successfully", func() { + + v2Obj := makeV2Obj() + + expected := &jobsv1.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + Spec: jobsv1.ExternalJobSpec{ + RunAt: "every 2 seconds", + }, + } + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + DesiredAPIVersion: "jobs.testprojects.kb.io/v1", + Objects: []runtime.RawExtension{ + { + Object: v2Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + + Expect(convReview.Response.ConvertedObjects).To(HaveLen(1)) + Expect(convReview.Response.Result.Status).To(Equal(metav1.StatusSuccess)) + got, _, err := decoder.Decode(convReview.Response.ConvertedObjects[0].Raw) + Expect(err).NotTo(HaveOccurred()) + Expect(got).To(Equal(expected)) + }) + + It("should convert spoke to spoke successfully", func() { + + v1Obj := makeV1Obj() + + expected := &jobsv3.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + Spec: jobsv3.ExternalJobSpec{ + DeferredAt: "every 2 seconds", + }, + } + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + DesiredAPIVersion: "jobs.testprojects.kb.io/v3", + Objects: []runtime.RawExtension{ + { + Object: v1Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + + Expect(convReview.Response.ConvertedObjects).To(HaveLen(1)) + Expect(convReview.Response.Result.Status).To(Equal(metav1.StatusSuccess)) + got, _, err := decoder.Decode(convReview.Response.ConvertedObjects[0].Raw) + Expect(err).NotTo(HaveOccurred()) + Expect(got).To(Equal(expected)) + }) + + It("should return error when dest/src objects belong to different API groups", func() { + v1Obj := makeV1Obj() + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + // request conversion for different group + DesiredAPIVersion: "jobss.example.org/v2", + Objects: []runtime.RawExtension{ + { + Object: v1Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + Expect(convReview.Response.Result.Status).To(Equal("Failure")) + Expect(convReview.Response.ConvertedObjects).To(BeEmpty()) + }) + + It("should return error when dest/src objects are of same type", func() { + + v1Obj := makeV1Obj() + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + DesiredAPIVersion: "jobs.testprojects.kb.io/v1", + Objects: []runtime.RawExtension{ + { + Object: v1Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + Expect(convReview.Response.Result.Status).To(Equal("Failure")) + Expect(convReview.Response.ConvertedObjects).To(BeEmpty()) + }) + + It("should return error when the API group does not have a hub defined", func() { + + v1Obj := &appsv1beta1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "obj-1", + }, + } + + convReq := &apix.ConversionReview{ + TypeMeta: metav1.TypeMeta{}, + Request: &apix.ConversionRequest{ + DesiredAPIVersion: "apps/v1", + Objects: []runtime.RawExtension{ + { + Object: v1Obj, + }, + }, + }, + } + + convReview := doRequest(convReq) + Expect(convReview.Response.Result.Status).To(Equal("Failure")) + Expect(convReview.Response.ConvertedObjects).To(BeEmpty()) + }) + +}) + +var _ = Describe("IsConvertible", func() { + + var scheme *runtime.Scheme + + BeforeEach(func() { + scheme = runtime.NewScheme() + + Expect(kscheme.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv1.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv2.AddToScheme(scheme)).To(Succeed()) + Expect(jobsv3.AddToScheme(scheme)).To(Succeed()) + }) + + It("should not error for uninitialized types", func() { + obj := &jobsv2.ExternalJob{} + + ok, err := conversion.IsConvertible(scheme, obj) + Expect(err).NotTo(HaveOccurred()) + Expect(ok).To(BeTrue()) + }) + + It("should not error for unstructured types", func() { + obj := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "ExternalJob", + "apiVersion": "jobs.testprojects.kb.io/v2", + }, + } + + ok, err := conversion.IsConvertible(scheme, obj) + Expect(err).NotTo(HaveOccurred()) + Expect(ok).To(BeTrue()) + }) + + It("should return true for convertible types", func() { + obj := &jobsv2.ExternalJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "ExternalJob", + APIVersion: "jobs.testprojects.kb.io/v2", + }, + } + + ok, err := conversion.IsConvertible(scheme, obj) + Expect(err).NotTo(HaveOccurred()) + Expect(ok).To(BeTrue()) + }) + + It("should return false for a non convertible type", func() { + obj := &appsv1beta1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1beta1", + }, + } + + ok, err := conversion.IsConvertible(scheme, obj) + Expect(err).NotTo(HaveOccurred()) + Expect(ok).ToNot(BeTrue()) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go new file mode 100644 index 00000000000..b6bb8bd9384 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go @@ -0,0 +1,50 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package conversion + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Decoder knows how to decode the contents of a CRD version conversion +// request into a concrete object. +// TODO(droot): consider reusing decoder from admission pkg for this. +type Decoder struct { + codecs serializer.CodecFactory +} + +// NewDecoder creates a Decoder given the runtime.Scheme +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} +} + +// Decode decodes the inlined object. +func (d *Decoder) Decode(content []byte) (runtime.Object, *schema.GroupVersionKind, error) { + deserializer := d.codecs.UniversalDeserializer() + return deserializer.Decode(content, nil, nil) +} + +// DecodeInto decodes the inlined object in the into the passed-in runtime.Object. +func (d *Decoder) DecodeInto(content []byte, into runtime.Object) error { + deserializer := d.codecs.UniversalDeserializer() + return runtime.DecodeInto(deserializer, content, into) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/.gitignore b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/.gitignore new file mode 100644 index 00000000000..d97ffc5159b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/.gitignore @@ -0,0 +1,24 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Kubernetes Generated files - skip generated files, except for vendored files + +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/Makefile b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/Makefile new file mode 100644 index 00000000000..2d9d3dda15a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/Makefile @@ -0,0 +1,64 @@ + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) +CRD_OPTIONS ?= "crd:trivialVersions=true" + +all: manager + +# Run tests +test: generate fmt vet manifests + go test ./api/... ./controllers/... -coverprofile cover.out + +# Build manager binary +manager: generate fmt vet + go build -o bin/manager main.go + +# Run against the configured Kubernetes cluster in ~/.kube/config +run: generate fmt vet + go run ./main.go + +# Install CRDs into a cluster +install: manifests + kubectl apply -f config/crd/bases + +# Deploy controller in the configured Kubernetes cluster in ~/.kube/config +deploy: manifests + kubectl apply -f config/crd/bases + kustomize build config/default | kubectl apply -f - + +# Generate manifests e.g. CRD, RBAC etc. +manifests: controller-gen + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +# Run go fmt against code +fmt: + go fmt ./... + +# Run go vet against code +vet: + go vet ./... + +# Generate code +generate: controller-gen + $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths=./api/... + +# Build the docker image +docker-build: test + docker build . -t ${IMG} + @echo "updating kustomize image patch file for manager resource" + sed -i'' -e 's@image: .*@image: '"${IMG}"'@' ./config/default/manager_image_patch.yaml + +# Push the docker image +docker-push: + docker push ${IMG} + +# find or download controller-gen +# download controller-gen if necessary +controller-gen: +ifeq (, $(shell which controller-gen)) + go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.0-beta.2 +CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen +else +CONTROLLER_GEN=$(shell which controller-gen) +endif diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/PROJECT b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/PROJECT new file mode 100644 index 00000000000..6b168dcbc11 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/PROJECT @@ -0,0 +1,13 @@ +version: "2" +domain: testprojects.kb.io +repo: sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata +resources: +- group: jobs + version: v1 + kind: ExternalJob +- group: jobs + version: v2 + kind: ExternalJob +- group: jobs + version: v3 + kind: ExternalJob diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/externaljob_types.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/externaljob_types.go new file mode 100644 index 00000000000..bf99e2a2040 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/externaljob_types.go @@ -0,0 +1,92 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + v2 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ExternalJobSpec defines the desired state of ExternalJob +type ExternalJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + RunAt string `json:"runAt"` +} + +// ExternalJobStatus defines the observed state of ExternalJob +type ExternalJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +kubebuilder:object:root=true + +// ExternalJob is the Schema for the externaljobs API +type ExternalJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExternalJobSpec `json:"spec,omitempty"` + Status ExternalJobStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExternalJobList contains a list of ExternalJob +type ExternalJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExternalJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExternalJob{}, &ExternalJobList{}) +} + +// ConvertTo implements conversion logic to convert to Hub type (v2.ExternalJob +// in this case) +func (ej *ExternalJob) ConvertTo(dst conversion.Hub) error { + switch t := dst.(type) { + case *v2.ExternalJob: + jobv2 := dst.(*v2.ExternalJob) + jobv2.ObjectMeta = ej.ObjectMeta + jobv2.Spec.ScheduleAt = ej.Spec.RunAt + return nil + default: + return fmt.Errorf("unsupported type %v", t) + } +} + +// ConvertFrom implements conversion logic to convert from Hub type (v2.ExternalJob +// in this case) +func (ej *ExternalJob) ConvertFrom(src conversion.Hub) error { + switch t := src.(type) { + case *v2.ExternalJob: + jobv2 := src.(*v2.ExternalJob) + ej.ObjectMeta = jobv2.ObjectMeta + ej.Spec.RunAt = jobv2.Spec.ScheduleAt + return nil + default: + return fmt.Errorf("unsupported type %v", t) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/groupversion_info.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/groupversion_info.go new file mode 100644 index 00000000000..5bbef617869 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/groupversion_info.go @@ -0,0 +1,35 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1 contains API Schema definitions for the jobs v1 API group +// +kubebuilder:object:generate=true +// +groupName=jobs.testprojects.kb.io +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "jobs.testprojects.kb.io", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..7208ba8c697 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,113 @@ +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// autogenerated by controller-gen object, do not modify manually + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJob) DeepCopyInto(out *ExternalJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJob. +func (in *ExternalJob) DeepCopy() *ExternalJob { + if in == nil { + return nil + } + out := new(ExternalJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobList) DeepCopyInto(out *ExternalJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExternalJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobList. +func (in *ExternalJobList) DeepCopy() *ExternalJobList { + if in == nil { + return nil + } + out := new(ExternalJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobSpec) DeepCopyInto(out *ExternalJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobSpec. +func (in *ExternalJobSpec) DeepCopy() *ExternalJobSpec { + if in == nil { + return nil + } + out := new(ExternalJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobStatus) DeepCopyInto(out *ExternalJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobStatus. +func (in *ExternalJobStatus) DeepCopy() *ExternalJobStatus { + if in == nil { + return nil + } + out := new(ExternalJobStatus) + in.DeepCopyInto(out) + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/externaljob_types.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/externaljob_types.go new file mode 100644 index 00000000000..de5a03a212a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/externaljob_types.go @@ -0,0 +1,68 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ExternalJobSpec defines the desired state of ExternalJob +type ExternalJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + ScheduleAt string `json:"scheduleAt"` +} + +// ExternalJobStatus defines the observed state of ExternalJob +type ExternalJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +kubebuilder:object:root=true + +// ExternalJob is the Schema for the externaljobs API +type ExternalJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExternalJobSpec `json:"spec,omitempty"` + Status ExternalJobStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExternalJobList contains a list of ExternalJob +type ExternalJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExternalJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExternalJob{}, &ExternalJobList{}) +} + +// Hub is just a marker method to indicate that v2.ExternalJob is the Hub type +// in this case. +// v2.ExternalJob is the storage version so mark this as Hub. +// Storage version doesn't need to implement any conversion methods because +// default conversionHandler implements conversion logic for storage version. +// TODO(droot): Add comment annotation here to mark it as storage version +func (ej *ExternalJob) Hub() {} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/groupversion_info.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/groupversion_info.go new file mode 100644 index 00000000000..5019111a00c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/groupversion_info.go @@ -0,0 +1,35 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v2 contains API Schema definitions for the jobs v2 API group +// +kubebuilder:object:generate=true +// +groupName=jobs.testprojects.kb.io +package v2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "jobs.testprojects.kb.io", Version: "v2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/zz_generated.deepcopy.go new file mode 100644 index 00000000000..53c9f758b1d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2/zz_generated.deepcopy.go @@ -0,0 +1,113 @@ +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// autogenerated by controller-gen object, do not modify manually + +package v2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJob) DeepCopyInto(out *ExternalJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJob. +func (in *ExternalJob) DeepCopy() *ExternalJob { + if in == nil { + return nil + } + out := new(ExternalJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobList) DeepCopyInto(out *ExternalJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExternalJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobList. +func (in *ExternalJobList) DeepCopy() *ExternalJobList { + if in == nil { + return nil + } + out := new(ExternalJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobSpec) DeepCopyInto(out *ExternalJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobSpec. +func (in *ExternalJobSpec) DeepCopy() *ExternalJobSpec { + if in == nil { + return nil + } + out := new(ExternalJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobStatus) DeepCopyInto(out *ExternalJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobStatus. +func (in *ExternalJobStatus) DeepCopy() *ExternalJobStatus { + if in == nil { + return nil + } + out := new(ExternalJobStatus) + in.DeepCopyInto(out) + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/externaljob_types.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/externaljob_types.go new file mode 100644 index 00000000000..15c438f68a1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/externaljob_types.go @@ -0,0 +1,92 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v3 + +import ( + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + v2 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ExternalJobSpec defines the desired state of ExternalJob +type ExternalJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + DeferredAt string `json:"deferredAt"` +} + +// ExternalJobStatus defines the observed state of ExternalJob +type ExternalJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +kubebuilder:object:root=true + +// ExternalJob is the Schema for the externaljobs API +type ExternalJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ExternalJobSpec `json:"spec,omitempty"` + Status ExternalJobStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ExternalJobList contains a list of ExternalJob +type ExternalJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ExternalJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ExternalJob{}, &ExternalJobList{}) +} + +// ConvertTo implements conversion logic to convert to Hub type (v2.ExternalJob +// in this case) +func (ej *ExternalJob) ConvertTo(dst conversion.Hub) error { + switch t := dst.(type) { + case *v2.ExternalJob: + jobv2 := dst.(*v2.ExternalJob) + jobv2.ObjectMeta = ej.ObjectMeta + jobv2.Spec.ScheduleAt = ej.Spec.DeferredAt + return nil + default: + return fmt.Errorf("unsupported type %v", t) + } +} + +// ConvertFrom implements conversion logic to convert from Hub type (v2.ExternalJob +// in this case) +func (ej *ExternalJob) ConvertFrom(src conversion.Hub) error { + switch t := src.(type) { + case *v2.ExternalJob: + jobv2 := src.(*v2.ExternalJob) + ej.ObjectMeta = jobv2.ObjectMeta + ej.Spec.DeferredAt = jobv2.Spec.ScheduleAt + return nil + default: + return fmt.Errorf("unsupported type %v", t) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/groupversion_info.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/groupversion_info.go new file mode 100644 index 00000000000..1ae8269614a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/groupversion_info.go @@ -0,0 +1,35 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v3 contains API Schema definitions for the jobs v3 API group +// +kubebuilder:object:generate=true +// +groupName=jobs.testprojects.kb.io +package v3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "jobs.testprojects.kb.io", Version: "v3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/zz_generated.deepcopy.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/zz_generated.deepcopy.go new file mode 100644 index 00000000000..a90942b427c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3/zz_generated.deepcopy.go @@ -0,0 +1,113 @@ +// +build !ignore_autogenerated + +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// autogenerated by controller-gen object, do not modify manually + +package v3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJob) DeepCopyInto(out *ExternalJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJob. +func (in *ExternalJob) DeepCopy() *ExternalJob { + if in == nil { + return nil + } + out := new(ExternalJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobList) DeepCopyInto(out *ExternalJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExternalJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobList. +func (in *ExternalJobList) DeepCopy() *ExternalJobList { + if in == nil { + return nil + } + out := new(ExternalJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobSpec) DeepCopyInto(out *ExternalJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobSpec. +func (in *ExternalJobSpec) DeepCopy() *ExternalJobSpec { + if in == nil { + return nil + } + out := new(ExternalJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalJobStatus) DeepCopyInto(out *ExternalJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalJobStatus. +func (in *ExternalJobStatus) DeepCopy() *ExternalJobStatus { + if in == nil { + return nil + } + out := new(ExternalJobStatus) + in.DeepCopyInto(out) + return out +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/hack/boilerplate.go.txt b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b92001fb4ed --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/hack/boilerplate.go.txt @@ -0,0 +1,14 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/main.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/main.go new file mode 100644 index 00000000000..a3922da009a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/main.go @@ -0,0 +1,74 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "flag" + "os" + + "k8s.io/apimachinery/pkg/runtime" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + jobsv1 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v1" + jobsv2 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2" + jobsv3 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v3" + // +kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + + jobsv1.AddToScheme(scheme) + jobsv2.AddToScheme(scheme) + jobsv3.AddToScheme(scheme) + // +kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, + "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") + flag.Parse() + + ctrl.SetLogger(zap.Logger(true)) + + mgr, err := ctrl.NewManager(context.Background(), ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + MetricsBindAddress: metricsAddr, + LeaderElection: enableLeaderElection, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + // +kubebuilder:scaffold:builder + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go new file mode 100644 index 00000000000..2c93f0d995b --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package webhook provides methods to build and bootstrap a webhook server. + +Currently, it only supports admission webhooks. It will support CRD conversion webhooks in the near future. +*/ +package webhook + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("webhook") diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/example_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/example_test.go new file mode 100644 index 00000000000..f68008755d3 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/example_test.go @@ -0,0 +1,151 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook_test + +import ( + "context" + "net/http" + + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + . "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +var ( + // Build webhooks used for the various server + // configuration options + // + // These handlers could be also be implementations + // of the AdmissionHandler interface for more complex + // implementations. + mutatingHook = &Admission{ + Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { + return Patched("some changes", + JSONPatchOp{Operation: "add", Path: "/metadata/annotations/access", Value: "granted"}, + JSONPatchOp{Operation: "add", Path: "/metadata/annotations/reason", Value: "not so secret"}, + ) + }), + } + + validatingHook = &Admission{ + Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { + return Denied("none shall pass!") + }), + } +) + +// This example registers a webhooks to a webhook server +// that gets ran by a controller manager. +func Example() { + // Create a manager + // Note: GetConfigOrDie will os.Exit(1) w/o any message if no kube-config can be found + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) + if err != nil { + panic(err) + } + + // Create a webhook server. + hookServer := NewServer(Options{ + Port: 8443, + }) + if err := mgr.Add(hookServer); err != nil { + panic(err) + } + + // Register the webhooks in the server. + hookServer.Register("/mutating", mutatingHook) + hookServer.Register("/validating", validatingHook) + + // Start the server by starting a previously-set-up manager + err = mgr.Start(ctrl.SetupSignalHandler()) + if err != nil { + // handle error + panic(err) + } +} + +// This example creates a webhook server that can be +// ran without a controller manager. +// +// Note that this assumes and requires a valid TLS +// cert and key at the default locations +// tls.crt and tls.key. +func ExampleServer_Start() { + // Create a webhook server + hookServer := NewServer(Options{ + Port: 8443, + }) + + // Register the webhooks in the server. + hookServer.Register("/mutating", mutatingHook) + hookServer.Register("/validating", validatingHook) + + // Start the server without a manger + err := hookServer.Start(signals.SetupSignalHandler()) + if err != nil { + // handle error + panic(err) + } +} + +// This example creates a standalone webhook handler +// and runs it on a vanilla go HTTP server to demonstrate +// how you could run a webhook on an existing server +// without a controller manager. +func ExampleStandaloneWebhook() { + // Assume you have an existing HTTP server at your disposal + // configured as desired (e.g. with TLS). + // For this example just create a basic http.ServeMux + mux := http.NewServeMux() + port := ":8000" + + // Create the standalone HTTP handlers from our webhooks + mutatingHookHandler, err := admission.StandaloneWebhook(mutatingHook, admission.StandaloneOptions{ + // Logger let's you optionally pass + // a custom logger (defaults to log.Log global Logger) + Logger: logf.RuntimeLog.WithName("mutating-webhook"), + // MetricsPath let's you optionally + // provide the path it will be served on + // to be used for labelling prometheus metrics + // If none is set, prometheus metrics will not be generated. + MetricsPath: "/mutating", + }) + if err != nil { + // handle error + panic(err) + } + + validatingHookHandler, err := admission.StandaloneWebhook(validatingHook, admission.StandaloneOptions{ + Logger: logf.RuntimeLog.WithName("validating-webhook"), + MetricsPath: "/validating", + }) + if err != nil { + // handle error + panic(err) + } + + // Register the webhook handlers to your server + mux.Handle("/mutating", mutatingHookHandler) + mux.Handle("/validating", validatingHookHandler) + + // Run your handler + if err := http.ListenAndServe(port, mux); err != nil { //nolint:gosec // it's fine to not set timeouts here + panic(err) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go new file mode 100644 index 00000000000..557004908b8 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go @@ -0,0 +1,85 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "net/http" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // RequestLatency is a prometheus metric which is a histogram of the latency + // of processing admission requests. + RequestLatency = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "controller_runtime_webhook_latency_seconds", + Help: "Histogram of the latency of processing admission requests", + }, + []string{"webhook"}, + ) + + // RequestTotal is a prometheus metric which is a counter of the total processed admission requests. + RequestTotal = func() *prometheus.CounterVec { + return prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "controller_runtime_webhook_requests_total", + Help: "Total number of admission requests by HTTP status code.", + }, + []string{"webhook", "code"}, + ) + }() + + // RequestInFlight is a prometheus metric which is a gauge of the in-flight admission requests. + RequestInFlight = func() *prometheus.GaugeVec { + return prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "controller_runtime_webhook_requests_in_flight", + Help: "Current number of admission requests being served.", + }, + []string{"webhook"}, + ) + }() +) + +func init() { + metrics.Registry.MustRegister(RequestLatency, RequestTotal, RequestInFlight) +} + +// InstrumentedHook adds some instrumentation on top of the given webhook. +func InstrumentedHook(path string, hookRaw http.Handler) http.Handler { + lbl := prometheus.Labels{"webhook": path} + + lat := RequestLatency.MustCurryWith(lbl) + cnt := RequestTotal.MustCurryWith(lbl) + gge := RequestInFlight.With(lbl) + + // Initialize the most likely HTTP status codes. + cnt.WithLabelValues("200") + cnt.WithLabelValues("500") + + return promhttp.InstrumentHandlerDuration( + lat, + promhttp.InstrumentHandlerCounter( + cnt, + promhttp.InstrumentHandlerInFlight(gge, hookRaw), + ), + ) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server.go new file mode 100644 index 00000000000..23d5bf43507 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server.go @@ -0,0 +1,333 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook + +import ( + "context" + "crypto/tls" + "crypto/x509" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "strconv" + "sync" + "time" + + "sigs.k8s.io/controller-runtime/pkg/certwatcher" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" + "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" +) + +// DefaultPort is the default port that the webhook server serves. +var DefaultPort = 9443 + +// Server is an admission webhook server that can serve traffic and +// generates related k8s resources for deploying. +// +// TLS is required for a webhook to be accessed by kubernetes, so +// you must provide a CertName and KeyName or have valid cert/key +// at the default locations (tls.crt and tls.key). If you do not +// want to configure TLS (i.e for testing purposes) run an +// admission.StandaloneWebhook in your own server. +type Server interface { + // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates + // the webhook server doesn't need leader election. + NeedLeaderElection() bool + + // Register marks the given webhook as being served at the given path. + // It panics if two hooks are registered on the same path. + Register(path string, hook http.Handler) + + // Start runs the server. + // It will install the webhook related resources depend on the server configuration. + Start(ctx context.Context) error + + // StartedChecker returns an healthz.Checker which is healthy after the + // server has been started. + StartedChecker() healthz.Checker + + // WebhookMux returns the servers WebhookMux + WebhookMux() *http.ServeMux +} + +// Options are all the available options for a webhook.Server +type Options struct { + // Host is the address that the server will listen on. + // Defaults to "" - all addresses. + Host string + + // Port is the port number that the server will serve. + // It will be defaulted to 9443 if unspecified. + Port int + + // CertDir is the directory that contains the server key and certificate. The + // server key and certificate. + CertDir string + + // CertName is the server certificate name. Defaults to tls.crt. + // + // Note: This option should only be set when TLSOpts does not override GetCertificate. + CertName string + + // KeyName is the server key name. Defaults to tls.key. + // + // Note: This option should only be set when TLSOpts does not override GetCertificate. + KeyName string + + // ClientCAName is the CA certificate name which server used to verify remote(client)'s certificate. + // Defaults to "", which means server does not verify client's certificate. + ClientCAName string + + // TLSVersion is the minimum version of TLS supported. Accepts + // "", "1.0", "1.1", "1.2" and "1.3" only ("" is equivalent to "1.0" for backwards compatibility) + // Deprecated: Use TLSOpts instead. + TLSMinVersion string + + // TLSOpts is used to allow configuring the TLS config used for the server + TLSOpts []func(*tls.Config) + + // WebhookMux is the multiplexer that handles different webhooks. + WebhookMux *http.ServeMux +} + +// NewServer constructs a new Server from the provided options. +func NewServer(o Options) Server { + return &DefaultServer{ + Options: o, + } +} + +// DefaultServer is the default implementation used for Server. +type DefaultServer struct { + Options Options + + // webhooks keep track of all registered webhooks + webhooks map[string]http.Handler + + // defaultingOnce ensures that the default fields are only ever set once. + defaultingOnce sync.Once + + // started is set to true immediately before the server is started + // and thus can be used to check if the server has been started + started bool + + // mu protects access to the webhook map & setFields for Start, Register, etc + mu sync.Mutex + + webhookMux *http.ServeMux +} + +// setDefaults does defaulting for the Server. +func (o *Options) setDefaults() { + if o.WebhookMux == nil { + o.WebhookMux = http.NewServeMux() + } + + if o.Port <= 0 { + o.Port = DefaultPort + } + + if len(o.CertDir) == 0 { + o.CertDir = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs") + } + + if len(o.CertName) == 0 { + o.CertName = "tls.crt" + } + + if len(o.KeyName) == 0 { + o.KeyName = "tls.key" + } +} + +func (s *DefaultServer) setDefaults() { + s.webhooks = map[string]http.Handler{} + s.Options.setDefaults() + + s.webhookMux = s.Options.WebhookMux +} + +// NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates +// the webhook server doesn't need leader election. +func (*DefaultServer) NeedLeaderElection() bool { + return false +} + +// Register marks the given webhook as being served at the given path. +// It panics if two hooks are registered on the same path. +func (s *DefaultServer) Register(path string, hook http.Handler) { + s.mu.Lock() + defer s.mu.Unlock() + + s.defaultingOnce.Do(s.setDefaults) + if _, found := s.webhooks[path]; found { + panic(fmt.Errorf("can't register duplicate path: %v", path)) + } + s.webhooks[path] = hook + s.webhookMux.Handle(path, metrics.InstrumentedHook(path, hook)) + + regLog := log.WithValues("path", path) + regLog.Info("Registering webhook") +} + +// tlsVersion converts from human-readable TLS version (for example "1.1") +// to the values accepted by tls.Config (for example 0x301). +func tlsVersion(version string) (uint16, error) { + switch version { + // default is previous behaviour + case "": + return tls.VersionTLS10, nil + case "1.0": + return tls.VersionTLS10, nil + case "1.1": + return tls.VersionTLS11, nil + case "1.2": + return tls.VersionTLS12, nil + case "1.3": + return tls.VersionTLS13, nil + default: + return 0, fmt.Errorf("invalid TLSMinVersion %v: expects 1.0, 1.1, 1.2, 1.3 or empty", version) + } +} + +// Start runs the server. +// It will install the webhook related resources depend on the server configuration. +func (s *DefaultServer) Start(ctx context.Context) error { + s.defaultingOnce.Do(s.setDefaults) + + baseHookLog := log.WithName("webhooks") + baseHookLog.Info("Starting webhook server") + + tlsMinVersion, err := tlsVersion(s.Options.TLSMinVersion) + if err != nil { + return err + } + + cfg := &tls.Config{ //nolint:gosec + NextProtos: []string{"h2"}, + MinVersion: tlsMinVersion, + } + // fallback TLS config ready, will now mutate if passer wants full control over it + for _, op := range s.Options.TLSOpts { + op(cfg) + } + + if cfg.GetCertificate == nil { + certPath := filepath.Join(s.Options.CertDir, s.Options.CertName) + keyPath := filepath.Join(s.Options.CertDir, s.Options.KeyName) + + // Create the certificate watcher and + // set the config's GetCertificate on the TLSConfig + certWatcher, err := certwatcher.New(certPath, keyPath) + if err != nil { + return err + } + cfg.GetCertificate = certWatcher.GetCertificate + + go func() { + if err := certWatcher.Start(ctx); err != nil { + log.Error(err, "certificate watcher error") + } + }() + } + + // Load CA to verify client certificate, if configured. + if s.Options.ClientCAName != "" { + certPool := x509.NewCertPool() + clientCABytes, err := os.ReadFile(filepath.Join(s.Options.CertDir, s.Options.ClientCAName)) + if err != nil { + return fmt.Errorf("failed to read client CA cert: %w", err) + } + + ok := certPool.AppendCertsFromPEM(clientCABytes) + if !ok { + return fmt.Errorf("failed to append client CA cert to CA pool") + } + + cfg.ClientCAs = certPool + cfg.ClientAuth = tls.RequireAndVerifyClientCert + } + + listener, err := tls.Listen("tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), cfg) + if err != nil { + return err + } + + log.Info("Serving webhook server", "host", s.Options.Host, "port", s.Options.Port) + + srv := httpserver.New(s.webhookMux) + + idleConnsClosed := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("Shutting down webhook server with timeout of 1 minute") + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + // Error from closing listeners, or context timeout + log.Error(err, "error shutting down the HTTP server") + } + close(idleConnsClosed) + }() + + s.mu.Lock() + s.started = true + s.mu.Unlock() + if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed { + return err + } + + <-idleConnsClosed + return nil +} + +// StartedChecker returns an healthz.Checker which is healthy after the +// server has been started. +func (s *DefaultServer) StartedChecker() healthz.Checker { + config := &tls.Config{ + InsecureSkipVerify: true, //nolint:gosec // config is used to connect to our own webhook port. + } + return func(req *http.Request) error { + s.mu.Lock() + defer s.mu.Unlock() + + if !s.started { + return fmt.Errorf("webhook server has not been started yet") + } + + d := &net.Dialer{Timeout: 10 * time.Second} + conn, err := tls.DialWithDialer(d, "tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), config) + if err != nil { + return fmt.Errorf("webhook server is not reachable: %w", err) + } + + if err := conn.Close(); err != nil { + return fmt.Errorf("webhook server is not reachable: closing connection: %w", err) + } + + return nil + } +} + +// WebhookMux returns the servers WebhookMux +func (s *DefaultServer) WebhookMux() *http.ServeMux { + return s.webhookMux +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server_test.go new file mode 100644 index 00000000000..9702b0fd6e9 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/server_test.go @@ -0,0 +1,260 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook_test + +import ( + "context" + "crypto/tls" + "fmt" + "io" + "net" + "net/http" + "path" + "reflect" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var _ = Describe("Webhook Server", func() { + var ( + ctx context.Context + ctxCancel context.CancelFunc + testHostPort string + client *http.Client + server webhook.Server + servingOpts envtest.WebhookInstallOptions + ) + + BeforeEach(func() { + ctx, ctxCancel = context.WithCancel(context.Background()) + // closed in individual tests differently + + servingOpts = envtest.WebhookInstallOptions{} + Expect(servingOpts.PrepWithoutInstalling()).To(Succeed()) + + testHostPort = net.JoinHostPort(servingOpts.LocalServingHost, fmt.Sprintf("%d", servingOpts.LocalServingPort)) + + // bypass needing to set up the x509 cert pool, etc ourselves + clientTransport, err := rest.TransportFor(&rest.Config{ + TLSClientConfig: rest.TLSClientConfig{CAData: servingOpts.LocalServingCAData}, + }) + Expect(err).NotTo(HaveOccurred()) + client = &http.Client{ + Transport: clientTransport, + } + + server = webhook.NewServer(webhook.Options{ + Host: servingOpts.LocalServingHost, + Port: servingOpts.LocalServingPort, + CertDir: servingOpts.LocalServingCertDir, + }) + }) + AfterEach(func() { + Expect(servingOpts.Cleanup()).To(Succeed()) + }) + + genericStartServer := func(f func(ctx context.Context)) (done <-chan struct{}) { + doneCh := make(chan struct{}) + go func() { + defer GinkgoRecover() + defer close(doneCh) + f(ctx) + }() + // wait till we can ping the server to start the test + Eventually(func() error { + _, err := client.Get(fmt.Sprintf("https://%s/unservedpath", testHostPort)) + return err + }).Should(Succeed()) + + return doneCh + } + + startServer := func() (done <-chan struct{}) { + return genericStartServer(func(ctx context.Context) { + Expect(server.Start(ctx)).To(Succeed()) + }) + } + + // TODO(directxman12): figure out a good way to test all the serving setup + // with httptest.Server to get all the niceness from that. + + Context("when serving", func() { + PIt("should verify the client CA name when asked to", func() { + + }) + PIt("should support HTTP/2", func() { + + }) + + // TODO(directxman12): figure out a good way to test the port default, etc + }) + + It("should panic if a duplicate path is registered", func() { + server.Register("/somepath", &testHandler{}) + doneCh := startServer() + + Expect(func() { server.Register("/somepath", &testHandler{}) }).To(Panic()) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + + Context("when registering new webhooks before starting", func() { + It("should serve a webhook on the requested path", func() { + server.Register("/somepath", &testHandler{}) + + Expect(server.StartedChecker()(nil)).ToNot(Succeed()) + + doneCh := startServer() + + Eventually(func() ([]byte, error) { + resp, err := client.Get(fmt.Sprintf("https://%s/somepath", testHostPort)) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + return io.ReadAll(resp.Body) + }).Should(Equal([]byte("gadzooks!"))) + + Expect(server.StartedChecker()(nil)).To(Succeed()) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + }) + + Context("when registering webhooks after starting", func() { + var ( + doneCh <-chan struct{} + ) + BeforeEach(func() { + doneCh = startServer() + }) + AfterEach(func() { + // wait for cleanup to happen + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + + It("should serve a webhook on the requested path", func() { + server.Register("/somepath", &testHandler{}) + resp, err := client.Get(fmt.Sprintf("https://%s/somepath", testHostPort)) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + + Expect(io.ReadAll(resp.Body)).To(Equal([]byte("gadzooks!"))) + }) + }) + + It("should respect passed in TLS configurations", func() { + var finalCfg *tls.Config + tlsCfgFunc := func(cfg *tls.Config) { + cfg.CipherSuites = []uint16{ + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + } + // save cfg after changes to test against + finalCfg = cfg + } + server = webhook.NewServer(webhook.Options{ + Host: servingOpts.LocalServingHost, + Port: servingOpts.LocalServingPort, + CertDir: servingOpts.LocalServingCertDir, + TLSMinVersion: "1.2", + TLSOpts: []func(*tls.Config){ + tlsCfgFunc, + }, + }) + server.Register("/somepath", &testHandler{}) + doneCh := genericStartServer(func(ctx context.Context) { + Expect(server.Start(ctx)).To(Succeed()) + }) + + Eventually(func() ([]byte, error) { + resp, err := client.Get(fmt.Sprintf("https://%s/somepath", testHostPort)) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + return io.ReadAll(resp.Body) + }).Should(Equal([]byte("gadzooks!"))) + Expect(finalCfg.MinVersion).To(Equal(uint16(tls.VersionTLS12))) + Expect(finalCfg.CipherSuites).To(ContainElements( + tls.TLS_AES_128_GCM_SHA256, + tls.TLS_AES_256_GCM_SHA384, + )) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) + + It("should prefer GetCertificate through TLSOpts", func() { + var finalCfg *tls.Config + finalCert, err := tls.LoadX509KeyPair( + path.Join(servingOpts.LocalServingCertDir, "tls.crt"), + path.Join(servingOpts.LocalServingCertDir, "tls.key"), + ) + Expect(err).NotTo(HaveOccurred()) + finalGetCertificate := func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { //nolint:unparam + return &finalCert, nil + } + server = &webhook.DefaultServer{Options: webhook.Options{ + Host: servingOpts.LocalServingHost, + Port: servingOpts.LocalServingPort, + CertDir: servingOpts.LocalServingCertDir, + TLSMinVersion: "1.2", + TLSOpts: []func(*tls.Config){ + func(cfg *tls.Config) { + cfg.GetCertificate = finalGetCertificate + // save cfg after changes to test against + finalCfg = cfg + }, + }, + }} + server.Register("/somepath", &testHandler{}) + doneCh := genericStartServer(func(ctx context.Context) { + Expect(server.Start(ctx)).To(Succeed()) + }) + + Eventually(func() ([]byte, error) { + resp, err := client.Get(fmt.Sprintf("https://%s/somepath", testHostPort)) + Expect(err).NotTo(HaveOccurred()) + defer resp.Body.Close() + return io.ReadAll(resp.Body) + }).Should(Equal([]byte("gadzooks!"))) + Expect(finalCfg.MinVersion).To(Equal(uint16(tls.VersionTLS12))) + // We can't compare the functions directly, but we can compare their pointers + if reflect.ValueOf(finalCfg.GetCertificate).Pointer() != reflect.ValueOf(finalGetCertificate).Pointer() { + Fail("GetCertificate was not set properly, or overwritten") + } + cert, err := finalCfg.GetCertificate(nil) + Expect(err).NotTo(HaveOccurred()) + Expect(cert).To(BeEquivalentTo(&finalCert)) + + ctxCancel() + Eventually(doneCh, "4s").Should(BeClosed()) + }) +}) + +type testHandler struct { +} + +func (t *testHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + if _, err := resp.Write([]byte("gadzooks!")); err != nil { + panic("unable to write http response!") + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_integration_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_integration_test.go new file mode 100644 index 00000000000..716692124be --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_integration_test.go @@ -0,0 +1,159 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook_test + +import ( + "context" + "crypto/tls" + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +var _ = Describe("Webhook", func() { + var c client.Client + var obj *appsv1.Deployment + BeforeEach(func() { + Expect(cfg).NotTo(BeNil()) + var err error + c, err = client.New(cfg, client.Options{}) + Expect(err).NotTo(HaveOccurred()) + + obj = &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"foo": "bar"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + }) + Context("when running a webhook server with a manager", func() { + It("should reject create request for webhook that rejects all requests", func() { + m, err := manager.New(cfg, manager.Options{ + Port: testenv.WebhookInstallOptions.LocalServingPort, + Host: testenv.WebhookInstallOptions.LocalServingHost, + CertDir: testenv.WebhookInstallOptions.LocalServingCertDir, + TLSOpts: []func(*tls.Config){func(config *tls.Config) {}}, + }) // we need manager here just to leverage manager.SetFields + Expect(err).NotTo(HaveOccurred()) + server := m.GetWebhookServer() + server.Register("/failing", &webhook.Admission{Handler: &rejectingValidator{d: admission.NewDecoder(testenv.Scheme)}}) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + err := server.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + Eventually(func() bool { + err := c.Create(context.TODO(), obj) + return err != nil && strings.HasSuffix(err.Error(), "Always denied") && apierrors.ReasonForError(err) == metav1.StatusReasonForbidden + }, 1*time.Second).Should(BeTrue()) + + cancel() + }) + It("should reject create request for multi-webhook that rejects all requests", func() { + m, err := manager.New(cfg, manager.Options{ + MetricsBindAddress: "0", + Port: testenv.WebhookInstallOptions.LocalServingPort, + Host: testenv.WebhookInstallOptions.LocalServingHost, + CertDir: testenv.WebhookInstallOptions.LocalServingCertDir, + TLSOpts: []func(*tls.Config){func(config *tls.Config) {}}, + }) // we need manager here just to leverage manager.SetFields + Expect(err).NotTo(HaveOccurred()) + server := m.GetWebhookServer() + server.Register("/failing", &webhook.Admission{Handler: admission.MultiValidatingHandler(&rejectingValidator{d: admission.NewDecoder(testenv.Scheme)})}) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + err = server.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + Eventually(func() bool { + err = c.Create(context.TODO(), obj) + return err != nil && strings.HasSuffix(err.Error(), "Always denied") && apierrors.ReasonForError(err) == metav1.StatusReasonForbidden + }, 1*time.Second).Should(BeTrue()) + + cancel() + }) + }) + Context("when running a webhook server without a manager", func() { + It("should reject create request for webhook that rejects all requests", func() { + server := webhook.NewServer(webhook.Options{ + Port: testenv.WebhookInstallOptions.LocalServingPort, + Host: testenv.WebhookInstallOptions.LocalServingHost, + CertDir: testenv.WebhookInstallOptions.LocalServingCertDir, + }) + server.Register("/failing", &webhook.Admission{Handler: &rejectingValidator{d: admission.NewDecoder(testenv.Scheme)}}) + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + err := server.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + Eventually(func() bool { + err := c.Create(context.TODO(), obj) + return err != nil && strings.HasSuffix(err.Error(), "Always denied") && apierrors.ReasonForError(err) == metav1.StatusReasonForbidden + }, 1*time.Second).Should(BeTrue()) + + cancel() + }) + }) +}) + +type rejectingValidator struct { + d *admission.Decoder +} + +func (v *rejectingValidator) Handle(ctx context.Context, req admission.Request) admission.Response { + var obj appsv1.Deployment + if err := v.d.Decode(req, &obj); err != nil { + return admission.Denied(err.Error()) + } + return admission.Denied("Always denied") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_suite_test.go new file mode 100644 index 00000000000..ee9c1f4057f --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/pkg/webhook/webhook_suite_test.go @@ -0,0 +1,105 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook_test + +import ( + "fmt" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + admissionv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestSource(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Webhook Integration Suite") +} + +var testenv *envtest.Environment +var cfg *rest.Config + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + testenv = &envtest.Environment{} + // we're initializing webhook here and not in webhook.go to also test the envtest install code via WebhookOptions + initializeWebhookInEnvironment() + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + fmt.Println("stopping?") + Expect(testenv.Stop()).To(Succeed()) +}) + +func initializeWebhookInEnvironment() { + namespacedScopeV1 := admissionv1.NamespacedScope + failedTypeV1 := admissionv1.Fail + equivalentTypeV1 := admissionv1.Equivalent + noSideEffectsV1 := admissionv1.SideEffectClassNone + webhookPathV1 := "/failing" + + testenv.WebhookInstallOptions = envtest.WebhookInstallOptions{ + ValidatingWebhooks: []*admissionv1.ValidatingWebhookConfiguration{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-validation-webhook-config", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "ValidatingWebhookConfiguration", + APIVersion: "admissionregistration.k8s.io/v1", + }, + Webhooks: []admissionv1.ValidatingWebhook{ + { + Name: "deployment-validation.kubebuilder.io", + Rules: []admissionv1.RuleWithOperations{ + { + Operations: []admissionv1.OperationType{"CREATE", "UPDATE"}, + Rule: admissionv1.Rule{ + APIGroups: []string{"apps"}, + APIVersions: []string{"v1"}, + Resources: []string{"deployments"}, + Scope: &namespacedScopeV1, + }, + }, + }, + FailurePolicy: &failedTypeV1, + MatchPolicy: &equivalentTypeV1, + SideEffects: &noSideEffectsV1, + ClientConfig: admissionv1.WebhookClientConfig{ + Service: &admissionv1.ServiceReference{ + Name: "deployment-validation-service", + Namespace: "default", + Path: &webhookPathV1, + }, + }, + AdmissionReviewVersions: []string{"v1"}, + }, + }, + }, + }, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md new file mode 100644 index 00000000000..40379c9b8cc --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md @@ -0,0 +1,125 @@ +# Envtest Binaries Manager + +This is a small tool that manages binaries for envtest. It can be used to +download new binaries, list currently installed and available ones, and +clean up versions. + +To use it, just go-install it on 1.16+ (it's a separate, self-contained +module): + +```shell +go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest +``` + +For full documentation, run it with the `--help` flag, but here are some +examples: + +```shell +# download the latest envtest, and print out info about it +setup-envtest use + +# download the latest 1.19 envtest, and print out the path +setup-envtest use -p path 1.19.x! + +# switch to the most recent 1.21 envtest on disk +source <(setup-envtest use -i -p env 1.21.x) + +# list all available local versions for darwin/amd64 +setup-envtest list -i --os darwin --arch amd64 + +# remove all versions older than 1.16 from disk +setup-envtest cleanup <1.16 + +# use the value from $KUBEBUILDER_ASSETS if set, otherwise follow the normal +# logic for 'use' +setup-envtest --use-env + +# use the value from $KUBEBUILDER_ASSETS if set, otherwise use the latest +# installed version +setup-envtest use -i --use-env + +# sideload a pre-downloaded tarball as Kubernetes 1.16.2 into our store +setup-envtest sideload 1.16.2 < downloaded-envtest.tar.gz +``` + +## Where does it put all those binaries? + +By default, binaries are stored in a subdirectory of an OS-specific data +directory, as per the OS's conventions. + +On Linux, this is `$XDG_DATA_HOME`; on Windows, `%LocalAppData`; and on +OSX, `~/Library/Application Support`. + +There's an overall folder that holds all files, and inside that is +a folder for each version/platform pair. The exact directory structure is +not guarnateed, except that the leaf directory will contain the names +expected by envtest. You should always use `setup-envtest fetch` or +`setup-envtest switch` (generally with the `-p path` or `-p env` flags) to +get the directory that you should use. + +## Why do I have to do that `source <(blah blah blah)` thing + +This is a normal binary, not a shell script, so we can't set the parent +process's environment variables. If you use this by hand a lot and want +to save the typing, you could put something like the following in your +`~/.zshrc` (or similar for bash/fish/whatever, modified to those): + +```shell +setup-envtest() { + if (($@[(Ie)use])); then + source <($GOPATH/bin/setup-envtest "$@" -p env) + else + $GOPATH/bin/setup-envtest "$@" + fi +} +``` + +## What if I don't want to talk to the internet? + +There are a few options. + +First, you'll probably want to set the `-i/--installed` flag. If you want +to avoid forgetting to set this flag, set the `ENVTEST_INSTALLED_ONLY` +env variable, which will switch that flag on by default. + +Then, you have a few options for managing your binaries: + +- If you don't *really* want to manage with this tool, or you want to + respect the $KUBEBUILDER_ASSETS variable if it's set to something + outside the store, use the `use --use-env -i` command. + + `--use-env` makes the command unconditionally use the value of + KUBEBUILDER_ASSETS as long as it contains the required binaries, and + `-i` indicates that we only ever want to work with installed binaries + (no reaching out the remote GCS storage). + + As noted about, you can use `ENVTEST_INSTALLED_ONLY=true` to switch `-i` + on by default, and you can use `ENVTEST_USE_ENV=true` to switch + `--use-env` on by default. + +- If you want to use this tool, but download your gziped tarballs + separately, you can use the `sideload` command. You'll need to use the + `-k/--version` flag to indicate which version you're sideloading. + + After that, it'll be as if you'd installed the binaries with `use`. + +- If you want to talk to some internal source, you can use the + `--remote-bucket` and `--remote-server` options. The former sets which + GCS bucket to download from, and the latter sets the host to talk to as + if it were a GCS endpoint. Theoretically, you could use the latter + version to run an internal "mirror" -- the tool expects + + - `HOST/storage/v1/b/BUCKET/o` to return JSON like + + ```json + {"items": [ + {"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""}, + {"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""}, + ]} + ``` + + - `HOST/storage/v1/b/BUCKET/o/TARBALL_NAME` to return JSON like + `{"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""}` + + - `HOST/storage/v1/b/BUCKET/o/TARBALL_NAME?alt=media` to return the + actual file contents diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go new file mode 100644 index 00000000000..e12a107352e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package env + +import ( + "context" + "errors" + "fmt" + "io" + "io/fs" + "path/filepath" + "sort" + "strings" + "text/tabwriter" + + "github.com/go-logr/logr" + "github.com/spf13/afero" // too bad fs.FS isn't writable :-/ + + "sigs.k8s.io/controller-runtime/tools/setup-envtest/remote" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/store" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +// Env represents an environment for downloading and otherwise manipulating +// envtest binaries. +// +// In general, the methods will use the Exit{,Cause} functions from this package +// to indicate errors. Catch them with a `defer HandleExitWithCode()`. +type Env struct { + // the following *must* be set on input + + // Platform is our current platform + Platform versions.PlatformItem + + // VerifiySum indicates whether or not we should run checksums. + VerifySum bool + // NoDownload forces us to not contact GCS, looking only + // at local files instead. + NoDownload bool + // ForceDownload forces us to ignore local files and always + // contact GCS & re-download. + ForceDownload bool + + // Client is our remote client for contacting GCS. + Client *remote.Client + + // Log allows us to log. + Log logr.Logger + + // the following *may* be set on input, or may be discovered + + // Version is the version(s) that we want to download + // (may be automatically retrieved later on). + Version versions.Spec + + // Store is used to load/store entries to/from disk. + Store *store.Store + + // FS is the file system to read from/write to for provisioning temp files + // for storing the archives temporarily. + FS afero.Afero + + // Out is the place to write output text to + Out io.Writer + + // manualPath is the manually discovered path from PathMatches, if + // a non-store path was used. It'll be printed by PrintInfo if present. + manualPath string +} + +// CheckCoherence checks that this environment has filled-out, coherent settings +// (e.g. NoDownload & ForceDownload aren't both set). +func (e *Env) CheckCoherence() { + if e.NoDownload && e.ForceDownload { + Exit(2, "cannot both skip downloading *and* force re-downloading") + } + + if e.Platform.OS == "" || e.Platform.Arch == "" { + Exit(2, "must specify non-empty OS and arch (did you specify bad --os or --arch values?)") + } +} + +func (e *Env) filter() store.Filter { + return store.Filter{Version: e.Version, Platform: e.Platform.Platform} +} + +func (e *Env) item() store.Item { + concreteVer := e.Version.AsConcrete() + if concreteVer == nil || e.Platform.IsWildcard() { + panic("no platform/version set") // unexpected, print stack trace + } + return store.Item{Version: *concreteVer, Platform: e.Platform.Platform} +} + +// ListVersions prints out all available versions matching this Env's +// platform & version selector (respecting NoDownload to figure +// out whether or not to match remote versions). +func (e *Env) ListVersions(ctx context.Context) { + out := tabwriter.NewWriter(e.Out, 4, 4, 2, ' ', 0) + defer out.Flush() + localVersions, err := e.Store.List(ctx, e.filter()) + if err != nil { + ExitCause(2, err, "unable to list installed versions") + } + for _, item := range localVersions { + // already filtered by onDiskVersions + fmt.Fprintf(out, "(installed)\tv%s\t%s\n", item.Version, item.Platform) + } + + if e.NoDownload { + return + } + + remoteVersions, err := e.Client.ListVersions(ctx) + if err != nil { + ExitCause(2, err, "unable list to available versions") + } + + for _, set := range remoteVersions { + if !e.Version.Matches(set.Version) { + continue + } + sort.Slice(set.Platforms, func(i, j int) bool { + return orderPlatforms(set.Platforms[i].Platform, set.Platforms[j].Platform) + }) + for _, plat := range set.Platforms { + if e.Platform.Matches(plat.Platform) { + fmt.Fprintf(out, "(available)\tv%s\t%s\n", set.Version, plat) + } + } + } +} + +// LatestVersion returns the latest version matching our version selector and +// platform from the remote server, with the correspoding checksum for later +// use as well. +func (e *Env) LatestVersion(ctx context.Context) (versions.Concrete, versions.PlatformItem) { + vers, err := e.Client.ListVersions(ctx) + if err != nil { + ExitCause(2, err, "unable to list versions to find latest one") + } + for _, set := range vers { + if !e.Version.Matches(set.Version) { + e.Log.V(1).Info("skipping non-matching version", "version", set.Version) + continue + } + // double-check that our platform is supported + for _, plat := range set.Platforms { + // NB(directxman12): we're already iterating in order, so no + // need to check if the wildcard is latest vs any + if e.Platform.Matches(plat.Platform) && e.Version.Matches(set.Version) { + return set.Version, plat + } + } + e.Log.Info("latest version not supported for your platform, checking older ones", "version", set.Version, "platform", e.Platform) + } + + Exit(2, "unable to find a version that was supported for platform %s", e.Platform) + return versions.Concrete{}, versions.PlatformItem{} // unreachable, but Go's type system can't express the "never" type +} + +// ExistsAndValid checks if our current (concrete) version & platform +// exist on disk (unless ForceDownload is set, in which cause it always +// returns false). +// +// Must be called after EnsureVersionIsSet so that we have a concrete +// Version selected. Must have a concrete platform, or ForceDownload +// must be set. +func (e *Env) ExistsAndValid() bool { + if e.ForceDownload { + // we always want to download, so don't check here + return false + } + + if e.Platform.IsWildcard() { + Exit(2, "you must have a concrete platform with this command -- you cannot use wildcard platforms with fetch or switch") + } + + exists, err := e.Store.Has(e.item()) + if err != nil { + ExitCause(2, err, "unable to check if existing version exists") + } + + if exists { + e.Log.Info("applicable version found on disk", "version", e.Version) + } + return exists +} + +// EnsureVersionIsSet ensures that we have a non-wildcard version +// configured. +// +// If necessary, it will enumerate on-disk and remote versions to accomplish +// this, finding a version that matches our version selector and platform. +// It will always yield a concrete version, it *may* yield a concrete platorm +// as well. +func (e *Env) EnsureVersionIsSet(ctx context.Context) { + if e.Version.AsConcrete() != nil { + return + } + var localVer *versions.Concrete + var localPlat versions.Platform + + items, err := e.Store.List(ctx, e.filter()) + if err != nil { + ExitCause(2, err, "unable to determine installed versions") + } + + for _, item := range items { + if !e.Version.Matches(item.Version) || !e.Platform.Matches(item.Platform) { + e.Log.V(1).Info("skipping version, doesn't match", "version", item.Version, "platform", item.Platform) + continue + } + // NB(directxman12): we're already iterating in order, so no + // need to check if the wildcard is latest vs any + ver := item.Version // copy to avoid referencing iteration variable + localVer = &ver + localPlat = item.Platform + break + } + + if e.NoDownload || !e.Version.CheckLatest { + // no version specified, but we either + // + // a) shouldn't contact remote + // b) don't care to find the absolute latest + // + // so just find the latest local version + if localVer != nil { + e.Version.MakeConcrete(*localVer) + e.Platform.Platform = localPlat + return + } + if e.NoDownload { + Exit(2, "no applicable on-disk versions for %s found, you'll have to download one, or run list -i to see what you do have", e.Platform) + } + // if we didn't ask for the latest version, but don't have anything + // available, try the internet ;-) + } + + // no version specified and we need the latest in some capacity, so find latest from remote + // so find the latest local first, then compare it to the latest remote, and use whichever + // of the two is more recent. + e.Log.Info("no version specified, finding latest") + serverVer, platform := e.LatestVersion(ctx) + + // if we're not forcing a download, and we have a newer local version, just use that + if !e.ForceDownload && localVer != nil && localVer.NewerThan(serverVer) { + e.Platform.Platform = localPlat // update our data with md5 + e.Version.MakeConcrete(*localVer) + return + } + + // otherwise, use the new version from the server + e.Platform = platform // update our data with md5 + e.Version.MakeConcrete(serverVer) +} + +// Fetch ensures that the requested platform and version are on disk. +// You must call EnsureVersionIsSet before calling this method. +// +// If ForceDownload is set, we always download, otherwise we only download +// if we're missing the version on disk. +func (e *Env) Fetch(ctx context.Context) { + log := e.Log.WithName("fetch") + + // if we didn't just fetch it, grab the sum to verify + if e.VerifySum && e.Platform.MD5 == "" { + if err := e.Client.FetchSum(ctx, *e.Version.AsConcrete(), &e.Platform); err != nil { + ExitCause(2, err, "unable to fetch checksum for requested version") + } + } + if !e.VerifySum { + e.Platform.MD5 = "" // skip verification + } + + var packedPath string + + // cleanup on error (needs to be here so it will happen after the other defers) + defer e.cleanupOnError(func() { + if packedPath != "" { + e.Log.V(1).Info("cleaning up downloaded archive", "path", packedPath) + if err := e.FS.Remove(packedPath); err != nil && !errors.Is(err, fs.ErrNotExist) { + e.Log.Error(err, "unable to clean up archive path", "path", packedPath) + } + } + }) + + archiveOut, err := e.FS.TempFile("", "*-"+e.Platform.ArchiveName(*e.Version.AsConcrete())) + if err != nil { + ExitCause(2, err, "unable to open file to write downloaded archive to") + } + defer archiveOut.Close() + packedPath = archiveOut.Name() + log.V(1).Info("writing downloaded archive", "path", packedPath) + + if err := e.Client.GetVersion(ctx, *e.Version.AsConcrete(), e.Platform, archiveOut); err != nil { + ExitCause(2, err, "unable to download requested version") + } + log.V(1).Info("downloaded archive", "path", packedPath) + + if err := archiveOut.Sync(); err != nil { // sync before reading back + ExitCause(2, err, "unable to flush downloaded archive file") + } + if _, err := archiveOut.Seek(0, 0); err != nil { + ExitCause(2, err, "unable to jump back to beginning of archive file to unzip") + } + + if err := e.Store.Add(ctx, e.item(), archiveOut); err != nil { + ExitCause(2, err, "unable to store version to disk") + } + + log.V(1).Info("removing archive from disk", "path", packedPath) + if err := e.FS.Remove(packedPath); err != nil { + // don't bail, this isn't fatal + log.Error(err, "unable to remove downloaded archive", "path", packedPath) + } +} + +// cleanup on error cleans up if we hit an exitCode error. +// +// Use it in a defer. +func (e *Env) cleanupOnError(extraCleanup func()) { + cause := recover() + if cause == nil { + return + } + // don't panic in a panic handler + var exit *exitCode + if asExit(cause, &exit) && exit.code != 0 { + e.Log.Info("cleaning up due to error") + // we already log in the function, and don't want to panic, so + // ignore the error + extraCleanup() + } + panic(cause) // re-start the panic now that we're done +} + +// Remove removes the data for our version selector & platform from disk. +func (e *Env) Remove(ctx context.Context) { + items, err := e.Store.Remove(ctx, e.filter()) + for _, item := range items { + fmt.Fprintf(e.Out, "removed %s\n", item) + } + if err != nil { + ExitCause(2, err, "unable to remove all requested version(s)") + } +} + +// PrintInfo prints out information about a single, current version +// and platform, according to the given formatting info. +func (e *Env) PrintInfo(printFmt PrintFormat) { + // use the manual path if it's set, otherwise use the standard path + path := e.manualPath + if e.manualPath == "" { + item := e.item() + var err error + path, err = e.Store.Path(item) + if err != nil { + ExitCause(2, err, "unable to get path for version %s", item) + } + } + switch printFmt { + case PrintOverview: + fmt.Fprintf(e.Out, "Version: %s\n", e.Version) + fmt.Fprintf(e.Out, "OS/Arch: %s\n", e.Platform) + if e.Platform.MD5 != "" { + fmt.Fprintf(e.Out, "md5: %s\n", e.Platform.MD5) + } + fmt.Fprintf(e.Out, "Path: %s\n", path) + case PrintPath: + fmt.Fprint(e.Out, path) // NB(directxman12): no newline -- want the bare path here + case PrintEnv: + // quote in case there are spaces, etc in the path + // the weird string below works like this: + // - you can't escape quotes in shell + // - shell strings that are next to each other are concatenated (so "a""b""c" == "abc") + // - you can intermix quote styles using the above + // - so `'"'"'` --> CLOSE_QUOTE + "'" + OPEN_QUOTE + shellQuoted := strings.ReplaceAll(path, "'", `'"'"'`) + fmt.Fprintf(e.Out, "export KUBEBUILDER_ASSETS='%s'\n", shellQuoted) + default: + panic(fmt.Sprintf("unexpected print format %v", printFmt)) + } +} + +// EnsureBaseDirs ensures that the base packed and unpacked directories +// exist. +// +// This should be the first thing called after CheckCoherence. +func (e *Env) EnsureBaseDirs(ctx context.Context) { + if err := e.Store.Initialize(ctx); err != nil { + ExitCause(2, err, "unable to make sure store is initialized") + } +} + +// Sideload takes an input stream, and loads it as if it had been a downloaded .tar.gz file +// for the current *concrete* version and platform. +func (e *Env) Sideload(ctx context.Context, input io.Reader) { + log := e.Log.WithName("sideload") + if e.Version.AsConcrete() == nil || e.Platform.IsWildcard() { + Exit(2, "must specify a concrete version and platform to sideload. Make sure you've passed a version, like 'sideload 1.21.0'") + } + log.V(1).Info("sideloading from input stream to version", "version", e.Version, "platform", e.Platform) + if err := e.Store.Add(ctx, e.item(), input); err != nil { + ExitCause(2, err, "unable to sideload item to disk") + } +} + +var ( + // expectedExectuables are the executables that are checked in PathMatches + // for non-store paths. + expectedExecutables = []string{ + "kube-apiserver", + "etcd", + "kubectl", + } +) + +// PathMatches checks if the path (e.g. from the environment variable) +// matches this version & platform selector, and if so, returns true. +func (e *Env) PathMatches(value string) bool { + e.Log.V(1).Info("checking if (env var) path represents our desired version", "path", value) + if value == "" { + // if we're unset, + return false + } + + if e.versionFromPathName(value) { + e.Log.V(1).Info("path appears to be in our store, using that info", "path", value) + return true + } + + e.Log.V(1).Info("path is not in our store, checking for binaries", "path", value) + for _, expected := range expectedExecutables { + _, err := e.FS.Stat(filepath.Join(value, expected)) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // one of our required binaries is missing, return false + e.Log.V(1).Info("missing required binary in (env var) path", "binary", expected, "path", value) + return false + } + ExitCause(2, err, "unable to check for existence of binary %s from existing (env var) path %s", value, expected) + } + } + + // success, all binaries present + e.Log.V(1).Info("all required binaries present in (env var) path, using that", "path", value) + + // don't bother checking the version, the user explicitly asked us to use this + // we don't know the version, so set it to wildcard + e.Version = versions.AnyVersion + e.Platform.OS = "*" + e.Platform.Arch = "*" + e.manualPath = value + return true +} + +// versionFromPathName checks if the given path's last component looks like one +// of our versions, and, if so, what version it represents. If succesfull, +// it'll set version and platform, and return true. Otherwise it returns +// false. +func (e *Env) versionFromPathName(value string) bool { + baseName := filepath.Base(value) + ver, pl := versions.ExtractWithPlatform(versions.VersionPlatformRE, baseName) + if ver == nil { + // not a version that we can tell + return false + } + + // yay we got a version! + e.Version.MakeConcrete(*ver) + e.Platform.Platform = pl + e.manualPath = value // might be outside our store, set this just in case + + return true +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_suite_test.go new file mode 100644 index 00000000000..3400dd91aaa --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_suite_test.go @@ -0,0 +1,47 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package env_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var testLog logr.Logger + +func zapLogger() logr.Logger { + testOut := zapcore.AddSync(GinkgoWriter) + enc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) + // bleh setting up logging to the ginkgo writer is annoying + zapLog := zap.New(zapcore.NewCore(enc, testOut, zap.DebugLevel), + zap.ErrorOutput(testOut), zap.Development(), zap.AddStacktrace(zap.WarnLevel)) + return zapr.NewLogger(zapLog) +} + +func TestEnv(t *testing.T) { + testLog = zapLogger() + + RegisterFailHandler(Fail) + RunSpecs(t, "Env Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_test.go new file mode 100644 index 00000000000..fd6e7633bda --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env_test.go @@ -0,0 +1,108 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package env_test + +import ( + "bytes" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/spf13/afero" + + . "sigs.k8s.io/controller-runtime/tools/setup-envtest/env" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/store" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +var _ = Describe("Env", func() { + // Most of the rest of this is tested e2e via the workflows test, + // but there's a few things that are easier to test here. Eventually + // we should maybe move some of the tests here. + var ( + env *Env + outBuffer *bytes.Buffer + ) + BeforeEach(func() { + outBuffer = new(bytes.Buffer) + env = &Env{ + Out: outBuffer, + Log: testLog, + + Store: &store.Store{ + // use spaces and quotes to test our quote escaping below + Root: afero.NewBasePathFs(afero.NewMemMapFs(), "/kb's test store"), + }, + + // shouldn't use these, but just in case + NoDownload: true, + FS: afero.Afero{Fs: afero.NewMemMapFs()}, + } + + env.Version.MakeConcrete(versions.Concrete{ + Major: 1, Minor: 21, Patch: 3, + }) + env.Platform.Platform = versions.Platform{ + OS: "linux", Arch: "amd64", + } + }) + + Describe("printing", func() { + It("should use a manual path if one is present", func() { + By("using a manual path") + Expect(env.PathMatches("/otherstore/1.21.4-linux-amd64")).To(BeTrue()) + + By("checking that that path is printed properly") + env.PrintInfo(PrintPath) + Expect(outBuffer.String()).To(Equal("/otherstore/1.21.4-linux-amd64")) + }) + + Context("as human-readable info", func() { + BeforeEach(func() { + env.PrintInfo(PrintOverview) + }) + + It("should contain the version", func() { + Expect(outBuffer.String()).To(ContainSubstring("/kb's test store/k8s/1.21.3-linux-amd64")) + }) + It("should contain the path", func() { + Expect(outBuffer.String()).To(ContainSubstring("1.21.3")) + }) + It("should contain the platform", func() { + Expect(outBuffer.String()).To(ContainSubstring("linux/amd64")) + }) + + }) + Context("as just a path", func() { + It("should print out just the path", func() { + env.PrintInfo(PrintPath) + Expect(outBuffer.String()).To(Equal(`/kb's test store/k8s/1.21.3-linux-amd64`)) + }) + }) + + Context("as env vars", func() { + BeforeEach(func() { + env.PrintInfo(PrintEnv) + }) + It("should set KUBEBUILDER_ASSETS", func() { + Expect(outBuffer.String()).To(HavePrefix("export KUBEBUILDER_ASSETS=")) + }) + It("should quote the return path, escaping quotes to deal with spaces, etc", func() { + Expect(outBuffer.String()).To(HaveSuffix(`='/kb'"'"'s test store/k8s/1.21.3-linux-amd64'` + "\n")) + }) + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go new file mode 100644 index 00000000000..ae393b593b1 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package env + +import ( + "errors" + "fmt" + "os" +) + +// Exit exits with the given code and error message. +// +// Defer HandleExitWithCode in main to catch this and get the right behavior. +func Exit(code int, msg string, args ...interface{}) { + panic(&exitCode{ + code: code, + err: fmt.Errorf(msg, args...), + }) +} + +// ExitCause exits with the given code and error message, automatically +// wrapping the underlying error passed as well. +// +// Defer HandleExitWithCode in main to catch this and get the right behavior. +func ExitCause(code int, err error, msg string, args ...interface{}) { + args = append(args, err) + panic(&exitCode{ + code: code, + err: fmt.Errorf(msg+": %w", args...), + }) +} + +// exitCode is an error that indicates, on a panic, to exit with the given code +// and message. +type exitCode struct { + code int + err error +} + +func (c *exitCode) Error() string { + return fmt.Sprintf("%v (exit code %d)", c.err, c.code) +} +func (c *exitCode) Unwrap() error { + return c.err +} + +// asExit checks if the given (panic) value is an exitCode error, +// and if so stores it in the given pointer. It's roughly analogous +// to errors.As, except it works on recover() values. +func asExit(val interface{}, exit **exitCode) bool { + if val == nil { + return false + } + err, isErr := val.(error) + if !isErr { + return false + } + if !errors.As(err, exit) { + return false + } + return true +} + +// HandleExitWithCode handles panics of type exitCode, +// printing the status message and existing with the given +// exit code, or re-raising if not an exitCode error. +// +// This should be the first defer in your main function. +func HandleExitWithCode() { + if cause := recover(); CheckRecover(cause, func(code int, err error) { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(code) + }) { + panic(cause) + } +} + +// CheckRecover checks the value of cause, calling the given callback +// if it's an exitCode error. It returns true if we should re-panic +// the cause. +// +// It's mainly useful for testing, normally you'd use HandleExitWithCode. +func CheckRecover(cause interface{}, cb func(int, error)) bool { + if cause == nil { + return false + } + var exitErr *exitCode + if !asExit(cause, &exitErr) { + // re-raise if it's not an exit error + return true + } + + cb(exitErr.code, exitErr.err) + return false +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go new file mode 100644 index 00000000000..2c98c88d959 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package env + +import ( + "fmt" + + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +// orderPlatforms orders platforms by OS then arch. +func orderPlatforms(first, second versions.Platform) bool { + // sort by OS, then arch + if first.OS != second.OS { + return first.OS < second.OS + } + return first.Arch < second.Arch +} + +// PrintFormat indicates how to print out fetch and switch results. +// It's a valid pflag.Value so it can be used as a flag directly. +type PrintFormat int + +const ( + // PrintOverview prints human-readable data, + // including path, version, arch, and checksum (when available). + PrintOverview PrintFormat = iota + // PrintPath prints *only* the path, with no decoration. + PrintPath + // PrintEnv prints the path with the corresponding env variable, so that + // you can source the output like + // `source $(fetch-envtest switch -p env 1.20.x)`. + PrintEnv +) + +func (f PrintFormat) String() string { + switch f { + case PrintOverview: + return "overview" + case PrintPath: + return "path" + case PrintEnv: + return "env" + default: + panic(fmt.Sprintf("unexpected print format %d", int(f))) + } +} + +// Set sets the value of this as a flag. +func (f *PrintFormat) Set(val string) error { + switch val { + case "overview": + *f = PrintOverview + case "path": + *f = PrintPath + case "env": + *f = PrintEnv + default: + return fmt.Errorf("unknown print format %q, use one of overview|path|env", val) + } + return nil +} + +// Type is the type of this value as a flag. +func (PrintFormat) Type() string { + return "{overview|path|env}" +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.mod b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.mod new file mode 100644 index 00000000000..542759927b7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.mod @@ -0,0 +1,24 @@ +module sigs.k8s.io/controller-runtime/tools/setup-envtest + +go 1.20 + +require ( + github.com/go-logr/logr v1.2.0 + github.com/go-logr/zapr v1.2.0 + github.com/onsi/ginkgo/v2 v2.1.4 + github.com/onsi/gomega v1.19.0 + github.com/spf13/afero v1.6.0 + github.com/spf13/pflag v1.0.5 + go.uber.org/zap v1.19.1 +) + +require ( + github.com/golang/protobuf v1.5.2 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.26.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.sum b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.sum new file mode 100644 index 00000000000..cb4c52f3e6e --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/go.sum @@ -0,0 +1,98 @@ +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= +github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +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/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +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/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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.1.5/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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go new file mode 100644 index 00000000000..8dca7741572 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package main + +import ( + goflag "flag" + "fmt" + "os" + "runtime" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "github.com/spf13/afero" + flag "github.com/spf13/pflag" + "go.uber.org/zap" + + envp "sigs.k8s.io/controller-runtime/tools/setup-envtest/env" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/remote" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/store" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows" +) + +const ( + // envNoDownload is an env variable that can be set to always force + // the --installed-only, -i flag to be set. + envNoDownload = "ENVTEST_INSTALLED_ONLY" + // envUseEnv is an env variable that can be set to control the --use-env + // flag globally. + envUseEnv = "ENVTEST_USE_ENV" +) + +var ( + force = flag.Bool("force", false, "force re-downloading dependencies, even if they're already present and correct") + installedOnly = flag.BoolP("installed-only", "i", os.Getenv(envNoDownload) != "", + "only look at installed versions -- do not query the remote API server, "+ + "and error out if it would be necessary to") + verify = flag.Bool("verify", true, "verify dependencies while downloading") + useEnv = flag.Bool("use-env", os.Getenv(envUseEnv) != "", "whether to return the value of KUBEBUILDER_ASSETS if it's already set") + + targetOS = flag.String("os", runtime.GOOS, "os to download for (e.g. linux, darwin, for listing operations, use '*' to list all platforms)") + targetArch = flag.String("arch", runtime.GOARCH, "architecture to download for (e.g. amd64, for listing operations, use '*' to list all platforms)") + + // printFormat is the flag value for -p, --print. + printFormat = envp.PrintOverview + // zapLvl is the flag value for logging verbosity. + zapLvl = zap.WarnLevel + + binDir = flag.String("bin-dir", "", + "directory to store binary assets (default: $OS_SPECIFIC_DATA_DIR/envtest-binaries)") + remoteBucket = flag.String("remote-bucket", "kubebuilder-tools", "remote GCS bucket to download from") + remoteServer = flag.String("remote-server", "storage.googleapis.com", + "remote server to query from. You can override this if you want to run "+ + "an internal storage server instead, or for testing.") +) + +// TODO(directxman12): handle interrupts? + +// setupLogging configures a Zap logger. +func setupLogging() logr.Logger { + logCfg := zap.NewDevelopmentConfig() + logCfg.Level = zap.NewAtomicLevelAt(zapLvl) + zapLog, err := logCfg.Build() + if err != nil { + envp.ExitCause(1, err, "who logs the logger errors?") + } + return zapr.NewLogger(zapLog) +} + +// setupEnv initializes the environment from flags. +func setupEnv(globalLog logr.Logger, version string) *envp.Env { + log := globalLog.WithName("setup") + if *binDir == "" { + dataDir, err := store.DefaultStoreDir() + if err != nil { + envp.ExitCause(1, err, "unable to deterimine default binaries directory (use --bin-dir to manually override)") + } + + *binDir = dataDir + } + log.V(1).Info("using binaries directory", "dir", *binDir) + + env := &envp.Env{ + Log: globalLog, + Client: &remote.Client{ + Log: globalLog.WithName("storage-client"), + Bucket: *remoteBucket, + Server: *remoteServer, + }, + VerifySum: *verify, + ForceDownload: *force, + NoDownload: *installedOnly, + Platform: versions.PlatformItem{ + Platform: versions.Platform{ + OS: *targetOS, + Arch: *targetArch, + }, + }, + FS: afero.Afero{Fs: afero.NewOsFs()}, + Store: store.NewAt(*binDir), + Out: os.Stdout, + } + + switch version { + case "", "latest": + env.Version = versions.LatestVersion + case "latest-on-disk": + // we sort by version, latest first, so this'll give us the latest on + // disk (as per the contract from env.List & store.List) + env.Version = versions.AnyVersion + env.NoDownload = true + default: + var err error + env.Version, err = versions.FromExpr(version) + if err != nil { + envp.ExitCause(1, err, "version be a valid version, or simply 'latest' or 'latest-on-disk'") + } + } + + env.CheckCoherence() + + return env +} + +func main() { + // exit with appropriate error codes -- this should be the first defer so + // that it's the last one executed. + defer envp.HandleExitWithCode() + + // set up flags + flag.Usage = func() { + name := os.Args[0] + fmt.Fprintf(os.Stderr, "Usage: %s [FLAGS] use|list|cleanup|sideload [VERSION]\n", name) + flag.PrintDefaults() + fmt.Fprintf(os.Stderr, + ` +Note: this command is currently alpha, and the usage/behavior may change from release to release. + +Examples: + + # download the latest envtest, and print out info about it + %[1]s use + + # download the latest 1.19 envtest, and print out the path + %[1]s use -p path 1.19.x! + + # switch to the most recent 1.21 envtest on disk + source <(%[1]s use -i -p env 1.21.x) + + # list all available local versions for darwin/amd64 + %[1]s list -i --os darwin --arch amd64 + + # remove all versions older than 1.16 from disk + %[1]s cleanup <1.16 + + # use the value from $KUBEBUILDER_ASSETS if set, otherwise follow the normal + # logic for 'use' + %[1]s --use-env + + # use the value from $KUBEBUILDER_ASSETS if set, otherwise use the latest + # installed version + %[1]s use -i --use-env + + # sideload a pre-downloaded tarball as Kubernetes 1.16.2 into our store + %[1]s sideload 1.16.2 < downloaded-envtest.tar.gz + +Commands: + + use: + get information for the requested version, downloading it if necessary and allowed. + Needs a concrete platform (no wildcards), but wilcard versions are supported. + + list: + list installed *and* available versions matching the given version & platform. + May have wildcard versions *and* platforms. + If the -i flag is passed, only installed versions are listed. + + cleanup: + remove all versions matching the given version & platform selector. + May have wildcard versions *and* platforms. + + sideload: + reads a .tar.gz file from stdin and expand it into the store. + must have a concrete version and platform. + +Versions: + + Versions take the form of a small subset of semver selectors. + + Basic semver whole versions are accepted: X.Y.Z. + Z may also be '*' or 'x' to match a wildcard. + You may also just write X.Y, which means X.Y.*. + + A version may be prefixed with '~' to match the most recent Z release + in the given Y release ( [X.Y.Z, X.Y+1.0) ). + + Finally, you may suffix the version with '!' to force checking the + remote API server for the latest version. + + For example: + + 1.16.x / 1.16.* / 1.16 # any 1.16 version + ~1.19.3 # any 1.19 version that's at least 1.19.3 + <1.17 # any release 1.17.x or below + 1.22.x! # the latest one 1.22 release available remotely + +Output: + + The fetch & switch commands respect the --print, -p flag. + + overview: human readable information + path: print out the path, by itself + env: print out the path in a form that can be sourced to use that version with envtest + + Other command have human-readable output formats only. + +Environment Variables: + + KUBEBUILDER_ASSETS: + --use-env will check this, and '-p/--print env' will return this. + If --use-env is true and this is set, we won't check our store + for versions -- we'll just immediately return whatever's in + this env var. + + %[2]s: + will switch the default of -i/--installed to true if set to any value + + %[3]s: + will switch the default of --use-env to true if set to any value + +`, name, envNoDownload, envUseEnv) + } + flag.CommandLine.AddGoFlag(&goflag.Flag{Name: "v", Usage: "logging level", Value: &zapLvl}) + flag.VarP(&printFormat, "print", "p", "what info to print after fetch-style commands (overview, path, env)") + needHelp := flag.Bool("help", false, "print out this help text") // register help so that we don't get an error at the end + flag.Parse() + + if *needHelp { + flag.Usage() + envp.Exit(2, "") + } + + // check our argument count + if numArgs := flag.NArg(); numArgs < 1 || numArgs > 2 { + flag.Usage() + envp.Exit(2, "please specify a command to use, and optionally a version selector") + } + + // set up logging + globalLog := setupLogging() + + // set up the environment + var version string + if flag.NArg() > 1 { + version = flag.Arg(1) + } + env := setupEnv(globalLog, version) + + // perform our main set of actions + switch action := flag.Arg(0); action { + case "use": + workflows.Use{ + UseEnv: *useEnv, + PrintFormat: printFormat, + AssetsPath: os.Getenv("KUBEBUILDER_ASSETS"), + }.Do(env) + case "list": + workflows.List{}.Do(env) + case "cleanup": + workflows.Cleanup{}.Do(env) + case "sideload": + workflows.Sideload{ + Input: os.Stdin, + PrintFormat: printFormat, + }.Do(env) + default: + flag.Usage() + envp.Exit(2, "unknown action %q", action) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/client.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/client.go new file mode 100644 index 00000000000..be82532583a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/client.go @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package remote + +import ( + "context" + "crypto/md5" //nolint:gosec + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "path" + "sort" + + "github.com/go-logr/logr" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +// objectList is the parts we need of the GCS "list-objects-in-bucket" endpoint. +type objectList struct { + Items []bucketObject `json:"items"` + NextPageToken string `json:"nextPageToken"` +} + +// bucketObject is the parts we need of the GCS object metadata. +type bucketObject struct { + Name string `json:"name"` + Hash string `json:"md5Hash"` +} + +// Client is a basic client for fetching versions of the envtest binary archives +// from GCS. +type Client struct { + // Bucket is the bucket to fetch from. + Bucket string + + // Server is the GCS-like storage server + Server string + + // Log allows us to log. + Log logr.Logger + + // Insecure uses http for testing + Insecure bool +} + +func (c *Client) scheme() string { + if c.Insecure { + return "http" + } + return "https" +} + +// ListVersions lists all available tools versions in the given bucket, along +// with supported os/arch combos and the corresponding hash. +// +// The results are sorted with newer versions first. +func (c *Client) ListVersions(ctx context.Context) ([]versions.Set, error) { + loc := &url.URL{ + Scheme: c.scheme(), + Host: c.Server, + Path: path.Join("/storage/v1/b/", c.Bucket, "o"), + } + query := make(url.Values) + + knownVersions := map[versions.Concrete][]versions.PlatformItem{} + for cont := true; cont; { + c.Log.V(1).Info("listing bucket to get versions", "bucket", c.Bucket) + + loc.RawQuery = query.Encode() + req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) + if err != nil { + return nil, fmt.Errorf("unable to construct request to list bucket items: %w", err) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, fmt.Errorf("unable to perform request to list bucket items: %w", err) + } + + err = func() error { + defer resp.Body.Close() + if resp.StatusCode != 200 { + return fmt.Errorf("unable list bucket items -- got status %q from GCS", resp.Status) + } + + var list objectList + if err := json.NewDecoder(resp.Body).Decode(&list); err != nil { + return fmt.Errorf("unable unmarshal bucket items list: %w", err) + } + + // continue listing if needed + cont = list.NextPageToken != "" + query.Set("pageToken", list.NextPageToken) + + for _, item := range list.Items { + ver, details := versions.ExtractWithPlatform(versions.ArchiveRE, item.Name) + if ver == nil { + c.Log.V(1).Info("skipping bucket object -- does not appear to be a versioned tools object", "name", item.Name) + continue + } + c.Log.V(1).Info("found version", "version", ver, "platform", details) + knownVersions[*ver] = append(knownVersions[*ver], versions.PlatformItem{ + Platform: details, + MD5: item.Hash, + }) + } + + return nil + }() + if err != nil { + return nil, err + } + } + + res := make([]versions.Set, 0, len(knownVersions)) + for ver, details := range knownVersions { + res = append(res, versions.Set{Version: ver, Platforms: details}) + } + // sort in inverse order so that the newest one is first + sort.Slice(res, func(i, j int) bool { + first, second := res[i].Version, res[j].Version + return first.NewerThan(second) + }) + + return res, nil +} + +// GetVersion downloads the given concrete version for the given concrete platform, writing it to the out. +func (c *Client) GetVersion(ctx context.Context, version versions.Concrete, platform versions.PlatformItem, out io.Writer) error { + itemName := platform.ArchiveName(version) + loc := &url.URL{ + Scheme: c.scheme(), + Host: c.Server, + Path: path.Join("/storage/v1/b/", c.Bucket, "o", itemName), + RawQuery: "alt=media", + } + + req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) + if err != nil { + return fmt.Errorf("unable to construct request to fetch %s: %w", itemName, err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("unable to fetch %s (%s): %w", itemName, req.URL, err) + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("unable fetch %s (%s) -- got status %q from GCS", itemName, req.URL, resp.Status) + } + + if platform.MD5 != "" { + // stream in chunks to do the checksum, don't load the whole thing into + // memory to avoid causing issues with big files. + buf := make([]byte, 32*1024) // 32KiB, same as io.Copy + checksum := md5.New() //nolint:gosec + for cont := true; cont; { + amt, err := resp.Body.Read(buf) + if err != nil && !errors.Is(err, io.EOF) { + return fmt.Errorf("unable read next chunk of %s: %w", itemName, err) + } + if amt > 0 { + // checksum never returns errors according to docs + checksum.Write(buf[:amt]) + if _, err := out.Write(buf[:amt]); err != nil { + return fmt.Errorf("unable write next chunk of %s: %w", itemName, err) + } + } + cont = amt > 0 && !errors.Is(err, io.EOF) + } + + sum := base64.StdEncoding.EncodeToString(checksum.Sum(nil)) + + if sum != platform.MD5 { + return fmt.Errorf("checksum mismatch for %s: %s (computed) != %s (reported from GCS)", itemName, sum, platform.MD5) + } + } else if _, err := io.Copy(out, resp.Body); err != nil { + return fmt.Errorf("unable to download %s: %w", itemName, err) + } + return nil +} + +// FetchSum fetches the checksum for the given concrete version & platform into +// the given platform item. +func (c *Client) FetchSum(ctx context.Context, ver versions.Concrete, pl *versions.PlatformItem) error { + itemName := pl.ArchiveName(ver) + loc := &url.URL{ + Scheme: c.scheme(), + Host: c.Server, + Path: path.Join("/storage/v1/b/", c.Bucket, "o", itemName), + } + + req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) + if err != nil { + return fmt.Errorf("unable to construct request to fetch metadata for %s: %w", itemName, err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("unable to fetch metadata for %s: %w", itemName, err) + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("unable fetch metadata for %s -- got status %q from GCS", itemName, resp.Status) + } + + var item bucketObject + if err := json.NewDecoder(resp.Body).Decode(&item); err != nil { + return fmt.Errorf("unable to unmarshal metadata for %s: %w", itemName, err) + } + + pl.MD5 = item.Hash + return nil +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/helpers.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/helpers.go new file mode 100644 index 00000000000..30902187e92 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/helpers.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package store + +import ( + "errors" + "os" + "path/filepath" + "runtime" +) + +// DefaultStoreDir returns the default location for the store. +// It's dependent on operating system: +// +// - Windows: %LocalAppData%\kubebuilder-envtest +// - OSX: ~/Library/Application Support/io.kubebuilder.envtest +// - Others: ${XDG_DATA_HOME:-~/.local/share}/kubebuilder-envtest +// +// Otherwise, it errors out. Note that these paths must not be relied upon +// manually. +func DefaultStoreDir() (string, error) { + var baseDir string + + // find the base data directory + switch runtime.GOOS { + case "windows": + baseDir = os.Getenv("LocalAppData") + if baseDir == "" { + return "", errors.New("%LocalAppData% is not defined") + } + case "darwin", "ios": + homeDir := os.Getenv("HOME") + if homeDir == "" { + return "", errors.New("$HOME is not defined") + } + baseDir = filepath.Join(homeDir, "Library/Application Support") + default: + baseDir = os.Getenv("XDG_DATA_HOME") + if baseDir == "" { + homeDir := os.Getenv("HOME") + if homeDir == "" { + return "", errors.New("neither $XDG_DATA_HOME nor $HOME are defined") + } + baseDir = filepath.Join(homeDir, ".local/share") + } + } + + // append our program-specific dir to it (OSX has a slightly different + // convention so try to follow that). + switch runtime.GOOS { + case "darwin", "ios": + return filepath.Join(baseDir, "io.kubebuilder.envtest"), nil + default: + return filepath.Join(baseDir, "kubebuilder-envtest"), nil + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go new file mode 100644 index 00000000000..e6f258e4ac7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package store + +import ( + "archive/tar" + "compress/gzip" + "context" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "sort" + + "github.com/go-logr/logr" + "github.com/spf13/afero" + + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +// TODO(directxman12): error messages don't show full path, which is gonna make +// things hard to debug + +// Item is a version-platform pair. +type Item struct { + Version versions.Concrete + Platform versions.Platform +} + +// dirName returns the directory name in the store for this item. +func (i Item) dirName() string { + return i.Platform.BaseName(i.Version) +} +func (i Item) String() string { + return fmt.Sprintf("%s (%s)", i.Version, i.Platform) +} + +// Filter is a version spec & platform selector (i.e. platform +// potentially with wilcards) to filter store items. +type Filter struct { + Version versions.Spec + Platform versions.Platform +} + +// Matches checks if this filter matches the given item. +func (f Filter) Matches(item Item) bool { + return f.Version.Matches(item.Version) && f.Platform.Matches(item.Platform) +} + +// Store knows how to list, load, store, and delete envtest tools. +type Store struct { + // Root is the root FS that the store stores in. You'll probably + // want to use a BasePathFS to scope it down to a particular directory. + // + // Note that if for some reason there are nested BasePathFSes, and they're + // interrupted by a non-BasePathFS, Path won't work properly. + Root afero.Fs +} + +// NewAt creates a new store on disk at the given path. +func NewAt(path string) *Store { + return &Store{ + Root: afero.NewBasePathFs(afero.NewOsFs(), path), + } +} + +// Initialize ensures that the store is all set up on disk, etc. +func (s *Store) Initialize(ctx context.Context) error { + log, err := logr.FromContext(ctx) + if err != nil { + return err + } + + log.V(1).Info("ensuring base binaries dir exists") + if err := s.unpackedBase().MkdirAll("", 0755); err != nil { + return fmt.Errorf("unable to make sure base binaries dir exists: %w", err) + } + return nil +} + +// Has checks if an item exists in the store. +func (s *Store) Has(item Item) (bool, error) { + path := s.unpackedPath(item.dirName()) + _, err := path.Stat("") + if err != nil && !errors.Is(err, afero.ErrFileNotFound) { + return false, fmt.Errorf("unable to check if version-platform dir exists: %w", err) + } + return err == nil, nil +} + +// List lists all items matching the given filter. +// +// Results are stored by version (newest first), and OS/arch (consistently, +// but no guaranteed ordering). +func (s *Store) List(ctx context.Context, matching Filter) ([]Item, error) { + var res []Item + if err := s.eachItem(ctx, matching, func(_ string, item Item) { + res = append(res, item) + }); err != nil { + return nil, fmt.Errorf("unable to list version-platform pairs in store: %w", err) + } + + sort.Slice(res, func(i, j int) bool { + if !res[i].Version.Matches(res[j].Version) { + return res[i].Version.NewerThan(res[j].Version) + } + return orderPlatforms(res[i].Platform, res[j].Platform) + }) + + return res, nil +} + +// Add adds this item to the store, with the given contents (a .tar.gz file). +func (s *Store) Add(ctx context.Context, item Item, contents io.Reader) (resErr error) { + log, err := logr.FromContext(ctx) + if err != nil { + return err + } + + itemName := item.dirName() + log = log.WithValues("version-platform", itemName) + itemPath := s.unpackedPath(itemName) + + // make sure to clean up if we hit an error + defer func() { + if resErr != nil { + // intentially ignore this because we can't really do anything + err := s.removeItem(itemPath) + if err != nil { + log.Error(err, "unable to clean up partially added version-platform pair after error") + } + } + }() + + log.V(1).Info("ensuring version-platform binaries dir exists and is empty & writable") + _, err = itemPath.Stat("") + if err != nil && !errors.Is(err, afero.ErrFileNotFound) { + return fmt.Errorf("unable to ensure version-platform binaries dir %s exists", itemName) + } + if err == nil { // exists + log.V(1).Info("cleaning up old version-platform binaries dir") + if err := s.removeItem(itemPath); err != nil { + return fmt.Errorf("unable to clean up existing version-platform binaries dir %s", itemName) + } + } + if err := itemPath.MkdirAll("", 0755); err != nil { + return fmt.Errorf("unable to make sure entry dir %s exists", itemName) + } + + log.V(1).Info("extracting archive") + gzStream, err := gzip.NewReader(contents) + if err != nil { + return fmt.Errorf("unable to start un-gz-ing entry archive") + } + tarReader := tar.NewReader(gzStream) + + var header *tar.Header + for header, err = tarReader.Next(); err == nil; header, err = tarReader.Next() { + if header.Typeflag != tar.TypeReg { // TODO(directxman12): support symlinks, etc? + log.V(1).Info("skipping non-regular-file entry in archive", "entry", header.Name) + continue + } + // just dump all files to the main path, ignoring the prefixed directory + // paths -- they're redundant. We also ignore bits for the most part (except for X), + // preferfing our own scheme. + targetPath := filepath.Base(header.Name) + log.V(1).Info("writing archive file to disk", "archive file", header.Name, "on-disk file", targetPath) + perms := 0555 & header.Mode // make sure we're at most r+x + binOut, err := itemPath.OpenFile(targetPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(perms)) + if err != nil { + return fmt.Errorf("unable to create file %s from archive to disk for version-platform pair %s", targetPath, itemName) + } + if err := func() error { // IIFE to get the defer properly in a loop + defer binOut.Close() + if _, err := io.Copy(binOut, tarReader); err != nil { //nolint:gosec + return fmt.Errorf("unable to write file %s from archive to disk for version-platform pair %s", targetPath, itemName) + } + return nil + }(); err != nil { + return err + } + } + if err != nil && !errors.Is(err, io.EOF) { + return fmt.Errorf("unable to finish un-tar-ing the downloaded archive: %w", err) + } + log.V(1).Info("unpacked archive") + + log.V(1).Info("switching version-platform directory to read-only") + if err := itemPath.Chmod("", 0555); err != nil { + // don't bail, this isn't fatal + log.Error(err, "unable to make version-platform directory read-only") + } + return nil +} + +// Remove removes all items matching the given filter. +// +// It returns a list of the successfully removed items (even in the case +// of an error). +func (s *Store) Remove(ctx context.Context, matching Filter) ([]Item, error) { + log, err := logr.FromContext(ctx) + if err != nil { + return nil, err + } + + var removed []Item + var savedErr error + if err := s.eachItem(ctx, matching, func(name string, item Item) { + log.V(1).Info("Removing version-platform pair at path", "version-platform", item, "path", name) + + if err := s.removeItem(s.unpackedPath(name)); err != nil { + log.Error(err, "unable to make existing version-platform dir writable to clean it up", "path", name) + savedErr = fmt.Errorf("unable to remove version-platform pair %s (dir %s): %w", item, name, err) + return // don't mark this as removed in the report + } + removed = append(removed, item) + }); err != nil { + return removed, fmt.Errorf("unable to list version-platform pairs to figure out what to delete: %w", err) + } + if savedErr != nil { + return removed, savedErr + } + return removed, nil +} + +// Path returns an actual path that case be used to access this item. +func (s *Store) Path(item Item) (string, error) { + path := s.unpackedPath(item.dirName()) + // NB(directxman12): we need root's realpath because RealPath only + // looks at its own path, and so thus doesn't prepend the underlying + // root's base path. + // + // Technically, if we're fed something that's double wrapped as root, + // this'll be wrong, but this is basically as much as we can do + return afero.FullBaseFsPath(path.(*afero.BasePathFs), ""), nil +} + +// unpackedBase returns the directory in which item dirs lives. +func (s *Store) unpackedBase() afero.Fs { + return afero.NewBasePathFs(s.Root, "k8s") +} + +// unpackedPath returns the item dir with this name. +func (s *Store) unpackedPath(name string) afero.Fs { + return afero.NewBasePathFs(s.unpackedBase(), name) +} + +// eachItem iterates through the on-disk versions that match our version & platform selector, +// calling the callback for each. +func (s *Store) eachItem(ctx context.Context, filter Filter, cb func(name string, item Item)) error { + log, err := logr.FromContext(ctx) + if err != nil { + return err + } + + entries, err := afero.ReadDir(s.unpackedBase(), "") + if err != nil { + return fmt.Errorf("unable to list folders in store's unpacked directory: %w", err) + } + + for _, entry := range entries { + if !entry.IsDir() { + log.V(1).Info("skipping dir entry, not a folder", "entry", entry.Name()) + continue + } + ver, pl := versions.ExtractWithPlatform(versions.VersionPlatformRE, entry.Name()) + if ver == nil { + log.V(1).Info("skipping dir entry, not a version", "entry", entry.Name()) + continue + } + item := Item{Version: *ver, Platform: pl} + + if !filter.Matches(item) { + log.V(1).Info("skipping on disk version, does not match version and platform selectors", "platform", pl, "version", ver, "entry", entry.Name()) + continue + } + + cb(entry.Name(), item) + } + + return nil +} + +// removeItem removes the given item directory from disk. +func (s *Store) removeItem(itemDir afero.Fs) error { + if err := itemDir.Chmod("", 0755); err != nil { + // no point in trying to remove if we can't fix the permissions, bail here + return fmt.Errorf("unable to make version-platform dir writable: %w", err) + } + if err := itemDir.RemoveAll(""); err != nil && !errors.Is(err, afero.ErrFileNotFound) { + return fmt.Errorf("unable to remove version-platform dir: %w", err) + } + return nil +} + +// orderPlatforms orders platforms by OS then arch. +func orderPlatforms(first, second versions.Platform) bool { + // sort by OS, then arch + if first.OS != second.OS { + return first.OS < second.OS + } + return first.Arch < second.Arch +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_suite_test.go new file mode 100644 index 00000000000..c2795a32276 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_suite_test.go @@ -0,0 +1,51 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package store_test + +import ( + "context" + "testing" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var testLog logr.Logger + +func zapLogger() logr.Logger { + testOut := zapcore.AddSync(GinkgoWriter) + enc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) + // bleh setting up logging to the ginkgo writer is annoying + zapLog := zap.New(zapcore.NewCore(enc, testOut, zap.DebugLevel), + zap.ErrorOutput(testOut), zap.Development(), zap.AddStacktrace(zap.WarnLevel)) + return zapr.NewLogger(zapLog) +} + +func logCtx() context.Context { + return logr.NewContext(context.Background(), testLog) +} + +func TestStore(t *testing.T) { + testLog = zapLogger() + RegisterFailHandler(Fail) + RunSpecs(t, "Store Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_test.go new file mode 100644 index 00000000000..d5607aede6d --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store_test.go @@ -0,0 +1,250 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package store_test + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto/rand" + "io" + "io/fs" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/spf13/afero" + + "sigs.k8s.io/controller-runtime/tools/setup-envtest/store" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +const ( + fakeStorePath = "/path/to/the/store" +) + +var _ = Describe("Store", func() { + var st *store.Store + BeforeEach(func() { + fs := afero.NewMemMapFs() + fakeStoreFiles(fs, fakeStorePath) + st = &store.Store{ + Root: afero.NewBasePathFs(fs, fakeStorePath), + } + }) + Describe("initialization", func() { + It("should ensure the repo root exists", func() { + // remove the old dir + Expect(st.Root.RemoveAll("")).To(Succeed(), "should be able to remove the store before trying to initialize") + + Expect(st.Initialize(logCtx())).To(Succeed(), "initialization should succeed") + Expect(st.Root.Stat("k8s")).NotTo(BeNil(), "store's binary dir should exist") + }) + + It("should be fine if the repo root already exists", func() { + Expect(st.Initialize(logCtx())).To(Succeed()) + }) + }) + Describe("listing items", func() { + It("should filter results by the given filter, sorted in version order (newest first)", func() { + sel, err := versions.FromExpr("<=1.16") + Expect(err).NotTo(HaveOccurred(), "should be able to construct <=1.16 selector") + Expect(st.List(logCtx(), store.Filter{ + Version: sel, + Platform: versions.Platform{OS: "*", Arch: "amd64"}, + })).To(Equal([]store.Item{ + {Version: ver(1, 16, 2), Platform: versions.Platform{OS: "ifonlysingularitywasstillathing", Arch: "amd64"}}, + {Version: ver(1, 16, 1), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 16, 0), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 14, 26), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + })) + }) + It("should skip non-folders in the store", func() { + Expect(afero.WriteFile(st.Root, "k8s/2.3.6-linux-amd128", []byte{0x01}, fs.ModePerm)).To(Succeed(), "should be able to create a non-store file in the store directory") + Expect(st.List(logCtx(), store.Filter{ + Version: versions.AnyVersion, Platform: versions.Platform{OS: "linux", Arch: "amd128"}, + })).To(BeEmpty()) + }) + + It("should skip non-matching names in the store", func() { + Expect(st.Root.Mkdir("k8s/somedir-2.3.6-linux-amd128", fs.ModePerm)).To(Succeed(), "should be able to create a non-store file in the store directory") + Expect(st.List(logCtx(), store.Filter{ + Version: versions.AnyVersion, Platform: versions.Platform{OS: "linux", Arch: "amd128"}, + })).To(BeEmpty()) + }) + }) + + Describe("removing items", func() { + var res []store.Item + BeforeEach(func() { + sel, err := versions.FromExpr("<=1.16") + Expect(err).NotTo(HaveOccurred(), "should be able to construct <=1.16 selector") + res, err = st.Remove(logCtx(), store.Filter{ + Version: sel, + Platform: versions.Platform{OS: "*", Arch: "amd64"}, + }) + Expect(err).NotTo(HaveOccurred(), "should be able to remove <=1.16 & */amd64") + }) + It("should return all items removed", func() { + Expect(res).To(ConsistOf( + store.Item{Version: ver(1, 16, 2), Platform: versions.Platform{OS: "ifonlysingularitywasstillathing", Arch: "amd64"}}, + store.Item{Version: ver(1, 16, 1), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + store.Item{Version: ver(1, 16, 0), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + store.Item{Version: ver(1, 14, 26), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + )) + }) + It("should remove all items matching the given filter from disk", func() { + Expect(afero.ReadDir(st.Root, "k8s")).NotTo(ContainElements( + WithTransform(fs.FileInfo.Name, Equal("1.16.2-ifonlysingularitywasstillathing-amd64")), + WithTransform(fs.FileInfo.Name, Equal("1.16.1-linux-amd64")), + WithTransform(fs.FileInfo.Name, Equal("1.16.0-linux-amd64")), + WithTransform(fs.FileInfo.Name, Equal("1.14.26-linux-amd64")), + )) + }) + + It("should leave items that don't match in place", func() { + Expect(afero.ReadDir(st.Root, "k8s")).To(ContainElements( + WithTransform(fs.FileInfo.Name, Equal("1.17.9-linux-amd64")), + WithTransform(fs.FileInfo.Name, Equal("1.16.2-linux-yourimagination")), + WithTransform(fs.FileInfo.Name, Equal("1.14.26-hyperwarp-pixiedust")), + )) + }) + }) + + Describe("adding items", func() { + It("should support .tar.gz input", func() { + Expect(st.Add(logCtx(), newItem, makeFakeArchive(newName))).To(Succeed()) + Expect(st.Has(newItem)).To(BeTrue(), "should have the item after adding it") + }) + + It("should extract binaries from the given archive to a directly to the item's directory, regardless of path", func() { + Expect(st.Add(logCtx(), newItem, makeFakeArchive(newName))).To(Succeed()) + + dirName := newItem.Platform.BaseName(newItem.Version) + Expect(afero.ReadFile(st.Root, filepath.Join("k8s", dirName, "some-file"))).To(HavePrefix(newName + "some-file")) + Expect(afero.ReadFile(st.Root, filepath.Join("k8s", dirName, "other-file"))).To(HavePrefix(newName + "other-file")) + }) + + It("should clean up any existing item directory before creating the new one", func() { + item := localVersions[0] + Expect(st.Add(logCtx(), item, makeFakeArchive(newName))).To(Succeed()) + Expect(st.Root.Stat(filepath.Join("k8s", item.Platform.BaseName(item.Version)))).NotTo(BeNil(), "new files should exist") + }) + It("should clean up if it errors before finishing", func() { + item := localVersions[0] + Expect(st.Add(logCtx(), item, new(bytes.Buffer))).NotTo(Succeed(), "should fail to extract") + _, err := st.Root.Stat(filepath.Join("k8s", item.Platform.BaseName(item.Version))) + Expect(err).To(HaveOccurred(), "the binaries dir for the item should be gone") + + }) + }) + + Describe("checking if items are present", func() { + It("should report that present directories are present", func() { + Expect(st.Has(localVersions[0])).To(BeTrue()) + }) + + It("should report that absent directories are absent", func() { + Expect(st.Has(newItem)).To(BeFalse()) + }) + }) + + Describe("getting the path", func() { + It("should return the absolute on-disk path of the given item", func() { + item := localVersions[0] + Expect(st.Path(item)).To(Equal(filepath.Join(fakeStorePath, "k8s", item.Platform.BaseName(item.Version)))) + }) + }) +}) + +var ( + // keep this sorted. + localVersions = []store.Item{ + {Version: ver(1, 17, 9), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 16, 2), Platform: versions.Platform{OS: "linux", Arch: "yourimagination"}}, + {Version: ver(1, 16, 2), Platform: versions.Platform{OS: "ifonlysingularitywasstillathing", Arch: "amd64"}}, + {Version: ver(1, 16, 1), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 16, 0), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 14, 26), Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Version: ver(1, 14, 26), Platform: versions.Platform{OS: "hyperwarp", Arch: "pixiedust"}}, + } + + newItem = store.Item{ + Version: ver(1, 16, 3), + Platform: versions.Platform{OS: "linux", Arch: "amd64"}, + } + + newName = "kubebuilder-tools-1.16.3-linux-amd64.tar.gz" +) + +func ver(major, minor, patch int) versions.Concrete { + return versions.Concrete{ + Major: major, + Minor: minor, + Patch: patch, + } +} + +func makeFakeArchive(magic string) io.Reader { + out := new(bytes.Buffer) + gzipWriter := gzip.NewWriter(out) + tarWriter := tar.NewWriter(gzipWriter) + Expect(tarWriter.WriteHeader(&tar.Header{ + Typeflag: tar.TypeDir, + Name: "kubebuilder/bin/", // so we can ensure we skip non-files + Mode: 0777, + })).To(Succeed()) + for _, fileName := range []string{"some-file", "other-file"} { + // create fake file contents: magic+fileName+randomBytes() + var chunk [1024 * 48]byte // 1.5 times our chunk read size in GetVersion + copy(chunk[:], magic) + copy(chunk[len(magic):], fileName) + start := len(magic) + len(fileName) + if _, err := rand.Read(chunk[start:]); err != nil { + panic(err) + } + + // write to kubebuilder/bin/fileName + err := tarWriter.WriteHeader(&tar.Header{ + Name: "kubebuilder/bin/" + fileName, + Size: int64(len(chunk[:])), + Mode: 0777, // so we can check that we fix this later + }) + if err != nil { + panic(err) + } + _, err = tarWriter.Write(chunk[:]) + if err != nil { + panic(err) + } + } + tarWriter.Close() + gzipWriter.Close() + + return out +} + +func fakeStoreFiles(fs afero.Fs, dir string) { + By("making the unpacked directory") + unpackedBase := filepath.Join(dir, "k8s") + Expect(fs.Mkdir(unpackedBase, 0755)).To(Succeed()) + + By("making some fake (empty) versions") + for _, item := range localVersions { + Expect(fs.Mkdir(filepath.Join(unpackedBase, item.Platform.BaseName(item.Version)), 0755)).To(Succeed()) + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/misc_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/misc_test.go new file mode 100644 index 00000000000..8a97de04104 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/misc_test.go @@ -0,0 +1,143 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package versions_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +var _ = Describe("Concrete", func() { + It("should match the only same version", func() { + ver16 := Concrete{Major: 1, Minor: 16} + ver17 := Concrete{Major: 1, Minor: 17} + Expect(ver16.Matches(ver16)).To(BeTrue(), "should match the same version") + Expect(ver16.Matches(ver17)).To(BeFalse(), "should not match a different version") + }) + It("should serialize as X.Y.Z", func() { + Expect(Concrete{Major: 1, Minor: 16, Patch: 3}.String()).To(Equal("1.16.3")) + }) + Describe("when ordering relative to other versions", func() { + ver1163 := Concrete{Major: 1, Minor: 16, Patch: 3} + Specify("newer patch should be newer", func() { + Expect(ver1163.NewerThan(Concrete{Major: 1, Minor: 16})).To(BeTrue()) + }) + Specify("newer minor should be newer", func() { + Expect(ver1163.NewerThan(Concrete{Major: 1, Minor: 15, Patch: 3})).To(BeTrue()) + }) + Specify("newer major should be newer", func() { + Expect(ver1163.NewerThan(Concrete{Major: 0, Minor: 16, Patch: 3})).To(BeTrue()) + }) + }) +}) + +var _ = Describe("Platform", func() { + Specify("a concrete platform should match exactly itself", func() { + plat1 := Platform{OS: "linux", Arch: "amd64"} + plat2 := Platform{OS: "linux", Arch: "s390x"} + plat3 := Platform{OS: "windows", Arch: "amd64"} + Expect(plat1.Matches(plat1)).To(BeTrue(), "should match itself") + Expect(plat1.Matches(plat2)).To(BeFalse(), "should reject a different arch") + Expect(plat1.Matches(plat3)).To(BeFalse(), "should reject a different os") + }) + Specify("a wildcard arch should match any arch", func() { + sel := Platform{OS: "linux", Arch: "*"} + plat1 := Platform{OS: "linux", Arch: "amd64"} + plat2 := Platform{OS: "linux", Arch: "s390x"} + plat3 := Platform{OS: "windows", Arch: "amd64"} + Expect(sel.Matches(sel)).To(BeTrue(), "should match itself") + Expect(sel.Matches(plat1)).To(BeTrue(), "should match some arch with the same OS") + Expect(sel.Matches(plat2)).To(BeTrue(), "should match another arch with the same OS") + Expect(plat1.Matches(plat3)).To(BeFalse(), "should reject a different os") + }) + Specify("a wildcard os should match any os", func() { + sel := Platform{OS: "*", Arch: "amd64"} + plat1 := Platform{OS: "linux", Arch: "amd64"} + plat2 := Platform{OS: "windows", Arch: "amd64"} + plat3 := Platform{OS: "linux", Arch: "s390x"} + Expect(sel.Matches(sel)).To(BeTrue(), "should match itself") + Expect(sel.Matches(plat1)).To(BeTrue(), "should match some os with the same arch") + Expect(sel.Matches(plat2)).To(BeTrue(), "should match another os with the same arch") + Expect(plat1.Matches(plat3)).To(BeFalse(), "should reject a different arch") + }) + It("should report a wildcard OS as a wildcard platform", func() { + Expect(Platform{OS: "*", Arch: "amd64"}.IsWildcard()).To(BeTrue()) + }) + It("should report a wildcard arch as a wildcard platform", func() { + Expect(Platform{OS: "linux", Arch: "*"}.IsWildcard()).To(BeTrue()) + }) + It("should serialize as os/arch", func() { + Expect(Platform{OS: "linux", Arch: "amd64"}.String()).To(Equal("linux/amd64")) + }) + + Specify("knows how to produce a base store name", func() { + plat := Platform{OS: "linux", Arch: "amd64"} + ver := Concrete{Major: 1, Minor: 16, Patch: 3} + Expect(plat.BaseName(ver)).To(Equal("1.16.3-linux-amd64")) + }) + + Specify("knows how to produce an archive name", func() { + plat := Platform{OS: "linux", Arch: "amd64"} + ver := Concrete{Major: 1, Minor: 16, Patch: 3} + Expect(plat.ArchiveName(ver)).To(Equal("kubebuilder-tools-1.16.3-linux-amd64.tar.gz")) + }) + + Describe("parsing", func() { + Context("for version-platform names", func() { + It("should accept strings of the form x.y.z-os-arch", func() { + ver, plat := ExtractWithPlatform(VersionPlatformRE, "1.16.3-linux-amd64") + Expect(ver).To(Equal(&Concrete{Major: 1, Minor: 16, Patch: 3})) + Expect(plat).To(Equal(Platform{OS: "linux", Arch: "amd64"})) + }) + It("should reject nonsense strings", func() { + ver, _ := ExtractWithPlatform(VersionPlatformRE, "1.16-linux-amd64") + Expect(ver).To(BeNil()) + }) + }) + Context("for archive names", func() { + It("should accept strings of the form kubebuilder-tools-x.y.z-os-arch.tar.gz", func() { + ver, plat := ExtractWithPlatform(ArchiveRE, "kubebuilder-tools-1.16.3-linux-amd64.tar.gz") + Expect(ver).To(Equal(&Concrete{Major: 1, Minor: 16, Patch: 3})) + Expect(plat).To(Equal(Platform{OS: "linux", Arch: "amd64"})) + }) + It("should reject nonsense strings", func() { + ver, _ := ExtractWithPlatform(ArchiveRE, "kubebuilder-tools-1.16.3-linux-amd64.tar.sum") + Expect(ver).To(BeNil()) + }) + }) + }) +}) + +var _ = Describe("Spec helpers", func() { + Specify("can fill a spec with a concrete version", func() { + spec := Spec{Selector: AnySelector{}} // don't just use AnyVersion so we don't modify it + spec.MakeConcrete(Concrete{Major: 1, Minor: 16}) + Expect(spec.AsConcrete()).To(Equal(&Concrete{Major: 1, Minor: 16})) + }) + It("should serialize as the underlying selector with ! for check latest", func() { + spec, err := FromExpr("1.16.*!") + Expect(err).NotTo(HaveOccurred()) + Expect(spec.String()).To(Equal("1.16.*!")) + }) + It("should serialize as the underlying selector by itself if not check latest", func() { + spec, err := FromExpr("1.16.*") + Expect(err).NotTo(HaveOccurred()) + Expect(spec.String()).To(Equal("1.16.*")) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go new file mode 100644 index 00000000000..c053bf87574 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package versions + +import ( + "fmt" + "regexp" + "strconv" +) + +var ( + // baseVersionRE is a semver-ish version -- either X.Y.Z, X.Y, or X.Y.{*|x}. + baseVersionRE = `(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:\.(?P0|[1-9]\d*|x|\*))?` + // versionExprRe matches valid version input for FromExpr. + versionExprRE = regexp.MustCompile(`^(?P<|~|<=)?` + baseVersionRE + `(?P!)?$`) + + // ConcreteVersionRE matches a concrete version anywhere in the string. + ConcreteVersionRE = regexp.MustCompile(`(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)`) + // OnlyConcreteVersionRE matches a string that's just a concrete version. + OnlyConcreteVersionRE = regexp.MustCompile(`^` + ConcreteVersionRE.String() + `$`) +) + +// FromExpr extracts a version from a string in the form of a semver version, +// where X, Y, and Z may also be wildcards ('*', 'x'), +// and pre-release names & numbers may also be wildcards. The prerelease section is slightly +// restricted to match what k8s does. +// The whole string is a version selector as follows: +// - X.Y.Z matches version X.Y.Z where x, y, and z are +// are ints >= 0, and Z may be '*' or 'x' +// - X.Y is equivalent to X.Y.* +// - ~X.Y.Z means >= X.Y.Z && < X.Y+1.0 +// - = comparisons, if we use + // wildcards with a selector we can just set them to zero. + if verInfo.Patch == AnyPoint { + verInfo.Patch = PointVersion(0) + } + baseVer := *verInfo.AsConcrete() + spec.Selector = TildeSelector{Concrete: baseVer} + default: + panic("unreachable: mismatch between FromExpr and its RE in selector") + } + + return spec, nil +} + +// PointVersionFromValidString extracts a point version +// from the corresponding string representation, which may +// be a number >= 0, or x|* (AnyPoint). +// +// Anything else will cause a panic (use this on strings +// extracted from regexes). +func PointVersionFromValidString(str string) PointVersion { + switch str { + case "*", "x": + return AnyPoint + default: + ver, err := strconv.Atoi(str) + if err != nil { + panic(err) + } + return PointVersion(ver) + } +} + +// PatchSelectorFromMatch constructs a simple selector according to the +// ParseExpr rules out of pre-validated sections. +// +// re must include name captures for major, minor, patch, prenum, and prelabel +// +// Any bad input may cause a panic. Use with when you got the parts from an RE match. +func PatchSelectorFromMatch(match []string, re *regexp.Regexp) PatchSelector { + // already parsed via RE, should be fine to ignore errors unless it's a + // *huge* number + major, err := strconv.Atoi(match[re.SubexpIndex("major")]) + if err != nil { + panic("invalid input passed as patch selector (invalid state)") + } + minor, err := strconv.Atoi(match[re.SubexpIndex("minor")]) + if err != nil { + panic("invalid input passed as patch selector (invalid state)") + } + + // patch is optional, means wilcard if left off + patch := AnyPoint + if patchRaw := match[re.SubexpIndex("patch")]; patchRaw != "" { + patch = PointVersionFromValidString(patchRaw) + } + return PatchSelector{ + Major: major, + Minor: minor, + Patch: patch, + } +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse_test.go new file mode 100644 index 00000000000..062fdcc6c8c --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse_test.go @@ -0,0 +1,95 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package versions_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +func patchSel(x, y int, z PointVersion) PatchSelector { + return PatchSelector{Major: x, Minor: y, Patch: z} +} + +func patchSpec(x, y int, z PointVersion) Spec { + return Spec{Selector: patchSel(x, y, z)} +} + +func tildeSel(x, y, z int) TildeSelector { + return TildeSelector{ + Concrete: Concrete{ + Major: x, Minor: y, Patch: z, + }, + } +} + +func tildeSpec(x, y, z int) Spec { + return Spec{Selector: tildeSel(x, y, z)} +} +func ltSpec(x, y int, z PointVersion) Spec { + // this just keeps the table a bit shorter + return Spec{Selector: LessThanSelector{ + PatchSelector: patchSel(x, y, z), + }} +} +func lteSpec(x, y int, z PointVersion) Spec { + // this just keeps the table a bit shorter + return Spec{Selector: LessThanSelector{ + PatchSelector: patchSel(x, y, z), + OrEquals: true, + }} +} + +var _ = Describe("Parse", func() { + DescribeTable("it should support", + func(spec string, expected Spec) { + Expect(FromExpr(spec)).To(Equal(expected)) + }, + Entry("X.Y versions", "1.16", patchSpec(1, 16, AnyPoint)), + Entry("X.Y.Z versions", "1.16.3", patchSpec(1, 16, PointVersion(3))), + Entry("X.Y.x wildcard", "1.16.x", patchSpec(1, 16, AnyPoint)), + Entry("X.Y.* wildcard", "1.16.*", patchSpec(1, 16, AnyPoint)), + + Entry("~X.Y selector", "~1.16", tildeSpec(1, 16, 0)), + Entry("~X.Y.Z selector", "~1.16.3", tildeSpec(1, 16, 3)), + Entry("~X.Y.x selector", "~1.16.x", tildeSpec(1, 16, 0)), + Entry("~X.Y.* selector", "~1.16.*", tildeSpec(1, 16, 0)), + + Entry("\w+)-(?P\w+)` + // VersionPlatformRE matches concrete version-platform strings. + VersionPlatformRE = regexp.MustCompile(`^` + versionPlatformREBase + `$`) + // ArchiveRE matches concrete version-platform.tar.gz strings. + ArchiveRE = regexp.MustCompile(`^kubebuilder-tools-` + versionPlatformREBase + `\.tar\.gz$`) +) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/selectors_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/selectors_test.go new file mode 100644 index 00000000000..8357d41c803 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/selectors_test.go @@ -0,0 +1,216 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package versions_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + . "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +var _ = Describe("Selectors", func() { + Describe("patch", func() { + var sel Selector + Context("with any patch", func() { + BeforeEach(func() { + var err error + sel, err = FromExpr("1.16.*") + Expect(err).NotTo(HaveOccurred()) + }) + + It("should match any patch version with the same major & minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 3})).To(BeTrue(), "should match 1.16.3") + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 0})).To(BeTrue(), "should match 1.16.0") + }) + + It("should reject a different major", func() { + Expect(sel.Matches(Concrete{Major: 2, Minor: 16, Patch: 3})).To(BeFalse(), "should reject 2.16.3") + + }) + + It("should reject a different minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 17, Patch: 3})).To(BeFalse(), "should reject 1.17.3") + }) + + It("should serialize as X.Y.*", func() { + Expect(sel.String()).To(Equal("1.16.*")) + }) + + It("should not be concrete", func() { + Expect(sel.AsConcrete()).To(BeNil()) + }) + }) + + Context("with a specific patch", func() { + BeforeEach(func() { + var err error + sel, err = FromExpr("1.16.3") + Expect(err).NotTo(HaveOccurred()) + }) + It("should match exactly the major/minor/patch", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 3})).To(BeTrue(), "should match 1.16.3") + }) + + It("should reject a different major", func() { + Expect(sel.Matches(Concrete{Major: 2, Minor: 16, Patch: 3})).To(BeFalse(), "should reject 2.16.3") + + }) + + It("should reject a different minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 17, Patch: 3})).To(BeFalse(), "should reject 1.17.3") + + }) + + It("should reject a different patch", func() { + + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 4})).To(BeFalse(), "should reject 1.16.4") + }) + It("should serialize as X.Y.Z", func() { + Expect(sel.String()).To(Equal("1.16.3")) + }) + It("may be concrete", func() { + Expect(sel.AsConcrete()).To(Equal(&Concrete{Major: 1, Minor: 16, Patch: 3})) + }) + }) + + }) + + Describe("tilde", func() { + var sel Selector + BeforeEach(func() { + var err error + sel, err = FromExpr("~1.16.3") + Expect(err).NotTo(HaveOccurred()) + }) + It("should match exactly the major/minor/patch", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 3})).To(BeTrue(), "should match 1.16.3") + }) + + It("should match a patch greater than the given one, with the same major/minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 4})).To(BeTrue(), "should match 1.16.4") + }) + + It("should reject a patch less than the given one, with the same major/minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 2})).To(BeFalse(), "should reject 1.16.2") + + }) + + It("should reject a different major", func() { + Expect(sel.Matches(Concrete{Major: 2, Minor: 16, Patch: 3})).To(BeFalse(), "should reject 2.16.3") + + }) + + It("should reject a different minor", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 17, Patch: 3})).To(BeFalse(), "should reject 1.17.3") + + }) + + It("should treat ~X.Y.* as ~X.Y.Z", func() { + sel, err := FromExpr("~1.16.*") + Expect(err).NotTo(HaveOccurred()) + + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 0})).To(BeTrue(), "should match 1.16.0") + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 3})).To(BeTrue(), "should match 1.16.3") + Expect(sel.Matches(Concrete{Major: 1, Minor: 17, Patch: 0})).To(BeFalse(), "should reject 1.17.0") + }) + It("should serialize as ~X.Y.Z", func() { + Expect(sel.String()).To(Equal("~1.16.3")) + }) + It("should never be concrete", func() { + Expect(sel.AsConcrete()).To(BeNil()) + }) + }) + + Describe("less-than", func() { + var sel Selector + BeforeEach(func() { + var err error + sel, err = FromExpr("<1.16.3") + Expect(err).NotTo(HaveOccurred()) + }) + It("should reject the exact major/minor/patch", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 3})).To(BeFalse(), "should reject 1.16.3") + + }) + It("should reject greater patches", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 4})).To(BeFalse(), "should reject 1.16.4") + + }) + It("should reject greater majors", func() { + Expect(sel.Matches(Concrete{Major: 2, Minor: 16, Patch: 3})).To(BeFalse(), "should reject 2.16.3") + + }) + It("should reject greater minors", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 17, Patch: 3})).To(BeFalse(), "should reject 1.17.3") + + }) + + It("should accept lesser patches", func() { + + Expect(sel.Matches(Concrete{Major: 1, Minor: 16, Patch: 2})).To(BeTrue(), "should accept 1.16.2") + }) + It("should accept lesser majors", func() { + Expect(sel.Matches(Concrete{Major: 0, Minor: 16, Patch: 3})).To(BeTrue(), "should accept 0.16.3") + + }) + It("should accept lesser minors", func() { + Expect(sel.Matches(Concrete{Major: 1, Minor: 15, Patch: 3})).To(BeTrue(), "should accept 1.15.3") + + }) + It("should serialize as other.Major + } + if c.Minor != other.Minor { + return c.Minor > other.Minor + } + return c.Patch > other.Patch +} + +// Matches checks if this version is equal to the other one. +func (c Concrete) Matches(other Concrete) bool { + return c == other +} + +func (c Concrete) String() string { + return fmt.Sprintf("%d.%d.%d", c.Major, c.Minor, c.Patch) +} + +// PatchSelector selects a set of versions where the patch is a wildcard. +type PatchSelector struct { + Major, Minor int + Patch PointVersion +} + +func (s PatchSelector) String() string { + return fmt.Sprintf("%d.%d.%s", s.Major, s.Minor, s.Patch) +} + +// Matches checks if the given version matches this selector. +func (s PatchSelector) Matches(ver Concrete) bool { + return s.Major == ver.Major && s.Minor == ver.Minor && s.Patch.Matches(ver.Patch) +} + +// AsConcrete returns nil if there are wildcards in this selector, +// and the concrete version that this selects otherwise. +func (s PatchSelector) AsConcrete() *Concrete { + if s.Patch == AnyPoint { + return nil + } + + return &Concrete{ + Major: s.Major, + Minor: s.Minor, + Patch: int(s.Patch), // safe to cast, we've just checked wilcards above + } +} + +// TildeSelector selects [X.Y.Z, X.Y+1.0). +type TildeSelector struct { + Concrete +} + +// Matches checks if the given version matches this selector. +func (s TildeSelector) Matches(ver Concrete) bool { + if s.Concrete.Matches(ver) { + // easy, "exact" match + return true + } + return ver.Major == s.Major && ver.Minor == s.Minor && ver.Patch >= s.Patch +} +func (s TildeSelector) String() string { + return "~" + s.Concrete.String() +} + +// AsConcrete returns nil (this is never a concrete version). +func (s TildeSelector) AsConcrete() *Concrete { + return nil +} + +// LessThanSelector selects versions older than the given one +// (mainly useful for cleaning up). +type LessThanSelector struct { + PatchSelector + OrEquals bool +} + +// Matches checks if the given version matches this selector. +func (s LessThanSelector) Matches(ver Concrete) bool { + if s.Major != ver.Major { + return s.Major > ver.Major + } + if s.Minor != ver.Minor { + return s.Minor > ver.Minor + } + if !s.Patch.Matches(ver.Patch) { + // matches rules out a wildcard, so it's fine to compare as normal numbers + return int(s.Patch) > ver.Patch + } + return s.OrEquals +} +func (s LessThanSelector) String() string { + if s.OrEquals { + return "<=" + s.PatchSelector.String() + } + return "<" + s.PatchSelector.String() +} + +// AsConcrete returns nil (this is never a concrete version). +func (s LessThanSelector) AsConcrete() *Concrete { + return nil +} + +// AnySelector matches any version at all. +type AnySelector struct{} + +// Matches checks if the given version matches this selector. +func (AnySelector) Matches(_ Concrete) bool { return true } + +// AsConcrete returns nil (this is never a concrete version). +func (AnySelector) AsConcrete() *Concrete { return nil } +func (AnySelector) String() string { return "*" } + +// Selector selects some concrete version or range of versions. +type Selector interface { + // AsConcrete tries to return this selector as a concrete version. + // If the selector would only match a single version, it'll return + // that, otherwise it'll return nil. + AsConcrete() *Concrete + // Matches checks if this selector matches the given concrete version. + Matches(ver Concrete) bool + String() string +} + +// Spec matches some version or range of versions, and tells us how to deal with local and +// remote when selecting a version. +type Spec struct { + Selector + + // CheckLatest tells us to check the remote server for the latest + // version that matches our selector, instead of just relying on + // matching local versions. + CheckLatest bool +} + +// MakeConcrete replaces the contents of this spec with one that +// matches the given concrete version (without checking latest +// from the server). +func (s *Spec) MakeConcrete(ver Concrete) { + s.Selector = ver + s.CheckLatest = false +} + +// AsConcrete returns the underlying selector as a concrete version, if +// possible. +func (s Spec) AsConcrete() *Concrete { + return s.Selector.AsConcrete() +} + +// Matches checks if the underlying selector matches the given version. +func (s Spec) Matches(ver Concrete) bool { + return s.Selector.Matches(ver) +} + +func (s Spec) String() string { + res := s.Selector.String() + if s.CheckLatest { + res += "!" + } + return res +} + +// PointVersion represents a wildcard (patch) version +// or concrete number. +type PointVersion int + +const ( + // AnyPoint matches any point version. + AnyPoint PointVersion = -1 +) + +// Matches checks if a point version is compatible +// with a concrete point version. +// Two point versions are compatible if they are +// a) both concrete +// b) one is a wildcard. +func (p PointVersion) Matches(other int) bool { + switch p { + case AnyPoint: + return true + default: + return int(p) == other + } +} +func (p PointVersion) String() string { + switch p { + case AnyPoint: + return "*" + default: + return strconv.Itoa(int(p)) + } +} + +var ( + // LatestVersion matches the most recent version on the remote server. + LatestVersion = Spec{ + Selector: AnySelector{}, + CheckLatest: true, + } + // AnyVersion matches any local or remote version. + AnyVersion = Spec{ + Selector: AnySelector{}, + } +) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/versions_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/versions_suite_test.go new file mode 100644 index 00000000000..db1fe76403a --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/versions_suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package versions_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestVersions(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Versions Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go new file mode 100644 index 00000000000..fdabd995ae7 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package workflows + +import ( + "context" + "io" + + "github.com/go-logr/logr" + + envp "sigs.k8s.io/controller-runtime/tools/setup-envtest/env" +) + +// Use is a workflow that prints out information about stored +// version-platform pairs, downloading them if necessary & requested. +type Use struct { + UseEnv bool + AssetsPath string + PrintFormat envp.PrintFormat +} + +// Do executes this workflow. +func (f Use) Do(env *envp.Env) { + ctx := logr.NewContext(context.TODO(), env.Log.WithName("use")) + env.EnsureBaseDirs(ctx) + if f.UseEnv { + // the env var unconditionally + if env.PathMatches(f.AssetsPath) { + env.PrintInfo(f.PrintFormat) + return + } + } + env.EnsureVersionIsSet(ctx) + if env.ExistsAndValid() { + env.PrintInfo(f.PrintFormat) + return + } + if env.NoDownload { + envp.Exit(2, "no such version (%s) exists on disk for this architecture (%s) -- try running `list -i` to see what's on disk", env.Version, env.Platform) + } + env.Fetch(ctx) + env.PrintInfo(f.PrintFormat) +} + +// List is a workflow that lists version-platform pairs in the store +// and on the remote server that match the given filter. +type List struct{} + +// Do executes this workflow. +func (List) Do(env *envp.Env) { + ctx := logr.NewContext(context.TODO(), env.Log.WithName("list")) + env.EnsureBaseDirs(ctx) + env.ListVersions(ctx) +} + +// Cleanup is a workflow that removes version-platform pairs from the store +// that match the given filter. +type Cleanup struct{} + +// Do executes this workflow. +func (Cleanup) Do(env *envp.Env) { + ctx := logr.NewContext(context.TODO(), env.Log.WithName("cleanup")) + + env.NoDownload = true + env.ForceDownload = false + + env.EnsureBaseDirs(ctx) + env.Remove(ctx) +} + +// Sideload is a workflow that adds or replaces a version-platform pair in the +// store, using the given archive as the files. +type Sideload struct { + Input io.Reader + PrintFormat envp.PrintFormat +} + +// Do executes this workflow. +func (f Sideload) Do(env *envp.Env) { + ctx := logr.NewContext(context.TODO(), env.Log.WithName("sideload")) + + env.EnsureBaseDirs(ctx) + env.NoDownload = true + env.Sideload(ctx, f.Input) + env.PrintInfo(f.PrintFormat) +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_suite_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_suite_test.go new file mode 100644 index 00000000000..1b487622bde --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_suite_test.go @@ -0,0 +1,46 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package workflows_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var testLog logr.Logger + +func zapLogger() logr.Logger { + testOut := zapcore.AddSync(GinkgoWriter) + enc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) + // bleh setting up logging to the ginkgo writer is annoying + zapLog := zap.New(zapcore.NewCore(enc, testOut, zap.DebugLevel), + zap.ErrorOutput(testOut), zap.Development(), zap.AddStacktrace(zap.WarnLevel)) + return zapr.NewLogger(zapLog) +} + +func TestWorkflows(t *testing.T) { + testLog = zapLogger() + RegisterFailHandler(Fail) + RunSpecs(t, "Workflows Suite") +} diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_test.go new file mode 100644 index 00000000000..a0bd7321f79 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_test.go @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package workflows_test + +import ( + "bytes" + "io/fs" + "path/filepath" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/ghttp" + "github.com/spf13/afero" + + envp "sigs.k8s.io/controller-runtime/tools/setup-envtest/env" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/remote" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/store" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" + wf "sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows" +) + +func ver(major, minor, patch int) versions.Concrete { + return versions.Concrete{ + Major: major, + Minor: minor, + Patch: patch, + } +} + +func shouldHaveError() { + var err error + var code int + if cause := recover(); envp.CheckRecover(cause, func(caughtCode int, caughtErr error) { + err = caughtErr + code = caughtCode + }) { + panic(cause) + } + Expect(err).To(HaveOccurred(), "should write an error") + Expect(code).NotTo(BeZero(), "should exit with a non-zero code") +} + +const ( + testStorePath = ".teststore" +) + +var _ = Describe("Workflows", func() { + var ( + env *envp.Env + out *bytes.Buffer + server *ghttp.Server + remoteItems []item + ) + BeforeEach(func() { + out = new(bytes.Buffer) + baseFs := afero.Afero{Fs: afero.NewMemMapFs()} + env = &envp.Env{ + Log: testLog, + VerifySum: true, // on by default + FS: baseFs, + Store: &store.Store{Root: afero.NewBasePathFs(baseFs, testStorePath)}, + Out: out, + Platform: versions.PlatformItem{ // default + Platform: versions.Platform{ + OS: "linux", + Arch: "amd64", + }, + }, + Client: &remote.Client{ + Log: testLog.WithName("remote-client"), + Bucket: "kubebuilder-tools-test", // test custom bucket functionality too + Server: "localhost:-1", + Insecure: true, // no https in httptest :-( + }, + } + server = ghttp.NewServer() + env.Client.Server = server.Addr() + + fakeStore(env.FS, testStorePath) + remoteItems = remoteVersions + }) + JustBeforeEach(func() { + handleRemoteVersions(server, remoteItems) + }) + AfterEach(func() { + server.Close() + server = nil + }) + + Describe("use", func() { + var flow wf.Use + BeforeEach(func() { + // some defaults for most tests + env.Version = versions.Spec{ + Selector: ver(1, 16, 0), + } + flow = wf.Use{ + PrintFormat: envp.PrintPath, + } + }) + + It("should initialize the store if it doesn't exist", func() { + Expect(env.FS.RemoveAll(testStorePath)).To(Succeed()) + // need to set this to a valid remote version cause our store is now empty + env.Version = versions.Spec{Selector: ver(1, 16, 4)} + flow.Do(env) + Expect(env.FS.Stat(testStorePath)).NotTo(BeNil()) + }) + + Context("when use env is set", func() { + BeforeEach(func() { + flow.UseEnv = true + }) + It("should fall back to normal behavior when the env is not set", func() { + flow.Do(env) + Expect(out.String()).To(HaveSuffix("/1.16.0-linux-amd64"), "should fall back to a local version") + }) + It("should fall back to normal behavior if binaries are missing", func() { + flow.AssetsPath = ".teststore/missing-binaries" + flow.Do(env) + Expect(out.String()).To(HaveSuffix("/1.16.0-linux-amd64"), "should fall back to a local version") + }) + It("should use the value of the env if it contains the right binaries", func() { + flow.AssetsPath = ".teststore/good-version" + flow.Do(env) + Expect(out.String()).To(Equal(flow.AssetsPath)) + }) + It("should not try and check the version of the binaries", func() { + flow.AssetsPath = ".teststore/wrong-version" + flow.Do(env) + Expect(out.String()).To(Equal(flow.AssetsPath)) + }) + It("should not need to contact the network", func() { + server.Close() + flow.AssetsPath = ".teststore/good-version" + flow.Do(env) + // expect to not get a panic -- if we do, it'll cause the test to fail + }) + }) + + Context("when downloads are disabled", func() { + BeforeEach(func() { + env.NoDownload = true + server.Close() + }) + + // It("should not contact the network") is a gimme here, because we + // call server.Close() above. + + It("should error if no matches are found locally", func() { + defer shouldHaveError() + env.Version.Selector = versions.Concrete{Major: 9001} + flow.Do(env) + }) + It("should settle for the latest local match if latest is requested", func() { + env.Version = versions.Spec{ + CheckLatest: true, + Selector: versions.PatchSelector{ + Major: 1, + Minor: 16, + Patch: versions.AnyPoint, + }, + } + + flow.Do(env) + + // latest on "server" is 1.16.4, shouldn't use that + Expect(out.String()).To(HaveSuffix("/1.16.1-linux-amd64"), "should use the latest local version") + }) + }) + + Context("if latest is requested", func() { + It("should contact the network to see if there's anything newer", func() { + env.Version = versions.Spec{ + CheckLatest: true, + Selector: versions.PatchSelector{ + Major: 1, Minor: 16, Patch: versions.AnyPoint, + }, + } + flow.Do(env) + Expect(out.String()).To(HaveSuffix("/1.16.4-linux-amd64"), "should use the latest remote version") + }) + It("should still use the latest local if the network doesn't have anything newer", func() { + env.Version = versions.Spec{ + CheckLatest: true, + Selector: versions.PatchSelector{ + Major: 1, Minor: 14, Patch: versions.AnyPoint, + }, + } + + flow.Do(env) + + // latest on the server is 1.14.1, latest local is 1.14.26 + Expect(out.String()).To(HaveSuffix("/1.14.26-linux-amd64"), "should use the latest local version") + }) + }) + + It("should check local for a match first", func() { + server.Close() // confirm no network + env.Version = versions.Spec{ + Selector: versions.TildeSelector{Concrete: ver(1, 16, 0)}, + } + flow.Do(env) + // latest on the server is 1.16.4, latest local is 1.16.1 + Expect(out.String()).To(HaveSuffix("/1.16.1-linux-amd64"), "should use the latest local version") + }) + + It("should fall back to the network if no local matches are found", func() { + env.Version = versions.Spec{ + Selector: versions.TildeSelector{Concrete: ver(1, 19, 0)}, + } + flow.Do(env) + Expect(out.String()).To(HaveSuffix("/1.19.2-linux-amd64"), "should have a remote version") + }) + + It("should error out if no matches can be found anywhere", func() { + defer shouldHaveError() + env.Version = versions.Spec{ + Selector: versions.TildeSelector{Concrete: ver(0, 0, 1)}, + } + flow.Do(env) + }) + + It("should skip local versions matches with non-matching platforms", func() { + env.NoDownload = true // so we get an error + defer shouldHaveError() + env.Version = versions.Spec{ + // has non-matching local versions + Selector: ver(1, 13, 0), + } + + flow.Do(env) + }) + + It("should skip remote version matches with non-matching platforms", func() { + defer shouldHaveError() + env.Version = versions.Spec{ + // has a non-matching remote version + Selector: versions.TildeSelector{Concrete: ver(1, 11, 1)}, + } + flow.Do(env) + }) + + Describe("verifying the checksum", func() { + BeforeEach(func() { + remoteItems = append(remoteItems, item{ + meta: bucketObject{ + Name: "kubebuilder-tools-86.75.309-linux-amd64.tar.gz", + Hash: "nottherightone!", + }, + contents: remoteItems[0].contents, // need a valid tar.gz file to not error from that + }) + env.Version = versions.Spec{ + Selector: ver(86, 75, 309), + } + }) + Specify("when enabled, should fail if the downloaded md5 checksum doesn't match", func() { + defer shouldHaveError() + flow.Do(env) + }) + Specify("when disabled, shouldn't check the checksum at all", func() { + env.VerifySum = false + flow.Do(env) + }) + }) + }) + + Describe("list", func() { + // split by fields so we're not matching on whitespace + listFields := func() [][]string { + resLines := strings.Split(strings.TrimSpace(out.String()), "\n") + resFields := make([][]string, len(resLines)) + for i, line := range resLines { + resFields[i] = strings.Fields(line) + } + return resFields + } + + Context("when downloads are disabled", func() { + BeforeEach(func() { + server.Close() // ensure no network + env.NoDownload = true + }) + It("should include local contents sorted by version", func() { + env.Version = versions.AnyVersion + env.Platform.Platform = versions.Platform{OS: "*", Arch: "*"} + wf.List{}.Do(env) + + Expect(listFields()).To(Equal([][]string{ + {"(installed)", "v1.17.9", "linux/amd64"}, + {"(installed)", "v1.16.2", "ifonlysingularitywasstillathing/amd64"}, + {"(installed)", "v1.16.2", "linux/yourimagination"}, + {"(installed)", "v1.16.1", "linux/amd64"}, + {"(installed)", "v1.16.0", "linux/amd64"}, + {"(installed)", "v1.14.26", "hyperwarp/pixiedust"}, + {"(installed)", "v1.14.26", "linux/amd64"}, + })) + }) + It("should skip non-matching local contents", func() { + env.Version.Selector = versions.PatchSelector{ + Major: 1, Minor: 16, Patch: versions.AnyPoint, + } + env.Platform.Arch = "*" + wf.List{}.Do(env) + + Expect(listFields()).To(Equal([][]string{ + {"(installed)", "v1.16.2", "linux/yourimagination"}, + {"(installed)", "v1.16.1", "linux/amd64"}, + {"(installed)", "v1.16.0", "linux/amd64"}, + })) + + }) + }) + Context("when downloads are enabled", func() { + Context("when sorting", func() { + BeforeEach(func() { + // shorten the list a bit for expediency + remoteItems = remoteItems[:7] + }) + It("should sort local & remote by version", func() { + env.Version = versions.AnyVersion + env.Platform.Platform = versions.Platform{OS: "*", Arch: "*"} + wf.List{}.Do(env) + + Expect(listFields()).To(Equal([][]string{ + {"(installed)", "v1.17.9", "linux/amd64"}, + {"(installed)", "v1.16.2", "ifonlysingularitywasstillathing/amd64"}, + {"(installed)", "v1.16.2", "linux/yourimagination"}, + {"(installed)", "v1.16.1", "linux/amd64"}, + {"(installed)", "v1.16.0", "linux/amd64"}, + {"(installed)", "v1.14.26", "hyperwarp/pixiedust"}, + {"(installed)", "v1.14.26", "linux/amd64"}, + {"(available)", "v1.11.1", "potato/cherrypie"}, + {"(available)", "v1.11.0", "darwin/amd64"}, + {"(available)", "v1.11.0", "linux/amd64"}, + {"(available)", "v1.10.1", "darwin/amd64"}, + {"(available)", "v1.10.1", "linux/amd64"}, + })) + + }) + }) + It("should skip non-matching remote contents", func() { + env.Version.Selector = versions.PatchSelector{ + Major: 1, Minor: 16, Patch: versions.AnyPoint, + } + env.Platform.Arch = "*" + wf.List{}.Do(env) + + Expect(listFields()).To(Equal([][]string{ + {"(installed)", "v1.16.2", "linux/yourimagination"}, + {"(installed)", "v1.16.1", "linux/amd64"}, + {"(installed)", "v1.16.0", "linux/amd64"}, + {"(available)", "v1.16.4", "linux/amd64"}, + })) + + }) + }) + }) + + Describe("cleanup", func() { + BeforeEach(func() { + server.Close() // ensure no network + flow := wf.Cleanup{} + env.Version = versions.AnyVersion + env.Platform.Arch = "*" + flow.Do(env) + }) + + It("should remove matching versions from the store & keep non-matching ones", func() { + entries, err := env.FS.ReadDir(".teststore/k8s") + Expect(err).NotTo(HaveOccurred(), "should be able to read the store") + Expect(entries).To(ConsistOf( + WithTransform(fs.FileInfo.Name, Equal("1.16.2-ifonlysingularitywasstillathing-amd64")), + WithTransform(fs.FileInfo.Name, Equal("1.14.26-hyperwarp-pixiedust")), + )) + }) + }) + + Describe("sideload", func() { + var ( + flow wf.Sideload + // remote version fake contents are prefixed by the + // name for easier debugging, so we can use that here + expectedPrefix = remoteVersions[0].meta.Name + ) + BeforeEach(func() { + server.Close() // ensure no network + flow.Input = bytes.NewReader(remoteVersions[0].contents) + flow.PrintFormat = envp.PrintPath + }) + It("should initialize the store if it doesn't exist", func() { + env.Version.Selector = ver(1, 10, 0) + Expect(env.FS.RemoveAll(testStorePath)).To(Succeed()) + flow.Do(env) + Expect(env.FS.Stat(testStorePath)).NotTo(BeNil()) + }) + It("should fail if a non-concrete version is given", func() { + defer shouldHaveError() + env.Version = versions.LatestVersion + flow.Do(env) + }) + It("should fail if a non-concrete platform is given", func() { + defer shouldHaveError() + env.Version.Selector = ver(1, 10, 0) + env.Platform.Arch = "*" + flow.Do(env) + }) + It("should load the given gizipped tarball into our store as the given version", func() { + env.Version.Selector = ver(1, 10, 0) + flow.Do(env) + baseName := env.Platform.BaseName(*env.Version.AsConcrete()) + expectedPath := filepath.Join(".teststore/k8s", baseName, "some-file") + outContents, err := env.FS.ReadFile(expectedPath) + Expect(err).NotTo(HaveOccurred(), "should be able to load the unzipped file") + Expect(string(outContents)).To(HavePrefix(expectedPrefix), "should have the debugging prefix") + }) + }) +}) diff --git a/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_testutils_test.go b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_testutils_test.go new file mode 100644 index 00000000000..f236ce460e4 --- /dev/null +++ b/third_party/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows_testutils_test.go @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2021 The Kubernetes Authors + +package workflows_test + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto/md5" //nolint:gosec + "crypto/rand" + "encoding/base64" + "net/http" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/ghttp" + "github.com/spf13/afero" + + "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" +) + +var ( + remoteNames = []string{ + "kubebuilder-tools-1.10-darwin-amd64.tar.gz", + "kubebuilder-tools-1.10-linux-amd64.tar.gz", + "kubebuilder-tools-1.10.1-darwin-amd64.tar.gz", + "kubebuilder-tools-1.10.1-linux-amd64.tar.gz", + "kubebuilder-tools-1.11.0-darwin-amd64.tar.gz", + "kubebuilder-tools-1.11.0-linux-amd64.tar.gz", + "kubebuilder-tools-1.11.1-potato-cherrypie.tar.gz", + "kubebuilder-tools-1.12.3-darwin-amd64.tar.gz", + "kubebuilder-tools-1.12.3-linux-amd64.tar.gz", + "kubebuilder-tools-1.13.1-darwin-amd64.tar.gz", + "kubebuilder-tools-1.13.1-linux-amd64.tar.gz", + "kubebuilder-tools-1.14.1-darwin-amd64.tar.gz", + "kubebuilder-tools-1.14.1-linux-amd64.tar.gz", + "kubebuilder-tools-1.15.5-darwin-amd64.tar.gz", + "kubebuilder-tools-1.15.5-linux-amd64.tar.gz", + "kubebuilder-tools-1.16.4-darwin-amd64.tar.gz", + "kubebuilder-tools-1.16.4-linux-amd64.tar.gz", + "kubebuilder-tools-1.17.9-darwin-amd64.tar.gz", + "kubebuilder-tools-1.17.9-linux-amd64.tar.gz", + "kubebuilder-tools-1.19.0-darwin-amd64.tar.gz", + "kubebuilder-tools-1.19.0-linux-amd64.tar.gz", + "kubebuilder-tools-1.19.2-darwin-amd64.tar.gz", + "kubebuilder-tools-1.19.2-linux-amd64.tar.gz", + "kubebuilder-tools-1.19.2-linux-arm64.tar.gz", + "kubebuilder-tools-1.19.2-linux-ppc64le.tar.gz", + "kubebuilder-tools-1.20.2-darwin-amd64.tar.gz", + "kubebuilder-tools-1.20.2-linux-amd64.tar.gz", + "kubebuilder-tools-1.20.2-linux-arm64.tar.gz", + "kubebuilder-tools-1.20.2-linux-ppc64le.tar.gz", + "kubebuilder-tools-1.9-darwin-amd64.tar.gz", + "kubebuilder-tools-1.9-linux-amd64.tar.gz", + "kubebuilder-tools-v1.19.2-darwin-amd64.tar.gz", + "kubebuilder-tools-v1.19.2-linux-amd64.tar.gz", + "kubebuilder-tools-v1.19.2-linux-arm64.tar.gz", + "kubebuilder-tools-v1.19.2-linux-ppc64le.tar.gz", + } + + remoteVersions = makeContents(remoteNames) + + // keep this sorted. + localVersions = []versions.Set{ + {Version: ver(1, 17, 9), Platforms: []versions.PlatformItem{ + {Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + }}, + {Version: ver(1, 16, 2), Platforms: []versions.PlatformItem{ + {Platform: versions.Platform{OS: "linux", Arch: "yourimagination"}}, + {Platform: versions.Platform{OS: "ifonlysingularitywasstillathing", Arch: "amd64"}}, + }}, + {Version: ver(1, 16, 1), Platforms: []versions.PlatformItem{ + {Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + }}, + {Version: ver(1, 16, 0), Platforms: []versions.PlatformItem{ + {Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + }}, + {Version: ver(1, 14, 26), Platforms: []versions.PlatformItem{ + {Platform: versions.Platform{OS: "linux", Arch: "amd64"}}, + {Platform: versions.Platform{OS: "hyperwarp", Arch: "pixiedust"}}, + }}, + } +) + +type item struct { + meta bucketObject + contents []byte +} + +// objectList is the parts we need of the GCS "list-objects-in-bucket" endpoint. +type objectList struct { + Items []bucketObject `json:"items"` +} + +// bucketObject is the parts we need of the GCS object metadata. +type bucketObject struct { + Name string `json:"name"` + Hash string `json:"md5Hash"` +} + +func makeContents(names []string) []item { + res := make([]item, len(names)) + for i, name := range names { + var chunk [1024 * 48]byte // 1.5 times our chunk read size in GetVersion + copy(chunk[:], name) + if _, err := rand.Read(chunk[len(name):]); err != nil { + panic(err) + } + res[i] = verWith(name, chunk[:]) + } + return res +} + +func verWith(name string, contents []byte) item { + out := new(bytes.Buffer) + gzipWriter := gzip.NewWriter(out) + tarWriter := tar.NewWriter(gzipWriter) + err := tarWriter.WriteHeader(&tar.Header{ + Name: "kubebuilder/bin/some-file", + Size: int64(len(contents)), + Mode: 0777, // so we can check that we fix this later + }) + if err != nil { + panic(err) + } + _, err = tarWriter.Write(contents) + if err != nil { + panic(err) + } + tarWriter.Close() + gzipWriter.Close() + res := item{ + meta: bucketObject{Name: name}, + contents: out.Bytes(), + } + hash := md5.Sum(res.contents) //nolint:gosec + res.meta.Hash = base64.StdEncoding.EncodeToString(hash[:]) + return res +} + +func handleRemoteVersions(server *ghttp.Server, versions []item) { + list := objectList{Items: make([]bucketObject, len(versions))} + for i, ver := range versions { + ver := ver // copy to avoid capturing the iteration variable + list.Items[i] = ver.meta + server.RouteToHandler("GET", "/storage/v1/b/kubebuilder-tools-test/o/"+ver.meta.Name, func(resp http.ResponseWriter, req *http.Request) { + if req.URL.Query().Get("alt") == "media" { + resp.WriteHeader(http.StatusOK) + Expect(resp.Write(ver.contents)).To(Equal(len(ver.contents))) + } else { + ghttp.RespondWithJSONEncoded( + http.StatusOK, + ver.meta, + )(resp, req) + } + }) + } + server.RouteToHandler("GET", "/storage/v1/b/kubebuilder-tools-test/o", ghttp.RespondWithJSONEncoded( + http.StatusOK, + list, + )) +} + +func fakeStore(fs afero.Afero, dir string) { + By("making the unpacked directory") + unpackedBase := filepath.Join(dir, "k8s") + Expect(fs.Mkdir(unpackedBase, 0755)).To(Succeed()) + + By("making some fake (empty) versions") + for _, set := range localVersions { + for _, plat := range set.Platforms { + Expect(fs.Mkdir(filepath.Join(unpackedBase, plat.BaseName(set.Version)), 0755)).To(Succeed()) + } + } + + By("making some fake non-store paths") + Expect(fs.Mkdir(filepath.Join(dir, "missing-binaries"), 0755)) + + Expect(fs.Mkdir(filepath.Join(dir, "wrong-version"), 0755)) + Expect(fs.WriteFile(filepath.Join(dir, "wrong-version", "kube-apiserver"), nil, 0755)).To(Succeed()) + Expect(fs.WriteFile(filepath.Join(dir, "wrong-version", "kubectl"), nil, 0755)).To(Succeed()) + Expect(fs.WriteFile(filepath.Join(dir, "wrong-version", "etcd"), nil, 0755)).To(Succeed()) + + Expect(fs.Mkdir(filepath.Join(dir, "good-version"), 0755)) + Expect(fs.WriteFile(filepath.Join(dir, "good-version", "kube-apiserver"), nil, 0755)).To(Succeed()) + Expect(fs.WriteFile(filepath.Join(dir, "good-version", "kubectl"), nil, 0755)).To(Succeed()) + Expect(fs.WriteFile(filepath.Join(dir, "good-version", "etcd"), nil, 0755)).To(Succeed()) + // TODO: put the right files +} diff --git a/vendor/cloud.google.com/go/compute/internal/version.go b/vendor/cloud.google.com/go/compute/internal/version.go new file mode 100644 index 00000000000..b1672963f6c --- /dev/null +++ b/vendor/cloud.google.com/go/compute/internal/version.go @@ -0,0 +1,18 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +// Version is the current tagged release of the library. +const Version = "1.21.0" diff --git a/vendor/cloud.google.com/go/compute/metadata/CHANGES.md b/vendor/cloud.google.com/go/compute/metadata/CHANGES.md new file mode 100644 index 00000000000..06b957349af --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/CHANGES.md @@ -0,0 +1,19 @@ +# Changes + +## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.2...compute/metadata/v0.2.3) (2022-12-15) + + +### Bug Fixes + +* **compute/metadata:** Switch DNS lookup to an absolute lookup ([119b410](https://github.com/googleapis/google-cloud-go/commit/119b41060c7895e45e48aee5621ad35607c4d021)), refs [#7165](https://github.com/googleapis/google-cloud-go/issues/7165) + +## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.1...compute/metadata/v0.2.2) (2022-12-01) + + +### Bug Fixes + +* **compute/metadata:** Set IdleConnTimeout for http.Client ([#7084](https://github.com/googleapis/google-cloud-go/issues/7084)) ([766516a](https://github.com/googleapis/google-cloud-go/commit/766516aaf3816bfb3159efeea65aa3d1d205a3e2)), refs [#5430](https://github.com/googleapis/google-cloud-go/issues/5430) + +## [0.1.0] (2022-10-26) + +Initial release of metadata being it's own module. diff --git a/vendor/cloud.google.com/go/compute/metadata/LICENSE b/vendor/cloud.google.com/go/compute/metadata/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/cloud.google.com/go/compute/metadata/README.md b/vendor/cloud.google.com/go/compute/metadata/README.md new file mode 100644 index 00000000000..f940fb2c85b --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/README.md @@ -0,0 +1,27 @@ +# Compute API + +[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/compute.svg)](https://pkg.go.dev/cloud.google.com/go/compute/metadata) + +This is a utility library for communicating with Google Cloud metadata service +on Google Cloud. + +## Install + +```bash +go get cloud.google.com/go/compute/metadata +``` + +## Go Version Support + +See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported) +section in the root directory's README. + +## Contributing + +Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md) +document for details. + +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. See +[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct) +for more information. diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index 111309f3d8b..c17faa142a4 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -16,7 +16,7 @@ // metadata and API service accounts. // // This package is a wrapper around the GCE metadata service, -// as documented at https://developers.google.com/compute/docs/metadata. +// as documented at https://cloud.google.com/compute/docs/metadata/overview. package metadata // import "cloud.google.com/go/compute/metadata" import ( @@ -70,7 +70,9 @@ func newDefaultHTTPClient() *http.Client { Timeout: 2 * time.Second, KeepAlive: 30 * time.Second, }).Dial, + IdleConnTimeout: 60 * time.Second, }, + Timeout: 5 * time.Second, } } @@ -145,7 +147,7 @@ func testOnGCE() bool { go func() { resolver := &net.Resolver{} - addrs, err := resolver.LookupHost(ctx, "metadata.google.internal") + addrs, err := resolver.LookupHost(ctx, "metadata.google.internal.") if err != nil || len(addrs) == 0 { resc <- false return diff --git a/vendor/cloud.google.com/go/compute/metadata/tidyfix.go b/vendor/cloud.google.com/go/compute/metadata/tidyfix.go new file mode 100644 index 00000000000..4cef4850081 --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/tidyfix.go @@ -0,0 +1,23 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file, and the {{.RootMod}} import, won't actually become part of +// the resultant binary. +//go:build modhack +// +build modhack + +package metadata + +// Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository +import _ "cloud.google.com/go/compute/internal" diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/alert_policy_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/alert_policy_client.go index 813b9deae35..84496844a2d 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/alert_policy_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/alert_policy_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -61,6 +61,7 @@ func defaultAlertPolicyGRPCClientOptions() []option.ClientOption { func defaultAlertPolicyCallOptions() *AlertPolicyCallOptions { return &AlertPolicyCallOptions{ ListAlertPolicies: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -72,6 +73,7 @@ func defaultAlertPolicyCallOptions() *AlertPolicyCallOptions { }), }, GetAlertPolicy: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -82,8 +84,11 @@ func defaultAlertPolicyCallOptions() *AlertPolicyCallOptions { }) }), }, - CreateAlertPolicy: []gax.CallOption{}, + CreateAlertPolicy: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, DeleteAlertPolicy: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -94,11 +99,13 @@ func defaultAlertPolicyCallOptions() *AlertPolicyCallOptions { }) }), }, - UpdateAlertPolicy: []gax.CallOption{}, + UpdateAlertPolicy: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, } } -// internalAlertPolicyClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalAlertPolicyClient is an interface that defines the methods available from Cloud Monitoring API. type internalAlertPolicyClient interface { Close() error setGoogleClientInfo(...string) @@ -114,14 +121,14 @@ type internalAlertPolicyClient interface { // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. // // The AlertPolicyService API is used to manage (list, create, delete, -// edit) alert policies in Stackdriver Monitoring. An alerting policy is +// edit) alert policies in Cloud Monitoring. An alerting policy is // a description of the conditions under which some aspect of your // system is considered to be “unhealthy” and the ways to notify // people or services about this state. In addition to using this API, alert // policies can also be managed through -// Stackdriver Monitoring (at https://cloud.google.com/monitoring/docs/), +// Cloud Monitoring (at https://cloud.google.com/monitoring/docs/), // which can be reached by clicking the “Monitoring” tab in -// Cloud Console (at https://console.cloud.google.com/). +// Cloud console (at https://console.cloud.google.com/). type AlertPolicyClient struct { // The internal transport-dependent client. internalClient internalAlertPolicyClient @@ -147,7 +154,8 @@ func (c *AlertPolicyClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *AlertPolicyClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -187,9 +195,6 @@ type alertPolicyGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing AlertPolicyClient CallOptions **AlertPolicyCallOptions @@ -204,14 +209,14 @@ type alertPolicyGRPCClient struct { // The returned client must be Closed when it is done being used to clean up its underlying connections. // // The AlertPolicyService API is used to manage (list, create, delete, -// edit) alert policies in Stackdriver Monitoring. An alerting policy is +// edit) alert policies in Cloud Monitoring. An alerting policy is // a description of the conditions under which some aspect of your // system is considered to be “unhealthy” and the ways to notify // people or services about this state. In addition to using this API, alert // policies can also be managed through -// Stackdriver Monitoring (at https://cloud.google.com/monitoring/docs/), +// Cloud Monitoring (at https://cloud.google.com/monitoring/docs/), // which can be reached by clicking the “Monitoring” tab in -// Cloud Console (at https://console.cloud.google.com/). +// Cloud console (at https://console.cloud.google.com/). func NewAlertPolicyClient(ctx context.Context, opts ...option.ClientOption) (*AlertPolicyClient, error) { clientOpts := defaultAlertPolicyGRPCClientOptions() if newAlertPolicyClientHook != nil { @@ -222,11 +227,6 @@ func NewAlertPolicyClient(ctx context.Context, opts ...option.ClientOption) (*Al clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -235,7 +235,6 @@ func NewAlertPolicyClient(ctx context.Context, opts ...option.ClientOption) (*Al c := &alertPolicyGRPCClient{ connPool: connPool, - disableDeadlines: disableDeadlines, alertPolicyClient: monitoringpb.NewAlertPolicyServiceClient(connPool), CallOptions: &client.CallOptions, } @@ -248,7 +247,8 @@ func NewAlertPolicyClient(ctx context.Context, opts ...option.ClientOption) (*Al // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *alertPolicyGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -257,7 +257,7 @@ func (c *alertPolicyGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *alertPolicyGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -314,11 +314,6 @@ func (c *alertPolicyGRPCClient) ListAlertPolicies(ctx context.Context, req *moni } func (c *alertPolicyGRPCClient) GetAlertPolicy(ctx context.Context, req *monitoringpb.GetAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -336,11 +331,6 @@ func (c *alertPolicyGRPCClient) GetAlertPolicy(ctx context.Context, req *monitor } func (c *alertPolicyGRPCClient) CreateAlertPolicy(ctx context.Context, req *monitoringpb.CreateAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -358,11 +348,6 @@ func (c *alertPolicyGRPCClient) CreateAlertPolicy(ctx context.Context, req *moni } func (c *alertPolicyGRPCClient) DeleteAlertPolicy(ctx context.Context, req *monitoringpb.DeleteAlertPolicyRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -376,11 +361,6 @@ func (c *alertPolicyGRPCClient) DeleteAlertPolicy(ctx context.Context, req *moni } func (c *alertPolicyGRPCClient) UpdateAlertPolicy(ctx context.Context, req *monitoringpb.UpdateAlertPolicyRequest, opts ...gax.CallOption) (*monitoringpb.AlertPolicy, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "alert_policy.name", url.QueryEscape(req.GetAlertPolicy().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/doc.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/doc.go index 8844a492f92..63c5feb8bf2 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/doc.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/doc.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,67 +19,80 @@ // // Manages your Cloud Monitoring data and configurations. // -// Example usage +// # General documentation +// +// For information about setting deadlines, reusing contexts, and more +// please visit https://pkg.go.dev/cloud.google.com/go. +// +// # Example usage // // To get started with this package, create a client. -// ctx := context.Background() -// c, err := monitoring.NewAlertPolicyClient(ctx) -// if err != nil { -// // TODO: Handle error. -// } -// defer c.Close() +// +// ctx := context.Background() +// // This snippet has been automatically generated and should be regarded as a code template only. +// // It will require modifications to work: +// // - It may require correct/in-range values for request initialization. +// // - It may require specifying regional endpoints when creating the service client as shown in: +// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options +// c, err := monitoring.NewAlertPolicyClient(ctx) +// if err != nil { +// // TODO: Handle error. +// } +// defer c.Close() // // The client will use your default application credentials. Clients should be reused instead of created as needed. // The methods of Client are safe for concurrent use by multiple goroutines. // The returned client must be Closed when it is done being used. // -// Using the Client +// # Using the Client // // The following is an example of making an API call with the newly created client. // -// ctx := context.Background() -// c, err := monitoring.NewAlertPolicyClient(ctx) -// if err != nil { -// // TODO: Handle error. -// } -// defer c.Close() -// -// req := &monitoringpb.ListAlertPoliciesRequest{ -// // TODO: Fill request struct fields. -// // See https://pkg.go.dev/google.golang.org/genproto/googleapis/monitoring/v3#ListAlertPoliciesRequest. -// } -// it := c.ListAlertPolicies(ctx, req) -// for { -// resp, err := it.Next() -// if err == iterator.Done { -// break -// } -// if err != nil { -// // TODO: Handle error. -// } -// // TODO: Use resp. -// _ = resp -// } -// -// Use of Context -// -// The ctx passed to NewClient is used for authentication requests and +// ctx := context.Background() +// // This snippet has been automatically generated and should be regarded as a code template only. +// // It will require modifications to work: +// // - It may require correct/in-range values for request initialization. +// // - It may require specifying regional endpoints when creating the service client as shown in: +// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options +// c, err := monitoring.NewAlertPolicyClient(ctx) +// if err != nil { +// // TODO: Handle error. +// } +// defer c.Close() +// +// req := &monitoringpb.ListAlertPoliciesRequest{ +// // TODO: Fill request struct fields. +// // See https://pkg.go.dev/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb#ListAlertPoliciesRequest. +// } +// it := c.ListAlertPolicies(ctx, req) +// for { +// resp, err := it.Next() +// if err == iterator.Done { +// break +// } +// if err != nil { +// // TODO: Handle error. +// } +// // TODO: Use resp. +// _ = resp +// } +// +// # Inspecting errors +// +// To see examples of how to inspect errors returned by this package please reference +// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors). +// +// # Use of Context +// +// The ctx passed to NewAlertPolicyClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. -// -// For information about setting deadlines, reusing contexts, and more -// please visit https://pkg.go.dev/cloud.google.com/go. package monitoring // import "cloud.google.com/go/monitoring/apiv3/v2" import ( "context" - "os" - "runtime" - "strconv" - "strings" - "unicode" "google.golang.org/api/option" "google.golang.org/grpc/metadata" @@ -110,16 +123,6 @@ func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { return metadata.NewOutgoingContext(ctx, out) } -func checkDisableDeadlines() (bool, error) { - raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE") - if !ok { - return false, nil - } - - b, err := strconv.ParseBool(raw) - return b, err -} - // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ @@ -129,40 +132,3 @@ func DefaultAuthScopes() []string { "https://www.googleapis.com/auth/monitoring.write", } } - -// versionGo returns the Go runtime version. The returned string -// has no whitespace, suitable for reporting in header. -func versionGo() string { - const develPrefix = "devel +" - - s := runtime.Version() - if strings.HasPrefix(s, develPrefix) { - s = s[len(develPrefix):] - if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { - s = s[:p] - } - return s - } - - notSemverRune := func(r rune) bool { - return !strings.ContainsRune("0123456789.", r) - } - - if strings.HasPrefix(s, "go1") { - s = s[2:] - var prerelease string - if p := strings.IndexFunc(s, notSemverRune); p >= 0 { - s, prerelease = s[:p], s[p:] - } - if strings.HasSuffix(s, ".") { - s += "0" - } else if strings.Count(s, ".") < 2 { - s += ".0" - } - if prerelease != "" { - s += "-" + prerelease - } - return s - } - return "UNKNOWN" -} diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/gapic_metadata.json b/vendor/cloud.google.com/go/monitoring/apiv3/v2/gapic_metadata.json index ad03f6ffbcf..a33cb6fcf53 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/gapic_metadata.json +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/gapic_metadata.json @@ -264,6 +264,35 @@ } } }, + "SnoozeService": { + "clients": { + "grpc": { + "libraryClient": "SnoozeClient", + "rpcs": { + "CreateSnooze": { + "methods": [ + "CreateSnooze" + ] + }, + "GetSnooze": { + "methods": [ + "GetSnooze" + ] + }, + "ListSnoozes": { + "methods": [ + "ListSnoozes" + ] + }, + "UpdateSnooze": { + "methods": [ + "UpdateSnooze" + ] + } + } + } + } + }, "UptimeCheckService": { "clients": { "grpc": { diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/group_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/group_client.go index d2a94a73f13..e754d57c7bb 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/group_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/group_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,13 +23,13 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -63,6 +63,7 @@ func defaultGroupGRPCClientOptions() []option.ClientOption { func defaultGroupCallOptions() *GroupCallOptions { return &GroupCallOptions{ ListGroups: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -74,6 +75,7 @@ func defaultGroupCallOptions() *GroupCallOptions { }), }, GetGroup: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -84,8 +86,11 @@ func defaultGroupCallOptions() *GroupCallOptions { }) }), }, - CreateGroup: []gax.CallOption{}, + CreateGroup: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, UpdateGroup: []gax.CallOption{ + gax.WithTimeout(180000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -97,6 +102,7 @@ func defaultGroupCallOptions() *GroupCallOptions { }), }, DeleteGroup: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -108,6 +114,7 @@ func defaultGroupCallOptions() *GroupCallOptions { }), }, ListGroupMembers: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -121,7 +128,7 @@ func defaultGroupCallOptions() *GroupCallOptions { } } -// internalGroupClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalGroupClient is an interface that defines the methods available from Cloud Monitoring API. type internalGroupClient interface { Close() error setGoogleClientInfo(...string) @@ -174,7 +181,8 @@ func (c *GroupClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *GroupClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -217,9 +225,6 @@ type groupGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing GroupClient CallOptions **GroupCallOptions @@ -255,11 +260,6 @@ func NewGroupClient(ctx context.Context, opts ...option.ClientOption) (*GroupCli clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -267,10 +267,9 @@ func NewGroupClient(ctx context.Context, opts ...option.ClientOption) (*GroupCli client := GroupClient{CallOptions: defaultGroupCallOptions()} c := &groupGRPCClient{ - connPool: connPool, - disableDeadlines: disableDeadlines, - groupClient: monitoringpb.NewGroupServiceClient(connPool), - CallOptions: &client.CallOptions, + connPool: connPool, + groupClient: monitoringpb.NewGroupServiceClient(connPool), + CallOptions: &client.CallOptions, } c.setGoogleClientInfo() @@ -281,7 +280,8 @@ func NewGroupClient(ctx context.Context, opts ...option.ClientOption) (*GroupCli // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *groupGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -290,7 +290,7 @@ func (c *groupGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *groupGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -347,11 +347,6 @@ func (c *groupGRPCClient) ListGroups(ctx context.Context, req *monitoringpb.List } func (c *groupGRPCClient) GetGroup(ctx context.Context, req *monitoringpb.GetGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -369,11 +364,6 @@ func (c *groupGRPCClient) GetGroup(ctx context.Context, req *monitoringpb.GetGro } func (c *groupGRPCClient) CreateGroup(ctx context.Context, req *monitoringpb.CreateGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -391,11 +381,6 @@ func (c *groupGRPCClient) CreateGroup(ctx context.Context, req *monitoringpb.Cre } func (c *groupGRPCClient) UpdateGroup(ctx context.Context, req *monitoringpb.UpdateGroupRequest, opts ...gax.CallOption) (*monitoringpb.Group, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 180000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "group.name", url.QueryEscape(req.GetGroup().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -413,11 +398,6 @@ func (c *groupGRPCClient) UpdateGroup(ctx context.Context, req *monitoringpb.Upd } func (c *groupGRPCClient) DeleteGroup(ctx context.Context, req *monitoringpb.DeleteGroupRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/metric_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/metric_client.go index 49e1a69e477..e702afd25d8 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/metric_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/metric_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" @@ -30,7 +31,6 @@ import ( gtransport "google.golang.org/api/transport/grpc" metricpb "google.golang.org/genproto/googleapis/api/metric" monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -67,6 +67,7 @@ func defaultMetricGRPCClientOptions() []option.ClientOption { func defaultMetricCallOptions() *MetricCallOptions { return &MetricCallOptions{ ListMonitoredResourceDescriptors: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -78,6 +79,7 @@ func defaultMetricCallOptions() *MetricCallOptions { }), }, GetMonitoredResourceDescriptor: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -89,6 +91,7 @@ func defaultMetricCallOptions() *MetricCallOptions { }), }, ListMetricDescriptors: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -100,6 +103,7 @@ func defaultMetricCallOptions() *MetricCallOptions { }), }, GetMetricDescriptor: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -110,8 +114,11 @@ func defaultMetricCallOptions() *MetricCallOptions { }) }), }, - CreateMetricDescriptor: []gax.CallOption{}, + CreateMetricDescriptor: []gax.CallOption{ + gax.WithTimeout(12000 * time.Millisecond), + }, DeleteMetricDescriptor: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -123,6 +130,7 @@ func defaultMetricCallOptions() *MetricCallOptions { }), }, ListTimeSeries: []gax.CallOption{ + gax.WithTimeout(90000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -133,12 +141,14 @@ func defaultMetricCallOptions() *MetricCallOptions { }) }), }, - CreateTimeSeries: []gax.CallOption{}, + CreateTimeSeries: []gax.CallOption{ + gax.WithTimeout(12000 * time.Millisecond), + }, CreateServiceTimeSeries: []gax.CallOption{}, } } -// internalMetricClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalMetricClient is an interface that defines the methods available from Cloud Monitoring API. type internalMetricClient interface { Close() error setGoogleClientInfo(...string) @@ -184,7 +194,8 @@ func (c *MetricClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *MetricClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -258,9 +269,6 @@ type metricGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing MetricClient CallOptions **MetricCallOptions @@ -286,11 +294,6 @@ func NewMetricClient(ctx context.Context, opts ...option.ClientOption) (*MetricC clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -298,10 +301,9 @@ func NewMetricClient(ctx context.Context, opts ...option.ClientOption) (*MetricC client := MetricClient{CallOptions: defaultMetricCallOptions()} c := &metricGRPCClient{ - connPool: connPool, - disableDeadlines: disableDeadlines, - metricClient: monitoringpb.NewMetricServiceClient(connPool), - CallOptions: &client.CallOptions, + connPool: connPool, + metricClient: monitoringpb.NewMetricServiceClient(connPool), + CallOptions: &client.CallOptions, } c.setGoogleClientInfo() @@ -312,7 +314,8 @@ func NewMetricClient(ctx context.Context, opts ...option.ClientOption) (*MetricC // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *metricGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -321,7 +324,7 @@ func (c *metricGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *metricGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -378,11 +381,6 @@ func (c *metricGRPCClient) ListMonitoredResourceDescriptors(ctx context.Context, } func (c *metricGRPCClient) GetMonitoredResourceDescriptor(ctx context.Context, req *monitoringpb.GetMonitoredResourceDescriptorRequest, opts ...gax.CallOption) (*monitoredrespb.MonitoredResourceDescriptor, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -445,11 +443,6 @@ func (c *metricGRPCClient) ListMetricDescriptors(ctx context.Context, req *monit } func (c *metricGRPCClient) GetMetricDescriptor(ctx context.Context, req *monitoringpb.GetMetricDescriptorRequest, opts ...gax.CallOption) (*metricpb.MetricDescriptor, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -467,11 +460,6 @@ func (c *metricGRPCClient) GetMetricDescriptor(ctx context.Context, req *monitor } func (c *metricGRPCClient) CreateMetricDescriptor(ctx context.Context, req *monitoringpb.CreateMetricDescriptorRequest, opts ...gax.CallOption) (*metricpb.MetricDescriptor, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 12000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -489,11 +477,6 @@ func (c *metricGRPCClient) CreateMetricDescriptor(ctx context.Context, req *moni } func (c *metricGRPCClient) DeleteMetricDescriptor(ctx context.Context, req *monitoringpb.DeleteMetricDescriptorRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -552,11 +535,6 @@ func (c *metricGRPCClient) ListTimeSeries(ctx context.Context, req *monitoringpb } func (c *metricGRPCClient) CreateTimeSeries(ctx context.Context, req *monitoringpb.CreateTimeSeriesRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 12000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert.pb.go similarity index 77% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert.pb.go index f413955f84d..845924be0f3 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert.pb.go @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/alert.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -102,6 +102,68 @@ func (AlertPolicy_ConditionCombinerType) EnumDescriptor() ([]byte, []int) { return file_google_monitoring_v3_alert_proto_rawDescGZIP(), []int{0, 0} } +// A condition control that determines how metric-threshold conditions +// are evaluated when data stops arriving. +// This control doesn't affect metric-absence policies. +type AlertPolicy_Condition_EvaluationMissingData int32 + +const ( + // An unspecified evaluation missing data option. Equivalent to + // EVALUATION_MISSING_DATA_NO_OP. + AlertPolicy_Condition_EVALUATION_MISSING_DATA_UNSPECIFIED AlertPolicy_Condition_EvaluationMissingData = 0 + // If there is no data to evaluate the condition, then evaluate the + // condition as false. + AlertPolicy_Condition_EVALUATION_MISSING_DATA_INACTIVE AlertPolicy_Condition_EvaluationMissingData = 1 + // If there is no data to evaluate the condition, then evaluate the + // condition as true. + AlertPolicy_Condition_EVALUATION_MISSING_DATA_ACTIVE AlertPolicy_Condition_EvaluationMissingData = 2 + // Do not evaluate the condition to any value if there is no data. + AlertPolicy_Condition_EVALUATION_MISSING_DATA_NO_OP AlertPolicy_Condition_EvaluationMissingData = 3 +) + +// Enum value maps for AlertPolicy_Condition_EvaluationMissingData. +var ( + AlertPolicy_Condition_EvaluationMissingData_name = map[int32]string{ + 0: "EVALUATION_MISSING_DATA_UNSPECIFIED", + 1: "EVALUATION_MISSING_DATA_INACTIVE", + 2: "EVALUATION_MISSING_DATA_ACTIVE", + 3: "EVALUATION_MISSING_DATA_NO_OP", + } + AlertPolicy_Condition_EvaluationMissingData_value = map[string]int32{ + "EVALUATION_MISSING_DATA_UNSPECIFIED": 0, + "EVALUATION_MISSING_DATA_INACTIVE": 1, + "EVALUATION_MISSING_DATA_ACTIVE": 2, + "EVALUATION_MISSING_DATA_NO_OP": 3, + } +) + +func (x AlertPolicy_Condition_EvaluationMissingData) Enum() *AlertPolicy_Condition_EvaluationMissingData { + p := new(AlertPolicy_Condition_EvaluationMissingData) + *p = x + return p +} + +func (x AlertPolicy_Condition_EvaluationMissingData) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AlertPolicy_Condition_EvaluationMissingData) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_alert_proto_enumTypes[1].Descriptor() +} + +func (AlertPolicy_Condition_EvaluationMissingData) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_alert_proto_enumTypes[1] +} + +func (x AlertPolicy_Condition_EvaluationMissingData) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AlertPolicy_Condition_EvaluationMissingData.Descriptor instead. +func (AlertPolicy_Condition_EvaluationMissingData) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_alert_proto_rawDescGZIP(), []int{0, 1, 0} +} + // A description of the conditions under which some aspect of your system is // considered to be "unhealthy" and the ways to notify people or services about // this state. For an overview of alert policies, see @@ -116,7 +178,7 @@ type AlertPolicy struct { // // projects/[PROJECT_ID_OR_NUMBER]/alertPolicies/[ALERT_POLICY_ID] // - // `[ALERT_POLICY_ID]` is assigned by Stackdriver Monitoring when the policy + // `[ALERT_POLICY_ID]` is assigned by Cloud Monitoring when the policy // is created. When calling the // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy] // method, do not include the `name` field in the alerting policy passed as @@ -309,7 +371,8 @@ type AlertPolicy_Documentation struct { // The text of the documentation, interpreted according to `mime_type`. // The content may not exceed 8,192 Unicode characters and may not exceed // more than 10,240 bytes when encoded in UTF-8 format, whichever is - // smaller. + // smaller. This text can be [templatized by using + // variables](https://cloud.google.com/monitoring/alerts/doc-variables). Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` // The format of the `content` field. Presently, only the value // `"text/markdown"` is supported. See @@ -376,13 +439,13 @@ type AlertPolicy_Condition struct { // // projects/[PROJECT_ID_OR_NUMBER]/alertPolicies/[POLICY_ID]/conditions/[CONDITION_ID] // - // `[CONDITION_ID]` is assigned by Stackdriver Monitoring when the + // `[CONDITION_ID]` is assigned by Cloud Monitoring when the // condition is created as part of a new or updated alerting policy. // // When calling the // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy] // method, do not include the `name` field in the conditions of the - // requested alerting policy. Stackdriver Monitoring creates the + // requested alerting policy. Cloud Monitoring creates the // condition identifiers and includes them in the new policy. // // When calling the @@ -755,6 +818,9 @@ type AlertPolicy_Condition_MetricThreshold struct { // or by the ratio, if `denominator_filter` and `denominator_aggregations` // are specified. Trigger *AlertPolicy_Condition_Trigger `protobuf:"bytes,7,opt,name=trigger,proto3" json:"trigger,omitempty"` + // A condition control that determines how metric-threshold conditions + // are evaluated when data stops arriving. + EvaluationMissingData AlertPolicy_Condition_EvaluationMissingData `protobuf:"varint,11,opt,name=evaluation_missing_data,json=evaluationMissingData,proto3,enum=google.monitoring.v3.AlertPolicy_Condition_EvaluationMissingData" json:"evaluation_missing_data,omitempty"` } func (x *AlertPolicy_Condition_MetricThreshold) Reset() { @@ -845,6 +911,13 @@ func (x *AlertPolicy_Condition_MetricThreshold) GetTrigger() *AlertPolicy_Condit return nil } +func (x *AlertPolicy_Condition_MetricThreshold) GetEvaluationMissingData() AlertPolicy_Condition_EvaluationMissingData { + if x != nil { + return x.EvaluationMissingData + } + return AlertPolicy_Condition_EVALUATION_MISSING_DATA_UNSPECIFIED +} + // A condition type that checks that monitored resources // are reporting data. The configuration defines a metric and // a set of monitored resources. The predicate is considered in violation @@ -1054,6 +1127,9 @@ type AlertPolicy_Condition_MonitoringQueryLanguageCondition struct { // or by the ratio, if `denominator_filter` and `denominator_aggregations` // are specified. Trigger *AlertPolicy_Condition_Trigger `protobuf:"bytes,3,opt,name=trigger,proto3" json:"trigger,omitempty"` + // A condition control that determines how metric-threshold conditions + // are evaluated when data stops arriving. + EvaluationMissingData AlertPolicy_Condition_EvaluationMissingData `protobuf:"varint,4,opt,name=evaluation_missing_data,json=evaluationMissingData,proto3,enum=google.monitoring.v3.AlertPolicy_Condition_EvaluationMissingData" json:"evaluation_missing_data,omitempty"` } func (x *AlertPolicy_Condition_MonitoringQueryLanguageCondition) Reset() { @@ -1109,6 +1185,13 @@ func (x *AlertPolicy_Condition_MonitoringQueryLanguageCondition) GetTrigger() *A return nil } +func (x *AlertPolicy_Condition_MonitoringQueryLanguageCondition) GetEvaluationMissingData() AlertPolicy_Condition_EvaluationMissingData { + if x != nil { + return x.EvaluationMissingData + } + return AlertPolicy_Condition_EVALUATION_MISSING_DATA_UNSPECIFIED +} + // Control over the rate of notifications sent to this alert policy's // notification channels. type AlertPolicy_AlertStrategy_NotificationRateLimit struct { @@ -1179,7 +1262,7 @@ var file_google_monitoring_v3_alert_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x1c, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x1f, 0x0a, 0x0b, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, @@ -1234,7 +1317,7 @@ var file_google_monitoring_v3_alert_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0xaf, 0x10, 0x0a, 0x09, 0x43, 0x6f, + 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0xd5, 0x13, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, @@ -1273,7 +1356,7 @@ var file_google_monitoring_v3_alert_proto_rawDesc = []byte{ 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, - 0x74, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xf7, 0x03, 0x0a, 0x0f, 0x4d, 0x65, + 0x74, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xf2, 0x04, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0c, 0x61, 0x67, @@ -1305,14 +1388,48 @@ var file_google_monitoring_v3_alert_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x1a, 0xf9, 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x62, - 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, - 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, + 0x67, 0x65, 0x72, 0x12, 0x79, 0x0a, 0x17, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, + 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x15, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, 0x61, 0x1a, 0xf9, + 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x41, 0x62, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x45, 0x0a, + 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x07, 0x74, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, + 0x72, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x1a, 0xe1, 0x01, 0x0a, 0x08, 0x4c, + 0x6f, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x74, 0x0a, 0x10, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x65, 0x78, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xb9, + 0x02, 0x0a, 0x20, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, @@ -1320,105 +1437,98 @@ var file_google_monitoring_v3_alert_proto_rawDesc = []byte{ 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x1a, - 0xe1, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, - 0x02, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x74, 0x0a, 0x10, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, - 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x1a, - 0x42, 0x0a, 0x14, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, - 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0xbe, 0x01, 0x0a, 0x20, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x35, - 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x07, 0x74, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x3a, 0x97, 0x02, 0xea, 0x41, 0x93, 0x02, 0x0a, 0x2e, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, - 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, - 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, - 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x7d, 0x12, 0x50, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, - 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x2f, 0x63, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x44, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, - 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, + 0x79, 0x0a, 0x17, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x41, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x15, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0xad, 0x01, 0x0a, 0x15, 0x45, + 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x27, 0x0a, 0x23, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, + 0x20, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, + 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x41, + 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x56, 0x41, 0x4c, 0x55, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x41, + 0x54, 0x41, 0x5f, 0x4e, 0x4f, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x3a, 0x97, 0x02, 0xea, 0x41, 0x93, + 0x02, 0x0a, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6c, 0x65, + 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x46, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x50, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x7b, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0x0b, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x94, 0x02, 0x0a, 0x0d, - 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x7d, 0x0a, - 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, - 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, + 0x7b, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x44, 0x66, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x61, 0x6c, + 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x7d, 0x12, 0x01, 0x2a, 0x42, 0x0b, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x1a, 0x94, 0x02, 0x0a, 0x0d, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x12, 0x7d, 0x0a, 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, + 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x15, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x1a, 0x4a, 0x0a, 0x15, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x15, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x0a, - 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x61, 0x75, 0x74, - 0x6f, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x1a, 0x4a, 0x0a, 0x15, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, - 0x31, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, - 0x6f, 0x64, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x61, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, - 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, - 0x4d, 0x42, 0x49, 0x4e, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x44, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, - 0x4f, 0x52, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x48, - 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x10, 0x03, 0x3a, 0xc9, 0x01, 0xea, 0x41, 0xc5, 0x01, 0x0a, 0x25, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, - 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x61, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x44, + 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x4e, + 0x44, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x49, 0x4e, 0x47, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x03, 0x3a, 0xc9, 0x01, 0xea, 0x41, 0xc5, + 0x01, 0x0a, 0x25, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6c, 0x65, + 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x12, 0x39, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x7d, 0x12, 0x2d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, + 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x7d, 0x12, 0x39, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, - 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x12, 0x2d, - 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, - 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, - 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x7d, 0x12, 0x01, 0x2a, - 0x42, 0xc2, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0a, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, - 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, - 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, - 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, - 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x79, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0xc5, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x76, 0x33, 0x42, 0x0a, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, + 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, + 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1433,62 +1543,65 @@ func file_google_monitoring_v3_alert_proto_rawDescGZIP() []byte { return file_google_monitoring_v3_alert_proto_rawDescData } -var file_google_monitoring_v3_alert_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_google_monitoring_v3_alert_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_google_monitoring_v3_alert_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_google_monitoring_v3_alert_proto_goTypes = []interface{}{ (AlertPolicy_ConditionCombinerType)(0), // 0: google.monitoring.v3.AlertPolicy.ConditionCombinerType - (*AlertPolicy)(nil), // 1: google.monitoring.v3.AlertPolicy - (*AlertPolicy_Documentation)(nil), // 2: google.monitoring.v3.AlertPolicy.Documentation - (*AlertPolicy_Condition)(nil), // 3: google.monitoring.v3.AlertPolicy.Condition - (*AlertPolicy_AlertStrategy)(nil), // 4: google.monitoring.v3.AlertPolicy.AlertStrategy - nil, // 5: google.monitoring.v3.AlertPolicy.UserLabelsEntry - (*AlertPolicy_Condition_Trigger)(nil), // 6: google.monitoring.v3.AlertPolicy.Condition.Trigger - (*AlertPolicy_Condition_MetricThreshold)(nil), // 7: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold - (*AlertPolicy_Condition_MetricAbsence)(nil), // 8: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence - (*AlertPolicy_Condition_LogMatch)(nil), // 9: google.monitoring.v3.AlertPolicy.Condition.LogMatch - (*AlertPolicy_Condition_MonitoringQueryLanguageCondition)(nil), // 10: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition - nil, // 11: google.monitoring.v3.AlertPolicy.Condition.LogMatch.LabelExtractorsEntry - (*AlertPolicy_AlertStrategy_NotificationRateLimit)(nil), // 12: google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit - (*wrapperspb.BoolValue)(nil), // 13: google.protobuf.BoolValue - (*status.Status)(nil), // 14: google.rpc.Status - (*MutationRecord)(nil), // 15: google.monitoring.v3.MutationRecord - (*durationpb.Duration)(nil), // 16: google.protobuf.Duration - (*Aggregation)(nil), // 17: google.monitoring.v3.Aggregation - (ComparisonType)(0), // 18: google.monitoring.v3.ComparisonType + (AlertPolicy_Condition_EvaluationMissingData)(0), // 1: google.monitoring.v3.AlertPolicy.Condition.EvaluationMissingData + (*AlertPolicy)(nil), // 2: google.monitoring.v3.AlertPolicy + (*AlertPolicy_Documentation)(nil), // 3: google.monitoring.v3.AlertPolicy.Documentation + (*AlertPolicy_Condition)(nil), // 4: google.monitoring.v3.AlertPolicy.Condition + (*AlertPolicy_AlertStrategy)(nil), // 5: google.monitoring.v3.AlertPolicy.AlertStrategy + nil, // 6: google.monitoring.v3.AlertPolicy.UserLabelsEntry + (*AlertPolicy_Condition_Trigger)(nil), // 7: google.monitoring.v3.AlertPolicy.Condition.Trigger + (*AlertPolicy_Condition_MetricThreshold)(nil), // 8: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold + (*AlertPolicy_Condition_MetricAbsence)(nil), // 9: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence + (*AlertPolicy_Condition_LogMatch)(nil), // 10: google.monitoring.v3.AlertPolicy.Condition.LogMatch + (*AlertPolicy_Condition_MonitoringQueryLanguageCondition)(nil), // 11: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition + nil, // 12: google.monitoring.v3.AlertPolicy.Condition.LogMatch.LabelExtractorsEntry + (*AlertPolicy_AlertStrategy_NotificationRateLimit)(nil), // 13: google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit + (*wrapperspb.BoolValue)(nil), // 14: google.protobuf.BoolValue + (*status.Status)(nil), // 15: google.rpc.Status + (*MutationRecord)(nil), // 16: google.monitoring.v3.MutationRecord + (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*Aggregation)(nil), // 18: google.monitoring.v3.Aggregation + (ComparisonType)(0), // 19: google.monitoring.v3.ComparisonType } var file_google_monitoring_v3_alert_proto_depIdxs = []int32{ - 2, // 0: google.monitoring.v3.AlertPolicy.documentation:type_name -> google.monitoring.v3.AlertPolicy.Documentation - 5, // 1: google.monitoring.v3.AlertPolicy.user_labels:type_name -> google.monitoring.v3.AlertPolicy.UserLabelsEntry - 3, // 2: google.monitoring.v3.AlertPolicy.conditions:type_name -> google.monitoring.v3.AlertPolicy.Condition + 3, // 0: google.monitoring.v3.AlertPolicy.documentation:type_name -> google.monitoring.v3.AlertPolicy.Documentation + 6, // 1: google.monitoring.v3.AlertPolicy.user_labels:type_name -> google.monitoring.v3.AlertPolicy.UserLabelsEntry + 4, // 2: google.monitoring.v3.AlertPolicy.conditions:type_name -> google.monitoring.v3.AlertPolicy.Condition 0, // 3: google.monitoring.v3.AlertPolicy.combiner:type_name -> google.monitoring.v3.AlertPolicy.ConditionCombinerType - 13, // 4: google.monitoring.v3.AlertPolicy.enabled:type_name -> google.protobuf.BoolValue - 14, // 5: google.monitoring.v3.AlertPolicy.validity:type_name -> google.rpc.Status - 15, // 6: google.monitoring.v3.AlertPolicy.creation_record:type_name -> google.monitoring.v3.MutationRecord - 15, // 7: google.monitoring.v3.AlertPolicy.mutation_record:type_name -> google.monitoring.v3.MutationRecord - 4, // 8: google.monitoring.v3.AlertPolicy.alert_strategy:type_name -> google.monitoring.v3.AlertPolicy.AlertStrategy - 7, // 9: google.monitoring.v3.AlertPolicy.Condition.condition_threshold:type_name -> google.monitoring.v3.AlertPolicy.Condition.MetricThreshold - 8, // 10: google.monitoring.v3.AlertPolicy.Condition.condition_absent:type_name -> google.monitoring.v3.AlertPolicy.Condition.MetricAbsence - 9, // 11: google.monitoring.v3.AlertPolicy.Condition.condition_matched_log:type_name -> google.monitoring.v3.AlertPolicy.Condition.LogMatch - 10, // 12: google.monitoring.v3.AlertPolicy.Condition.condition_monitoring_query_language:type_name -> google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition - 12, // 13: google.monitoring.v3.AlertPolicy.AlertStrategy.notification_rate_limit:type_name -> google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit - 16, // 14: google.monitoring.v3.AlertPolicy.AlertStrategy.auto_close:type_name -> google.protobuf.Duration - 17, // 15: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.aggregations:type_name -> google.monitoring.v3.Aggregation - 17, // 16: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.denominator_aggregations:type_name -> google.monitoring.v3.Aggregation - 18, // 17: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.comparison:type_name -> google.monitoring.v3.ComparisonType - 16, // 18: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.duration:type_name -> google.protobuf.Duration - 6, // 19: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger - 17, // 20: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.aggregations:type_name -> google.monitoring.v3.Aggregation - 16, // 21: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.duration:type_name -> google.protobuf.Duration - 6, // 22: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger - 11, // 23: google.monitoring.v3.AlertPolicy.Condition.LogMatch.label_extractors:type_name -> google.monitoring.v3.AlertPolicy.Condition.LogMatch.LabelExtractorsEntry - 16, // 24: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition.duration:type_name -> google.protobuf.Duration - 6, // 25: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger - 16, // 26: google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit.period:type_name -> google.protobuf.Duration - 27, // [27:27] is the sub-list for method output_type - 27, // [27:27] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 14, // 4: google.monitoring.v3.AlertPolicy.enabled:type_name -> google.protobuf.BoolValue + 15, // 5: google.monitoring.v3.AlertPolicy.validity:type_name -> google.rpc.Status + 16, // 6: google.monitoring.v3.AlertPolicy.creation_record:type_name -> google.monitoring.v3.MutationRecord + 16, // 7: google.monitoring.v3.AlertPolicy.mutation_record:type_name -> google.monitoring.v3.MutationRecord + 5, // 8: google.monitoring.v3.AlertPolicy.alert_strategy:type_name -> google.monitoring.v3.AlertPolicy.AlertStrategy + 8, // 9: google.monitoring.v3.AlertPolicy.Condition.condition_threshold:type_name -> google.monitoring.v3.AlertPolicy.Condition.MetricThreshold + 9, // 10: google.monitoring.v3.AlertPolicy.Condition.condition_absent:type_name -> google.monitoring.v3.AlertPolicy.Condition.MetricAbsence + 10, // 11: google.monitoring.v3.AlertPolicy.Condition.condition_matched_log:type_name -> google.monitoring.v3.AlertPolicy.Condition.LogMatch + 11, // 12: google.monitoring.v3.AlertPolicy.Condition.condition_monitoring_query_language:type_name -> google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition + 13, // 13: google.monitoring.v3.AlertPolicy.AlertStrategy.notification_rate_limit:type_name -> google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit + 17, // 14: google.monitoring.v3.AlertPolicy.AlertStrategy.auto_close:type_name -> google.protobuf.Duration + 18, // 15: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.aggregations:type_name -> google.monitoring.v3.Aggregation + 18, // 16: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.denominator_aggregations:type_name -> google.monitoring.v3.Aggregation + 19, // 17: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.comparison:type_name -> google.monitoring.v3.ComparisonType + 17, // 18: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.duration:type_name -> google.protobuf.Duration + 7, // 19: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger + 1, // 20: google.monitoring.v3.AlertPolicy.Condition.MetricThreshold.evaluation_missing_data:type_name -> google.monitoring.v3.AlertPolicy.Condition.EvaluationMissingData + 18, // 21: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.aggregations:type_name -> google.monitoring.v3.Aggregation + 17, // 22: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.duration:type_name -> google.protobuf.Duration + 7, // 23: google.monitoring.v3.AlertPolicy.Condition.MetricAbsence.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger + 12, // 24: google.monitoring.v3.AlertPolicy.Condition.LogMatch.label_extractors:type_name -> google.monitoring.v3.AlertPolicy.Condition.LogMatch.LabelExtractorsEntry + 17, // 25: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition.duration:type_name -> google.protobuf.Duration + 7, // 26: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition.trigger:type_name -> google.monitoring.v3.AlertPolicy.Condition.Trigger + 1, // 27: google.monitoring.v3.AlertPolicy.Condition.MonitoringQueryLanguageCondition.evaluation_missing_data:type_name -> google.monitoring.v3.AlertPolicy.Condition.EvaluationMissingData + 17, // 28: google.monitoring.v3.AlertPolicy.AlertStrategy.NotificationRateLimit.period:type_name -> google.protobuf.Duration + 29, // [29:29] is the sub-list for method output_type + 29, // [29:29] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_google_monitoring_v3_alert_proto_init() } @@ -1635,7 +1748,7 @@ func file_google_monitoring_v3_alert_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_monitoring_v3_alert_proto_rawDesc, - NumEnums: 1, + NumEnums: 2, NumMessages: 12, NumExtensions: 0, NumServices: 0, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert_service.pb.go similarity index 93% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert_service.pb.go index 18340450b6c..5a2718de868 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/alert_service.pb.go @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/alert_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -55,7 +55,7 @@ type CreateAlertPolicyRequest struct { // // Note that this field names the parent container in which the alerting // policy will be written, not the name of the created policy. |name| must be - // a host project of a workspace, otherwise INVALID_ARGUMENT error will + // a host project of a Metrics Scope, otherwise INVALID_ARGUMENT error will // return. The alerting policy that is returned will have a name that contains // a normalized representation of this name as a prefix but adds a suffix of // the form `/alertPolicies/[ALERT_POLICY_ID]`, identifying the policy in the @@ -558,54 +558,54 @@ var file_google_monitoring_v3_alert_service_proto_rawDesc = []byte{ 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0xda, 0x41, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x76, 0x33, 0x2f, + 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, + 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x33, 0x2f, - 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, - 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x2a, - 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xb5, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, + 0x63, 0x79, 0x22, 0x34, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x27, 0x12, 0x25, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xb5, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x22, 0x4d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x22, 0x23, 0x2f, 0x76, 0x33, 0x2f, 0x7b, - 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, - 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x3a, 0x0c, - 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xda, 0x41, 0x11, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x79, 0x22, 0x4d, 0xda, 0x41, 0x11, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x61, 0x6c, 0x65, 0x72, 0x74, + 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x0c, 0x61, + 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x23, 0x2f, 0x76, 0x33, + 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x7d, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x34, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x2a, 0x25, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, - 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x61, 0x6c, 0x65, - 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xcb, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, + 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x2a, 0x25, 0x2f, + 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xcb, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x63, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x32, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, - 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x0c, 0x61, 0x6c, 0x65, 0x72, 0x74, - 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xda, 0x41, 0x18, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2c, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x33, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x63, 0xda, + 0x41, 0x18, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2c, 0x61, 0x6c, + 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x42, + 0x3a, 0x0c, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x32, 0x32, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, + 0x2a, 0x7d, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, @@ -615,21 +615,21 @@ var file_google_monitoring_v3_alert_service_proto_rawDesc = []byte{ 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x42, 0xc9, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x42, 0xcc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x11, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, - 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, - 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, - 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, + 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/common.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/common.pb.go new file mode 100644 index 00000000000..d4fd9cf19d4 --- /dev/null +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/common.pb.go @@ -0,0 +1,1154 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/monitoring/v3/common.proto + +package monitoringpb + +import ( + reflect "reflect" + sync "sync" + + distribution "google.golang.org/genproto/googleapis/api/distribution" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Specifies an ordering relationship on two arguments, called `left` and +// `right`. +type ComparisonType int32 + +const ( + // No ordering relationship is specified. + ComparisonType_COMPARISON_UNSPECIFIED ComparisonType = 0 + // True if the left argument is greater than the right argument. + ComparisonType_COMPARISON_GT ComparisonType = 1 + // True if the left argument is greater than or equal to the right argument. + ComparisonType_COMPARISON_GE ComparisonType = 2 + // True if the left argument is less than the right argument. + ComparisonType_COMPARISON_LT ComparisonType = 3 + // True if the left argument is less than or equal to the right argument. + ComparisonType_COMPARISON_LE ComparisonType = 4 + // True if the left argument is equal to the right argument. + ComparisonType_COMPARISON_EQ ComparisonType = 5 + // True if the left argument is not equal to the right argument. + ComparisonType_COMPARISON_NE ComparisonType = 6 +) + +// Enum value maps for ComparisonType. +var ( + ComparisonType_name = map[int32]string{ + 0: "COMPARISON_UNSPECIFIED", + 1: "COMPARISON_GT", + 2: "COMPARISON_GE", + 3: "COMPARISON_LT", + 4: "COMPARISON_LE", + 5: "COMPARISON_EQ", + 6: "COMPARISON_NE", + } + ComparisonType_value = map[string]int32{ + "COMPARISON_UNSPECIFIED": 0, + "COMPARISON_GT": 1, + "COMPARISON_GE": 2, + "COMPARISON_LT": 3, + "COMPARISON_LE": 4, + "COMPARISON_EQ": 5, + "COMPARISON_NE": 6, + } +) + +func (x ComparisonType) Enum() *ComparisonType { + p := new(ComparisonType) + *p = x + return p +} + +func (x ComparisonType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ComparisonType) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_common_proto_enumTypes[0].Descriptor() +} + +func (ComparisonType) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_common_proto_enumTypes[0] +} + +func (x ComparisonType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ComparisonType.Descriptor instead. +func (ComparisonType) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{0} +} + +// The tier of service for a Workspace. Please see the +// [service tiers +// documentation](https://cloud.google.com/monitoring/workspaces/tiers) for more +// details. +// +// Deprecated: Marked as deprecated in google/monitoring/v3/common.proto. +type ServiceTier int32 + +const ( + // An invalid sentinel value, used to indicate that a tier has not + // been provided explicitly. + ServiceTier_SERVICE_TIER_UNSPECIFIED ServiceTier = 0 + // The Stackdriver Basic tier, a free tier of service that provides basic + // features, a moderate allotment of logs, and access to built-in metrics. + // A number of features are not available in this tier. For more details, + // see [the service tiers + // documentation](https://cloud.google.com/monitoring/workspaces/tiers). + ServiceTier_SERVICE_TIER_BASIC ServiceTier = 1 + // The Stackdriver Premium tier, a higher, more expensive tier of service + // that provides access to all Stackdriver features, lets you use Stackdriver + // with AWS accounts, and has a larger allotments for logs and metrics. For + // more details, see [the service tiers + // documentation](https://cloud.google.com/monitoring/workspaces/tiers). + ServiceTier_SERVICE_TIER_PREMIUM ServiceTier = 2 +) + +// Enum value maps for ServiceTier. +var ( + ServiceTier_name = map[int32]string{ + 0: "SERVICE_TIER_UNSPECIFIED", + 1: "SERVICE_TIER_BASIC", + 2: "SERVICE_TIER_PREMIUM", + } + ServiceTier_value = map[string]int32{ + "SERVICE_TIER_UNSPECIFIED": 0, + "SERVICE_TIER_BASIC": 1, + "SERVICE_TIER_PREMIUM": 2, + } +) + +func (x ServiceTier) Enum() *ServiceTier { + p := new(ServiceTier) + *p = x + return p +} + +func (x ServiceTier) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServiceTier) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_common_proto_enumTypes[1].Descriptor() +} + +func (ServiceTier) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_common_proto_enumTypes[1] +} + +func (x ServiceTier) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServiceTier.Descriptor instead. +func (ServiceTier) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{1} +} + +// The `Aligner` specifies the operation that will be applied to the data +// points in each alignment period in a time series. Except for +// `ALIGN_NONE`, which specifies that no operation be applied, each alignment +// operation replaces the set of data values in each alignment period with +// a single value: the result of applying the operation to the data values. +// An aligned time series has a single data value at the end of each +// `alignment_period`. +// +// An alignment operation can change the data type of the values, too. For +// example, if you apply a counting operation to boolean values, the data +// `value_type` in the original time series is `BOOLEAN`, but the `value_type` +// in the aligned result is `INT64`. +type Aggregation_Aligner int32 + +const ( + // No alignment. Raw data is returned. Not valid if cross-series reduction + // is requested. The `value_type` of the result is the same as the + // `value_type` of the input. + Aggregation_ALIGN_NONE Aggregation_Aligner = 0 + // Align and convert to + // [DELTA][google.api.MetricDescriptor.MetricKind.DELTA]. + // The output is `delta = y1 - y0`. + // + // This alignment is valid for + // [CUMULATIVE][google.api.MetricDescriptor.MetricKind.CUMULATIVE] and + // `DELTA` metrics. If the selected alignment period results in periods + // with no data, then the aligned value for such a period is created by + // interpolation. The `value_type` of the aligned result is the same as + // the `value_type` of the input. + Aggregation_ALIGN_DELTA Aggregation_Aligner = 1 + // Align and convert to a rate. The result is computed as + // `rate = (y1 - y0)/(t1 - t0)`, or "delta over time". + // Think of this aligner as providing the slope of the line that passes + // through the value at the start and at the end of the `alignment_period`. + // + // This aligner is valid for `CUMULATIVE` + // and `DELTA` metrics with numeric values. If the selected alignment + // period results in periods with no data, then the aligned value for + // such a period is created by interpolation. The output is a `GAUGE` + // metric with `value_type` `DOUBLE`. + // + // If, by "rate", you mean "percentage change", see the + // `ALIGN_PERCENT_CHANGE` aligner instead. + Aggregation_ALIGN_RATE Aggregation_Aligner = 2 + // Align by interpolating between adjacent points around the alignment + // period boundary. This aligner is valid for `GAUGE` metrics with + // numeric values. The `value_type` of the aligned result is the same as the + // `value_type` of the input. + Aggregation_ALIGN_INTERPOLATE Aggregation_Aligner = 3 + // Align by moving the most recent data point before the end of the + // alignment period to the boundary at the end of the alignment + // period. This aligner is valid for `GAUGE` metrics. The `value_type` of + // the aligned result is the same as the `value_type` of the input. + Aggregation_ALIGN_NEXT_OLDER Aggregation_Aligner = 4 + // Align the time series by returning the minimum value in each alignment + // period. This aligner is valid for `GAUGE` and `DELTA` metrics with + // numeric values. The `value_type` of the aligned result is the same as + // the `value_type` of the input. + Aggregation_ALIGN_MIN Aggregation_Aligner = 10 + // Align the time series by returning the maximum value in each alignment + // period. This aligner is valid for `GAUGE` and `DELTA` metrics with + // numeric values. The `value_type` of the aligned result is the same as + // the `value_type` of the input. + Aggregation_ALIGN_MAX Aggregation_Aligner = 11 + // Align the time series by returning the mean value in each alignment + // period. This aligner is valid for `GAUGE` and `DELTA` metrics with + // numeric values. The `value_type` of the aligned result is `DOUBLE`. + Aggregation_ALIGN_MEAN Aggregation_Aligner = 12 + // Align the time series by returning the number of values in each alignment + // period. This aligner is valid for `GAUGE` and `DELTA` metrics with + // numeric or Boolean values. The `value_type` of the aligned result is + // `INT64`. + Aggregation_ALIGN_COUNT Aggregation_Aligner = 13 + // Align the time series by returning the sum of the values in each + // alignment period. This aligner is valid for `GAUGE` and `DELTA` + // metrics with numeric and distribution values. The `value_type` of the + // aligned result is the same as the `value_type` of the input. + Aggregation_ALIGN_SUM Aggregation_Aligner = 14 + // Align the time series by returning the standard deviation of the values + // in each alignment period. This aligner is valid for `GAUGE` and + // `DELTA` metrics with numeric values. The `value_type` of the output is + // `DOUBLE`. + Aggregation_ALIGN_STDDEV Aggregation_Aligner = 15 + // Align the time series by returning the number of `True` values in + // each alignment period. This aligner is valid for `GAUGE` metrics with + // Boolean values. The `value_type` of the output is `INT64`. + Aggregation_ALIGN_COUNT_TRUE Aggregation_Aligner = 16 + // Align the time series by returning the number of `False` values in + // each alignment period. This aligner is valid for `GAUGE` metrics with + // Boolean values. The `value_type` of the output is `INT64`. + Aggregation_ALIGN_COUNT_FALSE Aggregation_Aligner = 24 + // Align the time series by returning the ratio of the number of `True` + // values to the total number of values in each alignment period. This + // aligner is valid for `GAUGE` metrics with Boolean values. The output + // value is in the range [0.0, 1.0] and has `value_type` `DOUBLE`. + Aggregation_ALIGN_FRACTION_TRUE Aggregation_Aligner = 17 + // Align the time series by using [percentile + // aggregation](https://en.wikipedia.org/wiki/Percentile). The resulting + // data point in each alignment period is the 99th percentile of all data + // points in the period. This aligner is valid for `GAUGE` and `DELTA` + // metrics with distribution values. The output is a `GAUGE` metric with + // `value_type` `DOUBLE`. + Aggregation_ALIGN_PERCENTILE_99 Aggregation_Aligner = 18 + // Align the time series by using [percentile + // aggregation](https://en.wikipedia.org/wiki/Percentile). The resulting + // data point in each alignment period is the 95th percentile of all data + // points in the period. This aligner is valid for `GAUGE` and `DELTA` + // metrics with distribution values. The output is a `GAUGE` metric with + // `value_type` `DOUBLE`. + Aggregation_ALIGN_PERCENTILE_95 Aggregation_Aligner = 19 + // Align the time series by using [percentile + // aggregation](https://en.wikipedia.org/wiki/Percentile). The resulting + // data point in each alignment period is the 50th percentile of all data + // points in the period. This aligner is valid for `GAUGE` and `DELTA` + // metrics with distribution values. The output is a `GAUGE` metric with + // `value_type` `DOUBLE`. + Aggregation_ALIGN_PERCENTILE_50 Aggregation_Aligner = 20 + // Align the time series by using [percentile + // aggregation](https://en.wikipedia.org/wiki/Percentile). The resulting + // data point in each alignment period is the 5th percentile of all data + // points in the period. This aligner is valid for `GAUGE` and `DELTA` + // metrics with distribution values. The output is a `GAUGE` metric with + // `value_type` `DOUBLE`. + Aggregation_ALIGN_PERCENTILE_05 Aggregation_Aligner = 21 + // Align and convert to a percentage change. This aligner is valid for + // `GAUGE` and `DELTA` metrics with numeric values. This alignment returns + // `((current - previous)/previous) * 100`, where the value of `previous` is + // determined based on the `alignment_period`. + // + // If the values of `current` and `previous` are both 0, then the returned + // value is 0. If only `previous` is 0, the returned value is infinity. + // + // A 10-minute moving mean is computed at each point of the alignment period + // prior to the above calculation to smooth the metric and prevent false + // positives from very short-lived spikes. The moving mean is only + // applicable for data whose values are `>= 0`. Any values `< 0` are + // treated as a missing datapoint, and are ignored. While `DELTA` + // metrics are accepted by this alignment, special care should be taken that + // the values for the metric will always be positive. The output is a + // `GAUGE` metric with `value_type` `DOUBLE`. + Aggregation_ALIGN_PERCENT_CHANGE Aggregation_Aligner = 23 +) + +// Enum value maps for Aggregation_Aligner. +var ( + Aggregation_Aligner_name = map[int32]string{ + 0: "ALIGN_NONE", + 1: "ALIGN_DELTA", + 2: "ALIGN_RATE", + 3: "ALIGN_INTERPOLATE", + 4: "ALIGN_NEXT_OLDER", + 10: "ALIGN_MIN", + 11: "ALIGN_MAX", + 12: "ALIGN_MEAN", + 13: "ALIGN_COUNT", + 14: "ALIGN_SUM", + 15: "ALIGN_STDDEV", + 16: "ALIGN_COUNT_TRUE", + 24: "ALIGN_COUNT_FALSE", + 17: "ALIGN_FRACTION_TRUE", + 18: "ALIGN_PERCENTILE_99", + 19: "ALIGN_PERCENTILE_95", + 20: "ALIGN_PERCENTILE_50", + 21: "ALIGN_PERCENTILE_05", + 23: "ALIGN_PERCENT_CHANGE", + } + Aggregation_Aligner_value = map[string]int32{ + "ALIGN_NONE": 0, + "ALIGN_DELTA": 1, + "ALIGN_RATE": 2, + "ALIGN_INTERPOLATE": 3, + "ALIGN_NEXT_OLDER": 4, + "ALIGN_MIN": 10, + "ALIGN_MAX": 11, + "ALIGN_MEAN": 12, + "ALIGN_COUNT": 13, + "ALIGN_SUM": 14, + "ALIGN_STDDEV": 15, + "ALIGN_COUNT_TRUE": 16, + "ALIGN_COUNT_FALSE": 24, + "ALIGN_FRACTION_TRUE": 17, + "ALIGN_PERCENTILE_99": 18, + "ALIGN_PERCENTILE_95": 19, + "ALIGN_PERCENTILE_50": 20, + "ALIGN_PERCENTILE_05": 21, + "ALIGN_PERCENT_CHANGE": 23, + } +) + +func (x Aggregation_Aligner) Enum() *Aggregation_Aligner { + p := new(Aggregation_Aligner) + *p = x + return p +} + +func (x Aggregation_Aligner) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Aggregation_Aligner) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_common_proto_enumTypes[2].Descriptor() +} + +func (Aggregation_Aligner) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_common_proto_enumTypes[2] +} + +func (x Aggregation_Aligner) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Aggregation_Aligner.Descriptor instead. +func (Aggregation_Aligner) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{2, 0} +} + +// A Reducer operation describes how to aggregate data points from multiple +// time series into a single time series, where the value of each data point +// in the resulting series is a function of all the already aligned values in +// the input time series. +type Aggregation_Reducer int32 + +const ( + // No cross-time series reduction. The output of the `Aligner` is + // returned. + Aggregation_REDUCE_NONE Aggregation_Reducer = 0 + // Reduce by computing the mean value across time series for each + // alignment period. This reducer is valid for + // [DELTA][google.api.MetricDescriptor.MetricKind.DELTA] and + // [GAUGE][google.api.MetricDescriptor.MetricKind.GAUGE] metrics with + // numeric or distribution values. The `value_type` of the output is + // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]. + Aggregation_REDUCE_MEAN Aggregation_Reducer = 1 + // Reduce by computing the minimum value across time series for each + // alignment period. This reducer is valid for `DELTA` and `GAUGE` metrics + // with numeric values. The `value_type` of the output is the same as the + // `value_type` of the input. + Aggregation_REDUCE_MIN Aggregation_Reducer = 2 + // Reduce by computing the maximum value across time series for each + // alignment period. This reducer is valid for `DELTA` and `GAUGE` metrics + // with numeric values. The `value_type` of the output is the same as the + // `value_type` of the input. + Aggregation_REDUCE_MAX Aggregation_Reducer = 3 + // Reduce by computing the sum across time series for each + // alignment period. This reducer is valid for `DELTA` and `GAUGE` metrics + // with numeric and distribution values. The `value_type` of the output is + // the same as the `value_type` of the input. + Aggregation_REDUCE_SUM Aggregation_Reducer = 4 + // Reduce by computing the standard deviation across time series + // for each alignment period. This reducer is valid for `DELTA` and + // `GAUGE` metrics with numeric or distribution values. The `value_type` + // of the output is `DOUBLE`. + Aggregation_REDUCE_STDDEV Aggregation_Reducer = 5 + // Reduce by computing the number of data points across time series + // for each alignment period. This reducer is valid for `DELTA` and + // `GAUGE` metrics of numeric, Boolean, distribution, and string + // `value_type`. The `value_type` of the output is `INT64`. + Aggregation_REDUCE_COUNT Aggregation_Reducer = 6 + // Reduce by computing the number of `True`-valued data points across time + // series for each alignment period. This reducer is valid for `DELTA` and + // `GAUGE` metrics of Boolean `value_type`. The `value_type` of the output + // is `INT64`. + Aggregation_REDUCE_COUNT_TRUE Aggregation_Reducer = 7 + // Reduce by computing the number of `False`-valued data points across time + // series for each alignment period. This reducer is valid for `DELTA` and + // `GAUGE` metrics of Boolean `value_type`. The `value_type` of the output + // is `INT64`. + Aggregation_REDUCE_COUNT_FALSE Aggregation_Reducer = 15 + // Reduce by computing the ratio of the number of `True`-valued data points + // to the total number of data points for each alignment period. This + // reducer is valid for `DELTA` and `GAUGE` metrics of Boolean `value_type`. + // The output value is in the range [0.0, 1.0] and has `value_type` + // `DOUBLE`. + Aggregation_REDUCE_FRACTION_TRUE Aggregation_Reducer = 8 + // Reduce by computing the [99th + // percentile](https://en.wikipedia.org/wiki/Percentile) of data points + // across time series for each alignment period. This reducer is valid for + // `GAUGE` and `DELTA` metrics of numeric and distribution type. The value + // of the output is `DOUBLE`. + Aggregation_REDUCE_PERCENTILE_99 Aggregation_Reducer = 9 + // Reduce by computing the [95th + // percentile](https://en.wikipedia.org/wiki/Percentile) of data points + // across time series for each alignment period. This reducer is valid for + // `GAUGE` and `DELTA` metrics of numeric and distribution type. The value + // of the output is `DOUBLE`. + Aggregation_REDUCE_PERCENTILE_95 Aggregation_Reducer = 10 + // Reduce by computing the [50th + // percentile](https://en.wikipedia.org/wiki/Percentile) of data points + // across time series for each alignment period. This reducer is valid for + // `GAUGE` and `DELTA` metrics of numeric and distribution type. The value + // of the output is `DOUBLE`. + Aggregation_REDUCE_PERCENTILE_50 Aggregation_Reducer = 11 + // Reduce by computing the [5th + // percentile](https://en.wikipedia.org/wiki/Percentile) of data points + // across time series for each alignment period. This reducer is valid for + // `GAUGE` and `DELTA` metrics of numeric and distribution type. The value + // of the output is `DOUBLE`. + Aggregation_REDUCE_PERCENTILE_05 Aggregation_Reducer = 12 +) + +// Enum value maps for Aggregation_Reducer. +var ( + Aggregation_Reducer_name = map[int32]string{ + 0: "REDUCE_NONE", + 1: "REDUCE_MEAN", + 2: "REDUCE_MIN", + 3: "REDUCE_MAX", + 4: "REDUCE_SUM", + 5: "REDUCE_STDDEV", + 6: "REDUCE_COUNT", + 7: "REDUCE_COUNT_TRUE", + 15: "REDUCE_COUNT_FALSE", + 8: "REDUCE_FRACTION_TRUE", + 9: "REDUCE_PERCENTILE_99", + 10: "REDUCE_PERCENTILE_95", + 11: "REDUCE_PERCENTILE_50", + 12: "REDUCE_PERCENTILE_05", + } + Aggregation_Reducer_value = map[string]int32{ + "REDUCE_NONE": 0, + "REDUCE_MEAN": 1, + "REDUCE_MIN": 2, + "REDUCE_MAX": 3, + "REDUCE_SUM": 4, + "REDUCE_STDDEV": 5, + "REDUCE_COUNT": 6, + "REDUCE_COUNT_TRUE": 7, + "REDUCE_COUNT_FALSE": 15, + "REDUCE_FRACTION_TRUE": 8, + "REDUCE_PERCENTILE_99": 9, + "REDUCE_PERCENTILE_95": 10, + "REDUCE_PERCENTILE_50": 11, + "REDUCE_PERCENTILE_05": 12, + } +) + +func (x Aggregation_Reducer) Enum() *Aggregation_Reducer { + p := new(Aggregation_Reducer) + *p = x + return p +} + +func (x Aggregation_Reducer) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Aggregation_Reducer) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_common_proto_enumTypes[3].Descriptor() +} + +func (Aggregation_Reducer) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_common_proto_enumTypes[3] +} + +func (x Aggregation_Reducer) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Aggregation_Reducer.Descriptor instead. +func (Aggregation_Reducer) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{2, 1} +} + +// A single strongly-typed value. +type TypedValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The typed value field. + // + // Types that are assignable to Value: + // *TypedValue_BoolValue + // *TypedValue_Int64Value + // *TypedValue_DoubleValue + // *TypedValue_StringValue + // *TypedValue_DistributionValue + Value isTypedValue_Value `protobuf_oneof:"value"` +} + +func (x *TypedValue) Reset() { + *x = TypedValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TypedValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypedValue) ProtoMessage() {} + +func (x *TypedValue) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TypedValue.ProtoReflect.Descriptor instead. +func (*TypedValue) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{0} +} + +func (m *TypedValue) GetValue() isTypedValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *TypedValue) GetBoolValue() bool { + if x, ok := x.GetValue().(*TypedValue_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (x *TypedValue) GetInt64Value() int64 { + if x, ok := x.GetValue().(*TypedValue_Int64Value); ok { + return x.Int64Value + } + return 0 +} + +func (x *TypedValue) GetDoubleValue() float64 { + if x, ok := x.GetValue().(*TypedValue_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (x *TypedValue) GetStringValue() string { + if x, ok := x.GetValue().(*TypedValue_StringValue); ok { + return x.StringValue + } + return "" +} + +func (x *TypedValue) GetDistributionValue() *distribution.Distribution { + if x, ok := x.GetValue().(*TypedValue_DistributionValue); ok { + return x.DistributionValue + } + return nil +} + +type isTypedValue_Value interface { + isTypedValue_Value() +} + +type TypedValue_BoolValue struct { + // A Boolean value: `true` or `false`. + BoolValue bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type TypedValue_Int64Value struct { + // A 64-bit integer. Its range is approximately ±9.2x1018. + Int64Value int64 `protobuf:"varint,2,opt,name=int64_value,json=int64Value,proto3,oneof"` +} + +type TypedValue_DoubleValue struct { + // A 64-bit double-precision floating-point number. Its magnitude + // is approximately ±10±300 and it has 16 + // significant digits of precision. + DoubleValue float64 `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +type TypedValue_StringValue struct { + // A variable-length string value. + StringValue string `protobuf:"bytes,4,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type TypedValue_DistributionValue struct { + // A distribution value. + DistributionValue *distribution.Distribution `protobuf:"bytes,5,opt,name=distribution_value,json=distributionValue,proto3,oneof"` +} + +func (*TypedValue_BoolValue) isTypedValue_Value() {} + +func (*TypedValue_Int64Value) isTypedValue_Value() {} + +func (*TypedValue_DoubleValue) isTypedValue_Value() {} + +func (*TypedValue_StringValue) isTypedValue_Value() {} + +func (*TypedValue_DistributionValue) isTypedValue_Value() {} + +// A closed time interval. It extends from the start time to the end time, and includes both: `[startTime, endTime]`. Valid time intervals depend on the [`MetricKind`](https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metricDescriptors#MetricKind) of the metric value. The end time must not be earlier than the start time. When writing data points, the start time must not be more than 25 hours in the past and the end time must not be more than five minutes in the future. +// +// - For `GAUGE` metrics, the `startTime` value is technically optional; if +// no value is specified, the start time defaults to the value of the +// end time, and the interval represents a single point in time. If both +// start and end times are specified, they must be identical. Such an +// interval is valid only for `GAUGE` metrics, which are point-in-time +// measurements. The end time of a new interval must be at least a +// millisecond after the end time of the previous interval. +// +// - For `DELTA` metrics, the start time and end time must specify a +// non-zero interval, with subsequent points specifying contiguous and +// non-overlapping intervals. For `DELTA` metrics, the start time of +// the next interval must be at least a millisecond after the end time +// of the previous interval. +// +// - For `CUMULATIVE` metrics, the start time and end time must specify a +// non-zero interval, with subsequent points specifying the same +// start time and increasing end times, until an event resets the +// cumulative value to zero and sets a new start time for the following +// points. The new start time must be at least a millisecond after the +// end time of the previous interval. +// +// - The start time of a new interval must be at least a millisecond after the +// end time of the previous interval because intervals are closed. If the +// start time of a new interval is the same as the end time of the previous +// interval, then data written at the new start time could overwrite data +// written at the previous end time. +type TimeInterval struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The end of the time interval. + EndTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + // Optional. The beginning of the time interval. The default value + // for the start time is the end time. The start time must not be + // later than the end time. + StartTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` +} + +func (x *TimeInterval) Reset() { + *x = TimeInterval{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TimeInterval) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TimeInterval) ProtoMessage() {} + +func (x *TimeInterval) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TimeInterval.ProtoReflect.Descriptor instead. +func (*TimeInterval) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{1} +} + +func (x *TimeInterval) GetEndTime() *timestamppb.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + +func (x *TimeInterval) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +// Describes how to combine multiple time series to provide a different view of +// the data. Aggregation of time series is done in two steps. First, each time +// series in the set is _aligned_ to the same time interval boundaries, then the +// set of time series is optionally _reduced_ in number. +// +// Alignment consists of applying the `per_series_aligner` operation +// to each time series after its data has been divided into regular +// `alignment_period` time intervals. This process takes _all_ of the data +// points in an alignment period, applies a mathematical transformation such as +// averaging, minimum, maximum, delta, etc., and converts them into a single +// data point per period. +// +// Reduction is when the aligned and transformed time series can optionally be +// combined, reducing the number of time series through similar mathematical +// transformations. Reduction involves applying a `cross_series_reducer` to +// all the time series, optionally sorting the time series into subsets with +// `group_by_fields`, and applying the reducer to each subset. +// +// The raw time series data can contain a huge amount of information from +// multiple sources. Alignment and reduction transforms this mass of data into +// a more manageable and representative collection of data, for example "the +// 95% latency across the average of all tasks in a cluster". This +// representative data can be more easily graphed and comprehended, and the +// individual time series data is still available for later drilldown. For more +// details, see [Filtering and +// aggregation](https://cloud.google.com/monitoring/api/v3/aggregation). +type Aggregation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The `alignment_period` specifies a time interval, in seconds, that is used + // to divide the data in all the + // [time series][google.monitoring.v3.TimeSeries] into consistent blocks of + // time. This will be done before the per-series aligner can be applied to + // the data. + // + // The value must be at least 60 seconds. If a per-series + // aligner other than `ALIGN_NONE` is specified, this field is required or an + // error is returned. If no per-series aligner is specified, or the aligner + // `ALIGN_NONE` is specified, then this field is ignored. + // + // The maximum value of the `alignment_period` is 104 weeks (2 years) for + // charts, and 90,000 seconds (25 hours) for alerting policies. + AlignmentPeriod *durationpb.Duration `protobuf:"bytes,1,opt,name=alignment_period,json=alignmentPeriod,proto3" json:"alignment_period,omitempty"` + // An `Aligner` describes how to bring the data points in a single + // time series into temporal alignment. Except for `ALIGN_NONE`, all + // alignments cause all the data points in an `alignment_period` to be + // mathematically grouped together, resulting in a single data point for + // each `alignment_period` with end timestamp at the end of the period. + // + // Not all alignment operations may be applied to all time series. The valid + // choices depend on the `metric_kind` and `value_type` of the original time + // series. Alignment can change the `metric_kind` or the `value_type` of + // the time series. + // + // Time series data must be aligned in order to perform cross-time + // series reduction. If `cross_series_reducer` is specified, then + // `per_series_aligner` must be specified and not equal to `ALIGN_NONE` + // and `alignment_period` must be specified; otherwise, an error is + // returned. + PerSeriesAligner Aggregation_Aligner `protobuf:"varint,2,opt,name=per_series_aligner,json=perSeriesAligner,proto3,enum=google.monitoring.v3.Aggregation_Aligner" json:"per_series_aligner,omitempty"` + // The reduction operation to be used to combine time series into a single + // time series, where the value of each data point in the resulting series is + // a function of all the already aligned values in the input time series. + // + // Not all reducer operations can be applied to all time series. The valid + // choices depend on the `metric_kind` and the `value_type` of the original + // time series. Reduction can yield a time series with a different + // `metric_kind` or `value_type` than the input time series. + // + // Time series data must first be aligned (see `per_series_aligner`) in order + // to perform cross-time series reduction. If `cross_series_reducer` is + // specified, then `per_series_aligner` must be specified, and must not be + // `ALIGN_NONE`. An `alignment_period` must also be specified; otherwise, an + // error is returned. + CrossSeriesReducer Aggregation_Reducer `protobuf:"varint,4,opt,name=cross_series_reducer,json=crossSeriesReducer,proto3,enum=google.monitoring.v3.Aggregation_Reducer" json:"cross_series_reducer,omitempty"` + // The set of fields to preserve when `cross_series_reducer` is + // specified. The `group_by_fields` determine how the time series are + // partitioned into subsets prior to applying the aggregation + // operation. Each subset contains time series that have the same + // value for each of the grouping fields. Each individual time + // series is a member of exactly one subset. The + // `cross_series_reducer` is applied to each subset of time series. + // It is not possible to reduce across different resource types, so + // this field implicitly contains `resource.type`. Fields not + // specified in `group_by_fields` are aggregated away. If + // `group_by_fields` is not specified and all the time series have + // the same resource type, then the time series are aggregated into + // a single output time series. If `cross_series_reducer` is not + // defined, this field is ignored. + GroupByFields []string `protobuf:"bytes,5,rep,name=group_by_fields,json=groupByFields,proto3" json:"group_by_fields,omitempty"` +} + +func (x *Aggregation) Reset() { + *x = Aggregation{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Aggregation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Aggregation) ProtoMessage() {} + +func (x *Aggregation) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Aggregation.ProtoReflect.Descriptor instead. +func (*Aggregation) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_common_proto_rawDescGZIP(), []int{2} +} + +func (x *Aggregation) GetAlignmentPeriod() *durationpb.Duration { + if x != nil { + return x.AlignmentPeriod + } + return nil +} + +func (x *Aggregation) GetPerSeriesAligner() Aggregation_Aligner { + if x != nil { + return x.PerSeriesAligner + } + return Aggregation_ALIGN_NONE +} + +func (x *Aggregation) GetCrossSeriesReducer() Aggregation_Reducer { + if x != nil { + return x.CrossSeriesReducer + } + return Aggregation_REDUCE_NONE +} + +func (x *Aggregation) GetGroupByFields() []string { + if x != nil { + return x.GroupByFields + } + return nil +} + +var File_google_monitoring_v3_common_proto protoreflect.FileDescriptor + +var file_google_monitoring_v3_common_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x1d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xee, 0x01, 0x0a, 0x0a, 0x54, 0x79, + 0x70, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, + 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, + 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, + 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, + 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x11, + 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0c, 0x54, + 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x35, 0x0a, 0x08, 0x65, + 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xf3, 0x07, + 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, + 0x10, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x72, + 0x69, 0x6f, 0x64, 0x12, 0x57, 0x0a, 0x12, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, + 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x52, 0x10, 0x70, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x5b, 0x0a, 0x14, + 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x64, + 0x75, 0x63, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x64, 0x75, 0x63, 0x65, 0x72, 0x52, 0x12, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x52, 0x65, 0x64, 0x75, 0x63, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x22, 0x8b, 0x03, 0x0a, 0x07, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, + 0x0a, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, + 0x0b, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x10, 0x01, 0x12, 0x0e, + 0x0a, 0x0a, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x50, 0x4f, 0x4c, + 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4e, + 0x45, 0x58, 0x54, 0x5f, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x41, + 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x10, 0x0a, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x4c, + 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x4c, 0x49, + 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x41, 0x4e, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x4c, 0x49, + 0x47, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x4c, + 0x49, 0x47, 0x4e, 0x5f, 0x53, 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x4c, 0x49, + 0x47, 0x4e, 0x5f, 0x53, 0x54, 0x44, 0x44, 0x45, 0x56, 0x10, 0x0f, 0x12, 0x14, 0x0a, 0x10, 0x41, + 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x55, 0x45, 0x10, + 0x10, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, 0x18, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x49, 0x47, + 0x4e, 0x5f, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x55, 0x45, 0x10, + 0x11, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, + 0x4e, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x39, 0x39, 0x10, 0x12, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, + 0x49, 0x47, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x39, + 0x35, 0x10, 0x13, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x50, 0x45, 0x52, + 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x35, 0x30, 0x10, 0x14, 0x12, 0x17, 0x0a, 0x13, + 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, + 0x5f, 0x30, 0x35, 0x10, 0x15, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x50, + 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, 0x22, + 0xb1, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x64, 0x75, 0x63, 0x65, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x52, + 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, + 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x4d, 0x45, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a, + 0x0a, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0e, 0x0a, + 0x0a, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0x03, 0x12, 0x0e, 0x0a, + 0x0a, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x53, 0x55, 0x4d, 0x10, 0x04, 0x12, 0x11, 0x0a, + 0x0d, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x44, 0x45, 0x56, 0x10, 0x05, + 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x55, 0x45, 0x10, 0x07, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x44, + 0x55, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, + 0x0f, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x46, 0x52, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x55, 0x45, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x52, + 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, + 0x5f, 0x39, 0x39, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, + 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x39, 0x35, 0x10, 0x0a, 0x12, + 0x18, 0x0a, 0x14, 0x52, 0x45, 0x44, 0x55, 0x43, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, + 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x35, 0x30, 0x10, 0x0b, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x44, + 0x55, 0x43, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x49, 0x4c, 0x45, 0x5f, 0x30, + 0x35, 0x10, 0x0c, 0x2a, 0x9e, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, + 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, + 0x5f, 0x47, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, + 0x53, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x50, + 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x54, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, + 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x11, + 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x51, 0x10, + 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, + 0x4e, 0x45, 0x10, 0x06, 0x2a, 0x61, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, + 0x69, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, + 0x49, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x49, 0x45, + 0x52, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x52, + 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x49, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x55, + 0x4d, 0x10, 0x02, 0x1a, 0x02, 0x18, 0x01, 0x42, 0xc6, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, + 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_monitoring_v3_common_proto_rawDescOnce sync.Once + file_google_monitoring_v3_common_proto_rawDescData = file_google_monitoring_v3_common_proto_rawDesc +) + +func file_google_monitoring_v3_common_proto_rawDescGZIP() []byte { + file_google_monitoring_v3_common_proto_rawDescOnce.Do(func() { + file_google_monitoring_v3_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_monitoring_v3_common_proto_rawDescData) + }) + return file_google_monitoring_v3_common_proto_rawDescData +} + +var file_google_monitoring_v3_common_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_google_monitoring_v3_common_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_google_monitoring_v3_common_proto_goTypes = []interface{}{ + (ComparisonType)(0), // 0: google.monitoring.v3.ComparisonType + (ServiceTier)(0), // 1: google.monitoring.v3.ServiceTier + (Aggregation_Aligner)(0), // 2: google.monitoring.v3.Aggregation.Aligner + (Aggregation_Reducer)(0), // 3: google.monitoring.v3.Aggregation.Reducer + (*TypedValue)(nil), // 4: google.monitoring.v3.TypedValue + (*TimeInterval)(nil), // 5: google.monitoring.v3.TimeInterval + (*Aggregation)(nil), // 6: google.monitoring.v3.Aggregation + (*distribution.Distribution)(nil), // 7: google.api.Distribution + (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 9: google.protobuf.Duration +} +var file_google_monitoring_v3_common_proto_depIdxs = []int32{ + 7, // 0: google.monitoring.v3.TypedValue.distribution_value:type_name -> google.api.Distribution + 8, // 1: google.monitoring.v3.TimeInterval.end_time:type_name -> google.protobuf.Timestamp + 8, // 2: google.monitoring.v3.TimeInterval.start_time:type_name -> google.protobuf.Timestamp + 9, // 3: google.monitoring.v3.Aggregation.alignment_period:type_name -> google.protobuf.Duration + 2, // 4: google.monitoring.v3.Aggregation.per_series_aligner:type_name -> google.monitoring.v3.Aggregation.Aligner + 3, // 5: google.monitoring.v3.Aggregation.cross_series_reducer:type_name -> google.monitoring.v3.Aggregation.Reducer + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_google_monitoring_v3_common_proto_init() } +func file_google_monitoring_v3_common_proto_init() { + if File_google_monitoring_v3_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_monitoring_v3_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TypedValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TimeInterval); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Aggregation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_google_monitoring_v3_common_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*TypedValue_BoolValue)(nil), + (*TypedValue_Int64Value)(nil), + (*TypedValue_DoubleValue)(nil), + (*TypedValue_StringValue)(nil), + (*TypedValue_DistributionValue)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_monitoring_v3_common_proto_rawDesc, + NumEnums: 4, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_monitoring_v3_common_proto_goTypes, + DependencyIndexes: file_google_monitoring_v3_common_proto_depIdxs, + EnumInfos: file_google_monitoring_v3_common_proto_enumTypes, + MessageInfos: file_google_monitoring_v3_common_proto_msgTypes, + }.Build() + File_google_monitoring_v3_common_proto = out.File + file_google_monitoring_v3_common_proto_rawDesc = nil + file_google_monitoring_v3_common_proto_goTypes = nil + file_google_monitoring_v3_common_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/dropped_labels.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/dropped_labels.pb.go similarity index 87% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/dropped_labels.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/dropped_labels.pb.go index f63082179b0..f4a78f6a21d 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/dropped_labels.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/dropped_labels.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/dropped_labels.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -115,20 +115,20 @@ var file_google_monitoring_v3_dropped_labels_proto_rawDesc = []byte{ 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0xca, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x02, 0x38, 0x01, 0x42, 0xcd, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x12, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, - 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, - 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, - 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, + 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group.pb.go similarity index 90% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group.pb.go index c001e17df94..f870b23a4dc 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/group.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -185,20 +185,20 @@ var file_google_monitoring_v3_group_proto_rawDesc = []byte{ 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7d, 0x12, 0x1f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0xc2, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, + 0x72, 0x6f, 0x75, 0x70, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0xc5, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0a, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, - 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, - 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, - 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, - 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, + 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group_service.pb.go similarity index 94% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group_service.pb.go index cabe69a6e1a..5d7745e9807 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/group_service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/group_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -783,44 +783,44 @@ var file_google_monitoring_v3_group_service_proto_rawDesc = []byte{ 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x7d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, + 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, + 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x7d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, - 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0xda, - 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x2d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x38, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x1c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, - 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x3a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0xda, 0x41, 0x0a, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x91, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x38, 0xda, + 0x41, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x25, 0x3a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x1c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, + 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3b, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x1a, 0x24, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x05, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0xda, 0x41, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x7e, 0x0a, 0x0b, 0x44, + 0xda, 0x41, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0x24, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x7e, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xa8, 0x01, 0x0a, 0x10, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0xda, 0x41, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x76, 0x33, + 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xa8, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, @@ -828,10 +828,10 @@ var file_google_monitoring_v3_group_service_proto_rawDesc = []byte{ 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, - 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0xda, - 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, + 0x35, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, @@ -842,20 +842,20 @@ var file_google_monitoring_v3_group_service_proto_rawDesc = []byte{ 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, - 0x61, 0x64, 0x42, 0xc9, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x61, 0x64, 0x42, 0xcc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x11, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, - 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, - 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, - 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, - 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, + 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, + 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, + 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric.pb.go similarity index 96% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric.pb.go index 23a28e07110..e414c4ab70a 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/metric.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -214,14 +214,14 @@ func (x *TimeSeries) GetMetricKind() metric.MetricDescriptor_MetricKind { if x != nil { return x.MetricKind } - return metric.MetricDescriptor_METRIC_KIND_UNSPECIFIED + return metric.MetricDescriptor_MetricKind(0) } func (x *TimeSeries) GetValueType() metric.MetricDescriptor_ValueType { if x != nil { return x.ValueType } - return metric.MetricDescriptor_VALUE_TYPE_UNSPECIFIED + return metric.MetricDescriptor_ValueType(0) } func (x *TimeSeries) GetPoints() []*Point { @@ -522,19 +522,19 @@ func (x *QueryError) GetMessage() string { // // For example, suppose the request field `text` contains: // -// text: "The quick brown fox jumps over the lazy dog." +// text: "The quick brown fox jumps over the lazy dog." // // Then the locator: // -// source: "text" -// start_position { -// line: 1 -// column: 17 -// } -// end_position { -// line: 1 -// column: 19 -// } +// source: "text" +// start_position { +// line: 1 +// column: 17 +// } +// end_position { +// line: 1 +// column: 19 +// } // // refers to the part of the text: "fox". type TextLocator struct { @@ -697,14 +697,14 @@ func (x *TimeSeriesDescriptor_ValueDescriptor) GetValueType() metric.MetricDescr if x != nil { return x.ValueType } - return metric.MetricDescriptor_VALUE_TYPE_UNSPECIFIED + return metric.MetricDescriptor_ValueType(0) } func (x *TimeSeriesDescriptor_ValueDescriptor) GetMetricKind() metric.MetricDescriptor_MetricKind { if x != nil { return x.MetricKind } - return metric.MetricDescriptor_METRIC_KIND_UNSPECIFIED + return metric.MetricDescriptor_MetricKind(0) } func (x *TimeSeriesDescriptor_ValueDescriptor) GetUnit() string { @@ -962,20 +962,20 @@ var file_google_monitoring_v3_metric_proto_rawDesc = []byte{ 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, 0x36, 0x0a, 0x08, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x42, 0xc3, 0x01, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x42, 0xc6, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0b, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, - 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, - 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, - 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, + 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, + 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric_service.pb.go similarity index 92% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric_service.pb.go index d49bc93c7c4..8008083f508 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/metric_service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/metric_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -920,11 +920,11 @@ type CreateTimeSeriesError struct { // DEPRECATED. Time series ID that resulted in the `status` error. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in google/monitoring/v3/metric_service.proto. TimeSeries *TimeSeries `protobuf:"bytes,1,opt,name=time_series,json=timeSeries,proto3" json:"time_series,omitempty"` // DEPRECATED. The status of the requested write operation for `time_series`. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in google/monitoring/v3/metric_service.proto. Status *status.Status `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } @@ -960,7 +960,7 @@ func (*CreateTimeSeriesError) Descriptor() ([]byte, []int) { return file_google_monitoring_v3_metric_service_proto_rawDescGZIP(), []int{11} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in google/monitoring/v3/metric_service.proto. func (x *CreateTimeSeriesError) GetTimeSeries() *TimeSeries { if x != nil { return x.TimeSeries @@ -968,7 +968,7 @@ func (x *CreateTimeSeriesError) GetTimeSeries() *TimeSeries { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in google/monitoring/v3/metric_service.proto. func (x *CreateTimeSeriesError) GetStatus() *status.Status { if x != nil { return x.Status @@ -1559,11 +1559,11 @@ var file_google_monitoring_v3_metric_service_proto_rawDesc = []byte{ 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, - 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0xda, 0x41, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0xcc, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x22, 0x41, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, + 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x73, 0x12, 0xcc, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, @@ -1571,12 +1571,12 @@ var file_google_monitoring_v3_metric_service_proto_rawDesc = []byte{ 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x44, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0xb8, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x44, 0xda, 0x41, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x33, + 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, + 0x2a, 0x7d, 0x12, 0xb8, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, @@ -1584,20 +1584,20 @@ var file_google_monitoring_v3_metric_service_proto_rawDesc = []byte{ 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, - 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xa0, 0x01, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, - 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x2f, 0x2a, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x39, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0x12, 0xc8, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, @@ -1605,59 +1605,59 @@ var file_google_monitoring_v3_metric_service_proto_rawDesc = []byte{ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x5b, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x22, 0x27, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, - 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x3a, + 0xda, 0x41, 0x16, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x3a, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0xda, 0x41, 0x16, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0xa0, 0x01, 0x0a, 0x16, + 0x6f, 0x72, 0x22, 0x27, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x76, 0x33, - 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, - 0x2a, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xfe, + 0x70, 0x74, 0x79, 0x22, 0x39, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x2a, 0x7d, 0x12, 0xfe, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x01, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x6e, 0x12, 0x20, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, - 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, - 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5a, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x33, 0x2f, 0x7b, - 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x6f, - 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, - 0x69, 0x65, 0x73, 0xda, 0x41, 0x19, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x2c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2c, 0x76, 0x69, 0x65, 0x77, 0x12, + 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x01, 0xda, + 0x41, 0x19, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2c, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x2c, 0x76, 0x69, 0x65, 0x77, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x6e, 0x5a, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, + 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x76, + 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, + 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x20, 0x2f, + 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x25, 0x22, 0x20, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, - 0x65, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x10, 0x6e, 0x61, 0x6d, 0x65, 0x2c, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0xae, 0x01, 0x0a, 0x17, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3e, 0xda, 0x41, 0x10, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x33, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0xae, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x4c, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x22, 0x2e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, - 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x10, 0x6e, 0x61, 0x6d, 0x65, - 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x1a, 0xda, 0x01, 0xca, + 0xda, 0x41, 0x10, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, + 0x69, 0x65, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, + 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0xda, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0xba, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, @@ -1671,72 +1671,72 @@ var file_google_monitoring_v3_metric_service_proto_rawDesc = []byte{ 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x42, 0x86, 0x08, 0x0a, 0x18, 0x63, 0x6f, - 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, - 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, - 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0xea, 0x41, 0xf0, 0x01, 0x0a, 0x2a, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, - 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3d, - 0x2a, 0x2a, 0x7d, 0x12, 0x45, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x39, 0x66, 0x6f, 0x6c, 0x64, - 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x01, 0x2a, 0x20, 0x01, 0xea, 0x41, 0xb7, 0x02, 0x0a, 0x35, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x4f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, - 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x69, 0x6e, 0x67, 0x2e, 0x77, 0x72, 0x69, 0x74, 0x65, 0x42, 0x89, 0x08, 0xea, 0x41, 0xf0, 0x01, + 0x0a, 0x2a, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3b, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, + 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x45, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3d, 0x2a, 0x2a, 0x7d, + 0x12, 0x39, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, + 0x72, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x01, 0x2a, 0x20, 0x01, + 0xea, 0x41, 0xb7, 0x02, 0x0a, 0x35, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x4f, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x7d, 0x12, 0x59, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x7d, 0x12, 0x4d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, + 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x7d, 0x12, 0x59, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x7d, 0x12, 0x01, 0x2a, 0x20, 0x01, 0xea, 0x41, 0x51, 0x0a, 0x23, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x12, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x12, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0xea, + 0x41, 0xb5, 0x01, 0x0a, 0x24, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, + 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x7d, 0x12, 0x35, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x73, 0x2f, 0x7b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x7d, 0x12, 0x4d, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, - 0x65, 0x72, 0x7d, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, - 0x2f, 0x7b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x7d, - 0x12, 0x01, 0x2a, 0x20, 0x01, 0xea, 0x41, 0x51, 0x0a, 0x23, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x7d, 0x12, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0xea, 0x41, 0xb5, 0x01, 0x0a, 0x24, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, - 0x69, 0x65, 0x73, 0x12, 0x2b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x7d, - 0x12, 0x35, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x5f, - 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x7d, 0x12, 0x29, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, - 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, - 0x73, 0x7d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, + 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x7d, 0x12, 0x29, 0x66, + 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, + 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x7d, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x33, 0x42, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, + 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/mutation_record.pb.go similarity index 85% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/mutation_record.pb.go index 0035a1cc766..fca8f5823bc 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/mutation_record.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/mutation_record.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -110,20 +110,20 @@ var file_google_monitoring_v3_mutation_record_proto_rawDesc = []byte{ 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x65, 0x64, 0x42, - 0x79, 0x42, 0xcb, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x79, 0x42, 0xce, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x13, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, - 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, - 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, - 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, - 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, + 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, + 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification.pb.go similarity index 96% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification.pb.go index 563f6cd4008..67dde79c30a 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/notification.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -138,7 +138,7 @@ type NotificationChannelDescriptor struct { // The tiers that support this notification channel; the project service tier // must be one of the supported_tiers. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in google/monitoring/v3/notification.proto. SupportedTiers []ServiceTier `protobuf:"varint,5,rep,packed,name=supported_tiers,json=supportedTiers,proto3,enum=google.monitoring.v3.ServiceTier" json:"supported_tiers,omitempty"` // The product launch stage for channels of this type. LaunchStage api.LaunchStage `protobuf:"varint,7,opt,name=launch_stage,json=launchStage,proto3,enum=google.api.LaunchStage" json:"launch_stage,omitempty"` @@ -211,7 +211,7 @@ func (x *NotificationChannelDescriptor) GetLabels() []*label.LabelDescriptor { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in google/monitoring/v3/notification.proto. func (x *NotificationChannelDescriptor) GetSupportedTiers() []ServiceTier { if x != nil { return x.SupportedTiers @@ -223,7 +223,7 @@ func (x *NotificationChannelDescriptor) GetLaunchStage() api.LaunchStage { if x != nil { return x.LaunchStage } - return api.LaunchStage_LAUNCH_STAGE_UNSPECIFIED + return api.LaunchStage(0) } // A `NotificationChannel` is a medium through which an alert is @@ -530,20 +530,21 @@ var file_google_monitoring_v3_notification_proto_rawDesc = []byte{ 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0xc9, 0x01, 0x0a, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0xcc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x11, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, - 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, - 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, + 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, + 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, + 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification_service.pb.go similarity index 94% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification_service.pb.go index 8c136d479cd..c0ce5de2d28 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/notification_service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/notification_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -1072,11 +1072,11 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, - 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0xda, 0x41, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xdd, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, + 0x22, 0x43, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x12, + 0x34, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x73, 0x12, 0xdd, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, @@ -1086,11 +1086,11 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x22, 0x45, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, 0x12, 0x36, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, - 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xc4, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, + 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, 0x12, 0x36, 0x2f, + 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xc4, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, @@ -1099,10 +1099,10 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, - 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, - 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xb5, 0x01, 0x0a, + 0x65, 0x22, 0x39, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, + 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0xb5, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, @@ -1110,11 +1110,11 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, - 0x2c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xe4, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x3b, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, @@ -1122,13 +1122,13 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x22, 0x2a, 0x2f, - 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x3a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0xda, - 0x41, 0x19, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x83, 0x02, 0x0a, 0x19, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x64, 0xda, 0x41, 0x19, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x42, 0x3a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, + 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x83, 0x02, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, @@ -1136,27 +1136,27 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x82, 0x01, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x59, 0x32, 0x41, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, - 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, - 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0xda, 0x41, - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2c, 0x6e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x12, 0xae, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x82, 0x01, 0xda, + 0x41, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2c, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x59, 0x3a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x32, 0x41, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, + 0x7d, 0x12, 0xae, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x2a, 0x2c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, - 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x12, 0xdc, 0x01, 0x0a, 0x27, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x41, 0xda, 0x41, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2e, 0x2a, 0x2c, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, + 0x2a, 0x7d, 0x12, 0xdc, 0x01, 0x0a, 0x27, 0x53, 0x65, 0x6e, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x44, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, @@ -1164,12 +1164,12 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x53, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x46, 0x22, 0x41, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, - 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x53, 0xda, 0x41, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x46, 0x3a, 0x01, 0x2a, 0x22, 0x41, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x6e, + 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x87, 0x02, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x43, 0x2e, 0x67, @@ -1181,12 +1181,12 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45, 0x22, - 0x40, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x67, 0x65, - 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, - 0x65, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xca, 0x01, 0x0a, 0x19, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45, 0x3a, 0x01, 0x2a, 0x22, 0x40, 0x2f, 0x76, 0x33, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x67, 0x65, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0xca, 0x01, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, @@ -1194,12 +1194,12 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x4a, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x38, 0x22, 0x33, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, - 0x2a, 0x7d, 0x3a, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x3a, 0x01, 0x2a, 0xda, 0x41, 0x09, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x4a, 0xda, 0x41, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x38, + 0x3a, 0x01, 0x2a, 0x22, 0x33, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x2f, 0x2a, + 0x7d, 0x3a, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, @@ -1210,20 +1210,21 @@ var file_google_monitoring_v3_notification_service_proto_rawDesc = []byte{ 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x42, 0xd0, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, + 0x72, 0x65, 0x61, 0x64, 0x42, 0xd3, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x18, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, - 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, - 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, - 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, + 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, + 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/query_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/query_service.pb.go similarity index 86% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/query_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/query_service.pb.go index 062a1787abb..4e65aa33222 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/query_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/query_service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/query_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -60,10 +60,10 @@ var file_google_monitoring_v3_query_service_proto_rawDesc = []byte{ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x26, 0x2f, 0x76, - 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x3a, 0x01, 0x2a, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x3a, 0x01, 0x2a, 0x22, + 0x26, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, + 0x73, 0x3a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, @@ -74,20 +74,20 @@ var file_google_monitoring_v3_query_service_proto_rawDesc = []byte{ 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, - 0x65, 0x61, 0x64, 0x42, 0xc9, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x65, 0x61, 0x64, 0x42, 0xcc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, - 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, - 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, - 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, - 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, + 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, + 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_google_monitoring_v3_query_service_proto_goTypes = []interface{}{ diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service.pb.go similarity index 98% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service.pb.go index de42fc917f8..12b275bb2d4 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/service.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -409,7 +409,7 @@ func (x *ServiceLevelObjective) GetCalendarPeriod() calendarperiod.CalendarPerio if x, ok := x.GetPeriod().(*ServiceLevelObjective_CalendarPeriod); ok { return x.CalendarPeriod } - return calendarperiod.CalendarPeriod_CALENDAR_PERIOD_UNSPECIFIED + return calendarperiod.CalendarPeriod(0) } func (x *ServiceLevelObjective) GetUserLabels() map[string]string { @@ -2071,21 +2071,21 @@ var file_google_monitoring_v3_service_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x77, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x6e, 0x42, 0xce, 0x01, 0x0a, 0x18, + 0x77, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x6e, 0x42, 0xd1, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, - 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, - 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, + 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, + 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, + 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/service_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service_service.pb.go similarity index 93% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/service_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service_service.pb.go index da1bce02fea..2d4f9fd3bb1 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/service_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/service_service.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/service_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -991,46 +991,46 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x19, - 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x7d, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0xda, 0x41, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x7e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3b, 0xda, 0x41, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x7e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x28, 0xda, 0x41, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2f, 0x2a, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x3d, 0x2a, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0xda, 0x41, - 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x98, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0xda, 0x41, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x76, + 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x32, 0x21, 0x2f, 0x76, - 0x33, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xda, 0x41, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x76, 0x69, 0x63, 0x65, 0x22, 0x3c, 0xda, 0x41, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, + 0x21, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x2a, 0x7d, 0x12, 0x7d, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, - 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0xfa, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x28, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, + 0x7d, 0x12, 0xfa, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, @@ -1038,14 +1038,14 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4d, - 0x22, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, - 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x73, 0x3a, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0xda, 0x41, 0x1e, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0xc1, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x74, 0xda, 0x41, 0x1e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x4d, 0x3a, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x32, 0x2f, 0x76, 0x33, 0x2f, + 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0xc1, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, @@ -1054,11 +1054,11 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, - 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, - 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, - 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0xd4, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x41, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2f, + 0x2a, 0x7d, 0x12, 0xd4, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, @@ -1067,11 +1067,11 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, 0x2f, 0x76, - 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, - 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x8c, 0x02, 0x0a, 0x1b, 0x55, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x8c, 0x02, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, @@ -1080,26 +1080,26 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x22, 0x85, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x65, 0x32, 0x4a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0xda, 0x41, - 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0xb2, 0x01, 0x0a, 0x1b, 0x44, 0x65, 0x6c, + 0x22, 0x85, 0x01, 0xda, 0x41, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, + 0x76, 0x65, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x65, 0x3a, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x32, 0x4a, 0x2f, 0x76, + 0x33, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x34, 0x2a, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, - 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0xa9, 0x01, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x41, 0xda, 0x41, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x2a, 0x32, 0x2f, 0x76, 0x33, 0x2f, 0x7b, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x2a, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, @@ -1110,21 +1110,21 @@ var file_google_monitoring_v3_service_service_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x42, 0xd5, 0x01, 0x0a, 0x18, 0x63, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x42, 0xd8, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, - 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, - 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, + 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze.pb.go new file mode 100644 index 00000000000..c619aff1f94 --- /dev/null +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze.pb.go @@ -0,0 +1,315 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/monitoring/v3/snooze.proto + +package monitoringpb + +import ( + reflect "reflect" + sync "sync" + + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// A `Snooze` will prevent any alerts from being opened, and close any that +// are already open. The `Snooze` will work on alerts that match the +// criteria defined in the `Snooze`. The `Snooze` will be active from +// `interval.start_time` through `interval.end_time`. +type Snooze struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The name of the `Snooze`. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER]/snoozes/[SNOOZE_ID] + // + // The ID of the `Snooze` will be generated by the system. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Required. This defines the criteria for applying the `Snooze`. See + // `Criteria` for more information. + Criteria *Snooze_Criteria `protobuf:"bytes,3,opt,name=criteria,proto3" json:"criteria,omitempty"` + // Required. The `Snooze` will be active from `interval.start_time` through + // `interval.end_time`. + // `interval.start_time` cannot be in the past. There is a 15 second clock + // skew to account for the time it takes for a request to reach the API from + // the UI. + Interval *TimeInterval `protobuf:"bytes,4,opt,name=interval,proto3" json:"interval,omitempty"` + // Required. A display name for the `Snooze`. This can be, at most, 512 + // unicode characters. + DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` +} + +func (x *Snooze) Reset() { + *x = Snooze{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Snooze) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Snooze) ProtoMessage() {} + +func (x *Snooze) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Snooze.ProtoReflect.Descriptor instead. +func (*Snooze) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_proto_rawDescGZIP(), []int{0} +} + +func (x *Snooze) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Snooze) GetCriteria() *Snooze_Criteria { + if x != nil { + return x.Criteria + } + return nil +} + +func (x *Snooze) GetInterval() *TimeInterval { + if x != nil { + return x.Interval + } + return nil +} + +func (x *Snooze) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +// Criteria specific to the `AlertPolicy`s that this `Snooze` applies to. The +// `Snooze` will suppress alerts that come from one of the `AlertPolicy`s +// whose names are supplied. +type Snooze_Criteria struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The specific `AlertPolicy` names for the alert that should be snoozed. + // The format is: + // + // projects/[PROJECT_ID_OR_NUMBER]/alertPolicies/[POLICY_ID] + // + // There is a limit of 10 policies per snooze. This limit is checked during + // snooze creation. + Policies []string `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty"` +} + +func (x *Snooze_Criteria) Reset() { + *x = Snooze_Criteria{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Snooze_Criteria) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Snooze_Criteria) ProtoMessage() {} + +func (x *Snooze_Criteria) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Snooze_Criteria.ProtoReflect.Descriptor instead. +func (*Snooze_Criteria) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Snooze_Criteria) GetPolicies() []string { + if x != nil { + return x.Policies + } + return nil +} + +var File_google_monitoring_v3_snooze_proto protoreflect.FileDescriptor + +var file_google_monitoring_v3_snooze_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, + 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x02, 0x0a, 0x06, 0x53, 0x6e, 0x6f, + 0x6f, 0x7a, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x08, + 0x63, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x2e, 0x43, 0x72, 0x69, + 0x74, 0x65, 0x72, 0x69, 0x61, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x63, 0x72, 0x69, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x12, 0x43, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x26, 0x0a, 0x0c, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x1a, 0x52, 0x0a, 0x08, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x12, 0x46, 0x0a, + 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, + 0x2a, 0xfa, 0x41, 0x27, 0x0a, 0x25, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x41, 0x6c, 0x65, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x3a, 0x4a, 0xea, 0x41, 0x47, 0x0a, 0x20, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, + 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x12, 0x23, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, + 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, + 0x7d, 0x42, 0xc6, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0b, + 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, + 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, + 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_google_monitoring_v3_snooze_proto_rawDescOnce sync.Once + file_google_monitoring_v3_snooze_proto_rawDescData = file_google_monitoring_v3_snooze_proto_rawDesc +) + +func file_google_monitoring_v3_snooze_proto_rawDescGZIP() []byte { + file_google_monitoring_v3_snooze_proto_rawDescOnce.Do(func() { + file_google_monitoring_v3_snooze_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_monitoring_v3_snooze_proto_rawDescData) + }) + return file_google_monitoring_v3_snooze_proto_rawDescData +} + +var file_google_monitoring_v3_snooze_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_google_monitoring_v3_snooze_proto_goTypes = []interface{}{ + (*Snooze)(nil), // 0: google.monitoring.v3.Snooze + (*Snooze_Criteria)(nil), // 1: google.monitoring.v3.Snooze.Criteria + (*TimeInterval)(nil), // 2: google.monitoring.v3.TimeInterval +} +var file_google_monitoring_v3_snooze_proto_depIdxs = []int32{ + 1, // 0: google.monitoring.v3.Snooze.criteria:type_name -> google.monitoring.v3.Snooze.Criteria + 2, // 1: google.monitoring.v3.Snooze.interval:type_name -> google.monitoring.v3.TimeInterval + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_google_monitoring_v3_snooze_proto_init() } +func file_google_monitoring_v3_snooze_proto_init() { + if File_google_monitoring_v3_snooze_proto != nil { + return + } + file_google_monitoring_v3_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_google_monitoring_v3_snooze_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Snooze); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_snooze_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Snooze_Criteria); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_monitoring_v3_snooze_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_monitoring_v3_snooze_proto_goTypes, + DependencyIndexes: file_google_monitoring_v3_snooze_proto_depIdxs, + MessageInfos: file_google_monitoring_v3_snooze_proto_msgTypes, + }.Build() + File_google_monitoring_v3_snooze_proto = out.File + file_google_monitoring_v3_snooze_proto_rawDesc = nil + file_google_monitoring_v3_snooze_proto_goTypes = nil + file_google_monitoring_v3_snooze_proto_depIdxs = nil +} diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze_service.pb.go new file mode 100644 index 00000000000..9637989da12 --- /dev/null +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/snooze_service.pb.go @@ -0,0 +1,867 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/monitoring/v3/snooze_service.proto + +package monitoringpb + +import ( + context "context" + reflect "reflect" + sync "sync" + + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The message definition for creating a `Snooze`. Users must provide the body +// of the `Snooze` to be created but must omit the `Snooze` field, `name`. +type CreateSnoozeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The + // [project](https://cloud.google.com/monitoring/api/v3#project_name) in which + // a `Snooze` should be created. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER] + Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` + // Required. The `Snooze` to create. Omit the `name` field, as it will be + // filled in by the API. + Snooze *Snooze `protobuf:"bytes,2,opt,name=snooze,proto3" json:"snooze,omitempty"` +} + +func (x *CreateSnoozeRequest) Reset() { + *x = CreateSnoozeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSnoozeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSnoozeRequest) ProtoMessage() {} + +func (x *CreateSnoozeRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateSnoozeRequest.ProtoReflect.Descriptor instead. +func (*CreateSnoozeRequest) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_service_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateSnoozeRequest) GetParent() string { + if x != nil { + return x.Parent + } + return "" +} + +func (x *CreateSnoozeRequest) GetSnooze() *Snooze { + if x != nil { + return x.Snooze + } + return nil +} + +// The message definition for listing `Snooze`s associated with the given +// `parent`, satisfying the optional `filter`. +type ListSnoozesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The + // [project](https://cloud.google.com/monitoring/api/v3#project_name) whose + // `Snooze`s should be listed. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER] + Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` + // Optional. Optional filter to restrict results to the given criteria. The + // following fields are supported. + // + // * `interval.start_time` + // * `interval.end_time` + // + // For example: + // + // ``` + // interval.start_time > "2022-03-11T00:00:00-08:00" AND + // interval.end_time < "2022-03-12T00:00:00-08:00" + // ``` + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + // Optional. The maximum number of results to return for a single query. The + // server may further constrain the maximum number of results returned in a + // single page. The value should be in the range [1, 1000]. If the value given + // is outside this range, the server will decide the number of results to be + // returned. + PageSize int32 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // Optional. The `next_page_token` from a previous call to + // `ListSnoozesRequest` to get the next page of results. + PageToken string `protobuf:"bytes,5,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` +} + +func (x *ListSnoozesRequest) Reset() { + *x = ListSnoozesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSnoozesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSnoozesRequest) ProtoMessage() {} + +func (x *ListSnoozesRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListSnoozesRequest.ProtoReflect.Descriptor instead. +func (*ListSnoozesRequest) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_service_proto_rawDescGZIP(), []int{1} +} + +func (x *ListSnoozesRequest) GetParent() string { + if x != nil { + return x.Parent + } + return "" +} + +func (x *ListSnoozesRequest) GetFilter() string { + if x != nil { + return x.Filter + } + return "" +} + +func (x *ListSnoozesRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListSnoozesRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +// The results of a successful `ListSnoozes` call, containing the matching +// `Snooze`s. +type ListSnoozesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // `Snooze`s matching this list call. + Snoozes []*Snooze `protobuf:"bytes,1,rep,name=snoozes,proto3" json:"snoozes,omitempty"` + // Page token for repeated calls to `ListSnoozes`, to fetch additional pages + // of results. If this is empty or missing, there are no more pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListSnoozesResponse) Reset() { + *x = ListSnoozesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSnoozesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSnoozesResponse) ProtoMessage() {} + +func (x *ListSnoozesResponse) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListSnoozesResponse.ProtoReflect.Descriptor instead. +func (*ListSnoozesResponse) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ListSnoozesResponse) GetSnoozes() []*Snooze { + if x != nil { + return x.Snoozes + } + return nil +} + +func (x *ListSnoozesResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// The message definition for retrieving a `Snooze`. Users must specify the +// field, `name`, which identifies the `Snooze`. +type GetSnoozeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The ID of the `Snooze` to retrieve. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER]/snoozes/[SNOOZE_ID] + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetSnoozeRequest) Reset() { + *x = GetSnoozeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSnoozeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSnoozeRequest) ProtoMessage() {} + +func (x *GetSnoozeRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSnoozeRequest.ProtoReflect.Descriptor instead. +func (*GetSnoozeRequest) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_service_proto_rawDescGZIP(), []int{3} +} + +func (x *GetSnoozeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The message definition for updating a `Snooze`. The field, `snooze.name` +// identifies the `Snooze` to be updated. The remainder of `snooze` gives the +// content the `Snooze` in question will be assigned. +// +// What fields can be updated depends on the start time and end time of the +// `Snooze`. +// +// - end time is in the past: These `Snooze`s are considered +// read-only and cannot be updated. +// - start time is in the past and end time is in the future: `display_name` +// and `interval.end_time` can be updated. +// - start time is in the future: `display_name`, `interval.start_time` and +// `interval.end_time` can be updated. +type UpdateSnoozeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The `Snooze` to update. Must have the name field present. + Snooze *Snooze `protobuf:"bytes,1,opt,name=snooze,proto3" json:"snooze,omitempty"` + // Required. The fields to update. + // + // For each field listed in `update_mask`: + // + // * If the `Snooze` object supplied in the `UpdateSnoozeRequest` has a + // value for that field, the value of the field in the existing `Snooze` + // will be set to the value of the field in the supplied `Snooze`. + // * If the field does not have a value in the supplied `Snooze`, the field + // in the existing `Snooze` is set to its default value. + // + // Fields not listed retain their existing value. + // + // The following are the field names that are accepted in `update_mask`: + // + // * `display_name` + // * `interval.start_time` + // * `interval.end_time` + // + // That said, the start time and end time of the `Snooze` determines which + // fields can legally be updated. Before attempting an update, users should + // consult the documentation for `UpdateSnoozeRequest`, which talks about + // which fields can be updated. + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` +} + +func (x *UpdateSnoozeRequest) Reset() { + *x = UpdateSnoozeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSnoozeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSnoozeRequest) ProtoMessage() {} + +func (x *UpdateSnoozeRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_snooze_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSnoozeRequest.ProtoReflect.Descriptor instead. +func (*UpdateSnoozeRequest) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_snooze_service_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateSnoozeRequest) GetSnooze() *Snooze { + if x != nil { + return x.Snooze + } + return nil +} + +func (x *UpdateSnoozeRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +var File_google_monitoring_v3_snooze_service_proto protoreflect.FileDescriptor + +var file_google_monitoring_v3_snooze_service_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x33, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, + 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x01, 0x0a, 0x13, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x40, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x12, 0x20, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, + 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x22, 0xb9, + 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x12, 0x20, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x75, 0x0a, 0x13, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x36, 0x0a, 0x07, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, + 0x52, 0x07, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0x50, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x0a, 0x20, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, + 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, + 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, + 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x32, 0x98, 0x06, 0x0a, 0x0d, 0x53, 0x6e, 0x6f, + 0x6f, 0x7a, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x0c, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x12, 0x29, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x22, 0x3f, 0xda, 0x41, 0x0d, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, + 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x06, 0x73, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x22, 0x1f, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x12, 0x94, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0xda, 0x41, 0x06, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x33, + 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x12, 0x81, 0x01, 0x0a, + 0x09, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x33, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, + 0x22, 0x2e, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, + 0x1f, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x73, 0x2f, 0x2a, 0x7d, + 0x12, 0xa4, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, + 0x65, 0x12, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x22, 0x4b, 0xda, 0x41, 0x12, 0x73, + 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, + 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x3a, 0x06, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x32, + 0x26, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x6e, 0x6f, + 0x6f, 0x7a, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, + 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x42, 0xcd, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, + 0x42, 0x12, 0x53, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, + 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_monitoring_v3_snooze_service_proto_rawDescOnce sync.Once + file_google_monitoring_v3_snooze_service_proto_rawDescData = file_google_monitoring_v3_snooze_service_proto_rawDesc +) + +func file_google_monitoring_v3_snooze_service_proto_rawDescGZIP() []byte { + file_google_monitoring_v3_snooze_service_proto_rawDescOnce.Do(func() { + file_google_monitoring_v3_snooze_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_monitoring_v3_snooze_service_proto_rawDescData) + }) + return file_google_monitoring_v3_snooze_service_proto_rawDescData +} + +var file_google_monitoring_v3_snooze_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_google_monitoring_v3_snooze_service_proto_goTypes = []interface{}{ + (*CreateSnoozeRequest)(nil), // 0: google.monitoring.v3.CreateSnoozeRequest + (*ListSnoozesRequest)(nil), // 1: google.monitoring.v3.ListSnoozesRequest + (*ListSnoozesResponse)(nil), // 2: google.monitoring.v3.ListSnoozesResponse + (*GetSnoozeRequest)(nil), // 3: google.monitoring.v3.GetSnoozeRequest + (*UpdateSnoozeRequest)(nil), // 4: google.monitoring.v3.UpdateSnoozeRequest + (*Snooze)(nil), // 5: google.monitoring.v3.Snooze + (*fieldmaskpb.FieldMask)(nil), // 6: google.protobuf.FieldMask +} +var file_google_monitoring_v3_snooze_service_proto_depIdxs = []int32{ + 5, // 0: google.monitoring.v3.CreateSnoozeRequest.snooze:type_name -> google.monitoring.v3.Snooze + 5, // 1: google.monitoring.v3.ListSnoozesResponse.snoozes:type_name -> google.monitoring.v3.Snooze + 5, // 2: google.monitoring.v3.UpdateSnoozeRequest.snooze:type_name -> google.monitoring.v3.Snooze + 6, // 3: google.monitoring.v3.UpdateSnoozeRequest.update_mask:type_name -> google.protobuf.FieldMask + 0, // 4: google.monitoring.v3.SnoozeService.CreateSnooze:input_type -> google.monitoring.v3.CreateSnoozeRequest + 1, // 5: google.monitoring.v3.SnoozeService.ListSnoozes:input_type -> google.monitoring.v3.ListSnoozesRequest + 3, // 6: google.monitoring.v3.SnoozeService.GetSnooze:input_type -> google.monitoring.v3.GetSnoozeRequest + 4, // 7: google.monitoring.v3.SnoozeService.UpdateSnooze:input_type -> google.monitoring.v3.UpdateSnoozeRequest + 5, // 8: google.monitoring.v3.SnoozeService.CreateSnooze:output_type -> google.monitoring.v3.Snooze + 2, // 9: google.monitoring.v3.SnoozeService.ListSnoozes:output_type -> google.monitoring.v3.ListSnoozesResponse + 5, // 10: google.monitoring.v3.SnoozeService.GetSnooze:output_type -> google.monitoring.v3.Snooze + 5, // 11: google.monitoring.v3.SnoozeService.UpdateSnooze:output_type -> google.monitoring.v3.Snooze + 8, // [8:12] is the sub-list for method output_type + 4, // [4:8] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_google_monitoring_v3_snooze_service_proto_init() } +func file_google_monitoring_v3_snooze_service_proto_init() { + if File_google_monitoring_v3_snooze_service_proto != nil { + return + } + file_google_monitoring_v3_snooze_proto_init() + if !protoimpl.UnsafeEnabled { + file_google_monitoring_v3_snooze_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSnoozeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_snooze_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSnoozesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_snooze_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSnoozesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_snooze_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSnoozeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_snooze_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSnoozeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_monitoring_v3_snooze_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_google_monitoring_v3_snooze_service_proto_goTypes, + DependencyIndexes: file_google_monitoring_v3_snooze_service_proto_depIdxs, + MessageInfos: file_google_monitoring_v3_snooze_service_proto_msgTypes, + }.Build() + File_google_monitoring_v3_snooze_service_proto = out.File + file_google_monitoring_v3_snooze_service_proto_rawDesc = nil + file_google_monitoring_v3_snooze_service_proto_goTypes = nil + file_google_monitoring_v3_snooze_service_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// SnoozeServiceClient is the client API for SnoozeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SnoozeServiceClient interface { + // Creates a `Snooze` that will prevent alerts, which match the provided + // criteria, from being opened. The `Snooze` applies for a specific time + // interval. + CreateSnooze(ctx context.Context, in *CreateSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) + // Lists the `Snooze`s associated with a project. Can optionally pass in + // `filter`, which specifies predicates to match `Snooze`s. + ListSnoozes(ctx context.Context, in *ListSnoozesRequest, opts ...grpc.CallOption) (*ListSnoozesResponse, error) + // Retrieves a `Snooze` by `name`. + GetSnooze(ctx context.Context, in *GetSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) + // Updates a `Snooze`, identified by its `name`, with the parameters in the + // given `Snooze` object. + UpdateSnooze(ctx context.Context, in *UpdateSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) +} + +type snoozeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSnoozeServiceClient(cc grpc.ClientConnInterface) SnoozeServiceClient { + return &snoozeServiceClient{cc} +} + +func (c *snoozeServiceClient) CreateSnooze(ctx context.Context, in *CreateSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) { + out := new(Snooze) + err := c.cc.Invoke(ctx, "/google.monitoring.v3.SnoozeService/CreateSnooze", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *snoozeServiceClient) ListSnoozes(ctx context.Context, in *ListSnoozesRequest, opts ...grpc.CallOption) (*ListSnoozesResponse, error) { + out := new(ListSnoozesResponse) + err := c.cc.Invoke(ctx, "/google.monitoring.v3.SnoozeService/ListSnoozes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *snoozeServiceClient) GetSnooze(ctx context.Context, in *GetSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) { + out := new(Snooze) + err := c.cc.Invoke(ctx, "/google.monitoring.v3.SnoozeService/GetSnooze", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *snoozeServiceClient) UpdateSnooze(ctx context.Context, in *UpdateSnoozeRequest, opts ...grpc.CallOption) (*Snooze, error) { + out := new(Snooze) + err := c.cc.Invoke(ctx, "/google.monitoring.v3.SnoozeService/UpdateSnooze", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SnoozeServiceServer is the server API for SnoozeService service. +type SnoozeServiceServer interface { + // Creates a `Snooze` that will prevent alerts, which match the provided + // criteria, from being opened. The `Snooze` applies for a specific time + // interval. + CreateSnooze(context.Context, *CreateSnoozeRequest) (*Snooze, error) + // Lists the `Snooze`s associated with a project. Can optionally pass in + // `filter`, which specifies predicates to match `Snooze`s. + ListSnoozes(context.Context, *ListSnoozesRequest) (*ListSnoozesResponse, error) + // Retrieves a `Snooze` by `name`. + GetSnooze(context.Context, *GetSnoozeRequest) (*Snooze, error) + // Updates a `Snooze`, identified by its `name`, with the parameters in the + // given `Snooze` object. + UpdateSnooze(context.Context, *UpdateSnoozeRequest) (*Snooze, error) +} + +// UnimplementedSnoozeServiceServer can be embedded to have forward compatible implementations. +type UnimplementedSnoozeServiceServer struct { +} + +func (*UnimplementedSnoozeServiceServer) CreateSnooze(context.Context, *CreateSnoozeRequest) (*Snooze, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSnooze not implemented") +} +func (*UnimplementedSnoozeServiceServer) ListSnoozes(context.Context, *ListSnoozesRequest) (*ListSnoozesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListSnoozes not implemented") +} +func (*UnimplementedSnoozeServiceServer) GetSnooze(context.Context, *GetSnoozeRequest) (*Snooze, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSnooze not implemented") +} +func (*UnimplementedSnoozeServiceServer) UpdateSnooze(context.Context, *UpdateSnoozeRequest) (*Snooze, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSnooze not implemented") +} + +func RegisterSnoozeServiceServer(s *grpc.Server, srv SnoozeServiceServer) { + s.RegisterService(&_SnoozeService_serviceDesc, srv) +} + +func _SnoozeService_CreateSnooze_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateSnoozeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SnoozeServiceServer).CreateSnooze(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.SnoozeService/CreateSnooze", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SnoozeServiceServer).CreateSnooze(ctx, req.(*CreateSnoozeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SnoozeService_ListSnoozes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListSnoozesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SnoozeServiceServer).ListSnoozes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.SnoozeService/ListSnoozes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SnoozeServiceServer).ListSnoozes(ctx, req.(*ListSnoozesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SnoozeService_GetSnooze_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSnoozeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SnoozeServiceServer).GetSnooze(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.SnoozeService/GetSnooze", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SnoozeServiceServer).GetSnooze(ctx, req.(*GetSnoozeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SnoozeService_UpdateSnooze_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSnoozeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SnoozeServiceServer).UpdateSnooze(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.SnoozeService/UpdateSnooze", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SnoozeServiceServer).UpdateSnooze(ctx, req.(*UpdateSnoozeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _SnoozeService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.monitoring.v3.SnoozeService", + HandlerType: (*SnoozeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateSnooze", + Handler: _SnoozeService_CreateSnooze_Handler, + }, + { + MethodName: "ListSnoozes", + Handler: _SnoozeService_ListSnoozes_Handler, + }, + { + MethodName: "GetSnooze", + Handler: _SnoozeService_GetSnooze_Handler, + }, + { + MethodName: "UpdateSnooze", + Handler: _SnoozeService_UpdateSnooze_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/monitoring/v3/snooze_service.proto", +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/span_context.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/span_context.pb.go similarity index 84% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/span_context.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/span_context.pb.go index 762ff15ee06..42e60c86de6 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/span_context.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/span_context.pb.go @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/span_context.proto -package monitoring +package monitoringpb import ( reflect "reflect" @@ -41,7 +41,7 @@ const ( // // It contains the name of a span with format: // -// projects/[PROJECT_ID_OR_NUMBER]/traces/[TRACE_ID]/spans/[SPAN_ID] +// projects/[PROJECT_ID_OR_NUMBER]/traces/[TRACE_ID]/spans/[SPAN_ID] type SpanContext struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -107,20 +107,21 @@ var file_google_monitoring_v3_span_context_proto_rawDesc = []byte{ 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x22, 0x2a, 0x0a, 0x0b, 0x53, 0x70, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x73, 0x70, 0x61, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0xc8, 0x01, 0x0a, 0x18, + 0x09, 0x52, 0x08, 0x73, 0x70, 0x61, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0xcb, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x10, 0x53, 0x70, 0x61, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x70, 0x69, 0x73, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, - 0x33, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, - 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, - 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, + 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, + 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime.pb.go new file mode 100644 index 00000000000..ad3cc26e1d8 --- /dev/null +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime.pb.go @@ -0,0 +1,2320 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/monitoring/v3/uptime.proto + +package monitoringpb + +import ( + reflect "reflect" + sync "sync" + + _ "google.golang.org/genproto/googleapis/api/annotations" + monitoredres "google.golang.org/genproto/googleapis/api/monitoredres" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The regions from which an Uptime check can be run. +type UptimeCheckRegion int32 + +const ( + // Default value if no region is specified. Will result in Uptime checks + // running from all regions. + UptimeCheckRegion_REGION_UNSPECIFIED UptimeCheckRegion = 0 + // Allows checks to run from locations within the United States of America. + UptimeCheckRegion_USA UptimeCheckRegion = 1 + // Allows checks to run from locations within the continent of Europe. + UptimeCheckRegion_EUROPE UptimeCheckRegion = 2 + // Allows checks to run from locations within the continent of South + // America. + UptimeCheckRegion_SOUTH_AMERICA UptimeCheckRegion = 3 + // Allows checks to run from locations within the Asia Pacific area (ex: + // Singapore). + UptimeCheckRegion_ASIA_PACIFIC UptimeCheckRegion = 4 + // Allows checks to run from locations within the western United States of + // America + UptimeCheckRegion_USA_OREGON UptimeCheckRegion = 5 + // Allows checks to run from locations within the central United States of + // America + UptimeCheckRegion_USA_IOWA UptimeCheckRegion = 6 + // Allows checks to run from locations within the eastern United States of + // America + UptimeCheckRegion_USA_VIRGINIA UptimeCheckRegion = 7 +) + +// Enum value maps for UptimeCheckRegion. +var ( + UptimeCheckRegion_name = map[int32]string{ + 0: "REGION_UNSPECIFIED", + 1: "USA", + 2: "EUROPE", + 3: "SOUTH_AMERICA", + 4: "ASIA_PACIFIC", + 5: "USA_OREGON", + 6: "USA_IOWA", + 7: "USA_VIRGINIA", + } + UptimeCheckRegion_value = map[string]int32{ + "REGION_UNSPECIFIED": 0, + "USA": 1, + "EUROPE": 2, + "SOUTH_AMERICA": 3, + "ASIA_PACIFIC": 4, + "USA_OREGON": 5, + "USA_IOWA": 6, + "USA_VIRGINIA": 7, + } +) + +func (x UptimeCheckRegion) Enum() *UptimeCheckRegion { + p := new(UptimeCheckRegion) + *p = x + return p +} + +func (x UptimeCheckRegion) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckRegion) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[0].Descriptor() +} + +func (UptimeCheckRegion) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[0] +} + +func (x UptimeCheckRegion) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckRegion.Descriptor instead. +func (UptimeCheckRegion) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{0} +} + +// The supported resource types that can be used as values of +// `group_resource.resource_type`. +// `INSTANCE` includes `gce_instance` and `aws_ec2_instance` resource types. +// The resource types `gae_app` and `uptime_url` are not valid here because +// group checks on App Engine modules and URLs are not allowed. +type GroupResourceType int32 + +const ( + // Default value (not valid). + GroupResourceType_RESOURCE_TYPE_UNSPECIFIED GroupResourceType = 0 + // A group of instances from Google Cloud Platform (GCP) or + // Amazon Web Services (AWS). + GroupResourceType_INSTANCE GroupResourceType = 1 + // A group of Amazon ELB load balancers. + GroupResourceType_AWS_ELB_LOAD_BALANCER GroupResourceType = 2 +) + +// Enum value maps for GroupResourceType. +var ( + GroupResourceType_name = map[int32]string{ + 0: "RESOURCE_TYPE_UNSPECIFIED", + 1: "INSTANCE", + 2: "AWS_ELB_LOAD_BALANCER", + } + GroupResourceType_value = map[string]int32{ + "RESOURCE_TYPE_UNSPECIFIED": 0, + "INSTANCE": 1, + "AWS_ELB_LOAD_BALANCER": 2, + } +) + +func (x GroupResourceType) Enum() *GroupResourceType { + p := new(GroupResourceType) + *p = x + return p +} + +func (x GroupResourceType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GroupResourceType) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[1].Descriptor() +} + +func (GroupResourceType) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[1] +} + +func (x GroupResourceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GroupResourceType.Descriptor instead. +func (GroupResourceType) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1} +} + +// Operational states for an internal checker. +type InternalChecker_State int32 + +const ( + // An internal checker should never be in the unspecified state. + InternalChecker_UNSPECIFIED InternalChecker_State = 0 + // The checker is being created, provisioned, and configured. A checker in + // this state can be returned by `ListInternalCheckers` or + // `GetInternalChecker`, as well as by examining the [long running + // Operation](https://cloud.google.com/apis/design/design_patterns#long_running_operations) + // that created it. + InternalChecker_CREATING InternalChecker_State = 1 + // The checker is running and available for use. A checker in this state + // can be returned by `ListInternalCheckers` or `GetInternalChecker` as + // well as by examining the [long running + // Operation](https://cloud.google.com/apis/design/design_patterns#long_running_operations) + // that created it. + // If a checker is being torn down, it is neither visible nor usable, so + // there is no "deleting" or "down" state. + InternalChecker_RUNNING InternalChecker_State = 2 +) + +// Enum value maps for InternalChecker_State. +var ( + InternalChecker_State_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "CREATING", + 2: "RUNNING", + } + InternalChecker_State_value = map[string]int32{ + "UNSPECIFIED": 0, + "CREATING": 1, + "RUNNING": 2, + } +) + +func (x InternalChecker_State) Enum() *InternalChecker_State { + p := new(InternalChecker_State) + *p = x + return p +} + +func (x InternalChecker_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (InternalChecker_State) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[2].Descriptor() +} + +func (InternalChecker_State) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[2] +} + +func (x InternalChecker_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use InternalChecker_State.Descriptor instead. +func (InternalChecker_State) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{0, 0} +} + +// What kind of checkers are available to be used by the check. +type UptimeCheckConfig_CheckerType int32 + +const ( + // The default checker type. Currently converted to `STATIC_IP_CHECKERS` + // on creation, the default conversion behavior may change in the future. + UptimeCheckConfig_CHECKER_TYPE_UNSPECIFIED UptimeCheckConfig_CheckerType = 0 + // `STATIC_IP_CHECKERS` are used for uptime checks that perform egress + // across the public internet. `STATIC_IP_CHECKERS` use the static IP + // addresses returned by `ListUptimeCheckIps`. + UptimeCheckConfig_STATIC_IP_CHECKERS UptimeCheckConfig_CheckerType = 1 + // `VPC_CHECKERS` are used for uptime checks that perform egress using + // Service Directory and private network access. When using `VPC_CHECKERS`, + // the monitored resource type must be `servicedirectory_service`. + UptimeCheckConfig_VPC_CHECKERS UptimeCheckConfig_CheckerType = 3 +) + +// Enum value maps for UptimeCheckConfig_CheckerType. +var ( + UptimeCheckConfig_CheckerType_name = map[int32]string{ + 0: "CHECKER_TYPE_UNSPECIFIED", + 1: "STATIC_IP_CHECKERS", + 3: "VPC_CHECKERS", + } + UptimeCheckConfig_CheckerType_value = map[string]int32{ + "CHECKER_TYPE_UNSPECIFIED": 0, + "STATIC_IP_CHECKERS": 1, + "VPC_CHECKERS": 3, + } +) + +func (x UptimeCheckConfig_CheckerType) Enum() *UptimeCheckConfig_CheckerType { + p := new(UptimeCheckConfig_CheckerType) + *p = x + return p +} + +func (x UptimeCheckConfig_CheckerType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_CheckerType) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[3].Descriptor() +} + +func (UptimeCheckConfig_CheckerType) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[3] +} + +func (x UptimeCheckConfig_CheckerType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_CheckerType.Descriptor instead. +func (UptimeCheckConfig_CheckerType) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 0} +} + +// The HTTP request method options. +type UptimeCheckConfig_HttpCheck_RequestMethod int32 + +const ( + // No request method specified. + UptimeCheckConfig_HttpCheck_METHOD_UNSPECIFIED UptimeCheckConfig_HttpCheck_RequestMethod = 0 + // GET request. + UptimeCheckConfig_HttpCheck_GET UptimeCheckConfig_HttpCheck_RequestMethod = 1 + // POST request. + UptimeCheckConfig_HttpCheck_POST UptimeCheckConfig_HttpCheck_RequestMethod = 2 +) + +// Enum value maps for UptimeCheckConfig_HttpCheck_RequestMethod. +var ( + UptimeCheckConfig_HttpCheck_RequestMethod_name = map[int32]string{ + 0: "METHOD_UNSPECIFIED", + 1: "GET", + 2: "POST", + } + UptimeCheckConfig_HttpCheck_RequestMethod_value = map[string]int32{ + "METHOD_UNSPECIFIED": 0, + "GET": 1, + "POST": 2, + } +) + +func (x UptimeCheckConfig_HttpCheck_RequestMethod) Enum() *UptimeCheckConfig_HttpCheck_RequestMethod { + p := new(UptimeCheckConfig_HttpCheck_RequestMethod) + *p = x + return p +} + +func (x UptimeCheckConfig_HttpCheck_RequestMethod) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_HttpCheck_RequestMethod) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[4].Descriptor() +} + +func (UptimeCheckConfig_HttpCheck_RequestMethod) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[4] +} + +func (x UptimeCheckConfig_HttpCheck_RequestMethod) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck_RequestMethod.Descriptor instead. +func (UptimeCheckConfig_HttpCheck_RequestMethod) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2, 0} +} + +// Header options corresponding to the content type of a HTTP request body. +type UptimeCheckConfig_HttpCheck_ContentType int32 + +const ( + // No content type specified. + UptimeCheckConfig_HttpCheck_TYPE_UNSPECIFIED UptimeCheckConfig_HttpCheck_ContentType = 0 + // `body` is in URL-encoded form. Equivalent to setting the `Content-Type` + // to `application/x-www-form-urlencoded` in the HTTP request. + UptimeCheckConfig_HttpCheck_URL_ENCODED UptimeCheckConfig_HttpCheck_ContentType = 1 + // `body` is in `custom_content_type` form. Equivalent to setting the + // `Content-Type` to the contents of `custom_content_type` in the HTTP + // request. + UptimeCheckConfig_HttpCheck_USER_PROVIDED UptimeCheckConfig_HttpCheck_ContentType = 2 +) + +// Enum value maps for UptimeCheckConfig_HttpCheck_ContentType. +var ( + UptimeCheckConfig_HttpCheck_ContentType_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "URL_ENCODED", + 2: "USER_PROVIDED", + } + UptimeCheckConfig_HttpCheck_ContentType_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "URL_ENCODED": 1, + "USER_PROVIDED": 2, + } +) + +func (x UptimeCheckConfig_HttpCheck_ContentType) Enum() *UptimeCheckConfig_HttpCheck_ContentType { + p := new(UptimeCheckConfig_HttpCheck_ContentType) + *p = x + return p +} + +func (x UptimeCheckConfig_HttpCheck_ContentType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_HttpCheck_ContentType) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[5].Descriptor() +} + +func (UptimeCheckConfig_HttpCheck_ContentType) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[5] +} + +func (x UptimeCheckConfig_HttpCheck_ContentType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck_ContentType.Descriptor instead. +func (UptimeCheckConfig_HttpCheck_ContentType) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2, 1} +} + +// An HTTP status code class. +type UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass int32 + +const ( + // Default value that matches no status codes. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_UNSPECIFIED UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 0 + // The class of status codes between 100 and 199. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_1XX UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 100 + // The class of status codes between 200 and 299. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_2XX UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 200 + // The class of status codes between 300 and 399. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_3XX UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 300 + // The class of status codes between 400 and 499. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_4XX UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 400 + // The class of status codes between 500 and 599. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_5XX UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 500 + // The class of all status codes. + UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_ANY UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass = 1000 +) + +// Enum value maps for UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass. +var ( + UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_name = map[int32]string{ + 0: "STATUS_CLASS_UNSPECIFIED", + 100: "STATUS_CLASS_1XX", + 200: "STATUS_CLASS_2XX", + 300: "STATUS_CLASS_3XX", + 400: "STATUS_CLASS_4XX", + 500: "STATUS_CLASS_5XX", + 1000: "STATUS_CLASS_ANY", + } + UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_value = map[string]int32{ + "STATUS_CLASS_UNSPECIFIED": 0, + "STATUS_CLASS_1XX": 100, + "STATUS_CLASS_2XX": 200, + "STATUS_CLASS_3XX": 300, + "STATUS_CLASS_4XX": 400, + "STATUS_CLASS_5XX": 500, + "STATUS_CLASS_ANY": 1000, + } +) + +func (x UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) Enum() *UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass { + p := new(UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) + *p = x + return p +} + +func (x UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[6].Descriptor() +} + +func (UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[6] +} + +func (x UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass.Descriptor instead. +func (UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2, 1, 0} +} + +// Options to perform content matching. +type UptimeCheckConfig_ContentMatcher_ContentMatcherOption int32 + +const ( + // No content matcher type specified (maintained for backward + // compatibility, but deprecated for future use). + // Treated as `CONTAINS_STRING`. + UptimeCheckConfig_ContentMatcher_CONTENT_MATCHER_OPTION_UNSPECIFIED UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 0 + // Selects substring matching. The match succeeds if the output contains + // the `content` string. This is the default value for checks without + // a `matcher` option, or where the value of `matcher` is + // `CONTENT_MATCHER_OPTION_UNSPECIFIED`. + UptimeCheckConfig_ContentMatcher_CONTAINS_STRING UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 1 + // Selects negation of substring matching. The match succeeds if the + // output does _NOT_ contain the `content` string. + UptimeCheckConfig_ContentMatcher_NOT_CONTAINS_STRING UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 2 + // Selects regular-expression matching. The match succeeds if the output + // matches the regular expression specified in the `content` string. + // Regex matching is only supported for HTTP/HTTPS checks. + UptimeCheckConfig_ContentMatcher_MATCHES_REGEX UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 3 + // Selects negation of regular-expression matching. The match succeeds if + // the output does _NOT_ match the regular expression specified in the + // `content` string. Regex matching is only supported for HTTP/HTTPS + // checks. + UptimeCheckConfig_ContentMatcher_NOT_MATCHES_REGEX UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 4 + // Selects JSONPath matching. See `JsonPathMatcher` for details on when + // the match succeeds. JSONPath matching is only supported for HTTP/HTTPS + // checks. + UptimeCheckConfig_ContentMatcher_MATCHES_JSON_PATH UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 5 + // Selects JSONPath matching. See `JsonPathMatcher` for details on when + // the match succeeds. Succeeds when output does _NOT_ match as specified. + // JSONPath is only supported for HTTP/HTTPS checks. + UptimeCheckConfig_ContentMatcher_NOT_MATCHES_JSON_PATH UptimeCheckConfig_ContentMatcher_ContentMatcherOption = 6 +) + +// Enum value maps for UptimeCheckConfig_ContentMatcher_ContentMatcherOption. +var ( + UptimeCheckConfig_ContentMatcher_ContentMatcherOption_name = map[int32]string{ + 0: "CONTENT_MATCHER_OPTION_UNSPECIFIED", + 1: "CONTAINS_STRING", + 2: "NOT_CONTAINS_STRING", + 3: "MATCHES_REGEX", + 4: "NOT_MATCHES_REGEX", + 5: "MATCHES_JSON_PATH", + 6: "NOT_MATCHES_JSON_PATH", + } + UptimeCheckConfig_ContentMatcher_ContentMatcherOption_value = map[string]int32{ + "CONTENT_MATCHER_OPTION_UNSPECIFIED": 0, + "CONTAINS_STRING": 1, + "NOT_CONTAINS_STRING": 2, + "MATCHES_REGEX": 3, + "NOT_MATCHES_REGEX": 4, + "MATCHES_JSON_PATH": 5, + "NOT_MATCHES_JSON_PATH": 6, + } +) + +func (x UptimeCheckConfig_ContentMatcher_ContentMatcherOption) Enum() *UptimeCheckConfig_ContentMatcher_ContentMatcherOption { + p := new(UptimeCheckConfig_ContentMatcher_ContentMatcherOption) + *p = x + return p +} + +func (x UptimeCheckConfig_ContentMatcher_ContentMatcherOption) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_ContentMatcher_ContentMatcherOption) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[7].Descriptor() +} + +func (UptimeCheckConfig_ContentMatcher_ContentMatcherOption) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[7] +} + +func (x UptimeCheckConfig_ContentMatcher_ContentMatcherOption) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_ContentMatcher_ContentMatcherOption.Descriptor instead. +func (UptimeCheckConfig_ContentMatcher_ContentMatcherOption) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 4, 0} +} + +// Options to perform JSONPath content matching. +type UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption int32 + +const ( + // No JSONPath matcher type specified (not valid). + UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JSON_PATH_MATCHER_OPTION_UNSPECIFIED UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption = 0 + // Selects 'exact string' matching. The match succeeds if the content at + // the `json_path` within the output is exactly the same as the + // `content` string. + UptimeCheckConfig_ContentMatcher_JsonPathMatcher_EXACT_MATCH UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption = 1 + // Selects regular-expression matching. The match succeeds if the + // content at the `json_path` within the output matches the regular + // expression specified in the `content` string. + UptimeCheckConfig_ContentMatcher_JsonPathMatcher_REGEX_MATCH UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption = 2 +) + +// Enum value maps for UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption. +var ( + UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption_name = map[int32]string{ + 0: "JSON_PATH_MATCHER_OPTION_UNSPECIFIED", + 1: "EXACT_MATCH", + 2: "REGEX_MATCH", + } + UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption_value = map[string]int32{ + "JSON_PATH_MATCHER_OPTION_UNSPECIFIED": 0, + "EXACT_MATCH": 1, + "REGEX_MATCH": 2, + } +) + +func (x UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) Enum() *UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption { + p := new(UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) + *p = x + return p +} + +func (x UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) Descriptor() protoreflect.EnumDescriptor { + return file_google_monitoring_v3_uptime_proto_enumTypes[8].Descriptor() +} + +func (UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) Type() protoreflect.EnumType { + return &file_google_monitoring_v3_uptime_proto_enumTypes[8] +} + +func (x UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption.Descriptor instead. +func (UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption) EnumDescriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 4, 0, 0} +} + +// An internal checker allows Uptime checks to run on private/internal GCP +// resources. +// +// Deprecated: Marked as deprecated in google/monitoring/v3/uptime.proto. +type InternalChecker struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A unique resource name for this InternalChecker. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER]/internalCheckers/[INTERNAL_CHECKER_ID] + // + // `[PROJECT_ID_OR_NUMBER]` is the Cloud Monitoring Metrics Scope project for + // the Uptime check config associated with the internal checker. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The checker's human-readable name. The display name + // should be unique within a Cloud Monitoring Metrics Scope in order to make + // it easier to identify; however, uniqueness is not enforced. + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + // The [GCP VPC network](https://cloud.google.com/vpc/docs/vpc) where the + // internal resource lives (ex: "default"). + Network string `protobuf:"bytes,3,opt,name=network,proto3" json:"network,omitempty"` + // The GCP zone the Uptime check should egress from. Only respected for + // internal Uptime checks, where internal_network is specified. + GcpZone string `protobuf:"bytes,4,opt,name=gcp_zone,json=gcpZone,proto3" json:"gcp_zone,omitempty"` + // The GCP project ID where the internal checker lives. Not necessary + // the same as the Metrics Scope project. + PeerProjectId string `protobuf:"bytes,6,opt,name=peer_project_id,json=peerProjectId,proto3" json:"peer_project_id,omitempty"` + // The current operational state of the internal checker. + State InternalChecker_State `protobuf:"varint,7,opt,name=state,proto3,enum=google.monitoring.v3.InternalChecker_State" json:"state,omitempty"` +} + +func (x *InternalChecker) Reset() { + *x = InternalChecker{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InternalChecker) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InternalChecker) ProtoMessage() {} + +func (x *InternalChecker) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InternalChecker.ProtoReflect.Descriptor instead. +func (*InternalChecker) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{0} +} + +func (x *InternalChecker) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *InternalChecker) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *InternalChecker) GetNetwork() string { + if x != nil { + return x.Network + } + return "" +} + +func (x *InternalChecker) GetGcpZone() string { + if x != nil { + return x.GcpZone + } + return "" +} + +func (x *InternalChecker) GetPeerProjectId() string { + if x != nil { + return x.PeerProjectId + } + return "" +} + +func (x *InternalChecker) GetState() InternalChecker_State { + if x != nil { + return x.State + } + return InternalChecker_UNSPECIFIED +} + +// This message configures which resources and services to monitor for +// availability. +type UptimeCheckConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A unique resource name for this Uptime check configuration. The format is: + // + // projects/[PROJECT_ID_OR_NUMBER]/uptimeCheckConfigs/[UPTIME_CHECK_ID] + // + // `[PROJECT_ID_OR_NUMBER]` is the Workspace host project associated with the + // Uptime check. + // + // This field should be omitted when creating the Uptime check configuration; + // on create, the resource name is assigned by the server and included in the + // response. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // A human-friendly name for the Uptime check configuration. The display name + // should be unique within a Cloud Monitoring Workspace in order to make it + // easier to identify; however, uniqueness is not enforced. Required. + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + // The resource the check is checking. Required. + // + // Types that are assignable to Resource: + // *UptimeCheckConfig_MonitoredResource + // *UptimeCheckConfig_ResourceGroup_ + Resource isUptimeCheckConfig_Resource `protobuf_oneof:"resource"` + // The type of Uptime check request. + // + // Types that are assignable to CheckRequestType: + // *UptimeCheckConfig_HttpCheck_ + // *UptimeCheckConfig_TcpCheck_ + CheckRequestType isUptimeCheckConfig_CheckRequestType `protobuf_oneof:"check_request_type"` + // How often, in seconds, the Uptime check is performed. + // Currently, the only supported values are `60s` (1 minute), `300s` + // (5 minutes), `600s` (10 minutes), and `900s` (15 minutes). Optional, + // defaults to `60s`. + Period *durationpb.Duration `protobuf:"bytes,7,opt,name=period,proto3" json:"period,omitempty"` + // The maximum amount of time to wait for the request to complete (must be + // between 1 and 60 seconds). Required. + Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` + // The content that is expected to appear in the data returned by the target + // server against which the check is run. Currently, only the first entry + // in the `content_matchers` list is supported, and additional entries will + // be ignored. This field is optional and should only be specified if a + // content match is required as part of the/ Uptime check. + ContentMatchers []*UptimeCheckConfig_ContentMatcher `protobuf:"bytes,9,rep,name=content_matchers,json=contentMatchers,proto3" json:"content_matchers,omitempty"` + // The type of checkers to use to execute the Uptime check. + CheckerType UptimeCheckConfig_CheckerType `protobuf:"varint,17,opt,name=checker_type,json=checkerType,proto3,enum=google.monitoring.v3.UptimeCheckConfig_CheckerType" json:"checker_type,omitempty"` + // The list of regions from which the check will be run. + // Some regions contain one location, and others contain more than one. + // If this field is specified, enough regions must be provided to include a + // minimum of 3 locations. Not specifying this field will result in Uptime + // checks running from all available regions. + SelectedRegions []UptimeCheckRegion `protobuf:"varint,10,rep,packed,name=selected_regions,json=selectedRegions,proto3,enum=google.monitoring.v3.UptimeCheckRegion" json:"selected_regions,omitempty"` + // If this is `true`, then checks are made only from the 'internal_checkers'. + // If it is `false`, then checks are made only from the 'selected_regions'. + // It is an error to provide 'selected_regions' when is_internal is `true`, + // or to provide 'internal_checkers' when is_internal is `false`. + // + // Deprecated: Marked as deprecated in google/monitoring/v3/uptime.proto. + IsInternal bool `protobuf:"varint,15,opt,name=is_internal,json=isInternal,proto3" json:"is_internal,omitempty"` + // The internal checkers that this check will egress from. If `is_internal` is + // `true` and this list is empty, the check will egress from all the + // InternalCheckers configured for the project that owns this + // `UptimeCheckConfig`. + // + // Deprecated: Marked as deprecated in google/monitoring/v3/uptime.proto. + InternalCheckers []*InternalChecker `protobuf:"bytes,14,rep,name=internal_checkers,json=internalCheckers,proto3" json:"internal_checkers,omitempty"` + // User-supplied key/value data to be used for organizing and + // identifying the `UptimeCheckConfig` objects. + // + // The field can contain up to 64 entries. Each key and value is limited to + // 63 Unicode characters or 128 bytes, whichever is smaller. Labels and + // values can contain only lowercase letters, numerals, underscores, and + // dashes. Keys must begin with a letter. + UserLabels map[string]string `protobuf:"bytes,20,rep,name=user_labels,json=userLabels,proto3" json:"user_labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *UptimeCheckConfig) Reset() { + *x = UptimeCheckConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig) ProtoMessage() {} + +func (x *UptimeCheckConfig) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1} +} + +func (x *UptimeCheckConfig) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UptimeCheckConfig) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (m *UptimeCheckConfig) GetResource() isUptimeCheckConfig_Resource { + if m != nil { + return m.Resource + } + return nil +} + +func (x *UptimeCheckConfig) GetMonitoredResource() *monitoredres.MonitoredResource { + if x, ok := x.GetResource().(*UptimeCheckConfig_MonitoredResource); ok { + return x.MonitoredResource + } + return nil +} + +func (x *UptimeCheckConfig) GetResourceGroup() *UptimeCheckConfig_ResourceGroup { + if x, ok := x.GetResource().(*UptimeCheckConfig_ResourceGroup_); ok { + return x.ResourceGroup + } + return nil +} + +func (m *UptimeCheckConfig) GetCheckRequestType() isUptimeCheckConfig_CheckRequestType { + if m != nil { + return m.CheckRequestType + } + return nil +} + +func (x *UptimeCheckConfig) GetHttpCheck() *UptimeCheckConfig_HttpCheck { + if x, ok := x.GetCheckRequestType().(*UptimeCheckConfig_HttpCheck_); ok { + return x.HttpCheck + } + return nil +} + +func (x *UptimeCheckConfig) GetTcpCheck() *UptimeCheckConfig_TcpCheck { + if x, ok := x.GetCheckRequestType().(*UptimeCheckConfig_TcpCheck_); ok { + return x.TcpCheck + } + return nil +} + +func (x *UptimeCheckConfig) GetPeriod() *durationpb.Duration { + if x != nil { + return x.Period + } + return nil +} + +func (x *UptimeCheckConfig) GetTimeout() *durationpb.Duration { + if x != nil { + return x.Timeout + } + return nil +} + +func (x *UptimeCheckConfig) GetContentMatchers() []*UptimeCheckConfig_ContentMatcher { + if x != nil { + return x.ContentMatchers + } + return nil +} + +func (x *UptimeCheckConfig) GetCheckerType() UptimeCheckConfig_CheckerType { + if x != nil { + return x.CheckerType + } + return UptimeCheckConfig_CHECKER_TYPE_UNSPECIFIED +} + +func (x *UptimeCheckConfig) GetSelectedRegions() []UptimeCheckRegion { + if x != nil { + return x.SelectedRegions + } + return nil +} + +// Deprecated: Marked as deprecated in google/monitoring/v3/uptime.proto. +func (x *UptimeCheckConfig) GetIsInternal() bool { + if x != nil { + return x.IsInternal + } + return false +} + +// Deprecated: Marked as deprecated in google/monitoring/v3/uptime.proto. +func (x *UptimeCheckConfig) GetInternalCheckers() []*InternalChecker { + if x != nil { + return x.InternalCheckers + } + return nil +} + +func (x *UptimeCheckConfig) GetUserLabels() map[string]string { + if x != nil { + return x.UserLabels + } + return nil +} + +type isUptimeCheckConfig_Resource interface { + isUptimeCheckConfig_Resource() +} + +type UptimeCheckConfig_MonitoredResource struct { + // The [monitored + // resource](https://cloud.google.com/monitoring/api/resources) associated + // with the configuration. + // The following monitored resource types are valid for this field: + // `uptime_url`, + // `gce_instance`, + // `gae_app`, + // `aws_ec2_instance`, + // `aws_elb_load_balancer` + // `k8s_service` + // `servicedirectory_service` + // `cloud_run_revision` + MonitoredResource *monitoredres.MonitoredResource `protobuf:"bytes,3,opt,name=monitored_resource,json=monitoredResource,proto3,oneof"` +} + +type UptimeCheckConfig_ResourceGroup_ struct { + // The group resource associated with the configuration. + ResourceGroup *UptimeCheckConfig_ResourceGroup `protobuf:"bytes,4,opt,name=resource_group,json=resourceGroup,proto3,oneof"` +} + +func (*UptimeCheckConfig_MonitoredResource) isUptimeCheckConfig_Resource() {} + +func (*UptimeCheckConfig_ResourceGroup_) isUptimeCheckConfig_Resource() {} + +type isUptimeCheckConfig_CheckRequestType interface { + isUptimeCheckConfig_CheckRequestType() +} + +type UptimeCheckConfig_HttpCheck_ struct { + // Contains information needed to make an HTTP or HTTPS check. + HttpCheck *UptimeCheckConfig_HttpCheck `protobuf:"bytes,5,opt,name=http_check,json=httpCheck,proto3,oneof"` +} + +type UptimeCheckConfig_TcpCheck_ struct { + // Contains information needed to make a TCP check. + TcpCheck *UptimeCheckConfig_TcpCheck `protobuf:"bytes,6,opt,name=tcp_check,json=tcpCheck,proto3,oneof"` +} + +func (*UptimeCheckConfig_HttpCheck_) isUptimeCheckConfig_CheckRequestType() {} + +func (*UptimeCheckConfig_TcpCheck_) isUptimeCheckConfig_CheckRequestType() {} + +// Contains the region, location, and list of IP +// addresses where checkers in the location run from. +type UptimeCheckIp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A broad region category in which the IP address is located. + Region UptimeCheckRegion `protobuf:"varint,1,opt,name=region,proto3,enum=google.monitoring.v3.UptimeCheckRegion" json:"region,omitempty"` + // A more specific location within the region that typically encodes + // a particular city/town/metro (and its containing state/province or country) + // within the broader umbrella region category. + Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` + // The IP address from which the Uptime check originates. This is a fully + // specified IP address (not an IP address range). Most IP addresses, as of + // this publication, are in IPv4 format; however, one should not rely on the + // IP addresses being in IPv4 format indefinitely, and should support + // interpreting this field in either IPv4 or IPv6 format. + IpAddress string `protobuf:"bytes,3,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` +} + +func (x *UptimeCheckIp) Reset() { + *x = UptimeCheckIp{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckIp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckIp) ProtoMessage() {} + +func (x *UptimeCheckIp) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckIp.ProtoReflect.Descriptor instead. +func (*UptimeCheckIp) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{2} +} + +func (x *UptimeCheckIp) GetRegion() UptimeCheckRegion { + if x != nil { + return x.Region + } + return UptimeCheckRegion_REGION_UNSPECIFIED +} + +func (x *UptimeCheckIp) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +func (x *UptimeCheckIp) GetIpAddress() string { + if x != nil { + return x.IpAddress + } + return "" +} + +// The resource submessage for group checks. It can be used instead of a +// monitored resource, when multiple resources are being monitored. +type UptimeCheckConfig_ResourceGroup struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The group of resources being monitored. Should be only the `[GROUP_ID]`, + // and not the full-path + // `projects/[PROJECT_ID_OR_NUMBER]/groups/[GROUP_ID]`. + GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + // The resource type of the group members. + ResourceType GroupResourceType `protobuf:"varint,2,opt,name=resource_type,json=resourceType,proto3,enum=google.monitoring.v3.GroupResourceType" json:"resource_type,omitempty"` +} + +func (x *UptimeCheckConfig_ResourceGroup) Reset() { + *x = UptimeCheckConfig_ResourceGroup{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_ResourceGroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_ResourceGroup) ProtoMessage() {} + +func (x *UptimeCheckConfig_ResourceGroup) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_ResourceGroup.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_ResourceGroup) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *UptimeCheckConfig_ResourceGroup) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *UptimeCheckConfig_ResourceGroup) GetResourceType() GroupResourceType { + if x != nil { + return x.ResourceType + } + return GroupResourceType_RESOURCE_TYPE_UNSPECIFIED +} + +// Information involved in sending ICMP pings alongside public HTTP/TCP +// checks. For HTTP, the pings are performed for each part of the redirect +// chain. +type UptimeCheckConfig_PingConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Number of ICMP pings. A maximum of 3 ICMP pings is currently supported. + PingsCount int32 `protobuf:"varint,1,opt,name=pings_count,json=pingsCount,proto3" json:"pings_count,omitempty"` +} + +func (x *UptimeCheckConfig_PingConfig) Reset() { + *x = UptimeCheckConfig_PingConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_PingConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_PingConfig) ProtoMessage() {} + +func (x *UptimeCheckConfig_PingConfig) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_PingConfig.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_PingConfig) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 1} +} + +func (x *UptimeCheckConfig_PingConfig) GetPingsCount() int32 { + if x != nil { + return x.PingsCount + } + return 0 +} + +// Information involved in an HTTP/HTTPS Uptime check request. +type UptimeCheckConfig_HttpCheck struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The HTTP request method to use for the check. If set to + // `METHOD_UNSPECIFIED` then `request_method` defaults to `GET`. + RequestMethod UptimeCheckConfig_HttpCheck_RequestMethod `protobuf:"varint,8,opt,name=request_method,json=requestMethod,proto3,enum=google.monitoring.v3.UptimeCheckConfig_HttpCheck_RequestMethod" json:"request_method,omitempty"` + // If `true`, use HTTPS instead of HTTP to run the check. + UseSsl bool `protobuf:"varint,1,opt,name=use_ssl,json=useSsl,proto3" json:"use_ssl,omitempty"` + // Optional (defaults to "/"). The path to the page against which to run + // the check. Will be combined with the `host` (specified within the + // `monitored_resource`) and `port` to construct the full URL. If the + // provided path does not begin with "/", a "/" will be prepended + // automatically. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // Optional (defaults to 80 when `use_ssl` is `false`, and 443 when + // `use_ssl` is `true`). The TCP port on the HTTP server against which to + // run the check. Will be combined with host (specified within the + // `monitored_resource`) and `path` to construct the full URL. + Port int32 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"` + // The authentication information. Optional when creating an HTTP check; + // defaults to empty. + AuthInfo *UptimeCheckConfig_HttpCheck_BasicAuthentication `protobuf:"bytes,4,opt,name=auth_info,json=authInfo,proto3" json:"auth_info,omitempty"` + // Boolean specifying whether to encrypt the header information. + // Encryption should be specified for any headers related to authentication + // that you do not wish to be seen when retrieving the configuration. The + // server will be responsible for encrypting the headers. + // On Get/List calls, if `mask_headers` is set to `true` then the headers + // will be obscured with `******.` + MaskHeaders bool `protobuf:"varint,5,opt,name=mask_headers,json=maskHeaders,proto3" json:"mask_headers,omitempty"` + // The list of headers to send as part of the Uptime check request. + // If two headers have the same key and different values, they should + // be entered as a single header, with the value being a comma-separated + // list of all the desired values as described at + // https://www.w3.org/Protocols/rfc2616/rfc2616.txt (page 31). + // Entering two separate headers with the same key in a Create call will + // cause the first to be overwritten by the second. + // The maximum number of headers allowed is 100. + Headers map[string]string `protobuf:"bytes,6,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The content type header to use for the check. The following + // configurations result in errors: + // 1. Content type is specified in both the `headers` field and the + // `content_type` field. + // 2. Request method is `GET` and `content_type` is not `TYPE_UNSPECIFIED` + // 3. Request method is `POST` and `content_type` is `TYPE_UNSPECIFIED`. + // 4. Request method is `POST` and a "Content-Type" header is provided via + // `headers` field. The `content_type` field should be used instead. + ContentType UptimeCheckConfig_HttpCheck_ContentType `protobuf:"varint,9,opt,name=content_type,json=contentType,proto3,enum=google.monitoring.v3.UptimeCheckConfig_HttpCheck_ContentType" json:"content_type,omitempty"` + // A user provided content type header to use for the check. The invalid + // configurations outlined in the `content_type` field apply to + // `custom_content_type`, as well as the following: + // 1. `content_type` is `URL_ENCODED` and `custom_content_type` is set. + // 2. `content_type` is `USER_PROVIDED` and `custom_content_type` is not + // set. + CustomContentType string `protobuf:"bytes,13,opt,name=custom_content_type,json=customContentType,proto3" json:"custom_content_type,omitempty"` + // Boolean specifying whether to include SSL certificate validation as a + // part of the Uptime check. Only applies to checks where + // `monitored_resource` is set to `uptime_url`. If `use_ssl` is `false`, + // setting `validate_ssl` to `true` has no effect. + ValidateSsl bool `protobuf:"varint,7,opt,name=validate_ssl,json=validateSsl,proto3" json:"validate_ssl,omitempty"` + // The request body associated with the HTTP POST request. If `content_type` + // is `URL_ENCODED`, the body passed in must be URL-encoded. Users can + // provide a `Content-Length` header via the `headers` field or the API will + // do so. If the `request_method` is `GET` and `body` is not empty, the API + // will return an error. The maximum byte size is 1 megabyte. + // + // Note: If client libraries aren't used (which performs the conversion + // automatically) base64 encode your `body` data since the field is of + // `bytes` type. + Body []byte `protobuf:"bytes,10,opt,name=body,proto3" json:"body,omitempty"` + // If present, the check will only pass if the HTTP response status code is + // in this set of status codes. If empty, the HTTP status code will only + // pass if the HTTP status code is 200-299. + AcceptedResponseStatusCodes []*UptimeCheckConfig_HttpCheck_ResponseStatusCode `protobuf:"bytes,11,rep,name=accepted_response_status_codes,json=acceptedResponseStatusCodes,proto3" json:"accepted_response_status_codes,omitempty"` + // Contains information needed to add pings to an HTTP check. + PingConfig *UptimeCheckConfig_PingConfig `protobuf:"bytes,12,opt,name=ping_config,json=pingConfig,proto3" json:"ping_config,omitempty"` +} + +func (x *UptimeCheckConfig_HttpCheck) Reset() { + *x = UptimeCheckConfig_HttpCheck{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_HttpCheck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_HttpCheck) ProtoMessage() {} + +func (x *UptimeCheckConfig_HttpCheck) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_HttpCheck) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2} +} + +func (x *UptimeCheckConfig_HttpCheck) GetRequestMethod() UptimeCheckConfig_HttpCheck_RequestMethod { + if x != nil { + return x.RequestMethod + } + return UptimeCheckConfig_HttpCheck_METHOD_UNSPECIFIED +} + +func (x *UptimeCheckConfig_HttpCheck) GetUseSsl() bool { + if x != nil { + return x.UseSsl + } + return false +} + +func (x *UptimeCheckConfig_HttpCheck) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *UptimeCheckConfig_HttpCheck) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *UptimeCheckConfig_HttpCheck) GetAuthInfo() *UptimeCheckConfig_HttpCheck_BasicAuthentication { + if x != nil { + return x.AuthInfo + } + return nil +} + +func (x *UptimeCheckConfig_HttpCheck) GetMaskHeaders() bool { + if x != nil { + return x.MaskHeaders + } + return false +} + +func (x *UptimeCheckConfig_HttpCheck) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *UptimeCheckConfig_HttpCheck) GetContentType() UptimeCheckConfig_HttpCheck_ContentType { + if x != nil { + return x.ContentType + } + return UptimeCheckConfig_HttpCheck_TYPE_UNSPECIFIED +} + +func (x *UptimeCheckConfig_HttpCheck) GetCustomContentType() string { + if x != nil { + return x.CustomContentType + } + return "" +} + +func (x *UptimeCheckConfig_HttpCheck) GetValidateSsl() bool { + if x != nil { + return x.ValidateSsl + } + return false +} + +func (x *UptimeCheckConfig_HttpCheck) GetBody() []byte { + if x != nil { + return x.Body + } + return nil +} + +func (x *UptimeCheckConfig_HttpCheck) GetAcceptedResponseStatusCodes() []*UptimeCheckConfig_HttpCheck_ResponseStatusCode { + if x != nil { + return x.AcceptedResponseStatusCodes + } + return nil +} + +func (x *UptimeCheckConfig_HttpCheck) GetPingConfig() *UptimeCheckConfig_PingConfig { + if x != nil { + return x.PingConfig + } + return nil +} + +// Information required for a TCP Uptime check request. +type UptimeCheckConfig_TcpCheck struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The TCP port on the server against which to run the check. Will be + // combined with host (specified within the `monitored_resource`) to + // construct the full URL. Required. + Port int32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` + // Contains information needed to add pings to a TCP check. + PingConfig *UptimeCheckConfig_PingConfig `protobuf:"bytes,2,opt,name=ping_config,json=pingConfig,proto3" json:"ping_config,omitempty"` +} + +func (x *UptimeCheckConfig_TcpCheck) Reset() { + *x = UptimeCheckConfig_TcpCheck{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_TcpCheck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_TcpCheck) ProtoMessage() {} + +func (x *UptimeCheckConfig_TcpCheck) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_TcpCheck.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_TcpCheck) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 3} +} + +func (x *UptimeCheckConfig_TcpCheck) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *UptimeCheckConfig_TcpCheck) GetPingConfig() *UptimeCheckConfig_PingConfig { + if x != nil { + return x.PingConfig + } + return nil +} + +// Optional. Used to perform content matching. This allows matching based on +// substrings and regular expressions, together with their negations. Only the +// first 4 MB of an HTTP or HTTPS check's response (and the first +// 1 MB of a TCP check's response) are examined for purposes of content +// matching. +type UptimeCheckConfig_ContentMatcher struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // String, regex or JSON content to match. Maximum 1024 bytes. An empty + // `content` string indicates no content matching is to be performed. + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + // The type of content matcher that will be applied to the server output, + // compared to the `content` string when the check is run. + Matcher UptimeCheckConfig_ContentMatcher_ContentMatcherOption `protobuf:"varint,2,opt,name=matcher,proto3,enum=google.monitoring.v3.UptimeCheckConfig_ContentMatcher_ContentMatcherOption" json:"matcher,omitempty"` + // Certain `ContentMatcherOption` types require additional information. + // `MATCHES_JSON_PATH` or `NOT_MATCHES_JSON_PATH` require a + // `JsonPathMatcher`; not used for other options. + // + // Types that are assignable to AdditionalMatcherInfo: + // *UptimeCheckConfig_ContentMatcher_JsonPathMatcher_ + AdditionalMatcherInfo isUptimeCheckConfig_ContentMatcher_AdditionalMatcherInfo `protobuf_oneof:"additional_matcher_info"` +} + +func (x *UptimeCheckConfig_ContentMatcher) Reset() { + *x = UptimeCheckConfig_ContentMatcher{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_ContentMatcher) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_ContentMatcher) ProtoMessage() {} + +func (x *UptimeCheckConfig_ContentMatcher) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_ContentMatcher.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_ContentMatcher) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 4} +} + +func (x *UptimeCheckConfig_ContentMatcher) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *UptimeCheckConfig_ContentMatcher) GetMatcher() UptimeCheckConfig_ContentMatcher_ContentMatcherOption { + if x != nil { + return x.Matcher + } + return UptimeCheckConfig_ContentMatcher_CONTENT_MATCHER_OPTION_UNSPECIFIED +} + +func (m *UptimeCheckConfig_ContentMatcher) GetAdditionalMatcherInfo() isUptimeCheckConfig_ContentMatcher_AdditionalMatcherInfo { + if m != nil { + return m.AdditionalMatcherInfo + } + return nil +} + +func (x *UptimeCheckConfig_ContentMatcher) GetJsonPathMatcher() *UptimeCheckConfig_ContentMatcher_JsonPathMatcher { + if x, ok := x.GetAdditionalMatcherInfo().(*UptimeCheckConfig_ContentMatcher_JsonPathMatcher_); ok { + return x.JsonPathMatcher + } + return nil +} + +type isUptimeCheckConfig_ContentMatcher_AdditionalMatcherInfo interface { + isUptimeCheckConfig_ContentMatcher_AdditionalMatcherInfo() +} + +type UptimeCheckConfig_ContentMatcher_JsonPathMatcher_ struct { + // Matcher information for `MATCHES_JSON_PATH` and `NOT_MATCHES_JSON_PATH` + JsonPathMatcher *UptimeCheckConfig_ContentMatcher_JsonPathMatcher `protobuf:"bytes,3,opt,name=json_path_matcher,json=jsonPathMatcher,proto3,oneof"` +} + +func (*UptimeCheckConfig_ContentMatcher_JsonPathMatcher_) isUptimeCheckConfig_ContentMatcher_AdditionalMatcherInfo() { +} + +// The authentication parameters to provide to the specified resource or +// URL that requires a username and password. Currently, only +// [Basic HTTP authentication](https://tools.ietf.org/html/rfc7617) is +// supported in Uptime checks. +type UptimeCheckConfig_HttpCheck_BasicAuthentication struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The username to use when authenticating with the HTTP server. + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // The password to use when authenticating with the HTTP server. + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *UptimeCheckConfig_HttpCheck_BasicAuthentication) Reset() { + *x = UptimeCheckConfig_HttpCheck_BasicAuthentication{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_HttpCheck_BasicAuthentication) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_HttpCheck_BasicAuthentication) ProtoMessage() {} + +func (x *UptimeCheckConfig_HttpCheck_BasicAuthentication) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck_BasicAuthentication.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_HttpCheck_BasicAuthentication) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2, 0} +} + +func (x *UptimeCheckConfig_HttpCheck_BasicAuthentication) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *UptimeCheckConfig_HttpCheck_BasicAuthentication) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +// A status to accept. Either a status code class like "2xx", or an integer +// status code like "200". +type UptimeCheckConfig_HttpCheck_ResponseStatusCode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Either a specific value or a class of status codes. + // + // Types that are assignable to StatusCode: + // *UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusValue + // *UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_ + StatusCode isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode `protobuf_oneof:"status_code"` +} + +func (x *UptimeCheckConfig_HttpCheck_ResponseStatusCode) Reset() { + *x = UptimeCheckConfig_HttpCheck_ResponseStatusCode{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_HttpCheck_ResponseStatusCode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_HttpCheck_ResponseStatusCode) ProtoMessage() {} + +func (x *UptimeCheckConfig_HttpCheck_ResponseStatusCode) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_HttpCheck_ResponseStatusCode.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_HttpCheck_ResponseStatusCode) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 2, 1} +} + +func (m *UptimeCheckConfig_HttpCheck_ResponseStatusCode) GetStatusCode() isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode { + if m != nil { + return m.StatusCode + } + return nil +} + +func (x *UptimeCheckConfig_HttpCheck_ResponseStatusCode) GetStatusValue() int32 { + if x, ok := x.GetStatusCode().(*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusValue); ok { + return x.StatusValue + } + return 0 +} + +func (x *UptimeCheckConfig_HttpCheck_ResponseStatusCode) GetStatusClass() UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass { + if x, ok := x.GetStatusCode().(*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_); ok { + return x.StatusClass + } + return UptimeCheckConfig_HttpCheck_ResponseStatusCode_STATUS_CLASS_UNSPECIFIED +} + +type isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode interface { + isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode() +} + +type UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusValue struct { + // A status code to accept. + StatusValue int32 `protobuf:"varint,1,opt,name=status_value,json=statusValue,proto3,oneof"` +} + +type UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_ struct { + // A class of status codes to accept. + StatusClass UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass `protobuf:"varint,2,opt,name=status_class,json=statusClass,proto3,enum=google.monitoring.v3.UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass,oneof"` +} + +func (*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusValue) isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode() { +} + +func (*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_) isUptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusCode() { +} + +// Information needed to perform a JSONPath content match. +// Used for `ContentMatcherOption::MATCHES_JSON_PATH` and +// `ContentMatcherOption::NOT_MATCHES_JSON_PATH`. +type UptimeCheckConfig_ContentMatcher_JsonPathMatcher struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // JSONPath within the response output pointing to the expected + // `ContentMatcher::content` to match against. + JsonPath string `protobuf:"bytes,1,opt,name=json_path,json=jsonPath,proto3" json:"json_path,omitempty"` + // The type of JSONPath match that will be applied to the JSON output + // (`ContentMatcher.content`) + JsonMatcher UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption `protobuf:"varint,2,opt,name=json_matcher,json=jsonMatcher,proto3,enum=google.monitoring.v3.UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption" json:"json_matcher,omitempty"` +} + +func (x *UptimeCheckConfig_ContentMatcher_JsonPathMatcher) Reset() { + *x = UptimeCheckConfig_ContentMatcher_JsonPathMatcher{} + if protoimpl.UnsafeEnabled { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UptimeCheckConfig_ContentMatcher_JsonPathMatcher) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UptimeCheckConfig_ContentMatcher_JsonPathMatcher) ProtoMessage() {} + +func (x *UptimeCheckConfig_ContentMatcher_JsonPathMatcher) ProtoReflect() protoreflect.Message { + mi := &file_google_monitoring_v3_uptime_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UptimeCheckConfig_ContentMatcher_JsonPathMatcher.ProtoReflect.Descriptor instead. +func (*UptimeCheckConfig_ContentMatcher_JsonPathMatcher) Descriptor() ([]byte, []int) { + return file_google_monitoring_v3_uptime_proto_rawDescGZIP(), []int{1, 4, 0} +} + +func (x *UptimeCheckConfig_ContentMatcher_JsonPathMatcher) GetJsonPath() string { + if x != nil { + return x.JsonPath + } + return "" +} + +func (x *UptimeCheckConfig_ContentMatcher_JsonPathMatcher) GetJsonMatcher() UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption { + if x != nil { + return x.JsonMatcher + } + return UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JSON_PATH_MATCHER_OPTION_UNSPECIFIED +} + +var File_google_monitoring_v3_uptime_proto protoreflect.FileDescriptor + +var file_google_monitoring_v3_uptime_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, + 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x02, 0x0a, 0x0f, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, + 0x19, 0x0a, 0x08, 0x67, 0x63, 0x70, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x67, 0x63, 0x70, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x65, + 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x64, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, + 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x45, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, + 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x8b, + 0x1f, 0x0a, 0x11, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x0e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, + 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x52, 0x0a, 0x0a, 0x68, + 0x74, 0x74, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x48, 0x01, 0x52, 0x09, 0x68, 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, + 0x4f, 0x0a, 0x09, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x63, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x48, 0x01, 0x52, 0x08, 0x74, 0x63, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x12, 0x31, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x70, 0x65, 0x72, + 0x69, 0x6f, 0x64, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x61, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x73, 0x12, 0x56, 0x0a, 0x0c, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x52, 0x0a, 0x10, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, + 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x27, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x0a, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x56, 0x0a, 0x11, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, + 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, + 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x78, + 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x4c, 0x0a, 0x0d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x2d, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x70, 0x69, 0x6e, + 0x67, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xc8, 0x0b, 0x0a, 0x09, 0x48, 0x74, 0x74, 0x70, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x66, 0x0a, 0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3f, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0d, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x73, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x53, 0x73, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x62, + 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x61, 0x73, 0x6b, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x48, 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, + 0x60, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, + 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x73, + 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x73, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x89, 0x01, 0x0a, 0x1e, 0x61, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x44, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x1b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, + 0x6f, 0x64, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, + 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x70, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x4d, 0x0a, 0x13, 0x42, 0x61, 0x73, + 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x1a, 0xf6, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x75, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x50, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x48, 0x00, 0x52, 0x0b, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x22, 0xb4, 0x01, 0x0a, 0x0b, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x18, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x31, 0x58, 0x58, 0x10, 0x64, 0x12, + 0x15, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, + 0x32, 0x58, 0x58, 0x10, 0xc8, 0x01, 0x12, 0x15, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x33, 0x58, 0x58, 0x10, 0xac, 0x02, 0x12, 0x15, 0x0a, + 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x34, 0x58, + 0x58, 0x10, 0x90, 0x03, 0x12, 0x15, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, + 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x35, 0x58, 0x58, 0x10, 0xf4, 0x03, 0x12, 0x15, 0x0a, 0x10, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x4e, 0x59, 0x10, + 0xe8, 0x07, 0x42, 0x0d, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3a, 0x0a, + 0x0d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x16, + 0x0a, 0x12, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x01, 0x12, + 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x02, 0x22, 0x47, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, + 0x0a, 0x0b, 0x55, 0x52, 0x4c, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, 0x44, + 0x10, 0x02, 0x1a, 0x73, 0x0a, 0x08, 0x54, 0x63, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x53, 0x0a, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x70, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x84, 0x06, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x4b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x74, 0x0a, 0x11, 0x6a, + 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4a, + 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x48, 0x00, + 0x52, 0x0f, 0x6a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x72, 0x1a, 0x94, 0x02, 0x0a, 0x0f, 0x4a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x7f, 0x0a, 0x0c, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x5c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, + 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x4a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x4a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x72, 0x22, 0x63, 0x0a, 0x15, 0x4a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x24, + 0x4a, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x45, + 0x52, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x41, 0x43, 0x54, 0x5f, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, 0x47, 0x45, 0x58, + 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x02, 0x22, 0xc8, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x26, 0x0a, 0x22, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x45, 0x52, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, + 0x54, 0x41, 0x49, 0x4e, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x53, 0x5f, 0x53, + 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x45, 0x53, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x4e, 0x4f, + 0x54, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, + 0x04, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x5f, 0x4a, 0x53, 0x4f, + 0x4e, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x4e, 0x4f, 0x54, 0x5f, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x54, + 0x48, 0x10, 0x06, 0x42, 0x19, 0x0a, 0x17, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x3d, + 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x55, 0x0a, + 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, + 0x43, 0x48, 0x45, 0x43, 0x4b, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, + 0x41, 0x54, 0x49, 0x43, 0x5f, 0x49, 0x50, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x45, 0x52, 0x53, + 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x56, 0x50, 0x43, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x45, + 0x52, 0x53, 0x10, 0x03, 0x3a, 0xf3, 0x01, 0xea, 0x41, 0xef, 0x01, 0x0a, 0x2b, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, + 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x75, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2f, + 0x7b, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x7d, 0x12, 0x45, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x7d, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2f, 0x7b, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x7d, 0x12, 0x39, 0x66, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7d, 0x2f, 0x75, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x2f, 0x7b, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x7d, 0x12, 0x01, 0x2a, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x8b, 0x01, 0x0a, + 0x0d, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x12, 0x3f, + 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, + 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, + 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2a, 0x95, 0x01, 0x0a, 0x11, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x47, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x53, 0x41, 0x10, + 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x55, 0x52, 0x4f, 0x50, 0x45, 0x10, 0x02, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x4f, 0x55, 0x54, 0x48, 0x5f, 0x41, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x41, 0x10, 0x03, + 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x53, 0x49, 0x41, 0x5f, 0x50, 0x41, 0x43, 0x49, 0x46, 0x49, 0x43, + 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x53, 0x41, 0x5f, 0x4f, 0x52, 0x45, 0x47, 0x4f, 0x4e, + 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x41, 0x5f, 0x49, 0x4f, 0x57, 0x41, 0x10, 0x06, + 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x53, 0x41, 0x5f, 0x56, 0x49, 0x52, 0x47, 0x49, 0x4e, 0x49, 0x41, + 0x10, 0x07, 0x2a, 0x5b, 0x0a, 0x11, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, + 0x43, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x57, 0x53, 0x5f, 0x45, 0x4c, 0x42, 0x5f, + 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, 0x10, 0x02, 0x42, + 0xc6, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x0b, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, + 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x76, + 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, + 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x70, 0x62, 0xaa, 0x02, + 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_monitoring_v3_uptime_proto_rawDescOnce sync.Once + file_google_monitoring_v3_uptime_proto_rawDescData = file_google_monitoring_v3_uptime_proto_rawDesc +) + +func file_google_monitoring_v3_uptime_proto_rawDescGZIP() []byte { + file_google_monitoring_v3_uptime_proto_rawDescOnce.Do(func() { + file_google_monitoring_v3_uptime_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_monitoring_v3_uptime_proto_rawDescData) + }) + return file_google_monitoring_v3_uptime_proto_rawDescData +} + +var file_google_monitoring_v3_uptime_proto_enumTypes = make([]protoimpl.EnumInfo, 9) +var file_google_monitoring_v3_uptime_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_google_monitoring_v3_uptime_proto_goTypes = []interface{}{ + (UptimeCheckRegion)(0), // 0: google.monitoring.v3.UptimeCheckRegion + (GroupResourceType)(0), // 1: google.monitoring.v3.GroupResourceType + (InternalChecker_State)(0), // 2: google.monitoring.v3.InternalChecker.State + (UptimeCheckConfig_CheckerType)(0), // 3: google.monitoring.v3.UptimeCheckConfig.CheckerType + (UptimeCheckConfig_HttpCheck_RequestMethod)(0), // 4: google.monitoring.v3.UptimeCheckConfig.HttpCheck.RequestMethod + (UptimeCheckConfig_HttpCheck_ContentType)(0), // 5: google.monitoring.v3.UptimeCheckConfig.HttpCheck.ContentType + (UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass)(0), // 6: google.monitoring.v3.UptimeCheckConfig.HttpCheck.ResponseStatusCode.StatusClass + (UptimeCheckConfig_ContentMatcher_ContentMatcherOption)(0), // 7: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.ContentMatcherOption + (UptimeCheckConfig_ContentMatcher_JsonPathMatcher_JsonPathMatcherOption)(0), // 8: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.JsonPathMatcher.JsonPathMatcherOption + (*InternalChecker)(nil), // 9: google.monitoring.v3.InternalChecker + (*UptimeCheckConfig)(nil), // 10: google.monitoring.v3.UptimeCheckConfig + (*UptimeCheckIp)(nil), // 11: google.monitoring.v3.UptimeCheckIp + (*UptimeCheckConfig_ResourceGroup)(nil), // 12: google.monitoring.v3.UptimeCheckConfig.ResourceGroup + (*UptimeCheckConfig_PingConfig)(nil), // 13: google.monitoring.v3.UptimeCheckConfig.PingConfig + (*UptimeCheckConfig_HttpCheck)(nil), // 14: google.monitoring.v3.UptimeCheckConfig.HttpCheck + (*UptimeCheckConfig_TcpCheck)(nil), // 15: google.monitoring.v3.UptimeCheckConfig.TcpCheck + (*UptimeCheckConfig_ContentMatcher)(nil), // 16: google.monitoring.v3.UptimeCheckConfig.ContentMatcher + nil, // 17: google.monitoring.v3.UptimeCheckConfig.UserLabelsEntry + (*UptimeCheckConfig_HttpCheck_BasicAuthentication)(nil), // 18: google.monitoring.v3.UptimeCheckConfig.HttpCheck.BasicAuthentication + (*UptimeCheckConfig_HttpCheck_ResponseStatusCode)(nil), // 19: google.monitoring.v3.UptimeCheckConfig.HttpCheck.ResponseStatusCode + nil, // 20: google.monitoring.v3.UptimeCheckConfig.HttpCheck.HeadersEntry + (*UptimeCheckConfig_ContentMatcher_JsonPathMatcher)(nil), // 21: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.JsonPathMatcher + (*monitoredres.MonitoredResource)(nil), // 22: google.api.MonitoredResource + (*durationpb.Duration)(nil), // 23: google.protobuf.Duration +} +var file_google_monitoring_v3_uptime_proto_depIdxs = []int32{ + 2, // 0: google.monitoring.v3.InternalChecker.state:type_name -> google.monitoring.v3.InternalChecker.State + 22, // 1: google.monitoring.v3.UptimeCheckConfig.monitored_resource:type_name -> google.api.MonitoredResource + 12, // 2: google.monitoring.v3.UptimeCheckConfig.resource_group:type_name -> google.monitoring.v3.UptimeCheckConfig.ResourceGroup + 14, // 3: google.monitoring.v3.UptimeCheckConfig.http_check:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck + 15, // 4: google.monitoring.v3.UptimeCheckConfig.tcp_check:type_name -> google.monitoring.v3.UptimeCheckConfig.TcpCheck + 23, // 5: google.monitoring.v3.UptimeCheckConfig.period:type_name -> google.protobuf.Duration + 23, // 6: google.monitoring.v3.UptimeCheckConfig.timeout:type_name -> google.protobuf.Duration + 16, // 7: google.monitoring.v3.UptimeCheckConfig.content_matchers:type_name -> google.monitoring.v3.UptimeCheckConfig.ContentMatcher + 3, // 8: google.monitoring.v3.UptimeCheckConfig.checker_type:type_name -> google.monitoring.v3.UptimeCheckConfig.CheckerType + 0, // 9: google.monitoring.v3.UptimeCheckConfig.selected_regions:type_name -> google.monitoring.v3.UptimeCheckRegion + 9, // 10: google.monitoring.v3.UptimeCheckConfig.internal_checkers:type_name -> google.monitoring.v3.InternalChecker + 17, // 11: google.monitoring.v3.UptimeCheckConfig.user_labels:type_name -> google.monitoring.v3.UptimeCheckConfig.UserLabelsEntry + 0, // 12: google.monitoring.v3.UptimeCheckIp.region:type_name -> google.monitoring.v3.UptimeCheckRegion + 1, // 13: google.monitoring.v3.UptimeCheckConfig.ResourceGroup.resource_type:type_name -> google.monitoring.v3.GroupResourceType + 4, // 14: google.monitoring.v3.UptimeCheckConfig.HttpCheck.request_method:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.RequestMethod + 18, // 15: google.monitoring.v3.UptimeCheckConfig.HttpCheck.auth_info:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.BasicAuthentication + 20, // 16: google.monitoring.v3.UptimeCheckConfig.HttpCheck.headers:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.HeadersEntry + 5, // 17: google.monitoring.v3.UptimeCheckConfig.HttpCheck.content_type:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.ContentType + 19, // 18: google.monitoring.v3.UptimeCheckConfig.HttpCheck.accepted_response_status_codes:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.ResponseStatusCode + 13, // 19: google.monitoring.v3.UptimeCheckConfig.HttpCheck.ping_config:type_name -> google.monitoring.v3.UptimeCheckConfig.PingConfig + 13, // 20: google.monitoring.v3.UptimeCheckConfig.TcpCheck.ping_config:type_name -> google.monitoring.v3.UptimeCheckConfig.PingConfig + 7, // 21: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.matcher:type_name -> google.monitoring.v3.UptimeCheckConfig.ContentMatcher.ContentMatcherOption + 21, // 22: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.json_path_matcher:type_name -> google.monitoring.v3.UptimeCheckConfig.ContentMatcher.JsonPathMatcher + 6, // 23: google.monitoring.v3.UptimeCheckConfig.HttpCheck.ResponseStatusCode.status_class:type_name -> google.monitoring.v3.UptimeCheckConfig.HttpCheck.ResponseStatusCode.StatusClass + 8, // 24: google.monitoring.v3.UptimeCheckConfig.ContentMatcher.JsonPathMatcher.json_matcher:type_name -> google.monitoring.v3.UptimeCheckConfig.ContentMatcher.JsonPathMatcher.JsonPathMatcherOption + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name +} + +func init() { file_google_monitoring_v3_uptime_proto_init() } +func file_google_monitoring_v3_uptime_proto_init() { + if File_google_monitoring_v3_uptime_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_monitoring_v3_uptime_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InternalChecker); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckIp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_ResourceGroup); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_PingConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_HttpCheck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_TcpCheck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_ContentMatcher); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_HttpCheck_BasicAuthentication); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_HttpCheck_ResponseStatusCode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UptimeCheckConfig_ContentMatcher_JsonPathMatcher); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_google_monitoring_v3_uptime_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*UptimeCheckConfig_MonitoredResource)(nil), + (*UptimeCheckConfig_ResourceGroup_)(nil), + (*UptimeCheckConfig_HttpCheck_)(nil), + (*UptimeCheckConfig_TcpCheck_)(nil), + } + file_google_monitoring_v3_uptime_proto_msgTypes[7].OneofWrappers = []interface{}{ + (*UptimeCheckConfig_ContentMatcher_JsonPathMatcher_)(nil), + } + file_google_monitoring_v3_uptime_proto_msgTypes[10].OneofWrappers = []interface{}{ + (*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusValue)(nil), + (*UptimeCheckConfig_HttpCheck_ResponseStatusCode_StatusClass_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_monitoring_v3_uptime_proto_rawDesc, + NumEnums: 9, + NumMessages: 13, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_monitoring_v3_uptime_proto_goTypes, + DependencyIndexes: file_google_monitoring_v3_uptime_proto_depIdxs, + EnumInfos: file_google_monitoring_v3_uptime_proto_enumTypes, + MessageInfos: file_google_monitoring_v3_uptime_proto_msgTypes, + }.Build() + File_google_monitoring_v3_uptime_proto = out.File + file_google_monitoring_v3_uptime_proto_rawDesc = nil + file_google_monitoring_v3_uptime_proto_goTypes = nil + file_google_monitoring_v3_uptime_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime_service.pb.go similarity index 75% rename from vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go rename to vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime_service.pb.go index e2514194d52..838cec626d7 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/monitoringpb/uptime_service.pb.go @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.12.2 +// protoc-gen-go v1.30.0 +// protoc v4.23.2 // source: google/monitoring/v3/uptime_service.proto -package monitoring +package monitoringpb import ( context "context" @@ -54,6 +54,12 @@ type ListUptimeCheckConfigsRequest struct { // // projects/[PROJECT_ID_OR_NUMBER] Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` + // If provided, this field specifies the criteria that must be met by + // uptime checks to be included in the response. + // + // For more details, see [Filtering + // syntax](https://cloud.google.com/monitoring/api/v3/sorting-and-filtering#filter_syntax). + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` // The maximum number of results to return in a single response. The server // may further constrain the maximum number of results returned in a single // page. If the page_size is <=0, the server will decide the number of results @@ -104,6 +110,13 @@ func (x *ListUptimeCheckConfigsRequest) GetParent() string { return "" } +func (x *ListUptimeCheckConfigsRequest) GetFilter() string { + if x != nil { + return x.Filter + } + return "" +} + func (x *ListUptimeCheckConfigsRequest) GetPageSize() int32 { if x != nil { return x.PageSize @@ -318,7 +331,7 @@ type UpdateUptimeCheckConfigRequest struct { // the values for the set of fields mentioned in the `updateMask`. If an // `updateMask` has not been given, this Uptime check configuration replaces // the current configuration. If a field is mentioned in `updateMask` but - // the corresonding field is omitted in this partial Uptime check + // the corresponding field is omitted in this partial Uptime check // configuration, it has the effect of deleting/clearing the field from the // configuration on the server. // @@ -574,180 +587,182 @@ var file_google_monitoring_v3_uptime_service_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa8, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x12, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, - 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0xc2, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x12, 0x75, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, - 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x66, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x55, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, - 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xcb, - 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x12, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x5c, - 0x0a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x11, 0x75, 0x70, 0x74, 0x69, 0x6d, - 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbb, 0x01, 0x0a, - 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, - 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x5c, 0x0a, 0x13, - 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, - 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x11, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x69, 0x0a, 0x1e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, - 0x41, 0x2d, 0x0a, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x57, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, - 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, - 0x10, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x70, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, - 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x52, 0x0e, 0x75, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x12, 0x26, 0x0a, 0x0f, - 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xbd, 0x0a, 0x0a, 0x12, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xc0, 0x01, 0x0a, 0x16, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc2, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, - 0x2a, 0x7d, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xad, - 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, - 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, + 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, - 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, - 0x2a, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xde, - 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x41, 0x22, 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, - 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x3a, 0x13, 0x75, - 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0xda, 0x41, 0x1a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x75, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0xeb, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x66, 0x69, 0x67, 0x52, 0x12, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x66, + 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, + 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, + 0x2d, 0x12, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, + 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x03, 0xe0, 0x41, + 0x02, 0x52, 0x11, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbb, 0x01, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x5c, 0x0a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x71, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x55, 0x32, 0x3e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x75, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2f, - 0x2a, 0x7d, 0x3a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xda, 0x41, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0xa2, 0x01, - 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, - 0x2a, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, - 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x11, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x22, 0x69, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, + 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x57, 0x0a, + 0x19, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x49, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x49, 0x70, 0x52, 0x0e, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x49, 0x70, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xbd, 0x0a, 0x0a, + 0x12, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0xc0, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x33, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0xda, 0x41, 0x06, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, + 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x2f, 0x2a, 0x7d, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0xad, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x39, 0xda, 0x41, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x33, 0x2f, + 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, + 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xde, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, + 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x22, 0x64, 0xda, 0x41, 0x1a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x75, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x2a, 0x2f, 0x76, 0x33, + 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0xeb, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x49, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x33, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, - 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, - 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x42, 0xca, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x33, 0x42, 0x12, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x6d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x33, 0x3b, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x5c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, - 0x33, 0xea, 0x02, 0x1d, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, - 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x22, 0x71, 0xda, 0x41, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x55, + 0x3a, 0x13, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0x3e, 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x75, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xa2, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x39, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, + 0x2f, 0x76, 0x33, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, + 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, + 0x73, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, + 0x33, 0x2f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x70, 0x73, + 0x1a, 0xa9, 0x01, 0xca, 0x41, 0x19, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, + 0x41, 0x89, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, + 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, + 0x68, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, + 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x42, 0xcd, 0x01, 0x0a, + 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x42, 0x12, 0x55, 0x70, 0x74, 0x69, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x41, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2f, + 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x70, 0x62, 0x3b, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x70, 0x62, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x33, 0xca, + 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4d, + 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x33, 0xea, 0x02, 0x1d, 0x47, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, + 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/notification_channel_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/notification_channel_client.go index d732affec53..04836724bcb 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/notification_channel_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/notification_channel_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -66,6 +66,7 @@ func defaultNotificationChannelGRPCClientOptions() []option.ClientOption { func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { return &NotificationChannelCallOptions{ ListNotificationChannelDescriptors: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -77,6 +78,7 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }), }, GetNotificationChannelDescriptor: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -88,6 +90,7 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }), }, ListNotificationChannels: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -99,6 +102,7 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }), }, GetNotificationChannel: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -109,9 +113,14 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }) }), }, - CreateNotificationChannel: []gax.CallOption{}, - UpdateNotificationChannel: []gax.CallOption{}, + CreateNotificationChannel: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, + UpdateNotificationChannel: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, DeleteNotificationChannel: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -122,8 +131,11 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }) }), }, - SendNotificationChannelVerificationCode: []gax.CallOption{}, + SendNotificationChannelVerificationCode: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, GetNotificationChannelVerificationCode: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -135,6 +147,7 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { }), }, VerifyNotificationChannel: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -148,7 +161,7 @@ func defaultNotificationChannelCallOptions() *NotificationChannelCallOptions { } } -// internalNotificationChannelClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalNotificationChannelClient is an interface that defines the methods available from Cloud Monitoring API. type internalNotificationChannelClient interface { Close() error setGoogleClientInfo(...string) @@ -195,7 +208,8 @@ func (c *NotificationChannelClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *NotificationChannelClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -288,9 +302,6 @@ type notificationChannelGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing NotificationChannelClient CallOptions **NotificationChannelCallOptions @@ -316,11 +327,6 @@ func NewNotificationChannelClient(ctx context.Context, opts ...option.ClientOpti clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -329,7 +335,6 @@ func NewNotificationChannelClient(ctx context.Context, opts ...option.ClientOpti c := ¬ificationChannelGRPCClient{ connPool: connPool, - disableDeadlines: disableDeadlines, notificationChannelClient: monitoringpb.NewNotificationChannelServiceClient(connPool), CallOptions: &client.CallOptions, } @@ -342,7 +347,8 @@ func NewNotificationChannelClient(ctx context.Context, opts ...option.ClientOpti // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *notificationChannelGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -351,7 +357,7 @@ func (c *notificationChannelGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *notificationChannelGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -408,11 +414,6 @@ func (c *notificationChannelGRPCClient) ListNotificationChannelDescriptors(ctx c } func (c *notificationChannelGRPCClient) GetNotificationChannelDescriptor(ctx context.Context, req *monitoringpb.GetNotificationChannelDescriptorRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannelDescriptor, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -475,11 +476,6 @@ func (c *notificationChannelGRPCClient) ListNotificationChannels(ctx context.Con } func (c *notificationChannelGRPCClient) GetNotificationChannel(ctx context.Context, req *monitoringpb.GetNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -497,11 +493,6 @@ func (c *notificationChannelGRPCClient) GetNotificationChannel(ctx context.Conte } func (c *notificationChannelGRPCClient) CreateNotificationChannel(ctx context.Context, req *monitoringpb.CreateNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -519,11 +510,6 @@ func (c *notificationChannelGRPCClient) CreateNotificationChannel(ctx context.Co } func (c *notificationChannelGRPCClient) UpdateNotificationChannel(ctx context.Context, req *monitoringpb.UpdateNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "notification_channel.name", url.QueryEscape(req.GetNotificationChannel().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -541,11 +527,6 @@ func (c *notificationChannelGRPCClient) UpdateNotificationChannel(ctx context.Co } func (c *notificationChannelGRPCClient) DeleteNotificationChannel(ctx context.Context, req *monitoringpb.DeleteNotificationChannelRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -559,11 +540,6 @@ func (c *notificationChannelGRPCClient) DeleteNotificationChannel(ctx context.Co } func (c *notificationChannelGRPCClient) SendNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.SendNotificationChannelVerificationCodeRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -577,11 +553,6 @@ func (c *notificationChannelGRPCClient) SendNotificationChannelVerificationCode( } func (c *notificationChannelGRPCClient) GetNotificationChannelVerificationCode(ctx context.Context, req *monitoringpb.GetNotificationChannelVerificationCodeRequest, opts ...gax.CallOption) (*monitoringpb.GetNotificationChannelVerificationCodeResponse, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -599,11 +570,6 @@ func (c *notificationChannelGRPCClient) GetNotificationChannelVerificationCode(c } func (c *notificationChannelGRPCClient) VerifyNotificationChannel(ctx context.Context, req *monitoringpb.VerifyNotificationChannelRequest, opts ...gax.CallOption) (*monitoringpb.NotificationChannel, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/query_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/query_client.go index e2e2b916df7..5dd3b8f16d5 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/query_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/query_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,12 +22,12 @@ import ( "math" "net/url" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" @@ -58,7 +58,7 @@ func defaultQueryCallOptions() *QueryCallOptions { } } -// internalQueryClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalQueryClient is an interface that defines the methods available from Cloud Monitoring API. type internalQueryClient interface { Close() error setGoogleClientInfo(...string) @@ -97,7 +97,8 @@ func (c *QueryClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *QueryClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -114,9 +115,6 @@ type queryGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing QueryClient CallOptions **QueryCallOptions @@ -143,11 +141,6 @@ func NewQueryClient(ctx context.Context, opts ...option.ClientOption) (*QueryCli clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -155,10 +148,9 @@ func NewQueryClient(ctx context.Context, opts ...option.ClientOption) (*QueryCli client := QueryClient{CallOptions: defaultQueryCallOptions()} c := &queryGRPCClient{ - connPool: connPool, - disableDeadlines: disableDeadlines, - queryClient: monitoringpb.NewQueryServiceClient(connPool), - CallOptions: &client.CallOptions, + connPool: connPool, + queryClient: monitoringpb.NewQueryServiceClient(connPool), + CallOptions: &client.CallOptions, } c.setGoogleClientInfo() @@ -169,7 +161,8 @@ func NewQueryClient(ctx context.Context, opts ...option.ClientOption) (*QueryCli // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *queryGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -178,7 +171,7 @@ func (c *queryGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *queryGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/service_monitoring_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/service_monitoring_client.go index 693f4b625b1..c371e993773 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/service_monitoring_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/service_monitoring_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -65,8 +65,11 @@ func defaultServiceMonitoringGRPCClientOptions() []option.ClientOption { func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { return &ServiceMonitoringCallOptions{ - CreateService: []gax.CallOption{}, + CreateService: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, GetService: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -78,6 +81,7 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { }), }, ListServices: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -88,8 +92,11 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { }) }), }, - UpdateService: []gax.CallOption{}, + UpdateService: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, DeleteService: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -100,8 +107,11 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { }) }), }, - CreateServiceLevelObjective: []gax.CallOption{}, + CreateServiceLevelObjective: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, GetServiceLevelObjective: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -113,6 +123,7 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { }), }, ListServiceLevelObjectives: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -123,8 +134,11 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { }) }), }, - UpdateServiceLevelObjective: []gax.CallOption{}, + UpdateServiceLevelObjective: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, DeleteServiceLevelObjective: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -138,7 +152,7 @@ func defaultServiceMonitoringCallOptions() *ServiceMonitoringCallOptions { } } -// internalServiceMonitoringClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalServiceMonitoringClient is an interface that defines the methods available from Cloud Monitoring API. type internalServiceMonitoringClient interface { Close() error setGoogleClientInfo(...string) @@ -187,7 +201,8 @@ func (c *ServiceMonitoringClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *ServiceMonitoringClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -249,9 +264,6 @@ type serviceMonitoringGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing ServiceMonitoringClient CallOptions **ServiceMonitoringCallOptions @@ -279,11 +291,6 @@ func NewServiceMonitoringClient(ctx context.Context, opts ...option.ClientOption clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -292,7 +299,6 @@ func NewServiceMonitoringClient(ctx context.Context, opts ...option.ClientOption c := &serviceMonitoringGRPCClient{ connPool: connPool, - disableDeadlines: disableDeadlines, serviceMonitoringClient: monitoringpb.NewServiceMonitoringServiceClient(connPool), CallOptions: &client.CallOptions, } @@ -305,7 +311,8 @@ func NewServiceMonitoringClient(ctx context.Context, opts ...option.ClientOption // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *serviceMonitoringGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -314,7 +321,7 @@ func (c *serviceMonitoringGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *serviceMonitoringGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -326,11 +333,6 @@ func (c *serviceMonitoringGRPCClient) Close() error { } func (c *serviceMonitoringGRPCClient) CreateService(ctx context.Context, req *monitoringpb.CreateServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -348,11 +350,6 @@ func (c *serviceMonitoringGRPCClient) CreateService(ctx context.Context, req *mo } func (c *serviceMonitoringGRPCClient) GetService(ctx context.Context, req *monitoringpb.GetServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -415,11 +412,6 @@ func (c *serviceMonitoringGRPCClient) ListServices(ctx context.Context, req *mon } func (c *serviceMonitoringGRPCClient) UpdateService(ctx context.Context, req *monitoringpb.UpdateServiceRequest, opts ...gax.CallOption) (*monitoringpb.Service, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service.name", url.QueryEscape(req.GetService().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -437,11 +429,6 @@ func (c *serviceMonitoringGRPCClient) UpdateService(ctx context.Context, req *mo } func (c *serviceMonitoringGRPCClient) DeleteService(ctx context.Context, req *monitoringpb.DeleteServiceRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -455,11 +442,6 @@ func (c *serviceMonitoringGRPCClient) DeleteService(ctx context.Context, req *mo } func (c *serviceMonitoringGRPCClient) CreateServiceLevelObjective(ctx context.Context, req *monitoringpb.CreateServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -477,11 +459,6 @@ func (c *serviceMonitoringGRPCClient) CreateServiceLevelObjective(ctx context.Co } func (c *serviceMonitoringGRPCClient) GetServiceLevelObjective(ctx context.Context, req *monitoringpb.GetServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -544,11 +521,6 @@ func (c *serviceMonitoringGRPCClient) ListServiceLevelObjectives(ctx context.Con } func (c *serviceMonitoringGRPCClient) UpdateServiceLevelObjective(ctx context.Context, req *monitoringpb.UpdateServiceLevelObjectiveRequest, opts ...gax.CallOption) (*monitoringpb.ServiceLevelObjective, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service_level_objective.name", url.QueryEscape(req.GetServiceLevelObjective().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -566,11 +538,6 @@ func (c *serviceMonitoringGRPCClient) UpdateServiceLevelObjective(ctx context.Co } func (c *serviceMonitoringGRPCClient) DeleteServiceLevelObjective(ctx context.Context, req *monitoringpb.DeleteServiceLevelObjectiveRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/snooze_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/snooze_client.go new file mode 100644 index 00000000000..6142e667156 --- /dev/null +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/snooze_client.go @@ -0,0 +1,382 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go_gapic. DO NOT EDIT. + +package monitoring + +import ( + "context" + "fmt" + "math" + "net/url" + "time" + + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" + gax "github.com/googleapis/gax-go/v2" + "google.golang.org/api/iterator" + "google.golang.org/api/option" + "google.golang.org/api/option/internaloption" + gtransport "google.golang.org/api/transport/grpc" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/proto" +) + +var newSnoozeClientHook clientHook + +// SnoozeCallOptions contains the retry settings for each method of SnoozeClient. +type SnoozeCallOptions struct { + CreateSnooze []gax.CallOption + ListSnoozes []gax.CallOption + GetSnooze []gax.CallOption + UpdateSnooze []gax.CallOption +} + +func defaultSnoozeGRPCClientOptions() []option.ClientOption { + return []option.ClientOption{ + internaloption.WithDefaultEndpoint("monitoring.googleapis.com:443"), + internaloption.WithDefaultMTLSEndpoint("monitoring.mtls.googleapis.com:443"), + internaloption.WithDefaultAudience("https://monitoring.googleapis.com/"), + internaloption.WithDefaultScopes(DefaultAuthScopes()...), + internaloption.EnableJwtWithScope(), + option.WithGRPCDialOption(grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(math.MaxInt32))), + } +} + +func defaultSnoozeCallOptions() *SnoozeCallOptions { + return &SnoozeCallOptions{ + CreateSnooze: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, + ListSnoozes: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 30000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + GetSnooze: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 30000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + UpdateSnooze: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, + } +} + +// internalSnoozeClient is an interface that defines the methods available from Cloud Monitoring API. +type internalSnoozeClient interface { + Close() error + setGoogleClientInfo(...string) + Connection() *grpc.ClientConn + CreateSnooze(context.Context, *monitoringpb.CreateSnoozeRequest, ...gax.CallOption) (*monitoringpb.Snooze, error) + ListSnoozes(context.Context, *monitoringpb.ListSnoozesRequest, ...gax.CallOption) *SnoozeIterator + GetSnooze(context.Context, *monitoringpb.GetSnoozeRequest, ...gax.CallOption) (*monitoringpb.Snooze, error) + UpdateSnooze(context.Context, *monitoringpb.UpdateSnoozeRequest, ...gax.CallOption) (*monitoringpb.Snooze, error) +} + +// SnoozeClient is a client for interacting with Cloud Monitoring API. +// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. +// +// The SnoozeService API is used to temporarily prevent an alert policy from +// generating alerts. A Snooze is a description of the criteria under which one +// or more alert policies should not fire alerts for the specified duration. +type SnoozeClient struct { + // The internal transport-dependent client. + internalClient internalSnoozeClient + + // The call options for this service. + CallOptions *SnoozeCallOptions +} + +// Wrapper methods routed to the internal client. + +// Close closes the connection to the API service. The user should invoke this when +// the client is no longer required. +func (c *SnoozeClient) Close() error { + return c.internalClient.Close() +} + +// setGoogleClientInfo sets the name and version of the application in +// the `x-goog-api-client` header passed on each request. Intended for +// use by Google-written clients. +func (c *SnoozeClient) setGoogleClientInfo(keyval ...string) { + c.internalClient.setGoogleClientInfo(keyval...) +} + +// Connection returns a connection to the API service. +// +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. +func (c *SnoozeClient) Connection() *grpc.ClientConn { + return c.internalClient.Connection() +} + +// CreateSnooze creates a Snooze that will prevent alerts, which match the provided +// criteria, from being opened. The Snooze applies for a specific time +// interval. +func (c *SnoozeClient) CreateSnooze(ctx context.Context, req *monitoringpb.CreateSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + return c.internalClient.CreateSnooze(ctx, req, opts...) +} + +// ListSnoozes lists the Snoozes associated with a project. Can optionally pass in +// filter, which specifies predicates to match Snoozes. +func (c *SnoozeClient) ListSnoozes(ctx context.Context, req *monitoringpb.ListSnoozesRequest, opts ...gax.CallOption) *SnoozeIterator { + return c.internalClient.ListSnoozes(ctx, req, opts...) +} + +// GetSnooze retrieves a Snooze by name. +func (c *SnoozeClient) GetSnooze(ctx context.Context, req *monitoringpb.GetSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + return c.internalClient.GetSnooze(ctx, req, opts...) +} + +// UpdateSnooze updates a Snooze, identified by its name, with the parameters in the +// given Snooze object. +func (c *SnoozeClient) UpdateSnooze(ctx context.Context, req *monitoringpb.UpdateSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + return c.internalClient.UpdateSnooze(ctx, req, opts...) +} + +// snoozeGRPCClient is a client for interacting with Cloud Monitoring API over gRPC transport. +// +// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. +type snoozeGRPCClient struct { + // Connection pool of gRPC connections to the service. + connPool gtransport.ConnPool + + // Points back to the CallOptions field of the containing SnoozeClient + CallOptions **SnoozeCallOptions + + // The gRPC API client. + snoozeClient monitoringpb.SnoozeServiceClient + + // The x-goog-* metadata to be sent with each request. + xGoogMetadata metadata.MD +} + +// NewSnoozeClient creates a new snooze service client based on gRPC. +// The returned client must be Closed when it is done being used to clean up its underlying connections. +// +// The SnoozeService API is used to temporarily prevent an alert policy from +// generating alerts. A Snooze is a description of the criteria under which one +// or more alert policies should not fire alerts for the specified duration. +func NewSnoozeClient(ctx context.Context, opts ...option.ClientOption) (*SnoozeClient, error) { + clientOpts := defaultSnoozeGRPCClientOptions() + if newSnoozeClientHook != nil { + hookOpts, err := newSnoozeClientHook(ctx, clientHookParams{}) + if err != nil { + return nil, err + } + clientOpts = append(clientOpts, hookOpts...) + } + + connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) + if err != nil { + return nil, err + } + client := SnoozeClient{CallOptions: defaultSnoozeCallOptions()} + + c := &snoozeGRPCClient{ + connPool: connPool, + snoozeClient: monitoringpb.NewSnoozeServiceClient(connPool), + CallOptions: &client.CallOptions, + } + c.setGoogleClientInfo() + + client.internalClient = c + + return &client, nil +} + +// Connection returns a connection to the API service. +// +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. +func (c *snoozeGRPCClient) Connection() *grpc.ClientConn { + return c.connPool.Conn() +} + +// setGoogleClientInfo sets the name and version of the application in +// the `x-goog-api-client` header passed on each request. Intended for +// use by Google-written clients. +func (c *snoozeGRPCClient) setGoogleClientInfo(keyval ...string) { + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) + kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) + c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) +} + +// Close closes the connection to the API service. The user should invoke this when +// the client is no longer required. +func (c *snoozeGRPCClient) Close() error { + return c.connPool.Close() +} + +func (c *snoozeGRPCClient) CreateSnooze(ctx context.Context, req *monitoringpb.CreateSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append((*c.CallOptions).CreateSnooze[0:len((*c.CallOptions).CreateSnooze):len((*c.CallOptions).CreateSnooze)], opts...) + var resp *monitoringpb.Snooze + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.snoozeClient.CreateSnooze(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *snoozeGRPCClient) ListSnoozes(ctx context.Context, req *monitoringpb.ListSnoozesRequest, opts ...gax.CallOption) *SnoozeIterator { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append((*c.CallOptions).ListSnoozes[0:len((*c.CallOptions).ListSnoozes):len((*c.CallOptions).ListSnoozes)], opts...) + it := &SnoozeIterator{} + req = proto.Clone(req).(*monitoringpb.ListSnoozesRequest) + it.InternalFetch = func(pageSize int, pageToken string) ([]*monitoringpb.Snooze, string, error) { + resp := &monitoringpb.ListSnoozesResponse{} + if pageToken != "" { + req.PageToken = pageToken + } + if pageSize > math.MaxInt32 { + req.PageSize = math.MaxInt32 + } else if pageSize != 0 { + req.PageSize = int32(pageSize) + } + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.snoozeClient.ListSnoozes(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, "", err + } + + it.Response = resp + return resp.GetSnoozes(), resp.GetNextPageToken(), nil + } + fetch := func(pageSize int, pageToken string) (string, error) { + items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) + if err != nil { + return "", err + } + it.items = append(it.items, items...) + return nextPageToken, nil + } + + it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) + it.pageInfo.MaxSize = int(req.GetPageSize()) + it.pageInfo.Token = req.GetPageToken() + + return it +} + +func (c *snoozeGRPCClient) GetSnooze(ctx context.Context, req *monitoringpb.GetSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append((*c.CallOptions).GetSnooze[0:len((*c.CallOptions).GetSnooze):len((*c.CallOptions).GetSnooze)], opts...) + var resp *monitoringpb.Snooze + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.snoozeClient.GetSnooze(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *snoozeGRPCClient) UpdateSnooze(ctx context.Context, req *monitoringpb.UpdateSnoozeRequest, opts ...gax.CallOption) (*monitoringpb.Snooze, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "snooze.name", url.QueryEscape(req.GetSnooze().GetName()))) + + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append((*c.CallOptions).UpdateSnooze[0:len((*c.CallOptions).UpdateSnooze):len((*c.CallOptions).UpdateSnooze)], opts...) + var resp *monitoringpb.Snooze + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.snoozeClient.UpdateSnooze(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +// SnoozeIterator manages a stream of *monitoringpb.Snooze. +type SnoozeIterator struct { + items []*monitoringpb.Snooze + pageInfo *iterator.PageInfo + nextFunc func() error + + // Response is the raw response for the current page. + // It must be cast to the RPC response type. + // Calling Next() or InternalFetch() updates this value. + Response interface{} + + // InternalFetch is for use by the Google Cloud Libraries only. + // It is not part of the stable interface of this package. + // + // InternalFetch returns results from a single call to the underlying RPC. + // The number of results is no greater than pageSize. + // If there are no more results, nextPageToken is empty and err is nil. + InternalFetch func(pageSize int, pageToken string) (results []*monitoringpb.Snooze, nextPageToken string, err error) +} + +// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. +func (it *SnoozeIterator) PageInfo() *iterator.PageInfo { + return it.pageInfo +} + +// Next returns the next result. Its second return value is iterator.Done if there are no more +// results. Once Next returns Done, all subsequent calls will return Done. +func (it *SnoozeIterator) Next() (*monitoringpb.Snooze, error) { + var item *monitoringpb.Snooze + if err := it.nextFunc(); err != nil { + return item, err + } + item = it.items[0] + it.items = it.items[1:] + return item, nil +} + +func (it *SnoozeIterator) bufLen() int { + return len(it.items) +} + +func (it *SnoozeIterator) takeBuf() interface{} { + b := it.items + it.items = nil + return b +} diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/uptime_check_client.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/uptime_check_client.go index 9203c54e639..6d8f6feddb9 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/uptime_check_client.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/uptime_check_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ import ( "net/url" "time" + monitoringpb "cloud.google.com/go/monitoring/apiv3/v2/monitoringpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -62,6 +62,7 @@ func defaultUptimeCheckGRPCClientOptions() []option.ClientOption { func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { return &UptimeCheckCallOptions{ ListUptimeCheckConfigs: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -73,6 +74,7 @@ func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { }), }, GetUptimeCheckConfig: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -83,9 +85,14 @@ func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { }) }), }, - CreateUptimeCheckConfig: []gax.CallOption{}, - UpdateUptimeCheckConfig: []gax.CallOption{}, + CreateUptimeCheckConfig: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, + UpdateUptimeCheckConfig: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), + }, DeleteUptimeCheckConfig: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -97,6 +104,7 @@ func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { }), }, ListUptimeCheckIps: []gax.CallOption{ + gax.WithTimeout(30000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -110,7 +118,7 @@ func defaultUptimeCheckCallOptions() *UptimeCheckCallOptions { } } -// internalUptimeCheckClient is an interface that defines the methods availaible from Cloud Monitoring API. +// internalUptimeCheckClient is an interface that defines the methods available from Cloud Monitoring API. type internalUptimeCheckClient interface { Close() error setGoogleClientInfo(...string) @@ -127,13 +135,13 @@ type internalUptimeCheckClient interface { // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. // // The UptimeCheckService API is used to manage (list, create, delete, edit) -// Uptime check configurations in the Stackdriver Monitoring product. An Uptime +// Uptime check configurations in the Cloud Monitoring product. An Uptime // check is a piece of configuration that determines which resources and // services to monitor for availability. These configurations can also be -// configured interactively by navigating to the [Cloud Console] -// (http://console.cloud.google.com (at http://console.cloud.google.com)), selecting the appropriate project, -// clicking on “Monitoring” on the left-hand side to navigate to Stackdriver, -// and then clicking on “Uptime”. +// configured interactively by navigating to the [Cloud console] +// (https://console.cloud.google.com (at https://console.cloud.google.com)), selecting the appropriate project, +// clicking on “Monitoring” on the left-hand side to navigate to Cloud +// Monitoring, and then clicking on “Uptime”. type UptimeCheckClient struct { // The internal transport-dependent client. internalClient internalUptimeCheckClient @@ -159,7 +167,8 @@ func (c *UptimeCheckClient) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *UptimeCheckClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } @@ -207,9 +216,6 @@ type uptimeCheckGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing UptimeCheckClient CallOptions **UptimeCheckCallOptions @@ -224,13 +230,13 @@ type uptimeCheckGRPCClient struct { // The returned client must be Closed when it is done being used to clean up its underlying connections. // // The UptimeCheckService API is used to manage (list, create, delete, edit) -// Uptime check configurations in the Stackdriver Monitoring product. An Uptime +// Uptime check configurations in the Cloud Monitoring product. An Uptime // check is a piece of configuration that determines which resources and // services to monitor for availability. These configurations can also be -// configured interactively by navigating to the [Cloud Console] -// (http://console.cloud.google.com (at http://console.cloud.google.com)), selecting the appropriate project, -// clicking on “Monitoring” on the left-hand side to navigate to Stackdriver, -// and then clicking on “Uptime”. +// configured interactively by navigating to the [Cloud console] +// (https://console.cloud.google.com (at https://console.cloud.google.com)), selecting the appropriate project, +// clicking on “Monitoring” on the left-hand side to navigate to Cloud +// Monitoring, and then clicking on “Uptime”. func NewUptimeCheckClient(ctx context.Context, opts ...option.ClientOption) (*UptimeCheckClient, error) { clientOpts := defaultUptimeCheckGRPCClientOptions() if newUptimeCheckClientHook != nil { @@ -241,11 +247,6 @@ func NewUptimeCheckClient(ctx context.Context, opts ...option.ClientOption) (*Up clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -254,7 +255,6 @@ func NewUptimeCheckClient(ctx context.Context, opts ...option.ClientOption) (*Up c := &uptimeCheckGRPCClient{ connPool: connPool, - disableDeadlines: disableDeadlines, uptimeCheckClient: monitoringpb.NewUptimeCheckServiceClient(connPool), CallOptions: &client.CallOptions, } @@ -267,7 +267,8 @@ func NewUptimeCheckClient(ctx context.Context, opts ...option.ClientOption) (*Up // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *uptimeCheckGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -276,7 +277,7 @@ func (c *uptimeCheckGRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *uptimeCheckGRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -333,11 +334,6 @@ func (c *uptimeCheckGRPCClient) ListUptimeCheckConfigs(ctx context.Context, req } func (c *uptimeCheckGRPCClient) GetUptimeCheckConfig(ctx context.Context, req *monitoringpb.GetUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -355,11 +351,6 @@ func (c *uptimeCheckGRPCClient) GetUptimeCheckConfig(ctx context.Context, req *m } func (c *uptimeCheckGRPCClient) CreateUptimeCheckConfig(ctx context.Context, req *monitoringpb.CreateUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -377,11 +368,6 @@ func (c *uptimeCheckGRPCClient) CreateUptimeCheckConfig(ctx context.Context, req } func (c *uptimeCheckGRPCClient) UpdateUptimeCheckConfig(ctx context.Context, req *monitoringpb.UpdateUptimeCheckConfigRequest, opts ...gax.CallOption) (*monitoringpb.UptimeCheckConfig, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "uptime_check_config.name", url.QueryEscape(req.GetUptimeCheckConfig().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -399,11 +385,6 @@ func (c *uptimeCheckGRPCClient) UpdateUptimeCheckConfig(ctx context.Context, req } func (c *uptimeCheckGRPCClient) DeleteUptimeCheckConfig(ctx context.Context, req *monitoringpb.DeleteUptimeCheckConfigRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 30000*time.Millisecond) - defer cancel() - ctx = cctx - } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) diff --git a/vendor/cloud.google.com/go/monitoring/apiv3/v2/version.go b/vendor/cloud.google.com/go/monitoring/apiv3/v2/version.go index bb4981e0fb4..accff0f5e47 100644 --- a/vendor/cloud.google.com/go/monitoring/apiv3/v2/version.go +++ b/vendor/cloud.google.com/go/monitoring/apiv3/v2/version.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/cloud.google.com/go/monitoring/internal/version.go b/vendor/cloud.google.com/go/monitoring/internal/version.go index e93235c2032..7dd6a0aa86f 100644 --- a/vendor/cloud.google.com/go/monitoring/internal/version.go +++ b/vendor/cloud.google.com/go/monitoring/internal/version.go @@ -15,4 +15,4 @@ package internal // Version is the current tagged release of the library. -const Version = "1.5.0" +const Version = "1.15.1" diff --git a/vendor/cloud.google.com/go/trace/apiv2/doc.go b/vendor/cloud.google.com/go/trace/apiv2/doc.go index b58f874c37e..4c1ce50139e 100644 --- a/vendor/cloud.google.com/go/trace/apiv2/doc.go +++ b/vendor/cloud.google.com/go/trace/apiv2/doc.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,61 +21,77 @@ // is collected for all App Engine applications by default. Trace data from // other applications can be provided using this API. This library is used to // interact with the Trace API directly. If you are looking to instrument -// your application for Stackdriver Trace, we recommend using OpenCensus. +// your application for Stackdriver Trace, we recommend using OpenTelemetry. // -// Example usage +// NOTE: This package is in beta. It is not stable, and may be subject to changes. +// +// # General documentation +// +// For information about setting deadlines, reusing contexts, and more +// please visit https://pkg.go.dev/cloud.google.com/go. +// +// # Example usage // // To get started with this package, create a client. -// ctx := context.Background() -// c, err := trace.NewClient(ctx) -// if err != nil { -// // TODO: Handle error. -// } -// defer c.Close() +// +// ctx := context.Background() +// // This snippet has been automatically generated and should be regarded as a code template only. +// // It will require modifications to work: +// // - It may require correct/in-range values for request initialization. +// // - It may require specifying regional endpoints when creating the service client as shown in: +// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options +// c, err := trace.NewClient(ctx) +// if err != nil { +// // TODO: Handle error. +// } +// defer c.Close() // // The client will use your default application credentials. Clients should be reused instead of created as needed. // The methods of Client are safe for concurrent use by multiple goroutines. // The returned client must be Closed when it is done being used. // -// Using the Client +// # Using the Client // // The following is an example of making an API call with the newly created client. // -// ctx := context.Background() -// c, err := trace.NewClient(ctx) -// if err != nil { -// // TODO: Handle error. -// } -// defer c.Close() +// ctx := context.Background() +// // This snippet has been automatically generated and should be regarded as a code template only. +// // It will require modifications to work: +// // - It may require correct/in-range values for request initialization. +// // - It may require specifying regional endpoints when creating the service client as shown in: +// // https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options +// c, err := trace.NewClient(ctx) +// if err != nil { +// // TODO: Handle error. +// } +// defer c.Close() // -// req := &cloudtracepb.BatchWriteSpansRequest{ -// // TODO: Fill request struct fields. -// // See https://pkg.go.dev/google.golang.org/genproto/googleapis/devtools/cloudtrace/v2#BatchWriteSpansRequest. -// } -// err = c.BatchWriteSpans(ctx, req) -// if err != nil { -// // TODO: Handle error. -// } +// req := &tracepb.BatchWriteSpansRequest{ +// // TODO: Fill request struct fields. +// // See https://pkg.go.dev/cloud.google.com/go/trace/apiv2/tracepb#BatchWriteSpansRequest. +// } +// err = c.BatchWriteSpans(ctx, req) +// if err != nil { +// // TODO: Handle error. +// } // -// Use of Context +// # Inspecting errors +// +// To see examples of how to inspect errors returned by this package please reference +// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors). +// +// # Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. -// -// For information about setting deadlines, reusing contexts, and more -// please visit https://pkg.go.dev/cloud.google.com/go. package trace // import "cloud.google.com/go/trace/apiv2" import ( "context" - "os" - "runtime" - "strconv" - "strings" - "unicode" + "net/http" "google.golang.org/api/option" "google.golang.org/grpc/metadata" @@ -106,16 +122,6 @@ func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { return metadata.NewOutgoingContext(ctx, out) } -func checkDisableDeadlines() (bool, error) { - raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE") - if !ok { - return false, nil - } - - b, err := strconv.ParseBool(raw) - return b, err -} - // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ @@ -124,39 +130,12 @@ func DefaultAuthScopes() []string { } } -// versionGo returns the Go runtime version. The returned string -// has no whitespace, suitable for reporting in header. -func versionGo() string { - const develPrefix = "devel +" - - s := runtime.Version() - if strings.HasPrefix(s, develPrefix) { - s = s[len(develPrefix):] - if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { - s = s[:p] - } - return s - } - - notSemverRune := func(r rune) bool { - return !strings.ContainsRune("0123456789.", r) - } - - if strings.HasPrefix(s, "go1") { - s = s[2:] - var prerelease string - if p := strings.IndexFunc(s, notSemverRune); p >= 0 { - s, prerelease = s[:p], s[p:] - } - if strings.HasSuffix(s, ".") { - s += "0" - } else if strings.Count(s, ".") < 2 { - s += ".0" - } - if prerelease != "" { - s += "-" + prerelease - } - return s +// buildHeaders extracts metadata from the outgoing context, joins it with any other +// given metadata, and converts them into a http.Header. +func buildHeaders(ctx context.Context, mds ...metadata.MD) http.Header { + if cmd, ok := metadata.FromOutgoingContext(ctx); ok { + mds = append(mds, cmd) } - return "UNKNOWN" + md := metadata.Join(mds...) + return http.Header(md) } diff --git a/vendor/cloud.google.com/go/trace/apiv2/gapic_metadata.json b/vendor/cloud.google.com/go/trace/apiv2/gapic_metadata.json index ef3c8d6d045..566e48c5cb8 100644 --- a/vendor/cloud.google.com/go/trace/apiv2/gapic_metadata.json +++ b/vendor/cloud.google.com/go/trace/apiv2/gapic_metadata.json @@ -21,6 +21,21 @@ ] } } + }, + "rest": { + "libraryClient": "Client", + "rpcs": { + "BatchWriteSpans": { + "methods": [ + "BatchWriteSpans" + ] + }, + "CreateSpan": { + "methods": [ + "CreateSpan" + ] + } + } } } } diff --git a/vendor/cloud.google.com/go/trace/apiv2/path_funcs.go b/vendor/cloud.google.com/go/trace/apiv2/path_funcs.go index 80b8d40b58e..e8a8a2b0767 100644 --- a/vendor/cloud.google.com/go/trace/apiv2/path_funcs.go +++ b/vendor/cloud.google.com/go/trace/apiv2/path_funcs.go @@ -17,7 +17,9 @@ package trace // ProjectPath returns the path for the project resource. // // Deprecated: Use -// fmt.Sprintf("projects/%s", project) +// +// fmt.Sprintf("projects/%s", project) +// // instead. func ProjectPath(project string) string { return "" + @@ -29,7 +31,9 @@ func ProjectPath(project string) string { // SpanPath returns the path for the span resource. // // Deprecated: Use -// fmt.Sprintf("projects/%s/traces/%s/spans/%s", project, trace, span) +// +// fmt.Sprintf("projects/%s/traces/%s/spans/%s", project, trace, span) +// // instead. func SpanPath(project, trace, span string) string { return "" + diff --git a/vendor/cloud.google.com/go/trace/apiv2/trace_client.go b/vendor/cloud.google.com/go/trace/apiv2/trace_client.go index b5b265eb444..aaf81a55e0f 100644 --- a/vendor/cloud.google.com/go/trace/apiv2/trace_client.go +++ b/vendor/cloud.google.com/go/trace/apiv2/trace_client.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,20 +17,26 @@ package trace import ( + "bytes" "context" "fmt" + "io" "math" + "net/http" "net/url" "time" + tracepb "cloud.google.com/go/trace/apiv2/tracepb" gax "github.com/googleapis/gax-go/v2" + "google.golang.org/api/googleapi" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" - cloudtracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2" + httptransport "google.golang.org/api/transport/http" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/encoding/protojson" ) var newClientHook clientHook @@ -55,8 +61,21 @@ func defaultGRPCClientOptions() []option.ClientOption { func defaultCallOptions() *CallOptions { return &CallOptions{ - BatchWriteSpans: []gax.CallOption{}, + BatchWriteSpans: []gax.CallOption{ + gax.WithTimeout(120000 * time.Millisecond), + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.Unavailable, + codes.DeadlineExceeded, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 30000 * time.Millisecond, + Multiplier: 2.00, + }) + }), + }, CreateSpan: []gax.CallOption{ + gax.WithTimeout(120000 * time.Millisecond), gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, @@ -71,23 +90,54 @@ func defaultCallOptions() *CallOptions { } } -// internalClient is an interface that defines the methods availaible from Stackdriver Trace API. +func defaultRESTCallOptions() *CallOptions { + return &CallOptions{ + BatchWriteSpans: []gax.CallOption{ + gax.WithTimeout(120000 * time.Millisecond), + gax.WithRetry(func() gax.Retryer { + return gax.OnHTTPCodes(gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 30000 * time.Millisecond, + Multiplier: 2.00, + }, + http.StatusServiceUnavailable, + http.StatusGatewayTimeout) + }), + }, + CreateSpan: []gax.CallOption{ + gax.WithTimeout(120000 * time.Millisecond), + gax.WithRetry(func() gax.Retryer { + return gax.OnHTTPCodes(gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 1000 * time.Millisecond, + Multiplier: 1.20, + }, + http.StatusServiceUnavailable, + http.StatusGatewayTimeout) + }), + }, + } +} + +// internalClient is an interface that defines the methods available from Stackdriver Trace API. type internalClient interface { Close() error setGoogleClientInfo(...string) Connection() *grpc.ClientConn - BatchWriteSpans(context.Context, *cloudtracepb.BatchWriteSpansRequest, ...gax.CallOption) error - CreateSpan(context.Context, *cloudtracepb.Span, ...gax.CallOption) (*cloudtracepb.Span, error) + BatchWriteSpans(context.Context, *tracepb.BatchWriteSpansRequest, ...gax.CallOption) error + CreateSpan(context.Context, *tracepb.Span, ...gax.CallOption) (*tracepb.Span, error) } // Client is a client for interacting with Stackdriver Trace API. // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. // -// This file describes an API for collecting and viewing traces and spans -// within a trace. A Trace is a collection of spans corresponding to a single -// operation or set of operations for an application. A span is an individual -// timed event which forms a node of the trace tree. A single trace may -// contain span(s) from multiple services. +// Service for collecting and viewing traces and spans within a trace. +// +// A trace is a collection of spans corresponding to a single +// operation or a set of operations in an application. +// +// A span is an individual timed event which forms a node of the trace tree. +// A single trace can contain spans from multiple services. type Client struct { // The internal transport-dependent client. internalClient internalClient @@ -113,19 +163,20 @@ func (c *Client) setGoogleClientInfo(keyval ...string) { // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *Client) Connection() *grpc.ClientConn { return c.internalClient.Connection() } -// BatchWriteSpans sends new spans to new or existing traces. You cannot update +// BatchWriteSpans batch writes new spans to new or existing traces. You cannot update // existing spans. -func (c *Client) BatchWriteSpans(ctx context.Context, req *cloudtracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { +func (c *Client) BatchWriteSpans(ctx context.Context, req *tracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { return c.internalClient.BatchWriteSpans(ctx, req, opts...) } // CreateSpan creates a new span. -func (c *Client) CreateSpan(ctx context.Context, req *cloudtracepb.Span, opts ...gax.CallOption) (*cloudtracepb.Span, error) { +func (c *Client) CreateSpan(ctx context.Context, req *tracepb.Span, opts ...gax.CallOption) (*tracepb.Span, error) { return c.internalClient.CreateSpan(ctx, req, opts...) } @@ -136,14 +187,11 @@ type gRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool - // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE - disableDeadlines bool - // Points back to the CallOptions field of the containing Client CallOptions **CallOptions // The gRPC API client. - client cloudtracepb.TraceServiceClient + client tracepb.TraceServiceClient // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD @@ -152,11 +200,13 @@ type gRPCClient struct { // NewClient creates a new trace service client based on gRPC. // The returned client must be Closed when it is done being used to clean up its underlying connections. // -// This file describes an API for collecting and viewing traces and spans -// within a trace. A Trace is a collection of spans corresponding to a single -// operation or set of operations for an application. A span is an individual -// timed event which forms a node of the trace tree. A single trace may -// contain span(s) from multiple services. +// Service for collecting and viewing traces and spans within a trace. +// +// A trace is a collection of spans corresponding to a single +// operation or a set of operations in an application. +// +// A span is an individual timed event which forms a node of the trace tree. +// A single trace can contain spans from multiple services. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { clientOpts := defaultGRPCClientOptions() if newClientHook != nil { @@ -167,11 +217,6 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error clientOpts = append(clientOpts, hookOpts...) } - disableDeadlines, err := checkDisableDeadlines() - if err != nil { - return nil, err - } - connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err @@ -179,10 +224,9 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error client := Client{CallOptions: defaultCallOptions()} c := &gRPCClient{ - connPool: connPool, - disableDeadlines: disableDeadlines, - client: cloudtracepb.NewTraceServiceClient(connPool), - CallOptions: &client.CallOptions, + connPool: connPool, + client: tracepb.NewTraceServiceClient(connPool), + CallOptions: &client.CallOptions, } c.setGoogleClientInfo() @@ -193,7 +237,8 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error // Connection returns a connection to the API service. // -// Deprecated. +// Deprecated: Connections are now pooled so this method does not always +// return the same resource. func (c *gRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } @@ -202,7 +247,7 @@ func (c *gRPCClient) Connection() *grpc.ClientConn { // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *gRPCClient) setGoogleClientInfo(keyval ...string) { - kv := append([]string{"gl-go", versionGo()}, keyval...) + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } @@ -213,12 +258,81 @@ func (c *gRPCClient) Close() error { return c.connPool.Close() } -func (c *gRPCClient) BatchWriteSpans(ctx context.Context, req *cloudtracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 120000*time.Millisecond) - defer cancel() - ctx = cctx +// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. +type restClient struct { + // The http endpoint to connect to. + endpoint string + + // The http client. + httpClient *http.Client + + // The x-goog-* metadata to be sent with each request. + xGoogMetadata metadata.MD + + // Points back to the CallOptions field of the containing Client + CallOptions **CallOptions +} + +// NewRESTClient creates a new trace service rest client. +// +// Service for collecting and viewing traces and spans within a trace. +// +// A trace is a collection of spans corresponding to a single +// operation or a set of operations in an application. +// +// A span is an individual timed event which forms a node of the trace tree. +// A single trace can contain spans from multiple services. +func NewRESTClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { + clientOpts := append(defaultRESTClientOptions(), opts...) + httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...) + if err != nil { + return nil, err + } + + callOpts := defaultRESTCallOptions() + c := &restClient{ + endpoint: endpoint, + httpClient: httpClient, + CallOptions: &callOpts, + } + c.setGoogleClientInfo() + + return &Client{internalClient: c, CallOptions: callOpts}, nil +} + +func defaultRESTClientOptions() []option.ClientOption { + return []option.ClientOption{ + internaloption.WithDefaultEndpoint("https://cloudtrace.googleapis.com"), + internaloption.WithDefaultMTLSEndpoint("https://cloudtrace.mtls.googleapis.com"), + internaloption.WithDefaultAudience("https://cloudtrace.googleapis.com/"), + internaloption.WithDefaultScopes(DefaultAuthScopes()...), } +} + +// setGoogleClientInfo sets the name and version of the application in +// the `x-goog-api-client` header passed on each request. Intended for +// use by Google-written clients. +func (c *restClient) setGoogleClientInfo(keyval ...string) { + kv := append([]string{"gl-go", gax.GoVersion}, keyval...) + kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "rest", "UNKNOWN") + c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) +} + +// Close closes the connection to the API service. The user should invoke this when +// the client is no longer required. +func (c *restClient) Close() error { + // Replace httpClient with nil to force cleanup. + c.httpClient = nil + return nil +} + +// Connection returns a connection to the API service. +// +// Deprecated: This method always returns nil. +func (c *restClient) Connection() *grpc.ClientConn { + return nil +} +func (c *gRPCClient) BatchWriteSpans(ctx context.Context, req *tracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) @@ -231,17 +345,12 @@ func (c *gRPCClient) BatchWriteSpans(ctx context.Context, req *cloudtracepb.Batc return err } -func (c *gRPCClient) CreateSpan(ctx context.Context, req *cloudtracepb.Span, opts ...gax.CallOption) (*cloudtracepb.Span, error) { - if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { - cctx, cancel := context.WithTimeout(ctx, 120000*time.Millisecond) - defer cancel() - ctx = cctx - } +func (c *gRPCClient) CreateSpan(ctx context.Context, req *tracepb.Span, opts ...gax.CallOption) (*tracepb.Span, error) { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).CreateSpan[0:len((*c.CallOptions).CreateSpan):len((*c.CallOptions).CreateSpan)], opts...) - var resp *cloudtracepb.Span + var resp *tracepb.Span err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreateSpan(ctx, req, settings.GRPC...) @@ -252,3 +361,114 @@ func (c *gRPCClient) CreateSpan(ctx context.Context, req *cloudtracepb.Span, opt } return resp, nil } + +// BatchWriteSpans batch writes new spans to new or existing traces. You cannot update +// existing spans. +func (c *restClient) BatchWriteSpans(ctx context.Context, req *tracepb.BatchWriteSpansRequest, opts ...gax.CallOption) error { + m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true} + jsonReq, err := m.Marshal(req) + if err != nil { + return err + } + + baseUrl, err := url.Parse(c.endpoint) + if err != nil { + return err + } + baseUrl.Path += fmt.Sprintf("/v2/%v/traces:batchWrite", req.GetName()) + + params := url.Values{} + params.Add("$alt", "json;enum-encoding=int") + + baseUrl.RawQuery = params.Encode() + + // Build HTTP headers from client and context metadata. + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + + headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json")) + return gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + if settings.Path != "" { + baseUrl.Path = settings.Path + } + httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq)) + if err != nil { + return err + } + httpReq = httpReq.WithContext(ctx) + httpReq.Header = headers + + httpRsp, err := c.httpClient.Do(httpReq) + if err != nil { + return err + } + defer httpRsp.Body.Close() + + // Returns nil if there is no error, otherwise wraps + // the response code and body into a non-nil error + return googleapi.CheckResponse(httpRsp) + }, opts...) +} + +// CreateSpan creates a new span. +func (c *restClient) CreateSpan(ctx context.Context, req *tracepb.Span, opts ...gax.CallOption) (*tracepb.Span, error) { + m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true} + jsonReq, err := m.Marshal(req) + if err != nil { + return nil, err + } + + baseUrl, err := url.Parse(c.endpoint) + if err != nil { + return nil, err + } + baseUrl.Path += fmt.Sprintf("/v2/%v", req.GetName()) + + params := url.Values{} + params.Add("$alt", "json;enum-encoding=int") + + baseUrl.RawQuery = params.Encode() + + // Build HTTP headers from client and context metadata. + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + + headers := buildHeaders(ctx, c.xGoogMetadata, md, metadata.Pairs("Content-Type", "application/json")) + opts = append((*c.CallOptions).CreateSpan[0:len((*c.CallOptions).CreateSpan):len((*c.CallOptions).CreateSpan)], opts...) + unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true} + resp := &tracepb.Span{} + e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + if settings.Path != "" { + baseUrl.Path = settings.Path + } + httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq)) + if err != nil { + return err + } + httpReq = httpReq.WithContext(ctx) + httpReq.Header = headers + + httpRsp, err := c.httpClient.Do(httpReq) + if err != nil { + return err + } + defer httpRsp.Body.Close() + + if err = googleapi.CheckResponse(httpRsp); err != nil { + return err + } + + buf, err := io.ReadAll(httpRsp.Body) + if err != nil { + return err + } + + if err := unm.Unmarshal(buf, resp); err != nil { + return err + } + + return nil + }, opts...) + if e != nil { + return nil, e + } + return resp, nil +} diff --git a/vendor/cloud.google.com/go/trace/apiv2/tracepb/trace.pb.go b/vendor/cloud.google.com/go/trace/apiv2/tracepb/trace.pb.go new file mode 100644 index 00000000000..1ea77774460 --- /dev/null +++ b/vendor/cloud.google.com/go/trace/apiv2/tracepb/trace.pb.go @@ -0,0 +1,1961 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/devtools/cloudtrace/v2/trace.proto + +package tracepb + +import ( + reflect "reflect" + sync "sync" + + _ "google.golang.org/genproto/googleapis/api/annotations" + status "google.golang.org/genproto/googleapis/rpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Type of span. Can be used to specify additional relationships between spans +// in addition to a parent/child relationship. +type Span_SpanKind int32 + +const ( + // Unspecified. Do NOT use as default. + // Implementations MAY assume SpanKind.INTERNAL to be default. + Span_SPAN_KIND_UNSPECIFIED Span_SpanKind = 0 + // Indicates that the span is used internally. Default value. + Span_INTERNAL Span_SpanKind = 1 + // Indicates that the span covers server-side handling of an RPC or other + // remote network request. + Span_SERVER Span_SpanKind = 2 + // Indicates that the span covers the client-side wrapper around an RPC or + // other remote request. + Span_CLIENT Span_SpanKind = 3 + // Indicates that the span describes producer sending a message to a broker. + // Unlike client and server, there is no direct critical path latency + // relationship between producer and consumer spans (e.g. publishing a + // message to a pubsub service). + Span_PRODUCER Span_SpanKind = 4 + // Indicates that the span describes consumer receiving a message from a + // broker. Unlike client and server, there is no direct critical path + // latency relationship between producer and consumer spans (e.g. receiving + // a message from a pubsub service subscription). + Span_CONSUMER Span_SpanKind = 5 +) + +// Enum value maps for Span_SpanKind. +var ( + Span_SpanKind_name = map[int32]string{ + 0: "SPAN_KIND_UNSPECIFIED", + 1: "INTERNAL", + 2: "SERVER", + 3: "CLIENT", + 4: "PRODUCER", + 5: "CONSUMER", + } + Span_SpanKind_value = map[string]int32{ + "SPAN_KIND_UNSPECIFIED": 0, + "INTERNAL": 1, + "SERVER": 2, + "CLIENT": 3, + "PRODUCER": 4, + "CONSUMER": 5, + } +) + +func (x Span_SpanKind) Enum() *Span_SpanKind { + p := new(Span_SpanKind) + *p = x + return p +} + +func (x Span_SpanKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Span_SpanKind) Descriptor() protoreflect.EnumDescriptor { + return file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[0].Descriptor() +} + +func (Span_SpanKind) Type() protoreflect.EnumType { + return &file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[0] +} + +func (x Span_SpanKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Span_SpanKind.Descriptor instead. +func (Span_SpanKind) EnumDescriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 0} +} + +// Indicates whether the message was sent or received. +type Span_TimeEvent_MessageEvent_Type int32 + +const ( + // Unknown event type. + Span_TimeEvent_MessageEvent_TYPE_UNSPECIFIED Span_TimeEvent_MessageEvent_Type = 0 + // Indicates a sent message. + Span_TimeEvent_MessageEvent_SENT Span_TimeEvent_MessageEvent_Type = 1 + // Indicates a received message. + Span_TimeEvent_MessageEvent_RECEIVED Span_TimeEvent_MessageEvent_Type = 2 +) + +// Enum value maps for Span_TimeEvent_MessageEvent_Type. +var ( + Span_TimeEvent_MessageEvent_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "SENT", + 2: "RECEIVED", + } + Span_TimeEvent_MessageEvent_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "SENT": 1, + "RECEIVED": 2, + } +) + +func (x Span_TimeEvent_MessageEvent_Type) Enum() *Span_TimeEvent_MessageEvent_Type { + p := new(Span_TimeEvent_MessageEvent_Type) + *p = x + return p +} + +func (x Span_TimeEvent_MessageEvent_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Span_TimeEvent_MessageEvent_Type) Descriptor() protoreflect.EnumDescriptor { + return file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[1].Descriptor() +} + +func (Span_TimeEvent_MessageEvent_Type) Type() protoreflect.EnumType { + return &file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[1] +} + +func (x Span_TimeEvent_MessageEvent_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Span_TimeEvent_MessageEvent_Type.Descriptor instead. +func (Span_TimeEvent_MessageEvent_Type) EnumDescriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 1, 1, 0} +} + +// The relationship of the current span relative to the linked span: child, +// parent, or unspecified. +type Span_Link_Type int32 + +const ( + // The relationship of the two spans is unknown. + Span_Link_TYPE_UNSPECIFIED Span_Link_Type = 0 + // The linked span is a child of the current span. + Span_Link_CHILD_LINKED_SPAN Span_Link_Type = 1 + // The linked span is a parent of the current span. + Span_Link_PARENT_LINKED_SPAN Span_Link_Type = 2 +) + +// Enum value maps for Span_Link_Type. +var ( + Span_Link_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "CHILD_LINKED_SPAN", + 2: "PARENT_LINKED_SPAN", + } + Span_Link_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "CHILD_LINKED_SPAN": 1, + "PARENT_LINKED_SPAN": 2, + } +) + +func (x Span_Link_Type) Enum() *Span_Link_Type { + p := new(Span_Link_Type) + *p = x + return p +} + +func (x Span_Link_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Span_Link_Type) Descriptor() protoreflect.EnumDescriptor { + return file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[2].Descriptor() +} + +func (Span_Link_Type) Type() protoreflect.EnumType { + return &file_google_devtools_cloudtrace_v2_trace_proto_enumTypes[2] +} + +func (x Span_Link_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Span_Link_Type.Descriptor instead. +func (Span_Link_Type) EnumDescriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 3, 0} +} + +// A span represents a single operation within a trace. Spans can be +// nested to form a trace tree. Often, a trace contains a root span +// that describes the end-to-end latency, and one or more subspans for +// its sub-operations. +// +// A trace can also contain multiple root spans, or none at all. +// Spans do not need to be contiguous. There might be +// gaps or overlaps between spans in a trace. +type Span struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The resource name of the span in the following format: + // + // * `projects/[PROJECT_ID]/traces/[TRACE_ID]/spans/[SPAN_ID]` + // + // `[TRACE_ID]` is a unique identifier for a trace within a project; + // it is a 32-character hexadecimal encoding of a 16-byte array. It should + // not be zero. + // + // `[SPAN_ID]` is a unique identifier for a span within a trace; it + // is a 16-character hexadecimal encoding of an 8-byte array. It should not + // be zero. + // . + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Required. The `[SPAN_ID]` portion of the span's resource name. + SpanId string `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` + // The `[SPAN_ID]` of this span's parent span. If this is a root span, + // then this field must be empty. + ParentSpanId string `protobuf:"bytes,3,opt,name=parent_span_id,json=parentSpanId,proto3" json:"parent_span_id,omitempty"` + // Required. A description of the span's operation (up to 128 bytes). + // Cloud Trace displays the description in the + // Cloud console. + // For example, the display name can be a qualified method name or a file name + // and a line number where the operation is called. A best practice is to use + // the same display name within an application and at the same call point. + // This makes it easier to correlate spans in different traces. + DisplayName *TruncatableString `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + // Required. The start time of the span. On the client side, this is the time + // kept by the local machine where the span execution starts. On the server + // side, this is the time when the server's application handler starts + // running. + StartTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + // Required. The end time of the span. On the client side, this is the time + // kept by the local machine where the span execution ends. On the server + // side, this is the time when the server application handler stops running. + EndTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + // A set of attributes on the span. You can have up to 32 attributes per + // span. + Attributes *Span_Attributes `protobuf:"bytes,7,opt,name=attributes,proto3" json:"attributes,omitempty"` + // Stack trace captured at the start of the span. + StackTrace *StackTrace `protobuf:"bytes,8,opt,name=stack_trace,json=stackTrace,proto3" json:"stack_trace,omitempty"` + // A set of time events. You can have up to 32 annotations and 128 message + // events per span. + TimeEvents *Span_TimeEvents `protobuf:"bytes,9,opt,name=time_events,json=timeEvents,proto3" json:"time_events,omitempty"` + // Links associated with the span. You can have up to 128 links per Span. + Links *Span_Links `protobuf:"bytes,10,opt,name=links,proto3" json:"links,omitempty"` + // Optional. The final status for this span. + Status *status.Status `protobuf:"bytes,11,opt,name=status,proto3" json:"status,omitempty"` + // Optional. Set this parameter to indicate whether this span is in + // the same process as its parent. If you do not set this parameter, + // Trace is unable to take advantage of this helpful information. + SameProcessAsParentSpan *wrapperspb.BoolValue `protobuf:"bytes,12,opt,name=same_process_as_parent_span,json=sameProcessAsParentSpan,proto3" json:"same_process_as_parent_span,omitempty"` + // Optional. The number of child spans that were generated while this span + // was active. If set, allows implementation to detect missing child spans. + ChildSpanCount *wrapperspb.Int32Value `protobuf:"bytes,13,opt,name=child_span_count,json=childSpanCount,proto3" json:"child_span_count,omitempty"` + // Optional. Distinguishes between spans generated in a particular context. + // For example, two spans with the same name may be distinguished using + // `CLIENT` (caller) and `SERVER` (callee) to identify an RPC call. + SpanKind Span_SpanKind `protobuf:"varint,14,opt,name=span_kind,json=spanKind,proto3,enum=google.devtools.cloudtrace.v2.Span_SpanKind" json:"span_kind,omitempty"` +} + +func (x *Span) Reset() { + *x = Span{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span) ProtoMessage() {} + +func (x *Span) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span.ProtoReflect.Descriptor instead. +func (*Span) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0} +} + +func (x *Span) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Span) GetSpanId() string { + if x != nil { + return x.SpanId + } + return "" +} + +func (x *Span) GetParentSpanId() string { + if x != nil { + return x.ParentSpanId + } + return "" +} + +func (x *Span) GetDisplayName() *TruncatableString { + if x != nil { + return x.DisplayName + } + return nil +} + +func (x *Span) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *Span) GetEndTime() *timestamppb.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + +func (x *Span) GetAttributes() *Span_Attributes { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *Span) GetStackTrace() *StackTrace { + if x != nil { + return x.StackTrace + } + return nil +} + +func (x *Span) GetTimeEvents() *Span_TimeEvents { + if x != nil { + return x.TimeEvents + } + return nil +} + +func (x *Span) GetLinks() *Span_Links { + if x != nil { + return x.Links + } + return nil +} + +func (x *Span) GetStatus() *status.Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *Span) GetSameProcessAsParentSpan() *wrapperspb.BoolValue { + if x != nil { + return x.SameProcessAsParentSpan + } + return nil +} + +func (x *Span) GetChildSpanCount() *wrapperspb.Int32Value { + if x != nil { + return x.ChildSpanCount + } + return nil +} + +func (x *Span) GetSpanKind() Span_SpanKind { + if x != nil { + return x.SpanKind + } + return Span_SPAN_KIND_UNSPECIFIED +} + +// The allowed types for `[VALUE]` in a `[KEY]:[VALUE]` attribute. +type AttributeValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type of the value. + // + // Types that are assignable to Value: + // *AttributeValue_StringValue + // *AttributeValue_IntValue + // *AttributeValue_BoolValue + Value isAttributeValue_Value `protobuf_oneof:"value"` +} + +func (x *AttributeValue) Reset() { + *x = AttributeValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AttributeValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AttributeValue) ProtoMessage() {} + +func (x *AttributeValue) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AttributeValue.ProtoReflect.Descriptor instead. +func (*AttributeValue) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{1} +} + +func (m *AttributeValue) GetValue() isAttributeValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *AttributeValue) GetStringValue() *TruncatableString { + if x, ok := x.GetValue().(*AttributeValue_StringValue); ok { + return x.StringValue + } + return nil +} + +func (x *AttributeValue) GetIntValue() int64 { + if x, ok := x.GetValue().(*AttributeValue_IntValue); ok { + return x.IntValue + } + return 0 +} + +func (x *AttributeValue) GetBoolValue() bool { + if x, ok := x.GetValue().(*AttributeValue_BoolValue); ok { + return x.BoolValue + } + return false +} + +type isAttributeValue_Value interface { + isAttributeValue_Value() +} + +type AttributeValue_StringValue struct { + // A string up to 256 bytes long. + StringValue *TruncatableString `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type AttributeValue_IntValue struct { + // A 64-bit signed integer. + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` +} + +type AttributeValue_BoolValue struct { + // A Boolean value represented by `true` or `false`. + BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +func (*AttributeValue_StringValue) isAttributeValue_Value() {} + +func (*AttributeValue_IntValue) isAttributeValue_Value() {} + +func (*AttributeValue_BoolValue) isAttributeValue_Value() {} + +// A call stack appearing in a trace. +type StackTrace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Stack frames in this stack trace. A maximum of 128 frames are allowed. + StackFrames *StackTrace_StackFrames `protobuf:"bytes,1,opt,name=stack_frames,json=stackFrames,proto3" json:"stack_frames,omitempty"` + // The hash ID is used to conserve network bandwidth for duplicate + // stack traces within a single trace. + // + // Often multiple spans will have identical stack traces. + // The first occurrence of a stack trace should contain both the + // `stackFrame` content and a value in `stackTraceHashId`. + // + // Subsequent spans within the same request can refer + // to that stack trace by only setting `stackTraceHashId`. + StackTraceHashId int64 `protobuf:"varint,2,opt,name=stack_trace_hash_id,json=stackTraceHashId,proto3" json:"stack_trace_hash_id,omitempty"` +} + +func (x *StackTrace) Reset() { + *x = StackTrace{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StackTrace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackTrace) ProtoMessage() {} + +func (x *StackTrace) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackTrace.ProtoReflect.Descriptor instead. +func (*StackTrace) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{2} +} + +func (x *StackTrace) GetStackFrames() *StackTrace_StackFrames { + if x != nil { + return x.StackFrames + } + return nil +} + +func (x *StackTrace) GetStackTraceHashId() int64 { + if x != nil { + return x.StackTraceHashId + } + return 0 +} + +// Binary module. +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // For example: main binary, kernel modules, and dynamic libraries + // such as libc.so, sharedlib.so (up to 256 bytes). + Module *TruncatableString `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` + // A unique identifier for the module, usually a hash of its + // contents (up to 128 bytes). + BuildId *TruncatableString `protobuf:"bytes,2,opt,name=build_id,json=buildId,proto3" json:"build_id,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{3} +} + +func (x *Module) GetModule() *TruncatableString { + if x != nil { + return x.Module + } + return nil +} + +func (x *Module) GetBuildId() *TruncatableString { + if x != nil { + return x.BuildId + } + return nil +} + +// Represents a string that might be shortened to a specified length. +type TruncatableString struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The shortened string. For example, if the original string is 500 + // bytes long and the limit of the string is 128 bytes, then + // `value` contains the first 128 bytes of the 500-byte string. + // + // Truncation always happens on a UTF8 character boundary. If there + // are multi-byte characters in the string, then the length of the + // shortened string might be less than the size limit. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + // The number of bytes removed from the original string. If this + // value is 0, then the string was not shortened. + TruncatedByteCount int32 `protobuf:"varint,2,opt,name=truncated_byte_count,json=truncatedByteCount,proto3" json:"truncated_byte_count,omitempty"` +} + +func (x *TruncatableString) Reset() { + *x = TruncatableString{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TruncatableString) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TruncatableString) ProtoMessage() {} + +func (x *TruncatableString) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TruncatableString.ProtoReflect.Descriptor instead. +func (*TruncatableString) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{4} +} + +func (x *TruncatableString) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *TruncatableString) GetTruncatedByteCount() int32 { + if x != nil { + return x.TruncatedByteCount + } + return 0 +} + +// A set of attributes as key-value pairs. +type Span_Attributes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A set of attributes. Each attribute's key can be up to 128 bytes + // long. The value can be a string up to 256 bytes, a signed 64-bit integer, + // or the boolean values `true` or `false`. For example: + // + // "/instance_id": { "string_value": { "value": "my-instance" } } + // "/http/request_bytes": { "int_value": 300 } + // "abc.com/myattribute": { "bool_value": false } + AttributeMap map[string]*AttributeValue `protobuf:"bytes,1,rep,name=attribute_map,json=attributeMap,proto3" json:"attribute_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The number of attributes that were discarded. Attributes can be discarded + // because their keys are too long or because there are too many attributes. + // If this value is 0 then all attributes are valid. + DroppedAttributesCount int32 `protobuf:"varint,2,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3" json:"dropped_attributes_count,omitempty"` +} + +func (x *Span_Attributes) Reset() { + *x = Span_Attributes{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_Attributes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_Attributes) ProtoMessage() {} + +func (x *Span_Attributes) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_Attributes.ProtoReflect.Descriptor instead. +func (*Span_Attributes) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Span_Attributes) GetAttributeMap() map[string]*AttributeValue { + if x != nil { + return x.AttributeMap + } + return nil +} + +func (x *Span_Attributes) GetDroppedAttributesCount() int32 { + if x != nil { + return x.DroppedAttributesCount + } + return 0 +} + +// A time-stamped annotation or message event in the Span. +type Span_TimeEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The timestamp indicating the time the event occurred. + Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + // A `TimeEvent` can contain either an `Annotation` object or a + // `MessageEvent` object, but not both. + // + // Types that are assignable to Value: + // *Span_TimeEvent_Annotation_ + // *Span_TimeEvent_MessageEvent_ + Value isSpan_TimeEvent_Value `protobuf_oneof:"value"` +} + +func (x *Span_TimeEvent) Reset() { + *x = Span_TimeEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_TimeEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_TimeEvent) ProtoMessage() {} + +func (x *Span_TimeEvent) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_TimeEvent.ProtoReflect.Descriptor instead. +func (*Span_TimeEvent) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *Span_TimeEvent) GetTime() *timestamppb.Timestamp { + if x != nil { + return x.Time + } + return nil +} + +func (m *Span_TimeEvent) GetValue() isSpan_TimeEvent_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *Span_TimeEvent) GetAnnotation() *Span_TimeEvent_Annotation { + if x, ok := x.GetValue().(*Span_TimeEvent_Annotation_); ok { + return x.Annotation + } + return nil +} + +func (x *Span_TimeEvent) GetMessageEvent() *Span_TimeEvent_MessageEvent { + if x, ok := x.GetValue().(*Span_TimeEvent_MessageEvent_); ok { + return x.MessageEvent + } + return nil +} + +type isSpan_TimeEvent_Value interface { + isSpan_TimeEvent_Value() +} + +type Span_TimeEvent_Annotation_ struct { + // Text annotation with a set of attributes. + Annotation *Span_TimeEvent_Annotation `protobuf:"bytes,2,opt,name=annotation,proto3,oneof"` +} + +type Span_TimeEvent_MessageEvent_ struct { + // An event describing a message sent/received between Spans. + MessageEvent *Span_TimeEvent_MessageEvent `protobuf:"bytes,3,opt,name=message_event,json=messageEvent,proto3,oneof"` +} + +func (*Span_TimeEvent_Annotation_) isSpan_TimeEvent_Value() {} + +func (*Span_TimeEvent_MessageEvent_) isSpan_TimeEvent_Value() {} + +// A collection of `TimeEvent`s. A `TimeEvent` is a time-stamped annotation +// on the span, consisting of either user-supplied key:value pairs, or +// details of a message sent/received between Spans. +type Span_TimeEvents struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A collection of `TimeEvent`s. + TimeEvent []*Span_TimeEvent `protobuf:"bytes,1,rep,name=time_event,json=timeEvent,proto3" json:"time_event,omitempty"` + // The number of dropped annotations in all the included time events. + // If the value is 0, then no annotations were dropped. + DroppedAnnotationsCount int32 `protobuf:"varint,2,opt,name=dropped_annotations_count,json=droppedAnnotationsCount,proto3" json:"dropped_annotations_count,omitempty"` + // The number of dropped message events in all the included time events. + // If the value is 0, then no message events were dropped. + DroppedMessageEventsCount int32 `protobuf:"varint,3,opt,name=dropped_message_events_count,json=droppedMessageEventsCount,proto3" json:"dropped_message_events_count,omitempty"` +} + +func (x *Span_TimeEvents) Reset() { + *x = Span_TimeEvents{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_TimeEvents) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_TimeEvents) ProtoMessage() {} + +func (x *Span_TimeEvents) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_TimeEvents.ProtoReflect.Descriptor instead. +func (*Span_TimeEvents) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *Span_TimeEvents) GetTimeEvent() []*Span_TimeEvent { + if x != nil { + return x.TimeEvent + } + return nil +} + +func (x *Span_TimeEvents) GetDroppedAnnotationsCount() int32 { + if x != nil { + return x.DroppedAnnotationsCount + } + return 0 +} + +func (x *Span_TimeEvents) GetDroppedMessageEventsCount() int32 { + if x != nil { + return x.DroppedMessageEventsCount + } + return 0 +} + +// A pointer from the current span to another span in the same trace or in a +// different trace. For example, this can be used in batching operations, +// where a single batch handler processes multiple requests from different +// traces or when the handler receives a request from a different project. +type Span_Link struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The `[TRACE_ID]` for a trace within a project. + TraceId string `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + // The `[SPAN_ID]` for a span within a trace. + SpanId string `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` + // The relationship of the current span relative to the linked span. + Type Span_Link_Type `protobuf:"varint,3,opt,name=type,proto3,enum=google.devtools.cloudtrace.v2.Span_Link_Type" json:"type,omitempty"` + // A set of attributes on the link. Up to 32 attributes can be + // specified per link. + Attributes *Span_Attributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"` +} + +func (x *Span_Link) Reset() { + *x = Span_Link{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_Link) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_Link) ProtoMessage() {} + +func (x *Span_Link) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_Link.ProtoReflect.Descriptor instead. +func (*Span_Link) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *Span_Link) GetTraceId() string { + if x != nil { + return x.TraceId + } + return "" +} + +func (x *Span_Link) GetSpanId() string { + if x != nil { + return x.SpanId + } + return "" +} + +func (x *Span_Link) GetType() Span_Link_Type { + if x != nil { + return x.Type + } + return Span_Link_TYPE_UNSPECIFIED +} + +func (x *Span_Link) GetAttributes() *Span_Attributes { + if x != nil { + return x.Attributes + } + return nil +} + +// A collection of links, which are references from this span to a span +// in the same or different trace. +type Span_Links struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A collection of links. + Link []*Span_Link `protobuf:"bytes,1,rep,name=link,proto3" json:"link,omitempty"` + // The number of dropped links after the maximum size was enforced. If + // this value is 0, then no links were dropped. + DroppedLinksCount int32 `protobuf:"varint,2,opt,name=dropped_links_count,json=droppedLinksCount,proto3" json:"dropped_links_count,omitempty"` +} + +func (x *Span_Links) Reset() { + *x = Span_Links{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_Links) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_Links) ProtoMessage() {} + +func (x *Span_Links) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_Links.ProtoReflect.Descriptor instead. +func (*Span_Links) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *Span_Links) GetLink() []*Span_Link { + if x != nil { + return x.Link + } + return nil +} + +func (x *Span_Links) GetDroppedLinksCount() int32 { + if x != nil { + return x.DroppedLinksCount + } + return 0 +} + +// Text annotation with a set of attributes. +type Span_TimeEvent_Annotation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A user-supplied message describing the event. The maximum length for + // the description is 256 bytes. + Description *TruncatableString `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + // A set of attributes on the annotation. You can have up to 4 attributes + // per Annotation. + Attributes *Span_Attributes `protobuf:"bytes,2,opt,name=attributes,proto3" json:"attributes,omitempty"` +} + +func (x *Span_TimeEvent_Annotation) Reset() { + *x = Span_TimeEvent_Annotation{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_TimeEvent_Annotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_TimeEvent_Annotation) ProtoMessage() {} + +func (x *Span_TimeEvent_Annotation) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_TimeEvent_Annotation.ProtoReflect.Descriptor instead. +func (*Span_TimeEvent_Annotation) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 1, 0} +} + +func (x *Span_TimeEvent_Annotation) GetDescription() *TruncatableString { + if x != nil { + return x.Description + } + return nil +} + +func (x *Span_TimeEvent_Annotation) GetAttributes() *Span_Attributes { + if x != nil { + return x.Attributes + } + return nil +} + +// An event describing a message sent/received between Spans. +type Span_TimeEvent_MessageEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Type of MessageEvent. Indicates whether the message was sent or + // received. + Type Span_TimeEvent_MessageEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=google.devtools.cloudtrace.v2.Span_TimeEvent_MessageEvent_Type" json:"type,omitempty"` + // An identifier for the MessageEvent's message that can be used to match + // `SENT` and `RECEIVED` MessageEvents. + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + // The number of uncompressed bytes sent or received. + UncompressedSizeBytes int64 `protobuf:"varint,3,opt,name=uncompressed_size_bytes,json=uncompressedSizeBytes,proto3" json:"uncompressed_size_bytes,omitempty"` + // The number of compressed bytes sent or received. If missing, the + // compressed size is assumed to be the same size as the uncompressed + // size. + CompressedSizeBytes int64 `protobuf:"varint,4,opt,name=compressed_size_bytes,json=compressedSizeBytes,proto3" json:"compressed_size_bytes,omitempty"` +} + +func (x *Span_TimeEvent_MessageEvent) Reset() { + *x = Span_TimeEvent_MessageEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Span_TimeEvent_MessageEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Span_TimeEvent_MessageEvent) ProtoMessage() {} + +func (x *Span_TimeEvent_MessageEvent) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Span_TimeEvent_MessageEvent.ProtoReflect.Descriptor instead. +func (*Span_TimeEvent_MessageEvent) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{0, 1, 1} +} + +func (x *Span_TimeEvent_MessageEvent) GetType() Span_TimeEvent_MessageEvent_Type { + if x != nil { + return x.Type + } + return Span_TimeEvent_MessageEvent_TYPE_UNSPECIFIED +} + +func (x *Span_TimeEvent_MessageEvent) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Span_TimeEvent_MessageEvent) GetUncompressedSizeBytes() int64 { + if x != nil { + return x.UncompressedSizeBytes + } + return 0 +} + +func (x *Span_TimeEvent_MessageEvent) GetCompressedSizeBytes() int64 { + if x != nil { + return x.CompressedSizeBytes + } + return 0 +} + +// Represents a single stack frame in a stack trace. +type StackTrace_StackFrame struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The fully-qualified name that uniquely identifies the function or + // method that is active in this frame (up to 1024 bytes). + FunctionName *TruncatableString `protobuf:"bytes,1,opt,name=function_name,json=functionName,proto3" json:"function_name,omitempty"` + // An un-mangled function name, if `function_name` is mangled. + // To get information about name mangling, run + // [this search](https://www.google.com/search?q=cxx+name+mangling). + // The name can be fully-qualified (up to 1024 bytes). + OriginalFunctionName *TruncatableString `protobuf:"bytes,2,opt,name=original_function_name,json=originalFunctionName,proto3" json:"original_function_name,omitempty"` + // The name of the source file where the function call appears (up to 256 + // bytes). + FileName *TruncatableString `protobuf:"bytes,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // The line number in `file_name` where the function call appears. + LineNumber int64 `protobuf:"varint,4,opt,name=line_number,json=lineNumber,proto3" json:"line_number,omitempty"` + // The column number where the function call appears, if available. + // This is important in JavaScript because of its anonymous functions. + ColumnNumber int64 `protobuf:"varint,5,opt,name=column_number,json=columnNumber,proto3" json:"column_number,omitempty"` + // The binary module from where the code was loaded. + LoadModule *Module `protobuf:"bytes,6,opt,name=load_module,json=loadModule,proto3" json:"load_module,omitempty"` + // The version of the deployed source code (up to 128 bytes). + SourceVersion *TruncatableString `protobuf:"bytes,7,opt,name=source_version,json=sourceVersion,proto3" json:"source_version,omitempty"` +} + +func (x *StackTrace_StackFrame) Reset() { + *x = StackTrace_StackFrame{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StackTrace_StackFrame) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackTrace_StackFrame) ProtoMessage() {} + +func (x *StackTrace_StackFrame) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackTrace_StackFrame.ProtoReflect.Descriptor instead. +func (*StackTrace_StackFrame) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *StackTrace_StackFrame) GetFunctionName() *TruncatableString { + if x != nil { + return x.FunctionName + } + return nil +} + +func (x *StackTrace_StackFrame) GetOriginalFunctionName() *TruncatableString { + if x != nil { + return x.OriginalFunctionName + } + return nil +} + +func (x *StackTrace_StackFrame) GetFileName() *TruncatableString { + if x != nil { + return x.FileName + } + return nil +} + +func (x *StackTrace_StackFrame) GetLineNumber() int64 { + if x != nil { + return x.LineNumber + } + return 0 +} + +func (x *StackTrace_StackFrame) GetColumnNumber() int64 { + if x != nil { + return x.ColumnNumber + } + return 0 +} + +func (x *StackTrace_StackFrame) GetLoadModule() *Module { + if x != nil { + return x.LoadModule + } + return nil +} + +func (x *StackTrace_StackFrame) GetSourceVersion() *TruncatableString { + if x != nil { + return x.SourceVersion + } + return nil +} + +// A collection of stack frames, which can be truncated. +type StackTrace_StackFrames struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Stack frames in this call stack. + Frame []*StackTrace_StackFrame `protobuf:"bytes,1,rep,name=frame,proto3" json:"frame,omitempty"` + // The number of stack frames that were dropped because there + // were too many stack frames. + // If this value is 0, then no stack frames were dropped. + DroppedFramesCount int32 `protobuf:"varint,2,opt,name=dropped_frames_count,json=droppedFramesCount,proto3" json:"dropped_frames_count,omitempty"` +} + +func (x *StackTrace_StackFrames) Reset() { + *x = StackTrace_StackFrames{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StackTrace_StackFrames) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackTrace_StackFrames) ProtoMessage() {} + +func (x *StackTrace_StackFrames) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackTrace_StackFrames.ProtoReflect.Descriptor instead. +func (*StackTrace_StackFrames) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *StackTrace_StackFrames) GetFrame() []*StackTrace_StackFrame { + if x != nil { + return x.Frame + } + return nil +} + +func (x *StackTrace_StackFrames) GetDroppedFramesCount() int32 { + if x != nil { + return x.DroppedFramesCount + } + return 0 +} + +var File_google_devtools_cloudtrace_v2_trace_proto protoreflect.FileDescriptor + +var file_google_devtools_cloudtrace_v2_trace_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x32, 0x2f, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, + 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x72, 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xb0, 0x15, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, + 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x58, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, + 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x3e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x0a, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, + 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, + 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0b, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, + 0x32, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, + 0x61, 0x6e, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x74, + 0x69, 0x6d, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x05, 0x6c, 0x69, 0x6e, + 0x6b, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, + 0x6e, 0x6b, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x5d, 0x0a, 0x1b, 0x73, + 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x73, 0x5f, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x17, 0x73, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x73, + 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x4a, 0x0a, 0x10, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x53, 0x70, 0x61, + 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4e, 0x0a, 0x09, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, + 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x73, 0x70, + 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x1a, 0x9d, 0x02, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x65, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, + 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x38, 0x0a, 0x18, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x16, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x6e, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x43, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xce, 0x05, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x61, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x1a, 0xb0, 0x01, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x95, 0x02, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, + 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x17, + 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x75, + 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x13, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, + 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x01, + 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x02, 0x42, 0x07, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0xd7, 0x01, 0x0a, 0x0a, 0x54, 0x69, 0x6d, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x19, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, + 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x3f, 0x0a, 0x1c, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x1a, 0x9a, 0x02, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x41, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, + 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x4e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, + 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x22, 0x4b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x15, 0x0a, 0x11, 0x43, 0x48, 0x49, 0x4c, 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44, 0x5f, + 0x53, 0x50, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, + 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44, 0x5f, 0x53, 0x50, 0x41, 0x4e, 0x10, 0x02, 0x1a, 0x75, + 0x0a, 0x05, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x3c, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, + 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, + 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x67, 0x0a, 0x08, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, + 0x64, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, + 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, + 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x45, 0x52, 0x10, 0x04, + 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x10, 0x05, 0x3a, 0x53, + 0xea, 0x41, 0x50, 0x0a, 0x1e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, + 0x70, 0x61, 0x6e, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x2f, 0x7b, 0x73, 0x70, + 0x61, 0x6e, 0x7d, 0x22, 0xb0, 0x01, 0x0a, 0x0e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, + 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x48, 0x00, + 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, + 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, + 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa7, 0x06, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x63, + 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, + 0x65, 0x73, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, + 0x2d, 0x0a, 0x13, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x48, 0x61, 0x73, 0x68, 0x49, 0x64, 0x1a, 0x81, + 0x04, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x55, 0x0a, + 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x66, 0x0a, 0x16, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x14, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x09, + 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, + 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, + 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x46, 0x0a, 0x0b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0a, 0x6c, + 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x57, 0x0a, 0x0e, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, + 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x1a, 0x8b, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, + 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, + 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, + 0x32, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x14, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x64, 0x72, + 0x6f, 0x70, 0x70, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x9f, 0x01, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x48, 0x0a, 0x06, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, + 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x49, 0x64, 0x22, 0x5b, 0x0a, 0x11, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x0a, + 0x14, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x74, 0x72, 0x75, + 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, + 0xad, 0x01, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, + 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x32, 0x42, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x76, 0x32, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x62, 0x3b, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x70, 0x62, 0xaa, 0x02, 0x15, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x15, 0x47, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x54, 0x72, 0x61, 0x63, + 0x65, 0x5c, 0x56, 0x32, 0xea, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x32, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_devtools_cloudtrace_v2_trace_proto_rawDescOnce sync.Once + file_google_devtools_cloudtrace_v2_trace_proto_rawDescData = file_google_devtools_cloudtrace_v2_trace_proto_rawDesc +) + +func file_google_devtools_cloudtrace_v2_trace_proto_rawDescGZIP() []byte { + file_google_devtools_cloudtrace_v2_trace_proto_rawDescOnce.Do(func() { + file_google_devtools_cloudtrace_v2_trace_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_devtools_cloudtrace_v2_trace_proto_rawDescData) + }) + return file_google_devtools_cloudtrace_v2_trace_proto_rawDescData +} + +var file_google_devtools_cloudtrace_v2_trace_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_google_devtools_cloudtrace_v2_trace_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_google_devtools_cloudtrace_v2_trace_proto_goTypes = []interface{}{ + (Span_SpanKind)(0), // 0: google.devtools.cloudtrace.v2.Span.SpanKind + (Span_TimeEvent_MessageEvent_Type)(0), // 1: google.devtools.cloudtrace.v2.Span.TimeEvent.MessageEvent.Type + (Span_Link_Type)(0), // 2: google.devtools.cloudtrace.v2.Span.Link.Type + (*Span)(nil), // 3: google.devtools.cloudtrace.v2.Span + (*AttributeValue)(nil), // 4: google.devtools.cloudtrace.v2.AttributeValue + (*StackTrace)(nil), // 5: google.devtools.cloudtrace.v2.StackTrace + (*Module)(nil), // 6: google.devtools.cloudtrace.v2.Module + (*TruncatableString)(nil), // 7: google.devtools.cloudtrace.v2.TruncatableString + (*Span_Attributes)(nil), // 8: google.devtools.cloudtrace.v2.Span.Attributes + (*Span_TimeEvent)(nil), // 9: google.devtools.cloudtrace.v2.Span.TimeEvent + (*Span_TimeEvents)(nil), // 10: google.devtools.cloudtrace.v2.Span.TimeEvents + (*Span_Link)(nil), // 11: google.devtools.cloudtrace.v2.Span.Link + (*Span_Links)(nil), // 12: google.devtools.cloudtrace.v2.Span.Links + nil, // 13: google.devtools.cloudtrace.v2.Span.Attributes.AttributeMapEntry + (*Span_TimeEvent_Annotation)(nil), // 14: google.devtools.cloudtrace.v2.Span.TimeEvent.Annotation + (*Span_TimeEvent_MessageEvent)(nil), // 15: google.devtools.cloudtrace.v2.Span.TimeEvent.MessageEvent + (*StackTrace_StackFrame)(nil), // 16: google.devtools.cloudtrace.v2.StackTrace.StackFrame + (*StackTrace_StackFrames)(nil), // 17: google.devtools.cloudtrace.v2.StackTrace.StackFrames + (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp + (*status.Status)(nil), // 19: google.rpc.Status + (*wrapperspb.BoolValue)(nil), // 20: google.protobuf.BoolValue + (*wrapperspb.Int32Value)(nil), // 21: google.protobuf.Int32Value +} +var file_google_devtools_cloudtrace_v2_trace_proto_depIdxs = []int32{ + 7, // 0: google.devtools.cloudtrace.v2.Span.display_name:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 18, // 1: google.devtools.cloudtrace.v2.Span.start_time:type_name -> google.protobuf.Timestamp + 18, // 2: google.devtools.cloudtrace.v2.Span.end_time:type_name -> google.protobuf.Timestamp + 8, // 3: google.devtools.cloudtrace.v2.Span.attributes:type_name -> google.devtools.cloudtrace.v2.Span.Attributes + 5, // 4: google.devtools.cloudtrace.v2.Span.stack_trace:type_name -> google.devtools.cloudtrace.v2.StackTrace + 10, // 5: google.devtools.cloudtrace.v2.Span.time_events:type_name -> google.devtools.cloudtrace.v2.Span.TimeEvents + 12, // 6: google.devtools.cloudtrace.v2.Span.links:type_name -> google.devtools.cloudtrace.v2.Span.Links + 19, // 7: google.devtools.cloudtrace.v2.Span.status:type_name -> google.rpc.Status + 20, // 8: google.devtools.cloudtrace.v2.Span.same_process_as_parent_span:type_name -> google.protobuf.BoolValue + 21, // 9: google.devtools.cloudtrace.v2.Span.child_span_count:type_name -> google.protobuf.Int32Value + 0, // 10: google.devtools.cloudtrace.v2.Span.span_kind:type_name -> google.devtools.cloudtrace.v2.Span.SpanKind + 7, // 11: google.devtools.cloudtrace.v2.AttributeValue.string_value:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 17, // 12: google.devtools.cloudtrace.v2.StackTrace.stack_frames:type_name -> google.devtools.cloudtrace.v2.StackTrace.StackFrames + 7, // 13: google.devtools.cloudtrace.v2.Module.module:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 7, // 14: google.devtools.cloudtrace.v2.Module.build_id:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 13, // 15: google.devtools.cloudtrace.v2.Span.Attributes.attribute_map:type_name -> google.devtools.cloudtrace.v2.Span.Attributes.AttributeMapEntry + 18, // 16: google.devtools.cloudtrace.v2.Span.TimeEvent.time:type_name -> google.protobuf.Timestamp + 14, // 17: google.devtools.cloudtrace.v2.Span.TimeEvent.annotation:type_name -> google.devtools.cloudtrace.v2.Span.TimeEvent.Annotation + 15, // 18: google.devtools.cloudtrace.v2.Span.TimeEvent.message_event:type_name -> google.devtools.cloudtrace.v2.Span.TimeEvent.MessageEvent + 9, // 19: google.devtools.cloudtrace.v2.Span.TimeEvents.time_event:type_name -> google.devtools.cloudtrace.v2.Span.TimeEvent + 2, // 20: google.devtools.cloudtrace.v2.Span.Link.type:type_name -> google.devtools.cloudtrace.v2.Span.Link.Type + 8, // 21: google.devtools.cloudtrace.v2.Span.Link.attributes:type_name -> google.devtools.cloudtrace.v2.Span.Attributes + 11, // 22: google.devtools.cloudtrace.v2.Span.Links.link:type_name -> google.devtools.cloudtrace.v2.Span.Link + 4, // 23: google.devtools.cloudtrace.v2.Span.Attributes.AttributeMapEntry.value:type_name -> google.devtools.cloudtrace.v2.AttributeValue + 7, // 24: google.devtools.cloudtrace.v2.Span.TimeEvent.Annotation.description:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 8, // 25: google.devtools.cloudtrace.v2.Span.TimeEvent.Annotation.attributes:type_name -> google.devtools.cloudtrace.v2.Span.Attributes + 1, // 26: google.devtools.cloudtrace.v2.Span.TimeEvent.MessageEvent.type:type_name -> google.devtools.cloudtrace.v2.Span.TimeEvent.MessageEvent.Type + 7, // 27: google.devtools.cloudtrace.v2.StackTrace.StackFrame.function_name:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 7, // 28: google.devtools.cloudtrace.v2.StackTrace.StackFrame.original_function_name:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 7, // 29: google.devtools.cloudtrace.v2.StackTrace.StackFrame.file_name:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 6, // 30: google.devtools.cloudtrace.v2.StackTrace.StackFrame.load_module:type_name -> google.devtools.cloudtrace.v2.Module + 7, // 31: google.devtools.cloudtrace.v2.StackTrace.StackFrame.source_version:type_name -> google.devtools.cloudtrace.v2.TruncatableString + 16, // 32: google.devtools.cloudtrace.v2.StackTrace.StackFrames.frame:type_name -> google.devtools.cloudtrace.v2.StackTrace.StackFrame + 33, // [33:33] is the sub-list for method output_type + 33, // [33:33] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name +} + +func init() { file_google_devtools_cloudtrace_v2_trace_proto_init() } +func file_google_devtools_cloudtrace_v2_trace_proto_init() { + if File_google_devtools_cloudtrace_v2_trace_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributeValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StackTrace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TruncatableString); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_Attributes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_TimeEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_TimeEvents); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_Link); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_Links); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_TimeEvent_Annotation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_TimeEvent_MessageEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StackTrace_StackFrame); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StackTrace_StackFrames); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*AttributeValue_StringValue)(nil), + (*AttributeValue_IntValue)(nil), + (*AttributeValue_BoolValue)(nil), + } + file_google_devtools_cloudtrace_v2_trace_proto_msgTypes[6].OneofWrappers = []interface{}{ + (*Span_TimeEvent_Annotation_)(nil), + (*Span_TimeEvent_MessageEvent_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_devtools_cloudtrace_v2_trace_proto_rawDesc, + NumEnums: 3, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_devtools_cloudtrace_v2_trace_proto_goTypes, + DependencyIndexes: file_google_devtools_cloudtrace_v2_trace_proto_depIdxs, + EnumInfos: file_google_devtools_cloudtrace_v2_trace_proto_enumTypes, + MessageInfos: file_google_devtools_cloudtrace_v2_trace_proto_msgTypes, + }.Build() + File_google_devtools_cloudtrace_v2_trace_proto = out.File + file_google_devtools_cloudtrace_v2_trace_proto_rawDesc = nil + file_google_devtools_cloudtrace_v2_trace_proto_goTypes = nil + file_google_devtools_cloudtrace_v2_trace_proto_depIdxs = nil +} diff --git a/vendor/cloud.google.com/go/trace/apiv2/tracepb/tracing.pb.go b/vendor/cloud.google.com/go/trace/apiv2/tracepb/tracing.pb.go new file mode 100644 index 00000000000..83517327a5c --- /dev/null +++ b/vendor/cloud.google.com/go/trace/apiv2/tracepb/tracing.pb.go @@ -0,0 +1,367 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v4.23.2 +// source: google/devtools/cloudtrace/v2/tracing.proto + +package tracepb + +import ( + context "context" + reflect "reflect" + sync "sync" + + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The request message for the `BatchWriteSpans` method. +type BatchWriteSpansRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The name of the project where the spans belong. The format is + // `projects/[PROJECT_ID]`. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Required. A list of new spans. The span names must not match existing + // spans, otherwise the results are undefined. + Spans []*Span `protobuf:"bytes,2,rep,name=spans,proto3" json:"spans,omitempty"` +} + +func (x *BatchWriteSpansRequest) Reset() { + *x = BatchWriteSpansRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_devtools_cloudtrace_v2_tracing_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchWriteSpansRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchWriteSpansRequest) ProtoMessage() {} + +func (x *BatchWriteSpansRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_devtools_cloudtrace_v2_tracing_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchWriteSpansRequest.ProtoReflect.Descriptor instead. +func (*BatchWriteSpansRequest) Descriptor() ([]byte, []int) { + return file_google_devtools_cloudtrace_v2_tracing_proto_rawDescGZIP(), []int{0} +} + +func (x *BatchWriteSpansRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *BatchWriteSpansRequest) GetSpans() []*Span { + if x != nil { + return x.Spans + } + return nil +} + +var File_google_devtools_cloudtrace_v2_tracing_proto protoreflect.FileDescriptor + +var file_google_devtools_cloudtrace_v2_tracing_proto_rawDesc = []byte{ + 0x0a, 0x2b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x32, 0x2f, + 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, + 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x32, 0x2f, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x47, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x73, + 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x42, + 0x03, 0xe0, 0x41, 0x02, 0x52, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x32, 0xba, 0x03, 0x0a, 0x0c, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa1, 0x01, 0x0a, + 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, + 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, + 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x3f, 0xda, 0x41, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, + 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x73, 0x3a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, + 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, + 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x2e, + 0x53, 0x70, 0x61, 0x6e, 0x1a, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x2b, 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x1a, 0x7a, 0xca, 0x41, + 0x19, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x5b, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, + 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, + 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, + 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x42, 0xaf, 0x01, 0x0a, 0x21, 0x63, 0x6f, 0x6d, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x32, 0x42, 0x0c, + 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x62, 0x3b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x62, 0xaa, + 0x02, 0x15, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x54, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x15, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x5c, 0x56, 0x32, 0xea, + 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, + 0x3a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_google_devtools_cloudtrace_v2_tracing_proto_rawDescOnce sync.Once + file_google_devtools_cloudtrace_v2_tracing_proto_rawDescData = file_google_devtools_cloudtrace_v2_tracing_proto_rawDesc +) + +func file_google_devtools_cloudtrace_v2_tracing_proto_rawDescGZIP() []byte { + file_google_devtools_cloudtrace_v2_tracing_proto_rawDescOnce.Do(func() { + file_google_devtools_cloudtrace_v2_tracing_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_devtools_cloudtrace_v2_tracing_proto_rawDescData) + }) + return file_google_devtools_cloudtrace_v2_tracing_proto_rawDescData +} + +var file_google_devtools_cloudtrace_v2_tracing_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_google_devtools_cloudtrace_v2_tracing_proto_goTypes = []interface{}{ + (*BatchWriteSpansRequest)(nil), // 0: google.devtools.cloudtrace.v2.BatchWriteSpansRequest + (*Span)(nil), // 1: google.devtools.cloudtrace.v2.Span + (*emptypb.Empty)(nil), // 2: google.protobuf.Empty +} +var file_google_devtools_cloudtrace_v2_tracing_proto_depIdxs = []int32{ + 1, // 0: google.devtools.cloudtrace.v2.BatchWriteSpansRequest.spans:type_name -> google.devtools.cloudtrace.v2.Span + 0, // 1: google.devtools.cloudtrace.v2.TraceService.BatchWriteSpans:input_type -> google.devtools.cloudtrace.v2.BatchWriteSpansRequest + 1, // 2: google.devtools.cloudtrace.v2.TraceService.CreateSpan:input_type -> google.devtools.cloudtrace.v2.Span + 2, // 3: google.devtools.cloudtrace.v2.TraceService.BatchWriteSpans:output_type -> google.protobuf.Empty + 1, // 4: google.devtools.cloudtrace.v2.TraceService.CreateSpan:output_type -> google.devtools.cloudtrace.v2.Span + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_google_devtools_cloudtrace_v2_tracing_proto_init() } +func file_google_devtools_cloudtrace_v2_tracing_proto_init() { + if File_google_devtools_cloudtrace_v2_tracing_proto != nil { + return + } + file_google_devtools_cloudtrace_v2_trace_proto_init() + if !protoimpl.UnsafeEnabled { + file_google_devtools_cloudtrace_v2_tracing_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchWriteSpansRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_devtools_cloudtrace_v2_tracing_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_google_devtools_cloudtrace_v2_tracing_proto_goTypes, + DependencyIndexes: file_google_devtools_cloudtrace_v2_tracing_proto_depIdxs, + MessageInfos: file_google_devtools_cloudtrace_v2_tracing_proto_msgTypes, + }.Build() + File_google_devtools_cloudtrace_v2_tracing_proto = out.File + file_google_devtools_cloudtrace_v2_tracing_proto_rawDesc = nil + file_google_devtools_cloudtrace_v2_tracing_proto_goTypes = nil + file_google_devtools_cloudtrace_v2_tracing_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// TraceServiceClient is the client API for TraceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type TraceServiceClient interface { + // Batch writes new spans to new or existing traces. You cannot update + // existing spans. + BatchWriteSpans(ctx context.Context, in *BatchWriteSpansRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Creates a new span. + CreateSpan(ctx context.Context, in *Span, opts ...grpc.CallOption) (*Span, error) +} + +type traceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewTraceServiceClient(cc grpc.ClientConnInterface) TraceServiceClient { + return &traceServiceClient{cc} +} + +func (c *traceServiceClient) BatchWriteSpans(ctx context.Context, in *BatchWriteSpansRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/google.devtools.cloudtrace.v2.TraceService/BatchWriteSpans", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *traceServiceClient) CreateSpan(ctx context.Context, in *Span, opts ...grpc.CallOption) (*Span, error) { + out := new(Span) + err := c.cc.Invoke(ctx, "/google.devtools.cloudtrace.v2.TraceService/CreateSpan", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TraceServiceServer is the server API for TraceService service. +type TraceServiceServer interface { + // Batch writes new spans to new or existing traces. You cannot update + // existing spans. + BatchWriteSpans(context.Context, *BatchWriteSpansRequest) (*emptypb.Empty, error) + // Creates a new span. + CreateSpan(context.Context, *Span) (*Span, error) +} + +// UnimplementedTraceServiceServer can be embedded to have forward compatible implementations. +type UnimplementedTraceServiceServer struct { +} + +func (*UnimplementedTraceServiceServer) BatchWriteSpans(context.Context, *BatchWriteSpansRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchWriteSpans not implemented") +} +func (*UnimplementedTraceServiceServer) CreateSpan(context.Context, *Span) (*Span, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSpan not implemented") +} + +func RegisterTraceServiceServer(s *grpc.Server, srv TraceServiceServer) { + s.RegisterService(&_TraceService_serviceDesc, srv) +} + +func _TraceService_BatchWriteSpans_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchWriteSpansRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TraceServiceServer).BatchWriteSpans(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.devtools.cloudtrace.v2.TraceService/BatchWriteSpans", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TraceServiceServer).BatchWriteSpans(ctx, req.(*BatchWriteSpansRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TraceService_CreateSpan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Span) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TraceServiceServer).CreateSpan(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.devtools.cloudtrace.v2.TraceService/CreateSpan", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TraceServiceServer).CreateSpan(ctx, req.(*Span)) + } + return interceptor(ctx, in, info, handler) +} + +var _TraceService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.devtools.cloudtrace.v2.TraceService", + HandlerType: (*TraceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "BatchWriteSpans", + Handler: _TraceService_BatchWriteSpans_Handler, + }, + { + MethodName: "CreateSpan", + Handler: _TraceService_CreateSpan_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/devtools/cloudtrace/v2/tracing.proto", +} diff --git a/vendor/cloud.google.com/go/trace/apiv2/version.go b/vendor/cloud.google.com/go/trace/apiv2/version.go index b52392b7872..ac7a1bda595 100644 --- a/vendor/cloud.google.com/go/trace/apiv2/version.go +++ b/vendor/cloud.google.com/go/trace/apiv2/version.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/cloud.google.com/go/trace/internal/version.go b/vendor/cloud.google.com/go/trace/internal/version.go index d0e4a6fd16b..c7287740734 100644 --- a/vendor/cloud.google.com/go/trace/internal/version.go +++ b/vendor/cloud.google.com/go/trace/internal/version.go @@ -15,4 +15,4 @@ package internal // Version is the current tagged release of the library. -const Version = "1.2.0" +const Version = "1.10.1" diff --git a/vendor/go.opentelemetry.io/contrib/LICENSE b/vendor/github.com/AdaLogics/go-fuzz-headers/LICENSE similarity index 100% rename from vendor/go.opentelemetry.io/contrib/LICENSE rename to vendor/github.com/AdaLogics/go-fuzz-headers/LICENSE diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/README.md b/vendor/github.com/AdaLogics/go-fuzz-headers/README.md new file mode 100644 index 00000000000..0a0d60c746d --- /dev/null +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/README.md @@ -0,0 +1,93 @@ +# go-fuzz-headers +This repository contains various helper functions for go fuzzing. It is mostly used in combination with [go-fuzz](https://github.com/dvyukov/go-fuzz), but compatibility with fuzzing in the standard library will also be supported. Any coverage guided fuzzing engine that provides an array or slice of bytes can be used with go-fuzz-headers. + + +## Usage +Using go-fuzz-headers is easy. First create a new consumer with the bytes provided by the fuzzing engine: + +```go +import ( + fuzz "github.com/AdaLogics/go-fuzz-headers" +) +data := []byte{'R', 'a', 'n', 'd', 'o', 'm'} +f := fuzz.NewConsumer(data) + +``` + +This creates a `Consumer` that consumes the bytes of the input as it uses them to fuzz different types. + +After that, `f` can be used to easily create fuzzed instances of different types. Below are some examples: + +### Structs +One of the most useful features of go-fuzz-headers is its ability to fill structs with the data provided by the fuzzing engine. This is done with a single line: +```go +type Person struct { + Name string + Age int +} +p := Person{} +// Fill p with values based on the data provided by the fuzzing engine: +err := f.GenerateStruct(&p) +``` + +This includes nested structs too. In this example, the fuzz Consumer will also insert values in `p.BestFriend`: +```go +type PersonI struct { + Name string + Age int + BestFriend PersonII +} +type PersonII struct { + Name string + Age int +} +p := PersonI{} +err := f.GenerateStruct(&p) +``` + +If the consumer should insert values for unexported fields as well as exported, this can be enabled with: + +```go +f.AllowUnexportedFields() +``` + +...and disabled with: + +```go +f.DisallowUnexportedFields() +``` + +### Other types: + +Other useful APIs: + +```go +createdString, err := f.GetString() // Gets a string +createdInt, err := f.GetInt() // Gets an integer +createdByte, err := f.GetByte() // Gets a byte +createdBytes, err := f.GetBytes() // Gets a byte slice +createdBool, err := f.GetBool() // Gets a boolean +err := f.FuzzMap(target_map) // Fills a map +createdTarBytes, err := f.TarBytes() // Gets bytes of a valid tar archive +err := f.CreateFiles(inThisDir) // Fills inThisDir with files +createdString, err := f.GetStringFrom("anyCharInThisString", ofThisLength) // Gets a string that consists of chars from "anyCharInThisString" and has the exact length "ofThisLength" +``` + +Most APIs are added as they are needed. + +## Projects that use go-fuzz-headers +- [runC](https://github.com/opencontainers/runc) +- [Istio](https://github.com/istio/istio) +- [Vitess](https://github.com/vitessio/vitess) +- [Containerd](https://github.com/containerd/containerd) + +Feel free to add your own project to the list, if you use go-fuzz-headers to fuzz it. + + + + +## Status +The project is under development and will be updated regularly. + +## References +go-fuzz-headers' approach to fuzzing structs is strongly inspired by [gofuzz](https://github.com/google/gofuzz). \ No newline at end of file diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go b/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go new file mode 100644 index 00000000000..adfeedf5e8a --- /dev/null +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go @@ -0,0 +1,914 @@ +// Copyright 2023 The go-fuzz-headers Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gofuzzheaders + +import ( + "archive/tar" + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math" + "os" + "path/filepath" + "reflect" + "strconv" + "strings" + "time" + "unsafe" +) + +var ( + MaxTotalLen uint32 = 2000000 + maxDepth = 100 +) + +func SetMaxTotalLen(newLen uint32) { + MaxTotalLen = newLen +} + +type ConsumeFuzzer struct { + data []byte + dataTotal uint32 + CommandPart []byte + RestOfArray []byte + NumberOfCalls int + position uint32 + fuzzUnexportedFields bool + curDepth int + Funcs map[reflect.Type]reflect.Value +} + +func IsDivisibleBy(n int, divisibleby int) bool { + return (n % divisibleby) == 0 +} + +func NewConsumer(fuzzData []byte) *ConsumeFuzzer { + return &ConsumeFuzzer{ + data: fuzzData, + dataTotal: uint32(len(fuzzData)), + Funcs: make(map[reflect.Type]reflect.Value), + curDepth: 0, + } +} + +func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error { + if f.dataTotal == 0 { + return errors.New("could not split") + } + numberOfCalls := int(f.data[0]) + if numberOfCalls < minCalls || numberOfCalls > maxCalls { + return errors.New("bad number of calls") + } + if int(f.dataTotal) < numberOfCalls+numberOfCalls+1 { + return errors.New("length of data does not match required parameters") + } + + // Define part 2 and 3 of the data array + commandPart := f.data[1 : numberOfCalls+1] + restOfArray := f.data[numberOfCalls+1:] + + // Just a small check. It is necessary + if len(commandPart) != numberOfCalls { + return errors.New("length of commandPart does not match number of calls") + } + + // Check if restOfArray is divisible by numberOfCalls + if !IsDivisibleBy(len(restOfArray), numberOfCalls) { + return errors.New("length of commandPart does not match number of calls") + } + f.CommandPart = commandPart + f.RestOfArray = restOfArray + f.NumberOfCalls = numberOfCalls + return nil +} + +func (f *ConsumeFuzzer) AllowUnexportedFields() { + f.fuzzUnexportedFields = true +} + +func (f *ConsumeFuzzer) DisallowUnexportedFields() { + f.fuzzUnexportedFields = false +} + +func (f *ConsumeFuzzer) GenerateStruct(targetStruct interface{}) error { + e := reflect.ValueOf(targetStruct).Elem() + return f.fuzzStruct(e, false) +} + +func (f *ConsumeFuzzer) setCustom(v reflect.Value) error { + // First: see if we have a fuzz function for it. + doCustom, ok := f.Funcs[v.Type()] + if !ok { + return fmt.Errorf("could not find a custom function") + } + + switch v.Kind() { + case reflect.Ptr: + if v.IsNil() { + if !v.CanSet() { + return fmt.Errorf("could not use a custom function") + } + v.Set(reflect.New(v.Type().Elem())) + } + case reflect.Map: + if v.IsNil() { + if !v.CanSet() { + return fmt.Errorf("could not use a custom function") + } + v.Set(reflect.MakeMap(v.Type())) + } + default: + return fmt.Errorf("could not use a custom function") + } + + verr := doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ + F: f, + })}) + + // check if we return an error + if verr[0].IsNil() { + return nil + } + return fmt.Errorf("could not use a custom function") +} + +func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error { + if f.curDepth >= maxDepth { + // return err or nil here? + return nil + } + f.curDepth++ + defer func() { f.curDepth-- }() + + // We check if we should check for custom functions + if customFunctions && e.IsValid() && e.CanAddr() { + err := f.setCustom(e.Addr()) + if err != nil { + return err + } + } + + switch e.Kind() { + case reflect.Struct: + for i := 0; i < e.NumField(); i++ { + var v reflect.Value + if !e.Field(i).CanSet() { + if f.fuzzUnexportedFields { + v = reflect.NewAt(e.Field(i).Type(), unsafe.Pointer(e.Field(i).UnsafeAddr())).Elem() + } + if err := f.fuzzStruct(v, customFunctions); err != nil { + return err + } + } else { + v = e.Field(i) + if err := f.fuzzStruct(v, customFunctions); err != nil { + return err + } + } + } + case reflect.String: + str, err := f.GetString() + if err != nil { + return err + } + if e.CanSet() { + e.SetString(str) + } + case reflect.Slice: + var maxElements uint32 + // Byte slices should not be restricted + if e.Type().String() == "[]uint8" { + maxElements = 10000000 + } else { + maxElements = 50 + } + + randQty, err := f.GetUint32() + if err != nil { + return err + } + numOfElements := randQty % maxElements + if (f.dataTotal - f.position) < numOfElements { + numOfElements = f.dataTotal - f.position + } + + uu := reflect.MakeSlice(e.Type(), int(numOfElements), int(numOfElements)) + + for i := 0; i < int(numOfElements); i++ { + // If we have more than 10, then we can proceed with that. + if err := f.fuzzStruct(uu.Index(i), customFunctions); err != nil { + if i >= 10 { + if e.CanSet() { + e.Set(uu) + } + return nil + } else { + return err + } + } + } + if e.CanSet() { + e.Set(uu) + } + case reflect.Uint16: + newInt, err := f.GetUint16() + if err != nil { + return err + } + if e.CanSet() { + e.SetUint(uint64(newInt)) + } + case reflect.Uint32: + newInt, err := f.GetUint32() + if err != nil { + return err + } + if e.CanSet() { + e.SetUint(uint64(newInt)) + } + case reflect.Uint64: + newInt, err := f.GetInt() + if err != nil { + return err + } + if e.CanSet() { + e.SetUint(uint64(newInt)) + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + newInt, err := f.GetInt() + if err != nil { + return err + } + if e.CanSet() { + e.SetInt(int64(newInt)) + } + case reflect.Float32: + newFloat, err := f.GetFloat32() + if err != nil { + return err + } + if e.CanSet() { + e.SetFloat(float64(newFloat)) + } + case reflect.Float64: + newFloat, err := f.GetFloat64() + if err != nil { + return err + } + if e.CanSet() { + e.SetFloat(float64(newFloat)) + } + case reflect.Map: + if e.CanSet() { + e.Set(reflect.MakeMap(e.Type())) + const maxElements = 50 + randQty, err := f.GetInt() + if err != nil { + return err + } + numOfElements := randQty % maxElements + for i := 0; i < numOfElements; i++ { + key := reflect.New(e.Type().Key()).Elem() + if err := f.fuzzStruct(key, customFunctions); err != nil { + return err + } + val := reflect.New(e.Type().Elem()).Elem() + if err = f.fuzzStruct(val, customFunctions); err != nil { + return err + } + e.SetMapIndex(key, val) + } + } + case reflect.Ptr: + if e.CanSet() { + e.Set(reflect.New(e.Type().Elem())) + if err := f.fuzzStruct(e.Elem(), customFunctions); err != nil { + return err + } + return nil + } + case reflect.Uint8: + b, err := f.GetByte() + if err != nil { + return err + } + if e.CanSet() { + e.SetUint(uint64(b)) + } + } + return nil +} + +func (f *ConsumeFuzzer) GetStringArray() (reflect.Value, error) { + // The max size of the array: + const max uint32 = 20 + + arraySize := f.position + if arraySize > max { + arraySize = max + } + stringArray := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf("string")), int(arraySize), int(arraySize)) + if f.position+arraySize >= f.dataTotal { + return stringArray, errors.New("could not make string array") + } + + for i := 0; i < int(arraySize); i++ { + stringSize := uint32(f.data[f.position]) + if f.position+stringSize >= f.dataTotal { + return stringArray, nil + } + stringToAppend := string(f.data[f.position : f.position+stringSize]) + strVal := reflect.ValueOf(stringToAppend) + stringArray = reflect.Append(stringArray, strVal) + f.position += stringSize + } + return stringArray, nil +} + +func (f *ConsumeFuzzer) GetInt() (int, error) { + if f.position >= f.dataTotal { + return 0, errors.New("not enough bytes to create int") + } + returnInt := int(f.data[f.position]) + f.position++ + return returnInt, nil +} + +func (f *ConsumeFuzzer) GetByte() (byte, error) { + if f.position >= f.dataTotal { + return 0x00, errors.New("not enough bytes to get byte") + } + returnByte := f.data[f.position] + f.position++ + return returnByte, nil +} + +func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) { + if f.position >= f.dataTotal { + return nil, errors.New("not enough bytes to get byte") + } + returnBytes := make([]byte, 0, numberOfBytes) + for i := 0; i < numberOfBytes; i++ { + newByte, err := f.GetByte() + if err != nil { + return nil, err + } + returnBytes = append(returnBytes, newByte) + } + return returnBytes, nil +} + +func (f *ConsumeFuzzer) GetUint16() (uint16, error) { + u16, err := f.GetNBytes(2) + if err != nil { + return 0, err + } + littleEndian, err := f.GetBool() + if err != nil { + return 0, err + } + if littleEndian { + return binary.LittleEndian.Uint16(u16), nil + } + return binary.BigEndian.Uint16(u16), nil +} + +func (f *ConsumeFuzzer) GetUint32() (uint32, error) { + u32, err := f.GetNBytes(4) + if err != nil { + return 0, err + } + return binary.BigEndian.Uint32(u32), nil +} + +func (f *ConsumeFuzzer) GetUint64() (uint64, error) { + u64, err := f.GetNBytes(8) + if err != nil { + return 0, err + } + littleEndian, err := f.GetBool() + if err != nil { + return 0, err + } + if littleEndian { + return binary.LittleEndian.Uint64(u64), nil + } + return binary.BigEndian.Uint64(u64), nil +} + +func (f *ConsumeFuzzer) GetBytes() ([]byte, error) { + var length uint32 + var err error + length, err = f.GetUint32() + if err != nil { + return nil, errors.New("not enough bytes to create byte array") + } + + if length == 0 { + length = 30 + } + bytesLeft := f.dataTotal - f.position + if bytesLeft <= 0 { + return nil, errors.New("not enough bytes to create byte array") + } + + // If the length is the same as bytes left, we will not overflow + // the remaining bytes. + if length != bytesLeft { + length = length % bytesLeft + } + byteBegin := f.position + if byteBegin+length < byteBegin { + return nil, errors.New("numbers overflow") + } + f.position = byteBegin + length + return f.data[byteBegin:f.position], nil +} + +func (f *ConsumeFuzzer) GetString() (string, error) { + if f.position >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") + } + length, err := f.GetUint32() + if err != nil { + return "nil", errors.New("not enough bytes to create string") + } + if f.position > MaxTotalLen { + return "nil", errors.New("created too large a string") + } + byteBegin := f.position + if byteBegin >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") + } + if byteBegin+length > f.dataTotal { + return "nil", errors.New("not enough bytes to create string") + } + if byteBegin > byteBegin+length { + return "nil", errors.New("numbers overflow") + } + f.position = byteBegin + length + return string(f.data[byteBegin:f.position]), nil +} + +func (f *ConsumeFuzzer) GetBool() (bool, error) { + if f.position >= f.dataTotal { + return false, errors.New("not enough bytes to create bool") + } + if IsDivisibleBy(int(f.data[f.position]), 2) { + f.position++ + return true, nil + } else { + f.position++ + return false, nil + } +} + +func (f *ConsumeFuzzer) FuzzMap(m interface{}) error { + return f.GenerateStruct(m) +} + +func returnTarBytes(buf []byte) ([]byte, error) { + return buf, nil + // Count files + var fileCounter int + tr := tar.NewReader(bytes.NewReader(buf)) + for { + _, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + fileCounter++ + } + if fileCounter >= 1 { + return buf, nil + } + return nil, fmt.Errorf("not enough files were created\n") +} + +func setTarHeaderFormat(hdr *tar.Header, f *ConsumeFuzzer) error { + ind, err := f.GetInt() + if err != nil { + hdr.Format = tar.FormatGNU + //return nil + } + switch ind % 4 { + case 0: + hdr.Format = tar.FormatUnknown + case 1: + hdr.Format = tar.FormatUSTAR + case 2: + hdr.Format = tar.FormatPAX + case 3: + hdr.Format = tar.FormatGNU + } + return nil +} + +func setTarHeaderTypeflag(hdr *tar.Header, f *ConsumeFuzzer) error { + ind, err := f.GetInt() + if err != nil { + return err + } + switch ind % 13 { + case 0: + hdr.Typeflag = tar.TypeReg + case 1: + hdr.Typeflag = tar.TypeLink + linkname, err := f.GetString() + if err != nil { + return err + } + hdr.Linkname = linkname + case 2: + hdr.Typeflag = tar.TypeSymlink + linkname, err := f.GetString() + if err != nil { + return err + } + hdr.Linkname = linkname + case 3: + hdr.Typeflag = tar.TypeChar + case 4: + hdr.Typeflag = tar.TypeBlock + case 5: + hdr.Typeflag = tar.TypeDir + case 6: + hdr.Typeflag = tar.TypeFifo + case 7: + hdr.Typeflag = tar.TypeCont + case 8: + hdr.Typeflag = tar.TypeXHeader + case 9: + hdr.Typeflag = tar.TypeXGlobalHeader + case 10: + hdr.Typeflag = tar.TypeGNUSparse + case 11: + hdr.Typeflag = tar.TypeGNULongName + case 12: + hdr.Typeflag = tar.TypeGNULongLink + } + return nil +} + +func (f *ConsumeFuzzer) createTarFileBody() ([]byte, error) { + return f.GetBytes() + /*length, err := f.GetUint32() + if err != nil { + return nil, errors.New("not enough bytes to create byte array") + } + + // A bit of optimization to attempt to create a file body + // when we don't have as many bytes left as "length" + remainingBytes := f.dataTotal - f.position + if remainingBytes <= 0 { + return nil, errors.New("created too large a string") + } + if f.position+length > MaxTotalLen { + return nil, errors.New("created too large a string") + } + byteBegin := f.position + if byteBegin >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") + } + if length == 0 { + return nil, errors.New("zero-length is not supported") + } + if byteBegin+length >= f.dataTotal { + return nil, errors.New("not enough bytes to create byte array") + } + if byteBegin+length < byteBegin { + return nil, errors.New("numbers overflow") + } + f.position = byteBegin + length + return f.data[byteBegin:f.position], nil*/ +} + +// getTarFileName is similar to GetString(), but creates string based +// on the length of f.data to reduce the likelihood of overflowing +// f.data. +func (f *ConsumeFuzzer) getTarFilename() (string, error) { + return f.GetString() + /*length, err := f.GetUint32() + if err != nil { + return "nil", errors.New("not enough bytes to create string") + } + + // A bit of optimization to attempt to create a file name + // when we don't have as many bytes left as "length" + remainingBytes := f.dataTotal - f.position + if remainingBytes <= 0 { + return "nil", errors.New("created too large a string") + } + if f.position > MaxTotalLen { + return "nil", errors.New("created too large a string") + } + byteBegin := f.position + if byteBegin >= f.dataTotal { + return "nil", errors.New("not enough bytes to create string") + } + if byteBegin+length > f.dataTotal { + return "nil", errors.New("not enough bytes to create string") + } + if byteBegin > byteBegin+length { + return "nil", errors.New("numbers overflow") + } + f.position = byteBegin + length + return string(f.data[byteBegin:f.position]), nil*/ +} + +type TarFile struct { + Hdr *tar.Header + Body []byte +} + +// TarBytes returns valid bytes for a tar archive +func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { + numberOfFiles, err := f.GetInt() + if err != nil { + return nil, err + } + var tarFiles []*TarFile + tarFiles = make([]*TarFile, 0) + + const maxNoOfFiles = 100 + for i := 0; i < numberOfFiles%maxNoOfFiles; i++ { + var filename string + var filebody []byte + var sec, nsec int + var err error + + filename, err = f.getTarFilename() + if err != nil { + var sb strings.Builder + sb.WriteString("file-") + sb.WriteString(strconv.Itoa(i)) + filename = sb.String() + } + filebody, err = f.createTarFileBody() + if err != nil { + var sb strings.Builder + sb.WriteString("filebody-") + sb.WriteString(strconv.Itoa(i)) + filebody = []byte(sb.String()) + } + + sec, err = f.GetInt() + if err != nil { + sec = 1672531200 // beginning of 2023 + } + nsec, err = f.GetInt() + if err != nil { + nsec = 1703980800 // end of 2023 + } + + hdr := &tar.Header{ + Name: filename, + Size: int64(len(filebody)), + Mode: 0o600, + ModTime: time.Unix(int64(sec), int64(nsec)), + } + if err := setTarHeaderTypeflag(hdr, f); err != nil { + return []byte(""), err + } + if err := setTarHeaderFormat(hdr, f); err != nil { + return []byte(""), err + } + tf := &TarFile{ + Hdr: hdr, + Body: filebody, + } + tarFiles = append(tarFiles, tf) + } + + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + defer tw.Close() + + for _, tf := range tarFiles { + tw.WriteHeader(tf.Hdr) + tw.Write(tf.Body) + } + return buf.Bytes(), nil +} + +// This is similar to TarBytes, but it returns a series of +// files instead of raw tar bytes. The advantage of this +// api is that it is cheaper in terms of cpu power to +// modify or check the files in the fuzzer with TarFiles() +// because it avoids creating a tar reader. +func (f *ConsumeFuzzer) TarFiles() ([]*TarFile, error) { + numberOfFiles, err := f.GetInt() + if err != nil { + return nil, err + } + var tarFiles []*TarFile + tarFiles = make([]*TarFile, 0) + + const maxNoOfFiles = 100 + for i := 0; i < numberOfFiles%maxNoOfFiles; i++ { + filename, err := f.getTarFilename() + if err != nil { + return tarFiles, err + } + filebody, err := f.createTarFileBody() + if err != nil { + return tarFiles, err + } + + sec, err := f.GetInt() + if err != nil { + return tarFiles, err + } + nsec, err := f.GetInt() + if err != nil { + return tarFiles, err + } + + hdr := &tar.Header{ + Name: filename, + Size: int64(len(filebody)), + Mode: 0o600, + ModTime: time.Unix(int64(sec), int64(nsec)), + } + if err := setTarHeaderTypeflag(hdr, f); err != nil { + hdr.Typeflag = tar.TypeReg + } + if err := setTarHeaderFormat(hdr, f); err != nil { + return tarFiles, err // should not happend + } + tf := &TarFile{ + Hdr: hdr, + Body: filebody, + } + tarFiles = append(tarFiles, tf) + } + return tarFiles, nil +} + +// CreateFiles creates pseudo-random files in rootDir. +// It creates subdirs and places the files there. +// It is the callers responsibility to ensure that +// rootDir exists. +func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { + numberOfFiles, err := f.GetInt() + if err != nil { + return err + } + maxNumberOfFiles := numberOfFiles % 4000 // This is completely arbitrary + if maxNumberOfFiles == 0 { + return errors.New("maxNumberOfFiles is nil") + } + + var noOfCreatedFiles int + for i := 0; i < maxNumberOfFiles; i++ { + // The file to create: + fileName, err := f.GetString() + if err != nil { + if noOfCreatedFiles > 0 { + // If files have been created, we don't return an error. + break + } else { + return errors.New("could not get fileName") + } + } + if strings.Contains(fileName, "..") || (len(fileName) > 0 && fileName[0] == 47) || strings.Contains(fileName, "\\") { + continue + } + fullFilePath := filepath.Join(rootDir, fileName) + + // Find the subdirectory of the file + if subDir := filepath.Dir(fileName); subDir != "" && subDir != "." { + // create the dir first; avoid going outside the root dir + if strings.Contains(subDir, "../") || (len(subDir) > 0 && subDir[0] == 47) || strings.Contains(subDir, "\\") { + continue + } + dirPath := filepath.Join(rootDir, subDir) + if _, err := os.Stat(dirPath); os.IsNotExist(err) { + err2 := os.MkdirAll(dirPath, 0o777) + if err2 != nil { + continue + } + } + fullFilePath = filepath.Join(dirPath, fileName) + } else { + // Create symlink + createSymlink, err := f.GetBool() + if err != nil { + if noOfCreatedFiles > 0 { + break + } else { + return errors.New("could not create the symlink") + } + } + if createSymlink { + symlinkTarget, err := f.GetString() + if err != nil { + return err + } + err = os.Symlink(symlinkTarget, fullFilePath) + if err != nil { + return err + } + // stop loop here, since a symlink needs no further action + noOfCreatedFiles++ + continue + } + // We create a normal file + fileContents, err := f.GetBytes() + if err != nil { + if noOfCreatedFiles > 0 { + break + } else { + return errors.New("could not create the file") + } + } + err = os.WriteFile(fullFilePath, fileContents, 0o666) + if err != nil { + continue + } + noOfCreatedFiles++ + } + } + return nil +} + +// GetStringFrom returns a string that can only consist of characters +// included in possibleChars. It returns an error if the created string +// does not have the specified length. +func (f *ConsumeFuzzer) GetStringFrom(possibleChars string, length int) (string, error) { + if (f.dataTotal - f.position) < uint32(length) { + return "", errors.New("not enough bytes to create a string") + } + output := make([]byte, 0, length) + for i := 0; i < length; i++ { + charIndex, err := f.GetInt() + if err != nil { + return string(output), err + } + output = append(output, possibleChars[charIndex%len(possibleChars)]) + } + return string(output), nil +} + +func (f *ConsumeFuzzer) GetRune() ([]rune, error) { + stringToConvert, err := f.GetString() + if err != nil { + return []rune("nil"), err + } + return []rune(stringToConvert), nil +} + +func (f *ConsumeFuzzer) GetFloat32() (float32, error) { + u32, err := f.GetNBytes(4) + if err != nil { + return 0, err + } + littleEndian, err := f.GetBool() + if err != nil { + return 0, err + } + if littleEndian { + u32LE := binary.LittleEndian.Uint32(u32) + return math.Float32frombits(u32LE), nil + } + u32BE := binary.BigEndian.Uint32(u32) + return math.Float32frombits(u32BE), nil +} + +func (f *ConsumeFuzzer) GetFloat64() (float64, error) { + u64, err := f.GetNBytes(8) + if err != nil { + return 0, err + } + littleEndian, err := f.GetBool() + if err != nil { + return 0, err + } + if littleEndian { + u64LE := binary.LittleEndian.Uint64(u64) + return math.Float64frombits(u64LE), nil + } + u64BE := binary.BigEndian.Uint64(u64) + return math.Float64frombits(u64BE), nil +} + +func (f *ConsumeFuzzer) CreateSlice(targetSlice interface{}) error { + return f.GenerateStruct(targetSlice) +} diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go b/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go new file mode 100644 index 00000000000..8ca3a61b878 --- /dev/null +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/funcs.go @@ -0,0 +1,62 @@ +// Copyright 2023 The go-fuzz-headers Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gofuzzheaders + +import ( + "fmt" + "reflect" +) + +type Continue struct { + F *ConsumeFuzzer +} + +func (f *ConsumeFuzzer) AddFuncs(fuzzFuncs []interface{}) { + for i := range fuzzFuncs { + v := reflect.ValueOf(fuzzFuncs[i]) + if v.Kind() != reflect.Func { + panic("Need only funcs!") + } + t := v.Type() + if t.NumIn() != 2 || t.NumOut() != 1 { + fmt.Println(t.NumIn(), t.NumOut()) + + panic("Need 2 in and 1 out params. In must be the type. Out must be an error") + } + argT := t.In(0) + switch argT.Kind() { + case reflect.Ptr, reflect.Map: + default: + panic("fuzzFunc must take pointer or map type") + } + if t.In(1) != reflect.TypeOf(Continue{}) { + panic("fuzzFunc's second parameter must be type Continue") + } + f.Funcs[argT] = v + } +} + +func (f *ConsumeFuzzer) GenerateWithCustom(targetStruct interface{}) error { + e := reflect.ValueOf(targetStruct).Elem() + return f.fuzzStruct(e, true) +} + +func (c Continue) GenerateStruct(targetStruct interface{}) error { + return c.F.GenerateStruct(targetStruct) +} + +func (c Continue) GenerateStructWithCustom(targetStruct interface{}) error { + return c.F.GenerateWithCustom(targetStruct) +} diff --git a/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go b/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go new file mode 100644 index 00000000000..2afd49f8481 --- /dev/null +++ b/vendor/github.com/AdaLogics/go-fuzz-headers/sql.go @@ -0,0 +1,556 @@ +// Copyright 2023 The go-fuzz-headers Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gofuzzheaders + +import ( + "fmt" + "strings" +) + +// returns a keyword by index +func getKeyword(f *ConsumeFuzzer) (string, error) { + index, err := f.GetInt() + if err != nil { + return keywords[0], err + } + for i, k := range keywords { + if i == index { + return k, nil + } + } + return keywords[0], fmt.Errorf("could not get a kw") +} + +// Simple utility function to check if a string +// slice contains a string. +func containsString(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} + +// These keywords are used specifically for fuzzing Vitess +var keywords = []string{ + "accessible", "action", "add", "after", "against", "algorithm", + "all", "alter", "always", "analyze", "and", "as", "asc", "asensitive", + "auto_increment", "avg_row_length", "before", "begin", "between", + "bigint", "binary", "_binary", "_utf8mb4", "_utf8", "_latin1", "bit", + "blob", "bool", "boolean", "both", "by", "call", "cancel", "cascade", + "cascaded", "case", "cast", "channel", "change", "char", "character", + "charset", "check", "checksum", "coalesce", "code", "collate", "collation", + "column", "columns", "comment", "committed", "commit", "compact", "complete", + "compressed", "compression", "condition", "connection", "constraint", "continue", + "convert", "copy", "cume_dist", "substr", "substring", "create", "cross", + "csv", "current_date", "current_time", "current_timestamp", "current_user", + "cursor", "data", "database", "databases", "day", "day_hour", "day_microsecond", + "day_minute", "day_second", "date", "datetime", "dec", "decimal", "declare", + "default", "definer", "delay_key_write", "delayed", "delete", "dense_rank", + "desc", "describe", "deterministic", "directory", "disable", "discard", + "disk", "distinct", "distinctrow", "div", "double", "do", "drop", "dumpfile", + "duplicate", "dynamic", "each", "else", "elseif", "empty", "enable", + "enclosed", "encryption", "end", "enforced", "engine", "engines", "enum", + "error", "escape", "escaped", "event", "exchange", "exclusive", "exists", + "exit", "explain", "expansion", "export", "extended", "extract", "false", + "fetch", "fields", "first", "first_value", "fixed", "float", "float4", + "float8", "flush", "for", "force", "foreign", "format", "from", "full", + "fulltext", "function", "general", "generated", "geometry", "geometrycollection", + "get", "global", "gtid_executed", "grant", "group", "grouping", "groups", + "group_concat", "having", "header", "high_priority", "hosts", "hour", "hour_microsecond", + "hour_minute", "hour_second", "if", "ignore", "import", "in", "index", "indexes", + "infile", "inout", "inner", "inplace", "insensitive", "insert", "insert_method", + "int", "int1", "int2", "int3", "int4", "int8", "integer", "interval", + "into", "io_after_gtids", "is", "isolation", "iterate", "invoker", "join", + "json", "json_table", "key", "keys", "keyspaces", "key_block_size", "kill", "lag", + "language", "last", "last_value", "last_insert_id", "lateral", "lead", "leading", + "leave", "left", "less", "level", "like", "limit", "linear", "lines", + "linestring", "load", "local", "localtime", "localtimestamp", "lock", "logs", + "long", "longblob", "longtext", "loop", "low_priority", "manifest", + "master_bind", "match", "max_rows", "maxvalue", "mediumblob", "mediumint", + "mediumtext", "memory", "merge", "microsecond", "middleint", "min_rows", "minute", + "minute_microsecond", "minute_second", "mod", "mode", "modify", "modifies", + "multilinestring", "multipoint", "multipolygon", "month", "name", + "names", "natural", "nchar", "next", "no", "none", "not", "no_write_to_binlog", + "nth_value", "ntile", "null", "numeric", "of", "off", "offset", "on", + "only", "open", "optimize", "optimizer_costs", "option", "optionally", + "or", "order", "out", "outer", "outfile", "over", "overwrite", "pack_keys", + "parser", "partition", "partitioning", "password", "percent_rank", "plugins", + "point", "polygon", "precision", "primary", "privileges", "processlist", + "procedure", "query", "quarter", "range", "rank", "read", "reads", "read_write", + "real", "rebuild", "recursive", "redundant", "references", "regexp", "relay", + "release", "remove", "rename", "reorganize", "repair", "repeat", "repeatable", + "replace", "require", "resignal", "restrict", "return", "retry", "revert", + "revoke", "right", "rlike", "rollback", "row", "row_format", "row_number", + "rows", "s3", "savepoint", "schema", "schemas", "second", "second_microsecond", + "security", "select", "sensitive", "separator", "sequence", "serializable", + "session", "set", "share", "shared", "show", "signal", "signed", "slow", + "smallint", "spatial", "specific", "sql", "sqlexception", "sqlstate", + "sqlwarning", "sql_big_result", "sql_cache", "sql_calc_found_rows", + "sql_no_cache", "sql_small_result", "ssl", "start", "starting", + "stats_auto_recalc", "stats_persistent", "stats_sample_pages", "status", + "storage", "stored", "straight_join", "stream", "system", "vstream", + "table", "tables", "tablespace", "temporary", "temptable", "terminated", + "text", "than", "then", "time", "timestamp", "timestampadd", "timestampdiff", + "tinyblob", "tinyint", "tinytext", "to", "trailing", "transaction", "tree", + "traditional", "trigger", "triggers", "true", "truncate", "uncommitted", + "undefined", "undo", "union", "unique", "unlock", "unsigned", "update", + "upgrade", "usage", "use", "user", "user_resources", "using", "utc_date", + "utc_time", "utc_timestamp", "validation", "values", "variables", "varbinary", + "varchar", "varcharacter", "varying", "vgtid_executed", "virtual", "vindex", + "vindexes", "view", "vitess", "vitess_keyspaces", "vitess_metadata", + "vitess_migration", "vitess_migrations", "vitess_replication_status", + "vitess_shards", "vitess_tablets", "vschema", "warnings", "when", + "where", "while", "window", "with", "without", "work", "write", "xor", + "year", "year_month", "zerofill", +} + +// Keywords that could get an additional keyword +var needCustomString = []string{ + "DISTINCTROW", "FROM", // Select keywords: + "GROUP BY", "HAVING", "WINDOW", + "FOR", + "ORDER BY", "LIMIT", + "INTO", "PARTITION", "AS", // Insert Keywords: + "ON DUPLICATE KEY UPDATE", + "WHERE", "LIMIT", // Delete keywords + "INFILE", "INTO TABLE", "CHARACTER SET", // Load keywords + "TERMINATED BY", "ENCLOSED BY", + "ESCAPED BY", "STARTING BY", + "TERMINATED BY", "STARTING BY", + "IGNORE", + "VALUE", "VALUES", // Replace tokens + "SET", // Update tokens + "ENGINE =", // Drop tokens + "DEFINER =", "ON SCHEDULE", "RENAME TO", // Alter tokens + "COMMENT", "DO", "INITIAL_SIZE = ", "OPTIONS", +} + +var alterTableTokens = [][]string{ + {"CUSTOM_FUZZ_STRING"}, + {"CUSTOM_ALTTER_TABLE_OPTIONS"}, + {"PARTITION_OPTIONS_FOR_ALTER_TABLE"}, +} + +var alterTokens = [][]string{ + { + "DATABASE", "SCHEMA", "DEFINER = ", "EVENT", "FUNCTION", "INSTANCE", + "LOGFILE GROUP", "PROCEDURE", "SERVER", + }, + {"CUSTOM_FUZZ_STRING"}, + { + "ON SCHEDULE", "ON COMPLETION PRESERVE", "ON COMPLETION NOT PRESERVE", + "ADD UNDOFILE", "OPTIONS", + }, + {"RENAME TO", "INITIAL_SIZE = "}, + {"ENABLE", "DISABLE", "DISABLE ON SLAVE", "ENGINE"}, + {"COMMENT"}, + {"DO"}, +} + +var setTokens = [][]string{ + {"CHARACTER SET", "CHARSET", "CUSTOM_FUZZ_STRING", "NAMES"}, + {"CUSTOM_FUZZ_STRING", "DEFAULT", "="}, + {"CUSTOM_FUZZ_STRING"}, +} + +var dropTokens = [][]string{ + {"TEMPORARY", "UNDO"}, + { + "DATABASE", "SCHEMA", "EVENT", "INDEX", "LOGFILE GROUP", + "PROCEDURE", "FUNCTION", "SERVER", "SPATIAL REFERENCE SYSTEM", + "TABLE", "TABLESPACE", "TRIGGER", "VIEW", + }, + {"IF EXISTS"}, + {"CUSTOM_FUZZ_STRING"}, + {"ON", "ENGINE = ", "RESTRICT", "CASCADE"}, +} + +var renameTokens = [][]string{ + {"TABLE"}, + {"CUSTOM_FUZZ_STRING"}, + {"TO"}, + {"CUSTOM_FUZZ_STRING"}, +} + +var truncateTokens = [][]string{ + {"TABLE"}, + {"CUSTOM_FUZZ_STRING"}, +} + +var createTokens = [][]string{ + {"OR REPLACE", "TEMPORARY", "UNDO"}, // For create spatial reference system + { + "UNIQUE", "FULLTEXT", "SPATIAL", "ALGORITHM = UNDEFINED", "ALGORITHM = MERGE", + "ALGORITHM = TEMPTABLE", + }, + { + "DATABASE", "SCHEMA", "EVENT", "FUNCTION", "INDEX", "LOGFILE GROUP", + "PROCEDURE", "SERVER", "SPATIAL REFERENCE SYSTEM", "TABLE", "TABLESPACE", + "TRIGGER", "VIEW", + }, + {"IF NOT EXISTS"}, + {"CUSTOM_FUZZ_STRING"}, +} + +/* +// For future use. +var updateTokens = [][]string{ + {"LOW_PRIORITY"}, + {"IGNORE"}, + {"SET"}, + {"WHERE"}, + {"ORDER BY"}, + {"LIMIT"}, +} +*/ + +var replaceTokens = [][]string{ + {"LOW_PRIORITY", "DELAYED"}, + {"INTO"}, + {"PARTITION"}, + {"CUSTOM_FUZZ_STRING"}, + {"VALUES", "VALUE"}, +} + +var loadTokens = [][]string{ + {"DATA"}, + {"LOW_PRIORITY", "CONCURRENT", "LOCAL"}, + {"INFILE"}, + {"REPLACE", "IGNORE"}, + {"INTO TABLE"}, + {"PARTITION"}, + {"CHARACTER SET"}, + {"FIELDS", "COLUMNS"}, + {"TERMINATED BY"}, + {"OPTIONALLY"}, + {"ENCLOSED BY"}, + {"ESCAPED BY"}, + {"LINES"}, + {"STARTING BY"}, + {"TERMINATED BY"}, + {"IGNORE"}, + {"LINES", "ROWS"}, + {"CUSTOM_FUZZ_STRING"}, +} + +// These Are everything that comes after "INSERT" +var insertTokens = [][]string{ + {"LOW_PRIORITY", "DELAYED", "HIGH_PRIORITY", "IGNORE"}, + {"INTO"}, + {"PARTITION"}, + {"CUSTOM_FUZZ_STRING"}, + {"AS"}, + {"ON DUPLICATE KEY UPDATE"}, +} + +// These are everything that comes after "SELECT" +var selectTokens = [][]string{ + {"*", "CUSTOM_FUZZ_STRING", "DISTINCTROW"}, + {"HIGH_PRIORITY"}, + {"STRAIGHT_JOIN"}, + {"SQL_SMALL_RESULT", "SQL_BIG_RESULT", "SQL_BUFFER_RESULT"}, + {"SQL_NO_CACHE", "SQL_CALC_FOUND_ROWS"}, + {"CUSTOM_FUZZ_STRING"}, + {"FROM"}, + {"WHERE"}, + {"GROUP BY"}, + {"HAVING"}, + {"WINDOW"}, + {"ORDER BY"}, + {"LIMIT"}, + {"CUSTOM_FUZZ_STRING"}, + {"FOR"}, +} + +// These are everything that comes after "DELETE" +var deleteTokens = [][]string{ + {"LOW_PRIORITY", "QUICK", "IGNORE", "FROM", "AS"}, + {"PARTITION"}, + {"WHERE"}, + {"ORDER BY"}, + {"LIMIT"}, +} + +var alter_table_options = []string{ + "ADD", "COLUMN", "FIRST", "AFTER", "INDEX", "KEY", "FULLTEXT", "SPATIAL", + "CONSTRAINT", "UNIQUE", "FOREIGN KEY", "CHECK", "ENFORCED", "DROP", "ALTER", + "NOT", "INPLACE", "COPY", "SET", "VISIBLE", "INVISIBLE", "DEFAULT", "CHANGE", + "CHARACTER SET", "COLLATE", "DISABLE", "ENABLE", "KEYS", "TABLESPACE", "LOCK", + "FORCE", "MODIFY", "SHARED", "EXCLUSIVE", "NONE", "ORDER BY", "RENAME COLUMN", + "AS", "=", "ASC", "DESC", "WITH", "WITHOUT", "VALIDATION", "ADD PARTITION", + "DROP PARTITION", "DISCARD PARTITION", "IMPORT PARTITION", "TRUNCATE PARTITION", + "COALESCE PARTITION", "REORGANIZE PARTITION", "EXCHANGE PARTITION", + "ANALYZE PARTITION", "CHECK PARTITION", "OPTIMIZE PARTITION", "REBUILD PARTITION", + "REPAIR PARTITION", "REMOVE PARTITIONING", "USING", "BTREE", "HASH", "COMMENT", + "KEY_BLOCK_SIZE", "WITH PARSER", "AUTOEXTEND_SIZE", "AUTO_INCREMENT", "AVG_ROW_LENGTH", + "CHECKSUM", "INSERT_METHOD", "ROW_FORMAT", "DYNAMIC", "FIXED", "COMPRESSED", "REDUNDANT", + "COMPACT", "SECONDARY_ENGINE_ATTRIBUTE", "STATS_AUTO_RECALC", "STATS_PERSISTENT", + "STATS_SAMPLE_PAGES", "ZLIB", "LZ4", "ENGINE_ATTRIBUTE", "KEY_BLOCK_SIZE", "MAX_ROWS", + "MIN_ROWS", "PACK_KEYS", "PASSWORD", "COMPRESSION", "CONNECTION", "DIRECTORY", + "DELAY_KEY_WRITE", "ENCRYPTION", "STORAGE", "DISK", "MEMORY", "UNION", +} + +// Creates an 'alter table' statement. 'alter table' is an exception +// in that it has its own function. The majority of statements +// are created by 'createStmt()'. +func createAlterTableStmt(f *ConsumeFuzzer) (string, error) { + maxArgs, err := f.GetInt() + if err != nil { + return "", err + } + maxArgs = maxArgs % 30 + if maxArgs == 0 { + return "", fmt.Errorf("could not create alter table stmt") + } + + var stmt strings.Builder + stmt.WriteString("ALTER TABLE ") + for i := 0; i < maxArgs; i++ { + // Calculate if we get existing token or custom string + tokenType, err := f.GetInt() + if err != nil { + return "", err + } + if tokenType%4 == 1 { + customString, err := f.GetString() + if err != nil { + return "", err + } + stmt.WriteString(" " + customString) + } else { + tokenIndex, err := f.GetInt() + if err != nil { + return "", err + } + stmt.WriteString(" " + alter_table_options[tokenIndex%len(alter_table_options)]) + } + } + return stmt.String(), nil +} + +func chooseToken(tokens []string, f *ConsumeFuzzer) (string, error) { + index, err := f.GetInt() + if err != nil { + return "", err + } + var token strings.Builder + token.WriteString(tokens[index%len(tokens)]) + if token.String() == "CUSTOM_FUZZ_STRING" { + customFuzzString, err := f.GetString() + if err != nil { + return "", err + } + return customFuzzString, nil + } + + // Check if token requires an argument + if containsString(needCustomString, token.String()) { + customFuzzString, err := f.GetString() + if err != nil { + return "", err + } + token.WriteString(" " + customFuzzString) + } + return token.String(), nil +} + +var stmtTypes = map[string][][]string{ + "DELETE": deleteTokens, + "INSERT": insertTokens, + "SELECT": selectTokens, + "LOAD": loadTokens, + "REPLACE": replaceTokens, + "CREATE": createTokens, + "DROP": dropTokens, + "RENAME": renameTokens, + "TRUNCATE": truncateTokens, + "SET": setTokens, + "ALTER": alterTokens, + "ALTER TABLE": alterTableTokens, // ALTER TABLE has its own set of tokens +} + +var stmtTypeEnum = map[int]string{ + 0: "DELETE", + 1: "INSERT", + 2: "SELECT", + 3: "LOAD", + 4: "REPLACE", + 5: "CREATE", + 6: "DROP", + 7: "RENAME", + 8: "TRUNCATE", + 9: "SET", + 10: "ALTER", + 11: "ALTER TABLE", +} + +func createStmt(f *ConsumeFuzzer) (string, error) { + stmtIndex, err := f.GetInt() + if err != nil { + return "", err + } + stmtIndex = stmtIndex % len(stmtTypes) + + queryType := stmtTypeEnum[stmtIndex] + tokens := stmtTypes[queryType] + + // We have custom creator for ALTER TABLE + if queryType == "ALTER TABLE" { + query, err := createAlterTableStmt(f) + if err != nil { + return "", err + } + return query, nil + } + + // Here we are creating a query that is not + // an 'alter table' query. For available + // queries, see "stmtTypes" + + // First specify the first query keyword: + var query strings.Builder + query.WriteString(queryType) + + // Next create the args for the + queryArgs, err := createStmtArgs(tokens, f) + if err != nil { + return "", err + } + query.WriteString(" " + queryArgs) + return query.String(), nil +} + +// Creates the arguments of a statements. In a select statement +// that would be everything after "select". +func createStmtArgs(tokenslice [][]string, f *ConsumeFuzzer) (string, error) { + var query, token strings.Builder + + // We go through the tokens in the tokenslice, + // create the respective token and add it to + // "query" + for _, tokens := range tokenslice { + // For extra randomization, the fuzzer can + // choose to not include this token. + includeThisToken, err := f.GetBool() + if err != nil { + return "", err + } + if !includeThisToken { + continue + } + + // There may be several tokens to choose from: + if len(tokens) > 1 { + chosenToken, err := chooseToken(tokens, f) + if err != nil { + return "", err + } + query.WriteString(" " + chosenToken) + } else { + token.WriteString(tokens[0]) + + // In case the token is "CUSTOM_FUZZ_STRING" + // we will then create a non-structured string + if token.String() == "CUSTOM_FUZZ_STRING" { + customFuzzString, err := f.GetString() + if err != nil { + return "", err + } + query.WriteString(" " + customFuzzString) + continue + } + + // Check if token requires an argument. + // Tokens that take an argument can be found + // in 'needCustomString'. If so, we add a + // non-structured string to the token. + if containsString(needCustomString, token.String()) { + customFuzzString, err := f.GetString() + if err != nil { + return "", err + } + token.WriteString(fmt.Sprintf(" %s", customFuzzString)) + } + query.WriteString(fmt.Sprintf(" %s", token.String())) + } + } + return query.String(), nil +} + +// Creates a semi-structured query. It creates a string +// that is a combination of the keywords and random strings. +func createQuery(f *ConsumeFuzzer) (string, error) { + queryLen, err := f.GetInt() + if err != nil { + return "", err + } + maxLen := queryLen % 60 + if maxLen == 0 { + return "", fmt.Errorf("could not create a query") + } + var query strings.Builder + for i := 0; i < maxLen; i++ { + // Get a new token: + useKeyword, err := f.GetBool() + if err != nil { + return "", err + } + if useKeyword { + keyword, err := getKeyword(f) + if err != nil { + return "", err + } + query.WriteString(" " + keyword) + } else { + customString, err := f.GetString() + if err != nil { + return "", err + } + query.WriteString(" " + customString) + } + } + if query.String() == "" { + return "", fmt.Errorf("could not create a query") + } + return query.String(), nil +} + +// GetSQLString is the API that users interact with. +// +// Usage: +// +// f := NewConsumer(data) +// sqlString, err := f.GetSQLString() +func (f *ConsumeFuzzer) GetSQLString() (string, error) { + var query string + veryStructured, err := f.GetBool() + if err != nil { + return "", err + } + if veryStructured { + query, err = createStmt(f) + if err != nil { + return "", err + } + } else { + query, err = createQuery(f) + if err != nil { + return "", err + } + } + return query, nil +} diff --git a/vendor/github.com/Microsoft/hcsshim/LICENSE b/vendor/github.com/Microsoft/hcsshim/LICENSE new file mode 100644 index 00000000000..49d21669aee --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go b/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go new file mode 100644 index 00000000000..6c435d2b649 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go @@ -0,0 +1,59 @@ +package osversion + +import ( + "fmt" + "sync" + + "golang.org/x/sys/windows" +) + +// OSVersion is a wrapper for Windows version information +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx +type OSVersion struct { + Version uint32 + MajorVersion uint8 + MinorVersion uint8 + Build uint16 +} + +var ( + osv OSVersion + once sync.Once +) + +// Get gets the operating system version on Windows. +// The calling application must be manifested to get the correct version information. +func Get() OSVersion { + once.Do(func() { + var err error + osv = OSVersion{} + osv.Version, err = windows.GetVersion() + if err != nil { + // GetVersion never fails. + panic(err) + } + osv.MajorVersion = uint8(osv.Version & 0xFF) + osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) + osv.Build = uint16(osv.Version >> 16) + }) + return osv +} + +// Build gets the build-number on Windows +// The calling application must be manifested to get the correct version information. +func Build() uint16 { + return Get().Build +} + +// String returns the OSVersion formatted as a string. It implements the +// [fmt.Stringer] interface. +func (osv OSVersion) String() string { + return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build) +} + +// ToString returns the OSVersion formatted as a string. +// +// Deprecated: use [OSVersion.String]. +func (osv OSVersion) ToString() string { + return osv.String() +} diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go b/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go new file mode 100644 index 00000000000..f8d411ad7e2 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go @@ -0,0 +1,35 @@ +package osversion + +// List of stable ABI compliant ltsc releases +// Note: List must be sorted in ascending order +var compatLTSCReleases = []uint16{ + V21H2Server, +} + +// CheckHostAndContainerCompat checks if given host and container +// OS versions are compatible. +// It includes support for stable ABI compliant versions as well. +// Every release after WS 2022 will support the previous ltsc +// container image. Stable ABI is in preview mode for windows 11 client. +// Refer: https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2022%2Cwindows-10#windows-server-host-os-compatibility +func CheckHostAndContainerCompat(host, ctr OSVersion) bool { + // check major minor versions of host and guest + if host.MajorVersion != ctr.MajorVersion || + host.MinorVersion != ctr.MinorVersion { + return false + } + + // If host is < WS 2022, exact version match is required + if host.Build < V21H2Server { + return host.Build == ctr.Build + } + + var supportedLtscRelease uint16 + for i := len(compatLTSCReleases) - 1; i >= 0; i-- { + if host.Build >= compatLTSCReleases[i] { + supportedLtscRelease = compatLTSCReleases[i] + break + } + } + return ctr.Build >= supportedLtscRelease && ctr.Build <= host.Build +} diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go new file mode 100644 index 00000000000..446369591a8 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go @@ -0,0 +1,84 @@ +package osversion + +// Windows Client and Server build numbers. +// +// See: +// https://learn.microsoft.com/en-us/windows/release-health/release-information +// https://learn.microsoft.com/en-us/windows/release-health/windows-server-release-info +// https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information +const ( + // RS1 (version 1607, codename "Redstone 1") corresponds to Windows Server + // 2016 (ltsc2016) and Windows 10 (Anniversary Update). + RS1 = 14393 + // V1607 (version 1607, codename "Redstone 1") is an alias for [RS1]. + V1607 = RS1 + // LTSC2016 (Windows Server 2016) is an alias for [RS1]. + LTSC2016 = RS1 + + // RS2 (version 1703, codename "Redstone 2") was a client-only update, and + // corresponds to Windows 10 (Creators Update). + RS2 = 15063 + // V1703 (version 1703, codename "Redstone 2") is an alias for [RS2]. + V1703 = RS2 + + // RS3 (version 1709, codename "Redstone 3") corresponds to Windows Server + // 1709 (Semi-Annual Channel (SAC)), and Windows 10 (Fall Creators Update). + RS3 = 16299 + // V1709 (version 1709, codename "Redstone 3") is an alias for [RS3]. + V1709 = RS3 + + // RS4 (version 1803, codename "Redstone 4") corresponds to Windows Server + // 1803 (Semi-Annual Channel (SAC)), and Windows 10 (April 2018 Update). + RS4 = 17134 + // V1803 (version 1803, codename "Redstone 4") is an alias for [RS4]. + V1803 = RS4 + + // RS5 (version 1809, codename "Redstone 5") corresponds to Windows Server + // 2019 (ltsc2019), and Windows 10 (October 2018 Update). + RS5 = 17763 + // V1809 (version 1809, codename "Redstone 5") is an alias for [RS5]. + V1809 = RS5 + // LTSC2019 (Windows Server 2019) is an alias for [RS5]. + LTSC2019 = RS5 + + // V19H1 (version 1903, codename 19H1) corresponds to Windows Server 1903 (semi-annual + // channel). + V19H1 = 18362 + // V1903 (version 1903) is an alias for [V19H1]. + V1903 = V19H1 + + // V19H2 (version 1909, codename 19H2) corresponds to Windows Server 1909 (semi-annual + // channel). + V19H2 = 18363 + // V1909 (version 1909) is an alias for [V19H2]. + V1909 = V19H2 + + // V20H1 (version 2004, codename 20H1) corresponds to Windows Server 2004 (semi-annual + // channel). + V20H1 = 19041 + // V2004 (version 2004) is an alias for [V20H1]. + V2004 = V20H1 + + // V20H2 corresponds to Windows Server 20H2 (semi-annual channel). + V20H2 = 19042 + + // V21H1 corresponds to Windows Server 21H1 (semi-annual channel). + V21H1 = 19043 + + // V21H2Win10 corresponds to Windows 10 (November 2021 Update). + V21H2Win10 = 19044 + + // V21H2Server corresponds to Windows Server 2022 (ltsc2022). + V21H2Server = 20348 + // LTSC2022 (Windows Server 2022) is an alias for [V21H2Server] + LTSC2022 = V21H2Server + + // V21H2Win11 corresponds to Windows 11 (original release). + V21H2Win11 = 22000 + + // V22H2Win10 corresponds to Windows 10 (2022 Update). + V22H2Win10 = 19045 + + // V22H2Win11 corresponds to Windows 11 (2022 Update). + V22H2Win11 = 22621 +) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go index 1592212e146..a4e2079e656 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn.go @@ -4,6 +4,8 @@ package antlr +import "sync" + var ATNInvalidAltNumber int type ATN struct { @@ -37,6 +39,10 @@ type ATN struct { ruleToTokenType []int states []ATNState + + mu sync.Mutex + stateMu sync.RWMutex + edgeMu sync.RWMutex } func NewATN(grammarType int, maxTokenType int) *ATN { @@ -59,14 +65,15 @@ func (a *ATN) NextTokensInContext(s ATNState, ctx RuleContext) *IntervalSet { // in s and staying in same rule. Token.EPSILON is in set if we reach end of // rule. func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet { - if s.GetNextTokenWithinRule() != nil { - return s.GetNextTokenWithinRule() + a.mu.Lock() + defer a.mu.Unlock() + iset := s.GetNextTokenWithinRule() + if iset == nil { + iset = a.NextTokensInContext(s, nil) + iset.readOnly = true + s.SetNextTokenWithinRule(iset) } - - s.SetNextTokenWithinRule(a.NextTokensInContext(s, nil)) - s.GetNextTokenWithinRule().readOnly = true - - return s.GetNextTokenWithinRule() + return iset } func (a *ATN) NextTokens(s ATNState, ctx RuleContext) *IntervalSet { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go index 0535d5246c5..97ba417f74f 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config.go @@ -251,7 +251,7 @@ func (l *LexerATNConfig) hash() int { f = 0 } h := murmurInit(7) - h = murmurUpdate(h, l.state.hash()) + h = murmurUpdate(h, l.state.GetStateNumber()) h = murmurUpdate(h, l.alt) h = murmurUpdate(h, l.context.hash()) h = murmurUpdate(h, l.semanticContext.hash()) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go index d9f74755fa7..49ad4a7197a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_config_set.go @@ -11,7 +11,7 @@ type ATNConfigSet interface { Add(ATNConfig, *DoubleDict) bool AddAll([]ATNConfig) bool - GetStates() *Set + GetStates() Set GetPredicates() []SemanticContext GetItems() []ATNConfig @@ -35,6 +35,8 @@ type ATNConfigSet interface { GetConflictingAlts() *BitSet SetConflictingAlts(*BitSet) + Alts() *BitSet + FullContext() bool GetUniqueAlt() int @@ -55,7 +57,7 @@ type BaseATNConfigSet struct { // effectively doubles the number of objects associated with ATNConfigs. All // keys are hashed by (s, i, _, pi), not including the context. Wiped out when // read-only because a set becomes a DFA state. - configLookup *Set + configLookup Set // configs is the added elements. configs []ATNConfig @@ -91,11 +93,19 @@ type BaseATNConfigSet struct { uniqueAlt int } +func (b *BaseATNConfigSet) Alts() *BitSet { + alts := NewBitSet() + for _, it := range b.configs { + alts.add(it.GetAlt()) + } + return alts +} + func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet { return &BaseATNConfigSet{ - cachedHash: -1, - configLookup: NewSet(nil, equalATNConfigs), - fullCtx: fullCtx, + cachedHash: -1, + configLookup: newArray2DHashSetWithCap(hashATNConfig, equalATNConfigs, 16, 2), + fullCtx: fullCtx, } } @@ -116,12 +126,11 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { b.dipsIntoOuterContext = true } - existing := b.configLookup.add(config).(ATNConfig) + existing := b.configLookup.Add(config).(ATNConfig) if existing == config { b.cachedHash = -1 b.configs = append(b.configs, config) // Track order here - return true } @@ -145,11 +154,11 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool { return true } -func (b *BaseATNConfigSet) GetStates() *Set { - states := NewSet(nil, nil) +func (b *BaseATNConfigSet) GetStates() Set { + states := newArray2DHashSet(nil, nil) for i := 0; i < len(b.configs); i++ { - states.add(b.configs[i].GetState()) + states.Add(b.configs[i].GetState()) } return states @@ -186,7 +195,7 @@ func (b *BaseATNConfigSet) OptimizeConfigs(interpreter *BaseATNSimulator) { panic("set is read-only") } - if b.configLookup.length() == 0 { + if b.configLookup.Len() == 0 { return } @@ -236,13 +245,11 @@ func (b *BaseATNConfigSet) hash() int { } func (b *BaseATNConfigSet) hashCodeConfigs() int { - h := murmurInit(1) - for _, c := range b.configs { - if c != nil { - h = murmurUpdate(h, c.hash()) - } + h := 1 + for _, config := range b.configs { + h = 31*h + config.hash() } - return murmurFinish(h, len(b.configs)) + return h } func (b *BaseATNConfigSet) Length() int { @@ -258,7 +265,7 @@ func (b *BaseATNConfigSet) Contains(item ATNConfig) bool { panic("not implemented for read-only sets") } - return b.configLookup.contains(item) + return b.configLookup.Contains(item) } func (b *BaseATNConfigSet) ContainsFast(item ATNConfig) bool { @@ -266,7 +273,7 @@ func (b *BaseATNConfigSet) ContainsFast(item ATNConfig) bool { panic("not implemented for read-only sets") } - return b.configLookup.contains(item) // TODO: containsFast is not implemented for Set + return b.configLookup.Contains(item) // TODO: containsFast is not implemented for Set } func (b *BaseATNConfigSet) Clear() { @@ -276,7 +283,7 @@ func (b *BaseATNConfigSet) Clear() { b.configs = make([]ATNConfig, 0) b.cachedHash = -1 - b.configLookup = NewSet(nil, equalATNConfigs) + b.configLookup = newArray2DHashSet(nil, equalATNConfigs) } func (b *BaseATNConfigSet) FullContext() bool { @@ -358,11 +365,20 @@ type OrderedATNConfigSet struct { func NewOrderedATNConfigSet() *OrderedATNConfigSet { b := NewBaseATNConfigSet(false) - b.configLookup = NewSet(nil, nil) + b.configLookup = newArray2DHashSet(nil, nil) return &OrderedATNConfigSet{BaseATNConfigSet: b} } +func hashATNConfig(i interface{}) int { + o := i.(ATNConfig) + hash := 7 + hash = 31*hash + o.GetState().GetStateNumber() + hash = 31*hash + o.GetAlt() + hash = 31*hash + o.GetSemanticContext().hash() + return hash +} + func equalATNConfigs(a, b interface{}) bool { if a == nil || b == nil { return false @@ -379,9 +395,13 @@ func equalATNConfigs(a, b interface{}) bool { return false } - nums := ai.GetState().GetStateNumber() == bi.GetState().GetStateNumber() - alts := ai.GetAlt() == bi.GetAlt() - cons := ai.GetSemanticContext().equals(bi.GetSemanticContext()) + if ai.GetState().GetStateNumber() != bi.GetState().GetStateNumber() { + return false + } + + if ai.GetAlt() != bi.GetAlt() { + return false + } - return nums && alts && cons + return ai.GetSemanticContext().equals(bi.GetSemanticContext()) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go index 18b89efafb2..cb8eafb0b2a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserialization_options.go @@ -4,7 +4,9 @@ package antlr -var ATNDeserializationOptionsdefaultOptions = &ATNDeserializationOptions{true, false, false} +import "errors" + +var defaultATNDeserializationOptions = ATNDeserializationOptions{true, true, false} type ATNDeserializationOptions struct { readOnly bool @@ -12,14 +14,48 @@ type ATNDeserializationOptions struct { generateRuleBypassTransitions bool } -func NewATNDeserializationOptions(CopyFrom *ATNDeserializationOptions) *ATNDeserializationOptions { - o := new(ATNDeserializationOptions) +func (opts *ATNDeserializationOptions) ReadOnly() bool { + return opts.readOnly +} + +func (opts *ATNDeserializationOptions) SetReadOnly(readOnly bool) { + if opts.readOnly { + panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) + } + opts.readOnly = readOnly +} + +func (opts *ATNDeserializationOptions) VerifyATN() bool { + return opts.verifyATN +} + +func (opts *ATNDeserializationOptions) SetVerifyATN(verifyATN bool) { + if opts.readOnly { + panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) + } + opts.verifyATN = verifyATN +} - if CopyFrom != nil { - o.readOnly = CopyFrom.readOnly - o.verifyATN = CopyFrom.verifyATN - o.generateRuleBypassTransitions = CopyFrom.generateRuleBypassTransitions +func (opts *ATNDeserializationOptions) GenerateRuleBypassTransitions() bool { + return opts.generateRuleBypassTransitions +} + +func (opts *ATNDeserializationOptions) SetGenerateRuleBypassTransitions(generateRuleBypassTransitions bool) { + if opts.readOnly { + panic(errors.New("Cannot mutate read only ATNDeserializationOptions")) } + opts.generateRuleBypassTransitions = generateRuleBypassTransitions +} +func DefaultATNDeserializationOptions() *ATNDeserializationOptions { + return NewATNDeserializationOptions(&defaultATNDeserializationOptions) +} + +func NewATNDeserializationOptions(other *ATNDeserializationOptions) *ATNDeserializationOptions { + o := new(ATNDeserializationOptions) + if other != nil { + *o = *other + o.readOnly = false + } return o } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go index 884d39cf7cd..aea9bbfa936 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_deserializer.go @@ -5,50 +5,34 @@ package antlr import ( - "encoding/hex" "fmt" "strconv" - "strings" - "unicode/utf16" ) -// This is the earliest supported serialized UUID. -// stick to serialized version for now, we don't need a UUID instance -var BaseSerializedUUID = "AADB8D7E-AEEF-4415-AD2B-8204D6CF042E" -var AddedUnicodeSMP = "59627784-3BE5-417A-B9EB-8131A7286089" +const serializedVersion = 4 -// This list contains all of the currently supported UUIDs, ordered by when -// the feature first appeared in this branch. -var SupportedUUIDs = []string{BaseSerializedUUID, AddedUnicodeSMP} - -var SerializedVersion = 3 - -// This is the current serialized UUID. -var SerializedUUID = AddedUnicodeSMP - -type LoopEndStateIntPair struct { +type loopEndStateIntPair struct { item0 *LoopEndState item1 int } -type BlockStartStateIntPair struct { +type blockStartStateIntPair struct { item0 BlockStartState item1 int } type ATNDeserializer struct { - deserializationOptions *ATNDeserializationOptions - data []rune - pos int - uuid string + options *ATNDeserializationOptions + data []int32 + pos int } func NewATNDeserializer(options *ATNDeserializationOptions) *ATNDeserializer { if options == nil { - options = ATNDeserializationOptionsdefaultOptions + options = &defaultATNDeserializationOptions } - return &ATNDeserializer{deserializationOptions: options} + return &ATNDeserializer{options: options} } func stringInSlice(a string, list []string) int { @@ -61,30 +45,10 @@ func stringInSlice(a string, list []string) int { return -1 } -// isFeatureSupported determines if a particular serialized representation of an -// ATN supports a particular feature, identified by the UUID used for -// serializing the ATN at the time the feature was first introduced. Feature is -// the UUID marking the first time the feature was supported in the serialized -// ATN. ActualUuid is the UUID of the actual serialized ATN which is currently -// being deserialized. It returns true if actualUuid represents a serialized ATN -// at or after the feature identified by feature was introduced, and otherwise -// false. -func (a *ATNDeserializer) isFeatureSupported(feature, actualUUID string) bool { - idx1 := stringInSlice(feature, SupportedUUIDs) - - if idx1 < 0 { - return false - } - - idx2 := stringInSlice(actualUUID, SupportedUUIDs) - - return idx2 >= idx1 -} - -func (a *ATNDeserializer) DeserializeFromUInt16(data []uint16) *ATN { - a.reset(utf16.Decode(data)) +func (a *ATNDeserializer) Deserialize(data []int32) *ATN { + a.data = data + a.pos = 0 a.checkVersion() - a.checkUUID() atn := a.readATN() @@ -92,15 +56,7 @@ func (a *ATNDeserializer) DeserializeFromUInt16(data []uint16) *ATN { a.readRules(atn) a.readModes(atn) - sets := make([]*IntervalSet, 0) - - // First, deserialize sets with 16-bit arguments <= U+FFFF. - sets = a.readSets(atn, sets, a.readInt) - // Next, if the ATN was serialized with the Unicode SMP feature, - // deserialize sets with 32-bit arguments <= U+10FFFF. - if (a.isFeatureSupported(AddedUnicodeSMP, a.uuid)) { - sets = a.readSets(atn, sets, a.readInt32) - } + sets := a.readSets(atn, nil) a.readEdges(atn, sets) a.readDecisions(atn) @@ -108,7 +64,7 @@ func (a *ATNDeserializer) DeserializeFromUInt16(data []uint16) *ATN { a.markPrecedenceDecisions(atn) a.verifyATN(atn) - if a.deserializationOptions.generateRuleBypassTransitions && atn.grammarType == ATNTypeParser { + if a.options.GenerateRuleBypassTransitions() && atn.grammarType == ATNTypeParser { a.generateRuleBypassTransitions(atn) // Re-verify after modification a.verifyATN(atn) @@ -118,42 +74,14 @@ func (a *ATNDeserializer) DeserializeFromUInt16(data []uint16) *ATN { } -func (a *ATNDeserializer) reset(data []rune) { - temp := make([]rune, len(data)) - - for i, c := range data { - // Don't adjust the first value since that's the version number - if i == 0 { - temp[i] = c - } else if c > 1 { - temp[i] = c - 2 - } else { - temp[i] = c + 65533 - } - } - - a.data = temp - a.pos = 0 -} - func (a *ATNDeserializer) checkVersion() { version := a.readInt() - if version != SerializedVersion { - panic("Could not deserialize ATN with version " + strconv.Itoa(version) + " (expected " + strconv.Itoa(SerializedVersion) + ").") + if version != serializedVersion { + panic("Could not deserialize ATN with version " + strconv.Itoa(version) + " (expected " + strconv.Itoa(serializedVersion) + ").") } } -func (a *ATNDeserializer) checkUUID() { - uuid := a.readUUID() - - if stringInSlice(uuid, SupportedUUIDs) < 0 { - panic("Could not deserialize ATN with UUID: " + uuid + " (expected " + SerializedUUID + " or a legacy UUID).") - } - - a.uuid = uuid -} - func (a *ATNDeserializer) readATN() *ATN { grammarType := a.readInt() maxTokenType := a.readInt() @@ -162,37 +90,36 @@ func (a *ATNDeserializer) readATN() *ATN { } func (a *ATNDeserializer) readStates(atn *ATN) { - loopBackStateNumbers := make([]LoopEndStateIntPair, 0) - endStateNumbers := make([]BlockStartStateIntPair, 0) - nstates := a.readInt() + // Allocate worst case size. + loopBackStateNumbers := make([]loopEndStateIntPair, 0, nstates) + endStateNumbers := make([]blockStartStateIntPair, 0, nstates) + + // Preallocate states slice. + atn.states = make([]ATNState, 0, nstates) + for i := 0; i < nstates; i++ { stype := a.readInt() // Ignore bad types of states if stype == ATNStateInvalidType { atn.addState(nil) - continue } ruleIndex := a.readInt() - if ruleIndex == 0xFFFF { - ruleIndex = -1 - } - s := a.stateFactory(stype, ruleIndex) if stype == ATNStateLoopEnd { loopBackStateNumber := a.readInt() - loopBackStateNumbers = append(loopBackStateNumbers, LoopEndStateIntPair{s.(*LoopEndState), loopBackStateNumber}) + loopBackStateNumbers = append(loopBackStateNumbers, loopEndStateIntPair{s.(*LoopEndState), loopBackStateNumber}) } else if s2, ok := s.(BlockStartState); ok { endStateNumber := a.readInt() - endStateNumbers = append(endStateNumbers, BlockStartStateIntPair{s2, endStateNumber}) + endStateNumbers = append(endStateNumbers, blockStartStateIntPair{s2, endStateNumber}) } atn.addState(s) @@ -200,20 +127,15 @@ func (a *ATNDeserializer) readStates(atn *ATN) { // Delay the assignment of loop back and end states until we know all the state // instances have been initialized - for j := 0; j < len(loopBackStateNumbers); j++ { - pair := loopBackStateNumbers[j] - + for _, pair := range loopBackStateNumbers { pair.item0.loopBackState = atn.states[pair.item1] } - for j := 0; j < len(endStateNumbers); j++ { - pair := endStateNumbers[j] - + for _, pair := range endStateNumbers { pair.item0.setEndState(atn.states[pair.item1].(*BlockEndState)) } numNonGreedyStates := a.readInt() - for j := 0; j < numNonGreedyStates; j++ { stateNumber := a.readInt() @@ -221,7 +143,6 @@ func (a *ATNDeserializer) readStates(atn *ATN) { } numPrecedenceStates := a.readInt() - for j := 0; j < numPrecedenceStates; j++ { stateNumber := a.readInt() @@ -233,12 +154,12 @@ func (a *ATNDeserializer) readRules(atn *ATN) { nrules := a.readInt() if atn.grammarType == ATNTypeLexer { - atn.ruleToTokenType = make([]int, nrules) // TODO: initIntArray(nrules, 0) + atn.ruleToTokenType = make([]int, nrules) } - atn.ruleToStartState = make([]*RuleStartState, nrules) // TODO: initIntArray(nrules, 0) + atn.ruleToStartState = make([]*RuleStartState, nrules) - for i := 0; i < nrules; i++ { + for i := range atn.ruleToStartState { s := a.readInt() startState := atn.states[s].(*RuleStartState) @@ -247,19 +168,13 @@ func (a *ATNDeserializer) readRules(atn *ATN) { if atn.grammarType == ATNTypeLexer { tokenType := a.readInt() - if tokenType == 0xFFFF { - tokenType = TokenEOF - } - atn.ruleToTokenType[i] = tokenType } } - atn.ruleToStopState = make([]*RuleStopState, nrules) //initIntArray(nrules, 0) - - for i := 0; i < len(atn.states); i++ { - state := atn.states[i] + atn.ruleToStopState = make([]*RuleStopState, nrules) + for _, state := range atn.states { if s2, ok := state.(*RuleStopState); ok { atn.ruleToStopState[s2.ruleIndex] = s2 atn.ruleToStartState[s2.ruleIndex].stopState = s2 @@ -269,17 +184,25 @@ func (a *ATNDeserializer) readRules(atn *ATN) { func (a *ATNDeserializer) readModes(atn *ATN) { nmodes := a.readInt() + atn.modeToStartState = make([]*TokensStartState, nmodes) - for i := 0; i < nmodes; i++ { + for i := range atn.modeToStartState { s := a.readInt() - atn.modeToStartState = append(atn.modeToStartState, atn.states[s].(*TokensStartState)) + atn.modeToStartState[i] = atn.states[s].(*TokensStartState) } } -func (a *ATNDeserializer) readSets(atn *ATN, sets []*IntervalSet, readUnicode func() int) []*IntervalSet { +func (a *ATNDeserializer) readSets(atn *ATN, sets []*IntervalSet) []*IntervalSet { m := a.readInt() + // Preallocate the needed capacity. + if cap(sets)-len(sets) < m { + isets := make([]*IntervalSet, len(sets), len(sets)+m) + copy(isets, sets) + sets = isets + } + for i := 0; i < m; i++ { iset := NewIntervalSet() @@ -293,8 +216,8 @@ func (a *ATNDeserializer) readSets(atn *ATN, sets []*IntervalSet, readUnicode fu } for j := 0; j < n; j++ { - i1 := readUnicode() - i2 := readUnicode() + i1 := a.readInt() + i2 := a.readInt() iset.addRange(i1, i2) } @@ -322,11 +245,9 @@ func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { } // Edges for rule stop states can be derived, so they are not serialized - for i := 0; i < len(atn.states); i++ { - state := atn.states[i] - - for j := 0; j < len(state.GetTransitions()); j++ { - var t, ok = state.GetTransitions()[j].(*RuleTransition) + for _, state := range atn.states { + for _, t := range state.GetTransitions() { + var rt, ok = t.(*RuleTransition) if !ok { continue @@ -334,48 +255,42 @@ func (a *ATNDeserializer) readEdges(atn *ATN, sets []*IntervalSet) { outermostPrecedenceReturn := -1 - if atn.ruleToStartState[t.getTarget().GetRuleIndex()].isPrecedenceRule { - if t.precedence == 0 { - outermostPrecedenceReturn = t.getTarget().GetRuleIndex() + if atn.ruleToStartState[rt.getTarget().GetRuleIndex()].isPrecedenceRule { + if rt.precedence == 0 { + outermostPrecedenceReturn = rt.getTarget().GetRuleIndex() } } - trans := NewEpsilonTransition(t.followState, outermostPrecedenceReturn) + trans := NewEpsilonTransition(rt.followState, outermostPrecedenceReturn) - atn.ruleToStopState[t.getTarget().GetRuleIndex()].AddTransition(trans, -1) + atn.ruleToStopState[rt.getTarget().GetRuleIndex()].AddTransition(trans, -1) } } - for i := 0; i < len(atn.states); i++ { - state := atn.states[i] - - if s2, ok := state.(*BaseBlockStartState); ok { + for _, state := range atn.states { + if s2, ok := state.(BlockStartState); ok { // We need to know the end state to set its start state - if s2.endState == nil { + if s2.getEndState() == nil { panic("IllegalState") } // Block end states can only be associated to a single block start state - if s2.endState.startState != nil { + if s2.getEndState().startState != nil { panic("IllegalState") } - s2.endState.startState = state + s2.getEndState().startState = state } if s2, ok := state.(*PlusLoopbackState); ok { - for j := 0; j < len(s2.GetTransitions()); j++ { - target := s2.GetTransitions()[j].getTarget() - - if t2, ok := target.(*PlusBlockStartState); ok { + for _, t := range s2.GetTransitions() { + if t2, ok := t.getTarget().(*PlusBlockStartState); ok { t2.loopBackState = state } } } else if s2, ok := state.(*StarLoopbackState); ok { - for j := 0; j < len(s2.GetTransitions()); j++ { - target := s2.GetTransitions()[j].getTarget() - - if t2, ok := target.(*StarLoopEntryState); ok { + for _, t := range s2.GetTransitions() { + if t2, ok := t.getTarget().(*StarLoopEntryState); ok { t2.loopBackState = state } } @@ -399,25 +314,13 @@ func (a *ATNDeserializer) readLexerActions(atn *ATN) { if atn.grammarType == ATNTypeLexer { count := a.readInt() - atn.lexerActions = make([]LexerAction, count) // initIntArray(count, nil) + atn.lexerActions = make([]LexerAction, count) - for i := 0; i < count; i++ { + for i := range atn.lexerActions { actionType := a.readInt() data1 := a.readInt() - - if data1 == 0xFFFF { - data1 = -1 - } - data2 := a.readInt() - - if data2 == 0xFFFF { - data2 = -1 - } - - lexerAction := a.lexerActionFactory(actionType, data1, data2) - - atn.lexerActions[i] = lexerAction + atn.lexerActions[i] = a.lexerActionFactory(actionType, data1, data2) } } } @@ -565,14 +468,12 @@ func (a *ATNDeserializer) markPrecedenceDecisions(atn *ATN) { } func (a *ATNDeserializer) verifyATN(atn *ATN) { - if !a.deserializationOptions.verifyATN { + if !a.options.VerifyATN() { return } // Verify assumptions - for i := 0; i < len(atn.states); i++ { - state := atn.states[i] - + for _, state := range atn.states { if state == nil { continue } @@ -587,18 +488,18 @@ func (a *ATNDeserializer) verifyATN(atn *ATN) { a.checkCondition(s2.loopBackState != nil, "") a.checkCondition(len(s2.GetTransitions()) == 2, "") - switch s2 := state.(type) { + switch s2.transitions[0].getTarget().(type) { case *StarBlockStartState: - var _, ok2 = s2.GetTransitions()[1].getTarget().(*LoopEndState) + _, ok := s2.transitions[1].getTarget().(*LoopEndState) - a.checkCondition(ok2, "") + a.checkCondition(ok, "") a.checkCondition(!s2.nonGreedy, "") case *LoopEndState: - var s3, ok2 = s2.GetTransitions()[1].getTarget().(*StarBlockStartState) + var _, ok = s2.transitions[1].getTarget().(*StarBlockStartState) - a.checkCondition(ok2, "") - a.checkCondition(s3.nonGreedy, "") + a.checkCondition(ok, "") + a.checkCondition(s2.nonGreedy, "") default: panic("IllegalState") @@ -607,9 +508,9 @@ func (a *ATNDeserializer) verifyATN(atn *ATN) { case *StarLoopbackState: a.checkCondition(len(state.GetTransitions()) == 1, "") - var _, ok2 = state.GetTransitions()[0].getTarget().(*StarLoopEntryState) + var _, ok = state.GetTransitions()[0].getTarget().(*StarLoopEntryState) - a.checkCondition(ok2, "") + a.checkCondition(ok, "") case *LoopEndState: a.checkCondition(s2.loopBackState != nil, "") @@ -617,8 +518,8 @@ func (a *ATNDeserializer) verifyATN(atn *ATN) { case *RuleStartState: a.checkCondition(s2.stopState != nil, "") - case *BaseBlockStartState: - a.checkCondition(s2.endState != nil, "") + case BlockStartState: + a.checkCondition(s2.getEndState() != nil, "") case *BlockEndState: a.checkCondition(s2.startState != nil, "") @@ -649,53 +550,7 @@ func (a *ATNDeserializer) readInt() int { a.pos++ - return int(v) -} - -func (a *ATNDeserializer) readInt32() int { - var low = a.readInt() - var high = a.readInt() - return low | (high << 16) -} - -//TODO -//func (a *ATNDeserializer) readLong() int64 { -// panic("Not implemented") -// var low = a.readInt32() -// var high = a.readInt32() -// return (low & 0x00000000FFFFFFFF) | (high << int32) -//} - -func createByteToHex() []string { - bth := make([]string, 256) - - for i := 0; i < 256; i++ { - bth[i] = strings.ToUpper(hex.EncodeToString([]byte{byte(i)})) - } - - return bth -} - -var byteToHex = createByteToHex() - -func (a *ATNDeserializer) readUUID() string { - bb := make([]int, 16) - - for i := 7; i >= 0; i-- { - integer := a.readInt() - - bb[(2*i)+1] = integer & 0xFF - bb[2*i] = (integer >> 8) & 0xFF - } - - return byteToHex[bb[0]] + byteToHex[bb[1]] + - byteToHex[bb[2]] + byteToHex[bb[3]] + "-" + - byteToHex[bb[4]] + byteToHex[bb[5]] + "-" + - byteToHex[bb[6]] + byteToHex[bb[7]] + "-" + - byteToHex[bb[8]] + byteToHex[bb[9]] + "-" + - byteToHex[bb[10]] + byteToHex[bb[11]] + - byteToHex[bb[12]] + byteToHex[bb[13]] + - byteToHex[bb[14]] + byteToHex[bb[15]] + return int(v) // data is 32 bits but int is at least that big } func (a *ATNDeserializer) edgeFactory(atn *ATN, typeIndex, src, trg, arg1, arg2, arg3 int, sets []*IntervalSet) Transition { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go index 563d5db38d4..3835bb2e931 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/atn_state.go @@ -243,6 +243,8 @@ func NewBasicBlockStartState() *BasicBlockStartState { return &BasicBlockStartState{BaseBlockStartState: b} } +var _ BlockStartState = &BasicBlockStartState{} + // BlockEndState is a terminal node of a simple (a|b|c) block. type BlockEndState struct { *BaseATNState @@ -318,6 +320,8 @@ func NewPlusBlockStartState() *PlusBlockStartState { return &PlusBlockStartState{BaseBlockStartState: b} } +var _ BlockStartState = &PlusBlockStartState{} + // StarBlockStartState is the block that begins a closure loop. type StarBlockStartState struct { *BaseBlockStartState @@ -331,6 +335,8 @@ func NewStarBlockStartState() *StarBlockStartState { return &StarBlockStartState{BaseBlockStartState: b} } +var _ BlockStartState = &StarBlockStartState{} + type StarLoopbackState struct { *BaseATNState } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go index 770c32a6bb5..d55a2a87d5d 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa.go @@ -6,7 +6,6 @@ package antlr import ( "sort" - "sync" ) type DFA struct { @@ -18,23 +17,27 @@ type DFA struct { // states is all the DFA states. Use Map to get the old state back; Set can only // indicate whether it is there. states map[int]*DFAState - statesMu sync.RWMutex s0 *DFAState - s0Mu sync.RWMutex // precedenceDfa is the backing field for isPrecedenceDfa and setPrecedenceDfa. // True if the DFA is for a precedence decision and false otherwise. precedenceDfa bool - precedenceDfaMu sync.RWMutex } func NewDFA(atnStartState DecisionState, decision int) *DFA { - return &DFA{ + dfa := &DFA{ atnStartState: atnStartState, decision: decision, states: make(map[int]*DFAState), } + if s, ok := atnStartState.(*StarLoopEntryState); ok && s.precedenceRuleDecision { + dfa.precedenceDfa = true + dfa.s0 = NewDFAState(-1, NewBaseATNConfigSet(false)) + dfa.s0.isAcceptState = false + dfa.s0.requiresFullContext = false + } + return dfa } // getPrecedenceStartState gets the start state for the current precedence and @@ -79,8 +82,6 @@ func (d *DFA) setPrecedenceStartState(precedence int, startState *DFAState) { } func (d *DFA) getPrecedenceDfa() bool { - d.precedenceDfaMu.RLock() - defer d.precedenceDfaMu.RUnlock() return d.precedenceDfa } @@ -104,46 +105,32 @@ func (d *DFA) setPrecedenceDfa(precedenceDfa bool) { d.setS0(nil) } - d.precedenceDfaMu.Lock() - defer d.precedenceDfaMu.Unlock() d.precedenceDfa = precedenceDfa } } func (d *DFA) getS0() *DFAState { - d.s0Mu.RLock() - defer d.s0Mu.RUnlock() return d.s0 } func (d *DFA) setS0(s *DFAState) { - d.s0Mu.Lock() - defer d.s0Mu.Unlock() d.s0 = s } func (d *DFA) getState(hash int) (*DFAState, bool) { - d.statesMu.RLock() - defer d.statesMu.RUnlock() s, ok := d.states[hash] return s, ok } func (d *DFA) setStates(states map[int]*DFAState) { - d.statesMu.Lock() - defer d.statesMu.Unlock() d.states = states } func (d *DFA) setState(hash int, state *DFAState) { - d.statesMu.Lock() - defer d.statesMu.Unlock() d.states[hash] = state } func (d *DFA) numStates() int { - d.statesMu.RLock() - defer d.statesMu.RUnlock() return len(d.states) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go index fcfef975c2e..bf2ccc06cd1 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_serializer.go @@ -7,6 +7,7 @@ package antlr import ( "fmt" "strconv" + "strings" ) // DFASerializer is a DFA walker that knows how to dump them to serialized @@ -112,7 +113,12 @@ func NewLexerDFASerializer(dfa *DFA) *LexerDFASerializer { } func (l *LexerDFASerializer) getEdgeLabel(i int) string { - return "'" + string(i) + "'" + var sb strings.Builder + sb.Grow(6) + sb.WriteByte('\'') + sb.WriteRune(rune(i)) + sb.WriteByte('\'') + return sb.String() } func (l *LexerDFASerializer) String() string { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go index 680ce9ace4a..970ed19865a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/dfa_state.go @@ -6,7 +6,6 @@ package antlr import ( "fmt" - "sync" ) // PredPrediction maps a predicate to a predicted alternative. @@ -51,7 +50,6 @@ type DFAState struct { // edges elements point to the target of the symbol. Shift up by 1 so (-1) // Token.EOF maps to the first element. edges []*DFAState - edgesMu sync.RWMutex isAcceptState bool @@ -92,16 +90,16 @@ func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState { } // GetAltSet gets the set of all alts mentioned by all ATN configurations in d. -func (d *DFAState) GetAltSet() *Set { - alts := NewSet(nil, nil) +func (d *DFAState) GetAltSet() Set { + alts := newArray2DHashSet(nil, nil) if d.configs != nil { for _, c := range d.configs.GetItems() { - alts.add(c.GetAlt()) + alts.Add(c.GetAlt()) } } - if alts.length() == 0 { + if alts.Len() == 0 { return nil } @@ -109,32 +107,22 @@ func (d *DFAState) GetAltSet() *Set { } func (d *DFAState) getEdges() []*DFAState { - d.edgesMu.RLock() - defer d.edgesMu.RUnlock() return d.edges } func (d *DFAState) numEdges() int { - d.edgesMu.RLock() - defer d.edgesMu.RUnlock() return len(d.edges) } func (d *DFAState) getIthEdge(i int) *DFAState { - d.edgesMu.RLock() - defer d.edgesMu.RUnlock() return d.edges[i] } func (d *DFAState) setEdges(newEdges []*DFAState) { - d.edgesMu.Lock() - defer d.edgesMu.Unlock() d.edges = newEdges } func (d *DFAState) setIthEdge(i int, edge *DFAState) { - d.edgesMu.Lock() - defer d.edgesMu.Unlock() d.edges[i] = edge } @@ -173,26 +161,11 @@ func (d *DFAState) String() string { } } - return fmt.Sprintf("%d:%s%s", fmt.Sprint(d.configs), s) + return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s) } func (d *DFAState) hash() int { - h := murmurInit(11) - - c := 1 - if d.isAcceptState { - if d.predicates != nil { - for _, p := range d.predicates { - h = murmurUpdate(h, p.alt) - h = murmurUpdate(h, p.pred.hash()) - c += 2 - } - } else { - h = murmurUpdate(h, d.prediction) - c += 1 - } - } - + h := murmurInit(7) h = murmurUpdate(h, d.configs.hash()) - return murmurFinish(h, c) -} \ No newline at end of file + return murmurFinish(h, 1) +} diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go index 977a6e45496..c4080dbfd18 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/error_strategy.go @@ -16,7 +16,7 @@ type ErrorStrategy interface { RecoverInline(Parser) Token Recover(Parser, RecognitionException) Sync(Parser) - inErrorRecoveryMode(Parser) bool + InErrorRecoveryMode(Parser) bool ReportError(Parser, RecognitionException) ReportMatch(Parser) } @@ -40,7 +40,7 @@ func NewDefaultErrorStrategy() *DefaultErrorStrategy { // error". This is used to suppress Reporting multiple error messages while // attempting to recover from a detected syntax error. // - // @see //inErrorRecoveryMode + // @see //InErrorRecoveryMode // d.errorRecoveryMode = false @@ -71,7 +71,7 @@ func (d *DefaultErrorStrategy) beginErrorCondition(recognizer Parser) { d.errorRecoveryMode = true } -func (d *DefaultErrorStrategy) inErrorRecoveryMode(recognizer Parser) bool { +func (d *DefaultErrorStrategy) InErrorRecoveryMode(recognizer Parser) bool { return d.errorRecoveryMode } @@ -118,7 +118,7 @@ func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) { func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionException) { // if we've already Reported an error and have not Matched a token // yet successfully, don't Report any errors. - if d.inErrorRecoveryMode(recognizer) { + if d.InErrorRecoveryMode(recognizer) { return // don't Report spurious errors } d.beginErrorCondition(recognizer) @@ -209,7 +209,7 @@ func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException // func (d *DefaultErrorStrategy) Sync(recognizer Parser) { // If already recovering, don't try to Sync - if d.inErrorRecoveryMode(recognizer) { + if d.InErrorRecoveryMode(recognizer) { return } @@ -312,7 +312,7 @@ func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *Faile // @param recognizer the parser instance // func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { - if d.inErrorRecoveryMode(recognizer) { + if d.InErrorRecoveryMode(recognizer) { return } d.beginErrorCondition(recognizer) @@ -341,7 +341,7 @@ func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) { // @param recognizer the parser instance // func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) { - if d.inErrorRecoveryMode(recognizer) { + if d.InErrorRecoveryMode(recognizer) { return } d.beginErrorCondition(recognizer) @@ -738,7 +738,11 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) { context := recognizer.GetParserRuleContext() for context != nil { context.SetException(e) - context = context.GetParent().(ParserRuleContext) + if parent, ok := context.GetParent().(ParserRuleContext); ok { + context = parent + } else { + context = nil + } } panic(NewParseCancellationException()) // TODO we don't emit e properly } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go index 510d9091141..1e9393adb60 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/interval_set.go @@ -226,16 +226,28 @@ func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []strin func (i *IntervalSet) toCharString() string { names := make([]string, len(i.intervals)) + var sb strings.Builder + for j := 0; j < len(i.intervals); j++ { v := i.intervals[j] if v.Stop == v.Start+1 { if v.Start == TokenEOF { names = append(names, "") } else { - names = append(names, ("'" + string(v.Start) + "'")) + sb.WriteByte('\'') + sb.WriteRune(rune(v.Start)) + sb.WriteByte('\'') + names = append(names, sb.String()) + sb.Reset() } } else { - names = append(names, "'"+string(v.Start)+"'..'"+string(v.Stop-1)+"'") + sb.WriteByte('\'') + sb.WriteRune(rune(v.Start)) + sb.WriteString("'..'") + sb.WriteRune(rune(v.Stop - 1)) + sb.WriteByte('\'') + names = append(names, sb.String()) + sb.Reset() } } if len(names) > 1 { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go index 20df84f9437..5a325be1372 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action.go @@ -414,10 +414,9 @@ func (l *LexerIndexedCustomAction) execute(lexer Lexer) { func (l *LexerIndexedCustomAction) hash() int { h := murmurInit(0) - h = murmurUpdate(h, l.actionType) h = murmurUpdate(h, l.offset) h = murmurUpdate(h, l.lexerAction.hash()) - return murmurFinish(h, 3) + return murmurFinish(h, 2) } func (l *LexerIndexedCustomAction) equals(other LexerAction) bool { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go index 80b949a1a54..056941dd6e7 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_action_executor.go @@ -161,10 +161,13 @@ func (l *LexerActionExecutor) hash() int { func (l *LexerActionExecutor) equals(other interface{}) bool { if l == other { return true - } else if _, ok := other.(*LexerActionExecutor); !ok { + } + othert, ok := other.(*LexerActionExecutor) + if !ok { + return false + } + if othert == nil { return false - } else { - return l.cachedHash == other.(*LexerActionExecutor).cachedHash && - &l.lexerActions == &other.(*LexerActionExecutor).lexerActions } + return l.cachedHash == othert.cachedHash && &l.lexerActions == &othert.lexerActions } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go index 32d69e1b87c..dc05153ea44 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/lexer_atn_simulator.go @@ -7,6 +7,7 @@ package antlr import ( "fmt" "strconv" + "strings" ) var ( @@ -90,11 +91,16 @@ func (l *LexerATNSimulator) Match(input CharStream, mode int) int { dfa := l.decisionToDFA[mode] - if dfa.getS0() == nil { + var s0 *DFAState + l.atn.stateMu.RLock() + s0 = dfa.getS0() + l.atn.stateMu.RUnlock() + + if s0 == nil { return l.MatchATN(input) } - return l.execATN(input, dfa.getS0()) + return l.execATN(input, s0) } func (l *LexerATNSimulator) reset() { @@ -116,11 +122,7 @@ func (l *LexerATNSimulator) MatchATN(input CharStream) int { suppressEdge := s0Closure.hasSemanticContext s0Closure.hasSemanticContext = false - next := l.addDFAState(s0Closure) - - if !suppressEdge { - l.decisionToDFA[l.mode].setS0(next) - } + next := l.addDFAState(s0Closure, suppressEdge) predict := l.execATN(input, next) @@ -202,11 +204,16 @@ func (l *LexerATNSimulator) execATN(input CharStream, ds0 *DFAState) int { // {@code t}, or {@code nil} if the target state for l edge is not // already cached func (l *LexerATNSimulator) getExistingTargetState(s *DFAState, t int) *DFAState { - if s.getEdges() == nil || t < LexerATNSimulatorMinDFAEdge || t > LexerATNSimulatorMaxDFAEdge { + if t < LexerATNSimulatorMinDFAEdge || t > LexerATNSimulatorMaxDFAEdge { return nil } - target := s.getIthEdge(t-LexerATNSimulatorMinDFAEdge) + l.atn.edgeMu.RLock() + defer l.atn.edgeMu.RUnlock() + if s.getEdges() == nil { + return nil + } + target := s.getIthEdge(t - LexerATNSimulatorMinDFAEdge) if LexerATNSimulatorDebug && target != nil { fmt.Println("reuse state " + strconv.Itoa(s.stateNumber) + " edge to " + strconv.Itoa(target.stateNumber)) } @@ -299,7 +306,7 @@ func (l *LexerATNSimulator) getReachableConfigSet(input CharStream, closure ATNC func (l *LexerATNSimulator) accept(input CharStream, lexerActionExecutor *LexerActionExecutor, startIndex, index, line, charPos int) { if LexerATNSimulatorDebug { - fmt.Printf("ACTION %s\n", lexerActionExecutor) + fmt.Printf("ACTION %v\n", lexerActionExecutor) } // seek to after last char in token input.Seek(index) @@ -536,7 +543,7 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg suppressEdge := cfgs.HasSemanticContext() cfgs.SetHasSemanticContext(false) - to = l.addDFAState(cfgs) + to = l.addDFAState(cfgs, true) if suppressEdge { return to @@ -550,6 +557,8 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg if LexerATNSimulatorDebug { fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + strconv.Itoa(tk)) } + l.atn.edgeMu.Lock() + defer l.atn.edgeMu.Unlock() if from.getEdges() == nil { // make room for tokens 1..n and -1 masquerading as index 0 from.setEdges(make([]*DFAState, LexerATNSimulatorMaxDFAEdge-LexerATNSimulatorMinDFAEdge+1)) @@ -563,7 +572,7 @@ func (l *LexerATNSimulator) addDFAEdge(from *DFAState, tk int, to *DFAState, cfg // configurations already. This method also detects the first // configuration containing an ATN rule stop state. Later, when // traversing the DFA, we will know which rule to accept. -func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet) *DFAState { +func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool) *DFAState { proposed := NewDFAState(-1, configs) var firstConfigWithRuleStopState ATNConfig @@ -584,16 +593,22 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet) *DFAState { } hash := proposed.hash() dfa := l.decisionToDFA[l.mode] + + l.atn.stateMu.Lock() + defer l.atn.stateMu.Unlock() existing, ok := dfa.getState(hash) if ok { - return existing - } - newState := proposed - newState.stateNumber = dfa.numStates() - configs.SetReadOnly(true) - newState.configs = configs - dfa.setState(hash, newState) - return newState + proposed = existing + } else { + proposed.stateNumber = dfa.numStates() + configs.SetReadOnly(true) + proposed.configs = configs + dfa.setState(hash, proposed) + } + if !suppressEdge { + dfa.setS0(proposed) + } + return proposed } func (l *LexerATNSimulator) getDFA(mode int) *DFA { @@ -630,7 +645,13 @@ func (l *LexerATNSimulator) GetTokenName(tt int) string { return "EOF" } - return "'" + string(tt) + "'" + var sb strings.Builder + sb.Grow(6) + sb.WriteByte('\'') + sb.WriteRune(rune(tt)) + sb.WriteByte('\'') + + return sb.String() } func resetSimState(sim *SimState) { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go index 3ebc40a76b8..6ffb37de694 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/ll1_analyzer.go @@ -38,7 +38,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { look := make([]*IntervalSet, count) for alt := 0; alt < count; alt++ { look[alt] = NewIntervalSet() - lookBusy := NewSet(nil, nil) + lookBusy := newArray2DHashSet(nil, nil) seeThruPreds := false // fail to get lookahead upon pred la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false) // Wipe out lookahead for la alternative if we found nothing @@ -75,7 +75,7 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet if ctx != nil { lookContext = predictionContextFromRuleContext(s.GetATN(), ctx) } - la.look1(s, stopState, lookContext, r, NewSet(nil, nil), NewBitSet(), seeThruPreds, true) + la.look1(s, stopState, lookContext, r, newArray2DHashSet(nil, nil), NewBitSet(), seeThruPreds, true) return r } @@ -109,22 +109,22 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet // outermost context is reached. This parameter has no effect if {@code ctx} // is {@code nil}. -func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { +func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) { returnState := la.atn.states[ctx.getReturnState(i)] la.look1(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF) } -func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool) { +func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool) { c := NewBaseATNConfig6(s, 0, ctx) - if lookBusy.contains(c) { + if lookBusy.Contains(c) { return } - lookBusy.add(c) + lookBusy.Add(c) if s == stopState { if ctx == nil { @@ -148,13 +148,13 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look } if ctx != BasePredictionContextEMPTY { - removed := calledRuleStack.contains(s.GetRuleIndex()) - defer func() { - if removed { - calledRuleStack.add(s.GetRuleIndex()) - } - }() - calledRuleStack.remove(s.GetRuleIndex()) + removed := calledRuleStack.contains(s.GetRuleIndex()) + defer func() { + if removed { + calledRuleStack.add(s.GetRuleIndex()) + } + }() + calledRuleStack.remove(s.GetRuleIndex()) // run thru all possible stack tops in ctx for i := 0; i < ctx.length(); i++ { returnState := la.atn.states[ctx.getReturnState(i)] @@ -198,7 +198,7 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look } } -func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { +func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) { newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber()) diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go index fb60258e331..2ab2f560521 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser.go @@ -425,7 +425,7 @@ func (p *BaseParser) Consume() Token { } hasListener := p.parseListeners != nil && len(p.parseListeners) > 0 if p.BuildParseTrees || hasListener { - if p.errHandler.inErrorRecoveryMode(p) { + if p.errHandler.InErrorRecoveryMode(p) { node := p.ctx.AddErrorNode(o) if p.parseListeners != nil { for _, l := range p.parseListeners { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go index c83e8137b6c..888d512975a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/parser_atn_simulator.go @@ -15,6 +15,7 @@ var ( ParserATNSimulatorListATNDecisions = false ParserATNSimulatorDFADebug = false ParserATNSimulatorRetryDebug = false + TurnOffLRLoopEntryBranchOpt = false ) type ParserATNSimulator struct { @@ -95,14 +96,18 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou // Now we are certain to have a specific decision's DFA // But, do we still need an initial state? var s0 *DFAState + p.atn.stateMu.RLock() if dfa.getPrecedenceDfa() { + p.atn.edgeMu.RLock() // the start state for a precedence DFA depends on the current // parser precedence, and is provided by a DFA method. s0 = dfa.getPrecedenceStartState(p.parser.GetPrecedence()) + p.atn.edgeMu.RUnlock() } else { // the start state for a "regular" DFA is just s0 s0 = dfa.getS0() } + p.atn.stateMu.RUnlock() if s0 == nil { if outerContext == nil { @@ -113,21 +118,10 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou " exec LA(1)==" + p.getLookaheadName(input) + ", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil)) } - // If p is not a precedence DFA, we check the ATN start state - // to determine if p ATN start state is the decision for the - // closure block that determines whether a precedence rule - // should continue or complete. - - t2 := dfa.atnStartState - t, ok := t2.(*StarLoopEntryState) - if !dfa.getPrecedenceDfa() && ok { - if t.precedenceRuleDecision { - dfa.setPrecedenceDfa(true) - } - } fullCtx := false s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx) + p.atn.stateMu.Lock() if dfa.getPrecedenceDfa() { // If p is a precedence DFA, we use applyPrecedenceFilter // to convert the computed start state to a precedence start @@ -135,14 +129,19 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou // appropriate start state for the precedence level rather // than simply setting DFA.s0. // + dfa.s0.configs = s0Closure s0Closure = p.applyPrecedenceFilter(s0Closure) s0 = p.addDFAState(dfa, NewDFAState(-1, s0Closure)) + p.atn.edgeMu.Lock() dfa.setPrecedenceStartState(p.parser.GetPrecedence(), s0) + p.atn.edgeMu.Unlock() } else { s0 = p.addDFAState(dfa, NewDFAState(-1, s0Closure)) dfa.setS0(s0) } + p.atn.stateMu.Unlock() } + alt := p.execATN(dfa, s0, input, index, outerContext) if ParserATNSimulatorDebug { fmt.Println("DFA after predictATN: " + dfa.String(p.parser.GetLiteralNames(), nil)) @@ -259,11 +258,13 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, stopIndex := input.Index() input.Seek(startIndex) alts := p.evalSemanticContext(D.predicates, outerContext, true) - if alts.length() == 0 { + + switch alts.length() { + case 0: panic(p.noViableAlt(input, outerContext, D.configs, startIndex)) - } else if alts.length() == 1 { + case 1: return alts.minValue() - } else { + default: // Report ambiguity after predicate evaluation to make sure the correct set of ambig alts is Reported. p.ReportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs) return alts.minValue() @@ -291,12 +292,17 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, // already cached func (p *ParserATNSimulator) getExistingTargetState(previousD *DFAState, t int) *DFAState { - edges := previousD.getEdges() - if edges == nil { + if t+1 < 0 { return nil } - return previousD.getIthEdge(t+1) + p.atn.edgeMu.RLock() + defer p.atn.edgeMu.RUnlock() + edges := previousD.getEdges() + if edges == nil || t+1 >= len(edges) { + return nil + } + return previousD.getIthEdge(t + 1) } // Compute a target state for an edge in the DFA, and attempt to add the @@ -422,7 +428,8 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT if reach.GetUniqueAlt() != ATNInvalidAltNumber { predictedAlt = reach.GetUniqueAlt() break - } else if p.predictionMode != PredictionModeLLExactAmbigDetection { + } + if p.predictionMode != PredictionModeLLExactAmbigDetection { predictedAlt = PredictionModeresolvesToJustOneViableAlt(altSubSets) if predictedAlt != ATNInvalidAltNumber { break @@ -479,7 +486,7 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT // the fact that we should predict alternative 1. We just can't say for // sure that there is an ambiguity without looking further. - p.ReportAmbiguity(dfa, D, startIndex, input.Index(), foundExactAmbig, nil, reach) + p.ReportAmbiguity(dfa, D, startIndex, input.Index(), foundExactAmbig, reach.Alts(), reach) return predictedAlt } @@ -503,7 +510,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // ensure that the alternative Matching the longest overall sequence is // chosen when multiple such configurations can Match the input. - var SkippedStopStates []*BaseATNConfig + var skippedStopStates []*BaseATNConfig // First figure out where we can reach on input t for _, c := range closure.GetItems() { @@ -511,14 +518,9 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt fmt.Println("testing " + p.GetTokenName(t) + " at " + c.String()) } - _, ok := c.GetState().(*RuleStopState) - - if ok { + if _, ok := c.GetState().(*RuleStopState); ok { if fullCtx || t == TokenEOF { - if SkippedStopStates == nil { - SkippedStopStates = make([]*BaseATNConfig, 0) - } - SkippedStopStates = append(SkippedStopStates, c.(*BaseATNConfig)) + skippedStopStates = append(skippedStopStates, c.(*BaseATNConfig)) if ParserATNSimulatorDebug { fmt.Println("added " + c.String() + " to SkippedStopStates") } @@ -526,8 +528,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt continue } - for j := 0; j < len(c.GetState().GetTransitions()); j++ { - trans := c.GetState().GetTransitions()[j] + for _, trans := range c.GetState().GetTransitions() { target := p.getReachableTarget(trans, t) if target != nil { cfg := NewBaseATNConfig4(c, target) @@ -538,6 +539,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt } } } + // Now figure out where the reach operation can take us... var reach ATNConfigSet @@ -550,7 +552,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // condition is not true when one or more configurations have been // withheld in SkippedStopStates, or when the current symbol is EOF. // - if SkippedStopStates == nil && t != TokenEOF { + if skippedStopStates == nil && t != TokenEOF { if len(intermediate.configs) == 1 { // Don't pursue the closure if there is just one state. // It can only have one alternative just add to result @@ -568,9 +570,10 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // if reach == nil { reach = NewBaseATNConfigSet(fullCtx) - closureBusy := NewSet(nil, nil) + closureBusy := newArray2DHashSet(nil, nil) treatEOFAsEpsilon := t == TokenEOF - for k := 0; k < len(intermediate.configs); k++ { + amount := len(intermediate.configs) + for k := 0; k < amount; k++ { p.closure(intermediate.configs[k], reach, closureBusy, false, fullCtx, treatEOFAsEpsilon) } } @@ -602,9 +605,9 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt // chooses an alternative Matching the longest overall sequence when // multiple alternatives are viable. // - if SkippedStopStates != nil && ((!fullCtx) || (!PredictionModehasConfigInRuleStopState(reach))) { - for l := 0; l < len(SkippedStopStates); l++ { - reach.Add(SkippedStopStates[l], p.mergeCache) + if skippedStopStates != nil && ((!fullCtx) || (!PredictionModehasConfigInRuleStopState(reach))) { + for l := 0; l < len(skippedStopStates); l++ { + reach.Add(skippedStopStates[l], p.mergeCache) } } if len(reach.GetItems()) == 0 { @@ -640,10 +643,7 @@ func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfi } result := NewBaseATNConfigSet(configs.FullContext()) for _, config := range configs.GetItems() { - - _, ok := config.GetState().(*RuleStopState) - - if ok { + if _, ok := config.GetState().(*RuleStopState); ok { result.Add(config, p.mergeCache) continue } @@ -665,7 +665,7 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full for i := 0; i < len(a.GetTransitions()); i++ { target := a.GetTransitions()[i].getTarget() c := NewBaseATNConfig6(target, i+1, initialContext) - closureBusy := NewSet(nil, nil) + closureBusy := newArray2DHashSet(nil, nil) p.closure(c, configs, closureBusy, true, fullCtx, false) } return configs @@ -787,7 +787,7 @@ func (p *ParserATNSimulator) getPredsForAmbigAlts(ambigAlts *BitSet, configs ATN } } nPredAlts := 0 - for i := 1; i < nalts+1; i++ { + for i := 1; i <= nalts; i++ { pred := altToPred[i] if pred == nil { altToPred[i] = SemanticContextNone @@ -972,14 +972,13 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti return predictions } -func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *Set, collectPredicates, fullCtx, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx, treatEOFAsEpsilon bool) { initialDepth := 0 p.closureCheckingStopState(config, configs, closureBusy, collectPredicates, fullCtx, initialDepth, treatEOFAsEpsilon) } -func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { - +func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { if ParserATNSimulatorDebug { fmt.Println("closure(" + config.String() + ")") fmt.Println("configs(" + configs.String() + ")") @@ -988,8 +987,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs } } - _, ok := config.GetState().(*RuleStopState) - if ok { + if _, ok := config.GetState().(*RuleStopState); ok { // We hit rule end. If we have context info, use it // run thru all possible stack tops in ctx if !config.GetContext().isEmpty() { @@ -1033,7 +1031,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs } // Do the actual work of walking epsilon edges// -func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy *Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { +func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) { state := config.GetState() // optimization if !state.GetEpsilonOnlyTransitions() { @@ -1042,30 +1040,24 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, // both epsilon transitions and non-epsilon transitions. } for i := 0; i < len(state.GetTransitions()); i++ { + if i == 0 && p.canDropLoopEntryEdgeInLeftRecursiveRule(config) { + continue + } + t := state.GetTransitions()[i] _, ok := t.(*ActionTransition) continueCollecting := collectPredicates && !ok c := p.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEOFAsEpsilon) if ci, ok := c.(*BaseATNConfig); ok && ci != nil { - if !t.getIsEpsilon() && closureBusy.add(c) != c { - // avoid infinite recursion for EOF* and EOF+ - continue - } newDepth := depth if _, ok := config.GetState().(*RuleStopState); ok { - // target fell off end of rule mark resulting c as having dipped into outer context // We can't get here if incoming config was rule stop and we had context // track how far we dip into outer context. Might // come in handy and we avoid evaluating context dependent // preds if p is > 0. - if closureBusy.add(c) != c { - // avoid infinite recursion for right-recursive rules - continue - } - if p.dfa != nil && p.dfa.getPrecedenceDfa() { if t.(*EpsilonTransition).outermostPrecedenceReturn == p.dfa.atnStartState.GetRuleIndex() { c.setPrecedenceFilterSuppressed(true) @@ -1073,15 +1065,27 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, } c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1) + + if closureBusy.Add(c) != c { + // avoid infinite recursion for right-recursive rules + continue + } + configs.SetDipsIntoOuterContext(true) // TODO: can remove? only care when we add to set per middle of p method newDepth-- if ParserATNSimulatorDebug { fmt.Println("dips into outer ctx: " + c.String()) } - } else if _, ok := t.(*RuleTransition); ok { - // latch when newDepth goes negative - once we step out of the entry context we can't return - if newDepth >= 0 { - newDepth++ + } else { + if !t.getIsEpsilon() && closureBusy.Add(c) != c { + // avoid infinite recursion for EOF* and EOF+ + continue + } + if _, ok := t.(*RuleTransition); ok { + // latch when newDepth goes negative - once we step out of the entry context we can't return + if newDepth >= 0 { + newDepth++ + } } } p.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEOFAsEpsilon) @@ -1089,12 +1093,93 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, } } +func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNConfig) bool { + if TurnOffLRLoopEntryBranchOpt { + return false + } + + _p := config.GetState() + + // First check to see if we are in StarLoopEntryState generated during + // left-recursion elimination. For efficiency, also check if + // the context has an empty stack case. If so, it would mean + // global FOLLOW so we can't perform optimization + if startLoop, ok := _p.(StarLoopEntryState); !ok || !startLoop.precedenceRuleDecision || config.GetContext().isEmpty() || config.GetContext().hasEmptyPath() { + return false + } + + // Require all return states to return back to the same rule + // that p is in. + numCtxs := config.GetContext().length() + for i := 0; i < numCtxs; i++ { + returnState := p.atn.states[config.GetContext().getReturnState(i)] + if returnState.GetRuleIndex() != _p.GetRuleIndex() { + return false + } + } + + decisionStartState := _p.(BlockStartState).GetTransitions()[0].getTarget().(BlockStartState) + blockEndStateNum := decisionStartState.getEndState().stateNumber + blockEndState := p.atn.states[blockEndStateNum].(*BlockEndState) + + // Verify that the top of each stack context leads to loop entry/exit + // state through epsilon edges and w/o leaving rule. + + for i := 0; i < numCtxs; i++ { // for each stack context + returnStateNumber := config.GetContext().getReturnState(i) + returnState := p.atn.states[returnStateNumber] + + // all states must have single outgoing epsilon edge + if len(returnState.GetTransitions()) != 1 || !returnState.GetTransitions()[0].getIsEpsilon() { + return false + } + + // Look for prefix op case like 'not expr', (' type ')' expr + returnStateTarget := returnState.GetTransitions()[0].getTarget() + if returnState.GetStateType() == ATNStateBlockEnd && returnStateTarget == _p { + continue + } + + // Look for 'expr op expr' or case where expr's return state is block end + // of (...)* internal block; the block end points to loop back + // which points to p but we don't need to check that + if returnState == blockEndState { + continue + } + + // Look for ternary expr ? expr : expr. The return state points at block end, + // which points at loop entry state + if returnStateTarget == blockEndState { + continue + } + + // Look for complex prefix 'between expr and expr' case where 2nd expr's + // return state points at block end state of (...)* internal block + if returnStateTarget.GetStateType() == ATNStateBlockEnd && + len(returnStateTarget.GetTransitions()) == 1 && + returnStateTarget.GetTransitions()[0].getIsEpsilon() && + returnStateTarget.GetTransitions()[0].getTarget() == _p { + continue + } + + // anything else ain't conforming + return false + } + + return true +} + func (p *ParserATNSimulator) getRuleName(index int) string { if p.parser != nil && index >= 0 { return p.parser.GetRuleNames()[index] } + var sb strings.Builder + sb.Grow(32) - return "" + sb.WriteString("') + return sb.String() } func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, collectPredicates, inContext, fullCtx, treatEOFAsEpsilon bool) ATNConfig { @@ -1110,25 +1195,7 @@ func (p *ParserATNSimulator) getEpsilonTarget(config ATNConfig, t Transition, co return p.actionTransition(config, t.(*ActionTransition)) case TransitionEPSILON: return NewBaseATNConfig4(config, t.getTarget()) - case TransitionATOM: - // EOF transitions act like epsilon transitions after the first EOF - // transition is traversed - if treatEOFAsEpsilon { - if t.Matches(TokenEOF, 0, 1) { - return NewBaseATNConfig4(config, t.getTarget()) - } - } - return nil - case TransitionRANGE: - // EOF transitions act like epsilon transitions after the first EOF - // transition is traversed - if treatEOFAsEpsilon { - if t.Matches(TokenEOF, 0, 1) { - return NewBaseATNConfig4(config, t.getTarget()) - } - } - return nil - case TransitionSET: + case TransitionATOM, TransitionRANGE, TransitionSET: // EOF transitions act like epsilon transitions after the first EOF // transition is traversed if treatEOFAsEpsilon { @@ -1196,7 +1263,7 @@ func (p *ParserATNSimulator) predTransition(config ATNConfig, pt *PredicateTrans } } var c *BaseATNConfig - if collectPredicates && ((pt.isCtxDependent && inContext) || !pt.isCtxDependent) { + if collectPredicates && (!pt.isCtxDependent || inContext) { if fullCtx { // In full context mode, we can evaluate predicates on-the-fly // during closure, which dramatically reduces the size of @@ -1381,14 +1448,18 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA if to == nil { return nil } + p.atn.stateMu.Lock() to = p.addDFAState(dfa, to) // used existing if possible not incoming + p.atn.stateMu.Unlock() if from == nil || t < -1 || t > p.atn.maxTokenType { return to } + p.atn.edgeMu.Lock() if from.getEdges() == nil { from.setEdges(make([]*DFAState, p.atn.maxTokenType+1+1)) } from.setIthEdge(t+1, to) // connect + p.atn.edgeMu.Unlock() if ParserATNSimulatorDebug { var names []string diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go index 99acb333fa2..9fdfd52b26c 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/prediction_context.go @@ -58,9 +58,15 @@ func calculateHash(parent PredictionContext, returnState int) int { return murmurFinish(h, 2) } +var _emptyPredictionContextHash int + +func init() { + _emptyPredictionContextHash = murmurInit(1) + _emptyPredictionContextHash = murmurFinish(_emptyPredictionContextHash, 0) +} + func calculateEmptyHash() int { - h := murmurInit(1) - return murmurFinish(h, 0) + return _emptyPredictionContextHash } // Used to cache {@link BasePredictionContext} objects. Its used for the shared @@ -113,16 +119,16 @@ type BaseSingletonPredictionContext struct { } func NewBaseSingletonPredictionContext(parent PredictionContext, returnState int) *BaseSingletonPredictionContext { - - s := new(BaseSingletonPredictionContext) - s.BasePredictionContext = NewBasePredictionContext(37) - + var cachedHash int if parent != nil { - s.cachedHash = calculateHash(parent, returnState) + cachedHash = calculateHash(parent, returnState) } else { - s.cachedHash = calculateEmptyHash() + cachedHash = calculateEmptyHash() } + s := new(BaseSingletonPredictionContext) + s.BasePredictionContext = NewBasePredictionContext(cachedHash) + s.parentCtx = parent s.returnState = returnState @@ -175,15 +181,7 @@ func (b *BaseSingletonPredictionContext) equals(other PredictionContext) bool { } func (b *BaseSingletonPredictionContext) hash() int { - h := murmurInit(1) - - if b.parentCtx == nil { - return murmurFinish(h, 0) - } - - h = murmurUpdate(h, b.parentCtx.hash()) - h = murmurUpdate(h, b.returnState) - return murmurFinish(h, 2) + return b.cachedHash } func (b *BaseSingletonPredictionContext) String() string { @@ -253,14 +251,21 @@ func NewArrayPredictionContext(parents []PredictionContext, returnStates []int) // from {@link //EMPTY} and non-empty. We merge {@link //EMPTY} by using // nil parent and // returnState == {@link //EmptyReturnState}. + hash := murmurInit(1) - c := new(ArrayPredictionContext) - c.BasePredictionContext = NewBasePredictionContext(37) + for _, parent := range parents { + hash = murmurUpdate(hash, parent.hash()) + } - for i := range parents { - c.cachedHash += calculateHash(parents[i], returnStates[i]) + for _, returnState := range returnStates { + hash = murmurUpdate(hash, returnState) } + hash = murmurFinish(hash, len(parents)<<1) + + c := new(ArrayPredictionContext) + c.BasePredictionContext = NewBasePredictionContext(hash) + c.parents = parents c.returnStates = returnStates @@ -305,17 +310,7 @@ func (a *ArrayPredictionContext) equals(other PredictionContext) bool { } func (a *ArrayPredictionContext) hash() int { - h := murmurInit(1) - - for _, p := range a.parents { - h = murmurUpdate(h, p.hash()) - } - - for _, r := range a.returnStates { - h = murmurUpdate(h, r) - } - - return murmurFinish(h, 2 * len(a.parents)) + return a.BasePredictionContext.cachedHash } func (a *ArrayPredictionContext) String() string { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go index 89d35244a2e..93efcf355d8 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/recognizer.go @@ -49,7 +49,7 @@ var tokenTypeMapCache = make(map[string]int) var ruleIndexMapCache = make(map[string]int) func (b *BaseRecognizer) checkVersion(toolVersion string) { - runtimeVersion := "4.9.2" + runtimeVersion := "4.10.1" if runtimeVersion != toolVersion { fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go index 49205a16240..9ada430779c 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/semantic_context.go @@ -108,7 +108,15 @@ func (p *Predicate) equals(other interface{}) bool { } func (p *Predicate) hash() int { - return p.ruleIndex*43 + p.predIndex*47 + h := murmurInit(0) + h = murmurUpdate(h, p.ruleIndex) + h = murmurUpdate(h, p.predIndex) + if p.isCtxDependent { + h = murmurUpdate(h, 1) + } else { + h = murmurUpdate(h, 0) + } + return murmurFinish(h, 3) } func (p *Predicate) String() string { @@ -154,21 +162,24 @@ func (p *PrecedencePredicate) equals(other interface{}) bool { } func (p *PrecedencePredicate) hash() int { - return p.precedence * 51 + h := uint32(1) + h = 31*h + uint32(p.precedence) + return int(h) } func (p *PrecedencePredicate) String() string { return "{" + strconv.Itoa(p.precedence) + ">=prec}?" } -func PrecedencePredicatefilterPrecedencePredicates(set *Set) []*PrecedencePredicate { +func PrecedencePredicatefilterPrecedencePredicates(set Set) []*PrecedencePredicate { result := make([]*PrecedencePredicate, 0) - for _, v := range set.values() { + set.Each(func(v interface{}) bool { if c2, ok := v.(*PrecedencePredicate); ok { result = append(result, c2) } - } + return true + }) return result } @@ -182,21 +193,21 @@ type AND struct { func NewAND(a, b SemanticContext) *AND { - operands := NewSet(nil, nil) + operands := newArray2DHashSet(nil, nil) if aa, ok := a.(*AND); ok { for _, o := range aa.opnds { - operands.add(o) + operands.Add(o) } } else { - operands.add(a) + operands.Add(a) } if ba, ok := b.(*AND); ok { for _, o := range ba.opnds { - operands.add(o) + operands.Add(o) } } else { - operands.add(b) + operands.Add(b) } precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) if len(precedencePredicates) > 0 { @@ -209,10 +220,10 @@ func NewAND(a, b SemanticContext) *AND { } } - operands.add(reduced) + operands.Add(reduced) } - vs := operands.values() + vs := operands.Values() opnds := make([]SemanticContext, len(vs)) for i, v := range vs { opnds[i] = v.(SemanticContext) @@ -334,21 +345,21 @@ type OR struct { func NewOR(a, b SemanticContext) *OR { - operands := NewSet(nil, nil) + operands := newArray2DHashSet(nil, nil) if aa, ok := a.(*OR); ok { for _, o := range aa.opnds { - operands.add(o) + operands.Add(o) } } else { - operands.add(a) + operands.Add(a) } if ba, ok := b.(*OR); ok { for _, o := range ba.opnds { - operands.add(o) + operands.Add(o) } } else { - operands.add(b) + operands.Add(b) } precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands) if len(precedencePredicates) > 0 { @@ -361,10 +372,10 @@ func NewOR(a, b SemanticContext) *OR { } } - operands.add(reduced) + operands.Add(reduced) } - vs := operands.values() + vs := operands.Values() opnds := make([]SemanticContext, len(vs)) for i, v := range vs { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/transition.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/transition.go index eb7e57e9aa0..53056bd74f4 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/transition.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/transition.go @@ -7,6 +7,7 @@ package antlr import ( "fmt" "strconv" + "strings" ) // atom, set, epsilon, action, predicate, rule transitions. @@ -236,7 +237,13 @@ func (t *RangeTransition) Matches(symbol, minVocabSymbol, maxVocabSymbol int) bo } func (t *RangeTransition) String() string { - return "'" + string(t.start) + "'..'" + string(t.stop) + "'" + var sb strings.Builder + sb.WriteByte('\'') + sb.WriteRune(rune(t.start)) + sb.WriteString("'..'") + sb.WriteRune(rune(t.stop)) + sb.WriteByte('\'') + return sb.String() } type AbstractPredicateTransition interface { diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go index bdeb6d78811..08ce22bba39 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/tree.go @@ -64,7 +64,7 @@ type BaseParseTreeVisitor struct{} var _ ParseTreeVisitor = &BaseParseTreeVisitor{} -func (v *BaseParseTreeVisitor) Visit(tree ParseTree) interface{} { return nil } +func (v *BaseParseTreeVisitor) Visit(tree ParseTree) interface{} { return tree.Accept(v) } func (v *BaseParseTreeVisitor) VisitChildren(node RuleNode) interface{} { return nil } func (v *BaseParseTreeVisitor) VisitTerminal(node TerminalNode) interface{} { return nil } func (v *BaseParseTreeVisitor) VisitErrorNode(node ErrorNode) interface{} { return nil } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go index bba2ffae793..ec219df983a 100644 --- a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils.go @@ -8,7 +8,7 @@ import ( "bytes" "errors" "fmt" - "sort" + "math/bits" "strconv" "strings" ) @@ -47,35 +47,6 @@ func (s *IntStack) Push(e int) { *s = append(*s, e) } -type Set struct { - data map[int][]interface{} - hashcodeFunction func(interface{}) int - equalsFunction func(interface{}, interface{}) bool -} - -func NewSet( - hashcodeFunction func(interface{}) int, - equalsFunction func(interface{}, interface{}) bool) *Set { - - s := new(Set) - - s.data = make(map[int][]interface{}) - - if hashcodeFunction != nil { - s.hashcodeFunction = hashcodeFunction - } else { - s.hashcodeFunction = standardHashFunction - } - - if equalsFunction == nil { - s.equalsFunction = standardEqualsFunction - } else { - s.equalsFunction = equalsFunction - } - - return s -} - func standardEqualsFunction(a interface{}, b interface{}) bool { ac, oka := a.(comparable) @@ -100,125 +71,92 @@ type hasher interface { hash() int } -func (s *Set) length() int { - return len(s.data) -} - -func (s *Set) add(value interface{}) interface{} { - - key := s.hashcodeFunction(value) +const bitsPerWord = 64 - values := s.data[key] - - if s.data[key] != nil { - for i := 0; i < len(values); i++ { - if s.equalsFunction(value, values[i]) { - return values[i] - } - } - - s.data[key] = append(s.data[key], value) - return value - } - - v := make([]interface{}, 1, 10) - v[0] = value - s.data[key] = v - - return value +func indexForBit(bit int) int { + return bit / bitsPerWord } -func (s *Set) contains(value interface{}) bool { - - key := s.hashcodeFunction(value) - - values := s.data[key] - - if s.data[key] != nil { - for i := 0; i < len(values); i++ { - if s.equalsFunction(value, values[i]) { - return true - } - } +func wordForBit(data []uint64, bit int) uint64 { + idx := indexForBit(bit) + if idx >= len(data) { + return 0 } - return false + return data[idx] } -func (s *Set) values() []interface{} { - var l []interface{} - - for _, v := range s.data { - l = append(l, v...) - } - - return l +func maskForBit(bit int) uint64 { + return uint64(1) << (bit % bitsPerWord) } -func (s *Set) String() string { - r := "" - - for _, av := range s.data { - for _, v := range av { - r += fmt.Sprint(v) - } - } - - return r +func wordsNeeded(bit int) int { + return indexForBit(bit) + 1 } type BitSet struct { - data map[int]bool + data []uint64 } func NewBitSet() *BitSet { - b := new(BitSet) - b.data = make(map[int]bool) - return b + return &BitSet{} } func (b *BitSet) add(value int) { - b.data[value] = true + idx := indexForBit(value) + if idx >= len(b.data) { + size := wordsNeeded(value) + data := make([]uint64, size) + copy(data, b.data) + b.data = data + } + b.data[idx] |= maskForBit(value) } func (b *BitSet) clear(index int) { - delete(b.data, index) + idx := indexForBit(index) + if idx >= len(b.data) { + return + } + b.data[idx] &= ^maskForBit(index) } func (b *BitSet) or(set *BitSet) { - for k := range set.data { - b.add(k) + // Get min size necessary to represent the bits in both sets. + bLen := b.minLen() + setLen := set.minLen() + maxLen := intMax(bLen, setLen) + if maxLen > len(b.data) { + // Increase the size of len(b.data) to repesent the bits in both sets. + data := make([]uint64, maxLen) + copy(data, b.data) + b.data = data + } + // len(b.data) is at least setLen. + for i := 0; i < setLen; i++ { + b.data[i] |= set.data[i] } } func (b *BitSet) remove(value int) { - delete(b.data, value) + b.clear(value) } func (b *BitSet) contains(value int) bool { - return b.data[value] -} - -func (b *BitSet) values() []int { - ks := make([]int, len(b.data)) - i := 0 - for k := range b.data { - ks[i] = k - i++ + idx := indexForBit(value) + if idx >= len(b.data) { + return false } - sort.Ints(ks) - return ks + return (b.data[idx] & maskForBit(value)) != 0 } func (b *BitSet) minValue() int { - min := 2147483647 - - for k := range b.data { - if k < min { - min = k + for i, v := range b.data { + if v == 0 { + continue } + return i*bitsPerWord + bits.TrailingZeros64(v) } - - return min + return 2147483647 } func (b *BitSet) equals(other interface{}) bool { @@ -227,12 +165,22 @@ func (b *BitSet) equals(other interface{}) bool { return false } - if len(b.data) != len(otherBitSet.data) { + if b == otherBitSet { + return true + } + + // We only compare set bits, so we cannot rely on the two slices having the same size. Its + // possible for two BitSets to have different slice lengths but the same set bits. So we only + // compare the relavent words and ignore the trailing zeros. + bLen := b.minLen() + otherLen := otherBitSet.minLen() + + if bLen != otherLen { return false } - for k, v := range b.data { - if otherBitSet.data[k] != v { + for i := 0; i < bLen; i++ { + if b.data[i] != otherBitSet.data[i] { return false } } @@ -240,18 +188,35 @@ func (b *BitSet) equals(other interface{}) bool { return true } +func (b *BitSet) minLen() int { + for i := len(b.data); i > 0; i-- { + if b.data[i-1] != 0 { + return i + } + } + return 0 +} + func (b *BitSet) length() int { - return len(b.data) + cnt := 0 + for _, val := range b.data { + cnt += bits.OnesCount64(val) + } + return cnt } func (b *BitSet) String() string { - vals := b.values() - valsS := make([]string, len(vals)) + vals := make([]string, 0, b.length()) - for i, val := range vals { - valsS[i] = strconv.Itoa(val) + for i, v := range b.data { + for v != 0 { + n := bits.TrailingZeros64(v) + vals = append(vals, strconv.Itoa(i*bitsPerWord+n)) + v &= ^(uint64(1) << n) + } } - return "{" + strings.Join(valsS, ", ") + "}" + + return "{" + strings.Join(vals, ", ") + "}" } type AltDict struct { @@ -353,65 +318,38 @@ func PrintArrayJavaStyle(sa []string) string { return buffer.String() } -// The following routines were lifted from bits.rotate* available in Go 1.9. - -const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64 - -// rotateLeft returns the value of x rotated left by (k mod UintSize) bits. -// To rotate x right by k bits, call RotateLeft(x, -k). -func rotateLeft(x uint, k int) uint { - if uintSize == 32 { - return uint(rotateLeft32(uint32(x), k)) - } - return uint(rotateLeft64(uint64(x), k)) -} - -// rotateLeft32 returns the value of x rotated left by (k mod 32) bits. -func rotateLeft32(x uint32, k int) uint32 { - const n = 32 - s := uint(k) & (n - 1) - return x<>(n-s) -} - -// rotateLeft64 returns the value of x rotated left by (k mod 64) bits. -func rotateLeft64(x uint64, k int) uint64 { - const n = 64 - s := uint(k) & (n - 1) - return x<>(n-s) -} - - // murmur hash -const ( - c1_32 uint = 0xCC9E2D51 - c2_32 uint = 0x1B873593 - n1_32 uint = 0xE6546B64 -) - func murmurInit(seed int) int { return seed } -func murmurUpdate(h1 int, k1 int) int { - var k1u uint - k1u = uint(k1) * c1_32 - k1u = rotateLeft(k1u, 15) - k1u *= c2_32 +func murmurUpdate(h int, value int) int { + const c1 uint32 = 0xCC9E2D51 + const c2 uint32 = 0x1B873593 + const r1 uint32 = 15 + const r2 uint32 = 13 + const m uint32 = 5 + const n uint32 = 0xE6546B64 + + k := uint32(value) + k *= c1 + k = (k << r1) | (k >> (32 - r1)) + k *= c2 - var h1u = uint(h1) ^ k1u - k1u = rotateLeft(k1u, 13) - h1u = h1u*5 + 0xe6546b64 - return int(h1u) + hash := uint32(h) ^ k + hash = (hash << r2) | (hash >> (32 - r2)) + hash = hash*m + n + return int(hash) } -func murmurFinish(h1 int, numberOfWords int) int { - var h1u uint = uint(h1) - h1u ^= uint(numberOfWords * 4) - h1u ^= h1u >> 16 - h1u *= uint(0x85ebca6b) - h1u ^= h1u >> 13 - h1u *= 0xc2b2ae35 - h1u ^= h1u >> 16 +func murmurFinish(h int, numberOfWords int) int { + var hash = uint32(h) + hash ^= uint32(numberOfWords) << 2 + hash ^= hash >> 16 + hash *= 0x85ebca6b + hash ^= hash >> 13 + hash *= 0xc2b2ae35 + hash ^= hash >> 16 - return int(h1u) + return int(hash) } diff --git a/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils_set.go b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils_set.go new file mode 100644 index 00000000000..0d4eac698dc --- /dev/null +++ b/vendor/github.com/antlr/antlr4/runtime/Go/antlr/utils_set.go @@ -0,0 +1,237 @@ +package antlr + +import "math" + +const ( + _initalCapacity = 16 + _initalBucketCapacity = 8 + _loadFactor = 0.75 +) + +var _ Set = (*array2DHashSet)(nil) + +type Set interface { + Add(value interface{}) (added interface{}) + Len() int + Get(value interface{}) (found interface{}) + Contains(value interface{}) bool + Values() []interface{} + Each(f func(interface{}) bool) +} + +type array2DHashSet struct { + buckets [][]interface{} + hashcodeFunction func(interface{}) int + equalsFunction func(interface{}, interface{}) bool + + n int // How many elements in set + threshold int // when to expand + + currentPrime int // jump by 4 primes each expand or whatever + initialBucketCapacity int +} + +func (as *array2DHashSet) Each(f func(interface{}) bool) { + if as.Len() < 1 { + return + } + + for _, bucket := range as.buckets { + for _, o := range bucket { + if o == nil { + break + } + if !f(o) { + return + } + } + } +} + +func (as *array2DHashSet) Values() []interface{} { + if as.Len() < 1 { + return nil + } + + values := make([]interface{}, 0, as.Len()) + as.Each(func(i interface{}) bool { + values = append(values, i) + return true + }) + return values +} + +func (as *array2DHashSet) Contains(value interface{}) bool { + return as.Get(value) != nil +} + +func (as *array2DHashSet) Add(value interface{}) interface{} { + if as.n > as.threshold { + as.expand() + } + return as.innerAdd(value) +} + +func (as *array2DHashSet) expand() { + old := as.buckets + + as.currentPrime += 4 + + var ( + newCapacity = len(as.buckets) << 1 + newTable = as.createBuckets(newCapacity) + newBucketLengths = make([]int, len(newTable)) + ) + + as.buckets = newTable + as.threshold = int(float64(newCapacity) * _loadFactor) + + for _, bucket := range old { + if bucket == nil { + continue + } + + for _, o := range bucket { + if o == nil { + break + } + + b := as.getBuckets(o) + bucketLength := newBucketLengths[b] + var newBucket []interface{} + if bucketLength == 0 { + // new bucket + newBucket = as.createBucket(as.initialBucketCapacity) + newTable[b] = newBucket + } else { + newBucket = newTable[b] + if bucketLength == len(newBucket) { + // expand + newBucketCopy := make([]interface{}, len(newBucket)<<1) + copy(newBucketCopy[:bucketLength], newBucket) + newBucket = newBucketCopy + newTable[b] = newBucket + } + } + + newBucket[bucketLength] = o + newBucketLengths[b]++ + } + } +} + +func (as *array2DHashSet) Len() int { + return as.n +} + +func (as *array2DHashSet) Get(o interface{}) interface{} { + if o == nil { + return nil + } + + b := as.getBuckets(o) + bucket := as.buckets[b] + if bucket == nil { // no bucket + return nil + } + + for _, e := range bucket { + if e == nil { + return nil // empty slot; not there + } + if as.equalsFunction(e, o) { + return e + } + } + + return nil +} + +func (as *array2DHashSet) innerAdd(o interface{}) interface{} { + b := as.getBuckets(o) + + bucket := as.buckets[b] + + // new bucket + if bucket == nil { + bucket = as.createBucket(as.initialBucketCapacity) + bucket[0] = o + + as.buckets[b] = bucket + as.n++ + return o + } + + // look for it in bucket + for i := 0; i < len(bucket); i++ { + existing := bucket[i] + if existing == nil { // empty slot; not there, add. + bucket[i] = o + as.n++ + return o + } + + if as.equalsFunction(existing, o) { // found existing, quit + return existing + } + } + + // full bucket, expand and add to end + oldLength := len(bucket) + bucketCopy := make([]interface{}, oldLength<<1) + copy(bucketCopy[:oldLength], bucket) + bucket = bucketCopy + as.buckets[b] = bucket + bucket[oldLength] = o + as.n++ + return o +} + +func (as *array2DHashSet) getBuckets(value interface{}) int { + hash := as.hashcodeFunction(value) + return hash & (len(as.buckets) - 1) +} + +func (as *array2DHashSet) createBuckets(cap int) [][]interface{} { + return make([][]interface{}, cap) +} + +func (as *array2DHashSet) createBucket(cap int) []interface{} { + return make([]interface{}, cap) +} + +func newArray2DHashSetWithCap( + hashcodeFunction func(interface{}) int, + equalsFunction func(interface{}, interface{}) bool, + initCap int, + initBucketCap int, +) *array2DHashSet { + if hashcodeFunction == nil { + hashcodeFunction = standardHashFunction + } + + if equalsFunction == nil { + equalsFunction = standardEqualsFunction + } + + ret := &array2DHashSet{ + hashcodeFunction: hashcodeFunction, + equalsFunction: equalsFunction, + + n: 0, + threshold: int(math.Floor(_initalCapacity * _loadFactor)), + + currentPrime: 1, + initialBucketCapacity: initBucketCap, + } + + ret.buckets = ret.createBuckets(initCap) + return ret +} + +func newArray2DHashSet( + hashcodeFunction func(interface{}) int, + equalsFunction func(interface{}, interface{}) bool, +) *array2DHashSet { + return newArray2DHashSetWithCap(hashcodeFunction, equalsFunction, _initalCapacity, _initalBucketCapacity) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index a4fa6e67c0b..e3208828bd6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -548,9 +548,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -2229,183 +2226,63 @@ var awsPartition = partition{ endpointKey{ Region: "af-south-1", }: endpoint{}, - endpointKey{ - Region: "af-south-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.af-south-1.api.aws", - }, endpointKey{ Region: "ap-east-1", }: endpoint{}, - endpointKey{ - Region: "ap-east-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-east-1.api.aws", - }, endpointKey{ Region: "ap-northeast-1", }: endpoint{}, - endpointKey{ - Region: "ap-northeast-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-northeast-1.api.aws", - }, endpointKey{ Region: "ap-northeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-northeast-2.api.aws", - }, endpointKey{ Region: "ap-south-1", }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-south-1.api.aws", - }, endpointKey{ Region: "ap-southeast-1", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-southeast-1.api.aws", - }, endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ap-southeast-2.api.aws", - }, endpointKey{ Region: "ca-central-1", }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.ca-central-1.api.aws", - }, endpointKey{ Region: "eu-central-1", }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-central-1.api.aws", - }, endpointKey{ Region: "eu-north-1", }: endpoint{}, - endpointKey{ - Region: "eu-north-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-north-1.api.aws", - }, endpointKey{ Region: "eu-south-1", }: endpoint{}, - endpointKey{ - Region: "eu-south-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-south-1.api.aws", - }, endpointKey{ Region: "eu-west-1", }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-west-1.api.aws", - }, endpointKey{ Region: "eu-west-2", }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-west-2.api.aws", - }, endpointKey{ Region: "eu-west-3", }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.eu-west-3.api.aws", - }, endpointKey{ Region: "me-south-1", }: endpoint{}, - endpointKey{ - Region: "me-south-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.me-south-1.api.aws", - }, endpointKey{ Region: "sa-east-1", }: endpoint{}, - endpointKey{ - Region: "sa-east-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.sa-east-1.api.aws", - }, endpointKey{ Region: "us-east-1", }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.us-east-1.api.aws", - }, endpointKey{ Region: "us-east-2", }: endpoint{}, - endpointKey{ - Region: "us-east-2", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.us-east-2.api.aws", - }, endpointKey{ Region: "us-west-1", }: endpoint{}, - endpointKey{ - Region: "us-west-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.us-west-1.api.aws", - }, endpointKey{ Region: "us-west-2", }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.us-west-2.api.aws", - }, }, }, "apprunner": service{ @@ -2645,9 +2522,6 @@ var awsPartition = partition{ endpointKey{ Region: "eu-west-1", }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, endpointKey{ Region: "us-east-1", }: endpoint{}, @@ -3046,73 +2920,6 @@ var awsPartition = partition{ }: endpoint{}, }, }, - "backup-gateway": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "af-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-east-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-3", - }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-north-1", - }: endpoint{}, - endpointKey{ - Region: "eu-south-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - }: endpoint{}, - endpointKey{ - Region: "me-south-1", - }: endpoint{}, - endpointKey{ - Region: "sa-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-1", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "batch": service{ Defaults: endpointDefaults{ defaultKey{}: endpoint{}, @@ -3716,6 +3523,9 @@ var awsPartition = partition{ }, "cloudhsm": service{ Endpoints: serviceEndpoints{ + endpointKey{ + Region: "eu-west-1", + }: endpoint{}, endpointKey{ Region: "us-east-1", }: endpoint{}, @@ -5863,9 +5673,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -6966,7 +6773,7 @@ var awsPartition = partition{ Region: "ap-south-1", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.ap-south-1.api.aws", + Hostname: "api.ec2.ap-south-1.aws", }, endpointKey{ Region: "ap-southeast-1", @@ -7002,7 +6809,7 @@ var awsPartition = partition{ Region: "eu-west-1", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.eu-west-1.api.aws", + Hostname: "api.ec2.eu-west-1.aws", }, endpointKey{ Region: "eu-west-2", @@ -7065,7 +6872,7 @@ var awsPartition = partition{ Region: "sa-east-1", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.sa-east-1.api.aws", + Hostname: "api.ec2.sa-east-1.aws", }, endpointKey{ Region: "us-east-1", @@ -7074,7 +6881,7 @@ var awsPartition = partition{ Region: "us-east-1", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.us-east-1.api.aws", + Hostname: "api.ec2.us-east-1.aws", }, endpointKey{ Region: "us-east-1", @@ -7089,7 +6896,7 @@ var awsPartition = partition{ Region: "us-east-2", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.us-east-2.api.aws", + Hostname: "api.ec2.us-east-2.aws", }, endpointKey{ Region: "us-east-2", @@ -7113,7 +6920,7 @@ var awsPartition = partition{ Region: "us-west-2", Variant: dualStackVariant, }: endpoint{ - Hostname: "ec2.us-west-2.api.aws", + Hostname: "api.ec2.us-west-2.aws", }, endpointKey{ Region: "us-west-2", @@ -7290,9 +7097,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -8381,96 +8185,24 @@ var awsPartition = partition{ }, "email": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "af-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-3", - }: endpoint{}, endpointKey{ Region: "ap-south-1", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - }: endpoint{}, endpointKey{ Region: "eu-central-1", }: endpoint{}, - endpointKey{ - Region: "eu-north-1", - }: endpoint{}, - endpointKey{ - Region: "eu-south-1", - }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - }: endpoint{}, - endpointKey{ - Region: "fips-us-east-1", - }: endpoint{ - Hostname: "email-fips.us-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "fips-us-west-2", - }: endpoint{ - Hostname: "email-fips.us-west-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-2", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "me-south-1", - }: endpoint{}, - endpointKey{ - Region: "sa-east-1", - }: endpoint{}, endpointKey{ Region: "us-east-1", }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "email-fips.us-east-1.amazonaws.com", - }, - endpointKey{ - Region: "us-east-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-1", - }: endpoint{}, endpointKey{ Region: "us-west-2", }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "email-fips.us-west-2.amazonaws.com", - }, }, }, "emr-containers": service{ @@ -8600,52 +8332,6 @@ var awsPartition = partition{ }, }, }, - "emr-serverless": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "fips-us-east-1", - }: endpoint{ - Hostname: "emr-serverless-fips.us-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "fips-us-west-2", - }: endpoint{ - Hostname: "emr-serverless-fips.us-west-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-2", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "emr-serverless-fips.us-east-1.amazonaws.com", - }, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "emr-serverless-fips.us-west-2.amazonaws.com", - }, - }, - }, "entitlement.marketplace": service{ Defaults: endpointDefaults{ defaultKey{}: endpoint{ @@ -9042,9 +8728,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -10776,9 +10459,6 @@ var awsPartition = partition{ }, "identity-chime": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, endpointKey{ Region: "us-east-1", }: endpoint{}, @@ -11449,83 +11129,15 @@ var awsPartition = partition{ endpointKey{ Region: "us-west-2", }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "api.tunneling.iot-fips.us-west-2.amazonaws.com", - }, - }, - }, - "iotsitewise": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "fips-us-east-1", - }: endpoint{ - Hostname: "iotsitewise-fips.us-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "fips-us-west-2", - }: endpoint{ - Hostname: "iotsitewise-fips.us-west-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-2", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "iotsitewise-fips.us-east-1.amazonaws.com", - }, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "iotsitewise-fips.us-west-2.amazonaws.com", - }, - }, - }, - "iotthingsgraph": service{ - Defaults: endpointDefaults{ - defaultKey{}: endpoint{ - CredentialScope: credentialScope{ - Service: "iotthingsgraph", - }, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "api.tunneling.iot-fips.us-west-2.amazonaws.com", }, }, + }, + "iotsitewise": service{ Endpoints: serviceEndpoints{ endpointKey{ Region: "ap-northeast-1", @@ -11533,9 +11145,18 @@ var awsPartition = partition{ endpointKey{ Region: "ap-northeast-2", }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, endpointKey{ Region: "ap-southeast-2", }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, @@ -11547,16 +11168,23 @@ var awsPartition = partition{ }: endpoint{}, }, }, - "iottwinmaker": service{ + "iotthingsgraph": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + CredentialScope: credentialScope{ + Service: "iotthingsgraph", + }, + }, + }, Endpoints: serviceEndpoints{ endpointKey{ - Region: "ap-southeast-1", + Region: "ap-northeast-1", }: endpoint{}, endpointKey{ - Region: "ap-southeast-2", + Region: "ap-northeast-2", }: endpoint{}, endpointKey{ - Region: "eu-central-1", + Region: "ap-southeast-2", }: endpoint{}, endpointKey{ Region: "eu-west-1", @@ -11638,19 +11266,6 @@ var awsPartition = partition{ }: endpoint{}, }, }, - "ivschat": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "kafka": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -12901,9 +12516,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -13456,52 +13068,6 @@ var awsPartition = partition{ }: endpoint{}, }, }, - "media-pipelines-chime": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "media-pipelines-chime-fips.us-east-1.amazonaws.com", - }, - endpointKey{ - Region: "us-east-1-fips", - }: endpoint{ - Hostname: "media-pipelines-chime-fips.us-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "media-pipelines-chime-fips.us-west-2.amazonaws.com", - }, - endpointKey{ - Region: "us-west-2-fips", - }: endpoint{ - Hostname: "media-pipelines-chime-fips.us-west-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-2", - }, - Deprecated: boxedTrue, - }, - }, - }, "mediaconnect": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -13949,9 +13515,6 @@ var awsPartition = partition{ }, "messaging-chime": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, endpointKey{ Region: "us-east-1", }: endpoint{}, @@ -14867,9 +14430,6 @@ var awsPartition = partition{ }, "nimble": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, endpointKey{ Region: "ap-southeast-2", }: endpoint{}, @@ -15598,14 +15158,6 @@ var awsPartition = partition{ Region: "ap-northeast-2", }, }, - endpointKey{ - Region: "ap-northeast-3", - }: endpoint{ - Hostname: "portal.sso.ap-northeast-3.amazonaws.com", - CredentialScope: credentialScope{ - Region: "ap-northeast-3", - }, - }, endpointKey{ Region: "ap-south-1", }: endpoint{ @@ -15771,25 +15323,6 @@ var awsPartition = partition{ }: endpoint{}, }, }, - "proton": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "qldb": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -15807,12 +15340,6 @@ var awsPartition = partition{ endpointKey{ Region: "ca-central-1", }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "qldb-fips.ca-central-1.amazonaws.com", - }, endpointKey{ Region: "eu-central-1", }: endpoint{}, @@ -15822,15 +15349,6 @@ var awsPartition = partition{ endpointKey{ Region: "eu-west-2", }: endpoint{}, - endpointKey{ - Region: "fips-ca-central-1", - }: endpoint{ - Hostname: "qldb-fips.ca-central-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "ca-central-1", - }, - Deprecated: boxedTrue, - }, endpointKey{ Region: "fips-us-east-1", }: endpoint{ @@ -15959,9 +15477,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -16826,70 +16341,6 @@ var awsPartition = partition{ }, }, }, - "resiliencehub": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "af-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-east-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-north-1", - }: endpoint{}, - endpointKey{ - Region: "eu-south-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - }: endpoint{}, - endpointKey{ - Region: "me-south-1", - }: endpoint{}, - endpointKey{ - Region: "sa-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-1", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "resource-groups": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -17127,9 +16578,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -19070,9 +18518,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-northeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-northeast-3", - }: endpoint{}, endpointKey{ Region: "ap-south-1", }: endpoint{}, @@ -19082,9 +18527,6 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -19686,40 +19128,6 @@ var awsPartition = partition{ }, }, }, - "sms-voice": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "snowball": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -21188,52 +20596,16 @@ var awsPartition = partition{ }: endpoint{}, endpointKey{ Region: "eu-south-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - }: endpoint{}, - endpointKey{ - Region: "fips-us-east-1", - }: endpoint{ - Hostname: "synthetics-fips.us-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-1", - }, - Deprecated: boxedTrue, - }, + }: endpoint{}, endpointKey{ - Region: "fips-us-east-2", - }: endpoint{ - Hostname: "synthetics-fips.us-east-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-east-2", - }, - Deprecated: boxedTrue, - }, + Region: "eu-west-1", + }: endpoint{}, endpointKey{ - Region: "fips-us-west-1", - }: endpoint{ - Hostname: "synthetics-fips.us-west-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-1", - }, - Deprecated: boxedTrue, - }, + Region: "eu-west-2", + }: endpoint{}, endpointKey{ - Region: "fips-us-west-2", - }: endpoint{ - Hostname: "synthetics-fips.us-west-2.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-west-2", - }, - Deprecated: boxedTrue, - }, + Region: "eu-west-3", + }: endpoint{}, endpointKey{ Region: "me-south-1", }: endpoint{}, @@ -21243,39 +20615,15 @@ var awsPartition = partition{ endpointKey{ Region: "us-east-1", }: endpoint{}, - endpointKey{ - Region: "us-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-east-1.amazonaws.com", - }, endpointKey{ Region: "us-east-2", }: endpoint{}, - endpointKey{ - Region: "us-east-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-east-2.amazonaws.com", - }, endpointKey{ Region: "us-west-1", }: endpoint{}, - endpointKey{ - Region: "us-west-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-west-1.amazonaws.com", - }, endpointKey{ Region: "us-west-2", }: endpoint{}, - endpointKey{ - Region: "us-west-2", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-west-2.amazonaws.com", - }, }, }, "tagging": service{ @@ -22224,23 +21572,6 @@ var awsPartition = partition{ Region: "ap-southeast-2", }, }, - endpointKey{ - Region: "ap-southeast-3", - }: endpoint{ - Hostname: "waf-regional.ap-southeast-3.amazonaws.com", - CredentialScope: credentialScope{ - Region: "ap-southeast-3", - }, - }, - endpointKey{ - Region: "ap-southeast-3", - Variant: fipsVariant, - }: endpoint{ - Hostname: "waf-regional-fips.ap-southeast-3.amazonaws.com", - CredentialScope: credentialScope{ - Region: "ap-southeast-3", - }, - }, endpointKey{ Region: "ca-central-1", }: endpoint{ @@ -22432,15 +21763,6 @@ var awsPartition = partition{ }, Deprecated: boxedTrue, }, - endpointKey{ - Region: "fips-ap-southeast-3", - }: endpoint{ - Hostname: "waf-regional-fips.ap-southeast-3.amazonaws.com", - CredentialScope: credentialScope{ - Region: "ap-southeast-3", - }, - Deprecated: boxedTrue, - }, endpointKey{ Region: "fips-ca-central-1", }: endpoint{ @@ -22662,64 +21984,6 @@ var awsPartition = partition{ }, }, }, - "wellarchitected": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "ap-east-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-northeast-2", - }: endpoint{}, - endpointKey{ - Region: "ap-south-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-1", - }: endpoint{}, - endpointKey{ - Region: "ap-southeast-2", - }: endpoint{}, - endpointKey{ - Region: "ca-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-central-1", - }: endpoint{}, - endpointKey{ - Region: "eu-north-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-1", - }: endpoint{}, - endpointKey{ - Region: "eu-west-2", - }: endpoint{}, - endpointKey{ - Region: "eu-west-3", - }: endpoint{}, - endpointKey{ - Region: "me-south-1", - }: endpoint{}, - endpointKey{ - Region: "sa-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-east-2", - }: endpoint{}, - endpointKey{ - Region: "us-west-1", - }: endpoint{}, - endpointKey{ - Region: "us-west-2", - }: endpoint{}, - }, - }, "wisdom": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -23207,21 +22471,9 @@ var awscnPartition = partition{ endpointKey{ Region: "cn-north-1", }: endpoint{}, - endpointKey{ - Region: "cn-north-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.cn-north-1.api.amazonwebservices.com.cn", - }, endpointKey{ Region: "cn-northwest-1", }: endpoint{}, - endpointKey{ - Region: "cn-northwest-1", - Variant: dualStackVariant, - }: endpoint{ - Hostname: "appmesh.cn-northwest-1.api.amazonwebservices.com.cn", - }, }, }, "appsync": service{ @@ -25244,16 +24496,6 @@ var awsusgovPartition = partition{ }: endpoint{}, }, }, - "backup-gateway": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-gov-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-gov-west-1", - }: endpoint{}, - }, - }, "batch": service{ Defaults: endpointDefaults{ defaultKey{}: endpoint{}, @@ -27152,24 +26394,9 @@ var awsusgovPartition = partition{ }, "iotsitewise": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "fips-us-gov-west-1", - }: endpoint{ - Hostname: "iotsitewise-fips.us-gov-west-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-gov-west-1", - }, - Deprecated: boxedTrue, - }, endpointKey{ Region: "us-gov-west-1", }: endpoint{}, - endpointKey{ - Region: "us-gov-west-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "iotsitewise-fips.us-gov-west-1.amazonaws.com", - }, }, }, "kafka": service{ @@ -28057,13 +27284,6 @@ var awsusgovPartition = partition{ }, }, }, - "robomaker": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-gov-west-1", - }: endpoint{}, - }, - }, "route53": service{ PartitionEndpoint: "aws-us-gov-global", IsRegionalized: boxedFalse, @@ -28761,13 +27981,6 @@ var awsusgovPartition = partition{ }, }, }, - "sms-voice": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-gov-west-1", - }: endpoint{}, - }, - }, "snowball": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -29183,42 +28396,12 @@ var awsusgovPartition = partition{ }, "synthetics": service{ Endpoints: serviceEndpoints{ - endpointKey{ - Region: "fips-us-gov-east-1", - }: endpoint{ - Hostname: "synthetics-fips.us-gov-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-gov-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "fips-us-gov-west-1", - }: endpoint{ - Hostname: "synthetics-fips.us-gov-west-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-gov-west-1", - }, - Deprecated: boxedTrue, - }, endpointKey{ Region: "us-gov-east-1", }: endpoint{}, - endpointKey{ - Region: "us-gov-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-gov-east-1.amazonaws.com", - }, endpointKey{ Region: "us-gov-west-1", }: endpoint{}, - endpointKey{ - Region: "us-gov-west-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "synthetics-fips.us-gov-west-1.amazonaws.com", - }, }, }, "tagging": service{ @@ -29583,13 +28766,6 @@ var awsisoPartition = partition{ }: endpoint{}, }, }, - "appconfigdata": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-iso-west-1", - }: endpoint{}, - }, - }, "application-autoscaling": service{ Defaults: endpointDefaults{ defaultKey{}: endpoint{ @@ -29807,18 +28983,6 @@ var awsisoPartition = partition{ }: endpoint{}, }, }, - "eks": service{ - Defaults: endpointDefaults{ - defaultKey{}: endpoint{ - Protocols: []string{"http", "https"}, - }, - }, - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-iso-east-1", - }: endpoint{}, - }, - }, "elasticache": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -30488,18 +29652,6 @@ var awsisobPartition = partition{ }: endpoint{}, }, }, - "eks": service{ - Defaults: endpointDefaults{ - defaultKey{}: endpoint{ - Protocols: []string{"http", "https"}, - }, - }, - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-isob-east-1", - }: endpoint{}, - }, - }, "elasticache": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -30507,28 +29659,6 @@ var awsisobPartition = partition{ }: endpoint{}, }, }, - "elasticfilesystem": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "fips-us-isob-east-1", - }: endpoint{ - Hostname: "elasticfilesystem-fips.us-isob-east-1.sc2s.sgov.gov", - CredentialScope: credentialScope{ - Region: "us-isob-east-1", - }, - Deprecated: boxedTrue, - }, - endpointKey{ - Region: "us-isob-east-1", - }: endpoint{}, - endpointKey{ - Region: "us-isob-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "elasticfilesystem-fips.us-isob-east-1.sc2s.sgov.gov", - }, - }, - }, "elasticloadbalancing": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -30653,13 +29783,6 @@ var awsisobPartition = partition{ }: endpoint{}, }, }, - "ram": service{ - Endpoints: serviceEndpoints{ - endpointKey{ - Region: "us-isob-east-1", - }: endpoint{}, - }, - }, "rds": service{ Endpoints: serviceEndpoints{ endpointKey{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go index 9556332b65e..e819ab6c0e8 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -330,9 +330,6 @@ func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) { // WithSetRequestHeaders updates the operation request's HTTP header to contain // the header key value pairs provided. If the header key already exists in the // request's HTTP header set, the existing value(s) will be replaced. -// -// Header keys added will be added as canonical format with title casing -// applied via http.Header.Set method. func WithSetRequestHeaders(h map[string]string) Option { return withRequestHeader(h).SetRequestHeaders } @@ -341,6 +338,6 @@ type withRequestHeader map[string]string func (h withRequestHeader) SetRequestHeaders(r *Request) { for k, v := range h { - r.HTTPRequest.Header.Set(k, v) + r.HTTPRequest.Header[k] = []string{v} } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 47386c4c985..c771b8c7cd9 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.44.23" +const SDKVersion = "1.43.31" diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index f1a7bfdd47b..718409b5498 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -1279,12 +1279,6 @@ func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request. // and Comparing the Amazon Web Services STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) // in the IAM User Guide. // -// No permissions are required for users to perform this operation. The purpose -// of the sts:GetSessionToken operation is to authenticate the user using MFA. -// You cannot use policies to control authentication operations. For more information, -// see Permissions for GetSessionToken (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getsessiontoken.html) -// in the IAM User Guide. -// // Session Duration // // The GetSessionToken operation must be called by using the long-term Amazon diff --git a/vendor/github.com/cenkalti/backoff/v4/.gitignore b/vendor/github.com/cenkalti/backoff/v4/.gitignore new file mode 100644 index 00000000000..50d95c548b6 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe + +# IDEs +.idea/ diff --git a/vendor/github.com/cenkalti/backoff/v4/LICENSE b/vendor/github.com/cenkalti/backoff/v4/LICENSE new file mode 100644 index 00000000000..89b81799655 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cenkalti/backoff/v4/README.md b/vendor/github.com/cenkalti/backoff/v4/README.md new file mode 100644 index 00000000000..16abdfc084f --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/README.md @@ -0,0 +1,32 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +Import path is `github.com/cenkalti/backoff/v4`. Please note the version part at the end. + +Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation. + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4 +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png +[travis]: https://travis-ci.org/cenkalti/backoff +[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master +[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master +[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master + +[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[advanced example]: https://pkg.go.dev/github.com/cenkalti/backoff/v4?tab=doc#pkg-examples diff --git a/vendor/github.com/cenkalti/backoff/v4/backoff.go b/vendor/github.com/cenkalti/backoff/v4/backoff.go new file mode 100644 index 00000000000..3676ee405d8 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // or backoff. Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/v4/context.go b/vendor/github.com/cenkalti/backoff/v4/context.go new file mode 100644 index 00000000000..48482330eb7 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/context.go @@ -0,0 +1,62 @@ +package backoff + +import ( + "context" + "time" +) + +// BackOffContext is a backoff policy that stops retrying after the context +// is canceled. +type BackOffContext interface { // nolint: golint + BackOff + Context() context.Context +} + +type backOffContext struct { + BackOff + ctx context.Context +} + +// WithContext returns a BackOffContext with context ctx +// +// ctx must not be nil +func WithContext(b BackOff, ctx context.Context) BackOffContext { // nolint: golint + if ctx == nil { + panic("nil context") + } + + if b, ok := b.(*backOffContext); ok { + return &backOffContext{ + BackOff: b.BackOff, + ctx: ctx, + } + } + + return &backOffContext{ + BackOff: b, + ctx: ctx, + } +} + +func getContext(b BackOff) context.Context { + if cb, ok := b.(BackOffContext); ok { + return cb.Context() + } + if tb, ok := b.(*backOffTries); ok { + return getContext(tb.delegate) + } + return context.Background() +} + +func (b *backOffContext) Context() context.Context { + return b.ctx +} + +func (b *backOffContext) NextBackOff() time.Duration { + select { + case <-b.ctx.Done(): + return Stop + default: + return b.BackOff.NextBackOff() + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/exponential.go b/vendor/github.com/cenkalti/backoff/v4/exponential.go new file mode 100644 index 00000000000..2c56c1e7189 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/exponential.go @@ -0,0 +1,161 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. + +The elapsed time can be reset by calling Reset(). + +Example: Given the following default arguments, for 10 tries the sequence will be, +and assuming we go over the MaxElapsedTime on the 10th try: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff returns Stop. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Stop time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + b := &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Stop: Stop, + Clock: SystemClock, + } + b.Reset() + return b +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +// Reset must be called before using b. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next backoff interval using the formula: +// Randomized interval = RetryInterval * (1 ± RandomizationFactor) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + elapsed := b.GetElapsedTime() + next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) + b.incrementCurrentInterval() + if b.MaxElapsedTime != 0 && elapsed+next > b.MaxElapsedTime { + return b.Stop + } + return next +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). It is +// safe to call even while the backoff policy is used by a running +// ticker. +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + if randomizationFactor == 0 { + return currentInterval // make sure no randomness is used when randomizationFactor is 0. + } + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/v4/retry.go b/vendor/github.com/cenkalti/backoff/v4/retry.go new file mode 100644 index 00000000000..b9c0c51cd75 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/retry.go @@ -0,0 +1,146 @@ +package backoff + +import ( + "errors" + "time" +) + +// An OperationWithData is executing by RetryWithData() or RetryNotifyWithData(). +// The operation will be retried using a backoff policy if it returns an error. +type OperationWithData[T any] func() (T, error) + +// An Operation is executing by Retry() or RetryNotify(). +// The operation will be retried using a backoff policy if it returns an error. +type Operation func() error + +func (o Operation) withEmptyData() OperationWithData[struct{}] { + return func() (struct{}, error) { + return struct{}{}, o() + } +} + +// Notify is a notify-on-error function. It receives an operation error and +// backoff delay if the operation failed (with an error). +// +// NOTE that if the backoff policy stated to stop retrying, +// the notify function isn't called. +type Notify func(error, time.Duration) + +// Retry the operation o until it does not return error or BackOff stops. +// o is guaranteed to be run at least once. +// +// If o returns a *PermanentError, the operation is not retried, and the +// wrapped error is returned. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +func Retry(o Operation, b BackOff) error { + return RetryNotify(o, b, nil) +} + +// RetryWithData is like Retry but returns data in the response too. +func RetryWithData[T any](o OperationWithData[T], b BackOff) (T, error) { + return RetryNotifyWithData(o, b, nil) +} + +// RetryNotify calls notify function with the error and wait duration +// for each failed attempt before sleep. +func RetryNotify(operation Operation, b BackOff, notify Notify) error { + return RetryNotifyWithTimer(operation, b, notify, nil) +} + +// RetryNotifyWithData is like RetryNotify but returns data in the response too. +func RetryNotifyWithData[T any](operation OperationWithData[T], b BackOff, notify Notify) (T, error) { + return doRetryNotify(operation, b, notify, nil) +} + +// RetryNotifyWithTimer calls notify function with the error and wait duration using the given Timer +// for each failed attempt before sleep. +// A default timer that uses system timer is used when nil is passed. +func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error { + _, err := doRetryNotify(operation.withEmptyData(), b, notify, t) + return err +} + +// RetryNotifyWithTimerAndData is like RetryNotifyWithTimer but returns data in the response too. +func RetryNotifyWithTimerAndData[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) { + return doRetryNotify(operation, b, notify, t) +} + +func doRetryNotify[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) { + var ( + err error + next time.Duration + res T + ) + if t == nil { + t = &defaultTimer{} + } + + defer func() { + t.Stop() + }() + + ctx := getContext(b) + + b.Reset() + for { + res, err = operation() + if err == nil { + return res, nil + } + + var permanent *PermanentError + if errors.As(err, &permanent) { + return res, permanent.Err + } + + if next = b.NextBackOff(); next == Stop { + if cerr := ctx.Err(); cerr != nil { + return res, cerr + } + + return res, err + } + + if notify != nil { + notify(err, next) + } + + t.Start(next) + + select { + case <-ctx.Done(): + return res, ctx.Err() + case <-t.C(): + } + } +} + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +func (e *PermanentError) Unwrap() error { + return e.Err +} + +func (e *PermanentError) Is(target error) bool { + _, ok := target.(*PermanentError) + return ok +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) error { + if err == nil { + return nil + } + return &PermanentError{ + Err: err, + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/ticker.go b/vendor/github.com/cenkalti/backoff/v4/ticker.go new file mode 100644 index 00000000000..df9d68bce52 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/ticker.go @@ -0,0 +1,97 @@ +package backoff + +import ( + "context" + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOff + ctx context.Context + timer Timer + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + return NewTickerWithTimer(b, &defaultTimer{}) +} + +// NewTickerWithTimer returns a new Ticker with a custom timer. +// A default timer that uses system timer is used when nil is passed. +func NewTickerWithTimer(b BackOff, timer Timer) *Ticker { + if timer == nil { + timer = &defaultTimer{} + } + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: b, + ctx: getContext(b), + timer: timer, + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + case <-t.ctx.Done(): + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + t.timer.Start(next) + return t.timer.C() +} diff --git a/vendor/github.com/cenkalti/backoff/v4/timer.go b/vendor/github.com/cenkalti/backoff/v4/timer.go new file mode 100644 index 00000000000..8120d0213c5 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/timer.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +type Timer interface { + Start(duration time.Duration) + Stop() + C() <-chan time.Time +} + +// defaultTimer implements Timer interface using time.Timer +type defaultTimer struct { + timer *time.Timer +} + +// C returns the timers channel which receives the current time when the timer fires. +func (t *defaultTimer) C() <-chan time.Time { + return t.timer.C +} + +// Start starts the timer to fire after the given duration +func (t *defaultTimer) Start(duration time.Duration) { + if t.timer == nil { + t.timer = time.NewTimer(duration) + } else { + t.timer.Reset(duration) + } +} + +// Stop is called when the timer is not used anymore and resources may be freed. +func (t *defaultTimer) Stop() { + if t.timer != nil { + t.timer.Stop() + } +} diff --git a/vendor/github.com/cenkalti/backoff/v4/tries.go b/vendor/github.com/cenkalti/backoff/v4/tries.go new file mode 100644 index 00000000000..28d58ca37c6 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v4/tries.go @@ -0,0 +1,38 @@ +package backoff + +import "time" + +/* +WithMaxRetries creates a wrapper around another BackOff, which will +return Stop if NextBackOff() has been called too many times since +the last time Reset() was called + +Note: Implementation is not thread-safe. +*/ +func WithMaxRetries(b BackOff, max uint64) BackOff { + return &backOffTries{delegate: b, maxTries: max} +} + +type backOffTries struct { + delegate BackOff + maxTries uint64 + numTries uint64 +} + +func (b *backOffTries) NextBackOff() time.Duration { + if b.maxTries == 0 { + return Stop + } + if b.maxTries > 0 { + if b.maxTries <= b.numTries { + return Stop + } + b.numTries++ + } + return b.delegate.NextBackOff() +} + +func (b *backOffTries) Reset() { + b.numTries = 0 + b.delegate.Reset() +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go index 875b06813e4..9cacb32acb9 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/agent/common/v1/common.proto // NOTE: This proto is experimental and is subject to change at this point. @@ -24,10 +24,9 @@ package v1 import ( - proto "github.com/golang/protobuf/proto" - timestamp "github.com/golang/protobuf/ptypes/timestamp" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -39,10 +38,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type LibraryInfo_Language int32 const ( @@ -207,7 +202,7 @@ type ProcessIdentifier struct { // Process id. Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` // Start time of this ProcessIdentifier. Represented in epoch time. - StartTimestamp *timestamp.Timestamp `protobuf:"bytes,3,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + StartTimestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` } func (x *ProcessIdentifier) Reset() { @@ -256,7 +251,7 @@ func (x *ProcessIdentifier) GetPid() uint32 { return 0 } -func (x *ProcessIdentifier) GetStartTimestamp() *timestamp.Timestamp { +func (x *ProcessIdentifier) GetStartTimestamp() *timestamppb.Timestamp { if x != nil { return x.StartTimestamp } @@ -447,7 +442,7 @@ var file_opencensus_proto_agent_common_v1_common_proto_rawDesc = []byte{ 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x57, 0x45, 0x42, 0x5f, 0x4a, 0x53, 0x10, 0x0a, 0x22, 0x21, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x42, 0xa2, 0x01, 0x0a, 0x23, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, + 0x65, 0x42, 0xa6, 0x01, 0x0a, 0x23, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, @@ -455,9 +450,10 @@ var file_opencensus_proto_agent_common_v1_common_proto_rawDesc = []byte{ 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2f, 0x76, 0x31, 0xea, 0x02, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x76, 0x31, 0xea, 0x02, 0x24, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, + 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x3a, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -475,13 +471,13 @@ func file_opencensus_proto_agent_common_v1_common_proto_rawDescGZIP() []byte { var file_opencensus_proto_agent_common_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_opencensus_proto_agent_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_opencensus_proto_agent_common_v1_common_proto_goTypes = []interface{}{ - (LibraryInfo_Language)(0), // 0: opencensus.proto.agent.common.v1.LibraryInfo.Language - (*Node)(nil), // 1: opencensus.proto.agent.common.v1.Node - (*ProcessIdentifier)(nil), // 2: opencensus.proto.agent.common.v1.ProcessIdentifier - (*LibraryInfo)(nil), // 3: opencensus.proto.agent.common.v1.LibraryInfo - (*ServiceInfo)(nil), // 4: opencensus.proto.agent.common.v1.ServiceInfo - nil, // 5: opencensus.proto.agent.common.v1.Node.AttributesEntry - (*timestamp.Timestamp)(nil), // 6: google.protobuf.Timestamp + (LibraryInfo_Language)(0), // 0: opencensus.proto.agent.common.v1.LibraryInfo.Language + (*Node)(nil), // 1: opencensus.proto.agent.common.v1.Node + (*ProcessIdentifier)(nil), // 2: opencensus.proto.agent.common.v1.ProcessIdentifier + (*LibraryInfo)(nil), // 3: opencensus.proto.agent.common.v1.LibraryInfo + (*ServiceInfo)(nil), // 4: opencensus.proto.agent.common.v1.ServiceInfo + nil, // 5: opencensus.proto.agent.common.v1.Node.AttributesEntry + (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp } var file_opencensus_proto_agent_common_v1_common_proto_depIdxs = []int32{ 2, // 0: opencensus.proto.agent.common.v1.Node.identifier:type_name -> opencensus.proto.agent.common.v1.ProcessIdentifier diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go index bfb4389384c..4f9faffd9cc 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go @@ -14,17 +14,20 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/agent/metrics/v1/metrics_service.proto package v1 import ( + context "context" v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1" v11 "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" - proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -38,10 +41,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type ExportMetricsServiceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -195,7 +194,7 @@ var file_opencensus_proto_agent_metrics_v1_metrics_service_proto_rawDesc = []byt 0x6f, 0x74, 0x6f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0xad, 0x01, 0x0a, 0x24, 0x69, 0x6f, 0x2e, 0x6f, + 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0xb1, 0x01, 0x0a, 0x24, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, @@ -204,9 +203,10 @@ var file_opencensus_proto_agent_metrics_v1_metrics_service_proto_rawDesc = []byt 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x2f, 0x76, 0x31, 0xea, 0x02, 0x21, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x76, 0x31, 0xea, 0x02, 0x25, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, + 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x3a, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -292,3 +292,119 @@ func file_opencensus_proto_agent_metrics_v1_metrics_service_proto_init() { file_opencensus_proto_agent_metrics_v1_metrics_service_proto_goTypes = nil file_opencensus_proto_agent_metrics_v1_metrics_service_proto_depIdxs = nil } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MetricsServiceClient is the client API for MetricsService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MetricsServiceClient interface { + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) +} + +type metricsServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMetricsServiceClient(cc grpc.ClientConnInterface) MetricsServiceClient { + return &metricsServiceClient{cc} +} + +func (c *metricsServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) { + stream, err := c.cc.NewStream(ctx, &_MetricsService_serviceDesc.Streams[0], "/opencensus.proto.agent.metrics.v1.MetricsService/Export", opts...) + if err != nil { + return nil, err + } + x := &metricsServiceExportClient{stream} + return x, nil +} + +type MetricsService_ExportClient interface { + Send(*ExportMetricsServiceRequest) error + Recv() (*ExportMetricsServiceResponse, error) + grpc.ClientStream +} + +type metricsServiceExportClient struct { + grpc.ClientStream +} + +func (x *metricsServiceExportClient) Send(m *ExportMetricsServiceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *metricsServiceExportClient) Recv() (*ExportMetricsServiceResponse, error) { + m := new(ExportMetricsServiceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// MetricsServiceServer is the server API for MetricsService service. +type MetricsServiceServer interface { + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(MetricsService_ExportServer) error +} + +// UnimplementedMetricsServiceServer can be embedded to have forward compatible implementations. +type UnimplementedMetricsServiceServer struct { +} + +func (*UnimplementedMetricsServiceServer) Export(MetricsService_ExportServer) error { + return status.Errorf(codes.Unimplemented, "method Export not implemented") +} + +func RegisterMetricsServiceServer(s *grpc.Server, srv MetricsServiceServer) { + s.RegisterService(&_MetricsService_serviceDesc, srv) +} + +func _MetricsService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(MetricsServiceServer).Export(&metricsServiceExportServer{stream}) +} + +type MetricsService_ExportServer interface { + Send(*ExportMetricsServiceResponse) error + Recv() (*ExportMetricsServiceRequest, error) + grpc.ServerStream +} + +type metricsServiceExportServer struct { + grpc.ServerStream +} + +func (x *metricsServiceExportServer) Send(m *ExportMetricsServiceResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *metricsServiceExportServer) Recv() (*ExportMetricsServiceRequest, error) { + m := new(ExportMetricsServiceRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _MetricsService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "opencensus.proto.agent.metrics.v1.MetricsService", + HandlerType: (*MetricsServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Export", + Handler: _MetricsService_Export_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "opencensus/proto/agent/metrics/v1/metrics_service.proto", +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go index 722e8efde42..3cc9bae4b93 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go @@ -13,14 +13,14 @@ import ( "io" "net/http" - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) // Suppress "imported and not used" errors @@ -29,7 +29,7 @@ var _ io.Reader var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage +var _ = metadata.Join func request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client MetricsServiceClient, req *http.Request, pathParams map[string]string) (MetricsService_ExportClient, runtime.ServerMetadata, error) { var metadata runtime.ServerMetadata @@ -55,15 +55,6 @@ func request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Mars } return nil } - if err := handleSend(); err != nil { - if cerr := stream.CloseSend(); cerr != nil { - grpclog.Infof("Failed to terminate client stream: %v", cerr) - } - if err == io.EOF { - return stream, metadata, nil - } - return nil, metadata, err - } go func() { for { if err := handleSend(); err != nil { @@ -86,6 +77,7 @@ func request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Mars // RegisterMetricsServiceHandlerServer registers the http handlers for service MetricsService to "mux". // UnaryRPC :call MetricsServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMetricsServiceHandlerFromEndpoint instead. func RegisterMetricsServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MetricsServiceServer) error { mux.Handle("POST", pattern_MetricsService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { @@ -140,7 +132,7 @@ func RegisterMetricsServiceHandlerClient(ctx context.Context, mux *runtime.Serve ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/opencensus.proto.agent.metrics.v1.MetricsService/Export", runtime.WithHTTPPathPattern("/v1/metrics")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -160,7 +152,7 @@ func RegisterMetricsServiceHandlerClient(ctx context.Context, mux *runtime.Serve } var ( - pattern_MetricsService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "metrics"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_MetricsService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "metrics"}, "")) ) var ( diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service_grpc.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service_grpc.pb.go deleted file mode 100644 index 0a600256e99..00000000000 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service_grpc.pb.go +++ /dev/null @@ -1,126 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion6 - -// MetricsServiceClient is the client API for MetricsService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type MetricsServiceClient interface { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) -} - -type metricsServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewMetricsServiceClient(cc grpc.ClientConnInterface) MetricsServiceClient { - return &metricsServiceClient{cc} -} - -func (c *metricsServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) { - stream, err := c.cc.NewStream(ctx, &_MetricsService_serviceDesc.Streams[0], "/opencensus.proto.agent.metrics.v1.MetricsService/Export", opts...) - if err != nil { - return nil, err - } - x := &metricsServiceExportClient{stream} - return x, nil -} - -type MetricsService_ExportClient interface { - Send(*ExportMetricsServiceRequest) error - Recv() (*ExportMetricsServiceResponse, error) - grpc.ClientStream -} - -type metricsServiceExportClient struct { - grpc.ClientStream -} - -func (x *metricsServiceExportClient) Send(m *ExportMetricsServiceRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *metricsServiceExportClient) Recv() (*ExportMetricsServiceResponse, error) { - m := new(ExportMetricsServiceResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// MetricsServiceServer is the server API for MetricsService service. -// All implementations must embed UnimplementedMetricsServiceServer -// for forward compatibility -type MetricsServiceServer interface { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(MetricsService_ExportServer) error - mustEmbedUnimplementedMetricsServiceServer() -} - -// UnimplementedMetricsServiceServer must be embedded to have forward compatible implementations. -type UnimplementedMetricsServiceServer struct { -} - -func (*UnimplementedMetricsServiceServer) Export(MetricsService_ExportServer) error { - return status.Errorf(codes.Unimplemented, "method Export not implemented") -} -func (*UnimplementedMetricsServiceServer) mustEmbedUnimplementedMetricsServiceServer() {} - -func RegisterMetricsServiceServer(s *grpc.Server, srv MetricsServiceServer) { - s.RegisterService(&_MetricsService_serviceDesc, srv) -} - -func _MetricsService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(MetricsServiceServer).Export(&metricsServiceExportServer{stream}) -} - -type MetricsService_ExportServer interface { - Send(*ExportMetricsServiceResponse) error - Recv() (*ExportMetricsServiceRequest, error) - grpc.ServerStream -} - -type metricsServiceExportServer struct { - grpc.ServerStream -} - -func (x *metricsServiceExportServer) Send(m *ExportMetricsServiceResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *metricsServiceExportServer) Recv() (*ExportMetricsServiceRequest, error) { - m := new(ExportMetricsServiceRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _MetricsService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "opencensus.proto.agent.metrics.v1.MetricsService", - HandlerType: (*MetricsServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "Export", - Handler: _MetricsService_Export_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "opencensus/proto/agent/metrics/v1/metrics_service.proto", -} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go index 0eed170b80c..c713bfb4f7e 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/agent/trace/v1/trace_service.proto // NOTE: This proto is experimental and is subject to change at this point. @@ -24,10 +24,13 @@ package v1 import ( + context "context" v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1" v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" v11 "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" - proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -41,10 +44,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type CurrentLibraryConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -342,7 +341,7 @@ var file_opencensus_proto_agent_trace_v1_trace_service_proto_rawDesc = []byte{ 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0xa5, 0x01, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0xa9, 0x01, 0x0a, 0x22, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, @@ -351,9 +350,10 @@ var file_opencensus_proto_agent_trace_v1_trace_service_proto_rawDesc = []byte{ 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x2f, 0x76, 0x31, 0xea, 0x02, 0x1f, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x76, 0x31, 0xea, 0x02, 0x23, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, + 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x3a, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -472,3 +472,193 @@ func file_opencensus_proto_agent_trace_v1_trace_service_proto_init() { file_opencensus_proto_agent_trace_v1_trace_service_proto_goTypes = nil file_opencensus_proto_agent_trace_v1_trace_service_proto_depIdxs = nil } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// TraceServiceClient is the client API for TraceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type TraceServiceClient interface { + // After initialization, this RPC must be kept alive for the entire life of + // the application. The agent pushes configs down to applications via a + // stream. + Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) +} + +type traceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewTraceServiceClient(cc grpc.ClientConnInterface) TraceServiceClient { + return &traceServiceClient{cc} +} + +func (c *traceServiceClient) Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) { + stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[0], "/opencensus.proto.agent.trace.v1.TraceService/Config", opts...) + if err != nil { + return nil, err + } + x := &traceServiceConfigClient{stream} + return x, nil +} + +type TraceService_ConfigClient interface { + Send(*CurrentLibraryConfig) error + Recv() (*UpdatedLibraryConfig, error) + grpc.ClientStream +} + +type traceServiceConfigClient struct { + grpc.ClientStream +} + +func (x *traceServiceConfigClient) Send(m *CurrentLibraryConfig) error { + return x.ClientStream.SendMsg(m) +} + +func (x *traceServiceConfigClient) Recv() (*UpdatedLibraryConfig, error) { + m := new(UpdatedLibraryConfig) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *traceServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) { + stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[1], "/opencensus.proto.agent.trace.v1.TraceService/Export", opts...) + if err != nil { + return nil, err + } + x := &traceServiceExportClient{stream} + return x, nil +} + +type TraceService_ExportClient interface { + Send(*ExportTraceServiceRequest) error + Recv() (*ExportTraceServiceResponse, error) + grpc.ClientStream +} + +type traceServiceExportClient struct { + grpc.ClientStream +} + +func (x *traceServiceExportClient) Send(m *ExportTraceServiceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *traceServiceExportClient) Recv() (*ExportTraceServiceResponse, error) { + m := new(ExportTraceServiceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// TraceServiceServer is the server API for TraceService service. +type TraceServiceServer interface { + // After initialization, this RPC must be kept alive for the entire life of + // the application. The agent pushes configs down to applications via a + // stream. + Config(TraceService_ConfigServer) error + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(TraceService_ExportServer) error +} + +// UnimplementedTraceServiceServer can be embedded to have forward compatible implementations. +type UnimplementedTraceServiceServer struct { +} + +func (*UnimplementedTraceServiceServer) Config(TraceService_ConfigServer) error { + return status.Errorf(codes.Unimplemented, "method Config not implemented") +} +func (*UnimplementedTraceServiceServer) Export(TraceService_ExportServer) error { + return status.Errorf(codes.Unimplemented, "method Export not implemented") +} + +func RegisterTraceServiceServer(s *grpc.Server, srv TraceServiceServer) { + s.RegisterService(&_TraceService_serviceDesc, srv) +} + +func _TraceService_Config_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TraceServiceServer).Config(&traceServiceConfigServer{stream}) +} + +type TraceService_ConfigServer interface { + Send(*UpdatedLibraryConfig) error + Recv() (*CurrentLibraryConfig, error) + grpc.ServerStream +} + +type traceServiceConfigServer struct { + grpc.ServerStream +} + +func (x *traceServiceConfigServer) Send(m *UpdatedLibraryConfig) error { + return x.ServerStream.SendMsg(m) +} + +func (x *traceServiceConfigServer) Recv() (*CurrentLibraryConfig, error) { + m := new(CurrentLibraryConfig) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _TraceService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TraceServiceServer).Export(&traceServiceExportServer{stream}) +} + +type TraceService_ExportServer interface { + Send(*ExportTraceServiceResponse) error + Recv() (*ExportTraceServiceRequest, error) + grpc.ServerStream +} + +type traceServiceExportServer struct { + grpc.ServerStream +} + +func (x *traceServiceExportServer) Send(m *ExportTraceServiceResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *traceServiceExportServer) Recv() (*ExportTraceServiceRequest, error) { + m := new(ExportTraceServiceRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _TraceService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "opencensus.proto.agent.trace.v1.TraceService", + HandlerType: (*TraceServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Config", + Handler: _TraceService_Config_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "Export", + Handler: _TraceService_Export_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "opencensus/proto/agent/trace/v1/trace_service.proto", +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go index 4733c404d0c..7808e9fb83b 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go @@ -13,14 +13,14 @@ import ( "io" "net/http" - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) // Suppress "imported and not used" errors @@ -29,7 +29,7 @@ var _ io.Reader var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage +var _ = metadata.Join func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client TraceServiceClient, req *http.Request, pathParams map[string]string) (TraceService_ExportClient, runtime.ServerMetadata, error) { var metadata runtime.ServerMetadata @@ -55,15 +55,6 @@ func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marsha } return nil } - if err := handleSend(); err != nil { - if cerr := stream.CloseSend(); cerr != nil { - grpclog.Infof("Failed to terminate client stream: %v", cerr) - } - if err == io.EOF { - return stream, metadata, nil - } - return nil, metadata, err - } go func() { for { if err := handleSend(); err != nil { @@ -86,6 +77,7 @@ func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marsha // RegisterTraceServiceHandlerServer registers the http handlers for service TraceService to "mux". // UnaryRPC :call TraceServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTraceServiceHandlerFromEndpoint instead. func RegisterTraceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TraceServiceServer) error { mux.Handle("POST", pattern_TraceService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { @@ -140,7 +132,7 @@ func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/opencensus.proto.agent.trace.v1.TraceService/Export", runtime.WithHTTPPathPattern("/v1/trace")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -160,7 +152,7 @@ func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu } var ( - pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "trace"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "trace"}, "")) ) var ( diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service_grpc.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service_grpc.pb.go deleted file mode 100644 index 90bda0aaa4a..00000000000 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service_grpc.pb.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion6 - -// TraceServiceClient is the client API for TraceService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type TraceServiceClient interface { - // After initialization, this RPC must be kept alive for the entire life of - // the application. The agent pushes configs down to applications via a - // stream. - Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) -} - -type traceServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewTraceServiceClient(cc grpc.ClientConnInterface) TraceServiceClient { - return &traceServiceClient{cc} -} - -func (c *traceServiceClient) Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) { - stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[0], "/opencensus.proto.agent.trace.v1.TraceService/Config", opts...) - if err != nil { - return nil, err - } - x := &traceServiceConfigClient{stream} - return x, nil -} - -type TraceService_ConfigClient interface { - Send(*CurrentLibraryConfig) error - Recv() (*UpdatedLibraryConfig, error) - grpc.ClientStream -} - -type traceServiceConfigClient struct { - grpc.ClientStream -} - -func (x *traceServiceConfigClient) Send(m *CurrentLibraryConfig) error { - return x.ClientStream.SendMsg(m) -} - -func (x *traceServiceConfigClient) Recv() (*UpdatedLibraryConfig, error) { - m := new(UpdatedLibraryConfig) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *traceServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) { - stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[1], "/opencensus.proto.agent.trace.v1.TraceService/Export", opts...) - if err != nil { - return nil, err - } - x := &traceServiceExportClient{stream} - return x, nil -} - -type TraceService_ExportClient interface { - Send(*ExportTraceServiceRequest) error - Recv() (*ExportTraceServiceResponse, error) - grpc.ClientStream -} - -type traceServiceExportClient struct { - grpc.ClientStream -} - -func (x *traceServiceExportClient) Send(m *ExportTraceServiceRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *traceServiceExportClient) Recv() (*ExportTraceServiceResponse, error) { - m := new(ExportTraceServiceResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// TraceServiceServer is the server API for TraceService service. -// All implementations must embed UnimplementedTraceServiceServer -// for forward compatibility -type TraceServiceServer interface { - // After initialization, this RPC must be kept alive for the entire life of - // the application. The agent pushes configs down to applications via a - // stream. - Config(TraceService_ConfigServer) error - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(TraceService_ExportServer) error - mustEmbedUnimplementedTraceServiceServer() -} - -// UnimplementedTraceServiceServer must be embedded to have forward compatible implementations. -type UnimplementedTraceServiceServer struct { -} - -func (*UnimplementedTraceServiceServer) Config(TraceService_ConfigServer) error { - return status.Errorf(codes.Unimplemented, "method Config not implemented") -} -func (*UnimplementedTraceServiceServer) Export(TraceService_ExportServer) error { - return status.Errorf(codes.Unimplemented, "method Export not implemented") -} -func (*UnimplementedTraceServiceServer) mustEmbedUnimplementedTraceServiceServer() {} - -func RegisterTraceServiceServer(s *grpc.Server, srv TraceServiceServer) { - s.RegisterService(&_TraceService_serviceDesc, srv) -} - -func _TraceService_Config_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TraceServiceServer).Config(&traceServiceConfigServer{stream}) -} - -type TraceService_ConfigServer interface { - Send(*UpdatedLibraryConfig) error - Recv() (*CurrentLibraryConfig, error) - grpc.ServerStream -} - -type traceServiceConfigServer struct { - grpc.ServerStream -} - -func (x *traceServiceConfigServer) Send(m *UpdatedLibraryConfig) error { - return x.ServerStream.SendMsg(m) -} - -func (x *traceServiceConfigServer) Recv() (*CurrentLibraryConfig, error) { - m := new(CurrentLibraryConfig) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func _TraceService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TraceServiceServer).Export(&traceServiceExportServer{stream}) -} - -type TraceService_ExportServer interface { - Send(*ExportTraceServiceResponse) error - Recv() (*ExportTraceServiceRequest, error) - grpc.ServerStream -} - -type traceServiceExportServer struct { - grpc.ServerStream -} - -func (x *traceServiceExportServer) Send(m *ExportTraceServiceResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *traceServiceExportServer) Recv() (*ExportTraceServiceRequest, error) { - m := new(ExportTraceServiceRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _TraceService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "opencensus.proto.agent.trace.v1.TraceService", - HandlerType: (*TraceServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "Config", - Handler: _TraceService_Config_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "Export", - Handler: _TraceService_Export_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "opencensus/proto/agent/trace/v1/trace_service.proto", -} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go index 30f758322b1..0cac88b2a54 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go @@ -19,19 +19,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/metrics/v1/metrics.proto package v1 import ( v1 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" - proto "github.com/golang/protobuf/proto" - timestamp "github.com/golang/protobuf/ptypes/timestamp" - wrappers "github.com/golang/protobuf/ptypes/wrappers" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" reflect "reflect" sync "sync" ) @@ -43,10 +42,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // The kind of metric. It describes how the data is reported. // // A gauge is an instantaneous measurement of a value. @@ -364,7 +359,7 @@ type TimeSeries struct { // was reset to zero. Exclusive. The cumulative value is over the time interval // (start_timestamp, timestamp]. If not specified, the backend can use the // previous recorded value. - StartTimestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + StartTimestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` // The set of label values that uniquely identify this timeseries. Applies to // all points. The order of label values must match that of label keys in the // metric descriptor. @@ -406,7 +401,7 @@ func (*TimeSeries) Descriptor() ([]byte, []int) { return file_opencensus_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{3} } -func (x *TimeSeries) GetStartTimestamp() *timestamp.Timestamp { +func (x *TimeSeries) GetStartTimestamp() *timestamppb.Timestamp { if x != nil { return x.StartTimestamp } @@ -493,7 +488,7 @@ type Point struct { // The moment when this point was recorded. Inclusive. // If not specified, the timestamp will be decided by the backend. - Timestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // The actual point value. // // Types that are assignable to Value: @@ -536,7 +531,7 @@ func (*Point) Descriptor() ([]byte, []int) { return file_opencensus_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{5} } -func (x *Point) GetTimestamp() *timestamp.Timestamp { +func (x *Point) GetTimestamp() *timestamppb.Timestamp { if x != nil { return x.Timestamp } @@ -721,11 +716,11 @@ type SummaryValue struct { // The total number of recorded values since start_time. Optional since // some systems don't expose this. - Count *wrappers.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` + Count *wrapperspb.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` // The total sum of recorded values since start_time. Optional since some // systems don't expose this. If count is zero then this field must be zero. // This field must be unset if the sum is not available. - Sum *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` + Sum *wrapperspb.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` // Values calculated over an arbitrary time window. Snapshot *SummaryValue_Snapshot `protobuf:"bytes,3,opt,name=snapshot,proto3" json:"snapshot,omitempty"` } @@ -762,14 +757,14 @@ func (*SummaryValue) Descriptor() ([]byte, []int) { return file_opencensus_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{7} } -func (x *SummaryValue) GetCount() *wrappers.Int64Value { +func (x *SummaryValue) GetCount() *wrapperspb.Int64Value { if x != nil { return x.Count } return nil } -func (x *SummaryValue) GetSum() *wrappers.DoubleValue { +func (x *SummaryValue) GetSum() *wrapperspb.DoubleValue { if x != nil { return x.Sum } @@ -926,7 +921,7 @@ type DistributionValue_Exemplar struct { // belongs to. Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` // The observation (sampling) time of the above value. - Timestamp *timestamp.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Contextual information about the example value. Attachments map[string]string `protobuf:"bytes,3,rep,name=attachments,proto3" json:"attachments,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -970,7 +965,7 @@ func (x *DistributionValue_Exemplar) GetValue() float64 { return 0 } -func (x *DistributionValue_Exemplar) GetTimestamp() *timestamp.Timestamp { +func (x *DistributionValue_Exemplar) GetTimestamp() *timestamppb.Timestamp { if x != nil { return x.Timestamp } @@ -1048,11 +1043,11 @@ type SummaryValue_Snapshot struct { // The number of values in the snapshot. Optional since some systems don't // expose this. - Count *wrappers.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` + Count *wrapperspb.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` // The sum of values in the snapshot. Optional since some systems don't // expose this. If count is zero then this field must be zero or not set // (if not supported). - Sum *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` + Sum *wrapperspb.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` // A list of values at different percentiles of the distribution calculated // from the current snapshot. The percentiles must be strictly increasing. PercentileValues []*SummaryValue_Snapshot_ValueAtPercentile `protobuf:"bytes,3,rep,name=percentile_values,json=percentileValues,proto3" json:"percentile_values,omitempty"` @@ -1090,14 +1085,14 @@ func (*SummaryValue_Snapshot) Descriptor() ([]byte, []int) { return file_opencensus_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{7, 0} } -func (x *SummaryValue_Snapshot) GetCount() *wrappers.Int64Value { +func (x *SummaryValue_Snapshot) GetCount() *wrapperspb.Int64Value { if x != nil { return x.Count } return nil } -func (x *SummaryValue_Snapshot) GetSum() *wrappers.DoubleValue { +func (x *SummaryValue_Snapshot) GetSum() *wrapperspb.DoubleValue { if x != nil { return x.Sum } @@ -1351,7 +1346,7 @@ var file_opencensus_proto_metrics_v1_metrics_proto_rawDesc = []byte{ 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x94, 0x01, 0x0a, 0x1e, 0x69, 0x6f, 0x2e, + 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x97, 0x01, 0x0a, 0x1e, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, @@ -1359,9 +1354,9 @@ var file_opencensus_proto_metrics_v1_metrics_proto_rawDesc = []byte{ 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, - 0x31, 0xea, 0x02, 0x1b, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0xea, 0x02, 0x1e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x3a, 0x3a, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1396,9 +1391,9 @@ var file_opencensus_proto_metrics_v1_metrics_proto_goTypes = []interface{}{ (*SummaryValue_Snapshot)(nil), // 14: opencensus.proto.metrics.v1.SummaryValue.Snapshot (*SummaryValue_Snapshot_ValueAtPercentile)(nil), // 15: opencensus.proto.metrics.v1.SummaryValue.Snapshot.ValueAtPercentile (*v1.Resource)(nil), // 16: opencensus.proto.resource.v1.Resource - (*timestamp.Timestamp)(nil), // 17: google.protobuf.Timestamp - (*wrappers.Int64Value)(nil), // 18: google.protobuf.Int64Value - (*wrappers.DoubleValue)(nil), // 19: google.protobuf.DoubleValue + (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp + (*wrapperspb.Int64Value)(nil), // 18: google.protobuf.Int64Value + (*wrapperspb.DoubleValue)(nil), // 19: google.protobuf.DoubleValue } var file_opencensus_proto_metrics_v1_metrics_proto_depIdxs = []int32{ 2, // 0: opencensus.proto.metrics.v1.Metric.metric_descriptor:type_name -> opencensus.proto.metrics.v1.MetricDescriptor diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go index 692746c049f..194dd70dfbd 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/resource/v1/resource.proto package v1 import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -35,10 +34,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Resource information. type Resource struct { state protoimpl.MessageState @@ -115,7 +110,7 @@ var file_opencensus_proto_resource_v1_resource_proto_rawDesc = []byte{ 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x42, 0x98, 0x01, 0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x02, 0x38, 0x01, 0x42, 0x9b, 0x01, 0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, @@ -123,9 +118,9 @@ var file_opencensus_proto_resource_v1_resource_proto_rawDesc = []byte{ 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xea, - 0x02, 0x1c, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x02, 0x1f, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x3a, 0x3a, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go index 66664fe11ee..d35612ca058 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go @@ -14,19 +14,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/trace/v1/trace.proto package v1 import ( v1 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" - proto "github.com/golang/protobuf/proto" - timestamp "github.com/golang/protobuf/ptypes/timestamp" - wrappers "github.com/golang/protobuf/ptypes/wrappers" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" reflect "reflect" sync "sync" ) @@ -38,10 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Type of span. Can be used to specify additional relationships between spans // in addition to a parent/child relationship. type Span_SpanKind int32 @@ -272,7 +267,7 @@ type Span struct { // keep end_time > start_time for consistency. // // This field is required. - StartTime *timestamp.Timestamp `protobuf:"bytes,5,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` // The end time of the span. On the client side, this is the time kept by // the local machine where the span execution ends. On the server side, this // is the time when the server application handler stops running. @@ -282,7 +277,7 @@ type Span struct { // keep end_time > start_time for consistency. // // This field is required. - EndTime *timestamp.Timestamp `protobuf:"bytes,6,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` // A set of attributes on the span. Attributes *Span_Attributes `protobuf:"bytes,7,opt,name=attributes,proto3" json:"attributes,omitempty"` // A stack trace captured at the start of the span. @@ -304,10 +299,10 @@ type Span struct { // to the same process as the current span. This flag is most commonly // used to indicate the need to adjust time as clocks in different // processes may not be synchronized. - SameProcessAsParentSpan *wrappers.BoolValue `protobuf:"bytes,12,opt,name=same_process_as_parent_span,json=sameProcessAsParentSpan,proto3" json:"same_process_as_parent_span,omitempty"` + SameProcessAsParentSpan *wrapperspb.BoolValue `protobuf:"bytes,12,opt,name=same_process_as_parent_span,json=sameProcessAsParentSpan,proto3" json:"same_process_as_parent_span,omitempty"` // An optional number of child spans that were generated while this span // was active. If set, allows an implementation to detect missing child spans. - ChildSpanCount *wrappers.UInt32Value `protobuf:"bytes,13,opt,name=child_span_count,json=childSpanCount,proto3" json:"child_span_count,omitempty"` + ChildSpanCount *wrapperspb.UInt32Value `protobuf:"bytes,13,opt,name=child_span_count,json=childSpanCount,proto3" json:"child_span_count,omitempty"` } func (x *Span) Reset() { @@ -384,14 +379,14 @@ func (x *Span) GetKind() Span_SpanKind { return Span_SPAN_KIND_UNSPECIFIED } -func (x *Span) GetStartTime() *timestamp.Timestamp { +func (x *Span) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } -func (x *Span) GetEndTime() *timestamp.Timestamp { +func (x *Span) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } @@ -440,14 +435,14 @@ func (x *Span) GetResource() *v1.Resource { return nil } -func (x *Span) GetSameProcessAsParentSpan() *wrappers.BoolValue { +func (x *Span) GetSameProcessAsParentSpan() *wrapperspb.BoolValue { if x != nil { return x.SameProcessAsParentSpan } return nil } -func (x *Span) GetChildSpanCount() *wrappers.UInt32Value { +func (x *Span) GetChildSpanCount() *wrapperspb.UInt32Value { if x != nil { return x.ChildSpanCount } @@ -952,7 +947,7 @@ type Span_TimeEvent struct { unknownFields protoimpl.UnknownFields // The time the event occurred. - Time *timestamp.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` // A `TimeEvent` can contain either an `Annotation` object or a // `MessageEvent` object, but not both. // @@ -994,7 +989,7 @@ func (*Span_TimeEvent) Descriptor() ([]byte, []int) { return file_opencensus_proto_trace_v1_trace_proto_rawDescGZIP(), []int{0, 2} } -func (x *Span_TimeEvent) GetTime() *timestamp.Timestamp { +func (x *Span_TimeEvent) GetTime() *timestamppb.Timestamp { if x != nil { return x.Time } @@ -1899,16 +1894,16 @@ var file_opencensus_proto_trace_v1_trace_proto_rawDesc = []byte{ 0x6c, 0x75, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x8c, 0x01, 0x0a, 0x1c, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x8f, 0x01, 0x0a, 0x1c, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x19, 0x4f, 0x70, 0x65, 0x6e, 0x43, - 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x1c, 0x4f, 0x70, 0x65, 0x6e, 0x43, + 0x65, 0x6e, 0x73, 0x75, 0x73, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1947,10 +1942,10 @@ var file_opencensus_proto_trace_v1_trace_proto_goTypes = []interface{}{ (*Span_TimeEvent_MessageEvent)(nil), // 18: opencensus.proto.trace.v1.Span.TimeEvent.MessageEvent (*StackTrace_StackFrame)(nil), // 19: opencensus.proto.trace.v1.StackTrace.StackFrame (*StackTrace_StackFrames)(nil), // 20: opencensus.proto.trace.v1.StackTrace.StackFrames - (*timestamp.Timestamp)(nil), // 21: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp (*v1.Resource)(nil), // 22: opencensus.proto.resource.v1.Resource - (*wrappers.BoolValue)(nil), // 23: google.protobuf.BoolValue - (*wrappers.UInt32Value)(nil), // 24: google.protobuf.UInt32Value + (*wrapperspb.BoolValue)(nil), // 23: google.protobuf.BoolValue + (*wrapperspb.UInt32Value)(nil), // 24: google.protobuf.UInt32Value } var file_opencensus_proto_trace_v1_trace_proto_depIdxs = []int32{ 9, // 0: opencensus.proto.trace.v1.Span.tracestate:type_name -> opencensus.proto.trace.v1.Span.Tracestate diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go index 0c19a4d2c9a..ee62b2e358e 100644 --- a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.12.3 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: opencensus/proto/trace/v1/trace_config.proto package v1 import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -35,10 +34,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // How spans should be sampled: // - Always off // - Always on @@ -432,7 +427,7 @@ var file_opencensus_proto_trace_v1_trace_config_proto_rawDesc = []byte{ 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x4c, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x22, 0x27, 0x0a, 0x13, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x70, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x71, 0x70, 0x73, 0x42, 0x92, 0x01, 0x0a, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x71, 0x70, 0x73, 0x42, 0x95, 0x01, 0x0a, 0x1c, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, @@ -440,9 +435,9 @@ var file_opencensus_proto_trace_v1_trace_config_proto_rawDesc = []byte{ 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x19, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, - 0x75, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x65, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x1c, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x65, 0x6e, 0x73, + 0x75, 0x73, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x54, 0x72, 0x61, 0x63, 0x65, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md index 792b4a60b34..8bf0e5b7815 100644 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ b/vendor/github.com/cespare/xxhash/v2/README.md @@ -3,8 +3,7 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2) [![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml) -xxhash is a Go implementation of the 64-bit -[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a +xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a high-quality hashing algorithm that is much faster than anything in the Go standard library. @@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error) func (*Digest) Sum64() uint64 ``` -This implementation provides a fast pure-Go implementation and an even faster -assembly implementation for amd64. +The package is written with optimized pure Go and also contains even faster +assembly implementations for amd64 and arm64. If desired, the `purego` build tag +opts into using the Go code even on those architectures. + +[xxHash]: http://cyan4973.github.io/xxHash/ ## Compatibility @@ -45,19 +47,20 @@ I recommend using the latest release of Go. Here are some quick benchmarks comparing the pure-Go and assembly implementations of Sum64. -| input size | purego | asm | -| --- | --- | --- | -| 5 B | 979.66 MB/s | 1291.17 MB/s | -| 100 B | 7475.26 MB/s | 7973.40 MB/s | -| 4 KB | 17573.46 MB/s | 17602.65 MB/s | -| 10 MB | 17131.46 MB/s | 17142.16 MB/s | +| input size | purego | asm | +| ---------- | --------- | --------- | +| 4 B | 1.3 GB/s | 1.2 GB/s | +| 16 B | 2.9 GB/s | 3.5 GB/s | +| 100 B | 6.9 GB/s | 8.1 GB/s | +| 4 KB | 11.7 GB/s | 16.7 GB/s | +| 10 MB | 12.0 GB/s | 17.3 GB/s | -These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using -the following commands under Go 1.11.2: +These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C +CPU using the following commands under Go 1.19.2: ``` -$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes' -$ go test -benchtime 10s -bench '/xxhash,direct,bytes' +benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$') +benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') ``` ## Projects using this package diff --git a/vendor/github.com/cespare/xxhash/v2/testall.sh b/vendor/github.com/cespare/xxhash/v2/testall.sh new file mode 100644 index 00000000000..94b9c443987 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/testall.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -eu -o pipefail + +# Small convenience script for running the tests with various combinations of +# arch/tags. This assumes we're running on amd64 and have qemu available. + +go test ./... +go test -tags purego ./... +GOARCH=arm64 go test +GOARCH=arm64 go test -tags purego diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go index 15c835d5417..a9e0d45c9dc 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go @@ -16,19 +16,11 @@ const ( prime5 uint64 = 2870177450012600261 ) -// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where -// possible in the Go code is worth a small (but measurable) performance boost -// by avoiding some MOVQs. Vars are needed for the asm and also are useful for -// convenience in the Go code in a few places where we need to intentionally -// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the -// result overflows a uint64). -var ( - prime1v = prime1 - prime2v = prime2 - prime3v = prime3 - prime4v = prime4 - prime5v = prime5 -) +// Store the primes in an array as well. +// +// The consts are used when possible in Go code to avoid MOVs but we need a +// contiguous array of the assembly code. +var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} // Digest implements hash.Hash64. type Digest struct { @@ -50,10 +42,10 @@ func New() *Digest { // Reset clears the Digest's state so that it can be reused. func (d *Digest) Reset() { - d.v1 = prime1v + prime2 + d.v1 = primes[0] + prime2 d.v2 = prime2 d.v3 = 0 - d.v4 = -prime1v + d.v4 = -primes[0] d.total = 0 d.n = 0 } @@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) { n = len(b) d.total += uint64(n) + memleft := d.mem[d.n&(len(d.mem)-1):] + if d.n+n < 32 { // This new data doesn't even fill the current block. - copy(d.mem[d.n:], b) + copy(memleft, b) d.n += n return } if d.n > 0 { // Finish off the partial block. - copy(d.mem[d.n:], b) + c := copy(memleft, b) d.v1 = round(d.v1, u64(d.mem[0:8])) d.v2 = round(d.v2, u64(d.mem[8:16])) d.v3 = round(d.v3, u64(d.mem[16:24])) d.v4 = round(d.v4, u64(d.mem[24:32])) - b = b[32-d.n:] + b = b[c:] d.n = 0 } @@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 { h += d.total - i, end := 0, d.n - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(d.mem[i:i+8])) + b := d.mem[:d.n&(len(d.mem)-1)] + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(d.mem[i:i+4])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for i < end { - h ^= uint64(d.mem[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 - i++ } h ^= h >> 33 diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go deleted file mode 100644 index ad14b807f4d..00000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !appengine -// +build gc -// +build !purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b. -// -//go:noescape -func Sum64(b []byte) uint64 - -//go:noescape -func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s index be8db5bf796..3e8b132579e 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s @@ -1,215 +1,209 @@ +//go:build !appengine && gc && !purego // +build !appengine // +build gc // +build !purego #include "textflag.h" -// Register allocation: -// AX h -// SI pointer to advance through b -// DX n -// BX loop end -// R8 v1, k1 -// R9 v2 -// R10 v3 -// R11 v4 -// R12 tmp -// R13 prime1v -// R14 prime2v -// DI prime4v - -// round reads from and advances the buffer pointer in SI. -// It assumes that R13 has prime1v and R14 has prime2v. -#define round(r) \ - MOVQ (SI), R12 \ - ADDQ $8, SI \ - IMULQ R14, R12 \ - ADDQ R12, r \ - ROLQ $31, r \ - IMULQ R13, r - -// mergeRound applies a merge round on the two registers acc and val. -// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v. -#define mergeRound(acc, val) \ - IMULQ R14, val \ - ROLQ $31, val \ - IMULQ R13, val \ - XORQ val, acc \ - IMULQ R13, acc \ - ADDQ DI, acc +// Registers: +#define h AX +#define d AX +#define p SI // pointer to advance through b +#define n DX +#define end BX // loop end +#define v1 R8 +#define v2 R9 +#define v3 R10 +#define v4 R11 +#define x R12 +#define prime1 R13 +#define prime2 R14 +#define prime4 DI + +#define round(acc, x) \ + IMULQ prime2, x \ + ADDQ x, acc \ + ROLQ $31, acc \ + IMULQ prime1, acc + +// round0 performs the operation x = round(0, x). +#define round0(x) \ + IMULQ prime2, x \ + ROLQ $31, x \ + IMULQ prime1, x + +// mergeRound applies a merge round on the two registers acc and x. +// It assumes that prime1, prime2, and prime4 have been loaded. +#define mergeRound(acc, x) \ + round0(x) \ + XORQ x, acc \ + IMULQ prime1, acc \ + ADDQ prime4, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that there is at least one block +// to process. +#define blockLoop() \ +loop: \ + MOVQ +0(p), x \ + round(v1, x) \ + MOVQ +8(p), x \ + round(v2, x) \ + MOVQ +16(p), x \ + round(v3, x) \ + MOVQ +24(p), x \ + round(v4, x) \ + ADDQ $32, p \ + CMPQ p, end \ + JLE loop // func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT, $0-32 +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 // Load fixed primes. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 - MOVQ ·prime4v(SB), DI + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 + MOVQ ·primes+24(SB), prime4 // Load slice. - MOVQ b_base+0(FP), SI - MOVQ b_len+8(FP), DX - LEAQ (SI)(DX*1), BX + MOVQ b_base+0(FP), p + MOVQ b_len+8(FP), n + LEAQ (p)(n*1), end // The first loop limit will be len(b)-32. - SUBQ $32, BX + SUBQ $32, end // Check whether we have at least one block. - CMPQ DX, $32 + CMPQ n, $32 JLT noBlocks // Set up initial state (v1, v2, v3, v4). - MOVQ R13, R8 - ADDQ R14, R8 - MOVQ R14, R9 - XORQ R10, R10 - XORQ R11, R11 - SUBQ R13, R11 - - // Loop until SI > BX. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop - - MOVQ R8, AX - ROLQ $1, AX - MOVQ R9, R12 - ROLQ $7, R12 - ADDQ R12, AX - MOVQ R10, R12 - ROLQ $12, R12 - ADDQ R12, AX - MOVQ R11, R12 - ROLQ $18, R12 - ADDQ R12, AX - - mergeRound(AX, R8) - mergeRound(AX, R9) - mergeRound(AX, R10) - mergeRound(AX, R11) + MOVQ prime1, v1 + ADDQ prime2, v1 + MOVQ prime2, v2 + XORQ v3, v3 + XORQ v4, v4 + SUBQ prime1, v4 + + blockLoop() + + MOVQ v1, h + ROLQ $1, h + MOVQ v2, x + ROLQ $7, x + ADDQ x, h + MOVQ v3, x + ROLQ $12, x + ADDQ x, h + MOVQ v4, x + ROLQ $18, x + ADDQ x, h + + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) JMP afterBlocks noBlocks: - MOVQ ·prime5v(SB), AX + MOVQ ·primes+32(SB), h afterBlocks: - ADDQ DX, AX - - // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8. - ADDQ $24, BX - - CMPQ SI, BX - JG fourByte - -wordLoop: - // Calculate k1. - MOVQ (SI), R8 - ADDQ $8, SI - IMULQ R14, R8 - ROLQ $31, R8 - IMULQ R13, R8 - - XORQ R8, AX - ROLQ $27, AX - IMULQ R13, AX - ADDQ DI, AX - - CMPQ SI, BX - JLE wordLoop - -fourByte: - ADDQ $4, BX - CMPQ SI, BX - JG singles - - MOVL (SI), R8 - ADDQ $4, SI - IMULQ R13, R8 - XORQ R8, AX - - ROLQ $23, AX - IMULQ R14, AX - ADDQ ·prime3v(SB), AX - -singles: - ADDQ $4, BX - CMPQ SI, BX + ADDQ n, h + + ADDQ $24, end + CMPQ p, end + JG try4 + +loop8: + MOVQ (p), x + ADDQ $8, p + round0(x) + XORQ x, h + ROLQ $27, h + IMULQ prime1, h + ADDQ prime4, h + + CMPQ p, end + JLE loop8 + +try4: + ADDQ $4, end + CMPQ p, end + JG try1 + + MOVL (p), x + ADDQ $4, p + IMULQ prime1, x + XORQ x, h + + ROLQ $23, h + IMULQ prime2, h + ADDQ ·primes+16(SB), h + +try1: + ADDQ $4, end + CMPQ p, end JGE finalize -singlesLoop: - MOVBQZX (SI), R12 - ADDQ $1, SI - IMULQ ·prime5v(SB), R12 - XORQ R12, AX +loop1: + MOVBQZX (p), x + ADDQ $1, p + IMULQ ·primes+32(SB), x + XORQ x, h + ROLQ $11, h + IMULQ prime1, h - ROLQ $11, AX - IMULQ R13, AX - - CMPQ SI, BX - JL singlesLoop + CMPQ p, end + JL loop1 finalize: - MOVQ AX, R12 - SHRQ $33, R12 - XORQ R12, AX - IMULQ R14, AX - MOVQ AX, R12 - SHRQ $29, R12 - XORQ R12, AX - IMULQ ·prime3v(SB), AX - MOVQ AX, R12 - SHRQ $32, R12 - XORQ R12, AX - - MOVQ AX, ret+24(FP) + MOVQ h, x + SHRQ $33, x + XORQ x, h + IMULQ prime2, h + MOVQ h, x + SHRQ $29, x + XORQ x, h + IMULQ ·primes+16(SB), h + MOVQ h, x + SHRQ $32, x + XORQ x, h + + MOVQ h, ret+24(FP) RET -// writeBlocks uses the same registers as above except that it uses AX to store -// the d pointer. - // func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT, $0-40 +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 // Load fixed primes needed for round. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 // Load slice. - MOVQ b_base+8(FP), SI - MOVQ b_len+16(FP), DX - LEAQ (SI)(DX*1), BX - SUBQ $32, BX + MOVQ b_base+8(FP), p + MOVQ b_len+16(FP), n + LEAQ (p)(n*1), end + SUBQ $32, end // Load vN from d. - MOVQ d+0(FP), AX - MOVQ 0(AX), R8 // v1 - MOVQ 8(AX), R9 // v2 - MOVQ 16(AX), R10 // v3 - MOVQ 24(AX), R11 // v4 + MOVQ s+0(FP), d + MOVQ 0(d), v1 + MOVQ 8(d), v2 + MOVQ 16(d), v3 + MOVQ 24(d), v4 // We don't need to check the loop condition here; this function is // always called with at least one block of data to process. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop + blockLoop() // Copy vN back to d. - MOVQ R8, 0(AX) - MOVQ R9, 8(AX) - MOVQ R10, 16(AX) - MOVQ R11, 24(AX) - - // The number of bytes written is SI minus the old base pointer. - SUBQ b_base+8(FP), SI - MOVQ SI, ret+32(FP) + MOVQ v1, 0(d) + MOVQ v2, 8(d) + MOVQ v3, 16(d) + MOVQ v4, 24(d) + + // The number of bytes written is p minus the old base pointer. + SUBQ b_base+8(FP), p + MOVQ p, ret+32(FP) RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s new file mode 100644 index 00000000000..7e3145a2218 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s @@ -0,0 +1,183 @@ +//go:build !appengine && gc && !purego +// +build !appengine +// +build gc +// +build !purego + +#include "textflag.h" + +// Registers: +#define digest R1 +#define h R2 // return value +#define p R3 // input pointer +#define n R4 // input length +#define nblocks R5 // n / 32 +#define prime1 R7 +#define prime2 R8 +#define prime3 R9 +#define prime4 R10 +#define prime5 R11 +#define v1 R12 +#define v2 R13 +#define v3 R14 +#define v4 R15 +#define x1 R20 +#define x2 R21 +#define x3 R22 +#define x4 R23 + +#define round(acc, x) \ + MADD prime2, acc, x, acc \ + ROR $64-31, acc \ + MUL prime1, acc + +// round0 performs the operation x = round(0, x). +#define round0(x) \ + MUL prime2, x \ + ROR $64-31, x \ + MUL prime1, x + +#define mergeRound(acc, x) \ + round0(x) \ + EOR x, acc \ + MADD acc, prime4, prime1, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that n >= 32. +#define blockLoop() \ + LSR $5, n, nblocks \ + PCALIGN $16 \ + loop: \ + LDP.P 16(p), (x1, x2) \ + LDP.P 16(p), (x3, x4) \ + round(v1, x1) \ + round(v2, x2) \ + round(v3, x3) \ + round(v4, x4) \ + SUB $1, nblocks \ + CBNZ nblocks, loop + +// func Sum64(b []byte) uint64 +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 + LDP b_base+0(FP), (p, n) + + LDP ·primes+0(SB), (prime1, prime2) + LDP ·primes+16(SB), (prime3, prime4) + MOVD ·primes+32(SB), prime5 + + CMP $32, n + CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 } + BLT afterLoop + + ADD prime1, prime2, v1 + MOVD prime2, v2 + MOVD $0, v3 + NEG prime1, v4 + + blockLoop() + + ROR $64-1, v1, x1 + ROR $64-7, v2, x2 + ADD x1, x2 + ROR $64-12, v3, x3 + ROR $64-18, v4, x4 + ADD x3, x4 + ADD x2, x4, h + + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) + +afterLoop: + ADD n, h + + TBZ $4, n, try8 + LDP.P 16(p), (x1, x2) + + round0(x1) + + // NOTE: here and below, sequencing the EOR after the ROR (using a + // rotated register) is worth a small but measurable speedup for small + // inputs. + ROR $64-27, h + EOR x1 @> 64-27, h, h + MADD h, prime4, prime1, h + + round0(x2) + ROR $64-27, h + EOR x2 @> 64-27, h, h + MADD h, prime4, prime1, h + +try8: + TBZ $3, n, try4 + MOVD.P 8(p), x1 + + round0(x1) + ROR $64-27, h + EOR x1 @> 64-27, h, h + MADD h, prime4, prime1, h + +try4: + TBZ $2, n, try2 + MOVWU.P 4(p), x2 + + MUL prime1, x2 + ROR $64-23, h + EOR x2 @> 64-23, h, h + MADD h, prime3, prime2, h + +try2: + TBZ $1, n, try1 + MOVHU.P 2(p), x3 + AND $255, x3, x1 + LSR $8, x3, x2 + + MUL prime5, x1 + ROR $64-11, h + EOR x1 @> 64-11, h, h + MUL prime1, h + + MUL prime5, x2 + ROR $64-11, h + EOR x2 @> 64-11, h, h + MUL prime1, h + +try1: + TBZ $0, n, finalize + MOVBU (p), x4 + + MUL prime5, x4 + ROR $64-11, h + EOR x4 @> 64-11, h, h + MUL prime1, h + +finalize: + EOR h >> 33, h + MUL prime2, h + EOR h >> 29, h + MUL prime3, h + EOR h >> 32, h + + MOVD h, ret+24(FP) + RET + +// func writeBlocks(d *Digest, b []byte) int +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 + LDP ·primes+0(SB), (prime1, prime2) + + // Load state. Assume v[1-4] are stored contiguously. + MOVD d+0(FP), digest + LDP 0(digest), (v1, v2) + LDP 16(digest), (v3, v4) + + LDP b_base+8(FP), (p, n) + + blockLoop() + + // Store updated state. + STP (v1, v2), 0(digest) + STP (v3, v4), 16(digest) + + BIC $31, n + MOVD n, ret+32(FP) + RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go new file mode 100644 index 00000000000..9216e0a40c1 --- /dev/null +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go @@ -0,0 +1,15 @@ +//go:build (amd64 || arm64) && !appengine && gc && !purego +// +build amd64 arm64 +// +build !appengine +// +build gc +// +build !purego + +package xxhash + +// Sum64 computes the 64-bit xxHash digest of b. +// +//go:noescape +func Sum64(b []byte) uint64 + +//go:noescape +func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go index 4a5a821603e..26df13bba4b 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go @@ -1,4 +1,5 @@ -// +build !amd64 appengine !gc purego +//go:build (!amd64 && !arm64) || appengine || !gc || purego +// +build !amd64,!arm64 appengine !gc purego package xxhash @@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 { var h uint64 if n >= 32 { - v1 := prime1v + prime2 + v1 := primes[0] + prime2 v2 := prime2 v3 := uint64(0) - v4 := -prime1v + v4 := -primes[0] for len(b) >= 32 { v1 = round(v1, u64(b[0:8:len(b)])) v2 = round(v2, u64(b[8:16:len(b)])) @@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 { h += uint64(n) - i, end := 0, len(b) - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(b[i:i+8:len(b)])) + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(b[i:i+4:len(b)])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for ; i < end; i++ { - h ^= uint64(b[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go index fc9bea7a31f..e86f1b5fd8e 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine // This file contains the safe implementations of otherwise unsafe-using code. diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go index 376e0ca2e49..1c1638fd88a 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go @@ -1,3 +1,4 @@ +//go:build !appengine // +build !appengine // This file encapsulates usage of unsafe. @@ -11,7 +12,7 @@ import ( // In the future it's possible that compiler optimizations will make these // XxxString functions unnecessary by realizing that calls such as -// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205. +// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205. // If that happens, even if we keep these functions they can be replaced with // the trivial safe code. diff --git a/vendor/github.com/common-nighthawk/go-figure/.travis.yml b/vendor/github.com/common-nighthawk/go-figure/.travis.yml new file mode 100644 index 00000000000..4f2ee4d9733 --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/.travis.yml @@ -0,0 +1 @@ +language: go diff --git a/vendor/github.com/common-nighthawk/go-figure/LICENSE b/vendor/github.com/common-nighthawk/go-figure/LICENSE new file mode 100644 index 00000000000..7d44d62aba7 --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Daniel Deutsch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/common-nighthawk/go-figure/README.md b/vendor/github.com/common-nighthawk/go-figure/README.md new file mode 100644 index 00000000000..ddf8d7a1ce9 --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/README.md @@ -0,0 +1,437 @@ +[![Build Status](https://travis-ci.com/common-nighthawk/go-figure.svg?branch=master)](https://travis-ci.com/common-nighthawk/go-figure) + +# Go Figure + +## Description +Go Figure prints beautiful ASCII art from text. +It supports [FIGlet](http://www.figlet.org/) files, +and most of its features. + +This package was inspired by the Ruby gem [artii](https://github.com/miketierney/artii), +but built from scratch and with a different feature set. + +## Installation +`go get github.com/common-nighthawk/go-figure` + +## Basic Example +```go +package main + +import("github.com/common-nighthawk/go-figure") + +func main() { + myFigure := figure.NewFigure("Hello World", "", true) + myFigure.Print() +} +``` + +```txt + _ _ _ _ __ __ _ _ + | | | | ___ | | | | ___ \ \ / / ___ _ __ | | __| | + | |_| | / _ \ | | | | / _ \ \ \ /\ / / / _ \ | '__| | | / _` | + | _ | | __/ | | | | | (_) | \ V V / | (_) | | | | | | (_| | + |_| |_| \___| |_| |_| \___/ \_/\_/ \___/ |_| |_| \__,_| +``` + +You can also make colorful figures: + +```go +func main() { + myFigure := figure.NewColorFigure("Hello World", "", "green", true) + myFigure.Print() +} +``` + +## Documentation +### Create a Figure +There are three ways to create a Figure. These are-- +the method `func NewFigure`, +the method `func NewColorFigure`, and +the method `func NewFigureWithFont`. + +Each constructor takes the arguments: the text, font, and strict mode. +The "color" constructor takes a color as an additional arg. +The "with font" specifies the font differently. +The method signature are: +``` +func NewFigure(phrase, fontName string, strict bool) figure +func NewColorFigure(phrase, fontName string, color string, strict bool) figure +func NewFigureWithFont(phrase string, reader io.Reader, strict bool) figure +``` + +`NewFigure` requires only the name of the font, and uses the font file shipped +with this package stored in bindata. + +If passed an empty string for the font name, a default is provided. +That is, these are both valid-- + +`myFigure := figure.NewFigure("Foo Bar", "", true)` + +`myFigure := figure.NewFigure("Foo Bar", "alphabet", true)` + +Please note that font names are case sensitive. + +`NewFigureWithFont`, on the other hand, accepts the font file directly. +This allows you to BYOF (bring your own font). +Provide the absolute path to the flf. +You can point to a file the comes with this project +or you can store the file anywhere you'd like and use that location. + +The font files are available in the [fonts folder](https://github.com/common-nighthawk/go-figure/tree/master/fonts) +and on [figlet.org](http://www.figlet.org/fontdb.cgi). + +Here are two examples-- + +`myFigure := figure.NewFigureWithFont("Foo Bar", "/home/ubuntu/go/src/github.com/common-nighthawk/go-figure/fonts/alphabet.flf", true)` + +`myFigure := figure.NewFigureWithFont("Foo Bar", "/home/lib/fonts/alaphabet.flf", true)` + +You can also make colorful figures! The current supported colors are: +blue, cyan, gray, green, purple, red, white, yellow. + +An example-- + +`myFigure := figure.NewColorFigure("Foo Bar", "", "green", true) + +Strict mode dictates how to handle characters outside of standard ASCII. +When set to true, a non-ASCII character (outside character codes 32-127) +will cause the program to panic. +When set to false, these characters are replaced with a question mark ('?'). +Examples of each-- + +`figure.NewFigure("Foo 👍 Bar", "alphabet", true).Print()` + +```txt +2016/12/01 19:35:38 invalid input. +``` + +`figure.NewFigure("Foo 👍 Bar", "alphabet", false).Print()` + +```txt + _____ ___ ____ + | ___| ___ ___ |__ \ | __ ) __ _ _ __ + | |_ / _ \ / _ \ / / | _ \ / _` | | '__| + | _| | (_) | | (_) | |_| | |_) | | (_| | | | + |_| \___/ \___/ (_) |____/ \__,_| |_| +``` + +### Methods: stdout +#### Print() +The most basic, and common, method is func Print. +A figure responds to Print(), and will write the output to the terminal. +There is no return value. + +`myFigure.Print()` + +But if you're feeling adventurous, +explore the methods below. + +#### Blink(duration, timeOn, timeOff int) +A figure responds to the func Blink, taking three arguments. +`duration` is the total time the banner will display, in milliseconds. +`timeOn` is the length of time the text will blink on (also in ms). +`timeOff` is the length of time the text will blink off (ms). +For an even blink, set `timeOff` to -1 +(same as setting `timeOff` to the value of `timeOn`). +There is no return value. + +`myFigure.Blink(5000, 1000, 500)` + +`myFigure.Blink(5000, 1000, -1)` + +#### Scroll(duration, stillness int, direction string) +A figure responds to the func Scroll, taking three arguments. +`duration` is the total time the banner will display, in milliseconds. +`stillness` is the length of time the text will not move (also in ms). +Therefore, the lower the stillness the faster the scroll speed. +`direction` can be either "right" or "left" (case insensitive). +The direction will be left if an invalid option (e.g. "foo") is passed. +There is no return value. + +`myFigure.Scroll(5000, 200, "right")` + +`myFigure.Scroll(5000, 100, "left")` + +#### Dance(duration, freeze int) +A figure responds to the func Dance, taking two arguments. +`duration` is the total time the banner will display, in milliseconds. +`freeze` is the length of time between dance moves (also in ms). +Therefore, the lower the freeze the faster the dancing. +There is no return value. + +`myFigure.Dance(5000, 800)` + +### Methods: Writers +#### Write(w io.Writer, fig figure) +Unlike the above methods that operate on a figure value, +func Write is a function that takes two arguments. +`w` is a value that implements all the methods in the io.Writer interface. +`fig` is the figure that will be written. + +`figure.Write(w, myFigure)` + +This method would be useful, for example, to add a nifty banner to a web page-- +```go +func landingPage(w http.ResponseWriter, r *http.Request) { + figure.Write(w, myFigure) +} +``` + +### Methods: Misc +#### Slicify() ([]string) +If you want to do something outside of the created methods, +you can grab the internal slice. +This gives you a good start to build anything +with the ASCII art, if manually. + +A figure responds to the func Slicify, +and will return the slice of strings. + +`myFigure.Slicify()` + +returns + +```txt +["FFFF BBBB ", + "F B B ", + "FFF ooo ooo BBBB aa rrr", + "F o o o o B B a a r ", + "F ooo ooo BBBB aaa r "] +``` + +## More Examples +`figure.NewFigure("Go-Figure", "isometric1", true).Print()` + +``` + ___ ___ ___ ___ ___ ___ ___ + /\ \ /\ \ /\ \ ___ /\ \ /\__\ /\ \ /\ \ + /::\ \ /::\ \ /::\ \ /\ \ /::\ \ /:/ / /::\ \ /::\ \ + /:/\:\ \ /:/\:\ \ /:/\:\ \ \:\ \ /:/\:\ \ /:/ / /:/\:\ \ /:/\:\ \ + /:/ \:\ \ /:/ \:\ \ /::\~\:\ \ /::\__\ /:/ \:\ \ /:/ / ___ /::\~\:\ \ /::\~\:\ \ + /:/__/_\:\__\ /:/__/ \:\__\ /:/\:\ \:\__\ __/:/\/__/ /:/__/_\:\__\ /:/__/ /\__\ /:/\:\ \:\__\ /:/\:\ \:\__\ + \:\ /\ \/__/ \:\ \ /:/ / \/__\:\ \/__/ /\/:/ / \:\ /\ \/__/ \:\ \ /:/ / \/_|::\/:/ / \:\~\:\ \/__/ + \:\ \:\__\ \:\ /:/ / \:\__\ \::/__/ \:\ \:\__\ \:\ /:/ / |:|::/ / \:\ \:\__\ + \:\/:/ / \:\/:/ / \/__/ \:\__\ \:\/:/ / \:\/:/ / |:|\/__/ \:\ \/__/ + \::/ / \::/ / \/__/ \::/ / \::/ / |:| | \:\__\ + \/__/ \/__/ \/__/ \/__/ \|__| \/__/ +``` + +`figure.NewFigure("Foo Bar Pop", "smkeyboard", true).Print()` + +``` + ____ ____ ____ ____ ____ ____ ____ ____ ____ +||F ||||o ||||o ||||B ||||a ||||r ||||P ||||o ||||p || +||__||||__||||__||||__||||__||||__||||__||||__||||__|| +|/__\||/__\||/__\||/__\||/__\||/__\||/__\||/__\||/__\| +``` + +`figure.NewFigure("Keep Your Eyes On Me", "rectangles", true).Print()` + +``` + + _____ __ __ _____ _____ _____ +| | | ___ ___ ___ | | | ___ _ _ ___ | __| _ _ ___ ___ | | ___ | | ___ +| -|| -_|| -_|| . ||_ _|| . || | || _|| __|| | || -_||_ -|| | || || | | || -_| +|__|__||___||___|| _| |_| |___||___||_| |_____||_ ||___||___||_____||_|_||_|_|_||___| + |_| |___| +``` + +`figure.NewFigure("ABCDEFGHIJ", "eftichess", true).Print()` + +``` +######### ######### ___ ######### ######### +##[`'`']# \`~'/ ##'\v/`## /\*/\ ##|`+'|## '\v/` ##\`~'/## [`'`'] '\v/` \`~'/ +###| |## (o o) ##(o 0)## /(o o)\ ##(o o)## (o 0) ##(o o)## | | (o 0) (o o) +###|__|## \ / \ ###(_)### (_) ###(_)### (_) ###\ / \# |__| (_) \ / \ +######### " ######### ######### ####"#### " +``` + +`figure.NewFigure("Give your reasons", "doom", true).Blink(10000, 500, -1)` + +![blink](docs/blink.gif "blink") + +`figure.NewFigure("I mean, I could...", "basic", true).Scroll(10000, 200, "right")` + +`figure.NewFigure("But why would I want to?", "basic", true).Scroll(10000, 200, "left")` + +![scroll](docs/scroll.gif "scroll") + +`figure.NewFigure("It's been waiting for you", "larry3d", true).Dance(10000, 500)` + +![dance](docs/dance.gif "dance") + +`figure.Write(w, figure.NewFigure("Hello, It's Me", "puffy", true))` + +![web](docs/web.png "web") + + +## Supported Fonts +* 3-d +* 3x5 +* 5lineoblique +* acrobatic +* alligator +* alligator2 +* alphabet +* avatar +* banner +* banner3-D +* banner3 +* banner4 +* barbwire +* basic +* bell +* big +* bigchief +* binary +* block +* bubble +* bulbhead +* calgphy2 +* caligraphy +* catwalk +* chunky +* coinstak +* colossal +* computer +* contessa +* contrast +* cosmic +* cosmike +* cricket +* cursive +* cyberlarge +* cybermedium +* cybersmall +* diamond +* digital +* doh +* doom +* dotmatrix +* drpepper +* eftichess +* eftifont +* eftipiti +* eftirobot +* eftitalic +* eftiwall +* eftiwater +* epic +* fender +* fourtops +* fuzzy +* goofy +* gothic +* graffiti +* hollywood +* invita +* isometric1 +* isometric2 +* isometric3 +* isometric4 +* italic +* ivrit +* jazmine +* jerusalem +* katakana +* kban +* larry3d +* lcd +* lean +* letters +* linux +* lockergnome +* madrid +* marquee +* maxfour +* mike +* mini +* mirror +* mnemonic +* morse +* moscow +* nancyj-fancy +* nancyj-underlined +* nancyj +* nipples +* ntgreek +* o8 +* ogre +* pawp +* peaks +* pebbles +* pepper +* poison +* puffy +* pyramid +* rectangles +* relief +* relief2 +* rev +* roman +* rot13 +* rounded +* rowancap +* rozzo +* runic +* runyc +* sblood +* script +* serifcap +* shadow +* short +* slant +* slide +* slscript +* small +* smisome1 +* smkeyboard +* smscript +* smshadow +* smslant +* smtengwar +* speed +* stampatello +* standard +* starwars +* stellar +* stop +* straight +* tanja +* tengwar +* term +* thick +* thin +* threepoint +* ticks +* ticksslant +* tinker-toy +* tombstone +* trek +* tsalagi +* twopoint +* univers +* usaflag +* wavy +* weird + +## Contributing +Because this project is small, we can dispense with formality. +Submit a pull request, open an issue, request a change. +All good! + +## Wanna Say Thanks? +GitHub stars are helpful. +Most importantly, they help with discoverability. +Projects with more stars are displayed higher +in search results when people are looking for packages. +Also--they make contributors feel good :) + +If you are feeling especially generous, +give a shout to [@cmmn_nighthawk](https://twitter.com/cmmn_nighthawk). + +## TODO +* Add proper support for spaces +* More animations +* Implement graceful line-wrapping and smushing +* Deep-copy font for Dance (current implementation is destructive) diff --git a/vendor/github.com/common-nighthawk/go-figure/bindata.go b/vendor/github.com/common-nighthawk/go-figure/bindata.go new file mode 100644 index 00000000000..f85d3bb57af --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/bindata.go @@ -0,0 +1,3641 @@ +// Code generated by go-bindata. +// sources: +// fonts/3-d.flf +// fonts/3x5.flf +// fonts/5lineoblique.flf +// fonts/acrobatic.flf +// fonts/alligator.flf +// fonts/alligator2.flf +// fonts/alphabet.flf +// fonts/avatar.flf +// fonts/banner.flf +// fonts/banner3-D.flf +// fonts/banner3.flf +// fonts/banner4.flf +// fonts/barbwire.flf +// fonts/basic.flf +// fonts/bell.flf +// fonts/big.flf +// fonts/bigchief.flf +// fonts/binary.flf +// fonts/block.flf +// fonts/bubble.flf +// fonts/bulbhead.flf +// fonts/calgphy2.flf +// fonts/caligraphy.flf +// fonts/catwalk.flf +// fonts/chunky.flf +// fonts/coinstak.flf +// fonts/colossal.flf +// fonts/computer.flf +// fonts/contessa.flf +// fonts/contrast.flf +// fonts/cosmic.flf +// fonts/cosmike.flf +// fonts/cricket.flf +// fonts/cursive.flf +// fonts/cyberlarge.flf +// fonts/cybermedium.flf +// fonts/cybersmall.flf +// fonts/diamond.flf +// fonts/digital.flf +// fonts/doh.flf +// fonts/doom.flf +// fonts/dotmatrix.flf +// fonts/drpepper.flf +// fonts/eftichess.flf +// fonts/eftifont.flf +// fonts/eftipiti.flf +// fonts/eftirobot.flf +// fonts/eftitalic.flf +// fonts/eftiwall.flf +// fonts/eftiwater.flf +// fonts/elite.flf +// fonts/epic.flf +// fonts/fender.flf +// fonts/fourtops.flf +// fonts/fuzzy.flf +// fonts/goofy.flf +// fonts/gothic.flf +// fonts/graffiti.flf +// fonts/hollywood.flf +// fonts/invita.flf +// fonts/isometric1.flf +// fonts/isometric2.flf +// fonts/isometric3.flf +// fonts/isometric4.flf +// fonts/italic.flf +// fonts/ivrit.flf +// fonts/jazmine.flf +// fonts/jerusalem.flf +// fonts/katakana.flf +// fonts/kban.flf +// fonts/larry3d.flf +// fonts/lcd.flf +// fonts/lean.flf +// fonts/letters.flf +// fonts/linux.flf +// fonts/lockergnome.flf +// fonts/madrid.flf +// fonts/marquee.flf +// fonts/maxfour.flf +// fonts/mike.flf +// fonts/mini.flf +// fonts/mirror.flf +// fonts/mnemonic.flf +// fonts/morse.flf +// fonts/moscow.flf +// fonts/nancyj-fancy.flf +// fonts/nancyj-underlined.flf +// fonts/nancyj.flf +// fonts/nipples.flf +// fonts/ntgreek.flf +// fonts/o8.flf +// fonts/ogre.flf +// fonts/pawp.flf +// fonts/peaks.flf +// fonts/pebbles.flf +// fonts/pepper.flf +// fonts/poison.flf +// fonts/puffy.flf +// fonts/pyramid.flf +// fonts/rectangles.flf +// fonts/relief.flf +// fonts/relief2.flf +// fonts/rev.flf +// fonts/roman.flf +// fonts/rot13.flf +// fonts/rounded.flf +// fonts/rowancap.flf +// fonts/rozzo.flf +// fonts/runic.flf +// fonts/runyc.flf +// fonts/sblood.flf +// fonts/script.flf +// fonts/serifcap.flf +// fonts/shadow.flf +// fonts/short.flf +// fonts/slant.flf +// fonts/slide.flf +// fonts/slscript.flf +// fonts/small.flf +// fonts/smisome1.flf +// fonts/smkeyboard.flf +// fonts/smscript.flf +// fonts/smshadow.flf +// fonts/smslant.flf +// fonts/smtengwar.flf +// fonts/speed.flf +// fonts/stampatello.flf +// fonts/standard.flf +// fonts/starwars.flf +// fonts/stellar.flf +// fonts/stop.flf +// fonts/straight.flf +// fonts/tanja.flf +// fonts/tengwar.flf +// fonts/term.flf +// fonts/thick.flf +// fonts/thin.flf +// fonts/threepoint.flf +// fonts/ticks.flf +// fonts/ticksslant.flf +// fonts/tinker-toy.flf +// fonts/tombstone.flf +// fonts/trek.flf +// fonts/tsalagi.flf +// fonts/twopoint.flf +// fonts/univers.flf +// fonts/usaflag.flf +// fonts/wavy.flf +// fonts/weird.flf +// DO NOT EDIT! + +package figure + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _fonts3DFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xb9\x8e\x1c\x37\x10\xcd\xf7\x2b\x2a\xd8\xa8\x00\xa9\x2c\x39\x51\x60\x18\x13\x28\xf0\x6f\xac\xb5\xb3\xb6\x00\x61\x04\xe8\x08\xfc\xf7\x06\x59\xd7\x2b\x92\x7d\xcc\x1a\xf0\x0a\xd3\x4d\x76\xb3\xc9\x3a\x5e\x3d\xbe\x6e\xbd\x7c\x79\x79\xff\xf4\x48\x1f\xe8\x03\xbd\xff\x85\xde\xbc\xa3\x77\x0f\xbf\xbe\xf9\x48\x2f\x5f\x6f\x3f\xe8\xd3\xb7\xeb\xd3\x8f\xeb\x33\xfd\xf9\x0f\x7d\x7c\xba\x7d\xbe\x7e\xa1\x3f\xae\xb7\xdb\xe7\xdb\x5f\xd7\x6f\xf4\xdb\xf3\xd3\xdf\xbd\x73\xb9\x7e\xfd\xfe\xf6\xf6\xe9\xfb\xcf\xb7\xd7\xe7\x9f\xbf\x3f\x3c\x3e\x5e\xf6\x7e\x97\x07\x62\xbe\x3c\xc8\xea\x20\xe4\x77\x85\xfa\x40\xa2\x7e\x8f\xa4\x9d\x88\xfa\xfd\xf6\xb7\x7b\xb2\xb3\xff\xf5\x2e\x33\xd9\xb1\xaf\x90\x7f\x6d\x2d\x61\x16\x3d\xf6\xc1\xd2\x07\xcb\xc9\xc1\xd2\x26\xee\x47\x5d\x18\x9e\x6a\xa6\x4b\x1f\x27\xf0\x78\xf3\x85\xb0\xaf\xf3\x0c\x96\xf7\x31\x6a\x72\x0f\x47\x18\xef\xce\x80\x5b\xad\xa9\xad\xc5\x63\xed\x70\xc9\xc1\x7d\xac\x98\x95\x32\x5c\x63\x8d\x79\x6b\xf6\xb0\xb7\x28\xb4\x56\x37\xb7\xdf\x6d\xae\x93\x25\xa7\xdb\xdf\x2f\xaa\x31\xcb\x83\xad\x6c\x26\x9a\x79\x3d\x20\x78\x12\xbd\x27\xa2\x23\x3d\xfd\xeb\x9b\xe5\x54\x26\xad\x41\xb4\x90\x44\x78\x24\x23\xd3\x27\xd3\x0b\x8b\x34\x43\xa2\xed\x57\xe6\x48\x83\x1c\x26\x3d\xc6\xb6\xac\x02\x62\xc2\xa1\x77\x18\x3a\x02\xd9\x8b\x85\x7b\x88\xa5\x61\x6c\x1e\x46\x8a\x93\x9c\x0d\x16\xda\x38\x94\x2c\xf9\x63\x8b\x73\xba\x9d\x0b\xcf\xe7\xc3\x95\xa0\x78\x3d\x09\xe1\x39\xfb\x3c\x77\x21\x99\x22\xb3\x61\x41\x47\x63\xbb\x2f\x62\xe4\xd1\xf0\xab\x0d\xe3\x0a\xcd\x55\x80\x38\x30\xec\x10\xf6\x89\xcc\x75\x84\xd9\xea\x94\xc1\x99\x2d\x20\xe5\x26\x5d\xa6\x7b\xc2\x56\x51\x8a\x0a\x77\x47\x18\x63\x7c\xc7\x44\x76\x8b\x76\x5d\xc9\xf8\xb2\xd8\xfa\x5a\xbc\x54\x96\xf5\x1c\x2c\x1a\x64\x35\x17\xcc\xa5\x48\x50\xb3\xc9\xa1\xc1\x01\xca\x23\x8b\x26\xd7\xfa\xe8\x32\x63\xbd\xb5\x31\x51\x0d\x5b\x59\x5f\x0b\xca\xdc\x77\x20\x39\x8c\x0c\x44\xb2\xc6\xcd\xc6\xb2\xa7\x2c\x3a\x39\xfa\x84\x45\x9b\x05\x3b\x6c\x84\x07\x63\x86\xf2\xce\xa2\x73\xea\xea\x0d\x7b\x54\xb2\xa6\xb2\xe8\xac\x63\x50\x10\x28\xdb\x52\xcd\xd8\x18\xe1\xbc\xba\x32\x3e\x35\x16\xf5\x09\x03\x0e\x5c\x58\xd1\x02\x3b\x2d\x30\x39\x21\x65\x75\x30\xe5\xbe\xbd\xb8\xb2\x91\x5e\x36\x7e\x71\x2d\xc2\x62\x5b\x2c\x1b\xf9\x0b\x15\xfe\x8e\x98\x31\x90\x77\x9f\x37\x56\x15\x57\x18\xba\xb1\x00\xd3\x64\x0d\xb2\x81\xde\x29\x8d\x28\x3d\x82\xe4\xe8\x03\xe4\x25\x25\x0c\xfb\x37\x27\xf5\xe4\x00\x72\xda\xf4\xf9\x6c\x4d\x2f\x73\x14\x0d\x1c\x84\xc6\x6e\x8b\x79\xe5\xfc\x10\x69\x2e\x6d\x71\xcd\x65\xdb\x2d\x03\x9f\x0d\xc5\xed\x5a\x00\x6c\x2f\xb6\xed\xb5\xd1\x41\x53\x01\x36\x3f\x2e\x00\xd1\x44\x3b\xab\xe7\x3a\x80\xd6\x03\x02\xd7\x25\xe6\xff\x6d\xe2\xf5\xf6\x16\x53\x43\xd4\x4b\xdc\xa7\xc8\xc3\x74\x61\xaa\x82\xca\x9e\x13\x29\x73\x8a\xd4\x1c\x24\x6b\x54\x94\x0d\x9d\x53\xc8\xdc\x85\xe9\x86\xee\x5f\x4a\x07\x4e\xaa\x3f\x6e\x99\x36\x53\xc7\x81\xb0\xd1\xc5\x30\x2f\x20\x16\xc0\xb3\xba\x6c\x6e\x01\x18\x63\x9c\xa4\x37\x20\x4d\xe7\x34\xde\xd7\xdc\x84\x15\x79\x22\xd3\xa2\x4e\x40\x9c\x76\x05\xb5\x99\x75\x8c\xe1\x17\x2f\x7d\x5f\x51\xa6\xf4\x8c\x19\xaa\x5c\x82\x70\x88\xb7\xa1\x5c\xbc\x2e\x5d\x17\x66\x5c\x56\xc2\x09\xf2\x2e\x82\x42\x2a\xde\x09\xf1\x9e\xba\xde\x9e\x04\xdb\x57\x3d\x09\xab\x09\xf1\x4e\x88\xf7\x4a\x09\x48\x39\x61\xf1\x48\x86\xaf\xab\x5c\x1a\x5d\x19\x7c\xa1\x6a\x3e\x56\xaf\xa4\x18\x85\x3d\x31\xfd\xf1\x17\x24\x75\xa8\x72\xd1\x9a\x45\x65\x66\x48\xe6\x30\x4b\x60\xf3\xc9\xac\x85\x63\xa8\x53\x6d\x7f\xf3\xd2\x9f\xb9\x7f\x42\x74\xaa\x88\x28\xd3\x71\x9f\xa9\xfb\x00\x08\x55\x78\x03\x12\xdc\x44\x5f\xd5\x49\xc9\x55\xc1\x3d\xa2\xe9\x7c\x1b\x40\x42\xaf\x61\x53\xdc\xbd\x34\xfe\x20\x44\x00\x43\x24\x07\x9e\xd4\x95\x70\xa9\xc2\x09\x8c\x85\xda\x61\x96\x58\xc7\x42\x55\x8e\xab\xdc\x50\x39\x0f\xcc\x07\xeb\x8b\xf1\x20\x72\x40\xe3\x94\xa2\x5e\xa1\x2c\x05\x83\x24\x4f\x47\x38\x7c\xf6\x08\xcc\x61\x53\x68\x16\x01\x40\x2e\x74\xd7\xab\xe8\xb6\x08\xb0\x82\x8a\x7a\xd8\x3d\xe3\x5b\xf6\xa0\x86\x73\x35\xcc\x79\x71\x59\x18\x34\x72\x7a\x81\x95\x36\x58\x96\x55\xb8\x7f\x9e\x2c\xa3\x2a\x5e\x99\x85\x90\xc8\x5c\x43\xc2\x0e\xbf\xfa\xdc\x71\xd4\xd9\xf9\x22\xb1\x75\x5e\xc4\xb0\x6b\xd9\xfe\xf2\xbc\xfd\x81\x02\xd7\x1d\xdb\xb0\x57\x14\x80\x40\x8d\x23\xad\xc2\xde\x4d\x03\x1c\x3c\x99\xeb\x56\xd9\x55\x72\xd7\x84\x4d\x27\xde\xb3\x8b\xc5\xb5\x55\x6d\x82\xcd\x37\x96\xdb\x16\x42\x51\xc1\x49\x16\xd8\xaa\x24\x3f\x58\x28\x83\xd3\x77\x5a\x88\xb5\xa2\xb6\x6e\x4c\x68\xd7\xc8\x3f\xbc\x41\xe5\x95\x4f\xb4\x1b\x8d\x45\xec\xb6\x22\xb6\x72\x0b\x02\xb1\x12\x91\xaf\xce\x2e\x0a\x2e\x04\x6e\xbe\xc6\xef\xea\x61\x2f\x56\xa1\xda\x1f\x8a\x38\x5d\x32\xe3\xd1\xf4\xb0\x37\xf6\x84\x90\xc1\xa1\x82\x43\xf3\x85\xdc\x53\x9b\x53\x08\xe8\x57\xb1\x9d\xa3\x27\x6b\xfc\x12\x3f\xf5\x72\xd3\x37\x34\x48\x2c\x49\x26\x2c\x69\xd5\x63\xec\x89\x59\x47\xc3\x82\xb5\x39\xae\x93\xd3\xd2\xd4\x04\x35\x8d\xd9\x5a\x4f\x4c\x33\x45\x8c\x62\x72\xd4\x0c\x49\x33\x23\x50\xcf\x32\x84\x8a\xa3\x8a\x3f\x23\xe2\x05\xf2\x29\x3f\x8a\xf8\xfb\x0c\xf2\x98\x9b\xc3\xf9\x49\xd0\x69\x41\x4e\x7c\xfc\xe9\x13\x7b\x8a\xc8\x23\x69\x80\x32\xd3\x64\x61\xd9\x18\xc1\x08\xe0\x6c\x19\x6a\xc7\x50\x8e\xf8\xbf\x1a\x48\x00\xe7\xd8\x22\xbc\x9d\x93\x80\x4e\xa2\xba\xda\x29\xe9\x1d\x62\x9c\x70\x48\x45\xb1\xa5\x18\x94\x03\xb5\x33\xc6\x70\xb1\xaf\xf2\xa4\xd0\xb0\x7e\xd8\xd8\xa1\xe7\x97\x25\x62\xce\x92\x82\x4f\xe6\xac\x6f\x85\x24\x88\xc3\x25\x9f\xbd\xf1\x84\xc6\x9b\x5f\x9a\x6b\xd2\xf1\xdb\x10\xc5\x87\x89\x98\x0a\x95\xdc\x4a\x91\xcd\x80\x5f\xe3\x33\x53\x0d\x52\x74\x1a\x83\x44\xcb\x21\x78\x06\x5c\x39\x9a\x97\x70\x72\x7e\x36\x6a\x6f\x09\xb6\x1f\x4d\xfd\xd3\xd3\xed\x18\x41\xf0\x1a\x90\xcc\x16\xf4\xe9\x8c\xb8\xc9\x5b\xfb\xcd\xcb\xc3\xf0\xef\xff\xba\xf0\x6f\x00\x00\x00\xff\xff\x99\xec\xf4\xdf\x8e\x1e\x00\x00") + +func fonts3DFlfBytes() ([]byte, error) { + return bindataRead( + _fonts3DFlf, + "fonts/3-d.flf", + ) +} + +func fonts3DFlf() (*asset, error) { + bytes, err := fonts3DFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/3-d.flf", size: 7822, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fonts3x5Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x56\xcd\x8e\xdb\x3c\x0c\xbc\xe7\x29\x06\xe0\x77\x48\x80\x6f\x0d\xb4\xdd\xee\xa1\xa7\x00\x2d\xd0\x43\x2f\x45\xdf\x40\x89\xed\x44\x88\x37\x5e\xd8\x0e\xda\x14\xe8\xbb\xf7\x90\x1f\x4b\xe4\xd0\x4e\x2f\x82\xe2\x50\x24\x35\x1c\x0e\x55\x37\xf5\xfb\xf0\x1f\x5e\xf0\x8c\x17\x3c\xbd\xc3\xf3\xe2\xc3\xaf\x8f\xa8\xdb\xe3\x80\xcd\x19\x3f\xe2\x76\x1f\xba\x12\xdf\x62\x77\xc0\xb2\x0b\x87\xf5\xb6\x6b\xfb\x3a\x56\x4d\x59\x6c\xdb\xe2\x74\x58\x15\x8b\xef\x6d\x37\x54\x25\x86\x16\x75\xdc\x35\xd5\xf0\x3f\xc2\xb1\x44\xdf\xc4\xdd\x7e\x68\xce\xd8\xee\xc3\x71\x57\x95\x58\xfe\x8c\xc3\xbe\x3d\x0d\x78\xab\xba\xd7\xd8\xf7\xb1\x3d\xe2\xd3\xd3\x9f\xd5\x62\x73\xc6\x97\x70\x8c\x55\x83\xcf\x61\x53\xfd\x0e\xf8\xda\x85\x1e\xcb\x4d\xe8\xca\x76\x5d\xc6\x50\xd4\xb1\x38\xbd\xbd\x16\x55\xbf\x5a\x2c\x00\x60\x3d\xbd\xde\x7f\x88\x59\xc7\xef\xb7\x1f\x02\xb9\xaf\xae\xa7\xab\x91\x08\xdb\x8f\x6e\x2f\x7f\xe0\xfe\x77\xf2\x25\xf7\x84\xcb\x7a\x31\x1d\xbf\xe7\x89\x4b\xea\x75\x0c\x3a\x26\xa8\x7d\x30\x08\x12\xa3\x1c\x08\x49\x73\xe2\x68\x89\x05\xf3\x76\x2f\xb5\x57\xd0\x19\x53\x95\x93\x59\x49\xb8\x64\xbd\x7a\x62\xb7\x9b\xf0\xa7\x20\x20\x88\xa7\x65\x49\x51\x86\x87\xf8\xf5\x5e\x06\xa7\xd4\xe8\x96\x6c\x4a\x92\x49\x23\xe8\x03\x8c\x99\xd9\x01\x18\x4f\xc2\x43\xfb\x46\xe4\x76\x26\xc4\x54\x38\xda\x0e\xbe\x11\xc9\x29\x6b\x51\xbd\x9f\x33\x12\x8f\xe3\x19\x95\x61\xc2\xa5\x4c\x4a\xf6\xb4\x11\xb4\xd7\xa9\xda\x59\x55\xc9\xf8\xe4\x84\xbb\x39\x37\x60\xe6\x88\xa7\x46\x6a\xaf\xa4\x07\x8a\xdd\x97\xef\xd4\x53\xc6\x2d\x92\x78\x7a\xc0\xa1\x2f\x31\x82\x9b\x53\x22\xb2\xd3\x1c\xa7\x10\x70\x11\x53\xcd\xa9\x89\x2b\x30\xfa\x64\xae\x4d\xc3\x79\x2b\x49\x5c\x1e\x48\x9c\x20\xce\xc4\x5e\x1b\x29\x3e\x59\x16\x78\x12\xad\xb1\xd6\x1d\xec\xf0\x89\x8c\x32\xd3\x0e\x84\x2a\x64\xb6\xb8\x88\x7b\xc2\xea\x19\x4d\xd4\xce\x99\xc1\xe6\x34\x2f\xb0\x36\x62\x89\x8b\x33\x36\x08\xe9\x08\x04\x0e\x9f\x32\x6d\xb1\x65\x61\x1c\x77\x0a\xec\xbf\x7a\x9c\x55\x6c\x4e\x79\x36\xae\xfa\x5a\x35\x37\x9a\xc9\x24\xdf\x78\x62\xb3\xca\xe8\xf8\xbf\x78\x12\x57\x58\xc5\x79\xb1\xb8\x39\x8d\xdd\x42\x70\xb2\x7d\xcc\xde\x99\x50\xf5\x9f\x37\xb2\xb3\x05\xbc\x39\xe7\x9e\xb5\x73\x38\x79\x89\x3b\x73\x61\xa2\x76\x0f\x15\x58\xf2\x62\xcf\x7b\x72\x06\x75\xd6\x39\x1e\x33\xb3\x57\x19\x91\xc3\xac\x45\xbd\xc4\xc9\x53\x6b\xd2\xc8\x7d\xab\x58\x7d\x72\x8d\x4c\x37\xfb\x9e\xdc\xf7\x93\xcc\xb0\xc0\x22\x64\xf5\xc9\x51\x70\x36\x80\xb2\x40\xac\xa5\x54\xe5\x99\xaa\x10\x71\x76\x75\xdc\xce\x4f\x3b\x36\x9c\x0a\xea\x70\x33\x22\xf6\x80\xf4\x90\x70\xc4\x48\xcc\x60\x4d\xdb\xfc\x6f\x00\x00\x00\xff\xff\x6e\x78\x13\xbb\x6d\x0f\x00\x00") + +func fonts3x5FlfBytes() ([]byte, error) { + return bindataRead( + _fonts3x5Flf, + "fonts/3x5.flf", + ) +} + +func fonts3x5Flf() (*asset, error) { + bytes, err := fonts3x5FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/3x5.flf", size: 3949, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fonts5lineobliqueFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\xcd\x8e\x1b\x37\x0c\xbe\xfb\x29\x78\xe0\x41\x03\xb4\x56\xbd\xed\xb6\x0d\x10\x2c\x9c\xfe\x9c\x7a\x2b\xd0\x9b\x00\xc1\xe9\xda\xc0\x22\x8b\x4d\xd0\x6c\x0e\x01\xf4\xf0\x85\x48\x51\xa2\x34\x9a\xf1\x8c\xed\x2c\x12\x8f\x38\x92\x48\xf1\x13\xff\xa4\x39\x3d\x9f\xee\x0e\x08\xbf\xc0\x3d\xdc\xfd\x00\xbb\x7b\xb8\xdb\xdc\x3f\x3f\xbd\x1c\x3f\xbe\x7f\xde\x9e\x9e\x4f\xb0\xdb\xd9\x37\x3f\xc1\xa7\x0f\x3f\xff\xba\xdb\x7d\xde\x1f\xfe\x3d\x3c\x6e\x1f\xff\x3b\x7c\x38\x6e\x8f\x8f\x5f\xbe\x83\x2f\x9f\x1e\x0f\xaf\xc7\x47\x80\x9d\x7d\x73\x0f\x9f\xbf\xbe\xff\x71\xff\xee\xb7\x3f\xff\xde\xbe\xfb\x7d\xfb\xcf\x5f\x9b\x3f\x8e\xa7\xa7\x97\xa7\xd7\xe3\xf3\x57\x38\xc0\xfd\xf7\x91\x2d\x9c\x3e\xbe\xbc\x6e\x37\x88\xfb\xa9\xff\xfb\x0d\xf0\x5f\x6a\x20\x37\xd0\x5a\x8c\x8d\xf8\x8c\x6f\xe8\x09\xfb\x0d\xc6\x11\xb1\x41\x34\x80\xcc\xcf\x0f\x0c\x10\xe2\x4c\x44\x9e\x37\x7e\x64\x89\x65\x9a\xcc\x05\xef\x6d\xfc\x17\x97\x26\x4d\x7a\x6f\x01\x2c\x60\x3b\x5e\xb5\x35\x51\x77\x65\xca\x7b\x6b\xbd\x50\x06\xac\x05\x18\x30\xf5\x39\x27\x23\x0d\x0d\x1b\x50\xe6\xc5\x61\x8d\x08\xdd\x30\x03\x24\xa4\x68\x64\x6c\xd0\x8c\xfd\x26\x3e\x4d\x16\x00\x73\x7a\x03\x18\x03\x00\x43\x1a\xed\x5c\xe6\x85\xd6\x39\x9b\xf6\xc4\x5a\x5e\x66\x94\x6a\xbc\xf7\xce\x65\x30\x09\xda\x08\x14\xaf\x25\x81\x0d\xe5\xb7\x96\x3f\x6a\x79\xc8\x2a\x64\x59\x28\x4a\x30\x14\xc6\x00\x9e\x63\x23\x0a\x40\x32\x1a\x6e\x24\x86\x28\xa8\xe0\x34\x9a\x64\x7f\xfa\x0d\x7a\xe7\xd8\x1c\xc0\x5a\x87\x6a\x8c\x0c\x1a\x3f\x89\x3f\x59\x50\x08\x3c\x35\x04\xa2\xf9\x7d\x46\x4c\xe1\x36\x7e\x43\x48\x2a\x9e\xd1\x72\x3b\x4f\xef\x3d\x61\xd7\xbc\xa7\x89\xf2\x83\xf9\x87\x47\x44\x30\x87\x69\x00\x72\x63\xda\xae\x70\xb1\xc5\x7b\xa8\xec\x78\x48\x16\x4f\x84\x05\x2b\x5b\x9c\x08\xda\x66\xef\xbd\x85\xc5\x22\x34\x15\xbd\xcb\x62\x59\x3f\x58\xd5\x97\x08\xd6\x84\x87\x5d\xab\x05\x75\x89\x16\x60\x23\xe5\x05\x23\xb0\x91\xba\x1a\xa8\xd8\x95\x81\xe2\xbf\x01\x86\xe2\x83\xac\xc9\x72\xa0\x12\xfa\x6a\xdd\xb4\x4e\x48\xe8\x83\xc2\x2d\x83\xd8\xba\xdd\xb4\x08\xb1\x46\x50\x71\x2b\xe9\xc4\x0a\x5e\xaf\x05\xa3\x7a\x4e\x84\x60\x78\x81\x08\xde\x0a\x84\x91\x99\x2a\x6c\x6e\x00\x94\x9a\x68\xd5\x76\x1b\xa3\xb6\x3b\xf5\x94\x90\xbb\xdc\x2f\x7c\x0b\x06\x4d\x55\x60\x2c\xd3\xa2\xfb\x4b\x49\xc5\x0c\x58\xc7\xf5\xe9\xa1\x90\xf3\xf5\x28\x59\x83\x84\x3f\x8e\x35\x6f\xdf\xf2\x4b\xe7\x50\xfa\x3a\x61\x35\x3f\xa3\x29\xc4\x48\xe9\xbd\xd5\x4f\x50\x61\x56\x89\xe2\x00\x19\x53\x18\x31\x7f\x78\xc0\x94\x5e\xa4\x4f\xe1\xd8\x36\xf3\x7e\xc5\x3c\x59\x7c\xb3\x98\x86\x29\x88\x9a\x61\xbc\x47\x1d\xa2\x31\xb3\xc8\x54\x82\xa1\x85\x94\x06\x9d\x8b\xf9\x5d\xe4\x39\x97\x2c\xe0\x2c\x6f\x6b\x21\x55\x41\xec\x17\x01\x42\x09\x51\xc0\x04\x3b\x0f\xf7\x24\x47\xa2\x39\xb5\x35\x41\x97\xac\x43\x54\x15\x4e\x48\x46\xc4\x03\x4a\x6c\xcf\x46\x4c\x23\x27\xac\x78\x99\x24\xdd\x5b\xa8\x22\x49\x48\x32\xf3\x29\x49\xad\xa8\x2a\x9c\x34\xc2\x2a\x67\x54\xfe\xaf\xc9\x56\xb3\x15\xaa\xc5\x19\x05\xc4\x1c\x15\x38\x97\xf4\x55\xbb\x10\xc4\x5a\x12\x56\x92\x00\x27\x24\x69\x56\xb7\xd8\xae\x94\x13\x1b\xfc\xae\xd9\xae\x5a\x2d\xa8\xb3\x31\xc0\xe4\x76\xc1\x74\xc8\x16\x97\xf7\xfc\x8b\x75\xec\x6f\xc2\x66\x53\x6b\x34\xc5\x06\x55\x68\x5c\x0b\x74\x25\x4d\xa8\x96\xe5\xa1\xa2\xeb\x2a\xa0\xce\x44\x6a\x71\xa8\x2b\xa8\x4b\xed\x43\x9b\xbd\x57\x55\x15\x8d\x74\xe0\x34\x8a\x91\x5e\x98\xbd\xad\x3e\x44\xcd\x96\x67\x65\x5e\xaa\xa4\x68\x79\x2d\x5a\x63\xfc\x32\xf3\xc0\x8a\xa9\x30\x18\x72\x60\x14\x73\x0c\xac\x7a\x28\x01\x31\xb0\x86\x2a\x2a\x86\x1c\x27\xc7\xe2\x27\xec\x32\x40\x0d\x67\x68\xc2\x48\x68\xc2\x48\x68\xec\x32\xac\xdf\xbc\xda\xe5\xea\x98\x55\x87\xac\x2c\xea\x42\x33\x99\x89\xfa\xd1\x6c\x70\x6d\x18\xb9\x55\x2c\x8e\x46\xa9\x35\xf3\x6c\x95\xb7\x52\x0d\x0c\x28\xd5\xa2\x7d\x28\xd5\xa2\x71\x5c\x26\x89\x8e\xdd\x7a\x70\xba\x07\xa8\xea\x64\xcc\x4a\xe5\xdd\x9b\x2d\x00\xc8\x63\x3d\x17\x43\x8d\x9f\x69\x37\xd3\x5e\x96\x1c\x73\x1d\x5e\xca\xc4\xaf\x36\xba\xaa\x19\x42\xe6\x1e\x42\xe6\x1c\x42\xe6\x1a\x42\xe6\x18\x60\xc2\x84\x3b\x86\x95\xf8\x86\x9a\xb9\xf8\x9f\x48\x10\xe6\x22\x86\x07\x89\x2c\x1a\x3e\xbf\x7c\xbe\x40\x11\x70\x1c\xe4\xb8\x5d\x42\xb6\x05\x1b\x77\x5a\x76\x21\xd6\xbb\x7a\xb9\x75\x9b\x6d\x22\x31\x74\x4e\x41\xed\x9c\xca\x02\x2a\x3d\x4d\x20\x8c\xe9\x6c\xc3\xb7\x32\x2a\xbf\xd8\xf1\x12\xb1\xb0\x93\xfc\x35\x57\x20\x53\xaa\xc4\xb1\x96\x8d\xad\x91\xa5\x35\xc7\xe2\xfa\x89\x49\x61\xa9\x7f\x51\x0e\x04\xdc\xdf\x20\xd5\x34\x59\x41\x2c\xd9\x86\x9b\x28\x87\x1f\x41\x26\x65\xe5\xde\x32\xe8\x50\x00\x94\x35\x54\xf6\x28\x4c\x21\x81\x07\xcd\xe5\x0c\x2e\x78\x7a\x2a\x7f\xe4\x72\x26\x9d\x7c\x30\xea\x8b\xa9\x95\x3b\x66\x1d\xbc\x25\x74\xe1\xa8\xc2\x8b\x76\x4b\x72\x3c\x03\x66\x94\xa8\xcf\x10\x16\x16\xf2\xee\x9d\xaf\xaf\x59\x77\x1a\xc6\xb1\x7c\x79\x20\x97\x3f\xd4\x12\x2c\x6a\x19\x3a\x47\x89\x11\xcc\x65\xc3\x55\x5a\x78\xef\x57\x69\xd1\xa3\xd4\x85\x00\xdd\x05\x7b\x40\x85\x12\xca\xc8\x42\xa4\x44\x84\xc2\x65\x3a\x94\x34\xed\xb2\x74\x85\x7f\xb9\x21\xa0\xf7\xe4\x51\xdf\xc0\x6a\x14\xfe\x73\x57\xba\xd2\x32\xe9\x7c\x9c\x3d\x58\x15\x4d\x6b\x6e\x5e\x1a\x2a\xb3\x05\x15\x1c\x84\x80\xb4\x79\x13\x27\x85\xd9\x36\x55\x0d\x62\x77\x5c\x31\xab\x4a\x25\x97\x0e\xb1\x4a\x99\xb9\x89\x95\xfc\x9a\x2f\x49\x12\x97\xee\x27\x90\x09\x5d\xa7\x68\x5f\xdd\x43\x59\xcb\xa7\xf4\xb2\x53\x16\xac\xde\x2c\x21\x57\x7b\xf9\xc5\xb6\x70\xc3\xc8\x77\x53\xde\xc5\x3d\x92\x8f\x2f\xba\xef\x59\xc2\xbb\x72\x3d\x20\xf3\x1c\x45\xec\xf9\x76\xcd\xb7\x0d\x45\xb4\xe2\x6e\x9d\xb7\x62\xc1\xfc\xa9\x48\x2a\xd8\x74\x18\x14\x30\x52\xb9\x3a\x5f\x29\x70\x33\x55\xa9\x98\x8b\x0d\x1c\x55\x0a\xa3\x2f\x3e\x4b\xcc\xad\x10\xba\x4a\x3d\x9f\x0c\xcf\xb5\x82\xae\x1b\x73\xc5\xd8\xbd\x57\xee\xf8\xdc\xc2\x17\x72\xfd\xa7\x97\xad\x1d\x31\x2e\xdd\x80\xe9\x58\xf4\xd9\x96\x2a\x4a\x9d\x3a\xdc\x58\xb7\xb6\xdc\x98\x40\x78\x64\xbc\x0b\x97\x88\xd9\xb6\xb0\x5c\x53\xab\x03\x04\x17\x8c\xe7\x4c\x2a\x5f\xd3\xa4\x1b\x5d\xa0\xcb\xe4\xfc\x15\x50\xae\x1d\x8c\x51\xc5\xe7\x5e\x8a\x2e\xda\xd3\xd1\xcf\x44\x58\x2e\x15\xe6\x30\xd4\xf1\x19\x1e\x1e\xe4\x0e\xf7\x7c\xb4\xf1\x65\xdd\xd6\x46\x37\xf2\x79\xe5\xf4\x0d\x4f\xe6\x54\x44\x66\xd0\xe5\xed\xc1\x77\x37\x6c\xd5\x75\x70\x7b\xcd\x51\x31\x2f\x21\xfd\x5b\x7c\xd8\xab\x44\xe8\xbe\xea\xb8\x79\x89\x88\x6e\x5a\x52\xd2\x6e\x5d\x41\x5f\xc2\x7b\x69\x8e\xea\xa0\x74\x36\xd8\xf5\xa3\x54\x97\x1c\x5f\x85\x68\xa7\x24\x5d\x8c\x14\x33\x51\x35\xb9\xa0\xc8\x49\x26\xa1\xff\x7f\x00\x00\x00\xff\xff\xf8\xbb\xf0\xab\x69\x22\x00\x00") + +func fonts5lineobliqueFlfBytes() ([]byte, error) { + return bindataRead( + _fonts5lineobliqueFlf, + "fonts/5lineoblique.flf", + ) +} + +func fonts5lineobliqueFlf() (*asset, error) { + bytes, err := fonts5lineobliqueFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/5lineoblique.flf", size: 8809, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsAcrobaticFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x5b\xef\x6e\xe3\x36\x12\xff\xee\xa7\x18\x04\x04\xda\xe2\x76\xab\x4d\xae\x05\x6e\x0b\x41\xd8\x02\x77\xf7\x00\xf7\x99\x80\x4e\xb1\xe5\xc4\xa8\x63\x16\xfe\xd7\x2d\xa0\x87\x3f\x90\x9c\x19\xce\x50\x74\x2c\x25\xd9\xee\x02\xe7\x00\xb1\x48\x53\xe2\xfc\xe3\xcc\x6f\x86\xd4\x7a\xbb\xbe\xeb\x0c\xdc\xde\xc1\x47\xb8\xfb\x19\x3e\xc0\xed\xcf\xf0\x61\xf1\xeb\x72\xef\xee\xbb\xe3\x66\x09\xf7\x7f\xc2\x7f\xba\xdd\x2a\xfc\x3f\xb8\x27\xf8\x47\xf5\xf1\x27\xa8\xf7\xa1\xf1\xe9\xb0\x5c\xff\x78\x3a\x2c\x7f\xec\x57\xa7\x66\xf1\xef\xcd\xc3\xb6\x3f\xc2\xbe\xdf\xf6\xdd\xa1\x87\xbb\x1f\x6f\xe1\xfd\x7b\xf8\xf5\xf4\x70\x3a\x1c\xe1\xf6\xee\x1d\xdc\x7e\xfc\xf8\xd3\xe2\x9f\xdd\xb1\xff\x05\xee\xfe\xee\x7f\x88\x3d\x8b\x7f\x7d\xfe\x7d\xdb\xed\xba\xe3\xc6\xed\xc0\xad\x61\xbd\xd9\x1f\x8e\xb0\xdd\xec\xfa\x5f\x16\x9e\x3a\x78\x0f\x37\x4f\xdd\xc3\x66\x09\xbb\xd3\xd3\x7d\xbf\xbf\x81\xb5\xdb\xc3\x7a\xb3\xed\x61\xb3\xea\x77\xc7\xcd\x7a\xb3\x0c\x37\x2f\x3a\x00\x80\xf7\x70\x78\x74\xa7\xed\x0a\xba\xed\x1f\xdd\x9f\x07\xb8\xef\xe1\xbf\xdd\x77\xef\xc2\x4d\x3b\xf7\xc7\xc2\xc4\x41\xc7\xc7\x1e\x6e\x1e\xbb\xfd\xea\x7e\xdb\xed\x7e\xbb\xf1\xa4\xfe\xbe\xdf\xec\x8e\x07\xe8\x0e\xd0\x41\xe8\x7d\x07\xf7\xa7\x23\x2c\xbb\xdd\x77\x47\xff\x98\xc3\xd3\xe9\xf0\xd8\xaf\x16\xb7\x77\xe1\x09\x8f\xfd\xe6\xe1\xf1\xe8\x29\xee\x60\xf9\xd8\xed\xbb\xe5\xb1\xdf\x2f\x3e\xc2\xe5\x1f\xdf\xc1\xce\x1d\x61\xb3\x5b\x6e\x4f\xab\xcd\xee\x01\x56\xfd\x61\xd9\xef\x56\xfd\xfe\xb0\xb8\xfb\x39\xdc\xf6\xd4\x7d\x0e\x9c\xc3\xb6\xdf\x3d\x1c\x1f\xe1\xfb\xfe\x33\x0d\x5e\xba\xa7\xa7\x7e\x17\x05\x73\xf8\x01\xfe\x06\x1d\xac\x4f\xab\x87\x1e\xd6\xdd\xf2\xe8\xf6\x8b\x0f\x71\xe2\x55\xbf\xee\x4e\xdb\x63\x24\xf6\xc9\xad\xfa\xc0\xf8\xf1\x71\x73\x80\xb5\xdb\x1d\xe1\xfb\xed\xe6\xb7\x1e\x6e\xde\x3f\xc1\x87\x1b\x70\xbb\xf0\xd8\x6e\xb7\x0a\x8f\xfd\x61\x71\x1b\xc9\x88\x82\xf6\xd4\xab\x59\x69\x8e\xfd\xd1\x6d\x17\x0b\x63\x8c\xf9\xf4\xfa\xff\x9f\xbc\x46\x1c\x80\x6f\x43\x3d\x34\xf1\xa2\x02\x1b\x2f\xac\xab\xe2\x05\x0c\x34\x06\x70\x8c\xff\x18\x79\x7b\x5b\x0f\x4d\x6b\x3e\x2d\x20\x7e\x0a\x17\x7e\xb4\x03\x7f\x83\x1f\xef\x67\xab\x87\x26\x5c\x42\xe3\x1f\xcc\xcf\x05\x78\xf9\x25\x40\x3e\xaf\xbe\x24\x6e\x20\xf1\x14\x88\x4a\x7c\xb4\x43\xd3\x42\x5b\x0f\x6d\x6b\x66\x0f\xae\x5d\x03\x10\xfe\x97\xee\xf5\x72\x05\x92\x2e\xc8\xcf\x95\xa6\x6c\x5f\xbe\xf6\x52\x18\x5a\x47\x74\x57\x00\xa4\x47\xb0\x4e\x48\xea\x6c\x85\xd4\x6a\x8b\x9c\x58\xd7\xb6\x55\xea\x1f\x32\x71\xea\xb9\x48\x95\x51\x16\x15\xe9\x33\x7c\xaa\x33\x90\x52\x43\xb3\x91\x2a\x72\x95\x52\x59\x75\x56\x2a\xac\x1a\xa9\xd2\x38\x96\xec\x85\xc6\x92\xd1\xd0\x58\xb4\x1c\x78\x4e\x80\xe3\xb6\xef\x30\x7e\x06\x94\x0c\x8e\x31\xb5\xe7\x3b\x72\x62\xb0\x0b\xac\x85\x0a\x49\x31\xb1\xcb\x55\x2d\xb4\xf1\xce\xc0\x3c\x18\xfc\xdd\x2b\xb8\x3a\xfb\x51\x82\x3e\x5b\x35\xe1\x59\xc6\xf2\xfc\x95\x75\xb1\x8b\xa5\xe8\xbc\x5e\xc2\xe3\x4d\x6d\xdb\x16\xda\x36\x3c\xa0\xb6\x23\xde\x0a\xec\x5c\xe8\x42\x29\x92\xf4\x48\x6a\x24\xed\x19\xdf\x7a\x0e\xfe\x8e\x17\x06\xa2\xcd\x85\x4b\x3f\x0f\xca\xad\x6a\x50\x86\xc6\x6b\x32\x8a\x38\x08\xd8\xe0\x43\x8c\xb5\x42\xf4\x60\x59\xe6\x10\xe4\x62\x70\xa2\x20\x90\xcb\xb6\x98\xd9\x65\xdb\xba\x34\x81\xb7\xf5\x34\x41\x6d\xc5\x04\xe0\x55\x40\x0c\xc0\xd0\x10\x03\x50\x55\xc4\x00\x54\xc4\x40\x30\xc2\xc8\x80\x57\x8c\x79\x96\x88\x7c\xa1\x58\xd6\x31\x79\xd3\x73\xb4\x04\x6f\xd1\x28\xe4\xda\x92\xf9\xf3\x02\xb4\xae\x1a\x48\x0d\xad\xf5\x6c\x0d\x5e\xd0\x55\xcb\x23\x2a\xb0\x83\x50\x54\x58\x2f\x61\x32\x74\x00\x71\xc1\x9c\x2d\xb9\x9f\x64\x91\x23\x07\x54\x30\xa0\x71\x47\x5a\xc5\xf1\x8b\x97\x31\xad\xfd\xd4\x01\x59\x47\x74\x7d\x92\x19\xd0\xcc\x80\x85\x2a\x7b\x86\xcb\x9e\x81\xde\xb4\x38\xcb\x4b\x98\xc9\x7f\x9a\x76\x61\x92\x47\x22\x57\x04\x29\x7a\x91\x8a\x71\x19\x18\x5c\x03\x33\xc3\x59\x90\x50\x2b\x65\xf3\x36\xa1\x4f\x76\x3d\xff\x65\x52\x94\x46\x67\x6e\xca\x23\xd3\x04\xe4\x6b\x52\x33\x7a\xc2\xd4\x6c\x0c\xdf\x17\x7c\xaf\xe1\xe7\xa0\xc0\x80\x57\x67\x94\x1b\xad\x5c\xf2\x1f\xb8\xaa\xc3\xba\x49\x0a\x09\x3e\xad\xc0\xf0\xb4\xb6\xf0\x61\x20\x7d\x07\x12\x05\x71\x05\x25\x27\xa2\x56\x51\x72\x6f\xfc\x89\x6e\x25\x06\x92\xf4\x89\xfe\x25\x38\x3c\xfe\x24\x47\x23\x02\x83\x76\x81\xe1\xe3\xa4\xa0\x38\x38\x8c\x7c\xd0\x45\x16\x9f\xe9\x44\x7f\xc9\x58\x26\x47\x7b\x6e\xd4\x03\x79\x8f\x82\x42\x57\xf0\x9f\xe7\xaa\x6d\x1d\xbb\x67\x2f\x38\x1f\xf5\xa2\x1a\x87\x28\xd5\x18\x18\x63\xc4\x0d\x46\xa2\xc0\x82\x86\x0a\x1a\x28\x28\x98\x40\xe1\x2e\xac\xa4\xaa\xcd\x7c\xc4\xb3\xad\x28\x7f\x34\x08\xd6\x3c\x1b\x03\x6a\x5d\x18\x42\xa2\x11\x80\xfd\x3c\xdb\x64\x5b\x0f\x90\x8d\xc0\x15\x2d\xac\x81\x6e\x91\x4a\x8f\x88\x44\x28\xfc\xa5\x4e\x9b\x30\x6b\xc2\x69\x04\xa2\x82\x07\xad\xc1\x06\x6a\x90\xe3\x00\x18\xec\x10\x1a\x83\xe4\x24\x36\x62\xab\x76\x29\x62\xf2\x2f\x18\x34\x33\xcc\xf2\x4c\x23\x10\x17\x67\xf5\x4a\x42\x02\x83\x98\xe3\x08\x89\x24\xb9\x23\x60\xd5\xb6\x4d\x1d\x51\xa4\xb9\xd7\x94\x92\xd6\x4b\xec\x4b\x49\xfa\x25\x66\x43\x61\x2e\x31\xe3\x25\x0f\x92\x99\xe1\xab\x30\x43\x51\x88\x4d\x22\xf2\x01\x01\x79\x28\x21\x57\xca\xbc\x1d\xfa\x30\x6c\xa3\x63\xe7\x45\xdc\x90\x87\x25\xc8\x42\x7e\x1e\x11\x0b\xfb\xf9\xe8\x6a\xcd\x05\x0a\xa7\xf9\xf5\xf9\x8b\x38\x03\x6b\x60\xc0\x67\x78\x72\x11\x57\x5f\x45\x1b\xaf\x63\x26\x2e\x50\x03\x36\x30\x13\x01\x58\xb6\x4e\x86\xbf\xd2\xb4\x4a\xe8\xc2\xa4\xc5\x2c\xbf\x66\xe0\x10\x1c\x1c\xd2\xb8\x06\x2f\xf0\x06\x43\x10\xa9\x74\x71\xf9\x2e\x17\x43\xb4\xf1\x48\x26\x42\x0d\xa3\x30\x43\x95\xd2\x9e\x94\xf5\x24\x54\x90\x72\x1e\x99\xf2\x88\x8c\xc7\xa5\x68\x8f\xd9\x1f\xc4\x44\x65\x6a\x25\x23\x7c\xe6\x02\xc9\x19\xf0\x72\x02\x11\x56\xe4\x5b\x12\x29\xa9\x6c\x4b\x26\x5b\x29\xd7\x62\x04\xe4\x38\xd3\x4a\xee\x22\x79\x8a\xeb\x44\xa8\xc5\x41\x10\x11\x28\xa5\x56\x0b\x43\x5a\xbd\x53\x7e\x0c\x53\x64\x6a\xa9\xba\x85\x16\x8d\xaa\x62\x84\xea\x4f\x21\x0b\xb9\xd2\xcc\x70\xa7\x29\xa0\x4e\x53\xc0\x9c\x46\x20\x4e\xbc\xb5\x49\x51\xb3\xc6\xa8\x5d\x25\xb4\x59\x83\xd4\xe6\x78\x81\xe7\x48\xb3\x80\x33\x0b\xd8\x71\x62\x97\xc8\x0e\xdc\x18\xa2\x87\x05\x97\x75\x62\xf5\x51\x75\x1a\xcc\x6c\x8d\xe8\x34\xc4\x6a\xa3\x00\x3b\x3e\x4d\x98\xa1\x00\xe7\x36\xb3\x0e\x60\x39\x4b\x1b\x61\x49\xbf\x01\xb8\x06\x69\x95\x94\x13\xd0\x84\xa8\x8a\x1a\xc1\x57\xa4\x13\x4d\x32\x62\x80\x1a\x9d\x32\x01\x80\x30\x92\x01\x43\x25\x7f\x8b\x6e\x32\x3c\x33\x6a\x6d\x2e\xde\x05\x4d\x6c\x6e\x89\x63\x43\x1c\x65\x3e\x26\x4f\x7b\x0c\x8c\x72\x9e\xb1\x11\x16\x6c\x70\x6c\x82\x63\x01\x4f\xea\x11\x1a\x60\xd4\xc1\x4a\x60\x3f\xc3\x7a\x40\xdc\x62\x99\x2b\xcc\xe5\x04\x00\x23\xd8\x4c\x0c\x44\x0f\x96\x6e\x61\xec\x93\xd4\x22\x66\xb9\x9c\xb7\x4d\x0d\x9b\x09\x2b\x67\x50\x39\x62\x49\x46\xca\x9a\x0a\x46\x60\x11\x65\x27\x04\x96\xfd\x9e\xb0\x68\x76\x3f\x3e\x3f\x32\x61\x4b\x09\xd5\x24\x44\xf6\xa5\x18\x60\x08\x19\x19\x10\x10\x72\x00\x5d\x2a\x48\xbe\xe5\xf5\xa5\x82\x62\xa5\xa0\x58\x28\x28\xd5\x09\x40\x97\x09\x52\x4c\xd6\x2b\x66\x28\x3b\xee\x62\x8d\xa0\xe0\xba\x8b\xae\x69\x72\x9f\x2a\xf3\xab\xfc\x11\x52\x0e\x99\x74\x46\x38\x4e\x2c\x17\xc4\x70\x41\x6b\x02\x76\xe6\x23\x92\xe1\xc5\xbc\x72\x3c\x42\x2c\xb9\x3c\xbf\x2c\x92\x5f\xce\x68\x12\xec\x91\x7b\x32\x11\xf8\x3e\xb3\xd7\xf5\xb2\x5a\x07\x44\xdb\x63\xbd\x02\xdb\xe2\x00\x22\x5f\x56\x5b\x42\x68\x9c\x48\x8c\xa8\x6b\xe1\x2d\xdc\x66\xe2\xec\x68\xc4\x17\x2c\x21\xc0\x78\xbb\x87\xf7\x3b\xc8\x0c\x78\xb7\x83\x72\x47\x5e\xbc\x5c\x52\x00\xed\x7e\xec\xc8\xff\xf0\xf6\x08\x9b\x41\x16\x34\x2f\x44\xe8\xe9\xd9\x47\x1a\x10\x58\xc9\x7c\x84\x70\x21\xd1\xb5\xa7\x24\x55\x78\x1c\x41\x8f\x01\x1d\x3a\x72\xf2\x99\xf8\x0b\xde\xf3\x2a\x58\x94\x1a\xe0\x95\xc8\xb2\xa8\x38\x2e\xd1\xae\x54\x05\x0c\x2b\xce\x61\x53\xca\xdb\x14\xaf\xac\xda\x06\xef\x94\x2f\x2d\x10\x77\x01\x69\xa2\xca\xd6\xe3\xa5\xbb\xe0\x9a\xe8\x2f\x46\xe8\x67\x18\xab\x33\xc6\x14\x89\xb8\x8d\xa2\x19\x1b\x93\xe8\xef\xcc\x18\x3b\xdb\x11\x63\xb5\x1d\x33\x56\xbf\x86\x31\xf8\xbf\x2e\x2b\xbf\x1a\xf9\x6a\xed\xa8\x52\x99\xc9\x57\x22\x3f\xb3\x40\xfd\x1c\xe4\xfb\x55\xb5\x64\x5d\x49\x4b\xc3\x48\x4b\x40\x19\xd2\xdb\x6a\x09\x20\xd7\x14\xe4\xf8\x98\x9c\x9e\xd0\x18\x08\xd7\x8e\x35\xb2\x0c\x5a\x8e\x9d\x7b\xc1\xbb\x17\xdc\x7b\x39\x03\x9b\xbe\xf6\x66\x57\xcb\xbe\xd9\xaa\xb2\xf1\x64\x31\x70\x46\x52\xe2\xe9\x0e\x7d\xca\x03\xd0\x8a\x88\x83\x54\xb7\x8f\x3d\xc0\x88\x02\x31\x9b\xd8\x0d\xc7\x51\x72\x4b\x2e\xee\xf3\xca\x25\x65\x80\xb7\xef\x53\xc2\xee\x5d\xeb\x25\x55\x4c\xaf\x13\x4c\x00\x9a\x39\x04\x54\x89\x5a\x1e\xa5\x06\x28\x63\xd3\xbf\xac\xbe\xa9\x3e\x39\x47\x92\x2d\xb5\xbd\xc1\xc7\x59\x8c\x55\x8f\x70\xe4\x2e\xce\x72\xcf\xe8\xcc\x0a\xac\x53\x30\x6e\xa4\x0e\x09\x0e\x64\x6a\x44\x48\x90\x69\x32\xc2\x82\xcb\xca\x9c\xdb\x3b\x53\x10\x72\xf1\x17\xb1\x08\x94\xf1\x08\x14\xd4\x1d\x9f\xab\x44\xe9\x2a\x3e\xb1\x93\x44\xe9\x9d\xc2\xd9\x66\xa2\x8c\x9e\x01\xcf\xed\xbc\x91\x20\xc4\xbe\x82\xc1\x4a\x29\x40\xda\x22\x37\x78\x00\x44\x56\x4c\xf5\x06\xf9\xa0\x83\xd3\xa8\xc4\x95\x17\xb7\x8a\xa5\xcf\xe7\x88\x2d\x60\xce\x37\x25\x3a\x79\x0a\x6c\x5a\x8e\x1f\xd7\x07\xcf\x20\xfa\xca\xb6\x55\x82\xfe\x95\xf4\x88\xa0\xa2\xaf\xd8\xb6\xc2\x66\xc3\xee\x52\x6e\x38\xa7\x6d\x2b\xec\xa0\x6d\xab\x57\x15\x49\x80\xe2\x4d\xfd\xba\x2c\x15\x8f\x25\xe6\x53\xc9\x2c\x35\xa8\x58\x56\x44\x82\x8e\x65\x51\x36\x28\x59\xfa\x84\xe0\x54\x54\x29\x96\x30\x92\x08\x13\x16\x8c\xf2\x2c\x62\xab\x03\x3b\xd2\x7e\x07\x76\x14\xe2\xfd\x14\x69\xf1\xf9\x85\x70\x6e\xef\xcb\xe6\xf4\x86\xbc\x08\x9f\x34\x38\x5b\x3a\x67\x30\xda\x5d\x78\xe5\x75\x99\x6b\x75\x2d\x1a\x2f\xbe\xbc\xb4\x71\xd4\x26\xd4\x93\x43\x0c\x7d\x49\x36\xe4\xfb\xce\x34\x2c\x49\x62\xc6\xb7\xa6\x8e\xbf\xe7\x39\x00\x09\xfd\x62\x6d\x99\x1c\x22\x1e\x65\x40\x87\x88\xd1\x85\x42\x8e\x45\x0f\x47\xf1\x8a\x8e\x3a\x44\xc4\x5d\x48\x70\x27\x26\xec\x12\x58\x37\xb2\x8e\x50\x31\x02\x53\xc5\x12\xa3\xd0\xf3\x99\x0e\xc3\x08\x08\x9e\x55\x9b\xb3\x5a\x73\x56\x69\x9e\x4b\xf4\xa5\x1f\xc7\x0d\x23\xea\x5a\xd1\xe5\xc5\x12\x96\x91\x87\x71\x6a\x89\x3c\x39\xff\x89\xf7\x04\x0f\x59\x57\x33\x8e\x8a\x00\x30\x2c\x15\xd5\xb3\x7a\x90\x07\x51\x28\x63\x57\x26\xa0\x2c\x20\x33\x00\xa5\xff\x4c\xfd\x17\xb5\x3f\x21\xa7\x9c\x2a\x73\xa2\x15\xb0\x36\x9a\x36\xa7\xf4\x31\xe7\x2a\xea\x9a\xf1\x1c\x02\x7c\xc4\x30\xde\x72\xd0\x5e\xc3\x91\xa7\x6a\x74\x24\x7a\x82\xea\xe7\x6c\xa1\x26\x74\x8a\x3b\x24\x4d\x4b\xea\x11\x16\xa9\x33\x3f\x9d\x1a\xea\xfc\xb2\x0c\x3a\xe7\xd8\xeb\xd5\xb4\xff\x2d\x4c\xc2\x47\x36\xaf\x2c\xfd\xb6\x02\xfe\xe6\x30\x79\x44\x8c\xcb\xa7\xb8\x4d\xe6\x0d\xb4\x33\xd0\xbe\x40\xbb\x02\xed\x09\xae\x56\x4e\xe2\x4f\xaa\x8a\x35\xdb\x76\xc7\x2f\x74\x44\xa2\x55\xac\x9c\xf4\xaa\x88\x7e\xcf\xa1\x18\x4f\xe3\x05\x3f\x17\x9b\xfa\x4d\x12\x9e\xbe\x3c\x98\x48\xa1\x1f\xc5\xac\x46\x16\xd2\xb3\xca\x7b\x6c\x21\x1a\x60\xbc\x83\xa4\x0b\x45\x82\xd4\xa4\x49\x8e\xdd\x08\x3d\x4a\x1f\x9d\xfc\x73\x52\x0a\x17\xc8\xd3\x8b\x00\xae\x92\x35\x10\xa9\xdc\xc9\x47\x3f\xd4\xb9\x98\x94\x2b\xe1\xa4\x57\x3a\xe5\x13\xe9\xab\x90\xbb\x4c\xed\x62\x9b\xa5\x32\x5a\x32\x47\xfc\x2f\x12\x3c\xfe\x9f\x4c\x98\xff\x8f\x6f\x84\xf2\x8d\x2f\x25\x75\x72\x88\x63\x96\x14\x33\x9a\x0d\xc5\x80\x22\x3d\x1f\x36\x6d\xd2\x97\x45\x8e\xa9\x1e\x9b\xef\x54\x6e\x0d\x83\xe9\x33\x9b\xed\x6f\x05\x1a\xbc\x44\x73\xbf\xa6\xdd\x9a\xf6\x6a\x52\xa2\xe9\x74\x03\x91\x48\xc3\x4c\x16\x52\x54\x40\x19\xd9\xf4\x94\x76\x8a\x13\x4a\xaa\x03\xad\xf3\x14\x2b\x00\x74\xb4\x00\xd0\xf1\x22\xde\x9f\x22\x06\x88\x74\x93\x7f\xe7\xfc\x13\x40\xbc\x8f\x02\x10\x5f\x7a\x79\x3b\x7b\xc5\x90\x45\xd2\x35\xba\x84\xae\x2a\xe8\x2f\xb2\xd7\x6b\x0d\x23\xf6\x41\x4d\xc2\x8b\x80\xe5\x19\x4e\xc5\xcf\x36\xe5\xd9\xe9\x38\x38\xa1\xc5\x39\xc4\xa1\x2a\x52\xc1\x29\x95\x88\x92\x8c\x0c\xef\x4f\x67\x7d\xe2\x57\x20\xb4\x15\x54\x29\x96\x73\xf1\x6a\xe6\x2a\xce\x56\x22\xd7\xc6\xb2\xea\x60\xbe\xb7\x3e\xc0\x78\x15\x23\x3a\x41\xd0\xf1\xc5\xa0\x14\xcf\xaa\x08\xd6\xf4\xe6\xa5\x37\x55\x72\x53\xa5\xb6\x71\x89\x6d\x0e\xba\x2e\xb3\x73\xa5\xf7\xed\xca\xb3\x5f\xb5\xa6\x58\x1e\xa2\xaf\x8d\x7a\x4b\xf1\x6c\x55\xf1\x8e\x53\x44\xc3\x78\x24\xba\x3b\x15\x41\xb2\xba\xcc\xc5\xeb\xaf\x6f\x42\xf4\xc6\x1e\xb9\x8f\x54\xa6\x4a\x6f\xed\x4d\x2b\x9b\xd0\x66\x10\xc1\x5f\x2c\x15\x1a\x50\x07\x55\x55\x44\x88\x41\xa9\x49\xa7\x78\x00\x20\x7b\xd3\x57\x43\x38\x48\x2f\x4e\x86\x4a\x1f\x16\x13\xeb\x81\xe2\x48\xc5\x20\x93\x4f\x50\x58\x7a\x59\xc6\x7b\x00\x3e\x65\x8f\x3b\x17\x79\xc1\xef\x92\x7b\x9a\x0e\x13\x27\x77\xa6\xf7\x2e\xf1\xc8\x3c\x19\xd6\x90\x8a\xc3\xe2\x08\x30\xa7\xec\xbc\x0b\x3a\x00\x4b\x18\x45\x19\xeb\x71\x65\x1e\x14\x37\x88\x3b\xc3\x87\x92\x39\x9b\xea\xaf\x72\xd7\x0e\xbe\xbd\xf6\xa7\xc5\x85\xbf\x6f\xf5\x87\xff\x05\x00\x00\xff\xff\x10\xbf\x87\x51\xb4\x42\x00\x00") + +func fontsAcrobaticFlfBytes() ([]byte, error) { + return bindataRead( + _fontsAcrobaticFlf, + "fonts/acrobatic.flf", + ) +} + +func fontsAcrobaticFlf() (*asset, error) { + bytes, err := fontsAcrobaticFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/acrobatic.flf", size: 17076, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsAlligatorFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x4d\x6f\xdc\x36\x10\xbd\xeb\x57\x0c\x20\xde\x54\x04\x88\x5d\xd4\x08\x51\x14\x6a\x8f\xbd\xf6\x17\xd8\xad\xd3\x06\x75\x13\xc0\x4d\x0e\xfe\xf7\xc5\x8a\xe4\xcc\x7b\x33\xd4\x7a\x65\xd9\x40\x0f\xda\x0d\x16\xa2\xb2\xcb\xf9\xe0\x9b\x37\x1f\xf2\xc7\x87\x8f\x57\xb7\x49\x6e\xe4\x46\xae\x7e\x90\xeb\x2b\xb9\x1e\x7e\x7e\x78\xf8\xf4\xe7\xed\xd7\x2f\x8f\x72\xf7\x24\xbf\x7d\xfa\xe7\xcb\x67\xf9\xe5\xf1\xf6\x8f\x87\xfb\x27\xf9\xf1\xdf\xa7\xbb\xeb\xf9\xf6\xee\xfe\xf1\xdd\xed\xef\xef\xbe\xfd\xfd\xd3\xf0\xfe\xe6\xeb\x5f\xf2\xeb\xb7\xcf\xf7\xdf\xc9\xfb\x0f\x1f\xbe\x1f\x86\x34\xc7\x7f\xf3\x20\xcb\x2b\xe7\x9c\xea\x75\x9e\x72\x92\x72\x3d\xe5\x29\x49\xb9\x9e\xc6\xd3\xe5\x72\x5d\x2f\x4f\xd7\x49\x52\xf9\xfd\x3c\x8c\xe3\xd8\xae\x61\x53\xb7\x31\x6e\x5e\xbe\xdd\x36\x85\xe5\xb2\x86\x65\x11\x64\x4b\x99\x07\x5a\x9a\xc0\x45\x62\x31\x46\x54\x89\x29\x37\xa3\x8a\xf6\x99\xde\x55\xb9\x69\x9c\xd4\xde\xd3\xf7\xa6\x91\xde\xf5\xb7\xe3\x34\xca\xf2\xa9\x8a\xc8\x38\x2e\xb7\xd4\x78\x50\xa6\xe8\x51\x15\x51\x89\xa9\x2a\x01\xc2\x16\xf1\x53\x9e\x4c\x50\x51\xa8\xad\x55\x0f\xfd\x3e\xc8\x5b\x04\x92\xdd\xde\x62\x33\x4c\xb7\xd6\x8d\x74\xe1\xec\x63\xcb\xc8\xc1\x19\xdd\x0b\xb2\x4c\x14\x8b\x2b\xc6\x89\x4c\x65\x5b\x35\xad\xd8\x73\x12\xd4\xa4\xaa\x5a\xa3\xbe\x92\x07\x94\x81\x49\xad\x4b\x66\x4d\x32\x5b\x92\x9d\x51\xd2\xb3\x19\x12\xb9\xcd\x6d\x4a\x20\x69\x9b\x82\x83\xf4\xb2\x9c\xc9\x33\xd0\x4f\x80\x40\xbd\x36\xc4\x95\x8d\xf1\x44\xea\x09\xa4\xd5\x4d\x93\x86\x41\x22\xf7\x07\x11\x78\x00\x0a\xad\xd3\x67\x0a\xe8\x12\x38\x02\x14\x0f\xb2\x02\xae\x93\xc0\xe9\x36\xb7\x09\x9a\xa8\xfe\x02\xd1\x0c\xbe\xfa\x7d\x73\x63\x8d\x7a\x3d\x1f\x32\xbb\x5e\x9e\xfe\xbb\x91\x47\x52\xde\x48\xfc\xe3\x62\x8e\x7a\x31\x3a\xd1\x5e\xb6\x2f\xdc\x23\x7a\xd2\xdf\x34\xe4\xa2\x2f\x81\xa8\x60\x6f\x65\x2b\x94\xd7\x28\x8b\x74\x78\x25\x0b\xab\x89\x70\x40\xe2\x10\x28\x9e\x0f\xe8\x98\xea\x9a\x0f\x06\xd6\x8c\xcc\x76\x07\x29\x48\x1c\xf4\x33\xc5\x14\xe2\xf3\x04\xce\x2a\xbb\x82\x13\xd3\x4c\x5d\xb6\x54\xc3\x74\xbb\x88\x1c\x3b\x61\xe1\xb3\x17\x90\x11\x66\x30\xca\x61\x8e\x05\xd5\x38\x16\x12\x78\x2f\xbb\xc0\xb3\xb8\x4b\x5e\x5c\xf2\xe4\x9a\x2e\x71\x29\x99\xe8\x5d\xca\x3e\x35\xe1\x09\x6c\x6d\x90\x5c\x40\x9a\x08\x8e\xce\xaf\xd1\xb1\xe7\x3d\x4b\x08\x6a\x24\xa3\x87\x58\x85\x63\xce\xac\xbf\xab\x62\xca\xca\x7b\x36\xe7\x75\xdb\x04\x10\x03\x95\x02\xe6\xca\x8e\x79\xd1\xbe\x68\xe0\xc5\x9e\x45\xe1\x41\xb6\x02\x76\xa3\x67\x33\x1b\x8d\x1c\x6e\xf1\x19\x52\xa8\x01\x09\x71\x04\x54\x60\xa6\x22\xa8\xb6\x19\xaa\x10\x52\x4b\xf7\x18\xba\x47\x6e\x8d\xa3\x17\x43\x97\x72\x64\xda\x46\xa9\x31\xe7\xed\xd9\xed\x5c\x71\xd0\xab\x38\x90\x88\x37\x54\x1c\x97\xe6\x35\xae\x7e\xb1\xf6\xb6\x7d\x2a\xd4\xa9\xfe\x7d\x49\x5e\xbb\xa0\x0a\x12\x63\x8a\x4b\xaa\xa0\xd5\xc8\x71\x81\xe3\xe2\x66\x1e\x7c\xd4\x50\xa5\xc1\x41\x13\x59\x1f\x2a\xde\xda\xc4\xf4\xaa\x79\xa6\xc5\xa5\xc4\xca\x53\x2b\xb6\x94\x1e\x2d\xc9\x61\x7d\x2f\xec\x6b\xab\x82\x29\xc7\x72\x8e\xa7\x36\x47\xbb\x2b\x28\xc3\xc1\xd1\x50\xb9\x18\x67\x43\x11\xca\x05\xe0\xe2\x90\xb2\x2e\x1a\x84\x70\x5e\x4f\x84\x67\x23\x1a\x92\x3e\x64\xe3\xd5\xa0\x7e\x21\x9b\x20\x5d\x13\xa8\x69\xfd\x12\x16\xdb\x66\x36\xc3\xf1\x15\xcc\x76\x4d\xba\xa1\x19\xea\x39\xbb\x85\x14\x1e\x42\x40\x3a\xc9\xa3\x5b\x84\xec\xd5\x22\x8f\x39\x4f\x39\x6f\xd7\x62\x05\xf9\x1b\x21\x90\xc7\xdc\x81\xc0\xa4\x45\xc9\x16\x08\x48\x28\x35\x25\xcc\x4b\x24\x8c\x4d\x6a\xdc\xf5\xd1\xdf\xc1\x81\x45\xdf\xd9\x33\xa0\xea\x5e\x0f\x22\xd6\xf7\x70\x8f\x19\xd0\xdf\x12\xae\xd7\x22\x1e\xbc\x32\x7d\x5d\xa2\x2a\x51\x93\xa8\x08\xeb\x51\x09\x31\xa8\x91\x56\x00\xd1\x3d\x18\x5f\xae\x72\xc7\x63\x4d\x9c\xe0\xc1\x50\x17\x14\xc7\x3d\x67\x0f\x06\x87\x22\xc9\x05\x04\xd5\x6d\x14\x04\x04\x7f\x0a\x3f\x2e\xc3\x63\x3a\x6d\x99\x28\x51\x49\x0e\x85\xb9\x56\xe6\x30\x6c\x50\x0a\xb4\x74\xdb\xb8\x1f\x4a\xf5\x46\xff\xb1\x60\x5f\x4e\x3d\xfa\xdb\x8f\x81\x4a\x7a\xf4\xa1\x50\x74\x74\x99\x80\x47\x5b\x36\x0c\xea\x44\xc3\xde\xea\xd2\x73\xf2\xee\xaa\x76\x67\x1a\xa4\xee\xcf\xb3\xe0\xf3\x2d\xf6\x9b\x9b\xfd\x8a\xd9\x3f\x6f\xca\xfe\x14\x64\xbb\x9b\xb5\x3d\xbd\x44\x87\xe4\x1c\xc3\x39\x7a\x73\xdc\xe6\x08\xf6\xa2\x66\x2d\x44\xd8\x5a\x53\x1c\x8b\x8b\xdc\xef\x4c\x37\x34\xc5\x55\xb8\x4a\xf7\xed\x69\xf3\x72\x93\xad\x95\x64\x13\x4d\x43\x1c\xb1\xf1\x35\x78\xa5\x6b\x76\x13\x0c\x86\x37\xd9\x60\xba\x1e\xb2\x83\xb3\xb1\x9c\x58\x9d\x0d\x53\xce\xaa\x06\x32\x8b\x42\xcd\x4f\xd3\xfb\x87\xd0\xc9\xf7\x94\x57\x2c\x93\x29\x22\x80\x84\xe3\xb0\xf5\xf9\x7c\xcf\xac\xef\x38\xb6\x37\xe6\xed\xd6\x58\x0e\x75\x6b\xcd\x4e\xb7\xae\x78\x8b\xa9\xe1\x39\x46\xf5\x21\xe6\x22\xcc\x05\xd8\x05\x86\x92\xa4\x22\xa0\xf0\x45\xc9\x91\xa5\xf9\x2c\x9f\xe5\xb1\x07\x25\xde\x7e\x71\x33\x77\x5b\x4d\x9e\x2e\xf2\x78\x31\x46\x9d\x37\xbf\x41\x4d\x62\x43\xc7\xb5\xa5\x25\x77\xf3\x6b\x98\x44\x27\x71\xed\x7a\x55\xc5\xdd\xe8\x0c\x0f\xc2\xe4\x20\x8c\xc3\x71\xbe\x89\xc2\xf8\x06\x89\xf7\x84\xe3\x89\xdd\x3d\xd6\xa9\x02\xd5\x99\xf6\x7c\xc7\x1e\xef\xd8\xd3\x9d\xc4\xf4\x85\xbe\x0c\xae\x9c\x8f\xde\xf8\xe8\x8d\xe7\xa3\x37\x3e\x7a\xe3\xa3\x37\x3e\x7a\xe3\xa3\x37\x3e\x7a\xe3\xa3\x37\x3e\x7a\xe3\xa3\x37\x3e\x7a\xe3\x2e\xe8\xfe\x4f\xbd\x31\x3d\x30\x56\xa0\x57\x79\x6c\x51\xff\xa1\x71\x15\xd0\xcb\xcd\x18\xbb\x18\xb7\xf3\x20\xf8\x48\xdb\xd5\x65\x29\xb8\xac\xa7\xb0\xc4\x27\xbf\x5c\x74\x91\x6f\x96\x05\x93\x8e\xdf\xbb\x9e\xc6\x4a\x55\x83\x7f\x8a\x66\xce\x05\xc4\xf9\x9b\x9d\xce\xb9\xde\x8d\x37\x3b\x1d\x74\x55\x8d\xde\x6f\xb9\xfc\x2f\x00\x00\xff\xff\xbc\x12\x7c\xa7\x15\x2c\x00\x00") + +func fontsAlligatorFlfBytes() ([]byte, error) { + return bindataRead( + _fontsAlligatorFlf, + "fonts/alligator.flf", + ) +} + +func fontsAlligatorFlf() (*asset, error) { + bytes, err := fontsAlligatorFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/alligator.flf", size: 11285, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsAlligator2Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x5f\x8f\xe3\x34\x10\x7f\xcf\xa7\x18\xc9\x96\x78\x30\xaa\xc4\x72\x62\x75\x16\x42\xad\x00\x1d\xcb\x9f\x17\x58\x09\x78\xec\xd1\x94\x46\x97\x6d\x4f\x6d\xf6\x8e\xe5\xd3\x23\x7b\x3c\xe3\x19\x27\xd9\xa4\x3d\x4e\xba\x87\xb6\x2b\x37\x76\x9c\x99\xf1\xf8\x37\x3f\x8f\x9d\xdd\xb6\xdb\x9b\xb5\x85\x5b\xb8\x85\x9b\xaf\xe0\xcb\x1b\x78\x51\xad\xda\xb6\xf9\x7b\xdd\x1d\x8e\x37\xf0\xfa\x09\xbe\x5b\xef\x9b\xba\x85\xdf\x9b\x7f\x17\xb0\xfa\x69\x05\xbf\xd4\xc7\xb6\xd9\xc3\xab\x63\xfd\xf4\xfe\xd0\x6e\xe1\xeb\x87\xd8\xb0\x7c\x7d\x5c\xef\x1e\x4e\x8b\xc7\x4d\xdd\x2e\xea\xcd\xe3\x37\xd5\xcd\x6d\xb7\x83\x1f\x1f\xdb\xa7\xcf\xe1\x8b\x97\x2f\x5f\x54\xf7\xbb\xe6\x04\xcd\x09\xba\x5d\x0d\xbf\xdd\xff\xba\xba\x7b\xf5\xc3\x3d\xbc\xab\x8f\xa7\xe6\xb0\x87\xc3\x36\xb6\x1f\xeb\x77\xcd\xa9\xde\x00\x9b\x00\xdb\xc3\xbe\x83\x3b\xa8\x37\x4d\x57\x6f\x16\xd5\x5d\xf7\xd9\x09\xbe\xff\x63\xf5\xed\xfd\xcf\x7f\x42\xdb\xbc\xa9\xe1\xe1\x09\x0e\xdd\xae\x3e\xc2\xdb\xc3\xa9\xab\x37\xf8\x40\xfd\xcf\x5f\xf5\xdb\x2e\x8a\xec\x9a\xb6\x83\xf7\xeb\x13\x74\xeb\x37\xf5\x1e\x0e\x8f\xdd\x62\x51\xd9\x65\xff\x6f\x59\x79\xef\xed\xb2\xf2\x2e\x94\xce\xbb\x50\x9a\x5c\x5a\xb0\xb0\xac\x8c\x31\xa9\x2b\x70\x77\xc0\x47\x2c\x84\x4f\xe8\x34\xf3\x6a\x59\x01\x04\x29\x58\x86\x66\x6c\x71\x1e\x4b\x6c\x71\x5e\x7d\x6d\xec\xe3\x8c\x0b\xa5\x77\xa9\x8f\x51\x5f\xec\x63\x9c\xc1\x92\x25\x1b\x63\xb0\x8c\x2d\xb1\x89\x55\xc7\x1e\xac\xc6\xa2\x62\x56\x11\xef\x3a\xe3\x9c\x77\x41\x3e\xa4\x67\x83\x19\xa4\x8f\xd5\xf3\xdd\xa4\x08\x92\xbf\xb2\xaa\x20\x4e\x8d\x92\x0c\xcc\x63\x92\x2d\x66\xba\x25\x8f\x95\x5b\x78\xac\x61\xa0\x1e\x3f\x76\x40\xf7\xb2\x0a\x3a\xfb\x03\x05\x70\x28\x2e\x0d\x32\x8d\x8c\x35\x85\xee\xcb\x2a\x68\x48\x1f\x0b\x02\x43\x71\xa2\x63\x8f\x91\x32\xba\x3b\x76\x86\xec\x6f\x9b\x26\x53\xfd\x02\xfb\x34\x83\x0f\x6f\xa4\x07\xd1\x69\xc9\x70\xf9\x4b\x26\xc7\x79\x08\x1a\x03\x86\x11\x7c\x2c\x00\x31\x40\x82\xa4\x2b\xa2\x05\x38\xe1\xa1\xcc\xc0\x4b\xee\x47\x05\xe4\xfe\xf8\xbc\x96\x9f\xa6\x82\x1a\x69\xb2\x78\xce\x09\x44\x34\xe3\x83\x0a\xc5\x6c\x13\xac\x10\xd1\x5c\xcf\xf2\x29\x48\xc7\x4a\xc4\x47\x9a\xa9\xf4\x50\x11\x96\xe3\xf5\xd2\xb6\x33\x9f\x9f\x6b\x1b\xe2\x95\x23\x53\xfa\x0c\xaf\x09\x26\xd9\x33\x34\xe3\x00\x19\x2e\x78\x4d\x11\x88\x93\xc1\x41\x20\x23\x20\xc5\xb9\x67\xc2\x03\x07\x7c\x6d\x08\x4a\x2a\xbe\x24\xde\x29\xa8\xa3\x48\x97\x70\x29\x6c\x64\x10\x8b\x2b\x34\x30\x5a\x67\x8a\x00\x15\xc6\x29\x56\x75\x29\xa2\xe4\xa0\xad\x42\x06\x8f\x3a\x0b\x9e\x29\x3b\x0d\x37\xc9\x46\x47\xdb\x4c\x34\x34\xf8\x62\xf4\x34\x7c\x4d\xa0\x1a\xdc\x39\x98\x12\x8d\x80\x88\x71\x4d\xd6\x90\xdd\xc2\xfc\x65\x89\x3a\xc9\xfe\xc2\xfc\x38\x71\x3d\x78\x9e\x65\xfe\xa8\x6b\xc6\x65\xe3\xd2\x33\x2d\xdb\x0f\x19\x9e\xa4\x03\xc8\x59\x05\x11\xe6\x3a\xe6\xb1\x46\x53\x9b\x6a\x79\x55\x99\x34\x3f\xf1\x22\xd9\x7f\x8e\xf9\xe7\xca\x16\x94\x30\x29\x1b\x23\x9e\x30\x38\xcc\x04\x16\x66\x77\xcd\x58\x24\xc6\x20\xba\xd0\x4b\x4a\x42\xa1\x8c\x42\x4a\x0b\xec\x0c\x42\x2c\xd3\x90\x01\x82\x54\xa8\x9e\x24\xc4\x22\xef\x81\xcc\x1f\x43\xd8\x90\xc8\x90\xb8\xa0\x85\xb1\xc4\x84\x9c\xb8\x99\xb0\x13\x24\x2a\xd6\x95\x3e\xec\x00\x24\xb8\x81\x97\x52\xe1\x20\x4a\xa0\x10\x2c\x44\x04\x89\x60\xb1\xcd\xa8\x36\xe3\x74\x3e\x15\xe0\x23\xdc\x99\x33\x38\xa6\xf4\x9c\xc3\x15\x29\x5c\x76\x24\x6b\x2f\x16\x30\xcb\x71\xa0\xc1\x0a\xbc\x0a\x31\x07\xc9\x48\x7e\x3e\x14\x66\xb2\x84\xb9\x90\x81\x46\x2a\x73\x18\x68\xd2\xee\x7e\x65\xca\xee\x92\xdc\x68\x4e\x28\x8d\xa3\x0a\x33\x4f\x8e\x42\xbc\x93\xd7\xab\xde\x82\x35\x53\xb6\x37\xde\x3b\xef\x67\xc8\xb6\x02\x2e\xf3\xfc\xed\x8d\x2f\xfd\xed\x92\x1b\x9e\xf5\x37\x30\x09\xcd\xc0\xc9\xa4\xbf\x87\x30\xc8\x39\x11\x39\x46\x66\x45\xc3\x81\xac\x6b\x79\x35\x31\x63\x6e\xff\x10\x15\x29\x6e\x39\x19\xcb\x01\x3b\xec\xa1\xfe\x66\x8b\x3d\xc4\x49\x78\x66\x29\xb1\xa7\x1b\xf0\x90\xc0\xc6\x73\x88\x1c\xa9\x4c\x20\x32\x19\xee\xf3\x52\x00\xbc\x14\x24\x7e\x53\x2c\x87\xe4\xc3\x3b\xe8\x24\x59\xd3\x4d\x49\x38\x6a\xba\x95\xa7\x44\xbe\x8a\x5a\xa1\x20\x54\xa1\x28\x6d\xd6\xe4\x5e\x4d\x03\x6a\x22\x2d\xbc\x84\x1d\x2e\x65\x1e\xc5\x98\xe7\x46\xb0\x16\x0e\x4a\x3a\x28\xd3\xa9\x66\x68\xfd\x44\xe3\x43\x9b\xcd\xbb\xd8\x0b\x09\xdf\x4f\x12\x3e\xf4\xb7\xe2\x73\x53\xce\x73\xf2\xaa\x8f\x41\x12\x30\x74\x90\x31\x87\xe3\x2e\x42\x0d\xf4\x84\x17\xce\x51\x12\x45\x0e\x2a\x33\x23\x3e\x87\x19\x35\xbf\xa7\xa4\x37\x07\xcf\x04\x72\x94\x2e\xd2\x14\x4a\x54\xf8\x8c\xa2\xd8\xbd\x8c\xf8\x0b\x32\xe5\xe5\xc3\x25\xb9\x55\x92\x40\x1d\x5b\x13\x06\xc8\x54\x9e\xe7\xb0\xe0\x81\x1d\x73\x79\x32\x66\x41\x6f\xb7\x3e\x7c\xeb\x5d\x2e\x2d\x79\x35\x67\x4e\x16\xa9\x39\x5f\xb0\x5d\xea\xf9\x7c\x86\x52\x6e\x31\x33\x50\xd5\xae\x49\xed\xa7\xe4\xb1\x1c\x94\x46\xc9\xfc\x58\x9e\x30\x16\x17\x32\x0d\xb2\x13\x99\xa7\x86\x6b\x4e\x58\xf5\x3e\x60\xa2\x26\xaa\xea\xde\xa5\x95\xde\x9a\x86\x87\x6f\xa1\xb4\x78\x7c\x35\x58\x5e\x73\xec\x6b\x8e\x7d\xcd\xb1\xaf\x39\xf6\x35\xc7\xbe\xe6\xd8\xd7\x1c\xfb\x9a\x63\x5f\x73\xec\x4f\x32\xc7\x26\xea\xe4\xf3\x6f\xf5\x26\x4a\x42\xaf\xff\x26\x4a\x50\x56\xff\x9f\x00\x2c\x05\x8b\x2d\xde\xd2\x79\x71\x7a\x3d\xf4\xee\x4b\xbf\x8f\x85\xde\xbb\x2f\x0b\xf9\x3d\xf0\x90\x9b\x93\x48\x99\x13\xff\x0f\xf5\x65\xa5\xbe\x1f\xb3\xfa\x5f\x00\x00\x00\xff\xff\x2d\x9b\xb0\x75\x5d\x22\x00\x00") + +func fontsAlligator2FlfBytes() ([]byte, error) { + return bindataRead( + _fontsAlligator2Flf, + "fonts/alligator2.flf", + ) +} + +func fontsAlligator2Flf() (*asset, error) { + bytes, err := fontsAlligator2FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/alligator2.flf", size: 8797, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsAlphabetFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x57\x69\x5b\xda\x5a\x17\xfd\x7e\x7e\xc5\xaa\x55\xd4\x2a\x15\x50\xac\x76\xf2\x60\x9d\xaa\x75\xc2\x3a\x4f\x0d\x90\x40\x24\x24\x48\x42\x95\x7a\xbd\xbf\xfd\x7d\xf6\x3e\x09\x19\xe1\xf6\x4d\x1e\xf7\xda\x6b\xad\xb3\xcf\x94\x09\x0d\xcb\x28\xe1\x03\xca\x28\x16\x90\x2f\xa2\x58\x12\x15\xab\xdb\xd2\x6a\xba\x87\xda\x00\xe7\xba\xdd\xd0\x2d\x0b\x3b\x66\xbd\xad\xdb\x28\x16\x17\x56\x17\x31\xf3\xd4\x62\x2a\xbb\x5a\x4f\x73\x1d\xc3\x7b\x5f\x77\x3a\xb3\x42\x6c\x3e\x77\x2d\xcd\xd6\x3c\xd3\xb1\xe1\x18\x30\xcc\x9e\xeb\xc1\x32\x6d\xfd\xa3\xe0\x51\xf2\x98\xe8\x68\x4d\xb3\x0e\xbb\xdf\xa9\xe9\xbd\x09\x18\x4e\x0f\x86\x69\xe9\x30\x1b\xba\xed\x99\x86\x59\xe7\x62\xa1\x01\x40\x1e\x6e\xcb\xe9\x5b\x0d\x68\xd6\x93\x36\x70\x51\xd3\xf1\x4b\x9b\x9e\xe7\x22\xdb\x79\x12\x93\xaa\x91\xd7\xd2\x31\xd1\xd2\x7a\x8d\x9a\xa5\xd9\xed\x09\xe4\xf3\xe8\xf6\x4c\xdb\x73\xa1\xb9\xd0\xc0\xea\x3c\x6a\x7d\x0f\x75\xcd\x9e\xf6\xa8\x1b\xb7\xd3\x77\x5b\x7a\x43\x2c\xab\x1e\x5a\xba\xd9\x6c\x79\x34\x63\x0d\xf5\x96\xd6\xd3\xea\x9e\xde\x13\xe5\x31\xe6\x3c\x6c\xc7\x83\x69\xd7\xad\x7e\xc3\xb4\x9b\x68\xe8\x6e\x9d\x36\xaa\xe7\x8a\x52\x81\xcb\x3a\xda\x33\xaf\x1c\x96\x6e\x37\xbd\x16\x66\xf4\xe7\xa0\x71\xdd\xe9\x74\x74\x5b\x6d\x8c\x3b\x8b\x39\x68\x30\xfa\x8d\xa6\x0e\x43\xab\x7b\x4e\x4f\x14\xcb\xdc\x43\x43\x37\xb4\xbe\xe5\xa9\xc9\x76\x9c\x86\xce\x0b\xf7\x5a\xa6\x0b\xc3\xb1\x3d\xcc\x58\x66\x5b\xc7\x44\xbe\x83\x62\x79\x02\x8e\xcd\xfd\x6a\x76\x83\xfb\x9d\x15\xc5\x12\xf7\xa2\x76\x9a\xa6\x1f\x1b\x56\x48\xff\x10\x6f\xde\xbc\x41\x3c\xd2\xba\xe3\x39\x47\x29\xa6\xa7\x31\x3d\x8d\x10\x81\xd0\x1e\x83\x52\xe0\x2d\xde\x92\xf0\x96\x0e\x8c\xe6\xe9\x42\x4c\x62\x52\x49\x93\x74\x50\x36\x99\xa1\xa9\x76\x93\x19\x1a\x77\x33\x05\x60\x6a\x4a\x75\x3c\x35\xa5\x4c\x42\x4a\x18\x21\x05\xe3\xd4\x70\xf0\x48\x22\x05\x72\x39\x56\x72\x40\x8e\x9d\x5c\x2e\x87\x1c\x71\x3a\x15\xcf\x65\xcd\x3f\xd8\x2e\x96\x32\x83\x14\x98\x99\x81\x14\x33\x33\x48\x44\xa5\xc7\x2e\xc0\xec\x2c\x93\xd9\xd9\x44\xf4\xf5\x68\xd3\x60\x2a\xef\x40\xa7\x14\x78\xf7\xee\x1d\x73\x3a\xa2\x3c\xf0\x11\x29\x94\x02\x73\x14\xe7\xe6\xe6\x86\x79\xa4\xf7\xc8\x18\xa9\x30\x3f\x4f\xd9\x7c\xb8\xba\x48\x59\x3e\x9f\xcf\xea\x68\x44\x77\xef\xdf\x07\x21\xba\x59\x00\x16\x16\x18\x17\x16\x58\x5d\x58\x60\x97\x00\x52\x30\x64\xde\x49\x85\x42\x81\x84\x02\x50\x28\x30\xd2\x29\x05\xa9\x84\x81\x9f\x2e\x2c\x16\x89\x17\x15\x20\x06\xc5\xa2\x55\x0c\xda\x06\x20\x05\x4a\x25\xa2\x25\xa0\xc4\x2a\x33\x8a\x24\x96\x4a\xa5\x74\xc5\xe2\xe2\xa2\x4f\x17\x09\x62\x2c\xf4\xa2\x15\x4b\xc0\x12\x42\x58\x5a\x5a\x52\x66\x1c\xa2\x15\xe5\x72\xb9\x0c\xa9\xde\x6a\xcc\x7c\xb3\x1c\x63\xb1\x75\x60\x59\xf1\x65\xa5\x2f\x2f\x2f\x2f\x33\x82\x1c\xd2\x15\x4f\x6d\xd9\x07\x3a\x94\xf0\x41\x19\x1f\x90\x8d\xc9\xbd\x5e\x59\x59\x21\x61\x05\xc0\x0a\x46\xf3\x74\xe1\xea\xea\xea\x2a\xa4\x58\x05\x40\x18\x70\xa6\x8c\xab\x23\x46\x24\xf6\xf1\x23\x52\x59\xfc\x9e\x93\xe2\xd3\x27\xc4\xb2\x4f\xc9\x36\x9f\x3f\x13\xf9\xfc\x99\x34\x8a\x21\x0b\xbc\xe4\xee\x12\xfb\xf2\xe5\x0b\xb2\xf2\xd8\x83\xf1\xf5\xab\x62\x84\x24\x7e\xfd\x1a\xb2\xc0\x4b\x74\xbe\xb6\xb6\x46\x7c\x0d\xc0\x9a\xd2\xd7\x94\xbf\x86\x38\x26\xf7\x43\x4a\x49\x82\x24\xaa\x50\xfa\xa8\x1a\xfa\x7e\xba\xb0\x52\x21\x5e\x01\x2a\x04\x95\x4a\x25\xc2\x14\x24\xe6\xb8\xbe\xbe\xbe\x4e\x7c\x1d\xc0\x3a\x46\xf3\xf4\x50\xdf\xbe\x7d\x83\x14\xdf\x94\x1c\x07\xdf\x4b\x0c\xb5\xb1\xb1\x41\x74\x03\xd8\x48\x83\xf2\x12\x15\x9b\x9b\x9b\x9b\x90\x62\x53\xa9\x44\x62\x6c\x33\x5d\xb1\xb5\xb5\xb5\x05\x29\xb6\x94\x4a\x24\xc2\x90\x79\x91\xb6\xb7\xb7\x89\x6f\xfb\xfa\x36\xb0\xbd\xed\x73\xc2\xc0\x4f\x6d\xc0\x0e\xb0\x83\x10\x76\x76\xa2\x4c\x41\x62\xa8\xef\xdf\xbf\x13\xfb\x8e\x44\xf4\xf5\xe4\x87\x63\x17\x69\xdc\x0d\xf8\xee\xee\x6e\xe6\xac\xf6\x80\x3d\x10\xec\x91\xbc\xb7\xc7\x6e\xc0\x94\x97\x98\xd5\x0f\x45\xb3\xe1\xc7\x8f\x1f\xe9\x8a\x7d\x00\xfb\x90\x62\x7f\x1f\xfb\x8c\xd8\x57\x3c\xd0\x7d\x4c\x4d\xee\x00\xc0\x01\xa4\x38\x38\xf0\x11\x07\x3e\xe2\xc0\x47\xe6\xe9\x9b\xed\xf0\xf0\x90\x84\x43\x00\x87\x19\x18\xf8\xa9\xc2\xa3\xa3\xa3\x23\x12\x8e\x00\x1c\x21\xce\xa3\x98\x1e\xf1\xf8\xf8\x98\x15\x8a\xc7\xc9\xe4\x98\x13\x6a\x73\x3c\xac\x3a\x1e\x96\x53\x7d\xb5\x5a\xad\x92\x55\x05\x50\x45\x94\x57\xe1\xeb\xd5\x6a\xe6\xc0\x27\x27\x27\x24\x9c\x04\x86\xcf\x89\x9d\x90\x1e\xe1\xb1\xc2\x9f\x7c\xb0\xf2\xf3\xa7\x6f\x8d\x49\x62\xe5\x54\x7f\x0a\xe0\x14\xa3\x11\xa7\xa7\xa7\x99\x03\x9f\x71\x72\x86\x68\x86\x33\x4e\xb8\xd9\x19\x13\x2e\x38\x8b\x0d\x1a\xcd\xa4\x38\xe7\xe4\x1c\x89\xec\x5c\x65\x38\xe7\x93\x4b\x38\x19\xd5\xcd\x05\x80\x0b\x92\x2e\x70\xa1\xac\x0b\xd5\xc4\xe7\x43\x3f\xb9\x8c\x4b\x00\x97\x24\x5c\xe2\x52\x19\x97\xc8\xc6\x44\xe1\x15\x1d\x4a\xb8\x52\xc6\x95\x6a\x70\xa5\x1a\x46\xfc\x78\xe1\xf5\xf5\xf5\x35\x08\x58\x4e\x02\x7b\x89\x27\xef\xe6\xc6\xe7\x9c\x90\x4e\x09\xfb\x37\x37\x7e\xbb\x9b\x9b\x8c\xa1\x6e\x6f\x6f\x6f\x99\x67\xc0\xd0\x8b\xbf\x17\xef\xee\x88\xde\x01\x77\x49\x33\x13\x32\xbe\x99\x7e\xbc\xbf\xbf\xbf\x0f\xa2\xdf\xf4\xd7\x2f\x24\xbf\xf0\x59\x1f\xfc\xb0\x23\x4d\x83\x14\x1a\x38\x72\x8e\xe8\xdb\xb2\xa6\x58\x00\xb5\x9a\xcf\x6a\x21\xcb\x98\x6b\x44\xad\xd7\xeb\x90\xa2\x1e\x63\xe9\x8a\x06\x42\x68\x34\x08\x1a\x31\x36\x66\x3f\x74\x5d\xa7\x08\x8e\x3a\x52\xaf\x7b\xc3\x20\x62\x90\x64\x44\x72\x3f\x26\xbf\x0c\x41\x6c\x36\x9b\x14\xd1\x1c\xe6\x08\x73\x29\x5a\xaa\x55\x00\xad\x96\xcf\x5a\x21\xa4\xa7\x2c\x85\x69\x22\x9a\x85\x34\xb9\x75\x0f\xc8\x60\x04\x0f\x3e\x7b\x78\xe0\x8a\xb6\x6a\xd3\x46\x9b\xa1\x1d\x63\x40\x3b\x3d\x0f\x0b\xe9\x3f\xe5\xcb\xd4\xcd\x2d\x3a\x9d\x4e\x87\x11\x74\x86\x98\x7a\x08\xe2\x17\xdd\xb6\x6d\x06\xc0\x0e\x61\xcc\x25\x74\x1c\x87\x22\x9c\x61\x9e\xba\x2e\x61\x07\xdd\x6e\x97\x01\xe8\xc6\x58\x08\xe9\x75\xe0\xf1\xf1\x91\xf0\x11\x78\x8c\x72\x04\x1c\x78\x7c\x4c\xce\xaa\xd7\xeb\x51\x54\x79\xf2\xd1\x4b\x3c\x44\xae\xcb\x91\x72\xd7\x4d\x37\xf5\x98\x70\xf4\x3c\x0f\xa1\xe2\x8d\x5f\x6b\x1f\xe8\x87\x80\x7e\xbf\x3f\x7e\x23\x7f\xe3\xf7\x30\xe2\x77\xe6\x94\xa3\xdb\xf2\x04\xe0\x89\xf1\x89\x91\x61\xd4\xe5\x0d\xe2\x33\x9e\x29\x7f\x8e\xe4\xa3\x17\x30\x00\x06\x21\x60\x30\x18\x28\x8f\xc5\xc1\x20\xd5\xf9\x9f\x3f\x9c\xfb\xf1\x4f\xba\xf3\x97\x17\x62\x2f\x2f\x24\x52\x0c\x59\xe0\xc5\x77\xe7\x9f\x7f\xb2\xff\xd8\x7c\x7d\x55\x6d\x09\x49\x7a\x7d\x0d\x59\xe0\x65\xbf\xdc\xfe\xc5\xbf\x90\x82\xe2\x7f\xbd\xba\x1d\xf0\x6d\x3d\xee\xdf\x87\x74\x85\x2a\x19\xf1\xcb\x6c\xe4\x2f\xb2\xa0\xf0\xff\xfe\x99\xa1\x9e\x3c\xfc\xcd\xf7\x20\xda\xf4\x3f\x1e\xdb\x60\xe5\x7f\x7f\x2b\xff\xed\x7f\x4c\xeb\xc9\x05\xfc\x2f\x00\x00\xff\xff\x82\x19\xcc\xe4\xe3\x15\x00\x00") + +func fontsAlphabetFlfBytes() ([]byte, error) { + return bindataRead( + _fontsAlphabetFlf, + "fonts/alphabet.flf", + ) +} + +func fontsAlphabetFlf() (*asset, error) { + bytes, err := fontsAlphabetFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/alphabet.flf", size: 5603, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsAvatarFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\xcd\x6e\xdb\x46\x10\xbe\xef\x53\x7c\x30\x04\x38\x41\x6d\x8f\x65\xd4\x06\xdc\x13\x83\xa2\xbd\x15\xe8\x03\x0c\xb0\x5d\x89\x4b\x89\x28\x45\x1a\x24\x95\xd8\xc0\x3e\x7c\xb1\x33\xa4\x44\x51\xa4\x63\xb7\x87\xe6\xe0\x83\xb2\x12\x39\x7f\xdf\x37\x3f\x3b\x71\x56\x64\x77\x6e\x81\x07\xdc\x63\x79\x8b\xe5\x03\x96\x0f\xe6\xcb\x57\xd7\xba\x1a\xab\x17\xfc\x5a\xb8\x7d\xea\xf1\x87\xab\xdb\xbc\x6c\x70\x7b\x47\x8f\xf7\xc6\xfc\x9e\x6f\x0a\xdf\xa2\xf6\x85\x77\x8d\xc7\xdd\xcd\x12\xd7\xd7\x58\xde\xe1\xcb\x7e\x83\xe5\xe3\xe3\xcf\xe6\x4f\x5f\xef\xf2\xa6\xc9\xab\x12\x79\x83\xad\xaf\xfd\xea\x05\x9b\xfc\xab\x2f\xd1\x56\xd8\x55\x69\x9e\xbd\xa0\xdd\xe6\x0d\xb2\xaa\x6c\xaf\xe0\x1a\x14\x55\xb9\x89\x67\xbb\xf5\x46\x04\x72\x5f\x5f\x36\x28\xdd\xce\x47\x1b\x4f\x85\x5b\xfb\x14\x55\x09\x87\x75\xb5\xdb\xf9\xb2\x45\x91\x97\xfe\xc6\x98\xdf\x9e\x9f\x0a\x57\xba\x36\x7a\xab\x32\x64\x79\xdd\xe8\xbb\x5f\x4c\x44\x87\x6b\x5c\xec\xdc\x26\x5f\xa3\xdc\xef\x56\xbe\xbe\x40\x56\xd5\xc8\xf2\xc2\x23\x4f\x7d\xd9\xe6\x59\xbe\x16\x65\xe3\x00\xe0\x1a\xcd\xb6\xda\x17\x29\x5c\xf1\xcd\xbd\x34\x58\x79\xfc\xe5\x2e\xaf\x44\xa9\xac\xbe\x99\x85\x0a\xb5\x5b\x8f\x8b\xad\xab\xd3\x55\xe1\xca\xbf\x2f\x22\x01\x4f\x75\x5e\xb6\x4d\xc4\xe0\x20\x4f\xaf\xb0\xda\xb7\x58\xbb\xf2\xb2\x8d\x66\x9a\xdd\xbe\xd9\xfa\xd4\x3c\xa8\x85\xad\xcf\x37\xdb\x36\x46\xec\xb0\xde\xba\xda\xad\x5b\x5f\x9b\xfb\x57\x5e\x5e\xa1\xac\x5a\xe4\xe5\xba\xd8\xa7\x79\xb9\x41\xea\x9b\xb5\x2f\x53\x5f\x37\x66\x79\xab\x7a\x3b\xf7\x2c\xd0\x51\xf8\x72\xd3\x6e\xf1\xc9\x3f\xf7\xd2\x43\xd6\x9a\xcf\xf8\x09\x0e\xd9\x3e\xdd\x78\x64\x6e\xdd\x56\xb5\x59\x3e\x88\x85\xd4\x67\x6e\x5f\xb4\x1a\xed\xae\x4a\xbd\x20\x3f\xe4\xaa\x17\x53\x2e\x63\x80\x27\x76\x8d\x59\x2c\x92\xa9\x4f\x62\x60\x91\x18\x02\x27\x26\x20\x24\x86\x2d\x25\xe6\x93\xfd\x9c\x18\x00\x49\x62\x2c\x60\x13\xc3\x21\x90\x3c\xc1\xc4\xbf\x7a\xc8\x6f\x4b\xc1\x06\x8e\x0a\x80\x05\x28\x5a\x8e\x5f\x38\x31\xe0\x80\x40\x38\x0a\x27\x06\x14\xc4\xb7\xe5\xa8\xc0\x51\x9f\x21\xdf\xa3\xa6\x48\x4b\x00\xd1\x32\x07\x8a\x02\x20\x90\xe8\x50\x0c\x9b\x09\x1c\x3a\x8b\x0a\x25\x8a\xd2\x0d\x8b\x06\x6c\x8c\x84\x02\x45\x6b\x6c\x2d\xf1\x50\x34\x31\x0a\xe9\xe4\x13\x5f\x58\x2b\x31\x51\x14\x88\x8f\x03\x8b\x2b\x6b\xf9\x80\xd7\x5a\x7d\x24\xb8\x34\x04\x4b\x21\x31\x64\x2d\x8d\x48\x11\x4e\x7a\x4a\x7a\x46\x7a\x42\x06\x7c\xa8\x82\x02\x80\x0d\x08\xd1\x43\x88\xbf\xad\x20\x0c\x36\x60\x40\xde\x90\x45\x8c\x3e\x0a\xed\x18\xc0\x21\x10\xdb\xc7\x6d\x0f\x60\x70\x1a\xc0\xf1\x13\x59\x60\xea\x49\xe9\xe4\x84\x41\x52\x10\xa4\xfc\x0f\x8a\xa0\x33\x2f\x19\x97\x72\xd2\xec\x04\xb0\x90\x23\x6e\x69\xe8\xee\xb4\xf2\x8e\xe5\x37\xb2\x67\x3b\xbe\xe8\xc8\x1f\xd9\x09\x7b\x03\x7c\xaa\x10\x35\x24\x37\x2c\x27\x9d\x05\x20\x8c\x27\x86\x18\xa4\xce\x59\x82\x00\xd0\x9f\x6c\xc3\x49\xc4\x3d\x44\x65\x30\x74\xa9\x8c\xa1\x60\x12\x62\xe7\x01\xd6\x0a\x50\x8a\xa1\x45\xac\xac\xa1\x4d\x70\x72\xf0\xa0\x96\x09\xe7\x21\xcd\x28\xd8\xbe\x8f\x48\x13\x64\x99\x5f\xf3\xd0\xb1\x34\x08\x05\xd3\x1e\x06\xd5\x30\xaa\x8a\x51\xa9\x1c\x0b\x4f\x9a\x08\xda\x45\xb1\x54\xa4\x1d\xa5\x8f\x70\x6c\xa4\x93\x26\x19\xd5\xe6\x4c\xad\x6a\xeb\x75\xbd\x27\xee\x65\x60\xc0\x6a\x51\x46\x96\x87\x3d\x7e\xc6\x25\x77\x08\x45\x3c\x22\xed\xe4\x99\xc6\x15\xac\xe9\x25\x1b\xb9\x0c\x60\x9e\xac\xb8\xf9\x92\x0f\xd7\x41\xab\xf9\x38\xa0\xa6\x3d\x04\xa8\x87\xf0\x9d\x6c\xc5\x42\xd2\x8a\xd3\xa1\x14\xb3\xf4\xb6\x90\x42\x1f\xd2\x5c\x17\xda\x6e\xe4\x41\x5e\x44\xcb\x9d\x07\x9a\xcc\xc0\x40\x41\xfa\x31\x0c\xb0\x68\x6a\x68\x34\x56\xce\x3c\x04\xb9\x54\x24\x24\x9a\xf4\xa0\x45\x11\xf3\x45\x5d\xec\x41\x4f\xcc\xd0\xfa\xfa\x24\xe9\xbb\x10\xda\xe7\x7d\x33\x11\xdb\x30\xd3\x85\x31\xd4\x68\x52\x2f\x8f\x20\x9a\x7a\xb2\x40\x0c\x3c\x1b\xb1\x92\x17\xfa\x53\xae\x9d\x49\x0f\xbd\x86\xb5\x1d\x48\xa6\x1e\xe5\x01\xe6\x00\xe7\x58\x0d\x3d\x37\x8c\x5e\x8d\x67\xd5\xde\x3d\x9a\xc7\x75\x0a\x56\x6f\x9a\xc2\xe9\x1c\xcf\x78\xe0\x30\x57\x45\xd3\x1e\xa0\xf7\x35\x8d\x29\x7e\xef\xec\xb5\x83\x49\xd7\x39\x27\xad\x6d\xc9\xbf\x7e\x11\x24\xe7\x14\x77\xc5\xc7\xc7\xa2\x7b\xed\x1a\x3b\x28\x84\x93\x9e\x66\x22\x6d\x20\x1a\x71\x35\x91\x44\xf4\x49\xa4\xb9\x24\xca\xe4\xd3\x3d\x82\xa3\x7d\x51\xd6\x95\x48\x8a\x32\x4e\x3f\x3e\x1b\x95\xd3\x0a\x12\x10\xcd\x26\xf1\xad\x37\xee\xc9\xb2\x24\x84\x86\x70\xb6\x2c\x75\x58\xbb\x9d\x4c\xa6\x36\x77\x8b\x13\xcd\x6c\x54\x41\x6e\xed\x30\xde\xa8\x62\x3a\xa6\x77\xd8\x8e\xd0\xb9\x73\x74\x9b\xc4\xa5\x32\x6e\x94\x33\xeb\xdf\xbf\x9e\xe8\xf8\xcf\x13\x1d\x1f\x13\xfd\x63\xa2\x7f\x4c\xf4\x8f\x89\xfe\x7f\x4d\x74\xed\x6b\xd6\xc5\x5d\xf7\x76\xee\x18\x1f\x4c\x74\x8b\x93\x96\x3c\xf6\xaa\x0d\x47\x1b\x56\x77\x6c\xd6\xfd\x9c\x46\x36\x48\x00\x2c\x98\x16\xc9\x2b\x7f\x57\x60\x62\x7a\xd7\x34\x9e\x55\x98\x4b\xf5\x41\xe1\xad\xb5\xf1\x03\x86\xf4\xdd\x2b\x88\x4e\xff\x47\xf7\x4f\x00\x00\x00\xff\xff\xc5\xb1\xe1\x30\x5d\x14\x00\x00") + +func fontsAvatarFlfBytes() ([]byte, error) { + return bindataRead( + _fontsAvatarFlf, + "fonts/avatar.flf", + ) +} + +func fontsAvatarFlf() (*asset, error) { + bytes, err := fontsAvatarFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/avatar.flf", size: 5213, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBannerFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5d\x6d\x73\xe2\x38\xb6\xfe\xce\xaf\x78\x6a\x95\x0f\x3d\x55\x28\x03\x04\xd2\xc9\xd6\xd4\x14\x06\x4c\xc2\x86\x40\x86\x97\xce\x66\xea\x7e\xb8\x4e\xe2\x04\x6f\x88\x9d\xc1\xa6\xbb\x33\x75\xeb\xfe\xf6\x2d\x8c\x5f\x24\x59\x92\x65\xd2\xdd\x5b\x3b\x1c\x40\x3e\xcf\xd1\x79\x3f\xb2\x93\x3c\xad\x9f\x5a\xce\x11\xce\xf0\x19\x9d\x36\x1a\x68\xb6\xd0\xc0\x69\xbb\x76\xef\xf8\xbe\xbb\x39\x7e\x5a\x3f\xe1\xab\xbb\x09\xbd\xc0\x47\x0b\xf7\xef\x98\xbd\x3b\x3e\xee\x82\xed\xc3\x0b\x3e\xbd\xef\x5e\xba\x0f\xe1\xf1\x76\xe3\x3e\x7b\xbe\x73\xfc\xe0\xfc\x52\xfb\x34\xdc\x04\xaf\x70\xb0\xf5\xbd\xef\x78\xdb\x04\xcf\x1b\xe7\x15\x0f\xce\x7a\xed\x3e\x62\xcf\xf4\x97\xda\x08\xce\x2b\xfc\x20\xc2\xc6\x0d\xdf\x02\x3f\xf4\xee\xd7\x2e\x9e\x82\x0d\xb6\xa1\x8b\xe0\x09\xd1\xca\x0b\xf1\x14\xf8\x11\x50\x5b\xac\x1c\xff\x25\x44\x14\xe0\x62\xed\xfa\x3e\xfa\x2b\xe7\xed\xcd\x5d\xaf\xe3\xf5\xbb\x75\x2b\x77\xfd\x56\xbb\x72\x22\xe7\xc5\xf1\x1d\x3c\xac\x9c\x8d\xf3\x10\xb9\x9b\x70\x27\xed\x17\xcf\xf7\xdd\x77\x2c\x56\x8e\x87\xdf\xc2\xf0\xc9\xf3\xa2\xae\xbb\xf1\xc2\xe3\x9d\xd0\xaf\xf7\xc7\xee\xe3\xf6\xf7\x5a\xff\x7d\xe3\xad\xd7\xde\x03\x7b\xed\xd3\x6e\x13\xff\x78\x09\xbc\xb3\xef\x67\xff\x40\x6f\x30\x8c\xc5\x39\xae\x0d\x9c\xc8\xfd\x27\xac\xed\xf3\x36\x8c\xd0\x6c\xd6\xd1\x3c\x3f\x6f\xd7\x6a\xd7\xee\xe6\x79\xb7\xbf\x77\xfc\x2b\x58\xf9\xe8\x07\xdf\x1c\x1f\xbf\x3d\xec\x5e\xba\x0f\x0f\xde\xfa\x38\xd8\x3c\xff\x5e\xbb\x0e\x1e\xbd\x27\x6f\xbf\xee\xc6\xd9\xae\xd1\xdb\x6e\xa2\xc0\xc7\x6f\x61\xb0\xde\x46\x5e\xe0\x77\x5d\x67\x13\xad\xd6\x9e\xff\x72\xec\xbb\xd1\xef\x68\xb6\x7e\x3d\x3f\xdd\x6d\xdd\xf3\x1f\xd6\xdb\x47\x17\xbe\xfb\x0d\x6f\xce\xc6\x79\x75\x23\x77\x53\x0b\xb7\x6f\x6f\xc1\x26\xda\x33\x1c\x8e\x2e\xd6\x6e\x04\xc7\x7f\xdc\x91\xb7\x9e\x7f\x0c\x5c\x3b\xef\x70\xd6\x61\x80\x7b\x17\xe1\xda\x7b\x5e\x45\xeb\x77\xbc\xa6\x52\xec\x14\x78\xef\x46\x91\x1b\xeb\xbd\x16\x3c\xc5\xec\x9f\xb6\xeb\x35\xfd\xe6\x3d\x46\xab\x5f\x5f\xdc\x8d\xff\x6b\xf8\xba\x0d\x57\x70\xd6\x91\xbb\xf1\x9d\xc8\xfb\xea\x86\x75\xdc\x6f\x23\x3c\xba\x4f\xce\x76\x1d\x21\xd8\x46\x6f\xdb\x08\x5e\x88\xc9\x74\xb1\x53\xa1\xff\xec\x3e\x1e\xd7\x70\x84\xa3\xae\xf9\x7f\xbb\x35\x10\x42\x8e\x0a\x2f\x20\xf1\x12\x00\x92\xef\x90\x5d\xc8\x7c\xc3\x5c\x99\x5e\x7d\x04\xa4\x1c\x18\x12\x7a\x32\xa6\xc9\x8e\xcb\x11\x4f\x92\xfd\x3f\xa3\x4f\x39\x92\x61\x1c\xaf\xdd\x5f\x17\x0b\x4a\x72\x72\xbf\x38\x5f\x00\x71\x01\x29\x2e\xe0\x54\x91\x2d\x26\xe9\xfe\x63\xad\x80\xe1\x96\xcb\x96\xeb\x8a\x64\x18\x8c\x7e\x59\x55\xe4\xb2\x81\xd9\x1e\x2b\x71\x6a\x25\x70\xdc\x52\x13\xc6\x0b\x0a\x8c\xa5\xe6\xce\x85\x55\xbc\x24\xd8\xa9\x38\x29\x94\xec\x95\x95\x35\x05\x4f\x90\x73\x3d\xa4\xaa\x91\xbf\xa6\x5a\xcc\x0d\x99\x48\x90\x7b\x0d\x61\xd8\x94\xf9\x04\xbb\x56\xe1\x77\x8c\x89\x78\x82\x63\x28\xae\x01\x47\x68\x15\xa8\x53\xbc\x84\x17\x43\x30\x12\x28\xd7\x1c\x22\x81\x10\xd4\xfb\x7f\x39\x50\xae\x30\xb9\x27\xb3\x86\xc8\x1d\x40\x1e\xd4\xa4\x68\x09\x92\xc3\xc9\x49\xde\xc2\x44\x16\xd4\xb9\x81\x33\x97\x2c\xda\x48\x63\x50\x79\x76\xe0\xb4\x50\x08\x7e\x66\x93\x44\xb0\x91\x24\x88\x2b\x30\x86\x42\x0b\xf2\xb4\x23\x48\x41\x74\xa4\x20\x1b\xc3\x4d\x9a\xcf\xd2\xc5\xba\x9d\x56\x97\x58\xae\x0a\x39\x63\x95\x43\xa8\x32\x30\x27\xb1\xa9\xdf\x2a\x48\x33\x89\xe5\x5e\xf1\x03\x54\xc1\x5c\x27\xfa\x8a\x09\x63\x14\x33\x4c\x1e\xa7\x8a\xef\x94\x19\xca\x2c\x6d\x71\x29\x5b\xac\x0d\x50\xa7\x7c\x55\xde\x2b\xa6\xbb\xf2\x04\x68\x84\xa8\x90\xd0\x3c\x56\xf7\x69\xa8\xe0\x52\xac\x30\x85\x4f\x35\xe6\x8e\x9b\x04\x19\x59\x48\x34\x2a\x73\x0b\xad\x85\x36\xc7\x8a\x71\x5d\x70\xa9\x42\x48\xe9\xd2\x74\x85\x05\xa6\x9e\xaf\xcb\xae\xa5\x9e\x5f\x2e\x50\x29\x69\x96\x5d\xe4\xf9\x50\x2b\xbc\xbc\x34\xfc\x00\xc6\x42\x18\x54\xd0\x71\x89\x2b\xe8\x6a\x4e\xa9\x0a\xcd\xd4\x2d\xa8\x82\xcd\x49\x9a\x97\x92\x96\x45\x47\x56\xdf\x6a\xde\x9d\x67\x6a\xcb\x2c\xc3\xa8\x32\x37\x06\x5b\x79\x73\x8e\xd2\x7a\x7d\x00\xa9\x70\x23\x56\xfd\x59\xcb\x4d\xf6\xff\xcb\x45\x3c\xc0\x28\x02\x63\x66\xc6\x91\x32\xe6\xe6\x8f\xf2\xe4\x52\x3d\x3e\xa5\x7e\x56\x64\x5c\x25\x6b\xfd\x80\x88\x92\x91\xf2\x51\x8c\x7c\x3c\xcf\x12\x79\xc7\x57\x64\x5c\x9a\x03\x0e\xee\x3b\x39\xd5\x13\x69\xe1\xab\x42\x4a\xdd\xed\x30\xf2\xe0\xac\xc5\xb2\x80\x64\xa8\x34\x92\x58\x72\x62\x50\x4a\x22\x3e\x3b\xd1\x31\x36\x10\xa8\xa4\xee\x1f\xce\xb8\x8a\xf1\x84\x80\x3c\x60\x74\xd4\x84\x74\xb6\x23\x63\x82\x14\x26\x3c\xce\xf5\x73\x92\x91\x85\xdf\x19\x3b\x6d\x16\xc2\x44\x2a\x21\xf7\x6d\x19\x21\x91\x90\x19\x66\x19\x2b\xea\xdb\x5e\x69\x23\x0c\xe1\xc3\x0f\x91\x99\x5d\xba\xca\x73\x42\x76\x56\x90\xbc\x30\x75\x30\x5e\xcd\x78\xab\x58\x2f\x85\xc2\x20\x50\x85\x2d\x66\x97\xc8\xd8\x88\x9f\x49\xbe\x95\x32\x84\xea\x62\x48\x28\xc2\x5f\x61\x2e\xa1\x9e\x32\x60\x28\xca\x25\xa4\x7b\xc9\xb7\x25\x3a\xac\xc6\x50\x70\x95\xaa\x3a\x2c\x58\xb9\x4c\x87\x2a\x2d\x19\x68\x93\x65\x18\x7f\xa3\xfd\x4f\xd1\x61\x39\x3e\x4a\xea\xc0\xad\xe4\x07\x34\x15\xfb\x49\x68\xad\x52\x42\x95\xb8\x03\xd8\xbe\x2f\xeb\x27\x89\x89\xeb\x1a\x30\x64\xfa\xc8\xbc\x1e\xe6\x0a\x31\x61\xa8\xf4\x2f\xb5\x5c\x1f\x8a\x51\x6d\x2c\x1c\x26\x21\x11\x7d\x00\x42\x83\xf8\x01\x09\x8d\xdc\x46\x3c\x67\x90\x68\xc9\x58\x87\x47\xdd\x92\x63\x72\x0d\x61\x18\xec\x1f\xb2\xae\x31\x1b\xf6\xbc\x59\x63\xdd\x32\x86\x59\xac\x10\x43\x87\x2e\x93\x41\x57\x34\xa5\xc6\x60\xd8\x91\x8f\x19\x83\xef\x6f\x98\x56\x29\xbb\x94\x69\xaa\x34\xd9\x85\xbd\x47\xc8\x11\xa4\xf0\x09\xdb\x2a\x16\xfa\xb8\x23\x31\x5d\x2b\x52\x38\x7b\xc3\x80\x14\x09\x22\xff\x8a\xbf\xcd\x90\x8e\x52\x8c\x5a\xd9\x1b\x6a\x62\xeb\x5e\x85\x14\xb9\xfd\xd0\xd3\x3b\xf0\x91\x51\xfd\x58\xac\x7c\x94\x12\x9d\xf7\x63\x8c\xe5\x91\xa0\xe8\xec\x0e\x2d\x3e\xa6\x55\xc3\x38\x9b\xc8\x3e\x33\x66\x58\xfd\xb0\xa2\x74\x41\xcc\xb8\x79\xda\x00\x26\x53\xda\x9b\xd9\xd6\x15\xe6\x37\x56\xdf\xce\x74\xcd\xea\x5d\x4b\x13\x61\xcc\x67\x26\x23\x09\xbd\x03\x3d\x07\xfa\xd3\x9b\xbb\xd9\xe8\xe2\x72\x81\xf9\xe8\x62\x52\x8b\x17\xa9\xff\xdf\xad\x35\x3f\x9f\x02\x03\xfb\x62\x66\xdb\xc9\x15\x1f\x14\xb3\x64\xfd\x0e\xf1\x0c\x98\x2f\x6f\xec\xd9\xbc\x3f\x1b\xdd\x2c\xb0\xb8\x9d\x9a\x6c\x90\xa7\x2b\x2b\xe7\xec\x04\xb8\x1e\x0d\x06\x63\x1b\x83\xe9\xa2\xc6\x72\x12\x8b\xa7\xf6\x13\x9e\xe8\xd6\x9a\xe7\xa7\xc0\xd8\x5a\x8c\x26\xe8\x5b\x37\xa3\x85\x35\xc6\xd8\x5e\x2c\xec\x19\x2c\xdc\x8e\x16\x97\x18\x8c\x2c\x7b\x66\xcf\x47\xf3\x9f\x97\x6c\x5a\xcd\xb6\x42\x86\xa9\x4c\x86\x9f\x92\x97\x5a\xad\x86\x42\x86\xa5\x56\x06\x21\x7e\x3f\x28\xc3\x49\x2a\xc3\xfc\xda\x1a\x67\x12\xcc\x2f\xad\xd9\x0d\xe6\x3f\x2f\xde\x5b\xad\x33\x29\x70\xd1\x05\x84\xed\x7e\x38\xc9\xb6\xda\xa7\x52\xe4\xa2\xe1\x8d\x91\x65\x78\x92\xe4\xd9\x6a\x7f\x06\x06\xa3\x2f\xa3\xf9\x68\x3a\x49\x72\x47\xce\x4e\x4f\x10\xed\x9a\x6e\xad\xd5\x69\x49\x77\x55\x74\x25\xe9\xae\x24\x9f\x99\xee\xaa\xf1\xbd\xd1\x6e\x34\x81\xfe\xdd\x6c\x34\x1e\x8f\xfa\xa2\x33\x8f\xa6\x7c\xee\xf9\xf1\xf4\x5e\x86\x66\x43\x2d\x83\x95\xa4\xb6\xac\xd5\x27\xd9\x33\x41\x79\xaf\xcb\xcc\x71\x84\xcf\x63\x05\x52\xd8\x7e\x53\xb3\xfd\x9e\x5d\xe4\xc7\x24\x44\x36\x37\x43\x0d\x48\xa4\xd1\x1b\x63\xb7\xd4\xd8\x5f\xec\x6a\xac\x2b\x63\x9f\xa8\xb1\x2f\x2e\xcd\x36\x6e\x4e\x8a\xe0\x6d\x35\xf8\xc0\x4e\xba\xf0\x6c\x48\x85\x29\x29\xb7\xbd\x88\xdd\xd1\xf8\xfb\x21\x06\x57\x2c\x90\x62\x9f\xaa\xb1\xff\xdc\x2b\x1d\xb9\x7b\xb3\x93\x14\x3b\x98\xb1\x87\xb6\x44\x24\x59\x0e\x02\xf8\x67\x0d\xb8\xcd\x17\x48\x41\x7b\x5c\xe7\x21\x7c\xca\xae\x55\x7b\xdb\x99\x46\xe9\x05\xe7\x25\x32\x92\xe4\x2e\x2d\x75\x74\xa5\xbd\xcf\xd5\xd0\xf3\xcb\xe9\x6c\x91\x08\xc0\x4e\xd0\x52\x59\x0e\x16\xc0\x52\x0b\x70\x65\x49\x00\x33\x3b\xb2\x4f\x8f\xe5\x5e\xa6\x0d\x78\x11\xbb\xa7\xc6\xb6\xc7\x69\xa0\x89\xe9\xb4\x0a\xa9\xc1\xee\x6b\xb0\xaf\x35\x19\x4b\xaa\x73\xf9\x5a\x25\xf6\x40\x83\x3d\x31\xe0\x57\x5a\x46\x34\xd8\xb6\x1a\x7b\xaa\x0a\xb3\x2a\xa4\x26\xcc\x86\x6a\xe8\x1b\x49\x6e\xfb\x10\x29\x60\xb7\x34\x35\xdc\x9e\x1d\x50\xcc\x2a\xd4\x93\x96\xa6\x88\xdb\x73\xad\xce\x4b\x0b\x58\x99\xce\x5b\x9a\x22\xbe\xb0\x85\x12\xcc\x4c\x6b\x07\x92\x3c\xb6\xa6\x88\x2f\x8d\x3d\x49\xcc\xf3\x66\xdb\xd6\x94\x70\x7b\x98\x9e\xd8\x41\x60\xc2\x87\xb4\x84\xe4\x01\x55\xdb\xd6\x94\xf0\x4b\x4b\xdc\x00\x88\xb6\x8a\xb2\x05\x95\x48\x92\xab\x88\xad\x29\xe1\x8b\xb9\x5d\x48\xd1\x07\x91\x42\xff\x90\xf5\xc9\x2d\x4d\x09\xef\x27\xfd\xc3\x21\x16\xd7\x90\xcc\xce\x35\x35\x7c\x9e\xa8\x5d\x6f\x5c\x03\x52\xd5\x39\xb5\xb4\x55\xbc\xff\x93\xe0\x73\xc5\x6b\x6a\xf8\xa5\x35\x1b\xe4\x13\x61\x9e\x3b\x32\x12\x1c\xc9\x36\xb6\xd2\xca\xaa\x0a\x38\x4d\x29\xbf\xb3\x67\x26\xe1\xbe\xef\x23\xf2\x4e\x43\x42\x12\xc9\x8f\x6f\xc4\xe8\x9a\x62\x3e\x9f\x0e\x17\x99\x02\x4a\x53\xea\xc1\x13\x4b\x4b\x57\xd3\x8d\xda\xd7\xc3\x93\x9d\xa6\xa4\xdf\x2d\x0b\x7d\x9b\xdc\xb3\xca\xbc\x10\x0a\x6c\x4d\x4d\xbf\xb3\x4c\x5a\x38\xee\x46\x99\x7e\x7a\x16\xb0\x4f\xd8\x9a\xce\x9f\xf5\x28\x6f\x37\x10\xee\x86\x06\x21\x92\x12\xc0\x7f\x2a\x05\x6e\xaa\x80\x7b\x76\x01\x99\xe5\x66\xe8\x70\x6a\x53\x9f\xb4\x54\xc8\x5f\x8a\xc8\xd0\x37\xe8\x72\x57\x57\x22\x9f\xa8\x90\xe3\x79\x5c\xa3\x6e\x22\xce\x64\x62\x2c\xa0\x4c\xdd\x6d\x15\xf4\x40\x44\x96\xc2\x49\x5d\xd0\x4c\xdd\x1d\x15\xf2\xc8\x64\xcf\xa5\xed\xa3\x06\xf9\x54\x85\xfc\xa7\x5a\xdd\xe5\xf3\xb9\xc9\x24\x7e\xf2\x59\x09\x5d\x71\xd3\x09\xb4\xb9\xba\xcf\x94\xea\xd6\x6c\x19\x07\xcc\xc3\x22\xf0\xb9\x0a\x38\x9b\xc1\x79\x78\x2e\x94\x3f\x0e\x6f\xa9\xe0\xaf\x94\x99\x4c\x35\x97\x97\x0c\xe3\x22\x72\x4f\x85\xbc\x9f\xbf\xa5\xb6\xae\x30\x95\x6b\x90\xfb\x4a\xe4\x6b\xa3\x3d\x9b\x0f\xe2\x22\xf2\x40\x89\x3c\x31\xd4\xb6\xe9\x18\x2e\x22\xdb\x2a\xe4\x69\xd5\x6c\x52\xad\x43\x38\x19\xaa\x80\x6f\xf4\x65\xa3\xfa\x49\x80\x80\xdc\x56\xd6\xe8\xdd\xd4\x5d\x0d\xb9\x64\x00\x17\x91\x95\x45\xda\x9e\x9b\x6a\x5b\x3b\xe4\x2b\xb5\xdd\x56\x16\xe9\x85\x89\xb6\xa1\x98\xad\x0d\x26\xee\xb6\xb2\x48\x2f\xab\x7a\x76\xd9\x4c\x96\xca\x9b\x00\x2b\x4b\x74\x32\x6d\x33\xc8\xc6\x83\xb7\xd1\xb4\xdd\x56\x96\xe8\x4b\x93\xdc\xa9\x98\xc0\x4d\x66\xed\xb6\xb2\x44\xc7\x93\xf6\x81\xea\x16\x1a\x50\x48\x07\xbe\xb6\xb2\x44\xf7\xb5\xdd\x81\xb9\x79\xa1\xdc\xb5\xb2\x46\xcf\xb5\x0a\xff\x01\x53\x76\x5b\x53\xa5\xfb\x3f\x09\x3c\x57\xb9\xb2\x46\x33\x13\xb6\x32\xb6\x51\x61\xd8\x56\x65\x15\x65\xa9\xde\xcf\xd7\xd5\xfc\x4d\x3e\x6a\xab\xe6\xeb\xb6\xb2\x58\x33\xd3\xb5\x46\x00\xe3\x41\x5b\xb9\x79\x75\xcd\x36\xca\xa8\xa5\x63\xb6\x12\x58\x59\xb2\xef\xd4\x3a\x67\xda\x5e\x10\xd9\x90\xcd\x7c\x9a\xaf\x15\x91\x95\x35\xfb\x4e\x3d\xde\xca\x5b\xb3\xd2\x01\x88\x47\xee\x28\x2b\xe7\x28\xef\x53\x58\x68\x46\xdf\x1c\x43\x30\xfb\x66\x27\x7c\xa8\xe9\x9d\x04\xad\x56\xf3\x1c\xe8\x2d\xc7\x63\x7b\x81\xe9\x8d\x3d\xb3\x16\xd3\x19\x7f\x3c\x50\x46\xca\x92\x88\x9c\x4c\x00\x2d\x60\xfe\xc7\xd2\x9a\xd9\x98\x4d\xa7\x8b\xb4\xc7\x3f\xea\xb2\x14\x5f\x8e\x24\x9f\x71\xbc\x59\x6a\x0f\xb2\x4b\x9d\xd6\xf8\x7a\x3a\x5f\xc0\xfe\x63\x69\x8d\xb1\x98\xea\x2f\xab\x89\xea\x15\xc0\x8b\xd4\x1e\xe8\xb4\x0d\x8c\xed\xf9\x9c\x2e\x2e\xad\x09\xa6\x33\x06\x2e\xeb\x1c\xb4\x44\xf9\x4f\x97\xc7\x30\x1d\xe0\x62\x66\x5b\x0b\x7b\x26\x41\x12\xda\x94\x52\x5a\xe5\x3f\x72\x3a\x96\xe0\xa4\xd5\x00\x16\xd3\x1b\x5c\x5a\xe3\x21\x46\x93\x85\x7d\x31\xb3\x94\x73\x8b\xc8\xbf\x10\x96\x25\x5e\x95\x40\x36\x81\xde\x74\xb1\x98\x5e\x8b\xa8\x95\x54\xab\x5c\x13\xa3\x74\x1a\x8d\x1d\xca\xbf\x31\x98\x59\xb7\xa3\xc9\xc5\x1c\xe3\xf8\x39\xc2\xcb\xe9\x6c\xf4\xe7\x74\xb2\xb0\xc6\x35\x66\x08\xe5\xe3\x9f\x2d\x34\x79\xd6\xcd\x5b\x8b\xac\xca\x14\x3d\xb4\xd3\x68\x49\x61\xbf\xd8\xb3\xc5\xa8\x9f\x6b\x56\xeb\xa3\xa4\x08\xaa\x0d\x8b\x4e\xa3\x2f\x05\x1d\x4c\x6f\x27\xb0\x26\x03\xc4\x8f\x50\x9a\x43\x83\x4b\x6b\xac\x3f\x15\xa1\x9b\x72\x35\x67\xd0\x63\x7b\x98\x3e\x9e\xc8\x67\x4d\x46\x9f\x79\x93\xc1\x37\xf0\x5c\xc2\x2d\xac\x47\x92\x95\x33\x49\xda\x52\x49\x96\x37\xac\x0a\x8c\x05\xe1\x5d\x97\x69\x74\xb9\xa3\x0a\xb6\xcd\xc9\x05\x39\xd3\x09\x92\x29\x24\x61\x93\x70\x60\xde\x49\x5f\x58\x95\xcb\xad\x9d\xba\x58\xd1\xe2\x30\xd7\x29\x77\x4c\xcd\xd6\x3f\x65\x06\xe9\xb4\xe4\x7a\xe7\xc4\xd9\x6f\x9a\x4f\x25\x06\xa8\x1a\xcb\x2b\xa5\x29\x09\x05\x2e\xfe\xf3\x5f\x90\x91\xc8\x51\xe5\xfd\x1e\xef\x44\xeb\x75\x22\x1a\xcb\x41\x78\xb6\xe7\x83\x9f\x27\xd2\x18\xb8\x06\x2b\x13\xe7\xea\xc2\x81\x10\xe1\xcf\x89\x8a\xa1\x51\xba\x7e\x2f\x53\x47\xcc\x10\x83\xe9\xb2\x37\xb6\x25\x72\xe4\x9c\xf2\x7c\x20\xa6\x42\x42\x54\xf9\x48\xcc\x4c\x9d\xa6\x1c\x57\x9f\x8a\x15\x09\x98\xdb\xa7\x9c\x4a\x50\xc5\xfc\x1f\x7b\xde\x7c\x34\xb9\x18\xdb\x79\x64\x26\xb2\xa8\xdb\x39\xbe\xe5\x13\xc5\xab\x54\xe2\x3b\x9d\x13\x99\x48\x89\x36\x72\x91\xf6\x32\xd6\x40\x74\xcf\xb8\x16\x8b\xb0\xf2\xa9\xd7\x18\x5a\x8c\x8e\x04\x55\x5e\x99\xaa\x75\xc4\x95\xd5\xd0\x29\xb1\xcc\x2e\x49\x71\x86\x61\x4f\x35\x14\x77\xee\x8b\x9f\xca\x2e\x83\xa0\x95\xd3\x12\x83\xc4\x92\xa4\xf6\xa8\xda\xed\x1d\xa4\x9b\xcf\x25\x76\x4a\x13\x78\xd9\xf0\x51\xf4\xe2\xca\xa2\x88\xd5\x73\x79\xa3\x0b\x9f\x0f\xf9\x4d\x49\x47\x9d\x08\x74\x5e\x14\x48\x19\x3c\xe5\xbb\xd4\x09\x64\x34\xda\x75\x3a\x96\xdc\x58\x85\x4e\x47\x99\xaa\x6a\x05\x1b\x19\xa6\xd4\x9e\xd6\x36\x5c\x00\x99\x75\xee\x46\x63\x52\xa7\x23\x96\x35\xde\x04\x62\xb8\x08\xac\xb4\xe9\x4b\x3b\x43\x74\x06\x5a\x4d\xb3\x5d\x4d\x99\x02\x85\xca\x52\x56\x45\x6c\x01\x38\xab\xe0\x95\x2b\x89\x59\x6c\x1a\x7a\xde\x50\x25\x96\x2e\x20\x4c\xb2\x57\xe9\xe7\xba\x08\x3d\x55\x74\x18\x8a\x8e\xd8\xe0\x10\xa0\xd2\xa9\x44\xe7\x54\xec\x34\x64\xd6\x12\xaa\x8b\xc2\xdf\x4b\xdc\x56\xe6\xa4\xa7\x62\xc7\x21\x33\x4a\x31\x44\x0e\x4c\x52\xe5\x74\x22\x55\xb1\xe9\x28\xda\x24\x9d\x85\x08\xf3\x20\xf4\x47\xa9\x04\xbe\xd8\x78\xf0\xc5\x3e\xef\x3e\x99\x8c\x95\x6f\xa5\xfa\x6b\x82\x2b\x6d\x32\x18\x43\x30\xb8\x6c\xc3\x65\xae\xde\xaa\xe6\x4b\xe4\x2a\xb6\x1c\x7c\x81\xe7\x27\x15\x7e\x14\xe6\x29\x10\xd9\xa9\x49\x69\x8c\x88\x1d\x06\x5f\x3a\x24\xe6\xc8\xd9\x1c\xa9\x46\x64\xc9\x92\x04\x4d\xd2\x44\xe8\x8d\x20\x45\xe3\x41\xd5\x68\x62\x87\xc0\x97\x09\xfe\xc8\x89\x3f\x37\xe0\x0f\x33\x8a\x34\x61\x7e\x4c\x00\x2c\xcd\x78\x7e\x7e\xdb\x2d\x11\x47\xec\x0f\x64\xe9\x48\xe1\xff\x6a\xb3\x4b\x5d\xa1\xdc\xec\x62\xc7\x20\x4b\x4e\xf2\x98\x60\x4e\x2d\xd2\xdd\x17\xfb\x09\x7d\x12\x4d\x64\x10\xbb\x07\x59\x2a\x12\x8d\x54\xcc\xc5\x65\x84\x1c\xfc\xac\x01\x2c\x6f\x6e\xe2\x9b\x5c\xe3\x21\x7a\xe3\x69\xff\x4a\x7f\xd2\xa3\x7e\x49\x38\xb6\x81\xf1\xf4\x56\xe0\x78\x50\x5d\xd3\x1f\x82\x77\xce\xce\x80\xe1\x72\x3c\xd6\x61\xc8\xf8\x55\xc2\xe8\x63\x5f\x9c\xf8\xcd\x10\x6e\x9e\x52\x51\x7c\x07\xa3\xa2\xf6\x40\xe7\x0d\x24\xad\x89\xa0\x36\x21\x65\xaa\xc9\x62\xc3\xa4\x22\x13\xc4\x26\x92\xf3\x97\xf9\xa5\x95\x3f\x67\x77\x54\xec\x0a\x3f\xa0\xbf\xf3\x16\x70\x6d\x0f\x46\xcb\xeb\x1c\x45\xaf\x28\xe0\x00\xe5\x9d\x00\x03\x6b\x76\x95\x62\xfc\x88\x52\x69\xed\xba\xb6\xb1\xd5\xbf\x4a\x6e\x1b\xa9\xb4\x4a\x84\x7b\xf8\x87\xdc\x9e\x3a\x69\x58\x2d\xc0\xca\xeb\x28\x7f\x72\xcb\x04\x30\x77\xd6\xce\x3d\x19\x43\x58\xde\x84\x45\x22\x12\x5c\x16\xba\x8d\xfc\xf1\x37\x59\xea\x27\xcc\xef\x9a\x87\xf8\x7b\xe2\xca\x69\x16\xea\x14\xe9\x73\x2a\xe2\x9d\xe2\xcc\x04\xe9\x35\xac\xee\xf8\xbb\xbc\x42\x9b\x9d\x57\x1f\xed\x2e\xcf\xc0\xdc\x49\x06\x5b\xa6\xd4\x0a\x36\x7b\x27\x33\x1a\x07\x6d\x81\x79\xfc\x8b\xa8\x2f\x12\x2a\x2c\xff\xf7\x0f\xb8\x47\x8b\x85\xa3\x66\xa2\xdc\x75\x0f\xf9\x13\x86\x1a\x81\x09\xa7\x71\xee\x1d\x61\xad\xb1\x17\x84\xb0\x7e\xa5\xc6\x1e\x00\x57\xa3\xe4\xf7\x5e\x31\xae\x98\x24\x91\x0a\xbf\xdb\xb1\xe8\x10\x19\xc6\x10\xb8\x5a\x4a\xfc\x9f\xdd\x1f\x61\x19\x90\x1f\xe6\x51\xbd\x26\x70\x65\x9b\x60\x67\x1d\x41\xc1\x89\x0c\x23\xb8\x88\x7d\x02\x5c\x4d\x45\x77\x56\x38\x62\xc5\x77\x19\x13\x15\x76\x07\x98\x5b\x99\x8c\x0a\x7f\x26\x45\xdf\xe0\xde\x11\x55\x60\x11\xed\xbe\x3f\x03\xf3\x11\x3e\xcd\x2f\x47\xbf\xb0\x5a\x4a\x4d\x9b\xba\x24\x6b\x77\x1e\x96\xc5\x65\x8d\xcd\x5b\x3b\x7b\x23\x0a\x92\x4b\x72\x0e\xcc\x97\xd2\xc9\x87\x8d\x68\x49\xf7\xcc\x44\x36\x61\xe3\xa1\x68\x8f\x0c\xab\x07\xec\x1f\x38\xe3\xbd\x82\x68\x6c\xcf\x69\x42\x73\x5d\xe6\xb0\x2a\x8d\x0f\x80\xf9\xb4\x26\x0d\x22\x3e\x47\xf3\xc6\xe5\x74\xcc\x69\x98\xd3\x2f\x07\x9a\x61\x0e\x81\x85\xc5\x78\x03\x17\x58\x5c\xee\x49\x53\x09\x8b\x49\x0e\xc1\xec\x37\x81\xc5\x08\x9f\xfa\x89\x67\xa5\xc2\x27\x76\x22\x84\xc8\x3d\x56\x12\x73\xea\xa2\xc1\x39\x5c\x41\x82\x36\xb0\x58\xe2\xd3\x62\xbe\xfc\x25\xcb\x9a\xf9\x7d\xb4\x9f\xa8\xef\xfe\x29\x92\x07\x57\xd3\x8d\x8a\x12\x56\xdc\x27\x64\x81\xa5\xd8\xf5\x19\xf6\x8f\xad\x30\x39\x32\x95\x38\xdd\x7a\x1a\xdc\xdc\xf7\x0c\xc7\x8c\x97\x05\x4c\x0c\xaa\x9d\xa9\xe4\x5c\x2e\x2a\xa9\x06\xfd\x1e\x30\x19\x15\x1b\x0c\xfe\x9d\x5a\xbf\xa5\xda\xd6\x61\xf7\x81\xc9\xb2\x34\xff\x27\x29\x39\xdf\xa9\x38\xd1\xb3\x16\x23\xbc\xe7\x28\xab\x7c\x7f\x00\x4c\x6c\xb3\x96\x88\xab\xb9\x44\xa6\x93\xb4\xd3\x51\xda\x8a\xc7\xb6\x81\x09\x53\x05\x79\xb0\x9f\x14\x2b\x43\xb0\xcf\x1d\x17\x56\xa5\x9a\xe6\x7e\x5d\xa0\x58\x91\xd8\x1c\x2a\x65\xc0\x63\x0e\x5a\xc0\xe5\xa8\xc6\xe7\x7b\xe4\x93\x01\x61\x7f\xee\x53\x58\x23\xa3\x25\xd3\x49\x8e\xd5\x01\x2e\x97\xf8\x34\x8c\x93\x90\xb6\xb8\x19\x14\x3a\x41\xa5\x52\xc0\x33\xe0\x52\xd2\x99\xf3\xef\x38\x0e\x84\xe3\x2d\xa0\x26\xf2\x18\x05\xce\xa0\x07\x5c\x4e\xab\x25\x0c\x52\xec\x51\xd9\x5f\x5e\x4d\x38\xbd\x68\x9c\x77\x60\x03\xd7\x96\x59\xe0\x13\x45\x1b\x45\xd4\x6d\x94\xd8\x62\xf1\xd8\x43\xe0\x7a\x54\xe3\x0f\xe9\xd8\x9f\x67\x62\x4a\x69\xce\xa1\xec\xdb\x3d\x6f\xbb\x01\x5c\x2f\x2b\xa5\x56\xd9\xb8\x2a\xb6\x95\x90\xa6\x34\x11\xbb\x09\x5c\xdb\xfa\x1c\x20\xf4\x0a\x9c\x96\xf8\x1c\xc8\xa7\x40\x31\x03\x66\x98\x2d\xe0\x7a\x2a\x4b\xee\x44\x63\x55\xbe\x11\xd0\xbd\x83\xa6\x39\xb3\xdb\x88\x9f\x15\x16\x62\x80\x08\x4d\x26\xa3\x6b\x52\x68\xb0\x45\x34\x53\x1f\xb2\x4f\xc1\x3e\x21\xad\x2b\x71\x06\xef\xaa\x15\x3c\xfb\x0c\xb8\x2b\x8c\x3f\x32\x6c\x4d\x7c\x94\x14\x2b\x25\xf6\x39\x30\xb3\xaa\x34\x4b\x59\xa6\xaf\x7a\xa4\x51\xc4\xb6\x80\xd9\x88\xf9\x65\xb7\x1a\x82\x77\xf9\x23\xf6\x64\x9a\xe7\xd9\x03\x66\x4b\x26\x18\xf8\xd0\xd0\xbd\x23\x4c\x46\x64\x4b\x5c\x7e\x5e\x24\xee\x4e\xdc\x4f\x1f\x98\xd9\x66\x45\x2b\xf5\x71\x36\xd3\xee\x69\xb3\x3a\x63\x0f\x80\xd9\xb4\xa6\x30\xd4\x91\x38\xd5\x68\xde\x48\xbd\x45\x9e\x1b\x86\xc0\x6d\xe1\x58\x4f\xea\x0f\xca\x1c\xcf\xfb\xb0\xd8\xa6\xa9\x7d\x65\xd8\x00\x6e\x47\x92\xfa\xc5\xe7\x53\xa5\x95\xf5\x55\x50\x5f\xdb\x86\x4d\xe0\xd6\x56\xa8\xaa\xf8\x46\x96\xe3\x25\x6f\xe4\xa5\x20\xc3\x6c\x01\xb7\x53\xb3\x43\x10\x81\x5f\xa9\x76\x89\xbc\x59\xcb\xb1\x4f\x80\x89\xb8\x29\x0e\x98\x14\x36\xf5\x81\x3e\x94\x36\xbe\x37\x1a\x8d\x36\x70\x65\x2d\xac\x6b\xeb\x86\x15\xc9\xf8\x5f\xb7\xe6\x50\x0b\x1e\xed\x61\x4b\xfb\x70\xe9\x00\x01\xb5\xf1\xe2\xd0\x21\x5e\x3c\x7a\x81\x97\x2d\xbd\xc4\x8b\x4b\x47\x78\x09\xe8\xbf\xf2\xab\x42\x87\x5e\x21\x5c\x79\x74\x8c\x70\x4b\xaf\x11\xba\x74\x82\x30\xa0\x53\x44\x0e\xbd\xc1\xc3\xca\xa3\x7f\x20\x0a\xb7\x74\x86\xc8\xa5\x73\x44\x01\x5d\x74\x6b\xbe\x43\x97\xf0\x3d\xfa\x05\xfe\x96\xde\xc2\x77\xe9\xbf\xe1\x07\xf4\x0e\x2b\x87\xfe\x89\x95\x47\x1d\x3c\x6d\xe9\x3d\x56\x2e\x7d\xc0\x2a\xa0\x8f\x31\xd6\xab\x43\x5d\xbc\x7a\xf4\x09\xaf\x5b\xfa\x8c\x57\x97\xae\xf0\x1a\x50\x0f\xef\x0e\xfd\x0f\xde\xb7\xf4\x05\xdf\x5c\xba\xc6\x7b\x40\x5f\x73\x09\x37\x0e\xf5\xb1\xf1\x68\x80\xcd\x96\xbe\x61\xe3\xd2\xbf\xb0\x09\xe8\x06\xdf\x1c\x1a\xe2\x9b\x47\x23\x7c\x0b\xe8\x56\xd0\x86\x4f\xbf\x1e\xa0\xc3\x83\x34\x9f\x5a\xf0\x74\xd7\x39\xcc\xfb\xd3\xdb\x9d\x0d\x1d\xea\xd4\x71\x4f\xef\xeb\xf8\x4a\xbf\xd6\xf1\x4c\x9f\xeb\x78\xa4\x8f\x75\xb8\xd4\xad\xe3\xef\x15\xfd\x4f\x1d\x7f\xd3\xbf\xeb\xf0\xa8\xd7\xad\x85\xab\x60\x13\xc1\xa3\xbf\xd7\xf1\x42\x5f\xea\x58\xd3\x75\x1d\xaf\xf4\xb5\x0e\x9f\xfa\x75\x04\x34\xa8\xe3\x8d\xbe\xd5\xb1\xa1\x9b\x6e\x2d\xa4\x61\x1d\x11\x8d\xea\xd8\xd2\x6d\x1d\x4f\xf4\xa9\x8e\x97\x15\x5d\xd5\x11\x85\xf4\xaf\x3a\x1e\x56\xf4\xa1\x8e\x70\x45\xbf\xc5\x16\x5e\x3d\xac\xe8\xf7\x3a\x56\xce\xe6\x91\xfe\x4f\x1d\xef\xee\x66\x4b\xff\xaf\x8e\x30\x78\x8a\xe8\xaf\x75\x6c\xdc\xaf\xee\x26\x74\xe1\xd2\xff\x47\xb7\xf6\xbe\xa5\xff\x5b\xdf\x19\xe4\xdd\x44\x5f\x7d\xe7\xcd\x8b\x9c\x75\x18\xff\x11\xee\xb1\x13\x79\x3e\x1e\xf6\x1f\x61\x1d\xff\x95\xe8\xb0\x0e\xf7\xfb\x83\xfb\x16\xfd\x13\xdd\xda\x2c\x41\xb2\xe9\x6f\x75\xdc\x6d\x69\x57\xcb\x7b\x12\xec\x78\x85\xf1\x9f\x9c\x4e\xf4\xb3\xdf\xc4\x7e\x0b\xfb\x0d\x1c\x67\x36\xf8\x6f\x00\x00\x00\xff\xff\xf9\xa0\x34\x27\x95\x7c\x00\x00") + +func fontsBannerFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBannerFlf, + "fonts/banner.flf", + ) +} + +func fontsBannerFlf() (*asset, error) { + bytes, err := fontsBannerFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/banner.flf", size: 31893, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBanner3DFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\xcd\x8a\x23\x37\x10\xbe\xfb\x29\x0a\x14\xd0\x25\x2b\xb2\xbb\x39\xec\xd4\xc9\x81\x40\x4e\x79\x88\x19\xd6\x93\x04\xbc\x13\xf0\xc4\x84\x79\xfb\x60\xa9\x54\xf5\x95\x24\xb7\xd5\x63\x12\x08\xf4\x2e\x4c\x4b\xad\x9f\xfa\xff\xaa\xaa\xfd\x7c\x7c\xfe\xf4\xf8\x1d\x7d\xa1\x2f\xf4\xe9\x07\xfa\xf0\x91\x3e\xef\x9e\x1e\x5f\x5e\x0e\xa7\xcf\x1f\x7e\xa6\xa7\x37\xfa\xf5\x70\x3a\xfe\xf1\x42\xbf\x9c\x0e\x6f\x7f\xff\x79\x7c\xa6\x6f\x79\xbe\x7f\x3a\x3d\xfe\xfe\xed\x35\x9d\xbf\x1e\x8e\xe9\xf0\xf5\xbc\xfb\xe9\xfc\xdb\xf9\xf5\x2f\x7a\xf8\x9e\x3e\x3e\x3c\xfc\xb8\xdb\x31\xf3\x7e\xe2\xcf\x7e\x17\x43\x08\x81\xf7\x3b\x6a\x9e\x4c\x21\xe4\x5d\x29\xe5\xdd\xed\xbe\x94\x2e\x0b\xf5\x02\xb7\xaa\x5b\x2e\x57\x24\x77\x8f\x5c\xc6\xf6\x6f\x76\x72\x99\xc5\x4c\x48\x96\x28\x13\x32\xde\x82\x32\x56\x56\xd2\xf2\x8a\xbb\x20\x33\x96\x79\xcb\x84\xf4\x94\x5c\x71\x39\x97\xe5\xc8\x02\x66\xcd\x64\xe1\xb3\x84\xb6\x93\x53\x82\x9d\x51\x76\x92\xea\xc2\xef\x4c\x45\x83\xaa\xc2\x90\xe5\xcb\xec\x08\x67\x65\x5a\xb5\x2a\xa2\xb3\xe8\x3e\xd5\xa9\xe8\x29\x8a\x11\x42\x99\x0b\x75\x92\x79\xde\x4c\xb6\x2e\xc6\xa8\x36\xe4\x22\xb2\xdc\x26\x12\x97\x49\x61\xdc\x56\x94\x09\xd9\x15\x55\x2d\x7a\xa6\x1c\x11\x35\x70\x21\x82\xce\x82\x5e\x44\xaa\x64\x91\x0c\x2d\xdf\x3d\x2b\xa7\xc2\x0b\xdb\x51\xe1\xc1\x0f\x1a\x29\x44\x72\xe3\x44\x48\x56\x0f\x65\xae\xea\xea\x07\xb2\x87\xec\x94\x7a\x8b\xf3\xd8\xa8\x76\x14\xaa\xf1\xa6\x8f\xf2\x54\x98\xd8\x4c\xed\x69\x8c\xd9\xfd\xf5\xf2\xe4\x57\x99\xbd\x66\xe1\xc2\xfe\x39\x69\x24\xe0\xef\xda\x30\xa2\xc8\xe2\xf1\xb7\x8f\xc9\x78\xf9\x11\x8d\xc7\x6a\x0e\xe5\x28\x56\xeb\x99\x29\x18\x75\x66\x91\xa5\x43\xf3\x28\x74\x2a\x10\xd7\xf9\x5f\xbd\xe9\x12\x03\x5e\x3b\x6c\x30\x31\x9e\x94\xed\x04\x1e\x12\xc0\x46\xce\xad\x22\x90\x51\x47\x36\x9f\x46\xeb\x0e\x87\xe6\x12\x9c\x20\xd6\x63\x03\x6e\x05\xb5\x4c\x50\xd2\xf8\xc2\x6d\x66\x28\x6a\x26\xbd\x8d\xdf\x4f\x48\x18\x35\x04\x75\x7a\xeb\xf0\x53\xe1\xb3\xe5\x2e\x6a\xb8\x32\xc6\xae\x9b\xb4\x7c\x1b\x0c\xd8\xb6\x32\xf1\x38\xad\x8e\x57\x45\x05\x8d\xd8\xc5\xec\xee\xad\x4c\x7a\x59\x18\x4d\xb3\xac\x32\x21\xa1\xf4\x6c\x1b\x0d\xb6\xcd\xa8\xcc\x4b\x42\x66\x99\xce\x95\x00\x49\x96\xc7\x35\x52\x66\x24\x21\xad\x32\x26\xb6\x2d\x48\xb2\x96\x50\x78\xaf\x97\x55\x9f\x8a\x0d\x2a\x2a\x58\x2f\xaf\x5f\xad\xa0\xae\xc2\xad\xa6\x53\xf6\x90\xa0\xa8\x35\x4a\x82\x3e\xe5\x89\x59\x34\x9b\x39\x94\x64\x18\x44\x17\x0a\xe3\x37\xdd\xa9\x59\xb2\xf5\x0d\x59\x79\xe3\x90\x75\x02\x2b\x20\x1c\x29\x38\xff\xb4\xb4\xa6\xde\x07\x08\xdf\xac\xdc\x70\x97\x18\x6a\xc5\x54\xd2\xb3\x9f\xb8\x70\x4b\x50\xe9\x8c\xdd\x45\x2a\x15\x4b\x33\x88\xcb\xec\xb3\x86\xb1\xd0\x01\xcc\x28\x1a\x92\xa2\x92\x0b\xe5\xc5\x43\x93\x98\xe1\xb6\xa5\x61\xa4\x99\xe6\xf0\xfc\x10\x09\x9b\xf1\x0d\xf4\x9b\x97\x64\x72\x72\x4d\x92\x15\x38\xce\xc6\xcb\x50\xaa\xe0\xc2\x24\x75\x36\xb9\x9b\x80\x8e\x7d\x19\x12\xe1\xb4\x19\xc3\x59\xa3\x4e\x00\x5f\xae\x24\xc3\x84\xbc\x98\x49\x20\xc2\xe3\xac\xb2\x97\x3d\xf7\x96\x1b\x23\x6c\xde\x78\xc6\xd0\xf4\xa1\x45\x37\x50\xfa\x59\x11\x3f\x1c\x63\x42\x9e\x75\x4f\xaf\x09\x28\x32\xa0\x73\xd3\xa0\x27\x68\xa3\x08\x42\x3e\x3f\x1c\xba\x99\x0a\x16\x82\x67\xd5\xf8\xaa\x5b\x3a\x63\x06\xed\xa6\xf2\x11\x70\x14\x07\x7e\x89\x02\xe8\x29\xcd\x19\xd3\xb9\x86\x73\x13\x46\x54\x45\x22\xc1\xb5\x92\x61\x49\x55\x93\x59\x7f\x72\x32\x55\x28\xad\x46\xd7\x34\xac\x96\x79\x10\xd0\xf7\x48\x14\x41\x87\x9c\x30\x7a\xd4\x84\xd2\x57\xdc\x9b\x2f\x5c\xfa\x6e\xe0\x66\xe4\x04\x33\xf9\xa2\x0f\xb6\x3e\x38\x27\xf2\x45\xf6\xf3\xcc\x64\x5f\xb8\xae\x1e\x5b\x55\x32\x0f\x7e\xf7\x7b\xd9\x6a\x42\x7d\x23\x49\x5a\x18\x25\x0a\x4e\xa0\x56\x22\xa0\x14\x31\x20\xe1\x83\xd5\xfc\x2c\x13\x13\x8a\x45\xb0\x4a\xb2\x95\x2c\x21\x6c\xba\xaf\x23\x0d\xcb\x28\x4c\x07\x9d\x63\x6f\x43\x74\x4e\x0a\xc9\xf8\x01\x4b\x6b\xd2\x77\x3b\x83\x47\xd5\xaa\xfa\x51\xf7\xdd\xb6\x46\x1a\xf8\xb7\x8b\x06\x28\x07\x0c\x30\x26\x46\xee\xca\x2e\x9f\x24\xe0\x40\xb5\xd0\xab\x04\xbf\x2e\xb0\xeb\x88\xad\x89\xe8\x4a\x4f\xa1\x6a\x1b\x66\x46\x71\xc4\xb1\xd6\xcc\x05\x3d\x48\xc1\xc3\xd9\xdc\xb5\x23\x33\xc3\x55\x9b\xa7\x3f\x65\x2d\x7e\xd0\x34\x7d\x21\xb7\xc3\x0f\x9a\x5b\x9f\xb0\xf5\x09\x5b\x9f\xb0\x90\xe8\xb6\x3e\x61\xeb\x13\x68\xeb\x13\xfe\x8d\x3e\x21\x6d\x7d\x02\x6f\x7d\xc2\xd6\x27\xfc\x9f\xfa\x04\xcb\xd4\xe5\xf7\x47\x3c\xa8\xbf\x6b\x43\xc9\x8f\xab\xac\xf0\xc9\xee\xa7\x70\xd1\x59\xfd\xab\x3f\x01\x8c\xde\xd7\x9c\xca\x1a\x4e\x28\x52\x1d\x85\xc1\x3b\xcb\xc7\xac\x19\x19\x20\xa0\x4a\x7e\x81\xaa\x6a\x99\x42\xb3\xda\xa6\xf6\x22\x15\x34\x19\xfe\xad\x98\xed\x77\xcd\xff\xff\xea\xc5\x3f\x01\x00\x00\xff\xff\x31\xb1\xff\x2e\xed\x23\x00\x00") + +func fontsBanner3DFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBanner3DFlf, + "fonts/banner3-D.flf", + ) +} + +func fontsBanner3DFlf() (*asset, error) { + bytes, err := fontsBanner3DFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/banner3-D.flf", size: 9197, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBanner3Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\xcd\x6e\x13\x31\x10\xbe\xef\x53\x7c\x92\x7d\x84\x8a\xb6\x48\x55\x6f\xcb\x89\x13\x0f\xd1\xa8\x09\x20\xa5\x41\x4a\x89\x50\xdf\x1e\x35\xeb\x9f\x6f\xc6\x63\xaf\x37\x81\xdb\xa6\x52\x3c\xde\x1d\x8f\xe7\xf7\xf3\x38\xdd\xed\x77\x77\x4f\x1e\x0f\x78\xc0\xdd\x27\x7c\xbc\xc5\x3d\x86\xcd\xd3\xe1\xb0\x3d\xde\x63\xf3\x86\x6f\xdb\xe3\xfe\xe7\x01\x5f\x8f\xdb\xb7\x3f\xbf\xf6\x3b\xbc\x9c\xe7\xe3\xe6\xf8\xf4\xe3\xe5\xf5\xe6\xf4\xbc\xdd\xdf\x6c\x9f\x4f\xc3\x97\xd3\xf7\xd3\xeb\x6f\x3c\x7e\xc0\xed\xe3\xe3\xe7\x61\xf0\xde\x8f\xed\xaf\x71\x70\xce\x39\xaf\x07\x38\x87\xf7\x01\x80\x7e\x37\x8d\xa0\x67\xa0\x45\x08\x2b\x3d\xc2\x47\xd1\xb0\xe9\xf7\xc9\x59\x50\x78\x91\x69\x17\x3f\x9d\xcf\x89\x3e\x6b\x34\x7d\xa6\x15\xe7\x77\x08\x7a\x4f\x93\x69\x0d\xb3\x01\x06\x5b\xb4\x2f\xb1\x05\x05\x02\xef\xc4\x99\x64\x46\xf5\x68\x87\x28\x35\x4f\x83\xdf\x26\xfd\xe3\xda\x6c\x0e\xe2\xdb\x69\x1e\xe5\xa6\x4d\x7c\xf1\x3c\x6d\xc6\xb2\x58\xc5\xc0\x93\x83\x58\xc4\x3b\x09\x2e\x87\xb0\x5d\x54\x21\x8a\x36\x46\xa1\x5e\xd8\x2a\x87\x26\x9a\x6b\x8e\x51\x8b\x18\x3e\x4e\x16\x4a\xae\xae\x3c\x10\xfc\x22\xd1\x92\x5d\xac\x57\x96\x65\xbe\x92\xeb\x0b\x1f\x35\xbc\x99\xb6\xf7\x36\xc5\xea\x37\xf8\xce\xa4\xaf\x7f\x27\x05\xf2\x8e\x59\xa8\xcc\xec\x9c\x71\xd9\x44\xf2\x59\x0e\x26\x07\xde\x70\x6b\xe0\xc9\x79\x66\xd0\x3a\x6c\x1c\x5b\x99\x96\x5e\x3c\x6b\x53\x2e\xd7\x86\x2a\x70\x61\xb6\xaa\x5b\xb6\xab\xa4\xdd\xe5\x42\xf9\xb9\x32\x9e\xf1\x42\xef\xcc\x1b\x58\xb4\xce\x0c\xde\x8c\x41\xc8\xf1\xc6\xd0\xa4\xd2\x92\x78\x59\x47\xb4\xec\xb6\x1c\xd5\x4a\x00\x14\x38\xe9\x8a\x6d\x67\x73\xd1\x22\x67\x55\xac\xc5\xbb\xad\xe2\x92\x05\x3a\x0f\x5a\x42\x51\x3b\x50\xad\x77\x05\x88\xf4\x21\x8b\x40\x4e\x0d\xcd\xb0\x91\x37\x58\xe0\xf3\x28\x2c\x33\xe6\x09\x0b\x66\x24\xd7\x34\x99\xab\x29\x06\x28\x99\x15\x46\xd3\xd0\x95\x0d\x8e\x4e\x40\x45\x97\x48\x20\x03\x17\x94\xd0\x27\x4d\x1d\xfa\x8a\x22\xd4\x74\x5f\xd9\x2c\xe4\xe1\xda\xe5\xd2\xaa\x01\x41\x81\x3e\xaa\xfa\xfb\xb6\xef\xa1\x5b\xd5\x6f\x03\x54\x53\xdb\x28\xe1\xdf\x48\x03\x54\xf6\x54\x10\x99\xf8\x15\x7c\x69\x7e\x92\xb3\xcc\x43\x9d\x1e\x2d\x40\xa4\x31\xb8\x4a\x07\xd0\x22\x8b\xdc\x31\x52\x43\x72\xc8\x86\x3a\xb5\xbb\x28\x9e\x16\xfe\xe2\x93\xb0\x3f\x57\xdb\x39\x21\x1c\x8b\xd8\xa6\x3a\x71\x4b\x11\x18\xd0\xe3\xf0\x42\x66\x14\x49\x48\xc2\x77\x04\x76\x8e\x53\x06\xf7\x9c\x2f\x9d\xcd\xd4\xd2\x72\x2d\x78\x8c\xce\x07\x45\x49\x2c\xd2\x54\x3a\x96\x4b\xe2\x1a\xec\xab\xd7\xa5\xf0\x69\x1d\xfb\x88\xc1\xce\x75\x0b\xfb\x74\x3b\x72\x09\x79\x2d\x7a\x56\xe3\xbd\x78\xb1\xe8\xbc\x45\xbb\xa5\x34\x35\x2e\xbb\x97\x4c\x10\xea\xa3\x54\xb8\x43\x99\x9e\xb3\x56\xc7\x0f\xe2\x66\x71\x49\xa0\x38\xec\xb8\xe8\x9e\xa4\x4f\xa7\xa4\x71\x37\xa1\x90\x4c\xed\x20\xfb\x20\xb2\x42\x5c\x4d\x75\xa2\x8f\x83\xb0\xac\x9b\xc8\xda\x00\x7c\xe7\x13\x95\x39\x77\x57\x55\xb7\xd6\x1e\xc6\xf6\xd5\x78\xac\xfd\x3c\xc5\x9d\x32\xf4\xcf\x15\x6b\x1b\x77\x1d\x10\xd9\xf8\xd8\x3a\x91\xd7\x36\x6e\x6d\xe3\xd6\x36\x6e\x6d\xe3\xd6\x36\xae\x11\xef\xc5\x8b\xd7\x36\x6e\x36\x50\x1c\x76\x5c\xd9\xc6\x41\xfe\x3f\x8b\x09\x57\x3c\x11\x72\xa3\x6d\x9e\xbf\xc2\x42\xfe\x8a\x10\x94\x34\x2b\x08\x67\xbe\xca\xc7\x53\xfa\x77\x0f\x8a\xe0\x21\x9c\x74\xd4\x4a\xa9\x5f\xd1\x9a\x93\x71\x10\x7f\xff\x73\xfa\x37\x00\x00\xff\xff\x81\xfa\x12\x5c\xf4\x1c\x00\x00") + +func fontsBanner3FlfBytes() ([]byte, error) { + return bindataRead( + _fontsBanner3Flf, + "fonts/banner3.flf", + ) +} + +func fontsBanner3Flf() (*asset, error) { + bytes, err := fontsBanner3FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/banner3.flf", size: 7412, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBanner4Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\x4d\x8f\x13\x3d\x0c\xbe\xcf\xaf\x88\x94\xf7\xf8\x62\xb1\xcb\x4a\xab\xde\x86\x13\x27\x7e\x44\xab\x6d\x01\xa9\x5b\xa4\x2e\x15\xda\x7f\x8f\xd4\x49\xe2\xc7\x1f\xc9\x64\x5a\xb8\x4d\x11\x13\x67\xc6\xb1\x1d\x7f\x3c\x71\xe0\x70\x3c\x3c\x6e\xff\x0b\xcf\xe1\x39\x3c\x7e\x0c\x1f\x1e\xc2\xa7\x30\xec\xb6\xa7\xd3\xfe\xfc\x14\x76\xef\xe1\xeb\xfe\x7c\xfc\x71\x0a\x5f\xce\xfb\xf7\xdf\x3f\x8f\x87\xf0\x7a\x9d\x8f\xbb\xf3\xf6\xfb\xeb\x1b\x5d\x5e\xf6\x47\xda\xbf\x5c\x86\xcf\x97\x6f\x97\xb7\x5f\x61\xf3\x7f\x78\xd8\x6c\x9e\x86\x81\x88\xc6\xf6\x63\x1c\x28\xc6\x18\xcd\x40\x31\x4e\x1c\x57\x46\xfc\x96\x46\x7c\x87\x8b\x70\x65\x5e\x3e\x4f\x5f\x27\x57\x41\xe9\x03\xd3\x31\xff\x3a\xdf\x33\x3d\x59\x34\xfd\xa6\x15\x94\xfe\xc2\x64\x5a\x83\x6c\x44\x0e\x5b\xde\x5f\x66\xcb\x06\x24\xde\x89\xb3\xc8\x2c\x5f\x59\x43\x96\xca\xd3\xe4\xb7\xc9\xfe\xbc\x96\xb7\x93\xb4\x65\xd7\x64\xb9\x45\x89\x7d\x5f\x94\xa1\x2c\x34\x31\xf1\x70\x10\x4d\xbc\x8b\x60\x33\x64\x75\xd9\x84\x2c\xda\x19\x85\x79\x49\x15\x87\x26\x6f\xd7\x1d\xb3\x15\x39\x7c\x98\x2c\x22\xb9\x3a\xf2\xc0\x4d\xc6\x32\x29\x6e\x46\x42\x0a\x52\x3c\xb8\xde\x0c\x75\x6f\xb2\xfa\x0a\x85\xe6\xd7\xf9\x26\xb2\xf1\x2c\x06\xb0\x46\x16\x2a\x33\x9b\x33\x8e\xb7\x08\x3e\xe3\x60\x62\xe0\x1d\xb7\x26\x1e\xce\x33\x87\xd6\x61\xc3\xd8\xca\xb4\x94\xef\xda\x54\xe4\xda\x50\x05\x2e\xb6\xad\xea\x16\xf7\x65\xe9\x78\xbb\x50\x7c\xaf\x36\x8f\x78\xa1\x35\xa3\x02\x8f\xd6\x99\x81\xca\x10\x84\x22\x2a\x26\x4d\x2a\x2b\x81\x17\x6d\xa4\xd6\xbe\x3d\x47\xb5\x12\x80\x0c\x4e\x46\xa3\x76\x36\x17\x1d\x72\xde\xc4\x5a\xbc\xdb\x26\x2e\x59\xa0\xf3\xa0\x25\x94\x6a\x07\xaa\xf3\xcd\x82\x48\x1f\xb2\x08\xe4\xd4\xd0\x4c\x2e\xf2\xe6\x1d\xc0\x28\x76\xe6\xcc\x0b\x16\xb4\x25\xd7\x2c\x99\xad\x29\x04\x28\x99\x15\x4e\xd3\xd0\x95\x0d\x11\x4e\x40\x45\x5b\x24\x90\x81\x4b\x46\xe8\x93\xa6\x0e\x7d\xa6\x08\x15\xdd\x59\x36\xcb\x78\xb0\x76\x45\x69\xd5\x80\x40\x91\xa6\xfa\xfb\xd4\xf7\xd0\xad\xea\xf7\x01\xaa\x69\x6d\x92\xf0\x97\xa4\x71\x2e\x5b\xee\xca\x19\xa1\xe0\x4b\xf3\xb3\x9c\x85\x1e\xea\xf3\xa8\x05\x91\xc6\x10\x2b\x1d\x40\x8b\x34\xb9\xe3\xa4\x86\xe4\x90\x0d\x75\x69\x77\xc9\xbc\x35\xfe\x1a\xfb\x13\xb4\x3b\x27\x84\x63\x4b\x9b\x1a\xc5\x2d\x45\x60\x40\x8f\xc3\x8d\xcc\x2c\x12\x90\x04\xef\x08\xe8\x9c\xa8\x36\xdc\x73\xbe\x74\x36\x53\x4b\xcb\xd5\xf0\x38\x9d\x0f\x99\x92\x58\x64\xa9\x74\x2c\x96\xc4\x3d\xd8\x57\xaf\x4b\xe1\xd3\x3a\xf6\x01\x83\x9f\xeb\x1e\xf6\xe9\x76\xe4\x06\xf2\x6e\xf4\xac\xc6\x7b\xf1\x62\x38\x58\xf1\x82\x9c\x8f\x37\xf0\x17\x06\xf3\xf6\x09\xa5\xfa\xb0\x06\xcf\x1b\xd3\x73\xd6\x9a\xf8\xa1\xc8\xe8\x74\x93\xf3\x81\xc2\xb0\xb3\x34\x22\x4f\x5a\x8c\xe4\xdc\x93\xf4\xe9\x54\x8c\xec\x26\x14\x92\x29\x0d\xa8\x57\xec\x02\x6c\x44\xcb\x89\x94\x35\x84\x90\x3f\x47\xb0\x35\x44\x78\xe7\x13\x95\x39\xce\xdd\x69\x11\x51\xba\x18\xdb\x57\x63\x3e\x01\xd5\x41\x48\xd8\x29\x93\xfe\xe7\x8a\xb5\x8d\xbb\x0f\x88\x7c\x7c\x6c\x9d\xc8\x6b\x1b\xb7\xb6\x71\x6b\x1b\xb7\xb6\x71\x6b\x1b\xd7\x88\xf7\xe2\xc5\x6b\x1b\x37\x1b\x28\x0c\x3b\x4b\x23\xf2\xa4\xc5\x99\x36\x8e\x10\xa7\x81\xb1\x80\x88\xfb\x89\x88\x91\x4c\x3c\xd2\x42\x78\x14\x08\x2a\x96\x19\x22\xba\x9f\xf8\x78\x4a\xa4\x84\x6a\x74\x80\xfa\x8f\x8f\xee\xc9\x38\x88\x3f\xff\x72\xfa\x27\x00\x00\xff\xff\xb5\x05\x67\x1b\xf4\x1c\x00\x00") + +func fontsBanner4FlfBytes() ([]byte, error) { + return bindataRead( + _fontsBanner4Flf, + "fonts/banner4.flf", + ) +} + +func fontsBanner4Flf() (*asset, error) { + bytes, err := fontsBanner4FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/banner4.flf", size: 7412, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBarbwireFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x8f\x1c\x35\x10\xbd\xcf\xaf\xa8\x43\xae\x40\x58\x21\x11\x24\xcb\x6a\x22\x11\x89\xeb\x5e\xb8\x26\x48\x1b\x14\x69\x05\x12\xe4\x02\xbf\x1e\xcd\x8c\x3f\xde\x7b\xf5\xdc\x3d\xb3\x44\x6c\x36\x6d\xbb\xdb\xae\x72\x7d\xbd\x2a\x7b\x3f\x3e\x7f\x7c\xf8\xf0\x2a\xde\xc4\xf7\xf1\xf0\x3a\xbe\xfa\x36\x1e\x4e\x6f\x7f\x7c\x7c\xfb\xcb\xcf\x8f\x3f\xc5\xaf\x7f\xc7\xe3\x1f\xbf\xc7\xbb\x3f\x3f\x7d\xfe\x27\xde\x7c\xf3\xc3\x77\xa7\x77\x9f\x7e\x7b\x7e\xfa\x1c\x8f\x4f\xcf\x4f\x1f\xfe\x7a\x8a\x87\xaf\x5f\x9f\x5e\x6d\xe6\x37\xb6\xed\x54\x4b\xe1\x47\xb4\x47\x44\xb4\x77\xe7\xde\xe5\x65\x2d\xa3\x89\xb8\x7c\x3f\x6e\x5a\xdb\x7f\xce\xc3\x5a\x4a\xb4\xe7\x85\xc3\xf9\x27\x2e\x6d\xfa\x7a\xe7\x64\x64\x74\x19\xf7\x2f\x97\x5d\x5f\x45\x2b\xb2\x8f\xb6\xae\xab\xa0\xcd\xcb\x54\x51\x92\x46\x67\x4c\x85\xb9\x93\x68\x63\x75\xe1\x5e\xfc\x32\xda\xe9\x9c\x3b\xf6\x32\xd7\x97\xb9\x5c\xe6\xc1\xda\x49\xf0\xfa\xa5\x19\x6a\xfd\x68\xdb\x6c\xe4\x1a\x7d\x6d\xc6\x7e\x3b\xbb\xce\xc1\x7d\xa4\x86\x88\xb2\x12\x45\x92\xf1\xe8\xf2\x34\x83\x75\x9b\x47\xb3\xbc\xf9\x6e\xd6\x33\x7d\xe3\x16\xe8\x8d\x91\x1d\xa1\xeb\xba\xb3\xdd\x9b\x96\xa9\x21\xa3\x9d\xc7\x30\x51\x5f\x96\x5b\xe2\x6e\xbe\xdf\xc5\x89\x95\x0f\x52\xbc\xc0\x83\x45\x5a\x09\x72\x20\x88\x84\xd0\xab\x06\xeb\x41\x6e\x7a\x0c\x6e\xab\x79\xbe\xda\x71\x1b\x20\x23\x6e\xe8\x9a\x0a\x4a\xa4\x9d\x8e\x28\x6a\x94\x8c\x6e\x50\x23\xa8\x87\x89\x45\x1c\xcb\x06\x25\x8c\x62\xd9\x39\x09\x67\x7a\xe8\x17\x75\x2f\xab\x63\x76\xc3\x8a\xa3\x1e\x20\x1c\x21\x10\x4f\x39\x5a\xbc\x8e\x49\x92\xc2\x1e\x20\xe6\xf1\x92\x78\xbc\xb3\xce\x82\xda\x46\x0f\x9c\xf6\xc9\x4e\xd4\xa7\xe5\x24\x20\xc6\xae\x23\x77\xa0\xd8\xc9\xd8\xac\xd2\x45\x7f\x4f\x92\x3e\xf0\x4e\x1f\x73\xbf\xe1\x25\x01\x55\xec\x19\x3f\x19\x78\xea\x9c\xa5\xab\xc5\x42\x17\x2b\xdb\x1a\x7f\x8d\x24\x82\x29\x87\x13\x01\xe6\x86\xfe\x25\xc5\x2b\xb6\xe0\x2e\x8d\x67\x19\xdd\x40\xa7\x16\x82\x4e\xfb\x26\x75\xee\xdf\xc0\x81\x08\x44\x58\x88\x6d\xa7\x4c\x6a\x5a\x72\xae\xb6\xef\x24\xab\x0d\x0a\x18\x38\xc1\xe5\x0f\x64\xc8\x16\x2d\x95\x41\xf7\xfd\xfb\xf7\x09\xbb\x7d\x51\x35\xbd\x1c\x5c\x2a\x04\x09\x9c\x9b\x51\x66\xe9\xc1\xc8\xb8\xaa\x69\x21\x99\x9b\x6c\x35\x31\x0d\x97\xce\x55\x0d\x7e\x12\xbe\xcf\x10\x81\xfa\xc2\x85\xb6\x44\x18\x15\x66\x64\x6e\xe9\xe3\xfc\x18\x51\x2d\x0c\x06\xcc\x8f\xc5\x24\x3c\x32\x5b\xf4\x21\xc1\x25\xd0\xd8\x20\x45\x29\x68\x43\xb7\xef\x6c\x77\x82\x06\xdc\x17\x21\x9c\x3c\x6c\x43\x5d\x75\xb7\x35\x1e\x61\x07\x3d\xcb\x0f\x25\x81\x9f\x19\x38\x15\xc4\xdc\x19\xcc\xa4\x71\xe3\x9a\xc4\xe8\xe8\x01\x81\x45\xd5\xc7\x51\xaf\x16\xac\x9b\x8a\x9e\x56\x20\xe6\xe0\xe0\x41\x65\x49\x8b\x8b\xca\x66\xc1\x69\xab\x8c\xeb\x74\x79\x8b\xb1\xef\x75\xb3\x36\xe8\xf2\x4e\x5b\x4f\x29\x2a\xd8\x80\x41\x6e\xe0\x90\x21\x45\xc3\x88\x24\x51\xf1\x7c\x41\x79\xcc\x95\x99\x72\xbc\x06\xb1\x4c\x1c\x27\xd6\xe4\xca\x47\xb4\x9f\xf7\xef\xc7\x81\x25\x41\x38\xfa\x46\x62\x89\x58\x87\x39\x39\xaa\xf7\x40\x70\x29\xa1\x08\x78\x64\x9e\x64\xad\x3a\x2a\x58\x48\x58\x1a\xe7\x67\xdb\x93\x64\x2c\x9b\x1b\x85\xba\xa7\xe6\x75\x35\x87\xb7\x65\xdf\x0d\xab\x4f\xb2\xaa\x64\xf5\x0c\xfd\x48\x27\xd9\x2a\xb8\x9e\x61\x62\x5f\x66\x44\x0c\xb3\x31\x5e\x3c\xb8\x01\x95\x8d\xce\x86\xb1\xd1\xb1\x7d\x71\x31\x02\x92\x45\x13\xe7\x77\x19\xc8\x6d\x64\x27\xde\x2a\xd7\x04\x09\x24\x10\x18\x66\x32\xf3\xf1\xba\xda\x00\xaa\x61\x88\x5c\xa1\xf6\x41\x59\xd2\x37\x0b\xe1\xd6\x6b\x2d\x43\x52\xfa\x8a\xe1\x3d\x23\x66\x98\x0e\x64\x60\x54\x63\xd1\x08\x73\x68\xa9\x52\x0a\x14\x93\x4a\x80\x61\x13\xf4\xb0\x49\x57\x5d\xc2\x4e\x0f\x08\x69\xaf\x10\x52\xcb\x73\x0b\x5e\x63\xee\x37\xe6\x0e\xa3\x32\x94\xd6\x83\x34\xfd\x92\x41\x1f\xdd\xdf\xb6\x9b\xab\x51\xe5\xe4\x13\x22\x3f\x08\xe1\xb4\x3f\x25\x1d\x61\xe6\x0a\x66\xf1\xd5\x92\x51\x13\x76\xb7\xe8\x92\x16\xb9\xd0\xa6\x09\x59\x47\x72\xa0\xac\x58\x8d\x0e\x36\xf0\x66\xce\x61\x42\xeb\xba\x0f\xc1\xc4\x56\x80\x6c\xf4\xdb\x75\xaa\x07\x09\x3a\x22\xc5\xac\xa3\x97\x49\x7d\xeb\x07\xce\xf3\xb2\xf1\x07\x02\x42\xab\x45\x27\xed\x54\xbb\x8c\x64\x6a\x11\x78\xdb\x15\x45\x91\x09\xda\x38\xcd\xc8\xc5\x1e\x5d\xc3\x24\xed\x96\x70\x3a\xc5\x9b\xf5\x83\x7a\x7e\x08\x61\xc7\xb6\xbd\xd6\x9e\xdb\x6a\xc3\x72\x88\x6f\x2a\x2f\xe4\xc1\xab\xad\x0f\x9d\xad\x9f\xd3\x27\xfd\x25\x43\x90\x42\x47\x86\x03\x0b\x89\x69\xfc\xf0\x2a\x64\xd5\x4d\xee\xbb\x43\xd5\x0b\x83\xe4\x03\xa4\x9e\x44\xfc\xc5\x28\x23\xd4\x6d\xfd\x96\xfc\x0d\xf7\x3d\x71\x65\x12\x56\x54\xb1\x06\xf7\x04\x03\x70\x05\x09\x4e\x43\x54\xaa\x8c\x47\xaf\x2c\x2e\xcb\x14\xae\x72\xa7\x4a\xfc\x7b\xdc\xab\x85\xae\x88\x3b\x72\x04\x20\x85\xe2\xd4\xe6\x80\xe1\x36\x14\xa1\xe4\xba\x56\xbe\x1e\xd5\x7c\x2f\x9a\xda\x16\x00\xaa\x69\x92\xf3\xac\x4d\x40\x63\x93\xa6\x8e\xf1\x79\xd6\x70\x62\x56\x83\x57\x61\xd8\x9f\xa3\xeb\x2f\x84\x40\xa4\x5c\x78\x10\x61\x88\xe8\xe0\xec\x31\xb3\x85\x24\xdd\x45\x84\x2d\x09\x57\xf9\x23\x6b\xc9\x75\x93\xb8\xdf\x3e\x61\x72\x28\x09\xcf\x4d\xee\x66\xdd\x2d\x43\xc8\xa1\x19\x3a\x7a\x5c\x95\xdc\x25\x7e\x7c\xbd\x4d\xbc\xfe\xbf\xf2\xa3\xb1\x86\x45\x26\x57\xab\x0f\x06\x76\x99\x6d\xb8\xed\x84\xae\x84\xa3\xff\xa9\xbf\x9d\xe4\xdf\xff\xf5\xe2\xdf\x00\x00\x00\xff\xff\xef\x0e\xd2\x08\xe7\x20\x00\x00") + +func fontsBarbwireFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBarbwireFlf, + "fonts/barbwire.flf", + ) +} + +func fontsBarbwireFlf() (*asset, error) { + bytes, err := fontsBarbwireFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/barbwire.flf", size: 8423, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBasicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\x4b\x6b\xe4\x38\x10\xbe\xfb\x57\xd4\xc1\xe0\x4b\x56\x90\x61\x61\x6a\x60\x59\x1c\xba\x59\x18\x58\x58\x9f\x04\xba\x39\x1a\x4d\x66\x13\xc2\x1a\x66\x92\xc3\x5c\xfc\xdb\x97\x7a\x48\xb2\xec\xb6\xba\x33\x0b\x0b\x03\x9d\xf4\xa3\x2c\xdb\xa5\x7a\x7e\xfa\xe4\x7e\x78\x7e\x78\x77\xdf\x02\x02\xc2\xed\x7b\xf8\xe5\x16\xde\x35\xfe\xfe\xdb\xe3\x27\xf3\xf0\xfc\x00\xfe\x3b\x1c\xbe\xde\x3f\x7e\x81\xbf\xba\x3f\x9e\xef\xff\xfe\xfc\xf5\xe5\x3b\xfc\xf6\x69\x7a\x78\xee\x1f\x5f\xcc\x3f\x2f\xaf\xe6\x73\x78\x35\xf7\xaf\xbf\x37\x77\xaf\x5f\x5e\xbf\xbd\xc0\xed\xfb\x1b\xb8\xfd\xf0\xe1\xd7\xa6\x6d\xfb\xda\xbb\x6f\x82\x6f\xfb\x06\xb1\xed\x1b\x37\xb4\x7d\x03\xd0\xea\x58\x3e\xa4\x8f\xbe\x31\x93\x01\x33\x99\xb6\x6f\x46\xec\x60\xc4\x8e\xcf\xf0\xdf\x8f\x48\xc5\x60\xf0\xf4\x6a\xfb\xe6\x80\xf4\x77\xa4\x31\x44\x7a\x95\x63\x6e\xa0\x57\x45\xe1\x9d\x0c\x9a\x40\xb7\x18\xf6\xac\x43\x60\x57\x46\xf4\x68\xf4\x96\xd1\xa2\x37\xec\x28\xc5\xfb\xc8\x67\x11\xd1\xa9\x4f\x56\x15\x06\x0f\x00\xe1\xc8\xc1\x00\x08\xd1\xe5\x80\x9d\xa8\x21\x41\xec\xc7\x0e\x38\x68\x3c\xa2\x91\x3b\x61\x21\xdb\xe5\x0d\x8d\xe2\x00\x00\x78\x24\x71\xb4\x3e\xe9\x0c\x88\x07\x99\xf2\x40\x3a\xf5\x02\x44\x1c\xc0\xf9\xac\x0c\x0a\xb1\x6f\x0e\x74\x6e\xe4\x18\x75\xcb\xb4\xad\x3e\xe4\x26\x56\x0f\x8b\x29\x45\xdf\x01\x55\x00\x1b\x05\xb0\x68\xe2\x54\xf6\x98\xe6\x94\x19\xa3\x19\x23\xfa\x68\x0f\xfa\x28\xa0\x5e\x8d\x92\x2e\x43\xee\xd2\x1c\x43\x61\x7c\x59\x06\x68\xe0\x0e\x0c\xb2\xc3\x06\x8d\x86\x1b\xc9\x2c\xce\x69\x87\x23\x67\x0d\x3b\xb0\x30\x62\xbd\xae\xc4\xc5\x68\x99\xea\x38\xa4\x4a\x8a\x23\x00\x76\x28\x0c\x2a\x2c\xdb\x46\x91\xb3\x6c\x79\xee\xa1\x08\xea\x69\x25\xcb\x19\x77\xaf\xb9\x64\xc6\x61\x9b\xc6\x98\xc7\xb3\x95\xa9\x86\x74\xd5\x66\xa4\xd2\x94\xca\xe4\x5c\xc5\xee\x01\x08\x1d\xa3\x03\x22\x84\x0e\x50\xb2\x83\x69\xce\xd1\x21\x0e\x1d\xec\x57\xa6\xf4\xc5\xc4\x37\xc2\xf6\x53\x1d\x83\xf8\x99\x7a\x84\x9d\x06\x18\x63\xf0\xa6\x70\xec\xa4\x92\xd4\xb5\x27\xa4\x76\xe6\xba\xc1\x32\xc8\x2b\xd7\x18\x0b\x36\x0a\xa7\x69\xd2\x76\x9f\xe7\x39\x82\x01\x08\x18\x38\xba\x63\xd8\x01\x38\x12\x9f\x50\x1a\x13\x9e\x70\x16\x90\x7a\xc2\x4e\xe1\xca\x16\xd6\xc8\x18\xf7\x4f\x0d\xb8\x26\xfa\xe3\xa8\x0c\xf3\x3c\xcf\x64\xcd\x10\x2f\xb4\xc9\x7e\x1a\x10\xfb\x11\xa7\xc9\xbb\x8a\x85\x10\x8e\xb0\x57\x0a\x39\x20\xc8\x48\x9e\xf0\x6f\xdf\xc2\x90\x9c\xb2\xe7\x91\x50\x27\xa9\xd6\x5b\xce\x32\xa3\x8e\xd8\x60\x63\x52\x4c\x88\x49\x59\x9c\x75\xd5\xa4\x2c\x15\x26\xa7\x2c\x4e\x78\x81\xad\x3b\x31\xdc\x36\xdf\x4e\x2f\xee\x5d\x58\x81\x09\x13\x78\xdc\x04\x81\xa1\x9b\x88\x8b\x63\x86\x55\x9b\x60\x75\xb4\xfe\x04\x64\x9e\x44\x97\xb7\xe2\x4d\xac\xb1\xd3\xd3\x9a\x68\xac\xb4\x5e\x10\xa8\x0c\x5b\x10\x3f\xd3\xb4\x40\x18\x01\xda\x77\xb0\x00\xde\x0a\x1e\x4d\x51\xa3\xa4\xc9\xa1\x2c\x9a\x44\x15\x28\x74\xe8\x81\xb2\x3b\x70\xbb\x12\x10\x40\x88\x78\x54\x54\xc9\x06\x8f\x4c\x50\x9c\x0b\x5c\x27\x5e\xbb\x69\x52\x94\x9b\xe7\x39\xe2\x1d\x80\xf2\x22\xa8\xad\xe9\xcb\x6e\x5a\xb6\xa7\x54\x32\x2b\x5c\x55\xf2\x39\x78\x21\xd7\xd5\xf3\x21\x3b\xae\x17\xa2\x8f\x92\x23\x31\x60\x46\xe1\xb7\x59\x18\xdd\x2b\x25\x93\x2d\x3c\xd6\x15\x6a\xe4\x62\x97\xb3\xcb\x8c\x61\xec\x32\x63\x98\x20\x34\x44\x85\x58\x8f\xe1\x29\x85\x2a\xcd\xf3\xac\x52\x72\x7e\xd8\xa8\x29\x62\xc8\xf5\x08\xaa\xd0\xa9\xea\x14\x43\x64\xc4\x55\x0b\x67\x24\x5b\xc1\xd5\x01\x90\xa9\xa0\x5f\xc5\xeb\xbf\x96\x8d\xf8\x4c\x39\x89\x98\x24\xc4\x64\x23\x1a\x54\xee\x2a\x81\x5c\x46\x72\x53\xe0\x54\x14\xaa\x17\xc6\x5c\x16\x79\x25\x12\x29\x78\xa3\x92\x3b\x83\xfd\x89\x05\x23\xc2\x8d\x28\x44\xbc\x51\x46\x87\x18\xf9\x1f\x22\xf9\x61\x92\xeb\xfb\x0b\xb2\x5f\x26\xa2\x26\xf9\x69\xe2\x1d\xc7\x99\xf2\x31\x28\xad\x10\x19\xbf\xf3\x61\x18\x53\x3a\xe4\x5d\x3d\x20\x83\xe5\xbd\x08\x66\x11\xd9\x98\xb4\x45\x19\xe0\x94\x54\x59\x9c\x92\x56\x5e\x73\x74\x02\x5a\xba\x15\x13\xc1\x56\x93\xb6\xa2\x5f\x2e\xd1\xaf\x65\x97\x46\xfa\xe5\x2f\xa7\x5f\x7b\xe8\x24\xc0\x7c\xaa\xb3\xb2\x74\xba\xb3\xde\x64\xe9\x50\x58\xda\x39\x7c\xbb\xa5\x5e\x71\x74\x5b\x66\x3c\xd3\x7e\x99\x15\x9b\x40\x48\x9b\xc0\x29\x6d\x02\x1d\xae\x78\x5f\xb1\x09\xac\xb6\xec\x48\xed\x3e\xcf\x5d\xa5\x65\x97\xa2\x1b\xd6\xfe\x96\xae\x73\x43\x64\x74\xd9\x04\xb2\x10\xa5\xd4\xdb\xbe\x99\x37\x0b\xc9\x65\x8a\x9d\x88\xc3\xba\x96\xd0\x27\x8e\x74\x91\xc5\x45\x37\x00\xc0\x47\xfc\x58\x18\xbc\x38\x76\xab\x63\x9a\x37\x60\x27\x9f\x3a\x39\x2f\xc7\xd9\x82\x9d\x36\xdc\x7a\xb6\xe3\x83\x09\x83\xdb\xd4\xa9\x2c\x1b\xae\xd2\x89\xe7\x15\xff\x68\x92\x13\x85\xbe\xfc\x61\xc2\xb9\x45\x33\xae\xe4\x7b\x5f\x7f\x66\x2e\x98\xbe\xe2\xd6\x1d\xa2\x87\xca\xfb\x58\xd4\xd5\x28\x53\xc0\xb4\xa3\xcf\xa4\x6e\x6b\xc9\x21\x6f\xaa\xf7\xbe\x0e\x88\xb8\xb5\x04\x64\x8b\x1e\xf3\x65\x95\x98\x11\x59\x5c\x72\xde\xfd\xb0\x56\x16\xc1\xb5\x99\x67\xa4\xc3\x99\x4d\x24\x3f\x92\x91\x52\x68\xfb\xda\x03\x96\x2b\xbf\xbc\xf2\xcb\x2b\xbf\xbc\xf2\xcb\x2b\xbf\xbc\xf2\xcb\x2b\xbf\xbc\xf2\xcb\x9f\x96\x5f\x02\x2d\x0b\x7a\x36\xfb\x1c\xc9\x52\xa4\x8d\x2e\xff\xf8\x63\x32\x69\x4c\x9a\x48\x11\x27\x4c\xdf\xd0\x6e\x8e\xfb\xc6\xc6\x27\xf9\x30\xe6\x5f\x9e\xbc\x49\x21\xd0\xdf\xab\x14\x88\x4c\xfa\xbd\xaa\x78\x7c\xab\xd4\x86\xda\x8f\x32\x21\x1c\x72\xbf\x78\xdf\xc6\x27\x57\xff\xff\xd7\xc0\xbf\x01\x00\x00\xff\xff\x8d\x92\x02\x2a\x14\x1e\x00\x00") + +func fontsBasicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBasicFlf, + "fonts/basic.flf", + ) +} + +func fontsBasicFlf() (*asset, error) { + bytes, err := fontsBasicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/basic.flf", size: 7700, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBellFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\x7b\x6f\xe4\xb6\x11\xff\x5f\x9f\xe2\x87\x60\x01\x25\x80\x44\x9e\xbd\x97\x1e\x6e\x71\x48\x37\x0f\x5c\x7b\xed\xf9\x02\xc4\x09\x8a\x02\x44\x29\x5a\x4b\xef\x2a\xb7\x96\x0c\x49\x7b\x86\x03\xa2\x9f\xbd\x18\xbe\x44\x69\xed\xa4\x3d\xd4\xde\x95\x28\x8a\xf3\xfa\xcd\x70\x66\xb8\xb7\xc7\xdb\x4b\xb5\xc2\x9f\xf0\x35\x2e\xbe\x46\x79\x81\xcb\x75\x76\xa3\x8f\x47\x76\x7b\xbc\xcd\xde\x77\x0f\xba\x47\xad\x06\x8d\xa3\x1e\x47\xdd\x0f\x05\xee\x4f\x6d\x3d\x9e\xd4\xd8\x74\x6d\x01\xd5\xee\x70\xd7\x0c\xb5\x3e\x1e\x55\xab\xbb\xd3\x80\xfa\xa0\xda\xbd\x1e\x70\xf3\x88\xbf\xeb\x76\xc4\x07\x35\x0c\xba\x2d\x90\xe1\xb3\xfe\x3e\xea\x76\x6c\xb7\xf5\xe3\x8d\xee\x87\x7b\x55\x6b\xd6\xf5\xfb\xcf\x63\xf5\x5e\x0d\xa3\xd7\x6e\x83\x8b\x17\xfc\xe2\x82\xbf\x7e\x99\xfd\x72\x7f\xbf\xb0\x10\x5d\xdf\xec\x9b\x56\x1d\x8f\x8f\x64\xc4\xdf\xba\xe1\x70\x52\xf8\x4e\x1f\x8f\x9b\x2c\xfb\xa0\x1f\x86\x7d\xdf\x9d\xee\x87\x0d\xd4\x71\x64\x6a\xa8\x9b\xa6\x54\xfd\x98\xbd\xed\xbb\xbb\x0d\x7e\x1d\x08\xbb\xad\xaa\x07\x76\xaa\xd5\x71\xaf\xfa\x47\x56\x2b\x7c\x99\x70\xf9\x2a\xbb\x3e\xdd\xfc\xaa\xeb\x71\x83\x7f\xea\x11\xdf\xb6\xdd\x78\xd0\x3d\x3e\x74\x6d\xf9\xb6\xd9\x1f\xf5\x88\xb7\x5d\x3b\x66\x57\x7a\x18\xd4\x5e\x97\xef\x7e\xd8\xe0\xcd\x95\xea\x2f\xd6\xec\xc5\xab\xf5\xcb\xf5\x25\xbb\x5c\xaf\x5f\xad\x97\x22\xbe\xc9\x7e\x50\xa3\xde\xe0\xfa\xd4\x16\xb8\x58\xe3\x4a\xf5\xb8\x78\xfd\xfa\x25\x5e\xbc\xda\xac\x5f\x6e\xd6\x97\xf8\xcb\xd5\xcf\xd9\x8f\xfd\x5e\xb5\xcd\x6f\xd6\x79\x1b\xfc\x7c\xd0\xf8\xa5\x6d\x3e\xe9\x7e\x68\xc6\x47\x74\xb7\xf8\xde\xf1\xcb\xde\x37\xad\x1e\x36\x58\xbf\xc8\xae\x47\x35\x9e\x86\x0d\x7e\xfa\x31\xcb\xde\xe5\x9f\x34\x0e\x6a\x87\xf1\xd0\x0c\xf8\xd8\xd4\x1f\x9b\x76\x0f\xd5\x77\xa7\x76\x87\xdb\xae\x87\xc2\xc3\xa1\x39\x6a\x86\x77\xb7\x50\xed\x63\xd7\x6a\x3c\xa8\x76\x1c\x30\x76\x50\xbb\x5d\xd6\xb4\x70\xc6\xd6\x07\xd5\xab\xda\xa2\x4d\x11\xe4\xec\x2e\x9b\xdf\x34\x9a\xb1\xc0\xbe\x43\xdf\xec\x0f\x23\xd4\x41\xab\x1d\xcb\x32\x87\x5e\x56\x96\x99\x09\xde\xfc\xe2\xaf\x6a\x40\x33\xe2\x46\xeb\x16\x0a\x37\x6a\x87\x47\xad\xfa\x02\x5d\x8f\x87\x83\x1a\xff\xfc\x05\xad\x2a\x71\xa5\xfb\x46\xed\xba\x1a\xdf\xf5\xaa\xdd\x3d\xde\x9c\xea\x8f\x45\xe0\x61\x26\x76\x00\x4e\xf7\x5d\x8b\x5e\x8f\xa7\xbe\x25\xb3\xc6\x0e\xe3\x41\xe3\xfa\xd0\xf4\x1a\xea\x76\xd4\xbd\x7d\xfe\x87\xea\x09\x28\x1a\xfe\xd4\xb4\x7b\x96\x30\x20\x76\xcf\xf8\x1f\xdf\xd6\x6a\xa7\xef\x9a\x1a\xdf\x77\x77\xf7\xa7\x91\x04\x5c\xeb\xfe\x53\x53\xeb\xa1\x78\xda\x07\x30\xd9\x0a\xc0\x6a\xfb\x5f\xdc\xb6\xd9\x8a\x6f\xb3\x95\x49\xbe\xd5\x36\x5b\xe5\xf4\xa2\x28\xe8\x2d\xbd\x76\xeb\xd3\x8b\xa5\x67\xf4\xb1\x13\xa5\x29\xe9\x63\x67\x0d\x7d\x68\xb6\x74\xb3\x4e\x56\x4e\x1f\x2f\x16\x5e\x74\xf2\x4f\x2f\x24\x80\x82\x96\x70\x08\x70\xbb\x58\x48\xce\x21\x1d\x19\x07\x87\xa0\x11\x07\x84\x24\xb5\xf2\xa7\x39\xa1\xd8\x66\xe0\xdb\x8c\x38\x24\x5f\x22\xb5\x16\x81\x0c\x8d\x17\x46\x17\x54\xdb\x38\xb4\x32\x4c\xbc\x14\x56\x90\x33\x98\x2c\x26\x84\x18\x0c\x2c\x2e\x10\x65\x6e\x89\x0a\x23\xec\x2b\x0e\x03\x81\x60\xa6\xc7\xa9\x08\x80\x1b\x37\x60\x65\x59\x96\x79\x3a\x03\x54\x98\xd0\xb1\x64\xab\xc5\xd7\xaa\xee\xd5\x88\x4b\x03\xb7\xfc\x89\xf9\x67\x39\x71\x7b\x9f\x05\x82\x33\x86\xdb\xa7\x22\xb7\xe2\xe6\x41\x02\x48\x69\x31\x67\x39\xc0\x85\x05\x0f\xdc\x22\x64\x8a\x1c\x76\xc0\xab\x44\x13\x4f\xc6\xac\x40\x63\x59\x25\x57\x69\xa4\x5d\xe7\x16\x49\x29\x9d\xdb\xe1\xc0\x87\x74\x6c\x68\x82\xe6\xa5\x94\x45\x60\xfb\xbb\x04\x70\xd8\x0b\x29\xe5\x57\x33\x82\x80\x09\xed\x5a\xab\x40\xc5\xa4\x34\x01\xa5\xf3\xc1\xa4\x98\xf4\x54\xd6\xef\x65\x59\xb2\xb0\xd4\xc9\x61\x79\x8a\x34\xa1\xb4\xf2\x20\xd9\x00\xf3\x04\xc6\x13\x54\x6c\x49\xe0\x2d\xc9\x27\x4b\x24\xf7\x2e\xa9\x7c\xd4\xaf\x96\x04\x48\x4c\xff\xa6\x2c\xcb\x37\x9e\x41\xe5\x55\x3c\x93\x90\x12\xd0\x02\x93\xd8\x70\x46\x30\x8f\x92\x24\x5a\x96\x2f\x42\x40\x2e\x76\x31\xd2\xf8\x73\xa3\xa2\x2c\xd3\xc8\x78\x66\xee\x3c\x1f\x48\x78\x2f\x57\x04\x62\x05\xc0\xaf\x77\x81\x8a\x02\x21\xb7\x10\xb5\x0d\x51\x6b\x2c\x38\xa4\x64\x64\xae\xa1\x18\x32\x64\xa8\x81\x90\xd2\x8f\x08\x2b\x12\x8d\xca\x2a\x01\x4b\xec\x76\x37\xdc\x90\x9b\x30\xa4\x64\xe3\x86\x9c\xf4\xa5\xf8\x2a\x5c\xde\x21\xfe\x31\x83\x93\xc2\x56\x7a\x8c\x4b\xeb\xff\x42\x96\x6f\x10\x22\x28\xf8\x67\xb9\x47\x82\x8b\x58\x88\x02\x57\x5b\xd2\x01\x28\x5e\xe3\x1e\xb0\xd2\x58\x2a\xad\x8a\xab\x4d\x3a\x20\x95\xf9\x3c\x1b\x11\x59\xdc\x3c\x6e\x4f\x10\x56\x61\x73\x38\x8e\xa4\x24\x3f\x93\x26\x03\x55\x20\x4a\xb6\x46\x98\x4f\xb6\x5c\xd0\xcf\x99\x15\x05\x4c\xa2\x5c\x5e\x27\xcb\xa4\x99\x0a\x83\x43\x92\xc8\xc3\xc6\xf1\xf2\xa4\x41\x3a\xc3\xad\x73\x66\xb6\xc9\x45\x25\x9b\x12\x9d\x74\x7f\x7e\xa3\xf0\x49\x57\x73\x3e\xac\x08\xb3\xc9\x98\x80\x5b\x62\xa8\xad\x98\xd2\x65\x7e\xe3\x5d\x3d\xe5\xa2\x80\xd8\x02\x19\xb3\xb8\xf3\x14\xe3\x60\xf4\x64\xb5\x37\x5b\xd8\x58\xb4\x73\x82\x4f\x86\x27\x96\x27\xc4\x90\x9e\x04\x81\x24\x8e\x20\xe2\x08\xc2\x2c\x88\x9d\xaf\x62\x08\x56\x2c\xfa\xca\xcc\x46\xd6\x57\x2c\x9f\x13\xb3\x45\x82\xa1\x98\xcf\xff\x38\x32\x52\x71\x53\xa8\x07\x1d\x0b\xe9\x86\x24\x91\x55\x31\xe9\x3e\x2b\x53\x46\x99\x4f\x3b\xc3\xe7\x06\x1a\x7d\x19\xf7\x14\x79\x9a\x45\xd5\x4c\xa8\x1c\x2c\x5f\xc2\xf3\xbf\x44\xcf\x7c\xc1\x2c\x18\xc0\x02\x1c\x2e\x82\x9e\x41\xf8\x4c\xbe\xf7\xad\x9c\xa3\x44\xce\x8d\x71\x20\xac\x54\x5f\x02\x9f\x95\xef\x99\x70\xff\x60\x26\xdc\xa7\x07\x2e\x02\x57\x5b\xd7\x05\x5d\x12\x66\x5e\x23\x84\x68\xab\x58\xa2\x44\x58\x5b\xe4\x62\xf2\xbd\xc0\xd2\x1c\x44\x6a\xa4\xe4\xa8\x58\xb4\xa1\xf0\x05\x94\x36\x19\xce\xcd\x09\x1e\x41\x6c\x02\x23\x13\x56\x96\x41\x63\x6f\x27\x15\x9b\xdc\xad\xe7\xa9\x25\x0e\xda\x59\x2f\x38\x5d\xca\x32\x14\x33\x8a\x0a\xaf\x81\x08\xb9\xd8\x87\x4f\x08\xcb\xc8\x29\x69\x1b\xe3\xc5\x72\xfa\xe3\x1a\xf9\xd4\xc8\x29\x5d\xcc\x3a\x5d\x5b\x76\xc5\x59\x57\x97\x36\x39\x08\x5d\x85\x45\xa0\x4a\x0b\x02\x6d\x60\x6e\xe6\x49\x33\x90\x89\x50\x87\x0c\x4f\xeb\x90\xad\x5a\xa4\xc6\xb2\x6a\xa5\xd2\xa6\xcd\xbc\xac\x5a\xec\x09\x32\x99\x36\x94\x56\x49\x63\x9d\x14\x94\x9c\x49\xab\x9e\xb6\x6d\x92\x16\x2a\xaa\x2d\x24\xc5\x4c\x5a\x11\x4b\x5d\xe5\xb2\x84\xaf\x3d\xc9\x8d\xa7\x8a\x21\x48\x60\x67\xf6\x18\x5f\x1a\x5c\xf3\x24\xac\xf2\x29\x7a\x3c\xd0\x9b\x22\x34\x7d\x81\x9e\x47\xfa\x09\x06\x7f\xce\x3a\xaf\x54\x69\x14\xb0\x30\x10\xb3\x06\x95\x57\x7e\x60\xb5\xb0\xf8\x88\xa4\xae\x16\xa1\x39\xb7\xe0\xbc\x09\x1b\x51\xc8\x59\x5b\xe8\x4e\x32\x94\xb6\xce\x6e\x5c\x48\x99\x44\x76\xd8\x2f\xee\x54\x20\x41\xdf\x95\xb3\xaf\xa2\x6f\x6c\x70\x43\xd3\x01\x7b\xda\x03\x9f\xd1\xa6\xb6\x15\xa1\xb5\x23\x88\xa6\x6a\x63\x9e\xc1\x2a\xf5\x3d\x3b\x6f\x94\xcc\xef\x44\x9a\x45\xa9\xf0\x71\x61\x57\xcf\xc8\x4c\xe8\x7e\xc5\x9c\x6c\x0a\x35\x36\xc5\x5a\xec\x5b\xdc\x29\xc1\xc6\x42\x2c\x4c\x66\x76\x34\x63\x8b\x03\x8a\xf1\xad\x2b\x5f\x1e\xcd\xe6\xc2\xa6\xfa\xe4\x05\xb0\x55\xac\x49\x73\xdb\x98\x4f\x10\x5c\x46\xc7\xcd\xee\x62\xca\x75\xab\x54\xb1\xc2\x57\x21\x93\x54\x1e\x9f\x17\x62\x5a\x98\x2b\x36\x6b\x4a\x6c\x4c\x55\xf1\x50\x22\xf8\xf2\xd0\x8a\x29\xe5\x82\xce\xf3\xbe\xce\x19\x2f\x05\xf8\x97\xef\xe1\x05\x87\xe0\x69\xb6\x4b\x94\x94\x94\xc5\xed\x22\x77\x14\xa5\x9a\xe4\xd1\x14\xe7\xe8\x45\xbb\xdc\x76\x71\x39\xeb\x59\x5f\xd9\x2d\x33\x97\x16\x92\x65\x3c\xff\x3a\xeb\xb8\x47\xbd\x9a\x4e\x52\xfe\xc7\x03\x39\x95\x09\xb7\xa9\x5c\x83\xb8\x68\x3e\xdd\x4f\x29\xdb\xcc\x46\xba\x55\x1c\x74\xe8\xb5\x1a\x49\x1e\x7f\x46\xc1\xfc\xf3\xef\x65\xb1\xf8\xff\x3e\xfc\x27\x00\x00\xff\xff\xd8\x43\x60\x70\xb3\x15\x00\x00") + +func fontsBellFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBellFlf, + "fonts/bell.flf", + ) +} + +func fontsBellFlf() (*asset, error) { + bytes, err := fontsBellFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/bell.flf", size: 5555, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBigFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7c\x6b\x73\xe2\xb8\xd2\xff\x7b\x3e\x45\xbf\x48\xd5\x42\x15\x13\x83\x73\xff\xd7\x4c\x0a\x07\x9c\xc4\x67\x00\x73\xb8\x64\x77\xfe\xe5\x5a\xad\x93\x38\x09\x67\xb9\xe4\x01\x32\xb3\x39\xe5\x0f\xff\x94\xee\x92\x2d\x19\x13\xf2\xa4\x66\x40\x18\xac\x6e\xa9\xbb\x7f\xdd\x2d\xb5\xfc\x34\x7b\x72\xe3\x03\x38\x87\x53\x38\xb9\x80\xe6\x09\x34\x1b\xd0\x00\xf7\xf8\xf8\xf4\xa8\x72\x35\x7d\x86\xfb\x77\xb8\x99\x25\x8b\x05\xb4\x5f\xe2\xd7\xd7\x64\x36\x83\x63\xe7\xe2\x08\xbe\x7c\x81\xfb\x78\x9d\x3c\xc2\x72\x01\xa3\x4d\xbc\x78\x8c\x57\x8f\x95\x60\xf1\x30\x7b\x7b\x4c\xd6\x10\x8c\x42\xe8\xc6\x9b\xe9\xe2\x4b\xb3\x72\xb3\x4a\x92\xbf\xe1\xe1\x25\x5e\xc5\x0f\x9b\x64\xb5\xc6\x3d\x5e\xad\xde\x1e\x12\xf8\x57\xfc\x77\xf2\x2b\x7e\x87\xaf\xaf\xf7\xff\xa1\xcd\xd6\x22\x79\x9b\xc7\x8b\xc5\xe1\xdb\xaf\x78\x93\xac\x66\xcb\xe5\xe1\x43\x7c\x59\x79\x9a\x3e\xcf\x92\x0d\xac\x92\x59\x12\xaf\x13\x70\x0f\x5d\x4c\xbf\xbf\xfc\x99\xcc\xef\x93\x15\x34\x2f\x2e\x4e\x2b\x83\x64\x35\x9f\xae\xd7\xd3\xe5\x02\xa6\x6b\x78\x49\x56\xc9\xfd\x3b\x3c\x4f\x7f\x26\x0b\xd8\x2c\x61\xbe\x7c\x9c\x3e\xbd\xc3\xe6\x65\xba\x86\xa7\xe5\x62\x53\x87\x78\x0d\xb3\xe5\xe2\x19\xbf\x6f\x5e\x92\x0a\xf9\xc1\x34\x59\xfd\xb6\x86\x45\x3c\x4f\x70\x1f\xaf\xb3\xf8\x81\x0e\x30\x86\x87\xe5\x7c\x9e\x2c\x36\x30\x9b\x2e\x92\xc3\x4a\xa5\x47\x7f\xfd\x88\xc7\x32\x88\xdf\x66\x70\xf5\xb6\xda\x2c\x17\xf0\x75\xbd\x9c\xbd\x6d\xa6\xcb\x45\x2b\x89\x57\x9b\x97\xd9\x74\xf1\xf7\xe1\x22\xd9\x5c\x42\xd3\x75\x2e\x4e\x31\x23\x53\x3a\x45\xb0\x48\x7e\xc1\x6b\xbc\x8a\xe7\xc9\x26\x59\x55\xd6\x6f\xaf\xaf\xcb\xd5\x86\x76\x78\x1d\xdc\xe0\xd1\xc6\x8b\x47\xdc\xfc\x7d\xba\x38\x04\xe8\xc5\xef\x10\xcf\xd6\x4b\xb8\x4f\x60\x3d\x9b\x3e\xbf\x6c\x66\xef\x30\xe7\x5c\x3c\x2d\x57\x70\x9f\x6c\x36\xc9\x0a\xde\xd6\x49\x65\xf9\x44\xba\x7f\x7a\x9b\xcd\xbe\xfc\x9a\x3e\x6e\x5e\x9c\xbf\x93\xd5\xc2\x59\xcf\xdf\xd6\x2f\x10\xcf\x36\xc9\x6a\x11\x6f\xa6\x3f\x93\x75\x1d\xee\xdf\x36\xf0\x98\x3c\xc5\x6f\xb3\x0d\x2c\xdf\x36\xaf\x6f\x1b\x3c\xf2\x7e\x38\xc6\x02\x5b\x3c\x27\x8f\x87\x15\x38\x68\x15\xfd\x6f\x55\x00\x10\xb4\x2a\x90\x42\x9a\x7d\x45\xf8\xb5\x8a\x6a\xf8\x37\x00\xec\x95\xde\x40\x6e\xa9\x42\x0a\xe4\xcb\x3b\xb8\xa3\x5f\x1f\x80\xf9\x1d\x94\x77\xda\x40\xe4\x1f\xb9\x8a\x52\x48\x53\x48\x29\x17\xf8\x3a\xfe\x9f\x16\x7f\x83\x99\x4b\x51\x2a\xbb\xd5\x68\x28\x84\x10\xbd\x9a\x42\x8a\xdf\x1d\x40\x64\x38\x11\x42\x10\x91\x11\x00\x38\xe4\x7b\x94\x9a\x39\xc5\x4c\x22\x44\xe7\x01\x1c\xfa\x63\xc0\x0d\xfa\x33\xdc\x20\x2d\xdc\x20\x7c\x3a\xc8\x91\x73\xa6\x33\xd5\x52\xf8\xa3\xcc\x21\x3e\x07\x55\x40\x50\xe3\x3d\x21\x88\x9c\x88\x88\xa1\x8a\x2e\x01\xbe\xe2\xab\x11\x42\xc8\x89\x9c\x6c\x0f\x1a\xa7\x64\x40\x98\x72\x4a\xb9\x3b\xc8\xbd\x6a\x52\xa4\xe3\x62\x83\x62\x13\x64\x7c\x83\x08\x45\x8c\x1a\xbe\x11\xd1\x39\x8d\x20\xe2\x53\x6b\x7b\xc3\x73\xa1\xdc\xc8\xe4\xce\x86\x19\xa5\x90\x3a\xb4\x8b\x08\xfe\x82\xdf\xe8\x94\xa6\x88\xfe\x2c\xa5\xac\xd5\xe1\x90\x91\x89\x9c\x14\xa5\x91\xa3\xc9\x58\x6b\x67\x67\x5c\x55\x2f\xa1\x41\x8a\xfa\xf0\xdf\x1d\xe8\x32\xca\x4a\xcb\xfc\x9a\x9f\x6c\x83\x78\x65\x13\x91\x3f\xca\x04\xf9\x4b\xd9\x0f\x14\xe2\x07\xf9\xdb\xca\x73\x62\x30\x52\x10\x12\x06\xd8\xa6\xb9\xc0\x35\xb7\x70\x2e\x10\x93\x3c\x55\x51\xae\x20\x02\x32\x64\x0b\x31\x2d\x20\x4a\x6b\xef\x10\x31\x83\xb1\x2b\x10\xc3\x20\xe5\x5e\x76\x23\x65\x24\x45\x8c\x0f\x80\x83\x1a\xbd\x41\x0c\xd0\xc1\x1d\xf3\x09\x4f\x05\x65\xd9\xe0\x72\xe1\x3d\x89\xae\x10\xaa\x71\xe2\x08\xbe\x72\xf9\xd5\x18\x26\x6e\x19\x92\xd0\x3b\x0a\x5d\x4a\x93\x73\x23\x95\x10\xf8\x0f\x74\x85\x34\x8a\x5f\x2a\x10\xf0\x01\xa5\xb4\x37\x9d\xfb\xd2\x9c\x02\xb7\x63\x5d\x15\x58\x87\xf0\x9b\x90\x70\x95\x4f\xc7\x56\x69\x6a\x3a\x0e\x4c\x1e\x70\x20\x54\x4e\x12\x92\x4a\x97\xd7\xba\xbc\xe6\x9b\xf4\x4e\x70\x75\x09\x4c\x48\xe5\x39\x2d\xee\x30\x42\xa8\xce\x79\x97\xd6\x82\x9c\xad\x28\xa1\x5a\xe2\xc1\x36\xdb\x2c\xba\xc1\x08\x2b\xcc\x94\x99\x21\x33\xc6\xbe\xc2\x57\x60\x08\xca\x94\x57\x42\x75\xd6\xe3\x8a\x6b\x66\x30\xb2\x42\x54\xb1\x74\xb8\x07\xc3\x0c\xe8\x9c\x5c\xc2\xa5\xc2\xa9\x36\x81\x1a\x67\x06\x63\x86\xac\x31\x0b\xeb\xc0\x52\x02\x8b\x31\xeb\x1c\x0a\xd3\x26\x52\xe6\x5d\x13\x37\xfd\x97\x40\xac\xaa\x40\x2a\x22\x76\x36\xe6\x28\x6b\x3a\x19\x02\xfc\x1b\x27\x92\x1f\x1c\xdc\x87\x54\x6e\x31\x1d\x0e\x65\x24\x52\x00\x56\x11\x51\x76\x46\x73\xb0\x04\x0a\xd2\x72\xc3\x06\xa9\xf1\x69\x59\x63\x17\xc2\x65\x0c\xf1\x09\x38\x10\x60\xa5\x34\xc5\x6f\xa3\x42\x45\x90\xb0\xc4\x59\x55\xbc\x82\xe2\x16\x14\xbf\x80\x52\xc9\xae\x3e\xc3\xc6\x8e\x91\xe8\x58\x43\x3c\x71\x35\xcd\x72\xbc\x45\x75\x77\xef\x98\x77\x41\x14\x70\x3b\x4c\x19\xe7\x18\x38\x39\xe2\x04\x32\x53\x51\x66\x8e\x89\x3a\xe7\x27\x56\xcc\x26\x85\xf2\xec\x74\x63\x8e\xd3\x12\xc2\xcb\x46\x46\xc2\x27\x89\x96\x12\x41\x65\x78\xcd\xe1\x20\xe7\x94\xfc\xa5\x90\x66\x9a\x08\x0c\xfc\x1b\xec\xcd\x30\x05\x04\xff\x70\xc8\xc8\xc2\x55\x1e\x2f\x02\x83\xc0\x94\x47\x8a\x38\x4c\x54\x2c\x4c\xc7\x08\x24\x2e\xaa\xc2\xb5\x35\x77\x52\x2b\x29\x67\x88\x1c\x2e\x8e\x08\x2b\x03\x1b\x6f\xe4\xe4\x6d\xa2\x84\x90\xa4\xf0\x23\x31\x77\x10\xf1\xd6\x21\x08\x34\x8b\x40\xf4\x19\x15\x09\x09\xa9\xee\xaf\xac\xc9\x96\x11\x92\x05\x0b\x90\x02\x5c\xac\x8b\x0f\x58\xd6\xc7\x38\xd6\xb1\xf6\x23\x1c\x03\x08\x8e\x23\xa1\x60\x59\x10\x2f\x89\x05\x55\x31\x8e\x48\x8b\xd8\x54\x14\x2f\x03\x8b\x6a\x28\xa9\xc5\x92\xb0\xa5\x8d\xd2\x6c\xd6\x94\xf5\x71\x36\xb0\xd9\x57\x3b\x10\xb3\x3c\x62\xc6\xc4\x3b\x8a\x58\x26\xa2\x56\xc2\xee\x8e\xb0\xf5\x88\x58\x81\x7c\x23\x3a\x8b\xb2\xa1\xa2\xc1\x79\x72\x42\x59\x62\x39\x82\x39\xa2\x39\xc2\x79\xe2\x06\x06\xcc\x17\x38\x23\x82\x03\x41\xfa\x8e\xd3\xbc\xe4\xb1\x9b\xc3\x91\x0b\xc7\x07\x9a\x5e\xe9\x96\xcb\x46\xa6\x0c\x4a\x8e\x07\x29\x43\x01\x39\x8a\x5d\x85\x4f\xfe\x78\x42\xc1\x52\xc6\x03\x63\xca\xc8\x73\xb7\x62\x87\xa0\x78\x5a\xa1\x3c\xe6\x77\x81\xb3\xa2\x33\x65\xc8\x52\x8a\x42\x7c\x42\x6e\x52\x60\x91\x90\x94\x7d\x0e\x41\xf1\x78\xc2\xdf\x99\xde\x95\x48\x45\xe3\x08\xe8\x92\x45\xea\x44\xf4\x32\x5b\x57\x31\xbe\xe9\x49\x6b\x7e\xd2\xcb\x36\x0f\xec\x81\x7b\x4b\x4f\x1a\x80\x72\xb5\x6d\xe1\x27\x3b\x31\x14\xb1\x40\x00\x16\x77\x29\x55\xc5\xbc\xeb\x45\x62\xe6\x17\x19\xae\xeb\xc9\xa9\x92\x4b\xca\x78\xf5\x70\x4b\x72\x0a\xd9\x30\x5f\xc5\x53\x81\xa6\x02\x4b\x6d\x09\x3e\xa8\x01\x09\x17\xb1\x40\xad\x0f\x0c\xb5\x98\x33\x88\xb8\x2f\x71\xb6\x72\x26\xef\x4a\x55\x13\xc8\x9a\x8a\xba\x2e\xa0\x29\xe2\xc7\xa4\x28\xa6\xc0\x11\x6b\x1c\x58\x10\xbb\x49\x51\x89\x5e\xd2\x42\xb5\x90\xf9\x6d\x7e\x8d\x99\xdf\xa8\x29\x26\x93\x95\xc8\x99\xd9\x67\x9b\x91\x3a\xdc\x48\xd5\x21\x88\x11\xb0\x46\x36\x72\x04\x96\x3d\x15\xc7\x89\x59\x76\xb7\xb2\x9e\x9f\x04\xfe\x09\x11\xb1\xa8\x13\xf9\x57\x66\x01\x4d\x9f\xd0\x4c\x44\x98\xef\xd3\x26\x7e\x04\x7b\x48\xcb\xa2\x4f\xc5\x2b\x25\x5b\x8d\xb8\x14\x87\x22\xdc\x3a\xd4\xe3\x43\x19\x1e\xee\xaf\xf1\x6a\x3a\x92\x32\xe4\xcc\x08\x9e\xf3\xc7\xd8\x93\x76\x28\x19\x29\x80\x19\xf5\x9d\x41\x02\xc7\x2a\xbe\xdd\x40\x8c\xcd\x68\xcc\x08\xcc\x0e\x11\x90\x86\x0e\xb8\xa7\xb4\x34\x1a\x20\x35\x94\x33\x2d\xce\x6e\x05\x3a\xbd\xc3\x6d\x11\x4d\xb4\x65\x91\x2c\x77\x5d\xe9\x56\xeb\x59\xeb\x5c\xeb\x3f\x43\xc2\x14\x00\xe6\xa5\x8a\x90\xec\x9c\x75\x7c\xc9\x40\xc0\xc1\x5d\xda\x40\xe0\x63\x73\x5a\x80\xb0\x06\x35\x41\x2c\x18\x51\x57\xf5\x1c\x64\x97\xb2\xbe\x0c\x28\xb6\xb5\x1c\x19\x24\x29\xd7\xf5\xe5\xc0\xed\xb8\x96\xc1\x38\xd3\xf2\x9e\xec\x19\x22\x13\x27\xda\x32\x1f\x19\x53\xe4\xa4\x34\x60\x62\x52\xb4\xed\x11\x5a\xf7\x0a\x91\xdc\xc6\xab\xa2\x1a\xc2\xf0\x43\x7f\xe0\xa8\x4b\x6e\x48\x5b\x71\x53\x17\xdc\x32\xeb\x6d\x5a\x5b\x13\x29\xeb\xbd\x65\xdd\xe1\x28\xbb\xaf\xa1\x74\xc8\x5c\xd9\x9e\x1b\x25\xf9\x0e\xf7\x0f\xd8\x0c\x1d\x7e\x1c\xeb\x4d\x1d\xee\x07\x3f\xe6\xcd\x26\xee\x28\xd2\xaf\x62\x09\x54\x5e\x4b\x99\xf3\x40\x69\xae\xc3\xe6\x69\x03\xa0\x1f\x7e\xb9\x1a\xfa\xde\x77\x18\x0d\xbc\xb6\xbf\x7d\x67\xbc\x79\xda\x04\x08\xfa\x77\xfe\x70\xec\x77\xc0\xff\xa3\xdd\xf5\x7a\xde\x38\x08\xfb\xd0\xf3\x86\xdf\xf5\x00\xa7\x4c\x94\xd0\x3c\x75\x01\xda\x7e\x7f\x0c\xa3\xe0\xa6\xaf\x63\x0e\x5f\xab\xe6\xf6\xc5\x77\xaa\x95\x30\x17\x80\xc6\xf8\xda\x66\x35\xed\xf7\x08\x60\x10\x4e\xfa\x1d\xa5\x63\xb9\xb7\x4c\xf6\x51\x11\xb3\x0e\xba\x96\xc7\x5d\x1a\xa2\x6b\x9d\x82\xb4\x58\xb5\xa8\xa2\x7a\x6e\xc9\x2b\x8f\xb5\xcd\xd3\x63\x80\xf6\x64\x38\xf4\xfb\xed\x1f\xda\xa0\x88\xf5\xd1\x3d\x6b\x82\x1e\xc0\x20\x4e\x6a\x14\x33\x53\xfc\x2d\x31\x52\xc7\xa2\x0a\xcd\xd3\x13\x80\x1f\x7e\x9f\x77\xcf\x9c\x10\x9b\x92\x48\xe4\xf0\x88\x38\x22\x91\x1d\x01\x5f\x74\x51\xda\x65\x92\xe0\xe6\xe9\x29\xc0\xd5\x30\xfc\xee\xf7\xe1\xca\x1b\x16\x44\xae\xc6\xeb\xb8\x83\x33\x80\x91\xdf\x26\x7a\x22\xa6\x84\x31\x8c\x1c\x20\x52\x75\x78\xba\x1a\x41\xc4\x80\x94\x24\xf1\x44\x9d\x34\x17\xa7\xcb\xf9\x1c\xa0\x13\x78\xfe\xd0\x1f\x05\x23\x8b\xd5\x1d\x80\xcc\xfc\x8a\x5a\xc6\xa9\xbe\x00\x68\x87\x83\x1f\xc3\xe0\xe6\x76\xac\x32\xcf\x32\x4f\x01\xb6\x6c\x45\x4e\x20\x2e\x95\x66\x0a\xdc\x50\xc5\x02\x1f\x5f\x07\x65\xca\xc5\x2f\xe0\x3b\xc9\x92\x51\x0a\xd2\xb9\xb3\xbf\xac\x83\xe7\xcc\x9d\x35\x00\xae\xfd\x5e\xd0\x0f\xfa\x3e\x84\xc3\x4e\xd0\xf7\xba\x10\xf4\x3b\x41\xdb\x1b\x87\xc3\xf2\x88\xa8\x2d\x62\x17\x6c\xfe\x37\xcf\x9a\x00\x5d\xff\x7a\xfc\x65\x10\x06\xfd\x71\xd0\xbf\x81\x4e\x38\xb9\xea\xfa\xe0\xf5\x6f\xba\x3e\xfc\x7b\x12\x8e\x35\x34\x10\xfe\x9c\x3a\x72\xe1\xd1\xc5\x4e\x9d\xb2\x57\x27\x77\xeb\xac\x6b\x15\xcd\x33\x17\x48\x29\x8f\x66\x57\xea\xdc\xb4\x0a\x76\x5d\xd5\x65\xe5\xc2\xca\x82\xe6\xd9\x11\xc0\x28\xbc\x1e\xc3\xed\x8f\xc1\xad\xdf\xb7\xc5\x3d\xfa\xd2\x43\x6e\xfa\x0a\x27\xf2\x18\x60\xe8\xdf\x04\xa3\xb1\x3f\xf4\x3b\x3b\xe9\x15\xdb\x00\x13\x7a\xc5\xb3\x05\xa1\x57\x7c\x3b\x4c\xea\x15\x5d\xff\x8e\xca\xeb\xd5\x09\x40\xcf\x6b\x0f\xc3\xfe\xee\x85\x1a\x65\xcb\x37\x9a\x67\xa7\x00\x1d\xff\x66\xe8\xfb\x62\xf8\xd2\xbf\x09\x67\x2b\x7d\xad\x23\xa7\x35\xd3\xc8\x62\xc2\xd9\x19\xc0\xa0\x3b\x19\x7d\xe9\x05\xfd\xc9\x48\x99\x5c\x50\x01\xbf\x65\x29\x7f\x31\x8b\xd5\x20\xc2\x73\x80\xd1\x64\xe0\x0f\x47\xed\x61\x30\x18\xc3\xf8\xf7\x50\x5f\x4c\xab\xb5\x4c\xf1\x6b\x71\x6c\xd7\x3c\xbb\xc8\xf4\x7a\x3b\xf4\x7d\x35\x2e\x46\xbc\x3a\x2b\x93\x3e\x6d\xe9\xf7\xbc\x01\xe0\xb5\x27\x63\x1f\xbc\x36\xf6\xb7\x15\x16\x37\x3b\xf4\xf6\xfc\xf2\x58\x6e\x91\xac\x79\xde\x04\xe8\x05\xed\x61\x98\x73\x6b\xaa\x51\x14\x45\x38\x38\x9b\xad\x2b\x39\x24\x68\xd9\x6c\xf3\xdc\x05\x18\x04\xdd\xf6\x30\xfc\x5d\x51\x09\x65\xdb\x80\x1a\x31\x55\x0c\x5a\x41\xc2\x74\x43\xb4\x89\x35\xc8\x36\xa9\x88\x2b\x72\x6d\xe7\x47\x78\x4c\x9d\x4e\xd7\x87\x4e\x38\x56\x07\x6c\x2c\x46\x30\x4c\x0a\x76\xf7\x7e\x27\xe8\x76\xbd\xcc\xdd\xf9\x57\xd2\x5f\x4d\xd4\x3e\xe0\xbb\x4f\x74\x69\x87\x7d\x9f\xff\xce\xc9\xbb\x57\x2b\x0f\xa7\xd8\x5c\x47\xed\x49\xb7\xc0\x0f\x94\x09\x64\x4b\xfb\x81\xf3\x33\x00\xe2\x11\x4b\x3a\x02\x09\x69\x91\x5e\x16\x21\x0b\x23\x64\x69\x04\x2f\x8e\x28\x48\x9d\x9b\xe7\xe7\x00\x77\x93\xee\x8d\x37\x84\xeb\xa1\x47\x23\x8b\xb0\x8f\x09\x7b\xc3\xb1\x3f\x14\x55\x8a\x2c\xec\x82\x54\x96\xd7\xd0\x65\x2f\xe0\x15\x16\x0e\xf9\x96\x47\x98\x4e\xca\xeb\x29\x69\xa2\xa4\xc5\x95\x59\x05\xa2\x9c\x5c\x98\x39\xb9\xf5\xba\xd7\x0a\x1b\x2a\x17\x82\x09\x8e\x15\xb4\xc8\xa8\x26\x27\x40\xd4\x87\x38\xd9\x80\x33\xab\xc0\x17\x8d\x3c\x79\x82\x19\x7c\x2a\x46\xa2\x78\x42\x6c\xe7\x63\x0c\x51\xca\x8d\x30\x94\xa8\x33\x82\xb4\x39\xd1\x67\x05\x6c\xf3\x92\xf3\x24\x84\x39\x35\x59\xf8\xf7\xc4\x1f\x65\x62\x03\x76\x93\x48\x5f\x15\x39\x00\x94\x5c\xd0\x6e\x5e\xb8\x00\x5d\x6f\x1c\xf4\xa1\xed\x0d\x82\xb1\xd7\x85\xae\x3f\x1e\xfb\x43\xf0\xe0\xf7\x60\x7c\x0b\x37\x43\xef\xce\xe7\x11\xa7\xb8\x19\xbb\x43\x99\x0b\x7c\x42\xd2\xdc\xbc\x38\x2a\xe6\x83\xa0\x2f\x4f\x44\x24\x6d\xe4\x7c\x36\x1f\xc7\xc5\x7c\xb4\x83\x61\x7b\xd2\xbb\xee\xfa\x7f\x50\xa2\x8e\x20\x9a\x3a\x28\x4a\x3f\x99\x99\x93\x62\x66\xc6\x41\xb7\x43\x27\xc5\x89\x1c\x51\x65\xe1\x44\x9f\x3e\x29\xa7\xc5\x7c\xa8\x29\xc4\xff\xf1\xea\x4a\xf3\xe2\xac\x98\x97\x21\x86\x53\xef\x2a\xbc\xe3\xda\x22\x3b\xa9\x2e\x6b\x9f\x3d\x31\xe7\x36\x66\x18\x75\x75\x7f\x9d\x92\x95\x35\x42\xec\x63\xaa\xc6\xab\x8e\x52\x2d\xc4\xb8\x11\x39\x34\xe1\xc8\x50\x39\x92\xe3\x4c\x70\x77\x61\xe1\xae\xcd\x74\x59\x7a\x5e\x5b\xa9\xd1\x0e\xe5\x5c\x35\xad\x92\x8e\x70\xe0\x36\x1a\x16\x0e\xfc\x0c\xba\x88\x39\xc0\xf9\x4b\xae\x2c\x15\xb4\xc2\xac\xed\xd1\xa5\xdb\x68\x16\xd3\x95\x68\xc2\x3d\x3b\x76\x98\x9f\x40\xd7\x86\xa6\xbe\x09\x3d\x08\x78\x10\x1f\xe2\x40\x94\xee\x4f\xdc\x06\xa1\x7e\xde\x4a\x8d\x2b\x8a\xfb\xd0\xb6\xc1\x66\xa0\x0b\x5a\x96\xab\xb0\xca\x17\xe6\x18\xb9\xef\xe2\xe7\x04\x2c\x0b\xd6\x6e\xc3\x86\x88\x41\x46\xb0\x5c\x9b\x79\x68\xb6\x2b\x1d\x1b\xe2\x05\x06\x41\x3a\x7c\x0b\x1f\x45\xe9\x87\x88\xd9\x20\x2d\x28\x16\x1c\x5f\x5b\x26\x04\x65\x0c\x90\x69\x11\xb2\xb6\x50\xd0\x6d\xd8\x10\xcc\x1f\xdf\x56\x04\x80\x89\x3e\x65\xe1\x2b\x4d\x03\x45\x51\x03\x46\x2d\x65\x33\x55\xec\x88\x9b\x6a\x90\xf2\x71\xa0\xdb\xb0\x41\x55\x3f\xe3\xe9\x88\xa3\xa3\x36\x13\x39\x05\x65\x6c\xe5\x8a\xd7\xdc\xa6\x0d\xa0\x42\x1b\x40\xd1\xd8\xa7\xb5\xdf\x92\xbe\xdb\xb4\x01\x54\x68\x03\x28\xb9\x13\xb2\x17\x5d\x1b\x40\x85\x5b\x00\x0a\x45\xe9\xfe\xc4\x6d\x00\x15\x16\x09\xf9\x13\x06\x6d\x03\xa7\xb0\x9c\x7d\xed\x45\xfb\x04\xa0\x37\xe9\x8e\x83\x41\x17\xe7\x93\xda\x1a\x2e\xff\x29\x59\xda\x26\xeb\xda\xec\x70\x56\xc4\x0f\x66\x19\xea\x7e\xdc\xa6\x0d\x9a\xd8\x68\x46\xe3\x61\xf8\xdd\xcf\x3b\x75\x47\x6c\x84\x3b\x22\x3b\x76\x44\x05\xa9\xe3\x88\x1a\x16\xa7\xb8\xf2\xce\x6d\xda\xe0\x6a\x52\xc2\xa9\x7f\x7c\xd7\xca\x6d\xda\xa0\x6a\x52\xc2\xa9\xef\x43\xd7\x86\x4d\x93\xb2\x4e\x7d\x0f\xe2\xae\x0d\xa0\x26\x25\x9d\xfa\x3e\xb4\x6d\x20\xf5\xc3\x32\xe1\x88\x4c\xb8\x7d\x3f\x5f\xf1\x4e\xfa\xe9\xa4\x0c\x5d\x1b\x48\x8d\x6f\xc3\x61\x3f\x5b\x74\x5d\xbe\x46\x78\x5b\x61\xb0\xeb\x0a\x80\x1a\xf5\xbc\xae\x20\x3b\xba\xf5\x86\x03\x18\x55\x3e\x7d\x13\xd1\x75\x8f\x8d\x04\xb3\xb9\xb7\xc1\xf9\xec\xb1\x5b\xeb\xba\x27\x45\x54\x8b\x5c\xcf\x5e\x54\x4f\x8b\xa8\x6e\x33\xa2\xfd\x48\x9f\x15\x91\x2e\x72\x3b\x7b\x51\x3d\x2f\xa2\xba\x6d\xdb\x6d\x2f\xca\x17\x45\x94\x33\x19\xb2\x90\x72\xb5\x5a\xab\xed\x3d\xe8\xa3\x86\x99\xb4\x6f\x0f\xff\x38\x45\xc5\x59\xfd\x05\xa2\xf4\x11\xd3\x55\xca\x1f\xeb\xdb\x37\x91\xdd\xa3\xa6\x91\x87\x7c\xd6\xab\xdd\xdd\xaa\x94\x2c\x0a\xad\x89\x15\x0d\x4e\xcf\x35\xd2\x33\xe5\xb8\xc2\x88\xb3\xd4\x4a\x17\x7a\xba\x47\x66\x90\x32\x65\xb6\xc2\x78\xf7\xa0\x66\x46\x28\x6b\x3e\x2b\x8c\x76\x0f\x92\x66\x78\x2a\x97\xc5\x9a\x21\x1a\xb8\x9b\x8b\x0a\x93\xa1\x23\x33\x44\xe9\x39\x2c\x1d\x12\x5b\x18\x2a\x51\x85\xea\x1e\x99\xd1\x27\x93\xb1\xaa\xfb\x49\xa5\x7a\x35\xa3\x4b\x61\x7e\x2a\xc4\xc2\xc0\x55\xcf\x4f\x6d\xcf\x2c\x70\x8f\xcc\x70\xb2\x25\x3b\x55\x6b\x6e\xb3\x39\x69\xd9\x48\xe0\xd8\x8c\x26\x34\x37\xc5\x31\x33\xbd\xe1\x12\xc4\x56\xb8\x13\x89\x83\x99\x0a\x74\x95\xa9\x39\x72\x8f\xcd\xb0\x51\x98\x81\xb2\x38\xf3\xe3\x65\xb2\xee\xb1\x19\x3c\x4a\xe4\x9f\x7b\xd4\x57\xb9\xc7\x66\x10\x29\x91\x7d\xee\x45\xd5\x0c\x26\xdb\x72\x4f\x25\x04\xf8\x38\x69\x33\xa8\x94\xc8\x3c\xf7\xa2\x6a\x06\x94\x2d\x79\xe7\x27\x14\xd0\xb9\xc7\x67\x00\x9d\xe0\x2e\x18\xe9\x19\xa7\xba\x1a\x8e\xf8\x6a\x38\xca\x15\x29\x08\x75\x35\xfe\x3e\x4f\x91\xd1\x34\x43\x52\x2e\x2f\xcd\xdd\xcd\x07\x2b\x47\xcb\x21\x0b\xaa\x8e\xc3\xc7\x8b\x13\xd3\xa2\xbc\xf4\xd8\x0c\x53\xd6\xac\x54\x5a\xd2\x1e\x85\x85\xee\x89\x19\xa2\xac\x39\xa9\xb4\xa4\xbd\xa8\x9a\xb1\xaa\x64\x46\xba\x1f\x69\x33\x60\x95\xcb\x47\xf7\xa3\x6c\x06\x2d\x5b\x36\xba\xd3\x54\x5b\x8b\xac\xdd\x13\x33\x68\xe9\xb9\xa8\x5e\x94\x51\x7c\x54\xa9\xf0\x50\x82\x7b\x62\x06\xaa\x1f\x9f\x35\xbd\xd6\x81\x36\xfe\x69\xb8\x57\x6d\x80\x5e\xd8\x09\xae\x03\x7f\x28\x42\xf7\x41\x88\x4d\x77\x70\x4b\x26\xb7\xc5\x5e\x6a\xb5\x96\xfa\x51\x7b\x61\x7d\x75\xf2\x7d\x0d\xfd\x3b\x7f\x38\xf2\x3b\xd0\x0e\x7b\x3d\x4f\xbd\xad\x5a\xdd\xd2\xdf\xd1\x99\x07\x70\x33\xf4\xfd\xef\xf0\x63\x10\xde\xf8\x37\x43\xaf\xd7\xf3\xfb\x81\xf5\x2e\xf5\x25\x4d\x59\x27\xe7\x67\xbc\x13\xaf\x1f\xc2\xd8\xef\xfa\x81\xac\x3c\xb1\x3d\x63\x23\x57\x33\x82\x7b\xba\x68\xf2\x9e\xb2\x5b\x7f\xdd\xc1\xad\x67\x43\xef\x54\x39\x62\x0f\xd9\x75\x99\xc2\x40\x81\xd0\x74\x2d\x34\xaf\xfc\xb1\x57\xf4\x98\x87\x1a\xbf\x56\xcd\x5c\xcb\xae\xcd\xe7\x49\x1e\x59\x48\xde\x78\x54\x82\xd2\x75\x90\x36\x5b\x74\x92\x9b\x85\x07\x39\xeb\xc8\x2d\x84\xe4\x68\x1e\x5b\x68\x76\xfc\xee\xd8\x33\xa4\x7e\xe5\x9e\x9b\xe1\x20\x14\xf1\xbd\x5d\xf6\x57\xfc\xdc\x0c\xc2\xcb\x89\x85\x17\x7f\x30\x0a\xba\xb2\xc4\x2f\x37\x03\xca\xd3\x1f\x6a\xea\x52\x95\x70\xb2\xb6\x27\x7a\x11\xaa\xa7\x16\xaa\xff\x5f\x0a\x9a\x3d\x44\x4c\x9e\xab\x35\x3f\x8a\x49\x3d\x57\x5b\x48\xf2\xcc\x36\x50\x4a\xb1\xb8\x32\xed\x43\xda\x7c\x6e\xa1\x38\xbe\xa5\x34\x6d\xc7\xf4\xcd\xcf\xa9\x28\x7d\x74\x9c\xd0\xbe\xb0\xd0\x0e\x42\x3e\xc1\xc0\x1e\xe7\x46\xb7\xd8\xb2\xa9\x12\x7d\xaf\xaa\x93\xda\xaa\xe8\x24\x3c\x0b\x89\xef\xde\x60\xe0\xa9\x4f\x82\x4b\x69\x69\x53\x4b\x54\x57\xd1\xb1\x89\xe7\x50\xa4\xca\x73\x02\xec\xe5\xbd\x84\xe6\x95\x85\x66\xd7\xeb\x75\xf6\xb0\x1c\x71\x1a\xba\xe4\x13\x67\x08\x2f\x6d\x0b\x2f\xbd\x89\x5e\x75\x4f\xaa\xbc\x1d\x59\x80\xfb\x53\x94\x29\xa6\x11\x52\x1f\x71\xa1\x68\x56\xf6\x21\x17\xd9\x58\x94\x30\xd0\xb1\x30\xd0\x9f\x6c\x7f\x0c\x06\x28\x4c\x94\xd9\x49\x24\x04\x7d\x0b\xc1\x3f\x02\x15\x26\xaa\x8a\x2d\x0a\x05\x27\x9a\x24\xa3\xf1\xec\xef\x2c\x04\xaf\x2d\x04\x43\x52\x69\xda\xb7\x7a\xa1\x0f\xef\x09\x60\xaa\x5e\xc3\x42\x75\x10\xe8\xc9\x44\x95\x25\x10\xc2\x82\x54\xeb\x31\xb6\xd9\x71\xd5\x2d\x82\xf5\x6c\xae\x77\x78\x1b\x96\xf1\x82\xb6\xe8\xab\x60\xc8\x36\x2f\x38\x0a\x6e\xb0\x17\x94\x63\x8e\x84\x0f\x50\x1f\x2b\x70\x09\x97\x3b\x03\xb2\x67\xf3\x82\x63\x6f\xa2\xab\x09\x9e\x66\x76\x90\xc7\xb4\xc0\x52\x6a\xa9\x85\x50\xb4\xf9\xba\x89\xe2\xeb\x84\xd9\x56\x11\x31\x5b\x46\x39\x82\x9f\x96\xa7\x44\xec\xf2\xc4\x08\xc2\x85\xcd\xf7\x0d\x6e\x83\x6c\x52\xca\x0e\x1f\xb5\x44\x7d\x73\x44\xf5\xae\x9a\x42\x5a\x63\x0f\x30\x20\x1c\x3b\x3b\x71\x60\x73\x85\x6d\xcc\x81\xe5\xd0\xea\x4f\xc3\x63\x38\xfe\x2c\xf3\x18\x0e\x42\xd1\xe6\x0a\x07\xa3\x40\x3c\x04\x90\xbb\x5f\x51\xa3\x9d\x12\xb8\x72\xb8\xd9\x6a\xe3\xdc\x79\xd6\x6d\x0e\x31\xec\xf9\x37\x1e\x4b\xab\xd4\x4a\x35\x84\xd4\x13\x9c\x9a\x39\x8b\x0f\x88\x9e\x8f\x15\x68\x96\xa6\xba\xce\x5b\x3c\xc7\x95\xb0\x6f\x7d\x0f\x81\x07\xd6\xb9\x3b\x5b\x3c\xaf\xe7\x0f\x20\xe5\xc7\x72\xab\x50\xad\xb1\x83\xb9\xe4\x10\x44\xd1\x43\x76\x08\x65\xd7\x48\xf9\x4a\xc6\x23\x86\x88\x5e\x09\xaf\xbf\x96\x07\x1b\x46\xf0\xc8\x48\x90\x07\xd7\x39\x75\xd1\xd2\x3e\xa2\x7e\xb5\x8c\xfa\xd9\x0d\x9f\x51\x3c\x36\x52\x94\xa1\xb5\xfa\x94\x3b\xb6\xd1\xa1\x3e\x7c\x4e\x98\x18\x12\x06\xb6\xc5\x5f\x5c\x9d\x18\x29\xca\x00\x5a\xbd\xab\xa5\x1f\x76\xaf\x91\xa2\x08\xca\x47\x54\x10\x6c\x5d\x9d\x1a\x69\xd0\x70\x59\x96\x30\x45\xf8\xbd\x96\x0f\x92\xb3\x79\x3b\x3d\x60\xcf\x89\xb0\x81\x62\x27\xed\x08\x82\x67\xe6\x41\x8d\xed\x62\xdb\xb6\x46\x2c\x4e\x5a\x65\x9f\x2b\x40\xe8\x9d\x1b\xe9\xa9\xa1\x72\xb9\x64\xb3\xb4\x9b\xbf\xba\x30\x52\x64\x01\xb2\xbc\x83\xe9\x24\x1b\x8f\x7c\x83\x48\x48\x8b\xbf\xb1\x8e\x3d\x63\xc7\x3c\x2c\xd6\xb9\x69\x99\x1f\xd6\xb6\xfd\x91\x1b\x84\xd2\x95\x91\x12\x0b\x86\xb7\x3d\x0b\xe8\x52\x6a\x7d\x69\x20\xbf\x6a\x1b\x29\x92\x90\xb7\xd0\x98\x77\x3f\xf0\x43\xc8\x75\x8c\xe4\xfa\x93\xb2\xf3\xc8\xb3\x0d\xfb\x19\x51\x42\xc6\x37\x92\xc1\x61\x6d\xf4\x2d\xe2\x9a\x77\x09\x2c\x84\xad\xd2\x98\x84\x5d\xa3\xd9\x6f\x95\x6c\xa4\x96\xb4\xad\x6b\x23\x39\x25\xa8\x35\xcc\xa4\xc1\x02\x76\x01\xa9\x76\xc3\x48\x73\x10\x58\x1d\x8e\x16\xe7\x22\x24\xc3\x5c\x25\x9a\xcd\x04\xb3\x79\x87\xd3\x36\xbb\x3a\x1a\xc8\x96\x1c\xe6\x2e\xfe\xa6\x6d\x76\x70\xd7\xe4\xcc\x13\x0b\x66\xad\x74\x95\x02\xf1\x9a\x5d\xa4\x7c\xca\xe9\xc1\x63\x4e\xd7\xec\xe7\xca\x52\x84\x43\x4e\xb1\xc6\xe0\x3b\x42\x05\x07\x9c\x08\x45\xb3\x9f\xa3\xc1\x33\x98\x3d\x4e\x2e\xdd\x57\x30\x2c\xeb\x71\xda\x66\xaf\x36\xd1\xbc\xda\x4e\xe6\x5e\x42\x49\xcd\x5e\xce\x10\x18\xab\x01\xe0\xee\x41\x72\x3e\x78\x64\xf4\xcd\x4e\xaf\x7d\x1b\x98\xc7\xfb\xf1\x50\x99\xd1\x33\x3b\x3d\x1a\x14\x1b\x8c\x4a\xa0\xdc\xde\xc1\x32\xa3\x6f\x76\x81\x32\x24\x36\xf1\xa0\x84\xa3\xca\x91\x5c\x6a\xad\xc2\x5e\xf1\x28\x15\xa9\xff\x99\x2f\x91\xce\x7e\xa2\x1c\x75\x04\x5e\x10\xcf\x0f\xa3\x1f\xbd\xab\xb0\xcb\xa4\xaf\x9e\xd0\x62\x87\x5a\xe8\xa7\x2a\xad\xde\x61\x8f\x0c\x80\x08\x44\xca\x98\xb2\xf2\xf0\x54\xd8\x31\x3d\xd8\x5c\x8a\x17\x61\x01\x83\xdb\x40\xe3\xc4\x26\x17\x19\x02\xa5\xca\x29\x65\x2a\xa3\x5d\xf4\xb0\x23\xec\x60\x60\x20\x6c\x62\x1e\x21\x94\xc1\x6b\xc4\x21\xfb\xa3\xe2\xf8\xd2\xf8\xa7\xd1\x68\x9c\x00\x54\xe2\xd9\xeb\x4b\x0c\xdf\x20\xae\xc3\x7d\xb2\xc1\xad\xfb\x3a\x3c\xc7\xf3\x39\x6e\x3e\xd7\xe1\x31\x99\x91\xab\x8f\x75\x48\x5e\xd7\xd3\xd9\x72\x01\xdf\x20\x21\x7d\xfe\x97\xfe\xfe\xbf\x75\xa0\x8d\x97\x3a\x6c\x5e\x68\xf3\x7f\xea\x30\x5d\x92\xd6\xb4\x0e\xb3\x78\xfe\x88\x9b\xb3\x3a\xcc\xdf\xe0\x1b\xcc\x5b\x95\x05\x7e\x5f\xd4\xe1\x9f\x29\x7c\x83\x7f\xea\xb0\x9c\x4f\x1f\x56\xa4\xeb\x65\x1d\x5e\xf1\xc5\xd7\x3a\xac\x5e\x96\xf0\x0d\x56\x75\x58\x4f\x9f\x09\x3b\x6b\x4c\xf5\xf5\x05\x7f\xfd\x54\x87\x07\xd2\x78\xa8\xc3\xeb\x1a\x37\xde\x71\x2f\xc9\x33\xfe\xdd\xaf\x3a\x3c\x4d\x17\xf1\x4c\xdc\x78\xa7\x4c\xc2\xeb\x14\xd6\xef\xf3\xfb\xe5\x0c\xbe\xc1\x4f\xce\xb1\xb8\xf2\xaf\x3a\x60\x02\xe2\xf3\x7f\xd4\xf9\x9b\x4f\x1f\x1f\x67\x09\x3c\x2e\x37\xf0\x0d\xfe\x5f\x1d\xde\x5f\x97\xcf\xc9\xf3\x2a\x9e\xcf\x93\x05\x66\x01\x41\xfe\x8f\xdd\xba\x5a\xbe\x3d\xbf\xc0\xfd\x2a\x89\x37\x2f\xd3\xc5\x33\x7c\x83\x6a\x1d\xd6\xf3\xe5\x72\xa3\x5f\xad\xe5\x6f\x8d\x1f\xde\x36\x09\xc4\x0f\x0f\xc9\x02\xd3\xfd\xad\x0e\xcf\xab\xf8\xa7\x72\xe5\xaf\x3a\x3c\x4e\xe3\xd9\xfb\x66\xfa\x37\x1e\xec\x9f\x54\xc4\xff\x1b\x00\x00\xff\xff\x3b\x67\x12\x3d\x0c\x67\x00\x00") + +func fontsBigFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBigFlf, + "fonts/big.flf", + ) +} + +func fontsBigFlf() (*asset, error) { + bytes, err := fontsBigFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/big.flf", size: 26380, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBigchiefFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x58\x5b\x8b\x1b\x47\x13\x7d\x9f\x5f\x51\x1f\x0c\xec\x0c\x4c\xab\xbc\xfb\xc5\xc6\x06\xaf\x19\x27\xe4\x29\x04\x87\x84\x40\x1e\x06\x2a\xb2\x25\x25\xc6\x8e\xb5\xac\xb2\x0f\x81\xfe\xf1\xa1\x6f\xd5\xd5\x33\x3d\x37\x49\x8e\x59\xef\x4a\x3d\x3d\xa7\xaa\x4f\x9f\xba\x74\x1f\x3e\x1f\xee\xb6\x25\xbc\x84\x17\x70\xf7\x0c\x6e\x9f\xc3\x5d\xf1\xfe\xe3\x1f\x1f\xfe\x3c\x6c\x0e\x9f\x0f\x70\xfb\x0c\x5f\x7d\x03\x0f\x9f\x5e\xbc\xbc\xbd\x3d\xb5\xdb\x0f\xdb\xdd\x66\xf7\xb8\xfd\xb4\xdf\xec\x77\x4f\x0d\x3c\x3d\xec\xb6\x7f\xef\xe1\x16\x5f\x3d\x87\xd3\x3f\xef\xff\xdf\xbe\xfd\xf6\xfb\x9f\x37\x6f\xbf\xdb\xfc\xfa\x43\xf1\xe3\xe3\x69\x03\x3f\xed\xbf\xec\xf6\x8f\xa7\xe3\x17\xf8\x78\x82\x5f\xde\xc1\xc3\xe3\xf1\x69\x07\xc7\x03\xfc\xb5\xff\x5f\x41\x44\xd4\x16\x00\x00\x6d\x51\x96\x65\xd9\x16\x4a\x29\x15\x3e\xcb\xa7\xf6\xb7\x1b\xe2\x51\x40\xff\x00\xcd\x0c\xa5\x14\xda\x97\xed\x77\x33\x42\x47\x39\x39\xa0\x44\x20\xc6\x46\x84\x60\xd9\xbf\x39\x6a\xd9\x8d\x1b\x4b\xa8\xcc\x43\xff\xc9\xbf\xaf\x22\x08\x44\xa4\xd4\x0b\xe1\x47\x0a\xcc\x73\x88\x90\xc2\xac\xca\x2c\xa6\x0e\xf0\x5d\x30\x50\x99\x39\x35\x9b\xc0\xa1\x91\xc4\x4c\x34\xe4\x07\x0d\x44\xed\x56\x8d\x16\x10\xab\x1a\x06\x53\x7a\x1e\xda\x11\x22\xff\xac\x32\x7e\x39\xc7\xba\x48\x7c\xe7\x5c\xaa\x88\xa0\x8b\xfe\xd4\xc2\x19\x07\x68\xbf\x1b\xbb\x0e\xc1\x7f\x15\x0f\x86\xa4\x9b\x7f\x1b\x05\xbc\xf7\x81\x74\x64\xd2\x91\x49\x47\x7e\x0d\x23\x1b\x6a\x48\xba\x07\x53\x1b\x76\x30\x48\xc1\xf3\xc2\x96\x02\xcb\xac\x2f\x81\xc8\x80\x01\x24\xfe\x55\xd4\x21\x39\x6e\xba\xa8\x87\xc1\xbc\x3c\xf5\x85\x22\xed\x5e\xd6\x30\xb9\x3b\x89\x56\x7b\x4a\x46\xcf\x42\xaa\xe4\x81\x25\x1f\x78\xf7\xf7\xf7\x53\x96\xda\x02\x4a\xf0\xbf\x7c\xa4\xba\x40\x13\x0f\x98\xdd\x92\x37\xbd\x94\x4c\xca\x2d\xe3\x1d\xc3\xbe\x80\xfb\x82\xe9\x09\x81\x38\x42\x2c\x44\x1d\x61\x31\x02\x63\xd0\xa2\xdb\x3b\x19\x10\xc9\xe7\xac\x81\x38\x09\xa3\xd6\x84\xd8\x84\xda\x86\xde\xcf\x1b\xe0\x38\xf2\x0b\xf0\x06\x0c\x98\xa4\x26\x92\xb3\x76\x05\x23\x06\x80\x00\x45\x8e\xaa\x2f\xa0\x08\x12\x03\x3e\x9b\x50\x5c\x01\xc8\xe0\x11\xe1\xb3\x7c\x05\x44\x90\x72\xad\x9c\x05\x75\xa5\x15\xcc\x19\xc0\xcb\x0c\xd8\x05\x0c\x28\x4a\xb3\xcb\x65\x14\xe5\xe3\xc0\xa8\x08\xd4\x95\xe2\x20\x67\xc0\x40\x01\xc6\x3d\x58\x65\x40\x64\x78\x9f\x43\x8e\x65\xc8\x21\x49\xea\x1f\x4c\x14\x35\x02\x93\x1a\x11\xf3\x9f\xa5\xf8\xb5\x9b\xdc\x8d\x57\x72\x1e\xb2\x02\x50\x44\x73\xa5\x9f\x87\x3a\xe7\xcd\x1b\x15\xb2\xea\xc8\x0b\x14\x0b\xa6\x63\xb0\x02\x11\x85\x98\x94\x2c\xf3\xc6\x71\x49\xfe\xf3\xb2\xe2\xb5\x7a\x40\x54\xea\x9d\x03\xec\xcc\xbe\xc8\xbe\x63\x19\xa0\xd8\x63\xcd\x41\xa0\x59\x40\x9a\x93\x90\x5e\x9a\xa1\x85\xf4\xa3\x9f\x16\x16\x70\x10\x5b\x67\xe5\xb7\x89\x12\x30\x48\xa0\xe7\x06\x2f\x2d\xad\x31\xe7\xac\x60\x60\xe0\x26\x50\x94\x59\x81\x35\x50\x7e\x6d\x03\xd7\x49\x3f\xe9\x1e\x28\xd5\x9c\xb1\x07\x42\xea\x00\x24\x4c\x60\x4c\xd2\x89\x92\xb0\x57\x2a\x17\xf4\xc2\xa2\xd0\x84\x4a\x1f\xc3\x93\xa3\xb3\x2d\x4a\x42\x43\x3d\x63\xc4\x0f\xf9\xaa\x28\x3f\x4f\xa6\xfc\xea\x8c\x94\x4f\x29\x21\xcd\x4d\xe0\x63\x73\x13\x39\xef\xe4\xa6\x76\xcb\x0c\xa4\xb9\x65\xbe\x59\xc3\xc5\xa9\xc0\xfe\x67\x50\x0c\x19\x46\x03\xaa\x90\x63\x34\xc6\x2c\x83\xbd\x3c\xb3\x56\x25\x5a\xa8\x44\x69\x50\x51\x25\x5a\xaa\x44\x2f\x56\xc9\x7f\xd7\x76\xf6\xb3\x66\x30\x60\xa1\xbe\x76\xc4\x62\x54\x8f\x58\xc1\x6f\xd2\x40\x77\xc9\x0a\x40\xac\x40\x8b\x15\xe8\xab\xb4\x3c\x9d\x3c\x7b\x07\xfd\xaf\xd9\x03\x33\x2c\x0d\x5d\xe1\xb0\x32\x9b\xc4\x44\x5a\x90\x49\xac\x5a\x95\xc4\x9c\xe7\x6c\x22\xca\x5f\x33\x38\x0b\x7f\xa0\xfa\x89\xc8\x25\x00\x09\xaa\x23\x2c\x6a\x06\x76\xa1\x1b\xce\xdc\x7a\x99\x1c\x5d\x5f\x14\x28\xd1\x81\x0e\x1d\x78\xd6\x81\x66\x3d\x75\x7d\x33\xce\xb1\x16\x1c\x5b\x54\x4e\xbd\x5a\xb6\xdb\x3a\xe1\x98\x0f\xf5\x15\x85\x28\x1b\x39\x94\xc8\x65\xcd\xb5\xf4\x55\x4f\x51\x66\x3c\x6b\x20\xaa\x3b\xfa\x33\xd6\x2b\x62\x78\x03\xed\x21\x2f\xb7\x89\x61\xc8\x75\xac\x0e\xaa\x0b\x40\x7c\x13\xd1\x8d\xde\x44\xe4\x3c\x02\xc0\xb0\x58\xee\xfd\xb9\xd9\xf4\x51\x46\x84\x59\x8f\x5a\xee\x90\x6d\xfa\x47\x3d\x7f\xd7\x36\x70\xad\x48\xef\xd7\xe2\xbc\xde\x78\x72\x78\xe8\x96\x5c\x30\x65\x34\xe6\xcf\x51\x1c\x9b\xb5\x8f\xcb\x6a\x52\x90\xbd\x67\x18\x8f\x94\x03\x20\x5c\x03\x94\xf3\xe8\xc6\x03\x95\x33\x21\x22\x62\x50\xe8\x96\xe1\x62\x56\xc6\xa4\x29\xc9\xbe\xb6\xc2\x43\x22\xaa\x97\x79\xc8\x42\x8b\xac\xfd\x6e\xb0\xc8\x76\xaa\xeb\x33\xef\x8a\xdd\x44\x12\x1b\xe5\xe3\x72\xf5\x6e\xe2\xcc\x6e\xfa\x01\xf7\xa7\xe1\xbb\x36\x79\x76\x48\xa6\xcc\xef\x5e\x93\xb9\x6e\x8e\xc7\x3e\x4c\x33\x8e\x48\x38\x19\xd2\x33\xed\x5e\x58\x5e\x25\x48\xef\xa6\x49\x4f\xfc\x47\x8f\xb3\x70\x89\x59\x5c\x83\x40\xe6\xc7\x81\x60\x60\x1a\xe7\x1b\xcf\x85\xdb\x3f\xb7\x6b\x67\xe9\x68\x55\x0c\x72\x46\xe3\xeb\x87\x00\x49\xc2\x3b\xe4\xd7\xf0\x1a\x1e\x86\x9b\xe0\x8a\x16\x00\xd5\x19\xce\x26\x2b\x72\x36\x67\x7b\x90\x8a\x4c\x58\x1b\x67\xea\xf1\xb2\x93\x03\x20\x8c\x5e\x58\x80\x32\x33\x6f\x81\x9e\x92\x9b\x01\x04\x4e\xe8\xd3\x7a\x9a\x2a\x43\xae\x75\x71\x5d\xd5\x25\x1e\x69\xd3\xf3\x58\x28\x8d\x09\xd8\x6c\xac\xf9\xce\x09\xdb\x22\xdc\xd3\x10\xda\xc3\x13\xe6\x62\x6d\x4c\x2f\x92\x97\x73\x32\x63\x5f\x78\xe0\x81\x24\xbd\x79\xa0\x88\x34\xda\xf7\xbc\xf6\xf8\xa2\xef\xa9\x72\x7d\x4f\x5b\xe8\xf4\xa7\x34\x3f\xe3\x65\x26\x9e\x1d\x44\x3f\x03\x6f\x7a\xfd\x0c\xe4\xfb\x19\xd1\x23\x3b\xb6\x3b\xc2\x94\x4c\xf6\x7a\x2e\x66\xc2\xc3\x06\x1a\xff\xd4\xb5\x98\x97\xdc\xc2\x85\xd1\xc6\x94\x0a\x48\x31\x8d\x83\x75\x5b\x88\xa3\x08\x1f\x38\xe6\x6a\x7e\x98\x10\x61\x41\xa0\xe2\xea\xd8\xea\xd3\xd2\x84\xca\x26\xea\xfe\x59\x8d\xd7\x14\xd0\xaa\xa4\xdf\x88\x5a\xdb\x0f\x91\x69\x8f\xa8\x77\x0f\x17\x8a\xa3\x3c\x15\x9b\xfe\xbd\xf1\x85\x52\xde\x87\xca\xeb\x44\xcc\x6d\x89\x35\xf4\x6f\x00\x00\x00\xff\xff\x11\x0a\x3c\x45\xb8\x1f\x00\x00") + +func fontsBigchiefFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBigchiefFlf, + "fonts/bigchief.flf", + ) +} + +func fontsBigchiefFlf() (*asset, error) { + bytes, err := fontsBigchiefFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/bigchief.flf", size: 8120, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBinaryFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x95\x5d\x6b\xdc\x48\x13\x85\xef\xfb\x57\x14\x43\x2e\x12\x88\x27\x7d\x5a\xdf\x77\x86\xbc\x37\x81\x97\xdd\x85\x2c\x7b\x2f\xdb\x9a\x8c\x60\x22\x65\x25\x39\xb3\xfe\xf7\x8b\xba\xaa\x74\xc8\xc6\x10\xeb\xd1\xd3\x55\x73\xda\xaa\x51\x5f\x6e\x97\xd4\xbf\x13\xec\x3f\x90\x87\xfc\x7f\x0c\xe1\x69\x9c\xfa\xe5\xed\x7c\xb9\x5d\xe4\xfd\xe7\x0f\x82\xae\x2b\xe5\xe9\x4d\xfe\x1a\x9f\xb7\x79\x91\x3f\xfa\xa5\x7f\xe9\xe5\xfd\xcf\x1f\xf9\xe2\x71\x9c\x2e\xe7\xd7\xed\xb2\x7e\x3f\x3f\xdf\x3e\x48\x57\x7e\x42\xfa\x14\xab\x10\x2e\xe3\xb7\xdb\xb0\x49\x3a\x43\x2e\xf3\xb4\x7d\x94\x71\x7a\xbe\xbd\xbe\x0c\xab\x7c\xf9\xfa\xbb\xfc\xbf\xdf\xc6\xe9\x01\x1f\x65\xf8\xc7\xee\x9e\x1e\xfe\x77\x92\xf9\xc7\x36\xce\x93\x3c\x5f\xfb\x65\x3d\x87\xf0\xf5\x47\xff\x3c\xac\xd2\x2f\x83\x4c\xf3\x26\xeb\x75\xbe\x4f\xd2\xaf\x62\x09\x45\xbe\x5c\x64\xbb\x8e\xab\x8c\xab\x2c\xc3\xdf\xaf\xe3\x32\xbc\x7c\xdc\xab\xa7\x6f\x83\x9c\xde\x3d\x9e\xe4\x69\xb8\xcd\xf7\xb0\xcd\x72\x8a\x11\x71\xff\x27\x8f\xa7\xb3\xc8\x67\x5d\xb3\x8b\xc7\xd3\xfe\x6b\x19\xbe\xcf\x3f\x07\xd9\xae\x83\x5c\xfb\xe5\x65\xdd\x3f\x59\x9e\x86\xed\x3e\x0c\x93\xdc\xe7\xe5\x65\x3d\x87\xdf\xe6\x6d\x5f\xd1\x6f\x62\x9b\xeb\x6f\xf7\xfe\x6d\xb5\xda\x55\x56\x8d\x7b\xbf\x0e\x93\x8c\x9b\xe8\xcd\x5c\xbb\x7f\x42\x2f\xd3\x70\x97\xdb\x38\x0d\xe7\x10\xfe\x5c\xde\x7c\xb3\xa7\x87\xef\x12\xff\x9b\xe1\xd7\xcf\xbf\x0d\xdb\x36\x2c\xab\xbc\x9f\x9f\xb7\x61\x5b\x3f\x9c\x43\x78\xf7\x18\x6c\x47\x10\xbf\x44\xe4\xe5\x71\x17\x31\xf2\x92\x77\xb9\x16\xc7\x5a\xc4\x63\x2d\xd8\x17\xec\x0b\xf6\x05\xfb\x82\x7d\xc1\xbe\x38\xfa\x22\x1e\x7d\xc1\xbc\x60\x5e\x30\x2f\x98\x17\xcc\x0b\xe6\x05\xf3\x82\x79\xc1\xbc\x60\x5e\x30\x2f\x98\x17\xcc\x0b\xe6\x85\xe7\xd5\x29\x89\xbc\xe4\x5d\xf0\x2e\xd7\x82\x6b\xc1\xb5\xe0\x5a\xf6\x05\xfb\x82\x7d\xc1\xbe\x60\x5f\xb0\x2f\xd8\x17\xec\xcb\xbc\x60\x5e\x30\x2f\x98\x17\xcc\x0b\xe6\x05\xf3\x82\x79\xc1\xbc\x60\x5e\x30\x2f\x98\x17\xcc\x0b\xe6\x05\xf3\x82\x79\xf9\xf7\x05\xff\xbe\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x70\x7e\xc1\xf9\x05\xe7\x17\x9c\x5f\x1c\xf3\xfb\xeb\x0f\x52\xe3\x72\x5f\x87\xd4\x06\x1b\xea\x98\xb1\x73\xcc\xb6\x88\x86\xb9\x13\x0a\x38\xaa\x4d\xc1\x46\x5f\x6d\xe1\xa8\xb6\x34\xb4\xda\xca\x51\x6d\x1d\xec\x0b\xa2\xb6\x71\x54\xdb\x1a\x5a\x6d\xe7\x98\x6d\xa9\xa9\x6c\xd7\x28\xe1\xa8\x36\x19\x6a\x6d\x59\x38\xaa\xcd\xa9\xfc\xa9\xa1\xac\x1c\xd5\xd6\x86\x56\xdb\x38\xaa\x6d\x83\x7d\x25\xd5\x76\x8e\xd9\x56\xd1\x50\x6b\x2b\x38\xaa\xcd\xa9\xfc\xa9\xa2\x2a\x1c\xd5\x96\x86\x56\x5b\x39\xaa\xd5\x54\xbe\xdf\xaa\x71\x54\xdb\x1a\x5a\x6d\xe7\x98\x6d\xbd\xa7\x3a\xbe\x55\xa8\xe1\xa8\x36\x19\x6a\x6d\x5d\x38\xaa\x2d\x03\x78\x4a\xa0\xae\x1c\xd5\xd6\x86\x56\xdb\x38\xaa\x6d\x03\x78\x6a\xa0\xee\x1c\xb3\x6d\xa2\xa1\xd6\x36\x70\x54\xab\xa9\x7c\xbf\x4d\xe1\xa8\xb6\x34\xb4\xda\xca\x51\x6d\x4e\x75\x3c\xdf\xa6\x71\x54\xdb\x1a\x5a\x6d\xe7\x98\x6d\x1b\x03\x78\xca\xa0\x85\xa3\xda\x64\xa8\xb5\x6d\xe1\xa8\x36\xa7\x3a\x9e\x6f\x5b\x39\xaa\xad\x0d\xad\xb6\x71\x54\xab\xa9\x7c\xbf\x6d\xe7\x98\x6d\x17\x0d\xb5\xb6\x83\xa3\xda\x14\xc0\x53\x09\x5d\xe1\xa8\xb6\x34\xb4\xda\xca\x51\x6d\x1d\xc0\x53\x0a\x5d\xe3\xa8\xb6\x35\xb4\xda\xce\x71\xb7\x29\xc6\x00\x9e\x5a\x29\xc2\x51\x6d\x32\x84\xda\xc2\x51\xad\xa6\xb2\xfd\xa6\x58\x39\xaa\xad\x0d\xad\xb6\x71\x54\x9b\x53\xf9\xf3\x4d\xb1\x73\xcc\x16\xd1\x50\x6b\x01\x47\xb5\x29\x80\xa7\x5c\x42\xe1\xa8\xb6\x34\xb4\xda\xca\x51\x6d\x4e\xe5\xcf\x37\xa1\x71\x54\xdb\x1a\x5a\x6d\xe7\x98\x6d\xd2\x54\xbe\xdf\x04\x47\xb5\xc9\x50\x6b\x53\xe1\xa8\x76\x4f\x75\x7c\x7f\x53\xaa\x1c\xd5\xd6\x86\x56\xdb\x38\xaa\x6d\x03\x78\x4a\xa6\xfd\xdd\xce\x93\x32\xed\xef\x76\x9e\x96\x69\x7f\xb7\xf3\xc4\x4c\xfb\xbb\x9d\xa7\x66\xda\xdf\xed\x3c\x39\x53\x51\x1a\x5a\x6d\xe5\xa8\x56\x53\xf9\x7e\x8b\xc6\x51\x6d\x6b\x68\xb5\x9d\x63\xb6\x65\x4e\x75\x3c\xdf\x12\x8e\x6a\x93\xa1\xd6\x96\x85\xa3\xda\x32\x80\xa7\x6c\x2a\x2b\x47\xb5\xb5\xa1\xd5\x36\x8e\x6a\x73\xaa\xe3\xf9\x96\x9d\x63\xb6\x55\x34\xd4\xda\x0a\x8e\x6a\x35\x95\xef\xb7\x2a\x1c\xd5\x96\x86\x56\x5b\x39\xee\xf6\xdf\x00\x00\x00\xff\xff\xbf\x19\x3e\xf0\x66\x0d\x00\x00") + +func fontsBinaryFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBinaryFlf, + "fonts/binary.flf", + ) +} + +func fontsBinaryFlf() (*asset, error) { + bytes, err := fontsBinaryFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/binary.flf", size: 3430, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBlockFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5b\x5b\x6f\xa3\xc8\xd6\x7d\xf7\xaf\x58\x0f\x48\xdf\xcb\xa4\xdb\x76\x2e\x8e\xa5\x4f\x47\x21\x36\x49\x50\x3b\xe0\xc1\xb8\x7b\xfa\xc9\x72\x77\x48\xc7\x1a\x07\x47\x36\xee\x51\x4b\xfd\xe3\x8f\xf0\xb5\xaa\xf6\xae\xa2\xc0\xe4\x1c\x9d\x1e\x69\x02\x01\x6a\xaf\x7d\xa9\xb5\x2f\x90\xe7\xf9\x73\x7b\xea\xe0\x1a\x57\x68\x77\xd0\x44\xab\x89\x26\x2e\x3b\x57\x8d\xdb\xf9\xe2\xfb\xdf\xf8\xf6\x0b\xf7\xf3\x24\x4d\xd1\x7b\x99\xbe\xbd\x25\xf3\x39\x2e\x3e\x76\xcf\x71\x76\x86\x55\xb6\x9c\xce\x7e\xbc\x64\xf8\x99\x2c\x57\xb3\x45\x8a\xc5\x33\x06\xc9\x34\x6d\xf8\xe9\xf7\xf9\xfa\x29\x59\xc1\x1f\x85\x18\x4c\xb3\x59\x7a\xd6\x6a\x3c\xcf\x7e\xcc\x93\x0c\xcb\x64\x9e\x4c\x57\x09\xda\x1f\x5a\xf9\x1a\xad\x36\xdc\xf5\x0f\xb4\xba\xdd\x8b\xc6\x30\x59\xbe\xce\x56\x9b\x95\x66\x2b\xbc\x24\xcb\xe4\xdb\x2f\xfc\x98\xfd\x4c\x52\x64\x0b\xbc\x2e\x9e\x66\xcf\xbf\x90\xbd\xcc\x56\x78\x5e\xa4\xd9\x1f\x98\xae\x30\x5f\xa4\x3f\xf2\x9f\xd9\x4b\xd2\xd8\xdc\x30\x4b\x96\xff\xb7\x42\x3a\x7d\x4d\xf2\x35\xde\xe6\xd3\xef\xc9\x13\x16\x29\xa6\xf8\xbe\x78\x7d\x4d\xd2\x0c\xf3\x59\x9a\x7c\x68\x34\x1e\xb7\x77\x3f\xe5\xfa\x0d\xa7\xeb\x39\x6e\xd7\xcb\x6c\x91\xe2\xff\x57\x8b\xf9\x3a\x9b\x2d\xd2\x9b\x64\xba\xcc\x5e\xe6\xb3\xf4\xef\x0f\x69\x92\xfd\x0b\xad\xf6\xc7\xee\x55\x0e\x64\xb6\xd5\x0e\x69\xf2\x0f\xde\xa6\xcb\xe9\x6b\x92\x25\xcb\xc6\x6a\xfd\xf6\xb6\x58\x66\xdb\x05\xef\xfc\xfb\x5c\xd7\x69\xfa\x94\x1f\x7e\x99\xa5\x1f\x80\xc7\xe9\x2f\x4c\xe7\xab\x05\xbe\x25\x58\xcd\x73\xbb\xcd\x7f\xe1\x75\x8f\xe2\x79\xb1\xc4\xb7\x24\xcb\x92\x25\xd6\xab\xa4\xb1\x78\xde\x2c\xff\xbc\x9e\xcf\xcf\xfe\x99\x3d\x65\x2f\x1f\xff\x4e\x96\xe9\xc7\xd5\xeb\x7a\xf5\x82\xe9\x3c\x4b\x96\xe9\x34\x9b\xfd\x4c\x56\x7f\xe0\xdb\x3a\xc3\x53\xf2\x3c\x5d\xcf\x33\x2c\xd6\xd9\xdb\x3a\xcb\x35\x0f\xc2\x18\xdf\x5f\xa6\xe9\x8f\xe4\xe9\x43\xa3\xe1\x00\xce\x8d\xfd\xff\x6f\x1a\x00\x1c\xe7\xa6\x81\xc9\x6f\xd0\x1f\xf2\xb5\xdd\x59\xfe\xef\x66\xfb\x5b\xe1\xf6\xe3\x4d\x38\xde\xe8\x38\x9b\x9b\xf5\x87\xdb\x7f\xe2\xa1\x70\x9c\xdf\xb7\x39\xdd\x2d\x8f\x9d\xac\xfd\x7f\x3b\x79\x25\xae\x92\x95\x41\x04\x4b\x42\x85\x25\x0f\x87\x87\xa5\xa4\xdf\x4a\xf2\x0e\xb2\x36\x8b\x49\x82\x1c\x61\x19\x48\xab\x4a\x0f\x6e\xaf\x4b\x2a\x08\xa6\x16\x4e\x95\x95\x75\x1a\x1d\xac\xbc\x95\xb2\x3b\x3d\x88\x95\x54\x82\x22\x89\xbf\x5a\x28\x58\x5c\xe5\x18\x0d\x37\x8d\xa3\xfb\xe9\x81\x12\x0e\xfc\x42\xf9\xf9\x1e\x3e\x3d\x10\x8c\x76\xf4\xc2\x8d\xe6\x5a\xf1\x81\x0a\x9f\x73\x26\xe4\xf8\xdf\x85\x83\x36\x1e\xa5\xab\xa0\x7b\xc7\xe8\x4c\x65\xf7\x6c\x35\x17\x4f\xa1\x13\xac\xb8\x9a\x3c\xcb\xec\x4b\x59\x70\xf1\x81\x63\x6f\x3a\x2a\x87\xdd\x25\x8a\x06\x3a\xe3\x98\x4f\xf7\x9c\xa5\xfd\x61\x20\x39\x8d\x54\x09\x13\xdd\xb9\x8e\x6e\xb7\x41\xdc\x8b\xfb\x8d\x59\x8a\x8b\x38\xce\x55\xc2\x4f\x25\x20\xca\xae\xaa\xa3\x6c\x36\x84\x64\x01\x39\x1c\x05\x76\x90\x99\x43\x36\xca\x11\x9e\x1c\xa2\x0a\x35\x4b\xc6\x20\x82\xa4\xfd\xa3\x38\x43\x77\x85\x79\x86\x64\x00\x46\x10\x64\x62\x21\x7b\x9a\x53\x4f\x78\xa6\x50\x90\x12\xe7\x82\xe9\xe4\xcc\x73\xb2\x46\x82\xc3\x2d\x04\x29\xde\x2b\x27\xc8\xbc\x77\xab\x6c\x1b\xa8\x29\xcc\xe0\x33\x53\x14\xd6\xa3\xa1\xa5\x20\x55\xd1\xb2\x3e\xd3\xd3\x52\x21\x57\xb1\x5b\x1c\xe2\xbd\x96\x34\xed\x88\x11\x4d\x69\x08\x84\x9c\x88\x87\xa5\xbd\x6c\xe4\x7f\x0b\xc2\xaf\x9e\x0e\x04\xb2\xb5\xc3\xce\xeb\x49\xcb\x56\x99\x64\x15\xef\x72\x25\xa3\x48\x2e\xa6\x7a\x58\xd1\x40\x0a\x14\xc1\x0e\x0a\xa7\xca\x62\x21\x14\x1b\x72\x9e\x00\xd4\xe4\x71\x5c\x95\x5d\x53\xd2\x4a\xf2\x83\xfd\xbe\x60\x58\x8e\x3b\xd1\x38\xd5\x9c\x06\x18\x41\x85\x57\x88\x5d\xa9\xe9\x0b\x49\x53\x4d\xee\x90\x4a\xe5\x1a\x35\xd2\x9f\x54\xd0\xa8\x30\xdf\x38\x54\xa3\x72\xa9\xba\x92\x20\x79\x63\x28\x25\xd2\x29\x3e\xe2\xa3\xae\x9c\x8f\x84\x5a\xdf\xe4\x89\x3a\xc2\xdb\xd0\x50\x0a\xa5\x05\xd7\x9d\x32\x4b\x33\xa6\x22\x68\xf8\x5c\x45\x4c\x55\x3a\xca\x94\xe5\x24\xc4\xa2\xbf\xa1\xaf\x1b\xb5\xa6\x12\xe2\x42\x8a\x18\xe3\x89\x18\x16\xe5\x9c\x2f\xe9\x44\xfa\x76\x45\x49\x25\x0e\xf9\x53\xe8\xc4\xda\x0b\x26\xd6\xe5\x27\x04\x55\x04\x5b\xb0\xb9\xee\xa4\x52\x39\x55\x8a\xcd\x2b\x31\x85\x90\x63\x49\xfc\x91\x3a\x5f\xa1\xa6\x49\xd5\x11\x48\x55\x0d\x2b\x31\x47\x21\x17\xd6\xd5\x1f\xc1\x50\x91\x4d\x8c\x23\x06\xf3\x69\xe1\x00\xc2\x82\x84\xf5\xd6\xab\xa8\xa1\x62\x27\xd3\x29\x64\x32\x83\xda\xd5\x58\x69\xc8\x08\x67\x24\x72\x6a\x72\x40\x08\x18\x02\x48\x0b\xca\xce\x22\x45\x3a\x33\xf4\x5e\x0f\x05\x16\x1b\xfb\xe4\x60\x33\xf5\x1d\x66\x8d\xb7\x0f\x97\xeb\x59\xc4\x39\x8c\x68\xb1\xc2\x51\xa7\xb4\xba\xe3\xc8\xf9\x91\x1f\x3c\x4d\xd4\xfe\x9a\x84\x85\xb2\x57\x6c\x7d\x36\xb1\x9a\x24\xa9\x07\xac\x06\x52\xd4\x70\x05\xce\x69\xef\x16\x38\xdf\xef\x01\x54\x3f\x15\x00\xaa\x6d\x92\x52\xc6\x1d\xb5\x6d\x88\x5c\x44\x0f\x40\x07\xe2\x0c\x7e\x1d\xf5\x9f\x56\xf9\x3a\xa4\x7c\x2a\xd9\xaa\x94\x25\x5d\xfb\x64\x76\x42\xbf\xc5\x57\xc2\x35\x9b\x8e\x68\xc4\x97\x54\xe6\x5c\x5d\x41\x23\xb5\x71\x60\xeb\x5d\x29\x4b\x2b\xc4\xc8\xd0\xe2\x7b\x45\x1d\xcd\xcd\xf5\x44\x1d\xac\x9b\x88\x1d\xa1\x92\x33\xf9\x07\x33\x66\xd3\x4e\xd7\x6c\xd8\xce\x46\x55\xa9\x26\xad\xa3\x5f\xd2\x29\x57\xa8\x2a\x78\xdf\x83\xd6\xb6\x9c\x7b\x8c\x85\x0a\x5b\xbb\xc8\x02\x0a\xab\x12\x75\x83\xd5\x1e\x25\x3a\x41\x96\xcd\x51\xf9\xca\xb3\xb2\x46\x16\x9d\xd2\x7b\xef\xe4\xc3\x89\x51\xd0\x44\x6e\x9b\x25\xa2\x82\x34\x53\x2b\x35\x0b\x2a\xd4\x88\x74\x27\x15\x12\x95\xd4\x48\x0a\xb8\xf7\x6b\xb0\x04\xcb\x4a\x55\x90\xda\x69\x54\xaa\xdf\x29\x23\x88\xaf\x61\x00\x22\xe1\x3d\xfa\x1d\x06\x80\x0e\x88\x06\x10\x0f\x8c\x07\xc8\x01\x85\x09\x30\x0f\xdc\xe8\x1a\x6b\x76\x10\x16\xa8\x24\xa8\x8e\x8c\xab\x17\xc4\xb5\xf7\x45\xd5\x85\x51\x23\xb9\x06\x51\x0e\x69\x23\x45\xee\xa5\xbd\x80\x5d\x62\x63\x7e\x94\x16\x58\x08\x79\x17\x3c\x62\x08\x3a\x6a\xce\x3e\x86\x19\x57\x70\xe9\x4f\x88\x87\x8e\x1f\x61\xe9\xa2\xc9\x3c\x71\x2a\x19\x8e\xd5\x04\xf1\x41\x67\x24\x59\xbd\xa0\x52\x71\x7f\x8a\xa0\x9a\xbb\x81\xff\x35\xd3\xd9\x72\x93\x55\x21\x64\x7d\x45\xd9\x45\x1b\x41\xad\xab\x26\x10\x84\x67\xb7\x91\xe7\x7e\xc2\x68\xe8\xf6\xbc\x06\xb6\x9f\x2f\x96\xfd\x91\x2f\xd6\x02\xfc\xe0\xb3\x17\xc5\x5e\x1f\xde\x5f\xbd\x81\xfb\xe8\xc6\x7e\x18\xe0\xd1\x8d\x3e\xa9\x55\xb2\x7d\x43\xd0\xba\x6a\x03\x3d\x2f\x88\x31\xf2\xef\x03\xc6\x41\x12\x6f\x4c\xd4\xd7\x05\x1c\x45\xe8\x69\xf7\xb0\x74\x2e\xf7\x1c\x18\x86\xe3\xa0\x2f\x09\x86\xfa\x85\x18\x25\x39\x48\xbd\x85\x62\xfe\x7d\x8a\x84\xf2\x69\x08\xa4\x32\x8a\x04\xa4\x10\x1e\xad\xab\x0b\xa0\x37\x8e\x22\x2f\xe8\x7d\x55\xb0\x41\x4d\xe9\x24\xf6\x48\x8e\x99\xfc\xd6\xa1\x27\x8f\x30\x8b\x4a\x62\x73\x6c\x97\xc0\x57\x2f\x20\xb0\x2c\x86\x8c\xe6\x79\xb7\xf9\xaa\xe4\x99\x1c\xc6\x15\x70\x1b\x85\x9f\xbc\x00\xb7\x6e\x54\x14\x67\xba\x50\xcc\x17\xea\x00\x23\xaf\xb7\x89\xe3\xbd\x4e\xea\x4c\x81\xc9\x59\x5c\x52\x53\x5c\x7c\xf8\xed\x21\xde\xae\x81\xbe\xef\x7a\x91\x37\xf2\x47\x26\xb6\xd9\x6d\xe0\xdd\xe7\x9e\x76\x27\x42\x04\x35\xd4\x70\xea\x02\xbd\x70\xf8\x35\xf2\xef\x1f\xc4\x4d\x26\x3a\x9f\x04\x2f\xe1\x9d\x09\xff\x25\x04\x18\x52\x52\x7f\x49\x1e\x67\x05\x31\x90\x6e\x1a\xad\x4e\x13\xb8\xf3\x1e\xfd\xc0\x0f\x3c\x84\x51\xdf\x0f\xdc\x01\xfc\xa0\xef\xf7\xdc\x38\x8c\xac\x13\x8f\x9e\x99\xd9\xea\x8b\xb1\x62\xa7\x05\x0c\xbc\xbb\xf8\x6c\x18\xfa\x41\xec\x07\xf7\xe8\x87\xe3\xdb\x81\x07\x37\xb8\x1f\x78\xf8\x73\x1c\xc6\x32\x1b\x2a\xc8\x40\xe3\x86\xa1\x2f\x6e\xee\x4f\x9e\x25\x2b\x4b\x38\xdb\xd8\x7c\xd3\x4e\x79\xc3\xa2\x5f\x61\x8d\x61\x21\x97\x81\x71\x0e\x8c\xc2\xbb\x18\x0f\x5f\x87\x0f\x5e\xa0\x37\xad\x8d\x3b\x1c\xc7\xbe\xa4\x6b\x75\x2e\x80\xc8\xbb\xf7\x47\xb1\x17\x79\xfd\x4a\xf1\xce\x90\xb6\x40\x9e\xf2\x2f\x6d\xee\x2c\x13\xef\x97\xc0\xa3\xdb\x8b\xc2\x40\xeb\x0f\x62\x8f\x53\x86\xed\xbc\xf3\xae\x80\xbe\x77\x1f\x79\x9e\xc0\x89\x85\xec\xe7\x30\x5f\x7a\x15\xbc\x4f\x68\x75\x3a\xc0\x70\x30\x1e\x9d\x3d\xfa\xc1\x78\x44\x2a\x00\xc3\xdb\x28\x54\xcd\x2a\x8a\x09\x25\x34\xd7\xc0\x68\x3c\xf4\xa2\x51\x2f\xf2\x87\x31\xe2\x2f\xa1\xa4\x9a\x42\xec\xd4\x0c\x44\x94\xfc\x35\x89\xa2\x7b\x57\x91\xf6\x10\x79\x9e\xf4\xe0\x44\xf3\x21\x8b\x31\xd3\x68\xe5\x5d\x37\x01\xb7\x37\x8e\x3d\xb8\xbd\xbc\xde\x6a\x28\x2c\xed\x1c\x3c\x56\xf6\xaf\x0c\x5a\xd7\x2d\xe0\xd1\xef\x45\x21\xa1\x9d\x8a\x95\x34\xd3\x63\x41\x7c\xa7\x77\x10\xdc\x06\x86\xfe\xa0\x17\x85\x5f\xf8\x92\x04\xea\x52\x24\x11\x29\xd4\x6a\x3e\x35\x04\xcf\xf5\x79\x6e\x83\x7e\x7f\xe0\xa1\x1f\xc6\x0d\x51\x7b\x52\x84\xec\x13\xbd\x23\xdf\xb2\x5b\x28\x2f\xff\xbc\xbe\x3f\x18\xb8\xd4\xd8\x85\x07\xec\xb7\xe9\xf9\xaa\x97\x72\xb4\x85\x81\x67\x78\xa0\xa1\x84\xb7\x23\xaf\x4e\x03\xe0\x2a\xa7\xad\x51\x6f\x3c\x30\xe6\xe9\x72\xdf\x19\x2b\x81\x63\x97\xa7\xaf\x3b\xc0\xa6\xd2\x29\x95\xa8\x1d\xf2\x37\x3d\x76\xa9\xd8\x9c\xc6\xc1\xa7\xac\x1d\xd0\x6b\xe0\xf3\x78\x70\xef\x46\xb8\x8b\xdc\x6d\x05\x1a\x06\x39\x40\x37\x8a\xbd\x48\x7e\x00\xea\x5f\x3b\x28\x09\x05\x80\xfc\xba\x43\xc0\xc6\x35\x00\x54\x31\xb1\x7a\xd3\x31\xaa\x28\x91\xb6\x2e\x8a\x8b\xf9\x7f\x1b\xcd\xbb\xbc\xe6\x0f\xee\xe0\x4e\xa7\x36\xaf\x34\xaf\x32\xd7\x02\x1d\x9f\xa3\xea\x32\x0e\x16\xed\x60\x50\x55\xab\x68\xae\x66\xb7\x49\xd5\xdc\x70\xfc\xde\xc5\x23\xa3\x8f\x85\xde\x52\xf5\xb1\xe8\x29\xe2\x63\xd0\x1a\x04\x52\xe7\x29\xea\xf6\x6e\x3e\xee\x8a\xc3\x82\x3f\xc7\xde\x88\xd9\x72\x6a\x1a\x85\x32\xd7\x61\x5a\x30\x43\x72\xcd\x85\xb6\x81\x81\x1b\xfb\x01\x7a\xee\xd0\x8f\xdd\x01\x06\x5e\x1c\x7b\x11\x5c\x7c\xf1\xe3\x07\xdc\x47\xee\x67\xef\x98\x4b\x95\xea\xc2\x48\x4c\x55\x86\x7e\xad\xee\xb9\x19\xcf\x26\x1b\x33\x10\x24\x47\xd7\x89\xe7\xc2\x8c\xa7\xe7\x47\xbd\xf1\xe3\xdd\xc0\xfb\xcb\xcc\xd1\xd4\x55\xda\x17\xf2\x16\xa0\x2e\xcd\xa0\x62\x7f\xd0\xf7\x1a\x5c\xe9\x4d\xa7\x3a\xb5\xe0\xb9\x32\xe3\xb1\x6a\xe1\xeb\x76\x5c\xc7\x8c\x29\xca\xd3\x9c\x7b\x1b\xee\xa3\xdb\x22\xb9\xd6\x00\xea\x5a\x07\xca\xa3\xc4\x26\x95\x62\x54\xd4\xee\x36\xa9\x62\x9f\x30\x9f\x91\x82\x99\x4a\xb0\x0c\xad\x7b\xf5\xdd\xea\x76\x35\xa8\x7b\xbb\x3d\x20\x57\x5e\xfa\xc9\x02\xf8\x57\xae\xc7\x2b\x24\x7f\x4c\x7e\x2b\x4c\xb6\x41\xd4\x6e\x36\x35\x88\xbc\x42\xd6\x62\xc3\x9c\x58\x8e\xbb\x4d\xef\xd7\x76\xb3\x65\xc6\x63\x60\xad\xf7\xc1\xa3\x63\x75\xaf\x0c\x6b\xd5\x0d\x4a\x47\xed\x5e\x09\x96\xa8\x1b\x93\x8e\xde\x7d\x29\x90\x48\x79\x4b\x5b\x57\xb5\x82\x22\x37\x10\x04\x1b\xf9\x3a\x26\xf7\xd9\xc0\xa9\x5f\xbe\x8e\xb9\x7d\x3e\x50\xe8\x44\xa3\x0e\x10\x3a\xaa\xf6\xd9\xc0\xa0\x8b\xd5\x81\x41\xc7\xcc\x5e\xfc\x20\x46\x90\xf4\x16\x80\xd6\xcc\x0e\xdf\x30\x43\xcd\x28\x4c\xc3\xc6\x75\x3c\xed\xa6\x8e\x7a\x03\xcb\x4c\x4f\x90\x29\xb7\x95\x4b\x60\xed\x96\x8e\x78\xc3\x1a\xca\x45\x62\x25\xbe\x5a\x91\xf0\xe8\x88\x37\xac\xa1\x5c\xac\x82\x47\x47\xbc\x61\xb9\x72\xb1\x5e\x50\x3a\xe2\x0d\xad\xcb\xc5\x7a\xf1\xe8\x48\x37\xac\xa9\x5c\xac\x82\xe9\x12\x78\x1c\x0f\x62\x7f\x38\xf0\x7b\xae\xf4\x6e\x6b\x77\x93\xc2\x38\x3c\x21\xf3\xad\x99\xb2\xc2\x4e\xa2\x8e\x7a\x77\x56\x18\xc5\x51\xf8\x49\x2a\x0b\xf9\xe9\x1c\xd4\xde\x4f\x21\x67\x30\x09\xdd\x8a\x7b\x5a\x3a\x5a\x1e\x5b\xef\x75\xc5\x62\x27\xba\x48\x47\xd1\x63\xeb\xbd\x5e\x2f\x1e\x1d\x37\x8f\x2b\xb7\x86\xa7\x83\x6a\xeb\x08\x7a\x5c\xaa\xc8\xd2\xc1\xa8\x86\x49\x47\xd2\x5f\x89\xe3\x94\xe8\x91\x2a\xe4\xe3\xf5\x9b\x86\x3a\xa8\x81\x2e\x0c\x2d\xc6\x8a\xed\xb6\x8e\xb4\xe3\x87\x30\xda\x50\x40\x95\x0f\xc4\xc9\x15\xfa\xb9\x09\x31\xd4\x81\xa8\x47\x8f\xee\xe0\x00\x63\xf4\xe0\x46\x43\x8c\x88\x8d\x4d\x04\x68\x7d\x85\xfb\x08\xa6\xdd\xbe\x60\x81\xd8\xcf\x84\x84\x60\x62\xfa\x40\xb5\x14\x2a\x28\x3a\xda\x97\x26\x34\x24\x7a\x68\xeb\x58\x2f\x9a\x2b\x13\x1a\x79\xd3\x93\x6a\x54\x9f\xc9\x4e\x82\xd4\x31\x41\xb2\x9c\x06\xd5\x87\xe6\xda\x84\xa6\x44\x72\xb7\x24\x20\x0b\x44\x5d\x13\x22\x79\x12\x64\x72\x99\x52\x10\x9d\x02\xe9\xbc\xc9\x43\x22\x73\x20\x50\xce\x62\xfa\x10\x86\x0a\x74\x65\xc2\x6e\x05\xf2\x38\x3b\x13\xd2\x4e\xec\x37\x3a\xb4\x58\x1d\x74\x53\x21\x2b\x6a\x50\xd8\x9e\xb7\xa9\x5a\x98\xee\xa6\x42\xe7\x6d\x16\x0f\x3b\x13\x92\xdf\x0b\x5b\xcd\x41\x75\x68\x74\x1e\xe6\xc9\x9c\x4e\x84\x4c\x21\x56\x1f\x1a\x9e\xd1\x4b\xcd\x83\xea\x86\xc4\xd3\x7a\x99\x69\x50\xdd\x88\x78\x6a\xe7\x66\x41\x7b\x7a\xd8\x2f\x52\xfc\xc7\x58\xf2\x9b\xe0\x5c\x1a\xcf\xda\xea\xe4\x47\x54\xc8\x39\x64\xea\xed\x6f\x74\x07\x4a\x21\xb6\x91\xc6\xb3\xb2\xf5\x9c\x07\xaa\x9a\xc7\xfa\x9a\x39\xa4\x1f\x56\xe4\x10\x78\x1a\xb6\x9d\xf2\x58\x88\x2d\x42\x70\xc1\xb3\xee\x66\xc6\x33\x61\xde\xfb\x32\x7f\x01\x57\x44\xfd\xc5\xe5\xf0\x05\x4f\x9b\xb6\x13\x1d\x69\x65\x53\x01\xaa\xdf\x34\x12\x1a\x9e\x34\xed\xe7\x39\xb0\x29\x49\xad\x6d\xc3\x93\xa6\xfd\x34\xa7\x5e\x34\x3c\x69\x96\x9c\xe5\x28\x21\x7c\x22\x24\x9e\x34\xe9\x24\x87\x8c\x04\xb8\x95\x4f\x46\xc3\x13\xe6\x7f\x71\x8e\x73\xd1\x01\xfa\xfe\x67\x7f\xa4\x4e\x70\x4c\xdf\xc6\x09\x70\x26\x85\x5f\xbf\xd9\xf7\x95\x17\x3c\xe5\x6a\xe7\x3b\x85\xe5\xd1\xe4\x37\x3f\xc8\xb5\x34\x0d\x4f\xbf\x63\xf6\x4d\x87\x44\xa8\xe5\xa7\x27\xc5\xbc\x73\xc9\x53\x31\x9d\xe5\x58\x34\x75\x35\xa0\xe1\x39\xf9\xfd\x26\x39\x16\x90\x78\x62\x7e\xb7\x39\x8e\x05\x22\x9e\x9c\xe9\x14\xa7\x86\xf1\x9b\x84\x86\x72\x40\x8e\x86\x27\xe7\x93\x66\x36\xd2\x89\x6e\x80\x33\x11\x3f\xa7\x6c\x5f\xf2\x84\xfc\xf5\x3f\xe2\x26\xce\x30\xff\x0e\x00\x00\xff\xff\x3f\x39\x52\x57\x73\x5f\x00\x00") + +func fontsBlockFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBlockFlf, + "fonts/block.flf", + ) +} + +func fontsBlockFlf() (*asset, error) { + bytes, err := fontsBlockFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/block.flf", size: 24435, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBubbleFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x9b\xe9\x9b\x23\x55\xf5\xc7\xdf\xf7\x5f\x71\x7e\x3f\x17\x40\xa7\x97\x24\x9d\xa4\x5b\x11\xa7\xba\x52\x9d\x2e\x26\x5d\x15\x2a\x95\x19\x7a\x44\x31\xdd\x5d\xdd\x1d\x49\x57\xda\x2c\x33\xb4\x1b\xee\xfb\xbe\xef\x0b\x08\xca\x22\x08\x08\x28\xbb\x82\x80\x88\xb2\x09\x82\xac\xca\x2a\xa2\x6c\x82\x20\x8b\x3e\x09\x6b\xce\x3d\xa7\xbe\xf5\xf8\xc2\xa7\xf5\x79\x3e\xe7\x33\x37\xa7\xce\x3d\x75\xee\x4d\x5c\x6b\xad\x65\x1b\xc7\xd0\x34\xe5\x68\x86\x32\x79\xca\x64\x68\x8a\x32\x53\x99\x6c\x71\x6c\xae\xbf\xbc\xdc\x8a\x68\x79\x9b\xca\xad\x28\x8e\xc9\xde\x68\x6c\x6d\x45\xad\x16\x4d\x4f\xce\xe6\xc6\xdc\x78\xa5\xd5\x5f\x8d\xba\xb4\xb2\xd1\xe8\x34\x56\x7a\x51\xa7\x4b\x99\xec\xcc\x78\x36\x9f\x1f\x73\xe2\x8d\x46\xbc\x12\xad\xd2\x5a\xbb\x43\x95\x46\xaf\x19\x8f\x67\x77\xe4\x76\x4c\x0f\x5c\x87\xb6\x37\x62\xb2\xdb\xfb\x1b\x31\x1d\xbc\x32\xf8\xb3\x73\x65\xa5\xd9\x9a\x68\x77\xd6\x0f\x19\x1b\xa2\x2f\x0b\xa9\x1b\xf5\xba\xd4\xed\x6f\x6d\xb5\x3b\xbd\x68\x95\xda\x71\x6b\x9b\x9a\x6b\xb4\xdd\xee\x77\xa8\xbb\xd2\x89\xa2\x98\xd6\xda\x71\x8f\x56\xdb\x51\x77\x6c\xad\xb9\xde\x8a\x7a\xd4\x89\x5a\x51\xa3\x1b\x51\x76\x22\x4b\xe3\xe3\xe4\xb5\xf7\x45\x9b\xcb\x51\x87\x32\xb3\xb3\x85\xb1\x6a\xd4\xd9\x6c\x76\xbb\xcd\x76\x4c\xcd\x2e\x6d\x44\x9d\x68\x79\x9b\xd6\x9b\xfb\xa2\x98\x7a\x6d\xda\x6c\xaf\x36\xd7\xb6\xa9\xb7\xd1\xec\x0e\xbd\x3b\xa8\xd1\xa5\x56\x3b\x5e\x1f\xfc\xed\x6d\x44\x63\x43\xa0\x19\x75\x0e\xe8\x52\xdc\xd8\x8c\x06\x8e\xad\x56\x63\x65\xb8\x34\x6a\xd0\x4a\x7b\x73\x33\x8a\x7b\xd4\x6a\xc6\xd1\xc4\xd8\xd8\xe2\xf3\xf4\xea\xe0\x53\x57\x1b\xfd\x16\xcd\xf5\x3b\xbd\x76\x4c\x07\x77\xdb\xad\x7e\xaf\xd9\x8e\x77\x46\x8d\x4e\x6f\xa3\xd5\x8c\x8f\x9a\x88\xa3\xde\x21\x94\xc9\x4e\xce\x16\x06\x0b\x69\x3e\x9f\x5b\x8a\xa3\xfd\xb4\xd5\xe8\x34\x36\xa3\x5e\xd4\x19\x7b\x39\x11\xcb\xdb\x34\xef\x96\x07\x9f\xb6\x11\xaf\x0e\xfe\xeb\x9e\x66\x3c\x41\xb4\xd8\xd8\xa6\x46\xab\xdb\xa6\xe5\x88\xba\xad\xe6\xfa\x46\xaf\xb5\x4d\x9b\x2f\xae\x62\xf0\x2c\x96\xa3\xde\x20\xaf\xfd\x6e\x34\xd6\x5e\x1b\xea\xd7\xfa\xad\xd6\xf8\xfe\xe6\x6a\x6f\x63\xf2\xa8\xa8\x13\x4f\x76\x37\xfb\xdd\x0d\x6a\xb4\x7a\x51\x27\x6e\xf4\x9a\xfb\xa2\xee\x0e\x5a\xee\xf7\x68\x35\x5a\x6b\xf4\x5b\x3d\x6a\xf7\x7b\x5b\xfd\xde\xe0\x93\x7b\x7e\x38\x78\x54\xf1\x7a\xb4\x3a\x31\x46\xc7\xec\x7c\xe5\x7f\x76\x8e\x11\xd1\x91\x44\x83\xbf\x93\x74\xc4\xe0\xef\x81\xf4\x7f\x74\xd0\xe0\x7f\x1f\x71\xe4\x24\xc9\xc0\xff\x23\xe0\x55\x08\x78\x35\x02\x5e\x83\x80\xd7\x22\xe0\x00\x04\x1c\x88\x80\x83\x10\xf0\x3a\x04\xbc\x1e\x01\x3b\x10\x30\x8e\x80\x09\x04\x4c\x22\x60\x0a\x01\x19\x04\x64\x11\x90\x43\xc0\x34\x02\xf2\x08\x28\x20\xa0\x88\x80\x19\x04\xcc\x22\xe0\x0d\x08\x78\x23\x02\x0e\x46\xc0\x9b\x10\x70\x08\x02\xde\x8c\x80\x9d\x08\xb0\x10\x30\x87\x00\x1b\x01\x25\x04\x38\x08\x98\x47\x40\x19\x01\x0b\x08\x70\x11\x70\x28\x02\x76\x21\xa0\x82\x80\x45\x04\x78\x08\xf0\x11\x50\x45\xc0\x61\x08\x08\x10\x50\x43\x40\x88\x80\x3a\x02\x76\x23\x60\x0f\x02\x0e\x47\xc0\x12\x02\xf6\x22\xe0\x2d\x08\x38\x02\x01\x6f\x45\xc0\xdb\x10\x70\x24\x02\xde\x8e\x80\x06\x02\x96\x11\xb0\x82\x80\x55\x04\x44\x08\x58\x43\xc0\x3a\x02\x36\x10\xd0\x44\xc0\x3b\x10\x70\x14\x02\x5a\x08\xd8\x44\x40\x8c\x80\x36\x02\xb6\x10\xf0\x4e\x04\x74\x10\xd0\x45\x40\x0f\x01\x7d\x04\xec\x43\xc0\x7e\x04\x1c\x8d\x80\x6d\x04\xbc\x0b\x01\xef\x46\xc0\x7b\x10\xf0\x5e\x04\xbc\x0f\x01\x97\x22\xe0\x46\x04\xdc\x8a\x80\xbb\x11\xf0\x04\x02\x9e\x41\xc0\x1d\x23\x40\x26\x3b\x23\x41\xef\x67\xd0\xac\x04\x7d\x60\x14\xca\x4d\x49\xd0\x07\x19\x94\x91\xa0\x0f\x31\x28\x2b\x41\x1f\x66\x50\x4e\x82\x3e\xc2\xa0\x69\x09\xfa\x28\x83\xf2\x12\xf4\x31\x06\x15\x24\xe8\xe3\x0c\x2a\x4a\xd0\x27\x18\x24\x66\xfc\x93\x0c\x12\x33\xfe\xa9\x51\x68\x5a\xcc\xf8\xa7\x19\x24\x66\xfc\x33\x0c\x12\x33\xfe\x59\x06\x89\x19\xff\x1c\x83\xc4\x8c\x7f\x9e\x41\x62\xc6\xbf\xc0\x20\x31\xe3\x5f\x64\x90\x98\xf1\x2f\x31\x48\xcc\xf8\x97\x19\x24\x66\xfc\x2b\xa3\x50\x5e\xcc\xf8\x57\x19\x24\x66\xfc\x6b\x0c\x12\x33\xfe\x75\x06\x89\x19\xff\x06\x83\xc4\x8c\x7f\x93\x41\x62\xc6\xbf\xc5\x20\x31\xe3\xdf\x66\x90\x98\xf1\xef\x30\x48\xcc\xf8\x77\x19\x24\x66\xfc\x7b\xa3\x50\x61\x8a\xc8\xf3\xc7\xe7\x02\xc7\xda\x45\xb5\xaa\x65\x3b\x52\xd0\xf7\x59\x50\x86\xc8\xf5\x76\x3b\x41\xe8\x94\xc8\x39\xdc\xae\x58\x8b\x56\xe8\xfa\x1e\x2d\x5a\xc1\x2e\x29\xfe\x07\x2c\x3e\x4b\x64\x3b\x5e\x48\x35\xb7\xec\x49\xfc\xb1\x8c\xcf\x11\x55\xfd\xba\x57\x52\x03\x8e\x63\x01\xd3\x44\x76\x3d\x08\x1c\xcf\x5e\x52\x63\x7e\xc8\x62\xf2\x44\x4b\x8e\xa7\xe2\xc7\x33\xbc\x40\x34\x17\xf8\xbb\x1c\x8f\xe6\xac\x40\x0a\x38\x81\x05\x14\x89\x6a\x8e\x3d\xcc\x93\xf6\x6f\xfc\x88\x85\xcc\x10\x95\x5c\xcb\x09\x9c\x9a\x5b\x93\xf8\x1f\x33\x7e\x96\xc8\xf6\xab\x4b\x81\x5b\x5e\xd0\x93\x7b\xe2\x68\x50\x71\x8a\x68\xde\x59\x74\x3d\xd7\x73\xc8\x0f\x4a\xae\x67\x55\xc8\xf5\x4a\xae\x6d\x85\xbe\xf8\xc1\x4e\x62\x82\x0c\x51\xc5\x99\x0f\xc7\xab\xbe\xeb\x85\xae\x57\xa6\x92\x5f\x9f\xab\x38\x64\x79\xe5\x8a\x43\x87\xd5\xfd\x30\xb9\x3a\x4e\x66\xbe\x2c\x0d\xaf\x16\xb5\xf5\x9f\xc2\xf0\x1c\x51\xcd\x9f\x0f\x69\x61\xa9\xba\xe0\x88\x11\x3f\x61\x11\xd3\x44\x81\x53\x76\x6b\xa1\x13\x38\x7a\x4d\x9d\xca\xa2\xf2\x44\x8b\x96\x1d\xf8\x22\x7c\x1a\x83\x0b\x44\x25\xa7\x1c\x38\x8e\xaa\xff\x29\x8b\x28\x12\x55\x2b\xf5\xda\xf8\xa2\xeb\xd5\x6b\x6a\xd4\xe9\x2c\x6a\x86\xa8\x56\xaf\x3a\x41\xcd\x0e\xdc\x6a\x48\xe1\x1e\x5f\x8a\x3a\x83\x45\xcd\xb2\xa8\x85\xc0\x11\xf7\xfd\x99\xa3\x71\x33\x53\x44\x96\x5d\x0f\x1d\xb2\xec\xc1\xfe\x95\x42\x7e\xc6\x42\x32\x44\x8b\xae\x1d\xf8\xea\x27\x3a\x8b\x05\x64\x89\xaa\x6e\xc5\x0e\xfc\x3d\x6a\xc8\xd9\x2c\x24\x37\xf8\x37\x4a\xa5\x8a\x43\x25\x5f\x5c\xd4\x39\x2c\x60\xd0\x1e\x9c\x92\x5b\xa9\x58\x12\xfd\x73\x46\xe7\x47\xb3\xe5\x7b\x62\xae\x7e\xc1\xa2\x0a\x83\x72\xa9\xd9\xf5\x4a\xea\x7d\x75\x2e\x33\x14\x89\x86\x3b\xf9\x7f\xde\x58\xe7\x31\xe1\x0c\xd1\xee\x7a\xa5\x6c\x05\x34\x1f\x58\xcf\x77\x22\xdf\x1b\x88\xac\x20\x74\xc4\x25\x9d\xcf\x0c\xb3\xb2\x61\xc1\xaa\xcc\x4b\xe1\x17\x8c\x86\xcf\x4e\x99\xe1\xc3\xda\x7b\x71\x09\x62\x93\xbb\x90\x49\x5e\xf9\xf2\x39\xac\xee\xd4\x12\x53\x70\x11\x0b\xce\x12\x55\xac\xd0\xf5\xc8\xb6\xaa\x6e\x68\x55\xa8\xe2\x84\xa1\x13\x90\x45\x7b\xdc\x70\x81\xca\x81\xb5\x5b\x7c\xba\x17\x33\x4f\x2e\xd9\x33\xdc\x25\x92\xe7\x97\xcc\x33\x9d\xec\xb1\xdd\xc0\xae\x2f\xce\x57\x9c\xc3\x25\xd9\xaf\x98\x2c\x9f\x2c\x0b\xdd\x4a\x49\x5c\xd4\x25\xcc\x53\x48\xf6\x24\xbe\x92\x2e\x65\xae\x62\xb2\x2b\x18\x94\xb5\x35\xe7\xcb\x59\xff\x35\x93\xcd\x68\x32\x31\xfa\x32\x16\x3d\xab\x44\xdb\x2f\xe4\x5a\xef\x08\x97\x8f\x98\xb2\x53\x53\x8a\xc9\x01\x55\x74\x05\xf3\x64\x92\x3d\x6a\x15\xfd\x86\x79\xb4\xaa\x76\xd2\x54\xd1\x95\x4c\xa6\x95\xb6\x93\xe2\xe9\xff\x96\xb9\xb4\xf2\x76\x41\xa2\xae\x62\x1e\xad\xb2\x5d\x90\xa8\xdf\x31\x8f\x56\xd9\x6e\x9a\x44\xfd\x9e\xc9\xb4\xd2\x76\x53\x24\xea\x6a\xe6\xd2\x2a\xdb\x09\x17\xa4\xf0\x6b\x58\xb8\x56\xda\x1e\xd8\xf9\xd7\x8e\x7a\x32\x5a\x61\xfb\xe0\x79\x5d\xc7\x3c\x5a\x61\xfb\xe0\x79\x5d\xcf\x3c\x5a\x61\xfb\x69\x9e\xd7\x1f\x98\x4c\x2b\x6c\x1f\x24\xe9\x06\xe6\xd1\x8a\xda\x4f\xf1\xdc\x6f\x64\xae\xc1\x50\x59\xaf\x84\x6e\xb5\x32\x98\x0b\x92\xce\x06\x7f\x64\x91\x5a\x29\xbf\xb0\x8a\x5a\x38\x38\x9c\x48\xa2\x9b\x98\x48\x2b\xe3\x3a\x78\xe6\x37\x33\x8f\x56\xc2\x75\xf0\xcc\xff\xc4\x3c\x5a\x2d\xd7\xd3\x3c\xf3\x5b\x46\x65\x59\xad\xa0\xeb\x29\x9e\xd5\xad\xcc\xa5\x15\xf5\x12\xf8\x80\xb7\x31\x8f\x56\xd4\xe1\x82\x1f\x88\x8f\xfe\x76\x26\x78\xa9\x90\x6b\x8b\x56\xe5\xa5\xf0\xda\x82\x15\x54\x49\xfc\x24\x77\x30\xc1\xb4\x28\x40\x33\xd0\x9d\xcc\x92\x4f\xb2\xa8\xd9\xf8\x33\xb3\x14\x92\x2c\xc9\x0f\xfb\x2f\x4c\x55\x4c\x52\xa9\xdb\xfb\x2e\x66\x99\x49\xb2\x24\x16\xcc\xdd\xcc\x34\x9b\x64\x4a\x9e\x7c\xee\x19\x55\xe5\xa6\x64\x95\x18\x7b\x2f\x8b\xcd\x88\xb1\x78\xea\xb9\x8f\x79\xb2\xa2\x07\xcd\x3c\xf7\x33\x8b\x5c\xbc\x68\xe2\xf9\x2b\xb3\xc8\x15\x9c\x6a\xde\x79\x80\xa9\xe4\x32\x4e\x33\xed\xfc\x8d\x99\xe4\x52\x46\xb3\xce\x83\xcc\x22\x57\x31\x9a\x74\xfe\xce\x2c\x72\x15\xa7\x9a\x73\xfe\xc1\x54\x72\x19\xa7\x99\x72\x1e\x1a\x35\x4d\xcb\x55\xac\xcc\x38\x0f\xb3\x60\xb9\x8c\xd1\x84\xf3\x08\xb3\xc8\x45\x8c\xe6\x9b\x47\x99\x45\x2e\x62\x34\xdd\x3c\xc6\x2c\x72\x11\xa7\x9a\x6d\xfe\xc9\x54\x72\x11\xa3\xc9\xe6\x71\x66\x91\x0b\x38\xcd\x5c\xf3\x04\x33\x15\x89\x4a\xee\x6e\xb7\x96\x34\xd1\xfc\x8b\xc5\xc8\x25\x0b\xe7\x99\x27\x99\x46\x2e\x57\x34\xcd\x3c\x35\x6a\xc9\xcb\xa5\x8a\x66\x99\x7f\x33\x8b\x5c\xb3\xa9\x26\x99\xa7\x99\x4a\x2e\xdc\x34\x73\xcc\x33\xcc\x24\x17\x2f\x9a\x62\x9e\x65\x16\xb9\x78\xd5\x19\xe6\x39\x16\x2e\x17\xec\x52\x8a\x8f\xf3\x9f\x11\xd3\xd4\xd1\x53\x19\xf5\x3c\xfe\xc2\xab\x56\xbf\xb6\xbd\xd8\x74\xc9\x8f\x0c\x9a\xee\x34\x4d\xe0\xae\x69\x2e\x70\xe4\x52\xbc\xc4\x54\xc9\x8f\x0c\x89\xee\x32\x45\xe0\xbe\xc9\x2f\xfb\x9e\x93\xe2\x2b\x9c\xa1\x2b\x71\xfe\xd3\x4d\xa7\x9b\x26\xed\x2c\x63\x83\x9a\xbc\xcc\x54\xc9\x6f\x4f\x24\xba\xd7\x14\x69\xc7\x19\x3b\xcd\xe6\x15\x16\x26\xb7\xa5\x54\x36\x61\x75\x56\xf2\xea\x4a\x7e\x98\xf6\x56\x6d\xa8\x9b\x4b\x5a\x5c\xa2\xec\x1e\x53\x66\x83\xcc\x59\xca\x16\xba\xc2\x54\x95\x12\x93\xa6\x89\xee\x37\x45\x8e\xb2\xa6\x12\x50\x5d\x6d\xaa\xe6\xc5\x35\x21\xd1\x43\x86\x48\xbd\x6c\x29\xa1\x37\xde\x35\xa6\x4b\xee\x5a\xd0\xf4\xb0\x69\x02\x77\x89\x7a\x07\x3c\xc9\x74\x25\xce\xfa\xba\xe9\x5c\xd3\xa4\x75\x08\x27\x45\x89\x5e\x65\xea\xe4\x2e\x91\x46\xf6\xa0\x29\x53\xef\xee\x50\x27\xbc\xd2\x74\xc9\x5d\x02\x9a\x1e\x30\x4d\x5a\x87\x70\x40\xa1\x0a\xd9\x92\xbb\x03\x12\x09\x99\xd2\x3a\x43\x39\x4d\x17\xbc\xc9\xf4\xc9\xed\x21\x95\xed\x49\xd3\xa6\xf5\x88\x32\x78\xcd\x9e\x6c\xaa\xe4\x1e\x81\x44\xe7\x19\x22\xf5\xfe\xaa\x9c\xa2\x54\x6f\x30\x75\x72\x9b\x48\x23\x7b\xdc\x94\x69\x9d\xa2\x0c\x6f\x16\xcc\x8c\x29\x77\x5a\x58\x25\xe4\x4c\x9b\x71\x16\xd2\xd4\xc5\x09\xa6\x4f\x9e\x73\x52\xd9\xce\x36\x6d\x5a\x27\x5b\x40\xbd\xda\x9c\xc0\x94\x0b\x2f\x68\x32\x27\xb0\xac\xd6\xc3\x5c\x70\x82\x3c\xde\x54\x25\x5e\x17\xa8\xa2\xb3\x4c\x91\xd6\xc1\x5c\xf4\xfe\x30\x5f\xda\x59\xb9\x85\x41\x93\xf9\xd6\xce\x6a\x5d\xc2\x45\x3d\xfa\x72\xd3\x25\xb7\x09\x68\xba\xcf\x30\xe5\xb4\x3e\xe1\xa6\xd8\xda\x27\x9a\x3a\x65\x9c\xf0\xc3\x8a\x53\xab\x91\x8b\x7f\xff\x30\xb4\x68\x1b\xf1\xd0\x34\x5b\xe7\x14\xd3\x27\x6f\xc4\x54\xb6\xf3\x4d\x9b\xb6\x11\x77\xc1\x9e\x73\xbd\x29\x93\x77\x22\x56\x3d\x66\xaa\xe4\x6b\x90\x5d\x81\x18\x7f\xac\x19\xaf\x7d\x7f\x52\x01\x67\x20\xf3\x58\x90\xb3\xc4\xa5\x20\x91\x79\x24\xc8\xcd\x25\xaf\x29\x21\x41\x66\x3f\xce\xd9\x49\xab\x4a\x50\x99\xcd\x38\x57\x02\xeb\xd2\x66\x1b\xb3\xed\xe5\x9c\xc4\x55\x69\x22\xb3\xed\x4d\x6b\x5f\x33\x55\x50\x5b\x3f\xce\x74\xc9\x97\x46\xd0\x74\xa6\x69\xd2\xbe\x3c\xf5\x40\x31\x5c\x6b\xaa\xe4\x9b\x23\x24\x7a\xc4\x14\x69\xbf\x0a\xf0\x60\x29\x08\xab\x92\xef\x3e\xb1\x4a\x58\x97\xf6\x8d\xaa\x07\x8a\xe1\x3a\x53\x25\x37\x03\x24\x7a\xd4\x14\xa9\xc7\x01\xaf\x2c\x19\x2e\x30\x0d\xca\x29\x40\x8e\xbf\xc8\x8c\xd7\x86\x7f\x1f\xbd\x84\x85\xb4\xc8\x83\x3f\x34\x99\x79\xc9\x83\x5f\x3c\xbc\xf8\x8b\x3b\xad\x2a\xcd\x19\x5b\xb9\xf3\x4d\xe9\x33\xc7\xec\xbc\xf6\x16\x0d\xc0\x86\x31\xef\x36\x95\x4b\x57\x24\x32\xaf\x36\xf3\xda\xbb\x33\x80\xdb\xc5\x6c\x52\x79\xf9\xdd\x89\x55\x66\x97\xca\x6b\x63\x6c\x00\x36\x8c\x79\xb6\xcc\xcb\x63\x2c\x12\x99\xc7\xca\xbc\xb6\xf3\x6a\x20\xed\xe6\x9b\x2f\x2f\x6f\x41\x24\x32\xdf\x7b\x79\x6d\x2f\xd6\xd2\xcc\x52\xb7\x9b\x3e\x79\x3f\xa6\xb2\x3d\x67\xda\xb4\x11\xbb\x06\x4b\xc2\xbc\x83\xca\xcb\x33\x36\x56\x99\x97\x50\x05\xad\x57\xd4\x40\x51\x98\x03\x76\x41\x6e\x12\x48\x64\xce\xd8\x05\xf5\xc7\x24\xf0\x03\x9a\x8f\xb1\x20\x1f\xc2\xb1\xca\x7c\x86\x05\xad\x6b\x85\xe0\x23\x9a\x57\x03\x05\xb9\x6b\x21\x91\x79\x31\x50\xd0\xba\x56\x88\xe6\x21\xf3\x2c\x52\x90\x9b\x16\x34\x99\xe7\x90\x02\xf8\xdd\x94\x7a\x62\xbe\xcd\x54\x25\x7e\xf5\xa9\x8a\x9e\x35\x45\x5a\xcf\xaa\xa3\x37\xac\x50\x54\x72\xd3\x82\x26\xa1\xa6\xb4\xae\x55\x07\xf7\x6a\x42\xa6\xe4\x86\x85\x44\x42\xa6\xb4\x5e\x55\x4f\xf3\x2b\x9f\x9b\x4d\x9f\xdc\xae\x52\xd9\x9e\x32\x6c\x45\xf4\xf3\x37\x30\x8d\xdc\x62\x1a\x13\xbf\xd1\x46\xbe\xa7\x4d\x9f\xd6\xbf\xea\xe8\x12\xc4\xcc\x5d\x51\x6e\x5f\xd0\x24\xe4\x4d\x3b\x43\xef\x05\xaf\x5a\xb3\x51\x14\xe5\x33\x34\x12\x99\x7d\xa2\xa8\x9d\xa1\xf7\xa6\xb8\xe2\x39\xcd\xd4\xc9\xa7\xe8\x34\x32\x73\xb6\x2f\x6a\xe7\xe8\xbd\xa0\x49\x9f\x6a\xaa\xe4\x73\x34\x12\x5d\xc8\x45\x59\xbb\x48\x3a\x7e\x8e\x81\x97\x66\x48\xdf\xf7\xc6\x2d\x4b\xb6\x34\x4b\xc9\x49\x32\x7e\xa5\x90\x2d\xcd\x51\x42\x11\x9e\x61\xf2\x25\x1a\xd9\x50\x09\xff\xa7\xab\xd1\xd3\xda\x7f\x03\x00\x00\xff\xff\x72\xcc\xde\x1a\xd2\x4d\x00\x00") + +func fontsBubbleFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBubbleFlf, + "fonts/bubble.flf", + ) +} + +func fontsBubbleFlf() (*asset, error) { + bytes, err := fontsBubbleFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/bubble.flf", size: 19922, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsBulbheadFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\x4d\x8f\xdb\x36\x13\xbe\xf3\x57\x3c\x30\x16\x88\x88\xd7\x5a\x6e\x92\x7d\x51\xb8\x08\x02\xb6\x40\x7b\xe8\xa9\x3f\x80\xe8\x84\xb6\x28\x5b\x8d\x2c\x05\x96\x8c\x6c\x0a\xfd\xf8\x82\x33\xa4\x2d\xab\xd9\x3d\xf5\xd0\xc3\x02\x4b\xad\xc9\xf9\x7e\xe6\x83\xac\xdb\xfa\x9d\xbf\xc3\x23\x1e\xb1\xd9\xe0\x01\x6f\x7f\x50\x3f\x9f\xdb\xed\x21\xf8\x0a\xdb\x6f\xf8\x2d\xd4\xf8\xbd\x1f\x3e\xfb\xee\xaf\x70\x5a\xe3\xdd\xfb\x3f\xcf\xdd\xe6\x51\xfd\xda\xec\xdb\x30\xe2\x14\xda\xe0\x87\x80\x77\xf7\x0f\x28\x4b\xfc\x74\xde\x9f\x87\x11\xff\x5f\xe3\xed\x66\xf3\x5e\x81\x88\x08\x98\x2f\xe4\x33\xf0\x92\xcd\x9c\xa4\x8a\x48\x70\x05\xa0\xf3\x02\xf2\x99\xa6\x22\x1e\x11\x91\x06\x0c\x91\xcb\x24\x05\x0d\xc2\x07\xe8\x82\x48\xe4\xa2\xc6\x74\x06\x8a\x5c\x9a\xa5\x4c\x64\x70\xcc\xa0\xa1\x55\x11\x4d\x1a\xfe\x46\xc1\xeb\xd7\x44\x7a\x31\x3b\xca\x8b\xc8\x28\xf5\xcb\xd3\x97\xd6\x77\x7e\x6c\xfa\x0e\x7d\x8d\xba\x39\x0d\x23\xda\xa6\x0b\x3f\xaa\x08\x27\x4a\xac\x8e\x7e\xdf\xec\xd0\x9d\x8f\xdb\x70\x5a\xa1\xee\x4f\xa8\x9b\x36\xa0\xa9\x42\x37\x36\x75\xb3\x63\x61\xe5\x63\xd8\x25\x86\x43\x7f\x6e\x2b\xf8\xf6\xab\xff\x36\x60\x1b\xf0\xc9\xbf\x59\xb3\x50\xd7\x7f\x55\x77\xc2\x34\x1e\x02\x56\x07\x7f\xaa\xb6\xad\xef\x3e\xaf\x22\xde\x5f\x4e\x4d\x37\x0e\xf0\x03\x3c\xf8\x74\x8d\xed\x79\xc4\xce\x77\x6f\xc6\xa8\x66\x38\x9e\x87\x43\xa8\xd4\xa3\x68\x38\x84\x66\x7f\x18\xa3\xc7\x1e\xbb\x83\x3f\xf9\xdd\x18\x4e\x2f\x12\xd7\xe8\xfa\x11\x4d\xb7\x6b\xcf\x55\xd3\xed\x51\x85\x61\x17\xba\x2a\x9c\x06\xb5\xd9\xb0\xd8\xd1\x3f\x71\xe4\x68\x43\xb7\x1f\x0f\x28\xc2\x53\x66\xde\xf5\xc7\x63\xe8\x04\x98\x41\xe3\x7f\xf0\xa8\xcf\xd5\x3e\xa0\xf6\xbb\xb1\x3f\xa9\x07\x31\x5c\x85\xda\x9f\xdb\x51\x9c\x3d\xf6\x55\xe0\xc0\xc7\x43\x33\xa0\xee\xbb\x11\x45\xdb\x7c\x0e\x58\x95\x47\x3c\xac\xd0\x77\xac\xd6\x77\x15\xab\xd5\xea\xed\x7b\x56\x22\x40\x47\xef\x6f\xac\x2a\x75\x77\x67\xe7\xcb\x2a\xe3\xac\xd2\x85\x55\xce\x58\x55\x68\x6b\xd5\x34\x59\x05\x5c\x96\x55\x98\x30\xc1\xaa\x72\x2a\xa7\xf2\xf2\x4f\x0e\xad\x02\x4d\x04\xab\x0c\x26\xd2\x56\x39\x9a\xe0\xac\x2a\x68\x22\xc3\x44\xae\xea\x78\xa0\x0d\x34\x2b\x34\x30\x51\x00\x05\xd7\x54\x64\x12\x16\x14\xc2\x60\x88\x3d\x21\x32\x2e\x7a\x67\x15\xd2\x9f\x70\x46\x0e\x68\xab\x0a\x14\xf1\xb7\x13\x15\x62\x04\x2e\x1e\x69\x26\x93\x11\x09\x58\xe5\x26\x63\x95\x99\x9c\x6c\xf9\x4b\x4c\x00\x4d\x60\xef\x0b\x6e\x3f\x1d\x49\x13\x4d\x89\x49\x56\xa1\x63\x70\x22\x25\x32\x24\x12\x24\xfc\xb8\xe1\x4e\x12\xc9\x86\x84\xab\xd9\x65\x03\x71\x2a\xc5\x41\x12\xb3\x89\xcd\xca\xae\x73\xff\x71\x40\x94\x5d\xa7\x14\x2d\x9f\xc7\x3e\x67\xd4\x52\xc0\x94\x70\x15\xf9\xa8\xc8\x24\xb7\xae\x0c\x42\xd7\x2c\x26\x69\x21\x49\x0b\xb2\xf9\x7b\xce\x6c\x0c\x5f\xa2\x89\x5e\x5c\xa5\x27\x70\x90\x13\x2d\xa5\x93\xef\x9a\x13\xcf\x44\x97\x89\xb7\x76\x17\x71\x27\x22\x98\xf8\x7d\xc9\xcb\x29\x60\xa4\x4a\x32\xbe\x85\x9e\xe1\x3b\xdb\xa8\x0b\x5c\x62\xd0\xaa\x0f\xf8\x20\xb5\xe1\xec\x3f\x12\x36\xdf\x59\x25\x38\x38\xc1\xf0\x23\x3e\x5a\x65\x92\xc1\x25\x7e\x46\xd0\xd7\x8b\xd4\xb8\x88\x52\xa1\x8d\x64\x2e\x57\x57\x2a\xaf\x34\x92\x23\xa7\x8c\x59\x56\xa8\x67\x39\x14\x38\x24\x64\x19\xcf\x29\x87\xe6\x52\x26\x92\x5c\x92\x92\x97\xbd\xa3\xb9\x86\x8b\x0a\x2e\xfe\x54\x47\xa2\x04\x37\x66\x12\x02\x3a\xce\xfd\x45\xa9\x3c\xc3\xa0\x67\xe5\x7a\xeb\x47\x79\x9f\x6b\x35\xb5\x1f\x44\x05\xdf\x48\x29\x96\x42\x1a\x1f\xc5\xad\x99\x5c\x6c\x11\x88\x1b\x3f\x32\x07\x32\xcb\x7d\xc9\x97\x97\xd4\x48\xae\xcc\x8b\x25\x93\x0c\x65\x3b\x79\x14\x08\xf8\x72\x51\x0a\x22\xb4\x08\x37\xe5\xaf\x00\x5c\xea\x2e\x1d\xfb\x58\xf4\x18\x67\xae\x43\x45\xd8\x5c\xf1\x9c\xa9\x59\x06\x85\x25\x5e\x91\xd9\xda\x33\x59\x66\xd0\x66\xe8\xbe\xac\xc5\x38\xf7\xfd\x5a\xe1\xfe\xb8\xf1\x45\xba\x47\xc6\xf0\x6d\xc7\x2e\xa1\x87\xc0\xca\xd3\x04\x4b\x4c\xf8\xbd\x90\x80\x9b\x05\xb3\xc4\x44\xe0\x77\xe0\x0e\x17\x24\x73\x29\x5c\x58\x9c\x59\xa2\x4b\xc6\x3d\xa3\x49\x5f\x13\xf0\xb2\xa9\x99\xd3\x97\xa8\xf2\xb0\x59\x66\x3a\x76\x27\xf2\x87\x28\x3b\x28\x77\x05\xb7\x92\xb4\x4d\xba\x47\xa4\xfc\x30\xa5\x0f\xd1\x64\x59\xaf\x74\xee\x1f\xd7\x89\x3f\x1b\xfc\xb3\xed\x72\xba\xb8\xdb\xcb\xeb\x75\x2e\xbc\xce\x85\xd7\xb9\xf0\x1f\x98\x0b\xeb\xd2\x2a\x8a\x0f\x1f\x7e\xfd\xe0\x53\x99\x9e\xc1\xf1\xe5\x1b\x97\x8b\xe0\x94\xf7\xcc\x40\x89\xab\x7c\x73\x79\x4f\x9a\xf8\x40\xcd\x6d\x6f\xaf\x3d\xae\xfe\xfd\xcd\xdf\x01\x00\x00\xff\xff\xd8\x64\xdc\x2f\x8d\x0e\x00\x00") + +func fontsBulbheadFlfBytes() ([]byte, error) { + return bindataRead( + _fontsBulbheadFlf, + "fonts/bulbhead.flf", + ) +} + +func fontsBulbheadFlf() (*asset, error) { + bytes, err := fontsBulbheadFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/bulbhead.flf", size: 3725, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCalgphy2Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x5c\xeb\x8f\xdc\xb6\x11\xff\xae\xbf\x62\x6c\x0a\x48\x53\x38\x47\x3b\x4e\x9c\xc6\x48\x82\x6d\x81\xba\x4d\xd1\x22\x05\x12\x34\x5f\xfa\x85\x27\x71\x77\x85\xd3\x4a\x6b\x3d\x7c\x39\xa0\xe8\xdf\x5e\x50\x7c\xcd\x90\xd4\xde\x3e\xb4\x57\xa7\xbd\x60\x1d\x72\x28\x51\xe4\x3c\x7f\x33\xd4\xee\xba\x5e\x7f\x2e\x72\xf8\xfc\x25\xbc\x7a\x03\xaf\xbf\x80\x97\xf0\xfa\x25\xbc\xcc\xfe\xd6\x96\xd5\xba\x92\x25\xdc\x3e\xc0\xdf\xc5\x58\xc3\x1f\xc6\x6e\x68\x1b\xf8\x51\xee\x07\xb9\xbb\x95\x1d\x7c\xfd\x06\xd6\x5d\xbb\x83\x42\xd4\xd5\xa6\x13\xfb\xed\xc3\xcd\xba\x5e\x83\xe8\x41\x40\x29\x77\x6d\xd3\x0f\x9d\x18\xaa\xb6\x81\x76\x0d\xd9\xbb\x6a\xf3\x73\xd5\xc0\x5a\x8a\x61\xec\x64\x7f\x03\xa0\x9f\x50\xe8\x4b\x86\xb6\xbd\x03\x71\xdb\x8e\x03\x7c\x09\xbb\xaa\x19\x07\xd9\xc3\xd8\x57\xcd\x06\xf4\x9d\x9f\xf4\xf0\xbc\x93\xc5\x20\x9a\x4d\x2d\x21\xeb\xa5\xe8\x8a\x2d\x88\xa6\x84\x4e\xee\x6b\x51\xc8\xe7\x76\xee\x1b\x80\x9f\xb6\x12\x8a\xad\xe8\x44\x31\xc8\xae\x87\x7d\x27\x3f\x54\xed\xd8\xd7\x0f\x50\xb4\x4d\x5f\xf5\x83\x2c\xd5\xa2\xda\xa6\x7e\x80\xe7\xbf\x7d\x0e\x99\xbf\x58\xdf\xdd\x4f\xf7\x37\x1b\xd9\x43\x27\xdf\x8f\x55\x27\x4b\x18\xee\x5b\xe8\x07\xb9\xef\xdf\x66\xd9\xbb\xaa\xeb\x87\x17\x20\xea\x1a\xaa\xa6\x1f\x44\x53\xc8\x5e\xcd\xa8\x26\xbb\x97\x9d\xb4\x8b\x2a\xe1\xbe\x1a\xb6\xf0\x9c\x3d\x87\xa1\x85\x4d\xf5\x41\xc2\xb0\x95\xb0\x6e\x9b\x41\x71\x49\x74\x77\xb2\x83\x4c\xec\xf7\x52\x74\x6a\x92\x1b\x80\x2c\x83\xb9\x3f\x96\x26\xf3\xec\xa7\xad\x6c\xe2\xd5\xbc\x55\x37\xc4\xab\x79\x0b\x1c\x00\x7e\xf3\x47\x51\x6c\xd5\x92\x87\x69\xb7\x95\x92\x5a\xe6\x19\xdc\xae\x61\xdd\x8e\x1d\xf4\xef\x47\xd1\xc9\xfe\x05\x54\x4d\x51\x8f\xa5\x92\x87\xe2\xc3\x6d\x2d\x9a\xbb\xfe\xe6\xd3\x2c\xfb\x7d\xdd\xb7\x20\xca\x52\x96\x20\x60\x2f\xbb\xaa\x2d\x5f\x80\xfc\xa5\xa8\xc5\x4e\x4b\x76\xdf\x56\x8d\x62\x55\x53\xc2\xfb\x51\xf6\x13\x6d\x27\xba\xbb\x89\xa2\x99\x5c\x4e\x4c\xc9\x4a\xb9\x16\x63\x3d\x40\xbf\x1b\xfb\xed\xae\x2d\xe5\x4d\x96\xfd\xd0\x55\x9b\xaa\x11\x75\xa8\x65\x45\xbb\xdb\xb7\xbd\x56\xcf\x7f\x54\x4d\x23\x1f\xe0\xa7\xad\xa8\xe0\x87\x62\x68\x27\xe5\xfc\x22\x83\xcf\x0e\xfd\x7d\xfb\xcd\x37\x46\xb3\xe0\xcf\x0f\x7b\x09\xdf\x7d\xf7\xed\xc1\xeb\x3f\xcb\xac\x5e\xb4\xbb\x9d\x6c\x86\x5e\x73\x76\x23\x1b\xd9\x09\xa5\x4f\x62\x1c\x5a\xb5\xe5\x42\xd4\xf5\x83\x5a\x96\x9e\xfd\x05\x34\xed\x30\xed\x4f\x8c\xc3\xb6\xed\x0c\xcb\xb3\x49\x07\x6e\xc0\xae\xa1\xea\xa7\x6b\x7e\xae\x9a\xb2\xbd\xef\xa1\xa8\xdb\x66\x12\xc2\xbb\xef\xff\x54\xcb\x41\x6b\x91\x80\xf5\x58\xd7\x56\xcd\x4b\xad\x45\xb2\xac\x86\xb6\x7b\x96\xc1\xbb\xb6\xdb\xc8\xc1\xd8\x50\xd9\x4e\x92\xda\x4a\xd8\x89\x61\xab\x74\x6f\x5d\x6d\xc6\x4e\x82\x1a\x54\x64\xc7\x63\x68\x46\x65\xcd\xcf\x00\xfe\x32\xf6\x03\x14\x5b\x59\xdc\x81\xc8\x60\x2d\xef\xe1\xb6\xfd\x45\xf6\xb0\x6e\x3b\x90\x4a\x59\xa6\x7b\xd4\xbc\xdd\x58\x2b\x4d\x25\x4f\x94\x4d\xa9\xa4\xda\x3f\x03\xf8\xab\xd4\xcf\x50\x32\x1a\x07\xd9\x65\xf8\xe1\xdb\xf6\x1e\x06\xa5\xa9\x4a\xfc\xaa\x73\x5f\x95\x12\x1e\x94\xae\x4d\xfb\xa9\x94\x05\x4e\x4b\x29\x3b\x71\x3f\xd1\x7a\xbd\xfd\x69\x37\xed\xd8\xcb\x6c\xba\xf7\xbe\xda\x4b\xbb\x95\x72\x23\xa7\x87\x43\xbb\x5e\xeb\xb9\xfa\xa2\x93\xb2\xd1\x0e\x4a\x3d\x6d\xd8\x8a\x01\x8a\x76\x6c\x86\xaa\xd9\x3c\xcb\x32\xc4\xf7\x89\xa9\x4a\xdf\x8d\x6b\x7a\x01\xb7\xe3\x00\xd5\xf0\x49\x0f\xa5\xec\xab\x4d\x33\xb1\xba\x83\xb1\x97\x4a\xac\x62\xda\x57\x2d\x07\x09\x55\x59\xb5\x4a\x86\xdf\xaf\x33\xf5\x54\x78\x3f\x8a\xba\x5a\x3f\xbc\x80\x0f\x55\x5f\x69\x1e\x98\xc7\xdc\xcb\xdb\xbe\x1a\x14\xd3\x7e\xd4\x0b\xeb\xb7\xed\xd0\x83\xe8\xa4\x6a\xdd\x37\xda\x3e\x5a\xa5\xd7\x63\xa7\x76\xa8\xa6\xbb\xaf\xea\x1a\x6e\x25\x88\xdb\x5a\x2a\x11\x96\xed\x7d\x53\xb7\xa2\x84\x6a\xb8\x99\xf3\x12\xdb\x61\xd8\xbf\xe5\x7c\xdb\xee\xe4\x8d\x14\xdd\xb0\xad\xab\xe6\xee\xa6\x91\x03\xff\x77\xdf\xd6\xa3\xb2\xbe\x2c\xcb\x21\x5f\x5d\xf9\x9f\x95\x5f\xdf\x2a\xcb\x19\x63\xb9\x69\x82\x69\xab\x26\x2c\xdc\x64\xc0\xa7\xc7\xab\x36\xcf\x35\xd5\xad\x41\x51\xf1\xb5\x79\x40\x45\xeb\x7d\xac\xa9\xda\x8f\x7f\xca\x7c\x95\xb5\xf9\x2a\x1b\xf3\x55\x76\x9b\xaf\xb2\x3a\x5f\x65\x32\x5f\x65\xef\x0d\x4d\x8d\x0d\x9a\x76\xdc\x84\x73\x9f\x3d\x7a\x50\x93\x4f\x0f\x3e\x7f\x32\xbb\xea\xda\x7c\x44\xbe\xca\xba\x73\x27\xdc\x9b\x2d\x77\xf9\x2a\x2b\x4c\xbb\xd1\xdb\x3e\x6d\x22\xb5\x8a\x5d\x4e\x27\xec\xcd\xea\x4e\xda\xb2\xba\xa9\x32\x37\x6d\xce\x15\x4a\x8b\x56\xd2\x98\xb6\xe1\x13\xde\x62\xb6\x35\x7d\xf5\xd0\x87\xb9\x09\x0b\xb3\x8a\xd6\x5c\x28\x2f\x9d\xf0\x31\x3e\xf6\x7e\x8b\xd3\x03\x2a\x4f\xbb\x4c\x0f\xad\xc4\x6b\xc3\xcb\xfe\xd2\x09\x0b\xc3\x96\x9d\xf9\x88\x4b\x27\xdc\x21\xe9\xa3\x15\x7a\xf3\x5e\xfa\x7f\x39\xcb\xad\xff\x73\xbd\x03\x37\x5c\xb6\xbb\x1e\x99\x6c\xaf\xb5\xe5\xbc\x89\x2c\x7b\x76\xc6\x73\x59\x4d\x79\xb9\xf4\x84\xaf\x96\x9e\xf0\xf3\xa5\x27\x7c\xbd\xf4\x84\x5f\x2c\x3d\xe1\x97\x4b\x4f\xf8\x66\xe9\x09\xbf\x5a\x7a\xc2\xdf\x2d\x3d\xe1\xd7\x4b\x79\x2a\xeb\xc8\x9b\x53\x27\xb4\x9e\xdf\x7a\xa8\x8b\x27\xc4\x9f\x1a\x85\x8d\xde\x6f\xfb\xb2\x2d\xe3\xa8\x29\xf4\x4a\xcf\x9b\x68\x83\x02\x9d\xa0\xb1\x69\x45\x50\xae\xea\x31\xfd\x37\x81\xb7\x29\x8f\x05\x0d\xe6\x56\x19\x77\x59\xb2\xea\x31\x9b\x2b\x7b\x97\xab\x32\x65\x7d\x9f\xef\xb8\x1e\xcf\x91\x1f\xd6\x1d\xd3\x33\x1d\xd3\x63\xa4\x07\x0e\xd7\x6a\x6a\x4e\xc6\x70\x8f\xd1\x2b\xc9\x58\x02\x62\x3e\xd6\xbb\x4c\x74\xf8\x23\x7c\xe4\x0f\xff\x3c\x8d\xd9\x6d\x3b\x0e\x31\x16\xd2\xb8\xdf\x24\xbe\x97\xc7\x34\x8e\x26\x3c\x40\xe3\xf8\xc9\xf3\x34\x0e\xb1\x24\x38\xf3\x7a\x62\x68\x9c\xee\x65\xa2\xb1\x98\x36\xdd\x89\x88\x46\xcb\x2c\xd5\xa4\x18\xdc\x5c\x60\x2e\x9c\x72\x0d\xb7\x4d\xcc\x3f\x16\x52\x0f\xf3\x19\xd1\x62\xa2\x53\x39\xb5\x16\xbb\x38\x63\x10\x96\xcf\x6a\xb9\x4c\xef\x96\xdb\x6b\x38\x58\x82\xbf\xcb\x12\x90\x11\x4c\x93\x12\x43\xd0\x14\x6c\x0c\x13\x85\x18\x84\xbe\x86\x61\xa6\xea\x79\x34\xcd\xb2\xd9\xb0\x4a\xc3\x20\xa0\x62\x33\x6c\xb7\x3c\xd5\x77\x71\x67\xea\x66\x66\x37\xec\x84\x9f\x60\x6d\xc0\xee\x59\x1e\x1e\x64\xb4\x25\xd0\x6d\x4d\x0c\xd3\x9c\xce\xad\x42\xe9\x45\x72\xbd\x4d\x0e\x76\xdf\x4e\x6d\x88\x3d\xf8\xc1\x05\x09\xd3\x23\xa9\x85\x29\xfe\x1b\x16\x5b\xfe\x1b\xee\x7b\xef\xa7\x19\x4b\x1c\x20\x63\x49\x9f\x74\x26\xe1\x90\x9a\x23\x05\x36\xa6\x49\x54\x78\xe2\x9d\xd7\x59\x86\xb5\xd8\x6a\xad\xd7\x2d\x47\xb2\x61\x00\x90\x0a\x62\x8d\x5b\x9c\x06\x31\x0d\xb9\x19\xab\x14\xcc\x2a\xb6\x63\x3f\x07\xaf\xda\x1c\xeb\xf6\x61\xed\x5e\xdc\x9d\x24\xfc\x49\xe8\x50\xb4\xb3\x23\x1e\x45\x6b\x3b\x27\xb2\x20\x3e\x25\x27\xd3\xbb\x99\x1f\x27\x51\x77\x6d\x49\xa1\xf3\x09\x6e\x84\x88\x04\x78\x0d\x40\x7c\x8b\x1e\xa3\xce\x05\x6f\x88\x2e\x22\x12\x40\x82\xff\xf3\x5c\xbd\x02\xf3\x21\xc1\x7c\xf8\xe8\x98\xcf\x22\xe6\x33\x4a\xb2\xcc\xf7\x3e\xcb\x04\x75\x3c\xd7\x93\x30\xdf\x7b\xf8\x84\x8f\xf7\xb0\xc1\x79\x79\x88\xfd\x7c\xc2\xd3\x27\xfc\x34\x22\xf9\x9d\x22\x92\x8f\x2b\x96\x84\x22\x8b\x21\x79\xe4\xe3\xbc\xbe\xe7\x77\xe4\xf7\x21\xf6\xfc\x09\xdf\x9f\xf0\xfe\x47\xb3\xf5\x6c\xe6\x87\xca\x4f\xe0\x97\xd3\x7f\x03\xb9\x42\x13\x00\x96\x72\x41\x4a\x90\x34\x50\x7b\xd6\x04\xa8\xe4\x68\x2a\x4b\x5a\xc0\xa1\x19\xb0\x01\x41\x8a\x8a\xc2\x03\x01\x9c\x31\x34\xe5\x88\x39\x40\x70\x5c\x60\x05\xa9\x38\x91\x8e\x14\xe9\xb8\x30\x4b\x3d\x28\x5f\xb3\x36\x17\xf6\x9c\xd4\xbc\x33\x62\xc8\x23\x79\xfc\xcd\x83\x44\x0b\x7b\x2d\xaf\x8a\x21\xe8\x8f\x49\x9c\x85\xa4\x29\x36\x3d\x72\xa3\x35\x2e\x14\x64\x35\x89\x24\x79\x86\xed\x9c\x62\x2a\x6f\x32\xd8\x90\xf2\x43\x6c\xbc\x92\xd5\xa4\x10\x54\x2a\x70\x60\x29\x20\x98\x0a\x33\xb1\x3b\x19\x41\xd2\x8e\x7f\x86\x4a\x84\x92\x96\xcb\x59\xf3\x9e\x48\x8d\x42\x10\xf1\x81\x96\x6a\xac\x0b\x11\xad\xdd\x01\xe3\xd4\xc2\x48\xce\x49\x9f\x16\x46\xa4\xb4\xe0\x20\x10\x53\x1c\xc6\x58\x82\x0e\x10\xb8\x3e\x88\x62\x26\xf2\x89\x41\xcd\xc2\x7a\x1a\x9e\x4c\xd7\xc0\x65\x87\xf1\x48\xb0\x79\xef\x0e\x79\xcc\x00\x92\xfc\x25\x46\x52\x36\xe2\x5c\x23\x4b\x21\x37\xd3\x67\xa4\x16\x40\x00\x1c\x76\xca\xd4\x4d\x9a\x70\xe7\xf2\x73\x34\x00\x0e\x3c\xa5\xdc\x25\xcc\xba\x4c\x98\x75\x90\x8f\x8c\x24\x87\x48\xd8\xc3\x62\xc1\xfe\xd3\xed\x8d\xc5\x16\x49\x7d\x28\x9a\x93\x47\x9a\x1c\x9a\xc7\x35\x89\x90\x20\xa6\x34\x89\xc8\x31\x05\xc5\x13\x60\xdc\x83\xa5\x58\x38\x49\x99\x1d\xe2\x7c\x40\x3c\xce\x5a\xc1\x2b\x6c\x5c\x72\x41\x48\x39\xc4\xea\x7e\x2c\xb0\x56\x8d\xde\xc0\xa7\xb0\x1e\xc5\x80\xf3\x29\xd4\x5a\x9f\x78\x84\x54\xc8\x66\x46\x9c\xb5\x06\xd5\x32\x24\xe5\xb8\x8e\x46\xac\xd5\x0c\xa5\x81\x0d\xcc\x82\x1b\x78\x22\x6b\x85\x50\x0f\x42\x16\x78\x35\x00\x48\xc3\x55\xe7\xe8\x42\xc4\x6a\x79\x1a\x95\xe3\x8c\xd7\x4c\x89\x66\x6e\x40\xab\xd3\x49\x03\x53\xf3\x98\x01\x17\x3c\x21\x2c\x60\xe3\x7a\xaa\x1f\xa0\x16\x1e\x66\x48\x71\xe4\x9b\x91\xfc\xac\xe0\x67\xe5\xfe\x98\x04\x13\x03\xd1\x48\x94\x15\x92\x9c\x10\x03\x59\x97\xf0\xd1\x7c\x10\x57\x2e\x2d\x67\x70\xe2\x07\xb0\x18\x81\x64\x80\x1a\x87\x7f\xb4\x75\xbf\x13\x90\x6b\x9c\x3f\x00\xaa\xf5\xd1\x94\x2f\xa8\xba\xd1\x7a\x32\x84\x6a\x7d\x90\x6a\x90\x2b\xe5\x9e\x45\xae\x01\x0b\xc1\xa7\x87\x01\x1f\xa3\x32\xca\xa5\x78\x36\xcc\x57\xd2\x29\x4b\x3a\x6b\x49\x27\x2e\xe9\xdc\xe5\x7f\xc6\x1a\x8c\x6e\x21\x6b\x60\xe8\x14\xc2\x8a\x12\x95\x75\x27\xee\x50\xed\x60\x54\x5d\x22\xfd\xa1\x4a\x82\xfa\x84\xa0\x55\x23\xb6\x06\x0a\x01\xed\xda\x7c\xd5\xc3\x72\x8d\x91\x23\x9b\xb8\xe0\x4a\x83\x86\x7b\x3a\x01\xf1\x98\x12\x9e\xea\xb0\xe8\x54\x07\x0b\x11\x47\x9d\xf0\x0c\x07\x55\xde\xc1\xbb\xef\x20\xf0\x6b\x7e\xd9\x22\x0e\x0d\xf4\xa8\x88\x72\xbd\x33\x1c\xe2\xdf\x58\xa8\xc1\x6e\x91\xc8\xaf\x00\xdd\xae\xcf\x29\xf2\xa4\xcd\x20\x56\xd2\xc2\x19\x63\x51\x55\x91\x10\x89\x2f\xf4\x2a\xe0\x88\x1c\x29\xa8\xa7\xc5\x1a\x89\x4e\x18\x2c\x8d\x53\x9c\x15\x9e\x2f\x90\x82\xd6\xbf\x12\xb8\xf9\x9f\x9f\xc6\x99\xe9\x0c\x57\x31\x69\x16\x71\x73\x0a\xf6\x4e\xc4\xfb\xfa\x1e\x9c\x63\x1b\x43\xe7\x90\xa8\x3d\x40\x9c\x4f\x86\x45\xd8\x25\x88\xc0\x92\x55\x6f\x5a\x7b\xa5\xce\x24\x78\xd1\x80\xd4\x5f\x11\xeb\x68\xca\x7b\x0c\xe3\x97\xc8\x75\xa8\x3f\x02\x8c\xe3\xbd\x53\x9a\x49\x71\x9c\x4a\x79\xf7\x64\x6d\x9b\xfa\x28\xc6\x52\x19\x07\xc0\xd3\x92\x21\x2c\x9a\xc7\xc2\x0b\x63\x37\xae\xa7\x87\x02\x0c\x2b\xe8\x2e\xd8\x1c\x90\xc2\x52\xe4\xe3\xf2\x15\xfc\x62\x44\x20\xd0\x03\x22\x9d\x15\x2a\x0a\x4f\x54\xac\xe1\x1b\x02\xfe\x0e\x36\x37\x30\x77\x47\x58\xab\x0a\x04\xf6\xd8\x1d\x48\xc4\x3c\x0f\x59\x02\x74\xa6\xb4\x95\xc2\x9c\xa5\xc2\x9c\xb5\xc2\x79\xd9\xc7\x02\xf9\x4a\xea\x3e\x62\xc8\x7e\x9d\x29\x7b\xf6\xdb\x48\x9b\xb5\x0f\x91\x09\xeb\xb6\x5c\xc8\x63\x23\x77\x4b\xb2\xa3\x44\x8e\x1f\xcd\x28\x71\x07\xf1\x28\xf6\x0a\x6e\x14\xa1\x3e\xaf\xfc\x2c\xe1\xf9\x9d\x8f\x00\x96\x48\x15\xc0\xe3\x22\x60\xf3\xf9\x17\xf9\xbb\xe2\xe8\xdc\xb0\x51\x1a\x4f\x40\xf9\x3c\xaa\xe3\x30\x5b\xba\xd4\x8a\x82\x19\xa3\xf7\xed\x55\x13\x00\x1d\x3b\x50\x56\x46\x25\x4d\x3d\x10\x55\x35\xed\x40\x92\xce\xd3\x47\x32\x29\x70\x00\x28\x8d\xa4\x74\x1e\x3e\x83\xc2\xc6\x00\xdc\x91\x72\x07\xb3\x28\x07\x93\x01\x1c\xd0\xa1\x64\xc0\x88\x3b\xf1\xb7\x18\xfd\xb1\x1b\x52\xd1\x7f\x26\xfc\xcf\xc4\x7f\x38\x00\x00\x66\x10\xc0\xc1\x30\x7d\x4d\xfa\x2c\x0e\x98\x05\x02\x5e\xa7\x03\x3a\xc5\xac\x14\xc7\x27\x21\x3f\x1a\x0d\x6a\x32\xde\x1d\xf8\x17\x87\x98\x1f\xe2\x8c\xbc\xf1\x6a\xaf\x35\xc8\x64\x69\x04\x6e\x72\x33\x32\x9d\xf5\x60\x78\xc2\x08\xc4\x42\x74\x9a\x8b\x69\x84\x18\x87\xdb\xd4\xe9\x63\xda\x31\xa4\xbc\xc2\x52\xa7\x0d\xb3\x16\xb9\x04\x02\x7f\xfc\x63\x5f\xd5\x5e\x9b\x17\xa1\x6f\xcd\xcb\xd1\xc2\xbc\x13\x7e\x67\xc6\x4f\xfe\xb2\xce\x6d\x30\xc9\x59\x5f\x16\xb1\x5f\x17\xda\x98\xef\x22\x2d\xba\xc2\xf0\x53\x04\x5f\x82\x3a\x69\x42\xf4\x5d\x38\xf2\x85\x31\xfb\x5e\x7d\x77\xce\x17\xef\x42\xe1\xcc\x7c\x69\x2c\xad\x08\x67\x77\x70\xbd\x8d\x83\x7f\x05\x95\x3b\x1f\x60\x5f\x77\xb7\x86\x7b\x4a\xc7\x7a\x16\x0b\x57\x72\x14\xf7\xc3\xaa\xc3\xb1\x9d\x68\x08\x19\x3b\xc1\xd3\x41\x65\x73\xbe\x83\x98\x60\x50\x15\x79\x5f\x6a\x51\x26\x38\xa7\x96\x86\x66\x67\x33\xe1\xf2\xce\x71\x9a\x70\x0e\x7f\x5d\x0a\x64\x98\xe0\x91\x1b\x2a\xc9\x2c\xc4\x84\x10\xfd\xe5\x27\x75\xf0\xcb\xef\xde\x67\x7b\x4d\x60\x1f\xb7\x26\x5c\xdc\xe6\x81\x0a\x90\x97\x8a\xf1\xde\x35\x53\x6c\x4c\x73\xed\x9c\x4a\x5f\xd3\xc1\x06\x48\x14\x17\x29\xee\x3b\x69\x9d\xa8\x83\xd6\xac\xa6\xe7\x64\x95\x76\x91\xb9\x5f\x4b\x8e\x97\xe5\x56\x8b\x8c\x3f\x7d\xed\x59\xcd\xe8\x75\xb1\xa3\x9a\xab\x20\xba\x5f\xa7\xcf\xa3\x34\xc3\xa7\x59\x3e\x75\xe1\xfe\x75\x50\x6c\x58\x97\xf6\x01\xc3\xda\x95\x45\xa9\x71\xba\x42\x0e\x57\xbc\x40\x2d\x78\xd5\xd6\x84\x10\x56\x7c\x2a\x82\x83\x03\x8e\x0d\xa1\x8a\xce\xb5\xbd\x6e\x4d\x19\x8c\x53\x2e\x8e\xb4\xcb\xee\xed\xb2\xb6\x3f\xfe\x58\x21\x18\xba\x42\xe8\xd3\xb4\x51\xaa\x1f\xc1\x73\xda\x72\x59\x03\xae\xd2\xe4\xe1\x75\x28\xbb\x20\xd5\x9c\x4b\x5a\xee\x15\x41\xff\x5a\x60\x62\x7d\x51\xcb\x35\x49\xc3\x6b\x91\xf3\xd1\x39\xbd\x86\xb1\xc4\x35\x2e\xa3\x34\x43\xd6\xdb\xa6\x2f\x46\x8a\xe6\xea\x37\x61\xc3\x9d\xdc\x92\x99\xaf\x00\x46\xbc\x13\xf6\x5a\xe7\xd4\x8e\xbb\x11\x40\x7b\x42\x89\x51\xf8\x06\x2a\xfa\xca\x81\x3b\x85\x43\x1e\xd2\x3a\xe6\x58\x5a\x67\x85\xa0\xeb\x28\xd4\xd3\xab\xe0\xcc\x4e\xaf\x41\x32\x07\x75\x18\x84\x82\x41\xa1\x5c\xd7\xff\xb8\x3d\x73\x06\x5b\xf4\x73\x21\xd4\x57\x22\x9c\x2e\x2f\x49\x62\xfe\x1f\x7c\xce\xed\x68\x8b\x72\x22\xa0\x2d\xda\xc5\xef\x80\x18\xd5\xd4\xd5\x53\xc4\xdc\x90\xb1\x01\x6f\xce\xee\xb2\x30\x96\x41\x92\x79\xa7\x75\xcf\xb2\xd3\xff\x66\x26\x48\x51\x35\x86\x02\x71\x99\xe7\x74\xbf\xf3\xeb\x62\x02\xc1\x3f\x81\x8f\x3e\x2a\x4a\xa0\x43\xe2\x5f\x2d\x13\x80\x56\xc4\xa2\xf2\xd8\x91\x1d\x5d\x54\xf8\xa8\x7c\x07\xa9\x33\x5e\xd6\x65\xa4\x8e\x39\x7b\x8a\xff\xf1\xf9\x0e\x04\x2c\xbc\xc6\x90\xe5\x07\x59\x6f\x50\x07\x70\x6f\x78\x99\x58\xa3\x91\x3e\xb3\xef\xb6\x5b\x76\x84\x27\x5f\xe7\xf9\x8e\xc3\x6d\xe4\xa0\x58\xb2\x4d\xea\x04\x3e\x25\x9e\xbd\xfe\xb2\x76\x50\xe1\x78\x7c\xfd\x89\x0d\x47\xec\x58\xa4\x8f\x8a\x24\x96\x31\x60\x23\x9e\x87\x99\xc8\x56\x98\x3f\xe9\x85\x4b\xfa\x9c\x3a\x11\x0e\x24\x73\x4c\xd5\x1a\xcf\xd9\xdf\xa5\x5e\x24\x3f\xd0\xf5\xac\x0a\x50\x04\xc3\x80\xc4\xc1\x06\xc4\x88\xb3\xbb\x1c\xb3\x88\x05\x6f\xf1\x46\x66\x75\x91\x8f\x39\x70\xe1\x65\x03\x84\x8b\x47\x0d\x60\x9d\x0c\xe0\x07\x19\x41\x5a\x0b\x98\x92\x80\x89\x10\xe9\xe5\x35\x06\xb8\x17\x1b\x10\xc1\x21\x01\x12\x11\x62\x51\x2e\xcc\xf6\xb9\x81\x68\xe4\x5a\x04\x8e\xcd\xc5\x46\x06\x70\xe1\xc1\xb2\x47\xff\x40\x02\xd2\x6c\x1e\x78\x4f\x1e\x04\x54\x0e\xf1\xf9\x3b\x56\x11\xf4\x2b\x22\x7a\x1d\x66\x49\x8c\xfc\x72\x0b\x24\x93\xe9\x73\x77\xfb\x54\x4c\xa5\xde\x3b\x72\xdf\x10\xfa\xef\xc8\x21\x2f\x45\x00\x96\x2c\x10\x26\x2a\x84\x41\x89\x30\xae\x11\x06\x45\xc2\x74\x95\x70\x19\x08\x84\xf1\x2b\x47\x28\x00\xbd\x27\xe7\xee\xc1\x2f\xf3\x60\x04\x13\x02\x60\x7c\x0f\xcd\x18\xe7\x3b\xfc\x88\xe7\xa0\xca\xe1\xea\xe0\x11\x64\x61\x8e\x20\x3b\x73\x9c\xfb\x70\xcd\x13\x59\x30\x3f\xf0\x58\xf9\xdf\xbf\x5c\x3d\x7a\x3e\x5c\x98\xd5\x8c\x4f\xb1\xc2\xc1\x2c\xa0\xf4\x3f\xed\xb9\xca\x8e\xfc\xef\xff\xf5\xc2\x57\x6f\x5e\x3e\xcd\x2f\x02\xbf\xfa\xea\xf5\x45\xc2\x4d\xfe\x7a\xe7\x7f\x02\x00\x00\xff\xff\xda\x71\xad\x47\xbf\x5e\x00\x00") + +func fontsCalgphy2FlfBytes() ([]byte, error) { + return bindataRead( + _fontsCalgphy2Flf, + "fonts/calgphy2.flf", + ) +} + +func fontsCalgphy2Flf() (*asset, error) { + bytes, err := fontsCalgphy2FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/calgphy2.flf", size: 24255, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCaligraphyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5c\x4b\x6f\xe3\xc8\x11\xbe\xf3\x57\x14\x0c\x02\xbb\xdb\xb1\x8d\xb1\x67\x36\xc9\x2c\x16\x0b\x5e\x72\xd9\xcb\x02\x41\x90\x73\x68\x89\xb2\x98\x91\x48\x47\xa4\xb0\xe3\x7f\x1f\x48\xec\xc7\x57\xd5\x45\x3d\xf8\xf0\xac\x83\x08\xa3\x31\xbb\xaa\xbb\xd8\x5d\x55\x5d\x2f\x36\xb5\xda\xac\x1e\xf3\x94\x1e\x1f\xe8\xe1\x33\x7d\xfc\x40\x77\x0f\xf4\xf0\x29\x59\xe4\x9b\xf2\x79\x97\xbf\xac\x5f\xef\x57\x9b\x15\x2d\xea\xed\x4b\xdd\x14\x4b\xa2\xa7\x57\xfa\x67\x59\x55\xc5\x2b\xfd\x63\x9d\x97\xf4\x73\xd3\xac\xca\xb2\xcd\x8a\x5d\xd9\xdc\x2f\x16\xf7\xfb\xed\xd3\x7d\xb1\xdc\xff\x02\x04\x68\x55\x57\x2d\x7d\xff\xeb\x2d\xfd\x76\x4b\x7f\xff\x21\xd0\x7a\x7a\xa5\x5f\xeb\x5d\x45\x3f\xff\xbb\xde\x55\x59\x55\x2f\x8b\xfb\xa6\x6c\x8b\xfb\x45\xde\xfe\x92\x2c\xf3\xb6\xf8\x89\x7e\x5b\xb4\xf4\xf8\xf1\x96\x1e\x3e\x7f\xfe\x94\x24\x7f\xfb\xfa\xb2\xc9\xab\xbc\x2d\xeb\x8a\xea\x15\xad\xca\x5d\xd3\xd2\xa6\xac\x8a\x9f\x92\xc3\x2a\xe8\x8e\x6e\xb6\xf9\x73\xb9\xa0\x6a\xbf\x7d\x2a\x76\x37\xb4\xaa\x77\xb4\x2a\x37\x05\x95\xcb\xa2\x6a\xcb\x55\xb9\x38\x0e\x4e\x72\x22\xa2\x3b\x6a\xd6\xf5\x7e\xb3\xa4\x7c\xf3\x7b\xfe\xda\xd0\x53\x41\xff\xca\xbf\xbb\x3d\x0e\xaa\xea\xdf\x93\xb4\xeb\xd4\xae\x0b\xba\x59\xe7\xbb\xe5\xd3\x26\xaf\xbe\xdc\xd0\xdd\x1d\xbd\xec\xca\xaa\x6d\x28\x6f\x28\xa7\x23\xf4\x96\x9e\xf6\x2d\x2d\xf2\xea\xbb\xf6\x40\xa6\xd9\xee\x9b\x75\xb1\x4c\x1e\x1f\x8e\x14\xd6\x45\xf9\xbc\x6e\x0f\x33\xce\x69\xb1\xce\x77\xf9\xa2\x2d\x76\xc9\xc3\xe7\x7e\xe4\x2d\x55\x75\x4b\x65\xb5\xd8\xec\x97\x65\xf5\x4c\xcb\xa2\x59\x14\xd5\xb2\xd8\x35\xc9\xe3\x87\xe3\xb0\x6d\xfe\xf5\xb8\x72\xda\x14\xd5\x73\xbb\xa6\xef\x8b\xaf\xae\xf3\xa2\xde\x6e\x8b\xaa\x63\x4c\xf3\x03\xfd\x89\x72\x5a\xed\x97\xcf\x05\xad\xf2\x45\x5b\xef\x92\xbb\x6e\x56\xcb\x62\x95\xef\x37\x6d\x37\xd9\x6d\xbd\x2c\x8e\x0b\x6f\xd7\x65\x63\x05\xb6\x29\xbf\x14\x74\x73\xb7\xa5\x0f\x37\x54\x57\x47\xb2\x79\xb5\x3c\x92\xfd\x21\x79\xf8\xf1\x48\xa4\x63\xf4\x61\xf6\xec\xae\x49\x92\x52\x9a\xbd\xc5\x7f\x59\x42\x74\xfe\x5b\xa4\x59\xf2\x35\xcd\x92\x45\x9a\x25\x9b\x34\x4b\xf2\x34\x4b\xb6\xf6\x6f\x9b\x66\x49\x99\x66\x49\x9d\x66\x49\x95\x1e\xfb\x5f\x46\x74\x69\x07\xed\xd3\x2c\x79\xb2\x84\x0f\x37\xfa\x8f\x85\xd5\x96\x78\x71\x0d\xd1\xbe\xef\x0b\xdc\xec\x30\xcb\xe5\x58\xa2\x6e\xf6\x1b\x60\xc9\x6e\x0c\xd1\x17\xbb\xd4\x9d\xe5\x73\x61\x67\xda\x0e\x21\xea\x04\x84\x44\x1b\x3b\xcb\xab\x97\xdf\x58\x09\x1f\x06\x3e\x8f\x11\x54\x0d\x33\xaa\xec\xb5\xe3\x1b\x2e\x77\x6d\xdb\x87\x1b\xbf\x9e\x22\xea\xf4\xb1\xb6\x9d\x8b\x29\x88\x9e\xe3\x6b\x03\xcb\xdd\x59\xd6\x34\x43\x05\xd5\xa7\x09\x1b\xcb\xdb\x66\x0a\xa2\x0b\xcb\xa2\x2d\x6c\xdb\xd1\x44\xb7\xa0\x15\x93\xcc\xf4\x45\xf0\xb4\x9e\x62\x9b\x3a\xfd\x75\x5b\xb4\xb1\x9a\x30\x98\xa8\x5b\xee\xd6\x5a\x2d\x37\xe3\x0f\x73\x10\x7d\x98\x83\xe8\xe3\x1c\x44\x3f\xce\x41\xf4\xd3\x1c\x44\x7f\x9c\x83\xe8\x9f\xe7\x20\xfa\x97\x39\x88\xfe\x75\x0e\xa2\x9f\xa7\xb4\x52\x9b\x21\xc1\x84\xfb\x3a\x2f\xe0\xac\xd3\x24\x44\xf1\xbb\x01\x37\xd2\x00\x0b\x46\x2f\x1f\x3d\x6a\x6e\x67\x3c\x98\xe8\x33\x38\xc0\x5c\xf8\xab\x41\x44\xdd\xcc\x0a\x70\x76\x83\xa2\xbe\x4b\xbe\x39\xf7\xa6\xf2\x13\x60\xc6\xa4\x1c\x66\x0e\x1f\x0e\x33\x47\x68\x2a\xc7\x2a\x30\x03\x04\x4f\xc0\x0c\xde\xb9\x1f\x66\xd8\x14\x2d\xcc\x7d\x02\xcc\xf0\xb5\xf4\xc1\x8e\xa3\x00\x98\x25\xc7\x5e\x0e\x6a\x0c\x99\x34\x4b\x8c\xed\x10\x3a\x66\x89\x5f\x26\xf2\xcf\x48\xe8\x69\x3e\x9f\x81\xc5\x40\x14\x87\x9f\xb0\x5d\xbe\xe3\xfd\x71\x1a\x96\xc5\xae\x8f\x71\x3c\x0f\xcb\xf4\x00\x02\x06\x99\xe3\x50\x64\xa3\xe9\x78\x40\x1c\xc2\x44\x67\xfb\x98\x88\x4e\x07\x73\xac\x37\x8e\x8b\x29\x28\x01\x40\xbc\x24\xdc\x28\x13\x04\xdb\x51\xf6\x68\x3f\x1f\x85\xdd\x42\x04\xbd\x3c\x3c\x0d\x89\x40\x61\xce\xb8\x50\x37\x47\x22\xbb\x2a\xe3\x41\xdd\xc2\xdd\xba\x41\xb9\xd8\x0e\x09\xc8\x09\x01\x9d\x10\xd9\x3e\x3c\x48\xc4\x2e\xc0\x49\xc4\x71\x3b\x15\xbb\x28\xc5\xd5\x8a\xfd\x78\x82\x67\x43\x00\xa7\x76\x02\xe8\xb8\x9f\x30\x68\xb9\x57\x73\xa7\xe7\xa0\xe8\x5e\xb1\xbd\xfa\x79\x50\x07\x74\xeb\xc5\x2d\x3d\x13\x8c\x62\x18\x58\x22\xa7\x25\xc1\x0a\x91\xb0\x42\x91\xfa\x9f\xde\x00\x6f\x62\x85\x14\x33\x24\xed\x50\x67\x37\x99\x21\xb2\x66\x93\x50\x3e\xcc\x14\xa5\x8c\xbc\xa7\x7c\x1e\x24\x2c\xbf\x41\x77\xd5\x3b\x90\x22\x10\xe1\x1c\x88\x99\xa4\x0e\xc7\x6d\x12\x2e\x88\x4f\x22\x12\x8a\x22\x93\x7e\xae\x9e\x03\x4d\x23\x0f\x52\xe4\x41\xef\x41\x1e\x1c\x64\xa2\xd8\xc4\xfa\x6d\xa4\xf5\xad\xe4\x41\x46\x1a\x50\x70\x17\xb0\xee\xb0\xa5\x23\x97\xa1\x38\x0d\xc5\xe4\x03\x88\xc0\x40\x7a\x50\x70\x51\x0e\x04\x4e\xca\x8d\x21\x74\x53\xe0\xaf\x53\xcd\x85\x50\xec\x44\x14\x37\xa2\x38\x92\x31\x9c\x1e\x2c\x0f\xb9\x45\xe2\x10\x30\x88\x21\xda\x28\x64\x34\xdb\x45\x86\x44\x18\x00\x8c\xe0\x51\xd0\xc5\xd0\x88\x71\x67\x29\xf0\x80\x57\x81\xa2\xaf\x61\x2b\x26\x09\x35\x5a\x30\xcc\x08\x7a\x4e\xc6\x4e\x47\x77\x3b\xba\x43\xb9\x12\x7a\x52\xea\x86\x05\x5f\x20\x4b\x08\x6a\xc0\x9a\x85\x2c\x80\x47\xb9\x0c\x02\x3a\x2b\xd3\x91\x18\x04\x16\xd7\x93\x8f\x40\xd1\x40\xbf\x0b\x83\x1f\x67\xf3\x74\xbd\xbc\x51\xf6\xb4\x0c\x37\x81\x7e\x12\xe9\x29\x36\xbe\xdd\xf6\xd2\xe2\x36\xcd\x0f\xa1\x60\x20\x5a\xa6\x9e\xe8\x40\x75\x48\xba\x1f\xe9\x81\x32\x39\xe9\xa2\x1a\x44\xf7\x4a\xa8\xe2\xd1\x3a\x04\x77\x6a\x56\x1b\x52\xc6\xdf\x90\xcf\x01\x94\x25\xc8\xfc\x6e\xe7\x1d\x5c\xbf\x38\x49\x08\x2f\x26\x65\x14\x38\xe8\xb6\x48\xdd\x29\x8a\xfc\x44\x56\xc9\xe2\x73\x25\xbb\x24\xbe\x78\x86\x11\x2c\x89\x42\x8e\x78\x8c\x91\x6c\x44\x6a\xd1\x66\xf2\x96\x35\xde\x79\x68\x5d\x71\xd6\x3c\x70\xc4\x9d\xcf\x83\x7d\x0a\x8e\x99\xc0\x9d\xc2\x38\xdd\xda\x52\xaf\xc5\xa5\x5e\x51\x0f\xc6\xa8\x28\x1e\x72\x8a\xa5\x1b\xc3\xcd\x96\x34\x6e\x4c\x1d\xa4\xe9\x32\x91\xe6\xcb\xed\x34\x27\x90\x14\xa0\xa6\x63\x46\xc8\x2a\x4e\x0e\xe2\xf4\x20\x04\x66\xb1\xd8\x54\x69\x9e\xe2\xfc\x25\xc0\xcb\x36\x37\x05\xfd\x8e\x0b\x4a\xb0\x95\xa2\xfc\xc1\xe3\xc4\xe6\xee\xc2\x47\x0a\xd9\x77\x88\x99\x88\x94\xf2\xd2\xdb\x63\x58\x34\xd0\x83\x09\x30\xa2\x88\x3b\xa4\x61\xe4\xe6\xb6\x28\x3d\x8c\xa2\xde\x50\x8a\xbe\xf9\xe6\xa6\x68\x83\xdb\xeb\x38\xb3\x24\xd2\xc3\xe6\x80\x49\x65\xfd\xb1\xbb\x36\xb2\x0c\x89\xc6\x5c\x08\xad\x0f\xa1\x57\x2b\x4f\x22\x42\x39\xf3\x0c\xc2\xfb\xe6\x60\xc0\xa5\xcd\x67\x08\x2e\x78\x99\xbc\xc5\x2e\xb4\x47\x27\x7a\x55\xa2\x57\x23\xce\x49\xf0\x1a\x44\x84\x89\x32\x59\x96\xc7\xb2\x5d\x44\xa1\xfe\x0c\x39\x2c\x96\x72\xc9\x42\x30\x59\x25\x9a\x0c\xc0\xb2\x56\x57\x53\x7e\x2f\x65\xcf\x2b\x42\xe8\x38\xb7\x21\xd2\x43\x68\x28\x76\x62\x88\xc5\x6a\xf0\x4a\xd1\x52\x87\xda\x49\x09\x76\x92\xe1\x49\x2a\xa3\xa0\x30\x36\x2a\x0f\x45\x9e\xf8\x4a\xa8\xcc\xa5\xf4\x74\x4a\xcf\xa8\x7a\x63\x59\x25\xaf\xba\x22\x84\x7e\x8f\x9b\xc6\x6a\x1c\x6c\x1a\x4c\xcb\xfc\x08\x54\x06\x18\x42\xbe\x13\x2a\x1c\xdc\x05\x01\x29\x67\x24\x4b\xf3\x08\x33\xf5\xd3\x5c\x16\x1e\xca\x60\x2d\x1d\xe3\x0f\xb6\x4b\xb4\x12\xb4\xf0\x42\xa9\x96\x5e\x20\x44\xba\x0f\xad\x64\x03\xdb\x14\xdc\x98\x7c\x18\x66\x80\x17\xc1\x1f\x88\x18\xc3\x60\x6c\x49\x3c\xa6\x60\x1b\x2f\x76\x25\x73\x3d\x0c\x63\x96\xd2\x48\x25\xf7\xd3\x06\x83\x44\x9c\x01\xc1\x83\xa6\xea\x66\x03\xe6\xf2\xb2\xa1\x31\x51\x4d\x95\x01\x99\x11\x25\x7c\x00\x64\x81\xdc\x24\x7a\x98\xd4\x51\x78\x32\x23\xa6\x8a\x41\x7e\xca\x3c\xf9\xa9\xc7\x32\x73\x57\x9c\xa7\x48\x4a\xec\xca\x29\x32\xaf\x5a\x6d\x5e\xd4\xa4\x83\x58\x27\x06\xda\xdd\x24\xfd\x00\x2f\x46\x73\x13\x24\x4d\x88\x51\x5c\x0e\x53\xb8\xb1\x69\xd6\xe8\x84\x2c\x8e\xb5\xe3\x54\x8c\x7a\xf2\x30\xaf\x7a\x60\xd8\x9c\x28\xb9\x75\x8b\x6b\xf5\xcc\x1b\xbc\x0d\x98\x05\x69\x29\xf5\x49\x34\x96\x69\x54\xaf\x45\xb1\x0a\xb9\x0a\xa3\x71\x99\x70\xa6\x02\x9f\x0b\xbb\x31\xa3\x52\xe5\x7c\x42\xd2\xbd\xb2\xee\x95\xb6\x7c\x72\x40\x34\x18\x61\x44\x59\xee\x4a\x04\x48\x5e\xca\x27\x64\x98\x52\x70\xc6\xf4\x20\xd8\xae\xa6\xbe\x9d\x4d\x13\xe7\x47\x13\x64\x54\xda\x38\xb6\xf1\xc3\x02\xb4\xfd\x4f\x04\xc1\x85\x62\x06\x82\xeb\x55\xac\x01\xd9\x7e\x69\x6c\x14\xfc\x94\x1c\x96\xc9\xf1\x0f\x83\x65\xe6\x23\xc6\xa2\x15\x09\xd8\x54\x31\x26\x46\x71\x1f\xde\xa6\x90\x51\x72\x17\x02\xff\xaa\x1a\x1e\xe5\xf3\xcd\xb0\x7d\x68\x11\xd3\x10\x16\x2a\x20\x7a\x30\xae\x84\xdb\xa9\x11\xb2\x0d\x13\x50\x9f\x9f\x78\x42\x8c\xd1\x32\xa0\x23\x61\x9d\x65\xbc\xd6\x07\x57\xe9\x28\xf1\x07\x41\xd6\xcb\xe1\x46\xde\x83\x07\xab\x22\xa4\x64\xec\xe9\x52\x00\x9b\x9f\x31\x44\x48\xd3\x04\x22\xed\x17\xcf\xec\xf0\x73\x03\xb4\x18\xa3\x27\xc8\xe8\x89\x32\xe8\x44\x98\xd1\x13\x67\x9c\x0c\x06\xe6\x84\xf7\x46\x1b\xbd\xe1\x46\x6f\xbc\xc1\xc3\x65\x91\x55\x68\x09\x08\x60\x65\xad\xc9\x04\x44\xb0\xf1\x1e\x05\xe5\x64\x76\x8b\xe8\xbe\x4c\xbe\x53\x27\x05\x06\x0e\x00\x84\xb1\x50\x73\x21\x9d\x4d\x44\xd1\x83\x74\x84\x71\xc6\x29\x71\x9a\xe6\xd1\x55\x03\x30\xe3\x53\x9a\xde\x1d\x3c\x5b\x52\x70\xfe\xeb\x0e\xc8\xaf\xec\x21\xee\x27\x7b\xec\x3c\xb7\xa7\xf1\xbf\x58\xfc\xa0\xd7\xa5\x9e\x04\xa1\xc1\xaf\xf6\xb8\x97\x8c\x9e\xed\xa0\xc9\x67\x2a\xbf\x0b\xf1\x5a\xda\xd5\x44\xf1\xcd\x45\x7c\xa5\xcf\xbd\xe1\xb0\x1b\xfa\xaa\xa4\x14\xd8\x89\xd7\xfa\x74\x05\x19\xdc\x30\xec\x34\x59\x38\x21\x63\x3c\xce\x16\x02\xfd\x31\x9f\x01\x0d\xa8\x52\x67\x3e\xa8\x90\x85\x94\x41\x8d\x08\x05\x66\x42\x54\x79\x2f\x6c\x00\x47\xac\xa9\x66\xa7\xe1\x26\xe5\x08\x3e\x10\x52\xcc\xe0\x34\x1c\x19\xdf\xb8\x4c\x47\x86\x30\xdb\x7b\x5b\xc7\x11\x9e\xe3\x46\x4e\x72\x32\x8e\xc8\x08\x34\xbd\xaa\x81\x6f\x54\x04\x3f\xf0\x3e\x75\x64\xf4\xb5\x54\x0e\x76\x26\x1d\x19\xd1\x71\x08\x1c\x29\xc6\x0e\x6c\xdf\xba\xcc\x1f\xb5\x02\x95\x62\xd4\x9c\xa1\x01\xf3\xef\x22\x15\x71\xcc\x35\x85\x89\x89\x4b\x98\x39\xd8\x0b\xbd\xef\xa0\xcb\xe8\x58\xe0\xb5\x97\x99\x08\x20\xe6\x69\x9b\x28\x1d\x0a\xe9\x20\x54\xa8\xa0\x06\x01\x9b\x6f\x6c\x5b\xc9\xbd\x43\x78\x9d\xb1\x5c\x3c\x3c\x9d\x0a\xb2\x25\x16\x46\xcb\x77\x86\xa2\xf5\x4a\x8d\x52\xc4\x76\xf1\x75\x50\xbb\x63\x72\x11\x76\x04\x28\x9e\x5b\xeb\xb8\xeb\xf0\xf8\x28\x83\x70\x38\x83\x28\xd8\x99\x44\x60\x62\x14\xa7\xc3\xe2\xf9\x15\x96\x04\x52\x09\x83\x05\xab\xfd\x46\x5d\xf9\xe3\xa1\xe2\xc9\xcd\xc5\x57\xfe\x92\x5d\x04\x5d\xf3\xd6\x3e\xe5\x7d\x8c\x51\xfa\xc8\xce\x6e\xbd\x7a\x67\x50\x47\x5f\xab\x8a\x2e\x5c\x1f\x7d\x1a\x33\x44\x3e\x04\x96\x0c\xdf\x93\xb2\x75\x0d\xdf\x0d\x16\x07\xf9\x9b\x3c\xa3\x1c\x64\x2e\x49\x83\xf4\xb0\x08\x29\xd6\x73\x75\x63\x6e\x85\xfb\x96\x2a\xda\xb3\xe6\x39\x40\xae\xa6\x89\x86\x10\x61\xbe\xc4\x65\x08\xfb\x65\x09\x96\x56\x40\xd7\xa7\x04\x99\xf0\x1f\x1e\x37\xf0\xb0\xb9\x99\x23\x60\x93\x36\xf1\xcc\x0e\xb9\x93\xdd\x26\x28\x11\x0b\x2e\x89\x78\xa8\x38\xb2\x69\xa4\x93\x24\x95\x9f\xa3\x9a\xe3\x37\xf8\xe5\xb9\x08\x4d\x11\x79\xb3\x28\x23\xae\x5c\x4d\x69\xb0\xfe\xf0\x1c\x61\x71\x96\x30\xee\x17\xb9\x17\xc2\xf8\xe7\x7f\x81\x23\x5a\xbe\x6a\xae\x4b\x23\x7d\xeb\x52\x8e\xbc\xb9\x89\x61\xf5\xd5\x71\x4d\x2e\xfe\xde\x03\x15\xef\xc0\xe2\x40\xe8\x82\xa9\x6c\xaa\xac\x36\x73\x39\x09\xaf\x36\x84\x82\x47\x48\x3d\x8c\x7b\x39\x22\xba\xe9\xf8\x25\xa8\x1c\x89\xaf\xc1\xc8\x19\xf5\x9a\x95\x3a\x30\x31\xef\xe9\x3f\xee\x9a\x62\x16\x8c\xba\x96\x0e\x7d\x7c\x1b\xf6\x8b\x63\x10\xf9\x98\x24\xc5\x84\xd5\xc0\xf9\x42\x66\x43\xc6\xb5\x7d\x06\x8b\xbe\x5b\xad\xae\x4e\xb2\x5e\xd1\xbe\xda\xfa\xa4\x27\x9a\x81\x77\x22\x48\x61\xf1\x8e\x8f\x4a\x80\x13\xc3\x9b\xc8\x33\xb0\xca\x7a\xed\x71\x46\xdb\x74\xa2\xe3\x45\x08\xc6\xca\x8b\x10\xa8\xa9\x22\xc0\x61\x18\x19\xf0\x73\x0c\x17\x8d\xa6\x9d\xf3\x21\x52\xb4\xcf\x86\x1f\x21\x47\x39\xfa\xbf\x71\x04\x77\x21\x77\xdf\x00\x11\x61\x26\x02\xb0\x43\x40\xce\xcd\x90\xf7\x35\x8e\x7f\x14\xe9\xbf\x30\xbe\xf1\x61\x88\xf8\x14\x04\xd3\x21\x62\xb7\xc5\x13\x69\xf0\x23\x49\xa4\xe6\xfe\x13\x2e\x5f\x00\x66\xba\x0d\xf7\x02\x91\x1b\x20\xe9\x07\x22\x43\x3e\x15\xc0\xfb\x67\xc3\xea\xa1\x4a\x41\x54\x54\x44\xe3\x92\xa8\xa8\x89\xf6\x16\x45\xcf\x71\x79\x68\x03\x2d\x32\x86\x1a\xb0\x64\x3f\x86\xc5\xd6\x91\xd2\xca\xa8\x2b\xb4\xc2\x4d\x4f\x34\x2e\xb9\xcf\xb9\xdc\x30\x3b\xfb\xbc\x77\x61\x9f\xf7\xee\xec\xb3\xf4\xd7\xb9\x1f\x85\x93\xfd\xb1\xcf\x12\x7e\x0e\x36\x22\xaa\x3d\xa0\x5f\xd8\x59\xed\xdf\x6a\xa6\xee\x57\xee\x96\xf0\xab\xb7\x1d\xd1\x51\xff\xfe\x3f\xfe\x5b\x8f\xff\x6f\x00\x00\x00\xff\xff\xae\xc6\xd0\x0a\xb5\x5d\x00\x00") + +func fontsCaligraphyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCaligraphyFlf, + "fonts/caligraphy.flf", + ) +} + +func fontsCaligraphyFlf() (*asset, error) { + bytes, err := fontsCaligraphyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/caligraphy.flf", size: 23989, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCatwalkFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x6f\x24\x35\x10\xbd\xcf\xaf\xa8\xc3\x5e\x91\x97\x11\x12\xcb\xad\x57\x48\x7b\x81\x53\x84\xc4\xd1\x09\xd2\x04\x45\x8a\x40\x82\x5c\xe0\xd7\xa3\x99\xb6\xcb\xef\x55\x3d\x77\xcf\x0c\xd1\x66\x93\x6e\xbb\xbb\x5d\xdf\xf5\xaa\xec\x7d\x7e\x7d\x3e\x3e\x7d\xb0\x4f\xf6\xbd\x1d\x3f\xda\x37\xdf\xda\xf1\xf0\xe3\xe7\x5f\x7e\xfd\xfc\xf3\x4f\xf6\xdb\x3f\xf6\xf0\xe7\x1f\xf6\xe5\xaf\x97\xb7\x7f\xed\x53\xf9\xe1\xbb\xc3\x97\x97\xdf\x5f\x4f\x6f\xf6\x70\x7a\x3d\x3d\xfd\x7d\xb2\x63\xf9\x78\xf8\xb0\x88\x5f\x5b\x96\x43\x2d\x85\x2f\xd6\x2e\x66\xd6\x9e\x9d\x47\x97\x87\xb5\xf8\xcd\xec\xf2\x7e\xff\xd6\xee\xfd\xe7\x3c\xad\xa5\x58\xbb\x5e\x38\x9c\x7f\xec\x72\x4f\x6f\x6f\xfc\x18\x19\x5d\xe6\xfd\x4d\x5d\x17\x5d\x28\x04\x39\xda\x3a\x7f\x7b\xfe\x4b\x6f\xa3\x26\x8d\xa4\x7f\xcc\x42\xc0\xd2\xc6\x6f\x10\x94\x6b\x49\x62\x9b\x4a\x7c\x56\xbb\xbb\x05\x49\x75\x2f\xd5\x24\xf1\xfa\xa6\x39\x6c\x7e\x69\xe2\x35\x72\x8d\x7e\xbc\xa1\x65\xc0\xbb\xe4\xa9\xae\xb3\xba\xb7\xf7\xe4\x2c\x37\xaa\x32\x0e\xea\x55\x0b\xc5\x80\xb5\x48\x10\xef\xc5\x7a\xa6\x2f\xc2\x04\xa3\xd3\x72\x60\x74\x9b\x77\xb6\x5b\x9f\x65\x6a\xc8\x68\xe3\xe2\xae\x72\xdb\xa4\x3b\x71\x17\xef\x6f\xe2\x84\xba\x07\x43\xdd\x1b\xd1\x51\xe9\x90\xfc\x48\x0a\x08\x60\x94\xb9\x00\x4e\x6f\x84\xa5\x71\x88\x29\x7f\xa2\xed\x52\x5c\xea\x7b\xb0\x69\x72\xe0\x9a\x5f\x9d\xa4\xb2\x16\xeb\x85\x76\xe9\x39\xbb\x82\x96\x08\x07\x70\x2c\x90\x72\x63\x73\xd0\x52\xe2\x74\x68\x28\x31\xec\xa4\xcd\x39\x3c\x2b\xbb\x33\xf0\xc3\x78\xef\x79\xa5\xa8\x6c\x6a\x42\x2e\x6c\xb9\xb3\xa7\x49\x04\x44\x95\x9a\x60\xe4\x1c\x48\x9d\x97\x99\x0a\xaa\xe1\xcc\x58\x2c\x02\xb2\x57\xaf\x31\x57\xe7\xc4\x74\xbc\xa5\x49\x9f\xe8\x24\x88\xc1\x97\x35\x01\x53\x6c\x39\x3f\x39\x78\xd8\x9c\xb5\xab\x45\x42\x1a\x1b\x5b\x3a\x7f\x8e\x30\x01\x6b\x76\x3f\x04\xf8\x73\xfb\x87\x56\x80\x23\x8b\xa5\x14\x91\x25\x6c\x03\x83\x5a\x28\xfd\xe5\x93\x34\xb8\x5d\x80\x1d\x15\x88\x70\x20\x36\x7c\x41\xcf\x6a\xf4\xbe\x7c\x16\xaa\x9d\x53\xc0\xc4\x31\x6a\x93\xb0\x72\xb6\x6c\xa9\x0c\xc2\x8f\x8f\x8f\x09\xcb\x63\x59\x05\x27\xb2\xf5\x6a\xb1\x80\x04\x2a\xcc\x46\x14\x42\xc3\xc7\x65\x26\x96\x89\xe4\x6e\xf2\xd5\xc0\x34\x5c\x3a\x56\x35\xf8\x81\x6f\x62\x8a\x40\xdf\xa1\x52\x3b\x64\x18\x35\x6e\xe4\xee\x30\xc6\xef\xcd\xb3\x3a\x30\x70\x98\xf7\xc5\xa4\x3c\x32\x9b\x8c\xb1\xd4\x45\x77\x39\x83\x42\x42\x27\xfc\x2e\x8c\x50\xf2\x83\x98\x70\xef\x42\x38\x45\xd8\x82\xb6\x1a\x75\x39\x45\x84\x9c\xf4\xad\x83\x1b\x09\xe2\x4c\xc0\x69\x40\xcc\x8d\xc9\x28\x1a\x57\xae\x49\x8c\xf6\x2e\x90\x58\x15\x9b\xd0\xbd\x51\x2d\xd8\x47\x71\x80\x2d\x18\x22\xdd\x48\xd0\x02\x20\x62\x79\x36\x8b\xcf\x66\x15\x57\xd9\xf2\x1a\x67\xdf\x1a\x66\x6d\xd2\xf5\x1d\xbe\x1e\x5a\x54\xf0\x01\x83\x9c\xe3\x90\x20\x45\x53\xb3\xa4\x51\xd1\x7c\xc1\x78\xcc\x95\x99\x72\xbe\x1a\xb1\x4c\x1c\x07\xd6\xe4\xce\x27\x58\x3f\xcb\xaf\xe7\x86\x2d\x81\x29\xfa\x42\xe3\x90\xb1\x0a\x73\x72\x56\x6f\x81\xe0\x54\xc3\xa0\xe0\x9e\x7b\x92\xb7\xaa\x77\xb0\x50\xb0\x62\x9e\x9f\x7d\x4f\x9a\xb1\x6e\x6a\x66\x31\x3c\x63\x5d\x8f\xee\xd0\xbe\xec\xd2\xb0\xf9\x42\x55\x0d\x55\x3d\x43\x3f\xd2\x49\xbe\x32\xee\x67\x98\xd8\xfb\xcc\x88\x61\x76\xc6\xdd\x93\x2b\x50\x59\xd8\xcc\x9d\x8d\x81\xad\x9b\x0b\x4f\x48\x56\x2d\x04\xbf\xaa\x40\x4a\x90\x8d\x7c\xab\xdc\x13\x24\x90\x40\x60\x18\xc5\x4c\xe7\xeb\x4c\x00\x34\x83\xab\x5c\xa1\xf7\x41\x5d\xd2\x3b\x09\xe1\x32\x6a\x25\x43\x32\xfa\x8c\xe1\x2d\x33\x66\x98\x36\x64\xe0\x54\xe1\x51\x33\xb1\x69\xa9\xa1\x15\x28\xa2\x94\x00\xc3\xa6\xe8\xee\x0d\x8f\xc2\x14\xbb\xb8\x41\x48\xb2\x42\x4a\x4d\xf7\x2d\x78\xdc\xb9\x7d\x0b\x12\x19\x27\x6b\x2d\x65\xb7\x4c\xdf\x33\xe9\xb3\xdb\xef\xed\xf4\xc5\xbb\x9c\xbc\x43\xe4\x0b\x21\x5c\x1c\x0f\x4d\x3d\xcd\x54\xc3\x1c\x62\xb5\x64\xd4\x04\xe9\x26\x43\xb2\x22\x37\xda\xf4\x41\xb6\x51\xd8\x50\x56\xec\x46\x9d\x0d\x3c\x19\xdf\x30\xa1\x79\xdf\x87\x60\x22\x3b\x40\x76\xfa\xf5\x36\x8d\x1b\x09\xda\x22\xd9\xe8\xa3\xa7\x45\x7d\xe9\x1b\xce\xf3\x32\xff\x8f\x04\x42\xab\xc9\x20\x49\x1a\x87\x8c\x64\xd1\x23\xf0\xb4\x1b\x8a\x32\x13\xac\x71\x18\x99\x8b\x23\x3a\x86\x49\xd6\x2d\xa6\x6c\x8a\x27\xef\x3b\xfd\xbc\x2b\x21\xe7\xf2\xbe\xf6\x9e\xcb\x4c\xe0\xb0\x89\x6f\x26\x2f\x14\xc1\x33\xd1\xdd\x66\xf3\xeb\x88\x49\x7d\xc8\x60\x64\x50\xaf\x70\xe0\xa1\xe0\x1a\x3d\x5d\x95\xac\x51\xc8\xed\x70\xa8\xf1\xc0\x20\xc5\x00\x99\x27\x11\xbf\x1b\x65\x02\x75\xd9\xbf\xa5\x78\x43\xb9\x07\xae\x0c\xc2\x11\x55\xa4\xc3\x35\x41\x03\x5c\x41\x82\xc3\x11\x95\x3a\x63\x1f\x95\xc9\x61\x59\x84\xab\x3c\xa8\x21\xff\x35\xee\xd5\x42\x47\xc4\x1d\x39\x0c\x90\x22\xe2\xd4\xa2\x80\xe1\x3a\x14\xa1\xe2\x3a\x37\x7e\xdc\xaa\xe9\x91\x35\xb3\x4d\x00\x34\x96\x49\xae\xb3\xb2\x00\xb9\x90\xa2\x8f\xd1\x75\x56\x70\x62\x56\xce\xab\x30\xec\x8f\xd9\xfa\x0b\x29\x60\xa9\x16\xee\x64\x18\x22\x3a\x04\xbb\x8d\x6a\x11\x8a\xee\x24\xc3\xa6\x84\x6b\x21\xc2\xa5\xe4\xbe\x29\x84\xdf\x36\x61\x0a\xa8\x90\x9e\x4b\x38\x9b\x55\xa7\x0c\xe0\xc7\xb4\x6a\x58\x51\xbf\xc5\xb5\x4e\x70\x3d\x55\x5c\xff\x56\x12\x34\xc7\x44\x9f\xd1\xac\x65\x43\x9e\x60\x85\xc5\xc3\x78\x40\x59\xc2\xd5\xff\x35\x5e\x0e\xe1\xdf\xd7\x7a\xf0\x5f\x00\x00\x00\xff\xff\x77\x4b\x9c\x34\x1e\x21\x00\x00") + +func fontsCatwalkFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCatwalkFlf, + "fonts/catwalk.flf", + ) +} + +func fontsCatwalkFlf() (*asset, error) { + bytes, err := fontsCatwalkFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/catwalk.flf", size: 8478, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsChunkyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x57\x4d\x4b\x1c\x4d\x10\xbe\xcf\xaf\x78\x0e\xc2\x5c\xa6\x7b\xd4\x57\x0f\x2f\x48\x18\xc8\x21\xc1\x43\x2e\x21\xb7\x85\xde\x95\xa8\x11\x44\x89\x92\x43\xa0\x7f\x7c\xe8\xea\xaf\xea\xee\xea\x9d\x59\x02\x91\x45\xc7\xd9\xfa\x7c\xea\xa9\xea\xea\x87\xe7\x87\xcb\xc3\x19\xae\x71\x85\xcb\x73\x5c\x5c\xe3\x62\xf8\xfa\xf3\xd7\xe1\xed\x1e\x77\xbf\xf1\xf1\xc7\xdb\xd3\x3b\x3e\x3d\x3d\x3f\x4f\xf8\xef\x5c\xdd\x7e\xfb\xa2\xfe\xbf\x82\x52\xb8\x3b\xbc\xdf\x7f\xc7\xeb\x0b\xf4\xfb\xd3\x23\x5e\x1f\x70\x7b\x7f\x87\xcf\x87\xc7\xc3\x8b\x1e\xce\x16\xfe\x59\x06\x18\x83\x65\xb0\x80\x5d\x06\x6b\x4c\xfa\x0d\x00\xfe\xeb\x20\xe0\x45\x60\x8d\x8d\x5f\x03\xe9\x2f\x3d\x18\x92\xa5\xb7\xc6\x49\x03\x96\x54\x8d\x17\x82\x37\xce\xfe\x71\x02\xc6\x7d\xa2\xab\x49\x4d\x31\x9c\x11\x63\x8c\x86\xe4\xfd\x23\xfd\x78\xf7\xd6\xa9\x05\x3d\x84\x20\xc9\x14\x89\x92\x8b\xa0\x6f\x72\x46\x39\x2b\xc9\x15\x0a\xad\x8e\xab\x08\x16\x12\x0e\x19\xac\x10\xc7\x34\x86\x64\x09\x04\xff\xd7\xbd\xdf\x6b\x32\xe9\x51\x45\x80\x66\xaf\x09\x08\x6f\xd3\xa4\x42\x98\x69\x8c\xb9\x65\xaf\x51\xec\x03\x45\x7a\x13\x52\xae\xf2\x4b\xd5\x60\xa5\xc8\x75\xc8\xb8\xe7\xf2\x45\x15\xa4\xdf\x75\x9e\x4c\xd2\x53\x22\xe2\x9d\x41\x2a\x08\xd1\xb3\x58\x50\xcb\x53\x86\x1e\x66\x60\x5e\x06\x4c\xa3\xfb\x2c\xc3\x6c\xcc\xcc\xad\x2d\x85\x57\x24\x42\xc0\xb1\x9d\x51\xa3\xa9\x72\x00\x81\x52\xb7\x35\x1c\x3d\x95\x18\x2a\x24\x2e\x6d\x53\xe1\x4f\x3d\x95\xc8\x0c\xf7\xe1\x2a\x08\xe5\xe9\x79\xe1\xe1\xac\x7b\xa9\x54\x3c\x2f\x36\xaa\x04\x41\xa4\xc0\xec\x8a\x4a\xb4\x7d\x82\x97\x2c\xb8\x92\x4b\xa6\x8f\x40\xa5\xf6\xeb\x8a\xbb\xf4\xd2\x91\xcb\x89\xcc\x44\xb8\x65\xd8\x01\x3b\x7a\xef\x1a\x73\x9d\xe4\xdd\xc8\x02\xc5\xf6\x9a\x6a\xe6\xac\xba\xf7\x9e\xd3\xd6\x75\x72\x31\x20\x03\x90\x11\xd3\x71\x02\x26\x35\xfa\xba\x2b\x15\xdb\x72\x54\x6a\xe4\x68\xe5\xb2\x98\xa8\xeb\xc9\xc3\xfe\xa9\x23\x65\xd3\x86\xeb\x33\x5a\x67\xc8\xad\x69\x87\x48\xe5\xd6\xa5\x15\x9e\x6e\x92\x8f\x79\x9d\x40\x70\x6d\xaa\x36\x35\x03\x1c\x7c\x6d\x63\xcf\x62\x33\x30\x6a\x1b\x5b\x3e\x9a\xc6\xd3\x66\x3d\x8b\x62\x8e\x49\x7a\xc8\x7a\x56\x38\x99\x7a\x7a\xf6\x44\xe0\xd9\xe1\x69\xe2\xe1\x50\xcc\x2e\x71\xea\x07\x8a\xf9\x3c\x04\x7f\x72\x9c\xc8\x6d\x33\x33\xad\x78\xc4\xec\x7a\x55\x4b\x90\x58\x56\xf4\xbf\x84\x44\x3c\xd0\xaa\x12\x58\x51\x6f\xbd\xe4\x8c\x92\x5b\xe2\x6c\xb8\x0f\x62\x7c\xe4\xc9\x51\x56\x16\xae\xd6\x59\xd9\xba\x42\x6c\x33\x69\x7f\x91\x08\xd9\x5b\x95\xd6\x88\x05\x9b\x8e\x47\x84\xd4\xb6\x56\xcd\xae\xfa\xc3\x31\x3d\xec\x9a\xfe\x2e\x66\x1e\x3b\x22\xf3\xc4\x2b\x7b\xae\xf0\x79\xc4\xa9\xa2\xef\xd5\xf1\xae\x6b\xf5\xdc\x38\xa7\x05\x65\x13\x38\xac\x02\x45\x5d\xba\xc5\x88\x55\x17\xb6\xc5\x40\xe7\x65\xf0\x8d\x16\xce\x2b\xcf\xba\xbd\x8e\xa7\x8d\x43\x70\xd7\x2c\x4a\x69\xe7\x91\x77\xcb\x7c\x2c\xa4\x7e\x72\x5f\xcc\xbb\xde\x6a\x5f\xbc\xaa\x9e\x78\xf6\xcc\x36\xbb\x55\x58\x34\x8b\x72\x50\xd6\x4a\x29\xad\xb4\xdf\x04\x52\x78\x9a\x41\x95\x8e\xd8\x60\x4f\x35\xd2\xa6\x92\x66\xa6\xa3\xac\xc9\x79\x97\x69\x51\x98\x9a\x4e\x5d\xbb\xc5\x6c\xb4\x1b\x0c\x2b\x56\xdf\x4a\xda\x43\xa2\xf3\x4d\x20\x8e\x00\x2b\x61\x5b\x9a\xcd\x41\x14\xd1\x74\x90\xe0\xf3\xaf\xc1\x2d\x5d\xea\xd8\x05\x8f\xc5\x08\xda\x91\xe8\x65\xdc\x98\xf2\xc1\xd4\x77\x98\x6e\x1e\xa2\xc3\xd4\xaa\xc2\xc2\x5f\xa6\xab\x58\x0e\x45\x1a\x42\x57\x4b\x40\xf5\x53\x3f\x0e\xeb\x09\xd2\xac\x89\xed\x16\xdb\xc5\x0e\x2f\xd3\x71\x33\x13\x8c\x01\xdb\x9b\x84\x9e\x60\xc3\x02\xec\x8c\xa9\x59\x1e\xcd\xea\x18\x81\xdd\x82\x44\x25\x4d\xa3\x7a\x86\x20\xcd\x15\xb8\xce\xca\x98\x6e\x5d\x99\x9c\x84\xde\x1e\x98\xd4\x27\x2d\x96\x4a\x61\xad\x59\x69\x9b\x96\xae\x07\x56\x9a\x6a\x35\xcb\xcb\x5b\xbd\x95\xaf\x02\x6e\x14\x16\x0e\x47\xaf\x3f\xb1\xfb\x1e\x2b\x5e\x4e\x96\xf2\x08\x57\xde\x1e\xe9\x45\xe9\x2e\xe9\xb9\xb4\x8d\xd2\x5d\x62\x14\xb6\x75\x63\x5b\xff\xbb\x48\xda\x25\x9e\xed\x66\xb4\x31\x85\x9b\xd0\x9c\x9a\x96\xf4\xfe\x04\x00\x00\xff\xff\x9e\x93\x6b\xf8\x4b\x13\x00\x00") + +func fontsChunkyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsChunkyFlf, + "fonts/chunky.flf", + ) +} + +func fontsChunkyFlf() (*asset, error) { + bytes, err := fontsChunkyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/chunky.flf", size: 4939, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCoinstakFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x5d\xab\x1c\x45\x10\x7d\x9f\x5f\x51\x0f\x79\xe9\x07\x49\x5c\x04\xe3\xdb\x88\x10\x10\xc1\x86\xe8\x0f\xb8\x11\x36\x12\xb8\x28\x68\x5e\xf4\xd7\xcb\xee\x74\x57\x9f\x73\xaa\x7a\x66\x77\xbd\x24\x5e\x67\xba\x67\xa6\xeb\xbb\x4e\x55\xf7\x7e\x7c\xfe\x78\xfa\xf0\xca\xde\xda\xb7\x76\x7a\x63\x5f\x7d\x6d\xa7\xe5\x87\xfa\xe3\xcf\xbf\xfc\xfa\xfd\x4f\xf6\xdb\x3f\xf6\xfe\xcf\x3f\xec\xdd\x5f\x9f\x3e\xff\x6b\x6f\x5f\x7f\xf7\xcd\xf2\xee\xd3\xef\xcf\xe7\xcf\xf6\xfe\xfc\x7c\xfe\xf0\xf7\xd9\x4e\xaf\xdf\x2c\xaf\xd6\xe4\xcf\xd6\x75\xa9\xa5\xf0\xc5\xda\xc5\xcc\xda\xb3\xcb\xe8\xfa\xb0\x16\xbf\x99\x5d\xdf\x1f\xdf\xda\xbd\xff\xbb\x4c\x6b\x29\xd6\xae\x57\x0e\x97\x7f\x76\xbd\x87\xb7\x77\x7e\x8c\x8c\xfc\xf5\xba\xd8\x55\xe8\x4d\xc5\x26\xc4\x36\xba\xae\xb9\x0c\xb7\x57\x15\x88\x3a\x39\xd4\xa0\x51\xd8\x56\x18\x71\x1e\x04\x95\x49\xb2\x0c\x08\xd7\x32\xbe\x45\x19\xdb\xb3\x32\x96\xcb\x77\xb0\x76\x10\xdc\xde\x34\x07\xcd\x2f\x4d\xcc\x46\xae\xd1\xd7\x9b\xcb\xdb\xd9\x75\x0e\xd9\x4b\xba\x11\x51\x36\xa2\x68\xe2\x97\xae\xcf\xe6\x29\xf7\xb5\x35\x8f\x27\xef\x93\xf5\x4c\x3f\x86\x03\x45\x21\xf9\x0c\x26\x75\xb0\xdd\xfb\x2c\x52\x43\x46\x3b\x17\x77\x51\x5f\x16\xef\xc4\x3d\x79\x7f\x17\x27\x36\x3e\x68\xf1\x40\x04\x8b\xb6\x92\xdc\x40\x10\x09\x61\x54\x51\xba\x81\x4c\x6d\xea\x62\xb5\xc8\x57\x3f\xae\x0e\x2e\x12\x86\xd9\xad\x82\x11\x39\x89\x29\xca\x26\x86\x71\x6b\x90\x09\x0a\x79\x26\x45\x87\xc4\xa0\x1c\x94\x04\x2f\x3d\xe5\x8b\x86\x55\x6a\x5b\x0e\xbf\xca\x28\x26\xfc\x30\x9e\x8b\x23\x60\xa4\xb2\xab\x49\x61\xcf\x8b\x5b\x72\x4d\x72\x9c\x4b\x83\x04\xcc\x44\x91\x47\x9e\x91\xe0\xe9\x9f\x45\xd0\x27\x46\x6e\x55\x51\x1b\xd3\x18\x65\xd9\x1f\xa7\x0c\xac\x43\x30\xd9\x1c\x85\x1d\xb2\x5a\xf6\x7c\x9f\x01\xfb\x95\x92\xa4\x5b\x67\x6a\x10\x29\x6f\x76\x23\x4a\x39\x62\x08\x76\x1c\x7e\x08\x70\xe6\xf6\x96\x12\xae\x18\x82\x21\x90\x44\x52\x62\x13\x18\x54\x49\xc4\xec\x49\x18\xdc\x2f\xc0\x81\x0a\x44\x58\x88\x0d\x47\xd0\x33\x62\x6a\x04\x0f\xeb\x92\x87\x01\x50\xc5\x44\x41\xf9\x2a\x55\xc2\x16\x0c\x95\xc1\xf5\xe9\xe9\x29\x60\x74\xda\x34\x99\x87\x35\x56\x3d\x93\xcc\xcf\x72\x98\x2a\x48\x4f\x3e\x42\xc0\x00\xff\xc1\xdd\xe4\xab\x81\x61\xb8\x74\xac\x6a\x70\x03\xdf\x68\x76\x40\x1f\x91\x65\x9a\x40\x34\x35\x60\xe4\x6e\x19\xe3\xf7\xe6\xb9\x2c\x0c\x1c\xd6\x7d\x31\x29\x8f\xcc\x26\x63\x28\x64\x45\xdd\xb5\x52\x41\x62\x90\x86\x61\x97\x6c\xf7\x03\x4d\xb8\x17\x21\x1c\x22\x6c\x45\x5b\xf5\xb0\x4d\x22\x22\x9d\xf4\x6a\xee\x46\x82\x38\x4b\xd0\x8d\x0a\xc6\xee\x64\x14\x89\x1b\xd7\x04\x46\x47\x17\x48\x2c\x6a\x34\x8e\x46\xb5\x60\x7f\xc4\x01\xb6\x62\x88\xe0\x06\x83\xda\x90\x96\x17\x95\xdd\x82\x9f\xcd\x2a\x6c\x66\xcb\x5b\x9c\x7d\x6f\x98\xb5\x49\xd7\x77\xf8\x7a\x68\x51\xc1\x07\x0c\x72\x8e\x43\x09\x29\x9a\x9a\x05\x8d\x4a\xce\x17\x8c\xc7\x5c\x99\x29\xe7\xab\x11\xcb\xc0\x71\x60\x4d\xec\x74\xc4\xfa\x51\xfe\x7c\x3e\x20\xbc\x62\x27\x9f\x95\x7a\xce\x68\xdb\xc7\x9f\x98\xd5\x7b\x20\x38\xd5\x50\x14\x3c\x72\x4f\xf0\x56\xf5\x8e\x15\x0a\x96\xe6\xf9\xb5\xa9\x42\xa9\x59\xb7\x6c\x66\x1a\x9e\x5a\xd7\xd5\x1d\xb9\x2f\xab\xb6\x74\xb4\x89\xe1\xbe\x8b\x7b\x4f\xfa\x1e\xe8\x04\x5f\x19\xf7\x33\x4c\xec\x65\x66\xc4\x30\x3a\xe3\xe1\xc9\x0d\xa8\x9c\xd8\xcc\x9d\x8d\x81\x9d\x37\x17\x9e\x90\xac\x9a\x04\x7f\x56\x81\x32\x41\x76\xf2\xad\x72\x4f\x10\x40\x02\x81\x61\x14\xb3\x3c\x5f\x67\x02\xa0\x19\x5c\xe5\x0a\xbd\x8f\x49\x0f\x4f\xef\x52\x08\x4f\xa3\x36\x65\x48\x46\x9f\x31\xbc\x67\xc6\x0c\xc3\x06\x0c\x9c\x9a\x78\xd4\x24\x75\xa4\x73\xc4\x3a\x52\x72\x0d\xdd\xf4\x87\xb7\x70\xa4\x25\xec\x74\x83\x10\x64\x85\x94\x9a\xee\x5b\xf0\x98\x72\xff\x96\x9c\x55\x54\x86\xd2\x7a\x50\xa6\x1f\x99\xf4\xd9\xfd\xf7\x76\x42\xe5\x5d\x4e\xdc\x21\xf2\x85\x10\x4e\xc7\x43\x53\x4f\xb3\xac\x61\x96\x58\x2d\x11\x35\x41\xba\xc9\x90\xac\xc8\x8d\x36\x7d\x10\x6d\x24\x1b\xca\x8a\xdd\xa8\xb3\x09\x07\xcb\xb0\x1f\x3d\xec\xfb\x10\x4c\xd2\x0e\x90\x9d\x7e\xbb\x4d\x75\x23\x41\x5b\x24\x1b\x7d\xf4\xb4\xa8\xaf\x7d\xc3\x79\x59\xe6\x3f\x00\x10\x5a\x4d\x06\x41\x52\x1d\x32\x92\xa9\x47\xe0\x69\x37\x14\x65\x26\x58\x63\x19\x99\x8b\xa3\x21\x77\x09\x36\x15\xe2\x06\xa7\x1d\x95\x8e\x37\xe6\xfd\xbc\x2b\x91\xce\xd3\xfb\xd6\x7b\xae\x33\x81\x65\x13\xdf\x4c\x5e\x28\x82\x67\xa2\xbb\xcd\xe6\xd7\x11\x93\xf9\x21\x83\x91\x41\xbd\xc2\x81\x87\xc4\x35\xf9\x74\x53\xb2\xaa\x90\xfb\xe1\x50\xf5\xc0\x20\xc4\x00\x99\x27\x10\x7f\x18\x65\x84\x7a\xda\xbf\x85\x78\x43\xb9\x07\xae\x0c\xc2\x8a\x2a\xa9\xc3\x73\x82\x06\xb8\x82\x04\x87\x23\x2a\x75\xc6\x3e\x2a\x93\xc3\x32\x85\xab\x38\xa8\x92\xff\x39\xee\x6d\x30\x81\x70\x67\xed\x90\xd8\x44\x5d\x26\xa4\xc0\x70\x1b\x8a\x50\x71\x9d\x1b\x5f\xb7\x6a\xf9\xc8\x9a\xd9\x26\x00\xaa\x65\x92\xeb\x6c\x5a\x80\x5c\xc8\xa4\x8f\xc9\xeb\x6c\xc2\x89\x59\x39\xaf\xc2\xb0\x3f\x66\xdb\x1f\xa4\x80\x85\x5a\x78\x90\x61\x88\xe8\x10\xec\x36\xaa\x85\x14\xdd\x49\x86\x4d\x09\xd7\x42\x84\x4b\x89\x7d\x93\x84\xdf\x3e\x61\x0a\xa8\x1a\x7e\x9f\x19\x26\xdf\xf9\x7d\x06\x37\xcd\x14\x87\xbc\x5d\x95\xda\x25\x71\xbc\x9d\x26\x6e\xff\x6f\xab\x69\x7e\x2b\xb9\x1d\x21\x06\xa7\x62\xf0\xeb\x6e\x82\xa3\xff\x6b\xbc\x2e\xf2\xdf\x97\x7a\xf0\x5f\x00\x00\x00\xff\xff\x43\xbc\x37\xa4\xc7\x20\x00\x00") + +func fontsCoinstakFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCoinstakFlf, + "fonts/coinstak.flf", + ) +} + +func fontsCoinstakFlf() (*asset, error) { + bytes, err := fontsCoinstakFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/coinstak.flf", size: 8391, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsColossalFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x1a\x4b\x8f\xdb\x38\xef\xee\x5f\x41\x18\x02\xa6\xc5\xd7\x31\x3a\x33\xdf\x41\xdd\x53\x80\xc5\x5e\x3a\x17\x1f\x7a\xa8\x6f\xb5\x23\x67\x92\xdd\xc4\xee\x26\x0e\xda\xfd\xf7\x0b\x89\x94\x44\xf9\xed\x3c\xb6\x39\x24\x64\xac\x07\x49\xf1\x6d\x6d\xf6\x9b\xe7\x5c\xc0\xd3\x13\x48\x78\xfe\x08\x2f\xcf\xf0\xf4\x12\xfd\x5e\xef\xeb\xd3\x29\xdf\x27\x9b\xfd\x06\xde\x7d\xae\xab\xbc\xd9\xd6\x15\x3c\xc2\x9f\x75\xb5\x3a\xfc\x9d\x94\xea\x9c\xe4\xe7\xf7\x91\x84\xcf\xe7\xaa\x84\xa7\x4f\x9f\xfe\x1f\x45\x7f\xfc\xfc\xbe\xcf\xab\xbc\xd9\xd5\x15\xd4\x1b\xd8\xec\x8e\xa7\x06\xf6\xbb\xaa\xfc\x2d\xd2\x9b\xc0\x23\xc4\x87\xfc\x6d\xb7\x86\xea\x7c\x28\xca\x63\x0c\x9b\xfa\x08\x9b\xdd\xbe\x84\x9d\x2a\xab\x66\xb7\xd9\xad\xcd\xe4\x28\x07\x00\x78\x84\xd3\xb6\x3e\xef\x15\xe4\xfb\x1f\xf9\x3f\x27\x28\x4a\xf8\x96\x3f\x7c\x30\x93\xaa\xfa\x47\x24\x70\x50\xb3\x2d\x21\xde\xe6\x47\x55\xec\xf3\xea\xaf\x18\x1e\x1f\xe1\xfb\x71\x57\x35\x27\xc8\x4f\x90\x83\xf9\xf7\x03\x14\xe7\x06\xd6\x79\xf5\xd0\xe8\x65\x4e\x87\xf3\x69\x5b\xaa\xe8\xe9\xc9\xac\xb0\x2d\x77\x6f\xdb\x46\x53\x9c\xc3\x7a\x9b\x1f\xf3\x75\x53\x1e\x23\x09\xc3\x0f\x3f\x40\x55\x37\xb0\xab\xd6\xfb\xb3\xda\x55\x6f\xa0\xca\xd3\xba\xac\x54\x79\x3c\x45\xcf\x1f\xcd\xb4\x43\xfe\xd3\x70\x0e\xfb\xb2\x7a\x6b\xb6\xf0\xae\xfc\x69\x07\xaf\xeb\xc3\xa1\xac\x50\x30\xa7\xf7\xf0\x3f\xc8\x61\x73\x56\x6f\x25\x6c\xf2\x75\x53\x1f\xa3\x97\x67\xb3\x82\x2a\x37\xf9\x79\xdf\x20\xb1\x87\x5a\x95\x86\xf1\x66\xbb\x3b\xc1\xa6\xae\x9a\xe8\xe9\xc5\x0c\x43\x51\x6a\xfa\x82\x75\x23\x2d\x1e\xb1\xba\xe6\x7b\x15\x49\x29\xc5\xf0\x77\x26\x53\xb1\x8a\x20\x06\xf7\x8f\x96\x58\xf0\xad\x1f\x00\x4e\x49\xc1\x0c\x8f\x01\x27\x80\xde\x02\x2e\xfe\xd5\xeb\x4b\x29\xe9\x4b\x74\x50\xc9\x3e\xdd\xa7\xd7\x0c\x06\xf6\x99\x42\x09\x97\xd2\x3e\x4d\x94\xd9\xa4\x48\x34\xa6\xa4\x16\x8a\x8c\xa5\x2c\x8c\x34\x65\x91\x98\x91\x86\xcd\x38\xa3\x91\x02\xdc\x2a\x6c\x24\x48\x99\x48\x92\x3f\x8e\x4c\x63\x36\x12\xfc\x19\xd8\x4f\x0b\x33\xdb\x17\x00\xa0\x70\x99\x4c\x13\x63\x10\xc7\x06\x22\x34\x91\x10\x3c\x01\x83\x20\x66\x11\xc2\x94\x5d\xa6\xb0\x0c\x02\x64\x44\xe8\x30\x31\x6d\xd2\x48\x4e\x45\x42\xcb\xe2\x42\x9a\x7d\xc4\x8d\xac\x38\x49\x28\x83\x34\xa6\xf1\x7a\x7a\x2a\xe5\x6b\x42\xcc\x49\x29\x63\x43\x87\x1e\x62\x25\x48\x7b\x80\xe0\xf3\xf5\x93\x90\x9c\x36\x79\x3d\xb8\x26\xb0\x30\xdb\xa4\xa8\xe9\x46\xcf\xad\xb6\xce\xfa\xd6\x3f\x9a\x20\x41\x32\x8c\xad\xf8\xf4\x2a\xa8\x7a\x1c\xc8\x50\x14\xab\x48\x18\x51\x18\x7b\xd2\x3c\x78\x31\xf7\x00\x7a\xbe\xd6\x27\x58\x45\x7a\x6c\x81\x47\x9b\xe1\x59\x19\xb5\x91\x21\x40\xd2\x43\x29\x9a\xed\xb5\x92\xf5\x2d\xcd\xf6\xe8\x15\x55\x6d\x0e\x06\x9c\x62\x15\x74\x50\xa4\x59\x88\x23\x59\xf4\x49\x63\xfd\xb4\xa5\xdb\x46\x32\x99\x3d\x34\xa5\xcf\x1b\xf4\xa0\x42\x0c\xec\x3b\x80\x12\xee\x79\xe9\x40\x2d\xd7\x20\xf8\x7f\x53\x73\x3b\x90\x06\x91\x81\xb1\xef\x96\x0e\x81\xf1\x95\xde\x91\xa2\xe3\x83\x79\x80\xa7\x7a\xc1\xac\x25\x64\x66\xce\xa4\x5b\xfe\x9e\x98\x56\xde\xe6\x05\xf7\x2a\x82\x7b\x15\xd1\xe3\x55\x50\x4d\x18\xe2\xbc\x8a\xa0\xa3\x64\xc8\xb8\x1f\x69\x7b\x15\x61\xbd\x8a\x70\x2e\x85\x94\x5f\xa2\xc7\x74\xc1\x6d\x0e\x62\xd4\xd0\xf2\x29\xac\x03\x11\xe1\xb6\x23\x88\x56\x60\xbd\x20\x11\x43\x10\x6a\xd9\x12\x88\x6b\x68\x7b\x1f\x06\x31\xa7\xda\x61\x9f\xa4\xe9\x35\x06\xac\xe3\x84\xa4\x56\xce\x6b\x2a\xf4\xb0\x60\x0d\x03\xe1\x20\x80\xb6\x42\xe0\x38\xfb\xe3\xf4\x38\x12\x84\xa1\x4c\xba\xac\x41\x3b\x05\xe3\xf2\x86\x8f\xc3\xfb\xf3\x25\xf4\x90\x2f\xb2\x4c\x28\x1d\x42\x08\x51\x26\x52\x23\xa2\x61\x8b\x28\x43\x02\x21\xad\x24\x02\xfc\x93\x1e\x64\x9a\x1e\xbf\x1a\x38\x5e\x59\x18\x60\x88\x17\xa3\x39\xc8\x98\xc4\x28\x00\xa6\xe4\xb3\x44\x5d\x27\xcd\xc7\xd1\xa3\xdc\x30\xbd\x89\xa3\xe7\xc6\xe6\xd3\x11\x37\xf7\x3a\xdc\xe9\x30\x9f\x23\xb8\x4c\x43\x8f\xc3\x1d\x4e\xe0\x6f\x66\xeb\xcf\xa0\x7c\x7c\xba\xc2\xf2\x35\xa3\x9b\x89\x92\x69\x7c\x27\x7d\x9e\xe9\xee\x1c\x71\xd2\x1d\x44\x4a\xc8\x6d\xf5\x67\x2a\x94\xcc\x0a\x2e\x3d\x4b\x98\x74\x28\x5d\x10\x46\xad\xd2\x79\x15\x71\xfa\xe1\xe3\x51\xe6\x92\x4d\xf0\xc9\x16\xb8\xdc\x43\xb0\xbc\xa9\xc5\x6d\xe8\x74\x67\xc6\x68\x66\xca\x8b\xa3\x76\x1f\xa9\xe0\x49\xe5\x29\x9e\x33\x90\x31\xd6\x27\x58\x1a\xd6\xab\xb6\xdf\x4e\x94\xd3\x11\x01\x18\x30\x3c\x02\xbe\x9e\x03\x80\xbe\x27\xcb\xf4\x3c\x20\x29\x66\x6e\xd0\xac\x68\x52\x4e\x16\xc5\xed\x17\xc3\x0b\x5f\x2c\x60\xad\xc0\x8a\x85\xc4\x6c\x96\x28\x6f\x23\x36\x2f\xbd\xa0\x58\x20\x7e\x15\x8f\x14\x88\x39\x4f\xa6\x9c\x11\x5a\xcc\x25\xe5\x54\x62\x59\x45\xa1\x1a\x4b\xba\xd2\x81\x39\x45\x7a\xc6\x32\xfb\x41\xba\xba\x19\xb2\x17\xa9\x8d\x38\x31\xd5\x0c\x06\x49\x5c\x4d\x60\x3e\xaf\x89\x7b\xd2\xeb\xee\x11\xf1\x12\xbe\x43\xf8\x09\x72\xb4\xfe\x40\x09\xb7\x0f\x3f\xc5\x2c\xc6\xe7\x21\xc9\x35\xf2\x09\x4e\x9e\xd6\xc6\xd0\xd6\x46\x30\xfe\xf5\x3d\x19\x9f\xd3\xd1\xa2\x5f\x48\x8f\x47\xee\xa5\x3f\xc0\x5c\xc3\xcc\xec\x7f\xa9\x7c\x66\x2a\x46\x47\x8c\x8b\x90\x85\xe7\x25\x2e\xa9\x41\x2e\xa9\x46\x20\x18\x19\xb3\x68\xca\xe6\xcf\x00\xd3\xce\xbf\xbe\x78\x71\xf1\x87\x9c\x39\x17\xbc\x72\xfe\x0b\x11\xef\x23\x94\x0d\x84\x98\xca\xbe\x86\x9a\x5a\x80\xf7\x88\x2e\xdc\xe2\x2a\x36\xe4\xd2\x0e\xad\x0c\xa1\x23\xf4\x6e\x85\x6a\x83\x1f\xdc\x08\xec\xd8\xec\x00\x68\x06\x17\x00\x54\x01\x91\xda\x15\xb6\x20\xb2\x6a\x58\x24\x8a\x69\x22\xb5\x66\xbc\xca\x99\xd4\x91\xab\x60\xe6\x03\x15\xd2\x15\xf7\x98\x59\x4f\x6c\x9a\x13\x44\x2d\xc1\x21\xb9\x9c\x58\x86\x51\xc7\x94\x11\x5a\x04\x64\x06\xe6\x95\x85\xc6\x96\x75\x09\x9c\x38\x45\xe1\xba\xbc\x3e\x1d\x69\xc5\x86\x96\x14\xa6\x31\x4c\x42\x92\xd0\xe1\x74\x23\xc4\x0c\x05\x6b\x05\xad\x11\x27\xd8\x17\x8d\xd0\xce\x69\xf1\x61\x64\x88\x86\xa1\xdc\xed\x7a\x51\x65\xee\x84\x8d\xa8\x32\x7d\xc2\x5c\x54\x92\xd7\x4e\x99\x4b\x8d\xef\x2c\xaa\x2f\x81\x83\xf8\xc2\x13\x28\xc4\x6e\x11\xbf\x5c\x82\x6a\x6a\x14\xc3\x6f\x91\x80\x6d\x07\xc4\xb6\x43\x8c\x87\x13\xdf\xaa\x9c\x93\x9d\xac\xc0\x6a\xc0\xfd\xb0\x81\xc3\xea\x77\xa3\xcb\x8d\xec\xbf\x31\xc0\x05\x1b\xb2\x8a\xcd\xa0\xbe\xa7\x91\x49\x59\xb3\xd7\x33\xe8\x7a\x5d\xf5\x96\xb9\xb6\xc6\x05\xa4\x85\xe4\xd4\x21\xde\xaa\xa3\xb0\x77\xef\x70\x32\x66\xe6\x85\xd3\xc0\xbb\xda\xd7\x41\x16\xc7\xea\xa4\xc7\xc3\xce\x0a\x01\x17\x48\xc8\x62\xec\x9d\x03\xc5\x38\x5b\x37\x2b\xa2\xb9\x80\xe0\x05\xd6\xc2\x40\x7e\xcd\xe1\xdd\xdf\x38\xac\x9b\xba\xa8\x41\x3f\xf2\xda\xcf\xbf\xad\xeb\xaf\x17\x66\x92\x66\x75\xcd\x27\x34\x4b\xa1\x79\x29\xa8\xed\x9b\xe0\x03\xc1\x50\xdf\xea\xa1\x49\x0c\x45\xb9\xb0\x9e\x0b\x43\xad\x3c\x59\xef\x05\xba\xad\xa2\x45\x92\xa0\xf6\xf7\x45\xd0\x82\x64\x1c\xa0\x76\x9a\xa4\x74\x94\x72\x96\x51\x90\x59\xa4\x71\x46\x5c\x08\x00\xdf\x82\xbb\x0a\x74\xed\x1f\xd6\x09\xba\x02\x5c\x94\xf1\x22\x9f\x64\x8e\xb6\x4f\x46\x33\x33\x67\x19\x74\xbe\x8e\xea\xc9\xdf\xe9\xad\xb1\x09\x8d\x57\x00\x84\x2f\x7d\x6c\x17\x8b\x95\x9d\xc2\xbf\x11\x9d\x9b\xc4\x5b\x8d\x1d\x04\x79\x46\x13\xb3\x7c\x26\xf0\xe9\x2e\x97\x69\xc5\xb7\x11\x61\x4e\xf1\x4c\xd9\x8b\x7f\x8d\x24\x78\x21\xef\x92\x18\x9f\xc2\x84\x77\x06\xc6\x77\x1e\x2b\x13\x85\x2f\x5a\x94\xce\x02\x3b\x22\x66\xc5\x81\x0d\xeb\xf3\x77\x9e\xe4\xd9\xe6\x6b\x26\x5d\x2b\x44\xa0\xa4\x19\xb6\xd7\xc0\xf3\x3c\x4f\xda\xc8\x92\x15\x25\x4b\xcb\xed\xea\x22\xfc\x67\x08\x68\x2f\xee\x81\xa5\xdc\xc9\xb4\xab\x4b\xfd\x72\x15\xc0\x32\x9c\x22\xc8\x40\x0d\x2b\xb7\xd2\xe2\x2e\x38\x2d\x57\xfe\xf6\x41\x00\x8c\x5c\x7d\xf2\x2b\x06\xdf\x2b\xec\xcf\x92\x9b\xcc\xdc\xfb\x4b\xbc\x36\x20\x9c\x4b\x8f\x9d\xa7\x9e\x04\x04\xb3\xc7\x05\x02\xe2\xfc\x27\xbc\x38\x79\x1d\x16\xdb\xb4\x80\xc6\xc5\x31\x53\x40\xfc\x33\x8d\xfb\xc6\x43\x70\xe2\x1d\xfa\xa7\xba\xfb\x17\x37\x1a\xa6\xa4\x72\x3f\x75\x9c\xdc\x39\x34\xc1\xb8\xd7\x04\x93\x84\x55\x2c\x37\x73\xe7\x17\x06\x92\x29\xcd\x9d\x1f\x48\x2e\x70\xe7\x02\x46\xc0\x89\x14\xc9\x16\x37\xde\x0e\x19\xdd\xfd\xd0\xe8\x7a\x33\x18\xb5\x01\xd3\x2c\xfa\x6a\xb3\x10\xe4\xc8\xd7\xf3\x5f\x91\x51\x94\xf1\xc3\x92\x2c\x61\x00\x18\x8a\x1e\x99\xbb\x8b\x18\x87\xf5\xda\x65\xd1\x63\xd2\x3c\xee\x16\x95\x07\xb7\xb3\xcd\x64\x91\xc9\x82\x9a\xc3\x26\x75\x4f\x61\xa1\xd1\xb4\x9f\x0d\xe0\x4b\x3d\x97\x95\x48\xeb\xad\x43\x6f\x17\xe2\x66\x9e\xcd\x6e\xfe\x0d\x85\xf2\x60\xf4\xee\x2b\x36\xc5\x8d\x8e\xc6\x31\xbb\xbc\x70\xe7\x43\xba\x30\xb9\x10\x2c\xb9\x98\xb3\x33\x2b\xbd\x6c\x61\xcc\xaf\x90\xf8\x92\x78\x59\xbd\xe1\xb2\x36\xe1\xd2\x36\x41\x55\xeb\x2a\x4a\x1c\x24\xa5\x7c\x87\x50\xec\xfe\xf3\xe3\x84\xb7\x43\xd1\x32\xc4\xd0\xbf\xe0\x9b\x74\x31\x01\x00\xc0\xe4\x18\x19\x5c\x5b\xe2\x56\xce\x1a\x8d\x31\xbb\x19\x61\x27\x18\x08\xef\xa6\xc2\x7b\x9e\xd6\xc4\xc1\x38\x23\x97\x14\xac\x6b\x0d\xac\xad\xdf\x65\x76\xd4\x99\xde\x7c\x63\x47\x53\xf0\x0e\x04\x06\xa0\x94\x9a\x2c\x8b\x9a\x75\xf3\x31\x83\x2a\x7c\x1f\xa1\xe8\xfe\x70\x86\x0d\x91\x4c\xa6\x34\xf8\x9a\x37\xfc\x5e\xcf\x5c\xa7\xa5\x27\x9b\x99\x40\x4d\x15\x5f\x58\x4a\x4d\x57\x2a\xb5\x84\x5e\xde\x89\xbf\x51\x5f\x74\x8c\xb4\x5f\xdc\xb2\x55\xa8\x57\xf6\x9e\x11\xd8\xcb\x46\x6e\xfc\xdd\xea\xf9\xe9\x9d\xef\x95\x00\x4e\xee\x7c\xbf\xf8\x9d\x28\x7f\xed\xc4\x64\x78\x43\xd7\x4e\xe0\x82\x6b\x27\x10\xa4\xa2\x21\x37\x3d\xc7\xbf\x5a\x45\xff\x06\x00\x00\xff\xff\xf0\xe4\xf5\xb7\x1d\x35\x00\x00") + +func fontsColossalFlfBytes() ([]byte, error) { + return bindataRead( + _fontsColossalFlf, + "fonts/colossal.flf", + ) +} + +func fontsColossalFlf() (*asset, error) { + bytes, err := fontsColossalFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/colossal.flf", size: 13597, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsComputerFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x58\x5f\x6b\xe4\x36\x10\x7f\xf7\xa7\xf8\x61\x0b\xf2\x72\xac\xae\x81\xf6\xd4\xe3\x38\x0a\x7d\x2e\x84\x3e\x1b\xf6\xd2\x64\xd2\xa4\xc9\x66\x43\xb2\x61\x39\xd8\x0f\x5f\xf4\x67\xa4\x91\x2c\xd9\x5e\xee\xe9\x42\xd6\x33\x5e\x7b\x34\xa3\x99\xdf\xfc\xd1\xde\x3d\xdd\x5d\x5e\x2b\x7c\xc2\x6f\xb8\xfc\x88\x8f\xb8\xec\x6e\xf6\xbb\x97\xf7\x03\xbd\x6e\xee\x9e\xee\xf0\xcf\x77\xfc\xf5\xf0\x48\xf8\x7b\xff\xf6\xfe\x44\x8f\xf8\xb2\xfb\xef\xf5\x8f\x67\x3a\x3c\x3c\xbf\x6d\x9e\xe9\xf0\xf5\x03\x3e\xe9\x5f\x2e\xf5\xef\xbf\x6e\xf0\xe7\x3d\xdd\x3c\x62\xff\x7e\xc0\xee\x7b\x77\xbf\xdf\xd1\xcb\xf5\xbf\x84\xeb\xc3\x67\xdc\x1f\x0e\x2f\x9f\xb5\x3e\x1e\x8f\x9b\x24\xaa\xdf\xee\xf7\xc7\x9b\xeb\x37\xd2\xbb\x87\x47\x3a\xbe\x3e\xdd\xea\x4e\xa9\xa1\xf5\x19\x3a\xa3\x30\x74\xc6\x28\x79\x51\xe0\xef\x00\xf7\x0e\x2c\xdf\xa3\xf7\xcf\xd0\xbc\x5a\x01\x00\xb7\x57\xb8\xbd\xb2\xeb\x02\x86\xff\xdc\x62\xfc\xc4\xaf\xcf\x4f\xec\x5d\x7a\xc2\x8b\xf1\x5f\x71\x37\x74\x44\x86\xc8\x9a\x0a\x38\xbb\x0c\x91\xbb\xb7\xb7\xf6\x9e\x02\x35\x44\x41\xad\x53\x31\x74\xa6\x37\xd6\x02\xf7\xc8\x44\x0b\xbd\x5a\xcb\xb1\x65\xd6\x16\xd3\x5b\xd1\xdb\x2b\xc0\x50\x70\x09\xeb\x47\xda\x90\x35\xe1\x83\x77\x20\x59\xb3\x9c\x03\x9d\x59\xc8\x39\xfb\x54\x21\x5b\x26\xac\xc0\xee\xae\x5c\xac\xc5\x8a\x23\x54\x5c\x48\xf1\x3b\x7d\x5c\xa7\xb8\xb0\xdd\xc3\xd0\x8d\x27\xad\x86\x4e\x9f\xc6\xe5\x00\xe6\x21\x88\xde\x8b\x5e\xe7\xfb\xe2\xbd\xf6\x2e\xd2\x46\xc3\xcb\x25\x09\xe1\xab\x3d\x5b\x5a\x55\x25\xcc\x69\x8f\x00\xe8\x10\x55\x1d\x82\xaa\x43\x4c\x75\x58\x58\x17\x18\x1b\xbc\x01\x11\x51\x1e\x52\x33\x0c\xb9\x58\x4a\x79\x86\x70\x8d\x04\xa4\x04\xa2\x84\xc6\x80\xd8\x44\xc2\xba\x26\xa4\x87\xf4\x4a\x90\x40\x78\x57\x50\x06\x56\x04\x7f\x00\xbd\xca\x8c\x0b\x0e\x63\x86\x13\x24\x65\x48\xf8\x26\x32\x85\x73\xd8\x2c\x64\xd9\x06\x23\x68\xee\x16\x61\xb1\xe1\x24\x28\x16\x90\xe9\x3b\x11\x94\x2f\x00\xa0\x0b\x47\xe9\x42\x09\x44\x16\x48\x1c\x3a\x50\xf4\x52\x4c\x3d\xc4\xd4\xf3\xe9\x68\x54\xce\xe5\xfe\xaa\xea\x67\x03\x85\x93\x32\xda\xca\x80\xa2\x94\xaa\x15\xef\xf8\x2c\xb1\xcb\x91\x4b\x7d\x4f\x5d\x92\x38\x6a\xb9\xde\x90\xe2\xd4\xf4\xbc\x97\xe8\x0d\xe5\xfb\x28\x33\x99\x29\xef\x8f\x64\xe2\x49\x3f\xce\x6b\x98\xb7\x4e\x16\xb8\xbe\xef\x7b\x86\x48\xc4\x08\x85\x2e\x13\x36\xd3\x97\xe8\x4c\xc8\xb3\x64\xbb\x8d\x96\x6c\x2e\x80\x6f\x1b\x6f\x8c\x76\xa1\xc6\x68\xe3\x7a\xb2\x25\x9a\x0c\x70\xb2\xaa\x46\x18\x03\xc3\x55\xe0\xdb\x66\xbb\xdd\x5c\xa8\xa2\x89\x48\xdb\xa6\x79\x6d\x62\xdc\x27\x8c\x2a\xe5\x81\xb8\x42\x84\x76\x68\x4e\x26\xee\x3a\x63\xa9\x28\x1f\x15\x6b\x5c\xcd\xa7\x5a\xd6\x82\x22\x66\x6b\xd6\x64\xbb\x69\x6e\xa2\x25\x5f\xc9\x71\xc3\xb5\x28\xd2\x0c\x31\xe7\x08\xaa\x1c\x62\xb3\x3b\x06\x88\x96\x2c\x16\x65\x59\xe6\xa8\xab\x6d\x15\x9a\x14\xe7\x2d\xb4\x32\xf8\x70\x49\x43\xc9\x90\x2c\x90\x84\x34\x65\x90\xa9\x19\x07\xc9\x14\xd3\xc1\x02\xb8\xd8\x13\xd1\xab\x75\x6f\xd6\xc2\x61\xa2\x5b\x4d\x44\x42\xf2\xc5\x0c\x57\x24\x6e\xee\xdc\xba\x53\xa7\xce\xb5\x82\x4b\xfd\x73\x92\x70\xf3\x38\x2e\x2b\xc6\x94\x99\x95\xaf\x30\xdb\xed\xd6\x2f\x2d\x9b\xb2\xd8\xf8\x0f\x04\x2e\xd3\x0f\xb6\x7f\x35\x70\x5c\xf8\x54\xd6\xe1\x88\xc7\xe8\x1a\x55\xed\x74\x68\x45\xac\xe8\xb5\xf5\x6d\xb9\x77\x7a\x13\x5b\xa8\xe8\xa5\x72\x8a\x65\xc5\x42\xb7\x50\x2f\x34\x57\x58\x57\x27\x27\x75\x70\x12\xad\x34\x9a\xad\xf2\x7f\x1b\x64\xde\x65\xa8\x31\x95\xf8\xcd\x74\x2c\xc1\x54\xf0\xeb\x74\x57\x2e\x69\x5c\x1f\xe3\x60\x3d\xc6\xd6\x36\x86\x19\xd5\x73\x5e\xfd\xc8\x75\x07\x63\x8e\x11\xb3\x3c\xee\xeb\x71\xe6\x54\x91\x06\x91\xea\x74\xb0\x30\x35\xb8\x0d\x38\xe3\xd7\x2c\xde\x1a\xa5\x9a\x15\x84\xf7\xd9\x91\x18\x1f\xdb\xa9\x38\x89\x40\x7e\xa4\x88\x70\x54\x31\x72\x4e\xca\xa8\xec\x80\xd1\x30\x75\x21\x75\x0a\x55\xd9\xd4\x9e\x54\x51\xa9\x6a\x49\x42\x15\xa7\x9f\x86\x71\xdc\x01\xd0\xb7\x8d\x83\xaf\x36\xe7\x06\x60\xe8\xa8\xd5\x24\xf3\xe8\xba\xb5\x8b\x33\x09\x55\x0e\xe0\x95\xe8\xb2\xe8\x9a\x42\x5b\x44\xd7\xdb\xb7\xd0\x20\x8b\xc6\x18\x9b\x5b\x28\x28\x74\x46\x8b\xac\x4c\xd4\xcb\x58\xa9\xc2\x3a\x13\x34\x59\xbd\x6e\x9d\x85\x96\x13\xa9\x31\x60\x35\x05\x45\x1b\x8c\x5d\xf0\x07\x32\xb0\x1d\x23\xa1\xb8\x57\xd3\x5f\x69\x1a\xe0\x48\x82\x4b\x4d\x70\x05\xd6\xd7\x64\xb0\x57\x19\x67\xeb\xb2\x0b\xce\x35\xbf\xd4\xba\xbc\x6e\xa1\x7e\xbe\x0f\x56\x9b\x5f\x96\x1c\xa0\x95\x5d\x70\x62\x4d\x4d\x7e\xa6\x0b\xb6\x03\xd7\x17\x07\x7b\x99\x5c\x99\x1b\x01\xed\x86\x96\x93\x5f\xd9\x93\x2f\xa1\xa5\x65\x5f\x02\xe3\xd6\xff\xe6\x58\xff\x28\xd7\xe0\xb8\x07\x9e\x94\x24\xf8\xaa\xca\x2f\xb7\x9a\xdb\x9d\x5e\xfa\x5d\xcb\x5f\xed\x84\x05\x37\x61\x9d\xdd\x98\x2a\x82\xeb\x32\x38\x0a\x9e\x8b\xce\x9f\xc8\x54\x55\xf9\x1f\xba\xff\x03\x00\x00\xff\xff\x33\x14\x99\x35\x04\x17\x00\x00") + +func fontsComputerFlfBytes() ([]byte, error) { + return bindataRead( + _fontsComputerFlf, + "fonts/computer.flf", + ) +} + +func fontsComputerFlf() (*asset, error) { + bytes, err := fontsComputerFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/computer.flf", size: 5892, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsContessaFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x55\x4d\x4f\x1b\x41\x0c\xbd\xcf\xaf\xf0\x01\x69\x37\x69\xe2\xa1\x69\x25\xa4\x06\xa2\x91\xb8\xf5\xd4\x3b\x13\x39\x40\x83\x88\x84\x08\x4a\xe0\x50\xc9\xe2\xb7\x57\xf6\x7c\xac\x67\x49\x0e\x99\xec\xfa\x8d\x9f\x3d\xcf\x1e\xef\xd3\xcb\xd3\xe2\xfe\x02\x7e\xc2\x0f\x58\x5c\xc2\xfc\x3b\x2c\xdc\xed\xfe\xf5\x7d\x7b\x3c\xde\xc3\xc3\x3f\xb8\x7d\x3e\xec\x8e\xef\xfb\xb7\xe7\xed\x01\x7e\xef\x8f\xdb\xb7\x67\xf8\xb3\x3b\xec\x5e\x5e\xf6\xd0\xbf\xe9\xc3\xe3\xe2\xea\xea\x32\x3c\xee\x1f\x0e\xf7\xf8\xf1\xba\xc3\xed\xdf\x8f\x89\x73\x17\x17\xc1\xfe\x82\x03\x86\xb2\x4c\x65\x01\x08\xc1\x4d\xf5\x79\x03\x9b\x64\x29\x6b\x70\xc4\xc4\x04\xc3\x3f\x30\x70\x81\x75\x03\xd0\x92\x10\x82\xeb\x05\x87\xe0\x90\x98\x26\xba\x61\x53\xa8\xbd\xbc\x7a\x01\x7d\x09\x59\x3c\x93\x5f\x59\xc5\x47\x80\x69\x70\xd0\xc9\xab\xfe\xd4\x39\xb8\x5e\x5f\x63\x4d\x39\x3f\x4e\x32\x9c\x8c\xc8\x33\x08\x6e\x3e\x9d\x43\x70\x1d\x6f\x4c\xb0\x99\xb8\xcf\xbf\x09\x00\x9d\x39\x60\x39\x6c\x91\xa3\xcb\x46\xb5\x10\x11\x0c\x6f\x67\x3c\xb2\xd1\x9e\xd2\xf2\x93\x64\xc4\x28\x82\x33\xf1\x38\x23\xaf\x6a\x22\xe3\xd8\xa3\x53\x15\x3d\x9d\x01\x30\x8b\x9c\x4e\x0d\x33\xc3\x6e\x62\x60\x0a\x9e\x0b\x33\x19\x03\xbd\x02\xbd\x05\x48\x81\xb3\xe7\x48\x7b\x1b\x0f\x0b\x34\xc1\x8d\x44\x56\xa7\xd6\xd8\xd5\xfa\x5e\x8f\xeb\x9b\x55\xbf\xb9\xb9\x31\x7f\xd0\x14\x7f\xd5\x14\x1f\xa4\x58\x9d\x76\xc4\xd2\x18\xf5\x90\xbe\x5f\x4b\x6a\x91\xc8\x1b\x1a\x24\xc2\xe0\xee\x88\xd6\xc1\x31\x00\x1b\x7d\x84\xeb\x8e\x68\x52\x56\x18\xe8\x54\x99\x8d\x92\xe1\xc8\x83\x01\xa2\x08\x4e\xde\x02\xa4\x24\x89\x90\x4e\x02\x6c\xa5\xce\xc1\x21\xc1\x68\xa8\x00\x50\xd9\xf9\x4b\xba\x98\xef\x74\xbe\x47\x59\xc0\x94\x1e\x6b\xaa\xfc\x85\xc6\xd7\x84\x07\xa0\xe6\xc2\x4d\xaa\xc9\x23\xfa\x2f\x81\x33\x00\x0a\xc4\x46\x40\x2c\x7b\xb9\x09\x6e\x94\x1d\x9f\xda\x7a\xc4\x73\x1e\xd1\xd6\x02\xa5\xf3\x48\xbb\xdb\x14\x49\x94\xc5\xd4\x8d\x60\xfe\x9a\x94\x4f\x64\xa6\x40\x04\x10\xc1\xa3\x87\xf1\x21\x93\x87\x37\x87\xcc\x7b\x57\xd7\xa9\x25\x5a\x21\x67\xc2\x82\xfe\x44\x02\x25\x3b\x2d\x00\xfa\xda\x45\x02\xde\x7d\x6a\xe9\xf5\xc0\xb5\x87\x23\xe4\xbb\xa1\x96\x68\xae\xd8\xe7\x5a\x9e\x65\xa1\x75\xd9\xed\x23\x34\x43\xaa\xde\xa6\xb2\x92\x2d\x6d\x9a\xfb\x76\xd8\xa6\xc9\xa7\xca\x56\x4e\x4c\x2d\xa1\x69\x4d\xda\xbb\x9c\x76\xe2\x60\x94\x47\x91\xd5\xb8\xe7\x9d\x32\x27\xfc\xac\x72\x52\x70\x3c\x13\x61\xdb\xc8\x90\x5d\x91\xb8\x8d\x0c\x43\xe4\xe0\xa6\xc1\x49\x21\x86\x79\x3c\x55\xa1\x1b\xb7\xa5\x5c\x43\xce\x75\x11\xa3\xfa\x0c\x6e\x69\x2c\x42\x22\xe7\x4c\x3f\xa4\x82\xe3\xa8\x26\xbf\xd6\x88\x55\x19\x3e\xad\x21\x0f\x3b\x31\xd7\xb7\xe1\xa4\xe0\xca\x4c\x4d\x9f\x06\xfd\x56\x95\xef\xb4\x09\x04\xca\xc9\x6d\x59\x31\x77\x9b\x6f\x86\x6f\x81\x0a\x58\xe1\x81\x2e\xca\x70\xf1\x5d\x6c\xb3\xd1\x6b\x40\x55\xca\xdc\x33\x52\x56\x5f\x87\x8b\x70\xad\x84\xa1\x14\x4f\xbf\x6f\x60\xaa\x19\x75\xa6\xa7\x9d\xa5\x2f\x73\x03\xfb\x13\x1f\xd5\xfd\x1e\x4e\x8e\xb6\x04\xf8\xcd\x26\xa6\xe9\x3d\x02\x7e\x01\x2c\x47\xf7\x38\x13\x2b\xdc\x13\xcf\x46\x1e\x69\x82\xf7\xcd\x50\x57\x20\xa9\xd8\x52\x95\xe1\x9c\x2a\xbb\xaa\xc0\xff\x00\x00\x00\xff\xff\x79\xe8\xd6\x6a\xad\x09\x00\x00") + +func fontsContessaFlfBytes() ([]byte, error) { + return bindataRead( + _fontsContessaFlf, + "fonts/contessa.flf", + ) +} + +func fontsContessaFlf() (*asset, error) { + bytes, err := fontsContessaFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/contessa.flf", size: 2477, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsContrastFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\xcd\x8e\xd4\x30\x0c\xbe\xcf\x53\xf8\x40\xc4\x05\x0c\x8c\xf8\x11\xb7\x95\x40\x48\x1c\x56\x1c\x78\x82\xee\xd2\x59\xaa\x5d\xa5\xa8\xad\x84\xe6\xed\x11\x9d\x99\xc6\x8e\xed\x38\xd3\xdb\x4a\x1d\xed\x21\x72\xe2\xf8\xef\xb3\xbf\x74\x0f\x4f\x87\x7d\xf3\x02\x3e\xc2\x07\xd8\xbf\x85\xd7\xef\x60\xbf\xfb\xd2\xc7\x69\x68\xc6\x09\xbe\xf5\x71\x82\xbb\x23\x7c\x6d\x63\xec\x46\xb8\xed\xe3\x23\xc0\xa7\x37\x9f\xdf\xef\x7e\x0c\xdd\x43\x17\x9b\x27\x38\xf4\x71\x7a\x05\xdf\x61\xfa\xdd\xc5\x47\x04\xb8\x6d\x8e\x77\x2d\x74\x71\xfc\xd3\x0d\xed\xaf\xff\xca\x7d\x6c\xa1\x3f\xc0\xcf\xfb\x66\x68\xef\x87\xfe\xef\xcb\x11\x70\xec\x1e\x46\xdc\xe1\xf9\x77\x73\xfd\x6a\x5e\x86\x70\x11\x6a\xab\xa4\x92\xcb\x6e\x76\xb3\x28\x04\x64\x2b\x0c\xf3\x5f\x85\xe5\xe5\x60\x98\x7f\xe8\xca\x98\xf2\x65\x3b\x04\xbc\x38\x36\x8b\xce\xce\x2e\x7e\x25\x99\xe6\xf6\x29\x2c\x1e\xdf\xbc\x9d\x05\x25\x2c\x5f\xf6\x97\xa8\x03\x26\xe9\xec\x13\x3f\xeb\xe7\x1c\x95\x9c\xab\x05\xc3\x90\x6c\x9e\xb6\x43\x3a\xb8\xc8\xc8\x39\x1a\x39\xdb\x4e\x77\x07\x2e\x63\xe7\x16\xe5\x73\x29\x4e\x35\x09\xac\x50\x42\x4a\xce\x3a\x91\x13\xfd\x02\x02\xcd\xc4\xd4\xa4\xd2\x50\xa6\x96\xbd\x9c\x9b\xdb\x55\x6e\x87\x90\xe7\x9c\xa1\x2d\xa1\x49\xc5\x39\x62\xd6\x6b\x04\xfb\x09\x7f\x12\xe7\xcc\x4a\xa1\xcb\x65\x1e\xc4\x8d\xb9\x95\xe4\xac\xaa\xcc\x84\x24\xe6\xfc\x42\xb5\x3d\xe9\xb6\x8c\x99\xa5\x53\xb6\x27\x4f\x8e\x1c\x0c\x8e\x65\xad\x2c\xb2\x02\x6a\xb6\xad\x98\x57\xd7\xb9\x2c\xab\x56\xd6\x7c\x30\xb0\x5d\x33\xf6\xd7\x2a\x97\x1b\x23\x41\x51\xbf\x50\xc2\x13\x6d\x00\x96\x3b\xbb\xc2\x8a\xe6\x4d\x39\xdb\x5a\xc5\xd5\x61\x90\x94\x17\x96\xa0\x2b\xa4\xcc\xb1\x76\x18\xa8\xbc\xa5\xe1\xb8\x2c\x73\x2d\x23\x41\xb4\xd7\x18\x8a\xb2\xda\xe3\x76\x57\xf1\x91\x93\x17\xc8\x19\x43\x9e\xb2\x5b\x67\x4c\xdc\x5e\x33\x7a\xcd\xf8\xaa\x4b\x55\x60\xc4\xe2\xdc\x2e\x4f\xca\x6b\xdc\x4e\x6f\x81\x40\xa2\x97\xc8\x97\x5d\xe5\xad\x54\xb7\xe9\x68\x46\xfa\xb8\x23\x15\x14\x4b\xcb\xf9\x40\xc3\xa8\xc9\xb9\x85\xf0\xca\xb4\x79\xbd\x75\x35\xc5\x1b\x38\x5b\xdf\xd5\x6e\xcc\x36\x57\xba\x74\x57\x02\xa9\x3a\x06\xbd\x41\xb0\xa2\xb7\x8a\xc4\x67\xe0\x8c\x2e\xd9\x17\x83\x78\xd4\xeb\xf6\x0d\x92\xf5\x9a\xa4\xe4\xa8\x93\xb6\xda\x27\x46\xf5\x30\xbc\xa6\x3d\xc5\x23\x82\xd2\xbb\x00\x8d\xe1\xb6\x18\x49\x88\xfa\x23\x4f\x7d\xc4\x5a\x99\x5d\xf9\x70\x2f\xc6\x6c\x94\xa5\xe2\xc2\x8d\xab\x37\xae\xde\xb8\x7a\xe3\xea\x8d\xab\x37\xae\x5e\xc5\xd5\x67\x83\xf9\x04\x41\xcd\x72\x2d\x6f\x55\xac\xd8\x04\xc9\xe8\x5d\x7a\xa3\x7f\xdd\xa6\x6f\x5a\xff\xbf\xc0\x56\xb6\x91\x21\xbc\xae\xb7\x0c\xe5\x3a\xd2\x93\xca\x2b\x10\xfe\xac\xdc\xce\x67\x1e\x9b\x65\x8e\xf4\x74\xc5\xbf\x00\x00\x00\xff\xff\x92\x0a\xba\xc5\xf3\x18\x00\x00") + +func fontsContrastFlfBytes() ([]byte, error) { + return bindataRead( + _fontsContrastFlf, + "fonts/contrast.flf", + ) +} + +func fontsContrastFlf() (*asset, error) { + bytes, err := fontsContrastFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/contrast.flf", size: 6387, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCosmicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\x6d\x8b\xdc\xca\xd1\xfd\xde\xbf\xa2\xe8\x6e\xd3\x0f\xa6\xdc\xf3\xd8\x21\x37\x1d\x75\x1c\x42\x0c\x17\x02\x11\x11\x09\x26\x88\x5e\x5b\xf2\xce\xac\xaf\x1d\x7b\x46\x97\xeb\x35\xce\x85\xfb\xe3\x43\x9d\xea\x96\xb4\xf6\x26\x21\xdf\x57\xac\x76\xf4\x32\xaa\xae\x3a\xe7\xd4\x8b\xe6\xed\xc7\xb7\xcf\xde\x3c\xa2\xef\xe8\x3b\x7a\xf6\x94\xfe\x9f\x9e\x99\x17\x7f\xf9\x5b\xff\xa7\x17\xf1\xfb\x3f\x7f\x4f\xd7\x3f\x53\xff\xfe\xc3\x0d\xfd\x75\xf9\xf4\xf9\xe3\xcd\x07\xfa\xdd\xf9\x1f\x3f\xfd\xe1\x72\x73\xfb\xfe\xf2\x29\x5e\x6e\x6e\x7f\xcf\xf4\x9b\xc3\xd3\xa7\x87\xdf\xfe\x3a\xd2\x1f\x3f\xff\xf0\x89\xde\xbe\xff\xe7\xcd\x49\xae\xfd\x4a\xae\x99\x17\xef\x6e\x8e\x1f\x68\xf9\x7c\x4b\xe7\x9f\xe9\xdd\x72\xbe\xf9\xf1\xcd\x0f\x37\xf4\xe6\xb6\xa3\x77\xb7\xb7\x3f\x76\x87\xc3\x97\x2f\x5f\xe2\x66\xee\xf0\xe9\xdd\xf2\xe5\xf8\xe6\xd3\xcd\xe1\xfc\xfe\xc3\xcd\x97\x9f\x3e\x9e\x0e\xe6\xd1\x23\x77\xdf\xee\x0c\xc5\xce\x99\x9c\xb3\x33\xa1\x14\x67\xc8\x7b\x67\xc8\x5a\x67\xa8\xef\x9d\x33\x5d\x47\x5d\xe7\x8c\xcd\x94\xe5\x9a\x6c\xf7\x7f\xe0\xb3\xeb\xb0\x3b\x33\x4d\x9c\x03\x76\x67\x42\x28\x45\x77\x67\x88\xbd\xc5\x4e\xce\x2c\x29\x2d\xd8\xc9\x19\xee\x2d\xc9\x5e\x0d\xc5\x4e\x2d\x73\xce\x39\x92\x33\xa5\x30\x4f\xb3\x5c\x99\xad\xb5\xe3\xe2\x0c\x8d\xcb\xc4\x27\xb8\x14\xfa\xd0\x1e\x8b\x24\xcf\xce\xce\x50\x26\xca\xc4\x19\xcf\xd0\xeb\xd7\xc4\x65\x6e\xbe\x1e\x07\x62\xc6\x31\x27\x4b\x89\x28\x39\xc3\xa7\x41\x6e\x59\x0b\x43\xdd\x95\x2e\x1f\x73\x0e\xe4\xcc\xff\x95\x69\x92\xf3\xa3\xb7\x70\xdc\x8e\x0b\x2f\x03\x8c\xd9\x9e\x01\x92\x33\x2c\xd1\xd1\x9d\x5d\x23\x71\x86\x61\xe5\x52\xe4\xf2\xe8\x71\x33\x2d\x2c\x77\x2d\x20\x8e\xb8\x14\x32\x2e\x95\x8b\xfc\xf7\xa3\x33\xbc\x24\x72\x46\x40\x51\x70\xc9\x99\xab\x5f\x0e\xe4\xcc\xe1\x97\x2b\x6a\x57\x76\xff\xbf\xe5\x05\x2b\x7a\xd9\xe4\x2c\x7d\x45\xd6\x37\xff\x4e\xe9\x1a\x4c\xb8\x7b\x8c\x9b\xe3\xf1\x78\xfc\x76\xb9\xfb\x6d\x8c\xfd\xd0\xbc\x39\x80\x0d\x39\xa8\x5c\xd0\xa5\x04\xfd\xf6\xd1\x5b\x7d\x6e\x49\x56\xed\x9e\xa1\x80\x2d\x94\x6a\x96\x73\x66\x39\x62\x79\xb2\x5c\x10\x93\xdc\x93\xb0\xc6\xc4\xe0\x51\x44\x3b\x9e\xcf\x03\x1e\xee\xa2\x48\x5a\x64\x23\x5f\x75\x26\x25\x67\xa0\x66\xe1\xa3\xab\x78\x73\x0e\xf3\x0c\x75\x51\x08\x44\x5c\x8a\x30\x18\x8f\xde\x0f\x41\x23\x49\x34\xf1\x22\x44\xf5\x7d\xff\x72\x78\x6c\x5f\xbf\xd6\x7c\x11\x03\xf2\x8d\x1c\xe6\x50\x5d\x13\xdd\x5d\x4a\xd1\xc3\x79\xb6\xde\xfb\x08\xd7\x79\x49\x09\xde\xd1\xd8\xf7\xc3\xca\x65\x44\x96\x88\x0f\x39\xd7\xc8\x4a\x91\xc0\x86\x69\xf2\xfe\xe8\x8c\xe8\xbc\x3e\x48\xd4\xf7\x88\xaa\x6e\xce\xcc\x39\xcf\x73\x08\xd9\x19\x2a\x85\x27\x85\x69\xb6\xf6\xf1\x08\x8e\xa6\x89\x97\x53\xd2\x14\x1e\xec\x86\x67\xac\x91\xcb\xb2\x1a\x01\x97\x12\x97\x53\xba\x56\x99\x58\x22\x0b\xa9\x8c\xe9\x9a\xf9\x94\x20\x71\x3b\x36\xb7\x63\x8c\x75\xfd\x10\x04\xba\x1c\xaa\xd9\x12\xd4\xaa\xf7\x95\xd9\x94\x52\xa5\xae\xef\xfb\xba\x3e\x9e\x15\xb4\x05\x73\xf1\x40\xc5\x7e\x29\x48\x45\x48\x41\xe2\xa6\xf1\x9a\x27\xde\x2f\xad\xb4\x31\xc3\x77\xce\x00\x9d\x51\x12\x68\x62\x94\xac\xd1\xfb\x41\x1d\x67\x9e\x58\x23\x27\xbb\x43\x5b\x9e\x63\x29\x70\xe1\x5e\x95\xde\x7f\x7b\x4b\x04\xe5\x97\x25\x3d\x55\x25\x47\x8f\x8b\x36\x5d\xb7\x34\x5e\xf5\x4e\xbb\x4f\x96\x0d\xf7\x2d\x0a\x2a\x2d\xcb\xb2\xac\xe7\xab\x6d\x66\x7c\x84\xa2\x50\x28\x0e\x95\xc1\xb1\xa5\x7f\x7c\x22\xf8\x3d\x81\xb0\xc3\x2c\xe8\x67\xf5\xea\x52\x2a\xfc\x27\x3f\xd4\x7c\x92\x32\x46\x2b\x01\x5b\x46\x09\x05\x41\xb7\x35\x0b\xa4\xc2\x49\x95\xcd\x39\x73\xcc\x34\xe7\xe8\x4c\x27\x42\x2e\x51\xa9\xc5\xb1\x36\x06\x26\x0a\xa3\x97\xfc\x18\x91\x24\x28\xbe\x63\x5a\xa0\x40\x82\xec\x96\x1a\xff\x6c\xc7\x97\x3d\xb6\x97\x63\xa3\xa1\xab\x89\x83\xaf\xe4\x3c\xe7\xdc\x70\x2a\x85\x10\x3d\x6a\xac\xf7\x47\xfc\x43\x99\x84\x90\x52\x4a\x02\xe3\x88\x58\xac\x9d\x77\xc9\xd0\x82\xc8\x21\x68\xad\xa6\x52\xca\x34\x95\x72\x15\xe1\xb2\x20\x3d\x8a\x34\xa6\x94\x16\x16\x50\x07\x67\xac\x3a\xb7\x69\x0b\xd8\x76\x55\x5f\x80\x77\x86\x92\x8b\x04\xbf\x16\x22\xaf\x55\xa7\x9e\xcd\x49\xd8\x97\x98\x95\xb5\x16\xf0\x60\x37\xef\x9e\x34\xf7\x84\x61\x95\x2d\xcd\xd5\x26\x30\x55\x50\xb5\x92\x21\xce\x89\x97\x34\x84\x9a\x39\xfd\x60\x67\xcd\x3c\xee\x56\x0f\x33\x82\x0d\x9a\x69\xa5\x48\x59\x56\x14\x35\x58\x3d\x4e\xd2\x56\x79\x9a\x08\xbd\xbc\xc6\x2b\x86\x34\xd2\x00\x33\xb0\x82\x20\x99\x9f\x3f\x97\x90\xa4\x06\xcc\xf3\x06\x3c\x1e\xef\x7b\x5e\x05\x54\x91\x3a\x54\xa8\x9e\x34\xa8\x56\xac\x0a\xb6\x83\x33\xd6\xfb\x23\xd8\xb6\xde\xa3\x3a\x8d\x02\x17\xca\x21\x52\x80\xe6\x30\xf6\x2f\x07\x3b\xd6\xba\x2c\xc1\xa1\xed\x6b\xd7\x27\x02\x6a\xa8\x50\x85\x59\xfe\x13\x8c\x4a\x90\x5e\x4d\xaa\x8f\x56\x0d\x6a\xa1\xa1\xb1\x0e\x2d\x6d\xa6\x29\xda\x02\xd0\x03\xd0\x04\xfa\x56\x0b\x5b\x35\xeb\x54\x3f\xba\x49\x38\xe8\x07\x33\x09\x51\xb1\x25\x28\x48\x9a\x95\x7f\x98\xba\x5e\x96\xe5\xd4\x30\xb2\x7d\xdd\x6c\x4b\x35\x70\x15\xa9\x89\x53\x06\x09\x8e\x2a\xce\x52\x0e\xe0\x6e\x92\xb6\xcc\xd5\x80\xf4\x08\x11\x28\xd5\x48\x6c\xd5\x91\x1a\xda\xec\xd4\xc3\xa6\x4b\xb0\x1e\xea\x21\x46\x29\x8e\xd3\x24\x02\xdf\x51\xde\x24\xab\x23\x95\x38\x42\x40\x37\x57\xd6\x0a\x4b\x02\x6a\xf1\xf1\x75\xab\x10\x0b\xc2\x63\x92\x21\x09\x20\x03\x63\x19\xb6\x6c\xdf\x60\x86\x2d\xf9\x44\x53\x82\xd0\x5b\x69\x42\xac\x91\x42\x13\xba\x27\x3b\xfa\xe3\xaa\x74\xb0\x25\x9c\xb4\x26\x21\xe4\x6d\xe4\xb4\xf8\x62\x65\x26\xd6\x76\x85\xeb\x57\xa5\x30\x9c\x05\x7e\x04\x7e\x05\x43\x9e\x68\xe2\xb4\x36\x8f\x7e\x4d\xf2\x6e\xdd\xd0\xef\x67\xa5\x3a\x56\x4f\xe7\x57\xaf\x2e\x97\xcb\xab\x57\xa1\x96\x5f\xef\xad\x5d\x4b\xb9\x84\xbe\x15\x76\x31\x7a\x4d\xfb\x96\xa6\x18\xd4\xce\x34\xeb\x40\xb0\x55\x8e\x52\xca\x95\x26\x03\x11\xca\x1a\x06\x95\xc7\x92\x0b\x63\x4a\xd7\xac\x43\xe4\xe3\x71\xb0\x64\xfb\x5d\xe5\x88\x91\x5a\xb2\xa3\xd6\xe7\xc6\x3b\x1f\x4a\xa9\x03\x94\x52\x75\xa4\x35\xe5\xaf\x25\x19\xb4\x25\xf5\x8a\xa9\xfd\xbb\xbd\xeb\x29\x4c\xce\x50\x33\x5a\xce\xf3\xe7\x07\x70\x8f\x52\x1e\x20\x25\x0f\x63\x08\xf2\xd4\x90\x3c\xf7\xe3\x57\x38\xd6\x0c\xcb\xad\x1c\xd5\x6e\xb6\x09\x53\x89\xd9\x9f\xa5\xc4\xbb\xb3\x4a\x3a\xbc\x8b\x4d\x46\x90\x39\x55\x7d\x0a\x8a\xa1\xa1\xd8\x66\xbe\xca\xb6\xea\x27\x9e\x90\xd5\x98\xfc\x90\x7f\x15\x41\xfd\x62\x84\x2c\x75\x42\x43\x8f\x03\xbf\x57\xe2\x62\x2c\xe5\x50\x5d\x19\xfd\x31\x62\xf4\x69\x0c\xa7\x34\xec\x3b\x79\x3f\xb4\x92\xef\x4c\x54\xd3\xfa\x96\x81\x41\x08\xc6\xc5\xe5\x66\x1e\x7d\x4c\xf7\xd0\x2c\x7a\xf4\x33\x3f\xac\x36\x2d\xd2\x3d\xed\xd0\xb0\x92\xf3\x76\xeb\xd4\xbc\x05\x01\x85\x6a\x6a\x45\xc6\xb4\x28\xd7\x65\x1d\xde\xd6\x90\x55\x3c\x56\xd0\xf3\x65\xb0\xf3\x2c\xef\x29\x90\xe6\xd9\xd6\x18\x6c\x7f\x66\x6d\x03\x9a\x60\x3a\x51\x50\x40\x7e\xa1\x0c\x2a\x91\x62\xbd\xec\xad\x1f\xf7\x10\x71\x42\x63\xaa\xa7\x6d\x68\x57\xdf\x77\xf2\x40\x73\x58\x07\x15\xcc\xc7\xa1\xce\x89\x18\xcd\x0c\x27\xed\xa1\x6d\x7a\x7d\xb9\xcd\xb9\x18\x73\x90\x47\x54\xc7\x7d\xe1\x9c\xf1\xf2\x85\xda\x33\xe3\x1d\x4d\x07\xdf\x7c\xd5\x7c\x09\xe5\xd2\x9c\xb4\x92\x19\x0d\xee\x65\xc3\xf9\xbc\xae\x20\x61\x6b\xa1\xd2\x02\x25\x9d\x47\x9b\x84\xd6\xde\xa8\xf9\x12\x68\xce\xdf\xbe\x5a\x7d\xfd\xe6\xbb\xbb\xf0\x5f\x0e\xce\xba\x21\x86\x5a\x8d\xf8\xbe\x17\xae\xd5\xf6\xc3\xdc\xf4\x30\x37\x3d\xcc\x4d\x0f\x73\xd3\xc3\xdc\xf4\x30\x37\x3d\xcc\x4d\x0f\x73\xd3\xbf\x9b\x9b\xf0\x43\xbe\x7c\x53\x48\xb7\xce\x24\x94\x58\xcc\x19\x92\x66\xf7\xfc\x1c\xaa\x3c\x3b\xa3\x3d\x42\xf4\xeb\x0c\xb2\x29\x74\xb1\x0b\x72\x97\xe6\xfd\xfc\xf3\x9f\x27\x1b\xfc\x92\xa5\x79\x8d\xdf\xd7\x43\xa8\xd3\x4a\xa8\xbf\x0f\xee\xc6\x15\xba\x3b\xaf\xdc\x1d\x58\xee\x4e\x2c\xda\x44\xaa\xd6\x99\x61\x77\xab\x6e\x9a\x41\xfb\x02\x47\xb5\x6c\xae\x35\x4e\xc7\x8c\x5d\x99\x6b\x6a\x5a\x2b\x5d\x5d\x66\xcb\xa7\xb6\xce\x96\x54\x75\xa1\x5d\x66\xd5\xd8\x77\xe9\x55\xaf\xec\x72\x6c\x1d\x46\xd7\x44\x7b\x00\xea\x7f\x02\xea\xd1\xd7\x7f\xce\xfc\x2b\x00\x00\xff\xff\xdf\x73\xc9\xcc\x69\x1b\x00\x00") + +func fontsCosmicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCosmicFlf, + "fonts/cosmic.flf", + ) +} + +func fontsCosmicFlf() (*asset, error) { + bytes, err := fontsCosmicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cosmic.flf", size: 7017, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCosmikeFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\xdf\x6b\xe4\xc8\x11\x7e\xef\xbf\xa2\xe8\xee\xa1\x2f\x4b\xb9\x27\x7b\x21\x97\x8e\x3a\x1b\x0e\x42\x1e\x05\x22\x60\x82\x68\xef\xaa\x3d\x9a\x71\xec\xd8\x33\x7d\xac\x7d\x31\x07\xf7\xc7\x87\xaa\xea\xd6\xe8\x62\xef\x42\xc8\xbd\xc5\xc2\x9a\x69\x69\xa4\x52\xd5\xf7\x7d\xf5\x43\xbe\x79\xb8\xf9\xf6\x7a\x03\xdf\xc1\x77\xf0\xed\x7b\xf8\x2d\xfc\x4e\xcd\xe5\xf1\x78\x37\xfb\x9b\x87\x1b\xd8\xfd\x04\xfd\xdd\xfd\x01\xfe\x56\x1e\x7f\x7c\x38\xdc\xc3\x9f\x8e\xff\xfc\xfc\xfd\xe9\xf0\x74\x77\x7a\xf4\xa7\xc3\xd3\x9f\x11\xfe\xb0\x7d\xff\x7e\xfb\xc7\xdf\x7b\xf8\xcb\xed\x61\xbe\x87\xf2\xe3\x13\x1c\x7f\x52\xb7\xe5\x78\xf8\xe1\xfa\x1f\x07\xb8\x7e\xea\xe0\xf6\xe9\xe9\x87\x6e\xbb\x7d\x7e\x7e\xf6\xe7\x5b\xb7\x8f\xb7\xe5\x79\xbe\x7e\x3c\x6c\x8f\x77\xf7\x87\xe7\xcf\x0f\xfb\xad\xba\xb8\xb8\xb8\x80\xbe\xec\xef\x6e\xee\x0e\x7b\xb8\x3e\xed\x61\x2e\x9f\x3f\x1f\xe6\xa7\xc3\x5e\x3c\x99\x6f\x0f\x0f\xf0\xd7\x9b\xa7\xbb\xe3\xf5\xfd\xdd\x23\x7c\x23\x67\xfc\x72\xe6\xfb\x7f\x3d\x3c\xde\xf9\xb9\x1c\x7f\x03\x64\x4b\x6d\x36\x9b\x8d\xf9\xfa\xa7\x51\xe0\x3b\xa3\x62\x8c\x46\xb9\x94\x8c\x02\x6b\x8d\x02\xad\x8d\x82\xbe\x37\x46\x6d\xba\x0e\xba\x8e\x2e\xd7\x11\xa2\xde\x18\x05\xb2\x7d\x6d\xc1\xab\xae\xe3\xdd\xa8\x69\xc2\xe8\x78\x37\xca\xb9\x94\x64\x37\x0a\xd0\x6a\xde\xc1\xa8\x12\x42\xe1\x1d\x8c\xc2\x5e\x03\xed\xd5\x90\xef\xc4\x36\xc6\x18\x3d\x18\x95\x12\xe2\x94\xe9\x4c\xd6\x5a\x8f\xc5\x28\x18\xcb\x84\x7b\x72\x19\x5c\xef\xda\x6d\x1e\xe8\xde\x6c\x14\x44\x80\x08\x18\xf9\x1e\xf8\xf4\x09\x30\xe5\xe6\xed\x3c\x00\x22\xaf\x31\x68\x08\x00\xc1\x28\xdc\x0f\xf4\x93\xd6\x6c\xa8\xbb\x92\xc7\xfb\x18\x1d\x18\xf5\x4d\x9a\x26\x3a\x9e\xad\x66\xc7\xf5\x58\xb0\x0c\x6c\x4c\xf7\x68\x8c\xea\x3a\xa3\x90\xa2\x83\x5f\xec\x12\x89\x51\xc8\x56\x4e\x89\x4e\x8f\x96\x7f\x0c\x05\xe9\x57\x4d\x70\x77\x9e\x4f\xb9\xc8\xa7\xd2\x89\x3e\xed\x68\x14\x96\x00\x46\x11\x28\x02\x2e\x18\x75\xf5\xf3\x16\x8c\xda\xfe\x7c\x05\xed\xcc\xea\xf3\x0b\xec\x24\x5e\x6c\x2c\x6d\x42\x65\x78\x49\xdc\x8b\x8f\x7d\xd8\x31\x2b\x8b\xd5\x97\xdf\x9b\x79\x9e\xe7\xcd\x8b\xf3\x5f\xb1\x37\xf6\x43\xb3\xb7\x65\x96\x68\x51\x39\x82\x53\x72\x72\xf5\x6c\xb5\xdc\x57\x82\x16\xcb\x47\x56\xc6\x3a\x44\xa1\x2f\x46\xa4\x15\xd2\x9d\xe9\x04\x46\x59\x4b\xbf\x91\x9c\xc7\x80\xcc\x2f\x09\x7b\x3c\x1e\x07\xbe\xb9\xf3\x24\x7b\x92\x13\x5d\x6a\x54\x08\x46\xb1\xe2\x89\xa7\xae\xf2\x80\xd1\xe5\xcc\xaa\x03\xe7\x00\x30\x25\x62\xd6\xcf\xd6\x0e\x4e\x22\x09\x30\x61\x21\x02\xfb\xbe\xbf\x1c\xde\xe9\x4f\x9f\x24\xa7\xc8\x00\x5d\x11\x5d\x76\xd5\x35\xd2\xe3\x29\x25\x59\xe6\xac\xad\xb5\x9e\x5d\xc7\x12\x02\x7b\x07\x63\xdf\x0f\x0b\xc7\x9e\xb3\x87\x7c\x88\xb1\x46\x96\x12\x05\x36\x4c\x93\xb5\xb3\x51\xa4\xff\x7a\x23\x40\xdf\x73\x54\x75\x33\x2a\xc7\x98\xb3\x73\xd1\x28\x48\x09\x27\x81\x29\x6b\xfd\x6e\x9c\x67\xa3\x60\x9a\xb0\xec\x83\xa4\xf9\xa0\xcf\x78\xfa\x1a\x39\x3d\x56\x22\xc0\x94\x7c\xd9\x87\x1d\x43\x4a\x74\x68\x2e\x11\x63\xd8\x21\xee\x03\x4b\x5f\x8f\xcd\x6d\xef\x7d\x7d\xbe\x73\x04\x5d\x74\xd5\x6c\x72\x62\xd5\xda\xca\x6c\x08\x4d\x7a\x7d\xdf\xd7\xe7\xf3\xbd\x84\x36\x61\x4e\x1e\x48\x12\x9c\x12\xa7\x28\x4b\x81\xe2\x86\x71\x87\x13\xae\x1f\x2d\xb4\x21\xb2\xef\x18\x19\x74\xe4\x52\x01\x13\x72\x59\x1b\xad\x1d\xc4\x71\xc4\x09\x25\x72\xd0\x2b\xb4\xe9\x3e\xa4\x22\xe8\x5e\x55\xe9\xeb\x3f\xaf\x92\x82\xbf\x90\xd2\x56\x54\x32\x5b\x3e\xa9\xc3\xae\xa5\xf7\xf0\x6a\x56\x6e\x90\x36\x2a\xb0\xa0\xb5\xe6\x02\xbb\x29\xa5\x14\x5e\xc8\x99\xe5\x09\x88\xfc\xe5\x92\x00\x22\x68\x54\x1e\xc7\x56\x1c\xfc\x05\xa1\x78\xc1\xf2\x76\x99\x38\x88\xe2\xdb\x29\x55\x12\xf6\x76\xa8\x59\x45\x45\x0e\x16\x1a\xce\x79\x45\x44\x38\xd9\x96\x5c\xa0\xfa\x47\x35\x38\xc6\x88\x3e\x42\x8e\xde\xa8\x8e\xe4\x9c\xbc\x10\xcc\x6b\x69\x21\x08\xe0\x46\x4b\x59\x32\x72\xaa\x70\x69\x1e\x43\x61\x1d\x02\x8b\xaf\x54\x10\xb2\x1e\x2f\x7b\xde\x2e\xc7\x46\x46\x57\xd3\x87\x2f\x89\x31\xc7\x58\x0f\x30\x25\xe0\xe8\xb9\x02\x5b\x3b\xf3\x07\x17\x51\x96\x53\x08\x81\xc0\x1e\x39\x16\xad\xf3\x2a\x25\x5a\x10\xd1\x39\xa9\xe4\x90\x52\x9a\xa6\x94\xae\x3c\xbb\x4c\x50\x8f\x24\x90\x29\x84\x82\x04\xea\x60\x94\x16\xe7\xce\x0a\x63\x6c\xbb\xaa\x32\x86\x37\xb3\x9e\x13\x05\xbf\x70\x6a\xa5\xf6\xd4\xa3\x1c\x48\x03\x14\xb3\xb0\xd6\x02\x1e\xf4\xd9\xbb\x8b\xe6\x1e\x31\x2c\xe2\x85\x5c\x6d\x32\xa6\x02\xaa\xd4\x33\x8e\x73\xc2\x12\x06\x57\xf3\xa7\x1f\x74\x96\xfc\xc3\x6e\xf1\x30\x72\xb0\x4e\xf2\x2d\x25\xaa\xd0\x82\xa2\x04\x2b\xeb\x40\x4d\x17\xa7\x09\xb8\xeb\xd7\x78\xc9\x90\x44\xea\xd8\x0c\x5b\xe1\x20\x11\x3f\x7c\xa0\x90\xa8\x12\xe4\x7c\x06\x9e\x6f\xef\x7b\x5c\x04\x54\x91\xda\x56\xa8\x2e\x1a\x54\x0b\x56\x89\xb7\xad\x51\xda\xda\x99\xd9\xd6\xd6\x72\x8d\x1a\x09\x2e\x2e\x8a\x85\x25\x92\xdd\xd8\x5f\x0e\x7a\xac\xd5\x99\x82\xe3\xa1\x40\x66\x02\x00\x46\x8d\xeb\x54\x42\xa4\x4f\x60\xa3\x14\xa4\x15\x93\xe2\xa3\x16\x83\x52\x6e\x40\xcc\x71\xa9\x8a\xd2\x07\xb8\x11\x70\x27\xe0\x56\xd0\xb7\x8a\xd8\x6a\x5a\x27\xfa\x91\x8d\xc2\xe1\xae\x90\x81\x88\xf2\x2d\x41\x99\xa4\x2c\xfc\xb3\xa9\x5d\x29\x65\xdf\x30\xd2\x7d\xdd\x74\x4b\x35\xe6\xca\x43\x13\x27\x8d\x19\xe8\x45\x9c\x29\x6d\x99\xbb\x89\xba\x35\x56\x03\xd4\x29\x48\xa0\x50\x23\xd1\x55\x47\x62\xe8\x6c\xa7\x2e\x9b\x2e\x99\x75\x57\x97\x3c\x68\xa1\x9f\x26\x12\xf8\x8a\xf2\x26\x59\x19\xb8\xc8\x11\x60\x74\x63\x65\x2d\x21\x25\xa0\x14\x1f\x5b\xb7\x0a\x31\x21\x3c\x06\x1a\xa1\x18\x64\xc6\x98\x46\x31\xdd\x37\x98\xd9\x16\x7d\x73\x6b\x62\xa1\xb7\xd2\xc4\xb1\x7a\x70\x4d\xe8\x16\xf4\x68\xe7\x45\xe9\xcc\x16\x71\xd2\x5a\x05\x91\x77\x26\xa7\xc5\xe7\x2b\x33\xbe\x36\x2d\x3e\x7f\x95\x12\xb2\xb3\x8c\x1f\x30\xbf\x84\x21\x4e\x30\x61\x58\x5a\x48\xbf\x24\x79\xb7\x6c\xdc\xf5\xb3\x50\xed\xab\xa7\xf9\xe3\xc7\xd3\xe9\xf4\xf1\xa3\xab\xe5\xd7\x5a\xad\x97\x7a\x4e\xa1\x9f\xab\x3b\x19\xdd\xc1\xba\xb1\x09\x06\xb5\x3f\x65\x19\x0b\xce\x95\x23\xa5\x74\x25\xc9\x00\xc0\x65\x8d\xc7\x95\x77\x94\x0b\x63\x08\x3b\x94\x11\xf3\xdd\x38\x68\xd0\xfd\xaa\x72\x78\x0f\x2d\xd9\xb9\xd6\xc7\xc6\x3b\x6e\x53\xaa\x63\x94\x50\x35\xc3\x92\xf2\x3b\x4a\x06\x69\x4c\xbd\x60\xaa\xff\xae\x7f\xe9\x29\x9b\xcc\xac\x66\x6e\x39\x1f\x3e\x6c\x99\x7b\x2e\xe5\x8e\xa5\x64\xd9\x18\x07\xb9\x6f\x48\x1e\xfb\xf1\x3f\x70\xac\x19\x16\x5b\x39\xaa\xdd\xec\x2c\x4c\x21\x66\x7d\x14\x02\xae\x8e\x2a\xe9\xec\x9d\x6f\x32\x62\x99\x43\xd5\x27\xa1\xe8\x1a\x8a\x6d\xf2\xab\x6c\x8b\x7e\xfc\x9e\xb3\x9a\xe7\x3f\xce\xbf\x8a\xa0\x5c\xe8\x59\x96\x32\xa7\x71\x8f\x63\x7e\xaf\xc8\x45\x9f\xd2\xb6\xba\x32\xda\xd9\xf3\x00\xd4\x18\x0e\x61\x58\xb7\xf3\x7e\x68\x25\xdf\x28\x2f\xa6\xe5\x1d\x84\xc7\x21\x36\x4e\x2e\x37\xf3\xdc\xc7\x64\x77\xcd\xa2\xe5\x7e\x66\x87\xc5\xa6\xe6\x74\x0f\x2b\x34\x34\xe5\xbc\x3e\x77\x6a\x3c\x07\xc1\x0a\x95\xd4\xf2\xc8\x33\x23\x9d\xa7\xe7\xe0\xf9\x19\xf4\x14\xcb\x4f\x90\xe3\x32\xe8\x9c\xe9\x2d\x86\xa5\x79\xd4\x35\x06\xdd\x1f\x51\xda\x80\x24\x98\x4c\x14\xe0\x38\xbf\xb8\x0c\x0a\x91\x64\x3d\xad\xad\xcf\x6b\x88\x30\x70\x63\xaa\x87\x6d\x74\x17\xdf\x57\xf2\xe0\xe6\xb0\x0c\x2a\x3c\x25\xbb\x3a\x2d\xf2\x80\xa6\x30\x48\x0f\x6d\x33\xec\xe5\x79\xda\xe5\x31\x87\xf3\x08\xea\xd0\x4f\x9c\x23\xbf\x9a\x71\xed\xc9\xfc\x06\x27\xe3\x6f\xbc\x6a\xbe\xb8\x74\x6a\x4e\x6a\xca\x8c\x06\x77\x39\xe3\x7c\x5c\x9e\x40\x61\x4b\xa1\x92\x02\x45\x9d\x47\x9a\x84\xd4\x5e\x2f\xf9\xe2\x20\xc7\xf5\x34\xf8\xe2\xeb\x0b\x6f\x65\x5f\x5a\x1c\x65\xe3\x18\x6a\x35\xc2\x57\xde\xf5\xce\x6f\x7c\x6f\x73\xd3\xdb\xdc\xf4\x36\x37\xbd\xcd\x4d\x6f\x73\xd3\xdb\xdc\xf4\x36\x37\xbd\xcd\x4d\x5f\x9a\x9b\xf8\x5f\xfe\x74\x25\x91\xae\x8d\x0a\x5c\x62\x79\xce\xa0\x34\x7b\xe5\x9f\xa2\xc2\xb3\x51\xd2\x23\x48\xbf\x46\x71\x36\xb9\xce\x77\x8e\x7e\x85\xbc\x9e\x7f\xbe\x3e\xd9\x50\x10\x40\xc9\x22\x0d\xf7\x7f\x9f\x55\xc8\x10\x69\xbc\xda\xfb\x75\x4a\x1a\x50\xff\x02\xfe\xfb\x75\xb2\xe6\xff\x30\xe4\xff\x6e\x84\x84\xd5\x08\x09\x7d\x9f\xc7\xe6\xd7\xbf\x03\x00\x00\xff\xff\x16\x77\xec\x28\xa6\x1b\x00\x00") + +func fontsCosmikeFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCosmikeFlf, + "fonts/cosmike.flf", + ) +} + +func fontsCosmikeFlf() (*asset, error) { + bytes, err := fontsCosmikeFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cosmike.flf", size: 7078, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCricketFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x5d\x8b\xe3\x38\x16\x7d\xf7\xaf\x38\x03\x0d\xe9\x86\xd8\x9e\x34\xb3\xcd\x76\x18\x96\xcc\x0c\x53\x45\x0d\xfb\xb0\xec\x3c\x34\x0b\x01\x95\x2b\x96\xcb\xa2\x1c\xab\xc7\x92\xdb\x5b\x60\xf6\xb7\x2f\xfa\xb2\xe5\xc4\x29\x3b\x1f\xb3\x6c\x68\x2a\x72\x2c\x9d\x7b\xef\xb9\x57\x47\x1f\x9d\x15\xd9\xc7\xe4\x1d\xfe\x8a\x1f\xb0\xfa\x01\xdf\xe3\xe3\x0a\xdf\x63\xf5\xe9\xe3\x5f\x3e\x05\xbf\x54\x6c\xf7\x42\x25\x9e\x5e\xf1\x77\x2a\x0a\x46\xf1\x73\x22\xa9\x80\xfd\xfc\x96\x94\x11\x56\x4b\xac\x3e\x7f\xfe\x14\xec\x4c\xdf\xcf\x9b\xa4\xe2\x22\x2a\xa9\xb4\x9d\x72\x29\xbf\xae\xe3\xb8\x69\x9a\xc8\xbd\x89\xff\xe3\x3a\x07\x0f\x68\x98\xc8\x21\x39\x64\x9e\x94\x2f\xf8\x92\xa4\x14\x77\xac\xdc\xe5\xb4\x42\xc6\x2b\xc8\x9c\xe2\xf7\x87\x7b\xf5\x5a\xa2\x49\x04\x6a\x41\x53\x24\x02\x09\x9e\x12\x41\x75\x1f\xe7\x66\x22\x82\x86\x16\x85\x7a\xfb\x4b\x5e\x31\x81\x7b\x56\x14\x68\x72\x8e\x94\x0a\xf6\x5c\xd2\xd4\xc0\xfd\x51\x27\x95\x1a\x59\xca\x25\x04\xdf\x53\xf0\x0c\x4d\xce\x76\x79\x6f\x80\x95\x70\xd1\x47\xf8\xa9\x4c\x91\xb1\x32\x29\x8a\x57\x1c\x3a\xfc\x8f\xa4\x2e\xf0\x73\x5d\x49\x5e\x2e\xb5\x29\x96\x81\x19\x4f\x4b\x2e\xb5\x7b\x39\x13\x08\x94\x07\x15\x55\xe3\x76\x15\x4d\x24\xc5\xdd\xc3\xfd\x17\x56\x2e\xf1\x80\x7d\xf2\x8a\x92\x7e\xa3\x15\xf2\xe4\x1b\x45\x9e\x18\x37\xf7\x5c\xb2\x6f\x89\x64\xbc\xf4\x46\x25\x08\xee\x1e\xee\x95\xeb\x51\x60\x21\xc0\x84\xee\xff\x85\x95\x29\x6f\x04\x76\x05\x2f\x75\x48\x77\x0f\xf7\x05\x95\x68\x98\xcc\x91\x20\xab\x8b\x02\x19\x4d\x64\x5d\xd1\x14\x16\x04\x34\x65\x92\x57\xdf\x05\xb8\xe3\xd5\xb3\xa2\xf0\x89\xd7\x12\x29\x67\xe5\xb3\x71\x22\x91\x3a\xd8\x8c\x3d\xd7\x15\x85\x7a\xa9\x7e\x16\xfb\x5a\xe4\x7b\x9e\x52\x94\xf5\xfe\x89\x56\x11\xf0\x5b\x2d\x24\x76\x39\xdd\xbd\x20\x09\x90\xd1\x06\x4f\xfc\xdf\x54\x68\x06\x68\xb2\xcb\xcd\x18\x85\x5b\xd5\x05\x8d\x30\xb4\x48\xcb\x74\x9f\x54\x2f\x02\x61\x08\xe5\xb4\x32\xb2\xe3\xfb\xaf\xb5\xa4\x55\xe0\x5b\xcf\x79\x03\x99\xa8\x24\x97\xa9\x7e\x68\x58\x4a\xf1\xca\xeb\x4a\x27\x14\x4c\x38\x5f\xd2\x2a\x69\x5c\x9c\xc2\xb0\x20\x73\x1a\x60\xcf\x6b\x41\xf5\xf0\x86\x7d\xa5\x2e\x9c\xf4\x99\x1a\x07\x78\x96\x19\x38\xb1\xab\x28\x2d\x91\x55\x7c\x0f\x65\x50\x57\xe0\x8e\xd7\xa5\x64\xe5\xf3\x77\x81\x4f\xbf\xe6\x96\x67\x8e\x5e\xb1\xc4\x53\x2d\xc1\xe4\x42\xf4\x95\xa7\x78\x50\x86\x9f\x5e\x91\xe8\xd0\x0a\x2a\x29\x58\xca\xb8\x8c\x80\x87\x2c\x50\x56\xf1\x47\x9d\x14\x2c\x7b\x5d\xe2\x1b\x13\xcc\xd0\x60\xcd\x34\xf4\x49\x30\xa9\x88\xfb\xdd\x38\x26\x72\x2e\x05\x54\x25\x8b\x9c\x37\xe5\x52\x87\xc4\x33\xe5\x62\x25\xa8\x81\xdb\x25\x25\x52\xde\x94\x05\x4f\x52\x30\x65\xe8\xfd\xdd\x3f\x7f\xfd\xf5\xbb\x0f\x41\x80\xd1\x8f\x9d\xad\x39\xdf\xd3\x88\x26\x95\xcc\x0b\x56\xbe\x98\x39\x2b\x78\x51\xab\x6a\x0c\x02\xfc\x54\x08\x0e\x41\xa9\xf3\x4f\x97\x99\xf1\x6f\xdd\x61\x08\x19\xaa\x49\xbf\x13\x51\xcd\xea\x5d\x44\xd3\x3a\xae\x05\xad\x44\xbc\xcb\x13\x16\x67\xec\xb9\xa0\x32\xca\xe5\xbe\x08\x02\xbc\x7b\xb7\x19\xff\x03\x78\x7f\xd4\x5f\x42\xd4\x43\x0b\xb4\xea\x8b\x10\xef\x0b\xae\xe3\xd1\x97\x19\xe8\x86\xda\xc1\x68\x49\xdb\x8d\xeb\xfa\xbe\xdd\x30\x2d\xa2\xb1\xcc\xef\x44\xa1\x29\x2c\x8d\x4d\x6c\x47\xeb\x96\xff\x04\xed\x26\x51\xfd\x37\x03\xf2\xdf\x7c\x32\x9e\x2f\xc3\x65\x17\xf7\x02\x8b\x2e\x6a\xdd\xc7\xb6\xf5\xc7\x86\xd3\x2a\x2b\x03\xa8\x93\x6d\xcb\xa9\x23\x47\xfb\x67\x20\x4d\xa4\x0e\xdd\xe3\xf8\x00\xe3\x44\xf3\x2d\xcf\x31\xc4\xbe\xca\xf3\xbe\x1a\xd0\x4e\x94\x81\x57\x0d\x2e\xe0\xe5\xc2\x25\x4b\xa7\xd1\x36\xf4\xab\xc7\x88\x90\xb7\xeb\xc3\x96\x15\x5c\xea\x1f\x23\x93\x67\xeb\x0e\xe9\xab\x94\x2c\x17\xd3\x40\x20\x5e\x3c\x1d\xca\xdf\x74\x97\x1f\x5d\x76\x0e\x13\x31\x9f\x2b\x6d\xc2\x2b\x5a\xaf\x62\xbd\x02\x9d\x93\xda\xe0\x10\xd8\x67\x78\x66\x4a\x0e\xf0\x4c\x11\xa0\x2f\x88\xf3\x8a\x6d\x8e\x47\x73\x44\xc2\x14\x86\x69\xc5\x40\xac\x5a\xcb\x85\xfa\xb7\x09\x10\x13\x12\x0f\x8c\x4d\xb4\xfa\xb8\x1c\x25\x20\x6e\x72\x45\xba\x4c\x8e\xdb\x6b\x60\xd5\xb5\xd7\x51\x84\x48\xb7\x1f\x43\xf3\x59\x8c\xcc\x80\x0e\xbe\x07\x77\x70\x8f\xa1\x06\x37\xc9\x5d\xf7\xad\x75\x64\x5a\x8f\x43\xc8\x31\x8f\xe1\x29\x8c\x83\x55\xd4\x10\x45\x46\xef\xf1\x16\xe7\x79\x3c\x42\x89\x6f\x80\xbc\x27\xe4\x1a\x4a\xe0\x19\xf8\x97\x27\x68\xad\xaf\x97\xce\xd8\x80\x1c\x9f\x9e\x23\x82\x26\x22\x00\xb0\x22\x9e\xac\x5d\x97\xd4\x09\x03\x91\xee\xbe\xc5\x4d\x0d\xf8\x39\xd0\x69\x46\x0c\xa7\x69\x70\xda\xe0\xb7\x35\x41\xa3\xc2\x3c\xab\xee\xff\x14\x8a\xba\x08\xb6\xd7\xe5\xc0\x57\x8d\x33\x34\x64\x74\xe0\x3c\x39\x34\x9d\x95\xdc\xe8\x7e\xb1\x4e\xc1\x26\xc0\x56\xc5\xa2\x5f\xa9\x45\x69\x72\x4d\xf2\x7e\x1c\xd5\xd5\x8b\x24\xd6\x06\xe3\x16\xbb\xc7\xc8\xbc\x55\xae\xe9\x57\x56\x2e\x5b\xb5\xd6\x4d\xee\xa1\x7c\xaf\x6c\x56\x16\x4b\x60\x19\xea\x7e\x6d\x18\xda\xfa\x5a\x84\xe1\x59\x3a\xeb\x15\x04\xf1\x4a\xa2\x1d\x14\xc8\x31\x13\x07\x64\xcc\xdb\x94\x9d\x2c\xf0\xd5\x89\x02\x6f\xbd\xfa\x6b\xd7\x7d\xfd\xe1\xcd\x02\xf7\x2d\x98\xd9\x6e\x4d\xc4\xf0\x6c\x0c\x74\x40\x67\xc4\x55\xb9\xce\x4a\x57\xe6\xc3\x50\x26\x23\xf1\xc4\xa6\x75\x7d\x2e\x9c\xaa\xf0\x23\xd9\x02\x9e\x1a\x6c\xfd\x07\xeb\xbc\x8d\x24\xf6\xac\xe8\x80\x1f\x5d\x20\x97\x47\x42\xc8\x87\xab\x22\x99\x63\x00\xf0\x92\xee\xd6\x46\xd7\xb6\xa2\x79\xa6\x6c\xfa\xb9\xb8\xf9\xda\x78\xcb\xb2\x75\xe0\x9d\xb7\xfe\xf7\xda\x03\x73\x54\x38\x90\xb9\x4b\xd3\x6d\x28\xf0\x39\xf8\xe0\x4d\xac\x18\xde\xc4\xda\x0e\x12\xb9\xed\x33\x19\x01\x1f\x7c\x22\xc6\xcb\xd1\xa9\x87\x5b\x96\x06\x85\x7e\x8b\x89\x75\x2a\x99\xe8\xdb\x5b\x25\xcd\xd7\x68\xd0\x70\xe2\x4e\xec\x5e\x07\x06\xba\x6d\xe8\x94\xc8\xfd\xb9\xdb\xe3\x19\x32\xed\x26\xd7\x4d\x67\xec\xac\x08\x7a\x8a\xc2\xb6\xdf\x78\xaa\x1f\x16\xa7\x0c\x6c\x2d\x68\xe1\x04\xd2\xce\xd8\xd5\x55\x0b\xcd\xff\x6a\x37\x8b\xe1\x31\xc5\x3f\xa8\xd8\xc1\x36\x86\xfe\xb0\x32\xbd\xd9\x3c\x35\x0f\x6e\x2b\x19\x17\x18\xc0\x56\x1b\x88\x6f\x11\x41\xac\xe4\xc8\x19\xc0\x59\x49\x1e\xa8\x1e\xde\xfb\xb2\xa7\x45\xae\xd3\x3d\x73\xb8\x73\xc2\x87\xd8\x57\xbe\xf7\x6b\x65\x67\x6d\xa5\xef\x94\xf6\x4d\x1e\xc2\x7a\x6a\x54\x4d\x11\x77\xc2\x38\x3f\xe9\x93\x47\x98\xab\xcf\xa9\x1d\x7a\xbf\x91\xdc\x04\xfe\x7d\xdf\x8c\x2b\x22\xbb\x0c\xd8\x6d\xbc\x7d\xfb\x18\x75\x3b\x68\x75\x4c\xd9\x4e\x6c\x71\x8f\x37\xbb\x76\x1b\xde\x9d\xe9\x47\xee\x9c\x66\x5d\x5e\xf5\xd3\xd2\x0c\x8b\xb7\x97\xdd\x89\x1e\xf8\x79\xd8\x1c\x3d\x87\x4c\x0c\xdb\x1c\x5f\xf7\xb6\x27\xce\x5d\xa7\xee\x96\x36\x01\xa2\x30\x0c\xa3\x30\x32\x28\xa4\x67\x27\xf2\x5d\x98\x45\x3a\xba\xb5\xbc\x0d\x47\x00\xc9\x99\x80\xbe\x83\x1d\x1c\x99\x97\xbc\x43\xf2\x0d\x4d\x91\x3e\x37\xb5\xb7\xf1\xac\x73\xcd\xf9\x16\xfa\x47\xa6\x33\x01\x6d\xee\x23\xef\xb6\x15\xdd\xd5\xfd\xd9\x75\x76\xe8\x99\x17\xea\x39\x41\x9f\xce\x6a\xaf\x25\xed\xb9\xa1\x0e\x4e\xff\xc3\xff\xa6\xc0\xdb\x05\x6b\x0f\xff\xae\x73\x77\x65\xe0\xe9\x9a\xb3\x75\xf4\xfd\x56\x28\xfd\xd5\xf1\x65\xa1\xf4\xe7\xe6\xd9\xa1\x1c\x25\x2a\xf4\xa9\x1d\xb2\x7b\x78\xf4\x9e\xfb\x70\xba\x1c\xae\xc8\xde\x38\xe0\xcd\xa7\x12\xe9\x17\x43\xe2\x4d\x83\x5b\x78\xd8\xdf\xde\xcd\x08\xfe\x94\x0c\xdd\x6c\x6e\x12\x82\x30\xbc\x94\x3b\xef\xce\xa0\x3d\x58\x89\xcf\x16\xc8\xce\xb3\xa8\x0b\xb2\xbd\x4d\x56\x8f\x00\xf5\xb5\x63\x3c\x05\x33\x06\x38\xc0\x1c\xc0\xfa\xae\x1e\x5d\x56\x5d\x3a\x63\x9c\x09\xe2\xd1\x1a\xdd\x94\x8a\x4b\x14\xd9\x07\x74\x65\x14\x86\xb8\x7e\xf1\xd1\xf3\xa4\x1d\xbf\x56\x6d\xe7\xed\x96\x46\xf4\x70\x4a\x16\x37\x07\xff\x47\x68\x77\x30\x23\xd7\xa6\xfd\xe6\xe6\x74\x21\xf7\xa1\x2c\xac\xdd\xe5\xc4\xb0\x51\x20\x2f\x57\x9a\x64\x1b\x49\x78\xb1\x70\x9e\x00\xbc\x5c\x38\x07\x80\x6d\x07\x78\xf9\x9c\x1d\x7a\x18\x8d\x78\x78\xe6\x86\xf0\xff\x3f\xe4\xa3\x83\x37\x21\xe6\xea\xc0\xb6\x7f\xdc\xf4\xd7\xe1\x71\xbf\x08\x0d\x65\xe3\x64\x7b\x13\xfc\x37\x00\x00\xff\xff\x78\x67\xe6\x4a\x39\x26\x00\x00") + +func fontsCricketFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCricketFlf, + "fonts/cricket.flf", + ) +} + +func fontsCricketFlf() (*asset, error) { + bytes, err := fontsCricketFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cricket.flf", size: 9785, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCursiveFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x57\x5d\x6f\xa3\x56\x13\xbe\xe7\x57\xcc\x45\x24\x40\x32\x4c\x12\x65\x57\x1b\xc9\xb2\xc8\x7b\xf1\xaa\x5d\xa9\x52\x2f\x5a\xed\x5e\x20\x9d\x10\x38\x89\x69\x6d\xb0\x00\xaf\xeb\xca\x3f\xbe\x9a\x99\x73\xf8\x26\x71\xeb\xc4\x98\x8f\xf9\x3a\xcf\x3c\x33\x73\x78\xdd\xbd\xde\x27\x37\xf0\x19\x1e\xe0\xfe\x16\x6e\xe1\xee\xce\x71\xfe\x97\xd4\x3a\x83\xb2\x80\xf4\x58\xd5\xf9\x0f\xed\x7d\xf6\xe1\xe5\x0c\x5f\x93\x02\xbe\x95\xbb\x46\x57\x40\x9f\xf5\x1f\x49\x91\x46\x69\x95\xef\x43\xad\xd3\x3a\x3c\xee\xf3\x74\x1b\xea\xec\xb8\x21\xd5\xfb\x07\xf8\x7a\xdc\xc1\xdd\xe3\x97\x4f\xce\xff\xf3\xb7\x9d\x6e\x82\xfc\x6f\x9d\x41\x52\x64\xac\xfd\x72\x86\x6f\xba\xc8\xf4\x6e\x07\x3f\xe5\xe9\x9f\xba\x80\xf5\x69\xcb\x27\xd1\x21\xa9\x92\xba\x7c\x6d\xc2\xb4\xdc\x6f\x58\xb8\x2c\x00\x3e\xc1\x2f\x49\x05\x77\x8f\x8f\x0f\x0e\xdd\x7a\xca\x32\x9d\xc1\x3e\xaf\xeb\xbc\x78\x83\xc3\xb1\x48\x9b\x63\xd2\xe4\x65\xc1\x1e\x8a\xe3\xfe\x45\x57\xb5\xf3\xb4\xdf\x93\x13\x71\x69\x3e\xb4\x12\x5d\x55\x49\x06\xbf\xe6\xba\x4a\x35\xad\xe4\xc0\x67\x51\x7a\x48\x8a\xb0\xac\xde\x36\xad\x30\x79\xfe\x02\x4f\xc7\x37\xb8\xbf\xbd\xbd\x67\xcf\xbf\x17\x99\xae\xea\xb4\xac\x34\xbb\xca\x92\x7a\x0b\xdb\xe4\x87\x86\x17\xad\x0b\x38\x1e\xb2\xa4\xd1\x19\x34\x25\xec\x49\x24\xdd\x95\xb5\xde\x9d\x61\x9f\x34\xe9\xb6\x07\xa8\xe3\x18\x0f\xbf\x6d\x35\x80\xab\x5c\x48\xb7\x49\x95\xa4\x84\x6e\x5e\x43\x53\x69\x36\x93\x17\x90\x40\x7d\xd0\x69\x9e\xec\xe0\x94\x9c\x43\x80\x9f\x1b\xd8\x27\x67\x78\xd1\xd6\x42\x5e\xd4\xba\x32\xc2\xcd\x56\x43\xa3\xff\x6a\x20\x29\xce\xa7\xad\xae\x34\x9c\xcb\x23\x9c\xf2\x7a\x4b\x11\xed\x74\xf1\xd6\x6c\x35\xd9\x84\xb4\x2c\x02\x6b\xa1\xd0\x69\x43\x30\xee\xf2\x82\x96\xd1\x9c\x68\x25\xcd\x89\x14\x9a\x46\x57\x75\xe8\x38\x37\x37\xd1\xdc\x37\x62\x13\x7c\x44\x3a\x22\x9d\xbb\x74\xa7\xb4\xf7\x41\x84\xe8\x4e\x19\x39\x2e\xb8\xe6\xb2\x3d\x88\x36\xeb\x07\x18\x60\x10\x39\xfc\x03\x91\x83\x80\xad\x95\xde\x2f\x9d\xac\x58\x10\x3c\x85\xf2\x00\xc1\x07\x56\x74\x67\x15\x3c\xbf\x17\x1f\xab\x20\x78\x7e\x2f\x7a\xb6\xea\xf9\x7c\x85\x31\xfd\x78\x00\xdf\xe9\x2a\x46\x88\x8d\x25\xfb\x13\x39\xb4\x9c\xc8\x71\xf9\x84\xff\xe9\x91\xc2\xce\x78\x77\x84\x11\x10\xd8\x1e\x15\x2e\x0a\xf1\x55\xcc\xe1\x06\xc1\xf7\x20\x60\xc3\x31\x4c\xe3\xe8\xe0\x67\x51\x34\xa2\x30\x23\x6a\xff\x6d\xe0\x94\xc0\x1b\x73\x08\x48\xaf\xbb\x94\xcc\xf6\x14\xda\x35\x4e\x61\x9c\x0b\x5f\x29\x93\x14\xf0\x45\x90\x14\x3c\x65\x93\x35\xc9\xa6\x62\x69\x16\x65\x93\x63\x76\x18\x7b\x20\xf6\xc2\x20\x70\xc5\xde\x12\x3b\x46\x0a\x00\x01\x19\x56\xcb\x01\xc8\x35\x72\x10\x6e\xc0\xd2\x00\x38\x87\x22\x28\xa5\x5a\x88\xdd\x20\x08\xc5\xb0\x3f\x9f\x9b\x0e\x2c\x25\x11\x8f\x39\x27\xd6\xc8\x2d\x13\x7a\xba\x76\x59\x89\x67\x56\x8e\x66\xe1\x73\xee\x54\xdf\x45\x97\xa1\x71\x6e\xda\x43\xd9\xd6\x65\x1f\xea\xf9\xc7\xae\x3c\x46\x8a\x30\x72\x98\x88\x5c\x14\xfc\xed\xeb\x31\x91\xf8\xd0\x5b\x45\x2b\x6f\xf4\x7b\x7a\x26\x51\x12\x35\x5a\x87\xb3\xc0\x9b\x4b\x25\xa9\x2a\x63\x59\xad\xe0\x37\x16\x1d\x11\x50\x32\x8a\x00\x9e\x7a\x9f\x30\x9d\xc2\x9a\x14\x88\x31\xea\x2a\x05\x11\x78\x87\xe2\xf3\x35\x81\xe4\xe0\x43\x85\x67\x09\xc9\x78\x50\xab\x45\x85\x16\x0d\x04\xee\xb3\xd4\x25\x57\xa2\x86\x03\x85\xc1\x19\x9d\x52\xeb\x5b\xb1\xbb\xe7\xc0\xbd\x98\x15\x99\x08\x83\x75\x17\x62\xef\x84\x28\x47\x27\x2b\xa2\x87\x6f\x29\x47\x50\xb7\x58\x2f\xa8\xd1\xc7\x9a\xbc\x10\x1c\xab\x20\x08\x2e\xac\x1f\x2b\x84\x58\x2d\xa8\xa9\xb6\x18\x60\x23\xd7\x28\xb5\xc8\x2e\xd7\x0a\x47\x90\xa8\x2e\x3a\x13\xdc\xda\xf6\x2c\x7f\x09\x43\xee\xcb\x5d\x23\x6f\x11\xed\x4a\x48\xf1\x9f\x98\xf5\x4d\x32\xd1\x74\x2e\xb7\xcf\xb0\x31\x56\xca\x6a\x0d\x18\x70\x0d\x29\xdd\xab\xda\xe8\xc4\x83\xf4\xc9\x61\xe6\xaf\x20\xa5\xa7\x62\xeb\xe1\xf9\x5a\x0f\xf1\xc2\x1a\xcc\x48\x35\x33\x95\x1d\x59\xda\xcf\x17\x96\x1a\xb2\x98\x1e\x32\xa5\xae\x61\x31\xd3\x91\x94\x0d\x1f\x6d\x4f\xef\xd5\xe6\x47\xca\x7d\x2e\x7b\xed\x08\x88\x11\x96\xb8\xac\xa0\xaf\x67\xfb\xae\xa1\xa4\xa7\xbc\x01\x29\xe7\x7c\x32\x41\x65\xd4\x03\x6d\x39\x4c\x42\xe2\x59\x78\x66\x0a\x0e\xac\x2b\xea\x24\x7c\xc7\xa2\x85\x56\xad\x1b\x32\xb6\xa4\xa3\xf1\x80\x1d\xce\x0c\x54\x93\xc9\x11\xdb\x3d\x89\x00\x22\x0f\xe2\xe9\x78\x11\xd3\xed\x2e\x41\x4d\x67\x10\x76\x93\xa3\xff\xed\x6d\x38\x54\xb7\xe1\xe0\xdd\xc7\xf3\x70\x9f\x35\x18\x0f\x4a\x85\xc2\x8c\xcb\xec\x20\xe8\x4f\x60\x45\x0b\xf3\xdf\x19\x89\x2a\x64\x1c\xc7\xe0\x58\x61\xde\xb3\x29\xa9\x90\xae\x6b\x0f\xdc\xb5\x96\xa8\x1f\xe1\x8c\x25\x6b\x4a\xf6\x01\x68\x36\x1a\x62\x0d\x37\xfc\x7c\x8d\xa3\xf0\xc5\xe2\x8a\xfd\xfa\xdc\xf0\x2e\x10\x39\x17\x5c\xd8\x65\x20\xe0\xa4\x67\x59\x98\x4b\x6a\x93\xd1\x60\x70\x8f\x66\xad\x8c\x7d\x34\x84\xa0\x89\xee\x2e\x6d\x67\x10\xd6\x53\x47\x86\x4a\x28\x44\x64\x14\x66\x10\x9f\x96\xb1\xd4\xbd\xd9\xf4\x77\x96\xa7\x35\x33\xac\x09\x51\x34\x6a\xeb\x85\x59\xdd\x66\x45\x31\x84\x8b\x59\x31\xbf\x86\xfc\x68\xc0\x96\xfb\xee\x98\x54\xd3\xac\x6c\xa6\x59\x31\x6e\xe5\x7d\x63\x06\xac\x9e\x90\xd4\x9d\xbf\x20\x64\x27\x1d\xcf\xb9\x59\x44\xdb\x63\x08\xa1\x30\x74\x91\xe8\x2b\x4a\x52\x8c\xf0\x3e\x10\x2b\xfa\x33\x3d\x6c\x01\xd8\x41\x21\x86\x2b\x49\x43\x3c\x5f\x88\xa3\xa4\x71\x1b\x23\x50\x8c\x6d\xd3\x27\xdc\x79\xdb\x5c\xe4\x08\x20\x45\xee\x5d\x06\xb6\xe9\xbd\x4b\x5d\xf7\xde\xf5\xd1\x8b\x8b\xc1\x04\x65\x1b\x60\xe5\x66\x4a\x5d\x19\x4f\xb1\xc2\xb9\x2a\x1a\xc4\x57\x2a\x55\x46\xff\x66\x37\xda\x29\x5c\x39\xf8\x4b\xd6\xf9\x6f\x73\xcf\xdc\x29\xa1\xbc\xa2\x9d\x9a\xb7\xf8\xc5\x4a\x12\x43\xef\x93\xb0\x7d\x39\x33\x78\xd8\xdd\xb6\xb2\xdb\x6d\x1c\x85\x19\x45\xce\x3f\x01\x00\x00\xff\xff\xbf\xcb\xeb\x13\xa7\x12\x00\x00") + +func fontsCursiveFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCursiveFlf, + "fonts/cursive.flf", + ) +} + +func fontsCursiveFlf() (*asset, error) { + bytes, err := fontsCursiveFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cursive.flf", size: 4775, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCyberlargeFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\x51\x6f\xab\x36\x14\x7e\xf7\xaf\xf8\x1e\x40\x24\x12\x98\xa4\xcb\x95\x52\xae\x98\x90\x36\xdd\xed\x6e\x77\x57\x57\xea\x1e\xd9\x0c\x49\x4d\x16\x35\x81\x0a\x48\x9b\x48\x28\xbf\x7d\xb2\x0d\x0e\x34\x34\x2d\xd3\xee\x5b\x5c\x81\x4f\xec\xef\x7c\xfe\xce\xf1\xe1\xa8\xc9\x26\xb9\x89\x0d\xcc\xf0\x03\xa6\x13\x38\x53\xdc\x4c\xc8\x4f\x87\x05\xcf\x93\x2c\x2d\xe1\x60\x13\xe7\x2b\x4e\x3e\xad\x57\x1b\x5e\x62\x99\xa5\x4f\x3c\x2f\xd6\x59\x8a\xc5\x01\xbf\xf3\xb4\xc4\xd7\xb8\x28\x78\x6a\xe3\x81\xa7\x65\x1a\x2c\x85\x67\xf1\x18\x2f\x39\xcd\xf2\x95\x8d\xb9\x33\x9d\x38\xb7\x33\xf2\x29\xcf\xb6\x1e\x8a\x32\x5b\x3e\x04\xc9\xf3\x9a\xee\x9e\x62\x9a\x6e\x30\xfa\xc2\xd3\x94\xe7\x25\xee\xc4\xce\x98\xfc\x1c\x97\xdc\xc3\xf4\x03\x7e\xdb\x6d\x30\xbd\xbd\x9d\x61\x32\xf1\x26\x33\xef\xe6\x03\x7e\xf9\xe3\x4f\x42\x7e\xe5\x39\x47\x9c\x73\x14\xd9\x96\x43\x28\x2c\x28\xbe\x66\xa9\x93\x28\x7d\x9f\xad\x2d\xe2\x24\x8f\xd7\xf7\x36\xd6\x09\x0e\xd9\x0e\xcf\x71\x9a\xc6\xb5\xf0\x12\xe5\x3f\x7c\x6b\x63\xc1\xc9\xf6\x80\xd5\x8e\x17\x25\xc5\x67\x3c\x66\x45\xc9\xef\xc5\x1e\xd6\x82\xb8\xcc\xd7\x4b\x45\x8e\x05\x4f\xb2\x9c\x53\x42\x9c\xff\x75\x10\x02\x31\xe8\xde\x94\x63\x4f\x31\x64\x9c\xdc\x24\x8d\x6d\xea\x31\x84\x87\xb6\xdc\x48\x4d\x63\x01\x63\x0b\x08\xc7\x03\x78\xbc\x11\x10\x89\xa7\x26\xb2\xcd\xbd\x39\x66\xf5\x18\x43\xc7\x8c\x2f\xe0\x48\x91\x82\x23\x47\x09\xe0\x0e\x25\x32\x2c\xf1\x50\x13\x8d\xc0\x00\x30\x86\x91\xb9\x97\x4c\x23\xd3\x34\x8f\x7f\xcf\xe7\xdf\x8e\xf3\xf9\xb7\x6a\x80\xa4\xea\xe8\xff\x08\xea\x3b\x47\x98\xa6\x39\x56\x4c\x9e\x47\x41\x3d\x3b\x04\xb5\x06\x30\x45\x14\xae\x2d\x3d\x3d\xc5\x14\x7d\x34\xbd\x28\xa4\x88\x1c\x0b\x43\x24\x01\x95\xf4\xa1\xae\xe5\x99\x9e\x25\x12\x1e\x45\xfb\x88\xc2\xf1\x7d\xbf\x57\xd2\xd9\xc7\xa2\x13\x19\x51\xdf\xf7\x1d\x50\x6b\x6f\x49\x22\xb8\x88\xbc\x88\x32\x46\x3f\x0e\x52\x04\x78\xc2\xc9\xf2\x2c\x84\x04\xf4\x7e\xbe\x50\xf5\x43\x69\x34\xb0\x20\x2d\x5a\x7b\x0a\x0e\x02\x03\x30\x82\xde\x29\x10\x7a\x5d\xf1\x76\x11\x10\x50\x40\xae\xc8\x0d\x4a\x03\x02\xcb\x92\x0b\xea\x15\x90\xfa\xef\xa2\x01\xe9\x27\x3c\xe4\xf3\x4e\x27\xa3\x7e\x94\xb3\xf8\x61\x88\x9f\x8c\x31\x6d\x8b\xf7\x0b\x64\x1d\x81\x0a\x41\xc5\x00\x57\x1e\xec\xbe\x5f\xf0\x7f\x33\xb4\x06\xad\xa3\xbd\x60\xbd\xe1\x2c\x3e\x46\xa9\x96\x31\x56\x89\x39\x6c\xb2\x1c\x75\x75\xa3\xfe\x72\x03\x82\x4a\x1a\x02\xad\x2a\xbd\x52\xb1\x43\x45\x5a\x03\xa1\x81\x7f\x75\xac\x33\x20\xd3\x3c\x86\x06\x1a\x7d\x40\x43\x03\x43\x0d\x74\x5f\x65\xec\xb1\xde\x02\x6a\x11\x2d\x20\xda\xdb\x67\xf1\xb7\x19\xa5\xf5\xde\xf4\xc8\xa5\x0a\xaa\xb2\xaa\x93\xba\x57\x00\x27\x55\x3d\x47\xb9\x3a\x31\xe1\x8b\x28\x0d\x9d\xd5\x6e\x7a\x35\xea\xec\x16\x2a\x25\xf7\x64\x75\x80\xcd\xa9\xa2\x48\x6a\x58\xd8\xca\xc3\x29\x5f\xe8\x04\xdf\x9b\x2f\xf4\x55\xc9\xeb\x37\xd0\x30\xd6\x89\x15\x4b\x61\x2f\x23\xeb\xd4\x46\x6f\x5a\xfa\x2e\x9f\xf5\xde\x69\xbb\x74\x2a\xad\xac\x3a\xd3\xd8\xba\x91\xcb\x51\xb3\x06\x27\x52\xe8\x2a\x96\xd0\x6d\xd1\xd5\x20\xa6\xd9\x2a\xcd\x56\x5d\xa8\x39\x84\x4d\x21\x30\xb7\x37\x62\x99\x3a\x75\x1c\x73\x2f\x04\xa2\x03\x6e\x32\xe8\x9e\x55\xcc\xa9\x25\x34\xbd\x22\xac\x5b\x46\xa8\x26\x84\xfd\xbd\x46\x11\x9c\xe6\x0e\x73\xd3\xb0\xa3\x56\xc3\xbe\xf6\x9c\x6b\xcf\xb9\xf6\x9c\x6b\xcf\xe9\x34\x91\xea\xe5\xeb\x3b\xfc\x4f\xf5\x6f\x00\x00\x00\xff\xff\x7b\x5a\x0e\x33\xfd\x0e\x00\x00") + +func fontsCyberlargeFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCyberlargeFlf, + "fonts/cyberlarge.flf", + ) +} + +func fontsCyberlargeFlf() (*asset, error) { + bytes, err := fontsCyberlargeFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cyberlarge.flf", size: 3837, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCybermediumFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x55\x51\x6f\xab\x36\x18\x7d\xf7\xaf\x38\x0f\x41\x24\x12\x7c\x24\x5d\x2a\xa5\x54\x4c\x48\x9b\xba\x75\xeb\xaa\x4a\xdd\xdb\xe8\x0c\x49\x4c\x87\x9a\x40\x05\xa4\x4d\x24\x94\xdf\x3e\x19\xbb\x24\xb4\x49\x74\xb9\xba\xf7\xe9\xd6\x89\x01\xe7\xf8\x1c\x1f\x1f\xdb\x24\x5e\xc4\x67\x51\x0f\x63\xfc\x84\x09\xec\x11\xce\x86\xec\x97\xcd\x54\xe4\x71\x96\x96\xb0\xb1\x14\xf3\x64\xb5\x64\x57\xc9\xe3\x42\x94\x98\x65\xe9\x8b\xc8\x8b\x24\x4b\x31\xdd\xe0\x4f\x91\x96\xb8\x8d\x8a\x42\xa4\x16\x9e\x44\x5a\xa6\xfe\x4c\x52\x8b\xe7\x68\x26\x28\xcb\x1f\x2d\x4c\xec\xd1\xc8\xbe\x18\xb3\xab\x3c\x5b\xba\x28\xca\x6c\xf6\xe4\xc7\xaf\x09\xad\x5e\x22\x4a\x17\xe8\xdf\x88\x34\x15\x79\x89\x7b\x89\x0c\xd8\xaf\x51\x29\x5c\x8c\xce\xf1\xc7\x6a\x81\xd1\xc5\xc5\x18\xc3\xa1\x3b\x1c\xbb\x67\xe7\xf8\xed\xaf\xbf\x19\xfb\x5d\xe4\x02\x51\x2e\x50\x64\x4b\x01\x69\xb1\x20\xdc\x66\xa9\x1d\x2b\x7f\xd7\xe6\x12\x51\x9c\x47\xc9\xdc\x42\x12\x63\x93\xad\xf0\x1a\xa5\x69\xa4\x8d\x97\x28\xff\x13\x4b\x0b\x53\xc1\x96\x1b\x3c\xae\x44\x51\x12\xae\xf1\x9c\x15\xa5\x98\x4b\x0c\x89\x14\x2e\xf3\x64\xa6\xc4\x31\x15\x71\x96\x0b\x62\xcc\xfe\xa6\x85\x31\xc8\x42\x6b\xa3\x2e\x6b\x42\x97\xb2\xa3\xd5\x32\x96\xd1\x94\x2e\x3a\xb4\x47\x63\x5a\xc6\x04\x06\x26\x10\x0c\x3a\xe8\xb8\x7d\x20\x94\x55\x0b\x59\xc6\xda\x18\x70\x5d\x06\x68\xe6\x8c\x1b\x08\xa4\x48\x21\x90\xa3\x04\x70\x8f\x12\x19\x66\x78\xd2\x42\x7d\x70\x00\x9c\xa3\x6f\xac\x6b\xa5\xbe\x61\x18\xdb\x7f\x27\x93\xbb\xed\x64\x72\x57\x75\xb0\x54\x6d\xbd\x9f\x41\x9e\xbd\x85\x61\x18\x03\xa5\xe4\xba\x04\x72\xad\x00\x64\x76\x50\x0a\x09\x8e\x55\x33\x5d\xa5\x14\x5e\x1a\x6e\x18\x10\x42\xdb\x44\x17\x4b\x40\x55\x73\xc8\x31\x5d\xc3\x35\x65\xe0\x61\xb8\x0e\x09\xb6\xe7\x79\x07\x2d\x7d\x38\x2c\x4d\x90\x21\x79\x9e\x67\x83\xcc\xb5\x59\x0b\xc1\x41\xe8\x86\xc4\x39\x5d\x76\x72\x04\xb8\x92\x64\xba\x26\x02\x06\x9a\x4f\xa6\x6a\xff\x10\x85\x1d\x37\xa4\x49\x9a\x29\x35\x58\x0f\x3d\xff\xdd\xc5\x67\x80\xe3\x33\x38\xf0\x19\x01\xb2\x09\xdf\x67\x44\x3e\x33\x4d\xd9\xaa\xab\xcf\xf4\xe7\xe4\x03\xc1\x67\x26\x3a\x92\x74\xe7\x37\xb2\x32\xc0\x38\xd7\x56\xb4\x1f\xd4\x5f\x92\xd7\xda\x31\x6a\xcb\xf0\x99\xf3\xd6\xe9\x4b\xc7\xfb\xba\x87\x5e\x3d\xb8\x1e\x5f\x35\x2c\xd5\x38\x41\xe2\x5c\x12\xf8\x83\xcf\x40\xcd\x4c\xf6\xd0\x7a\x92\x15\xe7\x95\xbc\xc9\x7d\xa8\x26\x02\x05\x42\x81\x0f\xbb\xdb\x1e\xc8\x15\x45\xf7\xe1\x07\x98\x40\xa0\x40\xe7\x00\xb3\x75\x3b\x02\xa2\x49\xb6\x35\xe6\x5b\x9f\x96\x21\xe0\xc4\x54\xea\x9f\x54\x55\x6b\x59\x0f\x2a\x9b\xbc\x6a\x62\x69\x24\x1c\xe5\x3e\xe0\x6d\x7d\x1c\x9f\xb0\x66\x06\xce\xc1\xc1\x35\x08\x05\x06\xd5\xc1\x1c\xab\x9d\xfb\x23\x2b\x70\x24\x0d\xcd\x3c\x28\xab\xa2\xd7\x0b\xf1\x0e\xfc\x47\xa9\xf3\x0f\x0b\xab\xa2\xd9\x5d\xdb\xd3\x38\xec\xb4\x05\x22\x70\x5a\x4e\xc1\x35\x5a\x69\x6e\xb5\x23\xef\xb1\x35\x8d\x3b\x1f\x82\x57\x28\xd7\xaa\xd5\x2e\x87\xbd\x94\xa0\x0e\x23\x9c\xd6\xca\x34\x5b\x3d\x50\xa4\x40\x75\x0d\x4e\x1d\xd8\x5d\xce\x4d\x1c\xfa\x8d\x04\x9f\x85\xfb\x2f\x97\xcf\xf3\xf3\x79\x7e\x7e\x90\xf3\x53\xa1\x55\xbf\xc3\xff\xdb\xff\x01\x00\x00\xff\xff\x21\xe3\xee\x74\x6d\x0c\x00\x00") + +func fontsCybermediumFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCybermediumFlf, + "fonts/cybermedium.flf", + ) +} + +func fontsCybermediumFlf() (*asset, error) { + bytes, err := fontsCybermediumFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cybermedium.flf", size: 3181, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsCybersmallFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x53\x61\x6b\xdb\x48\x10\xfd\xbe\xbf\xe2\x7d\x88\x90\x0d\xda\x91\x6d\x12\x70\x36\xa7\x20\xb8\x23\x77\xb9\xa6\x21\x90\x7e\x68\x89\xd2\x95\xec\xac\x52\x13\x7b\x15\x24\x39\xb1\x41\xf8\xb7\x97\x95\xb6\x8e\xd4\x34\x05\x41\xa1\x5f\x3a\x20\x69\x47\x4f\xef\xcd\x9b\xd9\x55\xba\x4c\x27\xc9\x01\x26\x98\x60\x0a\x3e\xc6\x64\xc4\xfe\xde\xce\x54\x9e\x66\xba\x04\x47\xb1\x4a\x96\x4b\x76\xb6\xb8\x5f\xaa\x12\xf3\x4c\x3f\xa9\xbc\x58\x64\x1a\xb3\x2d\xde\x29\x5d\xe2\x32\x29\x0a\xa5\x3d\x3c\x28\x5d\xea\x70\x6e\x98\xc5\x63\x32\x57\x94\xe5\xf7\x1e\xa6\x7c\x3c\xe6\xc7\x87\xec\x2c\xcf\x56\x02\x45\x99\xcd\x1f\xc2\xf4\x79\x41\xeb\xa7\x84\xf4\x12\x83\x0b\xa5\xb5\xca\x4b\x5c\x1b\x64\xc8\xfe\x49\x4a\x25\x30\x3e\xc2\xff\xeb\x25\xc6\xc7\xc7\x87\x18\x8d\xc4\xe8\x50\x4c\x8e\xf0\xef\xfb\x0f\x8c\xfd\xa7\x72\x85\x24\x57\x28\xb2\x95\x82\x71\x58\x10\x2e\x33\xcd\xd3\xc6\xdf\xb9\xbb\x42\x92\xe6\xc9\xe2\xce\xc3\x22\xc5\x36\x5b\xe3\x39\xd1\x3a\xb1\xc6\x4b\x94\x5f\xd4\xca\xc3\x4c\xb1\xd5\x16\xf7\x6b\x55\x94\x84\x73\x3c\x66\x45\xa9\xee\x0c\x86\x85\x11\x2e\xf3\xc5\xbc\x11\xc7\x4c\xa5\x59\xae\x88\x31\xfe\x4b\x83\x31\x98\xa0\x8d\x53\xc7\x86\xd0\x27\x5e\x68\xb5\x8c\xe7\xec\xa3\x8f\x0e\xb5\x68\xcc\xca\xb8\xc0\xd0\x05\xa2\x61\x0f\x1d\x31\x00\x62\x73\x59\x21\xcf\xd9\x38\x43\x69\x63\x88\x7d\xcf\xb8\x80\x82\x86\x86\x42\x8e\x12\xc0\x35\x4a\x64\x98\xe3\xc1\x0a\x0d\x20\x01\x48\x89\x81\xb3\xa9\x95\x06\x8e\xe3\xec\x3e\x4f\xa7\x57\xbb\xe9\xf4\xaa\xea\x61\xa9\xda\x05\xa7\xa0\x80\xef\xe0\x38\xce\xb0\x51\x12\x82\x40\xc2\x8b\x40\x6e\x0f\xa5\x98\xe0\x7b\x35\x53\x34\x4a\xf1\x89\x23\xe2\x88\x10\x73\x17\x7d\x2c\x01\x55\xcd\x21\xdf\x15\x8e\x70\xcd\xc0\xe3\x78\x13\x13\x78\x10\x04\x3f\xb4\xf4\xea\x67\xd9\x0f\x32\xa6\x20\x08\x38\xc8\xdd\xb8\xb5\x10\x7c\xc4\x22\x26\x29\xe9\xa4\x97\x23\x40\x18\x92\x2b\x5c\x44\x0c\x74\x37\x9d\x35\xe7\x87\x28\xee\x79\x20\x5d\xb2\x4c\xa3\xc1\x70\x10\x9a\x2b\x64\xf0\x43\x46\x30\x0b\xd7\x0d\x8d\xd3\x30\x64\x21\x7b\x7d\x43\x8d\xbe\x01\x1e\x20\x64\xf0\xc2\x86\xcf\xc0\x79\x18\x36\x15\xa8\x7e\xe7\x9b\x32\x6f\x71\x7f\x7e\x03\x7d\x53\x21\x5b\xe2\xfb\x0f\xb8\x67\xc0\xbd\x3a\xcc\x91\x0e\x19\x2a\xce\x2b\x9b\x1a\x4b\x55\x10\xdc\xb6\x51\xf3\x68\xa1\x52\x9e\xb6\xd1\x20\x08\xba\x52\xbc\xcb\xad\x5b\x95\x40\xa7\x90\x59\x37\x23\xa8\xd7\x52\xca\xaa\xf3\x99\x90\x36\x45\xdb\x80\x45\x23\xdf\xba\x6d\x52\x44\x55\xab\xe2\x8d\x94\xb7\x6d\xb7\x9c\xbb\x75\xa1\x26\xbd\x91\xde\x6d\xd7\xed\x5f\xad\x34\x78\xe9\xc5\x50\x2a\xb4\xab\x76\x2d\x22\xf2\x3b\xa8\x6f\x4d\x34\xed\x7c\x94\x2f\x09\x3e\xa1\xe5\x07\x7e\xdd\x4b\x33\xfe\xa8\x7e\x13\x75\xf7\xa8\xe9\xd9\xb6\x1c\xdb\x83\xf4\x67\xa7\x7e\xef\x4e\x55\x76\x0c\xbd\xfe\xc7\xaf\x01\x00\x00\xff\xff\x04\xac\x2e\xa0\x8a\x08\x00\x00") + +func fontsCybersmallFlfBytes() ([]byte, error) { + return bindataRead( + _fontsCybersmallFlf, + "fonts/cybersmall.flf", + ) +} + +func fontsCybersmallFlf() (*asset, error) { + bytes, err := fontsCybersmallFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/cybersmall.flf", size: 2186, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDiamondFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x8f\x1c\x35\x10\xbd\xcf\xaf\xa8\x43\xae\xe0\xb0\x42\x22\xdc\x1a\x29\x8a\xc4\x01\x90\x72\xf6\x61\x83\xb4\x41\x91\x56\x20\x41\x2e\xf0\xeb\xd1\xcc\xf8\xe3\xbd\x57\xcf\xdd\x33\x4b\xc4\x66\xd3\x6d\x77\xdb\xf5\x5d\xaf\xca\xbd\x1f\x9f\x3f\x3e\x7c\x78\x15\x6f\xe2\xbb\x78\x78\x1d\x5f\x7d\x13\x0f\xa7\xb7\x3f\xfe\xf0\xd3\x2f\x3f\xbf\x8d\x5f\xff\x8e\xf7\x7f\xfc\x1e\xef\xfe\xfc\xf4\xf9\x9f\x78\x53\xbe\xff\xf6\xf4\xee\xd3\x6f\xcf\x4f\x9f\xe3\xfd\xd3\xf3\xd3\x87\xbf\x9e\xe2\xe1\xeb\xd7\xa7\x57\x9b\xf9\x8d\x6d\x3b\x95\x5a\xf9\x12\xed\x12\x11\xed\xd9\x79\x74\x79\x58\xea\xb8\x45\x5c\xde\x1f\xdf\xda\xbd\xff\x9c\xa7\xa5\xd6\x68\xd7\x0b\x87\xf3\x4f\x5c\xee\xe9\xed\x9d\x8b\x91\xd1\x65\xde\xdf\x5c\xa4\xbe\xaa\x56\x45\x8e\xb6\xaf\x9b\xa0\xad\xcb\x54\x51\x93\x46\x67\x2c\x85\xb5\x93\x68\x63\x75\xe1\x5e\xfd\x36\x92\x74\xae\x1d\xb2\xcc\xfd\x75\x6e\x97\x75\xb0\x77\x12\xbc\xbe\x69\x8e\x5a\x5f\x9a\x98\x8d\x5c\xa3\xaf\xb7\x21\x6f\x67\xd7\x39\xb8\x97\x74\x23\xa2\x6c\x44\xd1\x64\x5c\xba\x3e\xcd\x61\xdd\xe7\xd1\x3c\x6f\xde\x9b\xfd\x4c\xdf\x84\x05\x46\x63\xe4\x40\xe8\xb6\xee\x6c\xf7\x96\x65\x6a\xc8\x68\xe7\x32\x5c\xd4\xb7\xe5\x3b\x71\x37\xef\xef\xe2\xc4\xc6\x07\x2d\x5e\x10\xc1\xa2\xad\x24\x39\x10\x44\x42\x18\x55\x83\xf5\x20\x37\x23\x06\xc5\x6a\x91\xaf\x7e\xdc\x06\xc8\x48\x18\xba\x5b\x01\x23\x72\x12\x53\x94\x1d\x59\x83\x4c\x50\xc9\x33\x16\x1d\x76\x49\x84\xe2\x4b\x4f\xf9\xaa\x61\x65\x6d\xcb\xe1\x57\x70\xd6\x55\xe2\xcc\x80\x3c\xca\x59\xe2\x6d\x4b\x9a\x54\xf6\xbc\xb8\xc5\x6b\xe2\x71\xce\x06\x09\x98\x89\x22\x6f\x78\xc6\x04\x4f\x5f\x96\xc1\x9f\x18\x0d\xab\x8a\xda\x98\xc6\x28\xcb\xfe\x78\x4f\x93\x3e\xf1\xc1\x1e\x53\xde\xf0\x9a\x80\x29\xf6\x9c\x9f\x1c\x3c\x6d\xce\xda\x95\x6a\x21\x8b\x8d\x6d\x9d\xbf\x46\x10\xc1\x92\xc3\x85\x00\x6f\xc3\xfe\x52\xda\x15\x53\x50\x4a\x13\x59\xc6\x36\x30\x28\x92\x98\xee\x49\x1a\xdc\x2f\xc0\x81\x0a\x44\x58\x88\x6d\xa7\x4c\x6a\x7a\x72\xee\xb6\xcf\xa4\x9a\x0d\x0a\x98\x38\xc1\x6d\x0f\x54\xc6\x96\x2d\x85\xc1\xf6\xf1\xf1\x31\x61\xb6\x6f\xa6\x66\x94\x43\x48\x85\x20\x81\x0b\x33\xaa\x28\x3d\x19\x29\x80\x53\x39\x48\xee\x26\x5f\x4d\x4c\xc3\xad\x73\x57\x83\x1f\x58\xa3\x29\x02\x7d\x85\x4b\x6d\xc9\x30\x6a\xc8\xc8\xdd\x32\xc6\xf5\x31\xb2\x5a\x18\x0c\x98\x1f\x9b\x49\x79\x64\xb6\x18\x43\x61\x4b\xa0\xb1\x51\x81\x62\xd0\x86\x61\x97\x6c\x77\x81\x26\xdc\x17\x21\x9c\x22\x6c\x43\x5b\xf5\xb0\x35\x11\x61\x27\xbd\xba\x0f\x23\x41\x9c\x19\x38\x15\xc4\xdc\x99\xcc\xa2\x71\xe3\x9e\xc4\xe8\xe8\x02\x89\x45\x1d\xd9\xd1\xa8\x54\xec\x97\xaa\x9e\x52\x20\xe7\xe0\xc0\x41\x6d\x49\xcb\x8b\xc2\x6e\xc1\x65\xab\x8a\xeb\x6c\x79\x8b\xb3\xef\x0d\xb3\x36\xe9\xfa\x4e\x5f\x4f\x2d\x0a\xf8\x80\x41\x6e\xe0\x90\x21\x45\xd3\x88\xa4\x51\xf5\x7c\xc1\x78\xcc\x95\x99\x72\xbe\x06\xb1\x4c\x1c\x27\xd6\xe4\xce\x47\xac\x9f\xe5\xf7\xf3\xc0\x96\x20\x1c\x7d\xa3\xb1\x64\xac\xc3\x9c\x9c\xd5\x7b\x20\xb8\xd4\x50\x14\x3c\x72\x4f\xf2\x56\x19\x1d\x2c\x14\x2c\xcd\xf3\xb3\xef\x49\x33\xd6\xcd\xcd\x42\xc3\x53\xeb\xba\xba\xc3\xfb\xb2\x4b\xc3\xe6\x93\xaa\x2a\x55\x3d\x43\x3f\xd2\x49\xbe\x0a\xee\x67\x98\xd8\x97\x99\x11\xc3\xec\x8c\x17\x4f\x6e\x40\x65\x63\xb3\xe1\x6c\x0c\x6c\xdf\x5c\x8c\x84\x64\xd5\x24\xf8\x5d\x05\x72\x82\xec\xe4\x5b\xe1\x9e\x20\x81\x04\x02\xc3\x2c\x66\x3e\x5f\x57\x02\xa0\x19\x86\xca\x05\x7a\x1f\xd4\x25\xbd\xb3\x10\x6e\xa3\xd6\x32\x24\xa3\xaf\x18\xde\x33\x63\x86\xe9\x40\x06\x4e\x35\x1e\x8d\x30\x87\x96\x22\xad\x40\x35\xa5\x04\x18\x36\x45\x0f\x6f\xe9\x13\x97\xb0\xd3\x03\x42\x92\x15\x52\x6a\x79\x6e\xc1\xcf\x97\xfb\x37\xf3\xed\xa2\x30\x94\x96\x83\x32\xfd\x92\x49\x9f\xdd\x7f\x6f\x5f\xac\x46\x97\x93\x4f\x88\x7c\x21\x84\xd3\xf1\xd4\x74\xa4\x99\x6b\x98\x25\x56\x6b\x46\x4d\x90\x6e\x31\x24\x2b\x72\xa3\x4d\x0b\xb2\x8d\xe4\x40\x59\xb0\x1b\x1d\x6c\xe0\xc9\x5c\xc3\x84\xd6\x7d\x1f\x82\x89\xed\x00\xd9\xe9\xb7\xdb\x54\x0f\x12\x74\x44\x8a\xd9\x47\x2f\x8b\xfa\xd6\x0f\x9c\xe7\x6d\xe3\x0f\x03\x84\x56\x8b\x41\x92\x54\x87\x8c\x64\xea\x11\x78\xda\x0d\x45\x99\x09\xd6\x38\xcd\xcc\xc5\x11\x7d\x86\x49\xd6\xad\xe1\x6c\x8a\x5f\xd4\x0f\xfa\xf9\xa1\x84\x9d\xdb\xfb\xb5\xf7\xdc\x56\x02\xcb\x21\xbe\x99\xbc\x52\x04\xaf\x44\x1f\x36\x5b\x5f\x67\x4c\xfa\x8f\x0c\x41\x06\x1d\x15\x0e\x3c\x24\xae\xf1\xd3\xab\x92\x45\x85\xdc\x0f\x87\xa2\x1f\x0c\x52\x0c\x90\x79\x12\xf1\x17\xa3\x8c\x50\xb7\xfd\x5b\x8a\x37\x94\x7b\xe2\xca\x24\xac\xa8\x62\x1d\xee\x09\x06\xe0\x0a\x12\x9c\x8e\x28\xd4\x19\x8f\x51\x5d\x7c\x2c\x53\xb8\xca\x83\x22\xf9\xef\x71\xef\x0a\x13\x08\x77\xd1\x3e\x1a\x87\xa8\xcb\x84\x14\x18\x6e\x43\x11\x2a\xae\x6b\xe3\xeb\x51\xcd\x8f\xa2\x99\x6d\x01\xa0\x5a\x26\xb9\xce\xda\x02\x34\x84\x34\x7d\x8c\xaf\xb3\x86\x13\xb3\x1a\xbc\x2a\xc3\xfe\x9c\x5d\x7f\x21\x05\x22\xd5\xc2\x83\x0c\x43\x44\x87\x60\x8f\x59\x2d\xa4\xe8\x2e\x32\x6c\x49\xb8\xc8\x1f\x57\x6b\xee\x9b\x24\xfc\xf6\x09\x53\x40\x49\x7a\x6e\xf2\x6d\x76\xf5\xf7\x1a\x3c\x34\x53\x1c\x32\x15\xa9\x5d\x12\xc7\xd7\xaf\x89\xd7\xff\xd7\xdd\x34\xd7\xb4\x58\x91\x33\x42\x84\xa4\xde\x00\xd3\xe9\x1d\xc1\xd1\xff\x34\xde\x4e\xf2\xef\xff\x7a\xf0\x6f\x00\x00\x00\xff\xff\x6c\xcd\x44\x15\xde\x20\x00\x00") + +func fontsDiamondFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDiamondFlf, + "fonts/diamond.flf", + ) +} + +func fontsDiamondFlf() (*asset, error) { + bytes, err := fontsDiamondFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/diamond.flf", size: 8414, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDigitalFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x9a\xf9\x77\x24\x55\x15\xc7\x7f\xef\xbf\xe2\xba\xa2\x32\x99\x49\x77\xa7\xbb\x13\x45\x9c\x4a\x75\xa5\x53\x4c\xa5\xaa\xa9\xae\x9e\x21\xe3\xda\x49\x2a\x49\x4b\xa7\x3a\x76\x57\xcf\x10\x45\x71\xdf\xf7\x7d\x5f\x40\x50\x16\x41\x40\x40\x76\x54\x04\x44\x94\x4d\x10\x64\x55\x56\x11\x65\x13\x04\xd9\x3c\x9d\x99\xa9\xba\x75\x97\xce\xf1\x07\x0f\x73\xbe\xb9\x9f\x57\x75\xdf\xfb\xde\x77\xdf\xab\x76\xb9\xb3\x5c\x68\x9d\x00\x45\x28\x40\x19\xf2\x90\xcf\xc3\x38\xe4\xcb\xa5\x7c\x31\x57\x6d\xaf\xb4\xe3\x56\x07\x16\x36\xa0\xd6\x09\xa3\x08\xcc\xd5\xd6\xfa\x7a\xd8\xe9\x40\x7e\xc7\xd4\x04\x8c\x8d\xc1\x42\xab\x1f\x2e\x41\x37\x82\xe9\xc1\xc2\x42\x27\xcc\xd9\xd1\x62\x67\xb0\x14\xf6\x61\x71\xb5\xd5\x6b\x2d\xc6\x61\xaf\x0f\xf9\xc2\xe4\x58\xa1\x54\xca\x59\xd1\x6a\x2b\x5a\x0c\x97\x60\xb9\xdb\x03\xa7\x15\xb7\xa3\xb1\xc2\xb6\xe2\xb6\x89\xe1\xf0\x47\x75\x57\x23\x30\xbb\xfb\x5b\x11\x1c\xb1\x38\xfc\xcf\xce\xc5\xc5\x76\x67\x7b\xb7\xb7\x72\x64\x6e\x33\x34\x1d\x10\xfa\x61\xdc\x87\xfe\x60\x7d\xbd\xdb\x8b\x37\x1f\xde\xd9\x80\xf6\x32\x6c\x74\x07\x3d\xe8\x2f\xf6\xc2\x30\x82\xe5\x6e\x14\xc3\x52\x37\xec\xe7\x96\xdb\x2b\x9d\x30\x86\x5e\xd8\x09\x5b\xfd\x10\x0a\xdb\x0b\xc3\xd7\x76\xbb\xfb\xc2\xb5\x85\xb0\x07\xf9\xa9\xa9\x72\xae\x1e\xf6\xd6\xda\xfd\x7e\xbb\x1b\x41\xbb\x0f\xab\x61\x2f\x5c\xd8\x80\x95\xf6\xbe\x30\x82\xb8\x0b\x6b\xdd\xa5\xf6\xf2\x06\xc4\xab\xed\xfe\xe6\xb8\xdb\xa0\xd5\x87\x4e\x37\x5a\x19\xfe\x37\x5e\x0d\x73\x9b\x01\xed\xb0\x77\x58\x1f\xa2\xd6\x5a\x38\x1c\x63\xbd\xd3\x5a\x3c\x30\x2f\x2d\x58\xec\xae\xad\x85\x51\x0c\x9d\x76\x14\x6e\xcf\xe5\xe6\x0e\x44\x2f\x0d\xb3\xae\xb7\x06\x1d\x98\x1e\xf4\xe2\x6e\x04\x47\xf4\xbb\x9d\x41\xdc\xee\x46\x3b\xc3\x56\x2f\x5e\xed\xb4\xa3\x63\xb7\x47\x61\x7c\x24\xe4\x0b\x3b\xa6\xca\xc3\x17\x69\x1f\x98\x5b\x88\xc2\xfd\xb0\xde\xea\xb5\xd6\xc2\x38\xec\xe5\xd2\x89\x58\xd8\x80\x19\xbb\x36\xcc\xb6\x15\x2d\x0d\xff\xb9\xa7\x1d\x6d\x07\x98\x6b\x6d\x40\xab\xd3\xef\xc2\x42\x08\xfd\x4e\x7b\x65\x35\xee\x6c\xc0\xda\xa1\xb7\x18\xae\xc5\x42\x18\x0f\xe7\x75\xd0\x0f\x73\xdd\xe5\xcd\xe1\x97\x07\x9d\xce\xd8\xfe\xf6\x52\xbc\xba\xe3\xd8\xb0\x17\xed\xe8\xaf\x0d\xfa\xab\xd0\xea\xc4\x61\x2f\x6a\xc5\xed\x7d\x61\x7f\x1b\x2c\x0c\x62\x58\x0a\x97\x5b\x83\x4e\x0c\xdd\x41\xbc\x3e\x88\x87\x99\xbb\x5e\x30\x5c\xaa\x68\x25\x5c\xda\x9e\x83\x13\x76\x1e\xfa\xdf\xce\x1c\x1c\x3e\x76\xf8\xce\x1c\x1c\xff\x8a\xe3\x0f\xfe\x3b\x95\x5e\xc9\xa5\x57\x71\xe9\xd5\x5c\x7a\x0d\x97\x5e\xcb\xa5\xc3\xb8\xf4\x3a\x2e\xbd\x9e\x4b\x6f\xe0\xd2\xe1\x5c\xda\xc6\xa5\x31\x2e\x6d\xe7\xd2\x0e\x2e\x8d\x73\x29\xcf\xa5\x02\x97\x8a\x5c\x9a\xe0\x52\x89\x4b\x65\x2e\x55\xb8\x34\xc9\xa5\x29\x2e\xbd\x91\x4b\x6f\xe2\xd2\x11\x5c\x7a\x33\x97\x8e\xe4\xd2\x5b\xb8\xb4\x93\x4b\x06\x97\xa6\xb9\x64\x72\xa9\xca\x25\x8b\x4b\x33\x5c\xaa\x71\x69\x96\x4b\x36\x97\x8e\xe2\xd2\x2e\x2e\x39\x5c\x9a\xe3\x92\xcb\x25\x8f\x4b\x75\x2e\x1d\xcd\x25\x9f\x4b\x0d\x2e\x05\x5c\x6a\x72\x69\x37\x97\xf6\x70\xe9\x18\x2e\xcd\x73\x69\x2f\x97\xde\xca\xa5\xb7\x71\xe9\xed\x5c\x7a\x07\x97\xde\xc9\xa5\x77\x71\xa9\xc5\xa5\x05\x2e\x2d\x72\x69\x89\x4b\x21\x97\x96\xb9\xb4\xc2\xa5\x55\x2e\xb5\xb9\xf4\x6e\x2e\x1d\xcb\xa5\x0e\x97\xd6\xb8\x14\x71\xa9\xcb\xa5\x75\x2e\xbd\x87\x4b\x3d\x2e\xf5\xb9\x14\x73\x69\xc0\xa5\x7d\x5c\xda\xcf\xa5\xe3\xb8\xb4\xc1\xa5\xf7\x72\xe9\x7d\x5c\x3a\x9e\x4b\xef\xe7\xd2\x07\xb8\x74\x25\x97\x6e\xe5\xd2\x9d\x5c\xba\x9f\x4b\xcf\x70\xe9\x05\x2e\xdd\x93\x4a\xf9\xc2\x64\x22\x7f\x10\xcb\x53\x89\xfc\x21\x24\x17\xc7\x13\xf9\xc3\x58\xce\x27\xf2\x47\xb0\x5c\x48\xe4\x8f\x62\xb9\x98\xc8\x1f\xc3\xf2\x44\x22\x7f\x1c\xcb\xa5\x44\xfe\x04\x96\xcb\x89\xfc\x49\x2c\x57\x12\xf9\x53\x58\x4e\xb3\xfc\x34\x96\xd3\x2c\x3f\x83\xe4\x89\x34\xcb\xcf\x62\x39\xcd\xf2\x73\x58\x4e\xb3\xfc\x3c\x96\xd3\x2c\xbf\x80\xe5\x34\xcb\x2f\x62\x39\xcd\xf2\x4b\x58\x4e\xb3\xfc\x32\x96\xd3\x2c\xbf\x82\xe5\x34\xcb\xaf\x62\x39\xcd\xf2\x6b\x48\x2e\xa5\x59\x7e\x1d\xcb\x69\x96\xdf\xc0\x72\x9a\xe5\x37\xb1\x9c\x66\xf9\x2d\x2c\xa7\x59\x7e\x1b\xcb\x69\x96\xdf\xc1\x72\x9a\xe5\x77\xb1\x9c\x66\xf9\x3d\x2c\xa7\x59\x7e\x1f\xcb\x69\x96\x3f\x40\x72\x79\x1c\xc0\xf5\xc6\xa6\x7d\xcb\xd8\x05\x8d\xba\x61\x5a\x49\xd8\x0f\x71\x58\x1e\xc0\x76\x77\x5b\x7e\x60\x55\xc1\x3a\xc6\x74\x8c\x39\x23\xb0\x3d\x17\xe6\x0c\x7f\x57\x42\xfc\x08\x13\x05\x00\xd3\x72\x03\x68\xd8\x35\x37\x89\x38\x11\x47\x14\x01\xea\x5e\xd3\xad\x66\x43\x4e\xc2\x21\x13\x00\x66\xd3\xf7\x2d\xd7\x9c\xcf\x46\xfd\x18\x47\x95\x00\xe6\x2d\x37\x1b\x70\x32\x0e\x28\x03\x4c\xfb\xde\x2e\xcb\x85\x69\xc3\x4f\x42\x4e\xc1\x21\x15\x80\x86\x65\x6e\xe6\x94\x19\xe7\x27\x38\x68\x12\xa0\x6a\x1b\x96\x6f\x35\xec\x46\x12\xf1\x53\x1c\x31\x05\x60\x7a\xf5\x79\xdf\xae\xcd\x92\xd4\x4f\x45\x61\x95\x71\x80\x19\x6b\xce\x76\x6d\xd7\x02\xcf\xaf\xda\xae\xe1\x80\xed\x56\x6d\xd3\x08\xbc\xf4\x05\x4f\xc3\x48\x1e\xc0\xb1\x66\x82\xb1\xba\x67\xbb\x81\xed\xd6\xa0\xea\x35\xa7\x1d\x0b\x0c\xb7\xe6\x58\x70\x74\xd3\x0b\x84\x15\x39\x1d\x8f\x50\x80\xcd\x8b\x46\xe6\xad\xce\xc0\x01\x45\x80\x86\x37\x13\xc0\xec\x7c\x7d\xd6\x4a\x63\x7e\x86\x63\x26\x00\x7c\xab\x66\x37\x02\xcb\xb7\xc8\xca\x9d\x89\xe3\x4a\x00\x73\x86\xe9\x7b\xe9\x9f\xcf\xc2\x7f\x2e\x03\x54\xad\x9a\x6f\x59\xd9\x21\x7e\x8e\x63\x2a\x00\x75\xa7\xd9\x18\x9b\xb3\xdd\x66\x23\x1b\x77\x36\x8e\x9b\x04\x68\x34\xeb\x96\xdf\x30\x7d\xbb\x1e\x40\xb0\xc7\x4b\xe2\xce\xc1\x71\x53\x24\x6e\xd6\xb7\x52\xb7\x9f\x8b\x22\x27\xc7\x01\x0c\xb3\x19\x58\x60\x98\x43\x0f\x27\x41\xbf\xc0\x41\x79\x80\x39\xdb\xf4\xbd\xec\x9b\x9d\x87\x43\x0a\x00\x75\xdb\x31\x7d\x6f\x4f\x36\xe8\x7c\x1c\x54\x1c\x8e\x53\xad\x3a\x16\x54\xbd\xf4\x51\x17\xe0\x90\x61\x19\x58\x55\xdb\x71\x8c\xe4\xef\xbf\xc4\x7f\x2f\x65\x33\xf3\xdc\x34\xaf\x0b\x71\x5c\x79\xb8\x28\x0d\xb3\xe9\x8c\xf6\xdd\x45\x98\xa9\x00\x6c\xba\xf9\xff\x33\xde\xc5\x78\x88\x49\x80\xdd\x4d\xa7\x66\xf8\x30\xe3\x1b\x07\x6a\xcc\x73\x87\xa8\xe1\x07\x56\xfa\xd8\x4b\x30\x33\x25\x33\xb3\x86\x33\x93\x00\x97\x22\x60\x6a\x9c\x03\x9b\x2b\x7c\xe8\x31\x69\xc1\x5e\x86\x31\xbc\xb1\x1d\xdd\xb4\x1a\x3c\x95\xcb\x71\x78\x01\xc0\x31\x02\xdb\x05\xd3\xa8\xdb\x81\xe1\x80\x63\x05\x81\xe5\x83\x01\x7b\xec\x60\x16\x6a\xbe\xb1\x3b\x9d\xfb\x2b\x30\x59\x1c\x4d\x6e\xfa\x2d\x21\x7f\x85\xc9\x89\xd1\xa4\x69\xfb\x66\x73\x6e\xc6\xb1\x8e\x49\xf0\x5f\x63\xbc\x34\x1a\x0f\x6c\xa7\x9a\x3e\xf8\x37\x98\x2c\x8f\x26\xf9\x56\x78\x25\xa6\x2b\xa3\x69\x7f\x68\x25\x63\xda\x43\xf3\xf5\x5b\x8c\x4f\x6a\x78\x1a\x7f\x15\x8e\x9f\x52\xe2\xcd\x83\xb3\x44\xea\xe7\xea\x94\x2d\x8c\x8f\x2b\xac\x25\xad\xea\x35\x98\xcc\x8f\x26\xb3\xab\xfa\x3b\x4c\x6a\x4e\xb2\xd4\x55\xbd\x16\xe3\x9a\x9d\x2c\x6d\x6d\x7e\x8f\x69\xcd\x52\xb6\x94\xf0\x75\x98\xd4\xdc\x64\x4b\x09\xff\x01\x93\x9a\x9b\x6c\x35\xe1\x3f\x62\x5c\xb3\x93\xad\x25\x7c\x3d\xa6\x35\x37\x59\xc1\x6c\x02\xdc\x80\x01\xcd\x4e\xae\x54\x35\x37\x22\x32\xaf\x99\xc9\x93\xe6\xf6\x26\x4c\x6a\x66\xf2\xa4\xb9\xbd\x19\x93\x9a\x99\x3c\x75\x6e\xff\x84\x71\xcd\x4c\x9e\x94\xec\x2d\x98\xd4\x8c\xe4\x69\xab\x72\x2b\xa6\x87\x87\x84\xa6\x13\xd8\x75\x67\xd8\x81\xd8\xd9\xeb\xcf\x38\x56\xb3\xcf\xc1\x27\x35\x82\xe1\x01\x2f\x41\x6f\xc3\xa8\x66\x9d\xa6\xb4\x22\xb7\x63\x52\xb3\x4d\x53\x5a\x91\xbf\x60\x52\xf3\x4f\x53\x5d\x91\x3b\x10\x5e\xd0\x4c\xd4\xd4\xe6\xf5\x4e\x4c\x6b\x46\x9a\x97\x5e\xfb\x2e\x4c\x6a\x46\x0a\x66\x3d\x3f\x5d\x98\xbb\x31\x92\x98\xa7\x31\x67\x38\x09\xd0\x98\x35\xfc\x3a\xa4\xef\x77\x0f\x46\x26\x44\x44\xec\xa1\xf7\x62\xae\x34\x8a\xcb\x66\xf5\x57\xcc\x95\x47\x71\xc2\x52\xfc\x0d\xc3\x95\x51\x70\xb6\x34\xee\xc3\xdc\xe4\x28\x8e\x2f\xe0\xfd\x98\x9d\x1a\xc5\x0a\x9d\xf3\x01\x04\x17\xc7\x65\x38\x8d\x7e\x10\x47\xe7\xc5\x68\xa5\x6b\x3e\x84\xc9\x82\x48\x8a\x3d\xf3\x61\xcc\xc9\x86\x11\x3b\xe6\xdf\x31\x27\xbb\x46\xef\x97\x8f\x60\x58\xb6\x8e\xda\x2d\xff\x81\x59\xd9\x3e\x62\xaf\x7c\x14\x73\xb2\x73\xc4\x4e\xf9\x4f\xcc\xc9\xce\xd1\xfb\xe4\xbf\x30\x2c\x5b\x47\xed\x92\x8f\x21\x76\x42\x76\x0e\xee\x91\x8f\xe3\x70\xd9\x3a\x62\x87\x7c\x02\x73\xb2\x71\xc4\xfe\xf8\x24\xe6\x64\xe3\x88\xdd\xf1\x29\xcc\xc9\xc6\xd1\x7b\xe3\xbf\x31\x2c\x1b\x47\xec\x8c\x4f\x63\x4e\x36\x8d\xda\x17\x9f\xc1\x6c\x05\xa0\x6a\xef\xb6\x1b\xac\x23\xfe\x07\x47\xc9\x36\x91\xfb\xe1\xb3\x18\x94\x2d\x22\x76\xc3\xe7\x10\x57\x92\xed\x21\xf6\xc2\xff\x62\x4e\xf6\x89\xde\x09\x9f\xc7\xb0\x6c\x16\xb5\x0f\xbe\x80\x59\xd9\x30\x62\x17\x7c\x11\x73\xb2\x61\xb2\x3d\xf0\x25\x0c\xc8\x26\x99\xd7\x5e\xf2\xe5\x94\x1d\x3f\x6e\x3c\xaf\xde\x3f\x0e\x6e\xf8\xe4\x43\xca\x15\x84\x96\xa7\x57\x66\xef\x25\xec\x16\xf7\xd9\x69\xdf\xda\x2d\x5e\x0e\x37\x61\x79\x7a\x45\xf4\x3e\x82\x6e\x71\xa7\xf5\x6a\x9e\x6b\x89\x1f\x16\x37\xe9\x91\xe7\x00\xc2\x9e\x4d\x58\xed\x1c\x69\x4a\xae\xb8\x8a\xc0\xf2\x8e\x2e\xa2\x0f\x12\x54\x3b\x4a\x9a\x6a\x19\xd0\x87\xcb\x65\xab\xf3\xf4\x0d\x8c\xd1\x6f\x50\xf5\x02\xfd\x3e\xbe\x39\xc0\xf4\xa8\x17\xe0\xf8\x03\x04\x37\xb7\x98\x01\x03\x1b\xf5\x1a\x02\x57\x47\x26\x9f\x41\x1f\x26\xa8\xa5\x3c\xb7\x2a\xc1\xd7\x13\x78\x46\x7c\xae\x88\x3e\x96\x45\xd5\x8b\x60\x55\xdc\xa1\x6f\x20\xb4\x5c\xd5\x32\xfb\x38\x61\xb7\xf8\xb6\x40\xf6\x84\xd3\x08\x3d\xf2\x7c\x46\xd8\x8b\x08\xab\x55\x97\xa5\x99\xe4\x3a\x32\x80\x5c\x61\x2a\xfe\x28\xc1\xd5\x7b\xbe\xb8\x37\x5c\x4b\x68\xb9\xc2\x64\xf6\x11\xc2\x6a\xd5\x65\x49\x56\xa1\x59\xcb\x95\x25\xa2\x34\x63\xad\xaa\x6a\xea\xbe\x70\x1b\x19\x41\x2e\x2d\x9d\x7f\x96\xf0\x5a\x7d\xd5\xa4\x46\x70\x3a\x81\xe5\xfa\x12\xd1\x8b\xb3\xa8\x7a\x47\xae\x69\x66\xb9\x85\x0c\x20\x97\x98\x8a\x3f\x4d\x70\xad\xca\x6a\xf2\xdd\x89\x64\xae\xdc\x9b\x15\x98\xe6\xae\xf5\xcf\x59\x75\xd5\x4e\x21\x23\xc8\x3d\x54\xe7\xcf\x27\xbc\x56\xe9\xb3\xe2\x0e\x45\x3a\xb8\x72\xa9\x96\x59\xd2\xc1\x0b\x5a\x8d\xdb\xd2\x99\xfc\x64\x02\x8f\xbc\x1e\x65\xd1\xf3\x08\xaa\x55\xb8\x2d\xee\x8c\xa4\x91\x14\xe4\x12\x97\x59\xd2\x49\x0a\x5a\x85\xd9\xe2\xce\x74\x35\xa1\xe5\x12\x93\xd9\x87\xb2\x6c\x51\xab\x31\x5b\x2b\x92\x53\xc9\x00\x4a\x1b\xf3\x02\xc7\x6a\x34\xc0\x4e\xb8\x0b\x09\xa7\x19\xfc\x28\xd5\xa0\x67\x90\x11\x64\x83\xeb\xfc\x25\x84\xd7\x0c\xbe\x4b\xae\xd0\x9b\x09\x2e\x3b\x5c\x81\x9f\x22\xb0\x7c\xb5\xdb\xe5\xa7\xc4\x89\x84\xd0\xbe\x37\x3a\xd2\xd9\x94\x1c\xec\x8a\x86\xf8\x38\x11\x25\x87\xba\xe2\xf4\xe8\xe7\xd2\x44\xc9\x2e\x54\x34\x47\x3d\x99\xc2\x64\x0b\x2a\x56\xb7\x78\x76\xa6\x6f\x92\x8d\xa0\x68\x8d\x7c\x72\x06\x25\x1b\xc1\x84\xf6\x79\xd5\x11\xb7\xaf\x93\x08\x2d\x5f\x68\x65\xf6\x5c\xc2\x6a\x1f\xea\x5d\x69\xa9\x6e\x24\xb0\x7c\xab\x15\xd1\x27\x08\xaa\xfd\xea\xe3\xca\x0b\x45\x9f\x2c\x7f\x0b\x51\x60\xfa\x6c\xed\xeb\xbd\x2b\x2d\xd5\x4d\x04\x96\x0b\x49\x44\x9f\x24\xa8\x7a\xa0\x73\x6b\x09\x73\x29\x61\x94\x73\x1c\x22\x2e\x27\x84\x76\x7c\xf3\xc4\xc6\x40\xd3\x93\x8f\x6e\x32\x4b\xf2\x2b\x6d\xf1\x3b\xd5\xa1\x5f\xf9\x33\xbe\x20\x27\x28\xe5\xcb\xce\xa8\x11\xc8\x21\xaa\xa4\xed\xf3\xbe\x64\x4b\xf2\xe5\x43\xf9\xec\x22\xa2\xe4\xc3\x47\x49\xdb\xdd\x7d\xd9\x94\xa4\x88\x4b\xf2\xee\xae\xc0\xa4\x8a\x4b\xda\x01\xc6\x97\x6c\x49\x4e\xeb\x25\xf9\x00\x23\xa2\xe4\xa0\x5e\xd2\x1c\xdd\x90\x26\x8c\xec\xd4\x25\xd9\xda\x22\x4a\xf6\xe9\x92\xe6\xf1\x86\xda\x8b\xef\x26\x23\xc8\x3e\xd7\xf9\x97\x08\xaf\x1d\xa0\x1a\xf2\x82\x91\x1b\x71\x49\x3e\x41\x29\x30\xb9\x12\x97\xb5\x3a\x6b\x48\x4b\x46\x8e\x4f\x65\xb9\xc0\x44\x94\x9c\xa0\xca\xea\x4f\x79\xf2\x6b\x93\x29\x2f\xcb\xd7\x13\x05\x26\xf3\x5d\xd6\xaa\x3a\x90\x5e\x9c\x5c\x8c\xca\x72\x55\x8b\x28\xb9\x16\x95\xb5\xaa\x0e\xc4\xee\x4a\x4e\x8c\x65\xb9\xa8\x65\x96\x9c\x16\xcb\x5b\xfc\x52\x9c\xbd\x59\xdc\x45\xe0\x91\x1f\xe4\xb3\xe8\x8b\x04\xd5\x6a\xba\x29\xf6\x00\xba\xc8\x72\x51\xcb\x2c\x5d\x63\xad\xaa\x9b\xd2\xdd\x9d\x66\x2c\x17\xb4\x88\xd2\x8c\xb5\x5a\x6e\xaa\xbf\x8e\xde\x4e\x46\x90\xcb\x59\xe7\x9f\xcb\xf2\x95\xad\x7e\x9c\x97\xfa\xde\x1d\x64\x8c\x91\xbf\x89\x88\x23\x3c\x4f\x46\xd0\xea\xbb\x29\x5e\xec\xc8\x1c\x54\xe4\xf2\x96\x59\x9a\xbf\x76\xd7\xd8\x2b\x35\x03\x52\x64\x15\xf9\xae\x21\xa2\xa4\xc6\x2a\xda\x5d\x63\xaf\x76\x19\x3d\x8b\x0c\x20\xdf\x36\x54\x9c\x9c\xd5\x2a\xda\x7d\x63\xaf\xb4\x35\x9d\x49\x60\xf9\xbe\x21\xa2\x97\x65\xd0\x82\x59\x01\x12\x70\x41\x36\xa0\x3a\x09\xa4\x66\x4e\x24\x01\x53\x20\xa4\xf7\x32\x09\x9a\x06\xba\xf0\xe7\x90\x88\x2a\x64\xac\x49\xff\xef\xb1\xe8\x34\xfc\xbf\x00\x00\x00\xff\xff\x76\x19\x2f\xf2\x1f\x3b\x00\x00") + +func fontsDigitalFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDigitalFlf, + "fonts/digital.flf", + ) +} + +func fontsDigitalFlf() (*asset, error) { + bytes, err := fontsDigitalFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/digital.flf", size: 15135, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDohFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x9c\x79\x77\x55\x37\x92\xc0\xff\xd7\xa7\x10\x4b\x3c\x90\x99\x10\x56\x07\x6e\xa7\x83\x0c\x13\x48\x48\xb3\x07\x08\x9d\xe0\x34\x8b\x31\x76\x83\x77\x70\x48\x4f\xf0\x57\x9f\x23\xd5\xa2\xaa\xba\xd2\x7d\xef\x3e\xdb\xef\x5d\xe7\xa4\x66\xce\xb8\xea\x57\xa5\xda\x24\xaf\x99\xe4\xf5\xdb\xd7\xe7\x9f\xef\xf9\xf3\x97\xe2\xff\x5e\xbc\xe4\xcf\xfa\x0b\xee\xd5\xfa\x9b\x33\xaf\xdf\xbe\xf6\x2f\x3e\xfa\xeb\xef\xb7\x76\x56\xb6\xfd\x93\xe7\x6b\x6b\x4b\x5b\xfe\xd4\xcb\xdd\xa4\x84\xe7\x2f\xb7\xcf\xbc\x78\x7f\x66\xe9\xd5\xfb\xd3\xee\xed\xf3\x9d\xa5\xed\x1d\xbf\xb5\xf4\x61\x65\x7b\x65\x7d\xcd\x7f\xe1\x2f\x7e\x79\xe5\x92\x73\x7b\x51\xc2\x51\xf9\x10\x9c\x8f\x92\x3f\x1c\x3b\x76\xcc\x07\x77\xec\x58\x73\xec\x58\x70\xc7\x9a\xa6\x99\xe8\x03\x1c\xc7\x64\xc5\xd4\xc6\x37\xee\x87\xe0\x8e\x27\xf1\xde\x83\x12\xdc\xf1\xa6\x69\x9a\x04\x92\x52\x00\x7b\xc7\x05\x38\x1e\x67\x8f\x1a\x82\xe3\x3e\x01\xcf\x49\x3d\x02\x21\x7f\x81\xfe\xc0\x92\xae\xe8\x9e\xbe\x13\x49\xb4\xc6\xbe\x78\xe7\x27\xb4\x36\xc2\x07\x49\x12\x31\x5a\x70\xc9\x28\xc9\x89\xee\x73\x7f\x86\x5e\x46\xee\xfa\x30\xee\x76\x18\x3e\xfc\x72\xe3\xfd\xc9\x28\xa0\x66\xd6\x34\x8d\x64\x29\x26\x32\x08\x0e\xce\x27\x53\xc8\xc9\xe0\x80\x40\xc8\x49\xc9\x4e\xca\x4a\x86\x61\x8d\x2a\xa3\x7c\xa9\xc5\x56\x5d\xe8\x05\x33\x53\xd9\x58\x57\x66\x3a\xd9\xc1\xc4\xf0\x5e\xf7\xac\xf3\xd9\x69\x71\x07\x72\x2d\x62\x7f\x62\x7d\x99\x89\x4a\xba\x97\x29\xb2\x12\xac\x05\x23\xff\x2c\x0a\x83\xcf\x40\x82\xfb\x2c\xed\x81\x1c\x64\x19\xce\x86\xce\x93\x63\x54\x5d\x71\x54\x72\x99\x51\x70\x55\x28\x73\xdd\x17\x73\x8d\x99\x1b\x4c\xdc\x62\xe4\x2d\x0c\x5c\x8f\x9c\xc6\x8c\xbc\xb4\x89\xb8\x87\xd2\xe2\x82\xc3\xc5\xea\x45\x77\xdd\xcb\xb0\x78\xd9\xd1\x4d\xe7\x58\x04\x9d\xcb\x9f\x64\x73\x4c\x13\x9c\x9b\x9b\x23\x9c\xe8\x1c\xc5\xcc\x8d\xa6\x2a\x83\xc9\x9b\x8b\xd9\x1e\xa0\x31\x91\x97\x73\xcf\xcd\xcd\x45\x8a\x0d\xcd\x25\x1a\x8d\x48\xb9\xcb\x39\x70\x35\x73\x8a\x7a\x39\x45\xa6\xb2\xdf\x39\x2a\x3f\xc7\x5a\xaa\x96\x7b\xc0\x41\x70\x8a\xbc\xc5\x39\xea\xac\xef\x5d\x4c\x89\xd2\x77\xa4\xf8\xad\xe9\xbf\x92\x44\x25\xce\xd2\x52\xa2\x2b\x7d\x8c\xc1\x31\x52\x7c\x43\x1b\xb0\x62\x07\xaf\xda\xa7\x92\x90\x7d\xea\x14\xdc\xec\xa9\x64\x93\xd5\x80\x9f\xad\x53\x5e\xda\xa7\x28\xdf\xa9\x6c\x1e\xa2\x6d\xeb\xe5\x7e\x6c\xbf\xad\x79\xda\xf3\x8e\xde\xcf\x41\xd9\x1a\xb4\xac\xd3\x49\xd0\x3a\x0d\x4d\x27\x3b\xfa\x1a\xb6\xe3\xb9\xd3\x6c\x43\x96\xd3\xca\x42\xf3\x40\x2d\x59\x41\x55\x57\x9d\x51\x54\x69\xa2\xce\xd9\x0f\xc2\xaa\x7c\x47\x38\x5c\xfc\x79\x12\x06\x60\x06\xf7\x79\xda\x03\x71\xb4\x52\x74\xd2\x40\x50\x4d\xb9\xc1\x42\x49\x09\x29\xb7\xa0\x32\xb7\x96\xcf\xab\xd1\xf5\xdc\xa5\x4e\xea\x7d\x97\xa6\x9c\xc1\xbe\x0f\x11\x97\x7f\x47\xa9\xfc\xea\x72\xc0\xf8\xbf\x41\x5a\x38\x5d\xc0\x68\x8c\xc7\x01\x83\x24\xdc\x7a\x27\x9d\xb8\x9c\xa4\x5f\x27\x9d\xe3\xcc\x60\xb1\x53\xc4\x33\xff\xbe\xff\x3f\x49\xa2\x12\x2f\xa5\xa5\x44\x57\xfa\x18\x83\x63\xe4\x04\x3f\x51\xd8\xc9\x0b\xcb\x18\x0c\xfa\x42\x4b\x42\xea\xd5\x7f\x51\x89\x1a\x44\xf7\xd3\x46\xcc\xf6\x06\xa6\x9d\x49\x92\xb4\x78\x69\x67\x34\x3b\x88\x1a\xfb\xfe\xd5\xf3\x4b\x10\xcb\xbf\x4c\xaf\xec\x4b\x1b\x4f\xd8\x70\xc6\x9a\x67\xac\xb8\xc0\x92\x4b\x2c\xb8\xc2\x99\x6b\xcc\xdc\x60\xe2\x16\x23\x6f\x61\xe0\x6d\x9c\x78\x01\x47\x5e\xc2\x3e\x38\x5c\xac\xb7\xdc\x17\x65\x70\xbc\xe8\xe8\x82\x67\x49\x32\x3c\x7b\x96\xbf\x5e\x25\x1c\x9c\x44\x88\x83\x3b\xcb\x06\x6b\x0c\xe3\xb1\xb3\x06\x42\x85\xb3\x63\xc1\xd8\xcf\x78\x70\xdc\x9c\xc5\x96\x4c\xf3\xc5\x31\xcb\x0b\xa9\xac\xae\xcf\xe6\xa7\x00\x47\xfd\x2a\x73\x0e\x04\xac\x73\x30\x21\x58\x68\x90\x75\xee\x9c\xb0\xbc\x87\xd8\xf1\xad\xb7\xfb\xb2\xa8\x7a\x73\xee\xdc\xb9\xdc\x59\xb4\x5b\x96\x90\x99\xfd\xfa\x57\xa5\xe7\xb5\x00\x3d\xdf\x68\x89\x9c\x29\x04\x82\x1a\x69\x3e\xe8\x33\x95\x55\xc6\xa6\x94\xf7\x3c\xf5\x9b\x2b\xa5\x16\x12\x3d\x7f\x3e\x77\x75\x9e\xa7\xc8\x9d\xe5\xd9\xa8\x82\x9e\x78\x1c\x0a\x23\x99\x89\x31\xa4\xbd\x1d\xa4\x05\x19\xc4\x5f\xf8\x6a\x7f\xf7\x1b\x37\x36\x38\x7f\x41\x4b\x82\x17\xcc\x0a\x2e\x5c\xc8\x30\x45\xa1\x1a\x5c\x3e\xe5\xfd\x05\x82\xb2\xc2\x68\x48\x95\x81\x61\x9f\xb2\x83\x0b\xd4\x7c\x31\x72\xfc\x42\x2d\x58\x6c\xbe\x3c\x66\x69\x21\xc5\xd5\xf5\xd8\xfc\x94\x60\x89\x76\xb2\x8b\x24\x99\x5d\xa4\xc1\x33\x63\x94\x59\x42\x17\x2f\x4a\x86\x86\x64\xa4\x0b\x46\xaa\x60\x98\x2b\x0a\x6a\xc8\xa4\x44\xc6\xd2\x70\x5c\x9e\xe9\xa2\xee\xb9\x07\xc3\x7c\x8d\xcc\x77\x51\xd4\xf5\x76\x59\x17\x7b\xef\xf9\x30\x59\x9f\x47\x73\xa9\x25\x11\xda\x5d\x8f\x80\xc5\xe3\x97\x4c\xa1\x0e\x98\x0f\xfb\x42\xa1\x4b\xb6\x4f\xae\x2e\x93\x21\xad\xc0\x9c\x5f\xc2\x26\x97\x6f\xf8\xf8\x25\x5d\xff\x12\x16\x12\x18\xfb\x84\x64\x97\x64\xea\xa3\xf2\x25\x60\xd4\xf9\x79\x14\x09\xe7\x61\xf8\x79\x19\x29\x19\x41\xc5\x10\x6a\x06\xd0\xb0\x04\x2d\x8b\x70\x9e\xd6\x4e\x1d\xf9\xe0\xe6\xf5\x0b\x89\x98\x61\x0a\xc3\x34\x04\xe7\x45\x67\xf3\x9d\x50\x1c\x8f\xd0\xcf\xcf\xdb\x4a\xd0\xfc\xbc\x2a\xce\xb3\x8b\xc5\xcd\xfc\xe2\xc7\x7f\x0d\xd5\x9f\x30\xbe\x2a\x48\x70\x5f\x35\x2d\xa9\x53\x21\x99\x8a\x22\x48\xbf\x52\x3d\x30\x94\x34\x43\x41\x05\xcc\x54\x42\xa6\x0a\x12\xd5\x10\xa9\x81\x40\x2d\x4c\xb4\x05\x23\x6d\x43\xb1\xc9\x71\xb6\x3e\x00\xda\xfb\x99\x5d\x26\xc9\xf0\xf2\x65\x7e\x08\x09\x07\x27\x11\xe2\xe0\x2e\x93\x7e\x99\xbc\x97\x09\x42\xb2\xcb\x9d\x90\x34\x3e\x7e\x39\x55\x37\x85\xa0\x7a\x21\x72\xfc\x42\x1d\xd0\x34\x5f\x1c\xb3\xbc\x90\xca\xea\xfa\x6c\x7e\x0a\xb0\xf7\xf9\x2b\x24\x19\x5e\xb9\xc2\xc3\x27\x1c\x9c\x44\x88\x83\xbb\x42\xfa\x15\xf2\x5e\x21\x08\xc9\xae\x74\x42\xd2\xd4\x71\x6f\x2b\x01\xc4\x36\x99\xc9\x89\xe8\xb0\x1c\x33\xb3\x0c\x05\x63\x28\x19\x2f\x44\x32\x84\x9a\xd1\x96\xc4\xde\x66\x7f\xf1\x95\xd7\x70\x40\x7f\xf9\x86\xf9\x6b\xda\xe1\x9d\x9d\x5c\xcb\xff\x60\x61\xef\x60\xd4\xbf\x25\x01\x35\x36\xff\x37\x4b\x27\xcd\x10\xb5\xa4\x26\x0d\x62\x63\xe0\xc1\xb5\x9e\x77\xe2\xa5\x8c\x67\x7e\x0d\x82\xe6\xd7\xe9\xe2\xbe\x46\x2f\x59\x60\xb2\x95\xcc\x6c\x45\x53\x58\x3e\x38\x69\xb5\xbd\xf6\xac\xcd\x6c\xeb\xda\xae\x6c\xcf\xfd\xe6\x3d\x04\x73\x26\xff\x58\xed\xef\x5a\x12\x52\x5f\x59\xff\x5e\x89\x3a\xe4\x5c\x7f\x32\xd4\xf3\x61\x7c\x03\xc2\xde\x6f\xd2\xfa\xbe\xe1\x60\x61\xa7\xb3\xd9\x86\x54\x6c\x63\x66\xb2\xa9\x10\xda\x45\xaf\x3e\xab\x33\xeb\xba\xba\x2b\xdb\x73\x9f\x79\x0f\xcd\x24\xfb\x2a\x88\x88\xb9\x7a\x15\x1f\x65\xa2\x91\x31\x49\x34\xb1\xab\x18\x81\xae\xab\xcc\x52\xa6\xab\x05\x86\x6a\x64\xb9\x22\xb3\x2c\xf9\xac\x45\x92\x71\xde\xcc\x72\x29\x66\xa2\x7a\x37\xbb\x8a\xd3\xaa\x7c\xd4\x64\xf1\x87\x03\x15\x67\xd9\xd5\xab\x4d\xfb\x6c\x21\xae\x98\xef\x10\x59\xf1\xa7\x9c\x13\x7d\x61\x20\xc9\x30\x04\x7e\x1f\x09\x9f\x70\x12\x21\x3e\xe1\x02\x1b\xac\x31\x8c\xc7\x82\x81\x01\x8a\xb5\x61\x63\x8f\x8f\x82\xc1\xe6\x84\xfe\x55\xf5\x3c\xa6\xe8\x93\x06\x2d\x4c\xd4\x9e\x3d\x43\xb1\x25\x3a\x7e\x00\x9b\x3f\x58\x58\xa4\x5a\xca\xbf\x33\x77\x87\x2c\x2c\x2c\x8c\x08\x59\x68\x9a\x66\xa1\x33\x64\x21\x2d\x73\xa1\x23\x64\x01\x17\xbe\x50\x0d\x59\xe0\x4b\x59\xa8\x84\x60\x15\x1b\x23\x42\xc8\x67\x63\x72\x48\xf6\x98\x18\x0e\x91\x5c\xc7\x50\x08\x52\x12\x19\x83\x21\x0b\x4d\x49\x16\x44\x88\xc9\xa1\xf3\xa4\x90\xd2\x4e\x33\x8b\x21\xa5\x08\x41\x83\xab\x44\xe4\x98\xe0\xb0\x76\x2b\x22\xbd\x8b\x28\x93\x3c\xa9\xa3\x1f\xd2\xef\x0f\x55\xd7\xac\x00\xb5\xf7\x7f\x4d\x50\x88\x43\x1c\x33\x50\x84\xf7\x1e\xf5\x58\xed\x5a\x6f\xaa\xf3\x52\x00\xb7\x70\xcd\xfb\x11\xb1\xfb\xe8\x81\x92\xe5\xbc\x89\xb6\x3e\x11\xae\xd5\xb7\x53\xdc\x64\x9f\xbb\x98\x2a\xad\x3c\xa5\x91\xf8\xba\x14\xc4\xd7\xaf\x5f\x97\xeb\x00\xac\x19\x61\x80\x74\x9e\x30\x52\x55\x22\x38\x4d\xb9\x93\x19\xe0\x4a\x83\xb5\x71\x6a\xc3\xd7\x56\x55\x5d\x6c\xef\xdb\x99\x1e\xee\x9b\xe5\x7f\xa5\x08\x2c\xb7\x41\x1e\x83\x93\x87\x92\x50\x20\x69\x50\x92\x8d\xac\x1a\x4c\xfa\xec\x71\x6e\xb0\x32\x4e\x6d\xf8\xca\xaa\xca\x8b\x3d\x88\x3b\x9e\xc1\xfb\xa9\x7e\x8b\x0b\xee\xdb\xa2\x04\xf7\x6d\x53\x90\x2e\x8e\x0e\x4e\x81\xdc\x7b\x70\x7c\x8b\x15\x29\xbf\xe5\xb9\x4f\x9b\xe8\x5b\xcd\x73\xd1\xf1\x78\x25\x4f\xad\xae\xed\xd3\xce\x35\x72\x0f\xd5\xfd\x94\xf7\xdc\xf7\xbe\x66\xc4\xfb\x27\xba\x51\x94\xe0\x6e\x94\x16\xd4\xc5\xd1\xc1\x29\x90\x7b\x0f\x8e\x1b\x58\x91\xf2\x5b\x9e\xfb\xb4\x89\x6e\x68\x9e\x8b\x8e\xc7\x2b\x79\x6a\x75\x2d\xa7\xb9\x9a\x1b\x37\x34\x6f\x7a\x72\xd5\xc7\xe8\x7b\x19\x18\x9f\xf4\xeb\xde\x4d\x29\x88\x6f\xde\xbc\x29\xef\x0b\xb0\x66\x84\x01\xd2\x79\xc2\x48\x55\x89\xe0\x34\xe5\x4e\x46\x63\xd9\xa0\xc4\xa2\x13\x1b\xdd\xc6\x7c\xa2\xd0\xe0\x88\x71\x6a\xc3\xcb\x55\x81\x72\xd3\x2e\x16\x95\x01\x7d\x6b\xeb\xf9\x1d\xaf\xfe\x5b\x5d\x70\xdf\x91\x24\x9b\xad\xe0\xbe\xc3\x2d\xa1\x83\xac\x2e\xc7\x77\x05\x47\x4c\x45\x86\x74\x7c\x07\x5d\x8d\x70\x34\xa9\x99\xa6\xe0\x10\x32\xa6\xa3\x96\x6a\xfc\xae\xaa\x03\x4e\xb2\xab\xca\xda\xfb\xdf\xe0\x2c\x1d\xd2\xa3\xf5\xef\x59\x82\xfb\x9e\x2e\xc4\xea\x68\xc4\x18\xef\x93\xf1\x3d\xe4\x39\x78\x5d\xd6\xaa\xf7\x93\x7b\xae\xcd\xb5\x0f\x7d\xf2\x4f\xf2\x5b\x59\x14\xe6\x97\x3e\x16\x26\xae\x93\x50\xfc\x2d\xdb\xc9\x24\x78\xb5\x23\x1a\x07\x68\x61\x52\x4b\x38\xf1\xac\x32\x6e\x6e\xe5\x69\x52\xc9\x5b\xb7\xd4\x67\x7e\x2a\x93\x3a\x11\x0e\xac\x8d\x0d\xf2\x46\xc7\xbf\x86\x19\xe3\x32\xaf\xd1\x1f\x48\xa2\x89\x6a\x70\x3f\xe0\x2e\x80\x82\x3a\x0e\x45\x3d\xd2\x1f\x98\x62\x64\xcc\xcb\x06\x7f\x84\xce\x28\x38\xa7\x17\x34\xc3\xd1\xb4\x98\x41\x57\x2b\x77\x56\x99\xa2\xcf\x1e\x8a\x9b\xec\x73\x17\x53\xa5\xd5\xaf\xd6\x1d\x7f\xdc\x0d\xee\x1f\x59\xac\x87\x2f\xa5\x87\x87\x5c\xad\x6c\xde\xff\xa3\x70\xe2\xe8\x79\x60\x55\x6a\x52\x14\xb0\xe4\x76\x94\x74\x7b\x2a\x32\xd9\x9d\xce\xdc\x53\x77\x8d\x3c\xcb\x01\xb7\x51\x8c\x83\x70\x70\xb7\x71\x7d\x3a\x82\x69\x0e\x50\x11\x19\x8a\x00\x11\x21\x98\x0c\xe0\x08\x89\x54\x00\x46\x28\x22\x9a\xa4\x88\xdb\x6c\xa9\x80\xdb\xe8\x50\x1f\x74\x80\x38\x7a\xdb\x17\x03\xbc\x5c\x49\x31\x00\xa9\x50\x6d\x80\xcf\x4b\xaf\x04\xb4\x76\x79\x30\x01\xa3\xae\x7b\xe4\x83\xf9\x53\x04\x4c\xf6\x89\x78\x07\x85\x08\xd9\xc1\xdd\xc1\x17\x41\x2e\xb4\x85\x87\x5c\x05\x0f\xba\x4a\x1e\x70\x15\x3d\xc9\xd5\xf6\xdc\x41\x57\xcb\x73\xc7\xdf\x11\x1f\xb4\x07\x5d\x4d\xc1\xe3\x55\x49\xe5\x91\x2e\xe3\x11\x2e\xeb\xc9\xae\x96\xc7\x97\x3b\xb0\xdb\x31\xb7\xe0\xf9\x16\x26\xb9\xd3\x99\x7b\x8a\xae\x2e\x78\x97\x24\xc3\xbb\x77\x79\xdd\x09\x07\x27\x11\xe2\xe0\xee\xb2\xc1\x1a\xc3\x78\xec\xae\x81\x50\xe1\xee\x8c\x60\xb1\x25\xd3\x7c\x71\xcc\xf2\x42\x2a\xab\xeb\xb3\xf9\x29\xc0\x7e\x3f\xa0\xde\xb3\x02\xb4\x31\x72\x4f\x50\x88\x43\x1c\x33\x50\x84\xf7\x1e\xf5\x58\xed\x5e\x6f\xaa\xf3\x52\x00\xb7\x70\xcf\x7b\x13\x0b\xed\x7a\x93\x57\x4c\x3c\x3e\xbd\x77\x2f\x57\x11\x54\xcc\x3f\x92\xaa\x9e\xba\xb7\x3e\x00\x3a\x41\x8a\xfb\x24\x82\xde\xbf\xcf\x17\x04\x3c\x38\xc9\x88\x07\x77\x9f\x2d\xd6\x32\x8d\x9f\x4d\xf7\x2d\x85\x4f\xb1\xfb\xd3\xa3\xf7\xa9\x37\xd5\x19\x0f\x73\x5f\x4d\x21\xa9\x9d\xb8\xb9\xdf\xde\x4e\x82\x76\x93\xb8\x1e\xb3\x75\x6c\xc2\xde\x05\x1c\x19\xf4\x33\x79\x60\x05\x68\x63\xe4\x81\xa0\x10\x87\x38\x66\xa0\x08\xef\x3d\xea\xb1\xda\x83\xde\x54\xe7\xa5\x00\x6e\xe1\x81\xf7\x23\x62\xf7\xd1\x43\x79\x8a\x07\x4d\x0f\x9a\x17\xe8\x3d\xea\x83\xf8\xba\xd1\xe3\x99\xd4\xe1\x43\x2d\x11\x3e\x7c\x68\x1e\xc9\xc3\xe0\x00\x41\x8c\x85\x29\x19\x9e\xd7\x90\x0b\x15\xa1\x7f\x48\x39\x55\x4b\x5c\x80\x3c\xd0\xfc\xc3\xdc\x56\xc4\x3c\x51\xee\xe9\xa1\x19\xf3\x21\xf5\x59\x84\x34\xb0\x86\x8d\x9d\x33\xc3\x46\x94\x4f\x5b\xd2\x8b\x9b\xf9\x4f\x1b\x3d\x7e\x04\xe9\xfa\x21\x36\xb8\x1f\xcb\x12\xdc\x8f\xf6\xab\x47\x92\xd1\x8e\x1f\xc9\x8f\xca\x8f\x54\xc3\x7b\x04\xde\x53\x0d\x6a\x83\x1d\xb6\xdd\x21\x3a\xc4\x80\xc6\x91\x97\x31\xae\x23\xcb\xc8\x8b\x1a\xa4\xa3\xe2\xa9\xe2\x47\x28\xc9\x24\x23\xb8\x47\xb0\x1d\xc4\x68\xd4\xf1\xa3\x16\x8e\x49\x7c\x01\x7b\xc6\xf2\xff\x2d\x6c\xb6\x38\x75\xc8\x6a\xc6\xcd\xa3\x47\xac\xa5\x0d\xb2\x49\x6e\x5a\xac\x70\xc0\x2a\x69\xdf\x8f\xd4\x7e\xeb\xd7\x30\x18\xdc\xf9\xf7\x9e\x11\xce\xc7\x28\x02\x12\x0a\xee\x31\xac\x47\x39\x11\xed\xc7\x89\x6a\xdb\xf9\x38\x75\x6b\xbd\x6c\xa7\x51\xb4\x37\x5b\x30\xa7\xf4\x0a\x1d\x97\x90\x89\x8c\xa3\x0d\x11\x53\x15\x78\x7d\x48\x55\xf5\xbc\xdb\xc7\xfc\x96\x1e\x17\x16\xff\xd8\xfa\xd4\xad\xb4\xb6\xa1\xae\xec\xb1\xd9\x94\xbe\x4f\x7d\x73\xa3\x2e\xfb\x48\x39\x3b\xbd\xbd\x52\xb5\x83\x9f\xa0\x74\x04\x51\x48\x70\x4f\xe0\xf2\x3a\x83\x31\xe4\x30\x83\x51\x7d\x62\x7b\x6c\x05\x3f\x49\xdb\xb0\xd1\x55\x3b\xad\x4e\x7b\xb1\xa8\xb1\x9f\xf0\x9e\x65\xf4\x13\x7e\xf9\x4f\x6c\x1d\xbc\x94\x4c\x50\xb3\xb6\x17\xc1\xcc\x6a\x1f\x55\x70\x2d\xa3\xea\x3e\xbf\x8d\x72\xaf\x6a\x2f\xe2\x21\x95\xb7\x20\x77\x28\x5f\xdd\xa8\x7d\xeb\x27\xfa\xc4\xde\xa4\xb1\xf5\x7b\xb6\x2f\xd5\xd8\x87\xf9\x99\xf2\x67\x0f\xee\xfb\x1d\xf8\x27\x10\xb4\xd1\x0a\xee\xa7\x74\xdb\x8c\xc1\x1a\x81\x91\x93\x91\x72\x33\x47\x2d\xe6\xce\x96\xcf\x7e\x68\x10\xed\x9c\x0d\xfb\xfe\x89\x1f\xf6\x4f\x7e\x24\x2e\x27\x29\x95\xac\x34\x58\x1b\xa7\xdf\x4e\xca\x8b\xed\x77\x3b\xd3\xc7\x7d\xb3\x3c\x05\x41\x1b\xad\xe0\x9e\xa6\x35\x30\x06\x6b\x04\x46\x4e\x46\xca\xcd\x1c\xb5\x98\x3b\x5b\x3e\xfb\xa1\x41\xb4\x73\x36\xec\xfb\x29\x3f\x94\xa7\x6a\x9c\xa7\x8a\xe6\x29\x75\x9f\x07\x88\x9f\xf2\x4c\xb8\x34\xd9\x77\x63\xfb\x7e\x2a\xa5\xf3\x1a\x06\x83\xfb\xfc\xb5\xe2\x9f\x6d\x09\xee\x9f\x8d\x95\x2e\x48\xe7\x80\x51\xce\x94\x9f\x98\xa8\xce\x48\x40\xc1\x18\x4a\x46\x50\x31\x84\x9a\x01\x34\x0c\x5a\x12\x4c\x8f\x29\xfa\xef\x37\x7b\x69\x75\xe3\x6f\x7e\x5a\x50\x50\xa5\xfe\x4c\x12\xdc\xcf\x38\x54\x49\xcd\x01\x3f\xc3\xb1\x03\x57\x9b\xae\x1e\x72\x93\xe5\x29\x26\x53\x6b\xdf\xcf\xeb\xfc\x17\x90\x76\xfc\x2f\xa9\xd5\x5f\xda\x79\x4a\x8e\x94\xbf\xe0\x80\xba\x6d\x07\xf6\xd3\x72\x50\x9f\xd6\xc1\xfd\x1b\x47\x9e\x4b\x3b\xc4\xbc\xca\x21\xf7\x20\x1d\x6a\x3f\xc2\xa1\xf7\x96\x1d\x66\x9f\xec\xb0\x7b\x26\x47\x6b\xff\xb8\xf6\xfe\xf7\x35\x23\x5e\x7b\x7a\xcf\x48\x82\x7b\x86\xaf\xdb\xa8\xcf\x9e\x91\xea\xbd\x7f\x76\x18\xaa\x28\x51\xed\x81\x9a\x2c\x4f\x31\x99\xda\xf3\xbf\x4e\xb4\xb8\xb8\x68\xd0\x62\xd3\x34\x8b\x0a\x2d\xa6\x96\x17\x05\x5a\xc4\x31\x16\x19\x2d\xf2\xd7\xea\x45\x44\x78\x0a\x59\x44\xa4\xe3\xc7\xbd\xe0\x16\x41\xa0\x8f\x28\xc3\xf8\xef\x34\x0d\x15\xb5\x59\x3d\xfa\x2f\xcf\x51\xf1\xfc\x5a\x91\xe0\x7e\x6d\xfd\x20\x94\xe4\xd7\xae\x33\x53\xea\x9a\x5c\x7b\x42\xf9\x57\x92\xa8\xc4\x2e\xb5\xf2\x2f\x54\xf6\x7c\xd2\xd2\xa9\x18\x5d\xca\x33\x0c\xa5\xf4\x5d\x67\x5a\xec\xb9\x14\x62\xf2\x09\x3c\x37\x71\x08\x55\xbe\xe7\x92\xb5\xe3\x9e\x9b\x84\xc1\xe1\x09\x0a\x4b\x0c\x93\x50\xba\x6e\x66\xce\xca\x96\x13\x7f\xae\x67\x03\x7d\x96\x7b\x6e\xb1\xf2\x8f\x1a\xc1\xbd\x40\x31\x14\x66\xdb\x07\xf5\x2f\xba\xa8\xac\xca\x94\x25\xf2\x36\x8d\xc9\x74\x06\xc2\xba\xda\x8b\x22\x25\x7d\x32\x2a\xca\xbd\x18\xd1\x99\x84\x89\x1a\xa9\xfe\xd8\x37\x08\x3a\x88\x26\x12\x7d\x69\x24\xd2\x97\x2f\xcd\x8a\x23\xb5\x2c\x51\x82\x70\xd6\xd0\x97\x5e\x14\x20\xfa\xd2\xf4\xd0\x45\xcb\x19\x6c\xb5\x72\x67\x95\x29\x2a\x13\x0f\xe3\x2e\x5a\x74\x9c\xe0\x57\x28\x86\xc2\xc8\xfb\xa6\xaf\xb0\x1a\x55\x91\x14\x0d\x96\x44\x5f\xd9\xbb\x88\x94\xa0\xce\x40\x75\x75\xb5\x57\x19\xee\x8b\x8a\x62\x4d\xda\x4e\xab\x33\x98\x38\x63\x0c\x87\x3d\xf0\xc0\xa4\x0f\xe2\x41\x0c\xfd\xab\xc9\x92\x10\xa2\x4b\x4b\x72\xe7\x91\x07\xe7\x97\xc8\x5a\x42\xf7\xd2\x52\x70\x04\x53\x42\xc4\x4c\x45\xac\xa4\x22\xb3\xcf\x19\x64\x17\x22\x83\xea\x77\xa9\x69\xe3\xdc\x59\x4e\x52\x9a\xa2\x59\x2a\x4d\xbc\xb4\x34\x90\x07\xd1\xe7\x99\x8c\xfa\xb3\xc9\x6b\x23\xc8\x5f\xdb\xf5\xbf\x4e\xbc\x85\x9b\xe6\xb5\xe0\x98\xc3\xf2\xd7\x58\x11\xbc\x6d\xce\xfd\x50\x7a\x6a\xc5\x72\x75\x6a\x0c\x6e\xf3\xd4\xea\x8e\xec\x67\xbf\x3c\x6f\x77\xdc\x7b\x19\x10\x1f\xc4\xeb\x8e\x74\x99\x84\xf4\x48\x97\xf9\x01\x2c\x2f\x27\x3d\xd2\xe5\xd6\x33\x5d\x0e\x6e\x99\xc3\x96\x59\x25\xba\x9c\xaa\x90\x3e\x09\x05\xdc\xa2\xa2\x5c\xa4\xed\xce\x12\xf5\xcb\xcb\x25\x9a\x47\xd6\x94\x44\x54\xa3\xbd\x94\xfa\x85\x7d\xb5\x7a\xe0\xb4\xe5\x1e\x96\x7d\xee\x81\x0f\xa8\x1b\x92\x45\xfb\x3e\x93\x37\x20\x96\xa6\x3a\xfb\xa1\xfe\x0d\x50\x99\x9d\x29\x1e\x01\x07\xd1\x2c\x91\x0b\xfa\x06\xe3\x9b\x37\x82\xc6\xa3\xa4\x32\x85\x42\x6f\x66\x45\xc5\x2a\x51\x1f\xcc\xa7\x6c\x9b\x66\xac\xb5\x95\x95\x95\x95\xa4\xad\xc4\xb9\x56\x34\xe3\xb8\x15\x90\xa8\x35\x1c\xb7\x32\xb9\x06\x59\x9a\x95\x8a\x86\x52\xeb\xb9\xa7\x36\xe1\x9f\x1e\x56\x57\x57\x57\x0d\x5b\x8d\x0d\xae\x8e\x8e\x2b\xe4\x5b\x05\xd1\xac\x29\xe4\x2b\xd5\x38\xda\x2c\x2d\x48\x33\x50\x56\xd5\x0e\x40\x6b\x56\x57\x49\x81\xb3\xf2\x2b\x05\xed\x39\xc7\xac\xca\xff\x74\x0d\xac\x18\x76\x5f\xfc\x34\xa8\xc0\x7f\xa3\x68\x08\x15\x26\x85\xfe\xdf\x19\x62\x7a\x05\x49\x93\x90\x15\x01\xf3\x09\x86\x8d\x48\x9d\xa1\xe8\x61\x04\x54\xc7\xb9\x79\x59\x28\x4f\x24\x5a\x12\x63\xe6\xe6\xe5\xea\xf2\x98\x63\x6f\x7e\x5a\xb0\xfc\x15\xe2\x2d\x48\xd4\xd2\x40\x35\xcd\xbf\x3d\x58\x0d\x32\x37\x6f\x2b\x1a\xca\x21\x7e\xf5\xeb\x58\xd5\xf4\x3d\xef\x40\xbc\x52\x83\xf3\xef\xde\xe1\xfb\x7d\xe7\x3d\xab\xef\x7c\x70\xef\xf2\xd3\x7e\x27\x75\xe5\x91\xc2\x9e\x77\x14\x4f\x0a\x79\x62\x49\xa3\x0c\xc2\x43\xeb\x30\xca\x40\x6e\xae\xaf\x67\xc2\x6f\xc4\x07\xc0\xd6\xd6\xd6\xd6\xbc\x5f\x43\x41\xd6\x34\xcd\xda\x1a\xbd\x91\x48\x81\x09\x59\x5b\x4b\x67\xcd\x73\x5a\x8b\x35\xd6\x30\x00\xbd\x99\xa5\xec\x6b\xd3\x65\x3c\x15\x68\xb3\xdb\x73\x81\x15\xe0\x34\xd0\x7a\x16\x40\xeb\xeb\xe2\x0a\xd7\xd7\x7d\x70\xeb\xe6\x5e\xd7\x09\xa5\x53\x0a\xad\xa7\xc4\xeb\x07\x82\x0a\xe9\x75\x13\x85\x56\x4b\x03\xcd\x62\xab\x06\x0d\xe2\x37\x1b\xb7\x11\xc5\x7b\xbf\x41\x02\x34\x2e\x6f\x63\x63\x83\x17\xb9\xc1\x54\xc9\x46\xca\x80\xfa\x06\x1f\xd8\x08\xce\x6f\xd0\xb9\x98\x7c\xbf\xb4\x9d\x37\x17\x13\xd4\x74\x66\xe9\x46\x9a\xc2\xcb\x7e\x61\x60\x6f\x7a\xc8\x3b\x2b\xd2\x8d\xbc\x94\x49\xa9\x2c\xde\x7d\x43\xc3\x78\x26\xde\xfb\x4d\x12\xd2\x23\xdd\xe4\xe5\x6e\x6e\x26\x3d\xd2\xcd\xd6\x3b\xd9\x0c\x6e\x93\xc3\x36\x59\x25\xba\x99\xaa\x90\x3e\x09\x05\xdc\xa2\xa2\x5c\xa4\xed\xce\x12\xf5\x9b\x9b\x25\x9a\x47\xd6\x94\x64\x73\x7c\xba\x99\xf7\x30\x29\x25\x19\xf4\x33\xd9\x8a\xe2\xbd\xdf\x22\x01\x1a\xc7\xd9\xda\xda\xe2\xfd\x6e\x31\x55\xb2\x95\x32\xa0\xbe\xc5\x07\xb6\x82\xf3\x5b\x74\x2e\x26\x2f\x53\x10\x43\x73\xbf\x87\x46\x79\xd0\x29\xec\x77\xdf\x74\x56\xdf\xfa\xb6\x59\x10\x6d\x6f\xe7\x7b\xdf\x8e\x48\x82\xc4\x82\x43\x12\x4f\x81\x12\x9c\xdf\xa6\x13\x98\x2d\xa5\xdf\xe6\x3c\xb2\x09\x41\x63\x7a\x2c\xbe\x6d\xd2\x73\xf6\x98\x5e\xf7\x90\xa2\xbc\x64\xdb\xdb\xd4\xbd\x9c\x67\xd0\x3f\x50\x74\xfd\x56\x21\x1c\x3b\x3b\x3b\x3b\x6d\xc7\xce\xce\x4e\xd3\x34\x25\x47\x5a\xc7\x78\x8e\x1d\x10\x70\x80\xa0\xa3\xf5\x15\x60\xa4\x23\x67\xa2\x5c\x93\x76\x35\xbe\x03\xea\x68\x47\x93\x27\xca\xbb\x32\x2d\xe7\xed\x2a\xd7\xce\x8e\xbc\x8f\x9d\x2c\xe3\x5d\xd4\x90\x1c\xb3\xfb\x5d\xe9\x7d\x92\xa8\x93\x16\xdc\xfb\xb8\x5d\x60\xa8\x4d\x91\x35\xb1\x8b\xc6\xb0\x2c\xef\xdf\x07\xe7\x5b\x30\xce\xf6\xfe\x7d\x8e\x21\x46\x53\xc5\xb9\xe2\xff\x1d\xfa\xef\xa4\x5d\xf1\x33\x71\x7d\x00\x11\x0c\x49\x70\xfe\x43\x5a\x76\xf6\x91\x1d\x13\x6a\x1f\x5b\xa9\x96\xf4\x65\x1d\xda\xc8\xb6\x88\xc2\x0e\x89\xc8\xf3\xd4\x3c\x32\x59\x95\xe7\xfa\xc0\xef\xe4\x43\x6b\xe4\x0f\xc6\x23\xb7\x61\xe7\x93\x8b\xfa\xa0\x3c\x7a\x87\x7a\x5f\x83\xb9\xca\x89\x5c\x1d\xbe\x1e\x69\x8e\x76\xe8\x2e\x88\x60\x45\x7b\x77\x37\x38\xbf\x9b\xde\x4c\xf6\xd5\xec\xd8\x80\xf6\xed\xe2\x4b\xdc\xb5\x27\x53\xaf\x32\x76\x97\xdf\xf3\xae\xa9\x01\x63\x65\x1b\x35\x6b\x8b\x0d\x10\xa9\x7d\x94\xcb\xaa\x64\x93\x5d\xf3\x5e\xcb\x3d\xca\xf9\xf2\x15\x94\x27\x17\x5b\x13\xb7\x35\x6a\xbf\xf2\x62\x77\x95\xa7\x65\xab\x37\xa0\xef\xd3\xda\x03\x78\x84\x47\x28\x74\x10\xbf\x9f\xb9\xdf\x40\xc0\x44\x23\x38\xff\x5b\x7a\x30\x09\x93\x1a\x33\x30\x66\x25\xe5\x45\x2b\x1f\x82\x6a\xbf\xf1\x6b\x86\x4c\xd8\xc3\x6f\x0a\x76\xd2\x62\x86\x62\xb5\x62\x67\xc5\x29\x2a\x13\x0f\xe0\x2e\x8a\x74\x28\xdf\xe2\xba\x5c\x1f\x41\x04\x43\x12\x9c\xff\x98\x16\x9f\x7d\x64\xc7\x84\xda\xc7\x56\xaa\x25\x7d\x59\x87\x36\xb2\x2d\xa2\xb0\x43\x22\xf2\x3c\x35\x8f\x4c\x56\xe5\xb9\x3e\xf2\x4b\xfb\xd8\x1a\xf9\xa3\xf1\xc8\x6d\xd8\xf9\xec\xa9\x8f\x85\x1d\xb6\x3c\xb6\xc3\xc2\xe6\x0b\x9e\xd6\x36\xac\xab\xe8\x81\xcd\xb7\x6e\xcc\xce\xd5\xc7\x35\xe6\x1f\x0c\x0e\x14\xfd\x6e\x25\xb8\xdf\x1b\x2d\x6d\xf4\xbb\x38\x48\x84\xd3\x67\x42\x48\x10\x44\x92\x00\x52\x24\x21\x22\xdc\x97\xb7\x5d\x94\x5b\x6d\x0f\x34\xfd\xad\xb6\x91\x62\x64\xfc\x27\x0a\x1a\xff\x89\xfd\xa3\x91\x74\x65\x60\x18\xe8\x98\x40\x1a\x78\x22\x19\xac\xfb\xe0\xb2\x6e\x3d\xfa\x4c\x47\x6a\x8a\x2b\xf5\xa6\xba\xd6\xf3\x14\x56\xb1\x7f\x23\xff\x6b\xa0\x7b\x5a\xfd\x3f\x90\xa4\xa6\x06\xfb\xab\x39\xc3\xcc\x4a\x4c\xa4\x9a\x75\xfd\x11\x85\x8d\x58\xfb\x0f\x69\x80\x15\xc3\x84\xe1\x3d\x5b\x65\x23\x5a\xa9\x0e\x59\x50\x14\xad\x96\x47\x9d\xa9\xa5\xfe\x23\xf7\x63\x7b\x53\x5d\xcb\x79\xa6\xf1\xb2\xb4\x54\xff\xcd\xe3\xa3\xe9\xf8\x44\xe2\xd9\x88\x8e\x4f\x9f\xf8\x4b\xe8\x27\xef\xc1\x88\x0e\xd4\xf4\x87\xbd\xe0\x3e\xe9\x50\xb4\xa2\xc3\x24\x07\x6b\x08\x93\x0f\xce\x11\x5c\xef\xff\xf9\xeb\x48\xff\x23\xff\x1f\x00\x00\xff\xff\xac\xd9\xf0\x1f\x3b\xc1\x00\x00") + +func fontsDohFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDohFlf, + "fonts/doh.flf", + ) +} + +func fontsDohFlf() (*asset, error) { + bytes, err := fontsDohFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/doh.flf", size: 49467, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDoomFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x58\x6d\x6b\xe3\x3a\x16\xfe\xee\x5f\xf1\x50\x02\x69\xd9\x36\x22\xb3\x9d\x32\xb3\x94\x92\x7d\x87\x85\x65\x06\x2e\xf4\x93\xb8\xaa\x9b\x28\x89\xb9\x8e\x53\x6c\x67\xa6\x05\xfd\xf8\x8b\xce\x91\x6c\xf9\x35\x6e\x67\xe8\x44\xc2\x96\x1f\x9d\xf3\x9c\x57\x69\x9b\x6e\x3f\xc5\x33\x7c\xc1\x1d\x96\xb7\x58\x7e\xc6\xf2\x2e\xfa\xd7\xb7\x6f\xff\xc7\xf3\x1b\xfe\x93\xc7\x59\x81\xef\x0b\x6c\x34\x1e\xf3\x44\x17\xb8\xdf\xbe\xfc\x58\xbd\xbe\x1d\x5e\xf6\x8b\x24\xde\x2e\xb2\xf4\x01\x58\x7e\xc1\xff\x4e\x19\x96\x5f\xbf\xde\x45\xcf\x71\xa1\x37\x38\x66\xf8\x47\xb2\xb3\x08\xff\x4d\x75\x96\xe1\x9f\xfb\xf8\xe5\x45\xa7\x29\x6e\xc5\xd7\xbf\xe2\xe6\x06\xd5\xb2\xdf\xca\x38\xdb\xc4\xf9\x26\xda\x26\xbb\x54\x97\xc8\x75\xaa\xe3\x42\xe3\xd3\x62\x69\xd7\x2d\x3f\xe1\xef\xa7\x9d\x85\xbe\x8d\xbe\xeb\xfc\x90\x14\x45\x72\xcc\x90\x14\xd8\xeb\x5c\x3f\xbf\x61\x97\xfc\xd0\x19\xca\x23\x0e\xc7\x4d\xb2\x7d\x43\xb9\x4f\x0a\x6c\x8f\x59\x79\x8d\xb8\x40\x7a\xcc\x76\x76\x2c\xf7\x3a\xa2\x05\x89\xce\xe7\x05\xb2\xf8\xa0\x2d\xc6\x4b\x1a\xaf\x59\x8c\x18\xeb\xe3\xe1\xa0\xb3\x12\x69\x92\xe9\x45\x14\xfd\xfb\xf5\x25\x8d\xb3\xb8\xb4\xbb\x1d\xb7\xd8\x26\x79\xc1\xef\xfe\x16\x59\xc2\x70\x83\x8b\x43\xbc\x4b\xd6\xc8\x4e\x87\x67\x9d\x5f\x60\x7b\xcc\xb1\x4d\x52\x8d\x64\xa3\xb3\x32\xd9\x26\x6b\xfa\x38\x8a\x01\xe0\x06\xc5\xfe\x78\x4a\x37\x88\xd3\x9f\xf1\x5b\x81\x67\x8d\xa7\x78\x7e\x4d\x1f\x65\xc7\x9f\xd1\x8c\x17\x95\x7b\x8d\x8b\x7d\x9c\x6f\x9e\xd3\x38\xfb\xe3\xc2\x12\xf0\x92\x27\x59\x59\x58\x1d\x62\xd0\xd3\x6b\x3c\x9f\x4a\xac\xe3\x6c\x5e\x5a\x98\xe2\x70\x2a\xf6\x7a\x13\x7d\x61\x84\xbd\x4e\x76\xfb\xd2\x4a\x1c\x63\xbd\x8f\xf3\x78\x5d\xea\x3c\xba\x1b\x79\x79\x8d\xec\x58\x22\xc9\xd6\xe9\x69\x93\x64\x3b\x6c\x74\xb1\xd6\xd9\x46\xe7\x45\xb4\xbc\xa5\xcf\x0e\xf1\x2b\x69\x8e\x54\x67\xbb\x72\x8f\x4b\xfd\xea\x17\x87\xa4\x15\x57\xf8\x0b\x62\x6c\x4f\x9b\x9d\xc6\x36\x5e\x97\xc7\x3c\x5a\x7e\x26\x84\x8d\xde\xc6\xa7\xb4\x64\x61\x0f\xc7\x8d\x26\xc5\x2b\x53\x45\xcb\x3b\x5a\xc6\x54\x5a\xf9\x1a\xb8\x51\x34\x5b\xf5\xfe\xad\x22\x28\xac\x22\x03\xd3\xf8\x51\x66\x15\x5d\xaa\xab\x55\x04\x80\x7f\x68\xa1\x5d\x7a\x09\x03\xfb\xe2\x11\x8f\xf4\x6a\x86\x9e\x01\xf5\x40\xa3\xa2\x3f\xfb\x4c\x19\x18\x03\x43\x9b\xda\xa7\xf6\xbf\x19\x79\x0e\xa3\x8c\x51\xa6\xc2\x0b\xb1\xeb\x0d\x14\x3d\x33\x30\x58\x45\x02\xca\x4a\x2e\x95\x82\xb4\xe2\x02\xc2\xbe\x53\xa6\x47\x32\x2b\x94\x52\xa4\x2b\x04\xad\x83\x1d\x69\x89\x1d\xed\xc4\x8e\x56\x2c\xa1\x04\x3c\x27\x0d\x21\x56\xb5\x38\x24\x8b\x72\xaa\x5e\x42\xe1\xca\x41\x28\x48\x21\x2d\xbb\x97\xea\x01\xb8\x5f\x45\x90\x4a\x29\x21\x45\xf3\x5b\x04\x92\x59\xd9\xaf\x56\x91\x21\x69\x66\xcd\x9f\xc0\x2a\x24\x3f\x0b\xcf\xfa\x77\x7f\x21\x95\x64\xf4\xd5\x2a\x52\xc4\x95\x84\x74\x8c\xf5\xfd\x5a\x55\xab\x0f\xc0\xf6\x63\x45\xa4\x81\x11\xf4\xa9\xc4\x13\xe6\x44\x95\xa1\xb7\x6c\x2e\x81\x6b\x2c\x18\x5b\x0a\xa3\x8c\x14\xa1\xb1\xc2\x69\x93\xc7\xc0\x3b\xbc\x0b\xd4\xf6\x77\x6b\x66\x0d\xd2\x9b\xec\x77\x7f\x5a\x04\x76\xcc\x54\xcd\x14\xfd\xa3\x4d\xe9\x9f\xe1\xb7\xf5\x6e\xb3\xf6\x17\x53\x76\x6e\x07\x0f\x9c\xa7\x81\x3d\x6c\xd0\xd3\xe0\x3c\x6d\x50\xd7\x4a\x5a\x22\x8d\x23\x56\xcc\x79\x02\x41\xe6\x93\x30\x8a\xf7\x20\x27\x1b\x04\xa2\xbd\x40\x2e\xf2\xe4\x3c\x85\x07\x32\x03\x85\x90\x12\x3d\x41\xe3\x24\x10\x04\x21\x57\xd1\x93\xf5\x03\x31\x0f\x54\x59\x08\x08\xa5\x1c\x44\x0d\x32\xa4\x0a\x8d\xa6\x41\xce\x0c\xd2\x42\x2f\x48\x01\xe1\x80\x86\x54\xe1\xa0\xe3\xfd\x89\x13\x8b\xc2\x9e\x0c\xa1\x98\x13\x0a\x4b\xb7\x87\x39\x2b\x11\x21\x1a\x16\x8d\xdd\x19\x60\x89\x84\x9c\x24\x91\x03\xb2\xa1\x4f\x40\x4c\x08\x41\x2b\xce\x4c\x06\x52\x09\x2f\xda\x38\x47\xca\x09\xe2\xa8\x69\xf9\xcd\xc2\xfb\x8d\x7c\x97\xdf\x40\xe2\x91\x81\x28\x3d\x71\xb6\xa8\xc9\x3a\x6f\xb5\xc0\x01\x83\xcf\xec\x64\xaa\xd5\x1a\xc1\x32\x1b\x89\x9d\x81\x85\xdd\xf0\xe6\x10\x63\x1f\x62\x9a\xee\x71\x0f\xce\x57\x6c\xc6\x2a\x17\x36\x2b\xd4\x58\x36\x18\xc8\x10\x9d\x4c\x52\xeb\xe6\x4a\x80\xdd\x33\xdc\xfb\x01\x0f\x95\x5c\x14\xe4\xbd\xc1\x05\xde\xc9\xbb\xdd\x15\x7b\xad\x33\xba\x4f\x87\xb6\x62\x55\x7b\x56\x63\x3b\xd7\x2a\x07\x07\xf2\x43\x46\xa4\x7a\xf6\xe4\x0c\x87\x4b\x36\x9d\x15\x51\xa9\x6b\x56\xad\x6d\xb5\xda\xa5\x11\xba\x8b\x75\x69\xc9\x9e\x5c\x7b\x02\x9c\x27\x98\xc1\x20\xab\xd9\xac\x23\xc1\xe5\xab\xee\x93\x51\x07\xaa\x13\x11\xfc\x67\x02\x90\xae\x12\xd2\x6a\x1b\x64\xca\x56\x5e\xa7\xd4\x39\x89\xc0\x19\xad\x52\x24\x9c\x08\x57\xed\x54\x60\xb9\xb3\xf9\x03\xc6\x19\xd4\x3e\x71\x25\x99\xd7\x8c\xa9\xa6\x7a\x81\xe0\x81\x0c\x10\xe8\x68\xc9\x9e\x14\xf6\x9e\xda\x9a\x23\xf7\xca\xb0\x1d\xc7\x38\xe2\x56\x09\x4d\x46\x94\x9b\xbc\xc7\xfc\x41\xd6\xaf\x6b\x3c\x5c\x8d\xf7\x13\xdf\x07\x8c\x16\xb0\x3a\xeb\x1b\x9f\xda\x67\xae\x8b\x01\x5c\x23\x33\x29\x59\xfb\x2e\xd0\xee\xee\x1b\x29\x67\x6c\x50\xda\xa7\x27\x92\x3c\xc3\xaa\x26\xc7\x38\xf2\xa6\x99\x75\x26\xfe\x95\x3a\x5b\x19\x29\xd2\x38\xed\x5b\x5b\x39\x72\x17\xc0\xc2\xd1\x2c\x45\xe5\x9d\x35\xe3\x0d\xca\x3b\xed\xa4\xb7\x9e\xf4\xd6\x83\x34\x1e\xd7\x67\x03\x09\x8f\x35\xac\x62\x4f\xf6\x6f\x85\x8a\xa4\xc2\x76\xa6\xfd\x18\xcd\x02\xe0\xcf\xde\xef\xe1\xc3\x12\x89\xb9\x93\x48\xd4\x05\xe0\x3d\x12\xc1\xf9\x83\xe1\x5c\xce\x1c\x99\x09\x79\x49\xd1\xfe\x4f\x37\x37\x0b\xbb\x88\xc6\xc9\x5d\xc4\x94\x50\xa9\x27\x72\x24\x2f\xf5\x04\x6f\x77\xe2\x4b\xc1\xb9\x50\x19\x07\x9a\x64\x7e\x0e\x15\x8f\x84\x96\x37\xd3\x21\xc3\x81\x41\x48\xee\x7b\x24\xe5\xf6\xd1\x8a\x4b\x71\x05\xe9\xea\x7f\xd0\xdf\xc0\x17\xac\xdf\x29\xd1\x49\x7a\x32\x14\x7b\xc3\x40\xf4\x64\x3a\xe9\xd3\x5a\xb7\x49\x7d\xb2\x4f\xfc\x8e\xa5\x9e\xc1\xf7\x27\xa6\x6e\x26\x94\xcf\x47\xd4\x87\x54\x9d\x88\x13\xdc\xf5\x26\xa8\xba\x93\xb0\x37\xea\x97\xc0\xa7\x59\xd3\x33\xb8\x5a\xd0\x94\x00\x74\x56\xb4\xc6\xe4\xec\xdc\xff\xeb\x37\x1b\x3a\xa1\x9d\x9d\xcd\x86\x7a\xb7\xb0\x51\x04\x09\x31\x72\x90\x6e\xa9\x4d\x1d\x0f\x7c\x13\xef\x52\xe4\x65\x1d\x23\xd7\x83\xe1\xef\x1e\x35\x73\x3e\x4f\xe6\x75\xa7\x7d\xc5\x7c\x2d\xc6\x0a\x1c\x9a\x3d\x5e\x70\xa6\x70\xd2\x54\x45\xd2\x0c\xf5\x82\x0a\x41\x3d\xe4\x26\xc4\xbc\x5b\xa5\x11\x49\x7c\x03\xa8\xc4\xa8\x24\xd5\x7a\x53\x7b\x6b\xd3\xa1\x83\x4b\x9e\x55\xbb\x33\x7f\x87\x55\xbc\x9a\x82\xaf\x33\x38\x05\x4d\xb6\x0a\xfc\xfd\x17\xcc\xb0\x79\xfd\x41\xa4\x75\x73\xe6\x3e\x08\x1c\x8a\xb9\xf7\xe7\x19\x85\xc1\xd8\x11\x2e\x76\x02\x51\xbd\xa4\xbe\x51\xf3\x5d\x09\x57\xa3\x7b\x66\x2c\x08\xd8\x90\xed\xbe\x2b\xbd\x01\x11\xbb\x21\xe5\x8f\x5b\x96\xe6\x80\xa0\x27\x34\x48\x6a\x10\xd5\x20\xab\x8b\xd6\x6b\x46\x85\x0f\xb1\xdf\xeb\x0f\xcd\x73\x89\xa1\xc3\xd1\xb9\x4a\x36\x4d\x22\x17\xa5\x58\xb4\x3a\x12\xe3\x3a\x92\x8f\x7b\x28\x82\x56\x95\x33\x55\x3b\xc8\x94\x6f\xcf\xe7\xaa\x8a\x93\x6a\xeb\xa1\x70\xaf\x87\xfa\x92\xc6\x54\xb7\xa1\x66\xe0\x46\x07\x3d\xb5\x04\x2a\x88\x55\x2b\xb8\x99\x12\x9d\xc3\xc7\x84\xf3\x09\x26\x04\x1a\x2f\xc3\xc3\x45\xb7\xd7\x05\xab\x52\x58\x23\x86\xa0\x21\x6e\x13\xba\x8d\xd3\xb5\x12\x77\xea\xdc\x62\x12\xe0\x03\x07\xa7\x68\x34\x9a\x6d\x2b\xbd\x8b\xb3\xa1\x8c\xd6\x31\xb7\xe2\x12\x2d\x82\x3b\x86\x01\xab\x85\xd7\x24\xfe\xd6\x5c\x20\xb8\xb1\x70\xd7\x81\xe1\x6d\xc9\x58\x5e\x69\x64\x98\xce\xf5\x47\x05\x46\x87\xcc\xe6\xb6\xe1\x2d\x08\xf5\x0b\xc2\x50\xc3\x20\x5c\x7f\x30\x3c\x74\x5d\xd8\x65\x66\xc5\x09\x77\xf8\x9a\x62\xfc\x78\xda\x06\xea\x39\xde\x4e\xee\x70\x1d\x10\x1c\xd0\xaf\xf5\xdc\x15\xd0\xaf\x34\x26\x1d\xa0\x8f\xe4\xce\x2e\xd0\x47\xc3\xbe\xbb\xbf\x81\x4b\xb9\xe6\x9e\xab\x5c\xf0\xc4\x90\x44\x9d\xd3\xe0\x2a\xfa\x33\x00\x00\xff\xff\x1c\xdc\xe5\xe3\x81\x1d\x00\x00") + +func fontsDoomFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDoomFlf, + "fonts/doom.flf", + ) +} + +func fontsDoomFlf() (*asset, error) { + bytes, err := fontsDoomFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/doom.flf", size: 7553, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDotmatrixFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x5c\x4b\x6f\xdc\x38\x0c\xbe\xcf\xaf\xe0\xc1\x07\xe7\xb0\x69\x9b\x62\x81\xdd\xdb\x00\xfb\x23\xf6\x48\xa4\x6d\x02\x04\xc8\xa6\x40\x1e\xfb\xf8\xf7\x8b\xd8\x7a\xf0\x25\x4b\xb2\x25\xcf\x4c\xa6\xc9\x34\xf9\x2c\x53\xa4\x48\x91\x14\xe9\xc9\xfd\xe3\xfd\xcd\xed\x00\x5f\x3e\xbf\x7f\xdd\x7c\x85\xcf\xf0\xf5\xf0\xe3\xe7\xeb\x5f\xb7\xaf\xcf\x0f\xff\x5e\xdf\x3f\xde\xc3\xb7\xff\xe0\x8f\xb7\xe7\xd7\x87\x17\xf8\xf3\xf6\xe9\xe9\xee\x19\xc6\xef\xff\x4c\x3f\x1c\x6f\xbf\xbf\x5c\x7f\x7b\xbb\xbe\xfb\xf1\x76\x75\x78\xbc\x7d\x79\x85\xe7\xbb\xbf\x1f\x5e\x1e\x7e\x3e\xc1\x2f\xf0\xdb\xa7\x9b\x2f\x9f\x7e\xff\xf5\x70\x80\xe9\x35\xf8\xd7\xfc\xeb\xf1\x83\xc1\x1e\x07\x18\x00\x61\xf0\xbf\x10\x78\xc4\xab\x6e\xb0\xfb\x56\x70\x15\x27\x29\x22\x14\x76\xf8\x00\x80\x30\x7d\x0f\x74\xf8\x00\x23\x5e\x4d\xdf\x9b\x60\x3a\xf5\x69\xe0\x77\x7c\xfa\x11\x21\xbc\x0f\xf3\xf0\x77\xf8\x9d\x67\xff\x1e\x60\x9c\x00\xff\xee\xe1\x11\xaf\xe8\xd7\xca\xd1\x89\x29\x93\x30\x7d\x2d\xc0\x04\x47\x72\xc1\xc3\x9e\xbb\xe9\xa2\x87\x91\x32\x18\xe0\x11\xaf\xcc\xd1\x40\x47\xa3\x49\x7b\x92\xd3\x18\x4d\x39\xf1\x22\x0a\x06\x85\x40\x29\xd8\xaf\x78\x14\x52\xae\xf8\x0c\x92\x15\x0f\x30\x3a\x4e\x18\x71\x74\xb7\x30\x18\x03\x8b\x04\x76\x20\xd2\x29\xc3\x48\xae\xe4\x70\xbb\xd2\x7d\x85\x36\xdd\xda\x06\x49\xdd\xf0\xa8\x37\xe4\xf0\x8c\x08\x79\xa2\x26\xd8\x5a\x79\xab\x45\xbe\x56\x8e\xf3\xf7\x0b\x74\xad\x28\x6d\x34\x69\xf3\xd1\xa6\x98\x16\x1c\x3c\xb0\x17\x94\x6d\xe5\xd9\xab\x28\xa7\x92\x86\x21\xf0\xc1\xe1\xb0\xa7\xc4\x68\xf2\x43\x57\x58\xe0\x68\x0c\x9f\xb4\x21\x61\x34\x19\xf7\xc6\x55\x0c\xa3\xc9\x61\xf0\x56\x8a\x71\x83\x93\x4a\x31\xd1\x1c\xee\xbc\x84\xad\xb6\x2a\x56\x6c\x18\xad\x25\x34\x4d\x22\xb1\x56\xe5\x62\x2e\x6c\x65\xbf\x5d\x91\xc1\x64\xaf\xb1\x38\x13\xf7\x5a\x49\xe4\x40\xb7\xd7\x14\x6d\xbf\x2a\x6b\x22\x47\x3e\xa0\xa4\x86\xa3\x09\x6b\xdf\x89\x2c\xfe\xe4\xc5\x34\x89\x2c\xc1\x1b\xc5\xf4\xbf\x90\xff\x77\x82\x2d\xaf\x17\x22\x56\x21\x6c\x7a\x3d\x97\x91\x95\x1a\x6d\x0d\x8c\x40\xbf\x8a\xb4\xb9\x75\xca\x62\xf8\x23\x68\xb3\x60\xca\x80\x87\x17\xb2\xe1\x1e\x9c\x4d\x80\xc3\x21\xb7\xa1\x70\x4c\x78\x08\x4c\xc0\x08\x33\xd0\xc3\x02\x74\xb0\x04\x35\x83\x19\x98\xe0\x34\xe3\x0b\xac\xf8\x3c\x00\x29\x4c\x73\xaf\x08\x13\x5e\xe8\xa2\xd4\xc1\xd1\x87\x31\xda\x00\x34\xc7\xda\x24\x26\xc9\xdd\xe3\x70\x04\x4b\x11\x6c\x46\x46\xbc\x01\x1c\xdc\xb5\x31\x65\xb8\x61\xad\x98\xc8\xd4\xe9\x2c\x88\x10\x8f\xb6\x4c\x79\xb3\x6c\x39\x2c\x0d\x5f\x42\xcd\xa1\xb5\x84\xf4\x90\xc3\xa6\xe4\x27\x97\xb5\x62\x22\x17\x34\x6e\x14\x72\x86\xb2\x36\xca\xf4\x8b\xd8\xb2\x7e\x87\x31\x58\x10\xa1\xa6\x43\x88\xb8\xcc\x5d\x13\x11\x52\x6e\x31\x5a\x90\xda\xf4\x58\x42\x11\x02\x46\x76\xf4\xa5\x8b\x82\xcc\x12\x8b\xf4\x93\xb0\xce\x6d\x46\x8b\x52\x9d\x4b\xac\x08\xab\xb2\x46\xdb\xee\x9a\xd9\x32\x9a\x30\xa5\xcd\xa5\x6f\xb4\x37\x2d\xa3\x65\x76\x4b\x60\xe9\xf5\xa3\xef\x64\xe2\x07\x98\x19\x7e\xd6\x01\xf7\x13\xb3\x4a\x9b\xf1\x85\xd6\x46\x41\x8b\x15\xba\x30\x6c\x09\x15\x87\xe9\x25\x2c\x92\xa7\xbb\x0b\x4a\x79\x8f\x26\x44\x9a\xb9\xa0\xcd\x01\xa5\x60\x5b\xd9\xb1\x40\x64\x58\x54\x46\xd0\x62\x66\xe4\xc9\x89\x79\x92\x74\x74\xff\x9c\xf6\x82\xc5\x2c\x3c\x88\xb1\xb3\xcb\x5c\xf8\xe0\x70\xa8\x06\x11\x18\x09\x1d\x0f\x23\x3b\x10\x7b\x98\xa6\x6e\x9c\x48\xb8\xa2\xa6\x8c\xd5\x20\xc9\xa0\xe6\x04\x4c\xda\x1c\x3e\x76\x3f\x58\x9e\xc5\x31\x34\x2a\xc2\x5a\x95\x96\x8a\xd8\x6e\x12\x25\x6a\x5b\xd0\xa6\x9f\x32\xb6\x05\xc0\xc1\xc4\xd5\x92\x02\x33\x8f\xec\xba\x08\x8c\x06\x8c\xbc\xfd\xe1\x60\x59\xf4\x89\xa3\x2d\x38\x35\x1a\xcc\xd1\x5a\x9b\x49\x31\x49\xd0\xa3\x75\x74\x57\xbc\x13\xf2\x8c\xae\x8e\xce\xcc\x70\x86\xdd\x0d\x05\xa3\x09\x6d\x56\xba\x07\xc3\xc4\x6b\xc5\x04\xbe\x86\x2c\xfe\x60\x68\x2e\xd0\xd8\x36\xc6\xda\x23\x4b\x26\xfc\xaa\xf3\x28\x6b\x84\xd3\x85\x7c\x99\x58\x4a\xf1\xd9\x4f\xf3\xcd\x61\x9d\xec\x01\xe4\x92\xf1\x85\x7a\x00\x8b\xed\xed\x72\x5a\x99\x03\x9d\x38\x0b\x32\xe6\x2c\x81\xb3\xba\xef\x90\xba\x33\x56\x4c\xe2\x23\x29\x05\x95\x29\x79\x11\x96\xba\x9f\xd9\x60\xc9\x5e\x23\x6d\x56\x9f\x37\x0d\xe2\x51\x11\x12\xb6\x2a\x47\x59\x22\x3d\x8a\x24\x67\x25\x66\x39\x5c\x2b\x66\xc3\xbd\x69\xac\x95\x10\x36\x47\x64\xd5\x31\xa7\x48\x4c\x5a\x7f\xaa\xf2\x35\x79\x0e\x9b\x44\x8e\x46\x01\x25\xa1\xcd\x25\xff\xa6\xcc\xb0\x19\xdc\xb5\x4e\x6b\xd8\x9b\xa6\xcf\xa9\x24\xe6\x2c\x84\xd1\x84\x7d\x12\x24\x47\x37\x39\x56\xe7\x8c\x56\x9a\x21\x18\x75\xcd\x31\x3c\xfd\xc3\xe6\xa4\x5b\x5b\x8c\x06\xad\x36\x1a\xab\xf2\xdb\x67\x8b\x98\xc6\x9c\xfb\xc2\x5d\x03\x4a\x78\xa9\x94\xc4\xd0\x26\x75\x9f\x74\xb4\x6f\xca\x2b\xdd\xd3\xf7\xd3\xb9\xa0\x9c\x98\x72\xce\x90\xb5\x4b\x56\xdc\x05\xcd\x61\x78\x06\xcc\xb0\xce\x1d\x3d\x6d\x93\x02\x66\x13\xb8\x67\x01\x53\x26\xb5\xc1\xed\xd5\x1d\x2e\x72\x27\x14\x30\x89\xc0\x6a\xb8\x56\xcc\xfe\xda\x44\x13\x26\xee\x59\x68\xd3\xef\x18\x1d\x50\xa8\x92\xeb\xc4\xac\x3a\x6f\xae\xcf\x82\x38\xed\xfd\x03\x4a\x23\x6d\x9a\x44\x94\xe9\x6b\xaf\xb7\xd7\xde\x5c\xd1\x2a\xea\x97\xec\xd5\xc2\x55\x62\xc6\xd7\x5e\x2e\x35\x01\xf7\xd5\x26\x93\x72\x65\x08\x0f\x4f\xf8\x31\xdd\xfb\xf1\xdc\xd3\xf2\x94\x81\x72\x18\x1e\xfc\x93\x8c\x6f\xd5\x26\xcf\xf5\xbc\x36\xb9\x13\x0f\x4b\x9b\x81\xd1\x82\x91\xa6\x0d\x01\x0e\xf9\x12\x85\x31\x48\x4f\xb5\x19\x27\xed\xa2\xcd\xa4\x7e\xd0\x7c\xfc\x29\xa5\x88\x16\x55\x50\xb6\xb0\xe7\x29\xe6\xf9\xb8\xa0\x33\x69\xca\xf7\x7d\x2e\x28\x36\xae\x58\x9f\x70\xa0\xf5\x7c\x0e\x83\xbb\xaf\x0b\x5c\xce\x49\x90\x64\x19\x36\x02\x0a\x18\x46\xcb\x17\x4b\x5e\x60\x46\x6b\xc0\xfc\x02\x5b\x71\xb9\x37\xd5\x05\xa5\x9f\x1d\xb5\x19\x26\xec\x01\x93\x1e\x54\x53\x6d\xc6\x0e\x64\xb8\x74\x3c\xb0\x0e\x24\x02\x6f\xe3\xd2\x8c\x54\x7d\x24\x26\xf0\x7e\x3c\xc1\xf3\xc1\xe9\x36\xae\x84\x61\xfe\x10\xd2\xd9\xc3\xa8\x5c\x27\xc2\xf1\x20\xbc\xd5\xfc\x15\x9f\x3d\xa0\x4f\x3b\x78\xe5\x8b\x4f\xd5\x64\x61\xa7\x65\x05\xcf\xb8\x86\x01\xcc\xd1\x1d\xe0\xca\xad\x2c\xcf\x33\x0c\x16\xa7\x36\x35\x9a\x85\x1f\x34\xb3\x54\xde\xf7\x6b\x7d\xde\x54\xae\x56\xa6\x58\x0a\x6e\x52\x6b\x48\xc0\xe5\x25\x88\x5a\x31\x4b\x87\x87\xc8\x6e\xd5\xe8\x71\xb9\x4d\xa8\xd7\xca\x86\x6b\xeb\xff\xeb\xc4\x2c\x8a\x56\x66\x3b\x47\xda\xe1\x4a\x6d\xf6\x6b\x15\x15\x0f\x3f\x30\x21\x4b\x8c\xb6\xa0\x76\xa2\x4e\x73\x99\x12\x44\x9e\xc1\x65\x31\x25\xe3\x33\x68\xec\x08\xde\xcd\x31\xdc\x84\x20\x62\x24\xaf\xcd\xe0\x7a\x31\xcb\xa9\x18\x89\xfe\x89\x8c\xb6\xec\x49\x85\x73\xf4\xb4\xe5\x70\xb1\x7a\x28\x9e\xcc\xba\x35\x6c\x74\xdf\x83\xa0\xc5\x44\x92\xb4\xc7\xae\xfd\x4d\x22\xaa\x3e\x2e\x68\xd8\xdc\xc9\x90\x8e\x6d\x9b\x60\x37\x93\x38\xc9\xf3\x4f\x79\x2f\x2c\xf8\x5a\xa3\x65\x37\x51\x58\xcd\x39\xa9\x46\xab\x8d\x36\x9c\x24\x11\x7d\x6c\x73\xf7\x9b\x95\x09\xcd\xa0\x86\x77\x31\xc3\xf3\x33\xda\xcc\x70\x1a\x37\x65\x6c\x73\xfa\xd1\x59\xaa\x78\x6f\x07\xef\x22\xe6\xa5\x7a\xda\x62\x31\xed\x9c\x76\xf5\x13\x7e\x02\x2e\x8b\x84\xfd\xc5\xcc\xf7\xcf\x10\x2c\x31\xb5\x2d\x9b\x30\x3b\xa0\x68\xda\x60\xd2\x86\x65\x78\x9d\x36\xf3\xfd\xb3\xf5\x62\x9a\xa7\xd3\x6c\x4e\x9b\x81\x57\x6a\x93\x08\x2b\x39\x54\xac\x08\x6f\x4d\x60\x6b\xca\x3a\xb8\x94\xef\x3d\xb4\x59\xd3\xf6\xa4\xb4\x47\xec\xf0\xf9\xcd\x64\xe5\x55\xc3\xec\xef\x02\x99\x9e\xb6\x80\x88\x4c\x33\x28\x2c\xf7\x26\x10\x51\x97\xe5\x69\xeb\x82\xdc\x8b\x8a\x19\x65\x61\x62\x56\xc3\x51\x95\xf4\xf4\x13\x17\x70\xa7\x80\x22\xf3\x42\x9c\x60\x51\x88\x9f\x74\x41\x18\x8f\x20\x65\xbc\x4d\xbf\xa9\x8f\x98\xb0\xaa\x1b\xaa\xdb\x9e\x51\x65\xa2\x91\xe9\x54\x26\x8c\x96\xa6\x40\xfb\x65\x41\x44\x48\x96\xa3\x83\x8e\x05\x69\xfd\x58\x6d\xcf\xf9\xee\x51\x54\x41\x95\x8d\x7f\x5c\xa3\xd5\xc7\x1c\x34\xff\x14\x86\x0c\x60\x8d\x03\xca\xb2\xd3\x47\xe3\x60\xc9\x9e\x4b\x0d\xb4\x27\xac\x4b\xc9\x6b\x20\xdc\x0f\x71\xf8\x00\x31\x1c\x0a\xd8\xf3\xc7\x60\x34\x61\x72\xac\x2a\x21\x12\xdd\xad\xe4\x04\x4c\x4e\xfc\x6b\x11\x0e\xe2\xcf\x6d\x94\x41\xae\xca\xfc\xa1\xad\xcd\x70\x57\xda\xaa\x87\xa2\xe1\xa8\x08\x6b\xc5\x49\x22\x6e\x2d\x6d\x0a\x36\x14\x41\x5a\x96\x19\x22\x71\xc3\x69\x4e\xf2\x6a\x5b\xd0\xe6\x42\x9f\x30\x4a\x2f\xfe\xe4\x5f\x0c\x05\xa2\xbf\xe9\xf9\x39\xbb\xfe\xa6\x17\x03\xc0\xec\x5c\x98\x7f\xac\xe3\xd2\x3e\x08\x58\x20\xa6\x11\x94\x9b\x3c\xc8\x58\x07\x6f\xcb\xe8\x65\xea\xce\x15\x41\xe5\xbc\xe8\x47\xf9\x16\xc5\x54\xea\x54\xda\x64\xa3\xdb\xb4\x71\xfd\x3d\x3d\xda\xb8\x95\x46\x7b\xb1\xb5\x20\x2e\x25\x59\x43\xc6\x52\xb0\x65\xb6\x36\x92\xf1\xb3\x3c\x88\x19\xff\x8e\x87\xff\x03\x00\x00\xff\xff\xd5\x8f\x77\xd0\x99\x5b\x00\x00") + +func fontsDotmatrixFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDotmatrixFlf, + "fonts/dotmatrix.flf", + ) +} + +func fontsDotmatrixFlf() (*asset, error) { + bytes, err := fontsDotmatrixFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/dotmatrix.flf", size: 23449, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsDrpepperFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x56\xdd\x6e\xe3\x36\x13\xbd\xe7\x53\x1c\xe4\x33\x3e\xed\xa2\x89\x98\x68\x93\xa0\x5d\x08\xaa\x8a\x76\x0b\xf4\xae\x40\x7b\x49\x60\xc2\x58\x94\x2d\x54\x96\x02\x89\xee\x6e\x00\x3e\x7c\x41\x52\x92\xf5\x67\xaf\x01\x5b\x7f\x3c\x1c\xce\x9c\x19\x1e\x4e\x5e\xe6\x91\xdc\xe0\x09\x8f\x88\xee\x71\x8f\x87\x67\xf6\x7b\x5d\x69\xe0\x33\x7e\x6b\x42\xfc\xa9\xde\xde\x54\x83\x0f\x32\xd7\xaa\x81\x44\x25\x0f\x0a\x45\x85\xba\x52\x68\x8b\x1d\x32\xfb\x50\x54\xd0\xfb\xa2\x45\xab\xdf\x4b\xf5\x31\x64\xbf\x1c\xf5\xbe\x6e\x3e\xe3\x8b\x6a\x6a\xfc\x2d\x0f\x87\xa2\x52\xd5\x2d\xf4\xc3\xd3\xfd\xa7\x87\xa7\x74\xbb\x0d\xf5\x51\x87\x79\x11\x32\xf6\xeb\x5e\x36\x72\xab\x55\xd3\x22\xf8\x5f\x00\x59\x65\x08\xfe\x1f\x40\x36\x0a\x65\x7d\x6c\xdf\xdd\x97\x3f\x82\x03\xaa\x5a\xe3\x5f\xd5\xbc\xa3\x95\xba\x68\xf3\x42\x65\xec\x6b\xa1\xf7\xd0\x7b\x85\x60\x13\xa0\x6e\x10\xe8\x20\x0c\x43\xfc\x75\xdc\xed\x54\xab\x8b\xba\x6a\x7f\x66\xec\xcb\xb7\xb7\x52\x56\xd2\xbe\xa2\xce\x91\x17\x4d\xab\x51\x16\x95\xfa\xcc\x6c\xe8\xb8\xc3\xcd\x41\xee\x8a\x2d\xaa\xe3\xe1\x55\x35\x37\xc8\xeb\x06\x79\x51\x2a\x14\x99\xaa\x74\x91\x17\x5b\x3b\x97\x49\x00\xb8\x43\xbb\xaf\x8f\x65\x06\x59\x7e\x95\xef\x2d\x5e\x15\x5e\x64\x70\xeb\xe6\x54\xf5\x57\xb6\xf1\x20\xeb\xd3\xcd\x5e\x36\xd9\x6b\x29\xab\x7f\x6e\x70\x77\x87\xb7\xa6\xa8\x74\x8b\x16\x12\xee\xe3\x2d\x5e\x8f\x1a\x5b\x59\x05\xda\x5a\x69\x0f\xc7\x76\xaf\x32\xf6\xe4\x0d\xec\x55\xb1\xdb\x6b\xeb\xaf\xc4\xb6\x67\x88\x3d\x5e\x18\xbc\x75\x04\x15\xd5\xb6\x3c\x66\x45\xb5\x43\xa6\xda\xad\xaa\x32\xd5\xb4\x2c\xba\xf7\xf3\x0e\xf2\x9b\x0b\x1c\xa5\xaa\x76\x7a\x8f\x0f\xea\x5b\x8f\xde\xd6\x87\x83\xaa\x3c\x2f\xed\x47\xfc\x00\xe4\xc7\x6c\xa7\x90\xcb\xad\xae\x1b\xd6\x19\xc8\x54\x2e\x8f\xa5\xf6\xce\x1e\xea\x4c\xb9\xb8\x5d\xe6\xf3\xba\xd2\xec\xe1\xd9\xc1\x3c\x91\xd6\xbf\x89\x59\xc6\x36\xe9\xf8\x97\x32\x10\x52\x66\x60\x52\x66\x88\xa7\x2c\xa6\x24\x65\x00\xfc\x08\xa5\xcc\x70\xc3\xdd\x17\x4c\xae\xfe\xe6\xde\x37\x64\xc8\xd0\x66\xf4\x00\x18\x98\x1e\x7a\x42\xa7\x0c\xc6\x90\x5d\xe3\x2e\x4e\x19\x27\xbb\x1e\x8c\xe9\x86\xc9\x8e\x24\x1c\xf6\x23\x07\x87\x45\xf0\x38\xe9\x8c\x78\x7f\xac\x8d\x18\x89\xbd\xf1\x50\xf0\x4d\xca\x04\x71\xb1\x19\x63\xac\xc7\xf6\x7d\xf8\xdb\x8b\xb5\x0d\x67\xda\x3a\xd6\x5f\x21\x48\xa4\x29\x23\xb2\x48\x01\xe1\x1c\xb4\x4c\xf8\x2b\x27\x7e\xf2\x9c\xb8\xa0\x94\x25\x40\x6c\xe7\xf1\x09\x0d\xde\x2f\x90\x81\x71\x64\xda\x77\x32\x8e\x06\x5a\xd0\xd0\xfd\x4f\x7e\xf6\xce\x33\x10\xf9\xe9\xe4\x27\x0f\x64\x77\x98\xfe\x62\x41\xe3\x34\x75\xe1\x61\x46\xdd\x64\x76\x67\x1a\x70\x89\x06\xb7\xb7\x17\x22\x0a\x26\xf4\xa6\x8c\xfb\x71\x57\x0d\xe6\x54\x08\xe4\xd7\x04\x92\x61\x85\x98\x88\x92\xe9\x0a\x2e\xb5\xe4\xbc\x88\x09\xc2\x63\xf8\x38\x06\x4f\x35\x78\xe8\xf8\xe7\x04\x84\x03\x4f\x3d\x4d\x63\x77\x1d\x13\x2f\xe4\x8c\x99\x99\xb1\x13\x26\xb1\xb7\xd0\x62\x5e\xd6\x31\xe4\xc2\xbe\x48\x4d\x8c\xd0\x06\xc7\xbd\x1d\x71\x66\xad\xd0\xf3\x06\xcf\x34\x71\xcc\xe8\xf3\x69\x99\x27\x68\x3a\x62\xba\x59\xb3\xc2\x8c\x11\xf7\x25\xc9\xe6\xee\xfb\x82\x58\x29\x8f\x59\xf1\x26\x2e\x04\x1a\x57\x67\x9f\xba\xd0\xa7\xce\x8f\xc5\x94\xac\x16\xc7\x8d\x4b\xbe\xe8\x48\x3f\xcf\x40\x5f\x47\x64\xc6\xae\x8c\x30\xa7\x8c\x9c\xcb\x1a\x7c\xd6\x62\x4b\xc0\xf9\xb5\x84\xdf\xaa\xe6\xbb\xd9\x77\x01\x99\x65\x49\xae\x60\xcc\x22\xfb\xae\xee\xbb\x61\xc4\xc4\xbb\x42\x1a\xd6\xeb\xc5\x10\x27\x6f\xce\x10\x30\x48\xe9\x7c\x07\xb9\x21\x3f\x97\xdc\x55\x0c\xe6\x3b\xe3\xe4\xf7\xa5\x93\x28\x97\x4d\x43\x43\x2d\x8c\xd4\xaf\x13\xd6\x41\x6a\x68\x96\x01\xf4\xfc\x0a\x78\xf6\x30\x72\x75\xc0\x4e\x43\x12\x93\x90\xc4\x99\x9c\x9a\x21\xfa\x85\x70\x4c\xf3\x05\x1b\xd9\x1a\xcf\x6b\x76\xc4\x05\x3b\x8e\x8c\x39\x0b\xe4\x65\xca\xe5\x54\xd0\xaa\xcc\x0c\xbb\x9e\x3a\x2d\x77\xdc\x9f\x24\x66\x25\x9d\xc1\xba\x20\x2e\x31\x86\xe6\xbb\x7e\x84\x1a\x62\xeb\x91\x27\xec\xb0\x59\xed\xf9\x28\xec\x09\xe2\x76\xbb\x4d\x93\x3f\x5c\x04\xce\x56\x9b\xf0\x54\x2c\x42\x70\x8a\x6b\x7a\x35\xea\xc4\x6d\x5e\x10\xfd\x76\x33\xeb\xb5\xe3\x9d\xea\x24\xa4\x77\xc9\x1a\x58\xa3\xbd\x17\xd2\xee\x94\xa4\x61\x67\x5a\x3b\xe0\x76\x62\xcc\x45\x72\xbe\x5d\xb8\x78\xd6\xa5\xcc\x7e\x12\x66\x71\x7a\x8f\x67\x58\xe9\x32\x3e\xe5\x66\x6d\x73\x8c\x2b\x68\x7e\xfa\x8c\xed\x70\x18\x04\xb6\x82\x0c\x85\x13\x0c\x61\x88\x8c\xfb\x6a\x15\xb3\xb5\x66\x76\xc2\xae\x12\x27\x76\x7a\xde\xdd\x22\x06\xe6\x6e\x45\x7a\xe6\x76\xfc\x5a\x61\x1f\x5e\xb0\x1a\xd7\x19\xd5\x89\xbd\xc4\xad\xaa\x8e\x3f\x7a\x46\x8d\x4d\xbc\x30\x3e\x12\x9f\x85\xea\x9c\x95\xb4\x2e\x80\xf0\xb4\x05\x82\x7e\x8f\x2c\xb5\x66\x84\x1d\xed\x25\x73\x91\xd8\xb5\x93\x78\x5a\x3e\x2b\x92\x73\x96\xd8\xbe\x74\x7d\xb1\xf6\x98\xde\x1f\xc7\xdf\x32\x41\xde\xcc\xac\x65\x9d\x35\x7e\x1b\xd7\xf8\x4d\xdb\xde\x95\xc6\x6f\xba\xe0\x20\x80\x6b\x04\x4c\x74\x67\x26\x38\x18\xa3\xa6\xca\xb3\x14\x1c\x0f\x1d\x7a\x04\x9e\x32\x3e\x69\x30\xd6\x9d\x9a\x96\x60\x97\xb8\x53\xa7\xc2\xfd\xf3\xb2\x85\xe1\x4e\x69\xc5\xb8\xb7\x36\x66\xfa\x5f\xf6\x2c\xc6\x66\x10\xc6\x1b\xe6\x63\xaf\xb8\xe0\x76\x16\x17\x1c\x8b\x76\x38\x4e\x28\x4e\xbe\xd3\x8f\xcc\x31\x6b\x67\xd7\x80\xb9\x74\x0e\xf8\xa5\x3b\xe8\xcb\xba\x00\x4d\x30\x17\x6b\x77\xba\xe4\xbc\x04\x56\x7b\x28\x84\xe3\xfa\x7e\xf8\xe9\xf9\xaa\xf8\xa3\x87\xc7\xab\x38\x88\xa2\xfb\xab\x78\x88\xa2\x4f\x57\xf9\x17\x45\x3f\x5e\xc5\x59\xf4\xf8\x7c\x15\x6f\xd1\x53\x74\x15\x77\xff\x05\x00\x00\xff\xff\xe3\x40\x2f\xeb\x45\x11\x00\x00") + +func fontsDrpepperFlfBytes() ([]byte, error) { + return bindataRead( + _fontsDrpepperFlf, + "fonts/drpepper.flf", + ) +} + +func fontsDrpepperFlf() (*asset, error) { + bytes, err := fontsDrpepperFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/drpepper.flf", size: 4421, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftichessFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\x5b\x6b\xdb\x4a\x10\x7e\xd7\xaf\x98\x68\x03\x92\x4e\xb0\x25\x27\xe4\xe4\x78\x5f\x8e\xd3\x92\xbc\xb5\x0f\x25\xf4\xa5\x2a\x2b\x63\x62\x22\xea\x44\x10\x9b\xd0\xc2\xd2\xdf\x5e\x76\xf6\xae\x9b\xe5\x58\x2d\xb4\x74\x0b\xf1\x74\xf4\xcd\xb7\xb3\xb3\x73\xd9\xf5\x66\x7d\xbe\x3c\x85\x4b\xb8\x84\xab\x39\x64\xf0\x5f\x10\xdc\x3d\x94\x5b\x58\x57\x4f\x3b\x28\xb7\x10\xaf\x12\x78\x57\xae\x1e\xee\x37\x70\xb3\xde\x95\x8f\xcb\x2f\xe5\x16\x66\xf3\xf9\x25\x4c\x26\xf0\xf1\xfe\x79\x5b\x56\x4f\x30\x9b\x66\xe2\xbf\x17\xf0\xb8\xfc\x86\x1f\x03\x60\x47\x2c\x00\x48\x0b\x14\x02\xde\xdc\xbc\xb1\x38\xfe\x0d\xaf\xb7\xab\xb2\x9c\x5c\x3f\xef\xca\xed\x2e\x44\x55\x94\xa7\x0a\x11\x08\x8c\x64\x9a\x1a\xa6\xc5\xcb\x66\x5b\x4e\x57\xd5\xa3\xc7\xe3\xad\x37\x55\x95\x4c\x20\xce\xb2\x44\x22\x24\xd1\xdd\xfd\x06\x28\xc4\x17\x17\x09\xcc\xcf\x61\xfe\x2f\x9c\x5f\xc1\x6c\x5e\x77\xa8\xb9\x62\x56\x44\x2c\xd1\x44\x8c\xc1\xed\xf2\x6b\x83\x28\x9b\xd9\xd8\x71\x0c\xc2\xed\x87\xeb\xf7\x6f\x6f\xdc\x88\x02\x3b\x39\x61\xa8\xe0\x3c\x00\x7e\x4c\xac\xed\x5e\x81\xf1\x73\xb1\x5f\x3c\xd5\x6b\xb1\x08\xcc\xbf\x31\xc4\xd7\x3a\x41\xf4\x3a\x48\x1c\xd5\xe3\x31\x56\x1b\x1d\xeb\x11\x58\x43\xe8\xa0\x4b\x73\x25\x70\x99\x81\x00\xa9\xfe\xc4\x21\xd7\x9f\xa0\x26\x58\x0c\xe3\x2e\x5d\x3a\x99\xe4\x35\xba\xdc\x1a\xeb\xaa\xd3\x4e\x99\x7a\xc8\xd9\xff\x5a\xc3\xfd\x1b\x1c\x63\xe9\xbb\x10\x3f\x29\x97\xce\x72\x30\x4a\x8b\x61\xea\x24\x89\x84\xb2\x1e\x0c\x4b\xdc\x9f\x1a\x06\xa6\xce\x5e\xd1\xa4\x67\x2f\xee\xd3\xd5\x79\x94\xcf\xf8\x13\xb7\x63\x98\xf2\x32\x75\xa0\xed\x7b\x29\x82\x56\x9e\xdf\xaf\xd0\x0c\x85\x71\xc7\xd5\xc8\x61\xd1\x8f\xd1\x87\x20\xe4\x53\x11\x15\xd1\x67\x02\x90\x17\xdf\xa3\x54\xa0\xa2\xfc\x25\x2d\x04\x2a\xcd\xff\x11\x15\x42\x08\x2f\xce\x22\x2e\x34\xf8\x49\x68\x10\x2c\x34\xd2\x1c\x99\x08\x07\x40\x54\x5c\x41\x95\x08\x54\x5c\x41\x96\x10\x02\x29\x6a\x72\xa9\xa9\x12\x85\xc9\x34\x46\x6a\x44\xf6\x73\x50\x4c\x8c\x21\x13\xe4\x90\x82\xb0\x23\x31\x4b\xa4\xe7\x31\xd6\x56\xab\x06\xc1\x44\x16\x99\x66\xb2\x27\x0e\xdb\x63\xd0\xae\x09\xc5\x9f\x46\x11\xe9\x1c\x50\x61\x10\xa2\x3a\x07\x02\xa4\x23\x7e\x66\x78\x76\x2a\xc4\xca\xae\xd2\x76\xf2\x90\xd2\x2e\xfc\xe9\xf3\x03\x2f\xb3\xe9\xc4\x5e\xe7\x39\x3d\xa3\xc6\x8e\x5a\x3b\xda\xb4\xeb\xda\x3a\xa2\x2f\xd4\xc4\x8d\x66\x7d\x14\xa0\xdb\xb6\x87\x10\x77\x4b\x79\x5d\xec\xb1\x63\xd6\x0e\xac\x1d\x6b\xb5\x93\x75\x83\x9d\x44\x26\xfe\x22\x30\x99\x3b\x2c\x44\xa6\x18\x9c\x6c\x76\xd2\x71\x48\x88\x3c\x0a\x4a\x0d\x85\x12\x87\x50\xe4\xc5\xd4\x66\x99\xbd\xa8\x9c\xa6\xb4\x9e\x65\xb5\x53\x53\x7b\x6a\x6a\x4f\xdd\x7f\xc1\x43\x2b\x6a\x48\x2f\xfa\xcb\xd4\xa9\x69\xcd\x71\x0f\x7f\xb8\xc6\x49\xea\x81\x1d\xb6\x4b\xe3\x54\x18\xce\x01\x4e\x54\x47\x3f\x58\xe3\x14\x28\xce\x01\x8d\x3a\x5c\xe3\x64\xec\x91\xb1\x1f\xb7\x07\x1f\xeb\x8c\x6d\x12\x62\x0c\x4f\xe5\x18\x56\x9d\x95\x10\x2c\x62\xa1\x51\xed\x9a\x10\xfc\x44\x88\xe9\x0b\x66\xe4\x3b\x8d\x45\x8c\x61\xaa\x07\x33\x36\x66\xa2\x7a\x00\x31\x4d\x04\x31\x99\xc6\x48\x0d\x11\xe6\xc4\x67\x22\xd8\x68\x88\xe9\x1c\x22\x49\xa8\x4e\x9b\x86\x46\x76\x25\x87\xc9\xbb\xb4\xf0\x90\x38\x85\xf5\x4b\x73\x62\x66\x5e\x35\x42\x54\xcf\x12\x04\xe8\xfc\xed\xb4\x53\x2f\x1d\x65\x57\x69\x3b\xf9\xd6\x90\xd8\x70\xb4\x24\x69\xeb\xab\x42\x54\x0f\xb0\xba\x13\x7b\x9d\xc7\x24\xd0\x76\xd4\xda\xd1\xa6\x5d\xd7\xd6\x2a\x7d\x14\x45\xd6\x47\xe1\xd9\xb9\x08\x4e\x79\x8b\xd8\x65\x67\x0f\xa5\x5b\x82\x53\xd3\x9d\x76\x38\xb3\x51\x54\x33\x7b\x60\x88\x4c\x31\x98\x07\xac\xf3\x02\x1d\x16\x22\x8f\x82\x52\x43\x61\xc5\xbd\x14\xaa\x90\xeb\x17\x25\x4b\xc9\xcf\xb2\xda\xa9\xa9\x3d\x35\xb5\xa7\xee\xbf\xe0\x31\x7b\xd1\x9f\xcc\x34\xe2\x00\xf1\xbe\x1e\x31\xbc\x9d\xeb\x1d\xd8\x61\xbb\x34\x4e\x39\x9a\xb7\xf4\xeb\x34\x23\x33\x1d\x13\xe9\x8e\x47\xea\xaf\x15\x7f\x04\x00\x00\xff\xff\x0d\x6b\x9d\x8e\x3f\x16\x00\x00") + +func fontsEftichessFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftichessFlf, + "fonts/eftichess.flf", + ) +} + +func fontsEftichessFlf() (*asset, error) { + bytes, err := fontsEftichessFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftichess.flf", size: 5695, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftifontFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\xdd\x6b\xdc\xba\x12\x7f\xd7\x5f\x31\x2d\x86\xb5\x21\x89\x6c\x79\xbf\x7c\x29\xc5\xbd\x97\xf6\x69\xef\x5d\xb8\xb4\x0b\xe7\x44\xa9\x36\x84\x86\xee\x39\xa9\x0d\xdd\x9c\x43\x1f\x44\xff\xf6\xc3\x8c\x3e\x2c\x59\xde\xdd\x40\x8d\x23\x67\x3d\x3f\xcd\xb7\x66\xc6\x8f\x4f\x8f\xe2\x3e\x83\x05\xcc\xa1\x2a\x61\x29\x60\xcd\xd8\xc7\xaf\x87\x23\x3c\xf6\xdd\x33\x1c\x8e\x90\x3f\x14\xf0\xdf\xc3\xc3\xd7\x2f\x4f\xf0\xfe\xf1\xf9\xf0\xed\xfe\xcf\xc3\x11\xaa\xa6\x59\xc0\xf5\x35\xec\xbe\x7c\x3f\x1e\xfa\x0e\xc4\x4d\x89\x3f\xc5\x0a\xfe\xb8\xef\x88\xca\x40\xfd\xc2\x05\x00\x7c\x4f\xff\x30\x9d\x4a\x4f\x2e\x4d\xeb\xeb\x77\xc7\x87\xc3\xe1\xfa\xdd\xf7\xe7\xc3\xf1\xf9\x35\xbd\x9a\x49\x6e\x11\x0c\x31\x86\xd3\x8d\xe7\xd4\xfe\x75\x7c\x7e\xb8\xf9\xfb\xe9\x78\xb8\x79\xe8\xbf\x39\x3e\xd1\xf5\xef\xbe\x2f\xae\x21\x2f\xcb\xc2\xf0\x31\x8c\x3e\x7e\x79\x82\x7f\x41\x5e\xd7\x05\x34\x02\x9a\x25\x5a\x5e\x35\x63\x85\xd2\x2b\x57\xfb\x99\x2a\x1c\x23\xa5\xe0\xc3\xfd\x8f\x84\x51\x59\x0d\xbe\xd3\xe4\x84\x0f\xff\x7f\xf7\xbf\xff\xbc\x0f\x3d\x0a\xea\xd5\x2b\x45\x2f\xb4\x66\xa0\x7f\xc5\xd7\x83\x2c\x96\xb5\xe1\xdd\x32\xad\x5b\xb6\xd1\x2d\x03\x68\x59\x5e\xd0\x13\x17\xfc\x79\x7b\x77\x7b\x87\xff\x67\x30\xac\x9e\x4c\x08\xa5\x35\xde\x2d\x03\xad\xf1\x6e\xd9\xf5\x46\xe3\x3d\x60\x90\xb6\x81\x96\x71\x50\xba\x65\x52\x81\x6c\xd1\x2b\xbc\x65\xb0\xd1\x83\xac\xbc\xe0\xab\x96\x01\xe7\x08\xe5\x46\x11\xb3\x5b\x11\xb9\x2f\x90\xd0\xef\x56\xc8\xa3\x93\x01\x19\xf1\x2d\x83\xcc\xfe\x19\x96\x8a\x78\xa1\x75\x99\x5d\x40\xca\xb6\x65\xc4\x4c\x4a\x68\x59\x86\x86\xd3\x82\x32\x5b\x76\x03\x57\x2d\x83\x1f\xd0\xb2\x19\xec\x91\x97\x31\xd7\x5b\x8b\xa2\xb4\x56\x80\xda\x03\xd9\x02\x68\x00\x78\xba\x81\x07\x4b\x5e\x64\x2d\xdb\x05\xfe\x74\x6c\x0c\x13\xc3\xe2\xe4\x46\x4f\x41\x53\xc8\x16\xe7\x1c\x08\x03\x41\x06\x01\x07\x34\x49\x43\x09\xc8\x54\x2a\xee\xd4\x32\x0e\x44\xcf\x39\x6b\x33\x13\x6c\x43\x41\xd2\x6d\x0f\xe8\x6d\x9e\x23\x2c\xd2\x4a\x29\x45\xd6\xf2\x96\x29\x55\x48\xf4\x3c\xc5\xcd\xab\x76\x43\x62\xb8\x26\x15\x7a\x7c\x6c\x94\xe7\x30\x48\xd0\x80\xdb\xa2\xd0\x0f\xea\x7b\xbb\x7a\x48\x24\x28\xab\x01\xa9\x00\x06\x07\x83\x03\x06\x09\x39\xd9\x30\xcd\x22\xe0\x0d\xde\x8b\x5e\x81\x21\xf1\x83\xe4\x8f\x5f\xee\xe2\x94\x7a\xf3\xc6\x66\x53\x98\x1e\x46\x59\x13\x57\x74\x80\x8e\xfd\x10\xa4\xdd\xdb\xb7\x26\xe3\xa2\x18\x68\x1b\x03\x7a\x9f\x11\xbb\xbc\xb0\x62\x8d\x8b\xc8\x79\x79\xde\xa3\x6d\x99\x54\x6a\x15\xb8\x60\x94\x04\x3d\x90\x02\xdd\x28\x10\xca\x12\x0b\xf3\x30\xb1\x70\xae\x8a\x64\x51\x76\xe7\x90\xd3\x2f\x99\x04\x94\xf8\x78\x59\x85\x89\x29\x4c\xc8\x32\x9e\x00\xa5\x21\x71\xc8\x09\x8c\x8e\x42\x3b\xd2\x47\xab\xce\xe8\xc3\xa3\xe4\x36\x7c\x3e\x91\xd1\x58\x74\x27\x6c\x27\x84\x76\x8b\xd2\xe1\xe9\x22\x81\x44\xe8\x14\x3d\xe4\xd8\x1a\x0a\xbd\x06\x4d\xf5\x04\x20\x37\x9a\xda\x04\xf0\x18\x23\xc3\x3e\xd4\x94\xc5\x56\x9a\xa6\xf3\xa9\xc3\x7f\x50\xb0\xc7\x0e\x52\x0d\xd8\x6a\x2e\xa5\x85\xca\x01\x99\x04\x3f\x37\x01\x49\x2a\x80\x0f\xbe\x24\x13\xd0\x83\xa9\xb3\x27\xf9\x5c\xad\xce\xf0\x01\x3e\xe1\x0a\x35\x5d\xec\x63\x16\xca\x54\x50\xf4\x18\x3e\x28\xfc\x49\x4c\xad\xe5\x26\xb4\x89\x37\x23\xcc\x6e\xba\xf0\x05\x28\x87\x73\xc8\x6e\xc0\x9a\x23\x8a\xad\xb6\x65\x12\x76\x54\x25\x0a\x30\xf5\xb0\x53\x81\x71\x23\x8c\x04\x3e\xa5\xbd\xb3\xd0\x54\x2b\x3a\x45\xfc\x44\x59\x34\x39\x99\xf9\x15\x51\x54\x2d\x4c\xb9\xa0\xf3\x27\x89\xb9\x94\xa3\x9a\xa6\x15\x50\x49\x1f\x56\xbb\xdb\xd4\x7b\x6a\x91\x19\xa4\x8d\x2c\x79\x84\x75\x0b\x65\xa3\xe4\xa4\x9f\x1a\x24\x50\x2d\x45\x85\xa4\xba\xba\x8b\xdb\x17\x75\x7f\xdd\x53\xc0\xf9\x20\x71\xe8\xd0\xc6\x02\xdf\xed\xa8\xf3\xf6\x94\x25\xe1\x79\xf4\xfd\x0a\x0b\x76\x3e\x2a\x93\xdc\x7a\xec\x0e\x3b\x8d\x8e\xfa\x60\xbc\x91\x34\x50\x45\xac\x1b\x26\xe3\xa6\xd3\xa1\x6e\x58\xde\x83\x01\x28\x7e\x69\x66\x83\x98\x07\x0e\x29\x1b\x2d\x43\x1e\x0e\x1a\xf0\x70\x0e\xb6\xe9\x87\x67\x0a\x65\xab\x4e\x75\xf1\xd9\x75\x30\x03\x22\xc8\x78\x2a\x18\x19\x35\x45\x21\x87\xfb\x61\x2a\xde\xa3\x69\xce\x8a\x29\x8a\xb4\xcd\x52\x6e\xf9\xc3\x0c\xf7\x14\x11\xc5\x3a\xef\xce\x88\x60\xe3\x89\x45\x7f\xd2\x13\xba\x51\x02\xe3\xb0\x06\xbb\x28\xfd\xdc\x2a\x77\x86\xb8\x1b\xc7\xd0\x6f\xe4\x9d\x8c\x37\x9a\xce\x23\x81\x36\x16\x7e\x14\x0a\x13\x19\xc2\x83\x17\x9f\x38\xdf\xbe\x39\x1a\x2e\x87\x89\x70\xdc\x1d\x5c\x8b\x88\x67\x45\x89\x0b\x77\xb3\xa2\x3d\x09\x9c\x54\x49\xc7\xe3\xbc\x50\x34\x4c\x9c\x6b\xc8\x31\x66\xba\x6e\x5b\xcc\xf9\x42\x48\xb6\x6f\xd5\xf6\xcc\xd1\xdc\xaa\xed\x89\x1c\xda\xc2\x76\x22\x82\xc1\x48\xa2\x4d\xa9\x77\x19\x86\xe4\x6a\x59\x26\x1f\x11\xd5\xb2\x72\xf3\x53\x78\x1e\x90\xb0\xf0\x55\x53\xed\x90\xcb\xad\x52\xea\x2e\xa9\x9a\xd5\x72\x19\x7d\x89\x04\x0c\xd6\xfe\x0b\x81\x24\x64\xa6\xa8\x05\xee\xae\xd6\xb5\x4d\x5f\xca\xdc\x51\xd1\xab\x1a\x41\xe5\xf3\xd2\x84\x54\x35\xb5\x9f\x2d\xcf\xe3\xe6\x0c\xf8\xe7\x17\xf0\x5b\x30\xe0\x92\x5f\xc6\x2d\x5f\x94\x30\x55\xb3\x62\x60\x3e\x83\x2e\xe0\xd6\x34\x39\xb9\xd9\xc9\x4d\x58\xbd\x9b\xb1\xba\x20\x81\xec\x8e\xe6\xc2\xec\xa7\x68\x16\x15\x65\x89\x67\xe6\xe2\x6c\x27\xca\x0a\x3d\xf9\x02\x9c\x70\x9e\xbc\x80\xab\x87\xa3\x70\x16\x37\x37\x73\xf9\xe4\xac\x27\xca\x85\xfd\x24\x9c\xa6\x2e\x19\xff\x7c\x7a\xef\xca\xc7\xc8\x8d\x2c\x53\x93\x8b\x28\x1b\x06\xca\x04\xfd\xe2\xe4\x26\xaa\x72\x94\x98\xd3\x55\x40\x54\xd5\x28\x31\x4f\xe1\xc4\x28\x31\x4f\xe1\xea\x51\x62\x9e\xc2\xcd\x5f\x54\xa5\x44\xb5\x62\xa0\xa4\xbc\x34\xb2\x89\x6a\x3d\xa4\xc5\x59\x5c\x33\xa4\xc5\x39\x9c\x28\x5f\x54\x21\x85\xa8\x2f\x95\x34\x21\xe6\xb6\xa6\xc3\x7e\x3f\x5d\x48\x85\x58\xb8\xcf\xd5\xd9\xec\x14\x64\xe9\x7a\xdc\xe7\x13\x93\x92\x10\x2b\x07\xf9\x79\x12\xb2\xbe\x54\xd4\x85\x68\x1c\x97\xed\x29\x2e\x75\x39\xf4\x45\x3b\x0f\xfc\x66\x3a\xc0\x55\x1e\x06\xaf\xae\xd2\x21\xed\x77\x22\x08\x53\x54\x61\xbf\x4f\xc7\x31\x51\xd7\xb6\xa5\xce\x66\x53\xd4\x39\x73\x7e\x98\xa2\x2e\x92\xb6\x14\x52\x97\x34\x83\xa2\xd4\x68\xaa\x12\xf5\x8a\xb4\x44\x81\x23\xc2\x9a\x4c\x98\xa5\x3b\x1a\x22\x6c\xb7\x63\xc2\xbc\xf2\xc3\xc8\xcf\xe9\xd9\x4b\xcc\x53\xf3\x87\x0e\x29\xe6\xa9\xf9\x21\x35\x35\x3f\xa4\x5a\xf3\x49\x74\x4a\x5d\x9e\xe9\xd9\x62\xde\x04\x5a\x8d\xfb\xb6\x58\x94\x81\x56\x29\xb5\x0a\xb4\x4a\xa9\xe2\xcc\x44\x20\x16\xb5\x4d\x7e\x45\xc9\x3f\x31\x84\x89\xc5\xc2\xcd\x69\xc4\x62\x02\xf2\x4f\x00\x00\x00\xff\xff\x10\xe7\x55\x45\x87\x16\x00\x00") + +func fontsEftifontFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftifontFlf, + "fonts/eftifont.flf", + ) +} + +func fontsEftifontFlf() (*asset, error) { + bytes, err := fontsEftifontFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftifont.flf", size: 5767, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftipitiFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x95\x51\x73\xdb\x36\x0c\xc7\xdf\xf1\x29\xd0\x9e\x6e\x92\xb7\xd8\x12\x29\xc9\xb6\xda\xf3\x8d\xd9\xae\x7d\xca\xf6\xb0\x75\x7b\x89\x62\xca\xf5\xec\x45\xab\x13\x6d\x91\xd3\x35\x1b\x9b\xcf\xde\x03\x49\xc1\x92\xfc\x58\x5f\xe2\xfb\xfd\x41\x82\x20\x40\x90\xde\x1f\xf6\x72\x13\x60\x8a\x12\x17\x98\xe0\x12\xe0\xdd\x6d\xdd\xe2\xbe\xb9\x3f\x62\xdd\x62\xb4\x9d\xe0\x4f\xf5\xf6\x76\x77\xc0\x37\xfb\x63\x7d\xb7\xf9\x50\xb7\x28\x8a\x22\xc7\xe9\x14\x7f\xdf\x3d\xb4\x75\x73\x8f\x62\x26\x48\x8a\x1c\xf7\xbb\xf7\x76\x14\x50\x7f\xc5\x07\x11\xe3\xca\x02\x98\xf3\xe8\x67\x1f\x63\xbf\x5f\x5e\xb6\xdb\xba\x9e\x5e\x3e\x1c\xeb\xf6\xf8\xd2\x9a\xc2\x32\xf6\x33\x80\xe6\xb8\x95\x66\xbc\x92\x7a\x6c\x8f\xdb\xd9\xc7\x43\x5b\xcf\xb6\xcd\x5d\xb7\xce\xe0\xf3\x43\xd3\x4c\xa6\x18\x25\xc9\xc4\xad\xe3\x16\x7a\xb7\x3b\xe0\x2b\x8c\xd2\x74\x82\x85\xc4\x62\x8e\x72\x81\xa2\x18\x6f\xe8\xfc\x13\xe9\x2a\xd4\x93\x6e\x21\xad\xf1\xed\xe6\xd3\xd9\x42\x89\x38\xd5\xce\xd8\x22\xbc\xfd\xe5\xf2\xe7\x1f\xdf\xf4\x2b\x8a\xfa\xc5\x0b\x6d\x0d\xc6\x00\x9a\xaf\xa9\xf5\x29\x16\x04\x81\xea\xfe\x15\x5c\xdf\x28\x88\x26\x0a\x10\x95\x82\x8b\x0b\x0b\x4e\xd0\xfe\x15\xac\x8c\x59\x79\x56\x60\x14\xfc\x4a\xdf\x0a\x9a\x58\x41\xdc\x74\x33\x15\x7c\x43\xdf\x0a\x2e\x14\x04\x8e\x30\x50\x10\x07\x0a\x2a\x0a\x12\xa0\x82\xa0\x54\x10\x84\x6e\xf6\xb7\x7e\x8e\x82\xef\x98\x2e\x98\xa6\x4c\x33\x4f\x14\x0c\x4f\xc1\x12\x9e\x20\x98\x24\x53\xca\x94\x31\xe5\x4c\x73\xa6\x05\xd3\x92\xa9\x60\x7a\xc5\xf4\xda\x51\xac\xa0\x64\xdb\xca\x51\x69\xcd\xde\xf6\xbd\x27\x8d\x0a\xa2\x8d\x2d\x29\xeb\x38\x2e\x07\xfa\xda\x7c\x3e\x69\x05\x51\xd4\x25\xe7\x06\x7b\xce\x9a\x34\x55\xa4\x9a\x0e\x75\x37\x4e\xd1\x8c\x7e\xcd\x67\xe4\x8e\xed\xfa\x66\x6a\xd8\x44\xe7\x4b\xe7\xec\xc6\xed\x69\x1b\xa3\xe0\x5a\x1b\x37\x9f\x46\x29\x0f\xac\xe8\x8c\x0d\x2a\xb8\xd2\x37\xbd\xfd\xfa\x0c\x7c\x0e\x9d\xd5\xee\xb4\x3c\x45\x71\x89\x47\xc3\xc4\x0d\xe5\x72\x65\xc6\xe3\xd5\x28\x57\xab\xd1\x15\x22\xa4\x26\xa1\x4e\x55\x80\xe4\xd9\x4b\x4c\x81\xf9\xcd\x28\xa8\xa6\x76\x0a\x55\xae\x2c\xe3\x2e\x1e\xed\xd3\x59\xbc\xed\xe4\x65\x67\x85\x61\x35\xf0\x0a\x43\xeb\xe5\x92\xd3\xa7\x5d\x07\x0a\x0c\x75\xaf\xd1\xd4\xba\x25\x6d\xa0\xf4\xb5\x0b\x68\x72\x80\x86\x88\x6a\xb7\x3e\xb5\x3b\xba\x3b\xb5\x5a\x29\xdb\xb6\x01\xb7\xc5\x86\xe9\x3d\xd3\x96\xe9\x0f\xa6\x1d\xd3\x9e\xe9\x4f\xa6\x5b\xa6\x9a\xe9\x2f\xa6\x0f\x4c\x07\xa6\x3b\xa6\x7b\xa6\x86\xe9\x6f\xa6\x7f\x98\x1e\x98\x5a\xa6\x23\xd3\x23\xd3\x47\xa6\x7f\x99\x3e\x31\x3d\x31\xfd\xc7\xf4\xbf\x23\xe3\xff\xac\xed\x33\x8f\x3e\x7b\x9a\xcd\x86\x17\x85\x74\xbf\x9f\x48\xf7\xce\x9f\xe4\xa6\x7b\x15\x48\x34\x7d\xf1\x88\xfd\x2b\x65\xe8\xbe\xb9\x36\x14\xf3\x84\x4e\xc7\xfe\x91\x12\xf6\x7a\xd0\x7d\xb8\x32\xd6\xb0\xb4\xfe\x74\x98\xd6\x5f\x2c\x53\xaa\x9b\x3f\x50\x51\x48\xc0\x6a\x78\xa3\x45\x91\x02\x86\x63\x5b\x06\xb8\x1e\xdb\x72\xc0\xe7\xb1\x6d\x7e\x96\xb8\x28\x16\x80\xcd\x78\xde\xd2\xfd\xd6\x5a\xab\x7f\x00\xec\x93\x20\x8a\x82\xaf\x0e\x52\x5d\x64\x92\x00\x56\x9a\x72\xe2\x77\x43\x26\x02\x30\x1c\xdb\x24\xe0\x7a\x6c\x4b\x7d\x9d\xfb\xb6\x0c\x28\xe3\x2b\xe3\x2b\x22\x93\x9c\x22\xf5\x0d\x73\x58\x0f\x67\x2c\x6c\x11\x7b\x86\x02\x50\x3f\x8f\x9f\x0c\x29\x12\x57\xcd\xde\x31\x4b\x21\x5c\x35\x07\x36\xe9\xaa\x39\xb0\xa5\xae\x9a\x03\x5b\x76\xd6\x36\x52\x2c\x5c\x8c\x5e\xeb\x48\xb1\x74\x31\x06\xb6\xc2\xc5\xe8\xdb\x64\x72\xd6\x76\x52\xa6\x67\x3d\x25\x65\x46\xbf\x5a\xfe\xaa\x4b\x99\xd3\xaf\x19\xab\x39\xbd\x13\xac\x16\xd4\xef\xac\x96\xc3\x36\x96\xb2\xa0\xd7\xa3\x1b\x4e\x85\x7f\x2d\x6c\xe0\x54\x52\x90\x5d\x37\x96\x52\x10\x56\x19\x05\x61\x95\xdb\x65\x77\xbc\x6c\x3a\x27\xd7\xba\x1b\x5e\x90\x2b\xab\x25\xb9\xb2\x2a\xac\x6b\xcd\xae\x99\xa0\x0d\xfb\x37\x44\x66\x76\x0f\x4d\xa7\xec\x1e\x58\xd9\x3d\xb0\xca\xc9\x8f\xd5\x7c\x78\x45\x65\x56\xd0\x42\xfe\x51\x91\x79\x42\x0b\xb1\x12\xb4\x10\x2b\x39\xbc\xd0\x32\xb7\x51\x9f\xba\x61\x97\xeb\x53\x37\xfc\x25\x00\x00\xff\xff\x63\xa2\xf8\x2b\xe9\x0a\x00\x00") + +func fontsEftipitiFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftipitiFlf, + "fonts/eftipiti.flf", + ) +} + +func fontsEftipitiFlf() (*asset, error) { + bytes, err := fontsEftipitiFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftipiti.flf", size: 2793, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftirobotFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\xdf\x6b\x24\x37\x0c\x7e\xf7\x5f\xf1\x5d\x18\x18\x1b\xb2\x71\xb6\x70\xa5\xc7\xbe\xf8\x5a\xae\x4f\xd7\x06\x4a\x9b\x27\x73\xda\x10\x2e\xdc\xd2\xe4\x06\x6e\x43\xa1\x60\xfa\xb7\x17\x49\xf6\xcc\x78\x7e\xec\x6e\xe9\x92\xcc\xce\xac\x25\x59\x96\x3e\x7d\xd2\x3c\x3d\x3f\x7d\xf7\xd0\xe0\x7b\xbc\xc5\x76\x8b\x5b\xfc\x60\xcc\xef\x5f\x0e\x47\x3c\x75\x5f\x5f\x71\x38\xc2\x3e\x3a\xfc\x72\x78\xfc\xf2\xf9\x19\x1f\x9e\x5e\x0f\x2f\x0f\x7f\x1e\x8e\xd8\xbe\x7b\xf7\x16\x9b\x0d\xee\x3f\x7f\x3b\x1e\xba\xaf\xd8\xde\xdc\xf2\xe3\x76\x8b\x97\x87\xbf\x65\xd5\x80\xfe\xc7\x07\x80\xdf\xcb\x8d\x49\xf3\xdd\x67\x9f\x24\xd7\xab\xf7\xc7\xc7\xc3\x61\xf3\xfe\xdb\xeb\xe1\xf8\x7a\x25\x3f\xb5\xd1\x67\x09\xc3\x32\x6a\xe9\xa6\xb7\x14\xfe\x7a\x3e\x1e\x6e\x1e\xbb\x97\xca\x4e\xf5\xf9\xb1\xeb\xdc\x06\xf6\xf6\xd6\xa9\x84\x1a\x3a\xf7\x59\x93\xb1\xb4\x6f\xc9\x15\x43\x17\x04\x42\x64\xf0\xf3\x6f\xef\x7f\xfd\xe9\xc3\x38\xa2\xa0\x37\x6f\x48\x7e\x48\xc9\xe0\x12\x4b\x17\xec\x65\x9a\x30\xf9\x0b\x06\x84\x60\x2c\x5c\x30\x89\x52\x7e\xf4\x14\x83\x01\x10\xe4\xca\xeb\xce\x3a\xbe\x6f\x30\xbd\xf6\x42\x50\x49\x80\x73\x4b\x7c\x4b\x09\x49\xfe\x83\x81\x85\x93\xff\x60\x36\x9e\xd2\x26\x51\xdc\x8c\xd5\xb2\x5e\x16\x0c\xc6\x83\xd8\x99\x48\x40\x0c\xc6\x12\x91\x0f\x46\xac\xa9\xc7\xea\x34\x39\x0f\x71\xcb\xc3\xab\xae\x57\xef\xbd\x25\x57\xcc\x8b\x02\xe9\x29\xd0\x39\xd9\xc4\x59\x79\xf6\xe8\xf6\xad\xe3\x6d\xc8\xc7\x58\x2b\x88\x99\x60\xf4\x94\xc3\xa5\xf7\x35\x18\xc8\xe6\x09\xa9\x91\xf8\x35\x7c\x1f\x9b\x60\x10\x29\x66\x2f\x79\x21\x22\x98\x26\x21\x05\xd3\x48\x94\x1b\xcf\xf7\x9e\xbc\x5a\xba\xe1\x3f\x96\x8e\xfb\xd6\x73\xa4\x1c\x9f\xce\xca\xa9\xda\x7d\x44\x1f\xa5\xe1\xa6\xfe\x49\x8f\x06\x09\xb4\x04\x85\x7f\xd3\xa8\x50\x9c\xa9\x55\x97\x1c\xc4\x60\x7c\xdb\x5b\x1d\xbe\x18\x84\x1a\x7b\x37\x59\x3b\x61\x69\xf0\x8f\x74\x71\x96\x21\x68\x86\x46\x27\x1a\x6f\xad\x20\xf0\x12\x35\x8b\x5b\x51\x8e\xe4\xeb\xad\xd5\x3b\xb1\x33\x8e\x6b\x06\xed\xd8\x1e\x89\xbd\x44\x48\x62\xd6\xaa\x12\x15\xc9\xca\x1e\x89\xa0\x0f\x86\xc8\x65\x50\xcc\xec\xe5\x64\xc1\xab\xbd\xce\x9d\xb1\x07\xb1\xe1\x18\xc4\x7e\x6a\x6f\xc0\x11\x1f\xcf\x76\x2c\xb4\xb8\x29\x15\xdf\x20\x6b\xce\x89\x12\xc5\x95\xa0\xd8\x8e\xc3\xe1\x97\xed\xf5\x91\xcb\xcb\x12\x60\x5f\x0b\xcd\x92\x5a\x67\x76\x79\xb9\x40\x68\xa8\x0c\x0f\x2f\x95\xd1\xd7\x44\xcd\x16\xa3\x6f\x1a\xa0\xa6\xf6\x46\x98\xc3\xb4\x94\x22\x3b\xde\xe8\x0e\x3d\x30\xc2\x08\xaf\xd7\x19\x71\x0a\x38\x92\x68\x35\x99\x5c\xf8\x69\xec\x00\x65\xbc\x91\x02\xce\xde\x39\xde\xb8\x89\xd4\xc7\xad\x14\x7c\x61\x27\x68\xf4\xbb\x8c\x50\x22\x75\x24\xf6\xe8\x1b\x9c\x51\xc6\x11\x05\x6e\x17\xaa\x70\x07\x55\xa0\x01\xd4\x63\xef\xb5\x76\x13\xf7\x17\x61\x95\x25\xc0\xf6\x6c\x06\x61\xb3\x8b\x6c\x17\xe3\xd9\x7a\x76\x0e\x54\x00\x3c\xf3\x7e\x59\x81\xb2\x42\x9c\x94\xef\x5c\xa1\xb4\x15\xa9\xa5\x85\x1d\x50\x04\xb4\xf5\xe0\xa3\x50\xe4\x89\x80\xf6\x5d\x4a\xe5\xdc\xac\x4b\x65\xc2\x91\x25\x70\xc5\xb3\x9c\x25\x9b\x39\x64\x1a\x93\xdc\xd8\xe0\xa0\x95\x9a\x3c\x97\x97\x05\xc1\xea\x11\xa3\xb4\xc3\x4a\x41\xe5\x71\x36\x41\x28\xa7\xdb\x6f\x5a\xf5\x99\x39\x4c\xfd\x46\xf1\x1d\xa3\x13\x4e\xd4\x22\xf2\x51\x63\x2c\xc7\x8d\xb1\xa8\xc5\x89\xda\x0c\x9b\x35\x1c\x16\x8e\x5e\xb0\x89\x8c\xcd\x3b\x94\xd8\xfb\xc5\xec\x5e\xb0\x43\xdf\x3e\xff\x39\xbd\xc3\x5a\x70\x55\xc1\x67\x44\x46\xba\xda\x68\x57\x24\xb7\x0e\xe9\x49\xbb\xcb\x39\x11\x04\xe8\xcd\xbc\x01\xce\x60\x97\x72\x7c\x3f\x26\x5c\x86\xd3\xa2\x10\xfd\x09\x5c\x51\x41\x4a\x51\x22\xca\x6a\x2d\xb0\x2f\x4d\x6d\xd4\xd7\xa6\xbb\x15\xeb\x28\x6d\x53\xa7\x22\xd6\x99\xba\x57\x34\xa8\x57\x51\x9d\x21\x0c\x3c\x36\x4d\xc2\x50\xf8\xb6\xa2\xca\xc5\xee\x58\x0a\xbb\xd4\x75\xa3\x47\x6b\xa0\xa8\x96\xee\xca\xb3\xda\xb8\xa4\x32\x7e\x22\x72\xf8\xa3\xc2\x06\x98\x7a\x5f\xb9\xa1\x43\x12\x9a\x5c\xc0\x52\x2f\xbd\xed\x82\x90\xeb\xdd\x7e\xb7\xdb\x5d\x07\xb3\xdb\xa1\x43\xc7\x31\xdd\x81\xae\x44\x33\x55\xc9\x58\xec\x34\x2b\x9d\x47\xc6\x6b\xde\x47\x9e\xd4\xcb\xe5\xc1\x6f\x69\x42\x82\x36\x5c\xfa\x34\x23\x81\x31\x5f\x14\xd1\x98\xe1\xbc\x38\x4c\xc9\xdc\xc9\x3c\x14\x2b\x6e\xa3\x92\xd0\x3c\xe8\xc9\xe8\x0a\x1d\x52\xa6\xb3\xc7\x92\x7f\x52\x20\xd1\xd6\x13\x1c\xaf\x5d\xb7\x85\xae\x25\xc7\x99\x61\x66\x63\x4a\x35\x37\xe8\xb6\x51\x5c\xf1\xeb\x27\x2d\x3c\x9e\x52\x15\x94\x32\x4d\xf4\x7c\x3e\x66\xf1\x85\xe5\x94\xa7\xe5\x09\x67\x17\x12\xce\x7b\xb5\x6b\x9c\x7d\xae\x69\x8c\xf1\xd0\x4f\x8c\x05\xf2\xfb\xb6\x1c\x82\x67\xf3\x58\xd7\xea\x0a\x94\xd6\x3b\xd8\x09\xec\x2c\x8c\xb8\x8b\xa2\x51\xdf\x8c\xbc\xbc\xab\xad\x8b\x0e\xe0\x40\xcc\x04\xb0\x98\xcc\x3e\xe3\xcd\x89\x8c\x5b\x6a\x95\x16\xdc\x68\xd4\x2a\x69\x38\x83\x9d\xb1\x67\x39\x19\x7f\x14\x9e\x3d\x01\xdb\x2c\x7a\xbf\x16\x1a\x54\x6f\x45\x34\x52\x28\x2a\x9f\x96\x88\xa0\xff\xe2\xb7\x6b\x0a\x26\xe2\x9e\x4b\x6d\x5a\xb8\xa7\x9c\x71\xf0\xe5\xf5\x65\x29\xf8\xd0\x8e\x94\x07\xf4\x89\x55\x2d\x62\x65\x69\x6d\x6b\x56\xdb\x21\x93\xbb\x04\xb7\x7f\x71\x9c\xa1\x36\x71\x22\xd3\x40\xb3\x99\x65\xf9\x4b\x58\x9b\xa7\x18\x27\x4f\x18\xfb\x27\x07\x15\x9f\x6c\x74\x9a\xc0\xa6\xc9\x3e\xcf\x6f\x7a\x5f\xf9\x6d\xff\x3f\x4d\xbb\x33\x85\x73\x23\x48\x56\xb8\xbc\x0f\xe7\x10\xdf\xe1\xee\x2c\xf1\x9e\x10\x5d\xa9\xb3\x22\x7a\x0a\xa2\xe7\x06\x7a\x40\x4c\x4b\x5d\xb2\xc2\xbf\x01\x00\x00\xff\xff\x62\x49\xb5\xa2\x76\x13\x00\x00") + +func fontsEftirobotFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftirobotFlf, + "fonts/eftirobot.flf", + ) +} + +func fontsEftirobotFlf() (*asset, error) { + bytes, err := fontsEftirobotFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftirobot.flf", size: 4982, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftitalicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x58\x5f\x6f\xdb\x36\x10\x7f\xd7\xa7\xb8\x16\x02\x28\x01\x8a\x29\xd1\x7f\x14\xaf\x45\xa1\x6e\x68\xdf\xb6\x00\x43\x97\x27\x21\x74\x10\x34\xa8\xb7\xd4\x02\xea\x6c\xe8\x03\xd1\xcf\x3e\xf0\x8e\xa4\x48\x91\xb2\x1d\xd4\x28\xc4\xd8\xfa\xf1\x78\xf7\xbb\xbf\xec\xe3\xd3\xa3\xb8\xcf\x61\x0d\x2b\x68\xd6\x50\xc3\x75\x96\x7d\xfa\xb2\x3f\xc2\xe3\x70\x78\x86\xfd\x11\x8a\x87\x12\x7e\xdf\x3f\x7c\xf9\xfc\x04\x1f\x1e\x9f\xf7\x5f\xef\xff\xd9\x1f\xa1\xd9\x6e\xd7\x70\x75\x05\xb7\x9f\xbf\x1d\xf7\xc3\x01\x9a\x45\xad\xbf\x8a\x16\xfe\xbe\x3f\xe0\xdb\x0c\xe4\x4f\x7c\x00\x80\xef\xf0\x8f\x4c\xc5\xa7\x47\x1f\x85\xcf\xd7\xef\x8f\x0f\xfb\xfd\xd5\xfb\x6f\xcf\xfb\xe3\xf3\x6b\xfc\x89\xf5\xdc\x20\x32\x8d\x21\x49\x0b\x27\xa9\xfb\xf7\xf8\xfc\xb0\xf8\xef\xe9\xb8\x5f\x3c\x0c\x5f\xad\x9c\xe0\xf3\xeb\x30\x94\x57\x50\xd4\x75\x49\x72\x48\xd0\xa7\xcf\x4f\xf0\x0b\x14\xcb\x65\x09\x5b\x01\xdb\x8d\xb6\xbc\xd9\x4e\x15\x8a\x3f\x85\xdc\x31\x59\x5a\x41\x52\xc2\xc7\xfb\xef\x91\xa0\xba\x19\xb9\x53\x48\xc2\xc7\x3f\xdf\xff\xf1\xdb\x07\x9f\x51\x90\xaf\x5e\x49\xfc\x41\xa9\x0c\xd4\xcf\x70\x3d\x9e\x95\x69\xc5\xf2\x4e\x2f\x39\xe8\x25\x07\xbd\xe4\xa0\x17\xfd\x84\x0e\x5f\xf2\x56\x2f\x9c\x23\x06\x5f\x16\x25\x2e\x30\x62\xa0\xcb\x78\x8b\xc0\xdc\xee\x36\xbf\x1b\x18\x98\x5f\x24\x6f\xf5\x3f\x23\x91\x73\xfd\xeb\x15\xe7\xfa\x9f\x13\xe9\xed\x93\x74\x78\xc5\x40\xf2\x2e\x03\xd9\xc3\x6e\xa1\xcf\x92\x52\x56\x4c\xe3\x39\x0f\x94\x28\x4a\xdc\x80\xca\x72\x5e\x94\x9e\x12\x12\xe5\x17\x43\x09\x5d\x56\xb1\xe1\xb6\xed\x32\x25\x0f\x2a\xb0\x43\xe2\x5e\xb4\x02\x8d\xc0\x77\x56\x15\x54\xe4\x0d\x43\x48\x8e\xf2\x11\xa1\x94\x87\x31\xd2\x94\x42\x3e\x89\xb3\x9c\xac\xac\xde\x30\x02\x2e\xa0\xea\x32\xf8\x0e\x5d\xc6\x60\x17\x1d\xa3\xbf\x48\xde\xa2\x91\x20\x8d\x31\x21\xd9\xc1\x43\xdb\xc8\xd9\xc8\x80\x15\x21\x25\xd2\xc4\x7d\x37\xf8\x8f\xa2\xcc\xbd\x63\x8d\x43\x46\xea\x42\xff\xa1\x5d\x15\x83\xbe\xcb\x38\xd4\xc0\xbb\xac\x37\xfc\xc3\x94\x20\xc6\x8d\xc9\x5d\x96\x4f\x35\xd7\x91\xac\x8f\x90\x00\x25\x0a\x7c\xd0\x32\x0a\x29\x65\xeb\x7c\x6f\x0e\x44\xfd\x41\x43\x2b\x86\xe6\xf0\xb7\x48\x36\xfa\x7d\x0c\x14\x4b\xda\x02\x57\x3a\xbc\x62\x03\x4f\x8b\x25\xa1\x9c\x62\x49\x49\x34\x47\x0b\x9c\x86\x32\x54\xac\xed\x32\x3e\x68\x80\x72\xef\x7d\x11\x12\xf8\x98\x14\x91\x83\xc8\x4c\xe0\x83\x36\xb3\x62\x03\x28\xa7\xfa\x44\x1f\x30\xef\xf5\x6b\x48\x0b\xf3\x1d\x5d\x94\x7e\xac\x44\x6f\x6e\x27\x61\xfc\xf6\xad\xf6\x71\xdf\x07\xf1\x05\xc6\x0c\xb2\x03\x23\x04\x17\x5f\x35\xcc\x95\xbe\xd7\x3e\x7c\xf7\x0e\xc3\xc1\x8f\x15\x6b\x1e\xa0\x7d\x00\xd0\x1a\xc3\x72\xb0\x0a\xf9\x61\x41\xe8\x8a\x21\xdf\xa0\x8a\x01\x19\xcd\x75\x15\x6b\xf3\xa9\x27\x09\xbc\xc0\x50\xc3\x13\x50\xbd\x43\xa8\x5e\xa8\xc4\xa2\x34\xd0\x3e\xa8\x0c\x21\x1a\x9d\x8a\xb6\x6a\xe7\xa1\x37\x78\xda\x69\xe0\x8e\x56\x26\x3c\xe2\xa3\x09\x88\x61\xa4\x17\x48\x50\xe8\x07\x31\xc8\x11\x8a\x58\x3e\xe6\xea\x9c\x8e\x07\x13\x31\xa1\x8e\x60\x24\xea\xda\x89\x12\x77\x40\xa7\x1f\x24\x4f\x4b\x04\x8b\xe4\xf6\xe4\x49\xd6\x4a\x2a\xf2\x1a\xa5\x85\x68\x58\x1f\x24\x99\x3d\x1a\x0c\x3f\x9c\x4a\x2c\x56\x65\x14\xd9\xf7\xe7\x8e\x96\x86\xa0\x89\x31\x23\xae\xaf\x98\xc1\xe2\x5f\x46\x55\x1e\x18\xe5\xed\xb3\xdb\x94\x3d\x41\x29\xbb\x49\x85\x7b\x12\xf5\xcb\xa4\xdb\xb4\x7e\xf9\x61\xad\xc8\x5b\xd6\xc0\x94\xb7\x52\x12\x4d\xa6\xcd\x4b\x74\x94\xed\x64\x1f\x15\x31\x13\x2d\xf3\xbd\x6e\x44\x4b\x69\xea\x3b\xd8\x20\xf4\x02\x2b\x2c\x31\xc4\x95\x09\x18\x0e\x7f\xcd\x39\x38\x04\x2a\xb8\x45\xa0\x4a\x01\xc1\x41\x5b\x07\xb6\xf0\x43\x58\x9f\xa7\x2e\x53\xa0\x38\xc5\x34\x07\xd2\xb9\x62\xf2\x20\xfb\x68\x8b\xdd\xe1\x36\x28\x20\xc1\x73\xc9\x63\xb9\x96\x40\x1d\x03\x2a\x46\x1b\x2a\x86\xa9\x19\xe9\x64\x13\xde\x26\xb2\x26\x11\xe7\x20\x5c\x89\x78\xee\xca\x21\xd5\x43\xc0\x72\x8a\xdb\xac\xaf\x43\xe7\xb9\xce\x90\x53\x26\xd1\x1a\x08\x33\xb1\xc3\x17\xfd\xfc\xb4\x14\x2d\xd6\xdf\x3a\x87\xf4\x57\xb0\x75\x3d\x31\xa8\xd8\x23\x2a\x36\x50\x58\xb6\x81\x70\x34\x15\x33\x78\xc0\xfe\x17\xb4\x37\xdb\x1d\xf4\x6e\xfd\xa2\x77\x71\x1a\xb4\x0f\x90\xdc\xeb\xb4\x2a\xe0\x37\x92\x33\xe8\x10\x91\x45\x28\xc7\x35\x05\xd4\x44\xb6\x60\xa6\x8e\xb4\x1c\xdf\x1a\xd6\x65\x52\x37\xa4\xa9\x35\x98\x8a\x87\x70\xe0\xc1\xd7\x38\x05\xd2\x44\xc5\x93\x44\xd3\x98\x88\x08\xd3\x7e\x39\x9f\x60\xec\x4b\xad\x2e\xe7\x7d\x1f\x4d\xbf\x56\x8b\xd4\xf4\xe4\xac\x00\x0a\xaf\x9e\x21\xf1\x07\xa7\xec\x2c\x50\xcb\x4c\x75\xbf\x24\x2b\x91\x5d\x76\x0a\xc1\xda\x83\x10\xdf\xae\xa4\x88\x90\x58\x0a\x54\x54\x82\x52\x23\x76\x2f\x14\x0f\x0c\x03\xb3\x9c\x09\x32\x62\x6c\x3e\xc0\xe9\xda\xc0\xa3\x76\xec\x46\x59\x02\x28\x57\x02\xc3\x40\x74\x10\x02\xdd\x45\xdd\x9a\xd2\x87\x74\xed\x6f\xb5\x91\x15\x3b\xc4\xfe\x23\x44\x7f\x8b\xd9\x5b\x3a\x2f\xc6\x19\x08\x24\x62\xd2\xcc\xec\xc4\xc5\x55\xde\x65\xbd\x32\x63\x57\x17\x75\x58\x30\x8d\x78\x52\xb1\x83\x89\x4b\xf5\xfa\xc1\x69\xec\x42\xe5\xb5\x78\xce\x7b\x4e\x95\x05\xc0\x5b\xac\x02\x45\x29\x29\x8c\xf5\xe8\x04\x76\x76\x9a\x19\x0d\x2c\xb8\x22\x2c\xf6\xa7\x74\xb1\xb7\x48\x6c\x0b\x60\x1b\x88\xeb\x20\x51\x0f\xd3\xcf\x9b\x9b\x93\xb5\x27\x78\x9d\x08\xdb\x1b\xb8\x39\x15\x16\xae\x6a\x9b\xe1\x93\x93\xee\x3a\x37\xa9\xb9\x72\x8b\x6e\x36\x35\xee\x38\x77\xc5\x6d\x36\x0d\xe2\xec\x6d\xd1\x65\xbc\xad\x07\x63\x69\xd2\xe0\x75\xa2\x3b\xe1\x55\x6d\xa6\x3b\x35\x9b\x0d\x7e\xa3\x9b\xac\x77\x8f\xa6\xe8\x9f\x8a\xbf\x76\x4c\x14\x25\x6a\x94\x53\x8f\xc8\xc1\x77\x78\x73\xbd\xb4\xf9\x59\x60\xea\xc5\x8d\xa4\xd9\x0a\xfc\x93\x1a\xd5\x99\x89\xba\xd9\x2e\x49\x49\x7e\x11\x78\x85\x96\xdc\x5d\x26\x79\x8d\xe0\xfe\x32\xc9\x9b\x17\xc6\x72\xb3\x6d\x3d\xe7\x9d\x15\x7f\x6d\x9b\xb5\xe9\xd7\x78\x82\x9d\xa1\x06\x6c\x6c\xf6\x9c\x60\xa0\x77\x02\xb6\xd9\xc9\xeb\x84\x29\x1a\xa2\xc6\xd0\x93\xc4\xfd\x99\x9b\x82\xa8\x9b\xb1\xa5\x9e\x07\x0b\x8f\xfb\xb3\xe0\xa5\x4f\xa7\x81\x79\xf7\x10\x39\xa5\x53\xd4\xe8\x5a\xab\xf7\xec\xcd\x41\xd4\x6b\x2f\x5e\x92\x35\xcd\x57\x43\x7b\xd5\xa9\x7c\x42\x68\x8b\xea\x5a\x6d\xcf\x08\x25\x57\xf0\x9e\xbf\xe4\x32\x20\x9a\xda\x19\x78\xea\x42\x20\x9a\x26\xb3\xf6\x9d\xc6\x09\x67\xdb\x69\x9c\x76\x05\x65\xc1\x69\xdc\xea\xf2\xfa\x2c\x1a\x4d\x98\xec\xfb\x4b\x46\x7c\xd1\x5c\xe3\xff\xbf\xf1\xcb\xc0\x5b\x32\xeb\x22\xb0\xa8\x5f\xd8\x2a\x84\x58\xbe\xb0\x98\x0b\xb1\xb2\x05\x0f\x76\xbb\x64\x83\x11\x02\x63\x12\xa3\x81\xb1\x19\xc8\x66\x9c\x5e\xee\x66\x20\xed\x08\xf9\x31\x03\xb9\x3e\xd7\xec\x84\xd8\x8e\x52\x66\x20\xcb\xda\x31\x32\xb6\x14\x0d\x34\x13\x73\xd5\x2e\x8a\x90\xb5\x65\x33\x19\xad\xc7\x11\xdd\x16\x9e\xa5\x98\xd2\x34\x9d\xbe\xc5\x72\x39\xa5\x29\x86\xac\xa6\x34\xc5\x90\xf5\x94\x83\x18\xb2\x09\x74\x49\xcc\xe0\x62\xd9\x06\xba\x24\x21\x23\xd9\x6c\x4e\xca\x36\xd0\x25\x05\x59\x35\xfe\x80\xfd\xe3\xe4\x80\x2d\x56\x11\x89\xd3\x69\x45\xac\x22\x12\x63\x48\x44\x62\x0c\x59\xa7\x63\xcd\x87\x6c\xce\x4d\x4e\x62\xb5\x1d\xa7\x7d\xcb\x74\x62\x7a\x12\x6b\x0a\x38\x1a\x47\x0d\xdd\x49\x5c\xe3\x0d\xe9\x77\xb3\x43\xba\x58\x8b\x8b\xa6\x36\xb1\xb6\xb3\x8a\x64\x2c\x3d\x64\x8b\xb5\x25\x42\xde\xdc\xa4\x21\xff\x07\x00\x00\xff\xff\x8b\x4c\x56\x74\xb9\x1a\x00\x00") + +func fontsEftitalicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftitalicFlf, + "fonts/eftitalic.flf", + ) +} + +func fontsEftitalicFlf() (*asset, error) { + bytes, err := fontsEftitalicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftitalic.flf", size: 6841, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftiwallFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x58\x6b\x6f\xdb\x36\x17\xfe\xae\x5f\x71\x1c\x19\x15\xa9\x8a\x64\xe2\xf6\x6d\x9a\x20\x0e\x94\x77\x68\xd1\x0f\xcb\x0c\x0c\xdd\x56\x60\x5a\x8e\x32\x43\x5e\x84\x26\x26\x60\xbb\x41\xd6\xb2\xf9\xed\x03\xa9\x1b\x25\x5f\x55\xd2\x86\xad\x23\xf1\x3c\x3c\x97\x47\x87\x97\xd9\xfd\x6c\x74\x3b\x84\xd7\xf0\x1a\x5e\x8d\xe0\xcd\x08\xde\x7a\xde\xc7\xbb\x7c\x09\x33\x39\x5f\x41\xbe\x04\x32\xa5\x70\x9d\x4f\xef\xb2\x7b\x78\x37\x5b\xe5\x0f\xb7\x9f\xf3\x25\x9c\x9c\x9d\xfd\x0f\x18\x83\xdf\xb3\xc5\x32\x97\x73\x38\xe1\x46\x1c\x8d\x60\x96\xfd\x6d\x9e\x7a\x80\x0e\x0d\x00\x44\x6a\x2e\x3c\xb5\x3e\xfa\x5a\x53\xe6\xf7\xe8\x6a\x39\xcd\x73\x76\xb5\x58\xe5\xcb\xd5\x91\xb9\x15\x24\xa2\xec\xe1\xe9\x3e\x05\x12\xaf\x91\xe2\x2f\xcb\xd5\x94\x3f\xde\x2f\x73\x3e\x95\x0f\x15\x4e\xab\xfd\x5f\x4a\xca\x80\x1c\x1f\xd3\x02\xa7\x00\xfa\x98\xdd\xc3\x39\x90\x57\xaf\x28\x9c\x8d\xe0\xec\x0d\x8c\x4e\xe1\xe4\xac\x6b\xd0\x7a\x23\x98\x06\x48\x2b\x20\x44\x78\x7f\xfb\xb4\x06\x74\x7c\xd2\xc4\x4e\x99\x20\xbc\xff\xf5\xea\x97\x9f\xde\xd9\x11\x05\x1c\x0c\xd0\xdc\x50\xca\x03\xe5\x12\xeb\x66\x2c\x6f\x38\x1c\xc6\xd6\x0f\x63\x2c\x8e\xbd\xca\xf6\xcd\x57\xac\x6c\x55\xc7\x44\xe8\xc7\x8f\x76\xc7\xc7\x6e\xc7\x61\xf5\xd5\x02\x2f\xba\xf2\xa2\x77\x08\x40\x00\x20\x8c\x3d\x7d\xc9\xcd\x8d\x46\xb7\x19\x46\x24\xd6\x00\x42\x0f\x9b\x18\x49\xa4\xa2\xbc\xd1\x52\x6b\x14\x0b\x72\x69\x01\x51\x8f\x44\x8d\x40\xca\x10\xd0\xb6\x96\x56\x4a\x01\x10\x20\xd0\x0f\x74\xfe\x28\x00\xd3\xda\x01\x80\x7e\x64\x75\x8f\x63\x2f\x2a\xae\x78\xec\x29\xf8\x90\xc3\x00\x54\xec\xa5\xe6\x16\xc1\xaa\x27\xc0\x96\x8e\x48\xcd\xbd\x40\xa3\xdb\x36\x63\xe5\xa8\x94\x09\x54\xd6\xd2\x64\x2d\xf8\x85\x67\x60\x25\x49\x00\x12\xca\xa0\xfa\x5c\xc6\x1e\x28\x43\xcd\xc1\x60\x3d\x81\x1b\xfc\xd8\xdc\x8c\xd1\x57\xcb\xcf\x30\x93\x0b\x90\xab\xbb\x6c\x01\x41\x36\x5b\xe5\x81\x29\x19\x4b\xcb\x95\xcd\xcd\x72\x70\x73\xb3\x38\x57\x67\x2c\xf6\x2e\x6a\x3f\x18\xa1\x68\xf2\x5b\xf5\x30\xee\x68\xcf\xfa\x7b\x63\x9c\xd9\x5e\xe2\xea\xfc\x6d\x6c\x4d\x52\x37\x36\x93\x69\x6d\x5f\x68\x72\x18\x16\x49\x09\xa1\xa4\x51\x41\x6d\xfd\x47\x40\x02\x0d\x0b\xda\x4b\x39\x29\xd5\x27\x52\x76\x43\x51\xbf\x7a\x9c\x73\x5b\x26\x1c\x38\x2d\x65\x03\x40\x74\x06\xfa\x00\x48\x90\x6e\x00\xcc\x15\x40\x02\x73\xb5\xc0\x11\x20\x84\xd0\x0d\xe0\x09\x9e\x5c\x63\x30\x71\x03\x98\xb8\x66\x01\xe4\x41\x00\xa5\x70\x54\x09\x69\xf9\x9a\x9a\x32\x59\x50\xf8\x20\x25\xd3\xd6\x95\xf6\xbe\xb1\x7f\x2c\xf2\x55\x06\xff\xca\x2f\x0b\x78\xc8\x96\xcb\xdb\x7f\x32\xb8\xcb\x16\x99\x5d\x71\x9d\xde\x58\x80\x79\x63\xb4\x9e\x18\x04\x26\x58\x16\x22\x13\xa7\xaf\xf0\x75\x6b\x9c\xdc\xac\xdf\x55\x3b\xf7\x95\xce\xca\xfa\xee\x1f\xe3\x18\x35\xc9\xb0\xff\x0b\x97\x58\x00\x90\x6e\xe5\x48\x3d\xb1\xfc\x68\xad\x88\xa2\xc8\x0d\x40\x4a\xe9\x06\x30\x1e\x8f\xdd\x00\x5e\xbe\x7c\xe9\x06\xe0\xfb\xbe\x13\x00\x0b\x9f\x43\xe6\x64\x41\x18\x86\x6e\x2e\x28\xa5\xdc\x5c\x48\x6f\x02\x37\x17\xc4\xe9\xe9\xa9\x13\x00\x8a\x53\xb7\x18\x50\x4a\xdd\x00\x08\x21\x6e\x00\x4f\x4f\x4f\x0e\x00\x4d\xa1\x36\x32\xab\xe7\x0c\x76\xb8\x05\x71\xef\x7a\x80\xdd\x18\x38\x16\x94\xcb\x4f\x17\x6e\x00\x41\x98\x3a\x01\x24\xec\x86\x09\x27\x0b\x6e\x6e\x6e\xdc\x5c\xa0\xca\x91\x48\x89\x12\x6e\x00\x2f\x5e\xbc\xe8\x07\x40\x3a\x00\x48\x7b\xf0\xa0\x75\x38\x10\x7b\xea\x67\x29\x3f\xc3\x47\x3d\x6f\xa6\x5c\xcb\xcd\xf3\x28\xa8\x36\x02\x4a\x59\x13\xa3\x05\x50\xa9\xc3\x87\x6c\x91\xa9\x96\xb2\x6a\xab\x96\x5b\x30\x5b\x15\xa2\xa0\x19\x5b\xe9\x75\x0c\x5f\x57\x6f\x01\xe8\x48\x1b\x65\x7d\xa1\x01\xe3\x67\x01\x11\x87\xe4\x39\x2e\xf6\x69\x48\x20\x41\x14\x40\xb1\xda\xb6\x26\x88\xbf\xa1\xa8\x2d\x08\x12\x91\x16\x61\x22\x66\x81\x66\x36\x81\xe6\x28\x41\x77\xc7\xc1\x00\xbb\xdb\x26\xb5\x81\xb4\x49\x92\x94\x4f\x84\x10\x2d\xfa\x16\xcb\x3e\x65\xe0\x61\x2d\x07\x13\xa9\x2f\x3b\xe9\x54\x1d\x78\xc5\xc7\xe3\x31\x6f\xe4\x6f\xdf\x25\xc8\x6f\xdf\x77\xf0\x81\x98\x4f\xa5\x10\x70\x53\x99\x78\x59\x99\x02\x00\x72\x09\x17\xb4\xac\x54\x07\x31\x32\x8a\xaa\x95\x86\x91\x85\x21\x54\xb2\x87\xd2\xed\x15\xb0\x8c\xc2\xc8\xe6\x21\x0c\xdf\x1a\x91\x20\x9d\x48\x39\xac\x90\x0c\x90\x41\xb2\x56\x5d\xea\xa8\x35\x3f\xa2\x42\x85\xfd\x5e\xb0\x76\x9d\xfc\x01\x80\x56\x3c\x10\xaf\xaf\xaf\x11\xfb\x00\x74\x96\x7a\x5c\x29\xc5\x7b\x58\xd0\x9c\xe5\x68\x05\x0e\xc0\xcf\xcf\xcf\x2d\x80\x73\x03\x70\xae\x7b\x1c\x5a\x64\x1e\x1f\x5b\x67\x49\xe4\xf8\xf9\xb8\x97\x0b\x22\xf1\xed\xb3\xa2\xbd\x9c\xc0\x26\x11\xb1\x07\x32\x80\x24\x1a\x73\x01\xa9\xec\x93\x46\xb4\xd3\x06\x02\x13\x48\xc3\xc3\xb3\x80\xb5\x19\x46\x0e\x92\x84\x09\x91\x1e\x9a\x05\xbf\x13\x03\x1f\xe0\x02\x43\xbc\x2c\xe5\xa1\xdf\x06\x60\x6f\x59\x1b\xc0\x87\x6e\xf3\x63\xcf\x1f\x4b\x39\x19\x57\x6d\x22\xe5\xd8\x37\x3d\x75\x41\x29\xd1\x74\x41\xf1\x9b\xdd\x15\x69\xf6\x31\x5b\x32\x13\xe8\xb8\xf4\xa2\xf7\xa0\x3a\xb7\xaa\x56\x32\xd0\x59\xc9\x7c\x9a\xf4\x58\xc9\x18\x80\xa8\x05\x20\x69\xbd\x14\xd2\x1b\xd2\x60\x1f\x3b\x09\x45\x42\x77\xb9\x90\xca\xa0\x03\x20\x6d\x80\xd4\x70\x23\xa8\x64\x56\x02\xb0\x83\xe9\xcd\x03\xf4\x31\xe5\xb5\xac\xfe\x94\x20\xff\x52\x3b\xb8\x51\x7f\x4b\x6e\xf8\x9c\xd7\xb2\xe6\x86\x3f\x01\x9f\x96\xb2\xf4\x27\xcc\x27\xe8\x33\xe6\x6f\x65\xa7\xc6\x2f\x8e\xb3\xfa\x54\x29\xbb\xa8\x44\x0c\x99\xb2\x00\x8d\x0b\x74\x0f\x40\x3b\x0d\x04\x91\xda\x79\x68\xce\xeb\x21\xf6\xe6\x73\xc6\x88\x44\x94\x94\xb1\xf9\x5c\x83\x94\x9f\x9d\x17\x00\x56\x3d\xb6\xc6\x69\x33\x76\xc3\x64\xd9\xb1\xb4\xa5\x00\x1d\x3b\x0f\x3d\x6e\x69\x18\x6b\xaf\xbd\x35\x63\x39\xdf\x6b\x01\x74\x2c\x88\x6b\xca\x1b\x0b\x38\xef\xb7\xfa\x47\xbf\x1d\x03\xca\xc8\x4e\x0b\xcc\xe1\xa6\x0d\x10\xa9\xf6\x69\x40\x0c\x71\x3f\x17\xa6\xd3\x69\x0b\x20\x0c\xb7\xc7\xe0\xbf\x00\x00\x00\xff\xff\x02\x9d\xcc\x12\xdf\x1a\x00\x00") + +func fontsEftiwallFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftiwallFlf, + "fonts/eftiwall.flf", + ) +} + +func fontsEftiwallFlf() (*asset, error) { + bytes, err := fontsEftiwallFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftiwall.flf", size: 6879, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEftiwaterFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\x4f\x6b\xeb\x46\x10\xbf\xef\xa7\x98\xf7\x58\x90\x16\x6c\xaf\xdd\xb4\xb8\x81\x24\x6c\x5a\xd2\x93\xdb\x43\x69\x7a\x12\x8c\x8c\xb1\x1b\xd1\x24\x1b\x22\xa7\x27\x7d\xf8\x32\x33\xbb\xd2\xae\x24\x97\x86\x27\xfc\x1e\xd2\xfc\xe6\xef\x6f\x76\x66\x73\x7a\x3e\x7d\xb7\xd7\xf0\x3d\x5c\xc1\x66\x0d\x6b\xf8\x51\xa9\x3f\x9e\x9a\x16\x4e\xfe\xf5\x0c\x4d\x0b\xe5\xc1\xc0\xaf\xcd\xe1\xe9\xf8\x0c\x0f\xa7\x73\xf3\xb2\xff\xbb\x69\x61\x73\x7d\xfd\x03\x2c\x97\xf0\xe7\xf1\xbd\x6d\xfc\x2b\x6c\x56\x6b\xfa\xbc\x5a\xc3\xfe\xe3\x2f\x46\x15\xe0\x37\x3c\x00\x60\x6b\x7e\x51\xdd\x34\x7a\x78\xbe\xde\xb7\x87\xa6\x59\xde\xbf\x9f\x9b\xf6\xfc\x95\x24\x1d\x8c\x9e\xa2\xb2\xf2\xd2\x29\xc2\xc4\xd3\xaa\xf7\xe4\x5a\xff\xf6\xd4\xec\x57\xc7\x8f\x77\xff\x76\x5c\xfd\xf3\xdc\x36\xab\x83\x7f\x49\xfd\xfc\xe4\xbd\x59\x42\xb9\x5e\x1b\xf1\x23\x8e\xfe\xef\x33\xd6\x2d\xb1\x2e\xd0\x44\x47\x9f\x20\x84\x75\xe1\x97\xdf\xef\x7f\xfb\xf9\x81\x98\x05\xfc\xf2\x05\x99\xe2\xae\x53\xf0\x19\x4f\xff\x11\x43\x69\xed\xd2\x7f\x4e\x01\x82\x53\x60\x8c\x53\x65\xa9\x9d\x02\x0f\x24\x04\xa7\x1e\x1f\x45\x0b\x44\x80\xfc\x73\x0a\x96\xc6\xd0\xcf\xa9\x65\x59\xd2\x8f\x55\xe4\x61\x77\xaf\x48\xfe\x4a\x74\x6a\x85\xc6\x12\xf8\x28\x1e\xc0\x29\x6f\xb7\x4e\x59\xeb\xe5\x33\x08\xa1\xa4\xe0\xb8\xed\x85\xe8\x94\x2d\x46\xc1\x9d\x02\x6b\x35\x25\x09\x24\xae\x2a\xd1\x24\x7b\x4d\x1f\x4a\x73\x0d\x60\x6d\xcc\xff\xee\x26\x73\xc1\x91\x80\x8c\x97\x5d\xcc\x39\x68\xb2\x13\x09\x1a\x53\x62\xbd\xa0\x16\x85\x9a\x84\xda\xe7\x42\x90\x8a\x06\x21\x75\x8e\x09\x05\xa6\x14\xcb\xc8\x4f\xe4\xba\x18\xb8\x8e\x16\x64\x80\x22\xc6\x24\xb5\x04\xc0\x68\xd0\x37\x83\x42\x17\x1d\x4c\x62\x48\x7c\x63\x90\x8b\x62\x4e\xfa\xe0\x9c\xd8\x4e\x6c\x06\x00\x11\xd9\xd9\x5c\x56\x66\x67\x46\xda\x02\x04\x11\x66\x59\x41\xa0\x67\xcc\x91\x08\xa9\x32\x5b\xb0\xd0\x5a\xa7\x6e\x6e\xa4\x8f\x99\x26\x62\xce\xbb\x74\xf6\xee\x8e\x28\x86\x3c\xb5\x22\x10\x06\x72\x68\x03\x2f\x81\xfb\x83\x64\x8d\x8b\x84\xfb\x00\x5a\xac\xc5\x2e\x6f\x4c\xb4\xc4\x60\x69\x72\x50\x4b\x4b\xa5\x72\x84\x0c\x14\xc3\x8a\x21\x9b\xf2\x24\x56\xbb\x60\xa5\x61\xc6\x65\x00\x61\x0c\x4a\x2e\xd2\xdc\xb4\x83\xa1\x29\xb3\x25\xe4\x73\x9c\x4e\x8e\x8c\x06\xcb\x57\x44\x5b\x72\x18\xb6\xa4\x5f\x57\x93\x53\x62\x42\xa9\x19\x20\x21\x2a\xbb\xe0\x28\x75\x7f\x26\xf3\xec\xaa\x3a\xc0\xb3\x04\xcf\x8e\x45\xce\xfe\x84\x8d\x19\xcb\xda\xcc\x59\xd6\xd5\x85\x49\xc8\xe6\x07\x47\x0d\xd5\x90\xc5\x8b\x4c\xd6\xb3\x03\x9c\x81\x8b\x62\x0c\xf6\x70\x50\x48\x54\x06\x1a\x25\x38\x0d\x03\x9d\xeb\xaa\x2f\x97\x93\x63\x17\x35\x93\x08\x73\x59\xdb\x45\x31\x77\x0c\xc1\xa9\x0e\x3b\xa7\xba\x4e\xcb\x1b\xb9\xa2\xc2\xaa\x8a\xcb\xe3\x51\x9a\x68\xeb\xae\x8b\xda\xa4\x55\xd4\xb4\xe6\x86\x9d\x99\xfe\x77\x7b\x7b\xcb\x3e\x29\x39\xa7\x20\xdd\xac\xd0\x77\x62\xca\x57\x7a\x9a\x4c\xba\x2c\x20\xd9\x25\xd9\x16\x91\xad\x17\xf7\x61\xe6\x2e\x18\x11\x50\x4c\x36\x55\x2d\xbd\xcc\x62\xcc\x64\x36\x0c\x40\x38\x39\x30\x3d\xad\x1e\x02\x49\xe9\x2c\xe5\xc2\xd1\x1c\x2d\x48\x5c\xe9\x9c\xe2\xe9\x38\xc6\x94\x20\x38\xaa\x37\xf9\x0c\xf5\xb8\xc0\xd5\xa8\x7a\x18\xed\xdf\x8b\x80\x31\x97\x2c\x24\xed\x14\xe8\xf4\x68\x89\x33\xc3\xf1\xea\x18\x6a\xd9\x4d\x6b\xe9\x79\x9c\x36\x8a\xb7\x39\x5d\xe5\x55\x69\x8b\xbc\x27\x01\x12\xb0\xec\xe1\xd4\x92\x43\x9a\xfc\xd2\x9b\xb8\xec\x8b\x64\x39\x27\x91\x2c\xbe\x78\xcf\x94\xe1\x9e\x99\xf6\x84\xa9\xc0\x30\x23\x4e\x69\x13\xee\x99\xe0\x73\x5b\xd1\x9f\x24\x7a\xb8\x77\xc0\xfb\xcb\x37\x88\x47\x7f\x79\xc1\x79\xf0\x97\x77\x4a\x70\x3b\x3f\x40\x11\x9b\xf6\x3c\x20\xb3\xf4\xcf\x5e\x67\xbc\xee\x9c\xfa\x37\x00\x00\xff\xff\x14\x6c\x6e\x6d\x0e\x0c\x00\x00") + +func fontsEftiwaterFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEftiwaterFlf, + "fonts/eftiwater.flf", + ) +} + +func fontsEftiwaterFlf() (*asset, error) { + bytes, err := fontsEftiwaterFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/eftiwater.flf", size: 3086, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEliteFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\xbd\x6e\xdb\x30\x10\xde\xf9\x14\x37\x64\x0d\x6d\x07\x09\xda\x78\xa9\xbb\xa4\xc8\xd0\x87\x50\x6d\x29\x76\x7f\xa2\x40\x56\x6b\x74\xd3\xc0\x41\x83\x06\x4d\x7a\x80\x8c\x7c\x01\xed\x7a\x14\x3d\x49\x71\xe4\x91\x3a\x32\x2e\x0a\x14\x05\x9a\x41\xb0\x21\x93\xf2\xf1\xf8\xdd\x77\xdf\x1d\x99\x7d\xcd\xae\x92\x0b\xb8\x81\x1b\x58\xad\xe0\x72\x05\x6f\x60\x89\x1f\x71\x97\x3f\x96\xf0\xfe\x7b\xb9\xcf\x8b\x35\xbc\x13\xe2\x63\x5e\xa4\x70\xff\x98\xe5\x6b\x21\xf6\x65\xf9\x74\x5c\x2f\x16\xa7\xf4\x93\x4c\x8a\xed\xfe\xf0\x23\x95\x79\xf1\x80\xf3\xc5\xd5\x72\x75\xb5\x7c\xbb\xba\x5d\x5e\x5f\x5f\xdf\xdc\x2e\xd0\x14\x2d\x4f\x27\x59\xe4\x3f\x8f\xc9\x56\x6e\xf3\x6f\x8b\x72\x9f\xee\x8a\xe4\x94\xe5\x8f\xe5\xf1\xb2\xdc\x65\x32\x39\x3e\x09\x71\x77\xff\xc1\xec\xba\x2d\xd2\xa4\x4c\x77\x70\x3a\x94\xfb\x35\x90\x87\xa7\xa4\xcc\x8b\xcf\x5f\xcc\xf2\xec\xf0\x80\x4b\x2f\xd3\xdd\xa1\xcc\x0b\x71\x01\x70\xb1\xf9\xdd\x73\x23\xc6\x4e\x8d\x9d\x02\x1c\xd4\xe6\xdb\xe0\xb0\x1d\xbb\x7a\xe8\x37\x42\x8e\x5d\x05\x1b\x01\xe6\x67\x23\xfc\xe7\x3f\x0e\x01\xe0\xe5\xe3\x15\xe1\xfb\x07\x11\xda\x9c\x8c\x9d\x1a\x7a\x70\xd9\xc0\x10\xf1\x87\x32\x56\x9b\xa9\x7f\x43\x16\xda\x8c\x1a\x22\xc4\xb1\xe2\xdd\x9d\xf5\x38\x76\xda\xbd\xf1\x3e\xc7\x4e\x4d\x82\x50\xce\x6f\xbd\x11\x43\xef\x6c\x2a\x72\x0e\xe7\xfc\x36\xe4\xb4\xb6\x53\x45\xfe\x5a\xe7\xd2\xca\x8c\x39\x43\x4f\x38\x9d\x80\x02\x93\xa4\x06\x72\x35\x49\x13\x9c\xb7\xc6\x99\x49\x6e\x54\x05\xdf\xea\x39\xa0\x01\x24\x99\x28\x94\x37\xca\xdc\x38\xb3\xd6\x3a\xc0\x6a\x57\x10\xa1\x67\xa1\x92\xad\xe5\x80\x43\x66\x15\x25\x19\x24\xc6\x19\x18\x60\x2c\x1b\x40\xb4\x29\x9e\x9d\x10\xcd\x1f\x32\x01\x32\x48\x9d\xb7\x76\x2f\xaa\xf8\x45\x63\x43\xe7\x00\x87\xde\x90\xa5\xa7\x0c\x00\x6f\x09\x01\xf1\xb4\xc6\xee\xde\x32\x52\x00\x10\x60\x4d\x7b\x69\x13\xad\x9f\xb6\x6e\xdf\x3a\xe2\x76\xac\x9e\x6d\xa2\x90\x1a\xd6\x96\x1a\x9b\x86\x49\xaa\xd6\x5e\x4d\x78\x64\x20\x2a\x23\x7d\x96\xf2\x86\xa9\xa9\x7a\x0e\xa5\x05\x2c\x24\x57\x3e\x32\x20\x16\x97\xa0\x0f\x04\x34\xf4\x12\xec\x26\xa4\x6d\xae\x69\x1d\x96\xc0\x14\xe6\xa4\x0c\x08\x89\xe7\x3c\x02\xb8\x9c\x85\xac\x02\x11\x81\x8c\x4c\x0b\x27\xd4\xad\x43\xed\x5c\xc7\x7e\x09\x9b\xe9\x95\x60\xe3\xd5\x34\x02\xd6\x4c\x14\x67\x42\xf2\x4e\xe2\xc4\x57\x91\x1b\xd6\x4d\x58\xc4\xca\xa0\xf2\x01\x56\x5c\x2c\x7a\xe8\x31\xb7\xf6\x3c\x01\x24\x55\x46\x95\xde\xda\xf4\xb3\x9e\x86\x30\x86\x5e\x86\x87\x92\xd5\x12\x51\x3a\xd5\x40\x2d\xc3\x0a\x77\x4d\xc0\xa8\x2e\xaa\x70\x16\xa7\xa3\xd4\x01\xb3\xa4\x13\x34\x88\x7a\xa5\x74\xbd\xb7\x8a\xfb\xe4\xcb\xea\x84\xb8\x38\x79\x6b\xb3\xab\x68\xef\x9a\xd2\x40\x22\xd6\x7e\x62\xa2\x8f\x1b\x0f\xae\x36\x6a\x54\x53\xc6\x75\x70\x72\xbf\x90\x96\x07\x17\x17\x1b\xf5\x0c\xd4\x75\x6b\x29\xd2\x86\xac\x78\x29\x31\xc5\x52\x8b\xf9\x91\xf6\x88\x09\x8a\x8c\xc4\xca\xc4\x68\x1a\x75\x28\xda\xa0\x33\x05\xea\xf5\x45\x18\xc9\x38\x24\xd3\xcb\x90\x1a\x8e\xa5\x03\x1c\xbc\xc6\x3d\x91\x49\x57\xa7\x94\x49\xed\xaa\xd1\x87\x48\x82\x23\xaf\x54\x71\xca\xa0\x56\xb1\xea\xea\x98\x18\xcf\x33\x4f\x5a\x35\xf4\x12\x2b\xcd\x38\xb5\x07\x4f\x78\xb0\x19\x2a\x6d\x99\x07\xea\xe6\x87\x7a\x45\x46\x14\x89\xff\x33\x3c\x33\x6d\xb7\x9c\xef\x1b\xf3\x7d\x63\xbe\x6f\xcc\xf7\x8d\xf9\xbe\x31\xdf\x37\xe6\xfb\xc6\x7c\xdf\x78\xfd\xf7\x8d\xbf\x1c\xfe\x0a\x00\x00\xff\xff\x36\xe3\x42\xc2\x8d\x13\x00\x00") + +func fontsEliteFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEliteFlf, + "fonts/elite.flf", + ) +} + +func fontsEliteFlf() (*asset, error) { + bytes, err := fontsEliteFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/elite.flf", size: 5005, mode: os.FileMode(420), modTime: time.Unix(1559099119, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsEpicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdd\x6e\xdb\x36\x14\xbe\xd7\x53\x7c\x08\x02\x94\xc4\x92\x12\x4e\x8b\xa2\xd9\x95\x87\xa1\xbb\x1b\xb0\x07\x20\xc0\x29\x36\x6d\x0b\xb3\xe5\xc0\x92\xd7\x06\xe0\xc3\x0f\x3c\x3c\xa4\xfe\x63\x3b\xe9\xdd\xec\xd6\xd6\x11\x75\xc4\xf3\xff\xf1\x50\xca\x6a\xbb\x7a\xc8\x6f\xf1\x88\xaf\x98\x7d\xc2\xec\x0b\x66\x5f\xb2\x6f\xcf\xc5\x02\x4f\x2f\xf8\x7d\x9b\x1f\x97\x16\x7f\xe6\x87\xba\x28\x2b\xcc\x1e\xd4\xe3\xe7\x2c\xfb\xa3\x58\x6f\x6d\x8d\x83\xdd\xda\xbc\xb2\x78\xf8\x38\xc3\xfd\x3d\x66\x0f\xf8\xed\xb8\xc6\xec\xf1\xf1\x73\xf6\x97\x3d\xec\x8a\xaa\x2a\xf6\x25\x8a\x0a\x1b\x7b\xb0\x4f\x2f\x58\x17\xff\xda\x12\xf5\x1e\xbb\xfd\xb2\x58\xbd\xa0\xde\x14\x15\x56\xfb\xb2\xbe\x43\x5e\x61\xbb\x2f\xd7\xfe\x58\x6f\x6c\x46\x0c\x85\x3d\x7c\xa8\x50\xe6\x3b\xeb\xe7\x78\xde\xe6\x0b\xbb\xc4\xbe\x44\x8e\xc5\x7e\xb7\xb3\x65\x8d\x6d\x51\xda\x8f\x59\xf6\xed\xc7\xf3\x36\x2f\xf3\xda\x4b\xdb\xaf\xb0\x2a\x0e\x55\xb8\xf6\x6b\xe6\x6d\xc3\x3d\x6e\x76\xf9\xba\x58\xa0\x3c\xee\x9e\xec\xe1\x06\xab\xfd\x01\xab\x62\x6b\x51\x2c\x6d\x59\x17\xab\x62\x41\x37\x67\x39\x00\xdc\xa3\xda\xec\x8f\xdb\x25\xf2\xed\xf7\xfc\xa5\xc2\x93\xc5\xdf\xf9\x87\x3b\xba\xa9\xdc\x7f\xcf\x6e\x03\x53\xbd\xb1\xb8\xd9\xe4\x87\xe5\xd3\x36\x2f\xff\xb9\xf1\x0e\x78\x3e\x14\x65\x5d\x79\x1b\x72\xd0\xe8\x1d\x9e\x8e\x35\x16\x79\xf9\xa1\xf6\xd3\x54\xbb\x63\xb5\xb1\xcb\xec\x31\xcc\xb0\xb1\xc5\x7a\x53\x7b\x8d\x73\x2c\x36\xf9\x21\x5f\xd4\xf6\x90\x7d\x7d\xe5\xe2\x1d\xca\x7d\x8d\xa2\x5c\x6c\x8f\xcb\xa2\x5c\x63\x69\xab\x85\x2d\x97\xf6\x50\x65\xb3\x4f\x74\xdb\x2e\xff\x41\x96\x63\x6b\xcb\x75\xbd\x81\xb0\x3f\x22\x73\xdb\x69\x95\xc4\x2f\xc8\xb1\x3a\x2e\xd7\x16\xab\x7c\x51\xef\x0f\xd9\xec\x0b\xcd\xb0\xb4\xab\xfc\xb8\xad\x83\xb2\xbb\xfd\xd2\x92\xe1\x29\x54\x91\x2d\xb8\xd2\xeb\xd7\x99\x37\xcb\x6e\x6f\xe7\xa7\xbe\xf3\x0c\x06\xf3\x4c\x40\xce\x33\x07\xd7\xfe\x11\x46\xc6\xab\x44\x01\x81\x3b\xde\x40\xf7\x40\x3b\xa7\x40\x57\x3d\xc3\xb9\x47\x22\x0c\x7f\xfd\x89\x80\xa4\xaf\x3f\x31\x0e\x8e\xbe\x24\x3a\x32\xca\x70\x45\x18\x39\x76\x05\x8e\xff\x85\xd9\x8c\xa4\x6f\x12\xd8\x92\x4a\xf7\x90\x18\xe3\x8c\x33\xc6\x78\x63\x60\xfc\x47\x79\xcb\x05\x8d\x92\x00\xff\x81\xb7\x52\x69\xcf\x2b\xbd\x57\xb4\x09\x9f\xe0\x11\xaf\x67\x47\xca\x3c\xd1\x4c\x28\x3d\xcf\x84\x04\x14\x14\x8d\x28\x04\x77\xf9\xa3\x27\xe8\x88\x79\x46\x47\x21\xe7\x99\x56\x1d\x57\x45\x5f\x45\x47\x29\x63\x34\x51\x02\x5a\x41\xd2\x98\x06\x4f\xe6\x0f\xda\x4b\xf4\xd3\xfa\x51\xb2\xcd\xcf\xe8\xc7\xbc\xea\x4a\xab\x46\xdb\x6e\xf4\x39\x8c\xd3\x3f\x1c\xb4\x20\x47\xb2\xee\xfe\x6e\xe1\x39\xd8\xf9\x7c\x06\x0d\x1d\x74\x63\x4f\xa5\xec\x21\x1e\xdd\xe1\x91\x88\x21\x6c\xce\x78\x6e\xa3\x92\x2b\xe6\xed\x60\x7a\x0e\x1d\xfc\x1b\x67\x8a\xae\xf5\xb1\xf7\xe1\x8f\x39\x92\x52\x24\x8c\x37\x5e\x67\xf1\xc1\xe1\x5a\x75\x92\xa5\x97\x2b\x21\x41\x99\x24\x4b\x39\x83\x90\x72\x85\x82\x24\xbb\x0c\x1d\x92\x12\x72\x98\x2b\xaf\xfd\x74\x82\xd3\xcf\xac\x2e\x11\x92\x35\x66\xad\x7c\x9d\xf9\x22\xf9\xad\xe2\x1f\x64\x36\x70\x66\x66\x7b\x62\x2c\xb3\xb9\x9a\xc0\x45\x08\x04\x20\x12\x3e\x5a\x8c\x44\x74\x3b\x91\x42\x41\xc9\x40\x7a\x31\x0c\x55\x10\xc6\xc8\x00\x58\xa6\x67\x3c\x6b\x1d\x8b\x87\x62\x1e\x42\x2e\xb9\x74\x28\x40\xa3\x84\x21\x0c\xe1\xb2\x31\x6a\x42\x6b\x05\x13\xb5\x26\xf3\x82\xd6\xc1\x2d\x08\x69\xed\x53\x38\xb8\xc6\x13\x21\xa1\x05\xe5\x83\xf1\x2e\x8c\x80\xa2\x7a\x5a\xb3\x88\x46\x86\x8e\x2e\xd4\xa1\x9c\x09\xb4\x64\x70\xbe\x37\x1d\x22\xb9\x56\x7a\x06\x45\xf5\x4e\x20\xc0\x32\xd4\x08\x52\x99\x84\x2c\x60\xfd\x39\x86\x92\xc1\x54\x31\x9a\xc6\xdc\x4a\xe5\x44\xdc\x22\xc5\x33\x81\x6f\x4c\xf5\x7e\x39\xf5\x42\x6d\x8c\x57\x92\x42\xed\xab\x8f\xc8\x68\x31\x43\xaf\x6e\x19\x24\xd9\x20\x43\xe4\xa4\x41\x49\x06\x54\x92\x21\x46\x65\xb8\x60\xbb\x46\x54\x82\x26\x16\xc4\x10\x20\x48\x8f\xcb\x98\x0e\x8c\xe4\x88\x93\x2b\x55\x72\x6a\x83\xcd\x2a\xe5\x21\x97\x04\xb4\xe9\x15\x45\xdb\x0e\x24\x3b\x48\x46\x47\xb7\x50\x82\x03\x86\x0b\xec\x98\x92\xd1\x9f\xc2\xc5\x29\x52\x6a\x7b\x06\x77\x5e\x3c\xc6\xa1\x64\x70\x3a\x0a\x46\x63\xb7\x74\xc1\xd0\x44\x1f\xcb\x08\x3c\x11\x77\xa2\x25\x71\x6d\x08\xcb\x24\x27\x54\xb3\x26\x25\x54\x6b\x0e\x0d\x8c\xca\xc1\x59\x97\x13\xad\x45\x2d\xae\x6a\xe3\x02\xe5\xa8\x82\x46\xf5\x5b\xa2\x13\x11\xa1\xa5\x2a\xc2\xac\x5f\x92\x52\xf5\xb5\x8a\xaf\x5d\x7b\xa9\xb4\x79\x34\xa2\x46\xd3\x4d\xb0\x98\xa8\x96\x61\x9d\xfd\xd4\x0a\x3a\x88\x75\x70\x42\x48\xd5\xac\xf6\x0c\x2c\xc1\x54\x8a\x7b\x5c\xeb\x87\x59\x30\x5e\xfb\x0d\xcc\x83\x01\x3d\xe5\x1a\xd7\x25\x8f\x36\x0c\x92\x2c\x76\x14\x7e\x2a\x67\x37\x59\x97\x62\xb4\xb4\x49\x46\x30\x82\x64\xc4\xb6\x45\xc4\x40\x39\xc8\x98\xcf\x4e\xb1\x91\xa3\x32\x5e\xc3\x30\xc7\xcc\x93\xa4\x08\x0e\x6b\x96\xab\x69\xe0\xe7\x25\x51\x37\x6a\x72\x38\x1a\xaf\x38\x20\xae\x83\xae\xe3\x4c\x45\xbc\x62\xa2\x2e\xcf\xc2\xe2\xa8\x31\x2d\x85\xc9\x57\x17\xda\xf1\x2e\x19\x32\x91\x2a\x4e\xfc\xae\x78\x30\xaf\x27\x75\xca\x41\x73\xaa\x7d\x48\xa2\x1d\xa3\x6e\x2f\x1f\xdf\x9f\xbb\x26\x7e\x08\x49\xa9\x46\x15\x03\x87\x18\xe9\x24\x47\x48\x13\xda\x15\x9e\x61\x2c\x1e\x03\x19\x48\x32\x12\x8e\x38\x24\x1c\x19\x21\x9d\xf6\x31\x92\x69\x81\x56\x23\xf1\x68\x7c\x05\x6e\xcf\xc9\x2b\x9a\xdb\x44\xea\xd6\x52\x0d\x22\xd5\xa0\x07\x15\xce\x73\xee\xcc\xe7\x99\x33\x2a\x86\x71\x42\x86\xe0\x65\xb0\x9f\x36\x3f\xab\x06\x39\xaf\xe8\x13\x72\x85\xb6\x10\xa1\xda\xc2\xff\x80\x8e\x46\xba\x41\x39\x9e\xc6\xab\x96\x1d\xa2\xc9\x2b\x6f\x93\x88\x4d\xae\x8e\xb3\x09\x0d\x9d\x4a\x5e\xc7\x86\x58\x12\x77\x92\x21\x07\xb9\x7b\x1a\x77\x7b\x00\x32\x24\x4f\xd6\xc7\xb0\x06\x93\x0c\xc8\x34\x85\x91\xa9\x3e\x68\x8a\xf7\xd5\xf9\xf9\x76\x28\x9d\xec\xf0\x19\x16\xed\xd0\xea\x9d\x76\xc4\xed\x1e\x85\x46\x24\x3b\x68\x41\x64\x3b\xf4\x1b\x31\xd1\xf4\x1f\x3f\x70\x06\xb6\x7b\xae\xc1\x93\x88\x9f\x88\x25\x5d\x52\x1a\x31\xb6\x6d\x4d\x11\x9b\xc0\xc4\xf7\xe7\xd5\x05\x32\x3a\x3d\x12\xf5\xd4\x2a\x3e\x18\x89\xdd\x37\x77\xda\x6f\x90\x61\x92\xf2\x02\xa9\xce\x9b\xea\x4f\x98\x70\x91\x1d\x82\x75\x0b\x1a\xfb\xee\x4c\xf1\xa3\x10\x93\x1e\x51\x08\xca\x27\xcf\x1b\x76\x7d\x72\x1a\x4b\x2e\x92\xd1\xf6\xca\x78\x52\x8c\xfa\xaa\xc9\xdd\x33\x36\xbd\x48\x9b\x5e\xa6\xe2\xfe\x57\x9c\xc4\xdd\x58\x1c\xa9\xfa\x62\xa8\xc7\x8e\xa2\xa9\x95\x41\x4f\x4f\x5b\x34\xcd\x84\x0e\x6b\x45\x6c\xcf\x53\x7f\xce\x06\xa7\xbd\xa6\xe6\xbd\x75\x67\xe1\x69\xab\xd6\xd4\xa4\x64\xab\xdd\xe8\xb1\x9d\xdd\x1d\xd5\xa8\x59\x16\x4a\xf3\xe0\x59\xbf\xf3\xde\xb3\x97\xcb\x89\x2e\xac\xc8\xce\xa3\xbf\x98\x4f\xd3\x3f\xd7\x16\xfe\xda\xc2\xbf\x4d\xc6\xb5\x85\xbf\xb6\xf0\xd7\x16\xfe\xda\xc2\x5f\x5b\xf8\x6b\x0b\x7f\x6d\xe1\xff\x07\x2d\x3c\xc2\xeb\x17\x11\xde\x12\x49\xf2\x84\x0a\xab\x8f\xe6\xf5\x48\x8a\xc0\x32\x7c\xa8\x3e\xf8\x73\x84\xd6\x1f\x21\xf4\xc6\xa2\x45\x61\x2d\xe3\xd7\x79\x32\xbc\x03\x73\xa1\x89\x77\xf4\x72\xcc\xd0\x20\xbd\x24\x1c\x4a\x4b\x6f\x78\x95\xd1\x46\xf9\x76\x4b\x91\xeb\xde\xd8\x67\xb3\x46\x88\xe5\x2f\xa3\x91\x53\xe8\x37\xda\x76\x9c\xd1\x27\x5f\x22\x63\x14\x61\xcf\x58\x13\xc6\x64\x5c\x84\x1a\x6f\x94\x71\xf5\xd5\xf4\x1a\x3d\xdc\x1b\xa5\xfd\x4e\x18\x55\xcd\x68\x60\x70\x71\x17\x74\x7a\x8d\xfe\x2f\x00\x00\xff\xff\x8c\x73\xa3\xb7\x7e\x26\x00\x00") + +func fontsEpicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsEpicFlf, + "fonts/epic.flf", + ) +} + +func fontsEpicFlf() (*asset, error) { + bytes, err := fontsEpicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/epic.flf", size: 9854, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsFenderFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x18\xdb\x6e\xdb\x36\xfb\x9e\x4f\xf1\x21\x48\x41\x1b\x3f\x45\xfd\x2e\xd6\x75\x5b\x8a\x41\x37\xdb\x0b\xec\x56\x17\x52\x6c\xd9\xd6\x6a\x4b\x85\x2c\x23\x2d\xc2\xbc\xfb\x40\x7e\x3c\x8b\x52\xec\x06\x31\x4f\x22\xbf\xf3\x89\xdc\x9f\xf6\x1f\xeb\x47\xf8\x0c\x9f\x60\xf3\x2b\x64\x1b\xd8\x7c\x24\x7f\x37\xdd\xae\x19\xe0\xf9\x07\xfc\xb3\xed\xfb\xb1\x19\xe0\xb7\xfc\xf7\x5f\x60\xf5\xef\xd7\xa1\x1e\xc7\xa6\x2b\x4e\xf5\x0b\x3f\x34\xfd\x70\x68\xc6\xfe\xa5\xe3\xcd\xee\xba\x26\x40\xfe\xfa\xfe\xed\x54\x77\xf5\xd8\xf6\x1d\xf4\x7b\xd8\xb7\xc3\x65\x84\x53\xdb\x35\x7f\x10\x89\x05\x32\x78\x38\xd7\x87\x76\x0b\xdd\xf5\xfc\xdc\x0c\x0f\xb0\xef\x07\xd8\xb7\xa7\x06\xda\x5d\xd3\x8d\xed\xbe\xdd\xaa\xc3\xa4\x06\x00\xc8\xe0\x72\xec\xaf\xa7\x1d\xd4\xa7\x97\xfa\xc7\x05\x9e\x1b\xa8\x6a\xca\xd4\xa1\xae\x7f\x21\x8f\xb8\x69\x3c\x36\xf0\x70\xac\x87\xdd\xf3\xa9\xee\xbe\x3e\x40\x96\xc1\xb7\xa1\xed\xc6\x0b\xd4\x17\xa8\x41\xad\x32\x78\xbe\x8e\xb0\xad\x3b\x3a\x4a\x30\x97\xf3\xf5\x72\x6c\x76\xe4\x33\x42\x38\x36\xed\xe1\x38\x4a\x8a\x6b\xd8\x1e\xeb\xa1\xde\x8e\xcd\x40\x3e\x2d\x7c\x64\xd0\xf5\x23\xb4\xdd\xf6\x74\xdd\xb5\xdd\x01\x76\xcd\x65\xab\x44\x76\x21\x9b\xff\xab\x63\xe7\xfa\xbb\xe2\x1c\x4e\x4d\x77\x18\x8f\xb0\x6a\xbe\x9b\xcd\xdb\xfe\x7c\x6e\x3a\x14\xcc\x65\x0d\xff\x83\x1a\xf6\xd7\xdd\xa1\x81\x7d\xbd\x1d\xfb\x81\x64\x1b\x05\x61\xd7\xec\xeb\xeb\x69\x44\x62\xcf\xfd\xae\x51\x8c\x8f\xc7\xf6\x02\xfb\xbe\x1b\x61\x75\x6a\xbf\x36\xf0\x90\x9d\x61\xf3\xe9\x01\xfa\x4e\xc1\xad\xbb\x9d\x82\xbb\x26\x9b\x8f\x0a\x0a\x4a\x5a\x92\x1f\xa0\x25\x40\x1e\x1f\x1f\x8b\xe5\xa6\x20\x42\x80\xdf\x00\x04\x23\xd9\x14\x84\x52\xa0\x14\x67\x66\xf5\x96\xbe\x20\x20\x40\xc8\x05\x2a\xff\x60\x7e\x3e\x3d\x88\x5f\xa0\x20\x9c\x0a\x2a\xa8\xa2\xca\xae\x41\x25\xa8\x60\x78\x00\x57\x0b\x02\x76\x9f\x3d\x5b\x90\x0a\x00\x0c\x33\x42\x63\x12\x1a\x86\xea\x91\x59\x00\x66\x91\x7b\x03\x89\x9c\x32\x44\x8d\x74\xf2\x8a\x32\x60\x86\x94\x82\x54\x8c\x89\x84\x60\x94\xc4\x3c\x09\xa6\x1a\x49\x81\xdc\x64\x78\x53\x2d\xf2\x24\xb8\x06\xa5\xdb\x82\x54\x42\xb3\xad\xd9\x2b\x08\x30\xd9\x72\x2b\x3d\xbb\xd5\x90\xc2\x40\x20\x57\x0c\xa1\x66\x99\xc8\x32\x2d\x27\xa5\x02\x10\x40\x43\x91\x23\x72\xb5\x59\x64\x76\xec\x41\xf7\x70\x4c\x1a\x86\xc8\x1c\x77\xde\xb1\x0c\x31\xc7\x80\x96\xc0\x71\x1e\x09\x0b\x00\x28\x55\xbd\x96\x2d\x45\x65\xcb\x4e\x59\xd4\x8c\x09\x72\x2a\x75\x88\x12\x16\x89\xbe\x62\x8c\x25\x55\xa8\x0d\x86\x6a\xbb\x09\x3a\x2e\xac\x8e\x6c\xa7\x68\x11\x4c\x89\xd6\x18\x1d\x47\xeb\xc8\x73\xb5\x6f\xb5\xe2\x9c\xa7\x50\x31\xaa\x4f\x82\xb5\x57\xb9\x22\xfc\x15\xca\x39\xf7\x6c\x2d\x30\x53\x00\xc8\x8d\x59\xe7\xb9\xb1\xf0\x3c\xe7\x92\x4e\xee\xa0\xc0\x74\x18\xc2\x52\xd0\x84\xd0\xde\x89\x1e\x22\x65\x34\xa1\x86\x2f\x51\xc3\x18\x63\xd6\xb3\x10\x90\xe6\x4f\xae\xa8\xf3\x95\x98\x3f\xaf\x82\x43\x8e\x4b\x52\x72\x72\xa0\x25\x88\xbd\xe2\x2d\x3a\xe6\x3b\xad\xa0\x1e\x3a\x2d\xcf\xf5\x3a\x5b\xad\x20\x58\x93\x34\x04\x44\xf8\xa3\x34\x18\x3c\x62\x24\xe1\x82\xa2\xb6\x45\x30\xd6\x08\x81\x6e\xe6\x43\x2b\x59\xd8\x43\xe3\x3d\xda\xc3\x98\xf6\x36\x70\x33\xf3\x2d\x32\x47\xed\x97\xcc\xfa\x1b\xb5\x04\x47\x1e\x98\x06\x17\xa2\x0a\x81\x27\x85\xac\x14\x46\x5d\xb8\xc5\x11\xe7\xa1\x4c\x02\x21\x5b\xef\xe4\xda\x2b\x85\xf2\x46\x6b\x79\xd2\x63\xd2\x09\x42\x22\xe3\xa5\xff\x21\xcf\xa1\x2c\xdd\x5c\xda\x3f\xc7\x05\x6b\x42\x80\x3b\x0a\xc2\xf5\x54\x2e\x70\xdf\x01\x62\x87\xb0\x56\x29\x34\xc7\x36\x77\xd8\x88\xf0\xf4\xf4\xf4\x04\xf1\xba\x72\x3d\x6e\x32\x52\x0a\xb0\x91\x22\x65\xce\xd7\x66\x46\xca\xee\xf8\xac\xa9\x6a\xda\xb8\x4f\xc2\xdc\xd0\xd2\x35\xeb\xff\x08\x8d\xba\x73\x5c\xf3\xa6\x16\xed\x2a\x38\x2e\xb9\xb8\x1d\x1a\x07\x0b\x2d\x48\xc4\x36\xac\xc6\x20\xc8\x54\x60\x54\x97\x2b\xdc\x09\x4a\xe8\x08\x85\xc0\x9c\xb3\xbe\xc7\xa9\xdc\x5b\x19\x2a\xac\x46\xa9\x1f\xf5\xad\x3e\xe5\x90\x2f\xc4\x4d\x4a\x91\x2b\x67\xff\xb3\x43\x81\xa1\x79\x41\x6e\xf7\x40\xa3\x68\x68\x0b\x72\x53\xfc\x68\xdf\x14\xc2\x86\x53\x21\xbe\x7c\x01\xab\x05\xe3\x1a\x72\x6f\xe4\x15\x09\x68\x81\xf2\xd2\x23\x6d\x6b\x0b\x66\x5b\x62\xea\xd2\x1a\x28\x4b\x9e\xe7\x22\xb0\xb1\xd4\x8c\xdb\x59\xec\xb9\xd1\xcc\xa2\xf0\x30\xf8\x20\xcb\xd2\x87\x5f\x96\x3e\xf8\x72\x02\x3d\x9c\x18\x5b\x74\x31\x10\x62\x03\xbc\xd7\x16\x6d\x15\x10\x38\xae\x3d\x17\xf8\xc9\x14\x44\xc2\x4f\x84\x4b\xc3\x9a\xd1\x78\x6c\x78\xd6\xf4\x95\xe5\x52\xb4\xba\x89\xc4\x9b\x8d\x88\xdb\x78\xe2\xc7\x39\x8b\x80\x3b\xf8\x8b\x69\xfa\x1e\x3f\x91\x05\x99\xe0\xef\xfa\x89\x1f\x12\x02\x03\x4c\x8c\xab\x1b\xa2\xbc\x4e\x4a\xd2\xeb\x0a\xa2\x53\x94\x29\x6c\xe4\xcc\x78\xa3\x9c\x99\x02\x47\xb6\x65\x9e\xb0\xbb\xc8\x08\x8d\x2b\x06\x34\x87\xa4\xe6\xce\xe6\x15\x02\x8d\x04\x11\xe6\x06\x4d\x94\xf2\xe2\x69\x41\x28\x92\x5a\x59\x38\x66\xd7\x9f\x26\x84\x80\x84\xed\xb2\xeb\x72\x08\x99\x83\xf6\x53\x6a\x13\x7e\xcd\x68\x65\xeb\x04\x6b\xcb\x46\x1e\x67\xab\xd0\x96\x84\x5f\xf8\xa6\xfa\x99\x02\xde\x95\x1d\xae\xde\xd0\xa2\xd0\x25\x87\xd6\xa8\xe7\x5f\x51\xc9\xeb\x5d\x53\xa7\x7d\x50\x75\x42\x50\x06\x71\xed\x6e\x20\xfc\x5b\x4e\xb4\x31\x5d\x3f\xcd\xb7\x52\x4a\xb6\x38\xac\x50\x49\x0b\x4d\x52\x9c\x78\x87\xe1\x48\x9d\x49\xa8\x15\x26\xbe\x85\x8c\x60\x16\xfd\x91\x1f\x74\x5c\x11\x33\x1f\x13\x62\xae\x25\x7e\xe6\xe9\x51\x52\x91\xbe\xf3\x39\x47\xf2\xb2\x8d\x21\xde\x15\x03\xef\xb0\x31\xd1\x30\x02\x61\xda\x84\x5c\x46\x80\xb4\x39\xc8\x7b\xe3\x93\x15\x02\x06\x5e\xf0\xe6\xe8\x0e\x33\xf4\xcf\x22\xf6\xaf\x5e\xc1\x65\x0e\x2a\x14\xe6\x5d\xf2\xf7\x6a\xfe\x34\xff\xfa\x6e\x7e\xe3\xd5\xd9\xcd\x29\x5d\x70\x04\x9b\x4f\x63\x8a\xc3\x04\x89\x35\x4e\x15\xd5\x38\x5c\xa5\x27\xbe\x1c\xfe\xab\x09\xc5\x37\x10\x1e\x83\xd2\x4a\x5b\x33\xb6\x72\x37\x06\xfc\x77\xe9\xfb\xdd\x02\x23\x49\x24\xa9\xb4\x3e\xe0\xce\xf2\xf4\x66\xdb\x98\x7f\x64\x88\x35\x8d\x15\x41\x64\x1b\xe0\x7c\xd3\x2f\x04\x97\x99\x42\x27\xab\x7c\x2f\x73\xa6\x0a\xce\x58\xdd\x23\x49\x35\xc3\x94\xab\x06\x8c\xb7\xc7\xc9\x63\xca\x94\xeb\x57\xe6\x61\xb2\xa2\x74\xad\xef\x9f\x33\x91\xc2\x65\x27\x5b\x86\x2b\xdc\xe1\x1a\x40\x18\x6c\xd2\x91\x22\x92\xc6\xcc\xbd\x44\x41\xba\x4f\xc5\xba\xbc\x50\x89\xc9\x96\x1c\xf9\xb2\x34\x62\xc0\x8a\x22\x53\xb5\xd8\x84\x1d\x14\x11\x89\x12\x62\xc6\x98\x93\xb4\x61\x09\x81\xaf\x3a\x73\x29\xf2\x7d\x49\x19\x6b\xd1\x1b\xcc\x90\x01\x88\xe0\x79\xc6\x8f\x50\x46\x71\x58\x3b\xa0\x84\x72\x2f\xc9\xfb\x8e\xfe\xfa\x2a\xa7\xaf\xaf\x72\x55\xb6\x6e\x66\xbe\x85\x27\x84\x48\xff\xd4\xc7\xb7\x37\xdc\x2b\x7b\xb9\xf4\xf6\xe6\x66\xe6\x5b\x4c\x00\x4e\x3f\xc0\x07\x28\x88\x6c\xe3\x3d\xd3\x13\xea\xed\xc6\x7b\xc0\x31\x0f\x26\x6a\x66\x9f\x4b\x0a\xe2\x3f\x96\xb8\xb7\x91\xe9\xcb\x48\x34\xd3\xcf\xae\xca\x63\x52\x0f\x42\xe2\xd6\xb7\x36\x07\x26\x75\xf8\x66\x30\x92\x53\xf3\x84\x65\x3f\xdf\x5f\x85\x68\x30\x3f\x1d\x29\x53\x64\x38\x37\xbe\xb9\x8a\x48\x4b\x14\x1f\x9b\xc2\x35\x23\x94\xe9\xb5\xb0\x28\xc8\x7f\x01\x00\x00\xff\xff\x82\xd6\x40\xe2\xfd\x1b\x00\x00") + +func fontsFenderFlfBytes() ([]byte, error) { + return bindataRead( + _fontsFenderFlf, + "fonts/fender.flf", + ) +} + +func fontsFenderFlf() (*asset, error) { + bytes, err := fontsFenderFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/fender.flf", size: 7165, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsFourtopsFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x55\x7f\x8b\xdb\x38\x10\xfd\x5f\x9f\xe2\x5d\x08\x24\x4b\x57\xd1\xa6\xcd\xfd\xb1\xa5\x1c\x2a\xdc\xf5\x03\xdc\x5f\x7b\x20\xd0\x2a\xb1\x92\x98\x3a\xf6\xe2\x1f\x74\x0b\xc2\x9f\xfd\xd0\x48\xb2\x95\xb4\xdb\x83\x63\xbd\x8e\x3c\x9a\x79\x7a\xf3\x66\x3c\x3e\x56\xc7\xf7\x66\x89\x1d\x3e\x60\xbb\xc5\x03\xb6\x3b\xf6\xa5\x19\xda\xbe\x79\xe9\xb0\xff\x8e\xbf\x4d\x5d\x98\xaa\xf2\xbf\x5d\x73\xc1\x4e\x3c\xee\xf0\xa9\xa5\x07\x79\x2a\xdb\xde\xec\x37\x43\x77\xd8\xd8\x62\xf8\x83\x7d\x29\x4f\x95\xed\xd1\xda\xca\x9a\xce\xe2\xfd\xe6\x01\x9c\xe3\xf3\x70\x1a\xba\x1e\xbf\xdf\x63\xfb\xf8\xf8\x81\xfd\x69\x7a\xfb\x11\x8f\xf8\xfc\xd2\x7a\xc3\x8e\xb1\xbf\x5e\x5f\x2a\x53\x9b\xbe\x6c\x6a\x34\x47\x1c\xcb\xb6\xeb\x51\x95\xb5\xfd\xc8\x3c\x39\x70\x2c\x2e\xe6\x54\x1e\x50\x0f\x97\xbd\x6d\x17\x38\x36\x2d\x8e\x65\x65\x51\x16\xb6\xee\xcb\x63\x79\xa0\x60\x66\x00\x80\xa3\x3b\x37\x43\x55\xc0\x54\xdf\xcc\xf7\x0e\x7b\x8b\x67\xb3\xba\xa7\xa0\xba\xf9\xc6\x96\xc1\xa9\x3f\x5b\x2c\xce\xa6\x2d\xf6\x95\xa9\xbf\x2e\x3c\xd1\x97\xb6\xac\xfb\x0e\xa6\x83\x01\x59\xef\xb1\x1f\x7a\x1c\x4c\xbd\xea\x3d\x4c\x77\x19\xba\xb3\x2d\xd8\x2e\x20\x9c\x6d\x79\x3a\xf7\x9e\xb1\xc1\xe1\x6c\x5a\x73\xe8\x6d\xcb\x3e\xfc\x62\xf3\x1e\x75\xd3\xa3\xac\x0f\xd5\x50\x94\xf5\x09\x85\xed\x0e\xb6\x2e\x6c\xdb\xb1\xed\x96\xc2\x2e\xe6\x95\x32\x47\x65\xeb\x53\x7f\xc6\xda\xbe\x26\xe7\x43\x73\xb9\xd8\x3a\x08\xd3\xdd\xe1\x1d\x0c\x8e\x43\x71\xb2\x38\x9a\x43\xdf\xb4\xec\x21\x1c\x5c\xd8\xa3\x19\xaa\x3e\x90\xbd\x34\x85\xa5\xc4\xfb\x73\xd9\xe1\xd8\xd4\x3d\xd6\x55\xf9\xd5\x62\xc1\x2f\x78\x58\xa0\xa9\x09\xd6\xd4\x05\xc1\xde\xb1\xed\x8e\x40\x82\xd0\x9e\xfd\xd5\xa9\x8c\x2d\x97\x32\xff\x97\xcc\xd1\xb5\x91\x8c\x1e\xdc\xcd\x2e\x36\xd8\x2c\x25\xe3\x8e\x3b\x3e\xfd\x60\x85\x55\xf2\x5e\x8f\x92\xe9\x3b\x5a\x4b\xb6\x81\x90\x6c\x29\x96\x92\x09\x78\x44\x78\xaf\x65\xf4\x5a\x6b\x5a\x4b\xe6\x7d\xe2\x25\x99\x8f\x70\x08\xff\x50\x52\x32\xe5\x17\x2e\xfc\x0b\x90\x41\x48\xc6\x9f\xb8\x7f\x54\x13\x28\xb1\x7a\xc7\x25\x5b\xae\x96\x93\x31\x5d\x42\x06\x13\xe3\x9c\xc7\x55\xee\x11\x93\x85\x07\x86\x80\x07\xf6\x87\x02\xc4\x67\x1c\x15\xf1\x01\x88\x86\xd2\x5a\x84\xdd\xe0\x20\x88\xa9\xbf\x69\xa7\x53\x94\x18\x95\x64\xb8\x17\x92\x09\x7d\x63\xc4\x27\xc9\x94\x16\x33\xbe\x0f\x15\x31\xd6\x45\x64\x2f\xe6\x38\x4a\xf6\xec\x43\xf4\xec\x2d\xbc\xf1\x1f\x6f\xcc\x20\xc6\xf1\x27\xbc\xd7\xe3\x5d\x3c\x51\xe5\xe1\x4a\xb2\x67\x9e\xdc\x83\x31\x08\x10\x35\x48\x6a\x90\x64\x5e\x0f\xef\xa7\x52\x2d\x66\x0d\x27\x21\xa7\xdd\xe4\x9d\xf2\xa4\x53\x7f\x9b\x4f\xf1\x3a\x2e\xbd\x8e\x6b\xa7\x7d\x57\x29\xad\x43\x1d\x00\x44\xf5\x15\xd1\x17\x5a\xab\x90\x0b\x08\x16\xb3\x20\x4a\x32\xc7\xf9\x27\xc9\x5c\xd2\x24\x95\x28\x14\x28\x94\x27\x97\x30\x95\xce\x85\x98\x54\xb8\xa4\xaf\xf3\x69\xb8\xb9\x44\x99\xf1\xa6\x05\xc8\x42\x8e\x6a\x3a\x9b\x22\x02\x36\xe7\x2e\xad\xe3\xc6\xe8\xc6\x1f\xfb\x62\x0c\x56\x32\x2b\x9d\x57\x9b\xfa\x7e\x4d\x6c\xd5\xc4\x06\x48\xb7\x8c\xa2\x02\x04\x1d\xa6\x04\x5c\xd6\x98\x13\x23\x15\x28\x41\xc5\x6d\xe5\x66\xba\xff\xd9\xce\x51\x65\xca\x31\x4a\xfa\x76\xe4\xd3\x2f\x22\xd5\x14\x19\xe4\x7b\xe6\x7c\xe3\x93\xce\x0a\xe7\xd5\x88\x72\x20\xfb\x99\x92\x4f\xe9\x85\xd3\xc4\xcd\x66\x30\x23\x76\xb2\x12\xb8\x22\x43\x68\x2e\x5b\x78\x0f\x35\xa7\x3a\x4d\x12\x3c\x21\x4e\x92\x64\x0c\x73\x40\x45\xe0\x2b\x52\xd9\xab\x96\x37\xcd\x3c\xb2\x9c\x0e\x10\x04\x40\xbc\xa6\xd2\xbb\x79\x8e\x69\x1a\x7b\xea\x66\xb6\xa6\x07\x8f\x4c\x06\x75\x35\x18\xa9\x18\x62\xf4\x38\x4a\x6b\x97\xb5\x0e\x75\x48\xa6\x7e\xaa\x58\x0c\x20\xff\xa9\x99\x49\x8c\x9f\xc0\x44\x6f\x21\x99\x12\x3a\x6b\x7d\x45\x63\x3e\xcc\x38\xe4\xde\x37\x6c\xe8\x1e\x2b\x23\x99\x13\xf9\xab\x97\xe4\x5b\xa5\xcf\x4b\x84\x58\x25\x3e\xe1\x3e\x43\xf8\x4c\xc4\xf5\xbb\x70\x13\x1a\x8b\x18\x0e\xca\x0e\xcb\x5f\x86\x99\xea\x9b\x8c\x62\x1a\xd7\x63\x12\x3f\x28\xea\xae\xa0\x7c\xda\x08\x74\x83\x22\x4e\xcc\x51\x22\xce\x8a\x5c\xab\xf9\xb3\x18\x0c\x3e\x6c\x9e\x0f\xd7\x34\xe7\x7e\xbf\xa6\x49\x73\x38\x74\xa6\xb8\xae\x43\xdc\x4a\x9b\xea\xea\x7d\xa6\x4d\x11\xba\xed\x0d\x28\x2d\x26\xcf\x91\xbe\x58\x13\xcd\x31\x7e\x52\x42\x43\x53\x6f\xbb\xf9\xf2\x39\xcc\x3d\x2e\x7c\x5b\xcf\x07\x68\xae\x79\x5a\x47\x2a\xf1\xef\xff\x2e\xfe\x0d\x00\x00\xff\xff\x60\x99\xf4\x95\xd7\x0a\x00\x00") + +func fontsFourtopsFlfBytes() ([]byte, error) { + return bindataRead( + _fontsFourtopsFlf, + "fonts/fourtops.flf", + ) +} + +func fontsFourtopsFlf() (*asset, error) { + bytes, err := fontsFourtopsFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/fourtops.flf", size: 2775, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsFuzzyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x58\x4b\x8f\x1c\x35\x10\xbe\xf7\xaf\xf8\x0e\x2d\x19\xa4\x76\xe5\x21\x50\x84\x5b\x23\xb5\x04\xe2\xc0\x81\x1b\x27\x40\xf6\x64\x35\x4b\x36\x4a\x76\xc3\xce\x0e\x28\xe1\xf1\xdb\x51\x55\xd9\xdd\x76\x3f\xa7\x43\x2b\x69\x7b\x3a\x55\xae\xd7\x57\x0f\xe7\xf6\xdd\xed\xcb\x63\x8d\x57\xf8\x1a\x2f\x5e\xe2\x39\x5e\x55\xb7\x97\x4f\x9f\x3e\xd2\xed\xbb\x5b\xbc\xfe\x88\x1f\x2e\xc7\x7b\x7c\x7b\x7c\xc4\x17\x6f\x6f\xba\xb7\x97\xdf\x2e\xa7\xa7\x13\xfd\x7e\xb9\x7b\x4f\x97\x9b\xf7\x74\x3a\x7f\x59\xfd\x71\x7a\x3c\xdf\x3d\xdc\xe3\x05\x3d\x87\xb5\x78\xf9\xec\xfb\xd3\xeb\x67\xdf\x7c\x55\x55\x3f\x9d\x4f\x67\x9c\x3f\x1c\xef\xef\xce\x6f\x70\xf3\xe6\xf8\x78\xbc\x79\x3a\x3d\xe2\x7c\x7a\xc2\x9f\x77\x4f\x6f\x60\xbf\xc3\xc3\x87\xa7\xbb\x87\x7b\x57\xe1\x73\x1e\x3f\xec\xaa\x9f\x71\xc0\xd1\x00\xf8\x05\x07\x9c\x78\x83\x5f\x71\xc0\x9d\xec\xfe\xc2\x01\x0f\xb2\xfb\x1b\x07\x5c\x64\xf7\x0f\x0e\xb8\x17\xe6\x7f\x71\xc0\x8f\x55\x55\xd7\xdd\xd2\xdf\xae\x22\x4b\x5d\xe5\xe0\xd2\xcb\xb7\xf1\x05\x40\x5f\x42\x13\xa9\x98\x24\x58\x63\x4d\x57\xa1\x46\x8d\xf9\x45\xf8\xbc\x9a\xd1\x55\xf0\x0e\xce\xc1\x79\xf0\xc9\x00\x11\xe0\x9d\xee\xc5\x44\xc7\xf4\xce\xb7\xce\xb7\x51\x66\x7c\x8a\x7d\x57\xa1\x71\x8e\x20\x7a\x38\xd6\x20\x90\xfe\x86\x77\xaa\x18\x39\xd7\x18\x39\xcc\x0d\xcc\x5d\x57\x35\x96\x20\x16\x04\x6b\xc8\x90\x90\xf0\xca\x34\xbc\xaa\x66\xac\x62\xdb\x8b\x1c\x36\x4c\x64\x2d\x41\x24\x53\x8b\x96\xff\xad\x05\x94\x0d\xae\x0d\x68\x59\xb8\xf7\xb4\xcc\x4f\x5d\xa5\x92\x83\x15\xb1\x75\x3d\xf7\x66\xa6\x46\x69\xc1\x96\xb0\xc7\xd1\x55\x01\x41\xec\x0c\x83\x80\xb4\x48\x70\x84\x86\x10\x48\x6c\x67\x57\xa0\x31\x60\x7e\xdf\x18\x4c\x38\x06\x0d\x3d\x59\x52\x2b\x02\x0c\xf3\x35\x8c\x20\x23\x9e\x72\x5e\x9c\x3c\x67\x4e\xf6\x29\x0b\x71\x8a\x6f\x1f\x50\x97\xb3\xe5\xfc\x11\x29\xe9\xa5\x1a\xb4\x5d\xd5\x9a\x1e\x72\x13\xb6\x0a\x9e\x1f\x91\xc1\x8f\x9b\xa5\x59\x97\x31\x82\x35\x93\x4a\x64\xa0\x70\x18\xc3\x02\x11\x16\x8b\x32\x04\x16\xac\x7b\x43\x31\x81\x52\x22\xb5\x8a\x47\xef\xa9\x77\x61\x86\xc7\x21\xc8\x12\xab\xa0\x21\x43\x5a\x66\x83\xac\xa2\x02\x2f\x42\xd5\x18\x06\xc8\x80\x5e\xef\x07\xf0\x65\xa2\x98\x51\x91\x6f\xc1\x2e\x06\x19\x88\x81\x3e\x34\x8c\x97\x15\x1d\x49\x24\x26\x8f\x0c\x92\x10\x92\x9e\xae\x5e\x91\xe8\xd8\x3d\x26\x02\x93\x0f\xb0\xa1\xd9\xf0\xca\x58\x22\x0c\xa5\xa4\x5b\x63\x9c\xd8\xc8\xbe\x61\x82\x98\x3e\x25\x14\x73\x89\x7d\x00\x93\x04\x06\xc0\x15\x12\xa7\x8c\xbe\x51\xa7\xa4\x20\xb2\xcc\x59\x1b\x07\x30\xba\x65\x58\x4e\x69\xe6\xd2\x43\x16\x36\xbc\x56\x30\x04\x12\x47\xd7\xb3\x08\x9a\x26\x4b\x63\x53\xa4\x64\x23\x95\x9d\x9f\x95\xa4\x67\x5f\x43\xab\x4d\xa0\x3a\x7a\x5a\xca\x0c\xea\xa9\xc4\xe4\x24\xdf\x14\x98\x45\xaa\xf3\x45\xbd\x1f\x79\xd7\x0e\xa9\x65\x6d\x13\xb3\x8a\xbd\x1d\xcb\x22\x79\xdf\xf8\x58\x76\x0b\xec\x97\x6d\x63\x26\x56\x92\xcf\x79\xb6\x4a\xe3\x59\x80\xd5\x98\x31\x47\x07\xe7\xdc\x16\x3a\xc4\x9b\x02\x43\xed\x15\x52\xc0\x56\x81\x1c\x19\x31\x57\x50\x76\x48\x0c\xed\x5e\x89\x63\x46\x55\x99\x43\xb4\x91\x3a\xbd\x8d\xa9\x1f\x6e\x24\x2b\xa5\x61\x62\x6f\x38\xca\x41\xa5\x9f\x56\xca\xd4\x49\x05\x5d\xf3\xd0\xe3\xba\x8a\x9c\x69\x65\x38\xd5\x58\x2b\xa3\xe6\x10\x97\xc9\x35\xad\x50\x38\x6c\x14\xeb\xc5\x90\x0d\x12\x83\x51\x15\x89\xca\x58\x2f\x4b\x4c\x8c\xd1\x36\x0a\x91\x91\x56\x19\x3f\xbb\x5d\xcd\x24\x82\x27\xb3\x0b\x24\x53\x89\x5e\x25\xee\x4d\xbd\x8d\x70\x8c\x61\x99\x9a\x0f\xb7\xbb\xed\x1e\xa2\x4d\x84\x67\x45\x13\xfb\xb1\xd2\x0c\x9b\x62\x42\xcd\xcb\x63\x06\x20\xb7\xd3\xb9\x4b\x8c\x41\x90\x88\x40\xc3\x0c\x37\x45\x5e\xe2\x25\x4b\x19\xfb\x70\xc2\x70\x48\x71\xce\xa4\x4a\x8e\xe1\x88\xa0\x09\xc0\x33\xca\x56\x02\x14\xfa\xa7\x1e\xca\x83\x46\x8b\x38\x82\xce\xeb\xdf\x77\xed\xcf\x1b\x69\x96\xca\xab\x2b\xc6\xc3\x99\x5c\x0d\x6c\x9c\xcc\xd3\xbc\x61\x02\xde\x08\x61\xd8\x1a\xa2\xa8\x68\xf3\xde\xbb\x54\x97\x17\xda\x3d\x8f\x24\x83\x17\x83\x35\x21\xde\x9d\xd2\x6c\x3a\xb7\xea\xa6\xff\xb2\xb4\x59\x1c\x88\xb5\x4d\xeb\xbd\x81\xcd\x54\x91\x8b\x37\x8e\x11\x98\x87\xeb\x8e\x49\xd7\x9d\x90\xda\xed\x3c\xf2\x47\x95\x2f\x48\x0a\x9a\xcd\x21\xaa\xfc\xd0\xe7\xae\xe1\x2b\xa2\x59\x67\x2c\xab\x3c\x59\xc1\xec\xff\x90\x68\xfc\xba\x44\xea\x11\x97\x9a\x64\x7f\x39\xcb\x6b\xc2\x78\xdc\x9a\x13\xd5\xeb\x48\x3a\x8f\x47\x48\xf1\x07\xb3\xe2\xce\xbe\x3f\x2c\x96\xbe\x7e\x96\xcc\x3a\xe5\xb4\x3f\xfa\x54\xc8\xba\xaa\x77\x63\x7e\xff\x88\xfa\xcc\xa8\xd3\xd7\x87\x38\x04\x6d\xd6\x05\x64\x4e\xea\x97\x34\x8e\x2c\x4e\xa8\x65\x65\xe2\xbb\xbb\xfe\x89\x6d\xa4\xc9\xbc\xe0\xd6\xc6\xbe\x51\x00\x8a\x43\x56\xfd\xb8\x1d\xb9\xeb\xd0\x55\x34\xb1\x20\xeb\x5c\xdb\x9c\x97\xc8\xaa\x4e\xb0\x52\xde\x2e\x46\x0e\xac\x86\xd6\x27\x52\x76\xc1\x32\x90\xb7\x5b\x19\x40\x5a\xc8\xf4\xd6\xa8\x35\x9e\x4d\x89\x83\xfc\xa6\xa8\xf1\xe0\xb7\xc3\x8f\x7d\x6b\xba\x86\x71\x0c\x20\x65\x1f\x4e\xc8\x0e\xc9\xcf\xd9\x04\x10\x45\x00\xf5\x97\x44\xdf\xd0\x55\x00\x9a\x31\x7c\x3e\xf5\x97\x00\x14\xec\x50\x9e\x16\x24\x6a\x7d\xaa\x1d\x1a\x2b\x2d\x54\xd3\xad\x6e\x35\xdf\x90\x27\xdc\xde\x99\x3a\x35\x03\x2e\x43\x7a\xe1\x77\xda\x56\x7c\x2b\xbf\x1d\x7b\x71\x61\xfa\xa3\xf8\xff\x1c\x8d\xba\x4c\xdb\xdf\x46\x57\x8b\x9b\x54\xe6\xf5\xc4\x56\x67\x97\x5d\x8d\x29\x6b\x13\xad\xdc\x3b\x77\x54\x7b\x66\x13\x26\x8a\x39\xe5\x62\xc2\x2a\x59\x7c\xaf\xc9\xd8\x2e\x16\x05\xe3\xf5\xd9\x91\x37\x7d\xb7\xa3\xae\xa5\x21\xa6\x8d\x97\xfd\xab\xef\x0d\xff\x05\x00\x00\xff\xff\x1d\x41\x25\x8d\x47\x17\x00\x00") + +func fontsFuzzyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsFuzzyFlf, + "fonts/fuzzy.flf", + ) +} + +func fontsFuzzyFlf() (*asset, error) { + bytes, err := fontsFuzzyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/fuzzy.flf", size: 5959, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsGoofyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\xdd\x6b\xe4\xc8\x11\x7f\xd7\x5f\x51\x7b\x74\x70\x6b\xe3\x39\x39\x3e\xd8\x87\xc3\x38\xe6\xe0\xc8\x5b\x72\x24\x7b\x84\x80\xa0\xd0\x8c\x7a\x66\x94\x95\x25\x47\xd2\xc4\x6b\xd2\xf9\xdf\x43\x57\x55\x7f\xcd\x87\x77\xf7\x25\x70\x60\x63\x7b\xaa\xbf\x7e\xf5\x5d\x5d\xd2\x6c\xfb\xed\x6d\xa3\xe0\x03\x7c\x80\x1f\x6e\xe0\x06\x6e\x6f\x8b\x9f\x3f\x3f\xf5\xcd\xd0\x2c\xdd\x38\xc0\xb8\x85\x6d\x37\xcd\x0b\xf4\xdd\x60\x7e\x84\x57\x7e\xde\xbf\x7f\x0f\x7f\x1a\xc7\xed\x3f\xe0\xe6\xfb\x3f\xb8\x51\x41\xd0\xb0\x82\xc1\x6c\xcc\x3c\x37\xd3\x0b\xcc\xcb\x61\xbb\x85\x65\x84\xae\x35\xc3\xd2\x6d\x5f\x60\xd9\x1b\xf8\xd4\x0d\x2d\x33\xea\x4d\xa1\x08\x6c\x45\x0b\xdf\xed\x9b\xa9\x5d\xf7\xcd\xf0\xe9\x3b\x58\xad\xe0\x69\xea\x86\x65\x86\x66\x86\x06\x68\xf6\x1a\xd6\x87\x05\x36\xcd\x70\xb5\xc0\xda\xc0\xfc\x78\x98\xf7\xa6\x2d\x3e\x08\xc4\xde\x74\xbb\xfd\xe2\x90\x1b\xd8\xec\x9b\xa9\xd9\x2c\x66\x7a\x7d\xf5\x1a\x86\x71\x81\x6e\xd8\xf4\x87\xb6\x1b\x76\xd0\x9a\x79\x63\x86\xd6\x4c\x73\xf1\xc3\x0d\x9f\x7b\x6c\x3e\x93\x31\xa0\x37\xc3\x6e\xd9\x83\x36\x9f\xfd\xee\xcd\xf8\xf8\x68\x06\xb6\xd5\x5c\xc2\xef\xa1\x81\xed\xa1\xdd\x19\xd8\x36\x9b\x65\x9c\x8a\x1b\x61\xfd\xe4\xa4\xf6\x2c\x67\x58\xc6\x9d\x59\xf6\xcc\x9c\x95\x70\x60\xe3\x04\xcf\xfb\x66\x31\xff\x76\x0b\x4f\xbd\x69\x66\xf3\xae\xb8\xbd\x65\x84\xe1\xf0\xb8\x36\x93\x13\x3e\xe3\x09\x7a\x5e\x9a\x69\x71\xc7\x9f\xbb\x65\x4f\x46\xbc\x4a\xdc\x79\x45\xdb\xca\xa2\xf8\xfb\xd4\x2d\x8b\x19\x60\xfd\x02\x7f\x73\x2c\x06\xb8\x23\xdf\xdd\x43\x6b\xe0\xa7\x69\x3c\x3c\x9b\x09\xb4\x9b\x9a\x4d\xff\xd0\xb6\xf3\xf7\x43\x5f\x16\x3f\x35\xb3\x69\x61\x1c\x08\x77\x5e\x0e\x4f\x5d\x0b\x93\x69\x36\x14\x29\xdb\x69\x7c\x84\x27\x33\x3e\xf5\xc6\x79\xf8\xb9\x59\x36\x22\xc0\x76\x9c\xcc\x6e\x1a\x0f\x43\xbb\x1a\xd7\xff\x34\x9b\x65\xbe\x82\x82\xa3\x4a\x77\xcb\x95\x73\xa7\x0f\x81\xdd\x38\x6e\x5f\xae\xa1\x9b\x9d\x4b\xbb\xe5\x8f\xf0\x63\x09\xc5\xc7\x7d\x37\xc3\x76\x1c\x16\xe8\x66\xf8\xf3\x5f\x3e\x3a\xaf\x74\xbb\xc1\xb4\x8e\xcf\xda\xc0\xc1\x49\xb5\x1d\x27\xd8\xf4\xa6\x99\xae\xa1\x1f\x87\x1d\x2c\xe6\xf3\xf2\xae\xf8\xb8\x37\x93\x71\xfc\xa1\x1f\x9f\xcd\xb4\xda\x34\xb3\x71\x28\xe6\x5f\x87\xa6\x77\xc7\x7f\xfd\xe5\x97\x9f\xff\x4a\xd3\xef\x0a\x00\x40\x44\x94\x78\xc6\x40\x67\x14\xc4\x65\xfa\x1f\xd6\x0b\x80\xca\x2d\x94\x3c\x51\x0a\x0d\x1a\x52\xaa\x96\xb3\xa5\x1b\x69\x9a\xe7\x9d\x05\x6f\xac\xe8\x97\xd9\x38\x38\x8d\xb5\x50\x7c\xd6\xba\x29\x94\x51\x5d\xc9\x52\xe5\xb8\x97\x20\x98\x9a\x16\xb5\x08\xea\x38\xa1\x97\xc1\x12\xf7\xd2\xa3\xf1\x69\x0d\x50\x30\xe5\x30\x69\xb9\x94\x75\x9a\xae\x49\xc4\x4a\xb8\x43\xc0\x15\xb1\xa0\x84\x42\x93\x0d\x18\x98\x24\x64\x5a\x63\x4a\x31\x0b\xde\x59\xf9\x45\x47\x15\x85\x2b\x1e\xbf\xce\x86\xe2\xe5\x77\xe4\xcb\x06\xda\xf1\xb0\xee\xcd\x6a\x04\x3d\x8e\xe5\x35\x34\x43\x4b\xcb\xff\xf9\xaf\xab\x00\x6b\xb3\xeb\x86\x15\x4d\x9a\xa1\x5d\x3d\x36\xd3\x27\x33\xcd\xef\xa8\xee\x20\xe2\x43\xa1\x94\x3a\xf9\xe7\x16\x1e\x0a\x54\x4a\x29\xb7\x45\x3b\xa2\x74\x8b\xb5\x52\x15\xef\xaa\x2b\xd9\x8e\xc8\x47\xb4\x52\x65\x38\x86\xc9\xc9\xd2\x1f\x2e\xb1\xa2\x3f\xe6\x22\x3f\x39\x8d\xe1\xc7\x01\x45\x24\x27\x27\x96\x4a\xd3\x9f\xdb\xa8\xc3\x1a\x41\xbf\xb2\x86\x61\x2d\x2a\x25\xd2\x39\xd1\x50\xb6\x69\xa5\x34\x5a\xcb\x12\xd5\x34\x5f\x13\x8d\xd6\x62\xc9\x1a\x68\x3e\xaa\xa3\x74\x24\x5b\xa4\x9c\x32\x4e\x5d\xde\xe8\xa9\x87\xc2\x19\x4d\x69\xac\x15\x99\x4f\x09\xb4\xc0\xa9\x52\x69\x85\x2a\xb5\xb1\xec\xab\x09\xa2\x52\xa2\x05\x71\xc6\x48\x05\x21\xd8\x60\x85\xd2\x4a\x97\x74\x84\xac\x7a\xaf\xd4\x1d\xe9\x41\xfc\xab\xda\xb9\x8c\xb5\xd0\x84\x71\x47\xb8\xc4\xed\xee\x5e\x95\xc1\x75\xc1\x6d\xe2\xb2\xe0\xa2\xf8\x99\xb8\x88\x8e\xb8\x95\xca\xfd\xb2\xaa\x95\x68\xa7\x83\x35\x6b\x3e\xe5\x28\x77\x4c\x64\x7e\x28\x78\x29\xdd\x44\x66\x2b\x53\x20\xf7\x19\xb8\x85\xf0\x28\xd8\xc7\x28\x82\xa1\x26\xf5\xc4\xff\x62\x15\x82\x51\x1a\xab\x9a\x6c\x96\x03\xc4\x91\xc7\xf2\x40\x11\x25\x42\xe4\xe7\xfd\x61\xb1\x48\xfc\x40\x14\xd5\xd9\xd0\x55\xc2\x27\xb1\x22\xa2\xe7\x20\xf8\xa7\x56\x3d\x83\x7d\xc2\xc2\x6f\x55\xde\x05\x64\xbb\x8a\xf7\x56\x21\x53\x99\x8a\x16\x15\x9b\xea\x3c\xcd\x88\x61\xe5\x43\xd3\x12\x37\x7b\x81\xe2\x40\x4e\xd2\x89\x4e\x57\x48\xcb\xcc\xd4\x9e\x23\xd1\x91\x98\x84\x7e\x99\xc7\x30\x49\x80\x3e\x24\xb4\x2b\x17\xa4\x52\xa2\x50\xd0\x88\xcd\x80\x19\x50\x10\x85\x22\x40\xd2\xd7\xb9\xce\x86\xa8\xb0\xf9\x9c\x8a\x8a\x20\x26\x49\x5c\x45\x55\xc8\x62\x36\x0b\x2c\x76\x5a\xd4\x26\x93\x22\xa9\x2f\x96\xd5\x2a\xc9\x78\x16\xa5\x52\x32\xe1\xa5\xcb\x6b\x4b\x95\x67\x35\xb3\xa7\x3d\x84\xa6\x3d\x44\x2c\x22\x56\x85\xca\xc1\xb9\xcc\x10\x89\x14\x9a\x19\x97\x5f\x13\x17\x9a\x73\xed\x62\x5c\xe8\x58\xa6\xee\x95\x94\x10\x9d\x0b\x70\x56\x85\xbc\xe2\x91\x13\xea\xe8\x8f\xe8\x10\xcc\x3d\x42\x65\x9f\x2d\xcf\x65\x3e\xd2\x49\xaa\x9c\xdd\x44\x02\xd9\xea\x4b\x55\xea\x8e\x94\x38\x5f\xa5\x42\xde\x1e\xe7\xeb\xd1\x38\xe4\xed\xab\x65\xed\xde\xfd\x9e\x2f\x6b\xc1\x51\xa1\xf2\x71\x05\x45\x29\xa0\xe8\x9d\x53\xa6\x55\x3f\x0f\x11\x8c\xf1\xe0\x8a\xbd\x44\x95\x55\x96\x13\xbd\x92\x35\xe9\x2a\x62\xe9\x4f\xd2\xd0\x4d\xc7\xd2\x53\xb1\x0e\x3e\x54\x82\x46\xae\x74\x94\x49\xf0\x05\x37\x72\x7c\x3a\x47\xc6\x00\xf4\xd6\xf0\x01\xa0\x6c\x0c\x20\x22\xef\x8e\x66\xab\x33\x69\x10\xb3\x40\xd4\x93\x1c\xb0\xca\x53\x1c\x4c\x5e\xa5\x98\x86\x28\x59\xf8\x55\x55\xcd\x9e\x64\x8f\x0a\xd2\x7b\xcf\x27\x39\xa8\xac\x0a\xa9\x29\xf3\xa8\x82\x06\x79\x31\xf8\x36\x20\x15\x6a\xb4\xf8\xeb\xd4\xe5\xd4\xb9\xa0\x3f\xc4\x21\x25\x70\x7c\xef\x6a\x6f\x70\x0a\x66\x5f\x64\xb8\x77\x08\x2d\x8c\xe0\xc9\xfd\x51\x73\xc9\xb3\x92\x21\x64\xd5\x8a\xc6\x5e\x46\x95\x8c\x2a\x55\xcb\xc8\xed\x41\x44\xeb\xb3\x26\xad\x3c\x49\xb9\xfc\xa6\x1b\x41\xae\x15\xbe\x7b\x43\x99\x90\x93\x9c\x11\xd6\x97\x70\x8b\x36\xb9\x96\x52\x0f\x26\x9a\x29\x1b\xee\x46\xb7\x3b\x54\x41\x76\xbf\x0e\x8e\xb0\x3e\x61\xe9\x06\x70\xe6\xaa\xd3\x68\x0a\x60\xf1\xc0\x79\x32\x8b\x85\x2c\x14\x48\x22\xeb\x69\x09\x3c\x5b\x57\x36\x0e\x82\x72\x27\x03\x64\x83\x25\x12\xa5\x80\x75\xb6\xb7\x56\x75\x86\x53\xab\x3a\x83\xad\x53\xfe\x48\x65\x8f\xa1\xcf\xf7\xb3\xbe\x90\x1f\xf7\xae\x69\xc7\x9a\xf6\xa9\xaf\xe6\xa0\xa4\x72\xa8\x4b\x31\x95\x2d\xe6\x11\x1f\x2e\x90\x70\x5f\x27\xd7\x47\x0c\x0b\x2b\x75\xd8\xe6\xd6\xb9\xc8\x59\xc4\xb5\x6c\x26\xe1\x5c\x67\x11\x1c\x1f\x11\x24\x69\xb5\x4f\x72\xe1\x9f\xde\xe2\xe7\x1f\x11\xd2\xf4\x3f\xea\x4a\xd3\x80\xb9\x38\x40\xf1\x37\x9e\x49\x57\x1b\xd2\x35\xba\xf4\xe2\x88\x53\x39\xc9\x92\x2c\x51\x8e\x30\xbf\x18\x89\x54\x54\xaa\xe0\x71\x9f\x76\x89\x8c\x47\x42\x1e\xc9\x75\x61\xc8\xb0\xc7\xc0\x29\x34\x86\x9b\x9c\xd3\xd4\xdf\xe6\xa9\x3c\x74\xd3\x86\x5b\xdd\xcd\x26\x29\x5d\x25\xb7\xbb\x57\x5c\x1e\x78\x74\x7c\xf2\xc8\xe1\x6a\x89\x16\x76\x4e\x19\x2e\x20\x0a\xde\xd8\x45\x67\x9e\xfe\x8a\x86\x0b\x4f\xca\x5e\x5e\x1e\x9c\xeb\xa3\x89\x8e\x29\x3e\x2d\x97\x57\x6a\x78\xb6\x8d\xbf\x43\xa4\xff\x08\x8a\xd4\x5e\x8d\xd8\xed\x60\x5e\xe4\x98\x7f\xd2\x9b\x05\xef\x24\xd5\x17\x6d\x76\x79\x9e\x36\x7c\x95\x64\x95\xeb\xe1\x55\x9d\x3c\xe5\xe4\x4f\xfc\xc9\x13\xd9\xb9\xe7\xa4\xa3\x4f\xdf\xb8\x94\x69\xc3\x9f\x3d\xae\xd6\xae\x63\x7a\xfd\x71\xf5\xad\xc7\x79\xeb\x71\xde\x7a\x9c\xb7\x1e\xe7\xad\xc7\x09\x21\xfc\xd6\xe3\xbc\xf5\x38\xea\xff\xd7\xe3\x84\x37\x6c\xf4\xc6\x9a\x8f\x85\x1a\x2f\xaf\x55\xfc\x56\xce\x9b\x0b\xff\x7d\x19\x65\x99\x19\x94\x31\x19\xf2\xa1\xa0\xd4\xe3\x34\xa3\x3f\xe6\x51\x57\xb4\x91\xde\x0b\x1f\x7d\x1d\x71\xb9\x37\xa1\xa8\x64\xcd\xf9\xfb\x04\x7e\x6f\x85\xb1\x6a\xf8\x04\x44\xef\x78\xb7\xcb\x7e\xcb\xe1\xf3\x6f\xd2\xce\x1d\x96\x6f\x38\xd8\x18\xd1\x20\xf6\xf4\xf5\xec\x6f\x53\xec\xb4\x3a\xf3\xb5\x1f\x5f\x6e\x61\x99\xbc\xda\x62\x6f\x3b\x1a\xe3\xbc\x0e\x40\xff\x0b\x00\x00\xff\xff\x7e\x7a\xbc\x62\xb5\x1f\x00\x00") + +func fontsGoofyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsGoofyFlf, + "fonts/goofy.flf", + ) +} + +func fontsGoofyFlf() (*asset, error) { + bytes, err := fontsGoofyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/goofy.flf", size: 8117, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsGothicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x39\xef\x6e\xe3\xb8\xf1\xdf\xf5\x14\x83\xe0\x00\x4b\xbf\x68\x42\xf8\xf6\x7e\x87\x4d\x63\x07\xc6\x15\x6d\xef\x01\x0e\xed\x17\x02\x34\x6d\xcb\xb6\xba\xb6\x14\x58\x32\x36\xdb\xe5\xe6\xd9\x0b\xce\x90\x12\x25\x4b\x4e\xb6\xb9\xf6\x82\x44\x1c\x51\xc3\xf9\x3f\xc3\x21\xb3\x3d\x6c\x7f\xd4\x3f\xc0\x3d\x7c\x84\xe9\x4f\x80\x53\x98\xfe\x1c\xfd\xad\xac\xf7\xf9\xfa\x6e\x7b\xd8\x02\xc2\x6f\xfa\x53\x56\xc0\xf6\x54\x1e\x41\xc3\x4a\x17\x45\x76\x82\xa7\x53\xb9\x3b\xe9\x23\xac\xf5\xe1\x90\x6d\xe0\x66\x47\x0b\x6e\x60\xf5\x05\x7e\x2d\x3f\xeb\xd3\x06\xfe\xbc\x3f\x47\x7f\xcd\x77\x87\xac\xce\xff\xa5\xeb\xbc\x2c\xa0\x3a\xef\x76\x59\x55\x67\x1b\x58\x9d\xe1\x97\x72\x05\xbf\x9c\xf2\xdd\xbe\x86\x78\x45\xe3\x62\xbd\xbe\x3b\x1f\x75\x91\xd7\xe5\x4a\xdf\xad\x75\xd2\x2c\xb7\x2b\xbe\xc0\x3f\xb2\x62\x93\x1d\x0e\xf0\x6b\xbe\xb6\xf2\x4c\xa7\x62\x7a\x2f\xee\x3f\x40\xfc\x79\x4f\x33\x8b\x27\x7d\xd2\x55\xb9\xad\xef\xd6\xe5\x31\x89\xfe\x9e\x9d\x2a\xcb\x75\x7a\x37\x05\x84\xf3\xd3\x46\x5b\xce\x25\x2d\xfc\xf1\x83\xb8\xff\x10\x62\x0c\xa0\x7c\xb4\xb4\x57\x5f\xac\x90\xba\x80\xdf\x74\x09\x71\xad\xcb\xd5\x22\x2f\xef\xca\xd3\x2e\x89\x20\xfc\x41\xd0\x9b\x7f\x9e\x59\x37\x5d\x65\x87\xbc\xc8\x40\x17\x1b\xd8\xe6\xcf\xd9\x06\xaa\xf2\x98\x41\xf5\xa4\xd7\x79\xb1\xb3\x96\x5b\x1d\xb2\x63\x15\xfd\xe5\xf9\xe9\xa0\x0b\x36\x4d\xb9\x85\x6d\x7e\xaa\x6a\xb0\x2b\xff\x14\x59\x97\x00\xc2\xcd\x51\xef\xf2\x35\x14\xe7\xe3\x2a\x3b\xdd\xc0\xb6\x3c\xc1\x36\x3f\x64\x90\x6f\xb2\xa2\xce\xb7\xf9\x9a\x16\x47\x9a\x25\xa8\xf6\xe5\xf9\xb0\x01\x7d\xf8\xac\xbf\x54\xb0\xca\x60\xa9\x27\x29\x2d\x2a\xca\xcf\xd1\x0f\x8c\x54\xef\x33\xb8\xd9\xeb\xd3\x66\x75\xd0\xc5\xa7\x1b\x40\x84\xa7\x53\x5e\xd4\x15\xe8\xca\x7a\xd7\xce\xa6\xb0\x3a\xd7\xb0\xd6\xc5\xa4\xb6\x64\xaa\xe3\xb9\xda\x67\x9b\xe8\x9e\x29\xec\x33\x72\x5a\xb9\x05\x0d\xeb\xbd\x3e\xe9\x75\x9d\x9d\xa2\x8f\x57\x3e\xa6\x50\x94\x35\xe4\xc5\xfa\x70\xde\x58\x0b\x6c\xb2\x6a\x6d\x7d\x79\xaa\xa2\xe9\x4f\xb4\xec\xa8\x9f\x49\x73\x38\x64\xc5\xae\xde\x43\x9c\x3d\x7b\xe4\x75\x79\x3c\x66\x05\x1b\xa6\x4a\xe0\x16\x34\x6c\xcf\x9b\x5d\x06\x5b\xbd\xae\xcb\x53\x84\x53\xa2\xb0\xc9\xb6\xfa\x7c\xa8\x59\xd8\x63\xb9\xc9\x48\xf1\x7a\x9f\x57\xb0\x2d\x8b\x1a\xe2\x43\xfe\x29\x83\x1b\x3c\xc2\xf4\xff\x6f\xac\x8b\x2d\x5d\xeb\x21\x4b\x37\x89\xa6\x3f\x13\x15\xb6\xb4\x15\xbf\xc3\x36\x72\xce\x5e\xbc\x77\x24\x60\x11\x09\x09\x8b\x48\x0a\x58\x44\xdf\xbe\x7a\x88\x3e\xcc\x1e\x3d\xc4\xd8\xb3\x47\xe0\xa9\x04\x20\x79\x1f\x5b\x26\xc5\x93\xdf\xbe\xda\x5f\x66\x78\x7b\x3b\xbf\xbd\x75\x7c\x5f\x9f\xef\xd2\xf1\x3f\x1d\x78\x11\x81\xba\xbd\x55\x29\x2c\x22\x63\x8c\xa1\xcf\xc6\x20\xde\x11\xde\x0b\xcd\xd9\x05\x0e\x48\x51\x29\x04\x37\x13\xd2\x6a\x81\xae\x3e\x29\xdb\x09\x9c\xd1\x04\xcf\x0b\xfe\x2e\x18\x4f\x00\xdb\x6d\x39\x60\x7e\x87\x28\x79\x94\xa2\x79\xb7\x84\xc5\x44\x4a\x92\x1c\x40\x92\x93\x24\x92\xb3\x2e\x0c\x3a\x7b\xb4\x5e\xb1\x13\xa3\x7f\x24\xce\x22\x12\x82\x0c\xd0\x79\x10\x6d\x90\x5d\x67\x4b\xf0\x5f\x7a\xd8\x44\x41\x40\x17\x3b\xb0\xbd\x73\x89\x9d\x93\xce\x10\xb3\x47\xfc\x3f\x74\xde\x13\x20\x2f\xf0\xfa\x7e\x0b\xa0\x01\x07\xb0\xdb\x9b\xd8\x71\x0c\xb0\x8d\x8e\x1e\xce\x90\xff\xae\x3c\x7c\x88\x77\x55\x1b\x1f\x67\x8f\x9e\xf5\x5b\x92\xed\x15\xb6\x7d\x8b\xf2\xd8\x0b\xae\x5e\x90\x5d\x04\xdb\x68\x90\x49\x8e\x7e\xf0\xce\x1c\x1c\x41\x4a\x31\x26\x3f\xd3\x31\xc4\xc7\xd0\x00\x43\x43\x2a\x70\x02\xed\x82\xfe\x7a\x12\x23\xf6\x35\x84\xe2\xc9\x29\x25\x62\x42\xf9\xaa\x94\xba\x5c\xaf\x78\x76\xd9\x59\x01\xac\x14\x40\x92\x04\x64\x26\xc1\xc2\x80\x7f\x1a\xca\x0f\x34\x28\x65\x2c\x51\x44\x44\xce\x7a\x42\x49\xa9\x60\x0c\xf1\x67\x43\xc1\x92\x46\xc5\xe5\x84\x42\x9a\xf0\x92\x24\xf4\x50\x28\xc6\xa0\x47\x20\x15\xa1\x0b\xe3\x98\x6b\x8f\x31\x4c\x28\x8e\xbd\x47\xc4\xb0\x47\xbc\x44\x4b\x70\x88\x00\x22\x0d\x25\x88\xd9\x9e\x4d\x2d\x33\xaf\x49\xd4\x8b\x11\xce\xe0\x76\x5e\x08\xf0\x25\x61\x28\x56\x5e\x0f\x36\x90\xc2\x4b\xea\xde\xd5\x68\xb0\x8d\x67\xc7\x50\xb2\xbc\x8a\x3d\x9c\xd1\x9d\xd4\x72\x7e\x98\xcd\xdc\x77\x29\x3d\x9e\x77\x30\xc8\x61\x47\x5e\x2f\x09\xaf\x94\x88\x76\x42\xfa\x0f\xd2\x23\xf8\xf0\x86\xc7\xc7\x4e\x68\x8d\x25\x3b\x2a\x9e\x27\x37\x2d\x7d\x58\x98\xd4\x47\x43\x1b\xd5\x41\xf1\xed\xe5\xe8\xa0\xff\x84\x1b\xa5\xf1\x39\xe0\x4c\xd4\xa6\x4a\x57\x23\x8a\x4d\x9a\x43\xdb\xcd\x10\x5a\x0c\xf0\xe2\x0a\x47\x6c\x8d\xee\xaa\x86\x14\xf3\xb9\x03\x85\x02\xd5\x20\x20\xf0\xfe\x07\xfe\x27\x04\x17\x9d\x2d\x5f\xa1\x02\x95\xa6\x1e\x07\x85\x2d\x2f\x04\xbf\x18\xa3\x66\x7e\xde\x98\xd6\xa2\xa9\x40\x74\xf6\x51\x88\x0a\x27\x9c\x32\x03\xbc\x3a\xcc\x28\x6f\x11\xd4\xcb\x1d\xa1\x4f\xa8\x9e\x70\xb6\xfa\x3c\x0b\x40\x88\x81\x2a\x0d\x2d\x43\x9b\xb0\xf8\x36\x85\x08\xd7\x5b\x10\x26\x60\x00\x9b\xf2\x65\x00\xcc\xd2\xe5\xb5\x21\xd3\x2d\xa2\x17\xc3\xf3\x64\xaf\x17\x5a\x9d\x3a\x33\xbe\x55\xa1\xb4\x55\x48\x34\x5a\x88\xf9\x3b\x15\x52\x90\x3a\x0e\x84\xa8\xa8\x6c\x2e\xa2\x49\xdb\x60\xb5\x40\xea\x7c\x29\x3a\xa4\x16\xbd\xde\x4b\x29\x57\xc9\x21\x45\x03\x2f\x4e\xac\x89\x31\x42\x71\x94\xd9\xba\x69\x6d\xd1\xc0\xf3\xb9\x09\x44\x4f\x5b\xd9\x45\xcf\x2c\x23\x26\xe2\x00\xc3\x16\x49\xa4\x2d\x6c\x0c\x28\xde\x09\x6c\xac\xa1\x0d\x5b\x37\x3f\x77\xbe\x81\x18\x6c\x9a\x98\x80\xc1\x72\x98\x19\xf1\x69\x4a\xb8\xa3\xce\x84\xdb\xb7\x06\x65\x20\x75\xc9\xc4\x68\x33\x81\x53\xcc\x29\xe8\x72\x2a\x00\x5c\xee\xd9\x7e\x37\xbd\x62\xeb\x50\xfd\xb4\x55\x5f\x40\xda\xaa\x2f\x7c\x9d\xb4\x52\xce\x06\xe6\x15\x2a\x95\xf6\x52\x79\xcc\xd6\xad\xa5\x6d\xac\x37\x2c\xb9\xe0\xb8\x38\xef\xcf\xc5\xe4\xcd\x90\x7c\x00\x85\x7c\x58\x78\x29\x53\xe1\xa4\x11\x54\xdf\xda\xe6\x25\x7c\x99\x9b\xb9\x7b\x79\xe9\x7e\x49\x6d\x59\x62\x02\x3e\x26\x7a\xfa\x04\x91\x0a\xcd\x06\x83\x69\x1b\xed\x89\x8f\x16\xc4\x00\x4c\xbd\x11\x7d\xab\x67\x52\xd7\xe5\x91\x49\x10\x5f\x86\xf2\x4b\x35\xec\x53\x34\x06\xd3\x36\x1f\x8c\x2b\x82\x9c\x04\x88\x6d\x57\xe1\x5f\x7c\x4a\x24\x9d\x7c\xee\x2b\x33\xa0\x99\xfb\x80\x4a\xf9\xad\x82\x35\xe3\xb3\x84\x30\x46\x29\xb7\xc1\xb7\x20\x21\x18\x36\x9b\x31\xe8\x93\xaf\x75\xe8\x7f\x5d\x33\x29\xbf\x53\xb3\x36\xc5\xa5\xaf\xbe\xc6\x37\xde\xd2\x18\x81\x41\x09\x93\x1c\xbc\x76\x2b\x31\x6f\xd8\xb5\x58\x2a\x74\x8d\x9a\x72\x54\x63\x05\xc8\x7b\x38\x10\x40\xaa\x58\x4b\xb1\x86\x2e\x37\xc6\x02\xdd\xed\x18\x4e\x03\xbb\x0f\x22\xb6\x15\x3a\x76\x35\x97\xde\x9a\x92\xee\x3b\x83\xee\x37\x11\xb6\x16\x3e\x2c\x3a\xe6\xea\xbf\x59\xf6\x40\xec\x15\x55\x58\x5b\xef\x6d\xd4\xfb\x72\x68\xdd\xe6\xab\x0e\x90\xab\x68\xfb\x1d\x7c\x13\x4d\x7d\x72\xdc\xb1\x5f\x3d\x86\xd9\x37\x9a\x23\x78\x79\x13\xf4\x07\x8d\x44\x29\xc5\xc9\xd6\x40\x7c\x93\x41\x7e\xa5\x70\x1c\x37\x6c\x68\x56\xb4\x75\xc9\x35\xda\x89\xa0\x5f\xcf\x20\x09\x58\x24\x5d\x26\x89\x67\x83\xaf\xed\x3a\x3d\x66\xb6\x7a\xd0\x6e\x4f\xad\x4b\x23\x25\xb5\xde\x0c\xcf\xe7\x42\xce\xe7\x4d\xa5\x71\x65\x97\x11\xde\x58\x76\x29\xe2\xc9\x77\xbe\xf2\xa0\xdb\xa3\x6c\xff\xa4\x92\xa4\x07\x82\xb1\xfd\x16\x21\xe0\x04\x5c\xbd\x8e\x6d\xa5\x87\x91\x88\xa7\xc2\xde\x9c\xeb\x3a\x7d\xf7\x5c\xb0\xf0\xbe\xab\xc5\xb0\xa9\x58\x74\x9b\x4a\xdf\x7c\xbe\x71\x08\x0e\x92\x8b\xf1\x36\xbb\x69\xf4\x9b\xd1\x37\x89\xc3\x8d\x7f\x53\xd7\xc3\x6d\xf9\xda\xd0\x94\x40\x2f\xc8\xb3\xdb\xe0\x98\x81\xe8\x32\x78\xeb\xf8\xdd\x0b\x5a\x57\xa8\xe0\x88\xdd\x9c\xa0\xe8\x90\xe2\x0f\x09\xe3\x8f\x21\xb2\xce\x20\x33\x70\xfb\x2a\x77\xd6\xc1\x09\x56\x0e\x5e\x5c\xf9\x89\xd4\xb5\x13\xbe\x06\xd9\xf3\x46\xda\x3b\x3f\x4e\x9a\x98\x1e\x23\x74\x31\xd8\x70\xec\xc7\x84\xdd\xfd\xfb\x98\x01\x41\xd3\x0b\x81\xde\x89\xf7\x6d\xb7\x24\x43\x96\x57\xe8\x6f\x0f\x1c\x41\xd1\x8a\x73\x55\x23\xbe\xf2\xe3\x72\x38\x37\x66\x0e\x17\xb7\x2e\x41\x8e\x0f\x68\xd4\xf7\xd1\x88\x46\x52\x2a\x34\x2e\x0b\xed\xf7\x09\x22\xe2\xf2\xba\x8f\x46\x08\x81\x61\x0b\xab\x8b\xcb\x01\xff\x98\x5c\x5e\x2e\x4a\x79\x11\x63\x57\xb0\xf9\xf1\xe0\xae\x22\x1b\xe5\xdd\x09\xb0\xf1\xb8\xe0\x55\x6a\xe6\xe4\x63\x83\xcb\x41\x6b\xd1\xea\x4b\x1e\x23\xb2\x75\xcd\xdb\x07\xa5\x0d\xf8\xd0\x3c\x81\x85\x3c\x45\xfe\x7d\xa5\x4f\xb8\x1c\xbb\x74\x3b\x66\xbf\x9e\x63\x17\xa3\x98\x8c\x10\xba\x16\x91\x03\x84\xf0\x22\xb4\x3d\x41\x3e\x53\x1b\x57\xd7\x27\xef\x90\xa8\x7b\x6b\x04\x30\x59\x5e\x23\x94\xde\x71\xe6\xb7\x17\x5f\x06\x9a\x4c\xf9\xde\xac\xe5\xa0\x50\xee\x3f\x06\xe0\xff\x4f\x80\xd7\xb3\x36\x85\xdf\x29\x6b\xbd\xd7\xc7\xb2\xf6\x5a\x65\x6d\x86\x87\x36\x76\xda\x4c\x68\x12\x42\x5c\x94\xce\x26\x14\x03\xe0\x21\x8c\xc0\x96\x8e\x09\x01\x8e\x7b\x18\x58\x3e\xe0\xa4\x56\x35\xee\x6f\xfc\x2e\xec\x2f\x1b\x01\xe4\xc3\xb8\xb3\x86\x98\x44\x93\xc6\x1e\xc6\xc0\xc3\x84\x01\xb7\x65\xf8\x30\x8c\x9b\x55\xae\x99\xe6\xf5\xdd\xa7\xa3\x22\x02\xd8\x98\x66\x26\x4e\xfd\x32\xde\x44\xdd\x9e\x99\x04\x03\xfa\xff\x43\x24\x9d\x21\x56\xfd\xa2\x33\x54\x6f\x7a\x0f\xc6\xf6\x9d\x55\xc2\x43\xdc\x19\xe0\x1b\x5e\x4c\xaa\xa4\xeb\x51\x47\x40\xd0\xa5\xeb\xeb\x3d\xc2\xc8\xb8\xf8\x9f\xdd\xed\xfd\x01\x27\xdb\x3f\xf8\x04\xe3\xa7\x97\xfe\x7e\xe8\x9d\x6d\x55\x4b\x08\xde\x59\xf2\x7b\x84\xfe\xb3\x72\xe4\x26\x7f\xc7\xbb\xda\xf0\xee\xc0\xc3\x8b\xe8\xdf\x01\x00\x00\xff\xff\x76\x13\xf5\x69\x44\x22\x00\x00") + +func fontsGothicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsGothicFlf, + "fonts/gothic.flf", + ) +} + +func fontsGothicFlf() (*asset, error) { + bytes, err := fontsGothicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/gothic.flf", size: 8772, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsGraffitiFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xc9\x8a\x1c\x47\x13\xbe\xd7\x53\x7c\x87\x06\x75\x1f\xa6\x02\xe9\x97\x7e\x90\x69\x9a\x3a\x18\x9f\x2c\xf0\x41\x17\x41\xe2\x70\x5b\xd3\x3d\x6a\x98\xc5\x9e\xe5\x60\x93\xe8\xd9\x4d\x6c\x99\x59\x4b\xcf\x48\x20\x7b\xd4\x15\x55\x95\xb1\x64\x2c\x5f\x44\xd6\xf1\xfa\xf8\x66\xbf\xc2\xff\xf1\x0e\xff\x7b\x83\xd7\xef\xf0\xb6\xfb\xe5\xee\xf6\x11\xb7\xfb\x9b\x03\x4e\x0f\xb8\xba\xdf\x1f\x8f\xa7\xc7\x53\x7f\xbc\x3e\x76\x1f\xbf\x9c\x1e\x70\x3c\x5d\x5d\x1f\x1e\x71\x94\x55\x97\x87\x87\xd3\xd5\xed\xe1\x12\x7f\xfe\x83\x5f\x0f\xa7\xab\x2f\xf8\xed\xe9\xfe\xf2\x74\xc0\xfa\x2f\xbd\x0e\xff\x1e\x9e\x1e\xfa\xa7\x87\xbf\xfb\xc3\xe5\x53\xbf\x7f\xda\x74\xaf\x8e\xa7\xab\x0b\xe1\x3d\x5c\xbe\x9a\x71\xed\x6f\x2f\xf1\xf1\x74\x83\x0f\xfb\xab\xab\xd3\x1d\xd6\x8f\xa7\x9b\xe1\xf3\xf5\xfe\xfe\x70\x73\x77\xfb\xd8\x7f\xbe\xbb\xd9\x74\x3f\xef\x1f\x0f\x3f\xe1\x1d\x3e\xec\xef\xf1\xfa\xfd\xfb\xb7\xdd\x6a\x98\xfc\x0d\x5d\xcf\xfd\xd0\x65\x64\xff\x41\x92\x1f\x66\xa1\x68\x18\x3a\x4a\x94\x86\x6e\x43\x1b\x1a\x3a\x00\x58\xf8\xd5\x0b\xeb\x1f\x86\x8e\x39\x23\x67\x64\x11\x91\xe4\x85\x3c\x16\xe6\x0c\x79\x8e\x8c\xa1\x23\x06\xbe\x7e\x05\x38\x09\x6f\xe6\x9c\x39\xbb\x20\x66\x66\x4a\xaa\x9f\x84\x11\xc4\xc2\x9c\x98\x09\x84\x04\x7d\x4e\xfa\x2e\x89\x20\x59\xc0\xa6\x00\x49\x9f\x92\x0a\x52\xad\xb2\x5c\x98\x64\xfd\xd0\x25\x26\x59\xad\x66\x13\x88\x44\x80\xbe\x4a\xa6\x42\xb8\x1b\x2b\x6c\x83\x24\xfb\x4a\x4a\xee\x84\xdc\x8a\x3b\x08\xd8\x72\x12\x07\x75\x49\x96\x0a\x6d\xce\x50\x03\xd4\x6d\xe2\x34\x79\x36\xfa\x37\x74\x2b\x75\x09\xaf\x94\x22\x80\x94\x12\x02\x42\xad\x81\x35\x94\x12\xa5\xc9\x28\xd9\x7d\x92\x58\xad\xcc\x2c\x79\xa8\x6f\x67\x0b\x37\xc0\x66\x2c\x90\xc4\x71\x58\xb9\x66\xfb\xcf\x56\xa4\x9c\xc8\x45\xf0\x46\x1e\xaf\xcd\xac\xc4\xba\x88\xa9\x88\x6c\x0c\x51\xae\x89\x38\x7f\x87\x5e\x8d\xb3\x3b\xc9\x02\xc9\x01\x76\x1b\x54\x62\x88\x94\x17\xb9\xf2\x15\x29\x7a\x3b\xff\x11\x5f\xae\x36\xd4\xe8\x5c\x4d\x48\x8d\x41\xa8\xe2\xaa\x67\xb6\xf6\x39\x0d\xa9\x68\xa0\xe4\x4c\xe4\xe1\xd1\x2c\x71\xbf\x92\x89\xb4\x14\x54\x7f\x51\xc8\x36\x33\x2c\x71\x92\xd5\x84\x66\x8e\x04\x83\x35\x4a\xfa\x3c\xb1\x67\x2f\x92\xaf\xa7\x26\x79\x2c\x7b\xe5\xb1\xd5\x89\x16\x65\x9e\x5e\x99\x39\x07\x53\xd5\xcc\xaa\xd9\xa9\x14\xe9\x2b\x0e\x31\x2b\x4c\x45\x59\xc3\xdc\xa4\xad\xe5\xed\x59\x41\xe0\xb5\xd0\x5b\x17\x6a\x1c\x62\xe1\xb9\x2d\x98\x62\x86\x97\x1b\xbc\xf4\x95\x59\x73\xc3\x2d\xfa\xdd\xe0\x21\xb9\xe7\xb2\xa3\x8a\xe5\x88\x08\xea\xc3\x26\xdf\xbf\xee\xc7\x7d\xd0\x6c\xf3\x1b\x2c\x6a\x04\xb9\x5f\x44\x10\x39\x48\x79\x74\x32\x6b\xa8\x9e\x89\x0e\x17\x27\x15\x47\x22\x1c\xa9\x86\x18\x83\x91\xb6\x7d\x8b\x01\xaa\xb3\xd1\x5a\x54\x80\x26\xb6\xb3\xb3\x25\x5b\x8f\xda\xc5\x85\x6d\x2d\x9d\xdd\x5a\x63\x51\x6c\xa7\x30\x7c\x8f\x45\x2b\x4f\xee\x64\x89\x3d\xa5\x4b\x09\x2d\x2f\xda\x8c\x17\x39\xca\x79\x11\x45\x09\xa5\x00\x93\xc4\x51\x66\x23\x3c\x39\x5f\xd0\x2f\xd7\xb6\x6c\x76\xac\x03\x69\x64\x03\x13\x5a\x9d\xf3\x48\x22\x22\x69\x6e\x54\xbf\x65\xcb\x58\x58\xaf\x32\xe8\x12\x7a\xcb\xcc\xbb\xda\x00\xdb\x6c\xd7\xd2\x8a\x5e\xd5\x5b\x7b\xd8\xc2\x33\x8a\x4a\x6e\xa5\x85\x94\x40\xc5\x10\x58\xf7\xf1\xf6\xd3\xa2\x88\x46\x32\xa3\x89\x72\x1e\xe7\xc5\x34\x55\x47\xb9\xaa\x5b\xcc\x2e\x82\xa9\xb9\xb1\x37\xf3\x34\x9b\x65\xbe\x8a\x33\x63\xab\x41\xc9\xd6\x29\xf6\xf9\x66\xcb\x56\x9f\x13\x07\x34\xd6\xd9\x66\xc3\xa0\x54\x6e\xfe\x18\x95\xf7\xf3\x9b\xe5\x6a\x1d\xd7\xfd\x31\x6f\xb8\x88\xc3\x8f\x10\x57\x4d\x15\xb3\xe1\x9b\xb5\xe4\x71\x71\xd6\x1d\x46\xf0\x83\x16\x7f\xdc\x77\xc9\x5c\xe9\xbe\x4b\x63\x08\x5a\xb2\xce\xd6\x37\xe0\x61\xe1\x8b\x50\x7c\x8d\xdc\x90\xeb\xa7\x80\x80\xa4\x89\x12\x18\x50\xec\xd3\x29\x50\xb5\x7b\x7f\x99\x5c\x9a\x66\x33\xf8\x55\xac\xea\x8d\xb6\x50\x8d\x69\x99\xe0\x82\x8e\x5e\x53\x1b\x56\x08\xb2\xad\xb1\x0d\xa0\xb2\x98\xc0\xae\x56\xd1\x0f\xf1\xdc\x36\x96\x23\xcf\xa7\x4d\xab\x0f\x98\x6b\x18\x96\x69\xdf\x65\x04\x62\x2a\x68\x5e\x7d\x68\xaa\x2f\xd9\x8f\x7b\xf8\xd3\xcb\xd5\x87\x36\xbf\x91\x30\x16\x37\x0e\xd8\x77\x14\x33\xc6\xcd\xf9\x65\x71\x2f\xe5\xf7\x32\x36\xa0\x4d\x76\xf7\xa2\x61\x43\xdc\x8c\xa2\xf9\xbc\x75\x84\x06\xb9\x12\x53\xdf\x58\x97\x7c\x00\x47\xc0\xc6\xee\x5b\xac\x3b\x8b\x5c\xf9\x6c\xb9\x44\x31\x3b\xb8\x8f\xa0\x78\x32\x48\x7c\x1f\x36\x70\xe3\xae\x6a\xd1\xfc\x86\x9b\xee\x31\xaf\x84\x5a\x82\xb1\xa1\x42\x53\xa5\xa9\x26\xf0\xbc\x7f\xbb\x97\xdc\x2e\x78\xce\x5a\xed\x7b\xce\x5a\xed\x5b\x32\x86\x80\x64\xc2\x96\xec\x72\x57\xfb\x64\x91\x9c\xcb\x91\x25\x51\x6a\xc5\xbb\x4c\x95\x2f\xa7\xb8\xaa\x00\x81\x84\xc5\xc6\x6a\x21\xb5\x02\xa8\x06\x41\xb3\x85\x4d\x4e\x29\x54\xc9\x14\x77\x7f\x6f\x10\xa4\xde\x8f\xb9\x38\xea\x20\x47\x5c\xcb\xf3\x0a\x41\x89\xe6\x49\xeb\x61\x6c\x86\x25\x9a\x9a\x43\x8c\x26\x25\xa6\xc8\xb1\x32\x0c\x92\xe1\x42\x67\xd4\xec\x54\x06\xe6\x94\xaf\x53\x83\x56\x7a\x58\x84\x9f\x19\xa2\x8b\x78\xe1\x28\x61\x11\x0a\x8d\x7e\x4a\x51\x07\x98\x14\xd9\xa2\x0d\x35\x79\x4e\x71\x50\x55\x9b\x1c\xfd\xfc\x08\x03\x1f\xe1\x12\xd5\xa9\x68\x7a\x2d\x1b\x7d\x9e\x08\x2f\xfa\x90\xe6\x47\xe0\xb4\x5e\x38\x02\x97\x04\xeb\x46\x80\x51\xd1\x42\xfc\xcb\x43\xb7\x1e\x17\x5f\xa9\xbc\xde\xbd\xc5\xc8\xde\xfe\x32\x62\xde\xca\xda\x3b\x03\x0b\xa6\xcc\x68\x0c\x67\xef\x9d\xac\xb9\x51\x8e\x66\xd6\x9e\xad\x8d\xef\x66\xcc\xbd\xe1\x87\x1e\x6f\xb5\xda\xd5\x58\xfd\xa4\x01\x19\x2e\x73\x80\x55\x3d\xc7\xbc\xa0\x39\x8e\x1d\x3e\x0b\x9c\xd1\x1c\x40\x68\xc6\x72\x8a\x4f\x2b\x31\x1e\xe5\x82\xce\x63\x78\x69\x34\xa3\xb4\xb7\x66\x48\x8d\x19\x55\xaa\x7f\xd7\x8c\x2f\x25\x8e\x31\x1c\xb8\x04\x3b\xd4\x07\xe5\x6d\xd9\x80\x25\xf9\xa0\x30\xf5\x79\x1f\x2d\xd7\x3a\x7b\xfd\x2d\x03\x41\x9d\x29\xdc\xf2\xfa\x2a\xb7\x93\x45\x9d\x2b\xea\x54\x91\x2b\x4a\xb9\x4d\x12\xa0\xac\xb3\x44\x80\xe6\xd6\xf5\xd7\xaa\x8d\xa9\xa1\x72\x4d\xae\x2a\x24\x1a\xc4\xa2\x27\x99\xdb\xd9\xab\x78\xe2\x53\x75\x45\x6e\x7d\xf1\x4c\x1a\x80\x1a\x7e\x75\xea\x19\x4f\x9e\x63\xb6\x1c\x5a\xcb\x81\x64\x87\x4d\x20\x1f\x2d\xa7\x41\x60\x5e\xe9\xd2\xa1\x39\xf3\x4e\x52\xc0\x4e\xd8\xde\x64\xf2\x8c\x19\x68\x9a\xa8\x3b\x68\x8b\xad\x07\x05\xa9\x20\x6e\x84\x71\xae\x99\xfd\xec\xe0\x28\xaa\x6e\x4f\xf4\x42\xf6\x4e\x34\xa3\xe9\xdd\xa5\x51\x2c\xd6\x0d\xbc\xd2\x04\x75\x4b\xd5\x94\xa2\x29\x5a\x2b\x94\x8d\x41\x0d\xd1\x93\x73\x34\x64\x0b\x4b\x9e\xb8\xb8\x65\xf3\xfe\x66\x80\x42\xa5\xb9\x45\x63\xa4\x45\x6d\xc6\x68\xdf\x51\x95\x35\x51\xcb\x5c\xd8\x29\x4d\xda\xfe\xd4\xc3\xb5\xb5\x46\x67\xdd\x45\x11\x90\x7e\x5a\x6d\x9a\x29\x8d\x3d\x6c\x4d\xb5\xd7\xa3\x2a\x6a\x44\xb9\xed\xa1\x79\xf2\xa5\x74\x12\x5b\xef\xa3\xde\x45\xcb\x07\x07\x9a\x74\xcd\xda\xc5\x96\x3e\x0d\x6c\xb1\xc5\xe8\x39\x27\x5e\x59\x93\xb5\x9e\x17\x2d\xcd\x2e\x17\x79\xfa\xd0\xbf\x94\x2e\x7d\x02\xc0\x0e\xbb\xf6\x39\x13\xd3\x2a\x8c\x01\xe2\xe3\x9e\x74\xa0\xf8\xc0\x61\xe3\x51\xfb\xb1\xf2\x3c\x3d\x74\xcd\xff\x3f\xfa\xe6\xbf\x00\x00\x00\xff\xff\xd7\x26\x94\xd0\x7f\x18\x00\x00") + +func fontsGraffitiFlfBytes() ([]byte, error) { + return bindataRead( + _fontsGraffitiFlf, + "fonts/graffiti.flf", + ) +} + +func fontsGraffitiFlf() (*asset, error) { + bytes, err := fontsGraffitiFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/graffiti.flf", size: 6271, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsHollywoodFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5b\x4b\x6f\xe3\xc8\x11\xbe\xeb\x57\xd4\xa1\x01\x4a\x00\xa9\x9e\xdd\x24\x58\x24\x03\x03\x02\x92\x53\x80\xc4\xa7\x9c\xc2\xa0\xe5\x4c\x34\x19\x2f\x66\xed\x8d\x1f\x59\x0c\xc2\xf0\xb7\x2f\xba\xfa\x51\x8f\x6e\x4a\xa4\x46\xf6\xd8\x80\x25\x56\x89\x62\x7d\xf5\x2e\x36\x5b\x1f\x3f\x7f\xfc\xfe\xc6\xc0\x77\xef\xe0\x07\xf8\xfe\x37\xf0\x0e\x7e\x58\x7d\xba\xff\xfc\xf9\xcb\x2f\xf7\xf7\xff\xda\x7e\xfc\xfc\x11\xfe\xf9\x05\xfe\xfc\x7c\x73\x07\x7f\xbc\x79\x80\xf5\x8f\x1f\x76\x3f\x3e\xff\xfb\xf9\xf0\x74\xd8\xfe\xe7\xf9\xf6\xa7\xed\xf3\x87\x9f\xb6\x87\xc7\xcd\xea\xbf\x87\x87\xc7\xdb\xfb\x3b\xf8\x6e\xfb\x0e\xba\x0e\x7e\x67\xff\x72\xf3\x60\x7f\xff\xdb\xd5\xea\x6f\x8f\x87\x47\x78\xfc\xf9\xe6\xee\xf6\xf1\x13\x7c\xf8\x74\xf3\x70\xf3\xe1\xe9\xf0\x00\x8f\x87\x27\xf8\xe5\xf6\xe9\x13\x74\x7f\x82\xfb\x9f\x9f\x6e\xef\xef\xfe\xb0\x82\x73\xfe\x1c\x1d\xad\xfe\x0e\x57\x70\xd3\x00\x40\x0f\x57\x70\xf0\x07\xf0\x0f\xb8\x82\x5b\x3c\xfa\x1f\x5c\xc1\x3d\x1e\x0d\x70\x05\xcf\x78\xf4\x7f\xb8\x82\x3b\xfc\xf2\x08\x57\xf0\xd7\x95\x80\x60\x76\xd3\xa4\xe1\xa4\x01\x03\x90\x48\x24\x12\x19\x89\x40\x66\xc2\x93\x8c\x08\x24\x4c\x93\x02\x87\xe1\x38\x0c\xd8\x26\x93\x9e\xc8\xb0\x02\x11\x71\x24\x02\x49\x22\x50\xd2\x35\xcc\x87\x05\x25\x2c\x13\x2d\x63\x6c\x03\x08\xc6\x78\xc3\x22\x0e\x13\x70\x84\xcb\x44\xe9\xc6\xe8\x4b\x9f\x38\x52\x3e\x50\x7e\x88\xa7\x19\x69\x03\x00\x32\x8b\xe9\x6c\xd3\x75\x9d\x7f\x35\x64\x0b\x3c\x23\x9a\x87\x9f\x11\x85\xf3\x33\x24\x1e\xa3\x6d\x53\x98\xeb\x98\xeb\x7c\xac\x5a\x0e\xdf\x36\xb0\xb7\x0d\x83\x1f\xac\xe8\x36\xe4\xc6\xb5\x73\xd6\x01\x73\x65\x40\x06\x1b\x48\xee\x8c\x0c\xdb\x24\xf8\xf8\x15\xd7\x46\x46\x00\x16\x54\x3a\x1f\xbe\x61\xf1\x9d\x62\x3b\x72\x0d\x5c\x47\xd7\x27\xab\xe1\x21\x4a\x34\xd1\x9a\xd7\x46\x08\x60\x81\xc6\x82\x6c\x77\x24\xc3\x04\x02\xd8\x76\xe3\x86\x50\xbc\x77\xdb\x31\x20\x71\xae\xeb\xc6\x21\xca\x6d\x47\x3c\x7d\x70\x0e\xc9\xfd\x16\x3f\xdd\x6f\x4d\xe1\x50\x65\x0d\x65\x09\x84\x65\x4c\xb0\x22\x06\xb8\x09\x81\x1c\xce\x3b\xf1\xaa\x22\xc0\x68\xf7\x4b\xdf\x53\xfe\x06\x2a\x79\x3d\x51\xc1\xe5\x44\x45\x7f\xb7\xca\xb3\xd2\xad\xc7\x8a\xcb\x71\x80\xd0\xc0\x86\xe5\x16\x06\x59\x8e\xcc\x18\x72\x39\x2c\x73\x00\x72\x2a\x00\xa4\x58\xfc\x2a\x80\xf5\x20\x6c\xd1\x3f\xbd\x97\xe9\x76\x2b\xe3\x9c\xeb\xad\x1b\xf1\xb0\xb3\x4d\x4f\x41\x08\xbd\x01\x2a\x4b\x1c\x08\xc3\x30\x37\xe6\x63\x91\xf1\xe2\xc0\x3a\xe7\xca\x98\x87\xf9\x31\x6f\x8e\xbd\xc6\xd0\xf3\xaf\x8d\x99\x08\x2e\x82\x4a\x48\x09\xa8\x09\x38\x5d\x82\x99\x78\x30\xab\x40\x7b\x87\xd6\xff\xcd\xb5\xff\x82\x3f\x15\xff\x8f\xf5\x4b\xd6\xa7\x30\x7e\x09\x30\xeb\x53\x89\x88\xfd\x52\x14\x60\x22\xbe\xae\x7d\x3a\xd5\x41\x7c\x0e\xf6\xaa\x02\x03\xe4\xb0\x4f\x74\xea\x28\x8c\xa6\xbe\x07\xac\x9f\xf8\xea\xeb\xb0\xfa\xca\xda\xa2\xcb\x4b\xa5\x1a\x9b\x09\xd0\x2c\x29\x8d\x2f\x61\xd4\xdc\x46\xa0\x9e\x6f\x44\x53\x63\xfd\x2b\x45\xe6\x65\x6d\xc9\x0d\x69\x5c\x37\x92\x15\xcd\x1a\xc8\x84\xf1\xeb\xce\x8e\x29\xe0\xfc\x71\x8e\xbf\x70\xec\x4f\xf3\xb0\xc6\x60\x39\x53\x1a\x49\x59\x48\xd5\x90\x85\x2e\x8e\x90\x36\x54\xc9\x42\x6b\x60\x86\xf4\x7f\xef\x03\x2c\x92\x13\x8a\x18\x77\xb1\x51\x46\xd2\x03\x8c\x51\x86\x34\x35\x5b\x7a\xa6\xcb\xa2\xb3\x83\xd1\xd5\xb9\x9f\x76\x68\x1b\xeb\x5c\x2e\x61\xd1\x89\xd2\xbb\xd2\xb9\xd2\xb7\xd2\x97\x8a\x3a\x2b\x49\xf6\x7c\x4a\x71\x8e\xca\x56\xfa\xe2\x86\xa2\xf1\x25\x2d\xb8\x08\x34\x65\xb6\x93\xa0\x53\x26\x27\xd0\x94\xd9\x2f\x05\x9a\x8a\x72\xbe\x50\xc8\x1d\x67\x59\x97\x8d\x29\xc3\x4c\xdb\x63\xda\x30\xdb\x3a\x3b\xf6\x7c\x96\x89\x69\xc5\x32\x7e\x94\xc0\x66\xce\x7f\xb2\x36\x5c\xc0\xe6\x2e\xd9\x50\xda\x7c\x03\xaf\x62\x73\x82\x4b\x40\x19\xc4\x28\x2c\xb4\xda\x0c\x23\x1c\x67\x40\xc0\xa1\x68\x10\xc5\x71\x12\x7c\xfc\xdd\xf7\xd1\xd4\xb2\xcd\x75\xec\x23\xa2\x7b\xe4\xf7\x33\x2e\x08\x36\x94\xd7\xc6\x1c\xb9\x20\x6b\xc8\xe9\x52\xd1\x52\x2e\x54\x23\x8c\x38\x3f\x46\xf7\xb1\x5a\xe3\x38\x45\x56\xc8\x6a\xd3\x01\x0f\x0c\xd6\x38\xf8\x20\xcf\xe6\xaa\x38\xaf\x74\xe1\x8f\x26\x96\x3c\xa9\xb0\x81\x8a\x89\x24\xa9\x46\x5b\x7d\x5a\xa7\x3e\x67\x53\x1f\xa7\x24\xd4\xd2\xb4\x49\x4b\x12\x66\xaa\x3a\x19\xa0\x50\x62\xcd\xaf\x6c\x7d\x3e\x74\x23\x41\xf3\x3d\x1f\x0f\xaf\xa5\x3a\x7c\x48\x28\xb2\xb5\x30\xeb\x79\xf3\x0c\x2e\x99\xb0\x79\xc6\x36\xb0\x11\xf3\xcc\xbe\xeb\xf6\x9d\x9a\x67\x00\x2e\x36\xcf\x40\x1a\xda\xe9\xcf\x36\xfc\xbe\xd8\x83\xb1\xb4\xde\xd0\xe2\xed\x2d\x2d\x40\xd8\x7d\xd7\xb5\x16\x12\x23\xde\xad\x07\xc1\xeb\x36\x2a\xbc\x46\xc8\x5a\xec\x1c\x86\xe6\xb8\xe2\x2c\xb4\x31\x28\xc0\xc0\xac\x1c\x38\xeb\x50\xb9\x32\xec\x54\xeb\x14\xf2\xf4\x1e\xc1\xc7\x6f\x4d\xa0\x5b\xc2\x13\x4c\xa5\x85\x52\x01\xe5\x6d\xf3\x48\x94\xc4\xc7\xaf\x10\x89\x0c\x4e\x22\xec\x3c\xf1\xd6\xb1\xbc\xa6\xcd\xe3\xbb\xb2\x39\xbe\xbf\x71\x9b\x23\x08\xba\xb0\xaf\x2a\x7e\xc4\x82\xa3\x36\x9f\xc4\xf2\x92\x36\x67\x98\xa1\x55\xa1\x12\xd3\xb3\x6b\x39\xaf\x00\xdf\x4a\xce\x2b\xdb\x9c\x62\xa6\x16\xe7\x2e\x33\xc2\xa7\x4d\xc8\xd8\x17\x88\x73\x57\x39\x2d\x49\xdb\x94\x91\x6e\x1b\xd0\x66\xc7\x57\x69\xf7\x88\x4e\x94\xc6\x26\x0b\x52\xe5\xb1\x0a\x72\x21\x53\xab\xe4\x94\x3e\x62\x91\x8b\x25\x9e\xa4\x99\x1a\x2a\xa0\x64\xf1\x59\xb7\x96\xa0\x57\x31\xcd\xe2\x48\xd0\x71\xd0\xe0\xcc\x75\x1b\xc1\x14\x5f\xa6\x52\x52\x53\xc9\x95\x5a\x79\x03\x68\xc5\x54\x28\xd5\x51\x7e\x9d\x1f\xf4\x99\x21\xb2\x9c\xee\xb3\x78\xab\xc0\xbd\x91\x6e\xc9\xb3\x3f\xfa\xc8\x10\x1e\xe9\x19\x9a\x1c\x54\xbd\x6b\xa7\x11\x9e\x97\xce\xa0\x03\x0a\xc0\x8e\xac\xfe\xc0\xd8\xd9\xa6\x1b\x67\x07\x94\x1d\xfb\x56\x64\xb9\x07\xbf\xef\xbd\x37\x36\x13\x90\xce\x08\xa8\xda\x89\x29\xb3\x9d\x4c\x6d\x8b\x77\x6b\x3c\xb7\xfd\x30\xe4\x9d\x20\x93\xbb\x01\x3b\x66\x5d\x44\x66\xd4\xd2\xfb\x54\x7e\x2f\xe3\xce\x0b\x2d\x28\x14\x03\xad\x96\xae\x58\x7e\xcc\x2b\x54\xb2\x15\x85\x8e\xab\xf3\x8a\x9d\x22\x16\x04\x35\x57\x14\x43\xc5\x1b\x9a\x88\xea\x53\x28\x93\xfa\xe6\xbb\x33\xb7\xb9\x53\x36\x6f\x60\xa3\x6c\x1e\x43\xe5\xcd\xd9\xfc\x3d\x97\x2a\x1b\x73\xad\x2f\x7f\xcb\x29\xd4\x15\x17\xde\x14\xd7\xb8\x74\x9c\x3b\x5d\x34\xd7\xbe\xb6\xbb\xa2\xdd\xda\x7d\xe7\x5c\x65\xe6\xff\x46\xe3\x83\x2b\x4f\x4b\x85\x9e\x07\x05\x2b\x10\x45\x70\x83\xba\xcb\xa2\x82\xa8\x38\xf5\xc1\xe1\x02\x81\xa2\x94\x28\x14\xb0\x51\xd7\x78\x4f\x6e\x21\xaf\xe2\x7b\xda\xd2\x32\x3e\x82\x76\x34\x2f\xc0\x6e\xc5\x88\x0a\x88\x93\xb4\x06\x38\x81\x73\x02\x2e\x04\x52\xa0\x26\xf4\x1c\x3c\x53\x82\xe9\xc0\x75\x21\x55\x84\x4a\xf5\x96\xb9\x94\x9d\xf9\x65\x3c\x35\x30\x80\x50\x0f\x70\x0b\x4b\x54\x82\x5d\x70\x88\x60\xe9\x5a\x76\x10\xd7\x0a\x9f\x0f\x89\xb5\x6e\x93\x22\x53\x25\x73\x36\x4b\x79\x29\x7a\xa7\x57\xb0\x7b\x35\x11\xf4\x7a\x18\x80\x32\x6b\x55\xca\x2a\xe1\x27\x48\x96\xa6\x72\xc0\x0f\xd3\xbd\x98\x57\x84\x31\x85\x25\x29\x06\x76\xab\x40\xd0\x8d\x5b\x48\xc7\x38\x3a\x9e\x1b\xdd\xe9\xcf\xc8\x87\x01\xb4\x7a\xc7\x57\x4f\xf3\x46\x8e\xc4\x33\x6c\x6b\x47\xe0\x71\x4e\xe0\x49\x0e\xe0\x13\x01\x14\x56\x3e\xf9\x2b\x1f\xff\xe9\x27\x00\xea\x79\x3d\x29\x62\x76\x2b\x33\xb0\x57\x18\xd8\x2b\x0c\xec\x55\x6e\xa0\x10\x56\x88\xcb\xbe\x95\x5d\x3e\x72\xaf\x53\x62\x01\xdf\x90\x00\xfc\x19\xa8\x66\x21\x53\xb3\x10\x44\x10\xa9\x9f\x8a\x4a\x49\x8c\x59\x79\x42\x3a\xf1\x94\xc4\x38\x3b\xc4\x9d\x29\x3e\x6e\xd0\x12\x29\x9a\x06\xbe\x92\xba\x78\x89\xfb\xc4\x03\x87\x72\xe9\xbb\x38\x30\xb4\x41\x20\x8b\x37\xbb\x15\xad\xbf\x73\x64\x06\x2f\x8d\xf8\x3d\xee\xbd\x78\xee\xaf\xff\xb9\x3f\x4f\x1c\x53\x5a\x86\x08\xdd\xe4\xae\x87\x85\x62\x1d\x27\x3a\x77\xea\x3a\x52\x79\xfd\x09\x0b\x1c\x36\x4e\xd8\xc6\xcf\x1c\x5c\x38\x70\xe9\x42\x3c\x4c\x5d\x5a\x13\x32\xa3\x67\x50\x71\xdc\xe2\x30\xbc\xf5\x41\x74\xf8\x00\x64\xf6\x35\xeb\x60\x2a\x67\xd4\x56\x38\x98\x85\xf8\xac\xc1\x00\xca\xb5\x8d\xca\xca\x46\xb4\xd9\x84\xc4\x85\x5d\xa5\xfc\x7c\x6e\x1c\xa5\x55\xdd\x5c\xa6\xcf\x8a\xa3\xd9\x90\x6d\xb3\x91\x2c\x7c\xb4\xc2\x58\xb8\xd1\x50\x8c\xb3\xac\xcd\x45\xc6\xda\xc9\xf9\x5b\xdc\x8a\xe1\xc0\xd2\x28\x10\xfa\x66\xad\x06\x7f\x31\x47\xdb\x8a\xac\xca\x69\xd6\xcc\xab\x99\xca\x26\x59\xad\xee\x5a\x4f\xb1\xd3\x81\xcc\x6d\xc8\xef\x06\x58\xfe\xf2\x04\x16\x19\x1c\x8f\xcb\x14\x9e\x97\x38\x13\xef\xd7\x29\xd2\x52\x06\xa0\x3e\xd3\xe7\x57\x5c\xb2\x9c\x71\x5d\x04\x97\x34\x92\xf8\x8a\x95\x78\x54\x9c\xc9\xda\x22\x6f\xf7\x4f\x44\x8f\x3f\x97\xaf\x21\xaa\x15\xc4\x56\xaf\x1f\xea\xd5\x43\xbd\x76\x98\x56\x0e\x27\xcd\xb0\xf4\x86\x6c\x5e\xe5\x07\x59\xd1\x00\x44\xc5\x4d\xee\x2c\xa5\xcd\xae\xfc\x13\x40\x8f\xb0\x5a\xe7\x54\x95\x4a\x41\x0d\x29\xf5\x78\xb5\x45\xff\x0b\x86\x6e\x93\xcb\x40\xcc\x55\x93\x81\x95\x30\x05\x40\x91\x79\xdf\xa8\x77\x52\x66\x3a\xf9\x54\x64\x96\x84\x8a\x8d\xaa\x86\x9b\xc5\xe4\x40\xe3\x1f\xc7\x2b\x58\xf2\xa6\xa8\x44\x5f\x34\x80\x82\x55\xed\x0a\x8b\x5d\x0c\x27\x5d\x5c\x14\x7d\xc2\xe9\x5b\x5d\x05\x8a\xb6\xea\x3c\x52\x58\x6f\xc3\xed\x26\x0a\x59\xd1\x2a\xe7\x93\x17\x8b\x3c\x68\xf2\xb3\xcf\xcb\x4c\x6d\xb5\x5a\x86\xbf\x55\xe8\x5e\xab\x96\xcd\x3e\x8e\x91\x71\xa1\x09\x7e\xe2\x68\x8b\x07\xed\x6e\x15\xd6\x31\x70\x6d\x67\x48\xc5\xdd\x0d\xba\xd3\x57\x8f\x16\x79\xdb\x0b\xdc\x42\xcb\x84\x0e\x96\x0b\xe6\xc2\x1b\x28\x00\x9c\x94\x70\x52\xe3\xa0\x72\xd8\x2f\xd3\xe7\xd5\x2c\xe8\x83\x50\x7f\xd7\xda\xbb\x65\x1a\x97\x28\xce\xe0\x90\xb7\x05\xfd\x32\x13\xe1\xb1\x43\x2a\x53\x38\x9a\x84\x24\x71\xb1\x8a\x3a\x3f\x24\xb6\x27\xae\xa0\xc5\xb1\x0d\xb9\x90\xf7\x55\xc7\x67\xd8\x66\xeb\xc2\xb5\xd3\x5d\xf4\x90\x4e\x42\xfa\xd5\x7e\xa8\x01\x46\x3c\xc8\x35\xfc\x57\x44\x71\xe7\x7c\x56\x20\xef\x14\xe6\x54\xa0\xd5\x6e\x61\xbe\x04\x52\xec\xfe\x2c\x00\x5d\xf0\x97\x24\x30\xf0\x35\x9b\xb6\xeb\xf6\x62\x1f\x7b\x5e\x0c\x09\xc3\xaa\xdc\x78\x36\xdf\xa2\xa8\x71\xdc\xf1\xeb\x75\x1d\xf0\x49\x42\x5a\x79\x99\xfd\x83\x88\x05\xbf\x58\x3b\x59\xcb\x43\x23\xe1\x7d\x04\x8e\x2d\x42\x54\x56\xa3\x2a\xc4\x45\x20\xe4\x7c\xe4\xb7\xcf\xe7\x40\xa8\x1d\x66\xe1\xad\xec\x1e\xac\x75\xb1\xc6\xc5\x7f\x2f\x53\x3f\x9c\x59\x70\xa9\x3c\x9d\x31\x3a\x4e\xe7\xc2\xb1\xbd\xf4\x27\xcd\xcf\x3e\x89\xc2\x2f\x1d\x01\x13\xf6\x68\xbb\xce\xb9\xb4\x0f\xb3\x65\x51\x30\xf3\x6e\xfa\x3c\x7b\xb8\x6e\x1c\xbb\x4e\x28\xff\xba\xdb\x07\x8a\xc5\xeb\xf9\xbc\xdd\xea\xd7\x00\x00\x00\xff\xff\x0b\x5d\x3b\xd8\x2d\x3d\x00\x00") + +func fontsHollywoodFlfBytes() ([]byte, error) { + return bindataRead( + _fontsHollywoodFlf, + "fonts/hollywood.flf", + ) +} + +func fontsHollywoodFlf() (*asset, error) { + bytes, err := fontsHollywoodFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/hollywood.flf", size: 15661, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsInvitaFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xdd\x6e\x23\x37\x0f\xbd\xf7\x53\xf0\x82\x80\x35\x80\xc7\xcc\x06\x8b\xe0\xfb\x80\xa2\xf0\x6d\xdf\x61\x00\xd6\xdd\x24\x4d\xb0\x69\xbc\x48\xbc\xed\xcd\x3c\x7c\x21\xfe\x48\xd4\xfc\xd8\x69\xbb\x8b\xcd\x8c\x66\x4c\x1d\x1e\x91\x47\x94\x34\x8f\x2f\x8f\xb7\x47\x84\x3b\xf8\x0c\xb7\x37\x70\x03\xb7\x9b\xe7\xd7\x3f\x9f\xcf\xc7\xfd\xe3\xcb\x23\xdc\xdc\xd1\xff\x3f\xc3\xb7\xaf\x77\xff\xfb\xf4\xe9\xfd\x70\xfc\x72\xbc\xdf\xdf\xbf\x1d\xbf\x3e\xec\x1f\xee\xbf\x6f\x8e\x2f\xc7\xf7\x1d\x9c\x9f\x1e\xe0\xcb\xe9\x8f\x6f\xdf\xcf\x0f\x6f\xf0\x74\x7c\x87\xdf\x1e\xce\xda\x7c\xbd\xff\xeb\xed\xf9\xfc\xfc\xfa\x3b\x9c\x9f\x8e\xaf\xf0\x0b\xdc\x9f\x60\x03\xf2\xef\x20\x77\x44\xb9\x23\xca\x33\xa2\xbc\xcf\x37\x38\x6c\xe4\x06\x07\x35\x24\xb5\x44\x52\x13\x20\xc5\xc0\x13\x56\xb0\xa6\x21\xad\xc3\x86\x08\xad\x65\x1d\xed\x52\x0c\xf3\x73\x4f\x7d\x4f\x3d\x1e\x36\xd6\x80\xe6\xd7\x79\x4b\x9b\xcc\xc4\xf6\x3a\x65\x3e\x9d\x7a\x82\x01\x40\x7c\xa5\x6c\xd0\x21\x04\xc2\x0d\x4c\x64\x91\x1b\xa9\xb3\x41\x8a\x6d\x8e\x03\xa5\x0e\xd7\xc6\xc6\x0c\xd9\x38\x99\xdf\xdd\x00\xa8\x3e\x07\x36\xcb\x84\xde\xc3\xfc\x1c\x36\x40\x80\xde\xc6\x02\x69\x57\xcb\x08\xec\x7b\x4b\x4a\xb6\xd6\xbc\x48\x4b\x28\x69\x4b\xba\xa7\x4c\xa1\x19\x90\x43\xf4\x7b\x70\x3f\x15\x24\xa0\x44\x18\xde\x6b\x73\x39\x30\xf5\x8e\x3c\x10\x63\xf6\x4b\x03\xe0\xec\x77\x6b\x08\x45\x35\x1f\xd5\x7a\x2c\xc6\x7e\x53\x32\xed\x15\xf5\x4a\x93\x60\x80\x33\xc7\x10\xf2\x6c\xab\xf1\xc3\x29\x01\x6c\x02\xba\xc1\xd3\xe4\x8d\xc5\x44\x03\x89\x26\x0b\xf1\x6b\x88\x13\x96\xee\x52\x14\x21\x79\x26\x91\x07\x4a\xa6\x6b\x68\x57\x04\xea\x7d\x3d\xeb\x04\x05\x0d\xc1\xc0\x66\x73\x86\xcd\x68\xeb\xca\xea\xfb\x6d\x7e\x43\x2c\xf9\x76\x6b\xbc\xd2\x0d\xa0\x4f\xce\x73\x55\xc5\xec\x48\x32\x2c\x73\x22\x69\x6e\xd9\xce\x49\x32\x97\xdf\xa4\x3f\xab\x7f\x66\xe6\xf5\x39\x03\xb8\xd2\xed\x32\x49\x33\x2a\xa1\xff\x60\x24\xb9\x4e\x51\x0d\xc9\xde\x22\x99\x2e\x93\xb4\x6e\x9e\xf2\xc4\xbc\xab\x6e\x11\xd6\x42\x02\x45\xcb\x5b\x11\xd3\x16\x97\xa6\x37\x84\x89\x72\x2a\x32\xce\x12\xc4\xa9\xf6\xd4\x53\x2e\x49\xf8\x13\x6a\x65\x1a\x70\x6d\x32\x69\x64\x3d\xbe\x8b\xb2\xcf\x4f\x83\xb9\xfe\x19\x7d\x88\x0b\x78\x16\xb8\x1c\x37\xd7\x92\x0f\xfc\xd4\x54\x9c\x65\x09\x7a\xe0\x28\x97\xd4\xfc\x66\xc8\xaa\x20\x5c\x8f\x77\x55\x76\xda\xe5\xee\xa3\x87\x8e\xfa\xbe\xd7\x87\x4e\x63\x3e\xb2\x14\x59\x9a\xcf\xb9\x16\xae\xc5\xab\x6b\x43\x06\x4c\x50\x10\x45\xae\x60\x90\x69\x09\x53\x40\x3b\xb0\xa0\xf8\xaa\xa2\x32\x0f\xcb\x4a\x10\xa1\x42\x24\x36\xa3\x7f\xc1\xd1\x2e\x92\x0a\x99\xf5\xba\xce\x25\x7b\x58\xe6\x08\x0e\xdb\xd5\x35\xcc\x89\x01\x74\x32\x87\x7c\x0d\x9a\xf1\xec\x66\x2b\x40\xcb\xd4\x51\x9d\x6a\x19\x55\x66\xb4\x33\x5c\x4d\x11\x16\xe0\xc6\x0f\xfc\x23\xbe\x14\x02\x6e\xbf\x90\x16\x08\xe1\xab\xd3\x7e\x95\xaf\x5c\x1b\xc2\x14\x18\xf7\x7d\x4f\x3e\x5c\xa5\x9c\xab\xcf\x9c\xf3\x94\x74\xcb\xda\x72\x25\xf8\xb5\x94\x90\x2f\xea\x52\x46\xd9\x23\x0c\x0b\x4b\x6c\x5d\xe2\x22\xde\x14\xb0\x22\x46\xc8\x3a\xa6\x89\x83\x5a\xc1\xf2\xa5\x84\xa0\x6b\x02\x90\xa0\x19\xfe\xb0\x30\xf8\x15\x79\x29\x08\x2a\x13\x4d\xc7\xce\x72\x01\xa5\x1a\x6b\x5b\x75\xd5\x24\xa9\x8b\xec\x1a\x7e\x34\x02\xd0\x58\x19\xc2\x98\xff\xb0\x72\x1c\x49\xa6\x7e\x61\xb9\x6d\x44\x38\xd7\xc0\xa2\x03\x98\x38\x88\xb2\x1d\x43\x34\xd5\x01\x5e\xd3\x80\x2f\x09\x69\xe7\x53\x97\x2c\x61\xae\x59\xf2\x6d\x28\x87\x34\xb6\x40\xb1\x0e\xb8\x58\xbd\x0e\x48\xba\xa9\x94\xc2\x3a\xe4\xae\x3c\x4c\xd3\x56\x41\x03\x66\x80\xac\x04\xd5\xa8\x32\x64\x2d\x7f\xc5\xac\xbb\x50\x9e\x6b\xa5\x2a\x04\x95\xd2\xc0\x70\xb5\x3c\x87\x4d\x55\x2e\xa5\x01\x2c\xa8\x32\x14\x11\x9c\x23\xc5\xd8\x79\xf9\xb0\x79\x53\x0c\x4b\x3e\xd1\xd5\xaf\x4f\x99\xdc\x02\xa4\xef\x34\x82\x70\xa6\xa5\x83\x22\xc7\xfa\x60\xf1\x4b\x7c\x19\xb4\x60\x76\x51\x89\x63\x45\xcc\x1a\x0c\x9a\x1b\x97\x48\x06\x8e\x2d\xe2\x38\x01\x9d\xe0\xb6\xd0\xb4\x82\x1e\x1d\xd4\xe9\xed\x53\x43\x4d\xc7\x58\x3b\x46\xae\x69\x82\xa5\x09\xe3\x07\xa5\x4a\x57\xab\x51\x64\xdb\x84\x55\xca\x06\x39\x6c\xb5\x9c\xd5\xb9\xb0\x0d\x05\x57\x66\x94\x79\x99\x36\x7e\x46\xec\xca\xb1\x2e\x95\x35\x54\x2d\xd0\xf7\xe9\x57\x0f\x5c\xc4\x30\x99\xc6\x87\x72\x68\xc0\xc1\xba\x0e\xd6\x6d\xf0\x03\x58\xbb\xa9\xc3\xb2\x51\xff\xc0\xd9\x0c\x78\xf5\x6c\xa6\xa3\x42\x2a\x7e\xca\xd9\x6b\xf1\x6c\x16\xfe\x73\xbe\x86\xbd\x18\x22\x0e\x88\xcd\xee\x0c\xeb\xc6\x01\xd6\x36\xba\xf9\xca\xba\x22\x27\x3e\xac\x6c\x74\x49\x73\x4e\x79\xd7\x46\x61\xcf\xdd\xc4\xc4\x2f\xac\x9b\xed\xf0\xae\x19\x89\x62\x71\x22\x77\x1a\x46\xb8\x59\xe6\x87\x19\x92\x13\x2d\xf2\x2b\x8b\x81\x6f\x40\x4c\x33\x64\xc8\xd4\x99\xec\x08\x60\x46\xa6\x2c\xca\x5e\xc9\xc4\xc7\xbe\xa7\x5a\x00\xc3\xa1\x5f\x26\x2a\xe9\x19\xa6\x5b\x22\x93\xaf\x3b\xfd\xc0\x92\x33\x94\x18\x2e\x31\xc6\x9d\x67\xcb\xd5\x23\x01\x56\xf7\xb5\x00\xcf\x08\xe4\x68\x90\x47\x78\x35\x5b\x1a\x87\x44\x35\xbe\xad\x82\xeb\x5b\x99\x7d\x87\x0d\x11\xb8\x02\x26\xa6\x7e\x35\x3b\x58\x14\x4a\x55\x53\x66\x96\xb8\x5b\x19\x3b\x4c\x5b\x65\x09\x06\xe2\xae\x84\x3f\xae\x40\x33\x0f\x7a\xfa\x93\x5c\x51\x02\xf3\x36\xa3\x81\x57\xb9\x22\xeb\x89\x7c\x35\x99\x32\x6a\x62\x2b\x37\x97\x46\x6d\xe7\xdf\x8b\xee\x18\x58\x53\xb2\x9a\x3a\x33\x03\x90\x10\x26\x5a\x3c\x26\x36\xa9\xd3\x83\xa5\xca\x81\x16\x4c\x1b\x9d\x23\x5c\xd5\xf9\xf2\xc4\xd8\x86\xcc\x4c\x3a\x2c\x7c\xe8\x42\xe8\xe1\xe3\x1f\xba\x4a\xb1\x2b\x1f\x99\xe6\x8d\x56\x38\xd7\xbe\x8f\x41\xdf\xd6\xff\xcb\xdf\xc7\x24\xdc\x72\xde\x87\x5f\xfb\x6d\xab\x4f\x8c\xd3\x73\xaa\xde\x83\x2d\x5d\x5b\xde\xfe\xb0\x53\x6f\x0e\x35\x6f\xff\xf3\x96\x94\x39\xef\xad\xb7\x3f\x76\x07\xa4\x2f\xf7\xb0\xd7\x2f\x4e\x97\xe4\x6e\x46\x17\x2a\x41\x31\xba\x30\x71\x66\xc7\xeb\x66\xd3\x4a\xf1\x13\x00\xc5\x4f\x00\xcb\x01\xce\xa0\x7f\x07\x00\x00\xff\xff\xd3\x8b\x3b\xc6\xa3\x17\x00\x00") + +func fontsInvitaFlfBytes() ([]byte, error) { + return bindataRead( + _fontsInvitaFlf, + "fonts/invita.flf", + ) +} + +func fontsInvitaFlf() (*asset, error) { + bytes, err := fontsInvitaFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/invita.flf", size: 6051, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsIsometric1Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdf\x6f\xdb\x36\x10\x7e\xd7\x5f\xf1\x3d\x54\x90\x0d\xd8\x64\xdc\xa5\x80\xc3\xc2\x83\x1f\x86\x6e\xdd\xba\xa2\x40\xf6\x28\x8c\xb2\x1d\x3a\x33\x92\x48\x85\xad\xb4\x0e\x40\xe8\x6f\x1f\x28\xfe\x10\xe9\xa4\x8b\x85\x38\x4e\x30\x88\x6d\xd1\x1c\x7f\x1c\x3f\x7e\xbc\xe3\x9d\x0e\x59\x5e\x2f\xdf\xce\xde\x60\x34\xaa\xff\x8e\x31\x1c\xe1\xed\x4f\xd1\x6a\x53\xdc\x88\x72\xbd\x5a\x8c\xc8\xf2\x7a\x19\x45\x1f\x56\x97\xd7\xa2\xc4\xa2\xc8\xbf\x89\xf5\x66\x55\xe4\x98\xdf\xe1\x0f\x91\x97\xf8\x3c\xdb\x6c\x44\x8e\xde\x95\xc8\xcb\x7c\xba\xb8\x9b\x8b\xf5\xe6\xeb\x6c\x21\x48\xb1\xbe\xec\x0f\x30\x1e\x8e\x4e\x86\x67\xa7\x03\xcc\x67\x1b\x71\x11\x15\x39\xca\x7f\x04\x96\x45\x5e\x6e\xf0\xb5\xd8\x94\xe2\x42\x69\xfa\x24\xf2\x5c\xac\x4b\x9c\x97\xc5\xe2\x8a\x45\xd1\x87\x75\x71\xc3\xb0\x51\xd2\x74\xf9\x7d\x45\x6e\xbf\xcd\x48\x7e\x8d\x5e\x30\xaf\x1f\xfd\x32\x2b\x05\xc3\xe8\x1d\x7e\xbf\xbd\xc6\xe8\xec\xec\x14\x27\x27\xec\xe4\x94\xbd\x7d\x87\x5f\xff\xfc\x2b\x8a\x7e\x13\x6b\x81\xd9\x5a\x40\x9d\x46\x6f\x4a\xf0\xb9\xc8\x87\x4b\x7d\x9c\x8f\xc9\x0d\x66\xcb\xf5\x6c\x75\x31\xc0\x6a\x89\xbb\xe2\x16\xdf\x67\x79\x3e\x33\xe7\x2c\x15\xd6\x9b\x01\xe6\x22\xba\xb9\xc3\xe5\xad\xd8\x94\x04\x1f\x2d\x6c\x75\x0e\x47\x93\x39\xd1\x5c\x2c\x8b\xb5\x20\x51\x34\x3c\x68\x8b\x22\xa8\x46\xb6\x71\xdd\xb6\x04\x6d\x5a\xb3\xac\x56\x33\x88\x5d\x6b\xa3\x87\x78\xcb\x22\xa3\x26\x01\xfa\x09\x90\xf6\x5b\xe8\x61\x3d\x20\x53\xff\x8c\xa2\x41\xbc\x8d\xfb\xdc\xb4\x3e\xdc\x99\xf1\x09\x02\x39\x72\x08\xac\x51\x02\x38\x47\x89\x02\x0b\x5c\x19\x45\x3d\x70\x00\x9c\xa3\x17\x6f\x6b\x4d\xbd\x38\x8e\xab\xbf\xc7\xe3\x2f\xd5\x78\xfc\x45\xb6\x80\x24\xab\xc9\xcf\x20\x93\x61\x85\x38\x8e\xfb\x5a\x13\x63\x04\x84\x0d\x52\x90\xa4\x85\xa6\x8c\x80\x0e\xea\x95\x4c\x6b\xca\xde\xc7\x2c\x4b\x09\xb2\x61\x82\x36\x90\x00\x59\xaf\x21\x34\x61\x31\x4b\x14\xe1\x59\xb6\xcd\x08\x86\x93\xc9\xe4\x41\x48\xf7\x9c\xc5\x11\x99\x91\xc9\x64\x32\x04\x49\xb6\x49\xad\x08\x14\x19\xcb\x08\xe7\xe4\x7d\x2b\x44\x00\x53\x8b\x12\x96\x20\x8d\x40\x2e\xc6\x73\x6d\x3f\x84\x64\x2d\x0d\x32\x21\x66\xa5\xd2\x11\xbd\x31\xdd\x6f\xa6\xc7\xfd\x71\x1a\x3d\xf8\xa7\xeb\xee\xba\xff\x27\xdd\xda\xd2\x39\xe7\xf5\xff\x46\xa6\x29\x90\x36\x32\x65\xcc\x74\xd4\x32\x65\x34\x35\x1d\x4a\x56\xa3\x95\xe9\x98\x46\x76\x34\x65\x29\xe7\xe9\x34\x42\x4a\x39\x4f\x59\x4a\x19\x05\xa8\xdd\x2f\x65\xb5\x68\xf7\x83\x1e\x6d\xf6\x37\xa2\x95\x95\x0e\x5a\xe3\x39\x24\x60\xce\x43\xc0\x92\x73\xa9\x00\xeb\xd1\x06\xb0\x1e\xf5\x00\xbb\x51\xbb\x9f\x1a\xd5\x08\x0d\x9e\xaa\x32\x4f\xc8\x81\x00\x53\x8d\xc2\x31\xac\x36\x6b\x18\x36\x53\x6b\x96\x2c\x60\xad\x1d\x0e\xb0\xed\xb0\x80\xeb\xd3\x3f\x1f\xc3\xd4\xed\xe1\x03\x6e\x18\x56\x53\x43\x86\xed\xa5\xbf\x10\xc3\xff\x6d\xc3\x66\x34\x60\xd8\x72\xe8\x18\x36\x1c\x1e\x89\xe1\x7d\x9c\xae\x01\xec\x43\xb2\x72\x08\xb8\x69\xf7\xe4\x67\xb3\x61\x1e\xda\x30\x7d\x84\xe1\xfb\x26\xd1\xf6\x95\x08\xae\xc4\xbd\x32\x0e\xb0\x59\xef\x18\x56\x60\x95\x8e\x86\x61\xad\xe3\xd9\x9e\xb5\xf0\x02\x34\xfc\x90\x6d\xbb\xd4\x31\x69\xa9\xd7\xb0\xc0\xb9\x42\x6a\x58\xa4\xa9\xbf\x65\xe3\x43\x30\x0c\xfb\x74\xa4\xfe\xd8\x03\x97\x1f\xa2\xd9\x81\xe3\xe3\x51\xf3\x1a\x40\x54\x7b\xb6\x45\xe4\xdd\xa2\x01\x11\x5e\x42\x1a\xdc\xc1\x8f\x8d\x72\x57\x3c\xd4\x8d\x73\x9e\x72\xff\xc6\x55\x6b\x6e\x5c\x32\x59\x55\xb2\x72\xfa\x24\x93\xd0\x39\xfb\x7e\x32\x52\xf5\x02\xde\x03\xec\x83\xf5\x81\x5a\x90\xd6\xa4\x3c\x73\xa2\xde\x73\x98\xfa\x7e\xe7\xfb\x5c\x68\x25\xce\xd7\x9c\xe9\xed\xcd\x9a\x3d\x86\x01\x24\x7d\x99\x32\x2a\xeb\x87\xdd\xb1\x06\x19\xb2\xc6\x69\x55\x85\x7e\x12\xbc\xf5\x07\x09\xff\xad\x01\x03\x01\x60\x19\x38\xb6\x64\x32\x00\x2c\x59\x08\x58\xb2\xe3\xe6\x2b\xfb\x84\xff\xb6\xd1\xf4\x08\x09\xd6\x53\x32\xc2\xa3\x06\x27\x17\xe0\x7d\x67\xd9\x71\x98\x57\x99\xc2\xfe\x98\x61\xc9\x42\xc0\x92\xc9\x00\xb0\x64\x32\x60\x78\xcf\xa7\xaa\x15\x60\x34\x80\x79\xcd\x30\x1c\xe0\x54\x33\x0c\xcf\x86\x1f\x4d\xb0\x0e\x6c\xc3\xe1\xbb\xe9\x77\x34\x57\xba\x13\x65\xa9\x6f\x12\xda\x2d\x5d\x82\xd5\xc4\x96\xdd\x48\xf6\x04\x1b\x7e\x24\x7a\xf9\x1b\x5a\xb1\x89\x5e\xf5\xfe\xf4\xb8\xaf\x44\x3b\xc0\xb5\x3a\x1b\x01\x8d\x05\xba\x28\xa8\xe5\x06\x70\x1d\x65\x42\xc0\xcc\x66\x34\x7a\xbf\xaa\xb2\x5f\x05\x4f\x60\x98\x53\xee\x03\xa6\x8d\x0d\xd6\xa2\x99\x61\x18\x76\x33\x9a\xd4\xc6\x67\xd8\xcc\x38\x20\xc3\x72\xe7\xab\x22\x88\x6c\x0f\xcb\x2e\x34\xab\xc4\x86\xfa\xa1\xb9\xe6\xaf\xaa\xa8\x4d\x68\xaa\x4a\x27\x38\x78\x6a\x42\x73\x20\xc0\xc6\x07\x59\xe8\x74\x1e\xe0\xe7\x71\xba\x96\xaf\x84\x17\x9a\x4d\x89\x3a\x0d\x18\xb6\x56\x6a\x9c\xae\xaa\x52\x6d\xa5\xd3\xe8\x38\x5f\xe6\x8c\x85\x81\xc3\x75\xd4\x36\xcc\xd8\xa7\xf3\xc0\x24\x46\x67\x67\xa7\xcc\xb7\xe1\x1a\xff\x8e\xd3\xed\x6b\xc3\x5d\x41\xeb\x98\xd9\x40\x57\xd0\x7a\xee\x14\xbc\x2b\x68\xbd\xec\x37\x43\x57\xd0\xea\x0a\x5a\x5d\x41\xab\xcd\x8d\x77\x05\xad\xae\xa0\xd5\x15\xb4\x5e\x41\x46\xd8\x15\xb4\xba\x82\x56\x57\xd0\xea\x0a\x5a\x5d\x41\xab\x2b\x68\x75\x05\x2d\x03\xf8\xf5\xfc\x1e\xd4\x0b\x74\xff\x1b\x00\x00\xff\xff\x1f\x45\xa0\xac\x57\x2d\x00\x00") + +func fontsIsometric1FlfBytes() ([]byte, error) { + return bindataRead( + _fontsIsometric1Flf, + "fonts/isometric1.flf", + ) +} + +func fontsIsometric1Flf() (*asset, error) { + bytes, err := fontsIsometric1FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/isometric1.flf", size: 11607, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsIsometric2Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x5d\x6f\xdb\x36\x17\xbe\xd7\xaf\x78\x2e\x2a\xc8\x06\x6c\x32\xce\x9b\x02\x0e\x0b\xbf\xf0\xc5\xd0\xad\x5b\x56\x14\xc8\x2e\x85\x51\xb6\x43\x67\x46\x12\xa9\x90\x95\xd6\x01\x04\xfd\xf6\x81\x12\x3f\x6d\x2f\x89\xe2\xc4\x1d\x06\xb1\x2d\x9a\x43\x93\x47\xcf\x79\x74\xbe\x7c\x90\xe5\xed\xf2\x74\xf6\x0e\xa3\x51\xfd\x77\x8c\xe1\x08\xa7\xff\x0b\x56\xeb\xec\x4e\x14\xf9\x6a\x71\x4a\x96\xb7\xcb\x20\xf8\xb8\xba\xbe\x15\x05\x16\x59\xfa\x4d\xe4\xeb\x55\x96\x62\xfe\x80\xdf\x44\x5a\xe0\xf3\x6c\xbd\x16\x29\x7a\x37\x22\x2d\xd2\xe9\xe2\x61\x2e\xf2\xf5\xd7\xd9\x42\x90\x2c\xbf\xee\x0f\x30\x1e\x8e\x4e\x86\xe7\x67\x03\xcc\x67\x6b\x71\x15\x64\x29\x8a\xbf\x04\x96\x59\x5a\xac\xf1\x35\x5b\x17\xe2\x4a\x6a\xba\x10\x69\x2a\xf2\x02\x97\x45\xb6\xb8\x61\x41\xf0\x31\xcf\xee\x18\xd6\x52\x9a\x2e\xbf\xaf\xc8\xfd\xb7\x19\x49\x6f\xd1\xf3\xce\xf5\x83\x9f\x66\x85\x60\x18\xbd\xc7\xaf\xf7\xb7\x18\x9d\x9f\x9f\xe1\xe4\x84\x9d\x9c\xb1\xd3\xf7\xf8\xf9\xf7\x3f\x82\xe0\x17\x91\x0b\xcc\x72\x01\x69\x4d\xf3\x50\x82\xcf\x59\x3a\x5c\x36\xe6\x7c\x8a\xee\x30\x5b\xe6\xb3\xd5\xd5\x00\xab\x25\x1e\xb2\x7b\x7c\x9f\xa5\xe9\x4c\xd9\x59\x48\xac\x77\x03\xcc\x45\x70\xf7\x80\xeb\x7b\xb1\x2e\x08\x3e\x69\xd8\xd2\x0e\x43\x93\xb2\x68\x2e\x96\x59\x2e\x48\x10\x0c\x5f\x75\x05\x01\xe4\x22\x9b\xb0\x5e\x1b\x82\x36\xcb\x5e\xab\xd5\x0c\x42\xb3\xda\xe8\x21\xce\xb5\x40\xa9\x89\x80\x7e\x04\xc4\xfd\x16\x7a\x58\x0f\x48\xe4\x3f\xa5\x68\x10\x6e\xc2\x3e\x57\xab\x0f\x63\x33\x2e\x20\x90\x22\x85\x40\x8e\x02\xc0\x25\x0a\x64\x58\xe0\x46\x29\xea\x81\x03\xe0\x1c\xbd\x70\x53\x6b\xea\x85\x61\x58\xfd\x39\x1e\x7f\xa9\xc6\xe3\x2f\x65\x0b\x48\x65\x35\xf9\x3f\xc8\x64\x58\x21\x0c\xc3\x7e\xa3\x89\x31\x02\xc2\x06\x31\x48\xd4\x42\x53\x42\x40\x07\xf5\x4d\xd6\x68\x4a\x3e\x84\x2c\x89\x09\x92\x61\x84\x36\x90\x80\xb2\xbe\x43\x68\xc4\x42\x16\x49\xc2\x93\x64\x93\x10\x0c\x27\x93\xc9\x5e\x48\x3b\xc1\x62\x88\x4c\xc8\x64\x32\x19\x82\x44\x9b\xa8\x56\x04\x8a\x84\x25\x84\x73\xf2\xa1\x15\x22\x80\xc9\x4b\x11\x8b\x10\x07\x20\x57\xe3\x79\xe3\x3f\x84\x24\x2d\x1d\x32\x22\xea\xa6\xd4\x11\xbc\x53\xdb\xef\xa6\xc7\xfd\x71\x1a\xec\xfd\xd3\x6d\x77\xdb\xff\x91\xed\xc6\xd3\x39\xe7\xf5\xff\x4a\xa6\x31\x10\x5b\x99\x32\xa6\x36\x6a\x99\x32\x1a\xab\x0d\x29\x53\x46\xcd\x89\x69\x20\x45\xde\x9c\xe0\x3c\x9e\x06\x88\x59\x2c\x4f\x20\xa6\x9c\x53\x79\x3e\x66\x4c\xfe\x68\x9f\xa7\x95\x99\xe7\x35\x77\x1d\x3c\xb1\xbe\x60\x00\xeb\xa5\xe4\xba\x32\xb4\x05\x2c\x9f\xe1\x02\x2e\x39\x2f\x2d\xe0\x1a\xb4\x05\xdc\x88\x06\xb0\x12\x0d\x60\x25\xfe\x33\xe0\x1d\x86\x3d\x0b\xb5\x3a\x0b\x58\x89\x06\xb0\x14\xa5\x0e\x05\x58\x6a\xa7\x96\x61\x69\x9b\x0b\x38\x36\x97\x5e\x0c\xf8\x50\x86\xf5\x5b\xb4\x80\x5d\x86\xdf\x00\xf0\xd3\x0c\x73\xca\x5d\x86\xd5\x09\xeb\x12\xcd\x09\xeb\x12\x2e\xc3\x3f\xc4\x25\x9e\x06\xac\x1e\x48\x2d\x9c\x5a\x76\xe0\x34\xe7\x5f\x25\xe8\x5e\x00\xf8\xb1\x2c\xc1\x63\x2f\x4b\x1c\xc3\x25\xbc\xb4\x66\x39\xd0\xe7\x5d\x1f\x96\x77\x5d\xc0\xb1\xf6\xf2\xb7\x4f\x6b\xfb\x24\xcf\x14\x8f\x79\x6a\x9e\x5b\xf3\xca\x1c\x23\x63\x15\x95\x4d\xde\x40\x55\x49\xd4\xca\x00\x87\x42\x4d\x8f\xc3\xb6\x01\xe7\x43\xf3\xb0\x78\x50\x3c\x24\x1e\x10\x07\x07\x2c\x0c\x45\xab\xe5\xc5\x03\xe1\x65\x45\xc5\xde\x16\x9e\xed\x77\x5b\xa2\xe9\x9e\x1b\xb9\x64\x8f\xc9\x9c\x7b\x32\x8d\xe5\xe7\x9c\x97\x32\xc7\xe9\x77\x2b\x97\xfb\x6e\xab\x8a\x56\xee\xbb\xad\xaa\xc3\x4a\x56\x2b\x59\x1b\xab\x2b\x80\xa2\xf6\x6d\x2b\xc0\xe3\xd1\x53\xfa\x15\x40\x32\xe8\x45\x4f\xc9\xca\xd8\x09\x77\xc6\x58\xc9\xdd\xe8\xa9\xf9\x73\xa2\xc7\x04\xcb\x2b\xe6\xa7\x76\xe1\xce\xf9\x16\x60\xb9\x3c\xc0\x55\x75\x4c\xc0\xcf\xab\xb1\x6e\x42\xa5\x38\x4a\x42\xf5\xe1\xfa\x60\x1d\xa8\x2a\xa8\xbd\xca\x49\xbd\xba\xb9\x05\xc1\xa6\x50\x9f\x51\x9f\xcf\xc7\xf2\xd3\x23\xe1\x74\xec\x16\xd7\x6d\xe0\x2c\x93\x87\xbd\xfc\x27\xca\x3f\xe7\x74\x3b\x81\x39\xfd\x8a\x4c\x60\x55\x55\xbd\x3c\x81\xbd\x72\xf9\xdf\xc3\xa0\xdf\x60\xf9\xde\x6a\x1b\x1c\xbf\x5c\x1d\x90\x71\xdb\xf6\xe4\x6e\x79\x77\x0a\xad\x32\x28\xf6\x2b\xaf\xc9\x26\x5e\xbe\x71\x3d\xf8\xe9\x9a\xd6\xb6\x5f\x71\xf3\x41\xf3\xc9\x1b\xe7\x83\x76\x41\xf6\x3c\x03\xf4\x97\x86\xfa\x13\x55\xa7\x8d\x01\x56\x6e\x8e\x36\x75\x5b\x1b\xc0\x74\x02\x69\xf4\xd7\xee\xde\x26\xe8\xb6\x5e\x19\x8d\x7d\x80\x52\xf0\x18\x56\x1b\x96\x61\xc3\xa1\x66\x58\x73\x78\x70\x11\xde\xe9\x73\x76\x1a\x9b\xfd\x1b\x86\x22\xe3\xa8\xaa\xa8\x71\xd5\xec\x48\x92\x34\x73\x5c\xb7\x82\x25\x2b\xab\xca\x69\x9f\x76\xfa\x29\x58\xad\x7a\xc3\x86\xc7\xf4\xc9\x6e\x76\xbb\x92\x34\xca\x7d\x03\x76\x25\x6b\x8b\x31\x44\xbf\x9c\xc6\x0a\xb7\xab\xf4\xdb\x4a\x9d\x9c\x9f\x1b\xfa\xda\x5c\x1d\xfa\xae\x4c\x19\x6d\x50\x99\xaf\xe3\x35\x4a\xd3\x8c\xd1\x1a\xa7\xdb\xc8\xa2\x64\x7e\x73\x5d\x32\x3f\x97\x95\x5b\x7e\x50\x1e\xda\x2a\xb8\xdc\xe8\x66\xc6\xed\x6d\x2e\x2e\xdd\xde\x86\x8d\xce\xcf\xcf\xbc\x6a\xa1\x8b\x87\x1b\x59\xcf\x75\xdc\x6e\x8a\xf5\xc2\xaf\x04\xdd\x14\xab\x9b\x62\x75\x53\xac\x6e\x8a\xd5\x4d\xb1\xba\x29\xd6\x56\x2f\xb7\x4f\xee\xa6\x58\xdd\x14\xab\x9b\x62\x75\x53\xac\x36\x5c\x77\x53\xac\x6e\x8a\xd5\x4d\xb1\xba\x29\x56\x37\xc5\xd2\x1b\xdd\x14\xeb\x28\x53\xac\x7f\xcf\x6f\x3c\xfd\x80\xed\xbf\x03\x00\x00\xff\xff\x98\xa5\xd7\x37\x41\x2d\x00\x00") + +func fontsIsometric2FlfBytes() ([]byte, error) { + return bindataRead( + _fontsIsometric2Flf, + "fonts/isometric2.flf", + ) +} + +func fontsIsometric2Flf() (*asset, error) { + bytes, err := fontsIsometric2FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/isometric2.flf", size: 11585, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsIsometric3Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x5d\x6f\xdb\x36\x14\x7d\xd7\xaf\x38\x0f\x15\x64\x03\x36\x19\xa7\x29\xe0\xb0\xf0\xe0\x87\xa1\x5b\xb7\xac\x28\x90\x3d\x12\xa3\x6c\x87\xce\x8c\x24\x52\x21\x2b\xad\x03\x08\xfa\xed\x03\x3f\x24\x91\x8e\x93\x58\x89\xd3\x0e\x9b\x98\x04\xc9\xa5\xc9\xcb\xc3\xc3\xfb\x85\x8b\x2c\xaf\x97\xc7\xb3\x37\x18\x8d\xf4\xf7\x18\xc3\x11\x8e\xdf\x06\xab\x75\x7a\x23\xf3\x6c\xb5\x78\x4b\x96\xd7\xcb\x20\xf8\xb0\xba\xbc\x96\x39\x16\x69\xf2\x55\x66\xeb\x55\x9a\x60\x7e\x87\xdf\x65\x92\xe3\xd3\x6c\xbd\x96\x09\x7a\x57\x32\xc9\x93\xe9\xe2\x6e\x2e\xb3\xf5\x97\xd9\x42\x92\x34\xbb\xec\x0f\x30\x1e\x8e\x8e\x86\xa7\x27\x03\xcc\x67\x6b\x79\x11\xa4\x09\xf2\xbf\x25\xbe\xa4\xeb\x5c\x69\x38\x93\x49\x22\xb3\x1c\xe7\x79\xba\xb8\x62\x08\x82\x0f\x59\x7a\xc3\xb0\x56\xe2\x74\xf9\x6d\x45\x6e\xbf\xce\x48\x72\x8d\x9e\xb7\xb0\x1f\xfc\x3c\xcb\x25\xc3\xe8\x1d\x7e\xbb\xbd\xc6\xe8\xf4\xf4\x04\x47\x47\xec\xe8\x84\x1d\xbf\xc3\x2f\x7f\xfc\x19\x04\xbf\xca\x4c\x62\x96\x49\xa8\x6b\x60\x99\x26\xf9\x9a\xe0\x53\x9a\x0c\x97\xe6\x1e\x1f\xa3\x1b\xcc\x96\xd9\x6c\x75\x31\xc0\x6a\x89\xbb\xf4\x16\xdf\x66\x49\x32\xb3\x17\xcc\x15\xc8\x9b\x01\xe6\x32\xb8\xb9\xc3\xe5\xad\x5c\xe7\x04\x1f\x35\x6a\x79\xa1\x2f\x50\xf3\x63\x94\x63\x2e\x97\x69\x26\x49\x10\x0c\x0f\x3a\x82\x00\x6a\x90\x4d\xa8\xc7\x86\xa0\xcd\x68\xb6\x69\x35\x83\xb0\x1e\x6d\xf4\x10\x67\x5b\x60\xd5\x44\x40\x3f\x02\x78\xbf\x85\x1e\xd6\x03\x62\xf5\x63\x15\x0d\xc2\x4d\xd8\x17\x76\xf4\x51\xdf\x19\x67\x90\x48\x90\x40\x22\x43\x0e\xe0\x1c\x39\x52\x2c\x70\x65\x15\xf5\x20\x00\x08\x81\x5e\xb8\xd1\x9a\x7a\x61\x18\x96\x7f\x8d\xc7\x9f\xcb\xf1\xf8\x73\xd1\x02\x52\x51\x4e\x7e\x02\x99\x0c\x4b\x84\x61\xd8\x37\x9a\x18\x23\x20\x6c\xc0\x41\xa2\x16\x9a\x62\x02\x3a\xd0\x3b\x99\xd1\x14\xbf\x0f\x59\xcc\x09\xe2\x61\x84\x36\x90\x80\x42\xef\x21\x34\x62\x21\x8b\x14\xe1\x71\xbc\x89\x09\x86\x93\xc9\x64\x27\xa4\x7b\xce\x52\x13\x19\x93\xc9\x64\x32\x04\x89\x36\x91\x56\x04\x8a\x98\xc5\x44\x08\xf2\xbe\x15\x22\x80\xa9\x4d\x11\x8b\xc0\x03\x90\x8b\xf1\xdc\xd8\x0f\x21\x71\x4b\x83\x8c\x88\xdd\xa9\x74\x04\x6f\xec\xf4\x9b\xe9\xf7\xfd\x73\x1a\xec\xfc\xea\xa6\xbb\xe9\xff\xc8\xb4\xb1\x74\x21\x84\xfe\x6d\x65\x0a\x50\xde\xc8\x4a\x64\x8c\x57\xb2\x16\x29\x57\x13\x4a\x36\x62\xa9\x57\x4c\x03\x50\x21\x28\xa3\x76\xc5\x34\x00\x07\x38\xe3\x94\x51\x21\x38\x55\xeb\xf5\x04\xa3\xcd\x79\x66\x85\x73\x7e\x33\x61\xf1\x70\xb5\x57\xcb\x15\xe0\x6a\x58\x59\x67\x86\x03\x00\x2e\x5c\xc0\x25\x65\x1e\x60\xb5\xca\x01\xac\x44\x17\xb0\xbe\xd2\x83\x80\xf7\x60\x98\xc2\x07\x5c\xaf\xaf\x44\xa5\xa3\x01\x6c\x74\xd4\x80\xed\xaa\x1a\x30\xc7\x8b\x00\x3f\x83\x51\x73\x6a\x03\x50\xe9\x74\x18\x3d\x14\xc0\x6d\x0b\x68\xc3\xb0\xd8\x62\x98\xfa\x17\xd0\x2b\x3c\x93\x70\x19\xb6\x53\x07\x36\x09\x1f\xae\x0f\xd6\x87\xea\x03\xf5\x61\x7a\x20\xe1\xbb\x99\xef\x64\xbe\x8b\xf9\xe0\x0e\xc8\xa5\xf0\xdd\x4b\xe9\x77\xe3\x01\x68\x59\x1e\xd0\x5a\xef\x01\x16\x82\x7a\x01\xc4\xbf\xbd\xd1\x50\xdd\x5f\xed\xad\xec\xdb\x02\xe6\xf8\x3e\x01\xcc\x48\x1e\x78\x8f\x6b\x2f\x2e\x68\x26\x6b\xb5\xdc\x52\x2a\x84\x77\xa8\x31\x93\xea\x86\x86\x61\x4b\x48\xc5\x6f\xf3\xdc\xc1\x0e\x47\x72\xdd\xbe\xc2\xe2\x41\xf1\x90\x38\x40\xb6\x2e\xef\xc2\xe0\x8e\x1d\x55\x90\x3c\x44\xbb\x00\x3d\xf6\xb6\x45\x23\x17\x40\xc1\x1e\x94\x85\xf0\x64\xfd\xb6\xa2\x60\x85\x8a\x6e\xce\xdb\xaa\xe1\xbe\x6d\x59\x96\xe5\xc1\x92\xd3\xa3\x72\x75\x39\x27\xb6\x73\xbc\x56\x6c\xdf\x37\x74\xfa\xde\xa3\x19\x74\xbc\xc7\x30\xda\x78\x4f\x21\x14\xa3\x6e\xec\x67\x8c\x15\x70\xbd\xa7\x2c\xb9\xe7\x3d\xdc\x21\xe4\x39\x0c\xb7\x76\x77\x27\xdc\xe9\xcc\x66\xfd\xdf\x01\xac\x86\x07\xb8\x2c\x7d\xc0\x2f\x32\x89\x97\x17\x58\x3b\xb3\xeb\xab\xa5\xff\xa7\x92\x53\xe5\xe0\xd4\x09\x94\x4d\x61\xf5\xba\xc9\x69\xdb\x9d\x7e\x6c\xf1\x5a\x31\xf7\xb2\xca\xe4\x69\x80\x14\x3e\xc0\xd7\x0c\x60\x07\x29\xa5\x9e\x60\xf4\xe1\xea\x5a\xc3\x71\xac\xb5\x2e\x78\xf7\xcb\xa6\x4f\x17\x56\xdb\x55\x76\x0d\xbb\x7a\x05\x73\x60\xf5\x06\xf6\x38\x27\xa9\xd9\x5b\xd4\xa7\xd7\xc1\x6d\x8f\xc7\x6f\x19\xaa\xdc\x7c\x6a\xf7\xbe\xb2\xe7\xef\xf6\xae\x2d\xf8\x5b\xe8\xb7\xc0\x37\xd8\x2b\xa8\x66\x9f\xc9\x1c\x35\xf2\x5a\xb4\xb2\xce\x23\xb5\x0d\x68\x93\x6e\x9c\x4a\x5b\xf4\xbe\xb4\x0a\x2e\x5c\x5a\xcd\xa7\x0d\xad\xf6\x53\x8f\x56\x3b\xd1\xd0\x6a\x88\x73\x68\xe5\xec\xc0\x15\x6a\x9b\x2a\x46\x73\x03\xb7\xfc\x62\x8a\x30\x1d\x04\x14\x3b\x2a\x5d\xd5\x41\x40\x37\x2c\xcb\x82\x15\x55\x10\x70\x14\x3e\x24\x0b\x51\xec\xef\x53\x06\xbc\x0f\xf5\xbe\xd4\xc0\x76\x41\x57\x2b\x0d\xe4\x83\xf8\xd4\xae\x80\x5a\xf8\xf1\xa9\x96\x8d\xa8\x4b\x40\x27\x3e\x29\x94\xa6\xe0\x32\x0f\x57\xb0\x82\x36\x5c\x2a\xd9\x29\x9f\x4d\x41\x44\x7d\x2e\xe9\x63\x5c\xb6\xcf\x00\x0d\x53\x95\xc8\xbc\x7a\xe5\xec\xdc\xad\x57\xd8\xe8\xf4\xf4\xc4\xcb\x00\x8e\xf7\x54\x13\xfb\x59\x6b\xd7\x83\x7a\x66\x99\xdf\xf5\xa0\xba\x1e\x54\xd7\x83\xea\x7a\x50\xfb\x57\x7a\x5d\x0f\x6a\xdb\x95\xba\x1e\x54\xd7\x83\xda\xe9\x3d\x5d\x0f\xaa\xeb\x41\x75\x3d\xa8\xae\x07\xd5\xb2\x94\xea\x7a\x50\x3b\xb9\xec\x7a\x50\x5d\x0f\xaa\xeb\x41\xfd\x6f\x7a\x50\xff\x9e\xff\x36\xfa\x01\xd3\xff\x04\x00\x00\xff\xff\x92\x72\x45\x3e\xb6\x2c\x00\x00") + +func fontsIsometric3FlfBytes() ([]byte, error) { + return bindataRead( + _fontsIsometric3Flf, + "fonts/isometric3.flf", + ) +} + +func fontsIsometric3Flf() (*asset, error) { + bytes, err := fontsIsometric3FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/isometric3.flf", size: 11446, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsIsometric4Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xdf\x6f\xdb\x36\x10\x7e\xd7\x5f\xf1\x3d\x44\x90\x0d\xd8\x54\x9c\xa5\x80\xc3\xc2\x83\x1f\x86\x6e\xdd\xb2\xa2\x40\xf6\x28\x8c\x92\x1d\x3a\x33\x92\x48\x85\xac\xb4\x0e\x20\xe8\x6f\x1f\xf8\x43\x24\x65\x3b\x35\x94\xc4\xce\x3a\x88\x6d\xd1\x1c\x4d\x1e\xbf\xfb\x78\xbc\x3b\x1f\xb2\xb8\x5b\x9c\x25\x27\x18\x8d\xe4\xdf\x31\x86\x23\x9c\xfd\xe4\x2d\x57\xd9\x3d\x2f\xf2\xe5\xfc\x9c\x2c\xee\x16\x9e\xf7\x61\x79\x73\xc7\x0b\xcc\xb3\xf4\x2b\xcf\x57\xcb\x2c\xc5\xec\x11\x7f\xf0\xb4\xc0\xa7\x64\xb5\xe2\x29\x7a\xb7\x3c\x2d\xd2\xe9\xfc\x71\xc6\xf3\xd5\x97\x64\xce\x49\x96\xdf\xf4\x07\x18\x0f\x47\xa7\xc3\x8b\xf3\x01\x66\xc9\x8a\x5f\x7b\x59\x8a\xe2\x1f\x8e\x45\x96\x16\x2b\x7c\xc9\x56\x05\xbf\x16\x9a\x2e\x79\x9a\xf2\xbc\xc0\x55\x91\xcd\x6f\xa9\xe7\x7d\xc8\xb3\x7b\x8a\x95\x90\xa6\x8b\x6f\x4b\xf2\xf0\x35\x21\xe9\x1d\x7a\x8d\x75\x7d\xef\x97\xa4\xe0\x14\xa3\x77\xf8\xfd\xe1\x0e\xa3\x8b\x8b\x73\x9c\x9e\xd2\xd3\x73\x7a\xf6\x0e\xbf\xfe\xf9\x97\xe7\xfd\xc6\x73\x8e\x24\xe7\x10\xd6\xa8\x43\x09\x3e\x65\xe9\x70\xa1\xcc\xf9\x18\xdc\x23\x59\xe4\xc9\xf2\x7a\x80\xe5\x02\x8f\xd9\x03\xbe\x25\x69\x9a\x68\x3b\x0b\x81\xf5\x7e\x80\x19\xf7\xee\x1f\x71\xf3\xc0\x57\x05\xc1\xc7\x1a\xb6\xb0\xc3\xd0\xa4\x2d\x9a\xf1\x45\x96\x73\xe2\x79\xc3\x57\x1d\x9e\x07\x31\xc8\xda\x97\x63\x4d\xd0\x66\xd8\x6d\x52\xcd\xc0\x37\xa3\x8d\x1e\xe2\x6c\xf3\xb4\x9a\x00\xe8\x07\x40\xd4\x6f\xa1\x87\xf6\x80\x58\xfc\xd3\x8a\x06\xfe\xda\xef\x33\x3d\xfa\x30\x36\xe3\x12\x1c\x29\x52\x70\xe4\x28\x00\x5c\xa1\x40\x86\x39\x6e\xb5\xa2\x1e\x18\x00\xc6\xd0\xf3\xd7\x52\x53\xcf\xf7\xfd\xea\xef\xf1\xf8\x73\x35\x1e\x7f\x2e\x5b\x40\x2a\xab\xc9\xcf\x20\x93\x61\x05\xdf\xf7\xfb\x4a\x13\xa5\x04\x84\x0e\x22\x90\xa0\x85\xa6\x98\x20\x1c\xc8\x9d\x54\x69\x8a\xdf\xfb\x34\x8e\x08\xe2\x61\x80\x36\x90\x80\x52\xee\x21\x61\x40\x7d\x1a\x08\xc2\xe3\x78\x1d\x13\x0c\x27\x93\xc9\x4e\x48\x5b\x8f\xc5\x10\x19\x93\xc9\x64\x32\x04\x09\xd6\x81\x54\x84\x10\x31\x8d\x09\x63\xe4\x7d\x2b\x44\x00\x15\x9b\x02\x1a\x20\xf2\x40\xae\xc7\x33\xe5\x3f\x84\xc4\x2d\x1d\x32\x20\x7a\xa7\xd0\xe1\x9d\xe8\xe9\x93\xe9\x71\x7f\x9c\x7a\x3b\xff\x74\xd3\xdd\xf4\xff\x64\x5a\x79\x3a\x63\x4c\xfe\xaf\xe5\x10\x08\x23\x2b\x0b\x91\xd2\xa8\x96\xa5\x18\x46\x62\x42\xc8\xf5\xa7\x62\x62\xea\x21\x64\x4c\x7d\xca\x22\x1a\x4d\x3d\x44\x8c\x45\x21\xc4\xa7\x21\x0d\xeb\xf3\xc4\x24\xa5\x61\x7d\x9e\x56\x69\xcf\x97\x3a\x2c\x1e\xad\x03\x38\x34\xe0\x52\x00\x96\x60\x1d\xc0\x6a\xc2\x01\x1c\xd5\xe6\xd4\xe7\xd5\xe6\x18\x3c\x00\xaa\xea\x75\x01\x2b\x0e\x2d\x60\x8d\xc2\x02\x56\x2c\x59\xc0\xb0\xe7\x39\x13\x1a\xb0\x99\x38\x1c\xc3\xdb\x80\x59\x93\x61\xb5\xca\x05\x1c\xbe\x29\xc3\x3b\x5c\xa2\xc9\xb0\xf4\x02\x17\xb0\xd9\x6f\x7c\x24\x6c\xc1\x70\x3d\x8e\x61\x80\x79\x84\xda\x00\x17\xa2\xc1\xa3\x57\x6d\xe1\x3b\x98\x4b\xb0\x88\x35\x18\x66\x2c\xdc\xc3\xb0\xeb\x12\x62\xe2\xc5\x51\x22\x44\x13\xb0\x59\x5f\x9b\x23\x74\x34\x18\x45\x78\xb8\xb0\xb6\xe1\x11\xda\x00\xa3\x4e\xf0\x63\x45\x79\x5a\xd4\x3c\x4c\x92\x29\xf6\x69\xfa\x25\x34\xb9\x2f\xa4\x61\x55\xc1\x50\xeb\x18\xbe\xe9\xaa\x16\x96\xb7\xdb\x0f\x9e\x8b\x52\xac\xb3\x28\xf5\xba\x1a\xa5\xb9\xdf\xa7\x50\xd6\xa8\xb6\x60\x3d\x81\xf2\x15\x2e\x9f\x6d\x5c\xbe\x18\xe6\xf2\xab\x92\x96\x55\x55\x55\x4a\x5f\x09\x94\xb4\xb4\xfa\xb7\x64\xc6\x1a\xb2\xd4\x51\x6e\x01\x76\xc1\xba\x40\x5d\x90\xee\x73\xb2\xd1\x55\xfe\x6c\xae\xd2\x8d\xaa\xee\x25\xbb\xc1\xc9\xf5\xc2\x56\x6f\xbc\x6c\xb0\x56\x1a\x59\x81\x2a\x69\xe9\xb2\xc6\xca\x06\x6b\x40\x58\x55\xce\x93\x71\x8d\xc2\xa1\x2a\x81\x56\x80\xe5\xbd\xb9\x6f\xbc\xa4\xa5\x05\x2c\xef\xd5\x01\x2c\xef\xf5\xb8\xa5\xcb\xee\xc4\x1a\x3d\x33\xb1\xee\x8f\xa2\x9b\x0f\xed\xe8\xc5\xa2\x86\x78\xa0\x3c\x65\x03\xbb\xfb\x50\x36\x1f\x8b\xfb\x60\x7e\x94\x6a\xd6\x0d\x55\x0e\x60\x15\x9a\x2c\x60\x25\x5b\x46\x55\xa8\xaa\xf6\x85\xaa\xe7\x32\xac\x93\xbe\x0b\x38\xc2\xde\x5a\x8b\xbd\xac\x12\xd8\xe7\xc3\x2a\x17\x59\x05\x6e\x1c\x85\xcd\x62\x9b\xc9\xd6\x25\x40\x9a\xe8\xc6\xec\xba\x1c\xb7\x0e\xb0\x95\xca\x5e\xe4\xc3\xdf\xcf\x5e\xf6\x00\xe7\xf8\xd0\xfd\xbe\xf0\xe6\x51\xe2\x69\x03\x34\xe2\x3a\x23\xea\x64\x6a\xb2\xa2\x92\x6d\x98\x53\x1e\xab\x36\x19\x86\x45\xda\x71\xa3\x84\xc8\xd5\x6d\x19\x66\x1b\x00\xc3\x66\x1c\x96\x2b\x2c\xc3\x6a\x85\x5b\xcb\x34\x18\xd6\x2b\x9e\xcd\xb0\xc6\x0b\x27\x13\x45\x1b\xb2\xcd\x74\x3b\x64\x4d\x92\x90\x45\x61\x23\x41\x3b\xa9\x59\xf2\xe5\x14\x34\x55\xf5\xd2\x82\x66\xdb\x25\x5e\xcd\x00\x73\x45\x94\x36\x1f\x9d\x31\xe0\x35\x1e\xdd\xde\xa8\xb0\xf5\x0d\xca\x56\x59\xaa\x5b\xdd\x4c\xcd\x7a\x38\x8f\xae\x92\x5e\xe9\x26\x1e\x7b\xde\x41\xbe\xa4\x53\xda\x4c\x1c\x6a\xa2\xf6\x61\x4a\x2f\xaf\x6a\x97\x90\x80\x47\x17\x17\xe7\x2e\x60\x85\xdf\x01\xec\x3e\xb2\xef\xfa\x70\xd7\xdb\x7a\xe3\x6a\xa0\xeb\x6d\x75\xbd\xad\xae\xb7\xf5\x82\x7a\xab\xeb\x6d\x75\xbd\xad\xae\xb7\xd5\xf5\xb6\xd0\xf5\xb6\x8e\x9c\x58\xbb\xde\x56\xd7\xdb\xea\x7a\x5b\xcf\xf5\xe1\xae\xb7\xd5\xf5\xb6\xba\xde\x56\xd7\xdb\xfa\x61\x7a\x5b\xff\x9d\xdf\x8e\x7a\x83\xe9\x7f\x03\x00\x00\xff\xff\x2b\xc1\x51\xba\x6d\x2d\x00\x00") + +func fontsIsometric4FlfBytes() ([]byte, error) { + return bindataRead( + _fontsIsometric4Flf, + "fonts/isometric4.flf", + ) +} + +func fontsIsometric4Flf() (*asset, error) { + bytes, err := fontsIsometric4FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/isometric4.flf", size: 11629, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsItalicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x55\xcd\x6a\xdc\x30\x10\x3e\x47\x4f\xf1\x1d\x04\x91\x21\xf6\x6c\x93\x9e\x4a\x29\xa2\xf7\x5e\x7a\x28\x2d\x18\x06\x67\xe3\x6d\xdd\x6c\xd6\x90\x4d\x68\x03\x7a\xf8\xa2\x91\x6c\x4b\xb2\xd3\xc0\xae\x25\xcd\x9f\x66\xbe\xf9\xd1\xe1\x78\xb8\xee\x34\xde\xe3\x06\xef\x76\xd8\xe1\x46\x0d\x4f\xdd\x71\xd8\x37\x87\xe3\xe1\xe2\xe2\x5b\xff\x78\x1e\xc6\x13\xae\xd5\xed\xcb\x07\xe0\x73\x77\xc6\x97\x7e\xf8\xdd\x3f\x02\x78\x90\x8d\x1d\x4e\x87\xb1\xf9\x33\x9c\x9a\xa7\xe7\xbe\x39\x1d\x01\xdc\x76\x67\x7b\xd7\x3d\xf4\xf7\xcd\xfd\xd3\xaf\xe6\xdc\xab\xc3\xf0\xb7\xbf\x83\xb7\xf0\xf5\xa5\x3b\xe1\xc7\xf8\xbc\xbf\x07\x5e\xfc\x62\xf7\xe7\xe6\xf9\xb1\xff\x39\x9c\xba\x66\xdf\x29\x6d\xe3\x0f\xd6\x2a\xc0\x2a\x07\xab\x1a\xc8\xde\x2a\x22\x58\xa5\xb5\x1c\xe3\x47\xbe\x72\x62\xc7\x8e\x61\x55\xed\x6a\x57\x63\xa6\x5b\x05\x27\x74\xe3\x9c\x16\x31\x57\x41\x88\x93\xb6\x55\x3b\x6f\x97\x76\x99\x49\xab\x4c\xe5\xc9\xe6\x7b\xbc\x4a\x1c\xf0\xf7\xc7\xbf\x10\xb4\x88\x08\xa9\x9d\xd5\x5b\x39\xfb\x5b\x48\xcf\x44\x0d\xf8\xc8\x5a\xf2\x5f\x6a\x75\xa4\xc8\x22\x1c\x76\x2c\x44\x07\x3d\x11\xad\x92\xbd\xb6\xea\x4a\xcb\x7e\x36\xc3\xac\xe7\x7d\x94\x0c\x7b\xed\xe1\xd2\xe1\x18\xa3\x13\x1f\x13\x4f\x00\x66\x89\x89\x00\xef\xa4\x61\x26\x64\x80\xf9\x53\x2d\x5a\x09\xcc\x41\x87\x25\x2c\xe6\x05\x93\x94\xc1\xf2\x45\x86\x22\x53\xbc\x2b\xd1\x60\x31\x82\xb5\x46\x30\x1c\x58\x66\xe1\x79\x26\x07\x1e\x47\xbf\x32\x2d\x39\x19\xae\xd6\x5a\x31\xd6\x48\x4d\x23\x8d\x05\xd6\xa4\x05\x36\x11\xae\xe6\xfc\x0a\xaa\x92\xb3\x36\xe2\x5b\xe4\xa0\xae\xd3\x54\xce\x82\x94\x48\xb3\x54\x0c\x2a\xff\x6d\xc2\x5e\x2e\x5b\x7e\x4b\x10\xc4\xbe\xe2\x0d\xe0\x32\x3f\xe7\x8c\x05\xfc\x7d\xa8\x79\xc6\x26\x7e\x84\x00\xdb\xda\x88\xda\x45\xbe\x03\xb4\x86\x05\x55\x2a\xb4\x67\xa6\x0e\x65\xf4\x8a\xe9\x05\xe6\xa2\x94\x82\x42\xc5\x53\xe2\x36\x6a\x0d\x14\x62\xce\x5a\x5a\x16\x8a\x15\x94\xdd\x19\xb9\x34\x9b\x5c\xdf\x39\x55\x9c\xc9\x2a\x75\xd6\x74\xe4\x62\x15\xb9\x4d\x6f\xc9\x05\xa4\xe0\x4a\x6f\xdf\x6c\x9d\x49\x20\x14\x1c\x01\xfa\x2d\x0b\xed\x1b\x16\xcc\x86\x05\x5f\xee\x98\xfa\x27\x6f\x92\xd0\x41\x92\x2d\x03\x6c\x23\x37\x01\xbb\x6e\x7c\x04\x35\xcf\x76\xdb\xb8\x9b\x98\x16\x47\x2b\x70\x82\xf5\x36\xf4\x21\xda\x95\x76\xbc\xd2\x7b\xa0\x8b\x1a\x5b\x5a\xbb\x98\x2d\x56\xc9\xd8\x76\x9c\x56\x87\x55\xc1\xf8\x32\x73\x05\x33\xed\x64\xc0\xe7\x92\xd4\xa6\x8f\x46\xf2\x74\x28\x5e\x6c\xb6\xe5\x60\x0f\x52\x52\xf9\x54\xa8\x0a\x74\x55\x41\xe4\xe9\x1d\xc8\x6a\x50\x22\x32\xd9\xec\x0b\x74\x6d\x95\xa9\xd3\xd9\x2a\x1d\x56\x8c\xe9\xa0\x16\x92\xed\x0d\x49\x3e\x52\x2f\xa8\xf4\xe2\xb2\x98\xd9\x73\xfe\x2f\x65\x11\x16\x53\x19\x0c\x99\xad\x08\xb1\x0a\x46\xd0\xa4\xaa\x0c\x06\x5b\x9e\x60\x05\x12\x96\xce\xac\xa6\x11\xbe\xc2\x99\x0a\xe2\x1a\x0f\xed\xc9\x5c\xe9\xc2\x0b\x2e\x9f\xab\x20\xbc\x91\x3f\x29\x85\x96\x56\x76\x45\x76\x12\xce\xa5\xab\x12\x20\xbd\xe1\x6f\x80\x67\x29\x29\xaf\xf3\x11\x61\x15\x82\xc3\xf2\x17\x82\x87\xe1\x13\xc2\x9a\xb8\x42\x2d\x21\x43\xcc\x2a\x8c\x3c\xbe\xfe\x3a\x8c\x1c\xb9\xaf\x0e\xa5\x11\x18\xff\xdf\xf7\x56\xd5\x5c\xaf\xc1\xaa\xeb\x8d\x62\xaf\xb1\x92\x9c\xde\x8c\xf8\x40\x61\x7a\xa1\x68\xbe\xe3\x5f\x00\x00\x00\xff\xff\x4a\x0e\x3c\xe0\x68\x0a\x00\x00") + +func fontsItalicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsItalicFlf, + "fonts/italic.flf", + ) +} + +func fontsItalicFlf() (*asset, error) { + bytes, err := fontsItalicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/italic.flf", size: 2664, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsIvritFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x5a\x7b\x6f\xda\xc8\xfa\xfe\x9f\x4f\xf1\xfc\xaa\xea\xd7\xe4\xc8\xc1\x81\xb6\x69\xab\x2d\x51\x68\x43\x1a\x76\x73\x3b\x81\xa6\xda\x23\x4b\x53\x03\x43\xf0\xc6\xd8\xac\x6d\xd2\x66\xe5\x0f\x7f\x34\xf7\xf1\xd8\x24\xb4\x3d\x68\x1b\x5f\x98\x79\x9f\x77\xde\xe7\xbd\xcd\xb0\xf3\x78\xde\x0d\x9f\xe3\x00\xaf\xf1\xe6\x00\x9d\xd7\xe8\xbc\x42\x07\x9d\x83\xee\x9b\x4e\x6b\x78\x9f\x45\x05\x76\x4e\xe9\x24\xa3\xdf\x76\xf1\x39\x89\xa6\xe9\x8c\x62\x9e\x26\x05\xc2\x3c\xa7\xcb\x49\x4c\x67\x98\x3c\xe0\xf7\x74\x91\xe0\x63\xfa\x2d\x4c\xf0\x7e\xca\x2e\x47\xd3\x69\x14\xb7\xd3\xec\xf6\xb0\x75\x16\x16\x51\x82\xe9\x22\xcc\x72\xcc\xb3\x74\x09\x8c\x8a\x30\x99\x85\x19\x9f\xf9\xa9\x8d\x8f\x8b\x70\xb5\xa2\x71\x8c\xff\xc7\x30\x4c\xd8\x63\xd4\x12\x90\xf6\xac\xdf\x69\xb6\xce\xc3\x98\x2e\xf9\x2c\x3a\x0b\xe3\x28\x5c\xe0\x24\x8b\xe8\x8c\x26\x13\x9a\xdd\xe2\xfd\xed\x5c\x3c\x1d\x25\x0f\xdf\xdb\xd3\xbc\x3d\x5b\xb7\xe9\x6c\x7d\xd8\x82\xfc\x7c\xce\x29\x9e\x45\xf1\x82\xcb\x6e\xcf\xe3\xe9\x33\xcc\xd3\x0c\x12\xeb\x8e\x3e\x4c\x52\xa6\xd5\x32\x5c\xad\xa2\xe4\xb6\x3a\x6d\x9d\xbb\xd3\x3e\xb7\x47\xed\xbd\xbc\x78\x88\x69\x6d\x2a\x76\x9e\xcd\xf9\xe8\x67\xc8\xa7\x59\xb4\x2a\x76\xab\xc2\xde\xbe\x7d\xfd\x6e\xef\xad\x11\x35\x1c\x5d\x42\xbc\x43\x41\xbf\x17\x7a\xf0\x65\x86\x75\x4e\xf1\x79\x7c\xb2\xf7\xb6\xf5\xa5\x7f\x7d\x31\xbc\xf8\xf4\x7f\x38\x19\x7e\x62\x0c\xe4\x08\x33\x9a\xbc\x28\x30\x89\x66\x51\x46\xa7\x45\x94\x26\x61\xfc\x1b\x8a\x45\x94\x23\xca\x91\x17\x59\x34\x2d\xe2\x07\x64\xd1\xed\xa2\xd8\x2b\xd2\xbd\x98\xce\x0b\x68\xe1\x3b\x93\x07\xcc\xe8\x3c\x5c\xc7\xc5\x2e\xe8\x3d\x4d\xb8\x2a\xc5\x82\xc2\x30\x16\x4e\x0b\x9a\xe5\xed\xd6\x3c\xba\x8d\x69\x81\x8c\xc6\x34\xcc\x29\xba\xed\x2e\xf6\xf6\x70\x91\xde\xd3\xe5\x84\x66\xe8\xbc\x7b\x77\xd0\x6a\x9d\xa7\xb3\x68\x1e\x09\x87\xb8\x0a\xd7\x31\x3e\xac\xb3\x22\x4d\xf0\x3e\x4f\xe3\x35\xd3\xee\x88\x86\x59\xb1\x88\xa3\xe4\xae\x9d\xd0\xe2\x10\x9d\xae\xff\xee\x00\x45\x8a\x28\x99\xc6\xeb\x19\x45\x42\xbf\x61\x15\x66\xe1\x92\x16\x34\x6b\xe5\xeb\xd5\x2a\xcd\x0a\x21\xf0\x64\xf8\x89\x69\x10\x26\x33\x76\xfb\x25\x4a\xda\xc0\x79\xf8\x80\x30\xce\x53\x4c\x28\xf2\x98\xad\x32\x7e\xc0\x52\x69\xc1\x56\x33\xa1\x45\x41\xb9\x11\x5b\xe9\x9c\x8b\x9f\xaf\xe3\x78\xef\x5b\x34\x2b\x16\xfe\x1d\xcd\x12\x3f\x5f\xae\xf3\x05\xc2\xb8\xa0\x59\x12\x16\xd1\x3d\xcd\x3d\x4c\xd6\x85\xb2\x0c\xd2\x75\xb1\x5a\x17\xcc\x9e\x17\x97\x63\x66\x93\xe4\x96\xce\xda\x2d\x3c\x3f\x6a\xfa\x77\xd4\x02\x08\x8e\x5a\x28\x51\x9a\xbf\x84\xfd\xdd\x21\xbb\x47\xdc\xf6\x72\x10\x1f\xb6\x83\x12\xfc\xf5\x0d\x6e\xc0\xbf\x7e\x8e\xea\x55\x4d\x60\x53\xd8\x7f\xfc\x2d\x29\x51\x96\x28\x05\x12\x01\xda\x6d\xf6\x4e\x3e\xf0\xb1\x25\x9f\x53\x92\xb2\x24\xa5\x91\x64\x89\x23\xe2\x6d\x89\x92\x5d\x7d\x10\xae\x5e\x40\x08\x02\xae\x17\xe0\xf3\xef\x49\xa9\x14\x06\x21\x62\x19\xbe\xf8\x0a\x3e\x7c\x2e\xc3\x87\xcf\x35\xf1\x89\xaf\x17\x69\x70\x88\x52\x7a\x07\x04\xbb\x90\x33\x08\x02\x3f\xe0\x16\xda\x21\x87\xc0\x7b\xf6\x36\x20\x84\xf8\x81\x6f\x29\x6b\xec\xb9\xc3\xcd\x54\x0a\xc0\xe7\xd6\x5f\x83\x23\x55\x11\x66\x47\xed\x82\x80\x04\x6c\x28\x11\x2b\x0f\x10\x28\x03\xd4\x2e\x3e\xf1\x95\xd1\x85\xee\x4c\x2f\x0e\x10\x40\x1a\xc6\x67\xf6\x08\xf8\x98\xc0\xb7\x0c\x6c\xa6\x41\xb3\xa6\x29\xd3\x7c\x59\xfc\xd8\xe4\xc8\xc9\xee\x5f\xc7\x00\x2e\x82\x1e\xc6\x3e\x02\x81\x7d\x04\x02\xf3\xa3\x6d\x11\x2a\x0e\xaa\x4d\xaa\x8c\x5a\xe1\x1b\x92\x6f\xd4\x96\x4e\xa4\x7d\x05\xc7\xca\xfe\x3a\x1c\x88\x34\x34\xe7\xda\x55\x4c\x78\x91\x1d\x39\x56\xfc\xe8\x41\x0a\x81\x2d\x53\x92\xc8\xbc\x57\xc8\x65\x8e\xec\xd7\x8c\x50\x99\xac\x6d\x24\x97\xc3\x18\x09\x94\x05\x77\x25\x62\xb3\x7a\x8a\x4d\x11\x7e\xd6\xad\x92\x69\xa8\x75\xb9\x75\x95\x67\xb7\xa5\xb3\x8c\x27\xf0\xa1\x43\x89\x47\x9c\x10\xf3\x42\x5b\x79\x47\xd9\xa0\xd9\xb6\x95\x95\xa3\xd4\xd4\x42\x73\x2b\x44\x57\x49\x75\x59\x15\x41\xec\xf0\xfb\x38\x72\xa3\x4b\xd8\x53\x3c\xad\x4d\xc3\xe4\x9a\x7f\x36\xfa\x6a\xf3\xa0\x6a\xc8\xd8\x19\x42\xae\x5b\x25\x81\x40\x86\x72\x2d\x7e\x1b\x62\xea\x89\xe8\x72\xd2\x4b\xc0\xd3\xa9\x42\x35\xeb\x53\x9c\x28\xbf\x09\x14\x0b\x3a\xe9\x32\x63\x93\xdd\x5a\x11\xd0\xc6\xe4\xae\x2e\x51\xd8\x72\xc8\x57\x15\x32\xd8\xd1\x51\xc6\xcd\x2b\x95\x0d\xa4\x53\xa9\xe8\x36\x29\xc0\xe7\x79\x4d\x09\x65\x0f\x2a\x94\x24\x80\x70\x0a\x63\xa5\x0d\x0e\x2d\x3c\xa3\x84\x15\xf9\x4f\x39\xb4\xb0\x80\xc0\x52\xea\xeb\x18\x53\xdf\x06\x9b\x42\x19\x35\xbc\x5a\xa6\xd9\x10\xca\x9a\x57\x68\x5e\x79\x8e\xae\x22\x3f\x95\x44\x60\xa9\xad\x53\x83\x16\x43\x4a\x34\x87\x52\xd3\x9a\x55\xd7\x60\x27\xc8\x3a\x32\xcc\xc0\xfa\x4a\xf9\xf7\x32\x61\x9a\xa4\x59\xf7\x36\x99\xa2\x54\x5d\x54\x65\xd2\xc6\xd3\x61\x40\x94\xfe\x52\x2d\x82\xad\x73\xb9\x08\xb8\x92\x05\xa0\x28\xca\x2f\x44\xd0\x95\x68\x4b\xba\x48\x69\xbb\x94\x5e\xa1\x22\xa1\xe9\xee\x09\x62\xf8\x3f\x61\x0b\x56\x96\xa5\xa2\x81\xaf\x75\x86\xa9\x29\xa8\xda\xa8\x66\xe1\x40\xaf\x14\x81\x9e\x1f\x18\x0b\x07\x35\xfc\x5f\x2b\x7e\x8d\xfe\xac\xe2\x07\xa6\xae\x6d\xf2\xaa\x2d\x91\x2b\x51\xbc\x1d\x32\xde\x43\xaf\x79\xe3\x64\x5f\x57\xb4\x60\xeb\x8a\x66\xa5\x57\xab\x29\x82\x2a\x9c\xd6\x5d\x43\xa3\xd4\x1c\x0c\xdb\x59\x9b\x08\x3f\x93\x3d\x5d\x60\x52\x2f\x7b\xd0\x45\x31\xc0\x0d\x74\x73\x17\x38\x85\xb1\x22\xa8\x2a\xcb\x11\xe7\x48\x74\x84\xd6\xe5\x5a\xa2\x95\x50\x2d\x4e\xb7\x60\x3a\x31\xbb\x21\x24\x9a\x10\xa5\x8c\x9e\x78\xa3\xbb\x9d\xc7\x8d\xca\x3e\xaa\x97\xd9\xd4\xe6\x57\x42\x4f\x45\x9e\x48\xa6\xe5\xa6\xf6\xbb\x64\x73\xb4\xc1\xb4\xa9\x94\x91\x94\x79\x02\x6d\x18\x37\x31\x28\x3f\xa9\xb7\xeb\x3a\xa4\x05\x02\x33\x38\xaf\xfb\x81\x50\x52\xee\x13\xaa\x97\x86\x4e\xfd\xb1\xbb\x5a\x1f\xe0\x34\x19\x10\x58\x4d\x1b\x13\x23\x8d\xc8\x4d\x9f\x5d\xac\x77\x2c\x2f\xf5\x1a\xf3\xbd\xc9\x7c\xb5\x8e\xcf\x54\xd7\x76\x53\x75\xb5\x80\x4d\xc5\x51\xb0\xa6\xb2\x3a\x54\xc2\x64\x7d\xa2\x94\xdb\x5a\xe1\x46\x4c\x04\x3a\x83\x6d\xc2\x34\x83\x75\x35\x55\xb5\x54\xe5\xbc\x5a\x69\xda\xd6\xaa\xd2\x47\x4c\xf3\xf3\x94\x55\xad\x12\xd1\x50\x45\x4d\x97\xb9\x79\x8f\xa2\x2d\xa8\xfa\x54\xa9\x8e\xae\xa2\xbe\xf2\x58\x5b\x25\x89\xee\x96\x4d\xe8\xf4\xdb\x50\x2d\x5d\x35\x1a\x95\xa9\x78\x32\x37\x98\xbd\xec\xaf\x4e\xc5\xa8\x2e\xdf\x29\x92\x0d\x2d\x32\x7e\xd8\x86\x8e\x9b\xb8\x75\xeb\x89\xed\xc4\x13\xc8\xba\x6e\xb5\x9d\x8a\xf9\x73\x7e\x23\xf2\x64\xd5\xb9\x89\xce\x77\x2f\xec\xae\x55\x63\xd5\x03\xea\xc8\xf4\x5f\x2a\x08\xd5\x51\x0b\x77\xcc\x8a\x73\x9b\x4d\xa6\x6e\x51\xed\xa8\x60\x33\xeb\x8d\x9a\xd2\xec\x91\x06\xf1\x91\x90\xc5\x16\x85\x83\x17\xaa\xc6\xc9\xd6\xfc\x8a\x88\x8a\x94\x8a\x20\x47\x96\x9b\x3e\x1a\x4a\xdf\xa1\x0c\x83\x86\x8a\xf7\x43\xeb\xaf\x65\x03\x8b\x1e\x22\x3b\x11\x5f\x96\x3b\x55\xed\x5c\x6b\xcb\x83\x11\xb5\x5b\x13\x05\xee\x3d\xde\x57\x8e\xd4\xf4\x81\xd3\xc6\x28\xd5\xb1\xaa\x8c\xa7\xaa\x62\x45\xca\x21\x0e\xad\x67\xbe\x13\x93\x55\xce\x2f\x45\x99\xf3\x55\x65\x6b\xbe\xd6\xfa\xa5\x1d\xb2\x4b\x54\x62\xf2\x49\xe0\xc4\x1f\x43\x68\x68\xf3\x1a\x26\xdb\xad\xe6\x53\x7b\x01\x3d\xd9\xe4\xce\xed\x37\x12\x4d\xc8\xdb\x17\xd0\x47\xd4\x7e\xe2\xc8\x64\x7b\xb5\x1b\xc2\xaa\x5e\x00\x75\x46\x2f\x03\xf5\xa6\xe4\xa1\x2f\xb3\xc6\x51\xab\x73\xb0\x0f\x5c\x5c\xee\x7d\xb8\x1e\xf4\xff\xc0\xe8\xaa\xff\x71\xb0\xf9\xa4\xb9\xf3\xe6\x25\x30\xba\x3c\x19\xe3\xf4\xcf\xab\xd3\xc1\xc5\xb6\xad\x0b\xff\xb6\x76\x70\xd1\x79\x77\x00\x9c\xf5\xc7\xc3\x0b\x7c\xec\x5f\x0d\xc7\xfd\x33\x9c\x0d\xc6\xe3\xc1\x35\xfa\xf8\x32\x1c\x9f\xe2\x78\xd8\x1f\x5c\x0f\x46\xc3\xd1\xaf\xb9\x52\xb7\xf3\x6a\x03\xce\xe5\x76\x38\x5b\x7a\x5d\xb7\xbb\xbf\x01\xe7\xf3\xe3\x38\x3f\xe8\xa0\xdd\xee\x4b\x85\x33\x3a\xef\x9f\x69\x94\xd1\x69\xff\xfa\x0a\xa3\x9f\xf5\x84\x6e\xf7\x6d\xa3\xd8\x2d\xc9\xd8\x32\x40\xba\xaf\x0e\x1a\x51\x7e\x9c\x8a\xc7\x22\xa9\xfb\xba\xdb\x88\xf2\x6b\x44\xb8\x6b\xd9\xff\xbe\xff\xfa\x78\x1f\x38\x1d\x7c\xb8\x1e\x7c\xd1\xf6\x3a\x1b\x9c\x34\x97\xb6\x52\x57\x24\x41\x03\x36\x6c\x71\xb9\xdc\x8e\x2b\xf7\xc3\x60\x2c\xa9\xd5\x1d\x4c\x29\x6e\x4b\xb3\x78\x95\xc3\x45\xe0\xa1\x24\x6a\xf7\x44\xec\x9a\x5f\x01\xea\xba\x40\x9f\x86\xe7\x83\x33\x59\x75\xf4\xd1\x5f\x59\x05\xb2\x71\x74\x9d\xe0\x3f\xa6\xd4\x4e\xec\x38\xc8\x4b\x17\xe4\xb8\x7f\xc6\xd7\x23\x55\xd3\xd9\x02\xfa\xa0\xd8\x2a\x48\xee\x3d\x29\xd1\x04\xf2\xca\x05\x39\x1d\x34\x20\xe8\xa3\x68\x02\x7b\x3b\x67\xee\xeb\xe7\x34\x1a\xe1\xb5\x8b\x70\xd3\xbf\xa9\x9c\x73\x55\x9b\x6e\x73\xad\x14\x74\x2e\xea\xc0\x15\xf5\x9f\xfe\x9f\xc3\x8b\x96\x52\x97\x0b\x0c\xa4\x17\x49\x93\xea\x9e\xcf\xbd\xaf\xb6\x80\x16\xc8\x9b\xba\x45\x5c\xa3\xb7\xc5\x21\x56\xdd\x0c\x5b\x9a\xe4\xad\x0b\x31\x96\x10\x26\x0d\x95\x6d\x94\xfc\xe7\x03\x23\xd8\x42\x21\x7a\xcf\x57\x4a\xbd\xca\x46\x3f\x7d\xe7\x02\xfd\x79\x79\xdc\x68\x7b\x53\x70\xaa\x57\x23\xaa\xef\x8a\x3a\x19\x5e\xf4\xcf\xf0\x47\xff\xa4\xd1\x23\xdb\x4f\x7b\xa4\xeb\x9d\x12\xe8\x83\x0b\x64\x41\xc0\x20\x04\xb6\x20\x2b\xac\xb4\xcb\xda\xe9\x4d\x0b\xff\xe8\x0a\x3f\xeb\x9f\x0f\x8e\x5b\x28\x7b\xa5\xb3\x00\xa5\xbf\x3e\x14\x32\x3f\xbe\xd4\x7e\x7d\xd1\xe2\x8f\x9b\x8d\x74\x3e\x38\x37\x46\xb2\x5c\xe8\x57\xe9\x1d\xb8\x70\x15\xa0\x27\x5d\xd5\x80\x94\xa5\x8b\xa1\x20\x4e\x9a\x57\x74\xf1\xf9\x62\xab\x18\xb6\xfc\x4b\x08\x1c\xd4\x72\xbf\x10\xa5\xcb\xaf\x11\x66\x88\xb5\x68\xad\x1c\x49\x70\x81\xb5\xa4\x3f\xea\x9f\x0f\xfe\x38\xdd\xde\x0e\x44\xee\xf3\x9b\xfc\x46\xa3\xd4\x32\xbe\xc8\x3c\x32\x66\xc5\x86\x4f\x9f\x45\xf3\x7b\xad\x7d\x80\xaf\x96\x5b\xba\x87\xd9\x5c\x7a\x2d\xd5\x0b\x2b\x5f\x99\x5c\x0c\x75\x38\xa3\x8f\xcb\x89\x39\x50\x23\x65\x59\xa9\x00\x56\x58\x29\x84\x5a\x9e\xbf\x72\xf3\xbc\xed\x90\x01\x6b\x12\xad\xb8\xaa\x04\x56\xb3\xa7\x0c\x6a\x79\x5e\xac\x61\x3c\xea\x1f\x0f\x2b\x86\xe2\xa9\xcd\x72\x43\xdf\x57\x5b\x29\xdf\x37\xbb\x2a\xa8\x72\x5d\xda\x20\xb5\x0a\xa0\xc4\xab\xe4\xd9\x56\xe6\xb7\x02\xd7\x3a\x20\x26\x8c\x0e\xb9\x79\x53\x7c\xd4\xb7\xb8\x1c\xaa\x56\x07\xfe\x7d\x79\x52\xa5\xc3\x29\x8c\xd6\x92\x4a\x52\x3e\xbe\x8e\x5a\x05\xb8\x1e\x8c\x4e\x37\x4b\x77\x68\xad\x32\x5c\x77\xa7\x5a\xda\x1f\x9d\x0a\x67\x45\x7d\xef\x8d\xca\x99\xbc\x79\xf2\x79\x96\xb3\x7e\xa4\x27\xb5\xc3\x00\x8d\x57\xab\x0d\x63\x5e\xe2\xed\xe5\xc0\xf6\xde\x6a\x08\x92\xca\x0f\x3e\xa4\xa1\x6e\x0a\xa0\xee\x9b\x6e\x07\x18\x8d\xfb\xd7\xb8\x3c\xc1\x71\xff\x66\x78\x5c\x39\x8c\xf8\x81\xff\xf9\x63\x6f\xff\xfb\xfe\xfe\x7e\x17\x68\x85\x31\x5d\x2d\xd0\x43\xe1\x61\x42\x0b\xff\x9e\x16\xe8\x61\xea\xe1\x36\x5a\xd2\x18\x3d\xcc\x3c\xcc\xc2\x98\xbf\xcd\x3d\x2c\x28\x7a\xb8\xf7\x70\x1f\xde\xa3\x87\xb5\x87\x7f\xc2\x87\x28\x41\x0f\xff\x30\xf9\x0b\x3e\xec\x2f\x0f\x05\xbf\x79\xf0\xf0\x90\xce\xd0\xc3\xc2\xc3\x5d\x38\xf7\xa7\x8b\x70\x8e\x1e\xe6\x1e\xe6\x51\x12\xc6\xec\x1d\x7a\x88\x3d\xc4\xe1\x92\xb2\x71\x77\x1e\x96\x74\x89\x1e\x92\xa3\x96\x18\x22\x1e\x53\x0f\xc9\x9a\xa1\x4c\xd4\x54\xf1\x18\x79\xc8\xc3\x25\xbd\x63\xfa\x7f\xf7\x20\x55\xb9\xf5\xb0\xa2\xfe\x9c\x69\xba\xf2\xb8\x6d\xc4\x9c\x15\x7b\xf3\x9b\x87\x22\x0f\x67\x11\x7a\x58\x2a\x61\xea\x45\xdb\xc3\xdf\x29\x53\x89\x7a\xc8\x68\xce\xa4\x66\x1e\xf2\x45\x94\xf8\x39\x97\x1c\xe2\xa8\x55\xf0\x95\x7b\x98\xa6\xcb\x65\x88\x1e\x5e\x30\xb4\x2c\xe2\xeb\xf4\x3d\xe4\x74\x19\x4d\xd3\x38\x65\xc3\xbf\x7a\xc8\xe3\x90\xcb\xf9\xdb\x43\xb8\x4a\xf3\x22\x4b\x57\xdc\x84\xdf\xb8\x5e\xa3\x22\xcc\x90\xce\x71\x1c\xde\x47\x6c\xfe\xbf\xf0\xb3\x1f\x4d\xe9\x4b\x8b\xd2\xd0\xa6\x74\x62\x28\xbd\x35\x94\xce\x24\xa5\x0b\x45\xe9\x7d\x23\xa5\x53\x45\x69\xa1\x28\x7d\xa8\x50\x7a\x57\xa5\x74\x6e\x28\x8d\x15\xa5\xcb\x0d\x94\x26\x9b\x29\xa5\x9a\x52\xf2\x18\xa5\x6b\x43\xe9\x5f\x2e\xa5\xdf\x14\xa5\x7f\x6f\xa0\x34\xd7\x94\x7e\xff\x69\xe3\x5b\x34\xfc\x6f\x29\xfd\x6f\x00\x00\x00\xff\xff\x0a\x39\xf3\x83\xf4\x2a\x00\x00") + +func fontsIvritFlfBytes() ([]byte, error) { + return bindataRead( + _fontsIvritFlf, + "fonts/ivrit.flf", + ) +} + +func fontsIvritFlf() (*asset, error) { + bytes, err := fontsIvritFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/ivrit.flf", size: 10996, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsJazmineFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x59\x4f\x8f\xdb\xb8\x0e\x3f\x8f\x3f\x05\x51\x3c\x40\x78\x40\x1f\xf1\xda\x93\xd6\xa7\x7c\x04\x5f\x7d\x73\x5c\x39\x9d\x6c\x33\xc3\x6e\x26\xd3\xc5\xee\xa7\x5f\x88\x14\x65\xc9\x96\xed\x78\x66\x80\x4d\x1b\x8b\x56\x6c\x92\xa2\xf8\xe7\x47\xcd\xe9\x72\xfa\x7a\xfc\x0f\x7c\xf9\x3f\xff\xff\x0a\xff\xfb\x02\xbf\x55\xd5\xc3\xc3\xc3\x03\xc0\xef\xc7\xbf\x9f\xce\xcf\x03\x9e\x2e\xa7\xaa\x7a\x00\xfe\xfc\x39\x5c\x2e\x9f\xe1\xf6\x38\x00\xd0\xf5\xfc\xfd\xfc\x7c\xbc\xc0\x75\xf8\xe3\x75\x78\xb9\x0d\x57\x78\x3a\x7f\x7f\xbc\xc1\x33\xdd\xe0\xf1\xf8\x6b\x80\xcb\xf9\xc7\xe0\xf4\x4d\xff\xce\xcb\xf9\x3b\x9c\xc1\x9d\x9d\xbb\x0c\x0e\x4e\x74\x85\xc7\xe1\xfa\x19\xfa\xd7\x9b\x9f\x1e\xbe\x9d\xdd\xe0\xe0\x46\xf0\x74\xfc\x31\xc0\xd1\xab\x01\x27\x7a\xbe\x01\xbd\xde\x80\x4e\x70\xbe\x21\xbc\x90\xe7\x74\x1d\x10\xea\xff\xb2\xa2\xc2\x1d\x7e\x1d\x9f\x7e\xfe\x75\x3d\x1c\xbf\xbd\x60\xff\x8a\x83\x7b\xad\x2a\x80\xc3\xe2\xb7\xae\xe3\xd7\x4f\xc0\xa1\xb2\x76\x7e\xe9\x8c\x52\x88\xe8\x1f\xae\xe5\xc2\xaf\xf8\x9f\xc0\xff\x66\xc0\x80\xce\xcc\xaf\xb5\xbe\xa5\x57\xf9\x21\x3e\x91\x13\x68\x11\x2d\x7a\xd1\xb6\x33\xd6\x14\x67\x6a\x44\xff\x5f\xd8\x45\xbe\x29\xeb\x74\xb4\x81\x6f\x23\x4c\x5a\xab\xf3\xad\xdc\x13\x09\x4f\x0b\xc2\x12\x13\xd6\xa9\xae\xae\x07\x40\x12\x7b\x20\xc9\x8a\xfd\xe8\x09\x1e\xbd\x14\x32\x40\xfe\x19\x7f\x1f\xec\xc6\x1c\x57\x74\xcd\xcd\x60\x83\x19\xa8\x21\xf4\x44\x4b\x88\x62\x6a\x02\xe0\x99\xae\xb5\x0d\x4b\x15\x95\x83\xce\x73\xd6\x87\x8a\x37\x47\xf7\x66\x76\x89\x9b\x19\x77\x94\x57\x07\x8e\x99\x5b\x13\x36\x38\x1b\x44\x15\x68\x51\xe4\x77\x24\x7c\xe2\xfa\x0e\x87\x8a\xc2\x33\x5d\x2f\x92\x3a\x2b\x02\xb3\x01\x79\xc0\x06\xd8\x54\xbc\x88\x74\x09\x2b\xfb\x48\x68\x59\x4d\xb1\xc2\xa1\xc2\x46\xf6\xf1\x13\x58\xf8\xe4\xef\xf3\xfd\x9b\xee\xe3\x9c\x61\x64\x4c\x96\x77\x6e\x3a\x2f\xc6\x2d\x33\x5c\xb9\x48\xf8\x34\x6c\xa6\x2c\x68\x72\x1d\xf2\x91\xfc\xa7\x30\x3f\x91\xbd\x4b\x07\xb5\x46\xae\x43\x60\x8e\x41\xda\x9a\x3f\x8b\x66\x46\xe3\x13\x27\x6e\x5c\xf2\x67\xa4\xa6\x25\x14\xbf\x41\xe2\x6c\x02\xd8\x18\x26\xd0\x19\x76\x02\xcb\x21\x12\x22\xb0\x09\x61\x8d\x2b\x61\xed\xd9\x46\xa7\x2e\x5c\xea\x42\x86\xca\xb5\xf1\xb7\xea\x8e\x22\x12\xfd\x10\xdd\x5d\xc2\x2c\xec\x01\xca\xe7\xce\x85\x26\xac\x51\x58\xfb\x89\x5e\x7f\xaa\xf7\x2c\x34\x6e\x0f\x5a\x21\x9c\x11\x82\x2d\x07\x87\xaa\x49\xfd\xc4\x42\x4a\xd4\x1c\x8d\x1b\xac\x49\xdf\xb7\x3a\x63\x7f\x16\x4c\xe4\xe3\x73\xaf\xd6\xf8\x73\xdc\x79\x35\xa8\xce\x98\xc0\xda\x67\x91\x37\xb0\xa6\x64\xd5\x1f\xec\xaf\x80\x8d\xa4\x34\x6f\x44\x9b\x7b\xf0\x3b\xb5\x5e\x60\x14\xfd\xe1\x4d\xb6\x9e\x05\xf9\x76\xcc\x6f\xbd\xb2\x9c\xaa\x82\xad\x83\xa9\xd5\xd2\xde\xb7\x43\x9e\xc7\x90\xe8\xd9\xdb\xeb\xac\xdc\xad\xe6\xdf\x72\xce\x9b\xde\xaf\xe5\x3e\xd1\x24\x56\x1c\x52\x4d\x82\x2b\xa3\x04\x22\x4a\xb9\xc4\x10\xea\xe2\x11\x8b\x0c\xd3\x3d\xeb\xba\x31\x1a\x90\x1a\x09\xc6\x66\x56\xb2\xc7\x42\x81\x9b\x9e\x06\x4e\x58\x7b\x6d\x50\x32\xa3\x0b\x99\x11\x2c\xb1\x0c\xcf\x0e\x71\xa7\xa7\x45\x9d\x30\x5a\x0f\x1b\x2d\xba\xbe\xd0\x0a\x49\x3e\x77\xc4\xe2\x2b\xb3\x42\x81\x1d\xa3\x25\x49\x7b\x89\xb0\x4c\x1c\x7b\x84\x26\x0d\xab\x59\x83\xac\xaa\x2c\x73\xbd\x52\x21\x4d\x53\xb6\xa0\x64\x45\x29\xb5\x50\x48\x84\xc7\x98\x57\x32\x62\x7f\x7e\x25\x0a\x7e\x63\xbd\xee\x2a\xa3\xb3\x53\x61\x1c\x98\x5e\x71\x71\x22\xbc\x63\x93\x47\xad\x51\x7d\xb4\x27\x92\x9f\x9a\xa9\xfa\x3b\xab\x42\x0c\x0f\xab\xeb\xb0\x81\x75\x9c\x99\x13\x75\xee\xf3\xdb\x45\xbb\x60\xeb\xb1\x60\x64\xb9\x8b\xb5\xb6\x1a\xa7\x91\x40\xcc\x7d\xc5\xab\x08\x94\x79\x03\x71\xa9\xb5\x13\x0f\x99\x53\xa2\x7c\xea\x92\x13\x5f\x39\x54\xa2\xda\xfc\x2b\x2f\x8d\x4d\x8e\x84\x40\x00\x77\xa5\x6b\x40\x05\x71\x1b\x0a\x1d\x0b\x25\x0b\x61\xdf\x20\x4b\xbd\x51\x73\x8f\x1e\x6f\x53\xa2\x96\x36\x60\xb5\x63\xa1\xcc\x33\x56\xc6\x0c\xa0\x2c\xe7\xb1\xc8\x92\xad\xd3\x03\x80\x63\xbb\x74\x3d\x03\x0a\xcf\xb0\x23\x93\x6c\x74\x4e\x89\xcb\xac\x98\x3d\x95\x11\x45\xa8\x84\xc0\xac\xeb\x95\x6b\xd7\xdb\x34\xc4\xa6\x7b\xba\xc7\x23\xcb\xc4\xae\x64\x39\xcb\x5e\x50\xc8\x5e\x69\x0c\x65\x54\x3d\x05\x15\x45\xd3\x8c\x0b\x18\xd5\x9c\x52\x0e\x95\xea\x7a\x3b\xa6\xfc\x46\x97\x51\x6f\xa5\xc8\x37\xe6\xe1\xbb\x63\xab\xb8\x13\x9a\xb6\xe6\x88\x71\xef\x4e\xa4\xe5\xde\x16\xdb\xb2\x3d\xed\xd8\xd4\x21\x3f\xde\x6b\x92\x80\x2a\x84\x4c\xc7\x41\x66\x42\xf7\x2b\x7d\xb4\x37\x8e\x51\x20\x93\xb7\xe9\xe5\x0d\x8d\x52\x12\x31\x69\x36\x0e\xa4\xeb\x55\xa6\xc7\xae\x41\xa8\x47\xaf\x26\x5a\x29\x2b\x54\x4b\x75\x3c\x49\xce\x41\xef\x51\xf1\xde\x19\xc5\x80\x8c\x8f\x15\x36\x08\x56\x96\x52\xc6\xcd\xb7\xe6\x8a\x2d\x71\xb2\x34\x12\x53\xa9\xa1\xcc\x3b\xb7\x3b\x05\x8c\x2e\x74\x5e\xba\x04\x5d\x80\x0b\x6d\x81\xbb\xa7\xbb\x4b\x9b\xa3\xfb\x86\x84\xe7\xf4\x04\x83\x55\xc4\x18\x35\xa4\x88\x00\x02\xa9\x78\x35\xe0\xb7\x88\x61\x15\xc5\xd6\x33\xcb\x66\x5e\x33\xae\xbd\x74\xcc\x52\x18\x42\xc9\x9d\xe9\x8a\xaa\x03\x3a\x23\x88\xde\x3b\xd5\xd8\xc1\x42\x8a\x7a\x17\xa8\x82\x86\x33\x0f\xdf\x33\xd0\x92\x5d\x19\x59\xb1\x13\xcd\x7a\x1b\x55\x64\xf9\xcc\x23\x27\x62\x66\x43\x45\x23\x0b\x18\x67\x0b\x99\x15\x80\xe9\x72\xf9\xda\x7d\x14\xb0\xa4\x35\x73\x34\x4a\xec\x6d\x1a\x92\xa4\x1d\x09\x66\xfd\xfe\x64\xb9\xae\x75\xb4\x75\x04\xc8\x2d\xe9\x39\xec\x06\x6b\x8e\xe6\x58\xcf\x7c\xa9\x6b\x60\xbc\xcb\x87\x34\x79\xcc\x02\x73\xdb\xae\x2b\xde\x20\x40\xd7\x9b\x03\xc7\xce\xef\xad\xde\x10\x89\x0d\x54\xc4\xa9\x3a\x50\x74\xdf\x09\xd8\xe6\x2b\x82\x7a\xc3\x99\xc1\xfa\x02\xf8\xb8\x50\x56\xa2\x87\xc3\xa1\xf9\xb7\x9a\xad\xd6\x4f\xbb\xcb\x20\xbd\x08\xd4\xa7\xa9\x65\xa4\x88\x5a\x8a\x27\x2a\x36\x1a\x70\x46\x49\x01\xdc\x80\x36\x85\xe3\x08\x17\x99\xc7\x5e\x30\x1d\x73\x20\x5f\x2a\x48\xfb\xbd\xea\xc3\x12\x41\xee\x55\xca\xda\x42\x60\x6d\x21\xb0\x56\xfc\xfa\x91\xb1\xb0\xd0\xfd\x15\x2c\x3c\xb2\xed\x4c\xa1\xbf\xd9\x3e\x9f\x59\xd1\xb5\xed\x51\x6b\xa9\x69\xfb\x7d\xf9\x50\x9a\x43\x05\x1f\x3e\x72\x6c\x93\xdc\x65\x43\x5a\x93\xef\xca\x2c\x2b\xa8\xf4\xbd\x3e\x10\x59\xb7\xf1\x88\xb2\x47\x85\x84\x6d\x13\x01\xe1\xc6\xb9\x45\x16\x67\x53\x5a\x70\x5b\x14\x83\x0d\x46\x49\x1e\x2f\xa8\x30\xc3\xdf\x88\xdb\x26\x08\x34\xa7\x57\xd7\xd4\x11\x00\x05\x80\x18\xc0\x9c\x33\xf2\x27\x25\x32\x3e\xdb\xdc\xdb\x43\xee\xdf\x89\xbb\x73\x7c\xc9\x0d\x63\x53\x84\x4e\xca\x92\xe6\xca\xbb\x0a\x1c\x6a\xc0\x2a\xc6\x01\x39\x3b\x02\x85\xdb\x53\xe4\xd9\x89\xd7\xd7\x39\x42\x4a\x33\xeb\x34\xeb\x66\x99\xb6\x8b\x87\xfe\xf2\xa8\xfc\x59\x8e\x02\x8a\x6e\x71\x86\x1e\x31\x1e\x90\xe0\xdc\xed\x59\x49\xdf\x8f\x98\x1d\x98\x71\xa4\x0a\x69\x3a\x4d\xd8\x85\x7f\xff\xf6\xe4\x3f\x01\x00\x00\xff\xff\x6f\x29\x93\x28\x3c\x20\x00\x00") + +func fontsJazmineFlfBytes() ([]byte, error) { + return bindataRead( + _fontsJazmineFlf, + "fonts/jazmine.flf", + ) +} + +func fontsJazmineFlf() (*asset, error) { + bytes, err := fontsJazmineFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/jazmine.flf", size: 8252, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsJerusalemFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x6d\x6f\xe3\xb8\x11\xfe\xce\x5f\xf1\x60\x11\x34\xf6\x35\x31\xcf\xb7\xbd\x3d\xdc\xde\x66\xa1\xa2\x7b\xd7\xf6\x80\x7e\x28\xae\xd8\x7e\x21\xc0\xa5\x2d\xca\xd2\x45\x96\x5c\x49\x4e\xe2\x05\xd1\xdf\x5e\xf0\x4d\x22\x65\x39\xf6\x6e\x13\x04\x12\x65\x91\x33\xc3\x99\x67\xde\xa8\xac\xcc\xbe\x13\x57\xf8\x01\x6f\xb0\xfc\xf6\x5b\x2c\xbf\xc7\xeb\x25\x96\xe4\x57\xd9\xec\x5b\x51\xca\x2d\x56\x07\xfc\x55\xa6\xa2\x2c\x44\x8e\x5f\x9a\x42\xa6\xb2\x5a\xc9\x66\x83\x5b\xac\x44\x2b\x53\xd4\x15\x7e\xeb\x44\x95\x8a\x26\x35\x73\x17\xf8\x4b\x2e\x76\x3b\x59\x96\xf8\x03\xfe\x2e\x2a\xfd\x58\x90\x7f\xee\x65\xdb\x15\x75\xd5\x42\x54\x29\xd6\xf5\x76\x2b\xab\xae\x45\x23\x37\xa2\x49\x8b\x6a\x83\xdf\x3d\xc3\x45\x56\x66\xe8\x6a\x6c\x32\xcb\x2c\xa9\x0e\x4f\x8b\x75\xbb\x48\xf7\x0b\x99\xee\xc9\x3f\xea\xb4\xc8\x0a\x99\x22\xab\x1b\x64\xc5\xa6\x94\x1d\xbe\x5b\x2c\x0d\xeb\x52\x56\xd5\xc0\x7d\xf9\x06\x1f\xe4\x1a\xcb\x1f\x7f\x7c\x4d\x3e\x88\x4e\xbe\xc5\xf2\x35\x7e\x91\x2b\xfd\xcb\x9f\x08\xf9\xf9\x69\x57\x8a\x4a\x68\xa1\x50\x67\xc8\x8a\xa6\xed\x50\x16\x95\x7c\x4b\xb4\x4e\x70\x8b\x57\x5b\xb1\x29\xd6\xa8\xf6\xdb\x95\x6c\x5e\x39\x86\xa5\x44\x91\xca\xaa\x2b\xb2\x62\x6d\x16\x13\x01\x00\xb7\x68\xf3\x7a\x5f\xa6\x10\xe5\xa3\x38\xb4\x58\x49\x7c\x12\xd7\x37\x66\x51\x55\x3f\x92\x2b\x3b\xa9\xcb\x25\x5e\xe5\xa2\x49\x57\xa5\xa8\xee\x5f\xe1\xf6\x16\xbb\xa6\xd0\x9a\x10\x2d\x04\xcc\xaf\x37\x58\xed\x3b\xac\x45\x75\xdd\x69\x32\xed\x76\xdf\xe6\x32\x25\x3f\x58\x0a\xb9\x2c\x36\x79\xa7\x25\x16\x58\xe7\xa2\x11\xeb\x4e\x36\xe4\xcd\x33\x2f\x6f\x50\xd5\x1d\x8a\x6a\x5d\xee\x8d\xa6\x53\xd9\xae\x65\x95\xca\xa6\x25\xda\xe2\xb8\x05\xb6\xe2\xc9\x6c\x1d\xa5\xac\x36\x5d\x8e\x99\x7c\xf2\xb3\x9d\xa9\xcc\xeb\x76\x8e\x3f\x42\x20\xdb\xa7\x1b\x89\x4c\xac\xbb\xba\x21\xcb\xef\x0d\xe7\x54\x66\x62\x5f\x76\x56\xda\x6d\x9d\x4a\xb3\xf3\x2e\x2f\x5a\x64\x75\xd5\x91\xd7\x4b\x33\xcd\xea\x52\x0b\x18\xd1\x25\x4b\x2b\xbf\xd1\x05\x1a\xbd\x89\xdb\xae\xbe\x2d\x65\xd6\x61\x16\x18\xb9\x6e\x50\x8a\x4e\x13\xa8\xca\xc3\x9c\x90\xbf\xc9\x55\x23\x1f\x71\x2f\x0f\xab\x5a\xe3\x6f\x2b\x76\xed\x5b\x42\xfe\x5c\x96\x58\x8b\x5d\xd1\x89\x12\xa5\xec\x3a\xd9\xb4\x8e\xb4\xd6\xbf\xac\x36\x65\xd1\xe6\x83\x82\x9c\xa8\xa2\xd3\x84\x16\x80\x5e\x6e\x05\x6d\x41\x34\x5c\xdb\xc3\x76\x55\x97\x2d\x44\x23\x0d\x85\x56\x6c\x25\x8a\x4a\xff\x5b\x09\xe8\xcf\x8e\xa6\x7c\x5a\xcb\x5d\xe7\x08\xd6\xad\xd4\xa8\x78\xac\x90\xcb\x46\x2e\xc8\xbf\x72\x89\x6f\x1c\xb1\xc8\xec\xbf\xca\x47\xbd\xb8\xed\x44\x83\xd9\x6f\xfa\x5a\x67\xf8\x20\x1e\x8a\x74\xbe\x20\xff\xce\x0d\xe6\x2a\x07\xf6\x1b\x74\x87\x9d\xc4\x7f\xb5\xdf\x09\x6b\xb4\xd5\x01\x45\xd7\x4a\xeb\x36\xad\x94\x56\xed\x65\xd1\x76\x6f\x09\x11\xa5\xdc\xe5\x00\xee\xd0\x41\xe1\xb3\x38\x14\x15\xcc\xe3\x67\x28\x94\x62\x2b\x53\xf3\x74\x0f\x85\xe1\xdd\x06\x0a\x6d\x5e\x54\xb4\xd5\xbf\xdc\x41\x90\x95\xec\xe8\x83\xec\x70\x87\x35\x14\xd6\xb9\xec\x60\xa7\xfe\x0e\x85\xad\xdc\xba\xa7\x0a\x0a\x3b\x79\xa0\x99\x3c\xe0\x0e\x3b\x28\x74\x22\xa3\xad\xc8\xcc\xdb\x1b\xb2\x29\xb6\x5b\x59\xea\x71\xaa\xdf\x39\x2a\xb8\xc3\x01\x0a\x59\x51\x89\x12\xaf\x70\x87\x3a\x7a\xfa\x09\x0a\x37\x33\x0d\x18\x31\xd7\x73\xaf\x49\x2a\x4a\x27\x77\x0b\x85\xc3\x3e\xf5\x64\x72\x28\x54\xfb\xca\x3d\xad\x34\x8f\xcf\x42\xa4\x85\x7e\xda\x42\x61\x31\xdb\xc9\xa6\xa8\xd3\x39\xee\x40\x49\x2e\x0e\x6e\xe6\x03\x14\xee\x45\x46\xd7\xb9\xc8\x70\x87\x2c\xe2\x5f\x44\x4f\x0b\x28\xfc\x04\xff\x77\x87\x4f\xe4\x41\x3c\xb8\xf1\x3e\x98\x89\x3b\x94\x5a\x8d\x62\x2b\xef\x73\xfd\xf4\xa4\x79\xec\x33\x37\x55\x42\x81\x06\x64\xfe\x63\xe0\x21\xda\x4e\x36\x45\x7b\x8f\xd9\x37\x73\x14\x1a\x1b\x11\x1c\xec\x64\x85\x46\xb6\xb9\x5d\xd6\x40\xe1\x7a\x26\x76\x75\xdb\x2d\xf4\xa6\x1e\x09\xb9\x4a\x8e\xff\x13\x02\x20\x21\xe0\x48\x88\x82\xf2\x17\xae\x12\x32\xe3\x73\xfb\xd6\x5c\xdd\x2c\x3d\x6f\x06\x05\xfd\xea\x23\x3e\xea\x1f\x71\x85\xf0\x16\xac\xf0\xcb\x00\x6e\xfe\x0d\x09\x05\xa5\xa0\x0c\x3f\x0e\x2c\x16\x00\x57\x76\xac\xff\xf4\x18\x50\x5c\x29\xae\x7a\x7a\x11\x51\x7d\xe3\xe6\xa6\xa0\x90\x10\x0a\xae\x05\x65\x9c\x83\x69\xd9\x00\xaa\xdf\x71\x35\x88\x61\x24\x07\xe7\x66\x4f\xd4\xbc\x07\x05\xd5\xbf\x53\x50\x2d\x0a\xe5\xd4\x6f\x37\x96\xdf\x70\xe3\x4e\xf6\x19\x38\xe6\xb0\xcb\x38\x18\x65\x5a\x5d\x33\xfe\x1e\x78\x97\x10\x30\xce\x39\x65\x34\x58\xeb\x95\x3b\xba\x58\x1d\xce\x13\xa2\xa8\x67\x65\xd9\x58\x79\x8c\x0d\x10\x5f\xc1\x38\xeb\xa7\x72\xb3\x7d\x06\xe6\x94\x10\x5f\x29\xa7\xd1\xce\xe1\x17\x51\xa6\x39\x30\x58\x0d\x51\xad\x11\xa6\xdf\x33\x1a\xcc\xeb\xa5\x8f\x07\x81\xf1\xbc\xe5\x06\x53\x85\x93\x8f\x2d\x6f\xfe\xcc\x58\xe9\x27\xc0\x2e\xd3\x4f\x56\x6a\x3e\x8c\x15\xe7\x9a\x9c\xb2\xa4\xc7\x96\x1f\x0b\xe5\x4d\xeb\x18\x28\x33\xb0\x2b\xaf\x30\x2d\x94\x99\x6e\xf6\x93\x10\xb5\x30\x52\x38\xc5\x81\x52\xa7\x4e\x4a\x7b\x74\xd9\x15\x66\x8b\x67\xcc\x39\xf2\x95\x00\x38\x1e\x2d\xce\x96\xde\xc9\xb8\xe5\x6c\x40\x33\x16\xd5\x11\xa5\x83\x3f\xf6\x4e\x39\xe6\xc1\x1d\x0f\xbd\x79\x0b\x08\xed\x0e\x86\xb4\x76\x0c\x3a\xd2\xcb\x91\x3a\x43\xe5\x59\x8f\xd0\x16\x66\xee\xd5\xdc\x1b\xe5\x58\xc6\xd0\xb1\xcc\xc8\xfa\xf5\x30\x72\x54\x7b\xa0\x8c\x90\x72\x62\x1b\x30\x08\x08\xf7\x73\x5e\x0c\xbb\x69\xa0\xf7\x67\x43\xe8\xda\xeb\x7c\xe6\xf4\x31\xa9\xea\x29\x35\x58\x84\xfa\x08\x61\xee\x86\x34\xa7\xd3\xa8\x0a\x4d\x6d\x43\x44\x64\xf3\x4b\xf8\x4f\x40\x25\x58\x76\xe3\x25\x9a\x84\xca\x08\x84\xd3\x70\xec\x37\x69\x03\xbd\x77\x44\x63\xa7\xc1\xf5\x14\x3c\x4c\x82\x11\x57\x93\x41\xca\xaa\xc7\x45\x21\x66\x43\xc9\x29\x5f\x3d\x72\xd1\x73\xbe\x3a\x0a\x72\x4c\x87\x76\xc7\xb6\xd7\x41\x98\x97\x3c\x75\x33\xcf\x4e\xb4\x29\x80\x18\x3d\x4e\xe4\xa5\x3e\x38\xc1\x19\xd9\xe3\x4d\xef\x8b\x7f\x72\xca\xc1\xcc\xfb\xa9\xb1\x83\x95\x98\x39\x24\x8e\xa9\x19\x47\x80\xc3\x0e\x43\x4f\x58\x8f\x9d\x3f\x5a\x1e\x16\x49\xbd\xce\x9e\x77\x07\x03\x27\x6d\x31\x1f\x42\x2e\x73\x07\x1b\x73\x0d\x4f\xb7\x15\xef\xa5\xee\x15\x3b\x13\x15\x30\x62\x3b\x8a\x5c\xcf\xf2\x1f\x80\xe6\xed\xad\xa3\x40\xc4\xff\xb2\xa8\x84\x41\x7e\x1f\x65\x3c\x21\xae\xf0\xac\x3b\x1e\xef\xdf\xd5\x38\x41\xe4\x3d\xc9\x1f\xfd\xec\xf1\xb6\x8d\x95\x6d\x34\x8e\xf2\xd4\x04\x1a\x6d\xe0\x73\x09\xdc\x65\xf3\x80\xe7\x91\xab\x70\x37\x70\x69\x11\x17\xe5\x8a\xa8\xbc\xd1\xd9\xcb\x16\x10\xd7\xc6\x3b\x15\x16\xd6\x7c\x5c\x05\x68\x3b\xda\xaa\x33\xcc\xf1\xe0\x9c\xa9\x7c\x3e\xf5\xc6\xd2\xa5\x84\x15\x99\x51\x2f\x7c\x9f\xda\xc7\x89\xfd\x84\xc6\x99\xdf\x36\x98\x27\xc1\x7a\x8d\xb3\x53\x16\xfb\xea\x5c\xfb\x0c\xe2\x9d\xa3\xa1\xcf\xa3\x67\x10\x77\x01\xff\xd0\xe7\xbf\x80\x3f\xde\xc1\xef\xff\xcc\x7a\xea\x13\x28\xfb\xb2\x04\x3a\x44\xe8\xa1\xb2\x83\xcb\xd7\xc3\xe0\x44\xad\x77\xc2\x63\x2e\xd6\xbf\x8f\xf7\xb0\x28\x66\x26\x78\xda\x20\xae\xc7\x3e\x11\x33\x7c\x84\xaf\x55\x59\x9c\x8c\x47\x95\x67\x40\x30\xa2\x19\x93\x8d\x29\xc7\xc4\x8f\xe8\xc7\x0e\xc7\x79\x4f\xd6\x13\xf4\xfd\x84\x8f\xf0\x27\x1c\xce\x56\x44\x4e\x22\xbf\xf6\xa3\x2f\xbd\xce\x68\xda\x1b\xca\x55\x56\x93\x8d\x4c\xe8\xaa\x43\xe2\xf6\xe1\x58\x4d\x75\x17\x8a\xf7\x39\x7e\xd0\x9c\xd7\x99\xd3\x96\xd3\x13\xf3\x1a\x1a\x6f\xae\xe7\xc1\xc7\x0d\x49\x5f\x5f\x04\x75\x04\x35\x10\xa7\xcc\x48\x7a\x85\xf1\xf5\x6c\xcd\x7f\x3c\x18\x97\x18\xcf\x55\x47\x71\xef\x35\x06\x71\x04\xe4\x08\xcc\xfd\x03\x35\xa5\xd8\x50\x5c\x6b\x5c\xc7\x60\x89\x3a\x30\x97\x8c\x54\x5f\x5a\xba\x08\x1f\x64\xd2\xb1\xc9\xa2\xc5\x3e\xb6\x28\x3b\x52\x3d\x2b\x97\x5b\xec\x96\xa1\xb8\xb3\xbf\x11\x28\xa2\x73\xba\xf0\x51\x11\xc5\x80\xa0\xeb\xae\x0d\xad\x53\xa5\x4a\x5c\x55\xf2\xa1\x78\xf6\xc9\xcb\xea\xac\xcf\x83\x38\xee\xa7\x62\xfb\xf5\x64\x18\xa2\x42\xd4\x09\xe4\xf5\x4d\x27\xfb\x08\x84\xdd\x9d\xc1\xaa\xab\x62\x99\x4b\x25\xe0\x9c\xe1\xd3\x40\x66\x2a\x1b\x85\xf9\x1b\xbe\xc3\x75\x75\x6a\x78\x7b\x76\xc5\xe4\x2d\xf0\xb1\x50\x73\xae\x15\xed\x5b\xe3\xa0\x33\x0e\x87\xc7\x7d\x71\xd2\x67\xef\x3e\x59\x8f\xcd\x30\x34\x31\x7d\x17\x33\x6e\x63\xc6\xd8\xe0\x63\x7b\x2e\x54\x8c\x8d\x67\x86\xe1\x99\x0b\xc2\xc6\x8c\xf3\x85\x0f\x1f\xbd\x40\x43\x34\xe7\xda\x2c\x36\xc4\x78\xbb\xc4\xde\xf4\x35\x7a\xe3\xbd\xde\x54\x6c\xe8\x23\x11\xf9\x98\x5e\x48\x70\xa0\xe8\x11\x08\xef\xf2\x27\xce\x28\xc6\x22\x06\x14\x99\xde\xe7\x00\xe8\x10\xd1\x27\x44\xb4\x77\xd3\x74\xf9\xd4\x15\x04\x7c\xf4\xbd\xc4\x44\xf4\x38\xe5\x9a\x71\x73\x17\xb5\x79\x17\x63\x02\x67\x30\xc1\xd5\x74\x6a\x9e\x4a\x7f\x0a\x2e\xfd\x99\x42\x8f\x3d\x53\xe8\x9c\x75\xb4\x89\xd2\x7a\x4a\xfe\x20\x48\x5d\xec\x68\x43\x1a\xf1\xc9\x83\xd8\x48\xe0\xc2\xc1\x57\x40\x54\x87\xb1\x01\x4f\xf4\x64\x31\xd3\x47\x35\xde\x9f\x5a\xd1\xff\x1f\xa2\x01\xea\x99\x23\xcf\x7c\x6e\xf2\x80\x0a\x87\x5c\x4d\xd7\x5b\x2e\x9d\x24\x43\xdb\x6d\x70\xf0\x0e\xef\x30\xb4\x3d\x18\xce\x2f\x8f\xcf\x9a\xa3\x03\xae\x9e\xaa\x3b\xd0\xf1\xa5\x87\xa7\xf3\x1e\xef\x87\x93\x5f\x93\x75\x93\x17\xfa\x92\x91\xbc\xd0\xa7\x8c\xe4\x85\xbe\x65\x24\x2f\xf4\x31\x23\x79\xa1\xaf\x19\xc9\x0b\x7d\xce\x48\x5e\xe8\x7b\xc6\x64\xfb\x31\xe3\x73\xee\x0e\xbf\x28\x67\x51\x43\xa6\xd1\x72\xba\x7d\x3a\x5a\x1f\xf4\x71\x97\xb4\x8f\xc3\x7a\x98\xf5\x5f\xda\x7e\x4e\xf1\x77\x87\x50\xb3\x61\xfd\xcd\xb9\x03\x8b\x29\xf9\x2f\x3a\xff\xbc\x4c\xfe\x49\xfe\x41\x85\x6b\x98\x86\xc7\x10\x8a\xb9\x67\xa5\x0b\x52\x17\x44\x12\xf2\xbf\x00\x00\x00\xff\xff\xa5\xc8\x5b\x7a\x5c\x20\x00\x00") + +func fontsJerusalemFlfBytes() ([]byte, error) { + return bindataRead( + _fontsJerusalemFlf, + "fonts/jerusalem.flf", + ) +} + +func fontsJerusalemFlf() (*asset, error) { + bytes, err := fontsJerusalemFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/jerusalem.flf", size: 8284, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsKatakanaFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xdb\x8e\xdb\x36\x13\xbe\x8e\x9f\xe2\x03\x46\x97\xff\x2c\xfe\x0d\x8a\xb6\x29\x82\x60\x93\xa6\xc7\xf4\x98\xa6\x69\xd3\x3b\xee\x46\x5e\xab\x5e\x4b\xad\x65\x35\xf0\xdb\x17\xb6\x25\x72\x86\x1c\x4a\x32\x36\xcd\x06\x16\x49\x49\x9c\xc3\x37\x47\x2a\xcb\xbb\xe5\x43\x57\xe0\x53\x7c\x82\x87\xff\x07\x5f\xe2\xe3\xc5\x0b\xb7\x73\x6b\x57\xbb\x8b\xe5\xdd\x12\xd7\x7b\xbc\xae\xea\xba\xdc\xe3\xd5\xca\x55\x78\xdc\xb6\xcb\xaa\xda\x5d\x95\xdb\xaa\xbd\xb8\x69\x2f\xba\xcd\xf5\x45\xf9\xb6\x7b\x82\xe7\x6e\x57\x7e\x86\xa7\xdd\x6d\xd7\xee\x70\x79\xf9\x3f\x5c\x3e\x7a\xf4\xd1\xe2\xda\xb5\xe5\x5b\x34\x35\x9e\xb9\xba\x2e\xb7\x07\x6a\x2f\xf7\xae\xc6\x9b\xa6\xbb\x59\xe3\xf1\xfe\x30\x5c\x1d\xc8\x6c\xcb\xdb\xaa\x76\x17\x37\xee\xc9\xc2\xf1\x53\x54\xfc\xec\x41\xc7\x9f\xa3\xe4\xe7\x0f\x1a\xfe\x02\x6b\xc7\x5f\x62\x5d\xf1\x57\x58\x77\xfc\x35\xd6\x25\x7f\xf3\x60\xdd\xf0\xb7\x68\x1d\xbf\x40\xbb\xaa\xf8\x3b\xb4\x1d\x7f\x8f\xb6\xe4\x1f\xd0\x36\xfc\x23\x76\x8e\x7f\xc2\xe2\x66\x55\xf1\xcf\xd8\xb5\x1d\xbf\xc4\xae\xe4\x5f\xb0\x6b\xf8\x15\x6a\xc7\xbf\xa2\xae\xf8\x35\xea\x8e\x7f\x43\x5d\xf2\xef\xa8\x1b\x7e\x83\x95\xe3\x3f\xb0\xaa\xd8\x61\xd9\xf1\x35\x56\x25\xdf\x60\xd5\xf0\x5b\x6c\x1c\x97\x8b\x4d\xc5\x4b\x6c\x3a\xbe\xc5\xa6\xe4\x15\x36\x0d\x57\xd8\x3b\xfe\x13\xfb\x8e\xd7\x28\xf9\x0e\xfb\x86\x37\xd8\x3a\xae\xb1\xad\xb8\xc1\xb6\xe3\xbf\xb0\x2d\xf9\x6f\x6c\x1b\xde\xe2\x9d\xe3\x16\x15\xef\xf0\xae\xe1\x0e\x8b\x9a\xff\x59\x14\x45\x71\x35\xe3\x72\xb5\x20\xa2\x42\x5f\x41\x38\x5c\x81\xf8\xfe\xe1\xce\x71\x01\x7f\x1b\x7e\x0b\x4e\xdb\x0a\x1c\xff\xd4\x0c\x63\xb3\xc3\x94\x0e\xfb\x0b\x39\xa3\xd3\xdf\xe4\x3d\x39\x0b\x04\x8f\xef\x1d\xb7\x1c\x9e\x83\xfc\xec\xf8\xa2\x7f\x8a\xe8\x29\xc5\x4f\x21\x54\x1e\x5e\xa4\x5e\xd1\xa3\xf2\x08\x64\xbc\x34\x1e\x10\x1a\x48\xc3\xe3\x27\x54\xf6\xd2\x20\xa8\x22\x24\xec\xe1\x87\x24\xd3\x1b\xe6\xf8\x94\x12\x09\x23\xfb\x79\xd9\xac\xeb\x89\x5b\xcf\xbe\xa7\x9e\x0c\x42\xae\x9e\xd9\x89\x93\x57\xb5\xd7\xdd\x18\x7a\x84\xbc\x61\x4e\x1c\xbd\xed\xbd\xb7\x4c\x18\x57\xbc\x67\xfa\x4d\x40\x5d\x8e\x92\x90\x7e\x0e\x39\x66\xc1\xc9\x81\x99\x50\xf0\x63\xe0\x68\x3f\x3f\x8b\xa3\x0a\xb6\x93\xb6\x9e\xb6\x07\xc3\xf2\x3c\x01\xae\x37\xa3\x15\x6c\x14\xa3\x4b\x9e\x89\x35\x53\xd6\xa2\x34\xd8\xb4\xff\x9e\x36\x48\xf1\xec\x89\x82\x2c\x8d\x5a\xa9\x74\x14\x97\x41\x2d\x31\x23\x4d\xef\x2c\x82\x30\x95\xb6\xd2\x80\xe6\x4c\xd9\x99\x96\x26\x90\x31\xf2\x4a\xff\x62\x5e\xa9\xb3\x24\xb4\x54\xb6\x08\xda\x76\xb6\x33\x9f\x94\x70\x8e\xff\x99\xb3\x19\x12\x5a\x56\xbe\x97\xca\x61\x0b\x9d\x87\x21\xcc\x52\x98\xb9\x9f\xad\x94\xa3\x69\x44\xa4\x49\x9d\x82\x91\x49\xaf\x66\xfe\x89\xf3\xce\x44\x1e\x9a\x62\x62\x89\x33\x2f\x96\x4e\x99\x21\xf2\x08\xc1\x3d\xbe\x97\x33\xdb\xb1\xa8\xa6\xb3\x28\xee\xc7\x3c\x55\x19\x9b\x64\xe8\x05\x11\x28\x92\x4c\xb9\xab\xca\xa2\x4a\x6c\x9d\x92\x07\x36\x24\xb2\xdf\x50\x7f\xa0\x4a\xce\xe4\x54\x10\x26\x1d\xab\x3a\x3b\xa8\xaa\x2f\x75\x0b\xf0\x12\x09\x90\xc6\x35\x08\x6a\x47\x89\x46\x45\xed\xf4\xc2\x00\x3e\x62\x44\xb9\xf7\x44\x35\x11\xdd\x94\xc0\xef\xa4\x83\x2e\x3a\x94\xd3\x28\x2b\x10\x49\xe8\xe4\x42\xfa\x72\xdf\x6a\x09\xe3\x5b\x8c\x48\xd7\xd9\xde\x31\x33\x9d\xa0\xd9\xc4\x24\x9d\xa0\x76\x41\x21\x39\x09\xa3\xd3\xfb\x30\xfa\x28\x23\x52\x95\xed\xbc\x60\xc9\x7b\x97\xed\x1c\x67\x2c\xfc\x7e\x8b\x11\x21\xe7\x5d\x94\x18\x50\x2e\xc8\xf6\xe9\xa4\x61\xd2\x8c\xa0\x4e\x12\x50\xbe\xa2\xc9\x0b\xfa\xc2\x36\xca\x38\x7e\x1e\xf1\x53\xb9\x4c\x48\x2f\x64\xcf\x26\x9e\x21\x72\x84\xbf\x24\x29\x46\x99\x8d\xb2\x86\x92\x1a\x66\xf7\x60\x70\x23\x2b\x4e\x14\x60\xb1\x30\xa4\x6c\x21\xa1\x92\x40\x49\x98\x24\x07\xe5\xce\xd2\x9b\x65\xec\x0e\x87\x35\x11\x9a\xe7\x32\x40\x88\xb8\x5e\xcf\x39\xd9\x2f\x97\x31\xa5\x27\x68\xa8\x54\x05\xfc\x2f\xa0\x1a\xa4\x2f\x26\xa3\x33\x9b\xee\x0d\x37\x36\x8d\x2e\x4e\x91\x43\x23\xe1\x4f\xe2\xe9\x09\x73\x56\xfa\x9e\x25\x14\x54\x7b\x60\x20\x61\x55\x3e\xb5\xc8\x81\x34\x81\x58\x06\x8a\xb1\xbc\x17\xb7\xd2\x14\x19\x36\xc0\x4c\xca\xb4\xe7\x57\x3e\xc5\x48\x9c\xde\x84\xae\x43\xb5\xcd\xc0\x9d\x40\xa7\x48\xbf\xe7\x88\xb6\x1e\xf4\x80\x91\x4c\x3f\x3a\xf3\xca\x06\x29\xdd\x1b\xd9\x64\x78\x79\xce\x48\xaa\x9b\xd6\x1d\x68\xe0\x10\x15\x90\xe0\x9a\x01\xcf\x5c\xf1\x57\x4d\xca\x8c\x31\x91\x28\x1c\xa7\x43\xda\x9f\xf1\x21\x62\x11\x83\x5e\xdc\x6f\xe6\x9d\xce\xfe\x90\x18\x8e\x44\xc9\x35\x98\x2e\x7c\x2a\x1b\x28\x4a\x73\x8c\x4d\x91\xfa\xfc\x54\x11\x9d\xaa\xa7\xda\x55\x93\x22\x6a\x79\x58\x9a\x1b\x49\x92\x02\x92\x46\x16\x53\x49\xa4\x97\x6f\x3a\x2d\x52\xd2\x6e\x0a\x77\x50\x3e\x31\x1e\xdb\x73\x92\x88\x8a\xef\x5c\x27\x85\xf8\xc8\x27\x6c\x22\xb2\x43\x31\x7c\x5a\xf5\x05\xda\xef\x18\x7d\x34\xbf\x14\x18\x67\xba\xa8\x5f\x84\x91\xa0\x2d\x68\x2c\x34\x68\x1e\x1a\x14\x9e\x50\xda\x98\xe6\xaa\x34\x65\x0d\xa2\x1a\x89\xfc\x02\x63\xad\x99\xf8\x08\x28\xfb\xc7\x00\x1d\xc5\xfd\x70\x44\x7b\xda\xd8\x72\x65\xd6\xd7\xa9\xc5\xdc\x62\x3b\xc5\x28\xeb\xa4\xa3\x75\x73\xac\xaa\xdb\x35\x50\x1d\x58\x60\xd6\x46\xf5\x81\x90\x8c\x1a\x98\xeb\x42\x94\x88\x64\x30\x9f\x3c\x1a\x6a\x4d\x44\xe1\xb4\x46\xd5\xfc\x0f\xa9\x30\x2a\x1c\xa4\x4b\xdf\xf8\x82\x42\xa2\x12\xe5\xdb\x7f\x32\x89\xc4\x8e\x24\xc5\x74\x25\xf0\xb8\x84\xb6\x73\x6e\x1a\x2f\xb4\x61\x73\x47\x17\x32\x8c\x4c\x93\xfd\xc6\x98\xc9\x32\x59\x55\xf7\x11\xba\x21\x34\x8d\xe9\xf7\x48\xff\xa7\x71\xc3\x8c\x95\x93\x6c\x9d\xb0\xe3\x24\xd1\xc8\xbb\xf7\xb8\x12\x64\x76\x6d\x49\xb3\x29\x71\xd7\xe7\x52\xdc\xa3\xd9\x2c\x46\x7f\x1f\xe6\x05\xf9\x9f\xa7\x62\xa4\x68\x2d\xbe\x29\x45\xfd\x68\x11\x7e\x28\x92\x75\x5f\x41\x55\x34\x87\x91\x8c\xfb\x2a\xf3\xf4\x5f\x69\x21\xcb\x81\xf8\xe8\x19\x10\x9d\x3f\xbb\x5a\x44\xff\x3e\xd4\x8d\x7f\x03\x00\x00\xff\xff\x28\xc0\xd7\xf9\x8d\x20\x00\x00") + +func fontsKatakanaFlfBytes() ([]byte, error) { + return bindataRead( + _fontsKatakanaFlf, + "fonts/katakana.flf", + ) +} + +func fontsKatakanaFlf() (*asset, error) { + bytes, err := fontsKatakanaFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/katakana.flf", size: 8333, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsKbanFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x58\x5b\x6b\x1c\x47\x13\x7d\x9f\x5f\x71\xf8\x90\xa9\xd5\xb7\x3b\xd5\x91\x13\x1c\x0c\xb2\x32\xcf\xb9\xbc\x04\x42\x1e\x32\x61\x24\x13\x39\x16\x04\x3d\xc4\x26\x44\x6c\xeb\xbf\x87\xae\xaa\xbe\x4c\xcf\x4c\xef\x2a\x6f\x31\x78\xfa\x56\x7d\xba\xfa\xd4\xa5\x6b\xf5\xe1\x8f\x0f\xaf\xef\x2e\xf0\x35\xde\xe0\xf5\x17\xe8\xaf\xf0\x65\xf7\xdd\xfb\xbb\x47\xbc\x7f\xc2\x8f\x77\x8f\xbf\x3d\xe1\xdb\xbb\x7b\xfc\x7c\xff\xf0\xf8\xe9\xf3\xfd\xc3\x63\xf7\xc3\xdd\x13\xae\xde\x1c\x70\xf5\xf6\xed\x57\xe8\xf1\xfd\xfd\xc7\x87\xdf\x3f\xe2\xa7\xc7\x87\xbf\xee\xff\xfc\xf4\xf0\xf9\xa9\x43\x77\x71\x81\xa1\xfd\x19\x3a\xf6\x8c\xa1\xf3\xde\x63\xe8\xc8\x13\x86\x0e\x1e\xe1\xcb\xc8\x33\x40\x10\xfd\x9f\x74\x57\xff\xab\x8c\xfe\x0b\xfd\xe7\x23\x8e\xcf\xd2\xbf\xbe\xd9\xef\xdf\xed\xf7\xd7\x37\x71\xfe\xf9\xd8\x9c\x2f\x70\xd2\x60\xe8\x30\xed\xf7\xd3\x41\x15\xf5\x32\xe3\x7d\xdf\x8b\x8a\x78\xe5\x55\x7b\xc0\x3a\x87\x7e\x9a\xfa\x6a\x7f\xf8\x77\x90\x63\x01\x67\x33\xce\x96\x9c\xc9\x38\x13\x76\x40\x10\x4b\xfb\xc3\xd2\xa8\xed\xe8\xd2\x38\xa0\x39\x1a\x47\xd1\x0a\x18\x47\x0c\xdd\x38\xf6\x6e\x0c\x1b\xa9\x4d\x95\x0b\x7b\x9d\x5e\xa3\xfe\x8e\xa3\x0a\x0a\x4e\x3c\x76\x14\xbb\xf8\xfa\xeb\x9c\xaa\x3b\x33\xc0\xd0\x89\xfa\x30\x6a\x31\xda\x45\xaf\x6f\xfa\xfe\xff\x7d\x7f\x7d\x63\x97\x1f\x57\x64\x13\xf3\xfb\xd6\x05\x0e\xad\xc5\xe6\xd5\xb9\xb5\xe8\x4e\xfb\x97\x50\x3f\x1a\x59\xc2\xc1\x56\x8b\x31\xd8\x2a\x6e\x0c\xfb\x84\x5d\xa7\x24\x63\xad\x39\xb8\x9e\x66\x3b\xe4\xa0\x1d\x70\xa9\x6e\xe2\x8c\xf2\x00\xb3\x13\x91\xe3\x34\x4d\x61\xc7\x24\x6d\x77\x3b\x93\x41\xb4\xe4\xe5\x65\xb1\x91\xa2\xb5\x0e\xa5\x56\x1a\x73\xd3\xe4\x03\x4c\xdf\xf7\xbd\xfa\xb3\x88\x90\x6a\x25\x67\x98\x97\xdc\x4a\x3b\x69\x20\x88\x25\x45\xeb\xcb\xa4\xa8\x40\x13\xe6\xcc\xe1\x60\x0b\xea\x0f\xbb\x9d\x44\x49\x00\x94\x8d\xbb\x5d\x64\xce\x29\x73\xf1\xc4\x5b\xd8\x02\xe0\x0e\xe5\x09\x3b\x65\x01\x16\x92\xf0\xf1\xc4\xca\x46\xea\x82\x79\xde\x39\xf5\xe8\x75\x5b\x35\x8c\x8c\xd1\x45\x4d\x6c\x3c\xa5\x8d\x22\xb5\xe8\xa5\xcf\xba\x0c\x55\x32\xd7\x6d\x17\x1c\xba\x77\x98\xb7\x69\xf1\xa6\xb5\xf3\x9b\xd6\xe2\x70\xca\xed\x7d\x4e\x62\x9a\xfd\xa2\x73\x44\xde\x99\x88\xc8\x4b\x36\x0c\xe9\x1c\xec\x3d\xa3\x4e\xc9\x45\x70\x93\xf7\x2a\x9f\x8c\x97\xe2\x20\x01\xe9\xbc\xd2\x1c\xf0\x98\x3d\xa1\x05\x0a\x04\x11\x22\xd6\x1d\x24\xf3\x14\x3d\x36\xed\xd1\x73\x01\x88\x86\xe1\x34\x66\xae\x90\xab\x41\x53\xe1\xa4\xe4\x8b\x15\x16\x50\xa2\x0c\xc4\x40\x62\xc1\xa3\x38\x4c\xfb\x0a\xca\xec\xcf\x02\x2d\x30\x0b\xc8\x02\x51\x01\x6b\x8c\x79\x16\xce\x94\xae\x73\x1a\xd4\xc9\x9c\x1a\x27\xca\xa9\xdd\xab\xcd\x29\x20\xdf\x92\xbc\xe4\x06\x54\x53\x9c\x34\x5e\xb8\xd7\x3a\xf6\x46\x96\x2d\x77\xc7\x46\xda\xb8\x29\xeb\xb1\xd2\xf3\x1e\xd1\xae\x44\x34\x3f\x3b\x5d\xca\x04\x82\x2c\x65\x9b\x7a\x2e\x6c\x6a\xa1\xa3\x17\x3a\x23\x5c\xd2\x42\xe1\x10\x5b\xfd\x73\x1d\x45\x6f\x65\x44\x79\x0b\x6e\x49\xa3\x3e\xd8\xcf\x06\x08\x35\x58\xa4\x8e\xe1\xcf\xa2\x9f\x85\x4f\x32\x34\xc4\xa7\x24\x80\x71\xea\xa7\x13\xd9\xe4\xdb\xf1\x2d\xbe\x98\x78\xa3\x99\x4d\x80\x18\x7a\x31\xbe\x35\x26\xd5\x17\xeb\x40\xdc\x8e\xef\x22\xbc\xa5\xab\x9b\xff\x55\xd4\x9c\xa7\x29\x31\x34\x58\x61\x51\x73\x86\x67\x6f\xa6\x4e\x7d\xff\xe2\x3c\x67\x6d\x73\x19\xbd\x41\x6d\x8e\x72\xb9\xb4\x05\x39\x02\x7f\xde\x80\x44\x98\xf4\x39\x24\x3e\x9d\xde\x84\x02\xcb\x44\xe6\xef\x8d\xae\xb1\xba\xc9\x69\xcc\x16\x65\xb2\x40\xab\x2f\x7c\x52\xad\xd6\x5a\x60\x19\xa8\xb0\x1a\x5f\x02\x09\x87\x95\x47\x6f\xf6\x18\x6e\x82\x62\x01\xbc\x04\xaf\x0f\x58\x1c\xb2\x3c\x68\x75\x6c\xb7\x88\x16\x0e\x48\x4b\x76\x7d\xce\x37\x58\xa4\x9b\x15\xa2\xdb\x68\x2f\x30\x9b\x24\x72\xca\x49\x94\x3d\xcd\x41\xa0\xde\x17\xf7\x5a\xe6\x6a\xa7\xae\x5f\xd0\x28\x58\xc6\xd6\xe2\xaf\xad\x45\xe0\x6f\x2b\xfe\xb4\xa0\x75\xf2\xdb\x65\xe8\xe6\x3a\x2c\xda\xa1\x9b\x5a\xa8\xb7\xed\x23\x13\x98\x3c\xa5\xa1\x47\x14\x58\x8d\xa9\x43\x7b\x9a\x90\xcb\x18\xae\x5f\x9d\x34\x1b\x1e\x1d\x8e\x99\x8c\xaa\xda\xc4\xdc\xb1\x2e\x78\xaa\xf4\x55\xcc\xb2\x61\x89\xdf\x10\x15\x29\x2c\x23\x6d\x28\x25\x6d\x36\x3d\x73\xcc\x54\x4c\x79\x5e\xbc\x27\xd6\x0d\xfa\xea\x34\x9f\xc2\x75\xdd\x82\xc3\xf8\x97\xe9\x66\x99\x36\xfb\xaf\x9f\x57\x5c\xe5\x52\x05\xb0\x54\x43\x6b\x49\xfd\x91\xa0\x71\x43\x14\xd5\xf0\xde\x0e\xe2\x5a\xa1\x15\xbb\xa5\x5a\xa1\x2c\x59\x8a\xb2\xa5\x19\xb9\x51\x90\xf3\x3b\x76\xba\xe8\xb1\xdf\x23\x5a\xc7\xe5\xf1\xbc\x0d\xb6\xd3\x54\x46\xab\x8a\x23\x1f\xc9\x34\xaf\x77\xce\x51\x9c\x1a\xbf\x89\x37\x15\xcf\x50\x81\x7f\x2e\xc8\x2b\x0c\x51\x0e\x38\x0e\x4e\xbc\xb0\x35\x32\xa3\xb2\xc4\xcb\x8c\x52\x79\x4a\x0c\x26\xb2\x3f\x7b\xe5\x4a\xc5\xc7\x52\x63\xdd\x61\x0b\xa5\xf8\x44\x84\xfb\x1c\xe1\xd9\x4e\x64\xe5\x6a\xfd\xa7\x1a\xf3\xdf\x00\x4c\xb9\x4e\xc9\x61\x59\xd6\x82\x98\x15\xc4\x82\x38\xbb\x22\x9b\x1d\x4c\x33\x2a\x2b\xa7\x5c\x38\xb5\xaf\x98\x52\xa1\x3c\x06\x5a\x87\xc8\xfb\xc9\x56\x78\x94\x24\xcd\x63\xb2\xf0\x37\x94\x7f\x15\xf0\x29\x25\xd0\x5a\xfa\xde\xe4\x76\xc5\xe0\x96\xa4\xce\x30\xb8\xa2\x71\x8c\x2c\x89\x86\x5c\x99\xa4\x57\x95\x7c\x0d\xb1\x8e\x36\x53\xcf\x30\x8b\x3a\x42\x1f\xeb\x58\x45\x68\xe4\xc6\x1a\xa2\x46\x99\x8d\x96\xe6\xe3\x74\x4d\xf3\x0f\x9f\xbd\x76\xee\xea\x0d\x0f\x3d\xfb\xde\xcc\xb9\xd0\x21\x5a\x57\xca\x2c\x42\x48\x3f\xbd\xac\x62\x88\xf5\x82\xdf\x52\xea\xd8\x7a\x7c\xe3\x93\x21\x3b\x16\x43\x05\x78\x6e\x01\xbc\x6a\x2d\x6e\x2c\xfc\x17\x17\xff\x09\x00\x00\xff\xff\xce\xd1\xdd\x67\x19\x18\x00\x00") + +func fontsKbanFlfBytes() ([]byte, error) { + return bindataRead( + _fontsKbanFlf, + "fonts/kban.flf", + ) +} + +func fontsKbanFlf() (*asset, error) { + bytes, err := fontsKbanFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/kban.flf", size: 6169, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLarry3dFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5a\x5d\x6b\x5c\x39\x0f\xbe\x9f\x5f\xa1\x8b\xc0\x69\xe1\x10\xbd\x4d\xfb\x2e\x14\x86\x61\xa0\x17\x85\x65\xae\xf7\xca\xa0\x33\x6d\x27\xd9\xb2\xd3\xa4\x24\xcd\xee\x06\xf2\xe3\x17\xdb\x92\x25\xf9\xf8\xcc\x67\x92\x0d\x5b\x7b\x4e\xc6\x8f\x25\x4b\x8f\x3e\x7c\xae\xb7\xd7\x57\xeb\x0b\xf8\x08\xbf\xc1\xfb\xff\xc1\x3b\xf8\xff\x6c\xbb\xbe\xbf\x7f\x7a\xff\xed\xf2\x7a\x7b\x0d\x5f\x9e\x60\x15\xa7\xf0\x79\xb3\xfd\xb2\xb9\xbf\x81\x37\xe9\xe9\xcd\x72\xfd\xf7\xc3\xe5\xd7\xbb\x1f\x6f\x67\x6f\x1e\x7e\xdd\x6d\x37\xb7\xb0\xfd\xfe\x65\x73\xbf\xde\x6e\x9f\xe0\xfa\xfe\xee\x07\xfc\xfe\xb8\xbe\x85\x4f\xeb\xfb\xee\x01\x7e\x3e\x5e\x5f\x3f\xc5\xd5\xde\xce\x7e\xfd\xb3\x59\xff\xb5\xf9\x16\x97\xfd\xbc\xdd\xdc\xde\xc2\xa7\x3f\xd7\x3f\x7f\x6e\xb6\x5b\x98\xdf\xdc\x7c\x5d\x3e\x7e\x7f\xfc\x7a\xb9\xf9\xf6\xb8\x98\xfd\xb1\xb9\x7f\xf8\x7e\x77\x0b\xef\x2e\xaf\xe0\x0a\xaf\x3e\xe0\xc7\x0f\xb3\xd9\xc5\xc5\x05\xf0\xcf\x72\x06\x3a\x5b\xce\x40\x67\x71\x52\x66\x69\x22\xb3\x3c\xe1\x19\x4f\xf2\x4c\x26\x69\x56\x26\x71\xb6\x5c\xce\x80\x88\xd7\xc2\x00\x21\x8f\xe2\x20\xe4\x55\x78\x18\xbf\x15\x20\x50\xc8\xdf\x0f\x18\x28\xe4\x95\x02\x12\xea\x9a\x66\x94\x97\x76\xab\x5b\x00\x0a\x71\xb5\x8c\x81\x84\x48\xc8\x3b\x65\x41\x79\xa7\x32\xd3\x85\x1d\xca\x68\x12\x67\x0a\x1b\x1f\x52\x06\x4e\x9f\xc4\x6d\xc4\x41\xfc\x4d\x52\x05\xa4\x55\x7e\xbe\xa2\xb4\x12\x86\xf8\x77\xe9\x79\x92\x19\x09\xf3\x56\x45\x48\xde\xac\x87\x85\xd1\x54\x15\x2b\xc2\x8b\x22\x02\x76\x44\x43\xd0\xcf\x03\x6f\x25\xee\x91\x08\x42\x56\x49\xd6\x76\xde\x04\x0c\x81\x80\xd5\x3c\x04\x52\xe5\xb3\xfa\x15\x2c\xfe\x93\x84\x8c\xeb\x23\x20\xcb\x88\x3c\x91\x6d\xe6\x09\xcf\xd2\x84\xb2\xf8\x90\xff\x96\x01\xd2\xa4\x3a\xe1\xb1\xb0\xac\x73\x55\x39\x3e\x47\x0d\x06\x9e\x3d\x63\x1c\x3d\xcb\x17\x03\x22\x44\xf9\x31\xc9\x19\xff\x34\xac\x16\x00\x73\x5a\xce\xe0\x39\xab\x80\x30\x6b\x3b\x20\x4f\x6a\xc0\x11\x7c\xdb\x86\xf1\x42\x20\x93\x1d\x89\x71\x19\xcb\xba\x68\x5a\xae\xb3\xe1\x64\x0c\xf9\x53\xec\x64\x71\x0c\xd0\x63\xe7\x7c\x45\x9c\x65\x28\xde\x32\x04\xe2\x73\x1a\x42\x65\x31\x76\x58\x6d\x9f\x2d\x23\xc4\x7f\xf3\x52\x43\x1c\x67\xc7\x1b\x42\xdc\x43\x3e\xa8\x40\x7c\x2c\xd5\xe2\xd5\xf6\x2b\x4f\x80\xe2\x06\x03\x74\x20\x3e\xb0\x80\x78\x02\xe2\x00\x3d\xf4\xce\xfa\xad\xe9\x3b\xe5\xbb\x71\x05\x26\x27\x91\xf4\x42\xd9\xb8\xd9\xff\xa2\x77\x45\x80\x78\xbe\xc9\xce\x19\xc0\x10\xcc\x21\x60\xf2\x51\xf5\x7f\x86\x89\x6a\x8a\x36\x90\xcf\x9f\x9f\x4e\x1c\x81\x1b\x52\xfe\x91\xbd\x52\xd9\x6a\x32\xc6\xfd\x2b\xec\xdf\x1a\x2f\x88\xee\xa9\x2c\x41\xa4\x3e\xaa\xfe\x99\x8f\x3c\xfb\xb3\xf1\xe5\xec\xa0\x71\xd1\x3c\xd8\x65\xc5\xc6\x8c\x1d\xff\x20\x13\x7c\x00\xf9\x4f\x68\x5f\xf9\x27\xa8\xec\x49\x13\xfb\x4e\xa6\xe9\x32\xd4\x73\x50\x49\x66\x25\x51\x45\x31\xc5\x02\x8c\x01\xec\x52\x31\x79\x89\x54\x24\x0a\x50\x64\x8a\x64\x8d\x80\x85\xdd\xe2\x98\xa5\x92\xd3\x35\x54\x53\xd3\xfa\x38\xb4\x4c\xa9\x91\xc2\xca\x40\x52\xa0\xe2\x4d\x90\x9e\x9c\xa2\x46\x17\xc6\x4c\xf8\x94\xb3\xf2\xbc\x13\x72\x88\x29\x40\xd0\x0b\xfb\xb0\x17\xab\x36\x73\x40\xd8\xcf\xa9\xc2\xe9\x09\x3d\xce\x83\x82\x13\x61\xc1\x8e\xca\x1f\xf2\x11\x06\x2b\xb0\x97\xb8\x25\x72\x33\x78\x0b\x68\x3e\x56\x13\x28\x19\x32\xc9\x2d\x88\x69\x33\xa7\x6b\xb8\xf6\x75\x00\x71\x76\xc4\x0e\x3b\x76\xc0\x2e\xfe\xa6\xe3\x4c\x23\xe6\x37\x75\xb9\x18\xd3\xc6\x00\x63\xaf\xb0\xb6\x03\xc6\x05\x8d\xed\x2c\x80\xe0\x05\x6c\xc7\x53\xb1\xa0\x39\xb8\x92\x72\xf4\xec\x8a\x71\xd9\x1e\xd5\x19\xbd\x3b\x36\xf2\x80\x86\x7b\x98\x4f\x25\xae\x49\x3a\xc2\xae\x21\x41\xa6\x04\x98\xd1\xf7\x8e\x5b\xa8\xe8\x47\x74\x53\x2f\x44\xc5\xf9\x81\x89\x34\x0d\xe2\x72\x73\x80\x39\x2b\x62\x48\xbf\x29\xda\xc6\xc0\xfd\x2c\x71\x7b\x47\x64\xb5\x7a\xa0\xe2\x2d\x26\x6c\xf0\x56\x33\xb3\x14\xc1\x25\xa4\x14\xd2\xd9\xa9\xd5\x5a\xc5\xad\x54\xc1\x6d\x7e\x01\xb0\xa8\xc4\x0d\xe2\xee\xd9\x4e\xf7\x64\x3a\xd9\x60\x72\x1a\x93\xa2\x7f\x18\x38\x5e\x15\x8f\xc0\x63\x0b\x81\x4a\x20\x63\x9b\x19\x8b\x04\x37\xce\x20\x94\x4c\x2e\x9b\x6a\x76\xf9\x98\x4e\xe5\xbc\x24\x8f\x45\x8b\x83\x70\x77\x43\x57\x44\x56\x5f\x51\x3e\x5b\xe1\xac\x5c\x95\x03\x29\xf7\x16\x02\xe5\xb8\x58\x68\xcc\xb8\x42\xe2\xd3\x03\x72\x62\x97\x12\x27\xca\x1a\x83\x17\x6c\x98\x77\x0a\x7d\x0e\x81\xee\x46\x15\x0f\x62\x11\xc5\x2c\x5f\x1d\xd5\xc8\xaa\xf1\xde\x25\x19\x2f\x8f\xba\xb2\xb2\x02\x85\x15\xbc\xac\xac\x06\xd3\x20\x2a\x1e\xaa\x29\x59\x3b\x52\x23\xda\x59\x11\x1c\x2c\x59\x58\x91\x95\x0c\xfb\x73\x24\x03\x5f\x4a\x55\x2d\x01\xaa\x1c\x06\x9c\xc3\xc0\x4b\x38\x8c\x81\x27\xae\xd2\x4d\xca\xa8\x55\xab\x2d\xbb\xe2\x34\x57\x18\x3c\x43\x43\x0f\x9a\xdb\x1d\x04\xaf\xe0\xa4\xd9\xaa\x4d\x57\x49\xe5\xc4\x33\x72\xe4\x7d\xaa\x8e\x54\xa8\xaa\xee\x53\x9c\x52\x55\x87\xc1\x64\xcf\xa7\xa9\x5a\x9f\x95\x4a\x0d\x6c\x39\x6b\xfc\x55\x9a\x03\x67\x7b\x8e\x7f\x86\x5d\x20\x34\x79\x49\xfa\x71\x29\xa6\xa3\x0d\x42\xc3\x1b\x14\x54\xe8\xe4\x4a\x87\x0a\xbd\x43\xe7\x43\x70\xe6\xdd\xc3\xe0\xcc\x7b\x78\x11\xf3\x36\x4a\x07\x6a\xb1\xa4\xa7\x49\xcf\x93\x60\x15\x7f\x8a\x79\xc3\x04\x6d\x81\xd0\x56\x2f\xf5\xd0\xe9\xb4\x75\xba\x88\xa1\x0b\x4e\x44\xab\xe1\xd4\x74\x3b\x3c\xe2\x7a\xda\x6c\x07\xfc\x1e\x4a\x4b\x4c\xeb\xa9\xe9\x03\x86\x33\xe1\x7b\xa6\x6d\x4e\xb5\x43\x21\x18\xd0\x54\x5f\xe0\x73\x7e\x73\x0a\x7f\x51\x45\x9e\x96\x3a\x2d\x71\xf2\xd2\xa6\xf6\xf6\xd9\x7e\x6d\xd0\xc7\xf2\x17\xbc\xb6\x31\x0b\xbc\x43\x77\xe0\x13\xf9\x06\x16\xfe\x4a\x5a\x66\xa8\x94\x45\x1e\x12\x1f\x01\x3c\x72\x9c\x79\x74\x6c\xef\x60\xb4\x0b\x93\xf9\xa4\x9d\xfc\xab\xbb\xe9\xd8\xe2\xc7\x7d\xe6\x5a\x19\x76\x67\xbe\x0b\x6a\x0f\x64\x08\x83\x89\x28\x43\x40\x58\xe4\x88\x52\xdc\xba\x43\x8d\x29\x29\xbf\xaf\xec\xbf\x41\xb0\xf5\x4e\x54\x43\xa5\x05\x27\x05\x5a\xde\x41\x44\x91\x0a\x4b\x2a\x6a\x18\xce\xb1\xc1\x51\xc6\x90\x4b\x78\x28\x81\x9b\xeb\x78\xfd\xb2\x4c\x45\xd2\x54\x72\x10\x81\xcf\x1c\x6a\x7b\x1c\x59\xe4\xf8\x18\x1c\x01\xb0\xfb\x3b\xea\x03\x17\x52\xad\x33\x80\x23\x3d\x1b\x4f\xf7\x79\x60\xc1\x2a\x2c\x3b\x94\xb2\x70\x90\xb1\xb4\x90\x07\xe9\x21\xfb\xc6\xf4\xae\x2e\x5b\x9d\x8f\xf9\x6c\x0c\x9a\x94\xa2\xbe\x9d\xb5\x79\xb0\x40\xae\x65\x01\xa6\x63\x41\x28\xc4\x19\x10\x63\x0d\x9b\x9b\xf9\xee\xa2\xa8\x75\x4f\xb4\x13\x6c\xef\x1f\x4d\x8e\x0b\x6e\xda\x84\xb6\x90\x5c\x71\xaf\xb5\xfd\xe4\xf5\x44\x28\xd7\x13\x78\xce\xf5\xc4\xd4\x7e\x27\x1b\xbe\xab\x70\x19\x48\xba\x3f\x78\x19\xca\x7e\x47\x59\xcc\x94\xc9\xb5\xb3\x46\x12\x3f\x8a\xb3\x0c\xd9\xce\x1a\xfb\x93\xb2\x46\x3f\x92\x48\x27\x4d\x42\x6d\x11\x96\x9b\x34\x3d\x86\xe9\xbe\x84\x51\x92\xba\xa5\xa9\x73\x7c\x3f\x42\xbb\x11\x54\x7a\x11\x18\x47\xb0\xb3\x53\xdd\x3a\x40\xbb\xfd\x21\x94\x6c\xe9\xc8\xed\x83\xa8\xbc\xad\x05\xe9\x01\x73\xc8\x59\xd6\x97\xb8\xbb\xee\x8d\x0e\xb3\xab\x66\x17\xd3\x5f\x64\x12\x51\x39\x7d\xb4\x45\x12\xe5\xf8\xe6\xec\xca\x1b\x96\xb1\x2c\x50\xf6\x04\x32\x97\x6c\x2f\x51\x77\x96\xcf\x4d\xf9\x27\x7c\xe3\xe3\x78\xd1\x60\x51\xa0\xfd\x7a\xeb\xcc\x2d\x7f\x16\xf6\x0c\xe3\xdb\xf5\x52\x56\x6a\x51\x69\x0a\x2c\xf1\x93\x03\x74\x85\x9d\xbd\x15\x78\x85\xc2\xd1\x84\x1d\xbd\xe4\x8d\xc4\x5c\x85\xb5\x12\x1d\x12\x0c\x98\xf3\x2f\xda\xdb\x1b\x11\x26\xb7\x52\x38\x40\x8b\x9a\x2e\x16\x1b\x5c\x70\x68\x52\x88\xea\xb2\x56\x62\x11\xf7\xb0\xac\xa6\xf1\x48\x39\x88\xb1\xc1\xe3\x5a\x4c\x83\x77\x24\x4d\x28\xcb\x81\xd2\x04\x93\x69\xc3\x3c\xf6\xf8\xb2\x1f\xda\x6a\xa1\xd0\xf5\x69\xf5\xe0\x0e\xfe\x9e\x8d\xae\x22\xe8\xc0\xab\x08\xda\x77\x15\xd1\x70\xbd\x19\x50\x79\x05\x62\xe8\xf2\xcd\x6d\xd9\xb9\xee\xdb\x33\xdf\x84\xe7\xfa\x63\x10\x9a\xed\x85\x66\xe3\x66\x73\x63\xfc\xd0\x63\xf0\x97\x79\xac\xfb\xac\x64\xdb\x93\x75\x99\xa1\x26\x86\xb6\x14\xde\x6b\x45\xa3\xa3\xd6\x37\x43\xac\x79\x96\x1a\xc4\xf6\x72\xc6\x31\xf9\x5c\x0c\x84\xe7\x82\x81\x72\x00\xd5\x15\xe4\x04\x06\x34\x3d\x5f\xb0\x3c\x5e\x85\x29\x95\x5e\xc6\x4d\xc5\x55\x57\xb0\x47\xf8\x2d\xa0\x09\x73\xe0\x17\x88\x18\xb8\x4b\x98\xb8\x00\x98\x23\x27\x81\x28\x3e\x8f\x47\xdc\x89\x34\xc4\x83\x66\x71\xab\x5d\x31\x1c\x34\xce\xc2\x90\x8e\x6d\x01\xe2\x24\x68\x8a\x5b\xd6\xf7\x6e\x2e\x80\x42\xea\xfd\x50\x1a\x07\x00\xee\xe2\xca\x5c\x5b\xed\x31\x42\x21\xfc\x4e\xda\xa3\x7d\xd2\xfe\x9c\xdf\x39\x99\x83\xd4\x23\x5a\x8d\x78\xd3\x76\x5e\x59\xbd\x4a\x25\xe3\x52\x4b\x41\xb3\xb0\x02\x0d\x75\x07\xb7\x3c\x5c\x16\xc0\x9c\xce\xef\xe2\xc8\x0b\x3e\x8b\x78\xca\xe9\xc5\x86\xcc\x03\xa9\x92\xcd\xca\x9a\x24\x15\x72\xb7\x6b\x10\xf8\xbd\x08\xa9\x6e\x08\xf3\xdb\x6f\xd9\x64\x08\xb9\x0a\x28\xef\x03\x56\xef\xbf\xd5\x71\x79\x6f\xcc\x06\x9f\x87\xf8\x5c\x44\xae\xc5\xec\x6d\xba\x6a\x11\x8a\x85\x65\x6d\xe1\x49\xbd\xe6\x9d\xf0\xe4\xe0\xf1\xd5\x5a\x45\x4d\xf8\xd7\x6f\xbb\xee\x80\xcf\x0a\xa4\xf2\x45\x2d\x37\x26\x9a\x82\xbd\xc0\xc7\xca\xbd\x3f\xba\x51\x56\xd0\x15\xdc\x61\xd7\xd0\x06\xf9\xe8\x46\x99\x4b\xa6\x6b\x54\xee\x79\xa0\xbd\x67\xb5\x01\xe9\x44\xd4\xaa\xc7\x4d\xa3\xb6\x5c\x39\xe6\xb9\xbc\xa1\x53\x0e\x5d\xa9\xc2\xbf\x90\x56\x50\x1b\xaf\xcd\x2c\x97\xb3\xff\x02\x00\x00\xff\xff\x1d\x76\x41\x67\x61\x2c\x00\x00") + +func fontsLarry3dFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLarry3dFlf, + "fonts/larry3d.flf", + ) +} + +func fontsLarry3dFlf() (*asset, error) { + bytes, err := fontsLarry3dFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/larry3d.flf", size: 11361, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLcdFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x57\x4d\x8b\xdc\x30\x0c\xbd\xe7\x57\xbc\x43\x6e\xc1\xb8\xb3\xa5\x85\xde\xe6\xde\xfd\x09\x81\x30\xed\x76\x4f\xdb\x29\x2c\xb4\x50\xd0\x8f\x2f\xd3\xd8\xb1\x2d\x45\x96\x92\xb9\x98\x64\xf2\x2c\x3f\xe9\xe9\xc3\xaf\x6f\xaf\x4f\xb7\x11\x9f\xf1\x09\x97\x0f\x08\x17\x3c\x0d\xcf\xdf\x5f\xf0\xed\x2f\xbe\xde\xde\xdf\xf0\xe7\xd7\x1d\xcf\xb7\xdf\x2f\x3f\xde\x7f\xde\xee\x77\x5c\x2e\xf1\xcb\xc7\x61\x18\xff\xff\xae\xde\xf5\x3a\x8c\x00\xf0\x78\x01\x4a\xeb\x94\xd6\xfc\x3e\xd4\xcf\x2d\x80\x9a\x0f\x77\xd7\xeb\x30\x2e\xcb\xf2\x78\x41\x09\x40\x61\x0a\x54\x3d\x8f\x21\x04\x15\xf0\x58\x11\xa6\xd0\x58\x94\x80\xd5\x24\x81\x62\x03\x88\xdb\x11\x03\xe7\xb0\xd4\x3b\x66\x40\xb6\x28\x2d\x14\x52\xb1\x43\x76\xdf\x42\xeb\xd6\xfc\xcc\x8f\xb4\x68\x71\xc8\x47\x92\x16\xd6\x17\xf3\x4a\x7a\x2c\xa4\x67\xed\x48\x6c\xc7\xe2\x56\x03\xc0\xd6\xa8\x93\x6e\xff\xd8\x2c\x78\x01\x62\x55\xc5\x97\xe3\x30\x19\x47\xda\xb4\x84\xb8\x8a\x6e\x5a\x45\x18\xd1\xd7\x92\x1e\x07\x45\xad\x8f\x17\x54\x91\xa6\xcd\x09\x4e\x40\x79\x56\xc4\x47\xee\xc0\x15\xd2\x22\x0e\x46\xc6\x25\x4b\x15\x87\x2e\xe0\x4c\x1c\x58\xc6\x39\x8e\x94\xbd\x44\x1e\x2f\x49\xaf\x98\xf2\xa6\xc3\xf2\x8e\xac\x54\x5a\x19\xa7\xe4\x83\xca\x61\x06\x4e\xb9\x75\x04\x97\x06\x4f\x20\x21\xbe\x75\x75\x14\x63\xb0\xea\x8d\xbd\xf2\x5f\x5b\x20\x71\x24\x9f\xf8\xd8\xda\x11\xdf\x66\x21\xad\x5e\x0b\xde\x14\x55\x01\x56\xc6\x11\x2c\x79\x57\x24\x0f\xbb\xd5\x57\x97\xaa\x1d\xea\xc4\xf1\x1c\x29\x26\xd2\xf9\xb9\x2f\x6f\x7f\xe0\xf2\x07\x33\x2b\xc6\x2a\xe9\x02\x00\x03\xcc\x5d\x2f\x11\x23\xeb\x2e\x33\x87\x22\xcd\x2c\xcc\x47\x2d\x28\x6e\x3d\x5b\xbd\x3b\xb3\x86\x1e\x38\x9f\x97\xb8\x34\x92\x05\xb2\x4a\x65\xd9\x79\x6b\xbb\x4a\xe0\x4a\xe5\xe3\x0d\xc5\xa8\xad\x1c\x60\x35\x45\xb5\x65\x49\xd2\x96\x5b\xbd\xd5\xbb\x13\x69\x18\x39\xad\x77\x20\xdf\xec\x6d\x0d\x58\x76\x07\x3a\x6a\x21\xf0\x61\x45\xe1\x50\x6a\x2b\x07\xb8\x2d\xc0\x06\xe4\xf1\xbf\xe9\x0f\x3b\xd7\x81\x7d\x0b\x45\x1a\xc2\x42\x2b\x0d\xc7\x28\xcd\x5a\x16\xda\x69\x46\x3b\x92\xea\x25\x69\x61\x61\x7f\x98\x45\x60\x1f\xe0\x88\xc3\xa6\xd6\x4c\xda\x79\xe1\x90\x09\xd4\x8f\x34\x05\x6c\xd7\xb2\x7e\xd5\xf0\x7b\xc9\x52\xab\x48\xd1\xf6\x03\xe2\xe2\x3b\x11\x69\x2f\x07\x7f\x4e\x07\x56\x66\x8c\xc9\x58\xaa\xd5\xc8\x07\x38\x73\x5a\x00\xbc\x37\x45\x7f\x7f\x28\x81\x6b\x39\x04\x8d\x83\x6c\x28\xc7\xa4\x51\xfa\x43\x27\xd2\xc9\xad\x3c\xe3\xac\x1b\x8a\xd9\xb2\xd4\x8c\xeb\xa7\x28\xcd\xbb\x3b\xee\x5a\x58\x67\x8d\x39\x8b\xcf\x9a\xf9\x12\x00\xe9\x0f\xc7\x3d\x0e\x4b\x1b\x69\x73\x22\x6b\x01\x76\x43\x31\x01\x0a\x07\xbf\xbc\xe5\xcc\xd7\x92\xe6\x91\xfe\x17\x00\x00\xff\xff\xc6\xce\x60\x5b\xbb\x13\x00\x00") + +func fontsLcdFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLcdFlf, + "fonts/lcd.flf", + ) +} + +func fontsLcdFlf() (*asset, error) { + bytes, err := fontsLcdFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/lcd.flf", size: 5051, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLeanFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x5c\xdd\x6f\xda\xd8\xb7\x7d\xe7\xaf\x58\x0f\x96\x7e\x2f\xd3\x26\x38\x09\x49\xa4\xab\x2b\x28\x71\x13\xab\x04\x67\x0c\xb4\xd3\x27\x8b\x36\x4e\x83\x86\x40\x14\xc8\x8c\xfa\xdf\x5f\xf1\x65\xef\xaf\x63\x6c\x02\xd1\xd5\xaf\xf3\x30\x26\x80\xcf\x3a\xfb\xec\x8f\xb5\xd7\x39\xe6\x61\xfc\xe0\x0f\x3d\x5c\xa0\x01\xff\x1c\xc7\xa8\x1f\xe3\x18\x67\xe7\x8d\x5a\x27\x1d\x4e\xf0\xe3\x37\xae\xc7\xe9\x64\x82\xf6\xe3\xf0\xf9\x39\x1d\x8f\x71\x7a\x74\x79\x82\x0f\x1f\xf0\x63\x38\x4b\xef\x31\x9d\xe0\x9f\xe1\xcb\x68\xfa\x3a\xc3\xc7\xd9\xe8\xd7\x7f\x66\xb5\x70\xf2\x73\xfc\x7a\x9f\xce\x10\xf6\x22\x74\x86\xf3\xd1\xe4\x43\xbd\xf6\x30\xfa\x35\x4e\xe7\x78\x49\xc7\xe9\x70\x96\xc2\xff\x58\x5f\xdc\xa2\xee\xa3\xf5\xfa\x0b\xf5\xcb\xcb\xd3\xda\x5d\xfa\xf2\x34\x9a\xcd\x46\xd3\x09\x46\x33\x3c\xa6\x2f\xe9\x8f\xdf\xf8\x35\xfa\x27\x9d\x60\x3e\xc5\xd3\xf4\x7e\xf4\xf0\x1b\xf3\xc7\xd1\x0c\x0f\xd3\xc9\xfc\x0f\x0c\x67\x18\x4f\x27\xbf\x16\xff\x9f\x3f\xa6\xb5\xe5\x07\x46\xe9\xcb\x7f\x66\x98\x0c\x9f\xd2\xc5\x3d\x9e\xc7\xc3\x9f\x2b\x84\x43\xfc\x9c\x3e\x3d\xa5\x93\x39\xc6\xa3\x49\xfa\xb1\x56\xbb\x5d\x7d\xfa\x7e\x31\xbd\xbb\xe1\xeb\x18\x9f\x5e\x5f\xe6\xd3\x09\xfe\x67\x36\x1d\xbf\xce\x47\xd3\x49\x33\x1d\xbe\xcc\x1f\xc7\xa3\xc9\xdf\x1f\x27\xe9\xfc\x7f\x51\xf7\x8f\x2e\x1b\x0b\x20\xa3\xd5\xec\x30\x49\xff\xc5\xf3\xf0\x65\xf8\x94\xce\xd3\x97\xda\xec\xf5\xf9\x79\xfa\x32\x5f\xdd\xf0\x73\x78\xbd\x98\xeb\x70\x72\xbf\xb8\xfc\x36\x9a\x7c\x04\x6e\x87\xbf\x31\x1c\xcf\xa6\xf8\x91\x62\x36\x1e\xfd\x7a\x9c\x8f\x7f\xe3\x69\x83\xe2\x61\xfa\x82\x1f\xe9\x7c\x9e\xbe\xe0\x75\x96\xd6\xa6\x0f\xcb\xdb\x3f\xbc\x8e\xc7\x1f\xfe\x1d\xdd\xcf\x1f\x8f\xfe\x4e\x5f\x26\x47\xb3\xa7\xd7\xd9\x23\x86\xe3\x79\xfa\x32\x19\xce\x47\xff\xa4\xb3\x3f\xf0\xe3\x75\x8e\xfb\xf4\x61\xf8\x3a\x9e\x63\xfa\x3a\x7f\x7e\x9d\x2f\x66\xde\x8d\xfa\xf8\xf9\x38\x9c\xfc\x4a\xef\x3f\xd6\x6a\x58\xfd\xf3\x00\xaf\x59\xcb\xaf\xb1\x7e\xb1\xbc\x5e\xbf\x58\x5d\xaf\x5e\xac\xaf\x97\x2f\x36\xd7\x8b\x17\xd9\x35\x9a\xb5\xfc\x1a\xcd\x66\x36\xd0\x7a\x98\xe4\x68\x33\xc8\xf2\x6a\x79\xb9\xba\x5a\x0f\xb0\xbe\xfd\xfa\x6f\xab\x9b\x67\xb7\x06\xd8\x8d\x93\xa3\xd5\x97\xd7\x37\x21\x37\xc7\xfa\x56\x4b\x9c\x19\x9a\xfc\x56\x4b\x9c\x5e\x7e\xbb\xfc\xce\xf2\x05\x7b\xb5\xf8\xfe\xfa\x0f\xeb\xf1\xb0\x19\x7d\xf3\x1f\x99\xde\xfa\xfd\xd5\x74\xc8\xfb\xcb\x21\xe8\xfb\xf9\x98\x14\x2b\xff\x47\x81\xe4\x28\x08\x04\xb0\xf1\x97\x97\xf9\x22\x92\x91\x09\x8c\x0d\x8e\xdc\xd4\xd4\x40\x0a\x42\xbe\x86\xcb\x2f\xb1\xb5\xe4\xd3\x25\xd8\x88\xf3\xac\x3e\x93\x8f\xbd\xb9\x0b\x5d\x6b\x32\x45\xdb\x0e\x0c\x98\x47\x8d\x97\xcd\x84\xb8\x03\x98\x75\x32\xc8\x19\xfe\x0d\x5e\xf2\x2e\x1d\x93\xdd\xdf\x00\xb0\x71\xbe\xec\x5e\x9b\xf0\xf1\x94\x3d\xdf\xe6\x7c\xf6\x40\x64\x19\x41\x8d\x98\x5d\x6f\xa6\x6a\xbe\x43\xc1\x19\xee\xc4\x57\x98\x05\x2c\x84\xa9\x28\x0e\x0a\x84\x8c\xcd\xe7\x5f\xe8\x5c\x3a\x96\xd7\x2e\x8b\x3c\x61\xc8\x68\xe2\x9f\xd9\x8c\x4d\xd6\x74\x07\xe7\xca\x12\x88\x9a\x2f\xf1\x2c\x3b\xf0\x29\x54\xb0\x90\xa6\x3e\xe0\x1a\xb8\xdc\x95\xe7\xe5\xe6\xce\x4d\x9d\x9b\x59\x9a\xb8\xe8\xa5\x67\xce\x44\x5b\xa1\xc4\xad\xf2\x81\xdd\xff\x5b\x0d\xb7\x1a\x86\xdc\xde\xed\x14\x9b\x7f\x12\x9b\x99\x71\xc8\x72\x53\x07\x94\x0e\xb9\xf9\x94\xe7\xa1\x68\x36\x50\x19\x87\xa5\x1b\x59\x7a\x72\x97\xcb\x5c\xd0\x93\x89\x56\xe6\x05\x6b\x20\x59\x2f\x37\xce\xce\xeb\x25\xcb\xa5\xdb\xeb\xa5\x9e\x44\x56\x27\x88\xeb\xca\xa0\xa7\x55\x64\xf5\x75\xd0\x92\xc6\x0b\x58\xe6\x7d\xce\x9c\xc9\x00\xe4\x51\xcb\x57\x95\xbe\xcf\x97\x18\xb2\x90\xf1\x0a\xea\x2c\xa0\x3c\xb0\x1d\xcb\xc6\x42\x9a\x05\xb4\x0c\x67\x16\xcc\x45\x8c\x81\x55\x4d\x23\x4f\x88\xa4\x46\xeb\x25\x58\x6a\xe5\xd3\x55\xf3\x2d\x66\x0c\x34\x96\x04\x4f\x60\x28\x04\x08\xe2\x10\x20\x75\x92\x41\x70\x23\xb0\x2d\xe1\xca\x33\xac\xbc\xf0\x62\x0e\x5e\x48\x44\x14\xab\x18\x2e\xb6\x84\xc7\xca\x0a\x8d\x61\xcd\x68\xf2\x38\xe6\x51\x27\xdd\xce\xe5\x75\x3b\x86\x5d\x1e\x58\x7b\xf4\x7a\xbb\x6e\x80\x66\x78\xcf\x63\xb9\x84\xd4\x92\x9a\x3d\x23\x15\x53\x50\x49\x9a\x96\x0f\xcf\x93\x24\x41\xf2\x13\x9b\x7e\x5a\xf7\x16\xcb\x43\x19\x0e\x6c\x56\x54\x32\x5e\x95\x11\x8b\xdd\x76\x33\x43\x8b\x93\x90\x59\x1b\x4e\xe9\xf6\xd2\xdc\x66\x9c\x56\xf2\x4c\xb9\xdd\x16\x8e\xd0\x34\x5b\x09\x95\x87\x5d\xad\x04\x49\xf1\x84\xdc\x48\x7e\x57\xb3\x67\xc6\xed\x4a\x3e\x46\xcc\x97\x83\xc8\x92\x13\x87\x03\x52\x38\xb2\x30\xc9\x09\x3f\x2b\xbb\xf4\xd3\xcc\x35\xe8\xbd\x59\x46\xcb\x91\x10\xb2\xbc\x4b\x1c\xd3\x9b\x64\x03\x2a\x60\xfb\x2c\x9f\x26\x00\x92\xdb\xb1\x9f\xf2\x59\xbe\x98\x90\x3c\xbd\x99\x31\x5b\x02\xa3\xf7\x73\x71\xf3\x1d\x2d\x00\x08\x1f\xd9\x97\x05\xaa\xd6\x75\x9e\xa0\x40\x1b\x15\xd3\x0e\xee\x26\x65\xcf\x40\x68\x59\x2d\xa4\xc6\x7b\x22\x18\xe0\x62\x04\x34\xc1\xd8\xd1\x27\x78\x0f\xa9\xf2\x23\x28\x81\xd6\x5a\x8c\xaa\x49\x46\xe7\x58\x72\x49\xf8\x82\xc8\xf4\x4d\x52\xbb\xd9\xa9\x70\x85\x46\xba\x65\x21\xc1\xe0\xfd\x92\xa8\x54\x6e\x42\x61\x2c\xc1\x1b\x39\x9e\xbd\x04\xb2\x85\x97\x65\x5b\xb6\xef\x3b\x2e\x81\x27\x4d\x2c\x18\x07\xa4\x56\xb2\xfe\x9a\x66\xfe\xb0\xda\xdf\x62\xe9\x42\xce\x9a\xfa\x7b\x93\xe8\x52\xd2\xf9\xb4\xfb\x59\xb3\x2f\x2d\x5d\x94\x03\xc6\x63\xc2\x06\x96\x28\xc1\xee\x6d\xc0\xca\xd0\x6f\x8e\x6d\xef\xf4\x7b\x87\xaa\x09\x8b\xf2\xe8\x1c\x59\x18\x1d\x65\x67\x9e\xbb\x4b\x42\x65\x4a\xa1\x52\xe6\x77\xf6\xbc\x43\xce\x7c\x2f\x84\x85\x53\xf8\xa2\x22\xc5\x32\x83\x4c\x56\x6f\xef\x82\x6d\xa1\x2b\x29\x90\xec\x38\xc7\x65\xcb\x2f\x56\xbf\x54\x6a\xae\x48\x50\x70\x80\xf6\x9b\x98\x54\xa5\x1f\x15\xe3\xe6\x4e\x85\x20\x76\x0c\x45\x09\xc2\xa2\xc1\x58\x80\x34\x28\x9d\x08\xe0\x00\xa7\x01\x62\x1b\x48\x1b\xa8\x3b\x83\xea\x92\x06\x2e\x54\xa8\xb2\xb7\xb7\xd4\xbe\x96\x4f\x95\xd5\x78\x7d\x85\x29\xfb\xbf\xcd\x89\x0d\xb6\xb9\x93\x24\x0b\x4d\x7f\x77\xb5\xc8\xea\x9b\x9c\x61\x71\x82\xc5\xca\xbf\x88\x70\xb9\x01\xc6\x9a\x3e\xe6\xd8\x4d\xf2\x92\xf4\xd9\xe4\x06\xc4\xec\x84\xd2\x11\x2c\x24\x59\x91\x19\xd9\x33\x11\xf4\x8d\xe5\x7c\x26\x31\xb8\x66\xb9\x6d\x26\x14\x5f\xf2\x2e\x7b\xa7\xca\xb7\x76\x79\x69\x95\x1b\x9d\xd4\x4b\xd9\xdf\x53\x3a\x09\x99\x17\x5d\x20\x63\xad\x2c\x90\x16\xed\xdf\xce\x64\x64\x41\xb5\xeb\x69\x53\x24\x31\x96\x95\x08\xa7\x2b\xcb\xa8\x74\x91\x2d\xd7\x60\x94\x9d\x31\xc0\xab\xc9\x5b\x66\xcc\x86\x02\xf8\x6a\x56\x92\x58\xde\xd2\x5c\xf2\xb4\xc4\xa9\x4a\x76\xeb\x35\x30\xd5\xf3\x26\x52\x16\xb4\x34\x41\xbb\x89\xcc\xf8\xa0\x62\x2a\x44\xd4\x52\x4c\xf5\x6d\x49\xde\x61\x7a\xa3\xaf\x77\x99\x1e\xd6\x4a\xcb\xec\x94\x6b\x0f\x7b\xf6\x6e\xc8\x24\xe9\xb0\x78\xe1\xf9\x94\x3c\x51\x30\xc6\x21\xcd\x5b\x6e\xbf\x2d\x7f\x29\xeb\x65\xe1\x26\x33\xb7\x06\xaf\xa2\x54\xb7\xb1\x4f\xdc\x28\x4b\x52\x4a\x62\x68\xbb\x84\x43\x70\x2b\x5a\xf7\x2c\x63\x42\xd6\x5d\xbe\xcd\x84\xd9\x5f\xd5\x1f\x3d\xe1\x20\xa6\x9b\x58\xce\xb2\x95\x5f\x8a\x51\xca\xb2\x46\xfa\x52\x82\x3b\x90\xf7\xca\x71\xed\x0c\x45\x06\x55\xd1\x2b\xca\x81\x9d\x14\xb7\x6d\x95\x78\xc6\x89\x0d\xea\x81\xdb\x14\x39\xc1\xa9\x0a\xb4\xc9\x43\xd7\x61\x67\xb4\x95\x4a\x95\xa4\x8b\x27\x41\xe6\x96\xc5\x77\x55\x14\x9c\x00\x54\xae\xe6\x1d\x2e\x95\x75\x76\x96\xc1\xd9\x66\x1e\xc0\x05\x34\xb1\x88\x59\x49\xa4\x12\x8e\x16\x70\xca\xb3\x47\x6f\x27\xd5\x68\x27\xe6\x61\x9a\x58\xb4\x5f\xb2\x89\xe6\x7d\x5f\x53\xb4\xcc\xcd\x1a\x6f\x46\xb7\xae\xb1\xeb\x83\x36\x20\x07\x30\x1b\xa0\x0d\x14\x06\xe0\x7c\xb8\x2d\x78\xaa\x44\x89\xe2\x72\x87\x51\x9f\x4a\x01\x38\x0c\xa3\x29\x06\xa0\x3a\x68\xd6\x3e\xb3\xa0\x49\x76\x3c\x6f\x93\xb8\x8e\x0e\x6e\xdd\x3e\x77\x69\x08\x4d\xf3\xe8\x20\x68\xf7\x2a\x74\x92\xaa\x8a\xbc\x95\xf7\xc5\x19\x45\xd0\x71\xf9\xae\xb8\x7c\x57\xee\xa6\x83\x9b\x40\x73\x28\xc1\x96\x19\x6d\xca\x4f\x16\x1e\xec\xb8\x67\xee\x79\x45\xe5\x55\x88\x0e\x2a\xd5\x31\xa2\x65\x4a\x4e\xdb\xf6\x52\x1c\x38\x14\xb9\x28\x15\xaf\xbb\x48\x97\xc5\x00\x8a\xe3\xf5\x1d\x00\xe0\xf0\xdd\xe7\x7f\xdf\x12\xec\xda\x7f\x7b\x2c\xa6\xb7\x71\xcb\xe2\xf0\x30\x62\xdf\x19\xfd\x4b\x20\xf5\xc6\x31\xd0\x8d\x3e\x7c\x8a\x83\xd6\x17\xf4\xee\x5a\xed\x20\x0b\xa2\x83\x3f\x41\x51\x6f\xd4\x81\xb0\xfb\x35\x88\xfb\xc1\x15\x82\xbf\xda\x9d\xd6\x6d\xab\x1f\x46\x5d\xdc\xb6\xe2\x2f\xee\xee\xeb\xad\x0d\x6c\xbd\xe1\x03\xed\xa0\xdb\x47\x2f\xbc\xee\x1a\x4d\x0d\x44\xf2\x95\x84\x9b\xd7\x18\x4e\xef\x79\x25\x93\x7e\xc9\x8e\x81\xd5\x1b\x27\xc0\x5d\x34\xe8\x5e\x49\x20\x12\x8c\xf4\x0c\xcb\x37\x34\x17\xde\x30\x1e\x90\x5d\x36\xc9\x25\x69\x63\x69\x13\x9f\x25\xd0\x53\xa0\x3d\x88\xe3\xa0\xdb\xfe\x6e\x61\x05\x67\xe8\x39\x68\xf0\x13\x45\x89\x3c\x71\x65\x66\x70\xf1\x47\x70\x4a\xc1\xb6\x2c\xe9\x40\x72\xa5\x79\x2d\xaf\x37\xce\x80\xef\x41\xd7\x84\x5f\x65\x37\x24\x31\xcf\xc3\xd1\x58\x73\x69\xff\xb2\xf7\x03\x27\x9d\x6b\x98\x0d\xe0\x53\x1c\x7d\x09\xba\xf8\xd4\x8a\xab\x50\x10\xae\x62\x78\x15\x29\x48\xbd\x71\x0e\xf4\x82\xf6\x32\xfe\x98\x8d\xf4\x46\x04\x8a\x78\x1d\xb3\x8b\x6a\xbf\xdc\xc4\x52\xf6\x0e\x0b\x48\x17\xc0\x55\xd8\x0a\xe2\xa0\x17\xf6\xca\x51\x88\xf5\x0d\x68\x26\x02\x78\x36\x62\x6b\xc0\x5f\x1b\x8c\xc1\xa0\x10\xf5\xc6\x25\xd0\x8e\xee\xbe\xc7\xe1\xf5\x8d\x4c\x22\xcc\x4f\x79\xb4\x82\xa7\x95\xcd\x54\x92\x7c\xf3\xbb\xc9\x1f\xf0\x31\x1b\x2f\x6a\x46\x7e\x0c\x50\x94\x24\x3e\x24\x00\xee\xbf\x64\xd6\xcb\x49\x9d\x1f\x03\x9f\x83\xdb\xb0\x1b\x76\x03\x44\xf1\x55\xd8\x6d\x75\x10\x76\xaf\xc2\x76\xab\x1f\xc5\xdc\x0c\xc5\x9b\xde\x9c\x99\x2a\x89\x18\x74\xb7\xc9\xac\x9c\xc5\xd6\x3f\xaf\x03\x9d\xe0\x73\xff\xc3\x5d\x14\x76\xfb\x61\xf7\x1a\x57\xd1\xe0\x53\x27\x40\xab\x7b\xdd\x09\xf0\xe7\x20\xea\xeb\x2a\xa2\x71\xbb\x2b\x2b\xaf\xa3\x56\x65\x65\x9e\x5e\x92\x78\xd6\xcf\x7d\x2c\x9f\x55\xd4\x09\xa8\x59\xf0\xd2\xfd\x04\x8b\x90\x30\xed\xe3\x12\x35\x0d\xe3\x04\xe8\x45\x9f\xfb\xb8\xf9\x7e\x77\x13\x74\xdd\xa4\xbd\x66\x62\xd8\xb6\x99\xe6\xba\xdb\x62\xe4\x53\x20\x0e\xae\xc3\x5e\x3f\x88\x03\x59\xf3\xaa\xc5\x8d\x28\x65\x3c\x6e\x12\x7d\x7c\x96\x17\x3e\xba\xc6\x78\x73\xdc\x9c\x01\xb7\xad\x76\x1c\x75\x6b\xac\x36\x34\x0d\x62\xc1\x59\x29\xef\x9d\xf8\x3e\x46\x91\x56\x66\x2d\x6a\x03\xb8\x0a\xae\xe3\x20\x20\x66\xcd\x6d\xa6\xbd\x9d\x70\x38\xc5\x96\xaa\xf4\x75\xf5\xf3\x73\xe0\xae\x33\xe8\x7d\xb8\x0d\xbb\x83\x9e\x72\x6e\xbe\x27\x2c\x33\x41\x92\x09\x6c\x30\xf7\xdd\x13\x26\xb4\x59\x75\x17\x70\x4a\xd8\x4b\x74\x17\x40\x6f\x70\x17\xc4\xbd\x76\x1c\xde\xf5\xd1\xff\x16\xd5\xe4\xa2\x18\xd4\xca\xd0\x12\xe4\xc0\xc6\xa0\xda\x36\x97\x62\xf4\x9b\x38\x08\x98\x5b\x50\xee\xe6\x89\x9a\xc9\x2b\x26\xaf\x97\xdc\x9b\xf8\xd4\xc5\xab\x66\xad\x7e\x71\x0c\xb4\xda\x83\x7e\x80\x56\x7b\xc1\x7b\x35\xab\x38\x54\xdb\x5f\xbf\xa8\x03\xb7\x61\x3b\x8e\x6c\xda\x28\x17\x4d\x90\x48\x69\x15\x9a\xf3\x64\xf7\xa3\xd4\x81\x3c\x94\x09\x61\x54\x0d\xd0\x85\x0f\xdc\x85\x9d\x76\x1c\x7d\xd3\x10\x2d\x39\x8b\xd7\x5a\xeb\x11\x5b\x23\xa3\x54\x69\x0e\xeb\x17\x27\x0b\x9b\x5d\x5d\x75\x02\x5c\x45\xd9\x62\x35\xc5\x45\xa6\x14\x93\xdc\x92\x2d\x8c\xfc\xf0\xfa\xc6\x0b\x1a\x1f\x5c\x85\x9d\x4e\xab\xa6\x57\xa0\xdc\x95\x7c\x3a\x73\x6d\x86\xc5\xdd\xcf\xb8\xb7\x47\xdd\xa0\xf8\x3b\x35\x96\x8e\x37\xe6\xd2\x4f\xe6\xd4\x98\x71\x1a\x8b\x74\xdb\x6b\x0f\x3a\x5b\x79\x4a\xa5\xc7\x92\x58\xcc\x21\x2f\xa7\x0e\x75\x52\x61\x23\x08\xcf\x81\x25\x33\xac\x4c\x50\xf8\xe3\x31\x3c\x26\x93\x23\xde\x93\x56\xa5\x30\x28\x14\x45\x56\xc0\x2f\x80\xaf\x83\xce\x75\x2b\xc6\xe7\xb8\xb5\xea\x04\xa2\xee\x02\x70\x2b\xee\x07\xb1\x0a\x5e\x4f\xf7\x36\xf4\xca\xcb\x52\x16\x81\xa7\xf6\x34\xc4\xd4\x28\xcd\xe5\xf5\x80\x74\xb3\x3a\x49\x3a\x50\x59\xff\x96\x33\xbd\xb4\x67\x7a\xd3\xea\x7c\x76\xdc\xd0\x9e\xa5\x07\x3d\xc9\x6c\x95\xe8\x1c\x41\xfd\x5f\x13\x1b\x45\x3d\xac\x3a\xa7\xf1\x38\xa6\x77\x79\xac\xa7\xb7\xac\x3d\x9b\xa5\xec\x19\x5f\xe6\xab\xc9\x27\xb5\xfa\x00\x4d\xc4\x7a\x45\xe9\xdf\xe4\x9a\xba\x57\x15\xa5\xd7\x75\xfb\xca\xae\x27\x4f\x45\xa5\x3f\x07\x41\xcf\x0a\x35\xcf\x71\x1c\x8d\xc4\x60\x72\x24\x9a\x2c\x2e\x37\x5a\x62\xa3\xae\xbc\x97\x3e\xd0\x69\xf5\xc3\x2e\xda\xad\xbb\xb0\xdf\xea\xa0\x13\xf4\xfb\x41\x8c\x16\xbe\x85\xfd\x1b\x5c\xc7\xad\xaf\x01\x63\x43\x8e\x13\x15\x49\xc1\x2e\x3b\x15\x6b\x55\x55\x24\x96\x33\x78\xe3\xe5\x49\x31\xbe\x25\x6b\xa0\x24\xdd\xb5\x1f\x71\x28\x7c\xa7\xc5\xf8\xda\x61\xdc\x1e\xdc\x7e\xee\x04\x7f\xe5\x46\x4c\x0a\x24\x54\xb5\xca\x42\xfc\x92\xd9\x3e\xb1\xf4\xa9\x6d\x8d\xde\xe5\x59\x31\xe8\x7e\xd8\xb9\x62\x8b\xce\x79\x98\xe8\x81\x20\x0f\x0f\xed\x1f\x6f\xa3\x18\x6f\x45\x09\x46\xd6\x53\xb9\xe4\xfb\xc1\x7c\x5e\x8c\x39\x5e\x94\xdd\xd6\xa7\x88\x46\x57\xb1\x63\xbc\x07\xe8\x0b\x17\xe8\xc0\xca\x69\x52\x65\x71\x68\x2d\xeb\x0f\x73\x12\xcc\x73\x94\xfe\x2c\xf4\x23\xa4\x66\x76\x2d\x38\xa9\x9c\xcd\xea\xd2\x31\xab\xf6\x3a\x46\x05\xe3\x34\xe7\xe6\x7e\xb6\x8f\xab\x73\x72\x0e\x30\xf6\x5e\x12\x26\x2b\x92\x77\xd7\x88\xfd\xe3\x63\x07\xe2\xc0\x99\x95\x79\x13\xcb\x7f\x99\x88\x48\x10\xee\xfe\x63\x87\x7d\x6e\xff\xb8\x5e\x8c\xd3\xc8\xce\x60\xe9\xf9\xbd\x70\xba\xaa\x5c\xb0\x5b\x96\xe6\x25\x43\x2f\xb1\x76\x64\xdb\x85\x8b\x82\xd1\x3f\x76\x95\xbe\x60\xa7\xac\xf7\x3e\x98\x5d\xe5\x30\x54\x8e\x9b\x18\x4a\xda\x76\xb9\x81\xd4\x16\xc3\x09\x4c\x17\x58\xe2\x72\x55\xbc\xb0\x12\x8d\xe0\x16\x64\x68\x58\x58\x57\x7d\x92\xd4\x3f\x76\x55\xb8\xd0\xed\xa0\xdc\x3d\xd5\x4e\xdb\x01\x40\xba\x4a\x5a\xe8\x74\x48\x97\xce\x78\x38\x8c\xae\x0a\x16\xf4\x6f\xcc\xd6\x3b\xeb\x24\x8c\xd6\xdb\x50\x52\x20\x05\x2f\x21\x79\x15\x9f\xdf\xf3\x8f\x5d\xa5\xa8\x5b\x99\x79\x49\xbd\x49\xaa\x3c\x89\xe3\x37\xdf\x2a\xc5\x73\xdd\x55\x88\x22\x5d\x88\x44\x77\x60\xc8\x17\x7b\x3b\x0b\xeb\xd7\x5d\x85\x27\xb2\xe2\x59\x6e\x0f\x1e\x10\x97\xab\xd0\x44\x8e\x38\xae\xa0\xfb\x28\xe7\xa3\xeb\xb9\xc3\x21\x13\xbf\xee\x2a\x30\x91\x76\x46\xe6\x8b\xaa\x09\x38\x30\x4e\x57\x51\x89\xac\xbc\xe3\xa8\x83\xef\x73\x70\xc7\xaf\x9f\x01\xb7\x83\x4e\x3f\xbc\xeb\x84\xed\x96\xde\xab\x86\x90\xf0\x9a\x05\x9b\x1f\x89\xfa\x61\xc4\x12\x9a\xbe\x5f\x77\x95\x92\xb5\xb5\x7a\xfd\x38\xfa\xa2\xe8\xbc\xa6\xf2\x32\xcf\xd0\x4c\x43\x30\x53\x33\x81\x66\x9b\x44\x9e\x86\xc8\x17\xc2\x61\xbf\xcd\x04\x5c\x65\x66\x50\x25\xe7\x90\x69\xed\x2b\xb6\x5d\xa5\x65\x50\x25\xe7\x1c\x00\x97\xab\xa6\x0c\x76\xca\x39\xf9\x2a\x1d\x22\x3e\x7c\x57\x41\x19\x54\x8f\x65\x65\xb2\x7d\x63\x75\x15\x99\xef\xae\x05\x07\x5d\xf1\x4c\x2e\x06\x13\x9b\x38\xa1\xe5\x90\x68\x23\xd8\x54\x1b\xb0\x0a\x9f\xab\xd8\xf4\x6f\xa2\xb8\xcb\xe3\x8d\xf6\x31\xe5\x1e\xec\xa2\x79\x32\x21\xfa\x22\xb6\x3e\xd2\xe6\xfb\x59\x61\xe9\xdd\xb6\x3a\x19\xac\xde\x4d\x2b\xbe\x43\xcf\xec\x4e\x50\xa2\xe7\x32\x2c\xa7\xf8\x8e\x14\x0f\x68\x6b\xae\x0e\x17\xfa\xfe\xa9\x09\xd4\xd0\x3e\x4b\x25\x1a\xd6\xba\x18\x01\x2d\x54\x45\xc7\xa3\x88\xbe\x7f\x56\x84\x4a\xb4\x2a\x3c\x3a\xcc\x54\x03\xc9\xb9\xf7\x71\x42\xd4\xf7\x1b\x45\x28\x75\xc3\xc2\x4d\x98\xa8\x07\x9f\x0f\x09\xf5\xbc\x08\x6a\x79\x9a\x73\x60\x94\x17\x45\x28\xab\x93\x9c\x4a\x89\xb1\x1a\xd2\xcb\x22\xa4\x5a\xd9\xdc\xb2\xf4\xa2\xc1\xdf\xab\x51\x4f\x8e\x6d\xa8\xa6\x9e\x69\x31\x12\xd5\x28\x1a\x4d\x43\x72\x64\xc4\x7d\xc2\x85\x42\xfa\x75\xb9\xbb\x00\x3a\x0f\x03\xc3\x66\x2e\x75\x73\x2e\x45\x2a\xa6\xb8\x5b\xf9\x1f\x8f\x03\x21\x1f\x4a\x68\x61\x45\x8b\xcb\x97\x4b\x9c\xbe\x89\xd3\xd0\x2e\x13\xaa\x01\x02\x82\xee\x0a\xa6\x6e\x78\x06\xf0\x06\xcf\xb0\x8b\x94\xad\x5c\x16\x64\xd9\x03\xa3\xb4\x2b\x94\x4b\xb7\xac\xd4\x4e\xee\x1b\xaa\x5d\xb6\x4c\xb5\xb2\x62\x93\xb6\x6f\xa4\x76\xe9\x92\x1a\xa5\x60\x23\x7b\x3a\xdc\xef\x9f\xd8\xd5\xc8\x52\x22\x93\xad\xe7\x9f\x84\x82\x9b\x8d\x48\x62\xb2\xf0\xe7\x48\xfd\x13\xbb\xea\x38\x74\x47\x4e\x17\x79\x01\xf7\xe4\xaf\x38\xed\x0c\xc9\x2e\x2f\x96\xca\x98\x28\x8d\x31\x57\x18\xb1\x3f\x23\x9d\xda\x55\x64\xa3\x29\x0a\x14\x64\xad\x12\x7e\x28\xa6\x98\x1e\x96\xec\xf7\x4e\xed\x32\x50\x5d\x41\x84\xf2\xa5\x44\xec\xdd\x42\xf4\xf4\xa8\xae\x20\x9e\xda\xc5\xa0\x92\x7e\x08\xc9\xba\x80\xb7\xda\xd0\x4e\xfe\x95\xd4\xc3\x03\xa0\xb2\x93\xfd\x6e\xda\xa1\x0b\xe0\x7e\x7a\xe3\x53\x3b\xd9\x9b\xca\xe1\xca\xe7\xdd\x94\x9a\x9d\x5f\xda\x2f\x4a\x3b\xd1\xff\x3f\xd4\x0d\x4f\xcf\x81\xab\xf0\x6b\xd8\xd3\x8a\xa1\xe7\xfc\x9d\x92\xcd\xfb\xae\x03\xf8\x46\x4e\x5e\x7f\xd7\x09\x66\x89\xc5\x2e\x09\x45\xfa\x61\x59\x9a\xc9\xba\x92\x84\xff\x5c\x74\xd5\xbd\x94\x53\xbb\x4c\x28\x95\x90\xb5\x17\xa6\x09\x4b\xa9\x71\x25\x9b\xf7\x33\xbb\x54\x98\x1a\x61\xe9\xe6\x7d\xef\x1d\xdc\x99\x5d\x43\xde\x49\x31\xac\x06\xd5\x2e\x20\xef\xa3\x17\x56\x43\x6a\x17\x15\x53\x2d\x64\x20\x8d\x85\x2f\xf1\x3b\x1b\x56\x2f\xc9\x05\xf8\x3c\x03\x2d\xd0\xd9\xc5\x85\x69\x85\xd2\xad\xb9\x5e\x08\xb9\x59\x6a\x6a\x74\x06\x40\xc1\x28\x4c\x02\x96\xc1\xb4\x0b\xcb\xf7\x1d\xcf\x3c\x48\x3c\x50\x9a\xa1\xa4\x8a\x7a\xd1\x39\x65\x24\x66\x5d\x22\xfe\xbf\x00\x00\x00\xff\xff\x63\xd4\xf0\x9c\xb1\x6f\x00\x00") + +func fontsLeanFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLeanFlf, + "fonts/lean.flf", + ) +} + +func fontsLeanFlf() (*asset, error) { + bytes, err := fontsLeanFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/lean.flf", size: 28593, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLettersFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x97\x69\x5f\x22\x39\x10\xc6\xdf\xf7\xa7\x78\xc6\x89\x0a\xea\x88\xb2\x5e\x8c\x2c\xc6\xd1\x5d\x15\xc7\x5b\x01\x15\x45\x44\xf0\x42\x40\x10\xbc\xfd\xec\xfb\xab\x4a\x3a\x9d\x34\xed\xba\x2f\xb6\x6c\x52\xff\x3c\x55\x95\x4a\x1f\x1c\xd6\xea\xb5\x64\x59\x60\x06\xd3\x48\x4e\x60\x72\x1a\xb3\xde\xef\xea\xc3\x43\xb5\xdd\xc1\xf9\x33\xf6\xda\xd7\xed\xf2\x1d\xb2\xe3\x58\x69\xd6\xeb\xe5\x56\xb9\x5e\xbf\x1e\x03\xb2\xdd\xfa\x33\x26\x27\xc6\x30\x99\x4a\x4d\x79\x1e\xd0\x2c\x95\xe0\xdb\xe8\x8f\x48\x1b\x35\x09\x28\x95\x9a\x1e\x4a\xe3\x99\x44\xdc\xaf\x7a\x8b\xec\x84\x37\x53\x11\x2b\xa6\xc7\x4b\x5e\xac\x14\x47\x91\x86\xff\xd2\x28\x56\x8a\x27\xc0\xc9\x1e\x5c\x4b\x77\xb8\x99\xac\x94\x5b\xe5\x4a\xa5\xda\xe9\x8c\x37\xdb\x97\x19\xcf\x13\x32\x74\x48\xef\xdb\xb7\x6f\xc2\x1d\x01\xb8\x2c\xbd\x01\x32\x11\x78\x0c\x0c\x0c\x40\x85\x11\xe1\xa5\xd9\x0f\x6b\xdf\xbf\xd3\x41\xf8\x5d\x59\x08\xad\x04\x53\x26\x3d\x24\xde\x7e\x14\x85\xf4\x12\x74\x91\x84\xf4\x8a\x3f\xd4\x9c\xae\xe5\x9b\x9e\x27\xec\x9e\x83\x83\xc0\xe0\xa0\x60\x18\x1c\x54\xcb\x91\x46\xc0\x92\xb0\x72\xac\x3e\x18\x1a\x1a\xd2\x5b\x1d\x1a\xa2\x43\x23\x9b\x90\xde\x50\xa4\xea\x6c\x75\x98\x82\xc3\xc3\xc3\x3c\xc2\x5c\x43\x6b\x54\x05\x34\x8b\xc5\x62\x42\x7a\xb1\x58\x0c\x7d\x4e\xc5\x4c\x6a\x3c\x1e\x67\x35\x1e\x8f\xf7\x39\x15\x0b\xae\xfc\x08\x80\x11\x0a\x8f\x8c\x8c\xc0\xf2\x46\x0f\xdd\x19\x96\x46\x47\x47\x99\x46\x95\x39\x14\x44\xed\x13\x0d\x9f\x96\x87\x31\x1a\xc7\xc6\xc6\x78\xec\xeb\x60\xa8\x44\x16\xd2\xfa\x29\xaa\xc3\xf8\xf8\xb8\x19\xad\x73\x48\xe8\x7b\x9f\xd0\x90\x48\x24\xb8\x86\x3c\x01\x7b\xb8\x77\x7a\x82\x8c\xb4\x89\x09\x00\x13\x13\x9f\x50\x90\x67\x6f\x6c\x92\x84\xc9\xc9\x49\x92\xad\x51\x2b\x3a\x29\x99\x4c\x26\xb9\x6b\x92\xcd\x5f\x23\x99\x4c\x8a\xfe\x68\xd2\xed\xf0\x07\x9b\x2e\x21\x64\xb2\x34\x28\xcd\xc9\xb3\x6f\xeb\xd4\x94\x7f\xc2\x53\x3e\x92\x57\x38\xa5\x2d\x94\x60\x2d\x31\xcd\x46\xea\xf4\xb4\x7f\x67\x02\x0d\x00\x61\x58\x0b\xfa\xcf\xcc\xcc\xa8\x25\xc9\x33\xcd\xb0\x29\x02\x25\xa8\xa8\xd6\xac\xe2\x59\x65\x5a\x34\x34\x3b\x3b\xab\x12\x09\x98\x18\xc2\x9d\xe7\xc8\x48\x9c\x9b\x03\x30\x37\x27\xbe\xd2\x42\x97\x4d\xaf\x98\x22\x23\x4a\xa5\x00\xa4\x52\x46\x4b\xe9\x12\x15\x25\x9f\xea\x7f\x56\x7f\xfe\xfc\x19\xc5\x6e\xd2\xfc\xfc\x7c\x88\xe7\xe7\x9d\xcf\x86\x74\x3a\x2d\xa4\x97\x4e\xa7\x11\x38\x2d\x46\xbd\x7f\x7d\xfa\x53\x99\x43\x9f\xbd\xbb\x48\xc9\x64\x32\x1c\xc8\x64\x32\x81\xf3\x45\x3f\x75\x61\x61\x81\xe6\x0b\x0b\x58\x58\x50\xba\xf6\x4a\x0f\xbc\x59\x5b\x4a\x29\x59\x92\x90\x12\x52\x48\x4f\x42\x92\xcc\x04\x13\x35\x79\xf6\xc6\x16\x17\x17\xd5\x6e\x17\xc9\x88\x48\xc0\xe2\x22\x13\x9b\xa3\x59\xc5\xbf\xc8\xb8\x98\x1c\x7e\x29\x62\xd1\x68\xbf\x1c\xcd\xee\xbc\x44\x46\xe2\xd2\x12\x69\x4b\x86\x5c\x2d\xc8\xb3\x8a\x97\xc9\x38\x91\xdc\xf2\xb2\x4f\x58\x5e\x0e\x11\x27\xba\xc5\x7f\x29\x13\x44\x7e\x3f\x56\x34\x39\x1a\xe7\x59\xc5\x7f\x2b\x13\x44\x7e\x22\x09\x3e\x05\x5a\xe4\x63\xb0\xb2\xb2\xb2\xc2\xe2\xca\x0a\x4d\x84\xf4\x08\x54\x22\x13\x6b\x9c\xa6\x28\x28\x5e\x5d\x05\xb0\xba\x2a\x5c\x62\x13\xd1\x51\xab\x78\x8d\x8c\xa4\xb5\xb5\x35\x44\x78\x13\xb7\x9f\xd8\x6c\x36\x2b\xa2\x29\x9b\x35\x5a\x96\x2c\x74\x9e\xeb\xeb\xc0\xfa\xba\x60\x58\x5f\x07\x03\x69\xae\xa2\x73\x82\xb2\xdf\xbf\xfd\x4b\xf1\x15\xb1\xb9\x3d\x37\x36\x88\x36\x36\x04\xe1\x06\x91\x42\xf0\x21\x42\x09\x06\x61\x2d\xb1\xb9\x09\x60\x73\x53\x10\x6d\x1a\xc2\xa6\x21\x6c\x1a\x52\x9a\x7d\x6f\xb7\xc8\x68\x7b\x5b\x5b\x00\xb6\xb6\x3e\x21\xce\x0b\x7f\xc9\x6d\xb3\x91\xb8\xbd\x0d\x60\x7b\x5b\xf4\x69\x70\xc9\xee\xbc\x43\x46\xe2\xce\x0e\x80\x9d\x9d\x3e\x52\x51\xce\xc3\x8e\x5b\xbc\xcb\x46\xe1\xdd\x5d\x00\xbb\xbb\x22\xac\x85\xa3\x76\xe7\x3d\x32\x0a\xef\xed\x99\x8d\x19\x8d\x95\xbd\xbd\x7e\x4d\x15\xef\x2b\x63\x71\x7f\x7f\x5f\x9f\xd5\xbf\x93\x29\x3e\x38\x00\x70\x70\x20\xbe\x22\x1c\x90\x85\x8a\x73\x39\xc6\x5c\x4e\xb8\x0c\x9e\xe4\x72\x2a\x3d\x97\xe3\xb9\x2a\xcd\x71\xc8\x7a\x5e\x78\xa1\x7c\x5e\x71\x3e\x2f\xa2\x26\x79\x3d\x41\x3e\x8f\x3c\xbf\x78\x01\x15\xcb\x3b\xab\xf1\x72\x85\x02\x51\xa1\x40\x01\xe2\x42\x41\xe5\x14\x0a\x34\x73\x55\x3b\xd7\x5a\xe2\xf0\x10\xc0\xe1\xa1\xb0\x09\x87\x64\x6a\x29\x82\x30\x99\xe2\x23\x32\x25\x69\x7f\x74\xc4\x29\x47\x47\x9c\x6a\xc5\x55\xc1\xf1\xf1\xf1\xb1\x20\xc7\xe1\xb0\xe3\x98\x9f\x5a\x2c\xfa\xcf\x07\x13\x47\x88\x54\x4a\xb1\xe8\x6f\xa5\x58\x74\x3e\x12\x4e\x4e\x4e\x4e\x58\x88\x70\x26\xa6\x1f\xc6\xd3\x53\x5a\xe4\xf4\xf4\xf4\x94\x1c\x70\x2a\x82\x2f\x78\xdb\x7d\xf1\x5b\xd8\xa2\x92\xb2\xd0\x43\x7f\x46\xa1\xb3\xb3\x33\x92\xd5\x18\xfe\xed\xec\xae\x56\x2e\xa3\x5c\x26\x62\x20\x2a\x97\xa1\x89\x9c\x8e\x06\x1d\xce\xcf\xfd\x62\x9b\xc8\x8c\x76\x7e\xee\x68\xf6\xf6\x82\xc6\x95\x4a\xa5\x22\xa4\x57\xa9\x68\xc5\x00\x47\x2a\xce\x85\x66\xb8\xb8\x10\x0e\x5d\xb0\x09\xe9\x5d\x5c\xf4\x6b\xd1\x3d\xab\xd5\x2a\x41\xb5\x0a\xa0\xca\xa0\x15\x30\xb9\x3d\x6b\xb5\x9a\x90\x5e\xad\xc6\xb5\xb5\xd0\xec\xb3\x3b\x76\xc9\x26\xa4\x77\x79\x09\x40\x93\xaf\x71\x96\x22\x96\xb8\xf8\xea\xca\x2f\xb6\x89\xcc\x68\x57\x57\x0e\x59\xe7\x76\x7d\x7d\x6d\x6e\xae\x62\x7b\x34\xdb\xbb\xb9\xb9\x09\xde\x19\xd6\xdc\xf5\x37\x37\x37\x37\x5c\x70\x7b\xab\x33\x09\x6e\x6f\x19\x6e\x6f\x6f\xb5\x62\x40\x85\x82\xcd\xd4\xeb\x75\xf1\xf9\xe8\x5e\x2b\xdd\xe0\xee\x0e\x7c\xdc\xdd\xa9\xd9\x1d\xa0\x5e\x5f\xcc\xe0\x7e\x36\x05\x0b\x36\x1a\x68\x34\x1a\x8a\x1a\x40\xa3\xa1\xb4\x3e\x8a\x7c\x3e\x9a\xcd\x66\x93\xa0\xd9\x04\x9a\x4d\x1b\x4c\x28\xaa\x67\xab\x85\x56\x4b\x53\x0b\x68\xb5\x14\xd1\x44\x45\x83\xbc\xa8\xf7\xf8\x3d\x99\x90\xde\xfd\x3d\x68\x42\xda\xbd\xaf\x71\x96\x4b\xd6\x86\xdb\x6d\xb4\xdb\x0a\xda\x40\x5b\x29\x26\xd4\xf7\x8f\xae\xaf\x74\x3a\x1d\xf2\x9d\xd0\x9c\xa6\x9d\x60\x2e\xbd\x87\x07\x95\x10\xf8\x87\x07\x7b\x0e\x12\xc2\x3f\xcb\x54\xa8\xdb\x05\xd0\xed\x7e\x42\xe8\x76\xbb\x5d\x74\xa3\x6e\x03\x15\xf7\x7a\x00\x7a\x3d\x0a\xf7\x7a\x74\x70\x62\x8f\x64\x55\xd2\x8b\xfc\x17\xc6\xd4\x3f\x3e\x2a\x7c\x7c\x0c\x4f\xf0\xf8\xa8\x0f\x2e\xa7\x18\xbd\xfa\xbe\xeb\xcc\x52\x4f\x4f\xc0\xd3\x13\xc7\x09\x6d\xb0\x42\xfd\xa7\xf0\xfc\x0c\xe0\xf9\xd9\x21\x3c\xb3\xf9\x15\x96\xe6\xdc\x9e\x17\x32\x4e\x7a\x79\xe1\x86\x2f\x2f\x21\x3d\xe8\xf6\xfa\xca\xc2\xeb\x2b\x25\xbc\xbe\xbe\xc2\xf6\xbe\xae\xf3\x08\x84\xf4\xde\xde\xa2\x07\xe9\xbd\xbf\xeb\xcb\x4a\xc0\x75\xef\xef\xef\xb6\xd7\xba\xce\xb3\xdf\x38\x1f\x1f\xf8\xf8\x10\xd2\xfb\x00\x3e\x9c\xa7\xae\x1f\xa4\x67\xfd\xfd\xdf\x93\x7f\x02\x00\x00\xff\xff\xd9\x6e\xbb\x3d\xd6\x15\x00\x00") + +func fontsLettersFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLettersFlf, + "fonts/letters.flf", + ) +} + +func fontsLettersFlf() (*asset, error) { + bytes, err := fontsLettersFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/letters.flf", size: 5590, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLinuxFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\xcd\x6e\xe3\x36\x10\xbe\xf3\x29\x3e\x38\x06\x94\xb4\x1a\xaa\x4e\x36\x87\x14\xcd\x82\x3d\xb4\x97\x16\x58\xa0\xbd\x0a\xb5\x68\x8b\xb2\x84\x95\xa8\x85\x44\x75\x13\x94\x7d\xf7\x82\xa4\xa4\xc8\x8e\x9d\xed\x03\x04\x96\x61\x8a\xdf\xfc\x7e\x33\x43\xba\xa8\x8b\x5b\xb9\xc6\x07\xdc\xe1\x01\xb4\xc1\xe6\x8e\xd5\x95\x1e\x9e\xb0\x7b\xc6\xef\xb2\xeb\x9e\xf1\x67\x53\x99\x12\xf7\xc9\xe6\x36\x79\xb8\x07\x61\x27\x7b\x95\xa3\xd5\xe0\x7d\x75\x40\x5b\xe0\x8f\x76\xa7\x3a\x53\xe2\x37\xd9\x35\x52\x73\xf6\x6b\x75\xa8\x95\x41\xa7\x6a\x25\x7b\x85\x5b\xfe\x03\x88\xf0\xf3\x70\x18\x7a\x83\xfb\x18\x9b\x87\x87\x3b\xc6\x7e\x79\xfa\x52\x4b\x2d\x4d\xd5\x6a\x67\xa4\xa8\xba\xde\xa0\xae\xb4\xfa\x91\xb9\x98\x40\x58\x35\xf2\x50\xed\xa1\x87\x66\xa7\xba\x15\x8a\xb6\x43\x51\xd5\x0a\x55\xae\xb4\xa9\x8a\x6a\xef\x95\x99\x04\x00\x42\x5f\xb6\x43\x9d\x43\xd6\x5f\xe5\x73\x8f\x9d\x42\x26\xa3\xd8\x2b\xe9\xf6\x2b\x43\x10\x32\xa5\xc2\xaa\x94\x5d\xbe\xab\xa5\xfe\xbc\x72\x71\x7d\xe9\x2a\x6d\x7a\xc8\x1e\x12\x7e\x37\xc6\x6e\x30\xd8\x4b\x1d\x19\x67\xa6\x6f\x86\xbe\x54\x39\xfb\x10\x2c\x94\xaa\x3a\x94\xc6\x45\x2c\xb1\x2f\x65\x27\xf7\x46\x75\xec\xee\x0d\x30\x86\x6e\x0d\x2a\xbd\xaf\x87\xbc\xd2\x07\xe4\xaa\xdf\x2b\x9d\xab\xae\x67\x0f\x41\xad\x91\x4f\x3e\x73\xd4\x4a\x1f\x4c\x89\x6b\xf5\x34\x09\xef\xdb\xa6\x51\x3a\x10\xd3\xdf\xe0\x7b\x48\x14\x43\x7e\x50\x28\xe4\xde\xb4\x1d\xa3\x8d\xb7\x90\xab\x42\x0e\xb5\x09\xc1\x36\x6d\xae\x7c\xe2\xa6\xac\x7a\x14\xad\x36\xb8\xae\xab\xcf\x0a\x2b\x6a\xb0\xb9\x5f\xb9\xda\x39\xbb\x52\xe7\xde\xee\x0d\xdb\xdc\x79\x2b\x81\x69\x17\xfe\x91\x5b\xc6\xd6\x62\x7e\x04\xe3\xc4\x05\xcb\xfe\x8e\x04\x43\x0b\xe1\x98\x15\x82\x59\xeb\x56\xf3\x57\x30\x58\x0b\xc1\x1e\x81\xc7\x69\x8d\x20\xc9\xc9\x3a\x03\x48\x6d\x0a\xc1\x32\xb2\x14\x05\xcc\x81\x2d\x62\x8a\x05\x43\x82\xc4\x83\x11\xda\x17\x50\x7a\xe3\xda\x9b\xca\x67\xc7\x82\x61\x7c\x04\x0b\xda\xd7\xb8\x76\xef\x19\x65\x0b\xa7\xdc\x6d\xdd\xe0\x46\xb0\x88\xa2\x97\x68\x52\x9b\x08\x46\xdf\x91\x60\x89\x4d\x27\x9b\xb8\x82\x60\x57\x57\x57\xe3\x6a\xdc\xf4\x4f\x32\x3a\xc2\x2c\x81\x13\x89\x4f\x93\x84\xe7\x69\xcc\xc4\xf9\xc4\x4b\x26\x9c\x88\x1c\x6a\x1d\x33\xd6\x25\x4a\x34\xd3\xe0\xb5\x13\xee\x69\x13\x0c\x44\x93\x7d\xa7\xb5\x24\x87\x96\xcc\xf1\x60\x11\x20\x6b\x5f\x81\x88\x3d\x18\x91\xf7\x06\x64\x4b\x30\x26\xef\x22\x45\xea\xf5\xa2\x99\x9b\x98\xb8\x0b\xda\x22\xf1\x15\x3f\xeb\x2f\xa3\x04\x89\x27\x3b\x3a\xce\xcf\x61\x49\xc2\x4f\x4c\x4e\x80\xd3\xc9\x96\x75\xc0\x5a\xb0\x76\xfc\x62\xbd\xd8\x48\xa6\x8d\x35\xb6\x5b\xd7\x81\x09\xdc\xd6\x3a\xa3\xcc\xfd\x00\x01\xdc\x06\x90\x88\xe6\xdd\x39\x9a\xf5\x76\xeb\x5e\xd7\x29\x52\xf7\x13\x51\xb4\xd0\x8c\xa7\x50\xe1\xfb\xf9\x25\x22\xe5\x96\x72\xd1\xd1\x7c\xae\x59\x28\xd9\x5f\x27\x74\x38\x8c\x7e\xc2\xeb\x8c\x27\xad\xb3\x45\xe3\x9e\xe1\x91\xfc\xe8\x0c\xc3\x16\x96\x2e\x96\x7b\x06\x5f\xb5\x57\x00\xa3\x6d\x30\x9b\x2c\x41\x1e\x5a\xd3\xc2\x3e\x8e\xa9\x44\x8b\x8e\x98\x84\xbc\x80\x07\xe7\xfe\x1e\x5b\x3a\x9e\x7b\xf6\x28\x20\x1e\x07\x25\x8e\x40\x42\x94\x1d\xb5\xb4\xf3\x1b\xda\xc9\x6e\xb7\x38\xd3\xf3\x9c\xfc\x67\x64\x78\xf4\xbd\xa0\x64\x12\x1a\x65\x78\x36\x8a\x9c\xba\xf9\xc6\x68\x2d\x98\x8b\x2e\x33\xf7\x09\xb1\x07\xd3\xf4\x04\x0c\x19\xd0\x85\x14\xc3\x0c\xa6\x48\x2f\x56\x2c\x73\x55\x39\x33\x30\x53\x5a\x17\xa3\x0e\x02\x48\xe1\xa7\x1f\xc8\x5e\x02\xbf\xc4\xde\x91\x91\x23\x2b\x1f\xe1\x8b\x14\xb9\x0c\xb2\x73\x6e\x3e\x8e\x6e\x96\xfc\x7c\xf3\x0c\x8a\x63\x72\x37\x81\x03\xb2\xc5\xa9\xe5\x4f\x91\x91\x94\x93\xb3\x87\xf8\x74\xce\x51\x34\xf7\xd9\xf8\x39\xb7\x78\x9f\xc1\xf7\x19\x7c\x9f\xc1\xb7\x66\xd0\xdd\xac\xff\xf8\x79\x9b\xaf\xad\xa9\x8d\xe6\x5e\x12\xcc\x8f\xe2\xbf\x82\x25\xf3\xdf\x35\xaf\xee\xae\xfc\x6d\x3c\xbf\x4d\x36\xdf\x18\xc8\xff\xb3\xf8\x2f\x00\x00\xff\xff\xf6\x6c\xf8\xe3\x63\x0c\x00\x00") + +func fontsLinuxFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLinuxFlf, + "fonts/linux.flf", + ) +} + +func fontsLinuxFlf() (*asset, error) { + bytes, err := fontsLinuxFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/linux.flf", size: 3171, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsLockergnomeFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\xdf\x6b\xe3\x38\x10\x7e\xf7\x5f\x31\x94\x82\x1b\x22\x59\xbd\xf6\xa0\x30\x38\x46\xdc\xc1\x1d\x2c\xfb\xb0\xb0\xaf\x82\x38\x49\xdd\x6d\x68\xda\x94\xb4\x7d\xe8\x22\xfc\xb7\x2f\x1a\x49\x96\x64\xcb\x61\xd9\x5d\x92\xa8\x1a\xcd\x37\xdf\x7c\x33\xfa\xf1\x70\x78\xb8\xd9\x5c\xc2\xdf\x70\x0b\x37\xd7\xc0\xff\x82\xdb\xe2\xeb\x71\xf7\xd4\x9d\xfe\x7f\x39\x3e\x77\xb0\xfd\x84\x7f\x1f\x4f\xfb\xb7\xf7\xe3\xeb\x63\x77\x82\x2f\xc7\xb7\xee\xf5\x11\xbe\xed\x4f\xfb\xc3\xe1\x08\xf5\x2b\x0d\x76\x37\x77\x77\xd7\x72\x77\xdc\x9e\x36\xd5\xc7\xcb\xbe\xea\xee\x3f\x9a\xe2\xbf\xfd\x8f\x43\xf7\xbe\xff\xd9\xdd\x1b\x90\xef\xfb\xe7\xe3\x0b\xfc\x73\xda\xdc\x1f\xba\x4f\xa8\xdf\x3e\xb7\xb7\x72\xb3\xed\x4e\xd5\x66\x57\x7d\x3c\x35\x45\x71\x79\x29\xe3\x8f\x2c\x10\x35\xc8\xa2\xc5\x12\x64\x01\x4b\x30\xdf\x00\xe0\x0c\xce\xd8\x02\x98\x8f\x35\x91\x39\x8c\x64\x01\xa8\x51\x9b\x39\xc4\xd5\x8a\x1c\x86\x99\xb0\xa8\x42\xd4\x88\xca\x44\x32\x83\x46\x16\xca\x0c\x84\x5d\xd4\xba\x90\x26\xa2\x28\xcd\x14\xa2\x30\x00\xcc\xfc\xa2\x8e\x91\x04\x22\x2a\xe2\xa0\x90\xa1\x58\x33\x13\x99\x31\xa6\xd6\x23\x5e\x96\xbc\xc5\x09\xa4\x0d\x61\x46\x71\xaf\xf0\x8a\x26\x5b\x54\xde\x51\x12\x28\xcd\x2e\x70\x01\x26\x58\x09\x89\xd1\x52\xe6\x1c\x39\x27\xb3\x0e\xce\x04\x4d\x92\x59\x31\xcc\x3f\x52\x63\x98\x8b\x45\x0b\x84\x62\xa2\x21\xd1\x22\xf2\x4f\x35\xcf\x7a\x07\x43\x4e\xc1\xd4\x9b\x19\x64\x26\x0b\x04\xce\x41\x53\x49\x10\xcb\x28\x0b\x74\xd5\xf3\x65\x0d\x34\xc8\xd8\xf7\xa6\x90\xe0\x64\x14\xc4\x33\xf2\x16\x58\xb6\x06\x1e\x40\x63\x6d\xcb\xc4\x52\x78\x0d\x36\xe3\xe0\x19\x25\x2a\x83\xa1\xa5\x52\x5b\xc2\x22\x5e\x40\x19\x28\xb3\x90\x73\xce\xb2\x19\x18\x17\x2f\x83\x49\x25\xf4\x41\xa2\x41\xc3\x39\xe7\x75\x06\xc1\x2f\x50\x66\x81\x76\x7f\x97\x49\xa9\xad\x38\x8b\xe1\x3b\x6b\x88\x4b\x6b\x05\xab\xb1\xce\xf4\xdd\xb4\xee\x93\x06\x30\x52\x56\xe4\xda\x60\x33\x6d\x4e\x81\x7d\xa8\x8c\xcb\x7e\xb9\x1c\x77\x8e\xdb\x3e\xb2\x68\xd5\x7a\xad\x61\x41\x23\x4c\xe4\x71\xbb\xda\x89\x8f\xa8\x19\x55\xc3\x1d\x08\x31\x9a\x6d\x72\x2a\x44\xc3\x11\x6b\x3f\x23\x92\x90\xa1\x5a\xda\x35\x6e\x39\x59\x14\x21\xb9\x28\x19\x24\xf4\x8d\x81\x88\x4d\xbc\xcb\xe6\x16\x99\x55\x71\xdc\x34\x3b\x47\x1c\x60\xb5\xf2\x33\xa3\x70\x09\x95\x73\x12\xe8\x61\x9b\x67\x39\x01\xed\x4b\x6d\xc3\x59\x1b\x26\x3d\x3d\x0d\x57\xc3\x4c\x38\x1d\xb6\xfd\xef\x48\x70\x31\x4f\x5c\x65\xb2\x53\x23\xe2\x51\x17\x9c\x21\x1e\x6a\xb7\xf6\x48\x7d\xdf\x4f\x15\x4f\xfa\x69\xa8\x41\x1e\x29\x6e\x3a\x35\xba\x4a\xc2\xf1\x40\x57\x09\x9b\xe3\x14\x97\x25\x1a\x64\x14\x77\xc4\xdb\x9c\x98\xd3\xcc\xd3\xed\x32\xaa\xdd\x45\xaa\x6a\x0e\xa9\x39\x5f\xe0\x69\xb8\x11\x71\xa8\x9d\x4e\xcc\x77\xed\xa0\x45\x8c\xb4\x02\x3a\x6c\xc1\x8f\x9d\xa1\xf5\x17\xa8\x41\x56\x0e\x19\x51\xb1\xd8\x7b\xb8\xc9\x61\x18\xfb\xed\x0c\x74\xf6\xa8\xc9\xb5\xea\x9d\xa3\x11\x8e\x0f\x31\x97\x22\x21\xd3\xa4\xfd\xf2\xa7\x98\x29\xae\x02\xfb\x4a\x88\xef\x1c\x7f\xa7\x96\x7a\x7a\x21\x05\x4f\x01\x2e\xb9\xd8\x68\xcf\xd2\x12\xe7\x3d\xb1\xef\x85\x35\xb2\xc8\xc8\xfc\x29\x6c\x05\x8c\x6e\xf0\xe0\x29\xec\x1a\x65\x7f\x58\x65\x18\x44\x6c\x2d\x80\x4e\x62\x2e\x97\x16\xcd\x7d\x79\x38\x9a\x66\xe0\xe1\x44\x26\x79\xbd\x26\x96\xba\x57\xa9\x31\x07\x67\x3d\x94\x38\x93\xb4\xdb\x8d\x3a\x67\x64\x43\x15\xc4\xbc\xa7\x35\x5a\x76\x33\x8a\x58\xf5\x63\x4f\x3d\xab\x65\x6d\xb7\x44\x83\x74\xb7\x85\x63\x23\x79\x83\x44\x1b\x21\xce\xd3\xbd\x61\xb3\x79\x2a\xe7\x29\x72\x9e\xfe\x7e\x56\x19\x4f\x65\x5d\xc4\xb0\x45\xe6\x63\x56\xcc\xbc\x9f\x07\xa3\xcb\xc1\x65\x14\x1a\x8a\xc4\x6c\x56\xe4\xa7\xd2\x97\xb6\x2c\x80\x4f\x5e\x73\x8a\x1a\x72\x55\x83\xbb\xec\x07\x03\xe3\xb8\x66\xe1\x39\x33\xfe\x95\x85\xfb\xff\xa7\x83\x5f\x01\x00\x00\xff\xff\x0f\xc2\xf4\x69\xae\x0c\x00\x00") + +func fontsLockergnomeFlfBytes() ([]byte, error) { + return bindataRead( + _fontsLockergnomeFlf, + "fonts/lockergnome.flf", + ) +} + +func fontsLockergnomeFlf() (*asset, error) { + bytes, err := fontsLockergnomeFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/lockergnome.flf", size: 3246, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMadridFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x55\x4f\x6b\x1b\x3f\x10\xbd\xef\xa7\x78\x98\x85\xdf\x2f\x87\xf5\xc4\x49\xa1\x34\x78\x82\xa1\x3d\xf5\x90\x5b\x4f\x55\x31\x5b\x67\xdd\x38\x24\x76\xea\xb5\x53\x4a\xd5\x7e\xf6\xa2\x91\xb4\x92\x56\xda\x4b\x0d\x6b\xb4\x7a\xf3\x7f\xde\xcc\x6e\x9f\xb6\x57\x6d\x8d\x37\x58\x60\x71\x89\x66\x81\xb7\xd5\x73\x7b\x7f\xdc\xdd\xcf\xb7\x4f\x5b\x7c\xfd\x89\x8f\xe7\x76\x8f\xf7\xed\x11\xff\x3f\x6e\x56\x8f\xe7\x6f\xe7\xee\xd4\xcd\xbf\x9f\x77\xcf\xf3\xf3\xe6\x79\xde\xf5\x17\xd5\x6b\x77\xec\x77\x87\x3d\x16\xf3\x4b\x34\x0d\xae\xae\xe9\xee\xf0\x4a\xef\xae\xab\xea\x53\xdf\xf5\xe8\x5f\xda\xfd\xae\x7f\xc0\xe6\xa1\x3d\xb6\x9b\x53\x77\x44\xdf\x9d\xf0\x63\x77\x7a\x40\xf3\x01\x87\x97\xd3\xee\xb0\xbf\xa9\xf0\x2f\xbf\x75\x38\x55\x9f\xc1\x68\xff\x03\xa0\xc0\xe8\xcc\x01\x5f\xc0\xd8\xc9\xe9\x17\x18\x07\x39\x69\x30\xce\x72\xfa\x0d\xc6\x5e\x94\xff\x80\x71\x57\x55\x75\xbd\x8a\x9f\x55\xa5\x6b\xfb\x70\xbd\xaa\x20\x17\xe6\x0d\x88\xff\xdc\x25\x1b\x99\x01\x5e\x55\xa4\x95\x39\x2b\x23\xa6\x34\xc9\xbd\x00\x0c\x79\x21\x03\x10\x38\x00\xd0\x17\xe6\x8a\x0d\xac\x48\x05\x80\xac\x77\xff\x18\x65\xe3\x4b\x5e\xd5\xe0\x50\x3c\x41\x8b\xd5\x70\x29\x9e\x1b\x6e\xea\x21\x22\xef\x0c\x03\x60\xcf\x1e\x70\x8e\x68\x70\x86\x48\x12\x05\x49\x0e\x92\xa2\xc4\x36\xb3\x48\x92\xd8\x78\xd6\x64\x82\x53\x1c\xd5\x42\x6e\x6c\x0d\xa2\xca\x89\xb4\x2b\x50\x22\x6d\x01\x5e\x8e\xcd\x40\xec\x2c\xd9\xda\xd0\x01\xd0\xa2\x31\x6b\x54\xe6\xd8\x46\xc4\x05\x40\xd4\x69\x56\xce\xe1\x36\x77\x4e\xce\x48\xe6\xdc\xd7\x26\xd4\xc7\xbd\x50\xd2\xc7\x25\xa7\x7d\x5c\xaf\x3d\x9b\x22\x8a\x49\x73\xf9\x36\x6d\xae\xaf\x07\x8d\x7b\xe8\xb2\x9b\xd1\x54\xda\xd2\x08\x24\x80\xe1\x9e\x5e\x0a\x5b\xe5\x9c\x6a\x00\x63\x53\x2c\x21\x69\x49\x98\x29\x77\xce\x99\x46\x0c\xe8\x02\x3d\xb0\xce\x34\x30\x11\xae\x9f\x49\xed\x2b\x69\x4d\xac\x91\x31\x4c\xdb\x59\x71\x4e\xe3\xa1\x02\xca\x89\x91\x9d\x3d\xcd\xce\xad\xf7\x1b\x47\xa4\x0a\x05\x54\x43\x39\x8a\x59\xd3\x54\xd6\x56\x43\x4d\x69\x64\x80\x5b\x29\x85\xc1\xb0\x14\x48\x88\x80\xa9\xa8\x80\x28\x49\x28\xdf\x40\x0f\xc2\xe1\x60\xcd\xf0\x22\x41\x0a\x9e\x95\xf1\xc0\x47\x91\xc6\xc0\x88\x99\x54\x9e\x6d\xcd\x7e\xa5\x69\x8e\x58\x8f\x60\x26\xb6\x6f\xa3\x16\x16\x64\x7b\x23\xd4\x78\x18\xc4\xf1\x55\xc5\x66\xbe\x56\x95\xca\x16\x2b\x6c\x60\x3a\x9a\x68\x47\x23\x0c\xfb\x42\x27\xab\xc7\x69\xdc\x88\xc6\x4d\x0c\xe8\xb2\x29\xaf\x61\xb7\x46\x52\x9b\x3a\xae\x03\x26\x22\x92\xff\x51\x44\xa5\xb5\xa3\xd3\xa4\xe0\x3e\x35\x89\x09\x99\x5d\x21\x74\xf8\x98\xc1\x07\xa0\x38\x8e\xc2\x47\xed\x1d\x7a\x97\x79\x52\x69\x34\x49\xb6\x59\xe1\xf4\x78\x3a\xca\x3d\xd0\x16\xa8\x7d\x91\xf2\xfa\xc8\xa2\x4d\x08\xd5\x94\xf3\x28\xcf\x43\x02\xa8\x14\x70\x7b\x42\xdb\xcf\x72\xbc\x0d\x2c\xa6\xe6\xe6\x8e\x66\x6a\xc2\x5c\xdc\x35\x1f\x2e\x8d\xf9\x2f\x03\xe3\x86\x31\xf4\xa2\x0e\x4f\xf8\x0c\x08\x45\x92\xcf\x00\x4d\xf1\x9e\xa6\x28\x48\x65\x0a\xda\x28\x30\x2e\x31\x4d\xb5\x90\xc2\x7a\x8e\x81\xa6\x69\xca\x6c\x70\x57\xf9\xfa\xfc\x1b\x00\x00\xff\xff\x57\xd0\xd4\x0a\x85\x0a\x00\x00") + +func fontsMadridFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMadridFlf, + "fonts/madrid.flf", + ) +} + +func fontsMadridFlf() (*asset, error) { + bytes, err := fontsMadridFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/madrid.flf", size: 2693, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMarqueeFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x8f\x1c\x35\x10\xbd\xcf\xaf\xa8\x43\xae\x98\x30\x42\x22\xf8\xd4\x1c\x92\x1b\x07\x56\xe2\xbe\x41\x9a\xa0\x95\x56\x20\xc1\x5e\xe0\xd7\xa3\xe9\xb6\xcb\xef\xbd\x2a\x77\xcf\x2c\xab\x6c\x36\xdd\x76\xb7\xbb\xbe\xeb\x55\xd9\xfb\xe5\xf9\xcb\xf9\xf3\x3b\xfb\x60\x3f\xd8\xf9\xbd\x7d\xf3\x9d\x9d\x4f\x3f\xff\xf4\xf0\xcb\xaf\x1f\x3f\xda\x6f\xff\xd8\xc3\x9f\x7f\xd8\xa7\xbf\x9e\x5e\xfe\xb5\x0f\xdf\xfe\xf8\xfd\xe9\xd3\xd3\xef\xcf\x97\x17\x7b\xb8\x3c\x5f\x3e\xff\x7d\xb1\x73\x79\x7f\x7a\xb7\x24\xbf\xb6\x2c\xa7\x52\x2b\x5f\xac\x5d\xcc\xac\x3d\xbb\x8e\xd6\x87\xa5\xfa\xcd\x6c\x7d\x7f\x7c\x6b\xf7\xfe\x73\x9d\x96\x5a\xad\x5d\x57\x0e\xeb\xcf\x7a\x0f\x6f\xef\x5c\x8c\x8c\xd6\x79\x7f\xb3\x4a\xbd\xa9\x56\x45\x8e\xed\xbb\xf1\x76\x1b\x45\xaa\xa0\xc9\x4a\x70\x5d\x89\x1f\x47\xa9\xdb\xba\x6e\xc9\xb1\x0e\x09\x96\xca\x04\x41\xc2\xab\x9a\xfe\x71\xce\x58\x24\xdc\xde\x34\x07\xcd\x2f\x4d\xc4\x46\xae\xd1\xd7\x9b\x8b\xeb\xec\x1a\x87\xec\x25\xdd\x88\x28\x1b\x4f\x34\xf1\x4b\x33\x5f\x77\x54\xf7\xb5\x75\x8f\xc7\xf7\xc9\xf7\x4c\x3f\x09\x07\x08\xc2\xe8\xfe\xce\xb4\x0c\x86\xe9\x1a\xa5\x83\x0c\x76\x2e\xee\x9a\xfe\x55\xbc\x23\xe7\xec\xfd\x5d\x9c\xd8\xe8\x6d\x38\x22\x70\x78\x67\xe8\xe5\xc1\x0a\x66\xec\x23\x54\x56\x92\x1a\xcd\x03\x84\x30\x9a\x28\xc3\x40\xa6\x36\xc5\x04\xca\xfc\xb7\x38\xa8\x48\xf8\x65\xb7\x02\x46\x0c\x49\x5b\x3b\xc0\xad\xcc\x38\x7d\x4b\xc8\x36\x8a\xbe\xa0\xfa\x48\x6a\xb1\x29\x07\x61\xad\xc5\xf5\xb9\x0a\xe0\x64\x8f\x6d\x2a\x01\x88\xb3\x9e\x08\x9c\x09\x90\x37\x31\x2b\x72\x9b\x92\x26\x95\x3d\x2e\xee\x20\x44\xec\x60\xa5\xb0\x26\x9a\x50\x70\x40\xbc\x51\xc4\x59\xf7\x89\xb8\x00\x3d\x13\x41\x5e\x72\x7a\xb3\xaa\xaa\x0d\x81\xbf\x93\xf7\xb9\x91\x72\x4d\xfa\x24\x0f\x72\x90\xd7\x24\xfc\xdb\x1b\x30\xc5\x0e\x23\x05\x3a\x37\xb8\x31\x39\xf6\x0a\x05\x48\x92\x49\x13\xec\x70\xc4\x10\xec\x38\x5c\x08\x70\x46\xd5\x90\xe1\x84\x30\x04\x43\x21\x89\xa8\xc4\x26\x30\x28\x92\x8f\xd9\x93\x30\xb8\x5f\x80\x03\x15\x88\xb0\x10\x1b\x8e\xa0\x67\x45\xbd\x9e\x3e\x93\xaa\xe5\x14\x30\x61\x8c\xdb\x1a\xa8\x80\x2d\x4b\x0a\x83\xeb\xe3\xe3\x63\xc0\xe8\xbc\x59\x1a\xd1\x0d\xf1\x64\x82\x00\x59\x2e\x53\x05\xe9\x49\x48\x48\x18\xe0\x3f\xb8\x9b\x7c\x35\x60\x00\x3f\x1d\x5f\x35\xd8\x81\x35\x9a\x1d\xd0\x3f\x64\x29\x2d\xfd\x19\x35\x5e\xe4\x6e\x19\xe3\x7a\xf3\x6c\x16\x06\x0d\x88\xe0\x63\x52\x1e\x99\x4d\xc6\x50\xc8\x02\x58\x2c\xa3\x2c\x55\x05\x6b\x18\x76\xc9\x76\x17\x68\xc2\xbd\x09\xe1\x10\x61\x0b\xda\xaa\x87\x6d\x12\x11\xe9\xa4\x57\x73\x37\x12\xc4\x59\x82\x6e\x04\xb7\xbb\x93\x51\x2c\x6e\xfc\x26\x30\x3a\xba\x40\x62\x51\x07\x76\x34\x2a\x15\xfb\xa3\x9a\xf4\xf8\xc6\x85\x07\xab\x26\x20\x96\x67\x73\xb2\x2c\x6b\xcf\x66\xb6\xbc\xc5\xd9\xf7\x86\x59\x9b\x74\x7d\x87\xaf\x87\x16\x05\x7c\xc0\x20\xe7\x38\x94\x90\xa2\xa9\x59\xd0\xa8\xe6\x7c\xc1\x78\xcc\x95\x99\x72\xbe\x1a\xb1\x0c\x1c\x07\xd6\xc4\x8e\x47\xac\x1f\xe5\xcf\xe7\x03\xc2\x0b\x76\xf2\x59\xa9\xe7\x8c\xb6\x7d\xfc\x89\x59\xbd\x07\x82\x53\x0d\x45\xc1\x23\xf7\x04\x6f\x15\xef\x5c\xa1\x60\x69\x9e\xaf\x9b\x5e\x94\x5a\x1a\xc6\x64\x66\x1a\x9e\x5a\xd7\xd5\x1d\xb9\x2f\xbb\x34\x6c\x3e\xa9\xaa\x52\xd5\x23\xf4\x23\x9d\xe0\x2b\xe3\x7e\x86\x89\xbd\xcd\x8c\x18\x46\x67\xbc\x7a\x72\x03\x2a\x27\x36\x73\x67\x63\x60\xe7\xcd\x85\x27\x24\xab\x26\xc1\x9f\x55\xa0\x4c\x90\x9d\x7c\x2b\xdc\x13\x04\x90\x40\x60\x18\xc5\x2c\xcf\xd7\x99\x00\x68\x06\x57\xb9\x40\xef\x63\xd2\xc3\xd3\xbb\x14\xc2\xd3\xa8\x4d\x19\x92\xd1\x67\x0c\xef\x99\x31\xc3\xb0\x11\x03\xa7\x26\x1e\x35\x49\x1d\xe9\x1c\xb1\x8e\xd4\x5c\x43\x37\xfd\xe1\x2d\x1c\x65\x09\x3b\xdd\x20\x04\x59\x21\xa5\xa6\xfb\x16\x3c\x9e\xdc\xbf\x25\x67\x15\x85\xa1\xb4\x1c\x94\xe9\xd7\x4c\xfa\xec\xfe\x7b\x3b\xa1\xf2\x2e\x27\xee\x10\xf9\x42\x08\xa7\xe3\xa1\xa9\xa7\x59\xd6\x30\x4b\xac\xd6\x88\x9a\x20\xdd\x64\x48\x56\xe4\x46\x9b\x16\x44\x1b\xc9\x86\xb2\x60\x37\xea\x6c\xe0\xc9\x58\xc3\x84\xe6\x7d\x1f\x82\x49\xda\x01\xb2\xd3\x6f\xb7\xa9\x6e\x24\x68\x8b\x64\xa3\x8f\x9e\x16\xf5\xa5\x6f\x38\xaf\x9f\xf9\xc1\x3f\xa1\xd5\x64\x10\x24\xd5\x21\x23\x99\x7a\x04\x9e\x76\x43\x51\x66\x82\x35\x4e\x23\x73\x71\x44\xc7\x2f\xc1\xba\xd5\x32\x9b\xe2\xc9\xf9\x41\x3f\xef\x4a\xa4\xf3\xf4\xbe\xf5\x9e\xcb\x4c\x60\xd9\xc4\x37\x93\x57\x8a\xe0\x99\xe8\x6e\xb3\xf9\x75\xc4\x64\x7e\xc8\x60\x64\x50\xaf\x70\xe0\x21\x71\x4d\x3e\xdd\x94\x2c\x2a\xe4\x7e\x38\x14\x3d\x30\x08\x31\x40\xe6\x09\xc4\x5f\x8d\x32\x42\x3d\xed\xdf\x42\xbc\xa1\xdc\x03\x57\x06\x61\x45\x95\xd4\xe1\x39\x41\x03\x5c\x41\x82\xc3\x11\x85\x3a\x63\x1f\xd5\xc9\x61\x99\xc2\x55\x1c\x14\xc9\xff\x1c\xf7\x36\x98\x40\xb8\xb3\x76\x58\x6c\xa2\x2e\x13\x52\x60\xb8\x0d\x45\xa8\xb8\xce\x8d\xaf\x5b\xb5\x7c\x64\xcd\x6c\x13\x00\xd5\x32\xc9\x75\x36\x2d\x40\x2e\x64\xd2\xc7\xe4\x75\x36\xe1\xc4\xac\x9c\x57\x65\xd8\x1f\xb3\xed\x17\x52\xc0\x42\x2d\x3c\xc8\x30\x44\x74\x08\x76\x1b\xd5\x42\x8a\xee\x24\xc3\xa6\x84\x8b\xfc\xf1\x34\xfc\x59\x44\x51\xff\x80\x30\x05\x94\xa4\xe7\x22\x67\xb3\xd9\x29\x83\xc9\xa6\x99\xe2\x90\xb7\xab\x52\xbb\x24\x8e\xb7\xd3\xc4\xed\xff\xf6\x35\xcd\x6f\x25\xb7\x23\xc4\xe0\x54\xbd\xe2\x5a\x8a\xa3\xff\x6b\xbc\x9c\xe4\xdf\xd7\x7a\xf0\x5f\x00\x00\x00\xff\xff\x20\x3b\xa8\x10\xbe\x20\x00\x00") + +func fontsMarqueeFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMarqueeFlf, + "fonts/marquee.flf", + ) +} + +func fontsMarqueeFlf() (*asset, error) { + bytes, err := fontsMarqueeFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/marquee.flf", size: 8382, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMaxfourFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x55\x4d\x6f\xe3\x36\x13\xbe\xf3\x57\x3c\xaf\x21\xc0\x0e\x36\x34\xe3\x4d\xde\x43\x8a\xa0\x60\x0f\xed\xad\x97\x9e\x52\x80\x00\xcb\x48\x94\x2d\x44\x96\x16\xfa\x68\xb2\x00\xa1\xdf\x5e\x70\x48\x4a\xb2\x77\xb3\xbd\x14\xd0\x07\x35\x9c\x8f\x67\x9e\x19\x8e\xca\xba\xfc\x6c\x32\x3c\xe0\x1e\x87\x03\xee\x70\xb8\x67\xbf\x9b\xf7\xb2\x1d\x3b\xbc\x7c\xc5\x1f\xa6\x29\x4c\x5d\xfb\x77\xdf\x9e\x71\x10\x8f\x0f\x78\xea\x47\x63\x72\x99\xf7\x7f\xef\xdf\x4c\xf7\x56\xe5\xaf\x7b\x93\xef\xc7\xd7\x9f\xd9\x6f\xd5\xb1\xb6\x03\x3a\x5b\x5b\xd3\x5b\x7c\xde\xdf\x81\x73\xfc\x32\x1e\xc7\x7e\xc0\xff\x6f\x71\x78\x7c\xbc\x67\xec\xd7\xf7\x2f\xb5\x69\xcc\x50\xb5\x0d\xda\x12\x65\xd5\xf5\x03\xea\xaa\xb1\x3f\x31\x0f\x06\x1c\x9b\xb3\x39\x56\x39\x9a\xf1\xfc\x62\xbb\x0d\xca\xb6\x43\x59\xd5\x16\x55\x61\x9b\xa1\x2a\xab\x9c\x8c\x99\x01\x00\x8e\xfe\xd4\x8e\x75\x01\x53\xbf\x99\xaf\x3d\x5e\x2c\xfe\x32\xdb\x5b\x32\x6a\xda\x37\x96\x05\xa5\xe1\x64\xb1\x39\x99\xae\x78\xa9\x4d\xf3\xba\xf1\xb8\xbe\x74\x55\x33\xf4\x30\x3d\x0c\x48\x7a\x8b\x97\x71\x40\x6e\x9a\xed\xe0\xdd\xf4\xe7\xb1\x3f\xd9\x82\x3d\x04\x0f\x27\x5b\x1d\x4f\x83\x47\x6c\x90\x9f\x4c\x67\xf2\xc1\x76\xec\xfe\x07\x9b\xb7\x68\xda\x01\x55\x93\xd7\x63\x51\x35\x47\x14\xb6\xcf\x6d\x53\xd8\xae\x67\x87\x03\x99\x9d\xcd\x3b\x65\x8e\xda\x36\xc7\xe1\x84\x9d\x7d\x4f\xca\x79\x7b\x3e\xdb\x26\x10\xd3\xdf\xe0\x13\x0c\xca\xb1\x38\x5a\x94\x26\x1f\xda\x8e\xdd\x85\xc0\x85\x2d\xcd\x58\x0f\x01\xec\xb9\x2d\x2c\x25\x3e\x9c\xaa\x1e\x65\xdb\x0c\xd8\xd5\xd5\xab\xc5\x86\x9f\x71\xb7\x41\xdb\x90\x5b\xd3\x14\xe4\xf6\x86\x1d\xee\xc9\x49\x20\xda\xa3\xbf\x88\xca\x58\x96\xc9\xf5\x2d\x99\xa3\x6b\x2f\x19\x7d\xb8\xab\x5d\xec\xb1\xcf\x24\xe3\x8e\x3b\x3e\xbf\xb0\xc5\x36\x69\xef\x26\xc9\xf4\x0d\xad\x25\x6b\x21\x24\xcb\x44\x26\x99\x40\x2b\x59\x06\xaf\x95\x45\xad\x9d\xa6\xb5\x64\x5e\x27\x5e\x92\x79\x0b\x87\x70\x43\x49\xc9\x94\x5f\xb8\x70\x0b\x90\x40\x48\xc6\x9f\xb9\xff\x54\xb3\x53\x42\xf5\x89\x4b\x96\x6d\xb3\x59\x48\x57\xeb\x23\x04\x11\xe3\x9c\xc7\xd5\x95\x06\x85\xf6\x8e\x21\xe0\x1d\xfb\xa0\x00\xe1\x99\x26\x45\x78\x00\x82\xa1\xb4\x16\x61\x37\x28\x08\x42\xea\x1f\xda\xe9\x64\x25\x26\xe5\xb9\x12\x92\x09\x7d\x25\xc4\x93\x64\x4a\x8b\xc5\xbf\x37\x15\xd1\xd6\x45\xcf\x9e\xcc\x69\x92\x6c\xeb\x4d\xf4\xa2\x2d\xbc\xf0\x4f\x2f\x5c\xb9\x98\xa6\xef\xe0\xde\x4d\x37\x31\xa2\x5a\x9b\x2b\xc9\xb6\x3c\xa9\x07\x61\x20\x20\x72\x30\x7f\x88\x58\x0b\xaf\xa7\x52\x2d\x16\x0e\x67\x22\xe7\xdd\xa4\x9d\xf2\xa4\xa8\xff\x5b\xa2\x78\x1e\x33\xcf\xe3\xce\x69\xdf\x55\x4a\xeb\x50\x07\x00\x91\x7d\x45\xf0\x85\xd6\x2a\xe4\x02\x72\x8b\x85\x10\x25\x99\xe3\xfc\x49\x32\x97\x38\x49\x25\x0a\x05\x0a\xe5\x59\x53\x98\x4a\xe7\x82\x4d\x2a\x5c\xe2\xd7\xf9\x34\xdc\x52\xa2\x95\xf0\xaa\x05\x48\x42\x8a\x6a\x8e\x4d\x16\xc1\x37\xe7\x2e\xad\xe3\xc6\xe4\xa6\x6f\xfb\x62\x0a\x52\x12\x2b\xbd\xae\x36\xf5\xfd\x8e\xd0\xaa\x19\x0d\x90\x1e\x2b\x88\x0a\x10\x14\x4c\x09\xb8\x55\x63\xce\x88\x54\x80\x04\x15\xb7\x95\x5b\xe0\xfe\x6b\x3b\x47\x96\x29\xc7\x48\xe9\xc7\x96\xcf\x3f\xb0\x54\xb3\x65\xa0\x6f\xcb\xf9\xde\x27\xbd\x2a\x9c\x67\x23\xd2\x81\xd5\x6b\x4e\x3e\xa5\x17\xa2\x89\xab\xcd\x20\x46\xec\x64\x25\x70\x01\x86\xbc\xb9\xd5\xc2\x6b\xa8\x25\xd5\x79\x92\xe0\x19\x71\x92\x24\x61\x98\x03\x2a\x3a\xbe\x00\xb5\x3a\x6a\xeb\xa6\x59\x46\x96\xd3\xc1\x05\x39\x20\x5c\x73\xe9\xdd\x32\xc7\x34\x8d\x3d\x75\x35\x5b\xd7\xa3\x58\x93\x9f\x8b\xc1\x48\xc5\x10\x93\xf7\xa3\xb4\x76\xab\xd6\xa1\x0e\x59\xb1\x9f\x2a\x16\x0d\x48\x7f\x6e\x66\x22\xe3\x3b\x6e\xa2\xb6\x90\x4c\x09\xbd\x6a\x7d\x45\x63\x3e\xcc\x38\xac\xb5\xaf\xd0\xd0\x33\x56\x46\x32\x27\xd6\x47\x2f\xd1\xb7\x4d\xbf\x97\xe8\x62\x9b\xf0\x84\xe7\xe2\xc2\x67\x22\x2e\xcf\xc2\x95\x69\x2c\x62\x08\xb4\x0a\xb6\x3e\x0c\x0b\xd4\x0f\x11\xc5\x34\x2e\xc7\x24\xbe\x61\xd4\x5d\xb8\xf2\x69\x23\xc0\x0d\x8c\x38\xb1\x58\x89\x38\x2b\xd6\x5c\x2d\xbf\xc5\x20\xf0\x66\xcb\x7c\xb8\x84\xb9\xf4\xfb\x25\x4c\x9a\xc3\xa1\x33\xc5\x65\x1d\xe2\x56\xda\x54\x17\xe7\x99\x36\x45\xe8\xb6\x0f\x5c\x69\x31\x6b\x4e\xf4\xc7\x9a\x61\x4e\xf1\x97\x12\x1a\x9a\x7a\xdb\x2d\x97\xcf\x61\xe9\x71\xe1\xdb\x7a\x09\xa0\xb9\xe6\x69\x9d\xa0\x2c\xd7\x7f\xfd\xc1\xfe\x09\x00\x00\xff\xff\x4a\xf6\xac\x28\xe4\x0a\x00\x00") + +func fontsMaxfourFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMaxfourFlf, + "fonts/maxfour.flf", + ) +} + +func fontsMaxfourFlf() (*asset, error) { + bytes, err := fontsMaxfourFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/maxfour.flf", size: 2788, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMikeFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x92\x5f\x6f\xd3\x30\x14\xc5\xdf\xfd\x29\x0e\x72\x85\xf8\xb7\xdc\xb5\x19\x8c\xc2\x18\x93\x90\xe0\xa9\x4f\x7b\x24\x60\x85\xd6\x49\xad\x19\xa7\xca\x9a\x01\x92\xb5\xcf\x8e\x12\x27\xd7\x6e\xe1\x91\x17\xa4\xa9\x8d\xf3\xbb\xf2\xcd\xb9\xd7\xe7\xba\xb2\xd5\xa2\x9c\x21\xc7\x02\xf9\x29\x4e\xe6\xc8\xc5\xca\xdc\x68\x7c\xfb\x85\x95\x59\x6f\x4b\x6d\x71\xdd\x59\x6b\xee\x4a\x87\xf9\x72\x79\x26\x3e\x9a\xda\xea\x3d\xee\x74\x7b\x6b\x1a\x87\xa6\xc2\x77\x73\xa3\x7f\xb4\x66\x6f\x5c\x8d\x5a\x3b\xdd\x96\x7b\xbd\xe9\x05\xb6\xa5\xdb\x64\x59\x26\x56\xc6\x35\x2d\x74\xdb\x36\xed\x2d\x2a\xf3\x33\xec\x7e\xb2\xda\x39\x7c\xd8\x96\xbb\x9d\xb6\x16\x17\x75\xbd\xbe\xea\x4c\xb7\xce\xf4\xa6\xbb\xc4\xe2\x1c\xd7\x7a\x17\x4a\xce\x66\x72\x7a\xa4\x78\x24\x05\xfa\xbf\x14\xde\x4b\x01\x0c\x4f\xbf\xd0\xfd\xbd\x22\x5e\x49\x0a\x10\x14\x81\x57\x82\x14\xd4\x23\x92\x75\x90\xe9\x35\x82\xd8\x10\x93\x14\xe4\x27\x59\x29\x1e\x87\x6a\xc4\x75\x21\xc5\x13\xa6\xa7\x4c\xcf\x98\x9e\x33\xbd\x60\x3a\x61\xca\x98\x88\xe9\x94\x69\xce\xb4\x60\xca\x99\xce\x98\x5e\x32\xbd\x62\x3a\x67\x7a\xcd\xb4\x64\x7a\xc3\xf4\x96\xe9\x82\xe9\x1d\xd3\x65\xa0\xf7\xe9\x79\xaf\x46\xc2\xe0\x37\x05\x7b\x82\x41\xc1\x3d\x9a\xdc\x0b\x19\x5e\xc5\xb8\xcf\x2d\x7c\x8c\xd5\x61\xbe\x2f\x26\x91\xe4\xfb\x50\xc0\x47\xfd\xe2\x70\x5f\xf9\xc3\x18\x31\x7f\xd4\x1e\x15\x63\x0b\x48\x3f\x09\x13\x2f\x92\x94\xbf\x55\xc1\x51\x95\xa9\x55\x96\x18\xab\x78\x8a\x07\x3b\x3e\x48\x62\x8c\x0a\x7b\x3e\xad\x1a\xcc\xf3\xc7\x8d\xd0\x1f\xbd\x52\x92\xd2\x1b\xca\xd7\x7e\x10\x0d\xb7\x9d\xbb\x40\xb4\x5f\x8a\xcf\x3c\xc5\x82\xe9\x0b\xd3\xd7\x69\xb2\x52\x28\x35\x8a\x16\x71\xf4\x0f\x03\xff\xcf\x06\x3e\xfc\xfe\xd5\xeb\x77\x00\x00\x00\xff\xff\x46\xb0\xae\x62\x1d\x06\x00\x00") + +func fontsMikeFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMikeFlf, + "fonts/mike.flf", + ) +} + +func fontsMikeFlf() (*asset, error) { + bytes, err := fontsMikeFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/mike.flf", size: 1565, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMiniFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x59\x5d\x6f\xa3\x3a\x13\xbe\xcf\xaf\x98\x0b\xa4\xed\x91\x96\x12\x9c\x34\x4d\xa4\xd5\x6a\x29\x71\x5b\xb4\x04\x72\x80\xec\xb6\x12\x12\x9b\xdd\xd2\x36\x3a\x29\x54\x09\x39\x47\x95\xf8\xf1\xaf\xc0\x06\x6c\x18\x47\x7a\x2f\x4a\x52\xec\x79\x3c\x1f\xcf\x8c\xc7\xce\xf3\xfe\x99\x6c\x35\x98\xc2\x04\xcc\x31\x8c\xf9\x63\x41\xc6\xa3\xd5\x2e\xdb\xc1\xef\x0f\xb8\xdb\xa7\x59\x06\xf6\xeb\xf6\xfd\x3d\xdd\xef\x61\x6a\x2c\x26\x23\x27\xfb\xb3\x3f\x3d\xa5\x47\x70\x42\x1f\xdc\x6d\xb1\xcb\x74\x73\xf4\xbc\x7b\xd9\xa7\x05\x1c\xd2\x7d\xba\x3d\xa6\x40\x2e\x4d\xd0\x75\x30\x09\x58\xa7\x17\x30\x17\x8b\xe9\x68\x9d\x1e\xde\x76\xc7\xe3\x2e\xcf\x60\x77\x84\xd7\xf4\x90\xfe\xfe\x80\x97\xdd\xbf\x69\x06\x45\x0e\x6f\xf9\xd3\xee\xf9\x03\x8a\xd7\xdd\x11\x9e\xf3\xac\xf8\x0c\xdb\x23\xec\xf3\xec\xa5\xfa\x2c\x5e\xd3\x51\x3d\x61\x97\x1e\x3e\x1d\x21\xdb\xbe\xa5\x15\xc6\xfb\x7e\xfb\x27\x7d\x82\x3c\x83\x2d\xfc\xc9\xdf\xde\xd2\xac\x80\xfd\x2e\x4b\x2f\x47\xa3\x15\x9b\xfd\x54\xd9\xb0\xde\x9e\xf6\x70\x73\x3a\x14\x79\x06\x5f\x8e\xf9\xfe\x54\xec\xf2\xec\x5b\xba\x3d\x14\xaf\xfb\x5d\xf6\xcf\x65\x96\x16\x5f\xc1\x24\xc6\x62\x56\x29\xb2\x63\xd6\x41\x96\xfe\x07\xef\xdb\xc3\xf6\x2d\x2d\xd2\xc3\xe8\x78\x7a\x7f\xcf\x0f\x05\x03\xbc\x75\xee\x2a\x5b\xb7\xd9\x53\xf5\xf5\xe7\x2e\xbb\x04\x58\x6d\x3f\x60\xbb\x3f\xe6\xf0\x3b\x85\xe3\x7e\xf7\xf2\x5a\xec\x3f\xe0\xad\xd1\xe2\x39\x3f\xc0\xef\xb4\x28\xd2\x03\x9c\x8e\xe9\x28\x7f\xae\xe1\x9f\x4f\xfb\xbd\xfe\xdf\xee\xa9\x78\x35\xfe\x49\x0f\x99\x71\x7c\x3b\x1d\x5f\x61\xbb\x2f\xd2\x43\xb6\x2d\x76\xff\xa6\xc7\xcf\xf0\xfb\x54\xc0\x53\xfa\xbc\x3d\xed\x0b\xc8\x4f\xc5\xfb\xa9\xa8\x2c\xf7\xfc\x08\xfe\xbc\x6e\xb3\x97\xf4\xe9\x72\x34\xd2\xb4\x6f\xe2\xdf\xb7\x11\x00\x7c\x1b\x41\xa9\x7d\x1b\x41\xae\xb1\x7f\xeb\x67\xfd\xb6\xd4\xda\xef\xdd\x00\xfb\x5f\x2f\xf5\x52\xd7\xc4\x2f\x7c\xa8\xfe\x96\x54\x2f\x2e\x4a\xad\x9a\x99\x94\x7f\x35\xc3\x1d\xb4\x6f\x54\xef\x0c\x5f\x93\xa1\x2b\xa9\xbf\x6a\xa9\x8b\xe4\x41\x96\xaa\xa6\x6b\xcd\x37\x11\x8a\xbd\x66\x6b\x41\xac\x75\x03\x31\x7b\x55\x1b\x61\x68\xe2\x1a\x71\xc9\x96\x2f\xe3\x9e\x66\x4c\xdf\x5a\xfb\x06\x51\x54\xa0\x7e\xe4\x0c\xaf\x5b\x27\x49\x10\x37\x49\xb3\x87\xea\x1a\x9a\x38\x3b\xa9\xff\x33\xa0\x56\x27\x4e\x8c\xa1\xbf\x8c\x52\x6b\x6d\xe1\x03\x4c\x08\x6a\xe7\x1a\xc9\x60\x20\xa9\x07\x92\xbf\x7a\x1e\xae\xe3\xda\x98\x28\xd8\x28\x2a\x52\x72\xe8\x44\x0e\x9c\x34\x58\xca\x83\xdc\x07\x4a\xdb\x2e\xd8\xf4\x0b\x14\xf2\x22\x29\x1b\x75\xfa\x1e\xcf\x07\xc4\x94\x5e\x1a\x9a\x4c\x8e\xb8\xef\x6d\x9d\x71\x54\xd7\x7a\xb1\x89\x35\x81\x4f\x3d\x67\xe6\x92\xfe\x95\x69\x2c\x6e\xc0\xa4\x4a\xb8\x60\xf4\x81\xb8\x1e\x12\x1c\x0b\x06\xe3\x9c\xa1\xeb\x2d\xb3\x64\xdf\xd5\x0b\x94\x03\x2f\xb4\x5e\x8b\xc5\x40\x36\x52\x7c\xdd\x1e\x2f\x12\xf6\xb2\x7b\x62\x03\x72\x28\xd8\x42\xec\x23\x4e\x4a\x84\xfc\x25\x7b\x5b\xca\xa1\x48\x12\x31\x25\x5a\xf6\x48\x92\x3c\x7a\x43\xd8\x0a\x8e\xa5\x68\x2c\x73\xb1\xd5\x4f\x56\xbf\x19\x8a\x0d\xae\x4a\xa7\x4b\x6f\x02\xf0\x09\x71\x89\x39\x5b\x91\x4e\x72\x24\x34\x80\xe1\x60\x2b\xf9\x70\x46\x12\xe4\xda\xc1\x3c\x74\xc1\x73\xaf\x9f\x1c\x52\x45\xe9\x17\x16\x66\x0d\x37\x66\x18\x95\x9a\x16\x3c\xb5\x20\x36\x7a\x19\x2b\x4e\xe9\x26\x89\xd3\x44\x7f\xc7\x2c\x41\xe3\x61\xd9\x6d\xdc\x24\x2b\x27\xa5\x35\x42\x32\x34\x7c\x5d\xe9\x8d\x87\xe5\xaa\x36\x2f\x11\xeb\x58\xa7\xcd\x70\xaf\xe9\x3d\x2b\x75\xa4\x0c\x96\x37\x03\x56\xb4\x2e\x35\xb1\xa4\xf4\xd8\x8d\xd5\xae\x46\x90\x07\x70\xe0\x1a\xae\x2e\x0e\xd9\x94\x30\xa3\x97\x13\x89\x76\x66\x2b\x91\x24\x39\x6c\xf5\x31\xd4\x54\x55\x12\xcb\xc1\xb6\x92\x6b\x92\x7b\xfb\x29\xf6\xa5\x5f\x01\xcb\x21\x0c\x1b\xb8\x4c\xda\xba\x23\x2c\x2f\xa9\x7e\xa9\xd0\x4e\xb6\xab\xef\x64\x51\x52\x48\x3f\x75\xec\x44\x33\x2e\x91\x7a\x26\xc4\x2d\xf9\x3a\x8c\x5b\xeb\x7d\xbc\x5c\x89\xf5\x0e\xa3\x5c\x6c\x20\x55\xa9\x4d\x17\xa3\x1d\x1e\x4a\x7e\xfd\x32\x48\x08\x29\xfd\x34\x61\x80\x57\x1c\x89\x76\x9f\x75\x1e\x45\xb1\x5c\xfc\xd2\x6b\x6f\x74\x61\x6b\x1e\xd5\xfe\x76\xc9\xa7\x8a\x74\xd3\x3f\x69\x3c\xbf\xba\x02\x28\x7f\x54\x64\x6a\x88\xa3\xda\xb9\xf2\x84\x6d\xb4\x68\x31\xcd\x39\x19\xd1\xda\xc5\x07\xf1\x84\x6c\x07\x31\xae\x34\x83\x78\x88\x1a\xee\xf1\x32\x2c\x12\xc9\x9c\x8d\x01\x3c\x5f\xbf\x09\xa8\xf5\x1d\xc2\xb5\x65\xd3\x11\x54\xad\xae\xfc\xa8\x26\x9a\x00\x8e\xf7\x83\x06\x11\x5d\x02\x7d\xb0\x5d\x6b\x65\x45\x8e\xef\xc1\xca\x0a\xbe\xe3\x89\x66\xce\x08\x80\x4d\xbd\x08\x42\xe7\xce\xeb\x3c\x59\xf2\xc2\xd1\xf9\xbe\x9a\x3b\x01\x58\xfb\x1b\x6f\xd9\x4d\x4e\xf8\x5e\x93\x18\xc9\x2f\x4e\xe3\x32\x69\x7b\x47\x68\x16\x99\x02\xd8\x9b\x20\xa0\x9e\xfd\x28\x2f\xf4\x2b\xff\x54\xcd\xfd\x04\xbf\x04\x77\x98\xb3\x2b\x80\x47\xea\x09\x53\x19\xad\xe2\x84\x71\x4a\xd7\x4b\x5d\x6e\xcf\xcd\xd9\x0c\xe0\x26\xf0\xbf\x53\x0f\x6e\xac\x00\xa7\x94\x39\xbb\x06\x08\xa9\x5d\xfb\x84\x63\x33\x3b\x59\xc0\xda\xe6\xb2\x9a\x3a\x07\x58\x3a\x16\x0d\x68\xe8\x84\xfd\xe8\xc9\x7c\x33\x67\x0b\x00\xdb\x5f\x3f\x06\xce\xdd\x7d\xd4\x01\xd7\x11\xb5\xeb\xe5\x7f\xe9\x9f\x44\xfb\xae\xc7\x00\xb7\x74\xe5\x78\x8e\x47\xc1\x0f\x96\x8e\x67\xb9\xe0\x78\x4b\xc7\xb6\x22\x3f\xe8\xd3\x4b\xef\x6c\xad\x85\x4d\x00\x97\xde\x46\xfa\xda\x77\xbc\xc8\xf1\xee\x60\xe9\x6f\x6e\x5c\x0a\x96\x77\xe7\x52\xf8\x7b\xe3\x47\x72\xd4\xeb\x14\x60\x9d\xa4\xb0\x77\x99\xd7\x04\xea\x73\x94\x14\x8f\xa6\x2f\x94\x8a\xa0\x79\x3d\x01\x08\xfd\xdb\x08\xee\x1f\xd7\xf7\xd4\x1b\x35\x59\x2e\x6d\x56\xe6\xf5\x14\x20\xa0\x77\x4e\x18\xd1\x80\x2e\x7b\x7e\x08\x50\x3f\x5c\x01\xac\x2c\x3b\xf0\xbd\xe1\x81\xa3\xd3\x73\x06\xb0\xa4\x77\x01\xa5\x1c\xd2\x17\xd7\x6d\x17\xbf\x06\x58\xbb\x9b\x50\x5f\x39\xde\x26\xec\x19\x55\x4a\x1b\x57\x23\x31\x07\x08\x37\x6b\x1a\x84\x76\xe0\xac\x23\x88\x7e\xfa\x23\x20\x28\xf6\xa2\x37\xf3\x3e\xa0\x74\x04\x13\x6c\xee\x7c\x0c\x60\xd9\x9b\x88\x82\x65\x57\x79\xd5\x3b\xe0\xb5\xd3\x4c\x80\x95\x63\x07\x7e\x2f\xef\xa4\xea\xd0\x14\x80\x39\x01\x58\x3b\xae\x1d\xf8\x3f\x5b\xaf\xf2\x1a\xd3\xec\x56\xa5\xdc\x4f\x9a\xf3\x49\x85\xbf\x5c\xba\x14\x96\x7e\x24\xe6\xbe\xa8\x44\x95\x96\x74\xe9\xb8\xae\xd5\xd3\x70\x04\x61\x9d\x05\xf3\x2b\xd9\x72\xdf\xa3\x23\x30\x51\x83\x66\x55\x28\x43\x7b\xe3\x2a\x39\x2d\x56\xc5\x1e\xa7\xe7\xd7\x00\x75\xf6\xfc\x5f\xa4\x66\x74\x36\x84\x2d\xcd\x9c\xcf\x01\x7e\x6c\xdc\x3b\x2b\x80\xdb\xc0\x62\x99\xee\x7b\x15\x80\x15\x44\x34\x68\x24\x4d\xb6\x67\x4d\x45\xc9\x05\x2e\x79\x6f\xb9\xb7\x3d\x31\x22\x88\x2d\xc6\x43\xb1\x9a\x1f\xcd\x92\x61\x23\x3c\x19\xae\xb9\x10\x0b\xf6\xdf\x1b\x1a\x0e\x4c\x64\x31\x13\x1b\x38\x73\x41\x00\x5c\x2b\x72\x3c\xb0\xad\xb5\x13\x59\x2e\xb8\x34\x8a\x68\x00\x16\xfc\x74\xa2\x7b\xb8\x0b\xac\x1f\xb4\x9a\xcd\xfb\x55\xc5\x26\x68\x2e\x26\xe7\x71\x6a\x16\xd7\x7d\xf2\xd9\x63\xa0\xb9\x98\x9e\xc7\xb1\x9d\xc0\xde\xac\x6e\x5d\xfa\xd0\x81\xa8\xc1\xae\xce\x83\x45\x8e\xbb\xac\x95\xe2\xfb\xbf\x12\x67\x76\x1e\x47\x2a\xed\xe7\xbb\x05\x73\x71\x7d\x1e\x2b\xa8\xe8\x6a\xdd\xf8\xcc\xeb\x7e\xe3\x2e\x68\xe1\x04\x3c\x06\x38\x57\x01\x52\xbe\xa9\xd6\x00\xac\x5c\x19\x7a\x57\xb6\x98\xf4\x42\x21\x6d\x73\x7f\xb7\x19\x3d\x3c\x82\xd7\x59\x4d\xc6\x63\x05\x02\x95\x18\x14\x2b\x0e\xe3\x64\x6c\x9e\x97\x6f\x98\xc3\xfa\xaa\x52\xbe\x7f\x69\x30\x54\x2c\xa6\x38\x6b\xd4\x40\x2a\x1a\xd3\x61\xa4\x59\xdb\xa7\xc0\x51\xd1\xd8\xe9\x39\x45\x7d\x6b\x40\xc6\x2a\xf6\x3a\x92\x63\x12\xe9\x58\xda\xc7\x50\x31\xd7\x51\x3a\x86\x37\x5c\x7d\x20\x15\x6d\x1d\x95\x63\x14\x0a\xa9\xd8\x4a\xa3\xfb\x11\x34\x75\x3d\x29\x93\x98\x1f\x4c\xa4\x33\x04\x19\xab\xe8\xea\xa1\x19\xad\xba\x00\x21\xa6\x8a\xb4\xbe\x5c\xf6\x62\xf5\x3d\x09\x31\x55\xc4\xf5\x07\x25\x4f\x8d\xa1\x22\xae\xaf\x8c\x8f\x02\x48\x45\x5c\x5f\x72\x0c\xf7\x8b\x02\x43\x45\x5a\x5f\x15\x63\x05\x4e\xd5\x88\x6d\xdc\xc8\x59\xbb\xd5\x7e\x2d\xf4\xc7\xed\x36\xff\xd0\x9e\x19\x88\xa9\xa2\x28\x5f\x35\x8c\xaa\x46\xbc\xeb\x52\x0c\xee\x87\xd8\xe8\x71\xc3\x54\x51\x74\x83\xc5\x14\x3d\x91\x11\x53\x45\xcf\x0d\x16\x53\x05\x86\x8a\xa3\x1b\x75\x31\x42\x81\x88\x8a\xa4\x1b\x64\xdb\x51\x1f\x33\x09\x51\x11\xf5\x11\x33\x0a\xbd\xe6\x22\x44\x45\xd4\xe8\xde\x0f\xbc\xfe\xbd\x91\x7c\x69\x48\x48\x4b\xce\x70\x65\xb9\xad\x68\x78\x6f\x05\x6b\x08\xcf\x1f\x58\x09\x99\xa2\xc2\x16\x16\x54\xf4\x24\x4d\xc8\xd5\x39\x04\xd9\x7a\x05\xc2\xec\x1c\x02\x12\x50\x05\xcc\xf5\x39\x18\x39\x45\x15\x08\xf3\x73\x08\xc8\x11\x13\x47\x59\x9c\x43\x91\x3a\x10\xff\x8c\x57\x26\x63\x1c\x86\x0a\xa7\xec\x7a\x3b\xe1\x97\x78\x46\x22\x75\x2e\x64\x62\xa2\xf2\x83\xce\x63\x78\xf9\xc8\x3a\x8f\x09\x41\xe5\x29\xce\x0c\xe4\x12\x92\x4c\x70\x62\x52\x9c\x19\x28\x02\xce\x4e\x75\xdf\xa1\x80\xc1\x29\x8a\x74\x1d\xf2\xad\x50\x0f\x05\xa7\x69\xaf\xe7\x68\x0f\x5c\xdd\xc5\x0d\x99\xe0\xcc\x94\x3b\x0d\x03\x95\xc4\x19\x89\xf4\x17\xe2\x2d\xb6\x78\x4b\x49\x26\x38\x1d\x91\xce\x42\xbe\x37\x91\x2b\xd4\x14\x67\x63\xdd\x57\x3c\xf0\x7a\x14\xcb\x3f\xa6\x71\x41\x9c\x86\x1e\x96\x95\xe8\xb5\x2e\x99\xe2\x44\x44\x7b\x09\xf4\x3e\x8f\x4c\x71\x22\xa2\x9d\x84\x02\x01\x27\xa2\xba\x8f\x50\xc0\xe0\x44\x44\xbb\x08\x05\x02\x4e\x42\xa4\x87\x38\x73\xc1\x49\xa6\xd7\x00\x4b\xe7\x87\x13\x0a\xdd\x03\xfb\xd5\xb1\x39\xec\xe7\x72\xf4\x71\x1a\xf6\x7b\x08\x90\x7f\x91\x90\x97\xc4\x69\x88\x76\x0f\x80\x5d\xbc\x92\x2b\x9c\x82\x68\xef\xa0\x40\xc0\xb9\xa8\xee\x1c\x14\x30\x38\x21\x95\x7d\x83\x02\x05\x27\xe5\xa0\x6b\x68\xb3\x5a\xbc\xbc\x27\x57\x38\x21\x79\xbf\xd0\xae\x88\xfc\xd8\x41\xae\x70\x12\x3e\x0e\xd5\xcf\xf1\xc5\xff\x17\x00\x00\xff\xff\x41\xfb\x7f\x3b\x8b\x23\x00\x00") + +func fontsMiniFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMiniFlf, + "fonts/mini.flf", + ) +} + +func fontsMiniFlf() (*asset, error) { + bytes, err := fontsMiniFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/mini.flf", size: 9099, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMirrorFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x1a\xeb\x8a\xe3\xbc\xf5\xbf\x9e\xe2\xb0\x0c\x9d\x84\xce\x46\xb1\x72\x2f\xcb\x90\xd2\x1b\x0b\x2d\x2d\x7c\x65\xfb\x47\xa0\xf5\x24\x4e\x62\xbe\xc4\x59\x62\xcf\x5e\xc0\x0f\x5f\x74\x74\x24\x4b\xb6\x92\x78\x66\x76\x49\x3c\x89\xce\xfd\x7e\x34\xbb\xe3\x4e\xa4\x0f\x30\x87\x19\x88\x31\x24\x33\x48\x96\x90\xb0\x7f\xe5\x97\xcb\xf9\x02\x2f\xbf\xe0\xaf\xe9\xf7\x7c\x0b\xff\x4b\x8f\xd5\xb9\x80\x4f\x3f\xf0\x7d\xbd\x29\x47\xaf\x9b\x6d\xfa\x3d\x2f\x47\xd9\xf6\xf5\x19\x40\x4c\xe1\xcf\xaf\x7b\x48\x56\xab\x29\xfb\xef\x21\x2f\x21\x2f\x21\x85\x93\xc1\x92\x9f\xd2\x7d\x06\xdf\xb3\x4b\x99\x9f\x0b\x38\xef\x46\xa3\x11\xfb\xad\x4a\x8b\x6d\x7a\xd9\x6a\x12\xff\x38\x66\x45\x01\x7f\x39\xa4\xdf\xbe\x65\xc7\x23\xfc\x01\x3e\xa7\xf8\x6b\x0e\x13\xbe\x9a\xc0\xc7\x8f\xf0\x92\x96\xd9\x16\xce\x05\xfc\xfd\x92\x16\xbf\x3f\x96\x30\x2a\xf3\x3d\xfb\x5c\x6c\x8e\xaf\xdb\xac\x84\xcf\xbf\xfd\x1b\xfe\x99\x56\x79\xf1\x31\x61\xbb\x7c\x7f\xcc\x2a\xb8\x64\xc7\x2c\x2d\x33\x10\xa3\x44\x23\x48\x44\xc3\xdf\x7f\xb2\xcb\x29\x2f\x91\x97\xbc\x84\x43\x76\xc9\x5e\x7e\xc1\x3e\xff\x9e\x15\x50\x9d\xe1\x74\xde\xe6\xbb\x5f\x50\x69\x21\x76\xe7\xa2\x7a\x82\xb4\x84\xe3\xb9\xd8\xeb\xf7\xea\x90\x31\x3c\x90\x67\x97\xc7\x12\x8a\xf4\x94\x69\x1c\xdf\x8e\xe9\xc6\xf0\x97\xc2\xe6\x7c\x3a\x65\x45\x05\xc7\xbc\xc8\x46\x8c\xfd\xed\xe7\xb7\x63\x5a\xa4\x95\x91\x1c\x76\xf9\xa5\x34\xdf\xfd\x89\x69\xcd\xc3\x47\xf8\x70\x4a\xf7\xf9\x06\x8a\xd7\xd3\x4b\x76\xf9\x00\xbb\xf3\x05\x76\xf9\x31\x83\x7c\x9b\x15\x55\xbe\xcb\x37\x08\xcc\x52\x00\x80\x8f\x50\x1e\xce\xaf\xc7\x2d\xa4\xc7\x1f\xe9\xaf\x12\x5e\x32\xf8\x9a\x3e\x3e\x21\x50\x71\xfe\xc1\x1e\xcc\xa1\xea\x90\xc1\x87\x43\x7a\xd9\xbe\x1c\xd3\xe2\xf7\x0f\x5a\x01\xdf\x2e\x79\x51\x95\x5a\x86\x14\xf0\xd3\x27\x78\x79\xad\x60\x93\x16\x8f\x95\x46\x53\x9e\x5e\xcb\x43\xb6\x65\x73\x83\xe1\x90\xe5\xfb\x43\xa5\x39\x4e\x61\x73\x48\x2f\xe9\xa6\xca\x2e\x6c\x76\xe3\xcb\x27\x28\xce\x15\xe4\x68\x92\xbc\xd8\xc3\x36\x2b\x37\x59\xb1\xcd\x2e\x25\x13\x63\x04\x3b\xa5\x3f\x51\x72\x38\x66\xc5\xbe\x3a\xc0\x20\xfb\x69\x0f\xfb\x4a\x2b\x87\xf0\x47\x48\x61\xf7\xba\xdd\x67\xb0\x4b\x37\xd5\xf9\xc2\x92\x19\x62\xd8\x66\xbb\xf4\xf5\x58\x19\x66\x4f\xe7\x6d\x86\x82\x3b\x53\xb1\x64\x89\xc7\x8c\x2a\x35\x7f\x01\x5e\xc6\x1e\xd6\xad\xff\x6b\x06\x0a\xd6\xac\x86\xda\xbe\xa8\x7a\xcd\x06\x6a\xb8\x66\x00\x60\xbe\xd6\x07\x06\x50\x83\xfe\xec\x0b\x7c\x01\xfd\xd5\x03\xf8\x6f\x74\x14\x40\xe1\x7f\xfd\x99\xaa\xa1\xae\xa1\x46\xe4\x0a\x60\x34\x02\x50\xb5\x79\xd6\x3f\xfa\x19\xa0\x56\x75\xad\x6a\x87\xa3\x41\xa4\xf0\xb3\x1a\x6a\x4d\x5a\x29\x90\x6b\xc6\x41\x29\xbe\x66\x12\x00\x19\xd1\x70\xeb\x35\x53\x48\x51\x7f\x2c\x0d\xd3\x12\xa4\xa1\xaf\x1f\x50\x12\xa9\xa4\xc5\x4f\x4c\x2a\x83\x1e\x06\xa0\x60\x08\x6b\xc6\x25\x07\x85\xc7\x9f\x01\x3e\xa9\xa1\xd6\x83\xe4\x52\x29\xc5\x3d\xd6\xac\xae\x06\x48\x5f\x6a\x01\x1e\xc0\xbe\x80\x65\x06\x59\x21\xe6\xc3\x57\xae\xb1\xa1\x70\x6a\xcd\x80\x03\x47\x8d\x43\xf8\x0a\x9a\x5b\xc7\x2e\x53\x4a\xb3\x61\xa4\xd6\x00\x5c\x8b\x8b\xe2\x48\xde\xa8\xcd\x01\x80\x35\x82\xb5\x80\x55\x7f\xa3\x6f\x4f\xd9\x06\x2c\x78\x09\xe4\x0b\xb1\xd2\x83\xd2\x3f\x88\x55\xff\x20\x56\xed\x05\xf7\xb1\x36\x2e\xa5\x94\xc1\x85\xa6\x02\xcf\x66\x40\xaa\x03\x68\xdb\xcc\x9a\xcc\xda\xa9\x46\xdf\x30\x3e\xab\x8c\x8e\x5b\xe6\x6a\x3c\x5b\x76\xdc\xdb\xc3\xaa\x08\x2b\x8a\x52\xc3\x80\xe8\x48\x45\x74\x3c\x29\x1d\x56\x0b\x26\x09\x4c\xc3\xa3\x5e\x11\x5e\x11\x7c\x1b\x8c\x82\x03\xcd\x80\xa1\xd1\x04\x89\xb5\x91\x67\xa4\x96\xdf\x39\x56\x35\x43\x50\xb7\x79\xbe\x41\x93\x5c\x9d\xc2\x41\x83\x7d\x05\x02\x1b\x5e\xd5\x9b\xb5\x31\x58\x09\x9d\xa9\x1a\x5b\x69\x1b\xb5\xac\x6e\xad\x64\xe3\xca\x33\xd7\x0d\x6a\x11\xe3\xd2\xe9\x1a\x46\x74\x5a\xd3\x8a\xf9\x58\xe3\x59\x2d\x1f\x8b\x7e\xdd\x38\x76\x10\xa9\x52\xbb\x88\x09\x48\xee\x98\x5b\xdf\x74\xfa\xdb\xde\xdf\x04\x38\x07\xee\xd1\xb1\x4e\x4d\x3a\x06\x93\xd4\x6a\x8a\x04\x9b\xd4\x18\x8a\xef\xa7\x55\xa4\x6e\x55\xa4\xcc\xd9\x1a\x1e\x15\xc5\x8b\x8e\x81\x21\x85\x83\x42\x8d\x71\xe7\x0f\xdc\x49\xa2\x5c\x24\x73\x67\x4c\xa3\x71\x17\x02\x88\x4d\xab\x20\x08\xc0\xb6\x0b\x0e\xa0\x71\x41\xb0\xbe\xd4\xc4\x60\x24\x5a\x80\x54\x67\xa3\x9b\xb2\xa2\x3e\x0b\x56\x99\x11\xa7\xb0\xb1\x49\x44\xa2\x11\x7f\x25\x36\x11\x25\x50\x38\x41\x97\xda\x0d\x30\x73\x1a\x80\x88\x38\x78\xc0\xc8\xbc\x23\x9b\x82\x16\x93\x31\xd9\x30\xd6\xa3\x49\xac\x06\x2b\x2d\x26\xef\x0e\x35\x93\xcd\x55\xed\x6a\x23\xbd\xd5\x9e\x44\x96\x02\x10\x85\xe6\x81\x68\x5e\xcd\x97\x5e\x2d\xa5\x23\xf0\x95\x0c\x3d\xa2\x02\xe6\xf1\x64\x03\x44\x05\x36\x8d\x1b\xb7\x23\x09\x26\x26\x94\x57\xd7\x31\xa3\x02\xc9\xad\x32\xac\x12\x75\x22\xf4\xb5\xd0\xd1\x1e\x27\x00\x8b\x03\x08\x85\xe2\x1d\xed\xbd\xb3\x84\x44\xfc\xd0\x73\xf6\xab\x9e\xd1\x83\x1a\x57\xfc\x2d\xd4\x9e\xe9\x13\x7e\x45\xb6\xa6\x3a\x48\x1b\xce\xfc\x4e\x75\x68\xbc\xbe\x69\x10\x80\x1a\x84\xe6\xa1\xd3\x32\xc4\xdc\xf7\xbe\x26\x4d\xd1\x07\xd3\xcc\x48\xcc\x42\x9c\x0a\x0b\xe5\x2b\x90\xf0\x05\xb8\x2b\x2e\x3c\x28\x82\x1e\x8a\x00\x4b\x88\x28\xc4\x15\xa2\xeb\x60\xf4\x9c\xde\xa0\xb3\x88\x0c\x0a\x0e\x36\x1d\x86\xcd\x88\x52\x1e\x03\x16\xe4\x0b\x91\xbd\xae\x36\xab\x6c\x69\xeb\x7c\xab\x51\xc5\x38\x09\x9a\x1e\x6b\x9b\x3a\xd6\x4c\xd6\x1a\x09\x25\x76\x45\x59\x9d\x9b\x94\x4e\xdc\xa3\xe8\x3c\x10\xba\xc1\x6a\x7a\xf1\x4e\xf7\x69\xb1\x72\xe4\x88\x53\x8f\x0b\xad\xd7\x6e\xc7\x79\xf5\xa1\x5d\x38\xfd\x4a\x5c\x73\xe8\xb6\xd0\x1e\x28\xf5\x2e\x54\xe8\x5c\x99\x73\x45\xae\xd5\x0d\xd8\x4c\x44\x79\x27\xe8\x74\x9c\x53\x3e\x75\x1a\x24\xc7\x27\x25\x72\xca\xe3\x96\x92\x4f\xa8\x95\x59\xdf\xca\x9e\x47\xc7\x66\x05\x9b\x42\x22\x74\x88\x1f\x62\xc7\x35\x89\xb6\x43\xf4\xdb\x83\x1e\x1a\xf3\x1a\x29\x65\x06\xa7\x9b\x1a\xab\x9b\x04\xdc\xa9\x42\xb6\xa5\x8a\xf7\xd4\xa6\x4f\xd1\x0d\x8c\xad\x3a\xde\x9b\xb4\x99\xc8\xb9\x2e\x8e\x38\x86\x98\xab\x3a\xcf\x00\xf1\x6a\xd3\x1a\x54\x3b\xed\x7c\x13\xd6\x94\x80\x95\x99\x5d\x31\x9b\x3e\x86\xc2\x05\x02\x86\x45\xa6\xe3\xde\x1e\x9a\xfb\xfa\x09\x39\xe8\xdf\x04\xdf\xa0\xe6\xfb\xaf\x5f\x70\xde\x68\x7b\x33\x57\xb4\xdc\x11\x28\x3a\xbf\x12\x62\x5b\xc5\x23\x85\xde\x6b\x41\x82\x81\xbc\xd5\x7b\x90\x57\xb9\xea\xef\x06\x1d\xfc\x8d\x43\xdc\x73\xaf\x76\x44\xd7\x82\x09\xee\x64\x62\x4c\xf7\x11\xb0\x06\xd2\x07\xf6\xe1\x7d\x14\x21\x96\x50\x7b\x9d\xca\xf1\x0c\xf0\x29\x56\x31\x7a\xc9\x79\x25\x42\x4d\xe1\xa0\xba\x61\xcb\x86\x49\x18\xb2\xd1\x24\x8d\x07\x6e\x8c\x30\xbd\x21\x3c\xc3\xb3\xfb\x8d\xdb\x51\x20\x16\x45\x36\x94\x8c\xf9\x14\xd5\x11\x07\xfb\x09\x3e\x05\x78\xcd\x8e\xa2\x96\xdc\x8c\x35\xa6\x4e\xb4\x56\x42\xe1\x66\xc8\x0a\x3e\x50\x43\x45\x53\x1a\x57\x32\x08\x0f\xcd\xa0\x3f\x75\xc4\xc1\xbc\x7e\xea\xd6\xdc\xef\xc0\xc0\xe6\xaa\x5e\xeb\x82\x16\xb5\x7e\xb9\xfd\x16\x93\xb7\x86\xec\xfb\x4c\x46\xa9\xb5\x2a\x08\x65\x4d\x4e\xad\xaf\x54\xb5\x1f\xc2\x6b\x96\xcc\xc7\xb1\xad\x5f\x32\x4f\xee\xe5\xf2\x64\x2e\x98\x5b\x26\x51\x0e\x1f\xb4\x0a\xe4\x00\xa8\x5b\x32\xfd\x8e\x06\x9a\xd8\xd4\x87\xc6\x55\x23\xb7\x2f\xc0\x64\xe9\x26\x03\xdb\x14\x8c\x68\x66\xb7\x02\x26\xf3\x29\x33\xab\x37\x69\x9c\x1e\x80\x7b\x9a\xa4\x39\x75\xcd\x24\x4e\xa9\xdc\xd7\x4d\x32\x9f\x99\x94\x46\xdb\x19\x13\xc7\x35\x7e\x52\x7b\x0f\x91\xee\x2c\x99\xcf\xfd\xc8\xc0\x53\xc1\xaf\xfa\xc8\xc2\x94\x65\x54\x03\xd5\x32\xdd\x66\x61\x2a\xe4\x18\x2f\x52\xb9\xfe\x53\xa9\x21\x02\x2d\x23\x96\xc6\x95\x01\x35\x3e\xed\x07\x8f\xa5\x95\x89\x46\xa7\x4c\x37\xa4\x1b\xca\xa6\x59\x31\x7e\x06\xc6\x20\x34\xb5\x99\x76\xc2\x31\xe2\xd6\x00\xc9\x62\x4c\x95\xc2\xfa\xb6\xf5\x31\x32\x86\x8d\x63\xbf\x15\x49\x16\x09\xb3\x83\xae\x84\x66\x65\x62\x97\x26\xb4\x36\x09\xfb\x97\x64\x21\x62\x5d\xa0\xdd\x27\xd9\x52\x14\x5b\x9f\x24\x8b\x49\x53\xa0\x7c\x0c\x70\x93\xc9\xe9\x6d\x65\xe9\x78\xa9\xad\xb2\x24\x16\x3a\x52\x16\x57\x9a\x9b\x98\xb2\x66\x77\xb6\x9d\xdd\x07\xc7\xcd\x9c\xb9\xd5\x1b\xcd\x11\x35\x0c\x5c\x2a\xe0\x10\x15\x61\xc1\x6e\x2d\x6f\x35\x9b\x6d\x56\x1c\xe8\xd2\xd6\xe6\x41\xbc\x4c\x04\xd9\x38\x59\xac\x9a\xaa\x82\xa8\x70\x81\xe9\x95\xf2\xf0\xf8\x72\xcc\xcc\x61\xc4\xf5\x10\xe9\xda\x93\x65\xd2\xbb\x9a\xb7\x5a\x98\x64\x29\xac\x9a\xc9\x93\xa1\x19\x98\x87\xb6\xdd\x72\x1d\x4c\x77\x37\x9a\x2c\xd1\x5f\x82\x6d\x5f\x87\xbd\x29\x83\xd6\x4e\xda\x83\x18\xe0\x91\x59\x67\x5f\xac\xea\x16\x96\xb9\xb7\xb6\xc3\x1c\xa4\x5c\xe8\xc4\xd4\xb6\xa0\xc9\xdc\x8b\x13\x68\x16\x82\x76\x25\x18\xb4\x0a\xc9\x72\x49\x33\x5d\xd3\x9d\xe3\x59\x64\x0b\xf5\x69\x33\xbe\xf6\x0c\x55\x4b\x90\x66\x1d\x84\x8a\x09\x56\xb2\x0e\x25\xe5\x11\xd7\x99\x29\x87\x70\x60\x16\xc3\x36\x6f\xe0\x3f\xbb\xde\x94\x1d\x6c\x1a\xd9\x6a\xec\xf8\xb3\x4b\x07\xe2\x90\x5c\xc9\xf2\x48\x2e\xd5\x70\xa9\x5a\x7c\xb6\x67\x71\x83\x3e\x71\x97\x3f\xb4\x04\xa5\x9e\x43\x49\x93\xac\x50\xe1\xcd\x71\xc1\xbc\x1d\x37\xb7\xcd\x5a\x8f\xd6\x22\x59\x4d\x28\x44\x6d\x47\xf3\x06\x50\xed\x4d\x5c\x52\xaf\xc5\x95\xac\xfb\x83\xce\x18\x60\xdf\x64\xa8\xf2\xb7\x80\xce\xdf\xdb\x46\x25\x2b\x3f\xb3\xc0\xe0\x3c\x7c\x83\xac\x4b\x8a\x4e\x5a\x1f\x9b\xc5\xaa\x5b\x20\xa3\x79\xed\x22\x43\xd7\xf5\xf0\xde\xa4\xb5\x46\x26\x94\xab\x37\x6e\x85\x07\x6a\x60\x40\xc5\x78\xec\xd9\x5b\xd7\x9c\x70\xd7\xab\xea\x66\x9c\x6e\xa5\x48\x31\x4e\x3c\x7b\xeb\xa8\x7b\x03\xa8\x88\xd8\xbb\x27\xe8\x24\xd6\x56\xf6\x03\x9d\x32\xda\x92\x02\xa7\xec\xe7\x6f\x7e\x5b\x2b\x5f\x31\x9e\xd9\xa5\x01\xc5\xed\x9d\xe3\x73\x86\x22\xad\x19\x0a\x74\xf7\xf8\x22\xe6\x7c\x08\x63\xfc\x80\xf6\x5e\xb5\x19\x5e\x02\x39\x96\xed\x1b\x0c\x70\x6b\x01\x57\xe5\xa0\x69\xce\xcc\xa2\xb2\xbd\xfb\x13\xe3\x15\x73\x81\x43\x71\x83\x8b\x5f\x2c\x10\x8f\x4f\xb4\xf6\x0d\xc7\x56\x91\x8c\x63\xf9\xa1\xcf\x0c\x21\x92\x24\x96\x1f\xfa\x81\xc6\xfc\xa5\x27\xe8\x24\x96\x1f\xfa\x81\x4e\xdf\x3b\x2f\x89\x64\xc6\xc0\xe5\x63\xbc\x0e\x97\xe6\x2a\x1c\xaf\xc1\x29\xe1\xe2\xc1\x79\x13\xba\x20\xa5\x45\x2d\xa5\x2d\xf3\x52\x5a\x1a\x52\xb6\x68\x2c\x62\xa1\xdb\x67\x2e\x13\xc9\x32\x16\xba\xfd\x40\x57\x81\x29\xc0\xfa\x4d\x0f\x50\x31\x7e\xef\x20\x29\x84\xe7\x3b\x0a\x19\xbe\xb6\x2e\x6e\xcf\x21\x42\x08\x6f\x33\x67\x53\x21\xde\xfa\x99\xe9\xee\xfa\x9d\x83\x10\x93\xb7\x4f\x87\x42\x4c\x5b\x66\xe9\xbd\xd3\x14\x62\xd6\x32\xcb\x1b\x40\xe7\xb1\x8c\xda\x0f\x74\xe1\x45\x88\x72\x99\xa0\x17\xe8\xf2\xbd\x33\xbe\x10\x2b\x4f\xd6\xc1\x60\x68\xd6\x9b\x5f\xa1\x07\xe8\x64\x1c\xac\x9e\x4c\xfc\x34\x66\xb2\xe4\xcd\x2a\xb8\x59\x3b\xab\xa7\xf0\xaf\x4f\x08\x59\x12\xcc\x44\x70\x6b\x67\x8d\x65\x13\x81\x84\x37\x8d\x18\x0b\xdf\x5d\x40\x8b\xc9\xc4\x4d\xbb\x36\xfb\xf5\x00\x9a\x32\x6b\x56\x6b\xd5\x1e\x40\xb3\x5b\x89\xab\xb9\x66\xab\xbb\x81\x36\xc1\x7c\x84\x9d\xcb\x95\x25\x86\x98\x2c\xbc\xe1\xe5\xca\x91\x65\xab\x16\x86\x97\xab\xf6\x56\xde\x11\x5d\x45\x1b\xb1\x1e\x57\x67\x62\x3a\xd6\x94\xc8\x79\x71\x5d\x88\xde\xc3\x25\xb7\x23\xb9\xb9\xbe\x33\x57\xf7\x21\x68\x72\xa5\x32\xdc\x5d\x49\x8b\x69\xb4\x4b\xee\xb3\xa4\x12\xd3\x68\x97\xdc\x0f\x34\xda\x25\xf7\x03\x8d\x76\xc9\xfd\x40\xa3\x5d\x72\x3f\xd0\x85\x37\xc3\x36\x83\xb8\xc6\x12\x8e\xdd\x74\xbb\xe1\x83\x2e\x99\x17\xe1\x4d\x89\xe4\x4d\x8d\x1c\x48\x39\x6c\x6a\x63\xeb\xef\xca\xc4\x74\xd5\xab\x3a\xc6\xf2\xcb\x6c\xdc\xab\x3a\x46\x41\x93\x5e\xd5\x31\x0a\x2a\xde\xbb\xc1\x14\xb3\x49\x3f\x86\xbb\x1b\x71\x31\x9b\x7a\xd5\xf1\xce\x4d\x5f\xb8\x66\x10\xb3\x59\x3f\x86\xbb\x54\xff\x1f\x00\x00\xff\xff\xbe\x22\xec\x0d\x20\x2c\x00\x00") + +func fontsMirrorFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMirrorFlf, + "fonts/mirror.flf", + ) +} + +func fontsMirrorFlf() (*asset, error) { + bytes, err := fontsMirrorFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/mirror.flf", size: 11296, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMnemonicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\xbd\x69\x77\xdb\x38\xb6\x35\xfc\x1d\xbf\x82\xe9\xf5\x36\xa2\x54\x95\x13\x6b\xb0\x25\xa5\xaa\x52\xa4\x44\x48\x62\x4c\x91\x0a\x07\x3b\xf6\x17\x2f\x8d\xb1\x13\xc7\x4e\x7b\x48\x2a\xf9\xf5\xef\x02\xc1\x73\x08\x8a\x07\xa4\x9f\xbb\xee\xea\xdc\x6e\x63\xef\x43\x0c\x7b\x1f\x00\x14\x09\xee\x6e\x76\x9d\xe5\xff\x67\xb5\xe5\xff\x75\xac\x83\xb6\x75\x64\x1d\x5a\x87\x56\xbb\x3f\xec\xb3\xaf\xb7\xdb\xaf\x77\xb7\xd7\x6b\xeb\xc0\x5a\x5a\x13\x6f\xba\xbb\xbb\x7d\xb4\x56\x3f\xad\xf7\x77\x57\xb7\xd6\xf8\xee\xc7\xf2\xd6\xfa\x6b\x2d\xff\x9f\x6d\xaf\xd7\xd7\x37\xaf\xef\xee\x3f\xbd\x63\xc9\xd5\xf5\x83\x95\x21\x9f\x1e\xb6\x0f\xd6\xe3\xd5\xd6\x82\x38\x0f\xd6\xdd\xce\x8a\x26\xe3\x76\xb7\x77\xc4\x5a\x57\x8f\x8f\xdf\xde\xbe\x79\xb3\x79\x78\x7d\x7d\xfb\xb8\xbd\xbf\xbd\x5e\xbf\xbe\xdd\x3e\xbe\xb9\xdf\xad\xe5\x7f\x24\xe6\xf5\xe3\xbf\x8f\xaf\xac\xc7\x3b\xeb\xfa\xeb\xb7\x9b\xed\xd7\xed\xed\xa3\xb5\xb4\xee\xb7\xcb\x9b\x9b\x9f\xd6\xcd\xf2\xfe\xd3\xd6\x5a\x5f\x2d\xef\x97\xeb\xc7\xed\x3d\x7b\xd8\x3e\x5a\xf7\xcb\xc7\xab\xed\xbd\xb5\xbe\x7f\xda\x6c\x6f\x7e\xfe\x61\xad\x9e\x1e\xad\xfb\xed\xf7\xed\xfd\xc3\xf5\xea\xe6\xe7\x6b\xcb\x4a\x7e\xdc\x1d\xdc\x6c\x1f\x1f\xb7\xf7\x45\x9d\xd8\xf2\x7e\x6b\x7d\xbb\xdf\xee\xae\xff\xdd\x6e\x64\xeb\xf8\x9f\x2a\xb8\x86\xb1\x2a\x98\x4b\x6b\x79\xbb\xb1\x76\x77\x37\x37\x77\x3f\xd4\x9f\x2e\x5f\x33\x1e\x2f\x6c\x9b\xbd\xb0\x6d\xf6\x1f\xdb\x66\x3c\x58\xc9\x7f\xdd\xd0\xb6\xd9\x7f\xe5\x7f\xb3\x6d\xf6\xd2\xb6\x59\xcb\xb6\xd9\x2b\xdb\x66\xbf\xd9\x36\xfb\xdd\xb6\xd9\x1f\xb6\xcd\x0e\x6c\x9b\xbd\xb6\x6d\xf6\xc6\xb6\xd9\xa1\x6d\xb3\xb6\x6d\xb3\x8e\x6d\xb3\xae\x6d\xb3\x9e\x6d\xb3\x23\xdb\x66\xc7\xb6\xcd\xfa\xb6\xcd\x06\xb6\xcd\x86\xb6\xcd\xde\xda\x36\xfb\xd3\xb6\xd9\x5f\xb6\xcd\xfe\xb6\x6d\xf6\xce\xb6\xd9\x3f\xf2\x3a\xce\xa3\x6d\x33\xc7\xb6\xd9\xc8\xb6\xd9\xd8\xb6\x99\x6b\xdb\x4c\xd8\x36\x9b\xd8\x36\x9b\xda\x36\x9b\xd9\x36\xf3\x6c\x9b\xbd\xb7\x6d\x76\x62\xdb\xcc\xb7\x6d\x36\xb7\x6d\x16\xd8\x36\x93\xb5\x95\xad\xf8\x60\xdb\x2c\xb2\x6d\x16\xdb\x36\x4b\x6c\x9b\xa5\xb6\xcd\x4e\x6d\x9b\x9d\xd9\x36\xfb\x68\xdb\xec\xdc\xb6\xd9\x85\xbc\xda\x5f\xb2\x3d\xfc\x8d\xac\x39\x7f\x25\xeb\xc0\x5f\xca\x7f\x2f\xb3\xff\x26\xfb\x62\x69\xdb\x4c\xf6\xc4\xda\xb6\xd9\xc6\xb6\xd9\xd6\xb6\xd9\xce\xb6\xd9\x27\xdb\x66\x57\xb6\xcd\xae\x6d\x9b\x7d\xb6\x6d\xf6\xc5\xb6\xd9\x8d\x6d\xb3\xaf\xb6\xcd\x6e\x6d\x9b\xdd\xd9\x36\xfb\x66\xdb\xec\x7f\xb6\xcd\xee\x6d\x9b\x3d\xd8\x36\x93\x2d\x7b\xb2\x6d\xf6\xdd\xb6\xd9\x0f\xdb\x66\xff\xda\x36\xfb\x69\xdb\xec\x97\xbc\x5a\x4b\x5e\x8d\xbf\x50\xff\xbe\xca\xae\xaf\xfa\x43\xf6\x14\x0f\xb3\x7f\xd3\xec\xdf\x65\xf6\xef\x5d\xf6\xef\x53\xf6\xef\x83\x8c\x7e\xf8\xef\xe1\xe1\x61\xdb\xb2\x2c\x2b\x4e\x9c\x28\xb1\xc2\x89\x35\x13\x8e\xeb\x05\x53\xab\x15\x87\xb3\x57\x8c\xc7\x33\x80\x75\x4a\xb0\x44\x7c\x4c\xac\x56\x9c\x7c\x94\x98\x8f\x80\xe9\x4a\x8c\x08\xdc\x02\x21\x32\x84\x40\x44\x4f\x47\x44\x4e\x10\xcf\xbd\x38\xf6\xc2\xc0\x6a\x89\x30\x91\xc8\x04\x90\x47\x0a\xf9\x21\xf5\xa2\x73\xab\x25\x82\x0f\xb2\xf4\x03\x94\x1e\xcb\x52\x67\x7c\x12\x84\x67\xbe\x70\xa7\xc2\x6a\x39\xe3\x93\x57\x8c\x3b\x27\x80\xe8\x4b\xc4\x48\xf8\xbe\xd5\x1a\x09\xff\x15\xe3\x23\x1f\x8a\x06\x59\x91\x33\x3e\x89\x17\xce\x58\x58\xad\x51\x2c\x8b\x63\x28\x1e\xca\xe2\xf1\xcc\x89\x9c\x71\x22\x22\x2b\x71\x46\xa9\xef\x24\x59\x25\x67\xb2\x8e\x33\xac\xe3\x52\x22\x7d\x2f\x10\xd6\x44\x08\xd7\x6a\xf9\x93\x57\x8c\xfb\x13\x28\x5e\x61\xb1\x1e\xe3\x54\xc6\x38\xc5\x18\x6b\x09\x9a\x84\xd1\x3c\x8f\x31\x91\x31\x26\x18\x63\x93\x55\xc6\x89\x22\xcf\x99\x0a\x2b\x12\x49\x1a\x05\x56\x6b\x1c\xbd\x62\x7c\x1c\x01\x68\x9b\x8d\xcd\xcc\x9b\x24\x56\x98\xca\x71\x09\xe5\xb0\x84\x50\xbc\x2b\x8a\xbd\xc0\x6a\xc5\x9e\x2c\xf5\xf2\xd2\xf6\xa1\x2c\x75\x9d\xc4\xf1\xbd\xe0\xc4\x12\xf1\xd8\x59\x08\xab\xe5\xfa\xe2\x15\xe3\x2e\xf4\x59\x3b\x53\x89\x2b\x4e\xbd\xb1\xb0\xc6\x61\x90\x44\xa1\x6f\x85\x81\x04\x8e\xdb\x12\xd8\x06\x60\x87\x00\x26\x67\xa1\x04\x76\x24\xb0\x03\xc0\x2e\x05\x9c\x45\x22\x8b\xd9\x95\xd0\x2e\x40\x7b\x04\x74\x12\xa6\x91\x44\xf6\x24\xb2\x07\xc8\x4c\x35\x81\x98\x3a\x89\x77\x2a\xca\x02\x09\x1c\x29\x90\x00\x04\xd2\xce\x24\x14\x9f\x07\xe3\x28\x0c\xc2\x34\xb6\x3c\xd7\x17\x56\x2b\x3e\x0f\x64\xef\x9c\x03\xaa\x6f\x12\xec\xc8\x0f\xc7\x27\x52\xe0\x23\x29\xcc\x11\xe0\x07\x6a\xbc\x82\xb1\xf0\xad\xd6\xd8\x91\xc1\xc6\x01\x14\x0e\xb5\x60\x73\xe1\x7a\xe9\xdc\x6a\x89\xb9\xe4\xcf\x01\x92\x49\x2a\x4e\x47\x71\xe2\x25\x69\x22\x2b\x94\xca\x0b\xc4\x78\x81\x4c\x54\x30\x4a\x22\x1e\x4b\xf6\x18\x0a\x95\x98\x3c\x5f\x58\xb1\x58\x38\x91\x93\x84\x91\xd5\xf2\x62\xd9\x47\x13\xd0\x77\x3b\x93\xd4\x34\x0a\xd3\x45\x19\x25\xfb\x7c\x8a\xa8\x4c\x53\x91\x18\x87\x91\x5b\x86\xc9\x51\x8c\x10\x96\x69\x2b\x0d\xbc\xa4\x0c\x92\x9a\x48\x01\xd4\xdf\xa9\xf1\xf3\x85\x6c\x90\x9b\xb9\xd1\x05\x03\x0c\x32\xfd\x2d\x1c\x37\x4b\x3b\x85\xed\x5a\x0b\xc7\x7d\xc5\xf8\xc2\x01\x5c\xa6\xc0\x99\x37\x9d\x59\xe1\x38\x11\x89\xb5\x88\x44\x2c\x12\xab\x35\x0b\x17\xd2\x94\xa0\xf6\x41\x26\xc0\x51\x24\x9c\x13\x6b\x21\xa2\xb9\x97\x24\xc2\xb5\x66\x22\x92\x46\x5f\xc8\x9c\x36\x82\x9c\x36\xc8\x24\x18\x84\x39\x5a\x61\x82\x91\xc4\x04\x88\xc9\xb4\xe7\x05\xae\xf8\x68\xb5\xbc\x40\x56\xc9\x83\xf1\x1c\xe4\x6a\xfb\x98\x28\x97\xb7\x82\xac\x69\x01\x98\x66\x70\x5c\xca\x99\xb1\xf0\xc5\x58\x56\xc6\x89\x84\x63\xb5\xe2\xd8\x91\x03\x8b\xed\xd3\x95\xb6\x07\x15\x19\x54\x40\x7f\x0e\x06\xc6\x0c\xa5\x7a\x24\x91\x09\x6d\x86\x70\x73\x42\x3b\xf3\x92\x99\xf5\x3e\x8d\x13\x6f\xe2\x8d\x31\xc7\xbd\x97\xec\xf7\xc0\x5e\x52\x59\x2c\xbb\xce\x69\x76\x9d\x53\xbc\xce\x4a\x8d\x64\x94\x78\x8e\x9f\xa7\xc5\x30\x3a\x73\x22\xd7\x6a\x2d\xfc\x6c\x30\x5d\x80\xae\x2b\x50\x99\x8f\x01\x9b\x4a\x6c\x0a\xd8\x8d\x52\xe2\xa9\x88\x62\xa1\x67\xdb\x48\xe6\xb1\x08\xf2\xd8\x40\x25\x41\x2f\x98\xfa\xe2\x40\x25\xbb\x2c\xed\xc4\x99\x60\x63\x48\x3b\x83\x5d\x15\xa6\x92\x4e\x9c\x19\x20\x86\xa4\x33\x3c\x24\x92\x4e\x9c\x44\xd9\xe4\xe8\x8e\x65\xcb\x5d\xf0\xdd\x30\xd3\xe6\x22\xf2\x4e\x9d\x44\x58\x69\x2c\x54\x6a\x5c\xa4\xd2\x06\x0b\x48\x8d\xc3\xce\x3e\x2a\xab\xe0\x22\x95\x15\x5c\x40\x05\x87\x99\x28\x65\xff\xe6\xe9\x26\x91\x0a\xca\x32\x41\xd6\xdd\x09\x74\xf7\xb0\xa7\xa5\x1a\xcd\x37\xe3\xb1\x14\xf0\x18\xeb\x96\x89\x74\x2e\xe2\x58\x4e\x20\x67\x8e\x97\x64\x2d\x98\x9f\xbd\x62\x7c\x7e\x06\xa0\xb2\x52\xa7\xa9\x13\xb9\x85\x50\x17\x99\x50\xa7\x80\xd5\x85\x5a\x46\x8a\x0c\x29\x10\x39\x28\xeb\x3f\xef\xbc\x38\x94\xed\x88\xb1\x1d\xc3\x62\x44\xac\x69\xe4\x2c\x66\xde\x58\x6b\x8f\x27\x7b\xde\x4d\xc7\xb2\x69\xf1\x74\x2c\xc7\x7c\x8a\x6d\x5b\x6a\x54\x03\x25\x63\xc4\xc8\xc8\x34\x8a\xc3\x29\x3e\xa4\x22\x18\x8b\x12\x63\x9c\xcd\x8f\x63\xd0\xd5\x70\xad\x1a\x91\xd5\x3d\x91\x09\x25\x50\x49\x2e\x96\xf3\x78\x0c\x69\x6c\x98\xa9\x34\x5c\x88\xc8\xc9\x3a\x38\x3e\x8f\x13\x31\xb7\xc6\xe1\x7c\xee\x04\xae\xd5\x0a\xb3\x4c\x1d\x62\x3d\xb6\xa8\x85\xf1\x39\x8e\x4e\x6b\x21\x27\x83\x05\x4c\x06\xc3\x4c\xab\xce\x62\xe1\x83\x39\x17\x51\x38\x8d\x1c\x2d\xac\xb3\x90\x61\x1d\x08\xbb\x3c\x54\x19\xed\x40\x65\xb4\x6c\x7d\xc3\x78\x00\x5d\xbd\x6c\xab\x64\x76\x2a\x22\x99\x5c\xc4\xc7\xb1\xef\xcc\x55\xe4\xb9\x13\x9d\x30\xfe\x02\x5a\xbd\xcc\xb4\x3a\x16\x41\x62\xc5\xde\x34\x60\x7c\xfc\x08\x25\x99\x3e\x17\x61\x1a\xb8\x79\xd1\x62\x03\x45\x4a\x91\x69\x14\x89\x60\x7c\x0e\xc4\x27\x28\xcd\x84\x78\x2e\x82\xbc\xe0\x7c\x0b\x05\xc7\x2a\x63\x87\x27\x22\xb0\x46\x4e\xc4\xf8\x08\x66\xbb\x65\x5f\x99\x61\xac\x92\x4e\xc6\x8b\x05\x14\x66\xf2\x72\x3d\x47\x44\x22\xf6\x62\xc6\x5f\xbe\x85\x12\x95\xf1\xc2\xc5\x79\xe4\x4d\x67\xd8\x84\x3b\x28\xce\x64\x33\x11\x73\x2f\x90\xd9\x24\x8c\x5c\x2f\x70\x7c\x99\xe4\x65\x3f\x87\x11\xe3\x07\x4b\x80\xaa\x35\x9c\x98\x24\x07\x8b\xd0\x0b\xb2\xa1\x75\xc3\x74\xe4\x0b\xcb\xc9\x54\xf7\x21\x0d\x13\xbd\x07\xff\xfa\x0b\x98\x6b\x35\x14\x70\xf5\x00\x26\xa8\x65\xa6\x94\x38\x9c\x24\xd6\xec\x7c\x31\x13\x01\xe3\x07\x07\x50\x96\xcf\xba\x53\x2f\x4e\x44\x24\xa0\x87\xa3\x4f\x50\x9e\x29\x62\xee\xc8\x35\x0b\xe3\x2f\xbf\xe6\x7f\x5e\xe5\xb9\x6a\x2a\x13\x99\xa2\xb8\x60\xc2\x95\xca\x4d\x7e\x1a\x1f\xcc\xbd\x20\x8d\xf3\xf2\xdf\xe1\x92\x2b\xb5\xb0\x4f\x17\x22\x8a\xc7\x91\xb7\xc8\xd2\x26\xe3\x1d\xd0\xcc\xaa\x5b\x29\x97\xf9\x92\xf1\x2e\x22\x7a\x6a\x31\x2e\x97\x2b\xce\x58\x6a\x86\xf1\x97\x2f\xa1\x50\xa5\x1f\x6f\x1c\x85\xf9\x95\xe7\x3f\xa1\x28\x1b\xf7\x85\xe7\x8f\xa3\xf0\x0c\xb4\x04\x02\x5c\xf5\x15\xcf\x95\xab\x32\x37\x4c\x18\x7f\x0d\xb6\x58\xa9\xe9\x4f\xb8\x9e\xef\x3b\x8c\xbf\xfc\x03\xfe\x3e\xdc\xaf\x69\x18\x08\xc6\xdb\x58\xcf\xa5\xea\xbc\x78\x9c\xfa\xa6\x71\x07\x89\xac\xb2\x71\xcf\xd4\xf3\xcc\x81\x7f\xf7\x0e\xa8\xd9\xc0\x9f\xa6\xfe\xd4\x89\xac\x89\x4c\x49\x12\x24\x27\x84\x0f\xa9\x13\x25\x22\x62\xbc\x0d\xeb\xd5\xd5\xc6\x84\x9d\x39\xfe\x84\xf1\x36\xcc\x0a\xab\x2d\x05\x54\x33\x57\x1e\x36\x66\xbc\x8b\x71\x77\x25\xa3\x7f\x48\x45\xac\x55\xf5\x1f\xe8\xe4\x75\xa6\x1b\x39\xa5\x07\xd6\xd8\x59\x78\x89\x9c\x8c\x45\x22\x73\xa8\xa3\xd6\x06\xd3\xc8\x39\x15\x8c\x3b\x2f\x80\xd1\x6e\x62\x64\x3a\x60\xdc\x01\x01\xac\x3b\x4d\x8c\xb1\x17\x8d\xd3\xf9\xc4\x17\x1f\x19\x77\xa0\x17\xd7\xdd\x26\x5a\xe2\xf9\xae\xbc\xd0\x3f\xc0\xe8\x35\x31\xb4\x54\xe1\x40\xaa\x58\x1f\x35\xb1\xb2\xc4\xef\x8c\xc2\xac\x1f\x60\xb5\xb6\x3e\x36\xd3\x24\x0e\x72\xd4\xba\x6f\xc4\x8d\xf3\xd6\x83\x8e\xc7\xa0\xe3\xf5\xc0\xc8\x11\xa5\x51\x11\x38\x2a\xc3\x26\x46\x3e\x2a\x02\x47\x65\xd9\xc4\xd0\x47\x45\xe0\xa8\xac\x9a\x68\x5a\x1f\x0b\xec\xe3\xb5\x91\xe5\x95\x1a\xe4\x61\x83\x36\x4d\x8c\xbc\x41\x1e\x36\x68\xdb\xc4\xd0\x1b\xe4\x61\x83\x76\x4d\x34\xad\x41\x1e\x34\x68\x63\xf6\x8d\x48\x66\x56\xcb\x5b\x6f\x6f\x96\xb7\x9b\xeb\xb5\x5c\x24\x42\xa2\xdd\x98\xad\x13\x94\x14\x1d\x80\xa2\x37\x66\xeb\x84\xa5\x7e\x0b\xa1\xdf\x36\x66\xd7\x84\xa5\x7e\x0b\xa1\xdf\x36\x66\xd7\x84\xd5\x7e\x0b\xa1\xdf\x36\x66\xdb\x84\xa5\xc6\x84\xd8\x18\xb3\x63\xc2\x4a\x4f\x87\xd8\xd3\x6a\x1a\x48\xfd\xc4\x2b\x56\x41\x6a\xaa\xf8\x0d\x6e\x2a\x6d\xcc\x7e\xc9\x23\xc7\x89\x5c\x5c\x30\x1e\xbe\x01\x8a\xd9\x30\x69\xa9\x67\x53\xec\x59\xb3\x61\xd2\x52\xcf\xa6\xd8\xb3\x66\xaf\xa4\xd5\x9e\x4d\xb1\x67\xcd\x66\x49\x2b\xfd\x94\x62\x3f\x99\x0d\x73\x5e\xaa\xde\x39\x56\xcf\x6c\x98\x64\x16\x46\x41\x59\xc5\x09\xec\x87\x37\x9a\x61\xe2\xb9\xe3\x23\x29\x9e\x39\xd1\xc2\x8a\xad\xd6\x74\x7b\xff\x75\x79\xfb\x4a\xbb\xc5\xb8\x3d\x34\x70\xca\x93\xcc\x12\xfa\x7a\xdb\xae\xc7\xe7\x4d\x59\x42\x53\xb6\x9d\x7a\xbc\xde\xcf\x4b\xe8\xe7\x6d\xb7\x9e\x94\xeb\x77\x09\xfa\xdd\xf6\xea\xf1\xda\xa8\x2c\x61\x54\xb6\x47\xf5\x1c\x7d\x6a\x59\xc2\x92\x73\x7b\x6c\x22\x49\x14\x2c\x9a\xb7\x7d\x03\x6a\x7f\x5a\x59\xc3\xb4\xb2\x1d\x18\x18\xe5\x49\x65\x8b\xa3\x30\xac\xc7\xe7\xa3\xb0\xc5\x51\x58\xd6\xe3\xf5\x51\xd8\xe2\x28\xac\xea\x49\x5a\xaf\x6e\xb1\x57\xd7\x06\x4e\x79\x32\xb9\xc6\x86\x6c\xea\xf1\x79\x43\xae\xb1\x21\xdb\x7a\xbc\xde\x90\x6b\x6c\x88\xc9\x17\xd5\x69\xe4\x1a\x1a\xb2\x33\xf9\xa2\x32\x89\x6c\x60\x12\xd9\x99\xac\x51\x9e\x42\x6e\x41\xb5\x3b\x93\x35\xca\x13\xc8\x1d\xf4\xd5\xce\xe4\x8a\xf2\xf4\x71\x07\x7d\xb5\x33\xb9\x82\x98\x3c\xee\xa0\xaf\x76\x26\x5b\x94\xa7\x8e\x3b\x6c\x84\xc9\x11\xd5\x89\xe3\x0e\xfb\xb6\xaf\x36\x87\xa7\x5e\x5c\x4c\x19\x07\x58\x6a\xf2\xc2\xde\x84\x71\x07\x13\xc6\xce\x64\x86\xf2\x74\xf1\x84\xfd\x68\x32\x43\x79\xb2\x78\xc2\x7e\x34\xf9\x80\x98\x2a\x9e\xb0\x1f\x4d\x46\xa8\x4e\x14\x4f\xd8\x72\x93\x19\xca\xd3\xc4\x4f\xac\x98\xc9\x0c\xc4\x24\xf1\x78\x05\x24\x93\x19\xce\x2b\x15\xfb\x99\x57\xac\x7d\xd8\xb8\x17\x81\x6d\xaf\x73\x00\x94\x86\x79\x02\x08\x4b\x24\x34\xee\x45\x46\x91\xc8\xd6\xf9\x2d\x60\x34\xcc\x12\x39\x7e\x89\xf8\xc6\x4d\x48\x38\x0d\x03\x71\xc2\xb8\xf3\x27\x50\x1a\x26\x09\x20\x2c\x91\x60\x5e\x49\x8d\x4b\x83\x38\x7e\x09\x8c\x86\xc9\x22\xc7\xaf\x11\x6f\x5e\x51\x8d\xab\x7a\x1c\xbf\x03\x9a\xc9\x24\x04\x69\x8d\x24\xf3\xc2\x2a\xa7\xb9\x61\x02\x93\xe4\xf8\x35\xb0\x4c\x7e\xa9\x72\xd6\xc8\x31\xaf\xac\xa0\x82\x4e\xa6\x97\xf1\x5f\xc0\x30\x99\xa5\x8c\x5f\x23\xde\xbc\xa6\x72\x4b\x0c\x17\x19\x26\xa7\x94\xf1\x1b\xc0\xb7\xcd\x2e\x71\xcb\xa9\xcb\x7d\x03\x14\x93\x4b\xf6\x08\x1b\x24\x98\x5d\x22\xca\xc6\x12\x60\xac\xb6\xc9\x26\x7b\x84\x2d\x12\xcc\x3e\x11\x25\x67\x09\x70\x56\xdb\x64\x93\x32\x7e\x8b\x78\xb3\x4b\x44\x45\x23\x02\x34\xd2\x36\x39\xa5\xca\xd9\x22\xa7\x71\xbf\x0e\x16\x16\x60\xe1\x76\xc3\xda\x0a\x08\x5b\x24\x34\xef\xd7\x95\x52\x04\x2a\xa5\x61\x65\x95\xe3\xb7\x88\x37\xbb\x63\x5a\xb5\xef\x14\xec\xdb\x36\x59\x84\x20\x7d\x42\x92\xd9\x27\xd3\xd2\x68\x4e\x71\x34\x4d\x3e\x29\xe3\x3f\x01\xbe\x63\xf6\xc9\xb4\x32\x92\x53\x18\xc9\x8e\xc9\x2a\x55\xce\x27\xe4\x98\xdd\x32\xdd\x5b\x8a\x4f\xff\x00\x8e\xc9\x2e\xfb\x8c\x4f\xc8\x30\xfb\x65\x56\xed\xe8\x19\x74\x74\xc7\x64\x1a\x82\x74\x85\x24\xb3\x73\x66\xe5\x94\x31\x83\x94\xd1\x31\xd9\x66\x8f\x70\x85\x04\xb3\x67\xbc\xd2\x22\xd0\xfb\x07\x18\x26\xcb\x94\xf1\xd7\x88\x37\x3b\xc6\x2b\x27\x25\x0f\x92\x52\xc7\x64\x99\x3d\xc2\x35\x12\x1a\x6f\x6c\xe5\xba\xf4\x50\x97\x0d\x7b\x91\x1c\x7f\x8d\xf8\xc6\xdb\x5a\x90\x2a\x3c\x48\x15\x9d\x86\x9d\x08\x10\xae\x81\xd0\x35\x7b\xc5\xab\xe8\xde\x03\xdd\x77\x4d\x5e\xf1\x24\xdc\x17\xb1\xdc\xe9\x20\x98\x32\x89\x37\x75\x92\x34\x12\x96\xf7\x9e\x71\xef\x3d\x20\xab\xd6\xd0\x71\xd7\x9f\x01\x67\x36\xc4\xfb\xaa\xb6\xdf\x83\xb6\xbb\x26\x43\x10\xa4\xcf\x48\x32\x1b\xe2\x64\xcf\xb0\x27\x60\xd8\xae\xc9\x11\xfb\x8c\x2f\xc8\x30\xed\x49\x4e\x22\xc7\x6a\x4d\xef\xb7\xdb\x5b\x5c\x69\x7f\xf9\x02\x24\xf3\x8d\x2c\xbf\xb4\xb6\xf3\x61\x6d\xd7\x35\xed\x4c\xca\xf8\x1b\xc4\x9b\x6f\x63\xf9\x7b\x4d\xf1\xb1\x29\xa6\x8d\xc9\x3e\xe3\x06\x19\xe6\xfb\x57\x7e\x69\xbe\xf2\x61\xbe\xea\x9a\x36\x26\x65\xfc\x0d\xe2\xcd\x77\x7a\x73\x86\xfe\x63\x93\x0f\xca\xed\x99\xf6\xe8\x04\xe9\x06\x49\xe6\x5b\xbd\x7e\x39\x21\xfa\x90\x10\x7b\xa6\x8d\xfa\x1e\xe1\x06\x09\xe6\x5b\xbd\x41\x69\x24\x03\x18\xc9\x9e\x69\xaf\x5e\xc6\xdf\x22\xde\x7c\x8f\x37\xd8\x1b\xc7\x00\xc6\xb1\x67\xda\xaa\xef\x33\x6e\x91\x61\xfe\x85\x24\x28\x8d\x64\x00\x23\xd9\x33\x19\xa5\x8c\xbf\x45\xbc\x69\xe6\x08\xac\x45\x24\xc6\xc2\x15\xae\x35\x3a\xb7\x9c\x45\x28\x3b\x79\x31\x13\x8c\xbf\xbc\x05\x6e\xcd\xba\x2b\x98\x5a\x2d\x7f\xf9\xed\xdb\xf5\xc3\xd5\x2b\xc6\x83\x29\x50\x8c\x0b\xaf\x32\xe1\xf6\x13\x10\xcc\xb3\x48\x58\x9e\x78\x42\x98\x78\x7a\xa6\x69\x64\x8f\x70\x87\x04\xf3\x3c\x12\x96\x66\x9e\x10\x66\x9e\x9e\x69\x1a\x29\xe3\xef\x00\x7f\x64\x9e\x45\xe0\x36\x4d\xfe\xf3\x69\xfe\x0b\xc4\x7f\x80\x68\x9a\x48\x48\xda\x1d\xd2\xea\xa6\x94\x50\x5e\x40\x00\xd2\x3c\xa5\x48\xdc\xdd\x16\x70\xe6\x29\x25\x2a\x39\x24\x02\x87\x1c\x99\x66\x93\x32\xfe\x1e\xf1\xe6\x89\x24\xda\xf3\x47\x04\xfe\x38\x32\x4d\x24\xfb\x8c\x7b\x64\x98\xd7\x56\x51\xc9\x21\x11\x38\xe4\xc8\xe4\x90\x32\xfe\x1e\xf1\x66\x57\xc4\xa5\x96\xc7\xd8\x72\x93\x29\xca\xf8\x07\xc4\x9b\x3d\x11\x57\x67\xea\x18\x66\xea\x23\x93\x2f\x08\xd2\x03\x92\xcc\xde\x88\xf7\xfa\x38\xc6\x3e\x36\xfe\x0c\xb2\xc7\x78\x00\xc6\xb1\xd9\x1f\x71\xa9\x97\x63\xe8\xe5\x63\x93\x31\xca\xf8\x07\xc4\x9b\x77\x22\xc9\x5e\xad\x12\xac\x95\x69\x27\xb2\xcf\x78\x44\x86\xd9\x25\x49\xa9\x5e\x09\xd6\xcb\xe4\x92\x32\xfe\x11\xf1\x66\x97\x24\xe5\xc9\x30\x81\xc9\xf0\xd8\x64\x92\x3d\xc2\x23\x12\xcc\x1e\x49\x4b\xfb\x89\x14\xf6\x13\xc7\x0d\x77\x80\x73\xfc\x13\xe2\x1b\x7f\x30\x84\x24\x9d\x42\x92\x3e\x6e\xb8\x09\x0c\x84\x27\x24\x34\xfe\x56\x98\x67\xe9\x14\xb2\xf4\xb1\xc9\x20\x65\xfc\x13\xe2\xcd\xde\x48\xab\xbf\x61\xa5\x87\x40\x33\xd9\x83\x20\x3d\x01\xa9\x6f\x76\x48\x4a\x4d\x05\x29\x4c\x05\x7d\x93\x51\x48\xda\x13\xd2\xcc\x7e\x49\xcb\x5b\xa5\x14\xb6\x4a\x7d\x93\x5d\xf6\x08\x4f\x48\x30\xbb\xe5\xac\x9a\x92\xce\x20\x25\xf5\x4d\x96\x21\x48\x3f\x90\x64\xf6\xcd\x79\x95\x76\x8e\x34\x93\x77\x08\xd2\x4f\x24\x99\xfd\x53\xbd\xc7\x7f\x0e\xf7\xf8\xfb\xe6\xdd\xca\x45\x69\x1e\xb8\x80\x79\xa0\x6f\xda\xad\x94\xf1\xbf\x10\x6f\xde\xad\x5c\x54\xf6\xb2\x17\xb0\x5e\xef\x9b\xf6\x2b\x55\xce\x2f\xe4\x98\x77\x2c\x17\xa5\xbc\x76\x01\x79\xad\x6f\xda\xb1\x94\xf1\xbf\x00\xbf\x6c\x5c\x51\xcd\xc2\x48\xae\x0a\x87\x40\x68\x58\x49\x29\xf8\x1d\xc2\x6b\x1e\x2f\xf1\x18\x0f\x3d\xc0\x19\x7f\x13\xf4\x18\xbf\xbb\x06\x94\xa6\x3e\x50\x42\xc4\xf8\xcf\x7b\x28\x37\xef\xbf\x52\xbd\x7a\x29\x54\x6f\x65\xda\x79\x95\xe0\x4f\x08\x37\xef\x56\x2e\xca\x93\xc0\x05\x4c\x02\x2b\xd3\x66\x65\x8f\xf0\x0b\x09\xe6\xbd\x8a\xb8\x98\x31\x2e\xf2\xe7\xdb\xdb\x35\xcf\x2f\x39\xa5\xc1\x76\x60\xb0\xd7\x26\x71\x94\xf1\x4b\xc4\x37\x3e\xb8\x94\x33\x3c\x60\x6c\x4c\xfd\x59\xc6\x5f\x23\xde\xbc\x89\x0d\x4b\x8c\x10\x19\x0d\x3f\x36\xe7\xf8\x3b\xc4\x9b\xb7\xb0\x69\x89\x91\x22\xc3\xb4\x85\x2d\xe3\x9f\x10\x6f\x16\xc5\xfe\x6f\xa4\x96\x13\xb8\x38\xc3\x5e\xa6\x6f\x0f\x2e\x21\x86\x49\x25\xf5\x11\x9e\xb4\x08\x66\xd9\x90\x31\xf2\xa4\x76\x99\xbe\x7d\x89\x21\x4c\x7b\xde\xda\x00\x4f\x5a\x80\xc6\x27\x9e\xca\x21\xf2\x9e\xbc\x4c\xdf\xfe\x85\x21\x1a\x7e\xd3\xa6\x03\x3c\x69\x01\x1a\x9f\x88\x2a\x87\xc8\x7f\x54\xbf\x4c\xdf\xbe\xc0\x10\xcf\xfd\xc9\xbb\x14\xe0\x49\x0b\x60\x5e\xd0\xec\x3f\xc8\x53\x1a\x4f\xa7\x0d\x01\x4c\x4b\x9b\x5a\xfa\x12\xe8\xdb\xc6\x9f\xb9\x71\xb2\x29\x5f\xbf\x0f\x01\x1a\x7e\xf4\xa6\xe9\x4b\xa4\xd7\xfc\x04\xbe\xf7\x63\x9d\xd3\x05\x8e\xf1\x47\xf0\x3d\xc6\x12\x19\xe6\x65\xcf\xb4\x9c\x5b\xa7\x90\x5b\x8d\xcf\x4a\xed\x11\x3e\x21\xc1\xbc\xdc\x99\x96\xb2\xc1\x14\xb2\x81\xf1\x99\xa9\x32\xfe\x13\xe2\xcd\x8b\x9c\x93\x12\xe3\x04\x19\xa6\x4d\x42\x19\xff\x05\xf1\xe6\x4d\x42\x58\x5e\x51\x86\xb0\xa2\x34\x3e\x31\xb5\x47\xb8\x43\x42\xe3\xed\x25\x45\x29\xe9\x25\x44\xbd\x36\xdc\x69\x22\xb8\x77\xc8\x35\x7b\x4d\x5c\xcc\x4a\x3d\x22\x2e\x80\x63\xb2\xd7\x3e\x63\xfb\x2b\x67\x18\x9f\xa2\x7a\x5f\xc2\x7f\x86\x3e\xdf\x35\x6a\x33\x4f\x9f\x53\x58\x54\x1a\x9f\x57\x2a\xe3\x3f\x21\xde\x3c\xaa\x95\x07\xff\x4a\xf9\xda\x71\x30\x5f\x1b\x1f\x08\xaa\x8f\xb0\x5c\x16\x11\xcc\xe3\xee\x94\x1f\xe1\xbb\x74\x44\xc1\x32\x8d\xf7\x3e\x67\xb9\x2d\x38\x8d\x37\x17\x95\x79\x4b\x35\x0d\xdf\x14\xfc\x86\x5b\x8d\x04\xfb\x0e\xd9\x1d\xf5\xae\xc3\x3c\x74\xbd\x89\x27\x22\xbc\x6d\x2e\x26\x49\xf6\x12\x45\xd6\x53\x8c\xff\x99\xbf\x05\xd2\x51\x4f\xe4\xe7\xa2\x78\x99\x8b\xa2\xa3\xe6\xd7\x7c\xf7\xfb\xb2\x05\x7f\xcd\xec\xac\xad\xfe\x5f\xbe\x86\x92\x6c\x88\xf5\x6d\xec\xcb\x43\x28\xca\x46\x0e\x6c\xf8\xf2\x4f\xf8\xf3\x46\xc5\x2a\xb6\xa2\xc5\xcb\x32\xf9\x8e\xb4\xab\x5e\x18\x9d\x46\x42\x9c\x54\x86\xcc\x5f\xcc\xf6\xde\xb0\xf8\x2f\xb0\x06\x46\x96\x58\xc4\x9e\x1f\x96\xef\xef\x0b\xe4\x0d\xcd\xbc\xa4\x7c\xad\x73\xe4\x2c\x8d\x1c\x2f\xdc\x23\x79\x48\x5a\x1b\x49\x61\xf6\x66\x50\xb9\x82\x21\xf2\xb6\x46\x5e\x4a\x34\x2c\x45\xde\xae\xe6\x7a\x62\x5a\xae\xe5\x19\xb0\xd4\x0b\x9f\x8a\x55\x5e\x1f\x97\x1b\x96\xe9\x50\x7f\x9c\xb3\x0b\x01\xda\xf5\xa3\xc7\xb8\xf3\x1b\x40\x3b\x46\xe8\x48\x24\x0e\xe3\x23\x44\x76\x8d\xc8\xa9\x33\x9f\x3b\x8c\x4f\x11\xda\x33\x42\x5d\xe1\xcb\xa8\x2e\x42\x8f\x9a\x24\xc3\xb8\x40\xb0\x59\x95\x17\x59\x65\x2f\x10\xd9\xaf\x53\x14\xe3\xe7\x08\x34\x4b\x36\x99\x65\xd0\x19\x42\xcd\x2a\x95\x03\xc3\xb8\x87\x48\xb3\x36\x4f\x9c\xc5\xc2\x61\xfc\x04\xa1\x2b\x23\xd4\x77\xe6\xae\xc3\xb8\x8f\x50\xb3\x78\xe7\x29\xe3\x73\xc4\x6d\x8c\xb8\x20\x65\x3c\x40\x9c\x59\xd4\x1f\x3d\xc6\xc7\x88\xab\x13\xb1\x97\xcf\xd2\x00\x5e\x1e\x1a\xc1\x0b\x8f\xf1\x05\xe2\xcc\x12\x8d\x66\x21\xe3\x11\x02\xcd\xb2\x8b\xbd\xa9\x94\x5d\x8c\x50\xb3\xec\x12\x27\x65\x3c\x41\xa0\x59\x74\x29\x88\x2e\x45\xb0\x59\x74\x8b\x99\xc7\xf8\x04\x81\x66\xcd\x8d\x25\xf0\x23\x02\xcd\x9a\x5b\xc4\x1e\xe3\x1f\x10\x68\x56\x5c\x96\x3e\x18\x3f\x43\xe8\x73\xd2\xa1\x96\x2b\xde\x23\xd1\x2c\xc0\x52\x6a\xd3\xb8\xa7\xc8\x5d\x1b\x12\x55\x75\x8e\x58\x42\x72\x5b\x6e\x0c\x1c\x6a\x86\xd8\x22\x6b\x6b\x62\xed\xa5\xfa\x9f\xc8\xd8\x3d\x2f\x89\x32\x7e\x0d\x94\x95\x29\xef\x56\x73\xfc\x7e\xea\x7d\x82\xd4\xbb\x6a\xd7\x75\x09\xe3\x4b\xe8\xbb\x55\xc7\x00\x54\x69\x77\x85\xb8\xae\x01\x97\x27\xdd\x4f\x08\xec\x19\x80\x79\xca\xdd\x20\xf0\xa8\x7e\x04\x18\xdf\x22\xf4\xd8\x00\x55\xe9\xf6\x17\xe2\xfa\xe6\xe1\x61\xfc\x27\xc2\x06\x06\x58\x9e\x6a\xaf\x10\x38\xac\x19\x3c\xc6\xaf\x11\xb7\x34\xe0\xf2\x34\xfb\x05\x81\x2b\x03\x30\x4f\xb2\x37\x08\x34\x49\x5a\xa6\xd8\xaf\x88\x32\x89\x58\x26\xd8\x5b\x44\x99\x44\x2b\xd3\xeb\x1a\x51\x26\xa1\x62\x72\xbd\x03\xe8\xda\x24\x50\x99\x5a\xbf\x21\xca\x24\xc1\x2c\xb1\xde\x23\xcc\x24\xc0\x49\xf6\x2e\x72\x9e\x5c\x7f\x7b\x00\xb8\x49\x87\x39\xf0\x01\xe3\x9a\x74\x98\xe5\xe0\x47\x84\x99\x54\x88\x19\xf8\x09\xa1\x26\x15\x66\xf9\x77\x87\x30\x93\x08\xb3\xec\xfb\x2f\xc2\x4c\x22\xcc\x72\xef\xff\x10\x66\x92\x60\x9e\x79\x7f\x20\xd0\xa4\x41\x32\xef\x7e\x46\x9a\x49\x91\xa6\xac\xfb\x1d\x99\x26\x89\x52\x4b\xd8\x3b\x48\x6e\x6b\x93\x64\xa9\x05\xec\x13\xb2\x4c\x12\xae\x2e\x5f\x7f\x00\x67\xa3\x75\x70\x90\xce\x45\xa4\xd4\x24\x37\x39\x53\x80\x68\x9d\xeb\x87\x67\x99\x71\x74\xe0\x1f\x08\x34\x4f\x6b\x71\xa2\x84\x97\x40\xea\xdd\x98\x7a\x14\x90\x8f\x88\x34\xaf\xa4\x5c\x2f\xcf\xab\x73\x04\x9b\x3a\x0e\xa1\x5f\x11\x6a\x5e\x51\x9d\x84\x6a\xdd\x87\x50\x93\xeb\x73\xe0\x17\x00\x6e\xcd\x0b\xaa\xd8\x99\x67\x6b\x2a\x84\x9a\x8c\x9f\x03\xbf\x01\x70\x57\x39\x27\xa1\x3c\x9f\x59\xad\xe4\xee\xf6\xee\x21\x3b\x68\xcf\xbd\x5e\xde\xfc\x7c\xbc\xfe\xb2\x7c\xc5\xf8\x4b\x18\xe2\x9d\x66\xde\x4c\xe6\x23\xe1\x87\x67\x8c\x7f\xce\xaf\xd0\x53\x2f\xc4\x8c\xcf\x23\xcf\xf7\xbd\x71\x75\x45\xc2\xb8\x17\x02\xb4\x53\x07\x75\xdf\x0b\xab\x15\x6f\xef\x57\x77\xeb\xfb\xbb\xe5\xe3\x75\xf6\x3e\xa7\xfb\x5f\xe0\x76\xeb\xb8\x53\xc9\x9d\x2f\xd7\xdb\xcd\xdd\xad\x22\x4e\x91\xd8\xab\x23\xa6\x27\x91\xe3\x05\x9e\x13\x58\x9e\xdc\x3d\x0a\x20\x1d\xd5\xd6\xf4\x62\xff\x6a\x6e\x0c\xc4\xe3\x3a\xe2\xe8\x5c\xf8\x61\x94\xc6\xb1\xe7\x04\x07\xda\xa5\x19\xf7\x3c\x08\xd0\xaf\x0b\x70\xee\x59\xad\xf4\xcb\xfd\xf2\x3a\xbf\xee\x39\xd2\x06\x75\xb4\xf7\x82\xf1\xf7\xd8\x21\xc3\x3a\xa8\x2f\xb1\xfe\x7b\xc0\x2e\xeb\xb0\x81\xc4\x06\x88\x5d\xd5\x61\x93\x78\x46\x0c\x6f\xf2\x00\xe4\x75\x1d\xf9\xa4\x32\xbc\x27\x78\xd5\x6d\x1d\x31\x9e\x85\x51\x62\xa5\x56\x6b\xf4\x73\x7b\x73\x77\xff\xf4\xf0\xa0\xe8\xa7\xd8\x19\xbb\xfa\x81\x9e\x09\xc6\xdd\xfc\x3e\x61\x4f\xbd\x08\x63\x02\xcb\xbd\xf6\xdf\x80\xac\x35\xc5\x48\x30\x3e\x42\x68\xad\x29\x4e\x05\xe3\xa7\x08\xad\xf7\x80\xac\xeb\x14\xb1\xb5\xb2\x77\x65\xb3\x10\x5a\x2b\x76\xe9\x0b\x81\xd0\x5a\x79\x67\xbd\x75\x01\x5d\xdb\xae\x55\xf2\x85\x84\x62\xd8\x5a\xf5\x4a\x7b\x20\xb2\x56\xbc\x6a\xb8\x3d\xc6\xdf\x23\xbe\x56\xc0\x27\x32\x4f\x23\xb4\x56\xbf\xc2\x67\xdc\x47\x68\xad\x5a\xc5\x9c\xf1\x39\x42\x37\xb5\xd0\x80\xf1\x00\xa1\xb5\x52\x0e\x19\x0f\x11\x59\xab\xda\x85\x60\x7c\x01\xd0\x4e\xad\x66\x45\xc4\x78\x84\xd0\x5a\xd1\x8a\x98\xf1\x18\xa1\xb5\xa2\x95\x6b\x84\x04\xa1\xb5\xa2\x4d\x19\x4f\x11\x59\x2b\x59\x31\x61\x7c\x82\xd0\x5a\xc9\xca\xdd\xd7\x0c\xa1\xb5\x92\x4d\x62\xc1\xf8\x18\xb1\xb5\x92\x1d\x4b\x79\x8f\x41\xde\x9d\x5a\xcd\xc6\xb2\x0e\x31\x62\x1b\x54\x3b\xce\xd0\x6b\x40\xd7\x6a\x76\xe6\x44\x70\x44\xd3\xdf\xff\x01\x46\xad\x74\xcf\x45\x94\x32\x7e\x8e\x8d\xac\x15\x6f\x76\x46\x94\x0a\xff\x5f\x0c\x5f\xaf\x61\xc6\xdf\xc3\xbc\xd9\xa9\x95\xf0\x79\xca\xf8\xfb\x14\xa0\xb5\x1a\x3e\x77\x18\x7f\x9f\x1f\x7c\xd3\xeb\x96\x35\x5c\xde\x6c\x33\xbe\x84\x96\x75\xdb\x66\x9c\xcc\xb9\x2b\x04\x76\xcc\x40\x99\x71\xbf\x23\xb0\x6b\x06\x66\xf9\xf6\x13\x22\x7b\x66\xa4\xcc\xb6\x1b\x04\x1e\x99\x81\x32\xd7\x6e\x11\x78\x6c\x06\x66\x99\xf6\x17\xc8\xab\xdb\xaf\x41\x4a\x20\x86\x1c\xd4\x5c\x9b\xf1\x6b\xc4\x0d\xcd\x38\xcc\xb1\x9f\x11\xbd\x34\xa3\x65\x86\xfd\x82\xc0\x95\x19\x28\xf3\xeb\x0d\x02\xd7\x35\xc0\x39\xe3\x5f\x11\xb8\xa9\x01\x06\x8c\xdf\x22\x70\x6b\x06\x86\x8c\xdf\x21\x6e\x67\xc6\xc9\xbc\xfa\x0d\x80\xbd\x1a\x4d\xca\xac\x7a\x8f\xc0\x1a\x51\xca\x9c\xfa\x80\xc0\x1a\x51\xca\x8c\xfa\x88\xc0\x1a\x51\xa6\x8c\x3f\x21\xae\x46\x92\x32\x9b\xee\x10\x58\x23\x49\x99\x99\xae\x10\x58\x23\xc9\x2c\x93\xae\x11\x59\x23\xc9\x2c\x8f\xae\x41\xbc\xbd\x1a\x4d\x66\x59\xf4\x01\x91\xb5\xaa\xcc\x72\xe8\x03\xe4\xd0\x5e\x8d\x26\xf5\x0c\xfa\x12\xf0\x35\xd2\x54\xf9\xf3\x27\x36\xad\x46\x9c\x7a\xf6\xc4\xd0\x75\x1a\x65\xfc\xf3\x16\x70\x35\x12\x95\x99\xf3\xf3\x13\x00\x6b\x34\x2a\xf3\xe6\xe7\xfc\x54\x97\xde\x51\x8d\xf4\xe4\xc6\xec\xfa\x0e\x80\x35\xd2\x23\xb7\x65\x1b\x18\x93\xa3\xba\x04\x59\x59\xb5\x7f\x42\x5a\x8d\x34\xcb\x5b\xb2\x6b\xe8\x9e\xa3\x1a\x91\x56\x37\x64\x1b\xd8\x58\x1c\xd5\x48\xd6\xbc\x1d\xbb\xbe\x06\x7a\x8d\x8e\xf7\x37\x63\x3f\x91\x54\x23\x69\xb9\x65\xfa\x8c\xdd\x50\xa3\xe8\x6c\x23\x76\xf3\x19\x90\x35\x7a\xce\xb6\x61\xb7\x88\xac\x51\x32\xbd\x09\x7b\xc4\xbe\xaa\x51\x76\x75\x0b\xf6\x05\xaf\x58\x23\x5c\xd3\x06\xec\x3b\x76\x41\x8d\x98\xd5\xf6\x6b\x93\x3f\x74\xd1\x3b\xae\x5d\x74\x9e\x3b\x09\xe3\xe7\x70\x57\xe2\xb8\x46\x97\x19\xf2\x27\x22\x6b\x57\x5b\x23\x6f\x6a\x9d\xa7\x31\xe3\x21\xe2\x6b\xfa\x17\xd1\x77\x80\xee\xd7\xd6\x79\xe2\x25\x0e\xe3\x13\x04\xd7\x54\x5a\x41\x77\x08\xad\x5d\x2b\x7b\x17\x33\x2f\x89\x1d\xc6\x4f\x11\x5f\xb7\xea\x00\xf4\x77\x40\x0f\x6a\x37\x0d\xf9\x7d\xab\x31\xa2\x6b\xd2\x4c\x8e\x5d\x03\x76\x58\x1b\x79\x3a\xcb\x1f\xf8\x48\x17\x49\x1a\x05\x8c\x4f\x91\x57\x73\x8d\x0a\xeb\x53\xce\x3a\x52\x8f\x9f\xce\xc4\x28\x12\x67\xb8\x60\xf4\xe5\xdc\xe7\xfc\x0e\x90\x76\x15\x32\x12\x09\xe3\x23\x44\x74\xaa\x88\xa9\x37\x97\x0b\x96\x29\x62\xba\x55\x8c\xeb\xf8\x32\x8e\x8b\x98\x5e\x15\x23\xf5\x3d\x43\xc0\x51\x15\x70\xea\x9c\x32\x7e\x86\x88\xe3\x2a\xe2\xc2\x39\xf7\x02\xc6\x2f\x10\xd3\xa7\x2e\x93\x30\xfe\x11\x11\x83\x2a\x22\x91\x88\xe4\x33\x20\x86\x55\xc4\x79\xe8\x32\xfe\x1e\x63\x2c\xab\x08\xf5\x6b\xc2\x89\x33\x61\xfc\xe4\xbf\x80\x5b\x55\x71\x0a\x81\x91\xd6\x55\x84\xef\xcc\x85\xcb\xb8\x8f\x98\x8d\xe9\x6a\xf3\x6c\xb3\x8d\x57\xdb\x56\x71\x0a\x81\x91\x76\xa6\x48\x41\x2a\xf7\xe2\x10\x69\x4b\x28\x47\x21\x20\xd2\x96\x10\x4e\xec\xcc\xc5\xc9\x8c\xf1\x18\x41\x84\x76\xd4\x78\x09\x84\x10\xd2\x51\x35\xca\xf6\xf1\x58\x21\x42\x3d\x19\x00\xe3\x10\xea\x51\x71\x92\xd8\x71\x3d\xc6\x2f\x60\x74\xb7\x84\x8a\x00\xf3\x1e\x30\x84\x8a\x3e\x84\x13\xc6\x3f\xe0\xf5\x08\x15\x45\x22\x9e\x31\x1e\x21\x84\x90\x51\x3c\x93\xad\x8f\xaf\x00\x42\xe8\x28\x91\x9a\x4f\xf2\x20\xc7\xea\xce\xa0\x13\x39\x23\x99\x2f\xc2\xec\x36\xfc\x1f\x50\xa8\xee\xd9\xe4\x85\xb1\x98\x7b\xe3\x30\xfb\x41\xe9\x4f\x04\xec\x34\xc0\xfe\x91\xb4\x00\x52\x37\x3e\x72\x10\x2e\x12\xe7\x17\x0e\xe3\xb3\x97\x80\xe9\x54\x31\x32\x95\xc0\xc3\xa8\xae\xeb\xe0\xa9\x7a\x73\xe0\x74\xeb\x38\xd9\x15\x90\x33\x03\x4e\xaf\xca\x39\x73\xce\x08\xca\x0f\xa4\x1c\x35\x5f\x26\xbf\x6b\xbf\xbc\x02\xce\x71\x95\x73\x2e\x66\xc4\x65\x7e\xe2\x65\xfa\xf4\x65\x18\x5f\x62\x47\x0e\xaa\x90\x91\x98\x31\xbe\x42\xc4\xb0\x8a\x48\x84\xec\xc0\x68\x94\xca\x19\xee\xf1\x2b\x20\x97\x24\x92\xf1\x47\x8c\xb5\x22\x10\xb3\x0c\xf2\x05\x20\xeb\x2a\xe4\xbd\x90\x19\xe1\x13\x46\xd9\x50\x83\x3f\x63\xfc\x0a\x83\x6c\xab\x88\x93\x0c\xf2\x2f\x06\xd9\x55\x21\xae\xe3\x33\xbe\x01\x84\xba\x87\xb1\x5f\xd9\x0c\x02\xd7\xe9\x12\x32\x8c\x64\x73\xee\x31\x08\x21\xc2\x0b\x47\x1a\xea\x17\x42\x08\xcd\xc5\x42\xee\x85\x1f\x10\x42\x48\x2c\x9e\x29\xcc\x2d\x60\x08\x4d\xc5\x8e\xcb\xf8\x1a\xa3\x10\x0a\x72\x25\x62\xb3\x01\x04\x21\x98\x44\x76\xdb\xe3\x67\x40\x10\x7a\xb9\x90\x88\x5f\x20\xba\x2e\xa1\x97\xac\xc1\x5b\xac\x07\xa1\x93\xe9\x2c\xc3\x5c\x03\xa6\xa7\x77\x7e\xe2\x24\x67\x42\xce\xde\xbf\x63\x31\xd1\xf1\x13\xd9\xf1\x3b\x44\x10\x1d\xff\x41\x4e\x63\xff\x43\x04\xd1\xef\xd9\x44\xf7\x05\x11\x44\xb7\xfb\xce\x9c\xf1\x1b\x44\x10\x9d\x3e\xcf\xd4\xfa\x15\x21\x44\xaf\x07\x61\x76\xf4\x00\x42\x88\x6e\xcf\x5c\x71\x85\x08\xa2\xdb\xcf\x9c\x33\xc6\x7f\x20\x82\xea\x76\x99\x52\xe6\xce\x49\x9c\x46\x72\x93\x89\x50\xa2\xff\xcf\xe5\xe5\x7e\x22\x42\xf7\xe9\xc4\x49\x66\x4e\xe2\x04\x8c\xbf\xc5\x72\xdd\xa4\xae\x33\x9f\xab\xf2\xff\x60\xb9\xee\xd0\x13\x27\x8e\x54\xf9\xdf\x58\xbe\xdd\x8f\xcf\xf8\x1b\x2c\xdc\xed\x07\x67\xfc\x25\x14\x1e\x1d\xee\x47\x66\xbc\x8d\x85\xba\x2a\xe2\x99\xcc\xf0\x8c\x77\xb1\x54\x57\x44\x9c\x9e\xc8\xb5\xc1\x21\x14\xaa\xb7\x4a\xf5\x53\xe1\xc9\xb4\x19\x03\x9c\x48\x30\x0b\xd9\x85\xdf\x20\xe0\x92\xd0\xce\xa9\x44\x7c\x47\x04\x91\x81\xa6\x52\x7f\x9f\x76\x39\x42\x3d\xb3\x2e\x9c\x38\x11\x51\x90\x23\x0f\xb2\x73\xe8\x2d\xd7\x9b\x7a\x89\x75\x21\xa2\x90\xf1\xc3\x25\xe0\xdb\x0d\x78\x75\xd2\x3d\xc2\x3b\x0d\x70\x75\xc4\x3f\xc2\xbb\x4d\xf0\xfc\xc4\x7f\x24\xf4\x1a\x08\x93\x30\x8d\x18\xef\x21\xfe\xa8\x09\xef\xc9\xe9\xed\x08\xf1\xc7\x0d\xf8\xd8\xfb\xc8\xf8\x31\xc2\xfb\x4d\x70\x71\x2a\x33\x6a\x1f\x09\x83\x06\x82\xf0\xa6\xb3\x84\xf1\x01\x12\x86\x0d\x84\xc0\x93\x03\x30\x54\xf8\xf6\xb6\xf9\x30\xcb\xec\xd1\xf1\x7c\x25\x70\xe9\x1c\x1c\x5e\x02\xb3\xe1\xf5\x9e\x12\x6f\xa9\xf1\xcc\xef\xf5\x8c\x2a\x2f\xb1\x8e\x5e\x03\xcb\xf4\x66\x4f\x95\xb3\x42\x8e\xf9\xfd\x09\x8d\x05\x55\x1c\x1d\xbc\xc6\x2a\x9a\x5e\xa3\x20\x68\x2b\x8d\x66\x7e\xcf\x27\x27\xaa\xef\x07\x29\xe6\x08\x69\xa6\x97\x7d\x08\xd2\x0a\x49\xcd\x07\x5f\xaa\x03\x11\x4a\x2f\x23\x8c\xff\x78\x89\x01\x9a\x8e\xc0\x24\xe8\x6b\x8d\x6e\x7e\x73\xc4\xad\x8c\x88\x8b\x23\x62\x7a\x57\xa4\xca\xd9\x20\xc7\xfc\x76\x88\x5b\x1d\x0e\x57\x1b\x0e\xd3\x0b\x22\x04\x6d\xa3\xd1\x1a\x8f\xc6\xd4\x07\xc4\x45\x5a\xc3\xf9\x98\x3a\x69\x03\xa4\xe6\x43\x32\xf1\x58\x0b\xf7\x0f\xe0\x34\x9c\x92\x89\x8c\x0d\x32\xcc\x8e\x73\xf7\xdf\x9c\xd7\x3a\xf2\x1d\xd6\xd2\xe4\x3d\x33\x7b\xa3\xb1\x1b\x0f\xd0\x54\xaf\x63\x95\xde\x83\x14\x07\x2f\x90\xdf\x70\x9c\x26\xc1\xde\x6a\xec\xc6\xc3\x35\x35\x3e\xe8\x5c\x1c\xa0\xce\x9b\x8e\xd9\x24\xd8\x5b\x8d\xdd\x78\xe0\x26\xd1\x77\x42\xeb\xbb\x86\xd3\x37\x09\xf6\x56\x63\x37\x1e\xc5\x99\x1d\x05\xa2\x5d\xf8\x1f\xa4\x36\x9c\xc9\x59\x26\x6e\x35\xa2\xd9\xad\xa2\x9a\x58\xf2\xd7\x98\x2e\xc5\x1f\x2d\x0c\x60\x72\x6d\x0d\x7d\xab\xd1\xcd\xee\x9d\x54\x72\xcc\x04\x72\x8c\xf1\xd0\xce\x2a\x67\x07\x9c\xe6\x83\x3b\xe1\x35\xc3\xe9\x01\x50\x1a\x4e\xed\x04\xc2\x27\x24\x98\x9d\x3b\xab\xd4\x6c\x86\x35\x33\xf9\xb5\xca\xb9\x42\x4e\xe3\xb1\x9d\x7a\xba\x9c\x15\xe9\xb2\xe9\xe0\x4e\x9d\x76\xa5\xd1\x1a\x8f\xee\xd4\x1e\x6d\x9d\xbd\x05\x56\xc3\xe9\x9d\x1a\xe7\x0a\x39\x66\x0f\xce\xf6\x32\xe6\x0c\x32\xa6\xf1\x08\xcf\x7d\xc6\x15\x32\xcc\x5e\xcb\x39\x99\x58\xb5\x1e\x44\xc9\x1a\x0f\xf3\x24\x89\x57\x1a\xb1\xf1\x50\xcf\xb2\x4d\xbd\xc2\xa6\x4d\xa7\x7b\x96\x89\xd7\x1a\xb1\xf1\x98\x4f\xfa\x05\x7f\xef\x2d\x26\xc5\xa6\x63\x3f\xe9\x00\xd7\x45\x80\x9a\x63\x40\x4f\x4a\x8f\x1c\x9f\xbc\x04\x86\xc9\x78\x65\xfc\x17\xc4\x9b\x7d\x77\x52\x95\xf5\x49\x21\x6b\xe2\x50\x50\x23\xed\x8b\x46\x33\xbb\xef\xa4\xba\x7c\x38\x41\x9a\xc9\x7b\x04\xe9\x0b\x92\xcc\xce\xf3\xab\x95\xf4\xb5\x4a\x9a\xcc\x47\xd0\x6e\x34\x9a\xd9\x7f\xfb\xc4\xf2\xb9\x14\xfe\x81\x16\xc4\x64\xc8\xfa\x10\x37\x7a\x08\xb3\x43\xfd\x6a\x77\xf9\x48\x33\xb9\x93\x20\xdd\x20\xc9\xec\x4c\xdf\x38\x73\xfb\xc5\xcc\xdd\x35\xd9\xd3\xcc\xbe\xd1\xd8\x66\x8f\xce\x4b\x7a\x9f\xa3\xde\x4d\x96\x2c\xe3\xbf\x02\xbe\x67\x76\xe0\xbc\x32\xc7\xcc\x61\x8e\xe9\x99\x5c\x58\xe5\x7c\x45\x8e\xd9\x89\xf3\xaa\xec\xe6\xc5\x70\xf7\x4c\x4e\x24\x68\x5f\x35\x9a\xd9\x89\x41\xa5\x96\x01\xd6\xd2\x64\xc4\x2a\xe7\x16\x39\x66\x1f\x06\xd5\x2a\x06\x5a\x15\x4d\x3e\x24\x68\xb7\x1a\xcd\xec\xc3\xa0\x2a\xe5\x00\x69\xe6\x33\x49\x2b\xa4\x5b\x24\x99\xbd\x16\x18\x15\x1c\x14\x0a\x36\x9e\x4c\xfa\x3c\x76\xe3\x39\x12\x6a\x7a\x2b\xbd\xe4\xff\x0f\x4e\x2f\x4d\x47\x96\x56\xc9\x77\x1a\xb9\xf1\x84\x81\x82\xae\xad\x56\x2e\xc3\x7f\xde\x62\x88\x86\x43\x06\xe8\x00\x77\x45\x80\xe6\x03\x4e\x89\x3d\x53\x58\xec\x99\x9a\xce\x39\x25\xd8\x77\x1a\xbb\xf1\x5b\x70\xc4\x9e\x29\x2c\xf6\x4c\xc4\x21\xa8\x4d\xec\x3b\x8d\x6d\xf6\xef\xa2\x94\xcb\x16\x90\xcb\x8c\x47\xa3\x96\xf1\xdf\x10\x6f\xf6\xed\xa2\xe2\xf6\x05\xb8\xdd\x78\x38\x6a\x95\xf3\x0d\x39\x8d\xc7\xa3\x6a\xac\x08\x59\x0d\x47\xa4\x6a\x9c\x7b\xe4\x98\xfd\x1a\x55\x93\x4a\x54\x24\x15\xe3\x69\xa9\x04\xed\x5e\xa3\x99\x1d\xba\x4f\x2c\x4f\xe8\x91\x36\xa1\x1b\x8f\x50\xad\x0f\x71\xaf\x87\x30\xbb\x35\xaa\xa6\xb7\x08\x69\x26\x87\x12\xa4\x7b\x20\x35\x1f\xab\xaa\x8d\x4c\x0c\x23\xd3\x74\xb4\xaa\xc6\x79\x40\x8e\xd9\x81\x71\x75\x58\xe2\xa2\x3b\x8c\x67\xac\x12\xb4\x07\x8d\x66\xf6\x5c\x5c\x79\x27\xba\xa8\xef\x65\xfc\xb2\x08\x61\x32\x61\x6d\x80\x07\x2d\x80\xd9\x95\xfa\x21\xb4\xd5\x3a\xfc\x55\x84\x30\x59\xb4\x36\xc0\x83\x16\xc0\xec\xd7\xfd\x0e\xac\xd6\xe3\xb5\xd6\x9f\x26\x07\xff\xbf\x45\x31\x7b\x3a\xa9\x68\x27\x41\xed\x98\x0c\x5d\xe5\x3c\x22\xc7\xec\xe6\xa4\x2a\x9c\x44\xab\xa2\xc9\xc1\x04\xed\x51\xa3\xd5\x7c\x10\xb2\x6a\xc0\x04\x69\x26\xd7\x12\xa4\x47\x20\xd5\x1c\xf5\x9a\x18\xd7\x22\x49\xb1\x16\x31\x9e\xf8\x6a\x66\x3f\x6a\xec\xc6\x83\x5f\x8b\xcd\x32\xd0\xd3\x83\x03\x5c\x09\x34\x9d\x02\x5b\x65\x3f\xe9\x6c\xb3\xaf\x53\xea\x36\x41\x5a\xdc\x26\x30\x1e\x0b\x4b\x12\x9f\x34\xa2\xd9\xc7\x95\x0f\xcc\x69\x17\x2e\x7a\xcc\x64\x62\x33\xfb\x49\x63\x3f\xef\xb0\xe5\xf2\xd9\x87\xc5\xe2\xaf\xff\x9c\x93\x97\xcb\xe7\x1e\x6a\xe4\x67\x1e\xc3\x5c\x59\xf9\xa5\xda\x88\x3d\xeb\x5c\xe6\x4a\x84\x27\x2d\x82\xd9\xcb\xa7\x5a\x23\x18\x3f\xfd\x07\x18\x26\x13\x97\xf1\xdf\x11\x6f\x76\xef\x69\xd5\xf6\xa7\x85\xed\xfb\x26\xff\x12\xb4\xef\x05\x6d\x60\x76\x70\xfe\x80\x54\xbe\x88\x3d\x7b\x01\x0c\x93\x67\xcb\xf8\x1f\x88\x37\xbb\xf4\xac\xb4\x86\x3c\x83\x35\xe4\xc0\xe4\xcb\x32\xfe\x07\xe2\x1b\x0f\x67\xd6\x86\xf3\x0c\xee\x7c\x0e\x1a\xce\x66\xd6\x38\x3f\x90\x63\xf6\xdf\x59\x65\x06\x38\x83\x19\x60\x60\x72\x5d\x95\xf3\x03\x39\x66\xaf\x9d\x55\x07\xf4\x4c\x1b\x50\x93\xcb\x08\xda\x0f\x8d\x66\xf6\xd7\xc7\x4a\x2d\x3f\x62\x2d\x4d\x8e\xaa\x72\xfe\x45\x8e\xd9\x43\x1f\x2b\x3d\xff\x11\x7b\xde\xe4\xa3\x2a\xe7\x5f\xe4\x98\xbd\x74\x5e\xa9\xdf\x39\xd6\xaf\xe9\xa3\x97\x05\xe7\x27\x70\x86\x66\x17\x5d\xec\x67\x56\xc6\x2f\xde\x01\xcd\x64\x25\x82\xf4\x0b\x49\x66\x3f\x5d\x54\x87\xf8\xa2\x18\xe2\xa1\xc9\x56\x04\xed\x97\x46\x33\xbb\xeb\xa2\xba\x34\xb8\x40\x9a\xc9\x5e\x04\xe9\x17\x92\x4c\x67\xf4\xce\xaa\xa4\x2b\x24\x35\x7c\x34\x40\x93\xc6\x23\x48\x63\x68\x3a\x87\x37\x77\x89\x7e\x22\xe0\x8f\x43\x20\x99\xac\x75\x5e\x25\xfd\x04\x52\xcd\xe9\xdf\x4e\xb5\xdf\x9d\xa2\xdf\x8d\xa7\x80\x13\xb4\xa5\x46\x6b\xfc\x36\xea\x2c\x0c\x4f\xa0\x9a\x4e\x07\x68\x0d\x1f\x48\xd5\x49\x4b\x24\x35\x7e\x25\x55\x5b\x50\x94\x0e\xc8\x7c\x87\x13\xfb\xb2\xe1\xb3\xa9\x86\x08\x4b\x2d\x82\x39\x29\xd3\x31\xe0\xb6\x8c\xf3\x0e\x6f\xcb\x2c\x4d\x1a\xaa\x8f\xb0\xd4\x22\x98\x13\x36\x1d\x43\xef\xd1\x4b\xe7\x5d\x07\x03\x99\x54\xf6\x8c\x30\x4b\x2d\x4c\xe3\xe1\xa5\x7b\x81\xf2\x95\xc8\xa5\xf3\x0e\x97\x9b\xcb\x86\xc3\x4b\x0d\x11\x96\x5a\x84\x9a\xc3\x4b\xc9\x18\x25\x33\xbc\xd3\x64\x6d\x3c\xcf\xb4\x31\xcc\x52\x0f\xd3\x78\x6c\xb4\xfa\x3d\xb1\x24\xd6\x56\x21\xb5\x86\x43\xa3\xab\xe4\x65\x41\x5e\x35\x66\x82\x82\x8e\x12\x6d\xa1\xc0\x56\x0d\xf9\xa0\x4a\x5e\x6a\xe4\xe7\x7d\x31\x99\x10\x66\x0b\x15\xb5\x7a\xce\x37\x94\x09\x4d\x6a\x11\x1a\xf3\x45\x11\x03\xe5\xd8\x42\x31\xad\x1a\x52\x45\x95\xbc\xd4\xc8\x8d\x59\xa2\xa0\x97\x44\xd8\x2a\xd4\xb3\x6a\xc8\x12\x74\x84\xa5\x1e\xa1\xf1\x91\x17\x9d\x29\x34\x62\xc3\xb3\x2e\x3a\x6d\xab\xd1\x1a\x1f\x72\xd1\xc7\x4a\x40\x62\x5f\x35\x3c\xe0\xa2\x93\xb6\x48\x6a\x7c\xb8\x25\x1f\x16\x01\x9b\x9d\x55\xc3\xd3\x2c\x39\x7e\x8b\xf8\x9a\x83\xa8\x6b\x67\x0b\x51\xcc\x16\x2b\xe3\xc1\xd4\xb5\x11\xb6\x45\x84\xb5\xd9\xc7\x74\x0c\x7c\x6c\xab\x98\x2d\xd6\x26\x33\xd7\x47\xd8\x6a\x11\x1a\xbf\xee\x5c\x37\x51\x88\x62\xa2\x58\x37\x7c\xf3\xb9\x2e\xcc\x56\x0b\xd3\xf8\x20\x9b\x61\xb6\x10\xc5\x6c\xb1\x6e\x78\x98\xcd\x10\x61\xab\x45\x68\x7c\xa0\xad\x66\xa2\x10\xda\x44\xb1\x6e\x78\xb2\xad\x26\xcc\x56\x0f\xd3\xf8\x7d\x5c\xbd\x3f\x3d\xb0\xd2\xba\xe1\x23\xb9\x3a\xe9\x1a\x49\x8d\x5f\xca\xd5\x6b\xe9\x69\x95\x6c\xf8\x5e\xae\x4e\xbb\xd6\x68\x8d\x3f\x24\xea\xc4\x50\x23\x36\xfc\x84\xa8\xd3\xee\x34\x5a\xe3\x8f\x87\x7a\xb7\x84\xd8\x2d\x0d\x3f\x18\xea\xa4\x3b\x20\x6d\x1a\x7f\x24\x34\xe4\x89\xb0\xc8\x13\x9b\x86\x1f\x0a\x0d\x11\xee\xb4\x08\x8d\x3f\x16\x1a\xf2\x44\x58\xe4\x89\x4d\xc3\x0f\x86\x86\x08\x77\x5a\x04\xb3\xb3\xe9\x18\xa5\x14\x11\x16\x29\x62\x63\xb2\xf7\x33\xc2\xdc\x69\x61\xcc\x1e\xa7\x03\x41\x9e\x08\x8b\x3c\xb1\x31\xd9\xbb\x3e\xc2\x9d\x16\xc1\xec\x6c\x3a\x46\xc9\x0c\x5a\x8a\xd8\x98\xbc\xde\x1c\xe6\x4e\x0f\xd3\xf8\x09\x8a\x59\x18\xed\xfd\xac\x3c\x2c\x94\xd6\xf0\x35\x8a\x0a\xf7\x4e\xe3\x36\xe6\x01\x64\xa3\x3e\x87\x85\xba\x1a\x92\x41\x85\x7b\xa7\x71\x9f\x91\x11\x72\x76\x59\x93\xc3\x42\x4c\x8d\xd9\x81\x0a\x70\x57\x04\xa8\xf9\x10\xcc\x7e\x08\xd4\xe1\x10\x55\x64\xfc\x0a\x8c\x89\x7b\xa7\x71\x1b\xb3\x03\xb2\x4b\xda\x1b\x16\xa2\x31\x7e\x11\xa6\x2e\xc0\x9d\x1e\xa0\xf1\x47\x10\x9d\x99\x6a\xc4\x86\x9f\x40\x74\xda\x93\x46\x6b\xfc\x01\x44\x1f\xa7\x14\xd2\xb9\xf1\x8b\x31\x04\xe9\x09\x49\x8d\x3f\x77\x54\x5c\x91\x16\xae\x30\x7e\x42\xc6\xc4\x7d\xd2\xb8\x8d\x3f\x76\x54\x5c\x91\x16\xae\x30\x7e\x59\xc6\xc4\x7d\xd2\xb8\x8d\x5f\xa2\xa4\x0d\x91\x6a\x86\x68\xf8\x34\x25\x1d\xe0\x49\x0b\xd0\xf8\xad\xca\x8a\x2b\x52\xcd\x15\x0d\x9f\xac\xac\x70\x9f\x0a\xee\xae\xf1\xcb\x95\xa4\x21\x52\xcd\x10\xbb\x86\x6f\x58\x92\x01\x9e\xf4\x00\x66\x57\x9f\x97\x7e\x60\x39\x87\x1f\x58\x76\x26\x13\x97\xf1\x3f\x11\x6f\xf6\xec\x79\xd5\x7c\xe7\x5a\xd5\x4c\x9e\x25\x68\x3f\x35\x5a\xe3\xf7\x2c\x75\x25\x9c\x83\xfd\x76\x0d\xdf\xb3\xd4\x49\x3f\x91\xd4\xf8\x3d\xcb\x7c\xd8\xcf\x61\x4f\xb9\x6b\xb8\xa9\x9b\xe3\x7f\xe6\xf8\xdd\xa1\x76\xa2\xb0\xeb\xc4\x9e\xf6\x0e\x18\x7e\x08\xe6\xcf\x97\x00\xd6\xce\x14\x5e\xc4\x9e\xef\x11\xe0\x3f\x10\xdc\xa1\x22\x9f\x3a\x91\xe7\x30\xfe\xe7\x0b\x40\x75\xa9\x90\x39\xea\x0f\x44\xf5\xa8\x58\x0b\x11\x79\xf1\x22\x9c\x8b\xc0\x63\xfc\x9f\x3f\x01\x7b\x44\x45\x2c\x63\xff\x00\xac\x76\x98\x78\xf9\x49\xf4\xbc\x06\x2f\xde\x02\xb2\x6f\x42\x96\x23\x2b\x7c\xe7\x50\xb5\x5e\x04\x56\xbc\x70\xc6\x82\xf1\x76\x00\x05\xea\xad\xd6\x39\x16\xcc\xa1\x20\x6b\x63\xf6\x4e\xeb\xc1\x42\x44\x07\x05\xa4\x8b\x90\xac\x69\x93\x30\x8d\xf6\x10\x3d\x44\x64\x0d\x8a\xbd\x8f\x7b\x80\x63\x04\x0c\xd5\x55\xbc\xa2\x66\x09\x14\xa9\x83\x36\x1c\x2f\xc2\xa2\x59\x5e\xa4\x5e\x5d\x9b\x9d\x2f\x66\x22\x60\xfc\xa0\x0d\x7f\xee\xe6\x8d\x74\x9d\x78\xc6\xf8\x01\xb4\x51\xbd\x05\x26\xe6\xf0\x77\xb8\xb8\x7a\xbb\x6b\x16\x46\xde\x45\x18\x48\x2d\x8f\x9c\x88\xf1\x83\x2e\x14\x67\x95\xcf\xbf\x45\x74\x2a\xa2\xc4\x1b\x4b\xbd\x67\xef\xb0\xbe\xe8\x00\xa8\xaf\x81\xfc\xf0\x2c\x2f\xff\x1b\xcb\x95\x65\x44\x76\xca\x5a\x30\xf5\x85\xf5\x21\x0d\x13\x47\x3b\xd4\xe3\xe5\x31\x40\xb3\xbe\x88\xbc\xe9\xcc\x8c\x1d\x02\x76\xa9\x3a\x36\x43\xf9\xe1\xd9\xc1\xb0\x82\x7d\x8d\xd8\x95\x86\x9d\x79\xd3\xd9\x41\x24\x4e\x45\x14\x0b\x97\x60\x0d\x5f\x02\x6b\x8d\x15\xcf\x5b\xb7\x0f\xfd\x0f\x56\x7c\x53\x54\xdc\x84\xc5\xca\x6c\xcb\xfd\x45\x54\xe1\x2d\x62\x77\x1a\xb6\xb1\xe2\xff\xc9\x59\xea\xdd\x28\xd7\x99\x4e\x45\xc4\xf8\x9b\x03\xf8\x73\x5b\x0b\x86\xa5\x7f\x43\x69\x26\x85\xe4\x2c\xcc\xd2\xac\x2f\x1c\x57\x16\xbf\x7e\x9d\x17\xab\xb7\x3e\x16\x22\xb2\xe6\x9e\xef\x0b\x38\x30\xef\x10\x8a\x33\x77\x2d\x22\x6f\x2e\x55\x0a\x3d\xa8\xde\xc7\xc8\xaf\x98\x17\x76\xb0\x50\xd9\x2b\xf2\x16\x45\x61\x17\x0b\xb3\xda\x40\x63\x31\x30\xb4\x50\xbd\x45\x81\xc5\x7b\x57\x40\x54\xbf\x84\xda\xbb\x14\xa2\xd4\xc9\x6f\x4e\x24\x12\xc6\xc7\x4b\xf8\xeb\x50\x97\x97\x98\x24\x07\x8b\xd0\x0b\x92\xec\x17\x38\x52\x98\x7f\x81\x07\xbb\xba\x30\x33\x49\x34\x51\xdf\x21\x75\xa5\x2a\x3c\x11\x91\x08\xc6\x02\xd4\xf0\x11\x8a\xd7\x5a\x77\x8a\x8f\x63\xdf\x99\xeb\x61\x2e\x5f\xfc\x96\xaf\x71\x3a\x87\xea\x25\x84\xf0\x54\x44\xca\x8d\x2f\x41\x04\xea\x09\xfb\x49\xe4\x8c\x33\x66\xec\x67\x09\xe1\xcd\x2e\x2f\xae\x9e\x82\x50\x3a\x67\x20\x06\x58\x8f\x86\xe5\xef\xf3\x23\xec\xc8\x00\x53\xaf\xf1\x23\xec\x98\x86\xa9\xb7\xf7\x11\xd5\x37\xa0\xf2\x97\xf6\x11\x37\xa0\x71\xf0\xae\x3e\xe2\x86\x34\x2e\x7f\x45\x1f\x61\xcb\x7d\xd8\xc2\x4f\xe3\x5c\xff\xbf\x23\x6a\xb5\x8f\x9a\x7b\x41\x1a\x33\x7e\x80\x88\xf5\x3e\x42\x7c\x48\x1d\x1f\x22\xfd\x8d\xb8\xcd\x3e\x2e\xcb\x40\x0b\x27\x12\x41\x32\x53\x3f\x33\xb7\x10\xbc\xdd\x07\xab\x1c\x54\x42\xbf\x42\xf4\xae\x12\xba\xba\x2c\x09\x18\xbf\x05\xc2\x20\x57\xc3\x88\xd2\xc2\x03\x80\xda\x14\x48\x1d\x34\x81\x98\x0e\x85\x51\xa7\x4b\x20\xa6\x4b\x62\xf2\x23\x25\x10\xd5\xa3\x50\xb9\xee\x10\x74\x44\x82\x94\xea\x10\x74\x4c\x81\x94\xe6\x10\xd3\x27\x31\xb9\xe2\x10\x35\xa0\x50\xa0\x37\x44\x0d\x29\x54\xae\x36\x04\x2d\xcb\x20\x5d\x6b\x88\x59\x95\x31\xa0\x34\x2c\x5f\x97\xcb\xcb\x3a\x43\xd4\xa6\x8c\x22\x54\x86\xd0\x6d\x19\x4a\x69\x0c\xb0\xf9\x4f\xf6\x5e\xe4\xe4\x17\xf4\xaf\xa1\xa4\xaf\x66\x90\x58\x24\x50\xb6\x78\x84\xb2\xac\x6f\xce\x64\x42\xca\x0a\xce\xf2\x59\xa9\xad\x16\x67\xae\x90\xeb\x3c\x4b\xae\x67\xbd\x69\xe4\xc8\xf5\xf2\xdd\x18\x10\x47\x90\xbe\xad\x70\xc2\xf8\xfa\x0e\xfe\x3e\xd4\x98\x13\x67\x16\x89\x60\x26\xbc\x84\xf1\xbb\x49\x8e\x50\xab\x9b\xec\xd3\x26\x61\x7e\xdd\xe0\x10\xca\xd4\xc0\x87\x69\xe0\x5a\x91\x18\x87\x91\x2b\xd3\xf7\x38\x5c\x9c\x47\x6a\x58\x17\x21\x20\xb7\x6a\xe6\x13\xaa\x73\x64\x52\x4d\x9c\x13\xc1\x78\xf4\x6f\x8e\x50\xd3\x71\x2c\xa2\x53\x0f\x73\x7a\x3c\x87\xc2\x8e\x9a\x05\x1d\x57\x15\xe5\x15\x49\xb0\x3c\xab\x64\x38\x9b\xe7\x05\xe1\x57\x28\x50\x27\xf4\x04\xd3\x38\x89\x42\x01\xc5\x0e\x54\x4b\xbd\xc7\x71\x9a\xfa\x53\x27\x2a\xd2\x7d\x18\x08\xb9\xd4\x8c\x5c\xc6\xdb\x5d\x40\xf6\x28\xa4\x5c\x08\x64\xc8\x98\xf1\x0e\x42\x8f\x4c\x41\x27\xde\x24\x99\x31\xde\x3e\x02\xe4\xb1\x29\x68\x86\x94\x41\x11\xda\x27\xa1\xb3\x6c\xdc\x72\x70\x17\xc1\x03\x0a\x2c\xed\x8f\xd8\x1e\x62\x87\xa6\xda\xc6\xde\xc7\xac\xb6\xc7\x80\x5c\x92\x51\xbd\xd3\x1c\x1a\x33\x7e\x84\xd8\x95\x29\x6a\x66\x78\x19\x76\x00\xd0\xb5\xb9\x65\x0a\x2c\x9b\x86\xe8\x8d\xb1\x12\x08\x3e\x42\xf0\x96\x02\x67\x89\xa9\x40\xf7\x01\xad\x5e\x7e\x88\xc2\xb9\x13\xe0\xa7\x7c\x54\x82\x8e\x00\xd1\xae\x22\x54\x7a\x46\x44\x87\x40\xe4\xc9\x19\x31\xdd\x2a\x26\x4f\xcd\x08\xe9\x11\x10\x95\x98\x11\x72\x54\x85\xa8\xb4\x8c\x88\x63\x02\x91\x27\x65\xc4\xf4\xab\x18\x48\xc9\x88\x19\x54\x31\x79\x42\x46\xc8\x90\x68\xb6\xbc\xd0\x12\x11\x4b\xe2\x42\xbe\xaa\xcd\x0a\x41\x2b\xaa\x7f\x85\x2f\x1b\xbe\x46\xd0\x9a\xea\x9b\x49\x72\xce\xf8\xe5\xd1\x61\xfe\xfe\x4b\xa7\xad\x9e\xdb\xaf\x8c\xa6\x35\x4b\x03\x37\x12\x2e\xe3\x97\xed\x43\x0d\xbd\xa5\x3b\x5c\x83\x1f\xe9\xf0\x1d\x1d\x3c\x99\x85\x69\xec\x04\x79\xf4\x02\x9f\x2f\x18\xb3\x15\x04\x25\xb0\x7b\xc0\xb5\x4d\x38\x25\x33\xc4\x75\x8c\xb8\x5c\x6c\x88\xec\x9a\x90\xb9\xe4\x10\xd8\x33\x02\x95\xf0\x10\x78\x64\x02\x2a\xf9\x21\xee\xd8\x88\xcb\x45\x88\xc8\xbe\x09\x09\x52\x44\xe4\xc0\x84\xcc\x05\x89\xc0\xa1\xb1\x83\x32\x59\x22\x6e\x69\xbc\x34\x88\x13\xa1\x2b\xf3\xd8\xe4\x12\x45\xe8\xda\xdc\x97\x20\xd4\x7b\xd4\xc6\xa6\x46\x1b\x65\xb9\x16\x9c\x6d\xdd\x60\x95\x45\x5b\x90\x76\x75\x17\xda\x93\x2e\xb2\x06\x74\x56\x44\xbc\x35\xb6\x50\xee\x63\x17\x59\x44\xa6\xcc\xaa\xa6\x5d\xe6\x48\x77\xc8\x80\x4a\x9c\x22\xd8\xaf\x56\x41\xc8\x1f\xf6\x15\x93\xe4\xcc\x89\xdc\xd8\x72\xa2\x28\x3c\x63\xfc\xaf\x03\x28\xcf\x6a\x90\x2e\x4a\xa5\x07\x2f\xa0\xb4\x83\xb7\x22\xca\x80\x77\x00\xc8\x37\xe5\x67\x41\xb9\xfc\x3b\x94\xf7\xf0\xb6\x87\x5a\xe8\xc1\xf5\x31\xc0\x91\xba\x7e\x16\x03\x4a\x53\x17\x4a\xd5\xaa\x2a\x8c\x92\x99\x75\x26\x62\xa4\x5f\xfe\xf5\xe2\x05\xb6\xb0\x5f\x60\x84\xa3\x61\xde\xbc\x79\x87\x98\x41\xbe\x02\xdb\xc7\xbc\x78\x51\x60\x86\x05\xa6\x7c\xad\x37\x6f\x00\xb3\xd9\xeb\x4d\xf8\xb2\x76\xde\x28\x58\x68\x6e\xf6\xbb\xad\x8c\xfb\x1b\x1a\xbf\xd9\xef\x9d\x3d\x5c\x1e\xaf\xa3\x6e\xe3\x4e\xc2\xc8\x72\x7c\x9f\xf1\x89\x03\x7f\x57\x37\x4a\x9c\x28\xf1\x1c\xdf\x72\xbd\x49\xb6\xd7\x97\xff\x83\xf1\xcd\x02\x40\xd9\x10\x25\x33\x11\xc9\x7d\xbe\x17\x27\x31\xe3\x89\x80\x42\x75\x48\xde\x7c\x91\x9c\x5b\xb1\x48\x18\x7f\x73\x08\x25\x59\xd7\x7b\xc1\x38\x12\xf3\xec\xd6\xaf\x8b\x1c\xd5\xe1\xce\xc8\x77\x18\x0f\x46\xf0\x57\x75\xbc\x9d\x9f\xa1\xb3\xd5\x73\xeb\x00\x8a\xd4\x89\xe9\x61\x90\x38\x5e\x10\x5b\x4e\x6c\xcd\xc5\x7c\x24\x22\xc6\x0f\x5e\x01\x24\x33\x5d\x70\xe0\x44\xe7\xd6\x22\x0a\xdd\x74\x9c\x30\xfe\x1b\x34\x41\x9d\x93\xa5\x4a\xe3\x74\xae\x6e\x54\x30\xfe\xfb\x05\x94\x67\xfd\x90\x6d\x5d\xf2\xa5\xeb\x41\x07\x8a\xba\x58\x74\x10\x46\x07\xda\x16\xe8\xe0\x77\x80\xa8\xf3\x32\xe3\x44\x44\x5e\x7c\x62\x85\x0b\x11\x39\x49\x18\x31\xfe\x1b\x34\x40\xdd\x75\xcc\x9e\x98\x2e\x4a\xc3\x15\x94\x66\xc2\x19\xa5\xbe\x2f\x12\xad\x3c\xc6\x72\x95\x3c\x3f\xa4\x72\x5b\x11\x85\x61\xc2\x78\x94\x40\xd9\x46\x2d\xf8\xc3\x45\x18\xc9\x46\x49\x3b\xcb\xfd\x70\x0b\xca\xb7\x6a\x14\x26\x5e\xe0\xc9\x8c\x78\x08\xc3\xa3\x6e\xe6\xe5\x9e\x0a\xa6\xbe\x60\xfc\xc0\xcf\xcb\xd4\x1e\x01\xfe\x7a\x0a\x7f\x3d\xca\xc5\xe2\xf8\xbe\x50\x97\x59\x40\x07\xe7\x87\xf1\x84\xd3\xec\x9e\x6c\x96\x47\x9c\x00\xca\x06\x7a\x59\xd6\xf2\x08\x8a\x86\xaa\x76\x89\x88\x62\x31\x56\x83\xd2\x4a\xa1\x30\x6b\x76\x1a\x64\x7f\x7d\x85\x7f\x5d\x01\x65\x1a\x49\x99\x7a\xb7\x50\xa0\xdf\x8f\x2a\xca\x5d\x0f\xca\xb7\x20\x22\xb9\x3e\xd7\x02\xe4\x7b\xb4\x4e\x7e\x0b\x50\xea\x7c\x12\x46\x82\xf1\xd7\x6f\xa1\x24\x6b\xf9\x48\x8c\x9d\x34\x16\x8c\xbf\x7d\x0d\x7f\x57\x2b\x3f\xa9\x26\xc6\xdf\x42\xa3\xd4\x8d\xbe\x62\x48\x18\x7f\x8b\x81\xb2\x3a\xaa\x57\xbf\x8a\x81\xfe\xa7\x0d\xc5\xf9\x60\x9d\x8a\x28\x11\xae\xe5\x3b\x17\xe7\x56\xcc\xf8\x78\x9a\x97\xe7\x47\xc4\xc6\xe7\xf3\x45\x12\x66\xb7\xbf\xfd\x73\xb5\xa1\xce\x46\xe3\x1f\x90\x5b\x7e\x0c\xec\x62\x11\x85\x1f\xbd\xb9\x93\x88\x32\x0c\xb2\x42\x7e\x8a\xab\x3f\x0f\xe3\x44\x2f\x07\xe9\xe7\xc7\xaa\xfa\xbe\x56\xf8\xf7\x3f\x79\xa1\xda\xd2\x79\x73\x67\x2a\xb7\xba\x96\x4c\x2d\x86\xeb\xcd\x60\x04\xd4\xc2\x3f\x08\xf5\x8b\xbd\x80\xca\xa8\x35\xbf\xe7\xca\xf4\x33\x86\x8b\x75\xa1\x30\xcf\x73\x71\x7c\x90\xcc\x9c\x40\x5e\x4d\xab\xd2\x5f\x80\x82\x9f\x76\x9c\x44\x44\x04\xf0\x1d\x5e\x2b\x53\xd6\x3c\x1d\xcf\x8a\x98\x8c\xff\xf5\x1b\x14\xaf\xb0\x58\x0f\xc6\xf8\x6f\xef\x00\xb1\x85\x96\x68\xfc\x17\x58\x8f\x1d\x94\x96\xe9\x2f\x80\x5e\xdc\x80\x12\x79\xa6\x1b\x43\x49\x7e\xdb\x69\x21\x0d\xa1\xca\x5e\x61\xd9\x71\x89\x55\x6e\x5b\x7e\x10\x54\xa7\x33\xe8\xef\x45\x28\xe3\x5e\x01\x4e\xcd\x56\x63\x2f\x1a\xfb\x42\xfd\x3e\x5b\x08\xf2\x10\x04\xae\x3e\x4e\x0f\xa0\xbd\xfc\x75\x08\x3a\x59\xc2\x14\x9c\x38\xe3\x13\xc6\x0f\x20\x37\xa9\x07\x1c\xcb\xa1\x5f\x43\xc6\x50\xbf\x7b\xe3\xcf\x38\xc2\xf7\xbd\x45\x76\xf3\xe6\x2d\x0c\xba\xfa\x6d\x7b\xee\xb9\xd9\x7b\x30\xda\xcf\x42\x05\xf6\x75\x8e\xed\xaa\x89\x4c\xae\x61\x04\xe3\xe2\x0a\xfe\x5a\xfc\xd8\x33\x16\x9e\xef\x05\x53\xc6\xff\xea\x43\xa1\xf6\xf3\x0e\x96\xbe\xc3\xd2\x25\x52\x27\x7e\x28\x6b\xde\xff\x0b\x8a\x56\x05\x11\xca\xf2\x91\xed\xaa\x5f\xc2\xf0\x26\xbf\xd4\x40\x7e\x2f\xc7\x03\x44\x7e\xec\xef\x98\xf1\x96\x03\x7f\x53\xbf\x76\x08\x5f\x2c\x66\x72\xcd\xa7\xee\xf1\xc8\xf9\x2d\xc9\x93\x4a\x57\xa5\xe4\x24\x5c\x58\x33\xc7\x9f\xe8\xe9\xeb\x09\x10\x99\x81\x46\x61\x92\x84\xf3\x0a\xe8\x06\x40\x43\x68\xd6\xfe\xcf\x00\xa3\xc8\x19\x9f\xc8\x09\xfc\xaf\x37\x80\x5d\x62\x3b\x8d\xe0\x37\x79\xc3\xf3\x8f\xf4\x85\x0b\x11\x58\xa3\xf0\x23\xe3\xa7\xf9\x2d\xb8\xfc\x33\x57\xe1\x38\xca\x7e\xc2\x66\xbc\x7d\x05\x05\x6d\x28\x18\xcf\x1c\x2f\x62\xbc\x8b\x25\x1d\x28\x99\x84\xd1\x09\xe3\x1d\x2c\xe8\x42\x01\xe6\x48\x85\xe8\x21\xe2\x18\x10\xa3\xc8\x09\xc6\x33\x6b\xe4\x04\x27\x79\x56\x99\x78\xe3\x7c\xde\x6f\x7f\x06\x78\x1f\xe0\xce\x3c\x4c\xb3\x65\x87\x35\x9e\x09\xa9\xe2\x0e\x62\x06\x80\x51\x3f\x57\x76\xb1\x60\x88\x0d\x48\xe3\x24\x9c\x8b\xc8\x72\xc6\xe3\x2c\x4c\x90\xaa\xe5\x49\x0f\xb0\x2a\xf5\xa1\xdb\x8a\x9b\xd2\x97\xed\x83\xbb\x4b\x00\xb5\xab\xa0\x6c\x3f\x7a\xd9\xd1\x40\x1d\x02\xa4\x36\xa3\x97\x5d\x0d\xd6\xad\xc2\xd4\x4e\xf4\xb2\xa7\xa1\x7a\x04\x2a\xdb\x86\x5e\x1e\x69\xa8\xa3\x2a\x2a\xdb\x83\x5e\x1e\x6b\xa0\x63\x02\xa4\xb6\x76\x97\x7d\x0d\xd6\xaf\xc2\xf2\xdd\xe7\xe5\x40\x83\x0d\xaa\x30\xb5\xf5\xbc\x1c\x6a\xa8\x52\x0e\x53\x9d\xae\x36\x9e\x97\xed\x43\x0d\xb6\x24\x60\xb0\xef\xbc\x6c\xeb\x23\xb0\xa2\x02\xe6\xdb\xce\xcb\xb6\x3e\x0c\x6b\x0a\x39\xf3\xa2\x44\xa8\xa8\xfa\x58\x6c\x08\xac\x1c\x0c\xc0\xea\x23\xb2\xa5\xb0\xde\x04\xa0\xfa\xb0\xec\x08\x68\xec\x7d\x04\xa8\x36\x38\xfd\x43\x0a\x2a\x3b\x00\xc0\xda\x10\xf5\xdb\x54\x77\xc9\x31\xca\xb1\xda\x38\xf5\x3b\x04\x56\x0e\x14\x60\xb5\xd1\xea\x77\xe9\xce\x0d\xb2\x9d\x7a\x47\x1b\x30\x75\x8f\xa4\xb8\xa5\x7f\xb1\xe7\x99\x56\xfb\x15\x42\x8f\x4c\x50\xe5\x9c\x56\xa7\x80\x1e\x1b\xa1\xb9\x7f\x5a\xdd\x02\xdc\x37\x81\x73\x17\xb5\x7a\x05\x76\x60\xc4\x2a\x2f\xb5\x8e\x0a\xec\xd0\x84\x55\x8e\x6a\x1d\x17\xd0\xa5\x11\x9a\x4b\xb7\xd5\x2f\xc0\x2b\x13\x18\xdc\xd5\x1a\x14\xe0\xb5\x09\x9c\x7b\xac\x35\x2c\xb0\x9b\x2a\xb6\xe4\xb4\x56\xfb\xb0\x00\x6f\x8d\x60\xf4\x5b\xab\xad\x8d\xde\xce\x1c\x1c\x5c\xd7\x6a\x17\x43\xa8\x6e\x92\xd0\xf8\xc2\x7b\xad\x76\x31\x8e\xea\x06\x09\xc9\xd0\x1c\xd8\x6a\x17\xa3\x39\xe8\x98\x19\xe8\xc3\x56\xbb\x18\x52\xb5\x66\x23\x09\x85\x1b\x5b\xed\x62\x60\x07\x84\xbc\x09\x4f\xb6\xda\xc5\xf0\x0e\x08\x99\x57\x9d\xd9\x6a\x17\x63\x3c\x20\xd4\x5e\xf5\x67\xab\x5d\x8c\xf4\x80\x90\xfc\xbe\x4b\x5b\x9d\x62\xb0\xd5\x0f\x8d\xe8\x4b\x6b\x92\xfa\xbe\x15\x27\xe1\x82\xf1\xf6\x6b\xc0\x0c\x0b\x4c\xf6\x7b\x4b\x81\xe9\x20\x66\xa9\x61\xd4\x0f\x2d\x05\xaa\x8b\xa8\x55\x81\x52\xbf\xb0\x14\xa0\x1e\x82\xd6\x1a\xc8\x3b\x2d\x45\x3a\x42\xd0\xa6\x00\xc5\xde\x47\x1d\x73\x8c\x98\xad\x86\xc9\x7e\xc7\xd0\x50\x7d\x44\xed\x0a\x94\x50\xeb\xc1\x02\x35\x00\x94\xba\x83\x56\xf8\x4b\x07\x0d\x11\xa4\xee\x50\xa0\xb1\x74\xd0\x65\xfb\xf0\x35\x74\xba\xba\xa1\x56\xf2\x54\x19\xda\x2e\xa0\x5d\x3d\x64\x66\xa7\x32\xb4\x53\x40\x7b\x3a\x34\x77\x52\x19\xdc\x2d\xc0\x47\x1a\x18\x4c\x54\x06\xf7\x0a\xf0\xb1\x0e\x56\xfe\x29\x63\x8f\x0a\x6c\x5f\xc3\xe6\xd6\x29\x63\x8f\x0b\xec\x40\xc7\x82\x6b\xca\xe8\x7e\x81\x1e\xea\xbd\x96\x1b\xa6\x0c\x1e\x14\xe0\xa5\x06\x06\xaf\x94\xc1\xc3\x02\xbc\x2a\x77\x72\x90\x9c\x97\xa0\x1d\x6d\xe8\x88\xac\x4b\xbd\x5d\x29\x6d\xb6\x44\x97\x0d\x89\xfc\x4b\xb0\x46\x92\xb5\x2a\x58\x44\x22\x26\x58\x63\xc9\x5a\x17\x2c\x22\x1d\x13\x2c\x57\xb2\x36\xc8\x5a\x12\x49\x99\x7a\x95\x4c\xb2\xb6\x05\x8b\x48\xcc\x04\x6b\x22\x59\xbb\x82\x45\x24\x67\x82\x35\x95\xac\x4f\x05\x8b\xc8\xd0\xd4\xb1\x0b\x92\x75\x55\xb0\x88\x34\x4d\xbd\x36\x26\x59\xd7\x05\x8b\xc8\xd4\x04\xeb\xbd\x64\x7d\x2e\x58\x44\xb6\x26\x58\x27\x92\xf5\xa5\x60\x11\x19\x9b\x60\xf9\x92\x75\x53\xb0\x88\xe5\x0a\xc1\x9a\x4b\xd6\xd7\x82\x45\x2c\x5c\xe8\x07\x76\x2e\x5b\xb7\x05\x8b\x58\xc3\x50\x2f\x60\x48\xd6\x5d\xc1\x22\x16\x33\x04\x4b\xfa\xab\xf5\xad\x60\x3d\xcf\x5f\x1f\x24\xeb\x7f\x05\xeb\x79\xfe\xca\x96\x7c\xf7\x05\xeb\x79\xfe\x8a\x25\xeb\xa1\x60\x3d\xcf\x5f\xd9\x6a\xed\x11\x59\xab\xe7\xf9\x2b\x95\xac\xa7\x82\xf5\x3c\x7f\x9d\x4a\xd6\xf7\x82\xf5\x3c\x7f\x9d\x49\xd6\x8f\x82\xf5\x3c\x7f\x65\xeb\xdb\x7f\x0b\xd6\xf3\xfc\x95\x2d\x3b\x7e\x16\xac\xe7\xf9\xeb\x42\xb2\x7e\x15\xac\xd2\xee\x94\x7e\x2f\x3e\x3b\x90\x04\xf7\x20\xab\x7e\x23\x63\x94\x7d\x29\xa6\x60\x0c\x1a\x19\x32\xdf\x8e\x35\xc6\xb0\x91\xe1\x66\x9f\xdf\x28\x18\xcb\x46\x86\xfa\x68\x45\xc1\x58\x35\x32\x64\x8e\x9d\x68\x8c\x75\x23\x43\xe6\xd7\xa9\xc6\xd8\x34\x32\x66\xd9\x39\xf7\x05\x63\xdb\xc8\xf0\xb2\xd7\x76\x0b\xc6\xae\x91\x21\x73\xea\xfb\x82\xb1\x3e\x6c\x64\x9c\x64\x27\xb6\x17\x8c\x76\x23\xc3\xcf\x0e\xe7\x2e\x18\x9d\x46\xc6\x3c\x3b\x8b\xba\x60\x74\x1b\x19\x41\x76\x84\x71\xc1\xe8\x35\x32\xc2\xec\x95\xe3\x82\x71\xd4\xc8\x90\xb9\x73\xa1\x31\x9a\xfd\x21\xf3\xe6\x07\x8d\xd1\xec\x8f\x28\x3b\xa4\xb5\x60\x34\xfb\x23\xce\xce\x20\x2d\x18\xcd\xfe\x48\xb2\x23\x16\x0b\x46\xb3\x3f\xd2\xec\xd5\xbc\x82\xd1\xec\x8f\xd3\xec\xec\xb9\x82\xd1\xec\x0f\x75\x4a\x59\xc1\x68\xf6\x87\xcc\x8d\x1f\x35\x46\xb3\x3f\xce\xb3\xd7\x95\x0a\x46\xb3\x3f\x2e\xb2\x13\xb2\x90\xb1\x21\xfc\x51\x59\x89\x2e\x35\x3c\xe1\x8e\xca\x1a\x74\xa5\xe1\x09\x6f\x54\x56\x9f\x6b\x0d\x4f\x38\xa3\xb2\xee\xdc\x68\x78\xc2\x17\x95\x15\xe7\x56\xc3\x13\xae\xa8\xac\x35\x77\x1a\x9e\xf0\x44\x65\x95\xf9\x49\xc3\x13\x8e\xa8\xac\x2f\xaf\x34\x3c\xe1\x87\xca\xca\xf2\x5a\xc3\x13\x6e\xa8\xac\x29\x3f\x6b\x78\xc2\x0b\x95\xd5\xe4\x17\x0d\x4f\x38\xa1\xb2\x8e\xbc\xd1\xf0\x84\x0f\x2a\x2b\xc8\xaf\x1a\x9e\x70\x41\x65\xed\x78\xab\xe1\x09\x0f\x54\x56\x8d\x77\x1a\x9e\x70\x40\x65\xbd\xf8\xad\xc0\x6f\x9b\xf4\x2f\x33\xde\xff\x34\x7c\x93\xfe\xa3\xec\x44\xe9\x02\xdf\xa4\xff\x38\x3b\x3a\xb9\xc0\x37\xe9\x3f\xc9\x0e\x84\x2d\xf0\x4d\xfa\x4f\xb3\xb7\x89\x0b\x7c\x93\xfe\x4f\xb3\xc3\x32\x0b\x7c\x93\xfe\xd5\xa1\x8a\x05\xbe\x49\xff\x32\xc7\xfd\xab\xe1\x9b\xf4\x7f\x9e\xbd\x59\x59\xe0\x9b\xf4\x7f\x91\x1d\xe5\x57\xe0\x4b\xfa\xd7\xdf\x16\xb8\x2c\xee\x35\x1f\xa9\x47\x63\x46\xe1\x47\xcb\x8d\x9c\x33\x2f\x98\xc6\x96\x9f\xdd\xca\x29\x7e\x70\x64\xfc\xea\x0a\xd0\xed\x0a\x7a\x26\x9c\xd3\xf3\x12\x7a\x36\x03\x74\xc7\x10\x1b\x7e\xf6\x64\xfc\xfb\x77\xc0\x76\x0d\x91\x0b\xec\xe9\x29\x60\x7b\x86\xb8\xf9\x4b\x45\xae\x13\xcf\x4a\x35\xea\x1e\x00\xf3\xc8\x70\x15\x23\x13\xfb\xe9\xf8\x19\xd7\x2c\xea\xda\x7d\x01\xbc\xfe\x33\xae\xa8\xf1\xde\x00\x6f\x60\xb8\xde\x87\xd4\x71\xa3\x94\xac\x6c\x0f\x9b\x39\x34\x5c\xb4\x8e\x8c\x2d\x5d\x3e\xef\xca\x45\xa5\x7b\xd8\xd8\xd5\xf3\xae\xab\x51\xb1\xbd\x6b\xc3\x55\xd5\x73\x6d\x81\x6b\xe5\xcf\xfa\x6f\xee\x81\xb1\xa9\x30\x32\xac\x9f\x3f\xd3\x93\x33\x54\x0d\x18\xdf\x44\xc0\xdb\xd2\x3c\x55\xd3\x82\xe7\xab\xeb\xb9\x78\xbd\x9d\xa1\x71\xfb\x35\x74\xe1\x4a\x6d\x93\xb7\x90\xe1\x8b\x89\x6c\xd2\x0d\x10\xaa\xf6\xda\x6b\x52\xf6\x8b\x3c\xb4\xc8\x07\x5a\xd5\x67\x7b\x2d\xca\x68\xd0\x20\xbc\x9a\xc9\x72\x7b\xd5\xf3\x5d\x20\x98\x7c\x97\x2e\xf4\xf6\x3f\x41\x8f\xb5\xab\x6e\x4b\x17\xa6\xf1\x79\xc2\x5e\xab\x3a\x2d\x5d\x98\x46\x27\xc5\x6b\x99\x7c\x56\xae\x5b\x8a\x57\x31\xf9\x2b\xc7\xab\xa6\x3f\x61\x5f\x55\x1d\x55\x6a\x8a\x3e\x2e\x4f\x38\x2e\x55\x27\x95\x5a\xa2\x8f\x4a\x8a\x57\x32\x79\xa8\x54\xb1\x14\xaf\x61\xf2\x0d\x3e\x5a\xa2\xb5\xfe\x3b\xf6\x56\xd5\x3b\xda\x1b\xc5\xe4\xf8\x7c\xc7\x9e\xab\xfa\x87\x18\x9f\x42\xb7\x72\xbf\xb1\x81\xe7\x7c\x8f\xda\x55\x17\x91\xee\x83\xde\x95\x73\xb8\x8b\xec\x4e\xd5\x51\x58\x6f\x83\x42\x4e\xa1\xcd\x9d\x46\x73\xe1\x95\xf3\x26\x5f\xa6\x9b\x08\xaf\x5c\xf5\x18\xa1\xe5\xa2\x29\x59\xbd\x0b\x76\xd3\xec\xa6\x8f\xd2\x29\xf4\x74\xc7\xe4\xb7\x12\x4b\x09\xe2\x3b\xe8\xa7\x53\x35\x1d\x31\xb4\xba\x5e\xbf\x83\x96\x3a\x0d\xce\xcb\xdf\xbe\x2e\x0d\xec\x0d\x36\xb1\x6a\x40\x2a\x09\x95\xc6\xb5\x20\x57\xdd\x48\x8c\xab\xee\x97\x53\x6c\x6f\xd5\x99\x54\xce\x2c\x8d\xaa\x8f\xd7\x25\x1d\xba\x47\xdd\x1b\xd4\x82\x6c\x72\x2a\x31\x3c\xa7\xd8\xc7\x8d\xf3\x9c\x3e\x29\x6f\x60\xe1\xd5\xa9\x1a\xb6\x18\x42\x93\xed\x36\x7e\x61\x9c\xaa\x69\x35\x77\x1b\x46\x77\x73\x53\x08\xd8\x60\xdb\xa2\xab\xb4\x07\xd4\x60\x7e\x82\x75\x60\xb7\xea\xda\x3d\x69\x68\x64\x98\xa5\xa0\xe5\xdd\xaa\x6d\x35\x7f\x1b\x46\xc9\x2d\x5a\xde\x25\x16\xa1\xa8\x23\x93\x75\xdd\xa2\xe5\xdd\xc6\x59\x52\x1f\x30\x17\xdb\xdc\x30\x57\xea\xa4\x27\x6c\x6b\xd5\xbb\xe4\x28\xeb\x26\xd2\x5a\x5a\xb5\x2f\x39\xc6\x3a\x5b\x6b\x67\xd5\xbf\x25\x2b\x54\xc7\xf7\x09\xdb\x5a\x75\x6f\x29\x6f\x54\x47\x37\xc5\x16\x57\xdd\x4b\x8e\xae\x6e\x5f\xad\xc5\xc4\x52\x95\x1a\x5b\x9d\xad\xb5\xb8\x61\xa6\xd5\x87\x28\xc5\xb6\x3e\x6b\xbe\xd5\xa9\xdf\xb1\xad\xcf\xf4\x70\x39\x5d\xcb\x4d\xa9\xd6\xe2\x67\xfa\xb8\x1a\x43\x6b\x77\xd5\xcb\xc4\x0c\x51\x1d\xef\xef\xd0\x07\xbd\xaa\x9f\x4b\xe3\xad\xac\x54\x19\xf4\xcb\x74\x73\x05\x75\xe8\x19\x26\xe3\x22\x88\x8c\x58\x0d\xf1\xe4\x16\x21\xaa\xc6\x26\xe6\x8c\x6a\x8c\x53\x18\x8f\x5e\xd5\xd9\x25\xad\x99\x57\x33\xc5\x78\xf4\xaa\x36\x2f\x4b\xce\x3c\x71\xe2\x78\xf4\x0c\xae\x6f\x5e\x17\x69\xf5\x30\x79\xbf\x79\x0e\x2e\xea\x61\x98\xc1\x0b\x4d\x94\xc7\xa4\x98\x4f\x67\x18\x82\xcc\x04\x45\x80\x7d\x65\x14\xb3\x6a\x11\xe2\x99\x19\xa1\x3c\xd6\x8c\x5f\x9e\x6a\xbd\xf1\xcc\xbc\x50\x8d\xa1\xf5\xc6\xb3\x66\x77\xdd\xe8\xa7\xe0\x8f\x7e\x55\xdc\xf9\x1c\xef\x39\xd3\xec\x1d\x95\x74\xb1\x10\x51\x5e\x89\x24\xb4\xfc\xf0\x4c\x44\xf9\x4a\x61\x02\xbb\xad\xbe\xe9\xee\xc9\x5e\x94\xac\x65\x18\x24\x5f\x43\x8e\x20\x8a\x7a\x64\x4c\x21\xb3\xa7\xa2\x47\x7e\x38\x3e\x61\x3c\x19\x01\x40\xbd\x5b\x90\x91\x75\x80\x8f\x80\x6c\x4c\xb3\x87\x3a\xf2\xa2\x09\x16\x15\x87\xf2\xe8\xd4\x1b\x28\x57\x8f\xfe\xe4\x09\x4a\x03\x44\x08\x50\x07\xa8\xa9\x33\x86\x66\xd9\x59\x02\xaf\x63\x28\x53\x2f\x25\x09\xd7\x4b\xe7\x50\xf8\x16\x0b\xd5\x7b\x73\xd9\x3b\xfa\xaa\xe8\x1f\x28\x52\xcf\x63\x8c\x7c\x67\x7c\x92\xbf\x34\xc4\xf8\x0e\x0b\xb3\x0b\x9e\xcd\xbc\x44\x60\x61\x88\x85\x9d\xfd\xc2\xfc\x53\x0f\x61\x1a\xb8\xc2\xb5\xc6\x61\x14\x88\x28\x66\x3c\x0a\x81\xd1\xad\x30\xf2\xd7\xb4\xbc\x60\x0a\x75\xc8\xee\xd1\xc1\xc5\x22\xd8\x8e\xa8\xc7\x2b\xf4\xcb\x68\xbe\x98\x78\xbe\xcf\x78\x34\x01\xec\xd1\x3e\x16\x45\x98\x23\xcf\x01\x79\xbc\x8f\x0c\xa3\x64\x16\x2a\xbd\x8c\xa3\x30\x8e\x67\x4e\x32\x9e\x01\x0d\x14\xab\x9e\xa4\xd0\x69\x46\x6d\x01\xf5\x02\xa8\x03\x9a\x4a\x88\x1b\xa8\x27\x40\x1d\xee\x53\x51\xda\xd5\xaa\x7e\x04\xd2\x52\x1b\xde\x52\xd7\x3e\x80\xaa\xd4\x93\x10\x0a\x12\x89\x71\x92\xbf\xc9\x15\xc3\xbe\x4a\x3d\xf3\xa0\x46\x4d\x2b\x0f\x61\x68\xd4\x53\x00\x8a\x9f\x2e\x8a\x87\xff\x93\xc8\xcb\xa1\x69\x02\x50\x4d\x00\x34\xf4\x09\xa1\xc7\x5a\xad\xca\x6f\x15\x14\xe8\x05\xd4\x51\xfd\xfe\x9e\xd7\xd1\x84\x4e\xb0\xc6\x5a\x8b\x65\x8e\xa5\xc0\xee\x23\x80\xb5\xe6\x9b\xc0\x1b\xa8\xf5\x5a\x73\x53\xf9\xbd\x09\xad\xd2\xb0\xb9\x59\x6b\xee\x32\x81\x13\xd8\xb8\xad\xb5\xfe\x70\x3d\x67\x1e\x06\x2e\xe3\xee\x0a\x4a\xb5\xf6\x17\xa5\x3f\xa0\x54\xbd\x9e\x12\x5e\x88\x60\x2a\x18\xf7\x41\x8c\xea\xd7\x4c\xc5\x52\x77\xbe\x19\x3f\xfc\x0a\x85\x6a\xed\x94\xfa\x7e\x2c\xce\x65\xc1\x1d\x14\xec\x8a\x9a\x20\x2b\x3f\xf3\xe3\x48\xff\x99\x30\xff\x2e\x8d\x96\xef\xb2\x37\x7e\x0e\xa1\xfd\xfa\x4f\x84\xf0\x95\x18\x2d\xf7\x29\x30\x8c\xb0\xfa\xfd\x2b\x7b\x93\x23\x16\xf9\xeb\x8f\x8c\xc7\xb7\x50\x3c\xd4\x8b\xcb\x4d\xf2\xd6\x39\x68\xab\x29\x55\xf7\x68\xd1\xdd\x93\x0d\x40\xbb\xfb\x50\x65\x6e\x44\x8e\x72\xe4\x71\x7e\x93\x5c\x39\x2c\x71\x22\xc6\x7f\xeb\x40\xd1\xb1\x96\xef\x54\x51\x1b\x8a\xb6\x05\x0b\x5f\xe5\x61\xfc\x32\x11\xb0\x61\x3e\x56\x77\x50\x15\x5b\x87\x3c\x6e\xe1\x46\xc0\xb1\xba\x9d\x55\x28\xc8\x42\x05\x79\x81\x2b\x3e\x32\xfe\xd7\x0c\x90\xdb\x3d\x83\x54\xa0\xef\x00\xaa\xb6\x09\x79\xad\xe7\xd9\xab\x4e\xd6\x24\x3b\xc2\xef\xf0\x09\x20\x2b\x3d\xab\x94\x20\x29\x40\xb4\xaa\xc5\x69\xfe\xf5\xe5\xc8\x39\x8f\x19\x8f\x01\xa3\x56\xc6\x13\x31\x77\xf0\x54\xb6\xc9\x57\x28\x53\xf3\x59\x51\x32\xcf\x9d\x70\x7c\xac\xcf\x58\x0b\xc7\x95\xf1\xbd\x84\xf1\x75\x0c\x00\xcd\x57\x33\xe1\x44\x09\x00\xa0\x85\xc7\x9d\x8a\x5b\x00\xe2\x02\x44\x1b\xff\xb1\x9f\x8e\xa0\x7c\x0c\xe5\x3d\xad\x79\x5a\x25\x2e\xd7\xf1\x01\x8c\xce\xb1\xa6\x0c\xbd\x1e\x97\xeb\x59\x81\xa9\xda\x1a\x51\x6e\x81\xd2\xec\xad\xd5\xe6\x72\x3d\x2e\x20\x99\x01\x64\x6e\xcf\x7e\x1c\x0d\xb3\xaf\xb4\x83\x46\xd5\x3b\x2d\xea\x70\x15\x28\x1b\x40\x99\x1a\x4b\x27\x8a\x84\xab\x43\x62\xc6\xe7\x20\x64\xf5\xfe\x4a\x8e\xc9\x9f\xb5\x2d\x60\x97\xf3\xf6\x31\x56\x23\xcb\x96\xf3\x34\xf6\xc6\xd6\xc4\x77\xe0\x85\xb6\xf9\x0a\xca\xb7\x45\x79\xe0\x24\xa9\x3a\xa1\x22\x83\xfc\x0b\x90\x5d\x01\x89\x67\x4e\xb4\x00\x40\x3e\xa7\xf5\xd5\x9d\xf8\xec\xcd\xab\xfc\x48\xa2\xf0\x04\x8a\xd4\xa2\xdc\xf1\xfd\x30\xb1\x3e\x32\xfe\x11\x38\xea\x56\xe8\xdc\xf1\x13\x11\x0b\x35\x5f\x32\x7e\xa0\x4a\xbb\x87\xea\x67\x3d\xcf\x15\xe1\x34\x72\x16\x33\x79\x61\x75\x68\xa5\x17\x03\xa2\xbd\x8f\x18\x87\xf3\xb9\xc3\xf8\x1f\x97\x80\xe8\xec\x23\x16\x22\xf2\x42\x97\xf1\xd7\x08\x51\xcb\x30\x2f\x49\xc2\xbc\xe2\xbf\xff\x07\x8a\x7a\xfb\xec\x12\x0c\x23\x1c\xed\xc3\xbc\x44\x44\xfa\x49\x7a\xbf\x21\xf4\xb8\x52\x63\x3f\x8c\xa5\x53\x15\xf0\x4f\x04\xf6\xf7\x81\xf9\x03\xca\xf9\x61\x69\x88\x2b\x5e\x72\x84\x83\x03\xf6\xde\x05\xfc\x1d\x90\xda\x3b\x8f\x34\xf4\x1d\x42\x8b\x35\xb1\x5a\x2f\x6a\xe1\x5e\x02\x46\x3b\xa1\x72\x1f\xf4\x0e\x41\x5b\x0c\x94\xfb\x64\x3f\x1c\x76\xb5\xf6\x2e\x3b\x0d\x7d\x07\xd0\x36\x1e\xc0\x80\x73\x7a\x90\x78\xe3\xd4\x77\x34\x74\x0b\xd1\xed\x22\xb0\x19\xfe\x0a\xe1\xea\xe9\xc9\x30\x96\x4b\x58\x35\x26\x7f\x27\x50\xa6\x4e\xb2\x15\x89\x03\x25\x30\x0a\xed\xe2\x10\x87\x24\x8c\x92\xd0\x8b\x85\x15\xcf\x84\xdc\x6e\x60\x85\xa0\x4f\xd4\x2f\x4a\xb0\xb4\xa4\xc1\xaf\x10\x7c\xbc\xd7\x81\x64\x5b\x3d\x40\xf7\xf7\x3b\x91\x6c\x2b\xc2\xd5\x6c\xe0\x9c\x0a\x38\xc6\xf5\x9f\xbc\x44\x19\x53\xeb\x85\x7c\x22\xb9\xfc\x3b\x79\xfb\x0a\x1a\xad\xee\x7f\xcc\xbc\xc8\x99\x3a\x81\x83\x4f\x44\x64\xeb\x59\x87\x71\xe7\x08\x70\x1d\x0a\xe7\x30\xbe\x44\x44\xd7\x1c\xc9\x63\xdc\x43\x5c\x8f\xc2\x79\x8c\x5f\x23\xe2\xc8\x1c\x29\x65\x3c\x45\xdc\x31\x85\x4b\x19\x7f\x42\x44\xdf\x1c\x49\x30\x2e\x10\x37\xa0\x70\x82\xf1\x2d\x22\x86\xe6\x48\x21\xe3\x21\xe2\x96\x14\x2e\x64\xfc\x0e\x11\x2b\x0a\x71\xe2\x30\xfe\x65\x09\x90\x35\x05\x99\x3a\x8c\x7f\x42\xc8\x86\x8c\xe2\x31\xfe\xe5\x1a\x20\x5b\x32\x8a\xc7\xf8\x27\x84\xec\xc8\x28\x29\xe3\x5f\x9e\x72\xc8\xd1\x21\x19\x25\x65\xfc\x13\x42\x48\x0d\x9d\x08\xc6\xbf\x6c\x01\x42\xca\x47\x2e\x99\x3f\x21\x84\xd4\xcf\x49\xc8\xf8\x97\x3b\x80\x90\xd2\x99\x86\x8c\x7f\x42\x08\xad\x1d\x87\xf1\x07\xe8\xba\x23\x52\x36\x17\x0e\xe3\xbf\x10\x42\xeb\xc6\x63\xfc\x01\xba\xee\x88\x94\xcc\x85\xc7\xf8\x2f\x84\xd0\x9a\x49\x19\x7f\xc0\xae\x23\xe5\x72\x91\x32\xfe\x0b\x21\xa4\x5e\x62\xb9\xcf\xc4\xae\x23\xf5\x72\x21\x18\xff\x85\x10\x52\x2f\x71\xc8\xf8\x03\x76\x1d\xa9\x97\x8b\x90\xf1\x5f\x08\x21\xf5\x92\x38\x8c\x3f\x42\xd7\x1d\x93\x7a\x71\x1d\xc6\x37\x08\x21\xf5\x92\x78\x8c\x3f\x42\xd7\x1d\x93\x7a\x71\x3d\xc6\x37\x08\xa9\xc9\x37\x49\xca\xf8\x63\x0a\x40\x52\x35\x19\x04\xfa\xf8\x98\x54\x8d\x9b\x32\xbe\x41\x08\xa9\x1a\xb9\xde\x7b\x84\x3e\x3e\x26\x55\xe3\xca\x5d\x2c\x42\x48\xd5\x24\x21\xe3\x8f\xd0\xc7\xc7\xa4\x6a\xdc\x90\xf1\x0d\x42\x48\xd5\x04\x0e\xe3\xb7\xd8\xc7\xa4\x6a\x02\x8f\xf1\x5b\xec\x40\x52\x35\x41\xca\xf8\x2d\x36\x9a\x54\x8d\xdc\x2b\xdd\x62\x8b\x48\xd5\x04\x21\xe3\xb7\x58\x5d\x52\x35\x33\x87\xf1\x2b\xa8\x6e\x9f\x54\xcd\xc8\x61\x7c\x85\x10\x52\x35\x0b\x87\xf1\x6f\x08\x21\x55\x33\xf3\x18\xbf\x82\x46\xf7\x49\xd5\x8c\x3c\xc6\x57\x08\x21\xf5\xb2\xf0\x18\xff\x86\x10\x52\x2f\xb3\x94\xf1\x2b\xe8\xba\x3e\xa9\x97\x51\xca\xf8\x0a\x21\xa4\x5e\x16\x29\xe3\xdf\x10\x42\xea\x65\x26\x18\xbf\x82\x01\xe8\x93\x7a\x19\x09\xc6\x57\x08\x21\xf5\xb2\x10\x8c\x7f\x43\x08\xa9\x97\x59\xc8\xf8\x15\x0c\x63\x9f\xd4\xcb\x28\x64\x7c\x85\x10\x52\x2f\x8b\x90\xf1\x6f\x08\x21\xf5\x22\xd7\xfb\x5f\x71\x18\x49\xbd\xcc\x3d\xc6\xbf\xc2\x00\x0c\x48\xbd\xcc\x53\xc6\xbf\x42\xd7\x0d\x48\xbd\xcc\x05\xe3\x5f\xa1\xd1\x03\x52\x2f\xf3\x90\xf1\xaf\x50\xdd\x41\x4d\x96\x39\x77\x18\xff\xe9\x00\x90\x54\x4d\x06\x81\x76\x0d\x6a\xd6\x35\xe7\x29\xe3\x3f\x21\x63\x0d\x48\xed\x64\x10\x6c\x5d\xcd\xca\xe6\x3c\x64\xfc\x67\x08\x40\x52\x41\x19\x04\xdb\x48\x2a\x28\x72\x18\xbf\xc7\xaa\x93\x0a\x8a\x3c\xc6\xef\x71\x48\x48\x05\x45\x29\xe3\xf7\x58\x69\x52\x41\x91\x60\xfc\x1e\x87\x84\x54\x90\xdc\x2d\xdd\x63\x75\x49\x05\xa9\xa6\x9f\x39\x8c\xff\xc0\x21\x21\x75\x94\x41\xa0\x5d\x43\x52\x47\x67\x1e\xe3\x3f\xa0\x5d\x43\x52\x47\x67\x82\xf1\x1f\x50\xe9\x21\xa9\xa3\xb3\x90\xf1\x1f\x50\xe9\x21\xa9\xa3\x80\xf1\x5b\x58\x17\x0e\x49\x01\x9d\xa6\x8c\x7f\x87\xfe\x53\x2f\xb9\x9e\x38\x89\x73\xe2\x04\xce\x01\x62\x4f\x43\x6f\x2c\xdc\xfc\x60\xe2\xfc\xc3\x02\x18\x76\x4d\x73\x62\x31\xf7\x0e\x08\xe2\x21\x12\xcb\x23\x51\xd9\x0d\x23\xae\x3c\x1c\x79\xc8\x7d\xf8\xef\x00\x57\x3f\x7c\x40\x7d\x2a\x1b\x8e\xe5\x31\xe0\x3a\x14\x4e\x6e\x49\x10\xd1\x35\x47\x92\xdb\x09\xc4\xf5\x28\x9c\xdc\x92\x20\xe2\xc8\x1c\x49\x6e\x27\x10\x77\x4c\xe1\xe4\x96\x04\x11\x7d\x73\x24\xb9\x9d\x40\xdc\x80\xc2\xc9\x2d\x09\x22\x86\xe6\x48\x72\x3b\x81\xb8\x25\x85\x93\x5b\x12\x44\xac\x28\x84\xdc\x70\x9c\x80\x0d\x96\x6b\x0a\x22\x37\x1c\x53\x84\x6c\xc8\x28\x1e\xe3\x27\xe0\x14\xf5\x32\x66\x25\x8a\xc7\xf8\x14\x21\x3b\x32\x4a\xca\xf8\x09\x88\x5c\xbd\x66\x59\x89\x92\x32\x3e\x45\x08\xa9\x21\xb9\xe1\x38\x01\x4b\xae\x48\xf9\xc8\x0d\xc7\x14\x21\xa4\x7e\xe4\x86\xe3\x04\x5c\xbb\x22\xa5\x23\x37\x1c\x53\x84\xd0\xda\x71\x18\x8f\xa1\xeb\x56\xa4\x6c\xe4\x86\xe3\x02\x21\xb4\x6e\x3c\xc6\x63\xe8\xba\x15\x29\x19\xb9\xe1\xb8\x40\x08\xad\x99\x94\xf1\x18\xbb\x8e\x94\x8b\xdc\x70\x5c\x20\x84\xd4\x8b\xdc\x70\xc4\xd8\x75\xa4\x5e\xe4\x86\xe3\x02\x21\xa4\x5e\xe4\x86\x23\xc6\xae\x23\xf5\x22\x37\x1c\x17\x08\x21\xf5\x22\x37\x1c\x09\x74\xdd\x9a\xd4\x8b\xdc\x70\xb8\x08\x21\xf5\x22\x37\x1c\x09\x74\xdd\x9a\xd4\x8b\xdc\x70\xb8\x08\xa9\xc9\x37\x72\x37\x91\xc0\xf4\xbd\x26\x55\x93\x41\xa0\x8f\xd7\xa4\x6a\xe4\x86\xc3\x45\x08\xa9\x1a\xb9\xe1\x48\xa0\x8f\xd7\xa4\x6a\xe4\x86\xc3\x45\x08\xa9\x1a\xb9\xe1\x48\xa0\x8f\xd7\xa4\x6a\xe4\x86\xc3\x45\x08\xa9\x1a\xb9\xe1\x08\xb0\x8f\x49\xd5\xc8\x0d\x47\x80\x1d\x48\xaa\x46\x6e\x38\x02\x6c\x34\xa9\x1a\xb9\xe1\x08\xb0\x45\xa4\x6a\xe4\x86\x23\xc0\xea\x92\xaa\x91\x1b\x8e\x19\x54\x77\x43\xaa\x46\x6e\x38\x46\x08\x21\x55\x23\x37\x1c\x0b\x84\x90\xaa\x91\x1b\x8e\x19\x34\x7a\x43\xaa\x46\x6e\x38\x46\x08\x21\xf5\x22\x37\x1c\x0b\x84\x90\x7a\x91\x1b\x8e\x19\x74\xdd\x86\xd4\x8b\xdc\x70\x8c\x10\x42\xea\x45\x6e\x38\x16\x08\x21\xf5\x22\x37\x1c\x33\x18\x80\x0d\xa9\x17\xb9\xe1\x18\x21\x84\xd4\x8b\xdc\x70\x2c\x10\x42\xea\x45\x6e\x38\x66\x30\x8c\x1b\x52\x2f\x72\xc3\x31\x42\x08\xa9\x17\xb9\xe1\x58\x20\x84\xd4\x8b\xdc\x70\xcc\x71\x18\x49\xbd\xc8\x0d\xc7\x1c\x06\x60\x4b\xea\x45\x6e\x38\xe6\xd0\x75\x5b\x52\x2f\x72\xc3\x31\x87\x46\x6f\x49\xbd\xc8\x0d\xc7\x1c\xaa\xbb\xad\xc9\x32\x72\x37\x71\x0e\xab\xdb\x2d\xa9\x9a\x0c\x02\xed\xda\xd6\xac\x6b\xe4\x6e\xe2\x1c\x32\xd6\x96\xd4\x4e\x06\xc1\xd6\xd5\xac\x6c\xe4\x6e\xe2\x1c\x36\x1c\x5b\x52\x41\x19\x04\xdb\x48\x2a\x48\x6e\x38\x22\xac\x3a\xa9\x20\xb9\xe1\x88\x70\x48\x48\x05\xc9\x0d\x47\x84\x95\x26\x15\x94\x3d\xfe\x82\x43\x42\x2a\x48\x6e\x38\x22\xac\x2e\xa9\xa0\x62\xc3\x71\x86\x43\x42\xea\x28\x83\x40\xbb\x76\xa4\x8e\xe4\x86\xe3\x0c\xda\xb5\x23\x75\x24\x37\x1c\x67\x50\xe9\x1d\xa9\x23\xb9\xe1\x38\x83\x4a\xef\x48\x1d\x05\x8c\x07\xb0\x2e\xdc\x91\x02\x92\x1b\x8e\x53\xe8\xbf\x5d\x8d\x80\xb2\x05\x24\xb4\x7c\x47\x0a\x28\x07\xca\x75\x99\x00\x20\x29\xa3\x53\x87\xf1\x53\xec\x22\x52\x40\xa7\x1e\xe3\xa7\xd8\x45\xa4\x80\x4e\x05\xe3\xa7\xd8\x45\xa4\x80\x4e\x43\xc6\x4f\xb1\x8b\xca\x02\x9a\x7b\xae\xeb\x0b\xcb\x0d\x13\xc6\x5f\x63\x27\x19\xb6\x4f\x8b\x28\xf4\xc3\x60\xba\xb7\x79\x3a\x40\x5a\x59\x55\x95\xcd\x13\xe2\xca\xd2\x32\x6d\x9e\x72\x78\x1b\x5e\x1b\x5c\x84\xf3\x70\x12\x62\x46\x64\x7c\xd5\x03\xc4\x31\x85\x58\x30\xfe\x0d\x11\x7d\x0a\x31\x67\xfc\x2b\x22\x06\x14\x62\xc2\xf8\x0e\x11\x43\x0a\xe1\x32\xbe\x41\xc4\x92\x42\x24\x8c\x3f\x22\x62\x45\x21\xe4\x8e\x18\x11\x6b\x0a\xe1\x33\x7e\x83\x88\x0d\x85\x98\x32\xfe\x09\x11\x5b\x0a\x71\xc2\xf8\x17\x44\xec\x28\xc4\x8c\xf1\x2b\x40\xc0\xeb\x73\x65\xc4\x7b\xc6\x3f\x23\xa2\x4d\x21\x3e\x30\xfe\x3f\x44\x74\x28\xc4\x47\xc6\xff\x45\x44\x97\x42\x5c\xcc\x18\xff\x75\x05\x90\x1e\x05\x19\xcf\x18\x5f\x23\x84\x54\x48\x3c\x63\xfc\x01\x21\xa4\x44\x22\xc6\xef\xb1\x2a\xa4\x44\x2e\x18\xff\x85\x08\x52\x22\x63\xc6\xd7\x88\x20\x25\x12\x33\xfe\x80\x08\x52\x22\x0e\xe3\x4b\x44\x90\x12\x91\xbb\x5f\x44\x90\x12\x91\x3b\x6d\x44\x90\x12\x11\x33\xc6\x2f\xb7\x57\xf9\xbb\xa6\xdd\x76\x9b\x94\x89\xe3\x31\xbe\xbc\x06\x08\xa9\x13\xe1\x31\xbe\x05\x48\x87\x14\x8a\x93\x32\xbe\x7c\x02\x08\xa9\x94\x30\x65\xfc\x0e\x21\xa4\x54\x9c\x80\xf1\xe5\x2d\x40\x48\xad\x88\x80\xf1\x2d\x42\x48\xad\x38\xc1\x94\xf1\x65\x00\x18\x52\x2c\x42\x62\xb6\x88\x21\xd5\x22\x22\xc6\xb7\xf7\x00\x21\xe5\xe2\x31\x7e\x0d\x83\xd0\x21\xe5\x92\x32\xfe\x84\x08\x52\x2e\x5e\xca\xf8\x35\xf6\x0b\xa9\x97\x53\xc6\xbf\x63\x10\x3a\xa5\x4c\x19\xbf\x9d\x02\x84\x14\xcc\x34\x60\xfc\x53\xde\x73\x9d\x36\x71\x7e\xd5\xcc\x09\xa6\xa9\x6f\xbd\xcf\x0e\x77\x7a\x9f\xc2\xcf\xe7\xf9\x09\xfd\x65\x2c\x3e\xef\x91\x7f\xec\x66\x0d\x58\xe2\x24\xa8\x02\xab\x3e\x78\x83\x58\xe2\xfc\x27\x0d\x9b\x7f\xf4\x06\xd1\xc4\xb9\x4f\x05\x3a\xff\xf0\x0d\x82\x89\xe3\x9e\x34\xb0\xfa\xf8\x0d\x82\x89\x53\x9e\x0a\xb0\xfa\x00\x0e\x62\x89\xb3\xd3\x34\x6c\xfe\x11\x1c\x44\x13\x67\xa6\x15\x68\xf8\x10\x0e\xa2\x89\xb3\xd2\x0a\x74\xfe\x31\x1c\x04\x13\x47\xa4\x69\x9d\x97\x9f\x4b\xbc\x86\x31\x54\x3f\x37\x9c\x84\x91\x70\x02\x2b\x4e\x9c\xc0\x75\x22\xd7\x8a\xcf\xe7\xa3\xd0\x67\xfc\xf2\x24\x1e\x2b\xe4\x36\x7f\x54\xe9\x7d\xe8\x05\x56\x32\xf3\xe2\xec\x9b\xb6\xea\xf1\xbb\x40\x7c\x4c\xd4\xff\x6c\xcd\x6f\xb7\x5f\xef\x6e\xaf\xd7\xaf\x18\x7f\xb3\x06\x62\x36\x9c\xe9\xed\xf5\xa3\xf5\xf0\x6d\xb9\xde\x5a\x8e\xd5\xf2\xe2\xf0\xc0\x8b\x0e\x06\x07\x6d\xeb\xf0\xb8\xf7\x8a\xf1\xd4\x01\x74\x77\x0f\x3d\x2a\xa3\x87\xc7\x12\x3d\x02\xb4\x3a\x33\x32\x0c\x0e\xe2\x85\x33\xf6\x82\xa9\x95\xce\x7d\x27\x4d\x90\xd3\x1d\x58\x9d\xc3\xf6\x2b\xab\xb5\xbe\x5a\xde\x2f\xd7\x8f\xdb\x7b\xeb\xdb\xf2\xfe\xf1\x15\xe3\xff\xe9\x42\x8c\xa3\xfd\x18\xc5\xc7\x93\xb3\xf6\xa9\xcf\x46\x63\xc8\xfe\xa1\xd5\x1e\x76\xc8\x90\x6d\x08\x79\xbc\x1f\x32\xfb\x22\xf8\x7e\xa4\xf6\x61\xd7\x6a\x0f\xbb\x64\xa8\x17\x10\xaa\xbf\x1f\x4a\xff\x96\xf5\x5e\xa8\x1e\x19\xea\x25\x84\x1a\xec\x87\x1a\x7b\xd1\x38\x9d\x4f\x7c\xf1\x91\x8e\x77\x44\xc6\x7b\x07\xf1\x86\xfb\xf1\xd4\x47\x25\xca\x31\x8e\xc9\x18\xff\x40\x8c\xe5\x7e\x8c\xb9\x33\x8e\xc2\x60\x2f\x48\x9f\x0c\x72\x00\x41\x56\xfb\x41\x46\x91\x38\xdd\xaf\xc8\x80\x8c\xd1\x82\x18\xeb\x8a\x0a\xc2\x44\x7d\xec\x7c\x2f\xce\x90\x8c\xf3\x1a\xe2\x6c\xcc\x6a\xd2\xe3\x74\x0e\x0f\xc9\x38\x6f\x21\xce\x76\x3f\x4e\xf6\xe5\x83\x6a\x85\x3a\x87\xb4\x16\x0f\x21\xd0\xae\xda\x30\xf5\xec\xdc\x38\x13\x52\x39\x16\xad\xa0\xff\xe4\xb1\xda\x87\x15\x05\x39\xfb\x83\xd5\x39\xa4\x47\xfc\x2f\x88\xd1\xae\xc4\x10\xae\xe7\xfb\xce\x5e\x14\xda\x16\x7f\x40\x94\xce\x7e\x94\x70\x1a\x06\xe2\xe4\x59\x55\xf9\x13\x82\x74\xf7\x83\xc0\xc7\xba\x9f\xd5\x2b\x90\x19\xdb\x95\x24\xb4\xf7\xe9\xef\x52\x36\x6a\xd3\x5a\xfe\x1b\x82\x55\xb2\x91\xdc\x6a\x59\x71\xe8\x7b\x6e\xaa\x49\xa8\x63\x4e\x6c\x6f\x20\x94\xf6\xe5\x78\x3d\xa0\x17\x26\x8e\x35\x12\xb2\x76\x10\xee\xe8\xc8\xea\xd2\xba\xbe\x86\x60\x7d\x3a\x98\xfa\xd4\xfd\x22\x10\xe9\xdc\x49\x9c\x52\x40\xda\x70\x1b\x08\x38\xa0\x03\xaa\xef\xe1\x93\x01\xe9\x9e\xfb\x06\x01\x87\xd6\xde\x07\xf8\x2b\x41\xda\x03\x6b\xd8\x79\xc5\xf8\x9f\xa8\x80\xa5\xb5\xf7\x21\x7e\x8a\xd3\xee\xc8\x29\xea\x0f\xd4\xde\xaa\x20\x95\xcf\x9a\x52\x9b\xe8\x91\xd8\xbb\xe4\xf0\x15\xe3\x2b\x98\x6e\xda\xda\x89\x55\xc5\xd4\xd6\xb5\x0e\x3b\x43\x79\x95\x31\x76\x78\x96\x48\x26\x69\x90\x7f\xc8\xd2\x9b\x6a\x3e\xeb\x75\xad\x4e\xa7\xfd\x8a\xf1\x1d\xe4\x2f\xb5\x88\xa7\x0e\x20\xbb\x98\x15\xbc\xa3\x81\xd5\xee\xc9\x1e\xd8\xe2\x30\x64\xe9\xc1\x09\x12\x61\xcd\x45\xe4\xb9\x9e\x33\xdf\xbf\xd6\xd0\x3a\xec\x1c\xf7\x5f\x31\xbe\xfc\x9a\x93\x8a\xa7\x2b\xeb\x49\x83\x57\x8c\x7f\x43\x52\x66\xfc\x44\xf8\xd6\x38\x9c\x2f\x9c\xc4\x1b\x79\xbe\x97\x9c\x93\x44\xd9\x63\x97\x09\xbc\x91\xb0\x3d\xec\xe4\x1f\x2c\x71\x46\xde\x18\x97\xf3\xbe\x98\x58\x13\x2f\xc8\x3e\x6f\x18\xcd\xf7\xa2\xb6\xbc\xd1\x7c\x70\x2c\x9b\x2b\x7b\xf5\x72\xf9\xfb\x5b\x8c\xa5\x1e\x97\x4e\x93\xf1\xcc\x9a\xa6\x72\xc6\x8a\xa0\x0e\xa3\x79\xaf\xdb\xb7\xda\x47\xf2\xf2\x93\x1b\xc0\x67\xf6\x9e\x3a\xf3\xb9\x43\x0d\x47\xfb\xf0\xb8\x77\x7c\xd0\x76\xbd\xd8\x3a\xec\x76\xde\xa8\xff\xf4\xdf\xb4\x3b\xb2\x9b\xa7\x13\x08\x52\x3c\x33\xab\x3e\xa6\x76\x2a\xc6\x49\x18\xe9\xf9\x9c\x0c\x34\x78\x73\xd8\x93\x2b\x9e\x77\xa7\x10\x48\x33\xf5\xa9\x13\x79\x8e\x99\xdc\xeb\xbc\x69\x67\x8b\xab\x17\xbf\x01\x59\x33\xf1\x42\x44\x5e\xbc\x08\xe7\x22\xf0\x1a\x42\x1c\xbd\x62\xfc\x1f\x0c\x31\x28\x74\xb6\x7f\xf4\xa5\x5a\x2e\xe5\x53\xc2\xcd\xdd\x8f\xed\xfd\x7a\xf9\xb0\x7d\x6b\x1d\x1e\x1e\xbe\x51\xff\x69\xbf\xe9\xf4\x0e\x5f\x31\xfe\x5e\xcd\x06\xbb\x95\x7a\x44\xbe\x24\x5b\x6f\xea\x24\x69\x24\xac\xc9\x84\xf1\xdd\x0e\x70\x6d\x33\xce\x63\x7c\x77\x0d\xb8\x8e\x19\xe7\x33\xbe\xbb\x01\x5c\xb7\xe6\xba\x1e\xe3\x97\xbb\xdd\xf5\x25\x60\x7b\x35\x58\x3f\xc3\xde\x20\xf6\xc8\x8c\x4d\x18\xdf\x3d\x02\xee\xd8\x88\x8b\x13\xc6\x1f\x72\xdc\x56\x3d\x54\x94\x0b\x3f\x9e\x39\xae\xeb\x64\x6f\x63\xe6\xa2\x67\xfc\xb2\xfb\x7b\xfe\xc8\xfd\x6e\x3b\x30\xb9\x24\x1b\x97\x79\x46\x56\x82\x2b\x6c\x23\xbd\x31\x7f\x8d\x11\x7a\x75\x11\x66\xce\xfc\x82\x8e\x30\x2b\x22\x6c\x0c\x11\xbc\x38\xf4\x9d\xfc\x6b\x39\x19\xe7\xf7\x03\xe4\x6c\x1b\xdd\x9d\x11\x8a\x8b\xec\xaa\x84\x91\x98\x55\xae\xb1\x2a\xae\xa1\x1e\x76\x21\x28\x81\x97\x68\xbd\xb9\xfa\xfd\x0f\x64\xb4\x69\x46\xb9\xfb\x57\x45\xf7\x0f\x89\xee\x97\x84\x52\x2b\x56\x45\x2b\xd4\x63\x31\x65\x7c\x22\x2f\xe0\x44\xa3\x34\x71\x2a\xad\x79\xfc\x5a\xb4\x86\x18\x27\x9d\x5a\xba\xe4\xe3\xd7\xe2\x92\x47\x34\xaf\x72\x29\xad\xe3\x8e\x0d\x94\x72\xc7\x3d\x6a\x1d\xd7\x37\x54\xae\xd4\x71\x8f\x5a\xc7\x0d\x68\x42\xb9\x15\x5a\xc7\x0d\x09\xfc\x8c\x6a\xc6\x97\xa2\x19\x4b\x13\x67\xaf\x1d\x5f\x8a\x76\xac\x0c\x94\xbd\x86\x7c\x29\x1a\xb2\x36\x30\xca\x2d\xf9\x52\xb4\x84\x70\xcb\x7b\x21\xe6\x95\x96\x7c\xd2\x06\x84\x70\x8b\xe2\x94\x5b\xf2\x49\x1b\x11\xc2\x2f\x19\xa5\xdc\x92\x4f\xc5\x90\x2c\x09\xbb\x64\x8c\x52\x4b\x3e\x15\x63\xb2\x24\xdc\x32\x73\xaa\x43\x72\x55\x0c\xc9\x92\xf0\x4b\x46\x29\xb7\xe3\xaa\x18\x91\x25\xe1\x18\xc9\x28\x37\xe3\xaa\x18\x90\x25\xe1\x13\x49\x28\xb5\xe2\xaa\x18\x8f\x25\xe1\x8f\x13\xaa\x19\xff\x16\xe3\xb1\x24\x0c\x72\x42\xb4\xe3\xdf\x62\x3c\x96\x84\x43\x4e\xaa\x0d\xf9\x57\x1b\x0f\xc2\x22\x27\x95\x96\xfc\xab\x8d\x07\xe1\x11\xd7\xf1\x2b\x0d\xd9\x68\x0d\x21\x2c\xe2\x66\x6f\xb7\x6b\x97\xd8\x68\x97\x20\xfd\x41\x5d\x43\x1b\x73\xd2\x21\x95\x8b\x68\x23\x42\x38\x24\x22\xac\x7e\xaf\xb5\x83\x30\x48\xb4\x6f\xc2\x7b\xad\x1d\x84\x3b\x2e\x1c\x2f\xa8\x5c\xe3\x57\x71\x8d\x15\xe1\x8f\x8c\x53\xba\xc8\xaf\xe2\x22\x2b\xc2\x1f\xb1\x10\xd5\x8b\x3c\x68\x17\x21\x0c\xa2\x38\x65\x65\x3d\x14\xca\x5a\x11\x0e\xc9\x28\x65\x65\x3d\x14\xca\x5a\x11\x16\xc9\x18\xa5\x96\x3c\x68\x2d\x21\x3c\x12\xcf\xc8\xa6\xdc\x16\x4d\x21\x4c\x92\x93\xf6\xda\x72\x5b\xb4\x85\x70\x89\xe2\xec\x35\xe6\xb6\x68\x0c\x61\x13\x45\x29\xb7\xe6\xb6\x68\x0d\xe1\x93\xd8\x71\x2b\x6d\x59\x6b\xc3\x42\xf8\x24\xa3\x94\x5b\xb2\xd6\x46\x85\x70\x8a\x64\x94\xdb\xb1\xd6\x06\x85\xb0\x89\x24\x94\x5a\xb1\xd6\xc6\x84\x70\x89\x4b\xb4\x62\xb3\x29\x5a\x41\xb8\xc4\xad\xb6\x62\xb3\x29\x5a\x41\xf8\xc4\xad\xb4\x62\xb3\xc1\x56\xac\x09\x93\xb8\xfb\xad\xd8\x6c\xb0\x15\x6b\xc2\x23\x09\x91\x7c\x1f\x3f\x63\x2b\xd6\x84\x45\x92\x6a\xee\x7d\xfc\x8c\xad\x58\x53\xab\xae\x4a\xea\x7d\xfc\x5c\xb4\x82\x5a\x6b\xed\x67\xde\xc7\xcf\x45\x2b\x08\x7f\x5c\x10\xad\xf8\x35\x2b\x5a\x41\xb8\xe3\xa2\xda\x8a\x5f\xb3\xa2\x15\x84\x37\x2e\x2a\xad\xf8\x35\x2b\x5a\x41\x38\xe3\x62\xbf\x15\xbf\x8a\x75\xfc\x9a\xf0\x05\x95\x13\xb7\x85\x2f\xd6\x84\x2f\x32\x4a\xb9\x15\xdb\xc2\x17\x6b\xc2\x17\x92\x51\x6e\xc5\xb6\xf0\xc5\x9a\xf0\x45\x25\xeb\x6e\x0b\x5f\xac\x09\x5f\x4c\x67\x54\x3b\xae\xb5\x76\x10\xce\xc8\x49\xe5\x96\x5c\x6b\x2d\x21\xbc\xa1\x38\xe5\xb6\x5c\x17\x6d\xd9\x10\xee\x50\x94\x52\x6b\xae\x8b\xd6\x6c\x08\x7f\x4c\x88\xb9\x70\x57\xb4\x65\x43\xf8\x63\x52\x5d\xf5\xee\x8a\x96\x6c\x08\x7f\x4c\x2a\x8b\xde\x9d\xd6\x0e\xc2\x1f\x93\xfd\xe9\x76\xa7\xb5\x82\xf0\xc7\x07\xa7\xba\x41\xfc\x9f\xd6\x0a\xc2\x1f\x19\xa5\xdc\x8a\xff\x69\xad\x20\xfc\x21\x19\xe5\x56\xfc\x4f\x6b\x05\xe1\x0f\x49\x28\xb5\xe2\x7f\x5a\x2b\x08\x7f\x9c\x10\xad\xf8\xa2\xb5\x82\xf0\xc7\x49\xb5\x15\x5f\xb4\x56\x10\xfe\x38\xa9\xb4\xe2\x8b\xd6\x0a\xc2\x1f\x27\xfb\xad\xf8\xa2\xb5\x82\xf0\x87\xef\x54\xb7\x1f\x37\x5a\x2b\x08\x77\x64\x94\x72\x2b\x6e\xb4\x56\x10\xde\x90\x8c\x72\x2b\x6e\x8a\x56\x6c\x09\x67\x48\x42\xa9\x15\x37\x45\x2b\xb6\x84\x2f\xe6\xd4\x2e\xea\x6b\xd1\x8c\x2d\x61\x8c\x39\xb1\x8b\xfa\x5a\xb4\x63\x4b\x38\x63\x5e\xdd\x45\x7d\xd5\x1a\x42\x58\x63\x5e\xd9\x45\x7d\xd5\x5a\x42\x78\x23\x08\xc3\x6a\xba\xba\xd5\x5a\x42\x98\x43\x71\xca\x2d\xb9\xd5\x5a\x42\xb8\x23\xa3\x94\x5b\x72\xab\xb5\x84\xb0\x47\xc6\x28\xb5\xe4\x56\x6b\x09\xe1\x0f\x6a\x8b\x7e\xa5\x35\x84\xf0\x07\xb1\x43\xbf\xd2\xda\x41\xf8\xa3\xba\x41\xbf\xd2\x9a\x41\xf8\xa3\xb2\x3f\xbf\xd2\x5a\x41\xf8\xe3\xcc\x39\xab\xb4\xe2\x87\xd6\x0a\xc2\x1f\x92\x52\xba\xc4\x0f\xed\x12\x84\x3b\xb2\x9b\x5f\x73\xe7\x24\x4e\xa3\xea\x6d\xa0\xcf\xc5\xb5\x76\x84\x51\x4a\xdc\xd2\x45\x3f\x17\x17\xdd\x11\x8e\x39\x27\x46\xe7\xa7\x76\x2d\xc2\x30\xe7\xd5\xd1\xf9\x59\x8c\xce\x8e\xf0\xcb\x79\x65\x74\x7e\x16\xa3\xb3\x23\xec\x72\xbe\x3f\x3a\x3f\xb5\x56\x94\xdc\x02\xf7\x4f\x65\xa6\x50\xbf\xdb\x93\xb7\x3e\x2b\xa9\x6d\x5e\x34\xf1\xf8\xff\x10\xaf\x9c\x94\x8a\x5b\xa9\xbb\xfe\x33\x83\xe9\x77\x55\x2b\x95\x2b\xd6\x88\xbb\xc1\xff\x21\x5e\xb9\x72\xc5\xea\x6e\x37\xfc\x7f\x0a\xa6\x7e\x2c\xac\x54\xee\xaa\xa8\xdc\xf2\xff\x10\xaf\x5c\xb9\xab\xa2\x72\xab\xe6\x60\x95\xba\x2c\x8b\xba\xac\x9b\xe9\xe5\x4b\x2f\xb3\x4b\xff\xff\x01\x00\x00\xff\xff\x71\x9d\xca\x8f\xdf\x44\x01\x00") + +func fontsMnemonicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMnemonicFlf, + "fonts/mnemonic.flf", + ) +} + +func fontsMnemonicFlf() (*asset, error) { + bytes, err := fontsMnemonicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/mnemonic.flf", size: 83167, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMorseFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x54\x6d\x6f\xdb\x36\x10\xfe\xce\x5f\x71\x73\x03\x24\xd9\x4c\xc6\xb2\xd3\x36\x4e\x8b\xbe\x2c\x1b\x8a\x00\x1d\x56\xac\xed\xa7\x61\xc0\xce\xe2\xc9\x22\x4a\x91\x02\x49\x59\x4d\x87\xed\xb7\x0f\x7c\x91\xed\x24\xc0\xbe\xcf\x41\x40\xea\x78\xf7\xdc\x3d\xcf\x1d\xd9\xe8\x66\x89\x27\x50\x41\x05\xab\x05\xf0\x0a\x2e\x17\xec\x17\xeb\x3c\xc1\xe6\x0e\xde\x69\x32\x06\x6e\x5a\xec\x7b\xd2\x1a\x5e\x6e\xb7\xf5\x9b\x41\x0d\xb5\x20\x39\xbc\x82\x6a\x71\xb1\x7e\xca\x7e\x44\x4f\x12\xac\x01\x65\x1a\x0b\x8d\xb3\x1d\xcc\x32\xc0\x8d\x95\x04\x68\x24\x84\x96\xe0\x43\x6b\x0d\x05\x55\xc3\x5b\xdd\xb7\xb8\xa1\xe0\x67\xec\xf3\x6f\xef\xaf\xa1\x0d\xa1\xbf\xbe\xb8\x18\xc7\x51\x78\x1b\xac\x11\x58\x8b\xe1\xcb\xc5\x3f\xbe\xee\xd7\xab\xba\xbd\x70\xd4\x90\xbb\xc0\x12\x25\xda\xd0\x69\x76\x6b\x6a\x3d\x48\xf2\xe0\x6d\x47\x70\xfb\xf1\x57\x78\x8f\x41\x19\x5e\x41\xdd\xa2\xc3\x3a\x90\xf3\xec\x03\xb9\x4e\x79\xaf\x62\x69\x1e\x5a\x72\xb4\xb9\x83\xad\xda\x91\x81\x60\xa1\xb3\x52\x35\x77\x10\x5a\xe5\xa1\xb1\x26\xcc\x01\x3d\x68\x6b\xb6\x71\x0d\x2d\xb1\xe4\xa0\xc8\x9d\x7a\x30\xd8\x51\xc4\xe8\x35\xd6\x99\x2b\x42\x6d\xbb\x8e\x4c\x00\xad\x0c\x09\xc6\x3e\x7b\x02\xdb\x1c\xe0\x00\xb5\xb6\xa3\x87\x46\x6d\x35\x85\x98\xb0\xb6\x66\x47\x2e\xc0\xdb\x8f\x37\xb7\xb7\xd1\x70\x6b\x02\x39\x83\x41\x59\x83\x1a\x92\x64\x2c\x4a\x26\x18\xfb\xd4\x12\x34\x36\x22\x28\xb3\x05\x3f\x6c\x7c\x50\x61\x88\x9e\x1e\x5a\xdc\x11\x6c\x88\x0c\x74\x28\x69\x0e\x4a\x90\x98\x83\x6a\xa6\x54\x8e\x6a\x52\x3b\xf2\x80\x6c\x2f\x46\x2c\x39\x36\x41\x53\x13\x22\x3f\x65\xfa\x21\xcc\x41\x05\x18\x95\xd6\xd0\x3b\x65\x42\x72\x38\x6a\x5c\x63\x5d\xd2\xe1\x11\x88\x53\xdb\x36\x5c\xb3\xef\xe0\xfe\x8f\xbf\x02\xc1\x5e\x3c\x36\x5e\xb3\xdf\xff\xf8\xeb\xef\x07\xc6\xb3\x73\xf6\x8e\x5c\x87\x06\x3c\xff\xb6\xb7\x7a\xcf\xa6\x3e\xce\x7a\xa7\x3a\x9a\x45\xeb\x29\x7b\xf2\x18\xf5\xe5\x4f\xa4\x29\x10\x68\xf4\x01\x46\xeb\xe4\x2b\xf6\xfd\x63\xaf\x9b\x96\xb1\x9f\xbf\xd6\xd4\x27\xd6\xc6\x06\x92\x80\x1b\xbb\xa3\xf9\xd1\xa0\x44\x3b\xe0\x0e\x95\xc6\x8d\x26\x50\xe6\x58\x85\x83\x3e\x0c\x3d\xcc\x5e\xcf\x04\x63\xa9\x71\x3c\x26\x05\xdf\x63\x4d\xc7\x3d\x21\xa3\xd1\x6d\x49\xc6\x06\xab\xae\x77\x76\x47\xe0\x08\x25\x6e\x94\x56\xe1\x4e\xc0\xa7\x34\x09\x8d\x75\x1d\x0b\x36\xe9\xe9\x03\x1a\x89\x4e\xfa\x24\x39\x0e\xc1\x76\x18\x2f\x4a\x70\x68\xfc\x34\xc1\xb6\x39\xaa\x6a\x0e\x83\x27\xf0\xdd\xe0\xdb\xce\x4a\x62\xdf\xc8\x59\x38\x9b\x95\x01\xe0\x0d\x74\xc9\x95\x77\x8b\xd9\xf9\x0b\x18\x51\xe5\xe6\xca\xc1\xa5\x69\x8b\x60\x08\xd2\x86\x94\x90\xb0\x6e\x61\xa3\xd1\x7c\x61\x2a\x37\xd8\x0e\x21\x8d\x07\x7a\x18\xe3\xb5\x47\x0f\x1b\x0a\x63\xa4\x87\xe6\x0e\xc2\x68\x8b\xcb\xb1\x88\x67\xd2\x06\x3f\x67\x12\x7d\x4b\x1e\xac\xcb\x90\xfe\x5c\xc4\x0e\xf4\x1a\xcd\x3e\x75\xa3\x9c\xcf\xf7\xe6\x9a\xc5\xd7\x07\x38\xcc\x3a\xdc\xaa\x1a\xcc\xd0\x6d\xc8\xcd\x52\x59\x8d\x8a\xbd\x90\x64\x82\x6a\x54\x9d\x82\x19\xa6\xb6\x82\x6f\xed\xa0\x25\xa0\x1e\xf1\x2e\x96\x06\x7f\xe2\xe9\x3c\x05\x19\x3b\xb2\x93\xec\x14\x89\xcc\x5a\x74\x32\xd5\x31\x03\xce\x73\x1b\x7d\xa4\x83\xb9\xba\x39\x6c\x22\x09\x34\xa7\x21\xc2\x24\x41\x49\xb2\x2a\x23\xb4\x14\x07\x3d\x8b\xb5\x27\xfa\x9f\x87\xf3\x34\x4a\x2a\x3d\x4e\xf1\xe2\x4a\xf2\x35\x19\x19\x1f\xa3\xd5\x22\x85\x75\xf8\x35\x31\x07\x4d\x66\x1b\x5a\x38\xa3\xaf\x93\xf3\xf1\x83\xe2\xcf\xe1\x07\x40\x68\x06\xb9\x25\x68\xb0\x0e\xd6\x31\x5e\x25\x04\x49\x0d\x0e\x3a\x1c\xba\x5f\x2e\x6a\x79\x77\xd8\x65\x4e\x94\xa5\x8c\xf5\xdd\xc3\x65\x0c\xe0\xe4\x0d\x13\x3c\xfe\xe5\x8d\xe0\x22\x6e\xca\xef\xe4\x0d\x7b\x7d\xf2\x64\xff\x2f\x38\xe7\xe9\x9c\x0b\x9e\x23\x0e\x1b\xce\x79\xf1\xe6\x11\x25\x1f\x0a\x31\xe1\x4e\xee\x19\x9f\x17\x77\x31\xad\x62\x5a\xc5\xb4\x8a\x69\x15\x13\x52\x8a\x9b\x56\x3e\xad\x7c\xff\x7d\x6f\x73\xaf\x6c\x51\xdc\x33\x87\x82\x97\xab\x2f\xe8\x31\x57\xae\xa3\xa4\x29\xc9\xd3\x52\x0a\xcd\x01\x45\xa6\xe4\x95\x2c\x39\x6b\xf6\x29\xc1\xc5\x29\x63\x44\x53\x86\x2e\x04\xb3\x6b\x51\xa3\x68\x58\xb8\x1d\x2b\x9a\xa4\x3c\xfe\x38\x74\xe1\xff\xca\x40\xec\x67\xa5\x94\x3a\x0d\xc7\x63\xa3\x10\x27\x39\xf3\x22\x45\x56\xcf\x16\x79\x56\xab\xe7\xd5\x61\x4c\xab\xab\xc5\x61\x26\xab\xab\xe7\xc7\x27\x57\x65\xb8\xb2\x65\x1a\xa8\xea\x6a\xfd\xc0\x9e\x99\x57\xeb\x45\x19\xbe\x07\xfe\xeb\x15\x9b\x18\x54\xeb\x67\x53\xb1\xd5\xfa\xf9\xde\xbc\x5c\x54\x49\x75\x91\xf6\xeb\xa4\x5e\xb2\x57\x97\x13\xa9\xe5\x72\x31\x11\x5b\x2e\x57\x47\xe4\x96\xcb\xa7\x07\x9c\xe5\xd5\x04\xbf\x5c\xae\x0f\xe6\xd5\xea\x00\x7f\x59\x1d\xe0\x2f\x9f\xed\xe1\x9f\x2e\x27\xf8\x7f\x03\x00\x00\xff\xff\xa9\x58\xa7\xd0\xc0\x09\x00\x00") + +func fontsMorseFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMorseFlf, + "fonts/morse.flf", + ) +} + +func fontsMorseFlf() (*asset, error) { + bytes, err := fontsMorseFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/morse.flf", size: 2496, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsMoscowFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\x4d\x8f\xd3\x30\x10\xbd\xe7\x57\x3c\x65\x38\xa4\x12\x94\x2d\x88\x95\x96\x03\x5a\x89\x13\x17\x2e\x20\x4e\x1c\x48\x53\xa7\x89\x36\x6d\x16\x27\xcb\xaa\x12\xe2\xb7\xa3\x6e\x63\x7b\x6c\x8f\xd3\xe5\x8a\x7a\x19\x7b\x9c\xf1\x9b\x0f\x3f\x8f\x53\x77\xf5\x9b\xf2\x05\xae\x71\x8d\x1b\xbc\x5a\x61\x75\x95\x7d\x3c\xe8\xb6\xeb\xda\x0a\x75\xbf\x1f\xb1\x3e\xe0\xab\x2e\xab\x03\xbe\x54\xcd\x43\xf3\xa8\xf4\x1d\x8a\xa7\x85\xa5\x5d\xb8\x1d\x36\xba\x5a\x56\xfd\x6e\xb1\xcc\x3e\xf7\xbf\xd4\x6e\xad\x34\x56\xef\xc6\xe6\x25\x56\x37\x37\x6f\x81\x6f\x4a\x0f\x6d\xbf\xc7\x6a\x79\x95\x7d\xc2\x50\x56\xba\xad\xdb\x4a\x6d\x30\x36\x0a\x75\xdf\x75\xfd\x63\xbb\xdf\x62\x38\xec\xd6\x7d\x37\xa0\xee\x35\x6c\x10\x9d\x1a\x47\xa5\x87\xf7\x19\x90\x7f\xcf\x51\x0c\x5d\x39\x34\x8b\xa3\xf6\x3a\x47\xb1\x2e\xab\x3b\xb8\xa5\xdf\x39\x8a\xfb\xf6\x5e\x2d\x70\xd4\xfe\xe4\x28\xc6\xb6\xdb\x4c\xea\x8f\xe3\xee\x76\xbf\xed\x14\x7e\x3e\xf4\xa3\x7a\xda\xf1\x21\x47\xb1\xd5\xaa\x1c\x95\xc6\xd8\x94\xfb\x45\x96\x01\xc0\xed\xbc\xb4\x0a\x45\xd2\xad\x1b\x85\x40\x56\x26\x91\x26\x23\x22\x69\xee\x60\x4f\x1f\x60\x3f\xb3\x15\x1f\x09\x27\x79\x32\x75\xeb\x7e\xe0\xc4\x51\x9d\x53\x17\x60\x88\x21\x95\x80\x19\xf9\x85\x20\x1e\x93\x5c\x2d\x8a\x8b\x69\xf2\x0a\xe6\x41\xe9\x22\xd3\x20\xa6\x48\x0a\xee\x98\x9c\x90\xa4\xec\x66\xf0\xfc\xec\x26\x49\xfc\x34\xb9\x11\xaf\x32\x52\x15\x27\x87\xe1\xd5\x89\x1b\x99\x60\x39\x49\x66\x8d\x10\x6e\x90\x98\xe9\x6d\x40\x84\x44\xb2\xeb\xb4\x91\x90\x5d\xe4\x62\xce\x9d\x78\x1d\xd2\x46\x42\x4c\xde\x15\x0d\xe7\xe7\x8c\x28\xc5\x71\x8f\xca\x88\xdc\x71\x26\xb1\xf9\x69\x30\x35\x9f\x6a\x65\x93\x30\x64\x31\x35\x3c\x73\x8e\x31\x01\x3d\x6e\x25\x5d\x1f\x51\xa6\xbd\x86\x55\xc4\x5c\xfa\xae\x8d\x81\x71\x36\x75\x0a\x7b\xe5\xc8\x01\xf0\xe4\x3c\x24\xb7\xc1\xe8\xbe\x07\x0b\x61\x31\xfd\x09\x91\x2d\x79\x1c\x98\xf1\xc3\x03\x25\xff\xbb\x94\xba\xbb\xa0\xc4\xf4\xe9\xbb\xec\xc1\xf3\xe4\x8f\x71\xea\xa6\xb8\x51\xb1\xa3\x1c\x1c\xf2\x79\x22\xcc\xc4\x1c\xe6\x24\x7b\x30\xa4\x00\xd7\x53\x65\x35\xe7\x1b\x8e\xe9\x1c\x28\xc8\x21\xc9\xa8\x80\x20\x67\x29\x08\x76\xb2\x82\xa1\xf9\x3e\x7f\x70\xff\x16\x52\x10\x9a\x48\x3e\x04\x86\xb3\xd4\x40\xc8\xd6\x60\x44\x74\x8d\xc8\x5d\x7b\xa4\xc7\x67\x91\x2f\xc1\xd6\x99\x1c\x98\x2e\x55\x89\xc4\x31\x38\x07\xbb\xc3\x9a\x88\x13\xc4\x17\x35\x38\xbe\xa8\xe5\x24\x7b\x94\x4f\x08\xab\x7b\x99\xd8\x1e\x1a\xff\xae\xf8\xcf\xcb\xb3\x1e\xf4\x18\x03\xa1\x11\xd8\x6e\xa4\x7f\xa1\x64\xe9\x95\xc6\x76\x8a\x09\xcf\xbe\x77\xf6\x18\x58\x37\xb9\x74\xfd\x4b\xd7\xbf\x74\xfd\x4b\xd7\xbf\x74\xfd\xb8\xeb\x93\xdc\xf5\x65\x9e\x06\xe9\x13\x10\x3d\x13\x0c\x29\x7e\x01\xa4\x58\x03\x8a\x45\xb1\xce\xc9\xff\xdd\xe8\x6f\x00\x00\x00\xff\xff\x2b\x5c\x68\xd7\x8f\x12\x00\x00") + +func fontsMoscowFlfBytes() ([]byte, error) { + return bindataRead( + _fontsMoscowFlf, + "fonts/moscow.flf", + ) +} + +func fontsMoscowFlf() (*asset, error) { + bytes, err := fontsMoscowFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/moscow.flf", size: 4751, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsNancyjFancyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x8f\x9c\x38\x13\xbe\xf3\x2b\x4a\x74\x24\x2e\x79\x4b\x9a\xf7\xb0\x5b\xca\xae\x56\x68\xef\x48\x5c\x7d\xc3\xc4\x74\xa6\x77\x9a\x26\x9a\x66\x12\xcd\xbf\x5f\xb9\x5c\x36\x86\xe6\xab\x67\x26\x4b\x32\x60\x1b\xbb\xbe\xeb\x71\xbb\x38\x9e\x8f\xff\xd7\x9f\x80\xe0\x37\x78\xf8\x1d\xfe\xf7\x00\x0f\x0f\x49\x02\xee\xba\xe8\xcb\xd7\xd7\x7f\xf0\x78\x3e\xf2\xd0\x45\xb7\x8d\x01\x7d\xec\x9b\x67\xe8\x1f\x1b\x38\x77\xdf\x4e\x17\xe8\x8e\xa0\xe1\x67\xd7\xea\x0b\xfc\x7c\xec\x00\xf4\xf5\xa9\x31\xd0\x36\xd0\x77\xd0\xea\xa7\x06\x1e\x9b\x67\xd0\x76\xfd\xf5\xf4\x0d\xa1\x7f\x3c\x5d\xe1\x74\x65\x02\xc7\xee\xd2\x43\xff\xa8\x7b\xf8\xaa\xdb\x06\xba\x97\xde\x52\x3b\xf5\x08\x61\x5a\xfb\x0a\xc7\xd3\xf3\xb5\x67\x91\x74\xdf\x37\xed\xf7\x1e\x74\x0f\x1a\x8e\xa7\x6f\xe7\xa6\x67\x1a\x9f\xe1\xda\xc1\xb9\xd1\x3f\x1a\xcb\x57\x9f\xbb\x4b\x83\x41\x09\x00\xf8\xa1\xdb\xef\xaf\xcf\xb9\xfe\x7a\xc5\xfa\x05\x1b\xf3\x92\x24\x45\x67\x4e\xc7\x53\x63\x82\x94\xbd\xae\xaf\x50\x9f\xf5\xe5\xe9\x0a\xf5\x2b\x94\xfa\xe5\x0c\x7f\xbf\x3c\xf7\xdd\x05\xfe\xbc\x76\xe7\x97\xfe\xd4\x5d\xf2\x46\x3f\xf7\x8f\xe7\xd3\xe5\x09\x2f\x4d\xff\x57\x92\x7c\xfa\x04\xf9\x8e\x5b\x9e\x98\x12\xf2\x84\xc8\xdf\xb8\x0b\x00\x79\xd2\x75\xbe\x65\x6f\xfc\x86\x5f\xfa\xa7\x53\x60\xf7\x33\x0f\x5a\xe7\x09\x38\x1a\xcc\x93\x2f\x3b\x46\x64\xff\x8f\xc7\xc2\xbc\x68\x2d\x44\x04\x0f\xfc\x1f\xf2\x04\x8d\x5d\x52\x66\x90\x27\x8a\x0e\x5d\x77\xe8\x10\xfc\x04\x26\x55\x51\x98\x10\x2d\x83\x5b\xba\xac\x2a\x95\x00\xcc\xd9\x8a\x03\x04\x60\x28\xe3\x8e\xa2\x52\xda\x6e\x89\x6d\xdb\xd9\xb6\xc3\xe3\x76\xb6\x53\x06\x00\x14\x95\x31\x65\x98\x74\x84\x02\xd5\xe1\x15\x55\x19\x45\xb4\xeb\x60\x2f\x2a\xab\x30\xcd\xf2\xa9\xa8\x76\x76\xa9\x58\xab\x4a\x6d\x30\x32\xc1\xc1\x58\xc6\x6e\x9d\xdc\xf2\x04\x34\xb1\xd0\x5e\x61\x12\x79\xfc\x53\x11\xba\xd9\xca\xca\x3d\xe3\x65\x45\xd4\xb9\x81\xca\x4f\x70\xbe\x0c\x4f\x14\x06\xa4\x16\xc3\x84\x4d\xcf\x6c\x6b\xb4\xcb\x90\xe5\xb7\x14\x89\x58\xb2\x3c\xb1\x64\x88\x58\x9c\x3c\xb1\x8e\x25\x82\x4a\x09\xa7\x81\xc0\xba\xf1\xa3\x17\x6e\x85\x97\x13\xa2\x40\xa4\xf1\xe8\x78\xee\x5c\xf8\xcc\x59\x77\x48\xb3\xe0\x80\x85\xf5\x71\x73\x2c\xc1\xfa\xdc\xfd\x12\xc4\xee\x06\x09\x62\x31\x9b\xd8\x76\x08\x78\x88\xc2\x5d\x5a\x21\x1a\x56\x25\xd0\x56\x6e\x0d\x12\x4a\x88\x1c\x0c\xd6\x95\x25\x78\xb4\x31\x99\x6b\x2a\xca\x32\x89\x0a\x1b\x56\x36\x00\xd7\x72\x93\x41\x02\x56\x1e\x86\x86\xbc\xf3\x0f\x1e\x25\x1b\x4e\x6e\xa4\x72\xbe\xd0\x5a\x1b\x06\x05\x8a\x74\x43\x69\x29\x87\x19\x4b\xf0\x33\x47\x10\x2c\xc1\x60\xce\x2a\x78\x0e\x1d\xb8\x6e\x10\x14\xd4\x11\xfb\x8a\x99\xb4\xd6\x43\x00\xcc\xb5\xcc\x22\x41\x0a\xfc\x62\xf5\x6a\xad\x35\xde\x48\x08\x7b\x24\x14\x98\x5d\x20\x48\x54\x09\x41\x6b\x16\x97\xb3\x95\x1a\x60\x77\xc9\x86\x81\x5f\xb0\x5c\x88\xc3\x10\x86\x21\x0a\x87\x20\x5c\x96\x90\x9d\xa2\x18\x26\x1d\xd4\xd4\xda\x48\xfc\x8d\x24\x94\xe8\xdb\x56\x39\x22\xe8\x36\x13\x4b\x90\x46\x36\x34\xe8\xbd\x5c\xdd\x84\xf0\xd4\xcb\xd3\x3c\x9c\xcf\xcd\xf5\x89\x63\x18\x71\xf8\xe8\x0d\xe8\xcd\x27\xe8\x08\xdc\xe0\x79\x8a\xd6\x76\xe6\x71\xd6\x69\xb9\xde\x0c\x49\xd6\xca\x3c\xc4\x7b\x97\xc3\x6f\x41\x6e\xab\x80\xb3\x11\x95\x51\x96\x26\xe3\x40\xab\xb5\x5b\x9d\x41\xb4\x9b\x80\x8d\xac\x10\x27\xa5\x87\x29\x48\xd3\x81\x46\xd7\x4d\x85\x19\xb7\x3d\x3e\x39\xc7\x1a\x61\xe0\x61\x89\x06\x88\x52\x9d\xdd\x72\xc2\xbe\x07\x61\xef\x9b\x46\xf5\x0d\x83\xa2\x28\x53\x77\x15\x05\xe4\x49\x91\x01\xb6\x6d\xdb\x02\xb8\x6e\x98\x5a\x49\xb7\xb0\xd7\xf0\x76\xad\x1b\x5d\xe3\x4d\xcd\x31\x3e\x08\xdf\xac\xb0\xbf\xf2\x0e\x07\x00\xcb\x18\x1d\xa7\x43\xe6\xa7\x22\xd3\x3a\x30\xed\x1a\x33\x15\x75\x8b\x0c\xc0\x77\xdd\xdc\x3f\x5c\xd7\x5f\x4c\xf9\x86\x71\x91\x31\x5b\x15\x2b\x8c\x63\x05\xbb\x2e\xee\x39\x05\x0a\x3b\xc7\xf2\x74\x12\x15\x28\x4e\x9e\xe8\x3a\xe1\x68\x19\x8a\x9e\xca\x5b\xa9\xbd\x65\x28\x8a\xcc\xf5\x3c\xc3\x60\x8f\x6d\x86\xc2\x31\x4d\x1d\x0f\x61\xd9\xb6\x2d\x77\x2b\x37\xd1\xab\x35\xd1\xf2\xb6\x1b\xfb\x61\xc3\xa7\xeb\x8c\xb3\x3b\x19\x8f\xba\x1b\x8c\x33\x61\xbb\xec\xd3\x22\x0a\xd2\x10\xd0\xf3\x3e\xdd\x61\x62\x9b\x2f\x45\x51\xf8\xb4\xb9\xc9\x84\x5f\x96\x36\x69\xea\x17\x6d\x3d\x22\x02\xf9\x40\x57\xd6\x7b\x0e\xb0\xd9\xfb\x00\x13\x6d\x05\xb3\x24\x37\xa8\x68\x66\x3d\x9b\x12\x7b\x18\x16\xc5\x92\xdb\x77\xf6\xe4\xda\x99\xd8\x95\x0d\xbd\x4a\x85\xdc\x46\xb9\xc5\xd1\x36\xc9\xe9\xfb\x06\x8a\xb5\x90\x88\x11\x26\x96\x62\x22\xc2\x2a\xc2\xcc\xf7\x56\x35\x97\x5d\x63\x0d\x43\x67\x89\x4e\x82\xc9\x9d\x1c\xcd\x1d\x90\x26\x2a\x7a\x64\x11\xb2\x93\xdd\xe2\xd7\x20\x8b\xa8\x63\x55\xfd\xbc\x92\xca\x56\xa4\xd0\xad\x1c\x80\x16\x51\xee\xa0\xb7\xd3\x16\xe3\x00\xa5\xb1\xc6\x9f\xd7\x34\xae\x11\xd2\x91\x8a\xde\x95\x4b\x9e\x9d\x65\x5c\x8e\xf8\x8a\xa1\x11\xc5\x7f\x0e\xd6\x54\x44\x08\x83\x6f\x31\xda\x93\xeb\x7b\xf7\x47\xc1\x09\x76\xaa\xdf\x31\x7c\x26\xdc\xd9\x99\xe3\xb4\x84\x48\xfb\x12\xa3\x8a\x35\x13\x8a\xbb\x34\xdb\x62\x58\x2e\xec\xf5\x45\x51\x66\x03\x3c\x3a\x43\xee\xc5\x5c\x7f\x5b\x84\x97\xd2\xdf\xfc\x40\xe6\x6e\x9e\x79\x95\x01\x42\x36\xe2\x8f\x66\x56\x84\x15\x44\x1a\x29\x5e\x0d\xe6\x93\x2c\x88\xd2\x69\x8c\x54\x73\x9d\x4d\x9f\x0a\x23\x74\x8c\xf0\x96\x11\x63\x8d\x79\x5f\xf0\xc4\x3f\x6d\x04\x7d\x86\x9f\x45\x25\xb3\x72\x3d\x69\x07\x70\x1c\x68\xde\xb1\xbb\x0c\x47\x58\x98\x2d\x71\x8d\xca\x3f\x73\xc7\x25\x55\xfb\xa1\x4a\x85\x12\x9d\x34\xed\x34\xd7\xe4\x05\xdc\xbc\x39\xb1\xcf\x9e\x82\x21\x4f\x6e\x6b\x65\xe3\xe7\xa2\x44\x36\x69\xa2\xf2\xa0\x9c\xb7\x2a\x3e\x11\xa5\xd9\x7d\xd5\xa3\x69\x21\x09\xe6\x5e\xbd\xbf\xdb\x45\xd7\x0c\x58\x0e\x07\x5d\x85\x30\x5f\xd0\x5a\x3b\xbb\xe2\x50\x9c\xe1\x4a\x85\x3f\xdc\x8d\x0f\xe9\x54\x2e\x1e\x63\xa5\x1a\x03\xd3\x72\x17\x91\x59\x27\x4c\xc4\xa7\xc3\x45\xa3\xef\x96\x38\x4d\x03\x61\xc4\x69\x05\x7b\x85\x70\x54\x0e\x72\x85\x02\x16\x58\x64\x7b\x9b\x29\x76\x48\x6c\xdd\x68\xe8\x5e\x89\x91\x29\x78\x0b\xa7\xbe\xde\x15\xd9\x3c\x6a\x4c\x6b\xba\x43\xe3\x7d\x51\x50\x0e\x39\x85\xf2\xd9\xc1\x57\x70\xee\x8d\x82\x60\x74\xb7\x6c\x54\x99\x9b\xa8\x3e\x7c\x5e\x59\xfc\x02\xb3\x31\x71\xbc\x64\x59\x54\xbb\xbf\x0c\x1f\x5b\xd2\x30\x5a\x49\xf5\xa3\x64\x9c\x5a\x11\x75\x95\xef\x6c\x2e\x4e\xf2\xdd\x19\xac\x46\x13\x4c\x56\xb9\x3f\x91\x44\xfe\x9c\x2c\xf2\xb7\x42\x6d\xc9\xdd\x1f\xe0\x95\xf7\xc4\xd1\x8e\xdc\xdc\x2b\xf1\x04\x4d\xa4\x42\x1d\x96\x0d\x9e\xfe\xb0\xc8\x8f\x77\x27\x17\x4e\xf7\xdb\x78\x22\xdb\x9b\x6d\xac\x18\x4d\x3a\x1c\xcb\xb6\xc7\xc6\xc6\x17\x13\x59\x20\xd9\x58\xcb\x78\x24\x6a\x98\xf2\x3e\x34\x89\xa2\x27\x8a\xa9\x0f\x88\x02\x26\x8c\x03\x61\x57\xde\x24\xb2\x64\x33\x9f\xb8\x43\xa1\x73\x95\xf0\x4d\xe6\x8d\x52\x6a\x94\x6c\x44\x68\x0d\x4e\xc2\xcd\x1a\x4a\x4d\x3e\xbd\xec\xcd\x3c\x53\xa2\xd7\xc0\xc2\x4a\xf8\x44\x67\xd8\xa3\x3c\xc1\xc6\xca\xfd\x99\xb7\xcf\xe6\xab\x08\xbe\x40\xd8\x55\xb1\xa5\xa6\x8c\x46\xdc\x86\x6c\x81\x68\xc2\xaa\xc4\x18\xbe\x34\xd1\x17\xf7\x1e\xbb\xf0\x81\x14\x4c\xf8\x60\xe8\xdf\x5a\x9c\x8d\x3f\x9b\x4e\x7f\x06\x06\x9c\xe5\xdf\x6c\x93\x6e\x84\xb3\x62\x56\xd7\xff\xe2\xe3\x19\x49\xf9\x9c\xa1\x7a\xf2\x56\xdd\x04\xd0\x88\x33\xa0\x4d\x37\x7b\x16\xb1\x6c\x53\x48\xcd\x34\x10\xde\xd5\xce\x93\xc9\xbf\xff\x6a\xe0\xdf\x00\x00\x00\xff\xff\x46\xd8\x61\x0e\x43\x22\x00\x00") + +func fontsNancyjFancyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsNancyjFancyFlf, + "fonts/nancyj-fancy.flf", + ) +} + +func fontsNancyjFancyFlf() (*asset, error) { + bytes, err := fontsNancyjFancyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/nancyj-fancy.flf", size: 8771, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsNancyjUnderlinedFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xcd\x8e\xdc\xa8\x13\x3f\x8f\x9f\xa2\xd4\x89\xe4\xcb\xff\x8f\x94\x95\x76\x55\x9b\x53\x3f\x82\xaf\xdc\x8c\x83\x3b\xd3\x9b\xe9\x21\x9a\x76\x12\xe5\xd2\xcf\xbe\xa2\x28\xa0\x8c\x3f\x7b\x66\xb4\x4e\xc6\x06\x1b\xea\xf3\x57\x45\x41\x9f\x9e\x4e\x7f\x98\x8f\x80\xf0\x17\x7c\xfa\x13\xfe\xff\x09\xfe\xae\xaa\x87\x87\x87\x07\x00\x78\x36\xcf\x5f\x7e\xff\xa3\x4e\x4f\xa7\xaa\x7a\xf0\xdd\x4b\x6f\xc1\x9c\x86\xfe\x05\x86\xc7\x1e\x9e\xdc\xd7\xf3\x33\xb8\x13\x18\xf8\xe5\x2e\xe6\x19\x7e\x3d\x3a\x00\x73\xfd\xd6\x5b\xb8\xf4\x30\x38\xb8\x98\x6f\x3d\x3c\xf6\x2f\x60\xfc\xfc\xeb\xf9\xab\x82\xe1\xf1\x7c\x85\xf3\x95\x08\x9c\xdc\xf3\x00\xc3\xa3\x19\xe0\x8b\xb9\xf4\xe0\x7e\x0c\x9e\xda\x79\x50\x90\x86\x5d\x7e\xc3\xe9\xfc\x72\x1d\x2a\x2f\x90\x19\x86\xfe\xf2\x7d\x00\x33\x80\x81\xd3\xf9\xeb\x53\x3f\x10\x8d\xff\xc1\xd5\xc1\x53\x6f\x7e\xf6\x9e\xaf\x79\x72\xcf\xbd\x22\x25\x20\x5c\x3f\xcd\xe5\xfb\xef\x97\xa3\xf9\x72\x55\xdd\x0f\xd5\xdb\x1f\x55\xf5\xf1\x23\x1c\x97\x6f\xce\xb9\xd0\x3a\x56\xb6\x81\x63\x85\x18\x6f\xd4\x05\xa0\x31\x71\xa0\xef\xd2\x17\xfa\x18\x9f\x81\xf5\xf2\xd3\xd1\x95\xfa\xb1\x41\x43\x02\x0d\xe2\x49\x97\x7f\x87\xe8\xff\x8f\xdf\xa5\x71\xce\x8d\xc9\x31\xc1\x0f\xf4\x1f\x8e\x95\xb2\x7e\x4a\x53\xc3\xb1\xd2\xf8\xc1\xb9\x0f\x4e\x41\x1c\x40\xa4\x5a\x4c\x03\xc4\x34\x37\xa5\x4b\xaa\x62\x03\x40\x9c\xbd\x38\x80\x00\x16\x6b\xea\x68\x6c\xb8\x1d\x34\xf5\x6d\x3f\xda\x77\xe8\xbd\x1f\x1d\x94\x01\x00\x4d\x5f\x9c\x9b\x63\x13\x4d\x62\x11\xbb\x44\x0e\xdb\x1a\x05\xed\x2e\xd9\x0b\x9b\x36\x0d\xf3\x7c\x5a\xec\xc8\x2e\xd0\x92\x56\xad\xde\x60\x64\x93\x83\x55\x72\x70\xbe\x09\x2f\x83\x41\x12\x3a\x2a\x8c\x2c\x4f\x7c\x6a\x54\x61\x9e\xf6\x72\xcf\x78\x59\x23\xba\x40\xb8\xa5\x01\x5e\x2b\x1c\x3d\x15\x33\x40\xbd\x08\x13\x32\x3d\xb1\xed\x94\x9f\xa6\x48\x7e\x4f\x11\x91\x24\x3b\x56\x9e\x0c\x22\x89\x73\xac\xbc\x63\x11\xa1\xd5\xcc\x29\x13\x58\x37\xbe\xc0\x6c\x98\x11\xe5\x04\x01\x44\x1c\xbf\x15\x63\x17\xe0\x93\xe3\xa0\xb8\x87\xb8\x21\x82\x37\xd5\xdc\xf8\x7d\x29\xc9\x4c\x73\x2c\xc9\xcc\x80\x65\x49\x26\xb7\x1c\xf0\xd2\xed\xc0\x60\x66\xf3\xb1\x8d\x33\xf0\x41\xc0\x9e\x5b\x09\x15\xab\x12\x18\x2f\xb7\x01\x86\x94\x52\x04\x0a\xef\xd2\x06\x62\xd6\xb1\x75\x68\x6a\xac\x6b\x46\x87\x87\x97\x07\xe2\x5a\x8c\x52\xb2\x80\x95\x87\xc5\x1c\x7f\x3c\x39\x4c\x44\x0f\xab\xf0\xa6\x0d\x41\x61\x8c\xb1\x94\x1c\x50\xe8\xa6\x20\x62\x3e\x08\xb3\x90\x86\xe6\x08\x82\x27\x98\xcc\xd9\x26\xcf\xa9\x90\x64\x37\x08\x72\xf6\x61\xfb\xb2\x99\x8c\x31\x19\x00\x73\x2d\xbb\x48\x10\x13\x3f\xa9\x5e\x67\x8c\x51\x13\x09\x61\x8f\x84\x9c\x6e\x17\x08\x22\xb6\x4c\xd0\x9b\x25\xc4\x6e\xab\x63\xfa\x5d\xb6\x21\x36\x02\x7e\x19\x7d\x19\x7c\x19\x7b\x31\x41\x2d\xae\x0d\x24\x21\x39\x45\x53\xba\x0c\x29\xa7\x33\x96\xf1\x37\x92\x90\xd1\xb7\xad\xb2\x20\x18\x16\x15\x4f\x10\x47\x36\xb4\x2a\x7a\xb9\x9d\x40\xb8\xf4\x32\xc7\xe1\x56\x6c\x8a\xb4\x01\x3b\xd3\x49\xc8\x97\xd1\x90\xd1\x8c\x9c\x2d\x81\x1a\x34\x4e\xe3\xda\x4a\x3d\xce\x31\x86\xaf\x3d\xa9\x69\x21\x68\x69\x0d\x23\xbb\xf1\xe2\xd5\x71\x26\xf7\x31\x18\x6c\x85\x4d\x26\x90\x83\x36\x00\xae\x33\x61\x76\x0d\x62\x75\x01\x8f\xb0\x84\x97\x26\xa6\x2b\x38\x1c\xb2\x0a\xce\x95\x72\x8d\x56\x83\x94\xa7\x82\x83\x2d\x33\x88\xe9\x09\x73\xaa\xd2\xce\x2f\x41\x69\x1d\x84\xb4\x16\x96\xe8\x9e\x32\x08\x2a\xc4\xcc\x54\x73\xa8\xc5\xd0\xf6\xc1\x6d\x72\x46\x8d\x5f\x96\x3a\x6b\xcb\x5a\x60\x13\x6c\xc5\xab\x56\x30\x96\x09\x9c\xb8\x0a\xa2\x2f\x2d\x27\xae\x30\x4c\xc5\x4a\x0c\x27\xb1\x30\xc7\x68\xd9\x64\x02\x1d\xb9\x1d\x4c\xc6\x3c\xf6\x98\x4c\x2a\x22\xf5\xc8\x96\x98\x6b\x2b\xce\x4b\x38\x5d\x41\x26\x3e\x89\x9a\x76\xd9\x06\x8c\xf5\x60\x2a\xf6\xaf\xfc\x52\x76\xf6\x99\xea\xcd\x8c\xb8\xa0\xd9\xac\x69\x14\xb1\x51\xb0\xe5\x13\xdd\x08\x18\xb3\x4f\x42\x8d\x5c\xaf\x9a\x8c\xe5\x88\xd5\x3b\xdc\x0d\xe3\x11\x81\x15\x4d\x8a\x7d\x49\xb1\x43\x29\x4b\x17\x90\x7b\x12\x90\xd9\x68\xd2\x26\xeb\x28\x2e\xda\x69\x59\xda\xad\x32\xab\xc2\xf9\x26\x2c\xc9\x4d\x9d\x54\xe4\x60\x92\x90\x94\x73\xb7\x18\x4c\x02\x66\x5f\x7b\x0e\x80\x33\x81\xd4\x19\x25\x63\x89\x52\xb0\x08\x27\x59\x69\xac\x75\x6d\xda\x19\x15\x3a\x95\x2e\x7c\x43\x04\xdf\x61\xba\x39\xbc\xaf\x31\x88\x78\x6f\x12\xde\x9b\x75\xe7\xdf\x95\x4d\xd9\x27\x6f\x8c\xdc\x91\x2a\x73\xb1\x64\x3b\xee\x90\x36\x9a\xb3\x1c\xab\xa3\xc5\xb6\xec\xbd\xd7\x07\x48\xbb\xf2\x19\xcf\x4c\x18\xf1\x82\xd7\x89\x62\xfa\x50\xc7\x52\x50\x54\xcc\x91\x7d\x50\x5a\xd6\xff\x1b\xe9\xdb\xa2\xac\x1a\xc5\xfe\x6c\xb3\xb9\xb1\x81\x9b\x44\xfc\x06\x54\x25\xaa\xda\x3d\x2b\xdb\x3a\x83\xb8\x82\x41\x2a\x85\x7d\x9b\x52\x56\x8a\xf8\x7a\xbd\x9c\x29\xc2\x74\x26\xa6\xa9\xdc\xca\x9c\xc8\xf8\x91\x99\x67\x85\x92\x5f\xed\xfd\x51\xb2\x9c\x8d\xf8\xa0\x19\x31\x25\xab\x24\x77\x7a\x5c\x25\x68\xcb\x20\x15\xc1\x3e\x46\xd4\x9c\x4f\x56\x08\xbf\xda\xd9\x38\x82\x91\x2c\x27\x55\xda\x76\xa8\xbc\xdd\x88\xad\xbc\x33\xdc\x91\x7d\x9b\x99\xa3\x94\xe9\x13\x71\xb6\x1c\xd7\x5d\xe4\xd7\xea\x74\x24\xc4\x4d\x3a\x68\xd1\x5d\xd4\x95\x9a\x72\x23\x37\x95\x29\xaa\x3c\x7b\x36\x33\x7e\x2e\x4a\x04\x94\x84\xd2\x8e\x8c\x13\x55\x7b\x48\x31\x9e\xf5\xbf\xfb\xc0\x02\xe6\x26\xbc\x43\xf7\x67\xbe\x7c\xf7\x90\xaf\x71\xb9\xa1\xd5\xf4\xcc\x64\x5a\x6e\x14\xea\xa8\x7c\x08\x80\x01\xe0\xb9\xd4\x90\xe7\x8f\xb8\x99\x74\x60\x7c\xac\x82\x68\xd7\x09\x23\x72\x09\xb3\x6d\xd3\x75\x89\xbd\x1d\x98\xb0\x52\xe3\x13\xd3\x55\xc2\xa2\xf0\x0a\x67\x29\x24\x30\xcb\xf6\x3a\x53\xec\x90\xd8\x4f\xb2\x78\xaf\xc4\x2a\xd6\xe0\x64\xe1\x43\x2c\xe2\x84\xcd\x45\xa3\x3c\x43\x4c\xa4\xde\x88\x82\x50\x79\xbb\xdb\xed\x76\x53\x88\x37\x0a\x21\x5e\xeb\xee\x45\x01\xec\xcf\x9f\x74\x9c\x5f\x1c\x32\xcc\xd6\xd3\x8b\x03\xf9\x76\x0b\x1f\x96\x45\xf5\x79\x33\xaf\x54\x07\x10\x25\xa7\x8a\xa2\x16\x07\xd6\x93\x48\xb8\xab\xf4\x87\x32\xde\x83\xc1\x3a\x65\x93\xc9\xda\xf0\xc7\x92\xf0\x5f\x90\x85\xff\xee\x38\x2a\x7e\x47\xaf\xbc\x05\x47\x3b\x62\xb3\xb4\x0c\x55\x72\x49\x68\x10\xc4\x41\x50\x87\x90\x53\x88\xfc\x0d\xf1\x96\xe8\x67\x8f\xbf\x4b\x04\xf8\xeb\x16\x22\x00\xa2\xa1\x5e\x63\x6b\x19\xad\x7b\xd6\x96\x25\x89\x35\x65\x15\xa7\xc6\xf9\x6c\x8f\xad\xf9\xa7\x22\x2e\x3b\x78\x81\x6d\xe4\x1b\xd1\xb0\xcd\x7d\x59\x45\xa0\x48\x60\xeb\x75\x68\x98\x12\x56\x99\x70\xaa\x35\x15\x6f\x89\xe3\xfe\x68\xd7\x7a\x5d\x74\x46\xa1\x35\x0a\x3a\x44\xbf\x13\x55\xc8\xdc\xbc\xa1\x74\x59\xe9\xef\x8c\x40\xdb\xa8\xa8\x81\x4f\x2f\xe9\xa7\x21\x4b\x1e\xa5\x01\x1e\x2b\xf7\x47\xe0\x3e\x9b\xaf\x66\xf2\x05\xc2\xe2\x1c\x28\xd4\xf4\x54\x2e\x29\xb2\x80\x18\xb0\x2a\xb1\xb2\x09\x5d\x9f\x19\xc5\x2e\xfd\x30\x07\x36\x95\xbe\xf1\x2b\xd0\x39\x47\xb7\x7d\x12\x4d\xb5\x5b\xd1\x95\x3f\x01\x07\xb3\x06\xd9\x3f\x47\x3c\x2b\xd4\x31\x66\xb0\x2b\xbe\xea\x09\x80\x46\x9c\x41\xf9\x70\x03\x65\x89\xed\x01\x0e\x36\xd5\xf2\x33\xa8\x5a\x6e\xcf\xe3\xe6\x78\xac\x8a\x7f\xff\xd5\x8b\x7f\x03\x00\x00\xff\xff\x8d\x44\x2c\x65\x74\x20\x00\x00") + +func fontsNancyjUnderlinedFlfBytes() ([]byte, error) { + return bindataRead( + _fontsNancyjUnderlinedFlf, + "fonts/nancyj-underlined.flf", + ) +} + +func fontsNancyjUnderlinedFlf() (*asset, error) { + bytes, err := fontsNancyjUnderlinedFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/nancyj-underlined.flf", size: 8308, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsNancyjFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xcd\x8e\xdb\xb8\x0f\x3f\x8f\x9f\x82\x48\x0b\xf8\xf2\xff\x0b\xe8\x02\xbb\xe0\xf6\x94\x47\xf0\x55\x37\xcb\x95\xd3\xc9\x36\x89\x8b\x89\xdb\xa2\x6f\xbf\x20\x45\xc9\xb4\xfc\x99\x99\xc1\xa6\x9d\x98\xb6\x25\x7e\xfe\x48\x51\xca\xe9\x72\xfa\xc3\x7d\x04\x84\xbf\xe0\xd3\x9f\xf0\xff\x4f\xf0\x77\x51\x3c\x3d\x3d\x3d\x01\xc0\xcd\xdd\xbe\xfc\xfe\xc7\x9c\x2e\xa7\xa2\x78\xa2\xdb\x6b\xeb\xc1\x9d\xfa\xf6\x05\xfa\xe7\x16\x2e\xdd\xd7\xf3\x0d\xba\x13\x38\xf8\xd5\x5d\xdd\x0d\x7e\x3d\x77\x00\xee\xfe\xad\xf5\x70\x6d\xa1\xef\xe0\xea\xbe\xb5\xf0\xdc\xbe\x80\xa3\xf9\xf7\xf3\x57\x03\xfd\xf3\xf9\x0e\xe7\x3b\x33\x38\x75\xb7\x1e\xfa\x67\xd7\xc3\x17\x77\x6d\xa1\xfb\xd1\x13\xb7\x73\x6f\x20\x0d\xbb\xfe\x86\xd3\xf9\xe5\xde\x17\xa4\x90\xeb\xfb\xf6\xfa\xbd\x07\xd7\x83\x83\xd3\xf9\xeb\xa5\xed\x99\xc7\xff\xe0\xde\xc1\xa5\x75\x3f\x5b\x92\xeb\x2e\xdd\xad\x35\x6c\x04\x84\xcf\x4f\x77\xfd\xfe\xfb\xe5\xe8\xbe\xdc\x4d\xf3\xc3\xb4\xfe\x47\x51\x7c\xfc\x08\xc7\x1d\x5f\xc7\xc2\x57\x70\x2c\x10\xe3\x17\xdf\x02\xc0\xb1\xe8\xba\x48\xd1\x17\xbf\xe1\x97\xf1\x1a\x44\xef\xbe\x46\x82\x1f\x05\x1e\x2c\x93\x3f\xf4\x0c\x91\xfe\x8f\x9f\xa5\x71\x6a\x2e\x28\x86\x1f\xf8\x3f\x1c\x0b\xe3\x69\x4a\x55\xc2\xb1\xb0\xf8\xa1\xeb\x3e\x74\x06\xe2\x00\x66\x55\x63\x1a\xa0\xa6\xc1\x94\x2f\x9b\x8a\x15\x00\x4b\x26\x75\x00\x01\x3c\x96\x7c\x63\xb1\x12\x3a\x4c\x21\x9a\x46\xd3\x0d\x3f\xa7\xd1\xc1\x18\x00\xb0\x58\x69\xce\x90\xdd\x08\x07\x6c\xd2\x2b\xac\x4b\x54\xbc\x9b\xe4\x2f\xac\xea\x34\x8c\xe4\xd4\xd8\x04\xbf\xd4\x6c\x55\x6d\x37\x04\xf9\x14\x60\x53\xe9\xb0\x66\x5f\xc7\x02\x1c\xb2\xd2\xd1\x60\x14\x7d\xe2\xd5\xa2\x09\xa3\x2d\xe9\x3d\x13\x65\x8b\xd8\x85\x07\x75\x1c\x10\x62\x99\xae\x46\x04\xa0\x5d\x84\x09\xbb\x9e\xc5\x36\x86\xa6\x19\xd6\x9f\x38\x22\xb2\x66\xc7\x82\xd8\x20\xb2\x3a\xc7\x82\x02\x8b\x08\xb5\x15\x49\x03\x83\x75\xe7\xab\x17\x61\x46\xd4\x13\x14\x10\x71\xfc\x74\x3c\x76\x0e\x3e\x73\xde\x1d\xd2\x2c\x05\x60\x61\xbe\x26\xc7\x1a\xac\x8f\xdd\xaf\x81\x0e\x37\x08\x88\xc5\x6d\xe2\xdb\x01\xf0\xa0\xe0\x2e\x54\x42\xc3\xaa\x06\x8e\xf4\x76\x20\x50\x32\x86\xc1\x40\xa1\xac\x20\x56\x1b\x5f\x06\xd2\x62\x59\x0a\x2a\x08\x56\x04\xc0\xb5\xdc\xe4\x22\x01\x2b\x17\x8f\x43\xde\xc5\x0b\x3f\x45\x82\x53\x78\x52\x87\x58\x38\xe7\x3c\x17\x05\x54\xb6\x19\xa1\x6c\xa8\x19\x4b\xe5\x67\x8e\x21\x10\xc3\xe4\xce\x3a\x45\xce\x84\xe2\xba\xc1\x50\xaa\x8e\xf8\x57\xdc\xe4\x9c\x1b\x00\x30\x47\xf9\x45\x86\x98\xe4\x69\xf3\x1a\xe7\x9c\x99\x68\x08\x7b\x34\x94\x32\xbb\xc0\x10\xb1\x16\x86\xe4\x96\x90\xb3\xb5\x1d\xca\xee\x92\x0f\x93\xbc\xe4\xb9\x84\xc3\x04\xc3\x84\xc2\x01\x84\xcb\x1a\x72\x50\x2c\x97\xc9\x50\x6a\x1a\xe7\x05\x7f\x23\x0d\x05\x7d\xdb\x26\x2b\x86\x61\x31\x21\x86\x38\xf2\xa1\x37\x31\xca\xf5\x04\xc2\x79\x94\xf3\x3c\x9c\xcf\xcd\xf5\x81\xe3\x32\x12\xea\x63\x74\x60\x74\x9f\x54\x47\x60\x82\xc7\x59\x5c\x5b\x99\xc7\x59\xe7\xe4\xf3\xea\x92\x44\x5e\xe6\x47\xbc\x76\x85\xfa\x2d\x95\x9b\x0c\x08\x3e\xc2\x4a\x65\x69\x31\x06\x5a\xe3\xc2\xec\x12\xd4\x6a\x02\x84\xac\x84\x93\x2a\x96\x29\x38\x1c\x06\x1e\x5d\x97\x2b\x33\xa6\x63\x7d\x0a\x81\xf5\x22\x20\x96\x25\x1c\x4a\x94\xed\x68\xc9\x49\xeb\x1e\xa4\xb5\x2f\x47\xf5\x54\x40\x30\x21\x56\x24\x06\x6d\xec\x6f\xd8\xad\x54\x1d\x53\x25\x8d\x6f\x96\x6e\x60\x5e\x0e\x0b\x0a\x62\x82\xaf\x64\x95\x0a\xce\x72\x41\x92\x28\xca\x6f\x6a\x29\x58\x61\x98\x89\x9d\x17\x4e\x72\x60\x4e\xd0\xb2\xcb\x14\x3a\x06\x3a\xb8\x4c\x64\xec\x71\x99\x36\x44\xdb\x31\x78\x62\x8e\x36\x52\x8f\x70\xba\x72\x4c\x62\x12\x2d\x6d\x06\x1f\x84\x61\xe2\x2a\x99\xa3\xdf\xe4\x37\xfb\x5c\xf5\x66\x41\xd2\xc0\x6c\xf6\x30\x86\xc5\x18\xd8\x8a\x89\xad\x14\x8c\x25\x26\xa1\x27\x2e\x57\x5d\x26\x7a\xc4\x6e\x3d\x3a\x7f\x3f\x8c\x47\x0c\x56\x2c\xc9\xf6\x21\x73\x3b\x92\x51\xb1\xd2\xab\x9e\xae\x46\x13\x9a\xbd\x63\xa4\x49\xe7\xe5\x68\xb7\xc9\x62\x8a\xd4\x9b\xb0\x14\x57\x65\x32\x51\x92\x49\x43\x52\xcf\xdd\x12\x30\x49\x98\x7d\xf4\x1c\x00\x67\x12\xa9\x71\x46\xe7\x12\x97\x60\x95\x4e\xba\xc3\x58\xbb\xf5\x69\x27\x94\xd9\x94\x87\xf0\x0d\x19\xfc\x80\xeb\xe6\xf0\xbe\x26\x20\xe2\xbd\x4a\x78\xaf\xd6\x83\xff\x50\x35\x8d\x0c\xde\x96\xb9\x23\x53\xe6\x72\xc9\x37\x72\xc3\xd6\xd8\x58\xe5\x82\x39\x56\x6d\xc3\xe6\x05\xbd\x7e\x7d\x80\xb4\x0b\x9f\x89\xcc\x44\x90\x2c\x78\x8d\x6a\xa2\x0f\x65\x6c\x01\x55\xa7\x1c\xc5\x07\xa3\x75\xdf\xbf\x51\xbe\xfd\x08\xfa\x6a\x3f\xb6\x49\x6e\x6c\xd8\x26\x19\xbf\x01\x55\x8d\xaa\x7a\xcf\xca\xb6\x2e\x20\xae\x60\x90\x5a\x60\xa2\xb9\x64\xa5\x8c\x2f\xd7\xdb\x99\x2c\x4d\x67\x72\x9a\xdb\xad\x41\x12\x3b\x3f\x0a\x23\x51\xa8\xe5\x95\x14\x8f\x5c\xe4\x6c\xc6\x07\xcb\x58\x28\x7b\x25\x85\x93\x70\x95\xa0\xad\x93\x54\x25\xfb\x18\x51\x73\x31\x59\x61\xfc\xea\x60\xe7\x15\x74\x68\x27\x4d\xda\x6e\x98\x61\x9b\x11\x29\x48\x7b\x85\x1d\xd5\xb7\x9a\x39\x3a\x99\x5e\x75\x1b\xad\xda\x71\xdb\xc4\x47\xb5\x4d\x47\x40\x42\xd2\xb0\x40\xf2\x04\x26\x27\x3b\xc2\xc9\x96\x63\x74\x8a\xb1\x7c\x5d\xd4\x08\xb8\x08\x49\x7d\xc3\x52\x0a\x55\xcd\x1d\xf7\xa1\xdc\xb1\x15\x58\x0a\x86\x46\xd3\x16\xd8\x1e\xbb\xed\xd4\x67\x1e\xb7\xd2\x5f\x58\xa3\xfb\x8b\xec\x6b\xc9\x06\x33\x6c\xfe\x31\x00\x7c\x68\x35\xf4\x79\xe3\xe2\x36\x49\x75\x01\xa3\xe3\x14\x44\xbf\xce\x18\x51\x5a\x98\x6d\x9f\xae\x6b\x7c\x38\x24\xc6\xc6\xe4\x27\xa4\x2b\x8c\x55\xd2\x86\x8d\x28\x2b\x2c\xba\xbd\xce\x15\x3b\x34\xa6\x30\x7a\x7c\x54\x63\x13\x7b\x70\xf6\xf0\x21\x36\x71\xca\xe7\x8a\xc8\xcf\x0c\x07\xe2\x6d\x28\xa8\x86\x9c\x92\xc6\xdb\xc7\xb5\xee\x51\x14\xc0\xfe\xfa\x39\x1c\xdf\x2f\x9e\xf0\x6f\x0c\x1c\x4f\x59\x56\x95\xea\xe6\xb0\x52\x1d\x40\xb5\x9c\x26\xaa\x9a\x1d\x50\x4f\x32\xe1\xa1\xd6\x1f\xa6\xbd\x15\x39\xac\x31\x3e\xb9\xac\x0e\x7f\xa2\x89\xfc\x05\x5d\xe4\x6f\xbd\x67\x9a\x0d\xf7\x3b\x44\xe5\x2d\x38\xda\x91\x9b\x7b\x35\xce\xaa\x49\x55\x8e\x63\x3a\x44\xfa\xdd\x90\xaf\x57\xa7\x00\xa7\xc7\x7d\x9c\xe9\xf6\x6a\x1f\x5b\xae\x26\x9d\x19\xeb\xb6\xc7\xc7\x3e\x1e\x56\xb1\x42\xb2\xb0\x56\xfa\x89\x22\x7c\xf5\x58\x35\x51\xe8\x51\x98\x7a\x07\x14\x30\x63\x33\x30\x4e\x3d\xa6\x91\xad\x70\xdc\x17\xed\x5a\xa7\xb3\x9b\x51\x4a\x8d\x92\x0d\x91\x76\xa0\x06\x45\x1a\x39\xca\xe6\x1d\xfe\xce\xcc\xf3\x95\x89\x16\x50\x59\x49\x3f\x01\x79\x8e\x28\x0f\x20\xac\x3c\x9e\x79\xfb\x7c\xbe\x5a\xc1\x17\x18\xab\xf3\x9f\xd0\xcb\x73\xd8\x0c\x7b\x40\x0d\x58\xd5\xd8\xa4\x5f\x32\xf0\x73\x78\x6f\xba\xf4\x03\x1c\xf8\xd4\xf2\xc6\xb7\xc0\xe7\x1b\xcd\x62\x1b\x98\xea\x2c\xf7\x6c\xd9\xad\xaa\xb3\xe2\xd6\x70\xff\x39\xe2\xd9\xa0\x8d\x39\x83\x4d\xf6\xd6\x4e\x00\x34\x92\x0c\x86\xd2\x0d\x8c\x67\xb1\x07\x38\xf8\xd5\xad\xde\xa3\xf4\xb1\xc8\xfe\xfd\x57\x0f\xfe\x0d\x00\x00\xff\xff\x77\xef\xd1\x81\x5c\x20\x00\x00") + +func fontsNancyjFlfBytes() ([]byte, error) { + return bindataRead( + _fontsNancyjFlf, + "fonts/nancyj.flf", + ) +} + +func fontsNancyjFlf() (*asset, error) { + bytes, err := fontsNancyjFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/nancyj.flf", size: 8284, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsNipplesFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x8f\x1c\x35\x10\xbd\xf7\xaf\xa8\x43\xae\x40\x58\x21\x11\x6e\x7d\x21\x12\x12\x42\x51\xf8\x01\xde\x20\x6d\x50\xa4\x15\x48\x90\x0b\x58\xfc\x77\x34\xdd\xb6\xeb\xbd\xaa\xe7\xee\x99\x61\xc5\x66\xd3\xb6\xbb\xed\x2a\xd7\xd7\xab\xb2\xf7\xe3\xf3\xc7\x87\x0f\xaf\xec\x8d\x7d\x6b\x0f\xaf\xed\x8b\xaf\xed\x61\xf9\xe9\x87\x77\xef\x7e\xfc\xfe\x67\xfb\xe5\x2f\x7b\xff\xfb\x6f\xf6\xf6\x8f\x4f\x9f\xff\xb6\x37\x5f\x7d\xf7\xcd\xf2\xf6\xd3\xaf\xcf\x4f\x9f\xed\xfd\xd3\xf3\xd3\x87\x3f\x9f\xec\xe1\xcb\xd7\xcb\xab\x55\xfc\xda\xba\x2e\xb5\x14\x7e\x58\x7b\x98\x59\x7b\x77\xe9\x6d\x2f\x6b\x19\x8d\xd9\xf6\xfd\xbc\x69\x6d\xff\xb9\x0c\x6b\x29\xd6\x9e\x1b\x87\xcb\x8f\x6d\x6d\xfa\x7a\xe3\x64\x64\xb4\x8d\xfb\x97\x6d\xd7\xbb\x68\x25\xec\xa3\xad\xeb\x2a\x68\xf3\x32\x55\x94\xa4\xd1\x19\x53\x61\xae\x13\x6d\xac\x36\xee\x45\x2f\xa3\x9d\xfa\xdc\xb1\x17\x5f\x5f\x7c\x79\x98\x07\x6b\x9d\xe0\xfe\xa5\x19\x6a\xfe\x68\xdb\x6c\xe4\x1a\xfd\xd8\x8c\xfd\x76\x76\x9d\x83\xfa\x48\x0d\x11\x65\x25\x06\x49\xc6\xa3\xcb\xd3\x0c\xd6\x6d\x6e\xcd\xf2\xe2\xbb\x58\xcf\xf4\x85\x5b\xa0\x37\x5a\x76\x84\xae\xeb\xce\xf6\x68\x5a\xa6\x86\x8c\x0e\x1e\xc3\x44\x7d\x59\x6e\x89\xbb\xf8\x7e\x13\x27\x56\x3e\x48\x71\x87\x07\x07\x69\x43\x90\x03\x41\x24\x84\x5e\x35\x58\x0f\x72\xee\x31\xb8\xad\xe6\xf9\xd1\x8e\xeb\x00\x99\xe0\x86\xaa\xa9\xa0\x44\xda\xe9\x88\xa2\x46\x49\xe8\x06\x35\x82\x7a\x70\x2c\xe2\x58\x16\x28\x21\x14\xcb\xce\x49\x38\xd3\x43\xbf\x44\xf7\x92\x3a\x66\x37\xac\x38\xea\x01\xc2\x11\x02\xf1\x94\xa3\x45\xeb\x98\x24\x29\xec\x01\xc1\x3c\x5a\x12\x8d\x77\xd2\x59\x50\xdb\xe8\x81\x6e\x9f\xec\x44\x7d\x5a\x4e\x02\xc1\xd8\x75\xe4\x0e\x14\x3b\x19\x9b\x55\x3a\xe9\x1f\x49\xd2\x07\xda\xe9\xcd\xf7\x6b\x5a\x12\x50\xc5\x91\xf1\x93\x81\x5d\xe7\x2c\x5d\x2d\x12\xba\x58\xd9\xd2\xf8\x73\x24\x09\x98\x72\x3a\x11\x60\x6e\xe8\x3f\xa4\xf8\x88\x2d\xb8\x4b\xe1\x59\x42\x37\xd0\xa9\x85\xa0\x53\xbe\x49\x9d\xdb\x37\x70\x22\x02\x11\x0e\xc4\xd6\x25\x93\x72\x4b\xfa\x6a\xf9\x2e\x64\xb5\x41\x01\x03\xc7\xb8\xfc\x81\x0c\xd9\xa2\xa5\x32\xe8\x3e\x3e\x3e\x26\xec\xd6\x45\x95\x7b\x39\xb8\x94\x05\x24\x50\x6e\x46\x99\xa5\x07\x23\xe3\x6a\x4c\x0b\xc9\xdc\x64\x2b\xc7\x34\x5c\xea\xab\x1a\xfc\x24\x7c\xf7\x10\x81\xfa\x42\x85\x76\x88\x30\x2a\xcc\xc8\xdc\xa1\x8f\xf3\x6d\x44\x75\x60\x30\x60\x7e\x2c\x26\xe1\x91\xd9\xa4\x0f\x09\x2e\x81\xc6\x0a\x29\x2a\x82\x36\x74\xfb\xce\x0e\x27\xc4\x80\x7b\x11\xc2\xc9\xc3\x56\xd4\x55\x77\x5b\xe1\x11\x72\xd0\xb3\xfc\x50\x12\xf8\x99\x80\xd3\x80\x98\x07\x03\x4f\x1a\x57\xae\x49\x8c\xce\x1e\x10\x58\x54\x7d\x9c\xf5\x6a\xc1\xba\xa9\xc4\xd3\x0a\xc4\x1c\x1c\x3c\xa8\x2c\x69\x71\x51\xd9\x2c\x38\x6d\x96\x71\x95\x2e\xaf\x31\xf6\xad\x6e\xd6\x06\x5d\x5e\xb7\xb5\x4b\x51\xc1\x06\x0c\x72\x03\x87\x04\x29\x1a\x9a\x25\x89\x8a\xe6\x0b\xca\x63\xae\xcc\x94\xe3\xd5\x88\x65\xe2\xe8\x58\x93\x2b\x9f\xa0\xfd\xbc\x7f\x3d\x36\x2c\x09\x4c\xd1\x17\x12\x87\x88\x55\x98\x93\xa3\xfa\x08\x04\xa7\x12\x06\x01\xcf\xcc\x93\xac\x55\x47\x05\x0b\x09\x2b\xc6\xf9\xc5\xf6\x24\x19\xcb\xa6\x46\x16\xdd\x33\xe6\xf5\x68\x0e\x6d\xcb\xbe\x1b\x56\x5f\xc8\xaa\x21\xab\x67\xe8\x47\x3a\xc9\x56\xc6\xf5\x0c\x13\x7b\x99\x11\x31\xcc\xc6\xb8\x7b\x70\x05\x2a\x0b\x9d\x0d\x63\xa3\x63\xeb\xe2\x62\x04\x24\x8b\x16\x9c\x5f\x65\x20\xb5\x91\x83\x78\xab\x5c\x13\x24\x90\x40\x60\xf0\x64\xa6\xe3\x75\xb6\x01\x54\xc3\x10\xb9\x42\xed\x83\xb2\xa4\x6f\x12\xc2\xa5\xd7\x4a\x86\xa4\xf4\x19\xc3\x5b\x46\xcc\x30\x1d\xc8\xc0\xa8\xc2\xa2\x66\xe2\xd0\x52\x43\x29\x50\x44\x2a\x01\x86\x4d\xd0\xd3\x26\x5d\x75\x05\x76\xf1\x80\x90\xf6\x0a\x21\x35\x3d\xb7\xe0\x35\xe6\x71\x23\xee\x30\x2a\x43\x69\x3d\x49\xd3\xf7\x0c\xfa\xe8\xf6\xb6\xdd\x5c\x8d\x2a\x27\x9f\x10\xf9\x41\x08\x17\xfb\x2e\xe9\x08\x33\x55\x30\x07\x5f\x2d\x19\x35\x61\x77\x93\x2e\x69\x91\x0b\x6d\x9a\x90\x75\x14\x0e\x94\x15\xab\xd1\xc1\x06\xde\xf8\x1c\x26\x34\xaf\xfb\x10\x4c\x64\x05\xc8\x46\xbf\x5e\xa7\xf1\x20\x41\x47\x24\xf3\x3a\x7a\x9a\xd4\xd7\x7e\xe0\xbc\x2c\x1b\x7f\x20\x20\xb4\x9a\x74\xd2\x4e\x63\x97\x91\x2c\x5a\x04\xde\x76\x45\x51\x64\x82\x36\x16\x8f\x5c\xec\xd1\x35\x4c\xd2\x6e\x31\xa5\x53\xbc\x59\x3f\xa9\xe7\x87\x10\x72\x2c\xdb\xbd\xf6\x5c\x67\x1b\x0e\x87\xf8\xa6\xf2\x42\x1e\x3c\xdb\xfa\xd0\xd9\xfc\xe9\x3e\xa9\x2f\x19\x8c\x14\x3a\x32\x1c\x58\x28\x98\x46\x0f\x77\x21\x6b\xdc\xe4\xb1\x3b\xd4\x78\x61\x90\x7c\x80\xd4\x93\x88\xdf\x8d\x32\x81\xba\xac\xdf\x92\xbf\xe1\xbe\x1d\x57\x9c\x70\x44\x15\x69\x70\x4d\xd0\x00\x57\x90\xa0\x1b\xa2\x52\x65\x3c\x7a\x65\x72\x59\x16\xe1\x2a\x77\x6a\x88\x7f\x8d\x7b\xb5\xd0\x15\x71\x47\x0e\x03\xa4\x88\x38\xb5\x2a\x60\xb8\x0e\x45\x28\xb9\xce\x95\x1f\x8f\x6a\xba\x67\x4d\x6d\x13\x00\x8d\x69\x92\xf3\xac\x4c\x40\x63\x93\xa2\x8e\xd1\x79\x56\x70\x62\x56\x83\x57\x61\xd8\xf7\xd1\xfe\x0b\x21\x60\x29\x17\x9e\x44\x18\x22\x3a\x38\xbb\x79\xb6\x08\x49\x77\x12\x61\x53\xc2\x35\xfc\x91\xb5\xe4\xba\x29\xb8\xdf\x31\x61\x72\xa8\x10\x9e\x6b\xb8\x9b\x55\xb7\x0c\x16\x0e\xcd\xe4\x87\x7c\x5c\x0d\xb9\x2b\xf8\xf1\x7e\x9b\xb8\xff\xdf\x57\xd3\x78\x5d\x4a\xf9\xa7\x93\xdb\xba\xd4\xd9\xba\xea\x13\xac\x72\x4e\xc5\xe0\xaf\xbe\x02\x47\xff\x53\x7f\x5d\xc2\xbf\xff\xeb\xc5\xbf\x01\x00\x00\xff\xff\x2e\x0c\xdd\x8b\xe6\x20\x00\x00") + +func fontsNipplesFlfBytes() ([]byte, error) { + return bindataRead( + _fontsNipplesFlf, + "fonts/nipples.flf", + ) +} + +func fontsNipplesFlf() (*asset, error) { + bytes, err := fontsNipplesFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/nipples.flf", size: 8422, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsNtgreekFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\xfb\x8f\xdb\xb8\x11\xfe\x9d\x7f\xc5\x87\xc5\xa2\x91\x50\xed\x2a\x9b\x34\x38\x24\x58\x2f\x9c\x7b\xa5\x77\x6d\xef\x7a\xbd\x6b\xd0\x16\x42\x18\x5a\xa2\x6d\xdd\xca\x92\x2b\xc9\xd9\xdd\x83\xfe\xf8\x82\x4f\x51\x2f\xaf\xbc\xe9\x19\xb6\x44\x51\xe4\xcc\x70\xf8\xcd\xc7\x21\xbd\xce\xd6\x2f\xd8\x39\x5e\xe3\x0b\x5c\xbd\xc4\xd5\x2b\xbc\x7c\x4e\x7e\xf8\xe5\x5d\xc9\xf9\x2d\x56\x0f\xf8\xb2\x3c\xc4\x1c\xdf\xb3\x5b\x7e\xc7\x1e\x2e\x2e\x56\xac\xe2\x09\x8a\x1c\x3f\xd7\x2c\x4f\x58\x99\x88\x36\xef\x32\x9e\xe7\xf8\x6a\xcb\xf6\x7b\x9e\x65\xf8\x03\xbe\x63\xf2\x31\x25\x3f\x1d\x78\x55\xa7\x45\x5e\x81\xe5\x09\xe2\x62\xb7\xe3\x79\x5d\xa1\xe4\x1b\x56\x26\x69\xbe\x41\x5e\x6f\x84\xa6\xcb\x75\xb6\x46\x5d\x60\xbf\xfa\x55\x69\x5a\xe6\xfc\xb0\x63\x79\x7e\x79\xb8\x63\x35\x2f\xb3\xa2\xb8\x8c\x19\xf9\xb6\x28\xb1\x4e\x37\x19\xaf\x51\xf2\x8c\xb3\x8a\xe3\xc5\xe5\x73\xf2\x35\xab\xf9\x1b\xe0\xea\xf5\xeb\x3f\xe1\xed\xbe\xc4\x0b\x42\xbe\xb9\xdf\x67\x2c\x67\x42\x37\x8a\x35\xd6\x69\x59\xd5\xc8\xd2\x9c\xbf\x21\x62\xc0\xb8\xc0\xd9\x8e\x6d\xd2\x18\xf9\x61\xb7\xe2\xe5\x19\xd6\x52\x74\xc6\x91\x26\x3c\xaf\xd3\x75\x1a\xcb\xce\x84\x01\xc0\x05\xaa\x6d\x71\xc8\x12\xb0\xec\x8e\x3d\x54\x58\x71\x7c\x64\xcf\x02\xd9\x29\x2f\xee\xc8\xb9\x6a\x54\x6f\x39\xce\xb6\xac\x4c\x56\x19\xcb\x6f\xcf\x70\x71\x81\x7d\x99\x8a\x01\xb3\x0a\x0c\xb2\x36\xc0\xea\x50\x23\x66\xf9\xb3\x5a\x88\xa9\x76\x87\x6a\xcb\x13\xf2\x5a\x49\xd8\xf2\x74\xb3\xad\x85\xc5\x0c\xf1\x96\x95\x2c\xae\x79\x49\xbe\x38\xf2\x32\x40\x5e\xd4\x48\xf3\x38\x3b\x48\x87\x26\xbc\x8a\x79\x9e\xf0\xb2\x22\x57\x2f\x65\xb7\x1d\xbb\x97\x23\x47\xc6\xf3\x4d\xbd\x85\xc7\xef\x4d\x63\x3d\x21\xf2\x75\xe5\xe3\x8f\x60\x58\x1f\x92\x0d\xc7\x9a\xc5\x75\x51\x92\xab\x57\x52\x42\xc2\xd7\xec\x90\xd5\xca\xd8\x5d\x91\x70\x39\xf0\x7a\x9b\x56\x58\x17\x79\x0d\x2f\x4b\x6f\x39\xce\x2e\x76\xb8\x7a\x75\x26\xc0\x21\xe4\x8a\x09\x17\x72\x7d\xf2\xf2\xb9\x94\xa2\x3c\x2d\xcc\xef\xa8\x25\x44\x61\xed\x96\x3f\xac\x0a\x01\xa8\x1d\xdb\x57\x6f\x08\x79\x9b\x65\xa2\xae\x12\xcf\x02\x1a\xf5\xb6\xa8\x38\xd2\x1c\x95\x41\x1e\xbf\x8f\xf9\xbe\x7e\x43\x08\xcb\xf6\x5b\x31\x4f\x0b\xbc\x0d\xc4\x3d\x63\xbb\x55\xc2\xc4\xf3\x5f\x83\x0c\xc0\x7e\x9b\xc2\xf9\x2c\xf0\x6d\xb0\x06\x50\x16\x87\xcd\x16\xab\x92\xb3\x7a\x2b\xbc\x81\x05\x3c\xb2\xe2\x35\x53\x8d\xbe\x0c\x56\x00\x76\x07\xd3\xe9\x6f\xc1\x0e\x40\xdc\x97\xf5\x55\x10\x03\xa8\x76\x45\x51\xbb\xc2\x16\xf0\xc9\x86\xed\x76\xca\xae\x77\xc1\x06\x40\x6e\x65\xfd\x10\xe4\xc2\xae\xaa\x27\xeb\xdf\xc1\x03\x00\x16\x1f\x6a\x0e\x16\xc7\xc2\x47\xea\xc5\x33\x92\xf0\xac\x56\xb2\xbe\x0e\x12\x00\xf7\xa9\xe9\xf4\xaf\xe0\x1e\x40\xb1\xe3\x1b\xe6\xca\xba\x0b\xee\x00\x6c\x4a\xf6\xa9\x27\xeb\x23\xe1\xfb\x2a\xcd\x8a\x1c\x0b\x7c\x13\x70\xd9\x37\x8d\x4b\xf9\xfc\x63\x50\x88\xc1\xc4\x65\xba\xaf\x05\x9c\xb5\xca\xef\x65\xd7\x24\x65\x25\xaf\xd2\xca\x51\xf2\x81\xfc\x66\xfd\xf5\x9f\xe0\x37\x31\x26\x6b\xd7\xdf\x83\x7d\x2b\xcb\x4c\xc1\x02\xbf\x12\xdd\x03\x0b\xfc\x39\xd8\x8a\x79\xd8\x16\xfa\xf9\x1f\x41\x09\x60\x9d\xe6\x2c\x43\x95\x6e\x76\x5a\xf2\x7b\xd2\x9a\xf2\x53\xf0\x5f\x21\x55\xbf\x5c\xe0\xe7\xa0\xb2\xa3\x5f\xb1\xd2\x28\xff\x44\xd2\xc2\x18\xf6\x5d\x20\x74\xd7\xec\xa0\xdf\xfd\x12\x08\x57\x94\x2c\x15\x54\xb6\xe7\x65\x5a\x24\xa2\xfa\x0d\xb9\x65\xfb\xbd\x92\xfa\x97\xe0\x16\xc0\xc1\xfa\xe9\x9f\x81\xe8\x2c\x45\x56\x87\x95\x1e\xd3\x02\x94\x90\xf3\xe5\xd4\x77\x49\x00\x2c\x09\x28\x96\xa4\x41\x63\x2e\xb4\xd1\x75\x1e\xf5\x4d\x13\x40\xb5\x36\x1d\xd4\x7b\xf8\x1e\x44\x93\xf7\xc0\x7b\x38\xef\xdb\xfb\x39\x86\xf5\xa6\xd0\xd6\x52\xfd\x13\xa2\x1b\x34\xf2\x27\xf5\x9b\x77\xfe\xd1\x37\xba\xbe\x69\x75\x74\x14\xba\x5a\xa9\x79\xa1\x24\x89\x62\x28\xeb\x7d\x39\x1e\xcf\xd6\x46\xb2\x65\x64\xdb\xfa\x72\xa0\x4a\x6f\xa8\x44\x4b\x8d\xae\x96\x76\x64\xca\x47\xa0\x54\x3a\x11\x21\x42\xf9\x2a\x84\xea\x2a\xee\x4a\x75\x28\x1d\x19\xd2\x10\xc6\xd9\x1d\xcb\x1d\x5f\x49\x43\xa8\xf6\x52\x28\x6d\x93\x76\xe2\x47\x2b\x8c\x22\x0a\x23\x39\x0c\x7a\x03\x5c\xcb\x51\x50\x1a\x46\x61\x57\x8a\x2b\xda\x5c\xc2\x70\x49\xc2\x10\x9d\xba\xce\x45\x5c\xdb\x9f\xe7\x75\x9f\xf5\xaf\x5b\xe1\xfb\x93\x8d\xba\x38\x11\x36\x0a\x57\x45\xe2\x51\x18\x22\xf0\x15\x89\xf7\x51\x38\x82\x9f\x01\x8e\xba\x05\x17\x48\x16\x2a\x16\x26\x98\xe8\x35\x74\xc9\x79\xd7\x07\x1a\xf0\x4b\xd2\x84\xbd\x80\x18\x17\x49\xc5\x47\xea\x17\x9f\xde\xdc\x9e\x3f\x51\xff\x68\x40\x1a\x01\xc2\x85\x50\x28\x9b\x44\x1b\x34\xda\x8e\xe8\xef\x80\xcd\xe0\x4a\x31\x04\x0c\x4b\xd8\x02\x95\x05\x85\xb3\x63\x23\x92\x28\x17\x4d\x2f\x5a\x9e\x69\xc9\x66\x6c\x44\x54\xeb\x17\xfe\x33\x71\x48\x55\x14\x86\x50\xda\x84\x7e\xe9\xe3\x66\xcc\xc7\xc3\x88\x6c\x67\x04\x3d\xd7\x78\x46\x07\xd5\x3a\xe4\xac\x4d\x8f\xc8\xa9\xd3\x70\x13\x82\x1a\xed\xaf\x42\x21\x2f\xa4\x2d\xf4\xa4\xcb\x1c\xda\x98\x8e\xc8\xde\xf0\x1b\x35\x6c\x3d\x58\xe8\xc1\x9e\x6c\xac\x8a\x0c\x8a\x3e\x20\xb4\x8e\x67\x66\x8a\x3d\xed\xe2\xe3\x13\x3a\x02\x71\xc8\x6e\x82\x1b\x65\x37\x4f\x53\xea\xd3\x41\xa7\xc9\x57\xf1\x9b\x03\x43\xef\x34\x1b\x07\x30\x56\xfd\x35\x68\x03\x34\xdd\x50\xa1\xe1\xcc\xc0\xec\x85\xe3\x79\x9f\x2b\xa7\x82\x77\x92\x46\xf4\x0c\xe9\xf9\xd1\x9e\x5b\x92\x6b\x5c\x6b\x9e\x57\x31\x10\x29\x62\x6c\xad\x1b\xa7\xa1\x21\xfb\x1c\xe5\xa3\x51\xff\x09\x62\x96\xb7\xc8\xae\x35\xca\x86\x1b\xdc\x58\xfb\x5c\x8f\xf5\x2c\x52\x4a\x75\xc0\x45\xed\xc0\x44\x00\xc8\x99\xd1\xa1\xe7\x4f\xf4\x77\xdd\x42\x5b\xec\x5a\xf8\x2b\x68\x49\x1a\xf1\xe0\xc1\xf3\xa1\xc9\x48\x22\x83\x86\x54\xf9\x4b\x7e\xc2\x81\xcc\x59\x60\xb1\x0c\xd7\x48\x73\x3b\xe4\xa7\x72\x8e\x19\x21\x62\xc2\xd8\x4a\x94\xf0\x95\x35\x5e\xa7\x66\x4e\x18\x53\x93\x57\x88\xc9\x50\xfe\x8c\xf0\x49\xc3\xf7\x46\x83\x25\xc4\x07\xa9\x4c\x4c\x4e\x0b\x98\x71\x16\xeb\xb9\x43\xad\x20\x91\x2d\x87\x32\xd1\x30\xb4\x61\x90\x20\x98\x83\x46\x5a\x87\xfe\x44\xb3\x5c\x6c\x60\x28\x79\x8d\xfa\x6a\xf8\x30\x2e\xf2\x71\x22\xad\xbb\x2c\xac\x66\xb0\x9b\xd7\x99\x90\xb7\x19\x5c\x74\x3c\x83\x23\xf3\xad\x3e\xd7\x56\xb7\x05\xd5\x58\x09\x7d\x94\x3b\x01\x93\x77\xf7\x16\xd3\x27\x40\xad\x8d\x34\x28\x1e\x16\x1d\xfb\x37\xcf\xf1\xe5\x58\xa4\x19\x4f\x52\xea\x4c\x3e\xb5\xb3\x2f\x78\x53\xa7\x54\xb2\xd6\xac\x6d\x6a\xb6\xcc\xf2\xa6\xc2\x2d\xec\x21\xa0\xf7\x30\xf0\x03\x55\x83\x95\x70\x6e\xd0\x28\x66\x11\x5e\xbc\xd6\x9e\x55\x50\x13\x7e\xf8\xbd\xe0\x0c\x44\x36\x64\x80\x8e\x9a\x49\x38\x6b\xc7\xab\x95\x55\x1a\x1c\xc9\x34\x40\xd9\xfe\x09\x66\x16\x23\x1a\xda\xc4\x09\xed\x94\xa2\x33\xa9\x47\xc0\x67\xa1\x12\x19\xa8\x20\x32\x85\x56\x09\x8c\xdc\xe8\x51\x56\xfa\x3f\xe6\x76\x8e\x1f\xec\x0a\xa3\xe3\xd1\x00\xd1\x41\xe1\x48\x51\x6f\xdd\x1e\xf3\x83\x31\xdb\xda\xdd\xd2\x69\x1b\x36\x36\x6e\xa8\x63\xbb\x6b\xfc\x9c\x6c\x6b\x48\xd3\x26\xd9\xc4\xfc\xf8\xb6\xce\x88\x0c\x63\x48\x7c\xc1\xac\x9f\x2d\x8b\x5a\x0a\x9d\x9f\xbe\xb6\x1b\x1a\x93\x54\x8e\x14\x26\xf6\x3a\x53\xe0\xf5\xa8\x04\xaf\x92\xab\x56\x14\xcd\x91\xb0\x1c\xe9\x16\xe7\x32\xe7\x48\x41\x8f\x43\x2d\xe5\xbe\xca\xc8\xcc\xa6\xdb\xa4\xfa\xd0\x39\x9e\x78\x15\x4e\x64\x04\x68\x33\x02\x1d\xc7\xd2\x40\x07\x63\xa6\x2c\x96\x2a\x99\xec\x2a\x16\x6c\x9a\x8e\xbb\xe7\x2c\x57\x4e\xd6\x64\x30\x28\xf9\x74\xa2\xcd\x71\xa7\xc3\x1c\xa0\x34\x68\xd4\x57\x06\xb7\x64\xbe\x66\xb0\x46\x3d\xc1\xe9\x0a\x7d\x26\x31\x9f\xdc\x0d\x3e\x0e\xbe\x76\xd5\xf3\x75\x04\x4c\xdf\xcc\x8a\xed\x0f\x16\x17\x9d\xb5\xd8\x54\xd2\x26\x93\x4a\x9b\x61\x61\xd8\x04\x13\xd3\x34\xdf\xc6\x40\xa3\xf1\x3e\x75\x53\x14\x20\xe7\x7b\xc4\x22\xcb\xaa\x22\xff\x1c\x3f\x7b\x99\x53\x58\x8e\x9d\x70\x74\x7e\x4d\xd3\xd9\x0f\x44\x6a\x57\x13\xb9\x75\xdd\xcb\x28\x59\xf5\x68\x50\xef\x14\x42\x79\x42\x12\xca\x10\xf2\xc5\x6a\xa9\x62\x28\xec\xac\x5e\x13\x94\x37\x9a\xeb\xb6\x99\xe9\xf5\x3c\x12\x3c\xea\xa4\x27\xe5\xaa\x5d\x41\x4e\xda\xef\x77\xc0\x72\xfa\x76\x70\x70\x53\x50\x12\xf4\xe1\x2f\xc9\x8d\x52\x10\x1d\x4f\x92\x96\xdd\x64\xd3\x09\xce\xd3\xf2\xce\x41\x4c\x1f\x07\x9b\xc5\xaa\xf4\xa3\xdf\xf1\xe3\x14\xf5\x3f\x26\x91\xf6\xb7\xfe\x6e\xb2\xa9\xb7\xc5\x4e\x81\x6a\x18\xa3\x77\xa5\x86\x04\xcc\x15\x91\x71\xa0\xbe\x4e\xf0\x55\x9f\x12\xad\x41\x8d\x4a\xc6\x5a\x76\x3c\xc1\x7d\x23\x77\x6a\xf3\x4b\x9d\x5e\xaa\x38\x69\x68\xe3\x44\x89\xbd\xcf\xe5\xac\x1b\x0b\xc3\xd9\x3b\xad\xa3\x33\x3b\xb6\x0d\xb8\xa4\x01\x6d\x8e\xc4\xdc\x9c\xc1\xea\x54\x9a\xd2\xb1\x83\xd4\xc7\xd7\xe9\x27\x86\xda\x34\x77\xb9\x49\xa2\x39\x34\x52\xf3\x0c\x95\x0c\x76\x73\xc1\x53\xb8\x6b\xb0\x79\x9a\x9d\xbf\xce\x1b\xfe\xe7\xb2\xa1\x9b\xf8\xe0\x52\x27\x3e\x3e\x7c\x43\xda\x93\xeb\xcb\x34\x77\xf5\xb6\x7b\x6d\xe8\x0d\xb9\xeb\x44\xf4\xcd\xca\xfa\x3b\x51\x3c\x7c\x30\x07\x03\x76\xba\xcd\x31\xa1\xd0\x22\xc2\xa5\xd5\xf4\xa1\x97\xa6\x0f\xa4\xcd\xd7\x6a\x73\x5a\xd8\x3f\x58\x22\x3b\x7f\x27\x6b\x75\x49\x40\xcb\xbc\xd1\x07\xb2\x9e\xfa\x37\x48\xd5\xc8\x83\x8b\xd1\x44\x16\x3a\x91\x85\xd7\x4b\x64\x8f\x91\xe1\x67\xe5\x87\x1d\x0e\xd3\x28\x96\xc6\xfb\x7a\x29\xed\xfe\x1d\x60\x0f\x96\x1f\xb1\xda\x3d\x9b\xec\x1c\x2c\x98\x23\xca\xee\xa1\x83\x7b\x52\x39\xfc\x8f\x71\xec\x62\xfe\x0a\x18\x9c\x3b\xf6\x04\xab\xe3\xc7\x4e\x65\xe7\x14\xb2\x0d\x81\x30\x0a\x85\xe0\x30\x0a\x87\x11\x34\x7d\xeb\x26\x87\x54\x25\x87\x9f\x7b\x22\x78\x54\xe2\x93\xf6\xde\x83\x04\x76\x54\xd0\xe9\x71\x3d\x9a\x78\xb8\x56\x7f\xd4\x27\xae\xad\xc4\xe0\xf1\x13\x87\xa3\x12\x9f\x74\xb0\x3f\x22\x71\xe8\x87\x93\x6c\x1c\x3b\x15\xd1\x8c\xdf\x5c\x9b\x8c\xd8\xd6\x34\x6a\x0d\xe8\x9f\x06\x2c\xc9\xff\x02\x00\x00\xff\xff\x3f\xc5\x21\x35\xb0\x24\x00\x00") + +func fontsNtgreekFlfBytes() ([]byte, error) { + return bindataRead( + _fontsNtgreekFlf, + "fonts/ntgreek.flf", + ) +} + +func fontsNtgreekFlf() (*asset, error) { + bytes, err := fontsNtgreekFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/ntgreek.flf", size: 9392, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsO8Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x4b\x8f\xdb\x36\x17\xdd\xfb\x57\x9c\x85\x16\xdf\xb7\xa8\xd1\xa4\x68\xc0\x00\x69\xe0\xa2\x8b\xa0\x40\x91\x6e\x82\xee\x35\x36\xfd\x40\x3c\xba\x03\x3f\xd0\x4e\x7f\x7d\x21\x3e\xee\x43\x22\x65\x79\x66\x84\x44\x22\x87\xd2\xe5\xe1\x7d\x1e\xd2\xdb\xe3\xf6\x7d\xdb\xe0\x03\x7e\xc6\xbb\x0f\xf8\x11\x1f\x17\x7f\x9e\x0e\xbb\x43\xd7\x1e\xb1\xa5\xee\x82\x87\x67\x7c\xa1\xd3\x86\x3a\xfc\xe1\x3d\x3e\x7d\xfc\x69\xfd\xb8\x3b\xae\x7c\xb7\x5b\xae\xdb\xc7\x65\xbb\x5e\x5e\xbf\x7f\x5e\xfc\x72\xf7\xa5\x66\x39\xec\x8e\xfe\x72\xf8\xb7\xbd\x1c\xa8\xeb\xa7\xfb\x46\xdd\x33\xbe\x5e\x77\xbe\xbb\xe0\x7f\xdf\x96\xb1\xb5\x3a\xaf\x2f\xcb\xdd\x75\xe9\x37\xd7\x65\x7b\xfd\xff\xe2\x2f\x7f\x3a\xf7\xef\xbf\x03\x7e\xc0\x57\xef\x37\x67\x9c\xfc\xf6\xd0\x1d\xba\x1d\xfe\x3e\x5c\xf6\xd8\xb7\xa7\xcd\xc3\xb1\xed\xbe\x9f\xd1\x76\x1b\xac\x8f\xbe\x0d\x83\xd7\x27\xd0\x16\x67\x7a\xf4\xa0\xed\xe2\xb2\xf7\x58\xef\xdb\x53\xbb\xbe\xf8\xd3\x79\x09\x7c\xdb\x7b\x1c\xdb\xf3\x05\x1f\xc2\xdf\xcf\xe8\xbc\xdf\xe0\x42\x78\xf0\xd8\x50\xe7\xf1\x74\xa2\x27\x7f\x3a\x3e\x2f\x5f\xb2\xe8\x8c\xfa\x7d\xbf\xce\xdf\xdb\x0e\xbf\xed\xdb\x03\x3e\x9d\x9f\xfc\xfa\x72\xf2\xab\xeb\xe1\xba\xee\x57\xf8\x19\xbf\x6e\x36\xfd\xb4\x7b\x2f\xeb\xc0\xf6\xf0\x4f\xbf\x94\x80\xf9\x8b\x3f\x3d\xb6\x9d\x86\xfe\x12\x38\x40\xb3\xaa\xde\x56\x0b\x10\x35\x58\x2d\x9c\x73\xae\xe1\x07\x9c\xeb\xff\x98\xc6\xd0\x5f\xab\x30\x08\x7e\x2d\xb5\x90\xae\x1b\xad\x20\x8b\x80\xfe\xde\x8b\x24\xe7\x1c\x51\xb8\xc7\xe9\x1c\x10\x24\xde\x18\x83\xba\x56\xa1\x4b\x14\x50\x22\xc2\x75\x2e\xfc\x8b\x2b\x4a\xbd\xbc\x86\x80\x19\x01\x35\x39\xfd\x66\x1e\x6b\x18\x69\x90\xdf\x43\x5d\x2d\x1c\xe0\x00\x0a\xa3\x01\x4d\xdf\x66\xc5\xf4\xed\x7e\x3c\x0a\x75\xe1\xbb\x32\x52\x0a\x57\x13\xf5\x12\xd6\xe4\xd2\x8c\xbd\xd0\xf0\x2d\xb1\x6e\x11\xa1\xc5\xb1\x30\x98\x94\x31\x10\xca\xd6\x4a\xf3\x8b\xb5\xec\x23\x41\xcd\xef\x46\x04\x0d\xd4\x53\x14\x1c\x66\x0a\xea\x1b\x0d\x44\x83\x3b\x23\x28\x69\x86\xd5\x96\x35\xd3\x2b\x3e\xc9\xee\x4d\x19\xae\xb8\x04\x4a\x46\x09\x16\x4b\x8b\x1d\x68\x2c\x9a\x16\xa2\x30\x80\xf5\xd5\x0b\x4c\xee\x11\x2d\x64\xc7\xc6\xbd\x81\xd0\xb1\x8a\x92\x18\xad\x45\xfd\xa5\x6d\x53\xbe\x9a\xfa\x3b\xa3\x39\xed\x3d\x39\x16\xc7\x8f\x9a\x8d\x74\x50\x69\x83\x12\x3b\x0b\xb7\xb3\x02\x1b\xc1\x26\x9d\x64\x73\xf6\xba\x68\x85\xf0\xad\x23\xf6\x32\x48\x3c\x53\x1a\x6c\xb2\xf1\xd8\xe5\x0b\x2a\xe4\x98\x22\x15\x97\xc5\x26\x87\xf1\x14\x2e\xe4\x6f\xf2\x7b\x64\x05\xf4\x8f\x26\xf9\x51\xb4\x7d\x21\x16\x4a\x42\xd5\xe4\xc9\x01\x63\x62\xe0\x39\xe6\x2c\x16\x7a\x30\x60\x48\x3d\x4a\x59\x10\x9c\xb4\xc2\xad\x11\x93\x8d\x1c\xbb\x17\x4a\xe2\x42\x1c\x80\xd9\x82\x4e\x42\x25\x3a\xca\x7c\xa4\x83\xe5\x57\x85\xde\xb1\x7c\x22\xed\xed\x8e\x75\x2a\x8b\x72\xfa\x43\xa7\x7c\x74\x2a\x06\xc7\x5e\x09\x95\xec\xe3\x95\x54\x43\x73\x97\xaf\x65\x32\xd0\x2c\x92\xc8\x69\xef\xb2\xce\xd5\x0c\x41\xae\x4a\x71\x5a\x8a\x59\x93\x37\x4a\x59\x64\xa1\xe5\x65\xaf\x55\x59\x91\x15\xc4\xc9\x56\x60\x0f\x9d\x30\xd9\x12\xe5\xfc\x33\x3d\x62\xd6\x16\xe7\xca\x03\x7a\x66\x99\x9a\xb5\x4c\x63\x2b\xae\x24\xa1\x1b\x75\xeb\x00\x26\xed\x17\xd6\x13\x6c\x4e\x9f\x16\x4a\xa4\xf9\x06\x34\xfb\x88\x35\xb3\xc9\x15\x32\x64\x85\x32\x41\xe8\x73\x87\x52\x84\x41\xe3\x00\x71\x80\x9c\x5a\x92\x71\xa8\x90\xbc\x4a\x01\x0c\x15\x17\x82\x46\xb0\xc9\x98\x10\x9b\x22\xd2\x2c\x34\xbf\x9a\x94\xda\x14\x72\x44\x26\x28\xe3\x09\x2b\x48\xb9\x94\xc3\x04\x86\xc5\x5d\x40\x7a\x3b\x2b\xc8\x87\xca\x18\x42\x6c\x1c\xb8\x5c\xc8\xf2\x0b\xe9\xfb\x3e\xa1\xa6\xe4\x65\x7f\x9e\xd0\x29\xf3\x4a\x11\xca\xd0\x72\x60\xd3\x78\xc2\xba\x4e\x31\x40\xea\x8a\x1f\x8e\x69\xed\xa4\x4b\x29\x56\x35\x7c\xda\xcf\x64\x69\x4d\x0a\x62\xe1\xb1\xd5\x96\xcb\x41\x19\x67\x93\xb5\x23\x13\x03\x76\x12\x15\x23\x8e\x09\xda\xbc\x25\xb0\x25\x8c\x95\xc6\xbd\xd8\x26\xf1\xb5\x72\x55\x4f\x48\x0d\xd6\x60\x29\xd1\x4f\x64\xc8\x62\x39\x64\xcc\x0d\xc7\x71\x5c\xde\x10\x73\x45\x15\xe1\x03\x2b\x5c\x44\xc3\x39\x2d\xb8\x46\xf6\x27\x4a\x9c\xcd\x96\x77\x94\xb8\xfb\xb2\xce\xbd\x11\x32\x13\xa9\x9b\x42\x1a\x36\x2d\x2f\xc8\x8f\xd6\xbd\x92\x98\x5a\x85\x27\x37\x66\x4d\x5c\x02\x0c\xdd\xe2\x54\x46\xd3\xb1\xac\x08\x8e\xf8\xce\xcd\x6d\x05\xab\xb5\x92\x20\x50\x4d\x65\xd5\x5e\xa6\x2a\x55\xeb\xd7\x84\x8a\xc7\x73\xc4\xcf\xa2\x62\x85\xe8\x8a\x7b\x61\x25\x18\x2e\xef\x8d\xb3\xe8\x01\xcf\xeb\xff\x17\xc4\x97\x50\x0f\x71\x0e\x8a\xb1\x61\xd3\x37\xca\xef\x5c\xa1\x77\x19\xcd\x78\x82\x25\xb7\xce\xb0\xb5\x5c\xd5\x24\x7b\x15\x8b\x5a\x4a\xa5\xec\xae\xb7\x1a\xe1\x65\xc5\xd0\xf8\x74\x40\xe5\x4e\xc0\x12\x38\xee\xeb\x30\xb4\x61\x90\xf6\xf3\x52\x78\x6f\x36\x04\x4b\x74\x0f\xcd\xdf\xd4\x6c\xe4\x84\x3e\xa6\x03\x95\x26\xb1\x46\xb5\xdf\xd7\x1a\x19\x78\xc8\xeb\xfb\x64\x0c\x57\x28\xa0\x86\x4f\x8f\x9e\x03\x93\x0d\xf2\x61\xea\x39\xc3\x18\x64\x82\x30\x84\x9a\x8b\xda\x7a\x57\x62\x61\x77\xf2\xae\x29\xa4\xa3\x5c\xad\x1d\x08\x93\xb4\x33\x5c\x1c\x4c\xf5\x05\x0f\xb7\x7f\xe6\x90\x6e\x12\x29\x49\xea\x8e\x75\xa4\x9a\xc7\x31\x11\x4c\x92\x0f\xd2\x36\x5b\x55\x3a\xdd\xd2\x4e\x79\x4b\x77\xe4\x1a\xb3\x5d\x84\xda\x2f\x52\x33\xde\xdb\x68\x7a\x37\xcb\xca\xf7\x33\x41\xb5\xf7\x22\x39\x4b\x73\xb6\x31\xf8\x56\x9f\xef\xe9\xb4\x58\x7a\x52\x15\x3c\x0c\xa9\x25\xa3\x5a\x37\x93\x03\x56\xe8\xeb\x04\x8d\xb5\x96\x89\xcc\x1a\x56\x8d\x5c\x73\xc6\x7d\x4a\x48\x4b\x78\x0a\x86\xcf\xc4\xfd\xb5\x36\x2a\x7b\x53\x39\x12\xb5\xff\xdc\x3e\x6b\x12\xa4\x34\x46\x5a\xcc\x19\x30\x39\x83\x34\xf7\xab\xfb\xfd\xf8\x3c\xa7\x16\xde\x8d\x2e\x2c\xb1\x94\xcc\xd0\xa9\xc2\x36\x9b\x89\x1a\xa4\x43\xb6\x47\x35\x7e\xc7\xe9\xa4\x42\xc4\xf5\xf1\x9c\x20\xd2\x0d\x14\x82\x69\x68\x0a\x60\x40\x67\x8b\x4e\x03\xe4\xd3\xfa\x9b\x4e\x43\x85\x2d\x98\x11\x53\x65\x1f\x55\xa1\x0a\xab\x15\xac\xe3\x07\xea\x84\x8d\x69\x97\x3e\x05\xb9\x07\xb5\xca\x13\x2b\x3e\x0f\x25\xc5\xe0\x4a\xdb\xae\xd7\xab\x22\x63\x25\x4e\x52\x13\xf1\x23\xc7\x61\xce\x58\x9c\x8f\xd0\x49\x79\x57\xa5\xe8\x68\x57\x96\x10\x8b\x7e\x39\x2c\x3f\x51\x78\xa6\x5c\xcd\x8d\x7b\xa4\x5a\xa4\xd8\xb5\x6c\xda\xe5\x2c\xce\x99\x6d\x3e\x1f\x41\xe7\x42\x90\x5f\x49\xaa\x2a\x15\xfa\xf9\xbd\xb4\x0b\x20\xbd\xb5\xb5\x34\xfd\x45\x67\x66\x90\x4d\xfe\x1b\x6e\x89\xfb\x31\x71\xb2\xb7\xd9\x69\x61\xf0\x33\xde\x9b\x10\xc2\x29\xa1\x2f\xaf\x18\xfc\xea\xdb\xa6\x29\x9d\x6b\x69\xee\xe1\x66\xe8\xb1\x6a\xf2\x8f\x3a\x49\xe8\x7f\x01\x00\x00\xff\xff\x89\xcf\x74\xf8\x80\x20\x00\x00") + +func fontsO8FlfBytes() ([]byte, error) { + return bindataRead( + _fontsO8Flf, + "fonts/o8.flf", + ) +} + +func fontsO8Flf() (*asset, error) { + bytes, err := fontsO8FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/o8.flf", size: 8320, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsOgreFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x58\xdf\x6b\xdb\x48\x10\x7e\xd7\x5f\xf1\x11\xca\xc5\xe6\x9c\x6c\x93\x90\x42\x8f\x10\x74\x1c\xd7\xe3\x9e\x0b\x79\x5a\x98\x2a\xb6\x6c\x8b\xca\x72\xb0\x65\xda\xc2\xfe\xf1\xc7\xec\xcc\x4a\xbb\x92\xe2\xa6\x67\x52\x5b\x95\x35\x33\xdf\xcc\x7c\xf3\x63\xbd\xae\xd7\xb7\xc5\x3b\x7c\xc0\x3d\x6e\xdf\xe3\xe6\x1e\x37\x77\xd9\xe7\xb6\x68\x56\xc5\x61\x85\xe7\x1f\xf8\xa7\x2e\x9b\x06\x7f\x6d\x8b\x97\x97\xb2\xae\xf1\x1b\xfe\x2d\xfc\x7f\x2b\xdc\x99\x8f\x77\xb8\xba\xc2\x73\x71\x2c\x57\xd8\x37\xb8\x3e\x56\x1b\xec\xd7\xf8\x74\x28\x9a\xaf\xf8\xbc\x2d\xcb\x43\xd1\x64\x9f\xaa\x4d\x5d\xb6\x38\x94\x75\x59\x1c\x4b\xdc\x5e\xbf\x67\xa1\x3f\x4f\x9b\xd3\xb1\xc5\xfd\x02\x37\x1f\x3f\xde\x65\xd9\xdf\xdf\x5f\xea\xa2\x29\xda\x6a\xdf\xb0\x8a\x75\x75\x38\xb6\xa8\xab\xa6\xfc\x23\x63\x84\xb8\xc2\xc5\xae\xd8\x54\x4b\x34\xa7\xdd\x73\x79\xb8\xc0\x7a\x7f\xc0\xba\xaa\x4b\x54\xab\xb2\x69\xab\x75\xb5\xf4\xc2\x59\x01\x00\x57\x38\x6e\xf7\xa7\x7a\x85\xa2\xfe\x56\xfc\x38\xe2\xb9\xc4\x97\xe2\x72\xe1\x85\x9a\xfd\xb7\xec\x9d\x3c\xd4\x6e\x4b\x5c\x6c\x8b\xc3\xea\xb9\x2e\x9a\xaf\x17\x8c\xeb\xe5\x50\x35\xed\x11\xc5\x11\x05\xfc\xdd\x05\x9e\x4f\x2d\x96\x45\x73\xd9\xb2\x9a\xe3\xee\x74\xdc\x96\xab\xec\x83\x68\xd8\x96\xd5\x66\xdb\x32\xe2\x02\xcb\x6d\x71\x28\x96\x6d\x79\xc8\xee\xcf\x7c\xb9\x40\xb3\x6f\x51\x35\xcb\xfa\xb4\xaa\x9a\x0d\x56\xe5\x71\x59\x36\xab\xf2\x70\xcc\x6e\xdf\x7b\xb1\x5d\xf1\xdd\x7b\x8e\xba\x6c\x36\xed\x16\xb3\xf2\x7b\x78\x78\xb9\xdf\xed\xca\x46\x02\x73\x9c\xe3\x77\x14\x58\x9f\x56\x9b\x12\xeb\x62\xd9\xee\x0f\xd9\xcd\xbd\xd7\xb0\x2a\xd7\xc5\xa9\x6e\x05\xec\x6e\xbf\x2a\xbd\xe3\xed\xb6\x3a\x62\xbd\x6f\x5a\xcc\xea\xea\x6b\x89\x8b\xab\x1d\x6e\xee\x2f\x38\x73\xac\xb7\x68\x56\x5e\xef\x3c\xbb\xb9\xf3\x5a\x24\xd2\x0c\x3f\x31\x9b\x65\xef\xf2\xc1\x5f\x9e\x01\x20\xf0\x87\x81\xcd\x33\x18\xc0\xe4\x99\xb1\x64\x90\x67\xd6\x00\xfe\x3b\xfe\xc8\x33\x90\x7f\x74\x06\x87\x79\x9e\xe1\x09\x4f\xdd\x97\xe9\x87\x6a\xe5\x3f\xbe\x47\x0e\xce\xc1\xb1\xac\x23\xe0\xfa\x1a\x20\x27\xd7\xfc\xe2\x6b\xc0\x91\x73\xe4\x3a\x1d\xbd\x22\xf2\xf7\x1c\x1c\xf2\xcc\x80\x68\x9e\x67\x96\x88\xc1\xce\xe0\xc1\xb2\xa8\xc2\x03\x51\x9e\xcd\x68\x6e\xfc\x7d\x18\xb0\x17\xfc\xc1\xb6\x0d\x99\x19\x4b\xc7\xba\x49\x21\xce\x40\x98\x43\x1e\x26\x58\x63\xf3\xcc\x61\x46\x8f\xc0\x43\x9e\xc1\x12\x91\xb1\xa6\x87\x26\xd6\x18\xc1\x3c\xcf\x9c\x11\xd0\xd1\x9b\xe8\x16\xd3\xac\x89\xb1\xc7\xef\xb0\x64\xf3\x3c\x23\xef\x9b\x85\x55\x0f\xd3\x77\xc3\x39\xe8\xe0\x66\x0c\x81\x75\x5a\x88\xdb\x86\xdd\xe5\x94\x81\xd3\x94\xb8\xd5\x27\x23\xca\x40\x08\x7f\x1f\xef\x28\xd8\xf9\xd0\x83\x81\x7f\xa9\x56\xbd\x20\x7e\x79\xad\xfc\x72\x13\xcf\xbc\xa2\x55\xb3\xa0\x5a\x7d\xa0\x80\x51\xce\x20\x39\xc3\xc0\x39\x92\xa8\x49\xa2\x34\xa2\x3e\x5e\xce\xfb\xe4\x42\xbe\x52\x18\x9e\x00\xfa\x54\x78\x53\xc8\xb9\xba\x02\x75\x45\xd2\xc1\x4c\xf3\xca\x98\x73\x66\xca\xcb\x41\x04\x04\x37\xc7\xd9\x6a\x70\xe6\x62\x65\x0a\x8c\x26\x46\x0a\xa3\xbf\x52\x5d\x5d\x92\x06\x59\x4a\xa1\xf2\x95\x4b\x30\x9f\xb3\x89\x40\x75\x5f\x0d\x5e\xfe\x32\x04\x70\xa6\xae\x4e\xc5\x2d\xf6\x10\x2e\x64\x0a\x21\x55\x5e\x63\x92\xa4\x34\x4b\x52\x58\x49\xba\xce\x58\x9b\x48\x6e\xf4\xf4\x22\xd8\x1f\x89\xa5\xcc\x1a\x73\x6c\xfc\x75\x4c\xec\xbe\x52\xc5\x33\x2d\x48\x2b\xd5\x35\xa8\xa9\x11\xe9\xcf\xb1\x3f\x29\x70\xab\x0d\xd6\x68\x69\x67\x51\x8c\xa5\xb7\xf1\x03\xd6\x68\x21\x58\x79\x64\x36\x1f\xb4\xd5\x10\x22\x4f\x4c\xd1\xcc\xb0\xe9\x8b\x12\x1b\xb3\x50\x05\x3e\x66\x82\xcc\x2a\x23\xe2\xa6\x00\x43\x56\x82\x6d\xc8\x5a\x8f\x80\xbf\x62\x0c\x64\x60\xc9\x0c\x62\x2c\x30\xc5\xae\xf7\x84\xc8\x1a\x1f\x34\x6e\x40\x5e\xcc\x5b\xf9\x99\x18\x84\x2d\xcc\x43\xff\x95\x9d\x62\x6b\x2f\xe7\x1f\xb7\xca\x37\xeb\x63\xc3\xa2\xc6\xf8\xf6\x40\xb4\xb8\x1c\x56\x88\xe7\xba\x38\xa8\x40\xbd\x9f\xc6\x68\x3a\xd8\xda\xa0\x61\x8e\x41\xaa\x8c\xb7\x1e\x46\xe1\xa8\xb5\x45\x62\x21\xb9\x64\x85\x47\x12\xd2\x57\x7c\x0b\xaa\x8c\xe5\x7f\xc1\x23\x61\x20\x83\xd4\xe1\x6b\x62\xa0\x7d\x85\xa8\x51\x4b\x21\x30\x3e\x32\x7e\x6c\x87\xe2\x56\xbb\x53\x81\x91\x7b\xca\x49\xb9\x62\x00\x56\xec\x4f\x56\x65\x8c\x37\xc0\x35\x14\xd0\x5a\x0d\x8f\x1d\x89\xf5\x4c\x35\xc0\x2f\xa4\xbe\x37\x67\x94\xa1\x02\xd4\x4b\xf2\x3d\x1b\x12\x32\x1c\xca\x88\x92\x6f\xbb\x8a\x63\x68\x92\x15\xab\xb1\x25\x9b\x4c\xcd\x51\x3e\x49\x69\xc0\xeb\x90\x50\x5c\x08\x67\x07\x61\x7d\x9d\x06\x73\x0d\x4f\xbf\x48\x4d\x89\xf5\xe6\xd0\xd9\x43\x30\x88\x60\x71\x41\xf6\xd5\x4c\x32\xc7\x25\x44\x56\x4a\xc2\xd7\xb0\xd8\xb4\xe3\x6e\x0e\x4d\x00\xd3\x5b\x5b\x93\x6c\x17\x72\x15\xaa\x63\x7a\x08\xf8\x02\xea\x6b\xd1\x44\x29\x85\x35\x13\x1e\xea\x2d\x4f\x1b\xad\x26\x49\x1e\x7e\x4a\xb7\x20\x08\x11\xf5\x84\x0d\x83\xc7\xe2\x09\x21\x0b\x36\x85\x1b\xfb\xa9\x6d\xd5\x74\x54\x90\xa4\x5b\xb5\x8c\x8e\x0e\x08\xf7\x87\xdb\x27\xe9\x4a\x69\x63\x21\x25\xa4\x95\xf5\xa4\x9b\x12\x3d\x78\xd9\x9f\x7d\x43\x04\x49\x90\x74\xa0\x98\x64\x9b\xe6\x97\x26\xcc\x68\xe3\xd7\x2a\x61\x61\x93\x34\x53\xf5\xca\x8f\x7d\x37\xb5\x52\x3a\x9e\x41\x82\xb8\x4f\xac\xc6\x4d\x83\x66\x43\xc4\xec\x58\x2b\x0d\xb7\x4f\xdd\xa9\x44\x6b\x9f\x0e\x9e\x9a\xd6\x75\x77\xfa\xf7\xc9\x0d\x71\x7c\x31\x1c\x9f\xf1\x3c\x86\x2a\xce\xd3\x45\xba\xd3\x41\x72\xfe\x88\x86\xdd\xac\x5f\xf8\x16\xc3\xd5\x4c\xc5\x78\xab\x1a\xee\x3b\x2e\xac\x49\xd7\xd3\xe4\x0b\x9b\x88\x6e\x7f\x6a\x8a\xa0\x7c\x75\xc3\x84\x93\x4a\xb8\xb0\x30\xfe\x1c\xde\x84\x1d\xf8\x43\x07\x24\xe9\x63\x3b\xdd\x73\xba\xea\x42\x9e\x96\x45\x76\x70\xf6\x7a\x5b\xc4\x24\xcd\xdd\x62\x70\x36\x62\x81\x0e\x7e\xc9\xce\x87\x9b\xb5\x5f\xac\xa6\x37\xeb\x10\x1d\x5d\xc8\xc4\xba\x7e\x90\x51\x8e\x45\x00\xc4\x1a\x17\x86\x83\xd3\xe3\x13\xf0\xe0\x29\xe3\x86\xd4\x45\x62\x75\x6c\x3a\x6a\x25\xe4\x83\x11\x39\xf6\x25\x3d\x3f\x24\x0e\x26\x4e\x8e\xc2\x4a\xf8\x95\xf8\xa4\xa9\x7e\xfb\x2a\x7c\xce\x9a\xf2\x17\xd7\xe1\x68\xe2\xfe\x57\xee\xe5\x80\x11\xd3\x91\x42\x93\xb9\xa4\xd0\x66\xd0\x19\x18\xf7\xb9\x7e\x75\xe5\xa7\xf5\x58\xee\xa2\xbe\x15\xd2\x1a\x51\x96\x22\x02\x33\x14\x37\xc5\x5c\x52\xde\x4c\x1f\xee\x26\x8b\x09\xda\xfc\xb4\x5f\x23\x34\xec\xa7\xd0\xe2\x27\x06\x77\x2a\x19\x0b\xc7\xf2\xb1\x8a\x54\x4b\x5a\xcc\xa3\x69\xf1\x28\xc4\x9d\x9e\x12\x6f\xf1\x73\x50\xa1\x7d\xd0\x49\xce\xf2\x61\x02\xcb\xb4\x48\x23\x29\xc7\x6a\x01\x22\x23\xe2\x01\x0f\xd1\x6f\x29\xd0\x1f\x21\x26\xab\x28\x94\x92\x46\x46\xe7\x49\x24\xfb\x88\xc7\xfe\x57\x19\x1f\x93\x1e\x9f\xb1\xc6\xf9\x39\xd1\x8f\xbb\xf4\x23\x72\x7c\x46\x73\x92\xd6\xd0\x57\x05\xe4\xa4\x39\xdd\x6c\x5e\x17\x3b\x7b\xfa\xef\xc4\x10\x7a\xd5\x9b\x7e\x34\x98\xb0\xf6\xb6\xd1\xf3\x1a\xc8\x73\x47\xed\xb7\x81\x1c\x59\xa3\xb0\x17\xe8\x04\x09\x5d\xd3\x59\xa9\x46\xe7\x92\x35\xe2\xbf\x00\x00\x00\xff\xff\x49\xee\xa5\xb3\x37\x16\x00\x00") + +func fontsOgreFlfBytes() ([]byte, error) { + return bindataRead( + _fontsOgreFlf, + "fonts/ogre.flf", + ) +} + +func fontsOgreFlf() (*asset, error) { + bytes, err := fontsOgreFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/ogre.flf", size: 5687, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPawpFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xcf\x6e\x23\x37\x0f\xbf\xcf\x53\xf0\xe0\x83\x74\xf8\x02\xe4\xc3\xb6\x40\x6e\x06\xf6\xd4\xbe\x40\x8f\x84\xb3\x6b\x17\x06\x12\x27\x88\xed\x2e\xf2\xf6\xc5\x48\x94\x48\x4a\x94\x46\x63\x07\x35\x60\x9b\x33\x23\x91\x14\xff\xfc\x48\x69\x0e\x2f\x87\xff\xef\x36\xf0\x04\xbf\xc3\xe3\x6f\xf0\x08\xdf\xa6\xf7\xdd\xaf\xf7\x87\xc3\xcb\x01\x9e\x3f\xe1\xfb\xf5\xe3\x72\x3c\xc3\x5f\xbb\xd3\x69\xff\x01\xee\xc7\xaf\x40\x6c\x77\x3f\xce\x0f\xcf\xd7\x87\xfd\xcf\xab\x9f\xdc\xeb\x27\x1c\x8e\x1f\xe7\x0b\x1c\x8e\x7f\xbf\xec\x2f\x70\x78\x3b\x5d\x1e\x00\xfe\xb8\xc0\xf1\x0c\xcf\xbb\xf3\xfe\x27\xbc\x9d\xe0\xfd\x7a\x38\x7c\x26\xb6\x7f\x5e\x77\x27\xf8\xbe\xfb\xf0\xd3\xcb\xee\x7c\xd9\x9f\x2f\xf0\xb1\xff\xe7\x78\x3e\xbe\x9d\xe0\x7f\x70\x7e\x7b\xdd\x5f\x8e\xaf\x7b\x38\x9e\xe0\xf1\xe9\xe9\xdb\x34\x6d\x36\x9b\xed\xe8\xcf\x76\x02\x84\xed\xe4\xd0\x57\x3f\xfc\x00\x00\xe2\xcf\x76\xda\x40\xfc\xcc\xd3\x01\x01\x00\x03\xe9\xd0\x83\x43\x5f\x90\x72\xec\x30\x19\x24\xf1\x27\x5e\x22\x7d\xe7\x4b\x44\x87\x3e\x7c\xa3\x82\xfc\xf1\x8b\x4f\x01\x48\xbd\xcc\xb9\x10\xc4\x97\x2c\x78\xa6\xd0\x81\x0f\x94\x43\x3f\x4f\x0f\x96\x41\x20\x43\xcd\x77\x82\xb8\x79\x90\x03\x2f\xc7\x91\x4c\xc1\x5f\x2f\x31\x18\x3a\x7e\xc8\xe0\x81\x4c\x86\x8f\x24\x4d\x47\x7a\x9a\x64\xea\x39\xc0\x73\x8c\x25\x29\xa9\xc1\x50\x88\x64\xd2\x68\x25\x4f\xb4\xcf\xcb\x81\xf0\xc0\xc7\x90\x80\xd9\xa4\xb4\x24\x71\xdf\x96\x16\x22\x65\x76\x2b\x6e\x82\x55\xb6\x93\x8b\x11\x61\xff\xd0\xd4\x60\xe8\x24\x38\x84\x61\xb2\x34\x69\xe9\xf9\x99\x14\x29\xe6\xcf\x4b\xaa\x87\x46\x4d\x15\x53\x6b\xbe\x5c\x09\xfb\x84\xbc\x8e\xc9\xfe\xcb\x41\x86\x14\x64\x79\x6e\xf2\xce\x58\xcc\x95\x8f\x38\x12\x59\xb6\x94\xcb\x81\x6d\x4c\xab\xc8\xb6\x17\x2c\x6f\x89\xa8\xb5\xa9\xa8\x02\x6b\xe3\x17\x67\x0c\x2b\x32\xf3\x2a\x43\xa4\x5a\x0f\xf2\xc5\x70\xce\x80\xc8\x99\x2a\x4d\x1a\x39\x13\x63\x13\x93\x4b\x51\x84\x66\x82\x4c\xa6\x10\x73\xc4\xa1\xf2\xba\x01\x02\xc4\x38\xb1\x8d\x0c\x1c\x3b\xd5\xfc\x17\xac\xaa\xa0\xc9\x5a\xa2\x52\x33\xc5\x6e\xb2\x02\x45\x75\x4e\x98\x52\xd5\x22\x68\x96\xed\x80\xa9\x6a\x70\xda\xae\xb1\x03\x08\x2c\x44\x76\x51\x4e\xfe\xc8\x4c\xe5\x5b\xb2\x85\xc4\xd7\x02\x6b\x2b\x58\x92\xa2\x50\xad\x3e\xeb\x5c\xdc\x0b\xe3\xc8\xb3\x63\xeb\x48\x36\x12\x46\x52\xdc\x99\x3d\xe6\xbb\xc2\x50\x23\x6e\xe0\xd4\xab\x91\xa0\xe1\x6a\x9a\x26\x72\x60\x40\x46\x67\x1d\xa5\xc6\x37\xaf\x63\x85\x0c\xed\xe1\x2e\xe4\xf5\x40\xc5\x82\x97\x85\xd1\x36\x2a\x26\xb8\x61\xa8\xc9\x30\x43\x1d\x42\x1c\x43\x91\x0b\x45\x91\x66\xa2\x89\xdb\xb6\x93\x9b\xae\x1f\xf2\x6c\x6e\x39\x1a\x3a\xd6\xeb\xd0\xca\x6a\xad\x29\xa2\x03\xdc\x78\x54\xa0\x08\xb2\xec\x89\xcc\x4c\x22\xab\xce\xa8\x09\x0b\x49\x4e\x0a\x6b\x59\x5c\x31\x37\x64\x11\x41\x19\xda\x30\x8b\x29\xa3\xb1\x05\x0b\x23\xf1\x28\x4c\x1e\x4d\xe3\x0a\xb2\x6f\xfd\x1e\xf4\x14\x30\x63\xdd\xeb\xdb\x2a\x55\x00\x76\x89\xf0\x89\x54\x14\x4a\xe8\x21\xdb\x0d\x55\x00\x5b\xfd\x4e\x25\x1c\x54\xdf\xee\x27\x62\xbf\x93\xc5\x71\x3d\x58\xee\x3b\x6e\x64\x4d\x33\x98\x5a\x36\x7a\x23\x66\x52\x6d\xcf\xc1\x79\x0f\xde\x03\xa8\x86\xdf\x15\xdc\xee\x8d\xcb\x5e\x4d\x11\x50\x9b\xc9\x56\x27\x3a\x26\xc3\x6a\x3b\x52\x7b\x9d\x49\x07\xe5\xa6\x63\xb0\x6e\xa5\x36\x42\x74\x11\xbc\xb7\x11\xee\xce\xae\xf1\xc5\xd8\x61\x7f\x14\x35\xb5\x49\xb6\xd6\xdc\x91\x91\x22\x8b\xc0\x8f\xb6\x30\x28\xb6\x45\xf4\x35\x2e\xa0\x48\xf7\xf1\xcd\x61\x3b\xd2\xf2\x8e\x37\x76\xa8\x32\xdb\x57\x46\x9a\x4c\x19\x99\x33\x52\x62\x4d\xa3\x8e\x85\xc1\x4e\x4f\x00\x96\xdc\xeb\x32\x3c\x55\x77\x0d\x07\xfe\x17\x0b\x72\x2a\x2a\xca\xdd\xf5\x4d\xf5\x03\x3c\xcc\xdf\xb2\x26\xc3\x3d\xad\x2b\x55\x0a\xcc\x63\xef\x6d\x5d\x01\xa1\x07\x33\x2d\x72\x51\x46\x20\xcc\xe2\x67\x90\x5f\x0b\xc9\x16\xf8\x26\xf4\x59\x53\x6b\x35\xd0\x64\x39\x08\x8d\xac\x97\x17\xe9\x8c\x82\x60\x03\x5c\xd9\x02\x8d\x42\x00\x84\x35\x40\x7b\x0d\x49\xf2\xea\x62\x63\x59\x4f\xc9\xf8\x82\x28\x68\x75\xca\xcd\xfd\xf0\x8a\x82\x16\xf9\xd3\xf8\xe4\x6e\xf9\x27\x9e\x49\x1e\xc5\x81\x93\x70\xb1\x6c\xca\xf3\x0c\xbe\xce\x2d\x35\x4a\x8d\xf2\x51\x13\xe4\x6b\xa8\x24\x18\xae\x2e\xd5\xcf\x9e\xe3\xfe\xbf\xa5\xfe\x26\x04\x61\xd8\x0e\xcd\xd2\xe2\xc1\x2f\x86\x63\xdf\x1c\x83\xf1\x4c\x77\x33\x44\x6c\x27\x20\x12\xbe\x84\xb4\xdc\x5e\x9d\x72\x6d\x9c\x5f\x3c\x93\x34\xf7\x3d\xe9\x0c\x24\x77\x25\xb1\x53\x49\x39\x82\xbe\xbf\xc7\xd3\xfb\x2f\xe5\x73\xb2\x37\x72\xb7\x92\x7b\x95\x05\x8e\x16\x41\x3a\xa2\xea\x3c\xa5\xd6\x8b\x1c\x8b\x5d\xab\x3e\xd0\x11\x3a\x8e\x73\x6c\x98\x4f\x2c\xd6\xaf\xd1\xd1\x62\x84\xa2\xc3\xd3\x26\x6e\xd8\xea\x16\x5f\x77\xec\xe0\x07\x7c\x5d\xeb\x28\x41\xbc\xa5\xa3\x7a\x2b\x63\xbc\xb8\x49\x33\xda\x2b\xaa\x8f\x21\xf4\x9d\x5c\x5a\x60\x70\x45\xa9\xc9\xe6\x46\xca\x17\x77\xba\x2b\x22\x14\x02\x75\x6a\x5f\xff\x2d\x82\x68\xff\x62\x7d\x0f\xdd\xe4\x66\x5a\x56\x1e\xa7\xdc\xe6\xd9\x6e\xf4\xe5\x66\xcc\x83\x11\x6b\x6b\x39\xaa\xde\xd1\x9b\x48\x53\xe5\xcc\xdd\x19\xa2\x62\xce\x05\x34\xd6\x7c\x92\x15\x93\x11\x93\x36\x49\x07\xfe\x2f\xe6\x59\x8c\xb0\x64\xc0\x40\xe8\xf9\xbe\xcd\x88\x14\x29\xeb\xb7\x2e\xea\x9d\xb7\x50\x2d\xab\x8b\x56\xc7\x99\x98\xb1\xda\x8f\x6d\x8e\xc5\xc1\x9a\xc1\x11\x96\x72\x06\xf3\x6b\x57\x92\x00\x5f\xd1\x5a\x36\x28\x14\xbb\x75\xd1\x60\xea\x0d\xba\x39\xf7\x2e\xa3\xd7\x45\xcd\xb7\x12\x5c\x75\x13\xfc\x96\x2f\x75\x8d\xfa\x51\xdf\x8d\x48\x88\x4b\x21\x24\x8e\x24\x3c\x37\x7c\xa0\xc6\x18\x1c\x2d\xf4\x6f\x54\x04\xbd\x10\x80\x5a\xda\xa2\x46\xed\x30\x62\x78\x0d\xc6\x00\xc6\x92\x3a\x2e\x56\x91\xda\x7d\x6a\x6b\xdb\xb8\x33\x00\xb4\x5d\x8e\xc5\xfc\x7a\xcc\x02\x47\x2e\xa1\x55\xd0\xad\xe1\xd8\x8e\xde\x4e\xdf\x34\xdf\x59\x2e\x2f\x36\xc7\x7b\xca\xcb\xd8\xf2\xef\x2f\x58\x2a\xc3\x64\x73\xe1\xaa\x3b\xc4\xf1\xdf\x00\x00\x00\xff\xff\x15\x86\x8b\x9b\xab\x23\x00\x00") + +func fontsPawpFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPawpFlf, + "fonts/pawp.flf", + ) +} + +func fontsPawpFlf() (*asset, error) { + bytes, err := fontsPawpFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/pawp.flf", size: 9131, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPeaksFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\x4d\x6f\x24\x35\x10\xbd\xcf\xaf\xa8\xc3\x5e\xc1\xcb\x08\x89\xe5\xd6\x1c\xc8\x85\x0b\x0a\x77\x2b\x41\x9a\xa0\x48\x11\x48\x90\x0b\xfc\x7a\x34\xd3\xb6\xeb\xbd\xaa\xe7\xee\x99\x21\x22\x9b\xed\xb6\xbb\xed\xfa\xae\x57\xe5\xce\xcb\xdb\xcb\xf1\xf9\x93\x7d\xb1\xef\xec\xf8\xd9\xbe\xfa\xc6\x8e\x87\x9f\x7f\xfc\xe1\xa7\x5f\xec\xd7\xbf\xed\xf1\x8f\xdf\xed\xe1\xcf\xd7\xf7\x7f\xec\x4b\xf9\xfe\xdb\xc3\xc3\xeb\x6f\x6f\xa7\x77\x7b\x3c\xbd\x9d\x9e\xff\x3a\xd9\xf1\xeb\xcf\x87\x4f\x8b\xf8\xb5\x65\x39\x94\x5a\xf9\x62\xed\x62\x66\xed\xd9\x79\x74\x79\x58\xea\xb8\x99\x5d\xde\xef\xdf\xda\xbd\xff\x9c\xa7\xa5\x56\x6b\xd7\x0b\x87\xf3\x8f\x5d\xee\xe9\xed\x8d\x8b\x91\xd1\x65\xde\xdf\x5c\xa4\x5e\x55\xab\x41\x8e\xb6\xaf\x9b\xa0\xad\xcb\x54\x51\x93\x46\x67\x2c\x85\xb5\x4e\xb4\xb1\xba\x70\xaf\x7a\x1b\x49\xea\x6b\x87\x2c\xbe\xbf\xfa\xf6\xb0\x0e\xf6\x3a\xc1\xf5\x4d\x73\xd4\xfc\xd2\xc4\x6c\xe4\x1a\xfd\x78\x1b\xf2\x76\x76\x9d\x83\x7a\x49\x37\x22\xca\x46\x0c\x9a\x8c\x4b\xd7\xa7\x39\xac\xfb\xdc\x9a\xe7\xc5\x7b\xb1\x9f\xe9\x8b\xb0\xc0\x68\xb4\x1c\x08\xdd\xd6\x9d\xed\xd6\xb2\x4c\x0d\x19\x6d\x5c\x86\x8b\xfa\xb6\x7c\x27\xee\xe2\xfd\x4d\x9c\xd8\xf8\xa0\xc5\x1d\x11\x1c\xb4\x0d\x49\x0e\x04\x91\x10\x46\xd5\x60\x3d\xc8\x79\xc4\xa0\x58\x2d\xf2\xa3\x1f\x97\x01\x32\x21\x0c\xd5\xad\x80\x11\x49\x52\xc7\x85\x95\x92\xb0\x0d\x5a\x04\xed\xe0\x58\xc4\xb9\x2c\x50\x42\x18\x96\x83\x93\x70\xa6\xa7\x7e\x8d\xe1\x25\x6d\xcc\x61\x58\x70\x06\x9a\x81\xf9\x21\x9f\x72\xb6\x68\x1b\x93\x26\x95\x23\x20\xb8\x47\x6b\xa2\xf1\x4e\x06\x0b\x5a\x1b\x23\xd0\xfd\x93\x83\xa8\x2f\xcb\x45\x20\x38\xbb\x8c\xda\x81\x6a\x27\x67\xb3\x49\x27\xe3\x2d\x4d\xfa\x44\x07\xbd\xb9\xbc\xa6\x35\x01\x53\x6c\x39\x3f\x39\xd8\x6d\xce\xda\x95\x2a\xa1\x8b\x8d\x2d\x9d\x3f\x47\x92\x80\x29\xbb\x0b\x01\xe6\x86\xfd\x43\x89\x8f\xd8\x82\x52\x8a\xc8\x12\xb6\x81\x41\xa9\x04\x9d\xf2\x49\x1a\xdc\x2e\xc0\x8e\x0a\x44\x38\x10\x5b\x0e\x99\x94\x7b\xd2\x77\xcb\x67\xa1\xaa\x0d\x0a\x98\x38\xc6\xed\x0f\x54\xc8\x96\x2d\x85\x41\xf7\xe9\xe9\x29\x61\xb7\x6e\xaa\x3c\xca\x21\xa4\x2c\x20\x81\x0a\x33\xaa\x2c\x3d\x19\x19\x57\x63\x59\x48\xee\x26\x5f\x31\x76\xf7\xad\xbe\xab\xc1\x4f\xc2\x77\x4f\x11\xe8\x2f\x54\x6a\x87\x0c\xa3\xc6\x8c\xdc\x1d\xc6\xb8\xde\x46\x56\x07\x06\x03\xe6\xc7\x66\x52\x1e\x99\x4d\xc6\x50\xe0\x12\x68\x2c\x50\xa2\x22\x68\xc3\xb0\x4b\xb6\xb9\x20\x26\xdc\x87\x10\x4e\x11\xb6\xa0\xad\x7a\xd8\x8a\x88\x90\x93\x5e\xe5\x87\x91\x20\xce\x04\x9c\x06\xc4\xdc\x98\x78\xd1\xb8\x72\x4f\x62\xb4\x77\x81\xc4\xa2\xee\x63\x6f\x54\x2a\xf6\x4d\x35\x9e\x56\x20\xe7\xe0\xe0\x41\x6d\x49\xcb\x8b\xc2\x6e\xc1\x65\xb3\x8a\xab\x6c\x79\x8d\xb3\x6f\x0d\xb3\x36\xe9\xfa\xba\xaf\x5d\x8b\x02\x3e\x60\x90\x1b\x38\x24\x48\xd1\xd4\x2c\x69\x54\x35\x5f\x30\x1e\x73\x65\xa6\x9c\xaf\x46\x2c\x13\x47\xc7\x9a\xdc\xf9\x04\xeb\x67\xf9\xf5\xdc\xb0\x25\x30\x45\x5f\x68\x1c\x32\x56\x61\x4e\xce\xea\x2d\x10\x9c\x6a\x18\x14\xdc\x73\x4f\xf2\x56\x19\x1d\x2c\x14\xac\x98\xe7\x67\xdf\x93\x66\xac\x9b\x9a\x59\x0c\xcf\x58\xd7\xa3\x3b\xb4\x2f\xbb\x34\x6c\xbe\x50\x55\x43\x55\xcf\xd0\x8f\x74\x92\xaf\x8c\xfb\x19\x26\xf6\x31\x33\x62\x98\x9d\x71\xf7\xe4\x0a\x54\x16\x36\x1b\xce\xc6\xc0\xd6\xcd\xc5\x48\x48\x56\x2d\x04\xbf\xaa\x40\x4a\x90\x8d\x7c\x2b\xdc\x13\x24\x90\x40\x60\xf0\x62\xa6\xf3\x75\x26\x00\x9a\x61\xa8\x5c\xa0\xf7\x41\x5d\xd2\x3b\x09\xe1\x32\x6a\x25\x43\x32\xfa\x8c\xe1\x2d\x33\x66\x98\x0e\x64\xe0\x54\xe1\x51\x33\x71\x68\x29\xa1\x15\xa8\xa2\x94\x00\xc3\xa6\xe8\xee\x2d\x7d\xea\x0a\xec\xe2\x01\x21\xc9\x0a\x29\x35\x3d\xb7\xe0\x67\xcc\xed\x9b\xf8\x86\x51\x18\x4a\xcb\x4e\x99\xbe\x67\xd2\x67\xb7\xdf\xdb\x97\xab\xd1\xe5\xe4\x13\x22\x5f\x08\xe1\xe2\xd8\x35\x1d\x69\xa6\x1a\xe6\x10\xab\x35\xa3\x26\x48\x37\x19\x92\x15\xb9\xd1\xa6\x05\xd9\x46\xe1\x40\x59\xb0\x1b\x1d\x6c\xe0\x89\xaf\x61\x42\xf3\xbe\x0f\xc1\x44\x76\x80\xec\xf4\xeb\x6d\x1a\x0f\x12\x74\x44\x32\xef\xa3\xa7\x45\x7d\xe9\x07\xce\xf3\xb6\xf1\x07\x02\x42\xab\xc9\x20\x49\x1a\x87\x8c\x64\xd1\x23\xf0\xb4\x1b\x8a\x32\x13\xac\x71\xf0\xcc\xc5\x11\x7d\x86\x49\xd6\xad\xa6\x6c\x8a\x5f\xd6\x77\xfa\xf9\xa1\x84\x9c\xcb\xfb\xda\x7b\x2e\x33\x81\xc3\x21\xbe\x99\xbc\x52\x04\xcf\x44\x1f\x36\x9b\x5f\x3d\x26\xf5\x47\x06\x23\x83\x8e\x0a\x07\x1e\x0a\xae\xd1\xd3\x55\xc9\x12\x85\xdc\x0e\x87\x12\x3f\x18\xa4\x18\x20\xf3\x24\xe2\x77\xa3\x4c\xa0\x2e\xfb\xb7\x14\x6f\x28\xb7\xe3\x8a\x13\x8e\xa8\x22\x1d\xae\x09\x1a\xe0\x0a\x12\x74\x47\x14\xea\x8c\xc7\xa8\x4e\x3e\x96\x45\xb8\xca\x83\x12\xf2\x5f\xe3\x5e\xa9\xf4\x89\xb8\x23\x87\x01\x52\x44\x9c\x5a\x14\x30\x5c\x87\x22\x54\x5c\xe7\xc6\x8f\x47\x35\x3d\xb2\x66\xb6\x09\x80\xc6\x32\xc9\x75\x56\x16\xa0\x21\xa4\xe8\x63\x74\x9d\x15\x9c\x98\xd5\xe0\x55\x19\xf6\x7d\xb6\xfe\x42\x0a\x58\xaa\x85\x3b\x19\x86\x88\x0e\xc1\x6e\x5e\x2d\x42\xd1\x9d\x64\xd8\x94\x70\x09\x7f\x64\xad\xb9\x6f\x0a\xe1\xb7\x4d\x98\x02\x2a\xa4\xe7\x12\xbe\xcd\xaa\xaf\x0c\x16\x0e\xcd\x14\x87\x7c\x5c\x0d\xb5\x2b\xc4\xf1\xfa\x35\x71\xfd\xbf\xee\xa6\xf9\xb5\xe4\x36\x84\x70\x4e\xd5\xe0\xaf\xbe\x02\x47\xff\xd3\x78\x39\x84\x7f\xff\xd7\x83\x7f\x03\x00\x00\xff\xff\x75\x29\x6c\x29\xe4\x20\x00\x00") + +func fontsPeaksFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPeaksFlf, + "fonts/peaks.flf", + ) +} + +func fontsPeaksFlf() (*asset, error) { + bytes, err := fontsPeaksFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/peaks.flf", size: 8420, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPebblesFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\xcd\x6f\xdc\xb6\x12\xbf\xef\x5f\x31\x07\x01\x4a\x00\x3f\xbe\x97\x87\x87\x97\xb4\x28\x0a\x5f\x1a\x34\x40\x81\x29\x7a\x29\x7a\x93\xbc\x4b\x7b\x05\xaf\x77\x8c\x95\x36\x4e\x7a\xe8\xdf\x5e\xf0\x63\xc8\x21\x45\x6a\xe5\xd8\x4d\xdd\x15\x49\xf1\x63\x3e\x7f\x33\x1c\xdd\x1e\x6e\xff\xdb\x37\xf0\xee\x3f\xf0\x01\xde\xfd\x1f\xfe\xf5\x0e\xde\x6f\x7e\xd5\x37\x37\x07\x3d\x5e\xc1\xed\x70\x77\xd0\xd3\xf0\xa7\xde\xc1\xcd\x57\xf8\xe9\xe1\xb1\x9f\xf6\xf0\xc3\xbe\xdf\xe9\xf1\xfa\xac\x9e\xfa\x71\x3f\x1c\xef\x26\x3a\x2a\xbd\x3b\xff\x08\xef\xff\xfd\xdd\xff\x36\x5b\x7a\x78\x3c\xe8\xc9\xad\xf8\xed\x6b\x7f\x84\x3f\xe8\xbc\xbd\x87\x37\x5f\xcd\xe3\x7a\x3b\xaa\xf3\x49\xdf\x0d\xc7\x5e\x6d\xfb\xb7\xf0\xc1\x2c\xf9\xeb\xe3\x89\x1e\xbe\x87\xdb\x83\xd6\xd7\xdb\x51\xab\xc7\xf1\x6c\x36\x84\x37\x1f\xf5\x61\xf8\x02\xbf\x68\xfd\x76\xf3\xb3\x3e\xe9\x76\x84\xfe\x08\xfd\xb8\x1d\x06\xb8\xa5\xe3\x04\x9f\xda\xcf\x1a\x6e\xb4\x3e\xc2\x13\x9d\xee\x87\xe3\x1d\xd0\x51\x01\x7c\x82\x71\xea\x4f\x86\x84\xa7\x61\xda\xc3\xb4\xd7\x30\xec\x74\x0f\x74\xbb\x39\x8f\x66\xd6\xcd\xd9\xf2\x07\x6f\x14\x10\xe0\x5b\x98\x08\x6e\xce\xc3\x61\x07\xbd\xdd\xf7\x0a\xdc\x34\xb3\xf0\x81\xa6\xe1\x16\x14\x21\x29\x98\x68\xa3\xbf\x3c\x9e\xf4\x38\x42\x0f\xdb\xf3\xe9\xb3\x56\x00\xbf\xef\xf5\xd1\x9c\x78\xaf\xa7\xed\x5e\xef\x80\xce\x93\x5d\x78\xa0\x27\x7d\xda\xf6\xa3\x86\x83\x9e\x26\x7d\x1a\xaf\x60\x98\x40\x1f\x77\x7a\xb7\x39\x3f\xc2\x81\xc8\x12\xfc\x40\x27\x0d\x87\xe1\x5e\xc3\xa3\x13\x3a\x4c\xfb\xfe\xc8\x14\x5e\xc1\x48\xf0\x09\x4e\xfa\xd8\x3f\xe8\x1d\x0c\x93\xda\x34\x00\x00\xcd\xf5\x6b\x3d\xaf\x37\x84\xcd\xf5\x06\xcd\x8f\x6b\x11\xb7\xec\xb4\xac\xeb\x96\x20\xd8\x51\x70\xc3\xf0\x9c\x5f\xfb\x00\x08\x23\xb1\x49\xf6\xcf\xec\x4b\x68\xff\xec\x28\xda\xbf\xea\x68\x6d\x33\x6e\xda\x36\xf9\x61\x45\x88\x46\x8f\x96\x76\xb3\x01\x59\x0e\x55\x98\x00\x1d\x22\xb9\x09\x60\x27\x74\x9e\x43\x33\x81\xdc\x5c\x04\x50\x76\xb4\x23\x22\x6c\xe3\x5c\x77\x9c\xb3\x14\xfb\x0f\xdd\x39\xee\x1d\xa0\x99\xd9\xa1\x59\x02\x40\x09\xf5\x28\xc9\x26\x94\x5c\x60\x22\x21\x73\x36\x79\x0e\xdc\x2b\x04\xe6\xc2\x4e\x73\xfb\x0b\x09\x04\x29\x30\xef\x71\xa9\x97\xb6\x13\x44\x1b\x8e\xc4\x78\x3e\xb5\x4e\x32\x61\x7f\x24\x77\x58\xe7\x86\xfd\x51\x1d\x1a\x49\x00\x52\x72\x6e\xd6\x49\x2c\xc9\x4a\xa6\x95\x36\x55\xfa\x71\x54\x1b\xbd\x61\x20\xc1\x8b\xb4\xd6\xeb\x88\xf5\xc8\xc4\xb8\x93\xbd\x4a\x49\x79\x75\x7a\x56\xeb\x3d\x6c\x2d\xb1\x41\x96\xc2\x70\x9b\xa4\x45\xac\x5a\xf3\x60\x4b\x35\x76\x4a\xc9\x98\x35\x26\xca\xd6\xce\x5b\x42\x66\xcd\xbc\x4d\xb9\x61\xb8\xc3\xec\x69\x94\x8d\xcf\xec\x6a\xb9\x7d\x41\x15\x25\xe5\xad\xda\x37\x69\x13\xff\x5b\x39\xff\x1b\x69\x8d\x30\x26\x4d\x29\xfe\xc3\xc4\x34\x51\xee\x9e\xfb\xa5\x01\xc9\xe8\x97\x16\x32\x83\x68\x6d\x0f\xd8\x2f\x5d\x0f\xbc\x73\xf9\x1e\x78\xc3\x84\xd0\x15\x64\x08\xb2\x3c\x36\x59\xf3\xb4\x4a\x23\x6f\xd9\x01\x43\x1c\xfa\x24\x23\xe8\xf0\x84\xb0\x6d\xc4\x3e\xd9\xd6\xd6\x44\x31\x3a\x3a\x23\xed\x42\xdf\x6c\x19\x44\x14\x9f\x25\x5a\x53\x71\x06\x13\x6c\x03\x26\x9a\x86\x62\x4f\x45\xf3\xdf\x02\xad\x17\xb7\x56\x14\x95\x45\x72\xce\x45\x31\x40\x80\x62\x2f\x46\xe2\x11\x0a\x2c\x47\x0f\x0a\xee\x96\x8f\xd4\xb6\x0e\xeb\x53\xb8\xf4\x61\xab\xc6\xd0\x2a\xaa\x53\xbb\x80\xe4\x8c\xe4\x15\x4a\xdb\x59\xb5\xb5\x8d\xa7\x33\xed\x05\x1a\x11\x12\x35\x82\x47\xda\x0c\x55\xd6\x50\x9d\x58\x73\x67\x5e\xb5\xe5\x57\xcf\x17\xc8\x7c\xfd\x8c\x8f\x15\x02\x49\x91\x03\x0b\xc8\x37\x43\x93\x02\x30\x96\x00\x28\x03\x4b\x8a\xc2\x8d\x21\x5d\x84\xe4\xa0\xe7\x74\xcc\x46\x5e\x09\xeb\x81\x47\x5a\x1f\x3d\xa2\x45\x96\x51\xf8\x05\xe8\x6c\xb8\x15\xb4\xc6\x09\x48\x82\xd6\xb8\x08\xf3\x31\x09\x51\x5e\x84\xd9\x31\x36\x53\x25\x0c\xa1\x1c\x62\x72\x26\x37\x54\x96\x7a\x33\xd1\x85\x6e\x24\xc6\x70\x92\x68\x5e\x1d\xe3\x4c\x89\x0f\x52\x9c\x80\x79\x93\x33\xe9\x97\xc9\xe0\x7c\xfe\xeb\x83\xb2\xf3\x3d\x9f\xeb\xb9\xd4\xc1\xa5\x62\x3e\x83\x40\x90\x82\xf3\xd9\x93\xc9\xb9\x9a\x90\x3e\xb5\x79\xca\xc4\xfa\x8c\x9a\x27\x10\xc9\x04\x43\x98\x73\xe2\x88\x3d\x11\x07\x84\x73\xf8\x51\x95\xca\x6a\x9e\x2b\x93\xc8\x90\x7d\xea\x47\xc2\x12\xd1\x87\x13\x23\x5e\x39\xc7\x29\x42\x1c\xea\xc7\x7d\x9e\x8c\x51\x1d\x35\xf3\xe1\xf4\xb4\x81\x20\x72\x32\x6d\xe2\x39\x0b\x6d\x14\x6d\x2f\x5a\x67\x05\x2c\xd8\xa5\x83\x49\xe5\x69\xb1\xcf\xd2\x84\xdc\x0a\x9c\x55\xc6\x95\x83\x18\xcf\xf0\xc5\x83\xf9\x3a\x23\x5c\x9e\x44\x93\x30\x05\x87\x7c\x42\x1c\xf5\x77\xa3\x05\xcd\x62\x98\x10\x37\x10\xeb\xcd\xdb\x7c\xac\xd0\xb2\x56\x9a\x7a\xe5\xa6\xa0\x45\xe1\x38\x24\x36\x80\xc4\x15\x7c\x5b\x71\xe4\x54\x52\xb0\xb6\xe3\xf9\x71\xd0\xbd\x2c\xcc\xb8\xb6\x62\xfa\x94\x85\xe8\xca\xdc\x6c\x42\x45\x98\x56\x94\x0c\xbd\x18\xde\x47\x88\x5e\x1e\x43\x91\x19\xa4\x00\x9e\x42\xb9\xb8\xef\x42\x8a\x9f\xe2\x22\xb1\x30\x2a\x34\x50\xf0\xc1\x8c\x27\xe7\x39\x18\x6c\x2c\x22\x0d\x86\x34\x32\xdc\x3f\x28\xcd\x06\x50\x98\x66\x82\x17\xf5\xe3\xb2\x8b\x65\xdd\xe2\x0a\x2d\xef\xe3\x36\x54\x5b\xbd\xd6\x44\x88\xac\x55\xa7\x6c\x8f\x9a\x5e\xc7\x0e\x4d\xd9\x0c\x90\x52\x9b\x48\x4c\x41\x24\xdd\x50\x9a\x06\x50\xe0\x92\xdd\x3c\x2e\xa1\xb0\xc0\xd3\xe2\x37\x22\x91\xde\x93\x4c\xf0\xc5\xb1\x48\xf1\x8e\x4f\x0b\x62\x2d\x78\xa0\x12\xe4\x4a\xa6\x70\x61\x3c\x5c\xf0\xd7\xe2\x28\xc6\xd8\xcc\x95\x88\x92\xaf\x29\x62\xb4\x71\xfb\x11\xe4\xfa\xb5\xa3\x6d\x81\xb9\x32\x9f\x09\xa3\x72\x47\x94\x7b\x52\xf9\xcd\x8b\xca\x19\x9d\x60\x99\xe3\xa0\x44\x73\xcc\xe3\x20\x0a\x1f\xf4\xae\x32\x8b\xad\x32\xa2\xd4\x44\x9d\x56\xb1\x20\x56\xb1\xc2\xec\xa4\x8a\x95\x26\x4a\x5c\xc5\x82\x62\x15\xab\x24\x6a\x87\x75\xf1\x7a\x24\x8b\x10\xa5\x82\xc4\xd2\x78\x32\x27\xcf\x78\x66\x26\x25\x28\xbe\x64\xb3\xb5\x39\xd2\x96\x65\x4e\x80\x2b\xa2\x49\xbb\xe4\x20\xf2\x60\x56\x78\x1b\x0e\xe3\x2a\x14\x09\xd8\xef\x9c\x55\xaf\x38\x38\xa8\x4c\xa4\x8d\x29\x1c\xe5\x20\x94\x10\x45\x19\x61\x98\x4a\xc2\xe7\xa9\xec\xd9\xd8\x96\x8b\x86\x85\x7e\x1a\x1a\x63\x0e\x2a\x33\x53\x71\xa3\xc9\x52\x57\x69\xed\xd2\x39\x17\xd0\xac\xa6\xf5\x04\x9d\x38\x09\x77\x6b\x3b\x99\x48\xaf\x31\xc3\xa2\x22\xac\x91\xc8\x7c\x2a\x86\x56\x4c\x76\x8f\x01\x3d\xf0\x39\x4b\xce\x5c\xea\xb5\x94\x9c\x79\xef\x5a\x51\xdf\x4c\x7b\x22\x7d\xf0\x0e\x13\x2a\x4d\xae\x10\x95\x74\xf9\x2e\x04\xa2\x88\xd5\xc8\x6e\x98\x10\xa8\x4b\x0a\x60\x3c\x41\xda\x05\x66\x66\x82\x99\xd5\x70\xb6\xe4\xe5\xe4\x2d\x64\x5d\x4f\x94\xa1\x38\x1f\x0a\x79\x46\x34\xa0\x68\x3e\xdf\xda\xa8\xda\xc1\xab\xb5\x2b\x37\x6b\x59\x28\x70\x5f\x07\x92\x2a\x43\xa5\x24\xbe\x82\x33\x77\x49\xcd\x2b\x5d\xf1\x03\x44\x51\x66\x3e\x2a\xb1\x5c\xc5\x93\xdd\xc8\x98\x1b\x27\x13\x0c\x47\xc8\x7b\xf2\x4e\xf1\x39\x1b\x98\x3d\x0d\x9d\xa5\x83\x96\x37\xac\xd7\xe9\x28\x30\x0f\xc5\x7a\xdf\x22\xf3\x2b\x68\x55\xbe\x68\xd6\x0a\x9a\xab\xb4\x2a\x2a\x39\x75\x24\x6d\xfe\x2e\xde\x18\x13\xb3\xbf\x4c\x17\x0a\x65\x60\x2c\x78\xc5\x8a\xa6\x05\x24\x4b\xe7\x5c\xcb\x94\x69\x9b\xb5\x4c\x99\x96\x51\x3a\x5b\xa2\x94\xc6\xcc\x32\x3f\x10\x7e\x30\x8c\xb9\x56\x3b\x33\x62\x07\xdd\x4d\x6c\xdb\x5f\xaf\x1d\x37\x9e\xb7\x3d\x03\x39\xc1\x34\x67\x84\x58\xd6\xc0\x9f\xfa\x16\x19\x08\x0e\xe8\xad\xb1\xd0\xaa\x7c\x4d\xa8\x61\xba\x6c\x76\x2e\x7f\x52\x3e\x2a\x50\x2c\x18\x60\x0c\xa5\xb4\x18\x08\xd7\x38\x7d\xcb\x8a\x0b\x15\x29\x40\x59\x9c\x58\xaa\xbc\xaf\xb1\xfb\xd7\x74\xfa\xd2\x86\x12\xb3\x80\x2f\x01\xaf\x84\x78\xf3\x4a\xbe\x81\xda\x75\x5b\x77\x89\x5c\xa1\x91\x15\x70\xaa\xad\x5a\x8f\x7d\x26\x21\x55\xc2\x4f\x9f\x21\x57\xbe\x76\x63\xcc\xc2\xe4\x78\xe8\x77\xb4\xfc\x39\x67\xa1\x31\x17\xe7\x7a\x30\xbd\x24\xd7\xa2\x99\x3a\x05\x75\xd4\x2e\xca\x75\xa5\xe7\xb5\x3e\x4f\xac\x7b\x5e\x87\xd4\xca\xef\x02\x65\xcf\x5b\x50\x23\x09\x78\xf5\x26\x11\x42\x5a\x5d\xea\x0b\x1b\xe6\x6e\x21\xf1\x9c\x37\xa4\x04\xcf\x61\x1e\x36\xf8\x11\x52\xa8\x50\x95\xf1\x11\xac\x14\x67\xdc\xb7\x76\x50\xa2\xc6\xdc\x88\x70\x91\xf5\xc3\xfb\x2e\x98\x19\x92\x64\xd4\x82\x6a\x33\x7f\xf2\xff\xe0\xfe\x77\x5f\xe7\xbd\xc1\xf2\x9d\x95\xfd\x35\x7e\x1e\xc8\xfa\xde\xd0\x5d\x0d\x41\x96\x5a\x1d\x9e\xab\x70\xff\x91\x17\x9b\x17\x37\x92\xeb\xcb\xcb\x4b\xf3\x97\xeb\xf1\x49\x6d\xe0\x05\xa5\x9d\x67\x97\x73\x92\x83\xc5\x24\x79\xaf\x2e\x5c\x81\xab\x07\xaf\xbe\x7b\xcf\x85\x4f\x69\x65\xf3\x05\xe9\x2d\xcc\x5d\x97\x5e\x1c\xe9\x2e\xd0\xfa\x8d\x00\xfa\x8f\x7c\x88\x41\x95\x15\xa0\x3c\xd1\x28\xe4\xff\x77\x00\x00\x00\xff\xff\x36\x15\xb6\xce\x0e\x28\x00\x00") + +func fontsPebblesFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPebblesFlf, + "fonts/pebbles.flf", + ) +} + +func fontsPebblesFlf() (*asset, error) { + bytes, err := fontsPebblesFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/pebbles.flf", size: 10254, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPepperFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x55\x51\x8b\xe3\x36\x10\x7e\xd7\xaf\xf8\x1e\x02\x4e\x20\xd6\x6c\xae\x0b\xed\xb6\x4d\x11\xec\xd1\xc2\x3d\x94\xbe\x14\x0a\x75\x51\x7c\x8e\x92\x38\x97\xd8\x6e\x6c\xf7\x28\x75\xf7\xb7\x17\x8d\x9c\xc4\x92\x1d\x28\xb7\xec\x7a\xe5\x19\xcd\x37\x9f\x3e\xcd\x8c\x77\xa7\xdd\xbb\x74\x86\x67\x7c\x85\xaf\xf1\x84\x17\x51\x99\xaa\x32\x17\xb9\x3b\xed\xf0\xf1\x6f\xbc\xbf\x48\xfc\xc2\x16\xcc\xcf\x59\x9d\xd5\xab\x63\xf6\xf9\xa8\xb6\x59\x23\xd3\x4c\xb6\x9f\x16\xe2\xb5\x3c\x57\x27\xd3\x98\x2d\xd2\x62\x8b\xaa\xbc\xd8\x65\x53\x62\x97\xef\x4f\xa6\xb1\x18\x1f\xda\xb4\xc0\x6b\x7a\xc1\xfc\x98\xa9\x63\xbb\x6f\x4d\x63\xe4\x9f\x6d\x7e\x96\x6d\x76\x96\xa6\x5e\x88\xbf\xcc\xa5\xce\xcb\x02\x2b\xf9\x84\x38\xc6\xbb\x27\xfa\x90\x16\xf4\xf2\x3c\x70\xac\xac\x63\xf5\x0d\xfd\x68\x3e\xd2\xcb\xb3\x7d\xa9\xcf\x6d\x7d\x38\x97\x5b\x83\xa7\x25\x9a\x43\x5a\x7c\xaa\x6d\xde\x9f\x4e\xa6\x28\xf0\x7a\x48\xab\xca\x9c\x4e\x98\xef\xf7\x99\x6a\xf3\x36\x93\x66\xdb\x2e\x84\xf8\xb5\x36\x35\xea\x2a\x2d\xf2\xfa\x80\xec\x90\x5e\xd2\xac\x31\x17\xd4\xa6\xc1\xe7\xbc\x39\x20\x7e\x8f\xb2\x6a\xf2\xb2\xf8\x56\xe0\x4b\x7e\xf4\x7d\x25\x7e\xc7\x1a\x69\x04\x20\xc1\x1a\xc6\x2e\xf0\x07\xd6\xc8\x79\xf5\x0f\xd6\x28\x79\xd5\x61\x8d\x96\x57\xff\x62\x8d\x82\x83\xdf\xb0\xc6\xcf\x42\xcc\xd4\xed\x57\x09\x40\x09\x90\x12\x12\xbc\xb6\x0f\xb6\x90\x12\x33\x5e\x5d\x8d\xfc\xa2\x49\x93\x12\x31\xc5\x84\xab\xd1\xfe\xd7\x4b\x1b\xa2\x37\x4a\x48\xcd\x9e\xa8\x77\x28\x21\x49\x09\x92\x37\x6c\xad\x04\xe6\xa4\xc4\x5c\xff\x76\xc3\x56\x82\xf8\x89\x01\x9d\xee\x4e\x47\x09\x74\x4a\x90\xc7\x4f\x76\x16\xb6\xdb\x0c\xf9\x29\xa1\x41\x5a\x09\x8a\x7a\xde\x3d\xf8\x15\xdf\x61\x69\xdd\x63\xde\xbd\xf2\xea\x65\x33\x31\xc2\x1d\x58\x33\x23\x36\x6b\x1a\x00\xc3\xea\xe0\xf1\xb2\xc8\x11\xef\x0b\xc3\x61\x55\x93\x7e\x38\x18\x90\xb1\x07\xbb\x35\x0b\x89\xd1\x6e\xc7\xc2\x2a\xec\xb3\x70\xc7\x99\xe6\xac\x47\x9c\xf5\x64\x52\x25\x20\xbd\x02\x70\x06\x1a\xa8\x44\x4a\x24\x43\x95\x6c\xda\x38\xc6\xe0\x0a\x93\xbb\xca\x36\x4b\xc4\xc9\x31\xe2\x24\x17\x96\xc1\xdb\xc4\xd1\x78\xff\xd4\x99\x39\x62\x31\x76\x80\xc5\x58\x4e\x38\x6c\xb9\x68\x19\x3d\x90\x6f\x22\x82\x1d\x98\x3d\xca\xf1\x9d\x77\x6f\x8f\xe8\xba\xc2\x1d\xd6\x83\xf3\x72\xb5\xd3\x03\x88\x4d\x12\xd4\x04\x63\x12\x37\x94\xd7\x79\xd4\x2d\x9d\xa2\x7e\xe7\xf5\x3e\x76\x75\x13\xfc\xc7\x65\x3b\x90\x7b\x86\x47\x11\xc9\xa3\x0b\x9a\x72\x6c\xc2\x6a\x75\x55\x8c\xa0\x00\xf0\x88\x11\x6c\xbb\x77\x4a\x74\x14\xce\x9b\x0e\xbd\xa3\x0b\x4e\xad\x44\xe2\x8a\x3e\x19\x44\xf4\xb5\x3d\x4c\xaa\x6f\x2d\xad\x65\xd8\x65\x2e\x00\xfe\x15\xf2\xf9\x92\x89\x2b\xd4\x61\xf3\x53\x37\x1c\x24\xf0\xa6\xcb\xb5\x23\xe0\xf5\x0c\xe7\xeb\x3c\xc2\x6e\x60\x71\x47\x22\xdc\x39\x0b\xa4\xc3\xb8\x9f\x07\xbb\x23\x0f\x42\x5b\x76\x34\xc3\x14\xae\x3d\x0c\x05\x0c\x40\xe1\x38\x18\xce\x5b\x07\xc3\x02\x5a\x73\x47\xe1\x01\x12\x7f\x9a\x50\x10\xee\x72\x73\x76\x5c\x53\x85\xb4\x30\xa9\x01\x8d\x34\xf0\xab\x77\xbc\x9b\x6e\x2c\x74\xf8\xd1\xe0\x09\xad\x13\x04\x4a\xe9\x09\xa5\x10\x66\x77\x7f\x1d\x85\xa2\xc0\x55\xa7\x3f\x06\xa0\xc4\x0f\xdf\xfb\x99\x43\xe5\xed\xc7\xca\x9a\xbc\x4a\xd3\xfd\xbc\xc1\xff\x1c\x2b\x52\xd3\xc6\x2f\x86\x2b\x95\x40\xcb\x68\xa2\xf2\x9c\x31\xf2\x8e\xb8\x1c\x49\xe6\x76\x05\x77\xc3\xfb\x46\x77\xa3\xe3\x78\x34\x13\xad\x69\x62\x3c\xfd\x17\x00\x00\xff\xff\xdd\xb3\x22\x4a\x20\x0a\x00\x00") + +func fontsPepperFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPepperFlf, + "fonts/pepper.flf", + ) +} + +func fontsPepperFlf() (*asset, error) { + bytes, err := fontsPepperFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/pepper.flf", size: 2592, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPoisonFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x4d\x8f\xdb\x36\x10\xbd\xfb\x57\xbc\x59\x18\x4d\x82\xee\x2e\xd6\xdb\xf4\x10\x22\x28\x78\x68\x0f\x3d\xf5\x52\xf4\x5c\xad\x25\xaf\x85\xd8\xd2\xc2\x92\x9b\xe4\xdf\x17\x22\x87\xc3\xa1\x3e\xfc\xb1\xbb\x49\x81\xc2\xdb\xd4\x22\x65\x8b\x7c\x7c\x1c\xce\x3c\x0e\xb5\xda\xac\xee\xb3\x39\x16\xf7\x58\xdc\xe1\xfe\x0e\x37\x0b\x2c\xde\xcf\x9e\xea\xb2\xa9\xab\xdb\xd5\x66\x85\x65\xbd\x7d\xaa\x9b\x22\x47\x59\xb5\x35\x56\xe5\xe3\xa6\x68\xf1\xf0\x15\x7f\x95\x55\x55\x7c\xc5\x9f\xeb\xac\xc4\xc7\xa6\x59\x95\x65\x6b\x8b\x5d\xd9\xdc\x2e\x97\xb7\xfb\xed\xc3\x6d\x91\xef\x7f\xe1\x76\xb0\xaa\xab\x16\x6f\xab\xfd\xf6\xa1\xd8\x35\xf8\x01\x4f\xfb\xaa\xdd\x67\x6d\x59\x57\xd8\x66\xbb\x4f\xcd\xbb\xd8\x4b\xda\x72\xda\xc0\xfe\xe9\xa9\xd8\x2d\xb3\xa6\xc0\x72\x9d\xed\xb2\x65\x5b\xec\xf4\xa3\xbf\x66\xff\x94\x39\x7e\x6f\x9a\x62\x83\x8f\x79\xd9\x5d\x6d\xb5\xaf\xca\xe5\x6d\xb5\xf7\x70\xf2\xac\x2d\x0c\xfe\x58\xb6\xb8\xff\xe9\x1a\x8b\x0f\x1f\xde\xcf\x7e\xfb\xf2\xb4\xc9\x2a\x8f\xa5\x5e\x61\x55\xee\x9a\x16\x9b\xb2\x2a\xcc\xac\xa3\x06\x37\xb8\xda\x66\x8f\xe5\x12\x1e\xfd\x15\x56\xf5\x0e\xab\x72\x53\xa0\xcc\x8b\xaa\x2d\x57\xe5\xd2\x3d\x3c\xcb\x00\xe0\x06\xcd\xba\xde\x6f\x72\x64\x9b\xcf\xd9\xd7\x06\x0f\x05\xfe\xce\xde\x5c\xbb\x87\xaa\xfa\xf3\x6c\xee\x7f\xd4\xae\x0b\x5c\xad\xb3\x5d\xfe\xb0\xc9\xaa\x4f\x57\xb8\xb9\xc1\xd3\xae\xac\xda\x06\x59\x83\x0c\xee\xee\x35\x1e\xf6\x2d\x96\x59\xf5\xa6\xed\x9a\x69\xb6\xfb\x66\x5d\xe4\xb3\xc5\xbd\x6b\x61\x5d\x94\x8f\xeb\xb6\x43\x9c\x45\x32\x66\x8b\xbb\xe9\x2f\xaf\x51\xd5\x2d\xca\x6a\xb9\xd9\xe7\x65\xf5\x88\xbc\x68\x96\x45\x95\x17\xbb\x66\x76\xef\x1f\xdb\x66\x5f\xdc\xc8\xb1\x29\xaa\xc7\x76\x8d\xb7\xc5\x97\xf0\xe3\x65\xbd\xdd\x16\x95\x27\xa6\x79\x87\x1f\x91\x61\xb5\xcf\x1f\x0b\xac\xb2\x65\x5b\xef\x66\x37\x0b\xd7\x42\x5e\xac\xb2\xfd\xa6\xf5\x60\xb7\x75\x5e\xb8\x81\xb7\xeb\xb2\xe1\x19\xdc\x94\x9f\x0a\x5c\xdd\x6c\x71\x77\x85\xba\x72\xcd\x66\x55\xee\x9a\x7d\x37\x5b\xfc\xec\x1a\xf1\x44\x77\xe8\x93\x5e\x67\xb3\x39\xe6\xf6\x99\x1f\x76\xd6\x11\x0f\x3b\xb3\xd6\x76\xf7\xe4\x42\xdd\x85\x2c\x5c\x8d\xdc\x4d\x22\x77\x93\x1f\x30\x64\x5c\xcd\xb8\x8b\xf1\x17\xff\x1d\x5f\x63\xc3\xaa\x71\xd5\x01\x77\x02\x4b\x00\x17\xd1\xd9\xc1\xbc\x7b\xec\xd9\xc5\xd0\xb1\x2a\x33\x12\xb8\xce\x3d\x82\xb1\xba\x25\x6b\xa9\xfb\x90\xd1\x93\x25\xbe\xe7\xd1\x75\x05\x50\xf7\xad\x7f\xbe\x63\xc4\x7d\xb8\x3a\x19\x22\xd3\x7d\x90\xa7\xa6\x2b\x1b\xbe\xe7\x9f\x37\x06\xdd\x87\x11\xac\xae\x0e\xd3\xc3\x3e\x36\x00\x5f\xf3\x50\x5d\xcd\x86\x3f\x0f\xd5\xf2\x3f\x06\x0e\x92\x5f\x92\x1b\x83\x47\x69\x67\x70\x55\xab\xe6\x92\x0c\x18\x20\x0f\x00\xbe\x66\x3a\xa4\xc6\xcd\x2f\xf7\xee\x81\xf7\xa1\x8e\x30\xed\x60\xf9\xef\xc2\xc4\x5b\xa9\xba\xef\x3b\x22\xbd\x01\xc4\xe6\x98\xd8\x50\xb7\x9e\xd7\x50\xa7\x50\xf5\x75\xc7\x71\xa4\xc6\x18\x72\x00\xd9\x28\x3d\xd3\x8e\x6a\x1e\x8a\xfb\xa5\x81\x32\xd3\xc9\x01\xb0\x65\x0c\xb9\x66\x74\x1d\x6c\x6d\x46\xdd\x58\x2c\x59\xc1\xce\x06\x13\x9a\xea\x08\x67\xf8\x8e\x7e\xe3\xff\x39\x22\x3a\xbc\x70\x9c\xbb\xa6\x3c\xdf\xc6\x04\xce\x99\x7f\x33\x82\x7a\xb0\x72\xc1\x54\xf3\x34\x33\x98\xd3\x2f\x3d\x26\x5c\x29\x34\x2d\x13\x17\xa7\x2c\x4e\x16\xc9\xd0\xc3\x14\x75\x25\x13\xda\x95\xc1\x05\x03\xe2\x3e\x92\x21\x25\x1d\x47\xa6\xd3\xb5\x4a\xe1\x61\x0a\xde\x02\x14\x56\x26\xa2\x41\x93\xd8\x00\x09\x8d\xdc\x9e\xd1\x16\x34\xbd\xca\x34\x14\xf2\x96\xe9\xbb\x21\xef\xaa\x02\x10\xef\x1b\xc4\x79\x38\x6f\x11\x60\xb8\x65\x14\xcc\x3b\x4c\xb3\x9f\xf3\x68\x9b\xf3\xc3\xbd\x4f\x1b\xe9\x91\x8a\xd5\x2b\x29\xce\x94\xc7\x18\xbd\xb9\x43\x9c\xd0\x16\x9e\x31\xba\x72\x42\xa7\x62\x8c\x67\x5f\xfa\x61\x24\x1a\xc8\x59\x23\x9e\xa8\x1c\x1c\xf1\x8b\x9a\x7e\xf1\x88\xcd\xe1\xc0\xd9\xef\x52\x96\xa2\xaa\xc6\xef\x5f\xd9\x93\xce\xa1\xeb\x52\x85\xf7\xa4\xf3\x71\x4a\x46\x57\x53\x0c\x52\x1c\x16\x62\xcc\x12\x37\x6a\x43\xcc\x82\x4c\x55\x77\x71\x41\x2c\xc4\x33\x09\xb4\xce\xb7\x50\x5c\xf0\x6e\x69\x21\x44\x30\xc3\xde\x93\x49\x35\xee\x3f\x18\x4d\x55\x0f\xa8\x78\x37\x06\xcb\xe1\x4a\x96\x71\x70\x35\xa2\x01\xe4\x4e\xea\x67\x3c\x55\x61\x2e\x93\xb5\x9d\xb0\x22\x9c\x24\x8c\x28\x13\x90\xb2\x0f\x22\xd1\xcd\x85\x68\x22\x2b\x93\x8c\x4c\xab\xa1\xe8\xda\x42\x0c\xe1\xf5\x34\x12\x3e\x06\x02\xad\x07\x47\x10\xf4\xc0\xf8\xf5\xc4\xb0\xfc\x62\x12\x66\x85\x0d\xe1\x83\x71\xa8\x89\x98\x4f\x0b\x34\x3d\x7c\xd1\x3a\xb1\x62\x55\x5f\xde\xcd\x72\x38\x22\x12\x7f\xec\x6d\x84\xbf\x09\x52\xcc\x78\x5d\xe3\x64\x98\xa2\xc1\x24\x91\xc8\x0c\x0c\x64\x8c\x21\x51\x32\x51\x73\x89\xc4\xb2\x14\xd5\x96\x0d\x80\x7c\x38\x50\x3a\xab\x5f\x54\xa6\x6a\x8e\x31\x24\xa2\x24\x9a\x6a\x1f\x87\x06\x12\x90\xd8\x04\x4a\x50\x79\x11\x81\x04\x26\x41\x23\xee\x78\x80\xa7\x0f\xc8\x0e\x79\xd1\x86\x1c\x47\x1b\xcd\xc4\x52\xa2\x9d\x83\x21\x93\x19\x33\xe4\xe8\x7a\xb4\xdf\x39\x00\x68\x6a\x65\x39\x4f\xd3\xf3\x33\x21\x9e\x0b\xb8\x30\x59\xac\x5e\x12\xff\xa2\xbd\x8b\xf6\x2d\xc7\x18\x3a\x17\x10\xa5\x12\x22\x0d\x56\x49\xf9\x5c\x40\x13\x97\xd0\xaf\x15\xcb\xe8\x5a\x9a\xcf\x4f\x8b\x53\x07\x1a\x85\x34\x1a\xbc\x63\xd2\xe8\xd1\x70\x9f\x6a\x34\x15\xfa\x94\x22\x8c\x3a\x07\xe2\x98\x11\x8d\x5f\x87\xad\x18\xf2\x90\xba\x51\xe9\xc8\x50\x6f\x73\x63\xfa\x0a\x68\x6c\x97\xf6\x4c\x8d\xc2\xd3\xec\x09\x4a\x34\x4a\x00\x35\x67\x15\x4d\x6e\x07\xe9\xb9\x52\x1e\xed\xb4\x7e\x06\x8c\xca\x9e\x06\x3a\xf2\xe9\x47\x13\x46\x81\x64\xb7\xcb\x37\x28\x11\x22\x89\x9c\x22\xa5\xf5\x53\x46\x95\x8a\x88\x32\x7c\x08\xf9\x59\x2b\x08\x07\x82\xa5\x1d\xc8\x58\x77\xdf\x28\x7d\xa4\x26\xda\x0c\x26\xfd\x59\x9a\x46\x2f\xed\x10\x31\xfd\xb2\x08\x2e\x99\xbf\xb3\x61\xb1\x13\x7b\x19\x92\x5d\xa1\x62\x4b\xfe\x62\x28\x1d\xfa\xe6\x17\xfb\x9e\x60\x86\xa2\x94\x49\x43\x1b\x73\x86\x6a\x13\x23\x79\x8c\xe3\xe1\xe2\x08\x20\xf4\x01\x85\xd8\x7e\x14\x10\x94\xe0\x60\xdd\x73\x92\x77\x1e\xc4\xaf\xc9\x80\x9a\x04\xd7\x58\x36\x49\x39\x89\x5f\x69\x40\x7d\x1d\x86\x92\x29\x83\xd2\xc8\x5a\x21\x4f\x31\x94\x0a\x8e\xe7\x46\x78\x3b\xc1\x4a\x37\x47\x26\x24\x08\x38\x0f\x06\x95\x0e\x18\x8b\xf0\x32\x65\x30\xc7\xa7\xec\x7b\x00\x8a\xe5\xd4\x35\x8e\x00\x4a\xbd\x81\x72\x06\xa9\x19\x25\xa0\x10\xfd\x82\x64\x55\x25\xe8\x77\xa6\x24\x5a\xda\x6f\x6d\x48\x0c\x48\xeb\xe9\x71\x1f\x30\x64\x4b\xa7\xe0\x80\xff\xcc\x05\x4c\xe6\x97\xb9\x7d\x9d\x5f\x56\xa3\x57\x4a\x41\x05\xa1\x81\x2e\xee\x69\x84\x09\x19\xaa\xd2\x46\x69\x14\x4b\x45\x96\x91\x11\x2b\x01\xa4\x45\x96\x19\x08\x81\x73\x68\xa7\x84\xf6\x20\x00\x44\xa8\x8b\x0a\x65\x23\xd5\x21\x41\x3b\xba\x94\xf6\x43\x1b\xbc\x00\xa8\xfb\x9b\xf7\xcb\x24\x65\x52\x65\x4b\xea\x7e\x52\x36\x52\x06\x6f\xbc\x07\x9e\x57\xb6\x0e\x07\x82\x68\x2f\x6e\x26\xd5\xe4\x78\x20\x49\x68\x4b\x3e\xc0\xfa\x25\x03\xa5\x5e\x81\x98\x2d\x60\x60\xc9\x2a\x4a\x66\x13\x2a\x15\xc9\x23\x3a\x2a\xee\x06\xd3\xaa\x8f\x32\xdc\xa1\x01\x43\x91\x15\xe4\xe2\xfd\x79\xde\x59\x32\x07\x9c\x22\x7c\xdd\xdd\xc5\xb9\xe1\xe2\xec\xed\xce\x33\xe2\xd7\xa4\xe1\xbf\xaa\x77\xe6\x14\x6d\x8a\x8f\x62\xba\x21\x82\x82\xa6\x09\x9a\x27\xd1\xe3\x2a\x75\xef\xd8\x9a\x43\xa8\xa2\x60\x53\x66\x2c\xbf\xfb\x72\xb6\x48\xb3\x65\x8f\xb8\x89\xb3\x05\xda\x88\x3d\x31\x07\x07\x12\x0c\x61\x77\xa0\xb6\xcf\x7e\xf5\xf5\xb2\x1d\x50\xe9\x0e\xa8\x7c\xc7\xe4\xf4\x4d\xa5\x5d\x92\x64\xa7\xda\x9d\x0c\x53\x0b\x6a\x9f\x67\xe5\x38\x40\x6b\x7e\x5f\xec\x2b\xfe\x97\x07\xd1\x6f\xbe\xca\x5e\x05\x90\x07\x21\x51\x96\xc2\x34\x81\x7d\x79\xc2\xcf\xa1\x2d\x51\x8a\x6a\x00\xad\x87\x8f\xa0\xbd\x3a\xe4\x23\xc4\x1d\x92\xe3\x34\x05\x37\xf1\xed\xa4\x80\x9b\x10\xa8\x11\xf5\x82\x3a\x34\x0b\x7b\x4f\x33\x79\xcc\xfa\xd2\xe0\x0d\xd2\xb9\xc9\xe8\xc3\x70\x7a\xf0\x3e\x30\xdd\x87\x8e\xcf\x49\x6f\x32\x03\x96\x01\x94\x57\x5b\x04\xa3\xba\x9b\x7f\xfb\x2a\xa9\xbe\x53\x15\x04\x23\x10\x28\x88\xfa\x5f\xfc\x13\x67\xb6\xd4\x4e\x4d\xa2\x8a\x74\x1c\x96\x5e\x58\x77\xc9\x71\xca\xd0\xc0\x91\x24\x4f\xfa\xd9\x13\x48\x9e\x3a\x39\x3c\xe9\x65\xa5\xfc\x25\x3d\x7e\xd1\x07\x32\xd2\x2d\x0d\xce\xdf\x8c\xe9\xe5\x61\x30\xd4\xa1\x03\xd2\x4e\x60\x4e\x4d\xdf\xc8\x59\x07\x4d\x9c\x75\x9c\xc1\x9c\x52\xe8\xea\x44\x9d\xd3\xfb\x31\x38\xbb\x0d\x11\xf3\x23\xf6\x24\xe4\x0a\x17\xdf\xf3\xce\x04\x8b\xbd\x71\xc9\xdf\x80\xf9\xef\x76\xc3\xe8\xbf\xd1\x1b\x13\x83\x51\xfb\xb1\x70\x9e\x82\xf0\x1a\xce\x79\x97\x4b\xfe\xe9\x92\x7f\xba\xe4\x9f\x2e\xf9\xa7\x4b\xfe\xe9\x92\x7f\xba\xe4\x9f\xf4\x54\x5e\xf2\x4f\x97\xfc\xd3\x25\xff\x74\xc9\x3f\x5d\xf2\x4f\x97\xfc\xd3\x25\xff\xf4\x3f\xc8\x3f\xe9\x04\x46\x00\x31\xf4\x0e\xda\x3d\xc4\x74\xd4\x60\xef\x96\xa6\x7a\x92\xd7\xae\x93\xcd\xfb\xf4\xcb\x78\x87\xa5\x2d\xbf\x76\x35\x2a\x6d\xa3\x04\x19\x7f\x09\x4b\xb2\x44\x83\x32\x12\x27\xd8\x7b\x47\xc8\x8e\x4a\x5b\xfd\x6a\x50\x3f\x01\x17\x02\xea\x89\x4b\x7d\xec\x06\xcb\xc7\xd0\xb7\xbc\x53\x15\xf7\xef\xe8\xbd\x17\x1d\x5f\xb4\xfa\x96\x37\x52\xa4\xce\x3e\xce\xf9\xff\xf2\xc0\x69\x0f\xfc\x1b\x00\x00\xff\xff\x36\x99\x57\x1a\xad\x39\x00\x00") + +func fontsPoisonFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPoisonFlf, + "fonts/poison.flf", + ) +} + +func fontsPoisonFlf() (*asset, error) { + bytes, err := fontsPoisonFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/poison.flf", size: 14765, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPuffyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x5f\x8b\xdc\xb6\x17\x7d\x9f\x4f\x71\x1e\x06\x6c\x81\x19\xb1\xbf\x5f\x5a\x1a\x58\x96\x81\xbe\x15\xfa\xda\x27\xc1\xf5\x36\xec\x96\x84\x24\x6d\x37\x5d\x68\xc0\x1f\xbe\xdc\x3f\x92\x25\x4b\x1e\x7b\x26\x19\xc2\x5a\xe3\xb1\x8f\xae\xee\x9f\xa3\x73\x95\xe7\x8f\xcf\xff\x7b\x3c\xe2\x27\xfc\x88\xbb\x37\xb8\xc3\xff\x0f\x7f\xbd\x3e\x3f\x7f\x3d\x3d\x7f\x7c\xc6\xef\x5f\xf1\xcb\xeb\xe3\x67\xfc\xfc\xf8\x82\xfe\xc3\xbb\xf3\x87\xd7\x3f\x5e\x9f\xfe\x79\x3a\xfd\xfd\xfa\xfe\xd3\xe9\xf5\xdd\xa7\xd3\xd3\x17\x77\xf8\xed\xe9\xe5\xcb\xfb\x3f\x3f\xe3\xee\x74\x87\x1f\xfc\xaf\x8f\x2f\xfe\xee\xed\xdb\x37\x87\xc3\xf1\x78\x3c\xef\xf8\x73\x3e\x80\x70\x3e\xf4\x70\xe7\xc3\x84\x29\xff\xd3\x93\xb3\x3f\x00\xce\xe7\xc3\x11\x04\x10\xf8\xc5\x1e\xae\x87\x93\x11\xb9\x9e\x64\x04\xf9\xec\x1f\x09\xac\x7d\x64\x2c\xe8\x32\x26\xc5\x17\xc3\x08\x38\x9d\x00\xb5\x45\x9f\x56\x93\x74\x66\x7b\x37\xc7\x89\x63\x79\x08\xfa\x84\xef\x08\x41\xd6\xd9\x93\x2e\x29\x50\xbc\xe3\xc8\xf1\xea\xc7\x40\x20\xdf\x19\x74\x86\xa5\x3e\xb2\xa9\xc5\x24\xc7\x43\xdf\xc1\xd9\x33\xbe\xe3\x7f\xf2\x45\x87\x36\xa7\x0e\xf5\x1d\x19\x22\xba\xb3\x65\xb0\x4e\xc4\x1f\xf9\xa1\x17\x77\x88\x21\x63\x00\x06\x06\xd0\x95\x8c\xc1\xb3\xe5\x13\x7a\x7a\xc0\x70\x3f\x8a\xed\x44\x3e\xa8\xf5\x35\x34\x07\x8f\x8e\x31\xca\x5e\xa2\xd0\xfe\x63\x81\x50\xeb\x25\x25\x06\x06\x9d\x30\x41\x66\x1c\x03\x74\xb6\xb8\x8c\x78\x31\x1f\xf1\x1c\xf6\x0c\x38\x87\x00\x49\x25\x46\x93\x8c\xa2\x64\x62\xf6\x62\x11\x77\xcd\xc6\x11\xea\xdd\x07\x00\xf7\xe2\xbf\x01\x43\x8a\x7b\x1e\x9c\x3c\x4a\x86\xa4\x37\x25\xf4\x82\x4a\x13\x26\xd2\x28\xf0\xcf\xd1\x78\x59\x94\x3d\x4b\x6e\xe1\xb1\xd2\x79\x2d\x6f\xd5\x0e\x9d\x5f\x2a\x46\xa4\x31\x95\xe9\xf9\xe3\x56\x9e\xab\x47\x97\x66\x66\x98\x32\x6c\x9a\xa0\x34\x03\x78\xec\xcc\x50\x64\x19\x5a\x25\xe5\x32\x43\x61\xf9\xe9\x3b\xd0\x68\x79\x08\x67\xac\x01\xa3\x0f\x76\xe8\x14\xf3\xb2\x5b\x8b\x56\x96\x68\x1c\xe0\x2c\x5f\xe2\xa5\x6f\x25\x5a\x32\x81\x8b\x41\x6d\x90\x00\x3a\x5b\x2e\x2f\x2b\x2e\xaf\x57\x70\x2a\xed\x28\x9d\x2c\x80\x14\x69\x42\x5f\x70\xba\x00\x50\x4f\x9a\x80\x70\xd9\x92\xb2\x18\x2e\x69\x22\x56\x81\x33\xea\x99\x30\xa5\xea\xe1\x51\xcc\xc3\x21\x82\x2c\x48\xac\xb4\x2c\xa5\x8e\x98\xe8\xd4\xb5\x24\x68\xfc\xc3\x18\x96\x96\xad\x39\xfb\x02\x10\xdb\xcc\x40\xfb\xa2\x46\x8b\x74\xce\x73\xcc\xde\xe1\x81\x85\x47\x73\x4a\xb2\xab\x4a\xa7\xb2\xc6\x66\x16\x10\x86\x33\xae\x76\xc6\x02\x84\xfb\x2e\xbb\xb3\x95\x57\x94\x48\x5f\x3d\x64\x0b\x63\xd2\xb7\x34\x4b\x19\x56\x72\x72\x0e\xd4\xac\xb8\x56\xed\xad\x3f\xd8\xa2\x07\x4a\x65\xe8\x52\x09\x9e\x0f\xf7\xcc\x73\x32\x7f\x80\x32\x28\x5f\x56\x13\xad\x4e\x96\x26\xcf\xec\x64\x9c\xb4\xc1\x19\x7d\xcb\x8f\x63\x88\x76\x30\x0b\x3f\x64\xb6\x1a\x55\xac\x57\x75\x19\x46\x0e\x99\xf9\x3a\xa6\xc8\x44\x93\xbe\x76\x99\xcc\x8b\xbb\x33\xb3\x2b\x72\x4c\x30\x1a\xe1\x34\x5b\xd0\x33\xd3\xab\x0f\xd9\x77\xb6\x61\x68\xc5\x96\x1b\xef\xb2\x24\x00\x97\x15\x80\x94\x44\xc1\x68\xfc\xc3\x5a\x9e\x20\xdf\xb1\x23\x23\x6a\x9e\x0a\xd0\x7d\x97\xdd\xe9\xe9\x72\x6d\x55\x40\x3a\xad\x50\x08\x19\x74\x7f\x0b\xd0\x94\x73\xb4\x22\xea\x62\xaf\xb6\x88\xcc\x22\x90\xfb\x26\x8b\x72\x20\xe3\x47\xcb\x41\x15\x58\x37\xf8\x48\x03\xca\xd0\xc3\xb6\x45\x51\x9a\xc1\x21\xca\x5f\x9a\x6e\x09\x3f\xac\xe6\x5b\xfa\x39\x3e\x5c\x24\x5c\x4e\x9b\x4a\x43\x64\x03\x26\xf3\x69\x9b\x83\x1b\xa6\x6b\x69\x4d\x18\x98\x47\xe4\x4e\x48\xe5\x77\xc1\xf4\x58\xf5\xe6\xf1\x14\x83\x2c\xe1\xa6\x1d\xe1\x8d\xb7\x7c\x17\xc8\xeb\x66\x22\x8b\x2b\x8a\x6a\x9f\x33\xab\xa5\x8d\xc1\x7c\x3a\x60\x34\xa0\x31\xec\x29\xca\xaa\xba\xd7\x64\x4a\x4f\x97\xf6\xf4\x46\x2d\xc5\xea\x1e\xd4\x23\xbb\x33\x77\x87\x45\x7d\x17\xcc\xa2\xb0\x65\xd1\xd4\xe0\x9b\x01\xa2\x7d\x38\xfc\xd8\x0e\xff\x6a\x51\x8e\x65\x7b\xb4\xa9\x7b\x52\x66\xa7\xf6\xcc\x44\x4f\x6b\x70\x81\xf4\x5b\x99\x1d\x5d\x73\x5d\xd4\xf6\x00\x05\xf2\xbb\x6a\x0d\x19\x18\xdf\x48\x80\x12\xbf\x0c\x74\xb6\xd0\x23\x64\x7e\xfb\x77\x21\x3f\x5b\xba\x9a\x8a\x59\x7a\x95\x39\x63\x88\x5b\xe6\x03\xb4\xb0\x79\xcf\x9b\x2b\xbb\x6c\x28\x5b\x5b\x7a\x42\x9c\x21\x29\x62\x8e\x01\xa6\xd4\xae\xe9\x86\xae\x96\x80\x85\x2a\x29\xf6\xe1\x1a\xd8\xb2\xd1\x65\x3d\x67\xbc\x44\x90\x95\xd6\x33\x22\x9a\x82\x41\xae\x62\xd2\xe3\xf1\xab\xbd\x9b\x69\x1c\xfd\xba\xa3\x3d\xb7\x34\x77\x55\xb3\x42\x53\xcc\xca\xda\xc2\x23\x6b\x52\xd6\x81\x1e\x08\xa2\x11\x7d\x50\x15\x99\x9d\x8a\xac\x5f\xcf\x07\xe8\x08\x37\x8d\x6a\x65\x98\x0b\xd4\x23\x13\xce\xc5\x03\x01\x54\x9c\x46\xb1\x77\x63\xf5\xa5\x0a\x3b\x6d\x5b\xc3\x35\xbb\x4d\x64\xb2\x6e\xc1\xad\x3d\x0d\xdb\xbb\x4d\x61\x51\xea\xe0\x54\xf9\xa2\xd7\x3b\x17\x79\x0b\xb3\x1e\xd7\xf2\xe0\xef\xf1\xc4\x82\x46\xdd\x91\xf7\x2c\xad\x6d\x51\xd6\xa3\xc6\xce\xcb\x6f\x5a\xb4\x58\x48\xd6\xa7\x71\xcb\xb8\x5b\x27\x5d\xb6\xa8\xec\x8b\x84\xed\xa3\xfc\x48\x9d\x12\xbb\x7f\x2d\x6a\xcb\xce\x71\xcf\xd6\xae\x4d\x4a\x2d\x96\x2a\x9d\x54\xbc\x9b\xc2\x43\x85\x60\xda\x56\x4e\x2b\xa6\xfb\x4e\x7d\x78\xb5\x4e\x92\xb2\xe7\x77\x61\x4d\x46\x71\x59\x21\xa6\xf9\x53\x7d\xe1\x38\x93\x3a\xd2\x77\xec\xc8\xb9\x0d\xd7\x3d\x2b\x73\xe8\xf6\xb9\x61\x23\xdc\x05\x78\xc8\xe4\xc6\x46\x94\x1a\x79\x03\x34\x1b\xf3\x8d\x36\x7c\x09\x44\xe9\x70\xa4\xab\x75\xcb\x8a\x92\xda\xcf\x3f\x29\x93\xdb\x1d\x7e\x7c\x3f\xbb\x12\x6c\xbf\xe9\x28\x6d\x38\x69\xea\xea\xf9\x06\x80\xd5\xaa\xef\xf4\x30\x47\xe6\x0e\x51\x29\xb7\x00\xd2\xe1\x10\x59\x41\xbb\xe5\x06\xb7\x72\xb6\xda\x72\x66\x25\x70\xf6\x1d\xba\xed\x00\xda\xa3\x8b\xd6\x72\x31\x02\x16\xa0\x39\x70\x0e\xbe\x47\x17\x55\x4e\xb7\x04\x61\x69\x64\x47\xc4\x7a\x42\xec\xb3\xdd\xbb\x8a\xda\x15\xbe\x1b\xd6\xe8\xa4\xca\x9f\x59\x0d\x0c\x7a\x96\xe3\xd3\x26\xbb\x66\x89\xd2\x99\x1d\xfe\xd8\xe9\xfa\x7d\x67\xca\xd8\xce\xd7\xcb\x83\x9f\x12\x60\xeb\xff\x6b\xf2\xad\x36\x6a\x21\x3b\x8d\x37\x11\x3e\xda\x51\x8e\xb1\x56\x3c\x16\xae\x66\xa2\xec\x80\x36\xc4\x43\x5a\x1f\x8a\x37\xd6\x65\xe2\x9a\xc6\xeb\xc9\x69\x87\xf1\xad\xa7\x2e\x4d\xa0\x5b\x1a\xbc\x34\xc9\xf7\xeb\x39\x32\xb3\x6f\x16\x4a\x35\xd0\x0d\x1c\x5c\x03\x7d\x3f\xda\xa8\xbb\xd9\xc9\xc3\x38\x3c\x44\x31\x37\x09\xe2\x4c\xe6\xff\x05\x00\x00\xff\xff\xc6\x63\x30\xa8\xef\x1c\x00\x00") + +func fontsPuffyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPuffyFlf, + "fonts/puffy.flf", + ) +} + +func fontsPuffyFlf() (*asset, error) { + bytes, err := fontsPuffyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/puffy.flf", size: 7407, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsPyramidFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x97\x57\x74\xdc\xd4\x16\x86\xdf\xf5\x7c\xef\xfb\xbe\xbe\x01\x27\xc4\x93\x58\x1a\x7b\xec\x09\x21\x38\x84\x00\x01\x02\xa1\xb7\x10\xe7\xcc\xe8\x68\x46\x44\x23\x19\x49\x93\xd8\x74\xd3\x7b\xef\xbd\x2f\x7a\x67\xd1\x7b\xef\xbd\xf7\xde\x7b\xef\xac\x19\x2f\x98\xff\x0f\x7b\x78\x49\xd6\xfa\xbe\xa3\x23\xe9\x93\x6c\x6f\x05\x51\xe0\x99\x49\x29\x4a\x51\x86\xa4\xe0\x8a\x5b\x72\x96\x4c\xa4\xa6\x11\xfa\x52\x99\x90\x05\x91\x69\xfa\x56\x16\x9b\x34\x0f\xe3\x4c\xfa\xbd\xd9\xe5\x41\x67\x51\x5c\x8d\x9a\xbe\xcd\xa4\x5a\x37\xa9\xa9\xe6\x36\xcd\xc4\xf5\x86\x0b\xde\xe0\xa0\x13\x84\xb5\xc8\xe6\x92\xda\xc8\x9a\xcc\x8a\x37\xcb\x95\x42\x41\x5c\x4f\xe6\x37\x6b\xe2\x96\xcb\x03\xce\x12\x9b\x36\xc2\x2c\x0b\x93\x58\xc2\x4c\xea\x36\xb5\x95\x09\xa9\x85\x2b\x6d\x2c\x79\x22\x8d\xc4\x0f\x83\x09\xc9\xeb\x61\x26\x41\x12\xe7\x7d\x62\x32\x89\x92\xb8\xd6\xfa\x3f\xaf\x5b\xa7\xbd\x20\xb4\x69\x6f\x26\xb1\x69\xd8\xd6\x1e\x63\x91\xa9\x5a\x5f\x92\x58\x8c\x54\x93\x46\xc3\xc6\xb9\x44\x61\x6c\x67\x39\xce\xc2\xf1\xb1\xc8\xc4\x26\x6f\x9d\x2d\x09\x24\x08\xd3\x6c\xca\xcd\x71\x5a\x37\x2e\x05\xe9\x69\x98\x5a\x58\x95\xb8\xd9\xa8\xd8\xb4\x47\x82\x24\x95\x20\x8c\xac\x84\xbe\x8d\xf3\x30\x08\xab\xed\x83\x1d\x23\x22\x52\x90\xac\x9e\x34\x23\x5f\x4c\xb4\xca\x4c\x64\x52\xb1\xb2\xdc\xf4\xf6\xb5\x0f\x8a\x93\x55\xce\xb4\xa9\x45\x79\xdd\x4a\x4f\xdd\xa4\x7e\x25\x32\xf1\x8a\x9e\x56\x80\xb1\x34\x8c\xf3\xac\x75\x0f\x46\xda\xb4\x4f\x2a\xcd\x5c\xaa\x26\xee\xcd\x5b\xdb\x64\x8d\x66\x56\xb7\xbe\x53\x9c\xda\xa1\x6e\xc3\x5a\x3d\x6f\x5d\xb1\xe9\x44\xfe\x57\xd9\x27\x71\x92\x4b\xd8\x7e\x32\x61\x5c\x13\xdf\x66\x55\x1b\xfb\x36\xcd\x9c\xa1\xf6\x51\x0d\x33\xde\xbe\x71\x89\x6c\x5c\xcb\xeb\x32\xdd\x8e\xff\xb5\x16\x9b\x65\x33\x64\xa6\x18\x09\x9a\x7e\xcd\x4a\x60\xaa\x79\x92\x3a\x05\xb7\xbd\x83\x6f\x03\xd3\x8c\xf2\xa9\x6b\x6d\x24\xbe\x6d\xdf\xf7\xdf\x4f\xca\x71\x4b\xed\x65\x53\x25\x5b\x97\x47\xfb\x3a\xce\xe4\xe4\xe4\x48\xe7\x9f\x11\x47\x64\x99\xc8\x88\x23\xb3\xff\xb7\x54\x46\x9c\xb9\xa3\xa3\xa3\xf3\x90\xf6\xa8\xf4\xff\x2a\x9d\xa6\xd2\x35\x54\xba\xa6\x4a\x7b\x55\x3a\x5d\xa5\x33\x54\xba\x96\x4a\x67\xaa\xb4\x4f\xa5\x05\x95\xce\x52\xe9\x6c\x95\xf6\xab\xd4\x55\xa9\xa7\xd2\xa2\x4a\x07\x54\x3a\xa8\xd2\x92\x4a\x87\x54\x3a\xac\xd2\xb2\x4a\xe7\xa8\x74\x6d\x95\xce\x55\xe9\x3a\x2a\x9d\xa7\xd2\x75\x55\x3a\xa2\xd2\xf9\x2a\x5d\x4f\xa5\x0b\x54\xba\xbe\x4a\x17\xaa\x74\x03\x95\x6e\xa8\xd2\x8d\x54\xba\x48\xa5\x1b\xab\x74\x13\x95\x6e\xaa\xd2\xc5\x2a\xdd\x4c\xa5\x9b\xab\x74\x89\x4a\xb7\x50\xe9\x96\x2a\xdd\x4a\xa5\x5b\xab\x74\x1b\x95\x6e\xab\xd2\xed\x54\xba\xbd\x4a\x77\x50\xe9\x8e\x2a\xdd\x49\xa5\x4b\x55\xba\xb3\x4a\x97\xa9\x74\x54\xa5\xcb\x55\x6a\x54\x5a\x51\x69\x55\xa5\xbe\x4a\xad\x4a\x03\x95\xd6\x54\x5a\x57\x69\xa8\xd2\x5d\x54\xba\x42\xa5\x91\x4a\x1b\x2a\x8d\x55\x9a\xa8\x74\x4c\xa5\xbb\xaa\x34\x55\x69\xa6\xd2\x5c\xa5\x4d\x95\xae\x54\xe9\x2a\x95\x8e\xab\x74\x42\xa5\xbb\xa9\x74\x77\x95\xee\xa1\xd2\x3d\x55\xba\x97\x4a\x7f\x53\xe9\x4b\x2a\x3d\x4d\xa5\xfb\xab\xf4\x07\x95\x1e\xab\xd2\x33\x91\xba\xde\x70\xc7\x3c\xc0\xa6\xdc\x31\xbf\x92\x29\xf6\x77\xcc\x47\x6c\xdc\x8e\x79\x9b\x8d\xd7\x31\xef\xb2\x29\x76\xcc\x9b\x6c\x06\x3a\xe6\x3d\x36\x83\x1d\xf3\x01\x9b\x52\xc7\x7c\xcc\x66\xa8\x63\x3e\x61\x03\x0d\x3e\x64\x03\x0d\xbe\x20\x33\x00\x0d\x3e\x67\x03\x0d\x3e\x65\x03\x0d\xee\x65\x03\x0d\xee\x63\x03\x0d\x1e\x62\x03\x0d\xde\x67\x03\x0d\xee\x67\x03\x0d\xbe\x65\x03\x0d\xbe\x67\x03\x0d\xbe\x26\x33\x08\x0d\x7e\x61\x03\x0d\x7e\x62\x03\x0d\xfe\x60\x03\x0d\x9e\x67\x03\x0d\x5e\x65\x03\x0d\xce\x65\x03\x0d\xce\x63\x03\x0d\x2e\x60\x03\x0d\xce\x67\x03\x0d\x4e\x24\x53\x82\x06\x6f\xb1\x81\x06\x9f\xb1\x81\x06\xdf\xb0\x81\x06\x3f\xb3\x81\x06\x5f\xb1\x81\x06\x4f\xb1\x81\x06\x97\xb0\x81\x06\x37\xb3\x81\x06\x77\xb0\x81\x06\x17\x91\x19\x82\x06\x97\xa1\x71\xdc\x21\x88\x70\x1b\x1f\x04\x11\x6e\x65\x03\x11\xce\x61\x03\x11\x2e\x65\x03\x11\xae\x64\xd3\xfa\x7e\x93\x8e\x3d\x89\x2d\x84\x38\x99\x0d\x84\x38\x85\x0d\x84\xf8\x9d\xcc\x30\x84\xb8\x96\x0d\x74\xb8\x8e\x0d\x74\xb8\x9e\x0d\x74\xb8\x91\x0d\x74\xb8\x89\x0d\x74\x38\x9b\x0d\xbc\x0c\x17\xb2\x81\x06\x17\xb3\x81\x06\x97\xb3\x81\x06\xb7\x90\x29\x43\x83\xdb\xd9\x40\x83\x3b\xd9\x40\x83\xbb\xd8\x40\x83\xbb\xd9\x40\x83\x7b\xd8\x40\x83\x07\xd9\x94\xba\xfc\x29\x76\xcb\xd0\xe0\x61\x36\xd0\xe0\x11\x36\xd0\xe0\x51\x34\x5e\x3f\x34\xb8\x82\x0d\x34\x78\x92\x0d\x34\x78\x81\x0d\x34\x78\x8d\x0d\x34\x78\x9d\x0d\x34\x78\x8c\x0d\x34\xf8\x92\x0d\x34\x78\x9c\x0d\x34\x78\x82\x0d\x34\x78\x9a\x8c\xdb\xcf\x3f\x77\xcf\xb0\x85\x0e\xcf\xb2\x81\x0e\xcf\xb1\x81\x0e\x2f\xb2\x19\xe8\x32\x4c\x79\x2e\x74\x78\x99\x4d\xfb\xf7\x02\x5d\xe2\x2b\xbc\x00\x72\xbc\xc3\x06\x72\x7c\xc7\x06\x72\x9c\x4a\xc6\xeb\xef\x32\xd9\x79\x1e\xa4\x38\x9d\x0d\xa4\x38\x83\x4d\xb1\xcb\x3c\xe7\x79\x90\x62\x1f\x36\x90\xe2\x0d\x36\xf0\x4a\xec\xcb\x06\x1a\xec\xc7\x66\xb8\xcb\x4c\xea\xe1\xdc\x78\x00\x19\x9c\x1b\x0f\x64\x03\x0d\x0e\x5a\x2a\x23\x02\x0a\x22\x1c\xcc\x07\x41\x84\x43\xd8\x40\x84\x43\xd9\x0c\xfe\xe3\xa9\x1f\xc6\x0b\xa0\xc5\xe1\x6c\xa0\xc5\x11\x6c\xa0\xc5\x91\x6c\xca\xab\x9f\xed\x28\xf2\x38\x45\xfe\x87\x0d\x14\xb9\x9a\x0d\x04\xf9\x91\x4d\x71\xf5\xb3\xed\xcd\x1e\xb2\x9c\xc5\x06\xde\x8d\xff\xb2\x29\x75\xf9\xca\xf0\x70\x96\x3c\x81\x0d\xf4\xb8\x8a\x0d\xbc\x1b\x37\x90\xc1\x59\xf2\x78\x36\x50\xe2\x38\x36\x5e\x97\x6f\x1d\x0f\x67\xc9\x6b\xd8\x40\x83\x63\xd8\x40\x83\xa3\xd1\xfc\x19\x00\x00\xff\xff\xc2\x6e\xde\xca\x4c\x18\x00\x00") + +func fontsPyramidFlfBytes() ([]byte, error) { + return bindataRead( + _fontsPyramidFlf, + "fonts/pyramid.flf", + ) +} + +func fontsPyramidFlf() (*asset, error) { + bytes, err := fontsPyramidFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/pyramid.flf", size: 6220, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRectanglesFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x58\xcd\x6a\xdb\x40\x10\xbe\xfb\x29\xbe\x83\x20\x97\xc8\xc2\xa1\x29\x14\x8c\xf1\xa1\xcf\xd0\x93\x60\x70\x5d\x39\x0d\xd8\x0e\x34\xa6\x50\xd0\xc3\x17\xcd\xee\xcc\xae\xf6\x4f\xeb\xa4\x50\x5b\x58\xf3\xcd\xef\xb7\x33\xb3\x39\x9d\x4f\x4f\x87\x06\x5f\xf1\x8c\xcd\x33\x36\xd8\xac\xfe\x0c\xc7\xdb\xe1\xfa\x72\x1e\xde\xd7\xa7\xf3\x09\x3f\xff\xe1\xfb\xe1\xef\xeb\x2f\xfc\x78\x3d\x9f\x87\x97\xc3\x3b\xb6\x97\xeb\x70\x19\xae\xb7\xdf\xfb\xeb\x70\x3b\xbe\x5d\xd6\xc7\xb7\xcb\x0e\x9b\xa7\xee\xdb\x97\x55\xd3\xec\x53\xff\xf7\x2b\x10\x61\xbf\x1a\x81\x51\x3f\x89\xf4\x13\x00\x58\x08\x46\x6a\x34\x02\x23\xbf\x6b\x9a\x06\xc1\x17\x23\x26\x61\x4c\x3f\x11\x03\x18\x39\xfd\x02\x18\xc5\xfa\x08\xb0\x2a\x96\x95\x7f\xa2\x42\x15\x58\xf7\x20\x5e\xc1\x3a\xe9\xeb\x10\x18\x2c\x8c\x6c\x54\x44\x1a\x98\xe2\x5d\x60\xcb\xd6\x1c\x2c\xb6\x66\x13\xc2\xe9\x98\xc2\x87\xf7\x61\xb5\xb2\x4e\xa3\x88\x83\x94\x2f\x62\x33\xac\xcb\x68\x9a\xff\x8a\xd1\x7d\x59\x7c\x22\x44\x22\x2d\x09\x7b\xd1\x02\x68\xa5\x3a\x51\x88\x16\x16\xc7\x1a\x46\xe6\xc3\x66\x31\x05\x11\x47\xf5\x27\x49\x79\xc4\x8d\x8c\x26\x49\x9b\x35\xe9\x72\x86\x8e\x43\xef\xd0\xb1\x58\xa7\x5e\x79\xa2\x12\xbd\x2d\xaf\x75\xcb\x95\x36\x4c\x96\x4d\x31\x4c\x05\xbc\xf0\x89\x62\x3e\xf8\x16\x48\x08\x44\x19\x0b\x91\xa8\x7c\x95\x44\xc5\x61\x40\x52\x5f\x08\x91\xaa\xb5\x1a\x51\xac\x97\x45\xd5\x72\x85\x03\x46\x5d\x8d\x56\x91\xc9\xf8\x3a\xab\xbc\x7b\xca\xbf\xf6\xc8\x36\x9d\x44\xc3\x8d\x4e\xb9\xb1\xc5\x96\x51\x3d\x7a\xa6\x48\x4f\xbd\xe5\xa5\xb2\x4f\xb9\x49\xb3\x72\xbb\xba\x5b\x99\xfd\xca\x72\x64\xd2\xe5\xeb\xdc\x61\xa7\xf6\x3a\xe6\x62\xa0\x4f\x13\x19\x1e\xa3\xf8\x3c\x25\x4e\xef\xd4\xa8\x0c\x83\x43\xc7\x16\x60\xda\xd7\xb4\x67\x57\xc0\x48\x60\x44\xb6\x57\xd4\x59\x83\x5a\x6b\xab\x60\x10\x58\x6f\x67\x8b\x12\x82\xba\xe5\x94\x44\xcd\xb7\xd2\xc9\x08\x36\xa2\xa2\x00\x0a\xf3\x9c\xac\xb0\x36\x7e\xa8\x00\x22\xed\x9a\x75\xc1\x1a\xfb\x66\xf0\x6e\x3e\x7f\xd4\xc9\x76\xd9\x49\xf3\x60\x60\xf6\x81\x4a\x4d\x32\xc7\x12\x7f\x4d\xa8\x81\x8d\x11\xec\x2e\x4e\xde\x97\x12\x8a\x17\x82\x2a\x96\x44\xd6\xe4\xbc\x83\x53\xba\x70\xde\xea\x0a\x10\x72\xd2\x2d\x3b\x35\xb1\x79\x93\x1c\x77\xb5\xa0\xcf\x92\xcb\x3c\xa0\x2f\x9d\x6e\x7f\x83\x0c\xca\x5d\xb4\x86\xc0\x5a\x5b\x49\xe5\x00\x56\xda\x72\x12\x99\x24\x44\x2c\x89\x9c\x0c\x66\xee\x6c\xc1\x73\xcb\xc5\xe8\x0f\x49\x7b\xac\xfa\x60\x68\xf9\x43\x32\x33\x9e\xed\x2e\xe8\xc6\x6a\x92\xd4\xbc\xd5\x8c\xc9\x09\xa8\x63\x2e\xff\xae\x30\x2f\x13\x8e\x15\x6f\x00\x6e\x63\xf3\x56\x83\x07\xe3\xfc\x63\x6a\x7d\x80\x9f\xb6\xe2\xa6\x81\xe4\x72\x94\x11\x25\xb8\xb4\xdd\xa3\xb5\x5d\x5e\xf6\xa4\xee\x70\xfb\xf9\x92\xd6\x78\x39\xca\x66\x00\xfe\x3d\x0b\xc9\x0d\xc9\xbb\x7b\xa4\xa2\x96\x95\x2e\x49\x9d\xb4\xd1\x07\x13\xca\x63\xc6\x28\x72\x46\xfd\xf3\x94\x6a\x9a\x99\x39\x90\x48\x69\x3a\xea\x42\x2e\x6b\x8a\xb9\x46\x58\xa8\xaa\x0a\xe9\xf5\xac\x48\xbc\x8a\xba\xbb\x55\x6b\x99\xf9\x35\x5a\xe7\x57\xf1\x62\x06\x7c\x51\xf4\xae\x3b\x67\x2a\x17\x35\xe9\xfc\xed\x68\x6e\x81\x32\xd4\x29\xf8\x9d\x3c\x05\xf3\xc4\xb5\x99\xc3\x6d\x5e\xbb\x95\x9b\xf4\x5e\x0d\x1d\x7c\xd0\x2b\xb6\xf4\xaf\x39\x85\x67\x64\x4e\x5e\x11\x3d\x1d\x91\x1d\xd2\x3f\x02\x44\x6b\x0c\x8d\xf3\x8b\x45\xb2\x07\xfb\x7f\xa0\x90\xf5\xb3\x62\xa3\x4f\xc1\x2a\xd6\xa0\x14\xac\x62\xe6\x4b\x6d\xed\x7d\xac\xd4\xc6\x33\xa2\x29\x86\x06\xa2\x4b\x64\x5e\xba\xc0\x30\x1b\xe4\xcc\x30\xec\x7f\x00\x00\x00\xff\xff\xbd\x5d\x2e\x99\x39\x13\x00\x00") + +func fontsRectanglesFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRectanglesFlf, + "fonts/rectangles.flf", + ) +} + +func fontsRectanglesFlf() (*asset, error) { + bytes, err := fontsRectanglesFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rectangles.flf", size: 4921, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsReliefFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\xb9\x6e\x1b\x31\x10\xed\xf5\x15\x0b\x28\x6d\x44\xc8\x08\x62\xb8\x4b\x1d\xc0\x2e\x52\x13\x20\x14\x47\x42\x04\x3b\x2e\x1c\xa8\x48\xc3\x6f\x0f\xac\x5d\x72\xe7\xcd\x0c\xaf\xb5\xe4\x8a\x2a\xc4\x6b\x39\x7c\x7c\x73\xae\x74\x78\x3e\xdc\xec\x3e\x0d\xb7\xc3\xed\xb0\xfd\x3a\x7c\xde\x0e\x37\xab\x1f\xfb\xe7\xe3\xfe\x30\xfc\xfc\x37\x3c\x1c\x1f\x9f\x86\xfb\xe3\xcb\xfe\xf5\xef\xf0\xb0\xb9\xdf\x8c\xdd\x6f\xbf\x4e\xaf\xbf\x77\x7f\x36\xbb\xc7\xcd\xe9\x69\xf5\xfd\xf4\xb2\x1f\xb6\x77\x77\x5f\x56\xee\xed\xb3\xae\x6f\xe2\xd0\x78\x6f\x45\x83\x6b\xb0\x63\x5a\xb0\xce\x4c\x1b\x42\x6f\x5e\xcd\xf6\xe6\x6e\x58\x08\x22\xa6\x13\xa7\x8f\x6d\x5a\x03\x99\x74\x78\xee\x1b\xba\xe9\xbc\x23\x8a\xb3\x11\x04\xce\x7b\xb8\x13\x0a\x0d\xb7\x0e\x8f\x8c\x7b\x89\x94\xf5\x0a\xe5\x71\x8a\x04\xc4\x88\x65\x7a\x1c\xe7\xbd\xb7\xe3\x7c\x3c\x88\x3c\x2f\x20\x8e\xe8\xd6\x2b\x13\x97\x95\xef\xb0\x2f\x20\x0d\xe7\xca\xd6\x51\x23\xa0\x1b\xc5\x03\xac\x35\x00\x50\x55\x4a\xd0\xab\x1d\x2f\x67\xe7\x1b\x5b\x3e\x4f\xb9\xd5\x69\x04\xa9\x7c\x60\xd0\x74\x52\x8f\x29\x56\x94\x6f\xe2\x5d\xad\x76\x45\xb5\x9f\xb0\xaf\x54\xbf\x05\x86\x20\x65\xec\x36\x59\x2a\x03\xa0\xfa\x2b\x71\x9c\xc9\xba\xc1\x76\xc1\x10\xe0\x48\x2f\x75\x28\x01\x03\x34\xee\xa0\xd0\x35\x0a\x93\xba\x6b\xcd\x16\xc9\xc9\xa0\x14\x54\x79\x7f\x51\x28\xe1\x82\x30\x51\x10\x8a\x0c\x4d\x98\x8c\x90\xa5\x98\x32\xd5\x6a\x82\x53\x0e\xd7\x61\x00\x04\x2b\xd1\x42\x4b\xc6\x79\xc1\x7b\x78\x18\xc3\xeb\xeb\xe1\x4a\x42\x7c\xbf\x9d\xd6\x41\x69\x83\x58\xbf\x59\xe7\x46\x08\x15\x8d\xf1\x53\xa4\x13\xa3\xa6\x1d\xe7\xe8\x1f\x0f\x8c\x28\x22\x83\x91\x3f\x32\xe3\x30\xca\xe7\x42\x59\x2a\x7c\x55\x84\x35\x0a\x4a\x39\x39\x0d\x53\x33\x98\x90\xd4\x33\x31\x8e\x62\x90\xb3\xdc\xfb\xa2\x05\xc6\xa3\x49\x22\x33\xc2\x7f\xc4\x1e\x97\xb0\x9b\x92\x6c\xee\x9b\x46\x19\x64\x64\xcf\xbc\xa7\x64\x17\x56\x96\xe2\xb6\x14\x82\x75\x32\xd6\xbd\x03\x77\x7a\xd0\x24\x5b\x85\x3a\x27\x21\x6d\xa5\x9a\xef\x46\xd9\xc4\x68\xae\xc3\x37\xc1\x3d\xae\x48\xdc\x05\x56\x97\xd8\xe0\xb4\x1b\xfc\x56\x76\x0c\xe3\x55\xc9\xf8\x9a\xfb\x2a\x5d\xe3\x65\x09\x51\xbe\x29\xa6\x4e\xac\xcb\x15\xb2\xf3\xda\x4f\xa8\x35\x3b\xa8\xb5\x2c\x54\x8a\x35\xfe\x82\x51\x82\x29\xdc\xa6\xb4\x6f\xd4\x83\x32\xb2\x4b\x56\xab\x42\xbd\x44\x94\xe0\x2b\x1a\xf9\x17\xc2\x4d\x4d\xba\x25\x4a\x34\x46\xe5\xa5\x7c\x6b\x2b\xe3\xe4\x42\xbe\xcb\xef\x49\xe9\x41\x46\x76\x65\x90\x5f\x64\x27\xb5\xe2\x2c\x94\x1e\x22\x9a\x88\x57\x9e\xd9\x2d\x2c\x16\x04\x75\x43\x47\x28\x75\x5c\x72\xee\x16\x19\xac\x86\xbf\x1b\xb4\x46\x80\x2c\x0f\x8b\x34\xcb\xbc\x42\x84\x6e\x07\xef\x59\x55\x51\x91\xe4\x0d\xe3\x31\xad\x62\x27\x93\x5b\xe2\x89\xf0\x02\x81\x3f\x26\x10\xac\x82\x47\x3d\xd3\xc9\x9a\x15\x43\x6b\xa2\x90\x0e\x67\xcc\x2f\x2f\x86\x17\x0c\x8a\x1e\xd3\x83\xda\xe7\x32\x83\x82\x16\xd6\xd3\x6f\x49\x6f\x98\xc3\x8c\xf8\xee\xc5\x6e\x2f\x76\x7b\xb1\xdb\x8b\xdd\x5e\xec\xf6\x62\xb7\x17\xbb\xa0\x97\x9a\x20\xdf\x8b\xdd\x5e\xec\x3a\x99\x1b\x8c\xc7\x02\x57\xd4\xad\x3c\xcf\x14\xff\xd4\xc5\x46\x39\xbf\xe2\x24\x1d\x55\xc2\x96\xe2\x66\x25\x81\x73\x85\x4a\xcb\xac\x19\x7f\x60\xe9\x79\xe5\xc0\x7f\xb5\x60\xd1\x39\x69\xc6\xad\x46\x1b\xcc\x8c\x20\xfb\x7f\x00\x00\x00\xff\xff\x8a\x69\x12\xdc\xc7\x21\x00\x00") + +func fontsReliefFlfBytes() ([]byte, error) { + return bindataRead( + _fontsReliefFlf, + "fonts/relief.flf", + ) +} + +func fontsReliefFlf() (*asset, error) { + bytes, err := fontsReliefFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/relief.flf", size: 8647, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRelief2Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\x3b\x6f\xdb\x30\x10\xde\xf5\x2b\x0e\x70\xd7\x86\xb0\x51\x34\xc8\xd6\x4e\x9d\xba\x74\xe6\x92\x20\x72\x1b\x40\x69\x01\xa7\x46\xe1\x7f\x5f\xd4\x12\xa9\x7b\x7c\x7c\x48\xb6\x3b\x31\x83\xf9\xd2\x1d\x3f\x7e\xf7\xe0\x31\xfb\x61\xbf\x7b\x7c\x47\xf7\x74\x4f\xdb\x8f\xf4\x7e\x4b\xbb\xee\x5b\x3f\xbc\xf4\xfb\x1d\x3d\x9d\xe8\x6b\x7f\x18\x5e\x7e\xd2\x97\x43\x7f\xfa\xf3\x6b\xd8\xd3\xeb\x79\xfc\xe9\xe9\xf0\xf8\xe3\xf5\xed\xee\xf8\xdc\x0f\x77\xfd\xf3\xb1\xfb\x7c\xfc\x7e\x7c\xfb\x4d\xdb\x87\x87\x0f\x9d\xff\xf7\xb7\xa9\x6f\xe2\xd0\x39\x47\xa6\x91\x6b\x42\x62\x5a\x20\x1f\x04\x42\x6f\x5e\xcd\xf6\xe6\x6e\x58\x08\x2a\xa6\x1d\xa7\x3f\x5a\xb4\x26\x74\xf2\xe1\xb9\x2f\x84\xce\x12\x51\x1d\x45\x10\x72\x5e\x9e\x49\x2a\x0d\xa7\x0e\x9f\x8c\xb2\x4c\xcb\xa6\x93\xfa\x34\x45\x06\x62\xc4\x32\x7d\x2e\xe7\x9d\xa3\x71\x3e\x6e\xc4\xbe\x37\x10\x47\x74\x9b\x6e\x5e\x06\xbf\x41\x2e\x20\x0d\xfb\xda\xd6\x0b\x2a\x98\xa0\xf9\x40\xb5\x12\x20\x34\x4a\xb0\x2b\x8d\x87\xa3\xf9\xc4\xa4\xe7\x39\xb7\x98\x46\xa1\x55\x0f\x94\xeb\xa4\x3e\x03\x5e\x94\x6f\x66\xa8\xe8\x88\xb0\x9f\xf0\xaf\x54\x7f\x09\x0c\x43\xca\xd8\x5d\xe4\xa9\x0a\x00\x8c\x57\xa7\xa4\x95\xef\x0a\x47\x10\x5b\x02\x1b\x5a\xc0\x42\xb9\x0e\x50\xd1\x45\x4c\xe2\xd0\x9a\x3d\xd2\xf8\x00\xa3\xa0\x2a\xfa\x8b\x4a\x19\x17\x8c\x89\x82\x52\xc9\xd0\x84\xc9\xea\x02\xae\xcc\xad\x9a\xe0\x54\xc3\xf5\x32\x01\x0a\x2f\x41\xa9\x25\x13\xbc\x22\x7a\x74\x1a\x93\xc7\xc7\xe9\xca\x42\xbc\xdc\x4f\xeb\xa0\x2c\x83\x58\x2f\x8c\xb9\x31\x4a\x4d\xe3\x42\xa6\x33\xa3\x45\x12\x67\x4c\x71\xc3\x88\x22\x32\x18\xf9\x63\x33\x5e\x66\xf9\x5c\x2a\x4b\xa5\xaf\x8a\xb4\xc6\x41\x81\x9d\xd3\x30\x91\xc3\x78\xe8\xbd\x28\x1a\x12\xb3\x3a\xfa\x9c\xb9\x84\x59\xc8\xd8\xf8\x31\x32\x3e\xe1\x37\x25\xdd\x3a\x36\xd1\x20\xa3\xdb\x15\x75\x17\x56\xd6\xe2\x26\x0e\x81\xbc\xcd\x75\x17\xe0\x4e\x0f\x16\xe9\x86\x50\x1d\xbf\x3e\xcc\x4a\x35\xdf\x0b\x75\x33\xa7\xb9\x0d\xdf\x0c\xb7\x93\x29\x00\x08\x5d\xcd\x07\x27\x69\x11\xb7\xb6\xa3\x79\x05\x37\x3e\x0a\x5f\xd0\x65\x0c\xe7\x2c\xa4\x8e\x20\xa4\x55\x5d\x0e\xc8\xce\x5b\x3f\x61\xd6\xec\xa0\xd6\xb3\xa4\x51\x88\x1b\x65\xaa\x06\xd6\x67\x09\x65\x70\x4a\x59\x1f\xbb\x42\x46\x77\xc9\x6b\xa1\xba\x6b\x64\x09\xbd\x82\xc8\xbf\x12\x6e\xee\xd2\x91\xba\x6b\xe1\xbe\x9c\x6f\xb4\x32\x4e\xae\xe4\xbb\xfc\x4e\x4a\x0f\x32\xba\x2b\x93\xfc\x2a\x3f\xa9\x55\x37\xbf\xa2\x3d\xca\x26\xe6\xc9\x33\x87\x05\xc9\x28\xa9\x1b\x7a\xe7\x12\x67\x28\x9c\x22\x83\xd5\xe9\xb7\xc1\xd2\x0c\x90\xe5\x61\x95\x65\x55\x86\x33\xa9\xdb\x8b\x77\x56\x55\x56\x64\xf7\x46\x84\x07\x3b\x99\xbb\x25\xee\x28\x1e\x10\xf2\x9f\x09\xdc\x34\x1a\x0f\xbe\xe9\x6c\xcd\x2a\x53\x6b\xa2\x90\x0e\x7b\xcc\x8f\x17\x46\x7c\xd2\x8e\xe9\x41\xed\x77\x99\x41\xc1\x0a\x9b\x2e\xf8\x4b\x58\x07\xbf\xad\xd8\x6d\xc5\x6e\x2b\x76\x6f\x50\xec\x7a\x67\xaf\xa7\x56\xec\xae\xd0\xdd\x8a\xdd\x56\xec\xb6\x62\x17\x64\x93\x56\xec\xae\xb2\xac\xca\x70\x26\x75\xaf\x28\x76\xcd\xdd\x10\x41\x0a\xbc\xb2\xeb\x70\xb1\x3a\x9d\x3f\xdf\x80\xfd\x2b\x76\xc2\xa8\x12\xbe\x14\x85\xc1\x05\xae\x0d\x6a\x3d\xb3\x66\xfc\x1f\x4b\xcf\x1b\x27\xfe\x9b\x25\x8b\xc6\xc9\x62\xdc\xe5\x15\xa9\xfb\x6f\x00\x00\x00\xff\xff\xa9\x47\x91\x3a\xcd\x21\x00\x00") + +func fontsRelief2FlfBytes() ([]byte, error) { + return bindataRead( + _fontsRelief2Flf, + "fonts/relief2.flf", + ) +} + +func fontsRelief2Flf() (*asset, error) { + bytes, err := fontsRelief2FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/relief2.flf", size: 8653, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRevFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\xbd\x72\x1b\x39\x0c\xee\xf5\x14\x28\xae\xb8\x14\xd1\x58\x4e\x8d\x19\x35\x29\xd3\xe5\x05\x9c\x58\x9a\x14\xb6\x33\x23\xcb\x99\xc9\xdb\x67\x2c\x89\x24\x3e\x00\x24\x41\xee\xda\x77\xd9\xc5\xae\x96\xe0\x87\x1f\x7e\x00\x77\x8f\x4f\xc7\xfb\x87\xff\x68\xb7\xa3\xdd\x1d\x7d\xb9\xa3\xcf\x3b\xba\xdf\x9c\x0e\x7f\x0e\xa7\xd7\xc3\xf6\xf8\x74\xa4\x1f\x7f\xe9\xdb\xc3\xf9\x4c\x5f\xb7\xf4\xfd\xd7\xdb\xe9\xf5\xfc\xfb\xe5\xff\xf3\x45\x78\x3e\xec\x7f\x3e\x3e\x6c\x9f\x4f\xaf\xdb\xb7\xe7\x97\xed\xe1\xf1\xed\xd3\x66\xc3\xef\x7f\xfb\x75\x4e\xd7\xf3\x7e\xc3\x44\xfd\xa3\x7d\xb2\xa8\x28\x3f\xa6\x9f\x88\xdf\xff\xc1\xaf\x6b\x48\x45\xbc\xde\xbe\xcd\xa8\x65\xba\xfd\x2d\x7d\x86\x2d\x04\x07\xc4\xf5\xf1\x34\xf8\xa2\xf3\xe6\x8d\xeb\xff\xe9\xbe\x7c\x9e\x8a\xd2\xea\xf3\x05\x84\x1c\x5b\x05\x21\xc2\x40\x9c\x02\x41\x0c\x16\xb3\x98\x58\x28\xbd\xfc\x20\x3c\xc1\x29\xca\x9c\xef\xc7\x3c\x71\xd5\x99\x32\x80\xdc\xfb\xc5\x13\xc9\xd3\x62\xb2\x12\x82\x9c\x64\x97\x01\x5d\x10\x25\x2b\xe5\x91\x63\xc7\xac\x2f\x7b\x26\xa3\xce\x70\x12\x46\x5f\x10\x8e\x85\xb0\x15\xcd\x72\x8e\xe0\x30\x23\x54\x01\xf5\x93\x02\x64\x48\x71\xa2\xa2\x4e\x2c\x09\x71\xbf\xbf\x24\x82\x99\xa9\x64\x5c\x12\xec\x81\xf0\x9f\x89\x82\x08\x1e\xfd\xc4\x89\xdb\xe1\xca\xca\x8e\x49\x3d\x43\x76\xf4\x28\x1a\x95\x13\x95\x0b\x09\x53\x06\x1a\x79\x8a\x55\x24\x60\x6d\x97\xc4\x64\x99\x9c\xda\x22\x8f\xc3\x05\x65\x52\x66\x9c\xeb\xf0\x59\xb9\xe8\x51\x54\x5a\x01\xa1\xe8\xb0\x92\x74\xf3\x72\x17\x04\xcb\xca\x90\x86\x30\x38\x06\xb8\x58\x6a\x23\x60\x75\x63\x47\xd6\x56\x22\xe3\xc1\x59\x0d\x0f\x41\x79\xab\x8c\x91\xda\xb4\xcb\x1b\x78\x74\x4a\x82\xe1\x04\xf5\x4c\x71\x17\xcb\x22\x23\xbd\x40\xae\x6a\xbc\xf0\xf1\x80\x06\x48\x77\x7d\x01\x1c\xcb\xa2\x22\xa7\xa9\xf4\x52\xcc\xd9\x5c\xb8\xb8\x8f\x87\x09\xdb\x0f\xad\x0e\x61\xf7\xf0\x20\x38\x0c\x78\x0c\x8f\xe7\x9f\x25\x4c\x13\xbd\xa8\xfa\x07\x70\xd7\x03\x01\xbd\xc8\xe2\x31\x83\x78\xac\xb3\x5a\x81\x48\x4d\x9d\x9f\x3f\x0c\x14\x58\x59\xef\x9d\xf2\xd1\xbe\x3f\xaf\xc2\xdf\x42\xb0\x6a\x7b\x44\x89\x29\xf5\xa5\xd8\x07\xf7\x20\x89\x80\x1e\x85\xdd\x33\x65\xbd\x56\xca\xe7\x4b\x3c\xd8\x3c\x65\x4b\xcc\x37\x15\x9b\x0d\x4d\xd8\x12\xca\x76\x62\xaf\xc2\x49\xdb\x3a\xad\x5a\xbc\xee\x4b\xce\xc8\xe9\xdd\x94\x25\x99\x2d\xaa\xfb\x4e\xc7\xdb\x68\x32\x14\xb9\xb5\xe5\x2a\x08\xa4\x63\x4d\x30\x44\xf6\xfe\xfc\xf3\x0d\x4f\x08\x77\x11\xd9\xca\x31\x21\x4b\x3d\xa0\xbf\xed\x89\x9e\xdb\x97\xc8\x71\x10\x03\xd6\xab\x70\x84\x9e\x0f\xe5\xc4\x47\x82\x90\xa1\xaf\x80\x88\xb7\xe6\x95\x09\xdc\xe7\x07\x97\xe8\x64\x8c\xa7\xf2\xc3\x82\xb8\x29\xcc\xd9\x3c\x71\x86\x58\x7b\xe5\xc7\xf4\xa0\x13\xb2\xe1\x81\x02\xa2\xbf\xf6\xeb\xc4\x51\x78\x3f\xb5\xd4\xd9\xc5\x62\x6c\x88\x8c\xfa\x2c\xf8\xd1\x72\x6f\xd9\xb1\x6d\xbc\x30\x89\x49\x16\x1d\x26\xb7\xd7\x9a\xb9\xa8\xe1\x41\x1b\x24\x26\xc8\x76\xa5\x56\x93\x37\x91\x89\x83\xc2\x80\x2b\x59\xb3\x8e\xc6\x58\xab\x1d\x23\x95\xb3\x2f\x4b\x3d\xac\xb7\x94\x1e\x88\xf1\xda\x61\xf6\x4a\x6b\x33\xe6\xbc\xf5\xaa\xc1\x91\x1c\xb4\x62\x15\x25\xe9\x89\x39\xb6\x5d\xe4\x89\xec\x53\xaf\x67\xec\x8f\x1d\x2b\xe5\x8d\x06\x75\x2d\xb9\x06\x62\x51\x1e\xd4\x92\xf7\xc3\xab\x28\xe3\x37\x01\xef\xeb\x08\xe1\x0b\x98\xa6\x27\x2c\x14\x3b\xf1\xe0\x9d\xb4\x30\x14\xb8\xf6\x9d\x7c\x69\xa0\x5b\x03\xaa\x59\xb5\xc0\x37\x3e\x55\xd6\x68\x33\x18\xd0\x45\xc1\x5a\x92\xda\xaa\xa6\x92\xbb\x61\xe4\x9a\x27\xd8\x93\x05\x29\xb4\x6b\xb6\xe8\xad\x80\xbe\x86\xce\xb5\xde\x0c\x39\x1f\x91\x21\x66\xb4\x0c\x6d\x46\x3a\x13\xce\x24\x2c\x67\x6a\xf9\x9a\x92\xeb\xf6\xa3\x3c\x77\xae\xda\x7c\x33\x43\xd8\x27\x12\x95\xb0\xb7\x34\xc3\xc6\xc5\x15\x54\xf4\xc5\x94\x41\x64\x67\xbe\x5a\xf3\x7e\x4c\x63\x06\x8e\x59\x5d\x47\x10\x25\x50\x96\xa1\x44\xdb\xf8\x13\xa6\xba\xff\xc5\xb0\x29\xe8\xc9\x3c\x01\x52\x6d\xde\x0e\x17\x47\xb1\xa3\x31\x87\xf6\x83\x15\x8c\x67\xac\xd0\xf2\xd5\xa0\x1d\x64\x0d\xea\xd8\x01\x84\x2a\x78\x56\x70\x84\x68\xcd\xf1\xee\x90\xb8\xd8\x3a\xc6\xee\x27\x1a\xa5\xf5\xb2\x8d\x9d\x28\xb9\xc7\xfc\x5c\x59\x96\xe6\x38\xe2\x0a\x64\x29\x37\xcf\x56\x70\x85\x5a\x54\x04\x75\x25\xe6\x8a\x9a\xb1\xed\xa3\x53\x8c\x23\xf2\x6d\x5f\x61\x8a\x6b\xf8\x45\xab\x2e\x4d\xd1\x78\xe0\xac\x53\x69\x33\x92\xfe\x31\x02\x99\x20\xc2\x66\xd6\x43\xff\x26\x85\x71\x3b\x02\xb4\x67\x85\x89\xaa\x8a\xdf\x74\xd5\x9b\x81\x90\x38\x9a\x09\x2e\x49\x15\x4a\x8d\x51\xb0\x77\x26\xf5\xba\x8d\xba\xaf\xe7\xbc\x36\xa8\x9f\xc6\xf1\xec\x9d\xab\x51\xad\x5c\x2d\xee\x28\x2e\xf3\x53\x4c\x45\xa7\x73\xa1\x5f\x6e\x11\xce\x0d\xf3\x23\x06\xc0\xa1\xdf\xd1\xac\x6a\xf3\x52\x7a\x88\xac\xa6\x40\xed\xef\x4a\xb8\x65\x91\x13\x94\x1c\x2f\x69\x6f\x47\x98\x3c\x6f\xe7\x33\xa8\xf3\xce\x6c\xf3\xbc\x53\x58\x62\x65\x67\x64\xee\x1e\x76\x93\xbb\x39\x04\x6e\x1d\x62\xfb\xbe\x63\x2d\xd9\x82\x30\xbb\x33\x11\xd0\x6c\x25\x39\x7b\x7a\xb5\x45\xef\x7e\x95\xf0\x41\x64\x3f\x92\x5d\x5d\x69\x6e\x62\x67\x79\xa6\xad\x5a\xf7\x02\x96\xb4\xf3\xa6\x35\xec\x94\x9a\x61\x31\x39\xfc\x46\xcb\x5d\xd4\x12\xdc\x3a\x5b\xae\xa1\x39\x96\x76\x1a\x76\x8e\x85\xa5\xc6\xfd\x6f\xbf\xf9\x17\x00\x00\xff\xff\xef\xe0\x0c\x2c\x8f\x2e\x00\x00") + +func fontsRevFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRevFlf, + "fonts/rev.flf", + ) +} + +func fontsRevFlf() (*asset, error) { + bytes, err := fontsRevFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rev.flf", size: 11919, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRomanFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x5f\xab\xe4\xb6\x15\x7f\x9f\x4f\x71\xf0\x0c\x38\x7d\xa8\xc8\xa6\x85\x9e\x40\x28\xa5\xf4\xa9\x90\x60\xfa\x70\xc1\x2c\x0b\x5a\x47\x09\x0d\x69\x56\xb0\x65\x1f\xfa\xed\x8b\xce\x1f\xe9\x48\x96\x3d\xf6\xdc\xb9\xa5\xc3\xbd\x33\x92\x2c\x5b\xbf\xf3\xff\xe8\xc8\x3f\xff\xeb\xe7\x6f\x3e\xde\xe0\xdd\xd7\xe9\xef\x0f\x5f\xc3\xef\xdf\xc1\x37\x97\x7f\xc4\xdf\x3e\x7e\x82\xe5\x3f\xf0\xc3\x2f\x3f\xfe\x0a\xdf\xff\xf2\xe9\xa7\xcf\xff\x86\x1f\xdc\xf7\x8e\x9b\x7f\x09\x5f\x3e\xff\xf3\xe3\x6f\xee\xe3\x8f\xee\xcb\xaf\x97\xbf\x7f\xf9\xf4\x13\xbc\xfb\xf6\xdb\x3f\x5e\x6e\xb7\xdb\xf5\xd4\xd7\xf5\xe2\xa2\xbb\x5d\x2f\x88\x98\xbf\x67\x9c\x6e\xd7\x8b\xc7\xf1\xa6\x57\x79\x04\x00\xea\xef\xeb\x25\x62\x84\x88\x31\x4d\x7f\x19\xc1\xbf\x8c\x7c\x09\xf2\xa4\xd7\xb7\x72\xd3\x45\xf9\xca\x57\x1d\x8e\xf2\x45\x43\x0e\xcd\x47\x91\x94\x39\x34\xab\x9e\x93\x6f\x2c\x73\x78\xa8\x1e\x31\x78\xf2\xe7\xe8\x10\x8d\x45\x59\x3c\xd0\xb2\x89\xd1\xef\x01\x79\xcc\xcf\x88\xf8\x57\xc7\xf7\x22\x7c\x10\x31\x20\x4e\xa3\x8e\x1d\xe1\x51\x12\x04\x00\x22\x3d\x72\x10\xf0\x96\x05\xdc\x66\x92\x0a\xd1\x96\x5a\x92\x74\x7a\x04\x40\x96\xf7\x9a\xb0\xba\x4d\x0f\x8a\xd1\x15\xee\x8e\xe0\xd1\x51\x07\xd3\xaf\xae\xed\x11\x1d\x4e\xfa\x80\xc4\x87\xf7\x82\x90\x6f\x91\x7b\xfc\x12\xc3\x34\xa6\x6e\xc5\xcc\xbd\x0e\xd1\x4e\x8c\x24\xcc\x23\xf4\x34\x75\xeb\x9b\xf1\x0b\x0f\x88\x00\xc1\x04\xe6\x27\x11\x94\xa6\x78\x41\xe5\x07\x81\x90\x7f\xae\x97\xe8\xba\x53\x49\xd8\xfa\x53\x2d\x31\x8c\xe6\xfe\xcb\x5a\x57\x3c\x3a\xcc\x37\xa0\x3e\x0f\x86\xe7\xd9\xd3\x06\x5f\x49\x01\x56\x9d\x62\x34\xbb\xd3\x8e\x8a\x6c\x5f\x34\x95\xd3\x69\x05\x7a\x9c\xe4\x1a\xf0\x79\x26\x1d\x45\xd8\x53\x2a\xc8\xb2\x07\x91\x3b\x18\x9b\xcc\x16\x99\xed\xb1\x58\x23\xf3\xf2\x10\x42\x17\x63\x14\xc5\x83\x80\xd3\xe8\x67\x5c\x84\x70\x06\x80\xbb\x1d\x8f\xb8\x40\xb2\x45\x82\x97\x6e\x4e\x0f\x39\x27\x46\x17\xd3\x68\x44\xf6\x3c\x70\xe7\x37\xcd\x8b\xfa\x94\xf5\x6f\x43\x93\x0b\xd3\x30\xcc\xc8\x34\xf1\xa2\x1f\xb2\x5b\x04\x57\xc0\xba\x30\x65\xff\x1e\xc9\xc9\xb0\x51\xaf\x94\xf6\x28\x4d\x07\x21\x7c\x87\xb8\xb8\x7c\x25\xb1\x33\x69\x05\x79\x43\x87\x38\xb1\x19\x2f\x21\xf9\xf2\xb3\xd6\x51\x87\xba\x14\x38\xd4\x6d\x87\x11\xa5\xe3\xc2\x48\xa2\x14\xb5\x89\x91\xd8\x9b\xf9\x8b\xf9\x1e\x00\xba\x72\x0e\x42\x94\x0f\x29\xd7\x34\xf0\xe7\x76\xbd\x70\x0c\x5b\x5c\xbe\xc9\xb7\xfc\x61\x51\x3f\x85\x0b\x49\x14\x25\xba\xe7\x80\x15\xa4\x0d\x82\x67\x1a\xe6\x45\x2c\x12\xdf\x33\x06\x09\xad\xc4\x87\x89\x5d\x32\x2e\x31\xe0\x39\xfd\x8e\x86\x0b\x41\x78\x80\x25\xc9\x31\x41\xd6\x46\x59\x1b\x66\x6d\x9c\xcd\x19\xc5\x19\x08\xa4\x8d\xa2\x8e\x42\x37\x47\x83\x19\xd1\xb9\xec\x5d\xbc\x8a\x45\x9d\x89\x4f\x04\x4b\x48\x62\x49\xd0\xb4\x25\xc6\xd3\x5c\xb0\x10\x28\x6d\x4a\x9c\x75\xad\x3b\x01\xff\xb2\xa4\x67\x1b\x6b\xab\xf2\xb0\x62\xae\x71\x1a\xcf\x72\x61\xc3\x0f\x4b\xe8\x1f\xc6\xa6\xdd\x7a\xe3\xa3\x37\x7f\x68\x42\x8e\xe2\x10\x51\x06\xba\xec\xc2\xc4\xd2\xd0\x7c\x66\x5e\x74\x8e\x4f\x4d\x9e\xec\xe7\xe5\x56\xdf\x5e\x37\x1e\x89\x5e\xa7\x23\x9a\x59\x77\x1f\xe4\x16\x69\xbb\xf8\x59\x2f\xa2\xe3\x3b\x46\xf6\x05\x0b\x3b\x23\xf1\xd0\x92\x8e\x1a\x67\x9d\x34\xd5\x58\x47\xce\x1d\x39\xed\x3c\xad\x17\x16\x03\x04\x36\x2f\x4f\xee\x28\xa4\x65\x87\x25\x00\x50\xe4\x03\x40\x97\x92\x69\x17\x12\x33\x1c\xc0\x1c\xa7\x61\x61\x50\x64\x22\xa4\xa4\xb4\xc2\xcc\xcf\x9c\xea\xf5\xee\xf4\x8a\xdb\x76\xf5\x84\xb4\xe5\x70\x76\xc4\xe1\xa0\x43\xc5\x45\x78\x19\x52\x5f\xc7\xde\x5c\xd2\xe2\xec\x38\x78\x16\x47\xd2\x48\x23\x34\x2b\xd6\x60\xd6\xf0\xb6\x46\xae\x97\xec\xe1\x98\x85\x1e\xc5\xc5\xb0\x20\x41\x2c\x5c\x4d\x9c\x02\x0c\x21\x1b\xcd\x55\xf1\x34\xda\x15\x5f\x93\x66\x91\x43\x68\x73\x8a\x15\x94\x55\xb7\x12\x6c\x4e\x6f\x18\x95\x49\x70\xf4\xe6\xfd\x2e\xa7\x39\x14\xd0\x40\x13\x9d\x47\x61\x59\x6e\xb5\xec\x02\xcb\x2f\xc3\xb0\x43\x7d\xc9\xc2\x2c\xcf\x56\x02\xbb\xdf\xb7\x00\x29\x66\x29\xbe\x24\xa3\x6a\x79\x00\x2b\xce\xd2\x05\xb3\xc7\x28\x93\xa3\xe6\x6e\xf4\x09\xf8\x0a\xbe\x3d\x13\x16\x28\xac\x83\x38\x76\xb5\xac\x55\xb3\x56\x93\xf6\xfa\x86\x2e\x32\x6b\xca\x55\x1a\x5d\x7b\x5c\x9c\xf5\x02\x92\x01\xd4\x16\x68\x13\xed\x28\x16\x0a\x1b\xd7\x6d\x5f\xb9\x17\x7b\x4e\xe4\x30\x40\x05\x76\x7b\xca\x0e\x00\x34\xeb\x64\x32\xe5\xe2\x91\x56\x72\xbd\xec\x7b\xa8\xaa\x32\x6d\x06\x45\xe1\x2a\x18\xf0\x24\x35\x71\x09\xd4\x0d\x39\x4a\x51\xcc\x7d\x9f\x1f\x83\x88\x9e\x13\xe0\x32\xd9\x6b\xea\x25\x0c\xed\xf1\xf3\xa0\x95\x94\xcb\xc5\x4a\x7a\x8a\x7f\xb8\xfb\x0c\xe3\xd5\x6e\xab\xe8\x12\xde\x54\xf2\xe4\x67\x81\x77\x28\x34\x04\x29\x51\x04\x37\x19\x05\x14\xe5\x85\x6a\x08\x60\x06\xb0\x6a\x59\x56\xec\x87\xb7\x4e\x34\xeb\x0f\x55\x5c\x2d\xe2\x5e\x18\xbe\x17\xe8\xa0\x12\x85\x02\x49\x86\x0c\x46\x1e\xb2\x03\x4c\x4c\x03\xd9\xe3\x1a\xca\x91\x81\xc3\x51\xaf\xda\xcb\x6f\x74\x35\xea\xd9\xed\xfd\xab\xa3\x5e\x09\x7a\xb2\xef\x73\x45\xd5\x5c\x28\x7a\x40\x0e\xc8\x1a\x53\x79\xf4\x5b\x79\xef\xb5\xff\x86\x96\x67\xc7\x47\x0c\xf3\x96\x9c\x34\x2b\xff\xe6\x25\x8c\x4f\xc8\xb7\x1e\xe4\xe5\x1b\xb9\x9e\xcc\x4a\x2a\x9c\x30\x1b\x09\x16\x6f\x34\x17\xc3\x63\x3f\xcc\x94\x73\x9a\xca\x07\x95\x48\x12\x04\x96\xa5\x24\xfe\x38\x0c\x52\xc9\x3e\x99\x48\xc7\x26\x5d\xc8\xde\x42\xf3\x85\x22\xac\x72\xfb\xc9\x7e\xd6\xbc\xd7\x84\x65\xeb\x51\x34\x9f\x19\x6b\x2d\x47\x38\xd2\x2f\x89\x43\xde\x25\xcd\x54\x0a\x7f\x0d\xc0\x8c\x30\xca\x12\xe2\xb3\xf3\x22\x3a\x64\x4a\x17\x3c\x64\xeb\x17\x3c\x84\xd5\x8e\xbd\xd0\x9b\x17\xf7\xf6\xf8\x04\x76\x01\xee\x9b\x86\x46\x99\x0d\xf4\xbb\x64\xf4\xe9\xa1\x81\x3d\xc2\xf6\x28\xdc\x23\x75\x87\xe6\x1d\x52\x8f\x5d\xca\x56\x50\x82\x2e\xd7\x78\x00\x38\x37\xb9\xc9\x96\x19\xd1\xf1\xc9\x8a\xa1\xca\xd2\xe2\x70\x9a\xed\xde\x32\x28\xc5\x0b\x34\x5e\xa3\x17\x68\x8f\xc5\xad\x4a\x72\x56\x5c\x8d\x8c\x5a\x45\x6b\xa5\x51\x89\xe0\x99\x06\x0b\x8d\x47\x09\x23\xd7\xf2\x82\xa9\x50\xb1\x02\x4d\xe5\x01\x01\xab\x4a\x05\x5f\x2c\x6c\x14\xb8\x6e\xaa\x8f\x15\xdb\xaa\xc1\x71\x83\xe5\x2a\x05\xdc\xfb\xc9\xd9\x31\xb4\x3f\xf6\xf0\xc0\x97\x02\x83\x2f\xc2\xd7\xb3\x39\x2e\x22\x16\xd6\xbb\xc2\xf4\x7e\xce\xdc\x66\xcf\x3c\x82\x77\x7e\x52\xec\xda\xc4\x0a\x2e\x0e\x1c\x44\x06\xda\xd2\x0c\xf7\x56\x3e\xdf\x3a\x11\x75\x4e\xf4\x6a\x55\x3a\x7c\x9f\x16\x19\x67\x3e\x3f\xf0\x32\xe1\xd8\xb7\x79\xd6\xad\x69\x9b\xe3\x0a\x3f\x01\xfc\x4e\xab\xf1\x2e\x4e\x83\x24\xa7\x01\xbf\xca\xb9\x35\x6d\x8d\x86\xa1\xb6\xf5\xed\x36\x3d\x08\xf3\x95\x21\x47\xae\x92\x9e\x68\xf1\x4d\x4e\x72\x4d\x29\xa8\x2a\x72\x68\x95\x78\xa6\x3a\xfc\x54\xe7\x50\x7b\x9d\x7b\xb4\x4b\x01\x92\x96\x1f\xe6\x2a\x17\xce\x6d\x17\xe5\x44\x60\xbd\xf6\x2e\xed\xf4\x49\x0c\xd0\x2b\xca\x52\x5e\x3a\xf3\x57\x2a\x78\x65\xc1\x5e\x47\x96\xc7\x69\x78\x13\xda\x51\x6a\xaf\x52\x3b\x2c\x7c\x70\xf1\x21\xda\x5d\x4c\x59\x9e\x0a\x90\xec\x93\xf7\x91\x26\x85\xd9\x68\x89\xb3\x3e\x63\x9f\x2b\x2e\x38\x9b\x01\x2a\x81\x6b\x9e\xa2\x90\xc5\x9d\x68\x98\x32\xd0\xa3\xe6\xbf\x91\xde\xce\xdd\x54\xd4\x16\x03\xd4\x6f\xe6\xd4\x4c\x29\x72\x79\x3f\xc6\x47\x4d\x58\xd5\xfa\xea\xca\x4a\x55\x57\xe9\xa4\xe2\xf7\x5c\x04\x44\x39\xa7\xf3\xc3\xa8\xbe\x26\xc3\xba\x3d\x56\x4f\x91\x37\x74\x80\x9c\xac\x88\xff\x99\x35\x96\x03\x2c\x04\xa5\x83\x19\x9a\xeb\x61\x1c\x32\xed\x7e\xa6\xd9\xce\x3c\xc0\xc2\x7b\x2c\x7b\x88\x85\xd5\xa7\x0d\xe0\x90\xe3\x82\x13\x65\x71\x76\x7f\xc7\x2a\xd3\x55\x9c\x9e\xfa\xf4\x94\x68\xb3\x0c\xb2\x85\xa5\x33\x76\x37\xa8\xb9\x1e\xec\xb7\xd3\xf4\xde\xa5\x7d\xbf\xd6\xd4\x3a\x10\x5f\xe1\xd3\x57\xa0\x88\x07\x66\x6d\xc0\x63\xf1\x0c\xd1\xac\x6f\x03\x4f\xa9\x6d\x6c\xfb\xf4\x2d\xaf\x07\x9c\xa5\x1e\x0c\x2b\x2f\x1c\x56\x4c\xd9\x09\xed\x1b\x54\x95\xd7\x1b\x1a\x08\xb7\xaa\x49\x6b\x07\x39\x37\xa6\x34\x61\x32\x64\xd5\xcd\x80\xa5\x3a\xd2\x7d\x58\x8f\xe2\x66\x06\xe7\x2e\x42\xeb\x57\x29\xba\xd2\x81\xe1\x9c\x9d\x80\xe3\x84\x26\x57\x13\x2a\x31\xef\x2f\xa7\x99\x2e\xa5\x2f\xe4\xb9\xca\xeb\x11\x98\xdf\x8d\xa8\x5b\xcc\xb4\xb4\xd0\xdd\x6c\xf4\x7e\x8e\x58\xbc\x9e\xd7\x4a\x4d\xc7\x80\x9a\x9e\x7f\x41\x7c\x19\x5e\xda\xfc\xe8\xb8\x39\x6d\x82\xd1\x62\x85\x14\x1b\xec\xd6\xcc\x35\x1b\xb3\x6a\x5b\xb6\x3e\xab\x3f\x03\xa6\x33\xa3\x82\xd5\xc3\xd6\x03\xf8\xa1\x83\xb2\x07\xb5\x8b\x77\x07\xc4\x7a\xe8\x2c\x2f\x17\xe7\x8a\x85\xcd\x06\x92\x8b\x38\x8c\x66\x9f\x2d\x55\xac\x47\xfd\xe4\x93\x05\x6b\xde\x89\x8d\xce\x4d\xb9\xc6\xe1\x67\x29\xfe\xed\x83\x59\x39\xae\xfa\x85\xa1\x71\x18\xfe\x14\xf2\x5e\xd8\x95\x13\x30\x69\xd2\xae\x39\xf4\xb7\xcc\x7b\x9d\xeb\xa5\x94\xb4\x83\x9e\xb2\xa9\x0d\x7f\x57\x27\xa2\xa9\x31\xa3\x6e\x73\x67\xeb\x12\x7b\x8d\xeb\x85\x42\x8b\xfc\xc3\x6d\xdd\x97\x7f\xad\x0f\xab\xfc\x8b\xfb\xe0\xa7\x21\xfe\xb9\x1a\xd1\xb7\xa0\x5c\x55\x5d\xd8\xc0\x50\x12\x88\xdb\xf5\xc2\xc5\xec\x53\xef\x4d\xbd\xba\x23\x39\x28\xbf\xc7\x60\xb3\x51\x7e\x8f\x41\xf2\x52\xf8\xbf\x7b\x8f\xc1\x1e\x19\xc9\x7b\x3d\x5a\xd3\xd6\xac\xb7\x39\xdd\x85\xaa\xf0\xdf\x1d\xb0\xa7\x28\x62\x54\x3b\x27\xba\x87\x06\x94\xbf\x05\x29\xf1\x94\xd9\xc2\xef\x22\x9d\xad\x2e\x3f\xbd\x7a\x2c\x67\xc2\x51\x5f\x26\xd7\x7d\xc3\x5b\x97\x1a\xf6\x17\x7e\xcb\x9c\x30\xaf\x0c\x45\x20\x76\x0b\xf6\xbf\x0d\xe5\x36\x0d\x55\x7a\xcb\xf1\x90\x2b\xef\x8a\x34\x3e\x70\x6b\x5a\x84\xf9\xdc\x2b\x7f\xff\x0d\x00\x00\xff\xff\xb1\xed\x38\xfe\x94\x32\x00\x00") + +func fontsRomanFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRomanFlf, + "fonts/roman.flf", + ) +} + +func fontsRomanFlf() (*asset, error) { + bytes, err := fontsRomanFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/roman.flf", size: 12948, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRot13Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\xd3\xd5\x77\x5d\x45\x18\x86\xf1\xfb\xe7\xaf\xd8\x50\xa4\x05\x92\xec\x99\xed\xe8\xdb\x16\x28\x45\x0b\x94\xe2\x72\x9a\x9c\xd3\x06\x4e\x93\x70\x92\x14\x8a\x15\x77\x77\x77\x77\x77\x77\x77\x77\x77\x77\x87\xf5\x76\xcd\xc5\x6f\xae\x66\xcd\x5a\xdf\xf3\x75\xba\x9d\xd8\x5a\x9a\x04\x9f\x34\xe9\x0b\x49\x0d\xbd\xd1\x89\x90\xf5\x77\xba\x9d\x64\xea\xcc\x69\x49\x68\x9a\x3c\x99\xbf\x24\x99\x37\x3c\x38\x31\xda\x4b\xe6\xb4\x7a\xad\xa1\x56\x32\x75\xf1\xd8\xb2\x8b\x86\x47\x3a\xfd\x93\x13\x9d\xf1\x45\xfd\x83\xdd\x69\x49\x93\x0f\x84\x38\x10\xeb\x7e\x98\xd1\x1a\x6f\x0f\x25\xa3\x23\xc9\xdc\x76\x6f\xd1\xf0\x48\xab\xeb\x47\x66\x75\xdb\x23\x23\xc9\xcc\x85\xad\xb1\xb1\x76\xb7\x9b\xe4\x03\x4d\x06\xb3\x47\x06\xbb\x93\x43\xed\xf1\x64\x70\x61\xab\xd7\x1a\x9c\x68\xf7\xc6\x93\x10\xeb\xbe\x58\x14\x74\x86\x17\x74\xdb\x13\x49\xaf\xdd\x6d\xb7\xc6\xdb\x49\xec\x0f\x49\x5f\x5f\x12\x62\x32\x7d\x72\xc1\xb2\xaf\xc1\x52\xb1\x9c\x58\x5e\x4c\x11\x2b\x88\x15\xc5\x4a\x62\x65\x31\x55\x4c\x13\xab\x88\x55\xc5\x6a\xa2\x4f\xf4\x8b\x01\x91\x8a\x20\xa2\xc8\x44\x2e\x0a\x51\x8a\x4a\xd4\xa2\x11\xab\x8b\x35\xc4\x9a\x62\x2d\xb1\xb6\x58\x47\x68\x0a\x9b\x8a\xcd\xc4\x1c\xb1\xb9\xd8\x42\x6c\x29\xe6\x8a\xad\xc4\x3c\xb1\xb5\xd8\x46\x6c\x2b\xb6\x13\xd3\xc5\x0c\x31\x53\xac\x2b\xd6\x13\xeb\x8b\x59\x62\x03\x31\x5b\x6c\x28\x36\x12\x1b\x8b\x4d\xc4\xf6\x62\x07\xb1\xa3\xd8\x49\xec\x2c\x76\x11\x23\x62\x54\x8c\x89\xdd\x45\x4f\x8c\x8b\x09\x31\x29\x16\x8b\x3d\xc4\x9e\x62\x89\xd8\x4b\xb4\xc4\x7c\x31\x28\x86\x44\x5b\x74\xc4\x02\xb1\x50\x0c\x8b\x5d\xc5\x6e\xa2\x2b\x16\x89\xbd\xc5\x3e\x62\x5f\xb1\x9f\x78\x58\xbc\x2a\xde\x16\x1f\x8b\x5f\xc5\xdf\xe2\x3d\x11\x62\xcd\xfe\xa6\xe1\x00\x11\xb2\x94\x03\x4d\xe0\x20\x13\x39\xd8\x64\x1c\x62\x72\x0e\x35\x05\x87\x99\x92\xc3\x4d\xc5\x11\xa6\xe6\x48\xd3\x70\x94\x08\x79\xca\xd1\x26\x70\x8c\x89\x1c\x6b\x32\x8e\x33\x39\xc7\x9b\x82\x13\x4c\xc9\x89\xa6\xe2\x24\x53\x73\xb2\x69\x38\x45\x84\x22\xe5\x54\x13\x38\xcd\x44\x4e\x37\x19\x67\x98\x9c\x33\x4d\xc1\x59\xa6\xe4\x6c\x53\x71\x8e\xa9\x39\xd7\x34\x9c\x27\x42\x99\x72\xbe\x09\x5c\x60\x22\x17\x9a\x8c\x8b\x4c\xce\xc5\xa6\xe0\x12\x53\x72\xa9\xa9\xb8\xcc\xd4\x5c\x6e\x1a\xae\x10\xa1\x4a\xb9\xd2\x04\xae\x32\x91\xab\x4d\xc6\x35\x26\xe7\x5a\x53\x70\x9d\x29\xb9\xde\x54\xdc\x60\x6a\x6e\x34\x0d\x37\x89\x50\xa7\xdc\x6c\x02\xb7\x98\xc8\xad\x26\xe3\x36\x93\x73\xbb\x29\xb8\xc3\x94\xdc\x69\x2a\xee\x32\x35\x77\x9b\x86\x7b\x44\x68\x52\xee\x35\x81\xfb\x4c\xe4\x7e\x93\xf1\x80\xc9\x79\xd0\x14\x3c\x64\x4a\x0f\x3d\x34\x15\x8f\x98\x9a\x47\x4d\xc3\x63\x22\xa6\x29\x8f\x9b\xc0\x13\x26\xf2\xa4\xc9\x78\xca\xe4\x3c\x6d\x0a\x9e\x31\x25\xcf\x9a\x8a\xe7\x4c\xcd\xf3\xa6\xe1\x05\x11\x43\xca\x8b\x26\xf0\x92\x89\xbc\x6c\x32\x5e\x31\xb9\x7b\x8b\xa1\xe0\x35\x53\xf2\xba\xa9\x78\xc3\xd4\xbc\x69\x1a\xde\x12\x31\xa6\xce\x32\xc6\xc0\x3b\x26\xf2\xae\xc9\xdc\x67\x8c\x39\xef\x9b\x82\x0f\x4c\xc9\x87\xa6\xe2\x23\x53\xbb\xe5\x18\x1b\x3e\x11\x31\x4b\xf9\xd4\x04\x3e\x33\x91\xcf\x4d\xc6\x17\x26\xe7\x4b\x53\xf0\x95\x29\xf9\xda\x54\x7c\x63\x6a\xbe\x35\x0d\xdf\x89\x98\xa7\x7c\x6f\x02\x3f\x98\xc8\x8f\x26\xe3\x27\x93\xf3\xb3\x29\xf8\xc5\x94\x5e\xa3\x98\x57\xfc\x66\x6a\x7e\x37\x0d\x7f\x88\x58\xa4\xfc\x69\x02\x7f\x99\xe8\x6d\x8b\x45\xc6\x3f\x26\xe7\x5f\x53\xf0\x9f\xf8\x3f\x00\x00\xff\xff\x89\x5e\x4d\x5c\x75\x05\x00\x00") + +func fontsRot13FlfBytes() ([]byte, error) { + return bindataRead( + _fontsRot13Flf, + "fonts/rot13.flf", + ) +} + +func fontsRot13Flf() (*asset, error) { + bytes, err := fontsRot13FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rot13.flf", size: 1397, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRoundedFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x58\xcb\x6a\x5e\x37\x10\xde\x9f\xa7\xf8\xc0\x59\xe8\x6c\xac\xc6\xf4\x42\x76\x7d\x01\xa7\x50\x68\xe9\xe2\xc0\xe0\xc6\x09\x0d\x69\x5d\x48\xf1\x22\xa0\x87\x2f\x9a\x9b\xa4\x23\x9d\x9b\xd3\x82\xfd\xff\x42\xbf\x34\xf7\xf9\x66\x34\x1f\xfe\xfc\x70\xf7\xf0\x0a\x3f\xe0\x7b\xdc\x7d\x83\xd7\xdf\xe1\x6e\xfa\xf9\xef\xe7\xa7\xc7\xf7\x8f\xf8\xfd\x0b\xde\x7e\x7c\xf7\x09\xf7\x1f\x9f\xde\x7f\xfe\x07\x6f\x6f\xef\x6f\x65\xf9\xe3\xe3\xf3\xe7\x3f\x1e\xfe\xba\x7d\x78\x77\xfb\xfc\x69\xba\x7f\xf8\x82\xd7\x6f\xde\x7c\x3b\xbd\x7a\x75\xb3\xf5\x7f\x33\x81\x70\x33\x25\x24\xfb\xa0\x64\x7b\xbc\x02\xe4\x0c\x6f\x05\xcc\x01\xf3\xcd\x94\x22\xb0\xc8\xaf\xf9\xc0\xd6\x37\x2f\x28\x5f\xce\x7b\x94\xf0\x0b\x12\x93\x21\xfe\x9d\x66\xd9\xfd\xa9\xdf\x45\xa2\x27\x4a\x85\x54\x45\xcd\x68\x25\x91\x1b\x44\xf9\x46\x22\x22\x64\xf9\x99\x8a\x48\x9e\x1a\x0a\xaa\x86\xe8\x41\x33\x58\x5b\x00\x11\x91\x0f\xe5\xef\xbc\xc8\xdf\xaa\x3e\x82\x08\x53\xf8\x33\x17\x39\x45\x58\xc0\x26\xc9\xc4\xe6\xbc\x37\x83\x10\x74\x2f\x1b\x28\xef\x2d\x44\x71\xa9\xa8\xc0\x2c\x6e\x76\x14\x13\xaf\x3e\x98\x95\xb0\x99\xd9\x2f\x68\x3f\xe1\x24\x55\xab\x4c\x8f\xf9\x89\x56\xd5\x67\x20\xe5\xa1\x06\x64\x1b\xb0\x09\xf3\xef\x2a\xca\x92\x90\x98\x15\x66\x16\x32\xb0\x8d\x62\x42\x32\x46\x6c\xcb\xde\x1d\xee\xee\x95\x5f\xc4\x0b\xf3\xc0\x0b\x8d\x39\x07\xda\x37\xb6\x19\x5c\x9b\xb2\x0f\x48\x78\x90\xf8\x7e\x70\xe6\x04\x0f\xbd\x69\x3c\x48\xaf\xed\x85\x05\x34\x2c\x3a\x1e\x22\x52\xde\x54\xa1\xa0\x39\x43\x96\x5d\x11\x51\x73\x0c\x88\x24\x4c\x16\x3e\x1b\x3b\xab\x7a\x90\x05\x26\x85\xe2\x37\x71\x05\xd4\xa0\x66\x6c\xac\x2d\x21\x51\xe1\x42\xc9\xcf\x12\x1f\x10\xf1\x66\x09\x61\x65\x9f\x94\x02\x24\x8f\x56\xc4\x76\xa8\x91\x53\xd3\xdd\x30\xda\xed\x55\x24\x37\x39\x2b\x23\x79\x96\xb5\x69\xa4\x00\x1c\x62\x52\xb5\xa4\x34\x94\xad\x84\x84\x48\x7f\x4e\xe2\x81\x6c\x07\xd4\x04\x72\x98\x9a\x48\xcc\xd4\xd2\x25\x6a\xaa\xbe\x1d\x8e\x82\x1f\x28\xd1\x96\x4d\x12\x07\x09\x37\x0c\xb4\x6a\x37\xba\x6c\x41\xa3\x67\xde\x0e\xb4\x3d\x4d\xcb\xee\x59\x2f\x8c\xd2\xab\x4f\xb4\x8d\x33\x6d\xc2\xb7\xf0\x17\x24\xaa\x0a\xe4\x4d\x1d\xfe\xf4\x90\x70\x0c\x12\x4e\xac\x86\x4f\x8d\x0c\x87\xcc\xa9\x4d\x4a\x07\xfe\x7c\x28\xc8\x69\xf5\x55\x8d\x82\x5c\x12\x36\x21\x22\xfb\x08\x16\x3f\x8c\x2a\x8a\xf1\x8b\x65\x63\xf2\xb3\x4b\xe5\xe5\x0b\x9e\xd3\x18\xd5\xa2\x6e\x9e\x13\xe8\xda\xca\x1f\xcf\x14\x94\x4c\x99\x55\x36\x96\x38\x98\x6c\xba\x7b\x2d\x7f\xdc\xfe\x22\x90\x2d\xed\xac\x6a\x7a\x88\x3b\x0e\xad\x0d\x7e\x58\xfb\x92\xc5\x89\x8e\x1f\xb1\xcb\x9f\x1d\xbb\xa1\xe4\xf6\xbc\x92\x6d\x1f\x13\xcf\x52\x73\xa5\x29\xad\x42\xf1\xc8\x6e\xe6\xd3\x0c\xd3\x70\x4d\x73\x0b\xb3\x93\xdb\x6e\x21\x8e\x45\xed\x64\x5e\x1c\x21\x6d\x8b\xb8\x6a\x16\x8f\x90\x8e\x3c\xcf\xb4\x74\x25\x6e\x0a\x92\x47\xf8\x00\xe9\xd6\xf2\x0b\xf4\x30\x59\xab\xa3\xd6\x62\x30\xa5\x45\x12\x8a\xe5\x5f\x7a\x4f\x79\xf4\x09\x35\x17\x68\x37\x26\x2f\xfa\x1d\xd6\x25\x27\xa4\x44\x29\x5d\xca\xbe\x71\xbe\xf4\x11\xfe\xdf\x52\x33\x6b\xee\x57\x88\xed\x1a\x2a\x51\x64\xa8\xf5\xf2\x08\x07\xb9\x17\xbc\xcd\x65\xd1\x2e\x20\xc3\x50\x36\xc0\x65\xab\x23\x64\x50\xbd\x5c\x36\xed\x8b\x68\xb6\x1a\x5a\x21\xf1\xd7\xf5\x10\x55\xf3\xad\xa9\xd0\x2f\x47\x6d\xf6\x46\x2e\xbf\xd4\xa7\xe7\xa9\xb1\xcd\xac\x11\x5e\xc6\x88\xea\x51\x1f\x68\x96\xbf\x2e\x17\xe0\xb9\x60\xcb\x6b\xb2\x55\x1d\xb1\xca\x66\x0d\xf9\xbe\x4f\x8f\x2c\x54\x77\x99\x05\x59\xcc\x63\xe7\x32\x4b\x82\x0c\xe5\xa9\x60\xb2\x6d\x60\x61\x45\x4d\x51\xd8\x10\xac\xfe\x32\xf4\xb1\x5b\x45\x1b\x4f\x34\xf5\x8e\x70\x5e\xe4\x2d\x0a\x8b\x72\xac\xec\x51\x38\x06\xeb\xe7\x52\xfd\x55\x34\x4f\x15\x47\xd1\x4d\x34\x13\xb2\xa1\x7d\xcc\x1e\x3e\xbd\x7a\x18\xd8\x5a\x6e\x57\x0f\xac\x1f\xcd\x36\x79\x58\x7f\x1c\x3f\x16\xb3\x92\xd2\x21\xa7\x9b\x69\x59\x79\x79\x68\x63\x8e\x16\xab\xe5\xde\xf3\x97\x8e\x3f\x8e\x34\x6e\x16\x0d\xaa\x38\xa6\x38\xa2\xcc\xdd\xfd\xd5\x43\xd4\xb2\x39\x42\xe7\x1b\x08\x75\x7e\xa7\x03\xfe\x5e\xcb\x4c\x6d\x5e\x90\x47\x7f\xc7\x5f\x85\x03\x0b\x3c\xdb\x93\xbe\xbc\xe9\xf5\x51\xef\x90\xb5\x46\xac\x63\x33\x0c\xd4\x28\x79\x97\xce\xbb\xa1\x14\xc2\x2e\xd4\x9b\xc7\xc5\xb8\x5d\x31\x43\x3b\xc4\x60\x3b\x2b\xe2\x66\x70\x38\xbc\x50\xb4\x9a\x23\x7d\x32\xa5\xa6\x0d\xf1\x31\x4d\x3f\xcb\x19\x4d\x74\xc6\x7e\x54\x03\xa0\x33\x00\xad\x0d\xb0\x7b\xff\x84\x01\xc7\x0e\x6c\xde\x3f\xda\xc3\x79\x07\xf7\x02\xfe\xa5\x93\x93\x0e\x42\x27\x2b\xe7\x02\xa8\xe1\xef\x6f\xd4\x24\x01\x74\x22\x0f\x8b\x17\x47\x03\x9d\x7a\xc7\xb4\xcf\x97\xab\x61\xa3\x86\x6c\xd1\xfc\xfc\x44\x4c\xc7\x36\x5c\x53\x7b\x00\x58\x19\xae\x2a\x61\xa9\x51\xfc\x1c\x00\x75\xf7\xb1\xe0\x57\x2f\xe9\x71\x08\xd9\xed\x7d\xea\xf8\xe3\x8a\xe3\xad\xa0\x73\x2b\x21\x23\xc6\xdf\x6c\xc0\xd8\xe5\xc8\x15\xfd\xdd\xf1\x41\x0d\x71\x58\x00\xe0\x73\xaf\x38\x1a\x0d\x58\xc9\x93\x8a\xc7\xbf\x68\x49\x0e\x08\x42\xcd\x5d\x57\x7b\xae\x7d\x21\x95\xf9\x79\xff\x42\xd2\x27\x88\x55\x6b\x4d\x7d\xe8\x20\x41\x1b\xde\xd0\xf4\x59\xda\x9c\xfa\x40\x04\x4b\xd4\x19\xc5\xd2\x36\x50\x07\xab\x55\x8d\x9d\x89\xe8\x2b\xdf\x84\x63\x6a\xfc\xfb\xff\xda\x95\x9e\xa4\x66\xb4\x42\x3f\x0f\x3a\xd5\x07\xb4\xf7\xaf\xe1\xdf\x80\xff\xb5\x34\xee\xb9\xe9\xb4\x29\x21\x05\x9b\xc4\xe8\x0e\xa5\xb0\xba\xff\x6f\x00\x00\x00\xff\xff\xed\x11\xce\x52\x3b\x1a\x00\x00") + +func fontsRoundedFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRoundedFlf, + "fonts/rounded.flf", + ) +} + +func fontsRoundedFlf() (*asset, error) { + bytes, err := fontsRoundedFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rounded.flf", size: 6715, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRowancapFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\xef\x4f\xeb\x36\x14\xfd\xee\xbf\xe2\x2a\xe2\xc3\x26\x15\xbf\x86\x3d\x7e\x55\xe8\x2d\x08\xd6\x27\x44\x33\x45\x80\x2a\xed\xa3\xe3\x38\x6d\x46\x62\x47\xb6\x03\x63\x7f\xfd\xe4\xc4\x89\x93\xfe\x00\xca\xa6\x09\xe9\xb5\x08\x1a\x17\x7c\x7c\xce\xb9\xe7\x5e\x9c\xe6\xe9\x11\x39\x80\x13\x38\x06\xff\x0c\xbe\xc2\x91\x8f\xd0\x34\x5b\xe4\x4c\x03\x15\xfc\x89\x49\x95\x09\x0e\xf1\x0b\xdc\x32\xae\xe1\x77\xa2\x14\xe3\x23\x78\xe4\xf5\x43\x50\x15\x19\x5d\x62\x96\x54\x23\xf0\xbf\xf8\x5f\xce\x8f\x11\x92\xe2\x99\x70\x4a\x4a\x9c\xe6\x29\x42\x53\x29\x0a\x50\x25\xa3\x5a\xb2\xa0\xca\x2a\x6a\xfe\x18\x5d\x13\xcd\x26\x70\x4f\xf4\x08\x7c\x1f\xae\x19\x05\xff\xfc\xfc\x17\xf0\x8f\x26\xc7\xe7\x13\xff\x0c\x0e\xc7\x27\xe3\x71\xbd\x77\x02\x37\x84\xc3\xd5\x92\x64\x70\xb1\x0a\xf3\x0d\xdd\xb1\x32\x7f\x01\x2d\x26\xe0\x5d\x67\x8a\x56\xca\x90\x55\x40\x62\x51\x69\xd0\x4b\x06\x45\x95\xeb\xec\x30\x15\x5c\x43\x4e\xe4\x82\x1d\xe6\x4c\x6b\x26\xa1\x94\x62\x21\x49\x31\x82\xe9\xcd\xf7\xd9\x6f\x0f\xd8\x43\x60\x5e\x17\xcd\xf2\x70\x16\x3c\x15\x09\xa6\x4a\x60\x77\xd6\x83\x98\x40\x68\xe0\xca\x9c\x81\x64\x34\x2b\x33\xc6\xb5\x02\x91\x42\x9e\x29\x0d\xed\xd6\x57\x41\xee\xab\xf8\x4f\x46\xf5\x04\xee\x45\xc1\xf4\x32\xe3\x0b\x48\x85\x04\x25\x0a\x26\x38\xab\xdf\x9f\x97\x4c\x32\xc0\x80\x31\x42\xdf\x1a\x0b\x66\x82\x3e\x32\x59\x92\x5c\x88\xbf\x09\x5c\x44\x37\x77\x37\xb3\xd9\xd5\xd1\xe9\xe9\x38\xa0\x22\x96\x04\x57\x3c\x6b\xf0\xd1\x54\x54\x3c\xa9\xa5\x53\x52\xaa\x1a\x9c\x40\x29\x94\xca\xe2\x9c\x41\x6d\x84\xf9\xac\xa9\xf0\x08\xb2\x14\x08\x7f\x31\x47\x3f\x8b\x2a\x4f\x80\x12\xc9\x40\x0b\x60\x7f\x95\x84\x27\xbf\x22\x5b\x03\xe5\xfb\xa7\xbe\x7f\x36\x0e\x16\x19\x61\x31\xa6\x14\x17\x82\x13\x55\x57\x1e\x93\x0a\x7e\xba\x33\x45\x87\x2b\x49\x9e\x53\x21\x93\x9f\x3b\x9d\x97\x30\x15\x5c\x63\x5b\x70\x7f\xdc\xab\xf5\xc9\xe4\xf8\xab\xa9\xf5\xf7\xf0\x01\xa1\x03\x80\x83\xe0\xf5\x9f\x01\xea\x7d\x7d\xee\x45\x9d\x25\x58\x7f\x3f\x00\x52\x48\xa3\x27\x09\x23\xa3\xcb\x7e\xfe\x19\x28\xff\x9f\xd6\x60\x12\x86\x61\xdc\xe8\x4f\xc2\xc8\x4b\xc2\xa8\x5e\x24\xa1\x79\x45\xb5\x63\xc6\x21\xf3\x6d\x16\xee\xb9\xf3\xb2\x35\x0e\xc0\x6e\xdb\x06\x77\xeb\xb5\x70\x98\x84\x53\x0b\x67\x4e\xf1\xb6\xc0\xf5\xc8\x19\xb0\x79\x03\x66\x8f\xb7\x6c\x30\xb1\xcc\xe6\x1b\x91\x36\xf3\x82\x79\xc7\xcb\xca\xe9\x78\x45\xef\xe0\xd5\xba\xe3\xf0\xba\x70\x25\x8d\x6b\xd0\x19\x07\x8e\x6b\xd8\xff\xdd\x7f\x05\x1a\x39\x98\x0d\xa0\xb5\x83\x4e\xab\xd7\x07\x69\x04\x36\x26\x76\x25\x75\x2e\x6e\x11\x5e\xfb\xe5\x38\xb6\xe6\xb9\xc0\x0c\x13\x33\x8c\xcc\x36\xe1\x16\x90\x14\xb2\x05\x8b\x06\x62\x9d\x50\x07\x10\x58\x0e\x3d\xd3\x5a\xdf\xec\xa2\xcb\xec\x2d\x7c\x58\x20\x1e\x0a\x34\x11\xb6\xbc\xbc\xcb\x3a\xc3\x3b\x09\xec\x81\xad\x0b\x1c\x0a\x59\x89\xc5\x5a\x5b\xf5\x5a\x2b\x5a\x8d\xf1\xc6\x8e\xdd\xd4\xb5\xab\xc7\xc4\x83\xc2\x6e\xea\x90\x77\x0e\x82\x95\xce\x4d\x5c\xe7\x5a\xac\x8f\x76\x2e\x1e\x4c\x94\xc8\x5b\x69\x89\x41\x47\xec\xc2\x0b\xf7\x78\x85\x8e\x57\xe4\xb5\x85\xda\x89\x97\x9b\x74\x36\x25\x6f\xfa\x95\x0c\x78\xc1\xbc\x01\x33\xce\xc4\xcd\xf6\xa8\xcd\xf0\x6b\x7e\xd9\xac\x0c\x67\x88\xcb\xdb\xd0\xac\xbe\x57\xeb\x02\xdf\x99\x01\x5b\xc4\xb7\x1a\xab\x87\x36\x0c\x41\x87\xf5\x47\xf8\x74\xd9\x89\x9a\x5b\xa0\xed\xbc\xd6\xb8\xbd\x12\x7f\xbc\x3e\xe1\xe6\x9b\xb9\xc2\xd6\x41\x70\xeb\x06\x41\x5d\xab\x0f\x0d\x82\x15\xde\x0e\x72\xee\x66\x67\x72\xb9\xcb\xb0\x1a\xcc\x0c\x9c\xb4\x0d\xd1\x3d\xd7\xab\xee\xf9\xcd\x7f\x43\xfb\xfb\xc5\xfe\x7e\xb1\xbf\x5f\xf4\x37\xff\xd0\xf7\x0b\xd8\xdf\x2f\xf6\xf7\x8b\x3e\xd0\xfe\x7e\xb1\xbf\x5f\x7c\x9e\xfb\xc5\xbf\x5e\xfc\x13\x00\x00\xff\xff\xdf\x17\x66\x40\x70\x15\x00\x00") + +func fontsRowancapFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRowancapFlf, + "fonts/rowancap.flf", + ) +} + +func fontsRowancapFlf() (*asset, error) { + bytes, err := fontsRowancapFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rowancap.flf", size: 5488, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRozzoFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xdf\x6b\x1c\xb7\x13\x7f\xbf\xbf\x62\xd0\x2d\x1c\x04\x7d\x7d\xdf\x18\x42\xa7\x6f\xa5\x67\xf2\x12\x0a\xa2\xe4\x65\x29\x85\xdc\x56\x72\x9b\xc6\xf5\x85\x38\x6e\x49\xfe\xfa\x22\xcd\x8c\x34\xda\xd5\xfe\x48\xea\xf6\xc0\xbb\x92\x56\x3b\x33\x9a\x9f\x9f\x59\xdf\xde\xdd\x5e\x9f\x3b\xf8\x06\x5e\xc0\xf5\xff\xe1\x7f\xcf\xe1\x7a\xf7\xe1\xf2\xf9\xf3\xe5\xea\xf6\xee\x16\x6e\x2f\xf7\x1f\x61\xf8\x04\x3f\xbc\x7d\x17\xe0\xc7\xcb\xc3\xe3\x5d\x78\x07\x3f\x3d\xde\x9f\x3f\x5c\x7f\xf7\x70\x7b\xbe\xba\xbc\x0f\x57\xc1\x5f\xfd\x7a\xf9\xf3\x67\x78\x7e\x7c\x7e\x7d\xfc\xf6\xc5\xee\xf5\x6f\x6f\x1f\xe0\xaf\xf3\x03\x0c\xe7\x87\xe0\xe1\x72\x0f\x2f\x1f\x7f\x7f\xfb\xe9\xfc\xc7\xf9\xfb\xbb\xf3\x2f\xef\xe0\xf5\x87\xc7\xf0\xfa\xd3\xfb\x00\x2f\x2f\xf7\x1f\xaf\x76\x5d\xb7\x9f\xfb\xdb\xef\x10\xb1\x93\xab\x41\xd3\xed\x77\x10\xa0\x8c\x01\xe4\xba\xdf\x21\xa4\xad\xe9\xaa\x1e\x4c\xaf\xe9\x06\x1e\x1d\xf8\x44\x05\xcb\x2f\x6d\xa1\x27\x2e\xbd\x50\x3f\x0b\xf2\x44\x88\xc9\x6f\x3c\x4b\x53\xe4\x07\x1e\x01\x93\xd0\x27\x44\xd9\xdc\x23\xe0\x20\xaf\x21\xde\xc4\x91\x41\x40\xc7\x6b\xc8\x64\x2c\x5a\x38\x02\x9f\xf8\x28\x9c\x8e\x42\xe6\x18\x9f\xc7\xd1\x11\x0c\x1a\x2d\x87\x1e\xf1\xd0\xe3\x60\xd3\xb2\xf5\x03\xf4\xee\x40\xca\xec\x71\x00\x88\xeb\x1e\x87\x38\x31\xf1\xd5\x1e\x69\x52\x1d\xac\x1e\xa7\x17\xd2\x56\xd7\xed\x77\x36\x09\xee\xe6\x15\x1e\x48\xb9\x5e\x14\x99\x0d\xcb\xa6\x65\xe5\xf7\x62\x04\x13\xef\x71\x43\x10\x3b\x0c\x62\x8f\xa0\x5e\x8c\x37\xb6\xa1\xa3\xe7\x86\x38\xf6\x03\x20\xf8\x28\x1a\xbc\xb9\xc1\x57\x87\xf8\xd0\x3b\x40\xe8\x87\xb6\x92\x16\x14\x97\x96\xb0\xf8\x83\x9a\x57\xaf\x94\x7b\xcb\xf7\x66\xd4\x55\x6f\x12\xea\xf3\x8e\xbb\x40\xb5\xe5\xe3\xb4\xe0\xc5\xb1\xc4\xaf\xd9\x8d\x13\x01\xb7\xac\x80\x80\x08\x62\x86\x64\x3f\x10\x63\x9c\x90\x67\xe4\xbf\x3d\xcf\x98\x95\x49\x33\xb3\x25\x54\x7c\xe5\x1c\xde\x64\x1d\x8f\xee\x23\x1d\x5b\xb4\x06\x29\xb4\xc0\xa4\x5d\x37\x39\xa2\x24\x90\xec\x33\x96\x40\x47\xf8\x44\x92\x42\x8d\x42\xc4\x80\x45\xa4\x08\x01\x38\xe1\x2b\xda\x1c\xe0\x0d\x6f\x30\x68\xd4\x86\x16\x35\x00\x1f\x59\xe6\x04\x40\x43\x4f\x1a\x8a\x1e\x6c\x8c\x01\x76\x5e\x92\x18\x61\x9e\x5a\x11\x9e\x52\x08\x10\x81\x18\xa6\x24\x18\xe4\x14\x19\xe5\x5a\x34\xa6\x89\x39\x23\xdb\x12\x48\x3d\x62\xca\x00\xda\x92\x37\x95\x21\x2b\xcb\x8d\x26\x22\x22\x2f\xdb\x40\x89\x26\x24\x33\xd8\x90\xb3\xa9\xd3\xaf\xaa\xc1\x7e\x07\x36\xaa\x69\x20\xd1\x4c\xcc\x8f\x8e\x58\xaa\xf5\x93\x96\x4b\xef\x69\x49\x95\x88\x6a\xe7\x3d\x69\xdf\xe5\x53\xc9\x19\x49\x83\x8e\x9f\x44\x25\x8e\x1d\x77\x72\xe0\x69\xe4\xcd\xc6\xe2\xf2\xd6\x51\x32\xe0\xa0\xe5\x90\xcd\xce\x97\xb3\x71\x8f\xc3\x4c\xc2\x01\xd0\x35\xab\x5b\x5b\x6b\xba\x48\x2a\x07\x15\xbf\x1b\x52\x11\xcb\x93\x13\x48\x23\x18\x0f\x59\xb7\x73\xc1\x68\x0e\x20\xc9\xc1\x8c\xbd\xbc\x0e\x1f\x1b\x8c\x31\x26\x24\xb3\x07\x03\x71\x16\x4c\xca\xfc\x70\x4a\x44\x53\x9d\x37\x01\xcc\xb3\x10\xcc\xb3\x14\x46\x6f\x4c\x88\xbf\x35\x4f\x8d\x77\xae\x7b\xf2\x94\x6b\x9f\xcc\x3d\x4a\xfd\xcb\x81\x42\xbf\x81\x83\x98\x27\xca\x14\x4d\x6e\x25\x34\x80\x13\x07\x0d\x53\xe2\x48\xc3\x57\x62\x9d\xc6\x86\x39\xd5\x44\xa7\x3e\xf4\x25\x65\x02\x1c\xfa\x1c\xc2\x19\x5f\xc4\xb1\xf5\x12\xc0\xd6\x57\xa9\x6f\x12\x28\xa8\xe2\x44\x87\x89\x4e\xf0\x3a\xbd\x63\x2b\xb9\x37\x88\xb2\x9c\x71\xbb\x4d\x52\x22\xe2\x29\x97\x52\x30\x49\x42\x1c\xcb\x57\xbb\xe4\x06\x32\x79\xb4\x56\xc9\x22\x21\xd0\x8a\x2b\xc9\x2f\xba\x4e\x55\xc6\xbe\x2c\xf9\x41\x06\x24\xa0\xb0\xcd\x74\x0d\x66\xc3\xb0\x46\xbb\xd3\xeb\xa4\xbc\x17\x4a\x93\x51\xca\x67\x8e\x2b\x82\x3b\xcc\x2a\x85\xdd\x4d\x44\xcb\xb6\x55\x7e\xa9\xfc\x60\x06\x3a\x69\xd5\xcf\x8e\xb6\x58\x9a\x22\x93\xfe\x54\x64\xfa\x12\x99\x14\xb7\x2a\x32\x87\xbc\xc0\x91\x99\x17\xb6\x44\x26\xe3\x5c\x81\x9e\x71\xdc\xed\x77\x03\x8f\xa3\xc0\x3c\x4e\xb2\xd3\x78\x25\x32\xff\x5d\xac\xa4\xaa\xb4\xaa\x85\x58\x9c\x14\x0b\x40\x50\xc3\xff\x40\xe0\xa1\xa2\x1f\x0b\xf6\x76\x81\x69\xb3\x4e\x83\x73\x02\x7b\x67\x30\x09\x47\xe6\x11\xc3\x47\xcb\x24\xba\xc1\xbb\x66\x75\x8a\x29\xb5\xe4\x11\x77\x20\xc0\x45\x89\x93\xc3\x46\xbd\xb2\x34\x5b\x32\x0d\xe9\xab\xdb\x36\x4e\xa9\x68\x94\xea\x27\x29\x94\x7c\x19\x25\x1d\xc9\xd4\x65\x28\x00\x7d\x29\xc8\x69\x5a\x88\xf4\xdb\x3a\xd5\x3e\x87\x4c\xc5\x84\x28\x2b\x36\x89\xb6\x62\x54\x82\x92\x58\xf5\xed\x20\x6b\x05\x5d\xa2\x9d\x59\x15\x26\xd0\xe5\x96\xb4\x34\xa4\xf3\x48\x45\xd3\xd1\x84\x84\x12\x9b\x6e\x32\x6c\x7a\x16\xb5\xf6\x71\xd5\xd5\xed\x92\x17\xf4\xe3\x91\xf1\xcf\x72\xad\x12\x94\xbe\x7a\xa3\x0e\x17\x9e\xa6\x4f\x2b\x7d\xe9\xda\x2d\x33\xf6\xac\x66\xa7\x7a\xe2\xf5\x7b\x55\x87\x1a\x57\x55\xab\x92\x8d\xc8\x3c\x64\x99\xf9\xd7\xaa\x53\x59\x69\x6c\x22\x4a\x24\x7a\x36\x84\xdc\xe2\xac\x95\x50\x59\x9d\xa6\x9e\x41\xa1\x98\x3a\x0b\xcd\x79\x85\x5a\x8e\xe8\x81\x1b\x54\xca\x1d\x48\x1f\x4a\x22\x3f\x6a\x1a\x11\x6d\xc0\x45\xe4\xa6\x0a\x74\x3e\x86\x2f\xa0\xa0\x57\xf8\x60\x72\xce\x19\xd9\x92\xc2\x02\x10\x52\xf6\xb9\x4c\x6b\xb9\xfa\x10\x9c\x99\xad\xb9\xde\xd9\x90\xf6\xe1\x00\x92\x91\x99\x71\x8e\x99\x3a\x78\xd4\x60\xa2\xa2\xed\x87\xb2\x02\x51\x52\xc3\x95\x1a\xb9\x31\x68\x08\xa1\xc6\x1e\x9b\x81\x14\x9f\xc8\xc0\x3a\x90\x5a\xde\xca\x8e\xa2\x85\xcb\xb2\xf1\x20\x63\xa6\x02\x94\x86\xb6\xaa\xbe\x10\xde\x95\x93\xf1\x69\xa1\x72\xe6\x5a\x27\xb5\x5e\x46\x9e\xd3\xcc\xfb\x23\xf2\x5f\xab\x6a\x98\x3a\x40\x00\xe5\x01\x83\x72\x01\x57\x7c\x60\xa5\x6f\x1f\x9f\x7d\x5b\x14\x37\xc1\xcf\x3f\x70\xd1\x0a\x59\x83\x4a\xd8\xc2\xc2\xa2\xcd\x2d\x48\x37\x72\x90\xc5\x80\xe9\x08\xcb\x70\xdf\x46\x5d\x73\x4f\xd8\xc8\xdb\x19\x0c\x13\xab\x42\x06\x6a\x00\xb9\x13\xfd\xd2\x48\x85\x05\x50\xf2\xd5\x96\x82\xae\x80\x15\x85\x22\x14\x82\x30\x05\x3d\xb8\x09\xa1\x19\xa2\x15\xe1\x2d\x10\xa5\x30\x71\x2d\x46\x63\x66\x2d\x0f\x21\x52\x7d\x21\xab\x50\x89\x82\x25\x1b\xaa\xc6\xba\x4e\xfa\x0a\x9d\x2c\x8c\xb5\xdb\x09\x50\x29\x38\x45\x60\x4a\x46\x29\x4d\xeb\xdb\x02\x11\x24\x16\x08\x64\xa4\x6f\x4c\x40\x16\x17\xe8\x94\xdd\xc8\xa0\x7c\x89\xef\x56\x2e\x14\x11\xe3\xf7\xfb\xec\x8f\xfc\x21\x29\x7b\x31\x14\x24\xc4\x1f\xed\xad\xc7\xc1\xa6\x03\xa0\x33\x3d\xce\x15\xad\xe5\x11\x75\xbf\x6c\x2f\xf9\x67\x91\xfc\x73\x83\xbf\xb7\x3e\xf1\x07\x9e\xc4\x50\x3a\xa9\xc2\x92\xd3\x95\x30\x55\x1d\x55\x09\x05\xe9\xaa\x32\xe1\xdc\x59\x4d\x59\xb5\x57\xf2\xf7\x5f\xa2\x5d\x04\x50\x6b\x46\x7f\x67\x96\x7d\x99\x9c\x96\x22\xb3\x50\x72\x34\xd8\xce\xad\x91\x30\xf4\x13\x39\x08\xce\x89\x08\x2c\x98\x50\x60\x60\x07\xc5\xdb\x60\x94\x3c\x9b\xec\x26\x59\x82\x3d\x7a\x8b\x1d\x9e\x50\xeb\x30\x3e\x6b\x56\x6f\x66\xa6\x15\xfe\xa4\xec\xe1\x2b\xcb\xc8\xdf\x01\x00\x00\xff\xff\x09\x1d\x1a\x8f\xf0\x1d\x00\x00") + +func fontsRozzoFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRozzoFlf, + "fonts/rozzo.flf", + ) +} + +func fontsRozzoFlf() (*asset, error) { + bytes, err := fontsRozzoFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/rozzo.flf", size: 7664, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRunicFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x54\x5d\x6b\x2b\x37\x10\x7d\xd7\xaf\x38\x84\x40\x12\x1a\x5b\x38\xf4\x06\xd2\xc2\xc5\x29\xf4\xe1\x3e\xf4\xed\x3e\x2e\x6c\xe5\xdd\x59\xaf\xc8\xae\x64\x24\x6d\x1d\x83\xc8\x6f\x2f\xfa\xda\xd8\x89\x7b\x09\xa5\xf4\x03\xea\x10\xcf\xcc\x4a\x73\xe6\xcc\x99\xf1\x76\x43\x77\x27\x2e\x71\x8f\x7b\xac\x3e\x61\xb1\xc2\xea\x81\x7d\xed\x09\x34\xb4\x64\xd0\x4d\xae\x17\xe6\x09\x58\x2c\xb0\x39\xe0\x27\x73\x10\x0a\x8f\x03\x3d\x0b\xd5\x92\x61\xd7\x22\xbb\xeb\x51\xb8\xbe\xb1\x4b\xd3\xeb\x96\xec\x92\xda\xe9\x86\x75\x72\x3b\x90\x83\xa1\x81\x84\x25\xdc\x2d\x57\x01\x65\x75\x87\xc7\x69\x8b\xd5\xc3\xc3\xf7\xec\x6b\x2f\x2d\x3a\xad\x1c\x1a\xad\xac\xb4\xce\x42\x77\x70\x3d\xc1\x4c\x8a\x2c\xa4\x8a\xc1\x09\x95\x25\xf0\xc5\x41\x5a\x88\xa6\x99\x8c\x70\x04\x61\x59\x27\x0c\x84\xc5\x17\x3c\x29\xbd\x5f\x02\x8f\xea\x80\x46\x1b\x43\x8d\x93\x5a\xd9\x5b\x68\x03\xd9\x92\xb0\xd0\x0a\x72\xdc\x19\xfd\x9b\x54\xdb\x08\x1e\xca\x5f\x59\x88\xdd\x8e\x84\x11\xaa\x21\x26\x0c\x61\x4f\x43\xa3\x47\x5a\x02\xbf\xe8\x56\x76\x87\x74\xbb\xb0\x0d\x56\x2a\xc2\x5e\xba\x1e\x23\xfd\x88\x5d\x6a\x91\x16\xa3\x90\x03\x46\x0a\xc8\xcc\x90\x9d\x06\xb7\x64\x8c\xfd\xfc\xbc\x1b\x84\x12\x81\x4b\x68\xb0\x93\xc6\x3a\x0c\x52\xd1\x0f\x2c\xc8\x8f\x05\x2e\x46\xb1\x95\x0d\xd4\x34\x6e\xc8\x5c\xa0\xd3\x06\x9d\x1c\x28\x90\x56\x4e\x76\xb2\x89\xc9\x4c\x00\xc0\x02\xb6\xd7\xd3\xd0\x42\x0c\x7b\x71\xb0\xd8\x10\x7e\x15\x57\xb7\x31\x49\xe9\x3d\xbb\x4c\x97\x42\x73\x17\xbd\x30\xed\x66\x10\xea\xe9\x22\x68\xbf\x33\x52\x39\x1b\x94\x12\x88\x4f\x6f\xb1\x99\x1c\x1a\xa1\xae\x5c\x80\xb1\xe3\x64\x7b\x6a\xd9\x7d\x42\xe8\x49\x6e\x7b\x17\x18\x0b\x34\xbd\x30\xa2\x71\x64\xbe\x79\x78\x0b\xa5\x1d\xa4\x6a\x86\xa9\x0d\x92\xb5\x64\x1b\x0a\x9b\x62\xd9\xea\x53\x4c\x1b\xc5\x73\xec\x1c\x03\xa9\xad\xeb\x71\x4d\xcf\xe5\x72\xa3\xc7\x91\x54\x12\xc6\xde\xe0\x3b\x08\x74\x53\xbb\x25\x74\xa2\x71\xda\xb0\xc5\x2a\x22\xb4\xd4\x89\x69\x70\x89\xec\xa8\x5b\x8a\x8d\xcf\xc3\x61\xab\x87\x78\x2d\x49\x19\xf8\x9d\xe0\xb2\x28\xcf\xe5\xfa\xd5\xd4\xd1\xf8\xda\x1f\x3f\x0c\x66\xcd\x8e\xfe\xfe\xbe\x00\xf1\xb3\x66\x75\xcd\xab\xba\x5e\xb3\x2a\x84\x7c\xcd\x78\x0d\xd4\x55\x38\xaf\x78\x38\xcf\xf7\x3e\x8e\x5b\x63\xcd\x7c\xed\xcf\x7a\xff\x50\xaf\xdf\x54\x21\xd3\xbb\xae\x6f\x72\x38\x7b\x7f\x75\x31\x5f\x05\x78\x8f\x0a\x6f\x7c\xa0\x7c\xaf\x99\x7f\xc9\x27\xf8\x1c\x45\x8b\x43\x38\xf7\x30\x65\xe0\x9d\xa9\x50\x90\xd3\xc3\x0a\xb9\x34\xc0\x7d\x39\xe1\xf0\xf9\x94\xa3\xb8\xbc\x2a\x2e\x0f\x59\xd1\xe5\x21\xad\xf2\x1f\x85\x08\x9f\x3f\x74\x13\x32\x4f\xb0\xa9\xad\x60\xe6\x32\xe5\xee\x6c\xcb\x52\x86\x11\xc5\x82\x28\x6b\x19\x1d\x9e\x3a\x4d\x6c\xb1\x66\x89\xeb\x2c\x8c\x2f\x62\xcc\x8c\x0b\xdf\x99\x57\x35\x13\xcc\xf4\xce\xfe\xa7\x12\x98\x4b\x04\xa7\x42\x2e\x8a\xe4\xe5\xdf\x09\xcf\x4e\x9a\x4f\x8e\x79\xc9\x4c\x69\x29\x27\x76\x32\xcb\xfa\x66\x5e\x67\x27\x9b\xae\x16\xfd\x8b\xfa\xfc\x75\x50\x27\xdd\x1c\xb5\x15\x4c\x2a\xee\x73\xf9\x6c\xe1\x33\x11\x9f\x3b\xc8\x2b\x08\xfe\x32\x0b\x5a\x65\xd6\x79\x08\x3c\x2b\x7e\x7c\x9e\x89\x15\x5e\xef\xe7\x98\x68\x16\x96\xef\x7e\x57\xaf\xcb\x9d\x5b\xe7\x47\x8b\x7f\xba\xc6\xc8\x0b\x83\xbc\x30\xbc\xae\xeb\x7a\xd6\x3c\xda\xbc\x25\x1c\x65\x04\x7e\x5e\x13\x3f\xd3\xf6\xf3\xcc\xb2\xc4\x67\xbc\xb2\xf1\x99\x44\x61\x91\xdb\xf2\xef\xed\x9f\x4c\x08\xe1\xe7\x2c\xce\xc9\xbb\xa0\xbc\x11\xde\x88\xf5\xb2\xa8\xeb\x57\x71\x23\x5c\x50\xa1\xce\xc0\x7e\x2e\xf1\xd6\xfb\x37\xbc\x6f\xff\x0f\xfe\xab\xc1\xef\x01\x00\x00\xff\xff\x5b\x92\x7b\xc9\xc1\x0b\x00\x00") + +func fontsRunicFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRunicFlf, + "fonts/runic.flf", + ) +} + +func fontsRunicFlf() (*asset, error) { + bytes, err := fontsRunicFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/runic.flf", size: 3009, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsRunycFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\xdf\x8b\x1b\x37\x10\x7e\xd7\x5f\xf1\x71\x04\x92\xd0\xb3\x15\xbb\x49\xca\xb5\x47\x70\x0a\x7d\x48\xa1\xd0\x87\x3c\xe4\x61\x61\xa3\xdb\x9d\xf5\x8a\xec\x6a\x8d\xa4\xcd\xdd\x81\xb8\xbf\xbd\xe8\xd7\xda\x3e\xaf\x8f\xd0\x1f\xe9\x05\x6b\x46\x3b\x9a\x99\x6f\xbe\x19\x89\x34\x5d\xb3\x16\xcf\xf0\x16\x6f\xb1\x7a\x83\xc5\x0a\xeb\x57\xec\x63\x4b\xa0\xae\x26\x8d\x66\xb4\xad\xd0\x5f\x80\xc5\x02\x37\xf7\xf8\x55\xdf\x0b\x85\xf7\x1d\xdd\x09\xe5\xcd\xd7\x22\xa9\x9b\x5e\xd8\xb6\x32\x4b\xdd\x0e\x35\x99\x25\xd5\xe3\x3b\xd6\xc8\x6d\x47\x16\x9a\x3a\x12\x86\xb0\x5e\xae\x7c\x94\xd5\x1a\xef\xc7\x2d\x56\x57\x57\xaf\xd9\xc7\x56\x1a\x34\x83\xb2\xa8\x06\x65\xa4\xb1\x06\x43\x03\xdb\x12\xf4\xa8\xc8\x40\xaa\xb0\x39\x82\xb2\x04\x3e\x58\x48\x03\x51\x55\xa3\x16\x96\x20\x0c\x6b\x84\x86\x30\xf8\x80\x2f\x6a\xb8\x5d\x02\xef\xd5\x3d\xaa\x41\x6b\xaa\xac\x1c\x94\xb9\xc4\xa0\x21\x6b\x12\x06\x83\x82\xec\x77\x7a\xf8\x2a\xd5\x36\x04\xf7\xe9\x9f\x1b\x88\xdd\x8e\x84\x16\xaa\x22\x26\x34\xe1\x96\xba\x6a\xe8\x69\x09\xfc\x31\xd4\xb2\xb9\x8f\xa7\x33\x5a\x2f\xa5\x22\xdc\x4a\xdb\xa2\xa7\x5f\xb0\x8b\x25\xd2\xa2\x17\xb2\x43\x4f\x3e\x32\xd3\x64\xc6\xce\x2e\x19\xfb\x11\xbb\x41\x2a\x8b\xaf\xa4\x8d\x1c\xd4\x71\x8d\xa3\xa1\xda\x63\x1f\x77\x3b\xd2\x95\x8f\x22\xea\x3a\x7e\xea\x86\xdb\xf4\xa9\x23\x6b\x49\x1b\x76\xc5\xd7\x6b\x7e\xf5\x13\x7e\x27\xad\x45\x8d\x3f\x25\xe9\x8a\x70\x7d\x43\xdd\xf6\x75\x2f\xed\xa6\x97\x36\x72\xcf\x7e\xbb\xdb\x75\x42\x09\x9b\xf2\x35\x52\x1b\x8b\x4e\x2a\xfa\x99\xf9\x8e\x63\x81\x8b\x5e\x6c\x65\x05\x35\xf6\x37\xa4\x2f\xd0\x0c\x1a\x8d\xec\xc8\xf3\xa4\xac\x6c\x64\x15\x9c\x99\x00\x80\x05\x4c\x3b\x8c\x5d\x0d\xd1\xdd\x8a\x7b\x83\x1b\xc2\x67\xf1\xfc\x32\x38\xa9\xe1\x96\x3d\x8b\x87\x7c\x55\x17\xad\xd0\xf5\x4d\x27\xd4\x97\x0b\xdf\xee\x9d\x96\xca\x1a\x5f\x8d\x40\xf8\x7a\x89\x9b\xd1\xa2\x12\xea\xb9\xf5\x61\x4c\x3f\x9a\x96\x6a\xf6\x36\x46\x68\x49\x6e\x5b\xeb\x11\x0b\x54\xad\xd0\xa2\xb2\xa4\x9f\x34\x5e\x42\x0d\x16\x52\x55\xdd\x58\xfb\x2e\xd5\x64\x2a\xf2\xc3\x69\xd8\xea\x4d\x70\xeb\xc5\x5d\xa8\x1c\x1d\xa9\xad\x6d\xf1\x82\xee\xf2\xe1\x6a\xe8\x7b\x52\x91\x18\xf3\x12\x3f\x40\xa0\x19\xeb\x2d\xa1\x11\x95\x1d\x34\x5b\xac\x42\x84\x9a\x1a\x31\x76\x36\x82\xed\x87\x9a\x42\xe1\xd3\x3c\xb0\xf5\xab\x70\x2c\x52\xe9\xf1\x1d\xc5\x65\x81\x9e\x67\x9b\xbd\x28\x83\x70\xa5\x3b\xfc\xe8\xc5\x86\x1d\xfc\xfb\x7e\x1b\x84\xbf\x0d\x2b\x4b\x5e\x94\xe5\x86\x15\x7e\xcb\x37\x8c\x97\x40\x59\x78\x7b\xc1\xbd\x3d\x9d\xfb\xf6\xb8\x25\x36\xcc\x95\x6e\x56\xfb\x9f\x6a\x7d\x92\x85\x04\xef\x45\xf9\x32\x6d\x27\xed\xdf\x4e\xe6\x0a\x1f\xde\xa1\xc0\x23\x1d\xc8\xeb\x86\xb9\x87\x64\xc1\xbb\x40\x5a\x68\xc2\xdc\xc7\xe8\x81\x13\x51\x20\x47\x8e\x1f\x0b\xa4\xd4\x00\x77\xd9\xc2\xe1\x92\x95\x23\xab\xbc\xc8\x2a\xf7\x5e\x41\xe5\xde\xad\x70\xdf\x1a\xc2\xff\x9d\x55\x63\x64\x1e\xc3\xc6\xb2\xbc\x98\xd2\xe4\xb3\x93\xcc\x43\xe9\x5b\x14\x12\x22\x8f\x65\x50\x78\xac\x34\xa2\xc5\x86\x45\xac\x13\x31\x2e\x93\x31\x21\xce\x78\x27\x5c\xc5\x04\x30\xc1\x9b\xfd\xc5\x14\x98\x52\x78\xa5\x40\x4a\x8a\xa8\xa5\x7b\xc2\x93\x12\xfb\x93\xf6\x3c\x7b\x46\xb7\xe8\x13\x2a\x99\x68\x7d\xd4\xaf\xd9\xce\xc6\xa3\x99\xff\xcc\x3e\xdf\x37\xea\xa8\x9a\x83\xb2\xbc\x88\xc9\x5d\x4a\x9f\x24\x5c\x02\xe2\x52\x05\x69\x04\xc1\x1f\x26\x42\x8b\x84\x3a\x35\x81\x27\xc6\x0f\xed\x09\x58\xc6\x75\xda\xc7\x08\x33\xa3\x3c\xb9\x57\xfb\xe1\x4e\xa5\xf3\x83\xc1\x3f\x1e\x63\xa4\x81\x41\x1a\x18\x5e\x96\x65\x39\x71\x1e\x64\x9a\x12\x8e\xdc\x02\x37\x8d\x89\x9b\x60\xbb\xa9\x67\x89\xe2\x19\x2d\x4f\x7c\x02\x91\x51\xa4\xb2\xdc\xa9\xfc\x9b\x0e\x7e\xfb\x2e\x91\x73\xf4\x16\xe4\x17\xe1\x11\x59\x0f\x8b\xb2\xdc\x93\x1b\xc2\x79\x16\xca\x14\xd8\x4d\x29\x1e\x6b\xdf\xe1\x21\x9d\x16\x57\x4c\x4b\xea\xc3\x8c\xf9\x3a\x56\x3d\x63\xde\x2f\xa9\xed\x53\x6f\x8e\xa4\x2b\xf2\x7d\xf8\x94\x6f\x41\xe1\x26\x87\xc7\xc2\x15\x7c\xe2\x23\x8b\x68\x3c\x5e\x1d\xe7\xc7\xed\x98\x3b\x54\xc4\x79\xfb\x14\x07\xaa\x38\x13\x29\x3d\x42\x2e\xeb\xde\xb0\xff\x1d\xbf\x31\x27\xde\xf9\xc9\x28\xd2\x40\x9f\xf2\x14\x30\x5c\xa7\x27\xe5\x1c\xcb\x38\x6c\xc2\x79\x56\x78\xf1\x34\x2b\x08\x81\x3e\xbb\xa8\x7f\x9e\x49\xc7\xc3\x5b\xc1\x93\x36\xcb\x47\xc1\xf7\xc3\xcd\x4f\x5f\x82\x59\xfc\xfc\x70\x0c\x8e\xf2\xf9\x65\xb1\x48\x3c\xcc\x32\x18\x22\xc0\x4d\xf8\xe7\x41\x1d\xb4\xea\xec\x4c\xcc\x1e\x3a\x03\xf6\xf4\xd6\xce\x04\x7c\x28\xe2\xff\x89\xfc\xea\xfe\xeb\xdb\xf9\x8f\x37\x7f\x05\x00\x00\xff\xff\x92\xe7\x29\xb9\x32\x0e\x00\x00") + +func fontsRunycFlfBytes() ([]byte, error) { + return bindataRead( + _fontsRunycFlf, + "fonts/runyc.flf", + ) +} + +func fontsRunycFlf() (*asset, error) { + bytes, err := fontsRunycFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/runyc.flf", size: 3634, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSbloodFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\x5b\x6f\xdb\x36\x1b\xbe\xd7\xaf\x78\x58\xfb\xa2\x05\x3e\x13\x39\x34\x69\xfb\xe2\xc3\xc0\x0e\x41\xb1\x62\x5d\x5a\x20\x1b\xb0\x5b\xda\xa6\x65\xb5\x36\x19\x48\x4c\x8c\xec\xd7\x0f\x3c\x49\x94\x25\xc7\x1e\xb0\xab\x21\x6e\x2b\xb3\x16\xf9\x1e\x9e\xe7\x3d\x49\xab\xcd\xea\x42\x4e\x71\x8d\x2b\x9c\xbf\xc7\xec\x1c\x17\xe7\x45\xf1\xa9\x2a\x37\xca\x62\x61\xf4\xa3\xaa\x9b\xca\x68\xcc\x9f\xf0\xab\xd2\x16\xb7\xb2\x69\x94\xc6\xeb\x1f\x4a\x5b\x2d\x16\x4f\x73\x55\x37\xf7\x72\xa1\xb8\xa9\xcb\x37\x98\xcb\x46\x2d\x61\x34\xec\x5a\x15\x2b\xa3\x2d\x96\xaa\xa9\x4a\xad\x96\x98\x3f\x51\x51\x7c\xac\x6d\xb5\xd8\x28\x5c\x5c\xbf\x7f\x07\xb3\x42\xad\x16\x5c\xd6\xb6\xe1\xb2\x59\x54\x15\x15\xdf\xa4\x5d\x13\xb4\xda\x35\xbc\xb2\x4b\xfe\xb0\xad\x16\x6b\xae\x96\x0f\x6c\x21\x95\x66\x5b\x69\xd7\xdc\xac\x2b\x33\x6b\xac\xb4\xca\xdf\x58\x9b\xdd\x46\xea\x25\xaf\x55\x63\x8d\xe6\x52\x37\x5c\x2b\xcb\xbc\x88\xe6\xbe\xae\xb4\xdd\x54\xfa\x87\xff\xad\x91\xcd\xba\xda\x56\x7c\xb7\x93\x7c\x61\xb6\x4c\x1b\x3b\x5b\x99\x7a\xb6\x95\xd5\xa6\xf8\x54\x9b\x2d\x61\x59\x35\x8d\xda\x08\xfd\xa0\xab\x05\xd7\x0f\x4e\x03\x5e\xdf\xc8\xc7\x6a\x89\x3b\x8e\xcf\xee\xe6\x9b\xe2\x56\xed\x9a\xb2\x36\x0f\xf7\x0d\xed\x39\xf0\x3f\xb9\xb1\x61\x35\x93\xb5\x2d\xee\x1e\xe6\xdf\xd5\xc2\x12\xbe\x54\x5a\x11\xee\xb6\x72\xb3\x51\x35\x7e\xfe\xf2\xf5\xeb\x0d\x3c\x3a\xaf\xaf\xb0\xa9\xb4\x7a\x53\xdc\x48\xab\x08\xd7\xb8\x35\x8f\x38\xff\xf0\xe1\x2d\xce\xaf\xe8\xec\x9a\x2e\xcf\x30\x3b\xbb\x3e\x3b\x2b\xbe\xd6\xa5\xd4\xd5\x5f\xd2\x56\x46\x13\x6e\xfd\xb7\xdc\xe0\x0f\x5d\x79\x82\xec\x53\xe1\x74\x34\x84\x77\x97\xc5\x9d\xd2\x4b\x55\x13\xe6\x66\x2e\x45\x74\xb6\xf8\x78\x7f\x5f\x9b\x47\xb5\xdc\xfb\xf9\x37\xd5\x34\xb2\x54\xb3\xcf\x37\x84\xff\x5f\x7e\xf8\x5e\x96\xdb\x69\xa5\x2f\x44\x29\xcb\xad\x4a\x48\xfd\x54\xdc\xde\xfe\xfe\x6d\xf6\xcd\x34\xb6\xd2\xe5\xec\x17\xd3\x58\x42\x6f\x47\xf1\x67\xad\x56\x63\xc4\xed\x33\xec\x89\xef\xa1\x44\xe7\x57\xef\x2e\xdf\x16\x45\xf1\xc9\xd4\xb0\x6b\xd3\x28\xec\xd6\xc6\xad\x1e\xca\xb5\x85\x5d\x4b\x1b\x11\xdb\xc9\x06\xd6\x18\xcc\xab\x92\x73\x8e\xcf\x30\xab\x95\xaa\x71\xe7\xef\x52\x31\xcb\x3e\xc5\x14\xc0\x74\x72\xc2\xd7\xa4\x98\x0a\x21\xda\x2b\x13\x2c\xdc\x99\x14\x53\xe2\x14\xd7\xfe\x36\x84\xf0\xa7\x04\x43\xda\xd4\xca\x19\x5f\xf8\xdd\xfe\xa0\x40\xd0\xc0\x84\x08\x7a\x20\x98\x00\x13\xcc\xfd\xce\x18\x23\xe6\x2e\xee\x77\x22\x80\x40\x48\x52\x10\xf5\xc3\x9f\xf4\xdb\x85\x60\xcc\x1b\x88\xb0\x0c\x5b\x9d\x10\x2f\x80\x13\xcf\x8f\xc7\xc3\x40\xd0\x0b\xb7\x08\xe6\x0b\x11\xc4\x30\x46\x48\x1e\xc3\x19\x30\x38\xec\x34\x23\xb8\xc0\xbc\x37\x51\xbb\x73\xa0\x15\xc1\x92\x55\x4e\x3f\x21\x81\xd7\x13\xe4\xcd\x0f\x08\x8d\x5d\xa3\xb6\x80\x55\xf0\x35\x21\x14\x24\x23\x09\x9d\x74\x7b\xe2\x09\x44\xea\x18\x73\x5f\x19\x84\x2d\x0d\x89\x07\xef\x39\x8b\x5e\x30\xb7\x62\x22\x9c\x02\x18\x11\xe5\x7e\x80\x53\x9f\x8b\x20\xae\x03\xa1\x5d\x79\x34\x22\xb2\x2d\x14\x9e\xca\x7d\x3c\x87\xae\x07\xe5\xe4\x9c\x73\xdc\x75\xfb\xa7\xfd\xa5\xc8\x95\x8c\x6d\x68\x97\x6e\x3d\x1d\x5e\xbc\x8a\x78\xdb\x47\x42\x8c\x89\x16\x19\xc6\x12\xb9\x2c\x52\xeb\x3d\x18\xf8\x20\xda\x70\xf4\x51\x14\x49\x73\x87\x83\x79\x3e\xa6\x22\xa8\x4e\x42\x1f\xc5\x8c\xe8\x51\xf6\x3a\xd0\xa6\x03\x6d\x99\xd9\x9c\xc5\xf8\x40\x1e\xc2\xe4\xb4\xd1\x9e\xb6\x4e\x42\x96\x01\x8e\xf5\xd6\xae\x90\x7f\x44\x34\xcc\x80\x14\x3c\x03\x6f\x7b\x64\xa4\x10\x02\xb2\x38\xed\xeb\x0f\xf1\x2f\x90\x92\x26\x4b\x5f\x84\xf4\x25\xda\xcb\xfe\x36\xdc\x5a\xb4\xd3\xf1\xa8\x1f\x27\xa1\x2d\x3a\x03\x90\xd7\x00\x20\x99\xc0\x03\x86\x1d\xe3\x63\x84\x0d\x39\xc7\x01\x2b\x3c\x0d\x27\x8a\x10\x21\x05\x3b\x20\x29\x3a\x42\x34\xb4\x22\x1c\x4e\xab\x88\x79\xb8\xb4\x95\xbb\xad\x75\xcf\x26\xd7\x5e\x12\x64\x89\xdc\xde\xed\x12\x19\x3e\xa8\xf6\xd2\x31\x16\xf4\xfe\xaf\xa9\x9c\x3f\x93\x99\xad\x7e\xd1\x06\x43\x5e\x52\x52\x12\x75\xfa\x3d\x12\xcf\x62\xe8\xb2\x41\xa4\x60\x7a\xf5\xaa\x75\x8f\xe8\x20\x93\xa9\x9b\x78\x7d\xb1\xf9\xc1\xb3\xe9\x34\xfa\xfc\x8f\x67\x43\x52\x1c\x6a\x4a\x23\x65\x20\x25\x46\x3f\x30\x9f\x49\x8c\x71\x11\x7b\x51\x45\x87\x2b\x49\x3f\xb9\x32\x1a\x91\xf9\x92\xb9\x72\xaa\x15\x23\xf5\xcc\x5b\x31\x8c\xed\x2c\xc3\x44\xa7\xda\x97\x98\x5e\x9b\x8d\x19\x76\xb8\x48\x9d\x26\x22\xe6\xe8\x71\x6a\x3b\x34\xfa\xd4\x76\xf3\xc6\x28\xb5\x47\x6b\xde\x49\xd4\x86\xd3\xa1\xd6\x85\x33\xde\xfb\xa8\x6d\xd0\x86\xb2\xb2\x14\x0e\x70\x5f\xe4\x43\x06\x70\x1a\xb4\xd2\x7d\x23\x59\x32\x52\xb4\x83\x03\x81\xda\xe1\x01\xe3\x98\x77\xc9\x98\x63\xde\x22\xd7\xa7\x8d\x1f\x0c\x9e\x2c\x7e\xe2\xbf\x28\xc8\xf5\x54\x91\xfc\x07\xf2\x0a\xe7\x3f\xfd\x22\x37\xea\x9a\xaf\x33\xc9\xb5\xb1\x88\xc4\x48\x44\xfe\xd3\x26\xcd\x0f\x06\xf5\x50\x44\x0e\xf0\x49\x11\x89\x5c\x06\x32\x3b\xa2\x14\xf7\x97\xd0\x59\x42\x83\xf1\xf1\x70\xa5\x38\x44\xf6\x80\x29\x8c\x74\x61\x8c\x76\x61\x3e\xec\xc2\x79\x07\x4d\xa3\x73\x68\x9f\xa9\x57\xb4\x44\xd2\x60\x60\x3a\x98\x4e\xa3\x5c\x8c\x36\xcf\xa3\x22\xc0\xdc\xd4\xcd\x9e\x29\xfc\xed\x14\xdc\x97\xc3\x90\x45\x6b\x18\x01\x43\xbc\x22\x18\xe5\x2f\x71\x9e\xf5\x43\xf1\x7e\x63\x3e\x92\x90\xe8\xe2\x05\x1d\x47\x5e\xc8\x78\x42\x76\x12\x58\x36\x64\xec\xc3\xcc\x47\x61\x1e\x1f\x73\xba\x47\xa6\xde\xa4\x78\x28\x9b\x93\x2b\xa1\x72\xa5\x07\x85\x54\x04\xba\x47\x9b\x49\xbf\x87\xb7\xcf\x49\xd9\x20\x1d\x9a\x78\x9a\x21\x72\x75\x6d\x44\xa6\xf6\x9f\x02\x2a\xb5\xfe\x60\x24\x7a\xda\xc2\x2c\x88\x2c\x83\xc4\x81\x41\xe3\xd8\xf8\x71\xc2\xe6\x62\xca\xc3\x67\xda\x36\x2d\x50\xf0\x39\x3e\x0a\x4f\x8e\x3c\xca\xbd\x4c\x07\x2f\xd3\xc1\xcb\x74\xf0\x32\x1d\xbc\x4c\x07\x2f\xd3\xc1\x7f\x61\x3a\xe8\xbf\xb5\x62\xa1\x09\x65\x59\x12\xb7\x8f\xbc\xe0\x8a\x7d\xbd\x23\xd1\x7d\xf1\xd0\x4e\x91\xbd\xca\x44\x3e\x05\x64\x2f\x3e\xd1\x9b\x02\x02\x0e\x93\xf8\x5e\x5a\x74\x5d\xfb\xd8\x6a\x52\x64\x7f\xfe\xed\xff\xfc\x1d\x00\x00\xff\xff\x06\x60\xe4\xa7\x4c\x1a\x00\x00") + +func fontsSbloodFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSbloodFlf, + "fonts/sblood.flf", + ) +} + +func fontsSbloodFlf() (*asset, error) { + bytes, err := fontsSbloodFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/sblood.flf", size: 6732, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsScriptFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5b\x7d\x6f\xe2\xb8\xf3\xff\x9f\x57\x31\x7f\x44\x3a\xfa\xfb\xb5\x6b\x92\x3e\x50\xa4\xd3\xa9\x59\xc8\xb6\xd1\x52\xc2\x05\xd8\xbd\x95\x22\x59\xec\x36\xdd\xa2\xa3\xa4\xe2\xe1\x4e\x2b\xe5\xc5\x7f\xe5\xc7\xd8\x8e\x9d\x02\xed\xad\x0a\x71\x82\x3d\x33\x1e\xcf\x7c\x3c\x33\xce\x3e\x2e\x1f\x83\xb9\x07\x5d\xb8\x04\xff\x0a\x3a\xe0\x77\xa0\x03\xe7\xbd\xce\x45\x6b\xf2\x63\xbd\x78\xd9\xc2\xf7\x5f\x70\xbb\xcc\x57\x2b\xe8\x3f\xcd\x5f\x5e\xf2\xe5\x12\x2e\x50\xef\xbc\x15\xaf\x7e\x2c\x77\x0f\xf9\x06\xe2\x49\x02\xc3\xf9\x76\xb1\x3a\xf3\x5b\x8f\x8b\x9f\xcb\x7c\x0b\xeb\x7c\x99\xcf\x37\x39\x04\x1f\x7c\x38\x3b\x03\x3f\x80\x70\xf7\x13\xfc\x5e\xef\xa2\x35\xce\xd7\xcf\x8b\xcd\x66\x51\xac\x60\xb1\x81\xa7\x7c\x9d\x7f\xff\x05\x3f\x17\xff\xe4\x2b\xd8\x16\xf0\x5c\x3c\x2c\x1e\x7f\xc1\xf6\x69\xb1\x81\xc7\x62\xb5\x3d\x85\xf9\x06\x96\xc5\xea\x27\xb9\x6e\x9f\xf2\x16\xed\xb0\xc8\xd7\xbf\x6d\x60\x35\x7f\xce\x09\x8d\x97\xe5\xfc\x47\xfe\x00\xc5\x0a\xe6\xf0\xa3\x78\x7e\xce\x57\x5b\x58\x2e\x56\xf9\x87\x56\xeb\x9e\xf5\x7e\x20\x73\x18\xcf\x77\x4b\xf8\xb8\x5b\x6f\x8b\x15\xfc\xbe\x29\x96\xbb\xed\xa2\x58\xdd\xe4\xf3\xf5\xf6\x69\xb9\x58\xfd\xfd\x61\x95\x6f\xff\x00\x3f\x40\xbd\x2b\x22\xc8\x82\xcd\x0e\x56\xf9\xbf\xf0\x32\x5f\xcf\x9f\xf3\x6d\xbe\x6e\x6d\x76\x2f\x2f\xc5\x7a\xcb\x08\x7e\x8a\x6f\xc9\x5c\xe7\xab\x07\xd2\xfc\xba\x58\x7d\x00\xb8\x9f\xff\x82\xf9\x72\x53\xc0\xf7\x1c\x36\xcb\xc5\xcf\xa7\xed\xf2\x17\x3c\x0b\x29\x1e\x8b\x35\x7c\xcf\xb7\xdb\x7c\x0d\xbb\x4d\xde\x2a\x1e\x29\xf9\xc7\xdd\x72\x79\xf6\xef\xe2\x61\xfb\x84\xfe\xce\xd7\x2b\xb4\x79\xde\x6d\x9e\x60\xbe\xdc\xe6\xeb\xd5\x7c\xbb\xf8\x27\xdf\x9c\xc2\xf7\xdd\x16\x1e\xf2\xc7\xf9\x6e\xb9\x85\x62\xb7\x7d\xd9\x6d\xc9\xcc\x47\xc9\x14\x7e\x3c\xcd\x57\x3f\xf3\x87\x0f\xad\x96\xe7\xdd\xb8\x3e\x37\x2d\x80\x9b\x16\x94\xca\xa7\xe0\xcf\x80\xfc\x58\x90\xbb\x92\x3c\x26\x03\x94\x2f\xd6\x85\xf6\x11\xff\x68\xb3\xa4\x7f\x37\x2d\x38\x3b\xfb\x7f\xfa\xa7\x37\x95\x0e\xda\x30\xde\x14\x6d\x72\x2d\x71\x89\x6f\x5a\xd0\x2e\x71\x49\xee\x71\x89\xcb\x13\xfa\x1c\x4a\x50\xfb\xa9\x03\x49\xff\x13\x40\xf4\x0e\xd1\x5f\x11\x7d\x88\xa0\x7d\x52\x75\xa9\xb1\x6a\x9f\xb0\x2b\xca\x78\x6f\xc8\x08\x8d\x0c\x63\x94\xd9\x58\x11\xa5\x90\x0e\x9e\xf2\x91\x2a\xe3\xa4\x88\xde\x40\xfb\x82\x4c\x51\x19\x21\xcf\xa6\xa9\x7d\x21\x43\xad\xea\x35\x2b\x11\x53\xec\xff\x31\x55\xa2\x32\x73\x2a\x42\xff\x41\x59\x11\xe5\xbe\x3e\xd0\xf8\x88\x69\x3a\xa8\x02\xa7\x7a\xc6\xa9\x7a\xfb\x53\x05\x95\x2a\xbb\xd8\x16\xad\x5a\x2d\x75\xd1\x30\x06\xd1\x2b\x63\xca\x05\xa6\x3c\xd9\xa0\x2b\x57\x19\x56\xd5\x20\xad\x53\x42\xba\xac\xab\x5e\xb5\x68\x8c\xb9\x00\xd4\x6a\x3c\x4d\x2a\x8c\xb1\x45\x2a\x2c\x87\xb0\x65\xf6\x30\xa6\x33\xf2\xd8\x7d\x86\xf9\xbd\x6b\xb1\xa8\x5b\x90\x2b\x66\x66\x0f\x20\xcd\xdc\x61\xee\x98\x09\x52\x0a\x02\x5c\x82\x3d\x38\xf2\x8e\xc8\xe3\x9c\xd9\x7d\x89\xb8\xe8\x99\x63\x20\xe6\x1c\x09\x07\x3e\x37\xa6\x18\x0f\xc9\x05\x71\x89\x2a\xdc\x8a\x7b\x55\xed\xae\xae\x4e\x3e\xa2\xa4\x7d\xd8\x7a\x89\x75\x12\x17\x6d\x04\xb7\x2c\xe1\x8e\xba\x95\x59\x7e\x44\x75\x7f\x45\x95\x57\x66\x16\x88\xb3\x18\x7d\x65\xfc\xae\xa9\x1b\x24\x91\xe2\xe3\x75\x6b\xe3\x96\x43\x45\xe3\x3e\x5a\xd8\x7d\x40\xe1\x44\x56\x45\xe8\x1f\xe3\x53\xee\x12\x88\x02\x25\x6d\x12\xf5\x31\x9e\xc4\x26\x54\xc7\xa8\x0c\x02\x9f\x56\x4b\x58\x42\xe5\x55\x66\x93\x61\x62\x65\x1f\x16\xfc\x3e\x15\xf3\x91\x06\x45\x2c\x4c\xcc\x89\x3f\x69\x2b\x36\x66\xf8\x27\x91\xc6\x63\xb2\xb4\xf1\x09\x67\xef\x81\xda\xd0\x8d\xdb\x18\xef\x55\x0a\x69\x53\x86\x12\x03\x99\xe1\x78\x58\x36\xdb\x28\xab\x29\xc4\x98\x0d\x17\x46\xc8\x92\x61\xec\xf1\xc5\xa2\x57\xa7\x97\x51\x29\xa8\xbb\xb4\xf1\x09\x94\x1e\xff\x11\x97\x6c\x6e\x80\xf8\xf2\x40\x1b\x23\x8d\xad\xd2\xd2\x27\xd8\x3e\xe1\x76\x8f\x32\xe6\x0e\x88\xcf\x02\xb5\x9b\xd0\x4e\x3c\x43\xa5\x84\x12\x02\x15\xbc\x45\x9e\x65\xb2\x85\x1a\xc4\xc0\x42\x8d\xa5\x72\xc5\xc0\x2c\x2b\xc3\x28\x6b\x84\x37\xb1\xb5\x4a\x98\x13\xb2\x64\x98\x73\x45\x1c\xe6\xb2\xd2\x26\x38\x12\x82\x73\xa8\x29\x21\xf3\x44\x0b\x34\x7b\x34\x05\xf7\x30\xeb\x98\xe1\x12\x9f\x88\xfd\xd0\x63\x1d\x3d\x2c\x5a\xdc\x12\x9c\x64\x4e\x31\xa6\xfb\x8e\x10\xa8\x8a\x62\x5e\xbd\xd1\x9c\x45\x33\xb0\xca\x61\xe4\x54\x11\x64\x00\xd5\xd2\xd8\x9b\x8d\xee\x57\x6d\x8f\x19\xce\xd0\x11\xdb\x63\xdd\x7d\xb1\xe2\xbe\x9e\xd6\xb0\x8c\x67\x6a\xaa\x36\xe8\x6a\x8f\xe1\x60\x82\xe8\x1a\x1f\x02\x26\x95\x38\xd2\x7c\xd1\x81\x56\xa0\x38\x11\xf7\x21\x29\xa1\xf0\xa0\x3d\xbc\x98\xff\xe8\x89\x96\x27\x26\xf5\x8a\x17\x7b\x58\x79\xde\xc6\x2a\x9e\x82\xfb\xc6\xa2\x1e\x8b\xf9\x48\xda\x92\xb4\xb0\x8f\xd2\x20\xac\xd0\x45\x06\x25\xad\xad\x09\xac\x11\xae\x13\x37\x19\xe8\x4c\xea\x8c\x6a\x53\x30\x18\x52\x5e\x99\x88\xb5\x00\xbc\x4c\x52\xf0\x90\x70\x0d\x42\xb5\xd1\x6c\x34\x6a\x15\xee\x81\xbd\xc9\x36\x48\x41\x02\x55\xe1\x16\x87\x22\x8f\x9b\x60\x1b\x8b\xbd\x84\x07\x84\x42\x4a\x24\xac\xc7\xc4\x30\x5c\x4f\x02\x78\x90\x77\xa3\x46\x16\x34\x44\xe0\x1e\xc1\xe7\x22\x22\xfb\xec\xa6\xb6\xf9\x33\x20\xb6\x04\xb0\xb8\x94\x54\x59\xda\xe2\x59\xbe\xe0\xc6\x15\xd3\xd4\xaf\x9e\x76\x65\x9e\xc0\xa3\xa7\xcc\x9d\xfd\x68\xeb\x41\xb5\xc0\x83\x0b\x24\xac\x83\xe8\xdb\xb5\x7d\x0b\xb8\x2e\x65\xec\x21\x61\x23\xc3\x0c\x33\x50\x5d\x5a\x9b\xf8\x02\x38\x38\xc2\x37\x47\xe0\xfc\x49\x29\x86\x96\xfb\x4b\xac\x2e\x0f\x19\x2b\x51\x8e\x05\xe5\x96\xe8\xd6\xc3\x9e\x98\x9a\x72\xd1\x46\x94\x59\x45\xc6\x3e\xb9\x53\x29\x20\x97\xcf\x6a\x82\x54\x9d\x95\x22\xcd\x16\xaa\x00\xda\xd8\x57\x6a\x00\x4a\x16\x5e\x3c\x66\x03\xa8\xb4\x48\x3e\xd1\xba\x42\x51\x75\x15\x51\x07\x62\x7b\x27\x11\xb7\x7c\x65\xad\xf1\x09\x88\xd0\xd5\x0e\xcb\xaf\x2a\x10\xec\x11\x73\x0d\x7e\xf8\x92\xb1\x3f\xa6\xd2\x92\xfd\xb1\x08\xc1\xb1\x8b\x9b\x54\x1c\x58\xd4\xaa\x53\x56\xc8\x36\xef\xe3\x0e\x73\x06\xe6\x07\xda\x16\xee\x32\x67\xd9\xe0\x21\x81\x74\xa2\x92\x8f\x46\xc2\x12\xb2\xb2\x61\x7c\xa3\x03\xcb\x22\x04\x89\x04\xed\xe3\x4f\xa5\x02\xe4\xf4\x61\x5f\x77\x12\x9c\xa9\xdc\x64\x37\xb0\xaf\x6d\x75\xc1\x25\x07\x48\x3e\xe5\x06\x6b\x70\xb4\xaa\x6d\xcc\x33\xfc\xbe\xee\x15\x56\xe4\xa4\x6b\xcb\xc5\x6d\x58\xa3\x9a\xa9\x68\x22\xa8\x44\x54\x3a\x7b\x98\x0a\xbf\x22\x3e\xcc\x43\x0e\x37\xb2\x2c\x95\xae\x03\xa1\x02\x3e\x5a\x6e\x8d\x62\x7f\x33\x19\x4b\x1b\x45\x74\xeb\xf3\x90\xb0\x51\x73\x63\xe4\xc3\x90\x44\x87\xdf\x55\xa4\x10\xbb\xde\x8d\x51\x99\xd4\x3f\x92\x4e\xa6\x8d\xfd\x43\xb6\x91\x0a\x4b\x3c\x3f\x61\x79\x58\xfd\x5b\x43\xb0\x02\xaa\xbc\xfb\x95\xd4\x78\x8f\x10\xb6\x90\x60\xe8\x8c\xcc\x1b\x03\x72\x4e\x81\x2d\xe5\xbe\x81\xe4\x7e\xb1\x63\xa1\xd6\x17\xf6\xf0\x75\x53\xb6\x6a\x6a\x07\x82\x94\xaa\x61\x43\xb4\xc3\x1c\x90\x57\xb2\xa8\xc5\x94\xa2\xea\xca\xef\xb0\xd0\x71\xe5\xf9\xfe\x55\x07\x60\x94\x9c\x7d\x4c\xa3\xf0\x33\x4c\xc6\x61\x3f\xaa\x55\xb6\xeb\x5f\x64\x9c\x0f\x10\x8f\xbe\x44\xe9\x34\x1a\x40\xf4\x57\x7f\x18\xde\x87\xd3\x38\x19\xc1\x7d\x98\x7e\xae\x0a\x4c\xaa\x85\x52\xb6\x74\x6c\x00\xd0\x8f\x46\x53\x98\xc4\xb7\x23\x9b\xd7\x94\xbc\xfe\x23\x14\xae\xc4\xd8\x8a\xd2\xfc\xab\x73\x80\x71\x32\x1b\x0d\x14\x42\x58\x74\x41\x2c\x64\xc4\xb8\x14\x56\x86\x4b\x1e\xb8\xb5\x91\x56\xd2\x33\x94\xe8\x5f\x5d\x00\xf4\x67\x69\x1a\x8d\xfa\xdf\x0c\x11\x33\xc0\xcc\x47\x91\xa8\x61\xf1\x6d\x43\x89\x4c\x75\x11\x2f\x01\xbe\x45\xa3\x1a\x19\xb6\x32\x38\xc3\x08\x0b\x21\x6b\x33\x54\xc9\x5c\x01\x7c\x4c\x93\xcf\xd1\x08\x3e\x86\x69\x5d\xad\x2a\x08\xf8\x57\x5d\x80\x49\xd4\xa7\xab\xc1\xf9\xd2\x84\x0d\x44\x1c\x4c\x7d\x0d\xb3\xfa\x3f\xfb\x22\xa3\xae\x01\x06\x71\x18\xa5\xd1\x24\x9e\x30\x4b\x66\x1b\x93\xe7\xba\x80\x61\x49\x3d\x80\x7e\x32\xfe\x96\xc6\xb7\x77\xca\xd2\xb2\xe2\x13\x87\x37\xe2\x0f\x99\x40\x0f\x44\x92\x4f\x5e\x9d\x2b\xd9\x5c\x99\xef\x33\x37\xe1\x8e\xc2\x4b\x74\x35\x5f\xf5\xbb\x1d\x80\x4f\xd1\x7d\x3c\x8a\x47\x11\x24\xe9\x20\x1e\x85\x43\x88\x47\x83\xb8\x1f\x4e\x93\xd4\x1e\x12\x62\x5e\xa2\x64\xd4\xec\xf5\x79\xbf\xeb\x03\x0c\xa3\x4f\xd3\xb3\x71\x12\x8f\xa6\xf1\xe8\x16\x06\xc9\xec\xe3\x30\x82\x70\x74\x3b\x8c\xe0\xcf\x59\x32\xd5\x4c\x9d\xcf\x87\x46\x73\xac\xf8\xc3\x6d\x23\x33\x80\xd4\xef\x06\x40\x4f\xa2\x2a\x6b\x60\x69\x04\xef\x52\x72\xa9\xd4\x8b\xa6\xe2\xee\x39\xc0\x24\xf9\x34\x85\xbb\x6f\xe3\xbb\x68\x54\x8b\x0d\xd8\x45\x39\x7f\xb0\x90\xb8\x00\x48\xa3\xdb\x78\x32\x8d\xd2\x68\xe0\x58\xa6\x53\xa8\x96\x89\x95\x60\x32\xb9\x8d\x63\x24\x97\x89\x86\xa3\xaf\x2e\xd3\x25\xc0\x7d\xd8\x4f\x93\x91\x52\x30\x37\x32\xa9\xfa\xd5\x5c\x92\x2b\x80\x41\x74\x9b\x46\x91\xb4\x68\xb6\xb4\xac\x62\xae\xc4\xdc\xb5\xdd\xcb\xef\x76\x01\xc6\xc3\xd9\xe4\xec\x3e\x1e\xcd\x26\x2e\xcc\x31\x8e\x84\x2a\x8f\x34\x25\xb9\x06\x98\xcc\xc6\x51\x3a\xe9\xa7\xf1\x78\x0a\xd3\xaf\x89\xc8\x40\x4f\xe8\x61\x88\xf4\x2a\x3d\xbb\xf4\xbb\x3d\x63\xe0\x5d\x1a\x45\x54\x25\x14\x9b\xa8\x4b\x72\x9f\x74\x4c\xe4\xba\x03\x10\xf6\x67\xd3\x08\xc2\x3e\x81\xcf\xfa\x91\x9b\x9a\x78\xfa\xd7\x3e\xc0\x7d\xdc\x4f\x13\x75\xca\x7b\x6c\x31\xa5\xdc\x62\x4a\xed\x57\x21\x45\x00\x30\x8e\x87\xfd\x34\xf9\x2a\xd7\x42\x9e\xf5\x94\xe2\x7c\xa2\x04\x59\x16\x35\x1b\x60\x6c\x9a\xfe\xf5\x39\x11\x74\x30\x18\x46\x30\x48\xa6\xea\xa4\x5b\xe0\x25\x5e\x43\x64\xe2\x5f\x13\xa8\x8e\x06\xf1\x70\x18\x56\xca\x56\xbf\xe8\x10\x01\x75\x64\xc0\xa5\xbe\x0a\xc9\x28\xaa\x9f\x80\xd9\x96\xef\xfa\x8a\x98\xf1\xa4\x3f\x1b\xba\xe1\xc6\xba\xd5\xbf\x0a\x37\xd7\x5d\x00\x8a\x99\x07\xe1\x8d\x86\x31\x0a\xf6\xe8\xea\xb9\x06\xf8\x32\x1b\xde\x86\x29\x7c\x4a\x43\xb6\x23\x24\x23\x42\x32\x4c\xa7\x51\x2a\x8a\xca\x2c\xef\x11\x85\x64\x51\x5f\x42\xfc\xbc\x19\x69\x27\x6e\xc6\xd2\xf5\xec\x0c\xee\xc2\xe1\x27\x4e\x5d\x10\x67\xb4\x45\x78\xc2\x9c\x05\x84\xbf\x18\x2a\xe9\x75\xea\x64\xa9\xbf\x08\xc9\x27\x0c\x36\x45\xbc\x80\xb8\xf0\x18\x9f\xc8\xea\x98\x10\xdf\x94\xdf\xd8\xec\x7b\x6a\x1c\xf3\xe7\x2c\x9a\xe8\x9a\x66\xbd\x0b\x11\x3f\xf0\xf2\x89\xeb\x98\xce\xef\x05\x00\xc3\x70\x1a\x8f\xa0\x1f\x8e\xe3\x69\x38\x84\x61\x34\x9d\x46\x29\x84\xf0\x35\x9e\xde\xc1\x6d\x1a\x7e\x89\x58\x38\x2a\x47\xbe\x35\xa0\xf6\x7b\xe7\xcd\x4c\x29\x66\xf0\x98\xe8\xfd\x98\x5e\x34\x33\xed\xc7\x69\x7f\x76\xff\x69\x18\xfd\xc5\x38\x67\xef\xc7\xf9\xb2\x99\xf3\x34\x1e\x0e\xe8\x74\x51\x55\x2a\x7d\x3b\xd3\xab\x66\xa6\x4a\xe4\xf4\xae\xd9\x92\xdf\xeb\x36\x33\x4e\x09\x5e\x84\x1f\x13\x6e\x56\xd2\x27\xa0\x8d\x4f\xde\xc8\xf9\xda\xc5\x39\x12\x33\xab\x0e\x26\x09\xd9\xea\x70\x12\x44\xcc\x2d\x18\xaa\x2c\xf1\x2b\x49\x98\xdf\xeb\x39\x18\xf7\xb9\x69\x55\x80\x7f\xd0\xc9\xa8\x3c\xed\xe2\x8c\x82\x4e\xc7\xc1\x28\x32\xbc\x55\xd6\xd9\xe5\x61\x67\x9b\x15\xe4\xfe\x38\x3b\x93\x70\xe0\x3a\x80\x0d\x3a\x7e\x33\x1b\xe9\x9f\xe8\x6d\x6c\x5c\xd8\x13\x59\x3c\x12\xbd\x71\x4a\x2e\xc8\x89\x6a\xee\x50\x54\xf8\x79\x1c\x2b\x17\xd0\xc4\x16\x48\x65\xfb\x2c\xf6\x44\x48\xc7\x5e\x94\x12\x95\xd0\x4c\xb7\x78\x9d\x8d\x0b\x55\x62\x0b\x88\xbe\x81\x8d\x0b\x47\x62\x1b\x6c\xa2\xb7\x4d\xc9\x05\x1d\xb1\x15\xb3\x8a\xb7\xb0\x72\x61\x45\x34\xbd\x73\xbd\x81\xc0\x33\xf3\x43\xdf\x40\x08\x3a\x2e\x78\x18\x39\xf1\x7f\xbf\x03\xe5\x06\x30\x0c\x7c\x17\x54\x24\x0e\xa8\x38\xaa\xb6\x15\xf8\x2e\xa8\x48\x5c\x56\x78\x1c\x1b\x17\x54\x24\x8d\x56\x78\x1c\x2f\x17\x54\x24\x96\xe5\x7a\x03\x1b\x17\x4c\x24\x4d\xc6\x7e\x1c\x2b\x92\xd1\xce\x86\xd3\x78\x3c\x24\xc1\xbf\x52\x66\xd1\xd2\x70\x2f\x43\x1e\x2b\x36\x3b\x6b\x26\x81\xef\x82\x03\x2e\xf5\x64\x9a\x26\x9f\xf9\x76\xcb\x0b\x4f\x24\xe5\xe6\xb5\x3d\xfe\x12\x83\x48\xc8\x11\xae\x8a\x51\xa6\xc8\x2e\x28\x98\x99\x20\xca\x02\x53\x78\xf7\xd2\x6a\xe0\xbb\x20\x62\x66\x9a\x76\x15\xa7\xbe\xb7\x08\x2e\xe4\x98\x59\x63\x56\xb6\x49\xfe\x07\x72\x04\x2e\x30\x99\xd5\x6d\xf5\xbf\x2b\x76\x07\x81\x0b\x6c\xbe\xd5\x56\x04\xe9\x02\x34\xbc\x46\xf0\xca\xbb\x03\x41\xe0\x82\x9e\xe9\x5d\x92\x8e\x94\x8c\x54\xbe\x86\xd9\xf4\xde\x8d\x3e\x31\x4a\x5f\xc2\xcd\xe4\x3e\x1c\x4a\xea\x93\xbb\x30\x1d\x03\x55\xe8\x81\x15\xf2\x20\xb8\xb0\x52\x34\x33\xba\x4c\x93\xe4\xc0\x83\x83\x20\xb8\x6c\x62\x52\x8b\x10\x8f\x64\x72\xd5\xc4\xc4\x1e\x1f\x1e\xc9\xa9\xdb\xc4\x49\x40\x3e\xd2\x8e\xf1\x0e\x67\x72\xdd\xc4\xc4\xa8\x65\xbf\x89\x51\xaf\x89\x91\x91\x81\xf1\xc1\xed\x93\x63\x38\x9d\x77\xec\x9c\x24\x69\xc5\x8b\x39\x71\x59\x75\xaa\xc2\xb4\xd2\x7d\xb8\x11\x9c\xfb\x56\x0e\xf5\xd4\x4a\x2d\xc9\x68\xd5\x2d\x19\xb1\x53\x1e\x6a\x52\x45\xe9\x07\x56\xfa\x46\x46\x95\xa9\x1b\xe5\x1e\x6f\x88\x04\xe7\x76\xb7\x36\x32\x28\x74\x30\x59\xbb\x6f\x5b\x32\x26\x74\xb8\xc8\x76\x97\xb6\x65\x48\xc5\xa1\xa4\xed\x8e\xac\x67\x44\x52\x60\xf9\xed\x7a\x45\x25\x38\xb7\xbb\xab\x9e\xfa\xa0\x03\xe8\xd9\x3d\xd3\x92\xe3\xa0\x6c\x7f\xa2\x76\x2f\xac\x27\x33\x86\x3e\x25\x59\xb7\x3e\x2f\xec\x6e\xc7\x92\x17\xd1\x95\x9d\x97\xe3\xdf\x4a\xed\x3d\x7c\x93\x13\xa1\x66\x77\x31\x77\x7a\xa2\x3a\xf4\x51\x2f\xc7\x04\x17\x76\xaf\x4b\x6a\x5e\xe7\xf0\xe9\xc6\xc3\xe9\xe0\xc2\xee\x7c\x66\x4e\x82\x8e\xa4\x6e\xf7\x41\x5b\x2a\xa2\x38\xe1\x61\x2c\xec\xae\x98\xd4\xb7\xa3\xa3\xa8\xdb\xbd\xb1\x9e\x78\x1c\xfb\x76\x40\x70\xd1\x05\x18\xc4\x5f\xe2\x89\x9e\x6b\xe8\x7d\x13\x7a\xad\xfe\x03\x46\x02\x76\x5a\x76\xdf\xac\x25\x1c\x35\x5b\xe1\xb9\x05\x62\xa2\x22\x25\xd7\xd0\xc8\xdb\xbd\xd4\xcc\x33\x32\xa8\xed\x65\xa0\xba\xea\x3e\x6f\x3b\x04\x97\x76\xb7\x35\x13\x0a\xf4\x2e\xbc\xec\x4e\x6d\xcd\x1c\xf4\xe0\xe9\x58\x86\x76\x97\xae\xa7\x08\xef\xf3\xea\x48\x70\x69\x77\x72\x33\x17\xa8\x45\xa0\x3a\xa3\xe6\x17\xa4\x82\x4b\xbb\xaf\x8b\xd8\x5f\x60\x9f\x7c\xf1\x51\x69\xbc\xfe\xa6\x5e\x70\x69\x77\xf3\x6f\x0d\x35\xc9\xa3\xa6\xf1\xbf\x00\x00\x00\xff\xff\xc7\x1c\x89\xcb\x08\x3c\x00\x00") + +func fontsScriptFlfBytes() ([]byte, error) { + return bindataRead( + _fontsScriptFlf, + "fonts/script.flf", + ) +} + +func fontsScriptFlf() (*asset, error) { + bytes, err := fontsScriptFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/script.flf", size: 15368, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSerifcapFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x55\x4b\x6a\x1c\x41\x0c\xdd\xf7\x29\xde\x62\x16\x12\x34\x51\x32\xf8\x00\x8d\xf7\xb9\x41\x81\x70\x9c\x19\x30\x84\x10\x26\x64\x91\xdb\x07\x7d\xaa\xaa\xab\xc6\x33\x04\x42\x76\x93\xd8\xed\x6e\x95\x3e\x4f\x7a\x7a\xdd\xe7\x6f\xe7\xe3\xcb\x01\x4f\x78\xc2\xf1\x23\x3e\xe1\xb8\xfc\x3c\x5d\xde\xce\xaf\x2f\x3f\xf0\xe5\x37\x9e\x2f\xbf\x5e\x4f\xf8\xfc\x01\xcf\x6f\xdf\xbf\x9e\x2e\xcb\x72\x38\x6c\xfb\xdf\x6d\x81\x62\x5b\x04\x65\x5b\x8a\xca\xb6\x90\x72\x18\xcd\x4c\x6a\x8f\x0b\xec\x5f\xfd\xb3\x2d\xf9\x7f\x77\x03\x85\xfd\x78\xb4\x80\xdd\x57\x20\x96\x02\xa4\x52\x73\x6a\xf8\x40\x95\xbd\xa6\x32\xd8\xca\xaa\x0a\x1a\x92\x2c\x18\x17\xbb\x7a\x16\x31\x4f\x02\xd9\x7d\xa9\x10\x3d\x59\x31\x93\x27\xa2\x48\xd3\x51\x39\x28\x3b\x56\x02\x47\x3f\x66\xf3\x02\xa4\x9c\xf9\x51\x2f\xb5\x7c\x6f\xd8\x10\x5b\x94\xf6\x29\x5c\x45\x50\x8d\xd0\x6c\x9b\x1d\xae\x20\x00\x65\x0f\x0e\x16\x02\x87\x4b\x20\x07\x8c\xd2\x3a\xf7\x4c\x70\x23\x53\xd4\x6c\x33\xf3\x27\x23\x48\xa0\x46\x51\xd1\xab\x43\xf6\x41\x9b\x8f\x81\x95\xb1\xe6\xca\xd9\x7a\xef\xbc\x47\x5b\xce\x20\x61\x8a\xce\xe0\x60\x6a\x8d\xfd\xc8\xc3\xb1\xee\xd4\x6b\x1e\x62\xb5\xc3\xf7\x23\xab\x15\x80\xc4\x86\x34\xfa\x63\xdf\x76\x73\x1d\x8d\x95\x9e\x9b\x3b\x31\x10\xb6\x7f\xba\xb3\x30\x57\x73\x94\xd8\x5b\x9e\xb6\x29\x07\x6a\x34\x79\x79\xd5\x12\xe0\x68\x28\x0e\xac\x4e\x23\xd6\x99\x0e\xc7\xac\x01\x5a\x03\xf5\xa4\x0c\x34\x74\x81\x4f\x47\x84\x49\x21\x47\x92\x69\x0d\xa6\x43\xee\xab\xb7\xaf\x2b\x25\xf7\xae\xc9\xd6\xcc\x4c\xb1\x7a\xaa\x34\xb5\x74\x63\x2f\x6b\x5e\xe4\xa1\x6a\x3d\x6e\x64\x66\x4b\x1c\xd3\xe2\x5c\x7d\xe5\x46\x15\xb2\x67\xf6\xb1\x32\x35\xb6\xba\x43\xad\x5f\x24\x31\x98\x06\xa3\x90\x14\xe9\x2f\x82\x70\x2b\x54\x9d\x68\x28\xf5\x17\xf2\xab\xcc\x95\x98\xa0\x4c\x13\xbc\x11\xad\x65\x64\x6f\xbd\xd5\xea\x1d\xa5\x69\xdd\xbe\xaa\x4f\xa6\x58\x33\xad\x3a\x9d\x49\x22\xce\x95\x6f\xa3\x1e\x1d\x4a\x11\x99\x33\xb4\x11\x49\x89\x37\x94\x89\xcf\x85\x8b\xb0\x8d\x99\xd2\x89\xfb\xb0\xe7\x51\xb7\x2c\x21\xfe\x49\xfd\x8a\xe1\xd5\x10\x8c\x0e\x9f\x8b\x94\xa2\x37\x12\x4b\x9f\x1a\xbe\x16\x5c\x1d\x7c\xa0\x88\xf7\x30\xb6\xe9\xb3\xf4\x8e\xda\xed\xa1\xcc\x1f\x93\x87\x86\x1f\x1a\x7e\x68\xf8\xdf\x35\xfc\xff\x6e\xfe\x04\x00\x00\xff\xff\x48\xe3\x7f\x45\xd1\x0a\x00\x00") + +func fontsSerifcapFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSerifcapFlf, + "fonts/serifcap.flf", + ) +} + +func fontsSerifcapFlf() (*asset, error) { + bytes, err := fontsSerifcapFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/serifcap.flf", size: 2769, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsShadowFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x5a\x5f\x6f\x9b\xca\xd3\xbe\xf7\xa7\x78\x2e\xd0\xdb\x46\x4a\x82\x21\x89\x13\x4b\xd5\x91\xa9\x4d\x12\x54\x07\x7c\x30\x6e\x4f\x25\xa4\xad\xdb\x90\xc6\x3a\x8e\x1d\xf9\xcf\xa9\x2a\xf9\xc3\xbf\x5a\x96\x5d\x76\x61\x17\x93\xfe\x72\x81\x89\xcd\x3e\x33\x3b\x33\xcf\xcc\xec\x2e\x4f\xcb\x27\x77\x6e\xe1\x0a\x97\x70\x7a\xe8\xc2\xe9\xa2\x8b\xcb\x7e\xdf\xed\x4c\x9f\xe7\x8f\xeb\x5f\xf8\xfe\x1b\x77\xcb\x6c\xb5\xc2\xf0\x79\xfe\xfa\x9a\x2d\x97\xe8\xd9\xfd\x0b\x9c\x9d\xe1\xfb\x7c\x9b\x3d\x62\xbd\xc2\x74\x37\x5f\x3d\xce\x37\x8f\xf8\x3f\x4c\x5f\xd8\xb0\x4e\xb0\xfa\xb1\xdc\x3f\x66\x5b\x04\xd3\x08\xe3\xf9\x6e\xb1\x3a\x73\x3a\x4f\x8b\x9f\xcb\x6c\x87\x4d\xb6\xcc\xe6\xdb\x0c\xee\xb9\x43\x71\x1c\x17\xde\xfe\x27\x9c\x7e\xff\xb2\x33\xc9\x36\x2f\x8b\xed\x76\xb1\x5e\x61\xb1\xc5\x73\xb6\xc9\xbe\xff\xc6\xcf\xc5\x7f\xd9\x0a\xbb\x35\x5e\xd6\x8f\x8b\xa7\xdf\xd8\x3d\x2f\xb6\x78\x5a\xaf\x76\xa7\x98\x6f\xb1\x5c\xaf\x7e\xd2\xcf\xdd\x73\xd6\xc9\x1f\x58\x64\x9b\x77\x5b\xac\xe6\x2f\x19\xc5\x78\x5d\xce\x7f\x30\x35\xe7\xf8\xb1\x7e\x79\xc9\x56\x3b\x2c\x17\xab\xec\xbc\xd3\x79\x60\x4f\x3f\xd2\x39\x4e\xe6\xfb\x25\x3e\xee\x37\xbb\xf5\x0a\x1f\xb6\xeb\xe5\x7e\xb7\x58\xaf\x06\xd9\x7c\xb3\x7b\x5e\x2e\x56\xff\x9e\xaf\xb2\xdd\x5f\x70\x5c\xbb\xdf\xa3\x8a\x2c\xd8\xec\xb0\xca\x7e\xe1\x75\xbe\x99\xbf\x64\xbb\x6c\xd3\xd9\xee\x5f\x5f\xd7\x9b\x1d\x03\xbc\x0d\xee\xe8\x5c\xe7\xab\x47\x7a\xfb\x65\xb1\x3a\x07\x1e\xe6\xbf\x31\x5f\x6e\xd7\xf8\x9e\x61\xbb\x5c\xfc\x7c\xde\x2d\x7f\xe3\x85\x6b\xf1\xb4\xde\xe0\x7b\xb6\xdb\x65\x1b\xec\xb7\x59\x67\xfd\x94\xc3\x3f\xed\x97\xcb\xb3\x5f\x8b\xc7\xdd\xb3\xfd\x6f\xb6\x59\xd9\xdb\x97\xfd\xf6\x19\xf3\xe5\x2e\xdb\xac\xe6\xbb\xc5\x7f\xd9\xf6\x14\xdf\xf7\x3b\x3c\x66\x4f\xf3\xfd\x72\x87\xf5\x7e\xf7\xba\xdf\xd1\x99\x87\x51\x82\x1f\xcf\xf3\xd5\xcf\xec\xf1\xbc\xd3\x81\x65\x0d\x74\x17\x7a\x3d\x58\xe2\x4a\xd8\xf5\x84\x5e\x01\xb0\x9f\x91\xff\xfb\x19\x9f\x2d\xd0\xaf\x2d\x0b\xca\x27\x7f\x10\xf4\x51\x1c\xd8\xb7\x04\x38\x10\x1c\x0a\x3c\xf9\x1f\x80\x1c\xa8\x9c\x72\xb0\x82\x90\xcb\xb0\x40\x98\x0e\x29\x21\x48\xe9\xcd\x7b\x00\x36\x1f\x6e\xe5\x4f\x93\x13\xf1\x95\x65\x17\xaa\xd9\x85\x74\xbb\x9c\x03\x9f\x06\x08\x4e\xb8\xe6\x04\x29\x83\xb5\xde\xe3\x1b\xf0\xa1\x10\x45\xec\xd4\xb6\x24\xad\xf2\x71\x39\x0e\xc3\xb7\xa4\x2b\x57\xd9\xb2\x0b\xeb\xa1\xf6\x91\x92\x34\x37\x30\x95\x05\x3e\x3d\xdd\x27\xb1\x2d\x3e\xff\x94\xa9\x98\x82\xcf\xd7\x22\x00\x49\xd9\xe3\xa9\xad\x58\x6d\x20\xdd\x72\xe3\x15\xb6\x47\x69\x6b\xdd\x90\xca\xb5\x9c\x63\x05\x91\xdf\x11\xfa\xc7\x75\xb6\x70\x1c\x51\x89\x20\x70\x2b\xe9\x1c\xa5\xa0\x0d\xb8\x77\x0a\x33\x82\xc6\x93\x72\x97\x7b\xc9\xaa\xc8\x27\xec\x37\x6e\x4e\x6e\xd5\x03\xf7\xe5\x80\x4d\x41\xb8\x01\x27\x7c\x00\x07\x93\x27\xa8\x0c\xe1\xb2\xea\x83\x89\x4e\x13\x89\x01\x32\x19\x08\x41\x09\x5f\x8d\xfd\x7c\x5c\x2e\x1e\xec\xae\x9d\x28\x66\xc3\x82\x2d\xdc\x62\xef\x9b\xed\x44\x48\xf1\xb3\xe4\x0a\xe1\x8b\xaa\x33\x64\xda\xa8\x7e\x69\x96\x62\x78\x50\x48\xd6\x0d\x91\x82\x86\xd1\xab\x1a\x40\x95\x9f\x2b\x11\x5b\x84\x57\x31\x25\xc1\xb7\x94\x13\xa7\x46\x96\xd2\xdf\x75\xcf\x2b\x9a\x95\x58\x48\x2d\x59\x96\x3c\x09\x66\xdb\xea\x03\xcc\x9f\x54\xed\x6a\x9a\x2c\x5d\x6c\xd9\x20\xdf\x44\x8c\x97\xe6\xa2\x06\x3b\x2d\xd4\x4a\xb9\xfb\x0b\xbf\xa5\xc2\x4b\xcc\xd0\x85\x73\x04\x28\xb1\xf3\x28\x4b\xe5\x4c\xc6\x83\xac\xf0\x65\xa9\x41\xc9\x2c\x43\x90\x71\xeb\xe4\xc9\x05\x50\xee\x52\x1d\x6b\x74\xd8\x47\xa4\x58\x02\xc7\x22\x44\xd0\xc7\xd2\x24\x1f\xdd\x90\x52\x31\x31\x98\x88\xef\x8e\xce\x45\x0e\xe5\xba\x14\xcd\x0c\x72\x4b\x17\xc5\x52\x4e\x32\x22\x17\x11\x91\x85\x20\x7d\x2a\xe8\x3c\x18\x2d\xf1\x55\x51\x84\xd3\x46\x66\x51\x25\x58\x51\x78\xc7\x2b\xd2\x39\x77\xfa\x41\x0e\xf6\xe2\xe9\xba\xc7\x8e\x59\x95\x16\x9e\x62\xbe\xa9\x5d\xf3\x9d\x6e\xbe\xd2\x10\x4a\x12\x3e\xb8\x1c\x92\xd6\x86\xfc\x41\x86\x97\x52\x9c\xe2\x88\x22\x7b\x1b\xdc\xdd\x2c\x45\x31\x58\x93\x14\x7c\x28\xa4\xa0\x3e\x44\xca\xdc\xa9\x52\x62\xb8\x4b\x49\x2d\xe2\x79\xba\x28\x2b\xaa\x28\x08\xe5\x9d\xa6\x6e\x6b\x83\xb1\xd9\x6c\x29\x6b\x24\x8a\x36\x89\xfd\xc7\x1f\xa2\xff\x95\xfd\x44\x5a\x4d\xfe\x15\x04\x15\xa4\x8a\x53\x85\xd2\xa1\xc9\x80\x1c\x4a\x80\x58\xdc\x70\x74\x6c\xd5\xc6\x5c\xef\x62\x8c\x18\x24\x99\x4b\x5b\x54\x69\xcd\x31\xf5\x1d\x6a\xf0\xb3\x8c\x72\x30\x76\x72\xf9\xc3\xbc\x1a\x40\xd4\x03\x08\x0b\x58\x62\xee\x55\xe5\xf5\xbd\x09\x8f\x0d\x06\x6b\xa7\x6c\x94\x25\x1a\x6c\xe9\x43\xd3\xe8\xe9\xee\x78\x5b\xc6\x79\x2d\x8a\x64\x7a\xb0\x0c\xad\x6b\x39\xda\x12\x45\x48\xae\xd8\xa7\x9a\x7c\x28\xe5\xda\x7a\x05\x39\xd7\x97\x76\x21\xa4\xb0\xf0\x7b\xab\x2c\x1f\x15\x27\x94\xbc\x69\xad\x93\x2c\xa0\x68\xea\xf3\x16\xc3\x20\x40\x72\xb3\xa8\x19\x3c\x85\xe8\x7b\x05\x93\x26\xec\xee\x50\x16\x67\x83\x75\x0e\x22\x15\x1e\xea\xd5\xe2\xc4\xd2\xae\xc0\x4a\x25\x44\x23\x24\x6a\x45\xe5\xa6\x2a\x5f\xa9\x13\x10\xb9\x4b\x57\x1e\x8e\x88\x96\x6c\x40\x27\xf4\xad\xe2\x72\xb5\x2c\x54\x4a\x43\xdd\x8c\xda\x88\xd1\x55\x94\xaa\x47\xdb\xb4\x9c\x8d\x52\xac\xf3\x6a\xa1\x78\x83\x7f\x51\x2c\xa6\xe4\x48\xb3\xa0\x34\x12\x02\xb8\x16\xca\x6a\xe0\x8b\xc5\x2c\x2b\x09\xf5\x62\x2d\xc5\x23\xff\x3f\xd5\xb5\x0d\xd5\xde\x45\xa9\x02\x26\x86\x14\xeb\xca\x54\xc9\xe4\x22\x89\x13\xbb\x9e\x3f\xd5\x10\x90\x12\xbf\x54\x07\x24\x80\x1a\x46\x4d\x63\x29\xf7\x7f\xe3\x91\xa9\xcd\xf8\xc7\x27\xa9\x76\x93\xc2\x40\xf9\xe2\x57\x59\x0c\xe8\xfa\x2e\xb1\x1a\x65\xd9\xfd\x03\x55\x05\xf2\x37\x10\x6b\xf7\x3a\x4b\x4a\xae\x88\x82\xa0\x0e\xfd\x86\xbf\x14\x78\xb6\xae\xca\xf3\x3c\x0a\xb7\x57\xb7\x50\x6a\x5b\x29\xe4\x04\xa9\xa0\xfe\x1b\xdb\x7c\x72\x22\xb2\x86\xa6\x05\xd2\x2f\x0c\xc5\x90\xf6\x6b\x6e\x59\x4a\xbb\x4c\xad\x55\xec\xc8\x8a\xf5\x98\x62\x9a\x68\x17\x65\x40\x64\xc1\x03\xdf\xed\x39\x14\xbc\x2b\xe8\x3a\xe8\x38\xbd\x2e\x10\x46\x67\x1f\x63\xdf\xfb\x84\xe9\xc4\x1b\xfa\x94\xde\x2c\x77\xea\xae\x74\x88\x03\x04\xe1\x67\x3f\x4e\xfc\x11\xfc\x7f\x86\x63\xef\xc1\x4b\x82\x28\xc4\x83\x17\x7f\x3a\x96\xd2\x9d\x9e\x0b\x0c\xfd\x30\xc1\x34\xb8\x0b\xe5\x28\xb1\x8a\x2d\xaf\xb2\x3c\x02\x28\x22\xa0\xd8\xf2\x72\x7a\x17\xc0\x24\x9a\x85\x23\x31\x1a\xd6\x29\x29\xe2\x01\x38\x90\x72\x69\x58\xb6\xc4\xe4\xb4\xda\xea\x17\x9a\x5c\x02\xc3\x59\x1c\xfb\xe1\xf0\x6b\x81\x97\x42\xe2\x8f\xf0\x0c\x8f\x3a\xaa\x53\x1e\x74\xd5\x4d\x32\xa7\x77\x05\x7c\xf5\x43\x81\xc2\xf3\x42\xd9\xe5\xca\xfd\x6e\xbd\xb7\x75\x7a\x3d\xe0\x63\x1c\x7d\xf2\x43\x7c\xf4\xe2\xba\xe1\x54\xda\x39\xbd\x6b\x60\xea\x0f\x73\xab\x97\x96\xe0\xb1\xc5\xfb\xb1\x14\x29\x5f\xb5\xa7\x79\x86\x1b\x74\xf0\x9e\x70\x36\x3a\xbd\x1b\x60\x14\x78\x7e\xec\x4f\x83\xa9\x12\x6a\x39\x1a\x0c\x77\xb2\xd6\x7d\x60\x18\x4d\xbe\xc6\xc1\xdd\xbd\xe4\x50\xfa\xb3\x20\x2c\xe8\xbc\x79\xb0\x23\x5f\xe2\xcb\x8b\x7c\x72\xe0\x29\x34\xe5\x2b\x85\x1c\xfa\xba\x0b\xdc\xfa\x0f\x41\x18\x84\x3e\xa2\x78\x14\x84\xde\x18\x41\x38\x0a\x86\x5e\x12\xc5\x32\xe9\x4a\x12\x34\xef\xd2\x39\xd7\x0e\x30\xf6\x6f\x93\xb3\x49\x14\x84\x49\x10\xde\x61\x14\xcd\x3e\x8e\x7d\x78\xe1\xdd\xd8\xc7\xdf\xb3\x28\x91\xe3\x38\xdf\x9c\xe0\xa9\x14\x62\x67\x45\xda\x5b\xa9\xa6\x6d\xe7\xda\x45\xbe\xed\x2c\x5c\x22\x92\x32\x11\x8b\xe6\xfc\x4f\x38\xb6\xa2\x26\x43\xb9\x00\xa6\xd1\x6d\x82\xfb\xaf\x93\x7b\x3f\xd4\x37\xbc\xc7\xe6\x7a\x09\xc4\xfe\x5d\x30\x4d\xfc\xd8\x1f\x99\x5d\x23\xe6\x93\xff\x02\x5b\xb8\x06\xe4\x40\x52\x83\x6b\xae\x80\x07\x6f\x18\x47\xa1\x49\x0d\xdd\x5d\xa9\x5a\x0f\x18\xf9\x77\xb1\xef\x73\xb5\x2c\x29\x17\x72\x97\x8a\x85\x91\xa5\xb6\x15\xce\xf5\x35\x30\x19\xcf\xa6\x67\x0f\x41\x38\x9b\x2a\x59\x04\x86\xbd\x5f\xdd\x52\xdf\xb9\xbe\x01\xa6\xb3\x89\x1f\x4f\x87\x71\x30\x49\x90\x7c\x89\xf2\xd1\x27\xda\xe2\x59\x29\x50\xce\x75\xbf\x32\xfa\x3e\xf6\xfd\x9c\xe5\xc5\xe6\x97\x68\x74\x6c\xed\xf8\x9b\x2e\xe0\x0d\x67\x89\x0f\x6f\x48\xb3\x61\xa7\xa8\x8c\x96\x61\x9f\xdd\xb9\x71\x80\x87\x60\x18\x47\x6a\x70\x99\x96\xc5\xe7\x82\x13\xa2\xe3\x73\x6e\x5c\x60\x12\x8c\x87\x71\xf4\xa5\xb4\xbc\x18\x41\x6d\x5f\xee\x55\x1e\x44\xb0\x12\xb5\x69\x67\x48\x17\x54\x99\xd1\x68\xec\x63\x14\x25\x3c\x43\x29\xfb\x93\x8a\xee\x34\xd1\xfa\xa3\x60\x3c\xf6\x3a\x65\x20\x97\x99\x4d\x6c\x78\xd2\x67\xaf\x54\xc3\x46\xa1\x5f\x5b\x43\x96\x3e\x19\x74\x4a\x9d\x7a\x34\x2a\xa7\xc3\xd9\xd8\x9c\x31\x8a\x1c\xce\xbd\x52\x89\x5d\x25\xcc\x6e\xae\x81\x3c\xad\xb5\xcc\x16\xa9\xb2\x53\x5a\x6e\x85\xf2\x78\xb0\x6b\xb5\xdd\xb9\xb9\x01\x3e\xcf\xc6\x77\x5e\x8c\xdb\xd8\x63\xc9\x3c\x0a\x29\xb4\x17\x27\x7e\x9c\x4f\x9b\xad\xf6\x79\x1f\x4d\x0b\x7a\xee\x1a\x56\xd7\x0e\xb4\xa1\x22\x65\xb8\xdb\x40\xb9\xed\x2a\xfd\xe5\xc2\xfa\x7a\x61\xf7\xde\xf8\x56\x91\x24\x04\x09\x2e\xe4\x72\xca\x5d\x07\x2a\xa6\x56\x4f\x99\x90\x7e\xb7\x2e\x24\x67\x06\x9f\xd3\x94\x51\x44\x99\x15\xc9\x9b\x62\x31\x2d\xea\x1c\x75\x5e\xe6\x89\x31\xa1\x72\x3b\xf2\xf7\xcc\x9f\x2a\x39\x5c\xec\x3e\x8b\x36\xc3\xb6\x0c\x8b\x6f\xa7\xef\x02\x63\x2f\x09\x42\x0c\xbd\x49\x90\x78\x63\x8c\xfd\x24\xf1\x63\x78\xf8\x12\x24\xf7\xb8\x8b\xbd\xcf\x7e\xb1\xad\xce\xf3\x5b\x6a\x55\x56\x6a\xb9\x79\xaa\x85\xa1\x7f\xd1\x8c\x9c\xa7\x02\x66\xdc\xb7\x22\x5f\x36\x23\x0f\x83\x78\x38\x7b\xb8\x1d\xfb\xff\xd0\x61\x76\x2a\x4e\xe2\x5a\xc2\x5f\x35\xc3\x27\xc1\x78\x44\x15\xb7\xcb\xf3\x80\xb6\xc8\xbd\x66\x64\xa9\x33\xf9\x5f\x56\x03\x4e\xff\xba\x59\x4e\x4c\xa9\xed\x7d\x8c\x72\xcf\xd2\xfe\xe4\xc4\xfa\xa3\xd3\x05\xa7\x7f\x63\x12\xc4\x90\x2d\x25\xdf\xd8\x10\x9b\xf5\xf9\x9a\xbd\xdc\x97\x66\xf4\x32\x10\xac\x6f\x90\x31\x2c\xbc\x2d\xb2\x6c\xfb\x73\x8b\x9c\x21\x83\x8e\xdb\xed\x1a\xb0\x7d\x43\xf4\x4b\x47\x10\x8d\xa5\xd6\xed\x3a\xcd\xc8\xb5\xe8\x6f\x8f\x6c\x62\xac\xdf\x14\xfd\x2a\x3c\x31\x1e\x80\xba\x5d\x13\x6d\xfd\x5a\x8c\x4a\xdd\x73\x6b\xe5\x4d\xd4\x0d\x14\x83\xa7\x62\x7d\xc3\x10\xa4\x44\xa9\x2c\xec\xdd\xae\x89\xab\x81\x6a\x66\xbe\x17\x54\x39\xa8\xa9\xe3\x99\x18\x1a\xd4\x8d\xcb\x4d\x7b\x1c\xd4\x44\xc7\xa0\xc1\xa4\x0c\x56\x5a\xd8\xe5\xdf\x11\xb5\x22\xe4\xe8\x26\x0e\xfa\xc9\x3d\x0b\x76\xe9\x84\x42\x3a\x93\xcb\xd7\x28\xbc\x8c\xd6\xce\x2b\x18\xb4\x89\x7a\xa1\x26\x13\x16\xe7\x42\x45\x2f\x26\x36\xfb\xd2\x4a\xc5\x71\x1d\x13\xe7\x22\x53\xc5\x69\xb9\xa3\xe1\x3a\x26\xce\x45\xa6\x8a\xd3\x1a\xd9\xc4\xb9\xa8\xb1\xe2\xb4\x86\x37\x71\x2e\x32\x55\x9c\xd6\xc8\x26\xbe\x45\x4d\xa1\xd7\x1a\x9d\xae\x8a\x66\xe3\x24\x98\x8c\x69\xc7\xa9\xac\xcc\xcb\x13\x93\x41\x07\xa7\xc0\x3b\xb6\x95\x20\xbd\x6c\x93\x23\x98\xf8\x56\xe8\x37\x4d\xe2\xe8\x93\xcf\x54\xb2\xb9\x4a\xfc\x90\x52\x2c\xdd\x88\xad\x53\xce\xc4\xba\x99\x29\xb7\xb7\xdc\x06\x73\x1d\x13\xe3\x66\xa6\xdc\xde\x1a\xd9\x44\xb8\x59\x63\x6e\x6f\x0b\xef\x9a\xa8\x37\x6b\xca\xed\xad\xd1\x4d\xf4\xfb\x5a\x31\x0b\x8f\x62\xfd\xb1\x60\x7d\xa7\xc8\x75\x4d\xf4\x4b\xee\xa3\x38\x54\xea\xbd\x78\x27\xc3\x12\x0b\x51\xdd\x49\xb1\xeb\x0a\xca\x4d\x1f\xbc\xb1\x00\x9c\xde\x7b\xf1\x04\xd3\x37\xee\x28\xba\xee\xa5\x16\xcd\xd8\x43\xb7\xdc\x3d\x75\xdd\xab\x26\x5c\x29\xce\x88\xf5\x36\xdc\x5e\x13\xae\x31\x9b\xb5\x04\xbf\x6e\x02\xd7\xe5\xb2\x96\xb8\x37\x4d\xb8\xa6\x4c\xd6\x12\xbb\xdf\x84\xad\xf6\xcb\xef\xa5\x97\xa3\xde\xb5\x01\xbf\xe8\xea\xc1\x7d\xb9\xd7\xe5\xda\xf2\x6d\x94\x1c\x53\x3a\xd4\xd4\x6c\xe8\x32\x70\x47\x0b\x5e\x6b\x8e\x25\x21\xe6\x23\x59\xde\x17\x5f\xb8\x5a\x50\x5d\x57\x3c\x68\x77\x08\xeb\x5e\xe8\x09\xa7\x6b\x87\x5b\x43\xea\x59\xa7\xeb\x83\xd5\x92\x7c\x0c\x57\xcf\xba\xa6\x06\x58\x2a\x99\xe2\x5d\xb7\x54\xd7\xad\x5d\xe8\x99\x57\x6f\x7f\x07\xcd\xef\x36\xba\x17\x7a\x96\xa9\x7d\x2f\xe1\x2f\xaa\x6a\xcf\x25\xdc\x0b\x3d\xa3\x0c\xbd\x6e\xfd\x0d\x89\x83\xbc\x1b\xe5\x5e\xe8\x39\xd4\xd8\xe4\xb6\x7c\x0f\xc6\xbd\xd4\x53\xa8\x68\x71\xcb\x83\x45\xda\x61\x94\x07\x18\xdf\xa4\xd7\xbc\x6a\xaf\xe3\xb8\x97\x7a\xe6\xe8\x7a\xdb\x7c\xd2\xef\xda\x9d\x65\xbb\x97\x7a\xf2\xb4\x68\x6f\x1b\xcf\xc5\xdc\x4b\x3d\x83\x5a\x34\xb7\x47\x70\xf5\x34\x6a\xdb\xda\x1e\x01\xd7\x73\xa9\x45\x63\x7b\x04\x57\xcf\xa3\x96\x6d\xed\x11\xec\x6b\x60\x14\x7c\x0e\xa6\x95\x86\x96\x87\xe7\x49\x7d\x81\x4b\x4e\xea\x21\xab\x27\x57\xb5\xb1\x55\x32\x33\x6c\xa1\xa0\x38\x96\xa8\x35\xb7\x0c\x5d\x4f\xb6\x37\xf6\xb6\xf5\x5a\x75\xa5\x27\xda\x1b\x3b\x5b\x0d\xae\x9e\x6c\x7f\xd2\xd7\x6a\xc0\xf5\x8c\xfb\x83\xae\x56\x83\xad\x67\x5d\xb5\xa7\x3d\x66\x90\xea\xbb\x0b\xee\x95\x9e\x75\xf5\x8e\xb6\xe5\xcb\x2d\xee\x95\x9e\x69\x5f\xff\xc0\x08\x55\x65\xff\x3f\x00\x00\xff\xff\xf9\x5f\xcd\xb2\x32\x34\x00\x00") + +func fontsShadowFlfBytes() ([]byte, error) { + return bindataRead( + _fontsShadowFlf, + "fonts/shadow.flf", + ) +} + +func fontsShadowFlf() (*asset, error) { + bytes, err := fontsShadowFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/shadow.flf", size: 13362, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsShortFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x53\xc1\x8a\xdb\x40\x0c\xbd\xeb\x2b\x74\x08\xac\x0d\xc9\x0c\xdd\xf6\x50\x68\x58\x04\x7b\x6a\xc9\x6d\x2f\x4b\x33\x30\x71\x12\x27\xcd\x92\xd8\x69\x12\xb7\x2c\x08\x7f\x7b\xd1\x8c\x67\xac\xcd\xad\x90\xc0\xbc\x91\xe6\xe9\x49\x4f\xde\x1d\x77\x8f\xd5\x04\x3f\xe3\x23\x7e\xc5\xd9\x27\xfc\x02\x2f\xbf\xda\xcb\x0d\xab\x66\x8b\xd7\xbf\x75\x7d\xc3\xf5\x3b\xbe\x74\xeb\xd9\xcf\xfa\xd2\x62\xb1\x6e\xb7\xed\x89\xba\xfd\xf1\xdd\x74\x9b\xab\x39\x34\xdb\x43\xd5\x54\xa6\xde\x76\x25\x3c\xb7\xa7\xf3\xb1\xbe\xd5\xdb\xf0\xf8\xdc\x5e\xe4\x78\x6b\x71\x77\xd8\x1f\x23\xcf\x8f\xae\x6a\xf0\xb9\xba\x60\xf1\xb6\xa1\xb7\x6e\xdf\xd5\xb7\xda\xfc\xee\x0e\x27\xd3\x6d\x4e\xa6\xbe\x96\xf0\xfd\x74\xbe\xb4\x7f\x84\x62\x5f\x1d\x1a\x5d\x1b\x60\x42\xf1\x47\x80\x4c\x80\x86\x00\x91\x08\x1e\x1e\xc2\x21\x02\xe6\xf8\x0f\xa0\xe0\x15\x81\xe7\x52\xa0\xe0\xd6\x12\xd8\x36\x05\x4b\x82\xe2\x75\x00\x53\x02\x61\x20\x02\x4b\xe0\xe2\xc9\x05\x10\x4e\x2c\x0f\xd9\x25\x1e\xcf\x5e\x34\x60\xc2\x38\x10\x10\x78\xaf\xb4\x20\x81\x89\xd7\x28\xef\xd3\xb5\x75\x04\xce\x26\xf1\xc2\x12\xf9\x22\x2e\x09\xac\x4f\xc1\x92\xc0\x94\xe9\x99\x64\xf6\xdc\xa7\x4c\x39\xf9\x14\x44\x61\x2f\x7c\xee\xb4\xd7\x05\x8b\xbe\xfc\x10\x0c\x18\xed\x28\xdf\xa8\x69\x86\x43\x52\x37\x0e\xc3\x13\xcc\xee\xc7\x22\x34\x9c\x9b\xf5\xa2\xc0\x09\x73\xdf\x07\x45\x4c\x60\x67\x9c\xe5\x96\xf1\x1f\x79\x57\x04\x6e\x9a\x2c\x73\x04\x9c\x2a\x2e\x7b\x82\xa5\x57\x20\x17\xb0\x3d\x12\x38\x3f\x12\xca\x91\x71\xc4\xe1\x87\xc3\x76\xf8\xb4\x03\xc2\x1c\x9d\xa3\x48\xc6\x3e\xd7\xb5\x81\x61\xa0\x88\x57\x18\xae\xdc\x78\xf5\xc1\x2d\xd6\x1d\x87\xc8\xab\x8e\xa4\x32\xc5\x4a\x59\x13\x2d\x1b\x97\x25\x48\x66\xd5\x87\x4c\x9b\xad\x8e\x07\x45\x8e\x93\x8a\x30\x75\x1b\x0b\x46\x10\x0c\x1a\x29\x83\xdb\xb9\xad\x5e\xf5\xe8\x24\xc7\x65\x25\x6a\x2e\x03\xd9\x60\x1e\xe6\xd5\x1d\x1c\x87\x74\x5d\xb0\x9e\x5d\xde\x37\x2f\x1b\x95\x00\xab\xb4\xb8\x07\x36\x2f\xf4\x72\x45\xc0\x13\x55\xa7\x88\x2a\xa2\xc8\xfc\xa9\x9a\xd1\x3d\x93\x1d\x1c\x8a\xce\x93\x82\x9c\x33\x95\x22\xcc\x79\x86\x53\x4d\x15\x8a\x94\x0a\x0c\xae\xa9\x7e\x38\x45\x56\xaa\x1f\x9f\xb7\x64\xa6\x26\x28\x69\x0b\x4d\x9d\x97\x01\x43\x68\x91\x45\x08\x7c\x9a\xdf\x65\xda\xf0\xf1\xe0\x9d\x3f\xf3\xb8\x87\xba\x25\x31\x07\x9f\x86\xb6\x9b\x4e\x99\x63\x8c\x1a\x6f\x00\xa5\x02\x0b\xfe\xbf\x34\x19\xc6\xb7\x14\xf9\x17\x00\x00\xff\xff\x6e\x3d\x1c\xff\xfd\x05\x00\x00") + +func fontsShortFlfBytes() ([]byte, error) { + return bindataRead( + _fontsShortFlf, + "fonts/short.flf", + ) +} + +func fontsShortFlf() (*asset, error) { + bytes, err := fontsShortFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/short.flf", size: 1533, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSlantFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x5b\x6d\x4f\xdb\xc8\x16\xfe\x9e\x5f\xf1\x7c\x40\xba\x20\x51\x06\x1b\x08\x44\x62\x2b\xd2\xc4\x05\xab\x21\xce\x3a\x49\xbb\x95\x22\x4d\xd3\x62\x4a\xb4\x21\x41\x49\xd8\x55\x25\xff\xf8\xab\x79\x9f\xb1\xc7\x4e\xd2\xf6\xde\xee\xaa\x36\xac\xe7\x9c\x99\x73\xce\x73\x5e\x67\x1f\xe7\x8f\xe1\xf4\x00\x4d\x5c\x20\x68\x22\xb8\x40\x70\x8a\x53\x04\x57\x67\x41\xab\x31\x9c\x4f\x17\x1b\x7c\xfd\x81\xdb\x79\xb6\x58\xa0\xf3\x34\x7d\x79\xc9\xe6\x73\x9c\x91\xd6\x19\xde\xbc\xc1\xd7\xe9\x3a\x7b\xc0\x72\x81\xe1\x66\xba\x78\x98\xae\x1e\x1a\xf1\xe2\xdb\xfc\xf5\x21\x5b\x23\x1e\x26\xe8\x4d\x37\xb3\xc5\x9b\xa0\xf1\x38\xfb\x3e\xcf\x36\x58\x65\xf3\x6c\xba\xce\x10\x9e\x04\x6c\x71\x10\xa2\xfd\xfa\x1d\x41\xab\x75\xde\x18\x64\xab\xe7\xd9\x7a\x3d\x5b\x2e\x30\x5b\xe3\x29\x5b\x65\x5f\x7f\xe0\xfb\xec\x9f\x6c\x81\xcd\x12\xcf\xcb\x87\xd9\xe3\x0f\x6c\x9e\x66\x6b\x3c\x2e\x17\x9b\x63\x4c\xd7\x98\x2f\x17\xdf\xd9\x73\xf3\x94\x35\xf8\x07\xb3\x6c\xf5\x9f\x35\x16\xd3\xe7\x8c\xd1\x78\x99\x4f\xbf\x89\xbd\x4d\xf1\x6d\xf9\xfc\x9c\x2d\x36\x98\xcf\x16\xd9\x49\xa3\x71\x2f\xbe\x7e\x60\x07\x1b\x4c\x5f\xe7\x78\xf7\xba\xda\x2c\x17\xb8\x5e\x2f\xe7\xaf\x9b\xd9\x72\x71\x93\x4d\x57\x9b\xa7\xf9\x6c\xf1\xf7\xc9\x22\xdb\xbc\x45\x10\x92\x56\x93\x6d\x64\x26\x4e\x87\x45\xf6\x2f\x5e\xa6\xab\xe9\x73\xb6\xc9\x56\x8d\xf5\xeb\xcb\xcb\x72\xb5\x11\x04\xdf\xc7\xb7\xec\xac\xd3\xc5\x03\x7b\xfd\x34\x5b\x9c\x00\xf7\xd3\x1f\x98\xce\xd7\x4b\x7c\xcd\xb0\x9e\xcf\xbe\x3f\x6d\xe6\x3f\xf0\xac\x76\xf1\xb8\x5c\xe1\x6b\xb6\xd9\x64\x2b\xbc\xae\xb3\xc6\xf2\x91\x93\x7f\x7c\x9d\xcf\xdf\xfc\x3b\x7b\xd8\x3c\x91\xbf\xb3\xd5\x82\xac\x9f\x5f\xd7\x4f\x98\xce\x37\xd9\x6a\x31\xdd\xcc\xfe\xc9\xd6\xc7\xf8\xfa\xba\xc1\x43\xf6\x38\x7d\x9d\x6f\xb0\x7c\xdd\xbc\xbc\x6e\xd8\xc9\xfb\xc9\x08\xdf\x9e\xa6\x8b\xef\xd9\xc3\x49\xa3\x01\xf6\xe7\xe0\xe0\xa6\x21\x9e\xe0\x2f\x07\x07\xe0\x2f\xec\xc9\x5e\xf8\x13\x37\x0d\xf1\xc4\x8d\xf8\x9a\x52\xfe\x24\x20\xec\x49\x40\xd8\xa7\x84\x12\xf6\xe5\x21\x3d\x12\x4b\xf5\x02\x0a\xca\x7e\x8f\x1c\x47\x37\x8d\x9c\xe4\xfc\x6b\x41\x5f\x52\xb7\x69\x83\x52\xf6\x2f\xfb\x81\x52\x02\x42\x40\x28\xa7\x0e\x50\xfe\xab\x9b\x86\x79\x97\x7c\x39\x6b\xc3\xb4\x40\x8e\xbf\x50\xbd\x59\x4e\x02\x87\x14\x38\xc2\x4d\x83\xf0\xff\xc4\x5e\x24\x0d\xf1\xb5\x5e\x78\x48\x8f\x28\xe1\x2b\xd8\x87\xe2\x53\xfe\x42\xa1\x56\xf1\x13\x5b\xbc\x25\x09\x4a\xe5\x96\x0e\x41\x21\xbe\x60\xcc\x31\x21\x39\x63\xcb\x69\x5d\xe3\xa6\x31\xa1\x94\x52\x32\x21\x25\x12\x5c\x08\x87\x4c\x68\xd0\x32\x13\x22\x13\x5f\x96\x4e\x48\xb5\x3a\x04\x33\x22\xb6\x08\x29\x9c\x9c\xe6\xce\x32\x49\x26\x47\x2e\x5e\xa4\x84\x94\x3e\xd5\x69\x1d\xc1\x28\x31\x53\x4a\x72\xc6\x96\x53\x14\x2a\xa1\x34\x87\xd8\xaa\xad\x0a\x77\x19\xa4\x6a\xb9\x66\xa9\xd4\x24\xdf\xb6\xe0\x52\x58\xe6\xfc\x25\x8c\x88\x9b\x50\x89\xaa\xfc\x82\xff\x61\x54\xb9\x48\xb9\x1d\x7b\x36\x53\xa6\x4a\x8f\xc4\x8f\xfa\x43\x29\x52\x23\x54\x57\xf7\x80\x25\x18\xbf\xee\x85\x74\x85\xc2\xa5\x32\xb8\x7c\x85\xe2\x89\xd6\xbb\xbd\x5a\x2f\x66\xcf\x6b\xb8\xe8\x82\xa5\x0c\x1b\x5d\xc2\xd2\xd8\x4b\x2e\x79\x09\xe9\x4a\x73\x23\x90\xf2\x20\x45\x31\x48\x61\x89\x75\x4a\xf5\x94\x9b\x24\xf8\xf7\xd6\x52\xcf\x26\xa5\x8c\x04\x42\xc5\x06\x95\x4e\xb5\x52\x8b\x5a\x35\xfe\x43\xf1\xe6\x7b\xd4\x1f\xb3\x03\x68\x4d\xea\x13\xcb\x2d\x38\xf0\x2e\x1c\x81\x53\x21\x1a\x61\xd8\x2e\x67\x63\x2a\xfb\xc8\x99\x2a\x40\x53\x0e\x4b\xce\x0d\xf9\x8e\x5a\x2d\x9b\x84\xd4\xd3\x84\xd2\xe3\x5a\x69\xcb\xdf\x48\xee\xdc\x5a\x85\x73\xb1\x5d\xcf\xb6\x4f\x85\x0f\xe2\xf0\x14\xee\x85\x8a\x4d\x08\x0f\x71\xd3\x98\x70\xb9\x61\x42\x27\xae\x7b\x51\x80\x17\xa2\x26\x52\x5d\x96\x4d\x95\x30\xc6\x84\x62\xe8\xa9\xc3\x0a\xa1\x5a\xb4\xa5\x44\x88\x32\x5b\x02\xe3\x09\x7c\x71\x44\xd9\x8d\x16\xa3\x85\x2d\x4a\xf1\x45\x9e\x44\x6b\x82\xcb\x55\x8a\x73\xa2\x8d\x48\x5b\x20\xa4\xfd\x41\xf8\x3f\x02\x22\x3c\x21\xa7\xcc\x95\xca\x16\xe4\x34\xf7\x9a\x2f\xb4\xf5\x72\x4b\x30\xa6\x60\xed\x40\x9b\xae\xd7\x41\x58\x96\x2b\x4d\x97\x48\x69\x13\x01\x05\x58\xe6\x54\x26\x51\xdc\xc5\x44\x19\xb1\x86\xe3\xd6\x5d\x54\xe1\x10\x9a\xa5\xb5\x93\x3a\x1c\x56\x12\xe2\x51\x12\xda\x15\xb9\x6e\xb3\x0a\xd0\x1e\xb9\x08\x8b\x52\x67\xda\x26\x17\x3b\x41\xb1\x92\x14\xaa\x21\xce\x41\xaf\xf6\x52\xf4\x51\xce\xa1\x94\x8d\x50\x13\x1a\x45\x10\x50\xc1\xb5\xb4\x0d\x4f\x10\x91\x7b\x10\x5c\xc9\x3e\x07\x31\xe7\xd0\xc1\xfd\xf8\x5a\xab\x26\x67\xe1\x57\x1c\x82\xc7\x76\x2f\x09\x3b\xa4\xdb\xb9\x41\x31\x52\x96\x45\xa8\x0f\xcf\x7c\x86\x12\x62\x4e\x6d\x47\x69\x7b\xcb\xb2\x1c\x35\x39\x3b\x65\xcc\x8d\x46\x18\x61\xa2\xcf\x62\x48\xe5\x35\xee\xfe\xa7\xc3\x6a\x15\x5e\xac\x58\xa9\xa2\xe5\x2f\x87\xf5\x09\x9d\xfc\x04\xff\x63\x68\xfe\x7e\x75\x96\xc3\x1d\xf3\x6b\xc2\xcd\x6e\x8b\xd8\xd4\x38\x70\x13\x9d\x61\x60\xee\x62\xd3\x13\xee\x4d\xbc\x37\x1e\x66\x77\x73\xa6\x0a\x10\xdc\x66\x39\x81\x5c\x98\x02\xf8\x9b\x5c\x9e\x7b\xe1\x44\x2d\x40\xe5\x22\xe5\xb4\x48\x38\x54\x2c\x42\x24\x2f\xbb\x2b\x93\xde\xcb\xd4\x87\x2f\x10\x6f\x50\xb6\x08\x0d\xab\x82\x1a\x64\x68\x63\x4b\x27\x98\xc8\xd8\x8d\x2d\x79\x43\x4d\xa2\xa1\x11\x48\xdc\x30\x67\xc0\xa7\x62\xa2\x41\xae\x57\x69\x3a\x43\xa7\xd2\xdf\xb2\xd8\x0b\x19\x7d\xc5\x32\x19\x8d\x61\xe2\xbb\x97\x9b\xcc\x03\xb5\xc3\xf0\x7a\x3c\x53\x0f\x10\x56\xcb\x20\x27\x79\x2e\x13\x81\xda\xca\xce\xcd\xd6\xcb\x2f\xc5\xfc\xfd\xc6\x2d\x82\xf0\xb1\xa6\x08\xb2\xd2\x14\x50\xe5\xe4\xbf\x14\x91\x79\x5c\xe1\x19\xa0\x0f\x5b\x95\xa4\x11\x7a\xe2\x26\xd1\x55\xf9\x91\x84\x26\x57\xaf\x42\x04\xf1\x16\x44\x42\xea\x32\xd5\xb5\xe2\x52\x11\x50\xc7\x15\xf1\x41\x33\x96\x41\x8d\x6d\x98\x48\x70\x4f\x9c\xcd\x96\x03\x9a\x13\xa1\x4d\x7c\xae\xf6\x00\x96\xb6\xb4\x8c\x8d\x90\xed\xf0\x2a\xb3\x59\xcb\x15\xed\x26\x67\x93\x23\x12\x9f\x9c\xa5\xef\x94\xb5\xda\xf6\x6c\xdd\x5a\x63\x96\xd9\x96\x6d\x4c\xbb\x14\xcd\xbd\x1b\xd6\xe5\x8e\xcc\x4a\x64\x20\xf6\xba\x09\x54\x36\x49\xea\x37\x5c\x14\xb2\x1d\x6f\xbe\xb8\xa2\x72\xc5\xe5\x8a\xcc\x03\x8c\xda\xe0\x55\x25\x73\x1b\x54\xba\xb8\xd2\xe6\xa9\xbd\xbd\xc7\xb6\xd5\xe1\xb6\x05\xbd\x93\x52\xd0\xdd\x0f\xcf\xda\x2b\xda\x76\xe6\x9c\xb9\x58\x1f\x6e\x89\x74\x75\x8b\x0f\xa9\x6a\x1a\x55\x57\xc5\xea\x80\x0a\x53\x62\xc3\x12\xc9\xc4\xab\x73\x71\x4e\x53\x90\x79\x32\x0a\xbf\xdf\x92\x5e\xd3\x8a\x8c\x2a\x2a\xca\x88\x58\xe9\x7a\xcc\x4a\x7b\xb1\xbd\xde\x90\x90\x71\xf4\xa6\x9c\x20\x1b\x51\xd9\xf1\x94\x8b\x8a\xbe\xe5\x1d\x8c\x1a\x78\xd8\x82\xf6\x26\x17\xdb\xfd\x89\x8a\x19\xa2\x8f\xa4\x96\x49\x18\x17\x62\x8f\xdb\x24\x53\xdd\x9c\x6b\xb6\x49\xd8\x4d\x32\x96\xba\x95\x97\x15\x7b\x63\xe5\x26\x9b\xdb\x24\xab\xec\xad\xd1\xb7\xf4\x6d\x45\x6f\x8d\x4c\x08\x3f\x82\x6a\x05\xaa\x0e\x2c\x4c\x3c\x2d\x39\x74\xdb\x2d\x6a\xcf\x48\x45\xfe\x22\x20\xb3\xa5\x42\xa0\x76\xaf\x80\x0a\x12\xb2\x87\xb2\x6b\x9d\xe2\x90\x80\x22\xb1\x47\x6e\x58\xb3\x8b\x2f\x3b\x47\xc3\xff\xf3\x41\x2a\x63\xb2\x71\x78\x96\xc7\x2b\x16\xa2\x0c\x6d\xb2\x65\x56\x08\xbb\x9c\x50\xd0\x3c\x05\xfa\xc9\x9b\x77\x69\xd4\xfe\x80\xe1\xa0\xdd\x89\x04\xf1\xfd\xbb\xf5\x41\x33\x00\xe2\xfe\xc7\x28\x1d\x45\x5d\x44\x7f\x75\x7a\xed\xfb\xf6\x28\x4e\xfa\xb8\x6f\xa7\x1f\xf6\x0f\xac\x41\x33\x04\x3a\x51\x7f\x84\x61\x7c\xdb\xb7\x31\x62\x67\x31\x6e\x02\x54\xee\xb0\x07\xcd\x33\x60\x90\x8c\xfb\x5d\x87\x8c\x25\xb9\x63\xca\xd3\x54\xd1\x27\x86\xce\x40\xa9\x20\x79\x48\x8f\xcb\x3d\x0d\x41\xf8\x1c\xe8\x8c\xd3\x34\xea\x77\x3e\x1b\xda\x84\x7b\x42\x01\xc5\x5c\x67\x59\xa6\x29\x00\xd9\xd8\x12\x65\x80\x6c\x92\xe5\xde\x99\x42\xd0\xbc\x00\x3e\x47\x7d\x43\x5c\x85\x09\xaa\x2a\x5b\xe2\xcc\x29\xa8\x19\x8e\x14\xbc\x60\xd0\x6c\x02\xef\xd2\xe4\x43\xd4\xc7\xbb\x76\x5a\xe1\x70\x64\x7c\x55\xd3\x84\xb2\xc3\x09\x9a\x97\xc0\x30\xea\x70\xad\xda\xe2\x94\xde\x95\x40\x69\x56\x9a\x5d\x8e\xdc\xbc\xa9\x66\x9b\x45\xee\x0a\xe8\xc6\xed\x28\x8d\x86\xf1\xb0\x61\xc1\xc2\xa0\x82\x3b\xa5\x03\xe5\x9d\x74\x46\x7e\x50\x3e\x61\x0b\xe8\x24\x83\xcf\x69\x7c\x7b\x37\x72\x45\x66\xe5\x56\xfc\xa7\x89\xf6\xab\x5c\xb3\xb9\x02\x9f\xd2\x56\xce\x8b\x5d\xad\xae\x09\xa5\x56\x34\x08\x2e\x4f\x81\xf7\xd1\x7d\xdc\x8f\xfb\x11\x92\xb4\x1b\xf7\xdb\x3d\xc4\xfd\x6e\xdc\x69\x8f\x92\x54\x86\x73\x9d\xb4\x8a\x9c\x95\x4e\x38\x8c\x9d\x70\x7e\x00\x94\xf5\x74\x19\x00\xbd\xe8\xfd\xe8\xcd\x20\x89\xfb\xa3\xb8\x7f\x8b\x6e\x32\x7e\xd7\x8b\xd0\xee\xdf\xf6\x22\xfc\x39\x4e\x46\x0e\xa6\x74\x29\xa0\xbb\xab\xaa\xbf\xaa\x3a\xac\x4e\x0d\x16\x5c\x86\xe0\xb3\x39\xa3\xbc\x52\x39\x04\xd7\x1c\xdc\x68\x20\x88\x9c\x01\xc3\xe4\xfd\x08\x77\x9f\x07\x77\x51\xbf\xe1\x1e\xc4\x29\x44\xad\xd9\x88\xb3\x8d\x73\x20\x8d\x6e\xe3\xe1\x28\x4a\xa3\x6e\x9d\xb6\x00\x4b\x5b\xcc\xc3\x2a\x6d\x1d\x83\xaa\x62\x5c\x06\x7e\xbf\xb6\x2e\x80\xfb\x76\x27\x4d\xfa\xb5\x43\x1b\x75\xca\xa2\x52\x38\x89\x26\xd0\x8d\x6e\xd3\x28\x52\x1b\x2d\x16\x42\x44\xa7\xa8\xc4\x8a\xa3\x16\x85\x4b\x60\xd0\x1b\x0f\xdf\xdc\xc7\xfd\xf1\xd0\x16\xbe\x86\x8e\x9c\x52\xc1\x6a\x9a\x50\x39\xfb\xab\xec\xab\x06\x97\x57\xc0\x70\x3c\x88\xd2\x61\x27\x8d\x07\x23\x8c\x3e\x25\x0d\x67\x4a\x03\xdd\x66\x76\x87\x33\x3e\xa5\xb6\x0a\xb4\xee\xd2\x28\x6a\x58\x4e\x27\x97\x96\x41\xe5\xe4\xa6\x96\xda\xd5\x29\xd0\xee\x8c\x47\x11\xda\x1d\xe6\xc3\xf5\x10\x40\x89\xdd\x5b\x5e\x07\x57\x01\x70\x1f\x77\xd2\xc4\x31\x50\x2b\xc5\xdf\xda\x6f\x3d\x51\x09\xac\x1b\xe6\xae\x42\x60\x10\xf7\x3a\x69\xf2\xc9\x52\xa2\x29\xa4\x21\x67\x8b\x38\xd4\x18\xa2\x56\xea\x45\x4b\x1d\x47\x4e\xf4\x8c\xed\xb6\xdb\xed\x45\xe8\x26\xec\x88\x70\xa6\x7c\x07\xe2\x78\x7c\x11\xff\x9c\x05\x8c\xa8\x1b\xf7\x7a\xed\x86\x22\xe6\xfc\x45\xf9\xb6\x8f\xf8\xb7\x17\xae\x36\x92\x7e\xd4\x50\xdd\x93\x6b\x9d\x80\xaa\x63\x96\x7a\x20\xc1\x55\x93\x99\xfd\xb0\x33\xee\xd5\x7a\x29\xe5\xa4\x26\xc2\x47\x15\xc6\x2d\x3e\xbd\x5e\x02\xdc\xc3\xee\xe6\xa0\x14\x9a\x8d\x43\x32\x43\x1a\x59\x0e\xba\xbd\x83\xe0\xea\x0a\xf8\x38\xee\xdd\xb6\x53\xbc\x4f\xdb\x22\xd2\x24\x7d\x46\xb8\x9d\x8e\xa2\xb4\xa1\xa6\xdd\x62\xf3\xd7\xa2\x6d\x45\x75\x9b\x8b\xfd\x23\x20\xce\x8a\x67\x9d\xe2\xcb\xd8\x6e\xba\x5f\x42\x6c\x8c\x5f\xcb\xcf\xef\xae\xdd\x7b\x6f\x33\x83\xc3\x4e\xe1\x9f\x33\x94\x30\x93\x97\x03\x88\x13\x87\x8b\xf3\x50\x73\xd0\xd6\x69\x99\x31\xc7\x9c\x3a\xea\x50\x97\xd2\xc6\x4f\xe4\x54\x8e\x08\xa8\x9a\x9b\xe3\x1a\xd6\xa1\x19\x33\xeb\xdc\xf2\xa0\xee\xd1\xed\xd3\xb7\xec\x94\xed\xcf\x71\x34\xac\xc9\xd7\x54\xd3\x97\x73\xf5\xb4\x7d\x82\x56\x08\xf4\xda\xa3\xb8\x8f\x4e\x7b\x10\x8f\xda\x3d\xf4\xa2\xd1\x28\x4a\xd1\xc6\xa7\x78\x74\x87\xdb\xb4\xfd\x31\x6a\x38\x5e\x4f\x46\x27\x5e\x48\xe8\x32\x42\x17\x11\x8e\xe5\xb5\xce\xea\xa9\x73\x6f\xe3\x2b\xc0\x76\xa3\x7e\x5e\x4f\xbd\x13\xa7\x9d\xf1\xfd\xfb\x5e\xf4\x97\x58\x45\x64\x8a\x47\x55\x43\x52\xd4\x42\xa6\x14\x32\x95\x90\x1b\xe0\x5b\x17\xf5\x8c\x46\x71\xaf\x2b\x8f\x21\xab\x34\x76\x10\x55\xa8\xed\x51\x71\x05\xad\x66\x3d\x27\x3b\xf1\xfa\xe5\xfa\x2e\x68\x5d\xd6\x73\x4b\x99\xab\x68\xbf\x4b\xa4\x05\x1c\x1e\x1e\x1d\x49\x3f\xbe\xdf\x50\x34\x68\x5d\x55\x31\x8a\xac\x14\xc2\x1e\xa8\xc9\x5f\xea\xb1\x12\xec\xa1\x23\xcf\x77\xcc\xe0\x51\x24\xfe\x9e\x6e\xbe\xe2\xde\xaa\xe0\xde\x91\x76\x62\xfc\xfb\x4f\x0d\x5e\x09\x1f\x45\x73\x5e\xe1\xe9\x69\x05\xaf\x68\x07\x3c\xa9\x2b\x0a\xc4\x6a\x36\xda\x16\x1f\x9e\x06\xf5\xd4\x6b\xf1\xb4\x9d\x7a\x95\x2f\x88\x76\xc7\x93\xf2\xea\xb4\x66\xfe\x19\x9e\x56\xb9\x85\x68\x0f\x2b\xa7\xaa\xc3\x62\x06\xc7\xb4\x74\xcf\x8b\x73\xab\x72\x13\xf1\x76\x95\x40\xb6\x83\x50\x2d\xb4\x2a\xdf\x10\x6f\x57\xc9\x0e\xd4\xab\xfc\x41\xbc\xb3\x4a\xa0\xc2\x4e\xdd\x48\x3a\x3c\xad\x72\x05\xf1\xee\x2a\x01\x75\x66\x41\x75\x2a\xa9\xf2\x07\xd1\xe8\xae\xba\x4f\x42\xa9\x35\x6e\x91\xe9\xb7\x2a\xcd\x7d\xd5\x7e\x78\x5a\x05\xfc\xfe\x6e\x7e\xdb\xcc\x9f\x61\xc6\xcf\xa5\xe9\x33\xe3\x14\x54\xc1\x3e\xa9\xb0\x31\x2a\x6d\x6c\x97\x9e\x79\x18\x54\xc1\x3e\xa9\xb0\x31\x4a\x89\x75\xdd\x69\x1b\xf5\x2a\xd8\x27\x5e\x1b\x93\x26\xa6\x2c\x6c\x37\x16\x55\x80\x4f\x8a\x8a\x50\x7a\xd0\x6a\xd8\xf5\xc6\x56\x18\x54\xc1\x3c\xf1\x58\xf0\xaf\xb6\x03\xc3\x80\x95\xa8\xe3\xde\x28\x1e\xf4\x58\x76\xee\xf6\x56\x6e\xf4\x83\xe4\x5c\x5a\x6f\x79\xf1\xa5\xee\xb6\x6a\x1a\x55\xe0\x96\x3b\x1e\x8e\xd2\xe4\x83\x2e\xe7\x74\xe2\x4f\x88\xca\xc6\x09\x51\x1d\x04\xfe\xc6\xb7\xab\x5b\x86\xee\x76\xab\xe0\x3d\xf6\xd8\xa7\x31\xd0\xea\x89\x83\x4f\x01\x55\xa0\x1e\x7b\xac\x14\xda\x4c\xf7\xe3\x51\x85\xe8\x71\x95\xad\x42\x1b\xeb\x5e\x8c\xc2\x2a\x40\x8f\xb7\x59\xd3\x4f\xb4\xb8\xc3\xb0\x0a\xe0\x9f\x0b\xa2\xe3\x82\x53\x62\x2b\x5f\x32\x28\x4c\x90\xc2\xb0\x0a\xda\xa3\xbb\x24\xed\x3b\xfa\xf6\x0e\x5d\xa9\xaa\x2e\x3d\xc3\xb0\x30\xd4\xa0\x1e\xde\xb7\x7b\x9a\xf4\xf0\xae\x9d\x0e\x30\xac\x76\xe3\xfb\xb6\xbb\xc3\xf0\xdc\xcb\xc8\x57\xa1\x14\x4d\x77\xb7\x21\x7f\x18\x5e\xd4\x71\xa8\x35\xdc\x5d\x39\x34\xeb\x38\x6c\x37\xdb\x5d\xd9\x5c\xd6\xb1\xa9\x70\xb3\xfb\x71\xb8\xaa\xe3\xb0\x9b\x93\xdd\x71\x6c\x13\x86\xad\x3a\x5e\x85\xea\xc4\xe8\x46\xd6\x29\x3b\x1f\xe9\xec\xd4\xcf\x26\xb2\x6b\x89\x9b\x86\x3b\x74\x17\xd4\x61\xc5\x3e\x73\xb5\xe2\x98\x7a\x3a\x08\x9c\x53\xe0\xe5\x54\xae\x43\x6c\x8e\xf5\xd7\x46\x64\xf1\xc1\xa9\x87\x5e\xea\xc5\xca\x43\xc9\x49\x27\x20\xb5\x17\x43\xc2\x33\x3f\xcc\x4b\x15\x87\xcc\x3c\x74\xe2\xb1\x85\xaa\x1f\xd3\xfe\x4a\xa3\x9c\x72\xc8\x8c\x40\xd6\x1b\x9e\x3b\x34\xe1\x99\x1f\xd2\xbe\x0a\x83\x5a\x66\xaa\xad\x54\x65\x02\xaa\xd0\x98\x78\xd3\xe6\x33\x3f\xac\x8b\x95\x85\x72\x82\xba\xae\xa8\x1d\xa2\x85\x67\x7e\x14\x97\x2a\x0a\x55\x2e\xd3\x5d\xae\x90\x84\x67\x7e\xe4\xfa\x2b\x09\x55\x48\x98\x3a\xc2\x3f\xd0\x76\x44\xee\x87\xab\xa7\x82\xb0\x67\x46\xd4\x9a\x2c\x5a\x2c\xaa\xee\x60\x84\xe7\x7e\xb4\xea\xca\x21\x57\xdd\x9b\x3f\xf2\xfc\x0f\x31\xd7\x10\xbf\x63\x18\xfa\xc2\x43\x8d\x3f\xe4\x9f\xfb\xc1\xb9\x63\xad\xa0\x2e\x5a\x5a\x71\x5f\x5d\x1e\x2e\x78\xb5\x73\x3f\x4c\x7f\x4b\xa5\x70\xee\x07\xeb\x6f\xa9\x13\xce\xfd\x90\xfd\x7d\x55\xc2\xb9\x1f\xb2\xbf\xb1\x46\x38\xf7\xc3\xf5\x7f\x52\x21\x9c\x5f\x02\xdd\xf8\x63\x3c\x74\x6b\x03\x3d\x16\x91\x43\x37\x46\xdd\x9e\x6e\xb9\xff\x5f\x83\xa0\xe4\x07\x6e\xa9\x4a\x70\xa3\x86\x6a\x8e\x10\x35\xee\x52\x03\x2f\x91\x65\x15\x04\xe3\x87\xee\xcf\x56\x07\x9e\x20\x7b\xe1\x87\xed\xcf\xd6\x06\x3e\x0e\x7e\xfc\xfe\x52\x65\xe0\x63\xe3\x87\xef\xaf\xd6\x05\xde\x04\xe8\xc2\x0f\xe7\x62\x55\xe0\xce\x24\x29\xd9\xf7\xb2\x54\x78\xe1\x87\xb6\xa9\x12\x4c\x99\x60\xea\x84\x3d\xae\xec\x85\x17\x7e\x68\x7f\xae\x68\x2e\x59\xdd\x25\xfb\xe2\x89\x89\x70\xf6\x9c\xff\xd8\x6a\x6c\xe9\x6b\x0a\xff\x0d\x00\x00\xff\xff\x0d\x26\x17\x04\x9d\x3c\x00\x00") + +func fontsSlantFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSlantFlf, + "fonts/slant.flf", + ) +} + +func fontsSlantFlf() (*asset, error) { + bytes, err := fontsSlantFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/slant.flf", size: 15517, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSlideFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x58\x4d\x8f\xdc\x36\x0c\xbd\xfb\x57\x3c\x58\x0b\x6c\x02\x34\xcc\x4e\x91\x14\xd9\x5b\x3f\x80\xc2\x87\xa0\xed\xa1\xed\xdd\x99\xf1\x74\x8d\xcc\xda\x03\x7b\xb6\x40\x00\x23\xbf\x3d\x18\x5b\x94\x28\x89\xf2\x38\x7b\xb0\x65\x49\xa4\xc8\xc7\x47\x52\xb3\xc7\xd3\xf1\xc7\x9a\xf0\x13\xde\x63\xf7\x1e\x0f\xd8\x3d\x14\xc5\x78\x6a\x0f\x0d\x1d\x4f\x47\xbc\xfa\xed\x35\x76\x8f\x8f\xef\xf0\xe9\x0b\xfe\x6d\xf7\x97\x7e\xc0\x5f\xf5\x50\x1f\x6a\xbc\xfa\xff\x3c\x0f\x7e\x6e\xbb\x23\xbd\x5c\x8e\xe3\x33\xed\x4f\xaf\xf1\xf8\xee\xed\xc3\x87\xb7\xbb\x0f\x54\x14\x1f\xfb\xfe\xf3\x88\xae\xdd\x37\x68\x3b\x8c\xfd\x73\x83\xcf\x6d\x77\x40\x7f\xc4\xb8\x1f\x9a\xa6\x1b\x51\x77\x07\x9c\xeb\x73\x33\x50\xf1\x7b\xd3\x9c\x70\x1c\x9a\x06\x97\x1e\x43\x73\x3e\xd5\xfb\x06\xa5\x29\x7f\x40\x59\x95\xf3\xc6\x72\x2a\xaf\x6b\xb3\xa2\xfe\xf2\xd4\x0c\xd8\x3f\xd5\xc3\x48\x45\xf1\xf7\xf0\x05\xfd\xf9\xd2\xf6\x1d\xca\x37\xcf\x78\xb3\x9b\x37\x1e\xda\xb1\xfe\x74\x6a\x30\x3e\xbf\x8c\x4f\xb3\x86\xff\x9a\x0b\xf6\xa7\xa6\x1e\x70\xec\xbb\xcb\x55\xf2\x63\x7d\x69\xbb\xe5\x0b\xf5\x3d\x9a\x7b\xb4\xf7\xe8\xef\xf1\x72\x8f\xee\xeb\x2c\xf3\xc7\x57\xb6\x66\xc4\x2f\x25\xfe\x2c\xf1\x4f\x89\xba\x44\x5f\xe2\x65\xb1\xeb\x57\x2a\x0a\x02\xee\x0a\xa2\xf0\x01\xfb\xb8\x2b\xcc\x04\xf9\x98\x97\xe7\x11\xec\xb2\x5d\x5b\x5e\x30\xd7\x75\xd0\xac\x00\xd7\x3f\x7e\xdd\x15\x30\x15\xaa\xe9\x3a\x63\x4c\x55\x55\xd3\xac\x64\x75\x0e\xf6\xef\x2a\x0c\x33\x2d\xda\x8c\xdd\x66\x4c\x35\x2d\xc7\x90\x71\x33\x2c\xb7\x6c\xbe\x4e\x01\x76\x8d\x75\x92\xb1\x62\xa6\x72\x4b\xcb\x20\x3c\x8d\xe0\x54\xd9\xfd\x91\x40\x30\x27\x4c\x15\x88\x39\x2c\x19\x88\x19\x06\xab\xc4\xba\x4d\xf0\x5f\x76\xcd\x69\x0a\x67\xc9\xc2\x23\xe5\x3d\xb8\x86\x6d\x82\xa9\x16\xa8\x04\xa4\x6e\x4e\xee\x13\xee\x92\xf5\x96\xc1\x31\x8c\xb2\x87\xcb\xed\x11\x62\xce\x33\x42\xec\xb7\x0f\xff\x42\x06\xc3\xfa\x54\x6a\xe4\x34\xb9\x65\xaa\xec\xa7\x09\x22\x5c\x2c\xef\x59\x3f\x21\xb6\x8f\xf9\x10\xb2\xc0\x52\x05\x4c\xb6\x80\x6b\x4b\x80\x2c\xbe\x3c\x0e\x9e\x1c\x1a\x96\x23\x44\x9a\xae\xa7\x45\x20\x7a\x6e\xe4\xc5\xdc\x8c\x51\x4c\x9a\x83\xbe\xec\x9e\xf8\x10\x1e\x54\x93\x3d\x84\xa6\x48\xcc\xf8\x5c\x91\x26\xdd\x3c\x4d\x78\x42\x08\xc4\x7c\xae\xa4\x62\x82\x33\xf9\x28\x99\x0d\x51\x5a\x99\xb9\x29\x36\xe9\xd8\x2a\xc9\x49\x1a\xd3\xb2\xcb\x96\xd2\x96\x86\x41\xee\xb2\xb3\x8e\xa2\x8b\x7d\x1a\xed\xb5\x24\x48\xf5\x4c\xca\x19\x79\xfe\x2c\xa9\x1d\x24\x28\xa3\xae\x82\x55\xc5\x99\x00\xae\x6f\x2a\xed\x00\x35\x22\x01\xb5\x72\x24\x0f\x77\xeb\x33\x91\x91\x11\x5b\x1d\xff\xa4\x91\xb7\x4f\x4b\x07\x79\xb6\x1a\xc4\xb9\x71\x33\x81\xf5\x94\x92\xd6\x26\xa5\x52\xf3\x2d\x06\x50\x3b\x4d\xf5\x44\x77\x52\x88\x55\x92\xa6\xe1\x8b\xd7\x7c\xe9\x67\x69\x1e\x50\xa2\x58\x43\x2f\xee\xab\xc6\x77\x1d\xc4\x89\x89\x80\xe9\xd0\xde\x12\x4b\x96\xb0\xe7\xf0\x41\x1e\x30\x81\x81\x68\xc9\x69\x23\x16\xa0\xa5\xe8\x65\xe9\xab\xb6\x8d\x2d\x90\xac\xb1\x9e\xb6\x97\x3f\xe5\xce\x32\x37\xf2\xef\x38\x2d\x1b\x80\x94\x87\x9b\xfa\x8f\x76\x1d\x70\x45\x26\x1d\xac\xd1\xf7\x3b\xc9\x95\xdf\xad\x9e\x86\x84\x17\xde\x61\x19\xf2\x3c\x57\x94\x13\xd2\x4e\xb3\x62\xaa\x66\xa1\x62\xea\x4a\xab\xac\xd6\x8a\xcf\x24\xef\x8c\xe1\x2b\xc8\x6b\x7f\x1d\xe2\xd6\x2b\xcd\x70\x77\x47\x4a\x69\x35\x89\x5e\x16\xbc\xa2\x13\x5c\x83\xe2\x2a\x3a\xc5\xf7\x3a\x79\xbd\x0b\x69\x2f\x9b\x95\xbb\x7a\x12\x05\x7e\x07\xcd\x98\x3b\x74\x70\x91\xb6\xba\x0c\xfb\x45\xb2\x12\xa9\xc5\x24\xae\x3a\x32\x61\xfc\x37\x44\x71\x14\x39\x22\xcb\x14\x82\x79\x29\x60\x27\xf8\xa2\xe0\x04\x83\x6f\x84\xc8\x2c\xf7\x3a\x69\xf3\x92\x9e\x9a\x40\x44\x81\x89\x12\x26\x28\xba\x75\x23\x28\x70\x7b\x0b\x3e\x88\x00\x9d\x97\x89\xaf\x4a\xfe\xe9\xb6\x89\x3b\x13\x2d\x0e\xe9\xcc\x62\x03\x44\x6f\x0c\x23\x19\x18\x12\x19\x60\x41\xc8\x1a\x00\xcf\x14\xff\x6b\xd3\xc0\xa3\xe2\xdc\x83\xd4\x1f\x91\x4c\xc7\x22\x31\x29\x8d\x28\x62\xf4\x63\x92\xe5\x4e\xa8\x26\xa5\x57\x6e\x88\x6b\x48\x42\x79\xc2\xaa\x66\xd5\x87\x30\x31\x28\x97\x28\xf2\x67\x23\xfc\xb7\x28\x6a\x39\xa7\x33\x70\xe6\x12\x25\x0f\xa7\x20\x7f\x1c\x75\x8e\xab\x8c\xb5\x6b\xa9\xbe\xcb\x6a\x51\x8f\x4e\xc9\x11\x71\xc5\x3c\x3d\xd7\x44\xd4\x2b\x6e\xac\x80\x82\xa4\x48\xfc\x00\x5a\x17\x34\xff\xef\x8c\x24\x37\xf2\x0f\x19\x53\x6e\x06\x14\x18\xa2\xc4\xd8\x61\x57\x49\xe2\x71\x6e\x47\xf5\x5d\x20\xc3\xbf\xa7\x89\xb6\x54\x69\xcc\x16\x2c\x58\xd3\xb6\x92\x38\x6d\xa8\x42\x89\xd6\xdb\x69\x69\x34\x66\x66\x19\xea\x23\x49\xb4\xad\x7a\xfa\x4b\x00\xb9\x82\x9b\xfc\x9f\x22\xb9\x72\x7c\x0b\x00\x00\xff\xff\x77\x0b\x22\xaa\xf6\x14\x00\x00") + +func fontsSlideFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSlideFlf, + "fonts/slide.flf", + ) +} + +func fontsSlideFlf() (*asset, error) { + bytes, err := fontsSlideFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/slide.flf", size: 5366, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSlscriptFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x57\x5d\x6f\xa3\x56\x13\xbe\xe7\x57\xcc\x45\x24\x40\x32\x4c\x12\x65\x57\x1b\xc9\xb2\xc8\x7b\xf1\xaa\x5d\xa9\x52\x2f\x5a\xed\x5e\x20\x9d\x10\x38\x89\x69\x6d\xb0\x00\xaf\xeb\xca\x3f\xbe\x9a\x99\x73\xf8\x26\x71\xeb\xc4\x98\x8f\xf9\x3a\xcf\x3c\x33\x73\x78\xdd\xbd\xde\x27\x37\xf0\x19\x1e\xe0\xfe\x16\x6e\xe1\xee\xce\x71\xfe\x97\xd4\x3a\x83\xb2\x80\xf4\x58\xd5\xf9\x0f\xed\x7d\xf6\xe1\xe5\x0c\x5f\x93\x02\xbe\x95\xbb\x46\x57\x40\x9f\xf5\x1f\x49\x91\x46\x69\x95\xef\x43\xad\xd3\x3a\x3c\xee\xf3\x74\x1b\xea\xec\xb8\x21\xd5\xfb\x07\xf8\x7a\xdc\xc1\xdd\xe3\x97\x4f\xce\xff\xf3\xb7\x9d\x6e\x82\xfc\x6f\x9d\x41\x52\x64\xac\xfd\x72\x86\x6f\xba\xc8\xf4\x6e\x07\x3f\xe5\xe9\x9f\xba\x80\xf5\x69\xcb\x27\xd1\x21\xa9\x92\xba\x7c\x6d\xc2\xb4\xdc\x6f\x58\xb8\x2c\x00\x3e\xc1\x2f\x49\x05\x77\x8f\x8f\x0f\x0e\xdd\x7a\xca\x32\x9d\xc1\x3e\xaf\xeb\xbc\x78\x83\xc3\xb1\x48\x9b\x63\xd2\xe4\x65\xc1\x1e\x8a\xe3\xfe\x45\x57\xb5\xf3\xb4\xdf\x93\x13\x71\x69\x3e\xb4\x12\x5d\x55\x49\x06\xbf\xe6\xba\x4a\x35\xad\xe4\xc0\x67\x51\x7a\x48\x8a\xb0\xac\xde\x36\xad\x30\x79\xfe\x02\x4f\xc7\x37\xb8\xbf\xbd\xbd\x67\xcf\xbf\x17\x99\xae\xea\xb4\xac\x34\xbb\xca\x92\x7a\x0b\xdb\xe4\x87\x86\x17\xad\x0b\x38\x1e\xb2\xa4\xd1\x19\x34\x25\xec\x49\x24\xdd\x95\xb5\xde\x9d\x61\x9f\x34\xe9\xb6\x07\xa8\xe3\x18\x0f\xbf\x6d\x35\x80\xab\x5c\x48\xb7\x49\x95\xa4\x84\x6e\x5e\x43\x53\x69\x36\x93\x17\x90\x40\x7d\xd0\x69\x9e\xec\xe0\x94\x9c\x43\x80\x9f\x1b\xd8\x27\x67\x78\xd1\xd6\x42\x5e\xd4\xba\x32\xc2\xcd\x56\x43\xa3\xff\x6a\x20\x29\xce\xa7\xad\xae\x34\x9c\xcb\x23\x9c\xf2\x7a\x4b\x11\xed\x74\xf1\xd6\x6c\x35\xd9\x84\xb4\x2c\x02\x6b\xa1\xd0\x69\x43\x30\xee\xf2\x82\x96\xd1\x9c\x68\x25\xcd\x89\x14\x9a\x46\x57\x75\xe8\x38\x37\x37\xd1\xdc\x37\x62\x13\x7c\x44\x3a\x22\x9d\xbb\x74\xa7\xb4\xf7\x41\x84\xe8\x4e\x19\x39\x2e\xb8\xe6\xb2\x3d\x88\x36\xeb\x07\x18\x60\x10\x39\xfc\x03\x91\x83\x80\xad\x95\xde\x2f\x9d\xac\x58\x10\x3c\x85\xf2\x00\xc1\x07\x56\x74\x67\x15\x3c\xbf\x17\x1f\xab\x20\x78\x7e\x2f\x7a\xb6\xea\xf9\x7c\x85\x31\xfd\x78\x00\xdf\xe9\x2a\x46\x88\x8d\x25\xfb\x13\x39\xb4\x9c\xc8\x71\xf9\x84\xff\xe9\x91\xc2\xce\x78\x77\x84\x11\x10\xd8\x1e\x15\x2e\x0a\xf1\x55\xcc\xe1\x06\xc1\xf7\x20\x60\xc3\x31\x4c\xe3\xe8\xe0\x67\x51\x34\xa2\x30\x23\x6a\xff\x6d\xe0\x94\xc0\x1b\x73\x08\x48\xaf\xbb\x94\xcc\xf6\x14\xda\x35\x4e\x61\x9c\x0b\x5f\x29\x93\x14\xf0\x45\x90\x14\x3c\x65\x93\x35\xc9\xa6\x62\x69\x16\x65\x93\x63\x76\x18\x7b\x20\xf6\xc2\x20\x70\xc5\xde\x12\x3b\x46\x0a\x00\x01\x19\x56\xcb\x01\xc8\x35\x72\x10\x6e\xc0\xd2\x00\x38\x87\x22\x28\xa5\x5a\x88\xdd\x20\x08\xc5\xb0\x3f\x9f\x9b\x0e\x2c\x25\x11\x8f\x39\x27\xd6\xc8\x2d\x13\x7a\xba\x76\x59\x89\x67\x56\x8e\x66\xe1\x73\xee\x54\xdf\x45\x97\xa1\x71\x6e\xda\x43\xd9\xd6\x65\x1f\xea\xf9\xc7\xae\x3c\x46\x8a\x30\x72\x98\x88\x5c\x14\xfc\xed\xeb\x31\x91\xf8\xd0\x5b\x45\x2b\x6f\xf4\x7b\x7a\x26\x51\x12\x35\x5a\x87\xb3\xc0\x9b\x4b\x25\xa9\x2a\x63\x59\xad\xe0\x37\x16\x1d\x11\x50\x32\x8a\x00\x9e\x7a\x9f\x30\x9d\xc2\x9a\x14\x88\x31\xea\x2a\x05\x11\x78\x87\xe2\xf3\x35\x81\xe4\xe0\x43\x85\x67\x09\xc9\x78\x50\xab\x45\x85\x16\x0d\x04\xee\xb3\xd4\x25\x57\xa2\x86\x03\x85\xc1\x19\x9d\x52\xeb\x5b\xb1\xbb\xe7\xc0\xbd\x98\x15\x99\x08\x83\x75\x17\x62\xef\x84\x28\x47\x27\x2b\xa2\x87\x6f\x29\x47\x50\xb7\x58\x2f\xa8\xd1\xc7\x9a\xbc\x10\x1c\xab\x20\x08\x2e\xac\x1f\x2b\x84\x58\x2d\xa8\xa9\xb6\x18\x60\x23\xd7\x28\xb5\xc8\x2e\xd7\x0a\x47\x90\xa8\x2e\x3a\x13\xdc\xda\xf6\x2c\x7f\x09\x43\xee\xcb\x5d\x23\x6f\x11\xed\x4a\x48\xf1\x9f\x98\xf5\x4d\x32\xd1\x74\x2e\xb7\xcf\xb0\x31\x56\xca\x6a\x0d\x18\x70\x0d\x29\xdd\xab\xda\xe8\xc4\x83\xf4\xc9\x61\xe6\xaf\x20\xa5\xa7\x62\xeb\xe1\xf9\x5a\x0f\xf1\xc2\x1a\xcc\x48\x35\x33\x95\x1d\x59\xda\xcf\x17\x96\x1a\xb2\x98\x1e\x32\xa5\xae\x61\x31\xd3\x91\x94\x0d\x1f\x6d\x4f\xef\xd5\xe6\x47\xca\x7d\x2e\x7b\xed\x08\x88\x11\x96\xb8\xac\xa0\xaf\x67\xfb\xae\xa1\xa4\xa7\xbc\x01\x29\xe7\x7c\x32\x41\x65\xd4\x03\x6d\x39\x4c\x42\xe2\x59\x78\x66\x0a\x0e\xac\x2b\xea\x24\x7c\xc7\xa2\x85\x56\xad\x1b\x32\xb6\xa4\xa3\xf1\x80\x1d\xce\x0c\x54\x93\xc9\x11\xdb\x3d\x89\x00\x22\x0f\xe2\xe9\x78\x11\xd3\xed\x2e\x41\x4d\x67\x10\x76\x93\xa3\xff\xed\x6d\x38\x54\xb7\xe1\xe0\xdd\xc7\xf3\x70\x9f\x35\x18\x0f\x4a\x85\xc2\x8c\xcb\xec\x20\xe8\x4f\x60\x45\x0b\xf3\xdf\x19\x89\x2a\x64\x1c\xc7\xe0\x58\x61\xde\xb3\x29\xa9\x90\xae\x6b\x0f\xdc\xb5\x96\xa8\x1f\xe1\x8c\x25\x6b\x4a\xf6\x01\x68\x36\x1a\x62\x0d\x37\xfc\x7c\x8d\xa3\xf0\xc5\xe2\x8a\xfd\xfa\xdc\xf0\x2e\x10\x39\x17\x5c\xd8\x65\x20\xe0\xa4\x67\x59\x98\x4b\x6a\x93\xd1\x60\x70\x8f\x66\xad\x8c\x7d\x34\x84\xa0\x89\xee\x2e\x6d\x67\x10\xd6\x53\x47\x86\x4a\x28\x44\x64\x14\x66\x10\x9f\x96\xb1\xd4\xbd\xd9\xf4\x77\x96\xa7\x35\x33\xac\x09\x51\x34\x6a\xeb\x85\x59\xdd\x66\x45\x31\x84\x8b\x59\x31\xbf\x86\xfc\x68\xc0\x96\xfb\xee\x98\x54\xd3\xac\x6c\xa6\x59\x31\x6e\xe5\x7d\x63\x06\xac\x9e\x90\xd4\x9d\xbf\x20\x64\x27\x1d\xcf\xb9\x59\x44\xdb\x63\x08\xa1\x30\x74\x91\xe8\x2b\x4a\x52\x8c\xf0\x3e\x10\x2b\xfa\x33\x3d\x6c\x01\xd8\x41\x21\x86\x2b\x49\x43\x3c\x5f\x88\xa3\xa4\x71\x1b\x23\x50\x8c\x6d\xd3\x27\xdc\x79\xdb\x5c\xe4\x08\x20\x45\xee\x5d\x06\xb6\xe9\xbd\x4b\x5d\xf7\xde\xf5\xd1\x8b\x8b\xc1\x04\x65\x1b\x60\xe5\x66\x4a\x5d\x19\x4f\xb1\xc2\xb9\x2a\x1a\xc4\x57\x2a\x55\x46\xff\x66\x37\xda\x29\x5c\x39\xf8\x4b\xd6\xf9\x6f\x73\xcf\xdc\x29\xa1\xbc\xa2\x9d\x9a\xb7\xf8\xc5\x4a\x12\x43\xef\x93\xb0\x7d\x39\x33\x78\xd8\xdd\xb6\xb2\xdb\x6d\x1c\x85\x19\x45\xce\x3f\x01\x00\x00\xff\xff\xbf\xcb\xeb\x13\xa7\x12\x00\x00") + +func fontsSlscriptFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSlscriptFlf, + "fonts/slscript.flf", + ) +} + +func fontsSlscriptFlf() (*asset, error) { + bytes, err := fontsSlscriptFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/slscript.flf", size: 4775, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmallFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x5a\x6d\x6f\xe2\x38\x17\xfd\xce\xaf\x38\x1f\x46\x9a\x22\x95\x9a\x04\x0a\xad\x54\x8d\x9a\x81\xb4\x8d\x96\x12\x9e\x10\x3a\x3b\x52\x24\x2f\x33\x4d\xa7\x68\x29\x54\xbc\xec\x6a\xa4\xfc\xf8\x47\x8e\xed\xc4\x71\xec\x94\x5d\x69\x27\x88\xda\xc7\xf7\x5e\xdf\x73\x7d\x7c\xc3\xcb\xfa\xc5\x5d\x7e\xc2\x25\xfa\x70\x7a\x70\x2e\xe1\x74\xd1\x85\xeb\xf6\x9d\xcb\xd6\xfc\x6d\xb9\x5e\xe3\xc7\x6f\xdc\xaf\xd3\xcd\x06\xa3\xd7\xe5\xfb\x7b\xba\x5e\xa3\x4f\xae\x7b\xe8\x74\xf0\x63\xb9\x4f\x9f\xb1\xdd\x60\x7e\x58\x6e\x9e\x97\xbb\xe7\x56\xb0\xf9\xb9\x3e\x3e\xa7\x7b\x04\xf3\x10\x93\xe5\x61\xb5\xe9\x38\xad\x97\xd5\xaf\x75\x7a\xc0\x2e\x5d\xa7\xcb\x7d\x0a\xf7\xc2\x61\x93\x1d\x17\xde\xf1\x17\x9c\xeb\xeb\x7e\x6b\x96\xee\xde\x56\xfb\xfd\x6a\xbb\xc1\x6a\x8f\xd7\x74\x97\xfe\xf8\x8d\x5f\xab\x7f\xd2\x0d\x0e\x5b\xbc\x6d\x9f\x57\x2f\xbf\x71\x78\x5d\xed\xf1\xb2\xdd\x1c\xce\xb1\xdc\x63\xbd\xdd\xfc\x62\xcf\xc3\x6b\xda\xca\x07\xac\xd2\xdd\xe7\x3d\x36\xcb\xb7\x94\x61\xbc\xaf\x97\x3f\xb9\x6d\x4b\xfc\xdc\xbe\xbd\xa5\x9b\x03\xd6\xab\x4d\x7a\xd1\x6a\x3d\xf2\xd1\xcf\xcc\xb1\xd9\xf2\xb8\xc6\xd7\xe3\xee\xb0\xdd\xe0\x66\xbf\x5d\x1f\x0f\xab\xed\xe6\x36\x5d\xee\x0e\xaf\xeb\xd5\xe6\xef\x8b\x4d\x7a\xf8\x02\xc7\x25\xd7\x03\x66\xc8\x8a\x7b\x87\x4d\xfa\x2f\xde\x97\xbb\xe5\x5b\x7a\x48\x77\xad\xfd\xf1\xfd\x7d\xbb\x3b\x70\xc0\xbb\xe0\x9e\xf9\xba\xdc\x3c\xb3\x8f\xdf\x56\x9b\x0b\xe0\x71\xf9\x1b\xcb\xf5\x7e\x8b\x1f\x29\xf6\xeb\xd5\xaf\xd7\xc3\xfa\x37\xde\xa4\x15\x2f\xdb\x1d\x7e\xa4\x87\x43\xba\xc3\x71\x9f\xb6\xb6\x2f\x39\xfc\xcb\x71\xbd\xee\xfc\xbb\x7a\x3e\xbc\x92\xbf\xd3\xdd\x86\xec\xdf\x8e\xfb\x57\x2c\xd7\x87\x74\xb7\x59\x1e\x56\xff\xa4\xfb\x73\xfc\x38\x1e\xf0\x9c\xbe\x2c\x8f\xeb\x03\xb6\xc7\xc3\xfb\xf1\xc0\x3c\x9f\x86\x31\x7e\xbe\x2e\x37\xbf\xd2\xe7\x8b\x56\x0b\x9f\x6e\xf5\xff\x6f\x5b\x00\xc5\x6d\x0b\x19\x32\xf6\x2f\x65\xff\x9e\xd1\x36\xfb\x1e\x10\x7f\xce\x07\x9c\x21\x43\xfe\xf5\x13\x9e\x90\xff\xf9\x13\xf8\x53\x0e\xe4\x43\xf9\x97\x34\x63\x88\x1c\x99\x02\x17\xec\x1b\xf1\x19\xe2\x33\xd8\x6a\x34\x2b\x26\xe7\xf3\xb2\x8c\xe6\x06\x74\x6e\x6e\x5b\x20\xa0\x84\x7f\x29\x2d\x01\xe5\xb6\xd0\x36\x01\xe1\xab\x13\x90\xfc\x3b\x10\x4a\x0a\xc3\x4b\xe3\xa9\x84\x26\xa0\x19\xe5\xd3\xbf\xb0\x8f\xdc\x88\x84\xb2\xff\x32\x94\xd3\x50\xc6\xe4\x2c\x77\x38\xe3\x0b\x7d\x82\x12\x13\x50\x9a\x2f\x09\xc2\x43\x87\xf2\x81\x84\x26\x6c\x0c\x5b\x99\x2d\x80\x84\x3b\x96\xc7\x57\x3c\x08\x25\xaa\xd7\x94\x24\x34\x37\x0b\x37\x39\x00\x91\xe6\x14\x61\x2d\x83\x5a\x84\x54\x09\x22\xa0\x79\x2d\xbf\x30\x78\x52\xec\x58\x1e\x1c\x81\x46\x05\x56\x7d\x47\x75\x9c\x4a\x66\xc8\x30\x88\x38\x40\xec\x09\xf3\x4e\xc3\x11\xc1\x00\x01\x0f\x47\x86\xb3\x36\x0f\x48\x42\x29\x29\xcd\x2f\x63\x4f\x78\x3e\x2a\x59\x59\x6e\x69\x11\x83\x76\x65\x55\xe9\x85\x32\x90\x72\xf7\xb8\x79\x19\x45\x22\xdc\x25\xd5\x81\xe0\xe6\x65\xc5\x56\xd2\x4a\x78\x35\xf3\xc4\xfa\xa0\x22\xa5\x6d\xb0\x22\x59\x0b\x03\xc1\x07\x26\xf5\xf5\xcb\x8d\x00\x8f\x8a\x9c\x53\x8d\x65\x65\xfd\x33\xd0\xdc\xff\x46\xd8\xea\xba\xe7\x62\x9b\x94\x88\xdf\xea\x5b\x6b\xd8\xe6\xfa\x9f\xab\xd9\xa4\x72\xe1\x06\x37\x05\x09\x2a\x39\x6c\xcc\xb8\x4c\xdf\x33\x8d\x34\x5f\xf0\x45\xb2\xa5\x55\xdf\x00\x11\xf8\xdc\x21\xf6\x3c\xa3\xed\x5a\xda\x95\x89\xc7\x46\xf3\x70\x10\xd0\xbf\xf2\x30\x27\x2c\x68\xe7\x54\xe6\x21\x2d\x59\x29\x19\x07\x42\x93\x02\x40\xcc\xa7\x44\xf1\xae\x9e\x14\x3c\x36\x68\x48\x0a\x5a\x58\xc4\x53\xfc\x4c\x7c\x93\xa8\xd1\x28\x61\x39\x6e\x41\x9c\xac\x0d\x19\xba\x1a\x71\xb4\xcc\x04\xcd\x60\x8a\xb2\x7d\x60\x56\x27\x6e\xdd\xda\x82\xb8\x35\x6b\xcb\xb3\x44\x10\x97\x45\x5d\x30\x38\x33\xf9\xc6\xb9\x46\x65\x69\x34\x5b\x0b\x01\x0b\x2a\xeb\x81\xc4\x37\x57\x0f\x9e\x90\x19\x4b\x50\x5e\x9e\x3f\xf3\xa4\xcc\x68\xa6\x6e\x9c\x1c\x5d\x50\x5f\x7e\x28\x73\xb4\x6e\xb2\x24\x75\x96\x97\x69\x69\x4d\x42\x8a\x42\x05\xa8\x8e\xd6\x02\x93\x48\x0f\x2e\xfe\x92\x33\x12\x7d\x15\xa8\x59\x5b\xd4\x4b\x5a\x16\x4c\xd5\xe7\x5a\xfa\x25\xdc\xba\x3c\xed\x2c\x1b\xda\x84\xdd\x98\xda\x02\x1b\x02\xbb\x1c\xaa\xd5\x1b\x79\xb4\xda\xea\x2d\x55\x6a\x78\x51\x68\x21\x6d\x35\x9d\x68\x14\x65\x6e\x95\x59\x40\x33\x7b\x4c\xf2\x93\x3f\xcf\x04\x56\x4d\xc4\x09\x95\xe0\x49\xea\x86\xa4\x52\x59\xcb\x29\xea\xac\xf2\x68\x4b\x90\x90\x84\x28\x73\xb5\xe9\x0a\x82\x9c\x2d\x66\xb2\x53\x5d\xd4\x0d\x3d\xfb\x3e\x32\xd1\x18\x08\x79\xa8\x41\x3b\x73\xeb\x1c\x17\xbb\x96\xd5\x24\x4a\xc6\xc6\xca\xf5\xa5\xab\xc2\x4b\xe9\xa0\xbe\xb5\x62\xbb\x14\x11\x53\x1c\xce\x1c\x0c\x84\x67\x13\x49\xa4\x96\x50\x1f\xda\x39\xa0\x3f\x2b\xe7\x82\x76\xce\x80\x03\x56\xf5\x57\x39\x51\xca\x05\x59\xd3\x8b\x8a\x6e\x24\xb9\x8c\xca\x67\x99\x9b\x17\x4a\x72\x56\x94\x68\x91\xcc\x02\x35\xd3\xfc\x10\x25\x49\xa4\x60\xe3\xfa\x9a\x97\x04\x9d\xfc\x30\x4d\xea\x95\xae\xac\xb6\x99\xa0\x71\x66\xa6\x71\xa3\xff\xea\x01\xa1\xfb\x2f\x3e\x7c\x16\xdc\x37\xd5\xe5\xf2\xb8\x37\xc9\x2f\xe9\x79\x21\x12\x44\x36\x50\x22\x97\x55\x56\x95\x41\xcf\x9f\xa2\x1c\xd3\x5a\x72\xa1\x5c\xca\xb8\x60\xe1\x2c\x68\x69\x7f\xe1\x00\xad\x14\x5c\x2d\x3c\x38\xc1\xe1\xda\xf6\xd8\x04\x55\xd5\x90\x4a\x1e\x41\xe4\x51\xbe\x55\x27\xef\x11\xe7\x78\xd5\x08\x14\xc8\xd6\xad\x17\xc6\x2a\x17\xa5\xd2\x52\x3d\xf4\x50\xf2\x48\x4d\xe3\x9a\x47\xda\xd1\xcd\xe4\xa2\x25\x50\xcc\x1f\x5e\xb4\x9e\x44\xc9\xd2\x05\x25\xaa\x63\xcb\xe1\xca\x8c\xa4\x52\xb1\x2d\x0b\x24\xf9\x70\x52\x4b\x99\x66\xbb\x45\x79\xa2\xd5\x5b\x16\x8a\xca\xc9\x31\x75\x46\x57\xee\x32\x54\xde\xe6\xe4\x53\x5e\xeb\x0c\xd9\x5a\xe4\xac\xa9\xa4\xb2\x3d\x50\x70\xb8\x9e\xe7\xe5\x92\x64\xbc\x5e\x12\x59\x29\xab\x4f\x5d\x3c\x9c\xd1\xb6\xa0\x1c\xe9\x74\x12\xcb\x91\x52\x1f\xcd\x95\xaf\xbc\xea\x92\x7a\x65\x94\xc3\x4b\xce\x37\x1d\xab\xc6\x05\x9a\x4b\xaf\x1c\x4e\xa5\xf9\x52\x79\x9c\xb8\x40\x73\x4e\x2a\x0a\x55\x50\x31\xbb\xc9\xef\xd1\x6c\x5a\x95\x93\xce\xa0\x0b\x4c\xc3\xce\xd7\xc8\xf7\xfe\xc0\x7c\xe6\x8d\x7c\x73\x4f\xc4\x19\x38\x40\x30\x7d\xf2\xa3\xd8\x1f\xc3\xff\x73\x34\xf1\x1e\xbd\x38\x08\xa7\x78\xf4\xa2\x3f\x3e\xaa\x91\xce\xc0\x05\x46\xfe\x34\xc6\x3c\xb8\x9f\x96\xf9\x97\x65\xa2\x0a\xe4\xc5\x9f\x3f\x44\x6f\xc3\x19\xf4\x80\x59\xb8\x98\x8e\xcb\x39\x52\xa8\x51\x02\x9a\x14\x4a\x59\xac\x7c\x5e\x11\xa7\x1c\xa2\x0f\x8c\x16\x51\xe4\x4f\x47\xdf\x05\x0a\x23\x59\xbe\xf5\xb8\xe0\x49\x2f\x4b\x1b\x41\xa2\x96\x36\x67\x70\x09\x7c\xf7\xa7\x72\x71\x2a\x0b\x5c\xa9\x46\xb2\xfc\xbb\xac\xf2\x49\x2a\x14\x06\x30\x00\xbe\x46\xe1\x1f\xfe\x14\x5f\xbd\xc8\xd4\x54\x52\x69\xe2\x0c\x86\xc0\xdc\x1f\xe5\x21\x55\x1d\x16\x0c\x14\x79\x22\xe5\x48\x22\x5a\x22\x67\x54\xb0\xc7\x19\x5c\x01\xe3\xc0\xf3\x23\x7f\x1e\xcc\x8d\x1c\xf9\x24\x15\xc3\x27\x45\x83\x88\xc9\xd7\xc0\x28\x9c\x7d\x8f\x82\xfb\x87\x72\x8f\xac\x77\xc5\x8c\x87\x2c\x2f\x9e\xb2\x7a\xc9\xb3\xd5\x19\x76\x81\x3b\xff\x31\x98\x06\x53\x1f\x61\x34\x0e\xa6\xde\x04\xc1\x74\x1c\x8c\xbc\x38\x8c\x1a\x05\x4a\xfd\x82\xe1\x0c\x1d\x60\xe2\xdf\xc5\x9d\x59\x18\x4c\xe3\x60\x7a\x8f\x71\xb8\xf8\x3a\xf1\xe1\x4d\xef\x27\x3e\xfe\xb7\x08\xe3\x4a\x1a\x4a\x35\x98\x1b\x2a\xaf\xdf\xc5\x05\xbc\x5a\x1a\x9c\xa1\x8b\xbc\x1f\x58\xec\x71\xad\xe9\x50\x64\xf1\x27\x54\x9b\x0e\xce\xb0\x07\xcc\xc3\xbb\x18\x0f\xdf\x67\x0f\xfe\x54\x57\x49\x59\xd9\x40\x2a\x6b\xaa\x33\xec\x03\x91\x7f\x1f\xcc\x63\x3f\xf2\xc7\x1f\x04\x3a\x43\xa7\x2d\x02\x9d\x65\x49\x52\x0f\xf4\x25\xf0\xe8\x8d\xa2\x70\xda\xd4\xb8\xaa\xd6\x4e\x67\x38\x00\xc6\xfe\x7d\xe4\xfb\x85\xd7\xf9\x6a\x17\xbc\x1e\x92\xdb\xaa\xae\x74\x86\x43\x60\x36\x59\xcc\x3b\x8f\xc1\x74\x31\x57\x32\xb3\xa1\x01\x97\x0b\x10\x69\x0d\x97\xaf\xce\xf0\x0a\x98\x2f\x66\x7e\x34\x1f\x45\xc1\x2c\x46\xfc\x2d\x54\x45\x74\x5b\x3d\x7f\xaa\x21\xbb\xd6\x26\x3e\x44\xbe\xaf\x1f\x5d\x19\x15\xca\xab\x32\xf5\xaa\x0b\x78\xa3\x45\xec\xc3\x1b\xb1\xe2\xd3\x12\x27\x1a\x51\xdd\x54\x9d\xbd\x72\x80\xc7\x60\x14\x85\x4a\x99\xb2\x1c\xaa\x19\x2e\xce\x4b\x39\xc2\x67\xbb\xc0\x2c\x98\x8c\xa2\xf0\x9b\x9e\x51\x24\x4f\xa5\x3c\xc2\xc5\x55\x81\x6a\xaa\xcb\xb9\xea\xb1\xd5\xc7\xe3\x89\x8f\x71\x18\xb7\x60\xe8\x32\x56\x8c\x65\xc5\xcd\x1f\x07\x93\x89\x57\x8c\xad\x75\x27\xdb\xb4\x9d\x8f\xbd\xac\x06\x31\x9c\xfa\x5a\x57\x91\xea\x37\x0a\xe7\x6a\xc0\xd2\x6b\x3e\x5a\x4c\xec\x44\x36\xaa\x43\xbd\x5d\xe1\x5c\x0d\x81\xbc\xb2\x9c\x48\xe2\x82\x0e\x89\xda\xf6\x92\x8d\x2f\xad\xbd\xe1\x5c\x5d\x01\x4f\x8b\xc9\xbd\x17\xe1\x2e\xf2\x78\x01\x0d\xa7\x0c\xd5\x8b\x62\x3f\x2a\x9a\xe4\xa2\xe5\x9d\x11\x96\x68\x3c\xed\xd8\xc7\xcf\x7c\x3b\x72\x15\x52\xed\x53\x70\xf4\x6b\x33\xfa\x83\x37\xb9\x2b\xa1\x4b\xe4\x12\x58\xb4\x62\x29\x21\x54\x6f\x7f\x38\xd7\xdd\x3a\x6a\x9e\xd8\xd2\xea\xb9\x08\xaf\xb4\x9b\xe5\xb9\x62\x38\x6d\x97\x96\x1b\x4d\xe7\xab\xa8\x47\xf6\xff\x16\xfe\xbc\x5a\x28\x79\x9a\x88\x16\xa1\xb4\x5d\xbf\x81\x39\xd7\x2e\x30\xf1\xe2\x60\x8a\x91\x37\x0b\x62\x6f\x82\x89\x1f\xc7\x7e\x04\x0f\xdf\x82\xf8\x01\xf7\x91\xf7\xe4\xb7\xca\x08\xb3\x32\x2b\x6a\x99\x55\x93\x39\xd7\xbd\x66\xd0\x9c\xb5\xd5\x13\x50\x6c\x7b\x13\x68\xbf\x19\x74\x14\x44\xa3\xc5\xe3\xdd\xc4\xff\x33\x07\x94\x6a\x94\x24\xd9\x87\xc8\x97\xcd\xc8\x71\x30\x19\xfb\x1c\x94\x64\x02\xf4\x63\x73\x07\xcd\xa0\xcd\x87\x79\x13\xf0\xb0\x19\x38\x62\x04\xf4\xbe\x86\xf9\xb6\x15\x9a\xea\xec\xac\xdd\xfe\xd0\xe4\x2b\x1b\xb2\xdc\xac\x62\xbb\xce\xa5\x20\x62\xd5\x81\x4a\xa1\x9f\x51\x03\x17\xae\x2d\xa0\x23\xb1\x6d\x65\x8d\x3b\xa5\x51\xdc\x66\xf9\x7c\xdb\x72\xbb\x5d\x0b\xac\x5f\xcb\xdb\xdb\xa2\x3b\x9f\x21\xbf\x3c\x66\x94\xde\x94\xe7\x88\xdb\x75\x9a\xa1\x8a\x6c\x15\xca\x83\x57\x41\x33\x94\x8d\x4d\xbe\x21\x47\x2b\xed\x23\x0b\x9e\x8d\x48\xfe\x29\x49\xc4\x30\x21\x2e\x86\x37\x95\xaa\xea\x76\x6d\x64\x0a\xea\xb4\x97\xac\x57\x5a\xd7\xfa\x19\xe0\x76\x6d\x14\x0a\x6a\x31\xc4\x6d\xf9\x46\xc6\x8e\x67\x63\x4f\x60\x0a\xa4\x8c\x24\xe5\xa1\xb4\x82\xda\x98\x13\x18\xa3\x59\xbb\xc6\x65\x32\xd5\x39\x74\xf5\x1a\xe7\x76\x6d\xec\xf1\xe3\x87\xaa\x0a\xcc\x0a\x15\x98\x23\xb6\x8b\xdb\x3b\xad\x75\x08\xdc\xae\x8d\x3e\xd3\x0f\x6a\x53\xd9\x79\xaf\x35\xdc\x5d\xc7\x46\x9e\xd0\x5e\xf4\x8b\x4e\xb7\xe5\x6a\xed\x3a\x36\x1a\x85\x96\xa2\x2f\xcf\xfa\x46\x50\x1b\xa1\xc2\x53\x8a\x7e\x23\xb2\x8d\x5a\xe1\x07\x81\x6d\x04\xb5\xd1\x2a\x3c\x81\xaf\x8d\xc0\xec\x32\xb0\x98\xc4\xc1\x6c\xc2\xf4\x59\xe5\x16\x99\x1b\x95\xe4\xd7\x5e\xf1\x42\x3d\x21\x89\xd2\x1d\x73\x1d\x1b\x99\x84\x55\xf3\x98\xdd\x63\x6b\x37\x15\x49\x2b\x9c\x11\x22\x5f\x97\x30\xb5\x53\xcb\x51\xc7\xc6\xab\x45\x35\x9d\xca\x7c\xa2\x32\xa1\x9a\x7b\x2f\xae\x63\xe3\xd4\xc2\x90\x53\x45\x52\x9d\x84\x6c\xe3\xd5\xc2\x98\x58\x65\x66\x21\xc9\x4e\x80\x77\x6d\x0c\x5b\x34\x97\x9a\x93\x5a\x52\xae\x6b\xa3\xda\x77\x63\xb5\xcd\x63\xa2\xb6\x2f\xd5\x57\xfc\x39\x9e\x8d\x65\xf1\x43\x18\x4d\x4d\xed\x55\xde\xcf\xd7\x7b\xb5\xae\x5b\x90\x6a\xfe\xe8\x4d\x0a\x98\xf9\x83\x17\xcd\x30\xff\x8f\xcd\x2b\xd7\xed\x1b\xd1\x1a\x94\xe9\x47\x6f\x46\x5c\xf7\xb2\x09\xb2\xa9\x44\xd9\x21\x07\x4d\x90\x1f\x16\x28\x3b\xee\xb0\x09\xb7\xa9\x3c\xd9\x21\xaf\x9a\x20\x3f\x2a\x4e\x76\xd8\xeb\x26\xd8\x66\x3d\xda\x84\xdb\xeb\x9a\x71\x7d\xa5\xfc\xc8\xde\x5d\xb9\xf3\xc5\xab\xa6\xf3\xba\x1a\x75\x7b\x8e\x11\xb2\xae\x45\x1b\x5e\x89\xf1\x4b\xb7\xdb\x73\x8d\x50\x75\xfd\xa9\x0a\x28\xdb\x9b\x30\xb7\x67\x66\x4e\x5d\x82\xaa\xf2\xc9\x8e\x66\x66\x8e\x51\x85\x56\xc5\x93\x1d\xd2\xcc\x1c\xb3\x10\x35\x74\xc0\x3b\xe2\xb7\x2a\x89\x41\x3a\xf5\xcc\x14\xaa\x6a\x51\x2a\x2e\xb0\x89\xb1\x05\xed\xf6\xcc\x74\xd1\xf4\xa7\xd2\x20\x32\x61\x98\xf9\x71\x82\xe6\x2c\xde\x9a\xe8\xa5\xb5\x67\xe6\xc6\x89\x8a\xb3\xf1\x37\x02\x6e\xdf\xcc\x0f\xae\x37\x93\x84\x88\x5e\x32\x49\x12\x9d\x69\x5a\x93\xc5\xed\x9b\x69\xa1\x69\x4c\x56\x6a\x20\xdf\xe0\xa0\xf9\x25\xa3\xdb\x37\xd3\xc3\xa0\x30\x2b\xf4\x30\xbf\x89\x74\xfb\x66\x7a\xe8\xd2\x52\xa7\x87\x0d\xcd\x4c\x0f\x93\xa6\xac\xd1\xc3\x06\x69\xa6\x47\x58\x8f\xa0\xf2\x0a\xcc\x8e\x66\x26\x84\x59\x45\xfe\xb7\xd7\x4d\x6e\x7f\x08\x8c\x83\xa7\x60\xae\x8a\xc8\x6a\xb7\xa8\xb8\x39\x69\x3f\x30\x73\xfb\x66\x82\xd4\x74\xa4\xfe\x7e\x99\xf0\x97\x32\x84\x68\x6e\x9a\xc9\xb1\xf8\xe0\x80\x6f\x78\x3d\xe6\x5e\x9a\x39\x61\xd2\x8b\xea\x01\xdf\x08\x69\x26\x87\x59\x28\x6a\x07\x7c\x23\xae\x99\x21\x66\x85\x78\xf2\x0b\x42\xf7\xd2\x4c\x15\x5d\x1a\x36\x46\xa0\xfa\x3e\xd9\xbd\x34\xf3\x45\x55\x87\x30\xff\xda\xa4\xf6\x2b\x01\xf7\xd2\x4c\x94\xef\xff\xd5\xeb\xaa\x89\xff\x0f\x00\x00\xff\xff\xde\x17\x3d\x84\xc8\x2f\x00\x00") + +func fontsSmallFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmallFlf, + "fonts/small.flf", + ) +} + +func fontsSmallFlf() (*asset, error) { + bytes, err := fontsSmallFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/small.flf", size: 12232, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmisome1Flf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x98\x5f\x4f\xdb\x3c\x14\xc6\xef\xfd\x29\x1e\x21\xa4\x17\xa4\x26\x6e\x51\x79\x01\xe7\x26\x17\x88\x8d\x2d\x70\xc3\x2e\x23\x59\x69\xeb\x74\x11\xad\x8d\x92\x14\xd6\xc9\x1f\x7e\x72\xfe\xba\x14\x41\x29\x99\x34\xa1\xa4\x17\xb5\x1b\xe7\xe7\xe7\x39\xc7\x76\x4f\x1b\x2f\xe2\x93\xe8\x10\x67\x38\xc3\xe8\x1c\xce\x08\xa3\x73\x92\x2d\x93\x4c\x2d\xc5\xc8\x8d\x17\x31\xb9\x54\x4f\x32\x4b\x7e\x8b\x19\x1e\x45\x9a\x25\x4a\x42\xc5\x28\xee\xe7\x69\x32\x2d\xc6\xc0\xc1\x8d\x8b\x20\x91\xb3\x4c\xac\x71\xb4\x9c\x2f\x8a\xa6\x2f\xd7\xbf\xdc\x69\xe6\xce\x56\xae\x98\xad\x8e\xc9\x95\x98\xa4\xab\x28\x5d\xe3\x64\x3c\xc0\xe8\xe2\xe2\x7f\xe2\x38\x0e\xd9\x44\x11\x72\x95\xcc\x17\x22\xc7\x54\xc9\x7a\xbe\xc9\x1a\xdf\x85\xcc\x71\x1b\x65\x99\x90\x38\xba\x17\x32\x97\xfe\x74\x3d\x11\x69\xf6\x10\x4d\x85\xab\xd2\xf9\xf1\x00\xe7\xce\x68\xe8\x5c\x8c\x07\x98\x44\x99\x98\x11\x25\x91\xff\x14\x88\x95\xcc\x33\x3c\xa8\x2c\x17\x33\x43\x0a\x84\x94\x22\xcd\x71\x97\xab\xe9\x3d\x23\xe4\x2a\x55\x4b\x86\xcc\xf4\xfc\xf8\x29\x71\x57\x8f\x91\x2b\x17\x38\xda\x18\x77\x4c\x2e\xa3\x5c\x30\x8c\x4e\xf1\x6d\xb5\x30\xda\xc7\x18\x0e\xd9\x70\xcc\x4e\x4e\xf1\xe5\xe6\x07\x21\x5f\x45\x2a\x10\xa5\x02\xc6\x4d\x39\xa9\x8b\x5b\x25\x9d\xb8\xb4\x73\xfd\xdf\x12\x51\x9c\x46\xc9\x6c\x80\x24\xc6\x5a\xad\xf0\x14\x49\x19\x55\x3e\x73\xa3\x75\x39\xc0\x44\x90\xe5\x1a\xf3\x95\xc8\x72\x17\xd7\xb5\x6c\xe3\xa3\x09\x53\xe5\x68\x22\x62\x95\x0a\x97\x98\x18\x76\x78\x11\x3c\xbf\x9a\x5b\x08\x20\x20\x21\x21\x90\x22\x07\x70\x87\x1c\x0a\x53\xdc\x6f\x3d\x03\x6c\x73\xb6\xae\xad\x98\x37\x13\x35\x90\x43\x00\x87\xfe\xee\x6f\x3e\xd9\x78\xf5\xdd\x4f\xd7\x35\xcb\x82\x73\x0e\xa0\x68\xd3\x10\x08\xcb\x36\x65\xac\xe8\xf8\xa4\x68\xb2\x90\xf3\xd0\x27\x08\x69\xc8\x18\x05\x68\x39\xbe\x68\x96\xcf\x86\x94\x73\x0a\xec\x05\x65\x16\xb4\x6a\xee\x09\xa5\x36\xb4\x7c\xbc\x84\x9a\x4f\xd1\x05\x94\x76\xa4\x74\xd3\x7e\xd8\x42\xc3\x6e\xa0\x46\x74\x6d\xbf\x26\xf9\xd6\x39\xb2\xa7\x7d\x66\xc5\x74\x37\xfb\x4d\xe0\x29\x33\x83\x78\xad\x94\x76\xb2\xa4\x78\xd8\x2a\x0d\x0d\xb6\x56\xca\xe8\xfe\xd9\xdf\x09\x5a\x72\xde\x8c\xa9\x6d\x1f\xad\x7d\xe7\xa0\x86\x7a\xcc\x73\x0e\x06\xce\x81\x19\xa3\x99\x06\x74\xad\x54\x73\xae\x77\x80\x82\xa2\x4a\x54\xa3\xa8\xd2\x5f\x8e\xd9\xd5\xbe\x05\x65\x01\x0f\x2a\xa5\x34\x68\x97\x14\xa7\xef\x4e\x94\x05\xd5\xe0\xba\xb6\xaf\xdb\xec\x6b\x2b\xfb\xba\xb3\xbd\xff\x17\xb6\xe9\xc6\x3a\xfd\xc0\x8e\x2a\xb7\x51\x09\x6d\xe4\x75\x7a\x9e\x7a\xac\x85\x6a\x66\x29\x7d\x65\x49\xbd\x08\x0d\x9f\x9f\x52\xef\xdc\xfb\x0d\x14\xed\x8e\x2a\x67\xa8\xec\xd3\xce\x76\x14\xe5\xf4\x23\xd9\x7f\x09\xaa\x19\x0b\x6a\xa8\x66\x56\x4c\x03\xcf\xdb\x29\xfb\x36\xb4\xe8\x94\x4a\x19\xb5\x0e\x94\xfd\x95\x1a\x79\x9c\x07\x55\xf6\x99\x9d\x7d\xaf\x8e\xa9\x66\xac\x48\xf9\x3e\xd0\xc2\x73\x9b\x28\xcf\x7b\x6f\xa2\x5e\x3c\x4f\x6d\xa5\xcc\x86\x7e\xe8\x2b\x3a\xb8\x6b\xa0\xe6\xe7\xc4\x1b\x31\xed\x2b\xa8\xbe\x82\xea\x2b\xa8\xbe\x82\xf2\xfb\x0a\xaa\xaf\xa0\xfa\x0a\xaa\xaf\xa0\x3e\x73\x05\xf5\x8f\xfc\xd5\xf4\x7a\xf7\x4f\x00\x00\x00\xff\xff\xf4\x63\xd4\xfe\x38\x17\x00\x00") + +func fontsSmisome1FlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmisome1Flf, + "fonts/smisome1.flf", + ) +} + +func fontsSmisome1Flf() (*asset, error) { + bytes, err := fontsSmisome1FlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smisome1.flf", size: 5944, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmkeyboardFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\xd5\x7f\x7f\xdb\x34\x13\x00\xf0\xff\xf5\x2a\xae\xcf\x53\x20\xa6\xb1\x9d\x64\x59\xbb\x9a\xad\xa4\xa5\xeb\x16\xba\x66\xa3\xc9\x80\x81\xc1\x28\xf6\xc5\xf1\x62\x5b\xc6\x52\x1a\x32\x0c\xaf\x9d\x8f\x1d\x39\x4d\xba\x6e\x17\x86\xfa\xc9\xc9\x96\xbe\x27\x4b\xf2\x8f\x4e\xe2\x49\x87\xef\x43\x17\xba\xd0\x3e\x84\x36\x3c\x3c\x62\x4c\x26\x33\x5c\x8e\x05\xcf\x03\x6b\x12\x4f\x18\x3b\x0d\x78\xa6\x30\x80\x89\xc8\x61\x12\x85\x31\x2a\x18\x2f\xe1\x12\x53\x05\x03\x2e\x25\xa6\x4d\x98\x61\xaa\xd2\x9e\xbf\x1c\x63\x2e\x33\xee\xa3\x25\xf2\xb0\x09\xed\xb6\xdd\xe9\xd8\xc7\xdd\x26\x8c\xb9\xc4\x80\x89\x14\xd4\x14\x21\x0a\x90\x3b\x8c\x5d\xe4\x22\x71\xca\x9e\x5e\xc0\x13\x9c\x59\x33\x35\xb5\x24\x42\xe3\x8c\x4b\xb8\xc2\xe8\x2d\xe6\x06\x1b\xe0\x42\x86\xb9\x98\x67\xd2\x81\x1c\x7d\x8b\xe7\x4a\x5a\x5c\xfa\x51\xc4\x86\xf3\xf1\x5b\xf4\x95\x03\x23\x1e\xcf\xcc\x38\x4a\xd1\x81\xad\x79\x9f\x73\x85\x0e\x74\x3a\x30\x10\x37\xd0\x3e\x3e\xee\x42\xeb\xc8\xe9\x1c\x3a\xed\x16\x98\xad\xc3\x56\x8b\xbd\xcc\x43\x9e\x46\xef\xb8\x8a\x44\xea\xc0\xb5\x58\xf2\x18\xfa\xa9\x54\x91\x9a\x2b\x04\x31\x81\x11\xfa\xd3\x54\xc4\x22\x5c\xb2\x17\x51\x8a\xd2\x81\x6e\x9b\x0d\x31\x0d\x30\x77\x60\x2c\xc6\xbc\x17\xf2\x30\x41\x6b\xb1\xe0\x96\x2f\x12\x76\x9a\x65\xb9\xb8\xc1\x40\x77\xd6\xcd\x57\x28\x25\x0f\xd1\xec\x9f\x3b\xf0\xf8\x01\x97\xf9\x34\xda\xf7\x45\xba\x9d\x7c\xc2\xae\x71\x82\x39\xa6\x7e\x79\x9d\x92\xc5\x2a\xdb\xe7\x22\x7c\x9f\x65\xf1\xd2\x1c\x89\xf7\xb7\x8e\x0d\x06\xa3\x57\xe6\x2b\x21\x55\x94\x86\xe6\x73\x21\x95\x03\xdb\x13\x64\xac\x9f\x02\xcf\x55\xe4\xc7\x08\xef\x8d\xdd\x04\x29\x27\x51\xa4\x7a\xbe\xb4\xe6\xc9\xd8\xc2\x60\x0e\x8d\xe1\x3c\xc3\x7c\xa8\x72\x44\x75\x11\x85\x53\x85\x79\x67\x34\xcf\xc7\xc2\x80\x45\x1e\x29\x94\x0e\x3b\x01\x76\x02\x7d\x98\xf2\x1b\x04\x5f\x24\x99\x90\x18\x00\x87\x14\x17\xf5\xd3\x32\x11\xa9\xda\x83\x27\x06\x3b\x81\x48\x41\x24\xc1\xe7\x71\x8c\xc1\xd6\xed\xb2\xa0\xaf\x20\x47\x89\xc9\x38\xc6\xea\x31\xe1\xbe\x9a\xf3\x78\x8d\x9a\xb0\xc0\x38\x6e\xc2\x2c\x4a\x03\xae\x47\xe3\xe9\x72\xc1\x97\x7b\x30\xc5\x1c\xcb\x71\x39\x48\x9e\x64\x31\xea\x6e\xf0\x56\x65\xd7\x9a\x9d\x40\xe1\x42\x59\xec\x9d\xeb\x32\x07\x0e\x4c\xd3\x3c\xd8\xbd\xae\x72\x0a\x80\x2a\xee\x58\xaf\x72\xa4\x6e\xe3\xba\x4e\x74\x9d\xe9\x3a\xd6\x35\xde\xe6\x7c\xc2\xdc\xec\x6a\x37\xdc\x9d\x6b\xc6\x60\x73\x1b\xf5\xd1\x9d\x40\x74\xb0\xa2\x38\x85\xa2\x28\x60\x55\x8a\xa2\x38\x2b\x43\xbf\x0c\xa3\xed\x8e\xea\xf4\xe5\x3a\xac\x3b\x58\x51\x78\x5e\x51\x86\xaa\x14\xeb\xd3\x62\xe7\x0e\x56\xae\xa9\x5e\x98\x3e\xba\x13\xa8\x8e\xea\x41\xda\x9c\xfd\xb3\xed\xd9\x57\x6d\x17\xdb\x6d\x6f\xd6\x8b\x79\xfd\x81\x15\x7d\x7c\x09\xbb\x2f\xeb\xe3\xeb\xa0\xd6\x56\xdf\xa4\x61\x19\x2e\xb7\xd7\x70\x55\x86\xa7\x65\xd8\xdb\xee\x70\xca\x60\x94\xe1\x1a\xd5\x3c\x4f\x77\x5f\xd6\x07\x3a\x6e\x77\xe7\xdf\xdf\x9d\x8d\xb6\xb8\x1e\x06\xfe\x4b\x89\x8b\x7a\x8f\xcf\xb8\xb4\x3e\x79\x98\x8d\x77\x89\x61\xc2\xa3\xf8\x9e\xff\x8c\x65\xa9\xde\x15\x1d\xcb\x72\x39\x7a\xde\x84\x73\xcc\x94\x55\xfe\xc3\xba\xe2\xfe\xd4\x82\x73\x94\x51\x98\xb2\xf5\xd7\x0d\xd6\x39\x75\x96\x5d\x06\x77\x15\x6f\xdf\xc1\x7b\x0a\x6b\xe8\xf9\x55\x78\x95\x51\xe6\xd4\x63\xd4\xc5\xd5\xb5\xb1\xf1\x5b\x57\x2e\xd3\x1f\x31\xdd\x50\x62\xd7\xf3\x3c\xe3\xce\x20\x55\x8f\xeb\x79\xb6\x0b\x60\xbb\xb7\xa7\x75\xee\x6a\x18\x00\x68\xac\x1a\x5c\x4f\xe7\x34\xea\xd6\xfa\x8a\x06\x80\xe1\x95\x0d\x46\x79\x91\x92\x18\x5e\x9d\xbb\x39\x99\x6a\x00\xc3\xd5\x29\xab\x45\xe8\x2b\x56\x73\xb3\x57\x6b\xd6\xdf\x7a\xd0\x87\xd5\x8f\x35\xf4\x16\xd9\x9e\x5d\xe5\xac\x4e\x6e\x37\x43\x6f\x56\xfd\xe8\x19\xfa\x67\xaf\x4f\xed\x6a\x0f\x3e\xf6\xf4\xb9\xd5\x90\xab\xc8\x14\xc6\x96\x03\x07\xdd\x43\xb3\xd1\x32\x1e\x99\x47\xc7\x2d\x38\x7c\xd0\x7a\x74\x6f\xe2\xd0\x6c\xb7\x5a\xd0\xed\xc2\x50\x09\x7f\x36\x15\x71\xd2\x84\xe1\x02\x03\x4c\x19\xdb\xf8\xe6\xf6\xd8\xc6\x7b\xda\x63\x1b\x6f\x5b\x8f\x6d\xbc\x33\xbd\x9e\xfe\xbe\x97\x64\x6f\x4d\x6b\x75\x07\xfc\x8f\x02\xff\xa7\xc0\x3e\x05\x3e\xa3\xc0\xe7\x14\xf8\x82\x02\x0d\x0a\x18\x14\xf8\x92\x02\x07\x14\x68\x52\xc0\xa4\x80\x45\x01\x9b\x02\x2d\x0a\xb4\x29\xd0\xa1\xc0\x03\x0a\x74\x29\xf0\x90\x02\x87\x14\x38\xa2\xc0\x23\x0a\x1c\x53\xc0\xa1\xc0\x57\x14\x78\x4c\x81\x27\x14\x38\xa1\xc0\xd7\x14\xe8\x51\xe0\x94\x02\x67\x14\xf8\x86\x02\xe7\x14\x78\x4a\x81\x0b\x0a\x3c\xa3\xc0\x73\x0a\xf4\x29\xf0\x2d\x05\x2e\x29\xf0\x82\x02\x57\x14\x18\x50\xe0\x25\x05\x5e\x51\xe0\x3b\x0a\x5c\x53\x60\x48\x81\x11\x05\x5e\x53\xe0\x7b\x0a\xfc\x40\x81\x1f\x29\xf0\x86\x02\x3f\x51\xe0\x67\x0a\xb8\x14\xf8\x85\x02\xbf\x52\xc0\xa3\xc0\x6f\x14\xe0\x14\x18\x53\xc0\xa7\x40\x40\x01\xa4\xc0\x84\x02\x21\x05\xa6\x14\x88\x28\xf0\x96\x02\x33\x0a\xc4\x14\x48\x28\x90\x52\x40\x50\x20\xa3\xc0\xef\x14\xc8\x29\x20\x29\xa0\x28\x30\xa7\xc0\x0d\x05\x16\x14\xf8\x83\x02\x4b\x0a\xbc\xa3\xc0\x9f\x14\x28\x28\xf0\x17\x05\xfe\xbe\x1f\xe8\xbf\x4f\x3d\xf8\x27\x00\x00\xff\xff\xd7\x48\x84\xb7\x84\x16\x00\x00") + +func fontsSmkeyboardFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmkeyboardFlf, + "fonts/smkeyboard.flf", + ) +} + +func fontsSmkeyboardFlf() (*asset, error) { + bytes, err := fontsSmkeyboardFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smkeyboard.flf", size: 5764, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmscriptFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x5a\xff\x6f\xe2\xb8\x12\xff\x9d\xbf\x62\x7e\x40\x3a\x78\x0f\xd6\x24\xa5\x5f\x90\x56\x2b\xb2\x90\xb6\xd1\xd1\x84\x0b\x61\xf7\x56\x8a\xe4\x47\xb7\x69\x8b\x8e\x42\xc5\x97\x3b\xad\xe4\x3f\xfe\x29\xf6\xd8\x8e\x13\x07\xe8\xdd\x89\x90\x92\x99\x8f\xc7\xe3\xcf\x8c\xc7\x93\x7d\x5e\x3d\xbb\x8b\x26\x5c\x42\x1f\x9c\x0b\xe8\x81\xd3\x83\x1e\x5c\x0c\x7a\xfd\xc6\xec\x6d\xf6\x73\xbb\x7c\xdf\xc3\xe3\x2f\xb8\x5b\x65\xeb\x35\x8c\x5e\x17\xef\xef\xd9\x6a\x05\x7d\x32\xb8\x80\x6e\x17\x1e\x17\xbb\xec\x09\x36\x6b\x10\x92\x8d\x60\xfd\x73\x75\x78\xca\x76\x10\xcc\x22\x98\x2c\xf6\xcb\x75\xd7\x69\x3c\x2f\x5f\x56\xd9\x1e\xb6\xd9\x2a\x5b\xec\x32\x70\x3f\x39\xb9\xaa\xe3\x82\x77\x78\x01\x67\x30\xe8\x37\xa6\xd9\xf6\x6d\xb9\xdb\x2d\x37\x6b\x58\xee\xe0\x35\xdb\x66\x8f\xbf\xe0\x65\xf9\x77\xb6\x86\xfd\x06\xde\x36\x4f\xcb\xe7\x5f\xb0\x7f\x5d\xee\xe0\x79\xb3\xde\x77\x60\xb1\x83\xd5\x66\xfd\x92\x7f\xef\x5f\xb3\x06\x17\x58\x66\xdb\xdf\x76\xb0\x5e\xbc\x65\x39\xc6\xfb\x6a\xf1\x53\x58\xb6\x80\x9f\x9b\xb7\xb7\x6c\xbd\x87\xd5\x72\x9d\x7d\x6a\x34\x1e\x84\xf4\x53\x3e\xad\xe9\xe2\xb0\x82\xaf\x87\xed\x7e\xb3\x86\xcf\xbb\xcd\xea\xb0\x5f\x6e\xd6\xc3\x6c\xb1\xdd\xbf\xae\x96\xeb\xbf\x3e\xad\xb3\xfd\x17\x70\x5c\x32\xb8\xca\x0d\x59\x8a\xd9\xc1\x3a\xfb\x07\xde\x17\xdb\xc5\x5b\xb6\xcf\xb6\x8d\xdd\xe1\xfd\x7d\xb3\xdd\x0b\xc0\xdb\xe0\x2e\x9f\xeb\x62\xfd\x94\xdf\x7e\x5f\xae\x3f\x01\x3c\x2c\x7e\xc1\x62\xb5\xdb\xc0\x63\x06\xbb\xd5\xf2\xe5\x75\xbf\xfa\x05\x6f\xd2\x8a\xe7\xcd\x16\x1e\xb3\xfd\x3e\xdb\xc2\x61\x97\x35\x36\xcf\x1c\xfe\xf9\xb0\x5a\x75\xff\x59\x3e\xed\x5f\xc9\x5f\xd9\x76\x4d\x76\x6f\x87\xdd\x2b\x2c\x56\xfb\x6c\xbb\x5e\xec\x97\x7f\x67\xbb\x0e\x3c\x1e\xf6\xf0\x94\x3d\x2f\x0e\xab\x3d\x6c\x0e\xfb\xf7\xc3\x3e\x9f\x79\x18\x25\xf0\xf3\x75\xb1\x7e\xc9\x9e\x3e\x35\x1a\x4d\x68\x0e\x6d\x97\x61\x03\x60\xd8\x00\x86\x9f\x0d\xff\x3b\xbf\xc9\xef\x58\xfe\x53\x2e\x89\x17\xfe\x84\xff\x37\x6c\x00\x65\x94\xd1\xc2\x37\x30\x60\xa0\x9e\x17\x04\x01\x05\x5a\x8c\x32\xa9\xd8\x56\x0a\x05\xc1\x56\x1b\x88\x40\x20\x42\x91\x40\xab\x5d\x42\x14\x62\xc3\x06\x90\x94\x0c\x1b\x90\x92\x14\x7f\x47\xe3\xf3\x1f\x9b\xf8\x41\x1d\x8e\x94\xcf\x06\xe4\x05\x52\xf5\x24\x15\x16\xca\x0b\x31\x2d\x4f\x19\x37\xa8\xdb\xfd\x4f\xb7\xcb\x61\x58\x6a\x9f\x22\x30\x10\x82\xff\x15\x82\xf8\xb7\x16\x2c\x7c\x84\x99\xf8\x54\x7f\x75\xbb\xa8\xda\x54\x3f\x5a\x14\x0b\x7e\x10\xb3\x12\x2e\x23\x12\x49\x3c\xa6\xd2\x7f\xa9\x98\x33\xce\x30\xa5\xc4\xb4\xaa\x93\xab\x32\xc3\x03\xf8\x84\x0a\xd4\xb6\x1e\x81\x52\x3d\x02\xa5\xe2\x2f\x4a\xb9\x09\x4d\xc8\x57\x21\xc5\xbf\x4a\xbe\x61\x80\x9e\xa7\xc8\x13\x28\xf3\x44\x80\x31\xca\xc7\xac\x03\x13\x0f\x09\xff\x62\x84\xcb\xe4\xf3\x29\xc8\x48\xa3\xa0\x49\x90\x44\xc2\x78\xc3\x9d\x62\x90\x16\xa5\x6d\xe1\x35\xdb\x58\x14\x27\xcf\xfd\x91\x52\xe1\x20\xe9\x1d\xbd\x2c\x1b\xa4\x99\x5e\x96\xd2\x8f\xc4\xe4\xdf\x67\xa4\x5e\x31\x90\xb4\xd9\xda\x7a\xc3\x5e\xcd\xd1\x2f\x82\x9e\x0d\x35\x5b\x71\x8f\x91\x94\x5f\x37\x26\x07\x28\x55\x34\xa0\xb4\x83\x4c\x20\x3c\xec\xf8\x6d\x3e\x33\x01\x98\xe6\xb2\x44\xe9\x75\xa4\x1a\xb2\x98\x69\x3e\xa7\x94\x68\xa7\x2b\x16\x21\x5b\x18\xa1\x68\x8d\x98\x25\x6b\x69\x51\x89\xdd\x54\x81\x8d\xc8\x4d\x50\x26\x68\xdc\x5c\xba\x29\xed\x6f\xe5\x78\x80\xc0\xdc\xf6\x56\x4a\x0b\x4c\x96\x8b\xd6\x14\xab\x26\x90\xbf\x74\x05\xb0\x81\x2b\x61\xb9\xa7\x5b\x6d\x60\x54\xa4\x35\x22\x5c\x02\x2d\xa2\x23\xb2\x14\xe0\xb9\x34\xb7\x3c\xe5\x74\x20\xad\x4a\x28\xa1\x24\x91\x7c\x07\xd6\xed\x32\x69\x36\x6b\xdb\x61\x41\x24\x14\x0a\x62\x25\x72\xf7\x92\x72\x82\x11\x89\x47\xb8\x8b\xc9\xb4\xc4\x6d\x62\x6a\xe8\x8e\x18\x9a\x22\xdb\x59\x2a\x53\x2f\xa4\x25\xb7\x72\x8f\x8b\xb1\x58\x5b\x27\x2f\x31\xc9\xb4\xbc\x08\xd0\xa1\x79\x32\xc1\x89\x31\x49\x83\xf2\x6d\x91\x12\x05\x77\x20\x2b\xb4\x31\x5a\xc9\xd4\x91\xec\xc0\xc9\xa6\x34\x25\xc8\x3b\x99\xb8\x2a\xeb\xad\x49\x87\x64\x43\xd3\x99\xdc\xab\x0c\x58\x04\xa6\x14\x6d\x61\x79\xe8\x2b\x4e\x97\x48\xad\x07\x50\x23\x80\x1c\xa2\xd6\xab\x8a\x26\x62\x06\x20\x48\xd2\x2e\xc4\xb2\xc1\x3c\xf4\x7c\x13\x6f\x6a\x98\x07\x2a\x00\x0a\x9e\x53\xca\xe5\x60\x2c\xea\xa1\x1a\x53\x4e\x51\x4a\xc6\x48\xc6\x50\x5a\xab\xa4\x58\xd0\x2d\xa9\x57\x07\x4d\x75\xca\xfd\xf2\x19\x33\x1c\x01\xa8\x66\x0d\x73\x40\x35\x18\x0e\xc4\x50\x5c\x72\x1c\xd7\x02\xda\x85\xa4\x4e\x70\xc9\x95\x8c\xb1\xc9\xe3\xa6\xa3\xf7\xcb\x14\x97\x1b\x87\xd0\xb9\x92\x9a\x35\x00\xbf\x50\x36\xe4\x45\xc6\xd0\x28\x80\x9a\xe5\xe4\x5d\xfe\x6a\xaa\x8c\x8e\x7b\x40\x5a\xad\x47\x50\x16\xd3\x2c\x41\xef\xa6\x84\x95\xb3\xa5\x60\x6a\x1b\x09\x9b\xf2\xed\x21\x25\xe6\xf6\x80\x58\x08\x25\x53\x9e\x6d\x1f\x06\xca\x4e\x0e\x38\x94\x3b\xbf\x48\x47\x4a\x40\x3f\x16\xf9\xaa\xf8\x98\xb5\x4d\x53\x3a\x72\x10\x31\x86\xb1\x42\x85\x39\xe1\xa4\x54\x89\x50\x32\x25\x77\x9f\x5e\x45\x52\xf4\xfb\x50\x6d\x75\x48\x1b\x22\x58\x64\x73\x1a\xee\x32\x69\xc9\x21\xd6\x89\x54\x03\xaf\x70\x4b\x58\xfe\x3f\xbf\x6d\xd6\xa4\x3c\x53\x0b\x75\x94\x46\x4d\xc2\x90\x2b\xc7\x57\xb7\x50\x9f\x99\xbb\x84\x4c\xa0\x48\x02\x26\xe4\x78\x5e\x38\x8f\x53\x85\x45\x02\x4c\xeb\xc8\x18\xee\xc3\x66\x75\x01\x50\xae\x68\x5e\xd3\x4a\x3e\xca\xa8\x8c\x5e\xb4\xad\x3c\x05\xc3\x29\x2a\x9d\x34\x0d\x02\x5a\x27\xcc\xf3\x10\x0e\x0c\x65\xf3\xaa\x6b\x24\x33\x17\x6a\x14\x95\xac\x51\x4b\xc4\x7c\x9a\xa4\x4c\x8f\x8a\x11\xd2\x5e\x21\x57\x62\xb3\xdc\xb7\x48\x5e\x68\x71\x3c\xb9\x8c\x5a\x90\x5f\x09\xf7\x56\x81\xb9\xe2\x1c\xc2\x2a\x9f\x72\xca\x92\xe7\x2b\x2c\xf4\xd5\xe9\x07\x6b\xc5\xe2\x15\x4f\x42\x79\x84\xa0\x6d\x1d\xbd\xd2\x80\x25\x46\xc9\xed\x1b\x19\x4f\x72\x22\xb8\xff\x1a\xbb\xae\x30\x8a\x94\xf3\x7f\x69\x7b\xb2\xef\x49\x1b\x65\xcd\x89\x9c\xb7\x91\x86\x1c\x89\x0a\x3d\xb7\xb3\x28\x45\x31\x03\xf0\xeb\x67\x9d\xb5\xf8\x63\xe7\xaa\x07\x10\x46\xdd\xaf\xb1\xef\xfd\x0e\xb3\xa9\x37\xf2\x75\xba\xd6\x9f\x5c\xd0\x01\x08\xc2\x6f\x7e\x9c\xf8\x63\xf0\xff\x1c\x4d\xbc\x07\x2f\x09\xa2\x10\x1e\xbc\xf8\x77\x5d\xfa\xcb\x35\x14\xe0\x2e\xc0\xc8\x0f\x13\x98\x05\x77\xa1\x91\x88\xa9\xe1\x05\xaa\xa2\x14\xf5\x2e\x00\xa6\xd1\x3c\x1c\x2b\x45\x2a\x23\xed\x7f\x32\xd4\x40\x96\xc1\x05\xf7\x39\x57\x7d\x80\xd1\x3c\x8e\xfd\x70\xf4\x03\x75\x53\xa0\xf2\x98\x28\x36\x3e\xf4\x26\xd1\x5b\x20\xea\x5e\x02\xfc\xf0\x43\xa5\x86\x74\x4d\x29\x11\xa7\x13\x86\xc7\x13\xf3\x60\xeb\x5c\x5d\x01\x7c\x8d\xa3\xdf\xfd\x10\xbe\x7a\x71\xd1\x01\x9a\xcc\xce\xd5\x35\xc0\xcc\x1f\x71\x7f\xe1\x94\x78\x1d\xc4\x27\x91\x97\x48\x58\x27\x71\xd9\x1b\x80\x71\xe0\xf9\xb1\x3f\x0b\x66\x9c\x11\x3c\x3f\x35\x4b\x57\x29\x3d\x00\x18\x45\xd3\x1f\x71\x70\x77\xaf\xfd\x6c\x1e\x7d\x40\x1d\x7d\xb0\x88\x67\x82\xd9\xb2\xb2\xc4\xa3\x8f\x73\xdd\x03\xb8\xf5\x1f\x82\x30\x08\x7d\x88\xe2\x71\x10\x7a\x13\x08\xc2\x71\x30\xf2\x92\x28\x56\x5b\x5b\x4b\x1c\x63\xbb\xdd\x2e\x86\x5d\x81\x9c\xce\xb5\x03\x30\xf1\x6f\x93\xee\x34\x0a\xc2\x24\x08\xef\x60\x1c\xcd\xbf\x4e\x7c\xf0\xc2\xbb\x89\x0f\x7f\xcc\xa3\xc4\xa0\x0d\x5a\xc9\x8f\x87\x78\x3e\xd4\x85\x89\x73\xed\x02\x6f\xe3\x28\xfe\x14\xce\x7d\xac\x14\xf3\xce\xf5\x05\xc0\x2c\xba\x4d\xe0\xfe\xc7\xf4\xde\x0f\x75\xda\x01\x61\x6d\x45\xbe\x0f\x10\xfb\x77\xc1\x2c\xf1\x63\x7f\x6c\xf5\x5d\x47\xfb\x8e\x51\xe9\x3b\x60\xa9\xc5\x77\x97\x00\x0f\xde\x28\x8e\xc2\xea\x49\xd6\xfc\xc2\xc1\xaf\x00\xc6\xfe\x5d\xec\xfb\x38\xb0\x68\xf4\x58\x2a\x2d\xe7\xfa\x1a\x60\x3a\x99\xcf\xba\x0f\x41\x38\x9f\x95\x63\xa9\xd4\x78\xd1\x3c\x95\xda\x37\x00\xb3\xf9\xd4\x8f\x67\xa3\x38\x98\x26\x90\x7c\x8f\x64\xc1\xc7\x3b\x00\xb4\x34\xd8\xa0\x24\x7e\x1f\xfb\x7e\x03\x64\xbb\x83\x87\x84\x20\x6b\xd1\x95\x37\x3d\x00\x6f\x34\x4f\x7c\xf0\x46\x79\xc0\x9b\x6d\x28\x59\xfa\x39\x37\x0e\xc0\x43\x30\x8a\xa3\xe2\x24\xec\x99\x8c\xc9\x4c\xc6\xd4\x4c\x6e\x5c\x80\x69\x30\x19\xc5\xd1\x77\x15\x44\x54\x25\x12\xd1\xaa\xc0\x73\x2c\x30\xd5\xac\x10\xaa\x17\xf9\xc0\xe3\xf1\xc4\x87\x71\x94\x98\xcc\x68\x46\xcd\xca\x74\xf2\x34\xe2\x8f\x83\xc9\xc4\x6b\x48\x51\x79\x11\x05\x6e\x9b\x8b\x5d\x9a\xbe\x8a\x42\xbf\xda\x52\xd2\xae\xbd\xb9\xca\x29\x32\x1b\xcd\x27\xb5\xf1\xc5\x93\x02\x77\xaf\x85\xaf\x37\xd7\x00\x3c\xcc\x3f\x14\x5b\x29\x36\x4f\x78\xf7\x84\x14\xe1\x6e\x00\xbe\xcd\x27\x77\x5e\x0c\xb7\xb1\x27\x72\x53\x14\xe6\x30\x5e\x9c\xf8\xb1\x79\x84\x95\xa5\x35\x30\x22\xbb\x9d\xc4\xe8\x63\x21\xe6\xc0\x8e\x79\xef\x4d\x6e\xcd\x16\x01\xc1\x9a\x89\x80\x6c\xb1\x21\x15\x15\xd6\xa0\x57\xc5\xe2\x6c\x94\x16\xce\x38\x2d\xf5\xa6\x42\xa4\x91\x94\xb6\x95\x95\x15\x33\x05\x76\x71\x33\xfb\x63\xee\xcf\xaa\x29\xa9\x50\x60\xb7\x0a\x9d\x3f\x67\xe0\x02\x4c\xbc\x24\x08\x61\xe4\x4d\x83\xc4\x9b\xc0\xc4\x4f\x12\x3f\x06\x0f\xbe\x07\xc9\x3d\xdc\xc5\xde\x37\x9f\x9f\xb2\xe0\xec\x02\xc4\x19\x5c\x1c\x07\xe5\xb1\x25\x67\x73\x36\x68\xff\x38\xe8\x28\x88\x47\xf3\x87\xdb\x89\xff\xa7\x38\xb0\x7f\x00\xf9\xf2\x38\x72\x12\x4c\xc6\x7e\x03\x8b\xa5\xb3\x41\xaf\x8e\x83\x1a\x7b\xe2\x07\xaa\x3b\x67\x70\x7d\x1c\x38\xce\x23\xc9\xfb\x1a\xf1\x65\x93\xcd\x9e\x3c\x0c\x4f\x23\xdf\xd4\x21\x0b\x28\xda\xd1\xfd\x3e\x60\xba\xe5\x07\xac\xab\xba\x7e\xc4\x6c\xfc\x49\xe4\x41\x0d\xf2\x08\xd7\x4e\x67\xa7\x73\x5a\x8a\x7c\x2e\xc3\x86\xdb\xeb\xd5\xc0\xfa\x55\xf2\x0e\x75\x4f\xf1\x33\x15\xd0\x9f\x4b\xbd\x44\xb7\xe7\x1c\xc7\x2b\xf2\xf6\x2c\xbc\xba\xe0\xf2\x6b\x28\x7b\x16\x68\x5d\x70\xf9\x76\x62\x9d\x85\x59\x17\x5b\x81\xe9\x48\x79\x80\x39\xd1\xe6\x74\x7b\x75\x11\x15\x94\x1c\x29\x3b\xe0\xa7\xf0\xea\x82\x29\xb0\x38\x12\xbb\x75\xa7\x41\xeb\x02\x29\xa8\x38\x52\x1d\x64\x4e\x62\xd6\x85\x90\x9f\xdc\xe3\x06\x0f\xc5\x16\x78\x97\x75\xeb\x5a\xe0\x6e\xaf\x2e\x68\x42\x33\x2d\x75\x64\x5e\x3a\xb7\x35\xeb\x3a\x75\x71\x13\xd5\xc5\xcd\xd1\x73\xa4\xeb\xd4\xc5\x4d\x54\x17\x37\x27\xf0\xea\xe2\x26\x3a\x1a\x37\x27\x40\xeb\xe2\x26\xaa\x66\xf9\xb3\xf0\xea\x62\x26\x3a\x16\x87\x27\x30\xf3\xb2\x7b\x3e\x49\x82\xe9\x24\xaf\xa2\x0a\xe7\x2b\x90\x07\xe2\xa6\xe8\x70\x88\x93\x93\x6a\x8d\x73\xe5\xba\x20\x41\x83\x66\x49\x7e\xae\x13\x39\x16\xdf\xa5\xa5\x04\x1b\xf3\xf8\x72\x8c\xb7\x60\xe5\x71\x12\x51\xeb\xa2\x64\x5e\x4a\x0d\xba\x44\xd0\xf5\xef\xc9\x56\x82\xeb\xd4\x05\xcc\xbc\x9a\x29\xfe\x0d\x7c\x5d\x0c\xcd\x6d\x89\x43\x97\x0d\x1f\x19\xc3\xad\x8b\xa6\x79\x35\x8f\xfc\xbb\x86\x8b\xeb\xd6\x05\xd8\x0f\x8b\x97\x8a\x07\x90\x56\x7d\x0f\xde\x75\xeb\xa2\x2c\xb9\x8f\xe2\x10\xeb\x5b\xf1\x1a\x0a\xab\x5b\xaa\xde\x07\x16\x5f\xc9\xb8\xae\x8a\xac\xd9\x83\x37\x51\x30\xb3\x7b\x2f\x9e\xc2\xec\x54\xcf\xc6\x75\xfb\x56\x75\x4b\x01\x3a\x3c\xdd\x72\x72\xdd\xcb\x63\x68\xd2\x51\xe4\x5c\xb4\xab\x63\x68\xf6\x3c\x74\x0a\xf2\xfa\x18\x24\x66\x21\x5d\x6a\x9e\x42\xbb\x39\x86\x66\x36\x5e\xce\x44\x1c\x1c\x43\x34\xaa\xcb\x56\xfb\x3c\xc8\x8b\x9e\x1d\xd2\x2f\x36\xd1\x3a\xf2\xec\x4b\xec\x18\x8e\x15\xa3\x5a\x40\x22\x9c\xac\x76\xa1\xf0\x06\x85\xb6\x05\x94\x6b\x85\xaa\x14\x8d\xc3\xfa\xb7\x27\xee\x85\x9d\xf3\x7e\x99\x66\x47\x31\xec\xc4\xb7\x14\x87\xe4\x84\x31\x76\xce\xdb\x0a\xc2\x62\x3f\x96\x09\x8e\x31\xe3\xfd\x92\x7b\x61\xa7\xbc\x59\x09\x62\x85\x55\x7d\xa1\xe3\x5e\xd8\xe9\x6d\x16\x7e\xa4\x5e\xdd\xce\x67\x4b\x9d\x87\xff\x52\xc8\x86\x61\x67\x70\xb5\xac\x53\x55\x9d\x6c\xd6\x58\xdc\xd1\xb7\x73\x97\xd7\x73\x29\x6f\x20\xfe\x96\x22\x71\x39\x6d\x41\x2f\x4b\xdf\x4e\xd9\xb0\xe6\x54\x29\xed\x38\xf2\x9a\xc9\xed\xdb\xa9\x5b\xad\xdb\x86\xc7\xbb\xee\x6e\xdf\xce\xdf\xa8\x92\x26\x4f\x02\xd9\x49\x5c\x53\xa9\x9d\x44\xb3\x33\x39\xaa\x24\xc7\x93\x40\x76\x16\xdb\x6a\xb3\x93\xaf\x28\xdc\xfe\x35\xc0\x38\xf8\x16\xcc\x8c\x82\x2c\x17\x88\x40\x37\xb7\xa2\xe2\xd2\xdb\x69\x5c\xa9\xc4\x54\x81\x8d\x55\x97\x78\x21\x98\x92\x42\x15\xc6\xe1\xec\x8c\x9e\xd7\xf4\x68\x0a\x8c\xae\x7b\x91\xe2\x5e\xda\x79\x5d\x2e\xbb\xc8\x47\x20\xed\x7c\xb7\x95\x5a\x66\xa1\x75\x0a\xd7\x4e\xfa\x6a\x79\xf5\xa1\x57\x49\xee\xa5\x3d\x04\xca\x25\x55\xf1\x55\x65\xfd\xdb\x43\xf7\xd2\x1e\x07\xb2\x96\x92\x4b\x23\xff\x8d\x4e\xcd\xab\x5f\xf7\xd2\x1e\x00\x3f\xea\xcf\x14\x27\x0c\xfb\x7f\x00\x00\x00\xff\xff\x9f\x52\x6a\x3c\x07\x2c\x00\x00") + +func fontsSmscriptFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmscriptFlf, + "fonts/smscript.flf", + ) +} + +func fontsSmscriptFlf() (*asset, error) { + bytes, err := fontsSmscriptFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smscript.flf", size: 11271, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmshadowFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x5a\x6d\x6f\xe2\x38\x17\xfd\xce\xaf\x38\x1f\x90\x66\x90\x4a\x43\x52\xfa\x82\x54\x8d\x9a\x82\xdb\x46\x4b\x13\x9e\x24\x74\xb6\x52\x24\x2f\x9d\xa6\x2d\x5a\x0a\x15\x84\x1d\x8d\xc4\x8f\x7f\x94\xf8\x25\x4e\x62\xa7\x95\x56\x90\x2d\xbe\xc7\xf7\x5e\x9f\x7b\x7c\xed\xcc\xcb\xea\xc5\x59\x74\x31\xc4\x09\xec\x21\x06\xb0\x07\xf9\xc7\xc8\x19\x74\xa2\xf7\xe8\x6d\xf1\xbc\xf9\x8d\xa7\x3f\xb8\x5d\xa5\xeb\x35\xc6\x6f\x8b\x8f\x8f\x74\xb5\xc2\xd0\x1a\x9d\xa0\xdf\xc7\xd3\x62\x97\x3e\x63\xb3\x46\xf4\xbe\x58\xad\x3a\xde\xfa\xd7\x6a\xff\x9c\xee\xe0\x45\x01\xa6\x8b\x6c\xb9\xee\xdb\x9d\x97\xe5\xeb\x2a\xcd\xb0\x4d\x57\xe9\x62\x97\xc2\x39\xb6\x73\x4b\xdb\x81\xbb\x7f\x85\x3d\x1a\x0d\x3b\xb3\x74\xfb\xbe\xdc\xed\x96\x9b\x35\x96\x3b\xbc\xa5\xdb\xf4\xe9\x0f\x5e\x97\xff\xa5\x6b\x64\x1b\xbc\x6f\x9e\x97\x2f\x7f\x90\xbd\x2d\x77\x78\xd9\xac\xb3\x23\x2c\x76\x58\x6d\xd6\xaf\xf9\x77\xf6\x96\x76\x8a\x01\xcb\x74\xfb\x6d\x87\xf5\xe2\x3d\xcd\x31\x3e\x56\x8b\x5f\xcc\xb1\x05\x7e\x6d\xde\xdf\xd3\x75\x86\xd5\x72\x9d\x1e\x77\x3a\xf7\x6c\xf4\x73\x1e\xd5\x6c\xb1\x5f\xe1\x7a\xbf\xcd\x36\x6b\x5c\xee\x36\xab\x7d\xb6\xdc\xac\xaf\xd2\xc5\x36\x7b\x5b\x2d\xd7\xff\x1e\xaf\xd3\xec\x07\x6c\xc7\x1a\x9d\xe5\x8e\x2c\x59\x74\x58\xa7\xbf\xf1\xb1\xd8\x2e\xde\xd3\x2c\xdd\x76\x76\xfb\x8f\x8f\xcd\x36\x63\x80\x37\xde\x6d\x1e\xeb\x62\xfd\x9c\x3f\xfe\x5c\xae\x8f\x81\xfb\xc5\x1f\x2c\x56\xbb\x0d\x9e\x52\xec\x56\xcb\xd7\xb7\x6c\xf5\x07\xef\xc2\x8b\x97\xcd\x16\x4f\x69\x96\xa5\x5b\xec\x77\x69\x67\xf3\x52\xc0\xbf\xec\x57\xab\xfe\xef\xe5\x73\xf6\x66\xfd\x9b\x6e\xd7\xd6\xee\x7d\xbf\x7b\xc3\x62\x95\xa5\xdb\xf5\x22\x5b\xfe\x97\xee\x8e\xf0\xb4\xcf\xf0\x9c\xbe\x2c\xf6\xab\x0c\x9b\x7d\xf6\xb1\xcf\xf2\xc8\xfd\x20\xc6\xaf\xb7\xc5\xfa\x35\x7d\x3e\xee\x74\xd0\xed\x5e\xd5\x3e\xae\x3a\xc0\x21\x7f\xa6\xec\xb3\x97\x7f\x02\x60\x3f\xa0\xf8\xdf\x07\x3c\x74\xc1\xfe\x8c\xf2\xbb\x78\x38\xe4\xd6\xc5\x1f\x29\x0e\xf9\x7f\x0c\x45\x79\x06\x3d\xe4\xd8\xd2\xa0\x40\xfa\x4e\xfb\x97\x6c\x20\xb5\xf8\xa0\x6e\x31\x80\xf6\x60\xf1\xb9\x2c\x8e\x6b\x95\x4e\xc9\x69\x0b\x40\xf0\x47\xee\x7a\x42\x29\xa5\x87\xd2\x51\x31\xb8\x30\x16\xa0\x50\xa2\x03\x9b\x9a\x9b\xb0\xaf\x84\x26\x45\x4e\x12\x24\xc2\xe2\xd0\x55\xbf\xa9\xc5\x1c\x4d\x90\x70\x50\xca\xfc\xe1\xae\x26\xaa\x03\x57\xc2\x92\x45\x42\x41\x79\x4e\x78\x46\xea\x03\xcb\x4f\xe9\x74\x19\x78\x0e\x20\xed\xd5\x95\x68\x58\x57\x17\x51\xc4\x29\xdc\xb5\xba\xf5\x45\x14\xb1\x7e\xe7\x41\x26\x94\x5a\xdd\x2a\x3c\x15\x69\x10\x6b\x2a\xdc\x60\x3f\xa2\x57\x99\x42\x75\xf3\x8a\x45\xce\x97\x19\x49\x97\x0d\xb0\x2a\x03\x70\xe0\xf9\xcf\x73\xa4\xa4\xa8\x1a\x22\x87\xa5\x46\x14\xc8\xd8\xf8\x90\xa4\x32\x46\xf8\x22\x12\x22\x58\x51\x49\x89\x60\x98\x08\xc9\x8c\xa4\xfc\x26\x21\x9b\x89\x93\x6b\x51\x5b\x17\xf5\x87\xfa\x72\x17\x60\x97\xb8\x64\x58\x05\x27\xab\x0b\x56\xe3\x43\x9d\x18\x2a\x81\x7f\xe0\x47\x49\xdc\xea\x9a\x24\xd2\xe7\x62\x40\xaf\x5b\xe3\x45\x31\xa4\xf8\x9b\x05\xfa\x0f\x5f\xfa\x84\xd2\x23\xa5\xe0\x4a\xa7\x13\x35\xf7\xbc\x72\xa1\xb8\x2e\x16\x91\x27\xd6\xbc\x88\x22\x96\xef\xbc\xc6\x93\x66\x74\x72\x0e\x26\x40\x02\x47\xcf\x17\xc1\xa4\x06\x2d\x1b\x03\x0e\x8d\xd2\x90\xbe\x50\x59\x1a\x0d\x5f\x0e\xb2\x2a\xa8\x90\x52\xd4\x07\x95\xb4\x36\xf9\x22\x6b\x2b\x31\x57\x61\x3e\x15\xcb\xd6\x31\x27\x07\x3d\xa8\xec\xe0\x83\x84\x36\x8a\x07\x0d\x3d\xca\x69\x70\x48\x2c\xe9\x76\xc5\x6f\x39\xf0\xc0\xa7\x14\xc3\x92\x26\x1a\x55\x34\xa4\xcc\x94\xd5\x10\x43\x41\x3a\xbe\xea\xba\x8c\xeb\x90\x12\x1d\x8f\x92\xae\x52\x2d\xf4\xd0\xa8\x12\x2a\x69\x2a\xa9\xa6\x11\x83\x32\x35\xd2\x17\x9d\x38\xcb\x45\x3e\x98\x97\x27\xdf\x13\xc4\x02\x95\xfb\x43\x5e\x32\x15\x81\x51\x07\x57\xc6\x27\x50\x4d\x1a\x56\xaa\x21\x33\xfa\x01\xa1\x11\xf9\xf0\x7a\x8a\x94\x81\x0a\xb2\x26\xb8\xa6\x24\xea\x18\xc3\xff\x50\xd9\x2e\x8b\x51\x42\x6d\xc0\xe3\x90\x21\x24\xf5\x1a\xa8\xec\x21\xa2\x6e\x19\x02\x37\xb3\x92\x72\x67\xe9\x54\x8a\x43\x55\xe8\xa6\x06\x4a\x11\x95\xf6\x57\x9d\xaa\x35\x8f\xfe\x1f\xb9\x7a\x47\x4d\xae\x2b\x5d\x05\xa7\xcc\xb1\x46\xf5\xcb\xce\x83\x23\x35\x2b\x59\x84\xd8\x3e\x5d\x09\xd5\x67\xbb\x81\x4e\x5d\xd4\xfd\x50\x5f\x31\xfa\xe8\xa4\x2c\x4a\x89\x2e\xa3\x13\x02\xad\xd1\xa9\x1e\x5f\x64\xd9\x11\x96\x7e\xf4\x2a\x8d\x90\x5c\x3f\x15\x9e\x15\x08\x2b\xc8\xc6\xb6\x75\x30\x42\x97\x11\xfc\x23\x5d\xa3\x87\xb6\x84\x99\x23\x50\xd3\xd1\xb2\x75\xd7\x07\xe1\x58\x95\xa4\x2f\x64\x16\x7c\x49\x34\x94\xd0\xaf\x91\xda\xf6\x36\xfb\x9f\xee\x17\x48\x85\xaa\xfe\x1c\x19\x43\x67\xe2\x53\x54\x55\x73\x0f\x41\x75\x9c\x3a\xb4\x3a\xda\x8c\x4a\x9b\x9b\x8e\xce\xbf\xca\xce\xac\xa4\x41\xc8\x8d\x6e\x13\x64\x3f\x08\x95\x11\xdf\xa2\x2d\x57\x39\x54\x32\xa9\x22\x40\xc0\x81\x96\x82\x7e\x25\xdb\x3b\x26\x4e\x85\x8d\x95\x58\xfa\xf3\x0c\xed\x21\xa1\x4a\xdf\xc7\x7b\x9f\x66\x17\x43\x7b\x65\x3d\x50\x85\x66\x2a\xcf\xc4\x40\x51\x52\x2d\xcd\xb5\x8a\xd6\xa6\x18\x25\x5a\x5b\x83\xab\x99\x52\x43\x15\xc1\xfb\x43\xde\x67\x16\x0f\xf5\x02\xb0\xcf\x06\x80\x1f\xf4\xaf\x43\xe2\xfe\x85\x68\xe6\x8e\x89\xfe\x04\x69\x9f\xd9\x80\xe7\x3f\x90\x30\x26\x13\x90\xbf\xc7\x53\xf7\xde\x8d\xbd\xc0\xc7\xbd\x1b\xfe\x65\x16\x15\xfb\xcc\x01\xc6\xc4\x8f\x11\x79\xb7\xbe\xb2\xdc\xdc\x22\x91\xd1\xb2\xd3\xa1\x7d\x76\x02\xcc\x82\xb9\x3f\x91\x06\xe2\xc0\x45\x65\xd1\xd1\xa3\xaa\x88\x32\xc3\x21\x30\x9e\x87\x21\xf1\xc7\x8f\xdc\x36\xc1\xb1\x6c\xda\x79\x2e\xad\x72\x1b\x14\x76\xa7\xc0\x23\xf1\xa5\x89\x3c\xf3\x51\xe5\x30\x52\x3b\xd4\xe5\x66\x67\xc0\x75\x18\xfc\x45\x7c\x5c\xbb\x61\x2d\x74\x85\xb6\xf6\xd9\x39\x10\x91\x71\x91\xab\x32\xa4\x5e\x57\xdd\x49\x13\x24\x62\x52\x4b\xe0\x5f\x00\x13\xcf\x25\x21\x89\xbc\xa8\x42\x0b\xe8\xf7\xc9\xdc\x66\x04\x8c\x83\xd9\x63\xe8\xdd\xde\x95\x09\x47\x79\xfa\x63\x67\x69\x96\x89\x42\x80\xa4\x2e\xc8\x0a\xb6\xcf\x07\xc0\x0d\xb9\xf7\x7c\xcf\x27\x08\xc2\x89\xe7\xbb\x53\x78\xfe\xc4\x1b\xbb\x71\x10\xea\xf9\x4b\xa9\x66\x41\xce\x6d\x60\x4a\x6e\xe2\xfe\x2c\xf0\xfc\xd8\xf3\x6f\x31\x09\xe6\xd7\x53\x02\xd7\xbf\x9d\x12\xfc\x6f\x1e\xc4\x2a\x83\x72\x61\x90\xa7\x22\xe5\x5c\x54\x2f\x4c\xfb\xdc\x41\x71\xe7\xc1\xe2\xcb\x67\xae\xaa\x75\x55\xd5\x4b\xb3\x13\x20\x0a\x6e\x62\xdc\x3d\xce\xee\x88\xaf\x48\x55\x45\xa2\x3a\x8a\xc5\x10\x08\xc9\xad\x17\xc5\x24\x24\x13\x43\x3e\xfb\x3d\x91\x4f\x1c\x92\x44\x97\xcf\x53\xe0\xde\x1d\x87\x81\x6f\x9a\x4a\x9d\xf2\x0c\x98\x90\xdb\x90\x10\x31\xdd\x31\xd7\x00\xab\xd9\x33\xd9\xe7\xe7\xc0\x6c\x3a\x8f\xfa\xf7\x9e\x3f\x8f\x4a\x07\xe5\x75\x4d\xa5\xb3\x90\xbd\x14\x27\xe6\xf9\x05\x10\xcd\x67\x24\x8c\xc6\xa1\x37\x8b\x11\xff\x0c\x3a\xe2\xe8\xa6\xf8\xa9\xce\x37\xaa\x59\xdc\x85\x84\xe4\x36\x5c\xea\x7b\x1a\x9b\x8b\x01\xe0\x8e\xe7\x31\x81\x3b\xce\x75\xa0\x03\x19\xca\x55\xb5\x89\xb3\x2f\x6c\xe0\xde\x1b\x87\x41\x25\xd5\xaa\xca\xe1\xf8\x48\xd9\x7e\x99\x91\x03\xcc\xbc\xe9\x38\x0c\x7e\xaa\x66\x9c\xa0\xc5\xa5\x03\x4f\x40\x83\xa0\x17\x27\xf9\x7c\x93\xc9\x94\x60\x12\xc4\xc2\x99\xca\xa1\x9d\x0f\xcc\xa5\x85\x4c\xbc\xe9\xd4\x6d\x3a\xce\x2c\xf2\x51\xa7\xd5\xec\x04\x3e\x29\x1b\x62\x6d\x3e\x2f\xce\x72\x6a\x44\xe3\xf9\xd4\x5c\x6b\xb5\x3d\xa0\xd9\xb5\xdb\x17\xe7\x40\x51\xf1\x5f\x2c\xb4\xa4\x72\x71\x20\xaf\x0e\x1a\x27\x39\xfb\xe2\x02\x78\x98\x4f\x6f\xdd\x10\x37\xa1\xcb\x14\x2c\xf0\x73\x40\x37\x8c\x49\x58\x04\xc7\xee\x63\xd8\x1e\x7c\x80\x45\xbf\xc9\x7c\x5b\xf5\x72\x14\xa8\x23\x3d\xea\x9d\x3b\xbd\x51\x20\x25\xa2\xbc\xa4\xb1\x40\x6b\x78\x39\xdc\x68\xd0\x84\x2b\x78\x29\xdc\x8c\x0a\x82\x96\x7e\x52\xda\xfb\x92\x9f\x23\x75\xc3\xfb\xdf\x9c\x44\x15\xad\x92\x37\x29\xdc\xd7\x66\x5b\x6f\x8f\x1c\x60\xea\xc6\x9e\x8f\xb1\x3b\xf3\x62\x77\x8a\x29\x89\x63\x12\xc2\xc5\x4f\x2f\xbe\xc3\x6d\xe8\x3e\x10\x76\x1d\xc9\xc2\xed\xf7\xc5\xa5\x4a\xbd\xf7\xb2\x47\x27\xed\x58\x45\x85\x75\x94\xcb\xa9\x36\xac\x61\x3b\xd6\xd8\x0b\xc7\xf3\xfb\x9b\x29\xf9\x3b\xef\x8c\x92\xe4\x73\xc0\xd3\x76\xc0\xd8\x9b\x4e\x48\x07\xd6\x97\x9c\x3b\x6b\xc7\xaa\x6e\x89\x5f\xea\xe4\xec\xd1\x79\x3b\x66\x98\x97\x8c\x7b\x1d\x3c\x14\x19\xfc\x0e\xb1\xb4\x6d\x97\x5c\xf6\xe8\xc2\x04\x5a\xa0\x1c\x29\x2d\x83\xbc\x7b\xb2\x50\xdb\x26\x19\xd2\xc8\x80\x34\xe6\xeb\xa1\x28\x0f\x8c\xd7\x66\x05\x21\xaf\x3a\xce\x60\x60\x40\x23\x0d\xd6\x15\x4b\xc1\x0f\x2b\x97\xdd\x52\x97\x9c\x81\xdd\x8e\x21\xd8\xc6\x95\x5c\x8f\x61\x62\x3f\x69\xb2\x2c\x27\x99\x19\xc8\x44\x7d\xa2\x63\x84\x20\x44\x5f\x5c\x9a\xd0\xcb\x6a\x27\xee\x0c\x4c\xf4\xf7\x9a\x65\xa9\xdc\xea\xd5\x0f\x32\xce\xc0\xc4\x7a\xaf\x91\xa4\x76\x1c\x13\xe3\x3d\x7d\xa2\xda\xc1\x4c\x54\xf7\x74\xc9\x12\xd9\x92\x0c\x45\xfd\xf5\x4a\x81\x69\x62\x3a\x89\xef\x2a\x65\x92\xeb\xb5\xb8\x25\x6d\xec\x26\xce\xc0\x44\x73\xbf\xa2\x12\x4c\x26\x0a\xd3\xc4\x74\x19\xe9\xd8\x26\x92\x07\x95\x35\x54\xb4\xb5\xf5\x08\xe7\xd8\x26\xc2\x07\x35\x79\x2d\xaf\xd8\xdb\xf1\x4c\xe4\x0f\x34\x12\x5b\x6a\xec\x27\xa0\xa6\x42\x08\x34\x09\xfc\x0a\x9e\xa9\x10\x82\x36\xae\x7c\x82\x99\x37\xbb\xf3\x69\xec\xcd\xa6\x79\x0f\xa3\x9c\x79\x12\x66\x75\x04\x7c\x63\x07\xb1\xa4\x72\x3d\xe2\xd8\xa6\x32\xe0\xde\x44\x71\x7e\xd8\x62\x7c\xb3\xe4\xf5\xb1\x25\x3b\x3d\xab\x46\x39\x06\x6a\x2a\x87\xb9\x61\x0b\x36\x9f\xe0\x1d\xdb\x54\x06\x73\xc3\x16\xdc\x86\x65\xaa\x85\x79\xdb\x16\xdc\x02\xe8\x98\x0a\x62\xde\x22\x92\x6d\x78\xa6\x82\x78\xd4\x07\x5b\xde\x1b\x35\xde\xe9\x39\x8e\xa9\x18\xe2\xbb\x20\xf4\x95\x8b\x31\x7e\x43\x5a\xbf\x5a\x73\x1c\x49\xfc\xe8\xde\x9d\x4a\xf3\xe8\xce\x0d\x67\x88\xbe\x76\xd1\xe1\x38\x43\x2d\x88\x6b\x16\x8c\x96\x5b\x1a\xc7\x39\x6d\x43\xd3\xc9\x45\x2b\xda\x59\x1b\x9a\x51\x2c\x5a\x21\xcf\xdb\x20\x75\x52\xd1\x8a\x76\xd1\x86\x66\x12\x8a\x56\xc4\x51\x1b\xa2\xb1\x23\x6b\x83\x3c\x19\xe8\x21\x89\x7a\x62\xe0\x28\xe5\x65\x7c\xfd\x2a\x89\x63\xd9\x5a\x2c\x5d\x47\xa6\xbf\xd3\x65\x67\x42\xe7\xc4\xd1\xe2\x10\x0d\xeb\x58\xdb\x62\x7a\x49\xe0\x9c\xe8\x8b\x80\x18\xc4\xa7\x0d\x49\x5f\x09\x9a\xbe\x4c\x21\x5b\x0b\x9c\xbe\x14\xb4\xdd\x59\xd9\x9e\xf1\xf3\x53\xa2\x6b\x38\x4e\xf4\xe5\xd0\xec\xcf\x0a\xb3\xc6\xf9\x3a\x47\xd0\xb3\xbf\xda\x99\x51\xab\x7a\x57\xd7\x91\xd6\x7a\xb6\x1b\xfa\xb1\xab\xf2\x4d\x59\x19\x49\x01\xa3\xa7\x78\x6b\x27\xd6\xfa\x86\xd2\x19\xea\x19\xce\xfb\xb0\x23\x24\xdf\x1a\x95\xd7\xec\xc3\x86\x7a\x6a\xfb\x86\xb3\xda\x37\xe3\x6b\x18\x67\xa8\x27\xb7\xae\x07\xbb\xd2\xdd\x65\x28\x48\x7a\x72\xd7\xbb\xaf\x52\xac\xcc\x48\x7a\x72\xeb\xfa\x2e\x45\x49\xcd\x70\x7a\x72\xeb\x3a\xae\xcf\x90\xf4\xa4\xd6\xf6\x5a\x9f\xbe\x00\x70\x86\xe7\xc0\xc4\x7b\xf0\x22\xa5\xc3\xe2\x25\x25\x2b\xb4\xf6\x8f\x3d\x9c\xa1\x9e\xd6\x8d\xfe\x4a\x6a\x5a\xde\x67\xf1\xde\xaa\x3e\xbd\x9e\xda\x9f\x77\x55\xf5\x97\x14\xce\xa9\x9e\xd2\x9f\xf7\x54\x4d\x24\x3d\xaf\xbf\xd8\x51\x35\xe1\xf4\xe4\xfe\x5a\x3f\xd5\x44\xd3\x13\xdc\xd0\x4d\xb5\xbc\x60\x73\x4e\xf5\x04\x57\x7b\x29\x56\xb7\xc6\x97\x9e\xce\xa9\x9e\xd4\x8f\x5f\x0b\xad\xe6\xd0\xff\x03\x00\x00\xff\xff\x37\x7a\xd8\x72\x4d\x2a\x00\x00") + +func fontsSmshadowFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmshadowFlf, + "fonts/smshadow.flf", + ) +} + +func fontsSmshadowFlf() (*asset, error) { + bytes, err := fontsSmshadowFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smshadow.flf", size: 10829, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmslantFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x5a\x6d\x4f\xdb\xc8\xf7\x7d\xef\x4f\x71\x5e\xa0\x7f\x89\x44\x98\xd8\x84\x40\x24\x84\xe2\x26\x06\xac\x0d\x71\xd6\x49\xda\xad\x64\x69\x9a\x16\x53\xa2\x0d\x09\xca\xc3\xae\x2a\xf9\xc3\xff\x35\x8f\x7e\x9a\x31\xec\x4f\xaa\x1a\x04\x33\x67\xee\xdc\xb9\xe7\xce\xb9\x77\xf2\xbc\x7e\xf6\x96\x27\xb8\x44\x17\x6e\x17\xee\x25\xdc\x0e\x3a\xf0\xbc\xae\x7b\xe9\xcc\x5e\x67\xeb\xe5\xe6\x80\x1f\xbf\x71\xbf\x4e\x37\x1b\x0c\x5f\x96\x6f\x6f\xe9\x7a\x8d\x1e\xe9\x5f\xa0\x8d\x1f\xcb\x7d\xfa\x84\xed\x06\xb3\xd7\xe5\x7a\x8d\xff\x03\x1f\xef\x84\x9b\x9f\xeb\xe3\x53\xba\x47\x38\x8b\x30\x5e\x1e\x56\x9b\xb6\xeb\x3c\xaf\x7e\xad\xd3\x03\x76\xe9\x3a\x5d\xee\x53\x78\xe7\x2e\xda\x6d\xb8\x1e\xfc\xe3\x2f\xb8\xfd\x7e\xd7\x99\xa6\xbb\xd7\xd5\x7e\xbf\xda\x6e\xb0\xda\xe3\x25\xdd\xa5\x3f\x7e\xe3\xd7\xea\x9f\x74\x83\xc3\x16\xaf\xdb\xa7\xd5\xf3\x6f\x1c\x5e\x56\x7b\x3c\x6f\x37\x87\x33\x2c\xf7\x58\x6f\x37\xbf\xd8\xe7\xe1\x25\x75\xf8\x80\x55\xba\xfb\xb4\xc7\x66\xf9\x9a\x32\x8c\xb7\xf5\xf2\xa7\x30\x70\x89\x9f\xdb\xd7\xd7\x74\x73\xc0\x7a\xb5\x49\xcf\x1d\xe7\x51\x8c\x7e\x62\x9b\x9b\x2e\x8f\x6b\x7c\x3e\xee\x0e\xdb\x0d\x6e\xf6\xdb\xf5\xf1\xb0\xda\x6e\x06\xe9\x72\x77\x78\x59\xaf\x36\x7f\x9f\x6f\xd2\xc3\x2d\x5c\x8f\xf4\x7b\xcc\x90\x95\xd8\x1d\x36\xe9\xbf\x78\x5b\xee\x96\xaf\xe9\x21\xdd\x39\xfb\xe3\xdb\xdb\x76\x77\x10\x80\x77\xe1\x3d\xdb\xeb\x72\xf3\xc4\x7e\xfc\xba\xda\x9c\x03\x8f\xcb\xdf\x58\xae\xf7\x5b\xfc\x48\xb1\x5f\xaf\x7e\xbd\x1c\xd6\xbf\xf1\xaa\xac\x78\xde\xee\xf0\x23\x3d\x1c\xd2\x1d\x8e\xfb\xd4\xd9\x3e\x73\xf8\xe7\xe3\x7a\xdd\xfe\x77\xf5\x74\x78\x21\x7f\xa7\xbb\x0d\xd9\xbf\x1e\xf7\x2f\x58\xae\x0f\xe9\x6e\xb3\x3c\xac\xfe\x49\xf7\x67\xf8\x71\x3c\xe0\x29\x7d\x5e\x1e\xd7\x07\x6c\x8f\x87\xb7\xe3\x81\xed\x7c\x12\xcd\xf1\xf3\x65\xb9\xf9\x95\x3e\x9d\x3b\x0e\x00\x9c\x0c\xd8\xc7\x09\xd8\xc7\x09\xd8\xc7\x09\xd8\x07\xfb\x1f\x03\xfe\x47\x4a\xd9\x07\x01\x19\x38\x20\x94\x60\xe0\x9c\xd2\x16\x1f\xaa\xc6\x50\x50\xf6\x5b\x64\x68\x0d\x9c\x8c\x64\x44\x03\xe4\x63\xc0\x91\x28\xe5\xbf\xa3\x94\x30\x40\xca\x11\x81\x73\xf6\x8b\x81\xc3\x7e\x14\x7f\x13\x2b\x51\x52\x9c\xcc\xe7\x11\x66\xc4\x29\x6d\xdf\x0c\x1c\x22\x27\x11\x6d\x84\x30\xf5\x94\xb6\xd8\x54\xf6\x1b\x86\x01\x86\x4b\x70\x4a\x5b\x12\x47\x22\x72\x5b\x38\x2a\x07\xa2\x7c\x97\xb7\x6c\x0e\xd8\xe4\x8c\xfd\x9d\x19\xa0\x67\xa9\x55\xd8\x46\xf9\x36\xc5\x26\xf9\xdf\xa5\x8d\xc2\x53\x72\x75\xb6\x43\xb6\x38\xb8\x81\x4e\x46\xb3\xc2\x40\x31\x2d\x43\xc6\x3f\x85\x6f\xa9\x70\xae\xd8\xb6\x1c\xc8\x7f\x9d\x0d\x9c\x5b\xd0\x1b\xbe\xa6\xb4\x47\x2f\xc8\x47\x50\xe1\x4b\xe6\x3f\x4a\xd5\x31\x15\x4c\x17\xa3\xd5\x7f\xa5\x2d\xe4\xce\xa5\xdc\x05\xcc\x11\x44\x47\x81\x6d\xb6\x74\x66\x7e\xae\x22\x50\x72\xb7\x43\x6f\x04\x35\xb7\x4b\x9f\x23\xe1\xce\xe1\x7b\x4f\xa8\x3c\xf5\xd2\xc0\x81\x83\x1b\x40\xf9\x52\x02\x96\x8c\x52\xf1\x94\x51\x70\x57\x12\x19\x3d\x84\x96\x00\xf3\xd1\x54\x8d\x96\x86\xe2\xc6\x36\x5a\x0e\x26\xe2\x70\xb8\x6b\xb5\x67\x4b\x86\x6a\x58\xa2\x9d\x4f\x91\xbc\x0b\x2b\x82\x17\x62\x68\x7d\xff\xea\x34\x1a\xf7\x2f\xb7\x7f\x0a\xca\x8e\x93\x81\x31\x2f\x98\x9d\x59\xf0\x3a\x12\x7a\x26\x36\x55\x1b\x28\x23\x53\x1c\xb0\xe0\x47\x95\xec\xc6\x31\xe0\x63\x32\x92\x2f\x28\xac\x1e\x38\x37\xdc\xc5\x48\x68\x52\x8a\x5c\xc9\x67\xe9\x0d\x2a\xf9\x5f\xb1\x87\x31\x74\xe0\x24\xdc\x45\xb8\xc5\xad\x70\x41\x8e\x23\xb6\xc5\xfd\x2d\x50\x88\xc1\x5c\x4a\xf3\xdd\x53\x15\x75\xa0\xf8\x4e\x38\x34\x3d\x13\x90\x89\xa4\x7b\x29\xae\xd8\x38\x15\x57\xec\x07\xb6\x7c\x46\xb3\x7a\x5c\xe9\xd1\x2d\xe9\x66\x31\xda\x12\x00\x2a\x02\x44\x08\x10\xb9\xcd\x4a\xbe\xa9\x63\x27\xc2\xa7\x44\x9d\x9d\x3d\xc2\x75\x28\x42\x51\xd1\x82\x6d\x19\x6d\x26\x6e\xc5\xee\x53\xca\xa3\xd2\x66\x77\x7e\x6f\xc8\xab\x83\x79\x45\x86\x31\x29\x67\xd6\xaa\x39\x90\x79\x04\x0d\xc6\xcb\x18\xa3\x54\x12\x94\x2f\xf3\x31\x73\xe4\x66\xcf\x6e\x20\x77\xcb\x73\x73\xdd\x1c\xe9\x78\x71\x1d\xb1\x63\x52\x6e\xaf\xf2\x5f\x65\x2b\x66\x2f\xe3\x80\xa4\x6c\x46\x0b\xbc\xad\x6c\x39\xe7\x92\x36\x2c\x53\x7e\x82\xf6\x53\x66\xf0\x53\x31\x9c\x65\x34\x53\x9d\x44\x8d\x21\x51\x09\x20\x45\x36\xcb\x21\x5b\xb1\x35\x85\x1b\xb0\xcf\x20\xb1\x99\x4b\xdf\x09\x37\xca\x88\x6d\x39\x5f\x4a\xf3\x04\x48\xf3\xeb\xd4\x1e\x9c\x79\xca\xd1\xf1\x40\xf3\x80\x30\xb9\x51\x45\x50\x86\x4c\x5e\xc0\x19\x3f\x02\x36\x30\xb3\x4e\x29\xcd\x2a\x4d\x2c\xcc\x25\x59\x55\x3a\xd4\x8e\x9b\x4d\x11\x5e\xb8\x05\xbb\xe5\x6c\x71\xa8\x77\x96\x20\x11\x8b\x31\xa7\x89\x53\x26\xf5\x40\xd7\x09\x55\x04\x61\x2e\xb2\x6a\x51\xab\x42\x96\xb3\x5e\x05\x3a\x4a\x8e\x56\x42\x44\x0a\x25\x79\x5c\x90\xf9\x38\x4f\xe9\x75\x44\xb1\xb8\xe2\x4e\x81\xc8\xea\x82\x20\x4c\xd4\x64\x24\xcb\x84\xd4\x10\x72\xb1\x7c\x41\xd4\x3e\x8a\x02\xa5\x28\x63\xf0\xa5\xae\xc4\xd4\x04\x50\x71\x2f\xf2\x64\xaf\x52\x7d\x03\xc9\x45\xd4\xd3\xf3\xba\xbb\x0a\x16\x88\x88\x4c\x0a\x64\xab\xa4\x24\x2a\x43\x50\x26\x3c\xb1\x70\x3d\x81\xe5\x37\x18\xda\xec\x32\xad\x23\xe6\x8c\xd1\xf9\x59\x0b\xc4\x8a\x79\xfa\x42\x85\xcc\xd2\x7c\xcf\xe2\xaa\x2f\x90\xac\x69\xd7\x32\x33\x96\xc2\x35\xbf\xe9\x6d\x1a\x2c\x97\xb3\xc8\x55\xb6\x3a\x79\x75\xf4\x92\x50\x85\x8c\xa9\xa2\x53\x58\x8b\x4f\x32\x6f\x24\x34\xa9\xe7\x8d\x41\x5e\x7f\xd8\x8d\x90\xfb\x87\x4c\x60\xf8\x24\x37\x45\x0b\xbb\xaa\xa9\x8f\x77\xf6\x5f\x3a\x23\x3e\x2a\x29\x30\xa9\xbc\xb4\x21\x1b\x9e\x97\x32\x6d\x63\x64\x42\x15\x3d\x16\x85\x84\x02\x94\xc1\x46\x19\x29\xb2\x32\xaa\xda\xa8\xf6\x49\x9a\xa3\x57\x58\x06\x11\xe3\x4a\x98\xd7\x39\xa3\xea\x00\x3e\x30\x93\xd7\x56\x66\xd0\x92\x85\xa1\xf9\x60\x3d\xfc\xac\x74\x59\x99\x8c\xe0\x99\x86\xef\xba\x18\x15\xf5\x03\xa7\x05\x5d\x64\x0e\x78\xe9\x73\x7e\x9f\x08\xf1\x44\x4a\xc9\xa6\x58\xb8\xd1\x4a\xe1\xc6\xd6\xae\x0c\x94\xc1\x58\xd0\x06\xa8\x14\x6e\x2a\xc2\x75\xb2\x54\x99\xb8\x5a\x1c\xb1\xe9\x09\xe1\x75\x6c\xc2\xc1\x8a\xe5\x77\x59\x74\xe7\x6c\x54\x84\x6c\x23\x6b\x50\x30\x54\x31\x93\x55\xc4\x7c\x8a\xb8\xd6\xf1\xce\xa5\x28\xa7\x40\x4e\x79\xff\x1e\x55\x33\xd4\x1a\xf8\x6e\xcd\x7a\xa6\xd1\x89\x55\xfd\xd6\x47\x6b\x91\x67\xcc\xa8\xba\xbf\x20\xc4\x66\x4b\x9e\x91\x2c\x41\xb8\xf4\x2b\x64\x50\x31\xcf\xed\x75\x80\x49\xd4\xfe\x1c\x07\xfe\x1f\x98\x4d\xfd\x61\xc0\xb1\xde\x6b\x8c\xb8\x3d\x17\x08\x27\x5f\x82\x78\x1e\x8c\x10\xfc\x35\x1c\xfb\x8f\xfe\x3c\x8c\x26\x78\xf4\xe3\x3f\x3e\x94\x3c\xdd\x9e\x07\x0c\x83\xc9\x1c\xb3\xf0\x7e\x52\xc8\x37\x84\xe4\x3c\x95\x39\x9f\xa8\x29\x17\xc0\x34\x5a\x4c\x46\x85\x39\x79\x53\x85\xf2\xda\x84\xb7\x30\x44\x9d\x7e\x46\x6b\x2c\x73\x7b\x5d\x60\xb8\x88\xe3\x60\x32\xfc\xa6\x51\x98\xd4\xcc\x84\x30\x39\x57\xb9\x08\x22\xbc\x84\xb6\x41\x15\xe5\x12\xf8\x16\x4c\x72\x33\x94\xbc\xa3\x99\xee\x15\x21\xef\xeb\xe4\x5d\x1d\x0d\xd0\x03\x3e\xc7\xd1\x1f\xc1\x04\x9f\xfd\xd8\xc4\x2e\x6a\x64\x97\xdb\xbb\x02\x66\xc1\x90\xfb\xba\xe6\x04\xe6\x2e\x2a\x0f\x9e\x69\x34\xa1\xce\x84\xdf\x4f\x69\x61\xf5\x6b\x60\x14\xfa\x41\x1c\xcc\xc2\x99\xa3\x03\x5f\xc7\x3d\x3f\xed\x13\x79\xde\x27\xe5\x50\x73\x7b\x7d\x60\x18\x4d\xbf\xc5\xe1\xfd\x43\x7e\x78\xa2\xa3\x24\x6f\x00\x2a\x32\x16\x11\x97\x76\xc6\x73\x1f\x95\x4c\x82\xa6\xd2\xc0\x71\xaf\x3a\xc0\x5d\xf0\x18\x4e\xc2\x49\x80\x28\x1e\x85\x13\x7f\x8c\x70\x32\x0a\x87\xfe\x3c\x8a\xd5\xbd\xa2\x64\x80\xb8\xd4\xa9\x4a\xcb\xc4\xc4\x49\xf7\xca\x05\xc6\xc1\xdd\xbc\x3d\x8d\xc2\xc9\x3c\x9c\xdc\x63\x14\x2d\x3e\x8f\x03\xf8\x93\xfb\x71\x80\x3f\x17\xd1\xbc\x14\xa9\xe5\x56\x07\x63\x8b\x2a\xd9\x73\xc5\xcf\x71\x3d\xf0\x0e\x62\x25\x5a\x4b\x8d\x8a\xd2\xad\xe2\x5e\x5d\x00\xb3\xe8\x6e\x8e\x87\x6f\xd3\x87\x60\x52\x49\xc5\xaa\xd1\xa4\x53\xb1\x7b\xd5\x05\xe2\xe0\x3e\x9c\xcd\x83\x38\x18\x59\x3c\x0b\xed\xd9\x76\x4b\x78\x96\x90\x24\x31\x78\xf6\x12\x78\xf4\x87\x71\x34\x31\x37\xb7\x2a\x39\xd6\xbd\xea\x01\xa3\xe0\x3e\x0e\x02\xb5\xb0\xbc\x37\xcf\xf9\x2a\x32\x82\x4f\x2a\x93\xae\x80\xe9\x78\x31\x6b\x3f\x86\x93\xc5\xac\xe0\x9a\x3c\x20\x65\x77\x0e\x39\x21\x38\x55\x09\x55\xc5\x4f\x6e\xf1\x35\x30\x5b\x4c\x83\x78\x36\x8c\xc3\xe9\x1c\xf3\xaf\x91\xb6\x22\x13\x3d\x1e\x2a\xea\xaa\xaa\x15\xfd\xca\xc4\x87\x38\x08\xb4\x2a\xc8\xd4\xa5\xd7\x32\x4c\xbd\xee\x00\xfe\x70\x31\x0f\xe0\x0f\x59\x2e\x72\xc4\xfd\x2f\xfd\x54\x12\xd6\xee\xb5\x0b\x3c\x86\xc3\x38\x2a\xee\x53\xab\x9f\x7a\xc1\x7f\x7e\x56\x4a\xb7\x1c\xc2\x03\xa6\xe1\x78\x18\x47\x5f\x73\x2f\xab\xf8\x03\x84\x36\xc8\xd3\x65\x35\xcb\xbb\xd7\x17\xcc\x84\xd1\x68\x1c\x60\x14\xcd\x1d\x94\x7b\x92\x25\x63\x59\x9a\x0b\x46\xe1\x78\xec\x3b\xc8\xfb\x97\x7a\x02\xa1\x2d\x3e\xec\xb2\xec\xba\x68\x12\xa8\xfe\xd5\x0d\x88\xea\x38\x95\xca\x13\xf7\xba\xc7\x22\x6b\x36\x5c\x8c\x1b\x49\x5b\x14\x83\x34\xc9\x7b\x5c\x95\x22\xdd\xbd\xbe\x02\x78\x2a\xf9\x18\x61\x15\x1b\x12\xe4\x9d\x31\xd9\x1b\x2b\x4b\x30\xf7\xfa\x1a\xf8\xb2\x18\xdf\xfb\x31\xee\x62\x5f\x64\xcc\x68\xc2\x00\xfd\x78\x1e\xc4\xba\x70\x16\x9b\xbb\x11\x3d\x77\xc9\x14\xc2\xff\x7d\x42\xde\x4e\x26\xa5\x9b\x44\x2d\xd1\x37\x2f\xf1\xe0\x8f\xef\x0a\xf8\x05\x78\xdd\x01\xca\x64\xb7\x8c\xf3\xa3\xd8\x2e\x90\xd0\xfd\x4e\x1d\x9a\x07\xb6\xb2\x7f\x26\x35\xbc\xde\x01\x8b\x9c\xc2\x16\x68\xab\xb0\x07\xdb\x26\xc4\x52\xc5\xbb\xfc\xcf\x45\x30\xab\x5f\xe4\x5a\x41\x31\x2e\x57\xaa\x00\xb7\xef\x01\x63\x7f\x1e\x4e\x30\xf4\xa7\xe1\xdc\x1f\x63\x1c\xcc\xe7\x41\x0c\x1f\x5f\xc3\xf9\x03\xee\x63\xff\x4b\x50\xa8\xbc\x64\x66\xe5\x0a\x4e\xe9\xb7\xe2\xc1\xf5\x2f\x9a\xf1\x38\x61\x6b\xca\xb5\x01\xaf\xdb\x8c\x37\x0c\xe3\xe1\xe2\xf1\x6e\x1c\xfc\x25\xaa\x37\x21\x05\xa8\x2c\xd0\x85\xd0\x34\xb6\x75\xdc\xfe\x65\x33\xf2\x3c\x1c\x8f\x84\xa5\x42\xe6\xf2\x37\x9c\x44\x5e\xec\x4d\xfa\xd5\xed\xf7\x9a\x91\x0b\xb7\xf7\x7f\x57\xc7\x6e\xff\xaa\x19\x3d\x66\x2c\xf4\x3f\x47\xe2\xd8\x4e\x4f\x5b\xad\xc1\xc7\xfa\xc1\x6e\xff\xda\x86\x1c\xa8\xbb\x2c\x2f\xeb\xf3\xee\x16\x7f\x60\x80\x22\x47\xad\x7f\xc4\x91\xfb\x16\xe4\xa1\x3c\x45\x9d\xed\xde\x6f\x32\x13\xda\x92\xb0\x5e\xa7\x63\x81\x0d\xca\xc1\x2b\x63\x57\x87\xae\xa8\x34\x6f\x0a\x97\x89\xd7\x71\x9b\xa1\xec\x71\x2b\xdf\x61\x6e\x4a\xd5\xad\xd7\xb1\xf1\x2a\x30\xc5\xad\x0c\xdb\x3c\x6a\x2d\xa0\x36\x72\x05\xf5\xc0\xaa\x56\x20\x02\x55\xc3\x96\xb8\xe0\x75\x6c\x2c\x0b\xeb\x59\x40\xa7\x01\x29\xb5\x6d\x97\x83\xd7\xb1\x11\x2c\xac\xba\x54\xf9\x54\x39\xb5\x09\xd4\xc6\xad\xf0\x43\xf9\xa0\x09\xd9\xc6\xab\xf0\x63\xac\xa5\xe5\x17\xbc\x32\x6b\xbd\x8e\x8d\x5b\xc1\xfc\xc1\x29\x14\x80\x54\x37\xb0\x59\x29\x94\x3f\x98\x54\x6b\x21\xaf\x63\xa3\xd4\xa4\x9a\xbe\xf2\xfc\x55\x48\x60\xaa\xe9\x4b\x0c\x2d\x5f\x06\xef\xda\xa8\x15\xd5\xa8\x05\x21\x12\x12\xa8\x32\x5d\x55\xdc\xc5\xd0\x75\x6d\xfc\x8a\x8c\xfc\x92\xa1\xd0\x80\x67\xe3\x57\x64\xe7\x97\x8c\x82\x06\x50\x1b\xbf\xa2\x8a\x4f\xa5\x47\x95\x3f\xb5\xb6\x37\x3c\x64\x78\xae\x8d\x5b\x91\x91\xb4\xff\xad\xf1\xe1\xb9\xac\x54\x58\x8c\xe7\xe1\x74\xcc\x24\x5c\xb9\xb2\x64\x27\x9d\xf1\xad\xdf\xf2\xc2\x48\x7e\xc1\x21\x9f\x6c\x23\x93\x34\x6d\x36\x67\x55\x6e\xe5\x25\x92\x10\xf5\xfe\xad\x1a\x6d\xaa\x39\x51\xb2\xcb\xc6\xa6\x85\x39\xa3\x50\x1d\x41\xf6\x37\x21\xcf\xb5\x91\x68\x61\xce\x28\x94\xab\xaa\xf7\x40\x6d\x44\x5a\x34\x64\x14\xaa\x63\xa9\x01\xd9\xb3\x71\x68\xd1\x7c\xf2\x1f\xea\x5f\x79\x9e\x8d\x51\xdf\x2a\xce\x60\xae\x90\x7c\x4a\xf0\xc5\x50\xec\x7a\x9e\x8d\x4c\xf3\x87\x28\x9e\x38\x86\xbe\x3b\xef\xfa\xd7\x7a\xba\x9e\xa7\x09\x34\x7b\xf4\xc7\x1a\x66\xf6\xe0\xc7\x53\xcc\xfe\xe7\x4e\x97\xe7\x75\x8d\xb8\xbe\x35\x17\x35\x3d\x9e\x78\xde\x65\x13\x9a\x35\x13\xd9\xd0\x7a\x4d\x68\xcd\x79\xc8\x06\x79\xd5\x04\xd9\x90\x85\xac\xfd\x4b\xcf\xbb\x6e\x82\x6c\x12\x0e\xcd\xb0\xfd\x26\xd8\xb2\x14\x95\x17\x9c\x50\xa4\xf6\xcd\x5f\x74\xcc\x90\x41\xe1\x82\x92\xef\x10\xfa\x79\xe3\xbb\x7a\x86\x3a\xab\x5e\x95\x02\xd2\x35\x42\xd6\xc4\x27\xac\x6f\x65\x5c\x74\x72\x28\xcf\x08\x65\x14\x9c\xa2\x56\x32\x3f\x91\x79\x17\x66\xaa\x54\xe5\x26\x55\xad\x77\x3b\x90\x99\x1b\x26\x9d\x29\xc2\x4f\x45\x9f\x19\xcd\xcc\x8d\xba\xc0\xa4\xba\xed\x28\xa3\xa4\xcd\x9b\x34\x09\xad\x7c\xcd\xc8\xbb\x30\xf3\x23\x6c\x94\xe8\x86\x9e\xb3\x77\x61\x66\x45\x55\x4d\xca\x0a\x85\x5a\x1f\xdd\xbc\x0b\x33\x17\x8c\x0a\xb2\xaa\xcc\x8b\x1d\xdd\xe2\x26\xcd\x3c\xa8\x4b\xc7\x42\xbb\x96\xe6\x0d\x76\xcb\xd7\x03\xbc\xae\x99\x0b\x4a\x33\x66\x99\xbc\xe5\xb2\x4c\x10\xe1\x3b\xaf\x76\x0d\x2f\x12\x5e\xd7\x4c\x81\x9a\x58\x34\xd4\xba\x54\x7d\xd9\xc1\xf0\xe5\x17\xaf\x6b\xe6\x43\x5d\x25\x16\xf8\x60\x7a\x8e\xf4\xba\x66\x3e\x54\xe5\x61\x89\x0f\x66\x20\x33\x1f\x3e\xa4\x0b\xcd\x5f\x69\xf3\xba\x66\x52\xbc\xaf\x0a\xad\x2f\x44\x5e\xd7\xcc\x0a\xb3\x26\xfc\xf0\xc3\x93\xd7\xbd\x02\x46\xe1\x97\x70\x56\x14\x82\xc5\x2e\x10\x35\x7d\xd5\xcc\xeb\x9a\x19\x51\x95\x81\x28\xbd\x2a\x13\xc2\xbc\x5f\x78\x7a\xe6\x48\x66\x22\x18\x54\x9f\x12\x7d\x0d\x4f\xb6\xde\xa5\x39\xfe\x6b\x72\xaf\x7c\x53\x5b\xd1\xcc\x1c\x30\xea\xbc\x4a\x64\x58\x21\xcd\xe1\x6f\x16\x78\x1f\x7e\x11\xf4\x2e\xcd\x64\xa8\x2a\xbb\x5a\xe1\x6c\x7f\x4a\xf6\x2e\xcd\xb4\xd0\x0a\x0f\xb9\x2c\x23\xa5\xfe\x6f\xfd\xcb\x00\xde\xa5\x99\x0f\xdf\x3e\xd8\xde\x22\xfa\x31\xe9\xac\xf4\x3d\x39\x86\xfd\xff\x01\x00\x00\xff\xff\xba\xc5\x6a\x59\xbf\x2f\x00\x00") + +func fontsSmslantFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmslantFlf, + "fonts/smslant.flf", + ) +} + +func fontsSmslantFlf() (*asset, error) { + bytes, err := fontsSmslantFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smslant.flf", size: 12223, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSmtengwarFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x55\x51\x6b\xdb\x30\x10\x7e\xd7\xaf\xb8\x07\x43\x1c\x70\xe4\xa6\x63\x63\x2d\xa5\x53\xc7\xd8\x5b\x1f\x06\x1d\xec\xc1\xa0\xc8\xb1\xd3\x78\x75\xed\x62\xa7\x0b\x85\xc3\xbf\x7d\xe8\xce\x92\xe5\xf4\x65\xdd\x5e\x07\x8d\x6a\xdd\x9d\xee\x3e\x7d\xdf\x97\x78\x57\xef\xce\x4d\x04\xef\xe0\x1c\xd6\x6b\x38\x83\xf7\xe2\xae\x6a\x5e\xe0\xae\x6c\xee\x8f\xa6\x83\xb5\x3c\x83\xfc\x05\x3e\x97\x75\xd5\x14\x06\x6e\xfa\xbc\xac\x6b\xb8\x7a\xcc\x8d\xda\x6e\x0b\xb9\x37\x5d\x57\xf5\x72\xdb\x3e\x5e\x8b\x9b\xc2\x3c\x1d\xca\x02\x76\x5d\xfb\x08\xb7\xd5\x43\x09\xdf\xbb\xdc\x34\x8b\x1e\xae\x9e\xed\x83\xea\xab\xa2\xec\xf7\xed\x51\xfe\x7c\xaa\x65\x63\x7a\x23\xef\xdb\x5f\xd7\x7e\xd4\xae\xed\x40\xdc\x96\x07\xb3\x6b\x9b\x03\xc4\xc7\x7d\xb5\xdd\x43\xd5\x27\x50\x35\x70\x78\xee\x9a\x04\x72\xd3\x97\x05\xb4\x0d\xdc\xb5\xf5\x43\x55\x36\x70\xb9\x14\x5f\xcc\xa1\xbc\x84\xf3\x8f\xf0\xb5\xcc\x61\x7d\x71\xf1\x41\x88\x48\xf1\x9f\x12\x69\xa4\x44\x16\xd1\x7f\x25\x52\xb0\x5b\x00\x70\xab\x12\x1a\x51\x47\x4a\xac\x10\x57\x1c\xa4\x68\x8c\x9b\x48\x09\x89\xcb\xa9\xb0\xb5\x47\xd3\x96\x02\x76\x0f\xdf\x6c\x97\x58\xff\x98\x4a\xa8\x39\x7f\x94\xa0\x51\x48\xdb\xcc\xee\x33\x7a\x44\xdb\x84\xf2\x19\x52\x43\xcc\x42\x2c\x9a\x6a\x02\x78\x63\x3b\x86\x4f\xb8\x57\x2b\x0f\x41\xca\x68\x5c\x60\x1a\x99\x82\xdf\x6f\x06\xdb\x3c\xd1\x69\x30\x42\x6b\x42\x0d\xb3\x10\xc7\x62\x1d\x30\xa0\x75\x10\xf7\x19\xce\x0d\x8c\x10\x99\x80\x84\x43\x9a\xb1\xc7\x7c\x26\x01\x17\xf5\x71\x9f\x19\xc1\x0e\x48\x4d\x91\xa2\x38\x86\xf4\xa8\x0d\xea\x25\x97\xe3\x54\xae\x21\xcc\x06\xf9\x89\x2a\xe9\xd8\x97\xe1\x26\x59\x44\x4a\x6c\x26\x9e\x08\x52\xc0\x23\x4b\x73\xed\xa5\x21\xd9\x79\x61\x5d\x89\x47\x54\x01\x8f\x72\x91\xbc\x92\xca\xe2\xb3\x75\x16\x1c\x9d\x75\x09\x00\x77\x47\xbe\x6f\x50\x0b\x4b\x98\xd5\x12\x54\x40\x0f\x0d\x5d\xcb\xb9\x5e\x4e\x18\x1c\x75\x41\x7f\x8d\x34\xf3\x67\x6d\x2b\xf4\x76\x04\x07\xe3\xe4\x94\x6b\x16\xa2\x1b\x8d\xb6\x9a\xf4\x3d\xbd\xdc\xc4\xfa\xc9\x4d\x7c\x62\x3b\x9b\xce\xca\x8d\xaa\xa2\xbf\x09\x06\xa3\xc1\x5b\x3c\xb3\x44\xc7\x6e\xae\x7d\xe6\xd6\x29\x4c\x21\x74\xbc\xd9\xd0\xa7\x70\x96\xf7\x89\x77\x09\x84\x68\xfd\xd9\x61\x18\x1c\x31\x78\x42\x4c\x50\xbb\x08\xa9\x9f\xa3\x59\xd2\xb4\xc1\x7d\xcd\xed\x97\xd7\x79\x69\x12\x81\x5d\x6e\x17\xf6\xb8\xd7\x47\x84\xe6\xe0\x95\xa4\x78\xdd\xe2\xbf\xd7\xde\xe6\x35\x16\x7f\xa0\xbb\xb2\xc6\x7f\x62\x34\x46\x3c\x84\x46\x0b\x1b\xbd\xd5\x68\xc1\xd9\xbf\x31\xda\x0c\x0d\x19\x2d\xb6\x46\xbb\x62\x5a\x69\x7a\xe4\x3f\x4a\x70\xa1\xfd\x05\xd3\x54\xbc\xd8\x2c\x4e\x5f\x74\xd3\x2b\xf1\x5f\x9e\x7e\x07\x00\x00\xff\xff\x7d\x58\x6d\xad\x2c\x08\x00\x00") + +func fontsSmtengwarFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSmtengwarFlf, + "fonts/smtengwar.flf", + ) +} + +func fontsSmtengwarFlf() (*asset, error) { + bytes, err := fontsSmtengwarFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/smtengwar.flf", size: 2092, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsSpeedFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x5a\xdd\x8b\xe3\xc8\x11\x7f\xef\xbf\xa2\x58\x0c\xe7\x21\xde\x6d\x4b\xfe\x0e\x73\x8b\x43\xc8\xc3\x41\x42\x02\x07\x79\x12\xf4\x68\xc6\xf2\x58\xc4\x23\x2f\xb6\x26\xb7\x0b\xfa\xe3\x43\x57\x77\x55\x77\x4b\x2d\x5b\xde\x5d\x72\x1c\x63\xed\x8c\xba\xba\x3e\x7f\xf5\xe5\xfd\x71\x9f\xe6\x23\x58\xc2\x02\x92\x25\x24\xfa\xa7\xf8\xfd\x4b\x51\xec\xe0\xf9\x1b\xfc\xf5\x98\xbf\xef\x0a\xf8\x47\x7e\xae\xcb\xea\x02\xa9\xdc\x2c\xe0\xe3\x47\x78\xce\x2f\xc5\x0e\x4e\x15\xfc\x7e\xcc\xab\x5a\xfc\x56\xbd\x1c\xdf\x77\xc5\x05\x7e\xfb\xfd\x9f\xf0\xf7\xbc\x2e\xab\x8f\x89\xd8\x97\xaf\xc7\xa2\x86\x73\x71\x2c\xf2\x4b\x01\xe9\xa7\x44\x9f\x4c\x52\xf8\xcb\xfb\x2b\x24\x9b\xcd\x5c\xfc\xab\x38\xbf\x95\x97\x4b\x79\xaa\xa0\xbc\xc0\xa1\x38\x17\xcf\xdf\xe0\xb5\xfc\x6f\x51\x41\x7d\x82\xb7\xd3\xae\xdc\x7f\x83\xfa\x50\x5e\x60\x7f\xaa\xea\x09\xe4\x17\x38\x9e\xaa\x57\xfd\x59\x1f\x0a\x81\x2f\x94\xc5\xf9\x97\x0b\x54\xf9\x5b\xa1\x69\x7c\x39\xe6\x2f\x86\xb1\x1c\x5e\x4e\x6f\x6f\x45\x55\xc3\xb1\xac\x8a\x4f\x42\xfc\xed\xeb\x97\x63\x5e\xe5\xb5\xbe\xed\xb4\x87\x7d\x79\xbe\x98\xbf\xfd\x59\x68\x0d\xc0\x47\xf8\xf0\x96\xbf\x96\x2f\x50\xbd\xbf\x3d\x17\xe7\x0f\xb0\x3f\x9d\x61\x5f\x1e\x0b\x28\x77\x45\x55\x97\xfb\xf2\x05\x0f\x8b\x1c\x00\xe0\x23\x5c\x0e\xa7\xf7\xe3\x0e\xf2\xe3\x1f\xf9\xb7\x0b\x3c\x17\xf0\x94\xff\x32\xc1\x43\xd5\xe9\x0f\x31\x32\x2f\xd5\x87\x02\x3e\x1c\xf2\xf3\xee\xf9\x98\x57\xff\xf9\xa0\x15\xf0\xe5\x5c\x56\xf5\x45\xcb\x90\x03\xfe\x76\x02\xcf\xef\x35\xbc\xe4\xd5\x2f\xb5\x26\x73\x79\x7b\xbf\x1c\x8a\x9d\x58\x1a\x0a\x87\xa2\x7c\x3d\xd4\x9a\xe3\x1c\x5e\x0e\xf9\x39\x7f\xa9\x8b\xb3\x58\x5c\xf9\xe3\x04\xaa\x53\x0d\x25\x9a\xa4\xac\x5e\x61\x57\x5c\x5e\x8a\x6a\x57\x9c\x2f\x22\x99\xe3\xb1\xb7\xfc\x2b\x4a\x0e\xc7\xa2\x7a\xad\x0f\x30\x2e\xbe\xd2\xcb\xbe\xd2\x2e\x0f\xf0\x27\xc8\x61\xff\xbe\x7b\x2d\x60\x9f\xbf\xd4\xa7\xb3\x48\x16\x48\x61\x57\xec\xf3\xf7\x63\x6d\x98\x7d\x3b\xed\x0a\x14\x9c\x4d\x25\x92\x25\xbe\x66\x54\xa9\xf9\x0b\xe8\x0a\xa1\xd9\x87\xd1\x68\x2b\xcc\x27\xe0\xc3\x68\x04\xf8\xa0\x3f\xf5\x03\x7e\xc2\x56\x98\x4f\xd8\x6e\x85\xc2\xff\xf0\x13\x40\xea\x4f\x00\xa9\x5f\x95\x4a\xea\x37\xc7\xea\xc1\x1c\xf5\x0e\x80\x82\xad\x50\x63\x68\xe0\x61\x2b\x54\x23\x1b\x69\x2e\xb1\x77\x40\xe7\x80\xc2\x43\x78\x4a\x29\x25\x41\x4a\x90\xfa\x4e\x50\x80\xff\x2b\xb9\x15\x92\x9f\xed\xed\xc8\x80\xa3\xd4\x22\xc7\xa4\x0c\xcb\x48\x42\x8d\x15\xc0\x03\x6c\x85\x04\x30\xdc\x13\x0d\xf3\x36\xe8\xf7\xf4\xe3\x58\x3d\x28\x89\x27\x34\x0d\xf3\x2a\x3e\x28\xa0\x53\x28\xb7\x77\x37\xdf\x0c\xe6\xe5\x31\x28\xc0\x37\xf0\x72\xc8\x64\xa3\xaf\x45\x5a\x8f\xb0\x15\x19\x52\xce\x64\x97\x84\x51\x9d\x51\x9c\x55\xd7\x56\x8c\x58\xd0\x8e\x84\x8a\x8d\x62\x2e\x93\x86\x45\xb0\xca\x69\x54\x13\xb2\x67\x1e\x1a\x68\x48\x66\x49\xc6\x25\x21\xbb\x8a\x51\x40\xa6\x69\xf4\xb5\x48\xd1\x98\x44\x53\xda\x0a\x68\x42\x53\x6c\xdd\x53\x70\xad\x31\xab\x24\x7b\x18\x75\x74\x8e\x85\x3f\x3b\x2a\x71\x1a\xf3\x9f\x94\xd3\x8a\xc4\x07\x69\x1c\xbc\xf5\xde\xb5\x1b\xd4\x43\x5b\xc5\xa4\x64\x15\xf7\x06\x00\x4f\x55\x71\x6f\x30\x82\x1b\x17\xb0\xe6\x41\x9f\x34\xae\x20\xd9\x13\x5a\x4c\xba\xcb\x1f\x83\xa8\x23\x3b\x87\x8a\x0b\x8d\xdb\xd8\xbb\xd8\xfd\x29\x68\xa4\xf9\x95\xaf\x6e\x5f\xcc\xc6\x39\x83\x54\xe8\xa4\x96\x84\x3b\x1a\x61\xd2\x46\x0c\x60\xcc\x1a\x06\xc9\xca\x6c\xe6\xb6\x9d\x03\x0d\x13\xb6\x58\x9b\x59\x41\x32\x7c\x9d\x18\x20\x0e\x5a\x64\x3a\x22\x20\x15\xc9\x31\x07\x83\xf5\x2c\x5b\xe8\x76\x43\xcf\x8a\x42\x5c\xa1\x57\xe2\x6d\xd0\x0c\xbc\xad\xeb\x12\xd6\x4e\x99\x52\x93\x7e\x6d\x07\x8e\x6e\x3e\xd1\x63\x19\x72\x02\x44\x1a\x74\xc0\x02\x14\x06\xaf\x65\xcf\x30\x64\xf0\x63\x2b\x32\xd4\x21\x64\x2a\xe3\xc8\x68\x07\x1c\xa2\xb4\xb2\x08\xcd\xfe\x35\x6a\xc3\x01\x63\x08\x52\x54\xe4\xa2\x46\xe9\xd2\x79\xe5\xd6\xe3\x97\x34\xa4\x24\x28\x7a\xad\x27\xe3\xb4\x14\xeb\x45\x9b\x52\xf0\x64\xe5\x61\xdb\x80\xd6\xb4\x55\x70\xc6\x6e\x15\xda\x47\xeb\xc8\x60\x24\x80\x34\x68\x89\x94\xd1\xcc\xfa\x40\xa3\x9a\xa8\x43\x03\xfb\x33\xfa\x86\x73\x0e\xb2\xb4\xef\xcc\x51\xc8\xf0\x7c\xd9\x3a\xb3\xb4\x3a\xd7\x32\x58\xeb\x65\x91\x70\x88\x73\x41\x8a\x06\x0e\xd0\x81\x5c\x74\x22\xd3\x00\x09\xe5\x19\xe2\xe4\x66\x64\xc6\x08\x61\x26\x05\x06\xa7\x10\x48\x7b\x09\x75\xf5\x62\xdc\x8a\x6c\x7b\x4b\x2f\x94\xdf\x3d\x75\x78\xfa\xb0\xa6\xe2\xc0\x6f\xa3\x56\x07\x6e\x90\xa0\x44\x9c\xa2\xfc\x6b\xd8\xb0\x5a\xe9\x07\x3d\xc7\x90\xa4\x8a\xc9\x98\x64\xa8\x20\x4e\x0e\x2e\x00\x26\x8f\x6c\x9a\x06\x1a\x12\x02\xf3\x7f\x94\x44\x90\xf6\xbd\xfa\x81\x00\x91\x73\x68\x47\x85\x74\x37\xa6\x7d\x52\x62\xe3\xb4\x28\x8d\x7a\xc9\xa4\x5d\x3d\x7a\x75\x85\x93\xa4\x71\x16\xd1\x84\x25\xcb\xe2\x48\x35\x57\x2c\xf2\x23\x89\x36\x1a\x2f\x5e\xf6\xa4\xfc\xf9\xc3\x89\x3e\x53\xd9\x77\xdc\x3f\x01\xbe\xbf\xd7\x9c\xad\x04\x68\x30\x70\x60\x0e\xf7\x23\xd4\x55\x93\xae\x9c\xf4\x64\x8f\x14\x00\xae\x02\x70\x08\x03\x72\xb8\x3b\x03\x3b\x01\xa0\xad\xa5\x7d\x94\xe4\x9a\x8d\xa4\xe0\xba\x46\x22\xa0\x02\x01\xa1\x90\x96\x4f\x4e\x36\x5d\xe4\xf2\xda\x01\x92\xac\x71\x9e\x49\x7e\x09\x1c\x62\x2d\x93\x6c\xc9\x0e\xfa\xb5\x4c\xde\x51\x55\x6c\x3b\x4d\x96\x09\x47\x32\x5d\x24\xe5\xf9\x28\xa4\x3c\x14\x8a\x19\xd0\xaf\xe8\x01\x38\x1b\x53\x05\x9c\x91\x4e\xd8\x6d\x14\xa5\xfd\xd8\x9d\x14\xf9\x0e\x42\xa2\x18\xc8\x77\x82\xd4\x1d\x90\x6e\x06\x1b\x5b\x20\xd8\x56\xd0\x34\x37\x5e\xfe\x67\x45\xde\x78\xf2\xf8\x21\xb4\xda\x86\xdd\x82\xfa\x77\xbc\x81\x6a\xd3\x00\x45\xe0\xff\xd4\x8e\xd8\x49\x4f\xc4\x00\x8b\xdc\x57\xce\x49\xf5\x29\x2c\xb7\xfb\xaa\x27\x1b\xb2\x98\xdb\x29\x52\x64\xa7\x7a\x8a\xe5\x0d\xca\x57\xed\x40\x9b\x44\xa2\x24\xb8\xd8\x26\x3b\xcd\xb0\xb4\x41\x9f\x05\xcc\x5e\x43\x06\xe5\xe7\xed\x1e\x64\x80\x8e\x99\x80\xf1\x09\x95\xec\xa7\x5d\x5b\xf7\x7a\x10\x35\x4c\xcf\x16\x60\x6d\xa6\x8e\x20\x93\x5f\xf3\x0e\xab\xeb\x15\x33\x4c\xa5\xb2\xe7\xdf\xce\xc1\x5d\x9b\xad\x54\xd8\x28\xfb\x0c\x73\x63\x64\xab\x15\x9b\xa0\x7b\x20\xa3\x1f\x01\xa2\x0c\x07\x78\xe5\x94\xec\xe7\xa1\xa7\x50\x55\xa1\xba\x42\x95\xf5\x04\xc6\x5d\x3a\x6f\x07\x15\xb7\x61\xec\x9e\x9c\x05\x22\x83\x02\x3f\xa2\xaf\x25\xc3\x4f\x9d\x64\x7c\x5f\x3c\x83\x0d\x2d\x49\x7e\x16\x05\x14\xbf\x93\xbc\x96\x01\x6f\x1c\x1e\x2b\x1a\x38\xf5\xe6\x5e\x82\x6b\x62\xd9\x32\x6c\x23\x59\x46\x6d\x1e\xa4\xa7\x78\xa5\xd1\xc5\xad\xe0\xb0\x9f\x2c\x39\x51\x4a\x76\xf4\xde\xc3\xde\xf9\x80\x44\x40\xc5\x23\x64\xf3\x6b\xbb\xf6\x8b\x0a\x82\x79\xd6\xa0\xcc\x67\x80\xc7\xde\x50\x69\x3b\x4c\xb4\x00\xb9\x8e\x2d\xa1\xd1\x5a\x51\x47\x20\x1b\xc9\xb7\x56\x28\xc3\xa4\x6d\x47\x1f\x35\xab\xe0\x8f\xdc\x74\x91\x17\x39\xd6\x9e\xb4\x75\x46\x76\xe1\x2c\xb2\x33\xa9\x93\x94\x70\x3f\xab\xcf\xdb\xf8\xa4\x4e\x66\x12\x1b\x65\x1a\x2c\x86\x13\xd7\x51\xe0\xbf\x5e\xfd\xc6\x40\xc9\x58\xa9\x4c\x75\x63\x82\xe8\x56\x2f\x01\x44\x62\xac\x1e\x2c\x6e\xda\xf9\xcb\xe0\x8e\xc6\x27\x01\x44\xe2\xae\x2a\xb2\x97\x8b\xa7\x61\xf9\xf1\xff\x2f\x48\x1f\x17\x7e\x1e\x72\x18\xd8\x6e\x59\x75\x8b\x67\xc7\x6d\xad\x44\x8c\x84\x92\xe5\xf4\x7b\x27\xfe\xc9\x32\xb9\x3f\x7f\x26\xcb\xb4\x15\x24\xae\x79\x0a\x8a\x9b\xee\xe4\x3d\x59\xce\x22\x72\x4f\xb0\xfa\xb4\x33\x63\xe0\xba\xd2\x66\xd8\xb1\x9a\x74\x60\xca\x12\x9b\xa3\xb2\x34\xf0\x28\x69\x22\xa7\x81\x20\xe8\xc8\x04\x26\x5b\x62\xb7\xb0\x15\x38\x03\x6b\xa2\x0b\x85\x64\xb9\x10\x36\xb7\x2a\x4b\xcf\x0a\x17\xac\x26\x94\xdb\x8a\xb4\x00\x2b\x59\x2e\xe3\x48\x60\xce\x28\x1e\xc8\x75\x91\x20\x59\xae\x44\xa8\x19\x09\x64\x0f\xeb\x01\x0d\x34\xee\x89\x26\x64\x1e\x81\xb5\xf0\xdc\x92\xbd\xd2\x60\xc3\x88\xd0\x81\x6b\xe4\x51\x97\xf9\x8d\xb3\x8e\xab\x6e\xf0\x5f\x19\xe3\x18\x32\xd6\x90\xb3\x93\xba\x1b\x80\xcc\x4d\x70\xcd\xa8\x8d\x31\x38\x59\x4d\xfd\x74\x8d\xa0\x83\x95\xa1\xca\x30\x34\x82\xa4\x39\x02\xe8\xaa\x75\x95\x38\x00\x07\xce\x81\x3c\xb8\xa4\xd1\xa5\xeb\x62\xf0\x50\xda\xdf\x42\xa0\x5d\xf4\x5f\xa4\x3f\xc6\x6c\xdf\x3a\x73\x95\x4e\x9b\x10\xb5\x22\x6e\xf7\xe0\x57\x3a\xc9\x6a\xde\xa3\x4a\x00\x4f\x95\x1a\x6e\x48\x95\xd8\xf9\x1b\x55\xda\x5c\x18\x57\xe5\x22\xd6\x0d\x05\xfb\x0f\x16\x25\xae\xca\x65\xa4\x31\x90\x5c\xb2\xc9\xd8\xde\x2e\x59\xad\x3a\x65\xb3\xe4\xf4\xc9\x1d\x83\x5d\x9b\xf5\x8e\x1b\x93\x95\xf6\x50\x70\xdb\x0b\xe0\x61\x6b\xb8\xb4\x68\x19\x03\x8f\x6e\x84\x17\x98\x0d\x05\x96\x5d\x5f\x5c\x3d\xba\x36\xde\x67\xc6\xca\x46\x41\xd1\x5e\x31\x59\x27\x3e\xc2\x70\x95\x7f\x63\x90\xf8\x89\x2a\xb0\x10\x95\xd7\x69\xd0\xcb\xe1\x46\xd3\xce\xdb\xc7\xec\xbb\x8a\xc7\x67\x9a\x62\x24\x4b\x24\xeb\x59\x74\x75\xe5\x44\xe0\x17\xe7\x10\xac\xba\xfc\x9f\xf6\xac\x54\x0f\xf8\xa6\x75\xa1\xad\xa0\x95\x93\xed\x2c\x8d\x18\xad\x1e\x3d\x59\x2f\xbd\x32\x9f\x5c\x46\x87\x6e\x6b\x13\x10\xd3\xfc\x4a\x78\x01\x60\x03\xd5\xcc\x1d\xdc\xa8\x9a\x3c\xa7\x75\x74\x4d\x47\xed\xb6\xf8\x11\x23\xc6\xbc\x67\x7a\x12\x45\xf3\x4b\xdd\x76\x59\xdb\xd8\x86\xc7\x0e\x6b\x81\x22\xdc\x90\xdc\xf8\x24\x21\x20\x6a\x15\x64\xc8\x5a\xc7\xb4\x8b\x67\x19\x00\x7e\x7b\xb3\xe6\x38\xde\x4c\xc9\x43\x81\x99\x36\x8e\x0a\xcc\xb7\xf1\x57\x8f\x75\x4d\xcc\xe3\xde\xb2\x1b\x0a\xe0\xcb\xb0\x49\x84\x57\x31\x06\x09\x1b\x05\x81\x48\x7b\x9f\x6c\x52\x11\xc4\x6e\xa6\x32\xae\xfd\xb8\xf2\xe3\xba\x2f\x30\xc3\x66\x16\x2d\x88\x07\x1d\x35\x10\x68\xa7\x41\x3a\x99\xe2\x40\x88\x6a\x4e\x57\x72\xba\x8a\x33\x44\xaa\x8d\xf5\x53\x5b\xea\xa2\xaa\x32\x09\x77\x96\xad\xc9\x66\xf9\x33\xaa\xdf\x64\x63\x7c\x79\x3c\x7e\xe0\xc5\xda\x5d\x4b\xa3\x64\xb3\xf6\x52\x82\xf2\x46\xeb\x10\xae\x4b\x9a\x60\xf7\xa2\xc2\xfd\x8b\xa9\x8b\x62\x93\x4c\x7b\xc9\x26\x9c\x20\xdd\xb1\x5a\x92\xb8\x6c\x43\x32\xe9\x74\xda\xe7\x31\xb4\x73\x95\xde\x4c\xc4\x37\x7b\x3a\x4d\xfa\x3c\xe6\xf6\xd1\xb4\xdf\x63\x14\xad\x6d\xae\xec\x5c\xd2\xe9\xec\x9a\xa9\x15\x35\x61\x6e\x0b\xa5\x3a\x5f\x2c\x41\x32\xf3\x1e\xe9\xed\xf0\xd5\xdb\x53\x77\x44\x58\xf4\x48\x3f\xe0\xe8\xb2\x57\x7a\x20\xf4\xb8\xb6\x71\x4a\xa7\xab\x2b\xd2\x83\x0a\x26\xb6\xd7\xa4\x5f\xdf\xe8\x4d\x68\xe8\x69\x54\x6a\xa1\xb1\x9b\xf0\x0d\xb1\xcd\x95\x18\x76\xab\x1f\x70\xcd\x46\x67\xf1\xa3\xc9\x24\x51\x7f\x1c\x32\x73\x4a\x93\xa8\x3f\x0e\x3b\x9a\x0a\xdf\x20\xd6\x1e\xc3\x8e\x1a\x4f\x64\xb1\x49\xea\xa1\xdf\x56\x48\x93\xf9\xcf\xe8\x53\xd3\x64\x61\x13\xb9\xa0\x94\x27\x1b\x2d\x0e\x7c\xc6\xba\x89\xbf\xb0\x45\xaf\x2f\xc3\x3a\x4f\xbb\x8d\xa4\x81\xa0\x94\x54\x78\xe3\x13\xde\xca\x2d\x69\x78\xeb\x8a\x8b\x27\xb6\x57\xff\x00\x2b\x26\xfd\xba\xdd\x0b\x29\x79\x1f\x81\x0d\x99\x0e\xd8\x76\x77\x11\x48\xa7\x3f\x63\x5a\x91\xa6\x49\xe0\xb8\x56\x0c\xb7\x2d\x6a\x7f\x19\xcb\x3f\x9a\x86\x4a\x8c\x0d\xc6\x15\x15\x61\x91\x81\x65\x9a\xc6\x9a\xed\xef\x1c\x32\xa4\xe9\xbc\xcf\xa4\xc3\x76\x29\x69\xba\xe8\x33\xe9\x50\x02\xcb\x3e\x93\x0e\x25\xb0\xea\xc6\xe4\x7d\x04\xd6\x3f\x63\xfc\x94\xa6\x9b\x96\x26\x6c\x4d\x31\x98\x8f\xd9\xb4\x33\xa5\xf5\x36\x02\x86\x0c\x78\x18\xe5\xf6\x3e\x13\xa5\xba\xe5\x2b\x92\x4c\xee\x5b\x58\xd9\x62\x01\x8f\xa6\xfe\x0c\x89\x91\xf9\xea\xc6\x29\x9d\xcd\x84\x07\xca\x8c\xc9\x37\x0e\xcd\x7b\xf0\xd8\x22\xaa\xad\x12\x22\x5b\xb5\x74\xb6\x10\x7e\x6a\xe4\xcc\x68\x0e\xbb\xd3\xee\x78\x5b\xe7\xcb\xae\x94\xb7\x26\x65\xe9\x6c\xd5\x95\xf2\xf6\xa1\x75\x4c\xca\xde\x19\x72\x20\xe5\xc6\x8c\xaa\x78\x02\x44\x1d\x82\x1c\xb6\xe5\x4f\xe7\x16\xf5\x1a\x1b\x63\xea\xd7\xa6\xf9\x75\xeb\xfd\x4e\x37\x43\x4f\x08\x15\x71\xd8\x9c\x27\xd7\x6a\x76\xbb\x70\xf6\x10\x94\xbe\x7b\xd3\x0a\x91\x79\xb4\x63\x19\x94\x79\xe7\xd1\x8e\x65\xd8\xd1\x3e\xff\x1a\x70\x74\xf1\x83\xf9\x7e\xbe\xfc\x29\xf9\x7e\xbe\x6a\xc5\x31\x70\x29\x18\x7c\xd5\x27\xfc\x66\x9d\x39\xba\x8e\x2f\x05\xb9\x06\x90\x5c\x02\x50\xde\x6f\x89\xb0\xb9\x27\xeb\x47\x70\x6d\x31\xbd\x27\xeb\xc7\x08\x24\xf7\x64\xfd\x18\x81\xf4\xde\xac\x1f\x45\xf8\xc5\x4c\xb4\x12\xaf\xcb\xfc\xc3\x57\x57\xe9\x82\x87\x88\xc0\xf9\x5b\xde\xbd\x32\x4d\x17\x0b\x37\xf7\x60\x6f\x00\x6f\x76\xe0\xbe\x81\xc5\x03\x73\xe2\xc8\x67\x49\x13\xfb\x5f\x00\x00\x00\xff\xff\x24\x85\xba\x3a\xcf\x32\x00\x00") + +func fontsSpeedFlfBytes() ([]byte, error) { + return bindataRead( + _fontsSpeedFlf, + "fonts/speed.flf", + ) +} + +func fontsSpeedFlf() (*asset, error) { + bytes, err := fontsSpeedFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/speed.flf", size: 13007, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStampatelloFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x5a\x5b\x6f\xe3\xba\x11\x7e\xe7\xaf\x18\x04\x02\x64\x37\xbc\x58\xf4\xfd\x9c\x45\x60\xf4\xa1\x6f\xc5\x3e\x14\x05\x76\x51\xd5\x92\x36\xf1\x9e\x63\xc0\x8d\xb6\x89\x4f\xf6\x61\xb9\xfe\xed\x05\x67\x48\x4a\xd4\xc5\xce\xe9\x06\x91\x19\x73\x38\x1c\x0e\xe7\xf2\xcd\x68\xbf\x9e\xbe\xea\x2a\x81\x15\x2c\x20\x5b\xc2\x0c\x16\xec\x1f\x87\xc7\xfa\xf9\xa9\x82\xb7\xc3\xcb\xeb\xb1\x7e\x3e\xc0\xd3\xe1\x04\x5f\xeb\xe7\x33\xdc\xbd\x9e\xab\xff\x7c\xab\xce\x87\xd3\xa9\xbe\x83\x6f\x87\x17\xf8\x7a\xfc\xed\x74\x38\xb3\x97\xe3\xdb\xe1\xe9\x8f\x73\x05\x07\x78\xac\x5f\x5e\x0e\xe7\x73\x05\xc7\x13\xe8\x2d\xfc\xed\xf0\xe5\xcb\x4b\x75\xac\x21\xdb\x6e\x57\xf0\x54\xb1\xbf\x57\x2f\x8f\x35\xfc\xb5\x7e\x7a\xa9\xce\x35\x7c\xf8\x42\x83\xdd\x6f\x87\xe7\x63\x2d\x5f\x9f\x5f\xe5\xf1\xfc\x00\xbf\x9f\xcf\xdf\x7e\x51\xea\xfb\xf7\xef\xee\x2b\x75\x71\x84\x8a\xfd\xf3\xb5\x82\xc7\xea\xa5\x3a\x9f\x0f\x2f\x47\x78\x45\x61\x6b\x38\x55\x70\xae\xbe\x1c\x4e\xa7\x0a\x8e\xaf\xf5\x66\xb3\xdc\xc2\xe4\xfe\xbf\x7f\x54\xa7\xc7\xdf\x0f\xf0\x7a\xaa\x9e\x1f\x8f\x35\x3c\x1d\xe1\x6b\xf5\x7c\xae\x5e\x8f\xd5\x94\x41\x02\x3b\x06\x49\x12\x1e\xb0\x63\x09\xb8\xc7\x8e\xa9\x3c\xd9\xb1\xe9\x24\xd9\xb1\x5c\x25\x3b\xf6\xcb\xaf\x96\xc6\x4e\x03\x4e\xff\x0a\xf4\x05\x31\x71\xdf\xc7\xcf\x1d\x03\x09\xd2\x12\x08\x23\x8c\x48\x9a\x4f\x48\xa1\x4c\x1c\x19\x34\x9f\x7e\x35\x37\x32\xd9\xb1\xf2\x1e\x9f\x26\x4d\xba\x5c\xdd\x2a\x2e\x81\x83\x25\x49\x15\x97\x8e\xab\x27\xee\x71\x25\x7a\x4b\xfe\x20\x7e\xe1\x76\x95\x48\xcb\x24\xcc\x79\x52\xcb\x07\x79\xe0\x54\xf8\xdd\x31\xe0\x56\x70\x85\x27\x35\xf8\xcc\xe9\xd4\xa5\x48\x82\x64\x42\xd2\xa9\x72\xfc\xca\xe0\xd3\x2a\x4f\xa4\x49\x2c\xfe\x8e\x49\xb0\x42\x88\x4f\x76\xb5\xd5\xc6\xc0\x19\x51\x7f\xa4\x35\x3a\xdd\x00\x11\x5e\x81\xbb\x41\xbc\x22\xbf\xd3\xae\x75\x5b\x4c\x88\xf6\xe5\xb1\xf1\xd5\x10\xad\xc6\xb1\x15\x13\x94\xfd\x3e\xed\x5e\x73\xb8\x2f\x61\xd5\x66\x94\x21\xb5\x0e\x8b\x69\xf9\xa4\xa8\x92\x32\xe9\xca\x81\x3c\x2c\x41\xa2\xac\x3c\xa9\x18\xd1\x07\x6d\x94\x88\x0f\xa3\x1b\x59\xf3\x45\x63\xf8\x51\xd8\xbd\x12\x18\x21\x92\xa8\x92\x12\xf9\x8d\x72\x72\xe7\xba\x4e\x24\xda\x82\x43\x72\x4d\x43\x0f\xd7\x05\xe7\x6e\xa3\x51\x35\x36\x6e\x38\x78\x5f\xfd\x69\x9e\x36\xd3\xe8\xde\x56\xd4\x0f\x76\x3a\x29\x3b\xab\xed\xb0\x28\x12\xf7\x08\x33\x6d\x5b\x41\xe3\x4e\x1e\xda\x46\xe6\xa6\x9d\xe4\x30\xb5\x4b\x27\x38\x59\xf7\x35\xc1\xc9\x3d\x14\x17\xd2\x3a\x88\xe1\xc2\xd8\xa3\xe6\xa5\xd8\x2b\xb4\x8b\xc6\x4d\x82\x56\xb8\xf4\x46\xa7\xc0\x24\x34\xad\x2e\x17\xba\x13\x9e\x02\x40\xa3\xa9\xc8\xed\xbd\x60\x5c\x08\x41\xc1\xc1\x14\x45\x81\xfb\x70\x03\xe4\xa2\xa5\xd8\x0b\x11\x2d\x6f\x8d\x50\x60\x32\x00\xb7\x87\x5d\x46\x37\x24\x82\x2f\x46\x71\x46\x0a\x5c\x61\x5d\x05\xfc\x1e\x1c\x47\xca\xef\xd6\x3a\x61\x67\x37\xb7\xd8\xea\x21\x2f\x0a\x77\x52\x17\x5f\xd3\x32\x12\xb3\x19\xb8\x65\x38\x97\x1b\xbf\xcc\xc6\x27\x0c\x4d\x69\x12\x51\xb3\xb6\x62\x9c\xa4\x06\x80\x84\x32\x00\x1c\x19\x95\x42\x08\x83\x8c\xb8\x90\x34\x28\xc5\xbd\xa5\xb1\xcb\x0a\x8a\xb5\x29\x98\xc2\xa0\x36\x95\x01\x47\x14\x85\xdf\xce\x6e\xa8\xf9\x94\x62\xa2\xdc\x83\x71\x6a\xec\x07\xe0\x98\x14\xa2\x0f\x55\xb6\x16\xe2\xe5\x52\x74\x9a\x1a\xe5\x0e\x9e\x93\xdc\x4d\x40\x8d\xf3\x00\x27\x63\x9a\xe2\x87\x53\xee\x98\x18\xf6\x87\x8c\xaf\xe4\x06\xec\x8f\xdb\x03\x7e\x05\x83\x76\x00\x30\x60\x7f\x10\x8d\x89\x91\x63\x13\x31\x21\x0b\x46\x51\xc7\x2d\x90\x7b\x0b\x2c\x39\x9e\xdc\x38\x45\x94\x91\xd9\xf6\x2d\xd0\x99\x7b\xb0\x76\x7f\x3f\xc9\x98\x35\x84\x7d\xa4\xdf\x47\xfa\x7d\x72\xbf\x4f\x39\xb8\x4f\xe9\xf7\x99\x1a\xc8\xd1\x2b\xca\x14\x5a\xea\xef\x18\x2b\xad\xca\x0b\x6f\xaa\xde\x11\x47\xce\xc3\x05\x9a\xb7\xa5\x00\xca\xba\xc0\xfd\x00\xc3\xc5\x98\x75\x4b\xeb\xaa\xe0\x74\xed\x57\xe0\xd0\x5d\x5d\x29\xc4\xfe\x6a\xe4\x90\x14\x7d\x2c\x02\xb1\xfe\x8b\xf3\x06\x07\x8d\x6b\x8d\xf9\x32\x2d\x8e\x18\x44\x4c\x22\x46\xd0\x67\x36\xf0\x17\x31\x25\x7e\x90\x2b\x97\xd7\x54\x4e\x36\x4c\x4c\x86\x75\x4e\x41\xcb\x80\xbf\x59\x77\xb1\xe8\x89\xa2\xe3\x50\x74\x95\x94\xee\x9d\xbc\x8a\x12\x5c\xc7\x3f\xa4\x4d\x9f\xe8\xf7\xcd\xc3\x23\xa1\x26\xc9\xd2\x81\xc9\x29\xfb\x18\x87\x0c\xc8\x44\x0f\x7f\x25\x3e\xe7\x20\x0a\x6d\xa0\x69\x2b\xe7\x24\x98\xde\x09\xa9\xd9\xf1\xe5\xb2\x63\xee\xc0\x0d\xc8\x18\x86\x3d\x21\xd7\x72\x97\x6b\xf7\x5d\xd1\x48\x72\xe3\xc2\xbf\x25\xda\xdf\x00\x09\xb8\xd7\x60\xd6\x6e\x36\x32\x30\xb2\x5d\xc4\xc9\x05\xe1\xe1\xfc\xcf\xef\x90\xc4\x2b\x3f\xed\xe2\x35\xde\x12\x99\x90\x04\x70\x02\x5d\x78\xc3\xfd\x73\xa5\x43\x08\x89\x70\xb0\xf1\x58\x38\x60\x60\xc2\xa4\xfd\x5b\x73\xcc\x81\xf2\x88\x35\x17\xf3\x81\xd2\x60\xef\xd2\x65\xc7\x66\xd2\x3e\x18\x74\x70\xd0\x0b\xe9\xc5\x84\x51\x6c\x1f\x1f\x7b\xf0\x44\x7d\xdd\xbc\x83\x88\xae\x82\x82\x47\x9a\x5c\xd7\xb2\xcb\x53\x65\xd2\x23\x22\x45\x5c\x05\x86\xa3\x38\x94\xb4\x15\xae\x7b\x48\x5b\x56\xef\xf2\x96\x71\x21\x15\x5d\x0c\x39\x77\xd9\x8a\x9d\x8d\x57\x43\xa0\xa5\xcc\x6a\x14\x65\x56\xab\xfd\x2b\xf5\x1a\xd5\x32\xf0\x09\xae\xd5\x32\xb1\x94\x86\xa0\x83\x3f\x75\x50\x47\x41\xe5\x06\x72\xba\xeb\xab\x03\x23\x8c\x45\x99\x68\x5e\x38\x4a\x9b\xa8\x63\x92\xfe\x2f\x45\x1a\xcb\x75\x82\xd1\xe0\xc1\x8f\x7c\x8d\xd1\x36\xba\xb4\xe4\x54\xfc\xb9\x94\x09\x89\x3f\x76\xd2\x3d\x76\xcd\xa5\x87\xb8\x2a\xa4\xf5\x3f\x81\x4c\xa1\x2e\x6a\x40\x59\x00\x8f\x71\x3b\xb5\x43\x6d\x41\xb5\xbd\x8d\x3c\x64\xb4\x26\xa1\xf5\xf2\x59\x94\x90\xec\xd2\x9b\x41\xaf\x4d\x34\xea\x25\x44\x74\xd3\xe4\xb8\x2f\x85\x4d\x41\xc9\x84\x1b\x90\x94\xea\xc7\x61\x62\xa6\x37\x16\x74\x3a\x68\xa1\x00\x1c\x10\xce\x1b\x24\x5c\x76\xa0\x70\x7c\xcc\x4c\x6f\x87\x22\x88\x8b\xa8\xfb\x61\xc5\x66\xf3\x19\x93\x74\xac\xc1\x24\xc9\xa5\x83\xef\x16\xf4\x5b\xf2\x35\x93\xa5\xe4\xa9\xb5\x29\x59\xaa\x1c\x07\x62\xf2\xe3\xe7\x14\x6b\x79\x9e\x2b\x59\xe2\x20\x2d\x65\x1b\x07\xd9\xa5\x9b\xc6\xc5\xea\x7a\xf6\x11\xef\xff\x33\x95\x4d\xb9\x2b\x9c\x20\x2f\xa6\x49\x24\x1e\x9e\x29\x54\x04\x53\x72\x10\x24\xf6\xc6\x53\xd6\x75\x3d\x8b\x16\x2d\x66\x0c\x0a\xda\x69\x02\xae\x53\x31\xa5\x4c\xec\x17\xcd\xea\xba\xe6\xf1\xa2\x2c\x88\xf7\x71\x46\x93\x41\xbc\x29\xc5\x8d\x49\xa1\x62\x57\xc8\x16\x9a\xd5\xd6\x1f\xac\xde\xf2\x3d\xba\x34\xe4\x9f\x1d\x82\x28\x70\xc7\x42\x41\x5e\xc4\x3b\x2d\x18\x14\xf4\xcf\x09\x59\x60\x45\x52\x4c\xe9\x9a\x15\x4c\x3e\x4e\x21\x2f\x2f\x68\xdb\x39\x12\xaa\xcb\x25\x46\xda\x03\x18\x29\x5b\x2c\x1d\x63\x4a\x74\x75\x5d\xff\xab\xf8\x37\xde\x69\x5d\xd7\x06\x4c\x18\x16\x34\x2c\x8a\xc2\x11\xc4\x6c\x56\x41\x3e\xc7\x29\x77\xb3\x39\xe5\xb8\x9f\x82\xfe\xfd\xa4\xca\xcb\xfa\x26\xd4\x3e\x07\xb8\xb9\x9e\xb4\x96\xf1\x9a\x01\xe0\xa9\x93\x1d\xfb\x71\x91\x85\xbc\x20\x0b\xd4\x33\xc6\x83\xe9\xe5\x2f\x97\x89\x55\xf9\xa4\x98\x8a\x49\xcb\x16\x1c\x03\x34\x21\xe3\x50\x39\x7e\x4e\xca\x74\x9a\x04\x50\x3a\x10\xae\xb2\x55\xc6\x08\x39\x5a\x91\x3a\x8d\x3d\x4f\xa2\x19\xf5\xea\x38\xb6\xdd\x8c\x41\x3c\x73\x8f\x67\x68\x77\xaf\xb2\xd5\x1c\xdd\xdb\x1a\x47\x61\x0a\xba\xae\x29\x79\x67\x1a\xd5\xb7\x91\x00\x0b\x17\x20\x72\xa1\x42\xe0\x50\xa1\xb6\x68\x71\x5f\xba\x6c\x52\x7c\x2e\xae\xb5\xbe\xb2\xd5\xaa\x09\xf1\xad\x70\x9f\xa0\x8b\xae\xd6\xa1\xe3\x42\x89\x75\xa4\xef\x92\xad\x36\x2e\xa0\x41\x72\xb5\x91\x99\xad\xb6\xfd\xfe\x85\x0b\x13\x79\x29\xd2\xc1\xfe\x45\xb6\xb6\x4e\x88\x37\x84\xcd\xa8\xcb\xe5\x42\xa0\xb4\xc7\x7d\x9d\xf9\x2f\x38\x76\x68\x28\xbb\x95\xbd\x4c\x9a\xad\xb5\x4f\xd9\xd6\x86\xa2\x02\x79\x20\x9d\x67\xeb\x39\x0b\xd4\xcd\x21\x07\x8e\xb7\x5e\x0c\x1c\xaf\x40\x67\xce\x0d\xe4\x23\xc7\x5b\xfa\x66\x51\xaf\x63\xe4\xad\x6a\xbd\x6a\x19\xde\x08\xc9\xda\xcb\x68\x90\x19\x1a\x9e\x10\xa2\x7f\xf6\x0d\xf1\xc2\x68\x7c\x77\xd7\x63\x68\x49\xb6\x8e\xe4\x7e\x78\xcf\x1d\xcb\x36\x33\xc6\x9b\x89\x41\x89\x36\xd9\x00\x64\x31\x98\xe5\x0c\x7e\x9f\x7a\x42\x8d\xe9\x8a\xe2\x24\xc5\x16\x28\xa9\xa9\x05\xfe\x6f\x10\x7b\x11\x85\xbe\xcd\x3c\x34\x96\xeb\x06\x5c\x33\x37\xb9\xe8\x88\x43\x70\xbb\x6c\xaa\xa2\x6c\xb3\x6c\xf7\x52\xfb\xa7\xb0\x24\x6d\xad\x0f\x6b\x6a\xe3\xb5\x2e\x29\x4f\x3f\x60\x5b\x2f\xed\x9b\xe6\xc6\xa6\x64\x70\x3b\xba\xc2\xd0\x57\xb2\xca\x7d\x0f\x90\xde\xfb\x33\xa2\xff\x6d\xb6\xd7\x16\xb9\x06\x12\x75\xc5\x00\xc0\x4a\xb8\x63\xd9\x76\x46\x25\x2e\xde\x9f\x47\xa9\xca\xe7\x83\xfe\x4e\x28\xde\x36\x78\x4e\xed\x10\x21\x66\xb8\x0e\x9c\xb6\x84\xe8\x39\x79\xab\x9f\x58\xb6\x50\xdb\x04\xe3\x84\xb0\x42\x45\xe8\xa4\x8b\xda\xb2\x2d\x79\x14\x0f\x59\x50\xa5\x3d\xf0\x57\xde\x04\x7f\xd9\x16\xef\x59\xed\xf3\xc0\x26\x0c\x2d\x1b\x78\x1f\x86\xcc\xb6\x4b\x1b\x8b\x11\xb5\x7a\x28\x1a\xb1\xe1\x14\x3c\x6f\xb2\x59\xf5\x11\x6d\x97\x0d\x49\xd3\xea\x7b\x0e\xb0\x21\x9b\xfa\x18\x9a\x8e\x41\x1a\x8e\x6c\x7c\xa7\x02\xa8\xdc\x19\x65\x43\x20\xc9\xf7\xa4\x88\x0f\x01\x41\x45\xf2\xb4\x39\x5d\xef\xbe\x65\xdb\x6d\xab\x8d\x9b\x46\x6d\x5c\x28\x85\x72\x0d\xab\x38\x5d\xea\xd9\xcc\xa6\x8f\x22\xf7\x8d\x4e\xc2\x5e\x2a\x34\xd2\xf6\xa3\xdd\x58\x3d\xcb\x70\xa9\x0a\x3d\x38\xdf\xef\x7b\xc7\x52\x6b\xa1\xca\xed\x1a\x96\xf2\x77\x2d\x9d\x33\xe0\x75\x51\x13\x5a\xea\xed\xca\xaf\x2d\xb5\x48\x2c\x27\xe7\xba\xc3\x9e\x10\xbf\xd2\x9d\xd5\x33\x8b\xaf\x54\x8b\xbc\x29\x5b\x06\xc9\x57\x0c\x4d\x7b\xc7\xf8\x9e\xc8\xaf\x73\x5f\xb3\xba\xa8\xdf\x2f\xcc\x86\x5d\xa4\xeb\x63\x5b\x2c\x42\xef\xdd\x7c\xbf\x9d\x77\xda\xed\xf1\xb1\xad\x5d\x78\xc7\x91\xe9\xdb\x9d\x6c\x3a\xb3\xc4\xe6\x7a\x67\x56\x67\x98\xdb\x5d\xc7\x03\xca\x4e\x09\x37\x0c\x83\x74\x66\xad\x03\x14\xd5\xe1\x69\xd4\xd2\x8d\x4d\x39\x5a\xa4\x03\x90\xb6\x32\xc9\xf7\x2d\x9a\x87\x6a\xd6\xbf\x01\xb9\x59\x61\xea\x6c\xf1\xe7\xcb\x52\x9d\x2d\x11\x70\xda\x2a\x0d\xe3\xf9\x27\x72\xd4\x1e\xb4\xd3\xd9\xca\x8a\x42\xf0\x0f\x91\x85\x51\x0e\x06\x0e\x5e\x6e\xb6\x66\x92\xe7\xae\x8b\x5b\x62\xa1\x9b\x84\x92\xb7\xf0\x25\xef\xf8\xfb\x14\x9d\x6d\xac\xf9\x28\x62\x30\x35\x51\xcd\xec\x3a\xd5\x57\x6b\x66\x9d\x6d\x59\x88\xcb\x61\x79\x10\xc4\x2e\x96\x63\x5e\xa5\x67\x2c\x94\xeb\xf1\x52\xf7\x02\x69\x3f\xea\x90\x3a\x63\x12\xd4\x68\xcb\xb6\x53\x8d\x6a\xad\x19\x77\x78\xdf\x34\xaf\x74\xe8\xee\x44\x78\xb3\x83\xf3\x7b\x91\xf8\x3d\xe6\xff\x6f\x89\xae\xf5\xc2\x35\x74\x6f\x34\x13\xb4\x5e\xba\xd7\xc6\x37\x09\x57\x8c\xef\xe5\xed\xf6\x84\xd6\x6b\xf6\xb6\x7f\x7b\x0f\xe1\xe6\x7d\x0d\x0f\xad\xb7\xcc\xa6\xab\xdb\x84\xf3\x59\xb0\x7c\xdf\x57\xe0\xe2\x46\x5f\x41\xcf\x3d\x36\x69\x77\x02\xcb\xb7\xd4\x41\x84\x16\x77\x1d\xe9\x74\xb4\x03\xac\xe7\xf3\x48\xa7\x57\x08\x17\x91\x4e\xaf\x10\x2e\xe3\xb6\xcf\x38\xe1\x8a\x59\xdb\x18\xec\x0b\xeb\xf9\x9a\xa9\xf1\xc9\x0d\xdb\x8f\x4f\x6e\x7d\x01\x46\xc6\x48\xaf\x12\xfb\x38\x54\x2f\x66\xec\x01\xdf\x5c\x73\xac\x1a\x47\xfb\x53\x7a\x91\x45\x56\x32\xda\x13\xd6\x8b\x8e\xd6\xc7\x39\x76\xb4\x3e\x4e\xd8\xd1\xfa\x38\xe1\x72\x40\xc6\x41\xc2\xd5\xfb\xba\x72\x7a\xb1\x8e\x70\xb0\xab\x9f\xfa\x2f\xe1\x35\xf5\x0f\x90\xa3\x0a\xff\x69\x43\x0d\x71\xdc\x3a\xf5\xdc\xe8\xf5\xe9\xe5\xcc\xa9\xe7\x26\x61\xe6\xd4\x73\x93\x50\xbf\xaf\xcd\xa8\x97\xf3\xc1\xad\x7b\xcd\x65\xbd\xf4\xfd\x07\xd3\x32\xf3\x7d\xbf\x12\xd7\xcb\xe5\xe0\xd6\x3d\x8e\xff\x0b\x00\x00\xff\xff\x2e\xb2\xdc\xa2\x36\x26\x00\x00") + +func fontsStampatelloFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStampatelloFlf, + "fonts/stampatello.flf", + ) +} + +func fontsStampatelloFlf() (*asset, error) { + bytes, err := fontsStampatelloFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/stampatello.flf", size: 9782, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStandardFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x7c\x6d\x73\xda\xc8\xb2\xff\x7b\x3e\x45\xbf\xd8\xfa\x07\xea\x1f\x3c\x46\xb6\xb1\x5d\x95\x93\x32\x06\xd9\xd6\x06\x83\x8f\x80\xec\x49\x56\x5b\xb3\x24\x26\x31\xb5\x04\x52\x36\x3e\x7b\x53\x57\xf7\xbb\xdf\x9a\x47\x8d\x66\x7a\xa4\x91\x73\x6e\x6a\xd7\x60\x8c\xfa\x37\x3d\x33\xdd\xbf\x7e\x18\xe9\xcb\xe6\x4b\xb4\xfc\x05\xfa\x70\x02\xbd\x3e\xf4\x4e\xa0\xd7\x83\x43\x88\x8e\x8f\xfb\x47\xad\xd9\x7e\xb9\xbd\x5f\x3e\xde\xc3\xa7\x1f\x70\xbd\x59\x6d\xb7\x30\x7c\x58\x7e\xff\xbe\xda\x6c\xe0\xff\x41\xb2\xe4\xbf\xae\xe1\x88\x9c\x1f\x41\xb7\x0b\x9f\x96\x4f\xab\x7b\xd8\x6d\xe1\xea\x71\xb9\xfd\xeb\xd5\x13\x1c\x3c\xad\xbf\xb6\x92\xed\xe7\xcd\xf3\xfd\xea\x09\x92\xd9\x14\xc6\xcb\xfd\x7a\xdb\xed\xb5\xbe\xac\xbf\x6e\x56\x7b\x78\x5c\x6d\x56\xcb\xa7\x15\x44\x07\x3d\x26\xa0\x17\xc1\xe0\xf9\x2b\xf4\xce\xcf\x8f\x5b\xb7\xbb\xfb\xf5\x97\xf5\xea\x1e\xbe\xec\x1e\x41\x7e\x3d\x3a\x88\xd8\x48\x7e\xdd\x3d\x6c\x61\xb8\xfb\x7b\xb9\x85\x37\x9f\xd9\xcb\xc5\xe7\xcf\xeb\xcd\xc1\xee\xf1\xeb\xdb\x16\xc0\x7e\x07\xcb\xfb\x7b\x89\xf4\xdf\xd1\xeb\xa3\xd7\xc7\xaf\x4f\xfe\x07\x9e\x9e\xbf\x7f\xdf\x3d\xee\xa1\xbd\xd8\xae\x3f\xef\xee\x57\xb0\xf8\xff\x87\xbd\xc3\xc3\xee\x61\xef\xf4\xaa\x73\xd0\xba\x5b\x3d\x7e\x5b\x3f\x3d\xad\x77\x5b\x58\x3f\xc1\xc3\xea\x71\xf5\xe9\x07\x7c\x5d\xff\x7b\xb5\x65\x02\xbf\xb1\xc1\xfc\x80\xfd\xc3\xfa\x09\xbe\xec\xb6\xfb\xd7\xb0\x7c\x82\xcd\x6e\xfb\x95\xbd\xee\x1f\x56\xad\x6f\x62\xb4\x8f\xaf\x9e\x60\xbb\xfc\xb6\x62\x32\xbe\x6f\x96\x9f\xc5\x74\x2c\xe1\xf3\xee\xdb\xb7\xd5\x76\x0f\x9b\xf5\x76\x75\xd0\x2a\x74\xfb\xf4\x03\xee\x96\xcf\x1b\xb8\x7c\x7e\xdc\xef\xb6\xf0\xe6\x69\xb7\x79\xde\xaf\x77\xdb\x8b\xd5\xf2\x71\xff\xb0\x59\x6f\xff\x3a\xd8\xae\xf6\x6f\xa1\x17\x91\xf3\x3e\x1b\xc8\x5a\x4c\x26\x6c\x57\x7f\xc3\xf7\xe5\xe3\xf2\xdb\x6a\xbf\x7a\x6c\x49\xdd\x84\xc0\xab\xe4\x9a\xcd\xd5\x72\x7b\xcf\xde\xfe\xb6\xde\x1e\x00\xdc\x2e\x7f\xc0\x72\xf3\xb4\x83\x4f\x2b\x78\xda\xac\xbf\x3e\xec\x37\x3f\xe0\x9b\x39\xc3\x9f\x56\xfb\xfd\xea\x11\x9e\x9f\x56\xad\xdd\x17\x2e\xfe\xcb\xf3\x66\xd3\xfd\x7b\x7d\xbf\x7f\x20\x7f\xad\x1e\xb7\xe4\xe9\xdb\xf3\xd3\x03\x2c\x37\xfb\xd5\xe3\x76\xb9\x5f\xff\x7b\xf5\xf4\x1a\x3e\x3d\xef\xe1\x7e\xf5\x65\xf9\xbc\xd9\xc3\xee\x79\xff\xfd\x79\xcf\x34\x9f\x4c\xe7\xf0\xf9\x61\xb9\xfd\xba\xba\x3f\x68\xc1\x2f\x17\xd8\xff\x17\x2d\x00\x0a\x17\x2d\xc8\x21\x2f\x7e\x52\xf6\xb3\x4d\x3b\xec\xaf\x00\xf2\x4b\xfc\x6b\x6d\xc8\x81\x7f\xfc\x1e\xde\x03\xff\xf3\x2f\x50\x7e\x55\x17\xb0\x4b\xd8\x7f\xfc\x53\x9a\x43\x9e\x43\x2e\x90\x28\xc0\xc1\x01\xfb\x4c\xfe\xc2\xbf\x9b\xf3\x6b\x72\x9a\xe7\x34\x2f\x24\x19\xe2\xa8\xf8\x34\x87\x9c\xbd\x12\xa0\x7c\x78\x19\xa5\x90\xf1\x71\x01\x10\xfe\x77\x9a\xab\x01\x03\xa5\x42\x0d\x22\xfe\x04\x04\x08\x97\x41\x80\xf0\x91\x10\x4a\xb4\x92\x05\x0e\x55\x83\x6e\x03\x85\x0e\xc8\x2b\x28\x64\x24\xe3\x33\xd4\xa6\x6f\x01\xde\xb0\x4f\x33\x4a\x29\xc9\x88\x31\xd8\x62\x3e\xdb\x7c\x9a\x72\x01\xf8\x8b\xf1\xb3\xc0\x91\x43\x11\xd3\x0e\xce\x0b\x64\x34\x63\x5f\xa5\x42\xf3\x0c\x32\x35\x01\xce\x0b\xa1\x44\x4d\xba\x18\x3b\x1b\x17\x07\xc8\x40\x4e\x0c\x61\xf3\x91\xf1\xef\x64\xc4\x98\xe0\xe2\x32\xd0\xab\xa6\x97\x4c\xaf\x97\xb1\x3e\xe6\xe2\xc8\x8b\xed\x9f\xd6\x04\xd8\x08\xfa\x6b\xec\x9f\x40\x60\xff\x04\x02\xdb\x47\xa1\x08\xa5\x0d\xaa\xa7\x54\x4d\x6a\x69\xbd\x41\xae\x37\x38\xaa\x53\x39\xbf\x62\x8d\xd5\xfc\x6b\x73\xa0\x72\xa2\xf9\x5a\xdb\x03\x13\xbb\xc8\xb4\x1c\xc3\x7e\xf4\x97\x14\x02\x53\x53\x2e\x22\xdb\xbd\x42\x2e\xdb\xc8\xc4\x99\x84\xd2\xc5\x7a\x8e\xa4\x3a\x6c\x45\x32\x35\x83\x1d\x89\x88\x0f\x4f\xad\xa6\x30\x3f\xe3\xad\x92\x59\x2c\xad\xbd\xb6\xf6\xe0\xd9\xdb\xdc\x52\xa3\x06\x1f\xb4\x29\x71\x8b\x13\x62\x5e\xe9\x59\x6e\xab\x39\xc0\xe7\xb6\xa4\x39\xe4\x7a\x69\x41\xaf\xad\x10\x5d\x5e\x54\x7b\x55\x85\x11\x5b\xeb\x5b\x8d\x8c\x6e\x09\xf3\x92\xd7\x7a\x34\xc8\xc5\xce\xfe\x44\xf7\x2a\xfe\xa5\xb2\xc9\x98\x1e\x42\xea\xad\x9c\x40\x26\x4d\xd9\xb1\x5f\xc4\xa6\x6a\xac\xcb\x72\x2f\x19\x77\xa7\x0a\xb5\xd0\x4f\xad\x89\xda\x37\x99\x5a\x05\xed\x74\xd9\x64\xd3\x8e\x43\x02\x7a\x32\xf9\x56\x97\x28\x4c\x1d\xfa\xa7\x32\x19\x68\x6b\x2b\xe3\xd3\x2b\x07\x9b\xc9\x4d\xa5\xac\xbb\x70\x01\x84\xfb\x35\x25\x94\xfd\xa2\x4c\x49\x02\x88\x4d\x51\xcc\x92\x67\x43\x8b\x9d\x91\x83\x61\xf9\x75\x1b\x5a\xcc\x80\xc0\x52\xc3\xd7\x36\xa6\xfe\x9a\xf9\x4c\x19\x1c\x3c\xc7\xd3\x78\x4c\x59\xaf\x2b\xe8\x75\xe5\x3e\xba\x8c\x5c\xe7\x44\xc0\x18\xb6\x76\x0d\x5a\x0c\xcd\x01\x37\x25\x4c\x67\x15\x35\x98\x0e\xd2\x45\x86\xe2\x8b\xae\xa6\xfc\xef\xd2\x61\x16\x4e\xd3\xdd\x6d\xd2\x45\x29\x5e\x54\x34\x69\xe2\x69\x33\xa0\x6a\xfc\x72\x58\x14\x82\x7d\xb9\x30\xb8\x9c\x19\xa0\x20\xe5\x57\xc2\xe8\x72\x38\x90\xcb\x45\x73\x73\x4b\x69\x0d\xd5\x22\x60\xef\x6a\x16\x86\xff\x2f\xe6\x82\xd1\xb2\x1c\x68\x46\xf4\x98\xa1\xe0\x14\x28\xcf\x91\x33\xc3\x99\xd6\x14\x32\x7d\x7d\x56\xcc\x70\xe6\xe0\xff\x1c\xf9\xa1\xfb\x59\xd9\x0f\x14\xbc\xe6\xdb\x55\x81\xc8\x25\x2b\x0e\x43\x86\x37\xa0\x75\xf6\x5e\x4c\x34\xa3\x65\xc1\x8c\x66\xb8\x57\x23\x28\x02\x45\x9c\xc6\x3b\x24\x50\xc2\x8d\x21\x6c\xb6\xa9\xd8\x67\x32\xa6\xcb\x0a\xd7\xcb\x7e\xd1\xa4\x98\xc1\x7b\xd0\xc1\x5d\x66\x11\x63\x49\x50\x59\x96\x25\xce\x92\x68\x09\x75\xe5\x1a\xa2\x95\x50\x2d\x4e\x87\x60\xda\x31\xdb\x26\x24\x82\x10\x35\x18\x7d\xe1\x7b\x1d\xed\x54\x4f\x2a\xfb\xa7\x62\x19\x5f\x98\x5f\x32\x3d\x65\x79\xc2\x99\xe6\xbe\xf0\x3b\x67\xd7\xe8\x09\xd3\x53\xa5\x26\x49\x4d\x4f\xa6\x27\xc6\x76\x0c\x6a\x9f\xb8\xe1\xba\x36\x69\x81\xc0\x26\x9c\xf3\x7e\x26\x06\x29\xf3\x84\xf2\x0b\x12\xa9\x57\xbd\x73\xe2\x00\x2b\xc8\x00\x81\x85\x25\x26\x85\x34\x2a\x93\x3e\x93\xac\xdb\xc6\x2e\x7d\x8d\xfa\xfb\xc2\xf3\x39\x11\x5f\xc1\xae\x07\x18\xbb\x1a\xc0\x05\xe3\x28\xd8\x82\x59\xad\xa5\x84\xc2\xeb\x53\x35\xb8\xe0\x01\xa3\x98\x90\x69\x0f\xe6\xc3\x2c\xbe\xac\xd9\x54\x71\xa9\xf2\x79\x0e\x35\x85\xce\xaa\xdc\x23\x45\xf0\x53\x37\xab\x06\x45\x20\x2c\x5a\x44\x99\xfe\x1c\x45\xcf\xa0\x8a\x53\xe5\x70\x34\x8b\x12\xb5\x63\xcd\x21\x49\x74\x9b\x36\x41\xbb\x5f\x84\x2d\xed\x61\xa0\x83\x29\xed\x64\x3e\x61\xa6\xda\x7f\x5a\x8c\x51\x56\xdf\x22\x49\x24\x44\x86\xc6\x73\x68\x6d\x13\x9b\xb7\x6a\xd2\x89\x1a\x64\xcd\x5b\x07\x16\x63\xbe\x6c\xdf\x08\x3f\x59\xde\xdc\x54\xfb\xbb\x57\x66\xd4\xaa\xb1\x5c\x83\xba\x28\xe2\x2f\x65\x84\xaa\xd4\xc2\x37\x66\x69\x73\x17\x49\xa6\x0e\x51\x4d\xab\x60\x57\xba\x81\x9a\x1a\x59\x45\x80\x58\x61\xb2\x10\x40\x1c\x9c\xa8\xd0\x8b\x8d\xeb\x4b\x22\x4a\x52\x4a\x82\x2c\x59\xb6\xfb\x40\xa8\xef\xad\x34\x03\x84\xf1\x1a\xe9\xef\x78\x03\x63\x79\xa8\x8c\x44\x88\xa4\x3b\xc5\x76\xf6\x6c\xcb\xc2\x88\xca\xd6\x04\xc1\xbd\x81\x37\xa5\x92\x9a\x2e\x38\x79\xad\x54\xdb\xaa\x9a\x3c\xc5\x8a\x25\x29\x6f\xe1\xad\xf1\x3b\xcf\xc4\x24\xcb\x91\x5c\xd0\x1c\x51\xcc\x86\xbf\x3a\xf1\x52\x9b\x76\xa8\x72\x4c\x84\x66\x96\xfd\x31\x04\x24\xcc\x43\x2e\x36\x43\xcd\xba\x5c\x40\x5f\x5c\xf8\xce\xf0\x44\x02\x43\x0e\x27\xd0\x8a\x61\xd7\x94\x4c\xc2\x87\x8d\x98\x95\x4b\x80\xda\xa3\xe7\x99\xfa\x24\xe7\xa6\x2f\xbd\xc6\x45\xab\xd7\x3f\x04\x98\x4c\xbb\x97\x69\x3c\x78\x07\xb3\xbb\xc1\x30\xf6\x57\x9a\x7b\xfd\x1e\x40\x32\x79\x1f\xa7\xf3\x78\x04\xf1\xbf\x86\xe3\xc1\xed\x60\x9e\x4c\x27\x70\x3b\x48\xdf\x85\x51\x55\xaf\x1f\x01\x0c\xe3\xc9\x1c\x66\xc9\xf5\x44\x32\x57\x11\x27\xaa\xa0\xa1\x53\x0e\x1a\x00\x40\xd2\x9a\xa8\x0e\xf7\xfa\x47\x00\x77\xd3\xc5\x64\x64\x88\x31\xea\x14\xaf\x29\x9f\x6f\x5a\x64\xc9\x46\x2a\xd7\xa6\xaf\xad\x5c\x4e\x88\x3c\x06\x18\x2e\xd2\x34\x9e\x0c\x3f\x48\xa9\x44\x14\x88\x45\x19\x56\x9a\x69\xb1\x86\xb2\x5c\xc1\xfe\xca\x8b\x15\xa4\xb4\x20\xbd\xfe\x09\xc0\x87\x78\xa2\x06\x48\x95\x0f\x2f\x3c\x5c\xce\x3f\xcb\x4b\xef\xb0\x20\xb9\xd7\xef\x03\x5c\xa6\xd3\x77\xf1\x04\x2e\x07\xa9\x65\xe0\x34\xb7\x4d\x9e\x1b\x78\xaf\x7f\x0a\x30\x8b\x87\x7c\x7d\x8c\x49\x02\x19\x0e\xf0\x29\x26\x2a\x00\xce\x20\x93\x85\xa3\x8c\x79\x4b\x3e\x4b\xd2\xf0\x7b\xfd\x33\x80\x51\x32\x88\xd3\x78\x96\xcc\xf0\x5d\xca\xcb\x52\x2a\x16\x75\xdf\x19\x9a\x9c\x03\x0c\xa7\x77\x1f\xd2\xe4\xfa\x66\x5e\x5a\x3b\x5d\x6a\xd4\x65\x20\x50\x4e\x91\x45\x85\x9a\xe6\xdb\xfc\x8b\x45\xb1\x89\xe6\x85\x97\x17\x29\x1f\x07\x3a\x3d\x04\xb8\x8a\x6f\x93\x49\x32\x89\x61\x9a\x8e\x92\xc9\x60\x0c\xc9\x64\x94\x0c\x07\xf3\x69\xda\x2a\xd8\x58\x5b\xb6\x36\xaa\xbc\x5c\x6e\x33\x3d\x7f\xef\xb4\x07\x30\x8e\xaf\xe6\xdd\xbb\x69\x32\x99\x27\x93\x6b\x18\x4d\x17\x97\xe3\x18\x06\x93\xeb\x71\x0c\xff\x5c\x4c\xe7\x25\x8b\x50\x4e\x9e\xeb\xa1\xea\x80\xba\x12\xa8\x6b\x81\x65\x7e\xe9\x9d\x46\xc0\x9b\x3f\x7a\x7e\x00\xcb\x0a\xa0\x14\x2f\xa8\xe1\x5a\x13\x7e\x7a\x04\x30\x9b\x5e\xcd\xe1\xe6\xc3\xdd\x4d\x3c\x29\x45\xcc\xa6\x54\xa8\x53\xfc\x18\x20\x8d\xaf\x93\xd9\x3c\x4e\xe3\x51\xd8\xca\xe5\xdc\xef\xc9\x95\xe3\x01\x0b\xd1\x2b\x97\xd3\x9c\x66\xf8\xca\x9d\x00\xdc\x0e\x86\xe9\x74\x12\xd0\x62\xc0\xde\xe9\x21\xf7\x01\x46\xf1\x75\x1a\xc7\x7a\xb8\x45\xec\xa7\x1d\x72\xe1\x8f\x09\x78\x54\x3f\x05\xb8\x1b\x2f\x66\xdd\xdb\x64\xb2\x98\x95\xfc\x96\x98\x3e\xa4\xd1\x42\x99\x7e\xce\xb8\xb5\xc4\x33\x80\xd9\xe2\x2e\x4e\x67\xc3\x34\xb9\x9b\xc3\xfc\xb7\x69\xa9\x5c\x06\x1d\x34\x1e\x28\xf3\x6b\xef\xf4\xdc\x92\x72\x93\xc6\xb1\x19\x57\x50\x55\xdc\xb5\xc2\x3e\x4b\xce\xd9\x21\xc0\x60\xb8\x98\xc7\x30\x18\x32\xcf\xdc\x92\xf1\x06\x11\x5f\x37\x53\x4c\x23\xd1\xec\x9d\xf5\x00\x6e\x93\x61\x3a\x45\xb6\x69\x75\xd5\xf0\x40\x1b\x5a\xae\x85\x45\x00\x77\xc9\x78\x98\x4e\x7f\x33\x16\xab\x60\x34\x00\x55\x5b\x6b\x2b\x89\x3c\x9e\x55\x69\x0e\xdf\x4f\xb6\x47\x3f\x3b\x62\x23\x1c\x8d\xc6\x31\x8c\xa6\xf3\x56\x31\xba\xa2\x6c\x8f\xa8\xc5\x68\x20\x1e\x25\xe3\xf1\xa0\x55\x58\x8a\xfd\x93\xcb\xe8\xd0\x0e\xbf\xe2\xa4\xbc\x0e\xd3\x49\x8c\xb6\x96\x68\xee\x60\xf5\xd9\x56\x9f\x0d\x17\x63\xbf\x97\x52\x4e\x4a\x10\x8d\x5c\xc3\xdc\xb7\x27\xce\x4e\x01\xb8\x6f\x0d\x74\x50\xba\x98\x96\x99\x0d\x04\xdd\x42\x50\x4d\x04\x33\x54\xe1\x30\x67\x00\xef\x17\xe3\xeb\x41\x0a\x57\xe9\x40\x70\xcc\x74\xc2\xc4\x0f\xd2\x79\x9c\xaa\x2d\xa0\x92\x4c\xe6\x0a\xb8\x23\x57\x69\x06\xe1\x1f\xc9\x32\x0d\x01\xc2\xf6\xbc\x50\x48\x14\xfe\x55\x3f\x02\xca\xeb\x79\x8e\xa3\xde\x0c\xc6\x57\x26\x64\x81\xa8\xb2\xa6\x5c\xf4\xaf\x3a\x0a\xaf\x28\x31\x51\x52\x0e\xb8\x35\xd8\xf9\xa1\x0b\xc6\x2d\x4c\x29\x39\xd3\xb5\x48\xad\x27\x37\x39\x43\x53\x6e\x7a\x25\x5d\x69\x59\x5b\xbf\xbe\x72\x10\x66\xc0\xf5\xcf\x45\x3c\x2b\x73\x8b\xec\x90\xc9\xa6\x8d\xee\xac\x8b\xaa\x59\x66\xe5\x11\xbd\xf3\x08\x60\x3c\x98\x27\x13\x18\x0e\xee\x92\xf9\x60\x0c\xe3\x78\x3e\x8f\x53\x18\xc0\x6f\xc9\xfc\x06\xae\xd3\xc1\xfb\xb8\x65\x76\xfd\x18\x35\x29\xd7\x1e\x14\xb6\xf7\xce\x8f\xaa\x31\xb8\x9f\x51\x91\x88\x92\x4c\x1a\x62\x1c\x57\x63\x0c\x93\x74\xb8\xb8\xbd\x1a\xc7\xff\xe2\x42\x89\xca\x6f\x08\xcd\xf2\x66\x40\x27\xd5\x40\xf3\x64\x3c\xe2\xca\xb0\xcc\x48\x62\x64\x4d\x95\xe9\x57\x63\xf8\x02\xaf\x86\xf9\x54\xef\xfc\xb4\x1a\x27\x65\xae\x62\x70\x39\x7d\x1f\x97\xb8\x0d\xda\xbb\x4e\x43\x85\xce\x7c\x40\x42\xb2\x70\xeb\xaa\xcb\x43\x00\x0a\x7e\xe4\x66\xa3\xa2\x5f\xde\x6c\x54\x21\x3b\x43\x72\x98\x54\x23\x9e\x7b\x10\x87\x72\x3f\x14\xde\xfc\x05\xed\xbf\x0e\xb3\xae\x8b\x56\x74\x78\xe8\x41\x89\x7d\xd6\xc3\xc2\x3a\xac\xe5\xe7\x8d\x0b\xa2\xc3\x5e\x35\x86\x6b\x3d\xcc\x35\x37\xc4\xf0\x79\x81\x38\xcc\x7a\xc2\x81\x7c\xae\x20\x0e\xda\xd9\xe1\x38\x3e\x77\x90\x94\x17\x46\x4d\x59\x46\x65\x2f\xb0\xdc\x95\xb4\xbb\x91\xd1\xa1\xcf\xfa\x13\x6b\x31\xd4\x96\x52\xc5\xbf\x3a\xb9\x3e\x8b\x4f\x90\x05\x20\xaa\xb5\x40\xb3\x3c\x48\xb8\xcf\xcc\x93\x30\x77\xc2\x01\x84\x6d\xea\xb6\x4d\xae\xda\x6c\xe6\xa4\xfb\xac\x3c\x9e\xdf\xe8\xbc\x40\xe7\xf5\xa0\xbb\x73\xa5\x36\x79\x51\xee\x77\xbb\x75\x12\xc6\x67\xda\x13\xc4\x03\x6b\x07\xcc\xf7\x8c\xee\xa0\x1e\xfc\xa9\xc2\xaf\xac\xdc\x05\x88\x7a\x3e\x93\x9e\xd6\x13\x62\x60\x29\x2a\xea\xf9\x4c\x7a\x5a\x4f\x88\xc1\x18\x3e\x93\x9e\x06\x12\x62\x30\x90\xcf\xa4\xa7\xf5\x84\x18\x8c\xe1\x33\xe7\x69\xd8\x0e\x0e\xc6\x61\x69\xe6\x62\x3c\x4f\xee\xc6\x2c\xda\x2e\x55\x49\xd4\x57\x19\xf3\x88\x53\x83\xf2\xc4\x60\x56\x9c\x16\xe4\x32\x7c\xa6\x2c\xc7\x3a\x9b\xa7\xd3\x77\xb1\x4d\x3c\x84\xa8\xa0\x54\xa5\x07\x84\xa8\xb6\x17\x41\x06\xea\x33\xe9\x45\x00\xf1\x84\xd5\x3c\xa3\x9e\xcf\x9c\x17\x01\xc4\x13\x8a\xe1\xb3\xe5\x45\xcd\x2e\x85\x2c\x6f\x04\x14\xf9\xcc\x7a\x51\xbd\x83\x1a\x16\x8a\xa3\xc8\x67\xda\x1f\x3c\x93\x46\xf9\xa4\x55\x34\xca\x9d\xca\x5f\x14\xf9\x4c\x7b\x7e\x33\x4d\x27\x4e\x6b\xb1\x38\x24\x54\xb4\x40\x8d\x82\xaf\x2d\x5c\x9b\xf3\xec\x76\x30\xd6\xa2\x67\x37\x83\xf4\x0e\x66\xad\x17\x96\x94\xa3\xe8\x18\x15\x5b\x99\x65\x34\x6a\x53\x47\xd1\x49\x15\x02\xee\x52\x1b\x22\xf4\xab\x10\x42\x1c\x6a\x18\xcc\x69\x15\x0c\xee\x4e\x1b\x2a\x72\x56\x85\x10\xe0\x4c\xc3\x50\xce\xab\x50\xec\xdc\x42\xad\x4a\xbb\xdd\x29\x4e\x76\xbe\x0a\x80\x39\x3a\xc4\x61\xe2\x52\xf2\x2e\x37\x97\xe9\x72\xff\x04\xbd\x81\x19\x80\x71\x30\xc0\x69\x05\x48\xa4\x1e\x8a\xe4\x66\x14\x00\x0d\x8e\x3c\xa8\x5c\xe2\x28\x42\xa5\x63\x99\x84\x8e\x3a\x2e\xc2\x8e\x36\x44\x47\xb8\x51\x63\x19\x84\x8e\x36\x82\x65\xe3\x96\xed\xcd\x1c\xb4\x51\x04\x03\xe0\x86\x1d\x96\x31\x98\xd4\xaf\x0e\xaf\xc9\x0e\x81\xb5\x8d\x70\xe3\x2e\xe7\x0b\x54\x16\x51\xb2\x8a\x66\x56\x74\x84\xdb\xaf\x95\x21\x18\xd5\x54\xbf\x24\xdc\x4e\x03\x72\x02\xb0\x8e\x55\x96\x8a\x49\x5c\x34\x6e\x9c\x81\x19\x01\x84\x9d\x8e\x8b\x8e\x71\xdb\x94\xf9\x00\x0b\xa3\xc4\x05\xaa\xad\x0e\x94\x7d\xa4\xfa\x68\xba\x05\xe3\xd2\xec\x31\x6e\x8a\x58\x06\x50\x0e\x39\x43\x8f\x87\x44\xc7\xb8\x39\x36\xcb\x02\xaa\x3a\xbb\xd1\x31\x6e\x94\xcd\x72\x80\x6a\x04\xdc\x34\x5f\x90\x01\x54\xc3\xe0\x06\xda\x2c\xfe\xaf\x46\xc0\x8d\xb3\x79\xf4\x5f\x8d\x72\x0a\x30\x4a\xde\x27\xb3\x72\xdc\xaf\x43\x24\x1d\x4a\x33\xd9\x76\xe9\x81\x49\xb6\xe5\xe1\xe6\xeb\xe4\x01\x65\xc2\x28\x4e\x22\x29\x9b\x86\x36\x21\x6a\xd8\x76\x32\x20\x80\x70\x63\x7e\x79\x2e\xe0\x90\xec\x09\x6e\xc8\x2f\xcf\x04\x5c\x04\xdc\xa2\x7f\x32\x0f\x70\x61\x70\xb3\xfe\xb9\x2c\xc0\x45\xc1\x4d\xdb\x97\x03\x04\x4c\x97\x75\x60\x28\x3a\xc1\x4d\x1b\xcf\x00\x1a\x1d\x4f\x8b\x4e\x70\x73\xfe\xf0\x73\x53\x64\x29\x70\xf8\x5f\x87\x3d\x6f\xf5\x54\x86\x88\xba\xe1\x6b\x84\x6d\x85\xd9\x86\x95\x9e\x39\x0e\xbe\xb5\x1c\x14\x1d\xae\x01\xa1\x40\x49\x83\x58\x97\xa3\xd4\x74\x52\x2e\xd3\x58\x94\x1c\xf5\xb9\xcc\x2c\x93\x69\x7f\x23\x65\xf0\xad\x65\x81\x18\xc7\xe4\x4c\x8f\x12\xac\x4b\x4d\x37\x65\x7a\x3d\x9d\xc4\xef\x3c\xee\xb1\x56\x99\x36\x6d\x2b\x9c\xca\x9c\x0d\x43\x09\x3f\xbd\x6c\xa0\xf8\x2a\x32\x43\xdb\x1e\x75\x00\x4c\x8d\x08\xb8\x38\xf7\xe8\xbf\x11\x88\xc3\xe0\x71\x9f\x03\x52\x6c\x32\xbd\xc7\xea\xce\x43\x73\xf1\xbe\x72\xcc\x10\x73\x91\xea\xfc\x39\x70\x1a\xc9\x9a\xaa\x82\x13\x0a\x8e\xa4\x80\x48\x91\x90\x04\xe9\x33\xa8\xd6\x67\x34\x9d\x1b\xf9\xe1\xef\x7f\x98\x0c\xd9\x54\x9d\xcb\x2a\x75\x4a\x40\x26\x4e\x23\x6d\x86\x35\xab\x33\x90\x4e\x26\xcb\x94\xcd\x53\x23\x6d\x0f\xd6\x64\x54\xb9\x30\x26\x88\xc2\x68\xa4\x45\xec\xd1\x62\xe4\xd3\x82\x52\x1d\x58\xbb\x35\x56\xec\x76\x1b\x0e\x73\x85\x6a\x61\x81\x30\xc1\x2f\xbc\x05\x80\x81\x78\x0b\xf9\x23\xb4\x0e\xab\x7b\xf3\xfa\x6e\x43\x5e\xd7\x92\xb7\x62\xe7\x34\x27\x0a\x2f\xa7\x68\x5f\x82\x63\xe2\x4c\xe3\x20\x42\xb7\xdb\xcd\x5f\xae\x59\x4d\xb7\xae\x8a\x37\x43\x3b\x68\x1c\xa7\xb2\x6a\x50\xe6\x4d\xea\xf0\x66\x48\xd6\xcd\x51\x7c\x5c\x13\xd7\xf2\x66\x23\x65\x2a\xab\x08\x0a\x24\xcb\x58\x74\x79\x21\xd7\xc8\x49\x52\x6a\x75\xf1\x31\x4d\x5c\xe5\xd3\x7c\xb7\x81\x56\xeb\x83\xb3\x8d\x0f\xe8\xc2\xa4\x9e\x80\xaa\x0b\x87\xf0\xf6\xf3\xbc\xfc\x1c\xae\x4a\x9b\x6a\x7e\xee\xe1\x6c\x83\xa2\xd8\xbe\xd9\xaf\x47\xc1\xff\x3d\x1f\xd3\xc4\x55\x5e\xad\xf9\x8a\xe0\x2c\x83\x81\x88\x6b\xb3\xe0\x22\x1b\x17\xef\x63\x98\x6b\x8c\x95\x29\xc9\xb0\x43\x0d\x14\xdc\x16\x06\xa6\x0a\x4e\x33\x28\x92\x19\x69\x50\x75\x48\x2c\xe8\x1e\x28\x8e\xe4\x63\x9c\x6b\x2b\xa0\x45\xd9\x32\x5c\x21\x9c\x71\x2c\x10\xa3\x28\xd0\xf4\x7e\x2e\x06\xe2\xed\x31\x5d\x23\x46\x49\x7f\xff\xe3\x27\xf4\x89\x70\xa2\xc1\x80\x98\x97\xf9\x09\x9d\x7c\x5c\x73\x1d\x7a\x8e\xa6\x42\xa3\x0e\x15\xb5\x6f\x0e\x84\x93\x8d\x0b\x63\xba\x81\x40\x7d\x3a\x9d\x4e\x47\xc1\xf8\xd8\xe6\x06\xd9\xdb\x3c\x6b\x11\xc3\x27\x90\x39\x47\x56\xab\x6e\x74\xe7\x58\x38\xe5\xa0\x48\xfa\x7e\x51\xc8\x75\xd9\x27\xac\x52\xc9\x91\x7c\xbc\x73\x63\x45\x1e\xe6\x21\xdc\x7f\x34\xbb\x75\x9f\xe3\xe0\xa4\x83\xa1\x88\xa0\xf0\x1f\x4d\x6f\x6d\xe4\x28\x3e\xde\x49\xca\x15\x45\x22\x3c\x69\xe8\xa3\x04\xb8\xe8\xca\xb2\xb7\x2e\x55\x82\x68\xf2\x57\xd4\xe6\xb9\x30\x1f\xaf\x24\xe5\x08\x89\xe8\x7e\x6b\x83\x81\xe2\x64\x62\x49\x56\x91\x97\x42\xa8\x2b\xfb\x73\xc9\x3e\x1e\x49\x1c\x67\xd8\x78\xd0\x38\x6d\x58\x82\xc5\xd1\xe2\xca\xce\x07\x17\xe6\x63\x86\xc4\x8a\x0b\x42\x9f\x28\x61\x44\x1c\x11\x4e\x07\x8e\x64\x50\xc5\x2d\xb9\x6f\x8d\x17\x9a\x53\x21\x54\xc9\x3c\xf2\x79\xff\xc4\x75\xca\x54\x44\x64\x4d\xe6\xd6\xd3\x7c\x1c\x4d\xe7\xe3\x78\x36\x83\xa4\xa5\x43\x30\xa8\x99\xd8\x23\xd7\xa5\x27\xd7\x83\xf9\x22\x8d\x21\xf9\x55\xce\x27\x14\x53\x5a\xdc\xdd\x0e\xc5\xdb\x22\xc1\xcb\xdd\x7a\x34\x07\xb1\xdd\x79\x19\xa2\xa6\x70\x58\x8c\x5c\xde\xa3\x0c\xfa\x2e\x65\x2e\xdc\xe7\xc4\x7f\xc5\x03\x14\x1d\xa1\xf0\x22\x45\x7e\xa1\x9f\x20\x62\x50\x93\x0e\xeb\xcb\xb7\x84\x2a\x44\xdc\x95\xe3\x78\x24\x53\xf5\x10\x31\x72\xa5\x81\x78\xb5\xee\xba\xe6\xd2\x7d\xee\xfb\x9d\xcd\x7e\x14\xca\xe7\xe5\x85\x67\x05\x95\x82\x1f\xc8\xfb\x6c\xc4\x5d\xda\x52\x0f\xc6\xb2\x0a\x08\xf7\xdf\x18\x8c\x42\x09\xb9\x11\xbc\x53\x00\xe0\x2d\x8f\x77\x69\xa9\x2f\x5e\xdc\xb9\x9c\x13\x15\xfa\xfa\x6e\x2f\xe7\x52\x7d\xa7\x84\xc6\x56\x4f\x15\x64\xf6\x96\xf3\xf3\x53\x4a\x03\xe7\x2c\x8c\x27\x80\x3f\x1a\xa0\x83\xb7\x40\x88\xe3\xb8\x70\x2b\xbb\xac\x1e\xb3\x35\xd9\xce\x58\xab\x47\x6d\xae\xe9\xb0\x6a\xd4\x65\x18\x25\x1a\x7b\xd5\xdd\x5b\x63\x35\x47\x35\x3a\xc8\x9c\x86\xaa\xa4\x86\x09\xcb\x9a\xcf\x7b\x5c\xa9\x41\x20\x88\x7a\x87\x1c\x6a\xe2\x20\x57\xd5\xba\x94\xee\x09\xf2\x2c\x89\xf4\xda\xb5\x0a\x79\xda\xde\x5e\x24\x0d\xa4\x71\x4a\x9f\x38\x77\xf3\x73\x0c\xdf\x41\xb3\xb1\x1d\x8c\x15\x10\x44\x3e\xe3\x25\x27\x44\x8a\x24\xfc\x08\x7d\xa5\x2e\x78\xc3\xcc\x41\x31\x58\x87\xaf\x12\x21\x98\x55\x1c\xfb\x0e\x8b\x4e\x2c\x4b\x56\x37\xac\x34\x7f\x00\x12\x87\xc1\xbb\x63\x13\xb7\xde\xaf\x1c\x92\x3a\xa8\xdd\x20\x4c\x3d\xf6\x9d\x05\x9f\x60\xa6\xd7\x48\x9b\x0e\xed\x98\x40\x78\xf7\xdb\x81\xb1\x1c\x6c\xbd\x3e\x16\x8c\xef\x4c\xe9\xc4\x32\xc4\x8c\xbc\xf4\xe1\x54\x1c\x06\xa7\x08\x0b\x84\x97\x62\x84\x2e\x19\xf2\x94\xc1\xda\xb5\xc1\xe3\xfc\x09\xdc\xa5\xf1\x30\x1e\xc5\x23\xb8\xfc\x00\x83\xbb\x29\xdb\xbf\x77\x37\xe6\x51\xb1\x0b\xf5\xd4\x30\xf1\xbe\x0d\x1d\x86\x2b\x0f\xd7\x18\x41\x10\xf6\x54\x12\x05\xee\xad\x37\x4d\xae\x1b\xee\x06\x50\xf2\x0b\xa7\x7c\xec\x29\x33\x49\xd9\x75\x0b\xaf\x25\x1a\x77\x49\x52\x3d\x72\x5f\x6e\x30\xad\xa8\x2c\x83\x79\x58\x0c\x64\x16\xee\x3f\x66\xc1\x71\xf0\x44\xe1\x3f\x8d\xe2\xcb\x20\xa6\x56\xa6\x03\xea\x81\x56\x40\xbb\xc8\x03\xcc\x2a\xce\xfb\x72\x18\x3c\x99\xf8\xcf\x82\x9c\xd4\xdc\x96\xa0\x6e\xe8\x34\xba\x8c\xc5\x59\x3e\xa7\x26\x5f\x8b\x86\x27\x1b\xff\x37\x58\xfe\x74\x64\xaa\xda\x33\x56\xc9\xd7\x78\x16\x8d\xa0\xc9\x52\x20\x9f\x8b\x66\x04\x87\xcb\x75\x6b\xc2\x36\x52\xe7\x88\x46\x19\xb4\xec\x10\xe4\xf3\x83\x4b\x83\x30\xea\xb6\x7c\x23\x96\xaa\xb7\xc4\xaa\xe1\x96\xa1\x7d\xe9\x4b\x6a\x93\x20\xc5\x7a\x6b\x21\x4f\xc4\xe3\x30\x78\xce\x92\x22\x4d\x6f\xcd\x81\xd2\x73\x18\x77\xc1\x79\x03\x90\x13\x5f\xd2\x92\x3a\xf4\xd7\xf4\xc9\x7e\x65\x5e\x3a\xc1\x93\x16\x07\xa6\xcc\x7e\x75\x9a\x74\x8a\xd2\xe3\x89\xaf\xde\x94\xda\xc4\xf7\x73\xeb\x81\x73\x52\x8a\x10\x9f\xe6\xbd\x26\xeb\xe1\x63\x9d\x99\x67\x57\x35\x7f\x54\x22\x87\xc1\xe9\x67\xe6\x9e\x72\xb8\x90\x60\x01\x4f\x9b\xe2\x82\x7d\xdc\x33\x43\x2b\xb3\xd9\x4b\x9f\xf7\xc8\xb1\x70\xfe\xc1\x90\xd4\xa6\x22\x34\xa3\xa1\x9a\xf8\x78\x67\xe6\xb5\x8c\x06\x6a\x18\xa9\xdf\x09\xce\x3c\x0e\x0c\x14\xdd\x39\xa8\xd4\xa1\x88\x32\xfa\x3e\xbe\x99\x79\x6c\xe2\x65\x0b\xd1\xc7\x89\x66\xe6\xda\x84\x34\x89\xea\xf1\x1b\x82\xbd\xf7\xc8\x60\x6b\x60\x3f\xa9\x03\x6a\xce\x37\x1b\x6b\xd0\xc7\xfb\x16\x2e\x4c\x91\x0d\x8b\x57\xdf\xe3\xd4\x8c\x35\xf0\xf1\xc4\xdc\x5a\x83\x97\x3f\xbf\x94\xc3\xe0\x3c\x31\x77\x4f\x63\x04\x8d\xdf\x10\xec\x63\x88\xb9\x93\xa2\x56\x29\xd0\xcd\xbb\x79\xb7\x52\x01\x9c\x20\x1c\x14\xcf\x0a\x74\x2b\x34\xa8\xb9\x05\xae\x68\x18\x68\x13\x23\x59\xb3\x5b\xe0\x38\x4c\xe5\xf9\xdd\x17\x80\x60\xa7\x46\xfa\x3e\x7e\x58\x54\x9d\x1a\x01\x55\xa7\x0f\x57\x06\x27\x88\x0a\x94\xe2\x29\x5a\x0d\xb4\xf1\xb1\xc5\xc2\x6e\x36\xe8\x18\x2e\xab\xbb\x39\x11\x83\xc1\x89\xe2\xe5\x20\xa8\x2e\x3e\xbe\x58\xa0\xb7\x4a\x4d\xb5\x37\xaf\x79\xca\x20\xba\x3a\x38\x65\xd4\x22\xd1\xc6\x5a\x9d\xd6\xdd\x71\x69\x65\x11\xdd\x2e\x74\xbb\x62\xd7\x11\xd2\x78\xd7\x9d\x56\x1e\x1f\xc7\x32\x16\x1d\x9f\x54\x62\xa1\x9a\xf9\xb8\x65\xe1\xf6\x8f\x1a\x3f\x1b\xda\xe8\x52\x9d\xe2\xd4\x62\xa3\x18\x7e\x21\xfc\xb9\x9b\x45\xdf\xea\xd4\xc7\x32\xbf\xb9\xd1\x90\xa8\x25\x92\xcc\x78\xbc\x26\x10\x92\x65\x3f\xff\x9c\x69\x3e\x12\x9c\x88\x90\x71\x80\x1a\x06\xc8\x87\x56\xb2\x41\xbc\xf8\x89\x9f\x1c\xdb\xc7\x55\x1f\x7c\x67\x5e\x05\x34\x03\x86\x06\x37\xef\x72\x2c\x9c\xaf\x2a\x91\x84\x8a\x95\x6b\x8b\x9c\xde\x38\xf5\xf1\x17\x72\x98\xff\xf7\x3f\x40\x14\x9e\xc5\x22\x37\xb9\x23\x99\x43\xf9\x7a\x34\x1f\xed\xfb\xde\x88\x7a\x5a\x55\xf8\xa3\xbd\x39\x00\xde\x9d\xf9\xe8\x24\x1e\x60\x24\x1e\x75\xcf\x51\xe5\x82\x7d\x9d\x9a\x8f\x48\xe3\x96\xfe\xfe\x47\xe3\x07\x93\x73\x10\xbc\x4b\x83\x40\xa8\xd3\x7a\x81\x4f\x82\xe5\xc2\x7d\x7d\x9a\x8f\x6e\xb0\xfe\xb2\xd1\xe3\x1d\x9a\x8f\xde\x30\x3d\x78\xe4\x38\x1d\x8d\xa7\x93\x6b\x71\xb3\x79\x71\x5c\x5e\x3f\x96\xbb\xab\x5b\x56\xdd\x9a\xd0\x36\x1a\x9e\x82\x1a\x9d\x1a\x5c\xa6\x9f\xe8\x87\xbf\x88\x0b\x47\x67\xa0\xd8\x9d\x9f\x36\x15\x36\xa6\x79\xe7\x17\xef\xab\xbc\xfc\x1c\xcc\x35\xe5\x66\x25\xbe\xe4\xfc\x90\x17\x5c\x82\xe9\xd0\x3d\x63\xd3\x2f\x45\xf1\x22\x1a\x8d\xa0\x44\x6f\xc6\xf3\xfa\x40\x3d\x26\x49\x67\x47\x55\xe3\xfe\xdf\x00\x00\x00\xff\xff\xf2\x77\x6b\x98\xab\x6e\x00\x00") + +func fontsStandardFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStandardFlf, + "fonts/standard.flf", + ) +} + +func fontsStandardFlf() (*asset, error) { + bytes, err := fontsStandardFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/standard.flf", size: 28331, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStarwarsFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\x4d\x8b\xdb\x48\x13\xbe\xeb\x57\x3c\x07\x81\x2d\xb0\xd4\x64\x48\xde\x97\x80\x19\x44\x76\x61\xd9\xeb\x1e\x02\x0b\x4d\xca\xce\xac\x9d\x0c\xeb\xb5\xc3\x78\xc2\x12\xe8\x1f\xbf\x74\x7d\x74\xb7\x3e\x3c\x93\x64\xae\xce\xce\x5a\x6a\xa9\xab\xeb\xa9\xaa\xa7\xaa\x4b\xd2\xfe\xb0\xbf\xd9\xd6\xf8\x3f\xfe\x87\x9b\x1b\xbc\x7a\x83\xd7\xd5\xf9\x71\xfb\xf0\xef\xf6\xe1\xdc\xed\x0f\x7b\x7c\xfc\x86\x3f\xbe\x6d\x8f\xf8\xf3\xf4\xf5\xee\x6f\x2c\xbf\xc5\x43\x7f\x77\xee\xbe\x3e\xec\x3e\xdd\x1f\xb7\xdd\xdd\xb6\xc1\xaf\xbb\x3b\xdc\xbc\x71\xaf\xde\xbe\x7d\x5d\xfd\x8e\xed\x3f\x38\x9e\x1e\xf1\xb0\x3b\x7f\x39\x1d\xcf\xf7\x1f\x0f\x3b\xec\x4f\x0f\xf8\x7a\xde\xe1\xb4\xc7\xe3\xe7\xfb\x33\xf6\xa7\xe3\x23\x50\xbd\xdb\x9e\x77\x7f\xe1\x74\xc4\xbb\xfb\x4f\xa6\xec\xb7\xc3\xee\x78\xc4\x2f\x9f\xb7\x5f\xbe\xec\x0e\x87\xaa\xaa\x51\xf7\x4f\xff\xf4\x15\x88\xe2\x20\x00\x61\x7a\x20\x8a\x87\x25\x51\x53\xf7\x15\x00\x95\x00\xa1\xaf\x96\x08\x68\xfa\x0a\xef\xf1\x1e\xf1\x66\x8d\x99\x03\x80\x9e\x8f\xc4\x7f\xf1\x1a\x05\x84\x80\x40\xbc\x3e\xa2\x7a\x50\x28\xae\x63\x74\x1d\x81\x42\xa0\x00\x45\x80\x62\xd1\x38\x6b\xd5\xb6\x2b\xea\x64\xe8\xf4\x2e\x8b\x21\x00\x58\xb6\x6d\xdb\x6e\xe4\xae\xd7\xff\xeb\xbe\xea\xe2\xe5\x46\xe6\x28\x8e\xb8\x96\x93\xbb\xc0\xa2\x6d\x17\xb2\x14\x1b\xcc\xd0\xe3\x04\xaa\xa3\x05\x8e\x97\x71\x80\xab\xd9\x0f\x27\x34\x3c\x02\xdf\xf5\xe4\x64\x24\x93\x75\x26\x0b\xf1\x90\x47\x2c\x14\x87\x4e\xb4\x46\xa1\x3e\x1b\xc8\x3a\x49\x1d\xb6\x04\xa1\x61\x5c\x0e\x04\xef\x7c\x8c\xcf\x92\x6e\x81\x35\xab\x23\x72\xde\x25\x59\x8b\x69\x0c\x1b\xab\x08\x4e\x03\x32\xfe\x55\x2f\x12\x11\x2f\x0d\x77\x89\x05\x72\x88\x9a\x7c\xdf\x57\x8c\xab\xaf\x3c\xc4\xa0\x20\xee\x9e\x3b\xb0\x6d\x6a\x15\xa9\x59\xce\x07\x04\xc7\x92\x1e\x1b\x2c\xe0\x92\xff\x25\xdc\x0e\x2b\x74\xf0\xac\xd0\x05\x0a\xde\xa1\x08\x7c\xf6\x91\xb1\xca\x28\x65\x7c\xca\xa4\x51\xc6\xd4\x40\x5e\x41\xe5\xf3\x6f\xe1\x90\xb1\xd3\x86\xe1\x48\x67\xc4\xff\x98\xa5\xfc\x2f\x68\x66\xa4\x79\xf5\x50\x62\xac\x11\x13\x8d\xd4\x14\xe1\x80\x45\x44\xa9\x92\x39\xc3\x74\x51\xd2\xe9\x09\xc4\xc9\x33\x1a\x39\x4a\x89\x33\x92\xe1\xfc\xdf\xf8\x8c\x42\x8a\x2e\xb9\x22\xc9\x8a\xda\xe0\x48\xa6\x84\xd9\x03\x97\x88\x42\x82\x34\xa5\x54\x2d\x50\x37\x32\x93\x93\x40\x20\x39\xd2\x39\x94\xa4\xb3\x7c\x5a\x20\xad\x40\xd4\x98\x32\xc2\x9a\xaf\x91\x5d\xe3\x45\xa6\xc0\x85\x1b\x62\x62\xb0\x34\xd7\x02\xa3\xf0\x22\x55\x6a\xad\x14\x41\x13\x9f\xfd\x51\x96\x9a\x04\x4a\xab\xa4\x41\x0e\x8c\x65\x04\xf4\x19\x50\x52\xd4\x92\x2b\xb2\x2f\x64\xe9\x45\x0a\xd4\xd2\xec\xbd\x10\x94\x04\x47\xbc\xa5\x56\xd4\xe6\xdf\x62\x79\x39\x13\x4d\x5c\x68\x26\xb6\xcd\x32\x25\x01\xb8\x85\x3a\xfc\x39\x50\x4f\x2f\xe3\x89\x56\x06\x33\xa1\x64\x40\x13\x17\x71\xf0\x62\x56\xc4\xa4\xa8\x87\x43\x4b\x91\x0b\x73\x62\xe6\xa6\xc4\xd5\x24\xd2\x14\xe2\x74\xe9\xab\x35\xb0\x96\x22\x0d\x29\x31\x52\xd4\xaa\x71\x71\xb9\x94\xe7\x17\x72\x1f\xe3\xfc\xb3\xda\xcd\x6a\x4c\x1f\x4f\xb9\x05\x6e\x15\x4f\x4a\xde\x52\xbf\x6a\xd0\x2d\x19\xbc\x65\xd5\x7d\xb5\xd1\x0d\xcb\xb2\x45\xb6\x1b\x65\x6c\x41\x59\xa2\x14\xe2\x58\x57\x0a\xe2\x49\xd5\xe6\x7d\x89\x04\x4b\x0c\x04\x6d\x62\xa1\x8e\xfc\x5f\xc6\x42\xc0\x48\x63\xb0\xc4\x32\x2f\x34\x9e\xa9\xbf\x82\x31\x99\xed\x04\xa7\x8d\x1d\xf0\x81\x2d\x47\x2a\x5a\x24\xae\xd0\xd2\xa5\x46\xb2\x6f\x74\x07\x94\x50\x0c\x36\x79\x25\x45\x37\xf2\x09\xc1\xf8\x85\x40\x4d\xda\xa3\xe2\xf5\xf5\xe4\xba\xc8\xba\x41\xf7\x90\x08\x1b\x37\x74\x01\x04\xe9\x1a\x02\xb0\x8a\x9e\x5e\xc8\x2a\xb0\x12\x02\xf6\x7f\xa7\xe4\x1f\x06\xbe\xc8\x49\x2a\xc2\xc6\xfc\x0a\x40\xd7\xb6\x9d\xad\xad\x7f\x7c\x2e\x2d\x46\x48\x10\xc9\x4d\x20\x52\xa6\x9b\x86\x50\x97\x29\x9d\x21\xfb\x9c\x5c\x2d\xa9\x59\x42\xc4\x4f\xac\x06\xd9\xa3\x84\x5d\x03\x7e\xa3\x70\x1f\x95\x01\x4d\x46\xe6\x96\x32\x96\xdb\x90\xf0\x15\x5b\xcd\xa0\xf2\x17\xdb\x0d\x06\xd2\x28\x5a\x10\x06\x92\x62\x1d\x67\x86\xc9\x34\x99\x33\x5a\xfa\xf9\x36\x77\xd0\xed\x16\xb5\x28\xa3\x51\x86\xe4\x04\x4c\x03\x8d\x6f\x5a\x69\x23\x71\x2d\xec\x1c\x92\x2f\x5b\x2a\xec\x8b\x92\x5a\x9d\x22\x2b\x34\xaf\xd9\xe7\x6b\x8b\x4b\x67\x8c\x27\x0a\xa3\x2c\x29\xfc\x56\x44\xee\xc9\x53\xe3\xf2\x0c\x51\x2c\xdd\x18\x5c\xa7\x38\xbc\xcb\xbe\xf6\x9c\xcd\xe6\x34\xef\xc2\x8f\x45\xa1\x93\x6d\xd7\x96\xf6\x85\xdf\xe0\xf3\x79\x87\x4d\xa1\x04\xc5\xb2\x7e\x8e\x36\x65\xd1\x14\x32\x16\x15\x62\xc0\xa1\x1f\x0e\xd4\x77\xd7\x1e\x95\x16\x0d\x52\xf8\x02\x28\x0c\xbb\xc1\x7a\x98\x3c\xd0\x1c\xcb\x98\x35\xe7\x12\xd2\x8b\x63\x01\xbf\x88\xdc\x4b\xf8\xf5\x77\x58\x41\x6b\x94\x56\x24\x79\x8c\xd4\xb1\x2d\xf9\xae\x96\x74\xbb\x1b\x6b\xb7\x91\x26\x1a\xb5\xe9\x26\x15\xa6\x4c\x1a\xe5\xd5\x8b\x1f\xca\x2c\x2a\x40\x3d\xd5\xa4\x36\x99\xa6\x50\xdc\x0e\xb2\x5f\x46\xe4\x85\xa6\xa2\xa8\xcd\x0d\xa5\xce\xd5\x18\x68\xaa\xf1\x6c\x59\x7a\x19\xbf\x2c\x2c\xba\x15\xa9\x37\xa2\xc9\xbc\x1d\x78\x4b\x3f\xed\x12\xbc\xc6\xc6\x9e\xae\xbd\x8d\x14\xb6\xd7\x87\x81\xc2\x0a\x19\x96\x9a\x66\xf5\xcd\x6a\x9d\xd3\x3d\x8b\x60\x0e\xc7\x2c\x9a\x09\x26\x58\x1d\xe4\x0e\xc9\x65\x04\xef\x53\x87\x73\x9b\x4a\x61\xbc\x6f\xb5\x90\xdb\x86\x71\xcb\xf0\x33\x2e\x95\xc9\xc9\x20\x89\x60\x46\xcd\x75\x6c\xde\xa5\x46\xf4\xc1\xb6\xef\xac\x5d\xe3\x16\x2d\xf5\xe3\xa9\x0d\xe7\x73\xeb\x26\x1c\xcd\x6c\xd6\xc5\x83\x90\x2e\xab\x1b\x6b\x64\x32\x53\xac\x1e\x1e\x53\x31\x0f\xc9\xa7\xe9\x09\x5d\xcc\xca\xcd\x17\x52\x4b\x8a\xdc\x04\x0f\xdb\xe0\x6c\x5b\xa1\x7f\xd3\xea\xa3\x3d\x86\xc7\x4e\xaf\x27\xfd\xda\x1b\x6a\x5b\x15\x1b\x4d\xd7\xb6\x1f\xda\xd6\xe7\xc7\xbc\x27\x4e\x2e\x3c\x73\x0f\xce\x26\x4f\xda\xd3\xae\x3c\x3d\x5b\x83\x1f\x11\x7c\x78\xfa\x15\xc8\xb5\xa1\xbd\x36\xb4\xd7\x86\xf6\xda\xd0\x5e\x1b\xda\x6b\x43\x8b\x11\xb1\x71\x6d\x68\xaf\x0d\xed\xb5\xa1\x7d\x79\x43\x3b\x7e\x25\xab\xc4\xb2\x2f\x1a\xa9\x2f\x4d\x7b\x92\x7e\x6f\xfa\x9e\x8d\xae\xdc\xef\x66\xde\xbe\x32\x8d\xad\xf9\x1d\x41\xc8\x6f\x61\xa5\x8e\x01\xd6\x02\x78\x27\xdd\x8c\xf3\xc5\x4b\xd0\xfc\x5d\x73\xee\x2c\x95\x43\x29\x48\x7d\x85\x25\x35\xb4\xa4\xc6\xda\x48\x9f\x3a\x48\x8a\xe7\xf2\xba\x5c\x5f\xc8\x3a\xfd\x12\xe8\xc7\x7d\x0e\x60\xaf\xbb\x49\x5e\x79\x8b\x74\x6f\x1f\x72\x7a\xfb\x8e\x93\x5e\xce\xa7\x15\x46\xf2\x60\xf9\x52\xec\x67\xe4\xd9\x4d\xea\x25\x7b\x81\xbc\xcc\xf2\xab\x22\xf8\x17\xe5\xed\x11\xc1\x0c\xe1\x4f\x05\xdf\xab\xdf\xae\xcc\xe3\x1f\xeb\x9f\xd1\x16\xd0\xa8\xd8\x1a\xeb\xd1\x95\xc0\xfa\x83\x74\x89\x7d\x5f\xfd\x17\x00\x00\xff\xff\x42\x0d\x06\x12\xe5\x1f\x00\x00") + +func fontsStarwarsFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStarwarsFlf, + "fonts/starwars.flf", + ) +} + +func fontsStarwarsFlf() (*asset, error) { + bytes, err := fontsStarwarsFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/starwars.flf", size: 8165, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStellarFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xcb\x8e\x1c\x45\x10\xbc\xcf\x57\xe4\xc1\x57\x0a\xb3\x42\xc2\xdc\x9a\x03\x3e\xf9\xb4\xf0\x01\x65\xa4\x35\xb2\xb4\x02\x09\x7c\x81\xaf\x47\x33\x53\x8f\x88\xc8\xa8\xee\x99\x65\xe5\xf5\xba\xbb\xaa\xbb\x2a\xdf\x19\x99\xd5\xfb\xe9\xf9\xd3\xc3\xc7\x37\xf1\x2e\x7e\x88\x87\xb7\xf1\xcd\x77\xf1\x70\xfa\xe5\xd7\x9f\x3f\x7c\xf8\xe9\x31\x7e\xfb\x27\x1e\xff\xfc\x23\xde\xff\xf5\xf9\xcb\xbf\xf1\xee\xdb\x1f\xbf\x3f\xbd\xff\xfc\xfb\xf3\xd3\x97\x78\x7c\x7a\x7e\xfa\xf8\xf7\x53\x3c\x94\xb7\xa7\x37\x9b\xf9\x8d\x6d\x3b\xd5\x52\xf8\x12\xed\x12\x11\xed\xd9\x79\x74\x79\x58\xcb\xb8\x45\x5c\xde\x1f\xdf\xda\xbd\xff\x9c\xa7\xb5\x94\x68\xd7\x0b\x87\xf3\x4f\x5c\xee\xe9\xed\x9d\x8b\x91\xd1\x65\xde\xdf\x5c\xa4\xbe\xaa\x56\x44\x8e\xb6\xaf\x9b\xa0\xad\xcb\x54\x51\x93\x46\x67\x2c\x85\xb5\x93\x68\x63\x75\xe1\x5e\xfc\x36\x92\x74\xae\x1d\xb2\xcc\xfd\x65\x6e\x97\x75\xb0\x77\x12\xbc\xbe\x69\x8e\x5a\x5f\x9a\x98\x8d\x5c\xa3\xaf\xb7\x21\x6f\x67\xd7\x39\xb8\x97\x74\x23\xa2\x6c\x44\xd1\x64\x5c\xba\x3e\xcd\x61\xdd\xe7\xd1\x3c\x6f\xde\x9b\xfd\x4c\xdf\x84\x05\x46\x63\xe4\x40\xe8\xb6\xee\x6c\xf7\x96\x65\x6a\xc8\x68\xe7\x32\x5c\xd4\xb7\xe5\x3b\x71\x37\xef\xef\xe2\xc4\xc6\x07\x2d\x5e\x10\xc1\xa2\xad\x24\x39\x10\x44\x42\x18\x55\x83\xf5\x20\x37\x23\x06\xc5\x6a\x91\xaf\x7e\xdc\x06\xc8\x48\x18\xba\x5b\x05\x23\x92\xa4\x33\x8b\xae\x94\x8c\x6d\xd0\x22\x68\x87\x89\x45\x9c\xcb\x06\x25\x8c\x61\x39\x38\x09\x67\x7a\xea\x17\x0d\x2f\x6b\x63\x0e\xc3\x8a\xb3\x9e\x20\x9c\x21\x90\x4f\x39\x5b\xbc\x8d\x49\x93\xc2\x11\x20\xee\xf1\x9a\x78\xbc\xb3\xc1\x82\xd6\xc6\x08\x9c\xfe\xc9\x41\xd4\x97\xe5\x22\x20\xce\xae\xa3\x76\xa0\xda\xc9\xd9\x6c\xd2\xc5\x78\x4f\x93\x3e\xf1\x41\x1f\x53\xde\xf0\x9a\x80\x29\xf6\x9c\x9f\x1c\x3c\x6d\xce\xda\xd5\x62\xa1\x8b\x8d\x6d\x9d\xbf\x46\x12\xc1\x94\xc3\x85\x00\x73\xc3\xfe\x52\xe2\x15\x5b\x50\x4a\x13\x59\xc6\x36\x30\xa8\x85\xa0\xd3\x3e\x49\x83\xfb\x05\x38\x50\x81\x08\x0b\xb1\xed\x94\x49\x4d\x4f\xce\xdd\xf6\x99\x54\xb5\x41\x01\x13\x27\xb8\xfd\x81\x0a\xd9\xb2\xa5\x32\xe8\xd6\x5a\x13\x76\xfb\xa6\x6a\x46\x39\x84\x54\x08\x12\xb8\x30\xa3\xca\xd2\x93\x91\x71\x55\xcb\x42\x72\x37\xf9\x6a\x62\x1a\x6e\x9d\xbb\x1a\xfc\x84\xe2\xfb\x4c\x11\xe8\x2f\x5c\x6a\x4b\x86\x51\x63\x46\xee\x96\x31\xae\x8f\x91\xd5\xc2\x60\xc0\xfc\xd8\x4c\xca\x23\xb3\xc5\x18\x0a\x5c\x02\x8d\x0d\x4a\x94\x82\x36\x0c\xbb\x64\xbb\x0b\x34\xe1\x5e\x85\x70\x8a\xb0\x0d\x6d\xd5\xc3\xd6\x44\x84\x9d\xf4\x2a\x3f\x8c\x04\x71\x66\xe0\x54\x10\x73\x67\x32\x8b\xc6\x8d\x7b\x12\xa3\xa3\x0b\x24\x16\x75\x1f\x47\xa3\x5a\xb0\x6f\x2a\x7a\x5a\x81\x9c\x83\x83\x07\xb5\x25\x2d\x2f\x2a\xbb\x05\x97\xad\x2a\xae\xb3\xe5\x2d\xce\xbe\x37\xcc\xda\xa4\xeb\x3b\x7d\x3d\xb5\xa8\xe0\x03\x06\xb9\x81\x43\x86\x14\x4d\x23\x92\x46\xc5\xf3\x05\xe3\x31\x57\x66\xca\xf9\x1a\xc4\x32\x71\x9c\x58\x93\x3b\x1f\xb1\x7e\x96\xdf\xcf\x03\x5b\x82\x70\xf4\x8d\xc6\x92\xb1\x0e\x73\x72\x56\xef\x81\xe0\x52\x43\x51\xf0\xc8\x3d\xc9\x5b\x75\x74\xb0\x50\xb0\x34\xcf\xcf\xbe\x27\xcd\x58\x37\x37\x0b\x0d\x4f\xad\xeb\xea\x0e\xef\xcb\x2e\x0d\x9b\x4f\xaa\xaa\x54\xf5\x0c\xfd\x48\x27\xf9\x2a\xb8\x9f\x61\x62\xaf\x33\x23\x86\xd9\x19\x2f\x9e\xdc\x80\xca\xc6\x66\xc3\xd9\x18\xd8\xbe\xb9\x18\x09\xc9\xaa\x49\xf0\xbb\x0a\xe4\x04\xd9\xc9\xb7\xca\x3d\x41\x02\x09\x04\x86\x59\xcc\x7c\xbe\xae\x04\xa0\x16\xad\x40\xbb\xa9\xfa\x46\x98\x77\x16\xc2\x6d\xd4\x5a\x86\x64\xf4\x15\xc3\x7b\x66\xcc\x30\x1d\xc8\xc0\xa9\xc6\xa3\x11\xe6\xd0\x52\xa5\x15\x28\xa6\x94\x00\xc3\xa6\xe8\xe1\x2d\x7d\xea\x12\x76\x7a\x40\x48\xb2\x42\x4a\x2d\xcf\x2d\xf8\x19\x73\xff\x66\xbe\x61\x54\x86\xd2\x7a\x50\xa6\x5f\x32\xe9\xb3\xfb\xef\xed\xcb\xd5\xe8\x72\xf2\x09\x91\x2f\x84\x70\x3a\x9e\x9a\x8e\x34\x73\x0d\xb3\xc4\x6a\xc9\xa8\x09\xd2\x2d\x86\x64\x45\x6e\xb4\x69\x41\xb6\x91\x1c\x28\x2b\x76\xa3\x83\x0d\x3c\x99\x6b\x98\xd0\xba\xef\x43\x30\xb1\x1d\x20\x3b\xfd\x76\x9b\xea\x41\x82\x8e\x48\x31\xfb\xe8\x65\x51\xdf\xfa\x81\xf3\xbc\x6d\xfc\x81\x80\xd0\x6a\x31\x48\x92\xea\x90\x91\x4c\x3d\x02\x4f\xbb\xa1\x28\x33\xc1\x1a\xa7\x99\xb9\x38\xa2\xcf\x30\xc9\xba\x25\x9c\x4d\xf1\xcb\xfa\x41\x3f\x3f\x94\xb0\x73\x7b\xbf\xf6\x9e\xdb\x4a\x60\x39\xc4\x37\x93\x17\x8a\xe0\x95\xe8\xc3\x66\xeb\xeb\x8c\x49\xff\x91\x21\xc8\xa0\xa3\xc2\x81\x87\xc4\x35\x7e\x7a\x55\xb2\xaa\x90\xfb\xe1\x50\xf5\x83\x41\x8a\x01\x32\x4f\x22\xfe\x62\x94\x11\xea\xb6\x7f\x4b\xf1\x86\x72\x4f\x5c\x99\x84\x15\x55\xac\xc3\x3d\xc1\x00\x5c\x41\x82\xd3\x11\x95\x3a\xe3\x31\x2a\x8b\x8f\x65\x0a\x57\x79\x50\x25\xff\x3d\xee\xd5\x42\x9f\x88\x3b\x72\x04\x20\x85\xe2\xd4\xe6\x80\xe1\x36\x14\xa1\xe2\xba\x36\xbe\x1e\xd5\xfc\x28\x9a\xd9\x16\x00\xaa\x65\x92\xeb\xac\x2d\x40\x43\x48\xd3\xc7\xf8\x3a\x6b\x38\x31\xab\xc1\xab\x30\xec\xcf\xd9\xf5\x17\x52\x20\x52\x2d\x3c\xc8\x30\x44\x74\x08\xf6\x98\xd5\x42\x8a\xee\x22\xc3\x96\x84\xab\xfc\x91\xb5\xe4\xbe\x49\xc2\x6f\x9f\x30\x05\x94\xa4\xe7\x26\xdf\x66\xdd\x57\x86\x90\x43\x33\xc5\x21\x53\x91\xda\x25\x71\x7c\xfd\x9a\x78\xfd\x7f\xdd\x4d\x73\x4d\x8b\x15\x39\x23\x44\x48\xea\x0d\x30\x9d\xde\x11\x1c\xfd\x5f\xe3\xed\x24\xff\xbe\xd6\x83\xff\x02\x00\x00\xff\xff\x45\xa0\xfc\xc0\xe6\x20\x00\x00") + +func fontsStellarFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStellarFlf, + "fonts/stellar.flf", + ) +} + +func fontsStellarFlf() (*asset, error) { + bytes, err := fontsStellarFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/stellar.flf", size: 8422, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStopFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x58\xc9\x6e\x1c\x37\x13\xbe\xcf\x53\x7c\xc0\xcc\xa1\xfb\x32\xfc\xed\x3f\x0b\x0c\x08\x82\x03\xf8\x6a\x1f\x12\x20\xc9\x81\x40\x61\xa2\x91\x12\xc1\xb6\x14\x48\x1a\x05\x01\xf8\xf0\x01\x6b\xe1\xd2\x4d\xf6\xf4\x58\x90\xd4\x6c\x36\x59\xac\xe5\xab\x85\x75\xf7\xe5\xee\xed\x61\x87\x1f\xf1\x03\xde\xfe\x0f\x6f\xbe\xc7\xff\x37\xbf\xbc\x3c\xfe\x8d\x3f\xfe\xc5\x87\xc3\xeb\xfd\x11\xbf\x1d\xbe\xbc\x3c\x3e\xe0\xea\x1f\x7e\xbe\xbf\x79\xde\x9f\x6e\x8e\x87\xd7\xfb\xe7\xfd\xed\xf1\x74\xbd\xf9\x70\xfb\x74\xff\x7a\x7b\xc4\xdd\xd3\xe3\x57\xfc\xfc\x78\x7a\x38\xde\x1e\xe3\xe6\x4f\xf7\x37\x9f\xf1\xf1\xfe\xe1\xf6\xe9\x19\x9f\xf6\x1f\xf7\x32\x7c\x7f\x3c\x3d\xfd\x75\xf8\xba\x3f\xdc\xec\x4f\x9f\x37\x6f\xdf\xe0\xa7\xd3\x9f\xa7\xe7\x17\xbc\x79\xf7\xee\xbb\xcd\x6e\xb7\xed\xfd\x6d\x37\x20\x6c\x37\x01\xc1\xfe\x51\xb0\x39\x1e\x01\xb2\x86\xa7\x06\x8c\x03\xc6\xed\x26\x38\x04\x07\xfe\x1a\x17\xf4\x9e\x3c\x20\xde\xcb\xb3\x14\x80\x10\x10\x98\x54\x9c\x0b\x01\xa0\x71\xf1\x0b\x02\x51\x08\xf1\xbb\x91\x2d\x69\x27\xba\x41\xa4\x00\x51\xdc\x15\x28\x9e\x1a\x94\x96\xc8\x51\xd3\x50\xa1\x44\x2a\x1a\xc1\xb2\x03\x70\x10\xb9\xe2\x33\x0e\xe2\x53\x95\x81\x41\x18\xca\xe7\xf3\x29\xb2\x8a\xe0\xc1\x0a\x8a\xc4\xc6\x38\x37\x82\x30\xe8\x9c\x03\x7c\x9c\xf3\x44\xce\x17\x54\x60\xfa\x37\xad\x8a\xc2\x27\xff\x4c\x8d\xc2\x17\x6f\x57\xf6\x86\x78\x02\x13\x86\x97\xef\x9e\x32\x79\x26\x2e\x1c\x0e\xca\x5f\xe4\xc3\x0b\xd9\x11\xac\x78\x11\x78\x20\x72\xb5\xe1\xc4\x6a\xc2\x9b\x0f\xd1\xdc\x23\x9f\x13\x67\x65\x07\x8b\xaa\xdc\xc4\x1f\xcf\xb3\x2e\x50\xa8\x44\x54\xfe\x13\x30\x26\x36\x13\x0b\x8d\x0d\x0b\x55\xaa\x6e\x68\xa6\xd2\x9b\xae\xce\x0f\x22\xa1\x9e\xf5\x31\x79\x2c\x51\xd5\x3d\x46\x95\x74\xd3\x12\x48\xa0\x20\x99\x71\x4e\xfc\xa3\x28\x61\x68\xb3\xa7\xc1\x39\x73\x3a\xe7\xa0\x43\x38\x22\x39\xc4\xf3\x2e\x87\xa9\x1e\x8d\x52\x5c\xe4\xc8\x09\x43\xa1\x7e\xa8\xdf\x1a\x00\xf8\x78\xd5\x05\x91\x9a\x3f\x0e\x05\x01\x2e\x9f\x44\x89\xd7\x41\x87\x53\x3b\xea\x34\xe5\x15\x4e\xd1\x29\x67\x00\x43\x3a\x83\xd2\x19\xba\x76\x2e\x8d\x28\x24\xeb\xd2\xb4\xa9\x5c\x88\x1b\xc3\xb8\x88\x5a\x33\x4b\x4c\x02\xc2\xb6\xcb\x7d\x5b\xfe\x35\xbc\xc1\x44\x4a\x76\x66\xd6\x90\x4c\xe9\xd5\xe1\x55\x91\x7e\x4a\xa7\xcf\x94\xa2\xca\xd6\x3a\x89\x18\xe5\x49\x18\xc8\x61\x26\x22\x92\x30\xcc\x41\x62\x21\xb9\xf3\x35\xae\x71\x85\x2b\x63\xac\xe4\xac\x09\x26\x5a\x14\x07\x8a\xf3\x42\x01\x13\xae\xb6\x1d\xdf\x99\x7b\x51\x67\xcd\xc4\x7f\x65\x9d\x06\x9e\xa8\x17\x0e\x3b\x03\x86\x28\x24\x33\x35\x96\xc1\x65\x12\x23\x1a\x8e\xdf\x0f\x03\x25\x11\x52\x6b\x0c\xf0\x83\x00\x64\xc4\xa8\xf0\x70\x43\xa9\xb9\x3a\x81\x14\xc8\xb2\xb0\xaa\x86\x10\x55\x95\x01\x8f\xc3\x65\xbd\x7f\xa7\xe3\x1d\xce\xbf\x50\x20\x79\x91\x18\xc2\x5f\x76\x1c\x6e\xe3\xef\xae\xde\x53\x18\x88\x59\xf1\xc9\xc9\x34\x0d\xb8\x38\xe7\x25\xf1\x6b\xc8\x09\x02\xcf\xd0\xc2\x6f\x72\x1f\x64\xf7\x19\xc1\xb6\x13\x37\x19\x8c\x94\xce\xf6\x9c\xaa\x0e\x86\x9a\xac\x35\x7f\x08\x89\x3c\xf4\x69\xad\x5f\x08\x46\xc8\xbc\x79\xb3\x25\x92\x6c\x16\xb4\x99\x37\x09\xdb\x41\x59\xbb\x20\x7c\x28\x43\x10\xa9\x95\x5a\x0e\x51\x0b\x81\x72\x25\xb5\x24\x34\x85\x09\xcc\xce\xe9\x4d\xb9\x40\xc0\x60\xb3\x12\x87\x16\x92\x08\xc7\x5c\x2b\xfb\x2a\x0d\xa5\x3c\x44\x34\xda\x6c\x5a\xc0\xbc\x85\x12\x20\x85\x15\x4c\xce\xb1\x82\xbc\x45\xec\x9c\xec\x6b\x5d\x6d\x53\xf2\xa0\x94\x3c\xf2\x77\x4a\x8a\x48\x74\x18\xab\xc9\xe2\x8d\x08\x49\x95\x68\x4e\x20\x1a\x34\x63\x07\x84\x18\x1c\xf5\xab\x82\x24\x8a\xd5\xa8\xc9\x9a\x90\xec\x0c\xd7\x81\x21\x9b\x3d\xa1\x33\x29\x3c\xc8\x6f\x3d\xe4\xba\xb7\xa3\xf0\x16\xb5\x6c\xc9\xd6\xb0\x63\xbe\x66\x4a\xe9\x52\xa3\x33\xf5\xc9\xb9\x6c\x2b\x1c\x93\xbb\x04\xf6\x67\x79\x63\x99\xbc\xb0\x64\x45\xf0\xa2\x15\x96\x2a\x01\xc9\x33\x40\x51\xee\xb5\xf5\x26\xf8\x94\xc5\xc2\x88\xcc\x7a\xab\xb4\x53\x1c\x5a\x51\x6d\x74\xc2\x45\x07\x85\x67\x03\x63\xc7\xc1\x57\xd9\x74\x8e\xb7\x8a\x58\x26\xa0\x9b\xe0\xad\x1c\xf6\x48\xd5\x8b\x9f\x97\x09\xf9\x42\xd1\x81\x3b\x18\xee\x97\x32\xe5\xe5\x58\x57\xb3\x32\x42\xee\x5e\x39\xd1\x71\xe5\xe2\xc9\xb7\xfc\xbc\x15\x0a\x5b\x38\x4f\xf7\x3d\xad\xad\xd6\x59\xf1\x5c\x95\xbb\x50\x6b\xab\x8f\x6b\x10\x43\xf9\xb0\x78\x33\x96\xb5\x7e\x8d\x16\x51\x09\xf2\xbd\x4f\x6d\x93\x4a\x95\x12\xd5\xdb\xa2\x58\x42\xe3\x5a\x21\xfa\x18\x0a\x53\x6c\x53\x6d\xc1\x92\x39\xcf\x64\x87\x49\x84\x5f\x18\x94\xf2\xae\x18\xf6\xb4\x5b\x5a\x53\x2b\x4a\xf8\xb0\xed\xde\xa4\x67\xdc\x14\xa9\x55\x9a\x06\x18\x0c\xdc\x75\xfc\x6d\xea\x58\xe2\xb8\xc1\xda\x6a\xaa\x31\x95\x41\xae\x25\x71\xef\x7c\x96\x49\x4a\xf7\xe4\xdf\xd3\x74\x39\xbb\x8f\x6a\x16\x81\x53\x4f\x8a\xfb\x0b\xf4\x86\x0b\xce\x87\x96\xdb\xea\x47\xad\xf3\x0b\x66\x47\x2b\x1b\xac\x66\x30\xb5\x58\x48\xb7\x9d\xdf\xa4\x78\xc3\x5b\x94\x60\xb5\xe2\x73\xb2\x9b\x1b\xae\xbc\x78\x4c\x1b\x5e\xb9\xa3\xa4\xa5\x7a\xf1\xd6\xf6\x03\xd7\x87\x43\x0a\x28\x56\x7f\x5c\x49\x81\x4c\xa1\xaa\x34\x1a\xcd\xb7\x0e\x57\x53\xcd\x15\x05\x00\x66\x92\xd3\x54\xf2\xc5\xfd\x74\x5e\x73\x6d\xcb\x59\x5a\x4e\x90\xcf\x90\x3b\x0b\xf9\x85\xf3\x63\x16\x70\x45\x2f\x65\x1d\x72\xd2\xfe\x84\x1c\x68\x7c\x5b\xe7\x72\xd9\x7c\xad\x16\x4e\x39\x53\xba\x40\xd1\x6c\x54\xac\xba\x39\xe4\x0d\x24\x1a\xb5\x2d\xa4\x23\xfb\x0e\xeb\x6c\x5c\xf6\x15\x2a\xd2\x54\x4a\x52\x17\x38\xf9\x6c\x3f\x3c\x7e\xb5\xbc\x5d\xdd\x86\x7a\xfb\x69\x76\x3e\xbe\xe1\xfc\x78\xbd\x96\x56\xe2\x88\xdf\xd9\x2b\xe2\xf5\x7a\xea\x15\x97\xca\x8f\x14\x2b\xa6\xad\x84\x12\x71\x96\x3a\x20\x7d\x2f\x88\xb9\x7a\x77\x12\xcd\xd7\xfc\xc5\x2e\x1d\xd6\x6e\xd5\xfc\xdb\x68\xb7\x62\xde\x46\x9f\xba\xf3\xac\x25\x1b\xa9\xf3\x57\x6d\xc9\xca\xfb\xbc\x25\xab\xad\x74\xe9\xff\x79\xa7\xed\x09\x3f\x69\x3a\x2d\x8f\xaa\x9a\x87\x1b\xb8\x29\xd8\x39\xe4\x36\x01\xe5\x3e\x01\xd9\x3d\x69\xa1\x10\x33\x6a\x44\x34\xd0\xb8\x50\xae\x9f\xbd\x3f\x54\xbc\x59\x20\x5e\x59\xa5\x35\x79\x33\x5a\x2a\xe5\xc5\xb9\x7e\xbe\x7f\x7d\xe0\x9b\xef\xbf\xd0\x8d\x1b\xa7\x61\xac\x73\x4a\x9a\xa1\x30\x4c\xce\xff\x2f\x00\x00\xff\xff\xc9\x25\x1d\xe0\x82\x1a\x00\x00") + +func fontsStopFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStopFlf, + "fonts/stop.flf", + ) +} + +func fontsStopFlf() (*asset, error) { + bytes, err := fontsStopFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/stop.flf", size: 6786, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsStraightFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x55\x4d\x6f\xe3\x36\x10\x3d\x87\xbf\xe2\x1d\x78\x90\x81\x48\x74\xd3\x9c\x82\xa2\x10\x8a\x5e\x7b\xe9\xa1\x68\x01\x02\x84\xe2\xd0\x89\x1a\x5b\x5a\x58\xce\xee\x06\x98\x1f\xbf\xe0\x0c\x45\x49\x94\xbc\x80\x2d\x52\xf3\xf1\xe6\xcd\x07\xa9\xe3\xe9\xf8\xd0\x68\x3c\xe2\x57\xfc\xb2\xc7\x1e\x8f\x6a\xb8\x5e\x9a\xf6\xf5\xed\x5a\x1d\x4f\xc7\xbb\xbb\x7f\xfc\x65\x68\xfb\x0e\x0f\xea\xf9\xf3\x09\xf8\xa3\x19\xf0\x97\x6f\xff\xf7\x17\x00\x67\xde\xd4\x6d\x77\xec\xab\x6f\x6d\x57\x5d\x3f\x7c\xd5\x9d\x00\x3c\x37\x43\xfd\xd2\x9c\xfd\x7b\xf5\x7e\x7d\xab\x06\xaf\x8e\xed\x77\xff\x82\x80\xf0\xf7\x67\xd3\xe1\xbf\xfe\xe3\xf0\x0e\x7c\x86\xa5\x3e\x0c\xd5\xc7\xc5\xbf\xb6\x5d\x53\x1d\x1a\xf5\x67\x3b\x1c\x4e\x4d\x7b\xf6\x97\x27\x9c\xfb\xe1\x8a\x43\xf3\xa5\xbd\x36\xa7\x01\x6f\xcd\x57\x8f\x67\xef\x3b\xbc\xf8\xa1\x7d\xed\x18\x10\x43\x7f\xf6\x7d\xe7\xe1\x4f\x83\x57\x5a\xd7\xf3\x7f\xad\x80\x5a\x11\x6a\x55\x81\xf7\xb5\x32\x06\x41\xc5\xaf\xf1\xc1\x4f\x7e\x73\xe4\xc8\xa1\x56\x25\x95\x54\x22\xc9\x6b\x05\x62\x79\x41\xa4\xd9\x8c\x76\x60\xe1\xe8\x5d\xab\x7d\xc0\x35\xfb\x05\x64\xad\x8a\x5d\x10\x17\xff\xc6\x50\x4c\x20\xc4\x8f\x7f\x16\x68\x36\x61\x91\x4d\xee\x96\xdf\x43\x14\xa3\x93\x50\x03\x21\x2f\x6b\xc2\xd3\x58\x1d\x25\xbc\xb0\xc6\x91\x63\x21\x41\x8f\xc2\x5a\x21\xd6\xe3\x5e\xf3\x3e\xc1\x38\xa7\xd3\x3e\x5a\xca\x5e\x87\x72\x69\x79\x8d\xd9\x31\xc7\x05\x13\xe7\xa2\x1c\x96\x99\x3b\x27\x89\x21\x51\x65\x35\x41\xf8\x44\x09\x87\x65\x0d\xdc\x8e\x0d\x9c\x1b\xdd\xd6\x4a\x27\xcb\x0c\x92\xb5\xe4\xdc\x08\x48\xcb\x98\x02\x46\x02\x92\x7b\x8f\x8c\xe3\x6a\x67\xfa\x18\x3b\x52\x91\x44\x0c\xb6\xbc\x8b\xe8\x55\xe4\xde\x33\x03\x2b\x29\x2c\x0b\x82\x38\x84\x69\x10\x47\xc1\x7d\x9a\x03\xae\x3e\xf7\xd6\xc6\x3e\x64\xbd\x2a\xcb\x79\xcb\x93\xa1\x99\x59\xc7\x14\x76\xe1\x59\x4d\x55\xc7\xf4\x8b\x53\xcd\x13\x14\x16\x53\x96\x76\x1c\xf5\xa9\x05\x24\xf9\xc5\x65\xae\x0c\x13\x1c\x2c\x2c\xef\x33\x2f\x99\x06\x92\xdc\x97\x5e\x34\xe2\x2e\xbd\x92\x02\x58\xc1\x19\xb8\x18\x69\x41\x42\xe8\xc7\x29\x20\x19\x82\x49\x29\xe7\x9d\x52\x99\x35\xe3\xea\x20\x98\x70\xd2\x84\x12\x33\x25\xd8\x95\x02\x6b\xba\x31\xb0\x35\x9b\x81\xa3\x12\xa2\xb4\xb4\x2e\x6a\x3c\x2c\x76\x5d\x9e\x59\xc5\x23\xe1\x1b\x9e\xf6\x67\x9e\x36\xf7\xac\x55\xc1\x16\x8b\xc4\xe3\x9c\xf3\x4d\x06\xc2\x2a\xbf\x1b\x2c\x45\x69\xe5\x78\xc0\x1a\x6c\x24\x2f\x25\x21\x63\xf3\xca\x04\x38\xbe\x42\xd6\x85\x16\xc5\x82\x48\x64\x28\x1e\xf3\x0e\xf0\x78\x33\x71\x72\xf3\x9b\x96\x79\x05\x56\x49\x28\x87\x91\x9b\x4e\x4b\x4b\x63\xe7\x1f\x80\xd9\x67\x40\xb9\x09\xd3\xe6\x97\xb4\x24\x28\xf3\x58\x8c\x90\x93\x62\x1c\xee\xdd\x42\x11\x09\x17\x2e\xfb\x2a\x80\x01\x72\x98\xd1\xba\x9c\xac\x93\x37\xe9\x15\x84\x30\x09\x01\x9d\x59\x33\xc1\x82\x89\xdc\x34\x94\x5f\x3d\xc4\x1d\x19\xa3\x4b\x5d\x8b\x59\xa0\xfc\x28\xcd\x22\x13\xad\x6a\x80\xad\xc8\x39\xd7\x2d\x8f\x38\xbd\x37\xeb\x4c\xcb\x02\x51\xde\xbb\x20\x1c\xc1\x53\x32\x6e\x35\x24\xdc\x4e\x99\x9d\xbc\xf0\x3c\x0e\xe3\xd1\xca\xac\xed\xce\x6c\x59\xef\x8a\x65\xc0\x09\xc2\x4c\x42\x39\xbb\x13\x8b\xe0\xf3\x1b\x64\x65\x01\xe5\x35\x0e\x69\xfc\x0e\x59\x67\x54\x4c\x3a\xf7\x89\x4a\x0f\xf4\xe1\x6d\xf3\x16\xef\x9d\xeb\x6f\x1e\xe5\xe8\xb9\xad\x94\x18\xa5\x2b\xb7\x07\x7d\x54\xac\x7a\x59\xa2\x5c\x95\x76\xeb\x53\x42\x51\xf9\x23\x00\x00\xff\xff\xfc\x24\xb9\x78\x77\x0a\x00\x00") + +func fontsStraightFlfBytes() ([]byte, error) { + return bindataRead( + _fontsStraightFlf, + "fonts/straight.flf", + ) +} + +func fontsStraightFlf() (*asset, error) { + bytes, err := fontsStraightFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/straight.flf", size: 2679, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTanjaFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x99\x7d\x57\xda\xca\x13\xc7\xff\xcf\xab\x18\x2f\xb5\x87\xf1\x54\xa8\x88\xc5\x9e\xc3\xd5\x20\xde\x62\x51\x14\x05\x45\xad\x1e\x2e\x02\x2a\x2a\x20\x20\x22\xb5\xfe\x5e\xfb\xef\xcc\xec\x43\x9e\x76\x11\xef\xf6\x98\x7c\xf6\x3b\xdf\x99\x24\x9b\x6c\x42\xd2\xeb\x87\xeb\x54\xe3\x13\xac\xc3\x37\x48\x7d\x85\xe5\x15\x48\x39\xd5\x46\xef\xae\x01\x93\xc6\x08\x26\xc3\xce\xd3\x53\xbb\x07\xd7\xfd\x21\x2c\xff\x2d\xf4\xbd\x69\xaf\xf7\x02\xc5\x46\xf3\x7e\xd4\xef\xfd\xbd\x0c\x57\x53\x27\x7f\x3b\xec\x8c\x9e\xfa\x8f\xb7\xed\x21\x14\x13\x50\xee\x0c\x3b\x0f\x0f\x7d\xf8\xab\x7a\xdb\x86\xbd\x7e\xf3\xbe\x3d\x84\x42\xaf\xdf\x6d\xff\x05\xd9\x47\x8e\xa5\xd3\x6e\x67\xd4\x1c\x8d\xc6\xbd\xc4\xb8\xd7\x49\xb4\x5b\xe3\x0d\xe7\xd3\xa7\x4f\xee\x1c\x0b\xd7\x81\x05\x04\x70\x9d\x05\x5c\x59\xf1\x56\x52\x04\x6a\x91\x1e\xaf\x5c\x67\x69\x69\x09\xe8\xcf\x75\x62\x31\x00\xfa\xf3\x13\xc8\x36\x37\x11\xc6\x10\x56\x57\x59\x8e\xe1\xaa\x68\x10\xd4\xe7\xf3\x44\xcb\xcb\x0d\x40\x05\xa5\x5e\xc1\x74\x3a\x9d\x26\xac\x20\x10\x84\x54\xe1\x4d\xa7\xd9\x90\x0e\xaa\xc1\xca\x54\x78\x91\xc4\xb5\xb5\x35\x70\x1d\x8d\xd2\xb3\x88\x6b\xd2\x2f\x88\x59\xa0\xf4\x4b\x9c\xb9\xe7\x9f\x31\x93\x11\xfa\x67\x04\x60\xb6\xa9\x84\xcc\xd2\x90\xc9\x64\x02\xbb\x1b\xd8\x73\x71\x02\xe9\x9c\x89\x93\x27\xa2\xd6\x25\xaf\xe2\x48\xdd\x38\xb2\x1c\x97\xc3\xa1\xd6\x4a\xd7\xbe\xc0\x46\x5d\xd7\x41\x3d\x7e\xa8\xae\x2a\xc4\xc0\x5a\xe8\x18\x18\x67\x5f\x01\x5a\x2d\xc9\x20\xad\xd7\x01\xd6\xd7\xd9\xb0\x84\xeb\xd4\x63\x7d\x5d\xb4\x88\xee\xf7\xcb\x32\x86\xcb\x24\xa0\xf2\xd5\x15\x13\x97\x1c\x37\xbf\x62\x32\xfb\x0b\x99\x96\x96\x41\x7f\x6f\xaa\xc4\x7c\x5b\x9f\xe5\x0b\x1e\x4a\x64\xa1\xa6\xac\x4f\x93\x39\x49\xdc\x94\xe9\x44\x02\x99\x18\x05\x11\x4a\x02\xd7\x51\x64\xbf\xc0\xe0\x2b\xa2\x38\xa1\x5f\x91\x4e\x2d\x0a\x42\x88\x10\xaa\x0b\x40\x67\x58\x0e\x69\x05\x17\x84\xb8\x82\x0b\x0b\x2a\xbc\x82\x56\x22\xdb\xc2\xc2\x82\xb5\x60\x0a\x73\xb9\x1c\x89\x29\xf2\xe7\x72\x32\x9c\x52\xfb\x90\x52\x05\x53\xf2\xaa\xe3\x04\xed\x8b\x16\x5c\xc5\x98\x38\xad\xab\x94\xa0\x86\x7a\x15\xbd\x1b\xe3\x2a\x06\xa3\x3a\xc3\x58\x30\x4d\xc6\x4a\x05\x82\x54\xa1\xa6\x8c\x69\x9c\x45\xe1\x82\x6b\xb8\xb8\xb8\xb8\x48\xe2\x1a\xaa\xb0\xa7\xb1\xb0\x86\x01\x0a\x45\x23\x87\xfc\x0d\xf7\xf7\xf7\x49\xfc\xa6\x0b\xb2\xe4\x69\xfb\xfb\x01\xf2\x32\x8c\x05\x33\xf8\x99\x9a\x14\x33\xea\x54\x64\xd4\xa9\xc8\xa8\xbb\x43\x46\x4d\xe1\x0c\xce\x9e\x09\xeb\x48\xd3\x0e\x5c\x67\x9d\x8c\x62\x06\x1a\x34\x53\xd4\x5c\xf0\x3b\xc6\xe3\x71\x12\xbf\x53\x4a\x3c\x0e\x4a\x8b\x2b\xe3\x77\x34\x44\xe7\x98\xab\xde\xe4\x0c\x4e\x53\xc7\x70\x5b\xd1\xf7\x83\xd9\xb7\x95\xac\x38\x9d\x59\x31\x90\x59\x31\x8c\x59\x35\x88\x59\x35\xac\x59\x35\xd0\x59\x0c\xdf\x72\xc3\x63\x6b\xba\x1b\xcd\x79\x87\x72\x9d\x0d\xb5\xe5\x0d\xb5\xe5\x0d\xb5\xe5\x0d\xf4\xf7\x65\x7c\x23\xf8\x30\x70\x1d\xd8\xc4\x64\x32\x99\x24\x6d\x93\x63\xc9\xa4\x0c\x6f\xea\xe9\xbf\x19\x79\x52\xdb\x55\xaf\x70\x0e\x53\xa9\x14\xa9\x39\x36\xa6\x04\xa5\x48\x14\xa4\x35\x10\x1a\xe4\xc2\x4f\x91\xd0\x69\xcd\x61\xa3\x21\x54\x72\x12\xab\xe2\x8d\x06\x63\x83\x5b\x58\xd5\x68\xd9\xd3\x2d\xbc\xba\xba\xba\x62\x79\x8b\xcc\xc4\x76\x15\x04\x2b\xc3\xd5\xac\x21\x80\x3c\x36\x9b\x4d\x96\xf3\x94\xd8\x6c\x82\xeb\xe4\x51\x9b\x7d\xe8\x33\xf8\xd3\xcc\x85\xb7\xb1\xd5\x6a\xb5\x58\xde\xa6\x34\x62\x89\xc4\x76\x6c\x89\x3c\x6b\xe1\x7f\xb0\xcd\x0d\x08\xb5\x43\xaa\x10\x56\xc3\x86\xb6\xbd\xf0\x0f\xbc\xe6\x06\x84\xda\x21\x55\x08\xab\x26\xb4\x8e\x71\x01\x6f\x6e\x6e\x6e\x48\x2e\xe8\x3b\x17\x11\x89\x12\xa9\xa3\x0d\x02\x45\xda\x8c\xc2\x3b\x9c\x77\x7b\x0b\x21\xbc\xe5\x16\x56\x4d\x68\x29\xfc\x13\x3b\x9d\x4e\x87\xc5\x9f\x6a\x8a\x59\xc1\x67\x0e\x96\x72\x5d\xa7\x88\x77\xdc\xa4\x58\xd4\xf3\x55\x21\xad\xee\xee\xc2\x08\x94\x37\x73\x4c\x77\x29\xfd\xfe\x9e\x64\x42\x22\xc6\x7b\xa6\xb0\x1a\xf0\x32\x5b\x0b\xef\x79\xa7\xf3\x63\xf8\xc0\x6d\xc6\x55\x50\xc2\x6e\x17\xba\xdd\x2e\x05\x4a\x08\x40\xd4\xed\xbe\xdb\xa1\x16\xed\x00\x98\x36\xc3\x1b\xda\xc7\x1e\x00\xf4\x7a\xc0\xd8\xd3\x48\x6b\x85\xd0\xeb\x69\x04\x1f\x0a\x83\xed\x08\x0e\xb0\xdf\xef\xf7\x49\x3e\x60\x73\xbf\x3f\x0f\xfa\xd2\x2c\x85\xcb\xf8\x48\x8d\xe4\x32\xe7\x3d\x3e\x82\x41\x05\x3b\xda\xf6\xf8\x10\x07\x83\xc1\x80\xe4\x43\x36\x0f\x06\x51\x1c\x0c\x40\xab\xc2\x2b\xd2\x58\xb5\x14\x3e\xc2\x21\x35\x92\x8f\xb8\xda\x70\x28\xd1\x53\x09\xb4\x21\xe2\xb5\xed\x71\x05\x47\xa3\xd1\x08\xc4\xbb\x2a\x00\x8c\x46\x20\x55\x9f\xb9\x82\x26\x83\x48\xb3\x14\xae\xe2\x13\x37\x21\x57\xbd\x07\xe3\x47\xd0\x54\xf8\x98\xc3\xe3\x31\x7c\x0c\xe1\x18\xc7\xe3\xf1\x78\x46\xe1\x13\x36\x3f\x3f\x83\x0d\x81\xf8\xf9\x59\xe4\x9d\x20\x91\x28\x71\x32\x7b\x8f\x6b\xf2\xba\x99\x4c\xc0\xd0\x99\x4c\xde\xed\x40\x0d\x27\x13\x98\x50\x7f\xe6\x4c\x3c\xe5\xda\x2f\x2f\x14\x20\x7e\x79\x11\x9e\x53\x24\x0a\xa1\x67\xf0\xa7\x99\x8f\xe0\x8c\x1d\xd3\x29\xc9\xc4\xd3\xa9\x70\x9c\x21\x91\x30\x9f\x79\x83\x60\x46\x53\xe1\x73\xfc\xcd\x4d\xcb\xe7\xea\xb7\xe1\xb9\xbe\x75\x9f\xab\x12\xe7\xfa\x59\x16\x49\x8b\x14\xfe\x85\xaf\xaf\x40\x2b\x8e\x58\x56\x6c\xf1\x27\xbb\xae\x73\x81\x7f\x74\x3d\xc5\x14\x95\xcc\x46\xc1\x22\x87\x59\xa6\x13\x5b\xf7\xe8\x12\xdf\xde\x58\xba\x44\xdb\x4a\x5b\x02\x7b\xc4\xaf\x0c\xe0\x7d\x00\x33\x3c\xf8\xe6\x81\x77\x7e\x37\xcf\xfd\x3b\xdc\x77\x48\xde\x17\xba\xe0\xcb\x82\x65\x69\xde\x46\x83\x5f\x78\x59\x6b\xa8\x97\xe5\x06\xbf\x2c\x7b\x9a\xf5\x75\xf8\x4a\x5f\x12\x7e\xda\xda\xda\xda\xd2\xda\xd6\x56\x88\x54\xd4\x58\xd0\x38\x1e\x4d\xcc\xe7\xf3\x79\x70\x9d\xa6\xde\x88\x47\x5e\xd4\x5e\xb0\xa5\xdf\x78\x04\xb5\x70\x7b\x7b\x7b\x1b\x5c\xa7\x45\x65\x42\xe4\x45\xe7\xde\xc3\x36\xfe\x43\x4d\x93\xd0\xb4\x4f\x8a\xb6\x82\xd7\xf8\xe3\xc7\x0f\x70\x9d\x6b\xf5\xae\x21\x84\xa0\x12\x86\x70\x25\xdb\xd8\xdd\x60\xa1\x50\x20\xba\xa1\xcc\x42\x21\x40\x22\x5a\x50\x19\x32\x5a\x10\x19\xae\x73\xab\x0f\xc1\x4f\x3b\x3b\x3b\x3b\x5a\xdb\xd9\xb1\x90\xf1\x50\xbd\x57\xde\x0e\x46\x17\xca\xad\x0e\xc5\x74\xe1\xdf\xe1\xbb\x74\x47\xfb\x50\x2c\x92\x76\x87\xc5\x62\x91\x0b\xde\xab\x71\x0b\xc0\xee\x2e\xc3\xee\xae\x52\x88\x7c\x21\xc3\x20\x3f\xe0\x1e\x0b\x0f\x68\x5d\x3d\xe0\xde\x9e\xe9\x36\x02\xd1\x31\x11\x9d\x2e\x96\x4a\x50\x2a\x95\xa8\xd3\x45\x00\xa2\x52\xc9\xd4\xa1\xc6\x1d\x6b\x35\xf3\x65\xd0\xd3\xdf\x6b\x7a\xa8\xbe\xd2\x98\xc8\x78\xd6\x8c\xd7\x55\x1f\x0f\x0e\x0e\x88\xfa\x94\x7c\x70\x10\x20\x2f\x3a\x77\xc1\x47\x2c\x97\xcb\x65\x41\x00\x50\x2e\x87\x28\x10\x85\x00\x59\xf6\x70\x80\x87\x87\x87\x44\x03\x32\x1e\x1e\x06\x48\x44\x0f\x55\xc6\x00\xfd\x64\x29\x38\xc4\xa3\xa3\x23\xa2\x21\x95\x39\x3a\x52\x04\x10\xa0\xf9\xc7\x70\x84\xf2\x33\x9f\x04\x15\x1d\x61\x54\x8b\x16\x7c\x12\x8f\xd1\x27\x7c\xaa\x56\xab\xe0\x53\xcc\x50\xfd\xc0\x5d\x63\x4c\x69\xc7\xc7\x16\x82\x31\x1e\x1f\x1f\xbf\x7b\xa8\xc1\x47\xf1\x33\x8f\xcf\xc9\x09\xa9\xc4\x27\x27\xc2\xf0\x8c\x44\xc2\xfb\x3c\xfb\xc7\x0a\x80\x29\x40\x9d\x89\x1c\xfc\x5a\x4d\x76\x6a\x35\x53\x07\x26\x58\xab\x41\x8d\xfa\x1f\x9e\x41\x2f\xb4\x89\xd3\x53\xd6\x5e\xf0\x54\x46\x15\xf9\xa3\x33\x86\xc4\x4f\x53\x4a\x39\x3b\xb3\x10\x4c\xf1\xec\x4c\x10\xb5\x29\x72\x94\x25\x5b\xc1\xdf\x78\x4e\x4d\x6a\xbf\xe5\x37\xb7\xdf\x68\x8a\x46\xf7\xf0\x15\x7f\xfd\xfa\xc5\xda\xab\xfc\x79\xf6\xaa\xcf\x86\x54\x40\x2b\x9e\x39\x58\xc9\x75\x9d\x3f\x78\x01\xef\x2d\xc1\xff\x9b\xe4\x0d\x2f\x2f\x2f\x45\xff\x4d\xff\xe6\x7c\xc3\xcb\x88\x42\xe0\x33\x47\xb6\xec\x1d\x57\x7d\xf9\xdf\xe5\xfa\xf2\xbf\xe6\x63\x9d\x97\x5c\x27\xf4\xef\x3f\x09\x5c\xeb\x82\x16\x49\x6f\x0b\x5f\x20\x01\x1b\xd9\x8d\x2c\x24\xe0\x8b\x94\x2e\x2e\x00\x92\x89\xc4\x05\x7f\xec\x24\xe9\x0b\x6b\x17\xf5\x7a\x92\x95\x2f\xe0\x3a\xe4\xb9\x10\xb5\x92\xea\xa3\xa8\xd0\xea\x75\xa9\xc8\x5a\xf5\x3a\x49\x42\x95\xc7\xf4\x3f\xd9\xac\x07\x07\xfc\x4b\x53\x2e\xe9\x51\x9d\x48\x24\xe4\x82\xba\xd5\x84\x6c\x79\x7e\x2a\xc7\x72\xa2\xb7\x23\xbf\x45\xc7\xf6\xa9\x77\xa4\xff\xdf\x2c\x56\x4c\x24\x7e\xc6\xbc\x21\x8d\xe5\x2a\x31\xff\x08\xc7\x62\x7a\x98\xff\x1f\x00\x00\xff\xff\xd0\x66\xcf\xd4\x57\x1f\x00\x00") + +func fontsTanjaFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTanjaFlf, + "fonts/tanja.flf", + ) +} + +func fontsTanjaFlf() (*asset, error) { + bytes, err := fontsTanjaFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/tanja.flf", size: 8023, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTengwarFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x5f\xaf\xa3\xb8\x15\x7f\xe7\x53\x1c\x21\x24\x76\x55\xc6\x9a\x3b\x0f\x57\xde\xab\xd1\x28\x5b\x75\xfb\xb6\x2d\x52\xa7\x0f\xbc\x61\xc7\xe4\x86\x4e\x02\xb7\x81\x34\xb3\xfd\xf4\x95\x8f\x6d\xb0\x8d\x21\x21\x3b\x53\x69\xa5\x44\x11\x1c\xdb\x60\xff\xce\xff\x63\x27\xbb\xc3\xee\x03\x4b\xe0\xe9\x3d\x3c\xc3\x87\x27\x78\x0f\x4f\xcf\xd1\xe7\xaa\x79\xbd\xb0\x13\x3c\x91\xf7\xb0\xab\x5f\x0f\x55\x0f\xfc\x37\xf8\x73\x75\xa8\x1b\xc1\xe0\xe7\x8e\x57\x87\x03\x7c\x3c\x72\xb6\xd9\x6e\x05\xd9\xb3\xd3\xa9\xee\xc8\xb6\x3d\x7e\x8a\x7e\x16\xec\xad\xaf\x04\xec\x4e\xed\x11\x7e\xad\xbf\x54\xf0\xcf\x13\x67\x4d\xda\xc1\xc7\xb3\x24\x36\x5d\x2d\xaa\x6e\xdf\x5e\xc8\xbf\xde\x0e\xa4\x61\x1d\x23\xaf\xed\x7f\x3e\x81\x59\x71\xd7\x9e\x20\xfa\xb5\xea\xd9\xae\x6d\x7a\xf8\xe1\xb2\xaf\xb7\x7b\xa8\xbb\x0c\xea\x06\xfa\xf3\xa9\xc9\x80\xb3\xae\x12\xd0\x36\xf0\xb9\x3d\x7c\xa9\xab\x06\x5e\x7e\x8c\xfe\xc2\xfa\xea\x05\x3e\x50\xf8\x6b\xc5\xe1\xe9\xa7\x9f\x9e\xa3\xe8\x97\xaf\x6f\x07\xd6\xb0\xbe\x6e\x1b\x68\x77\xb0\xab\x4f\x5d\x0f\x87\xba\xa9\x5e\x00\x3e\x6e\xdb\xb7\xda\x80\x6c\xfb\x7d\x75\x92\x5c\x76\x9f\x22\x29\x0b\x78\x07\xf1\x91\xbd\xd6\x5b\x68\xce\x47\x5e\x9d\x62\xc4\xb4\xab\x0f\x15\xd4\xa2\x6a\xfa\x7a\x57\x6f\x71\xda\x88\x01\x00\xbc\x83\x6e\xdf\x9e\x0f\x02\xd8\xe1\xc2\x7e\xeb\x80\x57\x50\xb2\x34\xc3\x97\x9a\xf6\x12\x25\xea\xa1\x7e\x5f\x41\xbc\x67\x27\xc1\x0f\xac\xf9\x12\xc3\xbb\x77\xf0\x76\xaa\x9b\xbe\x03\xd6\x01\x03\xec\xcd\x80\x9f\x7b\xd8\xb2\x26\xed\xe5\x34\xdd\xf1\xdc\xed\x2b\x11\x3d\xbd\xc7\x19\xf6\x55\xfd\xba\xef\x25\x2f\x0c\xb6\x7b\x76\x62\xdb\xbe\x3a\x45\xcf\x30\x3f\x98\x41\xd3\xf6\x50\x37\xdb\xc3\x59\xd4\xcd\x2b\x88\xaa\xdb\x56\x8d\xa8\x4e\x5d\xf4\xe1\x09\x5f\x3b\xb2\xaf\x28\x13\x38\x54\xcd\x6b\xbf\x87\x1f\xaa\xaf\xe6\xe1\x6d\x7b\x3c\x56\x8d\x12\x59\xf7\x23\xfc\x09\x18\xec\xce\xe2\xb5\x82\x1d\xdb\xf6\xed\x29\x52\xa0\x44\xb5\x63\xe7\x43\xaf\xb0\x1e\x5b\x51\x21\xdf\xfd\xbe\xee\x40\x2a\x30\x7a\x7a\xc6\xc7\x94\x24\x25\x3c\x67\xda\xe8\x6f\x7f\xff\xfc\xcb\x0b\xfc\xe3\xcc\xbb\xbe\xee\xcf\x52\xa8\xdd\x0b\xa4\x5f\xf6\x29\x4e\xf3\xef\x0c\xd2\xff\x6a\xfa\x6b\x06\xe9\x56\xd3\x5b\x12\x45\x49\x92\x24\x9b\xfb\xae\x9b\x08\x80\x88\x3c\x4d\x24\x41\x29\xc0\x8d\x84\x7c\x47\xf7\xc8\x4f\x88\xd8\x44\x20\x28\x80\xa0\xc9\x26\x62\x79\x0a\x4c\xaf\xe2\x3e\xf7\x3b\xa9\x81\x1c\xfa\x45\x2a\xbf\xb2\x51\x5e\x2e\x14\xbf\x44\x8d\x50\xfc\x06\x46\x48\x2e\xbf\xf6\xc4\x6b\x1a\x66\x55\xd9\x2f\xf2\x94\xa6\x71\x91\x6c\xa2\x82\x13\x3a\x3c\x4b\xe3\x82\x27\x9b\x88\x33\x42\x89\xc8\xb1\x2f\xcb\x57\xf2\x99\x09\x49\x29\x55\x49\xd9\x83\xc8\x87\x47\xc4\x38\x19\x92\x8a\x46\x32\x13\x89\x7c\x17\x7b\x6d\x05\xb8\x6c\xcc\xd3\x36\x77\x99\x88\x69\xcc\xa5\xcc\x28\x8e\x4a\x4e\xca\x82\x11\xd0\x26\x11\xa7\x8a\x52\xa3\x1c\x47\xf9\x45\x5c\xd7\xbb\x32\x2c\x39\xc7\x68\x24\x77\xdc\x36\x91\xb1\x65\x41\x15\x62\x6a\x23\x92\x77\x8d\xb5\x90\x84\x7c\xaf\x2c\x38\x31\x48\xa6\x77\x64\x80\xa8\x8e\x92\x72\x35\x50\x52\xfd\x80\xbe\x13\x75\x27\x34\x57\x92\x4e\x03\x13\x45\x8e\xb9\x0a\x8d\xaa\x2c\x38\x50\x30\xf2\x29\x38\xd5\x2a\x2d\x2f\x68\x9c\xda\x3a\x45\x4e\x0b\xae\xe5\x9f\x03\x85\x01\x71\x96\xaf\x54\xa3\x33\x60\x40\x80\xf2\x0c\xa5\x42\xbd\x70\xea\xf5\xaf\x5c\xcc\x5f\x38\x09\x5f\xd0\x34\x35\xf3\xf6\xc5\x76\x2f\xcf\xdb\x82\xcd\x4c\x50\xca\xa5\x62\x21\x4b\x36\x91\x64\x0b\xca\x82\x52\x4b\x11\x37\x4f\xb5\xd4\x94\x16\x2e\x83\xa5\xf6\x3f\xcb\xaa\x83\xc4\x9a\x87\xc7\xa5\x88\xe3\x2d\x6e\x90\x15\x8e\x0a\x54\xcb\x89\x00\xa6\x99\x99\xd6\x18\xa9\xef\xe4\x58\xc9\x56\x0d\xe5\x28\xd7\xf1\x29\xba\x40\x72\xf4\x0b\xed\x61\xd4\xe1\x62\x9e\xbc\xfe\x44\x94\x16\x94\x4a\x65\xcb\x5e\xa2\xf8\x92\x24\xda\x29\x37\x0e\x7d\x71\x35\x7f\x7d\xb9\x9b\x44\xa3\x96\x76\x97\xf7\x20\xb8\x30\xc4\x14\xca\x8d\x42\xf7\x3e\xc9\xad\x5d\x23\xc4\x29\xcc\x00\xd4\x29\xdc\x19\xc8\x6b\x40\xa8\xa8\x66\x46\x4b\x2b\x07\x2e\x51\x43\xfa\x55\x30\x47\x9d\x8e\x2a\x75\xf3\x85\x5e\x04\xdc\x95\x2c\x58\x7e\xd3\x96\x89\x1c\xb5\xe4\x21\x57\xb7\x64\x21\x47\x2c\x39\xe8\x11\xf3\xb0\x1e\x99\x51\x9d\x0d\x2b\x00\x2d\x00\x6f\x02\x71\x0a\x33\x00\x75\x0a\x57\x84\x21\x07\x60\x2f\xa8\x4e\x3a\x38\x37\x83\x43\x9e\x83\x6b\x44\xa6\x09\x61\xb2\xa1\xa7\xb1\x71\x6a\x77\xf9\x41\x30\xc3\x6c\x7e\x5b\xc4\x32\xff\xba\xe3\xd4\x69\x13\x53\x06\x65\x83\x08\x51\x7a\x0a\xcb\x38\x9f\x23\x00\x9f\xfd\x09\xc0\x20\xca\x20\xd4\x00\xde\x19\xd0\x41\xe4\x01\xf8\x33\x3c\x04\x19\x99\x53\xe6\x95\xcc\x4b\x66\x33\xef\xdc\xc8\xc2\x2b\x80\x55\xa6\x1e\xca\x4c\xca\xca\xc4\x60\xb5\x58\x43\x0d\xce\x60\xcb\xc6\xae\xbe\x96\xc2\xbe\xcb\xd4\x2c\xe7\xd7\x8b\x81\xef\x55\x2a\xdc\xc8\xe4\xa2\x98\x56\x49\xa1\xe4\x84\x11\xe3\xec\x25\xd7\x44\x86\x7b\x0b\x9a\xd1\xe9\x10\xd1\x43\x8a\x55\xaf\x9a\x73\x3d\x95\x08\x65\x81\xa0\x36\x34\x9a\x07\xac\xa2\x89\xc8\x63\x4e\xd0\xd9\xa9\x09\x33\xaa\x81\x66\x59\x16\xb9\xda\xfa\x58\xa0\xa5\x7c\xa9\xed\x0f\x53\x09\x7a\x0d\x6c\x09\xae\x06\xf0\x0e\x82\xfb\xa2\x48\x0b\x6e\x45\xce\x00\x49\x68\x7e\x8f\x49\x05\xfd\x29\xd8\x23\xc3\x05\x56\x47\x63\x89\x44\x71\x4d\x5a\xc8\x0b\xd7\x3d\xf2\x69\xd5\x4d\x87\x1e\xac\xc9\x88\xd9\x2a\x4c\x93\x36\xf5\x9d\x5e\x31\xe3\xcb\x68\x0a\xce\xa3\x55\xed\xa7\x8c\x4e\x23\x41\x10\x05\xc5\xc8\x42\x15\x1b\xd2\xfe\xa9\x5d\xc2\xcd\xd0\x05\x25\x53\x69\x4d\x44\x13\xea\x90\x2e\x30\x8a\x4a\x71\x98\x8e\x92\x9a\x08\xca\x74\x60\x21\x2b\x2f\x13\xa1\x84\x3a\x5c\x21\x39\x67\x1b\x22\x4f\x7d\x7b\x4f\xf5\xa6\x2a\x70\xc8\x81\x13\x85\x9c\xc3\xf2\x12\xbf\x00\xb1\xc0\x04\x9b\xc4\x44\x1e\x6d\x27\x29\x0a\xd4\x79\xd8\xac\x8a\xcd\xcc\xec\xe9\xc9\xa4\x2a\x98\x13\xf5\xad\xa6\x1c\x17\x9c\x99\x8f\xa0\x18\x90\x06\x43\x71\xcc\x14\x6c\x9b\x41\xb4\x60\x5b\x8e\x0a\x9d\x53\xfb\x51\x9f\x5b\x7a\xb4\x45\x95\x63\xc4\x18\xe2\xa7\xcb\x80\x69\x9b\xf7\x0b\x6e\x37\x45\x6e\x95\x9c\x28\x38\x13\x1c\xc8\x18\xbf\xae\x0a\x2f\x24\x4b\xd9\x6b\x62\x0f\x16\xd8\xda\x56\x87\xab\xda\xf5\x0f\xef\x9b\xeb\x5d\x5e\x32\x46\x05\xdb\x65\x27\x7e\x3b\x71\xde\x19\x0d\x5c\xef\x08\x38\xf4\x54\x2a\xa5\xb1\x16\x6d\x2a\x1a\xe1\x30\x9b\x31\x5e\xdd\x44\x74\x83\x85\xa8\xe8\x3f\x01\xb7\xdc\x9c\xc2\x4a\x96\x5b\x65\xe1\x79\x08\xb1\xb2\xaa\xb3\x19\x36\x68\xad\xd3\x1f\x42\xc6\x83\xb4\x32\x8e\xe3\x34\xb0\xc2\xb7\x4f\x11\xf4\x86\x14\x31\x56\x87\x64\x9a\x22\xae\xaf\x7e\x6f\xa4\x06\x3f\x52\xe7\xcb\x91\x1a\xa3\x25\x17\xfa\x72\xd3\x2a\x21\xa8\xb2\xb4\x40\xf7\x52\xba\x13\xe9\xff\x29\xe3\x5f\xb5\x2d\x4c\x5d\xa3\xfa\xd0\xb0\x68\xe1\x05\x6e\x37\x6e\xdb\x59\xdd\xcf\xe8\x6e\xa2\x72\xc0\x18\x0f\xd3\x9f\xa0\x97\x0c\xee\x68\x46\xb5\xa9\x2f\xfb\x1f\xba\xd4\xfa\xf0\x17\x1a\xf4\x1b\x3a\x56\x8f\xa7\x98\xf6\xc9\x74\xc1\xad\xa3\x69\xcd\x36\xc6\x54\x09\xda\xa8\xb3\x20\xf6\x71\x78\xa9\x5c\xf0\xb6\xf3\x20\xa5\x1a\xac\x54\x51\x31\xaa\x4e\x55\xe9\x84\x9a\x4d\x2a\x31\x66\x39\xfc\x68\x41\x42\x55\xf7\x1a\x8e\xb5\x49\x38\x16\xe1\x18\x84\x63\x0f\x8e\x01\xf8\x8d\xd1\x18\x24\x04\x74\x02\x15\x9d\x4a\x29\x1f\x9d\x71\x1c\x24\x63\xe5\x62\xd5\x2e\x36\xe9\xd6\x2f\x4b\x7e\x10\xda\xf2\xba\xc5\xe7\x42\x97\x15\xd9\xa6\x91\x02\x02\xb1\xcd\x0e\x6e\xe9\xa8\x0d\xa7\x00\x0e\x86\xb7\x40\x7c\x5b\xef\xc6\xe0\xb8\x71\x0e\x6e\xbc\xf5\xdc\x78\x12\x79\x7d\x58\x8b\x29\xc2\x73\xe4\xd9\x5c\x6c\xc9\x41\x75\xac\xca\xf8\x53\xa7\xbe\x3d\xda\x4e\x06\x7d\xbf\xca\xe3\x78\x3c\x0a\x92\x8e\x3c\x90\x22\xd7\xa7\x10\x17\x37\xdc\x5f\x8f\xb6\xf3\x0f\x13\xc6\x98\xb2\x7a\xfc\x59\xa2\xe4\xca\x01\xc8\x70\x8a\x8c\x1a\xc1\xcd\xac\x29\x90\xac\x4c\xef\x78\xf4\x58\x0e\x58\xbf\x6a\x0e\x4b\xae\x6f\xa8\xdd\xf0\xc4\x00\x96\x1a\xbf\xbf\xa2\x35\xed\x71\x62\x2b\xf9\xe1\xe7\xae\x8a\xd6\x93\x0c\xb8\x01\x64\x6d\xe3\x2e\xc9\x48\x95\xe9\x00\x27\x75\xb6\xfe\x04\x68\x0d\x69\x2d\x9e\x7c\x7f\x5a\x4b\x97\x63\xf5\xaa\x65\x54\x16\xcc\xf0\x77\xc7\x0d\xef\x8f\x93\x10\x7b\xad\xc7\x49\xc8\xe3\x24\xe4\x71\x12\x32\x97\x37\x1e\x27\x21\x8f\x93\x90\xc7\x49\x88\xdf\x73\x6f\xa4\x7e\x9c\x84\x78\x02\x79\x9c\x84\x2c\x35\x1e\x27\x21\x8f\x93\x90\x50\xf5\x1b\x88\x6d\x76\x70\x7b\x9c\x84\x3c\x4e\x42\x46\xf2\x9b\x9e\x84\x38\x7f\x28\x1c\xbc\xc2\x38\x05\x19\xf6\x02\xba\xec\x54\x51\x87\x72\x3b\xa1\xe8\x72\xc0\xa9\x1a\x6d\x0a\xff\xe5\x9d\x6a\x6b\xb9\xe7\x46\xd0\xd8\x5c\x0c\x63\x26\x1b\xfe\xa8\x6b\x63\x18\x78\x32\x7f\xf3\x1d\xdf\x20\xde\xfe\xc6\xc3\x4a\x4c\x54\x51\x7f\x2d\x93\x0e\x2a\xe7\x65\x22\x4f\x57\x66\x85\x6f\xd8\xdc\x44\xc9\xd2\xf7\x8f\x3c\xfc\xbf\x00\x00\x00\xff\xff\xbe\xff\x80\x0f\x50\x33\x00\x00") + +func fontsTengwarFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTengwarFlf, + "fonts/tengwar.flf", + ) +} + +func fontsTengwarFlf() (*asset, error) { + bytes, err := fontsTengwarFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/tengwar.flf", size: 13136, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTermFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x99\xe9\x9f\x23\x55\xd5\xc7\xdf\x9f\xbf\xe2\x3c\x0f\xcf\x23\x2e\xd3\x4d\x52\xe9\x24\x1d\x45\x3c\xd5\xc9\xed\x74\x31\xe9\xaa\x50\xa9\xcc\x30\xe3\x9a\x49\x57\x4f\xc7\x49\x57\xb5\x49\x1a\x68\x37\xdc\xf7\x7d\xdf\x17\x10\x94\x45\x10\x10\x90\x1d\x15\x01\x11\x65\x13\x04\x59\x44\x59\x45\x94\x4d\x10\x64\xf3\x73\x92\x9b\x99\xba\xa9\x7b\xd3\xbe\x3a\x9d\x53\xdf\x7b\xeb\xde\x73\x7e\x75\xee\xa9\xea\xd5\xee\xaa\xd5\x3a\x11\xb3\x98\xc5\x1c\xce\x64\x31\x9b\xc3\x0c\x66\x20\x08\x7b\xeb\x9d\xa8\xd5\xc5\x7d\x5b\x58\xed\x86\x51\x84\xe5\xb5\xd6\xc6\x46\xd8\xed\xe2\xdc\x11\xa5\x1c\x38\x51\xbb\xbb\xb9\x12\xf6\xb1\xbd\xd6\xea\xb5\xda\x83\xb0\xd7\xc7\xac\x35\x3f\x63\xe5\xf3\x20\xa2\xb5\x56\xd4\x0e\x57\x70\x35\xee\x61\xad\x35\xe8\x44\x33\xd6\x8e\xdc\x8e\x39\x9e\xeb\xe8\x78\x2d\xc2\x72\x7c\x7c\x2b\xc2\x23\xdb\x6c\xa8\xdd\xee\x74\x67\xe3\xde\xfe\xa3\x60\x88\x1e\x9a\x10\xfb\xe1\xa0\x8f\xfd\xcd\x8d\x8d\xb8\x37\x08\x57\x30\x8e\xba\x5b\xd8\x59\xc5\xad\x78\xb3\x87\xfd\x76\x2f\x0c\x23\x5c\x8d\xa3\x01\xae\xc4\x61\x1f\x56\x3b\xfb\xbb\xe1\x00\x7b\x61\x37\x6c\xf5\x43\xb4\x66\x2d\x9c\x99\x41\x37\x3e\x2e\x5c\xdf\x17\xf6\x30\x5b\x2a\x15\xa0\xce\x9b\xea\xf7\x3b\x71\x84\x9d\x3e\xae\x85\xbd\x70\xdf\x16\xee\xef\x1c\x17\x46\x38\x88\x71\x3d\x5e\xe9\xac\x6e\xe1\x60\xad\xd3\x1f\xce\xbb\x03\x5b\x7d\xec\xc6\xd1\x7e\xb6\x83\xb5\x10\x86\x40\x27\xec\x1d\xde\xc7\xa8\xb5\x1e\xf2\x1c\x1b\xdd\x56\x7b\xb8\x34\x6c\x61\x3b\x5e\x5f\x0f\xa3\x01\x76\x3b\x51\x38\x0b\x50\x89\x37\xf7\x75\xc3\x99\xf6\x5a\xd8\x3e\x10\xae\xf0\xde\xeb\xad\xcd\x2e\x2e\x6c\xf6\x06\x71\x84\x47\xf6\xe3\xee\xe6\xa0\x13\x47\x14\xb6\x7a\x83\xb5\x6e\x27\x3a\x30\x1b\x85\x83\xa3\x30\x6b\x1d\x51\x2a\xcc\x22\xda\x2b\x2b\xe1\x0a\xdf\x16\xa3\xf0\x78\xd8\x68\xf5\x5a\xeb\xe1\x30\x28\x07\xe3\xb1\x6f\x0b\x17\x9d\x2a\x6f\xba\x15\xad\xf0\x9f\xbb\x3b\xd1\x2c\x62\x33\xea\x76\x0e\x84\xd8\xea\x76\x31\x1e\xac\x85\x3d\xbe\xc2\xdb\xe9\xef\x18\x6d\x2d\x8e\x42\xe8\xf4\xb1\x13\x0d\xc2\x68\x78\x8b\x18\x37\x7a\xf1\xca\x66\x3b\xc4\x78\x73\xb0\xb1\x39\xc0\xf0\x84\x56\x7b\xd0\xdd\x1a\xde\xbc\xcf\x1b\x1d\xed\x1f\x3b\x11\x5f\xdd\x8c\xba\x61\xbf\x3f\xdc\x6f\x34\xe8\xc5\x5d\x58\xed\x74\x87\xb1\xd8\xec\x87\x2b\xb3\x88\x01\xc7\x75\x35\xee\x85\xd8\x19\x8c\x67\x1e\x8d\x6f\xd8\xcb\x62\x7c\x0f\x96\x46\x7f\x7d\xb3\xbf\xb6\x03\x0f\x84\xbd\x08\xe3\x1e\xae\x76\x06\xb3\x80\x08\x27\x12\xfc\x0f\xc1\xff\x12\x1c\x46\xf0\x7f\x04\xff\x4f\xf0\x0a\x82\xc3\x09\x5e\x49\xf0\x2a\x82\x57\x13\xbc\x86\x60\x07\xc1\x0c\xc1\x2c\xc1\x11\x04\x19\x82\x2c\x81\x45\x90\x23\x98\x23\xc8\x13\x14\x08\x8a\x04\xf3\x04\x25\x82\xd7\x12\xbc\x8e\xe0\x48\x82\xd7\x13\x1c\x45\xf0\x06\x02\x3a\x0c\x6c\x82\x05\x82\x32\x41\x85\x40\x10\x2c\x12\x54\x09\x96\x08\x1c\x82\xa3\x09\x76\x12\xd4\x08\x96\x09\x5c\x02\x8f\xa0\x4e\x70\x0c\x81\x4f\xd0\x20\x08\x08\x9a\x04\xbb\x08\x76\x13\x1c\x4b\xb0\x87\x60\x2f\xc1\x1b\x09\xde\x44\xf0\x66\x82\xb7\x10\xbc\x95\xe0\x6d\x04\x2d\x82\x7d\x04\x6d\x82\x15\x82\x90\x60\x95\x60\x3f\xc1\x1a\x41\x87\xe0\xed\x04\x07\x08\xba\x04\xeb\x04\x11\x41\x4c\xb0\x41\xf0\x0e\x82\x1e\x41\x9f\x60\x40\xb0\x49\x70\x1c\xc1\xf1\x04\x27\x10\x6c\x11\xbc\x93\xe0\x5d\x04\xef\x26\x78\x0f\xc1\x7b\x09\xae\x22\xb8\x8d\xe0\x2e\x82\xfb\x09\x9e\x21\x78\x81\xe0\x4f\x04\x59\x6b\x1e\xde\xc7\xa6\x04\xef\x27\xc8\xe6\x32\xf0\x01\x36\x59\xf8\x20\x1b\x0b\x3e\xc4\x26\x07\x1f\x66\x33\x07\x1f\x61\x93\x87\x8f\xb2\x29\xc0\xc7\xd8\x14\xe1\xe3\x6c\xe6\xe1\x13\x6c\x4a\xf0\x49\x82\xec\x5c\x06\x3e\xc5\x26\x0b\x9f\x66\x63\xc1\x67\xd8\xe4\xe0\xb3\x6c\xe6\xe0\x73\x6c\xf2\xf0\x79\x36\x05\xf8\x02\x9b\x22\x7c\x91\xcd\x3c\x7c\x89\x4d\x09\xbe\x4c\x90\xcd\x67\xe0\x2b\x6c\xb2\xf0\x55\x36\x16\x7c\x8d\x4d\x0e\xbe\xce\x66\x0e\xbe\xc1\x26\x0f\xdf\x64\x53\x80\x6f\xb1\x29\xc2\xb7\xd9\xcc\xc3\x77\xd8\x94\xe0\xbb\x04\xd9\x42\x06\xd1\xf5\x66\x16\x7c\x61\xef\xc4\x46\xdd\x2e\x0b\xf8\x1e\xbb\xb3\x88\x8e\xbb\x4b\xf8\x81\xa8\xa0\x38\xb6\x5c\xb3\x97\xed\xc0\xf1\x5c\x5c\xb6\xfd\x9d\xf0\x7d\x26\x2c\xc4\xb2\x70\x03\x6c\x38\x55\x17\x4e\x62\x4f\x0e\xb1\xee\x35\xdd\xca\xc8\x75\x32\xbb\xe6\x10\xcb\x4d\xdf\x17\x6e\x79\xcf\xc8\xfb\x03\xf6\xe6\x11\xf7\x08\x77\xe4\x38\x85\x1d\x05\xc4\x05\xdf\xdb\x29\x5c\x5c\xb0\x7d\x38\x95\x5d\x45\xc4\x86\x28\x0f\xef\x39\xe4\x7e\xc8\xce\x79\xc4\x8a\x63\x0b\x5f\x34\x9c\x06\xfc\x88\x3d\x25\xc4\xb2\x57\xdf\xe3\x3b\xd5\x25\xb9\x94\xd3\x08\xb2\xc5\x0c\xe2\xa2\x58\x76\x5c\xc7\x15\xe8\xf9\x15\xc7\xb5\x6b\xe8\xb8\x15\xa7\x6c\x07\x9e\x0f\xa7\x33\x92\x45\xac\x89\xc5\x60\xa6\xee\x39\x6e\xe0\xb8\x55\xac\x78\xcd\x85\x9a\x40\xdb\xad\xd6\x04\x1e\xd3\xf4\x82\xc4\x8e\xcf\xe0\x11\x16\x87\x4a\xde\xe5\x4c\x76\xe4\x10\x1b\xde\x62\x80\x4b\x7b\xea\x4b\xc2\x85\x1f\xb3\x6f\x0e\xd1\x17\x55\xa7\x11\x08\x5f\xc8\x48\x9c\xc5\xfe\x3c\xe2\xb2\x5d\xf6\x3d\x17\xce\xe6\x9f\x05\xc4\x8a\xa8\xfa\x42\x8c\x90\x9f\xb0\xaf\x88\x58\xaf\x35\x1b\x33\xcb\x8e\xdb\x6c\x8c\xfc\xe7\xb0\x7f\x1e\xb1\xd1\xac\x0b\xbf\x51\xf6\x9d\x7a\x80\xc1\x6e\x0f\xce\x65\x7f\x69\xc2\xbf\xe4\x0b\x01\xe7\x11\x64\xe7\x33\x88\x76\xb9\x19\x08\xb4\xcb\x9c\x23\xf8\x29\x3b\xb3\x88\xcb\x4e\xd9\xf7\x46\x33\x9f\xcf\x2e\x0b\xb1\xee\xd4\xca\xbe\xb7\x7b\xe4\xbc\x80\x9d\x39\xe6\x2a\x95\x9a\xc0\x8a\x17\xc0\x85\xec\xe2\x34\x8a\x8a\x53\xab\xd9\xf0\x33\xfe\x9d\x57\xef\xec\xb9\x02\x2e\x62\x7f\x81\x37\xd9\x28\x37\x6b\xfa\xb8\x5f\xcc\x4c\x11\x71\x98\xad\xff\x2e\xf0\x97\xf0\x90\x79\xc4\x5d\xcd\x5a\xd5\xf6\x71\xd1\xb7\x47\x9a\xf0\x5c\x46\x6d\x3f\x10\x3e\x5c\xca\x4c\x49\xcf\x2c\xd9\xb5\x45\xb8\x8c\x20\x5b\xca\xa4\x81\x61\xc4\xc6\xd3\x34\xe0\x72\xc6\x92\xc2\x3f\xa6\x29\x1a\x87\x96\x72\x05\x5f\xb6\x10\x6b\x76\xe0\xb8\x58\xb6\xeb\x4e\x60\xd7\xb0\x26\x82\x40\xf8\x68\xe3\x6e\x27\x58\xc2\xaa\x6f\xef\x12\x70\x25\x93\xb9\xe9\xe4\x30\x3f\xf0\x73\x26\xe7\xa6\x93\x65\xc7\x2f\x37\x97\x17\x6b\xe2\x58\xf8\x05\xe3\xf9\xe9\x78\xe0\xd4\x2a\x02\x7e\xc9\x64\x61\x3a\x79\xe8\x51\xba\x8a\xe9\xe2\x74\xda\xe7\x54\xd9\x0b\xde\x2e\x01\xbf\x62\x7c\xde\x84\x0b\xb8\x9a\xaf\x97\x0c\xd7\xcb\x72\x57\x52\x4f\xd7\x10\x58\x99\x8c\x81\x15\xc9\xa8\x5e\xcb\x64\x76\x3a\x39\x8a\xea\xaf\x99\x34\x65\x4a\xa4\xa2\x7a\x1d\xe3\xa6\x74\x89\xc9\x58\xfd\x86\x69\x53\xca\x9c\xe4\x82\xaf\x67\xd2\x94\x2d\x27\xb9\xe0\xdf\x32\x69\xca\x96\x93\x5a\xf0\xef\x18\x37\xa5\xcb\x99\x5c\xf0\x0d\x4c\x9b\xb2\x25\x82\x25\xb8\x91\x01\x53\xba\xdc\xa4\xaa\x6e\x22\xb0\xb2\xa6\x64\x79\xc9\xbd\xdf\xcc\xa4\x29\x59\x5e\x72\xef\xb7\x30\x69\x4a\x96\x97\xda\xfb\xef\x19\x37\x25\xcb\x4b\x2e\xf6\x56\x26\x4d\x89\xf2\x26\xa3\x74\x1b\xd3\x5c\xa4\x9b\xb5\xc0\xa9\xd7\xb8\x62\x1d\x3c\x7b\xfe\xc0\xd7\x4c\xe9\x91\x33\x35\x02\x3e\xc0\xe0\x76\x46\x4d\xa9\x69\x26\x23\x74\x07\x93\xa6\xb4\x34\x93\x11\xfa\x23\x93\xa6\xfc\x34\x53\x11\xba\x93\xc0\xb2\x4c\x49\x6a\x4e\xee\xfb\x2e\xa6\x4d\x89\xda\x93\x5c\xc6\xdd\x4c\x9a\x12\x15\x2c\x79\xbe\x0b\xf7\x30\x72\x30\x39\x8d\x65\xbb\x76\x10\x68\x2c\xd9\x7e\x1d\x1b\xdc\x54\x59\xd6\x9c\x16\x51\x6a\xe8\xbd\xcc\xe5\xa7\x71\xa3\x55\xfd\x99\xb9\xc2\x34\x2e\x11\x9a\xbf\x30\x5c\x9c\x06\x8f\xa4\x73\x1f\x73\xf3\xd3\xb8\x43\x01\xbc\x9f\xd9\xd2\x34\x36\x51\x39\x1f\x20\xb0\x72\x19\x3d\x2c\xe0\x41\xbe\x9a\xd5\x5e\x9d\xa8\x9a\x0f\x31\x69\x69\x49\xa5\x66\x3e\xcc\x9c\x3e\x21\x4a\xc5\xfc\x2b\x73\xfa\xac\xa4\xeb\xe5\x23\x0c\xeb\x53\x93\xaa\x96\x7f\x63\x56\x9f\x1e\xa5\x56\x3e\xca\x9c\x3e\x33\x4a\xa5\xfc\x3b\x73\xfa\xcc\xa4\xeb\xe4\x3f\x18\xd6\xa7\x26\x55\x25\x1f\x23\xb0\xe6\xf4\x99\xe1\x1a\xf9\x38\x5f\xd6\xa7\x46\xa9\x90\x4f\x30\xa7\x4f\x8c\x52\x1f\x9f\x64\x4e\x9f\x18\xa5\x3a\x3e\xc5\x9c\x3e\x31\xe9\xda\xf8\x4f\x86\xf5\x89\x51\x2a\xe3\xd3\xcc\xe9\x93\x92\xaa\x8b\xcf\x30\x5b\xe4\xbe\x7b\x97\xd3\x38\x58\x11\xff\xc5\x5e\x7d\x1a\xd4\x7a\xf8\x2c\x83\xfa\x14\x28\xd5\xf0\x39\x02\x2b\xaf\x0f\xbf\x52\x0b\xff\xcd\x9c\x3e\x0f\xe9\x4a\xf8\x3c\xc3\xfa\x64\xa4\xea\xe0\x0b\xcc\xea\x13\xa2\x54\xc1\x17\x99\xd3\x27\x64\x54\x03\x5f\x62\x40\x9f\x84\x3d\x93\x37\x7d\x99\x20\x73\x42\x26\x6b\xec\x7f\x64\x01\x91\x2f\x0e\x57\x4a\x5a\xbf\x7d\x95\xbd\x57\xb2\xdb\xf4\xab\x0b\xbe\xd8\x35\x6c\x16\x87\xb0\x7e\xfb\x0a\x7a\x9f\x44\xb7\xe9\x59\xbd\xaa\xe7\x8a\xe1\x8b\xe2\x90\x9e\x5a\xc7\x25\x7b\x8e\x64\x4d\xe7\x6c\x39\x99\x85\xab\x25\xac\xaf\x18\x0a\xfa\xa0\x44\x4d\x47\x6d\x39\x25\x9b\xf1\xe4\x7a\xd9\xa6\xf9\xf1\x1d\xec\xe9\x77\xa8\x78\xc1\xa1\xfe\x79\x38\x60\x61\xda\x0d\x0e\xe1\x0f\x48\xbc\xbc\xcd\x0e\x6c\x4e\xfc\xb5\x12\xae\x4c\x5d\xfc\x10\x7d\x58\xa2\xc2\x30\x6f\x25\x09\xdf\x20\xe1\x45\xed\xbc\x0a\xfa\xd8\x08\x35\x36\x8a\x15\xa5\x42\xdc\x28\x69\xbd\xaa\x55\xf6\x71\xc9\x6e\xd3\xdb\xcb\x67\xe0\x74\x49\x4f\x3d\xff\x24\x7b\xb1\x64\x4d\xea\x13\x93\x49\xb9\x5e\x0e\xd0\x2b\x30\x85\x3f\x2a\x71\x63\x1f\xae\x3c\x0b\xd7\x49\x5a\xaf\x40\x95\x7d\x44\xb2\x26\xf5\x89\x64\x6a\xc6\xab\xd6\x2b\x4f\x41\xc7\x2b\x36\xa9\xae\x9a\x7a\x0e\x6e\x97\x23\xf4\xd2\x4b\xf3\xcf\x4a\xde\xa4\xbf\x6a\xb2\xf0\x9c\x21\x61\xbd\xfe\x14\xf4\x92\x11\x6a\xec\x81\xab\x93\xc9\xb9\x55\x0e\xd0\x4b\x30\x85\x3f\x2d\x71\x93\x0a\xab\x6a\xaf\x26\x57\x6e\xe8\x8b\x27\xe0\xf1\xda\x4d\xf5\x75\x29\x15\xc5\x53\xe5\x08\x7d\x8d\x4d\xf3\x17\x48\xde\xa4\xf4\x25\xe5\x89\x93\x15\xdc\xd0\x34\xab\xac\xac\xe0\x96\x49\xe3\x4e\xb2\x07\x39\x45\xc2\x53\xdb\xb3\x11\x7a\xbe\x44\x4d\x0a\x77\x94\x27\x59\x16\x2a\x4b\x2f\x71\x95\x95\x95\xca\x32\x29\xd0\x51\x9e\xb4\x6b\x24\xad\x97\xa0\xca\x3e\x34\x62\x73\x26\x0d\x3a\x93\xa2\x3a\x4d\x0e\x30\x94\x41\x2f\xa8\x89\x46\x03\x1d\xb8\x48\x72\x26\x81\x1c\x9d\x4a\xf8\x99\x72\x84\x5e\x20\x69\xfe\x52\xc9\x9b\x04\xb2\x53\x55\xec\x2d\x12\xd7\x2b\x64\x02\x7e\x4a\xc2\xfa\xd6\x71\xa7\x6f\xc3\x49\x92\x30\xbd\xef\xd6\x92\x67\xbb\x3c\x48\x73\xb6\x76\x3a\x05\x95\x87\x68\x6e\x61\xfa\xbc\xe3\x85\xca\xa7\x2a\x57\x9e\x36\xf3\x18\x96\x8f\x54\xae\xb2\xcd\xdc\xc3\xba\x2a\x85\x9f\x13\x53\x67\x1e\xa2\x52\xf8\x73\xa6\xd7\xf3\x9a\xf2\xf8\x9d\x2c\x69\x7d\xc3\xab\xb2\xe7\x49\xd6\xf4\x21\xc5\x4d\x86\xee\x26\x09\xeb\xbb\x5e\x05\x7d\x42\xa2\xa6\xaf\x5e\xae\x1a\xb8\xf1\xcc\xfa\x77\x91\x09\x78\x3c\xb7\xe9\xeb\x8a\x9b\x0c\xdd\xcd\x12\xd6\x0b\x4d\x41\x9f\x94\xa8\xf1\x00\x75\xab\x70\x99\x64\x0c\xe7\xa6\x5b\x85\x2b\x24\x61\x3a\x2e\x3d\xa5\xf0\x8c\x97\xa7\x3f\x2a\x55\x56\xae\x2f\xbf\xcd\x77\xb7\xf1\x57\xf4\x61\x1e\xe4\x89\x66\x78\x53\xd2\x8d\x90\x87\x5a\xde\x54\x57\xfc\x64\x9a\xe5\x9b\x88\xe1\x35\x47\x41\xe5\x8b\x48\xde\x54\x4d\x7c\x35\xc9\x52\xc4\x79\x7d\x35\x99\x80\xa5\x8a\xf3\xa6\x03\xc7\x4f\xa6\x59\x76\x27\x79\xfd\x81\xa3\xa0\xb2\x31\xc9\x9b\x14\xd1\x48\x6e\x50\x56\x8a\xbc\x5e\x1a\x0a\x2a\xeb\x44\xde\xa4\x91\x46\xaa\x16\xdf\x23\x47\xe8\x75\x92\xe6\x5f\x92\xbc\xe9\x40\x6b\xa8\x01\x94\x1d\x72\x5e\x7f\xa2\x4d\xc0\xb2\x45\x2e\x98\x74\xd8\x48\x86\x50\x1e\x67\x05\xbd\x00\x15\x54\x9e\x68\x05\xe3\xa7\x45\x75\x19\x32\x24\x05\x7d\x3b\x35\x01\xcb\x78\x14\x4c\xaa\x0e\x92\x0b\x91\x8d\x5a\x41\xaf\x6a\x05\x95\x6d\x5a\xc1\xa4\xea\x40\xa9\xb6\xf2\x04\x2e\xe8\x45\xad\xb2\xf2\xf4\x2d\x6c\xf3\x65\x78\xd4\x19\xdd\x2d\xe1\xa9\x1f\x58\x46\xe8\x8b\x12\x35\x69\xba\xa9\xd4\x9c\x71\x90\xf5\xa2\x56\xd9\x71\x8c\x4d\xaa\x6e\x26\x7b\xf3\xf1\x8a\xf5\x82\x56\xd0\xf1\x8a\x4d\x5a\x6e\xa6\xbe\xae\xde\x21\x47\xe8\xe5\x9c\xe6\x9f\x1b\xf1\xc5\xed\x3e\x96\x27\xeb\xe4\x9d\x72\xcc\xd4\x6f\x50\xca\x88\xe7\xe5\x08\x93\xbe\x9b\x4a\xe3\x28\xf7\x50\xd4\xcb\x5b\x65\xc7\xeb\x37\xf5\x4a\x7b\x93\xc5\x47\x8a\xb0\xa8\xef\x95\x14\x54\x6a\xb0\x68\xea\x95\xf6\x4e\x36\xaf\x67\xcb\x01\xfa\x6e\x29\x85\xcb\xb3\xb2\x68\xea\x97\xf6\x26\x1f\xb5\xb3\x24\xac\xef\x97\x14\xf4\xf2\x21\x6a\x95\x8b\x28\x1d\x17\x8e\x1c\x95\x79\x94\x9a\x3a\x49\x3a\x4a\x98\x58\xce\xcb\xd2\xb9\x80\xe3\xc0\x9e\x2b\x3d\x15\x54\x52\x39\xfe\x77\xfa\x65\x04\xff\x09\x00\x00\xff\xff\x17\x87\xd5\xd4\xdd\x25\x00\x00") + +func fontsTermFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTermFlf, + "fonts/term.flf", + ) +} + +func fontsTermFlf() (*asset, error) { + bytes, err := fontsTermFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/term.flf", size: 9693, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsThickFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\x4d\x6f\xe3\x36\x10\xbd\xeb\x57\x3c\x08\x02\xbc\x8b\x26\x6a\x92\xda\xc0\x64\x4f\x2e\xd0\xf6\x52\x14\x10\x8a\x5e\x74\x33\x65\xd2\xb6\x10\x59\x5a\x58\x32\x98\xfd\xf7\x05\x39\xa4\x44\xca\x8a\x77\x7b\xe8\x62\xa3\x2f\xce\x3c\xbe\x99\x79\x1c\xd2\x87\xe6\xf0\x22\x32\x6c\xb0\xc6\xf3\x06\x4f\x78\x5e\x27\xff\x9c\xea\xfd\x1b\xaa\x6f\xf8\x5b\xb4\x52\x34\x8d\xb9\xf7\xdd\x19\x2f\x3f\xbf\xae\x93\x3f\xea\x63\xa3\x06\x5c\x54\xa3\x44\xaf\xf0\x92\x3f\xe1\xf1\x11\xbf\x5e\x8f\xd7\x7e\xc0\xe6\x01\xcf\xaf\xaf\xbf\x24\xbf\x89\x41\x7d\xc1\x06\x7f\x89\x8b\xf9\xb0\x4e\x92\xdf\xdf\xbf\x36\xa2\x15\x43\xdd\xb5\xe8\x0e\x38\xd4\x97\x7e\x40\x53\xb7\xea\x4b\x62\x18\xe0\x11\xe9\x59\x1c\xeb\x3d\xda\xeb\xb9\x52\x97\x14\x87\xee\x82\x43\xdd\x28\xd4\x52\xb5\x43\x7d\xa8\xf7\xd6\x39\x11\x00\xf0\x88\xfe\xd4\x5d\x1b\x09\xd1\x68\xf1\xad\x47\xa5\xb0\x13\xab\x07\xeb\xd4\x76\x3a\xc9\xd8\x68\x38\x29\xa4\x27\x71\x91\x55\x23\xda\xb7\xd4\x10\xfd\x7a\xa9\xdb\xa1\x87\xe8\x21\x60\xbf\x3e\xa0\xba\x0e\xd8\x8b\x76\x35\x18\x98\xfe\x7c\xed\x4f\x4a\x26\x1b\x46\x38\xa9\xfa\x78\x1a\x0c\x63\x81\xfd\x49\x5c\xc4\x7e\x50\x97\x64\x7d\x67\xf0\x01\x6d\x37\xa0\x6e\xf7\xcd\x55\xd6\xed\x11\x52\xf5\x7b\xd5\x4a\x75\xe9\x93\xe7\x8d\x75\x3b\x8b\x77\x1b\x39\x1a\xd5\x1e\x87\x13\x3e\xa9\x77\x6f\xbc\xef\xce\x67\xd5\x72\x62\xfa\xcf\xf8\x09\x02\x87\xab\x3c\x2a\x1c\xc4\x7e\xe8\x2e\xc9\x13\x4f\x2c\xd5\x41\x5c\x9b\x81\xc9\x9e\x3b\xa9\x6c\xe0\xc3\xa9\xee\x71\xe8\xda\x01\x9f\x9a\xfa\x4d\x21\x7d\x3c\xe3\x29\x45\xd7\x5a\x58\xd1\x4a\x0b\xfb\x39\x79\x5e\x5b\x10\x4e\xb4\x61\x1f\xcd\x9a\x24\x59\x96\x6d\x97\x2e\xdb\x84\x32\xfe\x4b\xb3\x6d\xa2\xed\xd7\xed\x36\xd1\x30\x8f\x29\xcc\xc7\x0c\x59\x7c\xdd\x26\x20\x80\x60\x1c\x48\x6b\xd2\xe1\xc3\x38\x04\xfb\xcf\x58\xe7\x9a\x74\x6e\xe0\x34\x59\x40\x80\x34\xf8\x5d\xf3\x7b\xca\x86\x1d\x20\x0b\xfb\x41\x16\x16\x42\x16\x66\x20\x31\xb7\xce\x43\x1a\x43\x59\x90\xb1\x2b\x2b\xad\xdd\xb0\x7d\xa3\xca\xa1\x59\x8e\x66\x28\x4f\x17\x22\xce\xed\x24\x64\xa7\x20\xeb\x4a\x95\xb9\xae\xca\xca\x0c\x97\x95\x21\x8b\x92\x98\xaa\xe5\x41\x76\x9a\x15\x0f\x3b\x96\xba\xac\x64\xa1\x99\x66\x59\x79\x9e\x65\x15\xc5\xee\x1e\x0c\x90\xbd\x9b\x2c\xe9\xe0\x7d\x34\x9c\xd7\xc6\xb3\x37\x39\x77\xa9\xb7\x37\xad\xad\x7f\xf4\xd1\x16\x6d\xfc\x1b\x8b\x88\x3b\xe9\x8c\xe6\xce\x25\x91\x0d\x9a\x4c\x00\xc4\x09\xe1\xa0\x77\x25\x91\x89\x3b\x08\xc9\x7e\xc7\xec\xe2\x46\x6c\x05\x52\x37\x2d\xcf\x2a\x89\xc8\xf9\x07\x36\xd0\x9a\xa9\x59\x77\x33\x49\x60\xe3\xe6\x86\x2c\x38\xef\x9a\x26\x53\x6f\x43\x0c\x4b\xda\x4a\x0b\xd8\x2d\xe1\x98\xc9\x6c\x7d\x0b\xcd\x76\xf7\xe2\x32\x88\x3f\x98\xae\x82\x35\x62\xf4\x67\x43\x95\x45\x9a\xda\xc2\xef\x8c\x26\x62\xd8\xdc\x45\x4c\x2e\x80\x1d\xe9\x31\x21\x14\x2b\x60\xac\x5d\x50\xc3\x2c\x73\x52\x9e\x9e\x58\x16\x88\xb3\x5c\x31\x47\x16\x22\xcb\x70\xae\x99\x65\xe9\x94\x33\x4f\x59\x05\xa8\x85\x5f\x6f\x1c\x5e\xea\x2b\xe3\x53\x04\x1d\xa7\x46\xa6\x69\x9a\x1a\xcb\x02\x45\x69\xc3\xab\x50\x49\xed\x17\xab\x5e\xcd\x17\x87\xe1\xed\xe6\x2d\x3c\x13\x59\x68\x3d\x2d\xa8\x68\x49\x8d\x95\x62\xb9\x6a\x56\x91\x49\xad\x4d\x71\x58\xd3\x28\xf7\xae\x84\xe4\x66\xdb\x05\x42\x89\x11\x5d\x51\xc6\xfb\x1c\x71\x92\x9d\x76\x66\xd9\xf8\xf1\xbe\xcd\x24\xa2\x91\x19\x4b\x13\xce\xee\x9e\x34\x3d\x1d\xad\x35\x2d\xd0\x0c\xe9\x71\x0f\x1e\xaf\x23\x35\xee\xdb\xe3\x2b\xb7\x6f\x77\xdf\x95\x3a\x8d\xea\x48\x4e\x5d\xa4\xb9\xd0\x44\x5c\x10\x0a\xab\xe1\x99\xdd\x04\x39\xcf\x87\xc9\xba\x0d\x8d\xca\xea\xcc\x8b\x9a\x6c\xd3\xf7\x31\x04\x51\x4c\x2e\xde\xc1\x9b\x2f\x06\xfc\xdf\x5a\x57\x50\xe6\xdc\xe5\xd3\x5a\x10\x7e\xa4\x23\xea\x09\x56\x7f\x0f\xf6\xcf\xd5\x52\xb6\x46\xd8\xd2\x37\x24\xe0\x7e\x43\xa2\x68\xaf\x98\xdf\x83\x22\x4c\xb9\x64\xb6\x79\xfe\x11\xac\x59\x66\xbe\x79\xf0\x66\xe6\x5b\x86\x6b\x78\x66\xc9\x85\x3d\x2f\xf2\x9b\xf9\xce\xfc\xe7\x18\x73\x9c\x10\xcb\xa3\x8c\xdd\xf6\xc3\x4d\x74\xc1\xda\x22\x73\x2e\x82\x64\xdc\xef\xe3\x81\x2c\x9d\xa1\x4d\x59\x7c\xa1\x31\x54\x1f\xa3\x0b\xce\x47\x55\xdd\x40\xcc\xf6\x42\x86\xb8\x8d\xc7\x9e\x5f\xb3\xa5\x87\xf9\x1e\xbf\xb4\xd5\x9b\xc5\x6a\x3a\x70\xbe\x70\xa0\x71\xea\x35\xea\x62\x11\xf8\xca\x87\x8b\xd0\x2f\x4d\xaf\x54\xa6\x3a\x6a\x23\xc6\xa9\xa6\xc5\xbc\x2b\x67\x7b\xb3\xf5\xbc\x3b\x17\x02\x42\x16\x29\xe7\x4d\xf1\xa6\xed\x82\x67\x02\xad\xfc\x61\xd2\x9d\x20\x17\x49\xdd\x4e\xc8\xdb\xef\xb4\x7e\x49\x8e\xab\xb6\x5c\x6c\x17\xda\xed\xad\xfe\xd0\xeb\x66\xe0\xe5\xac\xa7\x03\x9f\xbd\x06\xe0\x2e\x08\x4e\x20\x8b\x65\x14\x42\x78\x88\x9e\xe1\x8e\x8a\x67\x66\x21\xbb\x90\x61\xdc\xff\xe2\x1c\x7e\x37\xa4\x20\xd9\x6c\xb8\xe2\x26\x64\xea\xb6\x9a\x1b\x7e\xa4\x00\x5a\xa8\x9c\x6b\xe8\xe4\x37\x4c\x57\x14\x2a\x42\x30\x39\xee\xaf\xb7\x7b\x9c\xb3\x71\x22\xd8\xb9\x33\xd3\xec\x88\xc6\x07\x88\x59\xe9\x6f\x24\x37\xc2\xbb\x56\xec\x7b\x5b\x71\x9b\x0a\xfe\x29\x70\xa7\x61\xc4\xd6\xa1\x47\xe4\x15\x7b\x46\xde\x73\x62\x65\xe5\xfc\x76\x94\xbb\x25\x1f\xb7\x89\xbb\xc4\x7c\xc7\x74\xe7\xcc\xa0\x50\xf4\xf1\x31\x1a\xac\x46\xf0\xaf\x18\xbd\x62\x08\xd6\x26\xdc\x0f\x99\xb9\x28\x5d\x6b\xcb\x5d\x8a\x79\xf6\x1d\xff\x82\x21\xe6\xbd\xc2\xd4\xbb\xe0\x8e\xb6\x08\xb8\x4e\x09\xfb\xe0\x79\x9b\x64\xd1\xff\xff\xff\xfd\xdf\x00\x00\x00\xff\xff\xc0\xc7\x94\x97\xec\x10\x00\x00") + +func fontsThickFlfBytes() ([]byte, error) { + return bindataRead( + _fontsThickFlf, + "fonts/thick.flf", + ) +} + +func fontsThickFlf() (*asset, error) { + bytes, err := fontsThickFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/thick.flf", size: 4332, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsThinFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\xfd\x6e\xab\x36\x1c\xfd\xdf\x4f\x71\x14\x5d\x89\x76\xc5\xa0\x74\xea\xd5\x5d\x35\x4d\x68\xd2\xa6\xbd\xc1\xfe\x41\x0b\x0e\x98\x04\x95\xe0\x0a\x88\xda\x3b\xf1\xf0\x93\x3f\x30\x0e\x98\x24\xd3\x26\x05\x9b\x8f\xe3\xe3\xdf\x97\x8f\x9d\xb2\x2e\x9f\xd9\x17\x7c\xc5\x0b\xbe\x81\x6e\xb1\x7d\x26\xbf\xb2\x8e\x17\x10\x0d\x18\x6a\xf1\xc1\xdb\x9c\x75\x1c\xa5\x68\x7a\xbc\x8b\xae\xe7\x05\xf6\xdf\xd1\x8a\x3d\x6f\xfb\x24\xef\xa2\x9c\xd5\x3d\xcf\x8f\x11\x2f\xce\xe4\xf7\xea\x50\xf3\xbe\xfa\x5b\x63\xfe\xe4\x4d\xc1\xeb\x1a\x7f\x54\xf9\x1b\x6f\xb0\xdd\xc6\x3f\xfd\x88\x87\x8f\xa3\x7a\x4c\xde\x59\xcb\x3a\x51\xf6\x51\x2e\x4e\x8f\xe4\xb7\xcf\xf7\x9a\x35\xac\xaf\x44\x03\x51\xa2\xac\xda\xae\x47\x5d\x35\xfc\x95\x48\x0b\x41\xb1\x39\xb1\x43\x95\xa3\x39\x9f\xf6\xbc\xdd\xa0\x14\x2d\xca\xaa\xe6\xa8\x0a\xde\xf4\x55\x59\xe5\x6a\x30\x61\x00\x40\xd1\x1d\xc5\xb9\x2e\xc0\xea\x0f\xf6\xbd\xc3\x9e\x23\x63\x41\xa8\x06\x35\xe2\x83\x7c\xd1\xa0\xfe\xc8\xb1\x39\xb2\xb6\xd8\xd7\xac\x79\xdb\x80\x52\xbc\xb7\x55\xd3\x77\x60\x1d\x18\xd4\xdb\x10\xfb\x73\x8f\x9c\x35\x41\x2f\x69\xba\xd3\xb9\x3b\xf2\x82\x7c\xd5\x0c\x47\x5e\x1d\x8e\xbd\xb4\x98\x21\x3f\xb2\x96\xe5\x3d\x6f\xc9\xcb\x95\x8f\x21\x1a\xd1\xa3\x6a\xf2\xfa\x5c\x54\xcd\x01\x05\xef\x72\x19\xa7\xb6\x23\xdf\xf4\xb0\x13\xfb\x54\x9e\xa3\xe6\xcd\xa1\x3f\xe2\x81\x7f\x8e\xe0\x5c\x9c\x4e\xbc\xd1\x81\xe9\x1e\xf1\x04\x86\xf2\x5c\x1c\x38\x4a\x96\xf7\xa2\x25\x74\xab\x18\x0a\x5e\xb2\x73\xdd\x6b\x63\x4f\xa2\xe0\xca\xf1\xfe\x58\x75\x3a\x8d\x0f\x75\xf5\xc6\xb1\xa1\x27\x6c\x5f\x36\x32\xd1\x92\x97\x35\x85\xe2\x7d\x24\xdb\x67\xc5\xa2\x23\x2d\xcd\xbf\x98\x96\x10\x69\x66\x72\xbd\x4d\x08\x12\x32\xa8\x1f\x12\x22\x64\xab\xbe\x24\x64\xc0\x90\x90\x0c\x99\x79\xb4\x8d\x1e\x28\x1f\x22\x44\x48\x08\x7d\xa2\x4f\xd4\x76\xc8\x90\x61\x84\xc8\x3e\x94\xd0\x90\x0e\x34\x4a\x48\xa6\x3b\x40\x73\xd3\x81\x06\xf2\x29\xb3\xac\x09\x11\x40\x2c\xef\x63\x49\x12\xcb\x37\x31\x20\x26\x63\x27\xd3\x65\x17\x52\x69\x01\x86\xdd\xb0\x53\x2f\x87\x8b\xa9\xe5\x97\x84\x04\x30\xf7\xfa\x32\x37\xb1\x74\x70\xba\x90\x9a\x0f\xa9\x19\x35\x5e\xb1\x8d\x87\x6a\xa2\x21\x4a\x08\xfd\x81\x26\x24\x18\x32\x37\x1e\xb6\x1d\xa0\x63\x62\xef\xe1\x01\x2d\x06\x04\x16\xe4\x36\x94\xd2\xcb\xc0\x3b\xbf\x29\x55\xfa\xf3\x32\x6a\xf3\xb9\x43\x2a\x83\x3f\x40\xba\xa5\xdb\x8c\xea\x04\x38\x73\x07\x83\xca\x8f\x6d\x66\x4e\x6a\x8e\x50\x8d\x1b\xd4\x9b\x39\x87\x05\x01\x74\xd0\x49\xf1\x82\xac\x05\x16\x84\x71\xb6\x09\x44\xa9\x2e\x1b\xcd\xb7\xc2\x64\xfc\x72\xbc\xf3\x80\xe8\xc8\x11\xeb\xfa\x9b\x5a\x9f\x77\xd7\x98\xf4\xe7\x6c\xb7\x73\x0d\x0f\xdc\xe5\x34\x66\x67\xca\x91\xb9\xc4\x45\x55\x4e\x95\x18\x8f\x85\x97\xda\x12\xbd\x28\x81\x45\x1d\xb8\x78\x33\xde\x5d\x1e\xe1\xe8\x6d\xa8\xad\x37\x75\x28\x70\xb1\x3c\x5c\xe8\x00\xb1\x8b\x75\x4a\x75\x4e\x47\xb7\x3d\x50\xaa\x72\x36\x98\x7c\x4c\xce\xfb\xa1\xd1\x04\xbd\xca\x6a\xab\xe2\xaa\x01\x11\x2c\xdd\xc4\x1a\xac\xbb\x45\x29\xbd\x83\x55\x41\x77\xbb\xc8\x81\xba\x3a\xe3\xb1\x75\x77\xcb\xad\xd1\xc8\xab\xc1\x1a\x95\x57\x7e\x9a\x96\xb3\x99\x77\x98\x77\xeb\x13\xc5\xca\xfc\x58\x3f\xa5\xc6\xfc\xcc\x0b\x5d\x74\x6b\x41\x89\xb4\xa7\x83\x0e\xb5\xd9\x0c\x02\x5f\xae\x01\x48\x68\x6a\xb2\x92\x1a\x4f\xb3\xab\xb9\x1e\xee\x2c\x0b\x6a\xa5\xe6\x8e\xac\xcc\x58\xd3\xdb\xac\xeb\xc1\x0a\xad\xf6\x18\xe1\x58\xb7\x95\xd2\x48\x2f\x50\xb3\xce\x4c\x97\x79\x6c\x8d\x4c\xb0\x6e\x46\xc0\x60\x11\x1a\xe7\x65\x19\xa4\x46\xe0\x91\x05\x96\xfa\x82\x3b\xc2\x32\x67\x34\x98\x73\x2b\xe6\x30\x21\xf8\xe5\x67\xab\xc3\xc1\x5c\x7b\x9d\xc4\xce\x8c\x74\xbc\xbb\x08\x96\x64\x8c\xd4\x5a\x5c\xab\x2c\x89\xd3\xdb\xed\xab\xd9\x76\x33\x6a\x6d\x4a\x75\x6a\x53\xcd\x9e\x6a\xff\x52\xc7\xa6\x84\xa8\x44\xc8\x40\xbc\xea\x9e\x06\x56\x2a\x23\xb5\xe5\xa5\xf3\x1d\x74\xfe\x3c\x13\x56\x4d\xab\xb6\x81\x2c\x99\x1f\x12\xdc\x83\x86\x29\x86\x50\xaf\x66\xe9\xd8\x5f\xab\xab\xeb\x0e\xcd\xf3\x4a\xdf\x3a\x74\xb0\x33\xff\x1b\x56\x8d\xf9\xcf\x9a\xe7\x5d\x64\xd9\x14\x88\xe0\x56\x04\x16\x9a\x27\x12\x12\xad\x68\x9e\x39\xe8\x45\x7e\xe9\x5b\x4c\xf4\xff\x6a\x9e\x57\xfa\xfc\x9a\xe7\x0f\x8a\x77\x2b\x5c\x8d\xdf\x9d\xd0\x0b\x05\xbc\x2b\x2b\x3a\x66\x37\x8a\xed\x8e\x5c\x67\x53\xe7\xdf\x76\x70\xdf\x06\x6b\xe5\xc9\x2b\x27\x97\x9a\x07\x07\xac\x34\xea\x86\xe6\x59\xb8\x2b\x7d\x5e\xcd\xc3\x42\xf9\x7c\x9a\x37\x46\x60\x61\xeb\xb2\x08\x9d\x60\x4d\xd2\x17\x2c\xdc\x52\xff\x52\xd4\x31\x3f\x21\xf4\x15\xe6\x0e\x5a\xf9\x9c\x03\xc0\xe0\xfc\xf5\x32\xff\x6a\x64\xf3\x6a\xc7\x06\xae\x99\x3b\xd5\xc5\x48\x77\xf1\xdc\x20\x3b\xb7\x80\xb8\xf7\xd4\x76\x09\xbd\xba\x39\x69\xe8\xdd\xfb\xd8\x9c\xfc\xaa\x84\x7a\xed\xb8\xca\x7a\xbb\xa8\x56\x0e\xa3\xb3\x65\xf5\x4f\x00\x00\x00\xff\xff\xe8\x6e\xdc\x71\x5d\x11\x00\x00") + +func fontsThinFlfBytes() ([]byte, error) { + return bindataRead( + _fontsThinFlf, + "fonts/thin.flf", + ) +} + +func fontsThinFlf() (*asset, error) { + bytes, err := fontsThinFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/thin.flf", size: 4445, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsThreepointFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x54\xcf\x6b\xe3\x38\x14\xbe\xeb\xaf\xf8\x26\x18\x92\xd0\xc4\x6a\xda\xec\xa1\x43\x29\x1a\xd8\xdd\x53\x4f\x7b\x18\x72\x30\x28\x8a\x2d\xc7\x66\x1c\xb9\xd8\x32\xd3\x01\x91\xbf\x7d\x79\x92\xad\x38\x7b\x58\x18\x8a\x1b\xbf\x5f\xdf\xfb\xde\xfb\x24\x97\x4d\xf9\xa4\x12\x3c\xe3\x09\xbb\x1d\x1e\xb1\xdb\x33\x5b\x75\x5a\x7f\xb4\xb5\xb1\x38\xfd\xc2\x3f\xca\x14\xaa\x69\xe8\xb7\x6f\x2f\xd8\xf3\x97\x3d\x5e\x3b\x6f\x88\x73\xdd\x59\x75\x4a\x87\x3e\x4f\x75\x31\xbc\xb1\xbf\xeb\x73\xa3\x2d\x3a\xdd\x68\xd5\x6b\x3c\xa5\x8f\xd8\x6e\xf1\x6d\x38\x0f\xbd\xc5\x1f\x1b\xec\x5e\x5e\x9e\xd9\x9f\xca\xea\xaf\x78\xc1\xb7\x8f\x8e\x1c\x7b\xc6\xfe\xfa\xfc\x68\x94\x51\xb6\x6e\x0d\xda\x12\x65\xdd\xf5\x16\x4d\x6d\xf4\x57\x46\xf4\xb0\xc5\xe2\xa2\xce\x75\x0e\x33\x5c\x4e\xba\x5b\xa0\x6c\x3b\x94\x75\xa3\x51\x17\xda\xd8\xba\xac\x73\x5f\xcc\x14\x00\x6c\xd1\x57\xed\xd0\x14\x50\xcd\x4f\xf5\xab\xc7\x49\xe3\xa8\x96\x1b\x5f\x64\xda\x9f\x2c\x09\x49\xb6\xd2\x58\x54\xaa\x2b\x4e\x8d\x32\x3f\x16\x44\xf4\xa3\xab\x8d\xed\xa1\x7a\x28\x78\xef\x06\xa7\xc1\x22\x57\x66\x69\x09\xa6\xbf\x0c\x7d\xa5\x0b\xf6\x1c\x10\x2a\x5d\x9f\x2b\x4b\x8c\x15\xf2\x4a\x75\x2a\xb7\xba\x63\x4f\xff\x13\xdc\xc0\xb4\x16\xb5\xc9\x9b\xa1\xa8\xcd\x19\x85\xee\x73\x6d\x0a\xdd\xf5\x6c\xb7\xf3\x65\x17\xf5\xe9\x27\x47\xa3\xcd\xd9\x56\x58\xe9\xcf\x29\x39\x6f\x2f\x17\x6d\xc2\x62\xfa\x35\x1e\xa0\x50\x0e\xc5\x59\xa3\x54\xb9\x6d\x3b\xf6\x18\x1a\x17\xba\x54\x43\x63\x03\xd9\x4b\x5b\x68\x3f\xb8\xad\xea\x1e\x65\x6b\x2c\x56\x4d\xfd\x43\x63\xb1\xbd\xe0\x71\x81\xd6\x78\x58\x65\x0a\x0f\xbb\x66\xbb\xbd\x07\x09\x8b\x26\xf6\x77\x5d\x19\x4b\x12\x31\x3d\x82\x39\xc1\x52\xc1\xe8\x6d\xb9\x9c\xb9\x1f\x1e\xc2\xe3\x8d\x95\xbb\x0a\x26\xdd\x5a\xb0\x04\x3e\x93\x0b\xc6\x37\x53\x70\x0d\xc1\x56\xf2\x10\x83\x84\xe6\x01\xc1\x05\x73\x10\x0c\x99\x10\x2c\xa3\x17\x27\x18\x87\x10\x2c\xc5\x46\xb0\xed\x61\x2b\xd8\x12\x47\x41\xd8\x52\x30\x7c\xc1\x84\x91\x08\xb6\x09\x18\x52\xce\x48\x25\x91\x2b\x41\x73\x8c\x6e\x7e\x10\xec\xc0\x05\x03\x41\x2f\xa9\x63\xea\x52\x32\xbd\x7d\x5d\x53\xba\xbc\xb3\x53\xb9\x9e\x6c\x27\x1d\xbd\xba\xc9\x7e\xa7\x51\xd7\x23\x18\xb8\x9f\x2d\x26\x5f\xc7\xb6\xde\x58\x11\xd2\x2c\xb8\x0a\x9d\x30\xd9\x69\x64\x9b\xc6\x71\x88\xf7\x6a\x5a\xc9\x76\x1b\x1e\x9f\xed\xf7\xb3\x1e\xf7\x13\x48\x7f\x89\x50\x09\xbf\x5e\x33\x5a\xe6\xca\x71\xc1\x92\x4c\xca\xc0\x8e\x8a\x42\x08\xe3\x34\x54\xe8\x6e\x9c\xf8\xf5\x28\x58\x26\x37\x71\x5a\x0f\x23\xf9\x8d\x33\x8d\x30\x52\x20\x95\xe9\x19\x2b\x25\x55\xf2\xbb\x3d\xb9\xdb\x9e\xae\xe1\x4c\xc8\x3b\xfb\xdd\x45\xca\x44\xd4\x65\x13\x32\x08\x60\x32\x32\xee\xa1\x46\xac\xe0\x82\x77\x65\x37\x17\x27\xa6\xf3\xfe\x7e\xb2\x2b\x6e\x93\xf9\xf8\xe1\x3f\xf1\x6c\x3e\x59\xd4\xd1\x93\xc3\x8c\x9c\x6f\x27\xe3\x30\x19\x48\x18\x64\xa3\x78\xa3\x6b\x72\x46\x77\x08\xd0\x19\xc8\xa2\x6a\xfc\x0e\xd8\x1f\x90\xbb\x7d\x86\xc9\x47\x7d\xb3\xc8\x27\x5c\x06\xe9\x48\xec\xe3\xfc\x88\x27\xf1\xcc\x0b\x76\x8c\x57\x29\x91\x09\x09\xe5\x6e\x6a\x24\x77\x3a\x27\x72\xa6\x63\x42\x79\xb3\xe4\x50\x7c\xbb\x02\x70\xc7\x69\x25\xb3\xb8\xcf\xf7\x84\x02\xf8\x4d\xea\xd4\x7f\x25\x7c\x65\x1a\x78\xbf\xbb\x49\xd4\xd7\x69\xd6\x98\x93\x48\x8c\xf5\x93\xc0\xb1\xc7\x0c\x73\xec\xb9\xbe\xb3\xfd\x40\x6e\xb2\xfd\xd5\x0b\xab\x75\x7c\x9c\xd1\x21\xce\x28\x98\x9c\xd6\x19\x8e\xe1\x4d\x05\xfa\x3f\x97\x97\xcc\x6c\xfa\x40\x90\xf1\xfd\xfb\xcc\x78\x7b\x9d\x19\x19\x1f\xaf\x20\xf1\x89\x4a\x82\x96\xf5\x0a\xff\x09\x93\x71\x5a\xe7\x95\xf4\x5d\xdf\x88\x84\xbf\xb9\xc7\x65\xf8\x88\x8d\x5f\x32\xff\xf7\x3b\x3f\xff\x06\x00\x00\xff\xff\x14\xc8\xd7\xe6\xcc\x07\x00\x00") + +func fontsThreepointFlfBytes() ([]byte, error) { + return bindataRead( + _fontsThreepointFlf, + "fonts/threepoint.flf", + ) +} + +func fontsThreepointFlf() (*asset, error) { + bytes, err := fontsThreepointFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/threepoint.flf", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTicksFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\xcd\x6e\xdb\x38\x10\xbe\xeb\x29\x06\xc2\x02\x4e\x0e\x2b\x39\xde\xec\x02\xbe\x79\xdb\x6b\xd1\xf6\xd0\xf6\x14\x60\xa0\xd8\x52\x2b\xd4\x91\x02\x4b\x6e\x91\x4b\x9e\xbd\xa8\x61\x5b\x1c\xce\x0f\x29\xcb\x0d\x10\x4b\x14\xc9\xf9\xfd\xbe\xe1\xb0\xda\x56\x8b\xe2\x2f\xf8\x0f\xfe\x85\xc5\x1c\xe6\xb0\x84\x79\x92\xf4\xf5\xfa\x7b\x97\x55\xdb\x0a\x6e\xde\xde\xc2\xdd\x72\x79\x0f\x8f\x2f\xf0\xa5\x5e\xf7\xed\x0e\x3e\x16\xbb\x62\x53\xc0\xcd\x8f\xe7\xc3\xcb\xaa\x6e\xaa\x6c\xdf\x57\xdd\x53\xb6\xde\xde\xc2\xf2\x3e\x9f\x2f\xf3\xc5\x3f\x59\x92\x54\xf5\xd7\x6d\xd9\xc3\x22\xbb\x83\xaa\x6d\x7a\x78\x2c\xba\x72\x03\x6d\x03\xdd\xb6\xde\x94\xbf\xc5\x67\x49\xf2\x69\xf7\x02\xed\x73\x5f\xb7\x0d\xa4\x7f\x3f\xc1\x5d\x0a\x7d\x0b\xdd\xd3\xbe\xfb\x06\x6d\x53\x42\x8a\x29\x3c\x96\xfd\xcf\xb2\x6c\x0e\x42\xba\x2c\x49\xde\x15\x7d\x7d\x1c\x41\x31\x83\x72\x06\xf5\x0c\xda\x19\xec\x67\xd0\xbc\x42\xd1\x6c\xe0\xfd\x2b\xec\xca\xe7\x6d\xb1\x2e\x3b\xf8\x3f\x85\x0f\x29\x7c\x4e\xa1\x48\xa1\x4d\x61\x9f\x1e\x56\xbc\xc9\x92\x04\x11\x71\x65\xff\xae\x12\xcc\x1f\xf2\x07\x14\x9e\x78\x5c\x46\xc7\xc7\x0f\xee\xe2\xe1\x1d\x0f\xff\xe7\xc5\x68\xbd\x1f\x06\x87\xad\xc7\x5f\x57\xdc\x20\xf4\xb2\x35\xde\xdf\xea\xf8\xe9\xb8\x00\x87\x4d\x82\x27\x8e\xa5\xd2\xbc\xab\x62\x58\x7f\x8a\xd3\xe9\xe3\x79\xac\x6d\xf0\xac\x16\xf6\xdb\x1e\x70\x91\xc4\x2b\x45\xac\xb2\x46\x08\x17\x47\x85\x13\x59\xf6\x74\xa5\x9e\x63\xe5\xc0\x07\xdd\xd4\x79\x56\xf8\xa8\xb0\x16\xd1\x8c\x73\x65\x01\x78\xa1\xe3\xbb\x0e\x26\x7f\x4d\x34\xbc\x86\x0f\x3c\xdb\x9a\x1a\x12\x47\x6f\x3f\x57\x20\x3c\xe5\x44\x19\x14\xf4\xad\x90\xd6\x5c\xa4\x99\xc5\x82\x6a\x09\x33\x81\x08\xb6\x63\x41\xb9\xa8\x53\x8f\x42\xc4\x87\x8f\x98\x4f\x07\x3a\xc3\x56\xf2\x4d\x7e\x3b\x6f\x96\x2a\x05\x0a\xe0\x65\x0c\x41\x1d\x2a\x38\x45\x81\x3f\xaf\xed\x27\x09\x94\x68\x48\x2d\xce\xc5\x92\xac\x25\x5c\xf1\x80\x16\x29\x1e\x82\x8b\x3d\x88\x8d\xb1\x8c\xa0\x20\x42\x62\x5c\xfe\xa3\x18\x1f\x3b\x3f\x41\x01\x85\xe1\xa8\x10\x59\x0d\x45\x2e\x35\x16\x31\x1b\x48\x89\xf3\xa8\xc8\xce\x1c\x31\x29\x62\x89\x43\xbb\x3e\x6a\xdf\xb9\xcf\x41\xcd\x9a\xa5\x22\xbe\x34\x8e\xfb\x14\x45\x66\x95\x28\xdc\x4e\xbf\x4f\x49\x9d\xa2\x11\xf8\xd2\x1a\x2e\xbd\x68\x4b\x35\x81\xc5\x5c\x0b\x91\x2e\x30\x6e\xde\x08\x91\x5e\xa5\xac\xb1\xc6\xa0\x51\x1e\x84\xc6\x41\x0a\x52\x0f\x28\x4a\x34\x03\xf8\x7c\xd0\x83\xb8\x42\x1e\x0e\xd9\x45\x39\xb0\x50\x13\xe1\x41\x5c\x8c\xe3\x72\xa2\x86\x88\x97\x04\xf9\x5d\xb4\x56\x6f\xab\xf4\xb1\x1e\x0a\xab\x60\x1b\x37\x18\x67\xbb\xda\x06\x04\x43\x21\xe6\x3e\x62\x24\xa6\x90\x0a\xa5\x29\xe3\x0d\x20\x4f\xa3\x74\x51\x0a\x5f\x8b\x14\x55\x3a\x5a\x2c\x78\xa2\x9f\x64\x99\x30\xf1\xf0\x8b\x48\x72\x48\xc1\x95\x18\x3b\xc6\x03\x9f\x0b\x01\xc6\x8e\xf7\x60\x04\x4c\x43\x35\x67\x72\x7f\xed\xa3\x04\x85\xc3\x7a\xec\x38\x08\xd3\xab\xa3\x68\xaa\xc0\x28\x0f\x38\x4e\x64\xb2\x59\xcc\xa7\x72\x30\xec\x4d\xd8\x5a\x1b\x81\xa3\xc3\x15\x13\x9e\x60\xb8\x38\x69\x42\x1e\x9c\x04\x8c\x38\xe8\xd1\x6b\x5a\xad\x77\x26\x6c\xa5\x92\xc9\x1d\x4b\xae\xea\x64\x33\x2d\xf5\x17\x4a\xef\xaa\xa5\xda\xa1\x7c\x4a\x1d\xaa\x17\x01\xed\x76\x21\x66\x6f\xfc\x98\x26\x4b\xbc\x38\xd1\x0b\x14\x7d\x7a\x47\xe8\xc0\x1a\x96\x00\x7a\xe6\xc7\x1f\xc4\xfa\x09\xce\x2a\x32\x9b\x43\x35\x76\x94\x27\x01\x85\x28\xe7\xd5\x15\x2a\x70\x45\x51\x21\xcf\x45\x59\x2a\xc5\x6d\x94\xa5\x3a\xed\xd8\x09\x6d\xdd\x27\xc3\x71\xb4\x9c\x94\x52\x35\x31\xe3\x22\x83\x1d\xa1\xc3\x04\xf9\xe6\xc7\xd4\x5d\x27\x90\xdc\x8d\x45\x5c\x21\x30\x5c\x93\x01\x6b\x39\xaa\xba\x16\x7e\x13\x5d\xa3\x59\xcc\xdd\xe6\x93\x55\x86\x49\x7d\xae\xa4\x28\x26\x97\xa6\xfb\x32\x06\x63\x00\x12\x5d\x20\xe2\xeb\x8c\x8e\xdd\xab\xb1\xc5\x1d\x89\x96\x8e\xb7\x6d\x74\x7d\xf4\xe3\x66\xcd\x39\x42\x79\xad\xa1\x0e\x53\x85\x72\x4a\x83\x89\x8a\x05\x11\x8f\xf0\x05\x42\xb9\x6d\x62\x3b\xa5\x33\x8d\xc7\x2f\xd4\x8d\x22\xfa\xfc\xf4\x25\x07\x3c\xf0\x6d\x8e\x2e\x34\xe3\xc3\x12\x51\xed\xb9\xd0\x5c\xba\xc1\x04\xf1\xe3\x59\xaa\x83\xcb\x07\xbe\x04\x35\xbd\xce\x46\x3f\x45\x36\x68\xbc\x41\xa3\x3b\x12\x5d\x93\x01\x82\xe2\xc5\x97\x46\xd8\x1e\x2b\xd9\x72\x17\x6b\x76\x06\x12\x82\x42\x37\x74\x95\x36\x66\xc2\x99\x6e\x59\x34\xe1\xd8\x88\xa9\x3f\x23\xaa\x91\x1e\xd8\x89\xfd\x90\x22\x96\x77\x01\x44\x98\x76\xd7\xa4\x0a\x7e\x05\x00\x00\xff\xff\x75\xa7\xe0\x03\x21\x23\x00\x00") + +func fontsTicksFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTicksFlf, + "fonts/ticks.flf", + ) +} + +func fontsTicksFlf() (*asset, error) { + bytes, err := fontsTicksFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/ticks.flf", size: 8993, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTicksslantFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x4d\x6f\xe4\x44\x10\xbd\xfb\x57\x94\x2c\xa4\xd9\x95\x60\x3a\x09\xbb\x48\x73\x1b\xe0\x8a\x80\x03\x70\x8a\xd4\x72\x12\x3b\x58\x4c\xec\x28\xf6\x80\xf6\x92\xdf\x8e\xc6\xe3\xf1\xd4\x57\xbb\xdb\x6d\x1b\x11\x69\x57\x8e\xe3\xe9\xd7\xaf\xea\xd5\xab\x6a\x4f\x71\x28\xee\xb2\xaf\xe0\x3b\xf8\x0c\x77\x9f\xe1\x06\x76\x70\x93\x24\x6d\xf9\xf8\x57\xd3\x1c\xb2\xaa\xdd\x16\x87\x02\x3e\xfc\xf8\x11\x6e\x77\xbb\x4f\xf0\xf0\x05\xfe\x28\x1f\xdb\xfa\x0d\x7e\xcd\xde\xb2\xa7\x0c\x3e\xfc\xfd\xda\x5d\xec\xcb\xaa\xd8\x1e\xdb\xa2\x79\xd9\x3e\x1e\x3e\xc2\xee\x93\xb9\xd9\x99\xbb\x6f\xb7\x49\x52\x94\xcf\x87\xbc\x85\xbb\xed\x2d\x14\x75\xd5\xc2\x43\xd6\xe4\x4f\x50\x57\xd0\x61\x9c\x96\xff\x1a\x3a\xa4\xfc\x09\x8e\x4d\x59\x3d\x9f\x7f\x2b\xca\xe7\xd3\xe3\xdb\x24\xf9\xed\xed\x0b\xd4\xaf\x6d\x59\x57\x90\x7e\xf3\x02\xb7\x29\xb4\x35\x34\x2f\xc7\xe6\x4f\xa8\xab\x1c\x52\x9b\xc2\x43\xde\xfe\x93\xe7\x55\x07\xd0\x6c\x93\xe4\xa7\xac\x2d\xfb\xdf\x20\xdb\x40\xbe\x81\x72\x03\xf5\x06\x8e\x1b\xa8\xde\x21\xab\x9e\xe0\xe7\x77\x78\xcb\x5f\x0f\xd9\x63\xde\xc0\xf7\x29\xfc\x92\xc2\xef\x29\x64\x29\xd4\x29\x1c\xd3\xee\x89\x1f\xb6\x49\x02\xa7\x1f\x6b\xad\xdd\x27\x97\x2b\xe8\x2e\xbb\xab\xee\xf2\x7c\x75\xba\xec\xaf\x60\x9f\x5c\xae\x60\xbf\xef\x97\x30\xf7\xe6\xfe\xb2\x48\x77\xdd\x2f\x73\xbe\x1e\x16\x1a\x96\xea\xef\x5f\x16\xd3\x96\xe3\x4b\xd2\x65\x6d\xf7\x8f\x2c\x4d\x77\x7a\x5d\xf6\x02\x21\x61\xec\x79\x1f\xfd\xff\x1c\x8c\x42\xb2\x67\x7b\x60\xfe\xec\x05\x9e\x3d\x4b\x37\xa1\x6f\x65\x78\x1c\x65\x43\x6e\x63\xf8\x9d\x66\xc8\xf2\x2d\xa0\x4f\x92\x0d\xa0\xcf\x8a\xfc\x5d\xfe\x8c\xf3\x38\x70\x18\x64\x61\x25\x3c\x7a\x12\xe7\xd7\x5a\x99\xe7\x00\xf6\x58\x8d\xf8\x2e\x49\x04\x02\x1c\x12\x81\x9e\x27\x89\xc0\x9b\xf3\x26\xc2\xad\x64\x26\x37\x2c\x35\xb7\x92\x87\x1d\x10\x71\x5d\xd9\xf0\x60\xe2\x9c\x11\x06\xe3\x4a\x1e\x3e\xc6\xa4\x23\xf2\x46\x72\xc6\xe5\x12\x59\x30\x16\xc5\x99\x32\x23\xa5\xc1\xb4\x4a\x83\x18\x55\x30\xc3\x8f\x26\x18\x65\x1b\x7c\x13\x22\x8f\x18\xca\xaf\x58\x0c\x8b\x03\x4d\x34\xa9\x18\xde\xc0\x51\x61\x83\x97\x54\x58\xcc\x36\xbc\xf8\x5d\x8f\xe4\x00\x0b\xdc\xe2\xe8\x06\xb8\x06\x66\x81\xee\x84\xe5\x00\x79\x1c\x31\x2d\x2b\x9b\x90\xa5\x01\xe4\xbe\x80\x6b\xcd\xa9\x41\xb5\x18\x68\x61\xd3\x6e\x41\xb9\x52\xb1\x53\x00\xbd\xff\xf1\x2a\xe3\xcc\xd8\x8e\x89\x13\xf2\xc0\xe2\x0e\xe1\x61\x36\x07\x9e\x3e\x37\xde\x8c\x46\x54\xea\x32\x34\xe9\x9d\x92\xbd\x11\xed\xd8\xda\x51\x6f\x71\xb1\xe7\xbd\xd0\x92\xa2\x61\xac\x96\x63\xef\x56\xb5\x0f\xde\xb0\xb6\x1b\xa1\x6a\x8d\x3d\x0d\xe0\xff\xa2\xa6\xc7\x94\x3f\xbb\xa6\xa7\xc0\x4b\x4f\x9e\x19\x7c\x6d\xf8\xc0\x41\xe6\xd2\xf2\x8c\xd1\xb1\xcb\x39\x9a\x14\x95\x85\x56\x8f\x8a\x1c\x50\x1d\xaa\x0e\x34\xde\x0b\x8d\x98\xc4\xad\x60\x20\xcb\xdd\xdb\x0b\x8d\x3a\x6d\x2b\x02\x77\xb0\x31\x78\x92\xf6\x4d\x66\x21\x5e\x6a\xad\xcb\x4d\x2e\xcb\x92\x20\xce\xad\x27\x23\xce\x15\x5a\x8f\x94\xf0\x51\x56\x2e\x03\xad\x4b\x87\xc3\xf3\xdc\xf2\x12\x8f\x68\x64\x5a\x39\x87\x7a\x69\xb4\x95\xfb\x3b\x89\xa6\x6a\x77\xf0\x17\x67\xaf\x05\x7f\x26\x7b\xa3\xf6\x51\xfc\xb8\x3f\xf8\x98\x3d\xd7\xc3\x8a\x6d\xdc\x05\x4f\xa0\x96\xcc\xbd\x5e\x78\x46\xed\x24\xc1\xec\xad\x7a\xa0\x77\x29\xdf\x9f\x7b\x3b\xbd\xf0\xdc\xe6\xca\x9d\xce\x08\x73\x55\xa1\xf4\x56\x61\xc4\xb0\x22\xcd\x35\x44\xe1\x31\xed\x3a\xe0\xad\x09\x5a\x94\x49\x4c\xb2\x9e\x18\xe4\xfe\x0f\x52\x60\xd2\x5a\xa4\xb6\x65\x5d\x4b\x50\x17\x24\xe7\xac\xb7\x14\x97\xb8\xf8\xd1\x8b\xad\xab\x71\x0f\x0d\xfe\x75\x69\x9f\xc2\xcd\x9c\xd6\x32\xed\xf0\xb9\x8a\xf4\x42\xe1\x57\x75\xb7\x58\xf6\x54\xf9\x2b\x76\x36\x9d\xfd\xac\xc2\x0b\xf5\xf6\x95\xce\xc7\x46\xe9\x6c\x56\x79\xf5\x65\xd5\x23\x9a\xfe\xea\x0b\xdf\x5b\xb0\xb5\xac\xa4\xfc\x58\x78\x0e\x35\x83\xbd\xee\xfa\x6e\xeb\xd1\x5f\x3d\x2d\xee\x80\xda\x70\xad\xeb\x40\x46\x62\x62\x15\x84\x26\xc2\x55\x05\x0b\xc8\x50\xab\x82\x39\x2f\x2a\x22\x2c\x48\xd4\xbf\xe3\x30\xcc\xd9\x3a\xa1\x9c\x3d\x5e\x9e\x54\xad\xbf\xd6\xb5\x33\xf8\xc4\x1c\xab\x36\xe3\x3c\x24\xeb\xce\xe6\x9d\xe3\xa4\x97\xd3\x42\x3a\x2f\xbc\xc4\xeb\x6f\x11\x4c\x4c\x9e\x8e\x8b\x32\x98\x0e\x58\x04\x2d\x64\x14\xf2\x3a\x46\xff\x92\x54\x30\x72\xb2\x61\xe3\x8f\x2a\x0b\xfe\xb6\x64\xde\xf8\x37\x3e\x71\x4a\x48\x87\x2c\xb4\x42\xf7\xb1\xb4\x8a\x3c\xfc\x43\xae\x75\x6b\x51\x87\x74\xf8\x8a\x34\x35\x27\xcb\xc9\x90\x1a\x4b\xf5\xa0\xba\x0c\x4b\xbf\x81\xa9\x53\xe3\xb4\xf7\x5f\xe1\xf9\x33\x7a\xa3\x26\xb5\x86\x99\x31\x11\xad\xa3\x52\xa7\x53\xaa\x90\xd4\x53\xa8\x3a\x69\x18\x49\x21\xb0\xe5\x65\x00\xa5\x16\x95\x12\x77\x58\xb0\x1e\xb6\xe0\xa0\xf1\x3c\x85\xb8\x49\x54\xd0\xa4\xd8\x67\x06\x4d\x2a\xcf\xe0\xe3\xa1\xe7\x8b\x6a\x73\xbf\xd0\x39\xd5\xb5\x0d\xc9\x76\xdc\x4d\x26\x04\xd6\x5d\x73\xd3\x20\xad\x9d\x61\xd3\xa1\x2c\x35\xf9\x0c\x00\xbd\x5e\x27\xb2\x9c\xeb\x2c\xec\x8e\x8f\x65\x48\x91\x5c\x19\xe8\x2c\x23\x72\x39\x06\x49\x19\x4c\x6e\xb9\xc3\xfe\x58\x2e\x79\xff\xeb\x3f\xcc\x67\xea\xa5\xe4\xa3\x1d\xe8\xc2\x14\x1b\x55\x24\x21\x90\x94\xd3\xd5\x5f\xa7\xe6\x52\xc0\x5a\xf5\xf8\xea\x2a\x18\xae\x60\xea\x6b\xd1\xae\xa4\xcf\x38\xf2\xd4\x18\x65\xf7\xf3\x02\x1e\x35\x09\xe8\x90\x5c\xc9\x7c\x44\x96\x4a\x36\xe1\x23\x32\xda\xaf\x3c\xae\x39\xe7\x55\x77\xf1\x84\xf6\x51\xe5\x5c\x21\x4a\x05\xe7\x0c\xbb\xab\x5c\xce\x88\x79\x86\x5a\x39\xc9\xc1\x3e\xe1\x61\x8c\x75\x1c\xce\x64\xc4\xce\x27\x1f\xcc\xbc\xc5\x20\xc1\x71\xce\xa4\x4c\xcc\x9c\x93\x94\x84\xfc\x8f\x06\xfe\xd5\x66\xd4\x10\x36\x8b\x0f\x1c\x42\xfa\x6b\x76\x0c\x94\x0f\x3e\x8b\xaf\x79\xae\x18\x01\x15\x87\x35\x9d\x6b\xc4\x97\x1c\xff\x06\x00\x00\xff\xff\xdd\xdb\xf2\xef\x36\x2f\x00\x00") + +func fontsTicksslantFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTicksslantFlf, + "fonts/ticksslant.flf", + ) +} + +func fontsTicksslantFlf() (*asset, error) { + bytes, err := fontsTicksslantFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/ticksslant.flf", size: 12086, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTinkerToyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x58\x4b\x6b\xec\x36\x14\xde\xfb\x57\x7c\x0c\x17\x6e\x42\xa3\xfa\x4e\x4a\xb8\xb4\xab\xd9\x14\xba\xd3\xa6\xd0\x8d\xa1\x55\xfc\xc8\x98\x78\xac\x60\x7b\x48\x02\xfe\xf1\xc5\x7a\x58\x47\xb2\x6c\x4f\x02\xf1\x4b\x3a\xaf\xef\x3c\x35\x55\x53\x3d\x8a\x6f\xf8\x89\x27\x1c\x1f\xc1\x8e\x38\x3e\x26\x7f\xd7\xed\x6b\xd9\xb1\x41\x7e\xe2\xf9\x13\xff\x94\x6d\x51\x36\x0d\xfe\xaa\xf3\xd7\xb2\xc5\xf1\x98\xfe\xfe\x1b\xee\xde\xcf\xea\xf5\xf4\x26\x3a\xd1\xcb\x6a\xf8\x35\x97\x97\xfb\x24\xf9\xf3\xe3\xad\x11\xad\x18\x6a\xd9\x42\x56\xa8\xea\xae\x1f\xd0\xd4\x6d\xf9\x47\x32\x49\x02\xc3\xe1\x22\x5e\xea\x1c\xed\xf5\xf2\x5c\x76\x07\x54\xb2\x43\x55\x37\x25\xea\xa2\x6c\x87\xba\xaa\x73\x45\x9c\x08\x00\x60\xe8\xcf\xf2\xda\x14\x10\xcd\xbb\xf8\xec\xf1\x5c\xe2\x3f\xf1\xfd\x41\x11\xb5\xf2\x3d\xf9\xa6\x37\x0d\xe7\x12\x87\xb3\xe8\x8a\xe7\x46\xb4\xaf\x07\x30\x86\xb7\xae\x6e\x87\x1e\xa2\x87\x80\xfa\xfa\x80\xe7\xeb\x80\x5c\xb4\xdf\x87\x89\x4d\x7f\xb9\xf6\xe7\xb2\x48\x7e\x6a\x0e\xe7\xb2\x7e\x39\x0f\x93\xc6\x02\xf9\x59\x74\x22\x1f\xca\x2e\x79\xda\x58\x7c\x40\x2b\x07\xd4\x6d\xde\x5c\x8b\xba\x7d\x41\x51\xf6\xf9\x04\x54\xd7\x5b\xb2\x8b\xf8\x50\x96\xa3\x29\xdb\x97\xe1\x8c\xbb\xf2\xc3\x6e\xce\xe5\xe5\x52\xb6\x1a\x98\xfe\x1e\xbf\x40\xa0\xba\x16\x2f\x25\x2a\x91\x0f\xb2\x4b\x8e\x4f\x8a\x43\x51\x56\xe2\xda\x0c\x5a\xd9\x8b\x2c\x4a\x65\xf8\x70\xae\x7b\x54\xb2\x1d\x70\xd7\xd4\xaf\x25\x0e\xec\x82\xe3\xd3\x01\xb2\x55\x7c\x45\x5b\x28\xbe\xf7\xc9\xf1\x51\x71\xd1\x48\x4f\xea\x7b\x62\x93\x04\xc0\xb7\xd3\x2d\xd7\x53\x22\x71\x4a\x46\xe8\x3b\x70\x4a\xb8\xb9\x03\x6a\x51\x2f\x8f\xea\x03\xd6\xaf\xa7\x04\xd3\x2e\x9c\x12\xc6\x19\x67\x58\x7f\x07\x1c\x99\x26\xd4\x2b\xd3\x27\xbd\x57\x29\xb3\xfc\xa6\xf7\xc9\xc8\x37\xa3\x2a\xa0\x75\x47\xaa\x97\x52\xcd\x20\xd5\xf2\x38\xa0\x89\x97\xf2\xf5\xab\x5a\x4c\x15\x14\x8c\x33\xcd\x3b\xb0\xd1\x62\x85\xe5\xbf\x12\xa4\xb4\x98\xb6\xd8\x27\x64\x9a\x58\x5f\x4e\x49\xa6\x1e\xa5\x86\xc3\x3c\xa5\xf0\xf7\x58\x05\xa5\xb5\x36\x1b\xd5\x16\xc6\x38\x63\x5a\xc7\xcc\x5b\x0f\x0c\xd1\xa8\x4b\x36\x3f\xc7\x9c\x15\x18\x40\x0c\xf3\xf7\x4b\x26\x37\x9d\x1e\xf0\xf1\x82\x67\xda\x23\x8d\x43\x34\xc0\xd6\x1d\xda\x5b\x56\x77\x7b\x9b\xf0\x60\xd2\xac\xa6\x5a\xa5\x54\xe1\x24\x53\xe3\x1e\xb3\x1e\xf1\xe1\x0f\xe3\xec\x71\xc6\xce\xc6\x87\x31\x83\xc5\x9d\xcf\x4c\xbc\x19\x28\x53\xaa\x23\x73\x34\x4e\x47\xa7\x82\xf6\x20\x7d\xa3\xea\x11\x0a\x98\x2c\x32\x7b\x18\x27\xf4\x24\x28\xa9\x0c\x66\x28\x80\x50\x62\x5c\x86\x42\x97\x46\x3b\x9b\x91\x34\x7a\xae\x20\x27\xd9\x6c\x65\x6a\xf3\x80\x22\xe7\xde\x43\xe4\x0c\xc7\x31\x90\x10\xbe\x6f\x12\x1a\xa7\x32\x1e\xd5\x60\xe1\x64\x17\x60\x7c\x91\x7d\xa4\x84\x05\x69\xea\x92\xdb\xd6\x01\x95\x98\x2e\xe9\xfd\x88\xa6\x81\x69\x1c\x11\x8b\x04\xea\x5e\xc2\x90\xcf\x82\x64\x24\x5d\x5c\x7c\x23\x0e\xba\xdd\xce\x43\xd3\x67\xf7\x9a\xdc\xe7\x5a\xa3\x6c\xae\x5e\x6c\x05\x33\x3e\xd3\x19\x67\x1b\x17\x19\x2d\xe2\xb1\x47\xfc\xc8\x83\x77\xbb\x1e\x11\x65\x72\x8c\x14\x5c\x04\x3a\x46\x73\x50\x81\xa2\x25\x64\x56\x12\xd7\xf7\x74\x8e\xff\x95\xd8\x25\x69\xc2\x9d\x9e\x1b\xc9\xbb\x41\xb1\x57\x92\xac\x92\x3a\x24\x76\x13\xcb\xcb\x7a\xae\x63\xdc\xd6\x80\x95\xac\x37\x4e\x0d\x8a\x97\x2b\x62\x7c\xa5\x88\x91\x2a\x32\x92\x7b\x86\x9d\xb2\x39\xeb\xa8\x33\x83\x1b\x0b\x33\xac\xeb\x38\xa3\xb0\xbc\x71\x1d\x5d\x11\x0a\x25\x24\x83\x6a\xae\x23\x38\x46\x1a\x4f\x6b\x7d\x99\x10\x1a\x82\xcc\x12\x66\x9b\x84\x61\x96\x2d\x24\x6d\xd4\xc2\xd5\xd0\xa7\x31\xf0\x25\x89\x5c\x4b\xe4\xd9\x6d\x12\xb9\xa4\xa9\xb0\x6b\xa3\x55\x8d\xda\xb4\x99\xa5\x7b\x41\xb6\x5a\x7d\x43\xdb\xc2\xfb\x56\x90\xc5\xdd\x90\xed\xd4\x7b\x0d\xb7\x23\x86\xc7\x80\x30\xf1\x18\x51\x66\x08\x9f\x63\xd2\x79\x50\x59\x77\xc2\x71\x41\xb8\x0b\x5c\xd8\x61\xed\xec\x6a\xea\x24\x59\xf7\x09\xf9\x5c\xab\xfc\x2b\x0f\x67\x32\x57\xbb\x32\xa7\x8a\x5a\xb3\x41\x17\x2b\xf3\xdc\x28\xef\x5f\xed\x77\xaf\x6b\x41\x8d\xa9\x99\xbf\x10\x9f\x07\x97\x35\x74\xd9\x52\x5d\x95\x38\x25\x3f\x36\x47\x6a\x2a\x41\xba\xa3\xc8\x34\xce\xc5\x11\x58\x54\xf6\xad\x91\xc9\xd3\x4e\xd2\xce\x40\x5b\x95\x47\x61\xbe\x9a\x80\x27\x25\x7d\x95\x62\x36\xc0\x08\x60\xdf\x63\x63\xb5\x66\x30\x4f\xef\x9c\x4c\xef\x72\x07\x65\xd7\xd3\x96\xe3\xa5\x5e\x5b\xa2\xe3\x51\x44\x0b\x3d\xc8\x3c\x35\x2e\xe7\x29\xb7\x39\x0c\x5d\xda\x88\x82\x8a\x4b\xf4\xf8\x42\xc3\x71\xf2\xe9\x31\x75\xa1\x07\xed\x90\x23\x4c\x9c\x40\xae\x9f\xf9\x28\x82\x5e\xb4\xac\xe0\xb1\xf0\xe4\x1c\x5b\x3b\xee\xa1\xcc\x63\x23\xc7\x7a\x28\x92\x30\xf3\xce\x0b\x71\x75\xb0\x32\x74\x2e\xb6\x1a\xbc\x63\x31\x08\x44\x4f\x90\xbb\x31\x18\x1e\x71\x56\x10\xf4\x9c\x75\x6b\x1f\x80\xfd\xf3\x1e\xe7\x2e\x40\x9a\x00\xe9\x01\x2b\x64\x3e\x1c\x86\x26\x5e\xdf\x76\x6d\x8c\xe4\x59\x04\xeb\x74\x0d\xeb\xb9\x62\xcc\xd3\x5d\xd8\x4f\x56\xc6\x65\x92\x09\x8b\x8c\x70\xb3\xb2\xe5\xc2\x03\x29\x9b\x20\x4f\x60\xfc\xab\x40\x49\x3d\x14\x57\xef\xea\x28\xa2\x7c\xf0\x85\x13\x86\xb2\x4c\x6a\xe0\xed\x8f\x21\x36\xd8\xe7\x0a\xe2\x8d\x13\xe4\xc1\x66\xb5\x9b\x0a\xc6\x79\x34\x9b\x8f\x44\xa9\x43\x90\xfa\x9f\x3c\xd9\xdf\xb6\x70\x5b\x73\x91\xb7\x26\xbf\x5f\x3d\x6e\xc9\x8b\x5b\x0f\x5c\xc1\x14\x7a\x4a\xfe\x0f\x00\x00\xff\xff\x68\xbd\xa6\xb5\xe0\x15\x00\x00") + +func fontsTinkerToyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTinkerToyFlf, + "fonts/tinker-toy.flf", + ) +} + +func fontsTinkerToyFlf() (*asset, error) { + bytes, err := fontsTinkerToyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/tinker-toy.flf", size: 5600, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTombstoneFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x56\x5f\x6f\xdb\xb6\x17\x7d\xe7\xa7\x38\x30\x84\x9f\x62\x80\x31\x1b\xff\xba\xa1\xc9\x93\xdc\x0e\x01\x8c\x0d\xdd\xd6\x64\x6f\x04\x68\xd9\xa6\x6c\xa1\xae\xe4\x49\x4a\x0b\x03\x04\x3f\xfb\xc0\x4b\xfd\xb5\x14\x60\xdb\xeb\x8a\x48\x0c\x75\xff\x1c\x1e\x9e\xcb\x2b\x39\x39\x25\xcb\x38\xc0\x0f\x78\x8b\x77\xb8\xbd\xc3\xdd\x92\xcd\xd2\x2c\xc9\xcf\xf9\xb7\x62\x91\x9c\x92\x19\x7b\x1f\x97\x7a\x8f\x3c\x43\x8c\xbb\x25\x4e\xba\xaa\x74\x81\x24\xcf\x2a\x3c\x16\xf9\x97\x07\xcc\x56\x59\xf9\x4d\x17\x25\xaa\x1c\x8f\x85\xfe\xf3\x45\x67\xd5\xe9\x82\x55\xf9\x59\xef\xf1\xfb\x8b\x2e\xab\x34\xcf\x4a\x06\xac\xb6\xf9\x4b\x85\xe7\x7c\x1f\x5f\xc2\x12\x1f\x8a\xcb\xb9\xca\x0f\x45\x7c\x3e\x5e\xf8\x0c\x5f\x97\x8b\x37\xd8\x17\x71\x52\x61\x99\x70\xdc\x8b\xe5\x1b\x71\xff\x7f\x8e\xed\x05\xbf\xc5\x2f\x27\x3c\xc6\xc7\x8c\x33\x60\x97\x9f\x2f\x45\x7a\x38\x56\xb8\xbb\x77\xfe\x4f\x4f\x2b\xfc\x12\x6f\xf3\x22\xae\xf2\x22\xd5\x25\x7b\x3a\xeb\x5d\x9a\xa4\xbb\xf8\x74\xba\x70\x54\x47\x8d\xd5\xd3\x87\xf5\xba\x26\x9e\x66\x07\x24\x45\xfe\x85\x1c\xb3\x9f\xd6\x4f\xcf\x9f\xd6\xef\xff\x78\x5e\xff\xfa\xf1\x61\x86\x52\xef\x1c\xd7\x07\x36\x53\x50\x1c\x0a\x4a\xf9\x89\xe2\xf0\x06\xff\xa4\x9a\x19\xc5\xe0\x3a\xc4\x47\x28\x8e\x19\x83\x81\x91\x6e\x50\x10\x90\x30\x6a\x0e\x18\x29\x0c\x3d\xc1\xb8\x8b\xec\x14\x83\x1b\x05\x0a\x21\x13\x7c\x1a\x0c\xe6\x04\x03\xe9\x06\x48\x08\x37\xaf\x93\x8d\x35\xf5\xac\xb6\xbb\x18\x8e\xb9\xb3\x79\x93\xf0\x69\x30\x56\x32\x58\x58\xf8\xc1\x4f\x3a\x83\xc5\xd5\xd5\x4e\x7b\x26\xeb\xcd\x8c\xad\xf6\xfb\xd4\x29\x15\x9f\xb0\x3b\xc6\x45\xbc\xab\x5c\xfd\xff\x87\x24\x3d\x9c\x74\x85\x5d\x9e\x7d\xd5\x45\x99\xe6\x19\xb6\x97\x07\x06\xe0\x67\x9d\x55\xf8\x18\x97\xa5\xce\x38\x3e\xeb\xac\xca\xa2\xdd\x65\xab\x8b\xf2\x1c\xef\xf4\x22\x2f\x0e\x1c\xef\xc4\xdd\x8f\xe2\xfe\x2d\x0b\x82\xe8\xfa\x8e\x18\x78\xc4\x60\xea\x7b\x11\x31\x78\xa3\xb3\x86\x61\xc4\x80\xa0\x37\x44\xac\xfd\xfb\x1b\x53\x82\x0e\x09\xb2\xb9\x23\x06\xd1\x5b\x4f\x36\x46\xd9\x33\x8a\xda\xf8\x0a\x68\x03\xd6\x81\x0f\x58\x5a\x3b\xe0\x1b\xd0\xc5\x23\x66\xdd\xa4\x75\xb9\x35\x04\x06\x91\x50\x41\xc4\x84\x63\x22\xc9\x6d\xd1\x7a\xfa\x12\xd9\x76\x49\xc5\x29\x6a\x4e\x78\xa0\xa5\x69\xed\x81\x5b\x91\x9b\x82\xac\x47\xac\xdd\x04\x2a\x3c\xa4\x35\x64\x19\x65\x1b\x85\x57\xb2\xc9\x2d\xc8\x2d\x3d\x83\xbe\x5b\x91\x5b\x11\x29\x51\x3b\x46\xd9\x37\x44\xed\x66\x9c\xdd\xb8\x45\xbb\x31\x84\x3d\x77\x50\x9f\x93\x45\xbf\xa8\x8d\x71\x58\x94\x56\x65\x49\xf9\xb2\x15\xb4\xab\xd4\x55\xb9\xfa\x91\xfd\x1a\x11\xad\xa0\xe3\xeb\xed\x8b\xa0\xa5\x15\x10\xeb\x40\xf0\x79\xc4\x02\xb9\x09\x9d\xc5\x61\x07\x43\xc5\xfc\x41\x23\xbd\x6d\x5f\x6f\x55\xeb\x3d\x6f\x47\x3b\x56\x4c\x60\x43\x0c\xf9\xb4\xde\xc6\x83\x2b\x71\x9d\xad\x7a\xc5\x34\x18\x9d\x94\x09\xf7\xd4\xda\x8a\xd6\x16\xa3\xb5\xb9\xa2\x6c\x3a\x9f\xb8\xde\x58\xa0\x22\x16\x98\xfa\xb6\x4d\xcb\x43\xb9\x1c\x4e\xd1\x37\x34\x62\x40\xa8\x86\x14\xed\xa6\x86\x5a\xf1\x8e\xa9\x21\x31\x86\xdb\xe1\x44\xd5\xbd\x8b\x7d\x98\xe7\x54\x23\x5c\xc5\xf8\xb6\x82\x9c\x88\xe9\x57\x6c\x6a\xdf\xfd\x8a\xbd\xae\x1a\x65\x4b\x9f\xbd\x79\x2d\x7b\xb4\xc5\xa6\x05\x40\x32\x4d\xf4\x97\x63\x0f\x83\x6e\x9c\x28\x09\xba\x92\x6c\x6c\x38\x76\x93\xbc\x62\xc4\xdc\x7d\xe7\x3a\xe1\xdc\x57\x66\x42\x3f\xff\xfa\x08\xa5\xef\x03\x21\x31\x8e\xe1\xf5\x89\xa1\xf2\x4a\xd3\xbe\x48\x60\xc3\x7a\x0f\x0e\x62\x53\xb7\x92\x68\xce\x25\x7a\x10\x8b\x5b\x22\xd2\x0c\x9b\xdb\xae\x19\x7d\xcb\xfa\x6e\xf5\xed\xda\xdf\xc3\xed\x82\x94\x69\x86\xdb\xb0\x4d\x14\xf2\xfa\x9b\xd2\x41\xfa\x87\xc1\x3f\xdb\x1c\xad\x3a\x86\x70\x37\x53\xd9\xf5\x1b\x51\x4e\xb6\xc1\x7f\xaf\xbf\xb9\x6f\x70\xf8\x0e\xf7\x47\x74\x50\xdb\xef\x4d\xfe\xbd\xc9\xaf\x7e\x65\x51\x77\x99\xde\xfd\x4f\x7f\xf0\xfd\xcb\xe9\x5f\x01\x00\x00\xff\xff\xd7\x8b\x21\xb8\x29\x0d\x00\x00") + +func fontsTombstoneFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTombstoneFlf, + "fonts/tombstone.flf", + ) +} + +func fontsTombstoneFlf() (*asset, error) { + bytes, err := fontsTombstoneFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/tombstone.flf", size: 3369, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTrekFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x59\xeb\x6b\x1b\x47\x10\xff\x7e\x7f\xc5\x34\x2c\xdc\x17\x67\x95\xf4\x91\xda\x02\x97\xf3\x06\x42\xc1\x0e\x5d\x70\x9b\x2f\x21\x48\x3a\xef\xc5\x32\xc8\x92\xb1\x24\x48\x20\x7f\x7c\xd9\x9d\x9d\xd9\xd9\xbb\xd3\xc3\x56\x9c\x26\x50\xd5\x54\x73\x8f\x79\xbf\x7e\xab\x7c\x9c\x7d\xfc\x79\xa2\xe0\x15\xfc\x06\x2f\x5f\xc1\x0b\xf8\xe5\x45\x31\x18\x3c\x7f\xfc\x67\x30\x28\x06\x03\x78\xfc\x87\xf9\xb5\x33\xc6\x18\x0b\xe1\x2b\x11\x35\x80\xa0\xb6\xf0\x1b\xdb\xf7\xd8\x98\x48\xb8\xfe\xe7\x89\x7f\x9c\xb4\xd9\xc4\x12\xf8\x83\xfe\xf3\x1d\xf6\x13\x67\xc6\x1e\xf8\x99\xd8\xc2\x8f\xce\x97\x19\x3b\x7e\x48\x6a\xb9\x5b\xff\x63\x3e\xbd\xfc\x1b\x72\x10\xbd\xcb\x42\xb9\x5b\xbf\x7c\xdd\x19\xab\xf3\x4c\x6c\xd0\x6f\x93\x1d\xe7\x48\x58\x10\x51\xda\xce\x9f\xd8\x65\x06\x44\x42\xb7\xf3\x67\xec\x3e\xf0\x5c\x99\xb6\x9b\x87\x27\x89\x3f\x3c\x3f\x7d\x0f\x7f\x4f\x1b\x78\x73\x73\x3d\x6b\x56\xf0\x66\x31\x5f\xc1\x87\xd3\xe7\x7b\xf3\x3f\x58\xff\x7b\x78\xd7\xdc\x2f\x6f\x16\x73\x78\xa9\x5f\xc0\x87\x43\xed\x7f\x30\xff\xcb\x93\x93\x5f\x8f\xa0\xfe\x0c\xb6\x59\x35\xf7\x70\xa1\xc1\xac\x97\x57\xd3\xdb\xc9\xfc\xdb\xe8\xb7\xb3\x66\xb2\x6c\x60\xd9\xcc\x1d\x4c\x66\x33\xb8\x5a\xdc\xde\x36\xf3\xd5\x12\x56\x0b\x58\x4d\x1b\x98\xac\x57\xd3\xc5\x3d\x4c\x56\xc3\xa7\xd1\xff\x34\xfc\x27\xbf\xd7\x31\x8a\x77\xd5\x64\x76\x3b\xd1\x8d\x5b\x3f\x84\xff\x6e\x86\xfc\xd5\xfc\xf3\x27\x7d\xb5\xd4\x6e\xdd\x91\xf0\x95\xec\xff\xeb\xec\x12\xce\xce\x2e\xe1\xe2\xe2\xf2\xa7\x87\xf3\x1f\xb6\xbf\xfe\x6c\x6e\xae\xa7\xab\x23\xf8\xe7\x6e\xe4\xbf\xde\x4e\x3e\xcd\x9a\xf9\xf5\x6a\x7a\x04\x97\xb7\xeb\xe5\xf4\xed\xc2\x35\x47\xf0\x1a\x0b\xe2\xf5\x62\x3d\x5f\x15\x45\x50\xad\x94\xaa\x8a\x48\x40\xa0\x3c\x11\xa8\x40\x78\x0a\x09\xa8\x8a\x48\x40\x55\x45\x66\x67\x6c\xe4\xf6\x73\x05\xd9\xc3\xc4\x09\xfc\x38\x83\xbc\x80\xe8\x67\x55\x28\x9a\x4b\x24\x02\x9f\x3b\x0b\xce\xfa\xa7\xfe\x1b\xe4\xa3\x36\x51\x15\x28\xcc\x1d\x1f\x07\x35\xca\x53\xf8\x09\x02\x8e\x4d\xa0\x83\x35\x8a\x5e\x93\x12\xe4\xd5\x08\x92\x2d\x4a\x9f\x9e\x9e\xea\x40\x0d\xe1\x4b\xf4\x60\xcc\xf7\x00\xbe\xc0\x90\xef\x95\xf1\xde\x33\x64\xf6\x76\x07\x07\x82\xa7\xe8\x81\x0a\x04\x52\xce\x26\x3f\xf1\x3d\x10\x9a\xb5\x31\x75\x89\x0a\x8d\xd6\x64\xde\x1f\x18\xa8\xaa\x00\x6d\xc8\x68\xad\xc7\x26\xcc\x6e\xe1\x4d\x8c\x08\x86\xb6\x2a\x14\xe5\x21\xff\x7f\xcc\x92\x57\xa5\x45\x9a\x64\x9e\xd0\x40\x4a\x4f\xca\x94\xa7\xc7\x84\x5c\x44\xe6\x8d\x8e\x42\xc3\x92\x41\xa1\xb8\x6f\x62\x70\xa8\x10\x88\x8c\x82\x70\xf9\x50\x22\xb5\xc6\x44\xe9\xe1\x30\x54\x00\xae\xc9\x61\xa0\x86\xce\x98\x1a\xef\xd9\xe1\xb0\xa4\xd4\x93\x15\x8a\xfc\x53\x5c\x47\xa4\x5f\xe1\xce\x0f\x02\x93\xa3\x39\x73\xe4\x8c\x49\x8b\xc2\x7d\x8d\x63\x1c\x43\x20\xa9\x21\xb0\x49\x14\x51\x8a\x28\xa1\x87\xef\xe5\x7a\x62\x53\xa0\x32\xd4\x45\xa9\xca\xdb\x40\x8d\x46\x14\xdb\x11\xc7\x73\xc4\x31\x1c\x71\x92\x64\x62\x00\x5a\xda\xd0\x20\x4b\x29\x2e\x35\xa5\xc3\x99\xa1\x26\x59\xf1\x3e\x70\xa0\x6c\xa7\x43\xb0\xaa\x03\x6c\x12\x1e\x15\xa2\xbd\xb9\x80\x44\xf9\xb4\x99\x7d\xf6\xa8\xf9\x23\x33\xda\xe3\x79\x46\x23\xa1\xbf\x15\xb6\xc4\x9d\xb1\x23\x80\xa3\x36\x13\x99\xb6\xed\x96\x88\x86\x3a\x7e\xbb\x55\x18\xf4\xbe\x28\x8e\x8e\x1b\xad\xa0\xa6\x1a\xcf\x1d\x62\x71\x4a\x0a\x4c\x4f\x3a\xb3\x87\x92\x43\x22\xc3\x54\x10\x83\x10\xc5\xc5\x59\x81\xc2\xde\xf5\x89\xaa\x48\xcb\x63\x73\x44\x66\xd4\xd1\x22\x1e\x4e\xca\x59\xc3\x99\xb2\x34\xc8\x14\x90\x19\xdd\x18\xc9\x84\x39\xcb\x13\x21\x18\x6e\x6c\x8a\x0e\xcd\xec\x8d\x82\x80\xb6\x50\x72\x85\x98\xc9\x0d\x62\xe2\x5d\x90\x7d\x63\xf7\xf2\x35\xa7\xdd\xa6\x66\x0b\xf7\x2d\xc5\xd8\x87\xb7\x8e\xfe\x71\x24\xab\x4e\x44\x53\xe1\xa5\xfc\x66\x65\xd7\x89\xad\x90\x3c\x0e\x39\xca\xb5\xb6\x72\x88\x2f\x53\xe7\x3b\x93\xad\x41\xd5\x1a\x62\x55\x56\x8a\xa2\x12\xb1\xe3\xfc\xdb\x23\x2f\x84\x38\x9f\x79\xcc\x1f\xeb\xc8\x84\x11\xdc\xdf\xed\x5c\x4b\x0a\x8f\x9d\x5c\x4d\x48\x2b\x3a\x8c\x70\x7d\xc7\x77\x36\x16\x03\x75\x2a\x9b\x78\x5e\xd2\x08\x02\x57\x8b\x09\x54\x6e\xee\xbc\xac\xef\xb6\x2e\xac\x2d\x55\xd5\x32\x09\xe3\xc1\x53\xa2\x64\x59\xe1\x6c\xc4\xee\x95\x7d\x73\x91\xed\x82\xde\x2c\x74\x4c\xdb\x31\x66\xdb\x53\xbb\x53\x76\xbd\xe2\x6c\xa7\xea\xb6\x38\x9b\xd5\x08\x8b\x2b\x21\x5e\x50\x2e\x37\x8b\xb3\x5c\x98\x00\xdd\xa2\x13\xc3\x26\x1b\x38\x3d\x13\x35\x13\xda\xda\xe2\xfb\x4f\x2d\x48\x45\x95\xd9\x03\x20\x50\x87\x33\xa5\xdb\x63\xcb\xe1\x5a\x11\x0e\x86\xe3\xfd\xb1\x15\x0e\xc6\xe2\x54\xe9\xe8\xcd\x0e\x96\x87\x3a\xd8\xb7\xfd\x20\x6f\x67\x94\x51\xa6\xa2\x8d\xbe\x95\xb1\x6e\xe5\x65\xf2\x1c\x2f\x5b\xb6\x6d\xeb\x07\x2b\xb7\x66\x9e\xd0\x2c\x9f\x3b\x0b\x38\x87\x1d\xe5\x43\x61\x07\x4f\x22\xde\xfe\xa9\x57\x43\x2e\x36\xe3\xd4\x03\xec\x92\x9d\x50\xf6\x77\x42\x8f\x5d\x69\xae\x99\xf3\xb2\x33\x20\xe3\x2f\x2f\x1d\xbb\x74\xb2\xca\xa4\xd3\xc9\x38\x5b\xe5\x98\x83\xbe\xd9\x58\xd1\x02\x65\xcf\x44\x07\xec\xc6\xf2\xbd\x85\x0a\x6e\x03\xba\xb1\xb2\x9f\xec\x68\x4f\x74\x13\xf8\xe4\x31\xc7\x33\x40\x0c\xbe\x31\x14\xf9\xce\xb8\x16\x16\xe1\x5f\x6e\x53\xb2\x0a\xff\xd8\x2e\xba\x94\x7b\xa9\xc7\x36\x8c\x9d\xdf\xc5\xde\x96\xb8\xcd\x45\x49\x98\xf3\x34\x1a\x49\x58\x99\xaf\x62\xda\xd8\x22\x62\x2e\x09\xd8\x67\x7e\x65\x60\xb2\x95\xb7\xfd\x67\x43\x0d\x4a\x64\x8f\x41\x53\xbc\x10\x22\x95\x2c\x86\x04\xa3\x8c\xb1\xf9\x51\xde\xdf\x1f\xe3\x21\xaf\x2a\x00\x29\xac\xca\x3a\x3a\x30\x36\xb5\x6a\x01\x90\xb8\xf0\xc8\x14\x1f\x13\x86\x6f\x81\x66\xd8\x6e\xc9\x0e\xa2\x23\xaa\x15\x56\x28\x87\x20\xc9\xd9\x31\x8d\x3d\x81\xf5\xda\xdf\xa4\x5f\xfc\x7c\x81\xd4\x3e\xa7\xb5\xaa\xe0\x40\xd4\xa1\x22\x02\x64\xa4\x4e\xad\x0a\x68\x61\x22\x76\xdb\x18\x81\x88\x44\xbf\x8b\xba\xab\x5a\xe7\x90\x1f\x04\x0d\xed\x9a\xfe\x7d\xd2\xfe\x47\x43\x5b\x0e\x83\x3f\x2a\x1a\x6a\x39\xe8\x8e\xf1\x1f\x3b\x04\x1a\x82\x8d\x68\xe8\x60\x07\xfb\x27\x5e\x0e\x86\x54\xe6\xb1\x18\xff\xad\x65\x80\x56\x89\xd5\x00\xfd\x76\x3d\x21\x0e\xb2\x62\xb9\x58\x81\x37\xec\x7f\x8c\x83\xb6\xd8\x75\x38\x0e\x82\x6f\x87\x83\xb8\x32\xbe\x53\x1c\xd4\x01\x42\x02\x09\x09\x28\x24\xb0\x50\xdb\xc1\xa7\x46\x43\x02\x0c\x09\x2c\xc4\x50\x88\x91\x50\x17\x08\xb5\x71\x50\x7a\xcc\x3f\xd2\x70\x9f\x7c\x75\x1c\x24\xfe\xfb\x1e\x2e\xfe\x0d\x00\x00\xff\xff\xe4\x59\x27\x82\x90\x20\x00\x00") + +func fontsTrekFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTrekFlf, + "fonts/trek.flf", + ) +} + +func fontsTrekFlf() (*asset, error) { + bytes, err := fontsTrekFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/trek.flf", size: 8336, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTsalagiFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x59\xdb\x72\xdb\x46\xd2\xbe\xe7\x53\x7c\x09\x9d\x40\x8a\x1b\x1c\x49\x8e\xe3\x43\xb9\xf4\xcb\x71\xe2\x24\xce\xc9\x89\x95\xa3\xe1\x0c\x21\x69\x28\x22\x22\x09\x9a\x04\xa8\xd0\x99\xf0\xe9\xfe\x67\xd8\xab\xad\xda\x9b\x7d\x86\xbd\xda\x8b\xad\xc6\xcc\xe0\x4c\x49\x74\x71\x97\xa5\xd2\xd7\x02\x07\xdf\x74\xf7\xf4\x69\xec\xc1\x68\x70\x10\xde\xc2\x5d\xdc\xc5\xfe\x1e\xfc\x7d\xdc\xbd\xd3\x39\x59\xe2\x99\x9a\xcd\xc2\x33\x3c\x8f\xd4\xec\x54\xe1\xe5\x30\x49\xa6\x0f\x85\xb8\xbc\xbc\xec\x4d\x93\xe1\xc9\x49\x2f\x9e\x9d\x8b\x79\x3c\x48\x2e\xc3\x99\x12\x83\xe8\x7c\xa4\x12\x91\xcc\xc3\x51\x78\x1e\xf5\x86\xc9\x78\xf4\xaa\x03\x60\x7f\x5f\x3c\xb8\x47\x38\x10\x7b\x07\x84\xfb\x62\xef\xa0\xf3\x5c\xcd\xc6\xd1\x7c\x1e\xc5\x13\x24\x31\xc6\xf1\x59\x34\x58\xe2\x7c\x16\x4e\x12\x75\x46\x38\x49\x13\x4c\x47\x2a\x9c\x2b\xcc\xd5\xe4\x0c\x63\x85\x10\xa7\xf1\x74\x89\x78\x86\x49\x9c\xf0\xe2\xb1\xea\x75\x1e\x8f\xe6\x31\xc2\x45\x18\x8d\xc2\x93\x91\x7a\x88\x13\x35\x4f\x30\x88\x12\x31\x0e\x93\xd3\x21\xe2\x01\x4e\x87\xe1\x2c\x3c\x4d\xd4\x6c\x4e\x08\x47\xa3\xf8\x12\xd3\x74\x72\x9a\xa4\x61\xc2\x5b\x8f\xa2\x0b\x85\x1e\xde\x85\x87\xff\x63\x3d\xed\x47\xbe\xdd\xa7\x60\xd8\xc1\xdb\x7d\x76\xaf\xa3\x90\x92\x7f\x41\x66\xbf\xa4\xfd\x7b\x23\x0a\x01\xe9\x49\x68\x68\xf0\x4f\xc0\x0f\x36\xa4\xd0\x0e\x0c\x05\x82\x26\xc3\x4d\x28\x8e\x78\x77\xbb\x7f\x0b\xc3\xb5\x86\x04\x52\x8a\x6c\xf7\x6c\xff\xa3\xb6\x25\xd7\xba\xf3\xfa\xcf\x15\x14\x2f\x96\xa3\x51\x78\x32\x5b\xe2\x49\x3c\x59\xa8\x59\x16\xcb\xc7\x1c\x87\xff\x0b\x2d\x42\x42\x08\x40\x11\xfa\xfc\x67\x44\x58\x31\xc6\x84\xd7\x8c\x29\xe1\x3b\xc6\x05\xe1\xf1\x1a\x0a\x3f\xfb\xdc\xf6\xab\x58\x7f\x60\xc1\x50\xe0\x78\xa8\x66\x0a\xd1\xbc\xce\x75\x1e\x12\xe6\x9b\x59\x84\xd9\x70\xc9\x69\x3d\x39\xab\x93\x5d\x84\x84\x09\x93\x2a\xc2\x3e\x63\x44\x78\x87\x31\x26\x5c\x32\xa6\x84\x9f\x18\x17\x84\x17\x8e\x4c\x85\xf3\x78\xb2\x05\x13\xeb\x14\xc3\x90\x70\xc6\xa8\x08\x07\x8c\x11\x65\xb1\x36\x8c\x09\x7c\xd0\xc3\x94\xf0\x29\xe3\x82\xf0\x89\x55\x26\x44\x1f\x2b\xbc\xc6\x77\x78\xbc\x0d\xa7\x37\xbc\x3d\x0a\x09\x03\x46\x45\xb8\xc3\x18\x11\xba\x8c\x31\x61\xc6\x98\x12\xbe\x67\x5c\x10\x9e\x5a\x92\x09\xf6\xf1\x0e\x2e\xf1\x13\x5e\x6c\x43\xa7\x33\x1c\xe0\x08\x0a\x9f\xe2\x93\x3a\xdd\x38\x24\x9c\x33\x2a\xc2\x87\x8c\x11\xe1\x16\x63\x4c\x48\x18\x53\xc2\x71\x2d\x16\x06\xb8\x83\x2e\x66\xf8\x1e\x4f\xb7\xa1\xdd\x39\x3e\xc4\x2d\x24\x38\xae\x93\x4d\x42\xc2\xf0\x06\xd1\x59\xd6\x6d\xd8\x08\x09\x66\x19\x6f\x46\x32\x6e\x6a\x32\x24\xfc\x0c\x4c\x14\xe1\x2e\xff\x1d\x11\xde\x63\x8c\x09\x4b\xc6\x94\xf0\x0b\xe3\x82\xf0\x99\x25\xf9\x19\x77\xf1\x1e\x96\xf8\x05\x9f\x6d\xc3\x4b\xbf\xe3\x23\xfc\x86\x14\x3f\xe0\xf3\x3a\xdd\xeb\x34\x24\xfc\xce\xa8\x08\x1f\x31\x46\x84\xdf\x18\x63\x42\xca\x98\x12\x7e\x60\x5c\x10\x3e\x37\x74\x17\xdb\xd0\xe9\x09\xee\xe1\x7d\x44\xf8\x02\xcf\xea\x74\xf3\x90\x70\xb1\x89\xd7\xb1\x8b\x11\xee\xe3\x03\xc4\xf8\x16\x5f\x36\xe8\x08\x4f\x32\x54\x84\x7b\x8c\x11\xe1\x7d\xc6\x98\x10\x31\xa6\x84\x2f\x18\x17\x84\x67\x96\x4e\xe0\x01\x76\xb6\x61\xe6\x8f\x75\x92\xb3\x90\x30\x62\x54\x84\xfb\x8c\x11\xe1\x03\xc6\x98\x10\x33\xa6\x84\x6f\x19\x17\x84\x2f\x2d\xc9\xaf\xd8\xc3\x2e\xa6\x78\x8e\xaf\xea\x74\x49\x48\x59\x4f\x4d\x14\xe1\x01\x63\x44\xd7\xf4\x9e\x5d\x7c\x8c\x47\x90\x78\x89\x3f\xf1\xcd\x36\x4c\x5c\xe0\x10\xb7\xf1\x0a\x7f\xe1\xeb\x86\xb1\x5c\xc0\x7e\xdc\xec\x24\x4f\x10\x40\xe3\x0d\xfe\xc0\x69\xc3\x58\xa6\xfb\x95\x51\x11\xf6\x18\x23\xc2\x2e\x63\x4c\x98\x32\xa6\x84\xe7\x8c\x0b\xc2\x57\xd8\x52\x2f\x6c\x68\xc1\xf1\xf9\x31\xa3\x22\x3c\x62\x8c\x88\xe7\xb4\x84\x03\xea\x25\x63\x4a\xf8\x93\x71\x41\xf8\xe6\xbf\xa5\xc5\x65\x48\x58\x30\x2a\xc2\x21\x63\x44\xb8\xcd\x18\x13\x5e\x31\xa6\x84\xbf\x18\x17\x84\xaf\xdb\x29\xb6\xa0\xc5\x32\x24\x9c\x30\x2a\xe2\x09\x0f\xcb\x88\xb2\x91\x6f\x19\x13\xde\x30\xa6\x84\x3f\x18\x17\x84\xd3\x76\x8a\xcd\x3f\x65\x8a\xb7\x1c\xe0\x77\x3b\x19\xc7\xf1\x30\x9a\x23\x9d\xab\x39\x92\xa1\xc2\x38\x9c\x4e\xa3\xc9\x39\x5f\x26\x9e\xc5\xe1\x04\xc7\x71\xfa\x46\x25\xde\x1c\x4f\x67\x4a\xf1\xad\x07\x4f\x86\x6a\x16\x5f\x28\x85\x41\x3c\x49\xb0\xd8\xef\xed\x1d\x74\x72\x65\xf8\xd9\x43\xee\x1a\xc5\xc5\x29\x4c\x96\xd3\xe8\x34\x1c\xf5\x26\x2a\x11\xc2\xbd\x9d\xdd\x96\xf2\xd7\x2e\xd4\x72\x1c\x4e\x1f\x5e\xfd\x1a\x4f\x9b\xe6\xb5\xce\xad\x5b\xd9\x6b\xdd\x9b\x08\xdd\x8e\xbd\x3a\x74\x3b\x76\x00\xef\x76\xec\x18\xcf\x82\x30\xab\xed\x48\xdd\xe5\x47\xd9\xac\xcf\x42\x1f\x9e\x11\x2c\x65\x43\x60\x29\xbb\x94\x74\x3b\xf6\x7e\x90\x09\x7d\xcf\x3d\xc9\xbe\x92\x5a\x3a\x4d\xf8\x26\xc3\x8f\xec\x65\xa2\xdb\xd1\x52\xea\xda\x13\x2b\xb0\xde\x12\xa8\x30\x41\xd7\x77\xe3\xb7\xb5\x5c\xbb\x3a\x7f\x12\x38\x4d\x44\xc3\x4a\x6e\x75\x37\xb0\x52\x5a\x26\xed\xbe\x73\x82\x30\xc2\x91\xc8\xf6\xb3\xab\x29\xfb\x4e\xc0\x78\x50\x3b\xca\x5c\xb0\x17\x9a\x0a\x37\x6e\xc6\x6d\x09\x84\xb5\x49\xaf\xac\x25\x1a\x5a\x6a\xcb\x9d\x5b\xb9\xce\xa6\xc2\x4b\xa2\x64\x65\x63\x91\x49\xfa\x35\x3e\x59\xcb\x2d\x02\x2b\xd8\xcb\x62\x79\xb5\xce\x5c\xa8\x2b\x42\x16\x97\xac\xb7\xe0\x9f\x35\x67\x59\x17\xa4\x09\x1d\xe6\xce\xd2\xb9\xee\x41\x91\x56\x9e\x48\x5e\x9f\xaf\xe6\x47\x7d\xc6\x00\x26\x16\xa0\x8d\xe0\xfb\x5e\xb6\x3a\x0b\x1d\xab\xb7\x30\x8b\x78\xb7\xa3\xcc\xf1\xb5\x88\x45\x20\x35\x5a\x4e\x47\xdb\x03\x0f\x9c\x20\xb4\x3b\x1d\x5d\xf3\xa0\x08\x72\xe3\x82\xdc\x4a\xde\xf6\x48\xf3\xc6\xb2\xe6\x6f\x17\x30\x02\xd6\x00\x18\x03\x76\x4c\x80\x57\x56\x67\x21\xc4\x87\x22\xb5\x8d\x4a\x68\x9b\xd7\x25\x2b\x5d\x5e\xb9\x88\x45\x20\xf3\xdd\x8c\x6e\x7d\x99\x47\x95\xf3\xa0\x49\x06\x4b\x29\x9d\xe0\x54\x62\x3b\xbb\x2d\xc1\x70\x65\x9c\x5c\xb1\xba\x2d\x62\xa5\x94\x79\x54\xb9\x23\x64\xb7\x18\xc1\xd6\x3a\x7d\x45\x36\x64\x01\x5e\x11\x2a\x11\x2b\x02\x7b\x3a\x7d\xcd\xfb\x16\xa1\x2b\xc0\x02\x02\x2d\x8d\x95\x10\xab\x55\x80\xf2\x59\x00\x58\xad\xaa\xa7\x6b\xab\xae\x39\xc2\xbc\xfe\xda\xd7\x5c\xf2\xba\xc2\x74\x24\x70\x24\x6a\x51\xf5\x48\x1e\xd6\x0d\x70\x27\xd0\x7a\x96\xd2\x93\xf5\xea\x73\x54\xaf\x3e\xcd\x60\xe2\xd7\xd9\xdc\x40\x1b\x81\xd3\xd2\x5a\x59\xf2\xa0\x08\x2a\xea\x9a\x74\x96\x19\x77\xe0\x49\x51\x8e\x13\x54\x4e\x67\xbd\xde\xf6\x51\xdf\x25\x98\x2f\x1b\x05\x51\x96\x6a\x6c\x1e\xb1\x41\x5e\x5a\xf5\xbb\x4e\xa8\x5a\xe9\xea\x89\x09\x6f\x0e\x2f\x59\x04\x93\xb4\x4f\x38\x3d\x0a\x2b\x4d\x41\xd9\xe1\x7b\x80\x97\x9d\x6f\x50\x38\x31\xcf\x7b\x81\xbc\x55\xe5\x0d\xc2\x65\xb0\xd9\xbc\xdc\x7c\x38\x27\xf2\x0d\xa4\x0d\x0d\x4b\x5f\xb0\x3b\xf2\x32\x77\xbd\x3a\x14\xdc\xe6\xb5\x9e\x6d\x8c\xd5\x12\xe4\x59\x4a\x97\x24\x9e\x7b\xbf\xd2\x7c\x72\x37\xae\x56\x8d\x56\xb5\x5a\xbf\x5a\xb7\x97\x09\x2d\xcb\xcd\xc7\xf8\x84\x8d\x0c\x8c\x07\x02\x78\xe5\xc6\x56\x4e\x89\x46\x63\x63\x47\xef\x16\x1e\x6f\x34\xb6\xcc\x83\x3a\xb0\x65\xd5\x04\xa0\xf5\x89\xce\x7c\xc2\x42\xb5\x74\x6a\xdf\x77\x1e\x6c\xf4\x15\xdf\x2f\x4a\xe7\x9a\x71\x49\xba\x71\xa9\xda\xd8\xac\x95\xe8\x67\x56\xea\xec\x81\xed\x70\x9e\x29\x13\x32\x4f\xa0\x52\x2d\x08\xa4\x75\xa5\x40\x60\x2a\x9f\xb6\xe9\xc6\x86\xba\xe4\xb4\x8d\x2d\x9f\x56\xac\xd0\xcb\x9f\x04\xa5\xd3\x59\x3f\x76\xf8\xb7\x7d\x7b\x96\xba\xe1\x6f\xd7\x22\x9d\xd0\xf7\x5b\xd2\x2d\xf7\x97\x77\x6d\x43\x66\xa5\x5d\x36\xd8\x39\x53\xd7\x3b\x1c\x33\xcb\x40\xae\x19\x21\xfd\x47\xd5\x27\x87\x5a\x4a\xaf\xd0\x44\xda\xc6\xd6\x67\xc7\x65\xe5\xdd\x0e\x12\xb0\x65\x59\xba\xb2\x5c\xa4\x79\xe0\x0a\x96\x08\xbc\xea\x6e\x79\x0c\x5e\x39\x76\x08\xed\xd9\x2c\xd6\xb5\xe6\x73\x45\xce\xbb\xaf\x6a\x56\x56\x7b\x7c\x26\x88\xd2\xfb\x95\xb2\xdc\xcf\x1b\xaa\x8b\xaa\x4c\x73\x33\x76\x48\xd1\xa8\x10\x87\x0d\x0f\x3a\x7f\x17\xc5\x50\x56\x8b\xf0\xce\xa1\x2e\x0a\x75\xbd\x69\x36\x56\x73\x52\xad\x1b\x24\xa4\x3b\x9d\xbc\x21\xe7\x82\xfd\xe7\xff\xac\xb2\x05\x2d\xa3\xaf\xf4\x65\xb7\xd3\x0f\x4a\x71\xa2\x1b\x15\xa2\x5e\xf2\xd9\x70\x8d\x75\x25\xbf\xae\x77\x4f\xef\xec\x66\xe6\xee\x6a\xaf\xde\x7c\xca\x83\x84\xae\x9b\x6b\x93\x48\xea\x52\x7c\xdb\xea\xe3\xf6\xd5\xbe\xef\x57\xaa\x4f\x29\x2f\xdb\x3c\x58\x12\x7a\xe6\x98\x39\xc0\xbb\xdd\x8e\xaf\xfd\xf5\x31\x98\x4f\x0d\xa5\x81\x53\xba\xa6\x89\xea\xfc\xa1\x77\x5d\xf5\xca\xab\xa6\xd1\x5b\x3a\x4a\x6d\x4a\x9c\x11\xf2\xd3\x31\x0e\x6f\xbd\x98\xec\x68\x53\x0f\x4a\xd7\xa0\xbe\xf4\xd0\x72\x96\x99\x73\xcc\xff\xd8\x64\xb9\x67\x07\x09\xae\x91\xb6\xb2\xd5\x07\x4e\x0d\x72\x27\xe0\xe5\xd5\x7e\xed\x90\x22\x65\x50\x54\xc6\x7a\x4f\x93\x05\x77\x90\x3b\xa7\x56\x3e\x5b\xae\x48\x04\xe8\x15\x99\x91\xdb\xdd\x64\xab\xf5\xbf\x5d\x6f\x5b\xff\x2b\x5d\x4a\xf7\xd7\x5e\x91\x84\xd5\x44\x98\x79\xcf\x38\x49\xd6\xb8\xbd\x55\xbd\x7e\x4b\x37\x72\x94\x2f\x3d\xf6\xbb\xfa\x5d\xde\x8d\xce\x42\x16\xd5\xbe\x34\x70\x9a\x9c\x15\x45\xad\xd3\xa8\x55\xb6\x96\x2b\xa9\x1b\xc5\x44\x31\xfc\xe4\x27\xdf\xd2\xa5\x84\x2d\x5a\x22\x1f\x21\x77\x3c\xb1\xb6\xcf\x3b\x4a\x2b\x1c\xe5\x73\x55\x7e\xb5\x2b\xaa\x5e\xcb\x2d\xb9\xe8\x52\x2d\xfe\xae\x09\xff\x8f\x72\xe7\xbe\x6e\xf5\xdf\x36\x5a\xfd\xf7\x8d\x56\xff\x73\xa3\xd5\xff\xda\x68\xf5\xbf\x37\x5a\xfd\x8f\x7c\xf5\x7f\x02\x00\x00\xff\xff\xeb\x2c\x6b\xe6\x17\x20\x00\x00") + +func fontsTsalagiFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTsalagiFlf, + "fonts/tsalagi.flf", + ) +} + +func fontsTsalagiFlf() (*asset, error) { + bytes, err := fontsTsalagiFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/tsalagi.flf", size: 8215, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsTwopointFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x53\x51\x8b\xe3\x46\x0c\x7e\xd7\xaf\xf8\x08\x86\xc4\xdc\x26\xde\x84\x2d\xdc\x1d\x47\x99\x96\xb6\x0f\xfd\x05\x07\x6b\x98\x4e\xec\x71\xec\xae\x3d\x93\xda\x63\xb2\x0b\xae\x7f\x7b\x91\xc6\xde\x6c\x5f\xee\xc1\x41\xd2\x48\x9f\x3e\x7d\x52\xaa\xb6\x3a\x99\x04\x27\x9c\xf0\x19\x8f\x38\x3e\x51\xb8\xf9\xab\x6f\x5c\xc0\xf9\x0d\xbf\xf6\x63\x61\xf1\xa7\x79\xb1\x37\xf3\x86\xdd\xf5\xfc\x77\x34\x95\xb3\x63\x67\x9c\x3b\x8c\x37\x13\x6c\xdf\x7a\x7f\x28\x4c\x4a\x7f\xf8\x1e\x55\x73\x69\x6d\x40\x6f\x5b\x6b\x06\x8b\xd3\xe1\x91\x7e\x33\xc1\x7e\x05\x8e\x5f\xbe\x3c\xe1\x97\xf1\x82\xe3\x91\xe8\xf7\xd7\x6b\x6b\x9c\x09\x8d\x77\xf0\x15\xaa\xa6\x1f\x02\xda\xc6\xd9\xaf\xc4\x94\xb0\xc7\xa6\x33\x97\xa6\x80\x1b\xbb\xb3\xed\x37\xa8\x04\xbb\xb5\x68\x4a\xeb\x42\x53\x35\x85\x14\x93\x01\x80\x3d\x86\xda\x8f\x6d\x09\xd3\xde\xcc\xdb\x80\xb3\xc5\x5f\x66\xfb\x20\x45\xce\xdf\x28\x89\x49\xa1\xb6\xd8\xd4\xa6\x2f\xcf\xad\x71\x2f\x1b\xec\xf7\xb8\xf6\x8d\x0b\x03\xcc\x00\x03\x89\x3e\xe0\x3c\x06\x14\xc6\x6d\x03\xc3\x0c\xdd\x38\xd4\xb6\xa4\x53\x44\xa8\x6d\x73\xa9\x03\x33\x36\x28\x6a\xd3\x9b\x22\xd8\xfe\x87\x8f\x0f\x70\x3e\xa0\x71\x45\x3b\x96\x8d\xbb\xa0\xb4\x43\x61\x5d\x69\xfb\x81\x3e\xc7\xb2\xce\xbc\xca\xe4\x68\xad\xbb\x84\x1a\x3b\xfb\xba\x26\x17\xbe\xeb\xac\x8b\xc2\x0c\x29\x3d\xc6\x82\xd2\x56\x66\x6c\x43\xe4\xd6\xf9\xd2\xca\x9c\xa1\x6e\x06\x54\xde\x05\xec\xda\xe6\xc5\x62\xb3\xef\x70\xfc\x69\x03\xef\x04\xc6\xb8\x52\x60\x52\x3a\x3e\x09\x4a\x14\x96\xd9\xfe\xaf\x0b\x51\x92\x28\xfe\x14\x4d\x8a\xbc\x52\xb4\xdd\x2e\xfe\xa7\x4f\xf2\x29\xda\x4d\xb3\x22\x3d\xa5\x4a\x91\xcf\x14\x65\x9c\x05\x0f\x45\x3b\xfd\x5d\x29\x4a\x15\x71\x7a\x36\x2b\xca\xb5\x52\x34\xe7\x8a\x74\xa6\x14\xe5\x13\x67\x4f\xb9\x52\x94\x4c\x89\xa2\x79\x9a\xd9\xe4\x0a\x69\x41\xf3\xe2\x33\x60\xc2\xb9\x82\x93\x2b\xca\xb9\x7c\x3b\x71\x1d\x03\xa6\x8a\x32\x41\xce\x14\x69\x2e\xce\xee\x70\xc2\x8d\x63\xc8\x84\x51\xba\xe4\x09\xd6\x8e\x4b\x63\x6c\x37\x33\x9c\x44\x7d\xec\xe8\x23\x91\x4c\x11\x33\xdc\xef\xe5\x63\x87\xb2\xa5\xa9\xe7\x6c\x68\xc6\x35\xa9\xf4\x9a\xe2\x0f\xff\xa6\x8a\x26\x9d\x2e\x0c\x26\x2d\x46\xce\x16\x57\x3f\xcf\x8a\x9e\xf5\xfa\x18\x79\x6a\x7e\x94\x5a\xcd\x30\x98\xa2\xe6\x93\xc8\xc3\x02\xb3\x9f\x29\x12\xc1\x78\xc0\x08\x9a\x67\x92\x1d\xd3\x73\x88\x93\x4f\x22\x38\x2b\x25\xed\x22\x9b\x19\xf7\xe8\xf7\x7b\x34\x97\xe9\x17\x95\x58\x34\xd9\x46\x64\xb0\x30\xca\x81\x4c\x51\x92\x67\x31\x0e\xee\xc6\x6e\x0c\xe4\x99\x6c\x65\x31\x92\x55\x60\xfd\x71\xf6\x9c\xaf\x28\x97\x06\xcb\x28\xbc\x47\xb9\x23\xde\xb4\xe6\x9c\x9d\x22\x66\x98\xe8\x84\x97\x12\x95\x48\x56\x15\x13\xcd\x41\x31\xa6\xf5\x99\x63\xff\x4a\x8c\xfb\xc4\x7d\xc7\x3d\x7e\xa8\x16\x61\xfc\xa2\xa3\x5f\x75\xe4\x97\x6f\x77\x81\x0f\x1a\x4b\x32\xa2\xfb\x5e\xb9\xb0\x91\x45\xa6\x52\xc8\x07\xbf\x5c\xde\x41\x2f\x11\x66\xa2\x79\x3c\x3d\xe9\x55\xbf\x04\xc9\xaa\x1f\x8f\x28\x37\x9b\x00\x62\x46\x27\x51\xf4\xf3\xb7\x75\xe1\x91\x33\x77\xcb\x3e\x8c\xa4\xef\x1c\x67\x26\xad\x65\x48\xae\x17\x7c\x45\x7e\xf6\xeb\xcd\x89\x19\x17\xfe\x0f\xae\x6b\x6f\xaf\xfd\xaa\xd7\x62\xca\x1f\x15\xfe\xfd\xdc\xe4\x0c\xc0\xd1\xff\x02\x00\x00\xff\xff\xf1\x79\xae\x0d\xff\x05\x00\x00") + +func fontsTwopointFlfBytes() ([]byte, error) { + return bindataRead( + _fontsTwopointFlf, + "fonts/twopoint.flf", + ) +} + +func fontsTwopointFlf() (*asset, error) { + bytes, err := fontsTwopointFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/twopoint.flf", size: 1535, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsUniversFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3b\x7b\x8b\xe3\x38\xf2\xff\xfb\x53\x14\x22\x90\x59\x7e\x9e\x66\x7b\x76\x7e\xa0\x59\x96\x25\xdc\x83\xa3\x0f\xfa\xf0\x3f\x77\x60\x96\x63\x2c\x47\x4e\x77\xb8\xb4\x33\xe4\xb1\x3b\x73\x9f\xfe\x90\x54\x25\x95\x6c\xd9\xb1\xd3\x0f\xc6\x0d\xb1\xaa\xac\x47\xa9\x54\x2f\x95\xd4\x9b\xdd\xe6\x83\x5a\xc0\xed\x2d\x7c\x82\x8f\x3f\xc2\x4f\x1f\xe0\xf6\x63\xf6\xcf\x76\xfb\x7b\x73\x38\x42\xfd\x0d\xfe\xb1\x3f\x3c\xa9\x56\xc3\xbf\x9a\xed\x6e\xd7\x9c\xbf\xc2\x2f\xed\xef\xae\xb8\x6a\x9e\x0e\x37\x6b\xf5\x6b\xb6\xd9\x3e\xec\x9a\xd3\xf6\xbf\x8d\x36\x0d\xfe\xb6\x6b\xda\x16\xfe\xfc\xa8\xbe\x7c\x69\x76\x3b\xf8\xe5\xe1\x61\xbd\x3a\x6f\xcf\xeb\x9b\x46\x9f\x7f\x85\xbf\xab\xf6\xac\x0e\xdf\xe0\xf6\x43\x0e\xb7\x9f\x3e\x7d\xcc\xfe\xa2\x4e\xcd\xcf\xf0\xff\x70\xaf\x0e\x0e\x91\xfd\xf5\xeb\x97\x9d\x6a\xd5\x69\xbb\x6f\x61\xbf\x81\xcd\xf6\x70\x3c\xc1\x6e\xdb\x36\x3f\x67\x86\x58\x78\x0f\xe2\x49\x3d\x6c\xd7\xd0\x9e\x9f\xea\xe6\x20\x60\xb3\x3f\xc0\x66\xbb\x6b\x60\xab\x9b\xf6\xb4\xdd\x6c\xd7\xb6\x71\xa6\x00\x00\xde\xc3\xf1\x71\x7f\xde\x69\x50\xbb\x3f\xd4\xb7\x23\xd4\x0d\x54\x6a\x99\xdb\x46\xed\xfe\x8f\x6c\xe1\x2a\x9d\x1e\x1b\x10\x8f\xea\xa0\xeb\x9d\x6a\xff\x23\xe0\xfd\x7b\xf8\x72\xd8\xb6\xa7\x23\xa8\x23\x28\xb0\xd8\x1c\xea\xf3\x09\xd6\xaa\x5d\x9e\x4c\x37\xc7\xa7\xf3\xf1\xb1\xd1\xd9\xed\xad\xed\xe1\xb1\xd9\x3e\x3c\x9e\x0c\xc5\x0a\xd6\x8f\xea\xa0\xd6\xa7\xe6\x90\x7d\x82\xe1\x8f\x39\xb4\xfb\x13\x6c\xdb\xf5\xee\xac\xb7\xed\x03\xe8\xe6\xb8\x6e\x5a\xdd\x1c\x8e\xd9\xc7\x1f\x6d\xb3\x27\xf5\xd5\xce\x1c\x76\x4d\xfb\x70\x7a\x84\x77\xcd\x57\xaa\xbc\xde\x3f\x3d\x35\xad\x63\xcc\xf1\x07\xf8\x3f\x50\xb0\x39\xeb\x87\x06\x36\x6a\x7d\xda\x1f\xb2\x9f\x3e\xd8\x1e\x74\xb3\x51\xe7\xdd\xc9\x11\xfb\xb4\xd7\x8d\x9d\xf8\xe9\x71\x7b\x84\xcd\xbe\x3d\x65\xb7\x1f\x6d\x35\xc7\x4a\x43\x5f\xd4\x6f\x66\xd8\xb3\x58\x3d\xe7\x77\x95\x19\x0e\xac\x32\x29\x0d\x6a\xe8\x57\x08\xf3\xab\x54\xc0\xb8\x56\xf6\xd7\xbd\xa8\x17\xdf\xcc\xb7\x74\x8d\xc1\x0c\x67\xdb\x5c\x53\xf0\x63\xd0\x48\x60\xfa\xb7\x3f\x8b\x04\xa8\x94\x94\xca\xfd\x38\x22\xa4\x14\xee\xc7\xcd\x63\xec\xeb\x78\xcf\x3d\x32\x38\xe8\x60\x09\xb6\xae\xfd\xac\xb4\x34\x4f\xad\x60\x01\xab\x4c\x4b\x61\xbf\x0a\x59\x9b\x91\x4a\x99\xf3\xca\x55\x29\x95\xf9\xcb\x69\xa4\x4a\x48\xf3\x57\xe7\xc4\x3f\x53\xb9\xa2\xb6\xca\x82\x4a\x16\xf6\xab\x28\xed\x40\x85\xb0\x03\x75\xc9\x48\x50\xd9\x99\x48\xae\x74\xad\x72\x07\xe5\xda\xad\xe1\x1d\xc0\x9d\x44\x84\xeb\x57\x6c\x6a\x5d\x2c\x3d\x22\xf4\xed\x11\x84\x62\x08\x87\xb2\x08\x00\x1c\x67\xb1\xca\x10\x01\x80\xe3\x98\x11\x05\x36\xc0\x71\x16\x49\x52\xfb\xa8\x2e\xce\xc2\x34\x12\xc1\x34\x0c\xc1\x42\xba\x31\x18\x7d\xb2\x06\x14\xdb\x1b\x3b\x4d\x28\xeb\x5c\xde\x59\xca\x0a\xd7\xb3\x94\xd2\x92\x65\x16\xc5\xb4\x29\xcc\x6a\xb8\xb5\x73\xdc\x87\xb2\xee\x93\xdd\x83\x99\xca\x00\x68\xd7\xa5\x7b\x83\x53\x36\x20\xe1\xbf\xbe\x60\xc7\x50\xa8\xac\xdd\x31\xdc\x1b\xf5\x1e\xa2\x82\x91\x4a\x27\x80\xae\x64\x9a\xdb\x12\x72\x8d\x4d\x6f\xb5\xca\xa4\xc2\x66\x56\x2e\x6d\xb3\x0a\x79\x02\x24\xab\x40\x5c\x65\x85\x1c\xe5\xd6\xbe\x8d\xfc\xd9\x37\x58\x19\xe0\x82\x35\xb0\xb8\x31\x7c\x27\xad\x2f\x51\x66\xad\xec\x77\x51\xd6\x79\xae\xad\x32\x58\x6b\x60\x94\xdd\xea\x3c\x2a\xbc\xd1\x76\xab\xf4\xa8\xf1\xb9\x2e\x96\x55\x59\xd3\xc4\xef\x9c\x20\x0a\xdf\xdf\x85\xf1\xc7\xa4\x31\x05\x29\xc5\x35\x53\x7a\x3d\x55\x68\x95\x38\x99\x81\x48\x5e\xd3\x92\x27\x52\xfa\x3d\x0a\x11\x38\xe3\x8d\xc4\x80\xc0\x95\x43\x49\x92\x82\xdb\xc3\x68\xce\xf3\xcb\x0a\x1f\x9a\x35\x9f\xf3\x8c\x7e\x10\x98\xf3\x92\xe4\xae\x82\x58\xd3\x6b\x6c\x9d\x35\xd7\x02\x23\xc3\xdc\x56\xe9\x88\x37\xee\xa3\x6f\x1f\xdb\x49\xff\xd1\xc1\xdc\x66\x1a\xe2\xc2\xc7\xf9\x72\x07\xc1\x0e\x5a\xd9\xf7\x96\x30\x97\x85\x58\x1a\xe7\x42\xea\x9d\x93\x71\xf3\x7a\x6e\x3d\x1e\x3e\xde\x9f\x77\x30\x46\xb7\xfd\x84\xdd\xf4\x2b\x69\x5d\x48\xae\xc8\xca\x18\x21\x2d\xbd\x5b\x4a\xd9\xee\x04\x26\xa0\x82\xd0\xa3\x81\xa6\xb5\x62\xcb\x35\xbf\x14\x0f\x9b\x88\x2c\xd0\x67\xa3\xdf\x25\x2f\x45\xf2\x8f\x0b\x42\x7e\x77\xe1\x7c\x1d\xf9\xdd\x85\xf9\x10\xf4\x52\x45\xeb\xdb\x5d\xde\xf0\xf4\x5c\xc6\x05\x9f\x7d\x0d\x95\x4a\x91\x17\xb7\xa0\xf0\xeb\x4f\x95\x59\x54\xe2\xda\x4a\x1e\x59\xc8\x84\x3f\xbe\x18\x59\x30\x1d\xd1\x51\x00\x65\x16\x93\x21\x6c\x2c\x10\x10\x18\x1a\x10\x22\x44\x0a\x92\x9c\xd6\x10\xef\x7a\x61\x5a\x32\x6e\x4b\x21\x7a\x53\xe3\x23\x80\xd7\x80\x85\xff\x0a\xf0\xf9\xf3\xe7\xcf\xde\x7b\x2a\x59\x14\x45\x81\xcb\x51\x14\x8e\x60\x72\x80\xb4\xea\xce\x6e\x94\xce\x5d\x8d\xc4\x6e\x53\x39\x6c\x40\x27\x08\x18\x54\x81\xb4\x71\x8b\xe9\xd2\x89\x05\xd5\x44\xbe\xe5\xda\xd4\xae\x6b\x54\x73\x57\x19\xa9\xf4\x3a\x8e\xe1\xdf\x8b\x51\xd9\x59\xb1\xef\xdf\x74\x26\x03\x77\xe0\x2a\xd2\x63\x8d\xf1\xdc\xc4\x1a\x23\xaf\xc2\xc5\xed\x93\xda\x5e\xbf\xf8\x43\x54\x4a\x1e\xb3\xa2\xed\x43\xbd\x26\x33\x0a\xa2\xb0\x0f\x59\x0c\x62\x97\x23\xcb\xc5\xb7\x8e\x48\x13\xdc\xa1\x19\x5f\x4e\xde\x04\x4d\x74\xb8\x8b\xc5\x44\x2f\x3c\xf2\xa6\x66\x14\x34\xcc\x8f\x58\x3c\x56\x49\x1f\x77\xa8\x50\x5f\x49\x6f\xd1\x55\x10\xb3\x55\x26\x30\xf8\xc5\x0e\x3c\x88\xe1\x99\x03\xa9\x6b\x0b\x26\x07\x4d\x2d\xee\x38\xd4\xd1\x25\x12\xf4\x45\xe2\xdb\xe4\x3e\x47\xa0\x0e\xd5\xd7\x4f\x7b\x1e\x7b\x27\xb2\xea\xa2\xb6\x0a\x41\xa3\x17\x9e\x94\x5c\x71\x8d\xd3\x52\xa4\x02\xeb\x4e\xb4\xde\x09\xd7\xe7\x1a\x41\xaa\x63\xc2\x23\xe3\x2b\xd0\x66\x93\xf1\x82\x1b\xf5\xa4\x6e\x14\x31\xcc\x08\xad\x0d\xd5\xa4\xf9\x16\x82\xb0\x1b\xa3\xd5\x56\xb3\x03\xce\x25\x28\x96\x41\x79\x0d\xee\x4f\xd6\xe5\x62\x2c\xe6\x16\x4d\x48\xdb\x9f\xa4\x7d\x11\x54\xd6\x6e\xd9\x47\xa3\xa6\xbb\xf9\xfb\x18\x3c\x19\xa2\x8d\x4c\xce\x3e\xba\x8e\x76\xfe\x8e\xc3\xb2\xee\xac\xac\x96\xcb\xca\x23\x69\x1d\x96\xe8\x8d\x3c\x4e\xcb\xd2\x90\x57\x22\x72\x65\xf7\xb2\x44\x9f\xdf\x72\xda\x86\xee\xa1\xdd\x27\x43\xf1\x8d\xe8\x10\xcd\x23\x93\x0b\x3a\x85\xf2\x45\x8e\x52\xc4\x7e\x33\x27\xee\x3b\x8e\xa2\x67\x93\x92\x68\x8d\x42\xeb\x8e\xcf\x55\xd4\x56\x5e\xed\x64\x83\x70\xc5\x92\xe5\x5c\x3c\xd2\xca\xb9\x42\xfb\xff\x0b\x08\x8a\x07\x3d\x02\x4a\xa9\x6e\x0c\x74\xe3\x35\x0a\xfd\x43\x29\x96\x89\x0d\xf3\xe5\x60\x2b\xe6\x71\x1e\x13\xe2\x48\x8f\x28\xeb\x06\x2c\x89\x5d\x4a\x1f\x51\x70\xc4\x0d\x79\x36\x1a\xd6\x91\xfe\xcc\x40\xd1\x67\x4c\xa3\xaf\x1d\x10\x77\xba\x04\x06\x45\x4b\x55\xee\x80\xcf\xd8\x30\xbc\x21\x95\xc3\x91\xd7\x1b\xcb\xb0\x9f\x2d\x93\x61\xe4\x1d\x93\x61\x19\xc9\x70\x52\xf7\xa6\xc8\x30\xa7\xa3\x2b\x7d\x43\x30\x59\x5f\x82\xbd\x61\x9b\xd8\xbe\x33\xa9\x51\x8a\x27\xa6\xfa\xfb\xbf\xa1\xb3\xc1\x20\x25\x1e\xff\x79\x90\x94\x79\x14\xa6\x96\x03\x8b\x32\x16\xa4\x44\xcb\x11\x54\x1d\xac\x95\x66\xa9\x4f\x03\x31\xb1\x36\x83\x2e\xd9\x16\x4f\x4a\x21\x5d\x36\xd4\xc1\x85\x4d\x91\xd4\x21\x63\x0a\x2e\xda\xce\x63\xfb\x54\xa6\xbc\xcd\xe5\x3d\xc7\x2c\xb5\x7a\x1e\x78\xb5\x1d\x09\x5d\xd4\x0c\x0e\x99\x99\x9a\xe3\x10\x19\x32\x45\x5a\x2e\xbd\x60\x11\xd6\x68\x73\x10\x67\x87\xb5\x1a\xce\x64\xdc\x60\x9d\xd6\x73\xc1\xaf\x6c\x32\xbe\xab\x0d\x15\x5a\x87\x94\x4a\xa4\x66\x38\x30\x4f\x3e\x9b\x90\x77\xaa\x23\x98\xe6\xd0\x25\xbf\x43\x79\x87\xe8\xba\x4b\xaf\x8c\xb5\xb9\x4a\x2d\xcb\xd4\x6c\x5f\x64\x3b\xfb\xc6\x33\x8e\x8b\xfa\x6e\x74\x30\xdb\xc7\x0c\x28\x65\xee\xe3\x28\x00\x7a\x61\xc0\xdc\x6c\x5f\x60\xfb\xb3\x63\xad\xf8\x6c\x23\xf4\xfc\x72\x7e\xea\x2d\x98\x6d\x0c\x4b\x97\xd9\xa5\xec\x33\xbb\xec\xed\x2c\xdf\x90\xd9\x91\x35\xf5\xc1\x3b\x93\xee\x38\x76\x4b\x05\xe2\xd7\xa7\x39\xa2\x7c\x25\x3b\x45\x35\x0f\x3b\x45\x65\xe1\x37\xd5\xab\x5e\x3a\x19\x33\x94\xe3\xea\xee\x16\x5f\x1b\x1e\xa2\xf7\x65\xe2\x95\x79\x70\x6f\x9f\x30\xba\x4d\x98\x60\xe1\x0c\xcd\xb1\xdf\x81\xf8\x24\x82\x1f\x45\x70\x8c\x13\x04\xe6\x71\xc8\x3c\x05\x7f\x13\xb6\xba\xe4\x6d\xf8\xe1\x9a\xf3\x35\x31\xa7\x2b\xb9\x4c\x26\x2b\x86\x51\x49\xd7\x43\xd5\xef\x58\x8c\x4a\x05\x3c\x7d\xe6\xb3\xa9\x3b\x33\x15\xd8\x2c\x97\xac\xe4\x8f\x6d\x5d\x77\x05\x2b\x91\x56\xf8\x89\x47\x2c\x40\xa6\x28\x50\xd6\x72\x51\x89\x33\x47\xa1\x4d\x73\xa5\x98\x49\x64\xed\xaa\x1e\xb3\x92\x53\x1e\xfe\x94\x10\x56\x76\xdc\x84\x26\xd1\xe5\x33\x83\x41\x34\x55\xf8\x3c\xc8\x5a\xb2\xfc\x02\xcf\x2d\xd8\x73\xaf\x70\xda\x8d\xb6\xda\x5b\x2c\x76\x28\x76\x85\x3b\x9e\x42\xb0\x45\xe4\x61\x4d\x40\x48\xa5\xa2\xf3\xef\x4a\x76\x58\xfc\xba\xe6\x60\x20\x2e\xcc\x23\x18\x43\x66\x84\x7d\x00\x6d\xe1\x10\x4e\x83\x3d\x69\x8c\xee\x80\x70\x68\x74\xbc\x21\x82\xbb\x9b\xd7\x17\x28\xc4\x43\xa7\x57\x71\xc1\xe1\xaa\xa4\x0d\x01\x11\x29\x64\x27\xdd\x55\x15\xbe\x0a\xf6\x27\xa2\x94\x96\xa9\x12\xc4\x0e\x1f\xe1\x2f\x4d\x80\xaf\x32\x8f\x29\xa9\x5b\x16\xd7\x14\x86\x98\x12\x65\x41\x73\x49\x1b\x23\x77\xde\x51\x88\x92\xce\x3b\xee\xbc\x7b\xbe\x8b\xb2\xd3\xe0\x2f\x74\xbd\x0a\xc8\xe1\xee\xf7\xef\x03\xee\xc8\x7b\x60\x70\xf2\xee\x0c\x84\x2b\x10\x5e\x50\x66\x17\x46\x77\xcc\xa3\x50\xae\x74\x51\x94\x25\x1e\x2b\x62\x0a\x1d\x65\xd2\x7e\xb3\x19\xec\xb0\x5f\x27\x23\x61\x42\xdf\x5a\x17\xa2\x2f\xbd\xe3\xfb\xf5\xd9\x5b\xd8\xdc\xd0\x47\x39\x22\x3a\xc9\xc4\xe4\x79\xef\x24\xd3\xdd\xd6\xc2\xe3\x07\x13\x32\xd7\xb5\x8d\xd5\x67\x46\x79\xb3\x20\xc7\x41\x64\xa0\x22\xa5\x70\x14\x90\x6b\xb0\x8b\x25\xa4\x72\xe4\x29\x0a\x92\x88\xba\x79\x0c\xf4\x45\xd9\x3f\x13\xef\x83\x48\x1e\x2e\x1b\xd2\x57\x95\xb8\xa6\x75\x54\x99\x28\xa4\x9c\xcc\xf0\x22\xbf\x22\x03\x8b\xcf\xe6\x41\xfa\x8a\x82\x5d\x13\x12\xb4\xbe\x57\x33\xd0\x16\x15\x4d\x8f\x1f\x43\x7b\x5f\x71\x7f\x2f\xe5\xfd\xfd\x3d\x2c\x22\xec\x84\x62\x7f\xf0\x91\xa5\x9b\x04\xd2\xd2\xe9\xab\x96\xae\xe4\x4b\xa7\x14\x57\x5e\x7b\x6f\xc0\x7e\x36\x9a\xf1\x26\x1a\xda\xd9\x39\x24\xc1\x51\x76\x38\x78\x15\x5d\x54\x0e\xdb\xff\x79\x59\xcd\xd8\x1d\xf6\x0d\xf0\x1c\x6f\x9a\x7b\x6f\x6a\xb8\xd9\x3d\x43\x65\xcc\xba\x00\xd0\xd5\x19\x0b\xe4\xfe\xd8\xd4\x38\x91\xdf\xc0\x67\x26\xcd\xb2\x2a\x96\x86\xac\xfa\x49\x81\x18\x88\xd9\x36\xfd\x37\xc5\xb6\xb1\xf5\xb9\x0a\x6b\x65\xc7\x4c\xc8\x48\x7a\x57\x84\xdc\x89\x68\x4f\x92\xd8\x7b\x26\x76\x06\x65\xcf\x53\x5c\x59\xa7\x54\xa2\x7a\x25\x95\xb8\x96\x4a\x6e\x77\x81\x79\x2e\xa4\x32\xec\x3f\xb9\x79\xa1\x93\x7d\x32\x2f\xb3\x5d\xeb\xcb\xf0\x72\x62\x00\x20\x2b\x4e\xe5\xa8\x1d\x7b\x5b\x53\x0d\x09\x53\xbd\x9c\xe0\xce\xaf\xf7\xb2\x9c\x8f\x41\xc5\x4a\xbe\xcd\x4a\xf0\xa5\x0b\x8d\x8c\x30\x62\x83\x46\x80\xc8\xf7\xdf\xc9\xdf\x20\xd8\xe3\xca\xf8\x28\x12\x4e\xcb\xb1\x7f\x63\x96\x24\xc8\xde\x45\xc3\xd7\xfd\x60\x2d\xb6\xee\xbb\xef\x49\x5e\xdf\x6f\xe5\x6c\x7a\x2b\x1a\xfd\xe5\xbc\xfe\x2c\xf3\x10\xd4\x32\x16\xa5\xd9\x01\xdb\x7c\xb5\xc4\x62\x9c\x9a\x8b\xd3\x72\x51\x4a\x2e\x8f\x32\x36\x42\x26\x2f\xb5\x5f\xa2\x32\x5d\xeb\x2a\x2c\xcd\x40\xd7\x89\x89\x68\x49\x6f\x36\x1f\xbc\xc8\x12\x4f\x8b\xae\xb2\xc4\xf9\x28\xcc\x29\x95\x45\x72\x92\xe3\x94\x3d\xdb\x5e\xda\x12\x5a\x22\x97\x81\xc0\x3b\x94\xb6\xf2\x0f\x52\xca\x77\x6c\x47\x2f\xc0\xdf\x60\x44\xdb\x9a\x4c\x49\x7c\x5f\xe2\x53\x4a\x19\xdf\x18\xe5\xd9\x33\x1d\x92\x92\xd7\x19\xa5\x7e\xb6\xca\xdd\x22\x73\xc6\xc3\xdf\x8e\x8c\xfe\x17\x6a\x28\xc3\xd5\x37\x4a\x4a\xfb\x5a\x32\xcc\x29\x69\x73\x30\x67\x68\xbb\x7f\xe7\x67\x28\xd8\x1d\xa9\xc9\xa6\xea\x52\x1c\x38\x1e\x4a\x23\xf1\x74\x36\x83\x8b\x22\xa3\x80\xb9\x5f\x0c\xff\x57\x64\xc5\x0e\x3b\xd2\x21\xad\x98\x6c\x96\xcb\x70\xfb\x1b\x6f\xb0\xf5\x34\xe5\x3a\x84\xd2\xb2\xc6\xff\x5c\x50\x21\xdb\x21\x44\xc9\xae\xf5\xd3\x83\xac\x7c\x3e\x62\x95\x25\xff\xbe\x27\xf4\xff\x02\x00\x00\xff\xff\xaa\x8c\x6e\xd1\x7c\x3c\x00\x00") + +func fontsUniversFlfBytes() ([]byte, error) { + return bindataRead( + _fontsUniversFlf, + "fonts/univers.flf", + ) +} + +func fontsUniversFlf() (*asset, error) { + bytes, err := fontsUniversFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/univers.flf", size: 15484, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsUsaflagFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x58\x4d\x6f\xe3\x36\x13\xbe\xf3\x57\x4c\x16\x3a\xec\x02\xaf\xb4\x51\x36\xc9\x26\xc4\xab\xc2\x01\x82\xd4\x8b\x6e\xdd\x00\xe9\x02\xbd\xd2\x32\x2d\x73\x23\x93\x86\x48\x27\x48\x7f\x7d\xa1\x6f\x0e\x45\xdb\x72\xd0\x4b\x01\x3b\x88\x38\xa6\x86\x0f\x67\x9e\xe1\x8c\x46\x5e\xe6\xcb\x0b\x16\xc0\x35\x5c\x41\x7c\x03\x61\x0c\xf1\x2d\xd9\x6a\xb6\xcc\x59\x16\x2d\xf3\x25\x84\x21\xc4\xf1\xe7\xeb\xcf\xb7\x97\x84\x3c\x88\x2c\xe7\x06\x52\x25\x5f\x78\xa1\x85\x92\x30\x7f\x83\xdf\xb8\x34\x30\x63\x5a\x73\x09\x1f\x9f\xb9\x34\x72\x92\xbe\xcd\x79\xa1\x37\x2c\xe5\x91\x2a\xb2\x4f\x30\x67\x9a\x2f\x40\x49\x30\x2b\x4e\x96\x4a\x1a\x58\x70\x2d\xb2\x72\x39\x25\xe4\xae\x30\x22\xcd\x39\x5c\x5c\xdf\xdc\x80\x5a\x42\xc1\xd3\x88\x15\x46\x47\x4c\xa7\x42\x50\xf2\xc8\xcc\x8a\x82\xe4\xaf\x3a\x12\x66\x11\x6d\xd7\x22\x5d\x45\x7c\xb1\x3d\x4b\x19\x97\x67\x7a\xa3\x54\x1e\xad\xb7\xd5\xcc\x4a\xbd\xe6\x4c\x2e\xa2\x82\x6b\xa3\x64\xc4\xa4\x8e\x24\x37\x67\xd5\x5a\xbd\x29\x84\x34\xb9\x90\xcf\xd5\x9c\x66\x7a\x25\xd6\x22\x7a\x7d\x65\x51\xaa\xd6\x67\x52\x99\x70\xa9\x8a\x70\xcd\x44\x4e\x1e\x0a\xb5\xa6\xb0\x10\x5a\xf3\x7c\x22\xb7\x52\xa4\x91\xac\x76\x80\x8f\xf7\xec\x45\x2c\xe0\x29\x82\x6f\xe5\xcd\x4f\x64\xc6\x5f\x75\x56\xa8\xed\x46\x53\xc7\xf2\xff\xb1\xdc\xd4\x52\xc8\x0a\x43\x9e\xb6\xf3\x9f\x3c\x35\x14\xbe\x0b\xc9\x29\xfc\x78\xba\x83\x87\xef\x77\xbf\x42\xc9\x07\xb9\x67\x86\x53\xb8\x86\x99\x7a\x81\xf8\xf6\xf6\x12\xe2\x2b\x7a\x79\x43\xcf\x63\x08\xcf\xaf\xcf\xcf\xc9\x1f\x45\xc6\xa4\xf8\x9b\x19\xa1\x24\x85\x59\x35\xb2\x1c\x7e\x48\x51\x45\xc2\xbc\x91\x12\x55\x53\xf8\x7a\x41\x9e\xb8\x5c\xf0\x82\xc2\x5c\xcd\xd9\xa4\x71\x8f\xdc\x6d\x36\x85\x7a\xe1\x0b\x67\xfa\x77\xae\x35\xcb\x78\xf8\xed\x9e\xc2\xff\xbf\xdc\xfe\x14\xdb\x55\xf0\x1c\x5f\x4c\x32\x96\xad\x79\xcb\xcd\x2f\x64\x36\xfb\xf3\x31\x7c\x54\xda\x08\x99\x85\x53\xa5\x0d\x05\xa4\x41\xfe\x2a\xf8\xd2\x17\x23\x37\x98\x55\x8c\x11\x2f\x34\xbe\xfa\xfa\xe5\x86\x84\xe8\x43\x02\x00\x08\x26\x23\x86\x09\x09\x92\x24\x71\xae\x00\x80\xe4\xea\x0b\x24\x49\x39\x0b\x95\x54\xdf\xe8\x70\xfc\x42\xad\x9d\x54\xff\x35\x5e\xfd\x19\x39\x0f\xed\xa7\x06\x9a\x26\xd3\x46\x7d\x0a\x53\x68\x4c\xe9\x54\xa7\x30\x6d\x00\x5a\x3d\xb4\x38\x81\xde\xe8\xd6\xaf\x72\x6d\xb3\x3f\xb4\x1e\x03\x24\xee\x62\x4a\x69\xa7\x40\x29\xad\xb0\xac\xdd\x5b\xda\x3a\x38\x7b\xde\x71\xa1\x56\xad\xf1\x03\xcf\xb5\x59\xdd\x00\x0e\x86\xce\xf2\x36\x24\x68\x16\x0d\x16\x85\x15\x6a\x69\x78\xcf\x6b\xe9\x51\xef\xbc\xc5\x7e\x6d\x7b\xef\x07\x0c\x62\x51\xc3\xf5\xce\x82\x03\xb4\xe3\x2e\x5a\x0c\xee\xb5\xb5\xbc\xa1\xa7\xd7\x0f\xb0\x88\x4c\xf5\x29\x74\x62\x29\x07\xc3\x4b\xbd\x34\x98\x38\x27\xa1\xf7\x12\x3b\x8f\x4f\x87\x7b\x26\xea\x35\x2d\xb3\xad\xea\x40\x6c\x39\xb5\x58\x6c\x20\xba\xab\x3f\x03\xdd\x7d\x1c\x83\x13\xcb\x4e\xf0\x92\x63\x41\x00\xf6\x18\x59\xd4\xed\x9b\xf8\xce\x7e\x7b\x1f\xfb\x89\x76\xf2\x8b\xd8\x85\x16\xc1\x32\x75\xdc\xfe\x88\x67\xe4\x29\x8c\xe5\x79\x87\xb1\x16\x85\x38\xd6\x3b\x20\x9c\x68\xc3\x3b\xac\xf0\x43\xb8\xb6\x59\x39\x68\xe7\x8d\x7d\x80\x6d\xa9\x3d\xcf\x41\x9f\x4a\xb6\xdc\xb0\x3b\x38\xf4\xc3\xf2\x87\xd3\x15\x85\x72\x32\x26\x11\x0f\xa4\xe7\x88\xbd\x7c\x36\xf5\xfb\xdb\x84\x7b\x93\x01\xe0\xc3\x87\x6e\x59\x57\xa7\x87\x10\x7d\xd0\xac\x74\x6d\x4d\x6f\x0f\x01\x38\xfa\x70\x38\x9e\x16\x01\x3b\x6a\xc1\x58\x08\x18\x40\x1c\x38\xdb\x38\x3d\x3c\xa2\x7b\xd6\xde\x51\xc9\x8e\xb5\xc2\x89\xe6\xc1\x22\x35\x1a\x62\x4f\x92\xa2\x5a\x01\xde\xd0\xe2\xdc\xf3\x85\x76\x7f\xcd\x1b\x15\xda\xc3\xb5\xbd\x54\xae\x55\xb0\xd4\xaa\x1e\x53\x98\x51\x27\x65\xbb\xed\x56\x27\x17\xa2\x6f\x6b\xf6\x1e\x9e\x03\x61\xeb\x59\x6f\xb6\xb5\x0c\xc0\x49\xe5\xfb\x06\x30\x48\xad\xde\x35\x8b\x74\x9b\xff\x61\x28\xde\x7b\xa8\x8f\x2a\xd8\x83\xf2\x31\xe6\xb1\x61\x63\xd8\x27\xd2\x26\xb6\x7f\x10\x25\xc3\xc6\x71\x94\x2d\x07\x83\x8d\x73\xe3\xc8\x2e\x20\x41\x01\xd9\xd9\xe4\x79\xda\xbd\x9d\xe9\x74\x54\x2c\xf6\x43\xe0\x75\xbe\xc2\xdf\xf1\xef\xe0\xb8\x60\x6e\x75\x48\xec\xce\xb0\x09\x1b\xee\x87\xf7\xda\x08\x4e\x74\x0f\x26\x24\x4a\x69\x27\x46\x87\x68\x46\x19\x8a\x5a\xdb\x71\x9d\x22\xaa\x6f\xfe\xb1\x5f\xe3\x3c\xcd\x93\x9e\x74\xcb\xb8\x61\xe3\x39\xdc\x0d\x3d\xfc\xad\x71\xb0\x5b\x13\x82\xc0\x4b\xe0\xae\xf7\x00\xe7\x95\x60\xb4\xb2\xbf\xaf\xe9\x5f\xdf\xec\x36\x6b\xf8\x12\x77\xea\x0e\x46\x58\x71\xea\x0e\x4e\xdd\xc1\xa9\x3b\x38\x75\x07\xa7\xee\xe0\x3f\xd1\x1d\x58\x5b\x36\x46\x0e\x26\xa1\x7f\xb4\xef\xb9\x02\xfa\xf5\x12\x03\x39\x93\x96\x6a\x7d\xbb\x54\xdb\xfb\x93\x73\x27\x4c\x88\xf5\xf7\x6f\x7f\xf9\x27\x00\x00\xff\xff\x82\x85\xbc\xdc\xf4\x19\x00\x00") + +func fontsUsaflagFlfBytes() ([]byte, error) { + return bindataRead( + _fontsUsaflagFlf, + "fonts/usaflag.flf", + ) +} + +func fontsUsaflagFlf() (*asset, error) { + bytes, err := fontsUsaflagFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/usaflag.flf", size: 6644, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsWavyFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x59\x5b\x6f\xdb\x3a\x12\x7e\xd7\xaf\x98\x07\x01\x95\x81\x75\x64\xd1\x97\xd8\x6f\x56\x64\x26\xd1\x56\x91\x7c\x24\xb9\x4d\x00\x01\x6c\x4e\xeb\xb4\x06\x12\x7b\x91\xe4\x14\x28\x90\x1f\xbf\xe0\x4d\x22\xa5\xa1\x77\x03\x38\xb6\xc5\x99\xe1\x5c\x3e\xce\x0c\xc7\x4f\xcf\x4f\xe4\xd1\x87\x19\x4c\x21\x9a\xc0\x04\x16\xe0\x7d\x7d\xfc\xfd\x07\xfe\xfe\x03\x57\xaf\x87\xc7\x23\x7c\x7e\x3d\xfd\x84\x68\x12\x4e\xe6\x5e\x7a\xfc\xfe\xfc\xcf\x8f\xfd\x1b\xa4\x55\x01\xd9\xe3\xfb\xe1\x38\x8e\xbc\xa7\xc3\xcf\xe7\xfd\x3b\xbc\xee\x9f\xf7\x8f\x6f\x7b\x20\x17\xe4\x82\xc0\x78\x0c\x93\x39\xfc\xfb\x9f\x67\x20\x93\xc9\xdc\xdb\xee\x5f\x5f\x0e\x6f\x6f\x87\xd3\x11\x0e\x6f\xf0\x6b\xff\xba\xff\xfb\x0f\xfc\x3c\xfc\xde\x1f\xe1\xfd\x04\x2f\xa7\x1f\x87\xa7\x3f\xf0\xfe\xeb\xf0\x06\x4f\xa7\xe3\xfb\xbf\xe0\xf1\x0d\x9e\x4f\xc7\x9f\xfc\xfd\xfd\xd7\xde\x13\x04\x87\xfd\xeb\xa7\x37\x38\x3e\xbe\xec\xb9\x8c\xff\x3c\x3f\x7e\xdf\xff\x80\xd3\x11\x1e\xe1\xfb\xe9\xe5\x65\x7f\x7c\x87\xe7\xc3\x71\x7f\xe1\x79\xbe\xbf\x36\x5f\x6b\xcf\x87\xb5\xf7\xe1\xaf\xbd\x93\x2f\x3e\xaf\x3d\x10\x4f\xf8\x23\xf1\x09\xe4\x43\xfe\x27\xbe\xb2\x90\x85\xcc\x5f\x7b\xe3\x70\x1c\x8e\xc5\x13\xb1\x22\x89\xf8\xf7\x20\xfd\xe6\xaf\xbd\x8b\x74\xe4\xab\x27\xe2\x6d\xed\x9d\x42\x7f\xed\x85\x27\x5f\x8b\x64\x9c\xb8\xe1\x54\xc1\xbd\x24\x35\xb4\xe1\xef\x92\x95\x73\x05\x62\x9f\xa6\xa5\x6a\xc4\x77\xce\x1a\x4a\x42\xa5\x22\xff\xc2\x1a\xa1\x1e\x84\x92\x08\xac\x45\x9f\x7d\x88\x45\xff\xc3\x5c\x54\x9b\x09\x17\x84\x7e\x6b\x88\xcf\x98\x36\x41\x1b\x62\x52\x76\x96\x09\x1d\x4d\x4d\x18\x7f\xf7\x82\x0b\xa9\x42\xc3\xa4\x2b\x5a\x5f\xf0\xc5\x30\x10\x6f\xc0\x46\x72\x13\x69\x18\xeb\x0c\x63\xad\xb5\xe2\xa1\x90\x21\x05\xf9\x86\x41\x21\x0b\x14\xbf\xb9\x07\x13\x2c\x23\x29\x8d\x99\x81\x50\x9a\x49\x82\x9e\x66\xea\xa1\x94\x14\x18\x56\x83\x58\x08\x04\x71\x80\x8a\x53\xbe\xb6\xc4\x69\x3f\xb5\xbe\x32\x1f\x84\x3a\xd8\xdc\x75\x8d\x05\x3d\xe1\xf5\xf1\xb8\xb5\x54\xc0\x44\xb2\x78\x1d\x70\x84\x96\x27\x13\xa0\x4c\xe9\x1f\x02\x13\x8b\x01\x04\x4c\x01\x87\x31\xa6\xe2\xaa\x48\x84\xa2\x21\x84\x16\x44\x14\xff\x48\x2e\xb2\x5e\xd4\xb4\xf0\x6f\xc2\x09\x17\x0a\xf9\xbe\xc5\xa9\x22\xd7\x17\x2b\x22\x34\x52\x4e\x64\x3d\x4e\x73\xd1\x07\x90\x06\x81\xbd\x27\x13\x7b\x72\x1b\x0c\x85\xc0\xd0\x36\xd0\xf1\xb2\xc5\xc2\x48\x38\x34\xb0\xf6\xd4\x7e\x92\x2c\x4d\xdf\x4e\x89\xe8\x91\xd8\x2c\xb4\x61\xa5\xb7\xd4\x86\x18\xe7\x5b\x2f\x35\xa1\x54\xa7\xd5\x67\x40\x00\x0e\x02\x6d\xab\x04\xd9\xb9\xc8\x48\x2f\xf1\xff\x18\xe7\xbd\x96\x8b\x70\x42\x2f\x27\xa8\xd5\x80\x89\xa8\x5e\x70\x57\x68\x47\x69\x4f\xb5\xf6\xfa\x3a\x34\x3a\x1b\x8a\x3d\x43\x44\x5b\xe9\xc2\x06\xc4\x22\x34\x83\xc5\x76\xfd\xbe\x25\x69\xa9\xa0\x0d\xbe\xd8\x54\x04\xc1\x3a\xf4\x22\x64\x23\x99\x74\x3a\x85\xa4\xa2\x61\x9b\x37\xf4\xe9\xe4\xc9\x94\x67\x54\x66\x9c\x26\xd0\xf9\xb3\xb1\x33\x0c\xf0\xbc\xcb\x3e\x3a\x76\x71\x3c\x9b\x5e\x1d\xd0\x1f\xbb\xb3\xda\x9d\xd0\x2e\x69\xab\x52\x21\x81\x12\x58\x85\x40\x24\x0c\x30\xc3\xd2\x62\x40\x31\x71\x9e\x7e\x9e\xd3\x67\x9a\x05\x48\x56\x07\x4b\x5c\xc0\xcc\x6a\xa4\xf3\xe3\x68\xa0\x44\x9b\xbc\x82\x2e\x79\x0d\x35\x04\x2c\xa5\x05\x5d\x4a\x03\x95\x85\x02\x9d\xa4\xdb\x32\x08\x12\x3c\x8d\xb1\x71\x9b\xb8\x02\xbb\xb2\x2a\x0b\x65\xd6\xee\xf6\x84\x81\x33\x47\x7d\x3b\xec\xe4\xdc\xcb\x0d\xb6\x5b\xce\x5b\x0f\x52\xf5\x36\x04\x23\xa3\x9c\x75\x71\xe9\x1b\x29\xab\x97\xca\x2f\xa6\xdb\x95\x0f\xac\xd8\xb7\xa8\x69\x6c\x44\x1b\x89\xc0\x1b\xb1\x16\x13\x28\x57\xd0\x18\x41\xd2\xb1\x42\x23\xc8\x98\xa2\x19\xa9\x33\xce\x74\x05\x10\x28\x17\x80\x37\x52\x98\x6e\x3c\xd4\x4b\x9c\x89\x96\x46\xd1\x9b\x06\x86\x4d\xd8\x6f\x0e\xe0\xc4\x44\x77\x83\x57\x17\xbd\x88\x26\x38\x38\x81\x5a\x0d\xa5\xdf\xc2\xce\x40\x4e\xa0\x96\x19\xf8\x9d\x53\xc5\xc9\xd5\x0b\x03\x0c\xa8\x05\x18\x70\xf4\x8a\x95\x9d\xe1\xa3\xc5\x04\x20\x2f\xc6\x57\x25\x8d\x3f\x43\xb5\x8d\x13\x3a\xec\x18\xa3\x45\x04\x90\xe6\x5f\x68\x59\xd3\x0d\xd0\xfb\x24\x8b\xef\xe2\x3a\x2d\x72\xb8\x8b\xcb\xcf\xed\x21\xf9\xd0\x87\x24\x5a\x10\x80\x84\xe6\x35\x54\xe9\x4d\xae\x7d\xf6\x21\x55\xe6\x89\x57\x7c\xe6\x74\x53\x80\x6d\xb1\xcb\x37\x9a\x90\xa9\x13\x2c\x88\x4e\xba\x53\x52\xc4\x33\x80\x64\x57\x96\x34\x4f\x1e\x4c\xc1\xdf\x4e\x9f\xfc\xb5\xf7\x49\x64\xf4\x96\x76\x0e\xf0\x40\x73\x4d\xa6\x00\xd2\x48\xf4\x8e\xc7\xa1\xec\x36\x3a\xd1\x0b\x80\xab\xb2\xf8\x4c\x73\xb8\x8a\xcb\x16\x1a\x9f\x34\x34\xa2\xc5\x25\x40\x45\x13\x61\xb3\x94\xd9\x9e\x8e\x40\xf7\x69\x9c\x6c\x09\xb0\x49\x63\x5a\xd2\x2a\xad\xda\x88\x74\xc7\xa3\xdd\x6f\x05\x90\x14\xdb\x87\x32\xbd\xb9\xad\x5b\x81\x5c\x58\x32\xea\x83\x2c\xba\x9c\x00\x5c\xd3\xbb\x34\x4f\x73\x0a\x45\xb9\x49\xf3\x38\x83\x34\xdf\xa4\x49\x5c\x17\xa5\x85\x91\xb1\xb2\x4b\x31\x46\x00\x19\xbd\xae\xc7\xdb\x22\xcd\xeb\x34\xbf\x81\x4d\xb1\xbb\xca\x28\xc4\xf9\x4d\x46\xe1\xaf\x5d\x51\x1b\x51\x14\xc0\x09\x45\x77\xd6\xd5\x89\xe8\x92\x70\x78\x58\x81\xd4\xdd\xc4\x87\xb9\xd5\x14\xa0\x2a\xae\x6b\xb8\x7d\xd8\xde\xd2\x5c\x78\x90\x99\x05\x22\xba\x9c\x01\x94\xf4\x26\xad\x6a\x5a\xd2\x8d\x65\x73\x89\xd8\x3c\x07\xb8\x8b\x93\xb2\xc8\x55\xa5\xb3\xaa\x10\x27\x58\x00\x6c\xe8\x4d\x49\xa9\x14\x55\x74\x9b\xe9\x0d\x2f\x01\xb6\xd9\xae\x1a\xdf\xa5\xf9\xae\xb2\x0c\x50\x47\x9c\x99\x06\x2c\x01\xaa\xdd\x96\x96\x55\x52\xa6\xdb\x1a\xea\xaf\x85\x47\xc4\x7a\xfb\xe2\x54\xab\x1e\xd5\x6d\x49\xa9\x37\x1d\xec\xbd\x9c\x00\xc4\xc9\xae\xa6\x10\x27\xfc\x1c\xe8\x56\xd6\x24\x89\x00\xee\xd2\xa4\x2c\x0c\x8c\xf6\x9b\xbc\x50\x25\x83\x68\x49\x00\xb6\x69\x96\x94\xc5\x57\xed\x39\x81\x3f\x79\x69\xfb\x30\x23\xb1\x9c\x72\xb9\x9b\x4d\x46\x61\x53\xd4\xe6\xdd\x45\x6f\xcc\x8f\x11\xdd\xa4\x59\x16\x9b\x2a\x79\x95\x88\xf7\x72\x6e\x5b\x58\xe4\xd4\x8b\x86\xca\x2f\x78\x78\xaa\x64\x97\xb9\x30\xd9\xa5\x27\x1b\x93\xcb\x4b\x00\x81\xfa\xff\x13\x94\xa2\x0e\x34\x1a\x99\x5a\xc8\x12\xe0\xcb\x2e\xbb\x89\x4b\xb8\x2e\x63\x79\x2a\x8b\x9c\x33\xc7\x65\x4d\x4b\x09\xe5\x48\x34\x47\x33\x83\x6b\x85\x73\xdd\xc6\xd9\xb5\xc9\x42\x3a\x96\xd5\x64\xc8\x22\x62\xae\xb7\xaa\x24\xe3\xb4\xbf\xd7\xca\x4c\x98\x7f\xed\x68\xd5\x33\x49\x64\x06\xa3\xe9\x89\x56\x04\x20\x8b\xeb\x34\x87\x24\xde\xa6\x75\x9c\x41\x46\xeb\x9a\x96\x10\xc3\xd7\xb4\xbe\x85\x9b\x32\xfe\x42\x3d\x50\xfd\x2c\x5a\x70\xa2\xd5\xf4\xbc\x0c\x81\x48\x9e\x64\x43\x67\xd1\x8a\x56\xb3\xf3\x32\x92\xb4\x4c\x76\x77\xd7\x19\xbd\xf7\x00\x64\xaf\xe8\x10\x34\x3f\x2f\xa8\x4e\xb3\x0d\xe5\x97\xf6\x73\xca\x2c\xce\xcb\xe8\x52\xed\xd9\x4a\x1c\xad\x2e\xcf\xcb\x29\x39\x0c\xe3\xab\x42\x78\xb8\x38\xe7\xe1\xa5\x4b\x10\x95\xf7\x51\xa6\x94\x10\xf8\x0f\x21\x6c\x2f\x7f\x1a\xff\xab\x95\x43\x42\xa2\xfc\xab\x4e\x26\x7e\xfd\xac\xa4\x1e\x64\x32\x71\x48\xa1\x16\x5a\x58\xe3\xbe\x88\x92\x49\x74\x5e\x86\x42\x8b\x9c\xfd\xb8\x64\xb8\x50\x4b\x87\x68\x61\x12\x2d\x0e\x41\x2e\xe8\x52\x57\xa4\x1d\x72\x5c\xf0\x4d\x31\xc7\xa0\xb7\x65\x32\x71\x21\x37\xc5\x1c\xe3\x90\xe1\x42\x6e\xea\x74\x8c\x43\x90\x0b\xba\xa9\xcb\x31\x7d\x39\x0a\x31\x2e\xe4\xd2\xfa\x56\x77\x88\x4c\x0f\x42\x2c\xd0\x93\x89\x0b\xb2\xb9\x75\x92\xf5\x51\x76\x5d\xf8\x49\xe4\x02\x6d\x81\xa6\x38\xac\x6d\x26\x91\x0b\xb4\x05\x9a\xe2\x70\x19\x2e\xd0\x16\xee\x14\x87\x0b\x72\x81\xb6\x40\x53\x1c\x2e\xc3\x05\xd8\xc2\x99\xe2\x70\x39\xbc\x61\xda\x65\x75\xba\xcd\x78\x0d\x6e\xfb\x54\x4e\x74\x6f\xd6\x7f\x12\xb9\xa0\xa9\x76\xac\x6a\xde\x08\x77\x09\x48\xce\x77\xc2\xde\x76\x2e\x58\xee\xf0\x58\x22\x53\x13\x12\xb9\x20\xb9\xb3\x63\x09\xa1\xef\x96\xe1\xc2\xe6\xee\x4c\x2c\x31\x41\xc4\x05\xce\xdd\x20\x0e\xff\xeb\xea\x46\x88\x0b\xa4\x0f\x96\x61\x82\x1b\x19\xed\x10\xe2\x02\x68\x7d\x5b\x94\x79\x6f\x96\xd2\x1b\x21\x12\xd2\x82\xb2\xba\x8b\xb3\x96\xb5\xba\x8d\xcb\x2d\x54\xdd\x08\x4c\x0f\x1d\xba\xfb\xa0\x3a\xa6\x64\x86\x0a\xb0\xfb\x90\x46\x0d\x30\xfa\x77\x4d\x42\xe6\xe7\xb8\x4d\xcb\x51\xee\xc5\x39\x6e\x33\x98\x32\x96\x98\x88\xcb\x73\x22\xe4\x91\x54\x27\x12\xe3\x5e\x9e\xe3\x1e\x5c\xed\x30\x09\xab\x73\x12\xcc\x4e\xa3\x70\x79\x61\x3a\xc1\x45\x50\xe3\x47\x19\x3d\x3c\x02\xd6\x0e\xc1\xf4\x18\x8c\x4c\x23\x94\xbf\xdf\x61\xf8\xf6\xf0\xad\x92\x7b\x13\x94\x97\xf6\xa3\xef\x1c\xc2\x91\x29\x0e\x40\xbb\xab\xd0\x7d\x15\x2e\x01\x47\x20\xd2\x53\xe8\x9f\x7c\x98\x1a\x61\xdb\x62\x70\x28\x22\x1d\x85\xba\xa7\xe3\x52\x70\x48\x5a\xfd\x84\xaf\xc6\xa1\x22\x88\xd2\x8d\x38\x0a\xad\x0e\xc2\x57\x3f\x86\x18\x5c\x38\xfa\x90\x9e\xc1\xd7\x93\x5a\x63\xae\x48\xa6\x38\xf4\x86\x9d\x82\xb8\x14\x9e\x7a\xdc\x33\x1c\x75\xa2\x3f\x80\x7b\x1f\x19\xc9\x6a\x46\x1c\x6e\x39\x76\xe2\xfc\xfe\x48\x93\xcc\x70\xc0\x15\x58\xba\x19\xcc\xbc\xc8\x0c\x07\x5b\x81\xa5\x1b\x84\x1b\x07\x1a\xd2\x07\xa8\x74\x63\x8a\x90\xf0\x98\xe1\x20\x2b\x5c\xc6\xf7\x14\xc0\xc1\x35\xa8\xfd\xce\xa1\x1f\x99\x5d\x02\x6c\xd2\x2f\x69\xd5\x4d\xa6\xc4\x74\x5a\xdd\xba\x4f\xc6\x50\x85\xcc\x70\x78\xf5\xeb\xbe\xe1\xad\xd0\xda\x0a\x87\xd7\x0e\x89\xd4\x70\x08\x49\xe6\x38\xbc\x76\xfd\xb4\xe0\xe0\xc6\x31\x86\x54\x79\xd5\x4c\x23\x22\x70\xa0\x0d\xea\xbb\x73\x8e\x4a\xe6\x38\xd8\x1e\xd0\xcc\xd6\x8e\xc3\x8d\x41\x35\x99\xe3\x80\x93\x75\xbd\x1d\x6e\xcb\xec\x6a\x96\x77\xce\x8a\x03\xed\x01\x53\xdf\xa9\x80\xfe\xfb\x6f\x00\x00\x00\xff\xff\xa7\x48\xc0\xee\xe6\x20\x00\x00") + +func fontsWavyFlfBytes() ([]byte, error) { + return bindataRead( + _fontsWavyFlf, + "fonts/wavy.flf", + ) +} + +func fontsWavyFlf() (*asset, error) { + bytes, err := fontsWavyFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/wavy.flf", size: 8422, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _fontsWeirdFlf = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x57\x4f\x8f\xa3\xb8\x17\xbc\xfb\x53\x94\xfa\xc7\x4f\x49\x66\x1a\x3c\x3d\xa3\x9e\x43\x9f\xd0\x4a\x7b\x5c\xad\xb4\xb7\x95\x90\x1c\x07\x4c\x60\x9b\x3f\x2d\x20\xdb\xdd\x92\x3f\xfc\x0a\x3f\x07\x42\x62\x02\x73\x08\x0e\x50\x2e\xbf\x57\xcf\x2e\x9b\xb4\x48\xbf\x4b\x0f\x3f\xf1\x8c\xa7\x6f\xf8\x86\xa7\x1f\xec\x5d\xe5\x4d\x12\xa4\x45\x8a\xed\xbf\xaa\x69\xf3\xba\xc2\xf7\x1d\x3b\x7c\xbe\x00\xbf\xc9\x16\x7f\xa8\xfc\x1f\xd5\x00\x28\xcd\x9f\x30\xaf\xd2\x3a\x78\xcf\xab\xa0\x3b\xa9\xa0\x2a\x00\x1c\x64\x1b\x26\xb2\x54\xaf\xc1\x6b\x97\x05\xad\x62\x69\xfe\xa1\x12\xf4\x0c\x7f\x7d\xca\x0a\x7f\xd7\xa7\xf8\x15\xc0\x67\xdf\x86\x71\x1b\x9c\x1a\x75\xcc\x2b\x19\xc4\x92\xb5\x75\xa9\xd0\xbe\xa9\x38\x97\x05\xe2\x4c\x36\x32\xee\x54\xd3\x62\xf3\xbf\xff\x7f\xd9\x40\x75\x71\x00\xd9\x28\x54\x75\x87\x52\x76\x71\x96\x57\xc7\x47\x74\x99\xfa\x34\x8f\xd3\xa6\x2e\x51\x77\x99\x6a\x90\xd6\x55\xd7\x06\xec\xf7\x8f\xb7\x42\x56\xb2\xeb\xb3\xa8\x53\xa4\x79\xd3\x76\x28\xf2\x4a\xbd\xb0\x3e\x75\xf8\x78\x28\xe5\x31\x8f\x51\x9d\xca\x83\x6a\x1e\x90\xd6\x0d\xd2\xbc\x50\xc8\x13\x55\x75\x79\x9a\xc7\xa6\x33\x93\x00\xe0\xa3\xcd\xea\x53\x91\x40\x16\xef\xf2\xb3\xc5\x41\x61\x2f\x37\x8f\xa6\x53\x55\xbf\x33\x8f\x40\x5d\xa6\xf0\x90\xc9\x26\x39\x14\xb2\x7a\x7d\x80\xef\xe3\xad\xc9\xab\xae\x85\x6c\x21\x61\x9e\x3e\xe2\x70\xea\x10\xcb\x6a\xd3\xf5\x34\x6d\x79\x6a\x33\x95\xb0\x9f\xc4\x90\xa9\xfc\x98\x75\x7d\xc4\x72\x54\x81\x3d\xdf\x79\xf9\x68\x34\xc9\xab\xb8\x38\x25\x79\x75\x44\xa2\xda\x58\x55\x89\x6a\x5a\xf6\xfd\x9b\xe9\x56\xca\x0f\x93\x39\x0a\x55\x1d\xbb\x0c\x5b\xf5\x71\x06\xc7\x75\x59\xaa\x8a\x84\x69\x77\xf8\x0a\x89\xf4\x94\x1c\x15\x52\x19\x77\x75\xc3\x9e\x9e\x0d\x43\xa2\x52\x79\x2a\x3a\x0a\xb6\xac\x13\x65\x12\xef\xb2\xbc\x35\x72\x63\x5b\xe4\xaf\x0a\x0f\x7e\x89\xa7\xe7\x07\xd4\x95\xe1\x95\x55\x62\x78\x77\xec\xe9\x87\x61\x21\xa5\xfb\xf0\x27\xc3\x1a\xf1\xbc\x70\x45\x13\xb2\x5e\x07\xf4\xb7\xdc\x3c\xdd\xd2\x4b\x4d\x8d\x30\x0d\x41\xa8\x0d\x99\xc7\x39\x75\xbf\xbc\xc2\xbe\x1d\xf8\x10\x20\x40\xc8\xfc\xaf\xfe\x57\x7f\x68\xb0\xc7\x1e\x23\x9f\x87\x47\xd1\x77\xe7\x1a\x3a\x64\x5b\xa1\x85\x19\x4c\x63\x17\x32\x2d\x34\x0d\xb3\x1f\xa2\x0c\x59\x0d\x70\x13\xaa\xe9\xd5\x0f\xcd\x81\xfa\x62\x68\x41\x01\x42\x7b\x3d\x9f\xb0\xb8\xc8\xf0\x09\x1e\x4d\x52\xe9\x5f\x99\x11\xc6\x0b\xc5\x66\x5e\x87\xac\x1f\x4a\x63\xfc\x21\xb2\x2f\xa2\xfe\x46\x8f\x3f\x3e\x10\x9a\x4b\xa0\x83\x90\xf9\x5f\xfc\x90\x6d\xf4\x7e\x24\x1c\x24\x62\xd0\x20\x65\x86\xff\x53\x7d\xa7\xca\x0e\x57\x7e\x55\x2f\x5b\x21\x21\x6e\x4a\x8b\x55\x7c\x3e\x2e\x94\x85\x51\x16\xe0\x26\xf1\xfe\x09\x9f\x16\x55\x08\x52\xd6\x54\x0a\xa6\xd1\x00\xac\xb2\x93\x41\x6d\x11\x74\x3f\xc8\x16\x9a\x46\x34\x45\xf5\xa8\xa8\xb8\x65\xdd\x19\x56\xaa\x07\x37\x50\x7e\xcd\x2a\x6c\xd6\x9a\xb2\xd6\x74\x67\x58\xaf\xa0\xb6\xb8\x14\xeb\x14\x4a\x63\x38\x02\xf0\x4c\x22\x67\x2d\x5d\xac\x97\xd0\x2d\x41\x67\x15\xb8\x15\x6b\x31\x80\x31\xd6\x55\xac\x4b\x0a\x0c\xb5\x16\x17\x75\xf7\xcf\xb3\xe3\x1e\x88\x4f\x40\xfd\x83\x90\xf5\xec\x51\xff\xd2\x2c\x21\xea\xed\x9d\xaf\xa4\x05\x5d\x2f\x9e\xdb\xc5\x62\x7b\x9d\x59\xdc\x0a\x51\x2e\xdc\xe9\x39\x53\xe8\x9f\x82\x93\x42\xde\x3a\x85\xce\x62\x3a\x75\xd7\x04\xd5\x2b\x75\xf7\xa8\x9a\x4b\x85\x3f\xb3\x2e\xac\x12\xf7\x74\xa2\xb4\xae\x15\x10\x73\xd0\xeb\x05\x3f\x8d\xf5\xee\x24\x75\xac\x92\x39\xb1\xa8\x7c\xdb\x9e\xcc\xfe\x26\xa6\xe6\xe9\x8b\xeb\x2e\x64\x18\x46\x9a\x1d\x28\xb2\xe1\x47\xd7\x7e\xb5\x5a\x6a\x0b\xd5\xdc\x4c\x0b\x8e\x3b\xe1\x9f\xa1\x34\x83\x34\x41\x69\x97\xc1\x9c\x21\xad\xb0\x39\xf7\x64\xbb\x5b\x95\x09\xab\x73\x5b\x72\xb1\xce\x88\xe5\x98\x41\xf3\xde\x65\x04\x20\x43\x26\x3f\x1e\xae\xee\x3a\xdd\xcf\xdd\x01\xf5\x22\x6b\x70\xd1\x22\x54\x93\xc5\x6b\xae\xdd\x50\x6e\x12\xe2\x74\x36\x30\xac\x7c\xa6\xa4\x6b\xbc\xf0\x2c\x93\x61\xb5\x1e\x63\x59\xaf\xa0\x62\xdc\xec\x5f\x6c\xbb\xf7\x87\x79\x1e\xd1\x6c\x8f\x68\xce\x47\xb4\x39\x46\x83\x7e\xe2\xf2\x54\xf0\x42\xad\xbf\x31\xb4\x66\x37\x8d\x2e\x8f\x1a\xb8\x3c\x6a\x0c\x1b\x2d\xe6\x8e\x6a\xbe\xef\x7b\xc3\xa1\x25\x9a\x3f\xb4\x4c\x98\x6e\xb6\x28\xed\x14\x10\x8b\xbb\xd9\x0c\xab\xcb\xa9\x06\xe8\xb8\x49\xff\x0a\xab\x10\x62\xe7\xf4\xbf\x5b\x57\x98\xc4\xb1\x18\xeb\x18\x80\x10\x7c\x59\x01\xb7\xff\x79\x2e\xff\x23\x03\x04\x79\x1f\xc5\xe2\xf5\x1c\x80\x77\x67\xb8\x31\x89\x9d\x63\x61\xdf\xb1\xdb\xcb\xec\x40\x21\xeb\x79\xcf\x73\x0b\xf1\x0b\xd0\x95\x53\x61\x84\xea\x95\x50\x7d\x9e\x26\x8b\xb1\x2e\xd7\xd7\x5a\xdf\xac\x47\x61\x71\x83\x75\xac\xc0\x55\x0a\xd8\xe5\x79\xcf\xf9\xdc\xac\x7c\x19\x3a\x1a\xe0\x22\x34\xb2\xce\x17\xd9\x58\xf9\xbc\x58\x56\x25\x7e\xb3\xc4\xcc\x37\x5f\xc8\x84\xf9\xd2\xe9\xdd\xcf\xdc\x82\xfc\xcf\xce\xc2\xc9\x8c\xf4\x8c\xe7\x19\xd3\xeb\x6f\xb5\xb0\xfd\xcc\xad\xbf\x21\x43\x05\x7d\x49\x44\x82\xbb\xbf\x51\x86\x08\x3c\x5f\x08\x7f\xdd\x71\xe4\x0a\x7a\x6f\xa3\xf2\x7c\x60\x25\x74\xaa\xa8\x2f\xcc\x18\xf7\xcd\x73\x0e\x3a\xcf\x0a\xf8\x6b\x0f\x8f\x2e\xf3\xd4\xf6\x5c\xfd\x5f\x00\x00\x00\xff\xff\xa0\x78\x63\x55\x69\x12\x00\x00") + +func fontsWeirdFlfBytes() ([]byte, error) { + return bindataRead( + _fontsWeirdFlf, + "fonts/weird.flf", + ) +} + +func fontsWeirdFlf() (*asset, error) { + bytes, err := fontsWeirdFlfBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "fonts/weird.flf", size: 4713, mode: os.FileMode(436), modTime: time.Unix(1529341546, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "fonts/3-d.flf": fonts3DFlf, + "fonts/3x5.flf": fonts3x5Flf, + "fonts/5lineoblique.flf": fonts5lineobliqueFlf, + "fonts/acrobatic.flf": fontsAcrobaticFlf, + "fonts/alligator.flf": fontsAlligatorFlf, + "fonts/alligator2.flf": fontsAlligator2Flf, + "fonts/alphabet.flf": fontsAlphabetFlf, + "fonts/avatar.flf": fontsAvatarFlf, + "fonts/banner.flf": fontsBannerFlf, + "fonts/banner3-D.flf": fontsBanner3DFlf, + "fonts/banner3.flf": fontsBanner3Flf, + "fonts/banner4.flf": fontsBanner4Flf, + "fonts/barbwire.flf": fontsBarbwireFlf, + "fonts/basic.flf": fontsBasicFlf, + "fonts/bell.flf": fontsBellFlf, + "fonts/big.flf": fontsBigFlf, + "fonts/bigchief.flf": fontsBigchiefFlf, + "fonts/binary.flf": fontsBinaryFlf, + "fonts/block.flf": fontsBlockFlf, + "fonts/bubble.flf": fontsBubbleFlf, + "fonts/bulbhead.flf": fontsBulbheadFlf, + "fonts/calgphy2.flf": fontsCalgphy2Flf, + "fonts/caligraphy.flf": fontsCaligraphyFlf, + "fonts/catwalk.flf": fontsCatwalkFlf, + "fonts/chunky.flf": fontsChunkyFlf, + "fonts/coinstak.flf": fontsCoinstakFlf, + "fonts/colossal.flf": fontsColossalFlf, + "fonts/computer.flf": fontsComputerFlf, + "fonts/contessa.flf": fontsContessaFlf, + "fonts/contrast.flf": fontsContrastFlf, + "fonts/cosmic.flf": fontsCosmicFlf, + "fonts/cosmike.flf": fontsCosmikeFlf, + "fonts/cricket.flf": fontsCricketFlf, + "fonts/cursive.flf": fontsCursiveFlf, + "fonts/cyberlarge.flf": fontsCyberlargeFlf, + "fonts/cybermedium.flf": fontsCybermediumFlf, + "fonts/cybersmall.flf": fontsCybersmallFlf, + "fonts/diamond.flf": fontsDiamondFlf, + "fonts/digital.flf": fontsDigitalFlf, + "fonts/doh.flf": fontsDohFlf, + "fonts/doom.flf": fontsDoomFlf, + "fonts/dotmatrix.flf": fontsDotmatrixFlf, + "fonts/drpepper.flf": fontsDrpepperFlf, + "fonts/eftichess.flf": fontsEftichessFlf, + "fonts/eftifont.flf": fontsEftifontFlf, + "fonts/eftipiti.flf": fontsEftipitiFlf, + "fonts/eftirobot.flf": fontsEftirobotFlf, + "fonts/eftitalic.flf": fontsEftitalicFlf, + "fonts/eftiwall.flf": fontsEftiwallFlf, + "fonts/eftiwater.flf": fontsEftiwaterFlf, + "fonts/elite.flf": fontsEliteFlf, + "fonts/epic.flf": fontsEpicFlf, + "fonts/fender.flf": fontsFenderFlf, + "fonts/fourtops.flf": fontsFourtopsFlf, + "fonts/fuzzy.flf": fontsFuzzyFlf, + "fonts/goofy.flf": fontsGoofyFlf, + "fonts/gothic.flf": fontsGothicFlf, + "fonts/graffiti.flf": fontsGraffitiFlf, + "fonts/hollywood.flf": fontsHollywoodFlf, + "fonts/invita.flf": fontsInvitaFlf, + "fonts/isometric1.flf": fontsIsometric1Flf, + "fonts/isometric2.flf": fontsIsometric2Flf, + "fonts/isometric3.flf": fontsIsometric3Flf, + "fonts/isometric4.flf": fontsIsometric4Flf, + "fonts/italic.flf": fontsItalicFlf, + "fonts/ivrit.flf": fontsIvritFlf, + "fonts/jazmine.flf": fontsJazmineFlf, + "fonts/jerusalem.flf": fontsJerusalemFlf, + "fonts/katakana.flf": fontsKatakanaFlf, + "fonts/kban.flf": fontsKbanFlf, + "fonts/larry3d.flf": fontsLarry3dFlf, + "fonts/lcd.flf": fontsLcdFlf, + "fonts/lean.flf": fontsLeanFlf, + "fonts/letters.flf": fontsLettersFlf, + "fonts/linux.flf": fontsLinuxFlf, + "fonts/lockergnome.flf": fontsLockergnomeFlf, + "fonts/madrid.flf": fontsMadridFlf, + "fonts/marquee.flf": fontsMarqueeFlf, + "fonts/maxfour.flf": fontsMaxfourFlf, + "fonts/mike.flf": fontsMikeFlf, + "fonts/mini.flf": fontsMiniFlf, + "fonts/mirror.flf": fontsMirrorFlf, + "fonts/mnemonic.flf": fontsMnemonicFlf, + "fonts/morse.flf": fontsMorseFlf, + "fonts/moscow.flf": fontsMoscowFlf, + "fonts/nancyj-fancy.flf": fontsNancyjFancyFlf, + "fonts/nancyj-underlined.flf": fontsNancyjUnderlinedFlf, + "fonts/nancyj.flf": fontsNancyjFlf, + "fonts/nipples.flf": fontsNipplesFlf, + "fonts/ntgreek.flf": fontsNtgreekFlf, + "fonts/o8.flf": fontsO8Flf, + "fonts/ogre.flf": fontsOgreFlf, + "fonts/pawp.flf": fontsPawpFlf, + "fonts/peaks.flf": fontsPeaksFlf, + "fonts/pebbles.flf": fontsPebblesFlf, + "fonts/pepper.flf": fontsPepperFlf, + "fonts/poison.flf": fontsPoisonFlf, + "fonts/puffy.flf": fontsPuffyFlf, + "fonts/pyramid.flf": fontsPyramidFlf, + "fonts/rectangles.flf": fontsRectanglesFlf, + "fonts/relief.flf": fontsReliefFlf, + "fonts/relief2.flf": fontsRelief2Flf, + "fonts/rev.flf": fontsRevFlf, + "fonts/roman.flf": fontsRomanFlf, + "fonts/rot13.flf": fontsRot13Flf, + "fonts/rounded.flf": fontsRoundedFlf, + "fonts/rowancap.flf": fontsRowancapFlf, + "fonts/rozzo.flf": fontsRozzoFlf, + "fonts/runic.flf": fontsRunicFlf, + "fonts/runyc.flf": fontsRunycFlf, + "fonts/sblood.flf": fontsSbloodFlf, + "fonts/script.flf": fontsScriptFlf, + "fonts/serifcap.flf": fontsSerifcapFlf, + "fonts/shadow.flf": fontsShadowFlf, + "fonts/short.flf": fontsShortFlf, + "fonts/slant.flf": fontsSlantFlf, + "fonts/slide.flf": fontsSlideFlf, + "fonts/slscript.flf": fontsSlscriptFlf, + "fonts/small.flf": fontsSmallFlf, + "fonts/smisome1.flf": fontsSmisome1Flf, + "fonts/smkeyboard.flf": fontsSmkeyboardFlf, + "fonts/smscript.flf": fontsSmscriptFlf, + "fonts/smshadow.flf": fontsSmshadowFlf, + "fonts/smslant.flf": fontsSmslantFlf, + "fonts/smtengwar.flf": fontsSmtengwarFlf, + "fonts/speed.flf": fontsSpeedFlf, + "fonts/stampatello.flf": fontsStampatelloFlf, + "fonts/standard.flf": fontsStandardFlf, + "fonts/starwars.flf": fontsStarwarsFlf, + "fonts/stellar.flf": fontsStellarFlf, + "fonts/stop.flf": fontsStopFlf, + "fonts/straight.flf": fontsStraightFlf, + "fonts/tanja.flf": fontsTanjaFlf, + "fonts/tengwar.flf": fontsTengwarFlf, + "fonts/term.flf": fontsTermFlf, + "fonts/thick.flf": fontsThickFlf, + "fonts/thin.flf": fontsThinFlf, + "fonts/threepoint.flf": fontsThreepointFlf, + "fonts/ticks.flf": fontsTicksFlf, + "fonts/ticksslant.flf": fontsTicksslantFlf, + "fonts/tinker-toy.flf": fontsTinkerToyFlf, + "fonts/tombstone.flf": fontsTombstoneFlf, + "fonts/trek.flf": fontsTrekFlf, + "fonts/tsalagi.flf": fontsTsalagiFlf, + "fonts/twopoint.flf": fontsTwopointFlf, + "fonts/univers.flf": fontsUniversFlf, + "fonts/usaflag.flf": fontsUsaflagFlf, + "fonts/wavy.flf": fontsWavyFlf, + "fonts/weird.flf": fontsWeirdFlf, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "fonts": &bintree{nil, map[string]*bintree{ + "3-d.flf": &bintree{fonts3DFlf, map[string]*bintree{}}, + "3x5.flf": &bintree{fonts3x5Flf, map[string]*bintree{}}, + "5lineoblique.flf": &bintree{fonts5lineobliqueFlf, map[string]*bintree{}}, + "acrobatic.flf": &bintree{fontsAcrobaticFlf, map[string]*bintree{}}, + "alligator.flf": &bintree{fontsAlligatorFlf, map[string]*bintree{}}, + "alligator2.flf": &bintree{fontsAlligator2Flf, map[string]*bintree{}}, + "alphabet.flf": &bintree{fontsAlphabetFlf, map[string]*bintree{}}, + "avatar.flf": &bintree{fontsAvatarFlf, map[string]*bintree{}}, + "banner.flf": &bintree{fontsBannerFlf, map[string]*bintree{}}, + "banner3-D.flf": &bintree{fontsBanner3DFlf, map[string]*bintree{}}, + "banner3.flf": &bintree{fontsBanner3Flf, map[string]*bintree{}}, + "banner4.flf": &bintree{fontsBanner4Flf, map[string]*bintree{}}, + "barbwire.flf": &bintree{fontsBarbwireFlf, map[string]*bintree{}}, + "basic.flf": &bintree{fontsBasicFlf, map[string]*bintree{}}, + "bell.flf": &bintree{fontsBellFlf, map[string]*bintree{}}, + "big.flf": &bintree{fontsBigFlf, map[string]*bintree{}}, + "bigchief.flf": &bintree{fontsBigchiefFlf, map[string]*bintree{}}, + "binary.flf": &bintree{fontsBinaryFlf, map[string]*bintree{}}, + "block.flf": &bintree{fontsBlockFlf, map[string]*bintree{}}, + "bubble.flf": &bintree{fontsBubbleFlf, map[string]*bintree{}}, + "bulbhead.flf": &bintree{fontsBulbheadFlf, map[string]*bintree{}}, + "calgphy2.flf": &bintree{fontsCalgphy2Flf, map[string]*bintree{}}, + "caligraphy.flf": &bintree{fontsCaligraphyFlf, map[string]*bintree{}}, + "catwalk.flf": &bintree{fontsCatwalkFlf, map[string]*bintree{}}, + "chunky.flf": &bintree{fontsChunkyFlf, map[string]*bintree{}}, + "coinstak.flf": &bintree{fontsCoinstakFlf, map[string]*bintree{}}, + "colossal.flf": &bintree{fontsColossalFlf, map[string]*bintree{}}, + "computer.flf": &bintree{fontsComputerFlf, map[string]*bintree{}}, + "contessa.flf": &bintree{fontsContessaFlf, map[string]*bintree{}}, + "contrast.flf": &bintree{fontsContrastFlf, map[string]*bintree{}}, + "cosmic.flf": &bintree{fontsCosmicFlf, map[string]*bintree{}}, + "cosmike.flf": &bintree{fontsCosmikeFlf, map[string]*bintree{}}, + "cricket.flf": &bintree{fontsCricketFlf, map[string]*bintree{}}, + "cursive.flf": &bintree{fontsCursiveFlf, map[string]*bintree{}}, + "cyberlarge.flf": &bintree{fontsCyberlargeFlf, map[string]*bintree{}}, + "cybermedium.flf": &bintree{fontsCybermediumFlf, map[string]*bintree{}}, + "cybersmall.flf": &bintree{fontsCybersmallFlf, map[string]*bintree{}}, + "diamond.flf": &bintree{fontsDiamondFlf, map[string]*bintree{}}, + "digital.flf": &bintree{fontsDigitalFlf, map[string]*bintree{}}, + "doh.flf": &bintree{fontsDohFlf, map[string]*bintree{}}, + "doom.flf": &bintree{fontsDoomFlf, map[string]*bintree{}}, + "dotmatrix.flf": &bintree{fontsDotmatrixFlf, map[string]*bintree{}}, + "drpepper.flf": &bintree{fontsDrpepperFlf, map[string]*bintree{}}, + "eftichess.flf": &bintree{fontsEftichessFlf, map[string]*bintree{}}, + "eftifont.flf": &bintree{fontsEftifontFlf, map[string]*bintree{}}, + "eftipiti.flf": &bintree{fontsEftipitiFlf, map[string]*bintree{}}, + "eftirobot.flf": &bintree{fontsEftirobotFlf, map[string]*bintree{}}, + "eftitalic.flf": &bintree{fontsEftitalicFlf, map[string]*bintree{}}, + "eftiwall.flf": &bintree{fontsEftiwallFlf, map[string]*bintree{}}, + "eftiwater.flf": &bintree{fontsEftiwaterFlf, map[string]*bintree{}}, + "elite.flf": &bintree{fontsEliteFlf, map[string]*bintree{}}, + "epic.flf": &bintree{fontsEpicFlf, map[string]*bintree{}}, + "fender.flf": &bintree{fontsFenderFlf, map[string]*bintree{}}, + "fourtops.flf": &bintree{fontsFourtopsFlf, map[string]*bintree{}}, + "fuzzy.flf": &bintree{fontsFuzzyFlf, map[string]*bintree{}}, + "goofy.flf": &bintree{fontsGoofyFlf, map[string]*bintree{}}, + "gothic.flf": &bintree{fontsGothicFlf, map[string]*bintree{}}, + "graffiti.flf": &bintree{fontsGraffitiFlf, map[string]*bintree{}}, + "hollywood.flf": &bintree{fontsHollywoodFlf, map[string]*bintree{}}, + "invita.flf": &bintree{fontsInvitaFlf, map[string]*bintree{}}, + "isometric1.flf": &bintree{fontsIsometric1Flf, map[string]*bintree{}}, + "isometric2.flf": &bintree{fontsIsometric2Flf, map[string]*bintree{}}, + "isometric3.flf": &bintree{fontsIsometric3Flf, map[string]*bintree{}}, + "isometric4.flf": &bintree{fontsIsometric4Flf, map[string]*bintree{}}, + "italic.flf": &bintree{fontsItalicFlf, map[string]*bintree{}}, + "ivrit.flf": &bintree{fontsIvritFlf, map[string]*bintree{}}, + "jazmine.flf": &bintree{fontsJazmineFlf, map[string]*bintree{}}, + "jerusalem.flf": &bintree{fontsJerusalemFlf, map[string]*bintree{}}, + "katakana.flf": &bintree{fontsKatakanaFlf, map[string]*bintree{}}, + "kban.flf": &bintree{fontsKbanFlf, map[string]*bintree{}}, + "larry3d.flf": &bintree{fontsLarry3dFlf, map[string]*bintree{}}, + "lcd.flf": &bintree{fontsLcdFlf, map[string]*bintree{}}, + "lean.flf": &bintree{fontsLeanFlf, map[string]*bintree{}}, + "letters.flf": &bintree{fontsLettersFlf, map[string]*bintree{}}, + "linux.flf": &bintree{fontsLinuxFlf, map[string]*bintree{}}, + "lockergnome.flf": &bintree{fontsLockergnomeFlf, map[string]*bintree{}}, + "madrid.flf": &bintree{fontsMadridFlf, map[string]*bintree{}}, + "marquee.flf": &bintree{fontsMarqueeFlf, map[string]*bintree{}}, + "maxfour.flf": &bintree{fontsMaxfourFlf, map[string]*bintree{}}, + "mike.flf": &bintree{fontsMikeFlf, map[string]*bintree{}}, + "mini.flf": &bintree{fontsMiniFlf, map[string]*bintree{}}, + "mirror.flf": &bintree{fontsMirrorFlf, map[string]*bintree{}}, + "mnemonic.flf": &bintree{fontsMnemonicFlf, map[string]*bintree{}}, + "morse.flf": &bintree{fontsMorseFlf, map[string]*bintree{}}, + "moscow.flf": &bintree{fontsMoscowFlf, map[string]*bintree{}}, + "nancyj-fancy.flf": &bintree{fontsNancyjFancyFlf, map[string]*bintree{}}, + "nancyj-underlined.flf": &bintree{fontsNancyjUnderlinedFlf, map[string]*bintree{}}, + "nancyj.flf": &bintree{fontsNancyjFlf, map[string]*bintree{}}, + "nipples.flf": &bintree{fontsNipplesFlf, map[string]*bintree{}}, + "ntgreek.flf": &bintree{fontsNtgreekFlf, map[string]*bintree{}}, + "o8.flf": &bintree{fontsO8Flf, map[string]*bintree{}}, + "ogre.flf": &bintree{fontsOgreFlf, map[string]*bintree{}}, + "pawp.flf": &bintree{fontsPawpFlf, map[string]*bintree{}}, + "peaks.flf": &bintree{fontsPeaksFlf, map[string]*bintree{}}, + "pebbles.flf": &bintree{fontsPebblesFlf, map[string]*bintree{}}, + "pepper.flf": &bintree{fontsPepperFlf, map[string]*bintree{}}, + "poison.flf": &bintree{fontsPoisonFlf, map[string]*bintree{}}, + "puffy.flf": &bintree{fontsPuffyFlf, map[string]*bintree{}}, + "pyramid.flf": &bintree{fontsPyramidFlf, map[string]*bintree{}}, + "rectangles.flf": &bintree{fontsRectanglesFlf, map[string]*bintree{}}, + "relief.flf": &bintree{fontsReliefFlf, map[string]*bintree{}}, + "relief2.flf": &bintree{fontsRelief2Flf, map[string]*bintree{}}, + "rev.flf": &bintree{fontsRevFlf, map[string]*bintree{}}, + "roman.flf": &bintree{fontsRomanFlf, map[string]*bintree{}}, + "rot13.flf": &bintree{fontsRot13Flf, map[string]*bintree{}}, + "rounded.flf": &bintree{fontsRoundedFlf, map[string]*bintree{}}, + "rowancap.flf": &bintree{fontsRowancapFlf, map[string]*bintree{}}, + "rozzo.flf": &bintree{fontsRozzoFlf, map[string]*bintree{}}, + "runic.flf": &bintree{fontsRunicFlf, map[string]*bintree{}}, + "runyc.flf": &bintree{fontsRunycFlf, map[string]*bintree{}}, + "sblood.flf": &bintree{fontsSbloodFlf, map[string]*bintree{}}, + "script.flf": &bintree{fontsScriptFlf, map[string]*bintree{}}, + "serifcap.flf": &bintree{fontsSerifcapFlf, map[string]*bintree{}}, + "shadow.flf": &bintree{fontsShadowFlf, map[string]*bintree{}}, + "short.flf": &bintree{fontsShortFlf, map[string]*bintree{}}, + "slant.flf": &bintree{fontsSlantFlf, map[string]*bintree{}}, + "slide.flf": &bintree{fontsSlideFlf, map[string]*bintree{}}, + "slscript.flf": &bintree{fontsSlscriptFlf, map[string]*bintree{}}, + "small.flf": &bintree{fontsSmallFlf, map[string]*bintree{}}, + "smisome1.flf": &bintree{fontsSmisome1Flf, map[string]*bintree{}}, + "smkeyboard.flf": &bintree{fontsSmkeyboardFlf, map[string]*bintree{}}, + "smscript.flf": &bintree{fontsSmscriptFlf, map[string]*bintree{}}, + "smshadow.flf": &bintree{fontsSmshadowFlf, map[string]*bintree{}}, + "smslant.flf": &bintree{fontsSmslantFlf, map[string]*bintree{}}, + "smtengwar.flf": &bintree{fontsSmtengwarFlf, map[string]*bintree{}}, + "speed.flf": &bintree{fontsSpeedFlf, map[string]*bintree{}}, + "stampatello.flf": &bintree{fontsStampatelloFlf, map[string]*bintree{}}, + "standard.flf": &bintree{fontsStandardFlf, map[string]*bintree{}}, + "starwars.flf": &bintree{fontsStarwarsFlf, map[string]*bintree{}}, + "stellar.flf": &bintree{fontsStellarFlf, map[string]*bintree{}}, + "stop.flf": &bintree{fontsStopFlf, map[string]*bintree{}}, + "straight.flf": &bintree{fontsStraightFlf, map[string]*bintree{}}, + "tanja.flf": &bintree{fontsTanjaFlf, map[string]*bintree{}}, + "tengwar.flf": &bintree{fontsTengwarFlf, map[string]*bintree{}}, + "term.flf": &bintree{fontsTermFlf, map[string]*bintree{}}, + "thick.flf": &bintree{fontsThickFlf, map[string]*bintree{}}, + "thin.flf": &bintree{fontsThinFlf, map[string]*bintree{}}, + "threepoint.flf": &bintree{fontsThreepointFlf, map[string]*bintree{}}, + "ticks.flf": &bintree{fontsTicksFlf, map[string]*bintree{}}, + "ticksslant.flf": &bintree{fontsTicksslantFlf, map[string]*bintree{}}, + "tinker-toy.flf": &bintree{fontsTinkerToyFlf, map[string]*bintree{}}, + "tombstone.flf": &bintree{fontsTombstoneFlf, map[string]*bintree{}}, + "trek.flf": &bintree{fontsTrekFlf, map[string]*bintree{}}, + "tsalagi.flf": &bintree{fontsTsalagiFlf, map[string]*bintree{}}, + "twopoint.flf": &bintree{fontsTwopointFlf, map[string]*bintree{}}, + "univers.flf": &bintree{fontsUniversFlf, map[string]*bintree{}}, + "usaflag.flf": &bintree{fontsUsaflagFlf, map[string]*bintree{}}, + "wavy.flf": &bintree{fontsWavyFlf, map[string]*bintree{}}, + "weird.flf": &bintree{fontsWeirdFlf, map[string]*bintree{}}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} diff --git a/vendor/github.com/common-nighthawk/go-figure/figlet-parser.go b/vendor/github.com/common-nighthawk/go-figure/figlet-parser.go new file mode 100644 index 00000000000..4c595a5ee46 --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/figlet-parser.go @@ -0,0 +1,52 @@ +package figure + +import ( + "strconv" + "strings" +) + +const signature = "flf2" +const reverseFlag = "1" + +var charDelimiters = [3]string{"@", "#", "$"} +var hardblanksBlacklist = [2]byte{'a', '2'} + +func getHeight(metadata string) int { + datum := strings.Fields(metadata)[1] + height, _ := strconv.Atoi(datum) + return height +} + +func getBaseline(metadata string) int { + datum := strings.Fields(metadata)[2] + baseline, _ := strconv.Atoi(datum) + return baseline +} + +func getHardblank(metadata string) byte { + datum := strings.Fields(metadata)[0] + hardblank := datum[len(datum)-1] + if hardblank == hardblanksBlacklist[0] || hardblank == hardblanksBlacklist[1] { + return ' ' + } else { + return hardblank + } +} + +func getReverse(metadata string) bool { + data := strings.Fields(metadata) + return len(data) > 6 && data[6] == reverseFlag +} + +func lastCharLine(text string, height int) bool { + endOfLine, length := " ", 2 + if height == 1 && len(text) > 0 { + length = 1 + } + if len(text) >= length { + endOfLine = text[len(text)-length:] + } + return endOfLine == strings.Repeat(charDelimiters[0], length) || + endOfLine == strings.Repeat(charDelimiters[1], length) || + endOfLine == strings.Repeat(charDelimiters[2], length) +} diff --git a/vendor/github.com/common-nighthawk/go-figure/figure.go b/vendor/github.com/common-nighthawk/go-figure/figure.go new file mode 100644 index 00000000000..a2559fc4bca --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/figure.go @@ -0,0 +1,80 @@ +package figure + +import ( + "io" + "log" + "reflect" + "strings" +) + +const ascii_offset = 32 +const first_ascii = ' ' +const last_ascii = '~' + +type figure struct { + phrase string + font + strict bool + color string +} + +func NewFigure(phrase, fontName string, strict bool) figure { + font := newFont(fontName) + if font.reverse { + phrase = reverse(phrase) + } + return figure{phrase: phrase, font: font, strict: strict} +} + +func NewColorFigure(phrase, fontName string, color string, strict bool) figure { + color = strings.ToLower(color) + if _, found := colors[color]; !found { + log.Fatalf("invalid color. must be one of: %s", reflect.ValueOf(colors).MapKeys()) + } + + fig := NewFigure(phrase, fontName, strict) + fig.color = color + return fig +} + +func NewFigureWithFont(phrase string, reader io.Reader, strict bool) figure { + font := newFontFromReader(reader) + if font.reverse { + phrase = reverse(phrase) + } + return figure{phrase: phrase, font: font, strict: strict} +} + +func (figure figure) Slicify() (rows []string) { + for r := 0; r < figure.font.height; r++ { + printRow := "" + for _, char := range figure.phrase { + if char < first_ascii || char > last_ascii { + if figure.strict { + log.Fatal("invalid input.") + } else { + char = '?' + } + } + fontIndex := char - ascii_offset + charRowText := scrub(figure.font.letters[fontIndex][r], figure.font.hardblank) + printRow += charRowText + } + if r < figure.font.baseline || len(strings.TrimSpace(printRow)) > 0 { + rows = append(rows, strings.TrimRight(printRow, " ")) + } + } + return rows +} + +func scrub(text string, char byte) string { + return strings.Replace(text, string(char), " ", -1) +} + +func reverse(s string) string { + runes := []rune(s) + for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { + runes[i], runes[j] = runes[j], runes[i] + } + return string(runes) +} diff --git a/vendor/github.com/common-nighthawk/go-figure/font.go b/vendor/github.com/common-nighthawk/go-figure/font.go new file mode 100644 index 00000000000..fc6852e81ec --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/font.go @@ -0,0 +1,112 @@ +package figure + +import ( + "bufio" + "bytes" + "io" + "path" + "strings" +) + +const defaultFont = "standard" + +var colors = map[string]string{ + "reset": "\033[0m", + "red": "\033[31m", + "green": "\033[32m", + "yellow": "\033[33m", + "blue": "\033[34m", + "purple": "\033[35m", + "cyan": "\033[36m", + "gray": "\033[37m", + "white": "\033[97m", +} + +type font struct { + name string + height int + baseline int + hardblank byte + reverse bool + letters [][]string +} + +func newFont(name string) (font font) { + font.setName(name) + fontBytes, err := Asset(path.Join("fonts", font.name+".flf")) + if err != nil { + panic(err) + } + fontBytesReader := bytes.NewReader(fontBytes) + scanner := bufio.NewScanner(fontBytesReader) + font.setAttributes(scanner) + font.setLetters(scanner) + return font +} + +func newFontFromReader(reader io.Reader) (font font) { + scanner := bufio.NewScanner(reader) + font.setAttributes(scanner) + font.setLetters(scanner) + return font +} + +func (font *font) setName(name string) { + font.name = name + if len(name) < 1 { + font.name = defaultFont + } +} + +func (font *font) setAttributes(scanner *bufio.Scanner) { + for scanner.Scan() { + text := scanner.Text() + if strings.HasPrefix(text, signature) { + font.height = getHeight(text) + font.baseline = getBaseline(text) + font.hardblank = getHardblank(text) + font.reverse = getReverse(text) + break + } + } +} + +func (font *font) setLetters(scanner *bufio.Scanner) { + font.letters = append(font.letters, make([]string, font.height, font.height)) //TODO: set spaces from flf + for i := range font.letters[0] { + font.letters[0][i] = " " + } //TODO: set spaces from flf + letterIndex := 0 + for scanner.Scan() { + text, cutLength, letterIndexInc := scanner.Text(), 1, 0 + if lastCharLine(text, font.height) { + font.letters = append(font.letters, []string{}) + letterIndexInc = 1 + if font.height > 1 { + cutLength = 2 + } + } + if letterIndex > 0 { + appendText := "" + if len(text) > 1 { + appendText = text[:len(text)-cutLength] + } + font.letters[letterIndex] = append(font.letters[letterIndex], appendText) + } + letterIndex += letterIndexInc + } +} + +func (font *font) evenLetters() { + var longest int + for _, letter := range font.letters { + if len(letter) > 0 && len(letter[0]) > longest { + longest = len(letter[0]) + } + } + for _, letter := range font.letters { + for i, row := range letter { + letter[i] = row + strings.Repeat(" ", longest-len(row)) + } + } +} diff --git a/vendor/github.com/common-nighthawk/go-figure/public_methods.go b/vendor/github.com/common-nighthawk/go-figure/public_methods.go new file mode 100644 index 00000000000..5a154116214 --- /dev/null +++ b/vendor/github.com/common-nighthawk/go-figure/public_methods.go @@ -0,0 +1,108 @@ +package figure + +import ( + "fmt" + "io" + "strings" + "time" +) + +//stdout +func (fig figure) Print() { + for _, printRow := range fig.Slicify() { + if fig.color != "" { + printRow = colors[fig.color] + printRow + colors["reset"] + } + fmt.Println(printRow) + } +} + +// returns a colored string +func (fig figure) ColorString() string { + s := "" + for _, printRow := range fig.Slicify() { + if fig.color != "" { + printRow = colors[fig.color] + printRow + colors["reset"] + } + s += fmt.Sprintf("%s\n", printRow) + } + return s +} + +func (fig figure) String() string { + s := "" + for _, printRow := range fig.Slicify() { + s += fmt.Sprintf("%s\n", printRow) + } + return s +} + +func (fig figure) Scroll(duration, stillness int, direction string) { + endTime := time.Now().Add(time.Duration(duration) * time.Millisecond) + fig.phrase = fig.phrase + " " + clearScreen() + for time.Now().Before(endTime) { + var shiftedPhrase string + chars := []byte(fig.phrase) + if strings.HasPrefix(strings.ToLower(direction), "r") { + shiftedPhrase = string(append(chars[len(chars)-1:], chars[0:len(chars)-1]...)) + } else { + shiftedPhrase = string(append(chars[1:len(chars)], chars[0])) + } + fig.phrase = shiftedPhrase + fig.Print() + sleep(stillness) + clearScreen() + } +} + +func (fig figure) Blink(duration, timeOn, timeOff int) { + if timeOff < 0 { + timeOff = timeOn + } + endTime := time.Now().Add(time.Duration(duration) * time.Millisecond) + clearScreen() + for time.Now().Before(endTime) { + fig.Print() + sleep(timeOn) + clearScreen() + sleep(timeOff) + } +} + +func (fig figure) Dance(duration, freeze int) { + endTime := time.Now().Add(time.Duration(duration) * time.Millisecond) + font := fig.font //TODO: change to deep copy + font.evenLetters() + figures := []figure{figure{font: font}, figure{font: font}} + clearScreen() + for i, c := range fig.phrase { + appenders := []string{" ", " "} + appenders[i%2] = string(c) + for f, _ := range figures { + figures[f].phrase = figures[f].phrase + appenders[f] + } + } + for p := 0; time.Now().Before(endTime); p ^= 1 { + figures[p].Print() + figures[1-p].Print() + sleep(freeze) + clearScreen() + } +} + +//writers +func Write(w io.Writer, fig figure) { + for _, printRow := range fig.Slicify() { + fmt.Fprintf(w, "%v\n", printRow) + } +} + +//helpers +func clearScreen() { + fmt.Print("\033[H\033[2J") +} + +func sleep(milliseconds int) { + time.Sleep(time.Duration(milliseconds) * time.Millisecond) +} diff --git a/vendor/github.com/containerd/containerd/archive/compression/compression_fuzzer.go b/vendor/github.com/containerd/containerd/archive/compression/compression_fuzzer.go new file mode 100644 index 00000000000..3516494ac0b --- /dev/null +++ b/vendor/github.com/containerd/containerd/archive/compression/compression_fuzzer.go @@ -0,0 +1,28 @@ +//go:build gofuzz + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package compression + +import ( + "bytes" +) + +func FuzzDecompressStream(data []byte) int { + _, _ = DecompressStream(bytes.NewReader(data)) + return 1 +} diff --git a/vendor/github.com/containerd/containerd/content/content.go b/vendor/github.com/containerd/containerd/content/content.go index ff17a8417b3..8eb1a16924c 100644 --- a/vendor/github.com/containerd/containerd/content/content.go +++ b/vendor/github.com/containerd/containerd/content/content.go @@ -25,6 +25,26 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) +// Store combines the methods of content-oriented interfaces into a set that +// are commonly provided by complete implementations. +// +// Overall content lifecycle: +// - Ingester is used to initiate a write operation (aka ingestion) +// - IngestManager is used to manage (e.g. list, abort) active ingestions +// - Once an ingestion is complete (see Writer.Commit), Provider is used to +// query a single piece of content by its digest +// - Manager is used to manage (e.g. list, delete) previously committed content +// +// Note that until ingestion is complete, its content is not visible through +// Provider or Manager. Once ingestion is complete, it is no longer exposed +// through IngestManager. +type Store interface { + Manager + Provider + IngestManager + Ingester +} + // ReaderAt extends the standard io.ReaderAt interface with reporting of Size and io.Closer type ReaderAt interface { io.ReaderAt @@ -42,14 +62,31 @@ type Provider interface { // Ingester writes content type Ingester interface { - // Some implementations require WithRef to be included in opts. + // Writer initiates a writing operation (aka ingestion). A single ingestion + // is uniquely identified by its ref, provided using a WithRef option. + // Writer can be called multiple times with the same ref to access the same + // ingestion. + // Once all the data is written, use Writer.Commit to complete the ingestion. Writer(ctx context.Context, opts ...WriterOpt) (Writer, error) } +// IngestManager provides methods for managing ingestions. An ingestion is a +// not-yet-complete writing operation initiated using Ingester and identified +// by a ref string. +type IngestManager interface { + // Status returns the status of the provided ref. + Status(ctx context.Context, ref string) (Status, error) + + // ListStatuses returns the status of any active ingestions whose ref match + // the provided regular expression. If empty, all active ingestions will be + // returned. + ListStatuses(ctx context.Context, filters ...string) ([]Status, error) + + // Abort completely cancels the ingest operation targeted by ref. + Abort(ctx context.Context, ref string) error +} + // Info holds content specific information -// -// TODO(stevvooe): Consider a very different name for this struct. Info is way -// to general. It also reads very weird in certain context, like pluralization. type Info struct { Digest digest.Digest Size int64 @@ -58,7 +95,7 @@ type Info struct { Labels map[string]string } -// Status of a content operation +// Status of a content operation (i.e. an ingestion) type Status struct { Ref string Offset int64 @@ -71,12 +108,17 @@ type Status struct { // WalkFunc defines the callback for a blob walk. type WalkFunc func(Info) error -// Manager provides methods for inspecting, listing and removing content. -type Manager interface { +// InfoProvider provides info for content inspection. +type InfoProvider interface { // Info will return metadata about content available in the content store. // // If the content is not present, ErrNotFound will be returned. Info(ctx context.Context, dgst digest.Digest) (Info, error) +} + +// Manager provides methods for inspecting, listing and removing content. +type Manager interface { + InfoProvider // Update updates mutable information related to content. // If one or more fieldpaths are provided, only those @@ -94,21 +136,7 @@ type Manager interface { Delete(ctx context.Context, dgst digest.Digest) error } -// IngestManager provides methods for managing ingests. -type IngestManager interface { - // Status returns the status of the provided ref. - Status(ctx context.Context, ref string) (Status, error) - - // ListStatuses returns the status of any active ingestions whose ref match the - // provided regular expression. If empty, all active ingestions will be - // returned. - ListStatuses(ctx context.Context, filters ...string) ([]Status, error) - - // Abort completely cancels the ingest operation targeted by ref. - Abort(ctx context.Context, ref string) error -} - -// Writer handles the write of content into a content store +// Writer handles writing of content into a content store type Writer interface { // Close closes the writer, if the writer has not been // committed this allows resuming or aborting. @@ -131,15 +159,6 @@ type Writer interface { Truncate(size int64) error } -// Store combines the methods of content-oriented interfaces into a set that -// are commonly provided by complete implementations. -type Store interface { - Manager - Provider - IngestManager - Ingester -} - // Opt is used to alter the mutable properties of content type Opt func(*Info) error diff --git a/vendor/github.com/containerd/containerd/content/helpers.go b/vendor/github.com/containerd/containerd/content/helpers.go index 723c3139171..5404109a6db 100644 --- a/vendor/github.com/containerd/containerd/content/helpers.go +++ b/vendor/github.com/containerd/containerd/content/helpers.go @@ -21,12 +21,12 @@ import ( "errors" "fmt" "io" - "math/rand" "sync" "time" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/pkg/randutil" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -43,16 +43,26 @@ var bufPool = sync.Pool{ }, } +type reader interface { + Reader() io.Reader +} + // NewReader returns a io.Reader from a ReaderAt func NewReader(ra ReaderAt) io.Reader { - rd := io.NewSectionReader(ra, 0, ra.Size()) - return rd + if rd, ok := ra.(reader); ok { + return rd.Reader() + } + return io.NewSectionReader(ra, 0, ra.Size()) } // ReadBlob retrieves the entire contents of the blob from the provider. // // Avoid using this for large blobs, such as layers. func ReadBlob(ctx context.Context, provider Provider, desc ocispec.Descriptor) ([]byte, error) { + if int64(len(desc.Data)) == desc.Size && digest.FromBytes(desc.Data) == desc.Digest { + return desc.Data, nil + } + ra, err := provider.ReaderAt(ctx, desc) if err != nil { return nil, err @@ -113,7 +123,7 @@ func OpenWriter(ctx context.Context, cs Ingester, opts ...WriterOpt) (Writer, er // error or abort. Requires asserting for an ingest manager select { - case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))): + case <-time.After(time.Millisecond * time.Duration(randutil.Intn(retry))): if retry < 2048 { retry = retry << 1 } diff --git a/vendor/github.com/containerd/containerd/content/local/content_local_fuzzer.go b/vendor/github.com/containerd/containerd/content/local/content_local_fuzzer.go new file mode 100644 index 00000000000..a523f28d911 --- /dev/null +++ b/vendor/github.com/containerd/containerd/content/local/content_local_fuzzer.go @@ -0,0 +1,76 @@ +//go:build gofuzz + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package local + +import ( + "bufio" + "bytes" + "context" + _ "crypto/sha256" + "io" + "testing" + + "github.com/opencontainers/go-digest" + + "github.com/containerd/containerd/content" +) + +func FuzzContentStoreWriter(data []byte) int { + t := &testing.T{} + ctx := context.Background() + ctx, _, cs, cleanup := contentStoreEnv(t) + defer cleanup() + + cw, err := cs.Writer(ctx, content.WithRef("myref")) + if err != nil { + return 0 + } + if err := cw.Close(); err != nil { + return 0 + } + + // reopen, so we can test things + cw, err = cs.Writer(ctx, content.WithRef("myref")) + if err != nil { + return 0 + } + + err = checkCopyFuzz(int64(len(data)), cw, bufio.NewReader(io.NopCloser(bytes.NewReader(data)))) + if err != nil { + return 0 + } + expected := digest.FromBytes(data) + + if err = cw.Commit(ctx, int64(len(data)), expected); err != nil { + return 0 + } + return 1 +} + +func checkCopyFuzz(size int64, dst io.Writer, src io.Reader) error { + nn, err := io.Copy(dst, src) + if err != nil { + return err + } + + if nn != size { + return err + } + return nil +} diff --git a/vendor/github.com/containerd/containerd/content/local/readerat.go b/vendor/github.com/containerd/containerd/content/local/readerat.go index a83c171bbd2..899e85c0ba8 100644 --- a/vendor/github.com/containerd/containerd/content/local/readerat.go +++ b/vendor/github.com/containerd/containerd/content/local/readerat.go @@ -18,6 +18,7 @@ package local import ( "fmt" + "io" "os" "github.com/containerd/containerd/content" @@ -65,3 +66,7 @@ func (ra sizeReaderAt) Size() int64 { func (ra sizeReaderAt) Close() error { return ra.fp.Close() } + +func (ra sizeReaderAt) Reader() io.Reader { + return io.LimitReader(ra.fp, ra.size) +} diff --git a/vendor/github.com/containerd/containerd/content/local/store.go b/vendor/github.com/containerd/containerd/content/local/store.go index f41a92d04a5..baae3565bb4 100644 --- a/vendor/github.com/containerd/containerd/content/local/store.go +++ b/vendor/github.com/containerd/containerd/content/local/store.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "io" - "math/rand" "os" "path/filepath" "strconv" @@ -32,9 +31,10 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/pkg/randutil" "github.com/sirupsen/logrus" - digest "github.com/opencontainers/go-digest" + "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -262,7 +262,7 @@ func (s *store) Walk(ctx context.Context, fn content.WalkFunc, fs ...string) err return nil } - dgst := digest.NewDigestFromHex(alg.String(), filepath.Base(path)) + dgst := digest.NewDigestFromEncoded(alg, filepath.Base(path)) if err := dgst.Validate(); err != nil { // log error but don't report log.L.WithError(err).WithField("path", path).Error("invalid digest for blob path") @@ -473,7 +473,7 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content. lockErr = nil break } - time.Sleep(time.Millisecond * time.Duration(rand.Intn(1< maxSize + keyMaxLen = 64 ) // Validate a label's key and value are under 4096 bytes func Validate(k, v string) error { - if (len(k) + len(v)) > maxSize { - if len(k) > 10 { - k = k[:10] + total := len(k) + len(v) + if total > maxSize { + if len(k) > keyMaxLen { + k = k[:keyMaxLen] } - return fmt.Errorf("label key and value greater than maximum size (%d bytes), key: %s: %w", maxSize, k, errdefs.ErrInvalidArgument) + return fmt.Errorf("label key and value length (%d bytes) greater than maximum size (%d bytes), key: %s: %w", total, maxSize, k, errdefs.ErrInvalidArgument) } return nil } diff --git a/vendor/github.com/containerd/containerd/log/context.go b/vendor/github.com/containerd/containerd/log/context.go index 0db9562b82b..20153066f3a 100644 --- a/vendor/github.com/containerd/containerd/log/context.go +++ b/vendor/github.com/containerd/containerd/log/context.go @@ -14,56 +14,169 @@ limitations under the License. */ +// Package log provides types and functions related to logging, passing +// loggers through a context, and attaching context to the logger. +// +// # Transitional types +// +// This package contains various types that are aliases for types in [logrus]. +// These aliases are intended for transitioning away from hard-coding logrus +// as logging implementation. Consumers of this package are encouraged to use +// the type-aliases from this package instead of directly using their logrus +// equivalent. +// +// The intent is to replace these aliases with locally defined types and +// interfaces once all consumers are no longer directly importing logrus +// types. +// +// IMPORTANT: due to the transitional purpose of this package, it is not +// guaranteed for the full logrus API to be provided in the future. As +// outlined, these aliases are provided as a step to transition away from +// a specific implementation which, as a result, exposes the full logrus API. +// While no decisions have been made on the ultimate design and interface +// provided by this package, we do not expect carrying "less common" features. package log import ( "context" + "fmt" "github.com/sirupsen/logrus" ) -var ( - // G is an alias for GetLogger. - // - // We may want to define this locally to a package to get package tagged log - // messages. - G = GetLogger +// G is a shorthand for [GetLogger]. +// +// We may want to define this locally to a package to get package tagged log +// messages. +var G = GetLogger + +// L is an alias for the standard logger. +var L = &Entry{ + Logger: logrus.StandardLogger(), + // Default is three fields plus a little extra room. + Data: make(Fields, 6), +} - // L is an alias for the standard logger. - L = logrus.NewEntry(logrus.StandardLogger()) -) +type loggerKey struct{} -type ( - loggerKey struct{} -) +// Fields type to pass to "WithFields". +type Fields = map[string]any + +// Entry is a logging entry. It contains all the fields passed with +// [Entry.WithFields]. It's finally logged when Trace, Debug, Info, Warn, +// Error, Fatal or Panic is called on it. These objects can be reused and +// passed around as much as you wish to avoid field duplication. +// +// Entry is a transitional type, and currently an alias for [logrus.Entry]. +type Entry = logrus.Entry +// RFC3339NanoFixed is [time.RFC3339Nano] with nanoseconds padded using +// zeros to ensure the formatted time is always the same number of +// characters. +const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" + +// Level is a logging level. +type Level = logrus.Level + +// Supported log levels. const ( - // RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to - // ensure the formatted time is always the same number of characters. - RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" + // TraceLevel level. Designates finer-grained informational events + // than [DebugLevel]. + TraceLevel Level = logrus.TraceLevel + + // DebugLevel level. Usually only enabled when debugging. Very verbose + // logging. + DebugLevel Level = logrus.DebugLevel + + // InfoLevel level. General operational entries about what's going on + // inside the application. + InfoLevel Level = logrus.InfoLevel + + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel Level = logrus.WarnLevel + + // ErrorLevel level. Logs errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel Level = logrus.ErrorLevel + + // FatalLevel level. Logs and then calls "logger.Exit(1)". It exits + // even if the logging level is set to Panic. + FatalLevel Level = logrus.FatalLevel + + // PanicLevel level. This is the highest level of severity. Logs and + // then calls panic with the message passed to Debug, Info, ... + PanicLevel Level = logrus.PanicLevel +) - // TextFormat represents the text logging format - TextFormat = "text" +// SetLevel sets log level globally. It returns an error if the given +// level is not supported. +// +// level can be one of: +// +// - "trace" ([TraceLevel]) +// - "debug" ([DebugLevel]) +// - "info" ([InfoLevel]) +// - "warn" ([WarnLevel]) +// - "error" ([ErrorLevel]) +// - "fatal" ([FatalLevel]) +// - "panic" ([PanicLevel]) +func SetLevel(level string) error { + lvl, err := logrus.ParseLevel(level) + if err != nil { + return err + } + + L.Logger.SetLevel(lvl) + return nil +} - // JSONFormat represents the JSON logging format - JSONFormat = "json" +// GetLevel returns the current log level. +func GetLevel() Level { + return L.Logger.GetLevel() +} + +// OutputFormat specifies a log output format. +type OutputFormat string + +// Supported log output formats. +const ( + // TextFormat represents the text logging format. + TextFormat OutputFormat = "text" + + // JSONFormat represents the JSON logging format. + JSONFormat OutputFormat = "json" ) +// SetFormat sets the log output format ([TextFormat] or [JSONFormat]). +func SetFormat(format OutputFormat) error { + switch format { + case TextFormat: + L.Logger.SetFormatter(&logrus.TextFormatter{ + TimestampFormat: RFC3339NanoFixed, + FullTimestamp: true, + }) + return nil + case JSONFormat: + L.Logger.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: RFC3339NanoFixed, + }) + return nil + default: + return fmt.Errorf("unknown log format: %s", format) + } +} + // WithLogger returns a new context with the provided logger. Use in // combination with logger.WithField(s) for great effect. -func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context { - e := logger.WithContext(ctx) - return context.WithValue(ctx, loggerKey{}, e) +func WithLogger(ctx context.Context, logger *Entry) context.Context { + return context.WithValue(ctx, loggerKey{}, logger.WithContext(ctx)) } // GetLogger retrieves the current logger from the context. If no logger is // available, the default logger is returned. -func GetLogger(ctx context.Context) *logrus.Entry { - logger := ctx.Value(loggerKey{}) - - if logger == nil { - return L.WithContext(ctx) +func GetLogger(ctx context.Context) *Entry { + if logger := ctx.Value(loggerKey{}); logger != nil { + return logger.(*Entry) } - - return logger.(*logrus.Entry) + return L.WithContext(ctx) } diff --git a/vendor/github.com/containerd/containerd/pkg/randutil/randutil.go b/vendor/github.com/containerd/containerd/pkg/randutil/randutil.go new file mode 100644 index 00000000000..f4b657d7dd8 --- /dev/null +++ b/vendor/github.com/containerd/containerd/pkg/randutil/randutil.go @@ -0,0 +1,48 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Package randutil provides utilities for [cyrpto/rand]. +package randutil + +import ( + "crypto/rand" + "math" + "math/big" +) + +// Int63n is similar to [math/rand.Int63n] but uses [crypto/rand.Reader] under the hood. +func Int63n(n int64) int64 { + b, err := rand.Int(rand.Reader, big.NewInt(n)) + if err != nil { + panic(err) + } + return b.Int64() +} + +// Int63 is similar to [math/rand.Int63] but uses [crypto/rand.Reader] under the hood. +func Int63() int64 { + return Int63n(math.MaxInt64) +} + +// Intn is similar to [math/rand.Intn] but uses [crypto/rand.Reader] under the hood. +func Intn(n int) int { + return int(Int63n(int64(n))) +} + +// Int is similar to [math/rand.Int] but uses [crypto/rand.Reader] under the hood. +func Int() int { + return int(Int63()) +} diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go index 046e0356d19..8c600fc96b1 100644 --- a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go +++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go @@ -17,14 +17,9 @@ package platforms import ( - "bufio" - "fmt" - "os" "runtime" - "strings" "sync" - "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" ) @@ -37,95 +32,12 @@ var cpuVariantOnce sync.Once func cpuVariant() string { cpuVariantOnce.Do(func() { if isArmArch(runtime.GOARCH) { - cpuVariantValue = getCPUVariant() + var err error + cpuVariantValue, err = getCPUVariant() + if err != nil { + log.L.Errorf("Error getCPUVariant for OS %s: %v", runtime.GOOS, err) + } } }) return cpuVariantValue } - -// For Linux, the kernel has already detected the ABI, ISA and Features. -// So we don't need to access the ARM registers to detect platform information -// by ourselves. We can just parse these information from /proc/cpuinfo -func getCPUInfo(pattern string) (info string, err error) { - if !isLinuxOS(runtime.GOOS) { - return "", fmt.Errorf("getCPUInfo for OS %s: %w", runtime.GOOS, errdefs.ErrNotImplemented) - } - - cpuinfo, err := os.Open("/proc/cpuinfo") - if err != nil { - return "", err - } - defer cpuinfo.Close() - - // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse - // the first core is enough. - scanner := bufio.NewScanner(cpuinfo) - for scanner.Scan() { - newline := scanner.Text() - list := strings.Split(newline, ":") - - if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { - return strings.TrimSpace(list[1]), nil - } - } - - // Check whether the scanner encountered errors - err = scanner.Err() - if err != nil { - return "", err - } - - return "", fmt.Errorf("getCPUInfo for pattern: %s: %w", pattern, errdefs.ErrNotFound) -} - -func getCPUVariant() string { - if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { - // Windows/Darwin only supports v7 for ARM32 and v8 for ARM64 and so we can use - // runtime.GOARCH to determine the variants - var variant string - switch runtime.GOARCH { - case "arm64": - variant = "v8" - case "arm": - variant = "v7" - default: - variant = "unknown" - } - - return variant - } - - variant, err := getCPUInfo("Cpu architecture") - if err != nil { - log.L.WithError(err).Error("failure getting variant") - return "" - } - - // handle edge case for Raspberry Pi ARMv6 devices (which due to a kernel quirk, report "CPU architecture: 7") - // https://www.raspberrypi.org/forums/viewtopic.php?t=12614 - if runtime.GOARCH == "arm" && variant == "7" { - model, err := getCPUInfo("model name") - if err == nil && strings.HasPrefix(strings.ToLower(model), "armv6-compatible") { - variant = "6" - } - } - - switch strings.ToLower(variant) { - case "8", "aarch64": - variant = "v8" - case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": - variant = "v7" - case "6", "6tej": - variant = "v6" - case "5", "5t", "5te", "5tej": - variant = "v5" - case "4", "4t": - variant = "v4" - case "3": - variant = "v3" - default: - variant = "unknown" - } - - return variant -} diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go new file mode 100644 index 00000000000..722d86c3578 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go @@ -0,0 +1,161 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "bufio" + "bytes" + "fmt" + "os" + "runtime" + "strings" + + "github.com/containerd/containerd/errdefs" + "golang.org/x/sys/unix" +) + +// getMachineArch retrieves the machine architecture through system call +func getMachineArch() (string, error) { + var uname unix.Utsname + err := unix.Uname(&uname) + if err != nil { + return "", err + } + + arch := string(uname.Machine[:bytes.IndexByte(uname.Machine[:], 0)]) + + return arch, nil +} + +// For Linux, the kernel has already detected the ABI, ISA and Features. +// So we don't need to access the ARM registers to detect platform information +// by ourselves. We can just parse these information from /proc/cpuinfo +func getCPUInfo(pattern string) (info string, err error) { + + cpuinfo, err := os.Open("/proc/cpuinfo") + if err != nil { + return "", err + } + defer cpuinfo.Close() + + // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse + // the first core is enough. + scanner := bufio.NewScanner(cpuinfo) + for scanner.Scan() { + newline := scanner.Text() + list := strings.Split(newline, ":") + + if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { + return strings.TrimSpace(list[1]), nil + } + } + + // Check whether the scanner encountered errors + err = scanner.Err() + if err != nil { + return "", err + } + + return "", fmt.Errorf("getCPUInfo for pattern %s: %w", pattern, errdefs.ErrNotFound) +} + +// getCPUVariantFromArch get CPU variant from arch through a system call +func getCPUVariantFromArch(arch string) (string, error) { + + var variant string + + arch = strings.ToLower(arch) + + if arch == "aarch64" { + variant = "8" + } else if arch[0:4] == "armv" && len(arch) >= 5 { + //Valid arch format is in form of armvXx + switch arch[3:5] { + case "v8": + variant = "8" + case "v7": + variant = "7" + case "v6": + variant = "6" + case "v5": + variant = "5" + case "v4": + variant = "4" + case "v3": + variant = "3" + default: + variant = "unknown" + } + } else { + return "", fmt.Errorf("getCPUVariantFromArch invalid arch: %s, %w", arch, errdefs.ErrInvalidArgument) + } + return variant, nil +} + +// getCPUVariant returns cpu variant for ARM +// We first try reading "Cpu architecture" field from /proc/cpuinfo +// If we can't find it, then fall back using a system call +// This is to cover running ARM in emulated environment on x86 host as this field in /proc/cpuinfo +// was not present. +func getCPUVariant() (string, error) { + + variant, err := getCPUInfo("Cpu architecture") + if err != nil { + if errdefs.IsNotFound(err) { + //Let's try getting CPU variant from machine architecture + arch, err := getMachineArch() + if err != nil { + return "", fmt.Errorf("failure getting machine architecture: %v", err) + } + + variant, err = getCPUVariantFromArch(arch) + if err != nil { + return "", fmt.Errorf("failure getting CPU variant from machine architecture: %v", err) + } + } else { + return "", fmt.Errorf("failure getting CPU variant: %v", err) + } + } + + // handle edge case for Raspberry Pi ARMv6 devices (which due to a kernel quirk, report "CPU architecture: 7") + // https://www.raspberrypi.org/forums/viewtopic.php?t=12614 + if runtime.GOARCH == "arm" && variant == "7" { + model, err := getCPUInfo("model name") + if err == nil && strings.HasPrefix(strings.ToLower(model), "armv6-compatible") { + variant = "6" + } + } + + switch strings.ToLower(variant) { + case "8", "aarch64": + variant = "v8" + case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": + variant = "v7" + case "6", "6tej": + variant = "v6" + case "5", "5t", "5te", "5tej": + variant = "v5" + case "4", "4t": + variant = "v4" + case "3": + variant = "v3" + default: + variant = "unknown" + } + + return variant, nil +} diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go new file mode 100644 index 00000000000..fa5f19c427a --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go @@ -0,0 +1,59 @@ +//go:build !linux + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "fmt" + "runtime" + + "github.com/containerd/containerd/errdefs" +) + +func getCPUVariant() (string, error) { + + var variant string + + if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { + // Windows/Darwin only supports v7 for ARM32 and v8 for ARM64 and so we can use + // runtime.GOARCH to determine the variants + switch runtime.GOARCH { + case "arm64": + variant = "v8" + case "arm": + variant = "v7" + default: + variant = "unknown" + } + } else if runtime.GOOS == "freebsd" { + // FreeBSD supports ARMv6 and ARMv7 as well as ARMv4 and ARMv5 (though deprecated) + // detecting those variants is currently unimplemented + switch runtime.GOARCH { + case "arm64": + variant = "v8" + default: + variant = "unknown" + } + + } else { + return "", fmt.Errorf("getCPUVariant for OS %s: %v", runtime.GOOS, errdefs.ErrNotImplemented) + + } + + return variant, nil +} diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/containerd/platforms/database.go index dbe9957ca9d..2e26fd3b4fa 100644 --- a/vendor/github.com/containerd/containerd/platforms/database.go +++ b/vendor/github.com/containerd/containerd/platforms/database.go @@ -21,13 +21,6 @@ import ( "strings" ) -// isLinuxOS returns true if the operating system is Linux. -// -// The OS value should be normalized before calling this function. -func isLinuxOS(os string) bool { - return os == "linux" -} - // These function are generated from https://golang.org/src/go/build/syslist.go. // // We use switch statements because they are slightly faster than map lookups diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go b/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go index e249fe48d38..72355ca85fd 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go @@ -1,5 +1,4 @@ //go:build darwin -// +build darwin /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_freebsd.go b/vendor/github.com/containerd/containerd/platforms/defaults_freebsd.go new file mode 100644 index 00000000000..d3fe89e0766 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/defaults_freebsd.go @@ -0,0 +1,43 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "runtime" + + specs "github.com/opencontainers/image-spec/specs-go/v1" +) + +// DefaultSpec returns the current platform's default platform specification. +func DefaultSpec() specs.Platform { + return specs.Platform{ + OS: runtime.GOOS, + Architecture: runtime.GOARCH, + // The Variant field will be empty if arch != ARM. + Variant: cpuVariant(), + } +} + +// Default returns the default matcher for the platform. +func Default() MatchComparer { + return Ordered(DefaultSpec(), specs.Platform{ + OS: "linux", + Architecture: runtime.GOARCH, + // The Variant field will be empty if arch != ARM. + Variant: cpuVariant(), + }) +} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go index 49690f1b3e7..44acc47eb32 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go @@ -1,5 +1,4 @@ -//go:build !windows && !darwin -// +build !windows,!darwin +//go:build !windows && !darwin && !freebsd /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go index c1aaf72ca8e..d10fa9012bd 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - imagespec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/Microsoft/hcsshim/osversion" specs "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sys/windows" ) @@ -39,25 +39,52 @@ func DefaultSpec() specs.Platform { } } -type matchComparer struct { - defaults Matcher +type windowsmatcher struct { + specs.Platform osVersionPrefix string + defaultMatcher Matcher } // Match matches platform with the same windows major, minor // and build version. -func (m matchComparer) Match(p imagespec.Platform) bool { - if m.defaults.Match(p) { - // TODO(windows): Figure out whether OSVersion is deprecated. - return strings.HasPrefix(p.OSVersion, m.osVersionPrefix) +func (m windowsmatcher) Match(p specs.Platform) bool { + match := m.defaultMatcher.Match(p) + + if match && m.OS == "windows" { + // HPC containers do not have OS version filled + if p.OSVersion == "" { + return true + } + + hostOsVersion := GetOsVersion(m.osVersionPrefix) + ctrOsVersion := GetOsVersion(p.OSVersion) + return osversion.CheckHostAndContainerCompat(hostOsVersion, ctrOsVersion) + } + + return match +} + +func GetOsVersion(osVersionPrefix string) osversion.OSVersion { + parts := strings.Split(osVersionPrefix, ".") + if len(parts) < 3 { + return osversion.OSVersion{} + } + + majorVersion, _ := strconv.Atoi(parts[0]) + minorVersion, _ := strconv.Atoi(parts[1]) + buildNumber, _ := strconv.Atoi(parts[2]) + + return osversion.OSVersion{ + MajorVersion: uint8(majorVersion), + MinorVersion: uint8(minorVersion), + Build: uint16(buildNumber), } - return false } // Less sorts matched platforms in front of other platforms. // For matched platforms, it puts platforms with larger revision // number in front. -func (m matchComparer) Less(p1, p2 imagespec.Platform) bool { +func (m windowsmatcher) Less(p1, p2 specs.Platform) bool { m1, m2 := m.Match(p1), m.Match(p2) if m1 && m2 { r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion) @@ -78,14 +105,15 @@ func revision(v string) int { return r } +func prefix(v string) string { + parts := strings.Split(v, ".") + if len(parts) < 4 { + return v + } + return strings.Join(parts[0:3], ".") +} + // Default returns the current platform's default platform specification. func Default() MatchComparer { - major, minor, build := windows.RtlGetNtVersionNumbers() - return matchComparer{ - defaults: Ordered(DefaultSpec(), specs.Platform{ - OS: "linux", - Architecture: runtime.GOARCH, - }), - osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build), - } + return Only(DefaultSpec()) } diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/containerd/platforms/platforms.go index 23430994180..56613b07656 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms.go +++ b/vendor/github.com/containerd/containerd/platforms/platforms.go @@ -114,14 +114,18 @@ import ( "strconv" "strings" - "github.com/containerd/containerd/errdefs" specs "github.com/opencontainers/image-spec/specs-go/v1" + + "github.com/containerd/containerd/errdefs" ) var ( specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) ) +// Platform is a type alias for convenience, so there is no need to import image-spec package everywhere. +type Platform = specs.Platform + // Matcher matches platforms specifications, provided by an image or runtime. type Matcher interface { Match(platform specs.Platform) bool @@ -136,9 +140,7 @@ type Matcher interface { // // Applications should opt to use `Match` over directly parsing specifiers. func NewMatcher(platform specs.Platform) Matcher { - return &matcher{ - Platform: Normalize(platform), - } + return newDefaultMatcher(platform) } type matcher struct { @@ -194,6 +196,10 @@ func Parse(specifier string) (specs.Platform, error) { p.Variant = cpuVariant() } + if p.OS == "windows" { + p.OSVersion = GetWindowsOsVersion() + } + return p, nil } @@ -216,6 +222,10 @@ func Parse(specifier string) (specs.Platform, error) { p.Variant = "" } + if p.OS == "windows" { + p.OSVersion = GetWindowsOsVersion() + } + return p, nil case 3: // we have a fully specified variant, this is rare @@ -225,6 +235,10 @@ func Parse(specifier string) (specs.Platform, error) { p.Variant = "v8" } + if p.OS == "windows" { + p.OSVersion = GetWindowsOsVersion() + } + return p, nil } @@ -257,5 +271,6 @@ func Format(platform specs.Platform) string { func Normalize(platform specs.Platform) specs.Platform { platform.OS = normalizeOS(platform.OS) platform.Architecture, platform.Variant = normalizeArch(platform.Architecture, platform.Variant) + return platform } diff --git a/vendor/github.com/containerd/containerd/platforms/platforms_other.go b/vendor/github.com/containerd/containerd/platforms/platforms_other.go new file mode 100644 index 00000000000..59beeb3d1d9 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/platforms_other.go @@ -0,0 +1,34 @@ +//go:build !windows + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + specs "github.com/opencontainers/image-spec/specs-go/v1" +) + +// NewMatcher returns the default Matcher for containerd +func newDefaultMatcher(platform specs.Platform) Matcher { + return &matcher{ + Platform: Normalize(platform), + } +} + +func GetWindowsOsVersion() string { + return "" +} diff --git a/vendor/github.com/containerd/containerd/platforms/platforms_windows.go b/vendor/github.com/containerd/containerd/platforms/platforms_windows.go new file mode 100644 index 00000000000..733d18ddead --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/platforms_windows.go @@ -0,0 +1,42 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "fmt" + + specs "github.com/opencontainers/image-spec/specs-go/v1" + "golang.org/x/sys/windows" +) + +// NewMatcher returns a Windows matcher that will match on osVersionPrefix if +// the platform is Windows otherwise use the default matcher +func newDefaultMatcher(platform specs.Platform) Matcher { + prefix := prefix(platform.OSVersion) + return windowsmatcher{ + Platform: platform, + osVersionPrefix: prefix, + defaultMatcher: &matcher{ + Platform: Normalize(platform), + }, + } +} + +func GetWindowsOsVersion() string { + major, minor, build := windows.RtlGetNtVersionNumbers() + return fmt.Sprintf("%d.%d.%d", major, minor, build) +} diff --git a/vendor/github.com/containerd/containerd/reference/docker/helpers.go b/vendor/github.com/containerd/containerd/reference/docker/helpers.go new file mode 100644 index 00000000000..386025104ae --- /dev/null +++ b/vendor/github.com/containerd/containerd/reference/docker/helpers.go @@ -0,0 +1,58 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import "path" + +// IsNameOnly returns true if reference only contains a repo name. +func IsNameOnly(ref Named) bool { + if _, ok := ref.(NamedTagged); ok { + return false + } + if _, ok := ref.(Canonical); ok { + return false + } + return true +} + +// FamiliarName returns the familiar name string +// for the given named, familiarizing if needed. +func FamiliarName(ref Named) string { + if nn, ok := ref.(normalizedNamed); ok { + return nn.Familiar().Name() + } + return ref.Name() +} + +// FamiliarString returns the familiar string representation +// for the given reference, familiarizing if needed. +func FamiliarString(ref Reference) string { + if nn, ok := ref.(normalizedNamed); ok { + return nn.Familiar().String() + } + return ref.String() +} + +// FamiliarMatch reports whether ref matches the specified pattern. +// See https://godoc.org/path#Match for supported patterns. +func FamiliarMatch(pattern string, ref Reference) (bool, error) { + matched, err := path.Match(pattern, FamiliarString(ref)) + if namedRef, isNamed := ref.(Named); isNamed && !matched { + matched, _ = path.Match(pattern, FamiliarName(namedRef)) + } + return matched, err +} diff --git a/vendor/github.com/containerd/containerd/reference/docker/normalize.go b/vendor/github.com/containerd/containerd/reference/docker/normalize.go new file mode 100644 index 00000000000..b299bf6c068 --- /dev/null +++ b/vendor/github.com/containerd/containerd/reference/docker/normalize.go @@ -0,0 +1,196 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import ( + "fmt" + "strings" + + "github.com/opencontainers/go-digest" +) + +var ( + legacyDefaultDomain = "index.docker.io" + defaultDomain = "docker.io" + officialRepoName = "library" + defaultTag = "latest" +) + +// normalizedNamed represents a name which has been +// normalized and has a familiar form. A familiar name +// is what is used in Docker UI. An example normalized +// name is "docker.io/library/ubuntu" and corresponding +// familiar name of "ubuntu". +type normalizedNamed interface { + Named + Familiar() Named +} + +// ParseNormalizedNamed parses a string into a named reference +// transforming a familiar name from Docker UI to a fully +// qualified reference. If the value may be an identifier +// use ParseAnyReference. +func ParseNormalizedNamed(s string) (Named, error) { + if ok := anchoredIdentifierRegexp.MatchString(s); ok { + return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s) + } + domain, remainder := splitDockerDomain(s) + var remoteName string + if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 { + remoteName = remainder[:tagSep] + } else { + remoteName = remainder + } + if strings.ToLower(remoteName) != remoteName { + return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remoteName) + } + + ref, err := Parse(domain + "/" + remainder) + if err != nil { + return nil, err + } + named, isNamed := ref.(Named) + if !isNamed { + return nil, fmt.Errorf("reference %s has no name", ref.String()) + } + return named, nil +} + +// ParseDockerRef normalizes the image reference following the docker convention. This is added +// mainly for backward compatibility. +// The reference returned can only be either tagged or digested. For reference contains both tag +// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@ +// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as +// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa. +func ParseDockerRef(ref string) (Named, error) { + named, err := ParseNormalizedNamed(ref) + if err != nil { + return nil, err + } + if _, ok := named.(NamedTagged); ok { + if canonical, ok := named.(Canonical); ok { + // The reference is both tagged and digested, only + // return digested. + newNamed, err := WithName(canonical.Name()) + if err != nil { + return nil, err + } + newCanonical, err := WithDigest(newNamed, canonical.Digest()) + if err != nil { + return nil, err + } + return newCanonical, nil + } + } + return TagNameOnly(named), nil +} + +// splitDockerDomain splits a repository name to domain and remotename string. +// If no valid domain is found, the default domain is used. Repository name +// needs to be already validated before. +func splitDockerDomain(name string) (domain, remainder string) { + i := strings.IndexRune(name, '/') + if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost" && strings.ToLower(name[:i]) == name[:i]) { + domain, remainder = defaultDomain, name + } else { + domain, remainder = name[:i], name[i+1:] + } + if domain == legacyDefaultDomain { + domain = defaultDomain + } + if domain == defaultDomain && !strings.ContainsRune(remainder, '/') { + remainder = officialRepoName + "/" + remainder + } + return +} + +// familiarizeName returns a shortened version of the name familiar +// to the Docker UI. Familiar names have the default domain +// "docker.io" and "library/" repository prefix removed. +// For example, "docker.io/library/redis" will have the familiar +// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp". +// Returns a familiarized named only reference. +func familiarizeName(named namedRepository) repository { + repo := repository{ + domain: named.Domain(), + path: named.Path(), + } + + if repo.domain == defaultDomain { + repo.domain = "" + // Handle official repositories which have the pattern "library/" + if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName { + repo.path = split[1] + } + } + return repo +} + +func (r reference) Familiar() Named { + return reference{ + namedRepository: familiarizeName(r.namedRepository), + tag: r.tag, + digest: r.digest, + } +} + +func (r repository) Familiar() Named { + return familiarizeName(r) +} + +func (t taggedReference) Familiar() Named { + return taggedReference{ + namedRepository: familiarizeName(t.namedRepository), + tag: t.tag, + } +} + +func (c canonicalReference) Familiar() Named { + return canonicalReference{ + namedRepository: familiarizeName(c.namedRepository), + digest: c.digest, + } +} + +// TagNameOnly adds the default tag "latest" to a reference if it only has +// a repo name. +func TagNameOnly(ref Named) Named { + if IsNameOnly(ref) { + namedTagged, err := WithTag(ref, defaultTag) + if err != nil { + // Default tag must be valid, to create a NamedTagged + // type with non-validated input the WithTag function + // should be used instead + panic(err) + } + return namedTagged + } + return ref +} + +// ParseAnyReference parses a reference string as a possible identifier, +// full digest, or familiar name. +func ParseAnyReference(ref string) (Reference, error) { + if ok := anchoredIdentifierRegexp.MatchString(ref); ok { + return digestReference("sha256:" + ref), nil + } + if dgst, err := digest.Parse(ref); err == nil { + return digestReference(dgst), nil + } + + return ParseNormalizedNamed(ref) +} diff --git a/vendor/github.com/containerd/containerd/reference/docker/reference.go b/vendor/github.com/containerd/containerd/reference/docker/reference.go new file mode 100644 index 00000000000..4dc00474ee5 --- /dev/null +++ b/vendor/github.com/containerd/containerd/reference/docker/reference.go @@ -0,0 +1,453 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Package docker provides a general type to represent any way of referencing images within the registry. +// Its main purpose is to abstract tags and digests (content-addressable hash). +// +// Grammar +// +// reference := name [ ":" tag ] [ "@" digest ] +// name := [domain '/'] path-component ['/' path-component]* +// domain := host [':' port-number] +// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A +// domain-name := domain-component ['.' domain-component]* +// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ +// port-number := /[0-9]+/ +// path-component := alpha-numeric [separator alpha-numeric]* +// alpha-numeric := /[a-z0-9]+/ +// separator := /[_.]|__|[-]*/ +// +// tag := /[\w][\w.-]{0,127}/ +// +// digest := digest-algorithm ":" digest-hex +// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]* +// digest-algorithm-separator := /[+.-_]/ +// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/ +// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value +// +// identifier := /[a-f0-9]{64}/ +// short-identifier := /[a-f0-9]{6,64}/ +package docker + +import ( + "errors" + "fmt" + "strings" + + "github.com/opencontainers/go-digest" +) + +const ( + // NameTotalLengthMax is the maximum total number of characters in a repository name. + NameTotalLengthMax = 255 +) + +var ( + // ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference. + ErrReferenceInvalidFormat = errors.New("invalid reference format") + + // ErrTagInvalidFormat represents an error while trying to parse a string as a tag. + ErrTagInvalidFormat = errors.New("invalid tag format") + + // ErrDigestInvalidFormat represents an error while trying to parse a string as a tag. + ErrDigestInvalidFormat = errors.New("invalid digest format") + + // ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters. + ErrNameContainsUppercase = errors.New("repository name must be lowercase") + + // ErrNameEmpty is returned for empty, invalid repository names. + ErrNameEmpty = errors.New("repository name must have at least one component") + + // ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax. + ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax) + + // ErrNameNotCanonical is returned when a name is not canonical. + ErrNameNotCanonical = errors.New("repository name must be canonical") +) + +// Reference is an opaque object reference identifier that may include +// modifiers such as a hostname, name, tag, and digest. +type Reference interface { + // String returns the full reference + String() string +} + +// Field provides a wrapper type for resolving correct reference types when +// working with encoding. +type Field struct { + reference Reference +} + +// AsField wraps a reference in a Field for encoding. +func AsField(reference Reference) Field { + return Field{reference} +} + +// Reference unwraps the reference type from the field to +// return the Reference object. This object should be +// of the appropriate type to further check for different +// reference types. +func (f Field) Reference() Reference { + return f.reference +} + +// MarshalText serializes the field to byte text which +// is the string of the reference. +func (f Field) MarshalText() (p []byte, err error) { + return []byte(f.reference.String()), nil +} + +// UnmarshalText parses text bytes by invoking the +// reference parser to ensure the appropriately +// typed reference object is wrapped by field. +func (f *Field) UnmarshalText(p []byte) error { + r, err := Parse(string(p)) + if err != nil { + return err + } + + f.reference = r + return nil +} + +// Named is an object with a full name +type Named interface { + Reference + Name() string +} + +// Tagged is an object which has a tag +type Tagged interface { + Reference + Tag() string +} + +// NamedTagged is an object including a name and tag. +type NamedTagged interface { + Named + Tag() string +} + +// Digested is an object which has a digest +// in which it can be referenced by +type Digested interface { + Reference + Digest() digest.Digest +} + +// Canonical reference is an object with a fully unique +// name including a name with domain and digest +type Canonical interface { + Named + Digest() digest.Digest +} + +// namedRepository is a reference to a repository with a name. +// A namedRepository has both domain and path components. +type namedRepository interface { + Named + Domain() string + Path() string +} + +// Domain returns the domain part of the Named reference +func Domain(named Named) string { + if r, ok := named.(namedRepository); ok { + return r.Domain() + } + domain, _ := splitDomain(named.Name()) + return domain +} + +// Path returns the name without the domain part of the Named reference +func Path(named Named) (name string) { + if r, ok := named.(namedRepository); ok { + return r.Path() + } + _, path := splitDomain(named.Name()) + return path +} + +func splitDomain(name string) (string, string) { + match := anchoredNameRegexp.FindStringSubmatch(name) + if len(match) != 3 { + return "", name + } + return match[1], match[2] +} + +// SplitHostname splits a named reference into a +// hostname and name string. If no valid hostname is +// found, the hostname is empty and the full value +// is returned as name +// DEPRECATED: Use Domain or Path +func SplitHostname(named Named) (string, string) { + if r, ok := named.(namedRepository); ok { + return r.Domain(), r.Path() + } + return splitDomain(named.Name()) +} + +// Parse parses s and returns a syntactically valid Reference. +// If an error was encountered it is returned, along with a nil Reference. +// NOTE: Parse will not handle short digests. +func Parse(s string) (Reference, error) { + matches := ReferenceRegexp.FindStringSubmatch(s) + if matches == nil { + if s == "" { + return nil, ErrNameEmpty + } + if ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil { + return nil, ErrNameContainsUppercase + } + return nil, ErrReferenceInvalidFormat + } + + if len(matches[1]) > NameTotalLengthMax { + return nil, ErrNameTooLong + } + + var repo repository + + nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1]) + if len(nameMatch) == 3 { + repo.domain = nameMatch[1] + repo.path = nameMatch[2] + } else { + repo.domain = "" + repo.path = matches[1] + } + + ref := reference{ + namedRepository: repo, + tag: matches[2], + } + if matches[3] != "" { + var err error + ref.digest, err = digest.Parse(matches[3]) + if err != nil { + return nil, err + } + } + + r := getBestReferenceType(ref) + if r == nil { + return nil, ErrNameEmpty + } + + return r, nil +} + +// ParseNamed parses s and returns a syntactically valid reference implementing +// the Named interface. The reference must have a name and be in the canonical +// form, otherwise an error is returned. +// If an error was encountered it is returned, along with a nil Reference. +// NOTE: ParseNamed will not handle short digests. +func ParseNamed(s string) (Named, error) { + named, err := ParseNormalizedNamed(s) + if err != nil { + return nil, err + } + if named.String() != s { + return nil, ErrNameNotCanonical + } + return named, nil +} + +// WithName returns a named object representing the given string. If the input +// is invalid ErrReferenceInvalidFormat will be returned. +func WithName(name string) (Named, error) { + if len(name) > NameTotalLengthMax { + return nil, ErrNameTooLong + } + + match := anchoredNameRegexp.FindStringSubmatch(name) + if match == nil || len(match) != 3 { + return nil, ErrReferenceInvalidFormat + } + return repository{ + domain: match[1], + path: match[2], + }, nil +} + +// WithTag combines the name from "name" and the tag from "tag" to form a +// reference incorporating both the name and the tag. +func WithTag(name Named, tag string) (NamedTagged, error) { + if !anchoredTagRegexp.MatchString(tag) { + return nil, ErrTagInvalidFormat + } + var repo repository + if r, ok := name.(namedRepository); ok { + repo.domain = r.Domain() + repo.path = r.Path() + } else { + repo.path = name.Name() + } + if canonical, ok := name.(Canonical); ok { + return reference{ + namedRepository: repo, + tag: tag, + digest: canonical.Digest(), + }, nil + } + return taggedReference{ + namedRepository: repo, + tag: tag, + }, nil +} + +// WithDigest combines the name from "name" and the digest from "digest" to form +// a reference incorporating both the name and the digest. +func WithDigest(name Named, digest digest.Digest) (Canonical, error) { + if !anchoredDigestRegexp.MatchString(digest.String()) { + return nil, ErrDigestInvalidFormat + } + var repo repository + if r, ok := name.(namedRepository); ok { + repo.domain = r.Domain() + repo.path = r.Path() + } else { + repo.path = name.Name() + } + if tagged, ok := name.(Tagged); ok { + return reference{ + namedRepository: repo, + tag: tagged.Tag(), + digest: digest, + }, nil + } + return canonicalReference{ + namedRepository: repo, + digest: digest, + }, nil +} + +// TrimNamed removes any tag or digest from the named reference. +func TrimNamed(ref Named) Named { + repo := repository{} + if r, ok := ref.(namedRepository); ok { + repo.domain, repo.path = r.Domain(), r.Path() + } else { + repo.domain, repo.path = splitDomain(ref.Name()) + } + return repo +} + +func getBestReferenceType(ref reference) Reference { + if ref.Name() == "" { + // Allow digest only references + if ref.digest != "" { + return digestReference(ref.digest) + } + return nil + } + if ref.tag == "" { + if ref.digest != "" { + return canonicalReference{ + namedRepository: ref.namedRepository, + digest: ref.digest, + } + } + return ref.namedRepository + } + if ref.digest == "" { + return taggedReference{ + namedRepository: ref.namedRepository, + tag: ref.tag, + } + } + + return ref +} + +type reference struct { + namedRepository + tag string + digest digest.Digest +} + +func (r reference) String() string { + return r.Name() + ":" + r.tag + "@" + r.digest.String() +} + +func (r reference) Tag() string { + return r.tag +} + +func (r reference) Digest() digest.Digest { + return r.digest +} + +type repository struct { + domain string + path string +} + +func (r repository) String() string { + return r.Name() +} + +func (r repository) Name() string { + if r.domain == "" { + return r.path + } + return r.domain + "/" + r.path +} + +func (r repository) Domain() string { + return r.domain +} + +func (r repository) Path() string { + return r.path +} + +type digestReference digest.Digest + +func (d digestReference) String() string { + return digest.Digest(d).String() +} + +func (d digestReference) Digest() digest.Digest { + return digest.Digest(d) +} + +type taggedReference struct { + namedRepository + tag string +} + +func (t taggedReference) String() string { + return t.Name() + ":" + t.tag +} + +func (t taggedReference) Tag() string { + return t.tag +} + +type canonicalReference struct { + namedRepository + digest digest.Digest +} + +func (c canonicalReference) String() string { + return c.Name() + "@" + c.digest.String() +} + +func (c canonicalReference) Digest() digest.Digest { + return c.digest +} diff --git a/vendor/github.com/containerd/containerd/reference/docker/regexp.go b/vendor/github.com/containerd/containerd/reference/docker/regexp.go new file mode 100644 index 00000000000..4be3c575e04 --- /dev/null +++ b/vendor/github.com/containerd/containerd/reference/docker/regexp.go @@ -0,0 +1,191 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import "regexp" + +var ( + // alphaNumeric defines the alpha numeric atom, typically a + // component of names. This only allows lower case characters and digits. + alphaNumeric = `[a-z0-9]+` + + // separator defines the separators allowed to be embedded in name + // components. This allow one period, one or two underscore and multiple + // dashes. Repeated dashes and underscores are intentionally treated + // differently. In order to support valid hostnames as name components, + // supporting repeated dash was added. Additionally double underscore is + // now allowed as a separator to loosen the restriction for previously + // supported names. + separator = `(?:[._]|__|[-]*)` + + // nameComponent restricts registry path component names to start + // with at least one letter or number, with following parts able to be + // separated by one period, one or two underscore and multiple dashes. + nameComponent = expression( + alphaNumeric, + optional(repeated(separator, alphaNumeric))) + + // domainNameComponent restricts the registry domain component of a + // repository name to start with a component as defined by DomainRegexp. + domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])` + + // ipv6address are enclosed between square brackets and may be represented + // in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format + // are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as + // IPv4-Mapped are deliberately excluded. + ipv6address = expression( + literal(`[`), `(?:[a-fA-F0-9:]+)`, literal(`]`), + ) + + // domainName defines the structure of potential domain components + // that may be part of image names. This is purposely a subset of what is + // allowed by DNS to ensure backwards compatibility with Docker image + // names. This includes IPv4 addresses on decimal format. + domainName = expression( + domainNameComponent, + optional(repeated(literal(`.`), domainNameComponent)), + ) + + // host defines the structure of potential domains based on the URI + // Host subcomponent on rfc3986. It may be a subset of DNS domain name, + // or an IPv4 address in decimal format, or an IPv6 address between square + // brackets (excluding zone identifiers as defined by rfc6874 or special + // addresses such as IPv4-Mapped). + host = `(?:` + domainName + `|` + ipv6address + `)` + + // allowed by the URI Host subcomponent on rfc3986 to ensure backwards + // compatibility with Docker image names. + domain = expression( + host, + optional(literal(`:`), `[0-9]+`)) + + // DomainRegexp defines the structure of potential domain components + // that may be part of image names. This is purposely a subset of what is + // allowed by DNS to ensure backwards compatibility with Docker image + // names. + DomainRegexp = regexp.MustCompile(domain) + + tag = `[\w][\w.-]{0,127}` + // TagRegexp matches valid tag names. From docker/docker:graph/tags.go. + TagRegexp = regexp.MustCompile(tag) + + anchoredTag = anchored(tag) + // anchoredTagRegexp matches valid tag names, anchored at the start and + // end of the matched string. + anchoredTagRegexp = regexp.MustCompile(anchoredTag) + + digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}` + // DigestRegexp matches valid digests. + DigestRegexp = regexp.MustCompile(digestPat) + + anchoredDigest = anchored(digestPat) + // anchoredDigestRegexp matches valid digests, anchored at the start and + // end of the matched string. + anchoredDigestRegexp = regexp.MustCompile(anchoredDigest) + + namePat = expression( + optional(domain, literal(`/`)), + nameComponent, + optional(repeated(literal(`/`), nameComponent))) + // NameRegexp is the format for the name component of references. The + // regexp has capturing groups for the domain and name part omitting + // the separating forward slash from either. + NameRegexp = regexp.MustCompile(namePat) + + anchoredName = anchored( + optional(capture(domain), literal(`/`)), + capture(nameComponent, + optional(repeated(literal(`/`), nameComponent)))) + // anchoredNameRegexp is used to parse a name value, capturing the + // domain and trailing components. + anchoredNameRegexp = regexp.MustCompile(anchoredName) + + referencePat = anchored(capture(namePat), + optional(literal(":"), capture(tag)), + optional(literal("@"), capture(digestPat))) + // ReferenceRegexp is the full supported format of a reference. The regexp + // is anchored and has capturing groups for name, tag, and digest + // components. + ReferenceRegexp = regexp.MustCompile(referencePat) + + identifier = `([a-f0-9]{64})` + // IdentifierRegexp is the format for string identifier used as a + // content addressable identifier using sha256. These identifiers + // are like digests without the algorithm, since sha256 is used. + IdentifierRegexp = regexp.MustCompile(identifier) + + shortIdentifier = `([a-f0-9]{6,64})` + // ShortIdentifierRegexp is the format used to represent a prefix + // of an identifier. A prefix may be used to match a sha256 identifier + // within a list of trusted identifiers. + ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier) + + anchoredIdentifier = anchored(identifier) + // anchoredIdentifierRegexp is used to check or match an + // identifier value, anchored at start and end of string. + anchoredIdentifierRegexp = regexp.MustCompile(anchoredIdentifier) +) + +// literal compiles s into a literal regular expression, escaping any regexp +// reserved characters. +func literal(s string) string { + re := regexp.MustCompile(regexp.QuoteMeta(s)) + + if _, complete := re.LiteralPrefix(); !complete { + panic("must be a literal") + } + + return re.String() +} + +// expression defines a full expression, where each regular expression must +// follow the previous. +func expression(res ...string) string { + var s string + for _, re := range res { + s += re + } + + return s +} + +// optional wraps the expression in a non-capturing group and makes the +// production optional. +func optional(res ...string) string { + return group(expression(res...)) + `?` +} + +// repeated wraps the regexp in a non-capturing group to get one or more +// matches. +func repeated(res ...string) string { + return group(expression(res...)) + `+` +} + +// group wraps the regexp in a non-capturing group. +func group(res ...string) string { + return `(?:` + expression(res...) + `)` +} + +// capture wraps the expression in a capturing group. +func capture(res ...string) string { + return `(` + expression(res...) + `)` +} + +// anchored anchors the regular expression by adding start and end delimiters. +func anchored(res ...string) string { + return `^` + expression(res...) + `$` +} diff --git a/vendor/github.com/containerd/containerd/reference/docker/sort.go b/vendor/github.com/containerd/containerd/reference/docker/sort.go new file mode 100644 index 00000000000..984e37528d2 --- /dev/null +++ b/vendor/github.com/containerd/containerd/reference/docker/sort.go @@ -0,0 +1,73 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import ( + "sort" +) + +// Sort sorts string references preferring higher information references +// The precedence is as follows: +// 1. Name + Tag + Digest +// 2. Name + Tag +// 3. Name + Digest +// 4. Name +// 5. Digest +// 6. Parse error +func Sort(references []string) []string { + var prefs []Reference + var bad []string + + for _, ref := range references { + pref, err := ParseAnyReference(ref) + if err != nil { + bad = append(bad, ref) + } else { + prefs = append(prefs, pref) + } + } + sort.Slice(prefs, func(a, b int) bool { + ar := refRank(prefs[a]) + br := refRank(prefs[b]) + if ar == br { + return prefs[a].String() < prefs[b].String() + } + return ar < br + }) + sort.Strings(bad) + var refs []string + for _, pref := range prefs { + refs = append(refs, pref.String()) + } + return append(refs, bad...) +} + +func refRank(ref Reference) uint8 { + if _, ok := ref.(Named); ok { + if _, ok = ref.(Tagged); ok { + if _, ok = ref.(Digested); ok { + return 1 + } + return 2 + } + if _, ok = ref.(Digested); ok { + return 3 + } + return 4 + } + return 5 +} diff --git a/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go b/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go index c259873d2a2..64c6a38f91a 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go @@ -29,7 +29,6 @@ import ( "github.com/containerd/containerd/log" remoteserrors "github.com/containerd/containerd/remotes/errors" "github.com/containerd/containerd/version" - "golang.org/x/net/context/ctxhttp" ) var ( @@ -115,7 +114,7 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http. form.Set("access_type", "offline") } - req, err := http.NewRequest("POST", to.Realm, strings.NewReader(form.Encode())) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, to.Realm, strings.NewReader(form.Encode())) if err != nil { return nil, err } @@ -127,7 +126,7 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http. req.Header.Set("User-Agent", "containerd/"+version.Version) } - resp, err := ctxhttp.Do(ctx, client, req) + resp, err := client.Do(req) if err != nil { return nil, err } @@ -162,7 +161,7 @@ type FetchTokenResponse struct { // FetchToken fetches a token using a GET request func FetchToken(ctx context.Context, client *http.Client, headers http.Header, to TokenOptions) (*FetchTokenResponse, error) { - req, err := http.NewRequest("GET", to.Realm, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, to.Realm, nil) if err != nil { return nil, err } @@ -194,7 +193,7 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t req.URL.RawQuery = reqParams.Encode() - resp, err := ctxhttp.Do(ctx, client, req) + resp, err := client.Do(req) if err != nil { return nil, err } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go index eaa0e5dbdbc..8fc823144eb 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go @@ -29,7 +29,6 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/remotes/docker/auth" remoteerrors "github.com/containerd/containerd/remotes/errors" - "github.com/sirupsen/logrus" ) type dockerAuthorizer struct { @@ -45,13 +44,6 @@ type dockerAuthorizer struct { onFetchRefreshToken OnFetchRefreshToken } -// NewAuthorizer creates a Docker authorizer using the provided function to -// get credentials for the token server or basic auth. -// Deprecated: Use NewDockerAuthorizer -func NewAuthorizer(client *http.Client, f func(string) (string, string, error)) Authorizer { - return NewDockerAuthorizer(WithAuthClient(client), WithAuthCreds(f)) -} - type authorizerConfig struct { credentials func(string) (string, string, error) client *http.Client @@ -319,7 +311,7 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken st } return resp.Token, resp.RefreshToken, nil } - log.G(ctx).WithFields(logrus.Fields{ + log.G(ctx).WithFields(log.Fields{ "status": errStatus.Status, "body": string(errStatus.Body), }).Debugf("token request failed") diff --git a/vendor/github.com/containerd/containerd/remotes/docker/converter_fuzz.go b/vendor/github.com/containerd/containerd/remotes/docker/converter_fuzz.go new file mode 100644 index 00000000000..9082053924b --- /dev/null +++ b/vendor/github.com/containerd/containerd/remotes/docker/converter_fuzz.go @@ -0,0 +1,55 @@ +//go:build gofuzz + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import ( + "context" + "os" + + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/containerd/containerd/content/local" + "github.com/containerd/containerd/log" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" +) + +func FuzzConvertManifest(data []byte) int { + ctx := context.Background() + + // Do not log the message below + // level=warning msg="do nothing for media type: ..." + log.G(ctx).Logger.SetLevel(logrus.PanicLevel) + + f := fuzz.NewConsumer(data) + desc := ocispec.Descriptor{} + err := f.GenerateStruct(&desc) + if err != nil { + return 0 + } + tmpdir, err := os.MkdirTemp("", "fuzzing-") + if err != nil { + return 0 + } + cs, err := local.NewStore(tmpdir) + if err != nil { + return 0 + } + _, _ = ConvertManifest(ctx, cs, desc) + return 1 +} diff --git a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go index 11a75356e80..ecf245933f7 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go @@ -29,6 +29,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -52,18 +53,17 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R return newHTTPReadSeeker(desc.Size, func(offset int64) (io.ReadCloser, error) { // firstly try fetch via external urls for _, us := range desc.URLs { - ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", us)) - u, err := url.Parse(us) if err != nil { - log.G(ctx).WithError(err).Debug("failed to parse") + log.G(ctx).WithError(err).Debugf("failed to parse %q", us) continue } if u.Scheme != "http" && u.Scheme != "https" { log.G(ctx).Debug("non-http(s) alternative url is unsupported") continue } - log.G(ctx).Debug("trying alternative url") + ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u)) + log.G(ctx).Info("request") // Try this first, parse it host := RegistryHost{ @@ -151,8 +151,106 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R }) } +func (r dockerFetcher) createGetReq(ctx context.Context, host RegistryHost, ps ...string) (*request, int64, error) { + headReq := r.request(host, http.MethodHead, ps...) + if err := headReq.addNamespace(r.refspec.Hostname()); err != nil { + return nil, 0, err + } + + headResp, err := headReq.doWithRetries(ctx, nil) + if err != nil { + return nil, 0, err + } + if headResp.Body != nil { + headResp.Body.Close() + } + if headResp.StatusCode > 299 { + return nil, 0, fmt.Errorf("unexpected HEAD status code %v: %s", headReq.String(), headResp.Status) + } + + getReq := r.request(host, http.MethodGet, ps...) + if err := getReq.addNamespace(r.refspec.Hostname()); err != nil { + return nil, 0, err + } + return getReq, headResp.ContentLength, nil +} + +func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest) (io.ReadCloser, ocispec.Descriptor, error) { + var desc ocispec.Descriptor + ctx = log.WithLogger(ctx, log.G(ctx).WithField("digest", dgst)) + + hosts := r.filterHosts(HostCapabilityPull) + if len(hosts) == 0 { + return nil, desc, fmt.Errorf("no pull hosts: %w", errdefs.ErrNotFound) + } + + ctx, err := ContextWithRepositoryScope(ctx, r.refspec, false) + if err != nil { + return nil, desc, err + } + + var ( + getReq *request + sz int64 + firstErr error + ) + + for _, host := range r.hosts { + getReq, sz, err = r.createGetReq(ctx, host, "blobs", dgst.String()) + if err == nil { + break + } + // Store the error for referencing later + if firstErr == nil { + firstErr = err + } + } + + if getReq == nil { + // Fall back to the "manifests" endpoint + for _, host := range r.hosts { + getReq, sz, err = r.createGetReq(ctx, host, "manifests", dgst.String()) + if err == nil { + break + } + // Store the error for referencing later + if firstErr == nil { + firstErr = err + } + } + } + + if getReq == nil { + if errdefs.IsNotFound(firstErr) { + firstErr = fmt.Errorf("could not fetch content %v from remote: %w", dgst, errdefs.ErrNotFound) + } + if firstErr == nil { + firstErr = fmt.Errorf("could not fetch content %v from remote: (unknown)", dgst) + } + return nil, desc, firstErr + } + + seeker, err := newHTTPReadSeeker(sz, func(offset int64) (io.ReadCloser, error) { + return r.open(ctx, getReq, "", offset) + }) + if err != nil { + return nil, desc, err + } + + desc = ocispec.Descriptor{ + MediaType: "application/octet-stream", + Digest: dgst, + Size: sz, + } + return seeker, desc, nil +} + func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (_ io.ReadCloser, retErr error) { - req.header.Set("Accept", strings.Join([]string{mediatype, `*/*`}, ", ")) + if mediatype == "" { + req.header.Set("Accept", "*/*") + } else { + req.header.Set("Accept", strings.Join([]string{mediatype, `*/*`}, ", ")) + } if offset > 0 { // Note: "Accept-Ranges: bytes" cannot be trusted as some endpoints diff --git a/vendor/github.com/containerd/containerd/remotes/docker/fetcher_fuzz.go b/vendor/github.com/containerd/containerd/remotes/docker/fetcher_fuzz.go new file mode 100644 index 00000000000..b98886c5956 --- /dev/null +++ b/vendor/github.com/containerd/containerd/remotes/docker/fetcher_fuzz.go @@ -0,0 +1,81 @@ +//go:build gofuzz + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package docker + +import ( + "context" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + + refDocker "github.com/containerd/containerd/reference/docker" +) + +func FuzzFetcher(data []byte) int { + dataLen := len(data) + if dataLen == 0 { + return -1 + } + + s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header().Set("content-range", fmt.Sprintf("bytes %d-%d/%d", 0, dataLen-1, dataLen)) + rw.Header().Set("content-length", fmt.Sprintf("%d", dataLen)) + rw.Write(data) + })) + defer s.Close() + + u, err := url.Parse(s.URL) + if err != nil { + return 0 + } + + f := dockerFetcher{&dockerBase{ + repository: "nonempty", + }} + host := RegistryHost{ + Client: s.Client(), + Host: u.Host, + Scheme: u.Scheme, + Path: u.Path, + } + + ctx := context.Background() + req := f.request(host, http.MethodGet) + rc, err := f.open(ctx, req, "", 0) + if err != nil { + return 0 + } + b, err := io.ReadAll(rc) + if err != nil { + return 0 + } + + expected := data + if len(b) != len(expected) { + panic("len of request is not equal to len of expected but should be") + } + return 1 +} + +func FuzzParseDockerRef(data []byte) int { + _, _ = refDocker.ParseDockerRef(string(data)) + return 1 +} diff --git a/vendor/github.com/containerd/containerd/remotes/docker/handler.go b/vendor/github.com/containerd/containerd/remotes/docker/handler.go index 529cfbc274b..27638ccc02f 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/handler.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/handler.go @@ -30,11 +30,6 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) -var ( - // labelDistributionSource describes the source blob comes from. - labelDistributionSource = "containerd.io/distribution.source" -) - // AppendDistributionSourceLabel updates the label of blob with distribution source. func AppendDistributionSourceLabel(manager content.Manager, ref string) (images.HandlerFunc, error) { refspec, err := reference.Parse(ref) @@ -108,7 +103,7 @@ func appendDistributionSourceLabel(originLabel, repo string) string { } func distributionSourceLabelKey(source string) string { - return fmt.Sprintf("%s.%s", labelDistributionSource, source) + return fmt.Sprintf("%s.%s", labels.LabelDistributionSource, source) } // selectRepositoryMountCandidate will select the repo which has longest diff --git a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go index 56d60efe93b..ef6e8056a0d 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go @@ -191,6 +191,9 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str if resp == nil { resp, err = req.doWithRetries(ctx, nil) if err != nil { + if errors.Is(err, ErrInvalidAuthorization) { + return nil, fmt.Errorf("push access denied, repository does not exist or may require authorization: %w", err) + } return nil, err } } @@ -377,17 +380,24 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) { // If content has already been written, the bytes // cannot be written and the caller must reset - if status.Offset > 0 { - status.Offset = 0 - status.UpdatedAt = time.Now() - pw.tracker.SetStatus(pw.ref, status) - return 0, content.ErrReset - } + status.Offset = 0 + status.UpdatedAt = time.Now() + pw.tracker.SetStatus(pw.ref, status) + return 0, content.ErrReset default: } } n, err = pw.pipe.Write(p) + if errors.Is(err, io.ErrClosedPipe) { + // if the pipe is closed, we might have the original error on the error + // channel - so we should try and get it + select { + case err2 := <-pw.errC: + err = err2 + default: + } + } status.Offset += int64(n) status.UpdatedAt = time.Now() pw.tracker.SetStatus(pw.ref, status) @@ -428,7 +438,7 @@ func (pw *pushWriter) Digest() digest.Digest { func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { // Check whether read has already thrown an error - if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe { + if _, err := pw.pipe.Write([]byte{}); err != nil && !errors.Is(err, io.ErrClosedPipe) { return fmt.Errorf("pipe error before commit: %w", err) } @@ -439,9 +449,7 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di var resp *http.Response select { case err := <-pw.errC: - if err != nil { - return err - } + return err case resp = <-pw.respC: defer resp.Body.Close() case p, ok := <-pw.pipeC: @@ -453,18 +461,17 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di } pw.pipe.CloseWithError(content.ErrReset) pw.pipe = p + + // If content has already been written, the bytes + // cannot be written again and the caller must reset status, err := pw.tracker.GetStatus(pw.ref) if err != nil { return err } - // If content has already been written, the bytes - // cannot be written again and the caller must reset - if status.Offset > 0 { - status.Offset = 0 - status.UpdatedAt = time.Now() - pw.tracker.SetStatus(pw.ref, status) - return content.ErrReset - } + status.Offset = 0 + status.UpdatedAt = time.Now() + pw.tracker.SetStatus(pw.ref, status) + return content.ErrReset } // 201 is specified return status, some registries return diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index 709fa028de2..3d6c0182f1b 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -32,12 +32,12 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes" - "github.com/containerd/containerd/remotes/docker/schema1" + "github.com/containerd/containerd/remotes/docker/schema1" //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. + remoteerrors "github.com/containerd/containerd/remotes/errors" + "github.com/containerd/containerd/tracing" "github.com/containerd/containerd/version" - digest "github.com/opencontainers/go-digest" + "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/sirupsen/logrus" - "golang.org/x/net/context/ctxhttp" ) var ( @@ -70,6 +70,9 @@ type Authorizer interface { // unmodified. It may also add an `Authorization` header as // "bearer " // "basic " + // + // It may return remotes/errors.ErrUnexpectedStatus, which for example, + // can be used by the caller to find out the status code returned by the registry. Authorize(context.Context, *http.Request) error // AddResponses adds a 401 response for the authorizer to consider when @@ -95,25 +98,30 @@ type ResolverOptions struct { Tracker StatusTracker // Authorizer is used to authorize registry requests - // Deprecated: use Hosts + // + // Deprecated: use Hosts. Authorizer Authorizer // Credentials provides username and secret given a host. // If username is empty but a secret is given, that secret // is interpreted as a long lived token. - // Deprecated: use Hosts + // + // Deprecated: use Hosts. Credentials func(string) (string, string, error) // Host provides the hostname given a namespace. - // Deprecated: use Hosts + // + // Deprecated: use Hosts. Host func(string) (string, error) // PlainHTTP specifies to use plain http and not https - // Deprecated: use Hosts + // + // Deprecated: use Hosts. PlainHTTP bool // Client is the http client to used when making registry requests - // Deprecated: use Hosts + // + // Deprecated: use Hosts. Client *http.Client } @@ -140,6 +148,9 @@ func NewResolver(options ResolverOptions) remotes.Resolver { if options.Headers == nil { options.Headers = make(http.Header) + } else { + // make a copy of the headers to avoid race due to concurrent map write + options.Headers = options.Headers.Clone() } if _, ok := options.Headers["User-Agent"]; !ok { options.Headers.Set("User-Agent", "containerd/"+version.Version) @@ -152,7 +163,8 @@ func NewResolver(options ResolverOptions) remotes.Resolver { images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageManifest, - ocispec.MediaTypeImageIndex, "*/*"}, ", ")) + ocispec.MediaTypeImageIndex, "*/*", + }, ", ")) } else { resolveHeader["Accept"] = options.Headers["Accept"] delete(options.Headers, "Accept") @@ -299,11 +311,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp if resp.StatusCode > 399 { // Set firstErr when encountering the first non-404 status code. if firstErr == nil { - firstErr = fmt.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) + firstErr = remoteerrors.NewUnexpectedStatusErr(resp) } continue // try another host } - return "", ocispec.Descriptor{}, fmt.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) + return "", ocispec.Descriptor{}, remoteerrors.NewUnexpectedStatusErr(resp) } size := resp.ContentLength contentType := getManifestMediaType(resp) @@ -340,26 +352,31 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp if err != nil { return "", ocispec.Descriptor{}, err } - defer resp.Body.Close() bodyReader := countingReader{reader: resp.Body} contentType = getManifestMediaType(resp) - if dgst == "" { + err = func() error { + defer resp.Body.Close() + if dgst != "" { + _, err = io.Copy(io.Discard, &bodyReader) + return err + } + if contentType == images.MediaTypeDockerSchema1Manifest { b, err := schema1.ReadStripSignature(&bodyReader) if err != nil { - return "", ocispec.Descriptor{}, err + return err } dgst = digest.FromBytes(b) - } else { - dgst, err = digest.FromReader(&bodyReader) - if err != nil { - return "", ocispec.Descriptor{}, err - } + return nil } - } else if _, err := io.Copy(io.Discard, &bodyReader); err != nil { + + dgst, err = digest.FromReader(&bodyReader) + return err + }() + if err != nil { return "", ocispec.Descriptor{}, err } size = bodyReader.bytesRead @@ -525,13 +542,14 @@ type request struct { func (r *request) do(ctx context.Context) (*http.Response, error) { u := r.host.Scheme + "://" + r.host.Host + r.path - req, err := http.NewRequest(r.method, u, nil) + req, err := http.NewRequestWithContext(ctx, r.method, u, nil) if err != nil { return nil, err } - req.Header = http.Header{} // headers need to be copied to avoid concurrent map access - for k, v := range r.header { - req.Header[k] = v + if r.header == nil { + req.Header = http.Header{} + } else { + req.Header = r.header.Clone() // headers need to be copied to avoid concurrent map access } if r.body != nil { body, err := r.body() @@ -551,7 +569,7 @@ func (r *request) do(ctx context.Context) (*http.Response, error) { return nil, fmt.Errorf("failed to authorize: %w", err) } - var client = &http.Client{} + client := &http.Client{} if r.host.Client != nil { *client = *r.host.Client } @@ -566,11 +584,18 @@ func (r *request) do(ctx context.Context) (*http.Response, error) { return nil } } - - resp, err := ctxhttp.Do(ctx, client, req) + _, httpSpan := tracing.StartSpan( + ctx, + tracing.Name("remotes.docker.resolver", "HTTPRequest"), + tracing.WithHTTPRequest(req), + ) + defer httpSpan.End() + resp, err := client.Do(req) if err != nil { + httpSpan.SetStatus(err) return nil, fmt.Errorf("failed to do request: %w", err) } + httpSpan.SetAttributes(tracing.HTTPStatusCodeAttributes(resp.StatusCode)...) log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received") return resp, nil } @@ -630,7 +655,7 @@ func (r *request) String() string { return r.host.Scheme + "://" + r.host.Host + r.path } -func requestFields(req *http.Request) logrus.Fields { +func requestFields(req *http.Request) log.Fields { fields := map[string]interface{}{ "request.method": req.Method, } @@ -648,10 +673,10 @@ func requestFields(req *http.Request) logrus.Fields { } } - return logrus.Fields(fields) + return fields } -func responseFields(resp *http.Response) logrus.Fields { +func responseFields(resp *http.Response) log.Fields { fields := map[string]interface{}{ "response.status": resp.Status, } @@ -666,7 +691,7 @@ func responseFields(resp *http.Response) logrus.Fields { } } - return logrus.Fields(fields) + return fields } // IsLocalhost checks if the registry host is local. diff --git a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go index efa4e8d6eeb..8c9e520cd27 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go @@ -14,6 +14,9 @@ limitations under the License. */ +// Package schema1 provides a converter to fetch an image formatted in Docker Image Manifest v2, Schema 1. +// +// Deprecated: use images formatted in Docker Image Manifest v2, Schema 2, or OCI Image Spec v1. package schema1 import ( @@ -33,6 +36,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/labels" "github.com/containerd/containerd/log" "github.com/containerd/containerd/remotes" digest "github.com/opencontainers/go-digest" @@ -363,12 +367,12 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro cinfo := content.Info{ Digest: desc.Digest, Labels: map[string]string{ - "containerd.io/uncompressed": state.diffID.String(), + labels.LabelUncompressed: state.diffID.String(), labelDockerSchema1EmptyLayer: strconv.FormatBool(state.empty), }, } - if _, err := c.contentStore.Update(ctx, cinfo, "labels.containerd.io/uncompressed", fmt.Sprintf("labels.%s", labelDockerSchema1EmptyLayer)); err != nil { + if _, err := c.contentStore.Update(ctx, cinfo, "labels."+labels.LabelUncompressed, fmt.Sprintf("labels.%s", labelDockerSchema1EmptyLayer)); err != nil { return fmt.Errorf("failed to update uncompressed label: %w", err) } @@ -387,7 +391,7 @@ func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descri } desc.Size = cinfo.Size - diffID, ok := cinfo.Labels["containerd.io/uncompressed"] + diffID, ok := cinfo.Labels[labels.LabelUncompressed] if !ok { return false, nil } @@ -406,7 +410,7 @@ func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descri bState := blobState{empty: isEmpty} if bState.diffID, err = digest.Parse(diffID); err != nil { - log.G(ctx).WithField("id", desc.Digest).Warnf("failed to parse digest from label containerd.io/uncompressed: %v", diffID) + log.G(ctx).WithField("id", desc.Digest).Warnf("failed to parse digest from label %s: %v", labels.LabelUncompressed, diffID) return false, nil } diff --git a/vendor/github.com/containerd/containerd/remotes/errors/errors.go b/vendor/github.com/containerd/containerd/remotes/errors/errors.go index 67ccb23df6e..f60ff0fc286 100644 --- a/vendor/github.com/containerd/containerd/remotes/errors/errors.go +++ b/vendor/github.com/containerd/containerd/remotes/errors/errors.go @@ -33,7 +33,7 @@ type ErrUnexpectedStatus struct { } func (e ErrUnexpectedStatus) Error() string { - return fmt.Sprintf("unexpected status: %s", e.Status) + return fmt.Sprintf("unexpected status from %s request to %s: %s", e.RequestMethod, e.RequestURL, e.Status) } // NewUnexpectedStatusErr creates an ErrUnexpectedStatus from HTTP response diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index 4d91ed2e54d..0ff39179c2b 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -17,6 +17,7 @@ package remotes import ( + "bytes" "context" "errors" "fmt" @@ -27,10 +28,10 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/labels" "github.com/containerd/containerd/log" "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" ) @@ -90,7 +91,7 @@ func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string { // recursive fetch. func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) { - ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{ + ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{ "digest": desc.Digest, "mediatype": desc.MediaType, "size": desc.Size, @@ -100,20 +101,21 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc case images.MediaTypeDockerSchema1Manifest: return nil, fmt.Errorf("%v not supported", desc.MediaType) default: - err := fetch(ctx, ingester, fetcher, desc) + err := Fetch(ctx, ingester, fetcher, desc) + if errdefs.IsAlreadyExists(err) { + return nil, nil + } return nil, err } } } -func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error { +// Fetch fetches the given digest into the provided ingester +func Fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error { log.G(ctx).Debug("fetch") cw, err := content.OpenWriter(ctx, ingester, content.WithRef(MakeRefKey(ctx, desc)), content.WithDescriptor(desc)) if err != nil { - if errdefs.IsAlreadyExists(err) { - return nil - } return err } defer cw.Close() @@ -135,7 +137,11 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc if err != nil && !errdefs.IsAlreadyExists(err) { return fmt.Errorf("failed commit on ref %q: %w", ws.Ref, err) } - return nil + return err + } + + if desc.Size == int64(len(desc.Data)) { + return content.Copy(ctx, cw, bytes.NewReader(desc.Data), desc.Size, desc.Digest) } rc, err := fetcher.Fetch(ctx, desc) @@ -151,7 +157,7 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc // using a writer from the pusher. func PushHandler(pusher Pusher, provider content.Provider) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{ + ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{ "digest": desc.Digest, "mediatype": desc.MediaType, "size": desc.Size, @@ -197,17 +203,26 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc // // Base handlers can be provided which will be called before any push specific // handlers. -func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Store, limiter *semaphore.Weighted, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error { +// +// If the passed in content.Provider is also a content.InfoProvider (such as +// content.Manager) then this will also annotate the distribution sources using +// labels prefixed with "containerd.io/distribution.source". +func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, store content.Provider, limiter *semaphore.Weighted, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error { var m sync.Mutex - manifestStack := []ocispec.Descriptor{} + manifests := []ocispec.Descriptor{} + indexStack := []ocispec.Descriptor{} filterHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, - images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: m.Lock() - manifestStack = append(manifestStack, desc) + manifests = append(manifests, desc) + m.Unlock() + return nil, images.ErrStopHandler + case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + m.Lock() + indexStack = append(indexStack, desc) m.Unlock() return nil, images.ErrStopHandler default: @@ -219,13 +234,14 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st platformFilterhandler := images.FilterPlatforms(images.ChildrenHandler(store), platform) - annotateHandler := annotateDistributionSourceHandler(platformFilterhandler, store) + var handler images.Handler + if m, ok := store.(content.InfoProvider); ok { + annotateHandler := annotateDistributionSourceHandler(platformFilterhandler, m) + handler = images.Handlers(annotateHandler, filterHandler, pushHandler) + } else { + handler = images.Handlers(platformFilterhandler, filterHandler, pushHandler) + } - var handler images.Handler = images.Handlers( - annotateHandler, - filterHandler, - pushHandler, - ) if wrapper != nil { handler = wrapper(handler) } @@ -234,16 +250,18 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st return err } + if err := images.Dispatch(ctx, pushHandler, limiter, manifests...); err != nil { + return err + } + // Iterate in reverse order as seen, parent always uploaded after child - for i := len(manifestStack) - 1; i >= 0; i-- { - _, err := pushHandler(ctx, manifestStack[i]) + for i := len(indexStack) - 1; i >= 0; i-- { + err := images.Dispatch(ctx, pushHandler, limiter, indexStack[i]) if err != nil { // TODO(estesp): until we have a more complete method for index push, we need to report // missing dependencies in an index/manifest list by sensing the "400 Bad Request" // as a marker for this problem - if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || - manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && - errors.Unwrap(err) != nil && strings.Contains(errors.Unwrap(err).Error(), "400 Bad Request") { + if errors.Unwrap(err) != nil && strings.Contains(errors.Unwrap(err).Error(), "400 Bad Request") { return fmt.Errorf("manifest list/index references to blobs and/or manifests are missing in your target registry: %w", err) } return err @@ -327,14 +345,15 @@ func FilterManifestByPlatformHandler(f images.HandlerFunc, m platforms.Matcher) // annotateDistributionSourceHandler add distribution source label into // annotation of config or blob descriptor. -func annotateDistributionSourceHandler(f images.HandlerFunc, manager content.Manager) images.HandlerFunc { +func annotateDistributionSourceHandler(f images.HandlerFunc, provider content.InfoProvider) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { children, err := f(ctx, desc) if err != nil { return nil, err } - // only add distribution source for the config or blob data descriptor + // Distribution source is only used for config or blob but may be inherited from + // a manifest or manifest list switch desc.MediaType { case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: @@ -342,16 +361,32 @@ func annotateDistributionSourceHandler(f images.HandlerFunc, manager content.Man return children, nil } + // parentInfo can be used to inherit info for non-existent blobs + var parentInfo *content.Info + for i := range children { child := children[i] - info, err := manager.Info(ctx, child.Digest) + info, err := provider.Info(ctx, child.Digest) if err != nil { - return nil, err + if !errdefs.IsNotFound(err) { + return nil, err + } + if parentInfo == nil { + pi, err := provider.Info(ctx, desc.Digest) + if err != nil { + return nil, err + } + parentInfo = &pi + } + // Blob may not exist locally, annotate with parent labels for cross repo + // mount or fetch. Parent sources may apply to all children since most + // registries enforce that children exist before the manifests. + info = *parentInfo } for k, v := range info.Labels { - if !strings.HasPrefix(k, "containerd.io/distribution.source.") { + if !strings.HasPrefix(k, labels.LabelDistributionSource+".") { continue } diff --git a/vendor/github.com/containerd/containerd/remotes/resolver.go b/vendor/github.com/containerd/containerd/remotes/resolver.go index 624b14f05d6..f200c84bc7d 100644 --- a/vendor/github.com/containerd/containerd/remotes/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/resolver.go @@ -21,6 +21,7 @@ import ( "io" "github.com/containerd/containerd/content" + "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -33,7 +34,7 @@ type Resolver interface { // reference a specific host or be matched against a specific handler. // // The returned name should be used to identify the referenced entity. - // Dependending on the remote namespace, this may be immutable or mutable. + // Depending on the remote namespace, this may be immutable or mutable. // While the name may differ from ref, it should itself be a valid ref. // // If the resolution fails, an error will be returned. @@ -50,12 +51,23 @@ type Resolver interface { Pusher(ctx context.Context, ref string) (Pusher, error) } -// Fetcher fetches content +// Fetcher fetches content. +// A fetcher implementation may implement the FetcherByDigest interface too. type Fetcher interface { // Fetch the resource identified by the descriptor. Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) } +// FetcherByDigest fetches content by the digest. +type FetcherByDigest interface { + // FetchByDigest fetches the resource identified by the digest. + // + // FetcherByDigest usually returns an incomplete descriptor. + // Typically, the media type is always set to "application/octet-stream", + // and the annotations are unset. + FetchByDigest(ctx context.Context, dgst digest.Digest) (io.ReadCloser, ocispec.Descriptor, error) +} + // Pusher pushes content type Pusher interface { // Push returns a content writer for the given resource identified diff --git a/vendor/github.com/containerd/containerd/tracing/helpers.go b/vendor/github.com/containerd/containerd/tracing/helpers.go new file mode 100644 index 00000000000..981da6c7953 --- /dev/null +++ b/vendor/github.com/containerd/containerd/tracing/helpers.go @@ -0,0 +1,94 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tracing + +import ( + "encoding/json" + "fmt" + "strings" + + "go.opentelemetry.io/otel/attribute" +) + +const ( + spanDelimiter = "." +) + +func makeSpanName(names ...string) string { + return strings.Join(names, spanDelimiter) +} + +func any(k string, v interface{}) attribute.KeyValue { + if v == nil { + return attribute.String(k, "") + } + + switch typed := v.(type) { + case bool: + return attribute.Bool(k, typed) + case []bool: + return attribute.BoolSlice(k, typed) + case int: + return attribute.Int(k, typed) + case []int: + return attribute.IntSlice(k, typed) + case int8: + return attribute.Int(k, int(typed)) + case []int8: + ls := make([]int, 0, len(typed)) + for _, i := range typed { + ls = append(ls, int(i)) + } + return attribute.IntSlice(k, ls) + case int16: + return attribute.Int(k, int(typed)) + case []int16: + ls := make([]int, 0, len(typed)) + for _, i := range typed { + ls = append(ls, int(i)) + } + return attribute.IntSlice(k, ls) + case int32: + return attribute.Int64(k, int64(typed)) + case []int32: + ls := make([]int64, 0, len(typed)) + for _, i := range typed { + ls = append(ls, int64(i)) + } + return attribute.Int64Slice(k, ls) + case int64: + return attribute.Int64(k, typed) + case []int64: + return attribute.Int64Slice(k, typed) + case float64: + return attribute.Float64(k, typed) + case []float64: + return attribute.Float64Slice(k, typed) + case string: + return attribute.String(k, typed) + case []string: + return attribute.StringSlice(k, typed) + } + + if stringer, ok := v.(fmt.Stringer); ok { + return attribute.String(k, stringer.String()) + } + if b, err := json.Marshal(v); b != nil && err == nil { + return attribute.String(k, string(b)) + } + return attribute.String(k, fmt.Sprintf("%v", v)) +} diff --git a/vendor/github.com/containerd/containerd/tracing/log.go b/vendor/github.com/containerd/containerd/tracing/log.go new file mode 100644 index 00000000000..98fa16f931e --- /dev/null +++ b/vendor/github.com/containerd/containerd/tracing/log.go @@ -0,0 +1,66 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tracing + +import ( + "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +// NewLogrusHook creates a new logrus hook +func NewLogrusHook() *LogrusHook { + return &LogrusHook{} +} + +// LogrusHook is a logrus hook which adds logrus events to active spans. +// If the span is not recording or the span context is invalid, the hook is a no-op. +type LogrusHook struct{} + +// Levels returns the logrus levels that this hook is interested in. +func (h *LogrusHook) Levels() []logrus.Level { + return logrus.AllLevels +} + +// Fire is called when a log event occurs. +func (h *LogrusHook) Fire(entry *logrus.Entry) error { + span := trace.SpanFromContext(entry.Context) + if span == nil { + return nil + } + + if !span.SpanContext().IsValid() || !span.IsRecording() { + return nil + } + + span.AddEvent( + entry.Message, + trace.WithAttributes(logrusDataToAttrs(entry.Data)...), + trace.WithAttributes(attribute.String("level", entry.Level.String())), + trace.WithTimestamp(entry.Time), + ) + + return nil +} + +func logrusDataToAttrs(data logrus.Fields) []attribute.KeyValue { + attrs := make([]attribute.KeyValue, 0, len(data)) + for k, v := range data { + attrs = append(attrs, any(k, v)) + } + return attrs +} diff --git a/vendor/github.com/containerd/containerd/tracing/tracing.go b/vendor/github.com/containerd/containerd/tracing/tracing.go new file mode 100644 index 00000000000..7fe7bfd5bf2 --- /dev/null +++ b/vendor/github.com/containerd/containerd/tracing/tracing.go @@ -0,0 +1,117 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tracing + +import ( + "context" + "net/http" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" + httpconv "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv" + "go.opentelemetry.io/otel/trace" +) + +// StartConfig defines configuration for a new span object. +type StartConfig struct { + spanOpts []trace.SpanStartOption +} + +type SpanOpt func(config *StartConfig) + +// WithHTTPRequest marks span as a HTTP request operation from client to server. +// It'll append attributes from the HTTP request object and mark it with `SpanKindClient` type. +func WithHTTPRequest(request *http.Request) SpanOpt { + return func(config *StartConfig) { + config.spanOpts = append(config.spanOpts, + trace.WithSpanKind(trace.SpanKindClient), // A client making a request to a server + trace.WithAttributes(httpconv.ClientRequest(request)...), // Add HTTP attributes + ) + } +} + +// StartSpan starts child span in a context. +func StartSpan(ctx context.Context, opName string, opts ...SpanOpt) (context.Context, *Span) { + config := StartConfig{} + for _, fn := range opts { + fn(&config) + } + tracer := otel.Tracer("") + if parent := trace.SpanFromContext(ctx); parent != nil && parent.SpanContext().IsValid() { + tracer = parent.TracerProvider().Tracer("") + } + ctx, span := tracer.Start(ctx, opName, config.spanOpts...) + return ctx, &Span{otelSpan: span} +} + +// SpanFromContext returns the current Span from the context. +func SpanFromContext(ctx context.Context) *Span { + return &Span{ + otelSpan: trace.SpanFromContext(ctx), + } +} + +// Span is wrapper around otel trace.Span. +// Span is the individual component of a trace. It represents a +// single named and timed operation of a workflow that is traced. +type Span struct { + otelSpan trace.Span +} + +// End completes the span. +func (s *Span) End() { + s.otelSpan.End() +} + +// AddEvent adds an event with provided name and options. +func (s *Span) AddEvent(name string, options ...trace.EventOption) { + s.otelSpan.AddEvent(name, options...) +} + +// SetStatus sets the status of the current span. +// If an error is encountered, it records the error and sets span status to Error. +func (s *Span) SetStatus(err error) { + if err != nil { + s.otelSpan.RecordError(err) + s.otelSpan.SetStatus(codes.Error, err.Error()) + } else { + s.otelSpan.SetStatus(codes.Ok, "") + } +} + +// SetAttributes sets kv as attributes of the span. +func (s *Span) SetAttributes(kv ...attribute.KeyValue) { + s.otelSpan.SetAttributes(kv...) +} + +// Name sets the span name by joining a list of strings in dot separated format. +func Name(names ...string) string { + return makeSpanName(names...) +} + +// Attribute takes a key value pair and returns attribute.KeyValue type. +func Attribute(k string, v interface{}) attribute.KeyValue { + return any(k, v) +} + +// HTTPStatusCodeAttributes generates attributes of the HTTP namespace as specified by the OpenTelemetry +// specification for a span. +func HTTPStatusCodeAttributes(code int) []attribute.KeyValue { + return []attribute.KeyValue{semconv.HTTPStatusCodeKey.Int(code)} +} diff --git a/vendor/github.com/containerd/containerd/version/version.go b/vendor/github.com/containerd/containerd/version/version.go index 6e76097d271..350f81eaced 100644 --- a/vendor/github.com/containerd/containerd/version/version.go +++ b/vendor/github.com/containerd/containerd/version/version.go @@ -23,7 +23,7 @@ var ( Package = "github.com/containerd/containerd" // Version holds the complete version number. Filled in at linking time. - Version = "1.6.12+unknown" + Version = "1.7.6+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build // the program at linking time. diff --git a/vendor/github.com/dapr/go-sdk/LICENSE b/vendor/github.com/dapr/go-sdk/LICENSE new file mode 100644 index 00000000000..c2c85ba5774 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 The Dapr Authors. + + and others that have contributed code to the public domain. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/dapr/go-sdk/actor/actor.go b/vendor/github.com/dapr/go-sdk/actor/actor.go new file mode 100644 index 00000000000..c14d65506e6 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/actor.go @@ -0,0 +1,225 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package actor + +import ( + "context" + "sync" + "time" +) + +// Client is the interface that should be impl by user's actor client. +type Client interface { + // Type defines the type of the actor server to be invoke + Type() string + // ID should be unique, the actor server with target ID would be created before server processing the invocation. + ID() string +} + +// Deprecated: Server is deprecated in favour of ServerContext. +type Server interface { + // ID is impl by ServerImplBase. It can be called by user defined actor function to get the actor ID of it's instance. + ID() string + // SetID is impl by ServerImplBase. It is called by actor container to inject actor ID of the instance, and should + // not called by user + SetID(string) + // Type is defined by user + Type() string + // SetStateManager is impl by ServerImplBase to inject StateManager to this actor instance + // Deprecated: SetStateManager is deprecated in favour of SetStateManagerContext. + SetStateManager(StateManager) + // SaveState is impl by ServerImplBase, It saves the state cache of this actor instance to state store component by calling api of daprd. + // Save state is called at two places: 1. On invocation of this actor instance. 2. When new actor starts. + SaveState() error + + WithContext() ServerContext +} + +// ServerContext is the interface that would be impl by user's actor server with ServerImplBaseCtx +/* +Actor user should only impls func Type() string, and his user-defined-method, Other function could be impl by +combining ServerImplBaseCtx. +*/ +type ServerContext interface { + // ID is impl by ServerImplBase. It can be called by user defined actor function to get the actor ID of it's instance. + ID() string + // SetID is impl by ServerImplBase. It is called by actor container to inject actor ID of the instance, and should + // not called by user + SetID(string) + // Type is defined by user + Type() string + // SetStateManager is impl by ServerImplBase to inject StateManager to this actor instance + SetStateManager(StateManagerContext) + // SaveState is impl by ServerImplBase, It saves the state cache of this actor instance to state store component by calling api of daprd. + // Save state is called at two places: 1. On invocation of this actor instance. 2. When new actor starts. + SaveState(context.Context) error +} + +type ReminderCallee interface { + ReminderCall(string, []byte, string, string) +} + +type ( + Factory func() Server + FactoryContext func() ServerContext +) + +// Deprecated: ServerImplBase is deprecated in favour of ServerImplBaseCtx. +type ServerImplBase struct { + stateManager StateManager + ctx ServerImplBaseCtx + lock sync.RWMutex +} + +type ServerImplBaseCtx struct { + stateManager StateManagerContext + once sync.Once + id string + lock sync.RWMutex +} + +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) SetStateManager(stateManager StateManager) { + b.lock.Lock() + b.ctx.lock.Lock() + defer b.lock.Unlock() + defer b.ctx.lock.Unlock() + b.stateManager = stateManager + b.ctx.stateManager = stateManager.WithContext() +} + +// GetStateManager can be called by user-defined-method, to get state manager +// of this actor instance. +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) GetStateManager() StateManager { + b.ctx.lock.RLock() + defer b.ctx.lock.RUnlock() + return b.stateManager +} + +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) ID() string { + b.ctx.lock.RLock() + defer b.ctx.lock.RUnlock() + return b.ctx.id +} + +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) SetID(id string) { + b.lock.RLock() + defer b.lock.RUnlock() + b.ctx.SetID(id) +} + +// SaveState is to saves the state cache of this actor instance to state store +// component by calling api of daprd. +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) SaveState() error { + b.lock.RLock() + defer b.lock.RUnlock() + return b.ctx.SaveState(context.Background()) +} + +// Deprecated: Use ServerImplBaseCtx instead. +func (b *ServerImplBase) WithContext() *ServerImplBaseCtx { + b.ctx.lock.RLock() + defer b.ctx.lock.RUnlock() + return &b.ctx +} + +func (b *ServerImplBaseCtx) SetStateManager(stateManager StateManagerContext) { + b.lock.Lock() + defer b.lock.Unlock() + b.stateManager = stateManager +} + +// GetStateManager can be called by user-defined-method, to get state manager +// of this actor instance. +func (b *ServerImplBaseCtx) GetStateManager() StateManagerContext { + b.lock.RLock() + defer b.lock.RUnlock() + return b.stateManager +} + +func (b *ServerImplBaseCtx) ID() string { + b.lock.RLock() + defer b.lock.RUnlock() + return b.id +} + +func (b *ServerImplBaseCtx) SetID(id string) { + b.lock.RLock() + defer b.lock.RUnlock() + b.once.Do(func() { + b.id = id + }) +} + +// SaveState is to saves the state cache of this actor instance to state store +// component by calling api of daprd. +func (b *ServerImplBaseCtx) SaveState(ctx context.Context) error { + b.lock.RLock() + defer b.lock.RUnlock() + + if b.stateManager != nil { + return b.stateManager.Save(ctx) + } + + return nil +} + +// Deprecated: StateManager is deprecated in favour of StateManagerContext. +type StateManager interface { + // Add is to add new state store with @stateName and @value + Add(stateName string, value any) error + // Get is to get state store of @stateName with type @reply + Get(stateName string, reply any) error + // Set is to set new state store with @stateName and @value + Set(stateName string, value any) error + // Remove is to remove state store with @stateName + Remove(stateName string) error + // Contains is to check if state store contains @stateName + Contains(stateName string) (bool, error) + // Save is to saves the state cache of this actor instance to state store component by calling api of daprd. + Save() error + // Flush is called by StateManager after Save + Flush() + + // Returns a new StateManagerContext with the same state as this StateManager + // but uses context. + WithContext() StateManagerContext +} + +type StateManagerContext interface { + // Add is to add new state store with @stateName and @value + Add(ctx context.Context, stateName string, value any) error + // Get is to get state store of @stateName with type @reply + Get(ctx context.Context, stateName string, reply any) error + // Set sets a state store with @stateName and @value. + Set(ctx context.Context, stateName string, value any) error + // SetWithTTL sets a state store with @stateName and @value, for the given + // TTL. After the TTL has passed, the value will no longer be available with + // `Get`. Always preferred over `Set`. + // NOTE: SetWithTTL is in feature preview as of v1.11, and only available + // with the `ActorStateTTL` feature enabled in Dapr. + SetWithTTL(ctx context.Context, stateName string, value any, ttl time.Duration) error + // Remove is to remove state store with @stateName + Remove(ctx context.Context, stateName string) error + // Contains is to check if state store contains @stateName + Contains(ctx context.Context, stateName string) (bool, error) + // Save is to saves the state cache of this actor instance to state store component by calling api of daprd. + Save(ctx context.Context) error + // Flush is called by StateManager after Save + Flush(ctx context.Context) +} diff --git a/vendor/github.com/dapr/go-sdk/actor/api/reminder.go b/vendor/github.com/dapr/go-sdk/actor/api/reminder.go new file mode 100644 index 00000000000..5fc2f78ee76 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/api/reminder.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +type ActorReminderParams struct { + Data []byte `json:"data"` + DueTime string `json:"dueTime"` + Period string `json:"period"` + TTL string `json:"ttl"` +} diff --git a/vendor/github.com/dapr/go-sdk/actor/api/runtime.go b/vendor/github.com/dapr/go-sdk/actor/api/runtime.go new file mode 100644 index 00000000000..58c0eb6446d --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/api/runtime.go @@ -0,0 +1,22 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +type ActorRuntimeConfig struct { + RegisteredActorTypes []string `json:"entities"` + ActorIdleTimeout string `json:"actorIdleTimeout"` + ActorScanInterval string `json:"actorScanInterval"` + DrainOngingCallTimeout string `json:"drainOngoingCallTimeout"` + DrainBalancedActors bool `json:"drainRebalancedActors"` +} diff --git a/vendor/github.com/dapr/go-sdk/actor/api/timer.go b/vendor/github.com/dapr/go-sdk/actor/api/timer.go new file mode 100644 index 00000000000..ad118283ac5 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/api/timer.go @@ -0,0 +1,22 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +type ActorTimerParam struct { + CallBack string `json:"callback"` + Data []byte `json:"data"` + DueTime string `json:"dueTime"` + Period string `json:"period"` + TTL string `json:"ttl"` +} diff --git a/vendor/github.com/dapr/go-sdk/actor/codec/codec.go b/vendor/github.com/dapr/go-sdk/actor/codec/codec.go new file mode 100644 index 00000000000..ea96c47b50d --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/codec/codec.go @@ -0,0 +1,44 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package codec + +import ( + "fmt" +) + +// Codec is serializer interface. +type Codec interface { + Marshal(interface{}) ([]byte, error) + Unmarshal([]byte, interface{}) error +} + +// Factory is factory of codec. +type Factory func() Codec + +// codecFactoryMap stores. +var codecFactoryMap = make(map[string]Factory) + +// SetActorCodec set Actor's Codec. +func SetActorCodec(name string, f Factory) { + codecFactoryMap[name] = f +} + +// GetActorCodec gets the target codec instance. +func GetActorCodec(name string) (Codec, error) { + f, ok := codecFactoryMap[name] + if !ok { + return nil, fmt.Errorf("no actor codec implement named %s", name) + } + return f(), nil +} diff --git a/vendor/github.com/dapr/go-sdk/actor/codec/constant/constant.go b/vendor/github.com/dapr/go-sdk/actor/codec/constant/constant.go new file mode 100644 index 00000000000..556d0589c5e --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/codec/constant/constant.go @@ -0,0 +1,20 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package constant + +// DefaultSerializerType is default actor invocation serialization type json. +const DefaultSerializerType = "json" + +// YamlSerializerType is yaml actor invocation serialization type. +const YamlSerializerType = "yaml" diff --git a/vendor/github.com/dapr/go-sdk/actor/codec/impl/json.go b/vendor/github.com/dapr/go-sdk/actor/codec/impl/json.go new file mode 100644 index 00000000000..adde1266662 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/codec/impl/json.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package impl + +import ( + "encoding/json" + + "github.com/dapr/go-sdk/actor/codec" + "github.com/dapr/go-sdk/actor/codec/constant" +) + +func init() { + codec.SetActorCodec(constant.DefaultSerializerType, func() codec.Codec { + return &JSONCodec{} + }) +} + +// JSONCodec is json impl of codec.Codec. +type JSONCodec struct{} + +func (j *JSONCodec) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +func (j *JSONCodec) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} diff --git a/vendor/github.com/dapr/go-sdk/actor/codec/impl/yaml.go b/vendor/github.com/dapr/go-sdk/actor/codec/impl/yaml.go new file mode 100644 index 00000000000..bd8a385c0aa --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/codec/impl/yaml.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package impl + +import ( + "github.com/dapr/go-sdk/actor/codec" + "github.com/dapr/go-sdk/actor/codec/constant" + + "gopkg.in/yaml.v3" +) + +func init() { + codec.SetActorCodec(constant.YamlSerializerType, func() codec.Codec { + return &YamlCodec{} + }) +} + +// YamlCodec is json yaml of codec.Codec. +type YamlCodec struct{} + +func (y *YamlCodec) Marshal(v interface{}) ([]byte, error) { + return yaml.Marshal(v) +} + +func (y *YamlCodec) Unmarshal(data []byte, v interface{}) error { + return yaml.Unmarshal(data, v) +} diff --git a/vendor/github.com/dapr/go-sdk/actor/config/config.go b/vendor/github.com/dapr/go-sdk/actor/config/config.go new file mode 100644 index 00000000000..656cc81ac3e --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/config/config.go @@ -0,0 +1,42 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import "github.com/dapr/go-sdk/actor/codec/constant" + +// ActorConfig is Actor's configuration struct. +type ActorConfig struct { + SerializerType string +} + +// Option is option function of ActorConfig. +type Option func(config *ActorConfig) + +// WithSerializerName set serializer type of the actor as @serializerType. +func WithSerializerName(serializerType string) Option { + return func(config *ActorConfig) { + config.SerializerType = serializerType + } +} + +// GetConfigFromOptions get final ActorConfig set by @opts. +func GetConfigFromOptions(opts ...Option) *ActorConfig { + conf := &ActorConfig{ + SerializerType: constant.DefaultSerializerType, + } + for _, o := range opts { + o(conf) + } + return conf +} diff --git a/vendor/github.com/dapr/go-sdk/actor/error/error.go b/vendor/github.com/dapr/go-sdk/actor/error/error.go new file mode 100644 index 00000000000..74702d6dac2 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/error/error.go @@ -0,0 +1,33 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package error + +type ActorErr uint8 + +// TODO(@laurence) the classification, handle and print log of error should be optimized. +const ( + Success = ActorErr(0) + ErrActorTypeNotFound = ActorErr(1) + ErrRemindersParamsInvalid = ActorErr(2) + ErrActorMethodNoFound = ActorErr(3) + ErrActorInvokeFailed = ActorErr(4) + ErrReminderFuncUndefined = ActorErr(5) + ErrActorMethodSerializeFailed = ActorErr(6) + ErrActorSerializeNoFound = ActorErr(7) + ErrActorIDNotFound = ActorErr(8) + ErrActorFactoryNotSet = ActorErr(9) + ErrTimerParamsInvalid = ActorErr(10) + ErrSaveStateFailed = ActorErr(11) + ErrActorServerInvalid = ActorErr(12) +) diff --git a/vendor/github.com/dapr/go-sdk/actor/manager/container.go b/vendor/github.com/dapr/go-sdk/actor/manager/container.go new file mode 100644 index 00000000000..29619db4da9 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/manager/container.go @@ -0,0 +1,123 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "log" + "reflect" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/codec" + actorErr "github.com/dapr/go-sdk/actor/error" + "github.com/dapr/go-sdk/actor/state" + dapr "github.com/dapr/go-sdk/client" +) + +// Deprecated: use ActorContainerContext instead. +type ActorContainer interface { + Invoke(methodName string, param []byte) ([]reflect.Value, actorErr.ActorErr) + //nolint:staticcheck // SA1019 Deprecated: use ActorContainerContext instead. + GetActor() actor.Server +} + +type ActorContainerContext interface { + Invoke(ctx context.Context, methodName string, param []byte) ([]reflect.Value, actorErr.ActorErr) + GetActor() actor.ServerContext +} + +// DefaultActorContainer contains actor instance and methods type info +// generated from actor. +// Deprecated: use DefaultActorContainerContext instead. +type DefaultActorContainer struct { + //nolint:staticcheck + actor actor.Server + ctx *DefaultActorContainerContext +} + +// DefaultActorContainerContext contains actor instance and methods type info +// generated from actor. +type DefaultActorContainerContext struct { + methodType map[string]*MethodType + actor actor.ServerContext + serializer codec.Codec +} + +// NewDefaultActorContainer creates a new ActorContainer with provider impl actor and serializer. +// Deprecated: use NewDefaultActorContainerContext instead. +// +//nolint:staticcheck +func NewDefaultActorContainer(actorID string, impl actor.Server, serializer codec.Codec) (ActorContainer, actorErr.ActorErr) { + ctx, err := NewDefaultActorContainerContext(context.Background(), actorID, impl.WithContext(), serializer) + return &DefaultActorContainer{ctx: ctx.(*DefaultActorContainerContext), actor: impl}, err +} + +// Deprecated: use NewDefaultActorContainerContext instead. +func (d *DefaultActorContainer) GetActor() actor.Server { + return d.actor +} + +// Invoke call actor method with given methodName and param. +// Deprecated: use NewDefaultActorContainerContext instead. +func (d *DefaultActorContainer) Invoke(methodName string, param []byte) ([]reflect.Value, actorErr.ActorErr) { + return d.ctx.Invoke(context.Background(), methodName, param) +} + +// NewDefaultActorContainerContext is the same as NewDefaultActorContainer, but with initial context. +func NewDefaultActorContainerContext(ctx context.Context, actorID string, impl actor.ServerContext, serializer codec.Codec) (ActorContainerContext, actorErr.ActorErr) { + impl.SetID(actorID) + daprClient, _ := dapr.NewClient() + // create state manager for this new actor + impl.SetStateManager(state.NewActorStateManagerContext(impl.Type(), actorID, state.NewDaprStateAsyncProvider(daprClient))) + // save state of this actor + err := impl.SaveState(ctx) + if err != nil { + return nil, actorErr.ErrSaveStateFailed + } + methodType, err := getAbsctractMethodMap(impl) + if err != nil { + log.Printf("failed to get absctract method map from registered provider, err = %s", err) + return nil, actorErr.ErrActorServerInvalid + } + return &DefaultActorContainerContext{ + methodType: methodType, + actor: impl, + serializer: serializer, + }, actorErr.Success +} + +// Invoke call actor method with given context, methodName and param. +func (d *DefaultActorContainerContext) Invoke(ctx context.Context, methodName string, param []byte) ([]reflect.Value, actorErr.ActorErr) { + methodType, ok := d.methodType[methodName] + if !ok { + return nil, actorErr.ErrActorMethodNoFound + } + argsValues := make([]reflect.Value, 0) + argsValues = append(argsValues, reflect.ValueOf(d.actor), reflect.ValueOf(ctx)) + if len(methodType.argsType) > 0 { + typ := methodType.argsType[0] + paramValue := reflect.New(typ) + paramInterface := paramValue.Interface() + if err := d.serializer.Unmarshal(param, paramInterface); err != nil { + return nil, actorErr.ErrActorMethodSerializeFailed + } + argsValues = append(argsValues, reflect.ValueOf(paramInterface).Elem()) + } + returnValue := methodType.method.Func.Call(argsValues) + return returnValue, actorErr.Success +} + +func (d *DefaultActorContainerContext) GetActor() actor.ServerContext { + return d.actor +} diff --git a/vendor/github.com/dapr/go-sdk/actor/manager/manager.go b/vendor/github.com/dapr/go-sdk/actor/manager/manager.go new file mode 100644 index 00000000000..8070ca2cce0 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/manager/manager.go @@ -0,0 +1,325 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + "reflect" + "sync" + "unicode" + "unicode/utf8" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/api" + "github.com/dapr/go-sdk/actor/codec" + actorErr "github.com/dapr/go-sdk/actor/error" +) + +type ActorManager interface { + RegisterActorImplFactory(f actor.Factory) + InvokeMethod(actorID, methodName string, request []byte) ([]byte, actorErr.ActorErr) + DeactivateActor(actorID string) actorErr.ActorErr + InvokeReminder(actorID, reminderName string, params []byte) actorErr.ActorErr + InvokeTimer(actorID, timerName string, params []byte) actorErr.ActorErr +} + +type ActorManagerContext interface { + RegisterActorImplFactory(f actor.FactoryContext) + InvokeMethod(ctx context.Context, actorID, methodName string, request []byte) ([]byte, actorErr.ActorErr) + DeactivateActor(ctx context.Context, actorID string) actorErr.ActorErr + InvokeReminder(ctx context.Context, actorID, reminderName string, params []byte) actorErr.ActorErr + InvokeTimer(ctx context.Context, actorID, timerName string, params []byte) actorErr.ActorErr +} + +// DefaultActorManagerContext is to manage one type of actor. +type DefaultActorManagerContext struct { + // factory is the actor factory of specific type of actor + factory actor.FactoryContext + + // activeActors stores the map actorID -> ActorContainer + activeActors sync.Map + + // serializer is the param and response serializer of the actor + serializer codec.Codec +} + +// DefaultActorManager is to manage one type of actor. +// Deprecated: use DefaultActorManagerContext instead. +type DefaultActorManager struct { + ctx ActorManagerContext +} + +// Deprecated: use DefaultActorManagerContext instead. +func NewDefaultActorManager(serializerType string) (ActorManager, actorErr.ActorErr) { + ctx, err := NewDefaultActorManagerContext(serializerType) + return &DefaultActorManager{ctx: ctx}, err +} + +// Deprecated: use DefaultActorManagerContext instead. +func (m *DefaultActorManager) RegisterActorImplFactory(f actor.Factory) { + m.ctx.RegisterActorImplFactory(func() actor.ServerContext { return f().WithContext() }) +} + +// Deprecated: use DefaultActorManagerContext instead. +func (m *DefaultActorManager) InvokeMethod(actorID, methodName string, request []byte) ([]byte, actorErr.ActorErr) { + return m.ctx.InvokeMethod(context.Background(), actorID, methodName, request) +} + +// Deprecated: use DefaultActorManagerContext instead. +func (m *DefaultActorManager) DeactivateActor(actorID string) actorErr.ActorErr { + return m.ctx.DeactivateActor(context.Background(), actorID) +} + +// Deprecated: use DefaultActorManagerContext instead. +func (m *DefaultActorManager) InvokeReminder(actorID, reminderName string, params []byte) actorErr.ActorErr { + return m.ctx.InvokeReminder(context.Background(), actorID, reminderName, params) +} + +// Deprecated: use DefaultActorManagerContext instead. +func (m *DefaultActorManager) InvokeTimer(actorID, timerName string, params []byte) actorErr.ActorErr { + return m.ctx.InvokeTimer(context.Background(), actorID, timerName, params) +} + +func NewDefaultActorManagerContext(serializerType string) (ActorManagerContext, actorErr.ActorErr) { + serializer, err := codec.GetActorCodec(serializerType) + if err != nil { + return nil, actorErr.ErrActorSerializeNoFound + } + return &DefaultActorManagerContext{ + serializer: serializer, + }, actorErr.Success +} + +// RegisterActorImplFactory registers the action factory f. +func (m *DefaultActorManagerContext) RegisterActorImplFactory(f actor.FactoryContext) { + m.factory = f +} + +// getAndCreateActorContainerIfNotExist will. +func (m *DefaultActorManagerContext) getAndCreateActorContainerIfNotExist(ctx context.Context, actorID string) (ActorContainerContext, actorErr.ActorErr) { + val, ok := m.activeActors.Load(actorID) + if !ok { + newContainer, aerr := NewDefaultActorContainerContext(ctx, actorID, m.factory(), m.serializer) + if aerr != actorErr.Success { + return nil, aerr + } + m.activeActors.Store(actorID, newContainer) + val, _ = m.activeActors.Load(actorID) + } + return val.(ActorContainerContext), actorErr.Success +} + +// InvokeMethod to invoke local function by @actorID, @methodName and @request request param. +func (m *DefaultActorManagerContext) InvokeMethod(ctx context.Context, actorID, methodName string, request []byte) ([]byte, actorErr.ActorErr) { + if m.factory == nil { + return nil, actorErr.ErrActorFactoryNotSet + } + + actorContainer, aerr := m.getAndCreateActorContainerIfNotExist(ctx, actorID) + if aerr != actorErr.Success { + return nil, aerr + } + returnValue, aerr := actorContainer.Invoke(ctx, methodName, request) + if aerr != actorErr.Success { + return nil, aerr + } + if len(returnValue) == 1 { + return nil, actorErr.Success + } + + var ( + retErr interface{} + replyv reflect.Value + ) + + if len(returnValue) == 2 { + replyv = returnValue[0] + retErr = returnValue[1].Interface() + } + + if retErr != nil { + return nil, actorErr.ErrActorInvokeFailed + } + rspData, err := m.serializer.Marshal(replyv.Interface()) + if err != nil { + return nil, actorErr.ErrActorMethodSerializeFailed + } + if err := actorContainer.GetActor().SaveState(ctx); err != nil { + return nil, actorErr.ErrSaveStateFailed + } + return rspData, actorErr.Success +} + +// DeactivateActor removes actor from actor manager. +func (m *DefaultActorManagerContext) DeactivateActor(_ context.Context, actorID string) actorErr.ActorErr { + _, ok := m.activeActors.Load(actorID) + if !ok { + return actorErr.ErrActorIDNotFound + } + m.activeActors.Delete(actorID) + return actorErr.Success +} + +// InvokeReminder invoke reminder function with given params. +func (m *DefaultActorManagerContext) InvokeReminder(ctx context.Context, actorID, reminderName string, params []byte) actorErr.ActorErr { + if m.factory == nil { + return actorErr.ErrActorFactoryNotSet + } + reminderParams := &api.ActorReminderParams{} + if err := json.Unmarshal(params, reminderParams); err != nil { + log.Printf("failed to unmarshal reminder param, err: %v ", err) + return actorErr.ErrRemindersParamsInvalid + } + actorContainer, aerr := m.getAndCreateActorContainerIfNotExist(ctx, actorID) + if aerr != actorErr.Success { + return aerr + } + + targetActor, ok := actorContainer.GetActor().(actor.ReminderCallee) + if !ok { + return actorErr.ErrReminderFuncUndefined + } + targetActor.ReminderCall(reminderName, reminderParams.Data, reminderParams.DueTime, reminderParams.Period) + return actorErr.Success +} + +// InvokeTimer invoke timer callback function with given params. +func (m *DefaultActorManagerContext) InvokeTimer(ctx context.Context, actorID, timerName string, params []byte) actorErr.ActorErr { + if m.factory == nil { + return actorErr.ErrActorFactoryNotSet + } + timerParams := &api.ActorTimerParam{} + if err := json.Unmarshal(params, timerParams); err != nil { + log.Printf("failed to unmarshal reminder param, err: %v ", err) + return actorErr.ErrTimerParamsInvalid + } + actorContainer, aerr := m.getAndCreateActorContainerIfNotExist(ctx, actorID) + if aerr != actorErr.Success { + return aerr + } + _, aerr = actorContainer.Invoke(ctx, timerParams.CallBack, timerParams.Data) + return aerr +} + +func getAbsctractMethodMap(rcvr interface{}) (map[string]*MethodType, error) { + s := &Service{} + s.reflectType = reflect.TypeOf(rcvr) + s.reflctValue = reflect.ValueOf(rcvr) + sname := reflect.Indirect(s.reflctValue).Type().Name() + if !isExported(sname) { + return nil, fmt.Errorf("type %s is not exported", sname) + } + return suitableMethods(s.reflectType), nil +} + +func isExported(name string) bool { + s, _ := utf8.DecodeRuneInString(name) + return unicode.IsUpper(s) +} + +// Service is description of service. +type Service struct { + reflctValue reflect.Value + reflectType reflect.Type +} + +// MethodType is description of service method. +type MethodType struct { + method reflect.Method + ctxType reflect.Type // request context + argsType []reflect.Type // args except ctx, include replyType if existing + replyType reflect.Type // return value, otherwise it is nil +} + +// suitableMethods returns suitable Rpc methods of typ. +func suitableMethods(typ reflect.Type) map[string]*MethodType { + methods := make(map[string]*MethodType) + for m := 0; m < typ.NumMethod(); m++ { + method := typ.Method(m) + if mt, err := suiteMethod(method); err != nil { + log.Printf("method %s is illegal, err = %s, just skip it", method.Name, err) + } else { + methods[method.Name] = mt + } + } + return methods +} + +// suiteMethod returns a suitable Rpc methodType. +func suiteMethod(method reflect.Method) (*MethodType, error) { + mtype := method.Type + mname := method.Name + inNum := mtype.NumIn() + outNum := mtype.NumOut() + + // Method must be exported. + if method.PkgPath != "" { + return nil, errors.New("method is not exported") + } + + var ( + replyType, ctxType reflect.Type + argsType []reflect.Type + ) + + if outNum > 2 || outNum == 0 { + return nil, errors.New("num out invalid") + } + + // The latest return type of the method must be error. + if returnType := mtype.Out(outNum - 1); returnType != typeOfError { + return nil, fmt.Errorf("the latest return type %s of method %q is not error", returnType, mname) + } + + // replyType + if outNum == 2 { + replyType = mtype.Out(0) + if !isExportedOrBuiltinType(replyType) { + return nil, fmt.Errorf("reply type of method %s not exported{%v}", mname, replyType) + } + } + + index := 1 + + // ctxType + if inNum > 1 && mtype.In(1).String() == "context.Context" { + ctxType = mtype.In(1) + index = 2 + } + + for ; index < inNum; index++ { + argsType = append(argsType, mtype.In(index)) + // need not be a pointer. + if !isExportedOrBuiltinType(mtype.In(index)) { + return nil, fmt.Errorf("argument type of method %q is not exported %v", mname, mtype.In(index)) + } + } + + return &MethodType{method: method, argsType: argsType, replyType: replyType, ctxType: ctxType}, nil +} + +var typeOfError = reflect.TypeOf((*error)(nil)).Elem() + +func isExportedOrBuiltinType(t reflect.Type) bool { + for t.Kind() == reflect.Ptr { + t = t.Elem() + } + // PkgPath will be non-empty even for an exported type, + // so we need to check the type name as well. + return isExported(t.Name()) || t.PkgPath() == "" +} diff --git a/vendor/github.com/dapr/go-sdk/actor/runtime/actor_runtime.go b/vendor/github.com/dapr/go-sdk/actor/runtime/actor_runtime.go new file mode 100644 index 00000000000..5052b89c364 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/runtime/actor_runtime.go @@ -0,0 +1,156 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package runtime + +import ( + "context" + "encoding/json" + "sync" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/api" + "github.com/dapr/go-sdk/actor/config" + actorErr "github.com/dapr/go-sdk/actor/error" + "github.com/dapr/go-sdk/actor/manager" +) + +// Deprecated: use ActorRunTimeContext instead. +type ActorRunTime struct { + ctx *ActorRunTimeContext +} + +type ActorRunTimeContext struct { + config api.ActorRuntimeConfig + actorManagers sync.Map +} + +var ( + actorRuntimeInstance *ActorRunTime + actorRuntimeInstanceCtx *ActorRunTimeContext +) + +// NewActorRuntime creates an empty ActorRuntime. +// Deprecated: use NewActorRuntimeContext instead. +func NewActorRuntime() *ActorRunTime { + return &ActorRunTime{ctx: NewActorRuntimeContext()} +} + +// NewActorRuntimeContext creates an empty ActorRuntimeContext. +func NewActorRuntimeContext() *ActorRunTimeContext { + return &ActorRunTimeContext{} +} + +// GetActorRuntimeInstance gets or create runtime instance. +// Deprecated: use GetActorRuntimeInstanceContext instead. +func GetActorRuntimeInstance() *ActorRunTime { + if actorRuntimeInstance == nil { + actorRuntimeInstance = NewActorRuntime() + } + return actorRuntimeInstance +} + +// GetActorRuntimeInstanceContext gets or create runtime instance. +func GetActorRuntimeInstanceContext() *ActorRunTimeContext { + if actorRuntimeInstanceCtx == nil { + actorRuntimeInstanceCtx = NewActorRuntimeContext() + } + return actorRuntimeInstanceCtx +} + +// RegisterActorFactory registers the given actor factory from user, and create new actor manager if not exists. +func (r *ActorRunTimeContext) RegisterActorFactory(f actor.FactoryContext, opt ...config.Option) { + conf := config.GetConfigFromOptions(opt...) + actType := f().Type() + r.config.RegisteredActorTypes = append(r.config.RegisteredActorTypes, actType) + mng, ok := r.actorManagers.Load(actType) + if !ok { + newMng, err := manager.NewDefaultActorManagerContext(conf.SerializerType) + if err != actorErr.Success { + return + } + newMng.RegisterActorImplFactory(f) + r.actorManagers.Store(actType, newMng) + return + } + mng.(manager.ActorManagerContext).RegisterActorImplFactory(f) +} + +func (r *ActorRunTimeContext) GetJSONSerializedConfig() ([]byte, error) { + data, err := json.Marshal(&r.config) + return data, err +} + +func (r *ActorRunTimeContext) InvokeActorMethod(ctx context.Context, actorTypeName, actorID, actorMethod string, payload []byte) ([]byte, actorErr.ActorErr) { + mng, ok := r.actorManagers.Load(actorTypeName) + if !ok { + return nil, actorErr.ErrActorTypeNotFound + } + return mng.(manager.ActorManagerContext).InvokeMethod(ctx, actorID, actorMethod, payload) +} + +func (r *ActorRunTimeContext) Deactivate(ctx context.Context, actorTypeName, actorID string) actorErr.ActorErr { + targetManager, ok := r.actorManagers.Load(actorTypeName) + if !ok { + return actorErr.ErrActorTypeNotFound + } + return targetManager.(manager.ActorManagerContext).DeactivateActor(ctx, actorID) +} + +func (r *ActorRunTimeContext) InvokeReminder(ctx context.Context, actorTypeName, actorID, reminderName string, params []byte) actorErr.ActorErr { + targetManager, ok := r.actorManagers.Load(actorTypeName) + if !ok { + return actorErr.ErrActorTypeNotFound + } + mng := targetManager.(manager.ActorManagerContext) + return mng.InvokeReminder(ctx, actorID, reminderName, params) +} + +func (r *ActorRunTimeContext) InvokeTimer(ctx context.Context, actorTypeName, actorID, timerName string, params []byte) actorErr.ActorErr { + targetManager, ok := r.actorManagers.Load(actorTypeName) + if !ok { + return actorErr.ErrActorTypeNotFound + } + mng := targetManager.(manager.ActorManagerContext) + return mng.InvokeTimer(ctx, actorID, timerName, params) +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) RegisterActorFactory(f actor.Factory, opt ...config.Option) { + r.ctx.RegisterActorFactory(func() actor.ServerContext { return f().WithContext() }, opt...) +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) GetJSONSerializedConfig() ([]byte, error) { + return r.ctx.GetJSONSerializedConfig() +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) InvokeActorMethod(actorTypeName, actorID, actorMethod string, payload []byte) ([]byte, actorErr.ActorErr) { + return r.ctx.InvokeActorMethod(context.Background(), actorTypeName, actorID, actorMethod, payload) +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) Deactivate(actorTypeName, actorID string) actorErr.ActorErr { + return r.ctx.Deactivate(context.Background(), actorTypeName, actorID) +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) InvokeReminder(actorTypeName, actorID, reminderName string, params []byte) actorErr.ActorErr { + return r.ctx.InvokeReminder(context.Background(), actorTypeName, actorID, reminderName, params) +} + +// Deprecated: use ActorRunTimeContext instead. +func (r *ActorRunTime) InvokeTimer(actorTypeName, actorID, timerName string, params []byte) actorErr.ActorErr { + return r.ctx.InvokeTimer(context.Background(), actorTypeName, actorID, timerName, params) +} diff --git a/vendor/github.com/dapr/go-sdk/actor/state/actor_state_change.go b/vendor/github.com/dapr/go-sdk/actor/state/actor_state_change.go new file mode 100644 index 00000000000..ae8d3798857 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/state/actor_state_change.go @@ -0,0 +1,34 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package state + +import ( + "time" +) + +type ActorStateChange struct { + stateName string + value interface{} + changeKind ChangeKind + ttlInSeconds *int64 +} + +func NewActorStateChange(stateName string, value any, changeKind ChangeKind, ttl *time.Duration) *ActorStateChange { + var ttlF *int64 + if ttl != nil && *ttl > 0 { + ttlInSeconds := int64(ttl.Seconds()) + ttlF = &ttlInSeconds + } + return &ActorStateChange{stateName: stateName, value: value, changeKind: changeKind, ttlInSeconds: ttlF} +} diff --git a/vendor/github.com/dapr/go-sdk/actor/state/state_async_provider.go b/vendor/github.com/dapr/go-sdk/actor/state/state_async_provider.go new file mode 100644 index 00000000000..c1d5549a506 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/state/state_async_provider.go @@ -0,0 +1,121 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package state + +import ( + "context" + "fmt" + + "github.com/dapr/go-sdk/actor/codec" + "github.com/dapr/go-sdk/actor/codec/constant" + client "github.com/dapr/go-sdk/client" +) + +type DaprStateAsyncProvider struct { + daprClient client.Client + stateSerializer codec.Codec +} + +// Deprecated: use ContainsContext instead. +func (d *DaprStateAsyncProvider) Contains(actorType string, actorID string, stateName string) (bool, error) { + return d.ContainsContext(context.Background(), actorType, actorID, stateName) +} + +func (d *DaprStateAsyncProvider) ContainsContext(ctx context.Context, actorType string, actorID string, stateName string) (bool, error) { + result, err := d.daprClient.GetActorState(ctx, &client.GetActorStateRequest{ + ActorType: actorType, + ActorID: actorID, + KeyName: stateName, + }) + if err != nil || result == nil { + return false, err + } + return len(result.Data) > 0, err +} + +// Deprecated: use LoadContext instead. +func (d *DaprStateAsyncProvider) Load(actorType, actorID, stateName string, reply interface{}) error { + return d.LoadContext(context.Background(), actorType, actorID, stateName, reply) +} + +func (d *DaprStateAsyncProvider) LoadContext(ctx context.Context, actorType, actorID, stateName string, reply interface{}) error { + result, err := d.daprClient.GetActorState(ctx, &client.GetActorStateRequest{ + ActorType: actorType, + ActorID: actorID, + KeyName: stateName, + }) + if err != nil { + return fmt.Errorf("get actor state error = %w", err) + } + if len(result.Data) == 0 { + return fmt.Errorf("get actor state result empty, with actorType: %s, actorID: %s, stateName %s", actorType, actorID, stateName) + } + if err := d.stateSerializer.Unmarshal(result.Data, reply); err != nil { + return fmt.Errorf("unmarshal state data error = %w", err) + } + return nil +} + +// Deprecated: use ApplyContext instead. +func (d *DaprStateAsyncProvider) Apply(actorType, actorID string, changes []*ActorStateChange) error { + return d.ApplyContext(context.Background(), actorType, actorID, changes) +} + +func (d *DaprStateAsyncProvider) ApplyContext(ctx context.Context, actorType, actorID string, changes []*ActorStateChange) error { + if len(changes) == 0 { + return nil + } + + operations := make([]*client.ActorStateOperation, 0) + var value []byte + for _, stateChange := range changes { + if stateChange == nil { + continue + } + + daprOperationName := string(stateChange.changeKind) + if len(daprOperationName) == 0 { + continue + } + + if stateChange.changeKind == Add { + data, err := d.stateSerializer.Marshal(stateChange.value) + if err != nil { + return err + } + value = data + } + operations = append(operations, &client.ActorStateOperation{ + OperationType: daprOperationName, + Key: stateChange.stateName, + Value: value, + TTLInSeconds: stateChange.ttlInSeconds, + }) + } + + if len(operations) == 0 { + return nil + } + + return d.daprClient.SaveStateTransactionally(ctx, actorType, actorID, operations) +} + +// TODO(@laurence) the daprClient may be nil. +func NewDaprStateAsyncProvider(daprClient client.Client) *DaprStateAsyncProvider { + stateSerializer, _ := codec.GetActorCodec(constant.DefaultSerializerType) + return &DaprStateAsyncProvider{ + stateSerializer: stateSerializer, + daprClient: daprClient, + } +} diff --git a/vendor/github.com/dapr/go-sdk/actor/state/state_change_metadata.go b/vendor/github.com/dapr/go-sdk/actor/state/state_change_metadata.go new file mode 100644 index 00000000000..626e3244a78 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/state/state_change_metadata.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package state + +import "time" + +type ChangeKind string + +const ( + None = ChangeKind("") + Add = ChangeKind("upsert") + Update = ChangeKind("upsert") + Remove = ChangeKind("delete") +) + +type ChangeMetadata struct { + Kind ChangeKind + Value any + TTL *time.Duration +} + +func NewChangeMetadata(kind ChangeKind, value any) *ChangeMetadata { + return &ChangeMetadata{ + Kind: kind, + Value: value, + } +} + +func (c *ChangeMetadata) WithTTL(ttl time.Duration) *ChangeMetadata { + c.TTL = &ttl + return c +} diff --git a/vendor/github.com/dapr/go-sdk/actor/state/state_manager.go b/vendor/github.com/dapr/go-sdk/actor/state/state_manager.go new file mode 100644 index 00000000000..0bae7c9a852 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/actor/state/state_manager.go @@ -0,0 +1,269 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package state + +import ( + "context" + "errors" + "fmt" + "reflect" + "sync" + "time" + + "github.com/dapr/go-sdk/actor" +) + +type stateManager struct { + *stateManagerCtx +} + +type stateManagerCtx struct { + actorTypeName string + actorID string + stateChangeTracker sync.Map // map[string]*ChangeMetadata + stateAsyncProvider *DaprStateAsyncProvider +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Add(stateName string, value any) error { + return s.stateManagerCtx.Add(context.Background(), stateName, value) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Get(stateName string, reply any) error { + return s.stateManagerCtx.Get(context.Background(), stateName, reply) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Set(stateName string, value any) error { + return s.stateManagerCtx.Set(context.Background(), stateName, value) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Remove(stateName string) error { + return s.stateManagerCtx.Remove(context.Background(), stateName) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Contains(stateName string) (bool, error) { + return s.stateManagerCtx.Contains(context.Background(), stateName) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Save() error { + return s.stateManagerCtx.Save(context.Background()) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) Flush() { + s.stateManagerCtx.Flush(context.Background()) +} + +// Deprecated: use NewActorStateManagerContext instead. +func (s *stateManager) WithContext() actor.StateManagerContext { + return s.stateManagerCtx +} + +func (s *stateManagerCtx) Add(ctx context.Context, stateName string, value any) error { + if stateName == "" { + return errors.New("state name can't be empty") + } + exists, err := s.stateAsyncProvider.ContainsContext(ctx, s.actorTypeName, s.actorID, stateName) + if err != nil { + return err + } + + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == Remove { + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: Update, + Value: value, + }) + return nil + } + return fmt.Errorf("duplicate cached state: %s", stateName) + } + if exists { + return fmt.Errorf("duplicate state: %s", stateName) + } + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: Add, + Value: value, + }) + return nil +} + +func (s *stateManagerCtx) Get(ctx context.Context, stateName string, reply any) error { + if stateName == "" { + return errors.New("state name can't be empty") + } + + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == Remove { + return fmt.Errorf("state is marked for removal: %s", stateName) + } + replyVal := reflect.ValueOf(reply).Elem() + metadataValue := reflect.ValueOf(metadata.Value) + if metadataValue.Kind() == reflect.Ptr { + replyVal.Set(metadataValue.Elem()) + } else { + replyVal.Set(metadataValue) + } + + return nil + } + + err := s.stateAsyncProvider.LoadContext(ctx, s.actorTypeName, s.actorID, stateName, reply) + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: None, + Value: reply, + }) + return err +} + +func (s *stateManagerCtx) Set(_ context.Context, stateName string, value any) error { + if stateName == "" { + return errors.New("state name can't be empty") + } + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == None || metadata.Kind == Remove { + metadata.Kind = Update + } + s.stateChangeTracker.Store(stateName, NewChangeMetadata(metadata.Kind, value)) + return nil + } + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: Add, + Value: value, + }) + return nil +} + +func (s *stateManagerCtx) SetWithTTL(_ context.Context, stateName string, value any, ttl time.Duration) error { + if stateName == "" { + return errors.New("state name can't be empty") + } + + if ttl < 0 { + return errors.New("ttl can't be negative") + } + + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == None || metadata.Kind == Remove { + metadata.Kind = Update + } + s.stateChangeTracker.Store(stateName, NewChangeMetadata(metadata.Kind, value)) + return nil + } + s.stateChangeTracker.Store(stateName, (&ChangeMetadata{ + Kind: Add, + Value: value, + }).WithTTL(ttl)) + return nil +} + +func (s *stateManagerCtx) Remove(ctx context.Context, stateName string) error { + if stateName == "" { + return errors.New("state name can't be empty") + } + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == Remove { + return nil + } + if metadata.Kind == Add { + s.stateChangeTracker.Delete(stateName) + return nil + } + + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: Remove, + Value: nil, + }) + return nil + } + if exist, err := s.stateAsyncProvider.ContainsContext(ctx, s.actorTypeName, s.actorID, stateName); err != nil && exist { + s.stateChangeTracker.Store(stateName, &ChangeMetadata{ + Kind: Remove, + Value: nil, + }) + } + return nil +} + +func (s *stateManagerCtx) Contains(ctx context.Context, stateName string) (bool, error) { + if stateName == "" { + return false, errors.New("state name can't be empty") + } + if val, ok := s.stateChangeTracker.Load(stateName); ok { + metadata := val.(*ChangeMetadata) + if metadata.Kind == Remove { + return false, nil + } + return true, nil + } + return s.stateAsyncProvider.ContainsContext(ctx, s.actorTypeName, s.actorID, stateName) +} + +func (s *stateManagerCtx) Save(ctx context.Context) error { + changes := make([]*ActorStateChange, 0) + s.stateChangeTracker.Range(func(key, value any) bool { + stateName := key.(string) + metadata := value.(*ChangeMetadata) + changes = append(changes, NewActorStateChange(stateName, metadata.Value, metadata.Kind, metadata.TTL)) + return true + }) + if err := s.stateAsyncProvider.ApplyContext(ctx, s.actorTypeName, s.actorID, changes); err != nil { + return err + } + s.Flush(ctx) + return nil +} + +func (s *stateManagerCtx) Flush(_ context.Context) { + s.stateChangeTracker.Range(func(key, value any) bool { + stateName := key.(string) + metadata := value.(*ChangeMetadata) + if metadata.Kind == Remove { + s.stateChangeTracker.Delete(stateName) + return true + } + metadata = NewChangeMetadata(None, metadata.Value) + s.stateChangeTracker.Store(stateName, metadata) + return true + }) +} + +// Deprecated: use NewActorStateManagerContext instead. +func NewActorStateManager(actorTypeName string, actorID string, provider *DaprStateAsyncProvider) actor.StateManager { + return &stateManager{ + stateManagerCtx: &stateManagerCtx{ + stateAsyncProvider: provider, + actorTypeName: actorTypeName, + actorID: actorID, + }, + } +} + +func NewActorStateManagerContext(actorTypeName string, actorID string, provider *DaprStateAsyncProvider) actor.StateManagerContext { + return &stateManagerCtx{ + stateAsyncProvider: provider, + actorTypeName: actorTypeName, + actorID: actorID, + } +} diff --git a/vendor/github.com/dapr/go-sdk/client/actor.go b/vendor/github.com/dapr/go-sdk/client/actor.go new file mode 100644 index 00000000000..5cfcf44efaf --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/actor.go @@ -0,0 +1,506 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + + anypb "github.com/golang/protobuf/ptypes/any" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/codec" + "github.com/dapr/go-sdk/actor/config" + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +const ( + metadataKeyTTLInSeconds = "ttlInSeconds" +) + +type InvokeActorRequest struct { + ActorType string + ActorID string + Method string + Data []byte +} + +type InvokeActorResponse struct { + Data []byte +} + +// InvokeActor invokes specific operation on the configured Dapr binding. +// This method covers input, output, and bi-directional bindings. +func (c *GRPCClient) InvokeActor(ctx context.Context, in *InvokeActorRequest) (out *InvokeActorResponse, err error) { + if in == nil { + return nil, errors.New("actor invocation required") + } + if in.Method == "" { + return nil, errors.New("actor invocation method required") + } + if in.ActorType == "" { + return nil, errors.New("actor invocation actorType required") + } + if in.ActorID == "" { + return nil, errors.New("actor invocation actorID required") + } + + req := &pb.InvokeActorRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + Method: in.Method, + Data: in.Data, + } + + resp, err := c.protoClient.InvokeActor(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error invoking binding %s/%s: %w", in.ActorType, in.ActorID, err) + } + + out = &InvokeActorResponse{} + + if resp != nil { + out.Data = resp.Data + } + + return out, nil +} + +// ImplActorClientStub impls the given client stub @actorClientStub, an example of client stub is as followed +/* +type ClientStub struct { +// User defined function + GetUser func(context.Context, *User) (*User, error) + Invoke func(context.Context, string) (string, error) + Get func(context.Context) (string, error) + Post func(context.Context, string) error + StartTimer func(context.Context, *TimerRequest) error + StopTimer func(context.Context, *TimerRequest) error + ... +} + +// Type defined the target type, which should be compatible with server side actor +func (a *ClientStub) Type() string { + return "testActorType" +} + +// ID defined actor ID to be invoked +func (a *ClientStub) ID() string { + return "ActorImplID123456" +}. +*/ +func (c *GRPCClient) ImplActorClientStub(actorClientStub actor.Client, opt ...config.Option) { + serializerType := config.GetConfigFromOptions(opt...).SerializerType + serializer, err := codec.GetActorCodec(serializerType) + if err != nil { + fmt.Printf("[Actor] ERROR: serializer type %s unsupported\n", serializerType) + return + } + + c.implActor(actorClientStub, serializer) +} + +type RegisterActorReminderRequest struct { + ActorType string + ActorID string + Name string + DueTime string + Period string + TTL string + Data []byte +} + +// RegisterActorReminder registers a new reminder to target actor. Then, a reminder would be created and +// invoke actor's ReminderCall function if implemented. +// If server side actor impls this function, it's asserted to actor.ReminderCallee and can be invoked with call period +// and state data as param @in defined. +// Scheduling parameters 'DueTime', 'Period', and 'TTL' are optional. +func (c *GRPCClient) RegisterActorReminder(ctx context.Context, in *RegisterActorReminderRequest) (err error) { + if in == nil { + return errors.New("actor register reminder invocation request param required") + } + if in.ActorType == "" { + return errors.New("actor register reminder invocation actorType required") + } + if in.ActorID == "" { + return errors.New("actor register reminder invocation actorID required") + } + if in.Name == "" { + return errors.New("actor register reminder invocation name required") + } + + req := &pb.RegisterActorReminderRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + Name: in.Name, + DueTime: in.DueTime, + Period: in.Period, + Ttl: in.TTL, + Data: in.Data, + } + + _, err = c.protoClient.RegisterActorReminder(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error invoking register actor reminder %s/%s: %w", in.ActorType, in.ActorID, err) + } + return nil +} + +type UnregisterActorReminderRequest struct { + ActorType string + ActorID string + Name string +} + +// UnregisterActorReminder would unregister the actor reminder. +func (c *GRPCClient) UnregisterActorReminder(ctx context.Context, in *UnregisterActorReminderRequest) error { + if in == nil { + return errors.New("actor unregister reminder invocation request param required") + } + if in.ActorType == "" { + return errors.New("actor unregister reminder invocation actorType required") + } + if in.ActorID == "" { + return errors.New("actor unregister reminder invocation actorID required") + } + if in.Name == "" { + return errors.New("actor unregister reminder invocation name required") + } + + req := &pb.UnregisterActorReminderRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + Name: in.Name, + } + + _, err := c.protoClient.UnregisterActorReminder(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error invoking unregister actor reminder %s/%s: %w", in.ActorType, in.ActorID, err) + } + return nil +} + +type RenameActorReminderRequest struct { + OldName string + ActorType string + ActorID string + NewName string +} + +// RenameActorReminder would rename the actor reminder. +func (c *GRPCClient) RenameActorReminder(ctx context.Context, in *RenameActorReminderRequest) error { + if in == nil { + return errors.New("actor rename reminder invocation request param required") + } + if in.ActorType == "" { + return errors.New("actor rename reminder invocation actorType required") + } + if in.ActorID == "" { + return errors.New("actor rename reminder invocation actorID required") + } + if in.OldName == "" { + return errors.New("actor rename reminder invocation oldName required") + } + if in.NewName == "" { + return errors.New("actor rename reminder invocation newName required") + } + + req := &pb.RenameActorReminderRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + OldName: in.OldName, + NewName: in.NewName, + } + + _, err := c.protoClient.RenameActorReminder(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error invoking rename actor reminder %s/%s: %w", in.ActorType, in.ActorID, err) + } + return nil +} + +type RegisterActorTimerRequest struct { + ActorType string + ActorID string + Name string + DueTime string + Period string + TTL string + Data []byte + CallBack string +} + +// RegisterActorTimer register actor timer as given param @in defined. +// Scheduling parameters 'DueTime', 'Period', and 'TTL' are optional. +func (c *GRPCClient) RegisterActorTimer(ctx context.Context, in *RegisterActorTimerRequest) (err error) { + if in == nil { + return errors.New("actor register timer invocation request param required") + } + if in.ActorType == "" { + return errors.New("actor register timer invocation actorType required") + } + if in.ActorID == "" { + return errors.New("actor register timer invocation actorID required") + } + if in.Name == "" { + return errors.New("actor register timer invocation name required") + } + if in.CallBack == "" { + return errors.New("actor register timer invocation callback function required") + } + + req := &pb.RegisterActorTimerRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + Name: in.Name, + DueTime: in.DueTime, + Period: in.Period, + Ttl: in.TTL, + Data: in.Data, + Callback: in.CallBack, + } + + _, err = c.protoClient.RegisterActorTimer(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error invoking actor register timer %s/%s: %w", in.ActorType, in.ActorID, err) + } + + return nil +} + +type UnregisterActorTimerRequest struct { + ActorType string + ActorID string + Name string +} + +// UnregisterActorTimer unregisters actor timer. +func (c *GRPCClient) UnregisterActorTimer(ctx context.Context, in *UnregisterActorTimerRequest) error { + if in == nil { + return errors.New("actor unregister timer invocation request param required") + } + if in.ActorType == "" { + return errors.New("actor unregister timer invocation actorType required") + } + if in.ActorID == "" { + return errors.New("actor unregister timer invocation actorID required") + } + if in.Name == "" { + return errors.New("actor unregister timer invocation name required") + } + req := &pb.UnregisterActorTimerRequest{ + ActorType: in.ActorType, + ActorId: in.ActorID, + Name: in.Name, + } + + _, err := c.protoClient.UnregisterActorTimer(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error invoking binding %s/%s: %w", in.ActorType, in.ActorID, err) + } + + return nil +} + +func (c *GRPCClient) implActor(actor actor.Client, serializer codec.Codec) { + actorValue := reflect.ValueOf(actor) + valueOfActor := actorValue.Elem() + typeOfActor := valueOfActor.Type() + + // check incoming interface, the incoming interface's elem must be a struct. + if typeOfActor.Kind() != reflect.Struct { + fmt.Println("[Actor] ERROR: impl actor client stub failed, incoming interface is not struct") + return + } + + numField := valueOfActor.NumField() + for i := 0; i < numField; i++ { + t := typeOfActor.Field(i) + methodName := t.Name + if methodName == "Type" { + continue + } + f := valueOfActor.Field(i) + if f.Kind() == reflect.Func && f.IsValid() && f.CanSet() { + outNum := t.Type.NumOut() + + if outNum != 1 && outNum != 2 { + fmt.Printf("[Actor] ERROR: method %s of mtype %v has wrong number of in out parameters %d; needs exactly 1/2\n", + t.Name, t.Type.String(), outNum) + continue + } + + // The latest return type of the method must be error. + if returnType := t.Type.Out(outNum - 1); returnType != reflect.Zero(reflect.TypeOf((*error)(nil)).Elem()).Type() { + fmt.Printf("[Actor] ERROR: the latest return type %s of method %q is not error\n", returnType, t.Name) + continue + } + + funcOuts := make([]reflect.Type, outNum) + for i := 0; i < outNum; i++ { + funcOuts[i] = t.Type.Out(i) + } + + f.Set(reflect.MakeFunc(f.Type(), c.makeCallProxyFunction(actor, methodName, funcOuts, serializer))) + } + } +} + +func (c *GRPCClient) makeCallProxyFunction(actor actor.Client, methodName string, outs []reflect.Type, serializer codec.Codec) func(in []reflect.Value) []reflect.Value { + return func(in []reflect.Value) []reflect.Value { + var ( + err error + inIArr []interface{} + reply reflect.Value + ) + + if len(outs) == 2 { + if outs[0].Kind() == reflect.Ptr { + reply = reflect.New(outs[0].Elem()) + } else { + reply = reflect.New(outs[0]) + } + } + + start := 0 + end := len(in) + invCtx := context.Background() + if end > 0 { + if in[0].Type().String() == "context.Context" { + if !in[0].IsNil() { + invCtx = in[0].Interface().(context.Context) + } + start++ + } + } + + if end-start <= 0 { + inIArr = []interface{}{} + } else if end-start == 1 { + inIArr = []interface{}{in[start].Interface()} + } else { + fmt.Println("[Actor] ERROR: param nums is zero or one is allowed by actor") + return nil + } + + var data []byte + if len(inIArr) > 0 { + data, err = json.Marshal(inIArr[0]) + } + if err != nil { + panic(err) + } + + rsp, err := c.InvokeActor(invCtx, &InvokeActorRequest{ + ActorType: actor.Type(), + ActorID: actor.ID(), + Method: methodName, + Data: data, + }) + + if len(outs) == 1 { + return []reflect.Value{reflect.ValueOf(&err).Elem()} + } + + response := reply.Interface() + if rsp != nil { + if err = serializer.Unmarshal(rsp.Data, response); err != nil { + fmt.Printf("[Actor] ERROR: unmarshal response err = %v\n", err) + } + } + if len(outs) == 2 && outs[0].Kind() != reflect.Ptr { + return []reflect.Value{reply.Elem(), reflect.ValueOf(&err).Elem()} + } + return []reflect.Value{reply, reflect.ValueOf(&err).Elem()} + } +} + +type GetActorStateRequest struct { + ActorType string + ActorID string + KeyName string +} + +type GetActorStateResponse struct { + Data []byte +} + +func (c *GRPCClient) GetActorState(ctx context.Context, in *GetActorStateRequest) (*GetActorStateResponse, error) { + if in == nil { + return nil, errors.New("actor get state invocation request param required") + } + if in.ActorType == "" { + return nil, errors.New("actor get state invocation actorType required") + } + if in.ActorID == "" { + return nil, errors.New("actor get state invocation actorID required") + } + if in.KeyName == "" { + return nil, errors.New("actor get state invocation keyName required") + } + rsp, err := c.protoClient.GetActorState(c.withAuthToken(ctx), &pb.GetActorStateRequest{ + ActorId: in.ActorID, + ActorType: in.ActorType, + Key: in.KeyName, + }) + if err != nil { + return nil, fmt.Errorf("error invoking actor get state %s/%s: %w", in.ActorType, in.ActorID, err) + } + return &GetActorStateResponse{Data: rsp.Data}, nil +} + +type ActorStateOperation struct { + OperationType string + Key string + Value []byte + TTLInSeconds *int64 +} + +func (c *GRPCClient) SaveStateTransactionally(ctx context.Context, actorType, actorID string, operations []*ActorStateOperation) error { + if len(operations) == 0 { + return errors.New("actor save state transactionally invocation request param operations is empty") + } + if actorType == "" { + return errors.New("actor save state transactionally invocation actorType required") + } + if actorID == "" { + return errors.New("actor save state transactionally invocation actorID required") + } + grpcOperations := make([]*pb.TransactionalActorStateOperation, 0) + for _, op := range operations { + var metadata map[string]string + if op.TTLInSeconds != nil { + metadata = make(map[string]string) + metadata[metadataKeyTTLInSeconds] = strconv.FormatInt(*op.TTLInSeconds, 10) + } + grpcOperations = append(grpcOperations, &pb.TransactionalActorStateOperation{ + OperationType: op.OperationType, + Key: op.Key, + Value: &anypb.Any{ + Value: op.Value, + }, + Metadata: metadata, + }) + } + _, err := c.protoClient.ExecuteActorStateTransaction(c.withAuthToken(ctx), &pb.ExecuteActorStateTransactionRequest{ + ActorType: actorType, + ActorId: actorID, + Operations: grpcOperations, + }) + return err +} diff --git a/vendor/github.com/dapr/go-sdk/client/binding.go b/vendor/github.com/dapr/go-sdk/client/binding.go new file mode 100644 index 00000000000..855fb102b03 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/binding.go @@ -0,0 +1,86 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +// InvokeBindingRequest represents binding invocation request. +type InvokeBindingRequest struct { + // Name is name of binding to invoke. + Name string + // Operation is the name of the operation type for the binding to invoke + Operation string + // Data is the input bindings sent + Data []byte + // Metadata is the input binding metadata + Metadata map[string]string +} + +// BindingEvent represents the binding event handler input. +type BindingEvent struct { + // Data is the input bindings sent + Data []byte + // Metadata is the input binding metadata + Metadata map[string]string +} + +// InvokeBinding invokes specific operation on the configured Dapr binding. +// This method covers input, output, and bi-directional bindings. +func (c *GRPCClient) InvokeBinding(ctx context.Context, in *InvokeBindingRequest) (*BindingEvent, error) { + if in == nil { + return nil, errors.New("binding invocation required") + } + if in.Name == "" { + return nil, errors.New("binding invocation name required") + } + if in.Operation == "" { + return nil, errors.New("binding invocation operation required") + } + + req := &pb.InvokeBindingRequest{ + Name: in.Name, + Operation: in.Operation, + Data: in.Data, + Metadata: in.Metadata, + } + + resp, err := c.protoClient.InvokeBinding(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error invoking binding %s/%s: %w", in.Name, in.Operation, err) + } + + if resp != nil { + return &BindingEvent{ + Data: resp.Data, + Metadata: resp.Metadata, + }, nil + } + + return nil, nil +} + +// InvokeOutputBinding invokes configured Dapr binding with data (allows nil).InvokeOutputBinding +// This method differs from InvokeBinding in that it doesn't expect any content being returned from the invoked method. +func (c *GRPCClient) InvokeOutputBinding(ctx context.Context, in *InvokeBindingRequest) error { + if _, err := c.InvokeBinding(ctx, in); err != nil { + return fmt.Errorf("error invoking output binding: %w", err) + } + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/client/bufpool.go b/vendor/github.com/dapr/go-sdk/client/bufpool.go new file mode 100644 index 00000000000..757f3a654e8 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/bufpool.go @@ -0,0 +1,31 @@ +/* +Copyright 2023 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "sync" +) + +// Maximum size, in bytes, for the buffer used by stream invocations: 2KB. +const StreamBufferSize = 2 << 10 + +// Pool of *[]byte used by stream invocations. Their size is fixed at StreamBufferSize. +var bufPool = sync.Pool{ + New: func() any { + // Return a pointer here + // See https://github.com/dominikh/go-tools/issues/1336 for explanation + b := make([]byte, StreamBufferSize) + return &b + }, +} diff --git a/vendor/github.com/dapr/go-sdk/client/client.go b/vendor/github.com/dapr/go-sdk/client/client.go new file mode 100644 index 00000000000..2d5a4d37844 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/client.go @@ -0,0 +1,383 @@ +/* +Copyright 2023 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + "io" + "log" + "net" + "os" + "strconv" + "sync" + "time" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/config" + "github.com/dapr/go-sdk/version" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/types/known/emptypb" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" + + // used to import codec implements. + _ "github.com/dapr/go-sdk/actor/codec/impl" +) + +const ( + daprPortDefault = "50001" + daprPortEnvVarName = "DAPR_GRPC_PORT" /* #nosec */ + traceparentKey = "traceparent" + apiTokenKey = "dapr-api-token" /* #nosec */ + apiTokenEnvVarName = "DAPR_API_TOKEN" /* #nosec */ + clientDefaultTimeoutSeconds = 5 + clientTimeoutSecondsEnvVarName = "DAPR_CLIENT_TIMEOUT_SECONDS" +) + +var ( + logger = log.New(os.Stdout, "", 0) + lock = &sync.Mutex{} + _ Client = (*GRPCClient)(nil) + defaultClient Client +) + +// Client is the interface for Dapr client implementation. +// +//nolint:interfacebloat +type Client interface { + // InvokeBinding invokes specific operation on the configured Dapr binding. + // This method covers input, output, and bi-directional bindings. + InvokeBinding(ctx context.Context, in *InvokeBindingRequest) (out *BindingEvent, err error) + + // InvokeOutputBinding invokes configured Dapr binding with data.InvokeOutputBinding + // This method differs from InvokeBinding in that it doesn't expect any content being returned from the invoked method. + InvokeOutputBinding(ctx context.Context, in *InvokeBindingRequest) error + + // InvokeMethod invokes service without raw data + InvokeMethod(ctx context.Context, appID, methodName, verb string) (out []byte, err error) + + // InvokeMethodWithContent invokes service with content + InvokeMethodWithContent(ctx context.Context, appID, methodName, verb string, content *DataContent) (out []byte, err error) + + // InvokeMethodWithCustomContent invokes app with custom content (struct + content type). + InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) (out []byte, err error) + + // PublishEvent publishes data onto topic in specific pubsub component. + PublishEvent(ctx context.Context, pubsubName, topicName string, data interface{}, opts ...PublishEventOption) error + + // PublishEventfromCustomContent serializes an struct and publishes its contents as data (JSON) onto topic in specific pubsub component. + // Deprecated: This method is deprecated and will be removed in a future version of the SDK. Please use `PublishEvent` instead. + PublishEventfromCustomContent(ctx context.Context, pubsubName, topicName string, data interface{}) error + + // PublishEvents publishes multiple events onto topic in specific pubsub component. + // If all events are successfully published, response Error will be nil. + // The FailedEvents field will contain all events that failed to publish. + PublishEvents(ctx context.Context, pubsubName, topicName string, events []interface{}, opts ...PublishEventsOption) PublishEventsResponse + + // GetSecret retrieves preconfigured secret from specified store using key. + GetSecret(ctx context.Context, storeName, key string, meta map[string]string) (data map[string]string, err error) + + // GetBulkSecret retrieves all preconfigured secrets for this application. + GetBulkSecret(ctx context.Context, storeName string, meta map[string]string) (data map[string]map[string]string, err error) + + // SaveState saves the raw data into store using default state options. + SaveState(ctx context.Context, storeName, key string, data []byte, meta map[string]string, so ...StateOption) error + + // SaveState saves the raw data into store using provided state options and etag. + SaveStateWithETag(ctx context.Context, storeName, key string, data []byte, etag string, meta map[string]string, so ...StateOption) error + + // SaveBulkState saves multiple state item to store with specified options. + SaveBulkState(ctx context.Context, storeName string, items ...*SetStateItem) error + + // GetState retrieves state from specific store using default consistency option. + GetState(ctx context.Context, storeName, key string, meta map[string]string) (item *StateItem, err error) + + // GetStateWithConsistency retrieves state from specific store using provided state consistency. + GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (item *StateItem, err error) + + // GetBulkState retrieves state for multiple keys from specific store. + GetBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string, parallelism int32) ([]*BulkStateItem, error) + + // QueryStateAlpha1 runs a query against state store. + QueryStateAlpha1(ctx context.Context, storeName, query string, meta map[string]string) (*QueryResponse, error) + + // DeleteState deletes content from store using default state options. + DeleteState(ctx context.Context, storeName, key string, meta map[string]string) error + + // DeleteStateWithETag deletes content from store using provided state options and etag. + DeleteStateWithETag(ctx context.Context, storeName, key string, etag *ETag, meta map[string]string, opts *StateOptions) error + + // ExecuteStateTransaction provides way to execute multiple operations on a specified store. + ExecuteStateTransaction(ctx context.Context, storeName string, meta map[string]string, ops []*StateOperation) error + + // GetConfigurationItem can get target configuration item by storeName and key + GetConfigurationItem(ctx context.Context, storeName, key string, opts ...ConfigurationOpt) (*ConfigurationItem, error) + + // GetConfigurationItems can get a list of configuration item by storeName and keys + GetConfigurationItems(ctx context.Context, storeName string, keys []string, opts ...ConfigurationOpt) (map[string]*ConfigurationItem, error) + + // SubscribeConfigurationItems can subscribe the change of configuration items by storeName and keys, and return subscription id + SubscribeConfigurationItems(ctx context.Context, storeName string, keys []string, handler ConfigurationHandleFunction, opts ...ConfigurationOpt) (string, error) + + // UnsubscribeConfigurationItems can stop the subscription with target store's and id + UnsubscribeConfigurationItems(ctx context.Context, storeName string, id string, opts ...ConfigurationOpt) error + + // DeleteBulkState deletes content for multiple keys from store. + DeleteBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string) error + + // DeleteBulkStateItems deletes content for multiple items from store. + DeleteBulkStateItems(ctx context.Context, storeName string, items []*DeleteStateItem) error + + // TryLockAlpha1 attempts to grab a lock from a lock store. + TryLockAlpha1(ctx context.Context, storeName string, request *LockRequest) (*LockResponse, error) + + // UnlockAlpha1 deletes unlocks a lock from a lock store. + UnlockAlpha1(ctx context.Context, storeName string, request *UnlockRequest) (*UnlockResponse, error) + + // Encrypt data read from a stream, returning a readable stream that receives the encrypted data. + // This method returns an error if the initial call fails. Errors performed during the encryption are received by the out stream. + Encrypt(ctx context.Context, in io.Reader, opts EncryptOptions) (io.Reader, error) + + // Decrypt data read from a stream, returning a readable stream that receives the decrypted data. + // This method returns an error if the initial call fails. Errors performed during the encryption are received by the out stream. + Decrypt(ctx context.Context, in io.Reader, opts DecryptOptions) (io.Reader, error) + + // Shutdown the sidecar. + Shutdown(ctx context.Context) error + + // Wait for a sidecar to become available for at most `timeout` seconds. Returns errWaitTimedOut if timeout is reached. + Wait(ctx context.Context, timeout time.Duration) error + + // WithTraceID adds existing trace ID to the outgoing context. + WithTraceID(ctx context.Context, id string) context.Context + + // WithAuthToken sets Dapr API token on the instantiated client. + WithAuthToken(token string) + + // Close cleans up all resources created by the client. + Close() + + // RegisterActorTimer registers an actor timer. + RegisterActorTimer(ctx context.Context, req *RegisterActorTimerRequest) error + + // UnregisterActorTimer unregisters an actor timer. + UnregisterActorTimer(ctx context.Context, req *UnregisterActorTimerRequest) error + + // RegisterActorReminder registers an actor reminder. + RegisterActorReminder(ctx context.Context, req *RegisterActorReminderRequest) error + + // UnregisterActorReminder unregisters an actor reminder. + UnregisterActorReminder(ctx context.Context, req *UnregisterActorReminderRequest) error + + // RenameActorReminder rename an actor reminder. + RenameActorReminder(ctx context.Context, req *RenameActorReminderRequest) error + + // InvokeActor calls a method on an actor. + InvokeActor(ctx context.Context, req *InvokeActorRequest) (*InvokeActorResponse, error) + + // GetActorState get actor state + GetActorState(ctx context.Context, req *GetActorStateRequest) (data *GetActorStateResponse, err error) + + // SaveStateTransactionally save actor state + SaveStateTransactionally(ctx context.Context, actorType, actorID string, operations []*ActorStateOperation) error + + // ImplActorClientStub is to impl user defined actor client stub + ImplActorClientStub(actorClientStub actor.Client, opt ...config.Option) + + // GrpcClient returns the base grpc client if grpc is used and nil otherwise + GrpcClient() pb.DaprClient +} + +// NewClient instantiates Dapr client using DAPR_GRPC_PORT environment variable as port. +// Note, this default factory function creates Dapr client only once. All subsequent invocations +// will return the already created instance. To create multiple instances of the Dapr client, +// use one of the parameterized factory functions: +// +// NewClientWithPort(port string) (client Client, err error) +// NewClientWithAddress(address string) (client Client, err error) +// NewClientWithConnection(conn *grpc.ClientConn) Client +// NewClientWithSocket(socket string) (client Client, err error) +func NewClient() (client Client, err error) { + port := os.Getenv(daprPortEnvVarName) + if port == "" { + port = daprPortDefault + } + if defaultClient != nil { + return defaultClient, nil + } + lock.Lock() + defer lock.Unlock() + if defaultClient != nil { + return defaultClient, nil + } + c, err := NewClientWithPort(port) + if err != nil { + return nil, fmt.Errorf("error creating default client: %w", err) + } + defaultClient = c + + return defaultClient, nil +} + +// NewClientWithPort instantiates Dapr using specific gRPC port. +func NewClientWithPort(port string) (client Client, err error) { + if port == "" { + return nil, errors.New("nil port") + } + return NewClientWithAddress(net.JoinHostPort("127.0.0.1", port)) +} + +// NewClientWithAddress instantiates Dapr using specific address (including port). +// Deprecated: use NewClientWithAddressContext instead. +func NewClientWithAddress(address string) (client Client, err error) { + return NewClientWithAddressContext(context.Background(), address) +} + +// NewClientWithAddress instantiates Dapr using specific address (including port). +// Uses the provided context to create the connection. +func NewClientWithAddressContext(ctx context.Context, address string) (client Client, err error) { + if address == "" { + return nil, errors.New("empty address") + } + logger.Printf("dapr client initializing for: %s", address) + + timeoutSeconds, err := getClientTimeoutSeconds() + if err != nil { + return nil, err + } + ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSeconds)*time.Second) + conn, err := grpc.DialContext( + ctx, + address, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUserAgent("dapr-sdk-go/"+version.SDKVersion), + grpc.WithBlock(), + ) + cancel() + if err != nil { + return nil, fmt.Errorf("error creating connection to '%s': %w", address, err) + } + if hasToken := os.Getenv(apiTokenEnvVarName); hasToken != "" { + logger.Println("client uses API token") + } + + return NewClientWithConnection(conn), nil +} + +func getClientTimeoutSeconds() (int, error) { + timeoutStr := os.Getenv(clientTimeoutSecondsEnvVarName) + if len(timeoutStr) == 0 { + return clientDefaultTimeoutSeconds, nil + } + timeoutVar, err := strconv.Atoi(timeoutStr) + if err != nil { + return 0, err + } + if timeoutVar <= 0 { + return 0, errors.New("incorrect value") + } + return timeoutVar, nil +} + +// NewClientWithSocket instantiates Dapr using specific socket. +func NewClientWithSocket(socket string) (client Client, err error) { + if socket == "" { + return nil, errors.New("nil socket") + } + logger.Printf("dapr client initializing for: %s", socket) + addr := "unix://" + socket + conn, err := grpc.Dial( + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUserAgent("dapr-sdk-go/"+version.SDKVersion), + ) + if err != nil { + return nil, fmt.Errorf("error creating connection to '%s': %w", addr, err) + } + if hasToken := os.Getenv(apiTokenEnvVarName); hasToken != "" { + logger.Println("client uses API token") + } + return NewClientWithConnection(conn), nil +} + +// NewClientWithConnection instantiates Dapr client using specific connection. +func NewClientWithConnection(conn *grpc.ClientConn) Client { + return &GRPCClient{ + connection: conn, + protoClient: pb.NewDaprClient(conn), + authToken: os.Getenv(apiTokenEnvVarName), + } +} + +// GRPCClient is the gRPC implementation of Dapr client. +type GRPCClient struct { + connection *grpc.ClientConn + protoClient pb.DaprClient + authToken string +} + +// Close cleans up all resources created by the client. +func (c *GRPCClient) Close() { + if c.connection != nil { + c.connection.Close() + c.connection = nil + } +} + +// WithAuthToken sets Dapr API token on the instantiated client. +// Allows empty string to reset token on existing client. +func (c *GRPCClient) WithAuthToken(token string) { + c.authToken = token +} + +// WithTraceID adds existing trace ID to the outgoing context. +func (c *GRPCClient) WithTraceID(ctx context.Context, id string) context.Context { + if id == "" { + return ctx + } + logger.Printf("using trace parent ID: %s", id) + md := metadata.Pairs(traceparentKey, id) + return metadata.NewOutgoingContext(ctx, md) +} + +func (c *GRPCClient) withAuthToken(ctx context.Context) context.Context { + if c.authToken == "" { + return ctx + } + return metadata.NewOutgoingContext(ctx, metadata.Pairs(apiTokenKey, c.authToken)) +} + +// Shutdown the sidecar. +func (c *GRPCClient) Shutdown(ctx context.Context) error { + _, err := c.protoClient.Shutdown(c.withAuthToken(ctx), &emptypb.Empty{}) + if err != nil { + return fmt.Errorf("error shutting down the sidecar: %w", err) + } + return nil +} + +// GrpcClient returns the base grpc client. +func (c *GRPCClient) GrpcClient() pb.DaprClient { + return c.protoClient +} + +// GrpcClientConn returns the grpc.ClientConn object used by this client. +func (c *GRPCClient) GrpcClientConn() *grpc.ClientConn { + return c.connection +} diff --git a/vendor/github.com/dapr/go-sdk/client/configuration.go b/vendor/github.com/dapr/go-sdk/client/configuration.go new file mode 100644 index 00000000000..9c245c4f590 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/configuration.go @@ -0,0 +1,126 @@ +package client + +import ( + "context" + "errors" + "fmt" + "io" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +type ConfigurationItem struct { + Value string + Version string + Metadata map[string]string +} + +type ConfigurationOpt func(map[string]string) + +func WithConfigurationMetadata(key, value string) ConfigurationOpt { + return func(m map[string]string) { + m[key] = value + } +} + +func (c *GRPCClient) GetConfigurationItem(ctx context.Context, storeName, key string, opts ...ConfigurationOpt) (*ConfigurationItem, error) { + items, err := c.GetConfigurationItems(ctx, storeName, []string{key}, opts...) + if err != nil { + return nil, err + } + if len(items) == 0 { + return nil, nil + } + + return items[key], nil +} + +func (c *GRPCClient) GetConfigurationItems(ctx context.Context, storeName string, keys []string, opts ...ConfigurationOpt) (map[string]*ConfigurationItem, error) { + metadata := make(map[string]string) + for _, opt := range opts { + opt(metadata) + } + rsp, err := c.protoClient.GetConfiguration(ctx, &pb.GetConfigurationRequest{ + StoreName: storeName, + Keys: keys, + Metadata: metadata, + }) + if err != nil { + return nil, err + } + + configItems := make(map[string]*ConfigurationItem) + for k, v := range rsp.Items { + configItems[k] = &ConfigurationItem{ + Value: v.Value, + Version: v.Version, + Metadata: v.Metadata, + } + } + return configItems, nil +} + +type ConfigurationHandleFunction func(string, map[string]*ConfigurationItem) + +func (c *GRPCClient) SubscribeConfigurationItems(ctx context.Context, storeName string, keys []string, handler ConfigurationHandleFunction, opts ...ConfigurationOpt) (string, error) { + metadata := make(map[string]string) + for _, opt := range opts { + opt(metadata) + } + + client, err := c.protoClient.SubscribeConfiguration(ctx, &pb.SubscribeConfigurationRequest{ + StoreName: storeName, + Keys: keys, + Metadata: metadata, + }) + if err != nil { + return "", fmt.Errorf("subscribe configuration failed with error = %w", err) + } + subscribeIDChan := make(chan string, 1) + go func() { + isFirst := true + for { + rsp, err := client.Recv() + if errors.Is(err, io.EOF) || rsp == nil { + // receive goroutine would close if unsubscribe is called. + fmt.Println("dapr configuration subscribe finished.") + break + } + configurationItems := make(map[string]*ConfigurationItem) + + for k, v := range rsp.Items { + configurationItems[k] = &ConfigurationItem{ + Value: v.Value, + Version: v.Version, + Metadata: v.Metadata, + } + } + // Get the subscription ID from the first response. + if isFirst { + subscribeIDChan <- rsp.Id + isFirst = false + } + // Do not invoke handler in case there are no items. + if len(configurationItems) > 0 { + handler(rsp.Id, configurationItems) + } + } + }() + subscribeID := <-subscribeIDChan + close(subscribeIDChan) + return subscribeID, nil +} + +func (c *GRPCClient) UnsubscribeConfigurationItems(ctx context.Context, storeName string, id string, opts ...ConfigurationOpt) error { + resp, err := c.protoClient.UnsubscribeConfiguration(ctx, &pb.UnsubscribeConfigurationRequest{ + StoreName: storeName, + Id: id, + }) + if err != nil { + return fmt.Errorf("unsubscribe failed with error = %w", err) + } + if !resp.Ok { + return fmt.Errorf("unsubscribe error message = %s", resp.GetMessage()) + } + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/client/crypto.go b/vendor/github.com/dapr/go-sdk/client/crypto.go new file mode 100644 index 00000000000..e3d28c677ff --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/crypto.go @@ -0,0 +1,272 @@ +/* +Copyright 2023 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + "io" + + "google.golang.org/grpc" + "google.golang.org/protobuf/proto" + + commonv1pb "github.com/dapr/go-sdk/dapr/proto/common/v1" + runtimev1pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +// Encrypt data read from a stream, returning a readable stream that receives the encrypted data. +// This method returns an error if the initial call fails. Errors performed during the encryption are received by the out stream. +func (c *GRPCClient) Encrypt(ctx context.Context, in io.Reader, opts EncryptOptions) (io.Reader, error) { + // Ensure required options are present + // This short-circuits and avoids a call to the runtime + if opts.ComponentName == "" { + return nil, errors.New("option 'ComponentName' is required") + } + if opts.KeyName == "" { + return nil, errors.New("option 'KeyName' is required") + } + if opts.KeyWrapAlgorithm == "" { + return nil, errors.New("option 'Algorithm' is required") + } + + // Create the stream + stream, err := c.protoClient.EncryptAlpha1(ctx) + if err != nil { + return nil, err + } + + // Use the context of the stream here. + return c.performCryptoOperation( + stream.Context(), stream, + in, opts, + &runtimev1pb.EncryptRequest{}, + &runtimev1pb.EncryptResponse{}, + ) +} + +// Decrypt data read from a stream, returning a readable stream that receives the decrypted data. +// This method returns an error if the initial call fails. Errors performed during the encryption are received by the out stream. +func (c *GRPCClient) Decrypt(ctx context.Context, in io.Reader, opts DecryptOptions) (io.Reader, error) { + // Ensure required options are present + // This short-circuits and avoids a call to the runtime + if opts.ComponentName == "" { + return nil, errors.New("option 'ComponentName' is required") + } + + // Create the stream + stream, err := c.protoClient.DecryptAlpha1(ctx) + if err != nil { + return nil, err + } + + // Use the context of the stream here. + return c.performCryptoOperation( + stream.Context(), stream, + in, opts, + &runtimev1pb.DecryptRequest{}, + &runtimev1pb.DecryptResponse{}, + ) +} + +func (c *GRPCClient) performCryptoOperation(ctx context.Context, stream grpc.ClientStream, in io.Reader, opts cryptoOperationOpts, reqProto runtimev1pb.CryptoRequests, resProto runtimev1pb.CryptoResponses) (io.Reader, error) { + var err error + // Pipe for writing the response + pr, pw := io.Pipe() + + // Send the request in a background goroutine + go func() { + // Build the options object for the first message + optsProto := opts.getProto() + + // Get a buffer from the pool + reqBuf := bufPool.Get().(*[]byte) + defer func() { + bufPool.Put(reqBuf) + }() + + // Send the request in chunks + var ( + n int + seq uint64 + done bool + ) + for { + if ctx.Err() != nil { + pw.CloseWithError(ctx.Err()) + return + } + + // First message only - add the options + if optsProto != nil { + reqProto.SetOptions(optsProto) + optsProto = nil + } else { + // Reset the object so we can re-use it + reqProto.Reset() + } + + n, err = in.Read(*reqBuf) + if err == io.EOF { + done = true + } else if err != nil { + pw.CloseWithError(err) + return + } + + // Send the chunk if there's anything to send + if n > 0 { + reqProto.SetPayload(&commonv1pb.StreamPayload{ + Data: (*reqBuf)[:n], + Seq: seq, + }) + seq++ + + err = stream.SendMsg(reqProto) + if errors.Is(err, io.EOF) { + // If SendMsg returns an io.EOF error, it usually means that there's a transport-level error + // The exact error can only be determined by RecvMsg, so if we encounter an EOF error here, just consider the stream done and let RecvMsg handle the error + done = true + } else if err != nil { + pw.CloseWithError(fmt.Errorf("error sending message: %w", err)) + return + } + } + + // Stop the loop with the last chunk + if done { + err = stream.CloseSend() + if err != nil { + pw.CloseWithError(fmt.Errorf("failed to close the send direction of the stream: %w", err)) + return + } + + break + } + } + }() + + // Read the response in another goroutine + go func() { + var ( + expectSeq uint64 + readErr error + done bool + payload *commonv1pb.StreamPayload + ) + + // Read until the end of the stream + for { + if ctx.Err() != nil { + pw.CloseWithError(ctx.Err()) + return + } + + // Read the next chunk + readErr = stream.RecvMsg(resProto) + if errors.Is(readErr, io.EOF) { + // Receiving an io.EOF signifies that the client has stopped sending data over the pipe, so this is the end + done = true + } else if readErr != nil { + pw.CloseWithError(fmt.Errorf("error receiving message: %w", readErr)) + return + } + + // Write the data, if any, into the pipe + payload = resProto.GetPayload() + if payload != nil { + if payload.Seq != expectSeq { + pw.CloseWithError(fmt.Errorf("invalid sequence number in chunk: %d (expected: %d)", payload.Seq, expectSeq)) + return + } + expectSeq++ + + _, readErr = pw.Write(payload.Data) + if readErr != nil { + pw.CloseWithError(fmt.Errorf("error writing data: %w", readErr)) + return + } + } + + // Stop when done + if done { + break + } + + // Reset the proto + resProto.Reset() + } + + // Close the writer of the pipe when done + pw.Close() + }() + + // Return the readable stream + return pr, nil +} + +// Interface for EncryptOptions and DecryptOptions +type cryptoOperationOpts interface { + getProto() proto.Message +} + +// EncryptOptions contains options passed to the Encrypt method. +type EncryptOptions struct { + // Name of the component. Required. + ComponentName string + // Name (or name/version) of the key. Required. + KeyName string + // Key wrapping algorithm to use. Required. + // Supported options include: A256KW, A128CBC, A192CBC, A256CBC, RSA-OAEP-256. + KeyWrapAlgorithm string + // DataEncryptionCipher to use to encrypt data (optional): "aes-gcm" (default) or "chacha20-poly1305" + DataEncryptionCipher string + // If true, the encrypted document does not contain a key reference. + // In that case, calls to the Decrypt method must provide a key reference (name or name/version). + // Defaults to false. + OmitDecryptionKeyName bool + // Key reference to embed in the encrypted document (name or name/version). + // This is helpful if the reference of the key used to decrypt the document is different from the one used to encrypt it. + // If unset, uses the reference of the key used to encrypt the document (this is the default behavior). + // This option is ignored if omit_decryption_key_name is true. + DecryptionKeyName string +} + +func (o EncryptOptions) getProto() proto.Message { + return &runtimev1pb.EncryptRequestOptions{ + ComponentName: o.ComponentName, + KeyName: o.KeyName, + KeyWrapAlgorithm: o.KeyWrapAlgorithm, + DataEncryptionCipher: o.DataEncryptionCipher, + OmitDecryptionKeyName: o.OmitDecryptionKeyName, + DecryptionKeyName: o.DecryptionKeyName, + } +} + +// DecryptOptions contains options passed to the Decrypt method. +type DecryptOptions struct { + // Name of the component. Required. + ComponentName string + // Name (or name/version) of the key to decrypt the message. + // Overrides any key reference included in the message if present. + // This is required if the message doesn't include a key reference (i.e. was created with omit_decryption_key_name set to true). + KeyName string +} + +func (o DecryptOptions) getProto() proto.Message { + return &runtimev1pb.DecryptRequestOptions{ + ComponentName: o.ComponentName, + KeyName: o.KeyName, + } +} diff --git a/vendor/github.com/dapr/go-sdk/client/invoke.go b/vendor/github.com/dapr/go-sdk/client/invoke.go new file mode 100644 index 00000000000..46c2630f61c --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/invoke.go @@ -0,0 +1,153 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + + anypb "github.com/golang/protobuf/ptypes/any" + + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +// DataContent the service invocation content. +type DataContent struct { + // Data is the input data + Data []byte + // ContentType is the type of the data content + ContentType string +} + +func (c *GRPCClient) invokeServiceWithRequest(ctx context.Context, req *pb.InvokeServiceRequest) (out []byte, err error) { + if req == nil { + return nil, errors.New("nil request") + } + + resp, err := c.protoClient.InvokeService(c.withAuthToken(ctx), req) + if err != nil { + return nil, err + } + + // allow for service to not return any value + if resp != nil && resp.GetData() != nil { + out = resp.GetData().Value + return + } + + out = nil + return +} + +func queryAndVerbToHTTPExtension(query string, verb string) *v1.HTTPExtension { + if v, ok := v1.HTTPExtension_Verb_value[strings.ToUpper(verb)]; ok { + return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v), Querystring: query} + } + return &v1.HTTPExtension{Verb: v1.HTTPExtension_NONE} +} + +func hasRequiredInvokeArgs(appID, methodName, verb string) error { + if appID == "" { + return errors.New("appID") + } + if methodName == "" { + return errors.New("methodName") + } + if verb == "" { + return errors.New("verb") + } + return nil +} + +// InvokeMethod invokes service without raw data ([]byte). +func (c *GRPCClient) InvokeMethod(ctx context.Context, appID, methodName, verb string) (out []byte, err error) { + if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { + return nil, fmt.Errorf("missing required parameter: %w", err) + } + method, query := extractMethodAndQuery(methodName) + req := &pb.InvokeServiceRequest{ + Id: appID, + Message: &v1.InvokeRequest{ + Method: method, + HttpExtension: queryAndVerbToHTTPExtension(query, verb), + }, + } + return c.invokeServiceWithRequest(ctx, req) +} + +// InvokeMethodWithContent invokes service with content (data + content type). +func (c *GRPCClient) InvokeMethodWithContent(ctx context.Context, appID, methodName, verb string, content *DataContent) (out []byte, err error) { + if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { + return nil, fmt.Errorf("missing required parameter: %w", err) + } + if content == nil { + return nil, errors.New("content required") + } + method, query := extractMethodAndQuery(methodName) + req := &pb.InvokeServiceRequest{ + Id: appID, + Message: &v1.InvokeRequest{ + Method: method, + Data: &anypb.Any{Value: content.Data}, + ContentType: content.ContentType, + HttpExtension: queryAndVerbToHTTPExtension(query, verb), + }, + } + return c.invokeServiceWithRequest(ctx, req) +} + +// InvokeMethodWithCustomContent invokes service with custom content (struct + content type). +func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, methodName, verb string, contentType string, content interface{}) ([]byte, error) { + if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil { + return nil, fmt.Errorf("missing required parameter: %w", err) + } + if contentType == "" { + return nil, errors.New("content type required") + } + if content == nil { + return nil, errors.New("content required") + } + + contentData, err := json.Marshal(content) + if err != nil { + return nil, fmt.Errorf("error serializing input struct: %w", err) + } + + method, query := extractMethodAndQuery(methodName) + + req := &pb.InvokeServiceRequest{ + Id: appID, + Message: &v1.InvokeRequest{ + Method: method, + Data: &anypb.Any{Value: contentData}, + ContentType: contentType, + HttpExtension: queryAndVerbToHTTPExtension(query, verb), + }, + } + + return c.invokeServiceWithRequest(ctx, req) +} + +func extractMethodAndQuery(name string) (method, query string) { + splitStr := strings.SplitN(name, "?", 2) + method = splitStr[0] + if len(splitStr) == 2 { + query = splitStr[1] + } + return +} diff --git a/vendor/github.com/dapr/go-sdk/client/lock.go b/vendor/github.com/dapr/go-sdk/client/lock.go new file mode 100644 index 00000000000..c3e3c256f5e --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/lock.go @@ -0,0 +1,100 @@ +/* +Copyright 2022 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +// LockRequest is the lock request object. +type LockRequest struct { + ResourceID string + LockOwner string + ExpiryInSeconds int32 +} + +// UnlockRequest is the unlock request object. +type UnlockRequest struct { + ResourceID string + LockOwner string +} + +// LockResponse is the lock operation response object. +type LockResponse struct { + Success bool +} + +// UnlockResponse is the unlock operation response object. +type UnlockResponse struct { + StatusCode int32 + Status string +} + +// TryLockAlpha1 attempts to grab a lock from a lock store. +func (c *GRPCClient) TryLockAlpha1(ctx context.Context, storeName string, request *LockRequest) (*LockResponse, error) { + if storeName == "" { + return nil, errors.New("storeName is empty") + } + + if request == nil { + return nil, errors.New("request is nil") + } + + req := pb.TryLockRequest{ + ResourceId: request.ResourceID, + LockOwner: request.LockOwner, + ExpiryInSeconds: request.ExpiryInSeconds, + StoreName: storeName, + } + + resp, err := c.protoClient.TryLockAlpha1(ctx, &req) + if err != nil { + return nil, fmt.Errorf("error getting lock: %w", err) + } + + return &LockResponse{ + Success: resp.Success, + }, nil +} + +// UnlockAlpha1 deletes unlocks a lock from a lock store. +func (c *GRPCClient) UnlockAlpha1(ctx context.Context, storeName string, request *UnlockRequest) (*UnlockResponse, error) { + if storeName == "" { + return nil, errors.New("storeName is empty") + } + + if request == nil { + return nil, errors.New("request is nil") + } + + req := pb.UnlockRequest{ + ResourceId: request.ResourceID, + LockOwner: request.LockOwner, + StoreName: storeName, + } + + resp, err := c.protoClient.UnlockAlpha1(ctx, &req) + if err != nil { + return nil, fmt.Errorf("error getting lock: %w", err) + } + + return &UnlockResponse{ + StatusCode: int32(resp.Status), + Status: pb.UnlockResponse_Status_name[int32(resp.Status)], + }, nil +} diff --git a/vendor/github.com/dapr/go-sdk/client/pubsub.go b/vendor/github.com/dapr/go-sdk/client/pubsub.go new file mode 100644 index 00000000000..58cc52024dc --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/pubsub.go @@ -0,0 +1,264 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + + "github.com/google/uuid" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +const ( + rawPayload = "rawPayload" + trueValue = "true" +) + +// PublishEventOption is the type for the functional option. +type PublishEventOption func(*pb.PublishEventRequest) + +// PublishEvent publishes data onto specific pubsub topic. +func (c *GRPCClient) PublishEvent(ctx context.Context, pubsubName, topicName string, data interface{}, opts ...PublishEventOption) error { + if pubsubName == "" { + return errors.New("pubsubName name required") + } + if topicName == "" { + return errors.New("topic name required") + } + + request := &pb.PublishEventRequest{ + PubsubName: pubsubName, + Topic: topicName, + } + for _, o := range opts { + o(request) + } + + if data != nil { + switch d := data.(type) { + case []byte: + request.Data = d + case string: + request.Data = []byte(d) + default: + var err error + request.DataContentType = "application/json" + request.Data, err = json.Marshal(d) + if err != nil { + return fmt.Errorf("error serializing input struct: %w", err) + } + } + } + + _, err := c.protoClient.PublishEvent(c.withAuthToken(ctx), request) + if err != nil { + return fmt.Errorf("error publishing event unto %s topic: %w", topicName, err) + } + + return nil +} + +// PublishEventWithContentType can be passed as option to PublishEvent to set an explicit Content-Type. +func PublishEventWithContentType(contentType string) PublishEventOption { + return func(e *pb.PublishEventRequest) { + e.DataContentType = contentType + } +} + +// PublishEventWithMetadata can be passed as option to PublishEvent to set metadata. +func PublishEventWithMetadata(metadata map[string]string) PublishEventOption { + return func(e *pb.PublishEventRequest) { + e.Metadata = metadata + } +} + +// PublishEventWithRawPayload can be passed as option to PublishEvent to set rawPayload metadata. +func PublishEventWithRawPayload() PublishEventOption { + return func(e *pb.PublishEventRequest) { + if e.Metadata == nil { + e.Metadata = map[string]string{rawPayload: trueValue} + } else { + e.Metadata[rawPayload] = trueValue + } + } +} + +// PublishEventfromCustomContent serializes an struct and publishes its contents as data (JSON) onto topic in specific pubsub component. +// Deprecated: This method is deprecated and will be removed in a future version of the SDK. Please use `PublishEvent` instead. +func (c *GRPCClient) PublishEventfromCustomContent(ctx context.Context, pubsubName, topicName string, data interface{}) error { + log.Println("DEPRECATED: client.PublishEventfromCustomContent is deprecated and will be removed in a future version of the SDK. Please use `PublishEvent` instead.") + + // Perform the JSON marshaling here just in case someone passed a []byte or string as data + enc, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("error serializing input struct: %w", err) + } + + return c.PublishEvent(ctx, pubsubName, topicName, enc, PublishEventWithContentType("application/json")) +} + +// PublishEventsEvent is a type of event that can be published using PublishEvents. +type PublishEventsEvent struct { + EntryID string + Data []byte + ContentType string + Metadata map[string]string +} + +// PublishEventsResponse is the response type for PublishEvents. +type PublishEventsResponse struct { + Error error + FailedEvents []interface{} +} + +// PublishEventsOption is the type for the functional option. +type PublishEventsOption func(*pb.BulkPublishRequest) + +// PublishEvents publishes multiple events onto topic in specific pubsub component. +// If all events are successfully published, response Error will be nil. +// The FailedEvents field will contain all events that failed to publish. +func (c *GRPCClient) PublishEvents(ctx context.Context, pubsubName, topicName string, events []interface{}, opts ...PublishEventsOption) PublishEventsResponse { + if pubsubName == "" { + return PublishEventsResponse{ + Error: errors.New("pubsubName name required"), + FailedEvents: events, + } + } + if topicName == "" { + return PublishEventsResponse{ + Error: errors.New("topic name required"), + FailedEvents: events, + } + } + + failedEvents := make([]interface{}, 0, len(events)) + eventMap := make(map[string]interface{}, len(events)) + entries := make([]*pb.BulkPublishRequestEntry, 0, len(events)) + for _, event := range events { + entry, err := createBulkPublishRequestEntry(event) + if err != nil { + failedEvents = append(failedEvents, event) + continue + } + eventMap[entry.EntryId] = event + entries = append(entries, entry) + } + + request := &pb.BulkPublishRequest{ + PubsubName: pubsubName, + Topic: topicName, + Entries: entries, + } + for _, o := range opts { + o(request) + } + + res, err := c.protoClient.BulkPublishEventAlpha1(c.withAuthToken(ctx), request) + // If there is an error, all events failed to publish. + if err != nil { + return PublishEventsResponse{ + Error: fmt.Errorf("error publishing events unto %s topic: %w", topicName, err), + FailedEvents: events, + } + } + + for _, failedEntry := range res.FailedEntries { + event, ok := eventMap[failedEntry.EntryId] + if !ok { + // This should never happen. + failedEvents = append(failedEvents, failedEntry.EntryId) + } + failedEvents = append(failedEvents, event) + } + + if len(failedEvents) != 0 { + return PublishEventsResponse{ + Error: fmt.Errorf("error publishing events unto %s topic: %w", topicName, err), + FailedEvents: failedEvents, + } + } + + return PublishEventsResponse{ + Error: nil, + FailedEvents: make([]interface{}, 0), + } +} + +// createBulkPublishRequestEntry creates a BulkPublishRequestEntry from an interface{}. +func createBulkPublishRequestEntry(data interface{}) (*pb.BulkPublishRequestEntry, error) { + entry := &pb.BulkPublishRequestEntry{} + + switch d := data.(type) { + case PublishEventsEvent: + entry.EntryId = d.EntryID + entry.Event = d.Data + entry.ContentType = d.ContentType + entry.Metadata = d.Metadata + case []byte: + entry.Event = d + entry.ContentType = "application/octet-stream" + case string: + entry.Event = []byte(d) + entry.ContentType = "text/plain" + default: + var err error + entry.ContentType = "application/json" + entry.Event, err = json.Marshal(d) + if err != nil { + return &pb.BulkPublishRequestEntry{}, fmt.Errorf("error serializing input struct: %w", err) + } + + if isCloudEvent(entry.Event) { + entry.ContentType = "application/cloudevents+json" + } + } + + if entry.EntryId == "" { + entry.EntryId = uuid.New().String() + } + + return entry, nil +} + +// PublishEventsWithContentType can be passed as option to PublishEvents to explicitly set the same Content-Type for all events. +func PublishEventsWithContentType(contentType string) PublishEventsOption { + return func(r *pb.BulkPublishRequest) { + for _, entry := range r.Entries { + entry.ContentType = contentType + } + } +} + +// PublishEventsWithMetadata can be passed as option to PublishEvents to set request metadata. +func PublishEventsWithMetadata(metadata map[string]string) PublishEventsOption { + return func(r *pb.BulkPublishRequest) { + r.Metadata = metadata + } +} + +// PublishEventsWithRawPayload can be passed as option to PublishEvents to set rawPayload request metadata. +func PublishEventsWithRawPayload() PublishEventsOption { + return func(r *pb.BulkPublishRequest) { + if r.Metadata == nil { + r.Metadata = map[string]string{rawPayload: trueValue} + } else { + r.Metadata[rawPayload] = trueValue + } + } +} diff --git a/vendor/github.com/dapr/go-sdk/client/secret.go b/vendor/github.com/dapr/go-sdk/client/secret.go new file mode 100644 index 00000000000..604d198dd72 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/secret.go @@ -0,0 +1,80 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +// GetSecret retrieves preconfigured secret from specified store using key. +func (c *GRPCClient) GetSecret(ctx context.Context, storeName, key string, meta map[string]string) (data map[string]string, err error) { + if storeName == "" { + return nil, errors.New("empty storeName") + } + if key == "" { + return nil, errors.New("empty key") + } + + req := &pb.GetSecretRequest{ + Key: key, + StoreName: storeName, + Metadata: meta, + } + + resp, err := c.protoClient.GetSecret(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error invoking service: %w", err) + } + + if resp != nil { + data = resp.GetData() + } + + return +} + +// GetBulkSecret retrieves all preconfigured secrets for this application. +func (c *GRPCClient) GetBulkSecret(ctx context.Context, storeName string, meta map[string]string) (data map[string]map[string]string, err error) { + if storeName == "" { + return nil, errors.New("empty storeName") + } + + req := &pb.GetBulkSecretRequest{ + StoreName: storeName, + Metadata: meta, + } + + resp, err := c.protoClient.GetBulkSecret(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error invoking service: %w", err) + } + + if resp != nil { + data = map[string]map[string]string{} + + for secretName, secretResponse := range resp.Data { + data[secretName] = map[string]string{} + + for k, v := range secretResponse.Secrets { + data[secretName][k] = v + } + } + } + + return +} diff --git a/vendor/github.com/dapr/go-sdk/client/state.go b/vendor/github.com/dapr/go-sdk/client/state.go new file mode 100644 index 00000000000..8265a777051 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/state.go @@ -0,0 +1,527 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/golang/protobuf/ptypes/duration" + + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1" +) + +const ( + // StateConsistencyUndefined is the undefined value for state consistency. + StateConsistencyUndefined StateConsistency = 0 + // StateConsistencyEventual represents eventual state consistency value. + StateConsistencyEventual StateConsistency = 1 + // StateConsistencyStrong represents strong state consistency value. + StateConsistencyStrong StateConsistency = 2 + + // StateConcurrencyUndefined is the undefined value for state concurrency. + StateConcurrencyUndefined StateConcurrency = 0 + // StateConcurrencyFirstWrite represents first write concurrency value. + StateConcurrencyFirstWrite StateConcurrency = 1 + // StateConcurrencyLastWrite represents last write concurrency value. + StateConcurrencyLastWrite StateConcurrency = 2 + + // StateOperationTypeUndefined is the undefined value for state operation type. + StateOperationTypeUndefined OperationType = 0 + // StateOperationTypeUpsert represents upsert operation type value. + StateOperationTypeUpsert OperationType = 1 + // StateOperationTypeDelete represents delete operation type value. + StateOperationTypeDelete OperationType = 2 + // UndefinedType represents undefined type value. + UndefinedType = "undefined" +) + +type ( + // StateConsistency is the consistency enum type. + StateConsistency int + // StateConcurrency is the concurrency enum type. + StateConcurrency int + // OperationType is the operation enum type. + OperationType int +) + +// GetPBConsistency get consistency pb value. +func (s StateConsistency) GetPBConsistency() v1.StateOptions_StateConsistency { + return v1.StateOptions_StateConsistency(s) +} + +// GetPBConcurrency get concurrency pb value. +func (s StateConcurrency) GetPBConcurrency() v1.StateOptions_StateConcurrency { + return v1.StateOptions_StateConcurrency(s) +} + +// String returns the string value of the OperationType. +func (o OperationType) String() string { + names := [...]string{ + UndefinedType, + "upsert", + "delete", + } + if o < StateOperationTypeUpsert || o > StateOperationTypeDelete { + return UndefinedType + } + + return names[o] +} + +// String returns the string value of the StateConsistency. +func (s StateConsistency) String() string { + names := [...]string{ + UndefinedType, + "strong", + "eventual", + } + if s < StateConsistencyStrong || s > StateConsistencyEventual { + return UndefinedType + } + + return names[s] +} + +// String returns the string value of the StateConcurrency. +func (s StateConcurrency) String() string { + names := [...]string{ + UndefinedType, + "first-write", + "last-write", + } + if s < StateConcurrencyFirstWrite || s > StateConcurrencyLastWrite { + return UndefinedType + } + + return names[s] +} + +var stateOptionDefault = &v1.StateOptions{ + Concurrency: v1.StateOptions_CONCURRENCY_LAST_WRITE, + Consistency: v1.StateOptions_CONSISTENCY_STRONG, +} + +// StateOperation is a collection of StateItems with a store name. +type StateOperation struct { + Type OperationType + Item *SetStateItem +} + +// StateItem represents a single state item. +type StateItem struct { + Key string + Value []byte + Etag string + Metadata map[string]string +} + +// BulkStateItem represents a single state item. +type BulkStateItem struct { + Key string + Value []byte + Etag string + Metadata map[string]string + Error string +} + +// SetStateItem represents a single state to be persisted. +type SetStateItem struct { + Key string + Value []byte + Etag *ETag + Metadata map[string]string + Options *StateOptions +} + +// QueryItem represents a single query result item. +type QueryItem struct { + Key string + Value []byte + Etag string + Error string +} + +// QueryResponse represents a query result. +type QueryResponse struct { + Results []QueryItem + Token string + Metadata map[string]string +} + +// DeleteStateItem represents a single state to be deleted. +type DeleteStateItem SetStateItem + +// ETag represents an versioned record information. +type ETag struct { + Value string +} + +// StateOptions represents the state store persistence policy. +type StateOptions struct { + Concurrency StateConcurrency + Consistency StateConsistency +} + +// StateOption StateOptions's function type. +type StateOption func(*StateOptions) + +// WithConcurrency set StateOptions's Concurrency. +func WithConcurrency(concurrency StateConcurrency) StateOption { + return func(so *StateOptions) { + so.Concurrency = concurrency + } +} + +// WithConsistency set StateOptions's consistency. +func WithConsistency(consistency StateConsistency) StateOption { + return func(so *StateOptions) { + so.Consistency = consistency + } +} + +func toProtoSaveStateItem(si *SetStateItem) (item *v1.StateItem) { + s := &v1.StateItem{ + Key: si.Key, + Metadata: si.Metadata, + Value: si.Value, + Options: toProtoStateOptions(si.Options), + } + + if si.Etag != nil { + s.Etag = &v1.Etag{ + Value: si.Etag.Value, + } + } + + return s +} + +func toProtoStateOptions(so *StateOptions) (opts *v1.StateOptions) { + if so == nil { + return copyStateOptionDefaultPB() + } + return &v1.StateOptions{ + Concurrency: v1.StateOptions_StateConcurrency(so.Concurrency), + Consistency: v1.StateOptions_StateConsistency(so.Consistency), + } +} + +func copyStateOptionDefaultPB() *v1.StateOptions { + return &v1.StateOptions{ + Concurrency: stateOptionDefault.GetConcurrency(), + Consistency: stateOptionDefault.GetConsistency(), + } +} + +func copyStateOptionDefault() *StateOptions { + return &StateOptions{ + Concurrency: StateConcurrency(stateOptionDefault.GetConcurrency()), + Consistency: StateConsistency(stateOptionDefault.GetConsistency()), + } +} + +func toProtoDuration(d time.Duration) *duration.Duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &duration.Duration{ + Seconds: secs, + Nanos: int32(nanos), + } +} + +// ExecuteStateTransaction provides way to execute multiple operations on a specified store. +func (c *GRPCClient) ExecuteStateTransaction(ctx context.Context, storeName string, meta map[string]string, ops []*StateOperation) error { + if storeName == "" { + return errors.New("nil storeName") + } + if len(ops) == 0 { + return nil + } + + items := make([]*pb.TransactionalStateOperation, 0) + for _, op := range ops { + item := &pb.TransactionalStateOperation{ + OperationType: op.Type.String(), + Request: toProtoSaveStateItem(op.Item), + } + items = append(items, item) + } + + req := &pb.ExecuteStateTransactionRequest{ + Metadata: meta, + StoreName: storeName, + Operations: items, + } + _, err := c.protoClient.ExecuteStateTransaction(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error executing state transaction: %w", err) + } + return nil +} + +// SaveState saves the raw data into store, default options: strong, last-write. +func (c *GRPCClient) SaveState(ctx context.Context, storeName, key string, data []byte, meta map[string]string, so ...StateOption) error { + return c.SaveStateWithETag(ctx, storeName, key, data, "", meta, so...) +} + +// SaveStateWithETag saves the raw data into store using provided state options and etag. +func (c *GRPCClient) SaveStateWithETag(ctx context.Context, storeName, key string, data []byte, etag string, meta map[string]string, so ...StateOption) error { + stateOptions := new(StateOptions) + for _, o := range so { + o(stateOptions) + } + if len(so) == 0 { + stateOptions = copyStateOptionDefault() + } + item := &SetStateItem{ + Key: key, + Value: data, + Metadata: meta, + Options: stateOptions, + } + if etag != "" { + item.Etag = &ETag{Value: etag} + } + return c.SaveBulkState(ctx, storeName, item) +} + +// SaveBulkState saves the multiple state item to store. +func (c *GRPCClient) SaveBulkState(ctx context.Context, storeName string, items ...*SetStateItem) error { + if storeName == "" { + return errors.New("nil store") + } + if items == nil { + return errors.New("nil item") + } + + req := &pb.SaveStateRequest{ + StoreName: storeName, + States: make([]*v1.StateItem, 0), + } + + for _, si := range items { + item := toProtoSaveStateItem(si) + req.States = append(req.States, item) + } + + _, err := c.protoClient.SaveState(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error saving state: %w", err) + } + return nil +} + +// GetBulkState retrieves state for multiple keys from specific store. +func (c *GRPCClient) GetBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string, parallelism int32) ([]*BulkStateItem, error) { + if storeName == "" { + return nil, errors.New("nil store") + } + if len(keys) == 0 { + return nil, errors.New("keys required") + } + items := make([]*BulkStateItem, 0) + + req := &pb.GetBulkStateRequest{ + StoreName: storeName, + Keys: keys, + Metadata: meta, + Parallelism: parallelism, + } + + results, err := c.protoClient.GetBulkState(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error getting state: %w", err) + } + + if results == nil || results.Items == nil { + return items, nil + } + + for _, r := range results.Items { + item := &BulkStateItem{ + Key: r.Key, + Etag: r.Etag, + Value: r.Data, + Metadata: r.Metadata, + Error: r.Error, + } + items = append(items, item) + } + + return items, nil +} + +// GetState retrieves state from specific store using default consistency option. +func (c *GRPCClient) GetState(ctx context.Context, storeName, key string, meta map[string]string) (item *StateItem, err error) { + return c.GetStateWithConsistency(ctx, storeName, key, meta, StateConsistencyStrong) +} + +// GetStateWithConsistency retrieves state from specific store using provided state consistency. +func (c *GRPCClient) GetStateWithConsistency(ctx context.Context, storeName, key string, meta map[string]string, sc StateConsistency) (*StateItem, error) { + if err := hasRequiredStateArgs(storeName, key); err != nil { + return nil, fmt.Errorf("missing required arguments: %w", err) + } + + req := &pb.GetStateRequest{ + StoreName: storeName, + Key: key, + Consistency: v1.StateOptions_StateConsistency(sc), + Metadata: meta, + } + + result, err := c.protoClient.GetState(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error getting state: %w", err) + } + + return &StateItem{ + Etag: result.Etag, + Key: key, + Value: result.Data, + Metadata: result.Metadata, + }, nil +} + +// QueryStateAlpha1 runs a query against state store. +func (c *GRPCClient) QueryStateAlpha1(ctx context.Context, storeName, query string, meta map[string]string) (*QueryResponse, error) { + if storeName == "" { + return nil, errors.New("store name is not set") + } + if query == "" { + return nil, errors.New("query is not set") + } + req := &pb.QueryStateRequest{ + StoreName: storeName, + Query: query, + Metadata: meta, + } + resp, err := c.protoClient.QueryStateAlpha1(c.withAuthToken(ctx), req) + if err != nil { + return nil, fmt.Errorf("error querying state: %w", err) + } + + ret := &QueryResponse{ + Results: make([]QueryItem, len(resp.Results)), + Token: resp.Token, + Metadata: resp.Metadata, + } + for i, item := range resp.Results { + ret.Results[i].Key = item.Key + ret.Results[i].Value = item.Data + ret.Results[i].Etag = item.Etag + ret.Results[i].Error = item.Error + } + + return ret, nil +} + +// DeleteState deletes content from store using default state options. +func (c *GRPCClient) DeleteState(ctx context.Context, storeName, key string, meta map[string]string) error { + return c.DeleteStateWithETag(ctx, storeName, key, nil, meta, nil) +} + +// DeleteStateWithETag deletes content from store using provided state options and etag. +func (c *GRPCClient) DeleteStateWithETag(ctx context.Context, storeName, key string, etag *ETag, meta map[string]string, opts *StateOptions) error { + if err := hasRequiredStateArgs(storeName, key); err != nil { + return fmt.Errorf("missing required arguments: %w", err) + } + + req := &pb.DeleteStateRequest{ + StoreName: storeName, + Key: key, + Options: toProtoStateOptions(opts), + Metadata: meta, + } + + if etag != nil { + req.Etag = &v1.Etag{ + Value: etag.Value, + } + } + + _, err := c.protoClient.DeleteState(c.withAuthToken(ctx), req) + if err != nil { + return fmt.Errorf("error deleting state: %w", err) + } + + return nil +} + +// DeleteBulkState deletes content for multiple keys from store. +func (c *GRPCClient) DeleteBulkState(ctx context.Context, storeName string, keys []string, meta map[string]string) error { + if len(keys) == 0 { + return nil + } + + items := make([]*DeleteStateItem, 0, len(keys)) + for i := 0; i < len(keys); i++ { + item := &DeleteStateItem{ + Key: keys[i], + Metadata: meta, + } + items = append(items, item) + } + + return c.DeleteBulkStateItems(ctx, storeName, items) +} + +// DeleteBulkStateItems deletes content for multiple items from store. +func (c *GRPCClient) DeleteBulkStateItems(ctx context.Context, storeName string, items []*DeleteStateItem) error { + if len(items) == 0 { + return nil + } + + states := make([]*v1.StateItem, 0, len(items)) + for i := 0; i < len(items); i++ { + item := items[i] + if err := hasRequiredStateArgs(storeName, item.Key); err != nil { + return fmt.Errorf("missing required arguments: %w", err) + } + + state := &v1.StateItem{ + Key: item.Key, + Metadata: item.Metadata, + Options: toProtoStateOptions(item.Options), + } + if item.Etag != nil { + state.Etag = &v1.Etag{ + Value: item.Etag.Value, + } + } + states = append(states, state) + } + + req := &pb.DeleteBulkStateRequest{ + StoreName: storeName, + States: states, + } + _, err := c.protoClient.DeleteBulkState(c.withAuthToken(ctx), req) + + return err +} + +func hasRequiredStateArgs(storeName, key string) error { + if storeName == "" { + return errors.New("store") + } + if key == "" { + return errors.New("key") + } + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/client/utils.go b/vendor/github.com/dapr/go-sdk/client/utils.go new file mode 100644 index 00000000000..f49fb2a2243 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/utils.go @@ -0,0 +1,32 @@ +/* +Copyright 2023 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import "encoding/json" + +// isCloudEvent returns true if the event is a CloudEvent. +// An event is a CloudEvent if it `id`, `source`, `specversion` and `type` fields. +// See https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md for more details. +func isCloudEvent(event []byte) bool { + var ce struct { + ID string `json:"id"` + Source string `json:"source"` + SpecVersion string `json:"specversion"` + Type string `json:"type"` + } + if err := json.Unmarshal(event, &ce); err != nil { + return false + } + return ce.ID != "" && ce.Source != "" && ce.SpecVersion != "" && ce.Type != "" +} diff --git a/vendor/github.com/dapr/go-sdk/client/wait.go b/vendor/github.com/dapr/go-sdk/client/wait.go new file mode 100644 index 00000000000..6d7693f9d73 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/client/wait.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + "errors" + "time" + + "google.golang.org/grpc/connectivity" +) + +// The following errors are returned from Wait. +var ( + // A call to Wait timed out while waiting for a gRPC connection to reach a Ready state. + errWaitTimedOut = errors.New("timed out waiting for client connectivity") +) + +func (c *GRPCClient) Wait(ctx context.Context, timeout time.Duration) error { + timeoutCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + // SDKs for other languages implement Wait by attempting to connect to a TCP endpoint + // with a timeout. Go's SDKs handles more endpoints than just TCP ones. To simplify + // the code here, we rely on GRPCs connectivity state management instead. + // See https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md + for { + curState := c.connection.GetState() + if curState == connectivity.Ready { + return nil + } + + select { + case <-timeoutCtx.Done(): + return errWaitTimedOut + default: + // Multiple state changes can happen: keep waiting for a successful one or time out + c.connection.WaitForStateChange(timeoutCtx, curState) + } + } +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/common/v1/common.pb.go b/vendor/github.com/dapr/go-sdk/dapr/proto/common/v1/common.pb.go new file mode 100644 index 00000000000..577f5f7c458 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/common/v1/common.pb.go @@ -0,0 +1,1022 @@ +// +//Copyright 2021 The Dapr Authors +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +//http://www.apache.org/licenses/LICENSE-2.0 +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: dapr/proto/common/v1/common.proto + +package common + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Type of HTTP 1.1 Methods +// RFC 7231: https://tools.ietf.org/html/rfc7231#page-24 +// RFC 5789: https://datatracker.ietf.org/doc/html/rfc5789 +type HTTPExtension_Verb int32 + +const ( + HTTPExtension_NONE HTTPExtension_Verb = 0 + HTTPExtension_GET HTTPExtension_Verb = 1 + HTTPExtension_HEAD HTTPExtension_Verb = 2 + HTTPExtension_POST HTTPExtension_Verb = 3 + HTTPExtension_PUT HTTPExtension_Verb = 4 + HTTPExtension_DELETE HTTPExtension_Verb = 5 + HTTPExtension_CONNECT HTTPExtension_Verb = 6 + HTTPExtension_OPTIONS HTTPExtension_Verb = 7 + HTTPExtension_TRACE HTTPExtension_Verb = 8 + HTTPExtension_PATCH HTTPExtension_Verb = 9 +) + +// Enum value maps for HTTPExtension_Verb. +var ( + HTTPExtension_Verb_name = map[int32]string{ + 0: "NONE", + 1: "GET", + 2: "HEAD", + 3: "POST", + 4: "PUT", + 5: "DELETE", + 6: "CONNECT", + 7: "OPTIONS", + 8: "TRACE", + 9: "PATCH", + } + HTTPExtension_Verb_value = map[string]int32{ + "NONE": 0, + "GET": 1, + "HEAD": 2, + "POST": 3, + "PUT": 4, + "DELETE": 5, + "CONNECT": 6, + "OPTIONS": 7, + "TRACE": 8, + "PATCH": 9, + } +) + +func (x HTTPExtension_Verb) Enum() *HTTPExtension_Verb { + p := new(HTTPExtension_Verb) + *p = x + return p +} + +func (x HTTPExtension_Verb) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HTTPExtension_Verb) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_common_v1_common_proto_enumTypes[0].Descriptor() +} + +func (HTTPExtension_Verb) Type() protoreflect.EnumType { + return &file_dapr_proto_common_v1_common_proto_enumTypes[0] +} + +func (x HTTPExtension_Verb) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use HTTPExtension_Verb.Descriptor instead. +func (HTTPExtension_Verb) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{0, 0} +} + +// Enum describing the supported concurrency for state. +type StateOptions_StateConcurrency int32 + +const ( + StateOptions_CONCURRENCY_UNSPECIFIED StateOptions_StateConcurrency = 0 + StateOptions_CONCURRENCY_FIRST_WRITE StateOptions_StateConcurrency = 1 + StateOptions_CONCURRENCY_LAST_WRITE StateOptions_StateConcurrency = 2 +) + +// Enum value maps for StateOptions_StateConcurrency. +var ( + StateOptions_StateConcurrency_name = map[int32]string{ + 0: "CONCURRENCY_UNSPECIFIED", + 1: "CONCURRENCY_FIRST_WRITE", + 2: "CONCURRENCY_LAST_WRITE", + } + StateOptions_StateConcurrency_value = map[string]int32{ + "CONCURRENCY_UNSPECIFIED": 0, + "CONCURRENCY_FIRST_WRITE": 1, + "CONCURRENCY_LAST_WRITE": 2, + } +) + +func (x StateOptions_StateConcurrency) Enum() *StateOptions_StateConcurrency { + p := new(StateOptions_StateConcurrency) + *p = x + return p +} + +func (x StateOptions_StateConcurrency) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StateOptions_StateConcurrency) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_common_v1_common_proto_enumTypes[1].Descriptor() +} + +func (StateOptions_StateConcurrency) Type() protoreflect.EnumType { + return &file_dapr_proto_common_v1_common_proto_enumTypes[1] +} + +func (x StateOptions_StateConcurrency) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StateOptions_StateConcurrency.Descriptor instead. +func (StateOptions_StateConcurrency) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{6, 0} +} + +// Enum describing the supported consistency for state. +type StateOptions_StateConsistency int32 + +const ( + StateOptions_CONSISTENCY_UNSPECIFIED StateOptions_StateConsistency = 0 + StateOptions_CONSISTENCY_EVENTUAL StateOptions_StateConsistency = 1 + StateOptions_CONSISTENCY_STRONG StateOptions_StateConsistency = 2 +) + +// Enum value maps for StateOptions_StateConsistency. +var ( + StateOptions_StateConsistency_name = map[int32]string{ + 0: "CONSISTENCY_UNSPECIFIED", + 1: "CONSISTENCY_EVENTUAL", + 2: "CONSISTENCY_STRONG", + } + StateOptions_StateConsistency_value = map[string]int32{ + "CONSISTENCY_UNSPECIFIED": 0, + "CONSISTENCY_EVENTUAL": 1, + "CONSISTENCY_STRONG": 2, + } +) + +func (x StateOptions_StateConsistency) Enum() *StateOptions_StateConsistency { + p := new(StateOptions_StateConsistency) + *p = x + return p +} + +func (x StateOptions_StateConsistency) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StateOptions_StateConsistency) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_common_v1_common_proto_enumTypes[2].Descriptor() +} + +func (StateOptions_StateConsistency) Type() protoreflect.EnumType { + return &file_dapr_proto_common_v1_common_proto_enumTypes[2] +} + +func (x StateOptions_StateConsistency) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StateOptions_StateConsistency.Descriptor instead. +func (StateOptions_StateConsistency) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{6, 1} +} + +// HTTPExtension includes HTTP verb and querystring +// when Dapr runtime delivers HTTP content. +// +// For example, when callers calls http invoke api +// POST http://localhost:3500/v1.0/invoke//method/?query1=value1&query2=value2 +// +// Dapr runtime will parse POST as a verb and extract querystring to quersytring map. +type HTTPExtension struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. HTTP verb. + Verb HTTPExtension_Verb `protobuf:"varint,1,opt,name=verb,proto3,enum=dapr.proto.common.v1.HTTPExtension_Verb" json:"verb,omitempty"` + // Optional. querystring represents an encoded HTTP url query string in the following format: name=value&name2=value2 + Querystring string `protobuf:"bytes,2,opt,name=querystring,proto3" json:"querystring,omitempty"` +} + +func (x *HTTPExtension) Reset() { + *x = HTTPExtension{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HTTPExtension) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPExtension) ProtoMessage() {} + +func (x *HTTPExtension) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HTTPExtension.ProtoReflect.Descriptor instead. +func (*HTTPExtension) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPExtension) GetVerb() HTTPExtension_Verb { + if x != nil { + return x.Verb + } + return HTTPExtension_NONE +} + +func (x *HTTPExtension) GetQuerystring() string { + if x != nil { + return x.Querystring + } + return "" +} + +// InvokeRequest is the message to invoke a method with the data. +// This message is used in InvokeService of Dapr gRPC Service and OnInvoke +// of AppCallback gRPC service. +type InvokeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. method is a method name which will be invoked by caller. + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + // Required in unary RPCs. Bytes value or Protobuf message which caller sent. + // Dapr treats Any.value as bytes type if Any.type_url is unset. + Data *anypb.Any `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // The type of data content. + // + // This field is required if data delivers http request body + // Otherwise, this is optional. + ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // HTTP specific fields if request conveys http-compatible request. + // + // This field is required for http-compatible request. Otherwise, + // this field is optional. + HttpExtension *HTTPExtension `protobuf:"bytes,4,opt,name=http_extension,json=httpExtension,proto3" json:"http_extension,omitempty"` +} + +func (x *InvokeRequest) Reset() { + *x = InvokeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeRequest) ProtoMessage() {} + +func (x *InvokeRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeRequest.ProtoReflect.Descriptor instead. +func (*InvokeRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{1} +} + +func (x *InvokeRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *InvokeRequest) GetData() *anypb.Any { + if x != nil { + return x.Data + } + return nil +} + +func (x *InvokeRequest) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +func (x *InvokeRequest) GetHttpExtension() *HTTPExtension { + if x != nil { + return x.HttpExtension + } + return nil +} + +// InvokeResponse is the response message including data and its content type +// from app callback. +// This message is used in InvokeService of Dapr gRPC Service and OnInvoke +// of AppCallback gRPC service. +type InvokeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required in unary RPCs. The content body of InvokeService response. + Data *anypb.Any `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + // Required. The type of data content. + ContentType string `protobuf:"bytes,2,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` +} + +func (x *InvokeResponse) Reset() { + *x = InvokeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeResponse) ProtoMessage() {} + +func (x *InvokeResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeResponse.ProtoReflect.Descriptor instead. +func (*InvokeResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{2} +} + +func (x *InvokeResponse) GetData() *anypb.Any { + if x != nil { + return x.Data + } + return nil +} + +func (x *InvokeResponse) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +// Chunk of data sent in a streaming request or response. +// This is used in requests including InternalInvokeRequestStream. +type StreamPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Data sent in the chunk. + // The amount of data included in each chunk is up to the discretion of the sender, and can be empty. + // Additionally, the amount of data doesn't need to be fixed and subsequent messages can send more, or less, data. + // Receivers must not make assumptions about the number of bytes they'll receive in each chunk. + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + // Sequence number. This is a counter that starts from 0 and increments by 1 on each chunk sent. + Seq uint64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq,omitempty"` +} + +func (x *StreamPayload) Reset() { + *x = StreamPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StreamPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPayload) ProtoMessage() {} + +func (x *StreamPayload) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPayload.ProtoReflect.Descriptor instead. +func (*StreamPayload) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{3} +} + +func (x *StreamPayload) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *StreamPayload) GetSeq() uint64 { + if x != nil { + return x.Seq + } + return 0 +} + +// StateItem represents state key, value, and additional options to save state. +type StateItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The state key + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Required. The state data for key + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // The entity tag which represents the specific version of data. + // The exact ETag format is defined by the corresponding data store. + Etag *Etag `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + // The metadata which will be passed to state store component. + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Options for concurrency and consistency to save the state. + Options *StateOptions `protobuf:"bytes,5,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *StateItem) Reset() { + *x = StateItem{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateItem) ProtoMessage() {} + +func (x *StateItem) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StateItem.ProtoReflect.Descriptor instead. +func (*StateItem) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{4} +} + +func (x *StateItem) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *StateItem) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *StateItem) GetEtag() *Etag { + if x != nil { + return x.Etag + } + return nil +} + +func (x *StateItem) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *StateItem) GetOptions() *StateOptions { + if x != nil { + return x.Options + } + return nil +} + +// Etag represents a state item version +type Etag struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // value sets the etag value + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Etag) Reset() { + *x = Etag{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Etag) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Etag) ProtoMessage() {} + +func (x *Etag) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Etag.ProtoReflect.Descriptor instead. +func (*Etag) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{5} +} + +func (x *Etag) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +// StateOptions configures concurrency and consistency for state operations +type StateOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Concurrency StateOptions_StateConcurrency `protobuf:"varint,1,opt,name=concurrency,proto3,enum=dapr.proto.common.v1.StateOptions_StateConcurrency" json:"concurrency,omitempty"` + Consistency StateOptions_StateConsistency `protobuf:"varint,2,opt,name=consistency,proto3,enum=dapr.proto.common.v1.StateOptions_StateConsistency" json:"consistency,omitempty"` +} + +func (x *StateOptions) Reset() { + *x = StateOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateOptions) ProtoMessage() {} + +func (x *StateOptions) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StateOptions.ProtoReflect.Descriptor instead. +func (*StateOptions) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{6} +} + +func (x *StateOptions) GetConcurrency() StateOptions_StateConcurrency { + if x != nil { + return x.Concurrency + } + return StateOptions_CONCURRENCY_UNSPECIFIED +} + +func (x *StateOptions) GetConsistency() StateOptions_StateConsistency { + if x != nil { + return x.Consistency + } + return StateOptions_CONSISTENCY_UNSPECIFIED +} + +// ConfigurationItem represents all the configuration with its name(key). +type ConfigurationItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The value of configuration item. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + // Version is response only and cannot be fetched. Store is not expected to keep all versions available + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // the metadata which will be passed to/from configuration store component. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ConfigurationItem) Reset() { + *x = ConfigurationItem{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationItem) ProtoMessage() {} + +func (x *ConfigurationItem) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_common_v1_common_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigurationItem.ProtoReflect.Descriptor instead. +func (*ConfigurationItem) Descriptor() ([]byte, []int) { + return file_dapr_proto_common_v1_common_proto_rawDescGZIP(), []int{7} +} + +func (x *ConfigurationItem) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ConfigurationItem) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ConfigurationItem) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +var File_dapr_proto_common_v1_common_proto protoreflect.FileDescriptor + +var file_dapr_proto_common_v1_common_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe3, 0x01, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x04, 0x76, 0x65, 0x72, 0x62, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x62, 0x52, 0x04, + 0x76, 0x65, 0x72, 0x62, 0x12, 0x20, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x72, 0x0a, 0x04, 0x56, 0x65, 0x72, 0x62, 0x12, 0x08, + 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, + 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x45, 0x41, 0x44, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, + 0x4f, 0x53, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x04, 0x12, 0x0a, + 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, + 0x4e, 0x53, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x08, 0x12, + 0x09, 0x0a, 0x05, 0x50, 0x41, 0x54, 0x43, 0x48, 0x10, 0x09, 0x22, 0xc0, 0x01, 0x0a, 0x0d, 0x49, + 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, + 0x68, 0x74, 0x74, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x0a, + 0x0e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x35, 0x0a, 0x0d, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, + 0x73, 0x65, 0x71, 0x22, 0xa9, 0x02, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, + 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x65, 0x74, 0x61, + 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x74, 0x61, 0x67, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x49, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x3c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x1c, 0x0a, 0x04, 0x45, 0x74, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x89, 0x03, + 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x55, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x68, 0x0a, 0x10, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, + 0x17, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x46, 0x49, 0x52, + 0x53, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, + 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4c, 0x41, 0x53, 0x54, 0x5f, 0x57, + 0x52, 0x49, 0x54, 0x45, 0x10, 0x02, 0x22, 0x61, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, + 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x53, 0x49, + 0x53, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x55, 0x41, 0x4c, 0x10, + 0x01, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x43, 0x59, + 0x5f, 0x53, 0x54, 0x52, 0x4f, 0x4e, 0x47, 0x10, 0x02, 0x22, 0xd3, 0x01, 0x0a, 0x11, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x51, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, + 0x69, 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x5a, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x64, 0x61, 0x70, + 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xaa, 0x02, 0x1b, 0x44, + 0x61, 0x70, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x67, + 0x65, 0x6e, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_dapr_proto_common_v1_common_proto_rawDescOnce sync.Once + file_dapr_proto_common_v1_common_proto_rawDescData = file_dapr_proto_common_v1_common_proto_rawDesc +) + +func file_dapr_proto_common_v1_common_proto_rawDescGZIP() []byte { + file_dapr_proto_common_v1_common_proto_rawDescOnce.Do(func() { + file_dapr_proto_common_v1_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_dapr_proto_common_v1_common_proto_rawDescData) + }) + return file_dapr_proto_common_v1_common_proto_rawDescData +} + +var file_dapr_proto_common_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_dapr_proto_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_dapr_proto_common_v1_common_proto_goTypes = []interface{}{ + (HTTPExtension_Verb)(0), // 0: dapr.proto.common.v1.HTTPExtension.Verb + (StateOptions_StateConcurrency)(0), // 1: dapr.proto.common.v1.StateOptions.StateConcurrency + (StateOptions_StateConsistency)(0), // 2: dapr.proto.common.v1.StateOptions.StateConsistency + (*HTTPExtension)(nil), // 3: dapr.proto.common.v1.HTTPExtension + (*InvokeRequest)(nil), // 4: dapr.proto.common.v1.InvokeRequest + (*InvokeResponse)(nil), // 5: dapr.proto.common.v1.InvokeResponse + (*StreamPayload)(nil), // 6: dapr.proto.common.v1.StreamPayload + (*StateItem)(nil), // 7: dapr.proto.common.v1.StateItem + (*Etag)(nil), // 8: dapr.proto.common.v1.Etag + (*StateOptions)(nil), // 9: dapr.proto.common.v1.StateOptions + (*ConfigurationItem)(nil), // 10: dapr.proto.common.v1.ConfigurationItem + nil, // 11: dapr.proto.common.v1.StateItem.MetadataEntry + nil, // 12: dapr.proto.common.v1.ConfigurationItem.MetadataEntry + (*anypb.Any)(nil), // 13: google.protobuf.Any +} +var file_dapr_proto_common_v1_common_proto_depIdxs = []int32{ + 0, // 0: dapr.proto.common.v1.HTTPExtension.verb:type_name -> dapr.proto.common.v1.HTTPExtension.Verb + 13, // 1: dapr.proto.common.v1.InvokeRequest.data:type_name -> google.protobuf.Any + 3, // 2: dapr.proto.common.v1.InvokeRequest.http_extension:type_name -> dapr.proto.common.v1.HTTPExtension + 13, // 3: dapr.proto.common.v1.InvokeResponse.data:type_name -> google.protobuf.Any + 8, // 4: dapr.proto.common.v1.StateItem.etag:type_name -> dapr.proto.common.v1.Etag + 11, // 5: dapr.proto.common.v1.StateItem.metadata:type_name -> dapr.proto.common.v1.StateItem.MetadataEntry + 9, // 6: dapr.proto.common.v1.StateItem.options:type_name -> dapr.proto.common.v1.StateOptions + 1, // 7: dapr.proto.common.v1.StateOptions.concurrency:type_name -> dapr.proto.common.v1.StateOptions.StateConcurrency + 2, // 8: dapr.proto.common.v1.StateOptions.consistency:type_name -> dapr.proto.common.v1.StateOptions.StateConsistency + 12, // 9: dapr.proto.common.v1.ConfigurationItem.metadata:type_name -> dapr.proto.common.v1.ConfigurationItem.MetadataEntry + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_dapr_proto_common_v1_common_proto_init() } +func file_dapr_proto_common_v1_common_proto_init() { + if File_dapr_proto_common_v1_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dapr_proto_common_v1_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HTTPExtension); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StreamPayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Etag); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_common_v1_common_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigurationItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dapr_proto_common_v1_common_proto_rawDesc, + NumEnums: 3, + NumMessages: 10, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_dapr_proto_common_v1_common_proto_goTypes, + DependencyIndexes: file_dapr_proto_common_v1_common_proto_depIdxs, + EnumInfos: file_dapr_proto_common_v1_common_proto_enumTypes, + MessageInfos: file_dapr_proto_common_v1_common_proto_msgTypes, + }.Build() + File_dapr_proto_common_v1_common_proto = out.File + file_dapr_proto_common_v1_common_proto_rawDesc = nil + file_dapr_proto_common_v1_common_proto_goTypes = nil + file_dapr_proto_common_v1_common_proto_depIdxs = nil +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback.pb.go b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback.pb.go new file mode 100644 index 00000000000..b61cf152ee7 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback.pb.go @@ -0,0 +1,1897 @@ +// +//Copyright 2021 The Dapr Authors +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +//http://www.apache.org/licenses/LICENSE-2.0 +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: dapr/proto/runtime/v1/appcallback.proto + +package runtime + +import ( + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// TopicEventResponseStatus allows apps to have finer control over handling of the message. +type TopicEventResponse_TopicEventResponseStatus int32 + +const ( + // SUCCESS is the default behavior: message is acknowledged and not retried or logged. + TopicEventResponse_SUCCESS TopicEventResponse_TopicEventResponseStatus = 0 + // RETRY status signals Dapr to retry the message as part of an expected scenario (no warning is logged). + TopicEventResponse_RETRY TopicEventResponse_TopicEventResponseStatus = 1 + // DROP status signals Dapr to drop the message as part of an unexpected scenario (warning is logged). + TopicEventResponse_DROP TopicEventResponse_TopicEventResponseStatus = 2 +) + +// Enum value maps for TopicEventResponse_TopicEventResponseStatus. +var ( + TopicEventResponse_TopicEventResponseStatus_name = map[int32]string{ + 0: "SUCCESS", + 1: "RETRY", + 2: "DROP", + } + TopicEventResponse_TopicEventResponseStatus_value = map[string]int32{ + "SUCCESS": 0, + "RETRY": 1, + "DROP": 2, + } +) + +func (x TopicEventResponse_TopicEventResponseStatus) Enum() *TopicEventResponse_TopicEventResponseStatus { + p := new(TopicEventResponse_TopicEventResponseStatus) + *p = x + return p +} + +func (x TopicEventResponse_TopicEventResponseStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TopicEventResponse_TopicEventResponseStatus) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_runtime_v1_appcallback_proto_enumTypes[0].Descriptor() +} + +func (TopicEventResponse_TopicEventResponseStatus) Type() protoreflect.EnumType { + return &file_dapr_proto_runtime_v1_appcallback_proto_enumTypes[0] +} + +func (x TopicEventResponse_TopicEventResponseStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TopicEventResponse_TopicEventResponseStatus.Descriptor instead. +func (TopicEventResponse_TopicEventResponseStatus) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{1, 0} +} + +// BindingEventConcurrency is the kind of concurrency +type BindingEventResponse_BindingEventConcurrency int32 + +const ( + // SEQUENTIAL sends data to output bindings specified in "to" sequentially. + BindingEventResponse_SEQUENTIAL BindingEventResponse_BindingEventConcurrency = 0 + // PARALLEL sends data to output bindings specified in "to" in parallel. + BindingEventResponse_PARALLEL BindingEventResponse_BindingEventConcurrency = 1 +) + +// Enum value maps for BindingEventResponse_BindingEventConcurrency. +var ( + BindingEventResponse_BindingEventConcurrency_name = map[int32]string{ + 0: "SEQUENTIAL", + 1: "PARALLEL", + } + BindingEventResponse_BindingEventConcurrency_value = map[string]int32{ + "SEQUENTIAL": 0, + "PARALLEL": 1, + } +) + +func (x BindingEventResponse_BindingEventConcurrency) Enum() *BindingEventResponse_BindingEventConcurrency { + p := new(BindingEventResponse_BindingEventConcurrency) + *p = x + return p +} + +func (x BindingEventResponse_BindingEventConcurrency) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BindingEventResponse_BindingEventConcurrency) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_runtime_v1_appcallback_proto_enumTypes[1].Descriptor() +} + +func (BindingEventResponse_BindingEventConcurrency) Type() protoreflect.EnumType { + return &file_dapr_proto_runtime_v1_appcallback_proto_enumTypes[1] +} + +func (x BindingEventResponse_BindingEventConcurrency) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BindingEventResponse_BindingEventConcurrency.Descriptor instead. +func (BindingEventResponse_BindingEventConcurrency) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{8, 0} +} + +// TopicEventRequest message is compatible with CloudEvent spec v1.0 +// https://github.com/cloudevents/spec/blob/v1.0/spec.md +type TopicEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // id identifies the event. Producers MUST ensure that source + id + // is unique for each distinct event. If a duplicate event is re-sent + // (e.g. due to a network error) it MAY have the same id. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // source identifies the context in which an event happened. + // Often this will include information such as the type of the + // event source, the organization publishing the event or the process + // that produced the event. The exact syntax and semantics behind + // the data encoded in the URI is defined by the event producer. + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + // The type of event related to the originating occurrence. + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + // The version of the CloudEvents specification. + SpecVersion string `protobuf:"bytes,4,opt,name=spec_version,json=specVersion,proto3" json:"spec_version,omitempty"` + // The content type of data value. + DataContentType string `protobuf:"bytes,5,opt,name=data_content_type,json=dataContentType,proto3" json:"data_content_type,omitempty"` + // The content of the event. + Data []byte `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"` + // The pubsub topic which publisher sent to. + Topic string `protobuf:"bytes,6,opt,name=topic,proto3" json:"topic,omitempty"` + // The name of the pubsub the publisher sent to. + PubsubName string `protobuf:"bytes,8,opt,name=pubsub_name,json=pubsubName,proto3" json:"pubsub_name,omitempty"` + // The matching path from TopicSubscription/routes (if specified) for this event. + // This value is used by OnTopicEvent to "switch" inside the handler. + Path string `protobuf:"bytes,9,opt,name=path,proto3" json:"path,omitempty"` + // The map of additional custom properties to be sent to the app. These are considered to be cloud event extensions. + Extensions *structpb.Struct `protobuf:"bytes,10,opt,name=extensions,proto3" json:"extensions,omitempty"` +} + +func (x *TopicEventRequest) Reset() { + *x = TopicEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventRequest) ProtoMessage() {} + +func (x *TopicEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventRequest.ProtoReflect.Descriptor instead. +func (*TopicEventRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{0} +} + +func (x *TopicEventRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TopicEventRequest) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *TopicEventRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *TopicEventRequest) GetSpecVersion() string { + if x != nil { + return x.SpecVersion + } + return "" +} + +func (x *TopicEventRequest) GetDataContentType() string { + if x != nil { + return x.DataContentType + } + return "" +} + +func (x *TopicEventRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *TopicEventRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *TopicEventRequest) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *TopicEventRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *TopicEventRequest) GetExtensions() *structpb.Struct { + if x != nil { + return x.Extensions + } + return nil +} + +// TopicEventResponse is response from app on published message +type TopicEventResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of output bindings. + Status TopicEventResponse_TopicEventResponseStatus `protobuf:"varint,1,opt,name=status,proto3,enum=dapr.proto.runtime.v1.TopicEventResponse_TopicEventResponseStatus" json:"status,omitempty"` +} + +func (x *TopicEventResponse) Reset() { + *x = TopicEventResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventResponse) ProtoMessage() {} + +func (x *TopicEventResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventResponse.ProtoReflect.Descriptor instead. +func (*TopicEventResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{1} +} + +func (x *TopicEventResponse) GetStatus() TopicEventResponse_TopicEventResponseStatus { + if x != nil { + return x.Status + } + return TopicEventResponse_SUCCESS +} + +// TopicEventCERequest message is compatible with CloudEvent spec v1.0 +type TopicEventCERequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The unique identifier of this cloud event. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // source identifies the context in which an event happened. + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + // The type of event related to the originating occurrence. + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + // The version of the CloudEvents specification. + SpecVersion string `protobuf:"bytes,4,opt,name=spec_version,json=specVersion,proto3" json:"spec_version,omitempty"` + // The content type of data value. + DataContentType string `protobuf:"bytes,5,opt,name=data_content_type,json=dataContentType,proto3" json:"data_content_type,omitempty"` + // The content of the event. + Data []byte `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"` + // Custom attributes which includes cloud event extensions. + Extensions *structpb.Struct `protobuf:"bytes,7,opt,name=extensions,proto3" json:"extensions,omitempty"` +} + +func (x *TopicEventCERequest) Reset() { + *x = TopicEventCERequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventCERequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventCERequest) ProtoMessage() {} + +func (x *TopicEventCERequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventCERequest.ProtoReflect.Descriptor instead. +func (*TopicEventCERequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{2} +} + +func (x *TopicEventCERequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TopicEventCERequest) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *TopicEventCERequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *TopicEventCERequest) GetSpecVersion() string { + if x != nil { + return x.SpecVersion + } + return "" +} + +func (x *TopicEventCERequest) GetDataContentType() string { + if x != nil { + return x.DataContentType + } + return "" +} + +func (x *TopicEventCERequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *TopicEventCERequest) GetExtensions() *structpb.Struct { + if x != nil { + return x.Extensions + } + return nil +} + +// TopicEventBulkRequestEntry represents a single message inside a bulk request +type TopicEventBulkRequestEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier for the message. + EntryId string `protobuf:"bytes,1,opt,name=entry_id,json=entryId,proto3" json:"entry_id,omitempty"` + // The content of the event. + // + // Types that are assignable to Event: + // + // *TopicEventBulkRequestEntry_Bytes + // *TopicEventBulkRequestEntry_CloudEvent + Event isTopicEventBulkRequestEntry_Event `protobuf_oneof:"event"` + // content type of the event contained. + ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // The metadata associated with the event. + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *TopicEventBulkRequestEntry) Reset() { + *x = TopicEventBulkRequestEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventBulkRequestEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventBulkRequestEntry) ProtoMessage() {} + +func (x *TopicEventBulkRequestEntry) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventBulkRequestEntry.ProtoReflect.Descriptor instead. +func (*TopicEventBulkRequestEntry) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{3} +} + +func (x *TopicEventBulkRequestEntry) GetEntryId() string { + if x != nil { + return x.EntryId + } + return "" +} + +func (m *TopicEventBulkRequestEntry) GetEvent() isTopicEventBulkRequestEntry_Event { + if m != nil { + return m.Event + } + return nil +} + +func (x *TopicEventBulkRequestEntry) GetBytes() []byte { + if x, ok := x.GetEvent().(*TopicEventBulkRequestEntry_Bytes); ok { + return x.Bytes + } + return nil +} + +func (x *TopicEventBulkRequestEntry) GetCloudEvent() *TopicEventCERequest { + if x, ok := x.GetEvent().(*TopicEventBulkRequestEntry_CloudEvent); ok { + return x.CloudEvent + } + return nil +} + +func (x *TopicEventBulkRequestEntry) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +func (x *TopicEventBulkRequestEntry) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type isTopicEventBulkRequestEntry_Event interface { + isTopicEventBulkRequestEntry_Event() +} + +type TopicEventBulkRequestEntry_Bytes struct { + Bytes []byte `protobuf:"bytes,2,opt,name=bytes,proto3,oneof"` +} + +type TopicEventBulkRequestEntry_CloudEvent struct { + CloudEvent *TopicEventCERequest `protobuf:"bytes,3,opt,name=cloud_event,json=cloudEvent,proto3,oneof"` +} + +func (*TopicEventBulkRequestEntry_Bytes) isTopicEventBulkRequestEntry_Event() {} + +func (*TopicEventBulkRequestEntry_CloudEvent) isTopicEventBulkRequestEntry_Event() {} + +// TopicEventBulkRequest represents request for bulk message +type TopicEventBulkRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier for the bulk request. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The list of items inside this bulk request. + Entries []*TopicEventBulkRequestEntry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` + // The metadata associated with the this bulk request. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The pubsub topic which publisher sent to. + Topic string `protobuf:"bytes,4,opt,name=topic,proto3" json:"topic,omitempty"` + // The name of the pubsub the publisher sent to. + PubsubName string `protobuf:"bytes,5,opt,name=pubsub_name,json=pubsubName,proto3" json:"pubsub_name,omitempty"` + // The type of event related to the originating occurrence. + Type string `protobuf:"bytes,6,opt,name=type,proto3" json:"type,omitempty"` + // The matching path from TopicSubscription/routes (if specified) for this event. + // This value is used by OnTopicEvent to "switch" inside the handler. + Path string `protobuf:"bytes,7,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *TopicEventBulkRequest) Reset() { + *x = TopicEventBulkRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventBulkRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventBulkRequest) ProtoMessage() {} + +func (x *TopicEventBulkRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventBulkRequest.ProtoReflect.Descriptor instead. +func (*TopicEventBulkRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{4} +} + +func (x *TopicEventBulkRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TopicEventBulkRequest) GetEntries() []*TopicEventBulkRequestEntry { + if x != nil { + return x.Entries + } + return nil +} + +func (x *TopicEventBulkRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *TopicEventBulkRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *TopicEventBulkRequest) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *TopicEventBulkRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *TopicEventBulkRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +// TopicEventBulkResponseEntry Represents single response, as part of TopicEventBulkResponse, to be +// sent by subscibed App for the corresponding single message during bulk subscribe +type TopicEventBulkResponseEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier associated the message. + EntryId string `protobuf:"bytes,1,opt,name=entry_id,json=entryId,proto3" json:"entry_id,omitempty"` + // The status of the response. + Status TopicEventResponse_TopicEventResponseStatus `protobuf:"varint,2,opt,name=status,proto3,enum=dapr.proto.runtime.v1.TopicEventResponse_TopicEventResponseStatus" json:"status,omitempty"` +} + +func (x *TopicEventBulkResponseEntry) Reset() { + *x = TopicEventBulkResponseEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventBulkResponseEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventBulkResponseEntry) ProtoMessage() {} + +func (x *TopicEventBulkResponseEntry) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventBulkResponseEntry.ProtoReflect.Descriptor instead. +func (*TopicEventBulkResponseEntry) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{5} +} + +func (x *TopicEventBulkResponseEntry) GetEntryId() string { + if x != nil { + return x.EntryId + } + return "" +} + +func (x *TopicEventBulkResponseEntry) GetStatus() TopicEventResponse_TopicEventResponseStatus { + if x != nil { + return x.Status + } + return TopicEventResponse_SUCCESS +} + +// AppBulkResponse is response from app on published message +type TopicEventBulkResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of all responses for the bulk request. + Statuses []*TopicEventBulkResponseEntry `protobuf:"bytes,1,rep,name=statuses,proto3" json:"statuses,omitempty"` +} + +func (x *TopicEventBulkResponse) Reset() { + *x = TopicEventBulkResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEventBulkResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEventBulkResponse) ProtoMessage() {} + +func (x *TopicEventBulkResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEventBulkResponse.ProtoReflect.Descriptor instead. +func (*TopicEventBulkResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{6} +} + +func (x *TopicEventBulkResponse) GetStatuses() []*TopicEventBulkResponseEntry { + if x != nil { + return x.Statuses + } + return nil +} + +// BindingEventRequest represents input bindings event. +type BindingEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The name of the input binding component. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Required. The payload that the input bindings sent + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // The metadata set by the input binging components. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *BindingEventRequest) Reset() { + *x = BindingEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BindingEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BindingEventRequest) ProtoMessage() {} + +func (x *BindingEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BindingEventRequest.ProtoReflect.Descriptor instead. +func (*BindingEventRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{7} +} + +func (x *BindingEventRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *BindingEventRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *BindingEventRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// BindingEventResponse includes operations to save state or +// send data to output bindings optionally. +type BindingEventResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store where states are saved. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The state key values which will be stored in store_name. + States []*v1.StateItem `protobuf:"bytes,2,rep,name=states,proto3" json:"states,omitempty"` + // The list of output bindings. + To []string `protobuf:"bytes,3,rep,name=to,proto3" json:"to,omitempty"` + // The content which will be sent to "to" output bindings. + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + // The concurrency of output bindings to send data to + // "to" output bindings list. The default is SEQUENTIAL. + Concurrency BindingEventResponse_BindingEventConcurrency `protobuf:"varint,5,opt,name=concurrency,proto3,enum=dapr.proto.runtime.v1.BindingEventResponse_BindingEventConcurrency" json:"concurrency,omitempty"` +} + +func (x *BindingEventResponse) Reset() { + *x = BindingEventResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BindingEventResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BindingEventResponse) ProtoMessage() {} + +func (x *BindingEventResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BindingEventResponse.ProtoReflect.Descriptor instead. +func (*BindingEventResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{8} +} + +func (x *BindingEventResponse) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *BindingEventResponse) GetStates() []*v1.StateItem { + if x != nil { + return x.States + } + return nil +} + +func (x *BindingEventResponse) GetTo() []string { + if x != nil { + return x.To + } + return nil +} + +func (x *BindingEventResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *BindingEventResponse) GetConcurrency() BindingEventResponse_BindingEventConcurrency { + if x != nil { + return x.Concurrency + } + return BindingEventResponse_SEQUENTIAL +} + +// ListTopicSubscriptionsResponse is the message including the list of the subscribing topics. +type ListTopicSubscriptionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of topics. + Subscriptions []*TopicSubscription `protobuf:"bytes,1,rep,name=subscriptions,proto3" json:"subscriptions,omitempty"` +} + +func (x *ListTopicSubscriptionsResponse) Reset() { + *x = ListTopicSubscriptionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTopicSubscriptionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTopicSubscriptionsResponse) ProtoMessage() {} + +func (x *ListTopicSubscriptionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListTopicSubscriptionsResponse.ProtoReflect.Descriptor instead. +func (*ListTopicSubscriptionsResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{9} +} + +func (x *ListTopicSubscriptionsResponse) GetSubscriptions() []*TopicSubscription { + if x != nil { + return x.Subscriptions + } + return nil +} + +// TopicSubscription represents topic and metadata. +type TopicSubscription struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The name of the pubsub containing the topic below to subscribe to. + PubsubName string `protobuf:"bytes,1,opt,name=pubsub_name,json=pubsubName,proto3" json:"pubsub_name,omitempty"` + // Required. The name of topic which will be subscribed + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + // The optional properties used for this topic's subscription e.g. session id + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The optional routing rules to match against. In the gRPC interface, OnTopicEvent + // is still invoked but the matching path is sent in the TopicEventRequest. + Routes *TopicRoutes `protobuf:"bytes,5,opt,name=routes,proto3" json:"routes,omitempty"` + // The optional dead letter queue for this topic to send events to. + DeadLetterTopic string `protobuf:"bytes,6,opt,name=dead_letter_topic,json=deadLetterTopic,proto3" json:"dead_letter_topic,omitempty"` + // The optional bulk subscribe settings for this topic. + BulkSubscribe *BulkSubscribeConfig `protobuf:"bytes,7,opt,name=bulk_subscribe,json=bulkSubscribe,proto3" json:"bulk_subscribe,omitempty"` +} + +func (x *TopicSubscription) Reset() { + *x = TopicSubscription{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicSubscription) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicSubscription) ProtoMessage() {} + +func (x *TopicSubscription) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicSubscription.ProtoReflect.Descriptor instead. +func (*TopicSubscription) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{10} +} + +func (x *TopicSubscription) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *TopicSubscription) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *TopicSubscription) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *TopicSubscription) GetRoutes() *TopicRoutes { + if x != nil { + return x.Routes + } + return nil +} + +func (x *TopicSubscription) GetDeadLetterTopic() string { + if x != nil { + return x.DeadLetterTopic + } + return "" +} + +func (x *TopicSubscription) GetBulkSubscribe() *BulkSubscribeConfig { + if x != nil { + return x.BulkSubscribe + } + return nil +} + +type TopicRoutes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of rules for this topic. + Rules []*TopicRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` + // The default path for this topic. + Default string `protobuf:"bytes,2,opt,name=default,proto3" json:"default,omitempty"` +} + +func (x *TopicRoutes) Reset() { + *x = TopicRoutes{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicRoutes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicRoutes) ProtoMessage() {} + +func (x *TopicRoutes) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicRoutes.ProtoReflect.Descriptor instead. +func (*TopicRoutes) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{11} +} + +func (x *TopicRoutes) GetRules() []*TopicRule { + if x != nil { + return x.Rules + } + return nil +} + +func (x *TopicRoutes) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + +type TopicRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The optional CEL expression used to match the event. + // If the match is not specified, then the route is considered + // the default. + Match string `protobuf:"bytes,1,opt,name=match,proto3" json:"match,omitempty"` + // The path used to identify matches for this subscription. + // This value is passed in TopicEventRequest and used by OnTopicEvent to "switch" + // inside the handler. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *TopicRule) Reset() { + *x = TopicRule{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicRule) ProtoMessage() {} + +func (x *TopicRule) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicRule.ProtoReflect.Descriptor instead. +func (*TopicRule) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{12} +} + +func (x *TopicRule) GetMatch() string { + if x != nil { + return x.Match + } + return "" +} + +func (x *TopicRule) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +// BulkSubscribeConfig is the message to pass settings for bulk subscribe +type BulkSubscribeConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. Flag to enable/disable bulk subscribe + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + // Optional. Max number of messages to be sent in a single bulk request + MaxMessagesCount int32 `protobuf:"varint,2,opt,name=max_messages_count,json=maxMessagesCount,proto3" json:"max_messages_count,omitempty"` + // Optional. Max duration to wait for messages to be sent in a single bulk request + MaxAwaitDurationMs int32 `protobuf:"varint,3,opt,name=max_await_duration_ms,json=maxAwaitDurationMs,proto3" json:"max_await_duration_ms,omitempty"` +} + +func (x *BulkSubscribeConfig) Reset() { + *x = BulkSubscribeConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkSubscribeConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkSubscribeConfig) ProtoMessage() {} + +func (x *BulkSubscribeConfig) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkSubscribeConfig.ProtoReflect.Descriptor instead. +func (*BulkSubscribeConfig) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{13} +} + +func (x *BulkSubscribeConfig) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *BulkSubscribeConfig) GetMaxMessagesCount() int32 { + if x != nil { + return x.MaxMessagesCount + } + return 0 +} + +func (x *BulkSubscribeConfig) GetMaxAwaitDurationMs() int32 { + if x != nil { + return x.MaxAwaitDurationMs + } + return 0 +} + +// ListInputBindingsResponse is the message including the list of input bindings. +type ListInputBindingsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of input bindings. + Bindings []string `protobuf:"bytes,1,rep,name=bindings,proto3" json:"bindings,omitempty"` +} + +func (x *ListInputBindingsResponse) Reset() { + *x = ListInputBindingsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInputBindingsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInputBindingsResponse) ProtoMessage() {} + +func (x *ListInputBindingsResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInputBindingsResponse.ProtoReflect.Descriptor instead. +func (*ListInputBindingsResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{14} +} + +func (x *ListInputBindingsResponse) GetBindings() []string { + if x != nil { + return x.Bindings + } + return nil +} + +// HealthCheckResponse is the message with the response to the health check. +// This message is currently empty as used as placeholder. +type HealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *HealthCheckResponse) Reset() { + *x = HealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckResponse) ProtoMessage() {} + +func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead. +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP(), []int{15} +} + +var File_dapr_proto_runtime_v1_appcallback_proto protoreflect.FileDescriptor + +var file_dapr_proto_runtime_v1_appcallback_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x64, + 0x61, 0x70, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, + 0x02, 0x0a, 0x11, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x64, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, + 0x73, 0x75, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, + 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xae, 0x01, 0x0a, 0x12, 0x54, 0x6f, 0x70, 0x69, + 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x42, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x18, 0x54, 0x6f, + 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, + 0x53, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x54, 0x52, 0x59, 0x10, 0x01, 0x12, 0x08, + 0x0a, 0x04, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x02, 0x22, 0xed, 0x01, 0x0a, 0x13, 0x54, 0x6f, 0x70, + 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x2a, 0x0a, 0x11, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x61, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x37, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x65, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe4, 0x02, 0x0a, 0x1a, 0x54, 0x6f, 0x70, + 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x49, 0x64, 0x12, 0x16, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x0b, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x5b, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, + 0xe8, 0x02, 0x0a, 0x15, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x75, + 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4b, 0x0a, 0x07, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x6c, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x73, 0x75, + 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x94, 0x01, 0x0a, 0x1b, 0x54, + 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x49, 0x64, 0x12, 0x5a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x42, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, + 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0x68, 0x0a, 0x16, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, + 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x22, 0xd0, 0x01, 0x0a, 0x13, + 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb2, + 0x02, 0x0a, 0x14, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, + 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x65, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x43, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x37, 0x0a, 0x17, 0x42, 0x69, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x54, + 0x49, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x41, 0x52, 0x41, 0x4c, 0x4c, 0x45, + 0x4c, 0x10, 0x01, 0x22, 0x70, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x70, 0x69, 0x63, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x96, 0x03, 0x0a, 0x11, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x12, 0x52, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, + 0x69, 0x63, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3a, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x6f, 0x70, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x61, 0x64, 0x5f, 0x6c, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x5f, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, + 0x65, 0x61, 0x64, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x51, + 0x0a, 0x0e, 0x62, 0x75, 0x6c, 0x6b, 0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x75, 0x6c, 0x6b, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6b, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5f, + 0x0a, 0x0b, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, + 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, + 0x35, 0x0a, 0x09, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x90, 0x01, 0x0a, 0x13, 0x42, 0x75, 0x6c, 0x6b, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x41, 0x77, 0x61, 0x69, 0x74, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x22, 0x37, 0x0a, 0x19, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x86, 0x04, 0x0a, 0x0b, 0x41, 0x70, + 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x57, 0x0a, 0x08, 0x4f, 0x6e, 0x49, + 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x23, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, + 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x69, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, + 0x0c, 0x4f, 0x6e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x30, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x0e, 0x4f, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x32, 0x6d, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x53, 0x0a, 0x0b, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x32, 0x8b, 0x01, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x12, 0x77, 0x0a, 0x16, 0x4f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, + 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x79, 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x15, 0x44, + 0x61, 0x70, 0x72, 0x41, 0x70, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x73, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0xaa, 0x02, 0x20, 0x44, 0x61, 0x70, 0x72, 0x2e, 0x41, + 0x70, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x67, + 0x65, 0x6e, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_dapr_proto_runtime_v1_appcallback_proto_rawDescOnce sync.Once + file_dapr_proto_runtime_v1_appcallback_proto_rawDescData = file_dapr_proto_runtime_v1_appcallback_proto_rawDesc +) + +func file_dapr_proto_runtime_v1_appcallback_proto_rawDescGZIP() []byte { + file_dapr_proto_runtime_v1_appcallback_proto_rawDescOnce.Do(func() { + file_dapr_proto_runtime_v1_appcallback_proto_rawDescData = protoimpl.X.CompressGZIP(file_dapr_proto_runtime_v1_appcallback_proto_rawDescData) + }) + return file_dapr_proto_runtime_v1_appcallback_proto_rawDescData +} + +var file_dapr_proto_runtime_v1_appcallback_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_dapr_proto_runtime_v1_appcallback_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_dapr_proto_runtime_v1_appcallback_proto_goTypes = []interface{}{ + (TopicEventResponse_TopicEventResponseStatus)(0), // 0: dapr.proto.runtime.v1.TopicEventResponse.TopicEventResponseStatus + (BindingEventResponse_BindingEventConcurrency)(0), // 1: dapr.proto.runtime.v1.BindingEventResponse.BindingEventConcurrency + (*TopicEventRequest)(nil), // 2: dapr.proto.runtime.v1.TopicEventRequest + (*TopicEventResponse)(nil), // 3: dapr.proto.runtime.v1.TopicEventResponse + (*TopicEventCERequest)(nil), // 4: dapr.proto.runtime.v1.TopicEventCERequest + (*TopicEventBulkRequestEntry)(nil), // 5: dapr.proto.runtime.v1.TopicEventBulkRequestEntry + (*TopicEventBulkRequest)(nil), // 6: dapr.proto.runtime.v1.TopicEventBulkRequest + (*TopicEventBulkResponseEntry)(nil), // 7: dapr.proto.runtime.v1.TopicEventBulkResponseEntry + (*TopicEventBulkResponse)(nil), // 8: dapr.proto.runtime.v1.TopicEventBulkResponse + (*BindingEventRequest)(nil), // 9: dapr.proto.runtime.v1.BindingEventRequest + (*BindingEventResponse)(nil), // 10: dapr.proto.runtime.v1.BindingEventResponse + (*ListTopicSubscriptionsResponse)(nil), // 11: dapr.proto.runtime.v1.ListTopicSubscriptionsResponse + (*TopicSubscription)(nil), // 12: dapr.proto.runtime.v1.TopicSubscription + (*TopicRoutes)(nil), // 13: dapr.proto.runtime.v1.TopicRoutes + (*TopicRule)(nil), // 14: dapr.proto.runtime.v1.TopicRule + (*BulkSubscribeConfig)(nil), // 15: dapr.proto.runtime.v1.BulkSubscribeConfig + (*ListInputBindingsResponse)(nil), // 16: dapr.proto.runtime.v1.ListInputBindingsResponse + (*HealthCheckResponse)(nil), // 17: dapr.proto.runtime.v1.HealthCheckResponse + nil, // 18: dapr.proto.runtime.v1.TopicEventBulkRequestEntry.MetadataEntry + nil, // 19: dapr.proto.runtime.v1.TopicEventBulkRequest.MetadataEntry + nil, // 20: dapr.proto.runtime.v1.BindingEventRequest.MetadataEntry + nil, // 21: dapr.proto.runtime.v1.TopicSubscription.MetadataEntry + (*structpb.Struct)(nil), // 22: google.protobuf.Struct + (*v1.StateItem)(nil), // 23: dapr.proto.common.v1.StateItem + (*v1.InvokeRequest)(nil), // 24: dapr.proto.common.v1.InvokeRequest + (*emptypb.Empty)(nil), // 25: google.protobuf.Empty + (*v1.InvokeResponse)(nil), // 26: dapr.proto.common.v1.InvokeResponse +} +var file_dapr_proto_runtime_v1_appcallback_proto_depIdxs = []int32{ + 22, // 0: dapr.proto.runtime.v1.TopicEventRequest.extensions:type_name -> google.protobuf.Struct + 0, // 1: dapr.proto.runtime.v1.TopicEventResponse.status:type_name -> dapr.proto.runtime.v1.TopicEventResponse.TopicEventResponseStatus + 22, // 2: dapr.proto.runtime.v1.TopicEventCERequest.extensions:type_name -> google.protobuf.Struct + 4, // 3: dapr.proto.runtime.v1.TopicEventBulkRequestEntry.cloud_event:type_name -> dapr.proto.runtime.v1.TopicEventCERequest + 18, // 4: dapr.proto.runtime.v1.TopicEventBulkRequestEntry.metadata:type_name -> dapr.proto.runtime.v1.TopicEventBulkRequestEntry.MetadataEntry + 5, // 5: dapr.proto.runtime.v1.TopicEventBulkRequest.entries:type_name -> dapr.proto.runtime.v1.TopicEventBulkRequestEntry + 19, // 6: dapr.proto.runtime.v1.TopicEventBulkRequest.metadata:type_name -> dapr.proto.runtime.v1.TopicEventBulkRequest.MetadataEntry + 0, // 7: dapr.proto.runtime.v1.TopicEventBulkResponseEntry.status:type_name -> dapr.proto.runtime.v1.TopicEventResponse.TopicEventResponseStatus + 7, // 8: dapr.proto.runtime.v1.TopicEventBulkResponse.statuses:type_name -> dapr.proto.runtime.v1.TopicEventBulkResponseEntry + 20, // 9: dapr.proto.runtime.v1.BindingEventRequest.metadata:type_name -> dapr.proto.runtime.v1.BindingEventRequest.MetadataEntry + 23, // 10: dapr.proto.runtime.v1.BindingEventResponse.states:type_name -> dapr.proto.common.v1.StateItem + 1, // 11: dapr.proto.runtime.v1.BindingEventResponse.concurrency:type_name -> dapr.proto.runtime.v1.BindingEventResponse.BindingEventConcurrency + 12, // 12: dapr.proto.runtime.v1.ListTopicSubscriptionsResponse.subscriptions:type_name -> dapr.proto.runtime.v1.TopicSubscription + 21, // 13: dapr.proto.runtime.v1.TopicSubscription.metadata:type_name -> dapr.proto.runtime.v1.TopicSubscription.MetadataEntry + 13, // 14: dapr.proto.runtime.v1.TopicSubscription.routes:type_name -> dapr.proto.runtime.v1.TopicRoutes + 15, // 15: dapr.proto.runtime.v1.TopicSubscription.bulk_subscribe:type_name -> dapr.proto.runtime.v1.BulkSubscribeConfig + 14, // 16: dapr.proto.runtime.v1.TopicRoutes.rules:type_name -> dapr.proto.runtime.v1.TopicRule + 24, // 17: dapr.proto.runtime.v1.AppCallback.OnInvoke:input_type -> dapr.proto.common.v1.InvokeRequest + 25, // 18: dapr.proto.runtime.v1.AppCallback.ListTopicSubscriptions:input_type -> google.protobuf.Empty + 2, // 19: dapr.proto.runtime.v1.AppCallback.OnTopicEvent:input_type -> dapr.proto.runtime.v1.TopicEventRequest + 25, // 20: dapr.proto.runtime.v1.AppCallback.ListInputBindings:input_type -> google.protobuf.Empty + 9, // 21: dapr.proto.runtime.v1.AppCallback.OnBindingEvent:input_type -> dapr.proto.runtime.v1.BindingEventRequest + 25, // 22: dapr.proto.runtime.v1.AppCallbackHealthCheck.HealthCheck:input_type -> google.protobuf.Empty + 6, // 23: dapr.proto.runtime.v1.AppCallbackAlpha.OnBulkTopicEventAlpha1:input_type -> dapr.proto.runtime.v1.TopicEventBulkRequest + 26, // 24: dapr.proto.runtime.v1.AppCallback.OnInvoke:output_type -> dapr.proto.common.v1.InvokeResponse + 11, // 25: dapr.proto.runtime.v1.AppCallback.ListTopicSubscriptions:output_type -> dapr.proto.runtime.v1.ListTopicSubscriptionsResponse + 3, // 26: dapr.proto.runtime.v1.AppCallback.OnTopicEvent:output_type -> dapr.proto.runtime.v1.TopicEventResponse + 16, // 27: dapr.proto.runtime.v1.AppCallback.ListInputBindings:output_type -> dapr.proto.runtime.v1.ListInputBindingsResponse + 10, // 28: dapr.proto.runtime.v1.AppCallback.OnBindingEvent:output_type -> dapr.proto.runtime.v1.BindingEventResponse + 17, // 29: dapr.proto.runtime.v1.AppCallbackHealthCheck.HealthCheck:output_type -> dapr.proto.runtime.v1.HealthCheckResponse + 8, // 30: dapr.proto.runtime.v1.AppCallbackAlpha.OnBulkTopicEventAlpha1:output_type -> dapr.proto.runtime.v1.TopicEventBulkResponse + 24, // [24:31] is the sub-list for method output_type + 17, // [17:24] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name +} + +func init() { file_dapr_proto_runtime_v1_appcallback_proto_init() } +func file_dapr_proto_runtime_v1_appcallback_proto_init() { + if File_dapr_proto_runtime_v1_appcallback_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventCERequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventBulkRequestEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventBulkRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventBulkResponseEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEventBulkResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BindingEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BindingEventResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTopicSubscriptionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicSubscription); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicRoutes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkSubscribeConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInputBindingsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_dapr_proto_runtime_v1_appcallback_proto_msgTypes[3].OneofWrappers = []interface{}{ + (*TopicEventBulkRequestEntry_Bytes)(nil), + (*TopicEventBulkRequestEntry_CloudEvent)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dapr_proto_runtime_v1_appcallback_proto_rawDesc, + NumEnums: 2, + NumMessages: 20, + NumExtensions: 0, + NumServices: 3, + }, + GoTypes: file_dapr_proto_runtime_v1_appcallback_proto_goTypes, + DependencyIndexes: file_dapr_proto_runtime_v1_appcallback_proto_depIdxs, + EnumInfos: file_dapr_proto_runtime_v1_appcallback_proto_enumTypes, + MessageInfos: file_dapr_proto_runtime_v1_appcallback_proto_msgTypes, + }.Build() + File_dapr_proto_runtime_v1_appcallback_proto = out.File + file_dapr_proto_runtime_v1_appcallback_proto_rawDesc = nil + file_dapr_proto_runtime_v1_appcallback_proto_goTypes = nil + file_dapr_proto_runtime_v1_appcallback_proto_depIdxs = nil +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback_grpc.pb.go b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback_grpc.pb.go new file mode 100644 index 00000000000..5280e1ff11d --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/appcallback_grpc.pb.go @@ -0,0 +1,437 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: dapr/proto/runtime/v1/appcallback.proto + +package runtime + +import ( + context "context" + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AppCallbackClient is the client API for AppCallback service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AppCallbackClient interface { + // Invokes service method with InvokeRequest. + OnInvoke(ctx context.Context, in *v1.InvokeRequest, opts ...grpc.CallOption) (*v1.InvokeResponse, error) + // Lists all topics subscribed by this app. + ListTopicSubscriptions(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListTopicSubscriptionsResponse, error) + // Subscribes events from Pubsub + OnTopicEvent(ctx context.Context, in *TopicEventRequest, opts ...grpc.CallOption) (*TopicEventResponse, error) + // Lists all input bindings subscribed by this app. + ListInputBindings(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListInputBindingsResponse, error) + // Listens events from the input bindings + // + // User application can save the states or send the events to the output + // bindings optionally by returning BindingEventResponse. + OnBindingEvent(ctx context.Context, in *BindingEventRequest, opts ...grpc.CallOption) (*BindingEventResponse, error) +} + +type appCallbackClient struct { + cc grpc.ClientConnInterface +} + +func NewAppCallbackClient(cc grpc.ClientConnInterface) AppCallbackClient { + return &appCallbackClient{cc} +} + +func (c *appCallbackClient) OnInvoke(ctx context.Context, in *v1.InvokeRequest, opts ...grpc.CallOption) (*v1.InvokeResponse, error) { + out := new(v1.InvokeResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallback/OnInvoke", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appCallbackClient) ListTopicSubscriptions(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListTopicSubscriptionsResponse, error) { + out := new(ListTopicSubscriptionsResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallback/ListTopicSubscriptions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appCallbackClient) OnTopicEvent(ctx context.Context, in *TopicEventRequest, opts ...grpc.CallOption) (*TopicEventResponse, error) { + out := new(TopicEventResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallback/OnTopicEvent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appCallbackClient) ListInputBindings(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListInputBindingsResponse, error) { + out := new(ListInputBindingsResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallback/ListInputBindings", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appCallbackClient) OnBindingEvent(ctx context.Context, in *BindingEventRequest, opts ...grpc.CallOption) (*BindingEventResponse, error) { + out := new(BindingEventResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallback/OnBindingEvent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AppCallbackServer is the server API for AppCallback service. +// All implementations should embed UnimplementedAppCallbackServer +// for forward compatibility +type AppCallbackServer interface { + // Invokes service method with InvokeRequest. + OnInvoke(context.Context, *v1.InvokeRequest) (*v1.InvokeResponse, error) + // Lists all topics subscribed by this app. + ListTopicSubscriptions(context.Context, *emptypb.Empty) (*ListTopicSubscriptionsResponse, error) + // Subscribes events from Pubsub + OnTopicEvent(context.Context, *TopicEventRequest) (*TopicEventResponse, error) + // Lists all input bindings subscribed by this app. + ListInputBindings(context.Context, *emptypb.Empty) (*ListInputBindingsResponse, error) + // Listens events from the input bindings + // + // User application can save the states or send the events to the output + // bindings optionally by returning BindingEventResponse. + OnBindingEvent(context.Context, *BindingEventRequest) (*BindingEventResponse, error) +} + +// UnimplementedAppCallbackServer should be embedded to have forward compatible implementations. +type UnimplementedAppCallbackServer struct { +} + +func (UnimplementedAppCallbackServer) OnInvoke(context.Context, *v1.InvokeRequest) (*v1.InvokeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnInvoke not implemented") +} +func (UnimplementedAppCallbackServer) ListTopicSubscriptions(context.Context, *emptypb.Empty) (*ListTopicSubscriptionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListTopicSubscriptions not implemented") +} +func (UnimplementedAppCallbackServer) OnTopicEvent(context.Context, *TopicEventRequest) (*TopicEventResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnTopicEvent not implemented") +} +func (UnimplementedAppCallbackServer) ListInputBindings(context.Context, *emptypb.Empty) (*ListInputBindingsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListInputBindings not implemented") +} +func (UnimplementedAppCallbackServer) OnBindingEvent(context.Context, *BindingEventRequest) (*BindingEventResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnBindingEvent not implemented") +} + +// UnsafeAppCallbackServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AppCallbackServer will +// result in compilation errors. +type UnsafeAppCallbackServer interface { + mustEmbedUnimplementedAppCallbackServer() +} + +func RegisterAppCallbackServer(s grpc.ServiceRegistrar, srv AppCallbackServer) { + s.RegisterService(&AppCallback_ServiceDesc, srv) +} + +func _AppCallback_OnInvoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1.InvokeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackServer).OnInvoke(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallback/OnInvoke", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackServer).OnInvoke(ctx, req.(*v1.InvokeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AppCallback_ListTopicSubscriptions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackServer).ListTopicSubscriptions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallback/ListTopicSubscriptions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackServer).ListTopicSubscriptions(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AppCallback_OnTopicEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TopicEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackServer).OnTopicEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallback/OnTopicEvent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackServer).OnTopicEvent(ctx, req.(*TopicEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AppCallback_ListInputBindings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackServer).ListInputBindings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallback/ListInputBindings", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackServer).ListInputBindings(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AppCallback_OnBindingEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BindingEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackServer).OnBindingEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallback/OnBindingEvent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackServer).OnBindingEvent(ctx, req.(*BindingEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AppCallback_ServiceDesc is the grpc.ServiceDesc for AppCallback service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AppCallback_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dapr.proto.runtime.v1.AppCallback", + HandlerType: (*AppCallbackServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "OnInvoke", + Handler: _AppCallback_OnInvoke_Handler, + }, + { + MethodName: "ListTopicSubscriptions", + Handler: _AppCallback_ListTopicSubscriptions_Handler, + }, + { + MethodName: "OnTopicEvent", + Handler: _AppCallback_OnTopicEvent_Handler, + }, + { + MethodName: "ListInputBindings", + Handler: _AppCallback_ListInputBindings_Handler, + }, + { + MethodName: "OnBindingEvent", + Handler: _AppCallback_OnBindingEvent_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dapr/proto/runtime/v1/appcallback.proto", +} + +// AppCallbackHealthCheckClient is the client API for AppCallbackHealthCheck service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AppCallbackHealthCheckClient interface { + // Health check. + HealthCheck(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HealthCheckResponse, error) +} + +type appCallbackHealthCheckClient struct { + cc grpc.ClientConnInterface +} + +func NewAppCallbackHealthCheckClient(cc grpc.ClientConnInterface) AppCallbackHealthCheckClient { + return &appCallbackHealthCheckClient{cc} +} + +func (c *appCallbackHealthCheckClient) HealthCheck(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + out := new(HealthCheckResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallbackHealthCheck/HealthCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AppCallbackHealthCheckServer is the server API for AppCallbackHealthCheck service. +// All implementations should embed UnimplementedAppCallbackHealthCheckServer +// for forward compatibility +type AppCallbackHealthCheckServer interface { + // Health check. + HealthCheck(context.Context, *emptypb.Empty) (*HealthCheckResponse, error) +} + +// UnimplementedAppCallbackHealthCheckServer should be embedded to have forward compatible implementations. +type UnimplementedAppCallbackHealthCheckServer struct { +} + +func (UnimplementedAppCallbackHealthCheckServer) HealthCheck(context.Context, *emptypb.Empty) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method HealthCheck not implemented") +} + +// UnsafeAppCallbackHealthCheckServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AppCallbackHealthCheckServer will +// result in compilation errors. +type UnsafeAppCallbackHealthCheckServer interface { + mustEmbedUnimplementedAppCallbackHealthCheckServer() +} + +func RegisterAppCallbackHealthCheckServer(s grpc.ServiceRegistrar, srv AppCallbackHealthCheckServer) { + s.RegisterService(&AppCallbackHealthCheck_ServiceDesc, srv) +} + +func _AppCallbackHealthCheck_HealthCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackHealthCheckServer).HealthCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallbackHealthCheck/HealthCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackHealthCheckServer).HealthCheck(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +// AppCallbackHealthCheck_ServiceDesc is the grpc.ServiceDesc for AppCallbackHealthCheck service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AppCallbackHealthCheck_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dapr.proto.runtime.v1.AppCallbackHealthCheck", + HandlerType: (*AppCallbackHealthCheckServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "HealthCheck", + Handler: _AppCallbackHealthCheck_HealthCheck_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dapr/proto/runtime/v1/appcallback.proto", +} + +// AppCallbackAlphaClient is the client API for AppCallbackAlpha service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AppCallbackAlphaClient interface { + // Subscribes bulk events from Pubsub + OnBulkTopicEventAlpha1(ctx context.Context, in *TopicEventBulkRequest, opts ...grpc.CallOption) (*TopicEventBulkResponse, error) +} + +type appCallbackAlphaClient struct { + cc grpc.ClientConnInterface +} + +func NewAppCallbackAlphaClient(cc grpc.ClientConnInterface) AppCallbackAlphaClient { + return &appCallbackAlphaClient{cc} +} + +func (c *appCallbackAlphaClient) OnBulkTopicEventAlpha1(ctx context.Context, in *TopicEventBulkRequest, opts ...grpc.CallOption) (*TopicEventBulkResponse, error) { + out := new(TopicEventBulkResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallbackAlpha/OnBulkTopicEventAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AppCallbackAlphaServer is the server API for AppCallbackAlpha service. +// All implementations should embed UnimplementedAppCallbackAlphaServer +// for forward compatibility +type AppCallbackAlphaServer interface { + // Subscribes bulk events from Pubsub + OnBulkTopicEventAlpha1(context.Context, *TopicEventBulkRequest) (*TopicEventBulkResponse, error) +} + +// UnimplementedAppCallbackAlphaServer should be embedded to have forward compatible implementations. +type UnimplementedAppCallbackAlphaServer struct { +} + +func (UnimplementedAppCallbackAlphaServer) OnBulkTopicEventAlpha1(context.Context, *TopicEventBulkRequest) (*TopicEventBulkResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnBulkTopicEventAlpha1 not implemented") +} + +// UnsafeAppCallbackAlphaServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AppCallbackAlphaServer will +// result in compilation errors. +type UnsafeAppCallbackAlphaServer interface { + mustEmbedUnimplementedAppCallbackAlphaServer() +} + +func RegisterAppCallbackAlphaServer(s grpc.ServiceRegistrar, srv AppCallbackAlphaServer) { + s.RegisterService(&AppCallbackAlpha_ServiceDesc, srv) +} + +func _AppCallbackAlpha_OnBulkTopicEventAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TopicEventBulkRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppCallbackAlphaServer).OnBulkTopicEventAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.AppCallbackAlpha/OnBulkTopicEventAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppCallbackAlphaServer).OnBulkTopicEventAlpha1(ctx, req.(*TopicEventBulkRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AppCallbackAlpha_ServiceDesc is the grpc.ServiceDesc for AppCallbackAlpha service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AppCallbackAlpha_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dapr.proto.runtime.v1.AppCallbackAlpha", + HandlerType: (*AppCallbackAlphaServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "OnBulkTopicEventAlpha1", + Handler: _AppCallbackAlpha_OnBulkTopicEventAlpha1_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dapr/proto/runtime/v1/appcallback.proto", +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr.pb.go b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr.pb.go new file mode 100644 index 00000000000..368d28ab0d1 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr.pb.go @@ -0,0 +1,8260 @@ +// +//Copyright 2021 The Dapr Authors +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +//http://www.apache.org/licenses/LICENSE-2.0 +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: dapr/proto/runtime/v1/dapr.proto + +package runtime + +import ( + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type UnlockResponse_Status int32 + +const ( + UnlockResponse_SUCCESS UnlockResponse_Status = 0 + UnlockResponse_LOCK_DOES_NOT_EXIST UnlockResponse_Status = 1 + UnlockResponse_LOCK_BELONGS_TO_OTHERS UnlockResponse_Status = 2 + UnlockResponse_INTERNAL_ERROR UnlockResponse_Status = 3 +) + +// Enum value maps for UnlockResponse_Status. +var ( + UnlockResponse_Status_name = map[int32]string{ + 0: "SUCCESS", + 1: "LOCK_DOES_NOT_EXIST", + 2: "LOCK_BELONGS_TO_OTHERS", + 3: "INTERNAL_ERROR", + } + UnlockResponse_Status_value = map[string]int32{ + "SUCCESS": 0, + "LOCK_DOES_NOT_EXIST": 1, + "LOCK_BELONGS_TO_OTHERS": 2, + "INTERNAL_ERROR": 3, + } +) + +func (x UnlockResponse_Status) Enum() *UnlockResponse_Status { + p := new(UnlockResponse_Status) + *p = x + return p +} + +func (x UnlockResponse_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UnlockResponse_Status) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_runtime_v1_dapr_proto_enumTypes[0].Descriptor() +} + +func (UnlockResponse_Status) Type() protoreflect.EnumType { + return &file_dapr_proto_runtime_v1_dapr_proto_enumTypes[0] +} + +func (x UnlockResponse_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UnlockResponse_Status.Descriptor instead. +func (UnlockResponse_Status) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{54, 0} +} + +type SubtleGetKeyRequest_KeyFormat int32 + +const ( + // PEM (PKIX) (default) + SubtleGetKeyRequest_PEM SubtleGetKeyRequest_KeyFormat = 0 + // JSON (JSON Web Key) as string + SubtleGetKeyRequest_JSON SubtleGetKeyRequest_KeyFormat = 1 +) + +// Enum value maps for SubtleGetKeyRequest_KeyFormat. +var ( + SubtleGetKeyRequest_KeyFormat_name = map[int32]string{ + 0: "PEM", + 1: "JSON", + } + SubtleGetKeyRequest_KeyFormat_value = map[string]int32{ + "PEM": 0, + "JSON": 1, + } +) + +func (x SubtleGetKeyRequest_KeyFormat) Enum() *SubtleGetKeyRequest_KeyFormat { + p := new(SubtleGetKeyRequest_KeyFormat) + *p = x + return p +} + +func (x SubtleGetKeyRequest_KeyFormat) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SubtleGetKeyRequest_KeyFormat) Descriptor() protoreflect.EnumDescriptor { + return file_dapr_proto_runtime_v1_dapr_proto_enumTypes[1].Descriptor() +} + +func (SubtleGetKeyRequest_KeyFormat) Type() protoreflect.EnumType { + return &file_dapr_proto_runtime_v1_dapr_proto_enumTypes[1] +} + +func (x SubtleGetKeyRequest_KeyFormat) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SubtleGetKeyRequest_KeyFormat.Descriptor instead. +func (SubtleGetKeyRequest_KeyFormat) EnumDescriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{55, 0} +} + +// InvokeServiceRequest represents the request message for Service invocation. +type InvokeServiceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. Callee's app id. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Required. message which will be delivered to callee. + Message *v1.InvokeRequest `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *InvokeServiceRequest) Reset() { + *x = InvokeServiceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeServiceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeServiceRequest) ProtoMessage() {} + +func (x *InvokeServiceRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeServiceRequest.ProtoReflect.Descriptor instead. +func (*InvokeServiceRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{0} +} + +func (x *InvokeServiceRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *InvokeServiceRequest) GetMessage() *v1.InvokeRequest { + if x != nil { + return x.Message + } + return nil +} + +// GetStateRequest is the message to get key-value states from specific state store. +type GetStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The key of the desired state + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // The read consistency of the state store. + Consistency v1.StateOptions_StateConsistency `protobuf:"varint,3,opt,name=consistency,proto3,enum=dapr.proto.common.v1.StateOptions_StateConsistency" json:"consistency,omitempty"` + // The metadata which will be sent to state store components. + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetStateRequest) Reset() { + *x = GetStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStateRequest) ProtoMessage() {} + +func (x *GetStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStateRequest.ProtoReflect.Descriptor instead. +func (*GetStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{1} +} + +func (x *GetStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *GetStateRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GetStateRequest) GetConsistency() v1.StateOptions_StateConsistency { + if x != nil { + return x.Consistency + } + return v1.StateOptions_StateConsistency(0) +} + +func (x *GetStateRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetBulkStateRequest is the message to get a list of key-value states from specific state store. +type GetBulkStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The keys to get. + Keys []string `protobuf:"bytes,2,rep,name=keys,proto3" json:"keys,omitempty"` + // The number of parallel operations executed on the state store for a get operation. + Parallelism int32 `protobuf:"varint,3,opt,name=parallelism,proto3" json:"parallelism,omitempty"` + // The metadata which will be sent to state store components. + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetBulkStateRequest) Reset() { + *x = GetBulkStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBulkStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBulkStateRequest) ProtoMessage() {} + +func (x *GetBulkStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBulkStateRequest.ProtoReflect.Descriptor instead. +func (*GetBulkStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{2} +} + +func (x *GetBulkStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *GetBulkStateRequest) GetKeys() []string { + if x != nil { + return x.Keys + } + return nil +} + +func (x *GetBulkStateRequest) GetParallelism() int32 { + if x != nil { + return x.Parallelism + } + return 0 +} + +func (x *GetBulkStateRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetBulkStateResponse is the response conveying the list of state values. +type GetBulkStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of items containing the keys to get values for. + Items []*BulkStateItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *GetBulkStateResponse) Reset() { + *x = GetBulkStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBulkStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBulkStateResponse) ProtoMessage() {} + +func (x *GetBulkStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBulkStateResponse.ProtoReflect.Descriptor instead. +func (*GetBulkStateResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{3} +} + +func (x *GetBulkStateResponse) GetItems() []*BulkStateItem { + if x != nil { + return x.Items + } + return nil +} + +// BulkStateItem is the response item for a bulk get operation. +// Return values include the item key, data and etag. +type BulkStateItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // state item key + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The byte array data + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // The entity tag which represents the specific version of data. + // ETag format is defined by the corresponding data store. + Etag string `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + // The error that was returned from the state store in case of a failed get operation. + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` + // The metadata which will be sent to app. + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *BulkStateItem) Reset() { + *x = BulkStateItem{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkStateItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkStateItem) ProtoMessage() {} + +func (x *BulkStateItem) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkStateItem.ProtoReflect.Descriptor instead. +func (*BulkStateItem) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{4} +} + +func (x *BulkStateItem) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *BulkStateItem) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *BulkStateItem) GetEtag() string { + if x != nil { + return x.Etag + } + return "" +} + +func (x *BulkStateItem) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *BulkStateItem) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetStateResponse is the response conveying the state value and etag. +type GetStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The byte array data + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + // The entity tag which represents the specific version of data. + // ETag format is defined by the corresponding data store. + Etag string `protobuf:"bytes,2,opt,name=etag,proto3" json:"etag,omitempty"` + // The metadata which will be sent to app. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetStateResponse) Reset() { + *x = GetStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStateResponse) ProtoMessage() {} + +func (x *GetStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStateResponse.ProtoReflect.Descriptor instead. +func (*GetStateResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{5} +} + +func (x *GetStateResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *GetStateResponse) GetEtag() string { + if x != nil { + return x.Etag + } + return "" +} + +func (x *GetStateResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// DeleteStateRequest is the message to delete key-value states in the specific state store. +type DeleteStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The key of the desired state + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // The entity tag which represents the specific version of data. + // The exact ETag format is defined by the corresponding data store. + Etag *v1.Etag `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + // State operation options which includes concurrency/ + // consistency/retry_policy. + Options *v1.StateOptions `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` + // The metadata which will be sent to state store components. + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *DeleteStateRequest) Reset() { + *x = DeleteStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteStateRequest) ProtoMessage() {} + +func (x *DeleteStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteStateRequest.ProtoReflect.Descriptor instead. +func (*DeleteStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{6} +} + +func (x *DeleteStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *DeleteStateRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *DeleteStateRequest) GetEtag() *v1.Etag { + if x != nil { + return x.Etag + } + return nil +} + +func (x *DeleteStateRequest) GetOptions() *v1.StateOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *DeleteStateRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// DeleteBulkStateRequest is the message to delete a list of key-value states from specific state store. +type DeleteBulkStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The array of the state key values. + States []*v1.StateItem `protobuf:"bytes,2,rep,name=states,proto3" json:"states,omitempty"` +} + +func (x *DeleteBulkStateRequest) Reset() { + *x = DeleteBulkStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteBulkStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteBulkStateRequest) ProtoMessage() {} + +func (x *DeleteBulkStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteBulkStateRequest.ProtoReflect.Descriptor instead. +func (*DeleteBulkStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{7} +} + +func (x *DeleteBulkStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *DeleteBulkStateRequest) GetStates() []*v1.StateItem { + if x != nil { + return x.States + } + return nil +} + +// SaveStateRequest is the message to save multiple states into state store. +type SaveStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The array of the state key values. + States []*v1.StateItem `protobuf:"bytes,2,rep,name=states,proto3" json:"states,omitempty"` +} + +func (x *SaveStateRequest) Reset() { + *x = SaveStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SaveStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SaveStateRequest) ProtoMessage() {} + +func (x *SaveStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SaveStateRequest.ProtoReflect.Descriptor instead. +func (*SaveStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{8} +} + +func (x *SaveStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *SaveStateRequest) GetStates() []*v1.StateItem { + if x != nil { + return x.States + } + return nil +} + +// QueryStateRequest is the message to query state store. +type QueryStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of state store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The query in JSON format. + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + // The metadata which will be sent to state store components. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *QueryStateRequest) Reset() { + *x = QueryStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryStateRequest) ProtoMessage() {} + +func (x *QueryStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryStateRequest.ProtoReflect.Descriptor instead. +func (*QueryStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{9} +} + +func (x *QueryStateRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *QueryStateRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *QueryStateRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type QueryStateItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The object key. + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The object value. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // The entity tag which represents the specific version of data. + // ETag format is defined by the corresponding data store. + Etag string `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + // The error message indicating an error in processing of the query result. + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *QueryStateItem) Reset() { + *x = QueryStateItem{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryStateItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryStateItem) ProtoMessage() {} + +func (x *QueryStateItem) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryStateItem.ProtoReflect.Descriptor instead. +func (*QueryStateItem) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{10} +} + +func (x *QueryStateItem) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *QueryStateItem) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *QueryStateItem) GetEtag() string { + if x != nil { + return x.Etag + } + return "" +} + +func (x *QueryStateItem) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +// QueryStateResponse is the response conveying the query results. +type QueryStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // An array of query results. + Results []*QueryStateItem `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` + // Pagination token. + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + // The metadata which will be sent to app. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *QueryStateResponse) Reset() { + *x = QueryStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryStateResponse) ProtoMessage() {} + +func (x *QueryStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryStateResponse.ProtoReflect.Descriptor instead. +func (*QueryStateResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{11} +} + +func (x *QueryStateResponse) GetResults() []*QueryStateItem { + if x != nil { + return x.Results + } + return nil +} + +func (x *QueryStateResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *QueryStateResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// PublishEventRequest is the message to publish event data to pubsub topic +type PublishEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the pubsub component + PubsubName string `protobuf:"bytes,1,opt,name=pubsub_name,json=pubsubName,proto3" json:"pubsub_name,omitempty"` + // The pubsub topic + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + // The data which will be published to topic. + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + // The content type for the data (optional). + DataContentType string `protobuf:"bytes,4,opt,name=data_content_type,json=dataContentType,proto3" json:"data_content_type,omitempty"` + // The metadata passing to pub components + // + // metadata property: + // - key : the key of the message. + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PublishEventRequest) Reset() { + *x = PublishEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishEventRequest) ProtoMessage() {} + +func (x *PublishEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishEventRequest.ProtoReflect.Descriptor instead. +func (*PublishEventRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{12} +} + +func (x *PublishEventRequest) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *PublishEventRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *PublishEventRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *PublishEventRequest) GetDataContentType() string { + if x != nil { + return x.DataContentType + } + return "" +} + +func (x *PublishEventRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// BulkPublishRequest is the message to bulk publish events to pubsub topic +type BulkPublishRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the pubsub component + PubsubName string `protobuf:"bytes,1,opt,name=pubsub_name,json=pubsubName,proto3" json:"pubsub_name,omitempty"` + // The pubsub topic + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + // The entries which contain the individual events and associated details to be published + Entries []*BulkPublishRequestEntry `protobuf:"bytes,3,rep,name=entries,proto3" json:"entries,omitempty"` + // The request level metadata passing to to the pubsub components + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *BulkPublishRequest) Reset() { + *x = BulkPublishRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkPublishRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkPublishRequest) ProtoMessage() {} + +func (x *BulkPublishRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkPublishRequest.ProtoReflect.Descriptor instead. +func (*BulkPublishRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{13} +} + +func (x *BulkPublishRequest) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *BulkPublishRequest) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *BulkPublishRequest) GetEntries() []*BulkPublishRequestEntry { + if x != nil { + return x.Entries + } + return nil +} + +func (x *BulkPublishRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// BulkPublishRequestEntry is the message containing the event to be bulk published +type BulkPublishRequestEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The request scoped unique ID referring to this message. Used to map status in response + EntryId string `protobuf:"bytes,1,opt,name=entry_id,json=entryId,proto3" json:"entry_id,omitempty"` + // The event which will be pulished to the topic + Event []byte `protobuf:"bytes,2,opt,name=event,proto3" json:"event,omitempty"` + // The content type for the event + ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // The event level metadata passing to the pubsub component + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *BulkPublishRequestEntry) Reset() { + *x = BulkPublishRequestEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkPublishRequestEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkPublishRequestEntry) ProtoMessage() {} + +func (x *BulkPublishRequestEntry) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkPublishRequestEntry.ProtoReflect.Descriptor instead. +func (*BulkPublishRequestEntry) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{14} +} + +func (x *BulkPublishRequestEntry) GetEntryId() string { + if x != nil { + return x.EntryId + } + return "" +} + +func (x *BulkPublishRequestEntry) GetEvent() []byte { + if x != nil { + return x.Event + } + return nil +} + +func (x *BulkPublishRequestEntry) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +func (x *BulkPublishRequestEntry) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// BulkPublishResponse is the message returned from a BulkPublishEvent call +type BulkPublishResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The entries for different events that failed publish in the BulkPublishEvent call + FailedEntries []*BulkPublishResponseFailedEntry `protobuf:"bytes,1,rep,name=failedEntries,proto3" json:"failedEntries,omitempty"` +} + +func (x *BulkPublishResponse) Reset() { + *x = BulkPublishResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkPublishResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkPublishResponse) ProtoMessage() {} + +func (x *BulkPublishResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkPublishResponse.ProtoReflect.Descriptor instead. +func (*BulkPublishResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{15} +} + +func (x *BulkPublishResponse) GetFailedEntries() []*BulkPublishResponseFailedEntry { + if x != nil { + return x.FailedEntries + } + return nil +} + +// BulkPublishResponseFailedEntry is the message containing the entryID and error of a failed event in BulkPublishEvent call +type BulkPublishResponseFailedEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The response scoped unique ID referring to this message + EntryId string `protobuf:"bytes,1,opt,name=entry_id,json=entryId,proto3" json:"entry_id,omitempty"` + // The error message if any on failure + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *BulkPublishResponseFailedEntry) Reset() { + *x = BulkPublishResponseFailedEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BulkPublishResponseFailedEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BulkPublishResponseFailedEntry) ProtoMessage() {} + +func (x *BulkPublishResponseFailedEntry) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BulkPublishResponseFailedEntry.ProtoReflect.Descriptor instead. +func (*BulkPublishResponseFailedEntry) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{16} +} + +func (x *BulkPublishResponseFailedEntry) GetEntryId() string { + if x != nil { + return x.EntryId + } + return "" +} + +func (x *BulkPublishResponseFailedEntry) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +// InvokeBindingRequest is the message to send data to output bindings +type InvokeBindingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the output binding to invoke. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The data which will be sent to output binding. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // The metadata passing to output binding components + // + // Common metadata property: + // - ttlInSeconds : the time to live in seconds for the message. + // If set in the binding definition will cause all messages to + // have a default time to live. The message ttl overrides any value + // in the binding definition. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The name of the operation type for the binding to invoke + Operation string `protobuf:"bytes,4,opt,name=operation,proto3" json:"operation,omitempty"` +} + +func (x *InvokeBindingRequest) Reset() { + *x = InvokeBindingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeBindingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeBindingRequest) ProtoMessage() {} + +func (x *InvokeBindingRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeBindingRequest.ProtoReflect.Descriptor instead. +func (*InvokeBindingRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{17} +} + +func (x *InvokeBindingRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *InvokeBindingRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *InvokeBindingRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *InvokeBindingRequest) GetOperation() string { + if x != nil { + return x.Operation + } + return "" +} + +// InvokeBindingResponse is the message returned from an output binding invocation +type InvokeBindingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The data which will be sent to output binding. + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + // The metadata returned from an external system + Metadata map[string]string `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *InvokeBindingResponse) Reset() { + *x = InvokeBindingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeBindingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeBindingResponse) ProtoMessage() {} + +func (x *InvokeBindingResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeBindingResponse.ProtoReflect.Descriptor instead. +func (*InvokeBindingResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{18} +} + +func (x *InvokeBindingResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *InvokeBindingResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetSecretRequest is the message to get secret from secret store. +type GetSecretRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of secret store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The name of secret key. + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // The metadata which will be sent to secret store components. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetSecretRequest) Reset() { + *x = GetSecretRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSecretRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSecretRequest) ProtoMessage() {} + +func (x *GetSecretRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSecretRequest.ProtoReflect.Descriptor instead. +func (*GetSecretRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{19} +} + +func (x *GetSecretRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *GetSecretRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GetSecretRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetSecretResponse is the response message to convey the requested secret. +type GetSecretResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // data is the secret value. Some secret store, such as kubernetes secret + // store, can save multiple secrets for single secret key. + Data map[string]string `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetSecretResponse) Reset() { + *x = GetSecretResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSecretResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSecretResponse) ProtoMessage() {} + +func (x *GetSecretResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSecretResponse.ProtoReflect.Descriptor instead. +func (*GetSecretResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{20} +} + +func (x *GetSecretResponse) GetData() map[string]string { + if x != nil { + return x.Data + } + return nil +} + +// GetBulkSecretRequest is the message to get the secrets from secret store. +type GetBulkSecretRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of secret store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The metadata which will be sent to secret store components. + Metadata map[string]string `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetBulkSecretRequest) Reset() { + *x = GetBulkSecretRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBulkSecretRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBulkSecretRequest) ProtoMessage() {} + +func (x *GetBulkSecretRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBulkSecretRequest.ProtoReflect.Descriptor instead. +func (*GetBulkSecretRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{21} +} + +func (x *GetBulkSecretRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *GetBulkSecretRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// SecretResponse is a map of decrypted string/string values +type SecretResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Secrets map[string]string `protobuf:"bytes,1,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SecretResponse) Reset() { + *x = SecretResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SecretResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretResponse) ProtoMessage() {} + +func (x *SecretResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretResponse.ProtoReflect.Descriptor instead. +func (*SecretResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{22} +} + +func (x *SecretResponse) GetSecrets() map[string]string { + if x != nil { + return x.Secrets + } + return nil +} + +// GetBulkSecretResponse is the response message to convey the requested secrets. +type GetBulkSecretResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // data hold the secret values. Some secret store, such as kubernetes secret + // store, can save multiple secrets for single secret key. + Data map[string]*SecretResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetBulkSecretResponse) Reset() { + *x = GetBulkSecretResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBulkSecretResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBulkSecretResponse) ProtoMessage() {} + +func (x *GetBulkSecretResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBulkSecretResponse.ProtoReflect.Descriptor instead. +func (*GetBulkSecretResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{23} +} + +func (x *GetBulkSecretResponse) GetData() map[string]*SecretResponse { + if x != nil { + return x.Data + } + return nil +} + +// TransactionalStateOperation is the message to execute a specified operation with a key-value pair. +type TransactionalStateOperation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type of operation to be executed + OperationType string `protobuf:"bytes,1,opt,name=operationType,proto3" json:"operationType,omitempty"` + // State values to be operated on + Request *v1.StateItem `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` +} + +func (x *TransactionalStateOperation) Reset() { + *x = TransactionalStateOperation{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransactionalStateOperation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransactionalStateOperation) ProtoMessage() {} + +func (x *TransactionalStateOperation) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransactionalStateOperation.ProtoReflect.Descriptor instead. +func (*TransactionalStateOperation) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{24} +} + +func (x *TransactionalStateOperation) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *TransactionalStateOperation) GetRequest() *v1.StateItem { + if x != nil { + return x.Request + } + return nil +} + +// ExecuteStateTransactionRequest is the message to execute multiple operations on a specified store. +type ExecuteStateTransactionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. name of state store. + StoreName string `protobuf:"bytes,1,opt,name=storeName,proto3" json:"storeName,omitempty"` + // Required. transactional operation list. + Operations []*TransactionalStateOperation `protobuf:"bytes,2,rep,name=operations,proto3" json:"operations,omitempty"` + // The metadata used for transactional operations. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ExecuteStateTransactionRequest) Reset() { + *x = ExecuteStateTransactionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteStateTransactionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteStateTransactionRequest) ProtoMessage() {} + +func (x *ExecuteStateTransactionRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteStateTransactionRequest.ProtoReflect.Descriptor instead. +func (*ExecuteStateTransactionRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{25} +} + +func (x *ExecuteStateTransactionRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *ExecuteStateTransactionRequest) GetOperations() []*TransactionalStateOperation { + if x != nil { + return x.Operations + } + return nil +} + +func (x *ExecuteStateTransactionRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// RegisterActorTimerRequest is the message to register a timer for an actor of a given type and id. +type RegisterActorTimerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + DueTime string `protobuf:"bytes,4,opt,name=due_time,json=dueTime,proto3" json:"due_time,omitempty"` + Period string `protobuf:"bytes,5,opt,name=period,proto3" json:"period,omitempty"` + Callback string `protobuf:"bytes,6,opt,name=callback,proto3" json:"callback,omitempty"` + Data []byte `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"` + Ttl string `protobuf:"bytes,8,opt,name=ttl,proto3" json:"ttl,omitempty"` +} + +func (x *RegisterActorTimerRequest) Reset() { + *x = RegisterActorTimerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterActorTimerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterActorTimerRequest) ProtoMessage() {} + +func (x *RegisterActorTimerRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterActorTimerRequest.ProtoReflect.Descriptor instead. +func (*RegisterActorTimerRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{26} +} + +func (x *RegisterActorTimerRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *RegisterActorTimerRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *RegisterActorTimerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RegisterActorTimerRequest) GetDueTime() string { + if x != nil { + return x.DueTime + } + return "" +} + +func (x *RegisterActorTimerRequest) GetPeriod() string { + if x != nil { + return x.Period + } + return "" +} + +func (x *RegisterActorTimerRequest) GetCallback() string { + if x != nil { + return x.Callback + } + return "" +} + +func (x *RegisterActorTimerRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *RegisterActorTimerRequest) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +// UnregisterActorTimerRequest is the message to unregister an actor timer +type UnregisterActorTimerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *UnregisterActorTimerRequest) Reset() { + *x = UnregisterActorTimerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnregisterActorTimerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnregisterActorTimerRequest) ProtoMessage() {} + +func (x *UnregisterActorTimerRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnregisterActorTimerRequest.ProtoReflect.Descriptor instead. +func (*UnregisterActorTimerRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{27} +} + +func (x *UnregisterActorTimerRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *UnregisterActorTimerRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *UnregisterActorTimerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// RegisterActorReminderRequest is the message to register a reminder for an actor of a given type and id. +type RegisterActorReminderRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + DueTime string `protobuf:"bytes,4,opt,name=due_time,json=dueTime,proto3" json:"due_time,omitempty"` + Period string `protobuf:"bytes,5,opt,name=period,proto3" json:"period,omitempty"` + Data []byte `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"` + Ttl string `protobuf:"bytes,7,opt,name=ttl,proto3" json:"ttl,omitempty"` +} + +func (x *RegisterActorReminderRequest) Reset() { + *x = RegisterActorReminderRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterActorReminderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterActorReminderRequest) ProtoMessage() {} + +func (x *RegisterActorReminderRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterActorReminderRequest.ProtoReflect.Descriptor instead. +func (*RegisterActorReminderRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{28} +} + +func (x *RegisterActorReminderRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *RegisterActorReminderRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *RegisterActorReminderRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RegisterActorReminderRequest) GetDueTime() string { + if x != nil { + return x.DueTime + } + return "" +} + +func (x *RegisterActorReminderRequest) GetPeriod() string { + if x != nil { + return x.Period + } + return "" +} + +func (x *RegisterActorReminderRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *RegisterActorReminderRequest) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +// UnregisterActorReminderRequest is the message to unregister an actor reminder. +type UnregisterActorReminderRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *UnregisterActorReminderRequest) Reset() { + *x = UnregisterActorReminderRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnregisterActorReminderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnregisterActorReminderRequest) ProtoMessage() {} + +func (x *UnregisterActorReminderRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnregisterActorReminderRequest.ProtoReflect.Descriptor instead. +func (*UnregisterActorReminderRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{29} +} + +func (x *UnregisterActorReminderRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *UnregisterActorReminderRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *UnregisterActorReminderRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// RenameActorReminderRequest is the message to rename an actor reminder. +type RenameActorReminderRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + OldName string `protobuf:"bytes,3,opt,name=old_name,json=oldName,proto3" json:"old_name,omitempty"` + NewName string `protobuf:"bytes,4,opt,name=new_name,json=newName,proto3" json:"new_name,omitempty"` +} + +func (x *RenameActorReminderRequest) Reset() { + *x = RenameActorReminderRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RenameActorReminderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenameActorReminderRequest) ProtoMessage() {} + +func (x *RenameActorReminderRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenameActorReminderRequest.ProtoReflect.Descriptor instead. +func (*RenameActorReminderRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{30} +} + +func (x *RenameActorReminderRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *RenameActorReminderRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *RenameActorReminderRequest) GetOldName() string { + if x != nil { + return x.OldName + } + return "" +} + +func (x *RenameActorReminderRequest) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +// GetActorStateRequest is the message to get key-value states from specific actor. +type GetActorStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *GetActorStateRequest) Reset() { + *x = GetActorStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetActorStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActorStateRequest) ProtoMessage() {} + +func (x *GetActorStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActorStateRequest.ProtoReflect.Descriptor instead. +func (*GetActorStateRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{31} +} + +func (x *GetActorStateRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *GetActorStateRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *GetActorStateRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +// GetActorStateResponse is the response conveying the actor's state value. +type GetActorStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *GetActorStateResponse) Reset() { + *x = GetActorStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetActorStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActorStateResponse) ProtoMessage() {} + +func (x *GetActorStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActorStateResponse.ProtoReflect.Descriptor instead. +func (*GetActorStateResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{32} +} + +func (x *GetActorStateResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +// ExecuteActorStateTransactionRequest is the message to execute multiple operations on a specified actor. +type ExecuteActorStateTransactionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Operations []*TransactionalActorStateOperation `protobuf:"bytes,3,rep,name=operations,proto3" json:"operations,omitempty"` +} + +func (x *ExecuteActorStateTransactionRequest) Reset() { + *x = ExecuteActorStateTransactionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteActorStateTransactionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteActorStateTransactionRequest) ProtoMessage() {} + +func (x *ExecuteActorStateTransactionRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteActorStateTransactionRequest.ProtoReflect.Descriptor instead. +func (*ExecuteActorStateTransactionRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{33} +} + +func (x *ExecuteActorStateTransactionRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *ExecuteActorStateTransactionRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *ExecuteActorStateTransactionRequest) GetOperations() []*TransactionalActorStateOperation { + if x != nil { + return x.Operations + } + return nil +} + +// TransactionalActorStateOperation is the message to execute a specified operation with a key-value pair. +type TransactionalActorStateOperation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OperationType string `protobuf:"bytes,1,opt,name=operationType,proto3" json:"operationType,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Value *anypb.Any `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + // The metadata used for transactional operations. + // + // Common metadata property: + // - ttlInSeconds : the time to live in seconds for the stored value. + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *TransactionalActorStateOperation) Reset() { + *x = TransactionalActorStateOperation{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransactionalActorStateOperation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransactionalActorStateOperation) ProtoMessage() {} + +func (x *TransactionalActorStateOperation) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransactionalActorStateOperation.ProtoReflect.Descriptor instead. +func (*TransactionalActorStateOperation) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{34} +} + +func (x *TransactionalActorStateOperation) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *TransactionalActorStateOperation) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *TransactionalActorStateOperation) GetValue() *anypb.Any { + if x != nil { + return x.Value + } + return nil +} + +func (x *TransactionalActorStateOperation) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// InvokeActorRequest is the message to call an actor. +type InvokeActorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ActorType string `protobuf:"bytes,1,opt,name=actor_type,json=actorType,proto3" json:"actor_type,omitempty"` + ActorId string `protobuf:"bytes,2,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *InvokeActorRequest) Reset() { + *x = InvokeActorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeActorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeActorRequest) ProtoMessage() {} + +func (x *InvokeActorRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeActorRequest.ProtoReflect.Descriptor instead. +func (*InvokeActorRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{35} +} + +func (x *InvokeActorRequest) GetActorType() string { + if x != nil { + return x.ActorType + } + return "" +} + +func (x *InvokeActorRequest) GetActorId() string { + if x != nil { + return x.ActorId + } + return "" +} + +func (x *InvokeActorRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *InvokeActorRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *InvokeActorRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// InvokeActorResponse is the method that returns an actor invocation response. +type InvokeActorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *InvokeActorResponse) Reset() { + *x = InvokeActorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvokeActorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvokeActorResponse) ProtoMessage() {} + +func (x *InvokeActorResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvokeActorResponse.ProtoReflect.Descriptor instead. +func (*InvokeActorResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{36} +} + +func (x *InvokeActorResponse) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +// GetMetadataResponse is a message that is returned on GetMetadata rpc call +type GetMetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ActiveActorsCount []*ActiveActorsCount `protobuf:"bytes,2,rep,name=active_actors_count,json=actors,proto3" json:"active_actors_count,omitempty"` + RegisteredComponents []*RegisteredComponents `protobuf:"bytes,3,rep,name=registered_components,json=components,proto3" json:"registered_components,omitempty"` + ExtendedMetadata map[string]string `protobuf:"bytes,4,rep,name=extended_metadata,json=extended,proto3" json:"extended_metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Subscriptions []*PubsubSubscription `protobuf:"bytes,5,rep,name=subscriptions,proto3" json:"subscriptions,omitempty"` + HttpEndpoints []*MetadataHTTPEndpoint `protobuf:"bytes,6,rep,name=http_endpoints,json=httpEndpoints,proto3" json:"http_endpoints,omitempty"` +} + +func (x *GetMetadataResponse) Reset() { + *x = GetMetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMetadataResponse) ProtoMessage() {} + +func (x *GetMetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMetadataResponse.ProtoReflect.Descriptor instead. +func (*GetMetadataResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{37} +} + +func (x *GetMetadataResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetMetadataResponse) GetActiveActorsCount() []*ActiveActorsCount { + if x != nil { + return x.ActiveActorsCount + } + return nil +} + +func (x *GetMetadataResponse) GetRegisteredComponents() []*RegisteredComponents { + if x != nil { + return x.RegisteredComponents + } + return nil +} + +func (x *GetMetadataResponse) GetExtendedMetadata() map[string]string { + if x != nil { + return x.ExtendedMetadata + } + return nil +} + +func (x *GetMetadataResponse) GetSubscriptions() []*PubsubSubscription { + if x != nil { + return x.Subscriptions + } + return nil +} + +func (x *GetMetadataResponse) GetHttpEndpoints() []*MetadataHTTPEndpoint { + if x != nil { + return x.HttpEndpoints + } + return nil +} + +type ActiveActorsCount struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Count int32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *ActiveActorsCount) Reset() { + *x = ActiveActorsCount{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActiveActorsCount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActiveActorsCount) ProtoMessage() {} + +func (x *ActiveActorsCount) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActiveActorsCount.ProtoReflect.Descriptor instead. +func (*ActiveActorsCount) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{38} +} + +func (x *ActiveActorsCount) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ActiveActorsCount) GetCount() int32 { + if x != nil { + return x.Count + } + return 0 +} + +type RegisteredComponents struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Capabilities []string `protobuf:"bytes,4,rep,name=capabilities,proto3" json:"capabilities,omitempty"` +} + +func (x *RegisteredComponents) Reset() { + *x = RegisteredComponents{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisteredComponents) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisteredComponents) ProtoMessage() {} + +func (x *RegisteredComponents) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisteredComponents.ProtoReflect.Descriptor instead. +func (*RegisteredComponents) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{39} +} + +func (x *RegisteredComponents) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RegisteredComponents) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *RegisteredComponents) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RegisteredComponents) GetCapabilities() []string { + if x != nil { + return x.Capabilities + } + return nil +} + +type MetadataHTTPEndpoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *MetadataHTTPEndpoint) Reset() { + *x = MetadataHTTPEndpoint{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataHTTPEndpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataHTTPEndpoint) ProtoMessage() {} + +func (x *MetadataHTTPEndpoint) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataHTTPEndpoint.ProtoReflect.Descriptor instead. +func (*MetadataHTTPEndpoint) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{40} +} + +func (x *MetadataHTTPEndpoint) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type PubsubSubscription struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PubsubName string `protobuf:"bytes,1,opt,name=pubsub_name,json=pubsubname,proto3" json:"pubsub_name,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Rules *PubsubSubscriptionRules `protobuf:"bytes,4,opt,name=rules,proto3" json:"rules,omitempty"` + DeadLetterTopic string `protobuf:"bytes,5,opt,name=dead_letter_topic,json=deadLetterTopic,proto3" json:"dead_letter_topic,omitempty"` +} + +func (x *PubsubSubscription) Reset() { + *x = PubsubSubscription{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PubsubSubscription) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PubsubSubscription) ProtoMessage() {} + +func (x *PubsubSubscription) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PubsubSubscription.ProtoReflect.Descriptor instead. +func (*PubsubSubscription) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{41} +} + +func (x *PubsubSubscription) GetPubsubName() string { + if x != nil { + return x.PubsubName + } + return "" +} + +func (x *PubsubSubscription) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *PubsubSubscription) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *PubsubSubscription) GetRules() *PubsubSubscriptionRules { + if x != nil { + return x.Rules + } + return nil +} + +func (x *PubsubSubscription) GetDeadLetterTopic() string { + if x != nil { + return x.DeadLetterTopic + } + return "" +} + +type PubsubSubscriptionRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rules []*PubsubSubscriptionRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *PubsubSubscriptionRules) Reset() { + *x = PubsubSubscriptionRules{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PubsubSubscriptionRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PubsubSubscriptionRules) ProtoMessage() {} + +func (x *PubsubSubscriptionRules) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PubsubSubscriptionRules.ProtoReflect.Descriptor instead. +func (*PubsubSubscriptionRules) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{42} +} + +func (x *PubsubSubscriptionRules) GetRules() []*PubsubSubscriptionRule { + if x != nil { + return x.Rules + } + return nil +} + +type PubsubSubscriptionRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Match string `protobuf:"bytes,1,opt,name=match,proto3" json:"match,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *PubsubSubscriptionRule) Reset() { + *x = PubsubSubscriptionRule{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PubsubSubscriptionRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PubsubSubscriptionRule) ProtoMessage() {} + +func (x *PubsubSubscriptionRule) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PubsubSubscriptionRule.ProtoReflect.Descriptor instead. +func (*PubsubSubscriptionRule) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{43} +} + +func (x *PubsubSubscriptionRule) GetMatch() string { + if x != nil { + return x.Match + } + return "" +} + +func (x *PubsubSubscriptionRule) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +type SetMetadataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *SetMetadataRequest) Reset() { + *x = SetMetadataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetMetadataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetMetadataRequest) ProtoMessage() {} + +func (x *SetMetadataRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetMetadataRequest.ProtoReflect.Descriptor instead. +func (*SetMetadataRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{44} +} + +func (x *SetMetadataRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *SetMetadataRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +// GetConfigurationRequest is the message to get a list of key-value configuration from specified configuration store. +type GetConfigurationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The name of configuration store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // Optional. The key of the configuration item to fetch. + // If set, only query for the specified configuration items. + // Empty list means fetch all. + Keys []string `protobuf:"bytes,2,rep,name=keys,proto3" json:"keys,omitempty"` + // Optional. The metadata which will be sent to configuration store components. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetConfigurationRequest) Reset() { + *x = GetConfigurationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetConfigurationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetConfigurationRequest) ProtoMessage() {} + +func (x *GetConfigurationRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetConfigurationRequest.ProtoReflect.Descriptor instead. +func (*GetConfigurationRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{45} +} + +func (x *GetConfigurationRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *GetConfigurationRequest) GetKeys() []string { + if x != nil { + return x.Keys + } + return nil +} + +func (x *GetConfigurationRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// GetConfigurationResponse is the response conveying the list of configuration values. +// It should be the FULL configuration of specified application which contains all of its configuration items. +type GetConfigurationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items map[string]*v1.ConfigurationItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetConfigurationResponse) Reset() { + *x = GetConfigurationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetConfigurationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetConfigurationResponse) ProtoMessage() {} + +func (x *GetConfigurationResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetConfigurationResponse.ProtoReflect.Descriptor instead. +func (*GetConfigurationResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{46} +} + +func (x *GetConfigurationResponse) GetItems() map[string]*v1.ConfigurationItem { + if x != nil { + return x.Items + } + return nil +} + +// SubscribeConfigurationRequest is the message to get a list of key-value configuration from specified configuration store. +type SubscribeConfigurationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of configuration store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // Optional. The key of the configuration item to fetch. + // If set, only query for the specified configuration items. + // Empty list means fetch all. + Keys []string `protobuf:"bytes,2,rep,name=keys,proto3" json:"keys,omitempty"` + // The metadata which will be sent to configuration store components. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SubscribeConfigurationRequest) Reset() { + *x = SubscribeConfigurationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubscribeConfigurationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeConfigurationRequest) ProtoMessage() {} + +func (x *SubscribeConfigurationRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeConfigurationRequest.ProtoReflect.Descriptor instead. +func (*SubscribeConfigurationRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{47} +} + +func (x *SubscribeConfigurationRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *SubscribeConfigurationRequest) GetKeys() []string { + if x != nil { + return x.Keys + } + return nil +} + +func (x *SubscribeConfigurationRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// UnSubscribeConfigurationRequest is the message to stop watching the key-value configuration. +type UnsubscribeConfigurationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of configuration store. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // The id to unsubscribe. + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *UnsubscribeConfigurationRequest) Reset() { + *x = UnsubscribeConfigurationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnsubscribeConfigurationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnsubscribeConfigurationRequest) ProtoMessage() {} + +func (x *UnsubscribeConfigurationRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnsubscribeConfigurationRequest.ProtoReflect.Descriptor instead. +func (*UnsubscribeConfigurationRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{48} +} + +func (x *UnsubscribeConfigurationRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *UnsubscribeConfigurationRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type SubscribeConfigurationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Subscribe id, used to stop subscription. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The list of items containing configuration values + Items map[string]*v1.ConfigurationItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SubscribeConfigurationResponse) Reset() { + *x = SubscribeConfigurationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubscribeConfigurationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeConfigurationResponse) ProtoMessage() {} + +func (x *SubscribeConfigurationResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeConfigurationResponse.ProtoReflect.Descriptor instead. +func (*SubscribeConfigurationResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{49} +} + +func (x *SubscribeConfigurationResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *SubscribeConfigurationResponse) GetItems() map[string]*v1.ConfigurationItem { + if x != nil { + return x.Items + } + return nil +} + +type UnsubscribeConfigurationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *UnsubscribeConfigurationResponse) Reset() { + *x = UnsubscribeConfigurationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnsubscribeConfigurationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnsubscribeConfigurationResponse) ProtoMessage() {} + +func (x *UnsubscribeConfigurationResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[50] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnsubscribeConfigurationResponse.ProtoReflect.Descriptor instead. +func (*UnsubscribeConfigurationResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{50} +} + +func (x *UnsubscribeConfigurationResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *UnsubscribeConfigurationResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type TryLockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The lock store name,e.g. `redis`. + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // Required. resource_id is the lock key. e.g. `order_id_111` + // It stands for "which resource I want to protect" + ResourceId string `protobuf:"bytes,2,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"` + // Required. lock_owner indicate the identifier of lock owner. + // You can generate a uuid as lock_owner.For example,in golang: + // + // req.LockOwner = uuid.New().String() + // + // This field is per request,not per process,so it is different for each request, + // which aims to prevent multi-thread in the same process trying the same lock concurrently. + // + // The reason why we don't make it automatically generated is: + // 1. If it is automatically generated,there must be a 'my_lock_owner_id' field in the response. + // This name is so weird that we think it is inappropriate to put it into the api spec + // 2. If we change the field 'my_lock_owner_id' in the response to 'lock_owner',which means the current lock owner of this lock, + // we find that in some lock services users can't get the current lock owner.Actually users don't need it at all. + // 3. When reentrant lock is needed,the existing lock_owner is required to identify client and check "whether this client can reenter this lock". + // So this field in the request shouldn't be removed. + LockOwner string `protobuf:"bytes,3,opt,name=lock_owner,json=lockOwner,proto3" json:"lock_owner,omitempty"` + // Required. The time before expiry.The time unit is second. + ExpiryInSeconds int32 `protobuf:"varint,4,opt,name=expiry_in_seconds,json=expiryInSeconds,proto3" json:"expiry_in_seconds,omitempty"` +} + +func (x *TryLockRequest) Reset() { + *x = TryLockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TryLockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TryLockRequest) ProtoMessage() {} + +func (x *TryLockRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[51] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TryLockRequest.ProtoReflect.Descriptor instead. +func (*TryLockRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{51} +} + +func (x *TryLockRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *TryLockRequest) GetResourceId() string { + if x != nil { + return x.ResourceId + } + return "" +} + +func (x *TryLockRequest) GetLockOwner() string { + if x != nil { + return x.LockOwner + } + return "" +} + +func (x *TryLockRequest) GetExpiryInSeconds() int32 { + if x != nil { + return x.ExpiryInSeconds + } + return 0 +} + +type TryLockResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *TryLockResponse) Reset() { + *x = TryLockResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TryLockResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TryLockResponse) ProtoMessage() {} + +func (x *TryLockResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TryLockResponse.ProtoReflect.Descriptor instead. +func (*TryLockResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{52} +} + +func (x *TryLockResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type UnlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StoreName string `protobuf:"bytes,1,opt,name=store_name,json=storeName,proto3" json:"store_name,omitempty"` + // resource_id is the lock key. + ResourceId string `protobuf:"bytes,2,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"` + LockOwner string `protobuf:"bytes,3,opt,name=lock_owner,json=lockOwner,proto3" json:"lock_owner,omitempty"` +} + +func (x *UnlockRequest) Reset() { + *x = UnlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnlockRequest) ProtoMessage() {} + +func (x *UnlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[53] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnlockRequest.ProtoReflect.Descriptor instead. +func (*UnlockRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{53} +} + +func (x *UnlockRequest) GetStoreName() string { + if x != nil { + return x.StoreName + } + return "" +} + +func (x *UnlockRequest) GetResourceId() string { + if x != nil { + return x.ResourceId + } + return "" +} + +func (x *UnlockRequest) GetLockOwner() string { + if x != nil { + return x.LockOwner + } + return "" +} + +type UnlockResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status UnlockResponse_Status `protobuf:"varint,1,opt,name=status,proto3,enum=dapr.proto.runtime.v1.UnlockResponse_Status" json:"status,omitempty"` +} + +func (x *UnlockResponse) Reset() { + *x = UnlockResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnlockResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnlockResponse) ProtoMessage() {} + +func (x *UnlockResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnlockResponse.ProtoReflect.Descriptor instead. +func (*UnlockResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{54} +} + +func (x *UnlockResponse) GetStatus() UnlockResponse_Status { + if x != nil { + return x.Status + } + return UnlockResponse_SUCCESS +} + +// SubtleGetKeyRequest is the request object for SubtleGetKeyAlpha1. +type SubtleGetKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Name (or name/version) of the key to use in the key vault + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Response format + Format SubtleGetKeyRequest_KeyFormat `protobuf:"varint,3,opt,name=format,proto3,enum=dapr.proto.runtime.v1.SubtleGetKeyRequest_KeyFormat" json:"format,omitempty"` +} + +func (x *SubtleGetKeyRequest) Reset() { + *x = SubtleGetKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleGetKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleGetKeyRequest) ProtoMessage() {} + +func (x *SubtleGetKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[55] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleGetKeyRequest.ProtoReflect.Descriptor instead. +func (*SubtleGetKeyRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{55} +} + +func (x *SubtleGetKeyRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleGetKeyRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SubtleGetKeyRequest) GetFormat() SubtleGetKeyRequest_KeyFormat { + if x != nil { + return x.Format + } + return SubtleGetKeyRequest_PEM +} + +// SubtleGetKeyResponse is the response for SubtleGetKeyAlpha1. +type SubtleGetKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name (or name/version) of the key. + // This is returned as response too in case there is a version. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Public key, encoded in the requested format + PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (x *SubtleGetKeyResponse) Reset() { + *x = SubtleGetKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleGetKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleGetKeyResponse) ProtoMessage() {} + +func (x *SubtleGetKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[56] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleGetKeyResponse.ProtoReflect.Descriptor instead. +func (*SubtleGetKeyResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{56} +} + +func (x *SubtleGetKeyResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SubtleGetKeyResponse) GetPublicKey() string { + if x != nil { + return x.PublicKey + } + return "" +} + +// SubtleEncryptRequest is the request for SubtleEncryptAlpha1. +type SubtleEncryptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Message to encrypt. + Plaintext []byte `protobuf:"bytes,2,opt,name=plaintext,proto3" json:"plaintext,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Nonce / initialization vector. + // Ignored with asymmetric ciphers. + Nonce []byte `protobuf:"bytes,5,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Associated Data when using AEAD ciphers (optional). + AssociatedData []byte `protobuf:"bytes,6,opt,name=associated_data,json=associatedData,proto3" json:"associated_data,omitempty"` +} + +func (x *SubtleEncryptRequest) Reset() { + *x = SubtleEncryptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleEncryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleEncryptRequest) ProtoMessage() {} + +func (x *SubtleEncryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[57] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleEncryptRequest.ProtoReflect.Descriptor instead. +func (*SubtleEncryptRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{57} +} + +func (x *SubtleEncryptRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleEncryptRequest) GetPlaintext() []byte { + if x != nil { + return x.Plaintext + } + return nil +} + +func (x *SubtleEncryptRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleEncryptRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *SubtleEncryptRequest) GetNonce() []byte { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *SubtleEncryptRequest) GetAssociatedData() []byte { + if x != nil { + return x.AssociatedData + } + return nil +} + +// SubtleEncryptResponse is the response for SubtleEncryptAlpha1. +type SubtleEncryptResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Encrypted ciphertext. + Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // Authentication tag. + // This is nil when not using an authenticated cipher. + Tag []byte `protobuf:"bytes,2,opt,name=tag,proto3" json:"tag,omitempty"` +} + +func (x *SubtleEncryptResponse) Reset() { + *x = SubtleEncryptResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleEncryptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleEncryptResponse) ProtoMessage() {} + +func (x *SubtleEncryptResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[58] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleEncryptResponse.ProtoReflect.Descriptor instead. +func (*SubtleEncryptResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{58} +} + +func (x *SubtleEncryptResponse) GetCiphertext() []byte { + if x != nil { + return x.Ciphertext + } + return nil +} + +func (x *SubtleEncryptResponse) GetTag() []byte { + if x != nil { + return x.Tag + } + return nil +} + +// SubtleDecryptRequest is the request for SubtleDecryptAlpha1. +type SubtleDecryptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Message to decrypt. + Ciphertext []byte `protobuf:"bytes,2,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Nonce / initialization vector. + // Ignored with asymmetric ciphers. + Nonce []byte `protobuf:"bytes,5,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Authentication tag. + // This is nil when not using an authenticated cipher. + Tag []byte `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` + // Associated Data when using AEAD ciphers (optional). + AssociatedData []byte `protobuf:"bytes,7,opt,name=associated_data,json=associatedData,proto3" json:"associated_data,omitempty"` +} + +func (x *SubtleDecryptRequest) Reset() { + *x = SubtleDecryptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleDecryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleDecryptRequest) ProtoMessage() {} + +func (x *SubtleDecryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[59] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleDecryptRequest.ProtoReflect.Descriptor instead. +func (*SubtleDecryptRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{59} +} + +func (x *SubtleDecryptRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleDecryptRequest) GetCiphertext() []byte { + if x != nil { + return x.Ciphertext + } + return nil +} + +func (x *SubtleDecryptRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleDecryptRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *SubtleDecryptRequest) GetNonce() []byte { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *SubtleDecryptRequest) GetTag() []byte { + if x != nil { + return x.Tag + } + return nil +} + +func (x *SubtleDecryptRequest) GetAssociatedData() []byte { + if x != nil { + return x.AssociatedData + } + return nil +} + +// SubtleDecryptResponse is the response for SubtleDecryptAlpha1. +type SubtleDecryptResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Decrypted plaintext. + Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` +} + +func (x *SubtleDecryptResponse) Reset() { + *x = SubtleDecryptResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleDecryptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleDecryptResponse) ProtoMessage() {} + +func (x *SubtleDecryptResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[60] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleDecryptResponse.ProtoReflect.Descriptor instead. +func (*SubtleDecryptResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{60} +} + +func (x *SubtleDecryptResponse) GetPlaintext() []byte { + if x != nil { + return x.Plaintext + } + return nil +} + +// SubtleWrapKeyRequest is the request for SubtleWrapKeyAlpha1. +type SubtleWrapKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Key to wrap + PlaintextKey []byte `protobuf:"bytes,2,opt,name=plaintext_key,json=plaintextKey,proto3" json:"plaintext_key,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Nonce / initialization vector. + // Ignored with asymmetric ciphers. + Nonce []byte `protobuf:"bytes,5,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Associated Data when using AEAD ciphers (optional). + AssociatedData []byte `protobuf:"bytes,6,opt,name=associated_data,json=associatedData,proto3" json:"associated_data,omitempty"` +} + +func (x *SubtleWrapKeyRequest) Reset() { + *x = SubtleWrapKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleWrapKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleWrapKeyRequest) ProtoMessage() {} + +func (x *SubtleWrapKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[61] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleWrapKeyRequest.ProtoReflect.Descriptor instead. +func (*SubtleWrapKeyRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{61} +} + +func (x *SubtleWrapKeyRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleWrapKeyRequest) GetPlaintextKey() []byte { + if x != nil { + return x.PlaintextKey + } + return nil +} + +func (x *SubtleWrapKeyRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleWrapKeyRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *SubtleWrapKeyRequest) GetNonce() []byte { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *SubtleWrapKeyRequest) GetAssociatedData() []byte { + if x != nil { + return x.AssociatedData + } + return nil +} + +// SubtleWrapKeyResponse is the response for SubtleWrapKeyAlpha1. +type SubtleWrapKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Wrapped key. + WrappedKey []byte `protobuf:"bytes,1,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` + // Authentication tag. + // This is nil when not using an authenticated cipher. + Tag []byte `protobuf:"bytes,2,opt,name=tag,proto3" json:"tag,omitempty"` +} + +func (x *SubtleWrapKeyResponse) Reset() { + *x = SubtleWrapKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleWrapKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleWrapKeyResponse) ProtoMessage() {} + +func (x *SubtleWrapKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[62] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleWrapKeyResponse.ProtoReflect.Descriptor instead. +func (*SubtleWrapKeyResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{62} +} + +func (x *SubtleWrapKeyResponse) GetWrappedKey() []byte { + if x != nil { + return x.WrappedKey + } + return nil +} + +func (x *SubtleWrapKeyResponse) GetTag() []byte { + if x != nil { + return x.Tag + } + return nil +} + +// SubtleUnwrapKeyRequest is the request for SubtleUnwrapKeyAlpha1. +type SubtleUnwrapKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Wrapped key. + WrappedKey []byte `protobuf:"bytes,2,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Nonce / initialization vector. + // Ignored with asymmetric ciphers. + Nonce []byte `protobuf:"bytes,5,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Authentication tag. + // This is nil when not using an authenticated cipher. + Tag []byte `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` + // Associated Data when using AEAD ciphers (optional). + AssociatedData []byte `protobuf:"bytes,7,opt,name=associated_data,json=associatedData,proto3" json:"associated_data,omitempty"` +} + +func (x *SubtleUnwrapKeyRequest) Reset() { + *x = SubtleUnwrapKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleUnwrapKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleUnwrapKeyRequest) ProtoMessage() {} + +func (x *SubtleUnwrapKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[63] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleUnwrapKeyRequest.ProtoReflect.Descriptor instead. +func (*SubtleUnwrapKeyRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{63} +} + +func (x *SubtleUnwrapKeyRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleUnwrapKeyRequest) GetWrappedKey() []byte { + if x != nil { + return x.WrappedKey + } + return nil +} + +func (x *SubtleUnwrapKeyRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleUnwrapKeyRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *SubtleUnwrapKeyRequest) GetNonce() []byte { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *SubtleUnwrapKeyRequest) GetTag() []byte { + if x != nil { + return x.Tag + } + return nil +} + +func (x *SubtleUnwrapKeyRequest) GetAssociatedData() []byte { + if x != nil { + return x.AssociatedData + } + return nil +} + +// SubtleUnwrapKeyResponse is the response for SubtleUnwrapKeyAlpha1. +type SubtleUnwrapKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Key in plaintext + PlaintextKey []byte `protobuf:"bytes,1,opt,name=plaintext_key,json=plaintextKey,proto3" json:"plaintext_key,omitempty"` +} + +func (x *SubtleUnwrapKeyResponse) Reset() { + *x = SubtleUnwrapKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleUnwrapKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleUnwrapKeyResponse) ProtoMessage() {} + +func (x *SubtleUnwrapKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleUnwrapKeyResponse.ProtoReflect.Descriptor instead. +func (*SubtleUnwrapKeyResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{64} +} + +func (x *SubtleUnwrapKeyResponse) GetPlaintextKey() []byte { + if x != nil { + return x.PlaintextKey + } + return nil +} + +// SubtleSignRequest is the request for SubtleSignAlpha1. +type SubtleSignRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Digest to sign. + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` +} + +func (x *SubtleSignRequest) Reset() { + *x = SubtleSignRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleSignRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleSignRequest) ProtoMessage() {} + +func (x *SubtleSignRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleSignRequest.ProtoReflect.Descriptor instead. +func (*SubtleSignRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{65} +} + +func (x *SubtleSignRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleSignRequest) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *SubtleSignRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleSignRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +// SubtleSignResponse is the response for SubtleSignAlpha1. +type SubtleSignResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The signature that was computed + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *SubtleSignResponse) Reset() { + *x = SubtleSignResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleSignResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleSignResponse) ProtoMessage() {} + +func (x *SubtleSignResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleSignResponse.ProtoReflect.Descriptor instead. +func (*SubtleSignResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{66} +} + +func (x *SubtleSignResponse) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +// SubtleVerifyRequest is the request for SubtleVerifyAlpha1. +type SubtleVerifyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Digest of the message. + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` + // Algorithm to use, as in the JWA standard. + Algorithm string `protobuf:"bytes,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + // Name (or name/version) of the key. + KeyName string `protobuf:"bytes,4,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Signature to verify. + Signature []byte `protobuf:"bytes,5,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *SubtleVerifyRequest) Reset() { + *x = SubtleVerifyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleVerifyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleVerifyRequest) ProtoMessage() {} + +func (x *SubtleVerifyRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[67] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleVerifyRequest.ProtoReflect.Descriptor instead. +func (*SubtleVerifyRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{67} +} + +func (x *SubtleVerifyRequest) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *SubtleVerifyRequest) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *SubtleVerifyRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *SubtleVerifyRequest) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *SubtleVerifyRequest) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +// SubtleVerifyResponse is the response for SubtleVerifyAlpha1. +type SubtleVerifyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // True if the signature is valid. + Valid bool `protobuf:"varint,1,opt,name=valid,proto3" json:"valid,omitempty"` +} + +func (x *SubtleVerifyResponse) Reset() { + *x = SubtleVerifyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubtleVerifyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubtleVerifyResponse) ProtoMessage() {} + +func (x *SubtleVerifyResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[68] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubtleVerifyResponse.ProtoReflect.Descriptor instead. +func (*SubtleVerifyResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{68} +} + +func (x *SubtleVerifyResponse) GetValid() bool { + if x != nil { + return x.Valid + } + return false +} + +// EncryptRequest is the request for EncryptAlpha1. +type EncryptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Request details. Must be present in the first message only. + Options *EncryptRequestOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"` + // Chunk of data of arbitrary size. + Payload *v1.StreamPayload `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *EncryptRequest) Reset() { + *x = EncryptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EncryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EncryptRequest) ProtoMessage() {} + +func (x *EncryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[69] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EncryptRequest.ProtoReflect.Descriptor instead. +func (*EncryptRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{69} +} + +func (x *EncryptRequest) GetOptions() *EncryptRequestOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *EncryptRequest) GetPayload() *v1.StreamPayload { + if x != nil { + return x.Payload + } + return nil +} + +// EncryptRequestOptions contains options for the first message in the EncryptAlpha1 request. +type EncryptRequestOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component. Required. + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Name (or name/version) of the key. Required. + KeyName string `protobuf:"bytes,2,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + // Key wrapping algorithm to use. Required. + // Supported options include: A256KW (alias: AES), A128CBC, A192CBC, A256CBC, RSA-OAEP-256 (alias: RSA). + KeyWrapAlgorithm string `protobuf:"bytes,3,opt,name=key_wrap_algorithm,json=keyWrapAlgorithm,proto3" json:"key_wrap_algorithm,omitempty"` + // Cipher used to encrypt data (optional): "aes-gcm" (default) or "chacha20-poly1305" + DataEncryptionCipher string `protobuf:"bytes,10,opt,name=data_encryption_cipher,json=dataEncryptionCipher,proto3" json:"data_encryption_cipher,omitempty"` + // If true, the encrypted document does not contain a key reference. + // In that case, calls to the Decrypt method must provide a key reference (name or name/version). + // Defaults to false. + OmitDecryptionKeyName bool `protobuf:"varint,11,opt,name=omit_decryption_key_name,json=omitDecryptionKeyName,proto3" json:"omit_decryption_key_name,omitempty"` + // Key reference to embed in the encrypted document (name or name/version). + // This is helpful if the reference of the key used to decrypt the document is different from the one used to encrypt it. + // If unset, uses the reference of the key used to encrypt the document (this is the default behavior). + // This option is ignored if omit_decryption_key_name is true. + DecryptionKeyName string `protobuf:"bytes,12,opt,name=decryption_key_name,json=decryptionKeyName,proto3" json:"decryption_key_name,omitempty"` +} + +func (x *EncryptRequestOptions) Reset() { + *x = EncryptRequestOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EncryptRequestOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EncryptRequestOptions) ProtoMessage() {} + +func (x *EncryptRequestOptions) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EncryptRequestOptions.ProtoReflect.Descriptor instead. +func (*EncryptRequestOptions) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{70} +} + +func (x *EncryptRequestOptions) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *EncryptRequestOptions) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +func (x *EncryptRequestOptions) GetKeyWrapAlgorithm() string { + if x != nil { + return x.KeyWrapAlgorithm + } + return "" +} + +func (x *EncryptRequestOptions) GetDataEncryptionCipher() string { + if x != nil { + return x.DataEncryptionCipher + } + return "" +} + +func (x *EncryptRequestOptions) GetOmitDecryptionKeyName() bool { + if x != nil { + return x.OmitDecryptionKeyName + } + return false +} + +func (x *EncryptRequestOptions) GetDecryptionKeyName() string { + if x != nil { + return x.DecryptionKeyName + } + return "" +} + +// EncryptResponse is the response for EncryptAlpha1. +type EncryptResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Chunk of data. + Payload *v1.StreamPayload `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *EncryptResponse) Reset() { + *x = EncryptResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EncryptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EncryptResponse) ProtoMessage() {} + +func (x *EncryptResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EncryptResponse.ProtoReflect.Descriptor instead. +func (*EncryptResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{71} +} + +func (x *EncryptResponse) GetPayload() *v1.StreamPayload { + if x != nil { + return x.Payload + } + return nil +} + +// DecryptRequest is the request for DecryptAlpha1. +type DecryptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Request details. Must be present in the first message only. + Options *DecryptRequestOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"` + // Chunk of data of arbitrary size. + Payload *v1.StreamPayload `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *DecryptRequest) Reset() { + *x = DecryptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DecryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DecryptRequest) ProtoMessage() {} + +func (x *DecryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DecryptRequest.ProtoReflect.Descriptor instead. +func (*DecryptRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{72} +} + +func (x *DecryptRequest) GetOptions() *DecryptRequestOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *DecryptRequest) GetPayload() *v1.StreamPayload { + if x != nil { + return x.Payload + } + return nil +} + +// DecryptRequestOptions contains options for the first message in the DecryptAlpha1 request. +type DecryptRequestOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the component + ComponentName string `protobuf:"bytes,1,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"` + // Name (or name/version) of the key to decrypt the message. + // Overrides any key reference included in the message if present. + // This is required if the message doesn't include a key reference (i.e. was created with omit_decryption_key_name set to true). + KeyName string `protobuf:"bytes,12,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` +} + +func (x *DecryptRequestOptions) Reset() { + *x = DecryptRequestOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DecryptRequestOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DecryptRequestOptions) ProtoMessage() {} + +func (x *DecryptRequestOptions) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DecryptRequestOptions.ProtoReflect.Descriptor instead. +func (*DecryptRequestOptions) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{73} +} + +func (x *DecryptRequestOptions) GetComponentName() string { + if x != nil { + return x.ComponentName + } + return "" +} + +func (x *DecryptRequestOptions) GetKeyName() string { + if x != nil { + return x.KeyName + } + return "" +} + +// DecryptResponse is the response for DecryptAlpha1. +type DecryptResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Chunk of data. + Payload *v1.StreamPayload `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *DecryptResponse) Reset() { + *x = DecryptResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DecryptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DecryptResponse) ProtoMessage() {} + +func (x *DecryptResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[74] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DecryptResponse.ProtoReflect.Descriptor instead. +func (*DecryptResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{74} +} + +func (x *DecryptResponse) GetPayload() *v1.StreamPayload { + if x != nil { + return x.Payload + } + return nil +} + +// GetWorkflowRequest is the request for GetWorkflowAlpha1. +type GetWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to query. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` +} + +func (x *GetWorkflowRequest) Reset() { + *x = GetWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkflowRequest) ProtoMessage() {} + +func (x *GetWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[75] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkflowRequest.ProtoReflect.Descriptor instead. +func (*GetWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{75} +} + +func (x *GetWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *GetWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +// GetWorkflowResponse is the response for GetWorkflowAlpha1. +type GetWorkflowResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow. + WorkflowName string `protobuf:"bytes,2,opt,name=workflow_name,json=workflowName,proto3" json:"workflow_name,omitempty"` + // The time at which the workflow instance was created. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // The last time at which the workflow instance had its state changed. + LastUpdatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_updated_at,json=lastUpdatedAt,proto3" json:"last_updated_at,omitempty"` + // The current status of the workflow instance, for example, "PENDING", "RUNNING", "SUSPENDED", "COMPLETED", "FAILED", and "TERMINATED". + RuntimeStatus string `protobuf:"bytes,5,opt,name=runtime_status,json=runtimeStatus,proto3" json:"runtime_status,omitempty"` + // Additional component-specific properties of the workflow instance. + Properties map[string]string `protobuf:"bytes,6,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetWorkflowResponse) Reset() { + *x = GetWorkflowResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkflowResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkflowResponse) ProtoMessage() {} + +func (x *GetWorkflowResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[76] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkflowResponse.ProtoReflect.Descriptor instead. +func (*GetWorkflowResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{76} +} + +func (x *GetWorkflowResponse) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *GetWorkflowResponse) GetWorkflowName() string { + if x != nil { + return x.WorkflowName + } + return "" +} + +func (x *GetWorkflowResponse) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *GetWorkflowResponse) GetLastUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.LastUpdatedAt + } + return nil +} + +func (x *GetWorkflowResponse) GetRuntimeStatus() string { + if x != nil { + return x.RuntimeStatus + } + return "" +} + +func (x *GetWorkflowResponse) GetProperties() map[string]string { + if x != nil { + return x.Properties + } + return nil +} + +// StartWorkflowRequest is the request for StartWorkflowAlpha1. +type StartWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The ID to assign to the started workflow instance. If empty, a random ID is generated. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` + // Name of the workflow. + WorkflowName string `protobuf:"bytes,3,opt,name=workflow_name,json=workflowName,proto3" json:"workflow_name,omitempty"` + // Additional component-specific options for starting the workflow instance. + Options map[string]string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Input data for the workflow instance. + Input []byte `protobuf:"bytes,5,opt,name=input,proto3" json:"input,omitempty"` +} + +func (x *StartWorkflowRequest) Reset() { + *x = StartWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartWorkflowRequest) ProtoMessage() {} + +func (x *StartWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[77] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartWorkflowRequest.ProtoReflect.Descriptor instead. +func (*StartWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{77} +} + +func (x *StartWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *StartWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +func (x *StartWorkflowRequest) GetWorkflowName() string { + if x != nil { + return x.WorkflowName + } + return "" +} + +func (x *StartWorkflowRequest) GetOptions() map[string]string { + if x != nil { + return x.Options + } + return nil +} + +func (x *StartWorkflowRequest) GetInput() []byte { + if x != nil { + return x.Input + } + return nil +} + +// StartWorkflowResponse is the response for StartWorkflowAlpha1. +type StartWorkflowResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the started workflow instance. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` +} + +func (x *StartWorkflowResponse) Reset() { + *x = StartWorkflowResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartWorkflowResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartWorkflowResponse) ProtoMessage() {} + +func (x *StartWorkflowResponse) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[78] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartWorkflowResponse.ProtoReflect.Descriptor instead. +func (*StartWorkflowResponse) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{78} +} + +func (x *StartWorkflowResponse) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +// TerminateWorkflowRequest is the request for TerminateWorkflowAlpha1. +type TerminateWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to terminate. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` +} + +func (x *TerminateWorkflowRequest) Reset() { + *x = TerminateWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TerminateWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TerminateWorkflowRequest) ProtoMessage() {} + +func (x *TerminateWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[79] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TerminateWorkflowRequest.ProtoReflect.Descriptor instead. +func (*TerminateWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{79} +} + +func (x *TerminateWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *TerminateWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +// PauseWorkflowRequest is the request for PauseWorkflowAlpha1. +type PauseWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to pause. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` +} + +func (x *PauseWorkflowRequest) Reset() { + *x = PauseWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[80] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PauseWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PauseWorkflowRequest) ProtoMessage() {} + +func (x *PauseWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[80] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PauseWorkflowRequest.ProtoReflect.Descriptor instead. +func (*PauseWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{80} +} + +func (x *PauseWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *PauseWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +// ResumeWorkflowRequest is the request for ResumeWorkflowAlpha1. +type ResumeWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to resume. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` +} + +func (x *ResumeWorkflowRequest) Reset() { + *x = ResumeWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[81] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResumeWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeWorkflowRequest) ProtoMessage() {} + +func (x *ResumeWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[81] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResumeWorkflowRequest.ProtoReflect.Descriptor instead. +func (*ResumeWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{81} +} + +func (x *ResumeWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *ResumeWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +// RaiseEventWorkflowRequest is the request for RaiseEventWorkflowAlpha1. +type RaiseEventWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to raise an event for. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` + // Name of the event. + EventName string `protobuf:"bytes,3,opt,name=event_name,json=eventName,proto3" json:"event_name,omitempty"` + // Data associated with the event. + EventData []byte `protobuf:"bytes,4,opt,name=event_data,json=eventData,proto3" json:"event_data,omitempty"` +} + +func (x *RaiseEventWorkflowRequest) Reset() { + *x = RaiseEventWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[82] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RaiseEventWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RaiseEventWorkflowRequest) ProtoMessage() {} + +func (x *RaiseEventWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[82] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RaiseEventWorkflowRequest.ProtoReflect.Descriptor instead. +func (*RaiseEventWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{82} +} + +func (x *RaiseEventWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *RaiseEventWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +func (x *RaiseEventWorkflowRequest) GetEventName() string { + if x != nil { + return x.EventName + } + return "" +} + +func (x *RaiseEventWorkflowRequest) GetEventData() []byte { + if x != nil { + return x.EventData + } + return nil +} + +// PurgeWorkflowRequest is the request for PurgeWorkflowAlpha1. +type PurgeWorkflowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the workflow instance to purge. + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceID,proto3" json:"instance_id,omitempty"` + // Name of the workflow component. + WorkflowComponent string `protobuf:"bytes,2,opt,name=workflow_component,json=workflowComponent,proto3" json:"workflow_component,omitempty"` +} + +func (x *PurgeWorkflowRequest) Reset() { + *x = PurgeWorkflowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PurgeWorkflowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PurgeWorkflowRequest) ProtoMessage() {} + +func (x *PurgeWorkflowRequest) ProtoReflect() protoreflect.Message { + mi := &file_dapr_proto_runtime_v1_dapr_proto_msgTypes[83] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PurgeWorkflowRequest.ProtoReflect.Descriptor instead. +func (*PurgeWorkflowRequest) Descriptor() ([]byte, []int) { + return file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP(), []int{83} +} + +func (x *PurgeWorkflowRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *PurgeWorkflowRequest) GetWorkflowComponent() string { + if x != nil { + return x.WorkflowComponent + } + return "" +} + +var File_dapr_proto_runtime_v1_dapr_proto protoreflect.FileDescriptor + +var file_dapr_proto_runtime_v1_dapr_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x15, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x21, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x65, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3d, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa8, 0x02, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x55, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x50, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfd, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, + 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, + 0x79, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, + 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, + 0x6c, 0x69, 0x73, 0x6d, 0x12, 0x54, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x52, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x75, + 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3a, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x0d, + 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x4e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x01, 0x0a, 0x10, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x51, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc5, 0x02, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x2e, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x74, 0x61, 0x67, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, + 0x3c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x53, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x70, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x73, 0x22, 0x6a, 0x0a, 0x10, 0x53, 0x61, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x22, 0xd9, 0x01, + 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x60, 0x0a, 0x0e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xfd, 0x01, 0x0a, 0x12, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x53, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, + 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x02, 0x0a, 0x13, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, + 0x0a, 0x11, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x54, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa7, 0x02, + 0x0a, 0x12, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x73, 0x75, + 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x48, 0x0a, 0x07, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x84, 0x02, 0x0a, 0x17, 0x42, 0x75, 0x6c, 0x6b, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x72, + 0x0a, 0x13, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x22, 0x51, 0x0a, 0x1e, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xf0, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, + 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, + 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc0, 0x01, 0x0a, 0x15, 0x49, 0x6e, 0x76, + 0x6f, 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x56, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, + 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd3, 0x01, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x51, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x94, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, + 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, + 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, + 0x6c, 0x6b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xc3, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x5e, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7e, 0x0a, 0x1b, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x07, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb0, 0x02, 0x0a, 0x1e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5f, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xde, 0x01, 0x0a, 0x19, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x6f, + 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x75, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x75, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x22, 0x6b, 0x0a, 0x1b, 0x55, + 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, + 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, + 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xc5, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, + 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, + 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x75, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x75, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, + 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, 0x6c, + 0x22, 0x6e, 0x0a, 0x1e, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x8c, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, + 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x6c, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x22, + 0x62, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, + 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x49, + 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x22, 0x2b, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0xb8, 0x01, 0x0a, 0x23, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x63, 0x74, 0x6f, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x6f, + 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x49, 0x64, 0x12, 0x57, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x74, 0x6f, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa6, 0x02, 0x0a, 0x20, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x74, + 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x61, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x74, 0x6f, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8c, 0x02, 0x0a, 0x12, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x41, + 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x53, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, + 0x6b, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x29, 0x0a, 0x13, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9d, + 0x04, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x13, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x56, 0x0a, 0x15, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x65, 0x0a, + 0x11, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x12, 0x4f, 0x0a, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x73, 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x0e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x65, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x54, + 0x54, 0x50, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x68, 0x74, 0x74, 0x70, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x1a, 0x43, 0x0a, 0x15, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3d, + 0x0a, 0x11, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x7c, 0x0a, + 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x63, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x2a, 0x0a, 0x14, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x54, 0x54, 0x50, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xcf, 0x02, 0x0a, 0x12, 0x50, 0x75, 0x62, 0x73, + 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, + 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x53, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x75, 0x62, 0x73, 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x44, 0x0a, 0x05, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x75, 0x62, 0x73, 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x61, 0x64, 0x5f, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x5f, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x61, + 0x64, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x1a, 0x3b, 0x0a, 0x0d, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5e, 0x0a, 0x17, 0x50, 0x75, 0x62, + 0x73, 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x73, + 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x42, 0x0a, 0x16, 0x50, 0x75, 0x62, + 0x73, 0x75, 0x62, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x3c, 0x0a, + 0x12, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x58, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xcf, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, + 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x1a, 0x61, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xef, 0x01, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x5e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x50, 0x0a, 0x1f, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xeb, 0x01, 0x0a, 0x1e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x56, 0x0a, 0x05, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x1a, 0x61, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x20, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x0e, 0x54, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x6b, + 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, + 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x54, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x6e, + 0x0a, 0x0d, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xb6, + 0x01, 0x0a, 0x0e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x44, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x5e, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x17, + 0x0a, 0x13, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, + 0x42, 0x45, 0x4c, 0x4f, 0x4e, 0x47, 0x53, 0x5f, 0x54, 0x4f, 0x5f, 0x4f, 0x54, 0x48, 0x45, 0x52, + 0x53, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xbe, 0x01, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x74, + 0x6c, 0x65, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4c, 0x0a, 0x06, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x1e, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x45, 0x4d, 0x10, 0x00, 0x12, 0x08, + 0x0a, 0x04, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x22, 0x49, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x74, + 0x6c, 0x65, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x22, 0xd3, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, + 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x49, 0x0a, 0x15, 0x53, 0x75, 0x62, + 0x74, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x03, 0x74, 0x61, 0x67, 0x22, 0xe7, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x44, + 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, + 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, + 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x35, + 0x0a, 0x15, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xda, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, + 0x57, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0e, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x22, 0x4a, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x57, 0x72, 0x61, 0x70, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0xea, + 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, + 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, + 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x74, + 0x61, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x61, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x3e, 0x0a, 0x17, 0x53, + 0x75, 0x62, 0x74, 0x6c, 0x65, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, + 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x8b, 0x01, 0x0a, 0x11, + 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x19, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x32, 0x0a, 0x12, 0x53, 0x75, 0x62, + 0x74, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xab, 0x01, + 0x0a, 0x13, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x2c, 0x0a, 0x14, 0x53, + 0x75, 0x62, 0x74, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x22, 0x97, 0x01, 0x0a, 0x0e, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0xa6, 0x02, 0x0a, 0x15, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x5f, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6b, 0x65, 0x79, + 0x57, 0x72, 0x61, 0x70, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x34, 0x0a, + 0x16, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x69, 0x70, + 0x68, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x64, 0x65, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x6f, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, + 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x64, 0x65, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x50, 0x0a, 0x0f, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3d, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x97, + 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x46, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x07, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x59, 0x0a, 0x15, 0x44, 0x65, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x50, 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x64, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0x9c, 0x03, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x49, 0x44, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x5a, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb1, 0x02, 0x0a, 0x14, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x1a, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x38, + 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x22, 0x6a, 0x0a, 0x18, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x22, 0x66, 0x0a, 0x14, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, + 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0x67, 0x0a, 0x15, + 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0xa9, 0x01, 0x0a, 0x19, 0x52, 0x61, 0x69, 0x73, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, + 0x61, 0x22, 0x66, 0x0a, 0x14, 0x50, 0x75, 0x72, 0x67, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x32, 0xe9, 0x27, 0x0a, 0x04, 0x44, 0x61, + 0x70, 0x72, 0x12, 0x64, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, + 0x6b, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x75, + 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x09, 0x53, 0x61, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x27, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x69, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x28, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, + 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x75, 0x6c, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6a, 0x0a, + 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0c, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x71, 0x0a, 0x16, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, + 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, + 0x6b, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x42, + 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x60, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x27, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x75, 0x6c, 0x6b, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x6c, 0x6b, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x60, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x64, 0x0a, 0x14, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x41, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, + 0x6f, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, + 0x72, 0x12, 0x33, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x12, 0x6a, 0x0a, 0x17, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x35, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x13, + 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, + 0x64, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x6d, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x12, 0x6c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, + 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, + 0x0a, 0x1c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x63, + 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x0b, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x63, + 0x74, 0x6f, 0x72, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, + 0x6b, 0x65, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2e, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x10, 0x47, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x8f, 0x01, 0x0a, 0x1c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x12, 0x34, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x89, 0x01, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x93, + 0x01, 0x0a, 0x1e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x12, 0x36, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x8d, 0x01, 0x0a, 0x18, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x36, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0d, 0x54, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x41, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, + 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, + 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x24, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x0d, 0x44, 0x65, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x70, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x53, 0x0a, + 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, + 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2a, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2b, 0x2e, 0x64, + 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x74, 0x6c, + 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2b, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x13, 0x53, 0x75, 0x62, + 0x74, 0x6c, 0x65, 0x57, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x57, + 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x57, 0x72, 0x61, 0x70, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x15, 0x53, + 0x75, 0x62, 0x74, 0x6c, 0x65, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x41, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x12, 0x2d, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, + 0x74, 0x6c, 0x65, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, + 0x6c, 0x65, 0x55, 0x6e, 0x77, 0x72, 0x61, 0x70, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x53, 0x69, 0x67, + 0x6e, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x28, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, + 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x12, + 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x41, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, + 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, + 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x6c, 0x65, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x13, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x6c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x41, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, + 0x13, 0x50, 0x75, 0x72, 0x67, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x41, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, + 0x67, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x17, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2f, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x12, 0x5c, 0x0a, 0x13, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x5e, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x70, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x66, 0x0a, 0x18, 0x52, 0x61, 0x69, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x12, 0x30, 0x2e, 0x64, 0x61, + 0x70, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x69, 0x73, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, + 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x69, 0x0a, 0x0a, 0x69, 0x6f, 0x2e, 0x64, 0x61, 0x70, 0x72, + 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x44, 0x61, 0x70, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x5a, + 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x61, 0x70, 0x72, + 0x2f, 0x64, 0x61, 0x70, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0xaa, 0x02, 0x1b, 0x44, 0x61, 0x70, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dapr_proto_runtime_v1_dapr_proto_rawDescOnce sync.Once + file_dapr_proto_runtime_v1_dapr_proto_rawDescData = file_dapr_proto_runtime_v1_dapr_proto_rawDesc +) + +func file_dapr_proto_runtime_v1_dapr_proto_rawDescGZIP() []byte { + file_dapr_proto_runtime_v1_dapr_proto_rawDescOnce.Do(func() { + file_dapr_proto_runtime_v1_dapr_proto_rawDescData = protoimpl.X.CompressGZIP(file_dapr_proto_runtime_v1_dapr_proto_rawDescData) + }) + return file_dapr_proto_runtime_v1_dapr_proto_rawDescData +} + +var file_dapr_proto_runtime_v1_dapr_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_dapr_proto_runtime_v1_dapr_proto_msgTypes = make([]protoimpl.MessageInfo, 112) +var file_dapr_proto_runtime_v1_dapr_proto_goTypes = []interface{}{ + (UnlockResponse_Status)(0), // 0: dapr.proto.runtime.v1.UnlockResponse.Status + (SubtleGetKeyRequest_KeyFormat)(0), // 1: dapr.proto.runtime.v1.SubtleGetKeyRequest.KeyFormat + (*InvokeServiceRequest)(nil), // 2: dapr.proto.runtime.v1.InvokeServiceRequest + (*GetStateRequest)(nil), // 3: dapr.proto.runtime.v1.GetStateRequest + (*GetBulkStateRequest)(nil), // 4: dapr.proto.runtime.v1.GetBulkStateRequest + (*GetBulkStateResponse)(nil), // 5: dapr.proto.runtime.v1.GetBulkStateResponse + (*BulkStateItem)(nil), // 6: dapr.proto.runtime.v1.BulkStateItem + (*GetStateResponse)(nil), // 7: dapr.proto.runtime.v1.GetStateResponse + (*DeleteStateRequest)(nil), // 8: dapr.proto.runtime.v1.DeleteStateRequest + (*DeleteBulkStateRequest)(nil), // 9: dapr.proto.runtime.v1.DeleteBulkStateRequest + (*SaveStateRequest)(nil), // 10: dapr.proto.runtime.v1.SaveStateRequest + (*QueryStateRequest)(nil), // 11: dapr.proto.runtime.v1.QueryStateRequest + (*QueryStateItem)(nil), // 12: dapr.proto.runtime.v1.QueryStateItem + (*QueryStateResponse)(nil), // 13: dapr.proto.runtime.v1.QueryStateResponse + (*PublishEventRequest)(nil), // 14: dapr.proto.runtime.v1.PublishEventRequest + (*BulkPublishRequest)(nil), // 15: dapr.proto.runtime.v1.BulkPublishRequest + (*BulkPublishRequestEntry)(nil), // 16: dapr.proto.runtime.v1.BulkPublishRequestEntry + (*BulkPublishResponse)(nil), // 17: dapr.proto.runtime.v1.BulkPublishResponse + (*BulkPublishResponseFailedEntry)(nil), // 18: dapr.proto.runtime.v1.BulkPublishResponseFailedEntry + (*InvokeBindingRequest)(nil), // 19: dapr.proto.runtime.v1.InvokeBindingRequest + (*InvokeBindingResponse)(nil), // 20: dapr.proto.runtime.v1.InvokeBindingResponse + (*GetSecretRequest)(nil), // 21: dapr.proto.runtime.v1.GetSecretRequest + (*GetSecretResponse)(nil), // 22: dapr.proto.runtime.v1.GetSecretResponse + (*GetBulkSecretRequest)(nil), // 23: dapr.proto.runtime.v1.GetBulkSecretRequest + (*SecretResponse)(nil), // 24: dapr.proto.runtime.v1.SecretResponse + (*GetBulkSecretResponse)(nil), // 25: dapr.proto.runtime.v1.GetBulkSecretResponse + (*TransactionalStateOperation)(nil), // 26: dapr.proto.runtime.v1.TransactionalStateOperation + (*ExecuteStateTransactionRequest)(nil), // 27: dapr.proto.runtime.v1.ExecuteStateTransactionRequest + (*RegisterActorTimerRequest)(nil), // 28: dapr.proto.runtime.v1.RegisterActorTimerRequest + (*UnregisterActorTimerRequest)(nil), // 29: dapr.proto.runtime.v1.UnregisterActorTimerRequest + (*RegisterActorReminderRequest)(nil), // 30: dapr.proto.runtime.v1.RegisterActorReminderRequest + (*UnregisterActorReminderRequest)(nil), // 31: dapr.proto.runtime.v1.UnregisterActorReminderRequest + (*RenameActorReminderRequest)(nil), // 32: dapr.proto.runtime.v1.RenameActorReminderRequest + (*GetActorStateRequest)(nil), // 33: dapr.proto.runtime.v1.GetActorStateRequest + (*GetActorStateResponse)(nil), // 34: dapr.proto.runtime.v1.GetActorStateResponse + (*ExecuteActorStateTransactionRequest)(nil), // 35: dapr.proto.runtime.v1.ExecuteActorStateTransactionRequest + (*TransactionalActorStateOperation)(nil), // 36: dapr.proto.runtime.v1.TransactionalActorStateOperation + (*InvokeActorRequest)(nil), // 37: dapr.proto.runtime.v1.InvokeActorRequest + (*InvokeActorResponse)(nil), // 38: dapr.proto.runtime.v1.InvokeActorResponse + (*GetMetadataResponse)(nil), // 39: dapr.proto.runtime.v1.GetMetadataResponse + (*ActiveActorsCount)(nil), // 40: dapr.proto.runtime.v1.ActiveActorsCount + (*RegisteredComponents)(nil), // 41: dapr.proto.runtime.v1.RegisteredComponents + (*MetadataHTTPEndpoint)(nil), // 42: dapr.proto.runtime.v1.MetadataHTTPEndpoint + (*PubsubSubscription)(nil), // 43: dapr.proto.runtime.v1.PubsubSubscription + (*PubsubSubscriptionRules)(nil), // 44: dapr.proto.runtime.v1.PubsubSubscriptionRules + (*PubsubSubscriptionRule)(nil), // 45: dapr.proto.runtime.v1.PubsubSubscriptionRule + (*SetMetadataRequest)(nil), // 46: dapr.proto.runtime.v1.SetMetadataRequest + (*GetConfigurationRequest)(nil), // 47: dapr.proto.runtime.v1.GetConfigurationRequest + (*GetConfigurationResponse)(nil), // 48: dapr.proto.runtime.v1.GetConfigurationResponse + (*SubscribeConfigurationRequest)(nil), // 49: dapr.proto.runtime.v1.SubscribeConfigurationRequest + (*UnsubscribeConfigurationRequest)(nil), // 50: dapr.proto.runtime.v1.UnsubscribeConfigurationRequest + (*SubscribeConfigurationResponse)(nil), // 51: dapr.proto.runtime.v1.SubscribeConfigurationResponse + (*UnsubscribeConfigurationResponse)(nil), // 52: dapr.proto.runtime.v1.UnsubscribeConfigurationResponse + (*TryLockRequest)(nil), // 53: dapr.proto.runtime.v1.TryLockRequest + (*TryLockResponse)(nil), // 54: dapr.proto.runtime.v1.TryLockResponse + (*UnlockRequest)(nil), // 55: dapr.proto.runtime.v1.UnlockRequest + (*UnlockResponse)(nil), // 56: dapr.proto.runtime.v1.UnlockResponse + (*SubtleGetKeyRequest)(nil), // 57: dapr.proto.runtime.v1.SubtleGetKeyRequest + (*SubtleGetKeyResponse)(nil), // 58: dapr.proto.runtime.v1.SubtleGetKeyResponse + (*SubtleEncryptRequest)(nil), // 59: dapr.proto.runtime.v1.SubtleEncryptRequest + (*SubtleEncryptResponse)(nil), // 60: dapr.proto.runtime.v1.SubtleEncryptResponse + (*SubtleDecryptRequest)(nil), // 61: dapr.proto.runtime.v1.SubtleDecryptRequest + (*SubtleDecryptResponse)(nil), // 62: dapr.proto.runtime.v1.SubtleDecryptResponse + (*SubtleWrapKeyRequest)(nil), // 63: dapr.proto.runtime.v1.SubtleWrapKeyRequest + (*SubtleWrapKeyResponse)(nil), // 64: dapr.proto.runtime.v1.SubtleWrapKeyResponse + (*SubtleUnwrapKeyRequest)(nil), // 65: dapr.proto.runtime.v1.SubtleUnwrapKeyRequest + (*SubtleUnwrapKeyResponse)(nil), // 66: dapr.proto.runtime.v1.SubtleUnwrapKeyResponse + (*SubtleSignRequest)(nil), // 67: dapr.proto.runtime.v1.SubtleSignRequest + (*SubtleSignResponse)(nil), // 68: dapr.proto.runtime.v1.SubtleSignResponse + (*SubtleVerifyRequest)(nil), // 69: dapr.proto.runtime.v1.SubtleVerifyRequest + (*SubtleVerifyResponse)(nil), // 70: dapr.proto.runtime.v1.SubtleVerifyResponse + (*EncryptRequest)(nil), // 71: dapr.proto.runtime.v1.EncryptRequest + (*EncryptRequestOptions)(nil), // 72: dapr.proto.runtime.v1.EncryptRequestOptions + (*EncryptResponse)(nil), // 73: dapr.proto.runtime.v1.EncryptResponse + (*DecryptRequest)(nil), // 74: dapr.proto.runtime.v1.DecryptRequest + (*DecryptRequestOptions)(nil), // 75: dapr.proto.runtime.v1.DecryptRequestOptions + (*DecryptResponse)(nil), // 76: dapr.proto.runtime.v1.DecryptResponse + (*GetWorkflowRequest)(nil), // 77: dapr.proto.runtime.v1.GetWorkflowRequest + (*GetWorkflowResponse)(nil), // 78: dapr.proto.runtime.v1.GetWorkflowResponse + (*StartWorkflowRequest)(nil), // 79: dapr.proto.runtime.v1.StartWorkflowRequest + (*StartWorkflowResponse)(nil), // 80: dapr.proto.runtime.v1.StartWorkflowResponse + (*TerminateWorkflowRequest)(nil), // 81: dapr.proto.runtime.v1.TerminateWorkflowRequest + (*PauseWorkflowRequest)(nil), // 82: dapr.proto.runtime.v1.PauseWorkflowRequest + (*ResumeWorkflowRequest)(nil), // 83: dapr.proto.runtime.v1.ResumeWorkflowRequest + (*RaiseEventWorkflowRequest)(nil), // 84: dapr.proto.runtime.v1.RaiseEventWorkflowRequest + (*PurgeWorkflowRequest)(nil), // 85: dapr.proto.runtime.v1.PurgeWorkflowRequest + nil, // 86: dapr.proto.runtime.v1.GetStateRequest.MetadataEntry + nil, // 87: dapr.proto.runtime.v1.GetBulkStateRequest.MetadataEntry + nil, // 88: dapr.proto.runtime.v1.BulkStateItem.MetadataEntry + nil, // 89: dapr.proto.runtime.v1.GetStateResponse.MetadataEntry + nil, // 90: dapr.proto.runtime.v1.DeleteStateRequest.MetadataEntry + nil, // 91: dapr.proto.runtime.v1.QueryStateRequest.MetadataEntry + nil, // 92: dapr.proto.runtime.v1.QueryStateResponse.MetadataEntry + nil, // 93: dapr.proto.runtime.v1.PublishEventRequest.MetadataEntry + nil, // 94: dapr.proto.runtime.v1.BulkPublishRequest.MetadataEntry + nil, // 95: dapr.proto.runtime.v1.BulkPublishRequestEntry.MetadataEntry + nil, // 96: dapr.proto.runtime.v1.InvokeBindingRequest.MetadataEntry + nil, // 97: dapr.proto.runtime.v1.InvokeBindingResponse.MetadataEntry + nil, // 98: dapr.proto.runtime.v1.GetSecretRequest.MetadataEntry + nil, // 99: dapr.proto.runtime.v1.GetSecretResponse.DataEntry + nil, // 100: dapr.proto.runtime.v1.GetBulkSecretRequest.MetadataEntry + nil, // 101: dapr.proto.runtime.v1.SecretResponse.SecretsEntry + nil, // 102: dapr.proto.runtime.v1.GetBulkSecretResponse.DataEntry + nil, // 103: dapr.proto.runtime.v1.ExecuteStateTransactionRequest.MetadataEntry + nil, // 104: dapr.proto.runtime.v1.TransactionalActorStateOperation.MetadataEntry + nil, // 105: dapr.proto.runtime.v1.InvokeActorRequest.MetadataEntry + nil, // 106: dapr.proto.runtime.v1.GetMetadataResponse.ExtendedMetadataEntry + nil, // 107: dapr.proto.runtime.v1.PubsubSubscription.MetadataEntry + nil, // 108: dapr.proto.runtime.v1.GetConfigurationRequest.MetadataEntry + nil, // 109: dapr.proto.runtime.v1.GetConfigurationResponse.ItemsEntry + nil, // 110: dapr.proto.runtime.v1.SubscribeConfigurationRequest.MetadataEntry + nil, // 111: dapr.proto.runtime.v1.SubscribeConfigurationResponse.ItemsEntry + nil, // 112: dapr.proto.runtime.v1.GetWorkflowResponse.PropertiesEntry + nil, // 113: dapr.proto.runtime.v1.StartWorkflowRequest.OptionsEntry + (*v1.InvokeRequest)(nil), // 114: dapr.proto.common.v1.InvokeRequest + (v1.StateOptions_StateConsistency)(0), // 115: dapr.proto.common.v1.StateOptions.StateConsistency + (*v1.Etag)(nil), // 116: dapr.proto.common.v1.Etag + (*v1.StateOptions)(nil), // 117: dapr.proto.common.v1.StateOptions + (*v1.StateItem)(nil), // 118: dapr.proto.common.v1.StateItem + (*anypb.Any)(nil), // 119: google.protobuf.Any + (*v1.StreamPayload)(nil), // 120: dapr.proto.common.v1.StreamPayload + (*timestamppb.Timestamp)(nil), // 121: google.protobuf.Timestamp + (*v1.ConfigurationItem)(nil), // 122: dapr.proto.common.v1.ConfigurationItem + (*emptypb.Empty)(nil), // 123: google.protobuf.Empty + (*v1.InvokeResponse)(nil), // 124: dapr.proto.common.v1.InvokeResponse +} +var file_dapr_proto_runtime_v1_dapr_proto_depIdxs = []int32{ + 114, // 0: dapr.proto.runtime.v1.InvokeServiceRequest.message:type_name -> dapr.proto.common.v1.InvokeRequest + 115, // 1: dapr.proto.runtime.v1.GetStateRequest.consistency:type_name -> dapr.proto.common.v1.StateOptions.StateConsistency + 86, // 2: dapr.proto.runtime.v1.GetStateRequest.metadata:type_name -> dapr.proto.runtime.v1.GetStateRequest.MetadataEntry + 87, // 3: dapr.proto.runtime.v1.GetBulkStateRequest.metadata:type_name -> dapr.proto.runtime.v1.GetBulkStateRequest.MetadataEntry + 6, // 4: dapr.proto.runtime.v1.GetBulkStateResponse.items:type_name -> dapr.proto.runtime.v1.BulkStateItem + 88, // 5: dapr.proto.runtime.v1.BulkStateItem.metadata:type_name -> dapr.proto.runtime.v1.BulkStateItem.MetadataEntry + 89, // 6: dapr.proto.runtime.v1.GetStateResponse.metadata:type_name -> dapr.proto.runtime.v1.GetStateResponse.MetadataEntry + 116, // 7: dapr.proto.runtime.v1.DeleteStateRequest.etag:type_name -> dapr.proto.common.v1.Etag + 117, // 8: dapr.proto.runtime.v1.DeleteStateRequest.options:type_name -> dapr.proto.common.v1.StateOptions + 90, // 9: dapr.proto.runtime.v1.DeleteStateRequest.metadata:type_name -> dapr.proto.runtime.v1.DeleteStateRequest.MetadataEntry + 118, // 10: dapr.proto.runtime.v1.DeleteBulkStateRequest.states:type_name -> dapr.proto.common.v1.StateItem + 118, // 11: dapr.proto.runtime.v1.SaveStateRequest.states:type_name -> dapr.proto.common.v1.StateItem + 91, // 12: dapr.proto.runtime.v1.QueryStateRequest.metadata:type_name -> dapr.proto.runtime.v1.QueryStateRequest.MetadataEntry + 12, // 13: dapr.proto.runtime.v1.QueryStateResponse.results:type_name -> dapr.proto.runtime.v1.QueryStateItem + 92, // 14: dapr.proto.runtime.v1.QueryStateResponse.metadata:type_name -> dapr.proto.runtime.v1.QueryStateResponse.MetadataEntry + 93, // 15: dapr.proto.runtime.v1.PublishEventRequest.metadata:type_name -> dapr.proto.runtime.v1.PublishEventRequest.MetadataEntry + 16, // 16: dapr.proto.runtime.v1.BulkPublishRequest.entries:type_name -> dapr.proto.runtime.v1.BulkPublishRequestEntry + 94, // 17: dapr.proto.runtime.v1.BulkPublishRequest.metadata:type_name -> dapr.proto.runtime.v1.BulkPublishRequest.MetadataEntry + 95, // 18: dapr.proto.runtime.v1.BulkPublishRequestEntry.metadata:type_name -> dapr.proto.runtime.v1.BulkPublishRequestEntry.MetadataEntry + 18, // 19: dapr.proto.runtime.v1.BulkPublishResponse.failedEntries:type_name -> dapr.proto.runtime.v1.BulkPublishResponseFailedEntry + 96, // 20: dapr.proto.runtime.v1.InvokeBindingRequest.metadata:type_name -> dapr.proto.runtime.v1.InvokeBindingRequest.MetadataEntry + 97, // 21: dapr.proto.runtime.v1.InvokeBindingResponse.metadata:type_name -> dapr.proto.runtime.v1.InvokeBindingResponse.MetadataEntry + 98, // 22: dapr.proto.runtime.v1.GetSecretRequest.metadata:type_name -> dapr.proto.runtime.v1.GetSecretRequest.MetadataEntry + 99, // 23: dapr.proto.runtime.v1.GetSecretResponse.data:type_name -> dapr.proto.runtime.v1.GetSecretResponse.DataEntry + 100, // 24: dapr.proto.runtime.v1.GetBulkSecretRequest.metadata:type_name -> dapr.proto.runtime.v1.GetBulkSecretRequest.MetadataEntry + 101, // 25: dapr.proto.runtime.v1.SecretResponse.secrets:type_name -> dapr.proto.runtime.v1.SecretResponse.SecretsEntry + 102, // 26: dapr.proto.runtime.v1.GetBulkSecretResponse.data:type_name -> dapr.proto.runtime.v1.GetBulkSecretResponse.DataEntry + 118, // 27: dapr.proto.runtime.v1.TransactionalStateOperation.request:type_name -> dapr.proto.common.v1.StateItem + 26, // 28: dapr.proto.runtime.v1.ExecuteStateTransactionRequest.operations:type_name -> dapr.proto.runtime.v1.TransactionalStateOperation + 103, // 29: dapr.proto.runtime.v1.ExecuteStateTransactionRequest.metadata:type_name -> dapr.proto.runtime.v1.ExecuteStateTransactionRequest.MetadataEntry + 36, // 30: dapr.proto.runtime.v1.ExecuteActorStateTransactionRequest.operations:type_name -> dapr.proto.runtime.v1.TransactionalActorStateOperation + 119, // 31: dapr.proto.runtime.v1.TransactionalActorStateOperation.value:type_name -> google.protobuf.Any + 104, // 32: dapr.proto.runtime.v1.TransactionalActorStateOperation.metadata:type_name -> dapr.proto.runtime.v1.TransactionalActorStateOperation.MetadataEntry + 105, // 33: dapr.proto.runtime.v1.InvokeActorRequest.metadata:type_name -> dapr.proto.runtime.v1.InvokeActorRequest.MetadataEntry + 40, // 34: dapr.proto.runtime.v1.GetMetadataResponse.active_actors_count:type_name -> dapr.proto.runtime.v1.ActiveActorsCount + 41, // 35: dapr.proto.runtime.v1.GetMetadataResponse.registered_components:type_name -> dapr.proto.runtime.v1.RegisteredComponents + 106, // 36: dapr.proto.runtime.v1.GetMetadataResponse.extended_metadata:type_name -> dapr.proto.runtime.v1.GetMetadataResponse.ExtendedMetadataEntry + 43, // 37: dapr.proto.runtime.v1.GetMetadataResponse.subscriptions:type_name -> dapr.proto.runtime.v1.PubsubSubscription + 42, // 38: dapr.proto.runtime.v1.GetMetadataResponse.http_endpoints:type_name -> dapr.proto.runtime.v1.MetadataHTTPEndpoint + 107, // 39: dapr.proto.runtime.v1.PubsubSubscription.metadata:type_name -> dapr.proto.runtime.v1.PubsubSubscription.MetadataEntry + 44, // 40: dapr.proto.runtime.v1.PubsubSubscription.rules:type_name -> dapr.proto.runtime.v1.PubsubSubscriptionRules + 45, // 41: dapr.proto.runtime.v1.PubsubSubscriptionRules.rules:type_name -> dapr.proto.runtime.v1.PubsubSubscriptionRule + 108, // 42: dapr.proto.runtime.v1.GetConfigurationRequest.metadata:type_name -> dapr.proto.runtime.v1.GetConfigurationRequest.MetadataEntry + 109, // 43: dapr.proto.runtime.v1.GetConfigurationResponse.items:type_name -> dapr.proto.runtime.v1.GetConfigurationResponse.ItemsEntry + 110, // 44: dapr.proto.runtime.v1.SubscribeConfigurationRequest.metadata:type_name -> dapr.proto.runtime.v1.SubscribeConfigurationRequest.MetadataEntry + 111, // 45: dapr.proto.runtime.v1.SubscribeConfigurationResponse.items:type_name -> dapr.proto.runtime.v1.SubscribeConfigurationResponse.ItemsEntry + 0, // 46: dapr.proto.runtime.v1.UnlockResponse.status:type_name -> dapr.proto.runtime.v1.UnlockResponse.Status + 1, // 47: dapr.proto.runtime.v1.SubtleGetKeyRequest.format:type_name -> dapr.proto.runtime.v1.SubtleGetKeyRequest.KeyFormat + 72, // 48: dapr.proto.runtime.v1.EncryptRequest.options:type_name -> dapr.proto.runtime.v1.EncryptRequestOptions + 120, // 49: dapr.proto.runtime.v1.EncryptRequest.payload:type_name -> dapr.proto.common.v1.StreamPayload + 120, // 50: dapr.proto.runtime.v1.EncryptResponse.payload:type_name -> dapr.proto.common.v1.StreamPayload + 75, // 51: dapr.proto.runtime.v1.DecryptRequest.options:type_name -> dapr.proto.runtime.v1.DecryptRequestOptions + 120, // 52: dapr.proto.runtime.v1.DecryptRequest.payload:type_name -> dapr.proto.common.v1.StreamPayload + 120, // 53: dapr.proto.runtime.v1.DecryptResponse.payload:type_name -> dapr.proto.common.v1.StreamPayload + 121, // 54: dapr.proto.runtime.v1.GetWorkflowResponse.created_at:type_name -> google.protobuf.Timestamp + 121, // 55: dapr.proto.runtime.v1.GetWorkflowResponse.last_updated_at:type_name -> google.protobuf.Timestamp + 112, // 56: dapr.proto.runtime.v1.GetWorkflowResponse.properties:type_name -> dapr.proto.runtime.v1.GetWorkflowResponse.PropertiesEntry + 113, // 57: dapr.proto.runtime.v1.StartWorkflowRequest.options:type_name -> dapr.proto.runtime.v1.StartWorkflowRequest.OptionsEntry + 24, // 58: dapr.proto.runtime.v1.GetBulkSecretResponse.DataEntry.value:type_name -> dapr.proto.runtime.v1.SecretResponse + 122, // 59: dapr.proto.runtime.v1.GetConfigurationResponse.ItemsEntry.value:type_name -> dapr.proto.common.v1.ConfigurationItem + 122, // 60: dapr.proto.runtime.v1.SubscribeConfigurationResponse.ItemsEntry.value:type_name -> dapr.proto.common.v1.ConfigurationItem + 2, // 61: dapr.proto.runtime.v1.Dapr.InvokeService:input_type -> dapr.proto.runtime.v1.InvokeServiceRequest + 3, // 62: dapr.proto.runtime.v1.Dapr.GetState:input_type -> dapr.proto.runtime.v1.GetStateRequest + 4, // 63: dapr.proto.runtime.v1.Dapr.GetBulkState:input_type -> dapr.proto.runtime.v1.GetBulkStateRequest + 10, // 64: dapr.proto.runtime.v1.Dapr.SaveState:input_type -> dapr.proto.runtime.v1.SaveStateRequest + 11, // 65: dapr.proto.runtime.v1.Dapr.QueryStateAlpha1:input_type -> dapr.proto.runtime.v1.QueryStateRequest + 8, // 66: dapr.proto.runtime.v1.Dapr.DeleteState:input_type -> dapr.proto.runtime.v1.DeleteStateRequest + 9, // 67: dapr.proto.runtime.v1.Dapr.DeleteBulkState:input_type -> dapr.proto.runtime.v1.DeleteBulkStateRequest + 27, // 68: dapr.proto.runtime.v1.Dapr.ExecuteStateTransaction:input_type -> dapr.proto.runtime.v1.ExecuteStateTransactionRequest + 14, // 69: dapr.proto.runtime.v1.Dapr.PublishEvent:input_type -> dapr.proto.runtime.v1.PublishEventRequest + 15, // 70: dapr.proto.runtime.v1.Dapr.BulkPublishEventAlpha1:input_type -> dapr.proto.runtime.v1.BulkPublishRequest + 19, // 71: dapr.proto.runtime.v1.Dapr.InvokeBinding:input_type -> dapr.proto.runtime.v1.InvokeBindingRequest + 21, // 72: dapr.proto.runtime.v1.Dapr.GetSecret:input_type -> dapr.proto.runtime.v1.GetSecretRequest + 23, // 73: dapr.proto.runtime.v1.Dapr.GetBulkSecret:input_type -> dapr.proto.runtime.v1.GetBulkSecretRequest + 28, // 74: dapr.proto.runtime.v1.Dapr.RegisterActorTimer:input_type -> dapr.proto.runtime.v1.RegisterActorTimerRequest + 29, // 75: dapr.proto.runtime.v1.Dapr.UnregisterActorTimer:input_type -> dapr.proto.runtime.v1.UnregisterActorTimerRequest + 30, // 76: dapr.proto.runtime.v1.Dapr.RegisterActorReminder:input_type -> dapr.proto.runtime.v1.RegisterActorReminderRequest + 31, // 77: dapr.proto.runtime.v1.Dapr.UnregisterActorReminder:input_type -> dapr.proto.runtime.v1.UnregisterActorReminderRequest + 32, // 78: dapr.proto.runtime.v1.Dapr.RenameActorReminder:input_type -> dapr.proto.runtime.v1.RenameActorReminderRequest + 33, // 79: dapr.proto.runtime.v1.Dapr.GetActorState:input_type -> dapr.proto.runtime.v1.GetActorStateRequest + 35, // 80: dapr.proto.runtime.v1.Dapr.ExecuteActorStateTransaction:input_type -> dapr.proto.runtime.v1.ExecuteActorStateTransactionRequest + 37, // 81: dapr.proto.runtime.v1.Dapr.InvokeActor:input_type -> dapr.proto.runtime.v1.InvokeActorRequest + 47, // 82: dapr.proto.runtime.v1.Dapr.GetConfigurationAlpha1:input_type -> dapr.proto.runtime.v1.GetConfigurationRequest + 47, // 83: dapr.proto.runtime.v1.Dapr.GetConfiguration:input_type -> dapr.proto.runtime.v1.GetConfigurationRequest + 49, // 84: dapr.proto.runtime.v1.Dapr.SubscribeConfigurationAlpha1:input_type -> dapr.proto.runtime.v1.SubscribeConfigurationRequest + 49, // 85: dapr.proto.runtime.v1.Dapr.SubscribeConfiguration:input_type -> dapr.proto.runtime.v1.SubscribeConfigurationRequest + 50, // 86: dapr.proto.runtime.v1.Dapr.UnsubscribeConfigurationAlpha1:input_type -> dapr.proto.runtime.v1.UnsubscribeConfigurationRequest + 50, // 87: dapr.proto.runtime.v1.Dapr.UnsubscribeConfiguration:input_type -> dapr.proto.runtime.v1.UnsubscribeConfigurationRequest + 53, // 88: dapr.proto.runtime.v1.Dapr.TryLockAlpha1:input_type -> dapr.proto.runtime.v1.TryLockRequest + 55, // 89: dapr.proto.runtime.v1.Dapr.UnlockAlpha1:input_type -> dapr.proto.runtime.v1.UnlockRequest + 71, // 90: dapr.proto.runtime.v1.Dapr.EncryptAlpha1:input_type -> dapr.proto.runtime.v1.EncryptRequest + 74, // 91: dapr.proto.runtime.v1.Dapr.DecryptAlpha1:input_type -> dapr.proto.runtime.v1.DecryptRequest + 123, // 92: dapr.proto.runtime.v1.Dapr.GetMetadata:input_type -> google.protobuf.Empty + 46, // 93: dapr.proto.runtime.v1.Dapr.SetMetadata:input_type -> dapr.proto.runtime.v1.SetMetadataRequest + 57, // 94: dapr.proto.runtime.v1.Dapr.SubtleGetKeyAlpha1:input_type -> dapr.proto.runtime.v1.SubtleGetKeyRequest + 59, // 95: dapr.proto.runtime.v1.Dapr.SubtleEncryptAlpha1:input_type -> dapr.proto.runtime.v1.SubtleEncryptRequest + 61, // 96: dapr.proto.runtime.v1.Dapr.SubtleDecryptAlpha1:input_type -> dapr.proto.runtime.v1.SubtleDecryptRequest + 63, // 97: dapr.proto.runtime.v1.Dapr.SubtleWrapKeyAlpha1:input_type -> dapr.proto.runtime.v1.SubtleWrapKeyRequest + 65, // 98: dapr.proto.runtime.v1.Dapr.SubtleUnwrapKeyAlpha1:input_type -> dapr.proto.runtime.v1.SubtleUnwrapKeyRequest + 67, // 99: dapr.proto.runtime.v1.Dapr.SubtleSignAlpha1:input_type -> dapr.proto.runtime.v1.SubtleSignRequest + 69, // 100: dapr.proto.runtime.v1.Dapr.SubtleVerifyAlpha1:input_type -> dapr.proto.runtime.v1.SubtleVerifyRequest + 79, // 101: dapr.proto.runtime.v1.Dapr.StartWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.StartWorkflowRequest + 77, // 102: dapr.proto.runtime.v1.Dapr.GetWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.GetWorkflowRequest + 85, // 103: dapr.proto.runtime.v1.Dapr.PurgeWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.PurgeWorkflowRequest + 81, // 104: dapr.proto.runtime.v1.Dapr.TerminateWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.TerminateWorkflowRequest + 82, // 105: dapr.proto.runtime.v1.Dapr.PauseWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.PauseWorkflowRequest + 83, // 106: dapr.proto.runtime.v1.Dapr.ResumeWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.ResumeWorkflowRequest + 84, // 107: dapr.proto.runtime.v1.Dapr.RaiseEventWorkflowAlpha1:input_type -> dapr.proto.runtime.v1.RaiseEventWorkflowRequest + 123, // 108: dapr.proto.runtime.v1.Dapr.Shutdown:input_type -> google.protobuf.Empty + 124, // 109: dapr.proto.runtime.v1.Dapr.InvokeService:output_type -> dapr.proto.common.v1.InvokeResponse + 7, // 110: dapr.proto.runtime.v1.Dapr.GetState:output_type -> dapr.proto.runtime.v1.GetStateResponse + 5, // 111: dapr.proto.runtime.v1.Dapr.GetBulkState:output_type -> dapr.proto.runtime.v1.GetBulkStateResponse + 123, // 112: dapr.proto.runtime.v1.Dapr.SaveState:output_type -> google.protobuf.Empty + 13, // 113: dapr.proto.runtime.v1.Dapr.QueryStateAlpha1:output_type -> dapr.proto.runtime.v1.QueryStateResponse + 123, // 114: dapr.proto.runtime.v1.Dapr.DeleteState:output_type -> google.protobuf.Empty + 123, // 115: dapr.proto.runtime.v1.Dapr.DeleteBulkState:output_type -> google.protobuf.Empty + 123, // 116: dapr.proto.runtime.v1.Dapr.ExecuteStateTransaction:output_type -> google.protobuf.Empty + 123, // 117: dapr.proto.runtime.v1.Dapr.PublishEvent:output_type -> google.protobuf.Empty + 17, // 118: dapr.proto.runtime.v1.Dapr.BulkPublishEventAlpha1:output_type -> dapr.proto.runtime.v1.BulkPublishResponse + 20, // 119: dapr.proto.runtime.v1.Dapr.InvokeBinding:output_type -> dapr.proto.runtime.v1.InvokeBindingResponse + 22, // 120: dapr.proto.runtime.v1.Dapr.GetSecret:output_type -> dapr.proto.runtime.v1.GetSecretResponse + 25, // 121: dapr.proto.runtime.v1.Dapr.GetBulkSecret:output_type -> dapr.proto.runtime.v1.GetBulkSecretResponse + 123, // 122: dapr.proto.runtime.v1.Dapr.RegisterActorTimer:output_type -> google.protobuf.Empty + 123, // 123: dapr.proto.runtime.v1.Dapr.UnregisterActorTimer:output_type -> google.protobuf.Empty + 123, // 124: dapr.proto.runtime.v1.Dapr.RegisterActorReminder:output_type -> google.protobuf.Empty + 123, // 125: dapr.proto.runtime.v1.Dapr.UnregisterActorReminder:output_type -> google.protobuf.Empty + 123, // 126: dapr.proto.runtime.v1.Dapr.RenameActorReminder:output_type -> google.protobuf.Empty + 34, // 127: dapr.proto.runtime.v1.Dapr.GetActorState:output_type -> dapr.proto.runtime.v1.GetActorStateResponse + 123, // 128: dapr.proto.runtime.v1.Dapr.ExecuteActorStateTransaction:output_type -> google.protobuf.Empty + 38, // 129: dapr.proto.runtime.v1.Dapr.InvokeActor:output_type -> dapr.proto.runtime.v1.InvokeActorResponse + 48, // 130: dapr.proto.runtime.v1.Dapr.GetConfigurationAlpha1:output_type -> dapr.proto.runtime.v1.GetConfigurationResponse + 48, // 131: dapr.proto.runtime.v1.Dapr.GetConfiguration:output_type -> dapr.proto.runtime.v1.GetConfigurationResponse + 51, // 132: dapr.proto.runtime.v1.Dapr.SubscribeConfigurationAlpha1:output_type -> dapr.proto.runtime.v1.SubscribeConfigurationResponse + 51, // 133: dapr.proto.runtime.v1.Dapr.SubscribeConfiguration:output_type -> dapr.proto.runtime.v1.SubscribeConfigurationResponse + 52, // 134: dapr.proto.runtime.v1.Dapr.UnsubscribeConfigurationAlpha1:output_type -> dapr.proto.runtime.v1.UnsubscribeConfigurationResponse + 52, // 135: dapr.proto.runtime.v1.Dapr.UnsubscribeConfiguration:output_type -> dapr.proto.runtime.v1.UnsubscribeConfigurationResponse + 54, // 136: dapr.proto.runtime.v1.Dapr.TryLockAlpha1:output_type -> dapr.proto.runtime.v1.TryLockResponse + 56, // 137: dapr.proto.runtime.v1.Dapr.UnlockAlpha1:output_type -> dapr.proto.runtime.v1.UnlockResponse + 73, // 138: dapr.proto.runtime.v1.Dapr.EncryptAlpha1:output_type -> dapr.proto.runtime.v1.EncryptResponse + 76, // 139: dapr.proto.runtime.v1.Dapr.DecryptAlpha1:output_type -> dapr.proto.runtime.v1.DecryptResponse + 39, // 140: dapr.proto.runtime.v1.Dapr.GetMetadata:output_type -> dapr.proto.runtime.v1.GetMetadataResponse + 123, // 141: dapr.proto.runtime.v1.Dapr.SetMetadata:output_type -> google.protobuf.Empty + 58, // 142: dapr.proto.runtime.v1.Dapr.SubtleGetKeyAlpha1:output_type -> dapr.proto.runtime.v1.SubtleGetKeyResponse + 60, // 143: dapr.proto.runtime.v1.Dapr.SubtleEncryptAlpha1:output_type -> dapr.proto.runtime.v1.SubtleEncryptResponse + 62, // 144: dapr.proto.runtime.v1.Dapr.SubtleDecryptAlpha1:output_type -> dapr.proto.runtime.v1.SubtleDecryptResponse + 64, // 145: dapr.proto.runtime.v1.Dapr.SubtleWrapKeyAlpha1:output_type -> dapr.proto.runtime.v1.SubtleWrapKeyResponse + 66, // 146: dapr.proto.runtime.v1.Dapr.SubtleUnwrapKeyAlpha1:output_type -> dapr.proto.runtime.v1.SubtleUnwrapKeyResponse + 68, // 147: dapr.proto.runtime.v1.Dapr.SubtleSignAlpha1:output_type -> dapr.proto.runtime.v1.SubtleSignResponse + 70, // 148: dapr.proto.runtime.v1.Dapr.SubtleVerifyAlpha1:output_type -> dapr.proto.runtime.v1.SubtleVerifyResponse + 80, // 149: dapr.proto.runtime.v1.Dapr.StartWorkflowAlpha1:output_type -> dapr.proto.runtime.v1.StartWorkflowResponse + 78, // 150: dapr.proto.runtime.v1.Dapr.GetWorkflowAlpha1:output_type -> dapr.proto.runtime.v1.GetWorkflowResponse + 123, // 151: dapr.proto.runtime.v1.Dapr.PurgeWorkflowAlpha1:output_type -> google.protobuf.Empty + 123, // 152: dapr.proto.runtime.v1.Dapr.TerminateWorkflowAlpha1:output_type -> google.protobuf.Empty + 123, // 153: dapr.proto.runtime.v1.Dapr.PauseWorkflowAlpha1:output_type -> google.protobuf.Empty + 123, // 154: dapr.proto.runtime.v1.Dapr.ResumeWorkflowAlpha1:output_type -> google.protobuf.Empty + 123, // 155: dapr.proto.runtime.v1.Dapr.RaiseEventWorkflowAlpha1:output_type -> google.protobuf.Empty + 123, // 156: dapr.proto.runtime.v1.Dapr.Shutdown:output_type -> google.protobuf.Empty + 109, // [109:157] is the sub-list for method output_type + 61, // [61:109] is the sub-list for method input_type + 61, // [61:61] is the sub-list for extension type_name + 61, // [61:61] is the sub-list for extension extendee + 0, // [0:61] is the sub-list for field type_name +} + +func init() { file_dapr_proto_runtime_v1_dapr_proto_init() } +func file_dapr_proto_runtime_v1_dapr_proto_init() { + if File_dapr_proto_runtime_v1_dapr_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeServiceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBulkStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBulkStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkStateItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteBulkStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SaveStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryStateItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublishEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkPublishRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkPublishRequestEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkPublishResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BulkPublishResponseFailedEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeBindingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeBindingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSecretRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSecretResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBulkSecretRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SecretResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBulkSecretResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TransactionalStateOperation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteStateTransactionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterActorTimerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnregisterActorTimerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterActorReminderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnregisterActorReminderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RenameActorReminderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetActorStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetActorStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteActorStateTransactionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TransactionalActorStateOperation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeActorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvokeActorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetMetadataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActiveActorsCount); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisteredComponents); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataHTTPEndpoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PubsubSubscription); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PubsubSubscriptionRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PubsubSubscriptionRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetMetadataRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetConfigurationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetConfigurationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubscribeConfigurationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnsubscribeConfigurationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubscribeConfigurationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnsubscribeConfigurationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TryLockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TryLockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnlockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleGetKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleGetKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleEncryptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleEncryptResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleDecryptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleDecryptResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleWrapKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleWrapKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleUnwrapKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleUnwrapKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleSignRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleSignResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleVerifyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubtleVerifyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EncryptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EncryptRequestOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EncryptResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DecryptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DecryptRequestOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DecryptResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkflowResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartWorkflowResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TerminateWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PauseWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResumeWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RaiseEventWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dapr_proto_runtime_v1_dapr_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PurgeWorkflowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dapr_proto_runtime_v1_dapr_proto_rawDesc, + NumEnums: 2, + NumMessages: 112, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_dapr_proto_runtime_v1_dapr_proto_goTypes, + DependencyIndexes: file_dapr_proto_runtime_v1_dapr_proto_depIdxs, + EnumInfos: file_dapr_proto_runtime_v1_dapr_proto_enumTypes, + MessageInfos: file_dapr_proto_runtime_v1_dapr_proto_msgTypes, + }.Build() + File_dapr_proto_runtime_v1_dapr_proto = out.File + file_dapr_proto_runtime_v1_dapr_proto_rawDesc = nil + file_dapr_proto_runtime_v1_dapr_proto_goTypes = nil + file_dapr_proto_runtime_v1_dapr_proto_depIdxs = nil +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_additional.go b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_additional.go new file mode 100644 index 00000000000..f122a1c15a9 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_additional.go @@ -0,0 +1,154 @@ +/* +Copyright 2023 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package runtime + +import ( + "google.golang.org/protobuf/proto" + + commonv1pb "github.com/dapr/go-sdk/dapr/proto/common/v1" +) + +// This file contains additional, hand-written methods added to the generated objects. + +// SubtleCryptoRequests is an interface for all Subtle*Request structs. +type SubtleCryptoRequests interface { + // SetComponentName sets the value of the ComponentName property. + SetComponentName(name string) +} + +func (x *SubtleGetKeyRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleEncryptRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleDecryptRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleWrapKeyRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleUnwrapKeyRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleSignRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +func (x *SubtleVerifyRequest) SetComponentName(name string) { + if x != nil { + x.ComponentName = name + } +} + +// CryptoRequests is an interface for EncryptRequest and DecryptRequest. +type CryptoRequests interface { + proto.Message + + // SetPayload sets the payload. + SetPayload(payload *commonv1pb.StreamPayload) + // GetPayload returns the payload. + GetPayload() *commonv1pb.StreamPayload + // Reset the object. + Reset() + // SetOptions sets the Options property. + SetOptions(opts proto.Message) + // HasOptions returns true if the Options property is not empty. + HasOptions() bool +} + +func (x *EncryptRequest) SetPayload(payload *commonv1pb.StreamPayload) { + if x == nil { + return + } + + x.Payload = payload +} + +func (x *EncryptRequest) SetOptions(opts proto.Message) { + if x == nil { + return + } + + x.Options = opts.(*EncryptRequestOptions) +} + +func (x *EncryptRequest) HasOptions() bool { + return x != nil && x.Options != nil +} + +func (x *DecryptRequest) SetPayload(payload *commonv1pb.StreamPayload) { + if x == nil { + return + } + + x.Payload = payload +} + +func (x *DecryptRequest) SetOptions(opts proto.Message) { + if x == nil { + return + } + + x.Options = opts.(*DecryptRequestOptions) +} + +func (x *DecryptRequest) HasOptions() bool { + return x != nil && x.Options != nil +} + +// CryptoResponses is an interface for EncryptResponse and DecryptResponse. +type CryptoResponses interface { + proto.Message + + // SetPayload sets the payload. + SetPayload(payload *commonv1pb.StreamPayload) + // GetPayload returns the payload. + GetPayload() *commonv1pb.StreamPayload + // Reset the object. + Reset() +} + +func (x *EncryptResponse) SetPayload(payload *commonv1pb.StreamPayload) { + if x == nil { + return + } + + x.Payload = payload +} + +func (x *DecryptResponse) SetPayload(payload *commonv1pb.StreamPayload) { + if x == nil { + return + } + + x.Payload = payload +} diff --git a/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_grpc.pb.go b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_grpc.pb.go new file mode 100644 index 00000000000..f3e9484feab --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/dapr/proto/runtime/v1/dapr_grpc.pb.go @@ -0,0 +1,2014 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: dapr/proto/runtime/v1/dapr.proto + +package runtime + +import ( + context "context" + v1 "github.com/dapr/go-sdk/dapr/proto/common/v1" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// DaprClient is the client API for Dapr service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DaprClient interface { + // Invokes a method on a remote Dapr app. + // Deprecated: Use proxy mode service invocation instead. + InvokeService(ctx context.Context, in *InvokeServiceRequest, opts ...grpc.CallOption) (*v1.InvokeResponse, error) + // Gets the state for a specific key. + GetState(ctx context.Context, in *GetStateRequest, opts ...grpc.CallOption) (*GetStateResponse, error) + // Gets a bulk of state items for a list of keys + GetBulkState(ctx context.Context, in *GetBulkStateRequest, opts ...grpc.CallOption) (*GetBulkStateResponse, error) + // Saves the state for a specific key. + SaveState(ctx context.Context, in *SaveStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Queries the state. + QueryStateAlpha1(ctx context.Context, in *QueryStateRequest, opts ...grpc.CallOption) (*QueryStateResponse, error) + // Deletes the state for a specific key. + DeleteState(ctx context.Context, in *DeleteStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Deletes a bulk of state items for a list of keys + DeleteBulkState(ctx context.Context, in *DeleteBulkStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Executes transactions for a specified store + ExecuteStateTransaction(ctx context.Context, in *ExecuteStateTransactionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Publishes events to the specific topic. + PublishEvent(ctx context.Context, in *PublishEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Bulk Publishes multiple events to the specified topic. + BulkPublishEventAlpha1(ctx context.Context, in *BulkPublishRequest, opts ...grpc.CallOption) (*BulkPublishResponse, error) + // Invokes binding data to specific output bindings + InvokeBinding(ctx context.Context, in *InvokeBindingRequest, opts ...grpc.CallOption) (*InvokeBindingResponse, error) + // Gets secrets from secret stores. + GetSecret(ctx context.Context, in *GetSecretRequest, opts ...grpc.CallOption) (*GetSecretResponse, error) + // Gets a bulk of secrets + GetBulkSecret(ctx context.Context, in *GetBulkSecretRequest, opts ...grpc.CallOption) (*GetBulkSecretResponse, error) + // Register an actor timer. + RegisterActorTimer(ctx context.Context, in *RegisterActorTimerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Unregister an actor timer. + UnregisterActorTimer(ctx context.Context, in *UnregisterActorTimerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Register an actor reminder. + RegisterActorReminder(ctx context.Context, in *RegisterActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Unregister an actor reminder. + UnregisterActorReminder(ctx context.Context, in *UnregisterActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Rename an actor reminder. + RenameActorReminder(ctx context.Context, in *RenameActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Gets the state for a specific actor. + GetActorState(ctx context.Context, in *GetActorStateRequest, opts ...grpc.CallOption) (*GetActorStateResponse, error) + // Executes state transactions for a specified actor + ExecuteActorStateTransaction(ctx context.Context, in *ExecuteActorStateTransactionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // InvokeActor calls a method on an actor. + InvokeActor(ctx context.Context, in *InvokeActorRequest, opts ...grpc.CallOption) (*InvokeActorResponse, error) + // GetConfiguration gets configuration from configuration store. + GetConfigurationAlpha1(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error) + // GetConfiguration gets configuration from configuration store. + GetConfiguration(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error) + // SubscribeConfiguration gets configuration from configuration store and subscribe the updates event by grpc stream + SubscribeConfigurationAlpha1(ctx context.Context, in *SubscribeConfigurationRequest, opts ...grpc.CallOption) (Dapr_SubscribeConfigurationAlpha1Client, error) + // SubscribeConfiguration gets configuration from configuration store and subscribe the updates event by grpc stream + SubscribeConfiguration(ctx context.Context, in *SubscribeConfigurationRequest, opts ...grpc.CallOption) (Dapr_SubscribeConfigurationClient, error) + // UnSubscribeConfiguration unsubscribe the subscription of configuration + UnsubscribeConfigurationAlpha1(ctx context.Context, in *UnsubscribeConfigurationRequest, opts ...grpc.CallOption) (*UnsubscribeConfigurationResponse, error) + // UnSubscribeConfiguration unsubscribe the subscription of configuration + UnsubscribeConfiguration(ctx context.Context, in *UnsubscribeConfigurationRequest, opts ...grpc.CallOption) (*UnsubscribeConfigurationResponse, error) + // TryLockAlpha1 tries to get a lock with an expiry. + TryLockAlpha1(ctx context.Context, in *TryLockRequest, opts ...grpc.CallOption) (*TryLockResponse, error) + // UnlockAlpha1 unlocks a lock. + UnlockAlpha1(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error) + // EncryptAlpha1 encrypts a message using the Dapr encryption scheme and a key stored in the vault. + EncryptAlpha1(ctx context.Context, opts ...grpc.CallOption) (Dapr_EncryptAlpha1Client, error) + // DecryptAlpha1 decrypts a message using the Dapr encryption scheme and a key stored in the vault. + DecryptAlpha1(ctx context.Context, opts ...grpc.CallOption) (Dapr_DecryptAlpha1Client, error) + // Gets metadata of the sidecar + GetMetadata(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetMetadataResponse, error) + // Sets value in extended metadata of the sidecar + SetMetadata(ctx context.Context, in *SetMetadataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // SubtleGetKeyAlpha1 returns the public part of an asymmetric key stored in the vault. + SubtleGetKeyAlpha1(ctx context.Context, in *SubtleGetKeyRequest, opts ...grpc.CallOption) (*SubtleGetKeyResponse, error) + // SubtleEncryptAlpha1 encrypts a small message using a key stored in the vault. + SubtleEncryptAlpha1(ctx context.Context, in *SubtleEncryptRequest, opts ...grpc.CallOption) (*SubtleEncryptResponse, error) + // SubtleDecryptAlpha1 decrypts a small message using a key stored in the vault. + SubtleDecryptAlpha1(ctx context.Context, in *SubtleDecryptRequest, opts ...grpc.CallOption) (*SubtleDecryptResponse, error) + // SubtleWrapKeyAlpha1 wraps a key using a key stored in the vault. + SubtleWrapKeyAlpha1(ctx context.Context, in *SubtleWrapKeyRequest, opts ...grpc.CallOption) (*SubtleWrapKeyResponse, error) + // SubtleUnwrapKeyAlpha1 unwraps a key using a key stored in the vault. + SubtleUnwrapKeyAlpha1(ctx context.Context, in *SubtleUnwrapKeyRequest, opts ...grpc.CallOption) (*SubtleUnwrapKeyResponse, error) + // SubtleSignAlpha1 signs a message using a key stored in the vault. + SubtleSignAlpha1(ctx context.Context, in *SubtleSignRequest, opts ...grpc.CallOption) (*SubtleSignResponse, error) + // SubtleVerifyAlpha1 verifies the signature of a message using a key stored in the vault. + SubtleVerifyAlpha1(ctx context.Context, in *SubtleVerifyRequest, opts ...grpc.CallOption) (*SubtleVerifyResponse, error) + // Starts a new instance of a workflow + StartWorkflowAlpha1(ctx context.Context, in *StartWorkflowRequest, opts ...grpc.CallOption) (*StartWorkflowResponse, error) + // Gets details about a started workflow instance + GetWorkflowAlpha1(ctx context.Context, in *GetWorkflowRequest, opts ...grpc.CallOption) (*GetWorkflowResponse, error) + // Purge Workflow + PurgeWorkflowAlpha1(ctx context.Context, in *PurgeWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Terminates a running workflow instance + TerminateWorkflowAlpha1(ctx context.Context, in *TerminateWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Pauses a running workflow instance + PauseWorkflowAlpha1(ctx context.Context, in *PauseWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Resumes a paused workflow instance + ResumeWorkflowAlpha1(ctx context.Context, in *ResumeWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Raise an event to a running workflow instance + RaiseEventWorkflowAlpha1(ctx context.Context, in *RaiseEventWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Shutdown the sidecar + Shutdown(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type daprClient struct { + cc grpc.ClientConnInterface +} + +func NewDaprClient(cc grpc.ClientConnInterface) DaprClient { + return &daprClient{cc} +} + +func (c *daprClient) InvokeService(ctx context.Context, in *InvokeServiceRequest, opts ...grpc.CallOption) (*v1.InvokeResponse, error) { + out := new(v1.InvokeResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/InvokeService", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetState(ctx context.Context, in *GetStateRequest, opts ...grpc.CallOption) (*GetStateResponse, error) { + out := new(GetStateResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetBulkState(ctx context.Context, in *GetBulkStateRequest, opts ...grpc.CallOption) (*GetBulkStateResponse, error) { + out := new(GetBulkStateResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetBulkState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SaveState(ctx context.Context, in *SaveStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SaveState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) QueryStateAlpha1(ctx context.Context, in *QueryStateRequest, opts ...grpc.CallOption) (*QueryStateResponse, error) { + out := new(QueryStateResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/QueryStateAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) DeleteState(ctx context.Context, in *DeleteStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/DeleteState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) DeleteBulkState(ctx context.Context, in *DeleteBulkStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/DeleteBulkState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) ExecuteStateTransaction(ctx context.Context, in *ExecuteStateTransactionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/ExecuteStateTransaction", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) PublishEvent(ctx context.Context, in *PublishEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/PublishEvent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) BulkPublishEventAlpha1(ctx context.Context, in *BulkPublishRequest, opts ...grpc.CallOption) (*BulkPublishResponse, error) { + out := new(BulkPublishResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/BulkPublishEventAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) InvokeBinding(ctx context.Context, in *InvokeBindingRequest, opts ...grpc.CallOption) (*InvokeBindingResponse, error) { + out := new(InvokeBindingResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/InvokeBinding", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetSecret(ctx context.Context, in *GetSecretRequest, opts ...grpc.CallOption) (*GetSecretResponse, error) { + out := new(GetSecretResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetSecret", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetBulkSecret(ctx context.Context, in *GetBulkSecretRequest, opts ...grpc.CallOption) (*GetBulkSecretResponse, error) { + out := new(GetBulkSecretResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetBulkSecret", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) RegisterActorTimer(ctx context.Context, in *RegisterActorTimerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/RegisterActorTimer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) UnregisterActorTimer(ctx context.Context, in *UnregisterActorTimerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/UnregisterActorTimer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) RegisterActorReminder(ctx context.Context, in *RegisterActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/RegisterActorReminder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) UnregisterActorReminder(ctx context.Context, in *UnregisterActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/UnregisterActorReminder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) RenameActorReminder(ctx context.Context, in *RenameActorReminderRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/RenameActorReminder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetActorState(ctx context.Context, in *GetActorStateRequest, opts ...grpc.CallOption) (*GetActorStateResponse, error) { + out := new(GetActorStateResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetActorState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) ExecuteActorStateTransaction(ctx context.Context, in *ExecuteActorStateTransactionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/ExecuteActorStateTransaction", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) InvokeActor(ctx context.Context, in *InvokeActorRequest, opts ...grpc.CallOption) (*InvokeActorResponse, error) { + out := new(InvokeActorResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/InvokeActor", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetConfigurationAlpha1(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error) { + out := new(GetConfigurationResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetConfigurationAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetConfiguration(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error) { + out := new(GetConfigurationResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetConfiguration", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubscribeConfigurationAlpha1(ctx context.Context, in *SubscribeConfigurationRequest, opts ...grpc.CallOption) (Dapr_SubscribeConfigurationAlpha1Client, error) { + stream, err := c.cc.NewStream(ctx, &Dapr_ServiceDesc.Streams[0], "/dapr.proto.runtime.v1.Dapr/SubscribeConfigurationAlpha1", opts...) + if err != nil { + return nil, err + } + x := &daprSubscribeConfigurationAlpha1Client{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Dapr_SubscribeConfigurationAlpha1Client interface { + Recv() (*SubscribeConfigurationResponse, error) + grpc.ClientStream +} + +type daprSubscribeConfigurationAlpha1Client struct { + grpc.ClientStream +} + +func (x *daprSubscribeConfigurationAlpha1Client) Recv() (*SubscribeConfigurationResponse, error) { + m := new(SubscribeConfigurationResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *daprClient) SubscribeConfiguration(ctx context.Context, in *SubscribeConfigurationRequest, opts ...grpc.CallOption) (Dapr_SubscribeConfigurationClient, error) { + stream, err := c.cc.NewStream(ctx, &Dapr_ServiceDesc.Streams[1], "/dapr.proto.runtime.v1.Dapr/SubscribeConfiguration", opts...) + if err != nil { + return nil, err + } + x := &daprSubscribeConfigurationClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Dapr_SubscribeConfigurationClient interface { + Recv() (*SubscribeConfigurationResponse, error) + grpc.ClientStream +} + +type daprSubscribeConfigurationClient struct { + grpc.ClientStream +} + +func (x *daprSubscribeConfigurationClient) Recv() (*SubscribeConfigurationResponse, error) { + m := new(SubscribeConfigurationResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *daprClient) UnsubscribeConfigurationAlpha1(ctx context.Context, in *UnsubscribeConfigurationRequest, opts ...grpc.CallOption) (*UnsubscribeConfigurationResponse, error) { + out := new(UnsubscribeConfigurationResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/UnsubscribeConfigurationAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) UnsubscribeConfiguration(ctx context.Context, in *UnsubscribeConfigurationRequest, opts ...grpc.CallOption) (*UnsubscribeConfigurationResponse, error) { + out := new(UnsubscribeConfigurationResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/UnsubscribeConfiguration", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) TryLockAlpha1(ctx context.Context, in *TryLockRequest, opts ...grpc.CallOption) (*TryLockResponse, error) { + out := new(TryLockResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/TryLockAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) UnlockAlpha1(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error) { + out := new(UnlockResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/UnlockAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) EncryptAlpha1(ctx context.Context, opts ...grpc.CallOption) (Dapr_EncryptAlpha1Client, error) { + stream, err := c.cc.NewStream(ctx, &Dapr_ServiceDesc.Streams[2], "/dapr.proto.runtime.v1.Dapr/EncryptAlpha1", opts...) + if err != nil { + return nil, err + } + x := &daprEncryptAlpha1Client{stream} + return x, nil +} + +type Dapr_EncryptAlpha1Client interface { + Send(*EncryptRequest) error + Recv() (*EncryptResponse, error) + grpc.ClientStream +} + +type daprEncryptAlpha1Client struct { + grpc.ClientStream +} + +func (x *daprEncryptAlpha1Client) Send(m *EncryptRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *daprEncryptAlpha1Client) Recv() (*EncryptResponse, error) { + m := new(EncryptResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *daprClient) DecryptAlpha1(ctx context.Context, opts ...grpc.CallOption) (Dapr_DecryptAlpha1Client, error) { + stream, err := c.cc.NewStream(ctx, &Dapr_ServiceDesc.Streams[3], "/dapr.proto.runtime.v1.Dapr/DecryptAlpha1", opts...) + if err != nil { + return nil, err + } + x := &daprDecryptAlpha1Client{stream} + return x, nil +} + +type Dapr_DecryptAlpha1Client interface { + Send(*DecryptRequest) error + Recv() (*DecryptResponse, error) + grpc.ClientStream +} + +type daprDecryptAlpha1Client struct { + grpc.ClientStream +} + +func (x *daprDecryptAlpha1Client) Send(m *DecryptRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *daprDecryptAlpha1Client) Recv() (*DecryptResponse, error) { + m := new(DecryptResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *daprClient) GetMetadata(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetMetadataResponse, error) { + out := new(GetMetadataResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SetMetadata(ctx context.Context, in *SetMetadataRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SetMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleGetKeyAlpha1(ctx context.Context, in *SubtleGetKeyRequest, opts ...grpc.CallOption) (*SubtleGetKeyResponse, error) { + out := new(SubtleGetKeyResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleGetKeyAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleEncryptAlpha1(ctx context.Context, in *SubtleEncryptRequest, opts ...grpc.CallOption) (*SubtleEncryptResponse, error) { + out := new(SubtleEncryptResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleEncryptAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleDecryptAlpha1(ctx context.Context, in *SubtleDecryptRequest, opts ...grpc.CallOption) (*SubtleDecryptResponse, error) { + out := new(SubtleDecryptResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleDecryptAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleWrapKeyAlpha1(ctx context.Context, in *SubtleWrapKeyRequest, opts ...grpc.CallOption) (*SubtleWrapKeyResponse, error) { + out := new(SubtleWrapKeyResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleWrapKeyAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleUnwrapKeyAlpha1(ctx context.Context, in *SubtleUnwrapKeyRequest, opts ...grpc.CallOption) (*SubtleUnwrapKeyResponse, error) { + out := new(SubtleUnwrapKeyResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleUnwrapKeyAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleSignAlpha1(ctx context.Context, in *SubtleSignRequest, opts ...grpc.CallOption) (*SubtleSignResponse, error) { + out := new(SubtleSignResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleSignAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) SubtleVerifyAlpha1(ctx context.Context, in *SubtleVerifyRequest, opts ...grpc.CallOption) (*SubtleVerifyResponse, error) { + out := new(SubtleVerifyResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/SubtleVerifyAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) StartWorkflowAlpha1(ctx context.Context, in *StartWorkflowRequest, opts ...grpc.CallOption) (*StartWorkflowResponse, error) { + out := new(StartWorkflowResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/StartWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) GetWorkflowAlpha1(ctx context.Context, in *GetWorkflowRequest, opts ...grpc.CallOption) (*GetWorkflowResponse, error) { + out := new(GetWorkflowResponse) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/GetWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) PurgeWorkflowAlpha1(ctx context.Context, in *PurgeWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/PurgeWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) TerminateWorkflowAlpha1(ctx context.Context, in *TerminateWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/TerminateWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) PauseWorkflowAlpha1(ctx context.Context, in *PauseWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/PauseWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) ResumeWorkflowAlpha1(ctx context.Context, in *ResumeWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/ResumeWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) RaiseEventWorkflowAlpha1(ctx context.Context, in *RaiseEventWorkflowRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/RaiseEventWorkflowAlpha1", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *daprClient) Shutdown(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/dapr.proto.runtime.v1.Dapr/Shutdown", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DaprServer is the server API for Dapr service. +// All implementations should embed UnimplementedDaprServer +// for forward compatibility +type DaprServer interface { + // Invokes a method on a remote Dapr app. + // Deprecated: Use proxy mode service invocation instead. + InvokeService(context.Context, *InvokeServiceRequest) (*v1.InvokeResponse, error) + // Gets the state for a specific key. + GetState(context.Context, *GetStateRequest) (*GetStateResponse, error) + // Gets a bulk of state items for a list of keys + GetBulkState(context.Context, *GetBulkStateRequest) (*GetBulkStateResponse, error) + // Saves the state for a specific key. + SaveState(context.Context, *SaveStateRequest) (*emptypb.Empty, error) + // Queries the state. + QueryStateAlpha1(context.Context, *QueryStateRequest) (*QueryStateResponse, error) + // Deletes the state for a specific key. + DeleteState(context.Context, *DeleteStateRequest) (*emptypb.Empty, error) + // Deletes a bulk of state items for a list of keys + DeleteBulkState(context.Context, *DeleteBulkStateRequest) (*emptypb.Empty, error) + // Executes transactions for a specified store + ExecuteStateTransaction(context.Context, *ExecuteStateTransactionRequest) (*emptypb.Empty, error) + // Publishes events to the specific topic. + PublishEvent(context.Context, *PublishEventRequest) (*emptypb.Empty, error) + // Bulk Publishes multiple events to the specified topic. + BulkPublishEventAlpha1(context.Context, *BulkPublishRequest) (*BulkPublishResponse, error) + // Invokes binding data to specific output bindings + InvokeBinding(context.Context, *InvokeBindingRequest) (*InvokeBindingResponse, error) + // Gets secrets from secret stores. + GetSecret(context.Context, *GetSecretRequest) (*GetSecretResponse, error) + // Gets a bulk of secrets + GetBulkSecret(context.Context, *GetBulkSecretRequest) (*GetBulkSecretResponse, error) + // Register an actor timer. + RegisterActorTimer(context.Context, *RegisterActorTimerRequest) (*emptypb.Empty, error) + // Unregister an actor timer. + UnregisterActorTimer(context.Context, *UnregisterActorTimerRequest) (*emptypb.Empty, error) + // Register an actor reminder. + RegisterActorReminder(context.Context, *RegisterActorReminderRequest) (*emptypb.Empty, error) + // Unregister an actor reminder. + UnregisterActorReminder(context.Context, *UnregisterActorReminderRequest) (*emptypb.Empty, error) + // Rename an actor reminder. + RenameActorReminder(context.Context, *RenameActorReminderRequest) (*emptypb.Empty, error) + // Gets the state for a specific actor. + GetActorState(context.Context, *GetActorStateRequest) (*GetActorStateResponse, error) + // Executes state transactions for a specified actor + ExecuteActorStateTransaction(context.Context, *ExecuteActorStateTransactionRequest) (*emptypb.Empty, error) + // InvokeActor calls a method on an actor. + InvokeActor(context.Context, *InvokeActorRequest) (*InvokeActorResponse, error) + // GetConfiguration gets configuration from configuration store. + GetConfigurationAlpha1(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error) + // GetConfiguration gets configuration from configuration store. + GetConfiguration(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error) + // SubscribeConfiguration gets configuration from configuration store and subscribe the updates event by grpc stream + SubscribeConfigurationAlpha1(*SubscribeConfigurationRequest, Dapr_SubscribeConfigurationAlpha1Server) error + // SubscribeConfiguration gets configuration from configuration store and subscribe the updates event by grpc stream + SubscribeConfiguration(*SubscribeConfigurationRequest, Dapr_SubscribeConfigurationServer) error + // UnSubscribeConfiguration unsubscribe the subscription of configuration + UnsubscribeConfigurationAlpha1(context.Context, *UnsubscribeConfigurationRequest) (*UnsubscribeConfigurationResponse, error) + // UnSubscribeConfiguration unsubscribe the subscription of configuration + UnsubscribeConfiguration(context.Context, *UnsubscribeConfigurationRequest) (*UnsubscribeConfigurationResponse, error) + // TryLockAlpha1 tries to get a lock with an expiry. + TryLockAlpha1(context.Context, *TryLockRequest) (*TryLockResponse, error) + // UnlockAlpha1 unlocks a lock. + UnlockAlpha1(context.Context, *UnlockRequest) (*UnlockResponse, error) + // EncryptAlpha1 encrypts a message using the Dapr encryption scheme and a key stored in the vault. + EncryptAlpha1(Dapr_EncryptAlpha1Server) error + // DecryptAlpha1 decrypts a message using the Dapr encryption scheme and a key stored in the vault. + DecryptAlpha1(Dapr_DecryptAlpha1Server) error + // Gets metadata of the sidecar + GetMetadata(context.Context, *emptypb.Empty) (*GetMetadataResponse, error) + // Sets value in extended metadata of the sidecar + SetMetadata(context.Context, *SetMetadataRequest) (*emptypb.Empty, error) + // SubtleGetKeyAlpha1 returns the public part of an asymmetric key stored in the vault. + SubtleGetKeyAlpha1(context.Context, *SubtleGetKeyRequest) (*SubtleGetKeyResponse, error) + // SubtleEncryptAlpha1 encrypts a small message using a key stored in the vault. + SubtleEncryptAlpha1(context.Context, *SubtleEncryptRequest) (*SubtleEncryptResponse, error) + // SubtleDecryptAlpha1 decrypts a small message using a key stored in the vault. + SubtleDecryptAlpha1(context.Context, *SubtleDecryptRequest) (*SubtleDecryptResponse, error) + // SubtleWrapKeyAlpha1 wraps a key using a key stored in the vault. + SubtleWrapKeyAlpha1(context.Context, *SubtleWrapKeyRequest) (*SubtleWrapKeyResponse, error) + // SubtleUnwrapKeyAlpha1 unwraps a key using a key stored in the vault. + SubtleUnwrapKeyAlpha1(context.Context, *SubtleUnwrapKeyRequest) (*SubtleUnwrapKeyResponse, error) + // SubtleSignAlpha1 signs a message using a key stored in the vault. + SubtleSignAlpha1(context.Context, *SubtleSignRequest) (*SubtleSignResponse, error) + // SubtleVerifyAlpha1 verifies the signature of a message using a key stored in the vault. + SubtleVerifyAlpha1(context.Context, *SubtleVerifyRequest) (*SubtleVerifyResponse, error) + // Starts a new instance of a workflow + StartWorkflowAlpha1(context.Context, *StartWorkflowRequest) (*StartWorkflowResponse, error) + // Gets details about a started workflow instance + GetWorkflowAlpha1(context.Context, *GetWorkflowRequest) (*GetWorkflowResponse, error) + // Purge Workflow + PurgeWorkflowAlpha1(context.Context, *PurgeWorkflowRequest) (*emptypb.Empty, error) + // Terminates a running workflow instance + TerminateWorkflowAlpha1(context.Context, *TerminateWorkflowRequest) (*emptypb.Empty, error) + // Pauses a running workflow instance + PauseWorkflowAlpha1(context.Context, *PauseWorkflowRequest) (*emptypb.Empty, error) + // Resumes a paused workflow instance + ResumeWorkflowAlpha1(context.Context, *ResumeWorkflowRequest) (*emptypb.Empty, error) + // Raise an event to a running workflow instance + RaiseEventWorkflowAlpha1(context.Context, *RaiseEventWorkflowRequest) (*emptypb.Empty, error) + // Shutdown the sidecar + Shutdown(context.Context, *emptypb.Empty) (*emptypb.Empty, error) +} + +// UnimplementedDaprServer should be embedded to have forward compatible implementations. +type UnimplementedDaprServer struct { +} + +func (UnimplementedDaprServer) InvokeService(context.Context, *InvokeServiceRequest) (*v1.InvokeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InvokeService not implemented") +} +func (UnimplementedDaprServer) GetState(context.Context, *GetStateRequest) (*GetStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetState not implemented") +} +func (UnimplementedDaprServer) GetBulkState(context.Context, *GetBulkStateRequest) (*GetBulkStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBulkState not implemented") +} +func (UnimplementedDaprServer) SaveState(context.Context, *SaveStateRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SaveState not implemented") +} +func (UnimplementedDaprServer) QueryStateAlpha1(context.Context, *QueryStateRequest) (*QueryStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryStateAlpha1 not implemented") +} +func (UnimplementedDaprServer) DeleteState(context.Context, *DeleteStateRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteState not implemented") +} +func (UnimplementedDaprServer) DeleteBulkState(context.Context, *DeleteBulkStateRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteBulkState not implemented") +} +func (UnimplementedDaprServer) ExecuteStateTransaction(context.Context, *ExecuteStateTransactionRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteStateTransaction not implemented") +} +func (UnimplementedDaprServer) PublishEvent(context.Context, *PublishEventRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method PublishEvent not implemented") +} +func (UnimplementedDaprServer) BulkPublishEventAlpha1(context.Context, *BulkPublishRequest) (*BulkPublishResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BulkPublishEventAlpha1 not implemented") +} +func (UnimplementedDaprServer) InvokeBinding(context.Context, *InvokeBindingRequest) (*InvokeBindingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InvokeBinding not implemented") +} +func (UnimplementedDaprServer) GetSecret(context.Context, *GetSecretRequest) (*GetSecretResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSecret not implemented") +} +func (UnimplementedDaprServer) GetBulkSecret(context.Context, *GetBulkSecretRequest) (*GetBulkSecretResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBulkSecret not implemented") +} +func (UnimplementedDaprServer) RegisterActorTimer(context.Context, *RegisterActorTimerRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterActorTimer not implemented") +} +func (UnimplementedDaprServer) UnregisterActorTimer(context.Context, *UnregisterActorTimerRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnregisterActorTimer not implemented") +} +func (UnimplementedDaprServer) RegisterActorReminder(context.Context, *RegisterActorReminderRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterActorReminder not implemented") +} +func (UnimplementedDaprServer) UnregisterActorReminder(context.Context, *UnregisterActorReminderRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnregisterActorReminder not implemented") +} +func (UnimplementedDaprServer) RenameActorReminder(context.Context, *RenameActorReminderRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RenameActorReminder not implemented") +} +func (UnimplementedDaprServer) GetActorState(context.Context, *GetActorStateRequest) (*GetActorStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetActorState not implemented") +} +func (UnimplementedDaprServer) ExecuteActorStateTransaction(context.Context, *ExecuteActorStateTransactionRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteActorStateTransaction not implemented") +} +func (UnimplementedDaprServer) InvokeActor(context.Context, *InvokeActorRequest) (*InvokeActorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InvokeActor not implemented") +} +func (UnimplementedDaprServer) GetConfigurationAlpha1(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetConfigurationAlpha1 not implemented") +} +func (UnimplementedDaprServer) GetConfiguration(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetConfiguration not implemented") +} +func (UnimplementedDaprServer) SubscribeConfigurationAlpha1(*SubscribeConfigurationRequest, Dapr_SubscribeConfigurationAlpha1Server) error { + return status.Errorf(codes.Unimplemented, "method SubscribeConfigurationAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubscribeConfiguration(*SubscribeConfigurationRequest, Dapr_SubscribeConfigurationServer) error { + return status.Errorf(codes.Unimplemented, "method SubscribeConfiguration not implemented") +} +func (UnimplementedDaprServer) UnsubscribeConfigurationAlpha1(context.Context, *UnsubscribeConfigurationRequest) (*UnsubscribeConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnsubscribeConfigurationAlpha1 not implemented") +} +func (UnimplementedDaprServer) UnsubscribeConfiguration(context.Context, *UnsubscribeConfigurationRequest) (*UnsubscribeConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnsubscribeConfiguration not implemented") +} +func (UnimplementedDaprServer) TryLockAlpha1(context.Context, *TryLockRequest) (*TryLockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TryLockAlpha1 not implemented") +} +func (UnimplementedDaprServer) UnlockAlpha1(context.Context, *UnlockRequest) (*UnlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnlockAlpha1 not implemented") +} +func (UnimplementedDaprServer) EncryptAlpha1(Dapr_EncryptAlpha1Server) error { + return status.Errorf(codes.Unimplemented, "method EncryptAlpha1 not implemented") +} +func (UnimplementedDaprServer) DecryptAlpha1(Dapr_DecryptAlpha1Server) error { + return status.Errorf(codes.Unimplemented, "method DecryptAlpha1 not implemented") +} +func (UnimplementedDaprServer) GetMetadata(context.Context, *emptypb.Empty) (*GetMetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMetadata not implemented") +} +func (UnimplementedDaprServer) SetMetadata(context.Context, *SetMetadataRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMetadata not implemented") +} +func (UnimplementedDaprServer) SubtleGetKeyAlpha1(context.Context, *SubtleGetKeyRequest) (*SubtleGetKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleGetKeyAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleEncryptAlpha1(context.Context, *SubtleEncryptRequest) (*SubtleEncryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleEncryptAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleDecryptAlpha1(context.Context, *SubtleDecryptRequest) (*SubtleDecryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleDecryptAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleWrapKeyAlpha1(context.Context, *SubtleWrapKeyRequest) (*SubtleWrapKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleWrapKeyAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleUnwrapKeyAlpha1(context.Context, *SubtleUnwrapKeyRequest) (*SubtleUnwrapKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleUnwrapKeyAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleSignAlpha1(context.Context, *SubtleSignRequest) (*SubtleSignResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleSignAlpha1 not implemented") +} +func (UnimplementedDaprServer) SubtleVerifyAlpha1(context.Context, *SubtleVerifyRequest) (*SubtleVerifyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubtleVerifyAlpha1 not implemented") +} +func (UnimplementedDaprServer) StartWorkflowAlpha1(context.Context, *StartWorkflowRequest) (*StartWorkflowResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) GetWorkflowAlpha1(context.Context, *GetWorkflowRequest) (*GetWorkflowResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) PurgeWorkflowAlpha1(context.Context, *PurgeWorkflowRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method PurgeWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) TerminateWorkflowAlpha1(context.Context, *TerminateWorkflowRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TerminateWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) PauseWorkflowAlpha1(context.Context, *PauseWorkflowRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method PauseWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) ResumeWorkflowAlpha1(context.Context, *ResumeWorkflowRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResumeWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) RaiseEventWorkflowAlpha1(context.Context, *RaiseEventWorkflowRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RaiseEventWorkflowAlpha1 not implemented") +} +func (UnimplementedDaprServer) Shutdown(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented") +} + +// UnsafeDaprServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DaprServer will +// result in compilation errors. +type UnsafeDaprServer interface { + mustEmbedUnimplementedDaprServer() +} + +func RegisterDaprServer(s grpc.ServiceRegistrar, srv DaprServer) { + s.RegisterService(&Dapr_ServiceDesc, srv) +} + +func _Dapr_InvokeService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InvokeServiceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).InvokeService(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/InvokeService", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).InvokeService(ctx, req.(*InvokeServiceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetState(ctx, req.(*GetStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetBulkState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBulkStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetBulkState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetBulkState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetBulkState(ctx, req.(*GetBulkStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SaveState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SaveStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SaveState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SaveState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SaveState(ctx, req.(*SaveStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_QueryStateAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).QueryStateAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/QueryStateAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).QueryStateAlpha1(ctx, req.(*QueryStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_DeleteState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).DeleteState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/DeleteState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).DeleteState(ctx, req.(*DeleteStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_DeleteBulkState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteBulkStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).DeleteBulkState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/DeleteBulkState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).DeleteBulkState(ctx, req.(*DeleteBulkStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_ExecuteStateTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteStateTransactionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).ExecuteStateTransaction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/ExecuteStateTransaction", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).ExecuteStateTransaction(ctx, req.(*ExecuteStateTransactionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_PublishEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PublishEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).PublishEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/PublishEvent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).PublishEvent(ctx, req.(*PublishEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_BulkPublishEventAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BulkPublishRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).BulkPublishEventAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/BulkPublishEventAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).BulkPublishEventAlpha1(ctx, req.(*BulkPublishRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_InvokeBinding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InvokeBindingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).InvokeBinding(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/InvokeBinding", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).InvokeBinding(ctx, req.(*InvokeBindingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSecretRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetSecret(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetSecret", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetSecret(ctx, req.(*GetSecretRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetBulkSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBulkSecretRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetBulkSecret(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetBulkSecret", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetBulkSecret(ctx, req.(*GetBulkSecretRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_RegisterActorTimer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterActorTimerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).RegisterActorTimer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/RegisterActorTimer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).RegisterActorTimer(ctx, req.(*RegisterActorTimerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_UnregisterActorTimer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnregisterActorTimerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).UnregisterActorTimer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/UnregisterActorTimer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).UnregisterActorTimer(ctx, req.(*UnregisterActorTimerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_RegisterActorReminder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterActorReminderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).RegisterActorReminder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/RegisterActorReminder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).RegisterActorReminder(ctx, req.(*RegisterActorReminderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_UnregisterActorReminder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnregisterActorReminderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).UnregisterActorReminder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/UnregisterActorReminder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).UnregisterActorReminder(ctx, req.(*UnregisterActorReminderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_RenameActorReminder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RenameActorReminderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).RenameActorReminder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/RenameActorReminder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).RenameActorReminder(ctx, req.(*RenameActorReminderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetActorState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetActorStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetActorState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetActorState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetActorState(ctx, req.(*GetActorStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_ExecuteActorStateTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteActorStateTransactionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).ExecuteActorStateTransaction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/ExecuteActorStateTransaction", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).ExecuteActorStateTransaction(ctx, req.(*ExecuteActorStateTransactionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_InvokeActor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InvokeActorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).InvokeActor(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/InvokeActor", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).InvokeActor(ctx, req.(*InvokeActorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetConfigurationAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetConfigurationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetConfigurationAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetConfigurationAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetConfigurationAlpha1(ctx, req.(*GetConfigurationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetConfigurationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetConfiguration(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetConfiguration", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetConfiguration(ctx, req.(*GetConfigurationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubscribeConfigurationAlpha1_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SubscribeConfigurationRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(DaprServer).SubscribeConfigurationAlpha1(m, &daprSubscribeConfigurationAlpha1Server{stream}) +} + +type Dapr_SubscribeConfigurationAlpha1Server interface { + Send(*SubscribeConfigurationResponse) error + grpc.ServerStream +} + +type daprSubscribeConfigurationAlpha1Server struct { + grpc.ServerStream +} + +func (x *daprSubscribeConfigurationAlpha1Server) Send(m *SubscribeConfigurationResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Dapr_SubscribeConfiguration_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SubscribeConfigurationRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(DaprServer).SubscribeConfiguration(m, &daprSubscribeConfigurationServer{stream}) +} + +type Dapr_SubscribeConfigurationServer interface { + Send(*SubscribeConfigurationResponse) error + grpc.ServerStream +} + +type daprSubscribeConfigurationServer struct { + grpc.ServerStream +} + +func (x *daprSubscribeConfigurationServer) Send(m *SubscribeConfigurationResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Dapr_UnsubscribeConfigurationAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnsubscribeConfigurationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).UnsubscribeConfigurationAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/UnsubscribeConfigurationAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).UnsubscribeConfigurationAlpha1(ctx, req.(*UnsubscribeConfigurationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_UnsubscribeConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnsubscribeConfigurationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).UnsubscribeConfiguration(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/UnsubscribeConfiguration", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).UnsubscribeConfiguration(ctx, req.(*UnsubscribeConfigurationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_TryLockAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TryLockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).TryLockAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/TryLockAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).TryLockAlpha1(ctx, req.(*TryLockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_UnlockAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).UnlockAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/UnlockAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).UnlockAlpha1(ctx, req.(*UnlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_EncryptAlpha1_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(DaprServer).EncryptAlpha1(&daprEncryptAlpha1Server{stream}) +} + +type Dapr_EncryptAlpha1Server interface { + Send(*EncryptResponse) error + Recv() (*EncryptRequest, error) + grpc.ServerStream +} + +type daprEncryptAlpha1Server struct { + grpc.ServerStream +} + +func (x *daprEncryptAlpha1Server) Send(m *EncryptResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *daprEncryptAlpha1Server) Recv() (*EncryptRequest, error) { + m := new(EncryptRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Dapr_DecryptAlpha1_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(DaprServer).DecryptAlpha1(&daprDecryptAlpha1Server{stream}) +} + +type Dapr_DecryptAlpha1Server interface { + Send(*DecryptResponse) error + Recv() (*DecryptRequest, error) + grpc.ServerStream +} + +type daprDecryptAlpha1Server struct { + grpc.ServerStream +} + +func (x *daprDecryptAlpha1Server) Send(m *DecryptResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *daprDecryptAlpha1Server) Recv() (*DecryptRequest, error) { + m := new(DecryptRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Dapr_GetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetMetadata(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetMetadataRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SetMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SetMetadata(ctx, req.(*SetMetadataRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleGetKeyAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleGetKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleGetKeyAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleGetKeyAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleGetKeyAlpha1(ctx, req.(*SubtleGetKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleEncryptAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleEncryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleEncryptAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleEncryptAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleEncryptAlpha1(ctx, req.(*SubtleEncryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleDecryptAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleDecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleDecryptAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleDecryptAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleDecryptAlpha1(ctx, req.(*SubtleDecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleWrapKeyAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleWrapKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleWrapKeyAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleWrapKeyAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleWrapKeyAlpha1(ctx, req.(*SubtleWrapKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleUnwrapKeyAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleUnwrapKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleUnwrapKeyAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleUnwrapKeyAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleUnwrapKeyAlpha1(ctx, req.(*SubtleUnwrapKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleSignAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleSignRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleSignAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleSignAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleSignAlpha1(ctx, req.(*SubtleSignRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_SubtleVerifyAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubtleVerifyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).SubtleVerifyAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/SubtleVerifyAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).SubtleVerifyAlpha1(ctx, req.(*SubtleVerifyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_StartWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StartWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).StartWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/StartWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).StartWorkflowAlpha1(ctx, req.(*StartWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_GetWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).GetWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/GetWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).GetWorkflowAlpha1(ctx, req.(*GetWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_PurgeWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PurgeWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).PurgeWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/PurgeWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).PurgeWorkflowAlpha1(ctx, req.(*PurgeWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_TerminateWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TerminateWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).TerminateWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/TerminateWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).TerminateWorkflowAlpha1(ctx, req.(*TerminateWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_PauseWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PauseWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).PauseWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/PauseWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).PauseWorkflowAlpha1(ctx, req.(*PauseWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_ResumeWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResumeWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).ResumeWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/ResumeWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).ResumeWorkflowAlpha1(ctx, req.(*ResumeWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_RaiseEventWorkflowAlpha1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RaiseEventWorkflowRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).RaiseEventWorkflowAlpha1(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/RaiseEventWorkflowAlpha1", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).RaiseEventWorkflowAlpha1(ctx, req.(*RaiseEventWorkflowRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dapr_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DaprServer).Shutdown(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dapr.proto.runtime.v1.Dapr/Shutdown", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DaprServer).Shutdown(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +// Dapr_ServiceDesc is the grpc.ServiceDesc for Dapr service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Dapr_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dapr.proto.runtime.v1.Dapr", + HandlerType: (*DaprServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "InvokeService", + Handler: _Dapr_InvokeService_Handler, + }, + { + MethodName: "GetState", + Handler: _Dapr_GetState_Handler, + }, + { + MethodName: "GetBulkState", + Handler: _Dapr_GetBulkState_Handler, + }, + { + MethodName: "SaveState", + Handler: _Dapr_SaveState_Handler, + }, + { + MethodName: "QueryStateAlpha1", + Handler: _Dapr_QueryStateAlpha1_Handler, + }, + { + MethodName: "DeleteState", + Handler: _Dapr_DeleteState_Handler, + }, + { + MethodName: "DeleteBulkState", + Handler: _Dapr_DeleteBulkState_Handler, + }, + { + MethodName: "ExecuteStateTransaction", + Handler: _Dapr_ExecuteStateTransaction_Handler, + }, + { + MethodName: "PublishEvent", + Handler: _Dapr_PublishEvent_Handler, + }, + { + MethodName: "BulkPublishEventAlpha1", + Handler: _Dapr_BulkPublishEventAlpha1_Handler, + }, + { + MethodName: "InvokeBinding", + Handler: _Dapr_InvokeBinding_Handler, + }, + { + MethodName: "GetSecret", + Handler: _Dapr_GetSecret_Handler, + }, + { + MethodName: "GetBulkSecret", + Handler: _Dapr_GetBulkSecret_Handler, + }, + { + MethodName: "RegisterActorTimer", + Handler: _Dapr_RegisterActorTimer_Handler, + }, + { + MethodName: "UnregisterActorTimer", + Handler: _Dapr_UnregisterActorTimer_Handler, + }, + { + MethodName: "RegisterActorReminder", + Handler: _Dapr_RegisterActorReminder_Handler, + }, + { + MethodName: "UnregisterActorReminder", + Handler: _Dapr_UnregisterActorReminder_Handler, + }, + { + MethodName: "RenameActorReminder", + Handler: _Dapr_RenameActorReminder_Handler, + }, + { + MethodName: "GetActorState", + Handler: _Dapr_GetActorState_Handler, + }, + { + MethodName: "ExecuteActorStateTransaction", + Handler: _Dapr_ExecuteActorStateTransaction_Handler, + }, + { + MethodName: "InvokeActor", + Handler: _Dapr_InvokeActor_Handler, + }, + { + MethodName: "GetConfigurationAlpha1", + Handler: _Dapr_GetConfigurationAlpha1_Handler, + }, + { + MethodName: "GetConfiguration", + Handler: _Dapr_GetConfiguration_Handler, + }, + { + MethodName: "UnsubscribeConfigurationAlpha1", + Handler: _Dapr_UnsubscribeConfigurationAlpha1_Handler, + }, + { + MethodName: "UnsubscribeConfiguration", + Handler: _Dapr_UnsubscribeConfiguration_Handler, + }, + { + MethodName: "TryLockAlpha1", + Handler: _Dapr_TryLockAlpha1_Handler, + }, + { + MethodName: "UnlockAlpha1", + Handler: _Dapr_UnlockAlpha1_Handler, + }, + { + MethodName: "GetMetadata", + Handler: _Dapr_GetMetadata_Handler, + }, + { + MethodName: "SetMetadata", + Handler: _Dapr_SetMetadata_Handler, + }, + { + MethodName: "SubtleGetKeyAlpha1", + Handler: _Dapr_SubtleGetKeyAlpha1_Handler, + }, + { + MethodName: "SubtleEncryptAlpha1", + Handler: _Dapr_SubtleEncryptAlpha1_Handler, + }, + { + MethodName: "SubtleDecryptAlpha1", + Handler: _Dapr_SubtleDecryptAlpha1_Handler, + }, + { + MethodName: "SubtleWrapKeyAlpha1", + Handler: _Dapr_SubtleWrapKeyAlpha1_Handler, + }, + { + MethodName: "SubtleUnwrapKeyAlpha1", + Handler: _Dapr_SubtleUnwrapKeyAlpha1_Handler, + }, + { + MethodName: "SubtleSignAlpha1", + Handler: _Dapr_SubtleSignAlpha1_Handler, + }, + { + MethodName: "SubtleVerifyAlpha1", + Handler: _Dapr_SubtleVerifyAlpha1_Handler, + }, + { + MethodName: "StartWorkflowAlpha1", + Handler: _Dapr_StartWorkflowAlpha1_Handler, + }, + { + MethodName: "GetWorkflowAlpha1", + Handler: _Dapr_GetWorkflowAlpha1_Handler, + }, + { + MethodName: "PurgeWorkflowAlpha1", + Handler: _Dapr_PurgeWorkflowAlpha1_Handler, + }, + { + MethodName: "TerminateWorkflowAlpha1", + Handler: _Dapr_TerminateWorkflowAlpha1_Handler, + }, + { + MethodName: "PauseWorkflowAlpha1", + Handler: _Dapr_PauseWorkflowAlpha1_Handler, + }, + { + MethodName: "ResumeWorkflowAlpha1", + Handler: _Dapr_ResumeWorkflowAlpha1_Handler, + }, + { + MethodName: "RaiseEventWorkflowAlpha1", + Handler: _Dapr_RaiseEventWorkflowAlpha1_Handler, + }, + { + MethodName: "Shutdown", + Handler: _Dapr_Shutdown_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "SubscribeConfigurationAlpha1", + Handler: _Dapr_SubscribeConfigurationAlpha1_Handler, + ServerStreams: true, + }, + { + StreamName: "SubscribeConfiguration", + Handler: _Dapr_SubscribeConfiguration_Handler, + ServerStreams: true, + }, + { + StreamName: "EncryptAlpha1", + Handler: _Dapr_EncryptAlpha1_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "DecryptAlpha1", + Handler: _Dapr_DecryptAlpha1_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "dapr/proto/runtime/v1/dapr.proto", +} diff --git a/vendor/github.com/dapr/go-sdk/service/common/service.go b/vendor/github.com/dapr/go-sdk/service/common/service.go new file mode 100644 index 00000000000..7f306e4d036 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/common/service.go @@ -0,0 +1,58 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "context" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/config" +) + +const ( + // AppAPITokenEnvVar is the environment variable for app api token. + AppAPITokenEnvVar = "APP_API_TOKEN" /* #nosec */ + APITokenKey = "dapr-api-token" /* #nosec */ +) + +// Service represents Dapr callback service. +type Service interface { + // AddHealthCheckHandler sets a health check handler, name: http (router) and grpc (invalid). + AddHealthCheckHandler(name string, fn HealthCheckHandler) error + // AddServiceInvocationHandler appends provided service invocation handler with its name to the service. + AddServiceInvocationHandler(name string, fn ServiceInvocationHandler) error + // AddTopicEventHandler appends provided event handler with its topic and optional metadata to the service. + // Note, retries are only considered when there is an error. Lack of error is considered as a success + AddTopicEventHandler(sub *Subscription, fn TopicEventHandler) error + // AddBindingInvocationHandler appends provided binding invocation handler with its name to the service. + AddBindingInvocationHandler(name string, fn BindingInvocationHandler) error + // RegisterActorImplFactory Register a new actor to actor runtime of go sdk + // Deprecated: use RegisterActorImplFactoryContext instead + RegisterActorImplFactory(f actor.Factory, opts ...config.Option) + // RegisterActorImplFactoryContext Register a new actor to actor runtime of go sdk + RegisterActorImplFactoryContext(f actor.FactoryContext, opts ...config.Option) + // Start starts service. + Start() error + // Stop stops the previously started service. + Stop() error + // Gracefully stops the previous started service + GracefulStop() error +} + +type ( + ServiceInvocationHandler func(ctx context.Context, in *InvocationEvent) (out *Content, err error) + TopicEventHandler func(ctx context.Context, e *TopicEvent) (retry bool, err error) + BindingInvocationHandler func(ctx context.Context, in *BindingEvent) (out []byte, err error) + HealthCheckHandler func(context.Context) error +) diff --git a/vendor/github.com/dapr/go-sdk/service/common/type.go b/vendor/github.com/dapr/go-sdk/service/common/type.go new file mode 100644 index 00000000000..1883b3c3d79 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/common/type.go @@ -0,0 +1,118 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "encoding/json" +) + +// TopicEvent is the content of the inbound topic message. +type TopicEvent struct { + // ID identifies the event. + ID string `json:"id"` + // The version of the CloudEvents specification. + SpecVersion string `json:"specversion"` + // The type of event related to the originating occurrence. + Type string `json:"type"` + // Source identifies the context in which an event happened. + Source string `json:"source"` + // The content type of data value. + DataContentType string `json:"datacontenttype"` + // The content of the event. + // Note, this is why the gRPC and HTTP implementations need separate structs for cloud events. + Data interface{} `json:"data"` + // The content of the event represented as raw bytes. + // This can be deserialized into a Go struct using `Struct`. + RawData []byte `json:"-"` + // The base64 encoding content of the event. + // Note, this is processing rawPayload and binary content types. + // This field is deprecated and will be removed in the future. + DataBase64 string `json:"data_base64,omitempty"` + // Cloud event subject + Subject string `json:"subject"` + // The pubsub topic which publisher sent to. + Topic string `json:"topic"` + // PubsubName is name of the pub/sub this message came from + PubsubName string `json:"pubsubname"` +} + +func (e *TopicEvent) Struct(target interface{}) error { + // TODO: Enhance to inspect DataContentType for the best + // deserialization method. + return json.Unmarshal(e.RawData, target) +} + +// InvocationEvent represents the input and output of binding invocation. +type InvocationEvent struct { + // Data is the payload that the input bindings sent. + Data []byte `json:"data"` + // ContentType of the Data + ContentType string `json:"contentType"` + // DataTypeURL is the resource URL that uniquely identifies the type of the serialized + DataTypeURL string `json:"typeUrl,omitempty"` + // Verb is the HTTP verb that was used to invoke this service. + Verb string `json:"-"` + // QueryString represents an encoded HTTP url query string in the following format: name=value&name2=value2 + QueryString string `json:"-"` +} + +// Content is a generic data content. +type Content struct { + // Data is the payload that the input bindings sent. + Data []byte `json:"data"` + // ContentType of the Data + ContentType string `json:"contentType"` + // DataTypeURL is the resource URL that uniquely identifies the type of the serialized + DataTypeURL string `json:"typeUrl,omitempty"` +} + +// BindingEvent represents the binding event handler input. +type BindingEvent struct { + // Data is the input bindings sent + Data []byte `json:"data"` + // Metadata is the input binding metadata + Metadata map[string]string `json:"metadata,omitempty"` +} + +// Subscription represents single topic subscription. +type Subscription struct { + // PubsubName is name of the pub/sub this message came from + PubsubName string `json:"pubsubname"` + // Topic is the name of the topic + Topic string `json:"topic"` + // Metadata is the subscription metadata + Metadata map[string]string `json:"metadata,omitempty"` + // Route is the route of the handler where HTTP topic events should be published (passed as Path in gRPC) + Route string `json:"route"` + // Match is the CEL expression to match on the CloudEvent envelope. + Match string `json:"match"` + // Priority is the priority in which to evaluate the match (lower to higher). + Priority int `json:"priority"` + // DisableTopicValidation allows to receive events from publisher topics that differ from the subscribed topic. + DisableTopicValidation bool `json:"disableTopicValidation"` +} + +const ( + // SubscriptionResponseStatusSuccess means message is processed successfully. + SubscriptionResponseStatusSuccess = "SUCCESS" + // SubscriptionResponseStatusRetry means message to be retried by Dapr. + SubscriptionResponseStatusRetry = "RETRY" + // SubscriptionResponseStatusDrop means warning is logged and message is dropped. + SubscriptionResponseStatusDrop = "DROP" +) + +// SubscriptionResponse represents the response handling hint from subscriber to Dapr. +type SubscriptionResponse struct { + Status string `json:"status"` +} diff --git a/vendor/github.com/dapr/go-sdk/service/http/Readme.md b/vendor/github.com/dapr/go-sdk/service/http/Readme.md new file mode 100644 index 00000000000..6f28a344516 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/Readme.md @@ -0,0 +1,114 @@ +# Dapr HTTP Service SDK for Go + +Start by importing Dapr Go `service/http` package: + +```go +daprd "github.com/dapr/go-sdk/service/http" +``` + +## Creating and Starting Service + +To create an HTTP Dapr service, first, create a Dapr callback instance with a specific address: + +```go +s := daprd.NewService(":8080") +``` + +Or with address and an existing `http.ServeMux` in case you want to combine existing server implementations: + +```go +mux := http.NewServeMux() +mux.HandleFunc("/", myOtherHandler) +s := daprd.NewServiceWithMux(":8080", mux) +``` + +Once you create a service instance, you can "attach" to that service any number of event, binding, and service invocation logic handlers as shown below. Onces the logic is defined, you are ready to start the service: + +```go +if err := s.Start(); err != nil && err != http.ErrServerClosed { + log.Fatalf("error: %v", err) +} +``` + +## Event Handling + +To handle events from specific topic you need to add at least one topic event handler before starting the service: + +```go +sub := &common.Subscription{ + PubsubName: "messages", + Topic: "topic1", + Route: "/events", +} +err := s.AddTopicEventHandler(sub, eventHandler) +if err != nil { + log.Fatalf("error adding topic subscription: %v", err) +} +``` + +The handler method itself can be any method with the expected signature: + +```go +func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err error) { + log.Printf("event - PubsubName:%s, Topic:%s, ID:%s, Data: %v", e.PubsubName, e.Topic, e.ID, e.Data) + // do something with the event + return true, nil +} +``` + +## Service Invocation Handler + +To handle service invocations you will need to add at least one service invocation handler before starting the service: + +```go +if err := s.AddServiceInvocationHandler("/echo", echoHandler); err != nil { + log.Fatalf("error adding invocation handler: %v", err) +} +``` + +The handler method itself can be any method with the expected signature: + +```go +func echoHandler(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) { + log.Printf("echo - ContentType:%s, Verb:%s, QueryString:%s, %+v", in.ContentType, in.Verb, in.QueryString, string(in.Data)) + // do something with the invocation here + out = &common.Content{ + Data: in.Data, + ContentType: in.ContentType, + DataTypeURL: in.DataTypeURL, + } + return +} +``` + +## Binding Invocation Handler + +To handle binding invocations you will need to add at least one binding invocation handler before starting the service: + +```go +if err := s.AddBindingInvocationHandler("/run", runHandler); err != nil { + log.Fatalf("error adding binding handler: %v", err) +} +``` + +The handler method itself can be any method with the expected signature: + +```go +func runHandler(ctx context.Context, in *common.BindingEvent) (out []byte, err error) { + log.Printf("binding - Data:%v, Meta:%v", in.Data, in.Metadata) + // do something with the invocation here + return nil, nil +} +``` + +## Templates + +To accelerate your HTTP Dapr app development in Go even further you can use one of the GitHub templates integrating the HTTP Dapr callback package: + +* [Dapr HTTP Event Subscriber in Go](https://github.com/mchmarny/dapr-http-event-subscriber-template) - Template project to jump start your Dapr event subscriber service with HTTP development +* [Dapr HTTP cron Handler in Go](https://github.com/mchmarny/dapr-http-cron-handler-template) - Template project to jump start your Dapr service development for scheduled workloads + + +## Contributing to Dapr Go client + +See the [Contribution Guide](../../CONTRIBUTING.md) to get started with building and developing. diff --git a/vendor/github.com/dapr/go-sdk/service/http/binding.go b/vendor/github.com/dapr/go-sdk/service/http/binding.go new file mode 100644 index 00000000000..f8d888cd085 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/binding.go @@ -0,0 +1,84 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "fmt" + "io" + "net/http" + "strings" + + "github.com/dapr/go-sdk/service/common" +) + +// AddBindingInvocationHandler appends provided binding invocation handler with its route to the service. +func (s *Server) AddBindingInvocationHandler(route string, fn common.BindingInvocationHandler) error { + if route == "" { + return fmt.Errorf("binding route required") + } + if fn == nil { + return fmt.Errorf("binding handler required") + } + + if !strings.HasPrefix(route, "/") { + route = fmt.Sprintf("/%s", route) + } + + s.mux.Handle(route, optionsHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + var content []byte + if r.ContentLength > 0 { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + content = body + } + + // assuming Dapr doesn't pass multiple values for key + meta := map[string]string{} + for k, values := range r.Header { + // TODO: Need to figure out how to parse out only the headers set in the binding + Traceparent + // if k == "raceparent" || strings.HasPrefix(k, "dapr") { + for _, v := range values { + meta[k] = v + } + // } + } + + // execute handler + in := &common.BindingEvent{ + Data: content, + Metadata: meta, + } + out, err := fn(r.Context(), in) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + if out == nil { + out = []byte("{}") + } + + w.Header().Add("Content-Type", "application/json") + if _, err := w.Write(out); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + }))) + + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/service/http/health_check.go b/vendor/github.com/dapr/go-sdk/service/http/health_check.go new file mode 100644 index 00000000000..3f4ca7c15b4 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/health_check.go @@ -0,0 +1,45 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "fmt" + "net/http" + "strings" + + "github.com/dapr/go-sdk/service/common" +) + +// AddHealthCheckHandler appends provided app health check handler. +func (s *Server) AddHealthCheckHandler(route string, fn common.HealthCheckHandler) error { + if fn == nil { + return fmt.Errorf("health check handler required") + } + + if !strings.HasPrefix(route, "/") { + route = fmt.Sprintf("/%s", route) + } + + s.mux.Handle(route, optionsHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + if err := fn(r.Context()); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusNoContent) + }))) + + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/service/http/invoke.go b/vendor/github.com/dapr/go-sdk/service/http/invoke.go new file mode 100644 index 00000000000..f9500069cf7 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/invoke.go @@ -0,0 +1,97 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "fmt" + "io" + "net/http" + "strings" + + "google.golang.org/grpc/metadata" + + "github.com/dapr/go-sdk/service/common" +) + +// AddServiceInvocationHandler appends provided service invocation handler with its route to the service. +func (s *Server) AddServiceInvocationHandler(route string, fn common.ServiceInvocationHandler) error { + if route == "" || route == "/" { + return fmt.Errorf("service route required") + } + + if fn == nil { + return fmt.Errorf("invocation handler required") + } + + if !strings.HasPrefix(route, "/") { + route = "/" + route + } + + s.mux.Handle(route, optionsHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + if s.authToken != "" { + token := r.Header.Get(common.APITokenKey) + if token == "" || token != s.authToken { + http.Error(w, "authentication failed.", http.StatusNonAuthoritativeInfo) + return + } + } + // capture http args + e := &common.InvocationEvent{ + Verb: r.Method, + QueryString: r.URL.RawQuery, + ContentType: r.Header.Get("Content-type"), + } + + // check for post with no data + if r.ContentLength > 0 { + content, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + e.Data = content + } + + ctx := r.Context() + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + md = metadata.MD{} + } + for k, v := range r.Header { + md.Set(k, v...) + } + ctx = metadata.NewIncomingContext(ctx, md) + + // execute handler + o, err := fn(ctx, e) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // write to response if handler returned data + if o != nil && o.Data != nil { + if o.ContentType != "" { + w.Header().Set("Content-type", o.ContentType) + } + if _, err := w.Write(o.Data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } + }))) + + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/service/http/service.go b/vendor/github.com/dapr/go-sdk/service/http/service.go new file mode 100644 index 00000000000..df70f32f33b --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/service.go @@ -0,0 +1,108 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "context" + "net/http" + "os" + "time" + + "github.com/go-chi/chi/v5" + + "github.com/dapr/go-sdk/actor" + "github.com/dapr/go-sdk/actor/config" + "github.com/dapr/go-sdk/actor/runtime" + "github.com/dapr/go-sdk/service/common" + "github.com/dapr/go-sdk/service/internal" +) + +// NewService creates new Service. +func NewService(address string) common.Service { + return newServer(address, nil) +} + +// NewServiceWithMux creates new Service with existing http mux. +func NewServiceWithMux(address string, mux *chi.Mux) common.Service { + return newServer(address, mux) +} + +func newServer(address string, router *chi.Mux) *Server { + if router == nil { + router = chi.NewRouter() + } + return &Server{ + address: address, + httpServer: &http.Server{ //nolint:gosec + Addr: address, + Handler: router, + }, + mux: router, + topicRegistrar: make(internal.TopicRegistrar), + authToken: os.Getenv(common.AppAPITokenEnvVar), + } +} + +// Server is the HTTP server wrapping mux many Dapr helpers. +type Server struct { + address string + mux *chi.Mux + httpServer *http.Server + topicRegistrar internal.TopicRegistrar + authToken string +} + +// Deprecated: Use RegisterActorImplFactoryContext instead. +func (s *Server) RegisterActorImplFactory(f actor.Factory, opts ...config.Option) { + runtime.GetActorRuntimeInstance().RegisterActorFactory(f, opts...) +} + +func (s *Server) RegisterActorImplFactoryContext(f actor.FactoryContext, opts ...config.Option) { + runtime.GetActorRuntimeInstanceContext().RegisterActorFactory(f, opts...) +} + +// Start starts the HTTP handler. Blocks while serving. +func (s *Server) Start() error { + s.registerBaseHandler() + return s.httpServer.ListenAndServe() +} + +// Stop stops previously started HTTP service with a five second timeout. +func (s *Server) Stop() error { + ctxShutDown, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + return s.httpServer.Shutdown(ctxShutDown) +} + +func (s *Server) GracefulStop() error { + return s.Stop() +} + +func setOptions(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "POST,OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept") + w.Header().Set("Allow", "POST,OPTIONS") +} + +func optionsHandler(h http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions { + setOptions(w, r) + } else { + h.ServeHTTP(w, r) + } + } +} diff --git a/vendor/github.com/dapr/go-sdk/service/http/topic.go b/vendor/github.com/dapr/go-sdk/service/http/topic.go new file mode 100644 index 00000000000..461c2a99213 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/http/topic.go @@ -0,0 +1,291 @@ +/* +Copyright 2021 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "encoding/base64" + "encoding/json" + "errors" + "io" + "net/http" + + "github.com/go-chi/chi/v5" + + actorErr "github.com/dapr/go-sdk/actor/error" + "github.com/dapr/go-sdk/actor/runtime" + "github.com/dapr/go-sdk/service/common" + "github.com/dapr/go-sdk/service/internal" +) + +const ( + // PubSubHandlerSuccessStatusCode is the successful ack code for pubsub event appcallback response. + PubSubHandlerSuccessStatusCode int = http.StatusOK + + // PubSubHandlerRetryStatusCode is the error response code (nack) pubsub event appcallback response. + PubSubHandlerRetryStatusCode int = http.StatusInternalServerError + + // PubSubHandlerDropStatusCode is the pubsub event appcallback response code indicating that Dapr should drop that message. + PubSubHandlerDropStatusCode int = http.StatusSeeOther +) + +// topicEventJSON is identical to `common.TopicEvent` +// except for it treats `data` as a json.RawMessage so it can +// be used as bytes or interface{}. +type topicEventJSON struct { + // ID identifies the event. + ID string `json:"id"` + // The version of the CloudEvents specification. + SpecVersion string `json:"specversion"` + // The type of event related to the originating occurrence. + Type string `json:"type"` + // Source identifies the context in which an event happened. + Source string `json:"source"` + // The content type of data value. + DataContentType string `json:"datacontenttype"` + // The content of the event. + // Note, this is why the gRPC and HTTP implementations need separate structs for cloud events. + Data json.RawMessage `json:"data"` + // The base64 encoding content of the event. + // Note, this is processing rawPayload and binary content types. + DataBase64 string `json:"data_base64,omitempty"` + // Cloud event subject + Subject string `json:"subject"` + // The pubsub topic which publisher sent to. + Topic string `json:"topic"` + // PubsubName is name of the pub/sub this message came from + PubsubName string `json:"pubsubname"` +} + +func (s *Server) registerBaseHandler() { + // register subscribe handler + f := func(w http.ResponseWriter, r *http.Request) { + subs := make([]*internal.TopicSubscription, 0, len(s.topicRegistrar)) + for _, s := range s.topicRegistrar { + subs = append(subs, s.Subscription) + } + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(subs); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } + s.mux.HandleFunc("/dapr/subscribe", f) + + // register health check handler + fHealth := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + } + s.mux.Get("/healthz", fHealth) + + // register actor config handler + fRegister := func(w http.ResponseWriter, r *http.Request) { + data, err := runtime.GetActorRuntimeInstanceContext().GetJSONSerializedConfig() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + if _, err = w.Write(data); err != nil { + return + } + } + s.mux.Get("/dapr/config", fRegister) + + // register actor method invoke handler + fInvoke := func(w http.ResponseWriter, r *http.Request) { + actorType := chi.URLParam(r, "actorType") + actorID := chi.URLParam(r, "actorId") + methodName := chi.URLParam(r, "methodName") + reqData, _ := io.ReadAll(r.Body) + rspData, err := runtime.GetActorRuntimeInstanceContext().InvokeActorMethod(r.Context(), actorType, actorID, methodName, reqData) + if err == actorErr.ErrActorTypeNotFound { + w.WriteHeader(http.StatusNotFound) + return + } + if err != actorErr.Success { + w.WriteHeader(http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write(rspData) + } + s.mux.Put("/actors/{actorType}/{actorId}/method/{methodName}", fInvoke) + + // register deactivate actor handler + fDelete := func(w http.ResponseWriter, r *http.Request) { + actorType := chi.URLParam(r, "actorType") + actorID := chi.URLParam(r, "actorId") + err := runtime.GetActorRuntimeInstanceContext().Deactivate(r.Context(), actorType, actorID) + if err == actorErr.ErrActorTypeNotFound || err == actorErr.ErrActorIDNotFound { + w.WriteHeader(http.StatusNotFound) + } + if err != actorErr.Success { + w.WriteHeader(http.StatusInternalServerError) + } + w.WriteHeader(http.StatusOK) + } + s.mux.Delete("/actors/{actorType}/{actorId}", fDelete) + + // register actor reminder invoke handler + fReminder := func(w http.ResponseWriter, r *http.Request) { + actorType := chi.URLParam(r, "actorType") + actorID := chi.URLParam(r, "actorId") + reminderName := chi.URLParam(r, "reminderName") + reqData, _ := io.ReadAll(r.Body) + err := runtime.GetActorRuntimeInstanceContext().InvokeReminder(r.Context(), actorType, actorID, reminderName, reqData) + if err == actorErr.ErrActorTypeNotFound { + w.WriteHeader(http.StatusNotFound) + } + if err != actorErr.Success { + w.WriteHeader(http.StatusInternalServerError) + } + w.WriteHeader(http.StatusOK) + } + s.mux.Put("/actors/{actorType}/{actorId}/method/remind/{reminderName}", fReminder) + + // register actor timer invoke handler + fTimer := func(w http.ResponseWriter, r *http.Request) { + actorType := chi.URLParam(r, "actorType") + actorID := chi.URLParam(r, "actorId") + timerName := chi.URLParam(r, "timerName") + reqData, _ := io.ReadAll(r.Body) + err := runtime.GetActorRuntimeInstanceContext().InvokeTimer(r.Context(), actorType, actorID, timerName, reqData) + if err == actorErr.ErrActorTypeNotFound { + w.WriteHeader(http.StatusNotFound) + } + if err != actorErr.Success { + w.WriteHeader(http.StatusInternalServerError) + } + w.WriteHeader(http.StatusOK) + } + s.mux.Put("/actors/{actorType}/{actorId}/method/timer/{timerName}", fTimer) +} + +// AddTopicEventHandler appends provided event handler with it's name to the service. +func (s *Server) AddTopicEventHandler(sub *common.Subscription, fn common.TopicEventHandler) error { + if sub == nil { + return errors.New("subscription required") + } + // Route is only required for HTTP but should be specified for the + // app protocol to be interchangeable. + if sub.Route == "" { + return errors.New("handler route name") + } + if err := s.topicRegistrar.AddSubscription(sub, fn); err != nil { + return err + } + + s.mux.Handle(sub.Route, optionsHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + // check for post with no data + if r.ContentLength == 0 { + http.Error(w, "nil content", PubSubHandlerDropStatusCode) + return + } + + // deserialize the event + var in topicEventJSON + if err := json.NewDecoder(r.Body).Decode(&in); err != nil { + http.Error(w, err.Error(), PubSubHandlerDropStatusCode) + return + } + + if in.PubsubName == "" { + in.Topic = sub.PubsubName + } + if in.Topic == "" { + in.Topic = sub.Topic + } + + var data interface{} + var rawData []byte + if len(in.Data) > 0 { + rawData = []byte(in.Data) + data = rawData + var v interface{} + // We can assume that rawData is valid JSON + // without checking in.DataContentType == "application/json". + if err := json.Unmarshal(rawData, &v); err == nil { + data = v + // Handling of JSON base64 encoded or escaped in a string. + if str, ok := v.(string); ok { + // This is the path that will most likely succeed. + var vString interface{} + if err := json.Unmarshal([]byte(str), &vString); err == nil { + data = vString + } else if decoded, err := base64.StdEncoding.DecodeString(str); err == nil { + // Decoded Base64 encoded JSON does not seem to be in the spec + // but it is in existing unit tests so this handles that case. + var vBase64 interface{} + if err := json.Unmarshal(decoded, &vBase64); err == nil { + data = vBase64 + } + } + } + } + } else if in.DataBase64 != "" { + var err error + rawData, err = base64.StdEncoding.DecodeString(in.DataBase64) + if err == nil { + data = rawData + if in.DataContentType == "application/json" { + var v interface{} + if err := json.Unmarshal(rawData, &v); err == nil { + data = v + } + } + } + } + + te := common.TopicEvent{ + ID: in.ID, + SpecVersion: in.SpecVersion, + Type: in.Type, + Source: in.Source, + DataContentType: in.DataContentType, + Data: data, + RawData: rawData, + DataBase64: in.DataBase64, + Subject: in.Subject, + PubsubName: in.PubsubName, + Topic: in.Topic, + } + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + // execute user handler + retry, err := fn(r.Context(), &te) + if err == nil { + writeStatus(w, common.SubscriptionResponseStatusSuccess) + return + } + + if retry { + writeStatus(w, common.SubscriptionResponseStatusRetry) + return + } + + writeStatus(w, common.SubscriptionResponseStatusDrop) + }))) + + return nil +} + +func writeStatus(w http.ResponseWriter, s string) { + status := &common.SubscriptionResponse{Status: s} + if err := json.NewEncoder(w).Encode(status); err != nil { + http.Error(w, err.Error(), PubSubHandlerRetryStatusCode) + } +} diff --git a/vendor/github.com/dapr/go-sdk/service/internal/topicregistrar.go b/vendor/github.com/dapr/go-sdk/service/internal/topicregistrar.go new file mode 100644 index 00000000000..ec4efb9e080 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/internal/topicregistrar.go @@ -0,0 +1,64 @@ +package internal + +import ( + "errors" + "fmt" + + "github.com/dapr/go-sdk/service/common" +) + +// TopicRegistrar is a map of - to `TopicRegistration` +// and acts as a lookup as the application is building up subscriptions with +// potentially multiple routes per topic. +type TopicRegistrar map[string]*TopicRegistration + +// TopicRegistration encapsulates the subscription and handlers. +type TopicRegistration struct { + Subscription *TopicSubscription + DefaultHandler common.TopicEventHandler + RouteHandlers map[string]common.TopicEventHandler +} + +func (m TopicRegistrar) AddSubscription(sub *common.Subscription, fn common.TopicEventHandler) error { + if sub.Topic == "" { + return errors.New("topic name required") + } + if sub.PubsubName == "" { + return errors.New("pub/sub name required") + } + if fn == nil { + return fmt.Errorf("topic handler required") + } + + var key string + if !sub.DisableTopicValidation { + key = sub.PubsubName + "-" + sub.Topic + } else { + key = sub.PubsubName + } + + ts, ok := m[key] + if !ok { + ts = &TopicRegistration{ + Subscription: NewTopicSubscription(sub.PubsubName, sub.Topic), + RouteHandlers: make(map[string]common.TopicEventHandler), + DefaultHandler: nil, + } + ts.Subscription.SetMetadata(sub.Metadata) + m[key] = ts + } + + if sub.Match != "" { + if err := ts.Subscription.AddRoutingRule(sub.Route, sub.Match, sub.Priority); err != nil { + return err + } + } else { + if err := ts.Subscription.SetDefaultRoute(sub.Route); err != nil { + return err + } + ts.DefaultHandler = fn + } + ts.RouteHandlers[sub.Route] = fn + + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/service/internal/topicsubscription.go b/vendor/github.com/dapr/go-sdk/service/internal/topicsubscription.go new file mode 100644 index 00000000000..ca628993767 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/service/internal/topicsubscription.go @@ -0,0 +1,112 @@ +package internal + +import ( + "errors" + "fmt" + "sort" +) + +// TopicSubscription internally represents single topic subscription. +type TopicSubscription struct { + // PubsubName is name of the pub/sub this message came from. + PubsubName string `json:"pubsubname"` + // Topic is the name of the topic. + Topic string `json:"topic"` + // Route is the route of the handler where HTTP topic events should be published (passed as Path in gRPC). + Route string `json:"route,omitempty"` + // Routes specify multiple routes where topic events should be sent. + Routes *TopicRoutes `json:"routes,omitempty"` + // Metadata is the subscription metadata. + Metadata map[string]string `json:"metadata,omitempty"` +} + +// TopicRoutes encapsulates the default route and multiple routing rules. +type TopicRoutes struct { + Rules []TopicRule `json:"rules,omitempty"` + Default string `json:"default,omitempty"` + + // priority is used to track duplicate priorities where priority > 0. + // when priority is not specified (0), then the order in which they + // were added is used. + priorities map[int]struct{} +} + +// TopicRule represents a single routing rule. +type TopicRule struct { + // Match is the CEL expression to match on the CloudEvent envelope. + Match string `json:"match"` + // Path is the HTTP path to post the event to (passed as Path in gRPC). + Path string `json:"path"` + // priority is the optional priority order (low to high) for this rule. + priority int `json:"-"` +} + +// NewTopicSubscription creates a new `TopicSubscription`. +func NewTopicSubscription(pubsubName, topic string) *TopicSubscription { + return &TopicSubscription{ //nolint:exhaustivestruct + PubsubName: pubsubName, + Topic: topic, + } +} + +// SetMetadata sets the metadata for the subscription if not already set. +// An error is returned if it is already set. +func (s *TopicSubscription) SetMetadata(metadata map[string]string) error { + if s.Metadata != nil { + return fmt.Errorf("subscription for topic %s on pubsub %s already has metadata set", s.Topic, s.PubsubName) + } + s.Metadata = metadata + + return nil +} + +// SetDefaultRoute sets the default route if not already set. +// An error is returned if it is already set. +func (s *TopicSubscription) SetDefaultRoute(path string) error { + if s.Routes == nil { + if s.Route != "" { + return fmt.Errorf("subscription for topic %s on pubsub %s already has route %s", s.Topic, s.PubsubName, s.Route) + } + s.Route = path + } else { + if s.Routes.Default != "" { + return fmt.Errorf("subscription for topic %s on pubsub %s already has route %s", s.Topic, s.PubsubName, s.Routes.Default) + } + s.Routes.Default = path + } + + return nil +} + +// AddRoutingRule adds a routing rule. +// An error is returned if a there id a duplicate priority > 1. +func (s *TopicSubscription) AddRoutingRule(path, match string, priority int) error { + if path == "" { + return errors.New("path is required for routing rules") + } + if s.Routes == nil { + s.Routes = &TopicRoutes{ //nolint:exhaustivestruct + Default: s.Route, + priorities: map[int]struct{}{}, + } + s.Route = "" + } + if priority > 0 { + if _, exists := s.Routes.priorities[priority]; exists { + return fmt.Errorf("subscription for topic %s on pubsub %s already has a routing rule with priority %d", s.Topic, s.PubsubName, priority) + } + } + s.Routes.Rules = append(s.Routes.Rules, TopicRule{ + Match: match, + Path: path, + priority: priority, + }) + sort.SliceStable(s.Routes.Rules, func(i, j int) bool { + return s.Routes.Rules[i].priority < s.Routes.Rules[j].priority + }) + if priority > 0 { + s.Routes.priorities[priority] = struct{}{} + } + + return nil +} diff --git a/vendor/github.com/dapr/go-sdk/version/sdk-version b/vendor/github.com/dapr/go-sdk/version/sdk-version new file mode 100644 index 00000000000..b7c8e167db9 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/version/sdk-version @@ -0,0 +1 @@ +v1.7.0 \ No newline at end of file diff --git a/vendor/github.com/dapr/go-sdk/version/version.go b/vendor/github.com/dapr/go-sdk/version/version.go new file mode 100644 index 00000000000..e5c4a1128c9 --- /dev/null +++ b/vendor/github.com/dapr/go-sdk/version/version.go @@ -0,0 +1,11 @@ +package version + +import ( + // Required for go:embed. + _ "embed" +) + +// SDKVersion contains the version of the SDK. +// +//go:embed sdk-version +var SDKVersion string diff --git a/vendor/github.com/docker/cli/AUTHORS b/vendor/github.com/docker/cli/AUTHORS index 8990f85b56e..483743c9921 100644 --- a/vendor/github.com/docker/cli/AUTHORS +++ b/vendor/github.com/docker/cli/AUTHORS @@ -1,9 +1,10 @@ -# This file lists all individuals having contributed content to the repository. -# For how it is generated, see `scripts/docs/generate-authors.sh`. +# File @generated by scripts/docs/generate-authors.sh. DO NOT EDIT. +# This file lists all contributors to the repository. +# See scripts/docs/generate-authors.sh to make modifications. Aanand Prasad Aaron L. Xu -Aaron Lehmann +Aaron Lehmann Aaron.L.Xu Abdur Rehman Abhinandan Prativadi @@ -24,22 +25,27 @@ Akihiro Suda Akim Demaille Alan Thompson Albert Callarisa +Alberto Roura Albin Kerouanton Aleksa Sarai Aleksander Piotrowski Alessandro Boch +Alex Couture-Beil Alex Mavrogiannis Alex Mayer Alexander Boyd Alexander Larsson -Alexander Morozov +Alexander Morozov Alexander Ryabov Alexandre González +Alexey Igrychev +Alexis Couvreur Alfred Landrum Alicia Lauerman Allen Sun Alvin Deng Amen Belayneh +Amey Shrivastava <72866602+AmeyShrivastava@users.noreply.github.com> Amir Goldstein Amit Krishnan Amit Shukla @@ -48,6 +54,8 @@ Anca Iordache Anda Xu Andrea Luzzardi Andreas Köhler +Andres G. Aragoneses +Andres Leon Rangel Andrew France Andrew Hsu Andrew Macpherson @@ -67,8 +75,9 @@ Antonis Kalipetis Anusha Ragunathan Ao Li Arash Deshmeh -Arko Dasgupta -Arnaud Porterie +Arko Dasgupta +Arnaud Porterie +Arnaud Rebillout Arthur Peka Ashwini Oruganti Azat Khuyiyakhmetov @@ -76,18 +85,23 @@ Bardia Keyoumarsi Barnaby Gray Bastiaan Bakker BastianHofmann +Ben Bodenmiller Ben Bonnefoy Ben Creasy Ben Firshman Benjamin Boudreau +Benjamin Böhmke +Benjamin Nater Benoit Sigoure Bhumika Bayani Bill Wang Bin Liu Bingshen Wang +Bishal Das Boaz Shuster Bogdan Anton Boris Pruessmann +Brad Baker Bradley Cicenas Brandon Mitchell Brandon Philips @@ -96,6 +110,7 @@ Bret Fisher Brian (bex) Exelbierd Brian Goff Brian Wieder +Bruno Sousa Bryan Bess Bryan Boreham Bryan Murphy @@ -114,15 +129,19 @@ Charles Chan Charles Law Charles Smith Charlie Drage +Charlotte Mach ChaYoung You +Chee Hau Lim Chen Chuanliang Chen Hanxiao Chen Mingjie Chen Qiu +Chris Couzens Chris Gavin Chris Gibson Chris McKinnel Chris Snow +Chris Vermilion Chris Weyl Christian Persson Christian Stefanescu @@ -131,6 +150,7 @@ Christophe Vidal Christopher Biscardi Christopher Crone Christopher Jones +Christopher Svensson Christy Norman Chun Chen Clinton Kitson @@ -139,8 +159,10 @@ Colin Hebert Collin Guarino Colm Hally Comical Derskeal <27731088+derskeal@users.noreply.github.com> +Conner Crosby Corey Farrell Corey Quon +Cory Bennet Craig Wilhite Cristian Staretu Daehyeok Mun @@ -170,11 +192,13 @@ Dattatraya Kumbhar Dave Goodchild Dave Henderson Dave Tucker +David Alvarez David Beitey David Calavera David Cramer David Dooling David Gageot +David Karlsson David Lechner David Scott David Sheets @@ -186,7 +210,8 @@ Denis Defreyne Denis Gladkikh Denis Ollier Dennis Docter -Derek McGowan +Derek McGowan +Des Preston Deshi Xiao Dharmit Shah Dhawal Yogesh Bhanushali @@ -196,12 +221,14 @@ Dimitry Andric Ding Fei Diogo Monica Djordje Lukic +Dmitriy Fishman Dmitry Gusev Dmitry Smirnov Dmitry V. Krivenok Dominik Braun Don Kjer Dong Chen +DongGeon Lee Doug Davis Drew Erny Ed Costello @@ -211,12 +238,14 @@ Eli Uriegas Elias Faxö Elliot Luo <956941328@qq.com> Eric Curtin +Eric Engestrom Eric G. Noriega Eric Rosenberg Eric Sage Eric-Olivier Lamey Erica Windisch Erik Hollensbe +Erik Humphrey Erik St. Martin Essam A. Hassan Ethan Haynes @@ -229,8 +258,10 @@ Evelyn Xu Everett Toews Fabio Falci Fabrizio Soppelsa +Felix Geyer Felix Hupfeld Felix Rabe +fezzik1620 Filip Jareš Flavio Crisciani Florian Klein @@ -242,6 +273,7 @@ Frederic Hemberger Frederick F. Kautz IV Frederik Nordahl Jul Sabroe Frieder Bluemle +Gabriel Gore Gabriel Nicolas Avellaneda Gaetan de Villele Gang Qiao @@ -251,13 +283,18 @@ George MacRorie George Xie Gianluca Borello Gildas Cuisinier +Gio d'Amelio +Gleb Stsenov Goksu Toprak Gou Rao +Govind Rai Grant Reaber Greg Pflaum +Gsealy Guilhem Lettron Guillaume J. Charmes Guillaume Le Floch +Guillaume Tardif gwx296173 Günther Jungbluth Hakan Özler @@ -278,6 +315,7 @@ Hugo Gabriel Eyherabide huqun Huu Nguyen Hyzhou Zhy +Iain Samuel McLean Elder Ian Campbell Ian Philpot Ignacio Capurro @@ -287,6 +325,7 @@ Ilya Sotkov Ioan Eugen Stan Isabel Jimenez Ivan Grcic +Ivan Grund Ivan Markin Jacob Atzen Jacob Tomlinson @@ -302,15 +341,18 @@ Jan-Jaap Driessen Jana Radhakrishnan Jared Hocutt Jasmine Hegman +Jason Hall Jason Heiss Jason Plum Jay Kamat +Jean Lecordier Jean Rouge Jean-Christophe Sirot Jean-Pierre Huynh Jeff Lindsay Jeff Nickoloff Jeff Silberman +Jennings Zhang Jeremy Chambers Jeremy Unruh Jeremy Yallop @@ -322,6 +364,7 @@ Jian Zhang Jie Luo Jilles Oldenbeuving Jim Galasyn +Jim Lin Jimmy Leger Jimmy Song jimmyxian @@ -338,6 +381,7 @@ Johannes 'fish' Ziemke John Feminella John Harris John Howard +John Howard John Laswell John Maguire John Mulhausen @@ -347,13 +391,16 @@ John Tims John V. Martinez John Willis Jon Johnson +Jon Zeolla Jonatas Baldin Jonathan Boulle Jonathan Lee Jonathan Lomas Jonathan McCrohan +Jonathan Warriss-Simmons Jonh Wendell Jordan Jennings +Jorge Vallecillo Jose J. Escobar <53836904+jescobar-docker@users.noreply.github.com> Joseph Kern Josh Bodah @@ -383,9 +430,11 @@ Katie McLaughlin Ke Xu Kei Ohmura Keith Hudgins +Kelton Bassingthwaite Ken Cochrane Ken ICHIKAWA Kenfe-Mickaël Laventure +Kevin Alvarez Kevin Burke Kevin Feyrer Kevin Kern @@ -401,6 +450,7 @@ Krasi Georgiev Kris-Mikael Krister Kun Zhang Kunal Kushwaha +Kyle Mitofsky Lachlan Cooper Lai Jiangshan Lars Kellogg-Stedman @@ -410,6 +460,7 @@ Lee Gaines Lei Jitang Lennie Leo Gallucci +Leonid Skorospelov Lewis Daly Li Yi Li Yi @@ -445,6 +496,7 @@ Manjunath A Kumatagi Mansi Nahar mapk0y Marc Bihlmaier +Marc Cornellà Marco Mariani Marco Vedovati Marcus Martins @@ -459,6 +511,7 @@ Mason Fish Mason Malone Mateusz Major Mathieu Champlon +Mathieu Rollet Matt Gucci Matt Robenolt Matteo Orefice @@ -467,11 +520,13 @@ Matthieu Hauglustaine Mauro Porras P Max Shytikov Maxime Petazzoni +Maximillian Fan Xavier Mei ChunTao +Metal <2466052+tedhexaflow@users.noreply.github.com> Micah Zoltu Michael A. Smith Michael Bridgen -Michael Crosby +Michael Crosby Michael Friis Michael Irwin Michael Käufl @@ -487,6 +542,7 @@ Mihai Borobocea Mihuleacc Sergiu Mike Brown Mike Casas +Mike Dalton Mike Danese Mike Dillon Mike Goelzer @@ -503,9 +559,12 @@ Mohini Anne Dsouza Moorthy RS Morgan Bauer Morten Hekkvang +Morten Linderud Moysés Borges +Mozi <29089388+pzhlkj6612@users.noreply.github.com> Mrunal Patel muicoder +Murukesh Mohanan Muthukumar R Máximo Cuadros Mårten Cassel @@ -521,6 +580,7 @@ Nathan LeClaire Nathan McCauley Neil Peterson Nick Adcock +Nick Santos Nico Stapelbroek Nicola Kabar Nicolas Borboën @@ -535,6 +595,8 @@ Noah Treuhaft O.S. Tezer Odin Ugedal ohmystack +OKA Naoya +Oliver Pomeroy Olle Jonsson Olli Janatuinen Oscar Wieman @@ -550,9 +612,12 @@ Paul Lietar Paul Mulders Paul Weaver Pavel Pospisil +Paweł Gronowski +Paweł Pokrywka Paweł Szczekutowicz Peeyush Gupta Per Lundberg +Peter Dave Hello Peter Edge Peter Hsu Peter Jaffe @@ -560,11 +625,13 @@ Peter Kehl Peter Nagy Peter Salvatore Peter Waller -Phil Estes +Phil Estes Philip Alexander Etling Philipp Gillé Philipp Schmied +Phong Tran pidster +Pieter E Smit pixelistik Pratik Karki Prayag Verma @@ -574,6 +641,7 @@ Qiang Huang Qinglan Peng qudongfang Raghavendra K T +Rahul Kadyan Rahul Zoldyck Ravi Shekhar Jethani Ray Tsang @@ -582,6 +650,7 @@ Remy Suen Renaud Gaubert Ricardo N Feliciano Rich Moyse +Richard Chen Zheng <58443436+rchenzheng@users.noreply.github.com> Richard Mathie Richard Scothern Rick Wieman @@ -591,6 +660,7 @@ Rob Gulewich Robert Wallis Robin Naundorf Robin Speekenbrink +Roch Feuillade Rodolfo Ortiz Rogelio Canedo Rohan Verma @@ -609,11 +679,13 @@ Sainath Grandhi Sakeven Jiang Sally O'Malley Sam Neirinck +Sam Thibault Samarth Shah Sambuddha Basu Sami Tabet Samuel Cochran Samuel Karp +Sandro Jäckel Santhosh Manohar Sargun Dhillon Saswat Bhattacharya @@ -643,7 +715,8 @@ Slava Semushin Solomon Hykes Song Gao Spencer Brown -squeegels <1674195+squeegels@users.noreply.github.com> +Spring Lee +squeegels Srini Brahmaroutu Stefan S. Stefan Scherer @@ -654,6 +727,7 @@ Stephen Rust Steve Durrheimer Steve Richards Steven Burgess +Stoica-Marcu Floris-Andrei Subhajit Ghosh Sun Jianbo Sune Keller @@ -665,7 +739,10 @@ Sébastien HOUZÉ T K Sourabh TAGOMORI Satoshi taiji-tech +Takeshi Koenuma +Takuya Noguchi Taylor Jones +Teiva Harsanyi Tejaswini Duggaraju Tengfei Wang Teppei Fukuda @@ -696,6 +773,7 @@ Tom Fotherby Tom Klingenberg Tom Milligan Tom X. Tobin +Tomas Bäckman Tomas Tomecek Tomasz Kopczynski Tomáš Hrčka @@ -711,6 +789,7 @@ Ulrich Bareth Ulysses Souza Umesh Yadav Valentin Lorentz +Vardan Pogosian Venkateswara Reddy Bukkasamudram Veres Lajos Victor Vieux @@ -757,6 +836,7 @@ Yunxiang Huang Zachary Romero Zander Mackie zebrilee +Zeel B Patel Zhang Kun Zhang Wei Zhang Wentao @@ -768,4 +848,5 @@ Zhu Guihua Álex González Álvaro Lázaro Átila Camurça Alves +Александр Менщиков <__Singleton__@hackerdom.ru> 徐俊杰 diff --git a/vendor/github.com/docker/cli/cli/config/config.go b/vendor/github.com/docker/cli/cli/config/config.go index 31ad117d415..b7c05c3f860 100644 --- a/vendor/github.com/docker/cli/cli/config/config.go +++ b/vendor/github.com/docker/cli/cli/config/config.go @@ -19,7 +19,7 @@ const ( // ConfigFileName is the name of config file ConfigFileName = "config.json" configFileDir = ".docker" - oldConfigfile = ".dockercfg" + oldConfigfile = ".dockercfg" // Deprecated: remove once we stop printing deprecation warning contextsDir = "contexts" ) @@ -84,16 +84,6 @@ func Path(p ...string) (string, error) { return path, nil } -// LegacyLoadFromReader is a convenience function that creates a ConfigFile object from -// a non-nested reader -func LegacyLoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { - configFile := configfile.ConfigFile{ - AuthConfigs: make(map[string]types.AuthConfig), - } - err := configFile.LegacyLoadFromReader(configData) - return &configFile, err -} - // LoadFromReader is a convenience function that creates a ConfigFile object from // a reader func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { @@ -140,12 +130,8 @@ func load(configDir string) (*configfile.ConfigFile, bool, error) { // Can't find latest config file so check for the old one filename = filepath.Join(getHomeDir(), oldConfigfile) - if file, err := os.Open(filename); err == nil { + if _, err := os.Stat(filename); err == nil { printLegacyFileWarning = true - defer file.Close() - if err := configFile.LegacyLoadFromReader(file); err != nil { - return configFile, printLegacyFileWarning, errors.Wrap(err, filename) - } } return configFile, printLegacyFileWarning, nil } @@ -158,7 +144,7 @@ func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) } if printLegacyFileWarning { - _, _ = fmt.Fprintln(stderr, "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format is deprecated and will be removed in an upcoming release") + _, _ = fmt.Fprintln(stderr, "WARNING: Support for the legacy ~/.dockercfg configuration file and file-format has been removed and the configuration file will be ignored") } if !configFile.ContainsAuth() { configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index d6f710817ab..442c31110b1 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -3,9 +3,7 @@ package configfile import ( "encoding/base64" "encoding/json" - "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -16,13 +14,6 @@ import ( "github.com/sirupsen/logrus" ) -const ( - // This constant is only used for really old config files when the - // URL wasn't saved as part of the config file and it was just - // assumed to be this value. - defaultIndexServer = "https://index.docker.io/v1/" -) - // ConfigFile ~/.docker/config.json file info type ConfigFile struct { AuthConfigs map[string]types.AuthConfig `json:"auths"` @@ -46,8 +37,6 @@ type ConfigFile struct { PruneFilters []string `json:"pruneFilters,omitempty"` Proxies map[string]ProxyConfig `json:"proxies,omitempty"` Experimental string `json:"experimental,omitempty"` - StackOrchestrator string `json:"stackOrchestrator,omitempty"` - Kubernetes *KubernetesConfig `json:"kubernetes,omitempty"` CurrentContext string `json:"currentContext,omitempty"` CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"` Plugins map[string]map[string]string `json:"plugins,omitempty"` @@ -60,11 +49,7 @@ type ProxyConfig struct { HTTPSProxy string `json:"httpsProxy,omitempty"` NoProxy string `json:"noProxy,omitempty"` FTPProxy string `json:"ftpProxy,omitempty"` -} - -// KubernetesConfig contains Kubernetes orchestrator settings -type KubernetesConfig struct { - AllNamespaces string `json:"allNamespaces,omitempty"` + AllProxy string `json:"allProxy,omitempty"` } // New initializes an empty configuration file for the given filename 'fn' @@ -78,44 +63,6 @@ func New(fn string) *ConfigFile { } } -// LegacyLoadFromReader reads the non-nested configuration data given and sets up the -// auth config information with given directory and populates the receiver object -func (configFile *ConfigFile) LegacyLoadFromReader(configData io.Reader) error { - b, err := ioutil.ReadAll(configData) - if err != nil { - return err - } - - if err := json.Unmarshal(b, &configFile.AuthConfigs); err != nil { - arr := strings.Split(string(b), "\n") - if len(arr) < 2 { - return errors.Errorf("The Auth config file is empty") - } - authConfig := types.AuthConfig{} - origAuth := strings.Split(arr[0], " = ") - if len(origAuth) != 2 { - return errors.Errorf("Invalid Auth config file") - } - authConfig.Username, authConfig.Password, err = decodeAuth(origAuth[1]) - if err != nil { - return err - } - authConfig.ServerAddress = defaultIndexServer - configFile.AuthConfigs[defaultIndexServer] = authConfig - } else { - for k, authConfig := range configFile.AuthConfigs { - authConfig.Username, authConfig.Password, err = decodeAuth(authConfig.Auth) - if err != nil { - return err - } - authConfig.Auth = "" - authConfig.ServerAddress = k - configFile.AuthConfigs[k] = authConfig - } - } - return nil -} - // LoadFromReader reads the configuration data given and sets up the auth config // information with given directory and populates the receiver object func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error { @@ -134,7 +81,7 @@ func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error { ac.ServerAddress = addr configFile.AuthConfigs[addr] = ac } - return checkKubernetesConfiguration(configFile.Kubernetes) + return nil } // ContainsAuth returns whether there is authentication configured @@ -147,6 +94,9 @@ func (configFile *ConfigFile) ContainsAuth() bool { // GetAuthConfigs returns the mapping of repo to auth configuration func (configFile *ConfigFile) GetAuthConfigs() map[string]types.AuthConfig { + if configFile.AuthConfigs == nil { + configFile.AuthConfigs = make(map[string]types.AuthConfig) + } return configFile.AuthConfigs } @@ -191,10 +141,10 @@ func (configFile *ConfigFile) Save() (retErr error) { } dir := filepath.Dir(configFile.Filename) - if err := os.MkdirAll(dir, 0700); err != nil { + if err := os.MkdirAll(dir, 0o700); err != nil { return err } - temp, err := ioutil.TempFile(dir, filepath.Base(configFile.Filename)) + temp, err := os.CreateTemp(dir, filepath.Base(configFile.Filename)) if err != nil { return err } @@ -244,6 +194,7 @@ func (configFile *ConfigFile) ParseProxyConfig(host string, runOpts map[string]* "HTTPS_PROXY": &config.HTTPSProxy, "NO_PROXY": &config.NoProxy, "FTP_PROXY": &config.FTPProxy, + "ALL_PROXY": &config.AllProxy, } m := runOpts if m == nil { @@ -292,12 +243,11 @@ func decodeAuth(authStr string) (string, string, error) { if n > decLen { return "", "", errors.Errorf("Something went wrong decoding auth config") } - arr := strings.SplitN(string(decoded), ":", 2) - if len(arr) != 2 { + userName, password, ok := strings.Cut(string(decoded), ":") + if !ok || userName == "" { return "", "", errors.Errorf("Invalid auth configuration file") } - password := strings.Trim(arr[1], "\x00") - return arr[0], password, nil + return userName, strings.Trim(password, "\x00"), nil } // GetCredentialsStore returns a new credentials store from the settings in the @@ -352,7 +302,8 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, for registryHostname := range configFile.CredentialHelpers { newAuth, err := configFile.GetAuthConfig(registryHostname) if err != nil { - return nil, err + logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname) + continue } auths[registryHostname] = newAuth } @@ -399,17 +350,3 @@ func (configFile *ConfigFile) SetPluginConfig(pluginname, option, value string) delete(configFile.Plugins, pluginname) } } - -func checkKubernetesConfiguration(kubeConfig *KubernetesConfig) error { - if kubeConfig == nil { - return nil - } - switch kubeConfig.AllNamespaces { - case "": - case "enabled": - case "disabled": - default: - return fmt.Errorf("invalid 'kubernetes.allNamespaces' value, should be 'enabled' or 'disabled': %s", kubeConfig.AllNamespaces) - } - return nil -} diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go b/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go index 6af67181268..353887547cd 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file_unix.go @@ -12,7 +12,7 @@ import ( // ignoring any error during the process. func copyFilePermissions(src, dst string) { var ( - mode os.FileMode = 0600 + mode os.FileMode = 0o600 uid, gid int ) diff --git a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go index e509820b73f..ea30fc30063 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go @@ -52,7 +52,8 @@ func (c *fileStore) GetAll() (map[string]types.AuthConfig, error) { // Store saves the given credentials in the file store. func (c *fileStore) Store(authConfig types.AuthConfig) error { - c.file.GetAuthConfigs()[authConfig.ServerAddress] = authConfig + authConfigs := c.file.GetAuthConfigs() + authConfigs[authConfig.ServerAddress] = authConfig return c.file.Save() } @@ -75,7 +76,6 @@ func ConvertToHostname(url string) string { stripped = strings.TrimPrefix(url, "https://") } - nameParts := strings.SplitN(stripped, "/", 2) - - return nameParts[0] + hostName, _, _ := strings.Cut(stripped, "/") + return hostName } diff --git a/vendor/github.com/docker/distribution/.dockerignore b/vendor/github.com/docker/distribution/.dockerignore new file mode 100644 index 00000000000..e660fd93d31 --- /dev/null +++ b/vendor/github.com/docker/distribution/.dockerignore @@ -0,0 +1 @@ +bin/ diff --git a/vendor/github.com/docker/distribution/.golangci.yml b/vendor/github.com/docker/distribution/.golangci.yml index 1ba6cb91623..36c083b0fc4 100644 --- a/vendor/github.com/docker/distribution/.golangci.yml +++ b/vendor/github.com/docker/distribution/.golangci.yml @@ -18,3 +18,10 @@ run: deadline: 2m skip-dirs: - vendor + +issues: + exclude-rules: + # io/ioutil is deprecated, but won't be removed until Go v2. It's safe to ignore for the release/2.8 branch. + - text: "SA1019: \"io/ioutil\" has been deprecated since Go 1.16" + linters: + - staticcheck diff --git a/vendor/github.com/docker/distribution/.mailmap b/vendor/github.com/docker/distribution/.mailmap index 8f3738f3d0e..d94c3936e02 100644 --- a/vendor/github.com/docker/distribution/.mailmap +++ b/vendor/github.com/docker/distribution/.mailmap @@ -44,6 +44,8 @@ Thomas Berger Thomas Berger Samuel Karp Samuel Karp Justin Cormack sayboras -CrazyMax CrazyMax <1951866+crazy-max@users.noreply.github.com> -CrazyMax +Hayley Swimelar +Jose D. Gomez R +Shengjing Zhu +Silvin Lubecki <31478878+silvin-lubecki@users.noreply.github.com> diff --git a/vendor/github.com/docker/distribution/Dockerfile b/vendor/github.com/docker/distribution/Dockerfile index ae8c040c735..fb54b68138d 100644 --- a/vendor/github.com/docker/distribution/Dockerfile +++ b/vendor/github.com/docker/distribution/Dockerfile @@ -1,49 +1,59 @@ -# syntax=docker/dockerfile:1.3 +# syntax=docker/dockerfile:1 -ARG GO_VERSION=1.16.15 -ARG GORELEASER_XX_VERSION=1.2.5 +ARG GO_VERSION=1.19.9 +ARG ALPINE_VERSION=3.16 +ARG XX_VERSION=1.2.1 -FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:${GORELEASER_XX_VERSION} AS goreleaser-xx -FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS base -COPY --from=goreleaser-xx / / -RUN apk add --no-cache file git +FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base +COPY --from=xx / / +RUN apk add --no-cache bash coreutils file git +ENV GO111MODULE=auto +ENV CGO_ENABLED=0 WORKDIR /go/src/github.com/docker/distribution +FROM base AS version +ARG PKG="github.com/docker/distribution" +RUN --mount=target=. \ + VERSION=$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags) REVISION=$(git rev-parse HEAD)$(if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi); \ + echo "-X ${PKG}/version.Version=${VERSION#v} -X ${PKG}/version.Revision=${REVISION} -X ${PKG}/version.Package=${PKG}" | tee /tmp/.ldflags; \ + echo -n "${VERSION}" | tee /tmp/.version; + FROM base AS build -ENV GO111MODULE=auto -ENV CGO_ENABLED=0 -# GIT_REF is used by goreleaser-xx to handle the proper git ref when available. -# It will fallback to the working tree info if empty and use "git tag --points-at" -# or "git describe" to define the version info. -ARG GIT_REF ARG TARGETPLATFORM -ARG PKG="github.com/distribution/distribution" +ARG LDFLAGS="-s -w" ARG BUILDTAGS="include_oss include_gcs" -RUN --mount=type=bind,rw \ - --mount=type=cache,target=/root/.cache/go-build \ - --mount=target=/go/pkg/mod,type=cache \ - goreleaser-xx --debug \ - --name="registry" \ - --dist="/out" \ - --main="./cmd/registry" \ - --flags="-v" \ - --ldflags="-s -w -X '$PKG/version.Version={{.Version}}' -X '$PKG/version.Revision={{.Commit}}' -X '$PKG/version.Package=$PKG'" \ - --tags="$BUILDTAGS" \ - --files="LICENSE" \ - --files="README.md" - -FROM scratch AS artifact -COPY --from=build /out/*.tar.gz / -COPY --from=build /out/*.zip / -COPY --from=build /out/*.sha256 / +RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \ + --mount=type=cache,target=/root/.cache/go-build \ + --mount=target=/go/pkg/mod,type=cache \ + --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \ + set -x ; xx-go build -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \ + && xx-verify --static /usr/bin/registry FROM scratch AS binary -COPY --from=build /usr/local/bin/registry* / +COPY --from=build /usr/bin/registry / + +FROM base AS releaser +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT +WORKDIR /work +RUN --mount=from=binary,target=/build \ + --mount=type=bind,target=/src \ + --mount=type=bind,source=/tmp/.version,target=/tmp/.version,from=version \ + VERSION=$(cat /tmp/.version) \ + && mkdir -p /out \ + && cp /build/registry /src/README.md /src/LICENSE . \ + && tar -czvf "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz" * \ + && sha256sum -z "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz" | awk '{ print $1 }' > "/out/registry_${VERSION#v}_${TARGETOS}_${TARGETARCH}${TARGETVARIANT}.tar.gz.sha256" + +FROM scratch AS artifact +COPY --from=releaser /out / -FROM alpine:3.14 +FROM alpine:${ALPINE_VERSION} RUN apk add --no-cache ca-certificates COPY cmd/registry/config-dev.yml /etc/docker/registry/config.yml -COPY --from=build /usr/local/bin/registry /bin/registry +COPY --from=binary /registry /bin/registry VOLUME ["/var/lib/registry"] EXPOSE 5000 ENTRYPOINT ["registry"] diff --git a/vendor/github.com/docker/distribution/Makefile b/vendor/github.com/docker/distribution/Makefile index 331da27328d..75e11820152 100644 --- a/vendor/github.com/docker/distribution/Makefile +++ b/vendor/github.com/docker/distribution/Makefile @@ -50,7 +50,7 @@ version/version.go: check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck") @echo "$(WHALE) $@" - golangci-lint run + @GO111MODULE=off golangci-lint run test: ## run tests, except integration test with test.short @echo "$(WHALE) $@" diff --git a/vendor/github.com/docker/distribution/docker-bake.hcl b/vendor/github.com/docker/distribution/docker-bake.hcl index 4dd5a100c1d..91686e608a9 100644 --- a/vendor/github.com/docker/distribution/docker-bake.hcl +++ b/vendor/github.com/docker/distribution/docker-bake.hcl @@ -1,15 +1,3 @@ -// GITHUB_REF is the actual ref that triggers the workflow -// https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables -variable "GITHUB_REF" { - default = "" -} - -target "_common" { - args = { - GIT_REF = GITHUB_REF - } -} - group "default" { targets = ["image-local"] } @@ -20,13 +8,11 @@ target "docker-metadata-action" { } target "binary" { - inherits = ["_common"] target = "binary" output = ["./bin"] } target "artifact" { - inherits = ["_common"] target = "artifact" output = ["./bin"] } @@ -43,8 +29,13 @@ target "artifact-all" { ] } +// Special target: https://github.com/docker/metadata-action#bake-definition +target "docker-metadata-action" { + tags = ["registry:local"] +} + target "image" { - inherits = ["_common", "docker-metadata-action"] + inherits = ["docker-metadata-action"] } target "image-local" { diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go index 8c0c23b2fe1..b7cd00b0d68 100644 --- a/vendor/github.com/docker/distribution/reference/reference.go +++ b/vendor/github.com/docker/distribution/reference/reference.go @@ -3,13 +3,13 @@ // // Grammar // -// reference := name [ ":" tag ] [ "@" digest ] +// reference := name [ ":" tag ] [ "@" digest ] // name := [domain '/'] path-component ['/' path-component]* // domain := domain-component ['.' domain-component]* [':' port-number] // domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ // port-number := /[0-9]+/ // path-component := alpha-numeric [separator alpha-numeric]* -// alpha-numeric := /[a-z0-9]+/ +// alpha-numeric := /[a-z0-9]+/ // separator := /[_.]|__|[-]*/ // // tag := /[\w][\w.-]{0,127}/ diff --git a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go index a9616c58ad5..c3bf90f71d0 100644 --- a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go +++ b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go @@ -134,6 +134,19 @@ var ( }, } + invalidPaginationResponseDescriptor = ResponseDescriptor{ + Name: "Invalid pagination number", + Description: "The received parameter n was invalid in some way, as described by the error code. The client should resolve the issue and retry the request.", + StatusCode: http.StatusBadRequest, + Body: BodyDescriptor{ + ContentType: "application/json", + Format: errorsBody, + }, + ErrorCodes: []errcode.ErrorCode{ + ErrorCodePaginationNumberInvalid, + }, + } + repositoryNotFoundResponseDescriptor = ResponseDescriptor{ Name: "No Such Repository Error", StatusCode: http.StatusNotFound, @@ -490,6 +503,7 @@ var routeDescriptors = []RouteDescriptor{ }, }, Failures: []ResponseDescriptor{ + invalidPaginationResponseDescriptor, unauthorizedResponseDescriptor, repositoryNotFoundResponseDescriptor, deniedResponseDescriptor, @@ -1578,6 +1592,9 @@ var routeDescriptors = []RouteDescriptor{ }, }, }, + Failures: []ResponseDescriptor{ + invalidPaginationResponseDescriptor, + }, }, }, }, diff --git a/vendor/github.com/docker/distribution/registry/api/v2/errors.go b/vendor/github.com/docker/distribution/registry/api/v2/errors.go index 97d6923aa03..87e9f3c14be 100644 --- a/vendor/github.com/docker/distribution/registry/api/v2/errors.go +++ b/vendor/github.com/docker/distribution/registry/api/v2/errors.go @@ -133,4 +133,13 @@ var ( longer proceed.`, HTTPStatusCode: http.StatusNotFound, }) + + ErrorCodePaginationNumberInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{ + Value: "PAGINATION_NUMBER_INVALID", + Message: "invalid number of results requested", + Description: `Returned when the "n" parameter (number of results + to return) is not an integer, "n" is negative or "n" is bigger than + the maximum allowed.`, + HTTPStatusCode: http.StatusBadRequest, + }) ) diff --git a/vendor/github.com/docker/distribution/registry/client/errors.go b/vendor/github.com/docker/distribution/registry/client/errors.go index 52d49d5d295..024df43dd92 100644 --- a/vendor/github.com/docker/distribution/registry/client/errors.go +++ b/vendor/github.com/docker/distribution/registry/client/errors.go @@ -55,6 +55,8 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error { switch statusCode { case http.StatusUnauthorized: return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details) + case http.StatusForbidden: + return errcode.ErrorCodeDenied.WithMessage(detailsErr.Details) case http.StatusTooManyRequests: return errcode.ErrorCodeTooManyRequests.WithMessage(detailsErr.Details) default: diff --git a/vendor/github.com/docker/distribution/registry/client/repository.go b/vendor/github.com/docker/distribution/registry/client/repository.go index 3e2ae66d3cf..04e5a3ba01f 100644 --- a/vendor/github.com/docker/distribution/registry/client/repository.go +++ b/vendor/github.com/docker/distribution/registry/client/repository.go @@ -114,9 +114,7 @@ func (r *registry) Repositories(ctx context.Context, entries []string, last stri return 0, err } - for cnt := range ctlg.Repositories { - entries[cnt] = ctlg.Repositories[cnt] - } + copy(entries, ctlg.Repositories) numFilled = len(ctlg.Repositories) link := resp.Header.Get("Link") diff --git a/vendor/github.com/docker/distribution/registry/client/transport/http_reader.go b/vendor/github.com/docker/distribution/registry/client/transport/http_reader.go index 1d0b382fb51..9120dbed666 100644 --- a/vendor/github.com/docker/distribution/registry/client/transport/http_reader.go +++ b/vendor/github.com/docker/distribution/registry/client/transport/http_reader.go @@ -180,7 +180,6 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) { // context.GetLogger(hrs.context).Infof("Range: %s", req.Header.Get("Range")) } - req.Header.Add("Accept-Encoding", "identity") resp, err := hrs.client.Do(req) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index dffacff1120..b3141819258 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -1,5 +1,6 @@ -# This file lists all individuals having contributed content to the repository. -# For how it is generated, see `hack/generate-authors.sh`. +# File @generated by hack/generate-authors.sh. DO NOT EDIT. +# This file lists all contributors to the repository. +# See hack/generate-authors.sh to make modifications. Aanand Prasad Aaron Davidson @@ -7,16 +8,17 @@ Aaron Feng Aaron Hnatiw Aaron Huslage Aaron L. Xu -Aaron Lehmann +Aaron Lehmann Aaron Welch -Aaron.L.Xu Abel Muiño Abhijeet Kasurde -Abhinandan Prativadi +Abhinandan Prativadi Abhinav Ajgaonkar Abhishek Chanda Abhishek Sharma Abin Shahab +Abirdcfly +Ada Mancini Adam Avilla Adam Dobrawy Adam Eijdenberg @@ -26,6 +28,8 @@ Adam Mills Adam Pointer Adam Singer Adam Walz +Adam Williams +AdamKorcz Addam Hardy Aditi Rajagopal Aditya @@ -51,6 +55,7 @@ Akihiro Suda Akim Demaille Akira Koyasu Akshay Karle +Akshay Moghe Al Tobey alambike Alan Hoyle @@ -58,9 +63,11 @@ Alan Scherger Alan Thompson Albert Callarisa Albert Zhang -Albin Kerouanton +Albin Kerouanton +Alec Benson Alejandro González Hevia Aleksa Sarai +Aleksandr Chebotov Aleksandrs Fadins Alena Prokharchyk Alessandro Boch @@ -72,14 +79,17 @@ Alex Crawford Alex Ellis Alex Gaynor Alex Goodman +Alex Nordlund Alex Olshansky Alex Samorukov +Alex Stockinger Alex Warhawk Alexander Artemenko Alexander Boyd Alexander Larsson Alexander Midlash -Alexander Morozov +Alexander Morozov +Alexander Polakov Alexander Shopov Alexandre Beslic Alexandre Garnier @@ -90,7 +100,8 @@ Alexei Margasov Alexey Guskov Alexey Kotlyarov Alexey Shamrin -Alexis THOMAS +Alexis Ries +Alexis Thomas Alfred Landrum Ali Dehghani Alicia Lauerman @@ -103,6 +114,7 @@ Alvin Deng Alvin Richards amangoel Amen Belayneh +Ameya Gawde Amir Goldstein Amit Bakshi Amit Krishnan @@ -126,6 +138,7 @@ Andreas Köhler Andreas Savvides Andreas Tiefenthaler Andrei Gherzan +Andrei Ushakov Andrei Vagin Andrew C. Bodine Andrew Clay Shafer @@ -135,6 +148,7 @@ Andrew Gerrand Andrew Guenther Andrew He Andrew Hsu +Andrew Kim Andrew Kuklewicz Andrew Macgregor Andrew Macpherson @@ -150,15 +164,17 @@ Andrey Kolomentsev Andrey Petrov Andrey Stolbovsky André Martins -andy Andy Chambers andy diller Andy Goldstein Andy Kipp +Andy Lindeman Andy Rothfusz Andy Smith Andy Wilson +Andy Zhang Anes Hasicic +Angel Velazquez Anil Belur Anil Madhavapeddy Ankit Jain @@ -179,20 +195,25 @@ Antonio Murdaca Antonis Kalipetis Antony Messerli Anuj Bahuguna +Anuj Varma Anusha Ragunathan +Anyu Wang apocas Arash Deshmeh +arcosx ArikaChen -Arko Dasgupta +Arko Dasgupta Arnaud Lefebvre -Arnaud Porterie +Arnaud Porterie Arnaud Rebillout +Artem Khramov Arthur Barr Arthur Gautier Artur Meyster Arun Gupta Asad Saeeduddin Asbjørn Enge +Austin Vazquez averagehuman Avi Das Avi Kivity @@ -200,17 +221,21 @@ Avi Miller Avi Vaid ayoshitake Azat Khuyiyakhmetov +Bao Yonglei Bardia Keyoumarsi Barnaby Gray Barry Allard Bartłomiej Piotrowski Bastiaan Bakker +Bastien Pascard bdevloed +Bearice Ren Ben Bonnefoy Ben Firshman Ben Golub Ben Gould Ben Hall +Ben Langfeld Ben Sargent Ben Severson Ben Toews @@ -218,6 +243,8 @@ Ben Wiklund Benjamin Atkin Benjamin Baker Benjamin Boudreau +Benjamin Böhmke +Benjamin Wang Benjamin Yolken Benny Ng Benoit Chesneau @@ -231,12 +258,15 @@ Bhiraj Butala Bhumika Bayani Bilal Amarni Bill Wang +Billy Ridgway Bily Zhang Bin Liu Bingshen Wang +Bjorn Neergaard Blake Geno Boaz Shuster bobby abbott +Bojun Zhu Boqin Qin Boris Pruessmann Boshi Lian @@ -252,6 +282,7 @@ Brendan Dixon Brent Salisbury Brett Higgins Brett Kochendorfer +Brett Milford Brett Randall Brian (bex) Exelbierd Brian Bland @@ -282,6 +313,7 @@ Byung Kang Caleb Spare Calen Pennington Cameron Boehmer +Cameron Sparr Cameron Spear Campbell Allen Candid Dauth @@ -316,6 +348,7 @@ Charlie Drage Charlie Lewis Chase Bolt ChaYoung You +Chee Hau Lim Chen Chao Chen Chuanliang Chen Hanxiao @@ -325,6 +358,7 @@ Chen Qiu Cheng-mean Liu Chengfei Shang Chengguang Xu +Chenyang Yan chenyuzhu Chetan Birajdar Chewey @@ -339,6 +373,7 @@ Chris Fordham Chris Gavin Chris Gibson Chris Khoo +Chris Kreussling (Flatbush Gardener) Chris McKinnel Chris McKinnel Chris Price @@ -351,6 +386,7 @@ Chris Telfer Chris Wahl Chris Weyl Chris White +Christian Becker Christian Berendt Christian Brauner Christian Böhme @@ -359,6 +395,7 @@ Christian Persson Christian Rotzoll Christian Simon Christian Stefanescu +Christoph Ziebuhr Christophe Mehay Christophe Troestler Christophe Vidal @@ -372,7 +409,9 @@ Christy Norman Chun Chen Ciro S. Costa Clayton Coleman +Clint Armstrong Clinton Kitson +clubby789 Cody Roseborough Coenraad Loubser Colin Dunklau @@ -383,19 +422,23 @@ Colin Walters Collin Guarino Colm Hally companycy +Conor Evans Corbin Coleman Corey Farrell Cory Forsyth +Cory Snider cressie176 -CrimsonGlory Cristian Ariza Cristian Staretu cristiano balducci Cristina Yenyxe Gonzalez Garcia Cruceru Calin-Cristian CUI Wei +cuishuang +Cuong Manh Le Cyprian Gracz Cyril F +Da McGrady Daan van Berkel Daehyeok Mun Dafydd Crosby @@ -413,6 +456,7 @@ Dan Hirsch Dan Keder Dan Levy Dan McPherson +Dan Plamadeala Dan Stine Dan Williams Dani Hodovic @@ -433,6 +477,7 @@ Daniel Mizyrycki Daniel Nephin Daniel Norberg Daniel Nordberg +Daniel P. Berrangé Daniel Robinson Daniel S Daniel Sweet @@ -441,6 +486,7 @@ Daniel Watkins Daniel X Moore Daniel YC Lin Daniel Zhang +Daniele Rondina Danny Berger Danny Milosavljevic Danny Yates @@ -456,6 +502,7 @@ Dave Henderson Dave MacDonald Dave Tucker David Anderson +David Bellotti David Calavera David Chung David Corking @@ -470,9 +517,11 @@ David Lawrence David Lechner David M. Karr David Mackey +David Manouchehri David Mat David Mcanulty David McKay +David O'Rourke David P Hilton David Pelaez David R. Jenni @@ -503,14 +552,14 @@ Dennis Docter Derek Derek Derek Ch -Derek McGowan +Derek McGowan Deric Crago Deshi Xiao -devmeyster Devon Estes Devvyn Murphy Dharmit Shah Dhawal Yogesh Bhanushali +Dhilip Kumars Diego Romero Diego Siqueira Dieter Reuter @@ -522,9 +571,11 @@ Dimitris Rozakis Dimitry Andric Dinesh Subhraveti Ding Fei +dingwei Diogo Monica DiuDiugirl Djibril Koné +Djordje Lukic dkumor Dmitri Logvinenko Dmitri Shuralyov @@ -536,6 +587,8 @@ Dmitry Shyshkin Dmitry Smirnov Dmitry V. Krivenok Dmitry Vorobev +Dmytro Iakovliev +docker-unir[bot] Dolph Mathews Dominic Tubach Dominic Yin @@ -569,8 +622,9 @@ Eivind Uggedal Elan Ruusamäe Elango Sivanandam Elena Morozova -Eli Uriegas +Eli Uriegas Elias Faxö +Elias Koromilas Elias Probst Elijah Zupancic eluck @@ -580,14 +634,17 @@ Emil Hernvall Emily Maier Emily Rose Emir Ozer +Eng Zer Jun Enguerran Eohyung Lee epeterso +er0k Eric Barch Eric Curtin Eric G. Noriega Eric Hanchrow Eric Lee +Eric Mountain Eric Myhre Eric Paris Eric Rafaloff @@ -597,17 +654,21 @@ Eric Soderstrom Eric Yang Eric-Olivier Lamey Erica Windisch +Erich Cordoba Erik Bray Erik Dubbelboer Erik Hollensbe Erik Inge Bolsø Erik Kristensen +Erik Sipsma Erik St. Martin Erik Weathers Erno Hopearuoho Erwin van der Koogh +Espen Suenson Ethan Bell Ethan Mosbaugh +Euan Harris Euan Kemp Eugen Krizo Eugene Yakubovich @@ -657,6 +718,7 @@ Fengtu Wang Ferenc Szabo Fernando Fero Volar +Feroz Salam Ferran Rodenas Filipe Brandenburger Filipe Oliveira @@ -673,6 +735,7 @@ Florin Patan fonglh Foysal Iqbal Francesc Campoy +Francesco Degrassi Francesco Mari Francis Chuang Francisco Carriedo @@ -681,18 +744,24 @@ Frank Groeneveld Frank Herrmann Frank Macreery Frank Rosquin -frankyang +Frank Yang Fred Lifton Frederick F. Kautz IV +Frederico F. de Oliveira Frederik Loeffert Frederik Nordahl Jul Sabroe Freek Kalter Frieder Bluemle +frobnicaty <92033765+frobnicaty@users.noreply.github.com> +Frédéric Dalleau Fu JinLin Félix Baylac-Jacqué Félix Cantournet Gabe Rosenhouse Gabor Nagy +Gabriel Adrian Samfira +Gabriel Goller +Gabriel L. Somlo Gabriel Linder Gabriel Monroy Gabriel Nicolas Avellaneda @@ -707,12 +776,14 @@ Gaurav Singh Gaël PORTAY Genki Takiuchi GennadySpb +Geoff Levand Geoffrey Bachelet Geon Kim George Kontridze George MacRorie George Xie Georgi Hristozov +Georgy Yakovlev Gereon Frey German DZ Gert van Valkenhoef @@ -724,6 +795,7 @@ Gildas Cuisinier Giovan Isa Musthofa gissehel Giuseppe Mazzotta +Giuseppe Scrivano Gleb Fotengauer-Malinovskiy Gleb M Borisov Glyn Normington @@ -746,6 +818,8 @@ Guilhem Lettron Guilherme Salgado Guillaume Dufour Guillaume J. Charmes +Gunadhya S. <6939749+gunadhya@users.noreply.github.com> +Guoqiang QI guoxiuyan Guri Gurjeet Singh @@ -755,12 +829,13 @@ gwx296173 Günter Zöchbauer Haichao Yang haikuoliu +haining.cao Hakan Özler Hamish Hutchings Hannes Ljungberg Hans Kristian Flaatten Hans Rødtang -Hao Shu Wei +Hao Shu Wei Hao Zhang <21521210@zju.edu.cn> Harald Albers Harald Niesche @@ -786,21 +861,23 @@ Hongbin Lu Hongxu Jia Honza Pokorny Hsing-Hui Hsu +Hsing-Yu (David) Chen hsinko <21551195@zju.edu.cn> Hu Keping Hu Tao HuanHuan Ye Huanzhong Zhang Huayi Zhang +Hugo Barrera Hugo Duncan Hugo Marisco <0x6875676f@gmail.com> +Hui Kang Hunter Blanks huqun Huu Nguyen -hyeongkyu.lee +Hyeongkyu Lee Hyzhou Zhy Iago López Galeiras -Ian Babrou Ian Bishop Ian Bull Ian Calvert @@ -817,6 +894,8 @@ Igor Dolzhikov Igor Karpovich Iliana Weller Ilkka Laukkanen +Illia Antypenko +Illo Abdulrahim Ilya Dmitrichenko Ilya Gusev Ilya Khlopotov @@ -847,7 +926,8 @@ Jaivish Kothari Jake Champlin Jake Moshenko Jake Sanders -jakedt +Jakub Drahos +Jakub Guzik James Allen James Carey James Carr @@ -859,11 +939,15 @@ James Lal James Mills James Nesbitt James Nugent +James Sanders James Turnbull James Watkins-Harvey Jamie Hannaford Jamshid Afshar +Jan Breig Jan Chren +Jan Garcia +Jan Götte Jan Keromnes Jan Koprowski Jan Pazdziora @@ -876,7 +960,6 @@ Januar Wayong Jared Biel Jared Hocutt Jaroslaw Zabiello -jaseg Jasmine Hegman Jason A. Donenfeld Jason Divock @@ -891,10 +974,11 @@ Jason Shepherd Jason Smith Jason Sommer Jason Stangroome +Javier Bassi jaxgeller -Jay Jay Jay Kamat +Jay Lim Jean Rouge Jean-Baptiste Barth Jean-Baptiste Dalido @@ -912,12 +996,14 @@ Jeff Minard Jeff Nickoloff Jeff Silberman Jeff Welch +Jeff Zvier Jeffrey Bolle Jeffrey Morgan Jeffrey van Gogh Jenny Gebske Jeremy Chambers Jeremy Grosser +Jeremy Huntwork Jeremy Price Jeremy Qian Jeremy Unruh @@ -933,13 +1019,16 @@ Ji.Zhilong Jian Liao Jian Zhang Jiang Jinyang +Jianyong Wu Jie Luo Jie Ma Jihyun Hwang Jilles Oldenbeuving Jim Alateras +Jim Carroll Jim Ehrismann Jim Galasyn +Jim Lin Jim Minter Jim Perrin Jimmy Cuadra @@ -951,6 +1040,7 @@ Jiri Appl Jiri Popelka Jiuyue Ma Jiří Župka +Joakim Roubert Joao Fernandes Joao Trindade Joe Beda @@ -1012,6 +1102,7 @@ Joost Cassee Jordan Arentsen Jordan Jennings Jordan Sissel +Jordi Massaguer Pla Jorge Marin Jorit Kleine-Möllhoff Jose Diaz-Gonzalez @@ -1044,12 +1135,15 @@ Julien Pervillé Julien Pivotto Julio Guerra Julio Montes +Jun Du Jun-Ru Chang +junxu Jussi Nummelin Justas Brazauskas Justen Martin Justin Cormack Justin Force +Justin Keller <85903732+jk-vb@users.noreply.github.com> Justin Menga Justin Plock Justin Simonelis @@ -1062,6 +1156,7 @@ Jörg Thalheim K. Heller Kai Blin Kai Qiang Wu (Kennan) +Kaijie Chen Kamil Domański Kamjar Gerami Kanstantsin Shautsou @@ -1082,6 +1177,7 @@ Kawsar Saiyeed Kay Yan kayrus Kazuhiro Sera +Kazuyoshi Kato Ke Li Ke Xu Kei Ohmura @@ -1096,6 +1192,7 @@ Kenjiro Nakayama Kent Johnson Kenta Tada Kevin "qwazerty" Houdebert +Kevin Alvarez Kevin Burke Kevin Clark Kevin Feyrer @@ -1118,24 +1215,27 @@ Kimbro Staken Kir Kolyshkin Kiran Gangadharan Kirill SIbirev +Kirk Easterson knappe Kohei Tsuruta Koichi Shiraishi Konrad Kleine +Konrad Ponichtera Konstantin Gribov Konstantin L Konstantin Pelykh +Kostadin Plachkov Krasi Georgiev Krasimir Georgiev Kris-Mikael Krister Kristian Haugene Kristina Zabunova Krystian Wojcicki -Kun Zhang Kunal Kushwaha Kunal Tyagi Kyle Conroy Kyle Linden +Kyle Squizzato Kyle Wuolle kyu Lachlan Coote @@ -1150,21 +1250,28 @@ Lars Kellogg-Stedman Lars R. Damerow Lars-Magnus Skog Laszlo Meszaros +Laura Brehm Laura Frank +Laurent Bernaille Laurent Erignoux Laurie Voss +Leandro Motta Barros Leandro Siqueira +Lee Calcote Lee Chao <932819864@qq.com> Lee, Meng-Han -leeplay Lei Gong Lei Jitang +Leiiwang Len Weincier Lennie Leo Gallucci +Leonardo Nodari +Leonardo Taccari Leszek Kowalski Levi Blackstone Levi Gross +Levi Harrison Lewis Daly Lewis Marshall Lewis Peckover @@ -1173,11 +1280,12 @@ Liam Macgillavry Liana Lo Liang Mingqiang Liang-Chi Hsieh +liangwei Liao Qingwei Lifubang Lihua Tang Lily Guo -limsy +limeidan Lin Lu LingFaKe Linus Heckemann @@ -1207,6 +1315,7 @@ Lucas Chi Lucas Molas Lucas Silvestre Luciano Mores +Luis Henrique Mulinari Luis Martínez de Bartolomé Izquierdo Luiz Svoboda Lukas Heeren @@ -1222,7 +1331,7 @@ Ma Shimiao Mabin Madhan Raj Mookkandy Madhav Puri -Madhu Venugopal +Madhu Venugopal Mageee Mahesh Tiyyagura malnick @@ -1255,12 +1364,14 @@ Marius Gundersen Marius Sturm Marius Voila Mark Allen +Mark Feit Mark Jeromin Mark McGranaghan Mark McKinstry Mark Milstein Mark Oates Mark Parker +Mark Vainomaa Mark West Markan Patel Marko Mikulicic @@ -1269,11 +1380,14 @@ Markus Fix Markus Kortlang Martijn Dwars Martijn van Oosterhout +Martin Braun +Martin Dojcak Martin Honermeyer Martin Kelly Martin Mosegaard Amdisen Martin Muzatko Martin Redmond +Maru Newby Mary Anthony Masahito Zembutsu Masato Ohba @@ -1284,13 +1398,16 @@ Mathias Monnerville Mathieu Champlon Mathieu Le Marec - Pasquet Mathieu Parent +Mathieu Paturel Matt Apperson Matt Bachmann +Matt Bajor Matt Bentley Matt Haggard Matt Hoyle Matt McCormick Matt Moore +Matt Morrison <3maven@gmail.com> Matt Richardson Matt Rickard Matt Robenolt @@ -1305,12 +1422,14 @@ Matthew Riley Matthias Klumpp Matthias Kühnle Matthias Rampke +Matthieu Fronton Matthieu Hauglustaine Mattias Jernberg Mauricio Garavaglia mauriyouth Max Harmathy Max Shytikov +Max Timchenko Maxim Fedchyshyn Maxim Ivanov Maxim Kulkin @@ -1324,14 +1443,16 @@ Megan Kostick Mehul Kar Mei ChunTao Mengdi Gao +Menghui Chen Mert Yazıcıoğlu mgniu Micah Zoltu Michael A. Smith +Michael Beskin Michael Bridgen Michael Brown Michael Chiang -Michael Crosby +Michael Crosby Michael Currie Michael Friis Michael Gorsuch @@ -1340,6 +1461,7 @@ Michael Holzheu Michael Hudson-Doyle Michael Huettermann Michael Irwin +Michael Kuehn Michael Käufl Michael Neale Michael Nussbaum @@ -1349,23 +1471,29 @@ Michael Spetsiotis Michael Stapelberg Michael Steinert Michael Thies +Michael Weidmann Michael West Michael Zhao Michal Fojtik Michal Gebauer Michal Jemala +Michal Kostrzewa Michal Minář +Michal Rostecki Michal Wieczorek Michaël Pailloncy Michał Czeraszkiewicz Michał Gryko +Michał Kosek Michiel de Jong Mickaël Fortunato Mickaël Remars Miguel Angel Fernández Miguel Morales +Miguel Perez Mihai Borobocea Mihuleacc Sergiu +Mikael Davranche Mike Brown Mike Bush Mike Casas @@ -1384,6 +1512,7 @@ Mike Snitzer mikelinjie <294893458@qq.com> Mikhail Sobolev Miklos Szegedi +Milas Bowman Milind Chawre Miloslav Trmač mingqing @@ -1392,7 +1521,7 @@ Misty Stanley-Jones Mitch Capper Mizuki Urushida mlarcher -Mohammad Banikazemi +Mohammad Banikazemi Mohammad Nasirifar Mohammed Aaqib Ansari Mohit Soni @@ -1406,6 +1535,7 @@ Moysés Borges mrfly Mrunal Patel Muayyad Alsadi +Muhammad Zohaib Aslam Mustafa Akın Muthukumar R Máximo Cuadros @@ -1422,6 +1552,8 @@ Natasha Jarus Nate Brennand Nate Eagleson Nate Jones +Nathan Carlson +Nathan Herald Nathan Hsieh Nathan Kleyn Nathan LeClaire @@ -1443,8 +1575,10 @@ Nick Neisen Nick Parker Nick Payne Nick Russo +Nick Santos Nick Stenning Nick Stinemates +Nick Wood NickrenREN Nicola Kabar Nicolas Borboën @@ -1455,6 +1589,7 @@ Nicolas Kaiser Nicolas Sterchele Nicolas V Castet Nicolás Hock Isaza +Niel Drummond Nigel Poulton Nik Nyby Nikhil Chawla @@ -1462,6 +1597,7 @@ NikolaMandic Nikolas Garofil Nikolay Edigaryev Nikolay Milovanov +ningmingxiao Nirmal Mehta Nishant Totla NIWA Hideyuki @@ -1472,6 +1608,7 @@ noducks Nolan Darilek Noriki Nakamura nponeccop +Nurahmadie Nuutti Kotivuori nzwsch O.S. Tezer @@ -1489,7 +1626,10 @@ Olle Jonsson Olli Janatuinen Olly Pomeroy Omri Shiv +Onur Filiz Oriol Francès +Oscar Bonilla <6f6231@gmail.com> +oscar.chen <2972789494@qq.com> Oskar Niburski Otto Kekäläinen Ouyang Liduo @@ -1502,10 +1642,12 @@ Pascal Borreli Pascal Hartig Patrick Böänziger Patrick Devine +Patrick Haas Patrick Hemmer Patrick Stapleton Patrik Cyvoct pattichen +Paul "TBBle" Hampson Paul paul Paul Annesley @@ -1520,6 +1662,7 @@ Paul Liljenberg Paul Morie Paul Nasrat Paul Weaver +Paulo Gomes Paulo Ribeiro Pavel Lobashov Pavel Matěja @@ -1530,6 +1673,7 @@ Pavel Tikhomirov Pavlos Ratis Pavol Vargovcik Pawel Konczalski +Paweł Gronowski Peeyush Gupta Peggy Li Pei Su @@ -1537,6 +1681,7 @@ Peng Tao Penghan Wang Per Weijnitz perhapszzy@sina.com +Pete Woods Peter Bourgon Peter Braden Peter Bücker @@ -1552,8 +1697,10 @@ Peter Salvatore Peter Volpe Peter Waller Petr Švihlík +Petros Angelatos Phil -Phil Estes +Phil Estes +Phil Sphicas Phil Spitler Philip Alexander Etling Philip Monroe @@ -1570,21 +1717,25 @@ Pierre Dal-Pra Pierre Wacrenier Pierre-Alain RIVIERE Piotr Bogdan -pixelistik +Piotr Karbowski Porjo Poul Kjeldager Sørensen Pradeep Chhetri Pradip Dhara +Pradipta Kr. Banerjee Prasanna Gautam Pratik Karki Prayag Verma Priya Wadhwa Projjol Banerji Przemek Hejman +Puneet Pruthi Pure White pysqz Qiang Huang +Qin TianHuan Qinglan Peng +Quan Tian qudongfang Quentin Brossard Quentin Perez @@ -1607,6 +1758,7 @@ Ramon van Alteren RaviTeja Pothana Ray Tsang ReadmeCritic +realityone Recursive Madman Reficul Regan McCooey @@ -1617,9 +1769,9 @@ Renaud Gaubert Rhys Hiltner Ri Xu Ricardo N Feliciano +Rich Horwood Rich Moyse Rich Seymour -Richard Richard Burnison Richard Harvey Richard Mathie @@ -1634,12 +1786,14 @@ Riku Voipio Riley Guerin Ritesh H Shukla Riyaz Faizullabhoy +Rob Cowsill <42620235+rcowsill@users.noreply.github.com> Rob Gulewich Rob Vesse Robert Bachmann Robert Bittle Robert Obryk Robert Schneider +Robert Shade Robert Stern Robert Terhaar Robert Wallis @@ -1652,6 +1806,7 @@ Robin Speekenbrink Robin Thoni robpc Rodolfo Carvalho +Rodrigo Campos Rodrigo Vaz Roel Van Nyen Roger Peppe @@ -1666,11 +1821,14 @@ Roma Sokolov Roman Dudin Roman Mazur Roman Strashkin +Roman Volosatovs +Roman Zabaluev Ron Smits Ron Williams Rong Gao Rong Zhang Rongxiang Song +Rony Weng root root root @@ -1679,6 +1837,7 @@ Rory Hunter Rory McCune Ross Boucher Rovanion Luckey +Roy Reznik Royce Remer Rozhnov Alexandr Rudolph Gottesheim @@ -1690,13 +1849,16 @@ Russ Magee Ryan Abrams Ryan Anderson Ryan Aslett +Ryan Barry Ryan Belgrave +Ryan Campbell Ryan Detzel Ryan Fowler Ryan Liu Ryan McLaughlin Ryan O'Donnell Ryan Seto +Ryan Shea Ryan Simmen Ryan Stelly Ryan Thomas @@ -1706,9 +1868,9 @@ Ryan Zhang ryancooper7 RyanDeng Ryo Nakao +Ryoga Saito Rémy Greinhofer s. rannou -s00318865 Sabin Basyal Sachin Joshi Sagar Hani @@ -1728,8 +1890,9 @@ Sambuddha Basu Sami Wagiaalla Samuel Andaya Samuel Dion-Girardeau -Samuel Karp +Samuel Karp Samuel PHAN +sanchayanghosh Sandeep Bansal Sankar சங்கர் Sanket Saurav @@ -1745,6 +1908,7 @@ Satoshi Tagomori Scott Bessler Scott Collier Scott Johnston +Scott Percival Scott Stamp Scott Walls sdreyesg @@ -1757,6 +1921,9 @@ Sean P. Kane Sean Rodman Sebastiaan van Steenis Sebastiaan van Stijn +Sebastian Höffner +Sebastian Radloff +Sebastien Goasguen Senthil Kumar Selvaraj Senthil Kumaran SeongJae Park @@ -1776,12 +1943,15 @@ shaunol Shawn Landden Shawn Siefkas shawnhe +Shayan Pooya Shayne Wang Shekhar Gulati Sheng Yang Shengbo Song +Shengjing Zhu Shev Yan Shih-Yuan Lee +Shihao Xia Shijiang Wei Shijun Qin Shishir Mahajan @@ -1790,14 +1960,13 @@ Shourya Sarcar Shu-Wai Chow shuai-z Shukui Yang -Shuwei Hao Sian Lerk Lau +Siarhei Rasiukevich Sidhartha Mani sidharthamani Silas Sewell Silvan Jegen Simão Reis -Simei He Simon Barendse Simon Eskildsen Simon Ferquel @@ -1808,13 +1977,16 @@ Simon Vikstrom Sindhu S Sjoerd Langkemper skanehira +Smark Meng Solganik Alexander Solomon Hykes Song Gao Soshi Katsuta +Sotiris Salloumis Soulou Spencer Brown Spencer Smith +Spike Curtis Sridatta Thatipamala Sridhar Ratnakumar Srini Brahmaroutu @@ -1830,6 +2002,7 @@ Stefan S. Stefan Scherer Stefan Staudenmeyer Stefan Weil +Steffen Butzer Stephan Spindler Stephen Benjamin Stephen Crosby @@ -1848,7 +2021,9 @@ Steven Iveson Steven Merrill Steven Richards Steven Taylor +Stéphane Este-Gracias Stig Larsson +Su Wang Subhajit Ghosh Sujith Haridasan Sun Gengze <690388648@qq.com> @@ -1858,15 +2033,16 @@ Sunny Gogoi Suryakumar Sudar Sven Dowideit Swapnil Daingade -Sylvain Baubeau +Sylvain Baubeau Sylvain Bellemare Sébastien Sébastien HOUZÉ Sébastien Luttringer Sébastien Stormacq +Sören Tempel Tabakhase Tadej Janež -TAGOMORI Satoshi +Takuto Sato tang0th Tangi Colin Tatsuki Sugiura @@ -1877,18 +2053,21 @@ Ted M. Young Tehmasp Chaudhri Tejaswini Duggaraju Tejesh Mehta +Terry Chu terryding77 <550147740@qq.com> -tgic Thatcher Peskens theadactyl Thell 'Bo' Fowler Thermionix +Thiago Alves Silva Thijs Terlouw Thomas Bikeev Thomas Frössman Thomas Gazagnaire +Thomas Graf Thomas Grainger Thomas Hansen +Thomas Ledos Thomas Leonard Thomas Léveil Thomas Orozco @@ -1899,11 +2078,13 @@ Thomas Swift Thomas Tanaka Thomas Texier Ti Zhou +Tiago Seabra Tianon Gravi Tianyi Wang Tibor Vass Tiffany Jernigan Tiffany Low +Till Claassen Till Wegmüller Tim Tim Bart @@ -1915,11 +2096,14 @@ Tim Potter Tim Ruffles Tim Smith Tim Terhorst +Tim Wagner Tim Wang Tim Waugh Tim Wraight Tim Zju <21651152@zju.edu.cn> +timchenxiaoyu <837829664@qq.com> timfeirg +Timo Rothenpieler Timothy Hobbs tjwebb123 tobe @@ -1928,6 +2112,7 @@ Tobias Bradtke Tobias Gesellchen Tobias Klauser Tobias Munk +Tobias Pfandzelter Tobias Schmidt Tobias Schwab Todd Crane @@ -1941,25 +2126,33 @@ Tom Fotherby Tom Howe Tom Hulihan Tom Maaswinkel +Tom Parker Tom Sweeney Tom Wilkie Tom X. Tobin +Tom Zhao +Tomas Janousek +Tomas Kral Tomas Tomecek Tomasz Kopczynski Tomasz Lipinski Tomasz Nurkiewicz +Tomek Mańko Tommaso Visconti +Tomoya Tabuchi Tomáš Hrčka +tonic Tonny Xu Tony Abboud Tony Daws Tony Miller toogley Torstein Husebø +Toshiaki Makita Tõnis Tiigi Trace Andreason tracylihui <793912329@qq.com> -Trapier Marshall +Trapier Marshall Travis Cline Travis Thieman Trent Ogren @@ -1969,6 +2162,8 @@ Trevor Sullivan Trishna Guha Tristan Carel Troy Denton +Tudor Brindus +Ty Alexander Tycho Andersen Tyler Brock Tyler Brown @@ -1979,6 +2174,7 @@ Umesh Yadav Utz Bacher vagrant Vaidas Jablonskis +Valentin Kulesh vanderliang Velko Ivanov Veres Lajos @@ -1992,12 +2188,13 @@ Victor Palma Victor Vieux Victoria Bialas Vijaya Kumar K +Vikas Choudhary Vikram bir Singh Viktor Stanchev Viktor Vojnovski VinayRaghavanKS Vincent Batts -Vincent Bernat +Vincent Bernat Vincent Boulineau Vincent Demeester Vincent Giersch @@ -2017,9 +2214,9 @@ Vladimir Pouzanov Vladimir Rutsky Vladimir Varankin VladimirAus +Vladislav Kolesnikov Vlastimil Zeman Vojtech Vitek (V-Teq) -waitingkuo Walter Leibbrandt Walter Stanish Wang Chao @@ -2034,6 +2231,7 @@ wanghuaiqing Ward Vandewege WarheadsSE Wassim Dhif +Wataru Ishida Wayne Chang Wayne Song Weerasak Chongnguluam @@ -2048,7 +2246,6 @@ Wendel Fleming Wenjun Tang Wenkai Yin wenlxie -Wentao Zhang Wenxuan Zhao Wenyu You <21551128@zju.edu.cn> Wenzhi Liang @@ -2068,22 +2265,29 @@ William Thurston Wilson Júnior Wing-Kam Wong WiseTrem +Wolfgang Nagele Wolfgang Powisch Wonjun Kim +WuLonghui xamyzhao +Xia Wu Xian Chaobo Xianglin Gao +Xianjie Xianlu Bird Xiao YongBiao +Xiao Zhang XiaoBing Jiang Xiaodong Liu Xiaodong Zhang +Xiaohua Ding Xiaoxi He Xiaoxu Chen Xiaoyu Zhang xichengliudui <1693291525@qq.com> xiekeyang Ximo Guanter Gonzálbez +xin.li Xinbo Weng Xinfeng Liu Xinzi Zhou @@ -2092,12 +2296,17 @@ Xuecong Liao xuzhaokui Yadnyawalkya Tale Yahya +yalpul YAMADA Tsuyoshi Yamasaki Masahide +Yamazaki Masashi Yan Feng +Yan Zhu Yang Bai +Yang Li Yang Pengfei yangchenliang +Yann Autissier Yanqiang Miao Yao Zaiyong Yash Murty @@ -2117,6 +2326,7 @@ Yosef Fertel You-Sheng Yang (楊有勝) youcai Youcef YEKHLEF +Youfu Zhang Yu Changchun Yu Chengxia Yu Peng @@ -2124,14 +2334,18 @@ Yu-Ju Hong Yuan Sun Yuanhong Peng Yue Zhang +Yufei Xiong Yuhao Fang Yuichiro Kaneko +YujiOshima Yunxiang Huang Yurii Rashkovskii Yusuf Tarık Günaydın +Yves Blusseau <90z7oey02@sneakemail.com> Yves Junqueira Zac Dover Zach Borboa +Zach Gershman Zachary Jaffee Zain Memon Zaiste! @@ -2147,6 +2361,7 @@ Zhenan Ye <21551168@zju.edu.cn> zhenghenghuo Zhenhai Gao Zhenkun Bi +ZhiPeng Lu zhipengzuo Zhou Hao Zhoulin Xie @@ -2164,7 +2379,6 @@ Zou Yu zqh Zuhayr Elahi Zunayed Ali -Álex González Álvaro Lázaro Átila Camurça Alves 尹吉峰 @@ -2173,3 +2387,4 @@ Zunayed Ali 慕陶 搏通 黄艳红00139573 +정재영 diff --git a/vendor/github.com/docker/docker/api/types/auth.go b/vendor/github.com/docker/docker/api/types/auth.go index ddf15bb182d..9ee329a2fba 100644 --- a/vendor/github.com/docker/docker/api/types/auth.go +++ b/vendor/github.com/docker/docker/api/types/auth.go @@ -1,22 +1,7 @@ package types // import "github.com/docker/docker/api/types" +import "github.com/docker/docker/api/types/registry" -// AuthConfig contains authorization information for connecting to a Registry -type AuthConfig struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Auth string `json:"auth,omitempty"` - - // Email is an optional value associated with the username. - // This field is deprecated and will be removed in a later - // version of docker. - Email string `json:"email,omitempty"` - - ServerAddress string `json:"serveraddress,omitempty"` - - // IdentityToken is used to authenticate the user and get - // an access token for the registry. - IdentityToken string `json:"identitytoken,omitempty"` - - // RegistryToken is a bearer token to be sent to a registry - RegistryToken string `json:"registrytoken,omitempty"` -} +// AuthConfig contains authorization information for connecting to a Registry. +// +// Deprecated: use github.com/docker/docker/api/types/registry.AuthConfig +type AuthConfig = registry.AuthConfig diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index 9c464b73e25..d8cd3061354 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/registry" units "github.com/docker/go-units" ) @@ -59,7 +60,6 @@ type ContainerExecInspect struct { // ContainerListOptions holds parameters to list containers with. type ContainerListOptions struct { - Quiet bool Size bool All bool Latest bool @@ -113,10 +113,16 @@ type NetworkListOptions struct { Filters filters.Args } +// NewHijackedResponse intializes a HijackedResponse type +func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { + return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} +} + // HijackedResponse holds connection information for a hijacked request. type HijackedResponse struct { - Conn net.Conn - Reader *bufio.Reader + mediaType string + Conn net.Conn + Reader *bufio.Reader } // Close closes the hijacked connection and reader. @@ -124,6 +130,15 @@ func (h *HijackedResponse) Close() { h.Conn.Close() } +// MediaType let client know if HijackedResponse hold a raw or multiplexed stream. +// returns false if HTTP Content-Type is not relevant, and container must be inspected +func (h *HijackedResponse) MediaType() (string, bool) { + if h.mediaType == "" { + return "", false + } + return h.mediaType, true +} + // CloseWriter is an interface that implements structs // that close input streams to prevent from writing. type CloseWriter interface { @@ -166,7 +181,7 @@ type ImageBuildOptions struct { // at all (nil). See the parsing of buildArgs in // api/server/router/build/build_routes.go for even more info. BuildArgs map[string]*string - AuthConfigs map[string]AuthConfig + AuthConfigs map[string]registry.AuthConfig Context io.Reader Labels map[string]string // squash the resulting image's layers to the parent @@ -236,10 +251,20 @@ type ImageImportOptions struct { Platform string // Platform is the target platform of the image } -// ImageListOptions holds parameters to filter the list of images with. +// ImageListOptions holds parameters to list images with. type ImageListOptions struct { - All bool + // All controls whether all images in the graph are filtered, or just + // the heads. + All bool + + // Filters is a JSON-encoded set of filter arguments. Filters filters.Args + + // SharedSize indicates whether the shared size of images should be computed. + SharedSize bool + + // ContainerCount indicates whether container count should be computed. + ContainerCount bool } // ImageLoadResponse returns information to the client about a load process. diff --git a/vendor/github.com/docker/docker/api/types/configs.go b/vendor/github.com/docker/docker/api/types/configs.go index 3dd133a3a58..7d5930bbeb6 100644 --- a/vendor/github.com/docker/docker/api/types/configs.go +++ b/vendor/github.com/docker/docker/api/types/configs.go @@ -3,7 +3,7 @@ package types // import "github.com/docker/docker/api/types" import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" - specs "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // configs holds structs used for internal communication between the @@ -16,7 +16,7 @@ type ContainerCreateConfig struct { Config *container.Config HostConfig *container.HostConfig NetworkingConfig *network.NetworkingConfig - Platform *specs.Platform + Platform *ocispec.Platform AdjustCPUShares bool } @@ -33,6 +33,7 @@ type ExecConfig struct { User string // User that will run the command Privileged bool // Is the container in privileged mode Tty bool // Attach standard streams to a tty. + ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width] AttachStdin bool // Attach the standard input, makes possible user interaction AttachStderr bool // Attach the standard error AttachStdout bool // Attach the standard output diff --git a/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go b/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go new file mode 100644 index 00000000000..6b4b47390d4 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go @@ -0,0 +1,6 @@ +package container + +// ContainerChangeResponseItem change item in response to ContainerChanges operation +// +// Deprecated: use [FilesystemChange]. +type ContainerChangeResponseItem = FilesystemChange diff --git a/vendor/github.com/docker/docker/api/types/container/change_type.go b/vendor/github.com/docker/docker/api/types/container/change_type.go new file mode 100644 index 00000000000..fe8d6d36966 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_type.go @@ -0,0 +1,15 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// ChangeType Kind of change +// +// Can be one of: +// +// - `0`: Modified ("C") +// - `1`: Added ("A") +// - `2`: Deleted ("D") +// +// swagger:model ChangeType +type ChangeType uint8 diff --git a/vendor/github.com/docker/docker/api/types/container/change_types.go b/vendor/github.com/docker/docker/api/types/container/change_types.go new file mode 100644 index 00000000000..3a3a83866ec --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_types.go @@ -0,0 +1,23 @@ +package container + +const ( + // ChangeModify represents the modify operation. + ChangeModify ChangeType = 0 + // ChangeAdd represents the add operation. + ChangeAdd ChangeType = 1 + // ChangeDelete represents the delete operation. + ChangeDelete ChangeType = 2 +) + +func (ct ChangeType) String() string { + switch ct { + case ChangeModify: + return "C" + case ChangeAdd: + return "A" + case ChangeDelete: + return "D" + default: + return "" + } +} diff --git a/vendor/github.com/docker/docker/api/types/container/config.go b/vendor/github.com/docker/docker/api/types/container/config.go index f767195b94b..077583e66c1 100644 --- a/vendor/github.com/docker/docker/api/types/container/config.go +++ b/vendor/github.com/docker/docker/api/types/container/config.go @@ -1,6 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" import ( + "io" "time" "github.com/docker/docker/api/types/strslice" @@ -13,6 +14,24 @@ import ( // Docker interprets it as 3 nanoseconds. const MinimumDuration = 1 * time.Millisecond +// StopOptions holds the options to stop or restart a container. +type StopOptions struct { + // Signal (optional) is the signal to send to the container to (gracefully) + // stop it before forcibly terminating the container with SIGKILL after the + // timeout expires. If not value is set, the default (SIGTERM) is used. + Signal string `json:",omitempty"` + + // Timeout (optional) is the timeout (in seconds) to wait for the container + // to stop gracefully before forcibly terminating it with SIGKILL. + // + // - Use nil to use the default timeout (10 seconds). + // - Use '-1' to wait indefinitely. + // - Use '0' to not wait for the container to exit gracefully, and + // immediately proceeds to forcibly terminating the container. + // - Other positive values are used as timeout (in seconds). + Timeout *int `json:",omitempty"` +} + // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { // Test is the test to perform to check that the container is healthy. @@ -34,6 +53,14 @@ type HealthConfig struct { Retries int `json:",omitempty"` } +// ExecStartOptions holds the options to start container's exec. +type ExecStartOptions struct { + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + ConsoleSize *[2]uint `json:",omitempty"` +} + // Config contains the configuration data about a container. // It should hold only portable information about the container. // Here, "portable" means "independent from the host we are running on". diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go deleted file mode 100644 index 16dd5019eef..00000000000 --- a/vendor/github.com/docker/docker/api/types/container/container_changes.go +++ /dev/null @@ -1,20 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// ContainerChangeResponseItem change item in response to ContainerChanges operation -// swagger:model ContainerChangeResponseItem -type ContainerChangeResponseItem struct { - - // Kind of change - // Required: true - Kind uint8 `json:"Kind"` - - // Path to file that has changed - // Required: true - Path string `json:"Path"` -} diff --git a/vendor/github.com/docker/docker/api/types/container/container_create.go b/vendor/github.com/docker/docker/api/types/container/container_create.go deleted file mode 100644 index d0c852f84d5..00000000000 --- a/vendor/github.com/docker/docker/api/types/container/container_create.go +++ /dev/null @@ -1,20 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// ContainerCreateCreatedBody OK response to ContainerCreate operation -// swagger:model ContainerCreateCreatedBody -type ContainerCreateCreatedBody struct { - - // The ID of the created container - // Required: true - ID string `json:"Id"` - - // Warnings encountered when creating the container - // Required: true - Warnings []string `json:"Warnings"` -} diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go deleted file mode 100644 index 49e05ae6694..00000000000 --- a/vendor/github.com/docker/docker/api/types/container/container_wait.go +++ /dev/null @@ -1,28 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// ContainerWaitOKBodyError container waiting error, if any -// swagger:model ContainerWaitOKBodyError -type ContainerWaitOKBodyError struct { - - // Details of an error - Message string `json:"Message,omitempty"` -} - -// ContainerWaitOKBody OK response to ContainerWait operation -// swagger:model ContainerWaitOKBody -type ContainerWaitOKBody struct { - - // error - // Required: true - Error *ContainerWaitOKBodyError `json:"Error"` - - // Exit code of the container - // Required: true - StatusCode int64 `json:"StatusCode"` -} diff --git a/vendor/github.com/docker/docker/api/types/container/create_response.go b/vendor/github.com/docker/docker/api/types/container/create_response.go new file mode 100644 index 00000000000..aa0e7f7d078 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/create_response.go @@ -0,0 +1,19 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// CreateResponse ContainerCreateResponse +// +// OK response to ContainerCreate operation +// swagger:model CreateResponse +type CreateResponse struct { + + // The ID of the created container + // Required: true + ID string `json:"Id"` + + // Warnings encountered when creating the container + // Required: true + Warnings []string `json:"Warnings"` +} diff --git a/vendor/github.com/docker/docker/api/types/container/filesystem_change.go b/vendor/github.com/docker/docker/api/types/container/filesystem_change.go new file mode 100644 index 00000000000..9e9c2ad1d58 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/filesystem_change.go @@ -0,0 +1,19 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// FilesystemChange Change in the container's filesystem. +// +// swagger:model FilesystemChange +type FilesystemChange struct { + + // kind + // Required: true + Kind ChangeType `json:"Kind"` + + // Path to file or directory that has changed. + // + // Required: true + Path string `json:"Path"` +} diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go deleted file mode 100644 index 2d1cbaa9abd..00000000000 --- a/vendor/github.com/docker/docker/api/types/container/host_config.go +++ /dev/null @@ -1,447 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -import ( - "strings" - - "github.com/docker/docker/api/types/blkiodev" - "github.com/docker/docker/api/types/mount" - "github.com/docker/docker/api/types/strslice" - "github.com/docker/go-connections/nat" - units "github.com/docker/go-units" -) - -// CgroupnsMode represents the cgroup namespace mode of the container -type CgroupnsMode string - -// IsPrivate indicates whether the container uses its own private cgroup namespace -func (c CgroupnsMode) IsPrivate() bool { - return c == "private" -} - -// IsHost indicates whether the container shares the host's cgroup namespace -func (c CgroupnsMode) IsHost() bool { - return c == "host" -} - -// IsEmpty indicates whether the container cgroup namespace mode is unset -func (c CgroupnsMode) IsEmpty() bool { - return c == "" -} - -// Valid indicates whether the cgroup namespace mode is valid -func (c CgroupnsMode) Valid() bool { - return c.IsEmpty() || c.IsPrivate() || c.IsHost() -} - -// Isolation represents the isolation technology of a container. The supported -// values are platform specific -type Isolation string - -// IsDefault indicates the default isolation technology of a container. On Linux this -// is the native driver. On Windows, this is a Windows Server Container. -func (i Isolation) IsDefault() bool { - return strings.ToLower(string(i)) == "default" || string(i) == "" -} - -// IsHyperV indicates the use of a Hyper-V partition for isolation -func (i Isolation) IsHyperV() bool { - return strings.ToLower(string(i)) == "hyperv" -} - -// IsProcess indicates the use of process isolation -func (i Isolation) IsProcess() bool { - return strings.ToLower(string(i)) == "process" -} - -const ( - // IsolationEmpty is unspecified (same behavior as default) - IsolationEmpty = Isolation("") - // IsolationDefault is the default isolation mode on current daemon - IsolationDefault = Isolation("default") - // IsolationProcess is process isolation mode - IsolationProcess = Isolation("process") - // IsolationHyperV is HyperV isolation mode - IsolationHyperV = Isolation("hyperv") -) - -// IpcMode represents the container ipc stack. -type IpcMode string - -// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared. -func (n IpcMode) IsPrivate() bool { - return n == "private" -} - -// IsHost indicates whether the container shares the host's ipc namespace. -func (n IpcMode) IsHost() bool { - return n == "host" -} - -// IsShareable indicates whether the container's ipc namespace can be shared with another container. -func (n IpcMode) IsShareable() bool { - return n == "shareable" -} - -// IsContainer indicates whether the container uses another container's ipc namespace. -func (n IpcMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// IsNone indicates whether container IpcMode is set to "none". -func (n IpcMode) IsNone() bool { - return n == "none" -} - -// IsEmpty indicates whether container IpcMode is empty -func (n IpcMode) IsEmpty() bool { - return n == "" -} - -// Valid indicates whether the ipc mode is valid. -func (n IpcMode) Valid() bool { - return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer() -} - -// Container returns the name of the container ipc stack is going to be used. -func (n IpcMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 && parts[0] == "container" { - return parts[1] - } - return "" -} - -// NetworkMode represents the container network stack. -type NetworkMode string - -// IsNone indicates whether container isn't using a network stack. -func (n NetworkMode) IsNone() bool { - return n == "none" -} - -// IsDefault indicates whether container uses the default network stack. -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - -// IsPrivate indicates whether container uses its private network stack. -func (n NetworkMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsContainer indicates whether container uses a container network stack. -func (n NetworkMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// ConnectedContainer is the id of the container which network this container is connected to. -func (n NetworkMode) ConnectedContainer() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// UserDefined indicates user-created network -func (n NetworkMode) UserDefined() string { - if n.IsUserDefined() { - return string(n) - } - return "" -} - -// UsernsMode represents userns mode in the container. -type UsernsMode string - -// IsHost indicates whether the container uses the host's userns. -func (n UsernsMode) IsHost() bool { - return n == "host" -} - -// IsPrivate indicates whether the container uses the a private userns. -func (n UsernsMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// Valid indicates whether the userns is valid. -func (n UsernsMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// CgroupSpec represents the cgroup to use for the container. -type CgroupSpec string - -// IsContainer indicates whether the container is using another container cgroup -func (c CgroupSpec) IsContainer() bool { - parts := strings.SplitN(string(c), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the cgroup spec is valid. -func (c CgroupSpec) Valid() bool { - return c.IsContainer() || c == "" -} - -// Container returns the name of the container whose cgroup will be used. -func (c CgroupSpec) Container() string { - parts := strings.SplitN(string(c), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// UTSMode represents the UTS namespace of the container. -type UTSMode string - -// IsPrivate indicates whether the container uses its private UTS namespace. -func (n UTSMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// IsHost indicates whether the container uses the host's UTS namespace. -func (n UTSMode) IsHost() bool { - return n == "host" -} - -// Valid indicates whether the UTS namespace is valid. -func (n UTSMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// PidMode represents the pid namespace of the container. -type PidMode string - -// IsPrivate indicates whether the container uses its own new pid namespace. -func (n PidMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsHost indicates whether the container uses the host's pid namespace. -func (n PidMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether the container uses a container's pid namespace. -func (n PidMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the pid namespace is valid. -func (n PidMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - case "container": - if len(parts) != 2 || parts[1] == "" { - return false - } - default: - return false - } - return true -} - -// Container returns the name of the container whose pid namespace is going to be used. -func (n PidMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// DeviceRequest represents a request for devices from a device driver. -// Used by GPU device drivers. -type DeviceRequest struct { - Driver string // Name of device driver - Count int // Number of devices to request (-1 = All) - DeviceIDs []string // List of device IDs as recognizable by the device driver - Capabilities [][]string // An OR list of AND lists of device capabilities (e.g. "gpu") - Options map[string]string // Options to pass onto the device driver -} - -// DeviceMapping represents the device mapping between the host and the container. -type DeviceMapping struct { - PathOnHost string - PathInContainer string - CgroupPermissions string -} - -// RestartPolicy represents the restart policies of the container. -type RestartPolicy struct { - Name string - MaximumRetryCount int -} - -// IsNone indicates whether the container has the "no" restart policy. -// This means the container will not automatically restart when exiting. -func (rp *RestartPolicy) IsNone() bool { - return rp.Name == "no" || rp.Name == "" -} - -// IsAlways indicates whether the container has the "always" restart policy. -// This means the container will automatically restart regardless of the exit status. -func (rp *RestartPolicy) IsAlways() bool { - return rp.Name == "always" -} - -// IsOnFailure indicates whether the container has the "on-failure" restart policy. -// This means the container will automatically restart of exiting with a non-zero exit status. -func (rp *RestartPolicy) IsOnFailure() bool { - return rp.Name == "on-failure" -} - -// IsUnlessStopped indicates whether the container has the -// "unless-stopped" restart policy. This means the container will -// automatically restart unless user has put it to stopped state. -func (rp *RestartPolicy) IsUnlessStopped() bool { - return rp.Name == "unless-stopped" -} - -// IsSame compares two RestartPolicy to see if they are the same -func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool { - return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount -} - -// LogMode is a type to define the available modes for logging -// These modes affect how logs are handled when log messages start piling up. -type LogMode string - -// Available logging modes -const ( - LogModeUnset = "" - LogModeBlocking LogMode = "blocking" - LogModeNonBlock LogMode = "non-blocking" -) - -// LogConfig represents the logging configuration of the container. -type LogConfig struct { - Type string - Config map[string]string -} - -// Resources contains container's resources (cgroups config, ulimits...) -type Resources struct { - // Applicable to all platforms - CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) - Memory int64 // Memory limit (in bytes) - NanoCPUs int64 `json:"NanoCpus"` // CPU quota in units of 10-9 CPUs. - - // Applicable to UNIX platforms - CgroupParent string // Parent cgroup. - BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) - BlkioWeightDevice []*blkiodev.WeightDevice - BlkioDeviceReadBps []*blkiodev.ThrottleDevice - BlkioDeviceWriteBps []*blkiodev.ThrottleDevice - BlkioDeviceReadIOps []*blkiodev.ThrottleDevice - BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice - CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period - CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota - CPURealtimePeriod int64 `json:"CpuRealtimePeriod"` // CPU real-time period - CPURealtimeRuntime int64 `json:"CpuRealtimeRuntime"` // CPU real-time runtime - CpusetCpus string // CpusetCpus 0-2, 0,1 - CpusetMems string // CpusetMems 0-2, 0,1 - Devices []DeviceMapping // List of devices to map inside the container - DeviceCgroupRules []string // List of rule to be added to the device cgroup - DeviceRequests []DeviceRequest // List of device requests for device drivers - KernelMemory int64 // Kernel memory limit (in bytes), Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes - KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes) - MemoryReservation int64 // Memory soft limit (in bytes) - MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable *bool // Whether to disable OOM Killer or not - PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change. - Ulimits []*units.Ulimit // List of ulimits to be set in the container - - // Applicable to Windows - CPUCount int64 `json:"CpuCount"` // CPU count - CPUPercent int64 `json:"CpuPercent"` // CPU percent - IOMaximumIOps uint64 // Maximum IOps for the container system drive - IOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive -} - -// UpdateConfig holds the mutable attributes of a Container. -// Those attributes can be updated at runtime. -type UpdateConfig struct { - // Contains container's resources (cgroups, ulimits) - Resources - RestartPolicy RestartPolicy -} - -// HostConfig the non-portable Config structure of a container. -// Here, "non-portable" means "dependent of the host we are running on". -// Portable information *should* appear in Config. -type HostConfig struct { - // Applicable to all platforms - Binds []string // List of volume bindings for this container - ContainerIDFile string // File (path) where the containerId is written - LogConfig LogConfig // Configuration of the logs for this container - NetworkMode NetworkMode // Network mode to use for the container - PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host - RestartPolicy RestartPolicy // Restart policy to be used for the container - AutoRemove bool // Automatically remove container when it exits - VolumeDriver string // Name of the volume driver used to mount volumes - VolumesFrom []string // List of volumes to take from other container - - // Applicable to UNIX platforms - CapAdd strslice.StrSlice // List of kernel capabilities to add to the container - CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container - CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for - ExtraHosts []string // List of extra hosts - GroupAdd []string // List of additional groups that the container process will run as - IpcMode IpcMode // IPC namespace to use for the container - Cgroup CgroupSpec // Cgroup to use for the container - Links []string // List of links (in the name:alias form) - OomScoreAdj int // Container preference for OOM-killing - PidMode PidMode // PID namespace to use for the container - Privileged bool // Is the container in privileged mode - PublishAllPorts bool // Should docker publish all exposed port for the container - ReadonlyRootfs bool // Is the container root filesystem in read-only - SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. - StorageOpt map[string]string `json:",omitempty"` // Storage driver options per container. - Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container - UTSMode UTSMode // UTS namespace to use for the container - UsernsMode UsernsMode // The user namespace to use for the container - ShmSize int64 // Total shm memory usage - Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container - Runtime string `json:",omitempty"` // Runtime to use with this container - - // Applicable to Windows - ConsoleSize [2]uint // Initial console size (height,width) - Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) - - // Contains container's resources (cgroups, ulimits) - Resources - - // Mounts specs used by the container - Mounts []mount.Mount `json:",omitempty"` - - // MaskedPaths is the list of paths to be masked inside the container (this overrides the default set of paths) - MaskedPaths []string - - // ReadonlyPaths is the list of paths to be set as read-only inside the container (this overrides the default set of paths) - ReadonlyPaths []string - - // Run a custom init inside the container, if null, use the daemon's configured settings - Init *bool `json:",omitempty"` -} diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig.go b/vendor/github.com/docker/docker/api/types/container/hostconfig.go new file mode 100644 index 00000000000..d4e6f55375a --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/hostconfig.go @@ -0,0 +1,456 @@ +package container // import "github.com/docker/docker/api/types/container" + +import ( + "strings" + + "github.com/docker/docker/api/types/blkiodev" + "github.com/docker/docker/api/types/mount" + "github.com/docker/docker/api/types/strslice" + "github.com/docker/go-connections/nat" + units "github.com/docker/go-units" +) + +// CgroupnsMode represents the cgroup namespace mode of the container +type CgroupnsMode string + +// cgroup namespace modes for containers +const ( + CgroupnsModeEmpty CgroupnsMode = "" + CgroupnsModePrivate CgroupnsMode = "private" + CgroupnsModeHost CgroupnsMode = "host" +) + +// IsPrivate indicates whether the container uses its own private cgroup namespace +func (c CgroupnsMode) IsPrivate() bool { + return c == CgroupnsModePrivate +} + +// IsHost indicates whether the container shares the host's cgroup namespace +func (c CgroupnsMode) IsHost() bool { + return c == CgroupnsModeHost +} + +// IsEmpty indicates whether the container cgroup namespace mode is unset +func (c CgroupnsMode) IsEmpty() bool { + return c == CgroupnsModeEmpty +} + +// Valid indicates whether the cgroup namespace mode is valid +func (c CgroupnsMode) Valid() bool { + return c.IsEmpty() || c.IsPrivate() || c.IsHost() +} + +// Isolation represents the isolation technology of a container. The supported +// values are platform specific +type Isolation string + +// Isolation modes for containers +const ( + IsolationEmpty Isolation = "" // IsolationEmpty is unspecified (same behavior as default) + IsolationDefault Isolation = "default" // IsolationDefault is the default isolation mode on current daemon + IsolationProcess Isolation = "process" // IsolationProcess is process isolation mode + IsolationHyperV Isolation = "hyperv" // IsolationHyperV is HyperV isolation mode +) + +// IsDefault indicates the default isolation technology of a container. On Linux this +// is the native driver. On Windows, this is a Windows Server Container. +func (i Isolation) IsDefault() bool { + // TODO consider making isolation-mode strict (case-sensitive) + v := Isolation(strings.ToLower(string(i))) + return v == IsolationDefault || v == IsolationEmpty +} + +// IsHyperV indicates the use of a Hyper-V partition for isolation +func (i Isolation) IsHyperV() bool { + // TODO consider making isolation-mode strict (case-sensitive) + return Isolation(strings.ToLower(string(i))) == IsolationHyperV +} + +// IsProcess indicates the use of process isolation +func (i Isolation) IsProcess() bool { + // TODO consider making isolation-mode strict (case-sensitive) + return Isolation(strings.ToLower(string(i))) == IsolationProcess +} + +// IpcMode represents the container ipc stack. +type IpcMode string + +// IpcMode constants +const ( + IPCModeNone IpcMode = "none" + IPCModeHost IpcMode = "host" + IPCModeContainer IpcMode = "container" + IPCModePrivate IpcMode = "private" + IPCModeShareable IpcMode = "shareable" +) + +// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared. +func (n IpcMode) IsPrivate() bool { + return n == IPCModePrivate +} + +// IsHost indicates whether the container shares the host's ipc namespace. +func (n IpcMode) IsHost() bool { + return n == IPCModeHost +} + +// IsShareable indicates whether the container's ipc namespace can be shared with another container. +func (n IpcMode) IsShareable() bool { + return n == IPCModeShareable +} + +// IsContainer indicates whether the container uses another container's ipc namespace. +func (n IpcMode) IsContainer() bool { + _, ok := containerID(string(n)) + return ok +} + +// IsNone indicates whether container IpcMode is set to "none". +func (n IpcMode) IsNone() bool { + return n == IPCModeNone +} + +// IsEmpty indicates whether container IpcMode is empty +func (n IpcMode) IsEmpty() bool { + return n == "" +} + +// Valid indicates whether the ipc mode is valid. +func (n IpcMode) Valid() bool { + // TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid. + return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer() +} + +// Container returns the name of the container ipc stack is going to be used. +func (n IpcMode) Container() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName +} + +// NetworkMode represents the container network stack. +type NetworkMode string + +// IsNone indicates whether container isn't using a network stack. +func (n NetworkMode) IsNone() bool { + return n == "none" +} + +// IsDefault indicates whether container uses the default network stack. +func (n NetworkMode) IsDefault() bool { + return n == "default" +} + +// IsPrivate indicates whether container uses its private network stack. +func (n NetworkMode) IsPrivate() bool { + return !(n.IsHost() || n.IsContainer()) +} + +// IsContainer indicates whether container uses a container network stack. +func (n NetworkMode) IsContainer() bool { + _, ok := containerID(string(n)) + return ok +} + +// ConnectedContainer is the id of the container which network this container is connected to. +func (n NetworkMode) ConnectedContainer() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName +} + +// UserDefined indicates user-created network +func (n NetworkMode) UserDefined() string { + if n.IsUserDefined() { + return string(n) + } + return "" +} + +// UsernsMode represents userns mode in the container. +type UsernsMode string + +// IsHost indicates whether the container uses the host's userns. +func (n UsernsMode) IsHost() bool { + return n == "host" +} + +// IsPrivate indicates whether the container uses the a private userns. +func (n UsernsMode) IsPrivate() bool { + return !n.IsHost() +} + +// Valid indicates whether the userns is valid. +func (n UsernsMode) Valid() bool { + return n == "" || n.IsHost() +} + +// CgroupSpec represents the cgroup to use for the container. +type CgroupSpec string + +// IsContainer indicates whether the container is using another container cgroup +func (c CgroupSpec) IsContainer() bool { + _, ok := containerID(string(c)) + return ok +} + +// Valid indicates whether the cgroup spec is valid. +func (c CgroupSpec) Valid() bool { + // TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid. + return c == "" || c.IsContainer() +} + +// Container returns the ID or name of the container whose cgroup will be used. +func (c CgroupSpec) Container() (idOrName string) { + idOrName, _ = containerID(string(c)) + return idOrName +} + +// UTSMode represents the UTS namespace of the container. +type UTSMode string + +// IsPrivate indicates whether the container uses its private UTS namespace. +func (n UTSMode) IsPrivate() bool { + return !n.IsHost() +} + +// IsHost indicates whether the container uses the host's UTS namespace. +func (n UTSMode) IsHost() bool { + return n == "host" +} + +// Valid indicates whether the UTS namespace is valid. +func (n UTSMode) Valid() bool { + return n == "" || n.IsHost() +} + +// PidMode represents the pid namespace of the container. +type PidMode string + +// IsPrivate indicates whether the container uses its own new pid namespace. +func (n PidMode) IsPrivate() bool { + return !(n.IsHost() || n.IsContainer()) +} + +// IsHost indicates whether the container uses the host's pid namespace. +func (n PidMode) IsHost() bool { + return n == "host" +} + +// IsContainer indicates whether the container uses a container's pid namespace. +func (n PidMode) IsContainer() bool { + _, ok := containerID(string(n)) + return ok +} + +// Valid indicates whether the pid namespace is valid. +func (n PidMode) Valid() bool { + return n == "" || n.IsHost() || validContainer(string(n)) +} + +// Container returns the name of the container whose pid namespace is going to be used. +func (n PidMode) Container() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName +} + +// DeviceRequest represents a request for devices from a device driver. +// Used by GPU device drivers. +type DeviceRequest struct { + Driver string // Name of device driver + Count int // Number of devices to request (-1 = All) + DeviceIDs []string // List of device IDs as recognizable by the device driver + Capabilities [][]string // An OR list of AND lists of device capabilities (e.g. "gpu") + Options map[string]string // Options to pass onto the device driver +} + +// DeviceMapping represents the device mapping between the host and the container. +type DeviceMapping struct { + PathOnHost string + PathInContainer string + CgroupPermissions string +} + +// RestartPolicy represents the restart policies of the container. +type RestartPolicy struct { + Name string + MaximumRetryCount int +} + +// IsNone indicates whether the container has the "no" restart policy. +// This means the container will not automatically restart when exiting. +func (rp *RestartPolicy) IsNone() bool { + return rp.Name == "no" || rp.Name == "" +} + +// IsAlways indicates whether the container has the "always" restart policy. +// This means the container will automatically restart regardless of the exit status. +func (rp *RestartPolicy) IsAlways() bool { + return rp.Name == "always" +} + +// IsOnFailure indicates whether the container has the "on-failure" restart policy. +// This means the container will automatically restart of exiting with a non-zero exit status. +func (rp *RestartPolicy) IsOnFailure() bool { + return rp.Name == "on-failure" +} + +// IsUnlessStopped indicates whether the container has the +// "unless-stopped" restart policy. This means the container will +// automatically restart unless user has put it to stopped state. +func (rp *RestartPolicy) IsUnlessStopped() bool { + return rp.Name == "unless-stopped" +} + +// IsSame compares two RestartPolicy to see if they are the same +func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool { + return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount +} + +// LogMode is a type to define the available modes for logging +// These modes affect how logs are handled when log messages start piling up. +type LogMode string + +// Available logging modes +const ( + LogModeUnset LogMode = "" + LogModeBlocking LogMode = "blocking" + LogModeNonBlock LogMode = "non-blocking" +) + +// LogConfig represents the logging configuration of the container. +type LogConfig struct { + Type string + Config map[string]string +} + +// Resources contains container's resources (cgroups config, ulimits...) +type Resources struct { + // Applicable to all platforms + CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) + Memory int64 // Memory limit (in bytes) + NanoCPUs int64 `json:"NanoCpus"` // CPU quota in units of 10-9 CPUs. + + // Applicable to UNIX platforms + CgroupParent string // Parent cgroup. + BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) + BlkioWeightDevice []*blkiodev.WeightDevice + BlkioDeviceReadBps []*blkiodev.ThrottleDevice + BlkioDeviceWriteBps []*blkiodev.ThrottleDevice + BlkioDeviceReadIOps []*blkiodev.ThrottleDevice + BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice + CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period + CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota + CPURealtimePeriod int64 `json:"CpuRealtimePeriod"` // CPU real-time period + CPURealtimeRuntime int64 `json:"CpuRealtimeRuntime"` // CPU real-time runtime + CpusetCpus string // CpusetCpus 0-2, 0,1 + CpusetMems string // CpusetMems 0-2, 0,1 + Devices []DeviceMapping // List of devices to map inside the container + DeviceCgroupRules []string // List of rule to be added to the device cgroup + DeviceRequests []DeviceRequest // List of device requests for device drivers + + // KernelMemory specifies the kernel memory limit (in bytes) for the container. + // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes. + KernelMemory int64 `json:",omitempty"` + KernelMemoryTCP int64 `json:",omitempty"` // Hard limit for kernel TCP buffer memory (in bytes) + MemoryReservation int64 // Memory soft limit (in bytes) + MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap + MemorySwappiness *int64 // Tuning container memory swappiness behaviour + OomKillDisable *bool // Whether to disable OOM Killer or not + PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change. + Ulimits []*units.Ulimit // List of ulimits to be set in the container + + // Applicable to Windows + CPUCount int64 `json:"CpuCount"` // CPU count + CPUPercent int64 `json:"CpuPercent"` // CPU percent + IOMaximumIOps uint64 // Maximum IOps for the container system drive + IOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive +} + +// UpdateConfig holds the mutable attributes of a Container. +// Those attributes can be updated at runtime. +type UpdateConfig struct { + // Contains container's resources (cgroups, ulimits) + Resources + RestartPolicy RestartPolicy +} + +// HostConfig the non-portable Config structure of a container. +// Here, "non-portable" means "dependent of the host we are running on". +// Portable information *should* appear in Config. +type HostConfig struct { + // Applicable to all platforms + Binds []string // List of volume bindings for this container + ContainerIDFile string // File (path) where the containerId is written + LogConfig LogConfig // Configuration of the logs for this container + NetworkMode NetworkMode // Network mode to use for the container + PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host + RestartPolicy RestartPolicy // Restart policy to be used for the container + AutoRemove bool // Automatically remove container when it exits + VolumeDriver string // Name of the volume driver used to mount volumes + VolumesFrom []string // List of volumes to take from other container + ConsoleSize [2]uint // Initial console size (height,width) + Annotations map[string]string `json:",omitempty"` // Arbitrary non-identifying metadata attached to container and provided to the runtime + + // Applicable to UNIX platforms + CapAdd strslice.StrSlice // List of kernel capabilities to add to the container + CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container + CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container + DNS []string `json:"Dns"` // List of DNS server to lookup + DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for + DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for + ExtraHosts []string // List of extra hosts + GroupAdd []string // List of additional groups that the container process will run as + IpcMode IpcMode // IPC namespace to use for the container + Cgroup CgroupSpec // Cgroup to use for the container + Links []string // List of links (in the name:alias form) + OomScoreAdj int // Container preference for OOM-killing + PidMode PidMode // PID namespace to use for the container + Privileged bool // Is the container in privileged mode + PublishAllPorts bool // Should docker publish all exposed port for the container + ReadonlyRootfs bool // Is the container root filesystem in read-only + SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. + StorageOpt map[string]string `json:",omitempty"` // Storage driver options per container. + Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container + UTSMode UTSMode // UTS namespace to use for the container + UsernsMode UsernsMode // The user namespace to use for the container + ShmSize int64 // Total shm memory usage + Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container + Runtime string `json:",omitempty"` // Runtime to use with this container + + // Applicable to Windows + Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) + + // Contains container's resources (cgroups, ulimits) + Resources + + // Mounts specs used by the container + Mounts []mount.Mount `json:",omitempty"` + + // MaskedPaths is the list of paths to be masked inside the container (this overrides the default set of paths) + MaskedPaths []string + + // ReadonlyPaths is the list of paths to be set as read-only inside the container (this overrides the default set of paths) + ReadonlyPaths []string + + // Run a custom init inside the container, if null, use the daemon's configured settings + Init *bool `json:",omitempty"` +} + +// containerID splits "container:" values. It returns the container +// ID or name, and whether an ID/name was found. It returns an empty string and +// a "false" if the value does not have a "container:" prefix. Further validation +// of the returned, including checking if the value is empty, should be handled +// by the caller. +func containerID(val string) (idOrName string, ok bool) { + k, v, hasSep := strings.Cut(val, ":") + if !hasSep || k != "container" { + return "", false + } + return v, true +} + +// validContainer checks if the given value is a "container:" mode with +// a non-empty name/ID. +func validContainer(val string) bool { + id, ok := containerID(val) + return ok && id != "" +} diff --git a/vendor/github.com/docker/docker/api/types/container/wait_exit_error.go b/vendor/github.com/docker/docker/api/types/container/wait_exit_error.go new file mode 100644 index 00000000000..ab56d4eed8e --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/wait_exit_error.go @@ -0,0 +1,12 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// WaitExitError container waiting error, if any +// swagger:model WaitExitError +type WaitExitError struct { + + // Details of an error + Message string `json:"Message,omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/container/wait_response.go b/vendor/github.com/docker/docker/api/types/container/wait_response.go new file mode 100644 index 00000000000..84fc6afddc6 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/wait_response.go @@ -0,0 +1,18 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// WaitResponse ContainerWaitResponse +// +// OK response to ContainerWait operation +// swagger:model WaitResponse +type WaitResponse struct { + + // error + Error *WaitExitError `json:"Error,omitempty"` + + // Exit code of the container + // Required: true + StatusCode int64 `json:"StatusCode"` +} diff --git a/vendor/github.com/docker/docker/api/types/filters/errors.go b/vendor/github.com/docker/docker/api/types/filters/errors.go new file mode 100644 index 00000000000..f52f6944089 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/filters/errors.go @@ -0,0 +1,37 @@ +package filters + +import "fmt" + +// invalidFilter indicates that the provided filter or its value is invalid +type invalidFilter struct { + Filter string + Value []string +} + +func (e invalidFilter) Error() string { + msg := "invalid filter" + if e.Filter != "" { + msg += " '" + e.Filter + if e.Value != nil { + msg = fmt.Sprintf("%s=%s", msg, e.Value) + } + msg += "'" + } + return msg +} + +// InvalidParameter marks this error as ErrInvalidParameter +func (e invalidFilter) InvalidParameter() {} + +// unreachableCode is an error indicating that the code path was not expected to be reached. +type unreachableCode struct { + Filter string + Value []string +} + +// System marks this error as ErrSystem +func (e unreachableCode) System() {} + +func (e unreachableCode) Error() string { + return fmt.Sprintf("unreachable code reached for filter: %q with values: %s", e.Filter, e.Value) +} diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go index 4bc91cffd6e..0c39ab5f18b 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/docker/docker/api/types/filters/parse.go @@ -1,4 +1,5 @@ -/*Package filters provides tools for encoding a mapping of keys to a set of +/* +Package filters provides tools for encoding a mapping of keys to a set of multiple values. */ package filters // import "github.com/docker/docker/api/types/filters" @@ -48,7 +49,7 @@ func (args Args) Keys() []string { // MarshalJSON returns a JSON byte representation of the Args func (args Args) MarshalJSON() ([]byte, error) { if len(args.fields) == 0 { - return []byte{}, nil + return []byte("{}"), nil } return json.Marshal(args.fields) } @@ -97,7 +98,7 @@ func FromJSON(p string) (Args, error) { // Fallback to parsing arguments in the legacy slice format deprecated := map[string][]string{} if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil { - return args, err + return args, &invalidFilter{} } args.fields = deprecatedArgs(deprecated) @@ -106,9 +107,6 @@ func FromJSON(p string) (Args, error) { // UnmarshalJSON populates the Args from JSON encode bytes func (args Args) UnmarshalJSON(raw []byte) error { - if len(raw) == 0 { - return nil - } return json.Unmarshal(raw, &args.fields) } @@ -164,13 +162,13 @@ func (args Args) MatchKVList(key string, sources map[string]string) bool { } for value := range fieldValues { - testKV := strings.SplitN(value, "=", 2) + testK, testV, hasValue := strings.Cut(value, "=") - v, ok := sources[testKV[0]] + v, ok := sources[testK] if !ok { return false } - if len(testKV) == 2 && testKV[1] != v { + if hasValue && testV != v { return false } } @@ -197,6 +195,38 @@ func (args Args) Match(field, source string) bool { return false } +// GetBoolOrDefault returns a boolean value of the key if the key is present +// and is intepretable as a boolean value. Otherwise the default value is returned. +// Error is not nil only if the filter values are not valid boolean or are conflicting. +func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { + fieldValues, ok := args.fields[key] + + if !ok { + return defaultValue, nil + } + + if len(fieldValues) == 0 { + return defaultValue, &invalidFilter{key, nil} + } + + isFalse := fieldValues["0"] || fieldValues["false"] + isTrue := fieldValues["1"] || fieldValues["true"] + + conflicting := isFalse && isTrue + invalid := !isFalse && !isTrue + + if conflicting || invalid { + return defaultValue, &invalidFilter{key, args.Get(key)} + } else if isFalse { + return false, nil + } else if isTrue { + return true, nil + } + + // This code shouldn't be reached. + return defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)} +} + // ExactMatch returns true if the source matches exactly one of the values. func (args Args) ExactMatch(key, source string) bool { fieldValues, ok := args.fields[key] @@ -247,20 +277,12 @@ func (args Args) Contains(field string) bool { return ok } -type invalidFilter string - -func (e invalidFilter) Error() string { - return "Invalid filter '" + string(e) + "'" -} - -func (invalidFilter) InvalidParameter() {} - // Validate compared the set of accepted keys against the keys in the mapping. // An error is returned if any mapping keys are not in the accepted set. func (args Args) Validate(accepted map[string]bool) error { for name := range args.fields { if !accepted[name] { - return invalidFilter(name) + return &invalidFilter{name, nil} } } return nil diff --git a/vendor/github.com/docker/docker/api/types/graph_driver_data.go b/vendor/github.com/docker/docker/api/types/graph_driver_data.go index 4d9bf1c62c8..ce3deb331c5 100644 --- a/vendor/github.com/docker/docker/api/types/graph_driver_data.go +++ b/vendor/github.com/docker/docker/api/types/graph_driver_data.go @@ -3,15 +3,21 @@ package types // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command -// GraphDriverData Information about a container's graph driver. +// GraphDriverData Information about the storage driver used to store the container's and +// image's filesystem. +// // swagger:model GraphDriverData type GraphDriverData struct { - // data + // Low-level storage metadata, provided as key/value pairs. + // + // This information is driver-specific, and depends on the storage-driver + // in use, and should be used for informational purposes only. + // // Required: true Data map[string]string `json:"Data"` - // name + // Name of the storage driver. // Required: true Name string `json:"Name"` } diff --git a/vendor/github.com/docker/docker/api/types/image_summary.go b/vendor/github.com/docker/docker/api/types/image_summary.go index e145b3dcfcd..0f6f144840e 100644 --- a/vendor/github.com/docker/docker/api/types/image_summary.go +++ b/vendor/github.com/docker/docker/api/types/image_summary.go @@ -7,43 +7,88 @@ package types // swagger:model ImageSummary type ImageSummary struct { - // containers + // Number of containers using this image. Includes both stopped and running + // containers. + // + // This size is not calculated by default, and depends on which API endpoint + // is used. `-1` indicates that the value has not been set / calculated. + // // Required: true Containers int64 `json:"Containers"` - // created + // Date and time at which the image was created as a Unix timestamp + // (number of seconds sinds EPOCH). + // // Required: true Created int64 `json:"Created"` - // Id + // ID is the content-addressable ID of an image. + // + // This identifier is a content-addressable digest calculated from the + // image's configuration (which includes the digests of layers used by + // the image). + // + // Note that this digest differs from the `RepoDigests` below, which + // holds digests of image manifests that reference the image. + // // Required: true ID string `json:"Id"` - // labels + // User-defined key/value metadata. // Required: true Labels map[string]string `json:"Labels"` - // parent Id + // ID of the parent image. + // + // Depending on how the image was created, this field may be empty and + // is only set for images that were built/created locally. This field + // is empty if the image was pulled from an image registry. + // // Required: true ParentID string `json:"ParentId"` - // repo digests + // List of content-addressable digests of locally available image manifests + // that the image is referenced from. Multiple manifests can refer to the + // same image. + // + // These digests are usually only available if the image was either pulled + // from a registry, or if the image was pushed to a registry, which is when + // the manifest is generated and its digest calculated. + // // Required: true RepoDigests []string `json:"RepoDigests"` - // repo tags + // List of image names/tags in the local image cache that reference this + // image. + // + // Multiple image tags can refer to the same image, and this list may be + // empty if no tags reference the image, in which case the image is + // "untagged", in which case it can still be referenced by its ID. + // // Required: true RepoTags []string `json:"RepoTags"` - // shared size + // Total size of image layers that are shared between this image and other + // images. + // + // This size is not calculated by default. `-1` indicates that the value + // has not been set / calculated. + // // Required: true SharedSize int64 `json:"SharedSize"` - // size + // Total size of the image including all layers it is composed of. + // // Required: true Size int64 `json:"Size"` - // virtual size - // Required: true - VirtualSize int64 `json:"VirtualSize"` + // Total size of the image including all layers it is composed of. + // + // In versions of Docker before v1.10, this field was calculated from + // the image itself and all of its parent images. Images are now stored + // self-contained, and no longer use a parent-chain, making this field + // an equivalent of the Size field. + // + // Deprecated: this field is kept for backward compatibility, and will be removed in API v1.44. + VirtualSize int64 `json:"VirtualSize,omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/mount/mount.go b/vendor/github.com/docker/docker/api/types/mount/mount.go index 443b8d07a9f..ac4ce622310 100644 --- a/vendor/github.com/docker/docker/api/types/mount/mount.go +++ b/vendor/github.com/docker/docker/api/types/mount/mount.go @@ -17,6 +17,8 @@ const ( TypeTmpfs Type = "tmpfs" // TypeNamedPipe is the type for mounting Windows named pipes TypeNamedPipe Type = "npipe" + // TypeCluster is the type for Swarm Cluster Volumes. + TypeCluster Type = "cluster" ) // Mount represents a mount (volume). @@ -30,9 +32,10 @@ type Mount struct { ReadOnly bool `json:",omitempty"` Consistency Consistency `json:",omitempty"` - BindOptions *BindOptions `json:",omitempty"` - VolumeOptions *VolumeOptions `json:",omitempty"` - TmpfsOptions *TmpfsOptions `json:",omitempty"` + BindOptions *BindOptions `json:",omitempty"` + VolumeOptions *VolumeOptions `json:",omitempty"` + TmpfsOptions *TmpfsOptions `json:",omitempty"` + ClusterOptions *ClusterOptions `json:",omitempty"` } // Propagation represents the propagation of a mount. @@ -79,8 +82,9 @@ const ( // BindOptions defines options specific to mounts of type "bind". type BindOptions struct { - Propagation Propagation `json:",omitempty"` - NonRecursive bool `json:",omitempty"` + Propagation Propagation `json:",omitempty"` + NonRecursive bool `json:",omitempty"` + CreateMountpoint bool `json:",omitempty"` } // VolumeOptions represents the options for a mount of type volume. @@ -129,3 +133,8 @@ type TmpfsOptions struct { // Some of these may be straightforward to add, but others, such as // uid/gid have implications in a clustered system. } + +// ClusterOptions specifies options for a Cluster volume. +type ClusterOptions struct { + // intentionally empty +} diff --git a/vendor/github.com/docker/docker/api/types/registry/authconfig.go b/vendor/github.com/docker/docker/api/types/registry/authconfig.go new file mode 100644 index 00000000000..97a924e3747 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/registry/authconfig.go @@ -0,0 +1,99 @@ +package registry // import "github.com/docker/docker/api/types/registry" +import ( + "encoding/base64" + "encoding/json" + "io" + "strings" + + "github.com/pkg/errors" +) + +// AuthHeader is the name of the header used to send encoded registry +// authorization credentials for registry operations (push/pull). +const AuthHeader = "X-Registry-Auth" + +// AuthConfig contains authorization information for connecting to a Registry. +type AuthConfig struct { + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Auth string `json:"auth,omitempty"` + + // Email is an optional value associated with the username. + // This field is deprecated and will be removed in a later + // version of docker. + Email string `json:"email,omitempty"` + + ServerAddress string `json:"serveraddress,omitempty"` + + // IdentityToken is used to authenticate the user and get + // an access token for the registry. + IdentityToken string `json:"identitytoken,omitempty"` + + // RegistryToken is a bearer token to be sent to a registry + RegistryToken string `json:"registrytoken,omitempty"` +} + +// EncodeAuthConfig serializes the auth configuration as a base64url encoded +// RFC4648, section 5) JSON string for sending through the X-Registry-Auth header. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 +func EncodeAuthConfig(authConfig AuthConfig) (string, error) { + buf, err := json.Marshal(authConfig) + if err != nil { + return "", errInvalidParameter{err} + } + return base64.URLEncoding.EncodeToString(buf), nil +} + +// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON +// authentication information as sent through the X-Registry-Auth header. +// +// This function always returns an AuthConfig, even if an error occurs. It is up +// to the caller to decide if authentication is required, and if the error can +// be ignored. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 +func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) { + if authEncoded == "" { + return &AuthConfig{}, nil + } + + authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) + return decodeAuthConfigFromReader(authJSON) +} + +// DecodeAuthConfigBody decodes authentication information as sent as JSON in the +// body of a request. This function is to provide backward compatibility with old +// clients and API versions. Current clients and API versions expect authentication +// to be provided through the X-Registry-Auth header. +// +// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an +// error occurs. It is up to the caller to decide if authentication is required, +// and if the error can be ignored. +func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) { + return decodeAuthConfigFromReader(rdr) +} + +func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) { + authConfig := &AuthConfig{} + if err := json.NewDecoder(rdr).Decode(authConfig); err != nil { + // always return an (empty) AuthConfig to increase compatibility with + // the existing API. + return &AuthConfig{}, invalid(err) + } + return authConfig, nil +} + +func invalid(err error) error { + return errInvalidParameter{errors.Wrap(err, "invalid X-Registry-Auth header")} +} + +type errInvalidParameter struct{ error } + +func (errInvalidParameter) InvalidParameter() {} + +func (e errInvalidParameter) Cause() error { return e.error } + +func (e errInvalidParameter) Unwrap() error { return e.error } diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go index 53e47084c8d..b83f5d7b2e2 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/docker/docker/api/types/registry/registry.go @@ -4,7 +4,7 @@ import ( "encoding/json" "net" - v1 "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // ServiceConfig stores daemon registry services configuration. @@ -45,31 +45,32 @@ func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) { // IndexInfo contains information about a registry // // RepositoryInfo Examples: -// { -// "Index" : { -// "Name" : "docker.io", -// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"], -// "Secure" : true, -// "Official" : true, -// }, -// "RemoteName" : "library/debian", -// "LocalName" : "debian", -// "CanonicalName" : "docker.io/debian" -// "Official" : true, -// } // -// { -// "Index" : { -// "Name" : "127.0.0.1:5000", -// "Mirrors" : [], -// "Secure" : false, -// "Official" : false, -// }, -// "RemoteName" : "user/repo", -// "LocalName" : "127.0.0.1:5000/user/repo", -// "CanonicalName" : "127.0.0.1:5000/user/repo", -// "Official" : false, -// } +// { +// "Index" : { +// "Name" : "docker.io", +// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"], +// "Secure" : true, +// "Official" : true, +// }, +// "RemoteName" : "library/debian", +// "LocalName" : "debian", +// "CanonicalName" : "docker.io/debian" +// "Official" : true, +// } +// +// { +// "Index" : { +// "Name" : "127.0.0.1:5000", +// "Mirrors" : [], +// "Secure" : false, +// "Official" : false, +// }, +// "RemoteName" : "user/repo", +// "LocalName" : "127.0.0.1:5000/user/repo", +// "CanonicalName" : "127.0.0.1:5000/user/repo", +// "Official" : false, +// } type IndexInfo struct { // Name is the name of the registry, such as "docker.io" Name string @@ -112,8 +113,8 @@ type SearchResults struct { type DistributionInspect struct { // Descriptor contains information about the manifest, including // the content addressable digest - Descriptor v1.Descriptor + Descriptor ocispec.Descriptor // Platforms contains the list of platforms supported by the image, // obtained by parsing the manifest - Platforms []v1.Platform + Platforms []ocispec.Platform } diff --git a/vendor/github.com/docker/docker/api/types/swarm/common.go b/vendor/github.com/docker/docker/api/types/swarm/common.go index ef020f458bd..5ded7dba8a5 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/common.go +++ b/vendor/github.com/docker/docker/api/types/swarm/common.go @@ -1,12 +1,20 @@ package swarm // import "github.com/docker/docker/api/types/swarm" -import "time" +import ( + "strconv" + "time" +) // Version represents the internal object version. type Version struct { Index uint64 `json:",omitempty"` } +// String implements fmt.Stringer interface. +func (v Version) String() string { + return strconv.FormatUint(v.Index, 10) +} + // Meta is a base object inherited by most of the other once. type Meta struct { Version Version `json:",omitempty"` diff --git a/vendor/github.com/docker/docker/api/types/swarm/node.go b/vendor/github.com/docker/docker/api/types/swarm/node.go index 1e30f5fa10d..bb98d5eedc6 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/node.go +++ b/vendor/github.com/docker/docker/api/types/swarm/node.go @@ -53,6 +53,7 @@ type NodeDescription struct { Resources Resources `json:",omitempty"` Engine EngineDescription `json:",omitempty"` TLSInfo TLSInfo `json:",omitempty"` + CSIInfo []NodeCSIInfo `json:",omitempty"` } // Platform represents the platform (Arch/OS). @@ -68,6 +69,21 @@ type EngineDescription struct { Plugins []PluginDescription `json:",omitempty"` } +// NodeCSIInfo represents information about a CSI plugin available on the node +type NodeCSIInfo struct { + // PluginName is the name of the CSI plugin. + PluginName string `json:",omitempty"` + // NodeID is the ID of the node as reported by the CSI plugin. This is + // different from the swarm node ID. + NodeID string `json:",omitempty"` + // MaxVolumesPerNode is the maximum number of volumes that may be published + // to this node + MaxVolumesPerNode int64 `json:",omitempty"` + // AccessibleTopology indicates the location of this node in the CSI + // plugin's topology + AccessibleTopology *Topology `json:",omitempty"` +} + // PluginDescription represents the description of an engine plugin. type PluginDescription struct { Type string `json:",omitempty"` @@ -113,3 +129,11 @@ const ( // NodeStateDisconnected DISCONNECTED NodeStateDisconnected NodeState = "disconnected" ) + +// Topology defines the CSI topology of this node. This type is a duplicate of +// github.com/docker/docker/api/types.Topology. Because the type definition +// is so simple and to avoid complicated structure or circular imports, we just +// duplicate it here. See that type for full documentation +type Topology struct { + Segments map[string]string `json:",omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/swarm/swarm.go b/vendor/github.com/docker/docker/api/types/swarm/swarm.go index b25f9996462..3eae4b9b297 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/swarm.go +++ b/vendor/github.com/docker/docker/api/types/swarm/swarm.go @@ -213,6 +213,16 @@ type Info struct { Warnings []string `json:",omitempty"` } +// Status provides information about the current swarm status and role, +// obtained from the "Swarm" header in the API response. +type Status struct { + // NodeState represents the state of the node. + NodeState LocalNodeState + + // ControlAvailable indicates if the node is a swarm manager. + ControlAvailable bool +} + // Peer represents a peer. type Peer struct { NodeID string diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/docker/docker/api/types/swarm/task.go index a6f7ab7b5c7..ad3eeca0b7f 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/task.go +++ b/vendor/github.com/docker/docker/api/types/swarm/task.go @@ -62,6 +62,11 @@ type Task struct { // used to determine which Tasks belong to which run of the job. This field // is absent if the Service mode is Replicated or Global. JobIteration *Version `json:",omitempty"` + + // Volumes is the list of VolumeAttachments for this task. It specifies + // which particular volumes are to be used by this particular task, and + // fulfilling what mounts in the spec. + Volumes []VolumeAttachment } // TaskSpec represents the spec of a task. @@ -204,3 +209,17 @@ type ContainerStatus struct { type PortStatus struct { Ports []PortConfig `json:",omitempty"` } + +// VolumeAttachment contains the associating a Volume to a Task. +type VolumeAttachment struct { + // ID is the Swarmkit ID of the Volume. This is not the CSI VolumeId. + ID string `json:",omitempty"` + + // Source, together with Target, indicates the Mount, as specified in the + // ContainerSpec, that this volume fulfills. + Source string `json:",omitempty"` + + // Target, together with Source, indicates the Mount, as specified + // in the ContainerSpec, that this volume fulfills. + Target string `json:",omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index e3a159912e2..b413e020006 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -14,43 +14,135 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/api/types/volume" "github.com/docker/go-connections/nat" ) +const ( + // MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams + MediaTypeRawStream = "application/vnd.docker.raw-stream" + + // MediaTypeMultiplexedStream is vendor specific MIME-Type set for stdin/stdout/stderr multiplexed streams + MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream" +) + // RootFS returns Image's RootFS description including the layer IDs. type RootFS struct { - Type string - Layers []string `json:",omitempty"` - BaseLayer string `json:",omitempty"` + Type string `json:",omitempty"` + Layers []string `json:",omitempty"` } // ImageInspect contains response of Engine API: // GET "/images/{name:.*}/json" type ImageInspect struct { - ID string `json:"Id"` - RepoTags []string - RepoDigests []string - Parent string - Comment string - Created string - Container string + // ID is the content-addressable ID of an image. + // + // This identifier is a content-addressable digest calculated from the + // image's configuration (which includes the digests of layers used by + // the image). + // + // Note that this digest differs from the `RepoDigests` below, which + // holds digests of image manifests that reference the image. + ID string `json:"Id"` + + // RepoTags is a list of image names/tags in the local image cache that + // reference this image. + // + // Multiple image tags can refer to the same image, and this list may be + // empty if no tags reference the image, in which case the image is + // "untagged", in which case it can still be referenced by its ID. + RepoTags []string + + // RepoDigests is a list of content-addressable digests of locally available + // image manifests that the image is referenced from. Multiple manifests can + // refer to the same image. + // + // These digests are usually only available if the image was either pulled + // from a registry, or if the image was pushed to a registry, which is when + // the manifest is generated and its digest calculated. + RepoDigests []string + + // Parent is the ID of the parent image. + // + // Depending on how the image was created, this field may be empty and + // is only set for images that were built/created locally. This field + // is empty if the image was pulled from an image registry. + Parent string + + // Comment is an optional message that can be set when committing or + // importing the image. + Comment string + + // Created is the date and time at which the image was created, formatted in + // RFC 3339 nano-seconds (time.RFC3339Nano). + Created string + + // Container is the ID of the container that was used to create the image. + // + // Depending on how the image was created, this field may be empty. + Container string + + // ContainerConfig is an optional field containing the configuration of the + // container that was last committed when creating the image. + // + // Previous versions of Docker builder used this field to store build cache, + // and it is not in active use anymore. ContainerConfig *container.Config - DockerVersion string - Author string - Config *container.Config - Architecture string - Variant string `json:",omitempty"` - Os string - OsVersion string `json:",omitempty"` - Size int64 - VirtualSize int64 - GraphDriver GraphDriverData - RootFS RootFS - Metadata ImageMetadata + + // DockerVersion is the version of Docker that was used to build the image. + // + // Depending on how the image was created, this field may be empty. + DockerVersion string + + // Author is the name of the author that was specified when committing the + // image, or as specified through MAINTAINER (deprecated) in the Dockerfile. + Author string + Config *container.Config + + // Architecture is the hardware CPU architecture that the image runs on. + Architecture string + + // Variant is the CPU architecture variant (presently ARM-only). + Variant string `json:",omitempty"` + + // OS is the Operating System the image is built to run on. + Os string + + // OsVersion is the version of the Operating System the image is built to + // run on (especially for Windows). + OsVersion string `json:",omitempty"` + + // Size is the total size of the image including all layers it is composed of. + Size int64 + + // VirtualSize is the total size of the image including all layers it is + // composed of. + // + // In versions of Docker before v1.10, this field was calculated from + // the image itself and all of its parent images. Docker v1.10 and up + // store images self-contained, and no longer use a parent-chain, making + // this field an equivalent of the Size field. + // + // Deprecated: Unused in API 1.43 and up, but kept for backward compatibility with older API versions. + VirtualSize int64 `json:"VirtualSize,omitempty"` + + // GraphDriver holds information about the storage driver used to store the + // container's and image's filesystem. + GraphDriver GraphDriverData + + // RootFS contains information about the image's RootFS, including the + // layer IDs. + RootFS RootFS + + // Metadata of the image in the local cache. + // + // This information is local to the daemon, and not part of the image itself. + Metadata ImageMetadata } // ImageMetadata contains engine-local data about the image type ImageMetadata struct { + // LastTagTime is the date and time at which the image was last tagged. LastTagTime time.Time `json:",omitempty"` } @@ -107,6 +199,15 @@ type Ping struct { OSType string Experimental bool BuilderVersion BuilderVersion + + // SwarmStatus provides information about the current swarm status of the + // engine, obtained from the "Swarm" header in the API response. + // + // It can be a nil struct if the API version does not provide this header + // in the ping response, or if an error occurred, in which case the client + // should use other ways to get the current swarm status, such as the /swarm + // endpoint. + SwarmStatus *swarm.Status } // ComponentVersion describes the version information for a specific component. @@ -158,8 +259,8 @@ type Info struct { Plugins PluginsInfo MemoryLimit bool SwapLimit bool - KernelMemory bool // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes - KernelMemoryTCP bool + KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes + KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2. CPUCfsPeriod bool `json:"CpuCfsPeriod"` CPUCfsQuota bool `json:"CpuCfsQuota"` CPUShares bool @@ -195,8 +296,6 @@ type Info struct { Labels []string ExperimentalBuild bool ServerVersion string - ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated - ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated Runtimes map[string]Runtime DefaultRuntime string Swarm swarm.Info @@ -212,7 +311,12 @@ type Info struct { SecurityOptions []string ProductLicense string `json:",omitempty"` DefaultAddressPools []NetworkAddressPool `json:",omitempty"` - Warnings []string + + // Warnings contains a slice of warnings that occurred while collecting + // system information. These warnings are intended to be informational + // messages for the user, and are not intended to be parsed / used for + // other purposes, as they do not have a fixed format. + Warnings []string } // KeyValue holds a key/value pair @@ -243,20 +347,19 @@ func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) { continue } secopt := SecurityOpt{} - split := strings.Split(opt, ",") - for _, s := range split { - kv := strings.SplitN(s, "=", 2) - if len(kv) != 2 { + for _, s := range strings.Split(opt, ",") { + k, v, ok := strings.Cut(s, "=") + if !ok { return nil, fmt.Errorf("invalid security option %q", s) } - if kv[0] == "" || kv[1] == "" { + if k == "" || v == "" { return nil, errors.New("invalid empty security option") } - if kv[0] == "name" { - secopt.Name = kv[1] + if k == "name" { + secopt.Name = v continue } - secopt.Options = append(secopt.Options, KeyValue{Key: kv[0], Value: kv[1]}) + secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v}) } so = append(so, secopt) } @@ -283,6 +386,8 @@ type ExecStartCheck struct { Detach bool // Check if there's a tty Tty bool + // Terminal size [height, width], unused if Tty == false + ConsoleSize *[2]uint `json:",omitempty"` } // HealthcheckResult stores information about a single run of a healthcheck probe @@ -416,13 +521,44 @@ type DefaultNetworkSettings struct { // MountPoint represents a mount point configuration inside the container. // This is used for reporting the mountpoints in use by a container. type MountPoint struct { - Type mount.Type `json:",omitempty"` - Name string `json:",omitempty"` - Source string + // Type is the type of mount, see `Type` definitions in + // github.com/docker/docker/api/types/mount.Type + Type mount.Type `json:",omitempty"` + + // Name is the name reference to the underlying data defined by `Source` + // e.g., the volume name. + Name string `json:",omitempty"` + + // Source is the source location of the mount. + // + // For volumes, this contains the storage location of the volume (within + // `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains + // the source (host) part of the bind-mount. For `tmpfs` mount points, this + // field is empty. + Source string + + // Destination is the path relative to the container root (`/`) where the + // Source is mounted inside the container. Destination string - Driver string `json:",omitempty"` - Mode string - RW bool + + // Driver is the volume driver used to create the volume (if it is a volume). + Driver string `json:",omitempty"` + + // Mode is a comma separated list of options supplied by the user when + // creating the bind/volume mount. + // + // The default is platform-specific (`"z"` on Linux, empty on Windows). + Mode string + + // RW indicates whether the mount is mounted writable (read-write). + RW bool + + // Propagation describes how mounts are propagated from the host into the + // mount point, and vice-versa. Refer to the Linux kernel documentation + // for details: + // https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt + // + // This field is not used on Windows. Propagation mount.Propagation } @@ -516,12 +652,18 @@ type Checkpoint struct { // Runtime describes an OCI runtime type Runtime struct { - Path string `json:"path"` + // "Legacy" runtime configuration for runc-compatible runtimes. + + Path string `json:"path,omitempty"` Args []string `json:"runtimeArgs,omitempty"` + // Shimv2 runtime configuration. Mutually exclusive with the legacy config above. + + Type string `json:"runtimeType,omitempty"` + Options map[string]interface{} `json:"options,omitempty"` + // This is exposed here only for internal use - // It is not currently supported to specify custom shim configs - Shim *ShimConfig `json:"-"` + ShimConfig *ShimConfig `json:"-"` } // ShimConfig is used by runtime to configure containerd shims @@ -530,15 +672,36 @@ type ShimConfig struct { Opts interface{} } +// DiskUsageObject represents an object type used for disk usage query filtering. +type DiskUsageObject string + +const ( + // ContainerObject represents a container DiskUsageObject. + ContainerObject DiskUsageObject = "container" + // ImageObject represents an image DiskUsageObject. + ImageObject DiskUsageObject = "image" + // VolumeObject represents a volume DiskUsageObject. + VolumeObject DiskUsageObject = "volume" + // BuildCacheObject represents a build-cache DiskUsageObject. + BuildCacheObject DiskUsageObject = "build-cache" +) + +// DiskUsageOptions holds parameters for system disk usage query. +type DiskUsageOptions struct { + // Types specifies what object types to include in the response. If empty, + // all object types are returned. + Types []DiskUsageObject +} + // DiskUsage contains response of Engine API: // GET "/system/df" type DiskUsage struct { LayersSize int64 Images []*ImageSummary Containers []*Container - Volumes []*Volume + Volumes []*volume.Volume BuildCache []*BuildCache - BuilderSize int64 // deprecated + BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. } // ContainersPruneReport contains the response for Engine API: @@ -613,18 +776,31 @@ type BuildResult struct { ID string } -// BuildCache contains information about a build cache record +// BuildCache contains information about a build cache record. type BuildCache struct { - ID string - Parent string - Type string + // ID is the unique ID of the build cache record. + ID string + // Parent is the ID of the parent build cache record. + // + // Deprecated: deprecated in API v1.42 and up, as it was deprecated in BuildKit; use Parents instead. + Parent string `json:"Parent,omitempty"` + // Parents is the list of parent build cache record IDs. + Parents []string `json:" Parents,omitempty"` + // Type is the cache record type. + Type string + // Description is a description of the build-step that produced the build cache. Description string - InUse bool - Shared bool - Size int64 - CreatedAt time.Time - LastUsedAt *time.Time - UsageCount int + // InUse indicates if the build cache is in use. + InUse bool + // Shared indicates if the build cache is shared. + Shared bool + // Size is the amount of disk space used by the build cache (in bytes). + Size int64 + // CreatedAt is the date and time at which the build cache was created. + CreatedAt time.Time + // LastUsedAt is the date and time at which the build cache was last used. + LastUsedAt *time.Time + UsageCount int } // BuildCachePruneOptions hold parameters to prune the build cache diff --git a/vendor/github.com/docker/docker/api/types/versions/compare.go b/vendor/github.com/docker/docker/api/types/versions/compare.go index 8ccb0aa92eb..489e917ee52 100644 --- a/vendor/github.com/docker/docker/api/types/versions/compare.go +++ b/vendor/github.com/docker/docker/api/types/versions/compare.go @@ -8,6 +8,9 @@ import ( // compare compares two version strings // returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. func compare(v1, v2 string) int { + if v1 == v2 { + return 0 + } var ( currTab = strings.Split(v1, ".") otherTab = strings.Split(v2, ".") diff --git a/vendor/github.com/docker/docker/api/types/volume/cluster_volume.go b/vendor/github.com/docker/docker/api/types/volume/cluster_volume.go new file mode 100644 index 00000000000..55fc5d38993 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/cluster_volume.go @@ -0,0 +1,420 @@ +package volume + +import ( + "github.com/docker/docker/api/types/swarm" +) + +// ClusterVolume contains options and information specific to, and only present +// on, Swarm CSI cluster volumes. +type ClusterVolume struct { + // ID is the Swarm ID of the volume. Because cluster volumes are Swarm + // objects, they have an ID, unlike non-cluster volumes, which only have a + // Name. This ID can be used to refer to the cluster volume. + ID string + + // Meta is the swarm metadata about this volume. + swarm.Meta + + // Spec is the cluster-specific options from which this volume is derived. + Spec ClusterVolumeSpec + + // PublishStatus contains the status of the volume as it pertains to its + // publishing on Nodes. + PublishStatus []*PublishStatus `json:",omitempty"` + + // Info is information about the global status of the volume. + Info *Info `json:",omitempty"` +} + +// ClusterVolumeSpec contains the spec used to create this volume. +type ClusterVolumeSpec struct { + // Group defines the volume group of this volume. Volumes belonging to the + // same group can be referred to by group name when creating Services. + // Referring to a volume by group instructs swarm to treat volumes in that + // group interchangeably for the purpose of scheduling. Volumes with an + // empty string for a group technically all belong to the same, emptystring + // group. + Group string `json:",omitempty"` + + // AccessMode defines how the volume is used by tasks. + AccessMode *AccessMode `json:",omitempty"` + + // AccessibilityRequirements specifies where in the cluster a volume must + // be accessible from. + // + // This field must be empty if the plugin does not support + // VOLUME_ACCESSIBILITY_CONSTRAINTS capabilities. If it is present but the + // plugin does not support it, volume will not be created. + // + // If AccessibilityRequirements is empty, but the plugin does support + // VOLUME_ACCESSIBILITY_CONSTRAINTS, then Swarmkit will assume the entire + // cluster is a valid target for the volume. + AccessibilityRequirements *TopologyRequirement `json:",omitempty"` + + // CapacityRange defines the desired capacity that the volume should be + // created with. If nil, the plugin will decide the capacity. + CapacityRange *CapacityRange `json:",omitempty"` + + // Secrets defines Swarm Secrets that are passed to the CSI storage plugin + // when operating on this volume. + Secrets []Secret `json:",omitempty"` + + // Availability is the Volume's desired availability. Analogous to Node + // Availability, this allows the user to take volumes offline in order to + // update or delete them. + Availability Availability `json:",omitempty"` +} + +// Availability specifies the availability of the volume. +type Availability string + +const ( + // AvailabilityActive indicates that the volume is active and fully + // schedulable on the cluster. + AvailabilityActive Availability = "active" + + // AvailabilityPause indicates that no new workloads should use the + // volume, but existing workloads can continue to use it. + AvailabilityPause Availability = "pause" + + // AvailabilityDrain indicates that all workloads using this volume + // should be rescheduled, and the volume unpublished from all nodes. + AvailabilityDrain Availability = "drain" +) + +// AccessMode defines the access mode of a volume. +type AccessMode struct { + // Scope defines the set of nodes this volume can be used on at one time. + Scope Scope `json:",omitempty"` + + // Sharing defines the number and way that different tasks can use this + // volume at one time. + Sharing SharingMode `json:",omitempty"` + + // MountVolume defines options for using this volume as a Mount-type + // volume. + // + // Either BlockVolume or MountVolume, but not both, must be present. + MountVolume *TypeMount `json:",omitempty"` + + // BlockVolume defines options for using this volume as a Block-type + // volume. + // + // Either BlockVolume or MountVolume, but not both, must be present. + BlockVolume *TypeBlock `json:",omitempty"` +} + +// Scope defines the Scope of a Cluster Volume. This is how many nodes a +// Volume can be accessed simultaneously on. +type Scope string + +const ( + // ScopeSingleNode indicates the volume can be used on one node at a + // time. + ScopeSingleNode Scope = "single" + + // ScopeMultiNode indicates the volume can be used on many nodes at + // the same time. + ScopeMultiNode Scope = "multi" +) + +// SharingMode defines the Sharing of a Cluster Volume. This is how Tasks using a +// Volume at the same time can use it. +type SharingMode string + +const ( + // SharingNone indicates that only one Task may use the Volume at a + // time. + SharingNone SharingMode = "none" + + // SharingReadOnly indicates that the Volume may be shared by any + // number of Tasks, but they must be read-only. + SharingReadOnly SharingMode = "readonly" + + // SharingOneWriter indicates that the Volume may be shared by any + // number of Tasks, but all after the first must be read-only. + SharingOneWriter SharingMode = "onewriter" + + // SharingAll means that the Volume may be shared by any number of + // Tasks, as readers or writers. + SharingAll SharingMode = "all" +) + +// TypeBlock defines options for using a volume as a block-type volume. +// +// Intentionally empty. +type TypeBlock struct{} + +// TypeMount contains options for using a volume as a Mount-type +// volume. +type TypeMount struct { + // FsType specifies the filesystem type for the mount volume. Optional. + FsType string `json:",omitempty"` + + // MountFlags defines flags to pass when mounting the volume. Optional. + MountFlags []string `json:",omitempty"` +} + +// TopologyRequirement expresses the user's requirements for a volume's +// accessible topology. +type TopologyRequirement struct { + // Requisite specifies a list of Topologies, at least one of which the + // volume must be accessible from. + // + // Taken verbatim from the CSI Spec: + // + // Specifies the list of topologies the provisioned volume MUST be + // accessible from. + // This field is OPTIONAL. If TopologyRequirement is specified either + // requisite or preferred or both MUST be specified. + // + // If requisite is specified, the provisioned volume MUST be + // accessible from at least one of the requisite topologies. + // + // Given + // x = number of topologies provisioned volume is accessible from + // n = number of requisite topologies + // The CO MUST ensure n >= 1. The SP MUST ensure x >= 1 + // If x==n, then the SP MUST make the provisioned volume available to + // all topologies from the list of requisite topologies. If it is + // unable to do so, the SP MUST fail the CreateVolume call. + // For example, if a volume should be accessible from a single zone, + // and requisite = + // {"region": "R1", "zone": "Z2"} + // then the provisioned volume MUST be accessible from the "region" + // "R1" and the "zone" "Z2". + // Similarly, if a volume should be accessible from two zones, and + // requisite = + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // then the provisioned volume MUST be accessible from the "region" + // "R1" and both "zone" "Z2" and "zone" "Z3". + // + // If xn, then the SP MUST make the provisioned volume available from + // all topologies from the list of requisite topologies and MAY choose + // the remaining x-n unique topologies from the list of all possible + // topologies. If it is unable to do so, the SP MUST fail the + // CreateVolume call. + // For example, if a volume should be accessible from two zones, and + // requisite = + // {"region": "R1", "zone": "Z2"} + // then the provisioned volume MUST be accessible from the "region" + // "R1" and the "zone" "Z2" and the SP may select the second zone + // independently, e.g. "R1/Z4". + Requisite []Topology `json:",omitempty"` + + // Preferred is a list of Topologies that the volume should attempt to be + // provisioned in. + // + // Taken from the CSI spec: + // + // Specifies the list of topologies the CO would prefer the volume to + // be provisioned in. + // + // This field is OPTIONAL. If TopologyRequirement is specified either + // requisite or preferred or both MUST be specified. + // + // An SP MUST attempt to make the provisioned volume available using + // the preferred topologies in order from first to last. + // + // If requisite is specified, all topologies in preferred list MUST + // also be present in the list of requisite topologies. + // + // If the SP is unable to to make the provisioned volume available + // from any of the preferred topologies, the SP MAY choose a topology + // from the list of requisite topologies. + // If the list of requisite topologies is not specified, then the SP + // MAY choose from the list of all possible topologies. + // If the list of requisite topologies is specified and the SP is + // unable to to make the provisioned volume available from any of the + // requisite topologies it MUST fail the CreateVolume call. + // + // Example 1: + // Given a volume should be accessible from a single zone, and + // requisite = + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // preferred = + // {"region": "R1", "zone": "Z3"} + // then the the SP SHOULD first attempt to make the provisioned volume + // available from "zone" "Z3" in the "region" "R1" and fall back to + // "zone" "Z2" in the "region" "R1" if that is not possible. + // + // Example 2: + // Given a volume should be accessible from a single zone, and + // requisite = + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"}, + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z5"} + // preferred = + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z2"} + // then the the SP SHOULD first attempt to make the provisioned volume + // accessible from "zone" "Z4" in the "region" "R1" and fall back to + // "zone" "Z2" in the "region" "R1" if that is not possible. If that + // is not possible, the SP may choose between either the "zone" + // "Z3" or "Z5" in the "region" "R1". + // + // Example 3: + // Given a volume should be accessible from TWO zones (because an + // opaque parameter in CreateVolumeRequest, for example, specifies + // the volume is accessible from two zones, aka synchronously + // replicated), and + // requisite = + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"}, + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z5"} + // preferred = + // {"region": "R1", "zone": "Z5"}, + // {"region": "R1", "zone": "Z3"} + // then the the SP SHOULD first attempt to make the provisioned volume + // accessible from the combination of the two "zones" "Z5" and "Z3" in + // the "region" "R1". If that's not possible, it should fall back to + // a combination of "Z5" and other possibilities from the list of + // requisite. If that's not possible, it should fall back to a + // combination of "Z3" and other possibilities from the list of + // requisite. If that's not possible, it should fall back to a + // combination of other possibilities from the list of requisite. + Preferred []Topology `json:",omitempty"` +} + +// Topology is a map of topological domains to topological segments. +// +// This description is taken verbatim from the CSI Spec: +// +// A topological domain is a sub-division of a cluster, like "region", +// "zone", "rack", etc. +// A topological segment is a specific instance of a topological domain, +// like "zone3", "rack3", etc. +// For example {"com.company/zone": "Z1", "com.company/rack": "R3"} +// Valid keys have two segments: an OPTIONAL prefix and name, separated +// by a slash (/), for example: "com.company.example/zone". +// The key name segment is REQUIRED. The prefix is OPTIONAL. +// The key name MUST be 63 characters or less, begin and end with an +// alphanumeric character ([a-z0-9A-Z]), and contain only dashes (-), +// underscores (_), dots (.), or alphanumerics in between, for example +// "zone". +// The key prefix MUST be 63 characters or less, begin and end with a +// lower-case alphanumeric character ([a-z0-9]), contain only +// dashes (-), dots (.), or lower-case alphanumerics in between, and +// follow domain name notation format +// (https://tools.ietf.org/html/rfc1035#section-2.3.1). +// The key prefix SHOULD include the plugin's host company name and/or +// the plugin name, to minimize the possibility of collisions with keys +// from other plugins. +// If a key prefix is specified, it MUST be identical across all +// topology keys returned by the SP (across all RPCs). +// Keys MUST be case-insensitive. Meaning the keys "Zone" and "zone" +// MUST not both exist. +// Each value (topological segment) MUST contain 1 or more strings. +// Each string MUST be 63 characters or less and begin and end with an +// alphanumeric character with '-', '_', '.', or alphanumerics in +// between. +type Topology struct { + Segments map[string]string `json:",omitempty"` +} + +// CapacityRange describes the minimum and maximum capacity a volume should be +// created with +type CapacityRange struct { + // RequiredBytes specifies that a volume must be at least this big. The + // value of 0 indicates an unspecified minimum. + RequiredBytes int64 + + // LimitBytes specifies that a volume must not be bigger than this. The + // value of 0 indicates an unspecified maximum + LimitBytes int64 +} + +// Secret represents a Swarm Secret value that must be passed to the CSI +// storage plugin when operating on this Volume. It represents one key-value +// pair of possibly many. +type Secret struct { + // Key is the name of the key of the key-value pair passed to the plugin. + Key string + + // Secret is the swarm Secret object from which to read data. This can be a + // Secret name or ID. The Secret data is retrieved by Swarm and used as the + // value of the key-value pair passed to the plugin. + Secret string +} + +// PublishState represents the state of a Volume as it pertains to its +// use on a particular Node. +type PublishState string + +const ( + // StatePending indicates that the volume should be published on + // this node, but the call to ControllerPublishVolume has not been + // successfully completed yet and the result recorded by swarmkit. + StatePending PublishState = "pending-publish" + + // StatePublished means the volume is published successfully to the node. + StatePublished PublishState = "published" + + // StatePendingNodeUnpublish indicates that the Volume should be + // unpublished on the Node, and we're waiting for confirmation that it has + // done so. After the Node has confirmed that the Volume has been + // unpublished, the state will move to StatePendingUnpublish. + StatePendingNodeUnpublish PublishState = "pending-node-unpublish" + + // StatePendingUnpublish means the volume is still published to the node + // by the controller, awaiting the operation to unpublish it. + StatePendingUnpublish PublishState = "pending-controller-unpublish" +) + +// PublishStatus represents the status of the volume as published to an +// individual node +type PublishStatus struct { + // NodeID is the ID of the swarm node this Volume is published to. + NodeID string `json:",omitempty"` + + // State is the publish state of the volume. + State PublishState `json:",omitempty"` + + // PublishContext is the PublishContext returned by the CSI plugin when + // a volume is published. + PublishContext map[string]string `json:",omitempty"` +} + +// Info contains information about the Volume as a whole as provided by +// the CSI storage plugin. +type Info struct { + // CapacityBytes is the capacity of the volume in bytes. A value of 0 + // indicates that the capacity is unknown. + CapacityBytes int64 `json:",omitempty"` + + // VolumeContext is the context originating from the CSI storage plugin + // when the Volume is created. + VolumeContext map[string]string `json:",omitempty"` + + // VolumeID is the ID of the Volume as seen by the CSI storage plugin. This + // is distinct from the Volume's Swarm ID, which is the ID used by all of + // the Docker Engine to refer to the Volume. If this field is blank, then + // the Volume has not been successfully created yet. + VolumeID string `json:",omitempty"` + + // AccessibleTopolgoy is the topology this volume is actually accessible + // from. + AccessibleTopology []Topology `json:",omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/volume/create_options.go b/vendor/github.com/docker/docker/api/types/volume/create_options.go new file mode 100644 index 00000000000..37c41a60969 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/create_options.go @@ -0,0 +1,29 @@ +package volume + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// CreateOptions VolumeConfig +// +// Volume configuration +// swagger:model CreateOptions +type CreateOptions struct { + + // cluster volume spec + ClusterVolumeSpec *ClusterVolumeSpec `json:"ClusterVolumeSpec,omitempty"` + + // Name of the volume driver to use. + Driver string `json:"Driver,omitempty"` + + // A mapping of driver options and values. These options are + // passed directly to the driver and are driver specific. + // + DriverOpts map[string]string `json:"DriverOpts,omitempty"` + + // User-defined key/value metadata. + Labels map[string]string `json:"Labels,omitempty"` + + // The new volume's name. If not specified, Docker generates a name. + // + Name string `json:"Name,omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/volume/list_response.go b/vendor/github.com/docker/docker/api/types/volume/list_response.go new file mode 100644 index 00000000000..ca5192a2a91 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/list_response.go @@ -0,0 +1,18 @@ +package volume + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// ListResponse VolumeListResponse +// +// Volume list response +// swagger:model ListResponse +type ListResponse struct { + + // List of volumes + Volumes []*Volume `json:"Volumes"` + + // Warnings that occurred when fetching the list of volumes. + // + Warnings []string `json:"Warnings"` +} diff --git a/vendor/github.com/docker/docker/api/types/volume/options.go b/vendor/github.com/docker/docker/api/types/volume/options.go new file mode 100644 index 00000000000..8b0dd138998 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/options.go @@ -0,0 +1,8 @@ +package volume // import "github.com/docker/docker/api/types/volume" + +import "github.com/docker/docker/api/types/filters" + +// ListOptions holds parameters to list volumes. +type ListOptions struct { + Filters filters.Args +} diff --git a/vendor/github.com/docker/docker/api/types/volume.go b/vendor/github.com/docker/docker/api/types/volume/volume.go similarity index 87% rename from vendor/github.com/docker/docker/api/types/volume.go rename to vendor/github.com/docker/docker/api/types/volume/volume.go index c69b08448df..ea7d555e5b4 100644 --- a/vendor/github.com/docker/docker/api/types/volume.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume.go @@ -1,4 +1,4 @@ -package types +package volume // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command @@ -7,6 +7,9 @@ package types // swagger:model Volume type Volume struct { + // cluster volume + ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"` + // Date/Time the volume was created. CreatedAt string `json:"CreatedAt,omitempty"` @@ -47,14 +50,14 @@ type Volume struct { Status map[string]interface{} `json:"Status,omitempty"` // usage data - UsageData *VolumeUsageData `json:"UsageData,omitempty"` + UsageData *UsageData `json:"UsageData,omitempty"` } -// VolumeUsageData Usage details about the volume. This information is used by the +// UsageData Usage details about the volume. This information is used by the // `GET /system/df` endpoint, and omitted in other endpoints. // -// swagger:model VolumeUsageData -type VolumeUsageData struct { +// swagger:model UsageData +type UsageData struct { // The number of containers referencing this volume. This field // is set to `-1` if the reference-count is not available. diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_update.go b/vendor/github.com/docker/docker/api/types/volume/volume_update.go new file mode 100644 index 00000000000..f958f80a669 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/volume/volume_update.go @@ -0,0 +1,7 @@ +package volume // import "github.com/docker/docker/api/types/volume" + +// UpdateOptions is configuration to update a Volume with. +type UpdateOptions struct { + // Spec is the ClusterVolumeSpec to update the volume to. + Spec *ClusterVolumeSpec `json:"Spec,omitempty"` +} diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go index 5afe486779d..77bda389d1d 100644 --- a/vendor/github.com/docker/docker/errdefs/http_helpers.go +++ b/vendor/github.com/docker/docker/errdefs/http_helpers.go @@ -2,14 +2,12 @@ package errdefs // import "github.com/docker/docker/errdefs" import ( "net/http" - - "github.com/sirupsen/logrus" ) // FromStatusCode creates an errdef error, based on the provided HTTP status-code func FromStatusCode(err error, statusCode int) error { if err == nil { - return err + return nil } switch statusCode { case http.StatusNotFound: @@ -33,11 +31,6 @@ func FromStatusCode(err error, statusCode int) error { err = System(err) } default: - logrus.WithError(err).WithFields(logrus.Fields{ - "module": "api", - "status_code": statusCode, - }).Debug("FIXME: Got an status-code for which error does not match any expected type!!!") - switch { case statusCode >= 200 && statusCode < 400: // it's a client error diff --git a/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go b/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go index 5e6310fdcd6..ded1c7c8c61 100644 --- a/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go +++ b/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go @@ -64,13 +64,14 @@ func stick(f string) error { // GetDataHome returns XDG_DATA_HOME. // GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set. +// If HOME and XDG_DATA_HOME are not set, getpwent(3) is consulted to determine the users home directory. // // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html func GetDataHome() (string, error) { if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" { return xdgDataHome, nil } - home := os.Getenv("HOME") + home := Get() if home == "" { return "", errors.New("could not get either XDG_DATA_HOME or HOME") } @@ -79,15 +80,26 @@ func GetDataHome() (string, error) { // GetConfigHome returns XDG_CONFIG_HOME. // GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set. +// If HOME and XDG_CONFIG_HOME are not set, getpwent(3) is consulted to determine the users home directory. // // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html func GetConfigHome() (string, error) { if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { return xdgConfigHome, nil } - home := os.Getenv("HOME") + home := Get() if home == "" { return "", errors.New("could not get either XDG_CONFIG_HOME or HOME") } return filepath.Join(home, ".config"), nil } + +// GetLibHome returns $HOME/.local/lib +// If HOME is not set, getpwent(3) is consulted to determine the users home directory. +func GetLibHome() (string, error) { + home := Get() + if home == "" { + return "", errors.New("could not get HOME") + } + return filepath.Join(home, ".local/lib"), nil +} diff --git a/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go b/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go index fc48e674c11..11f1bec9858 100644 --- a/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go +++ b/vendor/github.com/docker/docker/pkg/homedir/homedir_others.go @@ -26,3 +26,8 @@ func GetDataHome() (string, error) { func GetConfigHome() (string, error) { return "", errors.New("homedir.GetConfigHome() is not supported on this system") } + +// GetLibHome is unsupported on non-linux system. +func GetLibHome() (string, error) { + return "", errors.New("homedir.GetLibHome() is not supported on this system") +} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go b/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go index 87514b643d7..c1cfa62fd27 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go @@ -29,11 +29,12 @@ var ( // and releases new byte slices to adjust to current needs, so the buffer // won't be overgrown after peak loads. type BytesPipe struct { - mu sync.Mutex - wait *sync.Cond - buf []*fixedBuffer - bufLen int - closeErr error // error to return from next Read. set to nil if not closed. + mu sync.Mutex + wait *sync.Cond + buf []*fixedBuffer + bufLen int + closeErr error // error to return from next Read. set to nil if not closed. + readBlock bool // check read BytesPipe is Wait() or not } // NewBytesPipe creates new BytesPipe, initialized by specified slice. @@ -50,12 +51,12 @@ func NewBytesPipe() *BytesPipe { // It can allocate new []byte slices in a process of writing. func (bp *BytesPipe) Write(p []byte) (int, error) { bp.mu.Lock() + defer bp.mu.Unlock() written := 0 loop0: for { if bp.closeErr != nil { - bp.mu.Unlock() return written, ErrClosed } @@ -72,7 +73,6 @@ loop0: // errBufferFull is an error we expect to get if the buffer is full if err != nil && err != errBufferFull { bp.wait.Broadcast() - bp.mu.Unlock() return written, err } @@ -86,6 +86,9 @@ loop0: // make sure the buffer doesn't grow too big from this write for bp.bufLen >= blockThreshold { + if bp.readBlock { + bp.wait.Broadcast() + } bp.wait.Wait() if bp.closeErr != nil { continue loop0 @@ -100,7 +103,6 @@ loop0: bp.buf = append(bp.buf, getBuffer(nextCap)) } bp.wait.Broadcast() - bp.mu.Unlock() return written, nil } @@ -126,17 +128,16 @@ func (bp *BytesPipe) Close() error { // Data could be read only once. func (bp *BytesPipe) Read(p []byte) (n int, err error) { bp.mu.Lock() + defer bp.mu.Unlock() if bp.bufLen == 0 { if bp.closeErr != nil { - err := bp.closeErr - bp.mu.Unlock() - return 0, err + return 0, bp.closeErr } + bp.readBlock = true bp.wait.Wait() + bp.readBlock = false if bp.bufLen == 0 && bp.closeErr != nil { - err := bp.closeErr - bp.mu.Unlock() - return 0, err + return 0, bp.closeErr } } @@ -161,7 +162,6 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) { } bp.wait.Broadcast() - bp.mu.Unlock() return } diff --git a/vendor/github.com/docker/docker/pkg/ioutils/fswriters.go b/vendor/github.com/docker/docker/pkg/ioutils/fswriters.go index 534d66ac268..82671d8cd55 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/fswriters.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/fswriters.go @@ -2,7 +2,6 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" import ( "io" - "io/ioutil" "os" "path/filepath" ) @@ -11,7 +10,7 @@ import ( // temporary file and closing it atomically changes the temporary file to // destination path. Writing and closing concurrently is not allowed. func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) { - f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) + f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename)) if err != nil { return nil, err } @@ -94,7 +93,7 @@ type AtomicWriteSet struct { // commit. If no temporary directory is given the system // default is used. func NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) { - td, err := ioutil.TempDir(tmpDir, "write-set-") + td, err := os.MkdirTemp(tmpDir, "write-set-") if err != nil { return nil, err } diff --git a/vendor/github.com/docker/docker/pkg/ioutils/readers.go b/vendor/github.com/docker/docker/pkg/ioutils/readers.go index 1f657bd3dca..de00b95e3f6 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/readers.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/readers.go @@ -2,9 +2,12 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" import ( "context" - "crypto/sha256" - "encoding/hex" "io" + + // make sure crypto.SHA256, crypto.sha512 and crypto.SHA384 are registered + // TODO remove once https://github.com/opencontainers/go-digest/pull/64 is merged. + _ "crypto/sha256" + _ "crypto/sha512" ) // ReadCloserWrapper wraps an io.Reader, and implements an io.ReadCloser @@ -49,15 +52,6 @@ func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader { } } -// HashData returns the sha256 sum of src. -func HashData(src io.Reader) (string, error) { - h := sha256.New() - if _, err := io.Copy(h, src); err != nil { - return "", err - } - return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil -} - // OnEOFReader wraps an io.ReadCloser and a function // the function will run at the end of file or close the file. type OnEOFReader struct { diff --git a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go b/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go deleted file mode 100644 index 4e67ec2f53f..00000000000 --- a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !windows -// +build !windows - -package ioutils // import "github.com/docker/docker/pkg/ioutils" - -import "io/ioutil" - -// TempDir on Unix systems is equivalent to ioutil.TempDir. -func TempDir(dir, prefix string) (string, error) { - return ioutil.TempDir(dir, prefix) -} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go b/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go deleted file mode 100644 index ecaba2e36d2..00000000000 --- a/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go +++ /dev/null @@ -1,16 +0,0 @@ -package ioutils // import "github.com/docker/docker/pkg/ioutils" - -import ( - "io/ioutil" - - "github.com/docker/docker/pkg/longpath" -) - -// TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format. -func TempDir(dir, prefix string) (string, error) { - tempDir, err := ioutil.TempDir(dir, prefix) - if err != nil { - return "", err - } - return longpath.AddPrefix(tempDir), nil -} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go b/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go new file mode 100644 index 00000000000..b3321602c2e --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go @@ -0,0 +1,10 @@ +package ioutils + +import "github.com/docker/docker/pkg/longpath" + +// TempDir is the equivalent of [os.MkdirTemp], except that on Windows +// the result is in Windows longpath format. On Unix systems it is +// equivalent to [os.MkdirTemp]. +// +// Deprecated: use [longpath.MkdirTemp]. +var TempDir = longpath.MkdirTemp diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go index cf8d04b1b20..035160c834e 100644 --- a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -16,8 +16,8 @@ import ( // ensure the formatted time isalways the same number of characters. const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" -// JSONError wraps a concrete Code and Message, `Code` is -// is an integer error code, `Message` is the error message. +// JSONError wraps a concrete Code and Message, Code is +// an integer error code, Message is the error message. type JSONError struct { Code int `json:"code,omitempty"` Message string `json:"message,omitempty"` @@ -27,20 +27,28 @@ func (e *JSONError) Error() string { return e.Message } -// JSONProgress describes a Progress. terminalFd is the fd of the current terminal, -// Start is the initial value for the operation. Current is the current status and -// value of the progress made towards Total. Total is the end value describing when -// we made 100% progress for an operation. +// JSONProgress describes a progress message in a JSON stream. type JSONProgress struct { + // Current is the current status and value of the progress made towards Total. + Current int64 `json:"current,omitempty"` + // Total is the end value describing when we made 100% progress for an operation. + Total int64 `json:"total,omitempty"` + // Start is the initial value for the operation. + Start int64 `json:"start,omitempty"` + // HideCounts. if true, hides the progress count indicator (xB/yB). + HideCounts bool `json:"hidecounts,omitempty"` + // Units is the unit to print for progress. It defaults to "bytes" if empty. + Units string `json:"units,omitempty"` + + // terminalFd is the fd of the current terminal, if any. It is used + // to get the terminal width. terminalFd uintptr - Current int64 `json:"current,omitempty"` - Total int64 `json:"total,omitempty"` - Start int64 `json:"start,omitempty"` - // If true, don't show xB/yB - HideCounts bool `json:"hidecounts,omitempty"` - Units string `json:"units,omitempty"` - nowFunc func() time.Time - winSize int + + // nowFunc is used to override the current time in tests. + nowFunc func() time.Time + + // winSize is used to override the terminal width in tests. + winSize int } func (p *JSONProgress) String() string { @@ -56,8 +64,7 @@ func (p *JSONProgress) String() string { if p.Total <= 0 { switch p.Units { case "": - current := units.HumanSize(float64(p.Current)) - return fmt.Sprintf("%8v", current) + return fmt.Sprintf("%8v", units.HumanSize(float64(p.Current))) default: return fmt.Sprintf("%d %s", p.Current, p.Units) } @@ -110,17 +117,17 @@ func (p *JSONProgress) String() string { return pbBox + numbersBox + timeLeftBox } -// shim for testing +// now returns the current time in UTC, but can be overridden in tests +// by setting JSONProgress.nowFunc to a custom function. func (p *JSONProgress) now() time.Time { - if p.nowFunc == nil { - p.nowFunc = func() time.Time { - return time.Now().UTC() - } + if p.nowFunc != nil { + return p.nowFunc() } - return p.nowFunc() + return time.Now().UTC() } -// shim for testing +// width returns the current terminal's width, but can be overridden +// in tests by setting JSONProgress.winSize to a non-zero value. func (p *JSONProgress) width() int { if p.winSize != 0 { return p.winSize @@ -164,13 +171,11 @@ func cursorDown(out io.Writer, l uint) { fmt.Fprint(out, aec.Down(l)) } -// Display displays the JSONMessage to `out`. If `isTerminal` is true, it will erase the -// entire current line when displaying the progressbar. +// Display prints the JSONMessage to out. If isTerminal is true, it erases +// the entire current line when displaying the progressbar. It returns an +// error if the [JSONMessage.Error] field is non-nil. func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { if jm.Error != nil { - if jm.Error.Code == 401 { - return fmt.Errorf("authentication is required") - } return jm.Error } var endl string @@ -204,9 +209,22 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { return nil } -// DisplayJSONMessagesStream displays a json message stream from `in` to `out`, `isTerminal` -// describes if `out` is a terminal. If this is the case, it will print `\n` at the end of -// each line and move the cursor while displaying. +// DisplayJSONMessagesStream reads a JSON message stream from in, and writes +// each [JSONMessage] to out. It returns an error if an invalid JSONMessage +// is received, or if a JSONMessage containers a non-zero [JSONMessage.Error]. +// +// Presentation of the JSONMessage depends on whether a terminal is attached, +// and on the terminal width. Progress bars ([JSONProgress]) are suppressed +// on narrower terminals (< 110 characters). +// +// - isTerminal describes if out is a terminal, in which case it prints +// a newline ("\n") at the end of each line and moves the cursor while +// displaying. +// - terminalFd is the fd of the current terminal (if any), and used +// to get the terminal width. +// - auxCallback allows handling the [JSONMessage.Aux] field. It is +// called if a JSONMessage contains an Aux field, in which case +// DisplayJSONMessagesStream does not present the JSONMessage. func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error { var ( dec = json.NewDecoder(in) @@ -271,13 +289,19 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, return nil } -type stream interface { +// Stream is an io.Writer for output with utilities to get the output's file +// descriptor and to detect wether it's a terminal. +// +// it is subset of the streams.Out type in +// https://pkg.go.dev/github.com/docker/cli@v20.10.17+incompatible/cli/streams#Out +type Stream interface { io.Writer FD() uintptr IsTerminal() bool } -// DisplayJSONMessagesToStream prints json messages to the output stream -func DisplayJSONMessagesToStream(in io.Reader, stream stream, auxCallback func(JSONMessage)) error { +// DisplayJSONMessagesToStream prints json messages to the output Stream. It is +// used by the Docker CLI to print JSONMessage streams. +func DisplayJSONMessagesToStream(in io.Reader, stream Stream, auxCallback func(JSONMessage)) error { return DisplayJSONMessagesStream(in, stream, stream.FD(), stream.IsTerminal(), auxCallback) } diff --git a/vendor/github.com/docker/docker/pkg/longpath/longpath.go b/vendor/github.com/docker/docker/pkg/longpath/longpath.go index 4177affba24..1c5dde5218f 100644 --- a/vendor/github.com/docker/docker/pkg/longpath/longpath.go +++ b/vendor/github.com/docker/docker/pkg/longpath/longpath.go @@ -1,17 +1,20 @@ -// longpath introduces some constants and helper functions for handling long paths -// in Windows, which are expected to be prepended with `\\?\` and followed by either -// a drive letter, a UNC server\share, or a volume identifier. - +// Package longpath introduces some constants and helper functions for handling +// long paths in Windows. +// +// Long paths are expected to be prepended with "\\?\" and followed by either a +// drive letter, a UNC server\share, or a volume identifier. package longpath // import "github.com/docker/docker/pkg/longpath" import ( + "os" + "runtime" "strings" ) // Prefix is the longpath prefix for Windows file paths. const Prefix = `\\?\` -// AddPrefix will add the Windows long path prefix to the path provided if +// AddPrefix adds the Windows long path prefix to the path provided if // it does not already have it. func AddPrefix(path string) string { if !strings.HasPrefix(path, Prefix) { @@ -24,3 +27,17 @@ func AddPrefix(path string) string { } return path } + +// MkdirTemp is the equivalent of [os.MkdirTemp], except that on Windows +// the result is in Windows longpath format. On Unix systems it is +// equivalent to [os.MkdirTemp]. +func MkdirTemp(dir, prefix string) (string, error) { + tempDir, err := os.MkdirTemp(dir, prefix) + if err != nil { + return "", err + } + if runtime.GOOS != "windows" { + return tempDir, nil + } + return AddPrefix(tempDir), nil +} diff --git a/vendor/github.com/docker/docker/pkg/stringid/README.md b/vendor/github.com/docker/docker/pkg/stringid/README.md deleted file mode 100644 index 37a5098fd98..00000000000 --- a/vendor/github.com/docker/docker/pkg/stringid/README.md +++ /dev/null @@ -1 +0,0 @@ -This package provides helper functions for dealing with string identifiers diff --git a/vendor/github.com/docker/docker/pkg/stringid/stringid.go b/vendor/github.com/docker/docker/pkg/stringid/stringid.go deleted file mode 100644 index 5fe071d6284..00000000000 --- a/vendor/github.com/docker/docker/pkg/stringid/stringid.go +++ /dev/null @@ -1,63 +0,0 @@ -// Package stringid provides helper functions for dealing with string identifiers -package stringid // import "github.com/docker/docker/pkg/stringid" - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "regexp" - "strconv" - "strings" -) - -const shortLen = 12 - -var ( - validShortID = regexp.MustCompile("^[a-f0-9]{12}$") - validHex = regexp.MustCompile(`^[a-f0-9]{64}$`) -) - -// IsShortID determines if an arbitrary string *looks like* a short ID. -func IsShortID(id string) bool { - return validShortID.MatchString(id) -} - -// TruncateID returns a shorthand version of a string identifier for convenience. -// A collision with other shorthands is very unlikely, but possible. -// In case of a collision a lookup with TruncIndex.Get() will fail, and the caller -// will need to use a longer prefix, or the full-length Id. -func TruncateID(id string) string { - if i := strings.IndexRune(id, ':'); i >= 0 { - id = id[i+1:] - } - if len(id) > shortLen { - id = id[:shortLen] - } - return id -} - -// GenerateRandomID returns a unique id. -func GenerateRandomID() string { - b := make([]byte, 32) - for { - if _, err := rand.Read(b); err != nil { - panic(err) // This shouldn't happen - } - id := hex.EncodeToString(b) - // if we try to parse the truncated for as an int and we don't have - // an error then the value is all numeric and causes issues when - // used as a hostname. ref #3869 - if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil { - continue - } - return id - } -} - -// ValidateID checks whether an ID string is a valid image ID. -func ValidateID(id string) error { - if ok := validHex.MatchString(id); !ok { - return fmt.Errorf("image ID %q is invalid", id) - } - return nil -} diff --git a/vendor/github.com/docker/docker/registry/auth.go b/vendor/github.com/docker/docker/registry/auth.go index 2d0ecde2d47..dd75a49f38d 100644 --- a/vendor/github.com/docker/docker/registry/auth.go +++ b/vendor/github.com/docker/docker/registry/auth.go @@ -9,19 +9,16 @@ import ( "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/auth/challenge" "github.com/docker/distribution/registry/client/transport" - "github.com/docker/docker/api/types" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -const ( - // AuthClientID is used the ClientID used for the token server - AuthClientID = "docker" -) +// AuthClientID is used the ClientID used for the token server +const AuthClientID = "docker" type loginCredentialStore struct { - authConfig *types.AuthConfig + authConfig *registry.AuthConfig } func (lcs loginCredentialStore) Basic(*url.URL) (string, string) { @@ -37,12 +34,12 @@ func (lcs loginCredentialStore) SetRefreshToken(u *url.URL, service, token strin } type staticCredentialStore struct { - auth *types.AuthConfig + auth *registry.AuthConfig } // NewStaticCredentialStore returns a credential store // which always returns the same credential values. -func NewStaticCredentialStore(auth *types.AuthConfig) auth.CredentialStore { +func NewStaticCredentialStore(auth *registry.AuthConfig) auth.CredentialStore { return staticCredentialStore{ auth: auth, } @@ -65,48 +62,33 @@ func (scs staticCredentialStore) RefreshToken(*url.URL, string) string { func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) { } -type fallbackError struct { - err error -} - -func (err fallbackError) Error() string { - return err.err.Error() -} - // loginV2 tries to login to the v2 registry server. The given registry // endpoint will be pinged to get authorization challenges. These challenges // will be used to authenticate against the registry to validate credentials. -func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { +func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { var ( endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/" modifiers = Headers(userAgent, nil) - authTransport = transport.NewTransport(NewTransport(endpoint.TLSConfig), modifiers...) + authTransport = transport.NewTransport(newTransport(endpoint.TLSConfig), modifiers...) credentialAuthConfig = *authConfig creds = loginCredentialStore{authConfig: &credentialAuthConfig} ) logrus.Debugf("attempting v2 login to registry endpoint %s", endpointStr) - loginClient, foundV2, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil) + loginClient, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil) if err != nil { return "", "", err } req, err := http.NewRequest(http.MethodGet, endpointStr, nil) if err != nil { - if !foundV2 { - err = fallbackError{err: err} - } return "", "", err } resp, err := loginClient.Do(req) if err != nil { err = translateV2AuthError(err) - if !foundV2 { - err = fallbackError{err: err} - } - return "", "", err } defer resp.Body.Close() @@ -116,20 +98,13 @@ func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent strin } // TODO(dmcgowan): Attempt to further interpret result, status code and error code string - err = errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode)) - if !foundV2 { - err = fallbackError{err: err} - } - return "", "", err + return "", "", errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode)) } -func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, bool, error) { - challengeManager, foundV2, err := PingV2Registry(endpoint, authTransport) +func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, error) { + challengeManager, err := PingV2Registry(endpoint, authTransport) if err != nil { - if !foundV2 { - err = fallbackError{err: err} - } - return nil, foundV2, err + return nil, err } tokenHandlerOptions := auth.TokenHandlerOptions{ @@ -142,13 +117,11 @@ func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifi tokenHandler := auth.NewTokenHandlerWithOptions(tokenHandlerOptions) basicHandler := auth.NewBasicHandler(creds) modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler)) - tr := transport.NewTransport(authTransport, modifiers...) return &http.Client{ - Transport: tr, + Transport: transport.NewTransport(authTransport, modifiers...), Timeout: 15 * time.Second, - }, foundV2, nil - + }, nil } // ConvertToHostname converts a registry url which has http|https prepended @@ -160,14 +133,11 @@ func ConvertToHostname(url string) string { } else if strings.HasPrefix(url, "https://") { stripped = strings.TrimPrefix(url, "https://") } - - nameParts := strings.SplitN(stripped, "/", 2) - - return nameParts[0] + return strings.SplitN(stripped, "/", 2)[0] } // ResolveAuthConfig matches an auth configuration to a server address or a URL -func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registrytypes.IndexInfo) types.AuthConfig { +func ResolveAuthConfig(authConfigs map[string]registry.AuthConfig, index *registry.IndexInfo) registry.AuthConfig { configKey := GetAuthConfigKey(index) // First try the happy case if c, found := authConfigs[configKey]; found || index.Official { @@ -183,7 +153,7 @@ func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registryt } // When all else fails, return an empty auth config - return types.AuthConfig{} + return registry.AuthConfig{} } // PingResponseError is used when the response from a ping @@ -197,18 +167,9 @@ func (err PingResponseError) Error() string { } // PingV2Registry attempts to ping a v2 registry and on success return a -// challenge manager for the supported authentication types and -// whether v2 was confirmed by the response. If a response is received but -// cannot be interpreted a PingResponseError will be returned. -func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (challenge.Manager, bool, error) { - var ( - foundV2 = false - v2Version = auth.APIVersion{ - Type: "registry", - Version: "2.0", - } - ) - +// challenge manager for the supported authentication types. +// If a response is received but cannot be interpreted, a PingResponseError will be returned. +func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (challenge.Manager, error) { pingClient := &http.Client{ Transport: transport, Timeout: 15 * time.Second, @@ -216,32 +177,20 @@ func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (challenge.M endpointStr := strings.TrimRight(endpoint.String(), "/") + "/v2/" req, err := http.NewRequest(http.MethodGet, endpointStr, nil) if err != nil { - return nil, false, err + return nil, err } resp, err := pingClient.Do(req) if err != nil { - return nil, false, err + return nil, err } defer resp.Body.Close() - versions := auth.APIVersions(resp, DefaultRegistryVersionHeader) - for _, pingVersion := range versions { - if pingVersion == v2Version { - // The version header indicates we're definitely - // talking to a v2 registry. So don't allow future - // fallbacks to the v1 protocol. - - foundV2 = true - break - } - } - challengeManager := challenge.NewSimpleManager() if err := challengeManager.AddResponse(resp); err != nil { - return nil, foundV2, PingResponseError{ + return nil, PingResponseError{ Err: err, } } - return challengeManager, foundV2, nil + return challengeManager, nil } diff --git a/vendor/github.com/docker/docker/registry/config.go b/vendor/github.com/docker/docker/registry/config.go index 54b83fa40aa..2766306ac20 100644 --- a/vendor/github.com/docker/docker/registry/config.go +++ b/vendor/github.com/docker/docker/registry/config.go @@ -1,7 +1,6 @@ package registry // import "github.com/docker/docker/registry" import ( - "fmt" "net" "net/url" "regexp" @@ -9,8 +8,7 @@ import ( "strings" "github.com/docker/distribution/reference" - registrytypes "github.com/docker/docker/api/types/registry" - "github.com/pkg/errors" + "github.com/docker/docker/api/types/registry" "github.com/sirupsen/logrus" ) @@ -22,18 +20,26 @@ type ServiceOptions struct { } // serviceConfig holds daemon configuration for the registry service. -type serviceConfig struct { - registrytypes.ServiceConfig -} - +type serviceConfig registry.ServiceConfig + +// TODO(thaJeztah) both the "index.docker.io" and "registry-1.docker.io" domains +// are here for historic reasons and backward-compatibility. These domains +// are still supported by Docker Hub (and will continue to be supported), but +// there are new domains already in use, and plans to consolidate all legacy +// domains to new "canonical" domains. Once those domains are decided on, we +// should update these consts (but making sure to preserve compatibility with +// existing installs, clients, and user configuration). const ( // DefaultNamespace is the default namespace DefaultNamespace = "docker.io" - // DefaultRegistryVersionHeader is the name of the default HTTP header - // that carries Registry version info - DefaultRegistryVersionHeader = "Docker-Distribution-Api-Version" - - // IndexHostname is the index hostname + // DefaultRegistryHost is the hostname for the default (Docker Hub) registry + // used for pushing and pulling images. This hostname is hard-coded to handle + // the conversion from image references without registry name (e.g. "ubuntu", + // or "ubuntu:latest"), as well as references using the "docker.io" domain + // name, which is used as canonical reference for images on Docker Hub, but + // does not match the domain-name of Docker Hub's registry. + DefaultRegistryHost = "registry-1.docker.io" + // IndexHostname is the index hostname, used for authentication and image search. IndexHostname = "index.docker.io" // IndexServer is used for user auth and image search IndexServer = "https://" + IndexHostname + "/v1/" @@ -42,76 +48,98 @@ const ( ) var ( - // DefaultV2Registry is the URI of the default v2 registry + // DefaultV2Registry is the URI of the default (Docker Hub) registry. DefaultV2Registry = &url.URL{ Scheme: "https", - Host: "registry-1.docker.io", + Host: DefaultRegistryHost, } - // ErrInvalidRepositoryName is an error returned if the repository name did - // not have the correct form - ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")") - emptyServiceConfig, _ = newServiceConfig(ServiceOptions{}) validHostPortRegex = regexp.MustCompile(`^` + reference.DomainRegexp.String() + `$`) // for mocking in unit tests lookupIP = net.LookupIP + + // certsDir is used to override defaultCertsDir. + certsDir string ) +// SetCertsDir allows the default certs directory to be changed. This function +// is used at daemon startup to set the correct location when running in +// rootless mode. +func SetCertsDir(path string) { + certsDir = path +} + +// CertsDir is the directory where certificates are stored. +func CertsDir() string { + if certsDir != "" { + return certsDir + } + return defaultCertsDir +} + // newServiceConfig returns a new instance of ServiceConfig func newServiceConfig(options ServiceOptions) (*serviceConfig, error) { - config := &serviceConfig{ - ServiceConfig: registrytypes.ServiceConfig{ - InsecureRegistryCIDRs: make([]*registrytypes.NetIPNet, 0), - IndexConfigs: make(map[string]*registrytypes.IndexInfo), - // Hack: Bypass setting the mirrors to IndexConfigs since they are going away - // and Mirrors are only for the official registry anyways. - }, - } - if err := config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil { + config := &serviceConfig{} + if err := config.loadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil { return nil, err } - if err := config.LoadMirrors(options.Mirrors); err != nil { + if err := config.loadMirrors(options.Mirrors); err != nil { return nil, err } - if err := config.LoadInsecureRegistries(options.InsecureRegistries); err != nil { + if err := config.loadInsecureRegistries(options.InsecureRegistries); err != nil { return nil, err } return config, nil } -// LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config. -func (config *serviceConfig) LoadAllowNondistributableArtifacts(registries []string) error { - cidrs := map[string]*registrytypes.NetIPNet{} +// copy constructs a new ServiceConfig with a copy of the configuration in config. +func (config *serviceConfig) copy() *registry.ServiceConfig { + ic := make(map[string]*registry.IndexInfo) + for key, value := range config.IndexConfigs { + ic[key] = value + } + return ®istry.ServiceConfig{ + AllowNondistributableArtifactsCIDRs: append([]*registry.NetIPNet(nil), config.AllowNondistributableArtifactsCIDRs...), + AllowNondistributableArtifactsHostnames: append([]string(nil), config.AllowNondistributableArtifactsHostnames...), + InsecureRegistryCIDRs: append([]*registry.NetIPNet(nil), config.InsecureRegistryCIDRs...), + IndexConfigs: ic, + Mirrors: append([]string(nil), config.Mirrors...), + } +} + +// loadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config. +func (config *serviceConfig) loadAllowNondistributableArtifacts(registries []string) error { + cidrs := map[string]*registry.NetIPNet{} hostnames := map[string]bool{} for _, r := range registries { if _, err := ValidateIndexName(r); err != nil { return err } - if validateNoScheme(r) != nil { - return fmt.Errorf("allow-nondistributable-artifacts registry %s should not contain '://'", r) + if hasScheme(r) { + return invalidParamf("allow-nondistributable-artifacts registry %s should not contain '://'", r) } if _, ipnet, err := net.ParseCIDR(r); err == nil { // Valid CIDR. - cidrs[ipnet.String()] = (*registrytypes.NetIPNet)(ipnet) - } else if err := validateHostPort(r); err == nil { + cidrs[ipnet.String()] = (*registry.NetIPNet)(ipnet) + } else if err = validateHostPort(r); err == nil { // Must be `host:port` if not CIDR. hostnames[r] = true } else { - return fmt.Errorf("allow-nondistributable-artifacts registry %s is not valid: %v", r, err) + return invalidParamWrapf(err, "allow-nondistributable-artifacts registry %s is not valid", r) } } - config.AllowNondistributableArtifactsCIDRs = make([]*(registrytypes.NetIPNet), 0) + config.AllowNondistributableArtifactsCIDRs = make([]*registry.NetIPNet, 0, len(cidrs)) for _, c := range cidrs { config.AllowNondistributableArtifactsCIDRs = append(config.AllowNondistributableArtifactsCIDRs, c) } - config.AllowNondistributableArtifactsHostnames = make([]string, 0) + config.AllowNondistributableArtifactsHostnames = make([]string, 0, len(hostnames)) for h := range hostnames { config.AllowNondistributableArtifactsHostnames = append(config.AllowNondistributableArtifactsHostnames, h) } @@ -119,9 +147,9 @@ func (config *serviceConfig) LoadAllowNondistributableArtifacts(registries []str return nil } -// LoadMirrors loads mirrors to config, after removing duplicates. +// loadMirrors loads mirrors to config, after removing duplicates. // Returns an error if mirrors contains an invalid mirror. -func (config *serviceConfig) LoadMirrors(mirrors []string) error { +func (config *serviceConfig) loadMirrors(mirrors []string) error { mMap := map[string]struct{}{} unique := []string{} @@ -139,40 +167,33 @@ func (config *serviceConfig) LoadMirrors(mirrors []string) error { config.Mirrors = unique // Configure public registry since mirrors may have changed. - config.IndexConfigs[IndexName] = ®istrytypes.IndexInfo{ - Name: IndexName, - Mirrors: config.Mirrors, - Secure: true, - Official: true, + config.IndexConfigs = map[string]*registry.IndexInfo{ + IndexName: { + Name: IndexName, + Mirrors: unique, + Secure: true, + Official: true, + }, } return nil } -// LoadInsecureRegistries loads insecure registries to config -func (config *serviceConfig) LoadInsecureRegistries(registries []string) error { - // Localhost is by default considered as an insecure registry - // This is a stop-gap for people who are running a private registry on localhost (especially on Boot2docker). - // - // TODO: should we deprecate this once it is easier for people to set up a TLS registry or change - // daemon flags on boot2docker? +// loadInsecureRegistries loads insecure registries to config +func (config *serviceConfig) loadInsecureRegistries(registries []string) error { + // Localhost is by default considered as an insecure registry. This is a + // stop-gap for people who are running a private registry on localhost. registries = append(registries, "127.0.0.0/8") - // Store original InsecureRegistryCIDRs and IndexConfigs - // Clean InsecureRegistryCIDRs and IndexConfigs in config, as passed registries has all insecure registry info. - originalCIDRs := config.ServiceConfig.InsecureRegistryCIDRs - originalIndexInfos := config.ServiceConfig.IndexConfigs - - config.ServiceConfig.InsecureRegistryCIDRs = make([]*registrytypes.NetIPNet, 0) - config.ServiceConfig.IndexConfigs = make(map[string]*registrytypes.IndexInfo) + var ( + insecureRegistryCIDRs = make([]*registry.NetIPNet, 0) + indexConfigs = make(map[string]*registry.IndexInfo) + ) skip: for _, r := range registries { // validate insecure registry if _, err := ValidateIndexName(r); err != nil { - // before returning err, roll back to original data - config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs - config.ServiceConfig.IndexConfigs = originalIndexInfos return err } if strings.HasPrefix(strings.ToLower(r), "http://") { @@ -181,35 +202,27 @@ skip: } else if strings.HasPrefix(strings.ToLower(r), "https://") { logrus.Warnf("insecure registry %s should not contain 'https://' and 'https://' has been removed from the insecure registry config", r) r = r[8:] - } else if validateNoScheme(r) != nil { - // Insecure registry should not contain '://' - // before returning err, roll back to original data - config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs - config.ServiceConfig.IndexConfigs = originalIndexInfos - return fmt.Errorf("insecure registry %s should not contain '://'", r) + } else if hasScheme(r) { + return invalidParamf("insecure registry %s should not contain '://'", r) } // Check if CIDR was passed to --insecure-registry _, ipnet, err := net.ParseCIDR(r) if err == nil { // Valid CIDR. If ipnet is already in config.InsecureRegistryCIDRs, skip. - data := (*registrytypes.NetIPNet)(ipnet) - for _, value := range config.InsecureRegistryCIDRs { + data := (*registry.NetIPNet)(ipnet) + for _, value := range insecureRegistryCIDRs { if value.IP.String() == data.IP.String() && value.Mask.String() == data.Mask.String() { continue skip } } // ipnet is not found, add it in config.InsecureRegistryCIDRs - config.InsecureRegistryCIDRs = append(config.InsecureRegistryCIDRs, data) - + insecureRegistryCIDRs = append(insecureRegistryCIDRs, data) } else { if err := validateHostPort(r); err != nil { - config.ServiceConfig.InsecureRegistryCIDRs = originalCIDRs - config.ServiceConfig.IndexConfigs = originalIndexInfos - return fmt.Errorf("insecure registry %s is not valid: %v", r, err) - + return invalidParamWrapf(err, "insecure registry %s is not valid", r) } // Assume `host:port` if not CIDR. - config.IndexConfigs[r] = ®istrytypes.IndexInfo{ + indexConfigs[r] = ®istry.IndexInfo{ Name: r, Mirrors: make([]string, 0), Secure: false, @@ -219,12 +232,14 @@ skip: } // Configure public registry. - config.IndexConfigs[IndexName] = ®istrytypes.IndexInfo{ + indexConfigs[IndexName] = ®istry.IndexInfo{ Name: IndexName, Mirrors: config.Mirrors, Secure: true, Official: true, } + config.InsecureRegistryCIDRs = insecureRegistryCIDRs + config.IndexConfigs = indexConfigs return nil } @@ -238,7 +253,7 @@ skip: // hostname should be a URL.Host (`host:port` or `host`) where the `host` part can be either a domain name // or an IP address. If it is a domain name, then it will be resolved to IP addresses for matching. If // resolution fails, CIDR matching is not performed. -func allowNondistributableArtifacts(config *serviceConfig, hostname string) bool { +func (config *serviceConfig) allowNondistributableArtifacts(hostname string) bool { for _, h := range config.AllowNondistributableArtifactsHostnames { if h == hostname { return true @@ -259,7 +274,7 @@ func allowNondistributableArtifacts(config *serviceConfig, hostname string) bool // or an IP address. If it is a domain name, then it will be resolved in order to check if the IP is contained // in a subnet. If the resolving is not successful, isSecureIndex will only try to match hostname to any element // of insecureRegistries. -func isSecureIndex(config *serviceConfig, indexName string) bool { +func (config *serviceConfig) isSecureIndex(indexName string) bool { // Check for configured index, first. This is needed in case isSecureIndex // is called from anything besides newIndexInfo, in order to honor per-index configurations. if index, ok := config.IndexConfigs[indexName]; ok { @@ -272,7 +287,7 @@ func isSecureIndex(config *serviceConfig, indexName string) bool { // isCIDRMatch returns true if URLHost matches an element of cidrs. URLHost is a URL.Host (`host:port` or `host`) // where the `host` part can be either a domain name or an IP address. If it is a domain name, then it will be // resolved to IP addresses for matching. If resolution fails, false is returned. -func isCIDRMatch(cidrs []*registrytypes.NetIPNet, URLHost string) bool { +func isCIDRMatch(cidrs []*registry.NetIPNet, URLHost string) bool { host, _, err := net.SplitHostPort(URLHost) if err != nil { // Assume URLHost is of the form `host` without the port and go on. @@ -308,18 +323,18 @@ func isCIDRMatch(cidrs []*registrytypes.NetIPNet, URLHost string) bool { func ValidateMirror(val string) (string, error) { uri, err := url.Parse(val) if err != nil { - return "", fmt.Errorf("invalid mirror: %q is not a valid URI", val) + return "", invalidParamWrapf(err, "invalid mirror: %q is not a valid URI", val) } if uri.Scheme != "http" && uri.Scheme != "https" { - return "", fmt.Errorf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri) + return "", invalidParamf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri) } if (uri.Path != "" && uri.Path != "/") || uri.RawQuery != "" || uri.Fragment != "" { - return "", fmt.Errorf("invalid mirror: path, query, or fragment at end of the URI %q", uri) + return "", invalidParamf("invalid mirror: path, query, or fragment at end of the URI %q", uri) } if uri.User != nil { // strip password from output uri.User = url.UserPassword(uri.User.Username(), "xxxxx") - return "", fmt.Errorf("invalid mirror: username/password not allowed in URI %q", uri) + return "", invalidParamf("invalid mirror: username/password not allowed in URI %q", uri) } return strings.TrimSuffix(val, "/") + "/", nil } @@ -331,17 +346,13 @@ func ValidateIndexName(val string) (string, error) { val = "docker.io" } if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") { - return "", fmt.Errorf("invalid index name (%s). Cannot begin or end with a hyphen", val) + return "", invalidParamf("invalid index name (%s). Cannot begin or end with a hyphen", val) } return val, nil } -func validateNoScheme(reposName string) error { - if strings.Contains(reposName, "://") { - // It cannot contain a scheme! - return ErrInvalidRepositoryName - } - return nil +func hasScheme(reposName string) bool { + return strings.Contains(reposName, "://") } func validateHostPort(s string) error { @@ -354,7 +365,7 @@ func validateHostPort(s string) error { // If match against the `host:port` pattern fails, // it might be `IPv6:port`, which will be captured by net.ParseIP(host) if !validHostPortRegex.MatchString(s) && net.ParseIP(host) == nil { - return fmt.Errorf("invalid host %q", host) + return invalidParamf("invalid host %q", host) } if port != "" { v, err := strconv.Atoi(port) @@ -362,14 +373,14 @@ func validateHostPort(s string) error { return err } if v < 0 || v > 65535 { - return fmt.Errorf("invalid port %q", port) + return invalidParamf("invalid port %q", port) } } return nil } // newIndexInfo returns IndexInfo configuration from indexName -func newIndexInfo(config *serviceConfig, indexName string) (*registrytypes.IndexInfo, error) { +func newIndexInfo(config *serviceConfig, indexName string) (*registry.IndexInfo, error) { var err error indexName, err = ValidateIndexName(indexName) if err != nil { @@ -382,18 +393,17 @@ func newIndexInfo(config *serviceConfig, indexName string) (*registrytypes.Index } // Construct a non-configured index info. - index := ®istrytypes.IndexInfo{ + return ®istry.IndexInfo{ Name: indexName, Mirrors: make([]string, 0), + Secure: config.isSecureIndex(indexName), Official: false, - } - index.Secure = isSecureIndex(config, indexName) - return index, nil + }, nil } // GetAuthConfigKey special-cases using the full index address of the official // index as the AuthConfig key, and uses the (host)name[:port] for private indexes. -func GetAuthConfigKey(index *registrytypes.IndexInfo) string { +func GetAuthConfigKey(index *registry.IndexInfo) string { if index.Official { return IndexServer } @@ -422,7 +432,12 @@ func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) { } // ParseSearchIndexInfo will use repository name to get back an indexInfo. -func ParseSearchIndexInfo(reposName string) (*registrytypes.IndexInfo, error) { +// +// TODO(thaJeztah) this function is only used by the CLI, and used to get +// information of the registry (to provide credentials if needed). We should +// move this function (or equivalent) to the CLI, as it's doing too much just +// for that. +func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) { indexName, _ := splitReposSearchTerm(reposName) indexInfo, err := newIndexInfo(emptyServiceConfig, indexName) diff --git a/vendor/github.com/docker/docker/registry/config_unix.go b/vendor/github.com/docker/docker/registry/config_unix.go index b5bb31cfa65..898c6b8a5bf 100644 --- a/vendor/github.com/docker/docker/registry/config_unix.go +++ b/vendor/github.com/docker/docker/registry/config_unix.go @@ -3,25 +3,10 @@ package registry // import "github.com/docker/docker/registry" -import ( - "path/filepath" - - "github.com/docker/docker/pkg/homedir" - "github.com/docker/docker/rootless" -) - -// CertsDir is the directory where certificates are stored -func CertsDir() string { - d := "/etc/docker/certs.d" - - if rootless.RunningWithRootlessKit() { - configHome, err := homedir.GetConfigHome() - if err == nil { - d = filepath.Join(configHome, "docker/certs.d") - } - } - return d -} +// defaultCertsDir is the platform-specific default directory where certificates +// are stored. On Linux, it may be overridden through certsDir, for example, when +// running in rootless mode. +const defaultCertsDir = "/etc/docker/certs.d" // cleanPath is used to ensure that a directory name is valid on the target // platform. It will be passed in something *similar* to a URL such as diff --git a/vendor/github.com/docker/docker/registry/config_windows.go b/vendor/github.com/docker/docker/registry/config_windows.go index 4ae1e07abfd..2674f2818ab 100644 --- a/vendor/github.com/docker/docker/registry/config_windows.go +++ b/vendor/github.com/docker/docker/registry/config_windows.go @@ -6,15 +6,15 @@ import ( "strings" ) -// CertsDir is the directory where certificates are stored -func CertsDir() string { - return os.Getenv("programdata") + `\docker\certs.d` -} +// defaultCertsDir is the platform-specific default directory where certificates +// are stored. On Linux, it may be overridden through certsDir, for example, when +// running in rootless mode. +var defaultCertsDir = os.Getenv("programdata") + `\docker\certs.d` // cleanPath is used to ensure that a directory name is valid on the target // platform. It will be passed in something *similar* to a URL such as // https:\index.docker.io\v1. Not all platforms support directory names // which contain those characters (such as : on Windows) func cleanPath(s string) string { - return filepath.FromSlash(strings.Replace(s, ":", "", -1)) + return filepath.FromSlash(strings.ReplaceAll(s, ":", "")) } diff --git a/vendor/github.com/docker/docker/registry/endpoint_v1.go b/vendor/github.com/docker/docker/registry/endpoint_v1.go index a355a4f872e..56257dc799a 100644 --- a/vendor/github.com/docker/docker/registry/endpoint_v1.go +++ b/vendor/github.com/docker/docker/registry/endpoint_v1.go @@ -3,109 +3,104 @@ package registry // import "github.com/docker/docker/registry" import ( "crypto/tls" "encoding/json" - "fmt" - "io/ioutil" + "io" "net/http" "net/url" "strings" "github.com/docker/distribution/registry/client/transport" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" "github.com/sirupsen/logrus" ) -// V1Endpoint stores basic information about a V1 registry endpoint. -type V1Endpoint struct { +// v1PingResult contains the information returned when pinging a registry. It +// indicates the registry's version and whether the registry claims to be a +// standalone registry. +type v1PingResult struct { + // Version is the registry version supplied by the registry in an HTTP + // header + Version string `json:"version"` + // Standalone is set to true if the registry indicates it is a + // standalone registry in the X-Docker-Registry-Standalone + // header + Standalone bool `json:"standalone"` +} + +// v1Endpoint stores basic information about a V1 registry endpoint. +type v1Endpoint struct { client *http.Client URL *url.URL IsSecure bool } -// NewV1Endpoint parses the given address to return a registry endpoint. -func NewV1Endpoint(index *registrytypes.IndexInfo, userAgent string, metaHeaders http.Header) (*V1Endpoint, error) { +// newV1Endpoint parses the given address to return a registry endpoint. +// TODO: remove. This is only used by search. +func newV1Endpoint(index *registry.IndexInfo, headers http.Header) (*v1Endpoint, error) { tlsConfig, err := newTLSConfig(index.Name, index.Secure) if err != nil { return nil, err } - endpoint, err := newV1EndpointFromStr(GetAuthConfigKey(index), tlsConfig, userAgent, metaHeaders) + endpoint, err := newV1EndpointFromStr(GetAuthConfigKey(index), tlsConfig, headers) if err != nil { return nil, err } - if err := validateEndpoint(endpoint); err != nil { + err = validateEndpoint(endpoint) + if err != nil { return nil, err } return endpoint, nil } -func validateEndpoint(endpoint *V1Endpoint) error { +func validateEndpoint(endpoint *v1Endpoint) error { logrus.Debugf("pinging registry endpoint %s", endpoint) // Try HTTPS ping to registry endpoint.URL.Scheme = "https" - if _, err := endpoint.Ping(); err != nil { + if _, err := endpoint.ping(); err != nil { if endpoint.IsSecure { // If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry` // in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fallback to HTTP. - return fmt.Errorf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host) + return invalidParamf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host) } // If registry is insecure and HTTPS failed, fallback to HTTP. - logrus.Debugf("Error from registry %q marked as insecure: %v. Insecurely falling back to HTTP", endpoint, err) + logrus.WithError(err).Debugf("error from registry %q marked as insecure - insecurely falling back to HTTP", endpoint) endpoint.URL.Scheme = "http" var err2 error - if _, err2 = endpoint.Ping(); err2 == nil { + if _, err2 = endpoint.ping(); err2 == nil { return nil } - return fmt.Errorf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2) + return invalidParamf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2) } return nil } -func newV1Endpoint(address url.URL, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) *V1Endpoint { - endpoint := &V1Endpoint{ - IsSecure: tlsConfig == nil || !tlsConfig.InsecureSkipVerify, - URL: new(url.URL), - } - - *endpoint.URL = address - - // TODO(tiborvass): make sure a ConnectTimeout transport is used - tr := NewTransport(tlsConfig) - endpoint.client = HTTPClient(transport.NewTransport(tr, Headers(userAgent, metaHeaders)...)) - return endpoint -} - // trimV1Address trims the version off the address and returns the // trimmed address or an error if there is a non-V1 version. func trimV1Address(address string) (string, error) { - var ( - chunks []string - apiVersionStr string - ) - address = strings.TrimSuffix(address, "/") - chunks = strings.Split(address, "/") - apiVersionStr = chunks[len(chunks)-1] + chunks := strings.Split(address, "/") + apiVersionStr := chunks[len(chunks)-1] if apiVersionStr == "v1" { return strings.Join(chunks[:len(chunks)-1], "/"), nil } for k, v := range apiVersions { if k != APIVersion1 && apiVersionStr == v { - return "", fmt.Errorf("unsupported V1 version path %s", apiVersionStr) + return "", invalidParamf("unsupported V1 version path %s", apiVersionStr) } } return address, nil } -func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*V1Endpoint, error) { +func newV1EndpointFromStr(address string, tlsConfig *tls.Config, headers http.Header) (*v1Endpoint, error) { if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") { address = "https://" + address } @@ -117,69 +112,67 @@ func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent strin uri, err := url.Parse(address) if err != nil { - return nil, err + return nil, invalidParam(err) } - endpoint := newV1Endpoint(*uri, tlsConfig, userAgent, metaHeaders) + // TODO(tiborvass): make sure a ConnectTimeout transport is used + tr := newTransport(tlsConfig) - return endpoint, nil + return &v1Endpoint{ + IsSecure: tlsConfig == nil || !tlsConfig.InsecureSkipVerify, + URL: uri, + client: httpClient(transport.NewTransport(tr, Headers("", headers)...)), + }, nil } // Get the formatted URL for the root of this registry Endpoint -func (e *V1Endpoint) String() string { +func (e *v1Endpoint) String() string { return e.URL.String() + "/v1/" } -// Path returns a formatted string for the URL -// of this endpoint with the given path appended. -func (e *V1Endpoint) Path(path string) string { - return e.URL.String() + "/v1/" + path -} - -// Ping returns a PingResult which indicates whether the registry is standalone or not. -func (e *V1Endpoint) Ping() (PingResult, error) { - logrus.Debugf("attempting v1 ping for registry endpoint %s", e) - +// ping returns a v1PingResult which indicates whether the registry is standalone or not. +func (e *v1Endpoint) ping() (v1PingResult, error) { if e.String() == IndexServer { // Skip the check, we know this one is valid // (and we never want to fallback to http in case of error) - return PingResult{Standalone: false}, nil + return v1PingResult{}, nil } - req, err := http.NewRequest(http.MethodGet, e.Path("_ping"), nil) + logrus.Debugf("attempting v1 ping for registry endpoint %s", e) + pingURL := e.String() + "_ping" + req, err := http.NewRequest(http.MethodGet, pingURL, nil) if err != nil { - return PingResult{Standalone: false}, err + return v1PingResult{}, invalidParam(err) } resp, err := e.client.Do(req) if err != nil { - return PingResult{Standalone: false}, err + return v1PingResult{}, invalidParam(err) } defer resp.Body.Close() - jsonString, err := ioutil.ReadAll(resp.Body) + jsonString, err := io.ReadAll(resp.Body) if err != nil { - return PingResult{Standalone: false}, fmt.Errorf("error while reading the http response: %s", err) + return v1PingResult{}, invalidParamWrapf(err, "error while reading response from %s", pingURL) } // If the header is absent, we assume true for compatibility with earlier // versions of the registry. default to true - info := PingResult{ + info := v1PingResult{ Standalone: true, } if err := json.Unmarshal(jsonString, &info); err != nil { - logrus.Debugf("Error unmarshaling the _ping PingResult: %s", err) + logrus.WithError(err).Debug("error unmarshaling _ping response") // don't stop here. Just assume sane defaults } if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" { - logrus.Debugf("Registry version header: '%s'", hdr) info.Version = hdr } - logrus.Debugf("PingResult.Version: %q", info.Version) + logrus.Debugf("v1PingResult.Version: %q", info.Version) standalone := resp.Header.Get("X-Docker-Registry-Standalone") - logrus.Debugf("Registry standalone header: '%s'", standalone) + // Accepted values are "true" (case-insensitive) and "1". if strings.EqualFold(standalone, "true") || standalone == "1" { info.Standalone = true @@ -187,6 +180,6 @@ func (e *V1Endpoint) Ping() (PingResult, error) { // there is a header set, and it is not "true" or "1", so assume fails info.Standalone = false } - logrus.Debugf("PingResult.Standalone: %t", info.Standalone) + logrus.Debugf("v1PingResult.Standalone: %t", info.Standalone) return info, nil } diff --git a/vendor/github.com/docker/docker/registry/errors.go b/vendor/github.com/docker/docker/registry/errors.go index 4906303efcf..7dc20ad8ff4 100644 --- a/vendor/github.com/docker/docker/registry/errors.go +++ b/vendor/github.com/docker/docker/registry/errors.go @@ -5,6 +5,7 @@ import ( "github.com/docker/distribution/registry/api/errcode" "github.com/docker/docker/errdefs" + "github.com/pkg/errors" ) func translateV2AuthError(err error) error { @@ -21,3 +22,15 @@ func translateV2AuthError(err error) error { return err } + +func invalidParam(err error) error { + return errdefs.InvalidParameter(err) +} + +func invalidParamf(format string, args ...interface{}) error { + return errdefs.InvalidParameter(errors.Errorf(format, args...)) +} + +func invalidParamWrapf(err error, format string, args ...interface{}) error { + return errdefs.InvalidParameter(errors.Wrapf(err, format, args...)) +} diff --git a/vendor/github.com/docker/docker/registry/registry.go b/vendor/github.com/docker/docker/registry/registry.go index 7a70bf28b51..5ff39ce5e7a 100644 --- a/vendor/github.com/docker/docker/registry/registry.go +++ b/vendor/github.com/docker/docker/registry/registry.go @@ -3,9 +3,6 @@ package registry // import "github.com/docker/docker/registry" import ( "crypto/tls" - "errors" - "fmt" - "io/ioutil" "net" "net/http" "os" @@ -18,21 +15,12 @@ import ( "github.com/sirupsen/logrus" ) -var ( - // ErrAlreadyExists is an error returned if an image being pushed - // already exists on the remote side - ErrAlreadyExists = errors.New("Image already exists") -) - -// HostCertsDir returns the config directory for a specific host -func HostCertsDir(hostname string) (string, error) { - certsDir := CertsDir() - - hostDir := filepath.Join(certsDir, cleanPath(hostname)) - - return hostDir, nil +// HostCertsDir returns the config directory for a specific host. +func HostCertsDir(hostname string) string { + return filepath.Join(CertsDir(), cleanPath(hostname)) } +// newTLSConfig constructs a client TLS configuration based on server defaults func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { // PreferredServerCipherSuites should have no effect tlsConfig := tlsconfig.ServerDefault() @@ -40,11 +28,7 @@ func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { tlsConfig.InsecureSkipVerify = !isSecure if isSecure && CertsDir() != "" { - hostDir, err := HostCertsDir(hostname) - if err != nil { - return nil, err - } - + hostDir := HostCertsDir(hostname) logrus.Debugf("hostDir: %s", hostDir) if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil { return nil, err @@ -54,7 +38,7 @@ func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { return tlsConfig, nil } -func hasFile(files []os.FileInfo, name string) bool { +func hasFile(files []os.DirEntry, name string) bool { for _, f := range files { if f.Name() == name { return true @@ -67,9 +51,9 @@ func hasFile(files []os.FileInfo, name string) bool { // including roots and certificate pairs and updates the // provided TLS configuration. func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { - fs, err := ioutil.ReadDir(directory) + fs, err := os.ReadDir(directory) if err != nil && !os.IsNotExist(err) { - return err + return invalidParam(err) } for _, f := range fs { @@ -77,12 +61,12 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { if tlsConfig.RootCAs == nil { systemPool, err := tlsconfig.SystemCertPool() if err != nil { - return fmt.Errorf("unable to get system cert pool: %v", err) + return invalidParamWrapf(err, "unable to get system cert pool") } tlsConfig.RootCAs = systemPool } logrus.Debugf("crt: %s", filepath.Join(directory, f.Name())) - data, err := ioutil.ReadFile(filepath.Join(directory, f.Name())) + data, err := os.ReadFile(filepath.Join(directory, f.Name())) if err != nil { return err } @@ -93,7 +77,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { keyName := certName[:len(certName)-5] + ".key" logrus.Debugf("cert: %s", filepath.Join(directory, f.Name())) if !hasFile(fs, keyName) { - return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName) + return invalidParamf("missing key %s for client certificate %s. CA certificates must use the extension .crt", keyName, certName) } cert, err := tls.LoadX509KeyPair(filepath.Join(directory, certName), filepath.Join(directory, keyName)) if err != nil { @@ -106,7 +90,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { certName := keyName[:len(keyName)-4] + ".cert" logrus.Debugf("key: %s", filepath.Join(directory, f.Name())) if !hasFile(fs, certName) { - return fmt.Errorf("Missing client certificate %s for key %s", certName, keyName) + return invalidParamf("missing client certificate %s for key %s", certName, keyName) } } } @@ -128,9 +112,9 @@ func Headers(userAgent string, metaHeaders http.Header) []transport.RequestModif return modifiers } -// HTTPClient returns an HTTP client structure which uses the given transport +// httpClient returns an HTTP client structure which uses the given transport // and contains the necessary headers for redirected requests -func HTTPClient(transport http.RoundTripper) *http.Client { +func httpClient(transport http.RoundTripper) *http.Client { return &http.Client{ Transport: transport, CheckRedirect: addRequiredHeadersToRedirectedRequests, @@ -173,9 +157,9 @@ func addRequiredHeadersToRedirectedRequests(req *http.Request, via []*http.Reque return nil } -// NewTransport returns a new HTTP transport. If tlsConfig is nil, it uses the +// newTransport returns a new HTTP transport. If tlsConfig is nil, it uses the // default TLS configuration. -func NewTransport(tlsConfig *tls.Config) *http.Transport { +func newTransport(tlsConfig *tls.Config) *http.Transport { if tlsConfig == nil { tlsConfig = tlsconfig.ServerDefault() } @@ -183,10 +167,9 @@ func NewTransport(tlsConfig *tls.Config) *http.Transport { direct := &net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, - DualStack: true, } - base := &http.Transport{ + return &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: direct.DialContext, TLSHandshakeTimeout: 10 * time.Second, @@ -194,6 +177,4 @@ func NewTransport(tlsConfig *tls.Config) *http.Transport { // TODO(dmcgowan): Call close idle connections when complete and use keep alive DisableKeepAlives: true, } - - return base } diff --git a/vendor/github.com/docker/docker/registry/search.go b/vendor/github.com/docker/docker/registry/search.go new file mode 100644 index 00000000000..60b86ea2280 --- /dev/null +++ b/vendor/github.com/docker/docker/registry/search.go @@ -0,0 +1,139 @@ +package registry // import "github.com/docker/docker/registry" + +import ( + "context" + "net/http" + "strconv" + "strings" + + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/errdefs" + + "github.com/docker/distribution/registry/client/auth" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +var acceptedSearchFilterTags = map[string]bool{ + "is-automated": true, + "is-official": true, + "stars": true, +} + +// Search queries the public registry for repositories matching the specified +// search term and filters. +func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) ([]registry.SearchResult, error) { + if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil { + return nil, err + } + + isAutomated, err := searchFilters.GetBoolOrDefault("is-automated", false) + if err != nil { + return nil, err + } + isOfficial, err := searchFilters.GetBoolOrDefault("is-official", false) + if err != nil { + return nil, err + } + + hasStarFilter := 0 + if searchFilters.Contains("stars") { + hasStars := searchFilters.Get("stars") + for _, hasStar := range hasStars { + iHasStar, err := strconv.Atoi(hasStar) + if err != nil { + return nil, errdefs.InvalidParameter(errors.Wrapf(err, "invalid filter 'stars=%s'", hasStar)) + } + if iHasStar > hasStarFilter { + hasStarFilter = iHasStar + } + } + } + + unfilteredResult, err := s.searchUnfiltered(ctx, term, limit, authConfig, headers) + if err != nil { + return nil, err + } + + filteredResults := []registry.SearchResult{} + for _, result := range unfilteredResult.Results { + if searchFilters.Contains("is-automated") { + if isAutomated != result.IsAutomated { + continue + } + } + if searchFilters.Contains("is-official") { + if isOfficial != result.IsOfficial { + continue + } + } + if searchFilters.Contains("stars") { + if result.StarCount < hasStarFilter { + continue + } + } + filteredResults = append(filteredResults, result) + } + + return filteredResults, nil +} + +func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, headers http.Header) (*registry.SearchResults, error) { + // TODO Use ctx when searching for repositories + if hasScheme(term) { + return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term) + } + + indexName, remoteName := splitReposSearchTerm(term) + + // Search is a long-running operation, just lock s.config to avoid block others. + s.mu.RLock() + index, err := newIndexInfo(s.config, indexName) + s.mu.RUnlock() + + if err != nil { + return nil, err + } + if index.Official { + // If pull "library/foo", it's stored locally under "foo" + remoteName = strings.TrimPrefix(remoteName, "library/") + } + + endpoint, err := newV1Endpoint(index, headers) + if err != nil { + return nil, err + } + + var client *http.Client + if authConfig != nil && authConfig.IdentityToken != "" && authConfig.Username != "" { + creds := NewStaticCredentialStore(authConfig) + scopes := []auth.Scope{ + auth.RegistryScope{ + Name: "catalog", + Actions: []string{"search"}, + }, + } + + // TODO(thaJeztah); is there a reason not to include other headers here? (originally added in 19d48f0b8ba59eea9f2cac4ad1c7977712a6b7ac) + modifiers := Headers(headers.Get("User-Agent"), nil) + v2Client, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes) + if err != nil { + return nil, err + } + // Copy non transport http client features + v2Client.Timeout = endpoint.client.Timeout + v2Client.CheckRedirect = endpoint.client.CheckRedirect + v2Client.Jar = endpoint.client.Jar + + logrus.Debugf("using v2 client for search to %s", endpoint.URL) + client = v2Client + } else { + client = endpoint.client + if err := authorizeClient(client, authConfig, endpoint); err != nil { + return nil, err + } + } + + return newSession(client, endpoint).searchRepositories(remoteName, limit) +} diff --git a/vendor/github.com/docker/docker/registry/service.go b/vendor/github.com/docker/docker/registry/service.go index 3b08e39da2c..b848065b3c7 100644 --- a/vendor/github.com/docker/docker/registry/service.go +++ b/vendor/github.com/docker/docker/registry/service.go @@ -3,110 +3,66 @@ package registry // import "github.com/docker/docker/registry" import ( "context" "crypto/tls" - "net/http" "net/url" "strings" "sync" "github.com/docker/distribution/reference" - "github.com/docker/distribution/registry/client/auth" - "github.com/docker/docker/api/types" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -const ( - // DefaultSearchLimit is the default value for maximum number of returned search results. - DefaultSearchLimit = 25 -) - -// Service is the interface defining what a registry service should implement. -type Service interface { - Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) - LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) - LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) - ResolveRepository(name reference.Named) (*RepositoryInfo, error) - Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) - ServiceConfig() *registrytypes.ServiceConfig - TLSConfig(hostname string) (*tls.Config, error) - LoadAllowNondistributableArtifacts([]string) error - LoadMirrors([]string) error - LoadInsecureRegistries([]string) error -} - -// DefaultService is a registry service. It tracks configuration data such as a list +// Service is a registry service. It tracks configuration data such as a list // of mirrors. -type DefaultService struct { +type Service struct { config *serviceConfig - mu sync.Mutex + mu sync.RWMutex } -// NewService returns a new instance of DefaultService ready to be +// NewService returns a new instance of defaultService ready to be // installed into an engine. -func NewService(options ServiceOptions) (*DefaultService, error) { +func NewService(options ServiceOptions) (*Service, error) { config, err := newServiceConfig(options) - return &DefaultService{config: config}, err + return &Service{config: config}, err } -// ServiceConfig returns the public registry service configuration. -func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig { - s.mu.Lock() - defer s.mu.Unlock() - - servConfig := registrytypes.ServiceConfig{ - AllowNondistributableArtifactsCIDRs: make([]*(registrytypes.NetIPNet), 0), - AllowNondistributableArtifactsHostnames: make([]string, 0), - InsecureRegistryCIDRs: make([]*(registrytypes.NetIPNet), 0), - IndexConfigs: make(map[string]*(registrytypes.IndexInfo)), - Mirrors: make([]string, 0), - } - - // construct a new ServiceConfig which will not retrieve s.Config directly, - // and look up items in s.config with mu locked - servConfig.AllowNondistributableArtifactsCIDRs = append(servConfig.AllowNondistributableArtifactsCIDRs, s.config.ServiceConfig.AllowNondistributableArtifactsCIDRs...) - servConfig.AllowNondistributableArtifactsHostnames = append(servConfig.AllowNondistributableArtifactsHostnames, s.config.ServiceConfig.AllowNondistributableArtifactsHostnames...) - servConfig.InsecureRegistryCIDRs = append(servConfig.InsecureRegistryCIDRs, s.config.ServiceConfig.InsecureRegistryCIDRs...) - - for key, value := range s.config.ServiceConfig.IndexConfigs { - servConfig.IndexConfigs[key] = value - } - - servConfig.Mirrors = append(servConfig.Mirrors, s.config.ServiceConfig.Mirrors...) - - return &servConfig +// ServiceConfig returns a copy of the public registry service's configuration. +func (s *Service) ServiceConfig() *registry.ServiceConfig { + s.mu.RLock() + defer s.mu.RUnlock() + return s.config.copy() } // LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries for Service. -func (s *DefaultService) LoadAllowNondistributableArtifacts(registries []string) error { +func (s *Service) LoadAllowNondistributableArtifacts(registries []string) error { s.mu.Lock() defer s.mu.Unlock() - return s.config.LoadAllowNondistributableArtifacts(registries) + return s.config.loadAllowNondistributableArtifacts(registries) } // LoadMirrors loads registry mirrors for Service -func (s *DefaultService) LoadMirrors(mirrors []string) error { +func (s *Service) LoadMirrors(mirrors []string) error { s.mu.Lock() defer s.mu.Unlock() - return s.config.LoadMirrors(mirrors) + return s.config.loadMirrors(mirrors) } // LoadInsecureRegistries loads insecure registries for Service -func (s *DefaultService) LoadInsecureRegistries(registries []string) error { +func (s *Service) LoadInsecureRegistries(registries []string) error { s.mu.Lock() defer s.mu.Unlock() - return s.config.LoadInsecureRegistries(registries) + return s.config.loadInsecureRegistries(registries) } // Auth contacts the public registry with the provided credentials, // and returns OK if authentication was successful. // It can be used to verify the validity of a client's credentials. -func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) { +func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (status, token string, err error) { // TODO Use ctx when searching for repositories var registryHostName = IndexHostname @@ -117,7 +73,7 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, } u, err := url.Parse(serverAddress) if err != nil { - return "", "", errdefs.InvalidParameter(errors.Errorf("unable to parse server address: %v", err)) + return "", "", invalidParamWrapf(err, "unable to parse server address") } registryHostName = u.Host } @@ -127,7 +83,7 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, // to a mirror. endpoints, err := s.LookupPushEndpoints(registryHostName) if err != nil { - return "", "", errdefs.InvalidParameter(err) + return "", "", invalidParam(err) } for _, endpoint := range endpoints { @@ -135,12 +91,11 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, if err == nil { return } - if fErr, ok := err.(fallbackError); ok { - logrus.WithError(fErr.err).Infof("Error logging in to endpoint, trying next endpoint") - continue + if errdefs.IsUnauthorized(err) { + // Failed to authenticate; don't continue with (non-TLS) endpoints. + return status, token, err } - - return "", "", err + logrus.WithError(err).Infof("Error logging in to endpoint, trying next endpoint") } return "", "", err @@ -158,81 +113,11 @@ func splitReposSearchTerm(reposName string) (string, string) { return nameParts[0], nameParts[1] } -// Search queries the public registry for images matching the specified -// search terms, and returns the results. -func (s *DefaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) { - // TODO Use ctx when searching for repositories - if err := validateNoScheme(term); err != nil { - return nil, err - } - - indexName, remoteName := splitReposSearchTerm(term) - - // Search is a long-running operation, just lock s.config to avoid block others. - s.mu.Lock() - index, err := newIndexInfo(s.config, indexName) - s.mu.Unlock() - - if err != nil { - return nil, err - } - - // *TODO: Search multiple indexes. - endpoint, err := NewV1Endpoint(index, userAgent, headers) - if err != nil { - return nil, err - } - - var client *http.Client - if authConfig != nil && authConfig.IdentityToken != "" && authConfig.Username != "" { - creds := NewStaticCredentialStore(authConfig) - scopes := []auth.Scope{ - auth.RegistryScope{ - Name: "catalog", - Actions: []string{"search"}, - }, - } - - modifiers := Headers(userAgent, nil) - v2Client, foundV2, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes) - if err != nil { - if fErr, ok := err.(fallbackError); ok { - logrus.Errorf("Cannot use identity token for search, v2 auth not supported: %v", fErr.err) - } else { - return nil, err - } - } else if foundV2 { - // Copy non transport http client features - v2Client.Timeout = endpoint.client.Timeout - v2Client.CheckRedirect = endpoint.client.CheckRedirect - v2Client.Jar = endpoint.client.Jar - - logrus.Debugf("using v2 client for search to %s", endpoint.URL) - client = v2Client - } - } - - if client == nil { - client = endpoint.client - if err := authorizeClient(client, authConfig, endpoint); err != nil { - return nil, err - } - } - - r := newSession(client, authConfig, endpoint) - - if index.Official { - // If pull "library/foo", it's stored locally under "foo" - remoteName = strings.TrimPrefix(remoteName, "library/") - } - return r.SearchRepositories(remoteName, limit) -} - // ResolveRepository splits a repository name into its components // and configuration of the associated registry. -func (s *DefaultService) ResolveRepository(name reference.Named) (*RepositoryInfo, error) { - s.mu.Lock() - defer s.mu.Unlock() +func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) { + s.mu.RLock() + defer s.mu.RUnlock() return newRepositoryInfo(s.config, name) } @@ -247,43 +132,20 @@ type APIEndpoint struct { TLSConfig *tls.Config } -// ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint -// Deprecated: this function is deprecated and will be removed in a future update -func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) *V1Endpoint { - return newV1Endpoint(*e.URL, e.TLSConfig, userAgent, metaHeaders) -} - -// TLSConfig constructs a client TLS configuration based on server defaults -func (s *DefaultService) TLSConfig(hostname string) (*tls.Config, error) { - s.mu.Lock() - defer s.mu.Unlock() - - return newTLSConfig(hostname, isSecureIndex(s.config, hostname)) -} - -// tlsConfig constructs a client TLS configuration based on server defaults -func (s *DefaultService) tlsConfig(hostname string) (*tls.Config, error) { - return newTLSConfig(hostname, isSecureIndex(s.config, hostname)) -} - -func (s *DefaultService) tlsConfigForMirror(mirrorURL *url.URL) (*tls.Config, error) { - return s.tlsConfig(mirrorURL.Host) -} - // LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference. // It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP. -func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { - s.mu.Lock() - defer s.mu.Unlock() +func (s *Service) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { + s.mu.RLock() + defer s.mu.RUnlock() return s.lookupV2Endpoints(hostname) } // LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference. // It gives preference to HTTPS over plain HTTP. Mirrors are not included. -func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { - s.mu.Lock() - defer s.mu.Unlock() +func (s *Service) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { + s.mu.RLock() + defer s.mu.RUnlock() allEndpoints, err := s.lookupV2Endpoints(hostname) if err == nil { @@ -295,3 +157,11 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn } return endpoints, err } + +// IsInsecureRegistry returns true if the registry at given host is configured as +// insecure registry. +func (s *Service) IsInsecureRegistry(host string) bool { + s.mu.RLock() + defer s.mu.RUnlock() + return !s.config.isSecureIndex(host) +} diff --git a/vendor/github.com/docker/docker/registry/service_v2.go b/vendor/github.com/docker/docker/registry/service_v2.go index 154ac7c93e8..c8c545d21fd 100644 --- a/vendor/github.com/docker/docker/registry/service_v2.go +++ b/vendor/github.com/docker/docker/registry/service_v2.go @@ -7,10 +7,8 @@ import ( "github.com/docker/go-connections/tlsconfig" ) -func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { - tlsConfig := tlsconfig.ServerDefault() - - ana := allowNondistributableArtifacts(s.config, hostname) +func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { + ana := s.config.allowNondistributableArtifacts(hostname) if hostname == DefaultNamespace || hostname == IndexHostname { for _, mirror := range s.config.Mirrors { @@ -19,9 +17,9 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp } mirrorURL, err := url.Parse(mirror) if err != nil { - return nil, err + return nil, invalidParam(err) } - mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL) + mirrorTLSConfig, err := newTLSConfig(mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host)) if err != nil { return nil, err } @@ -38,7 +36,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp Version: APIVersion2, Official: true, TrimHostname: true, - TLSConfig: tlsConfig, + TLSConfig: tlsconfig.ServerDefault(), AllowNondistributableArtifacts: ana, }) @@ -46,7 +44,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp return endpoints, nil } - tlsConfig, err = s.tlsConfig(hostname) + tlsConfig, err := newTLSConfig(hostname, s.config.isSecureIndex(hostname)) if err != nil { return nil, err } diff --git a/vendor/github.com/docker/docker/registry/session.go b/vendor/github.com/docker/docker/registry/session.go index d34dc1e58ab..86a5cd9edff 100644 --- a/vendor/github.com/docker/docker/registry/session.go +++ b/vendor/github.com/docker/docker/registry/session.go @@ -11,28 +11,23 @@ import ( "strings" "sync" - "github.com/docker/docker/api/types" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/jsonmessage" - "github.com/docker/docker/pkg/stringid" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -// A Session is used to communicate with a V1 registry -type Session struct { - indexEndpoint *V1Endpoint +// A session is used to communicate with a V1 registry +type session struct { + indexEndpoint *v1Endpoint client *http.Client - // TODO(tiborvass): remove authConfig - authConfig *types.AuthConfig - id string } type authTransport struct { http.RoundTripper - *types.AuthConfig + *registry.AuthConfig alwaysSetBasicAuth bool token []string @@ -41,7 +36,7 @@ type authTransport struct { modReq map[*http.Request]*http.Request // original -> modified } -// AuthTransport handles the auth layer when communicating with a v1 registry (private or official) +// newAuthTransport handles the auth layer when communicating with a v1 registry (private or official) // // For private v1 registries, set alwaysSetBasicAuth to true. // @@ -54,7 +49,7 @@ type authTransport struct { // If the server sends a token without the client having requested it, it is ignored. // // This RoundTripper also has a CancelRequest method important for correct timeout handling. -func AuthTransport(base http.RoundTripper, authConfig *types.AuthConfig, alwaysSetBasicAuth bool) http.RoundTripper { +func newAuthTransport(base http.RoundTripper, authConfig *registry.AuthConfig, alwaysSetBasicAuth bool) *authTransport { if base == nil { base = http.DefaultTransport } @@ -149,13 +144,13 @@ func (tr *authTransport) CancelRequest(req *http.Request) { } } -func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) error { +func authorizeClient(client *http.Client, authConfig *registry.AuthConfig, endpoint *v1Endpoint) error { var alwaysSetBasicAuth bool // If we're working with a standalone private registry over HTTPS, send Basic Auth headers // alongside all our requests. if endpoint.String() != IndexServer && endpoint.URL.Scheme == "https" { - info, err := endpoint.Ping() + info, err := endpoint.ping() if err != nil { return err } @@ -167,47 +162,41 @@ func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint // Annotate the transport unconditionally so that v2 can // properly fallback on v1 when an image is not found. - client.Transport = AuthTransport(client.Transport, authConfig, alwaysSetBasicAuth) + client.Transport = newAuthTransport(client.Transport, authConfig, alwaysSetBasicAuth) jar, err := cookiejar.New(nil) if err != nil { - return errors.New("cookiejar.New is not supposed to return an error") + return errdefs.System(errors.New("cookiejar.New is not supposed to return an error")) } client.Jar = jar return nil } -func newSession(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) *Session { - return &Session{ - authConfig: authConfig, +func newSession(client *http.Client, endpoint *v1Endpoint) *session { + return &session{ client: client, indexEndpoint: endpoint, - id: stringid.GenerateRandomID(), } } -// NewSession creates a new session -// TODO(tiborvass): remove authConfig param once registry client v2 is vendored -func NewSession(client *http.Client, authConfig *types.AuthConfig, endpoint *V1Endpoint) (*Session, error) { - if err := authorizeClient(client, authConfig, endpoint); err != nil { - return nil, err - } - - return newSession(client, authConfig, endpoint), nil -} +// defaultSearchLimit is the default value for maximum number of returned search results. +const defaultSearchLimit = 25 -// SearchRepositories performs a search against the remote repository -func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.SearchResults, error) { +// searchRepositories performs a search against the remote repository +func (r *session) searchRepositories(term string, limit int) (*registry.SearchResults, error) { + if limit == 0 { + limit = defaultSearchLimit + } if limit < 1 || limit > 100 { - return nil, errdefs.InvalidParameter(errors.Errorf("Limit %d is outside the range of [1, 100]", limit)) + return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit) } logrus.Debugf("Index server: %s", r.indexEndpoint) u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit)) req, err := http.NewRequest(http.MethodGet, u, nil) if err != nil { - return nil, errors.Wrap(errdefs.InvalidParameter(err), "Error building request") + return nil, invalidParamWrapf(err, "error building request") } // Have the AuthTransport send authentication, when logged in. req.Header.Set("X-Docker-Token", "true") @@ -217,11 +206,11 @@ func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.Sea } defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, &jsonmessage.JSONError{ + return nil, errdefs.Unknown(&jsonmessage.JSONError{ Message: fmt.Sprintf("Unexpected status code %d", res.StatusCode), Code: res.StatusCode, - } + }) } - result := new(registrytypes.SearchResults) + result := new(registry.SearchResults) return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results") } diff --git a/vendor/github.com/docker/docker/registry/types.go b/vendor/github.com/docker/docker/registry/types.go index 28ed2bfa5e8..37094737f22 100644 --- a/vendor/github.com/docker/docker/registry/types.go +++ b/vendor/github.com/docker/docker/registry/types.go @@ -2,39 +2,9 @@ package registry // import "github.com/docker/docker/registry" import ( "github.com/docker/distribution/reference" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" ) -// RepositoryData tracks the image list, list of endpoints for a repository -type RepositoryData struct { - // ImgList is a list of images in the repository - ImgList map[string]*ImgData - // Endpoints is a list of endpoints returned in X-Docker-Endpoints - Endpoints []string -} - -// ImgData is used to transfer image checksums to and from the registry -type ImgData struct { - // ID is an opaque string that identifies the image - ID string `json:"id"` - Checksum string `json:"checksum,omitempty"` - ChecksumPayload string `json:"-"` - Tag string `json:",omitempty"` -} - -// PingResult contains the information returned when pinging a registry. It -// indicates the registry's version and whether the registry claims to be a -// standalone registry. -type PingResult struct { - // Version is the registry version supplied by the registry in an HTTP - // header - Version string `json:"version"` - // Standalone is set to true if the registry indicates it is a - // standalone registry in the X-Docker-Registry-Standalone - // header - Standalone bool `json:"standalone"` -} - // APIVersion is an integral representation of an API version (presently // either 1 or 2) type APIVersion int @@ -45,9 +15,8 @@ func (av APIVersion) String() string { // API Version identifiers. const ( - _ = iota - APIVersion1 APIVersion = iota - APIVersion2 + APIVersion1 APIVersion = 1 + APIVersion2 APIVersion = 2 ) var apiVersions = map[APIVersion]string{ @@ -59,7 +28,7 @@ var apiVersions = map[APIVersion]string{ type RepositoryInfo struct { Name reference.Named // Index points to registry information - Index *registrytypes.IndexInfo + Index *registry.IndexInfo // Official indicates whether the repository is considered official. // If the registry is official, and the normalized name does not // contain a '/' (e.g. "foo"), then it is considered an official repo. diff --git a/vendor/github.com/docker/docker/rootless/rootless.go b/vendor/github.com/docker/docker/rootless/rootless.go deleted file mode 100644 index 376d5263de9..00000000000 --- a/vendor/github.com/docker/docker/rootless/rootless.go +++ /dev/null @@ -1,25 +0,0 @@ -package rootless // import "github.com/docker/docker/rootless" - -import ( - "os" - "sync" -) - -const ( - // RootlessKitDockerProxyBinary is the binary name of rootlesskit-docker-proxy - RootlessKitDockerProxyBinary = "rootlesskit-docker-proxy" -) - -var ( - runningWithRootlessKit bool - runningWithRootlessKitOnce sync.Once -) - -// RunningWithRootlessKit returns true if running under RootlessKit namespaces. -func RunningWithRootlessKit() bool { - runningWithRootlessKitOnce.Do(func() { - u := os.Getenv("ROOTLESSKIT_STATE_DIR") - runningWithRootlessKit = u != "" - }) - return runningWithRootlessKit -} diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go index 85f6ab07155..c245a89513f 100644 --- a/vendor/github.com/docker/go-units/size.go +++ b/vendor/github.com/docker/go-units/size.go @@ -2,7 +2,6 @@ package units import ( "fmt" - "regexp" "strconv" "strings" ) @@ -26,16 +25,17 @@ const ( PiB = 1024 * TiB ) -type unitMap map[string]int64 +type unitMap map[byte]int64 var ( - decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} - binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} - sizeRegex = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`) + decimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB} + binaryMap = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB} ) -var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} -var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +var ( + decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +) func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) { i := 0 @@ -89,20 +89,66 @@ func RAMInBytes(size string) (int64, error) { // Parses the human-readable size string into the amount it represents. func parseSize(sizeStr string, uMap unitMap) (int64, error) { - matches := sizeRegex.FindStringSubmatch(sizeStr) - if len(matches) != 4 { + // TODO: rewrite to use strings.Cut if there's a space + // once Go < 1.18 is deprecated. + sep := strings.LastIndexAny(sizeStr, "01234567890. ") + if sep == -1 { + // There should be at least a digit. return -1, fmt.Errorf("invalid size: '%s'", sizeStr) } + var num, sfx string + if sizeStr[sep] != ' ' { + num = sizeStr[:sep+1] + sfx = sizeStr[sep+1:] + } else { + // Omit the space separator. + num = sizeStr[:sep] + sfx = sizeStr[sep+1:] + } - size, err := strconv.ParseFloat(matches[1], 64) + size, err := strconv.ParseFloat(num, 64) if err != nil { return -1, err } + // Backward compatibility: reject negative sizes. + if size < 0 { + return -1, fmt.Errorf("invalid size: '%s'", sizeStr) + } + + if len(sfx) == 0 { + return int64(size), nil + } - unitPrefix := strings.ToLower(matches[3]) - if mul, ok := uMap[unitPrefix]; ok { + // Process the suffix. + + if len(sfx) > 3 { // Too long. + goto badSuffix + } + sfx = strings.ToLower(sfx) + // Trivial case: b suffix. + if sfx[0] == 'b' { + if len(sfx) > 1 { // no extra characters allowed after b. + goto badSuffix + } + return int64(size), nil + } + // A suffix from the map. + if mul, ok := uMap[sfx[0]]; ok { size *= float64(mul) + } else { + goto badSuffix + } + + // The suffix may have extra "b" or "ib" (e.g. KiB or MB). + switch { + case len(sfx) == 2 && sfx[1] != 'b': + goto badSuffix + case len(sfx) == 3 && sfx[1:] != "ib": + goto badSuffix } return int64(size), nil + +badSuffix: + return -1, fmt.Errorf("invalid suffix: '%s'", sfx) } diff --git a/vendor/github.com/dominikbraun/graph/.gitignore b/vendor/github.com/dominikbraun/graph/.gitignore new file mode 100644 index 00000000000..ee770a66d6c --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/.gitignore @@ -0,0 +1,17 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +.idea/ diff --git a/vendor/github.com/dominikbraun/graph/.golangci.yml b/vendor/github.com/dominikbraun/graph/.golangci.yml new file mode 100644 index 00000000000..cf3f55159a2 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/.golangci.yml @@ -0,0 +1,25 @@ +run: + timeout: 5m + +linters: + disable-all: true + enable: + - govet + - gofumpt + - errcheck + - gosimple + - ineffassign + - staticcheck + - typecheck + - unused + +linters-settings: + govet: + enable-all: true + disable: + - stdmethods + - fieldalignment + + gofumpt: + extra-rules: false + module-path: github.com/dominikbraun/graph \ No newline at end of file diff --git a/vendor/github.com/dominikbraun/graph/CHANGELOG.md b/vendor/github.com/dominikbraun/graph/CHANGELOG.md new file mode 100644 index 00000000000..94c07c9ea95 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/CHANGELOG.md @@ -0,0 +1,221 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.16.2] - 2023-03-27 + +### Fixed +* Fixed `ShortestPath` for an edge case. + +## [0.16.1] - 2023-03-06 + +### Fixed +* Fixed `TransitiveReduction` not to incorrectly report cycles. + +## [0.16.0] - 2023-03-01 + +**This release contains breaking changes of the public API (see "Changed").** + +### Added +* Added the `Store` interface, introducing support for custom storage implementations. +* Added the `NewWithStore` function for explicitly initializing a graph with a `Store` instance. +* Added the `EdgeData` functional option that can be used with `AddEdge`, introducing support for arbitrary data. +* Added the `Data` field to `EdgeProperties` for retrieving data added using `EdgeData`. + +### Changed +* Changed `Order` to additionally return an error instance (breaking change). +* Changed `Size` to additionally return an error instance (breaking change). + +## [0.15.1] - 2023-01-18 + +### Changed +* Changed `ShortestPath` to return `ErrTargetNotReachable` if the target vertex is not reachable. + +### Fixed +* Fixed `ShortestPath` to return correct results for large unweighted graphs. + +## [0.15.0] - 2022-11-25 + +### Added +* Added the `ErrVertexAlreadyExists` error instance. Use `errors.Is` to check for this instance. +* Added the `ErrEdgeAlreadyExists` error instance. Use `errors.Is` to check for this instance. +* Added the `ErrEdgeCreatesCycle` error instance. Use `errors.Is` to check for this instance. + +### Changed +* Changed `AddVertex` to return `ErrVertexAlreadyExists` if the vertex already exists. +* Changed `VertexWithProperties` to return `ErrVertexNotFound` if the vertex doesn't exist. +* Changed `AddEdge` to return `ErrVertexNotFound` if either vertex doesn't exist. +* Changed `AddEdge` to return `ErrEdgeAlreadyExists` if the edge already exists. +* Changed `AddEdge` to return `ErrEdgeCreatesCycle` if cycle prevention is active and the edge would create a cycle. +* Changed `Edge` to return `ErrEdgeNotFound` if the edge doesn't exist. +* Changed `RemoveEdge` to return the error instances returned by `Edge`. + +## [0.14.0] - 2022-11-01 + +### Added +* Added the `ErrVertexNotFound` error instance. + +### Changed +* Changed `TopologicalSort` to fail at runtime when a cycle is detected. +* Changed `TransitiveReduction` to return the transitive reduction as a new graph and fail at runtime when a cycle is detected. +* Changed `Vertex` to return `ErrVertexNotFound` if the desired vertex couldn't be found. + +## [0.13.0] - 2022-10-15 + +### Added +* Added the `VertexProperties` type for storing vertex-related properties. +* Added the `VertexWithProperties` method for retrieving a vertex and its properties. +* Added the `VertexWeight` functional option that can be used for `AddVertex`. +* Added the `VertexAttribute` functional option that can be used for `AddVertex`. +* Added support for rendering vertices with attributes using `draw.DOT`. + +### Changed +* Changed `AddVertex` to accept functional options. +* Renamed `PermitCycles` to `PreventCycles`. This seems to be the price to pay if English isn't a library author's native language. + +### Fixed +* Fixed the behavior of `ShortestPath` when the target vertex is not reachable from one of the visited vertices. + +## [0.12.0] - 2022-09-19 + +### Added +* Added the `PermitCycles` option to explicitly prevent the creation of cycles. + +### Changed +* Changed the `Acyclic` option to not implicitly impose cycle checks for operations like `AddEdge`. To prevent the creation of cycles, use `PermitCycles`. +* Changed `TopologicalSort` to only work for graphs created with `PermitCycles`. This is temporary. +* Changed `TransitiveReduction` to only work for graphs created with `PermitCycles`. This is temporary. + +## [0.11.0] - 2022-09-15 + +### Added +* Added the `Order` method for retrieving the number of vertices in the graph. +* Added the `Size` method for retrieving the number of edges in the graph. + +### Changed +* Changed the `graph` logo. +* Changed an internal operation of `ShortestPath` from O(n) to O(log(n)) by implementing the priority queue as a binary heap. Note that the actual complexity might still be defined by `ShortestPath` itself. + +### Fixed +* Fixed `draw.DOT` to work correctly with vertices that contain special characters and whitespaces. + +## [0.10.0] - 2022-09-09 + +### Added +* Added the `PredecessorMap` method for obtaining a map with all predecessors of each vertex. +* Added the `RemoveEdge` method for removing the edge between two vertices. +* Added the `Clone` method for retrieving a deep copy of the graph. +* Added the `TopologicalSort` function for obtaining the topological order of the vertices in the graph. +* Added the `TransitiveReduction` function for transforming the graph into its transitive reduction. + +### Changed +* Changed the `visit` function of `DFS` to accept a vertex hash instead of the vertex value (i.e. `K` instead of `T`). +* Changed the `visit` function of `BFS` to accept a vertex hash instead of the vertex value (i.e. `K` instead of `T`). + +### Removed +* Removed the `Predecessors` function. Use `PredecessorMap` instead and look up the respective vertex. + +## [0.9.0] - 2022-08-17 + +### Added +* Added the `Graph.AddVertex` method for adding a vertex. This replaces `Graph.Vertex`. +* Added the `Graph.AddEdge` method for creating an edge. This replaces `Graph.Edge`. +* Added the `Graph.Vertex` method for retrieving a vertex by its hash. This is not to be confused with the old `Graph.Vertex` function for adding vertices that got replaced with `Graph.AddVertex`. +* Added the `Graph.Edge` method for retrieving an edge. This is not to be confused with the old `Graph.Edge` function for creating an edge that got replaced with `Graph.AddEdge`. +* Added the `Graph.Predecessors` function for retrieving a vertex' predecessors. +* Added the `DFS` function. +* Added the `BFS` function. +* Added the `CreatesCycle` function. +* Added the `StronglyConnectedComponents` function. +* Added the `ShortestPath` function. +* Added the `ErrEdgeNotFound` error indicating that a desired edge could not be found. + +### Removed +* Removed the `Graph.EdgeByHashes` method. Use `Graph.AddEdge` instead. +* Removed the `Graph.GetEdgeByHashes` method. Use `Graph.Edge` instead. +* Removed the `Graph.DegreeByHash` method. Use `Graph.Degree` instead. +* Removed the `Graph.Degree` method. +* Removed the `Graph.DFS` and `Graph.DFSByHash` methods. Use `DFS` instead. +* Removed the `Graph.BFS` and `Graph.BFSByHash` methods. Use `BFS` instead. +* Removed the `Graph.CreatesCycle` and `Graph.CreatesCycleByHashes` methods. Use `CreatesCycle` instead. +* Removed the `Graph.StronglyConnectedComponents` method. Use `StronglyConnectedComponents` instead. +* Removed the `Graph.ShortestPath` and `Graph.ShortestPathByHash` methods. Use `ShortestPath` instead. + +## [0.8.0] - 2022-08-01 + +### Added +* Added the `EdgeWeight` and `EdgeAttribute` functional options. +* Added the `Properties` field to `Edge`. + +### Changed +* Changed `Edge` to accept a variadic `options` parameter. +* Changed `EdgeByHashes` to accept a variadic `options` parameter. +* Renamed `draw.Graph` to `draw.DOT` for more clarity regarding the rendering format. + +### Removed +* Removed the `WeightedEdge` function. Use `Edge` with the `EdgeWeight` functional option instead. +* Removed the `WeightedEdgeByHashes` function. Use `EdgeByHashes` with the `EdgeWeight` functional option instead. + +### Fixed +* Fixed missing edge attributes when drawing a graph using `draw.DOT`. + +## [0.7.0] - 2022-07-26 + +### Added +* Added `draw` package for graph visualization using DOT-compatible renderers. +* Added `Traits` function for retrieving the graph's traits. + +## [0.6.0] - 2022-07-22 + +### Added +* Added `AdjacencyMap` function for retrieving an adjancency map for all vertices. + +### Removed +* Removed the `AdjacencyList` function. + +## [0.5.0] - 2022-07-21 + +### Added +* Added `AdjacencyList` function for retrieving an adjacency list for all vertices. + +### Changed +* Updated the examples in the documentation. + +## [0.4.0] - 2022-07-01 + +### Added +* Added `ShortestPath` function for computing shortest paths. + +### Changed +* Changed the term "properties" to "traits" in the code and documentation. +* Don't traverse all vertices in disconnected graphs by design. + +## [0.3.0] - 2022-06-27 + +### Added +* Added `StronglyConnectedComponents` function for detecting SCCs. +* Added various images to usage examples. + +## [0.2.0] - 2022-06-20 + +### Added +* Added `Degree` and `DegreeByHash` functions for determining vertex degrees. +* Added cycle checks when adding an edge using the `Edge` functions. + +## [0.1.0] - 2022-06-19 + +### Added +* Added `CreatesCycle` and `CreatesCycleByHashes` functions for predicting cycles. + +## [0.1.0-beta] - 2022-06-17 + +### Changed +* Introduced dedicated types for directed and undirected graphs, making `Graph[K, T]` an interface. + +## [0.1.0-alpha] - 2022-06-13 + +### Added +* Introduced core types and methods. diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/LICENSE b/vendor/github.com/dominikbraun/graph/LICENSE similarity index 100% rename from vendor/go.opentelemetry.io/otel/exporters/otlp/LICENSE rename to vendor/github.com/dominikbraun/graph/LICENSE diff --git a/vendor/github.com/dominikbraun/graph/README.md b/vendor/github.com/dominikbraun/graph/README.md new file mode 100644 index 00000000000..e736935f665 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/README.md @@ -0,0 +1,413 @@ +# ![dominikbraun/graph](img/logo.svg) + +A library for creating generic graph data structures and modifying, analyzing, and visualizing them. + +# Features + +* Generic vertices of any type, such as `int` or `City`. +* Graph traits with corresponding validations, such as cycle checks in acyclic graphs. +* Algorithms for finding paths or components, such as shortest paths or strongly connected components. +* Algorithms for transformations and representations, such as transitive reduction or topological order. +* Algorithms for non-recursive graph traversal, such as DFS or BFS. +* Vertices and edges with optional metadata, such as weights or custom attributes. +* Visualization of graphs using the DOT language and Graphviz. +* Integrate any storage backend by using your own `Store` implementation. +* Extensive tests with ~90% coverage, and zero dependencies. + +> Status: Because `graph` is in version 0, the public API shouldn't be considered stable. + +> This README may contain unreleased changes. Check out the [latest documentation](https://pkg.go.dev/github.com/dominikbraun/graph). + +# Getting started + +``` +go get github.com/dominikbraun/graph +``` + +# Quick examples + +## Create a graph of integers + +![graph of integers](img/simple.svg) + +```go +g := graph.New(graph.IntHash) + +_ = g.AddVertex(1) +_ = g.AddVertex(2) +_ = g.AddVertex(3) +_ = g.AddVertex(4) +_ = g.AddVertex(5) + +_ = g.AddEdge(1, 2) +_ = g.AddEdge(1, 4) +_ = g.AddEdge(2, 3) +_ = g.AddEdge(2, 4) +_ = g.AddEdge(2, 5) +_ = g.AddEdge(3, 5) +``` + +## Create a directed acyclic graph of integers + +![directed acyclic graph](img/dag.svg) + +```go +g := graph.New(graph.IntHash, graph.Directed(), graph.Acyclic()) + +_ = g.AddVertex(1) +_ = g.AddVertex(2) +_ = g.AddVertex(3) +_ = g.AddVertex(4) + +_ = g.AddEdge(1, 2) +_ = g.AddEdge(1, 3) +_ = g.AddEdge(2, 3) +_ = g.AddEdge(2, 4) +_ = g.AddEdge(3, 4) +``` + +## Create a graph of a custom type + +To understand this example in detail, see the [concept of hashes](#hashes). + +```go +type City struct { + Name string +} + +cityHash := func(c City) string { + return c.Name +} + +g := graph.New(cityHash) + +_ = g.AddVertex(london) +``` + +## Create a weighted graph + +![weighted graph](img/cities.svg) + +```go +g := graph.New(cityHash, graph.Weighted()) + +_ = g.AddVertex(london) +_ = g.AddVertex(munich) +_ = g.AddVertex(paris) +_ = g.AddVertex(madrid) + +_ = g.AddEdge("london", "munich", graph.EdgeWeight(3)) +_ = g.AddEdge("london", "paris", graph.EdgeWeight(2)) +_ = g.AddEdge("london", "madrid", graph.EdgeWeight(5)) +_ = g.AddEdge("munich", "madrid", graph.EdgeWeight(6)) +_ = g.AddEdge("munich", "paris", graph.EdgeWeight(2)) +_ = g.AddEdge("paris", "madrid", graph.EdgeWeight(4)) +``` + +## Perform a Depth-First Search + +This example traverses and prints all vertices in the graph in DFS order. + +![depth-first search](img/dfs.svg) + +```go +g := graph.New(graph.IntHash, graph.Directed()) + +_ = g.AddVertex(1) +_ = g.AddVertex(2) +_ = g.AddVertex(3) +_ = g.AddVertex(4) + +_ = g.AddEdge(1, 2) +_ = g.AddEdge(1, 3) +_ = g.AddEdge(3, 4) + +_ = graph.DFS(g, 1, func(value int) bool { + fmt.Println(value) + return false +}) +``` + +``` +1 3 4 2 +``` + +## Find strongly connected components + +![strongly connected components](img/scc.svg) + +```go +g := graph.New(graph.IntHash) + +// Add vertices and edges ... + +scc, _ := graph.StronglyConnectedComponents(g) + +fmt.Println(scc) +``` + +``` +[[1 2 5] [3 4 8] [6 7]] +``` + +## Find the shortest path + +![shortest path algorithm](img/dijkstra.svg) + +```go +g := graph.New(graph.StringHash, graph.Weighted()) + +// Add vertices and weighted edges ... + +path, _ := graph.ShortestPath(g, "A", "B") + +fmt.Println(path) +``` + +``` +[A C E B] +``` + +## Perform a topological sort + +![topological sort](img/topological-sort.svg) + +```go +g := graph.New(graph.IntHash, graph.Directed(), graph.PreventCycles()) + +// Add vertices and edges ... + +order, _ := graph.TopologicalSort(g) + +fmt.Println(order) +``` + +``` +[1 2 3 4 5] +``` + +## Perform a transitive reduction + +![transitive reduction](img/transitive-reduction-before.svg) + +```go +g := graph.New(graph.StringHash, graph.Directed(), graph.PreventCycles()) + +// Add vertices and edges ... + +transitiveReduction, _ := graph.TransitiveReduction(g) +``` + +![transitive reduction](img/transitive-reduction-after.svg) + +## Prevent the creation of cycles + +![cycle checks](img/cycles.svg) + +```go +g := graph.New(graph.IntHash, graph.PreventCycles()) + +_ = g.AddVertex(1) +_ = g.AddVertex(2) +_ = g.AddVertex(3) + +_ = g.AddEdge(1, 2) +_ = g.AddEdge(1, 3) + +if err := g.AddEdge(2, 3); err != nil { + panic(err) +} +``` + +``` +panic: an edge between 2 and 3 would introduce a cycle +``` + +## Visualize a graph using Graphviz + +The following example will generate a DOT description for `g` and write it into the given file. + +```go +g := graph.New(graph.IntHash, graph.Directed()) + +_ = g.AddVertex(1) +_ = g.AddVertex(2) +_ = g.AddVertex(3) + +_ = g.AddEdge(1, 2) +_ = g.AddEdge(1, 3) + +file, _ := os.Create("./mygraph.gv") +_ = draw.DOT(g, file) +``` + +To generate an SVG from the created file using Graphviz, use a command such as the following: + +``` +dot -Tsvg -O mygraph.gv +``` + +### Draw a graph as in this documentation + +![simple graph](img/simple.svg) + +This graph has been rendered using the following program: + +```go +package main + +import ( + "os" + + "github.com/dominikbraun/graph" + "github.com/dominikbraun/graph/draw" +) + +func main() { + g := graph.New(graph.IntHash) + + _ = g.AddVertex(1, graph.VertexAttribute("colorscheme", "blues3"), graph.VertexAttribute("style", "filled"), graph.VertexAttribute("color", "2"), graph.VertexAttribute("fillcolor", "1")) + _ = g.AddVertex(2, graph.VertexAttribute("colorscheme", "greens3"), graph.VertexAttribute("style", "filled"), graph.VertexAttribute("color", "2"), graph.VertexAttribute("fillcolor", "1")) + _ = g.AddVertex(3, graph.VertexAttribute("colorscheme", "purples3"), graph.VertexAttribute("style", "filled"), graph.VertexAttribute("color", "2"), graph.VertexAttribute("fillcolor", "1")) + _ = g.AddVertex(4, graph.VertexAttribute("colorscheme", "ylorbr3"), graph.VertexAttribute("style", "filled"), graph.VertexAttribute("color", "2"), graph.VertexAttribute("fillcolor", "1")) + _ = g.AddVertex(5, graph.VertexAttribute("colorscheme", "reds3"), graph.VertexAttribute("style", "filled"), graph.VertexAttribute("color", "2"), graph.VertexAttribute("fillcolor", "1")) + + _ = g.AddEdge(1, 2) + _ = g.AddEdge(1, 4) + _ = g.AddEdge(2, 3) + _ = g.AddEdge(2, 4) + _ = g.AddEdge(2, 5) + _ = g.AddEdge(3, 5) + + file, _ := os.Create("./simple.gv") + _ = draw.DOT(g, file) +} +``` + +It has been rendered using the `neato` engine: + +``` +dot -Tsvg -Kneato -O simple.gv +``` + +The example uses the [Brewer color scheme](https://graphviz.org/doc/info/colors.html#brewer) supported by Graphviz. + +## Storing edge attributes + +Edges may have one or more attributes which can be used to store metadata. Attributes will be taken +into account when [visualizing a graph](#visualize-a-graph-using-graphviz). For example, this edge +will be rendered in red color: + +```go +_ = g.AddEdge(1, 2, graph.EdgeAttribute("color", "red")) +``` + +To get an overview of all supported attributes, take a look at the +[DOT documentation](https://graphviz.org/doc/info/attrs.html). + +The stored attributes can be retrieved by getting the edge and accessing the `Properties.Attributes` +field. + +```go +edge, _ := g.Edge(1, 2) +color := edge.Properties.Attributes["color"] +``` + +## Storing edge data + +It is also possible to store arbitrary data inside edges, not just key-value string pairs. This data +is of type `any`. + +```go +_ = g.AddEdge(1, 2, graph.EdgeData(myData)) +``` + +The stored data can be retrieved by getting the edge and accessing the `Properties.Data` field. + +```go +edge, _ := g.Edge(1, 2) +myData := edge.Properties.Data +``` + +## Storing vertex attributes + +Vertices may have one or more attributes which can be used to store metadata. Attributes will be +taken into account when [visualizing a graph](#visualize-a-graph-using-graphviz). For example, this +vertex will be rendered in red color: + +```go +_ = g.AddVertex(1, graph.VertexAttribute("style", "filled")) +``` + +The stored data can be retrieved by getting the vertex using `VertexWithProperties` and accessing +the `Attributes` field. + +```go +vertex, properties, _ := g.VertexWithProperties(1) +style := properties.Attributes["style"] +``` + +To get an overview of all supported attributes, take a look at the +[DOT documentation](https://graphviz.org/doc/info/attrs.html). + +## Store the graph in a custom storage + +You can integrate any storage backend by implementing the `Store` interface and initializing a new +graph with it: + +```go +g := graph.NewWithStore(graph.IntHash, myStore) +``` + +To implement the `Store` interface appropriately, take a look at the [documentation](https://pkg.go.dev/github.com/dominikbraun/graph#Store). +[`graph-sql`](https://github.com/dominikbraun/graph-sql) is a ready-to-use SQL store implementation. + +# Concepts + +## Hashes + +A graph consists of nodes (or vertices) of type `T`, which are identified by a hash value of type +`K`. The hash value is obtained using the hashing function passed to `graph.New`. + +### Primitive types + +For primitive types such as `string` or `int`, you may use a predefined hashing function such as +`graph.IntHash` – a function that takes an integer and uses it as a hash value at the same time: + +```go +g := graph.New(graph.IntHash) +``` + +> This also means that only one vertex with a value like `5` can exist in the graph if +> `graph.IntHash` used. + +### Custom types + +For storing custom data types, you need to provide your own hashing function. This example function +takes a `City` and returns the city name as an unique hash value: + +```go +cityHash := func(c City) string { + return c.Name +} +``` + +Creating a graph using this hashing function will yield a graph with vertices of type `City` +identified by hash values of type `string`. + +```go +g := graph.New(cityHash) +``` + +## Traits + +The behavior of a graph, for example when adding or retrieving edges, depends on its traits. You +can set the graph's traits using the functional options provided by this library: + +```go +g := graph.New(graph.IntHash, graph.Directed(), graph.Weighted()) +``` + +# Documentation + +The full documentation is available at [pkg.go.dev](https://pkg.go.dev/github.com/dominikbraun/graph). diff --git a/vendor/github.com/dominikbraun/graph/collection.go b/vendor/github.com/dominikbraun/graph/collection.go new file mode 100644 index 00000000000..17f95424b5c --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/collection.go @@ -0,0 +1,107 @@ +package graph + +import ( + "container/heap" + "errors" +) + +// priorityQueue is a priority queue implementation for minimum priorities, meaning that smaller +// values will be prioritized. It maintains a list of priority items in descending order. +// +// This implementation is built on top of heap.Interface with some adjustments to comply with the +// usage of generics. +type priorityQueue[T comparable] struct { + items *minHeap[T] + cache map[T]*priorityItem[T] +} + +// priorityItem is an item in the priority queue, consisting of a priority and an actual value. +type priorityItem[T comparable] struct { + value T + priority float64 + // index is used internally by heap.Interface to re-organize items in the queue. + index int +} + +func newPriorityQueue[T comparable]() *priorityQueue[T] { + return &priorityQueue[T]{ + items: &minHeap[T]{}, + cache: map[T]*priorityItem[T]{}, + } +} + +func (p *priorityQueue[T]) Len() int { + return p.items.Len() +} + +// Push pushes a new item with the given priority into the queue. +func (p *priorityQueue[T]) Push(item T, priority float64) { + if _, ok := p.cache[item]; ok { + return + } + + newItem := &priorityItem[T]{ + value: item, + priority: priority, + index: 0, + } + + heap.Push(p.items, newItem) + p.cache[item] = newItem +} + +// Pop returns the item with the smallest priority from the queue and removes that item. +func (p *priorityQueue[T]) Pop() (T, error) { + if len(*p.items) == 0 { + var empty T + return empty, errors.New("priority queue is empty") + } + + item := heap.Pop(p.items).(*priorityItem[T]) + delete(p.cache, item.value) + + return item.value, nil +} + +// UpdatePriority updates the priority of a given item to the given priority. The item must be +// pushed into the queue first. If the item doesn't exist, nothing happens. +func (p *priorityQueue[T]) UpdatePriority(item T, priority float64) { + targetItem, ok := p.cache[item] + if !ok { + return + } + + targetItem.priority = priority + heap.Fix(p.items, targetItem.index) +} + +// minHeap is a binary min heap that implements heap.Interface. +type minHeap[T comparable] []*priorityItem[T] + +func (m *minHeap[T]) Len() int { + return len(*m) +} + +func (m *minHeap[T]) Less(i, j int) bool { + return (*m)[i].priority < (*m)[j].priority +} + +func (m *minHeap[T]) Swap(i, j int) { + (*m)[i], (*m)[j] = (*m)[j], (*m)[i] + (*m)[i].index = i + (*m)[j].index = j +} + +func (m *minHeap[T]) Push(item interface{}) { + i := item.(*priorityItem[T]) + i.index = len(*m) + *m = append(*m, i) +} + +func (m *minHeap[T]) Pop() interface{} { + old := *m + item := old[len(old)-1] + *m = old[:len(old)-1] + + return item +} diff --git a/vendor/github.com/dominikbraun/graph/dag.go b/vendor/github.com/dominikbraun/graph/dag.go new file mode 100644 index 00000000000..ab6cb52b0ad --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/dag.go @@ -0,0 +1,144 @@ +package graph + +import ( + "errors" + "fmt" +) + +// TopologicalSort performs a topological sort on a given graph and returns the vertex hashes in +// topological order. A topological order is a non-unique order of the vertices in a directed graph +// where an edge from vertex A to vertex B implies that vertex A appears before vertex B. +// +// TopologicalSort only works for directed acyclic graphs. The current implementation works non- +// recursively and uses Kahn's algorithm. +func TopologicalSort[K comparable, T any](g Graph[K, T]) ([]K, error) { + if !g.Traits().IsDirected { + return nil, fmt.Errorf("topological sort cannot be computed on undirected graph") + } + + predecessorMap, err := g.PredecessorMap() + if err != nil { + return nil, fmt.Errorf("failed to get predecessor map: %w", err) + } + + queue := make([]K, 0) + + for vertex, predecessors := range predecessorMap { + if len(predecessors) == 0 { + queue = append(queue, vertex) + } + } + + order := make([]K, 0, len(predecessorMap)) + visited := make(map[K]struct{}) + + for len(queue) > 0 { + currentVertex := queue[0] + queue = queue[1:] + + if _, ok := visited[currentVertex]; ok { + continue + } + + order = append(order, currentVertex) + visited[currentVertex] = struct{}{} + + for vertex, predecessors := range predecessorMap { + delete(predecessors, currentVertex) + + if len(predecessors) == 0 { + queue = append(queue, vertex) + } + } + } + + gOrder, err := g.Order() + if err != nil { + return nil, fmt.Errorf("failed to get graph order: %w", err) + } + + if len(order) != gOrder { + return nil, errors.New("topological sort cannot be computed on graph with cycles") + } + + return order, nil +} + +// TransitiveReduction returns a new graph with the same vertices and the same reachability as the +// given graph, but with as few edges as possible. This significantly reduces its complexity. +// +// With a time complexity of O(V(V+E)), TransitiveReduction is a very costly operation. Note that +func TransitiveReduction[K comparable, T any](g Graph[K, T]) (Graph[K, T], error) { + if !g.Traits().IsDirected { + return nil, fmt.Errorf("transitive reduction cannot be performed on undirected graph") + } + + transitiveReduction, err := g.Clone() + if err != nil { + return nil, fmt.Errorf("failed to clone the graph: %w", err) + } + + adjacencyMap, err := transitiveReduction.AdjacencyMap() + if err != nil { + return nil, fmt.Errorf("failed to get adajcency map: %w", err) + } + + for vertex, successors := range adjacencyMap { + // For each direct successor of the current vertex, run a DFS starting from that successor. + // Then, for each vertex visited in the DFS, inspect all of its edges. Remove the edges that + // also appear in the edges of the top-level iteration vertex. + // + // These edges are redundant because their targets obviously are reachable through the DFS, + // hence they can be removed from the top-level vertex. + tOrder, err := transitiveReduction.Order() + if err != nil { + return nil, fmt.Errorf("failed to get graph order: %w", err) + } + for successor := range successors { + stack := make([]K, 0, tOrder) + visited := make(map[K]struct{}, tOrder) + onStack := make(map[K]bool, tOrder) + + stack = append(stack, successor) + + for len(stack) > 0 { + current := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + // If the vertex has already been visited, remove it from the stack and continue + // with the next vertex. Otherwise, proceed by putting it onto the stack. + if _, ok := visited[current]; ok { + onStack[current] = false + continue + } + + visited[current] = struct{}{} + onStack[current] = true + stack = append(stack, current) + + // Also, if the vertex is a leaf node, remove it from the stack. + if len(adjacencyMap[current]) == 0 { + onStack[current] = false + } + + for adjacency := range adjacencyMap[current] { + if _, ok := visited[adjacency]; ok { + if onStack[adjacency] { + // If the current adjacency is both on the stack and has already been + // visited, there is a cycle and an error is returned. + return nil, fmt.Errorf("transitive reduction cannot be performed on graph with cycle") + } + continue + } + + if _, ok := adjacencyMap[vertex][adjacency]; ok { + _ = transitiveReduction.RemoveEdge(vertex, adjacency) + } + stack = append(stack, adjacency) + } + } + } + } + + return transitiveReduction, nil +} diff --git a/vendor/github.com/dominikbraun/graph/directed.go b/vendor/github.com/dominikbraun/graph/directed.go new file mode 100644 index 00000000000..ce7ad33fc76 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/directed.go @@ -0,0 +1,229 @@ +package graph + +import ( + "errors" + "fmt" +) + +type directed[K comparable, T any] struct { + hash Hash[K, T] + traits *Traits + store Store[K, T] +} + +func newDirected[K comparable, T any](hash Hash[K, T], traits *Traits, store Store[K, T]) *directed[K, T] { + return &directed[K, T]{ + hash: hash, + traits: traits, + store: store, + } +} + +func (d *directed[K, T]) Traits() *Traits { + return d.traits +} + +func (d *directed[K, T]) AddVertex(value T, options ...func(*VertexProperties)) error { + hash := d.hash(value) + properties := VertexProperties{ + Weight: 0, + Attributes: make(map[string]string), + } + + for _, option := range options { + option(&properties) + } + + return d.store.AddVertex(hash, value, properties) +} + +func (d *directed[K, T]) Vertex(hash K) (T, error) { + vertex, _, err := d.store.Vertex(hash) + return vertex, err +} + +func (d *directed[K, T]) VertexWithProperties(hash K) (T, VertexProperties, error) { + vertex, properties, err := d.store.Vertex(hash) + if err != nil { + return vertex, VertexProperties{}, err + } + + return vertex, properties, nil +} + +func (d *directed[K, T]) AddEdge(sourceHash, targetHash K, options ...func(*EdgeProperties)) error { + _, _, err := d.store.Vertex(sourceHash) + if err != nil { + return fmt.Errorf("source vertex %v: %w", sourceHash, err) + } + + _, _, err = d.store.Vertex(targetHash) + if err != nil { + return fmt.Errorf("target vertex %v: %w", targetHash, err) + } + + if _, err := d.Edge(sourceHash, targetHash); !errors.Is(err, ErrEdgeNotFound) { + return ErrEdgeAlreadyExists + } + + // If the user opted in to preventing cycles, run a cycle check. + if d.traits.PreventCycles { + createsCycle, err := CreatesCycle[K, T](d, sourceHash, targetHash) + if err != nil { + return fmt.Errorf("check for cycles: %w", err) + } + if createsCycle { + return ErrEdgeCreatesCycle + } + } + + edge := Edge[K]{ + Source: sourceHash, + Target: targetHash, + Properties: EdgeProperties{ + Attributes: make(map[string]string), + }, + } + + for _, option := range options { + option(&edge.Properties) + } + + return d.addEdge(sourceHash, targetHash, edge) +} + +func (d *directed[K, T]) Edge(sourceHash, targetHash K) (Edge[T], error) { + edge, err := d.store.Edge(sourceHash, targetHash) + if err != nil { + return Edge[T]{}, err + } + + sourceVertex, _, err := d.store.Vertex(sourceHash) + if err != nil { + return Edge[T]{}, err + } + + targetVertex, _, err := d.store.Vertex(targetHash) + if err != nil { + return Edge[T]{}, err + } + + return Edge[T]{ + Source: sourceVertex, + Target: targetVertex, + Properties: EdgeProperties{ + Weight: edge.Properties.Weight, + Attributes: edge.Properties.Attributes, + Data: edge.Properties.Data, + }, + }, nil +} + +func (d *directed[K, T]) RemoveEdge(source, target K) error { + if _, err := d.Edge(source, target); err != nil { + return err + } + + if err := d.store.RemoveEdge(source, target); err != nil { + return fmt.Errorf("failed to remove edge from %v to %v: %w", source, target, err) + } + + return nil +} + +func (d *directed[K, T]) AdjacencyMap() (map[K]map[K]Edge[K], error) { + vertices, err := d.store.ListVertices() + if err != nil { + return nil, fmt.Errorf("failed to list vertices: %w", err) + } + + edges, err := d.store.ListEdges() + if err != nil { + return nil, fmt.Errorf("failed to list edges: %w", err) + } + + m := make(map[K]map[K]Edge[K]) + + for _, vertex := range vertices { + m[vertex] = make(map[K]Edge[K]) + } + + for _, edge := range edges { + m[edge.Source][edge.Target] = edge + } + + return m, nil +} + +func (d *directed[K, T]) PredecessorMap() (map[K]map[K]Edge[K], error) { + m := make(map[K]map[K]Edge[K]) + + vertices, err := d.store.ListVertices() + if err != nil { + return nil, fmt.Errorf("failed to list vertices: %w", err) + } + + edges, err := d.store.ListEdges() + if err != nil { + return nil, fmt.Errorf("failed to list edges: %w", err) + } + + for _, vertex := range vertices { + m[vertex] = make(map[K]Edge[K]) + } + + for _, edge := range edges { + if _, ok := m[edge.Target]; !ok { + m[edge.Target] = make(map[K]Edge[K]) + } + m[edge.Target][edge.Source] = edge + } + + return m, nil +} + +func (d *directed[K, T]) addEdge(sourceHash, targetHash K, edge Edge[K]) error { + return d.store.AddEdge(sourceHash, targetHash, edge) +} + +func (d *directed[K, T]) Clone() (Graph[K, T], error) { + traits := &Traits{ + IsDirected: d.traits.IsDirected, + IsAcyclic: d.traits.IsAcyclic, + IsWeighted: d.traits.IsWeighted, + IsRooted: d.traits.IsRooted, + } + + return &directed[K, T]{ + hash: d.hash, + traits: traits, + store: d.store, + }, nil +} + +func (d *directed[K, T]) Order() (int, error) { + return d.store.VertexCount() +} + +func (d *directed[K, T]) Size() (int, error) { + size := 0 + outEdges, err := d.AdjacencyMap() + if err != nil { + return 0, fmt.Errorf("failed to get adjacency map: %w", err) + } + + for _, outEdges := range outEdges { + size += len(outEdges) + } + + return size, nil +} + +func (d *directed[K, T]) edgesAreEqual(a, b Edge[T]) bool { + aSourceHash := d.hash(a.Source) + aTargetHash := d.hash(a.Target) + bSourceHash := d.hash(b.Source) + bTargetHash := d.hash(b.Target) + + return aSourceHash == bSourceHash && aTargetHash == bTargetHash +} diff --git a/vendor/github.com/dominikbraun/graph/graph.go b/vendor/github.com/dominikbraun/graph/graph.go new file mode 100644 index 00000000000..f4e4daf32ec --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/graph.go @@ -0,0 +1,249 @@ +// Package graph provides types and functions for creating generic graph data structures and +// modifying, analyzing, and visualizing them. +package graph + +import "errors" + +var ( + ErrVertexNotFound = errors.New("vertex not found") + ErrVertexAlreadyExists = errors.New("vertex already exists") + ErrEdgeNotFound = errors.New("edge not found") + ErrEdgeAlreadyExists = errors.New("edge already exists") + ErrEdgeCreatesCycle = errors.New("edge would create a cycle") +) + +// Graph represents a generic graph data structure consisting of vertices and edges. Its vertices +// are of type T, and each vertex is identified by a hash of type K. +type Graph[K comparable, T any] interface { + // Traits returns the graph's traits. Those traits must be set when creating a graph using New. + Traits() *Traits + + // AddVertex creates a new vertex in the graph. If the vertex already exists in the graph, + // ErrVertexAlreadyExists will be returned if no custom Store implementation is used. + // + // AddVertex accepts a variety of functional options to set further edge details such as the + // weight or an attribute: + // + // _ = graph.AddVertex("A", "B", graph.VertexWeight(4), graph.VertexAttribute("label", "my-label")) + // + AddVertex(value T, options ...func(*VertexProperties)) error + + // Vertex returns the vertex with the given hash or ErrVertexNotFound if it doesn't exist. + Vertex(hash K) (T, error) + + // VertexWithProperties returns the vertex with the given hash along with its properties or + // ErrVertexNotFound if it doesn't exist. + VertexWithProperties(hash K) (T, VertexProperties, error) + + // AddEdge creates an edge between the source and the target vertex. If the Directed option has + // been called on the graph, this is a directed edge. If either vertex can't be found, + // ErrVertexNotFound will be returned. If the edge already exists, ErrEdgeAlreadyExists will be + // returned. If cycle prevention has been activated using PreventCycles and adding the edge + // would create a cycle, ErrEdgeCreatesCycle will be returned. + // + // AddEdge accepts a variety of functional options to set further edge details such as the + // weight or an attribute: + // + // _ = graph.AddEdge("A", "B", graph.EdgeWeight(4), graph.EdgeAttribute("label", "my-label")) + // + AddEdge(sourceHash, targetHash K, options ...func(*EdgeProperties)) error + + // Edge returns the edge joining two given vertices or an error if the edge doesn't exist. In an + // undirected graph, an edge with swapped source and target vertices does match. + // + // If the edge doesn't exist, ErrEdgeNotFound will be returned. + Edge(sourceHash, targetHash K) (Edge[T], error) + + // RemoveEdge removes the edge between the given source and target vertices. If the edge doesn't + // exist, ErrEdgeNotFound will be returned if no custom Store implementation is used. + RemoveEdge(source, target K) error + + // AdjacencyMap computes and returns an adjacency map containing all vertices in the graph. + // + // There is an entry for each vertex, and each of those entries is another map whose keys are + // the hash values of the adjacent vertices. The value is an Edge instance that stores the + // source and target hash values (these are the same as the map keys) as well as edge metadata. + // + // For a graph with edges AB and AC, the adjacency map would look as follows: + // + // map[string]map[string]Edge[string]{ + // "A": map[string]Edge[string]{ + // "B": {Source: "A", Target: "B"} + // "C": {Source: "A", Target: "C"} + // } + // } + // + // This design makes AdjacencyMap suitable for a wide variety of scenarios and demands. + AdjacencyMap() (map[K]map[K]Edge[K], error) + + // PredecessorMap computes and returns a predecessors map containing all vertices in the graph. + // + // The map layout is the same as for AdjacencyMap. + // + // For an undirected graph, PredecessorMap is the same as AdjacencyMap. For a directed graph, + // PredecessorMap is the complement of AdjacencyMap. This is because in a directed graph, only + // vertices joined by an outgoing edge are considered adjacent to the current vertex, whereas + // predecessors are the vertices joined by an ingoing edge. + PredecessorMap() (map[K]map[K]Edge[K], error) + + // Clone creates an independent deep copy of the graph and returns that cloned graph. + Clone() (Graph[K, T], error) + + // Order computes and returns the number of vertices in the graph. + Order() (int, error) + + // Size computes and returns the number of edges in the graph. + Size() (int, error) +} + +// Edge represents a graph edge with a source and target vertex as well as a weight, which has the +// same value for all edges in an unweighted graph. Even though the vertices are referred to as +// source and target, whether the graph is directed or not is determined by its traits. +type Edge[T any] struct { + Source T + Target T + Properties EdgeProperties +} + +// EdgeProperties represents a set of properties that each edge possesses. They can be set when +// adding a new edge using the functional options provided by this library: +// +// g.AddEdge("A", "B", graph.EdgeWeight(2), graph.EdgeAttribute("color", "red")) +// +// The example above will create an edge with weight 2 and a "color" attribute with value "red". +type EdgeProperties struct { + Attributes map[string]string + Weight int + Data any +} + +// Hash is a hashing function that takes a vertex of type T and returns a hash value of type K. +// +// Every graph has a hashing function and uses that function to retrieve the hash values of its +// vertices. You can either use one of the predefined hashing functions, or, if you want to store a +// custom data type, provide your own function: +// +// cityHash := func(c City) string { +// return c.Name +// } +// +// The cityHash function returns the city name as a hash value. The types of T and K, in this case +// City and string, also define the types T and K of the graph. +type Hash[K comparable, T any] func(T) K + +// New creates a new graph with vertices of type T, identified by hash values of type K. These hash +// values will be obtained using the provided hash function (see Hash). +// +// For primitive vertex values, you may use the predefined hashing functions. As an example, this +// graph stores integer vertices: +// +// g := graph.New(graph.IntHash) +// _ = g.AddVertex(1) +// _ = g.AddVertex(2) +// _ = g.AddVertex(3) +// +// The provided IntHash hashing function takes an integer and uses it as a hash value at the same +// time. In a more complex scenario with custom objects, you should define your own function: +// +// type City struct { +// Name string +// } +// +// cityHash := func(c City) string { +// return c.Name +// } +// +// g := graph.New(cityHash) +// _ = g.AddVertex(london) +// +// This graph will store vertices of type City, identified by hashes of type string. Both type +// parameters can be inferred from the hashing function. +// +// All traits of the graph can be set using the predefined functional options. They can be combined +// arbitrarily. This example creates a directed acyclic graph: +// +// g := graph.New(graph.IntHash, graph.Directed(), graph.Acyclic()) +// +// Which Graph implementation will be returned depends on these traits. +func New[K comparable, T any](hash Hash[K, T], options ...func(*Traits)) Graph[K, T] { + return NewWithStore(hash, newMemoryStore[K, T](), options...) +} + +// NewWithStore creates a new graph same as New, but uses the provided store instead of the default +// memory store. +func NewWithStore[K comparable, T any](hash Hash[K, T], store Store[K, T], options ...func(*Traits)) Graph[K, T] { + var p Traits + + for _, option := range options { + option(&p) + } + + if p.IsDirected { + return newDirected(hash, &p, store) + } + + return newUndirected(hash, &p, store) +} + +// StringHash is a hashing function that accepts a string and uses that exact string as a hash +// value. Using it as Hash will yield a Graph[string, string]. +func StringHash(v string) string { + return v +} + +// IntHash is a hashing function that accepts an integer and uses that exact integer as a hash +// value. Using it as Hash will yield a Graph[int, int]. +func IntHash(v int) int { + return v +} + +// EdgeWeight returns a function that sets the weight of an edge to the given weight. This is a +// functional option for the Edge and AddEdge methods. +func EdgeWeight(weight int) func(*EdgeProperties) { + return func(e *EdgeProperties) { + e.Weight = weight + } +} + +// EdgeAttribute returns a function that adds the given key-value pair to the attributes of an +// edge. This is a functional option for the Edge and AddEdge methods. +func EdgeAttribute(key, value string) func(*EdgeProperties) { + return func(e *EdgeProperties) { + e.Attributes[key] = value + } +} + +// EdgeData returns a function that sets the data of an edge to the given value. This is a +// functional option for the Edge and AddEdge methods. +func EdgeData(data any) func(*EdgeProperties) { + return func(e *EdgeProperties) { + e.Data = data + } +} + +// VertexProperties represents a set of properties that each vertex has. They can be set when adding +// a new vertex using the functional options provided by this library: +// +// _ = g.AddVertex("A", "B", graph.VertexWeight(2), graph.VertexAttribute("color", "red")) +// +// The example above will create a vertex with weight 2 and a "color" attribute with value "red". +type VertexProperties struct { + Attributes map[string]string + Weight int +} + +// VertexWeight returns a function that sets the weight of a vertex to the given weight. This is a +// functional option for the Vertex and AddVertex methods. +func VertexWeight(weight int) func(*VertexProperties) { + return func(e *VertexProperties) { + e.Weight = weight + } +} + +// VertexAttribute returns a function that adds the given key-value pair to the attributes of a +// vertex. This is a functional option for the Vertex and AddVertex methods. +func VertexAttribute(key, value string) func(*VertexProperties) { + return func(e *VertexProperties) { + e.Attributes[key] = value + } +} diff --git a/vendor/github.com/dominikbraun/graph/paths.go b/vendor/github.com/dominikbraun/graph/paths.go new file mode 100644 index 00000000000..e6f16e3f26b --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/paths.go @@ -0,0 +1,237 @@ +package graph + +import ( + "errors" + "fmt" + "math" +) + +var ErrTargetNotReachable = errors.New("target vertex not reachable from source") + +// CreatesCycle determines whether an edge between the given source and target vertices would +// introduce a cycle. It won't create that edge in any case. +// +// A potential edge would create a cycle if the target vertex is also a parent of the source vertex. +// Given a graph A-B-C-D, adding an edge DA would introduce a cycle: +// +// A - +// | | +// B | +// | | +// C | +// | | +// D - +// +// CreatesCycle backtracks the ingoing edges of D, resulting in a reverse walk C-B-A. +func CreatesCycle[K comparable, T any](g Graph[K, T], source, target K) (bool, error) { + if _, err := g.Vertex(source); err != nil { + return false, fmt.Errorf("could not get vertex with hash %v: %w", source, err) + } + + if _, err := g.Vertex(target); err != nil { + return false, fmt.Errorf("could not get vertex with hash %v: %w", target, err) + } + + if source == target { + return true, nil + } + + predecessorMap, err := g.PredecessorMap() + if err != nil { + return false, fmt.Errorf("failed to get predecessor map: %w", err) + } + + stack := make([]K, 0) + visited := make(map[K]bool) + + stack = append(stack, source) + + for len(stack) > 0 { + currentHash := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if _, ok := visited[currentHash]; !ok { + // If the current vertex, e.g. an adjacency of the source vertex, also is the target + // vertex, an edge between these two would create a cycle. + if currentHash == target { + return true, nil + } + visited[currentHash] = true + + for adjacency := range predecessorMap[currentHash] { + stack = append(stack, adjacency) + } + } + } + + return false, nil +} + +// ShortestPath computes the shortest path between a source and a target vertex using the edge +// weights and returns the hash values of the vertices forming that path using Dijkstra's algorithm. +// This search runs in O(|V|+|E|log(|V|)) time. +// +// The returned path includes the source and target vertices. If the target cannot be reached +// from the source vertex, ErrTargetNotReachable will be returned. If there are multiple shortest +// paths, an arbitrary one will be returned. +func ShortestPath[K comparable, T any](g Graph[K, T], source, target K) ([]K, error) { + weights := make(map[K]float64) + visited := make(map[K]bool) + + weights[source] = 0 + visited[target] = true + + queue := newPriorityQueue[K]() + adjacencyMap, err := g.AdjacencyMap() + if err != nil { + return nil, fmt.Errorf("could not get adjacency map: %w", err) + } + + for hash := range adjacencyMap { + if hash != source { + weights[hash] = math.Inf(1) + visited[hash] = false + } + + queue.Push(hash, weights[hash]) + } + + // bestPredecessors stores the best (i.e. cheapest or least-weighted) predecessor for each + // vertex. If there is an edge AC with weight 4 and an edge BC with weight 2, the best + // predecessor for C is B. + bestPredecessors := make(map[K]K) + + for queue.Len() > 0 { + vertex, _ := queue.Pop() + hasInfiniteWeight := math.IsInf(weights[vertex], 1) + + for adjacency, edge := range adjacencyMap[vertex] { + edgeWeight := edge.Properties.Weight + + // Setting the weight to 1 is required for unweighted graphs whose + // edge weights are 0. Otherwise, all paths would have a sum of 0 + // and a random path would be returned. + if !g.Traits().IsWeighted { + edgeWeight = 1 + } + + weight := weights[vertex] + float64(edgeWeight) + + if weight < weights[adjacency] && !hasInfiniteWeight { + weights[adjacency] = weight + bestPredecessors[adjacency] = vertex + queue.UpdatePriority(adjacency, weight) + } + } + } + + // Backtrack the predecessors from target to source. These are the least-weighted edges. + path := []K{target} + hashCursor := target + + for hashCursor != source { + // If hashCursor is not a present key in bestPredecessors, hashCursor is set to the zero + // value. Without this check, this leads to endless prepending of zeros to the path. + if _, ok := bestPredecessors[hashCursor]; !ok { + return nil, ErrTargetNotReachable + } + hashCursor = bestPredecessors[hashCursor] + path = append([]K{hashCursor}, path...) + } + + return path, nil +} + +type sccState[K comparable] struct { + adjacencyMap map[K]map[K]Edge[K] + components [][]K + stack []K + onStack map[K]bool + visited map[K]struct{} + lowlink map[K]int + index map[K]int + time int +} + +// StronglyConnectedComponents detects all strongly connected components within the given graph +// and returns the hashes of the vertices shaping these components, so each component is a []K. +// +// The current implementation uses Tarjan's algorithm and runs recursively. +func StronglyConnectedComponents[K comparable, T any](g Graph[K, T]) ([][]K, error) { + if !g.Traits().IsDirected { + return nil, errors.New("SCCs can only be detected in directed graphs") + } + + adjacencyMap, err := g.AdjacencyMap() + if err != nil { + return nil, fmt.Errorf("could not get adjacency map: %w", err) + } + + state := &sccState[K]{ + adjacencyMap: adjacencyMap, + components: make([][]K, 0), + stack: make([]K, 0), + onStack: make(map[K]bool), + visited: make(map[K]struct{}), + lowlink: make(map[K]int), + index: make(map[K]int), + } + + for hash := range state.adjacencyMap { + if _, ok := state.visited[hash]; !ok { + findSCC(hash, state) + } + } + + return state.components, nil +} + +func findSCC[K comparable](vertexHash K, state *sccState[K]) { + state.stack = append(state.stack, vertexHash) + state.onStack[vertexHash] = true + state.visited[vertexHash] = struct{}{} + state.index[vertexHash] = state.time + state.lowlink[vertexHash] = state.time + + state.time++ + + for adjacency := range state.adjacencyMap[vertexHash] { + if _, ok := state.visited[adjacency]; !ok { + findSCC(adjacency, state) + + smallestLowlink := math.Min( + float64(state.lowlink[vertexHash]), + float64(state.lowlink[adjacency]), + ) + state.lowlink[vertexHash] = int(smallestLowlink) + } else { + // If the adjacent vertex already is on the stack, the edge joining the current and the + // adjacent vertex is a back edge. Therefore, update the vertex' lowlink value to the + // index of the adjacent vertex if it is smaller than the lowlink value. + if state.onStack[adjacency] { + smallestLowlink := math.Min( + float64(state.lowlink[vertexHash]), + float64(state.index[adjacency]), + ) + state.lowlink[vertexHash] = int(smallestLowlink) + } + } + } + + // If the lowlink value of the vertex is equal to its DFS index, this is th head vertex of a + // strongly connected component, shaped by this vertex and the vertices on the stack. + if state.lowlink[vertexHash] == state.index[vertexHash] { + var hash K + var component []K + + for hash != vertexHash { + hash = state.stack[len(state.stack)-1] + state.stack = state.stack[:len(state.stack)-1] + state.onStack[hash] = false + + component = append(component, hash) + } + + state.components = append(state.components, component) + } +} diff --git a/vendor/github.com/dominikbraun/graph/store.go b/vendor/github.com/dominikbraun/graph/store.go new file mode 100644 index 00000000000..bbcf5e8df30 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/store.go @@ -0,0 +1,179 @@ +package graph + +import "sync" + +// Store represents a storage for vertices and edges. The graph library provides an in-memory store +// by default and accepts any Store implementation to work with - for example, an SQL store. +// +// When implementing your own Store, make sure the individual methods and their behavior adhere to +// this documentation. Otherwise, the graphs aren't guaranteed to behave as expected. +type Store[K comparable, T any] interface { + // AddVertex should add the given vertex with the given hash value and vertex properties to the + // graph. If the vertex already exists, it is up to you whether ErrVertexAlreadyExists or no + // error should be returned. + AddVertex(hash K, value T, properties VertexProperties) error + + // Vertex should return the vertex and vertex properties with the given hash value. If the + // vertex doesn't exist, ErrVertexNotFound should be returned. + Vertex(hash K) (T, VertexProperties, error) + + // ListVertices should return all vertices in the graph in a slice. + ListVertices() ([]K, error) + + // VertexCount should return the number of vertices in the graph. This should be equal to the + // length of the slice returned by ListVertices. + VertexCount() (int, error) + + // AddEdge should add an edge between the vertices with the given source and target hashes. + // + // If either vertex doesn't exit, ErrVertexNotFound should be returned for the respective + // vertex. If the edge already exists, ErrEdgeAlreadyExists should be returned. + AddEdge(sourceHash, targetHash K, edge Edge[K]) error + + // RemoveEdge should remove the edge between the vertices with the given source and target + // hashes. + // + // If either vertex doesn't exist, it is up to you whether ErrVertexNotFound or no error should + // be returned. If the edge doesn't exist, it is up to you whether ErrEdgeNotFound or no error + // should be returned. + RemoveEdge(sourceHash, targetHash K) error + + // Edge should return the edge joining the vertices with the given hash values. It should + // exclusively look for an edge between the source and the target vertex, not vice versa. The + // graph implementation does this for undirected graphs itself. + // + // Note that unlike Graph.Edge, this function is supposed to return an Edge[K], i.e. an edge + // that only contains the vertex hashes instead of the vertices themselves. + // + // If the edge doesn't exist, ErrEdgeNotFound should be returned. + Edge(sourceHash, targetHash K) (Edge[K], error) + + // ListEdges should return all edges in the graph in a slice. + ListEdges() ([]Edge[K], error) +} + +type memoryStore[K comparable, T any] struct { + lock sync.RWMutex + vertices map[K]T + vertexProperties map[K]VertexProperties + + // outEdges and inEdges store all outgoing and ingoing edges for all vertices. For O(1) access, + // these edges themselves are stored in maps whose keys are the hashes of the target vertices. + outEdges map[K]map[K]Edge[K] // source -> target + inEdges map[K]map[K]Edge[K] // target -> source +} + +func newMemoryStore[K comparable, T any]() Store[K, T] { + return &memoryStore[K, T]{ + vertices: make(map[K]T), + vertexProperties: make(map[K]VertexProperties), + outEdges: make(map[K]map[K]Edge[K]), + inEdges: make(map[K]map[K]Edge[K]), + } +} + +func (s *memoryStore[K, T]) AddVertex(k K, t T, p VertexProperties) error { + s.lock.Lock() + defer s.lock.Unlock() + + if _, ok := s.vertices[k]; ok { + return ErrVertexAlreadyExists + } + + s.vertices[k] = t + s.vertexProperties[k] = p + + return nil +} + +func (s *memoryStore[K, T]) ListVertices() ([]K, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + var hashes []K + for k := range s.vertices { + hashes = append(hashes, k) + } + + return hashes, nil +} + +func (s *memoryStore[K, T]) VertexCount() (int, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + return len(s.vertices), nil +} + +func (s *memoryStore[K, T]) Vertex(k K) (T, VertexProperties, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + var v T + var ok bool + v, ok = s.vertices[k] + if !ok { + return v, VertexProperties{}, ErrVertexNotFound + } + + p := s.vertexProperties[k] + return v, p, nil +} + +func (s *memoryStore[K, T]) AddEdge(sourceHash, targetHash K, edge Edge[K]) error { + s.lock.Lock() + defer s.lock.Unlock() + + if _, ok := s.outEdges[sourceHash]; !ok { + s.outEdges[sourceHash] = make(map[K]Edge[K]) + } + + s.outEdges[sourceHash][targetHash] = edge + + if _, ok := s.inEdges[targetHash]; !ok { + s.inEdges[targetHash] = make(map[K]Edge[K]) + } + + s.inEdges[targetHash][sourceHash] = edge + + return nil +} + +func (s *memoryStore[K, T]) RemoveEdge(sourceHash, targetHash K) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.inEdges[sourceHash], targetHash) + delete(s.outEdges[sourceHash], targetHash) + return nil +} + +func (s *memoryStore[K, T]) Edge(sourceHash, targetHash K) (Edge[K], error) { + s.lock.RLock() + defer s.lock.RUnlock() + + sourceEdges, ok := s.outEdges[sourceHash] + if !ok { + return Edge[K]{}, ErrEdgeNotFound + } + + edge, ok := sourceEdges[targetHash] + if !ok { + return Edge[K]{}, ErrEdgeNotFound + } + + return edge, nil +} + +func (s *memoryStore[K, T]) ListEdges() ([]Edge[K], error) { + s.lock.RLock() + defer s.lock.RUnlock() + + res := make([]Edge[K], 0) + for _, edges := range s.outEdges { + for _, edge := range edges { + res = append(res, edge) + } + } + return res, nil +} diff --git a/vendor/github.com/dominikbraun/graph/traits.go b/vendor/github.com/dominikbraun/graph/traits.go new file mode 100644 index 00000000000..11b735766b5 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/traits.go @@ -0,0 +1,63 @@ +package graph + +// Traits represents a set of graph traits and types, such as directedness or acyclicness. These +// traits can be set when creating a graph by passing the corresponding functional options, for +// example: +// +// g := graph.New(graph.IntHash, graph.Directed()) +// +// This will set the IsDirected field to true. +type Traits struct { + IsDirected bool + IsAcyclic bool + IsWeighted bool + IsRooted bool + PreventCycles bool +} + +// Directed creates a directed graph. This has implications on graph traversal and the order of +// arguments of the Edge and AddEdge functions. +func Directed() func(*Traits) { + return func(t *Traits) { + t.IsDirected = true + } +} + +// Acyclic creates an acyclic graph. Note that creating edges that form a cycle will still be +// possible. To prevent this explicitly, use PreventCycles. +func Acyclic() func(*Traits) { + return func(t *Traits) { + t.IsAcyclic = true + } +} + +// Weighted creates a weighted graph. To set weights, use the Edge and AddEdge functions. +func Weighted() func(*Traits) { + return func(t *Traits) { + t.IsWeighted = true + } +} + +// Rooted creates a rooted graph. This is particularly common for building tree data structures. +func Rooted() func(*Traits) { + return func(t *Traits) { + t.IsRooted = true + } +} + +// Tree is an alias for Acyclic and Rooted, since most trees in Computer Science are rooted trees. +func Tree() func(*Traits) { + return func(t *Traits) { + Acyclic()(t) + Rooted()(t) + } +} + +// PreventCycles creates an acyclic graph that prevents and proactively prevents the creation of +// cycles. These cycle checks affect the performance and complexity of operations such as AddEdge. +func PreventCycles() func(*Traits) { + return func(t *Traits) { + Acyclic()(t) + t.PreventCycles = true + } +} diff --git a/vendor/github.com/dominikbraun/graph/traversal.go b/vendor/github.com/dominikbraun/graph/traversal.go new file mode 100644 index 00000000000..af5197c35ad --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/traversal.go @@ -0,0 +1,137 @@ +package graph + +import "fmt" + +// DFS performs a depth-first search on the graph, starting from the given vertex. The visit +// function will be invoked with the hash of the vertex currently visited. If it returns false, DFS +// will continue traversing the graph, and if it returns true, the traversal will be stopped. In +// case the graph is disconnected, only the vertices joined with the starting vertex are visited. +// +// This example prints all vertices of the graph in DFS-order: +// +// g := graph.New(graph.IntHash) +// +// _ = g.AddVertex(1) +// _ = g.AddVertex(2) +// _ = g.AddVertex(3) +// +// _ = g.AddEdge(1, 2) +// _ = g.AddEdge(2, 3) +// _ = g.AddEdge(3, 1) +// +// _ = graph.DFS(g, 1, func(value int) bool { +// fmt.Println(value) +// return false +// }) +// +// Similarly, if you have a graph of City vertices and the traversal should stop at London, the +// visit function would look as follows: +// +// func(c City) bool { +// return c.Name == "London" +// } +// +// DFS is non-recursive and maintains a stack instead. +func DFS[K comparable, T any](g Graph[K, T], start K, visit func(K) bool) error { + adjacencyMap, err := g.AdjacencyMap() + if err != nil { + return fmt.Errorf("could not get adjacency map: %w", err) + } + + if _, ok := adjacencyMap[start]; !ok { + return fmt.Errorf("could not find start vertex with hash %v", start) + } + + stack := make([]K, 0) + visited := make(map[K]bool) + + stack = append(stack, start) + + for len(stack) > 0 { + currentHash := stack[len(stack)-1] + + stack = stack[:len(stack)-1] + + if _, ok := visited[currentHash]; !ok { + // Stop traversing the graph if the visit function returns true. + if stop := visit(currentHash); stop { + break + } + visited[currentHash] = true + + for adjacency := range adjacencyMap[currentHash] { + stack = append(stack, adjacency) + } + } + } + + return nil +} + +// BFS performs a breadth-first search on the graph, starting from the given vertex. The visit +// function will be invoked with the hash of the vertex currently visited. If it returns false, BFS +// will continue traversing the graph, and if it returns true, the traversal will be stopped. In +// case the graph is disconnected, only the vertices joined with the starting vertex are visited. +// +// This example prints all vertices of the graph in BFS-order: +// +// g := graph.New(graph.IntHash) +// +// _ = g.AddVertex(1) +// _ = g.AddVertex(2) +// _ = g.AddVertex(3) +// +// _ = g.AddEdge(1, 2) +// _ = g.AddEdge(2, 3) +// _ = g.AddEdge(3, 1) +// +// _ = graph.BFS(g, 1, func(value int) bool { +// fmt.Println(value) +// return false +// }) +// +// Similarly, if you have a graph of City vertices and the traversal should stop at London, the +// visit function would look as follows: +// +// func(c City) bool { +// return c.Name == "London" +// } +// +// BFS is non-recursive and maintains a stack instead. +func BFS[K comparable, T any](g Graph[K, T], start K, visit func(K) bool) error { + adjacencyMap, err := g.AdjacencyMap() + if err != nil { + return fmt.Errorf("could not get adjacency map: %w", err) + } + + if _, ok := adjacencyMap[start]; !ok { + return fmt.Errorf("could not find start vertex with hash %v", start) + } + + queue := make([]K, 0) + visited := make(map[K]bool) + + visited[start] = true + queue = append(queue, start) + + for len(queue) > 0 { + currentHash := queue[0] + + queue = queue[1:] + + // Stop traversing the graph if the visit function returns true. + if stop := visit(currentHash); stop { + break + } + + for adjacency := range adjacencyMap[currentHash] { + if _, ok := visited[adjacency]; !ok { + visited[adjacency] = true + queue = append(queue, adjacency) + } + } + + } + + return nil +} diff --git a/vendor/github.com/dominikbraun/graph/undirected.go b/vendor/github.com/dominikbraun/graph/undirected.go new file mode 100644 index 00000000000..10828483696 --- /dev/null +++ b/vendor/github.com/dominikbraun/graph/undirected.go @@ -0,0 +1,249 @@ +package graph + +import ( + "errors" + "fmt" +) + +type undirected[K comparable, T any] struct { + hash Hash[K, T] + traits *Traits + store Store[K, T] +} + +func newUndirected[K comparable, T any](hash Hash[K, T], traits *Traits, store Store[K, T]) *undirected[K, T] { + return &undirected[K, T]{ + hash: hash, + traits: traits, + store: store, + } +} + +func (u *undirected[K, T]) Traits() *Traits { + return u.traits +} + +func (u *undirected[K, T]) AddVertex(value T, options ...func(*VertexProperties)) error { + hash := u.hash(value) + + prop := VertexProperties{ + Weight: 0, + Attributes: make(map[string]string), + } + + for _, option := range options { + option(&prop) + } + + return u.store.AddVertex(hash, value, prop) +} + +func (u *undirected[K, T]) Vertex(hash K) (T, error) { + vertex, _, err := u.store.Vertex(hash) + return vertex, err +} + +func (u *undirected[K, T]) VertexWithProperties(hash K) (T, VertexProperties, error) { + vertex, prop, err := u.store.Vertex(hash) + if err != nil { + return vertex, VertexProperties{}, err + } + + return vertex, prop, nil +} + +func (u *undirected[K, T]) AddEdge(sourceHash, targetHash K, options ...func(*EdgeProperties)) error { + if _, _, err := u.store.Vertex(sourceHash); err != nil { + return fmt.Errorf("could not find source vertex with hash %v: %w", sourceHash, err) + } + + if _, _, err := u.store.Vertex(targetHash); err != nil { + return fmt.Errorf("could not find target vertex with hash %v: %w", targetHash, err) + } + + // nolint: govet // false positive err shawdowing + if _, err := u.Edge(sourceHash, targetHash); !errors.Is(err, ErrEdgeNotFound) { + return ErrEdgeAlreadyExists + } + + // If the user opted in to preventing cycles, run a cycle check. + if u.traits.PreventCycles { + createsCycle, err := CreatesCycle[K, T](u, sourceHash, targetHash) + if err != nil { + return fmt.Errorf("check for cycles: %w", err) + } + if createsCycle { + return ErrEdgeCreatesCycle + } + } + + edge := Edge[K]{ + Source: sourceHash, + Target: targetHash, + Properties: EdgeProperties{ + Attributes: make(map[string]string), + }, + } + + for _, option := range options { + option(&edge.Properties) + } + + if err := u.addEdge(sourceHash, targetHash, edge); err != nil { + return fmt.Errorf("failed to add edge: %w", err) + } + + return nil +} + +func (u *undirected[K, T]) Edge(sourceHash, targetHash K) (Edge[T], error) { + // In an undirected graph, since multigraphs aren't supported, the edge AB is the same as BA. + // Therefore, if source[target] cannot be found, this function also looks for target[source]. + + edge, err := u.store.Edge(sourceHash, targetHash) + if errors.Is(err, ErrEdgeNotFound) { + edge, err = u.store.Edge(targetHash, sourceHash) + } + + if err != nil { + return Edge[T]{}, err + } + + sourceVertex, _, err := u.store.Vertex(sourceHash) + if err != nil { + return Edge[T]{}, err + } + + targetVertex, _, err := u.store.Vertex(targetHash) + if err != nil { + return Edge[T]{}, err + } + + return Edge[T]{ + Source: sourceVertex, + Target: targetVertex, + Properties: EdgeProperties{ + Weight: edge.Properties.Weight, + Attributes: edge.Properties.Attributes, + Data: edge.Properties.Data, + }, + }, nil +} + +func (u *undirected[K, T]) RemoveEdge(source, target K) error { + if _, err := u.Edge(source, target); err != nil { + return err + } + + if err := u.store.RemoveEdge(source, target); err != nil { + return fmt.Errorf("failed to remove edge from %v to %v: %w", source, target, err) + } + + if err := u.store.RemoveEdge(target, source); err != nil { + return fmt.Errorf("failed to remove edge from %v to %v: %w", target, source, err) + } + + return nil +} + +func (u *undirected[K, T]) AdjacencyMap() (map[K]map[K]Edge[K], error) { + vertices, err := u.store.ListVertices() + if err != nil { + return nil, fmt.Errorf("failed to list vertices: %w", err) + } + + edges, err := u.store.ListEdges() + if err != nil { + return nil, fmt.Errorf("failed to list edges: %w", err) + } + + m := make(map[K]map[K]Edge[K]) + + for _, vertex := range vertices { + m[vertex] = make(map[K]Edge[K]) + } + + for _, edge := range edges { + m[edge.Source][edge.Target] = edge + } + + return m, nil +} + +func (u *undirected[K, T]) PredecessorMap() (map[K]map[K]Edge[K], error) { + return u.AdjacencyMap() +} + +func (u *undirected[K, T]) Clone() (Graph[K, T], error) { + traits := &Traits{ + IsDirected: u.traits.IsDirected, + IsAcyclic: u.traits.IsAcyclic, + IsWeighted: u.traits.IsWeighted, + IsRooted: u.traits.IsRooted, + } + + return &undirected[K, T]{ + hash: u.hash, + traits: traits, + store: u.store, + }, nil +} + +func (u *undirected[K, T]) Order() (int, error) { + return u.store.VertexCount() +} + +func (u *undirected[K, T]) Size() (int, error) { + size := 0 + outEdges, err := u.AdjacencyMap() + if err != nil { + return 0, fmt.Errorf("failed to get adjacency map: %w", err) + } + for _, outEdges := range outEdges { + size += len(outEdges) + } + + // Divide by 2 since every add edge operation on undirected graph is counted twice. + return size / 2, nil +} + +func (u *undirected[K, T]) edgesAreEqual(a, b Edge[T]) bool { + aSourceHash := u.hash(a.Source) + aTargetHash := u.hash(a.Target) + bSourceHash := u.hash(b.Source) + bTargetHash := u.hash(b.Target) + + if aSourceHash == bSourceHash && aTargetHash == bTargetHash { + return true + } + + if !u.traits.IsDirected { + return aSourceHash == bTargetHash && aTargetHash == bSourceHash + } + + return false +} + +func (u *undirected[K, T]) addEdge(sourceHash, targetHash K, edge Edge[K]) error { + err := u.store.AddEdge(sourceHash, targetHash, edge) + if err != nil { + return err + } + + rEdge := Edge[K]{ + Source: edge.Target, + Target: edge.Source, + Properties: EdgeProperties{ + Weight: edge.Properties.Weight, + Attributes: edge.Properties.Attributes, + Data: edge.Properties.Data, + }, + } + + err = u.store.AddEdge(targetHash, sourceHash, rEdge) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/emicklei/go-restful/CHANGES.md b/vendor/github.com/emicklei/go-restful/CHANGES.md deleted file mode 100644 index 3a5299474b8..00000000000 --- a/vendor/github.com/emicklei/go-restful/CHANGES.md +++ /dev/null @@ -1,318 +0,0 @@ -# Change history of go-restful (v2 only) - -## v2.16.0 - 2022-07-11 - -- Backported CORS filter. #489 (#493) #503 - -## v2.15.0 - 2020-11-10 - -- Add OPTIONS in Webservice - -## v2.14.3 - 2020-08-31 -- Fixed duplicate compression in dispatch. #449 - - -## v2.14.2 - 2020-08-31 - -- Added check on writer to prevent compression of response twice. #447 - -## v2.14.0 - 2020-08-19 - -- Enable content encoding on Handle and ServeHTTP (#446) -- List available representations in 406 body (#437) -- Convert to string using rune() (#443) - -## v2.13.0 - 2020-06-21 - -- 405 Method Not Allowed must have Allow header (#436) -- add field allowedMethodsWithoutContentType (#424) - -## v2.12.0 - -- support describing response headers (#426) -- fix openapi examples (#425) -- merge v3 fix (#422) - -## v2.11.1 - -- fix WriteError return value (#415) - -## v2.11.0 - -- allow prefix and suffix in path variable expression (#414) - -## v2.9.6 - -- support google custome verb (#413) - -## v2.9.5 - -- fix panic in Response.WriteError if err == nil - -## v2.9.4 - -- fix issue #400 , parsing mime type quality -- Route Builder added option for contentEncodingEnabled (#398) - -## v2.9.3 - -- Avoid return of 415 Unsupported Media Type when request body is empty (#396) - -## v2.9.2 - -- Reduce allocations in per-request methods to improve performance (#395) - -## v2.9.1 - -- Fix issue with default responses and invalid status code 0. (#393) - -## v2.9.0 - -- add per Route content encoding setting (overrides container setting) - -## v2.8.0 - -- add Request.QueryParameters() -- add json-iterator (via build tag) -- disable vgo module (until log is moved) - -## v2.7.1 - -- add vgo module - -## v2.6.1 - -- add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+) - -## v2.6.0 - -- Make JSR 311 routing and path param processing consistent -- Adding description to RouteBuilder.Reads() -- Update example for Swagger12 and OpenAPI - -## 2017-09-13 - -- added route condition functions using `.If(func)` in route building. - -## 2017-02-16 - -- solved issue #304, make operation names unique - -## 2017-01-30 - - [IMPORTANT] For swagger users, change your import statement to: - swagger "github.com/emicklei/go-restful-swagger12" - -- moved swagger 1.2 code to go-restful-swagger12 -- created TAG 2.0.0 - -## 2017-01-27 - -- remove defer request body close -- expose Dispatch for testing filters and Routefunctions -- swagger response model cannot be array -- created TAG 1.0.0 - -## 2016-12-22 - -- (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool) - -## 2016-11-26 - -- Default change! now use CurlyRouter (was RouterJSR311) -- Default change! no more caching of request content -- Default change! do not recover from panics - -## 2016-09-22 - -- fix the DefaultRequestContentType feature - -## 2016-02-14 - -- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response -- add constructors for custom entity accessors for xml and json - -## 2015-09-27 - -- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency - -## 2015-09-25 - -- fixed problem with changing Header after WriteHeader (issue 235) - -## 2015-09-14 - -- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write) -- added support for custom EntityReaderWriters. - -## 2015-08-06 - -- add support for reading entities from compressed request content -- use sync.Pool for compressors of http response and request body -- add Description to Parameter for documentation in Swagger UI - -## 2015-03-20 - -- add configurable logging - -## 2015-03-18 - -- if not specified, the Operation is derived from the Route function - -## 2015-03-17 - -- expose Parameter creation functions -- make trace logger an interface -- fix OPTIONSFilter -- customize rendering of ServiceError -- JSR311 router now handles wildcards -- add Notes to Route - -## 2014-11-27 - -- (api add) PrettyPrint per response. (as proposed in #167) - -## 2014-11-12 - -- (api add) ApiVersion(.) for documentation in Swagger UI - -## 2014-11-10 - -- (api change) struct fields tagged with "description" show up in Swagger UI - -## 2014-10-31 - -- (api change) ReturnsError -> Returns -- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder -- fix swagger nested structs -- sort Swagger response messages by code - -## 2014-10-23 - -- (api add) ReturnsError allows you to document Http codes in swagger -- fixed problem with greedy CurlyRouter -- (api add) Access-Control-Max-Age in CORS -- add tracing functionality (injectable) for debugging purposes -- support JSON parse 64bit int -- fix empty parameters for swagger -- WebServicesUrl is now optional for swagger -- fixed duplicate AccessControlAllowOrigin in CORS -- (api change) expose ServeMux in container -- (api add) added AllowedDomains in CORS -- (api add) ParameterNamed for detailed documentation - -## 2014-04-16 - -- (api add) expose constructor of Request for testing. - -## 2014-06-27 - -- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification). -- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons). - -## 2014-07-03 - -- (api add) CORS can be configured with a list of allowed domains - -## 2014-03-12 - -- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter) - -## 2014-02-26 - -- (api add) Request now provides information about the matched Route, see method SelectedRoutePath - -## 2014-02-17 - -- (api change) renamed parameter constants (go-lint checks) - -## 2014-01-10 - -- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier - -## 2014-01-07 - -- (api change) Write* methods in Response now return the error or nil. -- added example of serving HTML from a Go template. -- fixed comparing Allowed headers in CORS (is now case-insensitive) - -## 2013-11-13 - -- (api add) Response knows how many bytes are written to the response body. - -## 2013-10-29 - -- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information. - -## 2013-10-04 - -- (api add) Response knows what HTTP status has been written -- (api add) Request can have attributes (map of string->interface, also called request-scoped variables - -## 2013-09-12 - -- (api change) Router interface simplified -- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths - -## 2013-08-05 - - add OPTIONS support - - add CORS support - -## 2013-08-27 - -- fixed some reported issues (see github) -- (api change) deprecated use of WriteError; use WriteErrorString instead - -## 2014-04-15 - -- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString - -## 2013-08-08 - -- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer. -- (api add) the swagger package has be extended to have a UI per container. -- if panic is detected then a small stack trace is printed (thanks to runner-mei) -- (api add) WriteErrorString to Response - -Important API changes: - -- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead. -- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead. - - -## 2013-07-06 - -- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature. - -## 2013-06-19 - -- (improve) DoNotRecover option, moved request body closer, improved ReadEntity - -## 2013-06-03 - -- (api change) removed Dispatcher interface, hide PathExpression -- changed receiver names of type functions to be more idiomatic Go - -## 2013-06-02 - -- (optimize) Cache the RegExp compilation of Paths. - -## 2013-05-22 - -- (api add) Added support for request/response filter functions - -## 2013-05-18 - - -- (api add) Added feature to change the default Http Request Dispatch function (travis cline) -- (api change) Moved Swagger Webservice to swagger package (see example restful-user) - -## [2012-11-14 .. 2013-05-18> - -- See https://github.com/emicklei/go-restful/commits - -## 2012-11-14 - -- Initial commit - - diff --git a/vendor/github.com/emicklei/go-restful/Makefile b/vendor/github.com/emicklei/go-restful/Makefile deleted file mode 100644 index 3a824ac3dfd..00000000000 --- a/vendor/github.com/emicklei/go-restful/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: test - -test: - go vet . - go test -cover -v . \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/README.md b/vendor/github.com/emicklei/go-restful/README.md deleted file mode 100644 index e5878a668d9..00000000000 --- a/vendor/github.com/emicklei/go-restful/README.md +++ /dev/null @@ -1,111 +0,0 @@ -go-restful -========== -package for building REST-style Web Services using Google Go - -[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) -[![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) -[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) -[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) - -- [Code examples using v3](https://github.com/emicklei/go-restful/tree/master/examples) - -REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping: - -- GET = Retrieve a representation of a resource -- POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm. -- PUT = Create if you are sending the full content of the specified resource (URI). -- PUT = Update if you are updating the full content of the specified resource. -- DELETE = Delete if you are requesting the server to delete the resource -- PATCH = Update partial content of a resource -- OPTIONS = Get information about the communication options for the request URI - -### Usage - -#### Using Go Modules - -As of version `v3.0.0` (on the v3 branch), this package supports Go modules. - -``` -import ( - restful "github.com/emicklei/go-restful/v3" -) -``` - -#### Without Go Modules - -All versions up to `v2.*.*` (on the master) are not supporting Go modules. - -``` -import ( - restful "github.com/emicklei/go-restful" -) -``` - -### Example - -```Go -ws := new(restful.WebService) -ws. - Path("/users"). - Consumes(restful.MIME_XML, restful.MIME_JSON). - Produces(restful.MIME_JSON, restful.MIME_XML) - -ws.Route(ws.GET("/{user-id}").To(u.findUser). - Doc("get a user"). - Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). - Writes(User{})) -... - -func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... -} -``` - -[Full API of a UserResource](https://github.com/emicklei/go-restful/tree/master/examples/user-resource/restful-user-resource.go) - -### Features - -- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support -- Configurable router: - - (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*}) - - Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions -- Request API for reading structs from JSON/XML and accesing parameters (path,query,header) -- Response API for writing structs to JSON/XML and setting headers -- Customizable encoding using EntityReaderWriter registration -- Filters for intercepting the request → response flow on Service or Route level -- Request-scoped variables using attributes -- Containers for WebServices on different HTTP endpoints -- Content encoding (gzip,deflate) of request and response payloads -- Automatic responses on OPTIONS (using a filter) -- Automatic CORS request handling (using a filter) -- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12)) -- Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) -- Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) -- Configurable (trace) logging -- Customizable gzip/deflate readers and writers using CompressorProvider registration - -## How to customize -There are several hooks to customize the behavior of the go-restful package. - -- Router algorithm -- Panic recovery -- JSON decoder -- Trace logging -- Compression -- Encoders for other serializers -- Use [jsoniter](https://github.com/json-iterator/go) by build this package using a tag, e.g. `go build -tags=jsoniter .` - -TODO: write examples of these. - -## Resources - -- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/) -- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/) -- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful) -- [showcase: Zazkia - tcp proxy for testing resiliency](https://github.com/emicklei/zazkia) -- [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora) - -Type ```git shortlog -s``` for a full list of contributors. - -© 2012 - 2020, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/container.go b/vendor/github.com/emicklei/go-restful/container.go deleted file mode 100644 index afca312a4fa..00000000000 --- a/vendor/github.com/emicklei/go-restful/container.go +++ /dev/null @@ -1,445 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "errors" - "fmt" - "net/http" - "os" - "runtime" - "strings" - "sync" - - "github.com/emicklei/go-restful/log" -) - -// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests. -// The requests are further dispatched to routes of WebServices using a RouteSelector -type Container struct { - webServicesLock sync.RWMutex - webServices []*WebService - ServeMux *http.ServeMux - isRegisteredOnRoot bool - containerFilters []FilterFunction - doNotRecover bool // default is true - recoverHandleFunc RecoverHandleFunction - serviceErrorHandleFunc ServiceErrorHandleFunction - router RouteSelector // default is a CurlyRouter (RouterJSR311 is a slower alternative) - contentEncodingEnabled bool // default is false -} - -// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter) -func NewContainer() *Container { - return &Container{ - webServices: []*WebService{}, - ServeMux: http.NewServeMux(), - isRegisteredOnRoot: false, - containerFilters: []FilterFunction{}, - doNotRecover: true, - recoverHandleFunc: logStackOnRecover, - serviceErrorHandleFunc: writeServiceError, - router: CurlyRouter{}, - contentEncodingEnabled: false} -} - -// RecoverHandleFunction declares functions that can be used to handle a panic situation. -// The first argument is what recover() returns. The second must be used to communicate an error response. -type RecoverHandleFunction func(interface{}, http.ResponseWriter) - -// RecoverHandler changes the default function (logStackOnRecover) to be called -// when a panic is detected. DoNotRecover must be have its default value (=false). -func (c *Container) RecoverHandler(handler RecoverHandleFunction) { - c.recoverHandleFunc = handler -} - -// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation. -// The first argument is the service error, the second is the request that resulted in the error and -// the third must be used to communicate an error response. -type ServiceErrorHandleFunction func(ServiceError, *Request, *Response) - -// ServiceErrorHandler changes the default function (writeServiceError) to be called -// when a ServiceError is detected. -func (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) { - c.serviceErrorHandleFunc = handler -} - -// DoNotRecover controls whether panics will be caught to return HTTP 500. -// If set to true, Route functions are responsible for handling any error situation. -// Default value is true. -func (c *Container) DoNotRecover(doNot bool) { - c.doNotRecover = doNot -} - -// Router changes the default Router (currently CurlyRouter) -func (c *Container) Router(aRouter RouteSelector) { - c.router = aRouter -} - -// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. -func (c *Container) EnableContentEncoding(enabled bool) { - c.contentEncodingEnabled = enabled -} - -// Add a WebService to the Container. It will detect duplicate root paths and exit in that case. -func (c *Container) Add(service *WebService) *Container { - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - - // if rootPath was not set then lazy initialize it - if len(service.rootPath) == 0 { - service.Path("/") - } - - // cannot have duplicate root paths - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - log.Printf("WebService with duplicate root path detected:['%v']", each) - os.Exit(1) - } - } - - // If not registered on root then add specific mapping - if !c.isRegisteredOnRoot { - c.isRegisteredOnRoot = c.addHandler(service, c.ServeMux) - } - c.webServices = append(c.webServices, service) - return c -} - -// addHandler may set a new HandleFunc for the serveMux -// this function must run inside the critical region protected by the webServicesLock. -// returns true if the function was registered on root ("/") -func (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool { - pattern := fixedPrefixPath(service.RootPath()) - // check if root path registration is needed - if "/" == pattern || "" == pattern { - serveMux.HandleFunc("/", c.dispatch) - return true - } - // detect if registration already exists - alreadyMapped := false - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - alreadyMapped = true - break - } - } - if !alreadyMapped { - serveMux.HandleFunc(pattern, c.dispatch) - if !strings.HasSuffix(pattern, "/") { - serveMux.HandleFunc(pattern+"/", c.dispatch) - } - } - return false -} - -func (c *Container) Remove(ws *WebService) error { - if c.ServeMux == http.DefaultServeMux { - errMsg := fmt.Sprintf("cannot remove a WebService from a Container using the DefaultServeMux: ['%v']", ws) - log.Print(errMsg) - return errors.New(errMsg) - } - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - // build a new ServeMux and re-register all WebServices - newServeMux := http.NewServeMux() - newServices := []*WebService{} - newIsRegisteredOnRoot := false - for _, each := range c.webServices { - if each.rootPath != ws.rootPath { - // If not registered on root then add specific mapping - if !newIsRegisteredOnRoot { - newIsRegisteredOnRoot = c.addHandler(each, newServeMux) - } - newServices = append(newServices, each) - } - } - c.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot - return nil -} - -// logStackOnRecover is the default RecoverHandleFunction and is called -// when DoNotRecover is false and the recoverHandleFunc is not set for the container. -// Default implementation logs the stacktrace and writes the stacktrace on the response. -// This may be a security issue as it exposes sourcecode information. -func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) { - var buffer bytes.Buffer - buffer.WriteString(fmt.Sprintf("recover from panic situation: - %v\r\n", panicReason)) - for i := 2; ; i += 1 { - _, file, line, ok := runtime.Caller(i) - if !ok { - break - } - buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line)) - } - log.Print(buffer.String()) - httpWriter.WriteHeader(http.StatusInternalServerError) - httpWriter.Write(buffer.Bytes()) -} - -// writeServiceError is the default ServiceErrorHandleFunction and is called -// when a ServiceError is returned during route selection. Default implementation -// calls resp.WriteErrorString(err.Code, err.Message) -func writeServiceError(err ServiceError, req *Request, resp *Response) { - for header, values := range err.Header { - for _, value := range values { - resp.Header().Add(header, value) - } - } - resp.WriteErrorString(err.Code, err.Message) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - if httpWriter == nil { - panic("httpWriter cannot be nil") - } - if httpRequest == nil { - panic("httpRequest cannot be nil") - } - c.dispatch(httpWriter, httpRequest) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // so we can assign a compressing one later - writer := httpWriter - - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - // Instal panic recovery unless told otherwise - if !c.doNotRecover { // catch all for 500 response - defer func() { - if r := recover(); r != nil { - c.recoverHandleFunc(r, writer) - return - } - }() - } - - // Find best match Route ; err is non nil if no match was found - var webService *WebService - var route *Route - var err error - func() { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - webService, route, err = c.router.SelectRoute( - c.webServices, - httpRequest) - }() - if err != nil { - // a non-200 response (may be compressed) has already been written - // run container filters anyway ; they should not touch the response... - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - switch err.(type) { - case ServiceError: - ser := err.(ServiceError) - c.serviceErrorHandleFunc(ser, req, resp) - } - // TODO - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer)) - return - } - - // Unless httpWriter is already an CompressingResponseWriter see if we need to install one - if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing { - // Detect if compression is needed - // assume without compression, test for override - contentEncodingEnabled := c.contentEncodingEnabled - if route != nil && route.contentEncodingEnabled != nil { - contentEncodingEnabled = *route.contentEncodingEnabled - } - if contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - } - - pathProcessor, routerProcessesPath := c.router.(PathProcessor) - if !routerProcessesPath { - pathProcessor = defaultPathProcessor{} - } - pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path) - wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams) - // pass through filters (if any) - if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 { - // compose filter chain - allFilters := make([]FilterFunction, 0, size) - allFilters = append(allFilters, c.containerFilters...) - allFilters = append(allFilters, webService.filters...) - allFilters = append(allFilters, route.Filters...) - chain := FilterChain{Filters: allFilters, Target: route.Function} - chain.ProcessFilter(wrappedRequest, wrappedResponse) - } else { - // no filters, handle request by route - route.Function(wrappedRequest, wrappedResponse) - } -} - -// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {} -func fixedPrefixPath(pathspec string) string { - varBegin := strings.Index(pathspec, "{") - if -1 == varBegin { - return pathspec - } - return pathspec[:varBegin] -} - -// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server -func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // Skip, if content encoding is disabled - if !c.contentEncodingEnabled { - c.ServeMux.ServeHTTP(httpWriter, httpRequest) - return - } - // content encoding is enabled - - // Skip, if httpWriter is already an CompressingResponseWriter - if _, ok := httpWriter.(*CompressingResponseWriter); ok { - c.ServeMux.ServeHTTP(httpWriter, httpRequest) - return - } - - writer := httpWriter - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - doCompress, encoding := wantsCompressedResponse(httpRequest) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - - c.ServeMux.ServeHTTP(writer, httpRequest) -} - -// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. -func (c *Container) Handle(pattern string, handler http.Handler) { - c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // Skip, if httpWriter is already an CompressingResponseWriter - if _, ok := httpWriter.(*CompressingResponseWriter); ok { - handler.ServeHTTP(httpWriter, httpRequest) - return - } - - writer := httpWriter - - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - if c.contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - - handler.ServeHTTP(writer, httpRequest) - })) -} - -// HandleWithFilter registers the handler for the given pattern. -// Container's filter chain is applied for handler. -// If a handler already exists for pattern, HandleWithFilter panics. -func (c *Container) HandleWithFilter(pattern string, handler http.Handler) { - f := func(httpResponse http.ResponseWriter, httpRequest *http.Request) { - if len(c.containerFilters) == 0 { - handler.ServeHTTP(httpResponse, httpRequest) - return - } - - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - handler.ServeHTTP(resp, req.Request) - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse)) - } - - c.Handle(pattern, http.HandlerFunc(f)) -} - -// Filter appends a container FilterFunction. These are called before dispatching -// a http.Request to a WebService from the container -func (c *Container) Filter(filter FilterFunction) { - c.containerFilters = append(c.containerFilters, filter) -} - -// RegisteredWebServices returns the collections of added WebServices -func (c *Container) RegisteredWebServices() []*WebService { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - result := make([]*WebService, len(c.webServices)) - for ix := range c.webServices { - result[ix] = c.webServices[ix] - } - return result -} - -// computeAllowedMethods returns a list of HTTP methods that are valid for a Request -func (c *Container) computeAllowedMethods(req *Request) []string { - // Go through all RegisteredWebServices() and all its Routes to collect the options - methods := []string{} - requestPath := req.Request.URL.Path - for _, ws := range c.RegisteredWebServices() { - matches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath) - if matches != nil { - finalMatch := matches[len(matches)-1] - for _, rt := range ws.Routes() { - matches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch) - if matches != nil { - lastMatch := matches[len(matches)-1] - if lastMatch == "" || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. - methods = append(methods, rt.Method) - } - } - } - } - } - // methods = append(methods, "OPTIONS") not sure about this - return methods -} - -// newBasicRequestResponse creates a pair of Request,Response from its http versions. -// It is basic because no parameter or (produces) content-type information is given. -func newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) { - resp := NewResponse(httpWriter) - resp.requestAccept = httpRequest.Header.Get(HEADER_Accept) - return NewRequest(httpRequest), resp -} diff --git a/vendor/github.com/emicklei/go-restful/doc.go b/vendor/github.com/emicklei/go-restful/doc.go deleted file mode 100644 index f7c16b01fee..00000000000 --- a/vendor/github.com/emicklei/go-restful/doc.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Package restful , a lean package for creating REST-style WebServices without magic. - -WebServices and Routes - -A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls. -Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes. -WebServices must be added to a container (see below) in order to handler Http requests from a server. - -A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept). -This package has the logic to find the best matching Route and if found, call its Function. - - ws := new(restful.WebService) - ws. - Path("/users"). - Consumes(restful.MIME_JSON, restful.MIME_XML). - Produces(restful.MIME_JSON, restful.MIME_XML) - - ws.Route(ws.GET("/{user-id}").To(u.findUser)) // u is a UserResource - - ... - - // GET http://localhost:8080/users/1 - func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... - } - -The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response. - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-user-resource.go with a full implementation. - -Regular expression matching Routes - -A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path. -For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters. -Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax) -This feature requires the use of a CurlyRouter. - -Containers - -A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests. -Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container. -The Default container of go-restful uses the http.DefaultServeMux. -You can create your own Container and create a new http.Server for that particular container. - - container := restful.NewContainer() - server := &http.Server{Addr: ":8081", Handler: container} - -Filters - -A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. -You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. -In the restful package there are three hooks into the request,response flow where filters can be added. -Each filter must define a FilterFunction: - - func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain) - -Use the following statement to pass the request,response pair to the next filter or RouteFunction - - chain.ProcessFilter(req, resp) - -Container Filters - -These are processed before any registered WebService. - - // install a (global) filter for the default container (processed before any webservice) - restful.Filter(globalLogging) - -WebService Filters - -These are processed before any Route of a WebService. - - // install a webservice filter (processed before any route) - ws.Filter(webserviceLogging).Filter(measureTime) - - -Route Filters - -These are processed before calling the function associated with the Route. - - // install 2 chained route filters (processed before calling findUser) - ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser)) - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go with full implementations. - -Response Encoding - -Two encodings are supported: gzip and deflate. To enable this for all responses: - - restful.DefaultContainer.EnableContentEncoding(true) - -If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding. -Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route. - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go - -OPTIONS support - -By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request. - - Filter(OPTIONSFilter()) - -CORS - -By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests. - - cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} - Filter(cors.Filter) - -Error Handling - -Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why. -For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation. - - 400: Bad Request - -If path or query parameters are not valid (content or type) then use http.StatusBadRequest. - - 404: Not Found - -Despite a valid URI, the resource requested may not be available - - 500: Internal Server Error - -If the application logic could not process the request (or write the response) then use http.StatusInternalServerError. - - 405: Method Not Allowed - -The request has a valid URL but the method (GET,PUT,POST,...) is not allowed. - - 406: Not Acceptable - -The request does not have or has an unknown Accept Header set for this operation. - - 415: Unsupported Media Type - -The request does not have or has an unknown Content-Type Header set for this operation. - -ServiceError - -In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response. - -Performance options - -This package has several options that affect the performance of your service. It is important to understand them and how you can change it. - - restful.DefaultContainer.DoNotRecover(false) - -DoNotRecover controls whether panics will be caught to return HTTP 500. -If set to false, the container will recover from panics. -Default value is true - - restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20)) - -If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool. -Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation. - -Trouble shooting - -This package has the means to produce detail logging of the complete Http request matching process and filter invocation. -Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as: - - restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) - -Logging - -The restful.SetLogger() method allows you to override the logger used by the package. By default restful -uses the standard library `log` package and logs to stdout. Different logging packages are supported as -long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your -preferred package is simple. - -Resources - -[project]: https://github.com/emicklei/go-restful - -[examples]: https://github.com/emicklei/go-restful/blob/master/examples - -[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ - -[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape - -(c) 2012-2015, http://ernestmicklei.com. MIT License -*/ -package restful diff --git a/vendor/github.com/emicklei/go-restful/filter.go b/vendor/github.com/emicklei/go-restful/filter.go deleted file mode 100644 index c23bfb591ad..00000000000 --- a/vendor/github.com/emicklei/go-restful/filter.go +++ /dev/null @@ -1,35 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction. -type FilterChain struct { - Filters []FilterFunction // ordered list of FilterFunction - Index int // index into filters that is currently in progress - Target RouteFunction // function to call after passing all filters -} - -// ProcessFilter passes the request,response pair through the next of Filters. -// Each filter can decide to proceed to the next Filter or handle the Response itself. -func (f *FilterChain) ProcessFilter(request *Request, response *Response) { - if f.Index < len(f.Filters) { - f.Index++ - f.Filters[f.Index-1](request, response, f) - } else { - f.Target(request, response) - } -} - -// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction -type FilterFunction func(*Request, *Response, *FilterChain) - -// NoBrowserCacheFilter is a filter function to set HTTP headers that disable browser caching -// See examples/restful-no-cache-filter.go for usage -func NoBrowserCacheFilter(req *Request, resp *Response, chain *FilterChain) { - resp.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1. - resp.Header().Set("Pragma", "no-cache") // HTTP 1.0. - resp.Header().Set("Expires", "0") // Proxies. - chain.ProcessFilter(req, resp) -} diff --git a/vendor/github.com/emicklei/go-restful/parameter.go b/vendor/github.com/emicklei/go-restful/parameter.go deleted file mode 100644 index febe2cc1702..00000000000 --- a/vendor/github.com/emicklei/go-restful/parameter.go +++ /dev/null @@ -1,151 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -const ( - // PathParameterKind = indicator of Request parameter type "path" - PathParameterKind = iota - - // QueryParameterKind = indicator of Request parameter type "query" - QueryParameterKind - - // BodyParameterKind = indicator of Request parameter type "body" - BodyParameterKind - - // HeaderParameterKind = indicator of Request parameter type "header" - HeaderParameterKind - - // FormParameterKind = indicator of Request parameter type "form" - FormParameterKind - - // MultiPartFormParameterKind = indicator of Request parameter type "multipart/form-data" - MultiPartFormParameterKind - - // CollectionFormatCSV comma separated values `foo,bar` - CollectionFormatCSV = CollectionFormat("csv") - - // CollectionFormatSSV space separated values `foo bar` - CollectionFormatSSV = CollectionFormat("ssv") - - // CollectionFormatTSV tab separated values `foo\tbar` - CollectionFormatTSV = CollectionFormat("tsv") - - // CollectionFormatPipes pipe separated values `foo|bar` - CollectionFormatPipes = CollectionFormat("pipes") - - // CollectionFormatMulti corresponds to multiple parameter instances instead of multiple values for a single - // instance `foo=bar&foo=baz`. This is valid only for QueryParameters and FormParameters - CollectionFormatMulti = CollectionFormat("multi") -) - -type CollectionFormat string - -func (cf CollectionFormat) String() string { - return string(cf) -} - -// Parameter is for documententing the parameter used in a Http Request -// ParameterData kinds are Path,Query and Body -type Parameter struct { - data *ParameterData -} - -// ParameterData represents the state of a Parameter. -// It is made public to make it accessible to e.g. the Swagger package. -type ParameterData struct { - Name, Description, DataType, DataFormat string - Kind int - Required bool - AllowableValues map[string]string - AllowMultiple bool - DefaultValue string - CollectionFormat string -} - -// Data returns the state of the Parameter -func (p *Parameter) Data() ParameterData { - return *p.data -} - -// Kind returns the parameter type indicator (see const for valid values) -func (p *Parameter) Kind() int { - return p.data.Kind -} - -func (p *Parameter) bePath() *Parameter { - p.data.Kind = PathParameterKind - return p -} -func (p *Parameter) beQuery() *Parameter { - p.data.Kind = QueryParameterKind - return p -} -func (p *Parameter) beBody() *Parameter { - p.data.Kind = BodyParameterKind - return p -} - -func (p *Parameter) beHeader() *Parameter { - p.data.Kind = HeaderParameterKind - return p -} - -func (p *Parameter) beForm() *Parameter { - p.data.Kind = FormParameterKind - return p -} - -func (p *Parameter) beMultiPartForm() *Parameter { - p.data.Kind = MultiPartFormParameterKind - return p -} - -// Required sets the required field and returns the receiver -func (p *Parameter) Required(required bool) *Parameter { - p.data.Required = required - return p -} - -// AllowMultiple sets the allowMultiple field and returns the receiver -func (p *Parameter) AllowMultiple(multiple bool) *Parameter { - p.data.AllowMultiple = multiple - return p -} - -// AllowableValues sets the allowableValues field and returns the receiver -func (p *Parameter) AllowableValues(values map[string]string) *Parameter { - p.data.AllowableValues = values - return p -} - -// DataType sets the dataType field and returns the receiver -func (p *Parameter) DataType(typeName string) *Parameter { - p.data.DataType = typeName - return p -} - -// DataFormat sets the dataFormat field for Swagger UI -func (p *Parameter) DataFormat(formatName string) *Parameter { - p.data.DataFormat = formatName - return p -} - -// DefaultValue sets the default value field and returns the receiver -func (p *Parameter) DefaultValue(stringRepresentation string) *Parameter { - p.data.DefaultValue = stringRepresentation - return p -} - -// Description sets the description value field and returns the receiver -func (p *Parameter) Description(doc string) *Parameter { - p.data.Description = doc - return p -} - -// CollectionFormat sets the collection format for an array type -func (p *Parameter) CollectionFormat(format CollectionFormat) *Parameter { - p.data.CollectionFormat = format.String() - return p -} diff --git a/vendor/github.com/emicklei/go-restful/response.go b/vendor/github.com/emicklei/go-restful/response.go deleted file mode 100644 index 8f0b56aa2da..00000000000 --- a/vendor/github.com/emicklei/go-restful/response.go +++ /dev/null @@ -1,256 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bufio" - "errors" - "net" - "net/http" -) - -// DefaultResponseMimeType is DEPRECATED, use DefaultResponseContentType(mime) -var DefaultResponseMimeType string - -//PrettyPrintResponses controls the indentation feature of XML and JSON serialization -var PrettyPrintResponses = true - -// Response is a wrapper on the actual http ResponseWriter -// It provides several convenience methods to prepare and write response content. -type Response struct { - http.ResponseWriter - requestAccept string // mime-type what the Http Request says it wants to receive - routeProduces []string // mime-types what the Route says it can produce - statusCode int // HTTP status code that has been written explicitly (if zero then net/http has written 200) - contentLength int // number of bytes written for the response body - prettyPrint bool // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses. - err error // err property is kept when WriteError is called - hijacker http.Hijacker // if underlying ResponseWriter supports it -} - -// NewResponse creates a new response based on a http ResponseWriter. -func NewResponse(httpWriter http.ResponseWriter) *Response { - hijacker, _ := httpWriter.(http.Hijacker) - return &Response{ResponseWriter: httpWriter, routeProduces: []string{}, statusCode: http.StatusOK, prettyPrint: PrettyPrintResponses, hijacker: hijacker} -} - -// DefaultResponseContentType set a default. -// If Accept header matching fails, fall back to this type. -// Valid values are restful.MIME_JSON and restful.MIME_XML -// Example: -// restful.DefaultResponseContentType(restful.MIME_JSON) -func DefaultResponseContentType(mime string) { - DefaultResponseMimeType = mime -} - -// InternalServerError writes the StatusInternalServerError header. -// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason) -func (r Response) InternalServerError() Response { - r.WriteHeader(http.StatusInternalServerError) - return r -} - -// Hijack implements the http.Hijacker interface. This expands -// the Response to fulfill http.Hijacker if the underlying -// http.ResponseWriter supports it. -func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { - if r.hijacker == nil { - return nil, nil, errors.New("http.Hijacker not implemented by underlying http.ResponseWriter") - } - return r.hijacker.Hijack() -} - -// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output. -func (r *Response) PrettyPrint(bePretty bool) { - r.prettyPrint = bePretty -} - -// AddHeader is a shortcut for .Header().Add(header,value) -func (r Response) AddHeader(header string, value string) Response { - r.Header().Add(header, value) - return r -} - -// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing. -func (r *Response) SetRequestAccepts(mime string) { - r.requestAccept = mime -} - -// EntityWriter returns the registered EntityWriter that the entity (requested resource) -// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say. -// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable. -func (r *Response) EntityWriter() (EntityReaderWriter, bool) { - sorted := sortedMimes(r.requestAccept) - for _, eachAccept := range sorted { - for _, eachProduce := range r.routeProduces { - if eachProduce == eachAccept.media { - if w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok { - return w, true - } - } - } - if eachAccept.media == "*/*" { - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - } - } - // if requestAccept is empty - writer, ok := entityAccessRegistry.accessorAt(r.requestAccept) - if !ok { - // if not registered then fallback to the defaults (if set) - if DefaultResponseMimeType == MIME_JSON { - return entityAccessRegistry.accessorAt(MIME_JSON) - } - if DefaultResponseMimeType == MIME_XML { - return entityAccessRegistry.accessorAt(MIME_XML) - } - // Fallback to whatever the route says it can produce. - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - if trace { - traceLogger.Printf("no registered EntityReaderWriter found for %s", r.requestAccept) - } - } - return writer, ok -} - -// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200) -func (r *Response) WriteEntity(value interface{}) error { - return r.WriteHeaderAndEntity(http.StatusOK, value) -} - -// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters. -// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces. -// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header. -// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead. -// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written. -// Current implementation ignores any q-parameters in the Accept Header. -// Returns an error if the value could not be written on the response. -func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error { - writer, ok := r.EntityWriter() - if !ok { - r.WriteHeader(http.StatusNotAcceptable) - return nil - } - return writer.Write(r, status, value) -} - -// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsXml(value interface{}) error { - return writeXML(r, http.StatusOK, MIME_XML, value) -} - -// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndXml(status int, value interface{}) error { - return writeXML(r, status, MIME_XML, value) -} - -// WriteAsJson is a convenience method for writing a value in json. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsJson(value interface{}) error { - return writeJSON(r, http.StatusOK, MIME_JSON, value) -} - -// WriteJson is a convenience method for writing a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteJson(value interface{}, contentType string) error { - return writeJSON(r, http.StatusOK, contentType, value) -} - -// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error { - return writeJSON(r, status, contentType, value) -} - -// WriteError writes the http status and the error string on the response. err can be nil. -// Return an error if writing was not successful. -func (r *Response) WriteError(httpStatus int, err error) (writeErr error) { - r.err = err - if err == nil { - writeErr = r.WriteErrorString(httpStatus, "") - } else { - writeErr = r.WriteErrorString(httpStatus, err.Error()) - } - return writeErr -} - -// WriteServiceError is a convenience method for a responding with a status and a ServiceError -func (r *Response) WriteServiceError(httpStatus int, err ServiceError) error { - r.err = err - return r.WriteHeaderAndEntity(httpStatus, err) -} - -// WriteErrorString is a convenience method for an error status with the actual error -func (r *Response) WriteErrorString(httpStatus int, errorReason string) error { - if r.err == nil { - // if not called from WriteError - r.err = errors.New(errorReason) - } - r.WriteHeader(httpStatus) - if _, err := r.Write([]byte(errorReason)); err != nil { - return err - } - return nil -} - -// Flush implements http.Flusher interface, which sends any buffered data to the client. -func (r *Response) Flush() { - if f, ok := r.ResponseWriter.(http.Flusher); ok { - f.Flush() - } else if trace { - traceLogger.Printf("ResponseWriter %v doesn't support Flush", r) - } -} - -// WriteHeader is overridden to remember the Status Code that has been written. -// Changes to the Header of the response have no effect after this. -func (r *Response) WriteHeader(httpStatus int) { - r.statusCode = httpStatus - r.ResponseWriter.WriteHeader(httpStatus) -} - -// StatusCode returns the code that has been written using WriteHeader. -func (r Response) StatusCode() int { - if 0 == r.statusCode { - // no status code has been written yet; assume OK - return http.StatusOK - } - return r.statusCode -} - -// Write writes the data to the connection as part of an HTTP reply. -// Write is part of http.ResponseWriter interface. -func (r *Response) Write(bytes []byte) (int, error) { - written, err := r.ResponseWriter.Write(bytes) - r.contentLength += written - return written, err -} - -// ContentLength returns the number of bytes written for the response content. -// Note that this value is only correct if all data is written through the Response using its Write* methods. -// Data written directly using the underlying http.ResponseWriter is not accounted for. -func (r Response) ContentLength() int { - return r.contentLength -} - -// CloseNotify is part of http.CloseNotifier interface -func (r Response) CloseNotify() <-chan bool { - return r.ResponseWriter.(http.CloseNotifier).CloseNotify() -} - -// Error returns the err created by WriteError -func (r Response) Error() error { - return r.err -} diff --git a/vendor/github.com/emicklei/go-restful/.gitignore b/vendor/github.com/emicklei/go-restful/v3/.gitignore similarity index 100% rename from vendor/github.com/emicklei/go-restful/.gitignore rename to vendor/github.com/emicklei/go-restful/v3/.gitignore diff --git a/vendor/github.com/emicklei/go-restful/v3/.goconvey b/vendor/github.com/emicklei/go-restful/v3/.goconvey new file mode 100644 index 00000000000..8485e986e45 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/.goconvey @@ -0,0 +1 @@ +ignore \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/.travis.yml b/vendor/github.com/emicklei/go-restful/v3/.travis.yml similarity index 100% rename from vendor/github.com/emicklei/go-restful/.travis.yml rename to vendor/github.com/emicklei/go-restful/v3/.travis.yml diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md new file mode 100644 index 00000000000..02a73ccfd1a --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -0,0 +1,387 @@ +# Change history of go-restful + +## [v3.10.1] - 2022-11-19 + +- fix broken 3.10.0 by using path package for joining paths + +## [v3.10.0] - 2022-10-11 - BROKEN + +- changed tokenizer to match std route match behavior; do not trimright the path (#511) +- Add MIME_ZIP (#512) +- Add MIME_ZIP and HEADER_ContentDisposition (#513) +- Changed how to get query parameter issue #510 + +## [v3.9.0] - 2022-07-21 + +- add support for http.Handler implementations to work as FilterFunction, issue #504 (thanks to https://github.com/ggicci) + +## [v3.8.0] - 2022-06-06 + +- use exact matching of allowed domain entries, issue #489 (#493) + - this changes fixes [security] Authorization Bypass Through User-Controlled Key + by changing the behaviour of the AllowedDomains setting in the CORS filter. + To support the previous behaviour, the CORS filter type now has a AllowedDomainFunc + callback mechanism which is called when a simple domain match fails. +- add test and fix for POST without body and Content-type, issue #492 (#496) +- [Minor] Bad practice to have a mix of Receiver types. (#491) + +## [v3.7.2] - 2021-11-24 + +- restored FilterChain (#482 by SVilgelm) + + +## [v3.7.1] - 2021-10-04 + +- fix problem with contentEncodingEnabled setting (#479) + +## [v3.7.0] - 2021-09-24 + +- feat(parameter): adds additional openapi mappings (#478) + +## [v3.6.0] - 2021-09-18 + +- add support for vendor extensions (#477 thx erraggy) + +## [v3.5.2] - 2021-07-14 + +- fix removing absent route from webservice (#472) + +## [v3.5.1] - 2021-04-12 + +- fix handling no match access selected path +- remove obsolete field + +## [v3.5.0] - 2021-04-10 + +- add check for wildcard (#463) in CORS +- add access to Route from Request, issue #459 (#462) + +## [v3.4.0] - 2020-11-10 + +- Added OPTIONS to WebService + +## [v3.3.2] - 2020-01-23 + +- Fixed duplicate compression in dispatch. #449 + + +## [v3.3.1] - 2020-08-31 + +- Added check on writer to prevent compression of response twice. #447 + +## [v3.3.0] - 2020-08-19 + +- Enable content encoding on Handle and ServeHTTP (#446) +- List available representations in 406 body (#437) +- Convert to string using rune() (#443) + +## [v3.2.0] - 2020-06-21 + +- 405 Method Not Allowed must have Allow header (#436) (thx Bracken ) +- add field allowedMethodsWithoutContentType (#424) + +## [v3.1.0] + +- support describing response headers (#426) +- fix openapi examples (#425) + +v3.0.0 + +- fix: use request/response resulting from filter chain +- add Go module + Module consumer should use github.com/emicklei/go-restful/v3 as import path + +v2.10.0 + +- support for Custom Verbs (thanks Vinci Xu <277040271@qq.com>) +- fixed static example (thanks Arthur ) +- simplify code (thanks Christian Muehlhaeuser ) +- added JWT HMAC with SHA-512 authentication code example (thanks Amim Knabben ) + +v2.9.6 + +- small optimization in filter code + +v2.11.1 + +- fix WriteError return value (#415) + +v2.11.0 + +- allow prefix and suffix in path variable expression (#414) + +v2.9.6 + +- support google custome verb (#413) + +v2.9.5 + +- fix panic in Response.WriteError if err == nil + +v2.9.4 + +- fix issue #400 , parsing mime type quality +- Route Builder added option for contentEncodingEnabled (#398) + +v2.9.3 + +- Avoid return of 415 Unsupported Media Type when request body is empty (#396) + +v2.9.2 + +- Reduce allocations in per-request methods to improve performance (#395) + +v2.9.1 + +- Fix issue with default responses and invalid status code 0. (#393) + +v2.9.0 + +- add per Route content encoding setting (overrides container setting) + +v2.8.0 + +- add Request.QueryParameters() +- add json-iterator (via build tag) +- disable vgo module (until log is moved) + +v2.7.1 + +- add vgo module + +v2.6.1 + +- add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+) + +v2.6.0 + +- Make JSR 311 routing and path param processing consistent +- Adding description to RouteBuilder.Reads() +- Update example for Swagger12 and OpenAPI + +2017-09-13 + +- added route condition functions using `.If(func)` in route building. + +2017-02-16 + +- solved issue #304, make operation names unique + +2017-01-30 + + [IMPORTANT] For swagger users, change your import statement to: + swagger "github.com/emicklei/go-restful-swagger12" + +- moved swagger 1.2 code to go-restful-swagger12 +- created TAG 2.0.0 + +2017-01-27 + +- remove defer request body close +- expose Dispatch for testing filters and Routefunctions +- swagger response model cannot be array +- created TAG 1.0.0 + +2016-12-22 + +- (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool) + +2016-11-26 + +- Default change! now use CurlyRouter (was RouterJSR311) +- Default change! no more caching of request content +- Default change! do not recover from panics + +2016-09-22 + +- fix the DefaultRequestContentType feature + +2016-02-14 + +- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response +- add constructors for custom entity accessors for xml and json + +2015-09-27 + +- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency + +2015-09-25 + +- fixed problem with changing Header after WriteHeader (issue 235) + +2015-09-14 + +- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write) +- added support for custom EntityReaderWriters. + +2015-08-06 + +- add support for reading entities from compressed request content +- use sync.Pool for compressors of http response and request body +- add Description to Parameter for documentation in Swagger UI + +2015-03-20 + +- add configurable logging + +2015-03-18 + +- if not specified, the Operation is derived from the Route function + +2015-03-17 + +- expose Parameter creation functions +- make trace logger an interface +- fix OPTIONSFilter +- customize rendering of ServiceError +- JSR311 router now handles wildcards +- add Notes to Route + +2014-11-27 + +- (api add) PrettyPrint per response. (as proposed in #167) + +2014-11-12 + +- (api add) ApiVersion(.) for documentation in Swagger UI + +2014-11-10 + +- (api change) struct fields tagged with "description" show up in Swagger UI + +2014-10-31 + +- (api change) ReturnsError -> Returns +- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder +- fix swagger nested structs +- sort Swagger response messages by code + +2014-10-23 + +- (api add) ReturnsError allows you to document Http codes in swagger +- fixed problem with greedy CurlyRouter +- (api add) Access-Control-Max-Age in CORS +- add tracing functionality (injectable) for debugging purposes +- support JSON parse 64bit int +- fix empty parameters for swagger +- WebServicesUrl is now optional for swagger +- fixed duplicate AccessControlAllowOrigin in CORS +- (api change) expose ServeMux in container +- (api add) added AllowedDomains in CORS +- (api add) ParameterNamed for detailed documentation + +2014-04-16 + +- (api add) expose constructor of Request for testing. + +2014-06-27 + +- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification). +- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons). + +2014-07-03 + +- (api add) CORS can be configured with a list of allowed domains + +2014-03-12 + +- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter) + +2014-02-26 + +- (api add) Request now provides information about the matched Route, see method SelectedRoutePath + +2014-02-17 + +- (api change) renamed parameter constants (go-lint checks) + +2014-01-10 + +- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier + +2014-01-07 + +- (api change) Write* methods in Response now return the error or nil. +- added example of serving HTML from a Go template. +- fixed comparing Allowed headers in CORS (is now case-insensitive) + +2013-11-13 + +- (api add) Response knows how many bytes are written to the response body. + +2013-10-29 + +- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information. + +2013-10-04 + +- (api add) Response knows what HTTP status has been written +- (api add) Request can have attributes (map of string->interface, also called request-scoped variables + +2013-09-12 + +- (api change) Router interface simplified +- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths + +2013-08-05 + - add OPTIONS support + - add CORS support + +2013-08-27 + +- fixed some reported issues (see github) +- (api change) deprecated use of WriteError; use WriteErrorString instead + +2014-04-15 + +- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString + +2013-08-08 + +- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer. +- (api add) the swagger package has be extended to have a UI per container. +- if panic is detected then a small stack trace is printed (thanks to runner-mei) +- (api add) WriteErrorString to Response + +Important API changes: + +- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead. +- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead. + + +2013-07-06 + +- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature. + +2013-06-19 + +- (improve) DoNotRecover option, moved request body closer, improved ReadEntity + +2013-06-03 + +- (api change) removed Dispatcher interface, hide PathExpression +- changed receiver names of type functions to be more idiomatic Go + +2013-06-02 + +- (optimize) Cache the RegExp compilation of Paths. + +2013-05-22 + +- (api add) Added support for request/response filter functions + +2013-05-18 + + +- (api add) Added feature to change the default Http Request Dispatch function (travis cline) +- (api change) Moved Swagger Webservice to swagger package (see example restful-user) + +[2012-11-14 .. 2013-05-18> + +- See https://github.com/emicklei/go-restful/commits + +2012-11-14 + +- Initial commit + + diff --git a/vendor/github.com/emicklei/go-restful/LICENSE b/vendor/github.com/emicklei/go-restful/v3/LICENSE similarity index 100% rename from vendor/github.com/emicklei/go-restful/LICENSE rename to vendor/github.com/emicklei/go-restful/v3/LICENSE diff --git a/vendor/github.com/emicklei/go-restful/v3/Makefile b/vendor/github.com/emicklei/go-restful/v3/Makefile new file mode 100644 index 00000000000..16d0b80bb0f --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/Makefile @@ -0,0 +1,8 @@ +all: test + +test: + go vet . + go test -cover -v . + +ex: + find ./examples -type f -name "*.go" | xargs -I {} go build -o /tmp/ignore {} \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md new file mode 100644 index 00000000000..0625359dc40 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -0,0 +1,111 @@ +go-restful +========== +package for building REST-style Web Services using Google Go + +[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) +[![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) +[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) +[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) + +- [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples) + +REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping: + +- GET = Retrieve a representation of a resource +- POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm. +- PUT = Create if you are sending the full content of the specified resource (URI). +- PUT = Update if you are updating the full content of the specified resource. +- DELETE = Delete if you are requesting the server to delete the resource +- PATCH = Update partial content of a resource +- OPTIONS = Get information about the communication options for the request URI + +### Usage + +#### Without Go Modules + +All versions up to `v2.*.*` (on the master) are not supporting Go modules. + +``` +import ( + restful "github.com/emicklei/go-restful" +) +``` + +#### Using Go Modules + +As of version `v3.0.0` (on the v3 branch), this package supports Go modules. + +``` +import ( + restful "github.com/emicklei/go-restful/v3" +) +``` + +### Example + +```Go +ws := new(restful.WebService) +ws. + Path("/users"). + Consumes(restful.MIME_XML, restful.MIME_JSON). + Produces(restful.MIME_JSON, restful.MIME_XML) + +ws.Route(ws.GET("/{user-id}").To(u.findUser). + Doc("get a user"). + Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). + Writes(User{})) +... + +func (u UserResource) findUser(request *restful.Request, response *restful.Response) { + id := request.PathParameter("user-id") + ... +} +``` + +[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) + +### Features + +- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support +- Configurable router: + - (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*}) + - Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions +- Request API for reading structs from JSON/XML and accessing parameters (path,query,header) +- Response API for writing structs to JSON/XML and setting headers +- Customizable encoding using EntityReaderWriter registration +- Filters for intercepting the request → response flow on Service or Route level +- Request-scoped variables using attributes +- Containers for WebServices on different HTTP endpoints +- Content encoding (gzip,deflate) of request and response payloads +- Automatic responses on OPTIONS (using a filter) +- Automatic CORS request handling (using a filter) +- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12)) +- Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) +- Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) +- Configurable (trace) logging +- Customizable gzip/deflate readers and writers using CompressorProvider registration +- Inject your own http.Handler using the `HttpMiddlewareHandlerToFilter` function + +## How to customize +There are several hooks to customize the behavior of the go-restful package. + +- Router algorithm +- Panic recovery +- JSON decoder +- Trace logging +- Compression +- Encoders for other serializers +- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` + +## Resources + +- [Example programs](./examples) +- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/) +- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/) +- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful) +- [showcase: Zazkia - tcp proxy for testing resiliency](https://github.com/emicklei/zazkia) +- [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora) + +Type ```git shortlog -s``` for a full list of contributors. + +© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/v3/SECURITY.md b/vendor/github.com/emicklei/go-restful/v3/SECURITY.md new file mode 100644 index 00000000000..810d3b51089 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| v3.7.x | :white_check_mark: | +| < v3.0.1 | :x: | + +## Reporting a Vulnerability + +Create an Issue and put the label `[security]` in the title of the issue. +Valid reported security issues are expected to be solved within a week. diff --git a/vendor/github.com/emicklei/go-restful/Srcfile b/vendor/github.com/emicklei/go-restful/v3/Srcfile similarity index 100% rename from vendor/github.com/emicklei/go-restful/Srcfile rename to vendor/github.com/emicklei/go-restful/v3/Srcfile diff --git a/vendor/github.com/emicklei/go-restful/bench_test.sh b/vendor/github.com/emicklei/go-restful/v3/bench_test.sh similarity index 100% rename from vendor/github.com/emicklei/go-restful/bench_test.sh rename to vendor/github.com/emicklei/go-restful/v3/bench_test.sh diff --git a/vendor/github.com/emicklei/go-restful/compress.go b/vendor/github.com/emicklei/go-restful/v3/compress.go similarity index 92% rename from vendor/github.com/emicklei/go-restful/compress.go rename to vendor/github.com/emicklei/go-restful/v3/compress.go index 220b37712f5..1ff239f99fe 100644 --- a/vendor/github.com/emicklei/go-restful/compress.go +++ b/vendor/github.com/emicklei/go-restful/v3/compress.go @@ -83,7 +83,11 @@ func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error } // WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested. -func wantsCompressedResponse(httpRequest *http.Request) (bool, string) { +// It also inspects the httpWriter whether its content-encoding is already set (non-empty). +func wantsCompressedResponse(httpRequest *http.Request, httpWriter http.ResponseWriter) (bool, string) { + if contentEncoding := httpWriter.Header().Get(HEADER_ContentEncoding); contentEncoding != "" { + return false, "" + } header := httpRequest.Header.Get(HEADER_AcceptEncoding) gi := strings.Index(header, ENCODING_GZIP) zi := strings.Index(header, ENCODING_DEFLATE) diff --git a/vendor/github.com/emicklei/go-restful/compressor_cache.go b/vendor/github.com/emicklei/go-restful/v3/compressor_cache.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/compressor_cache.go rename to vendor/github.com/emicklei/go-restful/v3/compressor_cache.go diff --git a/vendor/github.com/emicklei/go-restful/compressor_pools.go b/vendor/github.com/emicklei/go-restful/v3/compressor_pools.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/compressor_pools.go rename to vendor/github.com/emicklei/go-restful/v3/compressor_pools.go diff --git a/vendor/github.com/emicklei/go-restful/compressors.go b/vendor/github.com/emicklei/go-restful/v3/compressors.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/compressors.go rename to vendor/github.com/emicklei/go-restful/v3/compressors.go diff --git a/vendor/github.com/emicklei/go-restful/constants.go b/vendor/github.com/emicklei/go-restful/v3/constants.go similarity index 89% rename from vendor/github.com/emicklei/go-restful/constants.go rename to vendor/github.com/emicklei/go-restful/v3/constants.go index 203439c5e5f..2328bde6c7a 100644 --- a/vendor/github.com/emicklei/go-restful/constants.go +++ b/vendor/github.com/emicklei/go-restful/v3/constants.go @@ -7,12 +7,14 @@ package restful const ( MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() + MIME_ZIP = "application/zip" // Accept or Content-Type used in Consumes() and/or Produces() MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default HEADER_Allow = "Allow" HEADER_Accept = "Accept" HEADER_Origin = "Origin" HEADER_ContentType = "Content-Type" + HEADER_ContentDisposition = "Content-Disposition" HEADER_LastModified = "Last-Modified" HEADER_AcceptEncoding = "Accept-Encoding" HEADER_ContentEncoding = "Content-Encoding" diff --git a/vendor/github.com/emicklei/go-restful/v3/container.go b/vendor/github.com/emicklei/go-restful/v3/container.go new file mode 100644 index 00000000000..dd56246ddca --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/container.go @@ -0,0 +1,450 @@ +package restful + +// Copyright 2013 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + +import ( + "bytes" + "errors" + "fmt" + "net/http" + "os" + "runtime" + "strings" + "sync" + + "github.com/emicklei/go-restful/v3/log" +) + +// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests. +// The requests are further dispatched to routes of WebServices using a RouteSelector +type Container struct { + webServicesLock sync.RWMutex + webServices []*WebService + ServeMux *http.ServeMux + isRegisteredOnRoot bool + containerFilters []FilterFunction + doNotRecover bool // default is true + recoverHandleFunc RecoverHandleFunction + serviceErrorHandleFunc ServiceErrorHandleFunction + router RouteSelector // default is a CurlyRouter (RouterJSR311 is a slower alternative) + contentEncodingEnabled bool // default is false +} + +// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter) +func NewContainer() *Container { + return &Container{ + webServices: []*WebService{}, + ServeMux: http.NewServeMux(), + isRegisteredOnRoot: false, + containerFilters: []FilterFunction{}, + doNotRecover: true, + recoverHandleFunc: logStackOnRecover, + serviceErrorHandleFunc: writeServiceError, + router: CurlyRouter{}, + contentEncodingEnabled: false} +} + +// RecoverHandleFunction declares functions that can be used to handle a panic situation. +// The first argument is what recover() returns. The second must be used to communicate an error response. +type RecoverHandleFunction func(interface{}, http.ResponseWriter) + +// RecoverHandler changes the default function (logStackOnRecover) to be called +// when a panic is detected. DoNotRecover must be have its default value (=false). +func (c *Container) RecoverHandler(handler RecoverHandleFunction) { + c.recoverHandleFunc = handler +} + +// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation. +// The first argument is the service error, the second is the request that resulted in the error and +// the third must be used to communicate an error response. +type ServiceErrorHandleFunction func(ServiceError, *Request, *Response) + +// ServiceErrorHandler changes the default function (writeServiceError) to be called +// when a ServiceError is detected. +func (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) { + c.serviceErrorHandleFunc = handler +} + +// DoNotRecover controls whether panics will be caught to return HTTP 500. +// If set to true, Route functions are responsible for handling any error situation. +// Default value is true. +func (c *Container) DoNotRecover(doNot bool) { + c.doNotRecover = doNot +} + +// Router changes the default Router (currently CurlyRouter) +func (c *Container) Router(aRouter RouteSelector) { + c.router = aRouter +} + +// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. +func (c *Container) EnableContentEncoding(enabled bool) { + c.contentEncodingEnabled = enabled +} + +// Add a WebService to the Container. It will detect duplicate root paths and exit in that case. +func (c *Container) Add(service *WebService) *Container { + c.webServicesLock.Lock() + defer c.webServicesLock.Unlock() + + // if rootPath was not set then lazy initialize it + if len(service.rootPath) == 0 { + service.Path("/") + } + + // cannot have duplicate root paths + for _, each := range c.webServices { + if each.RootPath() == service.RootPath() { + log.Printf("WebService with duplicate root path detected:['%v']", each) + os.Exit(1) + } + } + + // If not registered on root then add specific mapping + if !c.isRegisteredOnRoot { + c.isRegisteredOnRoot = c.addHandler(service, c.ServeMux) + } + c.webServices = append(c.webServices, service) + return c +} + +// addHandler may set a new HandleFunc for the serveMux +// this function must run inside the critical region protected by the webServicesLock. +// returns true if the function was registered on root ("/") +func (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool { + pattern := fixedPrefixPath(service.RootPath()) + // check if root path registration is needed + if "/" == pattern || "" == pattern { + serveMux.HandleFunc("/", c.dispatch) + return true + } + // detect if registration already exists + alreadyMapped := false + for _, each := range c.webServices { + if each.RootPath() == service.RootPath() { + alreadyMapped = true + break + } + } + if !alreadyMapped { + serveMux.HandleFunc(pattern, c.dispatch) + if !strings.HasSuffix(pattern, "/") { + serveMux.HandleFunc(pattern+"/", c.dispatch) + } + } + return false +} + +func (c *Container) Remove(ws *WebService) error { + if c.ServeMux == http.DefaultServeMux { + errMsg := fmt.Sprintf("cannot remove a WebService from a Container using the DefaultServeMux: ['%v']", ws) + log.Print(errMsg) + return errors.New(errMsg) + } + c.webServicesLock.Lock() + defer c.webServicesLock.Unlock() + // build a new ServeMux and re-register all WebServices + newServeMux := http.NewServeMux() + newServices := []*WebService{} + newIsRegisteredOnRoot := false + for _, each := range c.webServices { + if each.rootPath != ws.rootPath { + // If not registered on root then add specific mapping + if !newIsRegisteredOnRoot { + newIsRegisteredOnRoot = c.addHandler(each, newServeMux) + } + newServices = append(newServices, each) + } + } + c.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot + return nil +} + +// logStackOnRecover is the default RecoverHandleFunction and is called +// when DoNotRecover is false and the recoverHandleFunc is not set for the container. +// Default implementation logs the stacktrace and writes the stacktrace on the response. +// This may be a security issue as it exposes sourcecode information. +func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) { + var buffer bytes.Buffer + buffer.WriteString(fmt.Sprintf("recover from panic situation: - %v\r\n", panicReason)) + for i := 2; ; i += 1 { + _, file, line, ok := runtime.Caller(i) + if !ok { + break + } + buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line)) + } + log.Print(buffer.String()) + httpWriter.WriteHeader(http.StatusInternalServerError) + httpWriter.Write(buffer.Bytes()) +} + +// writeServiceError is the default ServiceErrorHandleFunction and is called +// when a ServiceError is returned during route selection. Default implementation +// calls resp.WriteErrorString(err.Code, err.Message) +func writeServiceError(err ServiceError, req *Request, resp *Response) { + for header, values := range err.Header { + for _, value := range values { + resp.Header().Add(header, value) + } + } + resp.WriteErrorString(err.Code, err.Message) +} + +// Dispatch the incoming Http Request to a matching WebService. +func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { + if httpWriter == nil { + panic("httpWriter cannot be nil") + } + if httpRequest == nil { + panic("httpRequest cannot be nil") + } + c.dispatch(httpWriter, httpRequest) +} + +// Dispatch the incoming Http Request to a matching WebService. +func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // so we can assign a compressing one later + writer := httpWriter + + // CompressingResponseWriter should be closed after all operations are done + defer func() { + if compressWriter, ok := writer.(*CompressingResponseWriter); ok { + compressWriter.Close() + } + }() + + // Instal panic recovery unless told otherwise + if !c.doNotRecover { // catch all for 500 response + defer func() { + if r := recover(); r != nil { + c.recoverHandleFunc(r, writer) + return + } + }() + } + + // Find best match Route ; err is non nil if no match was found + var webService *WebService + var route *Route + var err error + func() { + c.webServicesLock.RLock() + defer c.webServicesLock.RUnlock() + webService, route, err = c.router.SelectRoute( + c.webServices, + httpRequest) + }() + if err != nil { + // a non-200 response (may be compressed) has already been written + // run container filters anyway ; they should not touch the response... + chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { + switch err.(type) { + case ServiceError: + ser := err.(ServiceError) + c.serviceErrorHandleFunc(ser, req, resp) + } + // TODO + }} + chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer)) + return + } + + // Unless httpWriter is already an CompressingResponseWriter see if we need to install one + if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing { + // Detect if compression is needed + // assume without compression, test for override + contentEncodingEnabled := c.contentEncodingEnabled + if route != nil && route.contentEncodingEnabled != nil { + contentEncodingEnabled = *route.contentEncodingEnabled + } + if contentEncodingEnabled { + doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + } + } + + pathProcessor, routerProcessesPath := c.router.(PathProcessor) + if !routerProcessesPath { + pathProcessor = defaultPathProcessor{} + } + pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path) + wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams) + // pass through filters (if any) + if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 { + // compose filter chain + allFilters := make([]FilterFunction, 0, size) + allFilters = append(allFilters, c.containerFilters...) + allFilters = append(allFilters, webService.filters...) + allFilters = append(allFilters, route.Filters...) + chain := FilterChain{ + Filters: allFilters, + Target: route.Function, + ParameterDocs: route.ParameterDocs, + Operation: route.Operation, + } + chain.ProcessFilter(wrappedRequest, wrappedResponse) + } else { + // no filters, handle request by route + route.Function(wrappedRequest, wrappedResponse) + } +} + +// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {} +func fixedPrefixPath(pathspec string) string { + varBegin := strings.Index(pathspec, "{") + if -1 == varBegin { + return pathspec + } + return pathspec[:varBegin] +} + +// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server +func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // Skip, if content encoding is disabled + if !c.contentEncodingEnabled { + c.ServeMux.ServeHTTP(httpWriter, httpRequest) + return + } + // content encoding is enabled + + // Skip, if httpWriter is already an CompressingResponseWriter + if _, ok := httpWriter.(*CompressingResponseWriter); ok { + c.ServeMux.ServeHTTP(httpWriter, httpRequest) + return + } + + writer := httpWriter + // CompressingResponseWriter should be closed after all operations are done + defer func() { + if compressWriter, ok := writer.(*CompressingResponseWriter); ok { + compressWriter.Close() + } + }() + + doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + + c.ServeMux.ServeHTTP(writer, httpRequest) +} + +// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. +func (c *Container) Handle(pattern string, handler http.Handler) { + c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) { + // Skip, if httpWriter is already an CompressingResponseWriter + if _, ok := httpWriter.(*CompressingResponseWriter); ok { + handler.ServeHTTP(httpWriter, httpRequest) + return + } + + writer := httpWriter + + // CompressingResponseWriter should be closed after all operations are done + defer func() { + if compressWriter, ok := writer.(*CompressingResponseWriter); ok { + compressWriter.Close() + } + }() + + if c.contentEncodingEnabled { + doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) + if doCompress { + var err error + writer, err = NewCompressingResponseWriter(httpWriter, encoding) + if err != nil { + log.Print("unable to install compressor: ", err) + httpWriter.WriteHeader(http.StatusInternalServerError) + return + } + } + } + + handler.ServeHTTP(writer, httpRequest) + })) +} + +// HandleWithFilter registers the handler for the given pattern. +// Container's filter chain is applied for handler. +// If a handler already exists for pattern, HandleWithFilter panics. +func (c *Container) HandleWithFilter(pattern string, handler http.Handler) { + f := func(httpResponse http.ResponseWriter, httpRequest *http.Request) { + if len(c.containerFilters) == 0 { + handler.ServeHTTP(httpResponse, httpRequest) + return + } + + chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { + handler.ServeHTTP(resp, req.Request) + }} + chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse)) + } + + c.Handle(pattern, http.HandlerFunc(f)) +} + +// Filter appends a container FilterFunction. These are called before dispatching +// a http.Request to a WebService from the container +func (c *Container) Filter(filter FilterFunction) { + c.containerFilters = append(c.containerFilters, filter) +} + +// RegisteredWebServices returns the collections of added WebServices +func (c *Container) RegisteredWebServices() []*WebService { + c.webServicesLock.RLock() + defer c.webServicesLock.RUnlock() + result := make([]*WebService, len(c.webServices)) + for ix := range c.webServices { + result[ix] = c.webServices[ix] + } + return result +} + +// computeAllowedMethods returns a list of HTTP methods that are valid for a Request +func (c *Container) computeAllowedMethods(req *Request) []string { + // Go through all RegisteredWebServices() and all its Routes to collect the options + methods := []string{} + requestPath := req.Request.URL.Path + for _, ws := range c.RegisteredWebServices() { + matches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath) + if matches != nil { + finalMatch := matches[len(matches)-1] + for _, rt := range ws.Routes() { + matches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch) + if matches != nil { + lastMatch := matches[len(matches)-1] + if lastMatch == "" || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. + methods = append(methods, rt.Method) + } + } + } + } + } + // methods = append(methods, "OPTIONS") not sure about this + return methods +} + +// newBasicRequestResponse creates a pair of Request,Response from its http versions. +// It is basic because no parameter or (produces) content-type information is given. +func newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) { + resp := NewResponse(httpWriter) + resp.requestAccept = httpRequest.Header.Get(HEADER_Accept) + return NewRequest(httpRequest), resp +} diff --git a/vendor/github.com/emicklei/go-restful/cors_filter.go b/vendor/github.com/emicklei/go-restful/v3/cors_filter.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/cors_filter.go rename to vendor/github.com/emicklei/go-restful/v3/cors_filter.go diff --git a/vendor/github.com/emicklei/go-restful/coverage.sh b/vendor/github.com/emicklei/go-restful/v3/coverage.sh similarity index 100% rename from vendor/github.com/emicklei/go-restful/coverage.sh rename to vendor/github.com/emicklei/go-restful/v3/coverage.sh diff --git a/vendor/github.com/emicklei/go-restful/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/curly.go rename to vendor/github.com/emicklei/go-restful/v3/curly.go diff --git a/vendor/github.com/emicklei/go-restful/curly_route.go b/vendor/github.com/emicklei/go-restful/v3/curly_route.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/curly_route.go rename to vendor/github.com/emicklei/go-restful/v3/curly_route.go diff --git a/vendor/github.com/emicklei/go-restful/custom_verb.go b/vendor/github.com/emicklei/go-restful/v3/custom_verb.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/custom_verb.go rename to vendor/github.com/emicklei/go-restful/v3/custom_verb.go diff --git a/vendor/github.com/emicklei/go-restful/v3/doc.go b/vendor/github.com/emicklei/go-restful/v3/doc.go new file mode 100644 index 00000000000..69b13057d01 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/doc.go @@ -0,0 +1,185 @@ +/* +Package restful , a lean package for creating REST-style WebServices without magic. + +WebServices and Routes + +A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls. +Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes. +WebServices must be added to a container (see below) in order to handler Http requests from a server. + +A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept). +This package has the logic to find the best matching Route and if found, call its Function. + + ws := new(restful.WebService) + ws. + Path("/users"). + Consumes(restful.MIME_JSON, restful.MIME_XML). + Produces(restful.MIME_JSON, restful.MIME_XML) + + ws.Route(ws.GET("/{user-id}").To(u.findUser)) // u is a UserResource + + ... + + // GET http://localhost:8080/users/1 + func (u UserResource) findUser(request *restful.Request, response *restful.Response) { + id := request.PathParameter("user-id") + ... + } + +The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response. + +See the example https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go with a full implementation. + +Regular expression matching Routes + +A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path. +For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters. +Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax) +This feature requires the use of a CurlyRouter. + +Containers + +A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests. +Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container. +The Default container of go-restful uses the http.DefaultServeMux. +You can create your own Container and create a new http.Server for that particular container. + + container := restful.NewContainer() + server := &http.Server{Addr: ":8081", Handler: container} + +Filters + +A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. +You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. +In the restful package there are three hooks into the request,response flow where filters can be added. +Each filter must define a FilterFunction: + + func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain) + +Use the following statement to pass the request,response pair to the next filter or RouteFunction + + chain.ProcessFilter(req, resp) + +Container Filters + +These are processed before any registered WebService. + + // install a (global) filter for the default container (processed before any webservice) + restful.Filter(globalLogging) + +WebService Filters + +These are processed before any Route of a WebService. + + // install a webservice filter (processed before any route) + ws.Filter(webserviceLogging).Filter(measureTime) + + +Route Filters + +These are processed before calling the function associated with the Route. + + // install 2 chained route filters (processed before calling findUser) + ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser)) + +See the example https://github.com/emicklei/go-restful/blob/v3/examples/filters/restful-filters.go with full implementations. + +Response Encoding + +Two encodings are supported: gzip and deflate. To enable this for all responses: + + restful.DefaultContainer.EnableContentEncoding(true) + +If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding. +Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route. + +See the example https://github.com/emicklei/go-restful/blob/v3/examples/encoding/restful-encoding-filter.go + +OPTIONS support + +By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request. + + Filter(OPTIONSFilter()) + +CORS + +By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests. + + cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} + Filter(cors.Filter) + +Error Handling + +Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why. +For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation. + + 400: Bad Request + +If path or query parameters are not valid (content or type) then use http.StatusBadRequest. + + 404: Not Found + +Despite a valid URI, the resource requested may not be available + + 500: Internal Server Error + +If the application logic could not process the request (or write the response) then use http.StatusInternalServerError. + + 405: Method Not Allowed + +The request has a valid URL but the method (GET,PUT,POST,...) is not allowed. + + 406: Not Acceptable + +The request does not have or has an unknown Accept Header set for this operation. + + 415: Unsupported Media Type + +The request does not have or has an unknown Content-Type Header set for this operation. + +ServiceError + +In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response. + +Performance options + +This package has several options that affect the performance of your service. It is important to understand them and how you can change it. + + restful.DefaultContainer.DoNotRecover(false) + +DoNotRecover controls whether panics will be caught to return HTTP 500. +If set to false, the container will recover from panics. +Default value is true + + restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20)) + +If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool. +Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation. + +Trouble shooting + +This package has the means to produce detail logging of the complete Http request matching process and filter invocation. +Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as: + + restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) + +Logging + +The restful.SetLogger() method allows you to override the logger used by the package. By default restful +uses the standard library `log` package and logs to stdout. Different logging packages are supported as +long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your +preferred package is simple. + +Resources + +[project]: https://github.com/emicklei/go-restful + +[examples]: https://github.com/emicklei/go-restful/blob/master/examples + +[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ + +[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape + +(c) 2012-2015, http://ernestmicklei.com. MIT License +*/ +package restful diff --git a/vendor/github.com/emicklei/go-restful/entity_accessors.go b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/entity_accessors.go rename to vendor/github.com/emicklei/go-restful/v3/entity_accessors.go diff --git a/vendor/github.com/emicklei/go-restful/v3/extensions.go b/vendor/github.com/emicklei/go-restful/v3/extensions.go new file mode 100644 index 00000000000..5023fa049b5 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/extensions.go @@ -0,0 +1,21 @@ +package restful + +// Copyright 2021 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + +// ExtensionProperties provides storage of vendor extensions for entities +type ExtensionProperties struct { + // Extensions vendor extensions used to describe extra functionality + // (https://swagger.io/docs/specification/2-0/swagger-extensions/) + Extensions map[string]interface{} +} + +// AddExtension adds or updates a key=value pair to the extension map. +func (ep *ExtensionProperties) AddExtension(key string, value interface{}) { + if ep.Extensions == nil { + ep.Extensions = map[string]interface{}{key: value} + } else { + ep.Extensions[key] = value + } +} diff --git a/vendor/github.com/emicklei/go-restful/v3/filter.go b/vendor/github.com/emicklei/go-restful/v3/filter.go new file mode 100644 index 00000000000..fd88c536c80 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/filter.go @@ -0,0 +1,37 @@ +package restful + +// Copyright 2013 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + +// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction. +type FilterChain struct { + Filters []FilterFunction // ordered list of FilterFunction + Index int // index into filters that is currently in progress + Target RouteFunction // function to call after passing all filters + ParameterDocs []*Parameter // the parameter docs for the route + Operation string // the name of the operation +} + +// ProcessFilter passes the request,response pair through the next of Filters. +// Each filter can decide to proceed to the next Filter or handle the Response itself. +func (f *FilterChain) ProcessFilter(request *Request, response *Response) { + if f.Index < len(f.Filters) { + f.Index++ + f.Filters[f.Index-1](request, response, f) + } else { + f.Target(request, response) + } +} + +// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction +type FilterFunction func(*Request, *Response, *FilterChain) + +// NoBrowserCacheFilter is a filter function to set HTTP headers that disable browser caching +// See examples/restful-no-cache-filter.go for usage +func NoBrowserCacheFilter(req *Request, resp *Response, chain *FilterChain) { + resp.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1. + resp.Header().Set("Pragma", "no-cache") // HTTP 1.0. + resp.Header().Set("Expires", "0") // Proxies. + chain.ProcessFilter(req, resp) +} diff --git a/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go b/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go new file mode 100644 index 00000000000..c246512fc0d --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/filter_adapter.go @@ -0,0 +1,21 @@ +package restful + +import ( + "net/http" +) + +// HttpMiddlewareHandler is a function that takes a http.Handler and returns a http.Handler +type HttpMiddlewareHandler func(http.Handler) http.Handler + +// HttpMiddlewareHandlerToFilter converts a HttpMiddlewareHandler to a FilterFunction. +func HttpMiddlewareHandlerToFilter(middleware HttpMiddlewareHandler) FilterFunction { + return func(req *Request, resp *Response, chain *FilterChain) { + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + req.Request = r + resp.ResponseWriter = rw + chain.ProcessFilter(req, resp) + }) + + middleware(next).ServeHTTP(resp.ResponseWriter, req.Request) + } +} diff --git a/vendor/github.com/emicklei/go-restful/json.go b/vendor/github.com/emicklei/go-restful/v3/json.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/json.go rename to vendor/github.com/emicklei/go-restful/v3/json.go diff --git a/vendor/github.com/emicklei/go-restful/jsoniter.go b/vendor/github.com/emicklei/go-restful/v3/jsoniter.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/jsoniter.go rename to vendor/github.com/emicklei/go-restful/v3/jsoniter.go diff --git a/vendor/github.com/emicklei/go-restful/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go similarity index 96% rename from vendor/github.com/emicklei/go-restful/jsr311.go rename to vendor/github.com/emicklei/go-restful/v3/jsr311.go index 9cfd59a1ce6..07a0c91e942 100644 --- a/vendor/github.com/emicklei/go-restful/jsr311.go +++ b/vendor/github.com/emicklei/go-restful/v3/jsr311.go @@ -151,6 +151,16 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R for _, candidate := range previous { available = append(available, candidate.Produces...) } + // if POST,PUT,PATCH without body + method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length") + if (method == http.MethodPost || + method == http.MethodPut || + method == http.MethodPatch) && length == "" { + return nil, NewError( + http.StatusUnsupportedMediaType, + fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")), + ) + } return nil, NewError( http.StatusNotAcceptable, fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")), diff --git a/vendor/github.com/emicklei/go-restful/log/log.go b/vendor/github.com/emicklei/go-restful/v3/log/log.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/log/log.go rename to vendor/github.com/emicklei/go-restful/v3/log/log.go diff --git a/vendor/github.com/emicklei/go-restful/logger.go b/vendor/github.com/emicklei/go-restful/v3/logger.go similarity index 95% rename from vendor/github.com/emicklei/go-restful/logger.go rename to vendor/github.com/emicklei/go-restful/v3/logger.go index 6595df00296..29202726f6c 100644 --- a/vendor/github.com/emicklei/go-restful/logger.go +++ b/vendor/github.com/emicklei/go-restful/v3/logger.go @@ -4,7 +4,7 @@ package restful // Use of this source code is governed by a license // that can be found in the LICENSE file. import ( - "github.com/emicklei/go-restful/log" + "github.com/emicklei/go-restful/v3/log" ) var trace bool = false diff --git a/vendor/github.com/emicklei/go-restful/mime.go b/vendor/github.com/emicklei/go-restful/v3/mime.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/mime.go rename to vendor/github.com/emicklei/go-restful/v3/mime.go diff --git a/vendor/github.com/emicklei/go-restful/options_filter.go b/vendor/github.com/emicklei/go-restful/v3/options_filter.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/options_filter.go rename to vendor/github.com/emicklei/go-restful/v3/options_filter.go diff --git a/vendor/github.com/emicklei/go-restful/v3/parameter.go b/vendor/github.com/emicklei/go-restful/v3/parameter.go new file mode 100644 index 00000000000..0b851bb437b --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/parameter.go @@ -0,0 +1,242 @@ +package restful + +import "sort" + +// Copyright 2013 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + +const ( + // PathParameterKind = indicator of Request parameter type "path" + PathParameterKind = iota + + // QueryParameterKind = indicator of Request parameter type "query" + QueryParameterKind + + // BodyParameterKind = indicator of Request parameter type "body" + BodyParameterKind + + // HeaderParameterKind = indicator of Request parameter type "header" + HeaderParameterKind + + // FormParameterKind = indicator of Request parameter type "form" + FormParameterKind + + // MultiPartFormParameterKind = indicator of Request parameter type "multipart/form-data" + MultiPartFormParameterKind + + // CollectionFormatCSV comma separated values `foo,bar` + CollectionFormatCSV = CollectionFormat("csv") + + // CollectionFormatSSV space separated values `foo bar` + CollectionFormatSSV = CollectionFormat("ssv") + + // CollectionFormatTSV tab separated values `foo\tbar` + CollectionFormatTSV = CollectionFormat("tsv") + + // CollectionFormatPipes pipe separated values `foo|bar` + CollectionFormatPipes = CollectionFormat("pipes") + + // CollectionFormatMulti corresponds to multiple parameter instances instead of multiple values for a single + // instance `foo=bar&foo=baz`. This is valid only for QueryParameters and FormParameters + CollectionFormatMulti = CollectionFormat("multi") +) + +type CollectionFormat string + +func (cf CollectionFormat) String() string { + return string(cf) +} + +// Parameter is for documententing the parameter used in a Http Request +// ParameterData kinds are Path,Query and Body +type Parameter struct { + data *ParameterData +} + +// ParameterData represents the state of a Parameter. +// It is made public to make it accessible to e.g. the Swagger package. +type ParameterData struct { + ExtensionProperties + Name, Description, DataType, DataFormat string + Kind int + Required bool + // AllowableValues is deprecated. Use PossibleValues instead + AllowableValues map[string]string + PossibleValues []string + AllowMultiple bool + AllowEmptyValue bool + DefaultValue string + CollectionFormat string + Pattern string + Minimum *float64 + Maximum *float64 + MinLength *int64 + MaxLength *int64 + MinItems *int64 + MaxItems *int64 + UniqueItems bool +} + +// Data returns the state of the Parameter +func (p *Parameter) Data() ParameterData { + return *p.data +} + +// Kind returns the parameter type indicator (see const for valid values) +func (p *Parameter) Kind() int { + return p.data.Kind +} + +func (p *Parameter) bePath() *Parameter { + p.data.Kind = PathParameterKind + return p +} +func (p *Parameter) beQuery() *Parameter { + p.data.Kind = QueryParameterKind + return p +} +func (p *Parameter) beBody() *Parameter { + p.data.Kind = BodyParameterKind + return p +} + +func (p *Parameter) beHeader() *Parameter { + p.data.Kind = HeaderParameterKind + return p +} + +func (p *Parameter) beForm() *Parameter { + p.data.Kind = FormParameterKind + return p +} + +func (p *Parameter) beMultiPartForm() *Parameter { + p.data.Kind = MultiPartFormParameterKind + return p +} + +// Required sets the required field and returns the receiver +func (p *Parameter) Required(required bool) *Parameter { + p.data.Required = required + return p +} + +// AllowMultiple sets the allowMultiple field and returns the receiver +func (p *Parameter) AllowMultiple(multiple bool) *Parameter { + p.data.AllowMultiple = multiple + return p +} + +// AddExtension adds or updates a key=value pair to the extension map +func (p *Parameter) AddExtension(key string, value interface{}) *Parameter { + p.data.AddExtension(key, value) + return p +} + +// AllowEmptyValue sets the AllowEmptyValue field and returns the receiver +func (p *Parameter) AllowEmptyValue(multiple bool) *Parameter { + p.data.AllowEmptyValue = multiple + return p +} + +// AllowableValues is deprecated. Use PossibleValues instead. Both will be set. +func (p *Parameter) AllowableValues(values map[string]string) *Parameter { + p.data.AllowableValues = values + + allowableSortedKeys := make([]string, 0, len(values)) + for k := range values { + allowableSortedKeys = append(allowableSortedKeys, k) + } + sort.Strings(allowableSortedKeys) + + p.data.PossibleValues = make([]string, 0, len(values)) + for _, k := range allowableSortedKeys { + p.data.PossibleValues = append(p.data.PossibleValues, values[k]) + } + return p +} + +// PossibleValues sets the possible values field and returns the receiver +func (p *Parameter) PossibleValues(values []string) *Parameter { + p.data.PossibleValues = values + return p +} + +// DataType sets the dataType field and returns the receiver +func (p *Parameter) DataType(typeName string) *Parameter { + p.data.DataType = typeName + return p +} + +// DataFormat sets the dataFormat field for Swagger UI +func (p *Parameter) DataFormat(formatName string) *Parameter { + p.data.DataFormat = formatName + return p +} + +// DefaultValue sets the default value field and returns the receiver +func (p *Parameter) DefaultValue(stringRepresentation string) *Parameter { + p.data.DefaultValue = stringRepresentation + return p +} + +// Description sets the description value field and returns the receiver +func (p *Parameter) Description(doc string) *Parameter { + p.data.Description = doc + return p +} + +// CollectionFormat sets the collection format for an array type +func (p *Parameter) CollectionFormat(format CollectionFormat) *Parameter { + p.data.CollectionFormat = format.String() + return p +} + +// Pattern sets the pattern field and returns the receiver +func (p *Parameter) Pattern(pattern string) *Parameter { + p.data.Pattern = pattern + return p +} + +// Minimum sets the minimum field and returns the receiver +func (p *Parameter) Minimum(minimum float64) *Parameter { + p.data.Minimum = &minimum + return p +} + +// Maximum sets the maximum field and returns the receiver +func (p *Parameter) Maximum(maximum float64) *Parameter { + p.data.Maximum = &maximum + return p +} + +// MinLength sets the minLength field and returns the receiver +func (p *Parameter) MinLength(minLength int64) *Parameter { + p.data.MinLength = &minLength + return p +} + +// MaxLength sets the maxLength field and returns the receiver +func (p *Parameter) MaxLength(maxLength int64) *Parameter { + p.data.MaxLength = &maxLength + return p +} + +// MinItems sets the minItems field and returns the receiver +func (p *Parameter) MinItems(minItems int64) *Parameter { + p.data.MinItems = &minItems + return p +} + +// MaxItems sets the maxItems field and returns the receiver +func (p *Parameter) MaxItems(maxItems int64) *Parameter { + p.data.MaxItems = &maxItems + return p +} + +// UniqueItems sets the uniqueItems field and returns the receiver +func (p *Parameter) UniqueItems(uniqueItems bool) *Parameter { + p.data.UniqueItems = uniqueItems + return p +} diff --git a/vendor/github.com/emicklei/go-restful/path_expression.go b/vendor/github.com/emicklei/go-restful/v3/path_expression.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/path_expression.go rename to vendor/github.com/emicklei/go-restful/v3/path_expression.go diff --git a/vendor/github.com/emicklei/go-restful/path_processor.go b/vendor/github.com/emicklei/go-restful/v3/path_processor.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/path_processor.go rename to vendor/github.com/emicklei/go-restful/v3/path_processor.go diff --git a/vendor/github.com/emicklei/go-restful/request.go b/vendor/github.com/emicklei/go-restful/v3/request.go similarity index 85% rename from vendor/github.com/emicklei/go-restful/request.go rename to vendor/github.com/emicklei/go-restful/v3/request.go index 05d768117c3..0020095e862 100644 --- a/vendor/github.com/emicklei/go-restful/request.go +++ b/vendor/github.com/emicklei/go-restful/v3/request.go @@ -13,11 +13,10 @@ var defaultRequestContentType string // Request is a wrapper for a http Request that provides convenience methods type Request struct { - Request *http.Request - pathParameters map[string]string - attributes map[string]interface{} // for storing request-scoped values - selectedRoutePath string // root path + route path that matched the request, e.g. /meetings/{id}/attendees - selectedRoute *Route + Request *http.Request + pathParameters map[string]string + attributes map[string]interface{} // for storing request-scoped values + selectedRoute *Route // is nil when no route was matched } func NewRequest(httpRequest *http.Request) *Request { @@ -32,7 +31,8 @@ func NewRequest(httpRequest *http.Request) *Request { // a "Unable to unmarshal content of type:" response is returned. // Valid values are restful.MIME_JSON and restful.MIME_XML // Example: -// restful.DefaultRequestContentType(restful.MIME_JSON) +// +// restful.DefaultRequestContentType(restful.MIME_JSON) func DefaultRequestContentType(mime string) { defaultRequestContentType = mime } @@ -49,7 +49,7 @@ func (r *Request) PathParameters() map[string]string { // QueryParameter returns the (first) Query parameter value by its name func (r *Request) QueryParameter(name string) string { - return r.Request.FormValue(name) + return r.Request.URL.Query().Get(name) } // QueryParameters returns the all the query parameters values by name @@ -114,11 +114,20 @@ func (r Request) Attribute(name string) interface{} { } // SelectedRoutePath root path + route path that matched the request, e.g. /meetings/{id}/attendees +// If no route was matched then return an empty string. func (r Request) SelectedRoutePath() string { + if r.selectedRoute == nil { + return "" + } + // skip creating an accessor return r.selectedRoute.Path } -// SelectedRoute return the Route that selected by the container +// SelectedRoute returns a reader to access the selected Route by the container +// Returns nil if no route was matched. func (r Request) SelectedRoute() RouteReader { + if r.selectedRoute == nil { + return nil + } return routeAccessor{route: r.selectedRoute} } diff --git a/vendor/github.com/emicklei/go-restful/v3/response.go b/vendor/github.com/emicklei/go-restful/v3/response.go new file mode 100644 index 00000000000..a41a92cc2c3 --- /dev/null +++ b/vendor/github.com/emicklei/go-restful/v3/response.go @@ -0,0 +1,259 @@ +package restful + +// Copyright 2013 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + +import ( + "bufio" + "errors" + "net" + "net/http" +) + +// DefaultResponseMimeType is DEPRECATED, use DefaultResponseContentType(mime) +var DefaultResponseMimeType string + +//PrettyPrintResponses controls the indentation feature of XML and JSON serialization +var PrettyPrintResponses = true + +// Response is a wrapper on the actual http ResponseWriter +// It provides several convenience methods to prepare and write response content. +type Response struct { + http.ResponseWriter + requestAccept string // mime-type what the Http Request says it wants to receive + routeProduces []string // mime-types what the Route says it can produce + statusCode int // HTTP status code that has been written explicitly (if zero then net/http has written 200) + contentLength int // number of bytes written for the response body + prettyPrint bool // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses. + err error // err property is kept when WriteError is called + hijacker http.Hijacker // if underlying ResponseWriter supports it +} + +// NewResponse creates a new response based on a http ResponseWriter. +func NewResponse(httpWriter http.ResponseWriter) *Response { + hijacker, _ := httpWriter.(http.Hijacker) + return &Response{ResponseWriter: httpWriter, routeProduces: []string{}, statusCode: http.StatusOK, prettyPrint: PrettyPrintResponses, hijacker: hijacker} +} + +// DefaultResponseContentType set a default. +// If Accept header matching fails, fall back to this type. +// Valid values are restful.MIME_JSON and restful.MIME_XML +// Example: +// restful.DefaultResponseContentType(restful.MIME_JSON) +func DefaultResponseContentType(mime string) { + DefaultResponseMimeType = mime +} + +// InternalServerError writes the StatusInternalServerError header. +// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason) +func (r Response) InternalServerError() Response { + r.WriteHeader(http.StatusInternalServerError) + return r +} + +// Hijack implements the http.Hijacker interface. This expands +// the Response to fulfill http.Hijacker if the underlying +// http.ResponseWriter supports it. +func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if r.hijacker == nil { + return nil, nil, errors.New("http.Hijacker not implemented by underlying http.ResponseWriter") + } + return r.hijacker.Hijack() +} + +// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output. +func (r *Response) PrettyPrint(bePretty bool) { + r.prettyPrint = bePretty +} + +// AddHeader is a shortcut for .Header().Add(header,value) +func (r Response) AddHeader(header string, value string) Response { + r.Header().Add(header, value) + return r +} + +// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing. +func (r *Response) SetRequestAccepts(mime string) { + r.requestAccept = mime +} + +// EntityWriter returns the registered EntityWriter that the entity (requested resource) +// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say. +// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable. +func (r *Response) EntityWriter() (EntityReaderWriter, bool) { + sorted := sortedMimes(r.requestAccept) + for _, eachAccept := range sorted { + for _, eachProduce := range r.routeProduces { + if eachProduce == eachAccept.media { + if w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok { + return w, true + } + } + } + if eachAccept.media == "*/*" { + for _, each := range r.routeProduces { + if w, ok := entityAccessRegistry.accessorAt(each); ok { + return w, true + } + } + } + } + // if requestAccept is empty + writer, ok := entityAccessRegistry.accessorAt(r.requestAccept) + if !ok { + // if not registered then fallback to the defaults (if set) + if DefaultResponseMimeType == MIME_JSON { + return entityAccessRegistry.accessorAt(MIME_JSON) + } + if DefaultResponseMimeType == MIME_XML { + return entityAccessRegistry.accessorAt(MIME_XML) + } + if DefaultResponseMimeType == MIME_ZIP { + return entityAccessRegistry.accessorAt(MIME_ZIP) + } + // Fallback to whatever the route says it can produce. + // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html + for _, each := range r.routeProduces { + if w, ok := entityAccessRegistry.accessorAt(each); ok { + return w, true + } + } + if trace { + traceLogger.Printf("no registered EntityReaderWriter found for %s", r.requestAccept) + } + } + return writer, ok +} + +// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200) +func (r *Response) WriteEntity(value interface{}) error { + return r.WriteHeaderAndEntity(http.StatusOK, value) +} + +// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters. +// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces. +// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header. +// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead. +// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written. +// Current implementation ignores any q-parameters in the Accept Header. +// Returns an error if the value could not be written on the response. +func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error { + writer, ok := r.EntityWriter() + if !ok { + r.WriteHeader(http.StatusNotAcceptable) + return nil + } + return writer.Write(r, status, value) +} + +// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value) +// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. +func (r *Response) WriteAsXml(value interface{}) error { + return writeXML(r, http.StatusOK, MIME_XML, value) +} + +// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value) +// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. +func (r *Response) WriteHeaderAndXml(status int, value interface{}) error { + return writeXML(r, status, MIME_XML, value) +} + +// WriteAsJson is a convenience method for writing a value in json. +// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. +func (r *Response) WriteAsJson(value interface{}) error { + return writeJSON(r, http.StatusOK, MIME_JSON, value) +} + +// WriteJson is a convenience method for writing a value in Json with a given Content-Type. +// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. +func (r *Response) WriteJson(value interface{}, contentType string) error { + return writeJSON(r, http.StatusOK, contentType, value) +} + +// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type. +// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. +func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error { + return writeJSON(r, status, contentType, value) +} + +// WriteError writes the http status and the error string on the response. err can be nil. +// Return an error if writing was not successful. +func (r *Response) WriteError(httpStatus int, err error) (writeErr error) { + r.err = err + if err == nil { + writeErr = r.WriteErrorString(httpStatus, "") + } else { + writeErr = r.WriteErrorString(httpStatus, err.Error()) + } + return writeErr +} + +// WriteServiceError is a convenience method for a responding with a status and a ServiceError +func (r *Response) WriteServiceError(httpStatus int, err ServiceError) error { + r.err = err + return r.WriteHeaderAndEntity(httpStatus, err) +} + +// WriteErrorString is a convenience method for an error status with the actual error +func (r *Response) WriteErrorString(httpStatus int, errorReason string) error { + if r.err == nil { + // if not called from WriteError + r.err = errors.New(errorReason) + } + r.WriteHeader(httpStatus) + if _, err := r.Write([]byte(errorReason)); err != nil { + return err + } + return nil +} + +// Flush implements http.Flusher interface, which sends any buffered data to the client. +func (r *Response) Flush() { + if f, ok := r.ResponseWriter.(http.Flusher); ok { + f.Flush() + } else if trace { + traceLogger.Printf("ResponseWriter %v doesn't support Flush", r) + } +} + +// WriteHeader is overridden to remember the Status Code that has been written. +// Changes to the Header of the response have no effect after this. +func (r *Response) WriteHeader(httpStatus int) { + r.statusCode = httpStatus + r.ResponseWriter.WriteHeader(httpStatus) +} + +// StatusCode returns the code that has been written using WriteHeader. +func (r Response) StatusCode() int { + if 0 == r.statusCode { + // no status code has been written yet; assume OK + return http.StatusOK + } + return r.statusCode +} + +// Write writes the data to the connection as part of an HTTP reply. +// Write is part of http.ResponseWriter interface. +func (r *Response) Write(bytes []byte) (int, error) { + written, err := r.ResponseWriter.Write(bytes) + r.contentLength += written + return written, err +} + +// ContentLength returns the number of bytes written for the response content. +// Note that this value is only correct if all data is written through the Response using its Write* methods. +// Data written directly using the underlying http.ResponseWriter is not accounted for. +func (r Response) ContentLength() int { + return r.contentLength +} + +// CloseNotify is part of http.CloseNotifier interface +func (r Response) CloseNotify() <-chan bool { + return r.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + +// Error returns the err created by WriteError +func (r Response) Error() error { + return r.err +} diff --git a/vendor/github.com/emicklei/go-restful/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go similarity index 96% rename from vendor/github.com/emicklei/go-restful/route.go rename to vendor/github.com/emicklei/go-restful/v3/route.go index 6ac26129314..ea05b3da887 100644 --- a/vendor/github.com/emicklei/go-restful/route.go +++ b/vendor/github.com/emicklei/go-restful/v3/route.go @@ -19,6 +19,7 @@ type RouteSelectionConditionFunction func(httpRequest *http.Request) bool // Route binds a HTTP Method,Path,Consumes combination to a RouteFunction. type Route struct { + ExtensionProperties Method string Produces []string Consumes []string @@ -163,15 +164,17 @@ func tokenizePath(path string) []string { if "/" == path { return nil } - return strings.Split(strings.Trim(path, "/"), "/") + return strings.Split(strings.TrimLeft(path, "/"), "/") } // for debugging -func (r Route) String() string { +func (r *Route) String() string { return r.Method + " " + r.Path } // EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. Overrides the container.contentEncodingEnabled value. -func (r Route) EnableContentEncoding(enabled bool) { +func (r *Route) EnableContentEncoding(enabled bool) { r.contentEncodingEnabled = &enabled } + +var TrimRightSlashEnabled = false diff --git a/vendor/github.com/emicklei/go-restful/route_builder.go b/vendor/github.com/emicklei/go-restful/v3/route_builder.go similarity index 94% rename from vendor/github.com/emicklei/go-restful/route_builder.go rename to vendor/github.com/emicklei/go-restful/v3/route_builder.go index 1d67a4c2358..830ebf148ed 100644 --- a/vendor/github.com/emicklei/go-restful/route_builder.go +++ b/vendor/github.com/emicklei/go-restful/v3/route_builder.go @@ -7,12 +7,13 @@ package restful import ( "fmt" "os" + "path" "reflect" "runtime" "strings" "sync/atomic" - "github.com/emicklei/go-restful/log" + "github.com/emicklei/go-restful/v3/log" ) // RouteBuilder is a helper to construct Routes. @@ -38,6 +39,7 @@ type RouteBuilder struct { errorMap map[int]ResponseError defaultResponse *ResponseError metadata map[string]interface{} + extensions map[string]interface{} deprecated bool contentEncodingEnabled *bool } @@ -45,11 +47,12 @@ type RouteBuilder struct { // Do evaluates each argument with the RouteBuilder itself. // This allows you to follow DRY principles without breaking the fluent programming style. // Example: -// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) // -// func Returns500(b *RouteBuilder) { -// b.Returns(500, "Internal Server Error", restful.ServiceError{}) -// } +// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) +// +// func Returns500(b *RouteBuilder) { +// b.Returns(500, "Internal Server Error", restful.ServiceError{}) +// } func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder { for _, each := range oneArgBlocks { each(b) @@ -204,13 +207,22 @@ func (b *RouteBuilder) Metadata(key string, value interface{}) *RouteBuilder { return b } +// AddExtension adds or updates a key=value pair to the extensions map. +func (b *RouteBuilder) AddExtension(key string, value interface{}) *RouteBuilder { + if b.extensions == nil { + b.extensions = map[string]interface{}{} + } + b.extensions[key] = value + return b +} + // Deprecate sets the value of deprecated to true. Deprecated routes have a special UI treatment to warn against use func (b *RouteBuilder) Deprecate() *RouteBuilder { b.deprecated = true return b } -// AllowedMethodsWithoutContentType overides the default list GET,HEAD,OPTIONS,DELETE,TRACE +// AllowedMethodsWithoutContentType overrides the default list GET,HEAD,OPTIONS,DELETE,TRACE // If a request does not include a content-type header then // depending on the method, it may return a 415 Unsupported Media. // Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,... @@ -221,6 +233,7 @@ func (b *RouteBuilder) AllowedMethodsWithoutContentType(methods []string) *Route // ResponseError represents a response; not necessarily an error. type ResponseError struct { + ExtensionProperties Code int Message string Model interface{} @@ -335,12 +348,13 @@ func (b *RouteBuilder) Build() Route { contentEncodingEnabled: b.contentEncodingEnabled, allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType, } + route.Extensions = b.extensions route.postBuild() return route } func concatPath(path1, path2 string) string { - return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/") + return path.Join(path1, path2) } var anonymousFuncCount int32 diff --git a/vendor/github.com/emicklei/go-restful/route_reader.go b/vendor/github.com/emicklei/go-restful/v3/route_reader.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/route_reader.go rename to vendor/github.com/emicklei/go-restful/v3/route_reader.go diff --git a/vendor/github.com/emicklei/go-restful/router.go b/vendor/github.com/emicklei/go-restful/v3/router.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/router.go rename to vendor/github.com/emicklei/go-restful/v3/router.go diff --git a/vendor/github.com/emicklei/go-restful/service_error.go b/vendor/github.com/emicklei/go-restful/v3/service_error.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/service_error.go rename to vendor/github.com/emicklei/go-restful/v3/service_error.go diff --git a/vendor/github.com/emicklei/go-restful/web_service.go b/vendor/github.com/emicklei/go-restful/v3/web_service.go similarity index 96% rename from vendor/github.com/emicklei/go-restful/web_service.go rename to vendor/github.com/emicklei/go-restful/v3/web_service.go index 2eac41497b0..789c4df259f 100644 --- a/vendor/github.com/emicklei/go-restful/web_service.go +++ b/vendor/github.com/emicklei/go-restful/v3/web_service.go @@ -6,7 +6,7 @@ import ( "reflect" "sync" - "github.com/emicklei/go-restful/log" + "github.com/emicklei/go-restful/v3/log" ) // Copyright 2013 Ernest Micklei. All rights reserved. @@ -188,22 +188,20 @@ func (w *WebService) Route(builder *RouteBuilder) *WebService { // RemoveRoute removes the specified route, looks for something that matches 'path' and 'method' func (w *WebService) RemoveRoute(path, method string) error { - if !w.dynamicRoutes { - return errors.New("dynamic routes are not enabled.") - } - w.routesLock.Lock() - defer w.routesLock.Unlock() - newRoutes := make([]Route, (len(w.routes) - 1)) - current := 0 - for ix := range w.routes { - if w.routes[ix].Method == method && w.routes[ix].Path == path { - continue - } - newRoutes[current] = w.routes[ix] - current++ - } - w.routes = newRoutes - return nil + if !w.dynamicRoutes { + return errors.New("dynamic routes are not enabled.") + } + w.routesLock.Lock() + defer w.routesLock.Unlock() + newRoutes := []Route{} + for _, route := range w.routes { + if route.Method == method && route.Path == path { + continue + } + newRoutes = append(newRoutes, route) + } + w.routes = newRoutes + return nil } // Method creates a new RouteBuilder and initialize its http method diff --git a/vendor/github.com/emicklei/go-restful/web_service_container.go b/vendor/github.com/emicklei/go-restful/v3/web_service_container.go similarity index 100% rename from vendor/github.com/emicklei/go-restful/web_service_container.go rename to vendor/github.com/emicklei/go-restful/v3/web_service_container.go diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go index 4bce5936d50..dc2b7e51e60 100644 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ b/vendor/github.com/evanphx/json-patch/patch.go @@ -568,6 +568,29 @@ func (p Patch) replace(doc *container, op Operation) error { return errors.Wrapf(err, "replace operation failed to decode path") } + if path == "" { + val := op.value() + + if val.which == eRaw { + if !val.tryDoc() { + if !val.tryAry() { + return errors.Wrapf(err, "replace operation value must be object or array") + } + } + } + + switch val.which { + case eAry: + *doc = &val.ary + case eDoc: + *doc = &val.doc + case eRaw: + return errors.Wrapf(err, "replace operation hit impossible case") + } + + return nil + } + con, key := findObject(doc, path) if con == nil { @@ -634,6 +657,25 @@ func (p Patch) test(doc *container, op Operation) error { return errors.Wrapf(err, "test operation failed to decode path") } + if path == "" { + var self lazyNode + + switch sv := (*doc).(type) { + case *partialDoc: + self.doc = *sv + self.which = eDoc + case *partialArray: + self.ary = *sv + self.which = eAry + } + + if self.equal(op.value()) { + return nil + } + + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + } + con, key := findObject(doc, path) if con == nil { diff --git a/vendor/github.com/evanphx/json-patch/v5/LICENSE b/vendor/github.com/evanphx/json-patch/v5/LICENSE new file mode 100644 index 00000000000..df76d7d7716 --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2014, Evan Phoenix +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the Evan Phoenix nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/evanphx/json-patch/v5/errors.go b/vendor/github.com/evanphx/json-patch/v5/errors.go new file mode 100644 index 00000000000..75304b4437c --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/errors.go @@ -0,0 +1,38 @@ +package jsonpatch + +import "fmt" + +// AccumulatedCopySizeError is an error type returned when the accumulated size +// increase caused by copy operations in a patch operation has exceeded the +// limit. +type AccumulatedCopySizeError struct { + limit int64 + accumulated int64 +} + +// NewAccumulatedCopySizeError returns an AccumulatedCopySizeError. +func NewAccumulatedCopySizeError(l, a int64) *AccumulatedCopySizeError { + return &AccumulatedCopySizeError{limit: l, accumulated: a} +} + +// Error implements the error interface. +func (a *AccumulatedCopySizeError) Error() string { + return fmt.Sprintf("Unable to complete the copy, the accumulated size increase of copy is %d, exceeding the limit %d", a.accumulated, a.limit) +} + +// ArraySizeError is an error type returned when the array size has exceeded +// the limit. +type ArraySizeError struct { + limit int + size int +} + +// NewArraySizeError returns an ArraySizeError. +func NewArraySizeError(l, s int) *ArraySizeError { + return &ArraySizeError{limit: l, size: s} +} + +// Error implements the error interface. +func (a *ArraySizeError) Error() string { + return fmt.Sprintf("Unable to create array of size %d, limit is %d", a.size, a.limit) +} diff --git a/vendor/github.com/evanphx/json-patch/v5/merge.go b/vendor/github.com/evanphx/json-patch/v5/merge.go new file mode 100644 index 00000000000..a7c45734285 --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/merge.go @@ -0,0 +1,408 @@ +package jsonpatch + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" +) + +func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode { + curDoc, err := cur.intoDoc() + + if err != nil { + pruneNulls(patch) + return patch + } + + patchDoc, err := patch.intoDoc() + + if err != nil { + return patch + } + + mergeDocs(curDoc, patchDoc, mergeMerge) + + return cur +} + +func mergeDocs(doc, patch *partialDoc, mergeMerge bool) { + for k, v := range patch.obj { + if v == nil { + if mergeMerge { + idx := -1 + for i, key := range doc.keys { + if key == k { + idx = i + break + } + } + if idx == -1 { + doc.keys = append(doc.keys, k) + } + doc.obj[k] = nil + } else { + _ = doc.remove(k, &ApplyOptions{}) + } + } else { + cur, ok := doc.obj[k] + + if !ok || cur == nil { + if !mergeMerge { + pruneNulls(v) + } + _ = doc.set(k, v, &ApplyOptions{}) + } else { + _ = doc.set(k, merge(cur, v, mergeMerge), &ApplyOptions{}) + } + } + } +} + +func pruneNulls(n *lazyNode) { + sub, err := n.intoDoc() + + if err == nil { + pruneDocNulls(sub) + } else { + ary, err := n.intoAry() + + if err == nil { + pruneAryNulls(ary) + } + } +} + +func pruneDocNulls(doc *partialDoc) *partialDoc { + for k, v := range doc.obj { + if v == nil { + _ = doc.remove(k, &ApplyOptions{}) + } else { + pruneNulls(v) + } + } + + return doc +} + +func pruneAryNulls(ary *partialArray) *partialArray { + newAry := []*lazyNode{} + + for _, v := range *ary { + if v != nil { + pruneNulls(v) + } + newAry = append(newAry, v) + } + + *ary = newAry + + return ary +} + +var errBadJSONDoc = fmt.Errorf("Invalid JSON Document") +var errBadJSONPatch = fmt.Errorf("Invalid JSON Patch") +var errBadMergeTypes = fmt.Errorf("Mismatched JSON Documents") + +// MergeMergePatches merges two merge patches together, such that +// applying this resulting merged merge patch to a document yields the same +// as merging each merge patch to the document in succession. +func MergeMergePatches(patch1Data, patch2Data []byte) ([]byte, error) { + return doMergePatch(patch1Data, patch2Data, true) +} + +// MergePatch merges the patchData into the docData. +func MergePatch(docData, patchData []byte) ([]byte, error) { + return doMergePatch(docData, patchData, false) +} + +func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) { + doc := &partialDoc{} + + docErr := json.Unmarshal(docData, doc) + + patch := &partialDoc{} + + patchErr := json.Unmarshal(patchData, patch) + + if isSyntaxError(docErr) { + return nil, errBadJSONDoc + } + + if isSyntaxError(patchErr) { + return nil, errBadJSONPatch + } + + if docErr == nil && doc.obj == nil { + return nil, errBadJSONDoc + } + + if patchErr == nil && patch.obj == nil { + return nil, errBadJSONPatch + } + + if docErr != nil || patchErr != nil { + // Not an error, just not a doc, so we turn straight into the patch + if patchErr == nil { + if mergeMerge { + doc = patch + } else { + doc = pruneDocNulls(patch) + } + } else { + patchAry := &partialArray{} + patchErr = json.Unmarshal(patchData, patchAry) + + if patchErr != nil { + return nil, errBadJSONPatch + } + + pruneAryNulls(patchAry) + + out, patchErr := json.Marshal(patchAry) + + if patchErr != nil { + return nil, errBadJSONPatch + } + + return out, nil + } + } else { + mergeDocs(doc, patch, mergeMerge) + } + + return json.Marshal(doc) +} + +func isSyntaxError(err error) bool { + if _, ok := err.(*json.SyntaxError); ok { + return true + } + if _, ok := err.(*syntaxError); ok { + return true + } + return false +} + +// resemblesJSONArray indicates whether the byte-slice "appears" to be +// a JSON array or not. +// False-positives are possible, as this function does not check the internal +// structure of the array. It only checks that the outer syntax is present and +// correct. +func resemblesJSONArray(input []byte) bool { + input = bytes.TrimSpace(input) + + hasPrefix := bytes.HasPrefix(input, []byte("[")) + hasSuffix := bytes.HasSuffix(input, []byte("]")) + + return hasPrefix && hasSuffix +} + +// CreateMergePatch will return a merge patch document capable of converting +// the original document(s) to the modified document(s). +// The parameters can be bytes of either two JSON Documents, or two arrays of +// JSON documents. +// The merge patch returned follows the specification defined at http://tools.ietf.org/html/draft-ietf-appsawg-json-merge-patch-07 +func CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { + originalResemblesArray := resemblesJSONArray(originalJSON) + modifiedResemblesArray := resemblesJSONArray(modifiedJSON) + + // Do both byte-slices seem like JSON arrays? + if originalResemblesArray && modifiedResemblesArray { + return createArrayMergePatch(originalJSON, modifiedJSON) + } + + // Are both byte-slices are not arrays? Then they are likely JSON objects... + if !originalResemblesArray && !modifiedResemblesArray { + return createObjectMergePatch(originalJSON, modifiedJSON) + } + + // None of the above? Then return an error because of mismatched types. + return nil, errBadMergeTypes +} + +// createObjectMergePatch will return a merge-patch document capable of +// converting the original document to the modified document. +func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { + originalDoc := map[string]interface{}{} + modifiedDoc := map[string]interface{}{} + + err := json.Unmarshal(originalJSON, &originalDoc) + if err != nil { + return nil, errBadJSONDoc + } + + err = json.Unmarshal(modifiedJSON, &modifiedDoc) + if err != nil { + return nil, errBadJSONDoc + } + + dest, err := getDiff(originalDoc, modifiedDoc) + if err != nil { + return nil, err + } + + return json.Marshal(dest) +} + +// createArrayMergePatch will return an array of merge-patch documents capable +// of converting the original document to the modified document for each +// pair of JSON documents provided in the arrays. +// Arrays of mismatched sizes will result in an error. +func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { + originalDocs := []json.RawMessage{} + modifiedDocs := []json.RawMessage{} + + err := json.Unmarshal(originalJSON, &originalDocs) + if err != nil { + return nil, errBadJSONDoc + } + + err = json.Unmarshal(modifiedJSON, &modifiedDocs) + if err != nil { + return nil, errBadJSONDoc + } + + total := len(originalDocs) + if len(modifiedDocs) != total { + return nil, errBadJSONDoc + } + + result := []json.RawMessage{} + for i := 0; i < len(originalDocs); i++ { + original := originalDocs[i] + modified := modifiedDocs[i] + + patch, err := createObjectMergePatch(original, modified) + if err != nil { + return nil, err + } + + result = append(result, json.RawMessage(patch)) + } + + return json.Marshal(result) +} + +// Returns true if the array matches (must be json types). +// As is idiomatic for go, an empty array is not the same as a nil array. +func matchesArray(a, b []interface{}) bool { + if len(a) != len(b) { + return false + } + if (a == nil && b != nil) || (a != nil && b == nil) { + return false + } + for i := range a { + if !matchesValue(a[i], b[i]) { + return false + } + } + return true +} + +// Returns true if the values matches (must be json types) +// The types of the values must match, otherwise it will always return false +// If two map[string]interface{} are given, all elements must match. +func matchesValue(av, bv interface{}) bool { + if reflect.TypeOf(av) != reflect.TypeOf(bv) { + return false + } + switch at := av.(type) { + case string: + bt := bv.(string) + if bt == at { + return true + } + case float64: + bt := bv.(float64) + if bt == at { + return true + } + case bool: + bt := bv.(bool) + if bt == at { + return true + } + case nil: + // Both nil, fine. + return true + case map[string]interface{}: + bt := bv.(map[string]interface{}) + if len(bt) != len(at) { + return false + } + for key := range bt { + av, aOK := at[key] + bv, bOK := bt[key] + if aOK != bOK { + return false + } + if !matchesValue(av, bv) { + return false + } + } + return true + case []interface{}: + bt := bv.([]interface{}) + return matchesArray(at, bt) + } + return false +} + +// getDiff returns the (recursive) difference between a and b as a map[string]interface{}. +func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { + into := map[string]interface{}{} + for key, bv := range b { + av, ok := a[key] + // value was added + if !ok { + into[key] = bv + continue + } + // If types have changed, replace completely + if reflect.TypeOf(av) != reflect.TypeOf(bv) { + into[key] = bv + continue + } + // Types are the same, compare values + switch at := av.(type) { + case map[string]interface{}: + bt := bv.(map[string]interface{}) + dst := make(map[string]interface{}, len(bt)) + dst, err := getDiff(at, bt) + if err != nil { + return nil, err + } + if len(dst) > 0 { + into[key] = dst + } + case string, float64, bool: + if !matchesValue(av, bv) { + into[key] = bv + } + case []interface{}: + bt := bv.([]interface{}) + if !matchesArray(at, bt) { + into[key] = bv + } + case nil: + switch bv.(type) { + case nil: + // Both nil, fine. + default: + into[key] = bv + } + default: + panic(fmt.Sprintf("Unknown type:%T in key %s", av, key)) + } + } + // Now add all deleted values as nil + for key := range a { + _, found := b[key] + if !found { + into[key] = nil + } + } + return into, nil +} diff --git a/vendor/github.com/evanphx/json-patch/v5/patch.go b/vendor/github.com/evanphx/json-patch/v5/patch.go new file mode 100644 index 00000000000..117f2c00dfe --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/patch.go @@ -0,0 +1,1135 @@ +package jsonpatch + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/pkg/errors" +) + +const ( + eRaw = iota + eDoc + eAry +) + +var ( + // SupportNegativeIndices decides whether to support non-standard practice of + // allowing negative indices to mean indices starting at the end of an array. + // Default to true. + SupportNegativeIndices bool = true + // AccumulatedCopySizeLimit limits the total size increase in bytes caused by + // "copy" operations in a patch. + AccumulatedCopySizeLimit int64 = 0 + startObject = json.Delim('{') + endObject = json.Delim('}') + startArray = json.Delim('[') + endArray = json.Delim(']') +) + +var ( + ErrTestFailed = errors.New("test failed") + ErrMissing = errors.New("missing value") + ErrUnknownType = errors.New("unknown object type") + ErrInvalid = errors.New("invalid state detected") + ErrInvalidIndex = errors.New("invalid index referenced") + + rawJSONArray = []byte("[]") + rawJSONObject = []byte("{}") + rawJSONNull = []byte("null") +) + +type lazyNode struct { + raw *json.RawMessage + doc *partialDoc + ary partialArray + which int +} + +// Operation is a single JSON-Patch step, such as a single 'add' operation. +type Operation map[string]*json.RawMessage + +// Patch is an ordered collection of Operations. +type Patch []Operation + +type partialDoc struct { + keys []string + obj map[string]*lazyNode +} + +type partialArray []*lazyNode + +type container interface { + get(key string, options *ApplyOptions) (*lazyNode, error) + set(key string, val *lazyNode, options *ApplyOptions) error + add(key string, val *lazyNode, options *ApplyOptions) error + remove(key string, options *ApplyOptions) error +} + +// ApplyOptions specifies options for calls to ApplyWithOptions. +// Use NewApplyOptions to obtain default values for ApplyOptions. +type ApplyOptions struct { + // SupportNegativeIndices decides whether to support non-standard practice of + // allowing negative indices to mean indices starting at the end of an array. + // Default to true. + SupportNegativeIndices bool + // AccumulatedCopySizeLimit limits the total size increase in bytes caused by + // "copy" operations in a patch. + AccumulatedCopySizeLimit int64 + // AllowMissingPathOnRemove indicates whether to fail "remove" operations when the target path is missing. + // Default to false. + AllowMissingPathOnRemove bool + // EnsurePathExistsOnAdd instructs json-patch to recursively create the missing parts of path on "add" operation. + // Default to false. + EnsurePathExistsOnAdd bool +} + +// NewApplyOptions creates a default set of options for calls to ApplyWithOptions. +func NewApplyOptions() *ApplyOptions { + return &ApplyOptions{ + SupportNegativeIndices: SupportNegativeIndices, + AccumulatedCopySizeLimit: AccumulatedCopySizeLimit, + AllowMissingPathOnRemove: false, + EnsurePathExistsOnAdd: false, + } +} + +func newLazyNode(raw *json.RawMessage) *lazyNode { + return &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw} +} + +func newRawMessage(buf []byte) *json.RawMessage { + ra := make(json.RawMessage, len(buf)) + copy(ra, buf) + return &ra +} + +func (n *lazyNode) MarshalJSON() ([]byte, error) { + switch n.which { + case eRaw: + return json.Marshal(n.raw) + case eDoc: + return json.Marshal(n.doc) + case eAry: + return json.Marshal(n.ary) + default: + return nil, ErrUnknownType + } +} + +func (n *lazyNode) UnmarshalJSON(data []byte) error { + dest := make(json.RawMessage, len(data)) + copy(dest, data) + n.raw = &dest + n.which = eRaw + return nil +} + +func (n *partialDoc) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + if _, err := buf.WriteString("{"); err != nil { + return nil, err + } + for i, k := range n.keys { + if i > 0 { + if _, err := buf.WriteString(", "); err != nil { + return nil, err + } + } + key, err := json.Marshal(k) + if err != nil { + return nil, err + } + if _, err := buf.Write(key); err != nil { + return nil, err + } + if _, err := buf.WriteString(": "); err != nil { + return nil, err + } + value, err := json.Marshal(n.obj[k]) + if err != nil { + return nil, err + } + if _, err := buf.Write(value); err != nil { + return nil, err + } + } + if _, err := buf.WriteString("}"); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +type syntaxError struct { + msg string +} + +func (err *syntaxError) Error() string { + return err.msg +} + +func (n *partialDoc) UnmarshalJSON(data []byte) error { + if err := json.Unmarshal(data, &n.obj); err != nil { + return err + } + buffer := bytes.NewBuffer(data) + d := json.NewDecoder(buffer) + if t, err := d.Token(); err != nil { + return err + } else if t != startObject { + return &syntaxError{fmt.Sprintf("unexpected JSON token in document node: %s", t)} + } + for d.More() { + k, err := d.Token() + if err != nil { + return err + } + key, ok := k.(string) + if !ok { + return &syntaxError{fmt.Sprintf("unexpected JSON token as document node key: %s", k)} + } + if err := skipValue(d); err != nil { + return err + } + n.keys = append(n.keys, key) + } + return nil +} + +func skipValue(d *json.Decoder) error { + t, err := d.Token() + if err != nil { + return err + } + if t != startObject && t != startArray { + return nil + } + for d.More() { + if t == startObject { + // consume key token + if _, err := d.Token(); err != nil { + return err + } + } + if err := skipValue(d); err != nil { + return err + } + } + end, err := d.Token() + if err != nil { + return err + } + if t == startObject && end != endObject { + return &syntaxError{msg: "expected close object token"} + } + if t == startArray && end != endArray { + return &syntaxError{msg: "expected close object token"} + } + return nil +} + +func deepCopy(src *lazyNode) (*lazyNode, int, error) { + if src == nil { + return nil, 0, nil + } + a, err := src.MarshalJSON() + if err != nil { + return nil, 0, err + } + sz := len(a) + return newLazyNode(newRawMessage(a)), sz, nil +} + +func (n *lazyNode) intoDoc() (*partialDoc, error) { + if n.which == eDoc { + return n.doc, nil + } + + if n.raw == nil { + return nil, ErrInvalid + } + + err := json.Unmarshal(*n.raw, &n.doc) + + if err != nil { + return nil, err + } + + n.which = eDoc + return n.doc, nil +} + +func (n *lazyNode) intoAry() (*partialArray, error) { + if n.which == eAry { + return &n.ary, nil + } + + if n.raw == nil { + return nil, ErrInvalid + } + + err := json.Unmarshal(*n.raw, &n.ary) + + if err != nil { + return nil, err + } + + n.which = eAry + return &n.ary, nil +} + +func (n *lazyNode) compact() []byte { + buf := &bytes.Buffer{} + + if n.raw == nil { + return nil + } + + err := json.Compact(buf, *n.raw) + + if err != nil { + return *n.raw + } + + return buf.Bytes() +} + +func (n *lazyNode) tryDoc() bool { + if n.raw == nil { + return false + } + + err := json.Unmarshal(*n.raw, &n.doc) + + if err != nil { + return false + } + + n.which = eDoc + return true +} + +func (n *lazyNode) tryAry() bool { + if n.raw == nil { + return false + } + + err := json.Unmarshal(*n.raw, &n.ary) + + if err != nil { + return false + } + + n.which = eAry + return true +} + +func (n *lazyNode) equal(o *lazyNode) bool { + if n.which == eRaw { + if !n.tryDoc() && !n.tryAry() { + if o.which != eRaw { + return false + } + + return bytes.Equal(n.compact(), o.compact()) + } + } + + if n.which == eDoc { + if o.which == eRaw { + if !o.tryDoc() { + return false + } + } + + if o.which != eDoc { + return false + } + + if len(n.doc.obj) != len(o.doc.obj) { + return false + } + + for k, v := range n.doc.obj { + ov, ok := o.doc.obj[k] + + if !ok { + return false + } + + if (v == nil) != (ov == nil) { + return false + } + + if v == nil && ov == nil { + continue + } + + if !v.equal(ov) { + return false + } + } + + return true + } + + if o.which != eAry && !o.tryAry() { + return false + } + + if len(n.ary) != len(o.ary) { + return false + } + + for idx, val := range n.ary { + if !val.equal(o.ary[idx]) { + return false + } + } + + return true +} + +// Kind reads the "op" field of the Operation. +func (o Operation) Kind() string { + if obj, ok := o["op"]; ok && obj != nil { + var op string + + err := json.Unmarshal(*obj, &op) + + if err != nil { + return "unknown" + } + + return op + } + + return "unknown" +} + +// Path reads the "path" field of the Operation. +func (o Operation) Path() (string, error) { + if obj, ok := o["path"]; ok && obj != nil { + var op string + + err := json.Unmarshal(*obj, &op) + + if err != nil { + return "unknown", err + } + + return op, nil + } + + return "unknown", errors.Wrapf(ErrMissing, "operation missing path field") +} + +// From reads the "from" field of the Operation. +func (o Operation) From() (string, error) { + if obj, ok := o["from"]; ok && obj != nil { + var op string + + err := json.Unmarshal(*obj, &op) + + if err != nil { + return "unknown", err + } + + return op, nil + } + + return "unknown", errors.Wrapf(ErrMissing, "operation, missing from field") +} + +func (o Operation) value() *lazyNode { + if obj, ok := o["value"]; ok { + return newLazyNode(obj) + } + + return nil +} + +// ValueInterface decodes the operation value into an interface. +func (o Operation) ValueInterface() (interface{}, error) { + if obj, ok := o["value"]; ok && obj != nil { + var v interface{} + + err := json.Unmarshal(*obj, &v) + + if err != nil { + return nil, err + } + + return v, nil + } + + return nil, errors.Wrapf(ErrMissing, "operation, missing value field") +} + +func isArray(buf []byte) bool { +Loop: + for _, c := range buf { + switch c { + case ' ': + case '\n': + case '\t': + continue + case '[': + return true + default: + break Loop + } + } + + return false +} + +func findObject(pd *container, path string, options *ApplyOptions) (container, string) { + doc := *pd + + split := strings.Split(path, "/") + + if len(split) < 2 { + return nil, "" + } + + parts := split[1 : len(split)-1] + + key := split[len(split)-1] + + var err error + + for _, part := range parts { + + next, ok := doc.get(decodePatchKey(part), options) + + if next == nil || ok != nil { + return nil, "" + } + + if isArray(*next.raw) { + doc, err = next.intoAry() + + if err != nil { + return nil, "" + } + } else { + doc, err = next.intoDoc() + + if err != nil { + return nil, "" + } + } + } + + return doc, decodePatchKey(key) +} + +func (d *partialDoc) set(key string, val *lazyNode, options *ApplyOptions) error { + found := false + for _, k := range d.keys { + if k == key { + found = true + break + } + } + if !found { + d.keys = append(d.keys, key) + } + d.obj[key] = val + return nil +} + +func (d *partialDoc) add(key string, val *lazyNode, options *ApplyOptions) error { + return d.set(key, val, options) +} + +func (d *partialDoc) get(key string, options *ApplyOptions) (*lazyNode, error) { + v, ok := d.obj[key] + if !ok { + return v, errors.Wrapf(ErrMissing, "unable to get nonexistent key: %s", key) + } + return v, nil +} + +func (d *partialDoc) remove(key string, options *ApplyOptions) error { + _, ok := d.obj[key] + if !ok { + if options.AllowMissingPathOnRemove { + return nil + } + return errors.Wrapf(ErrMissing, "unable to remove nonexistent key: %s", key) + } + idx := -1 + for i, k := range d.keys { + if k == key { + idx = i + break + } + } + d.keys = append(d.keys[0:idx], d.keys[idx+1:]...) + delete(d.obj, key) + return nil +} + +// set should only be used to implement the "replace" operation, so "key" must +// be an already existing index in "d". +func (d *partialArray) set(key string, val *lazyNode, options *ApplyOptions) error { + idx, err := strconv.Atoi(key) + if err != nil { + return err + } + + if idx < 0 { + if !options.SupportNegativeIndices { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + if idx < -len(*d) { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + idx += len(*d) + } + + (*d)[idx] = val + return nil +} + +func (d *partialArray) add(key string, val *lazyNode, options *ApplyOptions) error { + if key == "-" { + *d = append(*d, val) + return nil + } + + idx, err := strconv.Atoi(key) + if err != nil { + return errors.Wrapf(err, "value was not a proper array index: '%s'", key) + } + + sz := len(*d) + 1 + + ary := make([]*lazyNode, sz) + + cur := *d + + if idx >= len(ary) { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + + if idx < 0 { + if !options.SupportNegativeIndices { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + if idx < -len(ary) { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + idx += len(ary) + } + + copy(ary[0:idx], cur[0:idx]) + ary[idx] = val + copy(ary[idx+1:], cur[idx:]) + + *d = ary + return nil +} + +func (d *partialArray) get(key string, options *ApplyOptions) (*lazyNode, error) { + idx, err := strconv.Atoi(key) + + if err != nil { + return nil, err + } + + if idx < 0 { + if !options.SupportNegativeIndices { + return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + if idx < -len(*d) { + return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + idx += len(*d) + } + + if idx >= len(*d) { + return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + + return (*d)[idx], nil +} + +func (d *partialArray) remove(key string, options *ApplyOptions) error { + idx, err := strconv.Atoi(key) + if err != nil { + return err + } + + cur := *d + + if idx >= len(cur) { + if options.AllowMissingPathOnRemove { + return nil + } + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + + if idx < 0 { + if !options.SupportNegativeIndices { + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + if idx < -len(cur) { + if options.AllowMissingPathOnRemove { + return nil + } + return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx) + } + idx += len(cur) + } + + ary := make([]*lazyNode, len(cur)-1) + + copy(ary[0:idx], cur[0:idx]) + copy(ary[idx:], cur[idx+1:]) + + *d = ary + return nil +} + +func (p Patch) add(doc *container, op Operation, options *ApplyOptions) error { + path, err := op.Path() + if err != nil { + return errors.Wrapf(ErrMissing, "add operation failed to decode path") + } + + if options.EnsurePathExistsOnAdd { + err = ensurePathExists(doc, path, options) + + if err != nil { + return err + } + } + + con, key := findObject(doc, path, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "add operation does not apply: doc is missing path: \"%s\"", path) + } + + err = con.add(key, op.value(), options) + if err != nil { + return errors.Wrapf(err, "error in add for path: '%s'", path) + } + + return nil +} + +// Given a document and a path to a key, walk the path and create all missing elements +// creating objects and arrays as needed. +func ensurePathExists(pd *container, path string, options *ApplyOptions) error { + doc := *pd + + var err error + var arrIndex int + + split := strings.Split(path, "/") + + if len(split) < 2 { + return nil + } + + parts := split[1:] + + for pi, part := range parts { + + // Have we reached the key part of the path? + // If yes, we're done. + if pi == len(parts)-1 { + return nil + } + + target, ok := doc.get(decodePatchKey(part), options) + + if target == nil || ok != nil { + + // If the current container is an array which has fewer elements than our target index, + // pad the current container with nulls. + if arrIndex, err = strconv.Atoi(part); err == nil { + pa, ok := doc.(*partialArray) + + if ok && arrIndex >= len(*pa)+1 { + // Pad the array with null values up to the required index. + for i := len(*pa); i <= arrIndex-1; i++ { + doc.add(strconv.Itoa(i), newLazyNode(newRawMessage(rawJSONNull)), options) + } + } + } + + // Check if the next part is a numeric index or "-". + // If yes, then create an array, otherwise, create an object. + if arrIndex, err = strconv.Atoi(parts[pi+1]); err == nil || parts[pi+1] == "-" { + if arrIndex < 0 { + + if !options.SupportNegativeIndices { + return errors.Wrapf(ErrInvalidIndex, "Unable to ensure path for invalid index: %d", arrIndex) + } + + if arrIndex < -1 { + return errors.Wrapf(ErrInvalidIndex, "Unable to ensure path for negative index other than -1: %d", arrIndex) + } + + arrIndex = 0 + } + + newNode := newLazyNode(newRawMessage(rawJSONArray)) + doc.add(part, newNode, options) + doc, _ = newNode.intoAry() + + // Pad the new array with null values up to the required index. + for i := 0; i < arrIndex; i++ { + doc.add(strconv.Itoa(i), newLazyNode(newRawMessage(rawJSONNull)), options) + } + } else { + newNode := newLazyNode(newRawMessage(rawJSONObject)) + + doc.add(part, newNode, options) + doc, _ = newNode.intoDoc() + } + } else { + if isArray(*target.raw) { + doc, err = target.intoAry() + + if err != nil { + return err + } + } else { + doc, err = target.intoDoc() + + if err != nil { + return err + } + } + } + } + + return nil +} + +func (p Patch) remove(doc *container, op Operation, options *ApplyOptions) error { + path, err := op.Path() + if err != nil { + return errors.Wrapf(ErrMissing, "remove operation failed to decode path") + } + + con, key := findObject(doc, path, options) + + if con == nil { + if options.AllowMissingPathOnRemove { + return nil + } + return errors.Wrapf(ErrMissing, "remove operation does not apply: doc is missing path: \"%s\"", path) + } + + err = con.remove(key, options) + if err != nil { + return errors.Wrapf(err, "error in remove for path: '%s'", path) + } + + return nil +} + +func (p Patch) replace(doc *container, op Operation, options *ApplyOptions) error { + path, err := op.Path() + if err != nil { + return errors.Wrapf(err, "replace operation failed to decode path") + } + + if path == "" { + val := op.value() + + if val.which == eRaw { + if !val.tryDoc() { + if !val.tryAry() { + return errors.Wrapf(err, "replace operation value must be object or array") + } + } + } + + switch val.which { + case eAry: + *doc = &val.ary + case eDoc: + *doc = val.doc + case eRaw: + return errors.Wrapf(err, "replace operation hit impossible case") + } + + return nil + } + + con, key := findObject(doc, path, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing path: %s", path) + } + + _, ok := con.get(key, options) + if ok != nil { + return errors.Wrapf(ErrMissing, "replace operation does not apply: doc is missing key: %s", path) + } + + err = con.set(key, op.value(), options) + if err != nil { + return errors.Wrapf(err, "error in remove for path: '%s'", path) + } + + return nil +} + +func (p Patch) move(doc *container, op Operation, options *ApplyOptions) error { + from, err := op.From() + if err != nil { + return errors.Wrapf(err, "move operation failed to decode from") + } + + con, key := findObject(doc, from, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing from path: %s", from) + } + + val, err := con.get(key, options) + if err != nil { + return errors.Wrapf(err, "error in move for path: '%s'", key) + } + + err = con.remove(key, options) + if err != nil { + return errors.Wrapf(err, "error in move for path: '%s'", key) + } + + path, err := op.Path() + if err != nil { + return errors.Wrapf(err, "move operation failed to decode path") + } + + con, key = findObject(doc, path, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "move operation does not apply: doc is missing destination path: %s", path) + } + + err = con.add(key, val, options) + if err != nil { + return errors.Wrapf(err, "error in move for path: '%s'", path) + } + + return nil +} + +func (p Patch) test(doc *container, op Operation, options *ApplyOptions) error { + path, err := op.Path() + if err != nil { + return errors.Wrapf(err, "test operation failed to decode path") + } + + if path == "" { + var self lazyNode + + switch sv := (*doc).(type) { + case *partialDoc: + self.doc = sv + self.which = eDoc + case *partialArray: + self.ary = *sv + self.which = eAry + } + + if self.equal(op.value()) { + return nil + } + + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + } + + con, key := findObject(doc, path, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "test operation does not apply: is missing path: %s", path) + } + + val, err := con.get(key, options) + if err != nil && errors.Cause(err) != ErrMissing { + return errors.Wrapf(err, "error in test for path: '%s'", path) + } + + if val == nil { + if op.value().raw == nil { + return nil + } + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + } else if op.value() == nil { + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + } + + if val.equal(op.value()) { + return nil + } + + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) +} + +func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64, options *ApplyOptions) error { + from, err := op.From() + if err != nil { + return errors.Wrapf(err, "copy operation failed to decode from") + } + + con, key := findObject(doc, from, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing from path: %s", from) + } + + val, err := con.get(key, options) + if err != nil { + return errors.Wrapf(err, "error in copy for from: '%s'", from) + } + + path, err := op.Path() + if err != nil { + return errors.Wrapf(ErrMissing, "copy operation failed to decode path") + } + + con, key = findObject(doc, path, options) + + if con == nil { + return errors.Wrapf(ErrMissing, "copy operation does not apply: doc is missing destination path: %s", path) + } + + valCopy, sz, err := deepCopy(val) + if err != nil { + return errors.Wrapf(err, "error while performing deep copy") + } + + (*accumulatedCopySize) += int64(sz) + if options.AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > options.AccumulatedCopySizeLimit { + return NewAccumulatedCopySizeError(options.AccumulatedCopySizeLimit, *accumulatedCopySize) + } + + err = con.add(key, valCopy, options) + if err != nil { + return errors.Wrapf(err, "error while adding value during copy") + } + + return nil +} + +// Equal indicates if 2 JSON documents have the same structural equality. +func Equal(a, b []byte) bool { + la := newLazyNode(newRawMessage(a)) + lb := newLazyNode(newRawMessage(b)) + + return la.equal(lb) +} + +// DecodePatch decodes the passed JSON document as an RFC 6902 patch. +func DecodePatch(buf []byte) (Patch, error) { + var p Patch + + err := json.Unmarshal(buf, &p) + + if err != nil { + return nil, err + } + + return p, nil +} + +// Apply mutates a JSON document according to the patch, and returns the new +// document. +func (p Patch) Apply(doc []byte) ([]byte, error) { + return p.ApplyWithOptions(doc, NewApplyOptions()) +} + +// ApplyWithOptions mutates a JSON document according to the patch and the passed in ApplyOptions. +// It returns the new document. +func (p Patch) ApplyWithOptions(doc []byte, options *ApplyOptions) ([]byte, error) { + return p.ApplyIndentWithOptions(doc, "", options) +} + +// ApplyIndent mutates a JSON document according to the patch, and returns the new +// document indented. +func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { + return p.ApplyIndentWithOptions(doc, indent, NewApplyOptions()) +} + +// ApplyIndentWithOptions mutates a JSON document according to the patch and the passed in ApplyOptions. +// It returns the new document indented. +func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyOptions) ([]byte, error) { + if len(doc) == 0 { + return doc, nil + } + + var pd container + if doc[0] == '[' { + pd = &partialArray{} + } else { + pd = &partialDoc{} + } + + err := json.Unmarshal(doc, pd) + + if err != nil { + return nil, err + } + + err = nil + + var accumulatedCopySize int64 + + for _, op := range p { + switch op.Kind() { + case "add": + err = p.add(&pd, op, options) + case "remove": + err = p.remove(&pd, op, options) + case "replace": + err = p.replace(&pd, op, options) + case "move": + err = p.move(&pd, op, options) + case "test": + err = p.test(&pd, op, options) + case "copy": + err = p.copy(&pd, op, &accumulatedCopySize, options) + default: + err = fmt.Errorf("Unexpected kind: %s", op.Kind()) + } + + if err != nil { + return nil, err + } + } + + if indent != "" { + return json.MarshalIndent(pd, "", indent) + } + + return json.Marshal(pd) +} + +// From http://tools.ietf.org/html/rfc6901#section-4 : +// +// Evaluation of each reference token begins by decoding any escaped +// character sequence. This is performed by first transforming any +// occurrence of the sequence '~1' to '/', and then transforming any +// occurrence of the sequence '~0' to '~'. + +var ( + rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") +) + +func decodePatchKey(k string) string { + return rfc6901Decoder.Replace(k) +} diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore deleted file mode 100644 index e256a31e00a..00000000000 --- a/vendor/github.com/ghodss/yaml/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# OSX leaves these everywhere on SMB shares -._* - -# Eclipse files -.classpath -.project -.settings/** - -# Emacs save files -*~ - -# Vim-related files -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist - -# Go test binaries -*.test diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml deleted file mode 100644 index 0e9d6edc010..00000000000 --- a/vendor/github.com/ghodss/yaml/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -go: - - 1.3 - - 1.4 -script: - - go test - - go build diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE deleted file mode 100644 index 7805d36de73..00000000000 --- a/vendor/github.com/ghodss/yaml/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sam Ghods - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md deleted file mode 100644 index 0200f75b4d1..00000000000 --- a/vendor/github.com/ghodss/yaml/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# YAML marshaling and unmarshaling support for Go - -[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) - -## Introduction - -A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. - -In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). - -## Compatibility - -This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). - -## Caveats - -**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example: - -``` -BAD: - exampleKey: !!binary gIGC - -GOOD: - exampleKey: gIGC -... and decode the base64 data in your code. -``` - -**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys. - -## Installation and usage - -To install, run: - -``` -$ go get github.com/ghodss/yaml -``` - -And import using: - -``` -import "github.com/ghodss/yaml" -``` - -Usage is very similar to the JSON library: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -type Person struct { - Name string `json:"name"` // Affects YAML field names too. - Age int `json:"age"` -} - -func main() { - // Marshal a Person struct to YAML. - p := Person{"John", 30} - y, err := yaml.Marshal(p) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - age: 30 - name: John - */ - - // Unmarshal the YAML back into a Person struct. - var p2 Person - err = yaml.Unmarshal(y, &p2) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(p2) - /* Output: - {John 30} - */ -} -``` - -`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -func main() { - j := []byte(`{"name": "John", "age": 30}`) - y, err := yaml.JSONToYAML(j) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - name: John - age: 30 - */ - j2, err := yaml.YAMLToJSON(y) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(j2)) - /* Output: - {"age":30,"name":"John"} - */ -} -``` diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go deleted file mode 100644 index 58600740266..00000000000 --- a/vendor/github.com/ghodss/yaml/fields.go +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package yaml - -import ( - "bytes" - "encoding" - "encoding/json" - "reflect" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - if v.CanSet() { - v.Set(reflect.New(v.Type().Elem())) - } else { - v = reflect.New(v.Type().Elem()) - } - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// A field represents a single field found in a struct. -type field struct { - name string - nameBytes []byte // []byte(name) - equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent - - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -func fillField(f field) field { - f.nameBytes = []byte(f.name) - f.equalFold = foldFunc(f.nameBytes) - return f -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that JSON should recognize for the given type. -// The algorithm is breadth-first search over the set of structs to include - the top struct -// and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, fillField(field{ - name: name, - tag: tagged, - index: index, - typ: ft, - omitEmpty: opts.Contains("omitempty"), - quoted: opts.Contains("string"), - })) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// JSON tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -const ( - caseMask = ^byte(0x20) // Mask to ignore case in ASCII. - kelvin = '\u212a' - smallLongEss = '\u017f' -) - -// foldFunc returns one of four different case folding equivalence -// functions, from most general (and slow) to fastest: -// -// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 -// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') -// 3) asciiEqualFold, no special, but includes non-letters (including _) -// 4) simpleLetterEqualFold, no specials, no non-letters. -// -// The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign -// See http://play.golang.org/p/tTxjOc0OGo -// -// The returned function is specialized for matching against s and -// should only be given s. It's not curried for performance reasons. -func foldFunc(s []byte) func(s, t []byte) bool { - nonLetter := false - special := false // special letter - for _, b := range s { - if b >= utf8.RuneSelf { - return bytes.EqualFold - } - upper := b & caseMask - if upper < 'A' || upper > 'Z' { - nonLetter = true - } else if upper == 'K' || upper == 'S' { - // See above for why these letters are special. - special = true - } - } - if special { - return equalFoldRight - } - if nonLetter { - return asciiEqualFold - } - return simpleLetterEqualFold -} - -// equalFoldRight is a specialization of bytes.EqualFold when s is -// known to be all ASCII (including punctuation), but contains an 's', -// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. -// See comments on foldFunc. -func equalFoldRight(s, t []byte) bool { - for _, sb := range s { - if len(t) == 0 { - return false - } - tb := t[0] - if tb < utf8.RuneSelf { - if sb != tb { - sbUpper := sb & caseMask - if 'A' <= sbUpper && sbUpper <= 'Z' { - if sbUpper != tb&caseMask { - return false - } - } else { - return false - } - } - t = t[1:] - continue - } - // sb is ASCII and t is not. t must be either kelvin - // sign or long s; sb must be s, S, k, or K. - tr, size := utf8.DecodeRune(t) - switch sb { - case 's', 'S': - if tr != smallLongEss { - return false - } - case 'k', 'K': - if tr != kelvin { - return false - } - default: - return false - } - t = t[size:] - - } - if len(t) > 0 { - return false - } - return true -} - -// asciiEqualFold is a specialization of bytes.EqualFold for use when -// s is all ASCII (but may contain non-letters) and contains no -// special-folding letters. -// See comments on foldFunc. -func asciiEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, sb := range s { - tb := t[i] - if sb == tb { - continue - } - if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { - if sb&caseMask != tb&caseMask { - return false - } - } else { - return false - } - } - return true -} - -// simpleLetterEqualFold is a specialization of bytes.EqualFold for -// use when s is all ASCII letters (no underscores, etc) and also -// doesn't contain 'k', 'K', 's', or 'S'. -// See comments on foldFunc. -func simpleLetterEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, b := range s { - if b&caseMask != t[i]&caseMask { - return false - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// Contains reports whether a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go deleted file mode 100644 index 4fb4054a8b7..00000000000 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ /dev/null @@ -1,277 +0,0 @@ -package yaml - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" - "strconv" - - "gopkg.in/yaml.v2" -) - -// Marshals the object into JSON then converts JSON to YAML and returns the -// YAML. -func Marshal(o interface{}) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - y, err := JSONToYAML(j) - if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: %v", err) - } - - return y, nil -} - -// Converts YAML to JSON then uses JSON to unmarshal into an object. -func Unmarshal(y []byte, o interface{}) error { - vo := reflect.ValueOf(o) - j, err := yamlToJSON(y, &vo) - if err != nil { - return fmt.Errorf("error converting YAML to JSON: %v", err) - } - - err = json.Unmarshal(j, o) - if err != nil { - return fmt.Errorf("error unmarshaling JSON: %v", err) - } - - return nil -} - -// Convert JSON to YAML. -func JSONToYAML(j []byte) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - err := yaml.Unmarshal(j, &jsonObj) - if err != nil { - return nil, err - } - - // Marshal this object into YAML. - return yaml.Marshal(jsonObj) -} - -// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through -// this method should be a no-op. -// -// Things YAML can do that are not supported by JSON: -// * In YAML you can have binary and null keys in your maps. These are invalid -// in JSON. (int and float keys are converted to strings.) -// * Binary data in YAML with the !!binary tag is not supported. If you want to -// use binary data with this library, encode the data as base64 as usual but do -// not use the !!binary tag in your YAML. This will ensure the original base64 -// encoded data makes it all the way through to the JSON. -func YAMLToJSON(y []byte) ([]byte, error) { - return yamlToJSON(y, nil) -} - -func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { - // Convert the YAML to an object. - var yamlObj interface{} - err := yaml.Unmarshal(y, &yamlObj) - if err != nil { - return nil, err - } - - // YAML objects are not completely compatible with JSON objects (e.g. you - // can have non-string keys in YAML). So, convert the YAML-compatible object - // to a JSON-compatible object, failing with an error if irrecoverable - // incompatibilties happen along the way. - jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) - if err != nil { - return nil, err - } - - // Convert this object to JSON and return the data. - return json.Marshal(jsonObj) -} - -func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { - var err error - - // Resolve jsonTarget to a concrete value (i.e. not a pointer or an - // interface). We pass decodingNull as false because we're not actually - // decoding into the value, we're just checking if the ultimate target is a - // string. - if jsonTarget != nil { - ju, tu, pv := indirect(*jsonTarget, false) - // We have a JSON or Text Umarshaler at this level, so we can't be trying - // to decode into a string. - if ju != nil || tu != nil { - jsonTarget = nil - } else { - jsonTarget = &pv - } - } - - // If yamlObj is a number or a boolean, check if jsonTarget is a string - - // if so, coerce. Else return normal. - // If yamlObj is a map or array, find the field that each key is - // unmarshaling to, and when you recurse pass the reflect.Value for that - // field back into this function. - switch typedYAMLObj := yamlObj.(type) { - case map[interface{}]interface{}: - // JSON does not support arbitrary keys in a map, so we must convert - // these keys to strings. - // - // From my reading of go-yaml v2 (specifically the resolve function), - // keys can only have the types string, int, int64, float64, binary - // (unsupported), or null (unsupported). - strMap := make(map[string]interface{}) - for k, v := range typedYAMLObj { - // Resolve the key to a string first. - var keyString string - switch typedKey := k.(type) { - case string: - keyString = typedKey - case int: - keyString = strconv.Itoa(typedKey) - case int64: - // go-yaml will only return an int64 as a key if the system - // architecture is 32-bit and the key's value is between 32-bit - // and 64-bit. Otherwise the key type will simply be int. - keyString = strconv.FormatInt(typedKey, 10) - case float64: - // Stolen from go-yaml to use the same conversion to string as - // the go-yaml library uses to convert float to string when - // Marshaling. - s := strconv.FormatFloat(typedKey, 'g', -1, 32) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - keyString = s - case bool: - if typedKey { - keyString = "true" - } else { - keyString = "false" - } - default: - return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", - reflect.TypeOf(k), k, v) - } - - // jsonTarget should be a struct or a map. If it's a struct, find - // the field it's going to map to and pass its reflect.Value. If - // it's a map, find the element type of the map and pass the - // reflect.Value created from that type. If it's neither, just pass - // nil - JSON conversion will error for us if it's a real issue. - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Struct { - keyBytes := []byte(keyString) - // Find the field that the JSON library would use. - var f *field - fields := cachedTypeFields(t.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, keyBytes) { - f = ff - break - } - // Do case-insensitive comparison. - if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { - f = ff - } - } - if f != nil { - // Find the reflect.Value of the most preferential - // struct field. - jtf := t.Field(f.index[0]) - strMap[keyString], err = convertToJSONableObject(v, &jtf) - if err != nil { - return nil, err - } - continue - } - } else if t.Kind() == reflect.Map { - // Create a zero value of the map's element type to use as - // the JSON target. - jtv := reflect.Zero(t.Type().Elem()) - strMap[keyString], err = convertToJSONableObject(v, &jtv) - if err != nil { - return nil, err - } - continue - } - } - strMap[keyString], err = convertToJSONableObject(v, nil) - if err != nil { - return nil, err - } - } - return strMap, nil - case []interface{}: - // We need to recurse into arrays in case there are any - // map[interface{}]interface{}'s inside and to convert any - // numbers to strings. - - // If jsonTarget is a slice (which it really should be), find the - // thing it's going to map to. If it's not a slice, just pass nil - // - JSON conversion will error for us if it's a real issue. - var jsonSliceElemValue *reflect.Value - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Slice { - // By default slices point to nil, but we need a reflect.Value - // pointing to a value of the slice type, so we create one here. - ev := reflect.Indirect(reflect.New(t.Type().Elem())) - jsonSliceElemValue = &ev - } - } - - // Make and use a new array. - arr := make([]interface{}, len(typedYAMLObj)) - for i, v := range typedYAMLObj { - arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) - if err != nil { - return nil, err - } - } - return arr, nil - default: - // If the target type is a string and the YAML type is a number, - // convert the YAML type to a string. - if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { - // Based on my reading of go-yaml, it may return int, int64, - // float64, or uint64. - var s string - switch typedVal := typedYAMLObj.(type) { - case int: - s = strconv.FormatInt(int64(typedVal), 10) - case int64: - s = strconv.FormatInt(typedVal, 10) - case float64: - s = strconv.FormatFloat(typedVal, 'g', -1, 32) - case uint64: - s = strconv.FormatUint(typedVal, 10) - case bool: - if typedVal { - s = "true" - } else { - s = "false" - } - } - if len(s) > 0 { - yamlObj = interface{}(s) - } - } - return yamlObj, nil - } - - return nil, nil -} diff --git a/vendor/github.com/go-chi/chi/v5/.gitignore b/vendor/github.com/go-chi/chi/v5/.gitignore new file mode 100644 index 00000000000..ba22c99a99e --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/.gitignore @@ -0,0 +1,3 @@ +.idea +*.sw? +.vscode diff --git a/vendor/github.com/go-chi/chi/v5/CHANGELOG.md b/vendor/github.com/go-chi/chi/v5/CHANGELOG.md new file mode 100644 index 00000000000..a1feeec0551 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/CHANGELOG.md @@ -0,0 +1,320 @@ +# Changelog + +## v5.0.8 (2022-12-07) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.7...v5.0.8 + + +## v5.0.7 (2021-11-18) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.6...v5.0.7 + + +## v5.0.6 (2021-11-15) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.5...v5.0.6 + + +## v5.0.5 (2021-10-27) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.4...v5.0.5 + + +## v5.0.4 (2021-08-29) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.3...v5.0.4 + + +## v5.0.3 (2021-04-29) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.2...v5.0.3 + + +## v5.0.2 (2021-03-25) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.1...v5.0.2 + + +## v5.0.1 (2021-03-10) + +- Small improvements +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.0...v5.0.1 + + +## v5.0.0 (2021-02-27) + +- chi v5, `github.com/go-chi/chi/v5` introduces the adoption of Go's SIV to adhere to the current state-of-the-tools in Go. +- chi v1.5.x did not work out as planned, as the Go tooling is too powerful and chi's adoption is too wide. + The most responsible thing to do for everyone's benefit is to just release v5 with SIV, so I present to you all, + chi v5 at `github.com/go-chi/chi/v5`. I hope someday the developer experience and ergonomics I've been seeking + will still come to fruition in some form, see https://github.com/golang/go/issues/44550 +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.4...v5.0.0 + + +## v1.5.4 (2021-02-27) + +- Undo prior retraction in v1.5.3 as we prepare for v5.0.0 release +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.3...v1.5.4 + + +## v1.5.3 (2021-02-21) + +- Update go.mod to go 1.16 with new retract directive marking all versions without prior go.mod support +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.2...v1.5.3 + + +## v1.5.2 (2021-02-10) + +- Reverting allocation optimization as a precaution as go test -race fails. +- Minor improvements, see history below +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.1...v1.5.2 + + +## v1.5.1 (2020-12-06) + +- Performance improvement: removing 1 allocation by foregoing context.WithValue, thank you @bouk for + your contribution (https://github.com/go-chi/chi/pull/555). Note: new benchmarks posted in README. +- `middleware.CleanPath`: new middleware that clean's request path of double slashes +- deprecate & remove `chi.ServerBaseContext` in favour of stdlib `http.Server#BaseContext` +- plus other tiny improvements, see full commit history below +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.2...v1.5.1 + + +## v1.5.0 (2020-11-12) - now with go.mod support + +`chi` dates back to 2016 with it's original implementation as one of the first routers to adopt the newly introduced +context.Context api to the stdlib -- set out to design a router that is faster, more modular and simpler than anything +else out there -- while not introducing any custom handler types or dependencies. Today, `chi` still has zero dependencies, +and in many ways is future proofed from changes, given it's minimal nature. Between versions, chi's iterations have been very +incremental, with the architecture and api being the same today as it was originally designed in 2016. For this reason it +makes chi a pretty easy project to maintain, as well thanks to the many amazing community contributions over the years +to who all help make chi better (total of 86 contributors to date -- thanks all!). + +Chi has been an labour of love, art and engineering, with the goals to offer beautiful ergonomics, flexibility, performance +and simplicity when building HTTP services with Go. I've strived to keep the router very minimal in surface area / code size, +and always improving the code wherever possible -- and as of today the `chi` package is just 1082 lines of code (not counting +middlewares, which are all optional). As well, I don't have the exact metrics, but from my analysis and email exchanges from +companies and developers, chi is used by thousands of projects around the world -- thank you all as there is no better form of +joy for me than to have art I had started be helpful and enjoyed by others. And of course I use chi in all of my own projects too :) + +For me, the asthetics of chi's code and usage are very important. With the introduction of Go's module support +(which I'm a big fan of), chi's past versioning scheme choice to v2, v3 and v4 would mean I'd require the import path +of "github.com/go-chi/chi/v4", leading to the lengthy discussion at https://github.com/go-chi/chi/issues/462. +Haha, to some, you may be scratching your head why I've spent > 1 year stalling to adopt "/vXX" convention in the import +path -- which isn't horrible in general -- but for chi, I'm unable to accept it as I strive for perfection in it's API design, +aesthetics and simplicity. It just doesn't feel good to me given chi's simple nature -- I do not foresee a "v5" or "v6", +and upgrading between versions in the future will also be just incremental. + +I do understand versioning is a part of the API design as well, which is why the solution for a while has been to "do nothing", +as Go supports both old and new import paths with/out go.mod. However, now that Go module support has had time to iron out kinks and +is adopted everywhere, it's time for chi to get with the times. Luckily, I've discovered a path forward that will make me happy, +while also not breaking anyone's app who adopted a prior versioning from tags in v2/v3/v4. I've made an experimental release of +v1.5.0 with go.mod silently, and tested it with new and old projects, to ensure the developer experience is preserved, and it's +largely unnoticed. Fortunately, Go's toolchain will check the tags of a repo and consider the "latest" tag the one with go.mod. +However, you can still request a specific older tag such as v4.1.2, and everything will "just work". But new users can just +`go get github.com/go-chi/chi` or `go get github.com/go-chi/chi@latest` and they will get the latest version which contains +go.mod support, which is v1.5.0+. `chi` will not change very much over the years, just like it hasn't changed much from 4 years ago. +Therefore, we will stay on v1.x from here on, starting from v1.5.0. Any breaking changes will bump a "minor" release and +backwards-compatible improvements/fixes will bump a "tiny" release. + +For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`, +which will get you on the go.mod version line (as Go's mod cache may still remember v4.x). Brand new systems can run +`go get -u github.com/go-chi/chi` or `go get -u github.com/go-chi/chi@latest` to install chi, which will install v1.5.0+ +built with go.mod support. + +My apologies to the developers who will disagree with the decisions above, but, hope you'll try it and see it's a very +minor request which is backwards compatible and won't break your existing installations. + +Cheers all, happy coding! + + +--- + + +## v4.1.2 (2020-06-02) + +- fix that handles MethodNotAllowed with path variables, thank you @caseyhadden for your contribution +- fix to replace nested wildcards correctly in RoutePattern, thank you @@unmultimedio for your contribution +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.1...v4.1.2 + + +## v4.1.1 (2020-04-16) + +- fix for issue https://github.com/go-chi/chi/issues/411 which allows for overlapping regexp + route to the correct handler through a recursive tree search, thanks to @Jahaja for the PR/fix! +- new middleware.RouteHeaders as a simple router for request headers with wildcard support +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.0...v4.1.1 + + +## v4.1.0 (2020-04-1) + +- middleware.LogEntry: Write method on interface now passes the response header + and an extra interface type useful for custom logger implementations. +- middleware.WrapResponseWriter: minor fix +- middleware.Recoverer: a bit prettier +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.4...v4.1.0 + +## v4.0.4 (2020-03-24) + +- middleware.Recoverer: new pretty stack trace printing (https://github.com/go-chi/chi/pull/496) +- a few minor improvements and fixes +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.3...v4.0.4 + + +## v4.0.3 (2020-01-09) + +- core: fix regexp routing to include default value when param is not matched +- middleware: rewrite of middleware.Compress +- middleware: suppress http.ErrAbortHandler in middleware.Recoverer +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.2...v4.0.3 + + +## v4.0.2 (2019-02-26) + +- Minor fixes +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.1...v4.0.2 + + +## v4.0.1 (2019-01-21) + +- Fixes issue with compress middleware: #382 #385 +- History of changes: see https://github.com/go-chi/chi/compare/v4.0.0...v4.0.1 + + +## v4.0.0 (2019-01-10) + +- chi v4 requires Go 1.10.3+ (or Go 1.9.7+) - we have deprecated support for Go 1.7 and 1.8 +- router: respond with 404 on router with no routes (#362) +- router: additional check to ensure wildcard is at the end of a url pattern (#333) +- middleware: deprecate use of http.CloseNotifier (#347) +- middleware: fix RedirectSlashes to include query params on redirect (#334) +- History of changes: see https://github.com/go-chi/chi/compare/v3.3.4...v4.0.0 + + +## v3.3.4 (2019-01-07) + +- Minor middleware improvements. No changes to core library/router. Moving v3 into its +- own branch as a version of chi for Go 1.7, 1.8, 1.9, 1.10, 1.11 +- History of changes: see https://github.com/go-chi/chi/compare/v3.3.3...v3.3.4 + + +## v3.3.3 (2018-08-27) + +- Minor release +- See https://github.com/go-chi/chi/compare/v3.3.2...v3.3.3 + + +## v3.3.2 (2017-12-22) + +- Support to route trailing slashes on mounted sub-routers (#281) +- middleware: new `ContentCharset` to check matching charsets. Thank you + @csucu for your community contribution! + + +## v3.3.1 (2017-11-20) + +- middleware: new `AllowContentType` handler for explicit whitelist of accepted request Content-Types +- middleware: new `SetHeader` handler for short-hand middleware to set a response header key/value +- Minor bug fixes + + +## v3.3.0 (2017-10-10) + +- New chi.RegisterMethod(method) to add support for custom HTTP methods, see _examples/custom-method for usage +- Deprecated LINK and UNLINK methods from the default list, please use `chi.RegisterMethod("LINK")` and `chi.RegisterMethod("UNLINK")` in an `init()` function + + +## v3.2.1 (2017-08-31) + +- Add new `Match(rctx *Context, method, path string) bool` method to `Routes` interface + and `Mux`. Match searches the mux's routing tree for a handler that matches the method/path +- Add new `RouteMethod` to `*Context` +- Add new `Routes` pointer to `*Context` +- Add new `middleware.GetHead` to route missing HEAD requests to GET handler +- Updated benchmarks (see README) + + +## v3.1.5 (2017-08-02) + +- Setup golint and go vet for the project +- As per golint, we've redefined `func ServerBaseContext(h http.Handler, baseCtx context.Context) http.Handler` + to `func ServerBaseContext(baseCtx context.Context, h http.Handler) http.Handler` + + +## v3.1.0 (2017-07-10) + +- Fix a few minor issues after v3 release +- Move `docgen` sub-pkg to https://github.com/go-chi/docgen +- Move `render` sub-pkg to https://github.com/go-chi/render +- Add new `URLFormat` handler to chi/middleware sub-pkg to make working with url mime + suffixes easier, ie. parsing `/articles/1.json` and `/articles/1.xml`. See comments in + https://github.com/go-chi/chi/blob/master/middleware/url_format.go for example usage. + + +## v3.0.0 (2017-06-21) + +- Major update to chi library with many exciting updates, but also some *breaking changes* +- URL parameter syntax changed from `/:id` to `/{id}` for even more flexible routing, such as + `/articles/{month}-{day}-{year}-{slug}`, `/articles/{id}`, and `/articles/{id}.{ext}` on the + same router +- Support for regexp for routing patterns, in the form of `/{paramKey:regExp}` for example: + `r.Get("/articles/{name:[a-z]+}", h)` and `chi.URLParam(r, "name")` +- Add `Method` and `MethodFunc` to `chi.Router` to allow routing definitions such as + `r.Method("GET", "/", h)` which provides a cleaner interface for custom handlers like + in `_examples/custom-handler` +- Deprecating `mux#FileServer` helper function. Instead, we encourage users to create their + own using file handler with the stdlib, see `_examples/fileserver` for an example +- Add support for LINK/UNLINK http methods via `r.Method()` and `r.MethodFunc()` +- Moved the chi project to its own organization, to allow chi-related community packages to + be easily discovered and supported, at: https://github.com/go-chi +- *NOTE:* please update your import paths to `"github.com/go-chi/chi"` +- *NOTE:* chi v2 is still available at https://github.com/go-chi/chi/tree/v2 + + +## v2.1.0 (2017-03-30) + +- Minor improvements and update to the chi core library +- Introduced a brand new `chi/render` sub-package to complete the story of building + APIs to offer a pattern for managing well-defined request / response payloads. Please + check out the updated `_examples/rest` example for how it works. +- Added `MethodNotAllowed(h http.HandlerFunc)` to chi.Router interface + + +## v2.0.0 (2017-01-06) + +- After many months of v2 being in an RC state with many companies and users running it in + production, the inclusion of some improvements to the middlewares, we are very pleased to + announce v2.0.0 of chi. + + +## v2.0.0-rc1 (2016-07-26) + +- Huge update! chi v2 is a large refactor targetting Go 1.7+. As of Go 1.7, the popular + community `"net/context"` package has been included in the standard library as `"context"` and + utilized by `"net/http"` and `http.Request` to managing deadlines, cancelation signals and other + request-scoped values. We're very excited about the new context addition and are proud to + introduce chi v2, a minimal and powerful routing package for building large HTTP services, + with zero external dependencies. Chi focuses on idiomatic design and encourages the use of + stdlib HTTP handlers and middlwares. +- chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc` +- chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()` +- chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`, + which provides direct access to URL routing parameters, the routing path and the matching + routing patterns. +- Users upgrading from chi v1 to v2, need to: + 1. Update the old chi.Handler signature, `func(ctx context.Context, w http.ResponseWriter, r *http.Request)` to + the standard http.Handler: `func(w http.ResponseWriter, r *http.Request)` + 2. Use `chi.URLParam(r *http.Request, paramKey string) string` + or `URLParamFromCtx(ctx context.Context, paramKey string) string` to access a url parameter value + + +## v1.0.0 (2016-07-01) + +- Released chi v1 stable https://github.com/go-chi/chi/tree/v1.0.0 for Go 1.6 and older. + + +## v0.9.0 (2016-03-31) + +- Reuse context objects via sync.Pool for zero-allocation routing [#33](https://github.com/go-chi/chi/pull/33) +- BREAKING NOTE: due to subtle API changes, previously `chi.URLParams(ctx)["id"]` used to access url parameters + has changed to: `chi.URLParam(ctx, "id")` diff --git a/vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md b/vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md new file mode 100644 index 00000000000..c0ac2dfe853 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +## Prerequisites + +1. [Install Go][go-install]. +2. Download the sources and switch the working directory: + + ```bash + go get -u -d github.com/go-chi/chi + cd $GOPATH/src/github.com/go-chi/chi + ``` + +## Submitting a Pull Request + +A typical workflow is: + +1. [Fork the repository.][fork] [This tip maybe also helpful.][go-fork-tip] +2. [Create a topic branch.][branch] +3. Add tests for your change. +4. Run `go test`. If your tests pass, return to the step 3. +5. Implement the change and ensure the steps from the previous step pass. +6. Run `goimports -w .`, to ensure the new code conforms to Go formatting guideline. +7. [Add, commit and push your changes.][git-help] +8. [Submit a pull request.][pull-req] + +[go-install]: https://golang.org/doc/install +[go-fork-tip]: http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html +[fork]: https://help.github.com/articles/fork-a-repo +[branch]: http://learn.github.com/p/branching.html +[git-help]: https://guides.github.com +[pull-req]: https://help.github.com/articles/using-pull-requests diff --git a/vendor/github.com/go-chi/chi/v5/LICENSE b/vendor/github.com/go-chi/chi/v5/LICENSE new file mode 100644 index 00000000000..d99f02ffac5 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-chi/chi/v5/Makefile b/vendor/github.com/go-chi/chi/v5/Makefile new file mode 100644 index 00000000000..e0f18c7da21 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/Makefile @@ -0,0 +1,22 @@ +.PHONY: all +all: + @echo "**********************************************************" + @echo "** chi build tool **" + @echo "**********************************************************" + + +.PHONY: test +test: + go clean -testcache && $(MAKE) test-router && $(MAKE) test-middleware + +.PHONY: test-router +test-router: + go test -race -v . + +.PHONY: test-middleware +test-middleware: + go test -race -v ./middleware + +.PHONY: docs +docs: + npx docsify-cli serve ./docs diff --git a/vendor/github.com/go-chi/chi/v5/README.md b/vendor/github.com/go-chi/chi/v5/README.md new file mode 100644 index 00000000000..3e4cc4a2e1a --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/README.md @@ -0,0 +1,500 @@ +# chi + + +[![GoDoc Widget]][GoDoc] [![Travis Widget]][Travis] + +`chi` is a lightweight, idiomatic and composable router for building Go HTTP services. It's +especially good at helping you write large REST API services that are kept maintainable as your +project grows and changes. `chi` is built on the new `context` package introduced in Go 1.7 to +handle signaling, cancelation and request-scoped values across a handler chain. + +The focus of the project has been to seek out an elegant and comfortable design for writing +REST API servers, written during the development of the Pressly API service that powers our +public API service, which in turn powers all of our client-side applications. + +The key considerations of chi's design are: project structure, maintainability, standard http +handlers (stdlib-only), developer productivity, and deconstructing a large system into many small +parts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also +included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render) +and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too! + +## Install + +`go get -u github.com/go-chi/chi/v5` + + +## Features + +* **Lightweight** - cloc'd in ~1000 LOC for the chi router +* **Fast** - yes, see [benchmarks](#benchmarks) +* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http` +* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and sub-router mounting +* **Context control** - built on new `context` package, providing value chaining, cancellations and timeouts +* **Robust** - in production at Pressly, Cloudflare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91)) +* **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown +* **Go.mod support** - as of v5, go.mod support (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)) +* **No external dependencies** - plain ol' Go stdlib + net/http + + +## Examples + +See [_examples/](https://github.com/go-chi/chi/blob/master/_examples/) for a variety of examples. + + +**As easy as:** + +```go +package main + +import ( + "net/http" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" +) + +func main() { + r := chi.NewRouter() + r.Use(middleware.Logger) + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("welcome")) + }) + http.ListenAndServe(":3000", r) +} +``` + +**REST Preview:** + +Here is a little preview of how routing looks like with chi. Also take a look at the generated routing docs +in JSON ([routes.json](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.json)) and in +Markdown ([routes.md](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.md)). + +I highly recommend reading the source of the [examples](https://github.com/go-chi/chi/blob/master/_examples/) listed +above, they will show you all the features of chi and serve as a good form of documentation. + +```go +import ( + //... + "context" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" +) + +func main() { + r := chi.NewRouter() + + // A good base middleware stack + r.Use(middleware.RequestID) + r.Use(middleware.RealIP) + r.Use(middleware.Logger) + r.Use(middleware.Recoverer) + + // Set a timeout value on the request context (ctx), that will signal + // through ctx.Done() that the request has timed out and further + // processing should be stopped. + r.Use(middleware.Timeout(60 * time.Second)) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("hi")) + }) + + // RESTy routes for "articles" resource + r.Route("/articles", func(r chi.Router) { + r.With(paginate).Get("/", listArticles) // GET /articles + r.With(paginate).Get("/{month}-{day}-{year}", listArticlesByDate) // GET /articles/01-16-2017 + + r.Post("/", createArticle) // POST /articles + r.Get("/search", searchArticles) // GET /articles/search + + // Regexp url parameters: + r.Get("/{articleSlug:[a-z-]+}", getArticleBySlug) // GET /articles/home-is-toronto + + // Subrouters: + r.Route("/{articleID}", func(r chi.Router) { + r.Use(ArticleCtx) + r.Get("/", getArticle) // GET /articles/123 + r.Put("/", updateArticle) // PUT /articles/123 + r.Delete("/", deleteArticle) // DELETE /articles/123 + }) + }) + + // Mount the admin sub-router + r.Mount("/admin", adminRouter()) + + http.ListenAndServe(":3333", r) +} + +func ArticleCtx(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + articleID := chi.URLParam(r, "articleID") + article, err := dbGetArticle(articleID) + if err != nil { + http.Error(w, http.StatusText(404), 404) + return + } + ctx := context.WithValue(r.Context(), "article", article) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func getArticle(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + article, ok := ctx.Value("article").(*Article) + if !ok { + http.Error(w, http.StatusText(422), 422) + return + } + w.Write([]byte(fmt.Sprintf("title:%s", article.Title))) +} + +// A completely separate router for administrator routes +func adminRouter() http.Handler { + r := chi.NewRouter() + r.Use(AdminOnly) + r.Get("/", adminIndex) + r.Get("/accounts", adminListAccounts) + return r +} + +func AdminOnly(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + perm, ok := ctx.Value("acl.permission").(YourPermissionType) + if !ok || !perm.IsAdmin() { + http.Error(w, http.StatusText(403), 403) + return + } + next.ServeHTTP(w, r) + }) +} +``` + + +## Router interface + +chi's router is based on a kind of [Patricia Radix trie](https://en.wikipedia.org/wiki/Radix_tree). +The router is fully compatible with `net/http`. + +Built on top of the tree is the `Router` interface: + +```go +// Router consisting of the core routing methods used by chi's Mux, +// using only the standard net/http. +type Router interface { + http.Handler + Routes + + // Use appends one or more middlewares onto the Router stack. + Use(middlewares ...func(http.Handler) http.Handler) + + // With adds inline middlewares for an endpoint handler. + With(middlewares ...func(http.Handler) http.Handler) Router + + // Group adds a new inline-Router along the current routing + // path, with a fresh middleware stack for the inline-Router. + Group(fn func(r Router)) Router + + // Route mounts a sub-Router along a `pattern`` string. + Route(pattern string, fn func(r Router)) Router + + // Mount attaches another http.Handler along ./pattern/* + Mount(pattern string, h http.Handler) + + // Handle and HandleFunc adds routes for `pattern` that matches + // all HTTP methods. + Handle(pattern string, h http.Handler) + HandleFunc(pattern string, h http.HandlerFunc) + + // Method and MethodFunc adds routes for `pattern` that matches + // the `method` HTTP method. + Method(method, pattern string, h http.Handler) + MethodFunc(method, pattern string, h http.HandlerFunc) + + // HTTP-method routing along `pattern` + Connect(pattern string, h http.HandlerFunc) + Delete(pattern string, h http.HandlerFunc) + Get(pattern string, h http.HandlerFunc) + Head(pattern string, h http.HandlerFunc) + Options(pattern string, h http.HandlerFunc) + Patch(pattern string, h http.HandlerFunc) + Post(pattern string, h http.HandlerFunc) + Put(pattern string, h http.HandlerFunc) + Trace(pattern string, h http.HandlerFunc) + + // NotFound defines a handler to respond whenever a route could + // not be found. + NotFound(h http.HandlerFunc) + + // MethodNotAllowed defines a handler to respond whenever a method is + // not allowed. + MethodNotAllowed(h http.HandlerFunc) +} + +// Routes interface adds two methods for router traversal, which is also +// used by the github.com/go-chi/docgen package to generate documentation for Routers. +type Routes interface { + // Routes returns the routing tree in an easily traversable structure. + Routes() []Route + + // Middlewares returns the list of middlewares in use by the router. + Middlewares() Middlewares + + // Match searches the routing tree for a handler that matches + // the method/path - similar to routing a http request, but without + // executing the handler thereafter. + Match(rctx *Context, method, path string) bool +} +``` + +Each routing method accepts a URL `pattern` and chain of `handlers`. The URL pattern +supports named params (ie. `/users/{userID}`) and wildcards (ie. `/admin/*`). URL parameters +can be fetched at runtime by calling `chi.URLParam(r, "userID")` for named parameters +and `chi.URLParam(r, "*")` for a wildcard parameter. + + +### Middleware handlers + +chi's middlewares are just stdlib net/http middleware handlers. There is nothing special +about them, which means the router and all the tooling is designed to be compatible and +friendly with any middleware in the community. This offers much better extensibility and reuse +of packages and is at the heart of chi's purpose. + +Here is an example of a standard net/http middleware where we assign a context key `"user"` +the value of `"123"`. This middleware sets a hypothetical user identifier on the request +context and calls the next handler in the chain. + +```go +// HTTP middleware setting a value on the request context +func MyMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // create new context from `r` request context, and assign key `"user"` + // to value of `"123"` + ctx := context.WithValue(r.Context(), "user", "123") + + // call the next handler in the chain, passing the response writer and + // the updated request object with the new context value. + // + // note: context.Context values are nested, so any previously set + // values will be accessible as well, and the new `"user"` key + // will be accessible from this point forward. + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} +``` + + +### Request handlers + +chi uses standard net/http request handlers. This little snippet is an example of a http.Handler +func that reads a user identifier from the request context - hypothetically, identifying +the user sending an authenticated request, validated+set by a previous middleware handler. + +```go +// HTTP handler accessing data from the request context. +func MyRequestHandler(w http.ResponseWriter, r *http.Request) { + // here we read from the request context and fetch out `"user"` key set in + // the MyMiddleware example above. + user := r.Context().Value("user").(string) + + // respond to the client + w.Write([]byte(fmt.Sprintf("hi %s", user))) +} +``` + + +### URL parameters + +chi's router parses and stores URL parameters right onto the request context. Here is +an example of how to access URL params in your net/http handlers. And of course, middlewares +are able to access the same information. + +```go +// HTTP handler accessing the url routing parameters. +func MyRequestHandler(w http.ResponseWriter, r *http.Request) { + // fetch the url parameter `"userID"` from the request of a matching + // routing pattern. An example routing pattern could be: /users/{userID} + userID := chi.URLParam(r, "userID") + + // fetch `"key"` from the request context + ctx := r.Context() + key := ctx.Value("key").(string) + + // respond to the client + w.Write([]byte(fmt.Sprintf("hi %v, %v", userID, key))) +} +``` + + +## Middlewares + +chi comes equipped with an optional `middleware` package, providing a suite of standard +`net/http` middlewares. Please note, any middleware in the ecosystem that is also compatible +with `net/http` can be used with chi's mux. + +### Core middlewares + +---------------------------------------------------------------------------------------------------- +| chi/middleware Handler | description | +| :--------------------- | :---------------------------------------------------------------------- | +| [AllowContentEncoding] | Enforces a whitelist of request Content-Encoding headers | +| [AllowContentType] | Explicit whitelist of accepted request Content-Types | +| [BasicAuth] | Basic HTTP authentication | +| [Compress] | Gzip compression for clients that accept compressed responses | +| [ContentCharset] | Ensure charset for Content-Type request headers | +| [CleanPath] | Clean double slashes from request path | +| [GetHead] | Automatically route undefined HEAD requests to GET handlers | +| [Heartbeat] | Monitoring endpoint to check the servers pulse | +| [Logger] | Logs the start and end of each request with the elapsed processing time | +| [NoCache] | Sets response headers to prevent clients from caching | +| [Profiler] | Easily attach net/http/pprof to your routers | +| [RealIP] | Sets a http.Request's RemoteAddr to either X-Real-IP or X-Forwarded-For | +| [Recoverer] | Gracefully absorb panics and prints the stack trace | +| [RequestID] | Injects a request ID into the context of each request | +| [RedirectSlashes] | Redirect slashes on routing paths | +| [RouteHeaders] | Route handling for request headers | +| [SetHeader] | Short-hand middleware to set a response header key/value | +| [StripSlashes] | Strip slashes on routing paths | +| [Throttle] | Puts a ceiling on the number of concurrent requests | +| [Timeout] | Signals to the request context when the timeout deadline is reached | +| [URLFormat] | Parse extension from url and put it on request context | +| [WithValue] | Short-hand middleware to set a key/value on the request context | +---------------------------------------------------------------------------------------------------- + +[AllowContentEncoding]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentEncoding +[AllowContentType]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentType +[BasicAuth]: https://pkg.go.dev/github.com/go-chi/chi/middleware#BasicAuth +[Compress]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compress +[ContentCharset]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ContentCharset +[CleanPath]: https://pkg.go.dev/github.com/go-chi/chi/middleware#CleanPath +[GetHead]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetHead +[GetReqID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetReqID +[Heartbeat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Heartbeat +[Logger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Logger +[NoCache]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NoCache +[Profiler]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Profiler +[RealIP]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RealIP +[Recoverer]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Recoverer +[RedirectSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RedirectSlashes +[RequestLogger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestLogger +[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID +[RouteHeaders]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RouteHeaders +[SetHeader]: https://pkg.go.dev/github.com/go-chi/chi/middleware#SetHeader +[StripSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#StripSlashes +[Throttle]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Throttle +[ThrottleBacklog]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleBacklog +[ThrottleWithOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleWithOpts +[Timeout]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Timeout +[URLFormat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#URLFormat +[WithLogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithLogEntry +[WithValue]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithValue +[Compressor]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compressor +[DefaultLogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#DefaultLogFormatter +[EncoderFunc]: https://pkg.go.dev/github.com/go-chi/chi/middleware#EncoderFunc +[HeaderRoute]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRoute +[HeaderRouter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRouter +[LogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogEntry +[LogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogFormatter +[LoggerInterface]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LoggerInterface +[ThrottleOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleOpts +[WrapResponseWriter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WrapResponseWriter + +### Extra middlewares & packages + +Please see https://github.com/go-chi for additional packages. + +-------------------------------------------------------------------------------------------------------------------- +| package | description | +|:---------------------------------------------------|:------------------------------------------------------------- +| [cors](https://github.com/go-chi/cors) | Cross-origin resource sharing (CORS) | +| [docgen](https://github.com/go-chi/docgen) | Print chi.Router routes at runtime | +| [jwtauth](https://github.com/go-chi/jwtauth) | JWT authentication | +| [hostrouter](https://github.com/go-chi/hostrouter) | Domain/host based request routing | +| [httplog](https://github.com/go-chi/httplog) | Small but powerful structured HTTP request logging | +| [httprate](https://github.com/go-chi/httprate) | HTTP request rate limiter | +| [httptracer](https://github.com/go-chi/httptracer) | HTTP request performance tracing library | +| [httpvcr](https://github.com/go-chi/httpvcr) | Write deterministic tests for external sources | +| [stampede](https://github.com/go-chi/stampede) | HTTP request coalescer | +-------------------------------------------------------------------------------------------------------------------- + + +## context? + +`context` is a tiny pkg that provides simple interface to signal context across call stacks +and goroutines. It was originally written by [Sameer Ajmani](https://github.com/Sajmani) +and is available in stdlib since go1.7. + +Learn more at https://blog.golang.org/context + +and.. +* Docs: https://golang.org/pkg/context +* Source: https://github.com/golang/go/tree/master/src/context + + +## Benchmarks + +The benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark + +Results as of Nov 29, 2020 with Go 1.15.5 on Linux AMD 3950x + +```shell +BenchmarkChi_Param 3075895 384 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param5 2116603 566 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param20 964117 1227 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParamWrite 2863413 420 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubStatic 3045488 395 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubParam 2204115 540 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubAll 10000 113811 ns/op 81203 B/op 406 allocs/op +BenchmarkChi_GPlusStatic 3337485 359 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusParam 2825853 423 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlus2Params 2471697 483 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusAll 194220 5950 ns/op 5200 B/op 26 allocs/op +BenchmarkChi_ParseStatic 3365324 356 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseParam 2976614 404 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Parse2Params 2638084 439 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseAll 109567 11295 ns/op 10400 B/op 52 allocs/op +BenchmarkChi_StaticAll 16846 71308 ns/op 62802 B/op 314 allocs/op +``` + +Comparison with other routers: https://gist.github.com/pkieltyka/123032f12052520aaccab752bd3e78cc + +NOTE: the allocs in the benchmark above are from the calls to http.Request's +`WithContext(context.Context)` method that clones the http.Request, sets the `Context()` +on the duplicated (alloc'd) request and returns it the new request object. This is just +how setting context on a request in Go works. + + +## Credits + +* Carl Jackson for https://github.com/zenazn/goji + * Parts of chi's thinking comes from goji, and chi's middleware package + sources from goji. +* Armon Dadgar for https://github.com/armon/go-radix +* Contributions: [@VojtechVitek](https://github.com/VojtechVitek) + +We'll be more than happy to see [your contributions](./CONTRIBUTING.md)! + + +## Beyond REST + +chi is just a http router that lets you decompose request handling into many smaller layers. +Many companies use chi to write REST services for their public APIs. But, REST is just a convention +for managing state via HTTP, and there's a lot of other pieces required to write a complete client-server +system or network of microservices. + +Looking beyond REST, I also recommend some newer works in the field: +* [webrpc](https://github.com/webrpc/webrpc) - Web-focused RPC client+server framework with code-gen +* [gRPC](https://github.com/grpc/grpc-go) - Google's RPC framework via protobufs +* [graphql](https://github.com/99designs/gqlgen) - Declarative query language +* [NATS](https://nats.io) - lightweight pub-sub + + +## License + +Copyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka) + +Licensed under [MIT License](./LICENSE) + +[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi?tab=versions +[GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg +[Travis]: https://travis-ci.org/go-chi/chi +[Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master diff --git a/vendor/github.com/go-chi/chi/v5/chain.go b/vendor/github.com/go-chi/chi/v5/chain.go new file mode 100644 index 00000000000..a2278414f40 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/chain.go @@ -0,0 +1,49 @@ +package chi + +import "net/http" + +// Chain returns a Middlewares type from a slice of middleware handlers. +func Chain(middlewares ...func(http.Handler) http.Handler) Middlewares { + return Middlewares(middlewares) +} + +// Handler builds and returns a http.Handler from the chain of middlewares, +// with `h http.Handler` as the final handler. +func (mws Middlewares) Handler(h http.Handler) http.Handler { + return &ChainHandler{h, chain(mws, h), mws} +} + +// HandlerFunc builds and returns a http.Handler from the chain of middlewares, +// with `h http.Handler` as the final handler. +func (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler { + return &ChainHandler{h, chain(mws, h), mws} +} + +// ChainHandler is a http.Handler with support for handler composition and +// execution. +type ChainHandler struct { + Endpoint http.Handler + chain http.Handler + Middlewares Middlewares +} + +func (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + c.chain.ServeHTTP(w, r) +} + +// chain builds a http.Handler composed of an inline middleware stack and endpoint +// handler in the order they are passed. +func chain(middlewares []func(http.Handler) http.Handler, endpoint http.Handler) http.Handler { + // Return ahead of time if there aren't any middlewares for the chain + if len(middlewares) == 0 { + return endpoint + } + + // Wrap the end handler with the middleware chain + h := middlewares[len(middlewares)-1](endpoint) + for i := len(middlewares) - 2; i >= 0; i-- { + h = middlewares[i](h) + } + + return h +} diff --git a/vendor/github.com/go-chi/chi/v5/chi.go b/vendor/github.com/go-chi/chi/v5/chi.go new file mode 100644 index 00000000000..a1691bbeb10 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/chi.go @@ -0,0 +1,134 @@ +// Package chi is a small, idiomatic and composable router for building HTTP services. +// +// chi requires Go 1.14 or newer. +// +// Example: +// +// package main +// +// import ( +// "net/http" +// +// "github.com/go-chi/chi/v5" +// "github.com/go-chi/chi/v5/middleware" +// ) +// +// func main() { +// r := chi.NewRouter() +// r.Use(middleware.Logger) +// r.Use(middleware.Recoverer) +// +// r.Get("/", func(w http.ResponseWriter, r *http.Request) { +// w.Write([]byte("root.")) +// }) +// +// http.ListenAndServe(":3333", r) +// } +// +// See github.com/go-chi/chi/_examples/ for more in-depth examples. +// +// URL patterns allow for easy matching of path components in HTTP +// requests. The matching components can then be accessed using +// chi.URLParam(). All patterns must begin with a slash. +// +// A simple named placeholder {name} matches any sequence of characters +// up to the next / or the end of the URL. Trailing slashes on paths must +// be handled explicitly. +// +// A placeholder with a name followed by a colon allows a regular +// expression match, for example {number:\\d+}. The regular expression +// syntax is Go's normal regexp RE2 syntax, except that regular expressions +// including { or } are not supported, and / will never be +// matched. An anonymous regexp pattern is allowed, using an empty string +// before the colon in the placeholder, such as {:\\d+} +// +// The special placeholder of asterisk matches the rest of the requested +// URL. Any trailing characters in the pattern are ignored. This is the only +// placeholder which will match / characters. +// +// Examples: +// +// "/user/{name}" matches "/user/jsmith" but not "/user/jsmith/info" or "/user/jsmith/" +// "/user/{name}/info" matches "/user/jsmith/info" +// "/page/*" matches "/page/intro/latest" +// "/page/{other}/index" also matches "/page/intro/latest" +// "/date/{yyyy:\\d\\d\\d\\d}/{mm:\\d\\d}/{dd:\\d\\d}" matches "/date/2017/04/01" +package chi + +import "net/http" + +// NewRouter returns a new Mux object that implements the Router interface. +func NewRouter() *Mux { + return NewMux() +} + +// Router consisting of the core routing methods used by chi's Mux, +// using only the standard net/http. +type Router interface { + http.Handler + Routes + + // Use appends one or more middlewares onto the Router stack. + Use(middlewares ...func(http.Handler) http.Handler) + + // With adds inline middlewares for an endpoint handler. + With(middlewares ...func(http.Handler) http.Handler) Router + + // Group adds a new inline-Router along the current routing + // path, with a fresh middleware stack for the inline-Router. + Group(fn func(r Router)) Router + + // Route mounts a sub-Router along a `pattern`` string. + Route(pattern string, fn func(r Router)) Router + + // Mount attaches another http.Handler along ./pattern/* + Mount(pattern string, h http.Handler) + + // Handle and HandleFunc adds routes for `pattern` that matches + // all HTTP methods. + Handle(pattern string, h http.Handler) + HandleFunc(pattern string, h http.HandlerFunc) + + // Method and MethodFunc adds routes for `pattern` that matches + // the `method` HTTP method. + Method(method, pattern string, h http.Handler) + MethodFunc(method, pattern string, h http.HandlerFunc) + + // HTTP-method routing along `pattern` + Connect(pattern string, h http.HandlerFunc) + Delete(pattern string, h http.HandlerFunc) + Get(pattern string, h http.HandlerFunc) + Head(pattern string, h http.HandlerFunc) + Options(pattern string, h http.HandlerFunc) + Patch(pattern string, h http.HandlerFunc) + Post(pattern string, h http.HandlerFunc) + Put(pattern string, h http.HandlerFunc) + Trace(pattern string, h http.HandlerFunc) + + // NotFound defines a handler to respond whenever a route could + // not be found. + NotFound(h http.HandlerFunc) + + // MethodNotAllowed defines a handler to respond whenever a method is + // not allowed. + MethodNotAllowed(h http.HandlerFunc) +} + +// Routes interface adds two methods for router traversal, which is also +// used by the `docgen` subpackage to generation documentation for Routers. +type Routes interface { + // Routes returns the routing tree in an easily traversable structure. + Routes() []Route + + // Middlewares returns the list of middlewares in use by the router. + Middlewares() Middlewares + + // Match searches the routing tree for a handler that matches + // the method/path - similar to routing a http request, but without + // executing the handler thereafter. + Match(rctx *Context, method, path string) bool +} + +// Middlewares type is a slice of standard middleware handlers with methods +// to compose middleware chains and http.Handler's. +type Middlewares []func(http.Handler) http.Handler diff --git a/vendor/github.com/go-chi/chi/v5/context.go b/vendor/github.com/go-chi/chi/v5/context.go new file mode 100644 index 00000000000..e78a2385d8a --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/context.go @@ -0,0 +1,159 @@ +package chi + +import ( + "context" + "net/http" + "strings" +) + +// URLParam returns the url parameter from a http.Request object. +func URLParam(r *http.Request, key string) string { + if rctx := RouteContext(r.Context()); rctx != nil { + return rctx.URLParam(key) + } + return "" +} + +// URLParamFromCtx returns the url parameter from a http.Request Context. +func URLParamFromCtx(ctx context.Context, key string) string { + if rctx := RouteContext(ctx); rctx != nil { + return rctx.URLParam(key) + } + return "" +} + +// RouteContext returns chi's routing Context object from a +// http.Request Context. +func RouteContext(ctx context.Context) *Context { + val, _ := ctx.Value(RouteCtxKey).(*Context) + return val +} + +// NewRouteContext returns a new routing Context object. +func NewRouteContext() *Context { + return &Context{} +} + +var ( + // RouteCtxKey is the context.Context key to store the request context. + RouteCtxKey = &contextKey{"RouteContext"} +) + +// Context is the default routing context set on the root node of a +// request context to track route patterns, URL parameters and +// an optional routing path. +type Context struct { + Routes Routes + + // parentCtx is the parent of this one, for using Context as a + // context.Context directly. This is an optimization that saves + // 1 allocation. + parentCtx context.Context + + // Routing path/method override used during the route search. + // See Mux#routeHTTP method. + RoutePath string + RouteMethod string + + // URLParams are the stack of routeParams captured during the + // routing lifecycle across a stack of sub-routers. + URLParams RouteParams + + // Route parameters matched for the current sub-router. It is + // intentionally unexported so it cant be tampered. + routeParams RouteParams + + // The endpoint routing pattern that matched the request URI path + // or `RoutePath` of the current sub-router. This value will update + // during the lifecycle of a request passing through a stack of + // sub-routers. + routePattern string + + // Routing pattern stack throughout the lifecycle of the request, + // across all connected routers. It is a record of all matching + // patterns across a stack of sub-routers. + RoutePatterns []string + + // methodNotAllowed hint + methodNotAllowed bool +} + +// Reset a routing context to its initial state. +func (x *Context) Reset() { + x.Routes = nil + x.RoutePath = "" + x.RouteMethod = "" + x.RoutePatterns = x.RoutePatterns[:0] + x.URLParams.Keys = x.URLParams.Keys[:0] + x.URLParams.Values = x.URLParams.Values[:0] + + x.routePattern = "" + x.routeParams.Keys = x.routeParams.Keys[:0] + x.routeParams.Values = x.routeParams.Values[:0] + x.methodNotAllowed = false + x.parentCtx = nil +} + +// URLParam returns the corresponding URL parameter value from the request +// routing context. +func (x *Context) URLParam(key string) string { + for k := len(x.URLParams.Keys) - 1; k >= 0; k-- { + if x.URLParams.Keys[k] == key { + return x.URLParams.Values[k] + } + } + return "" +} + +// RoutePattern builds the routing pattern string for the particular +// request, at the particular point during routing. This means, the value +// will change throughout the execution of a request in a router. That is +// why its advised to only use this value after calling the next handler. +// +// For example, +// +// func Instrument(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// next.ServeHTTP(w, r) +// routePattern := chi.RouteContext(r.Context()).RoutePattern() +// measure(w, r, routePattern) +// }) +// } +func (x *Context) RoutePattern() string { + routePattern := strings.Join(x.RoutePatterns, "") + routePattern = replaceWildcards(routePattern) + routePattern = strings.TrimSuffix(routePattern, "//") + routePattern = strings.TrimSuffix(routePattern, "/") + return routePattern +} + +// replaceWildcards takes a route pattern and recursively replaces all +// occurrences of "/*/" to "/". +func replaceWildcards(p string) string { + if strings.Contains(p, "/*/") { + return replaceWildcards(strings.Replace(p, "/*/", "/", -1)) + } + return p +} + +// RouteParams is a structure to track URL routing parameters efficiently. +type RouteParams struct { + Keys, Values []string +} + +// Add will append a URL parameter to the end of the route param +func (s *RouteParams) Add(key, value string) { + s.Keys = append(s.Keys, key) + s.Values = append(s.Values, value) +} + +// contextKey is a value for use with context.WithValue. It's used as +// a pointer so it fits in an interface{} without allocation. This technique +// for defining context keys was copied from Go 1.7's new use of context in net/http. +type contextKey struct { + name string +} + +func (k *contextKey) String() string { + return "chi context value " + k.name +} diff --git a/vendor/github.com/go-chi/chi/v5/mux.go b/vendor/github.com/go-chi/chi/v5/mux.go new file mode 100644 index 00000000000..47e64cf296f --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/mux.go @@ -0,0 +1,487 @@ +package chi + +import ( + "context" + "fmt" + "net/http" + "strings" + "sync" +) + +var _ Router = &Mux{} + +// Mux is a simple HTTP route multiplexer that parses a request path, +// records any URL params, and executes an end handler. It implements +// the http.Handler interface and is friendly with the standard library. +// +// Mux is designed to be fast, minimal and offer a powerful API for building +// modular and composable HTTP services with a large set of handlers. It's +// particularly useful for writing large REST API services that break a handler +// into many smaller parts composed of middlewares and end handlers. +type Mux struct { + // The computed mux handler made of the chained middleware stack and + // the tree router + handler http.Handler + + // The radix trie router + tree *node + + // Custom method not allowed handler + methodNotAllowedHandler http.HandlerFunc + + // A reference to the parent mux used by subrouters when mounting + // to a parent mux + parent *Mux + + // Routing context pool + pool *sync.Pool + + // Custom route not found handler + notFoundHandler http.HandlerFunc + + // The middleware stack + middlewares []func(http.Handler) http.Handler + + // Controls the behaviour of middleware chain generation when a mux + // is registered as an inline group inside another mux. + inline bool +} + +// NewMux returns a newly initialized Mux object that implements the Router +// interface. +func NewMux() *Mux { + mux := &Mux{tree: &node{}, pool: &sync.Pool{}} + mux.pool.New = func() interface{} { + return NewRouteContext() + } + return mux +} + +// ServeHTTP is the single method of the http.Handler interface that makes +// Mux interoperable with the standard library. It uses a sync.Pool to get and +// reuse routing contexts for each request. +func (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Ensure the mux has some routes defined on the mux + if mx.handler == nil { + mx.NotFoundHandler().ServeHTTP(w, r) + return + } + + // Check if a routing context already exists from a parent router. + rctx, _ := r.Context().Value(RouteCtxKey).(*Context) + if rctx != nil { + mx.handler.ServeHTTP(w, r) + return + } + + // Fetch a RouteContext object from the sync pool, and call the computed + // mx.handler that is comprised of mx.middlewares + mx.routeHTTP. + // Once the request is finished, reset the routing context and put it back + // into the pool for reuse from another request. + rctx = mx.pool.Get().(*Context) + rctx.Reset() + rctx.Routes = mx + rctx.parentCtx = r.Context() + + // NOTE: r.WithContext() causes 2 allocations and context.WithValue() causes 1 allocation + r = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx)) + + // Serve the request and once its done, put the request context back in the sync pool + mx.handler.ServeHTTP(w, r) + mx.pool.Put(rctx) +} + +// Use appends a middleware handler to the Mux middleware stack. +// +// The middleware stack for any Mux will execute before searching for a matching +// route to a specific handler, which provides opportunity to respond early, +// change the course of the request execution, or set request-scoped values for +// the next http.Handler. +func (mx *Mux) Use(middlewares ...func(http.Handler) http.Handler) { + if mx.handler != nil { + panic("chi: all middlewares must be defined before routes on a mux") + } + mx.middlewares = append(mx.middlewares, middlewares...) +} + +// Handle adds the route `pattern` that matches any http method to +// execute the `handler` http.Handler. +func (mx *Mux) Handle(pattern string, handler http.Handler) { + mx.handle(mALL, pattern, handler) +} + +// HandleFunc adds the route `pattern` that matches any http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) HandleFunc(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mALL, pattern, handlerFn) +} + +// Method adds the route `pattern` that matches `method` http method to +// execute the `handler` http.Handler. +func (mx *Mux) Method(method, pattern string, handler http.Handler) { + m, ok := methodMap[strings.ToUpper(method)] + if !ok { + panic(fmt.Sprintf("chi: '%s' http method is not supported.", method)) + } + mx.handle(m, pattern, handler) +} + +// MethodFunc adds the route `pattern` that matches `method` http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) MethodFunc(method, pattern string, handlerFn http.HandlerFunc) { + mx.Method(method, pattern, handlerFn) +} + +// Connect adds the route `pattern` that matches a CONNECT http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Connect(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mCONNECT, pattern, handlerFn) +} + +// Delete adds the route `pattern` that matches a DELETE http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Delete(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mDELETE, pattern, handlerFn) +} + +// Get adds the route `pattern` that matches a GET http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Get(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mGET, pattern, handlerFn) +} + +// Head adds the route `pattern` that matches a HEAD http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Head(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mHEAD, pattern, handlerFn) +} + +// Options adds the route `pattern` that matches a OPTIONS http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Options(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mOPTIONS, pattern, handlerFn) +} + +// Patch adds the route `pattern` that matches a PATCH http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Patch(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPATCH, pattern, handlerFn) +} + +// Post adds the route `pattern` that matches a POST http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Post(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPOST, pattern, handlerFn) +} + +// Put adds the route `pattern` that matches a PUT http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Put(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mPUT, pattern, handlerFn) +} + +// Trace adds the route `pattern` that matches a TRACE http method to +// execute the `handlerFn` http.HandlerFunc. +func (mx *Mux) Trace(pattern string, handlerFn http.HandlerFunc) { + mx.handle(mTRACE, pattern, handlerFn) +} + +// NotFound sets a custom http.HandlerFunc for routing paths that could +// not be found. The default 404 handler is `http.NotFound`. +func (mx *Mux) NotFound(handlerFn http.HandlerFunc) { + // Build NotFound handler chain + m := mx + hFn := handlerFn + if mx.inline && mx.parent != nil { + m = mx.parent + hFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeHTTP + } + + // Update the notFoundHandler from this point forward + m.notFoundHandler = hFn + m.updateSubRoutes(func(subMux *Mux) { + if subMux.notFoundHandler == nil { + subMux.NotFound(hFn) + } + }) +} + +// MethodNotAllowed sets a custom http.HandlerFunc for routing paths where the +// method is unresolved. The default handler returns a 405 with an empty body. +func (mx *Mux) MethodNotAllowed(handlerFn http.HandlerFunc) { + // Build MethodNotAllowed handler chain + m := mx + hFn := handlerFn + if mx.inline && mx.parent != nil { + m = mx.parent + hFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeHTTP + } + + // Update the methodNotAllowedHandler from this point forward + m.methodNotAllowedHandler = hFn + m.updateSubRoutes(func(subMux *Mux) { + if subMux.methodNotAllowedHandler == nil { + subMux.MethodNotAllowed(hFn) + } + }) +} + +// With adds inline middlewares for an endpoint handler. +func (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router { + // Similarly as in handle(), we must build the mux handler once additional + // middleware registration isn't allowed for this stack, like now. + if !mx.inline && mx.handler == nil { + mx.updateRouteHandler() + } + + // Copy middlewares from parent inline muxs + var mws Middlewares + if mx.inline { + mws = make(Middlewares, len(mx.middlewares)) + copy(mws, mx.middlewares) + } + mws = append(mws, middlewares...) + + im := &Mux{ + pool: mx.pool, inline: true, parent: mx, tree: mx.tree, middlewares: mws, + notFoundHandler: mx.notFoundHandler, methodNotAllowedHandler: mx.methodNotAllowedHandler, + } + + return im +} + +// Group creates a new inline-Mux with a fresh middleware stack. It's useful +// for a group of handlers along the same routing path that use an additional +// set of middlewares. See _examples/. +func (mx *Mux) Group(fn func(r Router)) Router { + im := mx.With().(*Mux) + if fn != nil { + fn(im) + } + return im +} + +// Route creates a new Mux with a fresh middleware stack and mounts it +// along the `pattern` as a subrouter. Effectively, this is a short-hand +// call to Mount. See _examples/. +func (mx *Mux) Route(pattern string, fn func(r Router)) Router { + if fn == nil { + panic(fmt.Sprintf("chi: attempting to Route() a nil subrouter on '%s'", pattern)) + } + subRouter := NewRouter() + fn(subRouter) + mx.Mount(pattern, subRouter) + return subRouter +} + +// Mount attaches another http.Handler or chi Router as a subrouter along a routing +// path. It's very useful to split up a large API as many independent routers and +// compose them as a single service using Mount. See _examples/. +// +// Note that Mount() simply sets a wildcard along the `pattern` that will continue +// routing at the `handler`, which in most cases is another chi.Router. As a result, +// if you define two Mount() routes on the exact same pattern the mount will panic. +func (mx *Mux) Mount(pattern string, handler http.Handler) { + if handler == nil { + panic(fmt.Sprintf("chi: attempting to Mount() a nil handler on '%s'", pattern)) + } + + // Provide runtime safety for ensuring a pattern isn't mounted on an existing + // routing pattern. + if mx.tree.findPattern(pattern+"*") || mx.tree.findPattern(pattern+"/*") { + panic(fmt.Sprintf("chi: attempting to Mount() a handler on an existing path, '%s'", pattern)) + } + + // Assign sub-Router's with the parent not found & method not allowed handler if not specified. + subr, ok := handler.(*Mux) + if ok && subr.notFoundHandler == nil && mx.notFoundHandler != nil { + subr.NotFound(mx.notFoundHandler) + } + if ok && subr.methodNotAllowedHandler == nil && mx.methodNotAllowedHandler != nil { + subr.MethodNotAllowed(mx.methodNotAllowedHandler) + } + + mountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rctx := RouteContext(r.Context()) + + // shift the url path past the previous subrouter + rctx.RoutePath = mx.nextRoutePath(rctx) + + // reset the wildcard URLParam which connects the subrouter + n := len(rctx.URLParams.Keys) - 1 + if n >= 0 && rctx.URLParams.Keys[n] == "*" && len(rctx.URLParams.Values) > n { + rctx.URLParams.Values[n] = "" + } + + handler.ServeHTTP(w, r) + }) + + if pattern == "" || pattern[len(pattern)-1] != '/' { + mx.handle(mALL|mSTUB, pattern, mountHandler) + mx.handle(mALL|mSTUB, pattern+"/", mountHandler) + pattern += "/" + } + + method := mALL + subroutes, _ := handler.(Routes) + if subroutes != nil { + method |= mSTUB + } + n := mx.handle(method, pattern+"*", mountHandler) + + if subroutes != nil { + n.subroutes = subroutes + } +} + +// Routes returns a slice of routing information from the tree, +// useful for traversing available routes of a router. +func (mx *Mux) Routes() []Route { + return mx.tree.routes() +} + +// Middlewares returns a slice of middleware handler functions. +func (mx *Mux) Middlewares() Middlewares { + return mx.middlewares +} + +// Match searches the routing tree for a handler that matches the method/path. +// It's similar to routing a http request, but without executing the handler +// thereafter. +// +// Note: the *Context state is updated during execution, so manage +// the state carefully or make a NewRouteContext(). +func (mx *Mux) Match(rctx *Context, method, path string) bool { + m, ok := methodMap[method] + if !ok { + return false + } + + node, _, h := mx.tree.FindRoute(rctx, m, path) + + if node != nil && node.subroutes != nil { + rctx.RoutePath = mx.nextRoutePath(rctx) + return node.subroutes.Match(rctx, method, rctx.RoutePath) + } + + return h != nil +} + +// NotFoundHandler returns the default Mux 404 responder whenever a route +// cannot be found. +func (mx *Mux) NotFoundHandler() http.HandlerFunc { + if mx.notFoundHandler != nil { + return mx.notFoundHandler + } + return http.NotFound +} + +// MethodNotAllowedHandler returns the default Mux 405 responder whenever +// a method cannot be resolved for a route. +func (mx *Mux) MethodNotAllowedHandler() http.HandlerFunc { + if mx.methodNotAllowedHandler != nil { + return mx.methodNotAllowedHandler + } + return methodNotAllowedHandler +} + +// handle registers a http.Handler in the routing tree for a particular http method +// and routing pattern. +func (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *node { + if len(pattern) == 0 || pattern[0] != '/' { + panic(fmt.Sprintf("chi: routing pattern must begin with '/' in '%s'", pattern)) + } + + // Build the computed routing handler for this routing pattern. + if !mx.inline && mx.handler == nil { + mx.updateRouteHandler() + } + + // Build endpoint handler with inline middlewares for the route + var h http.Handler + if mx.inline { + mx.handler = http.HandlerFunc(mx.routeHTTP) + h = Chain(mx.middlewares...).Handler(handler) + } else { + h = handler + } + + // Add the endpoint to the tree and return the node + return mx.tree.InsertRoute(method, pattern, h) +} + +// routeHTTP routes a http.Request through the Mux routing tree to serve +// the matching handler for a particular http method. +func (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) { + // Grab the route context object + rctx := r.Context().Value(RouteCtxKey).(*Context) + + // The request routing path + routePath := rctx.RoutePath + if routePath == "" { + if r.URL.RawPath != "" { + routePath = r.URL.RawPath + } else { + routePath = r.URL.Path + } + if routePath == "" { + routePath = "/" + } + } + + // Check if method is supported by chi + if rctx.RouteMethod == "" { + rctx.RouteMethod = r.Method + } + method, ok := methodMap[rctx.RouteMethod] + if !ok { + mx.MethodNotAllowedHandler().ServeHTTP(w, r) + return + } + + // Find the route + if _, _, h := mx.tree.FindRoute(rctx, method, routePath); h != nil { + h.ServeHTTP(w, r) + return + } + if rctx.methodNotAllowed { + mx.MethodNotAllowedHandler().ServeHTTP(w, r) + } else { + mx.NotFoundHandler().ServeHTTP(w, r) + } +} + +func (mx *Mux) nextRoutePath(rctx *Context) string { + routePath := "/" + nx := len(rctx.routeParams.Keys) - 1 // index of last param in list + if nx >= 0 && rctx.routeParams.Keys[nx] == "*" && len(rctx.routeParams.Values) > nx { + routePath = "/" + rctx.routeParams.Values[nx] + } + return routePath +} + +// Recursively update data on child routers. +func (mx *Mux) updateSubRoutes(fn func(subMux *Mux)) { + for _, r := range mx.tree.routes() { + subMux, ok := r.SubRoutes.(*Mux) + if !ok { + continue + } + fn(subMux) + } +} + +// updateRouteHandler builds the single mux handler that is a chain of the middleware +// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this +// point, no other middlewares can be registered on this Mux's stack. But you can still +// compose additional middlewares via Group()'s or using a chained middleware handler. +func (mx *Mux) updateRouteHandler() { + mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP)) +} + +// methodNotAllowedHandler is a helper function to respond with a 405, +// method not allowed. +func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(405) + w.Write(nil) +} diff --git a/vendor/github.com/go-chi/chi/v5/tree.go b/vendor/github.com/go-chi/chi/v5/tree.go new file mode 100644 index 00000000000..4189b5228b2 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/tree.go @@ -0,0 +1,866 @@ +package chi + +// Radix tree implementation below is a based on the original work by +// Armon Dadgar in https://github.com/armon/go-radix/blob/master/radix.go +// (MIT licensed). It's been heavily modified for use as a HTTP routing tree. + +import ( + "fmt" + "net/http" + "regexp" + "sort" + "strconv" + "strings" +) + +type methodTyp uint + +const ( + mSTUB methodTyp = 1 << iota + mCONNECT + mDELETE + mGET + mHEAD + mOPTIONS + mPATCH + mPOST + mPUT + mTRACE +) + +var mALL = mCONNECT | mDELETE | mGET | mHEAD | + mOPTIONS | mPATCH | mPOST | mPUT | mTRACE + +var methodMap = map[string]methodTyp{ + http.MethodConnect: mCONNECT, + http.MethodDelete: mDELETE, + http.MethodGet: mGET, + http.MethodHead: mHEAD, + http.MethodOptions: mOPTIONS, + http.MethodPatch: mPATCH, + http.MethodPost: mPOST, + http.MethodPut: mPUT, + http.MethodTrace: mTRACE, +} + +// RegisterMethod adds support for custom HTTP method handlers, available +// via Router#Method and Router#MethodFunc +func RegisterMethod(method string) { + if method == "" { + return + } + method = strings.ToUpper(method) + if _, ok := methodMap[method]; ok { + return + } + n := len(methodMap) + if n > strconv.IntSize-2 { + panic(fmt.Sprintf("chi: max number of methods reached (%d)", strconv.IntSize)) + } + mt := methodTyp(2 << n) + methodMap[method] = mt + mALL |= mt +} + +type nodeTyp uint8 + +const ( + ntStatic nodeTyp = iota // /home + ntRegexp // /{id:[0-9]+} + ntParam // /{user} + ntCatchAll // /api/v1/* +) + +type node struct { + // subroutes on the leaf node + subroutes Routes + + // regexp matcher for regexp nodes + rex *regexp.Regexp + + // HTTP handler endpoints on the leaf node + endpoints endpoints + + // prefix is the common prefix we ignore + prefix string + + // child nodes should be stored in-order for iteration, + // in groups of the node type. + children [ntCatchAll + 1]nodes + + // first byte of the child prefix + tail byte + + // node type: static, regexp, param, catchAll + typ nodeTyp + + // first byte of the prefix + label byte +} + +// endpoints is a mapping of http method constants to handlers +// for a given route. +type endpoints map[methodTyp]*endpoint + +type endpoint struct { + // endpoint handler + handler http.Handler + + // pattern is the routing pattern for handler nodes + pattern string + + // parameter keys recorded on handler nodes + paramKeys []string +} + +func (s endpoints) Value(method methodTyp) *endpoint { + mh, ok := s[method] + if !ok { + mh = &endpoint{} + s[method] = mh + } + return mh +} + +func (n *node) InsertRoute(method methodTyp, pattern string, handler http.Handler) *node { + var parent *node + search := pattern + + for { + // Handle key exhaustion + if len(search) == 0 { + // Insert or update the node's leaf handler + n.setEndpoint(method, handler, pattern) + return n + } + + // We're going to be searching for a wild node next, + // in this case, we need to get the tail + var label = search[0] + var segTail byte + var segEndIdx int + var segTyp nodeTyp + var segRexpat string + if label == '{' || label == '*' { + segTyp, _, segRexpat, segTail, _, segEndIdx = patNextSegment(search) + } + + var prefix string + if segTyp == ntRegexp { + prefix = segRexpat + } + + // Look for the edge to attach to + parent = n + n = n.getEdge(segTyp, label, segTail, prefix) + + // No edge, create one + if n == nil { + child := &node{label: label, tail: segTail, prefix: search} + hn := parent.addChild(child, search) + hn.setEndpoint(method, handler, pattern) + + return hn + } + + // Found an edge to match the pattern + + if n.typ > ntStatic { + // We found a param node, trim the param from the search path and continue. + // This param/wild pattern segment would already be on the tree from a previous + // call to addChild when creating a new node. + search = search[segEndIdx:] + continue + } + + // Static nodes fall below here. + // Determine longest prefix of the search key on match. + commonPrefix := longestPrefix(search, n.prefix) + if commonPrefix == len(n.prefix) { + // the common prefix is as long as the current node's prefix we're attempting to insert. + // keep the search going. + search = search[commonPrefix:] + continue + } + + // Split the node + child := &node{ + typ: ntStatic, + prefix: search[:commonPrefix], + } + parent.replaceChild(search[0], segTail, child) + + // Restore the existing node + n.label = n.prefix[commonPrefix] + n.prefix = n.prefix[commonPrefix:] + child.addChild(n, n.prefix) + + // If the new key is a subset, set the method/handler on this node and finish. + search = search[commonPrefix:] + if len(search) == 0 { + child.setEndpoint(method, handler, pattern) + return child + } + + // Create a new edge for the node + subchild := &node{ + typ: ntStatic, + label: search[0], + prefix: search, + } + hn := child.addChild(subchild, search) + hn.setEndpoint(method, handler, pattern) + return hn + } +} + +// addChild appends the new `child` node to the tree using the `pattern` as the trie key. +// For a URL router like chi's, we split the static, param, regexp and wildcard segments +// into different nodes. In addition, addChild will recursively call itself until every +// pattern segment is added to the url pattern tree as individual nodes, depending on type. +func (n *node) addChild(child *node, prefix string) *node { + search := prefix + + // handler leaf node added to the tree is the child. + // this may be overridden later down the flow + hn := child + + // Parse next segment + segTyp, _, segRexpat, segTail, segStartIdx, segEndIdx := patNextSegment(search) + + // Add child depending on next up segment + switch segTyp { + + case ntStatic: + // Search prefix is all static (that is, has no params in path) + // noop + + default: + // Search prefix contains a param, regexp or wildcard + + if segTyp == ntRegexp { + rex, err := regexp.Compile(segRexpat) + if err != nil { + panic(fmt.Sprintf("chi: invalid regexp pattern '%s' in route param", segRexpat)) + } + child.prefix = segRexpat + child.rex = rex + } + + if segStartIdx == 0 { + // Route starts with a param + child.typ = segTyp + + if segTyp == ntCatchAll { + segStartIdx = -1 + } else { + segStartIdx = segEndIdx + } + if segStartIdx < 0 { + segStartIdx = len(search) + } + child.tail = segTail // for params, we set the tail + + if segStartIdx != len(search) { + // add static edge for the remaining part, split the end. + // its not possible to have adjacent param nodes, so its certainly + // going to be a static node next. + + search = search[segStartIdx:] // advance search position + + nn := &node{ + typ: ntStatic, + label: search[0], + prefix: search, + } + hn = child.addChild(nn, search) + } + + } else if segStartIdx > 0 { + // Route has some param + + // starts with a static segment + child.typ = ntStatic + child.prefix = search[:segStartIdx] + child.rex = nil + + // add the param edge node + search = search[segStartIdx:] + + nn := &node{ + typ: segTyp, + label: search[0], + tail: segTail, + } + hn = child.addChild(nn, search) + + } + } + + n.children[child.typ] = append(n.children[child.typ], child) + n.children[child.typ].Sort() + return hn +} + +func (n *node) replaceChild(label, tail byte, child *node) { + for i := 0; i < len(n.children[child.typ]); i++ { + if n.children[child.typ][i].label == label && n.children[child.typ][i].tail == tail { + n.children[child.typ][i] = child + n.children[child.typ][i].label = label + n.children[child.typ][i].tail = tail + return + } + } + panic("chi: replacing missing child") +} + +func (n *node) getEdge(ntyp nodeTyp, label, tail byte, prefix string) *node { + nds := n.children[ntyp] + for i := 0; i < len(nds); i++ { + if nds[i].label == label && nds[i].tail == tail { + if ntyp == ntRegexp && nds[i].prefix != prefix { + continue + } + return nds[i] + } + } + return nil +} + +func (n *node) setEndpoint(method methodTyp, handler http.Handler, pattern string) { + // Set the handler for the method type on the node + if n.endpoints == nil { + n.endpoints = make(endpoints) + } + + paramKeys := patParamKeys(pattern) + + if method&mSTUB == mSTUB { + n.endpoints.Value(mSTUB).handler = handler + } + if method&mALL == mALL { + h := n.endpoints.Value(mALL) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + for _, m := range methodMap { + h := n.endpoints.Value(m) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + } + } else { + h := n.endpoints.Value(method) + h.handler = handler + h.pattern = pattern + h.paramKeys = paramKeys + } +} + +func (n *node) FindRoute(rctx *Context, method methodTyp, path string) (*node, endpoints, http.Handler) { + // Reset the context routing pattern and params + rctx.routePattern = "" + rctx.routeParams.Keys = rctx.routeParams.Keys[:0] + rctx.routeParams.Values = rctx.routeParams.Values[:0] + + // Find the routing handlers for the path + rn := n.findRoute(rctx, method, path) + if rn == nil { + return nil, nil, nil + } + + // Record the routing params in the request lifecycle + rctx.URLParams.Keys = append(rctx.URLParams.Keys, rctx.routeParams.Keys...) + rctx.URLParams.Values = append(rctx.URLParams.Values, rctx.routeParams.Values...) + + // Record the routing pattern in the request lifecycle + if rn.endpoints[method].pattern != "" { + rctx.routePattern = rn.endpoints[method].pattern + rctx.RoutePatterns = append(rctx.RoutePatterns, rctx.routePattern) + } + + return rn, rn.endpoints, rn.endpoints[method].handler +} + +// Recursive edge traversal by checking all nodeTyp groups along the way. +// It's like searching through a multi-dimensional radix trie. +func (n *node) findRoute(rctx *Context, method methodTyp, path string) *node { + nn := n + search := path + + for t, nds := range nn.children { + ntyp := nodeTyp(t) + if len(nds) == 0 { + continue + } + + var xn *node + xsearch := search + + var label byte + if search != "" { + label = search[0] + } + + switch ntyp { + case ntStatic: + xn = nds.findEdge(label) + if xn == nil || !strings.HasPrefix(xsearch, xn.prefix) { + continue + } + xsearch = xsearch[len(xn.prefix):] + + case ntParam, ntRegexp: + // short-circuit and return no matching route for empty param values + if xsearch == "" { + continue + } + + // serially loop through each node grouped by the tail delimiter + for idx := 0; idx < len(nds); idx++ { + xn = nds[idx] + + // label for param nodes is the delimiter byte + p := strings.IndexByte(xsearch, xn.tail) + + if p < 0 { + if xn.tail == '/' { + p = len(xsearch) + } else { + continue + } + } else if ntyp == ntRegexp && p == 0 { + continue + } + + if ntyp == ntRegexp && xn.rex != nil { + if !xn.rex.MatchString(xsearch[:p]) { + continue + } + } else if strings.IndexByte(xsearch[:p], '/') != -1 { + // avoid a match across path segments + continue + } + + prevlen := len(rctx.routeParams.Values) + rctx.routeParams.Values = append(rctx.routeParams.Values, xsearch[:p]) + xsearch = xsearch[p:] + + if len(xsearch) == 0 { + if xn.isLeaf() { + h := xn.endpoints[method] + if h != nil && h.handler != nil { + rctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...) + return xn + } + + // flag that the routing context found a route, but not a corresponding + // supported method + rctx.methodNotAllowed = true + } + } + + // recursively find the next node on this branch + fin := xn.findRoute(rctx, method, xsearch) + if fin != nil { + return fin + } + + // not found on this branch, reset vars + rctx.routeParams.Values = rctx.routeParams.Values[:prevlen] + xsearch = search + } + + rctx.routeParams.Values = append(rctx.routeParams.Values, "") + + default: + // catch-all nodes + rctx.routeParams.Values = append(rctx.routeParams.Values, search) + xn = nds[0] + xsearch = "" + } + + if xn == nil { + continue + } + + // did we find it yet? + if len(xsearch) == 0 { + if xn.isLeaf() { + h := xn.endpoints[method] + if h != nil && h.handler != nil { + rctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...) + return xn + } + + // flag that the routing context found a route, but not a corresponding + // supported method + rctx.methodNotAllowed = true + } + } + + // recursively find the next node.. + fin := xn.findRoute(rctx, method, xsearch) + if fin != nil { + return fin + } + + // Did not find final handler, let's remove the param here if it was set + if xn.typ > ntStatic { + if len(rctx.routeParams.Values) > 0 { + rctx.routeParams.Values = rctx.routeParams.Values[:len(rctx.routeParams.Values)-1] + } + } + + } + + return nil +} + +func (n *node) findEdge(ntyp nodeTyp, label byte) *node { + nds := n.children[ntyp] + num := len(nds) + idx := 0 + + switch ntyp { + case ntStatic, ntParam, ntRegexp: + i, j := 0, num-1 + for i <= j { + idx = i + (j-i)/2 + if label > nds[idx].label { + i = idx + 1 + } else if label < nds[idx].label { + j = idx - 1 + } else { + i = num // breaks cond + } + } + if nds[idx].label != label { + return nil + } + return nds[idx] + + default: // catch all + return nds[idx] + } +} + +func (n *node) isLeaf() bool { + return n.endpoints != nil +} + +func (n *node) findPattern(pattern string) bool { + nn := n + for _, nds := range nn.children { + if len(nds) == 0 { + continue + } + + n = nn.findEdge(nds[0].typ, pattern[0]) + if n == nil { + continue + } + + var idx int + var xpattern string + + switch n.typ { + case ntStatic: + idx = longestPrefix(pattern, n.prefix) + if idx < len(n.prefix) { + continue + } + + case ntParam, ntRegexp: + idx = strings.IndexByte(pattern, '}') + 1 + + case ntCatchAll: + idx = longestPrefix(pattern, "*") + + default: + panic("chi: unknown node type") + } + + xpattern = pattern[idx:] + if len(xpattern) == 0 { + return true + } + + return n.findPattern(xpattern) + } + return false +} + +func (n *node) routes() []Route { + rts := []Route{} + + n.walk(func(eps endpoints, subroutes Routes) bool { + if eps[mSTUB] != nil && eps[mSTUB].handler != nil && subroutes == nil { + return false + } + + // Group methodHandlers by unique patterns + pats := make(map[string]endpoints) + + for mt, h := range eps { + if h.pattern == "" { + continue + } + p, ok := pats[h.pattern] + if !ok { + p = endpoints{} + pats[h.pattern] = p + } + p[mt] = h + } + + for p, mh := range pats { + hs := make(map[string]http.Handler) + if mh[mALL] != nil && mh[mALL].handler != nil { + hs["*"] = mh[mALL].handler + } + + for mt, h := range mh { + if h.handler == nil { + continue + } + m := methodTypString(mt) + if m == "" { + continue + } + hs[m] = h.handler + } + + rt := Route{subroutes, hs, p} + rts = append(rts, rt) + } + + return false + }) + + return rts +} + +func (n *node) walk(fn func(eps endpoints, subroutes Routes) bool) bool { + // Visit the leaf values if any + if (n.endpoints != nil || n.subroutes != nil) && fn(n.endpoints, n.subroutes) { + return true + } + + // Recurse on the children + for _, ns := range n.children { + for _, cn := range ns { + if cn.walk(fn) { + return true + } + } + } + return false +} + +// patNextSegment returns the next segment details from a pattern: +// node type, param key, regexp string, param tail byte, param starting index, param ending index +func patNextSegment(pattern string) (nodeTyp, string, string, byte, int, int) { + ps := strings.Index(pattern, "{") + ws := strings.Index(pattern, "*") + + if ps < 0 && ws < 0 { + return ntStatic, "", "", 0, 0, len(pattern) // we return the entire thing + } + + // Sanity check + if ps >= 0 && ws >= 0 && ws < ps { + panic("chi: wildcard '*' must be the last pattern in a route, otherwise use a '{param}'") + } + + var tail byte = '/' // Default endpoint tail to / byte + + if ps >= 0 { + // Param/Regexp pattern is next + nt := ntParam + + // Read to closing } taking into account opens and closes in curl count (cc) + cc := 0 + pe := ps + for i, c := range pattern[ps:] { + if c == '{' { + cc++ + } else if c == '}' { + cc-- + if cc == 0 { + pe = ps + i + break + } + } + } + if pe == ps { + panic("chi: route param closing delimiter '}' is missing") + } + + key := pattern[ps+1 : pe] + pe++ // set end to next position + + if pe < len(pattern) { + tail = pattern[pe] + } + + var rexpat string + if idx := strings.Index(key, ":"); idx >= 0 { + nt = ntRegexp + rexpat = key[idx+1:] + key = key[:idx] + } + + if len(rexpat) > 0 { + if rexpat[0] != '^' { + rexpat = "^" + rexpat + } + if rexpat[len(rexpat)-1] != '$' { + rexpat += "$" + } + } + + return nt, key, rexpat, tail, ps, pe + } + + // Wildcard pattern as finale + if ws < len(pattern)-1 { + panic("chi: wildcard '*' must be the last value in a route. trim trailing text or use a '{param}' instead") + } + return ntCatchAll, "*", "", 0, ws, len(pattern) +} + +func patParamKeys(pattern string) []string { + pat := pattern + paramKeys := []string{} + for { + ptyp, paramKey, _, _, _, e := patNextSegment(pat) + if ptyp == ntStatic { + return paramKeys + } + for i := 0; i < len(paramKeys); i++ { + if paramKeys[i] == paramKey { + panic(fmt.Sprintf("chi: routing pattern '%s' contains duplicate param key, '%s'", pattern, paramKey)) + } + } + paramKeys = append(paramKeys, paramKey) + pat = pat[e:] + } +} + +// longestPrefix finds the length of the shared prefix +// of two strings +func longestPrefix(k1, k2 string) int { + max := len(k1) + if l := len(k2); l < max { + max = l + } + var i int + for i = 0; i < max; i++ { + if k1[i] != k2[i] { + break + } + } + return i +} + +func methodTypString(method methodTyp) string { + for s, t := range methodMap { + if method == t { + return s + } + } + return "" +} + +type nodes []*node + +// Sort the list of nodes by label +func (ns nodes) Sort() { sort.Sort(ns); ns.tailSort() } +func (ns nodes) Len() int { return len(ns) } +func (ns nodes) Swap(i, j int) { ns[i], ns[j] = ns[j], ns[i] } +func (ns nodes) Less(i, j int) bool { return ns[i].label < ns[j].label } + +// tailSort pushes nodes with '/' as the tail to the end of the list for param nodes. +// The list order determines the traversal order. +func (ns nodes) tailSort() { + for i := len(ns) - 1; i >= 0; i-- { + if ns[i].typ > ntStatic && ns[i].tail == '/' { + ns.Swap(i, len(ns)-1) + return + } + } +} + +func (ns nodes) findEdge(label byte) *node { + num := len(ns) + idx := 0 + i, j := 0, num-1 + for i <= j { + idx = i + (j-i)/2 + if label > ns[idx].label { + i = idx + 1 + } else if label < ns[idx].label { + j = idx - 1 + } else { + i = num // breaks cond + } + } + if ns[idx].label != label { + return nil + } + return ns[idx] +} + +// Route describes the details of a routing handler. +// Handlers map key is an HTTP method +type Route struct { + SubRoutes Routes + Handlers map[string]http.Handler + Pattern string +} + +// WalkFunc is the type of the function called for each method and route visited by Walk. +type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error + +// Walk walks any router tree that implements Routes interface. +func Walk(r Routes, walkFn WalkFunc) error { + return walk(r, walkFn, "") +} + +func walk(r Routes, walkFn WalkFunc, parentRoute string, parentMw ...func(http.Handler) http.Handler) error { + for _, route := range r.Routes() { + mws := make([]func(http.Handler) http.Handler, len(parentMw)) + copy(mws, parentMw) + mws = append(mws, r.Middlewares()...) + + if route.SubRoutes != nil { + if err := walk(route.SubRoutes, walkFn, parentRoute+route.Pattern, mws...); err != nil { + return err + } + continue + } + + for method, handler := range route.Handlers { + if method == "*" { + // Ignore a "catchAll" method, since we pass down all the specific methods for each route. + continue + } + + fullRoute := parentRoute + route.Pattern + fullRoute = strings.Replace(fullRoute, "/*/", "/", -1) + + if chain, ok := handler.(*ChainHandler); ok { + if err := walkFn(method, fullRoute, chain.Endpoint, append(mws, chain.Middlewares...)...); err != nil { + return err + } + } else { + if err := walkFn(method, fullRoute, handler, mws...); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/vendor/github.com/go-ini/ini/.editorconfig b/vendor/github.com/go-ini/ini/.editorconfig new file mode 100644 index 00000000000..4a2d9180f96 --- /dev/null +++ b/vendor/github.com/go-ini/ini/.editorconfig @@ -0,0 +1,12 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*_test.go] +trim_trailing_whitespace = false diff --git a/vendor/github.com/go-ini/ini/.gitignore b/vendor/github.com/go-ini/ini/.gitignore new file mode 100644 index 00000000000..588388bda28 --- /dev/null +++ b/vendor/github.com/go-ini/ini/.gitignore @@ -0,0 +1,7 @@ +testdata/conf_out.ini +ini.sublime-project +ini.sublime-workspace +testdata/conf_reflect.ini +.idea +/.vscode +.DS_Store diff --git a/vendor/github.com/go-ini/ini/.golangci.yml b/vendor/github.com/go-ini/ini/.golangci.yml new file mode 100644 index 00000000000..631e369254d --- /dev/null +++ b/vendor/github.com/go-ini/ini/.golangci.yml @@ -0,0 +1,27 @@ +linters-settings: + staticcheck: + checks: [ + "all", + "-SA1019" # There are valid use cases of strings.Title + ] + nakedret: + max-func-lines: 0 # Disallow any unnamed return statement + +linters: + enable: + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - nakedret + - gofmt + - rowserrcheck + - unconvert + - goimports + - unparam diff --git a/vendor/github.com/go-ini/ini/LICENSE b/vendor/github.com/go-ini/ini/LICENSE new file mode 100644 index 00000000000..d361bbcdf5c --- /dev/null +++ b/vendor/github.com/go-ini/ini/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2014 Unknwon + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/go-ini/ini/Makefile b/vendor/github.com/go-ini/ini/Makefile new file mode 100644 index 00000000000..f3b0dae2d29 --- /dev/null +++ b/vendor/github.com/go-ini/ini/Makefile @@ -0,0 +1,15 @@ +.PHONY: build test bench vet coverage + +build: vet bench + +test: + go test -v -cover -race + +bench: + go test -v -cover -test.bench=. -test.benchmem + +vet: + go vet + +coverage: + go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md new file mode 100644 index 00000000000..30606d9700a --- /dev/null +++ b/vendor/github.com/go-ini/ini/README.md @@ -0,0 +1,43 @@ +# INI + +[![GitHub Workflow Status](https://img.shields.io/github/checks-status/go-ini/ini/main?logo=github&style=for-the-badge)](https://github.com/go-ini/ini/actions?query=branch%3Amain) +[![codecov](https://img.shields.io/codecov/c/github/go-ini/ini/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/go-ini/ini) +[![GoDoc](https://img.shields.io/badge/GoDoc-Reference-blue?style=for-the-badge&logo=go)](https://pkg.go.dev/github.com/go-ini/ini?tab=doc) +[![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/go-ini/ini) + +![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200) + +Package ini provides INI file read and write functionality in Go. + +## Features + +- Load from multiple data sources(file, `[]byte`, `io.Reader` and `io.ReadCloser`) with overwrites. +- Read with recursion values. +- Read with parent-child sections. +- Read with auto-increment key names. +- Read with multiple-line values. +- Read with tons of helper methods. +- Read and convert values to Go types. +- Read and **WRITE** comments of sections and keys. +- Manipulate sections, keys and comments with ease. +- Keep sections and keys in order as you parse and save. + +## Installation + +The minimum requirement of Go is **1.13**. + +```sh +$ go get gopkg.in/ini.v1 +``` + +Please add `-u` flag to update in the future. + +## Getting Help + +- [Getting Started](https://ini.unknwon.io/docs/intro/getting_started) +- [API Documentation](https://gowalker.org/gopkg.in/ini.v1) +- 中国大陆镜像:https://ini.unknwon.cn + +## License + +This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/github.com/go-ini/ini/codecov.yml b/vendor/github.com/go-ini/ini/codecov.yml new file mode 100644 index 00000000000..e02ec84bc05 --- /dev/null +++ b/vendor/github.com/go-ini/ini/codecov.yml @@ -0,0 +1,16 @@ +coverage: + range: "60...95" + status: + project: + default: + threshold: 1% + informational: true + patch: + defualt: + only_pulls: true + informational: true + +comment: + layout: 'diff' + +github_checks: false diff --git a/vendor/github.com/go-ini/ini/data_source.go b/vendor/github.com/go-ini/ini/data_source.go new file mode 100644 index 00000000000..c3a541f1d1b --- /dev/null +++ b/vendor/github.com/go-ini/ini/data_source.go @@ -0,0 +1,76 @@ +// Copyright 2019 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "os" +) + +var ( + _ dataSource = (*sourceFile)(nil) + _ dataSource = (*sourceData)(nil) + _ dataSource = (*sourceReadCloser)(nil) +) + +// dataSource is an interface that returns object which can be read and closed. +type dataSource interface { + ReadCloser() (io.ReadCloser, error) +} + +// sourceFile represents an object that contains content on the local file system. +type sourceFile struct { + name string +} + +func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) { + return os.Open(s.name) +} + +// sourceData represents an object that contains content in memory. +type sourceData struct { + data []byte +} + +func (s *sourceData) ReadCloser() (io.ReadCloser, error) { + return ioutil.NopCloser(bytes.NewReader(s.data)), nil +} + +// sourceReadCloser represents an input stream with Close method. +type sourceReadCloser struct { + reader io.ReadCloser +} + +func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) { + return s.reader, nil +} + +func parseDataSource(source interface{}) (dataSource, error) { + switch s := source.(type) { + case string: + return sourceFile{s}, nil + case []byte: + return &sourceData{s}, nil + case io.ReadCloser: + return &sourceReadCloser{s}, nil + case io.Reader: + return &sourceReadCloser{ioutil.NopCloser(s)}, nil + default: + return nil, fmt.Errorf("error parsing data source: unknown type %q", s) + } +} diff --git a/vendor/github.com/go-ini/ini/deprecated.go b/vendor/github.com/go-ini/ini/deprecated.go new file mode 100644 index 00000000000..48b8e66d6d6 --- /dev/null +++ b/vendor/github.com/go-ini/ini/deprecated.go @@ -0,0 +1,22 @@ +// Copyright 2019 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +var ( + // Deprecated: Use "DefaultSection" instead. + DEFAULT_SECTION = DefaultSection + // Deprecated: AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE. + AllCapsUnderscore = SnackCase +) diff --git a/vendor/github.com/go-ini/ini/error.go b/vendor/github.com/go-ini/ini/error.go new file mode 100644 index 00000000000..f66bc94b8b6 --- /dev/null +++ b/vendor/github.com/go-ini/ini/error.go @@ -0,0 +1,49 @@ +// Copyright 2016 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "fmt" +) + +// ErrDelimiterNotFound indicates the error type of no delimiter is found which there should be one. +type ErrDelimiterNotFound struct { + Line string +} + +// IsErrDelimiterNotFound returns true if the given error is an instance of ErrDelimiterNotFound. +func IsErrDelimiterNotFound(err error) bool { + _, ok := err.(ErrDelimiterNotFound) + return ok +} + +func (err ErrDelimiterNotFound) Error() string { + return fmt.Sprintf("key-value delimiter not found: %s", err.Line) +} + +// ErrEmptyKeyName indicates the error type of no key name is found which there should be one. +type ErrEmptyKeyName struct { + Line string +} + +// IsErrEmptyKeyName returns true if the given error is an instance of ErrEmptyKeyName. +func IsErrEmptyKeyName(err error) bool { + _, ok := err.(ErrEmptyKeyName) + return ok +} + +func (err ErrEmptyKeyName) Error() string { + return fmt.Sprintf("empty key name: %s", err.Line) +} diff --git a/vendor/github.com/go-ini/ini/file.go b/vendor/github.com/go-ini/ini/file.go new file mode 100644 index 00000000000..f8b22408be5 --- /dev/null +++ b/vendor/github.com/go-ini/ini/file.go @@ -0,0 +1,541 @@ +// Copyright 2017 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "strings" + "sync" +) + +// File represents a combination of one or more INI files in memory. +type File struct { + options LoadOptions + dataSources []dataSource + + // Should make things safe, but sometimes doesn't matter. + BlockMode bool + lock sync.RWMutex + + // To keep data in order. + sectionList []string + // To keep track of the index of a section with same name. + // This meta list is only used with non-unique section names are allowed. + sectionIndexes []int + + // Actual data is stored here. + sections map[string][]*Section + + NameMapper + ValueMapper +} + +// newFile initializes File object with given data sources. +func newFile(dataSources []dataSource, opts LoadOptions) *File { + if len(opts.KeyValueDelimiters) == 0 { + opts.KeyValueDelimiters = "=:" + } + if len(opts.KeyValueDelimiterOnWrite) == 0 { + opts.KeyValueDelimiterOnWrite = "=" + } + if len(opts.ChildSectionDelimiter) == 0 { + opts.ChildSectionDelimiter = "." + } + + return &File{ + BlockMode: true, + dataSources: dataSources, + sections: make(map[string][]*Section), + options: opts, + } +} + +// Empty returns an empty file object. +func Empty(opts ...LoadOptions) *File { + var opt LoadOptions + if len(opts) > 0 { + opt = opts[0] + } + + // Ignore error here, we are sure our data is good. + f, _ := LoadSources(opt, []byte("")) + return f +} + +// NewSection creates a new section. +func (f *File) NewSection(name string) (*Section, error) { + if len(name) == 0 { + return nil, errors.New("empty section name") + } + + if (f.options.Insensitive || f.options.InsensitiveSections) && name != DefaultSection { + name = strings.ToLower(name) + } + + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + if !f.options.AllowNonUniqueSections && inSlice(name, f.sectionList) { + return f.sections[name][0], nil + } + + f.sectionList = append(f.sectionList, name) + + // NOTE: Append to indexes must happen before appending to sections, + // otherwise index will have off-by-one problem. + f.sectionIndexes = append(f.sectionIndexes, len(f.sections[name])) + + sec := newSection(f, name) + f.sections[name] = append(f.sections[name], sec) + + return sec, nil +} + +// NewRawSection creates a new section with an unparseable body. +func (f *File) NewRawSection(name, body string) (*Section, error) { + section, err := f.NewSection(name) + if err != nil { + return nil, err + } + + section.isRawSection = true + section.rawBody = body + return section, nil +} + +// NewSections creates a list of sections. +func (f *File) NewSections(names ...string) (err error) { + for _, name := range names { + if _, err = f.NewSection(name); err != nil { + return err + } + } + return nil +} + +// GetSection returns section by given name. +func (f *File) GetSection(name string) (*Section, error) { + secs, err := f.SectionsByName(name) + if err != nil { + return nil, err + } + + return secs[0], err +} + +// HasSection returns true if the file contains a section with given name. +func (f *File) HasSection(name string) bool { + section, _ := f.GetSection(name) + return section != nil +} + +// SectionsByName returns all sections with given name. +func (f *File) SectionsByName(name string) ([]*Section, error) { + if len(name) == 0 { + name = DefaultSection + } + if f.options.Insensitive || f.options.InsensitiveSections { + name = strings.ToLower(name) + } + + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + + secs := f.sections[name] + if len(secs) == 0 { + return nil, fmt.Errorf("section %q does not exist", name) + } + + return secs, nil +} + +// Section assumes named section exists and returns a zero-value when not. +func (f *File) Section(name string) *Section { + sec, err := f.GetSection(name) + if err != nil { + if name == "" { + name = DefaultSection + } + sec, _ = f.NewSection(name) + return sec + } + return sec +} + +// SectionWithIndex assumes named section exists and returns a new section when not. +func (f *File) SectionWithIndex(name string, index int) *Section { + secs, err := f.SectionsByName(name) + if err != nil || len(secs) <= index { + // NOTE: It's OK here because the only possible error is empty section name, + // but if it's empty, this piece of code won't be executed. + newSec, _ := f.NewSection(name) + return newSec + } + + return secs[index] +} + +// Sections returns a list of Section stored in the current instance. +func (f *File) Sections() []*Section { + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + + sections := make([]*Section, len(f.sectionList)) + for i, name := range f.sectionList { + sections[i] = f.sections[name][f.sectionIndexes[i]] + } + return sections +} + +// ChildSections returns a list of child sections of given section name. +func (f *File) ChildSections(name string) []*Section { + return f.Section(name).ChildSections() +} + +// SectionStrings returns list of section names. +func (f *File) SectionStrings() []string { + list := make([]string, len(f.sectionList)) + copy(list, f.sectionList) + return list +} + +// DeleteSection deletes a section or all sections with given name. +func (f *File) DeleteSection(name string) { + secs, err := f.SectionsByName(name) + if err != nil { + return + } + + for i := 0; i < len(secs); i++ { + // For non-unique sections, it is always needed to remove the first one so + // in the next iteration, the subsequent section continue having index 0. + // Ignoring the error as index 0 never returns an error. + _ = f.DeleteSectionWithIndex(name, 0) + } +} + +// DeleteSectionWithIndex deletes a section with given name and index. +func (f *File) DeleteSectionWithIndex(name string, index int) error { + if !f.options.AllowNonUniqueSections && index != 0 { + return fmt.Errorf("delete section with non-zero index is only allowed when non-unique sections is enabled") + } + + if len(name) == 0 { + name = DefaultSection + } + if f.options.Insensitive || f.options.InsensitiveSections { + name = strings.ToLower(name) + } + + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + // Count occurrences of the sections + occurrences := 0 + + sectionListCopy := make([]string, len(f.sectionList)) + copy(sectionListCopy, f.sectionList) + + for i, s := range sectionListCopy { + if s != name { + continue + } + + if occurrences == index { + if len(f.sections[name]) <= 1 { + delete(f.sections, name) // The last one in the map + } else { + f.sections[name] = append(f.sections[name][:index], f.sections[name][index+1:]...) + } + + // Fix section lists + f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...) + f.sectionIndexes = append(f.sectionIndexes[:i], f.sectionIndexes[i+1:]...) + + } else if occurrences > index { + // Fix the indices of all following sections with this name. + f.sectionIndexes[i-1]-- + } + + occurrences++ + } + + return nil +} + +func (f *File) reload(s dataSource) error { + r, err := s.ReadCloser() + if err != nil { + return err + } + defer r.Close() + + return f.parse(r) +} + +// Reload reloads and parses all data sources. +func (f *File) Reload() (err error) { + for _, s := range f.dataSources { + if err = f.reload(s); err != nil { + // In loose mode, we create an empty default section for nonexistent files. + if os.IsNotExist(err) && f.options.Loose { + _ = f.parse(bytes.NewBuffer(nil)) + continue + } + return err + } + if f.options.ShortCircuit { + return nil + } + } + return nil +} + +// Append appends one or more data sources and reloads automatically. +func (f *File) Append(source interface{}, others ...interface{}) error { + ds, err := parseDataSource(source) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + for _, s := range others { + ds, err = parseDataSource(s) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + } + return f.Reload() +} + +func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { + equalSign := DefaultFormatLeft + f.options.KeyValueDelimiterOnWrite + DefaultFormatRight + + if PrettyFormat || PrettyEqual { + equalSign = fmt.Sprintf(" %s ", f.options.KeyValueDelimiterOnWrite) + } + + // Use buffer to make sure target is safe until finish encoding. + buf := bytes.NewBuffer(nil) + lastSectionIdx := len(f.sectionList) - 1 + for i, sname := range f.sectionList { + sec := f.SectionWithIndex(sname, f.sectionIndexes[i]) + if len(sec.Comment) > 0 { + // Support multiline comments + lines := strings.Split(sec.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + lines[i] + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } + } + } + + if i > 0 || DefaultHeader || (i == 0 && strings.ToUpper(sec.name) != DefaultSection) { + if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil { + return nil, err + } + } else { + // Write nothing if default section is empty + if len(sec.keyList) == 0 { + continue + } + } + + isLastSection := i == lastSectionIdx + if sec.isRawSection { + if _, err := buf.WriteString(sec.rawBody); err != nil { + return nil, err + } + + if PrettySection && !isLastSection { + // Put a line between sections + if _, err := buf.WriteString(LineBreak); err != nil { + return nil, err + } + } + continue + } + + // Count and generate alignment length and buffer spaces using the + // longest key. Keys may be modified if they contain certain characters so + // we need to take that into account in our calculation. + alignLength := 0 + if PrettyFormat { + for _, kname := range sec.keyList { + keyLength := len(kname) + // First case will surround key by ` and second by """ + if strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters) { + keyLength += 2 + } else if strings.Contains(kname, "`") { + keyLength += 6 + } + + if keyLength > alignLength { + alignLength = keyLength + } + } + } + alignSpaces := bytes.Repeat([]byte(" "), alignLength) + + KeyList: + for _, kname := range sec.keyList { + key := sec.Key(kname) + if len(key.Comment) > 0 { + if len(indent) > 0 && sname != DefaultSection { + buf.WriteString(indent) + } + + // Support multiline comments + lines := strings.Split(key.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + strings.TrimSpace(lines[i]) + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } + } + } + + if len(indent) > 0 && sname != DefaultSection { + buf.WriteString(indent) + } + + switch { + case key.isAutoIncrement: + kname = "-" + case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters): + kname = "`" + kname + "`" + case strings.Contains(kname, "`"): + kname = `"""` + kname + `"""` + } + + writeKeyValue := func(val string) (bool, error) { + if _, err := buf.WriteString(kname); err != nil { + return false, err + } + + if key.isBooleanType { + buf.WriteString(LineBreak) + return true, nil + } + + // Write out alignment spaces before "=" sign + if PrettyFormat { + buf.Write(alignSpaces[:alignLength-len(kname)]) + } + + // In case key value contains "\n", "`", "\"", "#" or ";" + if strings.ContainsAny(val, "\n`") { + val = `"""` + val + `"""` + } else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") { + val = "`" + val + "`" + } else if len(strings.TrimSpace(val)) != len(val) { + val = `"` + val + `"` + } + if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { + return false, err + } + return false, nil + } + + shadows := key.ValueWithShadows() + if len(shadows) == 0 { + if _, err := writeKeyValue(""); err != nil { + return nil, err + } + } + + for _, val := range shadows { + exitLoop, err := writeKeyValue(val) + if err != nil { + return nil, err + } else if exitLoop { + continue KeyList + } + } + + for _, val := range key.nestedValues { + if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { + return nil, err + } + } + } + + if PrettySection && !isLastSection { + // Put a line between sections + if _, err := buf.WriteString(LineBreak); err != nil { + return nil, err + } + } + } + + return buf, nil +} + +// WriteToIndent writes content into io.Writer with given indention. +// If PrettyFormat has been set to be true, +// it will align "=" sign with spaces under each section. +func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) { + buf, err := f.writeToBuffer(indent) + if err != nil { + return 0, err + } + return buf.WriteTo(w) +} + +// WriteTo writes file content into io.Writer. +func (f *File) WriteTo(w io.Writer) (int64, error) { + return f.WriteToIndent(w, "") +} + +// SaveToIndent writes content to file system with given value indention. +func (f *File) SaveToIndent(filename, indent string) error { + // Note: Because we are truncating with os.Create, + // so it's safer to save to a temporary file location and rename after done. + buf, err := f.writeToBuffer(indent) + if err != nil { + return err + } + + return ioutil.WriteFile(filename, buf.Bytes(), 0666) +} + +// SaveTo writes content to file system. +func (f *File) SaveTo(filename string) error { + return f.SaveToIndent(filename, "") +} diff --git a/vendor/github.com/go-ini/ini/helper.go b/vendor/github.com/go-ini/ini/helper.go new file mode 100644 index 00000000000..f9d80a682a5 --- /dev/null +++ b/vendor/github.com/go-ini/ini/helper.go @@ -0,0 +1,24 @@ +// Copyright 2019 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +func inSlice(str string, s []string) bool { + for _, v := range s { + if str == v { + return true + } + } + return false +} diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go new file mode 100644 index 00000000000..99e7f86511a --- /dev/null +++ b/vendor/github.com/go-ini/ini/ini.go @@ -0,0 +1,176 @@ +// Copyright 2014 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +// Package ini provides INI file read and write functionality in Go. +package ini + +import ( + "os" + "regexp" + "runtime" + "strings" +) + +const ( + // Maximum allowed depth when recursively substituing variable names. + depthValues = 99 +) + +var ( + // DefaultSection is the name of default section. You can use this var or the string literal. + // In most of cases, an empty string is all you need to access the section. + DefaultSection = "DEFAULT" + + // LineBreak is the delimiter to determine or compose a new line. + // This variable will be changed to "\r\n" automatically on Windows at package init time. + LineBreak = "\n" + + // Variable regexp pattern: %(variable)s + varPattern = regexp.MustCompile(`%\(([^)]+)\)s`) + + // DefaultHeader explicitly writes default section header. + DefaultHeader = false + + // PrettySection indicates whether to put a line between sections. + PrettySection = true + // PrettyFormat indicates whether to align "=" sign with spaces to produce pretty output + // or reduce all possible spaces for compact format. + PrettyFormat = true + // PrettyEqual places spaces around "=" sign even when PrettyFormat is false. + PrettyEqual = false + // DefaultFormatLeft places custom spaces on the left when PrettyFormat and PrettyEqual are both disabled. + DefaultFormatLeft = "" + // DefaultFormatRight places custom spaces on the right when PrettyFormat and PrettyEqual are both disabled. + DefaultFormatRight = "" +) + +var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") + +func init() { + if runtime.GOOS == "windows" && !inTest { + LineBreak = "\r\n" + } +} + +// LoadOptions contains all customized options used for load data source(s). +type LoadOptions struct { + // Loose indicates whether the parser should ignore nonexistent files or return error. + Loose bool + // Insensitive indicates whether the parser forces all section and key names to lowercase. + Insensitive bool + // InsensitiveSections indicates whether the parser forces all section to lowercase. + InsensitiveSections bool + // InsensitiveKeys indicates whether the parser forces all key names to lowercase. + InsensitiveKeys bool + // IgnoreContinuation indicates whether to ignore continuation lines while parsing. + IgnoreContinuation bool + // IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value. + IgnoreInlineComment bool + // SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs. + SkipUnrecognizableLines bool + // ShortCircuit indicates whether to ignore other configuration sources after loaded the first available configuration source. + ShortCircuit bool + // AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing. + // This type of keys are mostly used in my.cnf. + AllowBooleanKeys bool + // AllowShadows indicates whether to keep track of keys with same name under same section. + AllowShadows bool + // AllowNestedValues indicates whether to allow AWS-like nested values. + // Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values + AllowNestedValues bool + // AllowPythonMultilineValues indicates whether to allow Python-like multi-line values. + // Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure + // Relevant quote: Values can also span multiple lines, as long as they are indented deeper + // than the first line of the value. + AllowPythonMultilineValues bool + // SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value. + // Docs: https://docs.python.org/2/library/configparser.html + // Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names. + // In the latter case, they need to be preceded by a whitespace character to be recognized as a comment. + SpaceBeforeInlineComment bool + // UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format + // when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value" + UnescapeValueDoubleQuotes bool + // UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format + // when value is NOT surrounded by any quotes. + // Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all. + UnescapeValueCommentSymbols bool + // UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise + // conform to key/value pairs. Specify the names of those blocks here. + UnparseableSections []string + // KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:". + KeyValueDelimiters string + // KeyValueDelimiterOnWrite is the delimiter that are used to separate key and value output. By default, it is "=". + KeyValueDelimiterOnWrite string + // ChildSectionDelimiter is the delimiter that is used to separate child sections. By default, it is ".". + ChildSectionDelimiter string + // PreserveSurroundedQuote indicates whether to preserve surrounded quote (single and double quotes). + PreserveSurroundedQuote bool + // DebugFunc is called to collect debug information (currently only useful to debug parsing Python-style multiline values). + DebugFunc DebugFunc + // ReaderBufferSize is the buffer size of the reader in bytes. + ReaderBufferSize int + // AllowNonUniqueSections indicates whether to allow sections with the same name multiple times. + AllowNonUniqueSections bool + // AllowDuplicateShadowValues indicates whether values for shadowed keys should be deduplicated. + AllowDuplicateShadowValues bool +} + +// DebugFunc is the type of function called to log parse events. +type DebugFunc func(message string) + +// LoadSources allows caller to apply customized options for loading from data source(s). +func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { + sources := make([]dataSource, len(others)+1) + sources[0], err = parseDataSource(source) + if err != nil { + return nil, err + } + for i := range others { + sources[i+1], err = parseDataSource(others[i]) + if err != nil { + return nil, err + } + } + f := newFile(sources, opts) + if err = f.Reload(); err != nil { + return nil, err + } + return f, nil +} + +// Load loads and parses from INI data sources. +// Arguments can be mixed of file name with string type, or raw data in []byte. +// It will return error if list contains nonexistent files. +func Load(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{}, source, others...) +} + +// LooseLoad has exactly same functionality as Load function +// except it ignores nonexistent files instead of returning error. +func LooseLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{Loose: true}, source, others...) +} + +// InsensitiveLoad has exactly same functionality as Load function +// except it forces all section and key names to be lowercased. +func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{Insensitive: true}, source, others...) +} + +// ShadowLoad has exactly same functionality as Load function +// except it allows have shadow keys. +func ShadowLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{AllowShadows: true}, source, others...) +} diff --git a/vendor/github.com/go-ini/ini/key.go b/vendor/github.com/go-ini/ini/key.go new file mode 100644 index 00000000000..a19d9f38ef1 --- /dev/null +++ b/vendor/github.com/go-ini/ini/key.go @@ -0,0 +1,837 @@ +// Copyright 2014 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "strconv" + "strings" + "time" +) + +// Key represents a key under a section. +type Key struct { + s *Section + Comment string + name string + value string + isAutoIncrement bool + isBooleanType bool + + isShadow bool + shadows []*Key + + nestedValues []string +} + +// newKey simply return a key object with given values. +func newKey(s *Section, name, val string) *Key { + return &Key{ + s: s, + name: name, + value: val, + } +} + +func (k *Key) addShadow(val string) error { + if k.isShadow { + return errors.New("cannot add shadow to another shadow key") + } else if k.isAutoIncrement || k.isBooleanType { + return errors.New("cannot add shadow to auto-increment or boolean key") + } + + if !k.s.f.options.AllowDuplicateShadowValues { + // Deduplicate shadows based on their values. + if k.value == val { + return nil + } + for i := range k.shadows { + if k.shadows[i].value == val { + return nil + } + } + } + + shadow := newKey(k.s, k.name, val) + shadow.isShadow = true + k.shadows = append(k.shadows, shadow) + return nil +} + +// AddShadow adds a new shadow key to itself. +func (k *Key) AddShadow(val string) error { + if !k.s.f.options.AllowShadows { + return errors.New("shadow key is not allowed") + } + return k.addShadow(val) +} + +func (k *Key) addNestedValue(val string) error { + if k.isAutoIncrement || k.isBooleanType { + return errors.New("cannot add nested value to auto-increment or boolean key") + } + + k.nestedValues = append(k.nestedValues, val) + return nil +} + +// AddNestedValue adds a nested value to the key. +func (k *Key) AddNestedValue(val string) error { + if !k.s.f.options.AllowNestedValues { + return errors.New("nested value is not allowed") + } + return k.addNestedValue(val) +} + +// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv +type ValueMapper func(string) string + +// Name returns name of key. +func (k *Key) Name() string { + return k.name +} + +// Value returns raw value of key for performance purpose. +func (k *Key) Value() string { + return k.value +} + +// ValueWithShadows returns raw values of key and its shadows if any. Shadow +// keys with empty values are ignored from the returned list. +func (k *Key) ValueWithShadows() []string { + if len(k.shadows) == 0 { + if k.value == "" { + return []string{} + } + return []string{k.value} + } + + vals := make([]string, 0, len(k.shadows)+1) + if k.value != "" { + vals = append(vals, k.value) + } + for _, s := range k.shadows { + if s.value != "" { + vals = append(vals, s.value) + } + } + return vals +} + +// NestedValues returns nested values stored in the key. +// It is possible returned value is nil if no nested values stored in the key. +func (k *Key) NestedValues() []string { + return k.nestedValues +} + +// transformValue takes a raw value and transforms to its final string. +func (k *Key) transformValue(val string) string { + if k.s.f.ValueMapper != nil { + val = k.s.f.ValueMapper(val) + } + + // Fail-fast if no indicate char found for recursive value + if !strings.Contains(val, "%") { + return val + } + for i := 0; i < depthValues; i++ { + vr := varPattern.FindString(val) + if len(vr) == 0 { + break + } + + // Take off leading '%(' and trailing ')s'. + noption := vr[2 : len(vr)-2] + + // Search in the same section. + // If not found or found the key itself, then search again in default section. + nk, err := k.s.GetKey(noption) + if err != nil || k == nk { + nk, _ = k.s.f.Section("").GetKey(noption) + if nk == nil { + // Stop when no results found in the default section, + // and returns the value as-is. + break + } + } + + // Substitute by new value and take off leading '%(' and trailing ')s'. + val = strings.Replace(val, vr, nk.value, -1) + } + return val +} + +// String returns string representation of value. +func (k *Key) String() string { + return k.transformValue(k.value) +} + +// Validate accepts a validate function which can +// return modifed result as key value. +func (k *Key) Validate(fn func(string) string) string { + return fn(k.String()) +} + +// parseBool returns the boolean value represented by the string. +// +// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On, +// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off. +// Any other value returns an error. +func parseBool(str string) (value bool, err error) { + switch str { + case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On": + return true, nil + case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off": + return false, nil + } + return false, fmt.Errorf("parsing \"%s\": invalid syntax", str) +} + +// Bool returns bool type value. +func (k *Key) Bool() (bool, error) { + return parseBool(k.String()) +} + +// Float64 returns float64 type value. +func (k *Key) Float64() (float64, error) { + return strconv.ParseFloat(k.String(), 64) +} + +// Int returns int type value. +func (k *Key) Int() (int, error) { + v, err := strconv.ParseInt(k.String(), 0, 64) + return int(v), err +} + +// Int64 returns int64 type value. +func (k *Key) Int64() (int64, error) { + return strconv.ParseInt(k.String(), 0, 64) +} + +// Uint returns uint type valued. +func (k *Key) Uint() (uint, error) { + u, e := strconv.ParseUint(k.String(), 0, 64) + return uint(u), e +} + +// Uint64 returns uint64 type value. +func (k *Key) Uint64() (uint64, error) { + return strconv.ParseUint(k.String(), 0, 64) +} + +// Duration returns time.Duration type value. +func (k *Key) Duration() (time.Duration, error) { + return time.ParseDuration(k.String()) +} + +// TimeFormat parses with given format and returns time.Time type value. +func (k *Key) TimeFormat(format string) (time.Time, error) { + return time.Parse(format, k.String()) +} + +// Time parses with RFC3339 format and returns time.Time type value. +func (k *Key) Time() (time.Time, error) { + return k.TimeFormat(time.RFC3339) +} + +// MustString returns default value if key value is empty. +func (k *Key) MustString(defaultVal string) string { + val := k.String() + if len(val) == 0 { + k.value = defaultVal + return defaultVal + } + return val +} + +// MustBool always returns value without error, +// it returns false if error occurs. +func (k *Key) MustBool(defaultVal ...bool) bool { + val, err := k.Bool() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatBool(defaultVal[0]) + return defaultVal[0] + } + return val +} + +// MustFloat64 always returns value without error, +// it returns 0.0 if error occurs. +func (k *Key) MustFloat64(defaultVal ...float64) float64 { + val, err := k.Float64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64) + return defaultVal[0] + } + return val +} + +// MustInt always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt(defaultVal ...int) int { + val, err := k.Int() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatInt(int64(defaultVal[0]), 10) + return defaultVal[0] + } + return val +} + +// MustInt64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt64(defaultVal ...int64) int64 { + val, err := k.Int64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatInt(defaultVal[0], 10) + return defaultVal[0] + } + return val +} + +// MustUint always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint(defaultVal ...uint) uint { + val, err := k.Uint() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatUint(uint64(defaultVal[0]), 10) + return defaultVal[0] + } + return val +} + +// MustUint64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint64(defaultVal ...uint64) uint64 { + val, err := k.Uint64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatUint(defaultVal[0], 10) + return defaultVal[0] + } + return val +} + +// MustDuration always returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration { + val, err := k.Duration() + if len(defaultVal) > 0 && err != nil { + k.value = defaultVal[0].String() + return defaultVal[0] + } + return val +} + +// MustTimeFormat always parses with given format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time { + val, err := k.TimeFormat(format) + if len(defaultVal) > 0 && err != nil { + k.value = defaultVal[0].Format(format) + return defaultVal[0] + } + return val +} + +// MustTime always parses with RFC3339 format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTime(defaultVal ...time.Time) time.Time { + return k.MustTimeFormat(time.RFC3339, defaultVal...) +} + +// In always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) In(defaultVal string, candidates []string) string { + val := k.String() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InFloat64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 { + val := k.MustFloat64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt(defaultVal int, candidates []int) int { + val := k.MustInt() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 { + val := k.MustInt64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint(defaultVal uint, candidates []uint) uint { + val := k.MustUint() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 { + val := k.MustUint64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTimeFormat always parses with given format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time { + val := k.MustTimeFormat(format) + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTime always parses with RFC3339 format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time { + return k.InTimeFormat(time.RFC3339, defaultVal, candidates) +} + +// RangeFloat64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 { + val := k.MustFloat64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt(defaultVal, min, max int) int { + val := k.MustInt() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt64(defaultVal, min, max int64) int64 { + val := k.MustInt64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeTimeFormat checks if value with given format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time { + val := k.MustTimeFormat(format) + if val.Unix() < min.Unix() || val.Unix() > max.Unix() { + return defaultVal + } + return val +} + +// RangeTime checks if value with RFC3339 format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time { + return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max) +} + +// Strings returns list of string divided by given delimiter. +func (k *Key) Strings(delim string) []string { + str := k.String() + if len(str) == 0 { + return []string{} + } + + runes := []rune(str) + vals := make([]string, 0, 2) + var buf bytes.Buffer + escape := false + idx := 0 + for { + if escape { + escape = false + if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) { + buf.WriteRune('\\') + } + buf.WriteRune(runes[idx]) + } else { + if runes[idx] == '\\' { + escape = true + } else if strings.HasPrefix(string(runes[idx:]), delim) { + idx += len(delim) - 1 + vals = append(vals, strings.TrimSpace(buf.String())) + buf.Reset() + } else { + buf.WriteRune(runes[idx]) + } + } + idx++ + if idx == len(runes) { + break + } + } + + if buf.Len() > 0 { + vals = append(vals, strings.TrimSpace(buf.String())) + } + + return vals +} + +// StringsWithShadows returns list of string divided by given delimiter. +// Shadows will also be appended if any. +func (k *Key) StringsWithShadows(delim string) []string { + vals := k.ValueWithShadows() + results := make([]string, 0, len(vals)*2) + for i := range vals { + if len(vals) == 0 { + continue + } + + results = append(results, strings.Split(vals[i], delim)...) + } + + for i := range results { + results[i] = k.transformValue(strings.TrimSpace(results[i])) + } + return results +} + +// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Float64s(delim string) []float64 { + vals, _ := k.parseFloat64s(k.Strings(delim), true, false) + return vals +} + +// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Ints(delim string) []int { + vals, _ := k.parseInts(k.Strings(delim), true, false) + return vals +} + +// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Int64s(delim string) []int64 { + vals, _ := k.parseInt64s(k.Strings(delim), true, false) + return vals +} + +// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Uints(delim string) []uint { + vals, _ := k.parseUints(k.Strings(delim), true, false) + return vals +} + +// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Uint64s(delim string) []uint64 { + vals, _ := k.parseUint64s(k.Strings(delim), true, false) + return vals +} + +// Bools returns list of bool divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Bools(delim string) []bool { + vals, _ := k.parseBools(k.Strings(delim), true, false) + return vals +} + +// TimesFormat parses with given format and returns list of time.Time divided by given delimiter. +// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). +func (k *Key) TimesFormat(format, delim string) []time.Time { + vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false) + return vals +} + +// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter. +// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). +func (k *Key) Times(delim string) []time.Time { + return k.TimesFormat(time.RFC3339, delim) +} + +// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then +// it will not be included to result list. +func (k *Key) ValidFloat64s(delim string) []float64 { + vals, _ := k.parseFloat64s(k.Strings(delim), false, false) + return vals +} + +// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will +// not be included to result list. +func (k *Key) ValidInts(delim string) []int { + vals, _ := k.parseInts(k.Strings(delim), false, false) + return vals +} + +// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer, +// then it will not be included to result list. +func (k *Key) ValidInt64s(delim string) []int64 { + vals, _ := k.parseInt64s(k.Strings(delim), false, false) + return vals +} + +// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer, +// then it will not be included to result list. +func (k *Key) ValidUints(delim string) []uint { + vals, _ := k.parseUints(k.Strings(delim), false, false) + return vals +} + +// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned +// integer, then it will not be included to result list. +func (k *Key) ValidUint64s(delim string) []uint64 { + vals, _ := k.parseUint64s(k.Strings(delim), false, false) + return vals +} + +// ValidBools returns list of bool divided by given delimiter. If some value is not 64-bit unsigned +// integer, then it will not be included to result list. +func (k *Key) ValidBools(delim string) []bool { + vals, _ := k.parseBools(k.Strings(delim), false, false) + return vals +} + +// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter. +func (k *Key) ValidTimesFormat(format, delim string) []time.Time { + vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false) + return vals +} + +// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter. +func (k *Key) ValidTimes(delim string) []time.Time { + return k.ValidTimesFormat(time.RFC3339, delim) +} + +// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictFloat64s(delim string) ([]float64, error) { + return k.parseFloat64s(k.Strings(delim), false, true) +} + +// StrictInts returns list of int divided by given delimiter or error on first invalid input. +func (k *Key) StrictInts(delim string) ([]int, error) { + return k.parseInts(k.Strings(delim), false, true) +} + +// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictInt64s(delim string) ([]int64, error) { + return k.parseInt64s(k.Strings(delim), false, true) +} + +// StrictUints returns list of uint divided by given delimiter or error on first invalid input. +func (k *Key) StrictUints(delim string) ([]uint, error) { + return k.parseUints(k.Strings(delim), false, true) +} + +// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictUint64s(delim string) ([]uint64, error) { + return k.parseUint64s(k.Strings(delim), false, true) +} + +// StrictBools returns list of bool divided by given delimiter or error on first invalid input. +func (k *Key) StrictBools(delim string) ([]bool, error) { + return k.parseBools(k.Strings(delim), false, true) +} + +// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter +// or error on first invalid input. +func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) { + return k.parseTimesFormat(format, k.Strings(delim), false, true) +} + +// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter +// or error on first invalid input. +func (k *Key) StrictTimes(delim string) ([]time.Time, error) { + return k.StrictTimesFormat(time.RFC3339, delim) +} + +// parseBools transforms strings to bools. +func (k *Key) parseBools(strs []string, addInvalid, returnOnInvalid bool) ([]bool, error) { + vals := make([]bool, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := parseBool(str) + return val, err + } + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, val.(bool)) + } + } + return vals, err +} + +// parseFloat64s transforms strings to float64s. +func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) { + vals := make([]float64, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := strconv.ParseFloat(str, 64) + return val, err + } + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, val.(float64)) + } + } + return vals, err +} + +// parseInts transforms strings to ints. +func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) { + vals := make([]int, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := strconv.ParseInt(str, 0, 64) + return val, err + } + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, int(val.(int64))) + } + } + return vals, err +} + +// parseInt64s transforms strings to int64s. +func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) { + vals := make([]int64, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := strconv.ParseInt(str, 0, 64) + return val, err + } + + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, val.(int64)) + } + } + return vals, err +} + +// parseUints transforms strings to uints. +func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) { + vals := make([]uint, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := strconv.ParseUint(str, 0, 64) + return val, err + } + + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, uint(val.(uint64))) + } + } + return vals, err +} + +// parseUint64s transforms strings to uint64s. +func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) { + vals := make([]uint64, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := strconv.ParseUint(str, 0, 64) + return val, err + } + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, val.(uint64)) + } + } + return vals, err +} + +type Parser func(str string) (interface{}, error) + +// parseTimesFormat transforms strings to times in given format. +func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { + vals := make([]time.Time, 0, len(strs)) + parser := func(str string) (interface{}, error) { + val, err := time.Parse(format, str) + return val, err + } + rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) + if err == nil { + for _, val := range rawVals { + vals = append(vals, val.(time.Time)) + } + } + return vals, err +} + +// doParse transforms strings to different types +func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) { + vals := make([]interface{}, 0, len(strs)) + for _, str := range strs { + val, err := parser(str) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// SetValue changes key value. +func (k *Key) SetValue(v string) { + if k.s.f.BlockMode { + k.s.f.lock.Lock() + defer k.s.f.lock.Unlock() + } + + k.value = v + k.s.keysHash[k.name] = v +} diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go new file mode 100644 index 00000000000..44fc526c2cb --- /dev/null +++ b/vendor/github.com/go-ini/ini/parser.go @@ -0,0 +1,520 @@ +// Copyright 2015 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "bufio" + "bytes" + "fmt" + "io" + "regexp" + "strconv" + "strings" + "unicode" +) + +const minReaderBufferSize = 4096 + +var pythonMultiline = regexp.MustCompile(`^([\t\f ]+)(.*)`) + +type parserOptions struct { + IgnoreContinuation bool + IgnoreInlineComment bool + AllowPythonMultilineValues bool + SpaceBeforeInlineComment bool + UnescapeValueDoubleQuotes bool + UnescapeValueCommentSymbols bool + PreserveSurroundedQuote bool + DebugFunc DebugFunc + ReaderBufferSize int +} + +type parser struct { + buf *bufio.Reader + options parserOptions + + isEOF bool + count int + comment *bytes.Buffer +} + +func (p *parser) debug(format string, args ...interface{}) { + if p.options.DebugFunc != nil { + p.options.DebugFunc(fmt.Sprintf(format, args...)) + } +} + +func newParser(r io.Reader, opts parserOptions) *parser { + size := opts.ReaderBufferSize + if size < minReaderBufferSize { + size = minReaderBufferSize + } + + return &parser{ + buf: bufio.NewReaderSize(r, size), + options: opts, + count: 1, + comment: &bytes.Buffer{}, + } +} + +// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format. +// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding +func (p *parser) BOM() error { + mask, err := p.buf.Peek(2) + if err != nil && err != io.EOF { + return err + } else if len(mask) < 2 { + return nil + } + + switch { + case mask[0] == 254 && mask[1] == 255: + fallthrough + case mask[0] == 255 && mask[1] == 254: + _, err = p.buf.Read(mask) + if err != nil { + return err + } + case mask[0] == 239 && mask[1] == 187: + mask, err := p.buf.Peek(3) + if err != nil && err != io.EOF { + return err + } else if len(mask) < 3 { + return nil + } + if mask[2] == 191 { + _, err = p.buf.Read(mask) + if err != nil { + return err + } + } + } + return nil +} + +func (p *parser) readUntil(delim byte) ([]byte, error) { + data, err := p.buf.ReadBytes(delim) + if err != nil { + if err == io.EOF { + p.isEOF = true + } else { + return nil, err + } + } + return data, nil +} + +func cleanComment(in []byte) ([]byte, bool) { + i := bytes.IndexAny(in, "#;") + if i == -1 { + return nil, false + } + return in[i:], true +} + +func readKeyName(delimiters string, in []byte) (string, int, error) { + line := string(in) + + // Check if key name surrounded by quotes. + var keyQuote string + if line[0] == '"' { + if len(line) > 6 && line[0:3] == `"""` { + keyQuote = `"""` + } else { + keyQuote = `"` + } + } else if line[0] == '`' { + keyQuote = "`" + } + + // Get out key name + var endIdx int + if len(keyQuote) > 0 { + startIdx := len(keyQuote) + // FIXME: fail case -> """"""name"""=value + pos := strings.Index(line[startIdx:], keyQuote) + if pos == -1 { + return "", -1, fmt.Errorf("missing closing key quote: %s", line) + } + pos += startIdx + + // Find key-value delimiter + i := strings.IndexAny(line[pos+startIdx:], delimiters) + if i < 0 { + return "", -1, ErrDelimiterNotFound{line} + } + endIdx = pos + i + return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil + } + + endIdx = strings.IndexAny(line, delimiters) + if endIdx < 0 { + return "", -1, ErrDelimiterNotFound{line} + } + if endIdx == 0 { + return "", -1, ErrEmptyKeyName{line} + } + + return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil +} + +func (p *parser) readMultilines(line, val, valQuote string) (string, error) { + for { + data, err := p.readUntil('\n') + if err != nil { + return "", err + } + next := string(data) + + pos := strings.LastIndex(next, valQuote) + if pos > -1 { + val += next[:pos] + + comment, has := cleanComment([]byte(next[pos:])) + if has { + p.comment.Write(bytes.TrimSpace(comment)) + } + break + } + val += next + if p.isEOF { + return "", fmt.Errorf("missing closing key quote from %q to %q", line, next) + } + } + return val, nil +} + +func (p *parser) readContinuationLines(val string) (string, error) { + for { + data, err := p.readUntil('\n') + if err != nil { + return "", err + } + next := strings.TrimSpace(string(data)) + + if len(next) == 0 { + break + } + val += next + if val[len(val)-1] != '\\' { + break + } + val = val[:len(val)-1] + } + return val, nil +} + +// hasSurroundedQuote check if and only if the first and last characters +// are quotes \" or \'. +// It returns false if any other parts also contain same kind of quotes. +func hasSurroundedQuote(in string, quote byte) bool { + return len(in) >= 2 && in[0] == quote && in[len(in)-1] == quote && + strings.IndexByte(in[1:], quote) == len(in)-2 +} + +func (p *parser) readValue(in []byte, bufferSize int) (string, error) { + + line := strings.TrimLeftFunc(string(in), unicode.IsSpace) + if len(line) == 0 { + if p.options.AllowPythonMultilineValues && len(in) > 0 && in[len(in)-1] == '\n' { + return p.readPythonMultilines(line, bufferSize) + } + return "", nil + } + + var valQuote string + if len(line) > 3 && line[0:3] == `"""` { + valQuote = `"""` + } else if line[0] == '`' { + valQuote = "`" + } else if p.options.UnescapeValueDoubleQuotes && line[0] == '"' { + valQuote = `"` + } + + if len(valQuote) > 0 { + startIdx := len(valQuote) + pos := strings.LastIndex(line[startIdx:], valQuote) + // Check for multi-line value + if pos == -1 { + return p.readMultilines(line, line[startIdx:], valQuote) + } + + if p.options.UnescapeValueDoubleQuotes && valQuote == `"` { + return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil + } + return line[startIdx : pos+startIdx], nil + } + + lastChar := line[len(line)-1] + // Won't be able to reach here if value only contains whitespace + line = strings.TrimSpace(line) + trimmedLastChar := line[len(line)-1] + + // Check continuation lines when desired + if !p.options.IgnoreContinuation && trimmedLastChar == '\\' { + return p.readContinuationLines(line[:len(line)-1]) + } + + // Check if ignore inline comment + if !p.options.IgnoreInlineComment { + var i int + if p.options.SpaceBeforeInlineComment { + i = strings.Index(line, " #") + if i == -1 { + i = strings.Index(line, " ;") + } + + } else { + i = strings.IndexAny(line, "#;") + } + + if i > -1 { + p.comment.WriteString(line[i:]) + line = strings.TrimSpace(line[:i]) + } + + } + + // Trim single and double quotes + if (hasSurroundedQuote(line, '\'') || + hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote { + line = line[1 : len(line)-1] + } else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols { + line = strings.ReplaceAll(line, `\;`, ";") + line = strings.ReplaceAll(line, `\#`, "#") + } else if p.options.AllowPythonMultilineValues && lastChar == '\n' { + return p.readPythonMultilines(line, bufferSize) + } + + return line, nil +} + +func (p *parser) readPythonMultilines(line string, bufferSize int) (string, error) { + parserBufferPeekResult, _ := p.buf.Peek(bufferSize) + peekBuffer := bytes.NewBuffer(parserBufferPeekResult) + + for { + peekData, peekErr := peekBuffer.ReadBytes('\n') + if peekErr != nil && peekErr != io.EOF { + p.debug("readPythonMultilines: failed to peek with error: %v", peekErr) + return "", peekErr + } + + p.debug("readPythonMultilines: parsing %q", string(peekData)) + + peekMatches := pythonMultiline.FindStringSubmatch(string(peekData)) + p.debug("readPythonMultilines: matched %d parts", len(peekMatches)) + for n, v := range peekMatches { + p.debug(" %d: %q", n, v) + } + + // Return if not a Python multiline value. + if len(peekMatches) != 3 { + p.debug("readPythonMultilines: end of value, got: %q", line) + return line, nil + } + + // Advance the parser reader (buffer) in-sync with the peek buffer. + _, err := p.buf.Discard(len(peekData)) + if err != nil { + p.debug("readPythonMultilines: failed to skip to the end, returning error") + return "", err + } + + line += "\n" + peekMatches[0] + } +} + +// parse parses data through an io.Reader. +func (f *File) parse(reader io.Reader) (err error) { + p := newParser(reader, parserOptions{ + IgnoreContinuation: f.options.IgnoreContinuation, + IgnoreInlineComment: f.options.IgnoreInlineComment, + AllowPythonMultilineValues: f.options.AllowPythonMultilineValues, + SpaceBeforeInlineComment: f.options.SpaceBeforeInlineComment, + UnescapeValueDoubleQuotes: f.options.UnescapeValueDoubleQuotes, + UnescapeValueCommentSymbols: f.options.UnescapeValueCommentSymbols, + PreserveSurroundedQuote: f.options.PreserveSurroundedQuote, + DebugFunc: f.options.DebugFunc, + ReaderBufferSize: f.options.ReaderBufferSize, + }) + if err = p.BOM(); err != nil { + return fmt.Errorf("BOM: %v", err) + } + + // Ignore error because default section name is never empty string. + name := DefaultSection + if f.options.Insensitive || f.options.InsensitiveSections { + name = strings.ToLower(DefaultSection) + } + section, _ := f.NewSection(name) + + // This "last" is not strictly equivalent to "previous one" if current key is not the first nested key + var isLastValueEmpty bool + var lastRegularKey *Key + + var line []byte + var inUnparseableSection bool + + // NOTE: Iterate and increase `currentPeekSize` until + // the size of the parser buffer is found. + // TODO(unknwon): When Golang 1.10 is the lowest version supported, replace with `parserBufferSize := p.buf.Size()`. + parserBufferSize := 0 + // NOTE: Peek 4kb at a time. + currentPeekSize := minReaderBufferSize + + if f.options.AllowPythonMultilineValues { + for { + peekBytes, _ := p.buf.Peek(currentPeekSize) + peekBytesLength := len(peekBytes) + + if parserBufferSize >= peekBytesLength { + break + } + + currentPeekSize *= 2 + parserBufferSize = peekBytesLength + } + } + + for !p.isEOF { + line, err = p.readUntil('\n') + if err != nil { + return err + } + + if f.options.AllowNestedValues && + isLastValueEmpty && len(line) > 0 { + if line[0] == ' ' || line[0] == '\t' { + err = lastRegularKey.addNestedValue(string(bytes.TrimSpace(line))) + if err != nil { + return err + } + continue + } + } + + line = bytes.TrimLeftFunc(line, unicode.IsSpace) + if len(line) == 0 { + continue + } + + // Comments + if line[0] == '#' || line[0] == ';' { + // Note: we do not care ending line break, + // it is needed for adding second line, + // so just clean it once at the end when set to value. + p.comment.Write(line) + continue + } + + // Section + if line[0] == '[' { + // Read to the next ']' (TODO: support quoted strings) + closeIdx := bytes.LastIndexByte(line, ']') + if closeIdx == -1 { + return fmt.Errorf("unclosed section: %s", line) + } + + name := string(line[1:closeIdx]) + section, err = f.NewSection(name) + if err != nil { + return err + } + + comment, has := cleanComment(line[closeIdx+1:]) + if has { + p.comment.Write(comment) + } + + section.Comment = strings.TrimSpace(p.comment.String()) + + // Reset auto-counter and comments + p.comment.Reset() + p.count = 1 + // Nested values can't span sections + isLastValueEmpty = false + + inUnparseableSection = false + for i := range f.options.UnparseableSections { + if f.options.UnparseableSections[i] == name || + ((f.options.Insensitive || f.options.InsensitiveSections) && strings.EqualFold(f.options.UnparseableSections[i], name)) { + inUnparseableSection = true + continue + } + } + continue + } + + if inUnparseableSection { + section.isRawSection = true + section.rawBody += string(line) + continue + } + + kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line) + if err != nil { + switch { + // Treat as boolean key when desired, and whole line is key name. + case IsErrDelimiterNotFound(err): + switch { + case f.options.AllowBooleanKeys: + kname, err := p.readValue(line, parserBufferSize) + if err != nil { + return err + } + key, err := section.NewBooleanKey(kname) + if err != nil { + return err + } + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + continue + + case f.options.SkipUnrecognizableLines: + continue + } + case IsErrEmptyKeyName(err) && f.options.SkipUnrecognizableLines: + continue + } + return err + } + + // Auto increment. + isAutoIncr := false + if kname == "-" { + isAutoIncr = true + kname = "#" + strconv.Itoa(p.count) + p.count++ + } + + value, err := p.readValue(line[offset:], parserBufferSize) + if err != nil { + return err + } + isLastValueEmpty = len(value) == 0 + + key, err := section.NewKey(kname, value) + if err != nil { + return err + } + key.isAutoIncrement = isAutoIncr + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + lastRegularKey = key + } + return nil +} diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go new file mode 100644 index 00000000000..a3615d820b7 --- /dev/null +++ b/vendor/github.com/go-ini/ini/section.go @@ -0,0 +1,256 @@ +// Copyright 2014 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "errors" + "fmt" + "strings" +) + +// Section represents a config section. +type Section struct { + f *File + Comment string + name string + keys map[string]*Key + keyList []string + keysHash map[string]string + + isRawSection bool + rawBody string +} + +func newSection(f *File, name string) *Section { + return &Section{ + f: f, + name: name, + keys: make(map[string]*Key), + keyList: make([]string, 0, 10), + keysHash: make(map[string]string), + } +} + +// Name returns name of Section. +func (s *Section) Name() string { + return s.name +} + +// Body returns rawBody of Section if the section was marked as unparseable. +// It still follows the other rules of the INI format surrounding leading/trailing whitespace. +func (s *Section) Body() string { + return strings.TrimSpace(s.rawBody) +} + +// SetBody updates body content only if section is raw. +func (s *Section) SetBody(body string) { + if !s.isRawSection { + return + } + s.rawBody = body +} + +// NewKey creates a new key to given section. +func (s *Section) NewKey(name, val string) (*Key, error) { + if len(name) == 0 { + return nil, errors.New("error creating new key: empty key name") + } else if s.f.options.Insensitive || s.f.options.InsensitiveKeys { + name = strings.ToLower(name) + } + + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + if inSlice(name, s.keyList) { + if s.f.options.AllowShadows { + if err := s.keys[name].addShadow(val); err != nil { + return nil, err + } + } else { + s.keys[name].value = val + s.keysHash[name] = val + } + return s.keys[name], nil + } + + s.keyList = append(s.keyList, name) + s.keys[name] = newKey(s, name, val) + s.keysHash[name] = val + return s.keys[name], nil +} + +// NewBooleanKey creates a new boolean type key to given section. +func (s *Section) NewBooleanKey(name string) (*Key, error) { + key, err := s.NewKey(name, "true") + if err != nil { + return nil, err + } + + key.isBooleanType = true + return key, nil +} + +// GetKey returns key in section by given name. +func (s *Section) GetKey(name string) (*Key, error) { + if s.f.BlockMode { + s.f.lock.RLock() + } + if s.f.options.Insensitive || s.f.options.InsensitiveKeys { + name = strings.ToLower(name) + } + key := s.keys[name] + if s.f.BlockMode { + s.f.lock.RUnlock() + } + + if key == nil { + // Check if it is a child-section. + sname := s.name + for { + if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 { + sname = sname[:i] + sec, err := s.f.GetSection(sname) + if err != nil { + continue + } + return sec.GetKey(name) + } + break + } + return nil, fmt.Errorf("error when getting key of section %q: key %q not exists", s.name, name) + } + return key, nil +} + +// HasKey returns true if section contains a key with given name. +func (s *Section) HasKey(name string) bool { + key, _ := s.GetKey(name) + return key != nil +} + +// Deprecated: Use "HasKey" instead. +func (s *Section) Haskey(name string) bool { + return s.HasKey(name) +} + +// HasValue returns true if section contains given raw value. +func (s *Section) HasValue(value string) bool { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + for _, k := range s.keys { + if value == k.value { + return true + } + } + return false +} + +// Key assumes named Key exists in section and returns a zero-value when not. +func (s *Section) Key(name string) *Key { + key, err := s.GetKey(name) + if err != nil { + // It's OK here because the only possible error is empty key name, + // but if it's empty, this piece of code won't be executed. + key, _ = s.NewKey(name, "") + return key + } + return key +} + +// Keys returns list of keys of section. +func (s *Section) Keys() []*Key { + keys := make([]*Key, len(s.keyList)) + for i := range s.keyList { + keys[i] = s.Key(s.keyList[i]) + } + return keys +} + +// ParentKeys returns list of keys of parent section. +func (s *Section) ParentKeys() []*Key { + var parentKeys []*Key + sname := s.name + for { + if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 { + sname = sname[:i] + sec, err := s.f.GetSection(sname) + if err != nil { + continue + } + parentKeys = append(parentKeys, sec.Keys()...) + } else { + break + } + + } + return parentKeys +} + +// KeyStrings returns list of key names of section. +func (s *Section) KeyStrings() []string { + list := make([]string, len(s.keyList)) + copy(list, s.keyList) + return list +} + +// KeysHash returns keys hash consisting of names and values. +func (s *Section) KeysHash() map[string]string { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + hash := make(map[string]string, len(s.keysHash)) + for key, value := range s.keysHash { + hash[key] = value + } + return hash +} + +// DeleteKey deletes a key from section. +func (s *Section) DeleteKey(name string) { + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + for i, k := range s.keyList { + if k == name { + s.keyList = append(s.keyList[:i], s.keyList[i+1:]...) + delete(s.keys, name) + delete(s.keysHash, name) + return + } + } +} + +// ChildSections returns a list of child sections of current section. +// For example, "[parent.child1]" and "[parent.child12]" are child sections +// of section "[parent]". +func (s *Section) ChildSections() []*Section { + prefix := s.name + s.f.options.ChildSectionDelimiter + children := make([]*Section, 0, 3) + for _, name := range s.f.sectionList { + if strings.HasPrefix(name, prefix) { + children = append(children, s.f.sections[name]...) + } + } + return children +} diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go new file mode 100644 index 00000000000..a486b2fe0fd --- /dev/null +++ b/vendor/github.com/go-ini/ini/struct.go @@ -0,0 +1,747 @@ +// Copyright 2014 Unknwon +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "strings" + "time" + "unicode" +) + +// NameMapper represents a ini tag name mapper. +type NameMapper func(string) string + +// Built-in name getters. +var ( + // SnackCase converts to format SNACK_CASE. + SnackCase NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + } + newstr = append(newstr, unicode.ToUpper(chr)) + } + return string(newstr) + } + // TitleUnderscore converts to format title_underscore. + TitleUnderscore NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + chr -= 'A' - 'a' + } + newstr = append(newstr, chr) + } + return string(newstr) + } +) + +func (s *Section) parseFieldName(raw, actual string) string { + if len(actual) > 0 { + return actual + } + if s.f.NameMapper != nil { + return s.f.NameMapper(raw) + } + return raw +} + +func parseDelim(actual string) string { + if len(actual) > 0 { + return actual + } + return "," +} + +var reflectTime = reflect.TypeOf(time.Now()).Kind() + +// setSliceWithProperType sets proper values to slice based on its type. +func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { + var strs []string + if allowShadow { + strs = key.StringsWithShadows(delim) + } else { + strs = key.Strings(delim) + } + + numVals := len(strs) + if numVals == 0 { + return nil + } + + var vals interface{} + var err error + + sliceOf := field.Type().Elem().Kind() + switch sliceOf { + case reflect.String: + vals = strs + case reflect.Int: + vals, err = key.parseInts(strs, true, false) + case reflect.Int64: + vals, err = key.parseInt64s(strs, true, false) + case reflect.Uint: + vals, err = key.parseUints(strs, true, false) + case reflect.Uint64: + vals, err = key.parseUint64s(strs, true, false) + case reflect.Float64: + vals, err = key.parseFloat64s(strs, true, false) + case reflect.Bool: + vals, err = key.parseBools(strs, true, false) + case reflectTime: + vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + if err != nil && isStrict { + return err + } + + slice := reflect.MakeSlice(field.Type(), numVals, numVals) + for i := 0; i < numVals; i++ { + switch sliceOf { + case reflect.String: + slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i])) + case reflect.Int: + slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i])) + case reflect.Int64: + slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i])) + case reflect.Uint: + slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i])) + case reflect.Uint64: + slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i])) + case reflect.Float64: + slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i])) + case reflect.Bool: + slice.Index(i).Set(reflect.ValueOf(vals.([]bool)[i])) + case reflectTime: + slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i])) + } + } + field.Set(slice) + return nil +} + +func wrapStrictError(err error, isStrict bool) error { + if isStrict { + return err + } + return nil +} + +// setWithProperType sets proper value to field based on its type, +// but it does not return error for failing parsing, +// because we want to use default value that is already assigned to struct. +func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { + vt := t + isPtr := t.Kind() == reflect.Ptr + if isPtr { + vt = t.Elem() + } + switch vt.Kind() { + case reflect.String: + stringVal := key.String() + if isPtr { + field.Set(reflect.ValueOf(&stringVal)) + } else if len(stringVal) > 0 { + field.SetString(key.String()) + } + case reflect.Bool: + boolVal, err := key.Bool() + if err != nil { + return wrapStrictError(err, isStrict) + } + if isPtr { + field.Set(reflect.ValueOf(&boolVal)) + } else { + field.SetBool(boolVal) + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + // ParseDuration will not return err for `0`, so check the type name + if vt.Name() == "Duration" { + durationVal, err := key.Duration() + if err != nil { + if intVal, err := key.Int64(); err == nil { + field.SetInt(intVal) + return nil + } + return wrapStrictError(err, isStrict) + } + if isPtr { + field.Set(reflect.ValueOf(&durationVal)) + } else if int64(durationVal) > 0 { + field.Set(reflect.ValueOf(durationVal)) + } + return nil + } + + intVal, err := key.Int64() + if err != nil { + return wrapStrictError(err, isStrict) + } + if isPtr { + pv := reflect.New(t.Elem()) + pv.Elem().SetInt(intVal) + field.Set(pv) + } else { + field.SetInt(intVal) + } + // byte is an alias for uint8, so supporting uint8 breaks support for byte + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + durationVal, err := key.Duration() + // Skip zero value + if err == nil && uint64(durationVal) > 0 { + if isPtr { + field.Set(reflect.ValueOf(&durationVal)) + } else { + field.Set(reflect.ValueOf(durationVal)) + } + return nil + } + + uintVal, err := key.Uint64() + if err != nil { + return wrapStrictError(err, isStrict) + } + if isPtr { + pv := reflect.New(t.Elem()) + pv.Elem().SetUint(uintVal) + field.Set(pv) + } else { + field.SetUint(uintVal) + } + + case reflect.Float32, reflect.Float64: + floatVal, err := key.Float64() + if err != nil { + return wrapStrictError(err, isStrict) + } + if isPtr { + pv := reflect.New(t.Elem()) + pv.Elem().SetFloat(floatVal) + field.Set(pv) + } else { + field.SetFloat(floatVal) + } + case reflectTime: + timeVal, err := key.Time() + if err != nil { + return wrapStrictError(err, isStrict) + } + if isPtr { + field.Set(reflect.ValueOf(&timeVal)) + } else { + field.Set(reflect.ValueOf(timeVal)) + } + case reflect.Slice: + return setSliceWithProperType(key, field, delim, allowShadow, isStrict) + default: + return fmt.Errorf("unsupported type %q", t) + } + return nil +} + +func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool, allowNonUnique bool, extends bool) { + opts := strings.SplitN(tag, ",", 5) + rawName = opts[0] + for _, opt := range opts[1:] { + omitEmpty = omitEmpty || (opt == "omitempty") + allowShadow = allowShadow || (opt == "allowshadow") + allowNonUnique = allowNonUnique || (opt == "nonunique") + extends = extends || (opt == "extends") + } + return rawName, omitEmpty, allowShadow, allowNonUnique, extends +} + +// mapToField maps the given value to the matching field of the given section. +// The sectionIndex is the index (if non unique sections are enabled) to which the value should be added. +func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int, sectionName string) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + rawName, _, allowShadow, allowNonUnique, extends := parseTagOptions(tag) + fieldName := s.parseFieldName(tpField.Name, rawName) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + isStruct := tpField.Type.Kind() == reflect.Struct + isStructPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct + isAnonymousPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous + if isAnonymousPtr { + field.Set(reflect.New(tpField.Type.Elem())) + } + + if extends && (isAnonymousPtr || (isStruct && tpField.Anonymous)) { + if isStructPtr && field.IsNil() { + field.Set(reflect.New(tpField.Type.Elem())) + } + fieldSection := s + if rawName != "" { + sectionName = s.name + s.f.options.ChildSectionDelimiter + rawName + if secs, err := s.f.SectionsByName(sectionName); err == nil && sectionIndex < len(secs) { + fieldSection = secs[sectionIndex] + } + } + if err := fieldSection.mapToField(field, isStrict, sectionIndex, sectionName); err != nil { + return fmt.Errorf("map to field %q: %v", fieldName, err) + } + } else if isAnonymousPtr || isStruct || isStructPtr { + if secs, err := s.f.SectionsByName(fieldName); err == nil { + if len(secs) <= sectionIndex { + return fmt.Errorf("there are not enough sections (%d <= %d) for the field %q", len(secs), sectionIndex, fieldName) + } + // Only set the field to non-nil struct value if we have a section for it. + // Otherwise, we end up with a non-nil struct ptr even though there is no data. + if isStructPtr && field.IsNil() { + field.Set(reflect.New(tpField.Type.Elem())) + } + if err = secs[sectionIndex].mapToField(field, isStrict, sectionIndex, fieldName); err != nil { + return fmt.Errorf("map to field %q: %v", fieldName, err) + } + continue + } + } + + // Map non-unique sections + if allowNonUnique && tpField.Type.Kind() == reflect.Slice { + newField, err := s.mapToSlice(fieldName, field, isStrict) + if err != nil { + return fmt.Errorf("map to slice %q: %v", fieldName, err) + } + + field.Set(newField) + continue + } + + if key, err := s.GetKey(fieldName); err == nil { + delim := parseDelim(tpField.Tag.Get("delim")) + if err = setWithProperType(tpField.Type, key, field, delim, allowShadow, isStrict); err != nil { + return fmt.Errorf("set field %q: %v", fieldName, err) + } + } + } + return nil +} + +// mapToSlice maps all sections with the same name and returns the new value. +// The type of the Value must be a slice. +func (s *Section) mapToSlice(secName string, val reflect.Value, isStrict bool) (reflect.Value, error) { + secs, err := s.f.SectionsByName(secName) + if err != nil { + return reflect.Value{}, err + } + + typ := val.Type().Elem() + for i, sec := range secs { + elem := reflect.New(typ) + if err = sec.mapToField(elem, isStrict, i, sec.name); err != nil { + return reflect.Value{}, fmt.Errorf("map to field from section %q: %v", secName, err) + } + + val = reflect.Append(val, elem.Elem()) + } + return val, nil +} + +// mapTo maps a section to object v. +func (s *Section) mapTo(v interface{}, isStrict bool) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("not a pointer to a struct") + } + + if typ.Kind() == reflect.Slice { + newField, err := s.mapToSlice(s.name, val, isStrict) + if err != nil { + return err + } + + val.Set(newField) + return nil + } + + return s.mapToField(val, isStrict, 0, s.name) +} + +// MapTo maps section to given struct. +func (s *Section) MapTo(v interface{}) error { + return s.mapTo(v, false) +} + +// StrictMapTo maps section to given struct in strict mode, +// which returns all possible error including value parsing error. +func (s *Section) StrictMapTo(v interface{}) error { + return s.mapTo(v, true) +} + +// MapTo maps file to given struct. +func (f *File) MapTo(v interface{}) error { + return f.Section("").MapTo(v) +} + +// StrictMapTo maps file to given struct in strict mode, +// which returns all possible error including value parsing error. +func (f *File) StrictMapTo(v interface{}) error { + return f.Section("").StrictMapTo(v) +} + +// MapToWithMapper maps data sources to given struct with name mapper. +func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { + cfg, err := Load(source, others...) + if err != nil { + return err + } + cfg.NameMapper = mapper + return cfg.MapTo(v) +} + +// StrictMapToWithMapper maps data sources to given struct with name mapper in strict mode, +// which returns all possible error including value parsing error. +func StrictMapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { + cfg, err := Load(source, others...) + if err != nil { + return err + } + cfg.NameMapper = mapper + return cfg.StrictMapTo(v) +} + +// MapTo maps data sources to given struct. +func MapTo(v, source interface{}, others ...interface{}) error { + return MapToWithMapper(v, nil, source, others...) +} + +// StrictMapTo maps data sources to given struct in strict mode, +// which returns all possible error including value parsing error. +func StrictMapTo(v, source interface{}, others ...interface{}) error { + return StrictMapToWithMapper(v, nil, source, others...) +} + +// reflectSliceWithProperType does the opposite thing as setSliceWithProperType. +func reflectSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow bool) error { + slice := field.Slice(0, field.Len()) + if field.Len() == 0 { + return nil + } + sliceOf := field.Type().Elem().Kind() + + if allowShadow { + var keyWithShadows *Key + for i := 0; i < field.Len(); i++ { + var val string + switch sliceOf { + case reflect.String: + val = slice.Index(i).String() + case reflect.Int, reflect.Int64: + val = fmt.Sprint(slice.Index(i).Int()) + case reflect.Uint, reflect.Uint64: + val = fmt.Sprint(slice.Index(i).Uint()) + case reflect.Float64: + val = fmt.Sprint(slice.Index(i).Float()) + case reflect.Bool: + val = fmt.Sprint(slice.Index(i).Bool()) + case reflectTime: + val = slice.Index(i).Interface().(time.Time).Format(time.RFC3339) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + + if i == 0 { + keyWithShadows = newKey(key.s, key.name, val) + } else { + _ = keyWithShadows.AddShadow(val) + } + } + *key = *keyWithShadows + return nil + } + + var buf bytes.Buffer + for i := 0; i < field.Len(); i++ { + switch sliceOf { + case reflect.String: + buf.WriteString(slice.Index(i).String()) + case reflect.Int, reflect.Int64: + buf.WriteString(fmt.Sprint(slice.Index(i).Int())) + case reflect.Uint, reflect.Uint64: + buf.WriteString(fmt.Sprint(slice.Index(i).Uint())) + case reflect.Float64: + buf.WriteString(fmt.Sprint(slice.Index(i).Float())) + case reflect.Bool: + buf.WriteString(fmt.Sprint(slice.Index(i).Bool())) + case reflectTime: + buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339)) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + buf.WriteString(delim) + } + key.SetValue(buf.String()[:buf.Len()-len(delim)]) + return nil +} + +// reflectWithProperType does the opposite thing as setWithProperType. +func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow bool) error { + switch t.Kind() { + case reflect.String: + key.SetValue(field.String()) + case reflect.Bool: + key.SetValue(fmt.Sprint(field.Bool())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + key.SetValue(fmt.Sprint(field.Int())) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + key.SetValue(fmt.Sprint(field.Uint())) + case reflect.Float32, reflect.Float64: + key.SetValue(fmt.Sprint(field.Float())) + case reflectTime: + key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339))) + case reflect.Slice: + return reflectSliceWithProperType(key, field, delim, allowShadow) + case reflect.Ptr: + if !field.IsNil() { + return reflectWithProperType(t.Elem(), key, field.Elem(), delim, allowShadow) + } + default: + return fmt.Errorf("unsupported type %q", t) + } + return nil +} + +// CR: copied from encoding/json/encode.go with modifications of time.Time support. +// TODO: add more test coverage. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflectTime: + t, ok := v.Interface().(time.Time) + return ok && t.IsZero() + } + return false +} + +// StructReflector is the interface implemented by struct types that can extract themselves into INI objects. +type StructReflector interface { + ReflectINIStruct(*File) error +} + +func (s *Section) reflectFrom(val reflect.Value) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + if !val.Field(i).CanInterface() { + continue + } + + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + rawName, omitEmpty, allowShadow, allowNonUnique, extends := parseTagOptions(tag) + if omitEmpty && isEmptyValue(field) { + continue + } + + if r, ok := field.Interface().(StructReflector); ok { + return r.ReflectINIStruct(s.f) + } + + fieldName := s.parseFieldName(tpField.Name, rawName) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + if extends && tpField.Anonymous && (tpField.Type.Kind() == reflect.Ptr || tpField.Type.Kind() == reflect.Struct) { + if err := s.reflectFrom(field); err != nil { + return fmt.Errorf("reflect from field %q: %v", fieldName, err) + } + continue + } + + if (tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct) || + (tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") { + // Note: The only error here is section doesn't exist. + sec, err := s.f.GetSection(fieldName) + if err != nil { + // Note: fieldName can never be empty here, ignore error. + sec, _ = s.f.NewSection(fieldName) + } + + // Add comment from comment tag + if len(sec.Comment) == 0 { + sec.Comment = tpField.Tag.Get("comment") + } + + if err = sec.reflectFrom(field); err != nil { + return fmt.Errorf("reflect from field %q: %v", fieldName, err) + } + continue + } + + if allowNonUnique && tpField.Type.Kind() == reflect.Slice { + slice := field.Slice(0, field.Len()) + if field.Len() == 0 { + return nil + } + sliceOf := field.Type().Elem().Kind() + + for i := 0; i < field.Len(); i++ { + if sliceOf != reflect.Struct && sliceOf != reflect.Ptr { + return fmt.Errorf("field %q is not a slice of pointer or struct", fieldName) + } + + sec, err := s.f.NewSection(fieldName) + if err != nil { + return err + } + + // Add comment from comment tag + if len(sec.Comment) == 0 { + sec.Comment = tpField.Tag.Get("comment") + } + + if err := sec.reflectFrom(slice.Index(i)); err != nil { + return fmt.Errorf("reflect from field %q: %v", fieldName, err) + } + } + continue + } + + // Note: Same reason as section. + key, err := s.GetKey(fieldName) + if err != nil { + key, _ = s.NewKey(fieldName, "") + } + + // Add comment from comment tag + if len(key.Comment) == 0 { + key.Comment = tpField.Tag.Get("comment") + } + + delim := parseDelim(tpField.Tag.Get("delim")) + if err = reflectWithProperType(tpField.Type, key, field, delim, allowShadow); err != nil { + return fmt.Errorf("reflect field %q: %v", fieldName, err) + } + + } + return nil +} + +// ReflectFrom reflects section from given struct. It overwrites existing ones. +func (s *Section) ReflectFrom(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + + if s.name != DefaultSection && s.f.options.AllowNonUniqueSections && + (typ.Kind() == reflect.Slice || typ.Kind() == reflect.Ptr) { + // Clear sections to make sure none exists before adding the new ones + s.f.DeleteSection(s.name) + + if typ.Kind() == reflect.Ptr { + sec, err := s.f.NewSection(s.name) + if err != nil { + return err + } + return sec.reflectFrom(val.Elem()) + } + + slice := val.Slice(0, val.Len()) + sliceOf := val.Type().Elem().Kind() + if sliceOf != reflect.Ptr { + return fmt.Errorf("not a slice of pointers") + } + + for i := 0; i < slice.Len(); i++ { + sec, err := s.f.NewSection(s.name) + if err != nil { + return err + } + + err = sec.reflectFrom(slice.Index(i)) + if err != nil { + return fmt.Errorf("reflect from %dth field: %v", i, err) + } + } + + return nil + } + + if typ.Kind() == reflect.Ptr { + val = val.Elem() + } else { + return errors.New("not a pointer to a struct") + } + + return s.reflectFrom(val) +} + +// ReflectFrom reflects file from given struct. +func (f *File) ReflectFrom(v interface{}) error { + return f.Section("").ReflectFrom(v) +} + +// ReflectFromWithMapper reflects data sources from given struct with name mapper. +func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error { + cfg.NameMapper = mapper + return cfg.ReflectFrom(v) +} + +// ReflectFrom reflects data sources from given struct. +func ReflectFrom(cfg *File, v interface{}) error { + return ReflectFromWithMapper(cfg, v, nil) +} diff --git a/vendor/github.com/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml index 94ff801df1a..0cffafa7bf9 100644 --- a/vendor/github.com/go-logr/logr/.golangci.yaml +++ b/vendor/github.com/go-logr/logr/.golangci.yaml @@ -6,7 +6,6 @@ linters: disable-all: true enable: - asciicheck - - deadcode - errcheck - forcetypeassert - gocritic @@ -18,10 +17,8 @@ linters: - misspell - revive - staticcheck - - structcheck - typecheck - unused - - varcheck issues: exclude-use-default: false diff --git a/vendor/github.com/go-logr/logr/discard.go b/vendor/github.com/go-logr/logr/discard.go index 9d92a38f1d7..99fe8be93c1 100644 --- a/vendor/github.com/go-logr/logr/discard.go +++ b/vendor/github.com/go-logr/logr/discard.go @@ -20,35 +20,5 @@ package logr // used whenever the caller is not interested in the logs. Logger instances // produced by this function always compare as equal. func Discard() Logger { - return Logger{ - level: 0, - sink: discardLogSink{}, - } -} - -// discardLogSink is a LogSink that discards all messages. -type discardLogSink struct{} - -// Verify that it actually implements the interface -var _ LogSink = discardLogSink{} - -func (l discardLogSink) Init(RuntimeInfo) { -} - -func (l discardLogSink) Enabled(int) bool { - return false -} - -func (l discardLogSink) Info(int, string, ...interface{}) { -} - -func (l discardLogSink) Error(error, string, ...interface{}) { -} - -func (l discardLogSink) WithValues(...interface{}) LogSink { - return l -} - -func (l discardLogSink) WithName(string) LogSink { - return l + return New(nil) } diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go new file mode 100644 index 00000000000..e52f0cd01e2 --- /dev/null +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -0,0 +1,804 @@ +/* +Copyright 2021 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package funcr implements formatting of structured log messages and +// optionally captures the call site and timestamp. +// +// The simplest way to use it is via its implementation of a +// github.com/go-logr/logr.LogSink with output through an arbitrary +// "write" function. See New and NewJSON for details. +// +// # Custom LogSinks +// +// For users who need more control, a funcr.Formatter can be embedded inside +// your own custom LogSink implementation. This is useful when the LogSink +// needs to implement additional methods, for example. +// +// # Formatting +// +// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for +// values which are being logged. When rendering a struct, funcr will use Go's +// standard JSON tags (all except "string"). +package funcr + +import ( + "bytes" + "encoding" + "encoding/json" + "fmt" + "path/filepath" + "reflect" + "runtime" + "strconv" + "strings" + "time" + + "github.com/go-logr/logr" +) + +// New returns a logr.Logger which is implemented by an arbitrary function. +func New(fn func(prefix, args string), opts Options) logr.Logger { + return logr.New(newSink(fn, NewFormatter(opts))) +} + +// NewJSON returns a logr.Logger which is implemented by an arbitrary function +// and produces JSON output. +func NewJSON(fn func(obj string), opts Options) logr.Logger { + fnWrapper := func(_, obj string) { + fn(obj) + } + return logr.New(newSink(fnWrapper, NewFormatterJSON(opts))) +} + +// Underlier exposes access to the underlying logging function. Since +// callers only have a logr.Logger, they have to know which +// implementation is in use, so this interface is less of an +// abstraction and more of a way to test type conversion. +type Underlier interface { + GetUnderlying() func(prefix, args string) +} + +func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink { + l := &fnlogger{ + Formatter: formatter, + write: fn, + } + // For skipping fnlogger.Info and fnlogger.Error. + l.Formatter.AddCallDepth(1) + return l +} + +// Options carries parameters which influence the way logs are generated. +type Options struct { + // LogCaller tells funcr to add a "caller" key to some or all log lines. + // This has some overhead, so some users might not want it. + LogCaller MessageClass + + // LogCallerFunc tells funcr to also log the calling function name. This + // has no effect if caller logging is not enabled (see Options.LogCaller). + LogCallerFunc bool + + // LogTimestamp tells funcr to add a "ts" key to log lines. This has some + // overhead, so some users might not want it. + LogTimestamp bool + + // TimestampFormat tells funcr how to render timestamps when LogTimestamp + // is enabled. If not specified, a default format will be used. For more + // details, see docs for Go's time.Layout. + TimestampFormat string + + // Verbosity tells funcr which V logs to produce. Higher values enable + // more logs. Info logs at or below this level will be written, while logs + // above this level will be discarded. + Verbosity int + + // RenderBuiltinsHook allows users to mutate the list of key-value pairs + // while a log line is being rendered. The kvList argument follows logr + // conventions - each pair of slice elements is comprised of a string key + // and an arbitrary value (verified and sanitized before calling this + // hook). The value returned must follow the same conventions. This hook + // can be used to audit or modify logged data. For example, you might want + // to prefix all of funcr's built-in keys with some string. This hook is + // only called for built-in (provided by funcr itself) key-value pairs. + // Equivalent hooks are offered for key-value pairs saved via + // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and + // for user-provided pairs (see RenderArgsHook). + RenderBuiltinsHook func(kvList []interface{}) []interface{} + + // RenderValuesHook is the same as RenderBuiltinsHook, except that it is + // only called for key-value pairs saved via logr.Logger.WithValues. See + // RenderBuiltinsHook for more details. + RenderValuesHook func(kvList []interface{}) []interface{} + + // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only + // called for key-value pairs passed directly to Info and Error. See + // RenderBuiltinsHook for more details. + RenderArgsHook func(kvList []interface{}) []interface{} + + // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct + // that contains a struct, etc.) it may log. Every time it finds a struct, + // slice, array, or map the depth is increased by one. When the maximum is + // reached, the value will be converted to a string indicating that the max + // depth has been exceeded. If this field is not specified, a default + // value will be used. + MaxLogDepth int +} + +// MessageClass indicates which category or categories of messages to consider. +type MessageClass int + +const ( + // None ignores all message classes. + None MessageClass = iota + // All considers all message classes. + All + // Info only considers info messages. + Info + // Error only considers error messages. + Error +) + +// fnlogger inherits some of its LogSink implementation from Formatter +// and just needs to add some glue code. +type fnlogger struct { + Formatter + write func(prefix, args string) +} + +func (l fnlogger) WithName(name string) logr.LogSink { + l.Formatter.AddName(name) + return &l +} + +func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { + l.Formatter.AddValues(kvList) + return &l +} + +func (l fnlogger) WithCallDepth(depth int) logr.LogSink { + l.Formatter.AddCallDepth(depth) + return &l +} + +func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { + prefix, args := l.FormatInfo(level, msg, kvList) + l.write(prefix, args) +} + +func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { + prefix, args := l.FormatError(err, msg, kvList) + l.write(prefix, args) +} + +func (l fnlogger) GetUnderlying() func(prefix, args string) { + return l.write +} + +// Assert conformance to the interfaces. +var _ logr.LogSink = &fnlogger{} +var _ logr.CallDepthLogSink = &fnlogger{} +var _ Underlier = &fnlogger{} + +// NewFormatter constructs a Formatter which emits a JSON-like key=value format. +func NewFormatter(opts Options) Formatter { + return newFormatter(opts, outputKeyValue) +} + +// NewFormatterJSON constructs a Formatter which emits strict JSON. +func NewFormatterJSON(opts Options) Formatter { + return newFormatter(opts, outputJSON) +} + +// Defaults for Options. +const defaultTimestampFormat = "2006-01-02 15:04:05.000000" +const defaultMaxLogDepth = 16 + +func newFormatter(opts Options, outfmt outputFormat) Formatter { + if opts.TimestampFormat == "" { + opts.TimestampFormat = defaultTimestampFormat + } + if opts.MaxLogDepth == 0 { + opts.MaxLogDepth = defaultMaxLogDepth + } + f := Formatter{ + outputFormat: outfmt, + prefix: "", + values: nil, + depth: 0, + opts: &opts, + } + return f +} + +// Formatter is an opaque struct which can be embedded in a LogSink +// implementation. It should be constructed with NewFormatter. Some of +// its methods directly implement logr.LogSink. +type Formatter struct { + outputFormat outputFormat + prefix string + values []interface{} + valuesStr string + depth int + opts *Options +} + +// outputFormat indicates which outputFormat to use. +type outputFormat int + +const ( + // outputKeyValue emits a JSON-like key=value format, but not strict JSON. + outputKeyValue outputFormat = iota + // outputJSON emits strict JSON. + outputJSON +) + +// PseudoStruct is a list of key-value pairs that gets logged as a struct. +type PseudoStruct []interface{} + +// render produces a log line, ready to use. +func (f Formatter) render(builtins, args []interface{}) string { + // Empirically bytes.Buffer is faster than strings.Builder for this. + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + if f.outputFormat == outputJSON { + buf.WriteByte('{') + } + vals := builtins + if hook := f.opts.RenderBuiltinsHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + f.flatten(buf, vals, false, false) // keys are ours, no need to escape + continuing := len(builtins) > 0 + if len(f.valuesStr) > 0 { + if continuing { + if f.outputFormat == outputJSON { + buf.WriteByte(',') + } else { + buf.WriteByte(' ') + } + } + continuing = true + buf.WriteString(f.valuesStr) + } + vals = args + if hook := f.opts.RenderArgsHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + f.flatten(buf, vals, continuing, true) // escape user-provided keys + if f.outputFormat == outputJSON { + buf.WriteByte('}') + } + return buf.String() +} + +// flatten renders a list of key-value pairs into a buffer. If continuing is +// true, it assumes that the buffer has previous values and will emit a +// separator (which depends on the output format) before the first pair it +// writes. If escapeKeys is true, the keys are assumed to have +// non-JSON-compatible characters in them and must be evaluated for escapes. +// +// This function returns a potentially modified version of kvList, which +// ensures that there is a value for every key (adding a value if needed) and +// that each key is a string (substituting a key if needed). +func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { + // This logic overlaps with sanitize() but saves one type-cast per key, + // which can be measurable. + if len(kvList)%2 != 0 { + kvList = append(kvList, noValue) + } + for i := 0; i < len(kvList); i += 2 { + k, ok := kvList[i].(string) + if !ok { + k = f.nonStringKey(kvList[i]) + kvList[i] = k + } + v := kvList[i+1] + + if i > 0 || continuing { + if f.outputFormat == outputJSON { + buf.WriteByte(',') + } else { + // In theory the format could be something we don't understand. In + // practice, we control it, so it won't be. + buf.WriteByte(' ') + } + } + + if escapeKeys { + buf.WriteString(prettyString(k)) + } else { + // this is faster + buf.WriteByte('"') + buf.WriteString(k) + buf.WriteByte('"') + } + if f.outputFormat == outputJSON { + buf.WriteByte(':') + } else { + buf.WriteByte('=') + } + buf.WriteString(f.pretty(v)) + } + return kvList +} + +func (f Formatter) pretty(value interface{}) string { + return f.prettyWithFlags(value, 0, 0) +} + +const ( + flagRawStruct = 0x1 // do not print braces on structs +) + +// TODO: This is not fast. Most of the overhead goes here. +func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { + if depth > f.opts.MaxLogDepth { + return `""` + } + + // Handle types that take full control of logging. + if v, ok := value.(logr.Marshaler); ok { + // Replace the value with what the type wants to get logged. + // That then gets handled below via reflection. + value = invokeMarshaler(v) + } + + // Handle types that want to format themselves. + switch v := value.(type) { + case fmt.Stringer: + value = invokeStringer(v) + case error: + value = invokeError(v) + } + + // Handling the most common types without reflect is a small perf win. + switch v := value.(type) { + case bool: + return strconv.FormatBool(v) + case string: + return prettyString(v) + case int: + return strconv.FormatInt(int64(v), 10) + case int8: + return strconv.FormatInt(int64(v), 10) + case int16: + return strconv.FormatInt(int64(v), 10) + case int32: + return strconv.FormatInt(int64(v), 10) + case int64: + return strconv.FormatInt(int64(v), 10) + case uint: + return strconv.FormatUint(uint64(v), 10) + case uint8: + return strconv.FormatUint(uint64(v), 10) + case uint16: + return strconv.FormatUint(uint64(v), 10) + case uint32: + return strconv.FormatUint(uint64(v), 10) + case uint64: + return strconv.FormatUint(v, 10) + case uintptr: + return strconv.FormatUint(uint64(v), 10) + case float32: + return strconv.FormatFloat(float64(v), 'f', -1, 32) + case float64: + return strconv.FormatFloat(v, 'f', -1, 64) + case complex64: + return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"` + case complex128: + return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"` + case PseudoStruct: + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + v = f.sanitize(v) + if flags&flagRawStruct == 0 { + buf.WriteByte('{') + } + for i := 0; i < len(v); i += 2 { + if i > 0 { + buf.WriteByte(',') + } + k, _ := v[i].(string) // sanitize() above means no need to check success + // arbitrary keys might need escaping + buf.WriteString(prettyString(k)) + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1)) + } + if flags&flagRawStruct == 0 { + buf.WriteByte('}') + } + return buf.String() + } + + buf := bytes.NewBuffer(make([]byte, 0, 256)) + t := reflect.TypeOf(value) + if t == nil { + return "null" + } + v := reflect.ValueOf(value) + switch t.Kind() { + case reflect.Bool: + return strconv.FormatBool(v.Bool()) + case reflect.String: + return prettyString(v.String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(int64(v.Int()), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(uint64(v.Uint()), 10) + case reflect.Float32: + return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32) + case reflect.Float64: + return strconv.FormatFloat(v.Float(), 'f', -1, 64) + case reflect.Complex64: + return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"` + case reflect.Complex128: + return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"` + case reflect.Struct: + if flags&flagRawStruct == 0 { + buf.WriteByte('{') + } + printComma := false // testing i>0 is not enough because of JSON omitted fields + for i := 0; i < t.NumField(); i++ { + fld := t.Field(i) + if fld.PkgPath != "" { + // reflect says this field is only defined for non-exported fields. + continue + } + if !v.Field(i).CanInterface() { + // reflect isn't clear exactly what this means, but we can't use it. + continue + } + name := "" + omitempty := false + if tag, found := fld.Tag.Lookup("json"); found { + if tag == "-" { + continue + } + if comma := strings.Index(tag, ","); comma != -1 { + if n := tag[:comma]; n != "" { + name = n + } + rest := tag[comma:] + if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") { + omitempty = true + } + } else { + name = tag + } + } + if omitempty && isEmpty(v.Field(i)) { + continue + } + if printComma { + buf.WriteByte(',') + } + printComma = true // if we got here, we are rendering a field + if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" { + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1)) + continue + } + if name == "" { + name = fld.Name + } + // field names can't contain characters which need escaping + buf.WriteByte('"') + buf.WriteString(name) + buf.WriteByte('"') + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1)) + } + if flags&flagRawStruct == 0 { + buf.WriteByte('}') + } + return buf.String() + case reflect.Slice, reflect.Array: + // If this is outputing as JSON make sure this isn't really a json.RawMessage. + // If so just emit "as-is" and don't pretty it as that will just print + // it as [X,Y,Z,...] which isn't terribly useful vs the string form you really want. + if f.outputFormat == outputJSON { + if rm, ok := value.(json.RawMessage); ok { + // If it's empty make sure we emit an empty value as the array style would below. + if len(rm) > 0 { + buf.Write(rm) + } else { + buf.WriteString("null") + } + return buf.String() + } + } + buf.WriteByte('[') + for i := 0; i < v.Len(); i++ { + if i > 0 { + buf.WriteByte(',') + } + e := v.Index(i) + buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1)) + } + buf.WriteByte(']') + return buf.String() + case reflect.Map: + buf.WriteByte('{') + // This does not sort the map keys, for best perf. + it := v.MapRange() + i := 0 + for it.Next() { + if i > 0 { + buf.WriteByte(',') + } + // If a map key supports TextMarshaler, use it. + keystr := "" + if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok { + txt, err := m.MarshalText() + if err != nil { + keystr = fmt.Sprintf("", err.Error()) + } else { + keystr = string(txt) + } + keystr = prettyString(keystr) + } else { + // prettyWithFlags will produce already-escaped values + keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1) + if t.Key().Kind() != reflect.String { + // JSON only does string keys. Unlike Go's standard JSON, we'll + // convert just about anything to a string. + keystr = prettyString(keystr) + } + } + buf.WriteString(keystr) + buf.WriteByte(':') + buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1)) + i++ + } + buf.WriteByte('}') + return buf.String() + case reflect.Ptr, reflect.Interface: + if v.IsNil() { + return "null" + } + return f.prettyWithFlags(v.Elem().Interface(), 0, depth) + } + return fmt.Sprintf(`""`, t.Kind().String()) +} + +func prettyString(s string) string { + // Avoid escaping (which does allocations) if we can. + if needsEscape(s) { + return strconv.Quote(s) + } + b := bytes.NewBuffer(make([]byte, 0, 1024)) + b.WriteByte('"') + b.WriteString(s) + b.WriteByte('"') + return b.String() +} + +// needsEscape determines whether the input string needs to be escaped or not, +// without doing any allocations. +func needsEscape(s string) bool { + for _, r := range s { + if !strconv.IsPrint(r) || r == '\\' || r == '"' { + return true + } + } + return false +} + +func isEmpty(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Complex64, reflect.Complex128: + return v.Complex() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} + +func invokeMarshaler(m logr.Marshaler) (ret interface{}) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return m.MarshalLog() +} + +func invokeStringer(s fmt.Stringer) (ret string) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return s.String() +} + +func invokeError(e error) (ret string) { + defer func() { + if r := recover(); r != nil { + ret = fmt.Sprintf("", r) + } + }() + return e.Error() +} + +// Caller represents the original call site for a log line, after considering +// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and +// Line fields will always be provided, while the Func field is optional. +// Users can set the render hook fields in Options to examine logged key-value +// pairs, one of which will be {"caller", Caller} if the Options.LogCaller +// field is enabled for the given MessageClass. +type Caller struct { + // File is the basename of the file for this call site. + File string `json:"file"` + // Line is the line number in the file for this call site. + Line int `json:"line"` + // Func is the function name for this call site, or empty if + // Options.LogCallerFunc is not enabled. + Func string `json:"function,omitempty"` +} + +func (f Formatter) caller() Caller { + // +1 for this frame, +1 for Info/Error. + pc, file, line, ok := runtime.Caller(f.depth + 2) + if !ok { + return Caller{"", 0, ""} + } + fn := "" + if f.opts.LogCallerFunc { + if fp := runtime.FuncForPC(pc); fp != nil { + fn = fp.Name() + } + } + + return Caller{filepath.Base(file), line, fn} +} + +const noValue = "" + +func (f Formatter) nonStringKey(v interface{}) string { + return fmt.Sprintf("", f.snippet(v)) +} + +// snippet produces a short snippet string of an arbitrary value. +func (f Formatter) snippet(v interface{}) string { + const snipLen = 16 + + snip := f.pretty(v) + if len(snip) > snipLen { + snip = snip[:snipLen] + } + return snip +} + +// sanitize ensures that a list of key-value pairs has a value for every key +// (adding a value if needed) and that each key is a string (substituting a key +// if needed). +func (f Formatter) sanitize(kvList []interface{}) []interface{} { + if len(kvList)%2 != 0 { + kvList = append(kvList, noValue) + } + for i := 0; i < len(kvList); i += 2 { + _, ok := kvList[i].(string) + if !ok { + kvList[i] = f.nonStringKey(kvList[i]) + } + } + return kvList +} + +// Init configures this Formatter from runtime info, such as the call depth +// imposed by logr itself. +// Note that this receiver is a pointer, so depth can be saved. +func (f *Formatter) Init(info logr.RuntimeInfo) { + f.depth += info.CallDepth +} + +// Enabled checks whether an info message at the given level should be logged. +func (f Formatter) Enabled(level int) bool { + return level <= f.opts.Verbosity +} + +// GetDepth returns the current depth of this Formatter. This is useful for +// implementations which do their own caller attribution. +func (f Formatter) GetDepth() int { + return f.depth +} + +// FormatInfo renders an Info log message into strings. The prefix will be +// empty when no names were set (via AddNames), or when the output is +// configured for JSON. +func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { + args := make([]interface{}, 0, 64) // using a constant here impacts perf + prefix = f.prefix + if f.outputFormat == outputJSON { + args = append(args, "logger", prefix) + prefix = "" + } + if f.opts.LogTimestamp { + args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) + } + if policy := f.opts.LogCaller; policy == All || policy == Info { + args = append(args, "caller", f.caller()) + } + args = append(args, "level", level, "msg", msg) + return prefix, f.render(args, kvList) +} + +// FormatError renders an Error log message into strings. The prefix will be +// empty when no names were set (via AddNames), or when the output is +// configured for JSON. +func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { + args := make([]interface{}, 0, 64) // using a constant here impacts perf + prefix = f.prefix + if f.outputFormat == outputJSON { + args = append(args, "logger", prefix) + prefix = "" + } + if f.opts.LogTimestamp { + args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat)) + } + if policy := f.opts.LogCaller; policy == All || policy == Error { + args = append(args, "caller", f.caller()) + } + args = append(args, "msg", msg) + var loggableErr interface{} + if err != nil { + loggableErr = err.Error() + } + args = append(args, "error", loggableErr) + return f.prefix, f.render(args, kvList) +} + +// AddName appends the specified name. funcr uses '/' characters to separate +// name elements. Callers should not pass '/' in the provided name string, but +// this library does not actually enforce that. +func (f *Formatter) AddName(name string) { + if len(f.prefix) > 0 { + f.prefix += "/" + } + f.prefix += name +} + +// AddValues adds key-value pairs to the set of saved values to be logged with +// each log line. +func (f *Formatter) AddValues(kvList []interface{}) { + // Three slice args forces a copy. + n := len(f.values) + f.values = append(f.values[:n:n], kvList...) + + vals := f.values + if hook := f.opts.RenderValuesHook; hook != nil { + vals = hook(f.sanitize(vals)) + } + + // Pre-render values, so we don't have to do it on each Info/Error call. + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + f.flatten(buf, vals, false, true) // escape user-provided keys + f.valuesStr = buf.String() +} + +// AddCallDepth increases the number of stack-frames to skip when attributing +// the log line to a file and line. +func (f *Formatter) AddCallDepth(depth int) { + f.depth += depth +} diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index c3b56b3d2c5..e027aea3fd3 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -21,7 +21,7 @@ limitations under the License. // to back that API. Packages in the Go ecosystem can depend on this package, // while callers can implement logging with whatever backend is appropriate. // -// Usage +// # Usage // // Logging is done using a Logger instance. Logger is a concrete type with // methods, which defers the actual logging to a LogSink interface. The main @@ -30,16 +30,20 @@ limitations under the License. // "structured logging". // // With Go's standard log package, we might write: -// log.Printf("setting target value %s", targetValue) +// +// log.Printf("setting target value %s", targetValue) // // With logr's structured logging, we'd write: -// logger.Info("setting target", "value", targetValue) +// +// logger.Info("setting target", "value", targetValue) // // Errors are much the same. Instead of: -// log.Printf("failed to open the pod bay door for user %s: %v", user, err) +// +// log.Printf("failed to open the pod bay door for user %s: %v", user, err) // // We'd write: -// logger.Error(err, "failed to open the pod bay door", "user", user) +// +// logger.Error(err, "failed to open the pod bay door", "user", user) // // Info() and Error() are very similar, but they are separate methods so that // LogSink implementations can choose to do things like attach additional @@ -47,7 +51,7 @@ limitations under the License. // always logged, regardless of the current verbosity. If there is no error // instance available, passing nil is valid. // -// Verbosity +// # Verbosity // // Often we want to log information only when the application in "verbose // mode". To write log lines that are more verbose, Logger has a V() method. @@ -58,20 +62,22 @@ limitations under the License. // Error messages do not have a verbosity level and are always logged. // // Where we might have written: -// if flVerbose >= 2 { -// log.Printf("an unusual thing happened") -// } +// +// if flVerbose >= 2 { +// log.Printf("an unusual thing happened") +// } // // We can write: -// logger.V(2).Info("an unusual thing happened") // -// Logger Names +// logger.V(2).Info("an unusual thing happened") +// +// # Logger Names // // Logger instances can have name strings so that all messages logged through // that instance have additional context. For example, you might want to add // a subsystem name: // -// logger.WithName("compactor").Info("started", "time", time.Now()) +// logger.WithName("compactor").Info("started", "time", time.Now()) // // The WithName() method returns a new Logger, which can be passed to // constructors or other functions for further use. Repeated use of WithName() @@ -82,25 +88,27 @@ limitations under the License. // joining operation (e.g. whitespace, commas, periods, slashes, brackets, // quotes, etc). // -// Saved Values +// # Saved Values // // Logger instances can store any number of key/value pairs, which will be // logged alongside all messages logged through that instance. For example, // you might want to create a Logger instance per managed object: // // With the standard log package, we might write: -// log.Printf("decided to set field foo to value %q for object %s/%s", -// targetValue, object.Namespace, object.Name) +// +// log.Printf("decided to set field foo to value %q for object %s/%s", +// targetValue, object.Namespace, object.Name) // // With logr we'd write: -// // Elsewhere: set up the logger to log the object name. -// obj.logger = mainLogger.WithValues( -// "name", obj.name, "namespace", obj.namespace) // -// // later on... -// obj.logger.Info("setting foo", "value", targetValue) +// // Elsewhere: set up the logger to log the object name. +// obj.logger = mainLogger.WithValues( +// "name", obj.name, "namespace", obj.namespace) +// +// // later on... +// obj.logger.Info("setting foo", "value", targetValue) // -// Best Practices +// # Best Practices // // Logger has very few hard rules, with the goal that LogSink implementations // might have a lot of freedom to differentiate. There are, however, some @@ -124,15 +132,15 @@ limitations under the License. // around. For cases where passing a logger is optional, a pointer to Logger // should be used. // -// Key Naming Conventions +// # Key Naming Conventions // // Keys are not strictly required to conform to any specification or regex, but // it is recommended that they: -// * be human-readable and meaningful (not auto-generated or simple ordinals) -// * be constant (not dependent on input data) -// * contain only printable characters -// * not contain whitespace or punctuation -// * use lower case for simple keys and lowerCamelCase for more complex ones +// - be human-readable and meaningful (not auto-generated or simple ordinals) +// - be constant (not dependent on input data) +// - contain only printable characters +// - not contain whitespace or punctuation +// - use lower case for simple keys and lowerCamelCase for more complex ones // // These guidelines help ensure that log data is processed properly regardless // of the log implementation. For example, log implementations will try to @@ -141,51 +149,54 @@ limitations under the License. // While users are generally free to use key names of their choice, it's // generally best to avoid using the following keys, as they're frequently used // by implementations: -// * "caller": the calling information (file/line) of a particular log line -// * "error": the underlying error value in the `Error` method -// * "level": the log level -// * "logger": the name of the associated logger -// * "msg": the log message -// * "stacktrace": the stack trace associated with a particular log line or -// error (often from the `Error` message) -// * "ts": the timestamp for a log line +// - "caller": the calling information (file/line) of a particular log line +// - "error": the underlying error value in the `Error` method +// - "level": the log level +// - "logger": the name of the associated logger +// - "msg": the log message +// - "stacktrace": the stack trace associated with a particular log line or +// error (often from the `Error` message) +// - "ts": the timestamp for a log line // // Implementations are encouraged to make use of these keys to represent the // above concepts, when necessary (for example, in a pure-JSON output form, it // would be necessary to represent at least message and timestamp as ordinary // named values). // -// Break Glass +// # Break Glass // // Implementations may choose to give callers access to the underlying // logging implementation. The recommended pattern for this is: -// // Underlier exposes access to the underlying logging implementation. -// // Since callers only have a logr.Logger, they have to know which -// // implementation is in use, so this interface is less of an abstraction -// // and more of way to test type conversion. -// type Underlier interface { -// GetUnderlying() -// } +// +// // Underlier exposes access to the underlying logging implementation. +// // Since callers only have a logr.Logger, they have to know which +// // implementation is in use, so this interface is less of an abstraction +// // and more of way to test type conversion. +// type Underlier interface { +// GetUnderlying() +// } // // Logger grants access to the sink to enable type assertions like this: -// func DoSomethingWithImpl(log logr.Logger) { -// if underlier, ok := log.GetSink()(impl.Underlier) { -// implLogger := underlier.GetUnderlying() -// ... -// } -// } +// +// func DoSomethingWithImpl(log logr.Logger) { +// if underlier, ok := log.GetSink().(impl.Underlier); ok { +// implLogger := underlier.GetUnderlying() +// ... +// } +// } // // Custom `With*` functions can be implemented by copying the complete // Logger struct and replacing the sink in the copy: -// // WithFooBar changes the foobar parameter in the log sink and returns a -// // new logger with that modified sink. It does nothing for loggers where -// // the sink doesn't support that parameter. -// func WithFoobar(log logr.Logger, foobar int) logr.Logger { -// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok { -// log = log.WithSink(foobarLogSink.WithFooBar(foobar)) -// } -// return log -// } +// +// // WithFooBar changes the foobar parameter in the log sink and returns a +// // new logger with that modified sink. It does nothing for loggers where +// // the sink doesn't support that parameter. +// func WithFoobar(log logr.Logger, foobar int) logr.Logger { +// if foobarLogSink, ok := log.GetSink().(FoobarSink); ok { +// log = log.WithSink(foobarLogSink.WithFooBar(foobar)) +// } +// return log +// } // // Don't use New to construct a new Logger with a LogSink retrieved from an // existing Logger. Source code attribution might not work correctly and @@ -201,11 +212,14 @@ import ( ) // New returns a new Logger instance. This is primarily used by libraries -// implementing LogSink, rather than end users. +// implementing LogSink, rather than end users. Passing a nil sink will create +// a Logger which discards all log lines. func New(sink LogSink) Logger { logger := Logger{} logger.setSink(sink) - sink.Init(runtimeInfo) + if sink != nil { + sink.Init(runtimeInfo) + } return logger } @@ -244,7 +258,7 @@ type Logger struct { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info logs. func (l Logger) Enabled() bool { - return l.sink.Enabled(l.level) + return l.sink != nil && l.sink.Enabled(l.level) } // Info logs a non-error message with the given key/value pairs as context. @@ -254,6 +268,9 @@ func (l Logger) Enabled() bool { // information. The key/value pairs must alternate string keys and arbitrary // values. func (l Logger) Info(msg string, keysAndValues ...interface{}) { + if l.sink == nil { + return + } if l.Enabled() { if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() @@ -273,6 +290,9 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) { // triggered this log line, if present. The err parameter is optional // and nil may be passed instead of an error instance. func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { + if l.sink == nil { + return + } if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() } @@ -284,6 +304,9 @@ func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { // level means a log message is less important. Negative V-levels are treated // as 0. func (l Logger) V(level int) Logger { + if l.sink == nil { + return l + } if level < 0 { level = 0 } @@ -294,6 +317,9 @@ func (l Logger) V(level int) Logger { // WithValues returns a new Logger instance with additional key/value pairs. // See Info for documentation on how key/value pairs work. func (l Logger) WithValues(keysAndValues ...interface{}) Logger { + if l.sink == nil { + return l + } l.setSink(l.sink.WithValues(keysAndValues...)) return l } @@ -304,6 +330,9 @@ func (l Logger) WithValues(keysAndValues ...interface{}) Logger { // contain only letters, digits, and hyphens (see the package documentation for // more information). func (l Logger) WithName(name string) Logger { + if l.sink == nil { + return l + } l.setSink(l.sink.WithName(name)) return l } @@ -324,6 +353,9 @@ func (l Logger) WithName(name string) Logger { // WithCallDepth(1) because it works with implementions that support the // CallDepthLogSink and/or CallStackHelperLogSink interfaces. func (l Logger) WithCallDepth(depth int) Logger { + if l.sink == nil { + return l + } if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { l.setSink(withCallDepth.WithCallDepth(depth)) } @@ -345,6 +377,9 @@ func (l Logger) WithCallDepth(depth int) Logger { // implementation does not support either of these, the original Logger will be // returned. func (l Logger) WithCallStackHelper() (func(), Logger) { + if l.sink == nil { + return func() {}, l + } var helper func() if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { l.setSink(withCallDepth.WithCallDepth(1)) @@ -357,6 +392,11 @@ func (l Logger) WithCallStackHelper() (func(), Logger) { return helper, l } +// IsZero returns true if this logger is an uninitialized zero value +func (l Logger) IsZero() bool { + return l.sink == nil +} + // contextKey is how we find Loggers in a context.Context. type contextKey struct{} @@ -442,7 +482,7 @@ type LogSink interface { WithName(name string) LogSink } -// CallDepthLogSink represents a Logger that knows how to climb the call stack +// CallDepthLogSink represents a LogSink that knows how to climb the call stack // to identify the original call site and can offset the depth by a specified // number of frames. This is useful for users who have helper functions // between the "real" call site and the actual calls to Logger methods. @@ -467,7 +507,7 @@ type CallDepthLogSink interface { WithCallDepth(depth int) LogSink } -// CallStackHelperLogSink represents a Logger that knows how to climb +// CallStackHelperLogSink represents a LogSink that knows how to climb // the call stack to identify the original call site and can skip // intermediate helper functions if they mark themselves as // helper. Go's testing package uses that approach. diff --git a/vendor/go.opentelemetry.io/otel/sdk/export/metric/LICENSE b/vendor/github.com/go-logr/stdr/LICENSE similarity index 100% rename from vendor/go.opentelemetry.io/otel/sdk/export/metric/LICENSE rename to vendor/github.com/go-logr/stdr/LICENSE diff --git a/vendor/github.com/go-logr/stdr/README.md b/vendor/github.com/go-logr/stdr/README.md new file mode 100644 index 00000000000..5158667890c --- /dev/null +++ b/vendor/github.com/go-logr/stdr/README.md @@ -0,0 +1,6 @@ +# Minimal Go logging using logr and Go's standard library + +[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/stdr.svg)](https://pkg.go.dev/github.com/go-logr/stdr) + +This package implements the [logr interface](https://github.com/go-logr/logr) +in terms of Go's standard log package(https://pkg.go.dev/log). diff --git a/vendor/github.com/go-logr/stdr/stdr.go b/vendor/github.com/go-logr/stdr/stdr.go new file mode 100644 index 00000000000..93a8aab51be --- /dev/null +++ b/vendor/github.com/go-logr/stdr/stdr.go @@ -0,0 +1,170 @@ +/* +Copyright 2019 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package stdr implements github.com/go-logr/logr.Logger in terms of +// Go's standard log package. +package stdr + +import ( + "log" + "os" + + "github.com/go-logr/logr" + "github.com/go-logr/logr/funcr" +) + +// The global verbosity level. See SetVerbosity(). +var globalVerbosity int + +// SetVerbosity sets the global level against which all info logs will be +// compared. If this is greater than or equal to the "V" of the logger, the +// message will be logged. A higher value here means more logs will be written. +// The previous verbosity value is returned. This is not concurrent-safe - +// callers must be sure to call it from only one goroutine. +func SetVerbosity(v int) int { + old := globalVerbosity + globalVerbosity = v + return old +} + +// New returns a logr.Logger which is implemented by Go's standard log package, +// or something like it. If std is nil, this will use a default logger +// instead. +// +// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))) +func New(std StdLogger) logr.Logger { + return NewWithOptions(std, Options{}) +} + +// NewWithOptions returns a logr.Logger which is implemented by Go's standard +// log package, or something like it. See New for details. +func NewWithOptions(std StdLogger, opts Options) logr.Logger { + if std == nil { + // Go's log.Default() is only available in 1.16 and higher. + std = log.New(os.Stderr, "", log.LstdFlags) + } + + if opts.Depth < 0 { + opts.Depth = 0 + } + + fopts := funcr.Options{ + LogCaller: funcr.MessageClass(opts.LogCaller), + } + + sl := &logger{ + Formatter: funcr.NewFormatter(fopts), + std: std, + } + + // For skipping our own logger.Info/Error. + sl.Formatter.AddCallDepth(1 + opts.Depth) + + return logr.New(sl) +} + +// Options carries parameters which influence the way logs are generated. +type Options struct { + // Depth biases the assumed number of call frames to the "true" caller. + // This is useful when the calling code calls a function which then calls + // stdr (e.g. a logging shim to another API). Values less than zero will + // be treated as zero. + Depth int + + // LogCaller tells stdr to add a "caller" key to some or all log lines. + // Go's log package has options to log this natively, too. + LogCaller MessageClass + + // TODO: add an option to log the date/time +} + +// MessageClass indicates which category or categories of messages to consider. +type MessageClass int + +const ( + // None ignores all message classes. + None MessageClass = iota + // All considers all message classes. + All + // Info only considers info messages. + Info + // Error only considers error messages. + Error +) + +// StdLogger is the subset of the Go stdlib log.Logger API that is needed for +// this adapter. +type StdLogger interface { + // Output is the same as log.Output and log.Logger.Output. + Output(calldepth int, logline string) error +} + +type logger struct { + funcr.Formatter + std StdLogger +} + +var _ logr.LogSink = &logger{} +var _ logr.CallDepthLogSink = &logger{} + +func (l logger) Enabled(level int) bool { + return globalVerbosity >= level +} + +func (l logger) Info(level int, msg string, kvList ...interface{}) { + prefix, args := l.FormatInfo(level, msg, kvList) + if prefix != "" { + args = prefix + ": " + args + } + _ = l.std.Output(l.Formatter.GetDepth()+1, args) +} + +func (l logger) Error(err error, msg string, kvList ...interface{}) { + prefix, args := l.FormatError(err, msg, kvList) + if prefix != "" { + args = prefix + ": " + args + } + _ = l.std.Output(l.Formatter.GetDepth()+1, args) +} + +func (l logger) WithName(name string) logr.LogSink { + l.Formatter.AddName(name) + return &l +} + +func (l logger) WithValues(kvList ...interface{}) logr.LogSink { + l.Formatter.AddValues(kvList) + return &l +} + +func (l logger) WithCallDepth(depth int) logr.LogSink { + l.Formatter.AddCallDepth(depth) + return &l +} + +// Underlier exposes access to the underlying logging implementation. Since +// callers only have a logr.Logger, they have to know which implementation is +// in use, so this interface is less of an abstraction and more of way to test +// type conversion. +type Underlier interface { + GetUnderlying() StdLogger +} + +// GetUnderlying returns the StdLogger underneath this logger. Since StdLogger +// is itself an interface, the result may or may not be a Go log.Logger. +func (l logger) GetUnderlying() StdLogger { + return l.std +} diff --git a/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/vendor/github.com/go-openapi/jsonpointer/.travis.yml deleted file mode 100644 index 03a22fe06fd..00000000000 --- a/vendor/github.com/go-openapi/jsonpointer/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.15.x -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml index f9381aee541..013fc1943a9 100644 --- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml @@ -1,8 +1,6 @@ linters-settings: govet: check-shadowing: true - golint: - min-confidence: 0 gocyclo: min-complexity: 30 maligned: @@ -12,6 +10,8 @@ linters-settings: goconst: min-len: 2 min-occurrences: 4 + paralleltest: + ignore-missing: true linters: enable-all: true disable: @@ -39,3 +39,12 @@ linters: - nestif - godot - errorlint + - varcheck + - interfacer + - deadcode + - golint + - ifshort + - structcheck + - nosnakecase + - varnamelen + - exhaustruct diff --git a/vendor/github.com/go-openapi/jsonreference/.travis.yml b/vendor/github.com/go-openapi/jsonreference/.travis.yml deleted file mode 100644 index 05482f4b90c..00000000000 --- a/vendor/github.com/go-openapi/jsonreference/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -install: -- go get gotest.tools/gotestsum -jobs: - include: - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go index 8956c30884d..fb376fce2da 100644 --- a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go +++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go @@ -7,8 +7,8 @@ import ( ) const ( - defaultHttpPort = ":80" - defaultHttpsPort = ":443" + defaultHTTPPort = ":80" + defaultHTTPSPort = ":443" ) // Regular expressions used by the normalizations @@ -18,13 +18,14 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`) // NormalizeURL will normalize the specified URL // This was added to replace a previous call to the no longer maintained purell library: // The call that was used looked like the following: -// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) +// +// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) // // To explain all that was included in the call above, purell.FlagsSafe was really just the following: -// - FlagLowercaseScheme -// - FlagLowercaseHost -// - FlagRemoveDefaultPort -// - FlagRemoveDuplicateSlashes (and this was mixed in with the |) +// - FlagLowercaseScheme +// - FlagLowercaseHost +// - FlagRemoveDefaultPort +// - FlagRemoveDuplicateSlashes (and this was mixed in with the |) func NormalizeURL(u *url.URL) { lowercaseScheme(u) lowercaseHost(u) @@ -48,7 +49,7 @@ func removeDefaultPort(u *url.URL) { if len(u.Host) > 0 { scheme := strings.ToLower(u.Scheme) u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { - if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) { + if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) { return "" } return val diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index 2a4a71f3a85..bf503e40001 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -48,3 +48,7 @@ linters: - goimports - tenv - golint + - exhaustruct + - nilnil + - nonamedreturns + - nosnakecase diff --git a/vendor/github.com/go-openapi/swag/doc.go b/vendor/github.com/go-openapi/swag/doc.go index 8d2c8c5014e..55094cb74c4 100644 --- a/vendor/github.com/go-openapi/swag/doc.go +++ b/vendor/github.com/go-openapi/swag/doc.go @@ -17,16 +17,15 @@ Package swag contains a bunch of helper functions for go-openapi and go-swagger You may also use it standalone for your projects. - * convert between value and pointers for builtin types - * convert from string to builtin types (wraps strconv) - * fast json concatenation - * search in path - * load from file or http - * name mangling - + - convert between value and pointers for builtin types + - convert from string to builtin types (wraps strconv) + - fast json concatenation + - search in path + - load from file or http + - name mangling This repo has only few dependencies outside of the standard library: - * YAML utilities depend on gopkg.in/yaml.v2 + - YAML utilities depend on gopkg.in/yaml.v2 */ package swag diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go index 9a60409725e..00038c3773c 100644 --- a/vendor/github.com/go-openapi/swag/loading.go +++ b/vendor/github.com/go-openapi/swag/loading.go @@ -16,10 +16,11 @@ package swag import ( "fmt" - "io/ioutil" + "io" "log" "net/http" "net/url" + "os" "path/filepath" "runtime" "strings" @@ -40,13 +41,13 @@ var LoadHTTPCustomHeaders = map[string]string{} // LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in func LoadFromFileOrHTTP(path string) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) + return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) } // LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in // timeout arg allows for per request overriding of the request timeout func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path) + return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path) } // LoadStrategy returns a loader function for a given path or uri @@ -86,7 +87,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func( func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { return func(path string) ([]byte, error) { client := &http.Client{Timeout: timeout} - req, err := http.NewRequest("GET", path, nil) // nolint: noctx + req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx if err != nil { return nil, err } @@ -115,6 +116,6 @@ func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status) } - return ioutil.ReadAll(resp.Body) + return io.ReadAll(resp.Body) } } diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go index 193702f2cec..f78ab684a0a 100644 --- a/vendor/github.com/go-openapi/swag/util.go +++ b/vendor/github.com/go-openapi/swag/util.go @@ -99,10 +99,11 @@ const ( ) // JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) +// +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) func JoinByFormat(data []string, format string) []string { if len(data) == 0 { return data @@ -124,11 +125,11 @@ func JoinByFormat(data []string, format string) []string { } // SplitByFormat splits a string by a known format: -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) // +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) func SplitByFormat(data, format string) []string { if data == "" { return nil diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go index ec96914405b..f09ee609f3b 100644 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ b/vendor/github.com/go-openapi/swag/yaml.go @@ -22,7 +22,7 @@ import ( "github.com/mailru/easyjson/jlexer" "github.com/mailru/easyjson/jwriter" - yaml "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v3" ) // YAMLMatcher matches yaml @@ -43,16 +43,126 @@ func YAMLToJSON(data interface{}) (json.RawMessage, error) { // BytesToYAMLDoc converts a byte slice into a YAML document func BytesToYAMLDoc(data []byte) (interface{}, error) { - var canary map[interface{}]interface{} // validate this is an object and not a different type - if err := yaml.Unmarshal(data, &canary); err != nil { + var document yaml.Node // preserve order that is present in the document + if err := yaml.Unmarshal(data, &document); err != nil { return nil, err } + if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { + return nil, fmt.Errorf("only YAML documents that are objects are supported") + } + return &document, nil +} - var document yaml.MapSlice // preserve order that is present in the document - if err := yaml.Unmarshal(data, &document); err != nil { - return nil, err +func yamlNode(root *yaml.Node) (interface{}, error) { + switch root.Kind { + case yaml.DocumentNode: + return yamlDocument(root) + case yaml.SequenceNode: + return yamlSequence(root) + case yaml.MappingNode: + return yamlMapping(root) + case yaml.ScalarNode: + return yamlScalar(root) + case yaml.AliasNode: + return yamlNode(root.Alias) + default: + return nil, fmt.Errorf("unsupported YAML node type: %v", root.Kind) + } +} + +func yamlDocument(node *yaml.Node) (interface{}, error) { + if len(node.Content) != 1 { + return nil, fmt.Errorf("unexpected YAML Document node content length: %d", len(node.Content)) + } + return yamlNode(node.Content[0]) +} + +func yamlMapping(node *yaml.Node) (interface{}, error) { + m := make(JSONMapSlice, len(node.Content)/2) + + var j int + for i := 0; i < len(node.Content); i += 2 { + var nmi JSONMapItem + k, err := yamlStringScalarC(node.Content[i]) + if err != nil { + return nil, fmt.Errorf("unable to decode YAML map key: %w", err) + } + nmi.Key = k + v, err := yamlNode(node.Content[i+1]) + if err != nil { + return nil, fmt.Errorf("unable to process YAML map value for key %q: %w", k, err) + } + nmi.Value = v + m[j] = nmi + j++ + } + return m, nil +} + +func yamlSequence(node *yaml.Node) (interface{}, error) { + s := make([]interface{}, 0) + + for i := 0; i < len(node.Content); i++ { + + v, err := yamlNode(node.Content[i]) + if err != nil { + return nil, fmt.Errorf("unable to decode YAML sequence value: %w", err) + } + s = append(s, v) + } + return s, nil +} + +const ( // See https://yaml.org/type/ + yamlStringScalar = "tag:yaml.org,2002:str" + yamlIntScalar = "tag:yaml.org,2002:int" + yamlBoolScalar = "tag:yaml.org,2002:bool" + yamlFloatScalar = "tag:yaml.org,2002:float" + yamlTimestamp = "tag:yaml.org,2002:timestamp" + yamlNull = "tag:yaml.org,2002:null" +) + +func yamlScalar(node *yaml.Node) (interface{}, error) { + switch node.LongTag() { + case yamlStringScalar: + return node.Value, nil + case yamlBoolScalar: + b, err := strconv.ParseBool(node.Value) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w", node.Value, err) + } + return b, nil + case yamlIntScalar: + i, err := strconv.ParseInt(node.Value, 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w", node.Value, err) + } + return i, nil + case yamlFloatScalar: + f, err := strconv.ParseFloat(node.Value, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w", node.Value, err) + } + return f, nil + case yamlTimestamp: + return node.Value, nil + case yamlNull: + return nil, nil + default: + return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag()) + } +} + +func yamlStringScalarC(node *yaml.Node) (string, error) { + if node.Kind != yaml.ScalarNode { + return "", fmt.Errorf("expecting a string scalar but got %q", node.Kind) + } + switch node.LongTag() { + case yamlStringScalar, yamlIntScalar, yamlFloatScalar: + return node.Value, nil + default: + return "", fmt.Errorf("YAML tag %q is not supported as map key", node.LongTag()) } - return document, nil } // JSONMapSlice represent a JSON object, with the order of keys maintained @@ -105,6 +215,113 @@ func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) { *s = result } +func (s JSONMapSlice) MarshalYAML() (interface{}, error) { + var n yaml.Node + n.Kind = yaml.DocumentNode + var nodes []*yaml.Node + for _, item := range s { + nn, err := json2yaml(item.Value) + if err != nil { + return nil, err + } + ns := []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: item.Key, + }, + nn, + } + nodes = append(nodes, ns...) + } + + n.Content = []*yaml.Node{ + { + Kind: yaml.MappingNode, + Content: nodes, + }, + } + + return yaml.Marshal(&n) +} + +func json2yaml(item interface{}) (*yaml.Node, error) { + switch val := item.(type) { + case JSONMapSlice: + var n yaml.Node + n.Kind = yaml.MappingNode + for i := range val { + childNode, err := json2yaml(&val[i].Value) + if err != nil { + return nil, err + } + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: val[i].Key, + }, childNode) + } + return &n, nil + case map[string]interface{}: + var n yaml.Node + n.Kind = yaml.MappingNode + for k, v := range val { + childNode, err := json2yaml(v) + if err != nil { + return nil, err + } + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: k, + }, childNode) + } + return &n, nil + case []interface{}: + var n yaml.Node + n.Kind = yaml.SequenceNode + for i := range val { + childNode, err := json2yaml(val[i]) + if err != nil { + return nil, err + } + n.Content = append(n.Content, childNode) + } + return &n, nil + case string: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: val, + }, nil + case float64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlFloatScalar, + Value: strconv.FormatFloat(val, 'f', -1, 64), + }, nil + case int64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: strconv.FormatInt(val, 10), + }, nil + case uint64: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: strconv.FormatUint(val, 10), + }, nil + case bool: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlBoolScalar, + Value: strconv.FormatBool(val), + }, nil + } + return nil, nil +} + // JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice type JSONMapItem struct { Key string @@ -173,23 +390,10 @@ func transformData(input interface{}) (out interface{}, err error) { } switch in := input.(type) { - case yaml.MapSlice: - - o := make(JSONMapSlice, len(in)) - for i, mi := range in { - var nmi JSONMapItem - if nmi.Key, err = format(mi.Key); err != nil { - return nil, err - } - - v, ert := transformData(mi.Value) - if ert != nil { - return nil, ert - } - nmi.Value = v - o[i] = nmi - } - return o, nil + case yaml.Node: + return yamlNode(&in) + case *yaml.Node: + return yamlNode(in) case map[interface{}]interface{}: o := make(JSONMapSlice, 0, len(in)) for ke, va := range in { diff --git a/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go index 718c34f886e..dd0ed101563 100644 --- a/vendor/github.com/golang/glog/glog.go +++ b/vendor/github.com/golang/glog/glog.go @@ -1,6 +1,6 @@ -// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// Go support for leveled logs, analogous to https://github.com/google/glog. // -// Copyright 2013 Google Inc. All Rights Reserved. +// Copyright 2023 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -50,15 +50,15 @@ // Log files will be written to this directory instead of the // default temporary directory. // -// Other flags provide aids to debugging. +// Other flags provide aids to debugging. // // -log_backtrace_at="" -// When set to a file and line number holding a logging statement, -// such as +// A comma-separated list of file and line numbers holding a logging +// statement, such as // -log_backtrace_at=gopherflakes.go:234 -// a stack trace will be written to the Info log whenever execution -// hits that statement. (Unlike with -vmodule, the ".go" must be -// present.) +// A stack trace will be written to the Info log whenever execution +// hits one of these statements. (Unlike with -vmodule, the ".go" +// must bepresent.) // -v=0 // Enable V-leveled logging at the specified level. // -vmodule="" @@ -66,100 +66,46 @@ // where pattern is a literal file name (minus the ".go" suffix) or // "glob" pattern and N is a V level. For instance, // -vmodule=gopher*=3 -// sets the V level to 3 in all Go files whose names begin "gopher". -// +// sets the V level to 3 in all Go files whose names begin with "gopher", +// and +// -vmodule=/path/to/glog/glog_test=1 +// sets the V level to 1 in the Go file /path/to/glog/glog_test.go. +// If a glob pattern contains a slash, it is matched against the full path, +// and the file name. Otherwise, the pattern is +// matched only against the file's basename. When both -vmodule and -v +// are specified, the -vmodule values take precedence for the specified +// modules. package glog +// This file contains the parts of the log package that are shared among all +// implementations (file, envelope, and appengine). + import ( - "bufio" "bytes" "errors" - "flag" "fmt" - "io" stdLog "log" "os" - "path/filepath" + "reflect" "runtime" + "runtime/pprof" "strconv" - "strings" "sync" "sync/atomic" "time" -) - -// severity identifies the sort of log: info, warning etc. It also implements -// the flag.Value interface. The -stderrthreshold flag is of type severity and -// should be modified only through the flag.Value interface. The values match -// the corresponding constants in C++. -type severity int32 // sync/atomic int32 -// These constants identify the log levels in order of increasing severity. -// A message written to a high-severity log file is also written to each -// lower-severity log file. -const ( - infoLog severity = iota - warningLog - errorLog - fatalLog - numSeverity = 4 + "github.com/golang/glog/internal/logsink" + "github.com/golang/glog/internal/stackdump" ) -const severityChar = "IWEF" - -var severityName = []string{ - infoLog: "INFO", - warningLog: "WARNING", - errorLog: "ERROR", - fatalLog: "FATAL", -} - -// get returns the value of the severity. -func (s *severity) get() severity { - return severity(atomic.LoadInt32((*int32)(s))) -} - -// set sets the value of the severity. -func (s *severity) set(val severity) { - atomic.StoreInt32((*int32)(s), int32(val)) -} - -// String is part of the flag.Value interface. -func (s *severity) String() string { - return strconv.FormatInt(int64(*s), 10) -} - -// Get is part of the flag.Value interface. -func (s *severity) Get() interface{} { - return *s -} +var timeNow = time.Now // Stubbed out for testing. -// Set is part of the flag.Value interface. -func (s *severity) Set(value string) error { - var threshold severity - // Is it a known name? - if v, ok := severityByName(value); ok { - threshold = v - } else { - v, err := strconv.Atoi(value) - if err != nil { - return err - } - threshold = severity(v) - } - logging.stderrThreshold.set(threshold) - return nil -} +// MaxSize is the maximum size of a log file in bytes. +var MaxSize uint64 = 1024 * 1024 * 1800 -func severityByName(s string) (severity, bool) { - s = strings.ToUpper(s) - for i, name := range severityName { - if name == s { - return severity(i), true - } - } - return 0, false -} +// ErrNoLog is the error we return if no log file has yet been created +// for the specified log type. +var ErrNoLog = errors.New("log file not yet created") // OutputStats tracks the number of output lines and bytes written. type OutputStats struct { @@ -183,724 +129,99 @@ var Stats struct { Info, Warning, Error OutputStats } -var severityStats = [numSeverity]*OutputStats{ - infoLog: &Stats.Info, - warningLog: &Stats.Warning, - errorLog: &Stats.Error, +var severityStats = [...]*OutputStats{ + logsink.Info: &Stats.Info, + logsink.Warning: &Stats.Warning, + logsink.Error: &Stats.Error, + logsink.Fatal: nil, } -// Level is exported because it appears in the arguments to V and is -// the type of the v flag, which can be set programmatically. -// It's a distinct type because we want to discriminate it from logType. -// Variables of type level are only changed under logging.mu. -// The -v flag is read only with atomic ops, so the state of the logging -// module is consistent. - -// Level is treated as a sync/atomic int32. - -// Level specifies a level of verbosity for V logs. *Level implements -// flag.Value; the -v flag is of type Level and should be modified -// only through the flag.Value interface. +// Level specifies a level of verbosity for V logs. The -v flag is of type +// Level and should be modified only through the flag.Value interface. type Level int32 -// get returns the value of the Level. -func (l *Level) get() Level { - return Level(atomic.LoadInt32((*int32)(l))) -} - -// set sets the value of the Level. -func (l *Level) set(val Level) { - atomic.StoreInt32((*int32)(l), int32(val)) -} - -// String is part of the flag.Value interface. -func (l *Level) String() string { - return strconv.FormatInt(int64(*l), 10) -} - -// Get is part of the flag.Value interface. -func (l *Level) Get() interface{} { - return *l -} - -// Set is part of the flag.Value interface. -func (l *Level) Set(value string) error { - v, err := strconv.Atoi(value) - if err != nil { - return err - } - logging.mu.Lock() - defer logging.mu.Unlock() - logging.setVState(Level(v), logging.vmodule.filter, false) - return nil -} - -// moduleSpec represents the setting of the -vmodule flag. -type moduleSpec struct { - filter []modulePat -} - -// modulePat contains a filter for the -vmodule flag. -// It holds a verbosity level and a file pattern to match. -type modulePat struct { - pattern string - literal bool // The pattern is a literal string - level Level -} - -// match reports whether the file matches the pattern. It uses a string -// comparison if the pattern contains no metacharacters. -func (m *modulePat) match(file string) bool { - if m.literal { - return file == m.pattern - } - match, _ := filepath.Match(m.pattern, file) - return match -} - -func (m *moduleSpec) String() string { - // Lock because the type is not atomic. TODO: clean this up. - logging.mu.Lock() - defer logging.mu.Unlock() - var b bytes.Buffer - for i, f := range m.filter { - if i > 0 { - b.WriteRune(',') - } - fmt.Fprintf(&b, "%s=%d", f.pattern, f.level) - } - return b.String() -} - -// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the -// struct is not exported. -func (m *moduleSpec) Get() interface{} { - return nil -} - -var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N") +var metaPool sync.Pool // Pool of *logsink.Meta. -// Syntax: -vmodule=recordio=2,file=1,gfs*=3 -func (m *moduleSpec) Set(value string) error { - var filter []modulePat - for _, pat := range strings.Split(value, ",") { - if len(pat) == 0 { - // Empty strings such as from a trailing comma can be ignored. - continue - } - patLev := strings.Split(pat, "=") - if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 { - return errVmoduleSyntax - } - pattern := patLev[0] - v, err := strconv.Atoi(patLev[1]) - if err != nil { - return errors.New("syntax error: expect comma-separated list of filename=N") - } - if v < 0 { - return errors.New("negative value for vmodule level") - } - if v == 0 { - continue // Ignore. It's harmless but no point in paying the overhead. - } - // TODO: check syntax of filter? - filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)}) +// metaPoolGet returns a *logsink.Meta from metaPool as both an interface and a +// pointer, allocating a new one if necessary. (Returning the interface value +// directly avoids an allocation if there was an existing pointer in the pool.) +func metaPoolGet() (any, *logsink.Meta) { + if metai := metaPool.Get(); metai != nil { + return metai, metai.(*logsink.Meta) } - logging.mu.Lock() - defer logging.mu.Unlock() - logging.setVState(logging.verbosity, filter, true) - return nil + meta := new(logsink.Meta) + return meta, meta } -// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters -// that require filepath.Match to be called to match the pattern. -func isLiteral(pattern string) bool { - return !strings.ContainsAny(pattern, `\*?[]`) -} - -// traceLocation represents the setting of the -log_backtrace_at flag. -type traceLocation struct { - file string - line int -} +type stack bool -// isSet reports whether the trace location has been specified. -// logging.mu is held. -func (t *traceLocation) isSet() bool { - return t.line > 0 -} - -// match reports whether the specified file and line matches the trace location. -// The argument file name is the full path, not the basename specified in the flag. -// logging.mu is held. -func (t *traceLocation) match(file string, line int) bool { - if t.line != line { - return false - } - if i := strings.LastIndex(file, "/"); i >= 0 { - file = file[i+1:] - } - return t.file == file -} - -func (t *traceLocation) String() string { - // Lock because the type is not atomic. TODO: clean this up. - logging.mu.Lock() - defer logging.mu.Unlock() - return fmt.Sprintf("%s:%d", t.file, t.line) -} - -// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the -// struct is not exported -func (t *traceLocation) Get() interface{} { - return nil -} - -var errTraceSyntax = errors.New("syntax error: expect file.go:234") - -// Syntax: -log_backtrace_at=gopherflakes.go:234 -// Note that unlike vmodule the file extension is included here. -func (t *traceLocation) Set(value string) error { - if value == "" { - // Unset. - t.line = 0 - t.file = "" - } - fields := strings.Split(value, ":") - if len(fields) != 2 { - return errTraceSyntax - } - file, line := fields[0], fields[1] - if !strings.Contains(file, ".") { - return errTraceSyntax - } - v, err := strconv.Atoi(line) - if err != nil { - return errTraceSyntax - } - if v <= 0 { - return errors.New("negative or zero value for level") - } - logging.mu.Lock() - defer logging.mu.Unlock() - t.line = v - t.file = file - return nil -} - -// flushSyncWriter is the interface satisfied by logging destinations. -type flushSyncWriter interface { - Flush() error - Sync() error - io.Writer -} - -func init() { - flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files") - flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files") - flag.Var(&logging.verbosity, "v", "log level for V logs") - flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr") - flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") - flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") - - // Default stderrThreshold is ERROR. - logging.stderrThreshold = errorLog - - logging.setVState(0, nil, false) - go logging.flushDaemon() -} - -// Flush flushes all pending log I/O. -func Flush() { - logging.lockAndFlushAll() -} - -// loggingT collects all the global state of the logging setup. -type loggingT struct { - // Boolean flags. Not handled atomically because the flag.Value interface - // does not let us avoid the =true, and that shorthand is necessary for - // compatibility. TODO: does this matter enough to fix? Seems unlikely. - toStderr bool // The -logtostderr flag. - alsoToStderr bool // The -alsologtostderr flag. - - // Level flag. Handled atomically. - stderrThreshold severity // The -stderrthreshold flag. - - // freeList is a list of byte buffers, maintained under freeListMu. - freeList *buffer - // freeListMu maintains the free list. It is separate from the main mutex - // so buffers can be grabbed and printed to without holding the main lock, - // for better parallelization. - freeListMu sync.Mutex - - // mu protects the remaining elements of this structure and is - // used to synchronize logging. - mu sync.Mutex - // file holds writer for each of the log types. - file [numSeverity]flushSyncWriter - // pcs is used in V to avoid an allocation when computing the caller's PC. - pcs [1]uintptr - // vmap is a cache of the V Level for each V() call site, identified by PC. - // It is wiped whenever the vmodule flag changes state. - vmap map[uintptr]Level - // filterLength stores the length of the vmodule filter chain. If greater - // than zero, it means vmodule is enabled. It may be read safely - // using sync.LoadInt32, but is only modified under mu. - filterLength int32 - // traceLocation is the state of the -log_backtrace_at flag. - traceLocation traceLocation - // These flags are modified only under lock, although verbosity may be fetched - // safely using atomic.LoadInt32. - vmodule moduleSpec // The state of the -vmodule flag. - verbosity Level // V logging level, the value of the -v flag/ -} - -// buffer holds a byte Buffer for reuse. The zero value is ready for use. -type buffer struct { - bytes.Buffer - tmp [64]byte // temporary byte array for creating headers. - next *buffer -} - -var logging loggingT - -// setVState sets a consistent state for V logging. -// l.mu is held. -func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) { - // Turn verbosity off so V will not fire while we are in transition. - logging.verbosity.set(0) - // Ditto for filter length. - atomic.StoreInt32(&logging.filterLength, 0) - - // Set the new filters and wipe the pc->Level map if the filter has changed. - if setFilter { - logging.vmodule.filter = filter - logging.vmap = make(map[uintptr]Level) - } - - // Things are consistent now, so enable filtering and verbosity. - // They are enabled in order opposite to that in V. - atomic.StoreInt32(&logging.filterLength, int32(len(filter))) - logging.verbosity.set(verbosity) -} - -// getBuffer returns a new, ready-to-use buffer. -func (l *loggingT) getBuffer() *buffer { - l.freeListMu.Lock() - b := l.freeList - if b != nil { - l.freeList = b.next - } - l.freeListMu.Unlock() - if b == nil { - b = new(buffer) - } else { - b.next = nil - b.Reset() - } - return b -} - -// putBuffer returns a buffer to the free list. -func (l *loggingT) putBuffer(b *buffer) { - if b.Len() >= 256 { - // Let big buffers die a natural death. - return - } - l.freeListMu.Lock() - b.next = l.freeList - l.freeList = b - l.freeListMu.Unlock() -} - -var timeNow = time.Now // Stubbed out for testing. +const ( + noStack = stack(false) + withStack = stack(true) +) -/* -header formats a log header as defined by the C++ implementation. -It returns a buffer containing the formatted header and the user's file and line number. -The depth specifies how many stack frames above lives the source line to be identified in the log message. - -Log lines have this form: - Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... -where the fields are defined as follows: - L A single character, representing the log level (eg 'I' for INFO) - mm The month (zero padded; ie May is '05') - dd The day (zero padded) - hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds - threadid The space-padded thread ID as returned by GetTID() - file The file name - line The line number - msg The user-supplied message -*/ -func (l *loggingT) header(s severity, depth int) (*buffer, string, int) { - _, file, line, ok := runtime.Caller(3 + depth) +func appendBacktrace(depth int, format string, args []any) (string, []any) { + // Capture a backtrace as a stackdump.Stack (both text and PC slice). + // Structured log sinks can extract the backtrace in whichever format they + // prefer (PCs or text), and Text sinks will include it as just another part + // of the log message. + // + // Use depth instead of depth+1 so that the backtrace always includes the + // log function itself - otherwise the reason for the trace appearing in the + // log may not be obvious to the reader. + dump := stackdump.Caller(depth) + + // Add an arg and an entry in the format string for the stack dump. + // + // Copy the "args" slice to avoid a rare but serious aliasing bug + // (corrupting the caller's slice if they passed it to a non-Fatal call + // using "..."). + format = format + "\n\n%v\n" + args = append(append([]any(nil), args...), dump) + + return format, args +} + +// logf writes a log message for a log function call (or log function wrapper) +// at the given depth in the current goroutine's stack. +func logf(depth int, severity logsink.Severity, verbose bool, stack stack, format string, args ...any) { + now := timeNow() + _, file, line, ok := runtime.Caller(depth + 1) if !ok { file = "???" line = 1 - } else { - slash := strings.LastIndex(file, "/") - if slash >= 0 { - file = file[slash+1:] - } } - return l.formatHeader(s, file, line), file, line -} -// formatHeader formats a log header using the provided file name and line number. -func (l *loggingT) formatHeader(s severity, file string, line int) *buffer { - now := timeNow() - if line < 0 { - line = 0 // not a real line number, but acceptable to someDigits - } - if s > fatalLog { - s = infoLog // for safety. + if stack == withStack || backtraceAt(file, line) { + format, args = appendBacktrace(depth+1, format, args) } - buf := l.getBuffer() - - // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. - // It's worth about 3X. Fprintf is hard. - _, month, day := now.Date() - hour, minute, second := now.Clock() - // Lmmdd hh:mm:ss.uuuuuu threadid file:line] - buf.tmp[0] = severityChar[s] - buf.twoDigits(1, int(month)) - buf.twoDigits(3, day) - buf.tmp[5] = ' ' - buf.twoDigits(6, hour) - buf.tmp[8] = ':' - buf.twoDigits(9, minute) - buf.tmp[11] = ':' - buf.twoDigits(12, second) - buf.tmp[14] = '.' - buf.nDigits(6, 15, now.Nanosecond()/1000, '0') - buf.tmp[21] = ' ' - buf.nDigits(7, 22, pid, ' ') // TODO: should be TID - buf.tmp[29] = ' ' - buf.Write(buf.tmp[:30]) - buf.WriteString(file) - buf.tmp[0] = ':' - n := buf.someDigits(1, line) - buf.tmp[n+1] = ']' - buf.tmp[n+2] = ' ' - buf.Write(buf.tmp[:n+3]) - return buf -} - -// Some custom tiny helper functions to print the log header efficiently. - -const digits = "0123456789" - -// twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i]. -func (buf *buffer) twoDigits(i, d int) { - buf.tmp[i+1] = digits[d%10] - d /= 10 - buf.tmp[i] = digits[d%10] -} -// nDigits formats an n-digit integer at buf.tmp[i], -// padding with pad on the left. -// It assumes d >= 0. -func (buf *buffer) nDigits(n, i, d int, pad byte) { - j := n - 1 - for ; j >= 0 && d > 0; j-- { - buf.tmp[i+j] = digits[d%10] - d /= 10 + metai, meta := metaPoolGet() + *meta = logsink.Meta{ + Time: now, + File: file, + Line: line, + Depth: depth + 1, + Severity: severity, + Verbose: verbose, + Thread: int64(pid), } - for ; j >= 0; j-- { - buf.tmp[i+j] = pad - } -} - -// someDigits formats a zero-prefixed variable-width integer at buf.tmp[i]. -func (buf *buffer) someDigits(i, d int) int { - // Print into the top, then copy down. We know there's space for at least - // a 10-digit number. - j := len(buf.tmp) - for { - j-- - buf.tmp[j] = digits[d%10] - d /= 10 - if d == 0 { - break - } - } - return copy(buf.tmp[i:], buf.tmp[j:]) -} - -func (l *loggingT) println(s severity, args ...interface{}) { - buf, file, line := l.header(s, 0) - fmt.Fprintln(buf, args...) - l.output(s, buf, file, line, false) -} - -func (l *loggingT) print(s severity, args ...interface{}) { - l.printDepth(s, 1, args...) -} - -func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) { - buf, file, line := l.header(s, depth) - fmt.Fprint(buf, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, false) -} - -func (l *loggingT) printf(s severity, format string, args ...interface{}) { - buf, file, line := l.header(s, 0) - fmt.Fprintf(buf, format, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, false) + sinkf(meta, format, args...) + metaPool.Put(metai) } -// printWithFileLine behaves like print but uses the provided file and line number. If -// alsoLogToStderr is true, the log message always appears on standard error; it -// will also appear in the log file unless --logtostderr is set. -func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) { - buf := l.formatHeader(s, file, line) - fmt.Fprint(buf, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, alsoToStderr) -} - -// output writes the data to the log files and releases the buffer. -func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) { - l.mu.Lock() - if l.traceLocation.isSet() { - if l.traceLocation.match(file, line) { - buf.Write(stacks(false)) - } - } - data := buf.Bytes() - if !flag.Parsed() { - os.Stderr.Write([]byte("ERROR: logging before flag.Parse: ")) - os.Stderr.Write(data) - } else if l.toStderr { - os.Stderr.Write(data) - } else { - if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() { - os.Stderr.Write(data) - } - if l.file[s] == nil { - if err := l.createFiles(s); err != nil { - os.Stderr.Write(data) // Make sure the message appears somewhere. - l.exit(err) - } - } - switch s { - case fatalLog: - l.file[fatalLog].Write(data) - fallthrough - case errorLog: - l.file[errorLog].Write(data) - fallthrough - case warningLog: - l.file[warningLog].Write(data) - fallthrough - case infoLog: - l.file[infoLog].Write(data) - } - } - if s == fatalLog { - // If we got here via Exit rather than Fatal, print no stacks. - if atomic.LoadUint32(&fatalNoStacks) > 0 { - l.mu.Unlock() - timeoutFlush(10 * time.Second) - os.Exit(1) - } - // Dump all goroutine stacks before exiting. - // First, make sure we see the trace for the current goroutine on standard error. - // If -logtostderr has been specified, the loop below will do that anyway - // as the first stack in the full dump. - if !l.toStderr { - os.Stderr.Write(stacks(false)) - } - // Write the stack trace for all goroutines to the files. - trace := stacks(true) - logExitFunc = func(error) {} // If we get a write error, we'll still exit below. - for log := fatalLog; log >= infoLog; log-- { - if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. - f.Write(trace) - } - } - l.mu.Unlock() - timeoutFlush(10 * time.Second) - os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. - } - l.putBuffer(buf) - l.mu.Unlock() - if stats := severityStats[s]; stats != nil { +func sinkf(meta *logsink.Meta, format string, args ...any) { + meta.Depth++ + n, err := logsink.Printf(meta, format, args...) + if stats := severityStats[meta.Severity]; stats != nil { atomic.AddInt64(&stats.lines, 1) - atomic.AddInt64(&stats.bytes, int64(len(data))) + atomic.AddInt64(&stats.bytes, int64(n)) } -} -// timeoutFlush calls Flush and returns when it completes or after timeout -// elapses, whichever happens first. This is needed because the hooks invoked -// by Flush may deadlock when glog.Fatal is called from a hook that holds -// a lock. -func timeoutFlush(timeout time.Duration) { - done := make(chan bool, 1) - go func() { - Flush() // calls logging.lockAndFlushAll() - done <- true - }() - select { - case <-done: - case <-time.After(timeout): - fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout) - } -} - -// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines. -func stacks(all bool) []byte { - // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though. - n := 10000 - if all { - n = 100000 - } - var trace []byte - for i := 0; i < 5; i++ { - trace = make([]byte, n) - nbytes := runtime.Stack(trace, all) - if nbytes < len(trace) { - return trace[:nbytes] - } - n *= 2 - } - return trace -} - -// logExitFunc provides a simple mechanism to override the default behavior -// of exiting on error. Used in testing and to guarantee we reach a required exit -// for fatal logs. Instead, exit could be a function rather than a method but that -// would make its use clumsier. -var logExitFunc func(error) - -// exit is called if there is trouble creating or writing log files. -// It flushes the logs and exits the program; there's no point in hanging around. -// l.mu is held. -func (l *loggingT) exit(err error) { - fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err) - // If logExitFunc is set, we do that instead of exiting. - if logExitFunc != nil { - logExitFunc(err) - return - } - l.flushAll() - os.Exit(2) -} - -// syncBuffer joins a bufio.Writer to its underlying file, providing access to the -// file's Sync method and providing a wrapper for the Write method that provides log -// file rotation. There are conflicting methods, so the file cannot be embedded. -// l.mu is held for all its methods. -type syncBuffer struct { - logger *loggingT - *bufio.Writer - file *os.File - sev severity - nbytes uint64 // The number of bytes written to this file -} - -func (sb *syncBuffer) Sync() error { - return sb.file.Sync() -} - -func (sb *syncBuffer) Write(p []byte) (n int, err error) { - if sb.nbytes+uint64(len(p)) >= MaxSize { - if err := sb.rotateFile(time.Now()); err != nil { - sb.logger.exit(err) - } - } - n, err = sb.Writer.Write(p) - sb.nbytes += uint64(n) - if err != nil { - sb.logger.exit(err) - } - return -} - -// rotateFile closes the syncBuffer's file and starts a new one. -func (sb *syncBuffer) rotateFile(now time.Time) error { - if sb.file != nil { - sb.Flush() - sb.file.Close() - } - var err error - sb.file, _, err = create(severityName[sb.sev], now) - sb.nbytes = 0 if err != nil { - return err - } - - sb.Writer = bufio.NewWriterSize(sb.file, bufferSize) - - // Write header. - var buf bytes.Buffer - fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05")) - fmt.Fprintf(&buf, "Running on machine: %s\n", host) - fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH) - fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n") - n, err := sb.file.Write(buf.Bytes()) - sb.nbytes += uint64(n) - return err -} - -// bufferSize sizes the buffer associated with each log file. It's large -// so that log records can accumulate without the logging thread blocking -// on disk I/O. The flushDaemon will block instead. -const bufferSize = 256 * 1024 - -// createFiles creates all the log files for severity from sev down to infoLog. -// l.mu is held. -func (l *loggingT) createFiles(sev severity) error { - now := time.Now() - // Files are created in decreasing severity order, so as soon as we find one - // has already been created, we can stop. - for s := sev; s >= infoLog && l.file[s] == nil; s-- { - sb := &syncBuffer{ - logger: l, - sev: s, - } - if err := sb.rotateFile(now); err != nil { - return err - } - l.file[s] = sb - } - return nil -} - -const flushInterval = 30 * time.Second - -// flushDaemon periodically flushes the log file buffers. -func (l *loggingT) flushDaemon() { - for range time.NewTicker(flushInterval).C { - l.lockAndFlushAll() - } -} - -// lockAndFlushAll is like flushAll but locks l.mu first. -func (l *loggingT) lockAndFlushAll() { - l.mu.Lock() - l.flushAll() - l.mu.Unlock() -} - -// flushAll flushes all the logs and attempts to "sync" their data to disk. -// l.mu is held. -func (l *loggingT) flushAll() { - // Flush from fatal down, in case there's trouble flushing. - for s := fatalLog; s >= infoLog; s-- { - file := l.file[s] - if file != nil { - file.Flush() // ignore error - file.Sync() // ignore error - } + logsink.Printf(meta, "glog: exiting because of error: %s", err) + sinks.file.Flush() + os.Exit(2) } } @@ -912,9 +233,9 @@ func (l *loggingT) flushAll() { // Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not // recognized, CopyStandardLogTo panics. func CopyStandardLogTo(name string) { - sev, ok := severityByName(name) - if !ok { - panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name)) + sev, err := logsink.ParseSeverity(name) + if err != nil { + panic(fmt.Sprintf("log.CopyStandardLogTo(%q): %v", name, err)) } // Set a log format that captures the user's file and line: // d.go:23: message @@ -922,9 +243,22 @@ func CopyStandardLogTo(name string) { stdLog.SetOutput(logBridge(sev)) } +// NewStandardLogger returns a Logger that writes to the Google logs for the +// named and lower severities. +// +// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not +// recognized, NewStandardLogger panics. +func NewStandardLogger(name string) *stdLog.Logger { + sev, err := logsink.ParseSeverity(name) + if err != nil { + panic(fmt.Sprintf("log.NewStandardLogger(%q): %v", name, err)) + } + return stdLog.New(logBridge(sev), "", stdLog.Lshortfile) +} + // logBridge provides the Write method that enables CopyStandardLogTo to connect // Go's standard logs to the logs provided by this package. -type logBridge severity +type logBridge logsink.Severity // Write parses the standard logging line and passes its components to the // logger for severity(lb). @@ -946,36 +280,72 @@ func (lb logBridge) Write(b []byte) (n int, err error) { line = 1 } } - // printWithFileLine with alsoToStderr=true, so standard log messages - // always appear on standard error. - logging.printWithFileLine(severity(lb), file, line, true, text) + + // The depth below hard-codes details of how stdlog gets here. The alternative would be to walk + // up the stack looking for src/log/log.go but that seems like it would be + // unfortunately slow. + const stdLogDepth = 4 + + metai, meta := metaPoolGet() + *meta = logsink.Meta{ + Time: timeNow(), + File: file, + Line: line, + Depth: stdLogDepth, + Severity: logsink.Severity(lb), + Thread: int64(pid), + } + + format := "%s" + args := []any{text} + if backtraceAt(file, line) { + format, args = appendBacktrace(meta.Depth, format, args) + } + + sinkf(meta, format, args...) + metaPool.Put(metai) + return len(b), nil } -// setV computes and remembers the V level for a given PC -// when vmodule is enabled. -// File pattern matching takes the basename of the file, stripped -// of its .go suffix, and uses filepath.Match, which is a little more -// general than the *? matching used in C++. -// l.mu is held. -func (l *loggingT) setV(pc uintptr) Level { - fn := runtime.FuncForPC(pc) - file, _ := fn.FileLine(pc) - // The file is something like /a/b/c/d.go. We want just the d. - if strings.HasSuffix(file, ".go") { - file = file[:len(file)-3] +// defaultFormat returns a fmt.Printf format specifier that formats its +// arguments as if they were passed to fmt.Print. +func defaultFormat(args []any) string { + n := len(args) + switch n { + case 0: + return "" + case 1: + return "%v" + } + + b := make([]byte, 0, n*3-1) + wasString := true // Suppress leading space. + for _, arg := range args { + isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String + if wasString || isString { + b = append(b, "%v"...) + } else { + b = append(b, " %v"...) + } + wasString = isString } - if slash := strings.LastIndex(file, "/"); slash >= 0 { - file = file[slash+1:] + return string(b) +} + +// lnFormat returns a fmt.Printf format specifier that formats its arguments +// as if they were passed to fmt.Println. +func lnFormat(args []any) string { + if len(args) == 0 { + return "\n" } - for _, filter := range l.vmodule.filter { - if filter.match(file) { - l.vmap[pc] = filter.level - return filter.level - } + + b := make([]byte, 0, len(args)*3) + for range args { + b = append(b, "%v "...) } - l.vmap[pc] = 0 - return 0 + b[len(b)-1] = '\n' // Replace the last space with a newline. + return string(b) } // Verbose is a boolean type that implements Infof (like Printf) etc. @@ -986,9 +356,13 @@ type Verbose bool // The returned value is a boolean of type Verbose, which implements Info, Infoln // and Infof. These methods will write to the Info log if called. // Thus, one may write either +// // if glog.V(2) { glog.Info("log this") } +// // or +// // glog.V(2).Info("log this") +// // The second form is shorter but the first is cheaper if logging is off because it does // not evaluate its arguments. // @@ -997,184 +371,222 @@ type Verbose bool // V is at most the value of -v, or of -vmodule for the source file containing the // call, the V call will log. func V(level Level) Verbose { - // This function tries hard to be cheap unless there's work to do. - // The fast path is two atomic loads and compares. + return VDepth(1, level) +} - // Here is a cheap but safe test to see if V logging is enabled globally. - if logging.verbosity.get() >= level { - return Verbose(true) - } +// VDepth acts as V but uses depth to determine which call frame to check vmodule for. +// VDepth(0, level) is the same as V(level). +func VDepth(depth int, level Level) Verbose { + return Verbose(verboseEnabled(depth+1, level)) +} - // It's off globally but it vmodule may still be set. - // Here is another cheap but safe test to see if vmodule is enabled. - if atomic.LoadInt32(&logging.filterLength) > 0 { - // Now we need a proper lock to use the logging structure. The pcs field - // is shared so we must lock before accessing it. This is fairly expensive, - // but if V logging is enabled we're slow anyway. - logging.mu.Lock() - defer logging.mu.Unlock() - if runtime.Callers(2, logging.pcs[:]) == 0 { - return Verbose(false) - } - v, ok := logging.vmap[logging.pcs[0]] - if !ok { - v = logging.setV(logging.pcs[0]) - } - return Verbose(v >= level) +// Info is equivalent to the global Info function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) Info(args ...any) { + v.InfoDepth(1, args...) +} + +// InfoDepth is equivalent to the global InfoDepth function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfoDepth(depth int, args ...any) { + if v { + logf(depth+1, logsink.Info, true, noStack, defaultFormat(args), args...) } - return Verbose(false) } -// Info is equivalent to the global Info function, guarded by the value of v. +// InfoDepthf is equivalent to the global InfoDepthf function, guarded by the value of v. // See the documentation of V for usage. -func (v Verbose) Info(args ...interface{}) { +func (v Verbose) InfoDepthf(depth int, format string, args ...any) { if v { - logging.print(infoLog, args...) + logf(depth+1, logsink.Info, true, noStack, format, args...) } } // Infoln is equivalent to the global Infoln function, guarded by the value of v. // See the documentation of V for usage. -func (v Verbose) Infoln(args ...interface{}) { +func (v Verbose) Infoln(args ...any) { if v { - logging.println(infoLog, args...) + logf(1, logsink.Info, true, noStack, lnFormat(args), args...) } } // Infof is equivalent to the global Infof function, guarded by the value of v. // See the documentation of V for usage. -func (v Verbose) Infof(format string, args ...interface{}) { +func (v Verbose) Infof(format string, args ...any) { if v { - logging.printf(infoLog, format, args...) + logf(1, logsink.Info, true, noStack, format, args...) } } // Info logs to the INFO log. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Info(args ...interface{}) { - logging.print(infoLog, args...) +func Info(args ...any) { + InfoDepth(1, args...) } -// InfoDepth acts as Info but uses depth to determine which call frame to log. -// InfoDepth(0, "msg") is the same as Info("msg"). -func InfoDepth(depth int, args ...interface{}) { - logging.printDepth(infoLog, depth, args...) +// InfoDepth calls Info from a different depth in the call stack. +// This enables a callee to emit logs that use the callsite information of its caller +// or any other callers in the stack. When depth == 0, the original callee's line +// information is emitted. When depth > 0, depth frames are skipped in the call stack +// and the final frame is treated like the original callee to Info. +func InfoDepth(depth int, args ...any) { + logf(depth+1, logsink.Info, false, noStack, defaultFormat(args), args...) +} + +// InfoDepthf acts as InfoDepth but with format string. +func InfoDepthf(depth int, format string, args ...any) { + logf(depth+1, logsink.Info, false, noStack, format, args...) } // Infoln logs to the INFO log. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Infoln(args ...interface{}) { - logging.println(infoLog, args...) +func Infoln(args ...any) { + logf(1, logsink.Info, false, noStack, lnFormat(args), args...) } // Infof logs to the INFO log. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Infof(format string, args ...interface{}) { - logging.printf(infoLog, format, args...) +func Infof(format string, args ...any) { + logf(1, logsink.Info, false, noStack, format, args...) } // Warning logs to the WARNING and INFO logs. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Warning(args ...interface{}) { - logging.print(warningLog, args...) +func Warning(args ...any) { + WarningDepth(1, args...) } // WarningDepth acts as Warning but uses depth to determine which call frame to log. // WarningDepth(0, "msg") is the same as Warning("msg"). -func WarningDepth(depth int, args ...interface{}) { - logging.printDepth(warningLog, depth, args...) +func WarningDepth(depth int, args ...any) { + logf(depth+1, logsink.Warning, false, noStack, defaultFormat(args), args...) +} + +// WarningDepthf acts as Warningf but uses depth to determine which call frame to log. +// WarningDepthf(0, "msg") is the same as Warningf("msg"). +func WarningDepthf(depth int, format string, args ...any) { + logf(depth+1, logsink.Warning, false, noStack, format, args...) } // Warningln logs to the WARNING and INFO logs. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Warningln(args ...interface{}) { - logging.println(warningLog, args...) +func Warningln(args ...any) { + logf(1, logsink.Warning, false, noStack, lnFormat(args), args...) } // Warningf logs to the WARNING and INFO logs. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Warningf(format string, args ...interface{}) { - logging.printf(warningLog, format, args...) +func Warningf(format string, args ...any) { + logf(1, logsink.Warning, false, noStack, format, args...) } // Error logs to the ERROR, WARNING, and INFO logs. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Error(args ...interface{}) { - logging.print(errorLog, args...) +func Error(args ...any) { + ErrorDepth(1, args...) } // ErrorDepth acts as Error but uses depth to determine which call frame to log. // ErrorDepth(0, "msg") is the same as Error("msg"). -func ErrorDepth(depth int, args ...interface{}) { - logging.printDepth(errorLog, depth, args...) +func ErrorDepth(depth int, args ...any) { + logf(depth+1, logsink.Error, false, noStack, defaultFormat(args), args...) +} + +// ErrorDepthf acts as Errorf but uses depth to determine which call frame to log. +// ErrorDepthf(0, "msg") is the same as Errorf("msg"). +func ErrorDepthf(depth int, format string, args ...any) { + logf(depth+1, logsink.Error, false, noStack, format, args...) } // Errorln logs to the ERROR, WARNING, and INFO logs. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Errorln(args ...interface{}) { - logging.println(errorLog, args...) +func Errorln(args ...any) { + logf(1, logsink.Error, false, noStack, lnFormat(args), args...) } // Errorf logs to the ERROR, WARNING, and INFO logs. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Errorf(format string, args ...interface{}) { - logging.printf(errorLog, format, args...) +func Errorf(format string, args ...any) { + logf(1, logsink.Error, false, noStack, format, args...) +} + +func fatalf(depth int, format string, args ...any) { + logf(depth+1, logsink.Fatal, false, withStack, format, args...) + sinks.file.Flush() + + err := abortProcess() // Should not return. + + // Failed to abort the process using signals. Dump a stack trace and exit. + Errorf("abortProcess returned unexpectedly: %v", err) + sinks.file.Flush() + pprof.Lookup("goroutine").WriteTo(os.Stderr, 1) + os.Exit(2) // Exit with the same code as the default SIGABRT handler. } // Fatal logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). +// including a stack trace of all running goroutines, then calls os.Exit(2). // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Fatal(args ...interface{}) { - logging.print(fatalLog, args...) +func Fatal(args ...any) { + FatalDepth(1, args...) } // FatalDepth acts as Fatal but uses depth to determine which call frame to log. // FatalDepth(0, "msg") is the same as Fatal("msg"). -func FatalDepth(depth int, args ...interface{}) { - logging.printDepth(fatalLog, depth, args...) +func FatalDepth(depth int, args ...any) { + fatalf(depth+1, defaultFormat(args), args...) +} + +// FatalDepthf acts as Fatalf but uses depth to determine which call frame to log. +// FatalDepthf(0, "msg") is the same as Fatalf("msg"). +func FatalDepthf(depth int, format string, args ...any) { + fatalf(depth+1, format, args...) } // Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). +// including a stack trace of all running goroutines, then calls os.Exit(2). // Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Fatalln(args ...interface{}) { - logging.println(fatalLog, args...) +func Fatalln(args ...any) { + fatalf(1, lnFormat(args), args...) } // Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). +// including a stack trace of all running goroutines, then calls os.Exit(2). // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Fatalf(format string, args ...interface{}) { - logging.printf(fatalLog, format, args...) +func Fatalf(format string, args ...any) { + fatalf(1, format, args...) } -// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks. -// It allows Exit and relatives to use the Fatal logs. -var fatalNoStacks uint32 +func exitf(depth int, format string, args ...any) { + logf(depth+1, logsink.Fatal, false, noStack, format, args...) + sinks.file.Flush() + os.Exit(1) +} // Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Exit(args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.print(fatalLog, args...) +func Exit(args ...any) { + ExitDepth(1, args...) } // ExitDepth acts as Exit but uses depth to determine which call frame to log. // ExitDepth(0, "msg") is the same as Exit("msg"). -func ExitDepth(depth int, args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.printDepth(fatalLog, depth, args...) +func ExitDepth(depth int, args ...any) { + exitf(depth+1, defaultFormat(args), args...) +} + +// ExitDepthf acts as Exitf but uses depth to determine which call frame to log. +// ExitDepthf(0, "msg") is the same as Exitf("msg"). +func ExitDepthf(depth int, format string, args ...any) { + exitf(depth+1, format, args...) } // Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). -func Exitln(args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.println(fatalLog, args...) +func Exitln(args ...any) { + exitf(1, lnFormat(args), args...) } // Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Exitf(format string, args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.printf(fatalLog, format, args...) +func Exitf(format string, args ...any) { + exitf(1, format, args...) } diff --git a/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go index 65075d28111..a2e8439b24c 100644 --- a/vendor/github.com/golang/glog/glog_file.go +++ b/vendor/github.com/golang/glog/glog_file.go @@ -1,6 +1,6 @@ -// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// Go support for leveled logs, analogous to https://github.com/google/glog. // -// Copyright 2013 Google Inc. All Rights Reserved. +// Copyright 2023 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,26 +19,34 @@ package glog import ( + "bufio" + "bytes" "errors" "flag" "fmt" + "io" "os" "os/user" "path/filepath" + "runtime" "strings" "sync" "time" -) -// MaxSize is the maximum size of a log file in bytes. -var MaxSize uint64 = 1024 * 1024 * 1800 + "github.com/golang/glog/internal/logsink" +) // logDirs lists the candidate directories for new log files. var logDirs []string -// If non-empty, overrides the choice of directory in which to write logs. -// See createLogDirs for the full list of possible destinations. -var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory") +var ( + // If non-empty, overrides the choice of directory in which to write logs. + // See createLogDirs for the full list of possible destinations. + logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory") + logLink = flag.String("log_link", "", "If non-empty, add symbolic links in this directory to the log files") + logBufLevel = flag.Int("logbuflevel", int(logsink.Info), "Buffer log messages logged at this level or lower"+ + " (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms.") +) func createLogDirs() { if *logDir != "" { @@ -64,9 +72,17 @@ func init() { if err == nil { userName = current.Username } - - // Sanitize userName since it may contain filepath separators on Windows. - userName = strings.Replace(userName, `\`, "_", -1) + // Sanitize userName since it is used to construct file paths. + userName = strings.Map(func(r rune) rune { + switch { + case r >= 'a' && r <= 'z': + case r >= 'A' && r <= 'Z': + case r >= '0' && r <= '9': + default: + return '_' + } + return r + }, userName) } // shortHostname returns its argument, truncating at the first period. @@ -122,3 +138,271 @@ func create(tag string, t time.Time) (f *os.File, filename string, err error) { } return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr) } + +// flushSyncWriter is the interface satisfied by logging destinations. +type flushSyncWriter interface { + Flush() error + Sync() error + io.Writer + filenames() []string +} + +var sinks struct { + stderr stderrSink + file fileSink +} + +func init() { + // Register stderr first: that way if we crash during file-writing at least + // the log will have gone somewhere. + logsink.TextSinks = append(logsink.TextSinks, &sinks.stderr, &sinks.file) + + sinks.file.flushChan = make(chan logsink.Severity, 1) + go sinks.file.flushDaemon() +} + +// stderrSink is a logsink.Text that writes log entries to stderr +// if they meet certain conditions. +type stderrSink struct { + mu sync.Mutex + w io.Writer // if nil Emit uses os.Stderr directly +} + +// Enabled implements logsink.Text.Enabled. It returns true if any of the +// various stderr flags are enabled for logs of the given severity, if the log +// message is from the standard "log" package, or if google.Init has not yet run +// (and hence file logging is not yet initialized). +func (s *stderrSink) Enabled(m *logsink.Meta) bool { + return toStderr || alsoToStderr || m.Severity >= stderrThreshold.get() +} + +// Emit implements logsink.Text.Emit. +func (s *stderrSink) Emit(m *logsink.Meta, data []byte) (n int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + w := s.w + if w == nil { + w = os.Stderr + } + dn, err := w.Write(data) + n += dn + return n, err +} + +// severityWriters is an array of flushSyncWriter with a value for each +// logsink.Severity. +type severityWriters [4]flushSyncWriter + +// fileSink is a logsink.Text that prints to a set of Google log files. +type fileSink struct { + mu sync.Mutex + // file holds writer for each of the log types. + file severityWriters + flushChan chan logsink.Severity +} + +// Enabled implements logsink.Text.Enabled. It returns true if google.Init +// has run and both --disable_log_to_disk and --logtostderr are false. +func (s *fileSink) Enabled(m *logsink.Meta) bool { + return !toStderr +} + +// Emit implements logsink.Text.Emit +func (s *fileSink) Emit(m *logsink.Meta, data []byte) (n int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + + if err = s.createMissingFiles(m.Severity); err != nil { + return 0, err + } + for sev := m.Severity; sev >= logsink.Info; sev-- { + if _, fErr := s.file[sev].Write(data); fErr != nil && err == nil { + err = fErr // Take the first error. + } + } + n = len(data) + if int(m.Severity) > *logBufLevel { + select { + case s.flushChan <- m.Severity: + default: + } + } + + return n, err +} + +// syncBuffer joins a bufio.Writer to its underlying file, providing access to the +// file's Sync method and providing a wrapper for the Write method that provides log +// file rotation. There are conflicting methods, so the file cannot be embedded. +// s.mu is held for all its methods. +type syncBuffer struct { + sink *fileSink + *bufio.Writer + file *os.File + names []string + sev logsink.Severity + nbytes uint64 // The number of bytes written to this file +} + +func (sb *syncBuffer) Sync() error { + return sb.file.Sync() +} + +func (sb *syncBuffer) Write(p []byte) (n int, err error) { + if sb.nbytes+uint64(len(p)) >= MaxSize { + if err := sb.rotateFile(time.Now()); err != nil { + return 0, err + } + } + n, err = sb.Writer.Write(p) + sb.nbytes += uint64(n) + return n, err +} + +func (sb *syncBuffer) filenames() []string { + return sb.names +} + +const footer = "\nCONTINUED IN NEXT FILE\n" + +// rotateFile closes the syncBuffer's file and starts a new one. +func (sb *syncBuffer) rotateFile(now time.Time) error { + var err error + pn := "" + file, name, err := create(sb.sev.String(), now) + + if sb.file != nil { + // The current log file becomes the previous log at the end of + // this block, so save its name for use in the header of the next + // file. + pn = sb.file.Name() + sb.Flush() + // If there's an existing file, write a footer with the name of + // the next file in the chain, followed by the constant string + // \nCONTINUED IN NEXT FILE\n to make continuation detection simple. + sb.file.Write([]byte("Next log: ")) + sb.file.Write([]byte(name)) + sb.file.Write([]byte(footer)) + sb.file.Close() + } + + sb.file = file + sb.names = append(sb.names, name) + sb.nbytes = 0 + if err != nil { + return err + } + + sb.Writer = bufio.NewWriterSize(sb.file, bufferSize) + + // Write header. + var buf bytes.Buffer + fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05")) + fmt.Fprintf(&buf, "Running on machine: %s\n", host) + fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH) + fmt.Fprintf(&buf, "Previous log: %s\n", pn) + fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n") + n, err := sb.file.Write(buf.Bytes()) + sb.nbytes += uint64(n) + return err +} + +// bufferSize sizes the buffer associated with each log file. It's large +// so that log records can accumulate without the logging thread blocking +// on disk I/O. The flushDaemon will block instead. +const bufferSize = 256 * 1024 + +// createMissingFiles creates all the log files for severity from infoLog up to +// upTo that have not already been created. +// s.mu is held. +func (s *fileSink) createMissingFiles(upTo logsink.Severity) error { + if s.file[upTo] != nil { + return nil + } + now := time.Now() + // Files are created in increasing severity order, so we can be assured that + // if a high severity logfile exists, then so do all of lower severity. + for sev := logsink.Info; sev <= upTo; sev++ { + if s.file[sev] != nil { + continue + } + sb := &syncBuffer{ + sink: s, + sev: sev, + } + if err := sb.rotateFile(now); err != nil { + return err + } + s.file[sev] = sb + } + return nil +} + +// flushDaemon periodically flushes the log file buffers. +func (s *fileSink) flushDaemon() { + tick := time.NewTicker(30 * time.Second) + defer tick.Stop() + for { + select { + case <-tick.C: + s.Flush() + case sev := <-s.flushChan: + s.flush(sev) + } + } +} + +// Flush flushes all pending log I/O. +func Flush() { + sinks.file.Flush() +} + +// Flush flushes all the logs and attempts to "sync" their data to disk. +func (s *fileSink) Flush() error { + return s.flush(logsink.Info) +} + +// flush flushes all logs of severity threshold or greater. +func (s *fileSink) flush(threshold logsink.Severity) error { + s.mu.Lock() + defer s.mu.Unlock() + + var firstErr error + updateErr := func(err error) { + if err != nil && firstErr == nil { + firstErr = err + } + } + + // Flush from fatal down, in case there's trouble flushing. + for sev := logsink.Fatal; sev >= threshold; sev-- { + file := s.file[sev] + if file != nil { + updateErr(file.Flush()) + updateErr(file.Sync()) + } + } + + return firstErr +} + +// Names returns the names of the log files holding the FATAL, ERROR, +// WARNING, or INFO logs. Returns ErrNoLog if the log for the given +// level doesn't exist (e.g. because no messages of that level have been +// written). This may return multiple names if the log type requested +// has rolled over. +func Names(s string) ([]string, error) { + severity, err := logsink.ParseSeverity(s) + if err != nil { + return nil, err + } + + sinks.file.mu.Lock() + defer sinks.file.mu.Unlock() + f := sinks.file.file[severity] + if f == nil { + return nil, ErrNoLog + } + + return f.filenames(), nil +} diff --git a/vendor/github.com/golang/glog/glog_file_linux.go b/vendor/github.com/golang/glog/glog_file_linux.go new file mode 100644 index 00000000000..d795092d03a --- /dev/null +++ b/vendor/github.com/golang/glog/glog_file_linux.go @@ -0,0 +1,39 @@ +// Go support for leveled logs, analogous to https://github.com/google/glog. +// +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package glog + +import ( + "errors" + "runtime" + "syscall" +) + +// abortProcess attempts to kill the current process in a way that will dump the +// currently-running goroutines someplace useful (like stderr). +// +// It does this by sending SIGABRT to the current thread. +// +// If successful, abortProcess does not return. +func abortProcess() error { + runtime.LockOSThread() + if err := syscall.Tgkill(syscall.Getpid(), syscall.Gettid(), syscall.SIGABRT); err != nil { + return err + } + return errors.New("log: killed current thread with SIGABRT, but still running") +} diff --git a/vendor/github.com/golang/glog/glog_file_other.go b/vendor/github.com/golang/glog/glog_file_other.go new file mode 100644 index 00000000000..9540f14fc08 --- /dev/null +++ b/vendor/github.com/golang/glog/glog_file_other.go @@ -0,0 +1,30 @@ +// Go support for leveled logs, analogous to https://github.com/google/glog. +// +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !(unix || windows) + +package glog + +import ( + "fmt" + "runtime" +) + +// abortProcess returns an error on platforms that presumably don't support signals. +func abortProcess() error { + return fmt.Errorf("not sending SIGABRT (%s/%s does not support signals), falling back", runtime.GOOS, runtime.GOARCH) + +} diff --git a/vendor/github.com/golang/glog/glog_file_posix.go b/vendor/github.com/golang/glog/glog_file_posix.go new file mode 100644 index 00000000000..c27c7c0e4ab --- /dev/null +++ b/vendor/github.com/golang/glog/glog_file_posix.go @@ -0,0 +1,53 @@ +// Go support for leveled logs, analogous to https://github.com/google/glog. +// +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build (unix || windows) && !linux + +package glog + +import ( + "os" + "syscall" + "time" +) + +// abortProcess attempts to kill the current process in a way that will dump the +// currently-running goroutines someplace useful (like stderr). +// +// It does this by sending SIGABRT to the current process. Unfortunately, the +// signal may or may not be delivered to the current thread; in order to do that +// portably, we would need to add a cgo dependency and call pthread_kill. +// +// If successful, abortProcess does not return. +func abortProcess() error { + p, err := os.FindProcess(os.Getpid()) + if err != nil { + return err + } + if err := p.Signal(syscall.SIGABRT); err != nil { + return err + } + + // Sent the signal. Now we wait for it to arrive and any SIGABRT handlers to + // run (and eventually terminate the process themselves). + // + // We could just "select{}" here, but there's an outside chance that would + // trigger the runtime's deadlock detector if there happen not to be any + // background goroutines running. So we'll sleep a while first to give + // the signal some time. + time.Sleep(10 * time.Second) + select {} +} diff --git a/vendor/github.com/golang/glog/glog_flags.go b/vendor/github.com/golang/glog/glog_flags.go new file mode 100644 index 00000000000..fa4371afd32 --- /dev/null +++ b/vendor/github.com/golang/glog/glog_flags.go @@ -0,0 +1,398 @@ +// Go support for leveled logs, analogous to https://github.com/google/glog. +// +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package glog + +import ( + "bytes" + "errors" + "flag" + "fmt" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + + "github.com/golang/glog/internal/logsink" +) + +// modulePat contains a filter for the -vmodule flag. +// It holds a verbosity level and a file pattern to match. +type modulePat struct { + pattern string + literal bool // The pattern is a literal string + full bool // The pattern wants to match the full path + level Level +} + +// match reports whether the file matches the pattern. It uses a string +// comparison if the pattern contains no metacharacters. +func (m *modulePat) match(full, file string) bool { + if m.literal { + if m.full { + return full == m.pattern + } + return file == m.pattern + } + if m.full { + match, _ := filepath.Match(m.pattern, full) + return match + } + match, _ := filepath.Match(m.pattern, file) + return match +} + +// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters +// that require filepath.Match to be called to match the pattern. +func isLiteral(pattern string) bool { + return !strings.ContainsAny(pattern, `\*?[]`) +} + +// isFull reports whether the pattern matches the full file path, that is, +// whether it contains /. +func isFull(pattern string) bool { + return strings.ContainsRune(pattern, '/') +} + +// verboseFlags represents the setting of the -v and -vmodule flags. +type verboseFlags struct { + // moduleLevelCache is a sync.Map storing the -vmodule Level for each V() + // call site, identified by PC. If there is no matching -vmodule filter, + // the cached value is exactly v. moduleLevelCache is replaced with a new + // Map whenever the -vmodule or -v flag changes state. + moduleLevelCache atomic.Value + + // mu guards all fields below. + mu sync.Mutex + + // v stores the value of the -v flag. It may be read safely using + // sync.LoadInt32, but is only modified under mu. + v Level + + // module stores the parsed -vmodule flag. + module []modulePat + + // moduleLength caches len(module). If greater than zero, it + // means vmodule is enabled. It may be read safely using sync.LoadInt32, but + // is only modified under mu. + moduleLength int32 +} + +// NOTE: For compatibility with the open-sourced v1 version of this +// package (github.com/golang/glog) we need to retain that flag.Level +// implements the flag.Value interface. See also go/log-vs-glog. + +// String is part of the flag.Value interface. +func (l *Level) String() string { + return strconv.FormatInt(int64(l.Get().(Level)), 10) +} + +// Get is part of the flag.Value interface. +func (l *Level) Get() any { + if l == &vflags.v { + // l is the value registered for the -v flag. + return Level(atomic.LoadInt32((*int32)(l))) + } + return *l +} + +// Set is part of the flag.Value interface. +func (l *Level) Set(value string) error { + v, err := strconv.Atoi(value) + if err != nil { + return err + } + if l == &vflags.v { + // l is the value registered for the -v flag. + vflags.mu.Lock() + defer vflags.mu.Unlock() + vflags.moduleLevelCache.Store(&sync.Map{}) + atomic.StoreInt32((*int32)(l), int32(v)) + return nil + } + *l = Level(v) + return nil +} + +// vModuleFlag is the flag.Value for the --vmodule flag. +type vModuleFlag struct{ *verboseFlags } + +func (f vModuleFlag) String() string { + // Do not panic on the zero value. + // https://groups.google.com/g/golang-nuts/c/Atlr8uAjn6U/m/iId17Td5BQAJ. + if f.verboseFlags == nil { + return "" + } + f.mu.Lock() + defer f.mu.Unlock() + + var b bytes.Buffer + for i, f := range f.module { + if i > 0 { + b.WriteRune(',') + } + fmt.Fprintf(&b, "%s=%d", f.pattern, f.level) + } + return b.String() +} + +// Get returns nil for this flag type since the struct is not exported. +func (f vModuleFlag) Get() any { return nil } + +var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N") + +// Syntax: -vmodule=recordio=2,foo/bar/baz=1,gfs*=3 +func (f vModuleFlag) Set(value string) error { + var filter []modulePat + for _, pat := range strings.Split(value, ",") { + if len(pat) == 0 { + // Empty strings such as from a trailing comma can be ignored. + continue + } + patLev := strings.Split(pat, "=") + if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 { + return errVmoduleSyntax + } + pattern := patLev[0] + v, err := strconv.Atoi(patLev[1]) + if err != nil { + return errors.New("syntax error: expect comma-separated list of filename=N") + } + // TODO: check syntax of filter? + filter = append(filter, modulePat{pattern, isLiteral(pattern), isFull(pattern), Level(v)}) + } + + f.mu.Lock() + defer f.mu.Unlock() + f.module = filter + atomic.StoreInt32((*int32)(&f.moduleLength), int32(len(f.module))) + f.moduleLevelCache.Store(&sync.Map{}) + return nil +} + +func (f *verboseFlags) levelForPC(pc uintptr) Level { + if level, ok := f.moduleLevelCache.Load().(*sync.Map).Load(pc); ok { + return level.(Level) + } + + f.mu.Lock() + defer f.mu.Unlock() + level := Level(f.v) + fn := runtime.FuncForPC(pc) + file, _ := fn.FileLine(pc) + // The file is something like /a/b/c/d.go. We want just the d for + // regular matches, /a/b/c/d for full matches. + file = strings.TrimSuffix(file, ".go") + full := file + if slash := strings.LastIndex(file, "/"); slash >= 0 { + file = file[slash+1:] + } + for _, filter := range f.module { + if filter.match(full, file) { + level = filter.level + break // Use the first matching level. + } + } + f.moduleLevelCache.Load().(*sync.Map).Store(pc, level) + return level +} + +func (f *verboseFlags) enabled(callerDepth int, level Level) bool { + if atomic.LoadInt32(&f.moduleLength) == 0 { + // No vmodule values specified, so compare against v level. + return Level(atomic.LoadInt32((*int32)(&f.v))) >= level + } + + pcs := [1]uintptr{} + if runtime.Callers(callerDepth+2, pcs[:]) < 1 { + return false + } + frame, _ := runtime.CallersFrames(pcs[:]).Next() + return f.levelForPC(frame.Entry) >= level +} + +// traceLocation represents an entry in the -log_backtrace_at flag. +type traceLocation struct { + file string + line int +} + +var errTraceSyntax = errors.New("syntax error: expect file.go:234") + +func parseTraceLocation(value string) (traceLocation, error) { + fields := strings.Split(value, ":") + if len(fields) != 2 { + return traceLocation{}, errTraceSyntax + } + file, lineStr := fields[0], fields[1] + if !strings.Contains(file, ".") { + return traceLocation{}, errTraceSyntax + } + line, err := strconv.Atoi(lineStr) + if err != nil { + return traceLocation{}, errTraceSyntax + } + if line < 0 { + return traceLocation{}, errors.New("negative value for line") + } + return traceLocation{file, line}, nil +} + +// match reports whether the specified file and line matches the trace location. +// The argument file name is the full path, not the basename specified in the flag. +func (t traceLocation) match(file string, line int) bool { + if t.line != line { + return false + } + if i := strings.LastIndex(file, "/"); i >= 0 { + file = file[i+1:] + } + return t.file == file +} + +func (t traceLocation) String() string { + return fmt.Sprintf("%s:%d", t.file, t.line) +} + +// traceLocations represents the -log_backtrace_at flag. +// Syntax: -log_backtrace_at=recordio.go:234,sstable.go:456 +// Note that unlike vmodule the file extension is included here. +type traceLocations struct { + mu sync.Mutex + locsLen int32 // Safe for atomic read without mu. + locs []traceLocation +} + +func (t *traceLocations) String() string { + t.mu.Lock() + defer t.mu.Unlock() + + var buf bytes.Buffer + for i, tl := range t.locs { + if i > 0 { + buf.WriteString(",") + } + buf.WriteString(tl.String()) + } + return buf.String() +} + +// Get always returns nil for this flag type since the struct is not exported +func (t *traceLocations) Get() any { return nil } + +func (t *traceLocations) Set(value string) error { + var locs []traceLocation + for _, s := range strings.Split(value, ",") { + if s == "" { + continue + } + loc, err := parseTraceLocation(s) + if err != nil { + return err + } + locs = append(locs, loc) + } + + t.mu.Lock() + defer t.mu.Unlock() + atomic.StoreInt32(&t.locsLen, int32(len(locs))) + t.locs = locs + return nil +} + +func (t *traceLocations) match(file string, line int) bool { + if atomic.LoadInt32(&t.locsLen) == 0 { + return false + } + + t.mu.Lock() + defer t.mu.Unlock() + for _, tl := range t.locs { + if tl.match(file, line) { + return true + } + } + return false +} + +// severityFlag is an atomic flag.Value implementation for logsink.Severity. +type severityFlag int32 + +func (s *severityFlag) get() logsink.Severity { + return logsink.Severity(atomic.LoadInt32((*int32)(s))) +} +func (s *severityFlag) String() string { return strconv.FormatInt(int64(*s), 10) } +func (s *severityFlag) Get() any { return s.get() } +func (s *severityFlag) Set(value string) error { + threshold, err := logsink.ParseSeverity(value) + if err != nil { + // Not a severity name. Try a raw number. + v, err := strconv.Atoi(value) + if err != nil { + return err + } + threshold = logsink.Severity(v) + if threshold < logsink.Info || threshold > logsink.Fatal { + return fmt.Errorf("Severity %d out of range (min %d, max %d).", v, logsink.Info, logsink.Fatal) + } + } + atomic.StoreInt32((*int32)(s), int32(threshold)) + return nil +} + +var ( + vflags verboseFlags // The -v and -vmodule flags. + + logBacktraceAt traceLocations // The -log_backtrace_at flag. + + // Boolean flags. Not handled atomically because the flag.Value interface + // does not let us avoid the =true, and that shorthand is necessary for + // compatibility. TODO: does this matter enough to fix? Seems unlikely. + toStderr bool // The -logtostderr flag. + alsoToStderr bool // The -alsologtostderr flag. + + stderrThreshold severityFlag // The -stderrthreshold flag. +) + +// verboseEnabled returns whether the caller at the given depth should emit +// verbose logs at the given level, with depth 0 identifying the caller of +// verboseEnabled. +func verboseEnabled(callerDepth int, level Level) bool { + return vflags.enabled(callerDepth+1, level) +} + +// backtraceAt returns whether the logging call at the given function and line +// should also emit a backtrace of the current call stack. +func backtraceAt(file string, line int) bool { + return logBacktraceAt.match(file, line) +} + +func init() { + vflags.moduleLevelCache.Store(&sync.Map{}) + + flag.Var(&vflags.v, "v", "log level for V logs") + flag.Var(vModuleFlag{&vflags}, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") + + flag.Var(&logBacktraceAt, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") + + stderrThreshold = severityFlag(logsink.Error) + + flag.BoolVar(&toStderr, "logtostderr", false, "log to standard error instead of files") + flag.BoolVar(&alsoToStderr, "alsologtostderr", false, "log to standard error as well as files") + flag.Var(&stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr") +} diff --git a/vendor/github.com/golang/glog/internal/logsink/logsink.go b/vendor/github.com/golang/glog/internal/logsink/logsink.go new file mode 100644 index 00000000000..53758e1c9f5 --- /dev/null +++ b/vendor/github.com/golang/glog/internal/logsink/logsink.go @@ -0,0 +1,387 @@ +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logsink + +import ( + "bytes" + "fmt" + "strconv" + "strings" + "sync" + "time" + + "github.com/golang/glog/internal/stackdump" +) + +// MaxLogMessageLen is the limit on length of a formatted log message, including +// the standard line prefix and trailing newline. +// +// Chosen to match C++ glog. +const MaxLogMessageLen = 15000 + +// A Severity is a severity at which a message can be logged. +type Severity int8 + +// These constants identify the log levels in order of increasing severity. +// A message written to a high-severity log file is also written to each +// lower-severity log file. +const ( + Info Severity = iota + Warning + Error + + // Fatal contains logs written immediately before the process terminates. + // + // Sink implementations should not terminate the process themselves: the log + // package will perform any necessary cleanup and terminate the process as + // appropriate. + Fatal +) + +func (s Severity) String() string { + switch s { + case Info: + return "INFO" + case Warning: + return "WARNING" + case Error: + return "ERROR" + case Fatal: + return "FATAL" + } + return fmt.Sprintf("%T(%d)", s, s) +} + +// ParseSeverity returns the case-insensitive Severity value for the given string. +func ParseSeverity(name string) (Severity, error) { + name = strings.ToUpper(name) + for s := Info; s <= Fatal; s++ { + if s.String() == name { + return s, nil + } + } + return -1, fmt.Errorf("logsink: invalid severity %q", name) +} + +// Meta is metadata about a logging call. +type Meta struct { + // Time is the time at which the log call was made. + Time time.Time + + // File is the source file from which the log entry originates. + File string + // Line is the line offset within the source file. + Line int + // Depth is the number of stack frames between the logsink and the log call. + Depth int + + Severity Severity + + // Verbose indicates whether the call was made via "log.V". Log entries below + // the current verbosity threshold are not sent to the sink. + Verbose bool + + // Thread ID. This can be populated with a thread ID from another source, + // such as a system we are importing logs from. In the normal case, this + // will be set to the process ID (PID), since Go doesn't have threads. + Thread int64 + + // Stack trace starting in the logging function. May be nil. + // A logsink should implement the StackWanter interface to request this. + // + // Even if WantStack returns false, this field may be set (e.g. if another + // sink wants a stack trace). + Stack *stackdump.Stack +} + +// Structured is a logging destination that accepts structured data as input. +type Structured interface { + // Printf formats according to a fmt.Printf format specifier and writes a log + // entry. The precise result of formatting depends on the sink, but should + // aim for consistency with fmt.Printf. + // + // Printf returns the number of bytes occupied by the log entry, which + // may not be equal to the total number of bytes written. + // + // Printf returns any error encountered *if* it is severe enough that the log + // package should terminate the process. + // + // The sink must not modify the *Meta parameter, nor reference it after + // Printf has returned: it may be reused in subsequent calls. + Printf(meta *Meta, format string, a ...any) (n int, err error) +} + +// StackWanter can be implemented by a logsink.Structured to indicate that it +// wants a stack trace to accompany at least some of the log messages it receives. +type StackWanter interface { + // WantStack returns true if the sink requires a stack trace for a log message + // with this metadata. + // + // NOTE: Returning true implies that meta.Stack will be non-nil. Returning + // false does NOT imply that meta.Stack will be nil. + WantStack(meta *Meta) bool +} + +// Text is a logging destination that accepts pre-formatted log lines (instead of +// structured data). +type Text interface { + // Enabled returns whether this sink should output messages for the given + // Meta. If the sink returns false for a given Meta, the Printf function will + // not call Emit on it for the corresponding log message. + Enabled(*Meta) bool + + // Emit writes a pre-formatted text log entry (including any applicable + // header) to the log. It returns the number of bytes occupied by the entry + // (which may differ from the length of the passed-in slice). + // + // Emit returns any error encountered *if* it is severe enough that the log + // package should terminate the process. + // + // The sink must not modify the *Meta parameter, nor reference it after + // Printf has returned: it may be reused in subsequent calls. + // + // NOTE: When developing a text sink, keep in mind the surface in which the + // logs will be displayed, and whether it's important that the sink be + // resistent to tampering in the style of b/211428300. Standard text sinks + // (like `stderrSink`) do not protect against this (e.g. by escaping + // characters) because the cases where they would show user-influenced bytes + // are vanishingly small. + Emit(*Meta, []byte) (n int, err error) +} + +// bufs is a pool of *bytes.Buffer used in formatting log entries. +var bufs sync.Pool // Pool of *bytes.Buffer. + +// textPrintf formats a text log entry and emits it to all specified Text sinks. +// +// The returned n is the maximum across all Emit calls. +// The returned err is the first non-nil error encountered. +// Sinks that are disabled by configuration should return (0, nil). +func textPrintf(m *Meta, textSinks []Text, format string, args ...any) (n int, err error) { + // We expect at most file, stderr, and perhaps syslog. If there are more, + // we'll end up allocating - no big deal. + const maxExpectedTextSinks = 3 + var noAllocSinks [maxExpectedTextSinks]Text + + sinks := noAllocSinks[:0] + for _, s := range textSinks { + if s.Enabled(m) { + sinks = append(sinks, s) + } + } + if len(sinks) == 0 && m.Severity != Fatal { + return 0, nil // No TextSinks specified; don't bother formatting. + } + + bufi := bufs.Get() + var buf *bytes.Buffer + if bufi == nil { + buf = bytes.NewBuffer(nil) + bufi = buf + } else { + buf = bufi.(*bytes.Buffer) + buf.Reset() + } + + // Lmmdd hh:mm:ss.uuuuuu PID/GID file:line] + // + // The "PID" entry arguably ought to be TID for consistency with other + // environments, but TID is not meaningful in a Go program due to the + // multiplexing of goroutines across threads. + // + // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. + // It's worth about 3X. Fprintf is hard. + const severityChar = "IWEF" + buf.WriteByte(severityChar[m.Severity]) + + _, month, day := m.Time.Date() + hour, minute, second := m.Time.Clock() + twoDigits(buf, int(month)) + twoDigits(buf, day) + buf.WriteByte(' ') + twoDigits(buf, hour) + buf.WriteByte(':') + twoDigits(buf, minute) + buf.WriteByte(':') + twoDigits(buf, second) + buf.WriteByte('.') + nDigits(buf, 6, uint64(m.Time.Nanosecond()/1000), '0') + buf.WriteByte(' ') + + nDigits(buf, 7, uint64(m.Thread), ' ') + buf.WriteByte(' ') + + { + file := m.File + if i := strings.LastIndex(file, "/"); i >= 0 { + file = file[i+1:] + } + buf.WriteString(file) + } + + buf.WriteByte(':') + { + var tmp [19]byte + buf.Write(strconv.AppendInt(tmp[:0], int64(m.Line), 10)) + } + buf.WriteString("] ") + + msgStart := buf.Len() + fmt.Fprintf(buf, format, args...) + if buf.Len() > MaxLogMessageLen-1 { + buf.Truncate(MaxLogMessageLen - 1) + } + msgEnd := buf.Len() + if b := buf.Bytes(); b[len(b)-1] != '\n' { + buf.WriteByte('\n') + } + + for _, s := range sinks { + sn, sErr := s.Emit(m, buf.Bytes()) + if sn > n { + n = sn + } + if sErr != nil && err == nil { + err = sErr + } + } + + if m.Severity == Fatal { + savedM := *m + fatalMessageStore(savedEntry{ + meta: &savedM, + msg: buf.Bytes()[msgStart:msgEnd], + }) + } else { + bufs.Put(bufi) + } + return n, err +} + +const digits = "0123456789" + +// twoDigits formats a zero-prefixed two-digit integer to buf. +func twoDigits(buf *bytes.Buffer, d int) { + buf.WriteByte(digits[(d/10)%10]) + buf.WriteByte(digits[d%10]) +} + +// nDigits formats an n-digit integer to buf, padding with pad on the left. It +// assumes d != 0. +func nDigits(buf *bytes.Buffer, n int, d uint64, pad byte) { + var tmp [20]byte + + cutoff := len(tmp) - n + j := len(tmp) - 1 + for ; d > 0; j-- { + tmp[j] = digits[d%10] + d /= 10 + } + for ; j >= cutoff; j-- { + tmp[j] = pad + } + j++ + buf.Write(tmp[j:]) +} + +// Printf writes a log entry to all registered TextSinks in this package, then +// to all registered StructuredSinks. +// +// The returned n is the maximum across all Emit and Printf calls. +// The returned err is the first non-nil error encountered. +// Sinks that are disabled by configuration should return (0, nil). +func Printf(m *Meta, format string, args ...any) (n int, err error) { + m.Depth++ + n, err = textPrintf(m, TextSinks, format, args...) + + for _, sink := range StructuredSinks { + // TODO: Support TextSinks that implement StackWanter? + if sw, ok := sink.(StackWanter); ok && sw.WantStack(m) { + if m.Stack == nil { + // First, try to find a stacktrace in args, otherwise generate one. + for _, arg := range args { + if stack, ok := arg.(stackdump.Stack); ok { + m.Stack = &stack + break + } + } + if m.Stack == nil { + stack := stackdump.Caller( /* skipDepth = */ m.Depth) + m.Stack = &stack + } + } + } + sn, sErr := sink.Printf(m, format, args...) + if sn > n { + n = sn + } + if sErr != nil && err == nil { + err = sErr + } + } + return n, err +} + +// The sets of sinks to which logs should be written. +// +// These must only be modified during package init, and are read-only thereafter. +var ( + // StructuredSinks is the set of Structured sink instances to which logs + // should be written. + StructuredSinks []Structured + + // TextSinks is the set of Text sink instances to which logs should be + // written. + // + // These are registered separately from Structured sink implementations to + // avoid the need to repeat the work of formatting a message for each Text + // sink that writes it. The package-level Printf function writes to both sets + // independenty, so a given log destination should only register a Structured + // *or* a Text sink (not both). + TextSinks []Text +) + +type savedEntry struct { + meta *Meta + msg []byte +} + +// StructuredTextWrapper is a Structured sink which forwards logs to a set of Text sinks. +// +// The purpose of this sink is to allow applications to intercept logging calls before they are +// serialized and sent to Text sinks. For example, if one needs to redact PII from logging +// arguments before they reach STDERR, one solution would be to do the redacting in a Structured +// sink that forwards logs to a StructuredTextWrapper instance, and make STDERR a child of that +// StructuredTextWrapper instance. This is how one could set this up in their application: +// +// func init() { +// +// wrapper := logsink.StructuredTextWrapper{TextSinks: logsink.TextSinks} +// // sanitizersink will intercept logs and remove PII +// sanitizer := sanitizersink{Sink: &wrapper} +// logsink.StructuredSinks = append(logsink.StructuredSinks, &sanitizer) +// logsink.TextSinks = nil +// +// } +type StructuredTextWrapper struct { + // TextSinks is the set of Text sinks that should receive logs from this + // StructuredTextWrapper instance. + TextSinks []Text +} + +// Printf forwards logs to all Text sinks registered in the StructuredTextWrapper. +func (w *StructuredTextWrapper) Printf(meta *Meta, format string, args ...any) (n int, err error) { + return textPrintf(meta, w.TextSinks, format, args...) +} diff --git a/vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go b/vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go new file mode 100644 index 00000000000..3dc269abc21 --- /dev/null +++ b/vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go @@ -0,0 +1,35 @@ +package logsink + +import ( + "sync/atomic" + "unsafe" +) + +func fatalMessageStore(e savedEntry) { + // Only put a new one in if we haven't assigned before. + atomic.CompareAndSwapPointer(&fatalMessage, nil, unsafe.Pointer(&e)) +} + +var fatalMessage unsafe.Pointer // savedEntry stored with CompareAndSwapPointer + +// FatalMessage returns the Meta and message contents of the first message +// logged with Fatal severity, or false if none has occurred. +func FatalMessage() (*Meta, []byte, bool) { + e := (*savedEntry)(atomic.LoadPointer(&fatalMessage)) + if e == nil { + return nil, nil, false + } + return e.meta, e.msg, true +} + +// DoNotUseRacyFatalMessage is FatalMessage, but worse. +// +//go:norace +//go:nosplit +func DoNotUseRacyFatalMessage() (*Meta, []byte, bool) { + e := (*savedEntry)(fatalMessage) + if e == nil { + return nil, nil, false + } + return e.meta, e.msg, true +} diff --git a/vendor/github.com/golang/glog/internal/stackdump/stackdump.go b/vendor/github.com/golang/glog/internal/stackdump/stackdump.go new file mode 100644 index 00000000000..3427c9d6bd0 --- /dev/null +++ b/vendor/github.com/golang/glog/internal/stackdump/stackdump.go @@ -0,0 +1,127 @@ +// Copyright 2023 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package stackdump provides wrappers for runtime.Stack and runtime.Callers +// with uniform support for skipping caller frames. +// +// ⚠ Unlike the functions in the runtime package, these may allocate a +// non-trivial quantity of memory: use them with care. ⚠ +package stackdump + +import ( + "bytes" + "runtime" +) + +// runtimeStackSelfFrames is 1 if runtime.Stack includes the call to +// runtime.Stack itself or 0 if it does not. +// +// As of 2016-04-27, the gccgo compiler includes runtime.Stack but the gc +// compiler does not. +var runtimeStackSelfFrames = func() int { + for n := 1 << 10; n < 1<<20; n *= 2 { + buf := make([]byte, n) + n := runtime.Stack(buf, false) + if bytes.Contains(buf[:n], []byte("runtime.Stack")) { + return 1 + } else if n < len(buf) || bytes.Count(buf, []byte("\n")) >= 3 { + return 0 + } + } + return 0 +}() + +// Stack is a stack dump for a single goroutine. +type Stack struct { + // Text is a representation of the stack dump in a human-readable format. + Text []byte + + // PC is a representation of the stack dump using raw program counter values. + PC []uintptr +} + +func (s Stack) String() string { return string(s.Text) } + +// Caller returns the Stack dump for the calling goroutine, starting skipDepth +// frames before the caller of Caller. (Caller(0) provides a dump starting at +// the caller of this function.) +func Caller(skipDepth int) Stack { + return Stack{ + Text: CallerText(skipDepth + 1), + PC: CallerPC(skipDepth + 1), + } +} + +// CallerText returns a textual dump of the stack starting skipDepth frames before +// the caller. (CallerText(0) provides a dump starting at the caller of this +// function.) +func CallerText(skipDepth int) []byte { + for n := 1 << 10; ; n *= 2 { + buf := make([]byte, n) + n := runtime.Stack(buf, false) + if n < len(buf) { + return pruneFrames(skipDepth+1+runtimeStackSelfFrames, buf[:n]) + } + } +} + +// CallerPC returns a dump of the program counters of the stack starting +// skipDepth frames before the caller. (CallerPC(0) provides a dump starting at +// the caller of this function.) +func CallerPC(skipDepth int) []uintptr { + for n := 1 << 8; ; n *= 2 { + buf := make([]uintptr, n) + n := runtime.Callers(skipDepth+2, buf) + if n < len(buf) { + return buf[:n] + } + } +} + +// pruneFrames removes the topmost skipDepth frames of the first goroutine in a +// textual stack dump. It overwrites the passed-in slice. +// +// If there are fewer than skipDepth frames in the first goroutine's stack, +// pruneFrames prunes it to an empty stack and leaves the remaining contents +// intact. +func pruneFrames(skipDepth int, stack []byte) []byte { + headerLen := 0 + for i, c := range stack { + if c == '\n' { + headerLen = i + 1 + break + } + } + if headerLen == 0 { + return stack // No header line - not a well-formed stack trace. + } + + skipLen := headerLen + skipNewlines := skipDepth * 2 + for ; skipLen < len(stack) && skipNewlines > 0; skipLen++ { + c := stack[skipLen] + if c != '\n' { + continue + } + skipNewlines-- + skipLen++ + if skipNewlines == 0 || skipLen == len(stack) || stack[skipLen] == '\n' { + break + } + } + + pruned := stack[skipLen-headerLen:] + copy(pruned, stack[:headerLen]) + return pruned +} diff --git a/vendor/github.com/golang/protobuf/descriptor/descriptor.go b/vendor/github.com/golang/protobuf/descriptor/descriptor.go deleted file mode 100644 index ffde8a65081..00000000000 --- a/vendor/github.com/golang/protobuf/descriptor/descriptor.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package descriptor provides functions for obtaining the protocol buffer -// descriptors of generated Go types. -// -// Deprecated: See the "google.golang.org/protobuf/reflect/protoreflect" package -// for how to obtain an EnumDescriptor or MessageDescriptor in order to -// programatically interact with the protobuf type system. -package descriptor - -import ( - "bytes" - "compress/gzip" - "io/ioutil" - "sync" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protodesc" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoimpl" - - descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" -) - -// Message is proto.Message with a method to return its descriptor. -// -// Deprecated: The Descriptor method may not be generated by future -// versions of protoc-gen-go, meaning that this interface may not -// be implemented by many concrete message types. -type Message interface { - proto.Message - Descriptor() ([]byte, []int) -} - -// ForMessage returns the file descriptor proto containing -// the message and the message descriptor proto for the message itself. -// The returned proto messages must not be mutated. -// -// Deprecated: Not all concrete message types satisfy the Message interface. -// Use MessageDescriptorProto instead. If possible, the calling code should -// be rewritten to use protobuf reflection instead. -// See package "google.golang.org/protobuf/reflect/protoreflect" for details. -func ForMessage(m Message) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { - return MessageDescriptorProto(m) -} - -type rawDesc struct { - fileDesc []byte - indexes []int -} - -var rawDescCache sync.Map // map[protoreflect.Descriptor]*rawDesc - -func deriveRawDescriptor(d protoreflect.Descriptor) ([]byte, []int) { - // Fast-path: check whether raw descriptors are already cached. - origDesc := d - if v, ok := rawDescCache.Load(origDesc); ok { - return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes - } - - // Slow-path: derive the raw descriptor from the v2 descriptor. - - // Start with the leaf (a given enum or message declaration) and - // ascend upwards until we hit the parent file descriptor. - var idxs []int - for { - idxs = append(idxs, d.Index()) - d = d.Parent() - if d == nil { - // TODO: We could construct a FileDescriptor stub for standalone - // descriptors to satisfy the API. - return nil, nil - } - if _, ok := d.(protoreflect.FileDescriptor); ok { - break - } - } - - // Obtain the raw file descriptor. - fd := d.(protoreflect.FileDescriptor) - b, _ := proto.Marshal(protodesc.ToFileDescriptorProto(fd)) - file := protoimpl.X.CompressGZIP(b) - - // Reverse the indexes, since we populated it in reverse. - for i, j := 0, len(idxs)-1; i < j; i, j = i+1, j-1 { - idxs[i], idxs[j] = idxs[j], idxs[i] - } - - if v, ok := rawDescCache.LoadOrStore(origDesc, &rawDesc{file, idxs}); ok { - return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes - } - return file, idxs -} - -// EnumRawDescriptor returns the GZIP'd raw file descriptor representing -// the enum and the index path to reach the enum declaration. -// The returned slices must not be mutated. -func EnumRawDescriptor(e proto.GeneratedEnum) ([]byte, []int) { - if ev, ok := e.(interface{ EnumDescriptor() ([]byte, []int) }); ok { - return ev.EnumDescriptor() - } - ed := protoimpl.X.EnumTypeOf(e) - return deriveRawDescriptor(ed.Descriptor()) -} - -// MessageRawDescriptor returns the GZIP'd raw file descriptor representing -// the message and the index path to reach the message declaration. -// The returned slices must not be mutated. -func MessageRawDescriptor(m proto.GeneratedMessage) ([]byte, []int) { - if mv, ok := m.(interface{ Descriptor() ([]byte, []int) }); ok { - return mv.Descriptor() - } - md := protoimpl.X.MessageTypeOf(m) - return deriveRawDescriptor(md.Descriptor()) -} - -var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto - -func deriveFileDescriptor(rawDesc []byte) *descriptorpb.FileDescriptorProto { - // Fast-path: check whether descriptor protos are already cached. - if v, ok := fileDescCache.Load(&rawDesc[0]); ok { - return v.(*descriptorpb.FileDescriptorProto) - } - - // Slow-path: derive the descriptor proto from the GZIP'd message. - zr, err := gzip.NewReader(bytes.NewReader(rawDesc)) - if err != nil { - panic(err) - } - b, err := ioutil.ReadAll(zr) - if err != nil { - panic(err) - } - fd := new(descriptorpb.FileDescriptorProto) - if err := proto.Unmarshal(b, fd); err != nil { - panic(err) - } - if v, ok := fileDescCache.LoadOrStore(&rawDesc[0], fd); ok { - return v.(*descriptorpb.FileDescriptorProto) - } - return fd -} - -// EnumDescriptorProto returns the file descriptor proto representing -// the enum and the enum descriptor proto for the enum itself. -// The returned proto messages must not be mutated. -func EnumDescriptorProto(e proto.GeneratedEnum) (*descriptorpb.FileDescriptorProto, *descriptorpb.EnumDescriptorProto) { - rawDesc, idxs := EnumRawDescriptor(e) - if rawDesc == nil || idxs == nil { - return nil, nil - } - fd := deriveFileDescriptor(rawDesc) - if len(idxs) == 1 { - return fd, fd.EnumType[idxs[0]] - } - md := fd.MessageType[idxs[0]] - for _, i := range idxs[1 : len(idxs)-1] { - md = md.NestedType[i] - } - ed := md.EnumType[idxs[len(idxs)-1]] - return fd, ed -} - -// MessageDescriptorProto returns the file descriptor proto representing -// the message and the message descriptor proto for the message itself. -// The returned proto messages must not be mutated. -func MessageDescriptorProto(m proto.GeneratedMessage) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { - rawDesc, idxs := MessageRawDescriptor(m) - if rawDesc == nil || idxs == nil { - return nil, nil - } - fd := deriveFileDescriptor(rawDesc) - md := fd.MessageType[idxs[0]] - for _, i := range idxs[1:] { - md = md.NestedType[i] - } - return fd, md -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go index 60e82caa9a2..6c16c255ffb 100644 --- a/vendor/github.com/golang/protobuf/jsonpb/decode.go +++ b/vendor/github.com/golang/protobuf/jsonpb/decode.go @@ -386,8 +386,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error } func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { + if fd.Cardinality() == protoreflect.Repeated { + return false + } if md := fd.Message(); md != nil { - return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated + return md.FullName() == "google.protobuf.Value" + } + if ed := fd.Enum(); ed != nil { + return ed.FullName() == "google.protobuf.NullValue" } return false } diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go deleted file mode 100644 index 63dc0578514..00000000000 --- a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto - -package descriptor - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/descriptor.proto. - -type FieldDescriptorProto_Type = descriptorpb.FieldDescriptorProto_Type - -const FieldDescriptorProto_TYPE_DOUBLE = descriptorpb.FieldDescriptorProto_TYPE_DOUBLE -const FieldDescriptorProto_TYPE_FLOAT = descriptorpb.FieldDescriptorProto_TYPE_FLOAT -const FieldDescriptorProto_TYPE_INT64 = descriptorpb.FieldDescriptorProto_TYPE_INT64 -const FieldDescriptorProto_TYPE_UINT64 = descriptorpb.FieldDescriptorProto_TYPE_UINT64 -const FieldDescriptorProto_TYPE_INT32 = descriptorpb.FieldDescriptorProto_TYPE_INT32 -const FieldDescriptorProto_TYPE_FIXED64 = descriptorpb.FieldDescriptorProto_TYPE_FIXED64 -const FieldDescriptorProto_TYPE_FIXED32 = descriptorpb.FieldDescriptorProto_TYPE_FIXED32 -const FieldDescriptorProto_TYPE_BOOL = descriptorpb.FieldDescriptorProto_TYPE_BOOL -const FieldDescriptorProto_TYPE_STRING = descriptorpb.FieldDescriptorProto_TYPE_STRING -const FieldDescriptorProto_TYPE_GROUP = descriptorpb.FieldDescriptorProto_TYPE_GROUP -const FieldDescriptorProto_TYPE_MESSAGE = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE -const FieldDescriptorProto_TYPE_BYTES = descriptorpb.FieldDescriptorProto_TYPE_BYTES -const FieldDescriptorProto_TYPE_UINT32 = descriptorpb.FieldDescriptorProto_TYPE_UINT32 -const FieldDescriptorProto_TYPE_ENUM = descriptorpb.FieldDescriptorProto_TYPE_ENUM -const FieldDescriptorProto_TYPE_SFIXED32 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED32 -const FieldDescriptorProto_TYPE_SFIXED64 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED64 -const FieldDescriptorProto_TYPE_SINT32 = descriptorpb.FieldDescriptorProto_TYPE_SINT32 -const FieldDescriptorProto_TYPE_SINT64 = descriptorpb.FieldDescriptorProto_TYPE_SINT64 - -var FieldDescriptorProto_Type_name = descriptorpb.FieldDescriptorProto_Type_name -var FieldDescriptorProto_Type_value = descriptorpb.FieldDescriptorProto_Type_value - -type FieldDescriptorProto_Label = descriptorpb.FieldDescriptorProto_Label - -const FieldDescriptorProto_LABEL_OPTIONAL = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL -const FieldDescriptorProto_LABEL_REQUIRED = descriptorpb.FieldDescriptorProto_LABEL_REQUIRED -const FieldDescriptorProto_LABEL_REPEATED = descriptorpb.FieldDescriptorProto_LABEL_REPEATED - -var FieldDescriptorProto_Label_name = descriptorpb.FieldDescriptorProto_Label_name -var FieldDescriptorProto_Label_value = descriptorpb.FieldDescriptorProto_Label_value - -type FileOptions_OptimizeMode = descriptorpb.FileOptions_OptimizeMode - -const FileOptions_SPEED = descriptorpb.FileOptions_SPEED -const FileOptions_CODE_SIZE = descriptorpb.FileOptions_CODE_SIZE -const FileOptions_LITE_RUNTIME = descriptorpb.FileOptions_LITE_RUNTIME - -var FileOptions_OptimizeMode_name = descriptorpb.FileOptions_OptimizeMode_name -var FileOptions_OptimizeMode_value = descriptorpb.FileOptions_OptimizeMode_value - -type FieldOptions_CType = descriptorpb.FieldOptions_CType - -const FieldOptions_STRING = descriptorpb.FieldOptions_STRING -const FieldOptions_CORD = descriptorpb.FieldOptions_CORD -const FieldOptions_STRING_PIECE = descriptorpb.FieldOptions_STRING_PIECE - -var FieldOptions_CType_name = descriptorpb.FieldOptions_CType_name -var FieldOptions_CType_value = descriptorpb.FieldOptions_CType_value - -type FieldOptions_JSType = descriptorpb.FieldOptions_JSType - -const FieldOptions_JS_NORMAL = descriptorpb.FieldOptions_JS_NORMAL -const FieldOptions_JS_STRING = descriptorpb.FieldOptions_JS_STRING -const FieldOptions_JS_NUMBER = descriptorpb.FieldOptions_JS_NUMBER - -var FieldOptions_JSType_name = descriptorpb.FieldOptions_JSType_name -var FieldOptions_JSType_value = descriptorpb.FieldOptions_JSType_value - -type MethodOptions_IdempotencyLevel = descriptorpb.MethodOptions_IdempotencyLevel - -const MethodOptions_IDEMPOTENCY_UNKNOWN = descriptorpb.MethodOptions_IDEMPOTENCY_UNKNOWN -const MethodOptions_NO_SIDE_EFFECTS = descriptorpb.MethodOptions_NO_SIDE_EFFECTS -const MethodOptions_IDEMPOTENT = descriptorpb.MethodOptions_IDEMPOTENT - -var MethodOptions_IdempotencyLevel_name = descriptorpb.MethodOptions_IdempotencyLevel_name -var MethodOptions_IdempotencyLevel_value = descriptorpb.MethodOptions_IdempotencyLevel_value - -type FileDescriptorSet = descriptorpb.FileDescriptorSet -type FileDescriptorProto = descriptorpb.FileDescriptorProto -type DescriptorProto = descriptorpb.DescriptorProto -type ExtensionRangeOptions = descriptorpb.ExtensionRangeOptions -type FieldDescriptorProto = descriptorpb.FieldDescriptorProto -type OneofDescriptorProto = descriptorpb.OneofDescriptorProto -type EnumDescriptorProto = descriptorpb.EnumDescriptorProto -type EnumValueDescriptorProto = descriptorpb.EnumValueDescriptorProto -type ServiceDescriptorProto = descriptorpb.ServiceDescriptorProto -type MethodDescriptorProto = descriptorpb.MethodDescriptorProto - -const Default_MethodDescriptorProto_ClientStreaming = descriptorpb.Default_MethodDescriptorProto_ClientStreaming -const Default_MethodDescriptorProto_ServerStreaming = descriptorpb.Default_MethodDescriptorProto_ServerStreaming - -type FileOptions = descriptorpb.FileOptions - -const Default_FileOptions_JavaMultipleFiles = descriptorpb.Default_FileOptions_JavaMultipleFiles -const Default_FileOptions_JavaStringCheckUtf8 = descriptorpb.Default_FileOptions_JavaStringCheckUtf8 -const Default_FileOptions_OptimizeFor = descriptorpb.Default_FileOptions_OptimizeFor -const Default_FileOptions_CcGenericServices = descriptorpb.Default_FileOptions_CcGenericServices -const Default_FileOptions_JavaGenericServices = descriptorpb.Default_FileOptions_JavaGenericServices -const Default_FileOptions_PyGenericServices = descriptorpb.Default_FileOptions_PyGenericServices -const Default_FileOptions_PhpGenericServices = descriptorpb.Default_FileOptions_PhpGenericServices -const Default_FileOptions_Deprecated = descriptorpb.Default_FileOptions_Deprecated -const Default_FileOptions_CcEnableArenas = descriptorpb.Default_FileOptions_CcEnableArenas - -type MessageOptions = descriptorpb.MessageOptions - -const Default_MessageOptions_MessageSetWireFormat = descriptorpb.Default_MessageOptions_MessageSetWireFormat -const Default_MessageOptions_NoStandardDescriptorAccessor = descriptorpb.Default_MessageOptions_NoStandardDescriptorAccessor -const Default_MessageOptions_Deprecated = descriptorpb.Default_MessageOptions_Deprecated - -type FieldOptions = descriptorpb.FieldOptions - -const Default_FieldOptions_Ctype = descriptorpb.Default_FieldOptions_Ctype -const Default_FieldOptions_Jstype = descriptorpb.Default_FieldOptions_Jstype -const Default_FieldOptions_Lazy = descriptorpb.Default_FieldOptions_Lazy -const Default_FieldOptions_Deprecated = descriptorpb.Default_FieldOptions_Deprecated -const Default_FieldOptions_Weak = descriptorpb.Default_FieldOptions_Weak - -type OneofOptions = descriptorpb.OneofOptions -type EnumOptions = descriptorpb.EnumOptions - -const Default_EnumOptions_Deprecated = descriptorpb.Default_EnumOptions_Deprecated - -type EnumValueOptions = descriptorpb.EnumValueOptions - -const Default_EnumValueOptions_Deprecated = descriptorpb.Default_EnumValueOptions_Deprecated - -type ServiceOptions = descriptorpb.ServiceOptions - -const Default_ServiceOptions_Deprecated = descriptorpb.Default_ServiceOptions_Deprecated - -type MethodOptions = descriptorpb.MethodOptions - -const Default_MethodOptions_Deprecated = descriptorpb.Default_MethodOptions_Deprecated -const Default_MethodOptions_IdempotencyLevel = descriptorpb.Default_MethodOptions_IdempotencyLevel - -type UninterpretedOption = descriptorpb.UninterpretedOption -type SourceCodeInfo = descriptorpb.SourceCodeInfo -type GeneratedCodeInfo = descriptorpb.GeneratedCodeInfo -type DescriptorProto_ExtensionRange = descriptorpb.DescriptorProto_ExtensionRange -type DescriptorProto_ReservedRange = descriptorpb.DescriptorProto_ReservedRange -type EnumDescriptorProto_EnumReservedRange = descriptorpb.EnumDescriptorProto_EnumReservedRange -type UninterpretedOption_NamePart = descriptorpb.UninterpretedOption_NamePart -type SourceCodeInfo_Location = descriptorpb.SourceCodeInfo_Location -type GeneratedCodeInfo_Annotation = descriptorpb.GeneratedCodeInfo_Annotation - -var File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = []byte{ - 0x0a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, - 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x32, -} - -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() } -func file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() { - if File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto = out.File - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = nil - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = nil - file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go new file mode 100644 index 00000000000..16686a65523 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go @@ -0,0 +1,62 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/empty/empty.proto + +package empty + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/empty.proto. + +type Empty = emptypb.Empty + +var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{ + 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() } +func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() { + if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File + file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index b43beedc4bc..e973abfc547 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -8,9 +8,11 @@ go_library( name = "go_default_library", srcs = [ "cel.go", + "decls.go", "env.go", "io.go", "library.go", + "macro.go", "options.go", "program.go", ], @@ -21,6 +23,7 @@ go_library( "//checker/decls:go_default_library", "//common:go_default_library", "//common/containers:go_default_library", + "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", @@ -44,7 +47,10 @@ go_library( go_test( name = "go_default_test", srcs = [ + "cel_example_test.go", "cel_test.go", + "decls_test.go", + "env_test.go", "io_test.go", ], data = [ @@ -54,18 +60,17 @@ go_test( ":go_default_library", ], deps = [ - "//checker/decls:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", - "//interpreter/functions:go_default_library", "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/cel/decls.go b/vendor/github.com/google/cel-go/cel/decls.go new file mode 100644 index 00000000000..f2df721d076 --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/decls.go @@ -0,0 +1,1179 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cel + +import ( + "fmt" + "strings" + + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + "github.com/google/cel-go/interpreter/functions" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Kind indicates a CEL type's kind which is used to differentiate quickly between simple and complex types. +type Kind uint + +const ( + // DynKind represents a dynamic type. This kind only exists at type-check time. + DynKind Kind = iota + + // AnyKind represents a google.protobuf.Any type. This kind only exists at type-check time. + AnyKind + + // BoolKind represents a boolean type. + BoolKind + + // BytesKind represents a bytes type. + BytesKind + + // DoubleKind represents a double type. + DoubleKind + + // DurationKind represents a CEL duration type. + DurationKind + + // IntKind represents an integer type. + IntKind + + // ListKind represents a list type. + ListKind + + // MapKind represents a map type. + MapKind + + // NullTypeKind represents a null type. + NullTypeKind + + // OpaqueKind represents an abstract type which has no accessible fields. + OpaqueKind + + // StringKind represents a string type. + StringKind + + // StructKind represents a structured object with typed fields. + StructKind + + // TimestampKind represents a a CEL time type. + TimestampKind + + // TypeKind represents the CEL type. + TypeKind + + // TypeParamKind represents a parameterized type whose type name will be resolved at type-check time, if possible. + TypeParamKind + + // UintKind represents a uint type. + UintKind +) + +var ( + // AnyType represents the google.protobuf.Any type. + AnyType = &Type{ + kind: AnyKind, + runtimeType: types.NewTypeValue("google.protobuf.Any"), + } + // BoolType represents the bool type. + BoolType = &Type{ + kind: BoolKind, + runtimeType: types.BoolType, + } + // BytesType represents the bytes type. + BytesType = &Type{ + kind: BytesKind, + runtimeType: types.BytesType, + } + // DoubleType represents the double type. + DoubleType = &Type{ + kind: DoubleKind, + runtimeType: types.DoubleType, + } + // DurationType represents the CEL duration type. + DurationType = &Type{ + kind: DurationKind, + runtimeType: types.DurationType, + } + // DynType represents a dynamic CEL type whose type will be determined at runtime from context. + DynType = &Type{ + kind: DynKind, + runtimeType: types.NewTypeValue("dyn"), + } + // IntType represents the int type. + IntType = &Type{ + kind: IntKind, + runtimeType: types.IntType, + } + // NullType represents the type of a null value. + NullType = &Type{ + kind: NullTypeKind, + runtimeType: types.NullType, + } + // StringType represents the string type. + StringType = &Type{ + kind: StringKind, + runtimeType: types.StringType, + } + // TimestampType represents the time type. + TimestampType = &Type{ + kind: TimestampKind, + runtimeType: types.TimestampType, + } + // TypeType represents a CEL type + TypeType = &Type{ + kind: TypeKind, + runtimeType: types.TypeType, + } + //UintType represents a uint type. + UintType = &Type{ + kind: UintKind, + runtimeType: types.UintType, + } +) + +// Type holds a reference to a runtime type with an optional type-checked set of type parameters. +type Type struct { + // kind indicates general category of the type. + kind Kind + + // runtimeType is the runtime type of the declaration. + runtimeType ref.Type + + // parameters holds the optional type-checked set of type parameters that are used during static analysis. + parameters []*Type + + // isAssignableType function determines whether one type is assignable to this type. + // A nil value for the isAssignableType function falls back to equality of kind, runtimeType, and parameters. + isAssignableType func(other *Type) bool + + // isAssignableRuntimeType function determines whether the runtime type (with erasure) is assignable to this type. + // A nil value for the isAssignableRuntimeType function falls back to the equality of the type or type name. + isAssignableRuntimeType func(other ref.Val) bool +} + +// IsAssignableType determines whether the current type is type-check assignable from the input fromType. +func (t *Type) IsAssignableType(fromType *Type) bool { + if t.isAssignableType != nil { + return t.isAssignableType(fromType) + } + return t.defaultIsAssignableType(fromType) +} + +// IsAssignableRuntimeType determines whether the current type is runtime assignable from the input runtimeType. +// +// At runtime, parameterized types are erased and so a function which type-checks to support a map(string, string) +// will have a runtime assignable type of a map. +func (t *Type) IsAssignableRuntimeType(val ref.Val) bool { + if t.isAssignableRuntimeType != nil { + return t.isAssignableRuntimeType(val) + } + return t.defaultIsAssignableRuntimeType(val) +} + +// String returns a human-readable definition of the type name. +func (t *Type) String() string { + if len(t.parameters) == 0 { + return t.runtimeType.TypeName() + } + params := make([]string, len(t.parameters)) + for i, p := range t.parameters { + params[i] = p.String() + } + return fmt.Sprintf("%s(%s)", t.runtimeType.TypeName(), strings.Join(params, ", ")) +} + +// isDyn indicates whether the type is dynamic in any way. +func (t *Type) isDyn() bool { + return t.kind == DynKind || t.kind == AnyKind || t.kind == TypeParamKind +} + +// equals indicates whether two types have the same kind, type name, and parameters. +func (t *Type) equals(other *Type) bool { + if t.kind != other.kind || + t.runtimeType.TypeName() != other.runtimeType.TypeName() || + len(t.parameters) != len(other.parameters) { + return false + } + for i, p := range t.parameters { + if !p.equals(other.parameters[i]) { + return false + } + } + return true +} + +// defaultIsAssignableType provides the standard definition of what it means for one type to be assignable to another +// where any of the following may return a true result: +// - The from types are the same instance +// - The target type is dynamic +// - The fromType has the same kind and type name as the target type, and all parameters of the target type +// are IsAssignableType() from the parameters of the fromType. +func (t *Type) defaultIsAssignableType(fromType *Type) bool { + if t == fromType || t.isDyn() { + return true + } + if t.kind != fromType.kind || + t.runtimeType.TypeName() != fromType.runtimeType.TypeName() || + len(t.parameters) != len(fromType.parameters) { + return false + } + for i, tp := range t.parameters { + fp := fromType.parameters[i] + if !tp.IsAssignableType(fp) { + return false + } + } + return true +} + +// defaultIsAssignableRuntimeType inspects the type and in the case of list and map elements, the key and element types +// to determine whether a ref.Val is assignable to the declared type for a function signature. +func (t *Type) defaultIsAssignableRuntimeType(val ref.Val) bool { + valType := val.Type() + if !(t.runtimeType == valType || t.isDyn() || t.runtimeType.TypeName() == valType.TypeName()) { + return false + } + switch t.runtimeType { + case types.ListType: + elemType := t.parameters[0] + l := val.(traits.Lister) + if l.Size() == types.IntZero { + return true + } + it := l.Iterator() + for it.HasNext() == types.True { + elemVal := it.Next() + return elemType.IsAssignableRuntimeType(elemVal) + } + case types.MapType: + keyType := t.parameters[0] + elemType := t.parameters[1] + m := val.(traits.Mapper) + if m.Size() == types.IntZero { + return true + } + it := m.Iterator() + for it.HasNext() == types.True { + keyVal := it.Next() + elemVal := m.Get(keyVal) + return keyType.IsAssignableRuntimeType(keyVal) && elemType.IsAssignableRuntimeType(elemVal) + } + } + return true +} + +// ListType creates an instances of a list type value with the provided element type. +func ListType(elemType *Type) *Type { + return &Type{ + kind: ListKind, + runtimeType: types.ListType, + parameters: []*Type{elemType}, + } +} + +// MapType creates an instance of a map type value with the provided key and value types. +func MapType(keyType, valueType *Type) *Type { + return &Type{ + kind: MapKind, + runtimeType: types.MapType, + parameters: []*Type{keyType, valueType}, + } +} + +// NullableType creates an instance of a nullable type with the provided wrapped type. +// +// Note: only primitive types are supported as wrapped types. +func NullableType(wrapped *Type) *Type { + return &Type{ + kind: wrapped.kind, + runtimeType: wrapped.runtimeType, + parameters: wrapped.parameters, + isAssignableType: func(other *Type) bool { + return NullType.IsAssignableType(other) || wrapped.IsAssignableType(other) + }, + isAssignableRuntimeType: func(other ref.Val) bool { + return NullType.IsAssignableRuntimeType(other) || wrapped.IsAssignableRuntimeType(other) + }, + } +} + +// OpaqueType creates an abstract parameterized type with a given name. +func OpaqueType(name string, params ...*Type) *Type { + return &Type{ + kind: OpaqueKind, + runtimeType: types.NewTypeValue(name), + parameters: params, + } +} + +// ObjectType creates a type references to an externally defined type, e.g. a protobuf message type. +func ObjectType(typeName string) *Type { + return &Type{ + kind: StructKind, + runtimeType: types.NewObjectTypeValue(typeName), + } +} + +// TypeParamType creates a parameterized type instance. +func TypeParamType(paramName string) *Type { + return &Type{ + kind: TypeParamKind, + runtimeType: types.NewTypeValue(paramName), + } +} + +// Variable creates an instance of a variable declaration with a variable name and type. +func Variable(name string, t *Type) EnvOption { + return func(e *Env) (*Env, error) { + et, err := TypeToExprType(t) + if err != nil { + return nil, err + } + e.declarations = append(e.declarations, decls.NewVar(name, et)) + return e, nil + } +} + +// Function defines a function and overloads with optional singleton or per-overload bindings. +// +// Using Function is roughly equivalent to calling Declarations() to declare the function signatures +// and Functions() to define the function bindings, if they have been defined. Specifying the +// same function name more than once will result in the aggregation of the function overloads. If any +// signatures conflict between the existing and new function definition an error will be raised. +// However, if the signatures are identical and the overload ids are the same, the redefinition will +// be considered a no-op. +// +// One key difference with using Function() is that each FunctionDecl provided will handle dynamic +// dispatch based on the type-signatures of the overloads provided which means overload resolution at +// runtime is handled out of the box rather than via a custom binding for overload resolution via +// Functions(): +// +// - Overloads are searched in the order they are declared +// - Dynamic dispatch for lists and maps is limited by inspection of the list and map contents +// at runtime. Empty lists and maps will result in a 'default dispatch' +// - In the event that a default dispatch occurs, the first overload provided is the one invoked +// +// If you intend to use overloads which differentiate based on the key or element type of a list or +// map, consider using a generic function instead: e.g. func(list(T)) or func(map(K, V)) as this +// will allow your implementation to determine how best to handle dispatch and the default behavior +// for empty lists and maps whose contents cannot be inspected. +// +// For functions which use parameterized opaque types (abstract types), consider using a singleton +// function which is capable of inspecting the contents of the type and resolving the appropriate +// overload as CEL can only make inferences by type-name regarding such types. +func Function(name string, opts ...FunctionOpt) EnvOption { + return func(e *Env) (*Env, error) { + fn := &functionDecl{ + name: name, + overloads: []*overloadDecl{}, + options: opts, + } + err := fn.init() + if err != nil { + return nil, err + } + _, err = functionDeclToExprDecl(fn) + if err != nil { + return nil, err + } + if existing, found := e.functions[fn.name]; found { + fn, err = existing.merge(fn) + if err != nil { + return nil, err + } + } + e.functions[name] = fn + return e, nil + } +} + +// FunctionOpt defines a functional option for configuring a function declaration. +type FunctionOpt func(*functionDecl) (*functionDecl, error) + +// SingletonUnaryBinding creates a singleton function defintion to be used for all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Unary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonBinaryImpl creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonBinaryImpl(fn functions.BinaryOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Binary: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// SingletonFunctionImpl creates a singleton function definition to be used with all function overloads. +// +// Note, this approach works well if operand is expected to have a specific trait which it implements, +// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings. +func SingletonFunctionImpl(fn functions.FunctionOp, traits ...int) FunctionOpt { + trait := 0 + for _, t := range traits { + trait = trait | t + } + return func(f *functionDecl) (*functionDecl, error) { + if f.singleton != nil { + return nil, fmt.Errorf("function already has a singleton binding: %s", f.name) + } + f.singleton = &functions.Overload{ + Operator: f.name, + Function: fn, + OperandTrait: trait, + } + return f, nil + } +} + +// Overload defines a new global overload with an overload id, argument types, and result type. Through the +// use of OverloadOpt options, the overload may also be configured with a binding, an operand trait, and to +// be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func Overload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, false, args, resultType, opts...) +} + +// MemberOverload defines a new receiver-style overload (or member function) with an overload id, argument types, +// and result type. Through the use of OverloadOpt options, the overload may also be configured with a binding, +// an operand trait, and to be non-strict. +// +// Note: function bindings should be commonly configured with Overload instances whereas operand traits and +// strict-ness should be rare occurrences. +func MemberOverload(overloadID string, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return newOverload(overloadID, true, args, resultType, opts...) +} + +// OverloadOpt is a functional option for configuring a function overload. +type OverloadOpt func(*overloadDecl) (*overloadDecl, error) + +// UnaryBinding provides the implementation of a unary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func UnaryBinding(binding functions.UnaryOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + if len(o.argTypes) != 1 { + return nil, fmt.Errorf("unary function bound to non-unary overload: %s", o.id) + } + o.unaryOp = binding + return o, nil + } +} + +// BinaryBinding provides the implementation of a binary overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func BinaryBinding(binding functions.BinaryOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + if len(o.argTypes) != 2 { + return nil, fmt.Errorf("binary function bound to non-binary overload: %s", o.id) + } + o.binaryOp = binding + return o, nil + } +} + +// FunctionBinding provides the implementation of a variadic overload. The provided function is protected by a runtime +// type-guard which ensures runtime type agreement between the overload signature and runtime argument types. +func FunctionBinding(binding functions.FunctionOp) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + if o.hasBinding() { + return nil, fmt.Errorf("overload already has a binding: %s", o.id) + } + o.functionOp = binding + return o, nil + } +} + +// OverloadIsNonStrict enables the function to be called with error and unknown argument values. +// +// Note: do not use this option unless absoluately necessary as it should be an uncommon feature. +func OverloadIsNonStrict() OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + o.nonStrict = true + return o, nil + } +} + +// OverloadOperandTrait configures a set of traits which the first argument to the overload must implement in order to be +// successfully invoked. +func OverloadOperandTrait(trait int) OverloadOpt { + return func(o *overloadDecl) (*overloadDecl, error) { + o.operandTrait = trait + return o, nil + } +} + +type functionDecl struct { + name string + overloads []*overloadDecl + options []FunctionOpt + singleton *functions.Overload + initialized bool +} + +// init ensures that a function's options have been applied. +// +// This function is used in both the environment configuration and internally for function merges. +func (f *functionDecl) init() error { + if f.initialized { + return nil + } + f.initialized = true + + var err error + for _, opt := range f.options { + f, err = opt(f) + if err != nil { + return err + } + } + if len(f.overloads) == 0 { + return fmt.Errorf("function %s must have at least one overload", f.name) + } + return nil +} + +// bindings produces a set of function bindings, if any are defined. +func (f *functionDecl) bindings() ([]*functions.Overload, error) { + overloads := []*functions.Overload{} + nonStrict := false + for _, o := range f.overloads { + if o.hasBinding() { + overload := &functions.Overload{ + Operator: o.id, + Unary: o.guardedUnaryOp(f.name), + Binary: o.guardedBinaryOp(f.name), + Function: o.guardedFunctionOp(f.name), + OperandTrait: o.operandTrait, + NonStrict: o.nonStrict, + } + overloads = append(overloads, overload) + nonStrict = nonStrict || o.nonStrict + } + } + if f.singleton != nil { + if len(overloads) != 0 { + return nil, fmt.Errorf("singleton function incompatible with specialized overloads: %s", f.name) + } + return []*functions.Overload{ + { + Operator: f.name, + Unary: f.singleton.Unary, + Binary: f.singleton.Binary, + Function: f.singleton.Function, + OperandTrait: f.singleton.OperandTrait, + }, + }, nil + } + if len(overloads) == 0 { + return overloads, nil + } + // Single overload. Replicate an entry for it using the function name as well. + if len(overloads) == 1 { + if overloads[0].Operator == f.name { + return overloads, nil + } + return append(overloads, &functions.Overload{ + Operator: f.name, + Unary: overloads[0].Unary, + Binary: overloads[0].Binary, + Function: overloads[0].Function, + NonStrict: overloads[0].NonStrict, + OperandTrait: overloads[0].OperandTrait, + }), nil + } + // All of the defined overloads are wrapped into a top-level function which + // performs dynamic dispatch to the proper overload based on the argument types. + bindings := append([]*functions.Overload{}, overloads...) + funcDispatch := func(args ...ref.Val) ref.Val { + for _, o := range f.overloads { + if !o.matchesRuntimeSignature(args...) { + continue + } + switch len(args) { + case 1: + if o.unaryOp != nil { + return o.unaryOp(args[0]) + } + case 2: + if o.binaryOp != nil { + return o.binaryOp(args[0], args[1]) + } + } + if o.functionOp != nil { + return o.functionOp(args...) + } + // eventually this will fall through to the noSuchOverload below. + } + return noSuchOverload(f.name, args...) + } + function := &functions.Overload{ + Operator: f.name, + Function: funcDispatch, + NonStrict: nonStrict, + } + return append(bindings, function), nil +} + +// merge one function declaration with another. +// +// If a function is extended, by say adding new overloads to an existing function, then it is merged with the +// prior definition of the function at which point its overloads must not collide with pre-existing overloads +// and its bindings (singleton, or per-overload) must not conflict with previous definitions either. +func (f *functionDecl) merge(other *functionDecl) (*functionDecl, error) { + if f.name != other.name { + return nil, fmt.Errorf("cannot merge unrelated functions. %s and %s", f.name, other.name) + } + err := f.init() + if err != nil { + return nil, err + } + err = other.init() + if err != nil { + return nil, err + } + merged := &functionDecl{ + name: f.name, + overloads: make([]*overloadDecl, len(f.overloads)), + options: []FunctionOpt{}, + initialized: true, + singleton: f.singleton, + } + copy(merged.overloads, f.overloads) + for _, o := range other.overloads { + err := merged.addOverload(o) + if err != nil { + return nil, fmt.Errorf("function declaration merge failed: %v", err) + } + } + if other.singleton != nil { + if merged.singleton != nil { + return nil, fmt.Errorf("function already has a binding: %s", f.name) + } + merged.singleton = other.singleton + } + return merged, nil +} + +// addOverload ensures that the new overload does not collide with an existing overload signature; +// however, if the function signatures are identical, the implementation may be rewritten as its +// difficult to compare functions by object identity. +func (f *functionDecl) addOverload(overload *overloadDecl) error { + for index, o := range f.overloads { + if o.id != overload.id && o.signatureOverlaps(overload) { + return fmt.Errorf("overload signature collision in function %s: %s collides with %s", f.name, o.id, overload.id) + } + if o.id == overload.id { + if o.signatureEquals(overload) && o.nonStrict == overload.nonStrict { + // Allow redefinition of an overload implementation so long as the signatures match. + f.overloads[index] = overload + return nil + } else { + return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.name, o.id) + } + } + } + f.overloads = append(f.overloads, overload) + return nil +} + +func noSuchOverload(funcName string, args ...ref.Val) ref.Val { + argTypes := make([]string, len(args)) + for i, arg := range args { + argTypes[i] = arg.Type().TypeName() + } + signature := strings.Join(argTypes, ", ") + return types.NewErr("no such overload: %s(%s)", funcName, signature) +} + +// overloadDecl contains all of the relevant information regarding a specific function overload. +type overloadDecl struct { + id string + argTypes []*Type + resultType *Type + memberFunction bool + + // binding options, optional but encouraged. + unaryOp functions.UnaryOp + binaryOp functions.BinaryOp + functionOp functions.FunctionOp + + // behavioral options, uncommon + nonStrict bool + operandTrait int +} + +func (o *overloadDecl) hasBinding() bool { + return o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil +} + +// guardedUnaryOp creates an invocation guard around the provided unary operator, if one is defined. +func (o *overloadDecl) guardedUnaryOp(funcName string) functions.UnaryOp { + if o.unaryOp == nil { + return nil + } + return func(arg ref.Val) ref.Val { + if !o.matchesRuntimeUnarySignature(arg) { + return noSuchOverload(funcName, arg) + } + return o.unaryOp(arg) + } +} + +// guardedBinaryOp creates an invocation guard around the provided binary operator, if one is defined. +func (o *overloadDecl) guardedBinaryOp(funcName string) functions.BinaryOp { + if o.binaryOp == nil { + return nil + } + return func(arg1, arg2 ref.Val) ref.Val { + if !o.matchesRuntimeBinarySignature(arg1, arg2) { + return noSuchOverload(funcName, arg1, arg2) + } + return o.binaryOp(arg1, arg2) + } +} + +// guardedFunctionOp creates an invocation guard around the provided variadic function binding, if one is provided. +func (o *overloadDecl) guardedFunctionOp(funcName string) functions.FunctionOp { + if o.functionOp == nil { + return nil + } + return func(args ...ref.Val) ref.Val { + if !o.matchesRuntimeSignature(args...) { + return noSuchOverload(funcName, args...) + } + return o.functionOp(args...) + } +} + +// matchesRuntimeUnarySignature indicates whether the argument type is runtime assiganble to the overload's expected argument. +func (o *overloadDecl) matchesRuntimeUnarySignature(arg ref.Val) bool { + if o.nonStrict && types.IsUnknownOrError(arg) { + return true + } + return o.argTypes[0].IsAssignableRuntimeType(arg) && (o.operandTrait == 0 || arg.Type().HasTrait(o.operandTrait)) +} + +// matchesRuntimeBinarySignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *overloadDecl) matchesRuntimeBinarySignature(arg1, arg2 ref.Val) bool { + if o.nonStrict { + if types.IsUnknownOrError(arg1) { + return types.IsUnknownOrError(arg2) || o.argTypes[1].IsAssignableRuntimeType(arg2) + } + } else if !o.argTypes[1].IsAssignableRuntimeType(arg2) { + return false + } + return o.argTypes[0].IsAssignableRuntimeType(arg1) && (o.operandTrait == 0 || arg1.Type().HasTrait(o.operandTrait)) +} + +// matchesRuntimeSignature indicates whether the argument types are runtime assiganble to the overload's expected arguments. +func (o *overloadDecl) matchesRuntimeSignature(args ...ref.Val) bool { + if len(args) != len(o.argTypes) { + return false + } + if len(args) == 0 { + return true + } + allArgsMatch := true + for i, arg := range args { + if o.nonStrict && types.IsUnknownOrError(arg) { + continue + } + allArgsMatch = allArgsMatch && o.argTypes[i].IsAssignableRuntimeType(arg) + } + + arg := args[0] + return allArgsMatch && (o.operandTrait == 0 || (o.nonStrict && types.IsUnknownOrError(arg)) || arg.Type().HasTrait(o.operandTrait)) +} + +// signatureEquals indicates whether one overload has an identical signature to another overload. +// +// Providing a duplicate signature is not an issue, but an overloapping signature is problematic. +func (o *overloadDecl) signatureEquals(other *overloadDecl) bool { + if o.id != other.id || o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { + return false + } + for i, at := range o.argTypes { + oat := other.argTypes[i] + if !at.equals(oat) { + return false + } + } + return o.resultType.equals(other.resultType) +} + +// signatureOverlaps indicates whether one overload has an overlapping signature with another overload. +// +// The 'other' overload must first be checked for equality before determining whether it overlaps in order to be completely accurate. +func (o *overloadDecl) signatureOverlaps(other *overloadDecl) bool { + if o.memberFunction != other.memberFunction || len(o.argTypes) != len(other.argTypes) { + return false + } + argsOverlap := true + for i, argType := range o.argTypes { + otherArgType := other.argTypes[i] + argsOverlap = argsOverlap && + (argType.IsAssignableType(otherArgType) || + otherArgType.IsAssignableType(argType)) + } + return argsOverlap +} + +func newOverload(overloadID string, memberFunction bool, args []*Type, resultType *Type, opts ...OverloadOpt) FunctionOpt { + return func(f *functionDecl) (*functionDecl, error) { + overload := &overloadDecl{ + id: overloadID, + argTypes: args, + resultType: resultType, + memberFunction: memberFunction, + } + var err error + for _, opt := range opts { + overload, err = opt(overload) + if err != nil { + return nil, err + } + } + err = f.addOverload(overload) + if err != nil { + return nil, err + } + return f, nil + } +} + +func maybeWrapper(t *Type, pbType *exprpb.Type) *exprpb.Type { + if t.IsAssignableType(NullType) { + return decls.NewWrapperType(pbType) + } + return pbType +} + +// TypeToExprType converts a CEL-native type representation to a protobuf CEL Type representation. +func TypeToExprType(t *Type) (*exprpb.Type, error) { + switch t.kind { + case AnyKind: + return decls.Any, nil + case BoolKind: + return maybeWrapper(t, decls.Bool), nil + case BytesKind: + return maybeWrapper(t, decls.Bytes), nil + case DoubleKind: + return maybeWrapper(t, decls.Double), nil + case DurationKind: + return decls.Duration, nil + case DynKind: + return decls.Dyn, nil + case IntKind: + return maybeWrapper(t, decls.Int), nil + case ListKind: + et, err := TypeToExprType(t.parameters[0]) + if err != nil { + return nil, err + } + return decls.NewListType(et), nil + case MapKind: + kt, err := TypeToExprType(t.parameters[0]) + if err != nil { + return nil, err + } + vt, err := TypeToExprType(t.parameters[1]) + if err != nil { + return nil, err + } + return decls.NewMapType(kt, vt), nil + case NullTypeKind: + return decls.Null, nil + case OpaqueKind: + params := make([]*exprpb.Type, len(t.parameters)) + for i, p := range t.parameters { + pt, err := TypeToExprType(p) + if err != nil { + return nil, err + } + params[i] = pt + } + return decls.NewAbstractType(t.runtimeType.TypeName(), params...), nil + case StringKind: + return maybeWrapper(t, decls.String), nil + case StructKind: + switch t.runtimeType.TypeName() { + case "google.protobuf.Any": + return decls.Any, nil + case "google.protobuf.Duration": + return decls.Duration, nil + case "google.protobuf.Timestamp": + return decls.Timestamp, nil + case "google.protobuf.Value": + return decls.Dyn, nil + case "google.protobuf.ListValue": + return decls.NewListType(decls.Dyn), nil + case "google.protobuf.Struct": + return decls.NewMapType(decls.String, decls.Dyn), nil + case "google.protobuf.BoolValue": + return decls.NewWrapperType(decls.Bool), nil + case "google.protobuf.BytesValue": + return decls.NewWrapperType(decls.Bytes), nil + case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": + return decls.NewWrapperType(decls.Double), nil + case "google.protobuf.Int32Value", "google.protobuf.Int64Value": + return decls.NewWrapperType(decls.Int), nil + case "google.protobuf.StringValue": + return decls.NewWrapperType(decls.String), nil + case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": + return decls.NewWrapperType(decls.Uint), nil + default: + return decls.NewObjectType(t.runtimeType.TypeName()), nil + } + case TimestampKind: + return decls.Timestamp, nil + case TypeParamKind: + return decls.NewTypeParamType(t.runtimeType.TypeName()), nil + case TypeKind: + return decls.NewTypeType(decls.Dyn), nil + case UintKind: + return maybeWrapper(t, decls.Uint), nil + } + return nil, fmt.Errorf("missing type conversion to proto: %v", t) +} + +// ExprTypeToType converts a protobuf CEL type representation to a CEL-native type representation. +func ExprTypeToType(t *exprpb.Type) (*Type, error) { + switch t.GetTypeKind().(type) { + case *exprpb.Type_Dyn: + return DynType, nil + case *exprpb.Type_AbstractType_: + paramTypes := make([]*Type, len(t.GetAbstractType().GetParameterTypes())) + for i, p := range t.GetAbstractType().GetParameterTypes() { + pt, err := ExprTypeToType(p) + if err != nil { + return nil, err + } + paramTypes[i] = pt + } + return OpaqueType(t.GetAbstractType().GetName(), paramTypes...), nil + case *exprpb.Type_ListType_: + et, err := ExprTypeToType(t.GetListType().GetElemType()) + if err != nil { + return nil, err + } + return ListType(et), nil + case *exprpb.Type_MapType_: + kt, err := ExprTypeToType(t.GetMapType().GetKeyType()) + if err != nil { + return nil, err + } + vt, err := ExprTypeToType(t.GetMapType().GetValueType()) + if err != nil { + return nil, err + } + return MapType(kt, vt), nil + case *exprpb.Type_MessageType: + switch t.GetMessageType() { + case "google.protobuf.Any": + return AnyType, nil + case "google.protobuf.Duration": + return DurationType, nil + case "google.protobuf.Timestamp": + return TimestampType, nil + case "google.protobuf.Value": + return DynType, nil + case "google.protobuf.ListValue": + return ListType(DynType), nil + case "google.protobuf.Struct": + return MapType(StringType, DynType), nil + case "google.protobuf.BoolValue": + return NullableType(BoolType), nil + case "google.protobuf.BytesValue": + return NullableType(BytesType), nil + case "google.protobuf.DoubleValue", "google.protobuf.FloatValue": + return NullableType(DoubleType), nil + case "google.protobuf.Int32Value", "google.protobuf.Int64Value": + return NullableType(IntType), nil + case "google.protobuf.StringValue": + return NullableType(StringType), nil + case "google.protobuf.UInt32Value", "google.protobuf.UInt64Value": + return NullableType(UintType), nil + default: + return ObjectType(t.GetMessageType()), nil + } + case *exprpb.Type_Null: + return NullType, nil + case *exprpb.Type_Primitive: + switch t.GetPrimitive() { + case exprpb.Type_BOOL: + return BoolType, nil + case exprpb.Type_BYTES: + return BytesType, nil + case exprpb.Type_DOUBLE: + return DoubleType, nil + case exprpb.Type_INT64: + return IntType, nil + case exprpb.Type_STRING: + return StringType, nil + case exprpb.Type_UINT64: + return UintType, nil + default: + return nil, fmt.Errorf("unsupported primitive type: %v", t) + } + case *exprpb.Type_TypeParam: + return TypeParamType(t.GetTypeParam()), nil + case *exprpb.Type_Type: + return TypeType, nil + case *exprpb.Type_WellKnown: + switch t.GetWellKnown() { + case exprpb.Type_ANY: + return AnyType, nil + case exprpb.Type_DURATION: + return DurationType, nil + case exprpb.Type_TIMESTAMP: + return TimestampType, nil + default: + return nil, fmt.Errorf("unsupported well-known type: %v", t) + } + case *exprpb.Type_Wrapper: + t, err := ExprTypeToType(&exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: t.GetWrapper()}}) + if err != nil { + return nil, err + } + return NullableType(t), nil + default: + return nil, fmt.Errorf("unsupported type: %v", t) + } +} + +// ExprDeclToDeclaration converts a protobuf CEL declaration to a CEL-native declaration, either a Variable or Function. +func ExprDeclToDeclaration(d *exprpb.Decl) (EnvOption, error) { + switch d.GetDeclKind().(type) { + case *exprpb.Decl_Function: + overloads := d.GetFunction().GetOverloads() + opts := make([]FunctionOpt, len(overloads)) + for i, o := range overloads { + args := make([]*Type, len(o.GetParams())) + for j, p := range o.GetParams() { + a, err := ExprTypeToType(p) + if err != nil { + return nil, err + } + args[j] = a + } + res, err := ExprTypeToType(o.GetResultType()) + if err != nil { + return nil, err + } + opts[i] = Overload(o.GetOverloadId(), args, res) + } + return Function(d.GetName(), opts...), nil + case *exprpb.Decl_Ident: + t, err := ExprTypeToType(d.GetIdent().GetType()) + if err != nil { + return nil, err + } + return Variable(d.GetName(), t), nil + default: + return nil, fmt.Errorf("unsupported decl: %v", d) + } + +} + +func functionDeclToExprDecl(f *functionDecl) (*exprpb.Decl, error) { + overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(f.overloads)) + i := 0 + for _, o := range f.overloads { + paramNames := map[string]struct{}{} + argTypes := make([]*exprpb.Type, len(o.argTypes)) + for j, a := range o.argTypes { + collectParamNames(paramNames, a) + at, err := TypeToExprType(a) + if err != nil { + return nil, err + } + argTypes[j] = at + } + collectParamNames(paramNames, o.resultType) + resultType, err := TypeToExprType(o.resultType) + if err != nil { + return nil, err + } + if len(paramNames) == 0 { + if o.memberFunction { + overloads[i] = decls.NewInstanceOverload(o.id, argTypes, resultType) + } else { + overloads[i] = decls.NewOverload(o.id, argTypes, resultType) + } + } else { + params := []string{} + for pn := range paramNames { + params = append(params, pn) + } + if o.memberFunction { + overloads[i] = decls.NewParameterizedInstanceOverload(o.id, argTypes, resultType, params) + } else { + overloads[i] = decls.NewParameterizedOverload(o.id, argTypes, resultType, params) + } + } + i++ + } + return decls.NewFunction(f.name, overloads...), nil +} + +func collectParamNames(paramNames map[string]struct{}, arg *Type) { + if arg.kind == TypeParamKind { + paramNames[arg.runtimeType.TypeName()] = struct{}{} + } + for _, param := range arg.parameters { + collectParamNames(paramNames, param) + } +} diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/github.com/google/cel-go/cel/env.go index 0833561881e..4e9ecdd648a 100644 --- a/vendor/github.com/google/cel-go/cel/env.go +++ b/vendor/github.com/google/cel-go/cel/env.go @@ -32,9 +32,7 @@ import ( ) // Source interface representing a user-provided expression. -type Source interface { - common.Source -} +type Source = common.Source // Ast representing the checked or unchecked expression, its source, and related metadata such as // source position information. @@ -56,18 +54,30 @@ func (ast *Ast) IsChecked() bool { return ast.typeMap != nil && len(ast.typeMap) > 0 } -// SourceInfo returns character offset and newling position information about expression elements. +// SourceInfo returns character offset and newline position information about expression elements. func (ast *Ast) SourceInfo() *exprpb.SourceInfo { return ast.info } // ResultType returns the output type of the expression if the Ast has been type-checked, else // returns decls.Dyn as the parse step cannot infer the type. +// +// Deprecated: use OutputType func (ast *Ast) ResultType() *exprpb.Type { if !ast.IsChecked() { return decls.Dyn } - return ast.typeMap[ast.expr.Id] + return ast.typeMap[ast.expr.GetId()] +} + +// OutputType returns the output type of the expression if the Ast has been type-checked, else +// returns cel.DynType as the parse step cannot infer types. +func (ast *Ast) OutputType() *Type { + t, err := ExprTypeToType(ast.ResultType()) + if err != nil { + return DynType + } + return t } // Source returns a view of the input used to create the Ast. This source may be complete or @@ -84,12 +94,14 @@ func FormatType(t *exprpb.Type) string { // Env encapsulates the context necessary to perform parsing, type checking, or generation of // evaluable programs for different expressions. type Env struct { - Container *containers.Container - declarations []*exprpb.Decl - macros []parser.Macro - adapter ref.TypeAdapter - provider ref.TypeProvider - features map[int]bool + Container *containers.Container + functions map[string]*functionDecl + declarations []*exprpb.Decl + macros []parser.Macro + adapter ref.TypeAdapter + provider ref.TypeProvider + features map[int]bool + appliedFeatures map[int]bool // Internal parser representation prsr *parser.Parser @@ -98,6 +110,7 @@ type Env struct { chk *checker.Env chkErr error chkOnce sync.Once + chkOpts []checker.Option // Program options tied to the environment progOpts []ProgramOption @@ -110,8 +123,16 @@ type Env struct { // See the EnvOption helper functions for the options that can be used to configure the // environment. func NewEnv(opts ...EnvOption) (*Env, error) { - stdOpts := append([]EnvOption{StdLib()}, opts...) - return NewCustomEnv(stdOpts...) + // Extend the statically configured standard environment, disabling eager validation to ensure + // the cost of setup for the environment is still just as cheap as it is in v0.11.x and earlier + // releases. The user provided options can easily re-enable the eager validation as they are + // processed after this default option. + stdOpts := append([]EnvOption{EagerlyValidateDeclarations(false)}, opts...) + env, err := getStdEnv() + if err != nil { + return nil, err + } + return env.Extend(stdOpts...) } // NewCustomEnv creates a custom program environment which is not automatically configured with the @@ -130,13 +151,15 @@ func NewCustomEnv(opts ...EnvOption) (*Env, error) { return nil, err } return (&Env{ - declarations: []*exprpb.Decl{}, - macros: []parser.Macro{}, - Container: containers.DefaultContainer, - adapter: registry, - provider: registry, - features: map[int]bool{}, - progOpts: []ProgramOption{}, + declarations: []*exprpb.Decl{}, + functions: map[string]*functionDecl{}, + macros: []parser.Macro{}, + Container: containers.DefaultContainer, + adapter: registry, + provider: registry, + features: map[int]bool{}, + appliedFeatures: map[int]bool{}, + progOpts: []ProgramOption{}, }).configure(opts) } @@ -152,25 +175,8 @@ func (e *Env) Check(ast *Ast) (*Ast, *Issues) { pe, _ := AstToParsedExpr(ast) // Construct the internal checker env, erroring if there is an issue adding the declarations. - e.chkOnce.Do(func() { - ce, err := checker.NewEnv(e.Container, e.provider, - checker.HomogeneousAggregateLiterals( - e.HasFeature(featureDisableDynamicAggregateLiterals)), - checker.CrossTypeNumericComparisons( - e.HasFeature(featureCrossTypeNumericComparisons))) - if err != nil { - e.chkErr = err - return - } - err = ce.Add(e.declarations...) - if err != nil { - e.chkErr = err - return - } - e.chk = ce - }) - // The once call will ensure that this value is set or nil for all invocations. - if e.chkErr != nil { + err := e.initChecker() + if err != nil { errs := common.NewErrors(ast.Source()) errs.ReportError(common.NoLocation, e.chkErr.Error()) return nil, NewIssues(errs) @@ -210,7 +216,7 @@ func (e *Env) Compile(txt string) (*Ast, *Issues) { // issues discovered during Check. // // Note, for parse-only uses of CEL use Parse. -func (e *Env) CompileSource(src common.Source) (*Ast, *Issues) { +func (e *Env) CompileSource(src Source) (*Ast, *Issues) { ast, iss := e.ParseSource(src) if iss.Err() != nil { return nil, iss @@ -233,11 +239,29 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { if e.chkErr != nil { return nil, e.chkErr } - // Copy slices. - decsCopy := make([]*exprpb.Decl, len(e.declarations)) + + // The type-checker is configured with Declarations. The declarations may either be provided + // as options which have not yet been validated, or may come from a previous checker instance + // whose types have already been validated. + chkOptsCopy := make([]checker.Option, len(e.chkOpts)) + copy(chkOptsCopy, e.chkOpts) + + // Copy the declarations if needed. + decsCopy := []*exprpb.Decl{} + if e.chk != nil { + // If the type-checker has already been instantiated, then the e.declarations have been + // valdiated within the chk instance. + chkOptsCopy = append(chkOptsCopy, checker.ValidatedDeclarations(e.chk)) + } else { + // If the type-checker has not been instantiated, ensure the unvalidated declarations are + // provided to the extended Env instance. + decsCopy = make([]*exprpb.Decl, len(e.declarations)) + copy(decsCopy, e.declarations) + } + + // Copy macros and program options macsCopy := make([]parser.Macro, len(e.macros)) progOptsCopy := make([]ProgramOption, len(e.progOpts)) - copy(decsCopy, e.declarations) copy(macsCopy, e.macros) copy(progOptsCopy, e.progOpts) @@ -272,15 +296,27 @@ func (e *Env) Extend(opts ...EnvOption) (*Env, error) { for k, v := range e.features { featuresCopy[k] = v } + appliedFeaturesCopy := make(map[int]bool, len(e.appliedFeatures)) + for k, v := range e.appliedFeatures { + appliedFeaturesCopy[k] = v + } + funcsCopy := make(map[string]*functionDecl, len(e.functions)) + for k, v := range e.functions { + funcsCopy[k] = v + } + // TODO: functions copy needs to happen here. ext := &Env{ - Container: e.Container, - declarations: decsCopy, - macros: macsCopy, - progOpts: progOptsCopy, - adapter: adapter, - features: featuresCopy, - provider: provider, + Container: e.Container, + declarations: decsCopy, + functions: funcsCopy, + macros: macsCopy, + progOpts: progOptsCopy, + adapter: adapter, + features: featuresCopy, + appliedFeatures: appliedFeaturesCopy, + provider: provider, + chkOpts: chkOptsCopy, } return ext.configure(opts) } @@ -294,7 +330,7 @@ func (e *Env) HasFeature(flag int) bool { // Parse parses the input expression value `txt` to a Ast and/or a set of Issues. // -// This form of Parse creates a common.Source value for the input `txt` and forwards to the +// This form of Parse creates a Source value for the input `txt` and forwards to the // ParseSource method. func (e *Env) Parse(txt string) (*Ast, *Issues) { src := common.NewTextSource(txt) @@ -308,7 +344,7 @@ func (e *Env) Parse(txt string) (*Ast, *Issues) { // // It is possible to have both non-nil Ast and Issues values returned from this call; however, // the mere presence of an Ast does not imply that it is valid for use. -func (e *Env) ParseSource(src common.Source) (*Ast, *Issues) { +func (e *Env) ParseSource(src Source) (*Ast, *Issues) { res, errs := e.prsr.Parse(src) if len(errs.GetErrors()) > 0 { return nil, &Issues{errs: errs} @@ -316,7 +352,7 @@ func (e *Env) ParseSource(src common.Source) (*Ast, *Issues) { // Manually create the Ast to ensure that the text source information is propagated on // subsequent calls to Check. return &Ast{ - source: Source(src), + source: src, expr: res.GetExpr(), info: res.GetSourceInfo()}, nil } @@ -426,6 +462,30 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { return nil, err } } + + // If the default UTC timezone fix has been enabled, make sure the library is configured + if e.HasFeature(featureDefaultUTCTimeZone) { + if _, found := e.appliedFeatures[featureDefaultUTCTimeZone]; !found { + e, err = Lib(timeUTCLibrary{})(e) + if err != nil { + return nil, err + } + // record that the feature has been applied since it will generate declarations + // and functions which will be propagated on Extend() calls and which should only + // be registered once. + e.appliedFeatures[featureDefaultUTCTimeZone] = true + } + } + + // Initialize all of the functions configured within the environment. + for _, fn := range e.functions { + err = fn.init() + if err != nil { + return nil, err + } + } + + // Configure the parser. prsrOpts := []parser.Option{parser.Macros(e.macros...)} if e.HasFeature(featureEnableMacroCallTracking) { prsrOpts = append(prsrOpts, parser.PopulateMacroCalls(true)) @@ -434,9 +494,58 @@ func (e *Env) configure(opts []EnvOption) (*Env, error) { if err != nil { return nil, err } + + // Ensure that the checker init happens eagerly rather than lazily. + if e.HasFeature(featureEagerlyValidateDeclarations) { + err := e.initChecker() + if err != nil { + return nil, err + } + } + return e, nil } +func (e *Env) initChecker() error { + e.chkOnce.Do(func() { + chkOpts := []checker.Option{} + chkOpts = append(chkOpts, e.chkOpts...) + chkOpts = append(chkOpts, + checker.HomogeneousAggregateLiterals( + e.HasFeature(featureDisableDynamicAggregateLiterals)), + checker.CrossTypeNumericComparisons( + e.HasFeature(featureCrossTypeNumericComparisons))) + + ce, err := checker.NewEnv(e.Container, e.provider, chkOpts...) + if err != nil { + e.chkErr = err + return + } + // Add the statically configured declarations. + err = ce.Add(e.declarations...) + if err != nil { + e.chkErr = err + return + } + // Add the function declarations which are derived from the FunctionDecl instances. + for _, fn := range e.functions { + fnDecl, err := functionDeclToExprDecl(fn) + if err != nil { + e.chkErr = err + return + } + err = ce.Add(fnDecl) + if err != nil { + e.chkErr = err + return + } + } + // Add function declarations here separately. + e.chk = ce + }) + return e.chkErr +} + // Issues defines methods for inspecting the error details of parse and check calls. // // Note: in the future, non-fatal warnings and notices may be inspectable via the Issues struct. @@ -488,3 +597,17 @@ func (i *Issues) String() string { } return i.errs.ToDisplayString() } + +// getStdEnv lazy initializes the CEL standard environment. +func getStdEnv() (*Env, error) { + stdEnvInit.Do(func() { + stdEnv, stdEnvErr = NewCustomEnv(StdLib(), EagerlyValidateDeclarations(true)) + }) + return stdEnv, stdEnvErr +} + +var ( + stdEnvInit sync.Once + stdEnv *Env + stdEnvErr error +) diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/github.com/google/cel-go/cel/io.go index a2c317f3b89..e721c97f667 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/github.com/google/cel-go/cel/io.go @@ -44,7 +44,7 @@ func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) *Ast { // through future calls. // // Prefer CheckedExprToAst if loading expressions from storage. -func CheckedExprToAstWithSource(checkedExpr *exprpb.CheckedExpr, src common.Source) *Ast { +func CheckedExprToAstWithSource(checkedExpr *exprpb.CheckedExpr, src Source) *Ast { refMap := checkedExpr.GetReferenceMap() if refMap == nil { refMap = map[int64]*exprpb.Reference{} @@ -96,7 +96,7 @@ func ParsedExprToAst(parsedExpr *exprpb.ParsedExpr) *Ast { // expression, or if you need to separately check a subset of an expression. // // Prefer ParsedExprToAst if loading expressions from storage. -func ParsedExprToAstWithSource(parsedExpr *exprpb.ParsedExpr, src common.Source) *Ast { +func ParsedExprToAstWithSource(parsedExpr *exprpb.ParsedExpr, src Source) *Ast { si := parsedExpr.GetSourceInfo() if si == nil { si = &exprpb.SourceInfo{} @@ -241,7 +241,7 @@ func ValueToRefValue(adapter ref.TypeAdapter, v *exprpb.Value) (ref.Val, error) if err != nil { return nil, err } - return adapter.NativeToValue(msg.(proto.Message)), nil + return adapter.NativeToValue(msg), nil case *exprpb.Value_MapValue: m := v.GetMapValue() entries := make(map[ref.Val]ref.Val) diff --git a/vendor/github.com/google/cel-go/cel/library.go b/vendor/github.com/google/cel-go/cel/library.go index cef161d6a2c..5ca528459a8 100644 --- a/vendor/github.com/google/cel-go/cel/library.go +++ b/vendor/github.com/google/cel-go/cel/library.go @@ -15,19 +15,25 @@ package cel import ( + "strconv" + "strings" + "time" + "github.com/google/cel-go/checker" + "github.com/google/cel-go/common/overloads" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter/functions" - "github.com/google/cel-go/parser" ) -// Library provides a collection of EnvOption and ProgramOption values used to confiugre a CEL +// Library provides a collection of EnvOption and ProgramOption values used to configure a CEL // environment for a particular use case or with a related set of functionality. // // Note, the ProgramOption values provided by a library are expected to be static and not vary // between calls to Env.Program(). If there is a need for such dynamic configuration, prefer to // configure these options outside the Library and within the Env.Program() call directly. type Library interface { - // CompileOptions returns a collection of funcitional options for configuring the Parse / Check + // CompileOptions returns a collection of functional options for configuring the Parse / Check // environment. CompileOptions() []EnvOption @@ -65,7 +71,7 @@ type stdLibrary struct{} func (stdLibrary) CompileOptions() []EnvOption { return []EnvOption{ Declarations(checker.StandardDeclarations()...), - Macros(parser.AllMacros...), + Macros(StandardMacros...), } } @@ -75,3 +81,263 @@ func (stdLibrary) ProgramOptions() []ProgramOption { Functions(functions.StandardOverloads()...), } } + +type timeUTCLibrary struct{} + +func (timeUTCLibrary) CompileOptions() []EnvOption { + return timeOverloadDeclarations +} + +func (timeUTCLibrary) ProgramOptions() []ProgramOption { + return []ProgramOption{} +} + +// Declarations and functions which enable using UTC on time.Time inputs when the timezone is unspecified +// in the CEL expression. +var ( + utcTZ = types.String("UTC") + + timeOverloadDeclarations = []EnvOption{ + Function(overloads.TimeGetHours, + MemberOverload(overloads.DurationToHours, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Hours()) + }))), + Function(overloads.TimeGetMinutes, + MemberOverload(overloads.DurationToMinutes, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Minutes()) + }))), + Function(overloads.TimeGetSeconds, + MemberOverload(overloads.DurationToSeconds, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Seconds()) + }))), + Function(overloads.TimeGetMilliseconds, + MemberOverload(overloads.DurationToMilliseconds, []*Type{DurationType}, IntType, + UnaryBinding(func(dur ref.Val) ref.Val { + d := dur.(types.Duration) + return types.Int(d.Milliseconds()) + }))), + Function(overloads.TimeGetFullYear, + MemberOverload(overloads.TimestampToYear, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetFullYear(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToYearWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetFullYear), + ), + ), + Function(overloads.TimeGetMonth, + MemberOverload(overloads.TimestampToMonth, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMonth(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMonthWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMonth), + ), + ), + Function(overloads.TimeGetDayOfYear, + MemberOverload(overloads.TimestampToDayOfYear, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfYear(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfYearWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(func(ts, tz ref.Val) ref.Val { + return timestampGetDayOfYear(ts, tz) + }), + ), + ), + Function(overloads.TimeGetDayOfMonth, + MemberOverload(overloads.TimestampToDayOfMonthZeroBased, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfMonthZeroBased(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfMonthZeroBasedWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfMonthZeroBased), + ), + ), + Function(overloads.TimeGetDate, + MemberOverload(overloads.TimestampToDayOfMonthOneBased, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfMonthOneBased(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfMonthOneBasedWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfMonthOneBased), + ), + ), + Function(overloads.TimeGetDayOfWeek, + MemberOverload(overloads.TimestampToDayOfWeek, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetDayOfWeek(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToDayOfWeekWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetDayOfWeek), + ), + ), + Function(overloads.TimeGetHours, + MemberOverload(overloads.TimestampToHours, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetHours(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToHoursWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetHours), + ), + ), + Function(overloads.TimeGetMinutes, + MemberOverload(overloads.TimestampToMinutes, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMinutes(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMinutesWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMinutes), + ), + ), + Function(overloads.TimeGetSeconds, + MemberOverload(overloads.TimestampToSeconds, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetSeconds(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToSecondsWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetSeconds), + ), + ), + Function(overloads.TimeGetMilliseconds, + MemberOverload(overloads.TimestampToMilliseconds, []*Type{TimestampType}, IntType, + UnaryBinding(func(ts ref.Val) ref.Val { + return timestampGetMilliseconds(ts, utcTZ) + }), + ), + MemberOverload(overloads.TimestampToMillisecondsWithTz, []*Type{TimestampType, StringType}, IntType, + BinaryBinding(timestampGetMilliseconds), + ), + ), + } +) + +func timestampGetFullYear(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Year()) +} + +func timestampGetMonth(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + // CEL spec indicates that the month should be 0-based, but the Time value + // for Month() is 1-based. + return types.Int(t.Month() - 1) +} + +func timestampGetDayOfYear(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.YearDay() - 1) +} + +func timestampGetDayOfMonthZeroBased(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Day() - 1) +} + +func timestampGetDayOfMonthOneBased(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Day()) +} + +func timestampGetDayOfWeek(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Weekday()) +} + +func timestampGetHours(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Hour()) +} + +func timestampGetMinutes(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Minute()) +} + +func timestampGetSeconds(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Second()) +} + +func timestampGetMilliseconds(ts, tz ref.Val) ref.Val { + t, err := inTimeZone(ts, tz) + if err != nil { + return types.NewErr(err.Error()) + } + return types.Int(t.Nanosecond() / 1000000) +} + +func inTimeZone(ts, tz ref.Val) (time.Time, error) { + t := ts.(types.Timestamp) + val := string(tz.(types.String)) + ind := strings.Index(val, ":") + if ind == -1 { + loc, err := time.LoadLocation(val) + if err != nil { + return time.Time{}, err + } + return t.In(loc), nil + } + + // If the input is not the name of a timezone (for example, 'US/Central'), it should be a numerical offset from UTC + // in the format ^(+|-)(0[0-9]|1[0-4]):[0-5][0-9]$. The numerical input is parsed in terms of hours and minutes. + hr, err := strconv.Atoi(string(val[0:ind])) + if err != nil { + return time.Time{}, err + } + min, err := strconv.Atoi(string(val[ind+1:])) + if err != nil { + return time.Time{}, err + } + var offset int + if string(val[0]) == "-" { + offset = hr*60 - min + } else { + offset = hr*60 + min + } + secondsEastOfUTC := int((time.Duration(offset) * time.Minute).Seconds()) + timezone := time.FixedZone("", secondsEastOfUTC) + return t.In(timezone), nil +} diff --git a/vendor/github.com/google/cel-go/cel/macro.go b/vendor/github.com/google/cel-go/cel/macro.go new file mode 100644 index 00000000000..e43cb4eeea1 --- /dev/null +++ b/vendor/github.com/google/cel-go/cel/macro.go @@ -0,0 +1,139 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cel + +import ( + "github.com/google/cel-go/common" + "github.com/google/cel-go/parser" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +// Macro describes a function signature to match and the MacroExpander to apply. +// +// Note: when a Macro should apply to multiple overloads (based on arg count) of a given function, +// a Macro should be created per arg-count or as a var arg macro. +type Macro = parser.Macro + +// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error +// if the input arguments are not suitable for the expansion requirements for the macro in question. +// +// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call +// and produces as output an Expr ast node. +// +// Note: when the Macro.IsReceiverStyle() method returns true, the target argument will be nil. +type MacroExpander = parser.MacroExpander + +// MacroExprHelper exposes helper methods for creating new expressions within a CEL abstract syntax tree. +type MacroExprHelper = parser.ExprHelper + +// NewGlobalMacro creates a Macro for a global function with the specified arg count. +func NewGlobalMacro(function string, argCount int, expander MacroExpander) Macro { + return parser.NewGlobalMacro(function, argCount, expander) +} + +// NewReceiverMacro creates a Macro for a receiver function matching the specified arg count. +func NewReceiverMacro(function string, argCount int, expander MacroExpander) Macro { + return parser.NewReceiverMacro(function, argCount, expander) +} + +// NewGlobalVarArgMacro creates a Macro for a global function with a variable arg count. +func NewGlobalVarArgMacro(function string, expander MacroExpander) Macro { + return parser.NewGlobalVarArgMacro(function, expander) +} + +// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg count. +func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro { + return parser.NewReceiverVarArgMacro(function, expander) +} + +// HasMacroExpander expands the input call arguments into a presence test, e.g. has(.field) +func HasMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeHas(meh, target, args) +} + +// ExistsMacroExpander expands the input call arguments into a comprehension that returns true if any of the +// elements in the range match the predicate expressions: +// .exists(, ) +func ExistsMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeExists(meh, target, args) +} + +// ExistsOneMacroExpander expands the input call arguments into a comprehension that returns true if exactly +// one of the elements in the range match the predicate expressions: +// .exists_one(, ) +func ExistsOneMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeExistsOne(meh, target, args) +} + +// MapMacroExpander expands the input call arguments into a comprehension that transforms each element in the +// input to produce an output list. +// +// There are two call patterns supported by map: +// .map(, ) +// .map(, , ) +// In the second form only iterVar values which return true when provided to the predicate expression +// are transformed. +func MapMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeMap(meh, target, args) +} + +// FilterMacroExpander expands the input call arguments into a comprehension which produces a list which contains +// only elements which match the provided predicate expression: +// .filter(, ) +func FilterMacroExpander(meh MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + return parser.MakeFilter(meh, target, args) +} + +var ( + // Aliases to each macro in the CEL standard environment. + // Note: reassigning these macro variables may result in undefined behavior. + + // HasMacro expands "has(m.f)" which tests the presence of a field, avoiding the need to + // specify the field as a string. + HasMacro = parser.HasMacro + + // AllMacro expands "range.all(var, predicate)" into a comprehension which ensures that all + // elements in the range satisfy the predicate. + AllMacro = parser.AllMacro + + // ExistsMacro expands "range.exists(var, predicate)" into a comprehension which ensures that + // some element in the range satisfies the predicate. + ExistsMacro = parser.ExistsMacro + + // ExistsOneMacro expands "range.exists_one(var, predicate)", which is true if for exactly one + // element in range the predicate holds. + ExistsOneMacro = parser.ExistsOneMacro + + // MapMacro expands "range.map(var, function)" into a comprehension which applies the function + // to each element in the range to produce a new list. + MapMacro = parser.MapMacro + + // MapFilterMacro expands "range.map(var, predicate, function)" into a comprehension which + // first filters the elements in the range by the predicate, then applies the transform function + // to produce a new list. + MapFilterMacro = parser.MapFilterMacro + + // FilterMacro expands "range.filter(var, predicate)" into a comprehension which filters + // elements in the range, producing a new list from the elements that satisfy the predicate. + FilterMacro = parser.FilterMacro + + // StandardMacros provides an alias to all the CEL macros defined in the standard environment. + StandardMacros = []Macro{ + HasMacro, AllMacro, ExistsMacro, ExistsOneMacro, MapMacro, MapFilterMacro, FilterMacro, + } + + // NoMacros provides an alias to an empty list of macros + NoMacros = []Macro{} +) diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/github.com/google/cel-go/cel/options.go index 9a5df568c37..21c75701061 100644 --- a/vendor/github.com/google/cel-go/cel/options.go +++ b/vendor/github.com/google/cel-go/cel/options.go @@ -29,7 +29,6 @@ import ( "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" "github.com/google/cel-go/interpreter/functions" - "github.com/google/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" descpb "google.golang.org/protobuf/types/descriptorpb" @@ -53,6 +52,15 @@ const ( // Enable the use of cross-type numeric comparisons at the type-checker. featureCrossTypeNumericComparisons + + // Enable eager validation of declarations to ensure that Env values created + // with `Extend` inherit a validated list of declarations from the parent Env. + featureEagerlyValidateDeclarations + + // Enable the use of the default UTC timezone when a timezone is not specified + // on a CEL timestamp operation. This fixes the scenario where the input time + // is not already in UTC. + featureDefaultUTCTimeZone ) // EnvOption is a functional interface for configuring the environment. @@ -64,7 +72,7 @@ type EnvOption func(e *Env) (*Env, error) // comprehensions such as `all` and `exists` are enabled only via macros. func ClearMacros() EnvOption { return func(e *Env) (*Env, error) { - e.macros = parser.NoMacros + e.macros = NoMacros return e, nil } } @@ -95,14 +103,24 @@ func CustomTypeProvider(provider ref.TypeProvider) EnvOption { // for the environment. The NewEnv call builds on top of the standard CEL declarations. For a // purely custom set of declarations use NewCustomEnv. func Declarations(decls ...*exprpb.Decl) EnvOption { - // TODO: provide an alternative means of specifying declarations that doesn't refer - // to the underlying proto implementations. return func(e *Env) (*Env, error) { e.declarations = append(e.declarations, decls...) return e, nil } } +// EagerlyValidateDeclarations ensures that any collisions between configured declarations are caught +// at the time of the `NewEnv` call. +// +// Eagerly validating declarations is also useful for bootstrapping a base `cel.Env` value. +// Calls to base `Env.Extend()` will be significantly faster when declarations are eagerly validated +// as declarations will be collision-checked at most once and only incrementally by way of `Extend` +// +// Disabled by default as not all environments are used for type-checking. +func EagerlyValidateDeclarations(enabled bool) EnvOption { + return features(featureEagerlyValidateDeclarations, enabled) +} + // HomogeneousAggregateLiterals option ensures that list and map literal entry types must agree // during type-checking. // @@ -116,7 +134,7 @@ func HomogeneousAggregateLiterals() EnvOption { // Macros option extends the macro set configured in the environment. // // Note: This option must be specified after ClearMacros if used together. -func Macros(macros ...parser.Macro) EnvOption { +func Macros(macros ...Macro) EnvOption { return func(e *Env) (*Env, error) { e.macros = append(e.macros, macros...) return e, nil @@ -316,6 +334,9 @@ func CustomDecorator(dec interpreter.InterpretableDecorator) ProgramOption { } // Functions adds function overloads that extend or override the set of CEL built-ins. +// +// Deprecated: use Function() instead to declare the function, its overload signatures, +// and the overload implementations. func Functions(funcs ...*functions.Overload) ProgramOption { return func(p *prog) (*prog, error) { if err := p.dispatcher.Add(funcs...); err != nil { @@ -326,7 +347,8 @@ func Functions(funcs ...*functions.Overload) ProgramOption { } // Globals sets the global variable values for a given program. These values may be shadowed by -// variables with the same name provided to the Eval() call. +// variables with the same name provided to the Eval() call. If Globals is used in a Library with +// a Lib EnvOption, vars may shadow variables provided by previously added libraries. // // The vars value may either be an `interpreter.Activation` instance or a `map[string]interface{}`. func Globals(vars interface{}) ProgramOption { @@ -335,6 +357,9 @@ func Globals(vars interface{}) ProgramOption { if err != nil { return nil, err } + if p.defaultVars != nil { + defaultVars = interpreter.NewHierarchicalActivation(p.defaultVars, defaultVars) + } p.defaultVars = defaultVars return p, nil } @@ -422,7 +447,7 @@ func CostLimit(costLimit uint64) ProgramOption { } func fieldToCELType(field protoreflect.FieldDescriptor) (*exprpb.Type, error) { - if field.Kind() == protoreflect.MessageKind { + if field.Kind() == protoreflect.MessageKind || field.Kind() == protoreflect.GroupKind { msgName := (string)(field.Message().FullName()) wellKnownType, found := pb.CheckedWellKnowns[msgName] if found { @@ -503,6 +528,12 @@ func CrossTypeNumericComparisons(enabled bool) EnvOption { return features(featureCrossTypeNumericComparisons, enabled) } +// DefaultUTCTimeZone ensures that time-based operations use the UTC timezone rather than the +// input time's local timezone. +func DefaultUTCTimeZone(enabled bool) EnvOption { + return features(featureDefaultUTCTimeZone, enabled) +} + // features sets the given feature flags. See list of Feature constants above. func features(flag int, enabled bool) EnvOption { return func(e *Env) (*Env, error) { diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/github.com/google/cel-go/cel/program.go index f0971607241..6219a4da588 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/github.com/google/cel-go/cel/program.go @@ -49,7 +49,7 @@ type Program interface { // to support cancellation and timeouts. This method must be used in conjunction with the // InterruptCheckFrequency() option for cancellation interrupts to be impact evaluation. // - // The vars value may eitehr be an `interpreter.Activation` or `map[string]interface{}`. + // The vars value may either be an `interpreter.Activation` or `map[string]interface{}`. // // The output contract for `ContextEval` is otherwise identical to the `Eval` method. ContextEval(context.Context, interface{}) (ref.Val, *EvalDetails, error) @@ -168,6 +168,18 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) { } } + // Add the function bindings created via Function() options. + for _, fn := range e.functions { + bindings, err := fn.bindings() + if err != nil { + return nil, err + } + err = disp.Add(bindings...) + if err != nil { + return nil, err + } + } + // Set the attribute factory after the options have been set. var attrFactory interpreter.AttributeFactory if p.evalOpts&OptPartialEval == OptPartialEval { @@ -201,7 +213,10 @@ func newProgram(e *Env, ast *Ast, opts []ProgramOption) (Program, error) { factory := func(state interpreter.EvalState, costTracker *interpreter.CostTracker) (Program, error) { costTracker.Estimator = p.callCostEstimator costTracker.Limit = p.costLimit - decs := decorators + // Limit capacity to guarantee a reallocation when calling 'append(decs, ...)' below. This + // prevents the underlying memory from being shared between factory function calls causing + // undesired mutations. + decs := decorators[:len(decorators):len(decorators)] var observers []interpreter.EvalObserver if p.evalOpts&(OptExhaustiveEval|OptTrackState) != 0 { diff --git a/vendor/github.com/google/cel-go/checker/BUILD.bazel b/vendor/github.com/google/cel-go/checker/BUILD.bazel index 2ef326b988e..bec40b6e695 100644 --- a/vendor/github.com/google/cel-go/checker/BUILD.bazel +++ b/vendor/github.com/google/cel-go/checker/BUILD.bazel @@ -54,7 +54,7 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", - "@com_github_antlr//runtime/Go/antlr:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/github.com/google/cel-go/checker/checker.go index 99f7c5bdb86..fcddb1b2c28 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/github.com/google/cel-go/checker/checker.go @@ -80,10 +80,10 @@ func (c *checker) check(e *exprpb.Expr) { return } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: literal := e.GetConstExpr() - switch literal.ConstantKind.(type) { + switch literal.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: c.checkBoolLiteral(e) case *exprpb.Constant_BytesValue: @@ -149,8 +149,8 @@ func (c *checker) checkIdent(e *exprpb.Expr) { identExpr := e.GetIdentExpr() // Check to see if the identifier is declared. if ident := c.env.LookupIdent(identExpr.GetName()); ident != nil { - c.setType(e, ident.GetIdent().Type) - c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().Value)) + c.setType(e, ident.GetIdent().GetType()) + c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue())) // Overwrite the identifier with its fully qualified name. identExpr.Name = ident.GetName() return @@ -168,11 +168,9 @@ func (c *checker) checkSelect(e *exprpb.Expr) { if found { ident := c.env.LookupIdent(qname) if ident != nil { - if sel.TestOnly { - c.errors.expressionDoesNotSelectField(c.location(e)) - c.setType(e, decls.Bool) - return - } + // We don't check for a TestOnly expression here since the `found` result is + // always going to be false for TestOnly expressions. + // Rewrite the node to be a variable reference to the resolved fully-qualified // variable name. c.setType(e, ident.GetIdent().Type) @@ -188,27 +186,24 @@ func (c *checker) checkSelect(e *exprpb.Expr) { } // Interpret as field selection, first traversing down the operand. - c.check(sel.Operand) - targetType := c.getType(sel.Operand) + c.check(sel.GetOperand()) + targetType := substitute(c.mappings, c.getType(sel.GetOperand()), false) // Assume error type by default as most types do not support field selection. resultType := decls.Error switch kindOf(targetType) { case kindMap: // Maps yield their value type as the selection result type. mapType := targetType.GetMapType() - resultType = mapType.ValueType + resultType = mapType.GetValueType() case kindObject: // Objects yield their field type declaration as the selection result type, but only if // the field is defined. messageType := targetType - if fieldType, found := c.lookupFieldType( - c.location(e), - messageType.GetMessageType(), - sel.Field); found { + if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), sel.GetField()); found { resultType = fieldType.Type } case kindTypeParam: - // Set the operand type to DYN to prevent assignment to a potentionally incorrect type + // Set the operand type to DYN to prevent assignment to a potentially incorrect type // at a later point in type-checking. The isAssignable call will update the type // substitutions for the type param under the covers. c.isAssignable(decls.Dyn, targetType) @@ -226,7 +221,7 @@ func (c *checker) checkSelect(e *exprpb.Expr) { if sel.TestOnly { resultType = decls.Bool } - c.setType(e, resultType) + c.setType(e, substitute(c.mappings, resultType, false)) } func (c *checker) checkCall(e *exprpb.Expr) { @@ -322,35 +317,39 @@ func (c *checker) resolveOverload( var resultType *exprpb.Type var checkedRef *exprpb.Reference - for _, overload := range fn.GetFunction().Overloads { - if (target == nil && overload.IsInstanceFunction) || - (target != nil && !overload.IsInstanceFunction) { + for _, overload := range fn.GetFunction().GetOverloads() { + // Determine whether the overload is currently considered. + if c.env.isOverloadDisabled(overload.GetOverloadId()) { + continue + } + + // Ensure the call style for the overload matches. + if (target == nil && overload.GetIsInstanceFunction()) || + (target != nil && !overload.GetIsInstanceFunction()) { // not a compatible call style. continue } overloadType := decls.NewFunctionType(overload.ResultType, overload.Params...) - if len(overload.TypeParams) > 0 { + if len(overload.GetTypeParams()) > 0 { // Instantiate overload's type with fresh type variables. substitutions := newMapping() - for _, typePar := range overload.TypeParams { + for _, typePar := range overload.GetTypeParams() { substitutions.add(decls.NewTypeParamType(typePar), c.newTypeVar()) } overloadType = substitute(substitutions, overloadType, false) } - candidateArgTypes := overloadType.GetFunction().ArgTypes + candidateArgTypes := overloadType.GetFunction().GetArgTypes() if c.isAssignableList(argTypes, candidateArgTypes) { if checkedRef == nil { - checkedRef = newFunctionReference(overload.OverloadId) + checkedRef = newFunctionReference(overload.GetOverloadId()) } else { - checkedRef.OverloadId = append(checkedRef.OverloadId, overload.OverloadId) + checkedRef.OverloadId = append(checkedRef.GetOverloadId(), overload.GetOverloadId()) } // First matching overload, determines result type. - fnResultType := substitute(c.mappings, - overloadType.GetFunction().ResultType, - false) + fnResultType := substitute(c.mappings, overloadType.GetFunction().GetResultType(), false) if resultType == nil { resultType = fnResultType } else if !isDyn(resultType) && !proto.Equal(fnResultType, resultType) { @@ -371,7 +370,7 @@ func (c *checker) resolveOverload( func (c *checker) checkCreateList(e *exprpb.Expr) { create := e.GetListExpr() var elemType *exprpb.Type - for _, e := range create.Elements { + for _, e := range create.GetElements() { c.check(e) elemType = c.joinTypes(c.location(e), elemType, c.getType(e)) } @@ -384,7 +383,7 @@ func (c *checker) checkCreateList(e *exprpb.Expr) { func (c *checker) checkCreateStruct(e *exprpb.Expr) { str := e.GetStructExpr() - if str.MessageName != "" { + if str.GetMessageName() != "" { c.checkCreateMessage(e) } else { c.checkCreateMap(e) @@ -415,22 +414,22 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) { msgVal := e.GetStructExpr() // Determine the type of the message. messageType := decls.Error - decl := c.env.LookupIdent(msgVal.MessageName) + decl := c.env.LookupIdent(msgVal.GetMessageName()) if decl == nil { c.errors.undeclaredReference( - c.location(e), c.env.container.Name(), msgVal.MessageName) + c.location(e), c.env.container.Name(), msgVal.GetMessageName()) return } // Ensure the type name is fully qualified in the AST. msgVal.MessageName = decl.GetName() c.setReference(e, newIdentReference(decl.GetName(), nil)) ident := decl.GetIdent() - identKind := kindOf(ident.Type) + identKind := kindOf(ident.GetType()) if identKind != kindError { if identKind != kindType { - c.errors.notAType(c.location(e), ident.Type) + c.errors.notAType(c.location(e), ident.GetType()) } else { - messageType = ident.Type.GetType() + messageType = ident.GetType().GetType() if kindOf(messageType) != kindObject { c.errors.notAMessageType(c.location(e), messageType) messageType = decls.Error @@ -446,12 +445,12 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) { // Check the field initializers. for _, ent := range msgVal.GetEntries() { field := ent.GetFieldKey() - value := ent.Value + value := ent.GetValue() c.check(value) fieldType := decls.Error if t, found := c.lookupFieldType( - c.locationByID(ent.Id), + c.locationByID(ent.GetId()), messageType.GetMessageType(), field); found { fieldType = t.Type @@ -465,48 +464,48 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) { func (c *checker) checkComprehension(e *exprpb.Expr) { comp := e.GetComprehensionExpr() - c.check(comp.IterRange) - c.check(comp.AccuInit) - accuType := c.getType(comp.AccuInit) - rangeType := c.getType(comp.IterRange) + c.check(comp.GetIterRange()) + c.check(comp.GetAccuInit()) + accuType := c.getType(comp.GetAccuInit()) + rangeType := substitute(c.mappings, c.getType(comp.GetIterRange()), false) var varType *exprpb.Type switch kindOf(rangeType) { case kindList: - varType = rangeType.GetListType().ElemType + varType = rangeType.GetListType().GetElemType() case kindMap: // Ranges over the keys. - varType = rangeType.GetMapType().KeyType + varType = rangeType.GetMapType().GetKeyType() case kindDyn, kindError, kindTypeParam: - // Set the range type to DYN to prevent assignment to a potentionally incorrect type + // Set the range type to DYN to prevent assignment to a potentially incorrect type // at a later point in type-checking. The isAssignable call will update the type // substitutions for the type param under the covers. c.isAssignable(decls.Dyn, rangeType) // Set the range iteration variable to type DYN as well. varType = decls.Dyn default: - c.errors.notAComprehensionRange(c.location(comp.IterRange), rangeType) + c.errors.notAComprehensionRange(c.location(comp.GetIterRange()), rangeType) varType = decls.Error } // Create a scope for the comprehension since it has a local accumulation variable. // This scope will contain the accumulation variable used to compute the result. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.AccuVar, accuType)) + c.env.Add(decls.NewVar(comp.GetAccuVar(), accuType)) // Create a block scope for the loop. c.env = c.env.enterScope() - c.env.Add(decls.NewVar(comp.IterVar, varType)) + c.env.Add(decls.NewVar(comp.GetIterVar(), varType)) // Check the variable references in the condition and step. - c.check(comp.LoopCondition) - c.assertType(comp.LoopCondition, decls.Bool) - c.check(comp.LoopStep) - c.assertType(comp.LoopStep, accuType) + c.check(comp.GetLoopCondition()) + c.assertType(comp.GetLoopCondition(), decls.Bool) + c.check(comp.GetLoopStep()) + c.assertType(comp.GetLoopStep(), accuType) // Exit the loop's block scope before checking the result. c.env = c.env.exitScope() - c.check(comp.Result) + c.check(comp.GetResult()) // Exit the comprehension scope. c.env = c.env.exitScope() - c.setType(e, c.getType(comp.Result)) + c.setType(e, substitute(c.mappings, c.getType(comp.GetResult()), false)) } // Checks compatibility of joined types, and returns the most general common type. @@ -572,25 +571,25 @@ func (c *checker) lookupFieldType(l common.Location, messageType string, fieldNa } func (c *checker) setType(e *exprpb.Expr, t *exprpb.Type) { - if old, found := c.types[e.Id]; found && !proto.Equal(old, t) { + if old, found := c.types[e.GetId()]; found && !proto.Equal(old, t) { c.errors.ReportError(c.location(e), "(Incompatible) Type already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, t) return } - c.types[e.Id] = t + c.types[e.GetId()] = t } func (c *checker) getType(e *exprpb.Expr) *exprpb.Type { - return c.types[e.Id] + return c.types[e.GetId()] } func (c *checker) setReference(e *exprpb.Expr, r *exprpb.Reference) { - if old, found := c.references[e.Id]; found && !proto.Equal(old, r) { + if old, found := c.references[e.GetId()]; found && !proto.Equal(old, r) { c.errors.ReportError(c.location(e), - "Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.Id, old, r) + "Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, r) return } - c.references[e.Id] = r + c.references[e.GetId()] = r } func (c *checker) assertType(e *exprpb.Expr, t *exprpb.Type) { @@ -612,7 +611,7 @@ func newResolution(checkedRef *exprpb.Reference, t *exprpb.Type) *overloadResolu } func (c *checker) location(e *exprpb.Expr) common.Location { - return c.locationByID(e.Id) + return c.locationByID(e.GetId()) } func (c *checker) locationByID(id int64) common.Location { @@ -620,7 +619,7 @@ func (c *checker) locationByID(id int64) common.Location { var line = 1 if offset, found := positions[id]; found { col := int(offset) - for _, lineOffset := range c.sourceInfo.LineOffsets { + for _, lineOffset := range c.sourceInfo.GetLineOffsets() { if lineOffset < offset { line++ col = int(offset - lineOffset) diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go index 6f832d96b7e..7312d1fe2f8 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/github.com/google/cel-go/checker/cost.go @@ -88,9 +88,9 @@ func (e astNode) ComputedSize() *SizeEstimate { return e.derivedSize } var v uint64 - switch ek := e.expr.ExprKind.(type) { + switch ek := e.expr.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: - switch ck := ek.ConstExpr.ConstantKind.(type) { + switch ck := ek.ConstExpr.GetConstantKind().(type) { case *exprpb.Constant_StringValue: v = uint64(len(ck.StringValue)) case *exprpb.Constant_BytesValue: @@ -103,10 +103,10 @@ func (e astNode) ComputedSize() *SizeEstimate { return nil } case *exprpb.Expr_ListExpr: - v = uint64(len(ek.ListExpr.Elements)) + v = uint64(len(ek.ListExpr.GetElements())) case *exprpb.Expr_StructExpr: - if ek.StructExpr.MessageName == "" { - v = uint64(len(ek.StructExpr.Entries)) + if ek.StructExpr.GetMessageName() == "" { + v = uint64(len(ek.StructExpr.GetEntries())) } default: return nil @@ -121,7 +121,7 @@ type SizeEstimate struct { } // Add adds to another SizeEstimate and returns the sum. -// If add would result in an uint64 overflow, the result is Maxuint64. +// If add would result in an uint64 overflow, the result is math.MaxUint64. func (se SizeEstimate) Add(sizeEstimate SizeEstimate) SizeEstimate { return SizeEstimate{ addUint64NoOverflow(se.Min, sizeEstimate.Min), @@ -130,7 +130,7 @@ func (se SizeEstimate) Add(sizeEstimate SizeEstimate) SizeEstimate { } // Multiply multiplies by another SizeEstimate and returns the product. -// If multiply would result in an uint64 overflow, the result is Maxuint64. +// If multiply would result in an uint64 overflow, the result is math.MaxUint64. func (se SizeEstimate) Multiply(sizeEstimate SizeEstimate) SizeEstimate { return SizeEstimate{ multiplyUint64NoOverflow(se.Min, sizeEstimate.Min), @@ -148,7 +148,7 @@ func (se SizeEstimate) MultiplyByCostFactor(costPerUnit float64) CostEstimate { } // MultiplyByCost multiplies by the cost and returns the product. -// If multiply would result in an uint64 overflow, the result is Maxuint64. +// If multiply would result in an uint64 overflow, the result is math.MaxUint64. func (se SizeEstimate) MultiplyByCost(cost CostEstimate) CostEstimate { return CostEstimate{ multiplyUint64NoOverflow(se.Min, cost.Min), @@ -175,7 +175,7 @@ type CostEstimate struct { } // Add adds the costs and returns the sum. -// If add would result in an uint64 overflow for the min or max, the value is set to Maxuint64. +// If add would result in an uint64 overflow for the min or max, the value is set to math.MaxUint64. func (ce CostEstimate) Add(cost CostEstimate) CostEstimate { return CostEstimate{ addUint64NoOverflow(ce.Min, cost.Min), @@ -184,7 +184,7 @@ func (ce CostEstimate) Add(cost CostEstimate) CostEstimate { } // Multiply multiplies by the cost and returns the product. -// If multiply would result in an uint64 overflow, the result is Maxuint64. +// If multiply would result in an uint64 overflow, the result is math.MaxUint64. func (ce CostEstimate) Multiply(cost CostEstimate) CostEstimate { return CostEstimate{ multiplyUint64NoOverflow(ce.Min, cost.Min), @@ -297,7 +297,7 @@ func (c *coster) cost(e *exprpb.Expr) CostEstimate { return CostEstimate{} } var cost CostEstimate - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_ConstExpr: cost = constCost case *exprpb.Expr_IdentExpr: @@ -323,7 +323,7 @@ func (c *coster) costIdent(e *exprpb.Expr) CostEstimate { // build and track the field path if iterRange, ok := c.iterRanges.peek(identExpr.GetName()); ok { - switch c.checkedExpr.TypeMap[iterRange].TypeKind.(type) { + switch c.checkedExpr.TypeMap[iterRange].GetTypeKind().(type) { case *exprpb.Type_ListType_: c.addPath(e, append(c.exprPath[iterRange], "@items")) case *exprpb.Type_MapType_: @@ -350,7 +350,7 @@ func (c *coster) costSelect(e *exprpb.Expr) CostEstimate { } // build and track the field path - c.addPath(e, append(c.getPath(sel.GetOperand()), sel.Field)) + c.addPath(e, append(c.getPath(sel.GetOperand()), sel.GetField())) return sum } diff --git a/vendor/github.com/google/cel-go/checker/decls/scopes.go b/vendor/github.com/google/cel-go/checker/decls/scopes.go index 1064c73b1f5..608bca3e537 100644 --- a/vendor/github.com/google/cel-go/checker/decls/scopes.go +++ b/vendor/github.com/google/cel-go/checker/decls/scopes.go @@ -33,6 +33,19 @@ func NewScopes() *Scopes { } } +// Copy creates a copy of the current Scopes values, including a copy of its parent if non-nil. +func (s *Scopes) Copy() *Scopes { + cpy := NewScopes() + if s == nil { + return cpy + } + if s.parent != nil { + cpy.parent = s.parent.Copy() + } + cpy.scopes = s.scopes.copy() + return cpy +} + // Push creates a new Scopes value which references the current Scope as its parent. func (s *Scopes) Push() *Scopes { return &Scopes{ @@ -80,9 +93,9 @@ func (s *Scopes) FindIdentInScope(name string) *exprpb.Decl { return nil } -// AddFunction adds the function Decl to the current scope. +// SetFunction adds the function Decl to the current scope. // Note: Any previous entry for a function in the current scope with the same name is overwritten. -func (s *Scopes) AddFunction(fn *exprpb.Decl) { +func (s *Scopes) SetFunction(fn *exprpb.Decl) { s.scopes.functions[fn.Name] = fn } @@ -100,13 +113,30 @@ func (s *Scopes) FindFunction(name string) *exprpb.Decl { } // Group is a set of Decls that is pushed on or popped off a Scopes as a unit. -// Contains separate namespaces for idenifier and function Decls. +// Contains separate namespaces for identifier and function Decls. // (Should be named "Scope" perhaps?) type Group struct { idents map[string]*exprpb.Decl functions map[string]*exprpb.Decl } +// copy creates a new Group instance with a shallow copy of the variables and functions. +// If callers need to mutate the exprpb.Decl definitions for a Function, they should copy-on-write. +func (g *Group) copy() *Group { + cpy := &Group{ + idents: make(map[string]*exprpb.Decl, len(g.idents)), + functions: make(map[string]*exprpb.Decl, len(g.functions)), + } + for n, id := range g.idents { + cpy.idents[n] = id + } + for n, fn := range g.functions { + cpy.functions[n] = fn + } + return cpy +} + +// newGroup creates a new Group with empty maps for identifiers and functions. func newGroup() *Group { return &Group{ idents: make(map[string]*exprpb.Decl), diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/github.com/google/cel-go/checker/env.go index 659f2ec9339..c7eeb04eee6 100644 --- a/vendor/github.com/google/cel-go/checker/env.go +++ b/vendor/github.com/google/cel-go/checker/env.go @@ -18,6 +18,8 @@ import ( "fmt" "strings" + "google.golang.org/protobuf/proto" + "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/overloads" @@ -99,6 +101,9 @@ func NewEnv(container *containers.Container, provider ref.TypeProvider, opts ... if envOptions.crossTypeNumericComparisons { filteredOverloadIDs = make(map[string]struct{}) } + if envOptions.validatedDeclarations != nil { + declarations = envOptions.validatedDeclarations.Copy() + } return &Env{ container: container, provider: provider, @@ -117,7 +122,7 @@ func (e *Env) Add(decls ...*exprpb.Decl) error { case *exprpb.Decl_Ident: errMsgs = append(errMsgs, e.addIdent(sanitizeIdent(decl))) case *exprpb.Decl_Function: - errMsgs = append(errMsgs, e.addFunction(sanitizeFunction(decl))...) + errMsgs = append(errMsgs, e.setFunction(sanitizeFunction(decl))...) } } return formatError(errMsgs) @@ -176,8 +181,7 @@ func (e *Env) addOverload(f *exprpb.Decl, overload *exprpb.Decl_FunctionDecl_Ove overload.GetParams()...) overloadErased := substitute(emptyMappings, overloadFunction, true) for _, existing := range function.GetOverloads() { - existingFunction := decls.NewFunctionType(existing.GetResultType(), - existing.GetParams()...) + existingFunction := decls.NewFunctionType(existing.GetResultType(), existing.GetParams()...) existingErased := substitute(emptyMappings, existingFunction, true) overlap := isAssignable(emptyMappings, overloadErased, existingErased) != nil || isAssignable(emptyMappings, existingErased, overloadErased) != nil @@ -204,22 +208,37 @@ func (e *Env) addOverload(f *exprpb.Decl, overload *exprpb.Decl_FunctionDecl_Ove return errMsgs } -// addFunction adds the function Decl to the Env. +// setFunction adds the function Decl to the Env. // Adds a function decl if one doesn't already exist, then adds all overloads from the Decl. // If overload overlaps with an existing overload, adds to the errors in the Env instead. -func (e *Env) addFunction(decl *exprpb.Decl) []errorMsg { +func (e *Env) setFunction(decl *exprpb.Decl) []errorMsg { + errorMsgs := make([]errorMsg, 0) + overloads := decl.GetFunction().GetOverloads() current := e.declarations.FindFunction(decl.Name) if current == nil { //Add the function declaration without overloads and check the overloads below. current = decls.NewFunction(decl.Name) - e.declarations.AddFunction(current) - } - - errorMsgs := make([]errorMsg, 0) - for _, overload := range decl.GetFunction().GetOverloads() { - if _, found := e.filteredOverloadIDs[overload.GetOverloadId()]; found { - continue + } else { + existingOverloads := map[string]*exprpb.Decl_FunctionDecl_Overload{} + for _, overload := range current.GetFunction().GetOverloads() { + existingOverloads[overload.GetOverloadId()] = overload + } + newOverloads := []*exprpb.Decl_FunctionDecl_Overload{} + for _, overload := range overloads { + existing, found := existingOverloads[overload.GetOverloadId()] + if !found || !proto.Equal(existing, overload) { + newOverloads = append(newOverloads, overload) + } } + overloads = newOverloads + if len(newOverloads) == 0 { + return errorMsgs + } + // Copy on write since we don't know where this original definition came from. + current = proto.Clone(current).(*exprpb.Decl) + } + e.declarations.SetFunction(current) + for _, overload := range overloads { errorMsgs = append(errorMsgs, e.addOverload(current, overload)...) } return errorMsgs @@ -230,12 +249,21 @@ func (e *Env) addFunction(decl *exprpb.Decl) []errorMsg { func (e *Env) addIdent(decl *exprpb.Decl) errorMsg { current := e.declarations.FindIdentInScope(decl.Name) if current != nil { + if proto.Equal(current, decl) { + return "" + } return overlappingIdentifierError(decl.Name) } e.declarations.AddIdent(decl) return "" } +// isOverloadDisabled returns whether the overloadID is disabled in the current environment. +func (e *Env) isOverloadDisabled(overloadID string) bool { + _, found := e.filteredOverloadIDs[overloadID] + return found +} + // sanitizeFunction replaces well-known types referenced by message name with their equivalent // CEL built-in type instances. func sanitizeFunction(decl *exprpb.Decl) *exprpb.Decl { @@ -313,6 +341,12 @@ func getObjectWellKnownType(t *exprpb.Type) *exprpb.Type { return pb.CheckedWellKnowns[t.GetMessageType()] } +// validatedDeclarations returns a reference to the validated variable and function declaration scope stack. +// must be copied before use. +func (e *Env) validatedDeclarations() *decls.Scopes { + return e.declarations +} + // enterScope creates a new Env instance with a new innermost declaration scope. func (e *Env) enterScope() *Env { childDecls := e.declarations.Push() diff --git a/vendor/github.com/google/cel-go/checker/errors.go b/vendor/github.com/google/cel-go/checker/errors.go index 06566aecfbb..0014f9abe1c 100644 --- a/vendor/github.com/google/cel-go/checker/errors.go +++ b/vendor/github.com/google/cel-go/checker/errors.go @@ -29,10 +29,6 @@ func (e *typeErrors) undeclaredReference(l common.Location, container string, na e.ReportError(l, "undeclared reference to '%s' (in container '%s')", name, container) } -func (e *typeErrors) expressionDoesNotSelectField(l common.Location) { - e.ReportError(l, "expression does not select a field") -} - func (e *typeErrors) typeDoesNotSupportFieldSelection(l common.Location, t *exprpb.Type) { e.ReportError(l, "type '%s' does not support field selection", t) } diff --git a/vendor/github.com/google/cel-go/checker/options.go b/vendor/github.com/google/cel-go/checker/options.go index cacae10e731..cded00a660d 100644 --- a/vendor/github.com/google/cel-go/checker/options.go +++ b/vendor/github.com/google/cel-go/checker/options.go @@ -14,9 +14,12 @@ package checker +import "github.com/google/cel-go/checker/decls" + type options struct { crossTypeNumericComparisons bool homogeneousAggregateLiterals bool + validatedDeclarations *decls.Scopes } // Option is a functional option for configuring the type-checker @@ -39,3 +42,12 @@ func HomogeneousAggregateLiterals(enabled bool) Option { return nil } } + +// ValidatedDeclarations provides a references to validated declarations which will be copied +// into new checker instances. +func ValidatedDeclarations(env *Env) Option { + return func(opts *options) error { + opts.validatedDeclarations = env.validatedDeclarations() + return nil + } +} diff --git a/vendor/github.com/google/cel-go/checker/printer.go b/vendor/github.com/google/cel-go/checker/printer.go index 15c25ecc686..e2ed35be834 100644 --- a/vendor/github.com/google/cel-go/checker/printer.go +++ b/vendor/github.com/google/cel-go/checker/printer.go @@ -32,22 +32,22 @@ func (a *semanticAdorner) GetMetadata(elem interface{}) string { if !isExpr { return result } - t := a.checks.TypeMap[e.Id] + t := a.checks.TypeMap[e.GetId()] if t != nil { result += "~" result += FormatCheckedType(t) } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr, *exprpb.Expr_CallExpr, *exprpb.Expr_StructExpr, *exprpb.Expr_SelectExpr: - if ref, found := a.checks.ReferenceMap[e.Id]; found { + if ref, found := a.checks.ReferenceMap[e.GetId()]; found { if len(ref.GetOverloadId()) == 0 { result += "^" + ref.Name } else { - for i, overload := range ref.OverloadId { + for i, overload := range ref.GetOverloadId() { if i == 0 { result += "^" } else { diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/github.com/google/cel-go/checker/types.go index 38c11d41a0d..8683797d5bb 100644 --- a/vendor/github.com/google/cel-go/checker/types.go +++ b/vendor/github.com/google/cel-go/checker/types.go @@ -52,13 +52,13 @@ func FormatCheckedType(t *exprpb.Type) string { t.GetFunction().GetArgTypes(), false) case kindList: - return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().ElemType)) + return fmt.Sprintf("list(%s)", FormatCheckedType(t.GetListType().GetElemType())) case kindObject: return t.GetMessageType() case kindMap: return fmt.Sprintf("map(%s, %s)", - FormatCheckedType(t.GetMapType().KeyType), - FormatCheckedType(t.GetMapType().ValueType)) + FormatCheckedType(t.GetMapType().GetKeyType()), + FormatCheckedType(t.GetMapType().GetValueType())) case kindNull: return "null" case kindPrimitive: @@ -88,6 +88,8 @@ func FormatCheckedType(t *exprpb.Type) string { FormatCheckedType(decls.NewPrimitiveType(t.GetWrapper()))) case kindError: return "!error!" + case kindTypeParam: + return t.GetTypeParam() } return t.String() } @@ -149,28 +151,13 @@ func isEqualOrLessSpecific(t1 *exprpb.Type, t2 *exprpb.Type) bool { } } return true - case kindFunction: - fn1 := t1.GetFunction() - fn2 := t2.GetFunction() - if len(fn1.ArgTypes) != len(fn2.ArgTypes) { - return false - } - if !isEqualOrLessSpecific(fn1.ResultType, fn2.ResultType) { - return false - } - for i, a1 := range fn1.ArgTypes { - if !isEqualOrLessSpecific(a1, fn2.ArgTypes[i]) { - return false - } - } - return true case kindList: - return isEqualOrLessSpecific(t1.GetListType().ElemType, t2.GetListType().ElemType) + return isEqualOrLessSpecific(t1.GetListType().GetElemType(), t2.GetListType().GetElemType()) case kindMap: m1 := t1.GetMapType() m2 := t2.GetMapType() - return isEqualOrLessSpecific(m1.KeyType, m2.KeyType) && - isEqualOrLessSpecific(m1.ValueType, m2.ValueType) + return isEqualOrLessSpecific(m1.GetKeyType(), m2.GetKeyType()) && + isEqualOrLessSpecific(m1.GetValueType(), m2.GetValueType()) case kindType: return true default: @@ -178,45 +165,28 @@ func isEqualOrLessSpecific(t1 *exprpb.Type, t2 *exprpb.Type) bool { } } -/// internalIsAssignable returns true if t1 is assignable to t2. +// / internalIsAssignable returns true if t1 is assignable to t2. func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { - // A type is always assignable to itself. - // Early terminate the call to avoid cases of infinite recursion. - if proto.Equal(t1, t2) { - return true - } // Process type parameters. kind1, kind2 := kindOf(t1), kindOf(t2) if kind2 == kindTypeParam { - if t2Sub, found := m.find(t2); found { - // If the types are compatible, pick the more general type and return true - if !internalIsAssignable(m, t1, t2Sub) { - return false - } - m.add(t2, mostGeneral(t1, t2Sub)) + // If t2 is a valid type substitution for t1, return true. + valid, t2HasSub := isValidTypeSubstitution(m, t1, t2) + if valid { return true } - if notReferencedIn(m, t2, t1) { - m.add(t2, t1) - return true + // If t2 is not a valid type sub for t1, and already has a known substitution return false + // since it is not possible for t1 to be a substitution for t2. + if !valid && t2HasSub { + return false } + // Otherwise, fall through to check whether t1 is a possible substitution for t2. } if kind1 == kindTypeParam { - // For the lower type bound, we currently do not perform adjustment. The restricted - // way we use type parameters in lower type bounds, it is not necessary, but may - // become if we generalize type unification. - if t1Sub, found := m.find(t1); found { - // If the types are compatible, pick the more general type and return true - if !internalIsAssignable(m, t1Sub, t2) { - return false - } - m.add(t1, mostGeneral(t1Sub, t2)) - return true - } - if notReferencedIn(m, t1, t2) { - m.add(t1, t2) - return true - } + // Return whether t1 is a valid substitution for t2. If not, do no additional checks as the + // possible type substitutions have been searched in both directions. + valid, _ := isValidTypeSubstitution(m, t2, t1) + return valid } // Next check for wildcard types. @@ -262,25 +232,54 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool { } } -// internalIsAssignableAbstractType returns true if the abstract type names agree and all type -// parameters are assignable. -func internalIsAssignableAbstractType(m *mapping, - a1 *exprpb.Type_AbstractType, - a2 *exprpb.Type_AbstractType) bool { - if a1.GetName() != a2.GetName() { - return false +// isValidTypeSubstitution returns whether t2 (or its type substitution) is a valid type +// substitution for t1, and whether t2 has a type substitution in mapping m. +// +// The type t2 is a valid substitution for t1 if any of the following statements is true +// - t2 has a type substitition (t2sub) equal to t1 +// - t2 has a type substitution (t2sub) assignable to t1 +// - t2 does not occur within t1. +func isValidTypeSubstitution(m *mapping, t1, t2 *exprpb.Type) (valid, hasSub bool) { + // Early return if the t1 and t2 are the same instance. + kind1, kind2 := kindOf(t1), kindOf(t2) + if kind1 == kind2 && (t1 == t2 || proto.Equal(t1, t2)) { + return true, true + } + if t2Sub, found := m.find(t2); found { + // Early return if t1 and t2Sub are the same instance as otherwise the mapping + // might mark a type as being a subtitution for itself. + if kind1 == kindOf(t2Sub) && (t1 == t2Sub || proto.Equal(t1, t2Sub)) { + return true, true + } + // If the types are compatible, pick the more general type and return true + if internalIsAssignable(m, t1, t2Sub) { + t2New := mostGeneral(t1, t2Sub) + // only update the type reference map if the target type does not occur within it. + if notReferencedIn(m, t2, t2New) { + m.add(t2, t2New) + } + // acknowledge the type agreement, and that the substitution is already tracked. + return true, true + } + return false, true } - if internalIsAssignableList(m, a1.GetParameterTypes(), a2.GetParameterTypes()) { - return true + if notReferencedIn(m, t2, t1) { + m.add(t2, t1) + return true, false } - return false + return false, false +} + +// internalIsAssignableAbstractType returns true if the abstract type names agree and all type +// parameters are assignable. +func internalIsAssignableAbstractType(m *mapping, a1 *exprpb.Type_AbstractType, a2 *exprpb.Type_AbstractType) bool { + return a1.GetName() == a2.GetName() && + internalIsAssignableList(m, a1.GetParameterTypes(), a2.GetParameterTypes()) } // internalIsAssignableFunction returns true if the function return type and arg types are // assignable. -func internalIsAssignableFunction(m *mapping, - f1 *exprpb.Type_FunctionType, - f2 *exprpb.Type_FunctionType) bool { +func internalIsAssignableFunction(m *mapping, f1 *exprpb.Type_FunctionType, f2 *exprpb.Type_FunctionType) bool { f1ArgTypes := flattenFunctionTypes(f1) f2ArgTypes := flattenFunctionTypes(f2) if internalIsAssignableList(m, f1ArgTypes, f2ArgTypes) { @@ -360,7 +359,7 @@ func kindOf(t *exprpb.Type) int { if t == nil || t.TypeKind == nil { return kindUnknown } - switch t.TypeKind.(type) { + switch t.GetTypeKind().(type) { case *exprpb.Type_Error: return kindError case *exprpb.Type_Function: @@ -421,20 +420,11 @@ func notReferencedIn(m *mapping, t *exprpb.Type, withinType *exprpb.Type) bool { } } return true - case kindFunction: - fn := withinType.GetFunction() - types := flattenFunctionTypes(fn) - for _, a := range types { - if !notReferencedIn(m, t, a) { - return false - } - } - return true case kindList: - return notReferencedIn(m, t, withinType.GetListType().ElemType) + return notReferencedIn(m, t, withinType.GetListType().GetElemType()) case kindMap: mt := withinType.GetMapType() - return notReferencedIn(m, t, mt.KeyType) && notReferencedIn(m, t, mt.ValueType) + return notReferencedIn(m, t, mt.GetKeyType()) && notReferencedIn(m, t, mt.GetValueType()) case kindWrapper: return notReferencedIn(m, t, decls.NewPrimitiveType(withinType.GetWrapper())) default: @@ -454,7 +444,6 @@ func substitute(m *mapping, t *exprpb.Type, typeParamToDyn bool) *exprpb.Type { } switch kind { case kindAbstract: - // TODO: implement! at := t.GetAbstractType() params := make([]*exprpb.Type, len(at.GetParameterTypes())) for i, p := range at.GetParameterTypes() { @@ -464,17 +453,17 @@ func substitute(m *mapping, t *exprpb.Type, typeParamToDyn bool) *exprpb.Type { case kindFunction: fn := t.GetFunction() rt := substitute(m, fn.ResultType, typeParamToDyn) - args := make([]*exprpb.Type, len(fn.ArgTypes)) + args := make([]*exprpb.Type, len(fn.GetArgTypes())) for i, a := range fn.ArgTypes { args[i] = substitute(m, a, typeParamToDyn) } return decls.NewFunctionType(rt, args...) case kindList: - return decls.NewListType(substitute(m, t.GetListType().ElemType, typeParamToDyn)) + return decls.NewListType(substitute(m, t.GetListType().GetElemType(), typeParamToDyn)) case kindMap: mt := t.GetMapType() - return decls.NewMapType(substitute(m, mt.KeyType, typeParamToDyn), - substitute(m, mt.ValueType, typeParamToDyn)) + return decls.NewMapType(substitute(m, mt.GetKeyType(), typeParamToDyn), + substitute(m, mt.GetValueType(), typeParamToDyn)) case kindType: if t.GetType() != nil { return decls.NewTypeType(substitute(m, t.GetType(), typeParamToDyn)) diff --git a/vendor/github.com/google/cel-go/common/containers/container.go b/vendor/github.com/google/cel-go/common/containers/container.go index 07ae72c81be..d46698d3cdf 100644 --- a/vendor/github.com/google/cel-go/common/containers/container.go +++ b/vendor/github.com/google/cel-go/common/containers/container.go @@ -98,12 +98,12 @@ func (c *Container) Name() string { // // Given a container name a.b.c.M.N and a type name R.s, this will deliver in order: // -// a.b.c.M.N.R.s -// a.b.c.M.R.s -// a.b.c.R.s -// a.b.R.s -// a.R.s -// R.s +// a.b.c.M.N.R.s +// a.b.c.M.R.s +// a.b.c.R.s +// a.b.R.s +// a.R.s +// R.s // // If aliases or abbreviations are configured for the container, then alias names will take // precedence over containerized names. @@ -145,9 +145,9 @@ func (c *Container) aliasSet() map[string]string { // If the name is qualified, the first component of the qualified name is checked against known // aliases. Any alias that is found in a qualified name is expanded in the result: // -// alias: R -> my.alias.R -// name: R.S.T -// output: my.alias.R.S.T +// alias: R -> my.alias.R +// name: R.S.T +// output: my.alias.R.S.T // // Note, the name must not have a leading dot. func (c *Container) findAlias(name string) (string, bool) { @@ -177,19 +177,19 @@ type ContainerOption func(*Container) (*Container, error) // Abbreviations can be useful when working with variables, functions, and especially types from // multiple namespaces: // -// // CEL object construction -// qual.pkg.version.ObjTypeName{ -// field: alt.container.ver.FieldTypeName{value: ...} -// } +// // CEL object construction +// qual.pkg.version.ObjTypeName{ +// field: alt.container.ver.FieldTypeName{value: ...} +// } // // Only one the qualified names above may be used as the CEL container, so at least one of these // references must be a long qualified name within an otherwise short CEL program. Using the // following abbreviations, the program becomes much simpler: // -// // CEL Go option -// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName") -// // Simplified Object construction -// ObjTypeName{field: FieldTypeName{value: ...}} +// // CEL Go option +// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName") +// // Simplified Object construction +// ObjTypeName{field: FieldTypeName{value: ...}} // // There are a few rules for the qualified names and the simple abbreviations generated from them: // - Qualified names must be dot-delimited, e.g. `package.subpkg.name`. @@ -198,13 +198,13 @@ type ContainerOption func(*Container) (*Container, error) // - The abbreviation must not collide with unqualified names in use. // // Abbreviations are distinct from container-based references in the following important ways: -// - Abbreviations must expand to a fully-qualified name. -// - Expanded abbreviations do not participate in namespace resolution. -// - Abbreviation expansion is done instead of the container search for a matching identifier. -// - Containers follow C++ namespace resolution rules with searches from the most qualified name -// to the least qualified name. -// - Container references within the CEL program may be relative, and are resolved to fully -// qualified names at either type-check time or program plan time, whichever comes first. +// - Abbreviations must expand to a fully-qualified name. +// - Expanded abbreviations do not participate in namespace resolution. +// - Abbreviation expansion is done instead of the container search for a matching identifier. +// - Containers follow C++ namespace resolution rules with searches from the most qualified name +// to the least qualified name. +// - Container references within the CEL program may be relative, and are resolved to fully +// qualified names at either type-check time or program plan time, whichever comes first. // // If there is ever a case where an identifier could be in both the container and as an // abbreviation, the abbreviation wins as this will ensure that the meaning of a program is @@ -298,18 +298,18 @@ func Name(name string) ContainerOption { // ToQualifiedName converts an expression AST into a qualified name if possible, with a boolean // 'found' value that indicates if the conversion is successful. func ToQualifiedName(e *exprpb.Expr) (string, bool) { - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr: id := e.GetIdentExpr() - return id.Name, true + return id.GetName(), true case *exprpb.Expr_SelectExpr: sel := e.GetSelectExpr() // Test only expressions are not valid as qualified names. if sel.GetTestOnly() { return "", false } - if qual, found := ToQualifiedName(sel.Operand); found { - return qual + "." + sel.Field, true + if qual, found := ToQualifiedName(sel.GetOperand()); found { + return qual + "." + sel.GetField(), true } } return "", false diff --git a/vendor/github.com/google/cel-go/common/debug/debug.go b/vendor/github.com/google/cel-go/common/debug/debug.go index 5a4894733d4..bec885424b1 100644 --- a/vendor/github.com/google/cel-go/common/debug/debug.go +++ b/vendor/github.com/google/cel-go/common/debug/debug.go @@ -102,9 +102,9 @@ func (w *debugWriter) Buffer(e *exprpb.Expr) { } func (w *debugWriter) appendSelect(sel *exprpb.Expr_Select) { - w.Buffer(sel.Operand) + w.Buffer(sel.GetOperand()) w.append(".") - w.append(sel.Field) + w.append(sel.GetField()) if sel.TestOnly { w.append("~test-only~") } @@ -112,15 +112,15 @@ func (w *debugWriter) appendSelect(sel *exprpb.Expr_Select) { func (w *debugWriter) appendCall(call *exprpb.Expr_Call) { if call.Target != nil { - w.Buffer(call.Target) + w.Buffer(call.GetTarget()) w.append(".") } - w.append(call.Function) + w.append(call.GetFunction()) w.append("(") if len(call.GetArgs()) > 0 { w.addIndent() w.appendLine() - for i, arg := range call.Args { + for i, arg := range call.GetArgs() { if i > 0 { w.append(",") w.appendLine() @@ -138,7 +138,7 @@ func (w *debugWriter) appendList(list *exprpb.Expr_CreateList) { if len(list.GetElements()) > 0 { w.appendLine() w.addIndent() - for i, elem := range list.Elements { + for i, elem := range list.GetElements() { if i > 0 { w.append(",") w.appendLine() @@ -160,19 +160,19 @@ func (w *debugWriter) appendStruct(obj *exprpb.Expr_CreateStruct) { } func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) { - w.append(obj.MessageName) + w.append(obj.GetMessageName()) w.append("{") - if len(obj.Entries) > 0 { + if len(obj.GetEntries()) > 0 { w.appendLine() w.addIndent() - for i, entry := range obj.Entries { + for i, entry := range obj.GetEntries() { if i > 0 { w.append(",") w.appendLine() } w.append(entry.GetFieldKey()) w.append(":") - w.Buffer(entry.Value) + w.Buffer(entry.GetValue()) w.adorn(entry) } w.removeIndent() @@ -183,17 +183,17 @@ func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) { func (w *debugWriter) appendMap(obj *exprpb.Expr_CreateStruct) { w.append("{") - if len(obj.Entries) > 0 { + if len(obj.GetEntries()) > 0 { w.appendLine() w.addIndent() - for i, entry := range obj.Entries { + for i, entry := range obj.GetEntries() { if i > 0 { w.append(",") w.appendLine() } w.Buffer(entry.GetMapKey()) w.append(":") - w.Buffer(entry.Value) + w.Buffer(entry.GetValue()) w.adorn(entry) } w.removeIndent() @@ -208,43 +208,43 @@ func (w *debugWriter) appendComprehension(comprehension *exprpb.Expr_Comprehensi w.appendLine() w.append("// Variable") w.appendLine() - w.append(comprehension.IterVar) + w.append(comprehension.GetIterVar()) w.append(",") w.appendLine() w.append("// Target") w.appendLine() - w.Buffer(comprehension.IterRange) + w.Buffer(comprehension.GetIterRange()) w.append(",") w.appendLine() w.append("// Accumulator") w.appendLine() - w.append(comprehension.AccuVar) + w.append(comprehension.GetAccuVar()) w.append(",") w.appendLine() w.append("// Init") w.appendLine() - w.Buffer(comprehension.AccuInit) + w.Buffer(comprehension.GetAccuInit()) w.append(",") w.appendLine() w.append("// LoopCondition") w.appendLine() - w.Buffer(comprehension.LoopCondition) + w.Buffer(comprehension.GetLoopCondition()) w.append(",") w.appendLine() w.append("// LoopStep") w.appendLine() - w.Buffer(comprehension.LoopStep) + w.Buffer(comprehension.GetLoopStep()) w.append(",") w.appendLine() w.append("// Result") w.appendLine() - w.Buffer(comprehension.Result) + w.Buffer(comprehension.GetResult()) w.append(")") w.removeIndent() } func formatLiteral(c *exprpb.Constant) string { - switch c.ConstantKind.(type) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: return fmt.Sprintf("%t", c.GetBoolValue()) case *exprpb.Constant_BytesValue: diff --git a/vendor/github.com/google/cel-go/common/error.go b/vendor/github.com/google/cel-go/common/error.go index bfe93d9737f..f91f7f8d109 100644 --- a/vendor/github.com/google/cel-go/common/error.go +++ b/vendor/github.com/google/cel-go/common/error.go @@ -31,6 +31,9 @@ type Error struct { const ( dot = "." ind = "^" + + // maxSnippetLength is the largest number of characters which can be rendered in an error message snippet. + maxSnippetLength = 16384 ) var ( @@ -45,7 +48,7 @@ func (e *Error) ToDisplayString(source Source) string { e.Location.Line(), e.Location.Column()+1, // add one to the 0-based column for display e.Message) - if snippet, found := source.Snippet(e.Location.Line()); found { + if snippet, found := source.Snippet(e.Location.Line()); found && len(snippet) <= maxSnippetLength { snippet := strings.Replace(snippet, "\t", " ", -1) srcLine := "\n | " + snippet var bytes = []byte(snippet) diff --git a/vendor/github.com/google/cel-go/common/errors.go b/vendor/github.com/google/cel-go/common/errors.go index 6be0fdef324..daebba8609a 100644 --- a/vendor/github.com/google/cel-go/common/errors.go +++ b/vendor/github.com/google/cel-go/common/errors.go @@ -17,23 +17,32 @@ package common import ( "fmt" "sort" + "strings" ) // Errors type which contains a list of errors observed during parsing. type Errors struct { - errors []Error - source Source + errors []Error + source Source + numErrors int + maxErrorsToReport int } // NewErrors creates a new instance of the Errors type. func NewErrors(source Source) *Errors { return &Errors{ - errors: []Error{}, - source: source} + errors: []Error{}, + source: source, + maxErrorsToReport: 100, + } } // ReportError records an error at a source location. func (e *Errors) ReportError(l Location, format string, args ...interface{}) { + e.numErrors++ + if e.numErrors > e.maxErrorsToReport { + return + } err := Error{ Location: l, Message: fmt.Sprintf(format, args...), @@ -46,18 +55,28 @@ func (e *Errors) GetErrors() []Error { return e.errors[:] } -// Append takes an Errors object as input creates a new Errors object with the current and input -// errors. +// Append creates a new Errors object with the current and input errors. func (e *Errors) Append(errs []Error) *Errors { return &Errors{ - errors: append(e.errors, errs...), - source: e.source, + errors: append(e.errors, errs...), + source: e.source, + numErrors: e.numErrors + len(errs), + maxErrorsToReport: e.maxErrorsToReport, } } // ToDisplayString returns the error set to a newline delimited string. func (e *Errors) ToDisplayString() string { - var result = "" + errorsInString := e.maxErrorsToReport + if e.numErrors > e.maxErrorsToReport { + // add one more error to indicate the number of errors truncated. + errorsInString++ + } else { + // otherwise the error set will just contain the number of errors. + errorsInString = e.numErrors + } + + result := make([]string, errorsInString) sort.SliceStable(e.errors, func(i, j int) bool { ei := e.errors[i].Location ej := e.errors[j].Location @@ -65,10 +84,14 @@ func (e *Errors) ToDisplayString() string { (ei.Line() == ej.Line() && ei.Column() < ej.Column()) }) for i, err := range e.errors { - if i >= 1 { - result += "\n" + // This can happen during the append of two errors objects + if i >= e.maxErrorsToReport { + break } - result += err.ToDisplayString(e.source) + result[i] = err.ToDisplayString(e.source) + } + if e.numErrors > e.maxErrorsToReport { + result[e.maxErrorsToReport] = fmt.Sprintf("%d more errors were truncated", e.numErrors-e.maxErrorsToReport) } - return result + return strings.Join(result, "\n") } diff --git a/vendor/github.com/google/cel-go/common/location.go b/vendor/github.com/google/cel-go/common/location.go index 31fce6cd317..ec3fa7cb50f 100644 --- a/vendor/github.com/google/cel-go/common/location.go +++ b/vendor/github.com/google/cel-go/common/location.go @@ -27,7 +27,7 @@ type SourceLocation struct { } var ( - // Location implements the SourcceLocation interface. + // Location implements the SourceLocation interface. _ Location = &SourceLocation{} // NoLocation is a particular illegal location. NoLocation = &SourceLocation{-1, -1} diff --git a/vendor/github.com/google/cel-go/common/operators/operators.go b/vendor/github.com/google/cel-go/common/operators/operators.go index 9c30b985b38..fa25dfb7f07 100644 --- a/vendor/github.com/google/cel-go/common/operators/operators.go +++ b/vendor/github.com/google/cel-go/common/operators/operators.go @@ -14,7 +14,7 @@ // Package operators defines the internal function names of operators. // -// ALl operators in the expression language are modelled as function calls. +// All operators in the expression language are modelled as function calls. package operators // String "names" for CEL operators. @@ -141,3 +141,13 @@ func Precedence(symbol string) int { } return op.precedence } + +// Arity returns the number of argument the operator takes +// -1 is returned if an undefined symbol is provided +func Arity(symbol string) int { + op, found := operatorMap[symbol] + if !found { + return -1 + } + return op.arity +} diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/github.com/google/cel-go/common/types/BUILD.bazel index 1f77c86a172..5f1b1cd1fd2 100644 --- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/types/BUILD.bazel @@ -73,6 +73,7 @@ go_test( "timestamp_test.go", "type_test.go", "uint_test.go", + "util_test.go", ], embed = [":go_default_library"], deps = [ diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/github.com/google/cel-go/common/types/bool.go index 0039ecc9acf..1b55ba9529e 100644 --- a/vendor/github.com/google/cel-go/common/types/bool.go +++ b/vendor/github.com/google/cel-go/common/types/bool.go @@ -130,12 +130,13 @@ func (b Bool) Value() interface{} { } // IsBool returns whether the input ref.Val or ref.Type is equal to BoolType. -func IsBool(elem interface{}) bool { - switch elem := elem.(type) { - case ref.Type: - return elem == BoolType +func IsBool(elem ref.Val) bool { + switch v := elem.(type) { + case Bool: + return true case ref.Val: - return IsBool(elem.Type()) + return v.Type() == BoolType + default: + return false } - return false } diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/github.com/google/cel-go/common/types/bytes.go index 9dd16bce03e..3575717ec71 100644 --- a/vendor/github.com/google/cel-go/common/types/bytes.go +++ b/vendor/github.com/google/cel-go/common/types/bytes.go @@ -53,7 +53,7 @@ func (b Bytes) Add(other ref.Val) ref.Val { return append(b, otherBytes...) } -// Compare implments traits.Comparer interface method by lexicographic ordering. +// Compare implements traits.Comparer interface method by lexicographic ordering. func (b Bytes) Compare(other ref.Val) ref.Val { otherBytes, ok := other.(Bytes) if !ok { diff --git a/vendor/github.com/google/cel-go/common/types/compare.go b/vendor/github.com/google/cel-go/common/types/compare.go index a6150ee7f61..e1968261802 100644 --- a/vendor/github.com/google/cel-go/common/types/compare.go +++ b/vendor/github.com/google/cel-go/common/types/compare.go @@ -16,6 +16,8 @@ package types import ( "math" + + "github.com/google/cel-go/common/types/ref" ) func compareDoubleInt(d Double, i Int) Int { @@ -74,7 +76,7 @@ func compareDouble(a, b Double) Int { return IntZero } -func compareInt(a, b Int) Int { +func compareInt(a, b Int) ref.Val { if a < b { return IntNegOne } @@ -84,7 +86,7 @@ func compareInt(a, b Int) Int { return IntZero } -func compareUint(a, b Uint) Int { +func compareUint(a, b Uint) ref.Val { if a < b { return IntNegOne } diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/github.com/google/cel-go/common/types/err.go index 1ae247f41c0..93d79cdcbc5 100644 --- a/vendor/github.com/google/cel-go/common/types/err.go +++ b/vendor/github.com/google/cel-go/common/types/err.go @@ -72,18 +72,13 @@ func MaybeNoSuchOverloadErr(val ref.Val) ref.Val { return ValOrErr(val, "no such overload") } -// ValOrErr either returns the existing error or create a new one. +// ValOrErr either returns the existing error or creates a new one. // TODO: Audit the use of this function and standardize the error messages and codes. func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val { - if val == nil { - return NewErr(format, args...) - } - switch val.Type() { - case ErrType, UnknownType: - return val - default: + if val == nil || !IsUnknownOrError(val) { return NewErr(format, args...) } + return val } // wrapErr wraps an existing Go error value into a CEL Err value. @@ -126,5 +121,10 @@ func (e *Err) Value() interface{} { // IsError returns whether the input element ref.Type or ref.Val is equal to // the ErrType singleton. func IsError(val ref.Val) bool { - return val.Type() == ErrType + switch val.(type) { + case *Err: + return true + default: + return false + } } diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go index 7451b9b3cfc..7230f7ea121 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -96,14 +96,16 @@ func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister { } // NewMutableList creates a new mutable list whose internal state can be modified. -// -// The mutable list only handles `Add` calls correctly as it is intended only for use within -// comprehension loops which generate an immutable result upon completion. -func NewMutableList(adapter ref.TypeAdapter) traits.Lister { +func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister { + var mutableValues []ref.Val return &mutableList{ - TypeAdapter: adapter, - baseList: nil, - mutableValues: []ref.Val{}, + baseList: &baseList{ + TypeAdapter: adapter, + value: mutableValues, + size: 0, + get: func(i int) interface{} { return mutableValues[i] }, + }, + mutableValues: mutableValues, } } @@ -238,16 +240,14 @@ func (l *baseList) Equal(other ref.Val) ref.Val { // Get implements the traits.Indexer interface method. func (l *baseList) Get(index ref.Val) ref.Val { - i, ok := index.(Int) - if !ok { - return ValOrErr(index, "unsupported index type '%s' in list", index.Type()) + ind, err := indexOrError(index) + if err != nil { + return ValOrErr(index, err.Error()) } - iv := int(i) - if iv < 0 || iv >= l.size { - return NewErr("index '%d' out of range in list size '%d'", i, l.Size()) + if ind < 0 || ind >= l.size { + return NewErr("index '%d' out of range in list size '%d'", ind, l.Size()) } - elem := l.get(iv) - return l.NativeToValue(elem) + return l.NativeToValue(l.get(ind)) } // Iterator implements the traits.Iterable interface method. @@ -272,20 +272,25 @@ func (l *baseList) Value() interface{} { // mutableList aggregates values into its internal storage. For use with internal CEL variables only. type mutableList struct { - ref.TypeAdapter *baseList mutableValues []ref.Val } // Add copies elements from the other list into the internal storage of the mutable list. +// The ref.Val returned by Add is the receiver. func (l *mutableList) Add(other ref.Val) ref.Val { - otherList, ok := other.(traits.Lister) - if !ok { + switch otherList := other.(type) { + case *mutableList: + l.mutableValues = append(l.mutableValues, otherList.mutableValues...) + l.size += len(otherList.mutableValues) + case traits.Lister: + for i := IntZero; i < otherList.Size().(Int); i++ { + l.size++ + l.mutableValues = append(l.mutableValues, otherList.Get(i)) + } + default: return MaybeNoSuchOverloadErr(otherList) } - for i := IntZero; i < otherList.Size().(Int); i++ { - l.mutableValues = append(l.mutableValues, otherList.Get(i)) - } return l } @@ -323,7 +328,7 @@ func (l *concatList) Add(other ref.Val) ref.Val { nextList: otherList} } -// Contains implments the traits.Container interface method. +// Contains implements the traits.Container interface method. func (l *concatList) Contains(elem ref.Val) ref.Val { // The concat list relies on the IsErrorOrUnknown checks against the input element to be // performed by the `prevList` and/or `nextList`. @@ -391,10 +396,11 @@ func (l *concatList) Equal(other ref.Val) ref.Val { // Get implements the traits.Indexer interface method. func (l *concatList) Get(index ref.Val) ref.Val { - i, ok := index.(Int) - if !ok { - return MaybeNoSuchOverloadErr(index) + ind, err := indexOrError(index) + if err != nil { + return ValOrErr(index, err.Error()) } + i := Int(ind) if i < l.prevList.Size().(Int) { return l.prevList.Get(i) } @@ -462,3 +468,22 @@ func (it *listIterator) Next() ref.Val { } return nil } + +func indexOrError(index ref.Val) (int, error) { + switch iv := index.(type) { + case Int: + return int(iv), nil + case Double: + if ik, ok := doubleToInt64Lossless(float64(iv)); ok { + return int(ik), nil + } + return -1, fmt.Errorf("unsupported index value %v in list", index) + case Uint: + if ik, ok := uint64ToInt64Lossless(uint64(iv)); ok { + return int(ik), nil + } + return -1, fmt.Errorf("unsupported index value %v in list", index) + default: + return -1, fmt.Errorf("unsupported index type '%s' in list", index.Type()) + } +} diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/github.com/google/cel-go/common/types/map.go index 486c208ca46..58655940244 100644 --- a/vendor/github.com/google/cel-go/common/types/map.go +++ b/vendor/github.com/google/cel-go/common/types/map.go @@ -105,7 +105,7 @@ var ( // This interface implements portions of the API surface area required by the traits.Mapper // interface. type mapAccessor interface { - // Find returns a value, if one exists, for the inpput key. + // Find returns a value, if one exists, for the input key. // // If the key is not found the function returns (nil, false). Find(ref.Val) (ref.Val, bool) @@ -429,7 +429,7 @@ func (a *refValMapAccessor) Find(key ref.Val) (ref.Val, bool) { case Double: if ik, ok := doubleToInt64Lossless(float64(k)); ok { if keyVal, found := a.mapVal[Int(ik)]; found { - return keyVal, true + return keyVal, found } } if uk, ok := doubleToUint64Lossless(float64(k)); ok { diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/github.com/google/cel-go/common/types/object.go index 5e4212fa3f2..5faf8551104 100644 --- a/vendor/github.com/google/cel-go/common/types/object.go +++ b/vendor/github.com/google/cel-go/common/types/object.go @@ -53,24 +53,24 @@ func NewObject(adapter ref.TypeAdapter, } func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - pb := o.value - if reflect.TypeOf(pb).AssignableTo(typeDesc) { - return pb, nil + srcPB := o.value + if reflect.TypeOf(srcPB).AssignableTo(typeDesc) { + return srcPB, nil } if reflect.TypeOf(o).AssignableTo(typeDesc) { return o, nil } switch typeDesc { case anyValueType: - _, isAny := pb.(*anypb.Any) + _, isAny := srcPB.(*anypb.Any) if isAny { - return pb, nil + return srcPB, nil } - return anypb.New(pb) + return anypb.New(srcPB) case jsonValueType: // Marshal the proto to JSON first, and then rehydrate as protobuf.Value as there is no // support for direct conversion from proto.Message to protobuf.Value. - bytes, err := protojson.Marshal(pb) + bytes, err := protojson.Marshal(srcPB) if err != nil { return nil, err } @@ -88,7 +88,10 @@ func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { val := reflect.New(typeDesc.Elem()).Interface() dstPB, ok := val.(proto.Message) if ok { - proto.Merge(dstPB, pb) + err := pb.Merge(dstPB, srcPB) + if err != nil { + return nil, fmt.Errorf("type conversion error: %v", err) + } return dstPB, nil } } diff --git a/vendor/github.com/google/cel-go/common/types/overflow.go b/vendor/github.com/google/cel-go/common/types/overflow.go index 99780c3558f..c68a921826b 100644 --- a/vendor/github.com/google/cel-go/common/types/overflow.go +++ b/vendor/github.com/google/cel-go/common/types/overflow.go @@ -316,7 +316,7 @@ func doubleToUint64Checked(v float64) (uint64, error) { return uint64(v), nil } -// int64toUint64Checked converts an int64 to a uint64 value. +// int64ToUint64Checked converts an int64 to a uint64 value. // // If the conversion fails due to overflow the error return value will be non-nil. func int64ToUint64Checked(v int64) (uint64, error) { @@ -326,7 +326,7 @@ func int64ToUint64Checked(v int64) (uint64, error) { return uint64(v), nil } -// int64toInt32Checked converts an int64 to an int32 value. +// int64ToInt32Checked converts an int64 to an int32 value. // // If the conversion fails due to overflow the error return value will be non-nil. func int64ToInt32Checked(v int64) (int32, error) { @@ -336,7 +336,7 @@ func int64ToInt32Checked(v int64) (int32, error) { return int32(v), nil } -// uint64toUint32Checked converts a uint64 to a uint32 value. +// uint64ToUint32Checked converts a uint64 to a uint32 value. // // If the conversion fails due to overflow the error return value will be non-nil. func uint64ToUint32Checked(v uint64) (uint32, error) { @@ -346,7 +346,7 @@ func uint64ToUint32Checked(v uint64) (uint32, error) { return uint32(v), nil } -// uint64toInt64Checked converts a uint64 to an int64 value. +// uint64ToInt64Checked converts a uint64 to an int64 value. // // If the conversion fails due to overflow the error return value will be non-nil. func uint64ToInt64Checked(v uint64) (int64, error) { diff --git a/vendor/github.com/google/cel-go/common/types/pb/equal.go b/vendor/github.com/google/cel-go/common/types/pb/equal.go index 392a9496198..76893d85eab 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/equal.go +++ b/vendor/github.com/google/cel-go/common/types/pb/equal.go @@ -21,7 +21,8 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/known/anypb" + + anypb "google.golang.org/protobuf/types/known/anypb" ) // Equal returns whether two proto.Message instances are equal using the following criteria: diff --git a/vendor/github.com/google/cel-go/common/types/pb/pb.go b/vendor/github.com/google/cel-go/common/types/pb/pb.go index d02fbe0c25c..457b47ceeee 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/pb.go +++ b/vendor/github.com/google/cel-go/common/types/pb/pb.go @@ -17,6 +17,8 @@ package pb import ( + "fmt" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" @@ -48,6 +50,31 @@ var ( } ) +// Merge will copy the source proto message into the destination, or error if the merge cannot be completed. +// +// Unlike the proto.Merge, this method will fallback to proto.Marshal/Unmarshal of the two proto messages do not +// share the same instance of their type descriptor. +func Merge(dstPB, srcPB proto.Message) error { + src, dst := srcPB.ProtoReflect(), dstPB.ProtoReflect() + if src.Descriptor() == dst.Descriptor() { + proto.Merge(dstPB, srcPB) + return nil + } + if src.Descriptor().FullName() != dst.Descriptor().FullName() { + return fmt.Errorf("pb.Merge() arguments must be the same type. got: %v, %v", + dst.Descriptor().FullName(), src.Descriptor().FullName()) + } + bytes, err := proto.Marshal(srcPB) + if err != nil { + return fmt.Errorf("pb.Merge(dstPB, srcPB) failed to marshal source proto: %v", err) + } + err = proto.Unmarshal(bytes, dstPB) + if err != nil { + return fmt.Errorf("pb.Merge(dstPB, srcPB) failed to unmarshal to dest proto: %v", err) + } + return nil +} + // NewDb creates a new `pb.Db` with an empty type name to file description map. func NewDb() *Db { pbdb := &Db{ diff --git a/vendor/github.com/google/cel-go/common/types/pb/type.go b/vendor/github.com/google/cel-go/common/types/pb/type.go index 8594008b127..912076fa488 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/type.go +++ b/vendor/github.com/google/cel-go/common/types/pb/type.go @@ -87,7 +87,7 @@ func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) { // MaybeUnwrap accepts a proto message as input and unwraps it to a primitive CEL type if possible. // // This method returns the unwrapped value and 'true', else the original value and 'false'. -func (td *TypeDescription) MaybeUnwrap(msg proto.Message) (interface{}, bool) { +func (td *TypeDescription) MaybeUnwrap(msg proto.Message) (interface{}, bool, error) { return unwrap(td, msg) } @@ -118,7 +118,7 @@ func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescripti switch fieldDesc.Kind() { case protoreflect.EnumKind: reflectType = reflectTypeOf(protoreflect.EnumNumber(0)) - case protoreflect.MessageKind: + case protoreflect.GroupKind, protoreflect.MessageKind: zeroMsg = dynamicpb.NewMessage(fieldDesc.Message()) reflectType = reflectTypeOf(zeroMsg) default: @@ -248,8 +248,8 @@ func (fd *FieldDescription) GetFrom(target interface{}) (interface{}, error) { return &Map{Map: fv, KeyType: fd.KeyType, ValueType: fd.ValueType}, nil case protoreflect.Message: // Make sure to unwrap well-known protobuf types before returning. - unwrapped, _ := fd.MaybeUnwrapDynamic(fv) - return unwrapped, nil + unwrapped, _, err := fd.MaybeUnwrapDynamic(fv) + return unwrapped, err default: return fv, nil } @@ -267,7 +267,8 @@ func (fd *FieldDescription) IsMap() bool { // IsMessage returns true if the field is of message type. func (fd *FieldDescription) IsMessage() bool { - return fd.desc.Kind() == protoreflect.MessageKind + kind := fd.desc.Kind() + return kind == protoreflect.MessageKind || kind == protoreflect.GroupKind } // IsOneof returns true if the field is declared within a oneof block. @@ -288,7 +289,7 @@ func (fd *FieldDescription) IsList() bool { // // This function returns the unwrapped value and 'true' on success, or the original value // and 'false' otherwise. -func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (interface{}, bool) { +func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (interface{}, bool, error) { return unwrapDynamic(fd, msg) } @@ -316,7 +317,7 @@ func (fd *FieldDescription) Zero() proto.Message { } func (fd *FieldDescription) typeDefToType() *exprpb.Type { - if fd.desc.Kind() == protoreflect.MessageKind { + if fd.desc.Kind() == protoreflect.MessageKind || fd.desc.Kind() == protoreflect.GroupKind { msgType := string(fd.desc.Message().FullName()) if wk, found := CheckedWellKnowns[msgType]; found { return wk @@ -361,63 +362,63 @@ func checkedWrap(t *exprpb.Type) *exprpb.Type { // input message is a *dynamicpb.Message which obscures the typing information from Go. // // Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'. -func unwrap(desc description, msg proto.Message) (interface{}, bool) { +func unwrap(desc description, msg proto.Message) (interface{}, bool, error) { switch v := msg.(type) { case *anypb.Any: dynMsg, err := v.UnmarshalNew() if err != nil { - return v, false + return v, false, err } return unwrapDynamic(desc, dynMsg.ProtoReflect()) case *dynamicpb.Message: return unwrapDynamic(desc, v) case *dpb.Duration: - return v.AsDuration(), true + return v.AsDuration(), true, nil case *tpb.Timestamp: - return v.AsTime(), true + return v.AsTime(), true, nil case *structpb.Value: switch v.GetKind().(type) { case *structpb.Value_BoolValue: - return v.GetBoolValue(), true + return v.GetBoolValue(), true, nil case *structpb.Value_ListValue: - return v.GetListValue(), true + return v.GetListValue(), true, nil case *structpb.Value_NullValue: - return structpb.NullValue_NULL_VALUE, true + return structpb.NullValue_NULL_VALUE, true, nil case *structpb.Value_NumberValue: - return v.GetNumberValue(), true + return v.GetNumberValue(), true, nil case *structpb.Value_StringValue: - return v.GetStringValue(), true + return v.GetStringValue(), true, nil case *structpb.Value_StructValue: - return v.GetStructValue(), true + return v.GetStructValue(), true, nil default: - return structpb.NullValue_NULL_VALUE, true + return structpb.NullValue_NULL_VALUE, true, nil } case *wrapperspb.BoolValue: - return v.GetValue(), true + return v.GetValue(), true, nil case *wrapperspb.BytesValue: - return v.GetValue(), true + return v.GetValue(), true, nil case *wrapperspb.DoubleValue: - return v.GetValue(), true + return v.GetValue(), true, nil case *wrapperspb.FloatValue: - return float64(v.GetValue()), true + return float64(v.GetValue()), true, nil case *wrapperspb.Int32Value: - return int64(v.GetValue()), true + return int64(v.GetValue()), true, nil case *wrapperspb.Int64Value: - return v.GetValue(), true + return v.GetValue(), true, nil case *wrapperspb.StringValue: - return v.GetValue(), true + return v.GetValue(), true, nil case *wrapperspb.UInt32Value: - return uint64(v.GetValue()), true + return uint64(v.GetValue()), true, nil case *wrapperspb.UInt64Value: - return v.GetValue(), true + return v.GetValue(), true, nil } - return msg, false + return msg, false, nil } // unwrapDynamic unwraps a reflected protobuf Message value. // // Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'. -func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, bool) { +func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, bool, error) { msg := refMsg.Interface() if !refMsg.IsValid() { msg = desc.Zero() @@ -432,18 +433,22 @@ func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, // unwrapped before being returned to the caller. Otherwise, the dynamic protobuf object // represented by the Any will be returned. unwrappedAny := &anypb.Any{} - proto.Merge(unwrappedAny, msg) + err := Merge(unwrappedAny, msg) + if err != nil { + return nil, false, err + } dynMsg, err := unwrappedAny.UnmarshalNew() if err != nil { // Allow the error to move further up the stack as it should result in an type // conversion error if the caller does not recover it somehow. - return unwrappedAny, true + return nil, false, err } // Attempt to unwrap the dynamic type, otherwise return the dynamic message. - if unwrapped, nested := unwrapDynamic(desc, dynMsg.ProtoReflect()); nested { - return unwrapped, true + unwrapped, nested, err := unwrapDynamic(desc, dynMsg.ProtoReflect()) + if err == nil && nested { + return unwrapped, true, nil } - return dynMsg, true + return dynMsg, true, err case "google.protobuf.BoolValue", "google.protobuf.BytesValue", "google.protobuf.DoubleValue", @@ -456,34 +461,49 @@ func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, // The msg value is ignored when dealing with wrapper types as they have a null or value // behavior, rather than the standard zero value behavior of other proto message types. if !refMsg.IsValid() { - return structpb.NullValue_NULL_VALUE, true + return structpb.NullValue_NULL_VALUE, true, nil } valueField := refMsg.Descriptor().Fields().ByName("value") - return refMsg.Get(valueField).Interface(), true + return refMsg.Get(valueField).Interface(), true, nil case "google.protobuf.Duration": unwrapped := &dpb.Duration{} - proto.Merge(unwrapped, msg) - return unwrapped.AsDuration(), true + err := Merge(unwrapped, msg) + if err != nil { + return nil, false, err + } + return unwrapped.AsDuration(), true, nil case "google.protobuf.ListValue": unwrapped := &structpb.ListValue{} - proto.Merge(unwrapped, msg) - return unwrapped, true + err := Merge(unwrapped, msg) + if err != nil { + return nil, false, err + } + return unwrapped, true, nil case "google.protobuf.NullValue": - return structpb.NullValue_NULL_VALUE, true + return structpb.NullValue_NULL_VALUE, true, nil case "google.protobuf.Struct": unwrapped := &structpb.Struct{} - proto.Merge(unwrapped, msg) - return unwrapped, true + err := Merge(unwrapped, msg) + if err != nil { + return nil, false, err + } + return unwrapped, true, nil case "google.protobuf.Timestamp": unwrapped := &tpb.Timestamp{} - proto.Merge(unwrapped, msg) - return unwrapped.AsTime(), true + err := Merge(unwrapped, msg) + if err != nil { + return nil, false, err + } + return unwrapped.AsTime(), true, nil case "google.protobuf.Value": unwrapped := &structpb.Value{} - proto.Merge(unwrapped, msg) + err := Merge(unwrapped, msg) + if err != nil { + return nil, false, err + } return unwrap(desc, unwrapped) } - return msg, false + return msg, false, nil } // reflectTypeOf intercepts the reflect.Type call to ensure that dynamicpb.Message types preserve diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go index 3ab30b763fa..02087d14e34 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -206,7 +206,10 @@ func (p *protoTypeRegistry) NativeToValue(value interface{}) ref.Val { if !found { return NewErr("unknown type: '%s'", typeName) } - unwrapped, isUnwrapped := td.MaybeUnwrap(v) + unwrapped, isUnwrapped, err := td.MaybeUnwrap(v) + if err != nil { + return UnsupportedRefValConversionErr(v) + } if isUnwrapped { return p.NativeToValue(unwrapped) } @@ -394,7 +397,10 @@ func nativeToValue(a ref.TypeAdapter, value interface{}) (ref.Val, bool) { if !found { return nil, false } - val, unwrapped := td.MaybeUnwrap(v) + val, unwrapped, err := td.MaybeUnwrap(v) + if err != nil { + return UnsupportedRefValConversionErr(v), true + } if !unwrapped { return nil, false } diff --git a/vendor/github.com/google/cel-go/common/types/ref/reference.go b/vendor/github.com/google/cel-go/common/types/ref/reference.go index e12169988d5..3098580c910 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/reference.go +++ b/vendor/github.com/google/cel-go/common/types/ref/reference.go @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package ref contains the reference interfaces used throughout the types -// components. +// Package ref contains the reference interfaces used throughout the types components. package ref import ( @@ -29,31 +28,27 @@ type Type interface { // TypeName returns the qualified type name of the type. // - // The type name is also used as the type's identifier name at type-check - // and interpretation time. + // The type name is also used as the type's identifier name at type-check and interpretation time. TypeName() string } // Val interface defines the functions supported by all expression values. -// Val implementations may specialize the behavior of the value through the -// addition of traits. +// Val implementations may specialize the behavior of the value through the addition of traits. type Val interface { // ConvertToNative converts the Value to a native Go struct according to the // reflected type description, or error if the conversion is not feasible. ConvertToNative(typeDesc reflect.Type) (interface{}, error) - // ConvertToType supports type conversions between value types supported by - // the expression language. + // ConvertToType supports type conversions between value types supported by the expression language. ConvertToType(typeValue Type) Val - // Equal returns true if the `other` value has the same type and content as - // the implementing struct. + // Equal returns true if the `other` value has the same type and content as the implementing struct. Equal(other Val) Val // Type returns the TypeValue of the value. Type() Type - // Value returns the raw value of the instance which may not be directly - // compatible with the expression language types. + // Value returns the raw value of the instance which may not be directly compatible with the expression + // language types. Value() interface{} } diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go index 60192a46832..b6d665683c5 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -167,7 +167,7 @@ func (s String) Match(pattern ref.Val) ref.Val { return Bool(matched) } -// Receive implements traits.Reciever.Receive. +// Receive implements traits.Receiver.Receive. func (s String) Receive(function string, overload string, args []ref.Val) ref.Val { switch len(args) { case 1: diff --git a/vendor/github.com/google/cel-go/common/types/timestamp.go b/vendor/github.com/google/cel-go/common/types/timestamp.go index 692acd3367d..7513a1b210a 100644 --- a/vendor/github.com/google/cel-go/common/types/timestamp.go +++ b/vendor/github.com/google/cel-go/common/types/timestamp.go @@ -138,7 +138,7 @@ func (t Timestamp) Equal(other ref.Val) ref.Val { return Bool(ok && t.Time.Equal(otherTime.Time)) } -// Receive implements traits.Reciever.Receive. +// Receive implements traits.Receiver.Receive. func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref.Val { switch len(args) { case 0: @@ -299,7 +299,7 @@ func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor { if err != nil { return wrapErr(err) } - min, err := strconv.Atoi(string(val[ind+1])) + min, err := strconv.Atoi(string(val[ind+1:])) if err != nil { return wrapErr(err) } diff --git a/vendor/github.com/google/cel-go/common/types/traits/lister.go b/vendor/github.com/google/cel-go/common/types/traits/lister.go index f40e7ee40bc..5cf2593f3b9 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/lister.go +++ b/vendor/github.com/google/cel-go/common/types/traits/lister.go @@ -28,5 +28,6 @@ type Lister interface { // MutableLister interface which emits an immutable result after an intermediate computation. type MutableLister interface { + Lister ToImmutableList() Lister } diff --git a/vendor/github.com/google/cel-go/common/types/unknown.go b/vendor/github.com/google/cel-go/common/types/unknown.go index a950920d606..95b47426fd3 100644 --- a/vendor/github.com/google/cel-go/common/types/unknown.go +++ b/vendor/github.com/google/cel-go/common/types/unknown.go @@ -34,12 +34,12 @@ func (u Unknown) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { return u.Value(), nil } -// ConvertToType implements ref.Val.ConvertToType. +// ConvertToType is an identity function since unknown values cannot be modified. func (u Unknown) ConvertToType(typeVal ref.Type) ref.Val { return u } -// Equal implements ref.Val.Equal. +// Equal is an identity function since unknown values cannot be modified. func (u Unknown) Equal(other ref.Val) ref.Val { return u } @@ -57,5 +57,10 @@ func (u Unknown) Value() interface{} { // IsUnknown returns whether the element ref.Type or ref.Val is equal to the // UnknownType singleton. func IsUnknown(val ref.Val) bool { - return val.Type() == UnknownType + switch val.(type) { + case Unknown: + return true + default: + return false + } } diff --git a/vendor/github.com/google/cel-go/common/types/util.go b/vendor/github.com/google/cel-go/common/types/util.go index a58e0bded32..a8e9afa9e70 100644 --- a/vendor/github.com/google/cel-go/common/types/util.go +++ b/vendor/github.com/google/cel-go/common/types/util.go @@ -18,10 +18,10 @@ import ( "github.com/google/cel-go/common/types/ref" ) -// IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknonwType. +// IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknownType. func IsUnknownOrError(val ref.Val) bool { - switch val.Type() { - case UnknownType, ErrType: + switch val.(type) { + case Unknown, *Err: return true } return false diff --git a/vendor/github.com/google/cel-go/ext/BUILD.bazel b/vendor/github.com/google/cel-go/ext/BUILD.bazel index 582a79ac3ad..9c2520b4084 100644 --- a/vendor/github.com/google/cel-go/ext/BUILD.bazel +++ b/vendor/github.com/google/cel-go/ext/BUILD.bazel @@ -15,12 +15,8 @@ go_library( visibility = ["//visibility:public"], deps = [ "//cel:go_default_library", - "//checker/decls:go_default_library", "//common/types:go_default_library", "//common/types/ref:go_default_library", - "//common/types/traits:go_default_library", - "//interpreter/functions:go_default_library", - "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/ext/encoders.go b/vendor/github.com/google/cel-go/ext/encoders.go index 7c7002d5342..22e38c39f91 100644 --- a/vendor/github.com/google/cel-go/ext/encoders.go +++ b/vendor/github.com/google/cel-go/ext/encoders.go @@ -16,12 +16,11 @@ package ext import ( "encoding/base64" + "reflect" "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/interpreter/functions" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" ) // Encoders returns a cel.EnvOption to configure extended functions for string, byte, and object @@ -57,42 +56,23 @@ type encoderLib struct{} func (encoderLib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - cel.Declarations( - decls.NewFunction("base64.decode", - decls.NewOverload("base64_decode_string", - []*exprpb.Type{decls.String}, - decls.Bytes)), - decls.NewFunction("base64.encode", - decls.NewOverload("base64_encode_bytes", - []*exprpb.Type{decls.Bytes}, - decls.String)), - ), + cel.Function("base64.decode", + cel.Overload("base64_decode_string", []*cel.Type{cel.StringType}, cel.BytesType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return bytesOrError(base64DecodeString(string(s))) + }))), + cel.Function("base64.encode", + cel.Overload("base64_encode_bytes", []*cel.Type{cel.BytesType}, cel.StringType, + cel.UnaryBinding(func(bytes ref.Val) ref.Val { + b := bytes.(types.Bytes) + return stringOrError(base64EncodeBytes([]byte(b))) + }))), } } func (encoderLib) ProgramOptions() []cel.ProgramOption { - wrappedBase64EncodeBytes := callInBytesOutString(base64EncodeBytes) - wrappedBase64DecodeString := callInStrOutBytes(base64DecodeString) - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "base64.decode", - Unary: wrappedBase64DecodeString, - }, - &functions.Overload{ - Operator: "base64_decode_string", - Unary: wrappedBase64DecodeString, - }, - &functions.Overload{ - Operator: "base64.encode", - Unary: wrappedBase64EncodeBytes, - }, - &functions.Overload{ - Operator: "base64_encode_bytes", - Unary: wrappedBase64EncodeBytes, - }, - ), - } + return []cel.ProgramOption{} } func base64DecodeString(str string) ([]byte, error) { @@ -102,3 +82,7 @@ func base64DecodeString(str string) ([]byte, error) { func base64EncodeBytes(bytes []byte) (string, error) { return base64.StdEncoding.EncodeToString(bytes), nil } + +var ( + bytesListType = reflect.TypeOf([]byte{}) +) diff --git a/vendor/github.com/google/cel-go/ext/guards.go b/vendor/github.com/google/cel-go/ext/guards.go index 864cc21cd20..0794f859b50 100644 --- a/vendor/github.com/google/cel-go/ext/guards.go +++ b/vendor/github.com/google/cel-go/ext/guards.go @@ -17,287 +17,34 @@ package ext import ( "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - "github.com/google/cel-go/interpreter/functions" ) // function invocation guards for common call signatures within extension functions. -func callInBytesOutString(fn func([]byte) (string, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.Bytes) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - str, err := fn([]byte(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(str) +func intOrError(i int64, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.Int(i) } -func callInStrOutBytes(fn func(string) ([]byte, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - byt, err := fn(string(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Bytes(byt) +func bytesOrError(bytes []byte, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.Bytes(bytes) } -func callInStrOutStr(fn func(string) (string, error)) functions.UnaryOp { - return func(val ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - str, err := fn(string(vVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(str) +func stringOrError(str string, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.String(str) } -func callInStrIntOutStr(fn func(string, int64) (string, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), int64(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrOutInt(fn func(string, string) (int64, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), string(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Int(out) - } -} - -func callInStrStrOutListStr(fn func(string, string) ([]string, error)) functions.BinaryOp { - return func(val, arg ref.Val) ref.Val { - vVal, ok := val.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - argVal, ok := arg.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - out, err := fn(string(vVal), string(argVal)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInStrIntIntOutStr(fn func(string, int64, int64) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), int64(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrStrOutStr(fn func(string, string, string) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), string(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInStrStrIntOutInt(fn func(string, string, int64) (int64, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.Int(out) - } -} - -func callInStrStrIntOutListStr(fn func(string, string, int64) ([]string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 3 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - out, err := fn(string(vVal), string(arg1Val), int64(arg2Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInStrStrStrIntOutStr(fn func(string, string, string, int64) (string, error)) functions.FunctionOp { - return func(args ...ref.Val) ref.Val { - if len(args) != 4 { - return types.NoSuchOverloadErr() - } - vVal, ok := args[0].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - arg1Val, ok := args[1].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - arg2Val, ok := args[2].(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - arg3Val, ok := args[3].(types.Int) - if !ok { - return types.MaybeNoSuchOverloadErr(args[3]) - } - out, err := fn(string(vVal), string(arg1Val), string(arg2Val), int64(arg3Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.String(out) - } -} - -func callInListStrOutStr(fn func([]string) (string, error)) functions.UnaryOp { - return func(args1 ref.Val) ref.Val { - vVal, ok := args1.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(args1) - } - strings := make([]string, vVal.Size().Value().(int64)) - i := 0 - for it := vVal.Iterator(); it.HasNext() == types.True; { - next := it.Next() - v, ok := next.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(next) - } - strings[i] = string(v) - i++ - } - out, err := fn(strings) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) - } -} - -func callInListStrStrOutStr(fn func([]string, string) (string, error)) functions.BinaryOp { - return func(args1, args2 ref.Val) ref.Val { - vVal, ok := args1.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(args1) - } - arg1Val, ok := args2.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(args2) - } - strings := make([]string, vVal.Size().Value().(int64)) - i := 0 - for it := vVal.Iterator(); it.HasNext() == types.True; { - next := it.Next() - v, ok := next.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(next) - } - strings[i] = string(v) - i++ - } - out, err := fn(strings, string(arg1Val)) - if err != nil { - return types.NewErr(err.Error()) - } - return types.DefaultTypeAdapter.NativeToValue(out) +func listStringOrError(strs []string, err error) ref.Val { + if err != nil { + return types.NewErr(err.Error()) } + return types.DefaultTypeAdapter.NativeToValue(strs) } diff --git a/vendor/github.com/google/cel-go/ext/strings.go b/vendor/github.com/google/cel-go/ext/strings.go index 19032133595..6ce239ac2b2 100644 --- a/vendor/github.com/google/cel-go/ext/strings.go +++ b/vendor/github.com/google/cel-go/ext/strings.go @@ -19,16 +19,13 @@ package ext import ( "fmt" + "reflect" "strings" "unicode" "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter/functions" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) // Strings returns a cel.EnvOption to configure extended functions for string manipulation. @@ -207,194 +204,128 @@ type stringLib struct{} func (stringLib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - cel.Declarations( - decls.NewFunction("charAt", - decls.NewInstanceOverload("string_char_at_int", - []*exprpb.Type{decls.String, decls.Int}, - decls.String)), - decls.NewFunction("indexOf", - decls.NewInstanceOverload("string_index_of_string", - []*exprpb.Type{decls.String, decls.String}, - decls.Int), - decls.NewInstanceOverload("string_index_of_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.Int)), - decls.NewFunction("lastIndexOf", - decls.NewInstanceOverload("string_last_index_of_string", - []*exprpb.Type{decls.String, decls.String}, - decls.Int), - decls.NewInstanceOverload("string_last_index_of_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.Int)), - decls.NewFunction("lowerAscii", - decls.NewInstanceOverload("string_lower_ascii", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("replace", - decls.NewInstanceOverload("string_replace_string_string", - []*exprpb.Type{decls.String, decls.String, decls.String}, - decls.String), - decls.NewInstanceOverload("string_replace_string_string_int", - []*exprpb.Type{decls.String, decls.String, decls.String, decls.Int}, - decls.String)), - decls.NewFunction("split", - decls.NewInstanceOverload("string_split_string", - []*exprpb.Type{decls.String, decls.String}, - decls.NewListType(decls.String)), - decls.NewInstanceOverload("string_split_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.NewListType(decls.String))), - decls.NewFunction("substring", - decls.NewInstanceOverload("string_substring_int", - []*exprpb.Type{decls.String, decls.Int}, - decls.String), - decls.NewInstanceOverload("string_substring_int_int", - []*exprpb.Type{decls.String, decls.Int, decls.Int}, - decls.String)), - decls.NewFunction("trim", - decls.NewInstanceOverload("string_trim", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("upperAscii", - decls.NewInstanceOverload("string_upper_ascii", - []*exprpb.Type{decls.String}, - decls.String)), - decls.NewFunction("join", - decls.NewInstanceOverload("list_join", - []*exprpb.Type{decls.NewListType(decls.String)}, - decls.String), - decls.NewInstanceOverload("list_join_string", - []*exprpb.Type{decls.NewListType(decls.String), decls.String}, - decls.String), - ), - ), + cel.Function("charAt", + cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, + cel.BinaryBinding(func(str, ind ref.Val) ref.Val { + s := str.(types.String) + i := ind.(types.Int) + return stringOrError(charAt(string(s), int64(i))) + }))), + cel.Function("indexOf", + cel.MemberOverload("string_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType, + cel.BinaryBinding(func(str, substr ref.Val) ref.Val { + s := str.(types.String) + sub := substr.(types.String) + return intOrError(indexOf(string(s), string(sub))) + })), + cel.MemberOverload("string_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sub := args[1].(types.String) + offset := args[2].(types.Int) + return intOrError(indexOfOffset(string(s), string(sub), int64(offset))) + }))), + cel.Function("lastIndexOf", + cel.MemberOverload("string_last_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType, + cel.BinaryBinding(func(str, substr ref.Val) ref.Val { + s := str.(types.String) + sub := substr.(types.String) + return intOrError(lastIndexOf(string(s), string(sub))) + })), + cel.MemberOverload("string_last_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sub := args[1].(types.String) + offset := args[2].(types.Int) + return intOrError(lastIndexOfOffset(string(s), string(sub), int64(offset))) + }))), + cel.Function("lowerAscii", + cel.MemberOverload("string_lower_ascii", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(lowerASCII(string(s))) + }))), + cel.Function("replace", + cel.MemberOverload( + "string_replace_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + str := args[0].(types.String) + old := args[1].(types.String) + new := args[2].(types.String) + return stringOrError(replace(string(str), string(old), string(new))) + })), + cel.MemberOverload( + "string_replace_string_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.StringType, cel.IntType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + str := args[0].(types.String) + old := args[1].(types.String) + new := args[2].(types.String) + n := args[3].(types.Int) + return stringOrError(replaceN(string(str), string(old), string(new), int64(n))) + }))), + cel.Function("split", + cel.MemberOverload("string_split_string", []*cel.Type{cel.StringType, cel.StringType}, cel.ListType(cel.StringType), + cel.BinaryBinding(func(str, separator ref.Val) ref.Val { + s := str.(types.String) + sep := separator.(types.String) + return listStringOrError(split(string(s), string(sep))) + })), + cel.MemberOverload("string_split_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.ListType(cel.StringType), + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + sep := args[1].(types.String) + n := args[2].(types.Int) + return listStringOrError(splitN(string(s), string(sep), int64(n))) + }))), + cel.Function("substring", + cel.MemberOverload("string_substring_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, + cel.BinaryBinding(func(str, offset ref.Val) ref.Val { + s := str.(types.String) + off := offset.(types.Int) + return stringOrError(substr(string(s), int64(off))) + })), + cel.MemberOverload("string_substring_int_int", []*cel.Type{cel.StringType, cel.IntType, cel.IntType}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := args[0].(types.String) + start := args[1].(types.Int) + end := args[2].(types.Int) + return stringOrError(substrRange(string(s), int64(start), int64(end))) + }))), + cel.Function("trim", + cel.MemberOverload("string_trim", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(trimSpace(string(s))) + }))), + cel.Function("upperAscii", + cel.MemberOverload("string_upper_ascii", []*cel.Type{cel.StringType}, cel.StringType, + cel.UnaryBinding(func(str ref.Val) ref.Val { + s := str.(types.String) + return stringOrError(upperASCII(string(s))) + }))), + cel.Function("join", + cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType, + cel.UnaryBinding(func(list ref.Val) ref.Val { + l, err := list.ConvertToNative(stringListType) + if err != nil { + return types.NewErr(err.Error()) + } + return stringOrError(join(l.([]string))) + })), + cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType, + cel.BinaryBinding(func(list, delim ref.Val) ref.Val { + l, err := list.ConvertToNative(stringListType) + if err != nil { + return types.NewErr(err.Error()) + } + d := delim.(types.String) + return stringOrError(joinSeparator(l.([]string), string(d))) + }))), } } func (stringLib) ProgramOptions() []cel.ProgramOption { - wrappedReplace := callInStrStrStrOutStr(replace) - wrappedReplaceN := callInStrStrStrIntOutStr(replaceN) - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "charAt", - Binary: callInStrIntOutStr(charAt), - }, - &functions.Overload{ - Operator: "string_char_at_int", - Binary: callInStrIntOutStr(charAt), - }, - &functions.Overload{ - Operator: "indexOf", - Binary: callInStrStrOutInt(indexOf), - Function: callInStrStrIntOutInt(indexOfOffset), - }, - &functions.Overload{ - Operator: "string_index_of_string", - Binary: callInStrStrOutInt(indexOf), - }, - &functions.Overload{ - Operator: "string_index_of_string_int", - Function: callInStrStrIntOutInt(indexOfOffset), - }, - &functions.Overload{ - Operator: "lastIndexOf", - Binary: callInStrStrOutInt(lastIndexOf), - Function: callInStrStrIntOutInt(lastIndexOfOffset), - }, - &functions.Overload{ - Operator: "string_last_index_of_string", - Binary: callInStrStrOutInt(lastIndexOf), - }, - &functions.Overload{ - Operator: "string_last_index_of_string_int", - Function: callInStrStrIntOutInt(lastIndexOfOffset), - }, - &functions.Overload{ - Operator: "lowerAscii", - Unary: callInStrOutStr(lowerASCII), - }, - &functions.Overload{ - Operator: "string_lower_ascii", - Unary: callInStrOutStr(lowerASCII), - }, - &functions.Overload{ - Operator: "replace", - Function: func(values ...ref.Val) ref.Val { - if len(values) == 3 { - return wrappedReplace(values...) - } - if len(values) == 4 { - return wrappedReplaceN(values...) - } - return types.NoSuchOverloadErr() - }, - }, - &functions.Overload{ - Operator: "string_replace_string_string", - Function: wrappedReplace, - }, - &functions.Overload{ - Operator: "string_replace_string_string_int", - Function: wrappedReplaceN, - }, - &functions.Overload{ - Operator: "split", - Binary: callInStrStrOutListStr(split), - Function: callInStrStrIntOutListStr(splitN), - }, - &functions.Overload{ - Operator: "string_split_string", - Binary: callInStrStrOutListStr(split), - }, - &functions.Overload{ - Operator: "string_split_string_int", - Function: callInStrStrIntOutListStr(splitN), - }, - &functions.Overload{ - Operator: "substring", - Binary: callInStrIntOutStr(substr), - Function: callInStrIntIntOutStr(substrRange), - }, - &functions.Overload{ - Operator: "string_substring_int", - Binary: callInStrIntOutStr(substr), - }, - &functions.Overload{ - Operator: "string_substring_int_int", - Function: callInStrIntIntOutStr(substrRange), - }, - &functions.Overload{ - Operator: "trim", - Unary: callInStrOutStr(trimSpace), - }, - &functions.Overload{ - Operator: "string_trim", - Unary: callInStrOutStr(trimSpace), - }, - &functions.Overload{ - Operator: "upperAscii", - Unary: callInStrOutStr(upperASCII), - }, - &functions.Overload{ - Operator: "string_upper_ascii", - Unary: callInStrOutStr(upperASCII), - }, - &functions.Overload{ - Operator: "join", - Unary: callInListStrOutStr(join), - Binary: callInListStrStrOutStr(joinSeparator), - }, - &functions.Overload{ - Operator: "list_join", - Unary: callInListStrOutStr(join), - }, - &functions.Overload{ - Operator: "list_join_string", - Binary: callInListStrStrOutStr(joinSeparator), - }, - ), - } + return []cel.ProgramOption{} } func charAt(str string, ind int64) (string, error) { @@ -546,3 +477,7 @@ func joinSeparator(strs []string, separator string) (string, error) { func join(strs []string) (string, error) { return strings.Join(strs, ""), nil } + +var ( + stringListType = reflect.TypeOf([]string{}) +) diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/github.com/google/cel-go/interpreter/activation.go index 4f131519978..8686d4f04f1 100644 --- a/vendor/github.com/google/cel-go/interpreter/activation.go +++ b/vendor/github.com/google/cel-go/interpreter/activation.go @@ -35,13 +35,17 @@ type Activation interface { Parent() Activation } -// EmptyActivation returns a variable free activation. +// EmptyActivation returns a variable-free activation. func EmptyActivation() Activation { - // This call cannot fail. - a, _ := NewActivation(map[string]interface{}{}) - return a + return emptyActivation{} } +// emptyActivation is a variable-free activation. +type emptyActivation struct{} + +func (emptyActivation) ResolveName(string) (interface{}, bool) { return nil, false } +func (emptyActivation) Parent() Activation { return nil } + // NewActivation returns an activation based on a map-based binding where the map keys are // expected to be qualified names used with ResolveName calls. // diff --git a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go index e6e724931d8..b33f7f7fd90 100644 --- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go +++ b/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go @@ -105,7 +105,7 @@ func (apat *AttributePattern) QualifierPatterns() []*AttributeQualifierPattern { return apat.qualifierPatterns } -// AttributeQualifierPattern holds a wilcard or valued qualifier pattern. +// AttributeQualifierPattern holds a wildcard or valued qualifier pattern. type AttributeQualifierPattern struct { wildcard bool value interface{} @@ -125,7 +125,7 @@ func (qpat *AttributeQualifierPattern) Matches(q Qualifier) bool { // type, is equal to the value held in the Qualifier. This interface is used by the // AttributeQualifierPattern to determine pattern matches for non-wildcard qualifier patterns. // -// Note: Attribute values are also Qualifier values; however, Attriutes are resolved before +// Note: Attribute values are also Qualifier values; however, Attributes are resolved before // qualification happens. This is an implementation detail, but one relevant to why the Attribute // types do not surface in the list of implementations. // @@ -206,7 +206,7 @@ func (fac *partialAttributeFactory) AbsoluteAttribute(id int64, names ...string) } // MaybeAttribute implementation of the AttributeFactory interface which ensure that the set of -// 'maybe' NamespacedAttribute values are produced using the PartialAttributeFactory rather than +// 'maybe' NamespacedAttribute values are produced using the partialAttributeFactory rather than // the base AttributeFactory implementation. func (fac *partialAttributeFactory) MaybeAttribute(id int64, name string) Attribute { return &maybeAttribute{ diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go index 19cf87d6210..4f1772ea393 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/github.com/google/cel-go/interpreter/attributes.go @@ -587,7 +587,7 @@ func (a *relativeAttribute) Resolve(vars Activation) (interface{}, error) { if types.IsUnknown(v) { return v, nil } - // Next, qualify it. Qualification handles unkonwns as well, so there's no need to recheck. + // Next, qualify it. Qualification handles unknowns as well, so there's no need to recheck. var err error var obj interface{} = v for _, qual := range a.qualifiers { @@ -637,6 +637,8 @@ func newQualifier(adapter ref.TypeAdapter, id int64, v interface{}) (Qualifier, qual = &uintQualifier{id: id, value: uint64(val), celValue: val, adapter: adapter} case types.Bool: qual = &boolQualifier{id: id, value: bool(val), celValue: val, adapter: adapter} + case types.Double: + qual = &doubleQualifier{id: id, value: float64(val), celValue: val, adapter: adapter} default: return nil, fmt.Errorf("invalid qualifier type: %T", v) } diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/github.com/google/cel-go/interpreter/decorators.go index 9e37e185680..bdbbad43e25 100644 --- a/vendor/github.com/google/cel-go/interpreter/decorators.go +++ b/vendor/github.com/google/cel-go/interpreter/decorators.go @@ -98,7 +98,7 @@ func decDisableShortcircuits() InterpretableDecorator { } // decOptimize optimizes the program plan by looking for common evaluation patterns and -// conditionally precomputating the result. +// conditionally precomputing the result. // - build list and map values with constant elements. // - convert 'in' operations to set membership tests if possible. func decOptimize() InterpretableDecorator { diff --git a/vendor/github.com/google/cel-go/interpreter/functions/functions.go b/vendor/github.com/google/cel-go/interpreter/functions/functions.go index 4ca706e96cd..dd1e9ddd5ff 100644 --- a/vendor/github.com/google/cel-go/interpreter/functions/functions.go +++ b/vendor/github.com/google/cel-go/interpreter/functions/functions.go @@ -45,6 +45,10 @@ type Overload struct { // Function defines the overload with a FunctionOp implementation. May be // nil. Function FunctionOp + + // NonStrict specifies whether the Overload will tolerate arguments that + // are types.Err or types.Unknown. + NonStrict bool } // UnaryOp is a function that takes a single value and produces an output. diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/github.com/google/cel-go/interpreter/interpretable.go index c87b351a67e..4fdd12028bd 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpretable.go +++ b/vendor/github.com/google/cel-go/interpreter/interpretable.go @@ -421,12 +421,13 @@ func (zero *evalZeroArity) Args() []Interpretable { } type evalUnary struct { - id int64 - function string - overload string - arg Interpretable - trait int - impl functions.UnaryOp + id int64 + function string + overload string + arg Interpretable + trait int + impl functions.UnaryOp + nonStrict bool } // ID implements the Interpretable interface method. @@ -438,12 +439,13 @@ func (un *evalUnary) ID() int64 { func (un *evalUnary) Eval(ctx Activation) ref.Val { argVal := un.arg.Eval(ctx) // Early return if the argument to the function is unknown or error. - if types.IsUnknownOrError(argVal) { + strict := !un.nonStrict + if strict && types.IsUnknownOrError(argVal) { return argVal } // If the implementation is bound and the argument value has the right traits required to // invoke it, then call the implementation. - if un.impl != nil && (un.trait == 0 || argVal.Type().HasTrait(un.trait)) { + if un.impl != nil && (un.trait == 0 || (!strict && types.IsUnknownOrError(argVal)) || argVal.Type().HasTrait(un.trait)) { return un.impl(argVal) } // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the @@ -478,13 +480,14 @@ func (un *evalUnary) Args() []Interpretable { } type evalBinary struct { - id int64 - function string - overload string - lhs Interpretable - rhs Interpretable - trait int - impl functions.BinaryOp + id int64 + function string + overload string + lhs Interpretable + rhs Interpretable + trait int + impl functions.BinaryOp + nonStrict bool } // ID implements the Interpretable interface method. @@ -497,15 +500,18 @@ func (bin *evalBinary) Eval(ctx Activation) ref.Val { lVal := bin.lhs.Eval(ctx) rVal := bin.rhs.Eval(ctx) // Early return if any argument to the function is unknown or error. - if types.IsUnknownOrError(lVal) { - return lVal - } - if types.IsUnknownOrError(rVal) { - return rVal + strict := !bin.nonStrict + if strict { + if types.IsUnknownOrError(lVal) { + return lVal + } + if types.IsUnknownOrError(rVal) { + return rVal + } } // If the implementation is bound and the argument value has the right traits required to // invoke it, then call the implementation. - if bin.impl != nil && (bin.trait == 0 || lVal.Type().HasTrait(bin.trait)) { + if bin.impl != nil && (bin.trait == 0 || (!strict && types.IsUnknownOrError(lVal)) || lVal.Type().HasTrait(bin.trait)) { return bin.impl(lVal, rVal) } // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the @@ -537,12 +543,13 @@ func (bin *evalBinary) Args() []Interpretable { } type evalVarArgs struct { - id int64 - function string - overload string - args []Interpretable - trait int - impl functions.FunctionOp + id int64 + function string + overload string + args []Interpretable + trait int + impl functions.FunctionOp + nonStrict bool } // NewCall creates a new call Interpretable. @@ -565,16 +572,17 @@ func (fn *evalVarArgs) ID() int64 { func (fn *evalVarArgs) Eval(ctx Activation) ref.Val { argVals := make([]ref.Val, len(fn.args)) // Early return if any argument to the function is unknown or error. + strict := !fn.nonStrict for i, arg := range fn.args { argVals[i] = arg.Eval(ctx) - if types.IsUnknownOrError(argVals[i]) { + if strict && types.IsUnknownOrError(argVals[i]) { return argVals[i] } } // If the implementation is bound and the argument value has the right traits required to // invoke it, then call the implementation. arg0 := argVals[0] - if fn.impl != nil && (fn.trait == 0 || arg0.Type().HasTrait(fn.trait)) { + if fn.impl != nil && (fn.trait == 0 || (!strict && types.IsUnknownOrError(arg0)) || arg0.Type().HasTrait(fn.trait)) { return fn.impl(argVals...) } // Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the @@ -677,7 +685,19 @@ func (m *evalMap) Eval(ctx Activation) ref.Val { } func (m *evalMap) InitVals() []Interpretable { - return append(m.keys, m.vals...) + if len(m.keys) != len(m.vals) { + return nil + } + result := make([]Interpretable, len(m.keys)+len(m.vals)) + idx := 0 + for i, k := range m.keys { + v := m.vals[i] + result[idx] = k + idx++ + result[idx] = v + idx++ + } + return result } func (m *evalMap) Type() ref.Type { @@ -815,7 +835,9 @@ func (fold *evalFold) Eval(ctx Activation) ref.Val { varActivationPool.Put(accuCtx) // Convert a mutable list to an immutable one, if the comprehension has generated a list as a result. if !types.IsUnknownOrError(res) && buildingList { - res = res.(traits.MutableLister).ToImmutableList() + if _, ok := res.(traits.MutableLister); ok { + res = res.(traits.MutableLister).ToImmutableList() + } } return res } @@ -852,7 +874,7 @@ func (fold *evalFold) Cost() (min, max int64) { iMax + aMax + cMax*rangeCnt + sMax*rangeCnt + rMax } -// Optional Intepretable implementations that specialize, subsume, or extend the core evaluation +// Optional Interpretable implementations that specialize, subsume, or extend the core evaluation // plan via decorators. // evalSetMembership is an Interpretable implementation which tests whether an input value @@ -969,7 +991,7 @@ func (e *evalWatchConstQual) Qualify(vars Activation, obj interface{}) (interfac return out, err } -// QualifierValueEquals tests whether the incoming value is equal to the qualificying constant. +// QualifierValueEquals tests whether the incoming value is equal to the qualifying constant. func (e *evalWatchConstQual) QualifierValueEquals(value interface{}) bool { qve, ok := e.ConstantQualifier.(qualifierValueEquator) return ok && qve.QualifierValueEquals(value) diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/github.com/google/cel-go/interpreter/interpreter.go index a59b3e61d11..b3fd14f8b39 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpreter.go +++ b/vendor/github.com/google/cel-go/interpreter/interpreter.go @@ -162,7 +162,7 @@ type exprInterpreter struct { } // NewInterpreter builds an Interpreter from a Dispatcher and TypeProvider which will be used -// throughout the Eval of all Interpretable instances gerenated from it. +// throughout the Eval of all Interpretable instances generated from it. func NewInterpreter(dispatcher Dispatcher, container *containers.Container, provider ref.TypeProvider, diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/github.com/google/cel-go/interpreter/planner.go index 562d46b17f7..882e0419a5f 100644 --- a/vendor/github.com/google/cel-go/interpreter/planner.go +++ b/vendor/github.com/google/cel-go/interpreter/planner.go @@ -77,7 +77,7 @@ func newUncheckedPlanner(disp Dispatcher, } } -// planner is an implementatio of the interpretablePlanner interface. +// planner is an implementation of the interpretablePlanner interface. type planner struct { disp Dispatcher provider ref.TypeProvider @@ -95,7 +95,7 @@ type planner struct { // such as state-tracking, expression re-write, and possibly efficient thread-safe memoization of // repeated expressions. func (p *planner) Plan(expr *exprpb.Expr) (Interpretable, error) { - switch expr.ExprKind.(type) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: return p.decorate(p.planCall(expr)) case *exprpb.Expr_IdentExpr: @@ -146,10 +146,10 @@ func (p *planner) planIdent(expr *exprpb.Expr) (Interpretable, error) { func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interpretable, error) { // Plan a constant reference if this is the case for this simple identifier. - if identRef.Value != nil { + if identRef.GetValue() != nil { return p.Plan(&exprpb.Expr{Id: id, ExprKind: &exprpb.Expr_ConstExpr{ - ConstExpr: identRef.Value, + ConstExpr: identRef.GetValue(), }}) } @@ -157,9 +157,9 @@ func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interp // registered with the provider. cType := p.typeMap[id] if cType.GetType() != nil { - cVal, found := p.provider.FindIdent(identRef.Name) + cVal, found := p.provider.FindIdent(identRef.GetName()) if !found { - return nil, fmt.Errorf("reference to undefined type: %s", identRef.Name) + return nil, fmt.Errorf("reference to undefined type: %s", identRef.GetName()) } return NewConstValue(id, cVal), nil } @@ -167,14 +167,15 @@ func (p *planner) planCheckedIdent(id int64, identRef *exprpb.Reference) (Interp // Otherwise, return the attribute for the resolved identifier name. return &evalAttr{ adapter: p.adapter, - attr: p.attrFactory.AbsoluteAttribute(id, identRef.Name), + attr: p.attrFactory.AbsoluteAttribute(id, identRef.GetName()), }, nil } // planSelect creates an Interpretable with either: -// a) selects a field from a map or proto. -// b) creates a field presence test for a select within a has() macro. -// c) resolves the select expression to a namespaced identifier. +// +// a) selects a field from a map or proto. +// b) creates a field presence test for a select within a has() macro. +// c) resolves the select expression to a namespaced identifier. func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) { // If the Select id appears in the reference map from the CheckedExpr proto then it is either // a namespaced identifier or enum value. @@ -193,7 +194,7 @@ func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) { var fieldType *ref.FieldType opType := p.typeMap[sel.GetOperand().GetId()] if opType.GetMessageType() != "" { - ft, found := p.provider.FindFieldType(opType.GetMessageType(), sel.Field) + ft, found := p.provider.FindFieldType(opType.GetMessageType(), sel.GetField()) if found && ft.IsSet != nil && ft.GetFrom != nil { fieldType = ft } @@ -213,15 +214,15 @@ func (p *planner) planSelect(expr *exprpb.Expr) (Interpretable, error) { if sel.TestOnly { // Return the test only eval expression. return &evalTestOnly{ - id: expr.Id, - field: types.String(sel.Field), + id: expr.GetId(), + field: types.String(sel.GetField()), fieldType: fieldType, op: op, }, nil } // Build a qualifier. qual, err := p.attrFactory.NewQualifier( - opType, expr.Id, sel.Field) + opType, expr.GetId(), sel.GetField()) if err != nil { return nil, err } @@ -302,8 +303,18 @@ func (p *planner) planCall(expr *exprpb.Expr) (Interpretable, error) { case 0: return p.planCallZero(expr, fnName, oName, fnDef) case 1: + // If the FunctionOp has been used, then use it as it may exist for the purposes + // of dynamic dispatch within a singleton function implementation. + if fnDef != nil && fnDef.Unary == nil && fnDef.Function != nil { + return p.planCallVarArgs(expr, fnName, oName, fnDef, args) + } return p.planCallUnary(expr, fnName, oName, fnDef, args) case 2: + // If the FunctionOp has been used, then use it as it may exist for the purposes + // of dynamic dispatch within a singleton function implementation. + if fnDef != nil && fnDef.Binary == nil && fnDef.Function != nil { + return p.planCallVarArgs(expr, fnName, oName, fnDef, args) + } return p.planCallBinary(expr, fnName, oName, fnDef, args) default: return p.planCallVarArgs(expr, fnName, oName, fnDef, args) @@ -319,7 +330,7 @@ func (p *planner) planCallZero(expr *exprpb.Expr, return nil, fmt.Errorf("no such overload: %s()", function) } return &evalZeroArity{ - id: expr.Id, + id: expr.GetId(), function: function, overload: overload, impl: impl.Function, @@ -334,20 +345,23 @@ func (p *planner) planCallUnary(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { var fn functions.UnaryOp var trait int + var nonStrict bool if impl != nil { if impl.Unary == nil { return nil, fmt.Errorf("no such overload: %s(arg)", function) } fn = impl.Unary trait = impl.OperandTrait + nonStrict = impl.NonStrict } return &evalUnary{ - id: expr.Id, - function: function, - overload: overload, - arg: args[0], - trait: trait, - impl: fn, + id: expr.GetId(), + function: function, + overload: overload, + arg: args[0], + trait: trait, + impl: fn, + nonStrict: nonStrict, }, nil } @@ -359,21 +373,24 @@ func (p *planner) planCallBinary(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { var fn functions.BinaryOp var trait int + var nonStrict bool if impl != nil { if impl.Binary == nil { return nil, fmt.Errorf("no such overload: %s(lhs, rhs)", function) } fn = impl.Binary trait = impl.OperandTrait + nonStrict = impl.NonStrict } return &evalBinary{ - id: expr.Id, - function: function, - overload: overload, - lhs: args[0], - rhs: args[1], - trait: trait, - impl: fn, + id: expr.GetId(), + function: function, + overload: overload, + lhs: args[0], + rhs: args[1], + trait: trait, + impl: fn, + nonStrict: nonStrict, }, nil } @@ -385,20 +402,23 @@ func (p *planner) planCallVarArgs(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { var fn functions.FunctionOp var trait int + var nonStrict bool if impl != nil { if impl.Function == nil { return nil, fmt.Errorf("no such overload: %s(...)", function) } fn = impl.Function trait = impl.OperandTrait + nonStrict = impl.NonStrict } return &evalVarArgs{ - id: expr.Id, - function: function, - overload: overload, - args: args, - trait: trait, - impl: fn, + id: expr.GetId(), + function: function, + overload: overload, + args: args, + trait: trait, + impl: fn, + nonStrict: nonStrict, }, nil } @@ -406,7 +426,7 @@ func (p *planner) planCallVarArgs(expr *exprpb.Expr, func (p *planner) planCallEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalEq{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -416,7 +436,7 @@ func (p *planner) planCallEqual(expr *exprpb.Expr, func (p *planner) planCallNotEqual(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalNe{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -426,7 +446,7 @@ func (p *planner) planCallNotEqual(expr *exprpb.Expr, func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalAnd{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -436,7 +456,7 @@ func (p *planner) planCallLogicalAnd(expr *exprpb.Expr, func (p *planner) planCallLogicalOr(expr *exprpb.Expr, args []Interpretable) (Interpretable, error) { return &evalOr{ - id: expr.Id, + id: expr.GetId(), lhs: args[0], rhs: args[1], }, nil @@ -467,7 +487,7 @@ func (p *planner) planCallConditional(expr *exprpb.Expr, return &evalAttr{ adapter: p.adapter, - attr: p.attrFactory.ConditionalAttribute(expr.Id, cond, tAttr, fAttr), + attr: p.attrFactory.ConditionalAttribute(expr.GetId(), cond, tAttr, fAttr), }, nil } @@ -522,7 +542,7 @@ func (p *planner) planCreateList(expr *exprpb.Expr) (Interpretable, error) { elems[i] = elemVal } return &evalList{ - id: expr.Id, + id: expr.GetId(), elems: elems, adapter: p.adapter, }, nil @@ -551,7 +571,7 @@ func (p *planner) planCreateStruct(expr *exprpb.Expr) (Interpretable, error) { vals[i] = valVal } return &evalMap{ - id: expr.Id, + id: expr.GetId(), keys: keys, vals: vals, adapter: p.adapter, @@ -577,7 +597,7 @@ func (p *planner) planCreateObj(expr *exprpb.Expr) (Interpretable, error) { vals[i] = val } return &evalObj{ - id: expr.Id, + id: expr.GetId(), typeName: typeName, fields: fields, vals: vals, @@ -609,7 +629,7 @@ func (p *planner) planComprehension(expr *exprpb.Expr) (Interpretable, error) { return nil, err } return &evalFold{ - id: expr.Id, + id: expr.GetId(), accuVar: fold.AccuVar, accu: accu, iterVar: fold.IterVar, @@ -627,12 +647,12 @@ func (p *planner) planConst(expr *exprpb.Expr) (Interpretable, error) { if err != nil { return nil, err } - return NewConstValue(expr.Id, val), nil + return NewConstValue(expr.GetId(), val), nil } // constValue converts a proto Constant value to a ref.Val. func (p *planner) constValue(c *exprpb.Constant) (ref.Val, error) { - switch c.ConstantKind.(type) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: return p.adapter.NativeToValue(c.GetBoolValue()), nil case *exprpb.Constant_BytesValue: diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/github.com/google/cel-go/interpreter/prune.go index 7dab68efbbe..eab46e0c06e 100644 --- a/vendor/github.com/google/cel-go/interpreter/prune.go +++ b/vendor/github.com/google/cel-go/interpreter/prune.go @@ -41,17 +41,23 @@ type astPruner struct { // A) // 1) Evaluate expr with some unknowns, // 2) If result is unknown: -// a) PruneAst -// b) Goto 1 +// +// a) PruneAst +// b) Goto 1 +// // Functional call results which are known would be effectively cached across // iterations. // // B) // 1) Compile the expression (maybe via a service and maybe after checking a -// compiled expression does not exists in local cache) +// +// compiled expression does not exists in local cache) +// // 2) Prepare the environment and the interpreter. Activation might be empty. // 3) Eval the expression. This might return unknown or error or a concrete -// value. +// +// value. +// // 4) PruneAst // 4) Maybe cache the expression // This is effectively constant folding the expression. How the environment is @@ -228,13 +234,13 @@ func (p *astPruner) prune(node *exprpb.Expr) (*exprpb.Expr, bool) { } } - // We have either an unknown/error value, or something we dont want to + // We have either an unknown/error value, or something we don't want to // transform, or expression was not evaluated. If possible, drill down // more. - switch node.ExprKind.(type) { + switch node.GetExprKind().(type) { case *exprpb.Expr_SelectExpr: - if operand, pruned := p.prune(node.GetSelectExpr().Operand); pruned { + if operand, pruned := p.prune(node.GetSelectExpr().GetOperand()); pruned { return &exprpb.Expr{ Id: node.GetId(), ExprKind: &exprpb.Expr_SelectExpr{ diff --git a/vendor/github.com/google/cel-go/interpreter/runtimecost.go b/vendor/github.com/google/cel-go/interpreter/runtimecost.go index d8233804175..06b6b27ef1f 100644 --- a/vendor/github.com/google/cel-go/interpreter/runtimecost.go +++ b/vendor/github.com/google/cel-go/interpreter/runtimecost.go @@ -41,26 +41,42 @@ func CostObserver(tracker *CostTracker) EvalObserver { case ConstantQualifier: // TODO: Push identifiers on to the stack before observing constant qualifiers that apply to them // and enable the below pop. Once enabled this can case can be collapsed into the Qualifier case. - //tracker.stack.pop(1) tracker.cost++ case InterpretableConst: // zero cost case InterpretableAttribute: - // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions. - _, isConditional := t.Attr().(*conditionalAttribute) - if !isConditional { + switch a := t.Attr().(type) { + case *conditionalAttribute: + // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions. + tracker.stack.drop(a.falsy.ID(), a.truthy.ID(), a.expr.ID()) + default: + tracker.stack.drop(t.Attr().ID()) tracker.cost += common.SelectAndIdentCost } - case *evalExhaustiveConditional, *evalOr, *evalAnd, *evalExhaustiveOr, *evalExhaustiveAnd: + case *evalExhaustiveConditional: // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions. + tracker.stack.drop(t.attr.falsy.ID(), t.attr.truthy.ID(), t.attr.expr.ID()) + + // While the field names are identical, the boolean operation eval structs do not share an interface and so + // must be handled individually. + case *evalOr: + tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + case *evalAnd: + tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + case *evalExhaustiveOr: + tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + case *evalExhaustiveAnd: + tracker.stack.drop(t.rhs.ID(), t.lhs.ID()) + case *evalFold: + tracker.stack.drop(t.iterRange.ID()) case Qualifier: - tracker.stack.pop(1) tracker.cost++ case InterpretableCall: - if argVals, ok := tracker.stack.pop(len(t.Args())); ok { + if argVals, ok := tracker.stack.dropArgs(t.Args()); ok { tracker.cost += tracker.costCall(t, argVals, val) } case InterpretableConstructor: + tracker.stack.dropArgs(t.InitVals()) switch t.Type() { case types.ListType: tracker.cost += common.ListCreateBaseCost @@ -70,7 +86,7 @@ func CostObserver(tracker *CostTracker) EvalObserver { tracker.cost += common.StructCreateBaseCost } } - tracker.stack.push(val) + tracker.stack.push(val, id) if tracker.Limit != nil && tracker.cost > *tracker.Limit { panic(EvalCancelledError{Cause: CostLimitExceeded, Message: "operation cancelled: actual cost limit exceeded"}) @@ -170,19 +186,56 @@ func (c CostTracker) actualSize(value ref.Val) uint64 { return 1 } +type stackVal struct { + Val ref.Val + ID int64 +} + // refValStack keeps track of values of the stack for cost calculation purposes -type refValStack []ref.Val +type refValStack []stackVal -func (s *refValStack) push(value ref.Val) { +func (s *refValStack) push(val ref.Val, id int64) { + value := stackVal{Val: val, ID: id} *s = append(*s, value) } -func (s *refValStack) pop(count int) ([]ref.Val, bool) { - if len(*s) < count { +// TODO: Allowing drop and dropArgs to remove stack items above the IDs they are provided is a workaround. drop and dropArgs +// should find and remove only the stack items matching the provided IDs once all attributes are properly pushed and popped from stack. + +// drop searches the stack for each ID and removes the ID and all stack items above it. +// If none of the IDs are found, the stack is not modified. +// WARNING: It is possible for multiple expressions with the same ID to exist (due to how macros are implemented) so it's +// possible that a dropped ID will remain on the stack. They should be removed when IDs on the stack are popped. +func (s *refValStack) drop(ids ...int64) { + for _, id := range ids { + for idx := len(*s) - 1; idx >= 0; idx-- { + if (*s)[idx].ID == id { + *s = (*s)[:idx] + break + } + } + } +} + +// dropArgs searches the stack for all the args by their IDs, accumulates their associated ref.Vals and drops any +// stack items above any of the arg IDs. If any of the IDs are not found the stack, false is returned. +// Args are assumed to be found in the stack in reverse order, i.e. the last arg is expected to be found highest in +// the stack. +// WARNING: It is possible for multiple expressions with the same ID to exist (due to how macros are implemented) so it's +// possible that a dropped ID will remain on the stack. They should be removed when IDs on the stack are popped. +func (s *refValStack) dropArgs(args []Interpretable) ([]ref.Val, bool) { + result := make([]ref.Val, len(args)) +argloop: + for nIdx := len(args) - 1; nIdx >= 0; nIdx-- { + for idx := len(*s) - 1; idx >= 0; idx-- { + if (*s)[idx].ID == args[nIdx].ID() { + el := (*s)[idx] + *s = (*s)[:idx] + result[nIdx] = el.Val + continue argloop + } + } return nil, false } - idx := len(*s) - count - el := (*s)[idx:] - *s = (*s)[:idx] - return el, true + return result, true } diff --git a/vendor/github.com/google/cel-go/parser/BUILD.bazel b/vendor/github.com/google/cel-go/parser/BUILD.bazel index a1917b46409..b76e6e48441 100644 --- a/vendor/github.com/google/cel-go/parser/BUILD.bazel +++ b/vendor/github.com/google/cel-go/parser/BUILD.bazel @@ -23,7 +23,7 @@ go_library( "//common/operators:go_default_library", "//common/runes:go_default_library", "//parser/gen:go_default_library", - "@com_github_antlr//runtime/Go/antlr:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", "@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/structpb:go_default_library", @@ -45,7 +45,7 @@ go_test( "//common/debug:go_default_library", "//parser/gen:go_default_library", "//test:go_default_library", - "@com_github_antlr//runtime/Go/antlr:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel index 78e0432c406..22711310ce0 100644 --- a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel +++ b/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel @@ -21,6 +21,6 @@ go_library( ], importpath = "github.com/google/cel-go/parser/gen", deps = [ - "@com_github_antlr//runtime/Go/antlr:go_default_library", + "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", ], ) diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.interp b/vendor/github.com/google/cel-go/parser/gen/CEL.interp new file mode 100644 index 00000000000..13e3a10d175 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/CEL.interp @@ -0,0 +1,96 @@ +token literal names: +null +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null + +token symbolic names: +null +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +rule names: +start +expr +conditionalOr +conditionalAnd +relation +calc +unary +member +primary +exprList +fieldInitializerList +mapInitializerList +literal + + +atn: +[4, 1, 36, 209, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 41, 8, 2, 10, 2, 12, 2, 44, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 49, 8, 3, 10, 3, 12, 3, 52, 9, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 60, 8, 4, 10, 4, 12, 4, 63, 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 74, 8, 5, 10, 5, 12, 5, 77, 9, 5, 1, 6, 1, 6, 4, 6, 81, 8, 6, 11, 6, 12, 6, 82, 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 3, 6, 92, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 102, 8, 7, 1, 7, 3, 7, 105, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 115, 8, 7, 1, 7, 3, 7, 118, 8, 7, 1, 7, 5, 7, 121, 8, 7, 10, 7, 12, 7, 124, 9, 7, 1, 8, 3, 8, 127, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 132, 8, 8, 1, 8, 3, 8, 135, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 143, 8, 8, 1, 8, 3, 8, 146, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 151, 8, 8, 1, 8, 3, 8, 154, 8, 8, 1, 8, 1, 8, 3, 8, 158, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 163, 8, 9, 10, 9, 12, 9, 166, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 175, 8, 10, 10, 10, 12, 10, 178, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 188, 8, 11, 10, 11, 12, 11, 191, 9, 11, 1, 12, 3, 12, 194, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 199, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 207, 8, 12, 1, 12, 0, 3, 8, 10, 14, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1, 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 235, 0, 26, 1, 0, 0, 0, 2, 29, 1, 0, 0, 0, 4, 37, 1, 0, 0, 0, 6, 45, 1, 0, 0, 0, 8, 53, 1, 0, 0, 0, 10, 64, 1, 0, 0, 0, 12, 91, 1, 0, 0, 0, 14, 93, 1, 0, 0, 0, 16, 157, 1, 0, 0, 0, 18, 159, 1, 0, 0, 0, 20, 167, 1, 0, 0, 0, 22, 179, 1, 0, 0, 0, 24, 206, 1, 0, 0, 0, 26, 27, 3, 2, 1, 0, 27, 28, 5, 0, 0, 1, 28, 1, 1, 0, 0, 0, 29, 35, 3, 4, 2, 0, 30, 31, 5, 20, 0, 0, 31, 32, 3, 4, 2, 0, 32, 33, 5, 21, 0, 0, 33, 34, 3, 2, 1, 0, 34, 36, 1, 0, 0, 0, 35, 30, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 3, 1, 0, 0, 0, 37, 42, 3, 6, 3, 0, 38, 39, 5, 9, 0, 0, 39, 41, 3, 6, 3, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 45, 50, 3, 8, 4, 0, 46, 47, 5, 8, 0, 0, 47, 49, 3, 8, 4, 0, 48, 46, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0, 51, 7, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 6, 4, -1, 0, 54, 55, 3, 10, 5, 0, 55, 61, 1, 0, 0, 0, 56, 57, 10, 1, 0, 0, 57, 58, 7, 0, 0, 0, 58, 60, 3, 8, 4, 2, 59, 56, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 9, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, 65, 6, 5, -1, 0, 65, 66, 3, 12, 6, 0, 66, 75, 1, 0, 0, 0, 67, 68, 10, 2, 0, 0, 68, 69, 7, 1, 0, 0, 69, 74, 3, 10, 5, 3, 70, 71, 10, 1, 0, 0, 71, 72, 7, 2, 0, 0, 72, 74, 3, 10, 5, 2, 73, 67, 1, 0, 0, 0, 73, 70, 1, 0, 0, 0, 74, 77, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 11, 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 78, 92, 3, 14, 7, 0, 79, 81, 5, 19, 0, 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 92, 3, 14, 7, 0, 85, 87, 5, 18, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 92, 3, 14, 7, 0, 91, 78, 1, 0, 0, 0, 91, 80, 1, 0, 0, 0, 91, 86, 1, 0, 0, 0, 92, 13, 1, 0, 0, 0, 93, 94, 6, 7, -1, 0, 94, 95, 3, 16, 8, 0, 95, 122, 1, 0, 0, 0, 96, 97, 10, 3, 0, 0, 97, 98, 5, 16, 0, 0, 98, 104, 5, 36, 0, 0, 99, 101, 5, 14, 0, 0, 100, 102, 3, 18, 9, 0, 101, 100, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 103, 1, 0, 0, 0, 103, 105, 5, 15, 0, 0, 104, 99, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 121, 1, 0, 0, 0, 106, 107, 10, 2, 0, 0, 107, 108, 5, 10, 0, 0, 108, 109, 3, 2, 1, 0, 109, 110, 5, 11, 0, 0, 110, 121, 1, 0, 0, 0, 111, 112, 10, 1, 0, 0, 112, 114, 5, 12, 0, 0, 113, 115, 3, 20, 10, 0, 114, 113, 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 117, 1, 0, 0, 0, 116, 118, 5, 17, 0, 0, 117, 116, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, 121, 5, 13, 0, 0, 120, 96, 1, 0, 0, 0, 120, 106, 1, 0, 0, 0, 120, 111, 1, 0, 0, 0, 121, 124, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 123, 1, 0, 0, 0, 123, 15, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127, 5, 16, 0, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, 134, 5, 36, 0, 0, 129, 131, 5, 14, 0, 0, 130, 132, 3, 18, 9, 0, 131, 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 135, 5, 15, 0, 0, 134, 129, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 158, 1, 0, 0, 0, 136, 137, 5, 14, 0, 0, 137, 138, 3, 2, 1, 0, 138, 139, 5, 15, 0, 0, 139, 158, 1, 0, 0, 0, 140, 142, 5, 10, 0, 0, 141, 143, 3, 18, 9, 0, 142, 141, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 145, 1, 0, 0, 0, 144, 146, 5, 17, 0, 0, 145, 144, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 158, 5, 11, 0, 0, 148, 150, 5, 12, 0, 0, 149, 151, 3, 22, 11, 0, 150, 149, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 153, 1, 0, 0, 0, 152, 154, 5, 17, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 158, 5, 13, 0, 0, 156, 158, 3, 24, 12, 0, 157, 126, 1, 0, 0, 0, 157, 136, 1, 0, 0, 0, 157, 140, 1, 0, 0, 0, 157, 148, 1, 0, 0, 0, 157, 156, 1, 0, 0, 0, 158, 17, 1, 0, 0, 0, 159, 164, 3, 2, 1, 0, 160, 161, 5, 17, 0, 0, 161, 163, 3, 2, 1, 0, 162, 160, 1, 0, 0, 0, 163, 166, 1, 0, 0, 0, 164, 162, 1, 0, 0, 0, 164, 165, 1, 0, 0, 0, 165, 19, 1, 0, 0, 0, 166, 164, 1, 0, 0, 0, 167, 168, 5, 36, 0, 0, 168, 169, 5, 21, 0, 0, 169, 176, 3, 2, 1, 0, 170, 171, 5, 17, 0, 0, 171, 172, 5, 36, 0, 0, 172, 173, 5, 21, 0, 0, 173, 175, 3, 2, 1, 0, 174, 170, 1, 0, 0, 0, 175, 178, 1, 0, 0, 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 21, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 179, 180, 3, 2, 1, 0, 180, 181, 5, 21, 0, 0, 181, 189, 3, 2, 1, 0, 182, 183, 5, 17, 0, 0, 183, 184, 3, 2, 1, 0, 184, 185, 5, 21, 0, 0, 185, 186, 3, 2, 1, 0, 186, 188, 1, 0, 0, 0, 187, 182, 1, 0, 0, 0, 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 23, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 194, 5, 18, 0, 0, 193, 192, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 207, 5, 32, 0, 0, 196, 207, 5, 33, 0, 0, 197, 199, 5, 18, 0, 0, 198, 197, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 207, 5, 31, 0, 0, 201, 207, 5, 34, 0, 0, 202, 207, 5, 35, 0, 0, 203, 207, 5, 26, 0, 0, 204, 207, 5, 27, 0, 0, 205, 207, 5, 28, 0, 0, 206, 193, 1, 0, 0, 0, 206, 196, 1, 0, 0, 0, 206, 198, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 206, 202, 1, 0, 0, 0, 206, 203, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 205, 1, 0, 0, 0, 207, 25, 1, 0, 0, 0, 29, 35, 42, 50, 61, 73, 75, 82, 88, 91, 101, 104, 114, 117, 120, 122, 126, 131, 134, 142, 145, 150, 153, 157, 164, 176, 189, 193, 198, 206] \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp b/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp new file mode 100644 index 00000000000..26e7f471e82 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp @@ -0,0 +1,136 @@ +token literal names: +null +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null + +token symbolic names: +null +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +rule names: +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +BACKSLASH +LETTER +DIGIT +EXPONENT +HEXDIGIT +RAW +ESC_SEQ +ESC_CHAR_SEQ +ESC_OCT_SEQ +ESC_BYTE_SEQ +ESC_UNI_SEQ +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 36, 423, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 177, 8, 31, 1, 31, 4, 31, 180, 8, 31, 11, 31, 12, 31, 181, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 192, 8, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 225, 8, 38, 1, 39, 4, 39, 228, 8, 39, 11, 39, 12, 39, 229, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 238, 8, 40, 10, 40, 12, 40, 241, 9, 40, 1, 40, 1, 40, 1, 41, 4, 41, 246, 8, 41, 11, 41, 12, 41, 247, 1, 41, 1, 41, 4, 41, 252, 8, 41, 11, 41, 12, 41, 253, 1, 41, 3, 41, 257, 8, 41, 1, 41, 4, 41, 260, 8, 41, 11, 41, 12, 41, 261, 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 268, 8, 41, 11, 41, 12, 41, 269, 1, 41, 3, 41, 273, 8, 41, 3, 41, 275, 8, 41, 1, 42, 4, 42, 278, 8, 42, 11, 42, 12, 42, 279, 1, 42, 1, 42, 1, 42, 1, 42, 4, 42, 286, 8, 42, 11, 42, 12, 42, 287, 3, 42, 290, 8, 42, 1, 43, 4, 43, 293, 8, 43, 11, 43, 12, 43, 294, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 303, 8, 43, 11, 43, 12, 43, 304, 1, 43, 1, 43, 3, 43, 309, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 314, 8, 44, 10, 44, 12, 44, 317, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 323, 8, 44, 10, 44, 12, 44, 326, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 335, 8, 44, 10, 44, 12, 44, 338, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 349, 8, 44, 10, 44, 12, 44, 352, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 360, 8, 44, 10, 44, 12, 44, 363, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 370, 8, 44, 10, 44, 12, 44, 373, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 383, 8, 44, 10, 44, 12, 44, 386, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 398, 8, 44, 10, 44, 12, 44, 401, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 407, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 3, 46, 414, 8, 46, 1, 46, 1, 46, 1, 46, 5, 46, 419, 8, 46, 10, 46, 12, 46, 422, 9, 46, 4, 336, 350, 384, 399, 0, 47, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 0, 59, 0, 61, 0, 63, 0, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 29, 81, 30, 83, 31, 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 1, 0, 16, 2, 0, 65, 90, 97, 122, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, 39, 2, 0, 66, 66, 98, 98, 456, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, 3, 98, 1, 0, 0, 0, 5, 101, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 106, 1, 0, 0, 0, 11, 109, 1, 0, 0, 0, 13, 112, 1, 0, 0, 0, 15, 114, 1, 0, 0, 0, 17, 117, 1, 0, 0, 0, 19, 120, 1, 0, 0, 0, 21, 122, 1, 0, 0, 0, 23, 124, 1, 0, 0, 0, 25, 126, 1, 0, 0, 0, 27, 128, 1, 0, 0, 0, 29, 130, 1, 0, 0, 0, 31, 132, 1, 0, 0, 0, 33, 134, 1, 0, 0, 0, 35, 136, 1, 0, 0, 0, 37, 138, 1, 0, 0, 0, 39, 140, 1, 0, 0, 0, 41, 142, 1, 0, 0, 0, 43, 144, 1, 0, 0, 0, 45, 146, 1, 0, 0, 0, 47, 148, 1, 0, 0, 0, 49, 150, 1, 0, 0, 0, 51, 152, 1, 0, 0, 0, 53, 157, 1, 0, 0, 0, 55, 163, 1, 0, 0, 0, 57, 168, 1, 0, 0, 0, 59, 170, 1, 0, 0, 0, 61, 172, 1, 0, 0, 0, 63, 174, 1, 0, 0, 0, 65, 183, 1, 0, 0, 0, 67, 185, 1, 0, 0, 0, 69, 191, 1, 0, 0, 0, 71, 193, 1, 0, 0, 0, 73, 196, 1, 0, 0, 0, 75, 201, 1, 0, 0, 0, 77, 224, 1, 0, 0, 0, 79, 227, 1, 0, 0, 0, 81, 233, 1, 0, 0, 0, 83, 274, 1, 0, 0, 0, 85, 289, 1, 0, 0, 0, 87, 308, 1, 0, 0, 0, 89, 406, 1, 0, 0, 0, 91, 408, 1, 0, 0, 0, 93, 413, 1, 0, 0, 0, 95, 96, 5, 61, 0, 0, 96, 97, 5, 61, 0, 0, 97, 2, 1, 0, 0, 0, 98, 99, 5, 33, 0, 0, 99, 100, 5, 61, 0, 0, 100, 4, 1, 0, 0, 0, 101, 102, 5, 105, 0, 0, 102, 103, 5, 110, 0, 0, 103, 6, 1, 0, 0, 0, 104, 105, 5, 60, 0, 0, 105, 8, 1, 0, 0, 0, 106, 107, 5, 60, 0, 0, 107, 108, 5, 61, 0, 0, 108, 10, 1, 0, 0, 0, 109, 110, 5, 62, 0, 0, 110, 111, 5, 61, 0, 0, 111, 12, 1, 0, 0, 0, 112, 113, 5, 62, 0, 0, 113, 14, 1, 0, 0, 0, 114, 115, 5, 38, 0, 0, 115, 116, 5, 38, 0, 0, 116, 16, 1, 0, 0, 0, 117, 118, 5, 124, 0, 0, 118, 119, 5, 124, 0, 0, 119, 18, 1, 0, 0, 0, 120, 121, 5, 91, 0, 0, 121, 20, 1, 0, 0, 0, 122, 123, 5, 93, 0, 0, 123, 22, 1, 0, 0, 0, 124, 125, 5, 123, 0, 0, 125, 24, 1, 0, 0, 0, 126, 127, 5, 125, 0, 0, 127, 26, 1, 0, 0, 0, 128, 129, 5, 40, 0, 0, 129, 28, 1, 0, 0, 0, 130, 131, 5, 41, 0, 0, 131, 30, 1, 0, 0, 0, 132, 133, 5, 46, 0, 0, 133, 32, 1, 0, 0, 0, 134, 135, 5, 44, 0, 0, 135, 34, 1, 0, 0, 0, 136, 137, 5, 45, 0, 0, 137, 36, 1, 0, 0, 0, 138, 139, 5, 33, 0, 0, 139, 38, 1, 0, 0, 0, 140, 141, 5, 63, 0, 0, 141, 40, 1, 0, 0, 0, 142, 143, 5, 58, 0, 0, 143, 42, 1, 0, 0, 0, 144, 145, 5, 43, 0, 0, 145, 44, 1, 0, 0, 0, 146, 147, 5, 42, 0, 0, 147, 46, 1, 0, 0, 0, 148, 149, 5, 47, 0, 0, 149, 48, 1, 0, 0, 0, 150, 151, 5, 37, 0, 0, 151, 50, 1, 0, 0, 0, 152, 153, 5, 116, 0, 0, 153, 154, 5, 114, 0, 0, 154, 155, 5, 117, 0, 0, 155, 156, 5, 101, 0, 0, 156, 52, 1, 0, 0, 0, 157, 158, 5, 102, 0, 0, 158, 159, 5, 97, 0, 0, 159, 160, 5, 108, 0, 0, 160, 161, 5, 115, 0, 0, 161, 162, 5, 101, 0, 0, 162, 54, 1, 0, 0, 0, 163, 164, 5, 110, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 108, 0, 0, 166, 167, 5, 108, 0, 0, 167, 56, 1, 0, 0, 0, 168, 169, 5, 92, 0, 0, 169, 58, 1, 0, 0, 0, 170, 171, 7, 0, 0, 0, 171, 60, 1, 0, 0, 0, 172, 173, 2, 48, 57, 0, 173, 62, 1, 0, 0, 0, 174, 176, 7, 1, 0, 0, 175, 177, 7, 2, 0, 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 179, 1, 0, 0, 0, 178, 180, 3, 61, 30, 0, 179, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 64, 1, 0, 0, 0, 183, 184, 7, 3, 0, 0, 184, 66, 1, 0, 0, 0, 185, 186, 7, 4, 0, 0, 186, 68, 1, 0, 0, 0, 187, 192, 3, 71, 35, 0, 188, 192, 3, 75, 37, 0, 189, 192, 3, 77, 38, 0, 190, 192, 3, 73, 36, 0, 191, 187, 1, 0, 0, 0, 191, 188, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 191, 190, 1, 0, 0, 0, 192, 70, 1, 0, 0, 0, 193, 194, 3, 57, 28, 0, 194, 195, 7, 5, 0, 0, 195, 72, 1, 0, 0, 0, 196, 197, 3, 57, 28, 0, 197, 198, 2, 48, 51, 0, 198, 199, 2, 48, 55, 0, 199, 200, 2, 48, 55, 0, 200, 74, 1, 0, 0, 0, 201, 202, 3, 57, 28, 0, 202, 203, 7, 6, 0, 0, 203, 204, 3, 65, 32, 0, 204, 205, 3, 65, 32, 0, 205, 76, 1, 0, 0, 0, 206, 207, 3, 57, 28, 0, 207, 208, 5, 117, 0, 0, 208, 209, 3, 65, 32, 0, 209, 210, 3, 65, 32, 0, 210, 211, 3, 65, 32, 0, 211, 212, 3, 65, 32, 0, 212, 225, 1, 0, 0, 0, 213, 214, 3, 57, 28, 0, 214, 215, 5, 85, 0, 0, 215, 216, 3, 65, 32, 0, 216, 217, 3, 65, 32, 0, 217, 218, 3, 65, 32, 0, 218, 219, 3, 65, 32, 0, 219, 220, 3, 65, 32, 0, 220, 221, 3, 65, 32, 0, 221, 222, 3, 65, 32, 0, 222, 223, 3, 65, 32, 0, 223, 225, 1, 0, 0, 0, 224, 206, 1, 0, 0, 0, 224, 213, 1, 0, 0, 0, 225, 78, 1, 0, 0, 0, 226, 228, 7, 7, 0, 0, 227, 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 39, 0, 0, 232, 80, 1, 0, 0, 0, 233, 234, 5, 47, 0, 0, 234, 235, 5, 47, 0, 0, 235, 239, 1, 0, 0, 0, 236, 238, 8, 8, 0, 0, 237, 236, 1, 0, 0, 0, 238, 241, 1, 0, 0, 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 242, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 242, 243, 6, 40, 0, 0, 243, 82, 1, 0, 0, 0, 244, 246, 3, 61, 30, 0, 245, 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 251, 5, 46, 0, 0, 250, 252, 3, 61, 30, 0, 251, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, 253, 251, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, 257, 3, 63, 31, 0, 256, 255, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 275, 1, 0, 0, 0, 258, 260, 3, 61, 30, 0, 259, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 259, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 264, 3, 63, 31, 0, 264, 275, 1, 0, 0, 0, 265, 267, 5, 46, 0, 0, 266, 268, 3, 61, 30, 0, 267, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 267, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 272, 1, 0, 0, 0, 271, 273, 3, 63, 31, 0, 272, 271, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 275, 1, 0, 0, 0, 274, 245, 1, 0, 0, 0, 274, 259, 1, 0, 0, 0, 274, 265, 1, 0, 0, 0, 275, 84, 1, 0, 0, 0, 276, 278, 3, 61, 30, 0, 277, 276, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 290, 1, 0, 0, 0, 281, 282, 5, 48, 0, 0, 282, 283, 5, 120, 0, 0, 283, 285, 1, 0, 0, 0, 284, 286, 3, 65, 32, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, 289, 277, 1, 0, 0, 0, 289, 281, 1, 0, 0, 0, 290, 86, 1, 0, 0, 0, 291, 293, 3, 61, 30, 0, 292, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 292, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 297, 7, 9, 0, 0, 297, 309, 1, 0, 0, 0, 298, 299, 5, 48, 0, 0, 299, 300, 5, 120, 0, 0, 300, 302, 1, 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, 304, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 7, 9, 0, 0, 307, 309, 1, 0, 0, 0, 308, 292, 1, 0, 0, 0, 308, 298, 1, 0, 0, 0, 309, 88, 1, 0, 0, 0, 310, 315, 5, 34, 0, 0, 311, 314, 3, 69, 34, 0, 312, 314, 8, 10, 0, 0, 313, 311, 1, 0, 0, 0, 313, 312, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 318, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 407, 5, 34, 0, 0, 319, 324, 5, 39, 0, 0, 320, 323, 3, 69, 34, 0, 321, 323, 8, 11, 0, 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, 322, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 327, 1, 0, 0, 0, 326, 324, 1, 0, 0, 0, 327, 407, 5, 39, 0, 0, 328, 329, 5, 34, 0, 0, 329, 330, 5, 34, 0, 0, 330, 331, 5, 34, 0, 0, 331, 336, 1, 0, 0, 0, 332, 335, 3, 69, 34, 0, 333, 335, 8, 12, 0, 0, 334, 332, 1, 0, 0, 0, 334, 333, 1, 0, 0, 0, 335, 338, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 340, 5, 34, 0, 0, 340, 341, 5, 34, 0, 0, 341, 407, 5, 34, 0, 0, 342, 343, 5, 39, 0, 0, 343, 344, 5, 39, 0, 0, 344, 345, 5, 39, 0, 0, 345, 350, 1, 0, 0, 0, 346, 349, 3, 69, 34, 0, 347, 349, 8, 12, 0, 0, 348, 346, 1, 0, 0, 0, 348, 347, 1, 0, 0, 0, 349, 352, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 351, 353, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 353, 354, 5, 39, 0, 0, 354, 355, 5, 39, 0, 0, 355, 407, 5, 39, 0, 0, 356, 357, 3, 67, 33, 0, 357, 361, 5, 34, 0, 0, 358, 360, 8, 13, 0, 0, 359, 358, 1, 0, 0, 0, 360, 363, 1, 0, 0, 0, 361, 359, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 364, 1, 0, 0, 0, 363, 361, 1, 0, 0, 0, 364, 365, 5, 34, 0, 0, 365, 407, 1, 0, 0, 0, 366, 367, 3, 67, 33, 0, 367, 371, 5, 39, 0, 0, 368, 370, 8, 14, 0, 0, 369, 368, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 39, 0, 0, 375, 407, 1, 0, 0, 0, 376, 377, 3, 67, 33, 0, 377, 378, 5, 34, 0, 0, 378, 379, 5, 34, 0, 0, 379, 380, 5, 34, 0, 0, 380, 384, 1, 0, 0, 0, 381, 383, 9, 0, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, 407, 1, 0, 0, 0, 391, 392, 3, 67, 33, 0, 392, 393, 5, 39, 0, 0, 393, 394, 5, 39, 0, 0, 394, 395, 5, 39, 0, 0, 395, 399, 1, 0, 0, 0, 396, 398, 9, 0, 0, 0, 397, 396, 1, 0, 0, 0, 398, 401, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 400, 402, 1, 0, 0, 0, 401, 399, 1, 0, 0, 0, 402, 403, 5, 39, 0, 0, 403, 404, 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 407, 1, 0, 0, 0, 406, 310, 1, 0, 0, 0, 406, 319, 1, 0, 0, 0, 406, 328, 1, 0, 0, 0, 406, 342, 1, 0, 0, 0, 406, 356, 1, 0, 0, 0, 406, 366, 1, 0, 0, 0, 406, 376, 1, 0, 0, 0, 406, 391, 1, 0, 0, 0, 407, 90, 1, 0, 0, 0, 408, 409, 7, 15, 0, 0, 409, 410, 3, 89, 44, 0, 410, 92, 1, 0, 0, 0, 411, 414, 3, 59, 29, 0, 412, 414, 5, 95, 0, 0, 413, 411, 1, 0, 0, 0, 413, 412, 1, 0, 0, 0, 414, 420, 1, 0, 0, 0, 415, 419, 3, 59, 29, 0, 416, 419, 3, 61, 30, 0, 417, 419, 5, 95, 0, 0, 418, 415, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 418, 417, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 94, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 36, 0, 176, 181, 191, 224, 229, 239, 247, 253, 256, 261, 269, 272, 274, 279, 287, 289, 294, 304, 308, 313, 315, 322, 324, 334, 336, 348, 350, 361, 371, 384, 399, 406, 413, 418, 420, 1, 0, 1, 0] \ No newline at end of file diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go index a3315b84207..969a5986180 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go index daf7f807d76..8e84579ed17 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go index 4af96aba58f..7b4cca62e62 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go @@ -1,9 +1,10 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen import ( "fmt" + "sync" "unicode" "github.com/antlr/antlr4/runtime/Go/antlr" @@ -11,272 +12,292 @@ import ( // Suppress unused import error var _ = fmt.Printf +var _ = sync.Once{} var _ = unicode.IsLetter -var serializedLexerAtn = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 38, 425, - 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, - 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, - 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, - 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, - 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, - 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, - 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, - 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, - 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 3, 2, 3, - 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, - 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, - 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, - 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, - 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, - 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, - 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, - 32, 3, 32, 3, 33, 3, 33, 5, 33, 179, 10, 33, 3, 33, 6, 33, 182, 10, 33, - 13, 33, 14, 33, 183, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, - 36, 5, 36, 194, 10, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, - 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, - 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, - 3, 40, 3, 40, 3, 40, 5, 40, 227, 10, 40, 3, 41, 6, 41, 230, 10, 41, 13, - 41, 14, 41, 231, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 7, 42, 240, - 10, 42, 12, 42, 14, 42, 243, 11, 42, 3, 42, 3, 42, 3, 43, 6, 43, 248, 10, - 43, 13, 43, 14, 43, 249, 3, 43, 3, 43, 6, 43, 254, 10, 43, 13, 43, 14, - 43, 255, 3, 43, 5, 43, 259, 10, 43, 3, 43, 6, 43, 262, 10, 43, 13, 43, - 14, 43, 263, 3, 43, 3, 43, 3, 43, 3, 43, 6, 43, 270, 10, 43, 13, 43, 14, - 43, 271, 3, 43, 5, 43, 275, 10, 43, 5, 43, 277, 10, 43, 3, 44, 6, 44, 280, - 10, 44, 13, 44, 14, 44, 281, 3, 44, 3, 44, 3, 44, 3, 44, 6, 44, 288, 10, - 44, 13, 44, 14, 44, 289, 5, 44, 292, 10, 44, 3, 45, 6, 45, 295, 10, 45, - 13, 45, 14, 45, 296, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 6, 45, 305, - 10, 45, 13, 45, 14, 45, 306, 3, 45, 3, 45, 5, 45, 311, 10, 45, 3, 46, 3, - 46, 3, 46, 7, 46, 316, 10, 46, 12, 46, 14, 46, 319, 11, 46, 3, 46, 3, 46, - 3, 46, 3, 46, 7, 46, 325, 10, 46, 12, 46, 14, 46, 328, 11, 46, 3, 46, 3, - 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 337, 10, 46, 12, 46, 14, - 46, 340, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, - 3, 46, 7, 46, 351, 10, 46, 12, 46, 14, 46, 354, 11, 46, 3, 46, 3, 46, 3, - 46, 3, 46, 3, 46, 3, 46, 7, 46, 362, 10, 46, 12, 46, 14, 46, 365, 11, 46, - 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 372, 10, 46, 12, 46, 14, 46, - 375, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, - 46, 385, 10, 46, 12, 46, 14, 46, 388, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, - 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 400, 10, 46, 12, 46, 14, - 46, 403, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 5, 46, 409, 10, 46, 3, 47, - 3, 47, 3, 47, 3, 48, 3, 48, 5, 48, 416, 10, 48, 3, 48, 3, 48, 3, 48, 7, - 48, 421, 10, 48, 12, 48, 14, 48, 424, 11, 48, 6, 338, 352, 386, 401, 2, - 49, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, - 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, - 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, - 59, 2, 61, 2, 63, 2, 65, 2, 67, 2, 69, 2, 71, 2, 73, 2, 75, 2, 77, 2, 79, - 2, 81, 31, 83, 32, 85, 33, 87, 34, 89, 35, 91, 36, 93, 37, 95, 38, 3, 2, - 18, 4, 2, 67, 92, 99, 124, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, - 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 84, 84, 116, 116, 12, 2, 36, 36, 41, - 41, 65, 65, 94, 94, 98, 100, 104, 104, 112, 112, 116, 116, 118, 118, 120, - 120, 4, 2, 90, 90, 122, 122, 5, 2, 11, 12, 14, 15, 34, 34, 3, 2, 12, 12, - 4, 2, 87, 87, 119, 119, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 6, 2, 12, - 12, 15, 15, 41, 41, 94, 94, 3, 2, 94, 94, 5, 2, 12, 12, 15, 15, 36, 36, - 5, 2, 12, 12, 15, 15, 41, 41, 4, 2, 68, 68, 100, 100, 2, 458, 2, 3, 3, - 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, - 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, - 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, - 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, - 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, - 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, - 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, - 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, - 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, - 95, 3, 2, 2, 2, 3, 97, 3, 2, 2, 2, 5, 100, 3, 2, 2, 2, 7, 103, 3, 2, 2, - 2, 9, 106, 3, 2, 2, 2, 11, 108, 3, 2, 2, 2, 13, 111, 3, 2, 2, 2, 15, 114, - 3, 2, 2, 2, 17, 116, 3, 2, 2, 2, 19, 119, 3, 2, 2, 2, 21, 122, 3, 2, 2, - 2, 23, 124, 3, 2, 2, 2, 25, 126, 3, 2, 2, 2, 27, 128, 3, 2, 2, 2, 29, 130, - 3, 2, 2, 2, 31, 132, 3, 2, 2, 2, 33, 134, 3, 2, 2, 2, 35, 136, 3, 2, 2, - 2, 37, 138, 3, 2, 2, 2, 39, 140, 3, 2, 2, 2, 41, 142, 3, 2, 2, 2, 43, 144, - 3, 2, 2, 2, 45, 146, 3, 2, 2, 2, 47, 148, 3, 2, 2, 2, 49, 150, 3, 2, 2, - 2, 51, 152, 3, 2, 2, 2, 53, 154, 3, 2, 2, 2, 55, 159, 3, 2, 2, 2, 57, 165, - 3, 2, 2, 2, 59, 170, 3, 2, 2, 2, 61, 172, 3, 2, 2, 2, 63, 174, 3, 2, 2, - 2, 65, 176, 3, 2, 2, 2, 67, 185, 3, 2, 2, 2, 69, 187, 3, 2, 2, 2, 71, 193, - 3, 2, 2, 2, 73, 195, 3, 2, 2, 2, 75, 198, 3, 2, 2, 2, 77, 203, 3, 2, 2, - 2, 79, 226, 3, 2, 2, 2, 81, 229, 3, 2, 2, 2, 83, 235, 3, 2, 2, 2, 85, 276, - 3, 2, 2, 2, 87, 291, 3, 2, 2, 2, 89, 310, 3, 2, 2, 2, 91, 408, 3, 2, 2, - 2, 93, 410, 3, 2, 2, 2, 95, 415, 3, 2, 2, 2, 97, 98, 7, 63, 2, 2, 98, 99, - 7, 63, 2, 2, 99, 4, 3, 2, 2, 2, 100, 101, 7, 35, 2, 2, 101, 102, 7, 63, - 2, 2, 102, 6, 3, 2, 2, 2, 103, 104, 7, 107, 2, 2, 104, 105, 7, 112, 2, - 2, 105, 8, 3, 2, 2, 2, 106, 107, 7, 62, 2, 2, 107, 10, 3, 2, 2, 2, 108, - 109, 7, 62, 2, 2, 109, 110, 7, 63, 2, 2, 110, 12, 3, 2, 2, 2, 111, 112, - 7, 64, 2, 2, 112, 113, 7, 63, 2, 2, 113, 14, 3, 2, 2, 2, 114, 115, 7, 64, - 2, 2, 115, 16, 3, 2, 2, 2, 116, 117, 7, 40, 2, 2, 117, 118, 7, 40, 2, 2, - 118, 18, 3, 2, 2, 2, 119, 120, 7, 126, 2, 2, 120, 121, 7, 126, 2, 2, 121, - 20, 3, 2, 2, 2, 122, 123, 7, 93, 2, 2, 123, 22, 3, 2, 2, 2, 124, 125, 7, - 95, 2, 2, 125, 24, 3, 2, 2, 2, 126, 127, 7, 125, 2, 2, 127, 26, 3, 2, 2, - 2, 128, 129, 7, 127, 2, 2, 129, 28, 3, 2, 2, 2, 130, 131, 7, 42, 2, 2, - 131, 30, 3, 2, 2, 2, 132, 133, 7, 43, 2, 2, 133, 32, 3, 2, 2, 2, 134, 135, - 7, 48, 2, 2, 135, 34, 3, 2, 2, 2, 136, 137, 7, 46, 2, 2, 137, 36, 3, 2, - 2, 2, 138, 139, 7, 47, 2, 2, 139, 38, 3, 2, 2, 2, 140, 141, 7, 35, 2, 2, - 141, 40, 3, 2, 2, 2, 142, 143, 7, 65, 2, 2, 143, 42, 3, 2, 2, 2, 144, 145, - 7, 60, 2, 2, 145, 44, 3, 2, 2, 2, 146, 147, 7, 45, 2, 2, 147, 46, 3, 2, - 2, 2, 148, 149, 7, 44, 2, 2, 149, 48, 3, 2, 2, 2, 150, 151, 7, 49, 2, 2, - 151, 50, 3, 2, 2, 2, 152, 153, 7, 39, 2, 2, 153, 52, 3, 2, 2, 2, 154, 155, - 7, 118, 2, 2, 155, 156, 7, 116, 2, 2, 156, 157, 7, 119, 2, 2, 157, 158, - 7, 103, 2, 2, 158, 54, 3, 2, 2, 2, 159, 160, 7, 104, 2, 2, 160, 161, 7, - 99, 2, 2, 161, 162, 7, 110, 2, 2, 162, 163, 7, 117, 2, 2, 163, 164, 7, - 103, 2, 2, 164, 56, 3, 2, 2, 2, 165, 166, 7, 112, 2, 2, 166, 167, 7, 119, - 2, 2, 167, 168, 7, 110, 2, 2, 168, 169, 7, 110, 2, 2, 169, 58, 3, 2, 2, - 2, 170, 171, 7, 94, 2, 2, 171, 60, 3, 2, 2, 2, 172, 173, 9, 2, 2, 2, 173, - 62, 3, 2, 2, 2, 174, 175, 4, 50, 59, 2, 175, 64, 3, 2, 2, 2, 176, 178, - 9, 3, 2, 2, 177, 179, 9, 4, 2, 2, 178, 177, 3, 2, 2, 2, 178, 179, 3, 2, - 2, 2, 179, 181, 3, 2, 2, 2, 180, 182, 5, 63, 32, 2, 181, 180, 3, 2, 2, - 2, 182, 183, 3, 2, 2, 2, 183, 181, 3, 2, 2, 2, 183, 184, 3, 2, 2, 2, 184, - 66, 3, 2, 2, 2, 185, 186, 9, 5, 2, 2, 186, 68, 3, 2, 2, 2, 187, 188, 9, - 6, 2, 2, 188, 70, 3, 2, 2, 2, 189, 194, 5, 73, 37, 2, 190, 194, 5, 77, - 39, 2, 191, 194, 5, 79, 40, 2, 192, 194, 5, 75, 38, 2, 193, 189, 3, 2, - 2, 2, 193, 190, 3, 2, 2, 2, 193, 191, 3, 2, 2, 2, 193, 192, 3, 2, 2, 2, - 194, 72, 3, 2, 2, 2, 195, 196, 5, 59, 30, 2, 196, 197, 9, 7, 2, 2, 197, - 74, 3, 2, 2, 2, 198, 199, 5, 59, 30, 2, 199, 200, 4, 50, 53, 2, 200, 201, - 4, 50, 57, 2, 201, 202, 4, 50, 57, 2, 202, 76, 3, 2, 2, 2, 203, 204, 5, - 59, 30, 2, 204, 205, 9, 8, 2, 2, 205, 206, 5, 67, 34, 2, 206, 207, 5, 67, - 34, 2, 207, 78, 3, 2, 2, 2, 208, 209, 5, 59, 30, 2, 209, 210, 7, 119, 2, - 2, 210, 211, 5, 67, 34, 2, 211, 212, 5, 67, 34, 2, 212, 213, 5, 67, 34, - 2, 213, 214, 5, 67, 34, 2, 214, 227, 3, 2, 2, 2, 215, 216, 5, 59, 30, 2, - 216, 217, 7, 87, 2, 2, 217, 218, 5, 67, 34, 2, 218, 219, 5, 67, 34, 2, - 219, 220, 5, 67, 34, 2, 220, 221, 5, 67, 34, 2, 221, 222, 5, 67, 34, 2, - 222, 223, 5, 67, 34, 2, 223, 224, 5, 67, 34, 2, 224, 225, 5, 67, 34, 2, - 225, 227, 3, 2, 2, 2, 226, 208, 3, 2, 2, 2, 226, 215, 3, 2, 2, 2, 227, - 80, 3, 2, 2, 2, 228, 230, 9, 9, 2, 2, 229, 228, 3, 2, 2, 2, 230, 231, 3, - 2, 2, 2, 231, 229, 3, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 233, 3, 2, 2, - 2, 233, 234, 8, 41, 2, 2, 234, 82, 3, 2, 2, 2, 235, 236, 7, 49, 2, 2, 236, - 237, 7, 49, 2, 2, 237, 241, 3, 2, 2, 2, 238, 240, 10, 10, 2, 2, 239, 238, - 3, 2, 2, 2, 240, 243, 3, 2, 2, 2, 241, 239, 3, 2, 2, 2, 241, 242, 3, 2, - 2, 2, 242, 244, 3, 2, 2, 2, 243, 241, 3, 2, 2, 2, 244, 245, 8, 42, 2, 2, - 245, 84, 3, 2, 2, 2, 246, 248, 5, 63, 32, 2, 247, 246, 3, 2, 2, 2, 248, - 249, 3, 2, 2, 2, 249, 247, 3, 2, 2, 2, 249, 250, 3, 2, 2, 2, 250, 251, - 3, 2, 2, 2, 251, 253, 7, 48, 2, 2, 252, 254, 5, 63, 32, 2, 253, 252, 3, - 2, 2, 2, 254, 255, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, - 2, 256, 258, 3, 2, 2, 2, 257, 259, 5, 65, 33, 2, 258, 257, 3, 2, 2, 2, - 258, 259, 3, 2, 2, 2, 259, 277, 3, 2, 2, 2, 260, 262, 5, 63, 32, 2, 261, - 260, 3, 2, 2, 2, 262, 263, 3, 2, 2, 2, 263, 261, 3, 2, 2, 2, 263, 264, - 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 266, 5, 65, 33, 2, 266, 277, 3, - 2, 2, 2, 267, 269, 7, 48, 2, 2, 268, 270, 5, 63, 32, 2, 269, 268, 3, 2, - 2, 2, 270, 271, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, - 272, 274, 3, 2, 2, 2, 273, 275, 5, 65, 33, 2, 274, 273, 3, 2, 2, 2, 274, - 275, 3, 2, 2, 2, 275, 277, 3, 2, 2, 2, 276, 247, 3, 2, 2, 2, 276, 261, - 3, 2, 2, 2, 276, 267, 3, 2, 2, 2, 277, 86, 3, 2, 2, 2, 278, 280, 5, 63, - 32, 2, 279, 278, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 279, 3, 2, 2, 2, - 281, 282, 3, 2, 2, 2, 282, 292, 3, 2, 2, 2, 283, 284, 7, 50, 2, 2, 284, - 285, 7, 122, 2, 2, 285, 287, 3, 2, 2, 2, 286, 288, 5, 67, 34, 2, 287, 286, - 3, 2, 2, 2, 288, 289, 3, 2, 2, 2, 289, 287, 3, 2, 2, 2, 289, 290, 3, 2, - 2, 2, 290, 292, 3, 2, 2, 2, 291, 279, 3, 2, 2, 2, 291, 283, 3, 2, 2, 2, - 292, 88, 3, 2, 2, 2, 293, 295, 5, 63, 32, 2, 294, 293, 3, 2, 2, 2, 295, - 296, 3, 2, 2, 2, 296, 294, 3, 2, 2, 2, 296, 297, 3, 2, 2, 2, 297, 298, - 3, 2, 2, 2, 298, 299, 9, 11, 2, 2, 299, 311, 3, 2, 2, 2, 300, 301, 7, 50, - 2, 2, 301, 302, 7, 122, 2, 2, 302, 304, 3, 2, 2, 2, 303, 305, 5, 67, 34, - 2, 304, 303, 3, 2, 2, 2, 305, 306, 3, 2, 2, 2, 306, 304, 3, 2, 2, 2, 306, - 307, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 309, 9, 11, 2, 2, 309, 311, - 3, 2, 2, 2, 310, 294, 3, 2, 2, 2, 310, 300, 3, 2, 2, 2, 311, 90, 3, 2, - 2, 2, 312, 317, 7, 36, 2, 2, 313, 316, 5, 71, 36, 2, 314, 316, 10, 12, - 2, 2, 315, 313, 3, 2, 2, 2, 315, 314, 3, 2, 2, 2, 316, 319, 3, 2, 2, 2, - 317, 315, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 320, 3, 2, 2, 2, 319, - 317, 3, 2, 2, 2, 320, 409, 7, 36, 2, 2, 321, 326, 7, 41, 2, 2, 322, 325, - 5, 71, 36, 2, 323, 325, 10, 13, 2, 2, 324, 322, 3, 2, 2, 2, 324, 323, 3, - 2, 2, 2, 325, 328, 3, 2, 2, 2, 326, 324, 3, 2, 2, 2, 326, 327, 3, 2, 2, - 2, 327, 329, 3, 2, 2, 2, 328, 326, 3, 2, 2, 2, 329, 409, 7, 41, 2, 2, 330, - 331, 7, 36, 2, 2, 331, 332, 7, 36, 2, 2, 332, 333, 7, 36, 2, 2, 333, 338, - 3, 2, 2, 2, 334, 337, 5, 71, 36, 2, 335, 337, 10, 14, 2, 2, 336, 334, 3, - 2, 2, 2, 336, 335, 3, 2, 2, 2, 337, 340, 3, 2, 2, 2, 338, 339, 3, 2, 2, - 2, 338, 336, 3, 2, 2, 2, 339, 341, 3, 2, 2, 2, 340, 338, 3, 2, 2, 2, 341, - 342, 7, 36, 2, 2, 342, 343, 7, 36, 2, 2, 343, 409, 7, 36, 2, 2, 344, 345, - 7, 41, 2, 2, 345, 346, 7, 41, 2, 2, 346, 347, 7, 41, 2, 2, 347, 352, 3, - 2, 2, 2, 348, 351, 5, 71, 36, 2, 349, 351, 10, 14, 2, 2, 350, 348, 3, 2, - 2, 2, 350, 349, 3, 2, 2, 2, 351, 354, 3, 2, 2, 2, 352, 353, 3, 2, 2, 2, - 352, 350, 3, 2, 2, 2, 353, 355, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 355, - 356, 7, 41, 2, 2, 356, 357, 7, 41, 2, 2, 357, 409, 7, 41, 2, 2, 358, 359, - 5, 69, 35, 2, 359, 363, 7, 36, 2, 2, 360, 362, 10, 15, 2, 2, 361, 360, - 3, 2, 2, 2, 362, 365, 3, 2, 2, 2, 363, 361, 3, 2, 2, 2, 363, 364, 3, 2, - 2, 2, 364, 366, 3, 2, 2, 2, 365, 363, 3, 2, 2, 2, 366, 367, 7, 36, 2, 2, - 367, 409, 3, 2, 2, 2, 368, 369, 5, 69, 35, 2, 369, 373, 7, 41, 2, 2, 370, - 372, 10, 16, 2, 2, 371, 370, 3, 2, 2, 2, 372, 375, 3, 2, 2, 2, 373, 371, - 3, 2, 2, 2, 373, 374, 3, 2, 2, 2, 374, 376, 3, 2, 2, 2, 375, 373, 3, 2, - 2, 2, 376, 377, 7, 41, 2, 2, 377, 409, 3, 2, 2, 2, 378, 379, 5, 69, 35, - 2, 379, 380, 7, 36, 2, 2, 380, 381, 7, 36, 2, 2, 381, 382, 7, 36, 2, 2, - 382, 386, 3, 2, 2, 2, 383, 385, 11, 2, 2, 2, 384, 383, 3, 2, 2, 2, 385, - 388, 3, 2, 2, 2, 386, 387, 3, 2, 2, 2, 386, 384, 3, 2, 2, 2, 387, 389, - 3, 2, 2, 2, 388, 386, 3, 2, 2, 2, 389, 390, 7, 36, 2, 2, 390, 391, 7, 36, - 2, 2, 391, 392, 7, 36, 2, 2, 392, 409, 3, 2, 2, 2, 393, 394, 5, 69, 35, - 2, 394, 395, 7, 41, 2, 2, 395, 396, 7, 41, 2, 2, 396, 397, 7, 41, 2, 2, - 397, 401, 3, 2, 2, 2, 398, 400, 11, 2, 2, 2, 399, 398, 3, 2, 2, 2, 400, - 403, 3, 2, 2, 2, 401, 402, 3, 2, 2, 2, 401, 399, 3, 2, 2, 2, 402, 404, - 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 404, 405, 7, 41, 2, 2, 405, 406, 7, 41, - 2, 2, 406, 407, 7, 41, 2, 2, 407, 409, 3, 2, 2, 2, 408, 312, 3, 2, 2, 2, - 408, 321, 3, 2, 2, 2, 408, 330, 3, 2, 2, 2, 408, 344, 3, 2, 2, 2, 408, - 358, 3, 2, 2, 2, 408, 368, 3, 2, 2, 2, 408, 378, 3, 2, 2, 2, 408, 393, - 3, 2, 2, 2, 409, 92, 3, 2, 2, 2, 410, 411, 9, 17, 2, 2, 411, 412, 5, 91, - 46, 2, 412, 94, 3, 2, 2, 2, 413, 416, 5, 61, 31, 2, 414, 416, 7, 97, 2, - 2, 415, 413, 3, 2, 2, 2, 415, 414, 3, 2, 2, 2, 416, 422, 3, 2, 2, 2, 417, - 421, 5, 61, 31, 2, 418, 421, 5, 63, 32, 2, 419, 421, 7, 97, 2, 2, 420, - 417, 3, 2, 2, 2, 420, 418, 3, 2, 2, 2, 420, 419, 3, 2, 2, 2, 421, 424, - 3, 2, 2, 2, 422, 420, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, 423, 96, 3, 2, - 2, 2, 424, 422, 3, 2, 2, 2, 38, 2, 178, 183, 193, 226, 231, 241, 249, 255, - 258, 263, 271, 274, 276, 281, 289, 291, 296, 306, 310, 315, 317, 324, 326, - 336, 338, 350, 352, 363, 373, 386, 401, 408, 415, 420, 422, 3, 2, 3, 2, -} - -var lexerChannelNames = []string{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN", -} - -var lexerModeNames = []string{ - "DEFAULT_MODE", -} - -var lexerLiteralNames = []string{ - "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", - "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", - "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", +type CELLexer struct { + *antlr.BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string } -var lexerSymbolicNames = []string{ - "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", - "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", - "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", - "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", "NUL", - "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", - "BYTES", "IDENTIFIER", +var cellexerLexerStaticData struct { + once sync.Once + serializedATN []int32 + channelNames []string + modeNames []string + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA } -var lexerRuleNames = []string{ - "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", - "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", - "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", - "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", "NUL", - "BACKSLASH", "LETTER", "DIGIT", "EXPONENT", "HEXDIGIT", "RAW", "ESC_SEQ", - "ESC_CHAR_SEQ", "ESC_OCT_SEQ", "ESC_BYTE_SEQ", "ESC_UNI_SEQ", "WHITESPACE", - "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", "BYTES", "IDENTIFIER", +func cellexerLexerInit() { + staticData := &cellexerLexerStaticData + staticData.channelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + } + staticData.modeNames = []string{ + "DEFAULT_MODE", + } + staticData.literalNames = []string{ + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", + "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", + } + staticData.symbolicNames = []string{ + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", + "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", + "STRING", "BYTES", "IDENTIFIER", + } + staticData.ruleNames = []string{ + "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", + "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "BACKSLASH", "LETTER", "DIGIT", "EXPONENT", "HEXDIGIT", "RAW", + "ESC_SEQ", "ESC_CHAR_SEQ", "ESC_OCT_SEQ", "ESC_BYTE_SEQ", "ESC_UNI_SEQ", + "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", + "BYTES", "IDENTIFIER", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 0, 36, 423, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, + 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, + 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, + 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, + 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, + 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, + 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, + 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, + 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, + 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, + 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, + 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, + 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, + 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, + 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, + 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, + 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 177, 8, 31, 1, 31, 4, 31, 180, 8, 31, + 11, 31, 12, 31, 181, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, + 34, 3, 34, 192, 8, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, + 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, + 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, + 1, 38, 1, 38, 1, 38, 3, 38, 225, 8, 38, 1, 39, 4, 39, 228, 8, 39, 11, 39, + 12, 39, 229, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 238, 8, 40, + 10, 40, 12, 40, 241, 9, 40, 1, 40, 1, 40, 1, 41, 4, 41, 246, 8, 41, 11, + 41, 12, 41, 247, 1, 41, 1, 41, 4, 41, 252, 8, 41, 11, 41, 12, 41, 253, + 1, 41, 3, 41, 257, 8, 41, 1, 41, 4, 41, 260, 8, 41, 11, 41, 12, 41, 261, + 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 268, 8, 41, 11, 41, 12, 41, 269, 1, + 41, 3, 41, 273, 8, 41, 3, 41, 275, 8, 41, 1, 42, 4, 42, 278, 8, 42, 11, + 42, 12, 42, 279, 1, 42, 1, 42, 1, 42, 1, 42, 4, 42, 286, 8, 42, 11, 42, + 12, 42, 287, 3, 42, 290, 8, 42, 1, 43, 4, 43, 293, 8, 43, 11, 43, 12, 43, + 294, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 4, 43, 303, 8, 43, 11, 43, + 12, 43, 304, 1, 43, 1, 43, 3, 43, 309, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, + 314, 8, 44, 10, 44, 12, 44, 317, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, + 44, 323, 8, 44, 10, 44, 12, 44, 326, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 5, 44, 335, 8, 44, 10, 44, 12, 44, 338, 9, 44, 1, + 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 349, + 8, 44, 10, 44, 12, 44, 352, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 5, 44, 360, 8, 44, 10, 44, 12, 44, 363, 9, 44, 1, 44, 1, 44, 1, 44, + 1, 44, 1, 44, 5, 44, 370, 8, 44, 10, 44, 12, 44, 373, 9, 44, 1, 44, 1, + 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 383, 8, 44, 10, 44, + 12, 44, 386, 9, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 1, 44, 1, 44, 5, 44, 398, 8, 44, 10, 44, 12, 44, 401, 9, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 3, 44, 407, 8, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, + 46, 3, 46, 414, 8, 46, 1, 46, 1, 46, 1, 46, 5, 46, 419, 8, 46, 10, 46, + 12, 46, 422, 9, 46, 4, 336, 350, 384, 399, 0, 47, 1, 1, 3, 2, 5, 3, 7, + 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, + 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, + 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 0, 59, 0, 61, 0, 63, 0, + 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 29, 81, 30, 83, 31, + 85, 32, 87, 33, 89, 34, 91, 35, 93, 36, 1, 0, 16, 2, 0, 65, 90, 97, 122, + 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, + 102, 2, 0, 82, 82, 114, 114, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 96, + 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 88, 88, 120, + 120, 3, 0, 9, 10, 12, 13, 32, 32, 1, 0, 10, 10, 2, 0, 85, 85, 117, 117, + 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, + 92, 1, 0, 92, 92, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 10, 10, 13, 13, 39, + 39, 2, 0, 66, 66, 98, 98, 456, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, + 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, + 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, + 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, + 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, + 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, + 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, + 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, + 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, + 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, + 3, 98, 1, 0, 0, 0, 5, 101, 1, 0, 0, 0, 7, 104, 1, 0, 0, 0, 9, 106, 1, 0, + 0, 0, 11, 109, 1, 0, 0, 0, 13, 112, 1, 0, 0, 0, 15, 114, 1, 0, 0, 0, 17, + 117, 1, 0, 0, 0, 19, 120, 1, 0, 0, 0, 21, 122, 1, 0, 0, 0, 23, 124, 1, + 0, 0, 0, 25, 126, 1, 0, 0, 0, 27, 128, 1, 0, 0, 0, 29, 130, 1, 0, 0, 0, + 31, 132, 1, 0, 0, 0, 33, 134, 1, 0, 0, 0, 35, 136, 1, 0, 0, 0, 37, 138, + 1, 0, 0, 0, 39, 140, 1, 0, 0, 0, 41, 142, 1, 0, 0, 0, 43, 144, 1, 0, 0, + 0, 45, 146, 1, 0, 0, 0, 47, 148, 1, 0, 0, 0, 49, 150, 1, 0, 0, 0, 51, 152, + 1, 0, 0, 0, 53, 157, 1, 0, 0, 0, 55, 163, 1, 0, 0, 0, 57, 168, 1, 0, 0, + 0, 59, 170, 1, 0, 0, 0, 61, 172, 1, 0, 0, 0, 63, 174, 1, 0, 0, 0, 65, 183, + 1, 0, 0, 0, 67, 185, 1, 0, 0, 0, 69, 191, 1, 0, 0, 0, 71, 193, 1, 0, 0, + 0, 73, 196, 1, 0, 0, 0, 75, 201, 1, 0, 0, 0, 77, 224, 1, 0, 0, 0, 79, 227, + 1, 0, 0, 0, 81, 233, 1, 0, 0, 0, 83, 274, 1, 0, 0, 0, 85, 289, 1, 0, 0, + 0, 87, 308, 1, 0, 0, 0, 89, 406, 1, 0, 0, 0, 91, 408, 1, 0, 0, 0, 93, 413, + 1, 0, 0, 0, 95, 96, 5, 61, 0, 0, 96, 97, 5, 61, 0, 0, 97, 2, 1, 0, 0, 0, + 98, 99, 5, 33, 0, 0, 99, 100, 5, 61, 0, 0, 100, 4, 1, 0, 0, 0, 101, 102, + 5, 105, 0, 0, 102, 103, 5, 110, 0, 0, 103, 6, 1, 0, 0, 0, 104, 105, 5, + 60, 0, 0, 105, 8, 1, 0, 0, 0, 106, 107, 5, 60, 0, 0, 107, 108, 5, 61, 0, + 0, 108, 10, 1, 0, 0, 0, 109, 110, 5, 62, 0, 0, 110, 111, 5, 61, 0, 0, 111, + 12, 1, 0, 0, 0, 112, 113, 5, 62, 0, 0, 113, 14, 1, 0, 0, 0, 114, 115, 5, + 38, 0, 0, 115, 116, 5, 38, 0, 0, 116, 16, 1, 0, 0, 0, 117, 118, 5, 124, + 0, 0, 118, 119, 5, 124, 0, 0, 119, 18, 1, 0, 0, 0, 120, 121, 5, 91, 0, + 0, 121, 20, 1, 0, 0, 0, 122, 123, 5, 93, 0, 0, 123, 22, 1, 0, 0, 0, 124, + 125, 5, 123, 0, 0, 125, 24, 1, 0, 0, 0, 126, 127, 5, 125, 0, 0, 127, 26, + 1, 0, 0, 0, 128, 129, 5, 40, 0, 0, 129, 28, 1, 0, 0, 0, 130, 131, 5, 41, + 0, 0, 131, 30, 1, 0, 0, 0, 132, 133, 5, 46, 0, 0, 133, 32, 1, 0, 0, 0, + 134, 135, 5, 44, 0, 0, 135, 34, 1, 0, 0, 0, 136, 137, 5, 45, 0, 0, 137, + 36, 1, 0, 0, 0, 138, 139, 5, 33, 0, 0, 139, 38, 1, 0, 0, 0, 140, 141, 5, + 63, 0, 0, 141, 40, 1, 0, 0, 0, 142, 143, 5, 58, 0, 0, 143, 42, 1, 0, 0, + 0, 144, 145, 5, 43, 0, 0, 145, 44, 1, 0, 0, 0, 146, 147, 5, 42, 0, 0, 147, + 46, 1, 0, 0, 0, 148, 149, 5, 47, 0, 0, 149, 48, 1, 0, 0, 0, 150, 151, 5, + 37, 0, 0, 151, 50, 1, 0, 0, 0, 152, 153, 5, 116, 0, 0, 153, 154, 5, 114, + 0, 0, 154, 155, 5, 117, 0, 0, 155, 156, 5, 101, 0, 0, 156, 52, 1, 0, 0, + 0, 157, 158, 5, 102, 0, 0, 158, 159, 5, 97, 0, 0, 159, 160, 5, 108, 0, + 0, 160, 161, 5, 115, 0, 0, 161, 162, 5, 101, 0, 0, 162, 54, 1, 0, 0, 0, + 163, 164, 5, 110, 0, 0, 164, 165, 5, 117, 0, 0, 165, 166, 5, 108, 0, 0, + 166, 167, 5, 108, 0, 0, 167, 56, 1, 0, 0, 0, 168, 169, 5, 92, 0, 0, 169, + 58, 1, 0, 0, 0, 170, 171, 7, 0, 0, 0, 171, 60, 1, 0, 0, 0, 172, 173, 2, + 48, 57, 0, 173, 62, 1, 0, 0, 0, 174, 176, 7, 1, 0, 0, 175, 177, 7, 2, 0, + 0, 176, 175, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 179, 1, 0, 0, 0, 178, + 180, 3, 61, 30, 0, 179, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 179, + 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 64, 1, 0, 0, 0, 183, 184, 7, 3, + 0, 0, 184, 66, 1, 0, 0, 0, 185, 186, 7, 4, 0, 0, 186, 68, 1, 0, 0, 0, 187, + 192, 3, 71, 35, 0, 188, 192, 3, 75, 37, 0, 189, 192, 3, 77, 38, 0, 190, + 192, 3, 73, 36, 0, 191, 187, 1, 0, 0, 0, 191, 188, 1, 0, 0, 0, 191, 189, + 1, 0, 0, 0, 191, 190, 1, 0, 0, 0, 192, 70, 1, 0, 0, 0, 193, 194, 3, 57, + 28, 0, 194, 195, 7, 5, 0, 0, 195, 72, 1, 0, 0, 0, 196, 197, 3, 57, 28, + 0, 197, 198, 2, 48, 51, 0, 198, 199, 2, 48, 55, 0, 199, 200, 2, 48, 55, + 0, 200, 74, 1, 0, 0, 0, 201, 202, 3, 57, 28, 0, 202, 203, 7, 6, 0, 0, 203, + 204, 3, 65, 32, 0, 204, 205, 3, 65, 32, 0, 205, 76, 1, 0, 0, 0, 206, 207, + 3, 57, 28, 0, 207, 208, 5, 117, 0, 0, 208, 209, 3, 65, 32, 0, 209, 210, + 3, 65, 32, 0, 210, 211, 3, 65, 32, 0, 211, 212, 3, 65, 32, 0, 212, 225, + 1, 0, 0, 0, 213, 214, 3, 57, 28, 0, 214, 215, 5, 85, 0, 0, 215, 216, 3, + 65, 32, 0, 216, 217, 3, 65, 32, 0, 217, 218, 3, 65, 32, 0, 218, 219, 3, + 65, 32, 0, 219, 220, 3, 65, 32, 0, 220, 221, 3, 65, 32, 0, 221, 222, 3, + 65, 32, 0, 222, 223, 3, 65, 32, 0, 223, 225, 1, 0, 0, 0, 224, 206, 1, 0, + 0, 0, 224, 213, 1, 0, 0, 0, 225, 78, 1, 0, 0, 0, 226, 228, 7, 7, 0, 0, + 227, 226, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 227, 1, 0, 0, 0, 229, + 230, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 6, 39, 0, 0, 232, 80, + 1, 0, 0, 0, 233, 234, 5, 47, 0, 0, 234, 235, 5, 47, 0, 0, 235, 239, 1, + 0, 0, 0, 236, 238, 8, 8, 0, 0, 237, 236, 1, 0, 0, 0, 238, 241, 1, 0, 0, + 0, 239, 237, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 242, 1, 0, 0, 0, 241, + 239, 1, 0, 0, 0, 242, 243, 6, 40, 0, 0, 243, 82, 1, 0, 0, 0, 244, 246, + 3, 61, 30, 0, 245, 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 245, 1, + 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 251, 5, 46, 0, + 0, 250, 252, 3, 61, 30, 0, 251, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, + 253, 251, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, + 257, 3, 63, 31, 0, 256, 255, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 275, + 1, 0, 0, 0, 258, 260, 3, 61, 30, 0, 259, 258, 1, 0, 0, 0, 260, 261, 1, + 0, 0, 0, 261, 259, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 263, 1, 0, 0, + 0, 263, 264, 3, 63, 31, 0, 264, 275, 1, 0, 0, 0, 265, 267, 5, 46, 0, 0, + 266, 268, 3, 61, 30, 0, 267, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, + 267, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 272, 1, 0, 0, 0, 271, 273, + 3, 63, 31, 0, 272, 271, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 275, 1, + 0, 0, 0, 274, 245, 1, 0, 0, 0, 274, 259, 1, 0, 0, 0, 274, 265, 1, 0, 0, + 0, 275, 84, 1, 0, 0, 0, 276, 278, 3, 61, 30, 0, 277, 276, 1, 0, 0, 0, 278, + 279, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 290, + 1, 0, 0, 0, 281, 282, 5, 48, 0, 0, 282, 283, 5, 120, 0, 0, 283, 285, 1, + 0, 0, 0, 284, 286, 3, 65, 32, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, + 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, + 289, 277, 1, 0, 0, 0, 289, 281, 1, 0, 0, 0, 290, 86, 1, 0, 0, 0, 291, 293, + 3, 61, 30, 0, 292, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 292, 1, + 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 297, 7, 9, 0, + 0, 297, 309, 1, 0, 0, 0, 298, 299, 5, 48, 0, 0, 299, 300, 5, 120, 0, 0, + 300, 302, 1, 0, 0, 0, 301, 303, 3, 65, 32, 0, 302, 301, 1, 0, 0, 0, 303, + 304, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 306, + 1, 0, 0, 0, 306, 307, 7, 9, 0, 0, 307, 309, 1, 0, 0, 0, 308, 292, 1, 0, + 0, 0, 308, 298, 1, 0, 0, 0, 309, 88, 1, 0, 0, 0, 310, 315, 5, 34, 0, 0, + 311, 314, 3, 69, 34, 0, 312, 314, 8, 10, 0, 0, 313, 311, 1, 0, 0, 0, 313, + 312, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, + 1, 0, 0, 0, 316, 318, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 407, 5, 34, + 0, 0, 319, 324, 5, 39, 0, 0, 320, 323, 3, 69, 34, 0, 321, 323, 8, 11, 0, + 0, 322, 320, 1, 0, 0, 0, 322, 321, 1, 0, 0, 0, 323, 326, 1, 0, 0, 0, 324, + 322, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 327, 1, 0, 0, 0, 326, 324, + 1, 0, 0, 0, 327, 407, 5, 39, 0, 0, 328, 329, 5, 34, 0, 0, 329, 330, 5, + 34, 0, 0, 330, 331, 5, 34, 0, 0, 331, 336, 1, 0, 0, 0, 332, 335, 3, 69, + 34, 0, 333, 335, 8, 12, 0, 0, 334, 332, 1, 0, 0, 0, 334, 333, 1, 0, 0, + 0, 335, 338, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, + 339, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 340, 5, 34, 0, 0, 340, 341, + 5, 34, 0, 0, 341, 407, 5, 34, 0, 0, 342, 343, 5, 39, 0, 0, 343, 344, 5, + 39, 0, 0, 344, 345, 5, 39, 0, 0, 345, 350, 1, 0, 0, 0, 346, 349, 3, 69, + 34, 0, 347, 349, 8, 12, 0, 0, 348, 346, 1, 0, 0, 0, 348, 347, 1, 0, 0, + 0, 349, 352, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 351, + 353, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 353, 354, 5, 39, 0, 0, 354, 355, + 5, 39, 0, 0, 355, 407, 5, 39, 0, 0, 356, 357, 3, 67, 33, 0, 357, 361, 5, + 34, 0, 0, 358, 360, 8, 13, 0, 0, 359, 358, 1, 0, 0, 0, 360, 363, 1, 0, + 0, 0, 361, 359, 1, 0, 0, 0, 361, 362, 1, 0, 0, 0, 362, 364, 1, 0, 0, 0, + 363, 361, 1, 0, 0, 0, 364, 365, 5, 34, 0, 0, 365, 407, 1, 0, 0, 0, 366, + 367, 3, 67, 33, 0, 367, 371, 5, 39, 0, 0, 368, 370, 8, 14, 0, 0, 369, 368, + 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, + 0, 0, 372, 374, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 374, 375, 5, 39, 0, 0, + 375, 407, 1, 0, 0, 0, 376, 377, 3, 67, 33, 0, 377, 378, 5, 34, 0, 0, 378, + 379, 5, 34, 0, 0, 379, 380, 5, 34, 0, 0, 380, 384, 1, 0, 0, 0, 381, 383, + 9, 0, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 385, 1, 0, + 0, 0, 384, 382, 1, 0, 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, + 387, 388, 5, 34, 0, 0, 388, 389, 5, 34, 0, 0, 389, 390, 5, 34, 0, 0, 390, + 407, 1, 0, 0, 0, 391, 392, 3, 67, 33, 0, 392, 393, 5, 39, 0, 0, 393, 394, + 5, 39, 0, 0, 394, 395, 5, 39, 0, 0, 395, 399, 1, 0, 0, 0, 396, 398, 9, + 0, 0, 0, 397, 396, 1, 0, 0, 0, 398, 401, 1, 0, 0, 0, 399, 400, 1, 0, 0, + 0, 399, 397, 1, 0, 0, 0, 400, 402, 1, 0, 0, 0, 401, 399, 1, 0, 0, 0, 402, + 403, 5, 39, 0, 0, 403, 404, 5, 39, 0, 0, 404, 405, 5, 39, 0, 0, 405, 407, + 1, 0, 0, 0, 406, 310, 1, 0, 0, 0, 406, 319, 1, 0, 0, 0, 406, 328, 1, 0, + 0, 0, 406, 342, 1, 0, 0, 0, 406, 356, 1, 0, 0, 0, 406, 366, 1, 0, 0, 0, + 406, 376, 1, 0, 0, 0, 406, 391, 1, 0, 0, 0, 407, 90, 1, 0, 0, 0, 408, 409, + 7, 15, 0, 0, 409, 410, 3, 89, 44, 0, 410, 92, 1, 0, 0, 0, 411, 414, 3, + 59, 29, 0, 412, 414, 5, 95, 0, 0, 413, 411, 1, 0, 0, 0, 413, 412, 1, 0, + 0, 0, 414, 420, 1, 0, 0, 0, 415, 419, 3, 59, 29, 0, 416, 419, 3, 61, 30, + 0, 417, 419, 5, 95, 0, 0, 418, 415, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 418, + 417, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, + 1, 0, 0, 0, 421, 94, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 36, 0, 176, 181, + 191, 224, 229, 239, 247, 253, 256, 261, 269, 272, 274, 279, 287, 289, 294, + 304, 308, 313, 315, 322, 324, 334, 336, 348, 350, 361, 371, 384, 399, 406, + 413, 418, 420, 1, 0, 1, 0, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } } -type CELLexer struct { - *antlr.BaseLexer - channelNames []string - modeNames []string - // TODO: EOF string +// CELLexerInit initializes any static state used to implement CELLexer. By default the +// static state used to implement the lexer is lazily initialized during the first call to +// NewCELLexer(). You can call this function if you wish to initialize the static state ahead +// of time. +func CELLexerInit() { + staticData := &cellexerLexerStaticData + staticData.once.Do(cellexerLexerInit) } // NewCELLexer produces a new lexer instance for the optional input antlr.CharStream. -// -// The *CELLexer instance produced may be reused by calling the SetInputStream method. -// The initial lexer configuration is expensive to construct, and the object is not thread-safe; -// however, if used within a Golang sync.Pool, the construction cost amortizes well and the -// objects can be used in a thread-safe manner. func NewCELLexer(input antlr.CharStream) *CELLexer { + CELLexerInit() l := new(CELLexer) - lexerDeserializer := antlr.NewATNDeserializer(nil) - lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) - lexerDecisionToDFA := make([]*antlr.DFA, len(lexerAtn.DecisionToState)) - for index, ds := range lexerAtn.DecisionToState { - lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) - } l.BaseLexer = antlr.NewBaseLexer(input) - l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) - - l.channelNames = lexerChannelNames - l.modeNames = lexerModeNames - l.RuleNames = lexerRuleNames - l.LiteralNames = lexerLiteralNames - l.SymbolicNames = lexerSymbolicNames + staticData := &cellexerLexerStaticData + l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + l.channelNames = staticData.channelNames + l.modeNames = staticData.modeNames + l.RuleNames = staticData.ruleNames + l.LiteralNames = staticData.literalNames + l.SymbolicNames = staticData.symbolicNames l.GrammarFileName = "CEL.g4" // TODO: l.EOF = antlr.TokenEOF diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go index e555ae62723..1b631b6e1be 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_listener.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go index c5e18930e5b..afb3fe0d1c2 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_parser.go @@ -1,161 +1,181 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen // CEL import ( "fmt" - "reflect" "strconv" + "sync" "github.com/antlr/antlr4/runtime/Go/antlr" ) // Suppress unused import errors var _ = fmt.Printf -var _ = reflect.Copy var _ = strconv.Itoa - -var parserATN = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 38, 211, - 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, - 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, - 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 5, 3, 38, 10, 3, 3, 4, 3, 4, 3, 4, 7, 4, 43, 10, 4, 12, 4, 14, 4, 46, - 11, 4, 3, 5, 3, 5, 3, 5, 7, 5, 51, 10, 5, 12, 5, 14, 5, 54, 11, 5, 3, 6, - 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 7, 6, 62, 10, 6, 12, 6, 14, 6, 65, 11, 6, - 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 76, 10, 7, - 12, 7, 14, 7, 79, 11, 7, 3, 8, 3, 8, 6, 8, 83, 10, 8, 13, 8, 14, 8, 84, - 3, 8, 3, 8, 6, 8, 89, 10, 8, 13, 8, 14, 8, 90, 3, 8, 5, 8, 94, 10, 8, 3, - 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 104, 10, 9, 3, 9, 5, - 9, 107, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 117, - 10, 9, 3, 9, 5, 9, 120, 10, 9, 3, 9, 7, 9, 123, 10, 9, 12, 9, 14, 9, 126, - 11, 9, 3, 10, 5, 10, 129, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 134, 10, - 10, 3, 10, 5, 10, 137, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, - 5, 10, 145, 10, 10, 3, 10, 5, 10, 148, 10, 10, 3, 10, 3, 10, 3, 10, 5, - 10, 153, 10, 10, 3, 10, 5, 10, 156, 10, 10, 3, 10, 3, 10, 5, 10, 160, 10, - 10, 3, 11, 3, 11, 3, 11, 7, 11, 165, 10, 11, 12, 11, 14, 11, 168, 11, 11, - 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 177, 10, 12, 12, - 12, 14, 12, 180, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, - 3, 13, 7, 13, 190, 10, 13, 12, 13, 14, 13, 193, 11, 13, 3, 14, 5, 14, 196, - 10, 14, 3, 14, 3, 14, 3, 14, 5, 14, 201, 10, 14, 3, 14, 3, 14, 3, 14, 3, - 14, 3, 14, 3, 14, 5, 14, 209, 10, 14, 3, 14, 2, 5, 10, 12, 16, 15, 2, 4, - 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 2, 5, 3, 2, 3, 9, 3, 2, 25, 27, - 4, 2, 20, 20, 24, 24, 2, 237, 2, 28, 3, 2, 2, 2, 4, 31, 3, 2, 2, 2, 6, - 39, 3, 2, 2, 2, 8, 47, 3, 2, 2, 2, 10, 55, 3, 2, 2, 2, 12, 66, 3, 2, 2, - 2, 14, 93, 3, 2, 2, 2, 16, 95, 3, 2, 2, 2, 18, 159, 3, 2, 2, 2, 20, 161, - 3, 2, 2, 2, 22, 169, 3, 2, 2, 2, 24, 181, 3, 2, 2, 2, 26, 208, 3, 2, 2, - 2, 28, 29, 5, 4, 3, 2, 29, 30, 7, 2, 2, 3, 30, 3, 3, 2, 2, 2, 31, 37, 5, - 6, 4, 2, 32, 33, 7, 22, 2, 2, 33, 34, 5, 6, 4, 2, 34, 35, 7, 23, 2, 2, - 35, 36, 5, 4, 3, 2, 36, 38, 3, 2, 2, 2, 37, 32, 3, 2, 2, 2, 37, 38, 3, - 2, 2, 2, 38, 5, 3, 2, 2, 2, 39, 44, 5, 8, 5, 2, 40, 41, 7, 11, 2, 2, 41, - 43, 5, 8, 5, 2, 42, 40, 3, 2, 2, 2, 43, 46, 3, 2, 2, 2, 44, 42, 3, 2, 2, - 2, 44, 45, 3, 2, 2, 2, 45, 7, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 47, 52, 5, - 10, 6, 2, 48, 49, 7, 10, 2, 2, 49, 51, 5, 10, 6, 2, 50, 48, 3, 2, 2, 2, - 51, 54, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 52, 53, 3, 2, 2, 2, 53, 9, 3, 2, - 2, 2, 54, 52, 3, 2, 2, 2, 55, 56, 8, 6, 1, 2, 56, 57, 5, 12, 7, 2, 57, - 63, 3, 2, 2, 2, 58, 59, 12, 3, 2, 2, 59, 60, 9, 2, 2, 2, 60, 62, 5, 10, - 6, 4, 61, 58, 3, 2, 2, 2, 62, 65, 3, 2, 2, 2, 63, 61, 3, 2, 2, 2, 63, 64, - 3, 2, 2, 2, 64, 11, 3, 2, 2, 2, 65, 63, 3, 2, 2, 2, 66, 67, 8, 7, 1, 2, - 67, 68, 5, 14, 8, 2, 68, 77, 3, 2, 2, 2, 69, 70, 12, 4, 2, 2, 70, 71, 9, - 3, 2, 2, 71, 76, 5, 12, 7, 5, 72, 73, 12, 3, 2, 2, 73, 74, 9, 4, 2, 2, - 74, 76, 5, 12, 7, 4, 75, 69, 3, 2, 2, 2, 75, 72, 3, 2, 2, 2, 76, 79, 3, - 2, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 13, 3, 2, 2, 2, 79, - 77, 3, 2, 2, 2, 80, 94, 5, 16, 9, 2, 81, 83, 7, 21, 2, 2, 82, 81, 3, 2, - 2, 2, 83, 84, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 85, 3, 2, 2, 2, 85, 86, - 3, 2, 2, 2, 86, 94, 5, 16, 9, 2, 87, 89, 7, 20, 2, 2, 88, 87, 3, 2, 2, - 2, 89, 90, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 92, - 3, 2, 2, 2, 92, 94, 5, 16, 9, 2, 93, 80, 3, 2, 2, 2, 93, 82, 3, 2, 2, 2, - 93, 88, 3, 2, 2, 2, 94, 15, 3, 2, 2, 2, 95, 96, 8, 9, 1, 2, 96, 97, 5, - 18, 10, 2, 97, 124, 3, 2, 2, 2, 98, 99, 12, 5, 2, 2, 99, 100, 7, 18, 2, - 2, 100, 106, 7, 38, 2, 2, 101, 103, 7, 16, 2, 2, 102, 104, 5, 20, 11, 2, - 103, 102, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 105, 3, 2, 2, 2, 105, - 107, 7, 17, 2, 2, 106, 101, 3, 2, 2, 2, 106, 107, 3, 2, 2, 2, 107, 123, - 3, 2, 2, 2, 108, 109, 12, 4, 2, 2, 109, 110, 7, 12, 2, 2, 110, 111, 5, - 4, 3, 2, 111, 112, 7, 13, 2, 2, 112, 123, 3, 2, 2, 2, 113, 114, 12, 3, - 2, 2, 114, 116, 7, 14, 2, 2, 115, 117, 5, 22, 12, 2, 116, 115, 3, 2, 2, - 2, 116, 117, 3, 2, 2, 2, 117, 119, 3, 2, 2, 2, 118, 120, 7, 19, 2, 2, 119, - 118, 3, 2, 2, 2, 119, 120, 3, 2, 2, 2, 120, 121, 3, 2, 2, 2, 121, 123, - 7, 15, 2, 2, 122, 98, 3, 2, 2, 2, 122, 108, 3, 2, 2, 2, 122, 113, 3, 2, - 2, 2, 123, 126, 3, 2, 2, 2, 124, 122, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, - 125, 17, 3, 2, 2, 2, 126, 124, 3, 2, 2, 2, 127, 129, 7, 18, 2, 2, 128, - 127, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 130, 3, 2, 2, 2, 130, 136, - 7, 38, 2, 2, 131, 133, 7, 16, 2, 2, 132, 134, 5, 20, 11, 2, 133, 132, 3, - 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 137, 7, 17, 2, - 2, 136, 131, 3, 2, 2, 2, 136, 137, 3, 2, 2, 2, 137, 160, 3, 2, 2, 2, 138, - 139, 7, 16, 2, 2, 139, 140, 5, 4, 3, 2, 140, 141, 7, 17, 2, 2, 141, 160, - 3, 2, 2, 2, 142, 144, 7, 12, 2, 2, 143, 145, 5, 20, 11, 2, 144, 143, 3, - 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 147, 3, 2, 2, 2, 146, 148, 7, 19, 2, - 2, 147, 146, 3, 2, 2, 2, 147, 148, 3, 2, 2, 2, 148, 149, 3, 2, 2, 2, 149, - 160, 7, 13, 2, 2, 150, 152, 7, 14, 2, 2, 151, 153, 5, 24, 13, 2, 152, 151, - 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 153, 155, 3, 2, 2, 2, 154, 156, 7, 19, - 2, 2, 155, 154, 3, 2, 2, 2, 155, 156, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, - 157, 160, 7, 15, 2, 2, 158, 160, 5, 26, 14, 2, 159, 128, 3, 2, 2, 2, 159, - 138, 3, 2, 2, 2, 159, 142, 3, 2, 2, 2, 159, 150, 3, 2, 2, 2, 159, 158, - 3, 2, 2, 2, 160, 19, 3, 2, 2, 2, 161, 166, 5, 4, 3, 2, 162, 163, 7, 19, - 2, 2, 163, 165, 5, 4, 3, 2, 164, 162, 3, 2, 2, 2, 165, 168, 3, 2, 2, 2, - 166, 164, 3, 2, 2, 2, 166, 167, 3, 2, 2, 2, 167, 21, 3, 2, 2, 2, 168, 166, - 3, 2, 2, 2, 169, 170, 7, 38, 2, 2, 170, 171, 7, 23, 2, 2, 171, 178, 5, - 4, 3, 2, 172, 173, 7, 19, 2, 2, 173, 174, 7, 38, 2, 2, 174, 175, 7, 23, - 2, 2, 175, 177, 5, 4, 3, 2, 176, 172, 3, 2, 2, 2, 177, 180, 3, 2, 2, 2, - 178, 176, 3, 2, 2, 2, 178, 179, 3, 2, 2, 2, 179, 23, 3, 2, 2, 2, 180, 178, - 3, 2, 2, 2, 181, 182, 5, 4, 3, 2, 182, 183, 7, 23, 2, 2, 183, 191, 5, 4, - 3, 2, 184, 185, 7, 19, 2, 2, 185, 186, 5, 4, 3, 2, 186, 187, 7, 23, 2, - 2, 187, 188, 5, 4, 3, 2, 188, 190, 3, 2, 2, 2, 189, 184, 3, 2, 2, 2, 190, - 193, 3, 2, 2, 2, 191, 189, 3, 2, 2, 2, 191, 192, 3, 2, 2, 2, 192, 25, 3, - 2, 2, 2, 193, 191, 3, 2, 2, 2, 194, 196, 7, 20, 2, 2, 195, 194, 3, 2, 2, - 2, 195, 196, 3, 2, 2, 2, 196, 197, 3, 2, 2, 2, 197, 209, 7, 34, 2, 2, 198, - 209, 7, 35, 2, 2, 199, 201, 7, 20, 2, 2, 200, 199, 3, 2, 2, 2, 200, 201, - 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 209, 7, 33, 2, 2, 203, 209, 7, 36, - 2, 2, 204, 209, 7, 37, 2, 2, 205, 209, 7, 28, 2, 2, 206, 209, 7, 29, 2, - 2, 207, 209, 7, 30, 2, 2, 208, 195, 3, 2, 2, 2, 208, 198, 3, 2, 2, 2, 208, - 200, 3, 2, 2, 2, 208, 203, 3, 2, 2, 2, 208, 204, 3, 2, 2, 2, 208, 205, - 3, 2, 2, 2, 208, 206, 3, 2, 2, 2, 208, 207, 3, 2, 2, 2, 209, 27, 3, 2, - 2, 2, 31, 37, 44, 52, 63, 75, 77, 84, 90, 93, 103, 106, 116, 119, 122, - 124, 128, 133, 136, 144, 147, 152, 155, 159, 166, 178, 191, 195, 200, 208, -} -var literalNames = []string{ - "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", - "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", "'?'", - "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", -} -var symbolicNames = []string{ - "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", - "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", - "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", - "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", "NUL", - "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", "STRING", - "BYTES", "IDENTIFIER", -} - -var ruleNames = []string{ - "start", "expr", "conditionalOr", "conditionalAnd", "relation", "calc", - "unary", "member", "primary", "exprList", "fieldInitializerList", "mapInitializerList", - "literal", -} +var _ = sync.Once{} type CELParser struct { *antlr.BaseParser } +var celParserStaticData struct { + once sync.Once + serializedATN []int32 + literalNames []string + symbolicNames []string + ruleNames []string + predictionContextCache *antlr.PredictionContextCache + atn *antlr.ATN + decisionToDFA []*antlr.DFA +} + +func celParserInit() { + staticData := &celParserStaticData + staticData.literalNames = []string{ + "", "'=='", "'!='", "'in'", "'<'", "'<='", "'>='", "'>'", "'&&'", "'||'", + "'['", "']'", "'{'", "'}'", "'('", "')'", "'.'", "','", "'-'", "'!'", + "'?'", "':'", "'+'", "'*'", "'/'", "'%'", "'true'", "'false'", "'null'", + } + staticData.symbolicNames = []string{ + "", "EQUALS", "NOT_EQUALS", "IN", "LESS", "LESS_EQUALS", "GREATER_EQUALS", + "GREATER", "LOGICAL_AND", "LOGICAL_OR", "LBRACKET", "RPRACKET", "LBRACE", + "RBRACE", "LPAREN", "RPAREN", "DOT", "COMMA", "MINUS", "EXCLAM", "QUESTIONMARK", + "COLON", "PLUS", "STAR", "SLASH", "PERCENT", "CEL_TRUE", "CEL_FALSE", + "NUL", "WHITESPACE", "COMMENT", "NUM_FLOAT", "NUM_INT", "NUM_UINT", + "STRING", "BYTES", "IDENTIFIER", + } + staticData.ruleNames = []string{ + "start", "expr", "conditionalOr", "conditionalAnd", "relation", "calc", + "unary", "member", "primary", "exprList", "fieldInitializerList", "mapInitializerList", + "literal", + } + staticData.predictionContextCache = antlr.NewPredictionContextCache() + staticData.serializedATN = []int32{ + 4, 1, 36, 209, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, + 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, + 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 36, 8, 1, 1, 2, 1, 2, 1, 2, 5, 2, 41, 8, 2, 10, 2, + 12, 2, 44, 9, 2, 1, 3, 1, 3, 1, 3, 5, 3, 49, 8, 3, 10, 3, 12, 3, 52, 9, + 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 60, 8, 4, 10, 4, 12, 4, 63, + 9, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 74, 8, + 5, 10, 5, 12, 5, 77, 9, 5, 1, 6, 1, 6, 4, 6, 81, 8, 6, 11, 6, 12, 6, 82, + 1, 6, 1, 6, 4, 6, 87, 8, 6, 11, 6, 12, 6, 88, 1, 6, 3, 6, 92, 8, 6, 1, + 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 102, 8, 7, 1, 7, 3, + 7, 105, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 115, + 8, 7, 1, 7, 3, 7, 118, 8, 7, 1, 7, 5, 7, 121, 8, 7, 10, 7, 12, 7, 124, + 9, 7, 1, 8, 3, 8, 127, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 132, 8, 8, 1, 8, 3, + 8, 135, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 143, 8, 8, 1, 8, + 3, 8, 146, 8, 8, 1, 8, 1, 8, 1, 8, 3, 8, 151, 8, 8, 1, 8, 3, 8, 154, 8, + 8, 1, 8, 1, 8, 3, 8, 158, 8, 8, 1, 9, 1, 9, 1, 9, 5, 9, 163, 8, 9, 10, + 9, 12, 9, 166, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, + 10, 175, 8, 10, 10, 10, 12, 10, 178, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, + 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 188, 8, 11, 10, 11, 12, 11, 191, 9, + 11, 1, 12, 3, 12, 194, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 199, 8, 12, 1, + 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 207, 8, 12, 1, 12, 0, 3, + 8, 10, 14, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 3, 1, + 0, 1, 7, 1, 0, 23, 25, 2, 0, 18, 18, 22, 22, 235, 0, 26, 1, 0, 0, 0, 2, + 29, 1, 0, 0, 0, 4, 37, 1, 0, 0, 0, 6, 45, 1, 0, 0, 0, 8, 53, 1, 0, 0, 0, + 10, 64, 1, 0, 0, 0, 12, 91, 1, 0, 0, 0, 14, 93, 1, 0, 0, 0, 16, 157, 1, + 0, 0, 0, 18, 159, 1, 0, 0, 0, 20, 167, 1, 0, 0, 0, 22, 179, 1, 0, 0, 0, + 24, 206, 1, 0, 0, 0, 26, 27, 3, 2, 1, 0, 27, 28, 5, 0, 0, 1, 28, 1, 1, + 0, 0, 0, 29, 35, 3, 4, 2, 0, 30, 31, 5, 20, 0, 0, 31, 32, 3, 4, 2, 0, 32, + 33, 5, 21, 0, 0, 33, 34, 3, 2, 1, 0, 34, 36, 1, 0, 0, 0, 35, 30, 1, 0, + 0, 0, 35, 36, 1, 0, 0, 0, 36, 3, 1, 0, 0, 0, 37, 42, 3, 6, 3, 0, 38, 39, + 5, 9, 0, 0, 39, 41, 3, 6, 3, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, + 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 42, 1, 0, + 0, 0, 45, 50, 3, 8, 4, 0, 46, 47, 5, 8, 0, 0, 47, 49, 3, 8, 4, 0, 48, 46, + 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0, + 51, 7, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 6, 4, -1, 0, 54, 55, 3, + 10, 5, 0, 55, 61, 1, 0, 0, 0, 56, 57, 10, 1, 0, 0, 57, 58, 7, 0, 0, 0, + 58, 60, 3, 8, 4, 2, 59, 56, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1, + 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 9, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, + 65, 6, 5, -1, 0, 65, 66, 3, 12, 6, 0, 66, 75, 1, 0, 0, 0, 67, 68, 10, 2, + 0, 0, 68, 69, 7, 1, 0, 0, 69, 74, 3, 10, 5, 3, 70, 71, 10, 1, 0, 0, 71, + 72, 7, 2, 0, 0, 72, 74, 3, 10, 5, 2, 73, 67, 1, 0, 0, 0, 73, 70, 1, 0, + 0, 0, 74, 77, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 11, + 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 78, 92, 3, 14, 7, 0, 79, 81, 5, 19, 0, + 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, + 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 92, 3, 14, 7, 0, 85, 87, 5, 18, 0, + 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, + 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 92, 3, 14, 7, 0, 91, 78, 1, 0, 0, 0, + 91, 80, 1, 0, 0, 0, 91, 86, 1, 0, 0, 0, 92, 13, 1, 0, 0, 0, 93, 94, 6, + 7, -1, 0, 94, 95, 3, 16, 8, 0, 95, 122, 1, 0, 0, 0, 96, 97, 10, 3, 0, 0, + 97, 98, 5, 16, 0, 0, 98, 104, 5, 36, 0, 0, 99, 101, 5, 14, 0, 0, 100, 102, + 3, 18, 9, 0, 101, 100, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 103, 1, 0, + 0, 0, 103, 105, 5, 15, 0, 0, 104, 99, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, + 105, 121, 1, 0, 0, 0, 106, 107, 10, 2, 0, 0, 107, 108, 5, 10, 0, 0, 108, + 109, 3, 2, 1, 0, 109, 110, 5, 11, 0, 0, 110, 121, 1, 0, 0, 0, 111, 112, + 10, 1, 0, 0, 112, 114, 5, 12, 0, 0, 113, 115, 3, 20, 10, 0, 114, 113, 1, + 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 117, 1, 0, 0, 0, 116, 118, 5, 17, 0, + 0, 117, 116, 1, 0, 0, 0, 117, 118, 1, 0, 0, 0, 118, 119, 1, 0, 0, 0, 119, + 121, 5, 13, 0, 0, 120, 96, 1, 0, 0, 0, 120, 106, 1, 0, 0, 0, 120, 111, + 1, 0, 0, 0, 121, 124, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 122, 123, 1, 0, + 0, 0, 123, 15, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127, 5, 16, 0, 0, + 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 128, 1, 0, 0, 0, 128, + 134, 5, 36, 0, 0, 129, 131, 5, 14, 0, 0, 130, 132, 3, 18, 9, 0, 131, 130, + 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 135, 5, 15, + 0, 0, 134, 129, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 158, 1, 0, 0, 0, + 136, 137, 5, 14, 0, 0, 137, 138, 3, 2, 1, 0, 138, 139, 5, 15, 0, 0, 139, + 158, 1, 0, 0, 0, 140, 142, 5, 10, 0, 0, 141, 143, 3, 18, 9, 0, 142, 141, + 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143, 145, 1, 0, 0, 0, 144, 146, 5, 17, + 0, 0, 145, 144, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, + 147, 158, 5, 11, 0, 0, 148, 150, 5, 12, 0, 0, 149, 151, 3, 22, 11, 0, 150, + 149, 1, 0, 0, 0, 150, 151, 1, 0, 0, 0, 151, 153, 1, 0, 0, 0, 152, 154, + 5, 17, 0, 0, 153, 152, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 1, 0, + 0, 0, 155, 158, 5, 13, 0, 0, 156, 158, 3, 24, 12, 0, 157, 126, 1, 0, 0, + 0, 157, 136, 1, 0, 0, 0, 157, 140, 1, 0, 0, 0, 157, 148, 1, 0, 0, 0, 157, + 156, 1, 0, 0, 0, 158, 17, 1, 0, 0, 0, 159, 164, 3, 2, 1, 0, 160, 161, 5, + 17, 0, 0, 161, 163, 3, 2, 1, 0, 162, 160, 1, 0, 0, 0, 163, 166, 1, 0, 0, + 0, 164, 162, 1, 0, 0, 0, 164, 165, 1, 0, 0, 0, 165, 19, 1, 0, 0, 0, 166, + 164, 1, 0, 0, 0, 167, 168, 5, 36, 0, 0, 168, 169, 5, 21, 0, 0, 169, 176, + 3, 2, 1, 0, 170, 171, 5, 17, 0, 0, 171, 172, 5, 36, 0, 0, 172, 173, 5, + 21, 0, 0, 173, 175, 3, 2, 1, 0, 174, 170, 1, 0, 0, 0, 175, 178, 1, 0, 0, + 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 21, 1, 0, 0, 0, 178, + 176, 1, 0, 0, 0, 179, 180, 3, 2, 1, 0, 180, 181, 5, 21, 0, 0, 181, 189, + 3, 2, 1, 0, 182, 183, 5, 17, 0, 0, 183, 184, 3, 2, 1, 0, 184, 185, 5, 21, + 0, 0, 185, 186, 3, 2, 1, 0, 186, 188, 1, 0, 0, 0, 187, 182, 1, 0, 0, 0, + 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, + 23, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 194, 5, 18, 0, 0, 193, 192, + 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 207, 5, 32, + 0, 0, 196, 207, 5, 33, 0, 0, 197, 199, 5, 18, 0, 0, 198, 197, 1, 0, 0, + 0, 198, 199, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 207, 5, 31, 0, 0, 201, + 207, 5, 34, 0, 0, 202, 207, 5, 35, 0, 0, 203, 207, 5, 26, 0, 0, 204, 207, + 5, 27, 0, 0, 205, 207, 5, 28, 0, 0, 206, 193, 1, 0, 0, 0, 206, 196, 1, + 0, 0, 0, 206, 198, 1, 0, 0, 0, 206, 201, 1, 0, 0, 0, 206, 202, 1, 0, 0, + 0, 206, 203, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 205, 1, 0, 0, 0, 207, + 25, 1, 0, 0, 0, 29, 35, 42, 50, 61, 73, 75, 82, 88, 91, 101, 104, 114, + 117, 120, 122, 126, 131, 134, 142, 145, 150, 153, 157, 164, 176, 189, 193, + 198, 206, + } + deserializer := antlr.NewATNDeserializer(nil) + staticData.atn = deserializer.Deserialize(staticData.serializedATN) + atn := staticData.atn + staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState)) + decisionToDFA := staticData.decisionToDFA + for index, state := range atn.DecisionToState { + decisionToDFA[index] = antlr.NewDFA(state, index) + } +} + +// CELParserInit initializes any static state used to implement CELParser. By default the +// static state used to implement the parser is lazily initialized during the first call to +// NewCELParser(). You can call this function if you wish to initialize the static state ahead +// of time. +func CELParserInit() { + staticData := &celParserStaticData + staticData.once.Do(celParserInit) +} + // NewCELParser produces a new parser instance for the optional input antlr.TokenStream. -// -// The *CELParser instance produced may be reused by calling the SetInputStream method. -// The initial parser configuration is expensive to construct, and the object is not thread-safe; -// however, if used within a Golang sync.Pool, the construction cost amortizes well and the -// objects can be used in a thread-safe manner. func NewCELParser(input antlr.TokenStream) *CELParser { + CELParserInit() this := new(CELParser) - deserializer := antlr.NewATNDeserializer(nil) - deserializedATN := deserializer.DeserializeFromUInt16(parserATN) - decisionToDFA := make([]*antlr.DFA, len(deserializedATN.DecisionToState)) - for index, ds := range deserializedATN.DecisionToState { - decisionToDFA[index] = antlr.NewDFA(ds, index) - } this.BaseParser = antlr.NewBaseParser(input) - - this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) - this.RuleNames = ruleNames - this.LiteralNames = literalNames - this.SymbolicNames = symbolicNames + staticData := &celParserStaticData + this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.predictionContextCache) + this.RuleNames = staticData.ruleNames + this.LiteralNames = staticData.literalNames + this.SymbolicNames = staticData.symbolicNames this.GrammarFileName = "CEL.g4" return this @@ -273,7 +293,13 @@ func (s *StartContext) EOF() antlr.TerminalNode { } func (s *StartContext) Expr() IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -313,6 +339,9 @@ func (s *StartContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *CELParser) Start() (localctx IStartContext) { + this := p + _ = this + localctx = NewStartContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 0, CELParserRULE_start) @@ -431,12 +460,20 @@ func (s *ExprContext) SetE1(v IConditionalOrContext) { s.e1 = v } func (s *ExprContext) SetE2(v IExprContext) { s.e2 = v } func (s *ExprContext) AllConditionalOr() []IConditionalOrContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IConditionalOrContext)(nil)).Elem()) - var tst = make([]IConditionalOrContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IConditionalOrContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IConditionalOrContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IConditionalOrContext); ok { tst[i] = t.(IConditionalOrContext) + i++ } } @@ -444,7 +481,17 @@ func (s *ExprContext) AllConditionalOr() []IConditionalOrContext { } func (s *ExprContext) ConditionalOr(i int) IConditionalOrContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IConditionalOrContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IConditionalOrContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -462,7 +509,13 @@ func (s *ExprContext) QUESTIONMARK() antlr.TerminalNode { } func (s *ExprContext) Expr() IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -502,6 +555,9 @@ func (s *ExprContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *CELParser) Expr() (localctx IExprContext) { + this := p + _ = this + localctx = NewExprContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 2, CELParserRULE_expr) var _la int @@ -660,12 +716,20 @@ func (s *ConditionalOrContext) GetE1() []IConditionalAndContext { return s.e1 } func (s *ConditionalOrContext) SetE1(v []IConditionalAndContext) { s.e1 = v } func (s *ConditionalOrContext) AllConditionalAnd() []IConditionalAndContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IConditionalAndContext)(nil)).Elem()) - var tst = make([]IConditionalAndContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IConditionalAndContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IConditionalAndContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IConditionalAndContext); ok { tst[i] = t.(IConditionalAndContext) + i++ } } @@ -673,7 +737,17 @@ func (s *ConditionalOrContext) AllConditionalAnd() []IConditionalAndContext { } func (s *ConditionalOrContext) ConditionalAnd(i int) IConditionalAndContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IConditionalAndContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IConditionalAndContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -721,6 +795,9 @@ func (s *ConditionalOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{ } func (p *CELParser) ConditionalOr() (localctx IConditionalOrContext) { + this := p + _ = this + localctx = NewConditionalOrContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 4, CELParserRULE_conditionalOr) var _la int @@ -873,12 +950,20 @@ func (s *ConditionalAndContext) GetE1() []IRelationContext { return s.e1 } func (s *ConditionalAndContext) SetE1(v []IRelationContext) { s.e1 = v } func (s *ConditionalAndContext) AllRelation() []IRelationContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IRelationContext)(nil)).Elem()) - var tst = make([]IRelationContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IRelationContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IRelationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IRelationContext); ok { tst[i] = t.(IRelationContext) + i++ } } @@ -886,7 +971,17 @@ func (s *ConditionalAndContext) AllRelation() []IRelationContext { } func (s *ConditionalAndContext) Relation(i int) IRelationContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IRelationContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -934,6 +1029,9 @@ func (s *ConditionalAndContext) Accept(visitor antlr.ParseTreeVisitor) interface } func (p *CELParser) ConditionalAnd() (localctx IConditionalAndContext) { + this := p + _ = this + localctx = NewConditionalAndContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 6, CELParserRULE_conditionalAnd) var _la int @@ -1042,7 +1140,13 @@ func (s *RelationContext) GetOp() antlr.Token { return s.op } func (s *RelationContext) SetOp(v antlr.Token) { s.op = v } func (s *RelationContext) Calc() ICalcContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ICalcContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICalcContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1052,12 +1156,20 @@ func (s *RelationContext) Calc() ICalcContext { } func (s *RelationContext) AllRelation() []IRelationContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IRelationContext)(nil)).Elem()) - var tst = make([]IRelationContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IRelationContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IRelationContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IRelationContext); ok { tst[i] = t.(IRelationContext) + i++ } } @@ -1065,7 +1177,17 @@ func (s *RelationContext) AllRelation() []IRelationContext { } func (s *RelationContext) Relation(i int) IRelationContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IRelationContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IRelationContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -1137,6 +1259,9 @@ func (p *CELParser) Relation() (localctx IRelationContext) { } func (p *CELParser) relation(_p int) (localctx IRelationContext) { + this := p + _ = this + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() _parentState := p.GetState() localctx = NewRelationContext(p, p.GetParserRuleContext(), _parentState) @@ -1270,7 +1395,13 @@ func (s *CalcContext) GetOp() antlr.Token { return s.op } func (s *CalcContext) SetOp(v antlr.Token) { s.op = v } func (s *CalcContext) Unary() IUnaryContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IUnaryContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IUnaryContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1280,12 +1411,20 @@ func (s *CalcContext) Unary() IUnaryContext { } func (s *CalcContext) AllCalc() []ICalcContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ICalcContext)(nil)).Elem()) - var tst = make([]ICalcContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(ICalcContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]ICalcContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(ICalcContext); ok { tst[i] = t.(ICalcContext) + i++ } } @@ -1293,7 +1432,17 @@ func (s *CalcContext) AllCalc() []ICalcContext { } func (s *CalcContext) Calc(i int) ICalcContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ICalcContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ICalcContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -1357,6 +1506,9 @@ func (p *CELParser) Calc() (localctx ICalcContext) { } func (p *CELParser) calc(_p int) (localctx ICalcContext) { + this := p + _ = this + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() _parentState := p.GetState() localctx = NewCalcContext(p, p.GetParserRuleContext(), _parentState) @@ -1556,7 +1708,13 @@ func (s *LogicalNotContext) GetRuleContext() antlr.RuleContext { } func (s *LogicalNotContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1614,7 +1772,13 @@ func (s *MemberExprContext) GetRuleContext() antlr.RuleContext { } func (s *MemberExprContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1674,7 +1838,13 @@ func (s *NegateContext) GetRuleContext() antlr.RuleContext { } func (s *NegateContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1714,6 +1884,9 @@ func (s *NegateContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *CELParser) Unary() (localctx IUnaryContext) { + this := p + _ = this + localctx = NewUnaryContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 12, CELParserRULE_unary) var _la int @@ -1898,7 +2071,13 @@ func (s *SelectOrCallContext) GetRuleContext() antlr.RuleContext { } func (s *SelectOrCallContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1924,7 +2103,13 @@ func (s *SelectOrCallContext) LPAREN() antlr.TerminalNode { } func (s *SelectOrCallContext) ExprList() IExprListContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprListContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -1974,7 +2159,13 @@ func (s *PrimaryExprContext) GetRuleContext() antlr.RuleContext { } func (s *PrimaryExprContext) Primary() IPrimaryContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IPrimaryContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IPrimaryContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2034,7 +2225,13 @@ func (s *IndexContext) GetRuleContext() antlr.RuleContext { } func (s *IndexContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2052,7 +2249,13 @@ func (s *IndexContext) LBRACKET() antlr.TerminalNode { } func (s *IndexContext) Expr() IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2112,7 +2315,13 @@ func (s *CreateMessageContext) GetRuleContext() antlr.RuleContext { } func (s *CreateMessageContext) Member() IMemberContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMemberContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMemberContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2134,7 +2343,13 @@ func (s *CreateMessageContext) COMMA() antlr.TerminalNode { } func (s *CreateMessageContext) FieldInitializerList() IFieldInitializerListContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IFieldInitializerListContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IFieldInitializerListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2170,6 +2385,9 @@ func (p *CELParser) Member() (localctx IMemberContext) { } func (p *CELParser) member(_p int) (localctx IMemberContext) { + this := p + _ = this + var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() _parentState := p.GetState() localctx = NewMemberContext(p, p.GetParserRuleContext(), _parentState) @@ -2449,7 +2667,13 @@ func (s *CreateListContext) COMMA() antlr.TerminalNode { } func (s *CreateListContext) ExprList() IExprListContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprListContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2521,7 +2745,13 @@ func (s *CreateStructContext) COMMA() antlr.TerminalNode { } func (s *CreateStructContext) MapInitializerList() IMapInitializerListContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMapInitializerListContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IMapInitializerListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2571,7 +2801,13 @@ func (s *ConstantLiteralContext) GetRuleContext() antlr.RuleContext { } func (s *ConstantLiteralContext) Literal() ILiteralContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ILiteralContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ILiteralContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2634,7 +2870,13 @@ func (s *NestedContext) RPAREN() antlr.TerminalNode { } func (s *NestedContext) Expr() IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2720,7 +2962,13 @@ func (s *IdentOrGlobalCallContext) LPAREN() antlr.TerminalNode { } func (s *IdentOrGlobalCallContext) ExprList() IExprListContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprListContext)(nil)).Elem(), 0) + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprListContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } if t == nil { return nil @@ -2752,6 +3000,9 @@ func (s *IdentOrGlobalCallContext) Accept(visitor antlr.ParseTreeVisitor) interf } func (p *CELParser) Primary() (localctx IPrimaryContext) { + this := p + _ = this + localctx = NewPrimaryContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 16, CELParserRULE_primary) var _la int @@ -3007,12 +3258,20 @@ func (s *ExprListContext) GetE() []IExprContext { return s.e } func (s *ExprListContext) SetE(v []IExprContext) { s.e = v } func (s *ExprListContext) AllExpr() []IExprContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExprContext)(nil)).Elem()) - var tst = make([]IExprContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { tst[i] = t.(IExprContext) + i++ } } @@ -3020,7 +3279,17 @@ func (s *ExprListContext) AllExpr() []IExprContext { } func (s *ExprListContext) Expr(i int) IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -3068,6 +3337,9 @@ func (s *ExprListContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *CELParser) ExprList() (localctx IExprListContext) { + this := p + _ = this + localctx = NewExprListContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 18, CELParserRULE_exprList) @@ -3247,12 +3519,20 @@ func (s *FieldInitializerListContext) COLON(i int) antlr.TerminalNode { } func (s *FieldInitializerListContext) AllExpr() []IExprContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExprContext)(nil)).Elem()) - var tst = make([]IExprContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { tst[i] = t.(IExprContext) + i++ } } @@ -3260,7 +3540,17 @@ func (s *FieldInitializerListContext) AllExpr() []IExprContext { } func (s *FieldInitializerListContext) Expr(i int) IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -3308,6 +3598,9 @@ func (s *FieldInitializerListContext) Accept(visitor antlr.ParseTreeVisitor) int } func (p *CELParser) FieldInitializerList() (localctx IFieldInitializerListContext) { + this := p + _ = this + localctx = NewFieldInitializerListContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 20, CELParserRULE_fieldInitializerList) @@ -3492,12 +3785,20 @@ func (s *MapInitializerListContext) SetKeys(v []IExprContext) { s.keys = v } func (s *MapInitializerListContext) SetValues(v []IExprContext) { s.values = v } func (s *MapInitializerListContext) AllExpr() []IExprContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExprContext)(nil)).Elem()) - var tst = make([]IExprContext, len(ts)) + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } - for i, t := range ts { - if t != nil { + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { tst[i] = t.(IExprContext) + i++ } } @@ -3505,7 +3806,17 @@ func (s *MapInitializerListContext) AllExpr() []IExprContext { } func (s *MapInitializerListContext) Expr(i int) IExprContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), i) + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } if t == nil { return nil @@ -3561,6 +3872,9 @@ func (s *MapInitializerListContext) Accept(visitor antlr.ParseTreeVisitor) inter } func (p *CELParser) MapInitializerList() (localctx IMapInitializerListContext) { + this := p + _ = this + localctx = NewMapInitializerListContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 22, CELParserRULE_mapInitializerList) @@ -4112,6 +4426,9 @@ func (s *IntContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } func (p *CELParser) Literal() (localctx ILiteralContext) { + this := p + _ = this + localctx = NewLiteralContext(p, p.GetParserRuleContext(), p.GetState()) p.EnterRule(localctx, 24, CELParserRULE_literal) var _la int @@ -4285,6 +4602,9 @@ func (p *CELParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int } func (p *CELParser) Relation_Sempred(localctx antlr.RuleContext, predIndex int) bool { + this := p + _ = this + switch predIndex { case 0: return p.Precpred(p.GetParserRuleContext(), 1) @@ -4295,6 +4615,9 @@ func (p *CELParser) Relation_Sempred(localctx antlr.RuleContext, predIndex int) } func (p *CELParser) Calc_Sempred(localctx antlr.RuleContext, predIndex int) bool { + this := p + _ = this + switch predIndex { case 1: return p.Precpred(p.GetParserRuleContext(), 2) @@ -4308,6 +4631,9 @@ func (p *CELParser) Calc_Sempred(localctx antlr.RuleContext, predIndex int) bool } func (p *CELParser) Member_Sempred(localctx antlr.RuleContext, predIndex int) bool { + this := p + _ = this + switch predIndex { case 3: return p.Precpred(p.GetParserRuleContext(), 3) diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_visitor.go b/vendor/github.com/google/cel-go/parser/gen/cel_visitor.go index 8195d0fb31a..142675699bf 100644 --- a/vendor/github.com/google/cel-go/parser/gen/cel_visitor.go +++ b/vendor/github.com/google/cel-go/parser/gen/cel_visitor.go @@ -1,4 +1,4 @@ -// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/bin/../parser/gen/CEL.g4 by ANTLR 4.9.1. DO NOT EDIT. +// Code generated from /Users/tswadell/go/src/github.com/google/cel-go/parser/gen/CEL.g4 by ANTLR 4.10.1. DO NOT EDIT. package gen // CEL import "github.com/antlr/antlr4/runtime/Go/antlr" diff --git a/vendor/github.com/google/cel-go/parser/gen/generate.sh b/vendor/github.com/google/cel-go/parser/gen/generate.sh new file mode 100644 index 00000000000..3fcecf9eb02 --- /dev/null +++ b/vendor/github.com/google/cel-go/parser/gen/generate.sh @@ -0,0 +1,35 @@ +#!/bin/bash -eu +# +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# To regenerate the CEL lexer/parser statically do the following: +# 1. Download the latest anltr tool from https://www.antlr.org/download.html +# 2. Copy the downloaded jar to the gen directory. It will have a name +# like antlr--complete.jar. +# 3. Modify the script below to refer to the current ANTLR version. +# 4. Execute the generation script from the gen directory. +# 5. Delete the jar and commit the regenerated sources. + +#!/bin/sh + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Generate AntLR artifacts. +java -Xmx500M -cp ${DIR}/antlr-4.10.1-complete.jar org.antlr.v4.Tool \ + -Dlanguage=Go \ + -package gen \ + -o ${DIR} \ + -visitor ${DIR}/CEL.g4 + diff --git a/vendor/github.com/google/cel-go/parser/helper.go b/vendor/github.com/google/cel-go/parser/helper.go index 56cd1946921..be41339e3f2 100644 --- a/vendor/github.com/google/cel-go/parser/helper.go +++ b/vendor/github.com/google/cel-go/parser/helper.go @@ -217,7 +217,7 @@ func (p *parserHelper) buildMacroCallArg(expr *exprpb.Expr) *exprpb.Expr { return &exprpb.Expr{Id: expr.GetId()} } - switch expr.ExprKind.(type) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: // Iterate the AST from `expr` recursively looking for macros. Because we are at most // starting from the top level macro, this recursion is bounded by the size of the AST. This @@ -435,6 +435,11 @@ func (e *exprHelper) Ident(name string) *exprpb.Expr { return e.parserHelper.newIdent(e.nextMacroID(), name) } +// AccuIdent implements the ExprHelper interface method. +func (e *exprHelper) AccuIdent() *exprpb.Expr { + return e.parserHelper.newIdent(e.nextMacroID(), AccumulatorName) +} + // GlobalCall implements the ExprHelper interface method. func (e *exprHelper) GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr { return e.parserHelper.newGlobalCall(e.nextMacroID(), function, args...) diff --git a/vendor/github.com/google/cel-go/parser/macro.go b/vendor/github.com/google/cel-go/parser/macro.go index baeddd94ea7..9150b064e5f 100644 --- a/vendor/github.com/google/cel-go/parser/macro.go +++ b/vendor/github.com/google/cel-go/parser/macro.go @@ -23,8 +23,6 @@ import ( exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) -// TODO: Consider moving macros to common. - // NewGlobalMacro creates a Macro for a global function with the specified arg count. func NewGlobalMacro(function string, argCount int, expander MacroExpander) Macro { return ¯o{ @@ -50,8 +48,7 @@ func NewGlobalVarArgMacro(function string, expander MacroExpander) Macro { varArgStyle: true} } -// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg -// count. +// NewReceiverVarArgMacro creates a Macro for a receiver function matching a variable arg count. func NewReceiverVarArgMacro(function string, expander MacroExpander) Macro { return ¯o{ function: function, @@ -135,9 +132,13 @@ func makeVarArgMacroKey(name string, receiverStyle bool) string { return fmt.Sprintf("%s:*:%v", name, receiverStyle) } -// MacroExpander converts the target and args of a function call that matches a Macro. +// MacroExpander converts a call and its associated arguments into a new CEL abstract syntax tree, or an error +// if the input arguments are not suitable for the expansion requirements for the macro in question. +// +// The MacroExpander accepts as arguments a MacroExprHelper as well as the arguments used in the function call +// and produces as output an Expr ast node. // -// Note: when the Macros.IsReceiverStyle() is true, the target argument will be nil. +// Note: when the Macro.IsReceiverStyle() method returns true, the target argument will be nil. type MacroExpander func(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) @@ -208,6 +209,9 @@ type ExprHelper interface { // Ident creates an identifier Expr value. Ident(name string) *exprpb.Expr + // AccuIdent returns an accumulator identifier for use with comprehension results. + AccuIdent() *exprpb.Expr + // GlobalCall creates a function call Expr value for a global (free) function. GlobalCall(function string, args ...*exprpb.Expr) *exprpb.Expr @@ -225,34 +229,44 @@ type ExprHelper interface { } var ( - // AllMacros includes the list of all spec-supported macros. - AllMacros = []Macro{ - // The macro "has(m.f)" which tests the presence of a field, avoiding the need to specify - // the field as a string. - NewGlobalMacro(operators.Has, 1, makeHas), + // HasMacro expands "has(m.f)" which tests the presence of a field, avoiding the need to + // specify the field as a string. + HasMacro = NewGlobalMacro(operators.Has, 1, MakeHas) + + // AllMacro expands "range.all(var, predicate)" into a comprehension which ensures that all + // elements in the range satisfy the predicate. + AllMacro = NewReceiverMacro(operators.All, 2, MakeAll) - // The macro "range.all(var, predicate)", which is true if for all elements in range the - // predicate holds. - NewReceiverMacro(operators.All, 2, makeAll), + // ExistsMacro expands "range.exists(var, predicate)" into a comprehension which ensures that + // some element in the range satisfies the predicate. + ExistsMacro = NewReceiverMacro(operators.Exists, 2, MakeExists) - // The macro "range.exists(var, predicate)", which is true if for at least one element in - // range the predicate holds. - NewReceiverMacro(operators.Exists, 2, makeExists), + // ExistsOneMacro expands "range.exists_one(var, predicate)", which is true if for exactly one + // element in range the predicate holds. + ExistsOneMacro = NewReceiverMacro(operators.ExistsOne, 2, MakeExistsOne) - // The macro "range.exists_one(var, predicate)", which is true if for exactly one element - // in range the predicate holds. - NewReceiverMacro(operators.ExistsOne, 2, makeExistsOne), + // MapMacro expands "range.map(var, function)" into a comprehension which applies the function + // to each element in the range to produce a new list. + MapMacro = NewReceiverMacro(operators.Map, 2, MakeMap) - // The macro "range.map(var, function)", applies the function to the vars in the range. - NewReceiverMacro(operators.Map, 2, makeMap), + // MapFilterMacro expands "range.map(var, predicate, function)" into a comprehension which + // first filters the elements in the range by the predicate, then applies the transform function + // to produce a new list. + MapFilterMacro = NewReceiverMacro(operators.Map, 3, MakeMap) - // The macro "range.map(var, predicate, function)", applies the function to the vars in - // the range for which the predicate holds true. The other variables are filtered out. - NewReceiverMacro(operators.Map, 3, makeMap), + // FilterMacro expands "range.filter(var, predicate)" into a comprehension which filters + // elements in the range, producing a new list from the elements that satisfy the predicate. + FilterMacro = NewReceiverMacro(operators.Filter, 2, MakeFilter) - // The macro "range.filter(var, predicate)", filters out the variables for which the - // predicate is false. - NewReceiverMacro(operators.Filter, 2, makeFilter), + // AllMacros includes the list of all spec-supported macros. + AllMacros = []Macro{ + HasMacro, + AllMacro, + ExistsMacro, + ExistsOneMacro, + MapMacro, + MapFilterMacro, + FilterMacro, } // NoMacros list. @@ -270,62 +284,36 @@ const ( quantifierExistsOne ) -func makeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeAll expands the input call arguments into a comprehension that returns true if all of the +// elements in the range match the predicate expressions: +// .all(, ) +func MakeAll(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierAll, eh, target, args) } -func makeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeExists expands the input call arguments into a comprehension that returns true if any of the +// elements in the range match the predicate expressions: +// .exists(, ) +func MakeExists(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierExists, eh, target, args) } -func makeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeExistsOne expands the input call arguments into a comprehension that returns true if exactly +// one of the elements in the range match the predicate expressions: +// .exists_one(, ) +func MakeExistsOne(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { return makeQuantifier(quantifierExistsOne, eh, target, args) } -func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { - v, found := extractIdent(args[0]) - if !found { - location := eh.OffsetLocation(args[0].GetId()) - return nil, &common.Error{ - Message: "argument must be a simple name", - Location: location} - } - accuIdent := func() *exprpb.Expr { - return eh.Ident(AccumulatorName) - } - - var init *exprpb.Expr - var condition *exprpb.Expr - var step *exprpb.Expr - var result *exprpb.Expr - switch kind { - case quantifierAll: - init = eh.LiteralBool(true) - condition = eh.GlobalCall(operators.NotStrictlyFalse, accuIdent()) - step = eh.GlobalCall(operators.LogicalAnd, accuIdent(), args[1]) - result = accuIdent() - case quantifierExists: - init = eh.LiteralBool(false) - condition = eh.GlobalCall( - operators.NotStrictlyFalse, - eh.GlobalCall(operators.LogicalNot, accuIdent())) - step = eh.GlobalCall(operators.LogicalOr, accuIdent(), args[1]) - result = accuIdent() - case quantifierExistsOne: - zeroExpr := eh.LiteralInt(0) - oneExpr := eh.LiteralInt(1) - init = zeroExpr - condition = eh.LiteralBool(true) - step = eh.GlobalCall(operators.Conditional, args[1], - eh.GlobalCall(operators.Add, accuIdent(), oneExpr), accuIdent()) - result = eh.GlobalCall(operators.Equals, accuIdent(), oneExpr) - default: - return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)} - } - return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil -} - -func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeMap expands the input call arguments into a comprehension that transforms each element in the +// input to produce an output list. +// +// There are two call patterns supported by map: +// .map(, ) +// .map(, , ) +// In the second form only iterVar values which return true when provided to the predicate expression +// are transformed. +func MakeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { v, found := extractIdent(args[0]) if !found { return nil, &common.Error{Message: "argument is not an identifier"} @@ -345,7 +333,6 @@ func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E accuExpr := eh.Ident(AccumulatorName) init := eh.NewList() condition := eh.LiteralBool(true) - // TODO: use compiler internal method for faster, stateful add. step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(fn)) if filter != nil { @@ -354,7 +341,10 @@ func makeMap(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.E return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil } -func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { +// MakeFilter expands the input call arguments into a comprehension which produces a list which contains +// only elements which match the provided predicate expression: +// .filter(, ) +func MakeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { v, found := extractIdent(args[0]) if !found { return nil, &common.Error{Message: "argument is not an identifier"} @@ -364,12 +354,60 @@ func makeFilter(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprp accuExpr := eh.Ident(AccumulatorName) init := eh.NewList() condition := eh.LiteralBool(true) - // TODO: use compiler internal method for faster, stateful add. step := eh.GlobalCall(operators.Add, accuExpr, eh.NewList(args[0])) step = eh.GlobalCall(operators.Conditional, filter, step, accuExpr) return eh.Fold(v, target, AccumulatorName, init, condition, step, accuExpr), nil } +// MakeHas expands the input call arguments into a presence test, e.g. has(.field) +func MakeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok { + return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil + } + return nil, &common.Error{Message: "invalid argument to has() macro"} +} + +func makeQuantifier(kind quantifierKind, eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { + v, found := extractIdent(args[0]) + if !found { + location := eh.OffsetLocation(args[0].GetId()) + return nil, &common.Error{ + Message: "argument must be a simple name", + Location: location, + } + } + + var init *exprpb.Expr + var condition *exprpb.Expr + var step *exprpb.Expr + var result *exprpb.Expr + switch kind { + case quantifierAll: + init = eh.LiteralBool(true) + condition = eh.GlobalCall(operators.NotStrictlyFalse, eh.AccuIdent()) + step = eh.GlobalCall(operators.LogicalAnd, eh.AccuIdent(), args[1]) + result = eh.AccuIdent() + case quantifierExists: + init = eh.LiteralBool(false) + condition = eh.GlobalCall( + operators.NotStrictlyFalse, + eh.GlobalCall(operators.LogicalNot, eh.AccuIdent())) + step = eh.GlobalCall(operators.LogicalOr, eh.AccuIdent(), args[1]) + result = eh.AccuIdent() + case quantifierExistsOne: + zeroExpr := eh.LiteralInt(0) + oneExpr := eh.LiteralInt(1) + init = zeroExpr + condition = eh.LiteralBool(true) + step = eh.GlobalCall(operators.Conditional, args[1], + eh.GlobalCall(operators.Add, eh.AccuIdent(), oneExpr), eh.AccuIdent()) + result = eh.GlobalCall(operators.Equals, eh.AccuIdent(), oneExpr) + default: + return nil, &common.Error{Message: fmt.Sprintf("unrecognized quantifier '%v'", kind)} + } + return eh.Fold(v, target, AccumulatorName, init, condition, step, result), nil +} + func extractIdent(e *exprpb.Expr) (string, bool) { switch e.ExprKind.(type) { case *exprpb.Expr_IdentExpr: @@ -377,10 +415,3 @@ func extractIdent(e *exprpb.Expr) (string, bool) { } return "", false } - -func makeHas(eh ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) { - if s, ok := args[0].ExprKind.(*exprpb.Expr_SelectExpr); ok { - return eh.PresenceTest(s.SelectExpr.GetOperand(), s.SelectExpr.GetField()), nil - } - return nil, &common.Error{Message: "invalid argument to has() macro"} -} diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/github.com/google/cel-go/parser/parser.go index 70dbdd7cf7c..072f6245745 100644 --- a/vendor/github.com/google/cel-go/parser/parser.go +++ b/vendor/github.com/google/cel-go/parser/parser.go @@ -46,7 +46,7 @@ func NewParser(opts ...Option) (*Parser, error) { } } if p.maxRecursionDepth == 0 { - p.maxRecursionDepth = 200 + p.maxRecursionDepth = 250 } if p.maxRecursionDepth == -1 { p.maxRecursionDepth = int((^uint(0)) >> 1) @@ -270,6 +270,7 @@ type parser struct { errors *parseErrors helper *parserHelper macros map[string]Macro + recursionDepth int maxRecursionDepth int errorRecoveryLimit int errorRecoveryLookaheadTokenLimit int @@ -352,6 +353,13 @@ func (p *parser) parse(expr runes.Buffer, desc string) *exprpb.Expr { // Visitor implementations. func (p *parser) Visit(tree antlr.ParseTree) interface{} { + p.recursionDepth++ + if p.recursionDepth > p.maxRecursionDepth { + panic(&recursionError{message: "max recursion depth exceeded"}) + } + defer func() { + p.recursionDepth-- + }() switch tree.(type) { case *gen.StartContext: return p.VisitStart(tree.(*gen.StartContext)) @@ -799,13 +807,13 @@ func (p *parser) extractQualifiedName(e *exprpb.Expr) (string, bool) { if e == nil { return "", false } - switch e.ExprKind.(type) { + switch e.GetExprKind().(type) { case *exprpb.Expr_IdentExpr: return e.GetIdentExpr().GetName(), true case *exprpb.Expr_SelectExpr: s := e.GetSelectExpr() - if prefix, found := p.extractQualifiedName(s.Operand); found { - return prefix + "." + s.Field, true + if prefix, found := p.extractQualifiedName(s.GetOperand()); found { + return prefix + "." + s.GetField(), true } } // TODO: Add a method to Source to get location from character offset. diff --git a/vendor/github.com/google/cel-go/parser/unparser.go b/vendor/github.com/google/cel-go/parser/unparser.go index 6a610ff76ad..a459bb4a98d 100644 --- a/vendor/github.com/google/cel-go/parser/unparser.go +++ b/vendor/github.com/google/cel-go/parser/unparser.go @@ -36,9 +36,29 @@ import ( // - Floating point values are converted to the small number of digits needed to represent the value. // - Spacing around punctuation marks may be lost. // - Parentheses will only be applied when they affect operator precedence. -func Unparse(expr *exprpb.Expr, info *exprpb.SourceInfo) (string, error) { - un := &unparser{info: info} - err := un.visit(expr) +// +// This function optionally takes in one or more UnparserOption to alter the unparsing behavior, such as +// performing word wrapping on expressions. +func Unparse(expr *exprpb.Expr, info *exprpb.SourceInfo, opts ...UnparserOption) (string, error) { + unparserOpts := &unparserOption{ + wrapOnColumn: defaultWrapOnColumn, + wrapAfterColumnLimit: defaultWrapAfterColumnLimit, + operatorsToWrapOn: defaultOperatorsToWrapOn, + } + + var err error + for _, opt := range opts { + unparserOpts, err = opt(unparserOpts) + if err != nil { + return "", err + } + } + + un := &unparser{ + info: info, + options: unparserOpts, + } + err = un.visit(expr) if err != nil { return "", err } @@ -47,8 +67,10 @@ func Unparse(expr *exprpb.Expr, info *exprpb.SourceInfo) (string, error) { // unparser visits an expression to reconstruct a human-readable string from an AST. type unparser struct { - str strings.Builder - info *exprpb.SourceInfo + str strings.Builder + info *exprpb.SourceInfo + options *unparserOption + lastWrappedIndex int } func (un *unparser) visit(expr *exprpb.Expr) error { @@ -59,7 +81,7 @@ func (un *unparser) visit(expr *exprpb.Expr) error { if visited || err != nil { return err } - switch expr.ExprKind.(type) { + switch expr.GetExprKind().(type) { case *exprpb.Expr_CallExpr: return un.visitCall(expr) case *exprpb.Expr_ConstExpr: @@ -135,9 +157,8 @@ func (un *unparser) visitCallBinary(expr *exprpb.Expr) error { if !found { return fmt.Errorf("cannot unmangle operator: %s", fun) } - un.str.WriteString(" ") - un.str.WriteString(unmangled) - un.str.WriteString(" ") + + un.writeOperatorWithWrapping(fun, unmangled) return un.visitMaybeNested(rhs, rhsParen) } @@ -151,7 +172,8 @@ func (un *unparser) visitCallConditional(expr *exprpb.Expr) error { if err != nil { return err } - un.str.WriteString(" ? ") + un.writeOperatorWithWrapping(operators.Conditional, "?") + // add parens if operand is a conditional itself. nested = isSamePrecedence(operators.Conditional, args[1]) || isComplexOperator(args[1]) @@ -159,6 +181,7 @@ func (un *unparser) visitCallConditional(expr *exprpb.Expr) error { if err != nil { return err } + un.str.WriteString(" : ") // add parens if operand is a conditional itself. nested = isSamePrecedence(operators.Conditional, args[2]) || @@ -226,7 +249,7 @@ func (un *unparser) visitCallUnary(expr *exprpb.Expr) error { func (un *unparser) visitConst(expr *exprpb.Expr) error { c := expr.GetConstExpr() - switch c.ConstantKind.(type) { + switch c.GetConstantKind().(type) { case *exprpb.Constant_BoolValue: un.str.WriteString(strconv.FormatBool(c.GetBoolValue())) case *exprpb.Constant_BytesValue: @@ -444,3 +467,130 @@ func bytesToOctets(byteVal []byte) string { } return b.String() } + +// writeOperatorWithWrapping outputs the operator and inserts a newline for operators configured +// in the unparser options. +func (un *unparser) writeOperatorWithWrapping(fun string, unmangled string) bool { + _, wrapOperatorExists := un.options.operatorsToWrapOn[fun] + lineLength := un.str.Len() - un.lastWrappedIndex + len(fun) + + if wrapOperatorExists && lineLength >= un.options.wrapOnColumn { + un.lastWrappedIndex = un.str.Len() + // wrapAfterColumnLimit flag dictates whether the newline is placed + // before or after the operator + if un.options.wrapAfterColumnLimit { + // Input: a && b + // Output: a &&\nb + un.str.WriteString(" ") + un.str.WriteString(unmangled) + un.str.WriteString("\n") + } else { + // Input: a && b + // Output: a\n&& b + un.str.WriteString("\n") + un.str.WriteString(unmangled) + un.str.WriteString(" ") + } + return true + } else { + un.str.WriteString(" ") + un.str.WriteString(unmangled) + un.str.WriteString(" ") + } + return false +} + +// Defined defaults for the unparser options +var ( + defaultWrapOnColumn = 80 + defaultWrapAfterColumnLimit = true + defaultOperatorsToWrapOn = map[string]bool{ + operators.LogicalAnd: true, + operators.LogicalOr: true, + } +) + +// UnparserOption is a functional option for configuring the output formatting +// of the Unparse function. +type UnparserOption func(*unparserOption) (*unparserOption, error) + +// Internal representation of the UnparserOption type +type unparserOption struct { + wrapOnColumn int + operatorsToWrapOn map[string]bool + wrapAfterColumnLimit bool +} + +// WrapOnColumn wraps the output expression when its string length exceeds a specified limit +// for operators set by WrapOnOperators function or by default, "&&" and "||" will be wrapped. +// +// Example usage: +// +// Unparse(expr, sourceInfo, WrapOnColumn(40), WrapOnOperators(Operators.LogicalAnd)) +// +// This will insert a newline immediately after the logical AND operator for the below example input: +// +// Input: +// 'my-principal-group' in request.auth.claims && request.auth.claims.iat > now - duration('5m') +// +// Output: +// 'my-principal-group' in request.auth.claims && +// request.auth.claims.iat > now - duration('5m') +func WrapOnColumn(col int) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + if col < 1 { + return nil, fmt.Errorf("Invalid unparser option. Wrap column value must be greater than or equal to 1. Got %v instead", col) + } + opt.wrapOnColumn = col + return opt, nil + } +} + +// WrapOnOperators specifies which operators to perform word wrapping on an output expression when its string length +// exceeds the column limit set by WrapOnColumn function. +// +// Word wrapping is supported on non-unary symbolic operators. Refer to operators.go for the full list +// +// This will replace any previously supplied operators instead of merging them. +func WrapOnOperators(symbols ...string) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + opt.operatorsToWrapOn = make(map[string]bool) + for _, symbol := range symbols { + _, found := operators.FindReverse(symbol) + if !found { + return nil, fmt.Errorf("Invalid unparser option. Unsupported operator: %s", symbol) + } + arity := operators.Arity(symbol) + if arity < 2 { + return nil, fmt.Errorf("Invalid unparser option. Unary operators are unsupported: %s", symbol) + } + + opt.operatorsToWrapOn[symbol] = true + } + + return opt, nil + } +} + +// WrapAfterColumnLimit dictates whether to insert a newline before or after the specified operator +// when word wrapping is performed. +// +// Example usage: +// +// Unparse(expr, sourceInfo, WrapOnColumn(40), WrapOnOperators(Operators.LogicalAnd), WrapAfterColumnLimit(false)) +// +// This will insert a newline immediately before the logical AND operator for the below example input, ensuring +// that the length of a line never exceeds the specified column limit: +// +// Input: +// 'my-principal-group' in request.auth.claims && request.auth.claims.iat > now - duration('5m') +// +// Output: +// 'my-principal-group' in request.auth.claims +// && request.auth.claims.iat > now - duration('5m') +func WrapAfterColumnLimit(wrapAfter bool) UnparserOption { + return func(opt *unparserOption) (*unparserOption, error) { + opt.wrapAfterColumnLimit = wrapAfter + return opt, nil + } +} diff --git a/vendor/github.com/google/gnostic/jsonschema/display.go b/vendor/github.com/google/gnostic/jsonschema/display.go index 8677ed49a0e..028a760a91b 100644 --- a/vendor/github.com/google/gnostic/jsonschema/display.go +++ b/vendor/github.com/google/gnostic/jsonschema/display.go @@ -46,23 +46,8 @@ func (schema *Schema) describeSchema(indent string) string { if schema.Schema != nil { result += indent + "$schema: " + *(schema.Schema) + "\n" } - if schema.ReadOnly != nil && *schema.ReadOnly { - result += indent + fmt.Sprintf("readOnly: %+v\n", *(schema.ReadOnly)) - } - if schema.WriteOnly != nil && *schema.WriteOnly { - result += indent + fmt.Sprintf("writeOnly: %+v\n", *(schema.WriteOnly)) - } if schema.ID != nil { - switch strings.TrimSuffix(*schema.Schema, "#") { - case "http://json-schema.org/draft-04/schema#": - fallthrough - case "#": - fallthrough - case "": - result += indent + "id: " + *(schema.ID) + "\n" - default: - result += indent + "$id: " + *(schema.ID) + "\n" - } + result += indent + "id: " + *(schema.ID) + "\n" } if schema.MultipleOf != nil { result += indent + fmt.Sprintf("multipleOf: %+v\n", *(schema.MultipleOf)) diff --git a/vendor/github.com/google/gnostic/jsonschema/models.go b/vendor/github.com/google/gnostic/jsonschema/models.go index 0d877249abb..4781bdc5f50 100644 --- a/vendor/github.com/google/gnostic/jsonschema/models.go +++ b/vendor/github.com/google/gnostic/jsonschema/models.go @@ -23,11 +23,9 @@ import "gopkg.in/yaml.v3" // All fields are pointers and are nil if the associated values // are not specified. type Schema struct { - Schema *string // $schema - ID *string // id keyword used for $ref resolution scope - Ref *string // $ref, i.e. JSON Pointers - ReadOnly *bool - WriteOnly *bool + Schema *string // $schema + ID *string // id keyword used for $ref resolution scope + Ref *string // $ref, i.e. JSON Pointers // http://json-schema.org/latest/json-schema-validation.html // 5.1. Validation keywords for numeric instances (number and integer) diff --git a/vendor/github.com/google/gnostic/jsonschema/reader.go b/vendor/github.com/google/gnostic/jsonschema/reader.go index a909a34128b..b8583d46602 100644 --- a/vendor/github.com/google/gnostic/jsonschema/reader.go +++ b/vendor/github.com/google/gnostic/jsonschema/reader.go @@ -165,6 +165,7 @@ func NewSchemaFromObject(jsonData *yaml.Node) *Schema { default: fmt.Printf("schemaValue: unexpected node %+v\n", jsonData) + return nil } return nil diff --git a/vendor/github.com/google/gnostic/jsonschema/writer.go b/vendor/github.com/google/gnostic/jsonschema/writer.go index 15b1f905067..340dc5f9330 100644 --- a/vendor/github.com/google/gnostic/jsonschema/writer.go +++ b/vendor/github.com/google/gnostic/jsonschema/writer.go @@ -16,7 +16,6 @@ package jsonschema import ( "fmt" - "strings" "gopkg.in/yaml.v3" ) @@ -34,11 +33,7 @@ func renderMappingNode(node *yaml.Node, indent string) (result string) { value := node.Content[i+1] switch value.Kind { case yaml.ScalarNode: - if value.Tag == "!!bool" { - result += value.Value - } else { - result += "\"" + value.Value + "\"" - } + result += "\"" + value.Value + "\"" case yaml.MappingNode: result += renderMappingNode(value, innerIndent) case yaml.SequenceNode: @@ -63,11 +58,7 @@ func renderSequenceNode(node *yaml.Node, indent string) (result string) { item := node.Content[i] switch item.Kind { case yaml.ScalarNode: - if item.Tag == "!!bool" { - result += innerIndent + item.Value - } else { - result += innerIndent + "\"" + item.Value + "\"" - } + result += innerIndent + "\"" + item.Value + "\"" case yaml.MappingNode: result += innerIndent + renderMappingNode(item, innerIndent) + "" default: @@ -269,26 +260,11 @@ func (schema *Schema) nodeValue() *yaml.Node { content = appendPair(content, "title", nodeForString(*schema.Title)) } if schema.ID != nil { - switch strings.TrimSuffix(*schema.Schema, "#") { - case "http://json-schema.org/draft-04/schema": - fallthrough - case "#": - fallthrough - case "": - content = appendPair(content, "id", nodeForString(*schema.ID)) - default: - content = appendPair(content, "$id", nodeForString(*schema.ID)) - } + content = appendPair(content, "id", nodeForString(*schema.ID)) } if schema.Schema != nil { content = appendPair(content, "$schema", nodeForString(*schema.Schema)) } - if schema.ReadOnly != nil && *schema.ReadOnly { - content = appendPair(content, "readOnly", nodeForBoolean(*schema.ReadOnly)) - } - if schema.WriteOnly != nil && *schema.WriteOnly { - content = appendPair(content, "writeOnly", nodeForBoolean(*schema.WriteOnly)) - } if schema.Type != nil { content = appendPair(content, "type", schema.Type.nodeValue()) } diff --git a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go b/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go index 28c2777d511..0f17907667b 100644 --- a/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go +++ b/vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go @@ -7887,12 +7887,7 @@ func (m *Oauth2Scopes) ToRawInfo() *yaml.Node { if m == nil { return info } - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name)) - info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Value)) - } - } + // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} return info } diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go index d54a84db7c0..5f4a7025ea9 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go @@ -8560,12 +8560,7 @@ func (m *Strings) ToRawInfo() *yaml.Node { if m == nil { return info } - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name)) - info.Content = append(info.Content, compiler.NewScalarNodeForString(item.Value)) - } - } + // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} return info } diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go index 90a56f5526b..499e7f932d7 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go @@ -16,8 +16,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 -// protoc v3.19.4 +// protoc-gen-go v1.26.0 +// protoc v3.18.1 // source: openapiv3/OpenAPIv3.proto package openapi_v3 @@ -6760,13 +6760,12 @@ var file_openapiv3_OpenAPIv3_proto_rawDesc = []byte{ 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x56, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3e, 0x0a, 0x0e, 0x6f, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x6f, 0x70, 0x65, 0x6e, - 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, - 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, + 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto index 7aede5ed909..1be335b89ba 100644 --- a/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto +++ b/vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto @@ -42,7 +42,7 @@ option java_package = "org.openapi_v3"; option objc_class_prefix = "OAS"; // The Go package name. -option go_package = "github.com/google/gnostic/openapiv3;openapi_v3"; +option go_package = "./openapiv3;openapi_v3"; message AdditionalPropertiesItem { oneof oneof { diff --git a/vendor/github.com/google/gnostic/openapiv3/README.md b/vendor/github.com/google/gnostic/openapiv3/README.md index 83603b82aab..5ee12d92e24 100644 --- a/vendor/github.com/google/gnostic/openapiv3/README.md +++ b/vendor/github.com/google/gnostic/openapiv3/README.md @@ -19,7 +19,3 @@ for OpenAPI. The schema-generator directory contains support code which generates openapi-3.1.json from the OpenAPI 3.1 specification document (Markdown). - -### How to rebuild - -`protoc -I=. -I=third_party --go_out=. --go_opt=paths=source_relative openapiv3/*.proto` \ No newline at end of file diff --git a/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go b/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go deleted file mode 100644 index ae242f30431..00000000000 --- a/vendor/github.com/google/gnostic/openapiv3/annotations.pb.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2022 Google LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.0 -// protoc v3.19.4 -// source: openapiv3/annotations.proto - -package openapi_v3 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var file_openapiv3_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ - { - ExtendedType: (*descriptorpb.FileOptions)(nil), - ExtensionType: (*Document)(nil), - Field: 1143, - Name: "openapi.v3.document", - Tag: "bytes,1143,opt,name=document", - Filename: "openapiv3/annotations.proto", - }, - { - ExtendedType: (*descriptorpb.MethodOptions)(nil), - ExtensionType: (*Operation)(nil), - Field: 1143, - Name: "openapi.v3.operation", - Tag: "bytes,1143,opt,name=operation", - Filename: "openapiv3/annotations.proto", - }, - { - ExtendedType: (*descriptorpb.MessageOptions)(nil), - ExtensionType: (*Schema)(nil), - Field: 1143, - Name: "openapi.v3.schema", - Tag: "bytes,1143,opt,name=schema", - Filename: "openapiv3/annotations.proto", - }, - { - ExtendedType: (*descriptorpb.FieldOptions)(nil), - ExtensionType: (*Schema)(nil), - Field: 1143, - Name: "openapi.v3.property", - Tag: "bytes,1143,opt,name=property", - Filename: "openapiv3/annotations.proto", - }, -} - -// Extension fields to descriptorpb.FileOptions. -var ( - // optional openapi.v3.Document document = 1143; - E_Document = &file_openapiv3_annotations_proto_extTypes[0] -) - -// Extension fields to descriptorpb.MethodOptions. -var ( - // optional openapi.v3.Operation operation = 1143; - E_Operation = &file_openapiv3_annotations_proto_extTypes[1] -) - -// Extension fields to descriptorpb.MessageOptions. -var ( - // optional openapi.v3.Schema schema = 1143; - E_Schema = &file_openapiv3_annotations_proto_extTypes[2] -) - -// Extension fields to descriptorpb.FieldOptions. -var ( - // optional openapi.v3.Schema property = 1143; - E_Property = &file_openapiv3_annotations_proto_extTypes[3] -) - -var File_openapiv3_annotations_proto protoreflect.FileDescriptor - -var file_openapiv3_annotations_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, - 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x1a, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x61, - 0x70, 0x69, 0x76, 0x33, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x76, 0x33, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x4f, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x54, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, - 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x4e, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x42, 0x5a, 0x0a, 0x0e, 0x6f, - 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x10, 0x41, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, - 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_openapiv3_annotations_proto_goTypes = []interface{}{ - (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions - (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions - (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions - (*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions - (*Document)(nil), // 4: openapi.v3.Document - (*Operation)(nil), // 5: openapi.v3.Operation - (*Schema)(nil), // 6: openapi.v3.Schema -} -var file_openapiv3_annotations_proto_depIdxs = []int32{ - 0, // 0: openapi.v3.document:extendee -> google.protobuf.FileOptions - 1, // 1: openapi.v3.operation:extendee -> google.protobuf.MethodOptions - 2, // 2: openapi.v3.schema:extendee -> google.protobuf.MessageOptions - 3, // 3: openapi.v3.property:extendee -> google.protobuf.FieldOptions - 4, // 4: openapi.v3.document:type_name -> openapi.v3.Document - 5, // 5: openapi.v3.operation:type_name -> openapi.v3.Operation - 6, // 6: openapi.v3.schema:type_name -> openapi.v3.Schema - 6, // 7: openapi.v3.property:type_name -> openapi.v3.Schema - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 4, // [4:8] is the sub-list for extension type_name - 0, // [0:4] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_openapiv3_annotations_proto_init() } -func file_openapiv3_annotations_proto_init() { - if File_openapiv3_annotations_proto != nil { - return - } - file_openapiv3_OpenAPIv3_proto_init() - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openapiv3_annotations_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 4, - NumServices: 0, - }, - GoTypes: file_openapiv3_annotations_proto_goTypes, - DependencyIndexes: file_openapiv3_annotations_proto_depIdxs, - ExtensionInfos: file_openapiv3_annotations_proto_extTypes, - }.Build() - File_openapiv3_annotations_proto = out.File - file_openapiv3_annotations_proto_rawDesc = nil - file_openapiv3_annotations_proto_goTypes = nil - file_openapiv3_annotations_proto_depIdxs = nil -} diff --git a/vendor/github.com/google/gnostic/openapiv3/annotations.proto b/vendor/github.com/google/gnostic/openapiv3/annotations.proto deleted file mode 100644 index 0bd87810db6..00000000000 --- a/vendor/github.com/google/gnostic/openapiv3/annotations.proto +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2022 Google LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package openapi.v3; - -import "openapiv3/OpenAPIv3.proto"; -import "google/protobuf/descriptor.proto"; - -// This option lets the proto compiler generate Java code inside the package -// name (see below) instead of inside an outer class. It creates a simpler -// developer experience by reducing one-level of name nesting and be -// consistent with most programming languages that don't support outer classes. -option java_multiple_files = true; - -// The Java outer classname should be the filename in UpperCamelCase. This -// class is only used to hold proto descriptor, so developers don't need to -// work with it directly. -option java_outer_classname = "AnnotationsProto"; - -// The Java package name must be proto package name with proper prefix. -option java_package = "org.openapi_v3"; - -// A reasonable prefix for the Objective-C symbols generated from the package. -// It should at a minimum be 3 characters long, all uppercase, and convention -// is to use an abbreviation of the package name. Something short, but -// hopefully unique enough to not conflict with things that may come along in -// the future. 'GPB' is reserved for the protocol buffer implementation itself. -option objc_class_prefix = "OAS"; - -// The Go package name. -option go_package = "github.com/google/gnostic/openapiv3;openapi_v3"; - -extend google.protobuf.FileOptions { - Document document = 1143; -} - -extend google.protobuf.MethodOptions { - Operation operation = 1143; -} - -extend google.protobuf.MessageOptions { - Schema schema = 1143; -} - -extend google.protobuf.FieldOptions { - Schema property = 1143; -} \ No newline at end of file diff --git a/vendor/github.com/google/s2a-go/.gitignore b/vendor/github.com/google/s2a-go/.gitignore new file mode 100644 index 00000000000..01764d1cdf2 --- /dev/null +++ b/vendor/github.com/google/s2a-go/.gitignore @@ -0,0 +1,6 @@ +# Ignore binaries without extension +//example/client/client +//example/server/server +//internal/v2/fakes2av2_server/fakes2av2_server + +.idea/ \ No newline at end of file diff --git a/vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md b/vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..dc079b4d66e --- /dev/null +++ b/vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md @@ -0,0 +1,93 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + +Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the +Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/vendor/github.com/google/s2a-go/CONTRIBUTING.md b/vendor/github.com/google/s2a-go/CONTRIBUTING.md new file mode 100644 index 00000000000..22b241cb732 --- /dev/null +++ b/vendor/github.com/google/s2a-go/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement (CLA). You (or your employer) retain the copyright to your +contribution; this simply gives us permission to use and redistribute your +contributions as part of the project. Head over to + to see your current agreements on file or +to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google/conduct/). diff --git a/vendor/github.com/google/s2a-go/LICENSE.md b/vendor/github.com/google/s2a-go/LICENSE.md new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/google/s2a-go/LICENSE.md @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/google/s2a-go/README.md b/vendor/github.com/google/s2a-go/README.md new file mode 100644 index 00000000000..d566950f385 --- /dev/null +++ b/vendor/github.com/google/s2a-go/README.md @@ -0,0 +1,17 @@ +# Secure Session Agent Client Libraries + +The Secure Session Agent is a service that enables a workload to offload select +operations from the mTLS handshake and protects a workload's private key +material from exfiltration. Specifically, the workload asks the Secure Session +Agent for the TLS configuration to use during the handshake, to perform private +key operations, and to validate the peer certificate chain. The Secure Session +Agent's client libraries enable applications to communicate with the Secure +Session Agent during the TLS handshake, and to encrypt traffic to the peer +after the TLS handshake is complete. + +This repository contains the source code for the Secure Session Agent's Go +client libraries, which allow gRPC-Go applications to use the Secure Session +Agent. This repository supports the Bazel and Golang build systems. + +All code in this repository is experimental and subject to change. We do not +guarantee API stability at this time. diff --git a/vendor/github.com/google/s2a-go/fallback/s2a_fallback.go b/vendor/github.com/google/s2a-go/fallback/s2a_fallback.go new file mode 100644 index 00000000000..034d1b912ca --- /dev/null +++ b/vendor/github.com/google/s2a-go/fallback/s2a_fallback.go @@ -0,0 +1,167 @@ +/* + * + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package fallback provides default implementations of fallback options when S2A fails. +package fallback + +import ( + "context" + "crypto/tls" + "fmt" + "net" + + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" +) + +const ( + alpnProtoStrH2 = "h2" + alpnProtoStrHTTP = "http/1.1" + defaultHTTPSPort = "443" +) + +// FallbackTLSConfigGRPC is a tls.Config used by the DefaultFallbackClientHandshakeFunc function. +// It supports GRPC use case, thus the alpn is set to 'h2'. +var FallbackTLSConfigGRPC = tls.Config{ + MinVersion: tls.VersionTLS13, + ClientSessionCache: nil, + NextProtos: []string{alpnProtoStrH2}, +} + +// FallbackTLSConfigHTTP is a tls.Config used by the DefaultFallbackDialerAndAddress func. +// It supports the HTTP use case and the alpn is set to both 'http/1.1' and 'h2'. +var FallbackTLSConfigHTTP = tls.Config{ + MinVersion: tls.VersionTLS13, + ClientSessionCache: nil, + NextProtos: []string{alpnProtoStrH2, alpnProtoStrHTTP}, +} + +// ClientHandshake establishes a TLS connection and returns it, plus its auth info. +// Inputs: +// +// targetServer: the server attempted with S2A. +// conn: the tcp connection to the server at address targetServer that was passed into S2A's ClientHandshake func. +// If fallback is successful, the `conn` should be closed. +// err: the error encountered when performing the client-side TLS handshake with S2A. +type ClientHandshake func(ctx context.Context, targetServer string, conn net.Conn, err error) (net.Conn, credentials.AuthInfo, error) + +// DefaultFallbackClientHandshakeFunc returns a ClientHandshake function, +// which establishes a TLS connection to the provided fallbackAddr, returns the new connection and its auth info. +// Example use: +// +// transportCreds, _ = s2a.NewClientCreds(&s2a.ClientOptions{ +// S2AAddress: s2aAddress, +// FallbackOpts: &s2a.FallbackOptions{ // optional +// FallbackClientHandshakeFunc: fallback.DefaultFallbackClientHandshakeFunc(fallbackAddr), +// }, +// }) +// +// The fallback server's certificate must be verifiable using OS root store. +// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified, +// it uses default port 443. +// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption, +// and min TLS version is set to 1.3. +func DefaultFallbackClientHandshakeFunc(fallbackAddr string) (ClientHandshake, error) { + var fallbackDialer = tls.Dialer{Config: &FallbackTLSConfigGRPC} + return defaultFallbackClientHandshakeFuncInternal(fallbackAddr, fallbackDialer.DialContext) +} + +func defaultFallbackClientHandshakeFuncInternal(fallbackAddr string, dialContextFunc func(context.Context, string, string) (net.Conn, error)) (ClientHandshake, error) { + fallbackServerAddr, err := processFallbackAddr(fallbackAddr) + if err != nil { + if grpclog.V(1) { + grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err) + } + return nil, err + } + return func(ctx context.Context, targetServer string, conn net.Conn, s2aErr error) (net.Conn, credentials.AuthInfo, error) { + fbConn, fbErr := dialContextFunc(ctx, "tcp", fallbackServerAddr) + if fbErr != nil { + grpclog.Infof("dialing to fallback server %s failed: %v", fallbackServerAddr, fbErr) + return nil, nil, fmt.Errorf("dialing to fallback server %s failed: %v; S2A client handshake with %s error: %w", fallbackServerAddr, fbErr, targetServer, s2aErr) + } + + tc, success := fbConn.(*tls.Conn) + if !success { + grpclog.Infof("the connection with fallback server is expected to be tls but isn't") + return nil, nil, fmt.Errorf("the connection with fallback server is expected to be tls but isn't; S2A client handshake with %s error: %w", targetServer, s2aErr) + } + + tlsInfo := credentials.TLSInfo{ + State: tc.ConnectionState(), + CommonAuthInfo: credentials.CommonAuthInfo{ + SecurityLevel: credentials.PrivacyAndIntegrity, + }, + } + if grpclog.V(1) { + grpclog.Infof("ConnectionState.NegotiatedProtocol: %v", tc.ConnectionState().NegotiatedProtocol) + grpclog.Infof("ConnectionState.HandshakeComplete: %v", tc.ConnectionState().HandshakeComplete) + grpclog.Infof("ConnectionState.ServerName: %v", tc.ConnectionState().ServerName) + } + conn.Close() + return fbConn, tlsInfo, nil + }, nil +} + +// DefaultFallbackDialerAndAddress returns a TLS dialer and the network address to dial. +// Example use: +// +// fallbackDialer, fallbackServerAddr := fallback.DefaultFallbackDialerAndAddress(fallbackAddr) +// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{ +// S2AAddress: s2aAddress, // required +// FallbackOpts: &s2a.FallbackOptions{ +// FallbackDialer: &s2a.FallbackDialer{ +// Dialer: fallbackDialer, +// ServerAddr: fallbackServerAddr, +// }, +// }, +// }) +// +// The fallback server's certificate should be verifiable using OS root store. +// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified, +// it uses default port 443. +// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption, +// and min TLS version is set to 1.3. +func DefaultFallbackDialerAndAddress(fallbackAddr string) (*tls.Dialer, string, error) { + fallbackServerAddr, err := processFallbackAddr(fallbackAddr) + if err != nil { + if grpclog.V(1) { + grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err) + } + return nil, "", err + } + return &tls.Dialer{Config: &FallbackTLSConfigHTTP}, fallbackServerAddr, nil +} + +func processFallbackAddr(fallbackAddr string) (string, error) { + var fallbackServerAddr string + var err error + + if fallbackAddr == "" { + return "", fmt.Errorf("empty fallback address") + } + _, _, err = net.SplitHostPort(fallbackAddr) + if err != nil { + // fallbackAddr does not have port suffix + fallbackServerAddr = net.JoinHostPort(fallbackAddr, defaultHTTPSPort) + } else { + // FallbackServerAddr already has port suffix + fallbackServerAddr = fallbackAddr + } + return fallbackServerAddr, nil +} diff --git a/vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go b/vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go new file mode 100644 index 00000000000..aa3967f9d1f --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go @@ -0,0 +1,119 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package authinfo provides authentication and authorization information that +// results from the TLS handshake. +package authinfo + +import ( + "errors" + + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + contextpb "github.com/google/s2a-go/internal/proto/s2a_context_go_proto" + grpcpb "github.com/google/s2a-go/internal/proto/s2a_go_proto" + "google.golang.org/grpc/credentials" +) + +var _ credentials.AuthInfo = (*S2AAuthInfo)(nil) + +const s2aAuthType = "s2a" + +// S2AAuthInfo exposes authentication and authorization information from the +// S2A session result to the gRPC stack. +type S2AAuthInfo struct { + s2aContext *contextpb.S2AContext + commonAuthInfo credentials.CommonAuthInfo +} + +// NewS2AAuthInfo returns a new S2AAuthInfo object from the S2A session result. +func NewS2AAuthInfo(result *grpcpb.SessionResult) (credentials.AuthInfo, error) { + return newS2AAuthInfo(result) +} + +func newS2AAuthInfo(result *grpcpb.SessionResult) (*S2AAuthInfo, error) { + if result == nil { + return nil, errors.New("NewS2aAuthInfo given nil session result") + } + return &S2AAuthInfo{ + s2aContext: &contextpb.S2AContext{ + ApplicationProtocol: result.GetApplicationProtocol(), + TlsVersion: result.GetState().GetTlsVersion(), + Ciphersuite: result.GetState().GetTlsCiphersuite(), + PeerIdentity: result.GetPeerIdentity(), + LocalIdentity: result.GetLocalIdentity(), + PeerCertFingerprint: result.GetPeerCertFingerprint(), + LocalCertFingerprint: result.GetLocalCertFingerprint(), + IsHandshakeResumed: result.GetState().GetIsHandshakeResumed(), + }, + commonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}, + }, nil +} + +// AuthType returns the authentication type. +func (s *S2AAuthInfo) AuthType() string { + return s2aAuthType +} + +// ApplicationProtocol returns the application protocol, e.g. "grpc". +func (s *S2AAuthInfo) ApplicationProtocol() string { + return s.s2aContext.GetApplicationProtocol() +} + +// TLSVersion returns the TLS version negotiated during the handshake. +func (s *S2AAuthInfo) TLSVersion() commonpb.TLSVersion { + return s.s2aContext.GetTlsVersion() +} + +// Ciphersuite returns the ciphersuite negotiated during the handshake. +func (s *S2AAuthInfo) Ciphersuite() commonpb.Ciphersuite { + return s.s2aContext.GetCiphersuite() +} + +// PeerIdentity returns the authenticated identity of the peer. +func (s *S2AAuthInfo) PeerIdentity() *commonpb.Identity { + return s.s2aContext.GetPeerIdentity() +} + +// LocalIdentity returns the local identity of the application used during +// session setup. +func (s *S2AAuthInfo) LocalIdentity() *commonpb.Identity { + return s.s2aContext.GetLocalIdentity() +} + +// PeerCertFingerprint returns the SHA256 hash of the peer certificate used in +// the S2A handshake. +func (s *S2AAuthInfo) PeerCertFingerprint() []byte { + return s.s2aContext.GetPeerCertFingerprint() +} + +// LocalCertFingerprint returns the SHA256 hash of the local certificate used +// in the S2A handshake. +func (s *S2AAuthInfo) LocalCertFingerprint() []byte { + return s.s2aContext.GetLocalCertFingerprint() +} + +// IsHandshakeResumed returns true if a cached session was used to resume +// the handshake. +func (s *S2AAuthInfo) IsHandshakeResumed() bool { + return s.s2aContext.GetIsHandshakeResumed() +} + +// SecurityLevel returns the security level of the connection. +func (s *S2AAuthInfo) SecurityLevel() credentials.SecurityLevel { + return s.commonAuthInfo.SecurityLevel +} diff --git a/vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go b/vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go new file mode 100644 index 00000000000..8297c9a9746 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go @@ -0,0 +1,438 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package handshaker communicates with the S2A handshaker service. +package handshaker + +import ( + "context" + "errors" + "fmt" + "io" + "net" + "sync" + + "github.com/google/s2a-go/internal/authinfo" + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto" + "github.com/google/s2a-go/internal/record" + "github.com/google/s2a-go/internal/tokenmanager" + grpc "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" +) + +var ( + // appProtocol contains the application protocol accepted by the handshaker. + appProtocol = "grpc" + // frameLimit is the maximum size of a frame in bytes. + frameLimit = 1024 * 64 + // peerNotRespondingError is the error thrown when the peer doesn't respond. + errPeerNotResponding = errors.New("peer is not responding and re-connection should be attempted") +) + +// Handshaker defines a handshaker interface. +type Handshaker interface { + // ClientHandshake starts and completes a TLS handshake from the client side, + // and returns a secure connection along with additional auth information. + ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) + // ServerHandshake starts and completes a TLS handshake from the server side, + // and returns a secure connection along with additional auth information. + ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) + // Close terminates the Handshaker. It should be called when the handshake + // is complete. + Close() error +} + +// ClientHandshakerOptions contains the options needed to configure the S2A +// handshaker service on the client-side. +type ClientHandshakerOptions struct { + // MinTLSVersion specifies the min TLS version supported by the client. + MinTLSVersion commonpb.TLSVersion + // MaxTLSVersion specifies the max TLS version supported by the client. + MaxTLSVersion commonpb.TLSVersion + // TLSCiphersuites is the ordered list of ciphersuites supported by the + // client. + TLSCiphersuites []commonpb.Ciphersuite + // TargetIdentities contains a list of allowed server identities. One of the + // target identities should match the peer identity in the handshake + // result; otherwise, the handshake fails. + TargetIdentities []*commonpb.Identity + // LocalIdentity is the local identity of the client application. If none is + // provided, then the S2A will choose the default identity. + LocalIdentity *commonpb.Identity + // TargetName is the allowed server name, which may be used for server + // authorization check by the S2A if it is provided. + TargetName string + // EnsureProcessSessionTickets allows users to wait and ensure that all + // available session tickets are sent to S2A before a process completes. + EnsureProcessSessionTickets *sync.WaitGroup +} + +// ServerHandshakerOptions contains the options needed to configure the S2A +// handshaker service on the server-side. +type ServerHandshakerOptions struct { + // MinTLSVersion specifies the min TLS version supported by the server. + MinTLSVersion commonpb.TLSVersion + // MaxTLSVersion specifies the max TLS version supported by the server. + MaxTLSVersion commonpb.TLSVersion + // TLSCiphersuites is the ordered list of ciphersuites supported by the + // server. + TLSCiphersuites []commonpb.Ciphersuite + // LocalIdentities is the list of local identities that may be assumed by + // the server. If no local identity is specified, then the S2A chooses a + // default local identity. + LocalIdentities []*commonpb.Identity +} + +// s2aHandshaker performs a TLS handshake using the S2A handshaker service. +type s2aHandshaker struct { + // stream is used to communicate with the S2A handshaker service. + stream s2apb.S2AService_SetUpSessionClient + // conn is the connection to the peer. + conn net.Conn + // clientOpts should be non-nil iff the handshaker is client-side. + clientOpts *ClientHandshakerOptions + // serverOpts should be non-nil iff the handshaker is server-side. + serverOpts *ServerHandshakerOptions + // isClient determines if the handshaker is client or server side. + isClient bool + // hsAddr stores the address of the S2A handshaker service. + hsAddr string + // tokenManager manages access tokens for authenticating to S2A. + tokenManager tokenmanager.AccessTokenManager + // localIdentities is the set of local identities for whom the + // tokenManager should fetch a token when preparing a request to be + // sent to S2A. + localIdentities []*commonpb.Identity +} + +// NewClientHandshaker creates an s2aHandshaker instance that performs a +// client-side TLS handshake using the S2A handshaker service. +func NewClientHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ClientHandshakerOptions) (Handshaker, error) { + stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true)) + if err != nil { + return nil, err + } + tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + if err != nil { + grpclog.Infof("failed to create single token access token manager: %v", err) + } + return newClientHandshaker(stream, c, hsAddr, opts, tokenManager), nil +} + +func newClientHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ClientHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker { + var localIdentities []*commonpb.Identity + if opts != nil { + localIdentities = []*commonpb.Identity{opts.LocalIdentity} + } + return &s2aHandshaker{ + stream: stream, + conn: c, + clientOpts: opts, + isClient: true, + hsAddr: hsAddr, + tokenManager: tokenManager, + localIdentities: localIdentities, + } +} + +// NewServerHandshaker creates an s2aHandshaker instance that performs a +// server-side TLS handshake using the S2A handshaker service. +func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ServerHandshakerOptions) (Handshaker, error) { + stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true)) + if err != nil { + return nil, err + } + tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + if err != nil { + grpclog.Infof("failed to create single token access token manager: %v", err) + } + return newServerHandshaker(stream, c, hsAddr, opts, tokenManager), nil +} + +func newServerHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ServerHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker { + var localIdentities []*commonpb.Identity + if opts != nil { + localIdentities = opts.LocalIdentities + } + return &s2aHandshaker{ + stream: stream, + conn: c, + serverOpts: opts, + isClient: false, + hsAddr: hsAddr, + tokenManager: tokenManager, + localIdentities: localIdentities, + } +} + +// ClientHandshake performs a client-side TLS handshake using the S2A handshaker +// service. When complete, returns a TLS connection. +func (h *s2aHandshaker) ClientHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) { + if !h.isClient { + return nil, nil, errors.New("only handshakers created using NewClientHandshaker can perform a client-side handshake") + } + // Extract the hostname from the target name. The target name is assumed to be an authority. + hostname, _, err := net.SplitHostPort(h.clientOpts.TargetName) + if err != nil { + // If the target name had no host port or could not be parsed, use it as is. + hostname = h.clientOpts.TargetName + } + + // Prepare a client start message to send to the S2A handshaker service. + req := &s2apb.SessionReq{ + ReqOneof: &s2apb.SessionReq_ClientStart{ + ClientStart: &s2apb.ClientSessionStartReq{ + ApplicationProtocols: []string{appProtocol}, + MinTlsVersion: h.clientOpts.MinTLSVersion, + MaxTlsVersion: h.clientOpts.MaxTLSVersion, + TlsCiphersuites: h.clientOpts.TLSCiphersuites, + TargetIdentities: h.clientOpts.TargetIdentities, + LocalIdentity: h.clientOpts.LocalIdentity, + TargetName: hostname, + }, + }, + AuthMechanisms: h.getAuthMechanisms(), + } + conn, result, err := h.setUpSession(req) + if err != nil { + return nil, nil, err + } + authInfo, err := authinfo.NewS2AAuthInfo(result) + if err != nil { + return nil, nil, err + } + return conn, authInfo, nil +} + +// ServerHandshake performs a server-side TLS handshake using the S2A handshaker +// service. When complete, returns a TLS connection. +func (h *s2aHandshaker) ServerHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) { + if h.isClient { + return nil, nil, errors.New("only handshakers created using NewServerHandshaker can perform a server-side handshake") + } + p := make([]byte, frameLimit) + n, err := h.conn.Read(p) + if err != nil { + return nil, nil, err + } + // Prepare a server start message to send to the S2A handshaker service. + req := &s2apb.SessionReq{ + ReqOneof: &s2apb.SessionReq_ServerStart{ + ServerStart: &s2apb.ServerSessionStartReq{ + ApplicationProtocols: []string{appProtocol}, + MinTlsVersion: h.serverOpts.MinTLSVersion, + MaxTlsVersion: h.serverOpts.MaxTLSVersion, + TlsCiphersuites: h.serverOpts.TLSCiphersuites, + LocalIdentities: h.serverOpts.LocalIdentities, + InBytes: p[:n], + }, + }, + AuthMechanisms: h.getAuthMechanisms(), + } + conn, result, err := h.setUpSession(req) + if err != nil { + return nil, nil, err + } + authInfo, err := authinfo.NewS2AAuthInfo(result) + if err != nil { + return nil, nil, err + } + return conn, authInfo, nil +} + +// setUpSession proxies messages between the peer and the S2A handshaker +// service. +func (h *s2aHandshaker) setUpSession(req *s2apb.SessionReq) (net.Conn, *s2apb.SessionResult, error) { + resp, err := h.accessHandshakerService(req) + if err != nil { + return nil, nil, err + } + // Check if the returned status is an error. + if resp.GetStatus() != nil { + if got, want := resp.GetStatus().Code, uint32(codes.OK); got != want { + return nil, nil, fmt.Errorf("%v", resp.GetStatus().Details) + } + } + // Calculate the extra unread bytes from the Session. Attempting to consume + // more than the bytes sent will throw an error. + var extra []byte + if req.GetServerStart() != nil { + if resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) { + return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds") + } + extra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():] + } + result, extra, err := h.processUntilDone(resp, extra) + if err != nil { + return nil, nil, err + } + if result.GetLocalIdentity() == nil { + return nil, nil, errors.New("local identity must be populated in session result") + } + + // Create a new TLS record protocol using the Session Result. + newConn, err := record.NewConn(&record.ConnParameters{ + NetConn: h.conn, + Ciphersuite: result.GetState().GetTlsCiphersuite(), + TLSVersion: result.GetState().GetTlsVersion(), + InTrafficSecret: result.GetState().GetInKey(), + OutTrafficSecret: result.GetState().GetOutKey(), + UnusedBuf: extra, + InSequence: result.GetState().GetInSequence(), + OutSequence: result.GetState().GetOutSequence(), + HSAddr: h.hsAddr, + ConnectionID: result.GetState().GetConnectionId(), + LocalIdentity: result.GetLocalIdentity(), + EnsureProcessSessionTickets: h.ensureProcessSessionTickets(), + }) + if err != nil { + return nil, nil, err + } + return newConn, result, nil +} + +func (h *s2aHandshaker) ensureProcessSessionTickets() *sync.WaitGroup { + if h.clientOpts == nil { + return nil + } + return h.clientOpts.EnsureProcessSessionTickets +} + +// accessHandshakerService sends the session request to the S2A handshaker +// service and returns the session response. +func (h *s2aHandshaker) accessHandshakerService(req *s2apb.SessionReq) (*s2apb.SessionResp, error) { + if err := h.stream.Send(req); err != nil { + return nil, err + } + resp, err := h.stream.Recv() + if err != nil { + return nil, err + } + return resp, nil +} + +// processUntilDone continues proxying messages between the peer and the S2A +// handshaker service until the handshaker service returns the SessionResult at +// the end of the handshake or an error occurs. +func (h *s2aHandshaker) processUntilDone(resp *s2apb.SessionResp, unusedBytes []byte) (*s2apb.SessionResult, []byte, error) { + for { + if len(resp.OutFrames) > 0 { + if _, err := h.conn.Write(resp.OutFrames); err != nil { + return nil, nil, err + } + } + if resp.Result != nil { + return resp.Result, unusedBytes, nil + } + buf := make([]byte, frameLimit) + n, err := h.conn.Read(buf) + if err != nil && err != io.EOF { + return nil, nil, err + } + // If there is nothing to send to the handshaker service and nothing is + // received from the peer, then we are stuck. This covers the case when + // the peer is not responding. Note that handshaker service connection + // issues are caught in accessHandshakerService before we even get + // here. + if len(resp.OutFrames) == 0 && n == 0 { + return nil, nil, errPeerNotResponding + } + // Append extra bytes from the previous interaction with the handshaker + // service with the current buffer read from conn. + p := append(unusedBytes, buf[:n]...) + // From here on, p and unusedBytes point to the same slice. + resp, err = h.accessHandshakerService(&s2apb.SessionReq{ + ReqOneof: &s2apb.SessionReq_Next{ + Next: &s2apb.SessionNextReq{ + InBytes: p, + }, + }, + AuthMechanisms: h.getAuthMechanisms(), + }) + if err != nil { + return nil, nil, err + } + + // Cache the local identity returned by S2A, if it is populated. This + // overwrites any existing local identities. This is done because, once the + // S2A has selected a local identity, then only that local identity should + // be asserted in future requests until the end of the current handshake. + if resp.GetLocalIdentity() != nil { + h.localIdentities = []*commonpb.Identity{resp.GetLocalIdentity()} + } + + // Set unusedBytes based on the handshaker service response. + if resp.GetBytesConsumed() > uint32(len(p)) { + return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds") + } + unusedBytes = p[resp.GetBytesConsumed():] + } +} + +// Close shuts down the handshaker and the stream to the S2A handshaker service +// when the handshake is complete. It should be called when the caller obtains +// the secure connection at the end of the handshake. +func (h *s2aHandshaker) Close() error { + return h.stream.CloseSend() +} + +func (h *s2aHandshaker) getAuthMechanisms() []*s2apb.AuthenticationMechanism { + if h.tokenManager == nil { + return nil + } + // First handle the special case when no local identities have been provided + // by the application. In this case, an AuthenticationMechanism with no local + // identity will be sent. + if len(h.localIdentities) == 0 { + token, err := h.tokenManager.DefaultToken() + if err != nil { + grpclog.Infof("unable to get token for empty local identity: %v", err) + return nil + } + return []*s2apb.AuthenticationMechanism{ + { + MechanismOneof: &s2apb.AuthenticationMechanism_Token{ + Token: token, + }, + }, + } + } + + // Next, handle the case where the application (or the S2A) has provided + // one or more local identities. + var authMechanisms []*s2apb.AuthenticationMechanism + for _, localIdentity := range h.localIdentities { + token, err := h.tokenManager.Token(localIdentity) + if err != nil { + grpclog.Infof("unable to get token for local identity %v: %v", localIdentity, err) + continue + } + + authMechanism := &s2apb.AuthenticationMechanism{ + Identity: localIdentity, + MechanismOneof: &s2apb.AuthenticationMechanism_Token{ + Token: token, + }, + } + authMechanisms = append(authMechanisms, authMechanism) + } + return authMechanisms +} diff --git a/vendor/github.com/google/s2a-go/internal/handshaker/service/service.go b/vendor/github.com/google/s2a-go/internal/handshaker/service/service.go new file mode 100644 index 00000000000..49573af887c --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/handshaker/service/service.go @@ -0,0 +1,99 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package service is a utility for calling the S2A handshaker service. +package service + +import ( + "context" + "net" + "os" + "strings" + "sync" + "time" + + "google.golang.org/appengine" + "google.golang.org/appengine/socket" + grpc "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" +) + +// An environment variable, if true, opportunistically use AppEngine-specific dialer to call S2A. +const enableAppEngineDialerEnv = "S2A_ENABLE_APP_ENGINE_DIALER" + +var ( + // appEngineDialerHook is an AppEngine-specific dial option that is set + // during init time. If nil, then the application is not running on Google + // AppEngine. + appEngineDialerHook func(context.Context) grpc.DialOption + // mu guards hsConnMap and hsDialer. + mu sync.Mutex + // hsConnMap represents a mapping from an S2A handshaker service address + // to a corresponding connection to an S2A handshaker service instance. + hsConnMap = make(map[string]*grpc.ClientConn) + // hsDialer will be reassigned in tests. + hsDialer = grpc.Dial +) + +func init() { + if !appengine.IsAppEngine() && !appengine.IsDevAppServer() { + return + } + appEngineDialerHook = func(ctx context.Context) grpc.DialOption { + return grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { + return socket.DialTimeout(ctx, "tcp", addr, timeout) + }) + } +} + +// Dial dials the S2A handshaker service. If a connection has already been +// established, this function returns it. Otherwise, a new connection is +// created. +func Dial(handshakerServiceAddress string) (*grpc.ClientConn, error) { + mu.Lock() + defer mu.Unlock() + + hsConn, ok := hsConnMap[handshakerServiceAddress] + if !ok { + // Create a new connection to the S2A handshaker service. Note that + // this connection stays open until the application is closed. + grpcOpts := []grpc.DialOption{ + grpc.WithInsecure(), + } + if enableAppEngineDialer() && appEngineDialerHook != nil { + if grpclog.V(1) { + grpclog.Info("Using AppEngine-specific dialer to talk to S2A.") + } + grpcOpts = append(grpcOpts, appEngineDialerHook(context.Background())) + } + var err error + hsConn, err = hsDialer(handshakerServiceAddress, grpcOpts...) + if err != nil { + return nil, err + } + hsConnMap[handshakerServiceAddress] = hsConn + } + return hsConn, nil +} + +func enableAppEngineDialer() bool { + if strings.ToLower(os.Getenv(enableAppEngineDialerEnv)) == "true" { + return true + } + return false +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go b/vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go new file mode 100644 index 00000000000..16278a1d995 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go @@ -0,0 +1,389 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/common/common.proto + +package common_go_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The ciphersuites supported by S2A. The name determines the confidentiality, +// and authentication ciphers as well as the hash algorithm used for PRF in +// TLS 1.2 or HKDF in TLS 1.3. Thus, the components of the name are: +// - AEAD -- for encryption and authentication, e.g., AES_128_GCM. +// - Hash algorithm -- used in PRF or HKDF, e.g., SHA256. +type Ciphersuite int32 + +const ( + Ciphersuite_AES_128_GCM_SHA256 Ciphersuite = 0 + Ciphersuite_AES_256_GCM_SHA384 Ciphersuite = 1 + Ciphersuite_CHACHA20_POLY1305_SHA256 Ciphersuite = 2 +) + +// Enum value maps for Ciphersuite. +var ( + Ciphersuite_name = map[int32]string{ + 0: "AES_128_GCM_SHA256", + 1: "AES_256_GCM_SHA384", + 2: "CHACHA20_POLY1305_SHA256", + } + Ciphersuite_value = map[string]int32{ + "AES_128_GCM_SHA256": 0, + "AES_256_GCM_SHA384": 1, + "CHACHA20_POLY1305_SHA256": 2, + } +) + +func (x Ciphersuite) Enum() *Ciphersuite { + p := new(Ciphersuite) + *p = x + return p +} + +func (x Ciphersuite) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_common_common_proto_enumTypes[0].Descriptor() +} + +func (Ciphersuite) Type() protoreflect.EnumType { + return &file_internal_proto_common_common_proto_enumTypes[0] +} + +func (x Ciphersuite) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Ciphersuite.Descriptor instead. +func (Ciphersuite) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0} +} + +// The TLS versions supported by S2A's handshaker module. +type TLSVersion int32 + +const ( + TLSVersion_TLS1_2 TLSVersion = 0 + TLSVersion_TLS1_3 TLSVersion = 1 +) + +// Enum value maps for TLSVersion. +var ( + TLSVersion_name = map[int32]string{ + 0: "TLS1_2", + 1: "TLS1_3", + } + TLSVersion_value = map[string]int32{ + "TLS1_2": 0, + "TLS1_3": 1, + } +) + +func (x TLSVersion) Enum() *TLSVersion { + p := new(TLSVersion) + *p = x + return p +} + +func (x TLSVersion) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TLSVersion) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_common_common_proto_enumTypes[1].Descriptor() +} + +func (TLSVersion) Type() protoreflect.EnumType { + return &file_internal_proto_common_common_proto_enumTypes[1] +} + +func (x TLSVersion) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TLSVersion.Descriptor instead. +func (TLSVersion) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_common_common_proto_rawDescGZIP(), []int{1} +} + +type Identity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to IdentityOneof: + // + // *Identity_SpiffeId + // *Identity_Hostname + // *Identity_Uid + // *Identity_MdbUsername + // *Identity_GaiaId + IdentityOneof isIdentity_IdentityOneof `protobuf_oneof:"identity_oneof"` + // Additional identity-specific attributes. + Attributes map[string]string `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Identity) Reset() { + *x = Identity{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_common_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Identity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Identity) ProtoMessage() {} + +func (x *Identity) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_common_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Identity.ProtoReflect.Descriptor instead. +func (*Identity) Descriptor() ([]byte, []int) { + return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0} +} + +func (m *Identity) GetIdentityOneof() isIdentity_IdentityOneof { + if m != nil { + return m.IdentityOneof + } + return nil +} + +func (x *Identity) GetSpiffeId() string { + if x, ok := x.GetIdentityOneof().(*Identity_SpiffeId); ok { + return x.SpiffeId + } + return "" +} + +func (x *Identity) GetHostname() string { + if x, ok := x.GetIdentityOneof().(*Identity_Hostname); ok { + return x.Hostname + } + return "" +} + +func (x *Identity) GetUid() string { + if x, ok := x.GetIdentityOneof().(*Identity_Uid); ok { + return x.Uid + } + return "" +} + +func (x *Identity) GetMdbUsername() string { + if x, ok := x.GetIdentityOneof().(*Identity_MdbUsername); ok { + return x.MdbUsername + } + return "" +} + +func (x *Identity) GetGaiaId() string { + if x, ok := x.GetIdentityOneof().(*Identity_GaiaId); ok { + return x.GaiaId + } + return "" +} + +func (x *Identity) GetAttributes() map[string]string { + if x != nil { + return x.Attributes + } + return nil +} + +type isIdentity_IdentityOneof interface { + isIdentity_IdentityOneof() +} + +type Identity_SpiffeId struct { + // The SPIFFE ID of a connection endpoint. + SpiffeId string `protobuf:"bytes,1,opt,name=spiffe_id,json=spiffeId,proto3,oneof"` +} + +type Identity_Hostname struct { + // The hostname of a connection endpoint. + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3,oneof"` +} + +type Identity_Uid struct { + // The UID of a connection endpoint. + Uid string `protobuf:"bytes,4,opt,name=uid,proto3,oneof"` +} + +type Identity_MdbUsername struct { + // The MDB username of a connection endpoint. + MdbUsername string `protobuf:"bytes,5,opt,name=mdb_username,json=mdbUsername,proto3,oneof"` +} + +type Identity_GaiaId struct { + // The Gaia ID of a connection endpoint. + GaiaId string `protobuf:"bytes,6,opt,name=gaia_id,json=gaiaId,proto3,oneof"` +} + +func (*Identity_SpiffeId) isIdentity_IdentityOneof() {} + +func (*Identity_Hostname) isIdentity_IdentityOneof() {} + +func (*Identity_Uid) isIdentity_IdentityOneof() {} + +func (*Identity_MdbUsername) isIdentity_IdentityOneof() {} + +func (*Identity_GaiaId) isIdentity_IdentityOneof() {} + +var File_internal_proto_common_common_proto protoreflect.FileDescriptor + +var file_internal_proto_common_common_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xb1, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x09, + 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x75, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a, + 0x0c, 0x6d, 0x64, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x64, 0x62, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x07, 0x67, 0x61, 0x69, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x67, 0x61, 0x69, 0x61, 0x49, 0x64, 0x12, 0x43, 0x0a, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x6e, + 0x65, 0x6f, 0x66, 0x2a, 0x5b, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, + 0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, + 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45, + 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, + 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, + 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x02, + 0x2a, 0x24, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, + 0x0a, 0x06, 0x54, 0x4c, 0x53, 0x31, 0x5f, 0x32, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x4c, + 0x53, 0x31, 0x5f, 0x33, 0x10, 0x01, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_proto_common_common_proto_rawDescOnce sync.Once + file_internal_proto_common_common_proto_rawDescData = file_internal_proto_common_common_proto_rawDesc +) + +func file_internal_proto_common_common_proto_rawDescGZIP() []byte { + file_internal_proto_common_common_proto_rawDescOnce.Do(func() { + file_internal_proto_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_common_common_proto_rawDescData) + }) + return file_internal_proto_common_common_proto_rawDescData +} + +var file_internal_proto_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_internal_proto_common_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_internal_proto_common_common_proto_goTypes = []interface{}{ + (Ciphersuite)(0), // 0: s2a.proto.Ciphersuite + (TLSVersion)(0), // 1: s2a.proto.TLSVersion + (*Identity)(nil), // 2: s2a.proto.Identity + nil, // 3: s2a.proto.Identity.AttributesEntry +} +var file_internal_proto_common_common_proto_depIdxs = []int32{ + 3, // 0: s2a.proto.Identity.attributes:type_name -> s2a.proto.Identity.AttributesEntry + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_internal_proto_common_common_proto_init() } +func file_internal_proto_common_common_proto_init() { + if File_internal_proto_common_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_proto_common_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Identity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_internal_proto_common_common_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Identity_SpiffeId)(nil), + (*Identity_Hostname)(nil), + (*Identity_Uid)(nil), + (*Identity_MdbUsername)(nil), + (*Identity_GaiaId)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_common_common_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_internal_proto_common_common_proto_goTypes, + DependencyIndexes: file_internal_proto_common_common_proto_depIdxs, + EnumInfos: file_internal_proto_common_common_proto_enumTypes, + MessageInfos: file_internal_proto_common_common_proto_msgTypes, + }.Build() + File_internal_proto_common_common_proto = out.File + file_internal_proto_common_common_proto_rawDesc = nil + file_internal_proto_common_common_proto_goTypes = nil + file_internal_proto_common_common_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go b/vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go new file mode 100644 index 00000000000..f4f763ae102 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go @@ -0,0 +1,267 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/s2a_context/s2a_context.proto + +package s2a_context_go_proto + +import ( + common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type S2AContext struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The application protocol negotiated for this connection, e.g., 'grpc'. + ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"` + // The TLS version number that the S2A's handshaker module used to set up the + // session. + TlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=tls_version,json=tlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"tls_version,omitempty"` + // The TLS ciphersuite negotiated by the S2A's handshaker module. + Ciphersuite common_go_proto.Ciphersuite `protobuf:"varint,3,opt,name=ciphersuite,proto3,enum=s2a.proto.Ciphersuite" json:"ciphersuite,omitempty"` + // The authenticated identity of the peer. + PeerIdentity *common_go_proto.Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"` + // The local identity used during session setup. This could be: + // - The local identity that the client specifies in ClientSessionStartReq. + // - One of the local identities that the server specifies in + // ServerSessionStartReq. + // - If neither client or server specifies local identities, the S2A picks the + // default one. In this case, this field will contain that identity. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The SHA256 hash of the peer certificate used in the handshake. + PeerCertFingerprint []byte `protobuf:"bytes,6,opt,name=peer_cert_fingerprint,json=peerCertFingerprint,proto3" json:"peer_cert_fingerprint,omitempty"` + // The SHA256 hash of the local certificate used in the handshake. + LocalCertFingerprint []byte `protobuf:"bytes,7,opt,name=local_cert_fingerprint,json=localCertFingerprint,proto3" json:"local_cert_fingerprint,omitempty"` + // Set to true if a cached session was reused to resume the handshake. + IsHandshakeResumed bool `protobuf:"varint,8,opt,name=is_handshake_resumed,json=isHandshakeResumed,proto3" json:"is_handshake_resumed,omitempty"` +} + +func (x *S2AContext) Reset() { + *x = S2AContext{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *S2AContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*S2AContext) ProtoMessage() {} + +func (x *S2AContext) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead. +func (*S2AContext) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0} +} + +func (x *S2AContext) GetApplicationProtocol() string { + if x != nil { + return x.ApplicationProtocol + } + return "" +} + +func (x *S2AContext) GetTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.TlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *S2AContext) GetCiphersuite() common_go_proto.Ciphersuite { + if x != nil { + return x.Ciphersuite + } + return common_go_proto.Ciphersuite(0) +} + +func (x *S2AContext) GetPeerIdentity() *common_go_proto.Identity { + if x != nil { + return x.PeerIdentity + } + return nil +} + +func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *S2AContext) GetPeerCertFingerprint() []byte { + if x != nil { + return x.PeerCertFingerprint + } + return nil +} + +func (x *S2AContext) GetLocalCertFingerprint() []byte { + if x != nil { + return x.LocalCertFingerprint + } + return nil +} + +func (x *S2AContext) GetIsHandshakeResumed() bool { + if x != nil { + return x.IsHandshakeResumed + } + return false +} + +var File_internal_proto_s2a_context_s2a_context_proto protoreflect.FileDescriptor + +var file_internal_proto_s2a_context_s2a_context_proto_rawDesc = []byte{ + 0x0a, 0x2c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x73, 0x32, 0x61, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, + 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x03, + 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x31, 0x0a, 0x14, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x36, 0x0a, 0x0b, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x74, 0x6c, 0x73, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, + 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, + 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, + 0x65, 0x12, 0x38, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70, + 0x65, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x65, 0x72, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, + 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, + 0x65, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x69, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x75, + 0x6d, 0x65, 0x64, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x32, 0x61, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce sync.Once + file_internal_proto_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_s2a_context_s2a_context_proto_rawDesc +) + +func file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP() []byte { + file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce.Do(func() { + file_internal_proto_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_s2a_context_s2a_context_proto_rawDescData) + }) + return file_internal_proto_s2a_context_s2a_context_proto_rawDescData +} + +var file_internal_proto_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_internal_proto_s2a_context_s2a_context_proto_goTypes = []interface{}{ + (*S2AContext)(nil), // 0: s2a.proto.S2AContext + (common_go_proto.TLSVersion)(0), // 1: s2a.proto.TLSVersion + (common_go_proto.Ciphersuite)(0), // 2: s2a.proto.Ciphersuite + (*common_go_proto.Identity)(nil), // 3: s2a.proto.Identity +} +var file_internal_proto_s2a_context_s2a_context_proto_depIdxs = []int32{ + 1, // 0: s2a.proto.S2AContext.tls_version:type_name -> s2a.proto.TLSVersion + 2, // 1: s2a.proto.S2AContext.ciphersuite:type_name -> s2a.proto.Ciphersuite + 3, // 2: s2a.proto.S2AContext.peer_identity:type_name -> s2a.proto.Identity + 3, // 3: s2a.proto.S2AContext.local_identity:type_name -> s2a.proto.Identity + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_internal_proto_s2a_context_s2a_context_proto_init() } +func file_internal_proto_s2a_context_s2a_context_proto_init() { + if File_internal_proto_s2a_context_s2a_context_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*S2AContext); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_s2a_context_s2a_context_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_internal_proto_s2a_context_s2a_context_proto_goTypes, + DependencyIndexes: file_internal_proto_s2a_context_s2a_context_proto_depIdxs, + MessageInfos: file_internal_proto_s2a_context_s2a_context_proto_msgTypes, + }.Build() + File_internal_proto_s2a_context_s2a_context_proto = out.File + file_internal_proto_s2a_context_s2a_context_proto_rawDesc = nil + file_internal_proto_s2a_context_s2a_context_proto_goTypes = nil + file_internal_proto_s2a_context_s2a_context_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go b/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go new file mode 100644 index 00000000000..0a86ebee592 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go @@ -0,0 +1,1377 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/s2a/s2a.proto + +package s2a_go_proto + +import ( + common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AuthenticationMechanism struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // (Optional) Application may specify an identity associated to an + // authentication mechanism. Otherwise, S2A assumes that the authentication + // mechanism is associated with the default identity. If the default identity + // cannot be determined, session setup fails. + Identity *common_go_proto.Identity `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + // Types that are assignable to MechanismOneof: + // + // *AuthenticationMechanism_Token + MechanismOneof isAuthenticationMechanism_MechanismOneof `protobuf_oneof:"mechanism_oneof"` +} + +func (x *AuthenticationMechanism) Reset() { + *x = AuthenticationMechanism{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticationMechanism) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticationMechanism) ProtoMessage() {} + +func (x *AuthenticationMechanism) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthenticationMechanism.ProtoReflect.Descriptor instead. +func (*AuthenticationMechanism) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{0} +} + +func (x *AuthenticationMechanism) GetIdentity() *common_go_proto.Identity { + if x != nil { + return x.Identity + } + return nil +} + +func (m *AuthenticationMechanism) GetMechanismOneof() isAuthenticationMechanism_MechanismOneof { + if m != nil { + return m.MechanismOneof + } + return nil +} + +func (x *AuthenticationMechanism) GetToken() string { + if x, ok := x.GetMechanismOneof().(*AuthenticationMechanism_Token); ok { + return x.Token + } + return "" +} + +type isAuthenticationMechanism_MechanismOneof interface { + isAuthenticationMechanism_MechanismOneof() +} + +type AuthenticationMechanism_Token struct { + // A token that the application uses to authenticate itself to the S2A. + Token string `protobuf:"bytes,2,opt,name=token,proto3,oneof"` +} + +func (*AuthenticationMechanism_Token) isAuthenticationMechanism_MechanismOneof() {} + +type ClientSessionStartReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The application protocols supported by the client, e.g., "grpc". + ApplicationProtocols []string `protobuf:"bytes,1,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"` + // (Optional) The minimum TLS version number that the S2A's handshaker module + // will use to set up the session. If this field is not provided, S2A will use + // the minimum version it supports. + MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"min_tls_version,omitempty"` + // (Optional) The maximum TLS version number that the S2A's handshaker module + // will use to set up the session. If this field is not provided, S2A will use + // the maximum version it supports. + MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"max_tls_version,omitempty"` + // The TLS ciphersuites that the client is willing to support. + TlsCiphersuites []common_go_proto.Ciphersuite `protobuf:"varint,4,rep,packed,name=tls_ciphersuites,json=tlsCiphersuites,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuites,omitempty"` + // (Optional) Describes which server identities are acceptable by the client. + // If target identities are provided and none of them matches the peer + // identity of the server, session setup fails. + TargetIdentities []*common_go_proto.Identity `protobuf:"bytes,5,rep,name=target_identities,json=targetIdentities,proto3" json:"target_identities,omitempty"` + // (Optional) Application may specify a local identity. Otherwise, S2A chooses + // the default local identity. If the default identity cannot be determined, + // session setup fails. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,6,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The target name that is used by S2A to configure SNI in the TLS handshake. + // It is also used to perform server authorization check if avaiable. This + // check is intended to verify that the peer authenticated identity is + // authorized to run a service with the target name. + // This field MUST only contain the host portion of the server address. It + // MUST not contain the scheme or the port number. For example, if the server + // address is dns://www.example.com:443, the value of this field should be + // set to www.example.com. + TargetName string `protobuf:"bytes,7,opt,name=target_name,json=targetName,proto3" json:"target_name,omitempty"` +} + +func (x *ClientSessionStartReq) Reset() { + *x = ClientSessionStartReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientSessionStartReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientSessionStartReq) ProtoMessage() {} + +func (x *ClientSessionStartReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientSessionStartReq.ProtoReflect.Descriptor instead. +func (*ClientSessionStartReq) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{1} +} + +func (x *ClientSessionStartReq) GetApplicationProtocols() []string { + if x != nil { + return x.ApplicationProtocols + } + return nil +} + +func (x *ClientSessionStartReq) GetMinTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MinTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *ClientSessionStartReq) GetMaxTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MaxTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *ClientSessionStartReq) GetTlsCiphersuites() []common_go_proto.Ciphersuite { + if x != nil { + return x.TlsCiphersuites + } + return nil +} + +func (x *ClientSessionStartReq) GetTargetIdentities() []*common_go_proto.Identity { + if x != nil { + return x.TargetIdentities + } + return nil +} + +func (x *ClientSessionStartReq) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *ClientSessionStartReq) GetTargetName() string { + if x != nil { + return x.TargetName + } + return "" +} + +type ServerSessionStartReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The application protocols supported by the server, e.g., "grpc". + ApplicationProtocols []string `protobuf:"bytes,1,rep,name=application_protocols,json=applicationProtocols,proto3" json:"application_protocols,omitempty"` + // (Optional) The minimum TLS version number that the S2A's handshaker module + // will use to set up the session. If this field is not provided, S2A will use + // the minimum version it supports. + MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"min_tls_version,omitempty"` + // (Optional) The maximum TLS version number that the S2A's handshaker module + // will use to set up the session. If this field is not provided, S2A will use + // the maximum version it supports. + MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"max_tls_version,omitempty"` + // The TLS ciphersuites that the server is willing to support. + TlsCiphersuites []common_go_proto.Ciphersuite `protobuf:"varint,4,rep,packed,name=tls_ciphersuites,json=tlsCiphersuites,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuites,omitempty"` + // (Optional) A list of local identities supported by the server, if + // specified. Otherwise, S2A chooses the default local identity. If the + // default identity cannot be determined, session setup fails. + LocalIdentities []*common_go_proto.Identity `protobuf:"bytes,5,rep,name=local_identities,json=localIdentities,proto3" json:"local_identities,omitempty"` + // The byte representation of the first handshake message received from the + // client peer. It is possible that this first message is split into multiple + // chunks. In this case, the first chunk is sent using this field and the + // following chunks are sent using the in_bytes field of SessionNextReq + // Specifically, if the client peer is using S2A, this field contains the + // bytes in the out_frames field of SessionResp message that the client peer + // received from its S2A after initiating the handshake. + InBytes []byte `protobuf:"bytes,6,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` +} + +func (x *ServerSessionStartReq) Reset() { + *x = ServerSessionStartReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerSessionStartReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerSessionStartReq) ProtoMessage() {} + +func (x *ServerSessionStartReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerSessionStartReq.ProtoReflect.Descriptor instead. +func (*ServerSessionStartReq) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{2} +} + +func (x *ServerSessionStartReq) GetApplicationProtocols() []string { + if x != nil { + return x.ApplicationProtocols + } + return nil +} + +func (x *ServerSessionStartReq) GetMinTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MinTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *ServerSessionStartReq) GetMaxTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MaxTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *ServerSessionStartReq) GetTlsCiphersuites() []common_go_proto.Ciphersuite { + if x != nil { + return x.TlsCiphersuites + } + return nil +} + +func (x *ServerSessionStartReq) GetLocalIdentities() []*common_go_proto.Identity { + if x != nil { + return x.LocalIdentities + } + return nil +} + +func (x *ServerSessionStartReq) GetInBytes() []byte { + if x != nil { + return x.InBytes + } + return nil +} + +type SessionNextReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The byte representation of session setup, i.e., handshake messages. + // Specifically: + // - All handshake messages sent from the server to the client. + // - All, except for the first, handshake messages sent from the client to + // the server. Note that the first message is communicated to S2A using the + // in_bytes field of ServerSessionStartReq. + // + // If the peer is using S2A, this field contains the bytes in the out_frames + // field of SessionResp message that the peer received from its S2A. + InBytes []byte `protobuf:"bytes,1,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` +} + +func (x *SessionNextReq) Reset() { + *x = SessionNextReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionNextReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionNextReq) ProtoMessage() {} + +func (x *SessionNextReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionNextReq.ProtoReflect.Descriptor instead. +func (*SessionNextReq) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{3} +} + +func (x *SessionNextReq) GetInBytes() []byte { + if x != nil { + return x.InBytes + } + return nil +} + +type ResumptionTicketReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The byte representation of a NewSessionTicket message received from the + // server. + InBytes [][]byte `protobuf:"bytes,1,rep,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` + // A connection identifier that was created and sent by S2A at the end of a + // handshake. + ConnectionId uint64 `protobuf:"varint,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + // The local identity that was used by S2A during session setup and included + // in |SessionResult|. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,3,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` +} + +func (x *ResumptionTicketReq) Reset() { + *x = ResumptionTicketReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResumptionTicketReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumptionTicketReq) ProtoMessage() {} + +func (x *ResumptionTicketReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResumptionTicketReq.ProtoReflect.Descriptor instead. +func (*ResumptionTicketReq) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{4} +} + +func (x *ResumptionTicketReq) GetInBytes() [][]byte { + if x != nil { + return x.InBytes + } + return nil +} + +func (x *ResumptionTicketReq) GetConnectionId() uint64 { + if x != nil { + return x.ConnectionId + } + return 0 +} + +func (x *ResumptionTicketReq) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +type SessionReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to ReqOneof: + // + // *SessionReq_ClientStart + // *SessionReq_ServerStart + // *SessionReq_Next + // *SessionReq_ResumptionTicket + ReqOneof isSessionReq_ReqOneof `protobuf_oneof:"req_oneof"` + // (Optional) The authentication mechanisms that the client wishes to use to + // authenticate to the S2A, ordered by preference. The S2A will always use the + // first authentication mechanism that appears in the list and is supported by + // the S2A. + AuthMechanisms []*AuthenticationMechanism `protobuf:"bytes,5,rep,name=auth_mechanisms,json=authMechanisms,proto3" json:"auth_mechanisms,omitempty"` +} + +func (x *SessionReq) Reset() { + *x = SessionReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionReq) ProtoMessage() {} + +func (x *SessionReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionReq.ProtoReflect.Descriptor instead. +func (*SessionReq) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{5} +} + +func (m *SessionReq) GetReqOneof() isSessionReq_ReqOneof { + if m != nil { + return m.ReqOneof + } + return nil +} + +func (x *SessionReq) GetClientStart() *ClientSessionStartReq { + if x, ok := x.GetReqOneof().(*SessionReq_ClientStart); ok { + return x.ClientStart + } + return nil +} + +func (x *SessionReq) GetServerStart() *ServerSessionStartReq { + if x, ok := x.GetReqOneof().(*SessionReq_ServerStart); ok { + return x.ServerStart + } + return nil +} + +func (x *SessionReq) GetNext() *SessionNextReq { + if x, ok := x.GetReqOneof().(*SessionReq_Next); ok { + return x.Next + } + return nil +} + +func (x *SessionReq) GetResumptionTicket() *ResumptionTicketReq { + if x, ok := x.GetReqOneof().(*SessionReq_ResumptionTicket); ok { + return x.ResumptionTicket + } + return nil +} + +func (x *SessionReq) GetAuthMechanisms() []*AuthenticationMechanism { + if x != nil { + return x.AuthMechanisms + } + return nil +} + +type isSessionReq_ReqOneof interface { + isSessionReq_ReqOneof() +} + +type SessionReq_ClientStart struct { + // The client session setup request message. + ClientStart *ClientSessionStartReq `protobuf:"bytes,1,opt,name=client_start,json=clientStart,proto3,oneof"` +} + +type SessionReq_ServerStart struct { + // The server session setup request message. + ServerStart *ServerSessionStartReq `protobuf:"bytes,2,opt,name=server_start,json=serverStart,proto3,oneof"` +} + +type SessionReq_Next struct { + // The next session setup message request message. + Next *SessionNextReq `protobuf:"bytes,3,opt,name=next,proto3,oneof"` +} + +type SessionReq_ResumptionTicket struct { + // The resumption ticket that is received from the server. This message is + // only accepted by S2A if it is running as a client and if it is received + // after session setup is complete. If S2A is running as a server and it + // receives this message, the session is terminated. + ResumptionTicket *ResumptionTicketReq `protobuf:"bytes,4,opt,name=resumption_ticket,json=resumptionTicket,proto3,oneof"` +} + +func (*SessionReq_ClientStart) isSessionReq_ReqOneof() {} + +func (*SessionReq_ServerStart) isSessionReq_ReqOneof() {} + +func (*SessionReq_Next) isSessionReq_ReqOneof() {} + +func (*SessionReq_ResumptionTicket) isSessionReq_ReqOneof() {} + +type SessionState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The TLS version number that the S2A's handshaker module used to set up the + // session. + TlsVersion common_go_proto.TLSVersion `protobuf:"varint,1,opt,name=tls_version,json=tlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"tls_version,omitempty"` + // The TLS ciphersuite negotiated by the S2A's handshaker module. + TlsCiphersuite common_go_proto.Ciphersuite `protobuf:"varint,2,opt,name=tls_ciphersuite,json=tlsCiphersuite,proto3,enum=s2a.proto.Ciphersuite" json:"tls_ciphersuite,omitempty"` + // The sequence number of the next, incoming, TLS record. + InSequence uint64 `protobuf:"varint,3,opt,name=in_sequence,json=inSequence,proto3" json:"in_sequence,omitempty"` + // The sequence number of the next, outgoing, TLS record. + OutSequence uint64 `protobuf:"varint,4,opt,name=out_sequence,json=outSequence,proto3" json:"out_sequence,omitempty"` + // The key for the inbound direction. + InKey []byte `protobuf:"bytes,5,opt,name=in_key,json=inKey,proto3" json:"in_key,omitempty"` + // The key for the outbound direction. + OutKey []byte `protobuf:"bytes,6,opt,name=out_key,json=outKey,proto3" json:"out_key,omitempty"` + // The constant part of the record nonce for the outbound direction. + InFixedNonce []byte `protobuf:"bytes,7,opt,name=in_fixed_nonce,json=inFixedNonce,proto3" json:"in_fixed_nonce,omitempty"` + // The constant part of the record nonce for the inbound direction. + OutFixedNonce []byte `protobuf:"bytes,8,opt,name=out_fixed_nonce,json=outFixedNonce,proto3" json:"out_fixed_nonce,omitempty"` + // A connection identifier that can be provided to S2A to perform operations + // related to this connection. This identifier will be stored by the record + // protocol, and included in the |ResumptionTicketReq| message that is later + // sent back to S2A. This field is set only for client-side connections. + ConnectionId uint64 `protobuf:"varint,9,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + // Set to true if a cached session was reused to do an abbreviated handshake. + IsHandshakeResumed bool `protobuf:"varint,10,opt,name=is_handshake_resumed,json=isHandshakeResumed,proto3" json:"is_handshake_resumed,omitempty"` +} + +func (x *SessionState) Reset() { + *x = SessionState{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionState) ProtoMessage() {} + +func (x *SessionState) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionState.ProtoReflect.Descriptor instead. +func (*SessionState) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{6} +} + +func (x *SessionState) GetTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.TlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *SessionState) GetTlsCiphersuite() common_go_proto.Ciphersuite { + if x != nil { + return x.TlsCiphersuite + } + return common_go_proto.Ciphersuite(0) +} + +func (x *SessionState) GetInSequence() uint64 { + if x != nil { + return x.InSequence + } + return 0 +} + +func (x *SessionState) GetOutSequence() uint64 { + if x != nil { + return x.OutSequence + } + return 0 +} + +func (x *SessionState) GetInKey() []byte { + if x != nil { + return x.InKey + } + return nil +} + +func (x *SessionState) GetOutKey() []byte { + if x != nil { + return x.OutKey + } + return nil +} + +func (x *SessionState) GetInFixedNonce() []byte { + if x != nil { + return x.InFixedNonce + } + return nil +} + +func (x *SessionState) GetOutFixedNonce() []byte { + if x != nil { + return x.OutFixedNonce + } + return nil +} + +func (x *SessionState) GetConnectionId() uint64 { + if x != nil { + return x.ConnectionId + } + return 0 +} + +func (x *SessionState) GetIsHandshakeResumed() bool { + if x != nil { + return x.IsHandshakeResumed + } + return false +} + +type SessionResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The application protocol negotiated for this session. + ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"` + // The session state at the end. This state contains all cryptographic + // material required to initialize the record protocol object. + State *SessionState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + // The authenticated identity of the peer. + PeerIdentity *common_go_proto.Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"` + // The local identity used during session setup. This could be: + // - The local identity that the client specifies in ClientSessionStartReq. + // - One of the local identities that the server specifies in + // ServerSessionStartReq. + // - If neither client or server specifies local identities, the S2A picks the + // default one. In this case, this field will contain that identity. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The SHA256 hash of the local certificate used in the handshake. + LocalCertFingerprint []byte `protobuf:"bytes,6,opt,name=local_cert_fingerprint,json=localCertFingerprint,proto3" json:"local_cert_fingerprint,omitempty"` + // The SHA256 hash of the peer certificate used in the handshake. + PeerCertFingerprint []byte `protobuf:"bytes,7,opt,name=peer_cert_fingerprint,json=peerCertFingerprint,proto3" json:"peer_cert_fingerprint,omitempty"` +} + +func (x *SessionResult) Reset() { + *x = SessionResult{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionResult) ProtoMessage() {} + +func (x *SessionResult) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionResult.ProtoReflect.Descriptor instead. +func (*SessionResult) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{7} +} + +func (x *SessionResult) GetApplicationProtocol() string { + if x != nil { + return x.ApplicationProtocol + } + return "" +} + +func (x *SessionResult) GetState() *SessionState { + if x != nil { + return x.State + } + return nil +} + +func (x *SessionResult) GetPeerIdentity() *common_go_proto.Identity { + if x != nil { + return x.PeerIdentity + } + return nil +} + +func (x *SessionResult) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *SessionResult) GetLocalCertFingerprint() []byte { + if x != nil { + return x.LocalCertFingerprint + } + return nil +} + +func (x *SessionResult) GetPeerCertFingerprint() []byte { + if x != nil { + return x.PeerCertFingerprint + } + return nil +} + +type SessionStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The status code that is specific to the application and the implementation + // of S2A, e.g., gRPC status code. + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + // The status details. + Details string `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"` +} + +func (x *SessionStatus) Reset() { + *x = SessionStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionStatus) ProtoMessage() {} + +func (x *SessionStatus) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionStatus.ProtoReflect.Descriptor instead. +func (*SessionStatus) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{8} +} + +func (x *SessionStatus) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *SessionStatus) GetDetails() string { + if x != nil { + return x.Details + } + return "" +} + +type SessionResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The local identity used during session setup. This could be: + // - The local identity that the client specifies in ClientSessionStartReq. + // - One of the local identities that the server specifies in + // ServerSessionStartReq. + // - If neither client or server specifies local identities, the S2A picks the + // default one. In this case, this field will contain that identity. + // + // If the SessionResult is populated, then this must coincide with the local + // identity specified in the SessionResult; otherwise, the handshake must + // fail. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,1,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The byte representation of the frames that should be sent to the peer. May + // be empty if nothing needs to be sent to the peer or if in_bytes in the + // SessionReq is incomplete. All bytes in a non-empty out_frames must be sent + // to the peer even if the session setup status is not OK as these frames may + // contain appropriate alerts. + OutFrames []byte `protobuf:"bytes,2,opt,name=out_frames,json=outFrames,proto3" json:"out_frames,omitempty"` + // Number of bytes in the in_bytes field that are consumed by S2A. It is + // possible that part of in_bytes is unrelated to the session setup process. + BytesConsumed uint32 `protobuf:"varint,3,opt,name=bytes_consumed,json=bytesConsumed,proto3" json:"bytes_consumed,omitempty"` + // This is set if the session is successfully set up. out_frames may + // still be set to frames that needs to be forwarded to the peer. + Result *SessionResult `protobuf:"bytes,4,opt,name=result,proto3" json:"result,omitempty"` + // Status of session setup at the current stage. + Status *SessionStatus `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *SessionResp) Reset() { + *x = SessionResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionResp) ProtoMessage() {} + +func (x *SessionResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_s2a_s2a_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionResp.ProtoReflect.Descriptor instead. +func (*SessionResp) Descriptor() ([]byte, []int) { + return file_internal_proto_s2a_s2a_proto_rawDescGZIP(), []int{9} +} + +func (x *SessionResp) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *SessionResp) GetOutFrames() []byte { + if x != nil { + return x.OutFrames + } + return nil +} + +func (x *SessionResp) GetBytesConsumed() uint32 { + if x != nil { + return x.BytesConsumed + } + return 0 +} + +func (x *SessionResp) GetResult() *SessionResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *SessionResp) GetStatus() *SessionStatus { + if x != nil { + return x.Status + } + return nil +} + +var File_internal_proto_s2a_s2a_proto protoreflect.FileDescriptor + +var file_internal_proto_s2a_s2a_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, + 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x75, 0x0a, + 0x17, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x12, 0x2f, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, + 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x5f, 0x6f, + 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xac, 0x03, 0x0a, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x33, + 0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x73, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, + 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x41, 0x0a, 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x52, 0x0f, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0xe8, 0x02, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x33, 0x0a, + 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x73, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3d, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x41, 0x0a, 0x10, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, + 0x74, 0x65, 0x52, 0x0f, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, + 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x2b, + 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, + 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x13, + 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, + 0xf4, 0x02, 0x0a, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x45, + 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, + 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2f, 0x0a, 0x04, + 0x6e, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x65, + 0x78, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x12, 0x4d, 0x0a, + 0x11, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x63, 0x6b, + 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x69, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x10, 0x72, 0x65, 0x73, 0x75, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x4b, 0x0a, 0x0f, + 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x4d, + 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x72, 0x65, 0x71, + 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xa0, 0x03, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x74, 0x6c, 0x73, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, + 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x74, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x3f, 0x0a, 0x0f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x52, 0x0e, 0x74, 0x6c, 0x73, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x6f, + 0x75, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, + 0x74, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x69, 0x6e, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, + 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x69, 0x6e, + 0x46, 0x69, 0x78, 0x65, 0x64, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x75, + 0x74, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x46, 0x69, 0x78, 0x65, 0x64, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x68, 0x61, + 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, + 0x6b, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x22, 0xd1, 0x02, 0x0a, 0x0d, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x2d, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, + 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70, 0x65, 0x65, 0x72, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x14, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x46, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x65, + 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, + 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x3d, 0x0a, + 0x0d, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xf3, 0x01, 0x0a, + 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3a, 0x0a, 0x0e, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, + 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, + 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0d, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x30, + 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x32, 0x51, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x43, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x55, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x15, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, + 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x32, + 0x61, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_internal_proto_s2a_s2a_proto_rawDescOnce sync.Once + file_internal_proto_s2a_s2a_proto_rawDescData = file_internal_proto_s2a_s2a_proto_rawDesc +) + +func file_internal_proto_s2a_s2a_proto_rawDescGZIP() []byte { + file_internal_proto_s2a_s2a_proto_rawDescOnce.Do(func() { + file_internal_proto_s2a_s2a_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_s2a_s2a_proto_rawDescData) + }) + return file_internal_proto_s2a_s2a_proto_rawDescData +} + +var file_internal_proto_s2a_s2a_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_internal_proto_s2a_s2a_proto_goTypes = []interface{}{ + (*AuthenticationMechanism)(nil), // 0: s2a.proto.AuthenticationMechanism + (*ClientSessionStartReq)(nil), // 1: s2a.proto.ClientSessionStartReq + (*ServerSessionStartReq)(nil), // 2: s2a.proto.ServerSessionStartReq + (*SessionNextReq)(nil), // 3: s2a.proto.SessionNextReq + (*ResumptionTicketReq)(nil), // 4: s2a.proto.ResumptionTicketReq + (*SessionReq)(nil), // 5: s2a.proto.SessionReq + (*SessionState)(nil), // 6: s2a.proto.SessionState + (*SessionResult)(nil), // 7: s2a.proto.SessionResult + (*SessionStatus)(nil), // 8: s2a.proto.SessionStatus + (*SessionResp)(nil), // 9: s2a.proto.SessionResp + (*common_go_proto.Identity)(nil), // 10: s2a.proto.Identity + (common_go_proto.TLSVersion)(0), // 11: s2a.proto.TLSVersion + (common_go_proto.Ciphersuite)(0), // 12: s2a.proto.Ciphersuite +} +var file_internal_proto_s2a_s2a_proto_depIdxs = []int32{ + 10, // 0: s2a.proto.AuthenticationMechanism.identity:type_name -> s2a.proto.Identity + 11, // 1: s2a.proto.ClientSessionStartReq.min_tls_version:type_name -> s2a.proto.TLSVersion + 11, // 2: s2a.proto.ClientSessionStartReq.max_tls_version:type_name -> s2a.proto.TLSVersion + 12, // 3: s2a.proto.ClientSessionStartReq.tls_ciphersuites:type_name -> s2a.proto.Ciphersuite + 10, // 4: s2a.proto.ClientSessionStartReq.target_identities:type_name -> s2a.proto.Identity + 10, // 5: s2a.proto.ClientSessionStartReq.local_identity:type_name -> s2a.proto.Identity + 11, // 6: s2a.proto.ServerSessionStartReq.min_tls_version:type_name -> s2a.proto.TLSVersion + 11, // 7: s2a.proto.ServerSessionStartReq.max_tls_version:type_name -> s2a.proto.TLSVersion + 12, // 8: s2a.proto.ServerSessionStartReq.tls_ciphersuites:type_name -> s2a.proto.Ciphersuite + 10, // 9: s2a.proto.ServerSessionStartReq.local_identities:type_name -> s2a.proto.Identity + 10, // 10: s2a.proto.ResumptionTicketReq.local_identity:type_name -> s2a.proto.Identity + 1, // 11: s2a.proto.SessionReq.client_start:type_name -> s2a.proto.ClientSessionStartReq + 2, // 12: s2a.proto.SessionReq.server_start:type_name -> s2a.proto.ServerSessionStartReq + 3, // 13: s2a.proto.SessionReq.next:type_name -> s2a.proto.SessionNextReq + 4, // 14: s2a.proto.SessionReq.resumption_ticket:type_name -> s2a.proto.ResumptionTicketReq + 0, // 15: s2a.proto.SessionReq.auth_mechanisms:type_name -> s2a.proto.AuthenticationMechanism + 11, // 16: s2a.proto.SessionState.tls_version:type_name -> s2a.proto.TLSVersion + 12, // 17: s2a.proto.SessionState.tls_ciphersuite:type_name -> s2a.proto.Ciphersuite + 6, // 18: s2a.proto.SessionResult.state:type_name -> s2a.proto.SessionState + 10, // 19: s2a.proto.SessionResult.peer_identity:type_name -> s2a.proto.Identity + 10, // 20: s2a.proto.SessionResult.local_identity:type_name -> s2a.proto.Identity + 10, // 21: s2a.proto.SessionResp.local_identity:type_name -> s2a.proto.Identity + 7, // 22: s2a.proto.SessionResp.result:type_name -> s2a.proto.SessionResult + 8, // 23: s2a.proto.SessionResp.status:type_name -> s2a.proto.SessionStatus + 5, // 24: s2a.proto.S2AService.SetUpSession:input_type -> s2a.proto.SessionReq + 9, // 25: s2a.proto.S2AService.SetUpSession:output_type -> s2a.proto.SessionResp + 25, // [25:26] is the sub-list for method output_type + 24, // [24:25] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name +} + +func init() { file_internal_proto_s2a_s2a_proto_init() } +func file_internal_proto_s2a_s2a_proto_init() { + if File_internal_proto_s2a_s2a_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_proto_s2a_s2a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticationMechanism); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientSessionStartReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerSessionStartReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionNextReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResumptionTicketReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_internal_proto_s2a_s2a_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*AuthenticationMechanism_Token)(nil), + } + file_internal_proto_s2a_s2a_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*SessionReq_ClientStart)(nil), + (*SessionReq_ServerStart)(nil), + (*SessionReq_Next)(nil), + (*SessionReq_ResumptionTicket)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_s2a_s2a_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_internal_proto_s2a_s2a_proto_goTypes, + DependencyIndexes: file_internal_proto_s2a_s2a_proto_depIdxs, + MessageInfos: file_internal_proto_s2a_s2a_proto_msgTypes, + }.Build() + File_internal_proto_s2a_s2a_proto = out.File + file_internal_proto_s2a_s2a_proto_rawDesc = nil + file_internal_proto_s2a_s2a_proto_goTypes = nil + file_internal_proto_s2a_s2a_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go b/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go new file mode 100644 index 00000000000..0fa582fc874 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go @@ -0,0 +1,173 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: internal/proto/s2a/s2a.proto + +package s2a_go_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + S2AService_SetUpSession_FullMethodName = "/s2a.proto.S2AService/SetUpSession" +) + +// S2AServiceClient is the client API for S2AService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type S2AServiceClient interface { + // S2A service accepts a stream of session setup requests and returns a stream + // of session setup responses. The client of this service is expected to send + // exactly one client_start or server_start message followed by at least one + // next message. Applications running TLS clients can send requests with + // resumption_ticket messages only after the session is successfully set up. + // + // Every time S2A client sends a request, this service sends a response. + // However, clients do not have to wait for service response before sending + // the next request. + SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) +} + +type s2AServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient { + return &s2AServiceClient{cc} +} + +func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) { + stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &s2AServiceSetUpSessionClient{stream} + return x, nil +} + +type S2AService_SetUpSessionClient interface { + Send(*SessionReq) error + Recv() (*SessionResp, error) + grpc.ClientStream +} + +type s2AServiceSetUpSessionClient struct { + grpc.ClientStream +} + +func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error { + return x.ClientStream.SendMsg(m) +} + +func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) { + m := new(SessionResp) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// S2AServiceServer is the server API for S2AService service. +// All implementations must embed UnimplementedS2AServiceServer +// for forward compatibility +type S2AServiceServer interface { + // S2A service accepts a stream of session setup requests and returns a stream + // of session setup responses. The client of this service is expected to send + // exactly one client_start or server_start message followed by at least one + // next message. Applications running TLS clients can send requests with + // resumption_ticket messages only after the session is successfully set up. + // + // Every time S2A client sends a request, this service sends a response. + // However, clients do not have to wait for service response before sending + // the next request. + SetUpSession(S2AService_SetUpSessionServer) error + mustEmbedUnimplementedS2AServiceServer() +} + +// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations. +type UnimplementedS2AServiceServer struct { +} + +func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error { + return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented") +} +func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {} + +// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to S2AServiceServer will +// result in compilation errors. +type UnsafeS2AServiceServer interface { + mustEmbedUnimplementedS2AServiceServer() +} + +func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) { + s.RegisterService(&S2AService_ServiceDesc, srv) +} + +func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream}) +} + +type S2AService_SetUpSessionServer interface { + Send(*SessionResp) error + Recv() (*SessionReq, error) + grpc.ServerStream +} + +type s2AServiceSetUpSessionServer struct { + grpc.ServerStream +} + +func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error { + return x.ServerStream.SendMsg(m) +} + +func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) { + m := new(SessionReq) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var S2AService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "s2a.proto.S2AService", + HandlerType: (*S2AServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "SetUpSession", + Handler: _S2AService_SetUpSession_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "internal/proto/s2a/s2a.proto", +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go b/vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go new file mode 100644 index 00000000000..c84bed97748 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go @@ -0,0 +1,367 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/v2/common/common.proto + +package common_go_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The TLS 1.0-1.2 ciphersuites that the application can negotiate when using +// S2A. +type Ciphersuite int32 + +const ( + Ciphersuite_CIPHERSUITE_UNSPECIFIED Ciphersuite = 0 + Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 Ciphersuite = 1 + Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Ciphersuite = 2 + Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 Ciphersuite = 3 + Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Ciphersuite = 4 + Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384 Ciphersuite = 5 + Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Ciphersuite = 6 +) + +// Enum value maps for Ciphersuite. +var ( + Ciphersuite_name = map[int32]string{ + 0: "CIPHERSUITE_UNSPECIFIED", + 1: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + 2: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + 3: "CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + 4: "CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + 5: "CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + 6: "CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + } + Ciphersuite_value = map[string]int32{ + "CIPHERSUITE_UNSPECIFIED": 0, + "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": 1, + "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": 2, + "CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": 3, + "CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256": 4, + "CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384": 5, + "CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": 6, + } +) + +func (x Ciphersuite) Enum() *Ciphersuite { + p := new(Ciphersuite) + *p = x + return p +} + +func (x Ciphersuite) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_common_common_proto_enumTypes[0].Descriptor() +} + +func (Ciphersuite) Type() protoreflect.EnumType { + return &file_internal_proto_v2_common_common_proto_enumTypes[0] +} + +func (x Ciphersuite) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Ciphersuite.Descriptor instead. +func (Ciphersuite) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{0} +} + +// The TLS versions supported by S2A's handshaker module. +type TLSVersion int32 + +const ( + TLSVersion_TLS_VERSION_UNSPECIFIED TLSVersion = 0 + TLSVersion_TLS_VERSION_1_0 TLSVersion = 1 + TLSVersion_TLS_VERSION_1_1 TLSVersion = 2 + TLSVersion_TLS_VERSION_1_2 TLSVersion = 3 + TLSVersion_TLS_VERSION_1_3 TLSVersion = 4 +) + +// Enum value maps for TLSVersion. +var ( + TLSVersion_name = map[int32]string{ + 0: "TLS_VERSION_UNSPECIFIED", + 1: "TLS_VERSION_1_0", + 2: "TLS_VERSION_1_1", + 3: "TLS_VERSION_1_2", + 4: "TLS_VERSION_1_3", + } + TLSVersion_value = map[string]int32{ + "TLS_VERSION_UNSPECIFIED": 0, + "TLS_VERSION_1_0": 1, + "TLS_VERSION_1_1": 2, + "TLS_VERSION_1_2": 3, + "TLS_VERSION_1_3": 4, + } +) + +func (x TLSVersion) Enum() *TLSVersion { + p := new(TLSVersion) + *p = x + return p +} + +func (x TLSVersion) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TLSVersion) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_common_common_proto_enumTypes[1].Descriptor() +} + +func (TLSVersion) Type() protoreflect.EnumType { + return &file_internal_proto_v2_common_common_proto_enumTypes[1] +} + +func (x TLSVersion) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TLSVersion.Descriptor instead. +func (TLSVersion) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{1} +} + +// The side in the TLS connection. +type ConnectionSide int32 + +const ( + ConnectionSide_CONNECTION_SIDE_UNSPECIFIED ConnectionSide = 0 + ConnectionSide_CONNECTION_SIDE_CLIENT ConnectionSide = 1 + ConnectionSide_CONNECTION_SIDE_SERVER ConnectionSide = 2 +) + +// Enum value maps for ConnectionSide. +var ( + ConnectionSide_name = map[int32]string{ + 0: "CONNECTION_SIDE_UNSPECIFIED", + 1: "CONNECTION_SIDE_CLIENT", + 2: "CONNECTION_SIDE_SERVER", + } + ConnectionSide_value = map[string]int32{ + "CONNECTION_SIDE_UNSPECIFIED": 0, + "CONNECTION_SIDE_CLIENT": 1, + "CONNECTION_SIDE_SERVER": 2, + } +) + +func (x ConnectionSide) Enum() *ConnectionSide { + p := new(ConnectionSide) + *p = x + return p +} + +func (x ConnectionSide) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ConnectionSide) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_common_common_proto_enumTypes[2].Descriptor() +} + +func (ConnectionSide) Type() protoreflect.EnumType { + return &file_internal_proto_v2_common_common_proto_enumTypes[2] +} + +func (x ConnectionSide) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ConnectionSide.Descriptor instead. +func (ConnectionSide) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{2} +} + +// The ALPN protocols that the application can negotiate during a TLS handshake. +type AlpnProtocol int32 + +const ( + AlpnProtocol_ALPN_PROTOCOL_UNSPECIFIED AlpnProtocol = 0 + AlpnProtocol_ALPN_PROTOCOL_GRPC AlpnProtocol = 1 + AlpnProtocol_ALPN_PROTOCOL_HTTP2 AlpnProtocol = 2 + AlpnProtocol_ALPN_PROTOCOL_HTTP1_1 AlpnProtocol = 3 +) + +// Enum value maps for AlpnProtocol. +var ( + AlpnProtocol_name = map[int32]string{ + 0: "ALPN_PROTOCOL_UNSPECIFIED", + 1: "ALPN_PROTOCOL_GRPC", + 2: "ALPN_PROTOCOL_HTTP2", + 3: "ALPN_PROTOCOL_HTTP1_1", + } + AlpnProtocol_value = map[string]int32{ + "ALPN_PROTOCOL_UNSPECIFIED": 0, + "ALPN_PROTOCOL_GRPC": 1, + "ALPN_PROTOCOL_HTTP2": 2, + "ALPN_PROTOCOL_HTTP1_1": 3, + } +) + +func (x AlpnProtocol) Enum() *AlpnProtocol { + p := new(AlpnProtocol) + *p = x + return p +} + +func (x AlpnProtocol) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AlpnProtocol) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_common_common_proto_enumTypes[3].Descriptor() +} + +func (AlpnProtocol) Type() protoreflect.EnumType { + return &file_internal_proto_v2_common_common_proto_enumTypes[3] +} + +func (x AlpnProtocol) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AlpnProtocol.Descriptor instead. +func (AlpnProtocol) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{3} +} + +var File_internal_proto_v2_common_common_proto protoreflect.FileDescriptor + +var file_internal_proto_v2_common_common_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2a, 0xee, 0x02, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, + 0x73, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, + 0x55, 0x49, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, + 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49, + 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, + 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x01, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45, + 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, + 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, + 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x39, 0x0a, 0x35, + 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, + 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41, + 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, + 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x03, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49, 0x50, 0x48, 0x45, + 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, + 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, + 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x04, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49, + 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, + 0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, + 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x05, 0x12, 0x37, 0x0a, + 0x33, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, + 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41, 0x43, + 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48, + 0x41, 0x32, 0x35, 0x36, 0x10, 0x06, 0x2a, 0x7d, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, + 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, + 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x32, 0x10, 0x03, + 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x31, 0x5f, 0x33, 0x10, 0x04, 0x2a, 0x69, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, + 0x2a, 0x79, 0x0a, 0x0c, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, + 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x16, 0x0a, 0x12, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, + 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x50, 0x4e, 0x5f, + 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x02, + 0x12, 0x19, 0x0a, 0x15, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, + 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x31, 0x5f, 0x31, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_proto_v2_common_common_proto_rawDescOnce sync.Once + file_internal_proto_v2_common_common_proto_rawDescData = file_internal_proto_v2_common_common_proto_rawDesc +) + +func file_internal_proto_v2_common_common_proto_rawDescGZIP() []byte { + file_internal_proto_v2_common_common_proto_rawDescOnce.Do(func() { + file_internal_proto_v2_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_common_common_proto_rawDescData) + }) + return file_internal_proto_v2_common_common_proto_rawDescData +} + +var file_internal_proto_v2_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_internal_proto_v2_common_common_proto_goTypes = []interface{}{ + (Ciphersuite)(0), // 0: s2a.proto.v2.Ciphersuite + (TLSVersion)(0), // 1: s2a.proto.v2.TLSVersion + (ConnectionSide)(0), // 2: s2a.proto.v2.ConnectionSide + (AlpnProtocol)(0), // 3: s2a.proto.v2.AlpnProtocol +} +var file_internal_proto_v2_common_common_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_internal_proto_v2_common_common_proto_init() } +func file_internal_proto_v2_common_common_proto_init() { + if File_internal_proto_v2_common_common_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_v2_common_common_proto_rawDesc, + NumEnums: 4, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_internal_proto_v2_common_common_proto_goTypes, + DependencyIndexes: file_internal_proto_v2_common_common_proto_depIdxs, + EnumInfos: file_internal_proto_v2_common_common_proto_enumTypes, + }.Build() + File_internal_proto_v2_common_common_proto = out.File + file_internal_proto_v2_common_common_proto_rawDesc = nil + file_internal_proto_v2_common_common_proto_goTypes = nil + file_internal_proto_v2_common_common_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go new file mode 100644 index 00000000000..b7fd871c7a7 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go @@ -0,0 +1,248 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/v2/s2a_context/s2a_context.proto + +package s2a_context_go_proto + +import ( + common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type S2AContext struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The SPIFFE ID from the peer leaf certificate, if present. + // + // This field is only populated if the leaf certificate is a valid SPIFFE + // SVID; in particular, there is a unique URI SAN and this URI SAN is a valid + // SPIFFE ID. + LeafCertSpiffeId string `protobuf:"bytes,1,opt,name=leaf_cert_spiffe_id,json=leafCertSpiffeId,proto3" json:"leaf_cert_spiffe_id,omitempty"` + // The URIs that are present in the SubjectAltName extension of the peer leaf + // certificate. + // + // Note that the extracted URIs are not validated and may not be properly + // formatted. + LeafCertUris []string `protobuf:"bytes,2,rep,name=leaf_cert_uris,json=leafCertUris,proto3" json:"leaf_cert_uris,omitempty"` + // The DNSNames that are present in the SubjectAltName extension of the peer + // leaf certificate. + LeafCertDnsnames []string `protobuf:"bytes,3,rep,name=leaf_cert_dnsnames,json=leafCertDnsnames,proto3" json:"leaf_cert_dnsnames,omitempty"` + // The (ordered) list of fingerprints in the certificate chain used to verify + // the given leaf certificate. The order MUST be from leaf certificate + // fingerprint to root certificate fingerprint. + // + // A fingerprint is the base-64 encoding of the SHA256 hash of the + // DER-encoding of a certificate. The list MAY be populated even if the peer + // certificate chain was NOT validated successfully. + PeerCertificateChainFingerprints []string `protobuf:"bytes,4,rep,name=peer_certificate_chain_fingerprints,json=peerCertificateChainFingerprints,proto3" json:"peer_certificate_chain_fingerprints,omitempty"` + // The local identity used during session setup. + LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The SHA256 hash of the DER-encoding of the local leaf certificate used in + // the handshake. + LocalLeafCertFingerprint []byte `protobuf:"bytes,6,opt,name=local_leaf_cert_fingerprint,json=localLeafCertFingerprint,proto3" json:"local_leaf_cert_fingerprint,omitempty"` +} + +func (x *S2AContext) Reset() { + *x = S2AContext{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *S2AContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*S2AContext) ProtoMessage() {} + +func (x *S2AContext) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead. +func (*S2AContext) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0} +} + +func (x *S2AContext) GetLeafCertSpiffeId() string { + if x != nil { + return x.LeafCertSpiffeId + } + return "" +} + +func (x *S2AContext) GetLeafCertUris() []string { + if x != nil { + return x.LeafCertUris + } + return nil +} + +func (x *S2AContext) GetLeafCertDnsnames() []string { + if x != nil { + return x.LeafCertDnsnames + } + return nil +} + +func (x *S2AContext) GetPeerCertificateChainFingerprints() []string { + if x != nil { + return x.PeerCertificateChainFingerprints + } + return nil +} + +func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *S2AContext) GetLocalLeafCertFingerprint() []byte { + if x != nil { + return x.LocalLeafCertFingerprint + } + return nil +} + +var File_internal_proto_v2_s2a_context_s2a_context_proto protoreflect.FileDescriptor + +var file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x1a, + 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x02, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, + 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, + 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75, + 0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x66, 0x43, + 0x65, 0x72, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x61, 0x66, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x5f, 0x64, 0x6e, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x44, 0x6e, 0x73, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x23, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x20, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, + 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x12, 0x3d, 0x0a, 0x1b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4c, 0x65, 0x61, 0x66, + 0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x42, + 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce sync.Once + file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc +) + +func file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP() []byte { + file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce.Do(func() { + file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData) + }) + return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData +} + +var file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = []interface{}{ + (*S2AContext)(nil), // 0: s2a.proto.v2.S2AContext + (*common_go_proto.Identity)(nil), // 1: s2a.proto.Identity +} +var file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = []int32{ + 1, // 0: s2a.proto.v2.S2AContext.local_identity:type_name -> s2a.proto.Identity + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_internal_proto_v2_s2a_context_s2a_context_proto_init() } +func file_internal_proto_v2_s2a_context_s2a_context_proto_init() { + if File_internal_proto_v2_s2a_context_s2a_context_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*S2AContext); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes, + DependencyIndexes: file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs, + MessageInfos: file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes, + }.Build() + File_internal_proto_v2_s2a_context_s2a_context_proto = out.File + file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = nil + file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = nil + file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go new file mode 100644 index 00000000000..e843450c7ed --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go @@ -0,0 +1,2494 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: internal/proto/v2/s2a/s2a.proto + +package s2a_go_proto + +import ( + common_go_proto1 "github.com/google/s2a-go/internal/proto/common_go_proto" + common_go_proto "github.com/google/s2a-go/internal/proto/v2/common_go_proto" + s2a_context_go_proto "github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SignatureAlgorithm int32 + +const ( + SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED SignatureAlgorithm = 0 + // RSA Public-Key Cryptography Standards #1. + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256 SignatureAlgorithm = 1 + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384 SignatureAlgorithm = 2 + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512 SignatureAlgorithm = 3 + // ECDSA. + SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256 SignatureAlgorithm = 4 + SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384 SignatureAlgorithm = 5 + SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512 SignatureAlgorithm = 6 + // RSA Probabilistic Signature Scheme. + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256 SignatureAlgorithm = 7 + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384 SignatureAlgorithm = 8 + SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512 SignatureAlgorithm = 9 + // ED25519. + SignatureAlgorithm_S2A_SSL_SIGN_ED25519 SignatureAlgorithm = 10 +) + +// Enum value maps for SignatureAlgorithm. +var ( + SignatureAlgorithm_name = map[int32]string{ + 0: "S2A_SSL_SIGN_UNSPECIFIED", + 1: "S2A_SSL_SIGN_RSA_PKCS1_SHA256", + 2: "S2A_SSL_SIGN_RSA_PKCS1_SHA384", + 3: "S2A_SSL_SIGN_RSA_PKCS1_SHA512", + 4: "S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256", + 5: "S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384", + 6: "S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512", + 7: "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256", + 8: "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384", + 9: "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512", + 10: "S2A_SSL_SIGN_ED25519", + } + SignatureAlgorithm_value = map[string]int32{ + "S2A_SSL_SIGN_UNSPECIFIED": 0, + "S2A_SSL_SIGN_RSA_PKCS1_SHA256": 1, + "S2A_SSL_SIGN_RSA_PKCS1_SHA384": 2, + "S2A_SSL_SIGN_RSA_PKCS1_SHA512": 3, + "S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256": 4, + "S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384": 5, + "S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512": 6, + "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256": 7, + "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384": 8, + "S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512": 9, + "S2A_SSL_SIGN_ED25519": 10, + } +) + +func (x SignatureAlgorithm) Enum() *SignatureAlgorithm { + p := new(SignatureAlgorithm) + *p = x + return p +} + +func (x SignatureAlgorithm) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SignatureAlgorithm) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[0].Descriptor() +} + +func (SignatureAlgorithm) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[0] +} + +func (x SignatureAlgorithm) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SignatureAlgorithm.Descriptor instead. +func (SignatureAlgorithm) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{0} +} + +type GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate int32 + +const ( + GetTlsConfigurationResp_ServerTlsConfiguration_UNSPECIFIED GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 0 + GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 1 + GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 2 + GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 3 + GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 4 + GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate = 5 +) + +// Enum value maps for GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate. +var ( + GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "DONT_REQUEST_CLIENT_CERTIFICATE", + 2: "REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY", + 3: "REQUEST_CLIENT_CERTIFICATE_AND_VERIFY", + 4: "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY", + 5: "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY", + } + GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate_value = map[string]int32{ + "UNSPECIFIED": 0, + "DONT_REQUEST_CLIENT_CERTIFICATE": 1, + "REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY": 2, + "REQUEST_CLIENT_CERTIFICATE_AND_VERIFY": 3, + "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY": 4, + "REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY": 5, + } +) + +func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Enum() *GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate { + p := new(GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) + *p = x + return p +} + +func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[1].Descriptor() +} + +func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[1] +} + +func (x GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate.Descriptor instead. +func (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 1, 0} +} + +type OffloadPrivateKeyOperationReq_PrivateKeyOperation int32 + +const ( + OffloadPrivateKeyOperationReq_UNSPECIFIED OffloadPrivateKeyOperationReq_PrivateKeyOperation = 0 + // When performing a TLS 1.2 or 1.3 handshake, the (partial) transcript of + // the TLS handshake must be signed to prove possession of the private key. + // + // See https://www.rfc-editor.org/rfc/rfc8446.html#section-4.4.3. + OffloadPrivateKeyOperationReq_SIGN OffloadPrivateKeyOperationReq_PrivateKeyOperation = 1 + // When performing a TLS 1.2 handshake using an RSA algorithm, the key + // exchange algorithm involves the client generating a premaster secret, + // encrypting it using the server's public key, and sending this encrypted + // blob to the server in a ClientKeyExchange message. + // + // See https://www.rfc-editor.org/rfc/rfc4346#section-7.4.7.1. + OffloadPrivateKeyOperationReq_DECRYPT OffloadPrivateKeyOperationReq_PrivateKeyOperation = 2 +) + +// Enum value maps for OffloadPrivateKeyOperationReq_PrivateKeyOperation. +var ( + OffloadPrivateKeyOperationReq_PrivateKeyOperation_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "SIGN", + 2: "DECRYPT", + } + OffloadPrivateKeyOperationReq_PrivateKeyOperation_value = map[string]int32{ + "UNSPECIFIED": 0, + "SIGN": 1, + "DECRYPT": 2, + } +) + +func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) Enum() *OffloadPrivateKeyOperationReq_PrivateKeyOperation { + p := new(OffloadPrivateKeyOperationReq_PrivateKeyOperation) + *p = x + return p +} + +func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[2].Descriptor() +} + +func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[2] +} + +func (x OffloadPrivateKeyOperationReq_PrivateKeyOperation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OffloadPrivateKeyOperationReq_PrivateKeyOperation.Descriptor instead. +func (OffloadPrivateKeyOperationReq_PrivateKeyOperation) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{5, 0} +} + +type OffloadResumptionKeyOperationReq_ResumptionKeyOperation int32 + +const ( + OffloadResumptionKeyOperationReq_UNSPECIFIED OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 0 + OffloadResumptionKeyOperationReq_ENCRYPT OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 1 + OffloadResumptionKeyOperationReq_DECRYPT OffloadResumptionKeyOperationReq_ResumptionKeyOperation = 2 +) + +// Enum value maps for OffloadResumptionKeyOperationReq_ResumptionKeyOperation. +var ( + OffloadResumptionKeyOperationReq_ResumptionKeyOperation_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "ENCRYPT", + 2: "DECRYPT", + } + OffloadResumptionKeyOperationReq_ResumptionKeyOperation_value = map[string]int32{ + "UNSPECIFIED": 0, + "ENCRYPT": 1, + "DECRYPT": 2, + } +) + +func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Enum() *OffloadResumptionKeyOperationReq_ResumptionKeyOperation { + p := new(OffloadResumptionKeyOperationReq_ResumptionKeyOperation) + *p = x + return p +} + +func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[3].Descriptor() +} + +func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[3] +} + +func (x OffloadResumptionKeyOperationReq_ResumptionKeyOperation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OffloadResumptionKeyOperationReq_ResumptionKeyOperation.Descriptor instead. +func (OffloadResumptionKeyOperationReq_ResumptionKeyOperation) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{7, 0} +} + +type ValidatePeerCertificateChainReq_VerificationMode int32 + +const ( + // The default verification mode supported by S2A. + ValidatePeerCertificateChainReq_UNSPECIFIED ValidatePeerCertificateChainReq_VerificationMode = 0 + // The SPIFFE verification mode selects the set of trusted certificates to + // use for path building based on the SPIFFE trust domain in the peer's leaf + // certificate. + ValidatePeerCertificateChainReq_SPIFFE ValidatePeerCertificateChainReq_VerificationMode = 1 + // The connect-to-Google verification mode uses the trust bundle for + // connecting to Google, e.g. *.mtls.googleapis.com endpoints. + ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE ValidatePeerCertificateChainReq_VerificationMode = 2 +) + +// Enum value maps for ValidatePeerCertificateChainReq_VerificationMode. +var ( + ValidatePeerCertificateChainReq_VerificationMode_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "SPIFFE", + 2: "CONNECT_TO_GOOGLE", + } + ValidatePeerCertificateChainReq_VerificationMode_value = map[string]int32{ + "UNSPECIFIED": 0, + "SPIFFE": 1, + "CONNECT_TO_GOOGLE": 2, + } +) + +func (x ValidatePeerCertificateChainReq_VerificationMode) Enum() *ValidatePeerCertificateChainReq_VerificationMode { + p := new(ValidatePeerCertificateChainReq_VerificationMode) + *p = x + return p +} + +func (x ValidatePeerCertificateChainReq_VerificationMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValidatePeerCertificateChainReq_VerificationMode) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[4].Descriptor() +} + +func (ValidatePeerCertificateChainReq_VerificationMode) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[4] +} + +func (x ValidatePeerCertificateChainReq_VerificationMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValidatePeerCertificateChainReq_VerificationMode.Descriptor instead. +func (ValidatePeerCertificateChainReq_VerificationMode) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 0} +} + +type ValidatePeerCertificateChainResp_ValidationResult int32 + +const ( + ValidatePeerCertificateChainResp_UNSPECIFIED ValidatePeerCertificateChainResp_ValidationResult = 0 + ValidatePeerCertificateChainResp_SUCCESS ValidatePeerCertificateChainResp_ValidationResult = 1 + ValidatePeerCertificateChainResp_FAILURE ValidatePeerCertificateChainResp_ValidationResult = 2 +) + +// Enum value maps for ValidatePeerCertificateChainResp_ValidationResult. +var ( + ValidatePeerCertificateChainResp_ValidationResult_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "SUCCESS", + 2: "FAILURE", + } + ValidatePeerCertificateChainResp_ValidationResult_value = map[string]int32{ + "UNSPECIFIED": 0, + "SUCCESS": 1, + "FAILURE": 2, + } +) + +func (x ValidatePeerCertificateChainResp_ValidationResult) Enum() *ValidatePeerCertificateChainResp_ValidationResult { + p := new(ValidatePeerCertificateChainResp_ValidationResult) + *p = x + return p +} + +func (x ValidatePeerCertificateChainResp_ValidationResult) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValidatePeerCertificateChainResp_ValidationResult) Descriptor() protoreflect.EnumDescriptor { + return file_internal_proto_v2_s2a_s2a_proto_enumTypes[5].Descriptor() +} + +func (ValidatePeerCertificateChainResp_ValidationResult) Type() protoreflect.EnumType { + return &file_internal_proto_v2_s2a_s2a_proto_enumTypes[5] +} + +func (x ValidatePeerCertificateChainResp_ValidationResult) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValidatePeerCertificateChainResp_ValidationResult.Descriptor instead. +func (ValidatePeerCertificateChainResp_ValidationResult) EnumDescriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{10, 0} +} + +type AlpnPolicy struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // If true, the application MUST perform ALPN negotiation. + EnableAlpnNegotiation bool `protobuf:"varint,1,opt,name=enable_alpn_negotiation,json=enableAlpnNegotiation,proto3" json:"enable_alpn_negotiation,omitempty"` + // The ordered list of ALPN protocols that specify how the application SHOULD + // negotiate ALPN during the TLS handshake. + // + // The application MAY ignore any ALPN protocols in this list that are not + // supported by the application. + AlpnProtocols []common_go_proto.AlpnProtocol `protobuf:"varint,2,rep,packed,name=alpn_protocols,json=alpnProtocols,proto3,enum=s2a.proto.v2.AlpnProtocol" json:"alpn_protocols,omitempty"` +} + +func (x *AlpnPolicy) Reset() { + *x = AlpnPolicy{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlpnPolicy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlpnPolicy) ProtoMessage() {} + +func (x *AlpnPolicy) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlpnPolicy.ProtoReflect.Descriptor instead. +func (*AlpnPolicy) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{0} +} + +func (x *AlpnPolicy) GetEnableAlpnNegotiation() bool { + if x != nil { + return x.EnableAlpnNegotiation + } + return false +} + +func (x *AlpnPolicy) GetAlpnProtocols() []common_go_proto.AlpnProtocol { + if x != nil { + return x.AlpnProtocols + } + return nil +} + +type AuthenticationMechanism struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Applications may specify an identity associated to an authentication + // mechanism. Otherwise, S2A assumes that the authentication mechanism is + // associated with the default identity. If the default identity cannot be + // determined, the request is rejected. + Identity *common_go_proto1.Identity `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + // Types that are assignable to MechanismOneof: + // + // *AuthenticationMechanism_Token + MechanismOneof isAuthenticationMechanism_MechanismOneof `protobuf_oneof:"mechanism_oneof"` +} + +func (x *AuthenticationMechanism) Reset() { + *x = AuthenticationMechanism{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticationMechanism) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticationMechanism) ProtoMessage() {} + +func (x *AuthenticationMechanism) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthenticationMechanism.ProtoReflect.Descriptor instead. +func (*AuthenticationMechanism) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{1} +} + +func (x *AuthenticationMechanism) GetIdentity() *common_go_proto1.Identity { + if x != nil { + return x.Identity + } + return nil +} + +func (m *AuthenticationMechanism) GetMechanismOneof() isAuthenticationMechanism_MechanismOneof { + if m != nil { + return m.MechanismOneof + } + return nil +} + +func (x *AuthenticationMechanism) GetToken() string { + if x, ok := x.GetMechanismOneof().(*AuthenticationMechanism_Token); ok { + return x.Token + } + return "" +} + +type isAuthenticationMechanism_MechanismOneof interface { + isAuthenticationMechanism_MechanismOneof() +} + +type AuthenticationMechanism_Token struct { + // A token that the application uses to authenticate itself to S2A. + Token string `protobuf:"bytes,2,opt,name=token,proto3,oneof"` +} + +func (*AuthenticationMechanism_Token) isAuthenticationMechanism_MechanismOneof() {} + +type Status struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The status code that is specific to the application and the implementation + // of S2A, e.g., gRPC status code. + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + // The status details. + Details string `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"` +} + +func (x *Status) Reset() { + *x = Status{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{2} +} + +func (x *Status) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Status) GetDetails() string { + if x != nil { + return x.Details + } + return "" +} + +type GetTlsConfigurationReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The role of the application in the TLS connection. + ConnectionSide common_go_proto.ConnectionSide `protobuf:"varint,1,opt,name=connection_side,json=connectionSide,proto3,enum=s2a.proto.v2.ConnectionSide" json:"connection_side,omitempty"` + // The server name indication (SNI) extension, which MAY be populated when a + // server is offloading to S2A. The SNI is used to determine the server + // identity if the local identity in the request is empty. + Sni string `protobuf:"bytes,2,opt,name=sni,proto3" json:"sni,omitempty"` +} + +func (x *GetTlsConfigurationReq) Reset() { + *x = GetTlsConfigurationReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTlsConfigurationReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTlsConfigurationReq) ProtoMessage() {} + +func (x *GetTlsConfigurationReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTlsConfigurationReq.ProtoReflect.Descriptor instead. +func (*GetTlsConfigurationReq) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{3} +} + +func (x *GetTlsConfigurationReq) GetConnectionSide() common_go_proto.ConnectionSide { + if x != nil { + return x.ConnectionSide + } + return common_go_proto.ConnectionSide(0) +} + +func (x *GetTlsConfigurationReq) GetSni() string { + if x != nil { + return x.Sni + } + return "" +} + +type GetTlsConfigurationResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to TlsConfiguration: + // + // *GetTlsConfigurationResp_ClientTlsConfiguration_ + // *GetTlsConfigurationResp_ServerTlsConfiguration_ + TlsConfiguration isGetTlsConfigurationResp_TlsConfiguration `protobuf_oneof:"tls_configuration"` +} + +func (x *GetTlsConfigurationResp) Reset() { + *x = GetTlsConfigurationResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTlsConfigurationResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTlsConfigurationResp) ProtoMessage() {} + +func (x *GetTlsConfigurationResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTlsConfigurationResp.ProtoReflect.Descriptor instead. +func (*GetTlsConfigurationResp) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4} +} + +func (m *GetTlsConfigurationResp) GetTlsConfiguration() isGetTlsConfigurationResp_TlsConfiguration { + if m != nil { + return m.TlsConfiguration + } + return nil +} + +func (x *GetTlsConfigurationResp) GetClientTlsConfiguration() *GetTlsConfigurationResp_ClientTlsConfiguration { + if x, ok := x.GetTlsConfiguration().(*GetTlsConfigurationResp_ClientTlsConfiguration_); ok { + return x.ClientTlsConfiguration + } + return nil +} + +func (x *GetTlsConfigurationResp) GetServerTlsConfiguration() *GetTlsConfigurationResp_ServerTlsConfiguration { + if x, ok := x.GetTlsConfiguration().(*GetTlsConfigurationResp_ServerTlsConfiguration_); ok { + return x.ServerTlsConfiguration + } + return nil +} + +type isGetTlsConfigurationResp_TlsConfiguration interface { + isGetTlsConfigurationResp_TlsConfiguration() +} + +type GetTlsConfigurationResp_ClientTlsConfiguration_ struct { + ClientTlsConfiguration *GetTlsConfigurationResp_ClientTlsConfiguration `protobuf:"bytes,1,opt,name=client_tls_configuration,json=clientTlsConfiguration,proto3,oneof"` +} + +type GetTlsConfigurationResp_ServerTlsConfiguration_ struct { + ServerTlsConfiguration *GetTlsConfigurationResp_ServerTlsConfiguration `protobuf:"bytes,2,opt,name=server_tls_configuration,json=serverTlsConfiguration,proto3,oneof"` +} + +func (*GetTlsConfigurationResp_ClientTlsConfiguration_) isGetTlsConfigurationResp_TlsConfiguration() { +} + +func (*GetTlsConfigurationResp_ServerTlsConfiguration_) isGetTlsConfigurationResp_TlsConfiguration() { +} + +type OffloadPrivateKeyOperationReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The operation the private key is used for. + Operation OffloadPrivateKeyOperationReq_PrivateKeyOperation `protobuf:"varint,1,opt,name=operation,proto3,enum=s2a.proto.v2.OffloadPrivateKeyOperationReq_PrivateKeyOperation" json:"operation,omitempty"` + // The signature algorithm to be used for signing operations. + SignatureAlgorithm SignatureAlgorithm `protobuf:"varint,2,opt,name=signature_algorithm,json=signatureAlgorithm,proto3,enum=s2a.proto.v2.SignatureAlgorithm" json:"signature_algorithm,omitempty"` + // The input bytes to be signed or decrypted. + // + // Types that are assignable to InBytes: + // + // *OffloadPrivateKeyOperationReq_RawBytes + // *OffloadPrivateKeyOperationReq_Sha256Digest + // *OffloadPrivateKeyOperationReq_Sha384Digest + // *OffloadPrivateKeyOperationReq_Sha512Digest + InBytes isOffloadPrivateKeyOperationReq_InBytes `protobuf_oneof:"in_bytes"` +} + +func (x *OffloadPrivateKeyOperationReq) Reset() { + *x = OffloadPrivateKeyOperationReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OffloadPrivateKeyOperationReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OffloadPrivateKeyOperationReq) ProtoMessage() {} + +func (x *OffloadPrivateKeyOperationReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OffloadPrivateKeyOperationReq.ProtoReflect.Descriptor instead. +func (*OffloadPrivateKeyOperationReq) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{5} +} + +func (x *OffloadPrivateKeyOperationReq) GetOperation() OffloadPrivateKeyOperationReq_PrivateKeyOperation { + if x != nil { + return x.Operation + } + return OffloadPrivateKeyOperationReq_UNSPECIFIED +} + +func (x *OffloadPrivateKeyOperationReq) GetSignatureAlgorithm() SignatureAlgorithm { + if x != nil { + return x.SignatureAlgorithm + } + return SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED +} + +func (m *OffloadPrivateKeyOperationReq) GetInBytes() isOffloadPrivateKeyOperationReq_InBytes { + if m != nil { + return m.InBytes + } + return nil +} + +func (x *OffloadPrivateKeyOperationReq) GetRawBytes() []byte { + if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_RawBytes); ok { + return x.RawBytes + } + return nil +} + +func (x *OffloadPrivateKeyOperationReq) GetSha256Digest() []byte { + if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha256Digest); ok { + return x.Sha256Digest + } + return nil +} + +func (x *OffloadPrivateKeyOperationReq) GetSha384Digest() []byte { + if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha384Digest); ok { + return x.Sha384Digest + } + return nil +} + +func (x *OffloadPrivateKeyOperationReq) GetSha512Digest() []byte { + if x, ok := x.GetInBytes().(*OffloadPrivateKeyOperationReq_Sha512Digest); ok { + return x.Sha512Digest + } + return nil +} + +type isOffloadPrivateKeyOperationReq_InBytes interface { + isOffloadPrivateKeyOperationReq_InBytes() +} + +type OffloadPrivateKeyOperationReq_RawBytes struct { + // Raw bytes to be hashed and signed, or decrypted. + RawBytes []byte `protobuf:"bytes,4,opt,name=raw_bytes,json=rawBytes,proto3,oneof"` +} + +type OffloadPrivateKeyOperationReq_Sha256Digest struct { + // A SHA256 hash to be signed. Must be 32 bytes. + Sha256Digest []byte `protobuf:"bytes,5,opt,name=sha256_digest,json=sha256Digest,proto3,oneof"` +} + +type OffloadPrivateKeyOperationReq_Sha384Digest struct { + // A SHA384 hash to be signed. Must be 48 bytes. + Sha384Digest []byte `protobuf:"bytes,6,opt,name=sha384_digest,json=sha384Digest,proto3,oneof"` +} + +type OffloadPrivateKeyOperationReq_Sha512Digest struct { + // A SHA512 hash to be signed. Must be 64 bytes. + Sha512Digest []byte `protobuf:"bytes,7,opt,name=sha512_digest,json=sha512Digest,proto3,oneof"` +} + +func (*OffloadPrivateKeyOperationReq_RawBytes) isOffloadPrivateKeyOperationReq_InBytes() {} + +func (*OffloadPrivateKeyOperationReq_Sha256Digest) isOffloadPrivateKeyOperationReq_InBytes() {} + +func (*OffloadPrivateKeyOperationReq_Sha384Digest) isOffloadPrivateKeyOperationReq_InBytes() {} + +func (*OffloadPrivateKeyOperationReq_Sha512Digest) isOffloadPrivateKeyOperationReq_InBytes() {} + +type OffloadPrivateKeyOperationResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The signed or decrypted output bytes. + OutBytes []byte `protobuf:"bytes,1,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"` +} + +func (x *OffloadPrivateKeyOperationResp) Reset() { + *x = OffloadPrivateKeyOperationResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OffloadPrivateKeyOperationResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OffloadPrivateKeyOperationResp) ProtoMessage() {} + +func (x *OffloadPrivateKeyOperationResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OffloadPrivateKeyOperationResp.ProtoReflect.Descriptor instead. +func (*OffloadPrivateKeyOperationResp) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{6} +} + +func (x *OffloadPrivateKeyOperationResp) GetOutBytes() []byte { + if x != nil { + return x.OutBytes + } + return nil +} + +type OffloadResumptionKeyOperationReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The operation the resumption key is used for. + Operation OffloadResumptionKeyOperationReq_ResumptionKeyOperation `protobuf:"varint,1,opt,name=operation,proto3,enum=s2a.proto.v2.OffloadResumptionKeyOperationReq_ResumptionKeyOperation" json:"operation,omitempty"` + // The bytes to be encrypted or decrypted. + InBytes []byte `protobuf:"bytes,2,opt,name=in_bytes,json=inBytes,proto3" json:"in_bytes,omitempty"` +} + +func (x *OffloadResumptionKeyOperationReq) Reset() { + *x = OffloadResumptionKeyOperationReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OffloadResumptionKeyOperationReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OffloadResumptionKeyOperationReq) ProtoMessage() {} + +func (x *OffloadResumptionKeyOperationReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OffloadResumptionKeyOperationReq.ProtoReflect.Descriptor instead. +func (*OffloadResumptionKeyOperationReq) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{7} +} + +func (x *OffloadResumptionKeyOperationReq) GetOperation() OffloadResumptionKeyOperationReq_ResumptionKeyOperation { + if x != nil { + return x.Operation + } + return OffloadResumptionKeyOperationReq_UNSPECIFIED +} + +func (x *OffloadResumptionKeyOperationReq) GetInBytes() []byte { + if x != nil { + return x.InBytes + } + return nil +} + +type OffloadResumptionKeyOperationResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The encrypted or decrypted bytes. + OutBytes []byte `protobuf:"bytes,1,opt,name=out_bytes,json=outBytes,proto3" json:"out_bytes,omitempty"` +} + +func (x *OffloadResumptionKeyOperationResp) Reset() { + *x = OffloadResumptionKeyOperationResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OffloadResumptionKeyOperationResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OffloadResumptionKeyOperationResp) ProtoMessage() {} + +func (x *OffloadResumptionKeyOperationResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OffloadResumptionKeyOperationResp.ProtoReflect.Descriptor instead. +func (*OffloadResumptionKeyOperationResp) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{8} +} + +func (x *OffloadResumptionKeyOperationResp) GetOutBytes() []byte { + if x != nil { + return x.OutBytes + } + return nil +} + +type ValidatePeerCertificateChainReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The verification mode that S2A MUST use to validate the peer certificate + // chain. + Mode ValidatePeerCertificateChainReq_VerificationMode `protobuf:"varint,1,opt,name=mode,proto3,enum=s2a.proto.v2.ValidatePeerCertificateChainReq_VerificationMode" json:"mode,omitempty"` + // Types that are assignable to PeerOneof: + // + // *ValidatePeerCertificateChainReq_ClientPeer_ + // *ValidatePeerCertificateChainReq_ServerPeer_ + PeerOneof isValidatePeerCertificateChainReq_PeerOneof `protobuf_oneof:"peer_oneof"` +} + +func (x *ValidatePeerCertificateChainReq) Reset() { + *x = ValidatePeerCertificateChainReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatePeerCertificateChainReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePeerCertificateChainReq) ProtoMessage() {} + +func (x *ValidatePeerCertificateChainReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePeerCertificateChainReq.ProtoReflect.Descriptor instead. +func (*ValidatePeerCertificateChainReq) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9} +} + +func (x *ValidatePeerCertificateChainReq) GetMode() ValidatePeerCertificateChainReq_VerificationMode { + if x != nil { + return x.Mode + } + return ValidatePeerCertificateChainReq_UNSPECIFIED +} + +func (m *ValidatePeerCertificateChainReq) GetPeerOneof() isValidatePeerCertificateChainReq_PeerOneof { + if m != nil { + return m.PeerOneof + } + return nil +} + +func (x *ValidatePeerCertificateChainReq) GetClientPeer() *ValidatePeerCertificateChainReq_ClientPeer { + if x, ok := x.GetPeerOneof().(*ValidatePeerCertificateChainReq_ClientPeer_); ok { + return x.ClientPeer + } + return nil +} + +func (x *ValidatePeerCertificateChainReq) GetServerPeer() *ValidatePeerCertificateChainReq_ServerPeer { + if x, ok := x.GetPeerOneof().(*ValidatePeerCertificateChainReq_ServerPeer_); ok { + return x.ServerPeer + } + return nil +} + +type isValidatePeerCertificateChainReq_PeerOneof interface { + isValidatePeerCertificateChainReq_PeerOneof() +} + +type ValidatePeerCertificateChainReq_ClientPeer_ struct { + ClientPeer *ValidatePeerCertificateChainReq_ClientPeer `protobuf:"bytes,2,opt,name=client_peer,json=clientPeer,proto3,oneof"` +} + +type ValidatePeerCertificateChainReq_ServerPeer_ struct { + ServerPeer *ValidatePeerCertificateChainReq_ServerPeer `protobuf:"bytes,3,opt,name=server_peer,json=serverPeer,proto3,oneof"` +} + +func (*ValidatePeerCertificateChainReq_ClientPeer_) isValidatePeerCertificateChainReq_PeerOneof() {} + +func (*ValidatePeerCertificateChainReq_ServerPeer_) isValidatePeerCertificateChainReq_PeerOneof() {} + +type ValidatePeerCertificateChainResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result of validating the peer certificate chain. + ValidationResult ValidatePeerCertificateChainResp_ValidationResult `protobuf:"varint,1,opt,name=validation_result,json=validationResult,proto3,enum=s2a.proto.v2.ValidatePeerCertificateChainResp_ValidationResult" json:"validation_result,omitempty"` + // The validation details. This field is only populated when the validation + // result is NOT SUCCESS. + ValidationDetails string `protobuf:"bytes,2,opt,name=validation_details,json=validationDetails,proto3" json:"validation_details,omitempty"` + // The S2A context contains information from the peer certificate chain. + // + // The S2A context MAY be populated even if validation of the peer certificate + // chain fails. + Context *s2a_context_go_proto.S2AContext `protobuf:"bytes,3,opt,name=context,proto3" json:"context,omitempty"` +} + +func (x *ValidatePeerCertificateChainResp) Reset() { + *x = ValidatePeerCertificateChainResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatePeerCertificateChainResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePeerCertificateChainResp) ProtoMessage() {} + +func (x *ValidatePeerCertificateChainResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePeerCertificateChainResp.ProtoReflect.Descriptor instead. +func (*ValidatePeerCertificateChainResp) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{10} +} + +func (x *ValidatePeerCertificateChainResp) GetValidationResult() ValidatePeerCertificateChainResp_ValidationResult { + if x != nil { + return x.ValidationResult + } + return ValidatePeerCertificateChainResp_UNSPECIFIED +} + +func (x *ValidatePeerCertificateChainResp) GetValidationDetails() string { + if x != nil { + return x.ValidationDetails + } + return "" +} + +func (x *ValidatePeerCertificateChainResp) GetContext() *s2a_context_go_proto.S2AContext { + if x != nil { + return x.Context + } + return nil +} + +type SessionReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The identity corresponding to the TLS configurations that MUST be used for + // the TLS handshake. + // + // If a managed identity already exists, the local identity and authentication + // mechanisms are ignored. If a managed identity doesn't exist and the local + // identity is not populated, S2A will try to deduce the managed identity to + // use from the SNI extension. If that also fails, S2A uses the default + // identity (if one exists). + LocalIdentity *common_go_proto1.Identity `protobuf:"bytes,1,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"` + // The authentication mechanisms that the application wishes to use to + // authenticate to S2A, ordered by preference. S2A will always use the first + // authentication mechanism that matches the managed identity. + AuthenticationMechanisms []*AuthenticationMechanism `protobuf:"bytes,2,rep,name=authentication_mechanisms,json=authenticationMechanisms,proto3" json:"authentication_mechanisms,omitempty"` + // Types that are assignable to ReqOneof: + // + // *SessionReq_GetTlsConfigurationReq + // *SessionReq_OffloadPrivateKeyOperationReq + // *SessionReq_OffloadResumptionKeyOperationReq + // *SessionReq_ValidatePeerCertificateChainReq + ReqOneof isSessionReq_ReqOneof `protobuf_oneof:"req_oneof"` +} + +func (x *SessionReq) Reset() { + *x = SessionReq{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionReq) ProtoMessage() {} + +func (x *SessionReq) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionReq.ProtoReflect.Descriptor instead. +func (*SessionReq) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{11} +} + +func (x *SessionReq) GetLocalIdentity() *common_go_proto1.Identity { + if x != nil { + return x.LocalIdentity + } + return nil +} + +func (x *SessionReq) GetAuthenticationMechanisms() []*AuthenticationMechanism { + if x != nil { + return x.AuthenticationMechanisms + } + return nil +} + +func (m *SessionReq) GetReqOneof() isSessionReq_ReqOneof { + if m != nil { + return m.ReqOneof + } + return nil +} + +func (x *SessionReq) GetGetTlsConfigurationReq() *GetTlsConfigurationReq { + if x, ok := x.GetReqOneof().(*SessionReq_GetTlsConfigurationReq); ok { + return x.GetTlsConfigurationReq + } + return nil +} + +func (x *SessionReq) GetOffloadPrivateKeyOperationReq() *OffloadPrivateKeyOperationReq { + if x, ok := x.GetReqOneof().(*SessionReq_OffloadPrivateKeyOperationReq); ok { + return x.OffloadPrivateKeyOperationReq + } + return nil +} + +func (x *SessionReq) GetOffloadResumptionKeyOperationReq() *OffloadResumptionKeyOperationReq { + if x, ok := x.GetReqOneof().(*SessionReq_OffloadResumptionKeyOperationReq); ok { + return x.OffloadResumptionKeyOperationReq + } + return nil +} + +func (x *SessionReq) GetValidatePeerCertificateChainReq() *ValidatePeerCertificateChainReq { + if x, ok := x.GetReqOneof().(*SessionReq_ValidatePeerCertificateChainReq); ok { + return x.ValidatePeerCertificateChainReq + } + return nil +} + +type isSessionReq_ReqOneof interface { + isSessionReq_ReqOneof() +} + +type SessionReq_GetTlsConfigurationReq struct { + // Requests the certificate chain and TLS configuration corresponding to the + // local identity, which the application MUST use to negotiate the TLS + // handshake. + GetTlsConfigurationReq *GetTlsConfigurationReq `protobuf:"bytes,3,opt,name=get_tls_configuration_req,json=getTlsConfigurationReq,proto3,oneof"` +} + +type SessionReq_OffloadPrivateKeyOperationReq struct { + // Signs or decrypts the input bytes using a private key corresponding to + // the local identity in the request. + // + // WARNING: More than one OffloadPrivateKeyOperationReq may be sent to the + // S2Av2 by a server during a TLS 1.2 handshake. + OffloadPrivateKeyOperationReq *OffloadPrivateKeyOperationReq `protobuf:"bytes,4,opt,name=offload_private_key_operation_req,json=offloadPrivateKeyOperationReq,proto3,oneof"` +} + +type SessionReq_OffloadResumptionKeyOperationReq struct { + // Encrypts or decrypts the input bytes using a resumption key corresponding + // to the local identity in the request. + OffloadResumptionKeyOperationReq *OffloadResumptionKeyOperationReq `protobuf:"bytes,5,opt,name=offload_resumption_key_operation_req,json=offloadResumptionKeyOperationReq,proto3,oneof"` +} + +type SessionReq_ValidatePeerCertificateChainReq struct { + // Verifies the peer's certificate chain using + // (a) trust bundles corresponding to the local identity in the request, and + // (b) the verification mode in the request. + ValidatePeerCertificateChainReq *ValidatePeerCertificateChainReq `protobuf:"bytes,6,opt,name=validate_peer_certificate_chain_req,json=validatePeerCertificateChainReq,proto3,oneof"` +} + +func (*SessionReq_GetTlsConfigurationReq) isSessionReq_ReqOneof() {} + +func (*SessionReq_OffloadPrivateKeyOperationReq) isSessionReq_ReqOneof() {} + +func (*SessionReq_OffloadResumptionKeyOperationReq) isSessionReq_ReqOneof() {} + +func (*SessionReq_ValidatePeerCertificateChainReq) isSessionReq_ReqOneof() {} + +type SessionResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status of the session response. + // + // The status field is populated so that if an error occurs when making an + // individual request, then communication with the S2A may continue. If an + // error is returned directly (e.g. at the gRPC layer), then it may result + // that the bidirectional stream being closed. + Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // Types that are assignable to RespOneof: + // + // *SessionResp_GetTlsConfigurationResp + // *SessionResp_OffloadPrivateKeyOperationResp + // *SessionResp_OffloadResumptionKeyOperationResp + // *SessionResp_ValidatePeerCertificateChainResp + RespOneof isSessionResp_RespOneof `protobuf_oneof:"resp_oneof"` +} + +func (x *SessionResp) Reset() { + *x = SessionResp{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionResp) ProtoMessage() {} + +func (x *SessionResp) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionResp.ProtoReflect.Descriptor instead. +func (*SessionResp) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{12} +} + +func (x *SessionResp) GetStatus() *Status { + if x != nil { + return x.Status + } + return nil +} + +func (m *SessionResp) GetRespOneof() isSessionResp_RespOneof { + if m != nil { + return m.RespOneof + } + return nil +} + +func (x *SessionResp) GetGetTlsConfigurationResp() *GetTlsConfigurationResp { + if x, ok := x.GetRespOneof().(*SessionResp_GetTlsConfigurationResp); ok { + return x.GetTlsConfigurationResp + } + return nil +} + +func (x *SessionResp) GetOffloadPrivateKeyOperationResp() *OffloadPrivateKeyOperationResp { + if x, ok := x.GetRespOneof().(*SessionResp_OffloadPrivateKeyOperationResp); ok { + return x.OffloadPrivateKeyOperationResp + } + return nil +} + +func (x *SessionResp) GetOffloadResumptionKeyOperationResp() *OffloadResumptionKeyOperationResp { + if x, ok := x.GetRespOneof().(*SessionResp_OffloadResumptionKeyOperationResp); ok { + return x.OffloadResumptionKeyOperationResp + } + return nil +} + +func (x *SessionResp) GetValidatePeerCertificateChainResp() *ValidatePeerCertificateChainResp { + if x, ok := x.GetRespOneof().(*SessionResp_ValidatePeerCertificateChainResp); ok { + return x.ValidatePeerCertificateChainResp + } + return nil +} + +type isSessionResp_RespOneof interface { + isSessionResp_RespOneof() +} + +type SessionResp_GetTlsConfigurationResp struct { + // Contains the certificate chain and TLS configurations corresponding to + // the local identity. + GetTlsConfigurationResp *GetTlsConfigurationResp `protobuf:"bytes,2,opt,name=get_tls_configuration_resp,json=getTlsConfigurationResp,proto3,oneof"` +} + +type SessionResp_OffloadPrivateKeyOperationResp struct { + // Contains the signed or encrypted output bytes using the private key + // corresponding to the local identity. + OffloadPrivateKeyOperationResp *OffloadPrivateKeyOperationResp `protobuf:"bytes,3,opt,name=offload_private_key_operation_resp,json=offloadPrivateKeyOperationResp,proto3,oneof"` +} + +type SessionResp_OffloadResumptionKeyOperationResp struct { + // Contains the encrypted or decrypted output bytes using the resumption key + // corresponding to the local identity. + OffloadResumptionKeyOperationResp *OffloadResumptionKeyOperationResp `protobuf:"bytes,4,opt,name=offload_resumption_key_operation_resp,json=offloadResumptionKeyOperationResp,proto3,oneof"` +} + +type SessionResp_ValidatePeerCertificateChainResp struct { + // Contains the validation result, peer identity and fingerprints of peer + // certificates. + ValidatePeerCertificateChainResp *ValidatePeerCertificateChainResp `protobuf:"bytes,5,opt,name=validate_peer_certificate_chain_resp,json=validatePeerCertificateChainResp,proto3,oneof"` +} + +func (*SessionResp_GetTlsConfigurationResp) isSessionResp_RespOneof() {} + +func (*SessionResp_OffloadPrivateKeyOperationResp) isSessionResp_RespOneof() {} + +func (*SessionResp_OffloadResumptionKeyOperationResp) isSessionResp_RespOneof() {} + +func (*SessionResp_ValidatePeerCertificateChainResp) isSessionResp_RespOneof() {} + +// Next ID: 8 +type GetTlsConfigurationResp_ClientTlsConfiguration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The certificate chain that the client MUST use for the TLS handshake. + // It's a list of PEM-encoded certificates, ordered from leaf to root, + // excluding the root. + CertificateChain []string `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"` + // The minimum TLS version number that the client MUST use for the TLS + // handshake. If this field is not provided, the client MUST use the default + // minimum version of the client's TLS library. + MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"min_tls_version,omitempty"` + // The maximum TLS version number that the client MUST use for the TLS + // handshake. If this field is not provided, the client MUST use the default + // maximum version of the client's TLS library. + MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"max_tls_version,omitempty"` + // The ordered list of TLS 1.0-1.2 ciphersuites that the client MAY offer to + // negotiate in the TLS handshake. + Ciphersuites []common_go_proto.Ciphersuite `protobuf:"varint,6,rep,packed,name=ciphersuites,proto3,enum=s2a.proto.v2.Ciphersuite" json:"ciphersuites,omitempty"` + // The policy that dictates how the client negotiates ALPN during the TLS + // handshake. + AlpnPolicy *AlpnPolicy `protobuf:"bytes,7,opt,name=alpn_policy,json=alpnPolicy,proto3" json:"alpn_policy,omitempty"` +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) Reset() { + *x = GetTlsConfigurationResp_ClientTlsConfiguration{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTlsConfigurationResp_ClientTlsConfiguration) ProtoMessage() {} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTlsConfigurationResp_ClientTlsConfiguration.ProtoReflect.Descriptor instead. +func (*GetTlsConfigurationResp_ClientTlsConfiguration) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetCertificateChain() []string { + if x != nil { + return x.CertificateChain + } + return nil +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetMinTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MinTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetMaxTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MaxTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetCiphersuites() []common_go_proto.Ciphersuite { + if x != nil { + return x.Ciphersuites + } + return nil +} + +func (x *GetTlsConfigurationResp_ClientTlsConfiguration) GetAlpnPolicy() *AlpnPolicy { + if x != nil { + return x.AlpnPolicy + } + return nil +} + +// Next ID: 12 +type GetTlsConfigurationResp_ServerTlsConfiguration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The certificate chain that the server MUST use for the TLS handshake. + // It's a list of PEM-encoded certificates, ordered from leaf to root, + // excluding the root. + CertificateChain []string `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"` + // The minimum TLS version number that the server MUST use for the TLS + // handshake. If this field is not provided, the server MUST use the default + // minimum version of the server's TLS library. + MinTlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=min_tls_version,json=minTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"min_tls_version,omitempty"` + // The maximum TLS version number that the server MUST use for the TLS + // handshake. If this field is not provided, the server MUST use the default + // maximum version of the server's TLS library. + MaxTlsVersion common_go_proto.TLSVersion `protobuf:"varint,3,opt,name=max_tls_version,json=maxTlsVersion,proto3,enum=s2a.proto.v2.TLSVersion" json:"max_tls_version,omitempty"` + // The ordered list of TLS 1.0-1.2 ciphersuites that the server MAY offer to + // negotiate in the TLS handshake. + Ciphersuites []common_go_proto.Ciphersuite `protobuf:"varint,10,rep,packed,name=ciphersuites,proto3,enum=s2a.proto.v2.Ciphersuite" json:"ciphersuites,omitempty"` + // Whether to enable TLS resumption. + TlsResumptionEnabled bool `protobuf:"varint,6,opt,name=tls_resumption_enabled,json=tlsResumptionEnabled,proto3" json:"tls_resumption_enabled,omitempty"` + // Whether the server MUST request a client certificate (i.e. to negotiate + // TLS vs. mTLS). + RequestClientCertificate GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate `protobuf:"varint,7,opt,name=request_client_certificate,json=requestClientCertificate,proto3,enum=s2a.proto.v2.GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate" json:"request_client_certificate,omitempty"` + // Returns the maximum number of extra bytes that + // |OffloadResumptionKeyOperation| can add to the number of unencrypted + // bytes to form the encrypted bytes. + MaxOverheadOfTicketAead uint32 `protobuf:"varint,9,opt,name=max_overhead_of_ticket_aead,json=maxOverheadOfTicketAead,proto3" json:"max_overhead_of_ticket_aead,omitempty"` + // The policy that dictates how the server negotiates ALPN during the TLS + // handshake. + AlpnPolicy *AlpnPolicy `protobuf:"bytes,11,opt,name=alpn_policy,json=alpnPolicy,proto3" json:"alpn_policy,omitempty"` +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) Reset() { + *x = GetTlsConfigurationResp_ServerTlsConfiguration{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTlsConfigurationResp_ServerTlsConfiguration) ProtoMessage() {} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTlsConfigurationResp_ServerTlsConfiguration.ProtoReflect.Descriptor instead. +func (*GetTlsConfigurationResp_ServerTlsConfiguration) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetCertificateChain() []string { + if x != nil { + return x.CertificateChain + } + return nil +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMinTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MinTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMaxTlsVersion() common_go_proto.TLSVersion { + if x != nil { + return x.MaxTlsVersion + } + return common_go_proto.TLSVersion(0) +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetCiphersuites() []common_go_proto.Ciphersuite { + if x != nil { + return x.Ciphersuites + } + return nil +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetTlsResumptionEnabled() bool { + if x != nil { + return x.TlsResumptionEnabled + } + return false +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetRequestClientCertificate() GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate { + if x != nil { + return x.RequestClientCertificate + } + return GetTlsConfigurationResp_ServerTlsConfiguration_UNSPECIFIED +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetMaxOverheadOfTicketAead() uint32 { + if x != nil { + return x.MaxOverheadOfTicketAead + } + return 0 +} + +func (x *GetTlsConfigurationResp_ServerTlsConfiguration) GetAlpnPolicy() *AlpnPolicy { + if x != nil { + return x.AlpnPolicy + } + return nil +} + +type ValidatePeerCertificateChainReq_ClientPeer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The certificate chain to be verified. The chain MUST be a list of + // DER-encoded certificates, ordered from leaf to root, excluding the root. + CertificateChain [][]byte `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"` +} + +func (x *ValidatePeerCertificateChainReq_ClientPeer) Reset() { + *x = ValidatePeerCertificateChainReq_ClientPeer{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatePeerCertificateChainReq_ClientPeer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePeerCertificateChainReq_ClientPeer) ProtoMessage() {} + +func (x *ValidatePeerCertificateChainReq_ClientPeer) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePeerCertificateChainReq_ClientPeer.ProtoReflect.Descriptor instead. +func (*ValidatePeerCertificateChainReq_ClientPeer) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 0} +} + +func (x *ValidatePeerCertificateChainReq_ClientPeer) GetCertificateChain() [][]byte { + if x != nil { + return x.CertificateChain + } + return nil +} + +type ValidatePeerCertificateChainReq_ServerPeer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The certificate chain to be verified. The chain MUST be a list of + // DER-encoded certificates, ordered from leaf to root, excluding the root. + CertificateChain [][]byte `protobuf:"bytes,1,rep,name=certificate_chain,json=certificateChain,proto3" json:"certificate_chain,omitempty"` + // The expected hostname of the server. + ServerHostname string `protobuf:"bytes,2,opt,name=server_hostname,json=serverHostname,proto3" json:"server_hostname,omitempty"` + // The UnrestrictedClientPolicy specified by the user. + SerializedUnrestrictedClientPolicy []byte `protobuf:"bytes,3,opt,name=serialized_unrestricted_client_policy,json=serializedUnrestrictedClientPolicy,proto3" json:"serialized_unrestricted_client_policy,omitempty"` +} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) Reset() { + *x = ValidatePeerCertificateChainReq_ServerPeer{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatePeerCertificateChainReq_ServerPeer) ProtoMessage() {} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) ProtoReflect() protoreflect.Message { + mi := &file_internal_proto_v2_s2a_s2a_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatePeerCertificateChainReq_ServerPeer.ProtoReflect.Descriptor instead. +func (*ValidatePeerCertificateChainReq_ServerPeer) Descriptor() ([]byte, []int) { + return file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) GetCertificateChain() [][]byte { + if x != nil { + return x.CertificateChain + } + return nil +} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) GetServerHostname() string { + if x != nil { + return x.ServerHostname + } + return "" +} + +func (x *ValidatePeerCertificateChainReq_ServerPeer) GetSerializedUnrestrictedClientPolicy() []byte { + if x != nil { + return x.SerializedUnrestrictedClientPolicy + } + return nil +} + +var File_internal_proto_v2_s2a_s2a_proto protoreflect.FileDescriptor + +var file_internal_proto_v2_s2a_s2a_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x1a, + 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, + 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0a, + 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x41, 0x6c, 0x70, 0x6e, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x0d, 0x61, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x22, 0x75, 0x0a, 0x17, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, + 0x12, 0x2f, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x65, 0x63, + 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x36, 0x0a, 0x06, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x22, 0x71, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x45, + 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x69, 0x64, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x69, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x73, 0x6e, 0x69, 0x22, 0xf1, 0x0b, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, + 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x78, 0x0a, 0x18, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6c, + 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x16, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x6c, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x78, 0x0a, + 0x18, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x16, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xcf, 0x02, 0x0a, 0x16, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, + 0x40, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, + 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x32, 0x61, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, + 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x0a, 0x61, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x04, 0x08, + 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x1a, 0xfa, 0x06, 0x0a, 0x16, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x54, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, + 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x4c, 0x53, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x54, 0x6c, 0x73, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, + 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, + 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, + 0x69, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x6c, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x75, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x74, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x93, 0x01, 0x0a, 0x1a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x55, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6c, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x18, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x12, 0x3c, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, + 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x61, 0x65, 0x61, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x6d, 0x61, 0x78, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, + 0x61, 0x64, 0x4f, 0x66, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x65, 0x61, 0x64, 0x12, 0x39, + 0x0a, 0x0b, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x61, + 0x6c, 0x70, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x9e, 0x02, 0x0a, 0x18, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x4f, 0x4e, 0x54, 0x5f, + 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, + 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x2e, 0x0a, 0x2a, + 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, + 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x55, 0x54, 0x5f, 0x44, + 0x4f, 0x4e, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x02, 0x12, 0x29, 0x0a, 0x25, + 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, + 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x56, + 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x03, 0x12, 0x3a, 0x0a, 0x36, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, 0x43, + 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, + 0x45, 0x5f, 0x42, 0x55, 0x54, 0x5f, 0x44, 0x4f, 0x4e, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, + 0x59, 0x10, 0x04, 0x12, 0x35, 0x0a, 0x31, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x41, + 0x4e, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x4e, + 0x44, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x42, 0x13, 0x0a, 0x11, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x03, 0x0a, 0x1d, + 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x5d, 0x0a, + 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x3f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, + 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x13, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, + 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x32, 0x61, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x12, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, + 0x1d, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x72, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x25, + 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x44, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x33, 0x38, 0x34, 0x5f, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, + 0x73, 0x68, 0x61, 0x33, 0x38, 0x34, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, + 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x44, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, + 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50, 0x54, + 0x10, 0x02, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3d, + 0x0a, 0x1e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe7, 0x01, + 0x0a, 0x20, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x12, 0x63, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x45, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, + 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x22, 0x43, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x0b, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, + 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0x02, 0x22, 0x40, 0x0a, 0x21, 0x4f, 0x66, 0x66, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, + 0x6f, 0x75, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x6f, 0x75, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xf8, 0x04, 0x0a, 0x1f, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x12, 0x5b, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, + 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x52, 0x65, 0x71, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72, + 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x5b, + 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x65, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0a, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x1a, 0xb5, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x73, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x51, 0x0a, 0x25, 0x73, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x22, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x46, + 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, + 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x10, 0x01, 0x12, + 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x4f, 0x5f, 0x47, 0x4f, + 0x4f, 0x47, 0x4c, 0x45, 0x10, 0x02, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6f, + 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xb2, 0x02, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6c, 0x0a, 0x11, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3d, 0x0a, 0x10, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0f, + 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, + 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x02, 0x22, 0x97, 0x05, 0x0a, 0x0a, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x12, 0x62, 0x0a, 0x19, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x52, 0x18, + 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x12, 0x61, 0x0a, 0x19, 0x67, 0x65, 0x74, 0x5f, + 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x32, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c, + 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x48, 0x00, 0x52, 0x16, 0x67, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x77, 0x0a, 0x21, 0x6f, + 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x1d, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x12, 0x80, 0x01, 0x0a, 0x24, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x20, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, + 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x7d, 0x0a, 0x23, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x1f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x42, 0x0b, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x5f, 0x6f, 0x6e, + 0x65, 0x6f, 0x66, 0x22, 0xb4, 0x04, 0x0a, 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x64, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x17, + 0x67, 0x65, 0x74, 0x54, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x7a, 0x0a, 0x22, 0x6f, 0x66, 0x66, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x48, 0x00, 0x52, 0x1e, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x83, 0x01, 0x0a, 0x25, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x5f, + 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x76, 0x32, 0x2e, 0x4f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x21, 0x6f, 0x66, 0x66, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x80, 0x01, 0x0a, 0x24, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x48, 0x00, 0x52, 0x20, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0c, 0x0a, 0x0a, + 0x72, 0x65, 0x73, 0x70, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x2a, 0xa2, 0x03, 0x0a, 0x12, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, + 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, + 0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, + 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, + 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f, 0x53, 0x48, 0x41, + 0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, + 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x4b, 0x43, 0x53, 0x31, 0x5f, + 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0x03, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32, 0x41, 0x5f, + 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x53, + 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, + 0x04, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, + 0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x33, 0x38, 0x34, 0x52, + 0x31, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x05, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x32, + 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, + 0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, + 0x32, 0x10, 0x06, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, + 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x5f, 0x52, 0x53, 0x41, 0x45, + 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x07, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x32, 0x41, + 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, + 0x53, 0x5f, 0x52, 0x53, 0x41, 0x45, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x08, 0x12, + 0x24, 0x0a, 0x20, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, + 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x5f, 0x52, 0x53, 0x41, 0x45, 0x5f, 0x53, 0x48, 0x41, + 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x32, 0x41, 0x5f, 0x53, 0x53, 0x4c, + 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x0a, 0x32, + 0x57, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 0x0a, + 0x0c, 0x53, 0x65, 0x74, 0x55, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, + 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, + 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_proto_v2_s2a_s2a_proto_rawDescOnce sync.Once + file_internal_proto_v2_s2a_s2a_proto_rawDescData = file_internal_proto_v2_s2a_s2a_proto_rawDesc +) + +func file_internal_proto_v2_s2a_s2a_proto_rawDescGZIP() []byte { + file_internal_proto_v2_s2a_s2a_proto_rawDescOnce.Do(func() { + file_internal_proto_v2_s2a_s2a_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_s2a_s2a_proto_rawDescData) + }) + return file_internal_proto_v2_s2a_s2a_proto_rawDescData +} + +var file_internal_proto_v2_s2a_s2a_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_internal_proto_v2_s2a_s2a_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_internal_proto_v2_s2a_s2a_proto_goTypes = []interface{}{ + (SignatureAlgorithm)(0), // 0: s2a.proto.v2.SignatureAlgorithm + (GetTlsConfigurationResp_ServerTlsConfiguration_RequestClientCertificate)(0), // 1: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.RequestClientCertificate + (OffloadPrivateKeyOperationReq_PrivateKeyOperation)(0), // 2: s2a.proto.v2.OffloadPrivateKeyOperationReq.PrivateKeyOperation + (OffloadResumptionKeyOperationReq_ResumptionKeyOperation)(0), // 3: s2a.proto.v2.OffloadResumptionKeyOperationReq.ResumptionKeyOperation + (ValidatePeerCertificateChainReq_VerificationMode)(0), // 4: s2a.proto.v2.ValidatePeerCertificateChainReq.VerificationMode + (ValidatePeerCertificateChainResp_ValidationResult)(0), // 5: s2a.proto.v2.ValidatePeerCertificateChainResp.ValidationResult + (*AlpnPolicy)(nil), // 6: s2a.proto.v2.AlpnPolicy + (*AuthenticationMechanism)(nil), // 7: s2a.proto.v2.AuthenticationMechanism + (*Status)(nil), // 8: s2a.proto.v2.Status + (*GetTlsConfigurationReq)(nil), // 9: s2a.proto.v2.GetTlsConfigurationReq + (*GetTlsConfigurationResp)(nil), // 10: s2a.proto.v2.GetTlsConfigurationResp + (*OffloadPrivateKeyOperationReq)(nil), // 11: s2a.proto.v2.OffloadPrivateKeyOperationReq + (*OffloadPrivateKeyOperationResp)(nil), // 12: s2a.proto.v2.OffloadPrivateKeyOperationResp + (*OffloadResumptionKeyOperationReq)(nil), // 13: s2a.proto.v2.OffloadResumptionKeyOperationReq + (*OffloadResumptionKeyOperationResp)(nil), // 14: s2a.proto.v2.OffloadResumptionKeyOperationResp + (*ValidatePeerCertificateChainReq)(nil), // 15: s2a.proto.v2.ValidatePeerCertificateChainReq + (*ValidatePeerCertificateChainResp)(nil), // 16: s2a.proto.v2.ValidatePeerCertificateChainResp + (*SessionReq)(nil), // 17: s2a.proto.v2.SessionReq + (*SessionResp)(nil), // 18: s2a.proto.v2.SessionResp + (*GetTlsConfigurationResp_ClientTlsConfiguration)(nil), // 19: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration + (*GetTlsConfigurationResp_ServerTlsConfiguration)(nil), // 20: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration + (*ValidatePeerCertificateChainReq_ClientPeer)(nil), // 21: s2a.proto.v2.ValidatePeerCertificateChainReq.ClientPeer + (*ValidatePeerCertificateChainReq_ServerPeer)(nil), // 22: s2a.proto.v2.ValidatePeerCertificateChainReq.ServerPeer + (common_go_proto.AlpnProtocol)(0), // 23: s2a.proto.v2.AlpnProtocol + (*common_go_proto1.Identity)(nil), // 24: s2a.proto.Identity + (common_go_proto.ConnectionSide)(0), // 25: s2a.proto.v2.ConnectionSide + (*s2a_context_go_proto.S2AContext)(nil), // 26: s2a.proto.v2.S2AContext + (common_go_proto.TLSVersion)(0), // 27: s2a.proto.v2.TLSVersion + (common_go_proto.Ciphersuite)(0), // 28: s2a.proto.v2.Ciphersuite +} +var file_internal_proto_v2_s2a_s2a_proto_depIdxs = []int32{ + 23, // 0: s2a.proto.v2.AlpnPolicy.alpn_protocols:type_name -> s2a.proto.v2.AlpnProtocol + 24, // 1: s2a.proto.v2.AuthenticationMechanism.identity:type_name -> s2a.proto.Identity + 25, // 2: s2a.proto.v2.GetTlsConfigurationReq.connection_side:type_name -> s2a.proto.v2.ConnectionSide + 19, // 3: s2a.proto.v2.GetTlsConfigurationResp.client_tls_configuration:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration + 20, // 4: s2a.proto.v2.GetTlsConfigurationResp.server_tls_configuration:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration + 2, // 5: s2a.proto.v2.OffloadPrivateKeyOperationReq.operation:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationReq.PrivateKeyOperation + 0, // 6: s2a.proto.v2.OffloadPrivateKeyOperationReq.signature_algorithm:type_name -> s2a.proto.v2.SignatureAlgorithm + 3, // 7: s2a.proto.v2.OffloadResumptionKeyOperationReq.operation:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationReq.ResumptionKeyOperation + 4, // 8: s2a.proto.v2.ValidatePeerCertificateChainReq.mode:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.VerificationMode + 21, // 9: s2a.proto.v2.ValidatePeerCertificateChainReq.client_peer:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.ClientPeer + 22, // 10: s2a.proto.v2.ValidatePeerCertificateChainReq.server_peer:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq.ServerPeer + 5, // 11: s2a.proto.v2.ValidatePeerCertificateChainResp.validation_result:type_name -> s2a.proto.v2.ValidatePeerCertificateChainResp.ValidationResult + 26, // 12: s2a.proto.v2.ValidatePeerCertificateChainResp.context:type_name -> s2a.proto.v2.S2AContext + 24, // 13: s2a.proto.v2.SessionReq.local_identity:type_name -> s2a.proto.Identity + 7, // 14: s2a.proto.v2.SessionReq.authentication_mechanisms:type_name -> s2a.proto.v2.AuthenticationMechanism + 9, // 15: s2a.proto.v2.SessionReq.get_tls_configuration_req:type_name -> s2a.proto.v2.GetTlsConfigurationReq + 11, // 16: s2a.proto.v2.SessionReq.offload_private_key_operation_req:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationReq + 13, // 17: s2a.proto.v2.SessionReq.offload_resumption_key_operation_req:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationReq + 15, // 18: s2a.proto.v2.SessionReq.validate_peer_certificate_chain_req:type_name -> s2a.proto.v2.ValidatePeerCertificateChainReq + 8, // 19: s2a.proto.v2.SessionResp.status:type_name -> s2a.proto.v2.Status + 10, // 20: s2a.proto.v2.SessionResp.get_tls_configuration_resp:type_name -> s2a.proto.v2.GetTlsConfigurationResp + 12, // 21: s2a.proto.v2.SessionResp.offload_private_key_operation_resp:type_name -> s2a.proto.v2.OffloadPrivateKeyOperationResp + 14, // 22: s2a.proto.v2.SessionResp.offload_resumption_key_operation_resp:type_name -> s2a.proto.v2.OffloadResumptionKeyOperationResp + 16, // 23: s2a.proto.v2.SessionResp.validate_peer_certificate_chain_resp:type_name -> s2a.proto.v2.ValidatePeerCertificateChainResp + 27, // 24: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.min_tls_version:type_name -> s2a.proto.v2.TLSVersion + 27, // 25: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.max_tls_version:type_name -> s2a.proto.v2.TLSVersion + 28, // 26: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.ciphersuites:type_name -> s2a.proto.v2.Ciphersuite + 6, // 27: s2a.proto.v2.GetTlsConfigurationResp.ClientTlsConfiguration.alpn_policy:type_name -> s2a.proto.v2.AlpnPolicy + 27, // 28: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.min_tls_version:type_name -> s2a.proto.v2.TLSVersion + 27, // 29: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.max_tls_version:type_name -> s2a.proto.v2.TLSVersion + 28, // 30: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.ciphersuites:type_name -> s2a.proto.v2.Ciphersuite + 1, // 31: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.request_client_certificate:type_name -> s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.RequestClientCertificate + 6, // 32: s2a.proto.v2.GetTlsConfigurationResp.ServerTlsConfiguration.alpn_policy:type_name -> s2a.proto.v2.AlpnPolicy + 17, // 33: s2a.proto.v2.S2AService.SetUpSession:input_type -> s2a.proto.v2.SessionReq + 18, // 34: s2a.proto.v2.S2AService.SetUpSession:output_type -> s2a.proto.v2.SessionResp + 34, // [34:35] is the sub-list for method output_type + 33, // [33:34] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name +} + +func init() { file_internal_proto_v2_s2a_s2a_proto_init() } +func file_internal_proto_v2_s2a_s2a_proto_init() { + if File_internal_proto_v2_s2a_s2a_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_proto_v2_s2a_s2a_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlpnPolicy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticationMechanism); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Status); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTlsConfigurationReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTlsConfigurationResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OffloadPrivateKeyOperationReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OffloadPrivateKeyOperationResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OffloadResumptionKeyOperationReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OffloadResumptionKeyOperationResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatePeerCertificateChainReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatePeerCertificateChainResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTlsConfigurationResp_ClientTlsConfiguration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTlsConfigurationResp_ServerTlsConfiguration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatePeerCertificateChainReq_ClientPeer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatePeerCertificateChainReq_ServerPeer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*AuthenticationMechanism_Token)(nil), + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[4].OneofWrappers = []interface{}{ + (*GetTlsConfigurationResp_ClientTlsConfiguration_)(nil), + (*GetTlsConfigurationResp_ServerTlsConfiguration_)(nil), + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*OffloadPrivateKeyOperationReq_RawBytes)(nil), + (*OffloadPrivateKeyOperationReq_Sha256Digest)(nil), + (*OffloadPrivateKeyOperationReq_Sha384Digest)(nil), + (*OffloadPrivateKeyOperationReq_Sha512Digest)(nil), + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[9].OneofWrappers = []interface{}{ + (*ValidatePeerCertificateChainReq_ClientPeer_)(nil), + (*ValidatePeerCertificateChainReq_ServerPeer_)(nil), + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[11].OneofWrappers = []interface{}{ + (*SessionReq_GetTlsConfigurationReq)(nil), + (*SessionReq_OffloadPrivateKeyOperationReq)(nil), + (*SessionReq_OffloadResumptionKeyOperationReq)(nil), + (*SessionReq_ValidatePeerCertificateChainReq)(nil), + } + file_internal_proto_v2_s2a_s2a_proto_msgTypes[12].OneofWrappers = []interface{}{ + (*SessionResp_GetTlsConfigurationResp)(nil), + (*SessionResp_OffloadPrivateKeyOperationResp)(nil), + (*SessionResp_OffloadResumptionKeyOperationResp)(nil), + (*SessionResp_ValidatePeerCertificateChainResp)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_proto_v2_s2a_s2a_proto_rawDesc, + NumEnums: 6, + NumMessages: 17, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_internal_proto_v2_s2a_s2a_proto_goTypes, + DependencyIndexes: file_internal_proto_v2_s2a_s2a_proto_depIdxs, + EnumInfos: file_internal_proto_v2_s2a_s2a_proto_enumTypes, + MessageInfos: file_internal_proto_v2_s2a_s2a_proto_msgTypes, + }.Build() + File_internal_proto_v2_s2a_s2a_proto = out.File + file_internal_proto_v2_s2a_s2a_proto_rawDesc = nil + file_internal_proto_v2_s2a_s2a_proto_goTypes = nil + file_internal_proto_v2_s2a_s2a_proto_depIdxs = nil +} diff --git a/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go new file mode 100644 index 00000000000..2566df6c304 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go @@ -0,0 +1,159 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: internal/proto/v2/s2a/s2a.proto + +package s2a_go_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + S2AService_SetUpSession_FullMethodName = "/s2a.proto.v2.S2AService/SetUpSession" +) + +// S2AServiceClient is the client API for S2AService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type S2AServiceClient interface { + // SetUpSession is a bidirectional stream used by applications to offload + // operations from the TLS handshake. + SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) +} + +type s2AServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient { + return &s2AServiceClient{cc} +} + +func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) { + stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &s2AServiceSetUpSessionClient{stream} + return x, nil +} + +type S2AService_SetUpSessionClient interface { + Send(*SessionReq) error + Recv() (*SessionResp, error) + grpc.ClientStream +} + +type s2AServiceSetUpSessionClient struct { + grpc.ClientStream +} + +func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error { + return x.ClientStream.SendMsg(m) +} + +func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) { + m := new(SessionResp) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// S2AServiceServer is the server API for S2AService service. +// All implementations must embed UnimplementedS2AServiceServer +// for forward compatibility +type S2AServiceServer interface { + // SetUpSession is a bidirectional stream used by applications to offload + // operations from the TLS handshake. + SetUpSession(S2AService_SetUpSessionServer) error + mustEmbedUnimplementedS2AServiceServer() +} + +// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations. +type UnimplementedS2AServiceServer struct { +} + +func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error { + return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented") +} +func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {} + +// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to S2AServiceServer will +// result in compilation errors. +type UnsafeS2AServiceServer interface { + mustEmbedUnimplementedS2AServiceServer() +} + +func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) { + s.RegisterService(&S2AService_ServiceDesc, srv) +} + +func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream}) +} + +type S2AService_SetUpSessionServer interface { + Send(*SessionResp) error + Recv() (*SessionReq, error) + grpc.ServerStream +} + +type s2AServiceSetUpSessionServer struct { + grpc.ServerStream +} + +func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error { + return x.ServerStream.SendMsg(m) +} + +func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) { + m := new(SessionReq) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var S2AService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "s2a.proto.v2.S2AService", + HandlerType: (*S2AServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "SetUpSession", + Handler: _S2AService_SetUpSession_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "internal/proto/v2/s2a/s2a.proto", +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go new file mode 100644 index 00000000000..486f4ec4f2a --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go @@ -0,0 +1,34 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package aeadcrypter provides the interface for AEAD cipher implementations +// used by S2A's record protocol. +package aeadcrypter + +// S2AAEADCrypter is the interface for an AEAD cipher used by the S2A record +// protocol. +type S2AAEADCrypter interface { + // Encrypt encrypts the plaintext and computes the tag of dst and plaintext. + // dst and plaintext may fully overlap or not at all. + Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) + // Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may + // fully overlap or not at all. + Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) + // TagSize returns the tag size in bytes. + TagSize() int +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go new file mode 100644 index 00000000000..85c4e595d75 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go @@ -0,0 +1,70 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package aeadcrypter + +import ( + "crypto/aes" + "crypto/cipher" + "fmt" +) + +// Supported key sizes in bytes. +const ( + AES128GCMKeySize = 16 + AES256GCMKeySize = 32 +) + +// aesgcm is the struct that holds an AES-GCM cipher for the S2A AEAD crypter. +type aesgcm struct { + aead cipher.AEAD +} + +// NewAESGCM creates an AES-GCM crypter instance. Note that the key must be +// either 128 bits or 256 bits. +func NewAESGCM(key []byte) (S2AAEADCrypter, error) { + if len(key) != AES128GCMKeySize && len(key) != AES256GCMKeySize { + return nil, fmt.Errorf("%d or %d bytes, given: %d", AES128GCMKeySize, AES256GCMKeySize, len(key)) + } + c, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + a, err := cipher.NewGCM(c) + if err != nil { + return nil, err + } + return &aesgcm{aead: a}, nil +} + +// Encrypt is the encryption function. dst can contain bytes at the beginning of +// the ciphertext that will not be encrypted but will be authenticated. If dst +// has enough capacity to hold these bytes, the ciphertext and the tag, no +// allocation and copy operations will be performed. dst and plaintext may +// fully overlap or not at all. +func (s *aesgcm) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) { + return encrypt(s.aead, dst, plaintext, nonce, aad) +} + +func (s *aesgcm) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) { + return decrypt(s.aead, dst, ciphertext, nonce, aad) +} + +func (s *aesgcm) TagSize() int { + return TagSize +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go new file mode 100644 index 00000000000..214df4ca415 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go @@ -0,0 +1,67 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package aeadcrypter + +import ( + "crypto/cipher" + "fmt" + + "golang.org/x/crypto/chacha20poly1305" +) + +// Supported key size in bytes. +const ( + Chacha20Poly1305KeySize = 32 +) + +// chachapoly is the struct that holds a CHACHA-POLY cipher for the S2A AEAD +// crypter. +type chachapoly struct { + aead cipher.AEAD +} + +// NewChachaPoly creates a Chacha-Poly crypter instance. Note that the key must +// be Chacha20Poly1305KeySize bytes in length. +func NewChachaPoly(key []byte) (S2AAEADCrypter, error) { + if len(key) != Chacha20Poly1305KeySize { + return nil, fmt.Errorf("%d bytes, given: %d", Chacha20Poly1305KeySize, len(key)) + } + c, err := chacha20poly1305.New(key) + if err != nil { + return nil, err + } + return &chachapoly{aead: c}, nil +} + +// Encrypt is the encryption function. dst can contain bytes at the beginning of +// the ciphertext that will not be encrypted but will be authenticated. If dst +// has enough capacity to hold these bytes, the ciphertext and the tag, no +// allocation and copy operations will be performed. dst and plaintext may +// fully overlap or not at all. +func (s *chachapoly) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) { + return encrypt(s.aead, dst, plaintext, nonce, aad) +} + +func (s *chachapoly) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) { + return decrypt(s.aead, dst, ciphertext, nonce, aad) +} + +func (s *chachapoly) TagSize() int { + return TagSize +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go new file mode 100644 index 00000000000..b3c36ad95dc --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go @@ -0,0 +1,92 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package aeadcrypter + +import ( + "crypto/cipher" + "fmt" +) + +const ( + // TagSize is the tag size in bytes for AES-128-GCM-SHA256, + // AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256. + TagSize = 16 + // NonceSize is the size of the nonce in number of bytes for + // AES-128-GCM-SHA256, AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256. + NonceSize = 12 + // SHA256DigestSize is the digest size of sha256 in bytes. + SHA256DigestSize = 32 + // SHA384DigestSize is the digest size of sha384 in bytes. + SHA384DigestSize = 48 +) + +// sliceForAppend takes a slice and a requested number of bytes. It returns a +// slice with the contents of the given slice followed by that many bytes and a +// second slice that aliases into it and contains only the extra bytes. If the +// original slice has sufficient capacity then no allocation is performed. +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return head, tail +} + +// encrypt is the encryption function for an AEAD crypter. aead determines +// the type of AEAD crypter. dst can contain bytes at the beginning of the +// ciphertext that will not be encrypted but will be authenticated. If dst has +// enough capacity to hold these bytes, the ciphertext and the tag, no +// allocation and copy operations will be performed. dst and plaintext may +// fully overlap or not at all. +func encrypt(aead cipher.AEAD, dst, plaintext, nonce, aad []byte) ([]byte, error) { + if len(nonce) != NonceSize { + return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce)) + } + // If we need to allocate an output buffer, we want to include space for + // the tag to avoid forcing the caller to reallocate as well. + dlen := len(dst) + dst, out := sliceForAppend(dst, len(plaintext)+TagSize) + data := out[:len(plaintext)] + copy(data, plaintext) // data may fully overlap plaintext + + // Seal appends the ciphertext and the tag to its first argument and + // returns the updated slice. However, sliceForAppend above ensures that + // dst has enough capacity to avoid a reallocation and copy due to the + // append. + dst = aead.Seal(dst[:dlen], nonce, data, aad) + return dst, nil +} + +// decrypt is the decryption function for an AEAD crypter, where aead determines +// the type of AEAD crypter, and dst the destination bytes for the decrypted +// ciphertext. The dst buffer may fully overlap with plaintext or not at all. +func decrypt(aead cipher.AEAD, dst, ciphertext, nonce, aad []byte) ([]byte, error) { + if len(nonce) != NonceSize { + return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce)) + } + // If dst is equal to ciphertext[:0], ciphertext storage is reused. + plaintext, err := aead.Open(dst, nonce, ciphertext, aad) + if err != nil { + return nil, fmt.Errorf("message auth failed: %v", err) + } + return plaintext, nil +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go new file mode 100644 index 00000000000..ddeaa6d77d7 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go @@ -0,0 +1,98 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package halfconn + +import ( + "crypto/sha256" + "crypto/sha512" + "fmt" + "hash" + + s2apb "github.com/google/s2a-go/internal/proto/common_go_proto" + "github.com/google/s2a-go/internal/record/internal/aeadcrypter" +) + +// ciphersuite is the interface for retrieving ciphersuite-specific information +// and utilities. +type ciphersuite interface { + // keySize returns the key size in bytes. This refers to the key used by + // the AEAD crypter. This is derived by calling HKDF expand on the traffic + // secret. + keySize() int + // nonceSize returns the nonce size in bytes. + nonceSize() int + // trafficSecretSize returns the traffic secret size in bytes. This refers + // to the secret used to derive the traffic key and nonce, as specified in + // https://tools.ietf.org/html/rfc8446#section-7. + trafficSecretSize() int + // hashFunction returns the hash function for the ciphersuite. + hashFunction() func() hash.Hash + // aeadCrypter takes a key and creates an AEAD crypter for the ciphersuite + // using that key. + aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) +} + +func newCiphersuite(ciphersuite s2apb.Ciphersuite) (ciphersuite, error) { + switch ciphersuite { + case s2apb.Ciphersuite_AES_128_GCM_SHA256: + return &aesgcm128sha256{}, nil + case s2apb.Ciphersuite_AES_256_GCM_SHA384: + return &aesgcm256sha384{}, nil + case s2apb.Ciphersuite_CHACHA20_POLY1305_SHA256: + return &chachapolysha256{}, nil + default: + return nil, fmt.Errorf("unrecognized ciphersuite: %v", ciphersuite) + } +} + +// aesgcm128sha256 is the AES-128-GCM-SHA256 implementation of the ciphersuite +// interface. +type aesgcm128sha256 struct{} + +func (aesgcm128sha256) keySize() int { return aeadcrypter.AES128GCMKeySize } +func (aesgcm128sha256) nonceSize() int { return aeadcrypter.NonceSize } +func (aesgcm128sha256) trafficSecretSize() int { return aeadcrypter.SHA256DigestSize } +func (aesgcm128sha256) hashFunction() func() hash.Hash { return sha256.New } +func (aesgcm128sha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) { + return aeadcrypter.NewAESGCM(key) +} + +// aesgcm256sha384 is the AES-256-GCM-SHA384 implementation of the ciphersuite +// interface. +type aesgcm256sha384 struct{} + +func (aesgcm256sha384) keySize() int { return aeadcrypter.AES256GCMKeySize } +func (aesgcm256sha384) nonceSize() int { return aeadcrypter.NonceSize } +func (aesgcm256sha384) trafficSecretSize() int { return aeadcrypter.SHA384DigestSize } +func (aesgcm256sha384) hashFunction() func() hash.Hash { return sha512.New384 } +func (aesgcm256sha384) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) { + return aeadcrypter.NewAESGCM(key) +} + +// chachapolysha256 is the ChaChaPoly-SHA256 implementation of the ciphersuite +// interface. +type chachapolysha256 struct{} + +func (chachapolysha256) keySize() int { return aeadcrypter.Chacha20Poly1305KeySize } +func (chachapolysha256) nonceSize() int { return aeadcrypter.NonceSize } +func (chachapolysha256) trafficSecretSize() int { return aeadcrypter.SHA256DigestSize } +func (chachapolysha256) hashFunction() func() hash.Hash { return sha256.New } +func (chachapolysha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) { + return aeadcrypter.NewChachaPoly(key) +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go new file mode 100644 index 00000000000..9499cdca759 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go @@ -0,0 +1,60 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package halfconn + +import "errors" + +// counter is a 64-bit counter. +type counter struct { + val uint64 + hasOverflowed bool +} + +// newCounter creates a new counter with the initial value set to val. +func newCounter(val uint64) counter { + return counter{val: val} +} + +// value returns the current value of the counter. +func (c *counter) value() (uint64, error) { + if c.hasOverflowed { + return 0, errors.New("counter has overflowed") + } + return c.val, nil +} + +// increment increments the counter and checks for overflow. +func (c *counter) increment() { + // If the counter is already invalid due to overflow, there is no need to + // increase it. We check for the hasOverflowed flag in the call to value(). + if c.hasOverflowed { + return + } + c.val++ + if c.val == 0 { + c.hasOverflowed = true + } +} + +// reset sets the counter value to zero and sets the hasOverflowed flag to +// false. +func (c *counter) reset() { + c.val = 0 + c.hasOverflowed = false +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go new file mode 100644 index 00000000000..e05f2c36a6d --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go @@ -0,0 +1,59 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package halfconn + +import ( + "fmt" + "hash" + + "golang.org/x/crypto/hkdf" +) + +// hkdfExpander is the interface for the HKDF expansion function; see +// https://tools.ietf.org/html/rfc5869 for details. its use in TLS 1.3 is +// specified in https://tools.ietf.org/html/rfc8446#section-7.2 +type hkdfExpander interface { + // expand takes a secret, a label, and the output length in bytes, and + // returns the resulting expanded key. + expand(secret, label []byte, length int) ([]byte, error) +} + +// defaultHKDFExpander is the default HKDF expander which uses Go's crypto/hkdf +// for HKDF expansion. +type defaultHKDFExpander struct { + h func() hash.Hash +} + +// newDefaultHKDFExpander creates an instance of the default HKDF expander +// using the given hash function. +func newDefaultHKDFExpander(h func() hash.Hash) hkdfExpander { + return &defaultHKDFExpander{h: h} +} + +func (d *defaultHKDFExpander) expand(secret, label []byte, length int) ([]byte, error) { + outBuf := make([]byte, length) + n, err := hkdf.Expand(d.h, secret, label).Read(outBuf) + if err != nil { + return nil, fmt.Errorf("hkdf.Expand.Read failed with error: %v", err) + } + if n < length { + return nil, fmt.Errorf("hkdf.Expand.Read returned unexpected length, got %d, want %d", n, length) + } + return outBuf, nil +} diff --git a/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go new file mode 100644 index 00000000000..dff99ff5940 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go @@ -0,0 +1,193 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package halfconn manages the inbound or outbound traffic of a TLS 1.3 +// connection. +package halfconn + +import ( + "fmt" + "sync" + + s2apb "github.com/google/s2a-go/internal/proto/common_go_proto" + "github.com/google/s2a-go/internal/record/internal/aeadcrypter" + "golang.org/x/crypto/cryptobyte" +) + +// The constants below were taken from Section 7.2 and 7.3 in +// https://tools.ietf.org/html/rfc8446#section-7. They are used as the label +// in HKDF-Expand-Label. +const ( + tls13Key = "tls13 key" + tls13Nonce = "tls13 iv" + tls13Update = "tls13 traffic upd" +) + +// S2AHalfConnection stores the state of the TLS 1.3 connection in the +// inbound or outbound direction. +type S2AHalfConnection struct { + cs ciphersuite + expander hkdfExpander + // mutex guards sequence, aeadCrypter, trafficSecret, and nonce. + mutex sync.Mutex + aeadCrypter aeadcrypter.S2AAEADCrypter + sequence counter + trafficSecret []byte + nonce []byte +} + +// New creates a new instance of S2AHalfConnection given a ciphersuite and a +// traffic secret. +func New(ciphersuite s2apb.Ciphersuite, trafficSecret []byte, sequence uint64) (*S2AHalfConnection, error) { + cs, err := newCiphersuite(ciphersuite) + if err != nil { + return nil, fmt.Errorf("failed to create new ciphersuite: %v", ciphersuite) + } + if cs.trafficSecretSize() != len(trafficSecret) { + return nil, fmt.Errorf("supplied traffic secret must be %v bytes, given: %v bytes", cs.trafficSecretSize(), len(trafficSecret)) + } + + hc := &S2AHalfConnection{cs: cs, expander: newDefaultHKDFExpander(cs.hashFunction()), sequence: newCounter(sequence), trafficSecret: trafficSecret} + if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil { + return nil, fmt.Errorf("failed to create half connection using traffic secret: %v", err) + } + + return hc, nil +} + +// Encrypt encrypts the plaintext and computes the tag of dst and plaintext. +// dst and plaintext may fully overlap or not at all. Note that the sequence +// number will still be incremented on failure, unless the sequence has +// overflowed. +func (hc *S2AHalfConnection) Encrypt(dst, plaintext, aad []byte) ([]byte, error) { + hc.mutex.Lock() + sequence, err := hc.getAndIncrementSequence() + if err != nil { + hc.mutex.Unlock() + return nil, err + } + nonce := hc.maskedNonce(sequence) + crypter := hc.aeadCrypter + hc.mutex.Unlock() + return crypter.Encrypt(dst, plaintext, nonce, aad) +} + +// Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may +// fully overlap or not at all. Note that the sequence number will still be +// incremented on failure, unless the sequence has overflowed. +func (hc *S2AHalfConnection) Decrypt(dst, ciphertext, aad []byte) ([]byte, error) { + hc.mutex.Lock() + sequence, err := hc.getAndIncrementSequence() + if err != nil { + hc.mutex.Unlock() + return nil, err + } + nonce := hc.maskedNonce(sequence) + crypter := hc.aeadCrypter + hc.mutex.Unlock() + return crypter.Decrypt(dst, ciphertext, nonce, aad) +} + +// UpdateKey advances the traffic secret key, as specified in +// https://tools.ietf.org/html/rfc8446#section-7.2. In addition, it derives +// a new key and nonce, and resets the sequence number. +func (hc *S2AHalfConnection) UpdateKey() error { + hc.mutex.Lock() + defer hc.mutex.Unlock() + + var err error + hc.trafficSecret, err = hc.deriveSecret(hc.trafficSecret, []byte(tls13Update), hc.cs.trafficSecretSize()) + if err != nil { + return fmt.Errorf("failed to derive traffic secret: %v", err) + } + + if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil { + return fmt.Errorf("failed to update half connection: %v", err) + } + + hc.sequence.reset() + return nil +} + +// TagSize returns the tag size in bytes of the underlying AEAD crypter. +func (hc *S2AHalfConnection) TagSize() int { + return hc.aeadCrypter.TagSize() +} + +// updateCrypterAndNonce takes a new traffic secret and updates the crypter +// and nonce. Note that the mutex must be held while calling this function. +func (hc *S2AHalfConnection) updateCrypterAndNonce(newTrafficSecret []byte) error { + key, err := hc.deriveSecret(newTrafficSecret, []byte(tls13Key), hc.cs.keySize()) + if err != nil { + return fmt.Errorf("failed to update key: %v", err) + } + + hc.nonce, err = hc.deriveSecret(newTrafficSecret, []byte(tls13Nonce), hc.cs.nonceSize()) + if err != nil { + return fmt.Errorf("failed to update nonce: %v", err) + } + + hc.aeadCrypter, err = hc.cs.aeadCrypter(key) + if err != nil { + return fmt.Errorf("failed to update AEAD crypter: %v", err) + } + return nil +} + +// getAndIncrement returns the current sequence number and increments it. Note +// that the mutex must be held while calling this function. +func (hc *S2AHalfConnection) getAndIncrementSequence() (uint64, error) { + sequence, err := hc.sequence.value() + if err != nil { + return 0, err + } + hc.sequence.increment() + return sequence, nil +} + +// maskedNonce creates a copy of the nonce that is masked with the sequence +// number. Note that the mutex must be held while calling this function. +func (hc *S2AHalfConnection) maskedNonce(sequence uint64) []byte { + const uint64Size = 8 + nonce := make([]byte, len(hc.nonce)) + copy(nonce, hc.nonce) + for i := 0; i < uint64Size; i++ { + nonce[aeadcrypter.NonceSize-uint64Size+i] ^= byte(sequence >> uint64(56-uint64Size*i)) + } + return nonce +} + +// deriveSecret implements the Derive-Secret function, as specified in +// https://tools.ietf.org/html/rfc8446#section-7.1. +func (hc *S2AHalfConnection) deriveSecret(secret, label []byte, length int) ([]byte, error) { + var hkdfLabel cryptobyte.Builder + hkdfLabel.AddUint16(uint16(length)) + hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(label) + }) + // Append an empty `Context` field to the label, as specified in the RFC. + // The half connection does not use the `Context` field. + hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte("")) + }) + hkdfLabelBytes, err := hkdfLabel.Bytes() + if err != nil { + return nil, fmt.Errorf("deriveSecret failed: %v", err) + } + return hc.expander.expand(secret, hkdfLabelBytes, length) +} diff --git a/vendor/github.com/google/s2a-go/internal/record/record.go b/vendor/github.com/google/s2a-go/internal/record/record.go new file mode 100644 index 00000000000..c60515510a7 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/record.go @@ -0,0 +1,757 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package record implements the TLS 1.3 record protocol used by the S2A +// transport credentials. +package record + +import ( + "encoding/binary" + "errors" + "fmt" + "math" + "net" + "sync" + + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + "github.com/google/s2a-go/internal/record/internal/halfconn" + "github.com/google/s2a-go/internal/tokenmanager" + "google.golang.org/grpc/grpclog" +) + +// recordType is the `ContentType` as described in +// https://tools.ietf.org/html/rfc8446#section-5.1. +type recordType byte + +const ( + alert recordType = 21 + handshake recordType = 22 + applicationData recordType = 23 +) + +// keyUpdateRequest is the `KeyUpdateRequest` as described in +// https://tools.ietf.org/html/rfc8446#section-4.6.3. +type keyUpdateRequest byte + +const ( + updateNotRequested keyUpdateRequest = 0 + updateRequested keyUpdateRequest = 1 +) + +// alertDescription is the `AlertDescription` as described in +// https://tools.ietf.org/html/rfc8446#section-6. +type alertDescription byte + +const ( + closeNotify alertDescription = 0 +) + +// sessionTicketState is used to determine whether session tickets have not yet +// been received, are in the process of being received, or have finished +// receiving. +type sessionTicketState byte + +const ( + ticketsNotYetReceived sessionTicketState = 0 + receivingTickets sessionTicketState = 1 + notReceivingTickets sessionTicketState = 2 +) + +const ( + // The TLS 1.3-specific constants below (tlsRecordMaxPlaintextSize, + // tlsRecordHeaderSize, tlsRecordTypeSize) were taken from + // https://tools.ietf.org/html/rfc8446#section-5.1. + + // tlsRecordMaxPlaintextSize is the maximum size in bytes of the plaintext + // in a single TLS 1.3 record. + tlsRecordMaxPlaintextSize = 16384 // 2^14 + // tlsRecordTypeSize is the size in bytes of the TLS 1.3 record type. + tlsRecordTypeSize = 1 + // tlsTagSize is the size in bytes of the tag of the following three + // ciphersuites: AES-128-GCM-SHA256, AES-256-GCM-SHA384, + // CHACHA20-POLY1305-SHA256. + tlsTagSize = 16 + // tlsRecordMaxPayloadSize is the maximum size in bytes of the payload in a + // single TLS 1.3 record. This is the maximum size of the plaintext plus the + // record type byte and 16 bytes of the tag. + tlsRecordMaxPayloadSize = tlsRecordMaxPlaintextSize + tlsRecordTypeSize + tlsTagSize + // tlsRecordHeaderTypeSize is the size in bytes of the TLS 1.3 record + // header type. + tlsRecordHeaderTypeSize = 1 + // tlsRecordHeaderLegacyRecordVersionSize is the size in bytes of the TLS + // 1.3 record header legacy record version. + tlsRecordHeaderLegacyRecordVersionSize = 2 + // tlsRecordHeaderPayloadLengthSize is the size in bytes of the TLS 1.3 + // record header payload length. + tlsRecordHeaderPayloadLengthSize = 2 + // tlsRecordHeaderSize is the size in bytes of the TLS 1.3 record header. + tlsRecordHeaderSize = tlsRecordHeaderTypeSize + tlsRecordHeaderLegacyRecordVersionSize + tlsRecordHeaderPayloadLengthSize + // tlsRecordMaxSize + tlsRecordMaxSize = tlsRecordMaxPayloadSize + tlsRecordHeaderSize + // tlsApplicationData is the application data type of the TLS 1.3 record + // header. + tlsApplicationData = 23 + // tlsLegacyRecordVersion is the legacy record version of the TLS record. + tlsLegacyRecordVersion = 3 + // tlsAlertSize is the size in bytes of an alert of TLS 1.3. + tlsAlertSize = 2 +) + +const ( + // These are TLS 1.3 handshake-specific constants. + + // tlsHandshakeNewSessionTicketType is the prefix of a handshake new session + // ticket message of TLS 1.3. + tlsHandshakeNewSessionTicketType = 4 + // tlsHandshakeKeyUpdateType is the prefix of a handshake key update message + // of TLS 1.3. + tlsHandshakeKeyUpdateType = 24 + // tlsHandshakeMsgTypeSize is the size in bytes of the TLS 1.3 handshake + // message type field. + tlsHandshakeMsgTypeSize = 1 + // tlsHandshakeLengthSize is the size in bytes of the TLS 1.3 handshake + // message length field. + tlsHandshakeLengthSize = 3 + // tlsHandshakeKeyUpdateMsgSize is the size in bytes of the TLS 1.3 + // handshake key update message. + tlsHandshakeKeyUpdateMsgSize = 1 + // tlsHandshakePrefixSize is the size in bytes of the prefix of the TLS 1.3 + // handshake message. + tlsHandshakePrefixSize = 4 + // tlsMaxSessionTicketSize is the maximum size of a NewSessionTicket message + // in TLS 1.3. This is the sum of the max sizes of all the fields in the + // NewSessionTicket struct specified in + // https://tools.ietf.org/html/rfc8446#section-4.6.1. + tlsMaxSessionTicketSize = 131338 +) + +const ( + // outBufMaxRecords is the maximum number of records that can fit in the + // ourRecordsBuf buffer. + outBufMaxRecords = 16 + // outBufMaxSize is the maximum size (in bytes) of the outRecordsBuf buffer. + outBufMaxSize = outBufMaxRecords * tlsRecordMaxSize + // maxAllowedTickets is the maximum number of session tickets that are + // allowed. The number of tickets are limited to ensure that the size of the + // ticket queue does not grow indefinitely. S2A also keeps a limit on the + // number of tickets that it caches. + maxAllowedTickets = 5 +) + +// preConstructedKeyUpdateMsg holds the key update message. This is needed as an +// optimization so that the same message does not need to be constructed every +// time a key update message is sent. +var preConstructedKeyUpdateMsg = buildKeyUpdateRequest() + +// conn represents a secured TLS connection. It implements the net.Conn +// interface. +type conn struct { + net.Conn + // inConn is the half connection responsible for decrypting incoming bytes. + inConn *halfconn.S2AHalfConnection + // outConn is the half connection responsible for encrypting outgoing bytes. + outConn *halfconn.S2AHalfConnection + // pendingApplicationData holds data that has been read from the connection + // and decrypted, but has not yet been returned by Read. + pendingApplicationData []byte + // unusedBuf holds data read from the network that has not yet been + // decrypted. This data might not consist of a complete record. It may + // consist of several records, the last of which could be incomplete. + unusedBuf []byte + // outRecordsBuf is a buffer used to store outgoing TLS records before + // they are written to the network. + outRecordsBuf []byte + // nextRecord stores the next record info in the unusedBuf buffer. + nextRecord []byte + // overheadSize is the overhead size in bytes of each TLS 1.3 record, which + // is computed as overheadSize = header size + record type byte + tag size. + // Note that there is no padding by zeros in the overhead calculation. + overheadSize int + // readMutex guards against concurrent calls to Read. This is required since + // Close may be called during a Read. + readMutex sync.Mutex + // writeMutex guards against concurrent calls to Write. This is required + // since Close may be called during a Write, and also because a key update + // message may be written during a Read. + writeMutex sync.Mutex + // handshakeBuf holds handshake messages while they are being processed. + handshakeBuf []byte + // ticketState is the current processing state of the session tickets. + ticketState sessionTicketState + // sessionTickets holds the completed session tickets until they are sent to + // the handshaker service for processing. + sessionTickets [][]byte + // ticketSender sends session tickets to the S2A handshaker service. + ticketSender s2aTicketSender + // callComplete is a channel that blocks closing the record protocol until a + // pending call to the S2A completes. + callComplete chan bool +} + +// ConnParameters holds the parameters used for creating a new conn object. +type ConnParameters struct { + // NetConn is the TCP connection to the peer. This parameter is required. + NetConn net.Conn + // Ciphersuite is the TLS ciphersuite negotiated by the S2A handshaker + // service. This parameter is required. + Ciphersuite commonpb.Ciphersuite + // TLSVersion is the TLS version number negotiated by the S2A handshaker + // service. This parameter is required. + TLSVersion commonpb.TLSVersion + // InTrafficSecret is the traffic secret used to derive the session key for + // the inbound direction. This parameter is required. + InTrafficSecret []byte + // OutTrafficSecret is the traffic secret used to derive the session key + // for the outbound direction. This parameter is required. + OutTrafficSecret []byte + // UnusedBuf is the data read from the network that has not yet been + // decrypted. This parameter is optional. If not provided, then no + // application data was sent in the same flight of messages as the final + // handshake message. + UnusedBuf []byte + // InSequence is the sequence number of the next, incoming, TLS record. + // This parameter is required. + InSequence uint64 + // OutSequence is the sequence number of the next, outgoing, TLS record. + // This parameter is required. + OutSequence uint64 + // HSAddr stores the address of the S2A handshaker service. This parameter + // is optional. If not provided, then TLS resumption is disabled. + HSAddr string + // ConnectionId is the connection identifier that was created and sent by + // S2A at the end of a handshake. + ConnectionID uint64 + // LocalIdentity is the local identity that was used by S2A during session + // setup and included in the session result. + LocalIdentity *commonpb.Identity + // EnsureProcessSessionTickets allows users to wait and ensure that all + // available session tickets are sent to S2A before a process completes. + EnsureProcessSessionTickets *sync.WaitGroup +} + +// NewConn creates a TLS record protocol that wraps the TCP connection. +func NewConn(o *ConnParameters) (net.Conn, error) { + if o == nil { + return nil, errors.New("conn options must not be nil") + } + if o.TLSVersion != commonpb.TLSVersion_TLS1_3 { + return nil, errors.New("TLS version must be TLS 1.3") + } + + inConn, err := halfconn.New(o.Ciphersuite, o.InTrafficSecret, o.InSequence) + if err != nil { + return nil, fmt.Errorf("failed to create inbound half connection: %v", err) + } + outConn, err := halfconn.New(o.Ciphersuite, o.OutTrafficSecret, o.OutSequence) + if err != nil { + return nil, fmt.Errorf("failed to create outbound half connection: %v", err) + } + + // The tag size for the in/out connections should be the same. + overheadSize := tlsRecordHeaderSize + tlsRecordTypeSize + inConn.TagSize() + var unusedBuf []byte + if o.UnusedBuf == nil { + // We pre-allocate unusedBuf to be of size + // 2*tlsRecordMaxSize-1 during initialization. We only read from the + // network into unusedBuf when unusedBuf does not contain a complete + // record and the incomplete record is at most tlsRecordMaxSize-1 + // (bytes). And we read at most tlsRecordMaxSize bytes of data from the + // network into unusedBuf at one time. Therefore, 2*tlsRecordMaxSize-1 + // is large enough to buffer data read from the network. + unusedBuf = make([]byte, 0, 2*tlsRecordMaxSize-1) + } else { + unusedBuf = make([]byte, len(o.UnusedBuf)) + copy(unusedBuf, o.UnusedBuf) + } + + tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + if err != nil { + grpclog.Infof("failed to create single token access token manager: %v", err) + } + + s2aConn := &conn{ + Conn: o.NetConn, + inConn: inConn, + outConn: outConn, + unusedBuf: unusedBuf, + outRecordsBuf: make([]byte, tlsRecordMaxSize), + nextRecord: unusedBuf, + overheadSize: overheadSize, + ticketState: ticketsNotYetReceived, + // Pre-allocate the buffer for one session ticket message and the max + // plaintext size. This is the largest size that handshakeBuf will need + // to hold. The largest incomplete handshake message is the + // [handshake header size] + [max session ticket size] - 1. + // Then, tlsRecordMaxPlaintextSize is the maximum size that will be + // appended to the handshakeBuf before the handshake message is + // completed. Therefore, the buffer size below should be large enough to + // buffer any handshake messages. + handshakeBuf: make([]byte, 0, tlsHandshakePrefixSize+tlsMaxSessionTicketSize+tlsRecordMaxPlaintextSize-1), + ticketSender: &ticketSender{ + hsAddr: o.HSAddr, + connectionID: o.ConnectionID, + localIdentity: o.LocalIdentity, + tokenManager: tokenManager, + ensureProcessSessionTickets: o.EnsureProcessSessionTickets, + }, + callComplete: make(chan bool), + } + return s2aConn, nil +} + +// Read reads and decrypts a TLS 1.3 record from the underlying connection, and +// copies any application data received from the peer into b. If the size of the +// payload is greater than len(b), Read retains the remaining bytes in an +// internal buffer, and subsequent calls to Read will read from this buffer +// until it is exhausted. At most 1 TLS record worth of application data is +// written to b for each call to Read. +// +// Note that for the user to efficiently call this method, the user should +// ensure that the buffer b is allocated such that the buffer does not have any +// unused segments. This can be done by calling Read via io.ReadFull, which +// continually calls Read until the specified buffer has been filled. Also note +// that the user should close the connection via Close() if an error is thrown +// by a call to Read. +func (p *conn) Read(b []byte) (n int, err error) { + p.readMutex.Lock() + defer p.readMutex.Unlock() + // Check if p.pendingApplication data has leftover application data from + // the previous call to Read. + if len(p.pendingApplicationData) == 0 { + // Read a full record from the wire. + record, err := p.readFullRecord() + if err != nil { + return 0, err + } + // Now we have a complete record, so split the header and validate it + // The TLS record is split into 2 pieces: the record header and the + // payload. The payload has the following form: + // [payload] = [ciphertext of application data] + // + [ciphertext of record type byte] + // + [(optionally) ciphertext of padding by zeros] + // + [tag] + header, payload, err := splitAndValidateHeader(record) + if err != nil { + return 0, err + } + // Decrypt the ciphertext. + p.pendingApplicationData, err = p.inConn.Decrypt(payload[:0], payload, header) + if err != nil { + return 0, err + } + // Remove the padding by zeros and the record type byte from the + // p.pendingApplicationData buffer. + msgType, err := p.stripPaddingAndType() + if err != nil { + return 0, err + } + // Check that the length of the plaintext after stripping the padding + // and record type byte is under the maximum plaintext size. + if len(p.pendingApplicationData) > tlsRecordMaxPlaintextSize { + return 0, errors.New("plaintext size larger than maximum") + } + // The expected message types are application data, alert, and + // handshake. For application data, the bytes are directly copied into + // b. For an alert, the type of the alert is checked and the connection + // is closed on a close notify alert. For a handshake message, the + // handshake message type is checked. The handshake message type can be + // a key update type, for which we advance the traffic secret, and a + // new session ticket type, for which we send the received ticket to S2A + // for processing. + switch msgType { + case applicationData: + if len(p.handshakeBuf) > 0 { + return 0, errors.New("application data received while processing fragmented handshake messages") + } + if p.ticketState == receivingTickets { + p.ticketState = notReceivingTickets + grpclog.Infof("Sending session tickets to S2A.") + p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete) + } + case alert: + return 0, p.handleAlertMessage() + case handshake: + if err = p.handleHandshakeMessage(); err != nil { + return 0, err + } + return 0, nil + default: + return 0, errors.New("unknown record type") + } + } + // Write as much application data as possible to b, the output buffer. + n = copy(b, p.pendingApplicationData) + p.pendingApplicationData = p.pendingApplicationData[n:] + return n, nil +} + +// Write divides b into segments of size tlsRecordMaxPlaintextSize, builds a +// TLS 1.3 record (of type "application data") from each segment, and sends +// the record to the peer. It returns the number of plaintext bytes that were +// successfully sent to the peer. +func (p *conn) Write(b []byte) (n int, err error) { + p.writeMutex.Lock() + defer p.writeMutex.Unlock() + return p.writeTLSRecord(b, tlsApplicationData) +} + +// writeTLSRecord divides b into segments of size maxPlaintextBytesPerRecord, +// builds a TLS 1.3 record (of type recordType) from each segment, and sends +// the record to the peer. It returns the number of plaintext bytes that were +// successfully sent to the peer. +func (p *conn) writeTLSRecord(b []byte, recordType byte) (n int, err error) { + // Create a record of only header, record type, and tag if given empty + // byte array. + if len(b) == 0 { + recordEndIndex, _, err := p.buildRecord(b, recordType, 0) + if err != nil { + return 0, err + } + + // Write the bytes stored in outRecordsBuf to p.Conn. Since we return + // the number of plaintext bytes written without overhead, we will + // always return 0 while p.Conn.Write returns the entire record length. + _, err = p.Conn.Write(p.outRecordsBuf[:recordEndIndex]) + return 0, err + } + + numRecords := int(math.Ceil(float64(len(b)) / float64(tlsRecordMaxPlaintextSize))) + totalRecordsSize := len(b) + numRecords*p.overheadSize + partialBSize := len(b) + if totalRecordsSize > outBufMaxSize { + totalRecordsSize = outBufMaxSize + partialBSize = outBufMaxRecords * tlsRecordMaxPlaintextSize + } + if len(p.outRecordsBuf) < totalRecordsSize { + p.outRecordsBuf = make([]byte, totalRecordsSize) + } + for bStart := 0; bStart < len(b); bStart += partialBSize { + bEnd := bStart + partialBSize + if bEnd > len(b) { + bEnd = len(b) + } + partialB := b[bStart:bEnd] + recordEndIndex := 0 + for len(partialB) > 0 { + recordEndIndex, partialB, err = p.buildRecord(partialB, recordType, recordEndIndex) + if err != nil { + // Return the amount of bytes written prior to the error. + return bStart, err + } + } + // Write the bytes stored in outRecordsBuf to p.Conn. If there is an + // error, calculate the total number of plaintext bytes of complete + // records successfully written to the peer and return it. + nn, err := p.Conn.Write(p.outRecordsBuf[:recordEndIndex]) + if err != nil { + numberOfCompletedRecords := int(math.Floor(float64(nn) / float64(tlsRecordMaxSize))) + return bStart + numberOfCompletedRecords*tlsRecordMaxPlaintextSize, err + } + } + return len(b), nil +} + +// buildRecord builds a TLS 1.3 record of type recordType from plaintext, +// and writes the record to outRecordsBuf at recordStartIndex. The record will +// have at most tlsRecordMaxPlaintextSize bytes of payload. It returns the +// index of outRecordsBuf where the current record ends, as well as any +// remaining plaintext bytes. +func (p *conn) buildRecord(plaintext []byte, recordType byte, recordStartIndex int) (n int, remainingPlaintext []byte, err error) { + // Construct the payload, which consists of application data and record type. + dataLen := len(plaintext) + if dataLen > tlsRecordMaxPlaintextSize { + dataLen = tlsRecordMaxPlaintextSize + } + remainingPlaintext = plaintext[dataLen:] + newRecordBuf := p.outRecordsBuf[recordStartIndex:] + + copy(newRecordBuf[tlsRecordHeaderSize:], plaintext[:dataLen]) + newRecordBuf[tlsRecordHeaderSize+dataLen] = recordType + payload := newRecordBuf[tlsRecordHeaderSize : tlsRecordHeaderSize+dataLen+1] // 1 is for the recordType. + // Construct the header. + newRecordBuf[0] = tlsApplicationData + newRecordBuf[1] = tlsLegacyRecordVersion + newRecordBuf[2] = tlsLegacyRecordVersion + binary.BigEndian.PutUint16(newRecordBuf[3:], uint16(len(payload)+tlsTagSize)) + header := newRecordBuf[:tlsRecordHeaderSize] + + // Encrypt the payload using header as aad. + encryptedPayload, err := p.outConn.Encrypt(newRecordBuf[tlsRecordHeaderSize:][:0], payload, header) + if err != nil { + return 0, plaintext, err + } + recordStartIndex += len(header) + len(encryptedPayload) + return recordStartIndex, remainingPlaintext, nil +} + +func (p *conn) Close() error { + p.readMutex.Lock() + defer p.readMutex.Unlock() + p.writeMutex.Lock() + defer p.writeMutex.Unlock() + // If p.ticketState is equal to notReceivingTickets, then S2A has + // been sent a flight of session tickets, and we must wait for the + // call to S2A to complete before closing the record protocol. + if p.ticketState == notReceivingTickets { + <-p.callComplete + grpclog.Infof("Safe to close the connection because sending tickets to S2A is (already) complete.") + } + return p.Conn.Close() +} + +// stripPaddingAndType strips the padding by zeros and record type from +// p.pendingApplicationData and returns the record type. Note that +// p.pendingApplicationData should be of the form: +// [application data] + [record type byte] + [trailing zeros] +func (p *conn) stripPaddingAndType() (recordType, error) { + if len(p.pendingApplicationData) == 0 { + return 0, errors.New("application data had length 0") + } + i := len(p.pendingApplicationData) - 1 + // Search for the index of the record type byte. + for i > 0 { + if p.pendingApplicationData[i] != 0 { + break + } + i-- + } + rt := recordType(p.pendingApplicationData[i]) + p.pendingApplicationData = p.pendingApplicationData[:i] + return rt, nil +} + +// readFullRecord reads from the wire until a record is completed and returns +// the full record. +func (p *conn) readFullRecord() (fullRecord []byte, err error) { + fullRecord, p.nextRecord, err = parseReadBuffer(p.nextRecord, tlsRecordMaxPayloadSize) + if err != nil { + return nil, err + } + // Check whether the next record to be decrypted has been completely + // received. + if len(fullRecord) == 0 { + copy(p.unusedBuf, p.nextRecord) + p.unusedBuf = p.unusedBuf[:len(p.nextRecord)] + // Always copy next incomplete record to the beginning of the + // unusedBuf buffer and reset nextRecord to it. + p.nextRecord = p.unusedBuf + } + // Keep reading from the wire until we have a complete record. + for len(fullRecord) == 0 { + if len(p.unusedBuf) == cap(p.unusedBuf) { + tmp := make([]byte, len(p.unusedBuf), cap(p.unusedBuf)+tlsRecordMaxSize) + copy(tmp, p.unusedBuf) + p.unusedBuf = tmp + } + n, err := p.Conn.Read(p.unusedBuf[len(p.unusedBuf):min(cap(p.unusedBuf), len(p.unusedBuf)+tlsRecordMaxSize)]) + if err != nil { + return nil, err + } + p.unusedBuf = p.unusedBuf[:len(p.unusedBuf)+n] + fullRecord, p.nextRecord, err = parseReadBuffer(p.unusedBuf, tlsRecordMaxPayloadSize) + if err != nil { + return nil, err + } + } + return fullRecord, nil +} + +// parseReadBuffer parses the provided buffer and returns a full record and any +// remaining bytes in that buffer. If the record is incomplete, nil is returned +// for the first return value and the given byte buffer is returned for the +// second return value. The length of the payload specified by the header should +// not be greater than maxLen, otherwise an error is returned. Note that this +// function does not allocate or copy any buffers. +func parseReadBuffer(b []byte, maxLen uint16) (fullRecord, remaining []byte, err error) { + // If the header is not complete, return the provided buffer as remaining + // buffer. + if len(b) < tlsRecordHeaderSize { + return nil, b, nil + } + msgLenField := b[tlsRecordHeaderTypeSize+tlsRecordHeaderLegacyRecordVersionSize : tlsRecordHeaderSize] + length := binary.BigEndian.Uint16(msgLenField) + if length > maxLen { + return nil, nil, fmt.Errorf("record length larger than the limit %d", maxLen) + } + if len(b) < int(length)+tlsRecordHeaderSize { + // Record is not complete yet. + return nil, b, nil + } + return b[:tlsRecordHeaderSize+length], b[tlsRecordHeaderSize+length:], nil +} + +// splitAndValidateHeader splits the header from the payload in the TLS 1.3 +// record and returns them. Note that the header is checked for validity, and an +// error is returned when an invalid header is parsed. Also note that this +// function does not allocate or copy any buffers. +func splitAndValidateHeader(record []byte) (header, payload []byte, err error) { + if len(record) < tlsRecordHeaderSize { + return nil, nil, fmt.Errorf("record was smaller than the header size") + } + header = record[:tlsRecordHeaderSize] + payload = record[tlsRecordHeaderSize:] + if header[0] != tlsApplicationData { + return nil, nil, fmt.Errorf("incorrect type in the header") + } + // Check the legacy record version, which should be 0x03, 0x03. + if header[1] != 0x03 || header[2] != 0x03 { + return nil, nil, fmt.Errorf("incorrect legacy record version in the header") + } + return header, payload, nil +} + +// handleAlertMessage handles an alert message. +func (p *conn) handleAlertMessage() error { + if len(p.pendingApplicationData) != tlsAlertSize { + return errors.New("invalid alert message size") + } + alertType := p.pendingApplicationData[1] + // Clear the body of the alert message. + p.pendingApplicationData = p.pendingApplicationData[:0] + if alertType == byte(closeNotify) { + return errors.New("received a close notify alert") + } + // TODO(matthewstevenson88): Add support for more alert types. + return fmt.Errorf("received an unrecognized alert type: %v", alertType) +} + +// parseHandshakeHeader parses a handshake message from the handshake buffer. +// It returns the message type, the message length, the message, the raw message +// that includes the type and length bytes and a flag indicating whether the +// handshake message has been fully parsed. i.e. whether the entire handshake +// message was in the handshake buffer. +func (p *conn) parseHandshakeMsg() (msgType byte, msgLen uint32, msg []byte, rawMsg []byte, ok bool) { + // Handle the case where the 4 byte handshake header is fragmented. + if len(p.handshakeBuf) < tlsHandshakePrefixSize { + return 0, 0, nil, nil, false + } + msgType = p.handshakeBuf[0] + msgLen = bigEndianInt24(p.handshakeBuf[tlsHandshakeMsgTypeSize : tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize]) + if msgLen > uint32(len(p.handshakeBuf)-tlsHandshakePrefixSize) { + return 0, 0, nil, nil, false + } + msg = p.handshakeBuf[tlsHandshakePrefixSize : tlsHandshakePrefixSize+msgLen] + rawMsg = p.handshakeBuf[:tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize+msgLen] + p.handshakeBuf = p.handshakeBuf[tlsHandshakePrefixSize+msgLen:] + return msgType, msgLen, msg, rawMsg, true +} + +// handleHandshakeMessage handles a handshake message. Note that the first +// complete handshake message from the handshake buffer is removed, if it +// exists. +func (p *conn) handleHandshakeMessage() error { + // Copy the pending application data to the handshake buffer. At this point, + // we are guaranteed that the pending application data contains only parts + // of a handshake message. + p.handshakeBuf = append(p.handshakeBuf, p.pendingApplicationData...) + p.pendingApplicationData = p.pendingApplicationData[:0] + // Several handshake messages may be coalesced into a single record. + // Continue reading them until the handshake buffer is empty. + for len(p.handshakeBuf) > 0 { + handshakeMsgType, msgLen, msg, rawMsg, ok := p.parseHandshakeMsg() + if !ok { + // The handshake could not be fully parsed, so read in another + // record and try again later. + break + } + switch handshakeMsgType { + case tlsHandshakeKeyUpdateType: + if msgLen != tlsHandshakeKeyUpdateMsgSize { + return errors.New("invalid handshake key update message length") + } + if len(p.handshakeBuf) != 0 { + return errors.New("key update message must be the last message of a handshake record") + } + if err := p.handleKeyUpdateMsg(msg); err != nil { + return err + } + case tlsHandshakeNewSessionTicketType: + // Ignore tickets that are received after a batch of tickets has + // been sent to S2A. + if p.ticketState == notReceivingTickets { + continue + } + if p.ticketState == ticketsNotYetReceived { + p.ticketState = receivingTickets + } + p.sessionTickets = append(p.sessionTickets, rawMsg) + if len(p.sessionTickets) == maxAllowedTickets { + p.ticketState = notReceivingTickets + grpclog.Infof("Sending session tickets to S2A.") + p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete) + } + default: + return errors.New("unknown handshake message type") + } + } + return nil +} + +func buildKeyUpdateRequest() []byte { + b := make([]byte, tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize) + b[0] = tlsHandshakeKeyUpdateType + b[1] = 0 + b[2] = 0 + b[3] = tlsHandshakeKeyUpdateMsgSize + b[4] = byte(updateNotRequested) + return b +} + +// handleKeyUpdateMsg handles a key update message. +func (p *conn) handleKeyUpdateMsg(msg []byte) error { + keyUpdateRequest := msg[0] + if keyUpdateRequest != byte(updateNotRequested) && + keyUpdateRequest != byte(updateRequested) { + return errors.New("invalid handshake key update message") + } + if err := p.inConn.UpdateKey(); err != nil { + return err + } + // Send a key update message back to the peer if requested. + if keyUpdateRequest == byte(updateRequested) { + p.writeMutex.Lock() + defer p.writeMutex.Unlock() + n, err := p.writeTLSRecord(preConstructedKeyUpdateMsg, byte(handshake)) + if err != nil { + return err + } + if n != tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize { + return errors.New("key update request message wrote less bytes than expected") + } + if err = p.outConn.UpdateKey(); err != nil { + return err + } + } + return nil +} + +// bidEndianInt24 converts the given byte buffer of at least size 3 and +// outputs the resulting 24 bit integer as a uint32. This is needed because +// TLS 1.3 requires 3 byte integers, and the binary.BigEndian package does +// not provide a way to transform a byte buffer into a 3 byte integer. +func bigEndianInt24(b []byte) uint32 { + _ = b[2] // bounds check hint to compiler; see golang.org/issue/14808 + return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16 +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/github.com/google/s2a-go/internal/record/ticketsender.go b/vendor/github.com/google/s2a-go/internal/record/ticketsender.go new file mode 100644 index 00000000000..33fa3c55d47 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/record/ticketsender.go @@ -0,0 +1,176 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package record + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/google/s2a-go/internal/handshaker/service" + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto" + "github.com/google/s2a-go/internal/tokenmanager" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" +) + +// sessionTimeout is the timeout for creating a session with the S2A handshaker +// service. +const sessionTimeout = time.Second * 5 + +// s2aTicketSender sends session tickets to the S2A handshaker service. +type s2aTicketSender interface { + // sendTicketsToS2A sends the given session tickets to the S2A handshaker + // service. + sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool) +} + +// ticketStream is the stream used to send and receive session information. +type ticketStream interface { + Send(*s2apb.SessionReq) error + Recv() (*s2apb.SessionResp, error) +} + +type ticketSender struct { + // hsAddr stores the address of the S2A handshaker service. + hsAddr string + // connectionID is the connection identifier that was created and sent by + // S2A at the end of a handshake. + connectionID uint64 + // localIdentity is the local identity that was used by S2A during session + // setup and included in the session result. + localIdentity *commonpb.Identity + // tokenManager manages access tokens for authenticating to S2A. + tokenManager tokenmanager.AccessTokenManager + // ensureProcessSessionTickets allows users to wait and ensure that all + // available session tickets are sent to S2A before a process completes. + ensureProcessSessionTickets *sync.WaitGroup +} + +// sendTicketsToS2A sends the given sessionTickets to the S2A handshaker +// service. This is done asynchronously and writes to the error logs if an error +// occurs. +func (t *ticketSender) sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool) { + // Note that the goroutine is in the function rather than at the caller + // because the fake ticket sender used for testing must run synchronously + // so that the session tickets can be accessed from it after the tests have + // been run. + if t.ensureProcessSessionTickets != nil { + t.ensureProcessSessionTickets.Add(1) + } + go func() { + if err := func() error { + defer func() { + if t.ensureProcessSessionTickets != nil { + t.ensureProcessSessionTickets.Done() + } + }() + hsConn, err := service.Dial(t.hsAddr) + if err != nil { + return err + } + client := s2apb.NewS2AServiceClient(hsConn) + ctx, cancel := context.WithTimeout(context.Background(), sessionTimeout) + defer cancel() + session, err := client.SetUpSession(ctx) + if err != nil { + return err + } + defer func() { + if err := session.CloseSend(); err != nil { + grpclog.Error(err) + } + }() + return t.writeTicketsToStream(session, sessionTickets) + }(); err != nil { + grpclog.Errorf("failed to send resumption tickets to S2A with identity: %v, %v", + t.localIdentity, err) + } + callComplete <- true + close(callComplete) + }() +} + +// writeTicketsToStream writes the given session tickets to the given stream. +func (t *ticketSender) writeTicketsToStream(stream ticketStream, sessionTickets [][]byte) error { + if err := stream.Send( + &s2apb.SessionReq{ + ReqOneof: &s2apb.SessionReq_ResumptionTicket{ + ResumptionTicket: &s2apb.ResumptionTicketReq{ + InBytes: sessionTickets, + ConnectionId: t.connectionID, + LocalIdentity: t.localIdentity, + }, + }, + AuthMechanisms: t.getAuthMechanisms(), + }, + ); err != nil { + return err + } + sessionResp, err := stream.Recv() + if err != nil { + return err + } + if sessionResp.GetStatus().GetCode() != uint32(codes.OK) { + return fmt.Errorf("s2a session ticket response had error status: %v, %v", + sessionResp.GetStatus().GetCode(), sessionResp.GetStatus().GetDetails()) + } + return nil +} + +func (t *ticketSender) getAuthMechanisms() []*s2apb.AuthenticationMechanism { + if t.tokenManager == nil { + return nil + } + // First handle the special case when no local identity has been provided + // by the application. In this case, an AuthenticationMechanism with no local + // identity will be sent. + if t.localIdentity == nil { + token, err := t.tokenManager.DefaultToken() + if err != nil { + grpclog.Infof("unable to get token for empty local identity: %v", err) + return nil + } + return []*s2apb.AuthenticationMechanism{ + { + MechanismOneof: &s2apb.AuthenticationMechanism_Token{ + Token: token, + }, + }, + } + } + + // Next, handle the case where the application (or the S2A) has specified + // a local identity. + token, err := t.tokenManager.Token(t.localIdentity) + if err != nil { + grpclog.Infof("unable to get token for local identity %v: %v", t.localIdentity, err) + return nil + } + return []*s2apb.AuthenticationMechanism{ + { + Identity: t.localIdentity, + MechanismOneof: &s2apb.AuthenticationMechanism_Token{ + Token: token, + }, + }, + } +} diff --git a/vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go b/vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go new file mode 100644 index 00000000000..ec96ba3b6a6 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go @@ -0,0 +1,70 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package tokenmanager provides tokens for authenticating to S2A. +package tokenmanager + +import ( + "fmt" + "os" + + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" +) + +const ( + s2aAccessTokenEnvironmentVariable = "S2A_ACCESS_TOKEN" +) + +// AccessTokenManager manages tokens for authenticating to S2A. +type AccessTokenManager interface { + // DefaultToken returns a token that an application with no specified local + // identity must use to authenticate to S2A. + DefaultToken() (token string, err error) + // Token returns a token that an application with local identity equal to + // identity must use to authenticate to S2A. + Token(identity *commonpb.Identity) (token string, err error) +} + +type singleTokenAccessTokenManager struct { + token string +} + +// NewSingleTokenAccessTokenManager returns a new AccessTokenManager instance +// that will always manage the same token. +// +// The token to be managed is read from the s2aAccessTokenEnvironmentVariable +// environment variable. If this environment variable is not set, then this +// function returns an error. +func NewSingleTokenAccessTokenManager() (AccessTokenManager, error) { + token, variableExists := os.LookupEnv(s2aAccessTokenEnvironmentVariable) + if !variableExists { + return nil, fmt.Errorf("%s environment variable is not set", s2aAccessTokenEnvironmentVariable) + } + return &singleTokenAccessTokenManager{token: token}, nil +} + +// DefaultToken always returns the token managed by the +// singleTokenAccessTokenManager. +func (m *singleTokenAccessTokenManager) DefaultToken() (string, error) { + return m.token, nil +} + +// Token always returns the token managed by the singleTokenAccessTokenManager. +func (m *singleTokenAccessTokenManager) Token(*commonpb.Identity) (string, error) { + return m.token, nil +} diff --git a/vendor/github.com/google/s2a-go/internal/v2/README.md b/vendor/github.com/google/s2a-go/internal/v2/README.md new file mode 100644 index 00000000000..3806d1e9ccc --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/README.md @@ -0,0 +1 @@ +**This directory has the implementation of the S2Av2's gRPC-Go client libraries** diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go b/vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go new file mode 100644 index 00000000000..cc811879b53 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go @@ -0,0 +1,122 @@ +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package certverifier offloads verifications to S2Av2. +package certverifier + +import ( + "crypto/x509" + "fmt" + + "github.com/google/s2a-go/stream" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +// VerifyClientCertificateChain builds a SessionReq, sends it to S2Av2 and +// receives a SessionResp. +func VerifyClientCertificateChain(verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + // Offload verification to S2Av2. + if grpclog.V(1) { + grpclog.Infof("Sending request to S2Av2 for client peer cert chain validation.") + } + if err := s2AStream.Send(&s2av2pb.SessionReq{ + ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{ + ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{ + Mode: verificationMode, + PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer_{ + ClientPeer: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer{ + CertificateChain: rawCerts, + }, + }, + }, + }, + }); err != nil { + grpclog.Infof("Failed to send request to S2Av2 for client peer cert chain validation.") + return err + } + + // Get the response from S2Av2. + resp, err := s2AStream.Recv() + if err != nil { + grpclog.Infof("Failed to receive client peer cert chain validation response from S2Av2.") + return err + } + + // Parse the response. + if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) { + return fmt.Errorf("failed to offload client cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details) + + } + + if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS { + return fmt.Errorf("client cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails) + } + + return nil + } +} + +// VerifyServerCertificateChain builds a SessionReq, sends it to S2Av2 and +// receives a SessionResp. +func VerifyServerCertificateChain(hostname string, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream, serverAuthorizationPolicy []byte) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + // Offload verification to S2Av2. + if grpclog.V(1) { + grpclog.Infof("Sending request to S2Av2 for server peer cert chain validation.") + } + if err := s2AStream.Send(&s2av2pb.SessionReq{ + ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{ + ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{ + Mode: verificationMode, + PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer_{ + ServerPeer: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer{ + CertificateChain: rawCerts, + ServerHostname: hostname, + SerializedUnrestrictedClientPolicy: serverAuthorizationPolicy, + }, + }, + }, + }, + }); err != nil { + grpclog.Infof("Failed to send request to S2Av2 for server peer cert chain validation.") + return err + } + + // Get the response from S2Av2. + resp, err := s2AStream.Recv() + if err != nil { + grpclog.Infof("Failed to receive server peer cert chain validation response from S2Av2.") + return err + } + + // Parse the response. + if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) { + return fmt.Errorf("failed to offload server cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details) + } + + if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS { + return fmt.Errorf("server cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails) + } + + return nil + } +} diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der new file mode 100644 index 00000000000..958f3cfaddf Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der new file mode 100644 index 00000000000..d2817641baf Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der new file mode 100644 index 00000000000..d8c3710c85f Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der new file mode 100644 index 00000000000..dae619c0975 Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der new file mode 100644 index 00000000000..ce7f8d31d68 Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der new file mode 100644 index 00000000000..04b0d73600b Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go new file mode 100644 index 00000000000..e7478d43fbc --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go @@ -0,0 +1,186 @@ +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package remotesigner offloads private key operations to S2Av2. +package remotesigner + +import ( + "crypto" + "crypto/rsa" + "crypto/x509" + "fmt" + "io" + + "github.com/google/s2a-go/stream" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +// remoteSigner implementes the crypto.Signer interface. +type remoteSigner struct { + leafCert *x509.Certificate + s2AStream stream.S2AStream +} + +// New returns an instance of RemoteSigner, an implementation of the +// crypto.Signer interface. +func New(leafCert *x509.Certificate, s2AStream stream.S2AStream) crypto.Signer { + return &remoteSigner{leafCert, s2AStream} +} + +func (s *remoteSigner) Public() crypto.PublicKey { + return s.leafCert.PublicKey +} + +func (s *remoteSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + signatureAlgorithm, err := getSignatureAlgorithm(opts, s.leafCert) + if err != nil { + return nil, err + } + + req, err := getSignReq(signatureAlgorithm, digest) + if err != nil { + return nil, err + } + if grpclog.V(1) { + grpclog.Infof("Sending request to S2Av2 for signing operation.") + } + if err := s.s2AStream.Send(&s2av2pb.SessionReq{ + ReqOneof: &s2av2pb.SessionReq_OffloadPrivateKeyOperationReq{ + OffloadPrivateKeyOperationReq: req, + }, + }); err != nil { + grpclog.Infof("Failed to send request to S2Av2 for signing operation.") + return nil, err + } + + resp, err := s.s2AStream.Recv() + if err != nil { + grpclog.Infof("Failed to receive signing operation response from S2Av2.") + return nil, err + } + + if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) { + return nil, fmt.Errorf("failed to offload signing with private key to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details) + } + + return resp.GetOffloadPrivateKeyOperationResp().GetOutBytes(), nil +} + +// getCert returns the leafCert field in s. +func (s *remoteSigner) getCert() *x509.Certificate { + return s.leafCert +} + +// getStream returns the s2AStream field in s. +func (s *remoteSigner) getStream() stream.S2AStream { + return s.s2AStream +} + +func getSignReq(signatureAlgorithm s2av2pb.SignatureAlgorithm, digest []byte) (*s2av2pb.OffloadPrivateKeyOperationReq, error) { + if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256) { + return &s2av2pb.OffloadPrivateKeyOperationReq{ + Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN, + SignatureAlgorithm: signatureAlgorithm, + InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha256Digest{ + Sha256Digest: digest, + }, + }, nil + } else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384) { + return &s2av2pb.OffloadPrivateKeyOperationReq{ + Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN, + SignatureAlgorithm: signatureAlgorithm, + InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha384Digest{ + Sha384Digest: digest, + }, + }, nil + } else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519) { + return &s2av2pb.OffloadPrivateKeyOperationReq{ + Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN, + SignatureAlgorithm: signatureAlgorithm, + InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha512Digest{ + Sha512Digest: digest, + }, + }, nil + } else { + return nil, fmt.Errorf("unknown signature algorithm: %v", signatureAlgorithm) + } +} + +// getSignatureAlgorithm returns the signature algorithm that S2A must use when +// performing a signing operation that has been offloaded by an application +// using the crypto/tls libraries. +func getSignatureAlgorithm(opts crypto.SignerOpts, leafCert *x509.Certificate) (s2av2pb.SignatureAlgorithm, error) { + if opts == nil || leafCert == nil { + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm") + } + switch leafCert.PublicKeyAlgorithm { + case x509.RSA: + if rsaPSSOpts, ok := opts.(*rsa.PSSOptions); ok { + return rsaPSSAlgorithm(rsaPSSOpts) + } + return rsaPPKCS1Algorithm(opts) + case x509.ECDSA: + return ecdsaAlgorithm(opts) + case x509.Ed25519: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519, nil + default: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm: %q", leafCert.PublicKeyAlgorithm) + } +} + +func rsaPSSAlgorithm(opts *rsa.PSSOptions) (s2av2pb.SignatureAlgorithm, error) { + switch opts.HashFunc() { + case crypto.SHA256: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256, nil + case crypto.SHA384: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384, nil + case crypto.SHA512: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512, nil + default: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm") + } +} + +func rsaPPKCS1Algorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) { + switch opts.HashFunc() { + case crypto.SHA256: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256, nil + case crypto.SHA384: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384, nil + case crypto.SHA512: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512, nil + default: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm") + } +} + +func ecdsaAlgorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) { + switch opts.HashFunc() { + case crypto.SHA256: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256, nil + case crypto.SHA384: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384, nil + case crypto.SHA512: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512, nil + default: + return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm") + } +} diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der new file mode 100644 index 00000000000..d8c3710c85f Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem new file mode 100644 index 00000000000..493a5a26481 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 +a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 +OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 +RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK +P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 +HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu +0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 +EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 +/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA +QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ +nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD +X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco +pKklVz0= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem new file mode 100644 index 00000000000..55a7f10c742 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF +l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj ++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G +4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA +xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh +68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ +/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL +Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA +VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 +9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH +MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt +aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq +xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx +2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv +EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z +aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq +udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs +VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm +56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT +GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V +Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm +HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q +BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH +qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh +GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der new file mode 100644 index 00000000000..04b0d73600b Binary files /dev/null and b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der differ diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem new file mode 100644 index 00000000000..0f98322c724 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT +fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ +qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE +xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es +Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 +Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM +ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR +e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X +POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl +AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg +odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ +PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN +Dhm6uZM= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem new file mode 100644 index 00000000000..81afea783df --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs +8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO +QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk +XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA +Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc +gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf +LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl +jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 +4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q +Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P +nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 +drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE +duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 +L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG +06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm +eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD +uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 +lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL +a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb +hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ +7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j +r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 +eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD +B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz +7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/s2av2.go b/vendor/github.com/google/s2a-go/internal/v2/s2av2.go new file mode 100644 index 00000000000..ff172883f24 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/s2av2.go @@ -0,0 +1,354 @@ +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package v2 provides the S2Av2 transport credentials used by a gRPC +// application. +package v2 + +import ( + "context" + "crypto/tls" + "errors" + "net" + "os" + "time" + + "github.com/golang/protobuf/proto" + "github.com/google/s2a-go/fallback" + "github.com/google/s2a-go/internal/handshaker/service" + "github.com/google/s2a-go/internal/tokenmanager" + "github.com/google/s2a-go/internal/v2/tlsconfigstore" + "github.com/google/s2a-go/stream" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" + + commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto" + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +const ( + s2aSecurityProtocol = "tls" + defaultS2ATimeout = 3 * time.Second +) + +// An environment variable, which sets the timeout enforced on the connection to the S2A service for handshake. +const s2aTimeoutEnv = "S2A_TIMEOUT" + +type s2av2TransportCreds struct { + info *credentials.ProtocolInfo + isClient bool + serverName string + s2av2Address string + tokenManager *tokenmanager.AccessTokenManager + // localIdentity should only be used by the client. + localIdentity *commonpbv1.Identity + // localIdentities should only be used by the server. + localIdentities []*commonpbv1.Identity + verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode + fallbackClientHandshake fallback.ClientHandshake + getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error) + serverAuthorizationPolicy []byte +} + +// NewClientCreds returns a client-side transport credentials object that uses +// the S2Av2 to establish a secure connection with a server. +func NewClientCreds(s2av2Address string, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, fallbackClientHandshakeFunc fallback.ClientHandshake, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error), serverAuthorizationPolicy []byte) (credentials.TransportCredentials, error) { + // Create an AccessTokenManager instance to use to authenticate to S2Av2. + accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + + creds := &s2av2TransportCreds{ + info: &credentials.ProtocolInfo{ + SecurityProtocol: s2aSecurityProtocol, + }, + isClient: true, + serverName: "", + s2av2Address: s2av2Address, + localIdentity: localIdentity, + verificationMode: verificationMode, + fallbackClientHandshake: fallbackClientHandshakeFunc, + getS2AStream: getS2AStream, + serverAuthorizationPolicy: serverAuthorizationPolicy, + } + if err != nil { + creds.tokenManager = nil + } else { + creds.tokenManager = &accessTokenManager + } + if grpclog.V(1) { + grpclog.Info("Created client S2Av2 transport credentials.") + } + return creds, nil +} + +// NewServerCreds returns a server-side transport credentials object that uses +// the S2Av2 to establish a secure connection with a client. +func NewServerCreds(s2av2Address string, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)) (credentials.TransportCredentials, error) { + // Create an AccessTokenManager instance to use to authenticate to S2Av2. + accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + creds := &s2av2TransportCreds{ + info: &credentials.ProtocolInfo{ + SecurityProtocol: s2aSecurityProtocol, + }, + isClient: false, + s2av2Address: s2av2Address, + localIdentities: localIdentities, + verificationMode: verificationMode, + getS2AStream: getS2AStream, + } + if err != nil { + creds.tokenManager = nil + } else { + creds.tokenManager = &accessTokenManager + } + if grpclog.V(1) { + grpclog.Info("Created server S2Av2 transport credentials.") + } + return creds, nil +} + +// ClientHandshake performs a client-side mTLS handshake using the S2Av2. +func (c *s2av2TransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + if !c.isClient { + return nil, nil, errors.New("client handshake called using server transport credentials") + } + // Remove the port from serverAuthority. + serverName := removeServerNamePort(serverAuthority) + timeoutCtx, cancel := context.WithTimeout(ctx, GetS2ATimeout()) + defer cancel() + s2AStream, err := createStream(timeoutCtx, c.s2av2Address, c.getS2AStream) + if err != nil { + grpclog.Infof("Failed to connect to S2Av2: %v", err) + if c.fallbackClientHandshake != nil { + return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) + } + return nil, nil, err + } + defer s2AStream.CloseSend() + if grpclog.V(1) { + grpclog.Infof("Connected to S2Av2.") + } + var config *tls.Config + + var tokenManager tokenmanager.AccessTokenManager + if c.tokenManager == nil { + tokenManager = nil + } else { + tokenManager = *c.tokenManager + } + + if c.serverName == "" { + config, err = tlsconfigstore.GetTLSConfigurationForClient(serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy) + if err != nil { + grpclog.Info("Failed to get client TLS config from S2Av2: %v", err) + if c.fallbackClientHandshake != nil { + return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) + } + return nil, nil, err + } + } else { + config, err = tlsconfigstore.GetTLSConfigurationForClient(c.serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy) + if err != nil { + grpclog.Info("Failed to get client TLS config from S2Av2: %v", err) + if c.fallbackClientHandshake != nil { + return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) + } + return nil, nil, err + } + } + if grpclog.V(1) { + grpclog.Infof("Got client TLS config from S2Av2.") + } + creds := credentials.NewTLS(config) + + conn, authInfo, err := creds.ClientHandshake(ctx, serverName, rawConn) + if err != nil { + grpclog.Infof("Failed to do client handshake using S2Av2: %v", err) + if c.fallbackClientHandshake != nil { + return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) + } + return nil, nil, err + } + grpclog.Infof("Successfully done client handshake using S2Av2 to: %s", serverName) + + return conn, authInfo, err +} + +// ServerHandshake performs a server-side mTLS handshake using the S2Av2. +func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + if c.isClient { + return nil, nil, errors.New("server handshake called using client transport credentials") + } + ctx, cancel := context.WithTimeout(context.Background(), GetS2ATimeout()) + defer cancel() + s2AStream, err := createStream(ctx, c.s2av2Address, c.getS2AStream) + if err != nil { + grpclog.Infof("Failed to connect to S2Av2: %v", err) + return nil, nil, err + } + defer s2AStream.CloseSend() + if grpclog.V(1) { + grpclog.Infof("Connected to S2Av2.") + } + + var tokenManager tokenmanager.AccessTokenManager + if c.tokenManager == nil { + tokenManager = nil + } else { + tokenManager = *c.tokenManager + } + + config, err := tlsconfigstore.GetTLSConfigurationForServer(s2AStream, tokenManager, c.localIdentities, c.verificationMode) + if err != nil { + grpclog.Infof("Failed to get server TLS config from S2Av2: %v", err) + return nil, nil, err + } + if grpclog.V(1) { + grpclog.Infof("Got server TLS config from S2Av2.") + } + creds := credentials.NewTLS(config) + return creds.ServerHandshake(rawConn) +} + +// Info returns protocol info of s2av2TransportCreds. +func (c *s2av2TransportCreds) Info() credentials.ProtocolInfo { + return *c.info +} + +// Clone makes a deep copy of s2av2TransportCreds. +func (c *s2av2TransportCreds) Clone() credentials.TransportCredentials { + info := *c.info + serverName := c.serverName + fallbackClientHandshake := c.fallbackClientHandshake + + s2av2Address := c.s2av2Address + var tokenManager tokenmanager.AccessTokenManager + if c.tokenManager == nil { + tokenManager = nil + } else { + tokenManager = *c.tokenManager + } + verificationMode := c.verificationMode + var localIdentity *commonpbv1.Identity + if c.localIdentity != nil { + localIdentity = proto.Clone(c.localIdentity).(*commonpbv1.Identity) + } + var localIdentities []*commonpbv1.Identity + if c.localIdentities != nil { + localIdentities = make([]*commonpbv1.Identity, len(c.localIdentities)) + for i, localIdentity := range c.localIdentities { + localIdentities[i] = proto.Clone(localIdentity).(*commonpbv1.Identity) + } + } + creds := &s2av2TransportCreds{ + info: &info, + isClient: c.isClient, + serverName: serverName, + fallbackClientHandshake: fallbackClientHandshake, + s2av2Address: s2av2Address, + localIdentity: localIdentity, + localIdentities: localIdentities, + verificationMode: verificationMode, + } + if c.tokenManager == nil { + creds.tokenManager = nil + } else { + creds.tokenManager = &tokenManager + } + return creds +} + +// NewClientTLSConfig returns a tls.Config instance that uses S2Av2 to establish a TLS connection as +// a client. The tls.Config MUST only be used to establish a single TLS connection. +func NewClientTLSConfig( + ctx context.Context, + s2av2Address string, + tokenManager tokenmanager.AccessTokenManager, + verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, + serverName string, + serverAuthorizationPolicy []byte) (*tls.Config, error) { + s2AStream, err := createStream(ctx, s2av2Address, nil) + if err != nil { + grpclog.Infof("Failed to connect to S2Av2: %v", err) + return nil, err + } + + return tlsconfigstore.GetTLSConfigurationForClient(removeServerNamePort(serverName), s2AStream, tokenManager, nil, verificationMode, serverAuthorizationPolicy) +} + +// OverrideServerName sets the ServerName in the s2av2TransportCreds protocol +// info. The ServerName MUST be a hostname. +func (c *s2av2TransportCreds) OverrideServerName(serverNameOverride string) error { + serverName := removeServerNamePort(serverNameOverride) + c.info.ServerName = serverName + c.serverName = serverName + return nil +} + +// Remove the trailing port from server name. +func removeServerNamePort(serverName string) string { + name, _, err := net.SplitHostPort(serverName) + if err != nil { + name = serverName + } + return name +} + +type s2AGrpcStream struct { + stream s2av2pb.S2AService_SetUpSessionClient +} + +func (x s2AGrpcStream) Send(m *s2av2pb.SessionReq) error { + return x.stream.Send(m) +} + +func (x s2AGrpcStream) Recv() (*s2av2pb.SessionResp, error) { + return x.stream.Recv() +} + +func (x s2AGrpcStream) CloseSend() error { + return x.stream.CloseSend() +} + +func createStream(ctx context.Context, s2av2Address string, getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error)) (stream.S2AStream, error) { + if getS2AStream != nil { + return getS2AStream(ctx, s2av2Address) + } + // TODO(rmehta19): Consider whether to close the connection to S2Av2. + conn, err := service.Dial(s2av2Address) + if err != nil { + return nil, err + } + client := s2av2pb.NewS2AServiceClient(conn) + gRPCStream, err := client.SetUpSession(ctx, []grpc.CallOption{}...) + if err != nil { + return nil, err + } + return &s2AGrpcStream{ + stream: gRPCStream, + }, nil +} + +// GetS2ATimeout returns the timeout enforced on the connection to the S2A service for handshake. +func GetS2ATimeout() time.Duration { + timeout, err := time.ParseDuration(os.Getenv(s2aTimeoutEnv)) + if err != nil { + return defaultS2ATimeout + } + return timeout +} diff --git a/vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem new file mode 100644 index 00000000000..493a5a26481 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 +a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 +OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 +RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK +P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 +HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu +0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 +EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 +/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA +QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ +nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD +X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco +pKklVz0= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem b/vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem new file mode 100644 index 00000000000..55a7f10c742 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF +l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj ++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G +4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA +xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh +68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ +/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL +Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA +VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 +9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH +MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt +aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq +xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx +2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv +EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z +aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq +udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs +VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm +56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT +GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V +Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm +HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q +BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH +qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh +GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem new file mode 100644 index 00000000000..0f98322c724 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT +fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ +qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE +xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es +Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 +Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM +ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR +e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X +POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl +AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg +odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ +PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN +Dhm6uZM= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem b/vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem new file mode 100644 index 00000000000..81afea783df --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs +8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO +QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk +XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA +Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc +gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf +LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl +jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 +4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q +Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P +nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 +drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE +duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 +L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG +06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm +eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD +uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 +lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL +a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb +hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ +7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j +r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 +eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD +B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz +7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem new file mode 100644 index 00000000000..493a5a26481 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 +a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 +OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 +RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK +P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 +HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu +0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 +EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 +/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA +QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ +nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD +X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco +pKklVz0= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem new file mode 100644 index 00000000000..55a7f10c742 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF +l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj ++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G +4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA +xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh +68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ +/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL +Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA +VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 +9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH +MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt +aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq +xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx +2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv +EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z +aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq +udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs +VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm +56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT +GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V +Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm +HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q +BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH +qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh +GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem new file mode 100644 index 00000000000..0f98322c724 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT +fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ +qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE +xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es +Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 +Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM +ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR +e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X +POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl +AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg +odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ +PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN +Dhm6uZM= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem new file mode 100644 index 00000000000..81afea783df --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs +8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO +QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk +XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA +Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc +gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf +LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl +jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 +4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q +Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P +nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 +drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE +duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 +L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG +06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm +eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD +uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 +lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL +a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb +hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ +7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j +r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 +eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD +B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz +7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go new file mode 100644 index 00000000000..4d919132295 --- /dev/null +++ b/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go @@ -0,0 +1,404 @@ +/* + * + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package tlsconfigstore offloads operations to S2Av2. +package tlsconfigstore + +import ( + "crypto/tls" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" + + "github.com/google/s2a-go/internal/tokenmanager" + "github.com/google/s2a-go/internal/v2/certverifier" + "github.com/google/s2a-go/internal/v2/remotesigner" + "github.com/google/s2a-go/stream" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + + commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto" + commonpb "github.com/google/s2a-go/internal/proto/v2/common_go_proto" + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +const ( + // HTTP/2 + h2 = "h2" +) + +// GetTLSConfigurationForClient returns a tls.Config instance for use by a client application. +func GetTLSConfigurationForClient(serverHostname string, s2AStream stream.S2AStream, tokenManager tokenmanager.AccessTokenManager, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, serverAuthorizationPolicy []byte) (*tls.Config, error) { + authMechanisms := getAuthMechanisms(tokenManager, []*commonpbv1.Identity{localIdentity}) + + if grpclog.V(1) { + grpclog.Infof("Sending request to S2Av2 for client TLS config.") + } + // Send request to S2Av2 for config. + if err := s2AStream.Send(&s2av2pb.SessionReq{ + LocalIdentity: localIdentity, + AuthenticationMechanisms: authMechanisms, + ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{ + GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{ + ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_CLIENT, + }, + }, + }); err != nil { + grpclog.Infof("Failed to send request to S2Av2 for client TLS config") + return nil, err + } + + // Get the response containing config from S2Av2. + resp, err := s2AStream.Recv() + if err != nil { + grpclog.Infof("Failed to receive client TLS config response from S2Av2.") + return nil, err + } + + // TODO(rmehta19): Add unit test for this if statement. + if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) { + return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details) + } + + // Extract TLS configiguration from SessionResp. + tlsConfig := resp.GetGetTlsConfigurationResp().GetClientTlsConfiguration() + + var cert tls.Certificate + for i, v := range tlsConfig.CertificateChain { + // Populate Certificates field. + block, _ := pem.Decode([]byte(v)) + if block == nil { + return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty") + } + x509Cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + cert.Certificate = append(cert.Certificate, x509Cert.Raw) + if i == 0 { + cert.Leaf = x509Cert + } + } + + if len(tlsConfig.CertificateChain) > 0 { + cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream) + if cert.PrivateKey == nil { + return nil, errors.New("failed to retrieve Private Key from Remote Signer Library") + } + } + + minVersion, maxVersion, err := getTLSMinMaxVersionsClient(tlsConfig) + if err != nil { + return nil, err + } + + // Create mTLS credentials for client. + config := &tls.Config{ + VerifyPeerCertificate: certverifier.VerifyServerCertificateChain(serverHostname, verificationMode, s2AStream, serverAuthorizationPolicy), + ServerName: serverHostname, + InsecureSkipVerify: true, // NOLINT + ClientSessionCache: nil, + SessionTicketsDisabled: true, + MinVersion: minVersion, + MaxVersion: maxVersion, + NextProtos: []string{h2}, + } + if len(tlsConfig.CertificateChain) > 0 { + config.Certificates = []tls.Certificate{cert} + } + return config, nil +} + +// GetTLSConfigurationForServer returns a tls.Config instance for use by a server application. +func GetTLSConfigurationForServer(s2AStream stream.S2AStream, tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (*tls.Config, error) { + return &tls.Config{ + GetConfigForClient: ClientConfig(tokenManager, localIdentities, verificationMode, s2AStream), + }, nil +} + +// ClientConfig builds a TLS config for a server to establish a secure +// connection with a client, based on SNI communicated during ClientHello. +// Ensures that server presents the correct certificate to establish a TLS +// connection. +func ClientConfig(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, s2AStream stream.S2AStream) func(chi *tls.ClientHelloInfo) (*tls.Config, error) { + return func(chi *tls.ClientHelloInfo) (*tls.Config, error) { + tlsConfig, err := getServerConfigFromS2Av2(tokenManager, localIdentities, chi.ServerName, s2AStream) + if err != nil { + return nil, err + } + + var cert tls.Certificate + for i, v := range tlsConfig.CertificateChain { + // Populate Certificates field. + block, _ := pem.Decode([]byte(v)) + if block == nil { + return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty") + } + x509Cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + cert.Certificate = append(cert.Certificate, x509Cert.Raw) + if i == 0 { + cert.Leaf = x509Cert + } + } + + cert.PrivateKey = remotesigner.New(cert.Leaf, s2AStream) + if cert.PrivateKey == nil { + return nil, errors.New("failed to retrieve Private Key from Remote Signer Library") + } + + minVersion, maxVersion, err := getTLSMinMaxVersionsServer(tlsConfig) + if err != nil { + return nil, err + } + + clientAuth := getTLSClientAuthType(tlsConfig) + + var cipherSuites []uint16 + cipherSuites = getCipherSuites(tlsConfig.Ciphersuites) + + // Create mTLS credentials for server. + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + VerifyPeerCertificate: certverifier.VerifyClientCertificateChain(verificationMode, s2AStream), + ClientAuth: clientAuth, + CipherSuites: cipherSuites, + SessionTicketsDisabled: true, + MinVersion: minVersion, + MaxVersion: maxVersion, + NextProtos: []string{h2}, + }, nil + } +} + +func getCipherSuites(tlsConfigCipherSuites []commonpb.Ciphersuite) []uint16 { + var tlsGoCipherSuites []uint16 + for _, v := range tlsConfigCipherSuites { + s := getTLSCipherSuite(v) + if s != 0xffff { + tlsGoCipherSuites = append(tlsGoCipherSuites, s) + } + } + return tlsGoCipherSuites +} + +func getTLSCipherSuite(tlsCipherSuite commonpb.Ciphersuite) uint16 { + switch tlsCipherSuite { + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + default: + return 0xffff + } +} + +func getServerConfigFromS2Av2(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, sni string, s2AStream stream.S2AStream) (*s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration, error) { + authMechanisms := getAuthMechanisms(tokenManager, localIdentities) + var locID *commonpbv1.Identity + if localIdentities != nil { + locID = localIdentities[0] + } + + if err := s2AStream.Send(&s2av2pb.SessionReq{ + LocalIdentity: locID, + AuthenticationMechanisms: authMechanisms, + ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{ + GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{ + ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_SERVER, + Sni: sni, + }, + }, + }); err != nil { + return nil, err + } + + resp, err := s2AStream.Recv() + if err != nil { + return nil, err + } + + // TODO(rmehta19): Add unit test for this if statement. + if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) { + return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details) + } + + return resp.GetGetTlsConfigurationResp().GetServerTlsConfiguration(), nil +} + +func getTLSClientAuthType(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) tls.ClientAuthType { + var clientAuth tls.ClientAuthType + switch x := tlsConfig.RequestClientCertificate; x { + case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE: + clientAuth = tls.NoClientCert + case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + clientAuth = tls.RequestClientCert + case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + // This case actually maps to tls.VerifyClientCertIfGiven. However this + // mapping triggers normal verification, followed by custom verification, + // specified in VerifyPeerCertificate. To bypass normal verification, and + // only do custom verification we set clientAuth to RequireAnyClientCert or + // RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full + // discussion. + clientAuth = tls.RequireAnyClientCert + case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + clientAuth = tls.RequireAnyClientCert + case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + // This case actually maps to tls.RequireAndVerifyClientCert. However this + // mapping triggers normal verification, followed by custom verification, + // specified in VerifyPeerCertificate. To bypass normal verification, and + // only do custom verification we set clientAuth to RequireAnyClientCert or + // RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full + // discussion. + clientAuth = tls.RequireAnyClientCert + default: + clientAuth = tls.RequireAnyClientCert + } + return clientAuth +} + +func getAuthMechanisms(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity) []*s2av2pb.AuthenticationMechanism { + if tokenManager == nil { + return nil + } + if len(localIdentities) == 0 { + token, err := tokenManager.DefaultToken() + if err != nil { + grpclog.Infof("Unable to get token for empty local identity: %v", err) + return nil + } + return []*s2av2pb.AuthenticationMechanism{ + { + MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{ + Token: token, + }, + }, + } + } + var authMechanisms []*s2av2pb.AuthenticationMechanism + for _, localIdentity := range localIdentities { + if localIdentity == nil { + token, err := tokenManager.DefaultToken() + if err != nil { + grpclog.Infof("Unable to get default token for local identity %v: %v", localIdentity, err) + continue + } + authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{ + Identity: localIdentity, + MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{ + Token: token, + }, + }) + } else { + token, err := tokenManager.Token(localIdentity) + if err != nil { + grpclog.Infof("Unable to get token for local identity %v: %v", localIdentity, err) + continue + } + authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{ + Identity: localIdentity, + MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{ + Token: token, + }, + }) + } + } + return authMechanisms +} + +// TODO(rmehta19): refactor switch statements into a helper function. +func getTLSMinMaxVersionsClient(tlsConfig *s2av2pb.GetTlsConfigurationResp_ClientTlsConfiguration) (uint16, uint16, error) { + // Map S2Av2 TLSVersion to consts defined in tls package. + var minVersion uint16 + var maxVersion uint16 + switch x := tlsConfig.MinTlsVersion; x { + case commonpb.TLSVersion_TLS_VERSION_1_0: + minVersion = tls.VersionTLS10 + case commonpb.TLSVersion_TLS_VERSION_1_1: + minVersion = tls.VersionTLS11 + case commonpb.TLSVersion_TLS_VERSION_1_2: + minVersion = tls.VersionTLS12 + case commonpb.TLSVersion_TLS_VERSION_1_3: + minVersion = tls.VersionTLS13 + default: + return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x) + } + + switch x := tlsConfig.MaxTlsVersion; x { + case commonpb.TLSVersion_TLS_VERSION_1_0: + maxVersion = tls.VersionTLS10 + case commonpb.TLSVersion_TLS_VERSION_1_1: + maxVersion = tls.VersionTLS11 + case commonpb.TLSVersion_TLS_VERSION_1_2: + maxVersion = tls.VersionTLS12 + case commonpb.TLSVersion_TLS_VERSION_1_3: + maxVersion = tls.VersionTLS13 + default: + return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x) + } + if minVersion > maxVersion { + return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion") + } + return minVersion, maxVersion, nil +} + +func getTLSMinMaxVersionsServer(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) (uint16, uint16, error) { + // Map S2Av2 TLSVersion to consts defined in tls package. + var minVersion uint16 + var maxVersion uint16 + switch x := tlsConfig.MinTlsVersion; x { + case commonpb.TLSVersion_TLS_VERSION_1_0: + minVersion = tls.VersionTLS10 + case commonpb.TLSVersion_TLS_VERSION_1_1: + minVersion = tls.VersionTLS11 + case commonpb.TLSVersion_TLS_VERSION_1_2: + minVersion = tls.VersionTLS12 + case commonpb.TLSVersion_TLS_VERSION_1_3: + minVersion = tls.VersionTLS13 + default: + return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x) + } + + switch x := tlsConfig.MaxTlsVersion; x { + case commonpb.TLSVersion_TLS_VERSION_1_0: + maxVersion = tls.VersionTLS10 + case commonpb.TLSVersion_TLS_VERSION_1_1: + maxVersion = tls.VersionTLS11 + case commonpb.TLSVersion_TLS_VERSION_1_2: + maxVersion = tls.VersionTLS12 + case commonpb.TLSVersion_TLS_VERSION_1_3: + maxVersion = tls.VersionTLS13 + default: + return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x) + } + if minVersion > maxVersion { + return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion") + } + return minVersion, maxVersion, nil +} diff --git a/vendor/github.com/google/s2a-go/s2a.go b/vendor/github.com/google/s2a-go/s2a.go new file mode 100644 index 00000000000..1c1349de4af --- /dev/null +++ b/vendor/github.com/google/s2a-go/s2a.go @@ -0,0 +1,412 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package s2a provides the S2A transport credentials used by a gRPC +// application. +package s2a + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "sync" + "time" + + "github.com/golang/protobuf/proto" + "github.com/google/s2a-go/fallback" + "github.com/google/s2a-go/internal/handshaker" + "github.com/google/s2a-go/internal/handshaker/service" + "github.com/google/s2a-go/internal/tokenmanager" + "github.com/google/s2a-go/internal/v2" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" + + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +const ( + s2aSecurityProtocol = "tls" + // defaultTimeout specifies the default server handshake timeout. + defaultTimeout = 30.0 * time.Second +) + +// s2aTransportCreds are the transport credentials required for establishing +// a secure connection using the S2A. They implement the +// credentials.TransportCredentials interface. +type s2aTransportCreds struct { + info *credentials.ProtocolInfo + minTLSVersion commonpb.TLSVersion + maxTLSVersion commonpb.TLSVersion + // tlsCiphersuites contains the ciphersuites used in the S2A connection. + // Note that these are currently unconfigurable. + tlsCiphersuites []commonpb.Ciphersuite + // localIdentity should only be used by the client. + localIdentity *commonpb.Identity + // localIdentities should only be used by the server. + localIdentities []*commonpb.Identity + // targetIdentities should only be used by the client. + targetIdentities []*commonpb.Identity + isClient bool + s2aAddr string + ensureProcessSessionTickets *sync.WaitGroup +} + +// NewClientCreds returns a client-side transport credentials object that uses +// the S2A to establish a secure connection with a server. +func NewClientCreds(opts *ClientOptions) (credentials.TransportCredentials, error) { + if opts == nil { + return nil, errors.New("nil client options") + } + var targetIdentities []*commonpb.Identity + for _, targetIdentity := range opts.TargetIdentities { + protoTargetIdentity, err := toProtoIdentity(targetIdentity) + if err != nil { + return nil, err + } + targetIdentities = append(targetIdentities, protoTargetIdentity) + } + localIdentity, err := toProtoIdentity(opts.LocalIdentity) + if err != nil { + return nil, err + } + if opts.EnableLegacyMode { + return &s2aTransportCreds{ + info: &credentials.ProtocolInfo{ + SecurityProtocol: s2aSecurityProtocol, + }, + minTLSVersion: commonpb.TLSVersion_TLS1_3, + maxTLSVersion: commonpb.TLSVersion_TLS1_3, + tlsCiphersuites: []commonpb.Ciphersuite{ + commonpb.Ciphersuite_AES_128_GCM_SHA256, + commonpb.Ciphersuite_AES_256_GCM_SHA384, + commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256, + }, + localIdentity: localIdentity, + targetIdentities: targetIdentities, + isClient: true, + s2aAddr: opts.S2AAddress, + ensureProcessSessionTickets: opts.EnsureProcessSessionTickets, + }, nil + } + verificationMode := getVerificationMode(opts.VerificationMode) + var fallbackFunc fallback.ClientHandshake + if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackClientHandshakeFunc != nil { + fallbackFunc = opts.FallbackOpts.FallbackClientHandshakeFunc + } + return v2.NewClientCreds(opts.S2AAddress, localIdentity, verificationMode, fallbackFunc, opts.getS2AStream, opts.serverAuthorizationPolicy) +} + +// NewServerCreds returns a server-side transport credentials object that uses +// the S2A to establish a secure connection with a client. +func NewServerCreds(opts *ServerOptions) (credentials.TransportCredentials, error) { + if opts == nil { + return nil, errors.New("nil server options") + } + var localIdentities []*commonpb.Identity + for _, localIdentity := range opts.LocalIdentities { + protoLocalIdentity, err := toProtoIdentity(localIdentity) + if err != nil { + return nil, err + } + localIdentities = append(localIdentities, protoLocalIdentity) + } + if opts.EnableLegacyMode { + return &s2aTransportCreds{ + info: &credentials.ProtocolInfo{ + SecurityProtocol: s2aSecurityProtocol, + }, + minTLSVersion: commonpb.TLSVersion_TLS1_3, + maxTLSVersion: commonpb.TLSVersion_TLS1_3, + tlsCiphersuites: []commonpb.Ciphersuite{ + commonpb.Ciphersuite_AES_128_GCM_SHA256, + commonpb.Ciphersuite_AES_256_GCM_SHA384, + commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256, + }, + localIdentities: localIdentities, + isClient: false, + s2aAddr: opts.S2AAddress, + }, nil + } + verificationMode := getVerificationMode(opts.VerificationMode) + return v2.NewServerCreds(opts.S2AAddress, localIdentities, verificationMode, opts.getS2AStream) +} + +// ClientHandshake initiates a client-side TLS handshake using the S2A. +func (c *s2aTransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + if !c.isClient { + return nil, nil, errors.New("client handshake called using server transport credentials") + } + + // Connect to the S2A. + hsConn, err := service.Dial(c.s2aAddr) + if err != nil { + grpclog.Infof("Failed to connect to S2A: %v", err) + return nil, nil, err + } + + var cancel context.CancelFunc + ctx, cancel = context.WithCancel(ctx) + defer cancel() + + opts := &handshaker.ClientHandshakerOptions{ + MinTLSVersion: c.minTLSVersion, + MaxTLSVersion: c.maxTLSVersion, + TLSCiphersuites: c.tlsCiphersuites, + TargetIdentities: c.targetIdentities, + LocalIdentity: c.localIdentity, + TargetName: serverAuthority, + EnsureProcessSessionTickets: c.ensureProcessSessionTickets, + } + chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts) + if err != nil { + grpclog.Infof("Call to handshaker.NewClientHandshaker failed: %v", err) + return nil, nil, err + } + defer func() { + if err != nil { + if closeErr := chs.Close(); closeErr != nil { + grpclog.Infof("Close failed unexpectedly: %v", err) + err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr) + } + } + }() + + secConn, authInfo, err := chs.ClientHandshake(context.Background()) + if err != nil { + grpclog.Infof("Handshake failed: %v", err) + return nil, nil, err + } + return secConn, authInfo, nil +} + +// ServerHandshake initiates a server-side TLS handshake using the S2A. +func (c *s2aTransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + if c.isClient { + return nil, nil, errors.New("server handshake called using client transport credentials") + } + + // Connect to the S2A. + hsConn, err := service.Dial(c.s2aAddr) + if err != nil { + grpclog.Infof("Failed to connect to S2A: %v", err) + return nil, nil, err + } + + ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) + defer cancel() + + opts := &handshaker.ServerHandshakerOptions{ + MinTLSVersion: c.minTLSVersion, + MaxTLSVersion: c.maxTLSVersion, + TLSCiphersuites: c.tlsCiphersuites, + LocalIdentities: c.localIdentities, + } + shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts) + if err != nil { + grpclog.Infof("Call to handshaker.NewServerHandshaker failed: %v", err) + return nil, nil, err + } + defer func() { + if err != nil { + if closeErr := shs.Close(); closeErr != nil { + grpclog.Infof("Close failed unexpectedly: %v", err) + err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr) + } + } + }() + + secConn, authInfo, err := shs.ServerHandshake(context.Background()) + if err != nil { + grpclog.Infof("Handshake failed: %v", err) + return nil, nil, err + } + return secConn, authInfo, nil +} + +func (c *s2aTransportCreds) Info() credentials.ProtocolInfo { + return *c.info +} + +func (c *s2aTransportCreds) Clone() credentials.TransportCredentials { + info := *c.info + var localIdentity *commonpb.Identity + if c.localIdentity != nil { + localIdentity = proto.Clone(c.localIdentity).(*commonpb.Identity) + } + var localIdentities []*commonpb.Identity + if c.localIdentities != nil { + localIdentities = make([]*commonpb.Identity, len(c.localIdentities)) + for i, localIdentity := range c.localIdentities { + localIdentities[i] = proto.Clone(localIdentity).(*commonpb.Identity) + } + } + var targetIdentities []*commonpb.Identity + if c.targetIdentities != nil { + targetIdentities = make([]*commonpb.Identity, len(c.targetIdentities)) + for i, targetIdentity := range c.targetIdentities { + targetIdentities[i] = proto.Clone(targetIdentity).(*commonpb.Identity) + } + } + return &s2aTransportCreds{ + info: &info, + minTLSVersion: c.minTLSVersion, + maxTLSVersion: c.maxTLSVersion, + tlsCiphersuites: c.tlsCiphersuites, + localIdentity: localIdentity, + localIdentities: localIdentities, + targetIdentities: targetIdentities, + isClient: c.isClient, + s2aAddr: c.s2aAddr, + } +} + +func (c *s2aTransportCreds) OverrideServerName(serverNameOverride string) error { + c.info.ServerName = serverNameOverride + return nil +} + +// TLSClientConfigOptions specifies parameters for creating client TLS config. +type TLSClientConfigOptions struct { + // ServerName is required by s2a as the expected name when verifying the hostname found in server's certificate. + // tlsConfig, _ := factory.Build(ctx, &s2a.TLSClientConfigOptions{ + // ServerName: "example.com", + // }) + ServerName string +} + +// TLSClientConfigFactory defines the interface for a client TLS config factory. +type TLSClientConfigFactory interface { + Build(ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error) +} + +// NewTLSClientConfigFactory returns an instance of s2aTLSClientConfigFactory. +func NewTLSClientConfigFactory(opts *ClientOptions) (TLSClientConfigFactory, error) { + if opts == nil { + return nil, fmt.Errorf("opts must be non-nil") + } + if opts.EnableLegacyMode { + return nil, fmt.Errorf("NewTLSClientConfigFactory only supports S2Av2") + } + tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager() + if err != nil { + // The only possible error is: access token not set in the environment, + // which is okay in environments other than serverless. + grpclog.Infof("Access token manager not initialized: %v", err) + return &s2aTLSClientConfigFactory{ + s2av2Address: opts.S2AAddress, + tokenManager: nil, + verificationMode: getVerificationMode(opts.VerificationMode), + serverAuthorizationPolicy: opts.serverAuthorizationPolicy, + }, nil + } + return &s2aTLSClientConfigFactory{ + s2av2Address: opts.S2AAddress, + tokenManager: tokenManager, + verificationMode: getVerificationMode(opts.VerificationMode), + serverAuthorizationPolicy: opts.serverAuthorizationPolicy, + }, nil +} + +type s2aTLSClientConfigFactory struct { + s2av2Address string + tokenManager tokenmanager.AccessTokenManager + verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode + serverAuthorizationPolicy []byte +} + +func (f *s2aTLSClientConfigFactory) Build( + ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error) { + serverName := "" + if opts != nil && opts.ServerName != "" { + serverName = opts.ServerName + } + return v2.NewClientTLSConfig(ctx, f.s2av2Address, f.tokenManager, f.verificationMode, serverName, f.serverAuthorizationPolicy) +} + +func getVerificationMode(verificationMode VerificationModeType) s2av2pb.ValidatePeerCertificateChainReq_VerificationMode { + switch verificationMode { + case ConnectToGoogle: + return s2av2pb.ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE + case Spiffe: + return s2av2pb.ValidatePeerCertificateChainReq_SPIFFE + default: + return s2av2pb.ValidatePeerCertificateChainReq_UNSPECIFIED + } +} + +// NewS2ADialTLSContextFunc returns a dialer which establishes an MTLS connection using S2A. +// Example use with http.RoundTripper: +// +// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{ +// S2AAddress: s2aAddress, // required +// }) +// transport := http.DefaultTransport +// transport.DialTLSContext = dialTLSContext +func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, network, addr string) (net.Conn, error) { + + return func(ctx context.Context, network, addr string) (net.Conn, error) { + + fallback := func(err error) (net.Conn, error) { + if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackDialer != nil && + opts.FallbackOpts.FallbackDialer.Dialer != nil && opts.FallbackOpts.FallbackDialer.ServerAddr != "" { + fbDialer := opts.FallbackOpts.FallbackDialer + grpclog.Infof("fall back to dial: %s", fbDialer.ServerAddr) + fbConn, fbErr := fbDialer.Dialer.DialContext(ctx, network, fbDialer.ServerAddr) + if fbErr != nil { + return nil, fmt.Errorf("error fallback to %s: %v; S2A error: %w", fbDialer.ServerAddr, fbErr, err) + } + return fbConn, nil + } + return nil, err + } + + factory, err := NewTLSClientConfigFactory(opts) + if err != nil { + grpclog.Infof("error creating S2A client config factory: %v", err) + return fallback(err) + } + + serverName, _, err := net.SplitHostPort(addr) + if err != nil { + serverName = addr + } + timeoutCtx, cancel := context.WithTimeout(ctx, v2.GetS2ATimeout()) + defer cancel() + s2aTLSConfig, err := factory.Build(timeoutCtx, &TLSClientConfigOptions{ + ServerName: serverName, + }) + if err != nil { + grpclog.Infof("error building S2A TLS config: %v", err) + return fallback(err) + } + + s2aDialer := &tls.Dialer{ + Config: s2aTLSConfig, + } + c, err := s2aDialer.DialContext(ctx, network, addr) + if err != nil { + grpclog.Infof("error dialing with S2A to %s: %v", addr, err) + return fallback(err) + } + grpclog.Infof("success dialing MTLS to %s with S2A", addr) + return c, nil + } +} diff --git a/vendor/github.com/google/s2a-go/s2a_options.go b/vendor/github.com/google/s2a-go/s2a_options.go new file mode 100644 index 00000000000..94feafb9cf8 --- /dev/null +++ b/vendor/github.com/google/s2a-go/s2a_options.go @@ -0,0 +1,208 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package s2a + +import ( + "context" + "crypto/tls" + "errors" + "sync" + + "github.com/google/s2a-go/fallback" + "github.com/google/s2a-go/stream" + + s2apb "github.com/google/s2a-go/internal/proto/common_go_proto" +) + +// Identity is the interface for S2A identities. +type Identity interface { + // Name returns the name of the identity. + Name() string +} + +type spiffeID struct { + spiffeID string +} + +func (s *spiffeID) Name() string { return s.spiffeID } + +// NewSpiffeID creates a SPIFFE ID from id. +func NewSpiffeID(id string) Identity { + return &spiffeID{spiffeID: id} +} + +type hostname struct { + hostname string +} + +func (h *hostname) Name() string { return h.hostname } + +// NewHostname creates a hostname from name. +func NewHostname(name string) Identity { + return &hostname{hostname: name} +} + +type uid struct { + uid string +} + +func (h *uid) Name() string { return h.uid } + +// NewUID creates a UID from name. +func NewUID(name string) Identity { + return &uid{uid: name} +} + +// VerificationModeType specifies the mode that S2A must use to verify the peer +// certificate chain. +type VerificationModeType int + +// Three types of verification modes. +const ( + Unspecified = iota + ConnectToGoogle + Spiffe +) + +// ClientOptions contains the client-side options used to establish a secure +// channel using the S2A handshaker service. +type ClientOptions struct { + // TargetIdentities contains a list of allowed server identities. One of the + // target identities should match the peer identity in the handshake + // result; otherwise, the handshake fails. + TargetIdentities []Identity + // LocalIdentity is the local identity of the client application. If none is + // provided, then the S2A will choose the default identity, if one exists. + LocalIdentity Identity + // S2AAddress is the address of the S2A. + S2AAddress string + // EnsureProcessSessionTickets waits for all session tickets to be sent to + // S2A before a process completes. + // + // This functionality is crucial for processes that complete very soon after + // using S2A to establish a TLS connection, but it can be ignored for longer + // lived processes. + // + // Usage example: + // func main() { + // var ensureProcessSessionTickets sync.WaitGroup + // clientOpts := &s2a.ClientOptions{ + // EnsureProcessSessionTickets: &ensureProcessSessionTickets, + // // Set other members. + // } + // creds, _ := s2a.NewClientCreds(clientOpts) + // conn, _ := grpc.Dial(serverAddr, grpc.WithTransportCredentials(creds)) + // defer conn.Close() + // + // // Make RPC call. + // + // // The process terminates right after the RPC call ends. + // // ensureProcessSessionTickets can be used to ensure resumption + // // tickets are fully processed. If the process is long-lived, using + // // ensureProcessSessionTickets is not necessary. + // ensureProcessSessionTickets.Wait() + // } + EnsureProcessSessionTickets *sync.WaitGroup + // If true, enables the use of legacy S2Av1. + EnableLegacyMode bool + // VerificationMode specifies the mode that S2A must use to verify the + // peer certificate chain. + VerificationMode VerificationModeType + + // Optional fallback after dialing with S2A fails. + FallbackOpts *FallbackOptions + + // Generates an S2AStream interface for talking to the S2A server. + getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error) + + // Serialized user specified policy for server authorization. + serverAuthorizationPolicy []byte +} + +// FallbackOptions prescribes the fallback logic that should be taken if the application fails to connect with S2A. +type FallbackOptions struct { + // FallbackClientHandshakeFunc is used to specify fallback behavior when calling s2a.NewClientCreds(). + // It will be called by ClientHandshake function, after handshake with S2A fails. + // s2a.NewClientCreds() ignores the other FallbackDialer field. + FallbackClientHandshakeFunc fallback.ClientHandshake + + // FallbackDialer is used to specify fallback behavior when calling s2a.NewS2aDialTLSContextFunc(). + // It passes in a custom fallback dialer and server address to use after dialing with S2A fails. + // s2a.NewS2aDialTLSContextFunc() ignores the other FallbackClientHandshakeFunc field. + FallbackDialer *FallbackDialer +} + +// FallbackDialer contains a fallback tls.Dialer and a server address to connect to. +type FallbackDialer struct { + // Dialer specifies a fallback tls.Dialer. + Dialer *tls.Dialer + // ServerAddr is used by Dialer to establish fallback connection. + ServerAddr string +} + +// DefaultClientOptions returns the default client options. +func DefaultClientOptions(s2aAddress string) *ClientOptions { + return &ClientOptions{ + S2AAddress: s2aAddress, + VerificationMode: ConnectToGoogle, + } +} + +// ServerOptions contains the server-side options used to establish a secure +// channel using the S2A handshaker service. +type ServerOptions struct { + // LocalIdentities is the list of local identities that may be assumed by + // the server. If no local identity is specified, then the S2A chooses a + // default local identity, if one exists. + LocalIdentities []Identity + // S2AAddress is the address of the S2A. + S2AAddress string + // If true, enables the use of legacy S2Av1. + EnableLegacyMode bool + // VerificationMode specifies the mode that S2A must use to verify the + // peer certificate chain. + VerificationMode VerificationModeType + + // Generates an S2AStream interface for talking to the S2A server. + getS2AStream func(ctx context.Context, s2av2Address string) (stream.S2AStream, error) +} + +// DefaultServerOptions returns the default server options. +func DefaultServerOptions(s2aAddress string) *ServerOptions { + return &ServerOptions{ + S2AAddress: s2aAddress, + VerificationMode: ConnectToGoogle, + } +} + +func toProtoIdentity(identity Identity) (*s2apb.Identity, error) { + if identity == nil { + return nil, nil + } + switch id := identity.(type) { + case *spiffeID: + return &s2apb.Identity{IdentityOneof: &s2apb.Identity_SpiffeId{SpiffeId: id.Name()}}, nil + case *hostname: + return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Hostname{Hostname: id.Name()}}, nil + case *uid: + return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Uid{Uid: id.Name()}}, nil + default: + return nil, errors.New("unrecognized identity type") + } +} diff --git a/vendor/github.com/google/s2a-go/s2a_utils.go b/vendor/github.com/google/s2a-go/s2a_utils.go new file mode 100644 index 00000000000..d649cc46148 --- /dev/null +++ b/vendor/github.com/google/s2a-go/s2a_utils.go @@ -0,0 +1,79 @@ +/* + * + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package s2a + +import ( + "context" + "errors" + + commonpb "github.com/google/s2a-go/internal/proto/common_go_proto" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/peer" +) + +// AuthInfo exposes security information from the S2A to the application. +type AuthInfo interface { + // AuthType returns the authentication type. + AuthType() string + // ApplicationProtocol returns the application protocol, e.g. "grpc". + ApplicationProtocol() string + // TLSVersion returns the TLS version negotiated during the handshake. + TLSVersion() commonpb.TLSVersion + // Ciphersuite returns the ciphersuite negotiated during the handshake. + Ciphersuite() commonpb.Ciphersuite + // PeerIdentity returns the authenticated identity of the peer. + PeerIdentity() *commonpb.Identity + // LocalIdentity returns the local identity of the application used during + // session setup. + LocalIdentity() *commonpb.Identity + // PeerCertFingerprint returns the SHA256 hash of the peer certificate used in + // the S2A handshake. + PeerCertFingerprint() []byte + // LocalCertFingerprint returns the SHA256 hash of the local certificate used + // in the S2A handshake. + LocalCertFingerprint() []byte + // IsHandshakeResumed returns true if a cached session was used to resume + // the handshake. + IsHandshakeResumed() bool + // SecurityLevel returns the security level of the connection. + SecurityLevel() credentials.SecurityLevel +} + +// AuthInfoFromPeer extracts the authinfo.S2AAuthInfo object from the given +// peer, if it exists. This API should be used by gRPC clients after +// obtaining a peer object using the grpc.Peer() CallOption. +func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) { + s2aAuthInfo, ok := p.AuthInfo.(AuthInfo) + if !ok { + return nil, errors.New("no S2AAuthInfo found in Peer") + } + return s2aAuthInfo, nil +} + +// AuthInfoFromContext extracts the authinfo.S2AAuthInfo object from the given +// context, if it exists. This API should be used by gRPC server RPC handlers +// to get information about the peer. On the client-side, use the grpc.Peer() +// CallOption and the AuthInfoFromPeer function. +func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) { + p, ok := peer.FromContext(ctx) + if !ok { + return nil, errors.New("no Peer found in Context") + } + return AuthInfoFromPeer(p) +} diff --git a/vendor/github.com/google/s2a-go/stream/s2a_stream.go b/vendor/github.com/google/s2a-go/stream/s2a_stream.go new file mode 100644 index 00000000000..584bf32b1c7 --- /dev/null +++ b/vendor/github.com/google/s2a-go/stream/s2a_stream.go @@ -0,0 +1,34 @@ +/* + * + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package stream provides an interface for bidirectional streaming to the S2A server. +package stream + +import ( + s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto" +) + +// S2AStream defines the operation for communicating with the S2A server over a bidirectional stream. +type S2AStream interface { + // Send sends the message to the S2A server. + Send(*s2av2pb.SessionReq) error + // Recv receives the message from the S2A server. + Recv() (*s2av2pb.SessionResp, error) + // Closes the channel to the S2A server. + CloseSend() error +} diff --git a/vendor/github.com/google/s2a-go/testdata/client_cert.pem b/vendor/github.com/google/s2a-go/testdata/client_cert.pem new file mode 100644 index 00000000000..493a5a26481 --- /dev/null +++ b/vendor/github.com/google/s2a-go/testdata/client_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 +a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 +OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 +RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK +P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 +HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu +0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 +EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 +/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA +QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ +nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD +X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco +pKklVz0= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/testdata/client_key.pem b/vendor/github.com/google/s2a-go/testdata/client_key.pem new file mode 100644 index 00000000000..55a7f10c742 --- /dev/null +++ b/vendor/github.com/google/s2a-go/testdata/client_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF +l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj ++Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G +4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA +xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh +68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ +/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL +Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA +VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 +9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH +MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt +aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq +xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx +2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv +EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z +aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq +udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs +VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm +56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT +GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V +Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm +HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q +BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH +qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh +GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/s2a-go/testdata/server_cert.pem b/vendor/github.com/google/s2a-go/testdata/server_cert.pem new file mode 100644 index 00000000000..0f98322c724 --- /dev/null +++ b/vendor/github.com/google/s2a-go/testdata/server_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL +BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 +YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE +AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN +MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx +ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ +KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT +fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ +qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE +xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es +Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 +Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM +ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR +e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X +POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl +AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg +odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ +PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN +Dhm6uZM= +-----END CERTIFICATE----- diff --git a/vendor/github.com/google/s2a-go/testdata/server_key.pem b/vendor/github.com/google/s2a-go/testdata/server_key.pem new file mode 100644 index 00000000000..81afea783df --- /dev/null +++ b/vendor/github.com/google/s2a-go/testdata/server_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs +8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO +QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk +XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA +Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc +gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf +LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl +jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 +4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q +Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P +nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 +drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE +duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 +L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG +06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm +eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD +uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 +lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL +a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb +hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ +7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j +r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 +eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD +B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz +7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a60ba9..00000000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md new file mode 100644 index 00000000000..2bd78667afb --- /dev/null +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) + + +### Bug Fixes + +* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) + +## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md index 04fdf09f136..5566888726d 100644 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -2,6 +2,22 @@ We definitely welcome patches and contribution to this project! +### Tips + +Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). + +Always try to include a test case! If it is not possible or not necessary, +please explain why in the pull request description. + +### Releasing + +Commits that would precipitate a SemVer change, as desrcibed in the Conventional +Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) +to create a release candidate pull request. Once submitted, `release-please` +will create a release. + +For tips on how to work with `release-please`, see its documentation. + ### Legal requirements In order to protect both you and ourselves, you will need to sign the diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md index f765a46f915..3e9a61889de 100644 --- a/vendor/github.com/google/uuid/README.md +++ b/vendor/github.com/google/uuid/README.md @@ -1,6 +1,6 @@ -# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +# uuid The uuid package generates and inspects UUIDs based on -[RFC 4122](http://tools.ietf.org/html/rfc4122) +[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) and DCE 1.1: Authentication and Security Services. This package is based on the github.com/pborman/uuid package (previously named @@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this change is the ability to represent an invalid UUID (vs a NIL UUID). ###### Install -`go get github.com/google/uuid` +```sh +go get github.com/google/uuid +``` ###### Documentation -[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) +[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go index 24b78edc907..b2a0bc8711b 100644 --- a/vendor/github.com/google/uuid/node_js.go +++ b/vendor/github.com/google/uuid/node_js.go @@ -7,6 +7,6 @@ package uuid // getHardwareInterface returns nil values for the JS version of the code. -// This remvoves the "net" dependency, because it is not used in the browser. +// This removes the "net" dependency, because it is not used in the browser. // Using the "net" library inflates the size of the transpiled JS code by 673k bytes. func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index a57207aeb6f..a56138cc4bd 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -69,7 +69,7 @@ func Parse(s string) (UUID, error) { // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: - if strings.ToLower(s[:9]) != "urn:uuid:" { + if !strings.EqualFold(s[:9], "urn:uuid:") { return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) } s = s[9:] @@ -101,7 +101,8 @@ func Parse(s string) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(s[x], s[x+1]) if !ok { return uuid, errors.New("invalid UUID format") @@ -117,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) { switch len(b) { case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) } b = b[9:] @@ -145,7 +146,8 @@ func ParseBytes(b []byte) (UUID, error) { 9, 11, 14, 16, 19, 21, - 24, 26, 28, 30, 32, 34} { + 24, 26, 28, 30, 32, 34, + } { v, ok := xtob(b[x], b[x+1]) if !ok { return uuid, errors.New("invalid UUID format") diff --git a/vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE b/vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go b/vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go new file mode 100644 index 00000000000..b3283b81588 --- /dev/null +++ b/vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go @@ -0,0 +1,185 @@ +// Copyright 2022 Google LLC. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package client is a cross-platform client for the signer binary (a.k.a."EnterpriseCertSigner"). +// +// The signer binary is OS-specific, but exposes a standard set of APIs for the client to use. +package client + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + "encoding/gob" + "errors" + "fmt" + "io" + "net/rpc" + "os" + "os/exec" + + "github.com/googleapis/enterprise-certificate-proxy/client/util" +) + +const signAPI = "EnterpriseCertSigner.Sign" +const certificateChainAPI = "EnterpriseCertSigner.CertificateChain" +const publicKeyAPI = "EnterpriseCertSigner.Public" + +// A Connection wraps a pair of unidirectional streams as an io.ReadWriteCloser. +type Connection struct { + io.ReadCloser + io.WriteCloser +} + +// Close closes c's underlying ReadCloser and WriteCloser. +func (c *Connection) Close() error { + rerr := c.ReadCloser.Close() + werr := c.WriteCloser.Close() + if rerr != nil { + return rerr + } + return werr +} + +func init() { + gob.Register(crypto.SHA256) + gob.Register(&rsa.PSSOptions{}) +} + +// SignArgs contains arguments to a crypto Signer.Sign method. +type SignArgs struct { + Digest []byte // The content to sign. + Opts crypto.SignerOpts // Options for signing, such as Hash identifier. +} + +// Key implements credential.Credential by holding the executed signer subprocess. +type Key struct { + cmd *exec.Cmd // Pointer to the signer subprocess. + client *rpc.Client // Pointer to the rpc client that communicates with the signer subprocess. + publicKey crypto.PublicKey // Public key of loaded certificate. + chain [][]byte // Certificate chain of loaded certificate. +} + +// CertificateChain returns the credential as a raw X509 cert chain. This contains the public key. +func (k *Key) CertificateChain() [][]byte { + return k.chain +} + +// Close closes the RPC connection and kills the signer subprocess. +// Call this to free up resources when the Key object is no longer needed. +func (k *Key) Close() error { + if err := k.cmd.Process.Kill(); err != nil { + return fmt.Errorf("failed to kill signer process: %w", err) + } + // Wait for cmd to exit and release resources. Since the process is forcefully killed, this + // will return a non-nil error (varies by OS), which we will ignore. + _ = k.cmd.Wait() + // The Pipes connecting the RPC client should have been closed when the signer subprocess was killed. + // Calling `k.client.Close()` before `k.cmd.Process.Kill()` or `k.cmd.Wait()` _will_ cause a segfault. + if err := k.client.Close(); err.Error() != "close |0: file already closed" { + return fmt.Errorf("failed to close RPC connection: %w", err) + } + return nil +} + +// Public returns the public key for this Key. +func (k *Key) Public() crypto.PublicKey { + return k.publicKey +} + +// Sign signs a message digest, using the specified signer options. +func (k *Key) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) (signed []byte, err error) { + if opts != nil && opts.HashFunc() != 0 && len(digest) != opts.HashFunc().Size() { + return nil, fmt.Errorf("Digest length of %v bytes does not match Hash function size of %v bytes", len(digest), opts.HashFunc().Size()) + } + err = k.client.Call(signAPI, SignArgs{Digest: digest, Opts: opts}, &signed) + return +} + +// ErrCredUnavailable is a sentinel error that indicates ECP Cred is unavailable, +// possibly due to missing config or missing binary path. +var ErrCredUnavailable = errors.New("Cred is unavailable") + +// Cred spawns a signer subprocess that listens on stdin/stdout to perform certificate +// related operations, including signing messages with the private key. +// +// The signer binary path is read from the specified configFilePath, if provided. +// Otherwise, use the default config file path. +// +// The config file also specifies which certificate the signer should use. +func Cred(configFilePath string) (*Key, error) { + if configFilePath == "" { + configFilePath = util.GetDefaultConfigFilePath() + } + enterpriseCertSignerPath, err := util.LoadSignerBinaryPath(configFilePath) + if err != nil { + if errors.Is(err, util.ErrConfigUnavailable) { + return nil, ErrCredUnavailable + } + return nil, err + } + k := &Key{ + cmd: exec.Command(enterpriseCertSignerPath, configFilePath), + } + + // Redirect errors from subprocess to parent process. + k.cmd.Stderr = os.Stderr + + // RPC client will communicate with subprocess over stdin/stdout. + kin, err := k.cmd.StdinPipe() + if err != nil { + return nil, err + } + kout, err := k.cmd.StdoutPipe() + if err != nil { + return nil, err + } + k.client = rpc.NewClient(&Connection{kout, kin}) + + if err := k.cmd.Start(); err != nil { + return nil, fmt.Errorf("starting enterprise cert signer subprocess: %w", err) + } + + if err := k.client.Call(certificateChainAPI, struct{}{}, &k.chain); err != nil { + return nil, fmt.Errorf("failed to retrieve certificate chain: %w", err) + } + + var publicKeyBytes []byte + if err := k.client.Call(publicKeyAPI, struct{}{}, &publicKeyBytes); err != nil { + return nil, fmt.Errorf("failed to retrieve public key: %w", err) + } + + publicKey, err := x509.ParsePKIXPublicKey(publicKeyBytes) + if err != nil { + return nil, fmt.Errorf("failed to parse public key: %w", err) + } + + var ok bool + k.publicKey, ok = publicKey.(crypto.PublicKey) + if !ok { + return nil, fmt.Errorf("invalid public key type: %T", publicKey) + } + + switch pub := k.publicKey.(type) { + case *rsa.PublicKey: + if pub.Size() < 256 { + return nil, fmt.Errorf("RSA modulus size is less than 2048 bits: %v", pub.Size()*8) + } + case *ecdsa.PublicKey: + default: + return nil, fmt.Errorf("unsupported public key type: %v", pub) + } + + return k, nil +} diff --git a/vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go b/vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go new file mode 100644 index 00000000000..1640ec1c9e3 --- /dev/null +++ b/vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go @@ -0,0 +1,91 @@ +// Copyright 2022 Google LLC. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package util provides helper functions for the client. +package util + +import ( + "encoding/json" + "errors" + "io" + "os" + "os/user" + "path/filepath" + "runtime" +) + +const configFileName = "certificate_config.json" + +// EnterpriseCertificateConfig contains parameters for initializing signer. +type EnterpriseCertificateConfig struct { + Libs Libs `json:"libs"` +} + +// Libs specifies the locations of helper libraries. +type Libs struct { + ECP string `json:"ecp"` +} + +// ErrConfigUnavailable is a sentinel error that indicates ECP config is unavailable, +// possibly due to entire config missing or missing binary path. +var ErrConfigUnavailable = errors.New("Config is unavailable") + +// LoadSignerBinaryPath retrieves the path of the signer binary from the config file. +func LoadSignerBinaryPath(configFilePath string) (path string, err error) { + jsonFile, err := os.Open(configFilePath) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return "", ErrConfigUnavailable + } + return "", err + } + + byteValue, err := io.ReadAll(jsonFile) + if err != nil { + return "", err + } + var config EnterpriseCertificateConfig + err = json.Unmarshal(byteValue, &config) + if err != nil { + return "", err + } + signerBinaryPath := config.Libs.ECP + if signerBinaryPath == "" { + return "", ErrConfigUnavailable + } + return signerBinaryPath, nil +} + +func guessHomeDir() string { + // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470 + if v := os.Getenv("HOME"); v != "" { + return v + } + // Else, fall back to user.Current: + if u, err := user.Current(); err == nil { + return u.HomeDir + } + return "" +} + +func getDefaultConfigFileDirectory() (directory string) { + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud") + } + return filepath.Join(guessHomeDir(), ".config/gcloud") +} + +// GetDefaultConfigFilePath returns the default path of the enterprise certificate config file created by gCloud. +func GetDefaultConfigFilePath() (path string) { + return filepath.Join(getDefaultConfigFileDirectory(), configFileName) +} diff --git a/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json b/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json index 0e643a05b57..91d60a809fa 100644 --- a/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json +++ b/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json @@ -1,3 +1,3 @@ { - "v2": "2.4.0" + "v2": "2.11.0" } diff --git a/vendor/github.com/googleapis/gax-go/v2/CHANGES.md b/vendor/github.com/googleapis/gax-go/v2/CHANGES.md index b42ace44c98..e17b196f6c7 100644 --- a/vendor/github.com/googleapis/gax-go/v2/CHANGES.md +++ b/vendor/github.com/googleapis/gax-go/v2/CHANGES.md @@ -1,5 +1,86 @@ # Changelog +## [2.11.0](https://github.com/googleapis/gax-go/compare/v2.10.0...v2.11.0) (2023-06-13) + + +### Features + +* **v2:** add GoVersion package variable ([#283](https://github.com/googleapis/gax-go/issues/283)) ([26553cc](https://github.com/googleapis/gax-go/commit/26553ccadb4016b189881f52e6c253b68bb3e3d5)) + + +### Bug Fixes + +* **v2:** handle space in non-devel go version ([#288](https://github.com/googleapis/gax-go/issues/288)) ([fd7bca0](https://github.com/googleapis/gax-go/commit/fd7bca029a1c5e63def8f0a5fd1ec3f725d92f75)) + +## [2.10.0](https://github.com/googleapis/gax-go/compare/v2.9.1...v2.10.0) (2023-05-30) + + +### Features + +* update dependencies ([#280](https://github.com/googleapis/gax-go/issues/280)) ([4514281](https://github.com/googleapis/gax-go/commit/4514281058590f3637c36bfd49baa65c4d3cfb21)) + +## [2.9.1](https://github.com/googleapis/gax-go/compare/v2.9.0...v2.9.1) (2023-05-23) + + +### Bug Fixes + +* **v2:** drop cloud lro test dep ([#276](https://github.com/googleapis/gax-go/issues/276)) ([c67eeba](https://github.com/googleapis/gax-go/commit/c67eeba0f10a3294b1d93c1b8fbe40211a55ae5f)), refs [#270](https://github.com/googleapis/gax-go/issues/270) + +## [2.9.0](https://github.com/googleapis/gax-go/compare/v2.8.0...v2.9.0) (2023-05-22) + + +### Features + +* **apierror:** add method to return HTTP status code conditionally ([#274](https://github.com/googleapis/gax-go/issues/274)) ([5874431](https://github.com/googleapis/gax-go/commit/587443169acd10f7f86d1989dc8aaf189e645e98)), refs [#229](https://github.com/googleapis/gax-go/issues/229) + + +### Documentation + +* add ref to usage with clients ([#272](https://github.com/googleapis/gax-go/issues/272)) ([ea4d72d](https://github.com/googleapis/gax-go/commit/ea4d72d514beba4de450868b5fb028601a29164e)), refs [#228](https://github.com/googleapis/gax-go/issues/228) + +## [2.8.0](https://github.com/googleapis/gax-go/compare/v2.7.1...v2.8.0) (2023-03-15) + + +### Features + +* **v2:** add WithTimeout option ([#259](https://github.com/googleapis/gax-go/issues/259)) ([9a8da43](https://github.com/googleapis/gax-go/commit/9a8da43693002448b1e8758023699387481866d1)) + +## [2.7.1](https://github.com/googleapis/gax-go/compare/v2.7.0...v2.7.1) (2023-03-06) + + +### Bug Fixes + +* **v2/apierror:** return Unknown GRPCStatus when err source is HTTP ([#260](https://github.com/googleapis/gax-go/issues/260)) ([043b734](https://github.com/googleapis/gax-go/commit/043b73437a240a91229207fb3ee52a9935a36f23)), refs [#254](https://github.com/googleapis/gax-go/issues/254) + +## [2.7.0](https://github.com/googleapis/gax-go/compare/v2.6.0...v2.7.0) (2022-11-02) + + +### Features + +* update google.golang.org/api to latest ([#240](https://github.com/googleapis/gax-go/issues/240)) ([f690a02](https://github.com/googleapis/gax-go/commit/f690a02c806a2903bdee943ede3a58e3a331ebd6)) +* **v2/apierror:** add apierror.FromWrappingError ([#238](https://github.com/googleapis/gax-go/issues/238)) ([9dbd96d](https://github.com/googleapis/gax-go/commit/9dbd96d59b9d54ceb7c025513aa8c1a9d727382f)) + +## [2.6.0](https://github.com/googleapis/gax-go/compare/v2.5.1...v2.6.0) (2022-10-13) + + +### Features + +* **v2:** copy DetermineContentType functionality ([#230](https://github.com/googleapis/gax-go/issues/230)) ([2c52a70](https://github.com/googleapis/gax-go/commit/2c52a70bae965397f740ed27d46aabe89ff249b3)) + +## [2.5.1](https://github.com/googleapis/gax-go/compare/v2.5.0...v2.5.1) (2022-08-04) + + +### Bug Fixes + +* **v2:** resolve bad genproto pseudoversion in go.mod ([#218](https://github.com/googleapis/gax-go/issues/218)) ([1379b27](https://github.com/googleapis/gax-go/commit/1379b27e9846d959f7e1163b9ef298b3c92c8d23)) + +## [2.5.0](https://github.com/googleapis/gax-go/compare/v2.4.0...v2.5.0) (2022-08-04) + + +### Features + +* add ExtractProtoMessage to apierror ([#213](https://github.com/googleapis/gax-go/issues/213)) ([a6ce70c](https://github.com/googleapis/gax-go/commit/a6ce70c725c890533a9de6272d3b5ba2e336d6bb)) + ## [2.4.0](https://github.com/googleapis/gax-go/compare/v2.3.0...v2.4.0) (2022-05-09) diff --git a/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go b/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go index 7d0128a0cd5..d785a065cab 100644 --- a/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go +++ b/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go @@ -29,6 +29,10 @@ // Package apierror implements a wrapper error for parsing error details from // API calls. Both HTTP & gRPC status errors are supported. +// +// For examples of how to use [APIError] with client libraries please reference +// [Inspecting errors](https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors) +// in the client library documentation. package apierror import ( @@ -39,8 +43,10 @@ import ( jsonerror "github.com/googleapis/gax-go/v2/apierror/internal/proto" "google.golang.org/api/googleapi" "google.golang.org/genproto/googleapis/rpc/errdetails" + "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" ) // ErrDetails holds the google/rpc/error_details.proto messages. @@ -60,6 +66,30 @@ type ErrDetails struct { Unknown []interface{} } +// ErrMessageNotFound is used to signal ExtractProtoMessage found no matching messages. +var ErrMessageNotFound = errors.New("message not found") + +// ExtractProtoMessage provides a mechanism for extracting protobuf messages from the +// Unknown error details. If ExtractProtoMessage finds an unknown message of the same type, +// the content of the message is copied to the provided message. +// +// ExtractProtoMessage will return ErrMessageNotFound if there are no message matching the +// protocol buffer type of the provided message. +func (e ErrDetails) ExtractProtoMessage(v proto.Message) error { + if v == nil { + return ErrMessageNotFound + } + for _, elem := range e.Unknown { + if elemProto, ok := elem.(proto.Message); ok { + if v.ProtoReflect().Type() == elemProto.ProtoReflect().Type() { + proto.Merge(v, elemProto) + return nil + } + } + } + return ErrMessageNotFound +} + func (e ErrDetails) String() string { var d strings.Builder if e.ErrorInfo != nil { @@ -172,12 +202,12 @@ func (a *APIError) Unwrap() error { // Error returns a readable representation of the APIError. func (a *APIError) Error() string { var msg string - if a.status != nil { - msg = a.err.Error() - } else if a.httpErr != nil { + if a.httpErr != nil { // Truncate the googleapi.Error message because it dumps the Details in // an ugly way. msg = fmt.Sprintf("googleapi: Error %d: %s", a.httpErr.Code, a.httpErr.Message) + } else if a.status != nil { + msg = a.err.Error() } return strings.TrimSpace(fmt.Sprintf("%s\n%s", msg, a.details)) } @@ -208,30 +238,53 @@ func (a *APIError) Metadata() map[string]string { } -// FromError parses a Status error or a googleapi.Error and builds an APIError. -func FromError(err error) (*APIError, bool) { - if err == nil { - return nil, false - } - - ae := APIError{err: err} +// setDetailsFromError parses a Status error or a googleapi.Error +// and sets status and details or httpErr and details, respectively. +// It returns false if neither Status nor googleapi.Error can be parsed. +// When err is a googleapi.Error, the status of the returned error will +// be set to an Unknown error, rather than nil, since a nil code is +// interpreted as OK in the gRPC status package. +func (a *APIError) setDetailsFromError(err error) bool { st, isStatus := status.FromError(err) var herr *googleapi.Error isHTTPErr := errors.As(err, &herr) switch { case isStatus: - ae.status = st - ae.details = parseDetails(st.Details()) + a.status = st + a.details = parseDetails(st.Details()) case isHTTPErr: - ae.httpErr = herr - ae.details = parseHTTPDetails(herr) + a.httpErr = herr + a.details = parseHTTPDetails(herr) + a.status = status.New(codes.Unknown, herr.Message) default: - return nil, false + return false } + return true +} - return &ae, true +// FromError parses a Status error or a googleapi.Error and builds an +// APIError, wrapping the provided error in the new APIError. It +// returns false if neither Status nor googleapi.Error can be parsed. +func FromError(err error) (*APIError, bool) { + return ParseError(err, true) +} +// ParseError parses a Status error or a googleapi.Error and builds an +// APIError. If wrap is true, it wraps the error in the new APIError. +// It returns false if neither Status nor googleapi.Error can be parsed. +func ParseError(err error, wrap bool) (*APIError, bool) { + if err == nil { + return nil, false + } + ae := APIError{} + if wrap { + ae = APIError{err: err} + } + if !ae.setDetailsFromError(err) { + return nil, false + } + return &ae, true } // parseDetails accepts a slice of interface{} that should be backed by some @@ -296,3 +349,13 @@ func parseHTTPDetails(gae *googleapi.Error) ErrDetails { return parseDetails(details) } + +// HTTPCode returns the underlying HTTP response status code. This method returns +// `-1` if the underlying error is a [google.golang.org/grpc/status.Status]. To +// check gRPC error codes use [google.golang.org/grpc/status.Code]. +func (a *APIError) HTTPCode() int { + if a.httpErr == nil { + return -1 + } + return a.httpErr.Code +} diff --git a/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go b/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go new file mode 100644 index 00000000000..e4b03f161d8 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go @@ -0,0 +1,256 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.17.3 +// source: custom_error.proto + +package jsonerror + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Error code for `CustomError`. +type CustomError_CustomErrorCode int32 + +const ( + // Default error. + CustomError_CUSTOM_ERROR_CODE_UNSPECIFIED CustomError_CustomErrorCode = 0 + // Too many foo. + CustomError_TOO_MANY_FOO CustomError_CustomErrorCode = 1 + // Not enough foo. + CustomError_NOT_ENOUGH_FOO CustomError_CustomErrorCode = 2 + // Catastrophic error. + CustomError_UNIVERSE_WAS_DESTROYED CustomError_CustomErrorCode = 3 +) + +// Enum value maps for CustomError_CustomErrorCode. +var ( + CustomError_CustomErrorCode_name = map[int32]string{ + 0: "CUSTOM_ERROR_CODE_UNSPECIFIED", + 1: "TOO_MANY_FOO", + 2: "NOT_ENOUGH_FOO", + 3: "UNIVERSE_WAS_DESTROYED", + } + CustomError_CustomErrorCode_value = map[string]int32{ + "CUSTOM_ERROR_CODE_UNSPECIFIED": 0, + "TOO_MANY_FOO": 1, + "NOT_ENOUGH_FOO": 2, + "UNIVERSE_WAS_DESTROYED": 3, + } +) + +func (x CustomError_CustomErrorCode) Enum() *CustomError_CustomErrorCode { + p := new(CustomError_CustomErrorCode) + *p = x + return p +} + +func (x CustomError_CustomErrorCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CustomError_CustomErrorCode) Descriptor() protoreflect.EnumDescriptor { + return file_custom_error_proto_enumTypes[0].Descriptor() +} + +func (CustomError_CustomErrorCode) Type() protoreflect.EnumType { + return &file_custom_error_proto_enumTypes[0] +} + +func (x CustomError_CustomErrorCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CustomError_CustomErrorCode.Descriptor instead. +func (CustomError_CustomErrorCode) EnumDescriptor() ([]byte, []int) { + return file_custom_error_proto_rawDescGZIP(), []int{0, 0} +} + +// CustomError is an example of a custom error message which may be included +// in an rpc status. It is not meant to reflect a standard error. +type CustomError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Error code specific to the custom API being invoked. + Code CustomError_CustomErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=error.CustomError_CustomErrorCode" json:"code,omitempty"` + // Name of the failed entity. + Entity string `protobuf:"bytes,2,opt,name=entity,proto3" json:"entity,omitempty"` + // Message that describes the error. + ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` +} + +func (x *CustomError) Reset() { + *x = CustomError{} + if protoimpl.UnsafeEnabled { + mi := &file_custom_error_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomError) ProtoMessage() {} + +func (x *CustomError) ProtoReflect() protoreflect.Message { + mi := &file_custom_error_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomError.ProtoReflect.Descriptor instead. +func (*CustomError) Descriptor() ([]byte, []int) { + return file_custom_error_proto_rawDescGZIP(), []int{0} +} + +func (x *CustomError) GetCode() CustomError_CustomErrorCode { + if x != nil { + return x.Code + } + return CustomError_CUSTOM_ERROR_CODE_UNSPECIFIED +} + +func (x *CustomError) GetEntity() string { + if x != nil { + return x.Entity + } + return "" +} + +func (x *CustomError) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +var File_custom_error_proto protoreflect.FileDescriptor + +var file_custom_error_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xfa, 0x01, 0x0a, 0x0b, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x76, 0x0a, 0x0f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x4f, 0x4f, 0x5f, 0x4d, 0x41, + 0x4e, 0x59, 0x5f, 0x46, 0x4f, 0x4f, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x4f, 0x54, 0x5f, + 0x45, 0x4e, 0x4f, 0x55, 0x47, 0x48, 0x5f, 0x46, 0x4f, 0x4f, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, + 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x45, 0x5f, 0x57, 0x41, 0x53, 0x5f, 0x44, 0x45, 0x53, + 0x54, 0x52, 0x4f, 0x59, 0x45, 0x44, 0x10, 0x03, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, + 0x73, 0x2f, 0x67, 0x61, 0x78, 0x2d, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x3b, 0x6a, 0x73, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_custom_error_proto_rawDescOnce sync.Once + file_custom_error_proto_rawDescData = file_custom_error_proto_rawDesc +) + +func file_custom_error_proto_rawDescGZIP() []byte { + file_custom_error_proto_rawDescOnce.Do(func() { + file_custom_error_proto_rawDescData = protoimpl.X.CompressGZIP(file_custom_error_proto_rawDescData) + }) + return file_custom_error_proto_rawDescData +} + +var file_custom_error_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_custom_error_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_custom_error_proto_goTypes = []interface{}{ + (CustomError_CustomErrorCode)(0), // 0: error.CustomError.CustomErrorCode + (*CustomError)(nil), // 1: error.CustomError +} +var file_custom_error_proto_depIdxs = []int32{ + 0, // 0: error.CustomError.code:type_name -> error.CustomError.CustomErrorCode + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_custom_error_proto_init() } +func file_custom_error_proto_init() { + if File_custom_error_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_custom_error_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_custom_error_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_custom_error_proto_goTypes, + DependencyIndexes: file_custom_error_proto_depIdxs, + EnumInfos: file_custom_error_proto_enumTypes, + MessageInfos: file_custom_error_proto_msgTypes, + }.Build() + File_custom_error_proto = out.File + file_custom_error_proto_rawDesc = nil + file_custom_error_proto_goTypes = nil + file_custom_error_proto_depIdxs = nil +} diff --git a/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto b/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto new file mode 100644 index 00000000000..21678ae65c9 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto @@ -0,0 +1,50 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package error; + +option go_package = "github.com/googleapis/gax-go/v2/apierror/internal/proto;jsonerror"; + + +// CustomError is an example of a custom error message which may be included +// in an rpc status. It is not meant to reflect a standard error. +message CustomError { + + // Error code for `CustomError`. + enum CustomErrorCode { + // Default error. + CUSTOM_ERROR_CODE_UNSPECIFIED = 0; + + // Too many foo. + TOO_MANY_FOO = 1; + + // Not enough foo. + NOT_ENOUGH_FOO = 2; + + // Catastrophic error. + UNIVERSE_WAS_DESTROYED = 3; + + } + + // Error code specific to the custom API being invoked. + CustomErrorCode code = 1; + + // Name of the failed entity. + string entity = 2; + + // Message that describes the error. + string error_message = 3; +} diff --git a/vendor/github.com/googleapis/gax-go/v2/call_option.go b/vendor/github.com/googleapis/gax-go/v2/call_option.go index e092005563b..c52e03f6436 100644 --- a/vendor/github.com/googleapis/gax-go/v2/call_option.go +++ b/vendor/github.com/googleapis/gax-go/v2/call_option.go @@ -218,6 +218,14 @@ func (p pathOpt) Resolve(s *CallSettings) { s.Path = p.p } +type timeoutOpt struct { + t time.Duration +} + +func (t timeoutOpt) Resolve(s *CallSettings) { + s.timeout = t.t +} + // WithPath applies a Path override to the HTTP-based APICall. // // This is for internal use only. @@ -230,6 +238,15 @@ func WithGRPCOptions(opt ...grpc.CallOption) CallOption { return grpcOpt(append([]grpc.CallOption(nil), opt...)) } +// WithTimeout is a convenience option for setting a context.WithTimeout on the +// singular context.Context used for **all** APICall attempts. Calculated from +// the start of the first APICall attempt. +// If the context.Context provided to Invoke already has a Deadline set, that +// will always be respected over the deadline calculated using this option. +func WithTimeout(t time.Duration) CallOption { + return &timeoutOpt{t: t} +} + // CallSettings allow fine-grained control over how calls are made. type CallSettings struct { // Retry returns a Retryer to be used to control retry logic of a method call. @@ -241,4 +258,8 @@ type CallSettings struct { // Path is an HTTP override for an APICall. Path string + + // Timeout defines the amount of time that Invoke has to complete. + // Unexported so it cannot be changed by the code in an APICall. + timeout time.Duration } diff --git a/vendor/github.com/googleapis/gax-go/v2/content_type.go b/vendor/github.com/googleapis/gax-go/v2/content_type.go new file mode 100644 index 00000000000..1b53d0a3ac1 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/content_type.go @@ -0,0 +1,112 @@ +// Copyright 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package gax + +import ( + "io" + "io/ioutil" + "net/http" +) + +const sniffBuffSize = 512 + +func newContentSniffer(r io.Reader) *contentSniffer { + return &contentSniffer{r: r} +} + +// contentSniffer wraps a Reader, and reports the content type determined by sniffing up to 512 bytes from the Reader. +type contentSniffer struct { + r io.Reader + start []byte // buffer for the sniffed bytes. + err error // set to any error encountered while reading bytes to be sniffed. + + ctype string // set on first sniff. + sniffed bool // set to true on first sniff. +} + +func (cs *contentSniffer) Read(p []byte) (n int, err error) { + // Ensure that the content type is sniffed before any data is consumed from Reader. + _, _ = cs.ContentType() + + if len(cs.start) > 0 { + n := copy(p, cs.start) + cs.start = cs.start[n:] + return n, nil + } + + // We may have read some bytes into start while sniffing, even if the read ended in an error. + // We should first return those bytes, then the error. + if cs.err != nil { + return 0, cs.err + } + + // Now we have handled all bytes that were buffered while sniffing. Now just delegate to the underlying reader. + return cs.r.Read(p) +} + +// ContentType returns the sniffed content type, and whether the content type was successfully sniffed. +func (cs *contentSniffer) ContentType() (string, bool) { + if cs.sniffed { + return cs.ctype, cs.ctype != "" + } + cs.sniffed = true + // If ReadAll hits EOF, it returns err==nil. + cs.start, cs.err = ioutil.ReadAll(io.LimitReader(cs.r, sniffBuffSize)) + + // Don't try to detect the content type based on possibly incomplete data. + if cs.err != nil { + return "", false + } + + cs.ctype = http.DetectContentType(cs.start) + return cs.ctype, true +} + +// DetermineContentType determines the content type of the supplied reader. +// The content of media will be sniffed to determine the content type. +// After calling DetectContentType the caller must not perform further reads on +// media, but rather read from the Reader that is returned. +func DetermineContentType(media io.Reader) (io.Reader, string) { + // For backwards compatibility, allow clients to set content + // type by providing a ContentTyper for media. + // Note: This is an anonymous interface definition copied from googleapi.ContentTyper. + if typer, ok := media.(interface { + ContentType() string + }); ok { + return media, typer.ContentType() + } + + sniffer := newContentSniffer(media) + if ctype, ok := sniffer.ContentType(); ok { + return sniffer, ctype + } + // If content type could not be sniffed, reads from sniffer will eventually fail with an error. + return sniffer, "" +} diff --git a/vendor/github.com/googleapis/gax-go/v2/header.go b/vendor/github.com/googleapis/gax-go/v2/header.go index 139371a0bf1..6488461f4dc 100644 --- a/vendor/github.com/googleapis/gax-go/v2/header.go +++ b/vendor/github.com/googleapis/gax-go/v2/header.go @@ -29,7 +29,73 @@ package gax -import "bytes" +import ( + "bytes" + "runtime" + "strings" + "unicode" +) + +var ( + // GoVersion is a header-safe representation of the current runtime + // environment's Go version. This is for GAX consumers that need to + // report the Go runtime version in API calls. + GoVersion string + // version is a package internal global variable for testing purposes. + version = runtime.Version +) + +// versionUnknown is only used when the runtime version cannot be determined. +const versionUnknown = "UNKNOWN" + +func init() { + GoVersion = goVersion() +} + +// goVersion returns a Go runtime version derived from the runtime environment +// that is modified to be suitable for reporting in a header, meaning it has no +// whitespace. If it is unable to determine the Go runtime version, it returns +// versionUnknown. +func goVersion() string { + const develPrefix = "devel +" + + s := version() + if strings.HasPrefix(s, develPrefix) { + s = s[len(develPrefix):] + if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { + s = s[:p] + } + return s + } else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { + s = s[:p] + } + + notSemverRune := func(r rune) bool { + return !strings.ContainsRune("0123456789.", r) + } + + if strings.HasPrefix(s, "go1") { + s = s[2:] + var prerelease string + if p := strings.IndexFunc(s, notSemverRune); p >= 0 { + s, prerelease = s[:p], s[p:] + } + if strings.HasSuffix(s, ".") { + s += "0" + } else if strings.Count(s, ".") < 2 { + s += ".0" + } + if prerelease != "" { + // Some release candidates already have a dash in them. + if !strings.HasPrefix(prerelease, "-") { + prerelease = "-" + prerelease + } + s += prerelease + } + return s + } + return "UNKNOWN" +} // XGoogHeader is for use by the Google Cloud Libraries only. // diff --git a/vendor/github.com/googleapis/gax-go/v2/internal/version.go b/vendor/github.com/googleapis/gax-go/v2/internal/version.go index bf272a5045c..374dcdb1151 100644 --- a/vendor/github.com/googleapis/gax-go/v2/internal/version.go +++ b/vendor/github.com/googleapis/gax-go/v2/internal/version.go @@ -30,4 +30,4 @@ package internal // Version is the current tagged release of the library. -const Version = "2.4.0" +const Version = "2.11.0" diff --git a/vendor/github.com/googleapis/gax-go/v2/invoke.go b/vendor/github.com/googleapis/gax-go/v2/invoke.go index 9fcc29959b9..721d1af5517 100644 --- a/vendor/github.com/googleapis/gax-go/v2/invoke.go +++ b/vendor/github.com/googleapis/gax-go/v2/invoke.go @@ -68,6 +68,16 @@ type sleeper func(ctx context.Context, d time.Duration) error // invoke implements Invoke, taking an additional sleeper argument for testing. func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error { var retryer Retryer + + // Only use the value provided via WithTimeout if the context doesn't + // already have a deadline. This is important for backwards compatibility if + // the user already set a deadline on the context given to Invoke. + if _, ok := ctx.Deadline(); !ok && settings.timeout != 0 { + c, cc := context.WithTimeout(ctx, settings.timeout) + defer cc() + ctx = c + } + for { err := call(ctx, settings) if err == nil { diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel deleted file mode 100644 index 5242751fb2d..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel +++ /dev/null @@ -1,23 +0,0 @@ -load("@rules_proto//proto:defs.bzl", "proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") - -package(default_visibility = ["//visibility:public"]) - -proto_library( - name = "internal_proto", - srcs = ["errors.proto"], - deps = ["@com_google_protobuf//:any_proto"], -) - -go_proto_library( - name = "internal_go_proto", - importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", - proto = ":internal_proto", -) - -go_library( - name = "go_default_library", - embed = [":internal_go_proto"], - importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go deleted file mode 100644 index 61101d7177f..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.pb.go +++ /dev/null @@ -1,189 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: internal/errors.proto - -package internal - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - any "github.com/golang/protobuf/ptypes/any" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Error is the generic error returned from unary RPCs. -type Error struct { - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - // This is to make the error more compatible with users that expect errors to be Status objects: - // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto - // It should be the exact same message as the Error field. - Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - Details []*any.Any `protobuf:"bytes,4,rep,name=details,proto3" json:"details,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Error) Reset() { *m = Error{} } -func (m *Error) String() string { return proto.CompactTextString(m) } -func (*Error) ProtoMessage() {} -func (*Error) Descriptor() ([]byte, []int) { - return fileDescriptor_9b093362ca6d1e03, []int{0} -} - -func (m *Error) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Error.Unmarshal(m, b) -} -func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Error.Marshal(b, m, deterministic) -} -func (m *Error) XXX_Merge(src proto.Message) { - xxx_messageInfo_Error.Merge(m, src) -} -func (m *Error) XXX_Size() int { - return xxx_messageInfo_Error.Size(m) -} -func (m *Error) XXX_DiscardUnknown() { - xxx_messageInfo_Error.DiscardUnknown(m) -} - -var xxx_messageInfo_Error proto.InternalMessageInfo - -func (m *Error) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *Error) GetCode() int32 { - if m != nil { - return m.Code - } - return 0 -} - -func (m *Error) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *Error) GetDetails() []*any.Any { - if m != nil { - return m.Details - } - return nil -} - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -type StreamError struct { - GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"` - HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"` - Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *StreamError) Reset() { *m = StreamError{} } -func (m *StreamError) String() string { return proto.CompactTextString(m) } -func (*StreamError) ProtoMessage() {} -func (*StreamError) Descriptor() ([]byte, []int) { - return fileDescriptor_9b093362ca6d1e03, []int{1} -} - -func (m *StreamError) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_StreamError.Unmarshal(m, b) -} -func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_StreamError.Marshal(b, m, deterministic) -} -func (m *StreamError) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamError.Merge(m, src) -} -func (m *StreamError) XXX_Size() int { - return xxx_messageInfo_StreamError.Size(m) -} -func (m *StreamError) XXX_DiscardUnknown() { - xxx_messageInfo_StreamError.DiscardUnknown(m) -} - -var xxx_messageInfo_StreamError proto.InternalMessageInfo - -func (m *StreamError) GetGrpcCode() int32 { - if m != nil { - return m.GrpcCode - } - return 0 -} - -func (m *StreamError) GetHttpCode() int32 { - if m != nil { - return m.HttpCode - } - return 0 -} - -func (m *StreamError) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *StreamError) GetHttpStatus() string { - if m != nil { - return m.HttpStatus - } - return "" -} - -func (m *StreamError) GetDetails() []*any.Any { - if m != nil { - return m.Details - } - return nil -} - -func init() { - proto.RegisterType((*Error)(nil), "grpc.gateway.runtime.Error") - proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError") -} - -func init() { proto.RegisterFile("internal/errors.proto", fileDescriptor_9b093362ca6d1e03) } - -var fileDescriptor_9b093362ca6d1e03 = []byte{ - // 252 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xc1, 0x4a, 0xc4, 0x30, - 0x10, 0x86, 0x89, 0xbb, 0x75, 0xdb, 0xe9, 0x2d, 0x54, 0x88, 0xee, 0xc1, 0xb2, 0xa7, 0x9e, 0x52, - 0xd0, 0x27, 0xd0, 0xc5, 0x17, 0xe8, 0xde, 0xbc, 0x2c, 0xd9, 0xdd, 0x31, 0x16, 0xda, 0xa4, 0x24, - 0x53, 0xa4, 0xf8, 0x56, 0x3e, 0xa1, 0x24, 0xa5, 0xb0, 0x27, 0xf1, 0xd6, 0xf9, 0xfb, 0xcf, 0x7c, - 0x1f, 0x81, 0xbb, 0xd6, 0x10, 0x3a, 0xa3, 0xba, 0x1a, 0x9d, 0xb3, 0xce, 0xcb, 0xc1, 0x59, 0xb2, - 0xbc, 0xd0, 0x6e, 0x38, 0x4b, 0xad, 0x08, 0xbf, 0xd4, 0x24, 0xdd, 0x68, 0xa8, 0xed, 0xf1, 0xe1, - 0x5e, 0x5b, 0xab, 0x3b, 0xac, 0x63, 0xe7, 0x34, 0x7e, 0xd4, 0xca, 0x4c, 0xf3, 0xc2, 0xee, 0x1b, - 0x92, 0xb7, 0x70, 0x80, 0x17, 0x90, 0xc4, 0x4b, 0x82, 0x95, 0xac, 0xca, 0x9a, 0x79, 0xe0, 0x1c, - 0xd6, 0x67, 0x7b, 0x41, 0x71, 0x53, 0xb2, 0x2a, 0x69, 0xe2, 0x37, 0x17, 0xb0, 0xe9, 0xd1, 0x7b, - 0xa5, 0x51, 0xac, 0x62, 0x77, 0x19, 0xb9, 0x84, 0xcd, 0x05, 0x49, 0xb5, 0x9d, 0x17, 0xeb, 0x72, - 0x55, 0xe5, 0x4f, 0x85, 0x9c, 0xc9, 0x72, 0x21, 0xcb, 0x17, 0x33, 0x35, 0x4b, 0x69, 0xf7, 0xc3, - 0x20, 0x3f, 0x90, 0x43, 0xd5, 0xcf, 0x0e, 0x5b, 0xc8, 0x82, 0xff, 0x31, 0x22, 0x59, 0x44, 0xa6, - 0x21, 0xd8, 0x07, 0xec, 0x16, 0xb2, 0x4f, 0xa2, 0xe1, 0x78, 0xe5, 0x93, 0x86, 0x60, 0xff, 0xb7, - 0xd3, 0x23, 0xe4, 0x71, 0xcd, 0x93, 0xa2, 0x31, 0x78, 0x85, 0xbf, 0x10, 0xa2, 0x43, 0x4c, 0xae, - 0xa5, 0x93, 0x7f, 0x48, 0xbf, 0xc2, 0x7b, 0xba, 0xbc, 0xfd, 0xe9, 0x36, 0x56, 0x9e, 0x7f, 0x03, - 0x00, 0x00, 0xff, 0xff, 0xde, 0x72, 0x6b, 0x83, 0x8e, 0x01, 0x00, 0x00, -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto deleted file mode 100644 index 4fb212c6b69..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/errors.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; -package grpc.gateway.runtime; -option go_package = "internal"; - -import "google/protobuf/any.proto"; - -// Error is the generic error returned from unary RPCs. -message Error { - string error = 1; - // This is to make the error more compatible with users that expect errors to be Status objects: - // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto - // It should be the exact same message as the Error field. - int32 code = 2; - string message = 3; - repeated google.protobuf.Any details = 4; -} - -// StreamError is a response type which is returned when -// streaming rpc returns an error. -message StreamError { - int32 grpc_code = 1; - int32 http_code = 2; - string message = 3; - string http_status = 4; - repeated google.protobuf.Any details = 5; -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel deleted file mode 100644 index 58b72b9cf75..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel +++ /dev/null @@ -1,85 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -package(default_visibility = ["//visibility:public"]) - -go_library( - name = "go_default_library", - srcs = [ - "context.go", - "convert.go", - "doc.go", - "errors.go", - "fieldmask.go", - "handler.go", - "marshal_httpbodyproto.go", - "marshal_json.go", - "marshal_jsonpb.go", - "marshal_proto.go", - "marshaler.go", - "marshaler_registry.go", - "mux.go", - "pattern.go", - "proto2_convert.go", - "proto_errors.go", - "query.go", - ], - importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime", - deps = [ - "//internal:go_default_library", - "//utilities:go_default_library", - "@com_github_golang_protobuf//descriptor:go_default_library_gen", - "@com_github_golang_protobuf//jsonpb:go_default_library_gen", - "@com_github_golang_protobuf//proto:go_default_library", - "@go_googleapis//google/api:httpbody_go_proto", - "@io_bazel_rules_go//proto/wkt:any_go_proto", - "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", - "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//grpclog:go_default_library", - "@org_golang_google_grpc//metadata:go_default_library", - "@org_golang_google_grpc//status:go_default_library", - ], -) - -go_test( - name = "go_default_test", - size = "small", - srcs = [ - "context_test.go", - "convert_test.go", - "errors_test.go", - "fieldmask_test.go", - "handler_test.go", - "marshal_httpbodyproto_test.go", - "marshal_json_test.go", - "marshal_jsonpb_test.go", - "marshal_proto_test.go", - "marshaler_registry_test.go", - "mux_test.go", - "pattern_test.go", - "query_test.go", - ], - embed = [":go_default_library"], - deps = [ - "//internal:go_default_library", - "//runtime/internal/examplepb:go_default_library", - "//utilities:go_default_library", - "@com_github_golang_protobuf//jsonpb:go_default_library_gen", - "@com_github_golang_protobuf//proto:go_default_library", - "@com_github_golang_protobuf//ptypes:go_default_library_gen", - "@go_googleapis//google/api:httpbody_go_proto", - "@go_googleapis//google/rpc:errdetails_go_proto", - "@io_bazel_rules_go//proto/wkt:duration_go_proto", - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", - "@io_bazel_rules_go//proto/wkt:struct_go_proto", - "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", - "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", - "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//metadata:go_default_library", - "@org_golang_google_grpc//status:go_default_library", - ], -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go deleted file mode 100644 index d8cbd4cc96b..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go +++ /dev/null @@ -1,291 +0,0 @@ -package runtime - -import ( - "context" - "encoding/base64" - "fmt" - "net" - "net/http" - "net/textproto" - "strconv" - "strings" - "sync" - "time" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// MetadataHeaderPrefix is the http prefix that represents custom metadata -// parameters to or from a gRPC call. -const MetadataHeaderPrefix = "Grpc-Metadata-" - -// MetadataPrefix is prepended to permanent HTTP header keys (as specified -// by the IANA) when added to the gRPC context. -const MetadataPrefix = "grpcgateway-" - -// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to -// HTTP headers in a response handled by grpc-gateway -const MetadataTrailerPrefix = "Grpc-Trailer-" - -const metadataGrpcTimeout = "Grpc-Timeout" -const metadataHeaderBinarySuffix = "-Bin" - -const xForwardedFor = "X-Forwarded-For" -const xForwardedHost = "X-Forwarded-Host" - -var ( - // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound - // header isn't present. If the value is 0 the sent `context` will not have a timeout. - DefaultContextTimeout = 0 * time.Second -) - -func decodeBinHeader(v string) ([]byte, error) { - if len(v)%4 == 0 { - // Input was padded, or padding was not necessary. - return base64.StdEncoding.DecodeString(v) - } - return base64.RawStdEncoding.DecodeString(v) -} - -/* -AnnotateContext adds context information such as metadata from the request. - -At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", -except that the forwarded destination is not another HTTP service but rather -a gRPC service. -*/ -func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) { - ctx, md, err := annotateContext(ctx, mux, req) - if err != nil { - return nil, err - } - if md == nil { - return ctx, nil - } - - return metadata.NewOutgoingContext(ctx, md), nil -} - -// AnnotateIncomingContext adds context information such as metadata from the request. -// Attach metadata as incoming context. -func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) { - ctx, md, err := annotateContext(ctx, mux, req) - if err != nil { - return nil, err - } - if md == nil { - return ctx, nil - } - - return metadata.NewIncomingContext(ctx, md), nil -} - -func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, metadata.MD, error) { - var pairs []string - timeout := DefaultContextTimeout - if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { - var err error - timeout, err = timeoutDecode(tm) - if err != nil { - return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) - } - } - - for key, vals := range req.Header { - key = textproto.CanonicalMIMEHeaderKey(key) - for _, val := range vals { - // For backwards-compatibility, pass through 'authorization' header with no prefix. - if key == "Authorization" { - pairs = append(pairs, "authorization", val) - } - if h, ok := mux.incomingHeaderMatcher(key); ok { - // Handles "-bin" metadata in grpc, since grpc will do another base64 - // encode before sending to server, we need to decode it first. - if strings.HasSuffix(key, metadataHeaderBinarySuffix) { - b, err := decodeBinHeader(val) - if err != nil { - return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err) - } - - val = string(b) - } - pairs = append(pairs, h, val) - } - } - } - if host := req.Header.Get(xForwardedHost); host != "" { - pairs = append(pairs, strings.ToLower(xForwardedHost), host) - } else if req.Host != "" { - pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) - } - - if addr := req.RemoteAddr; addr != "" { - if remoteIP, _, err := net.SplitHostPort(addr); err == nil { - if fwd := req.Header.Get(xForwardedFor); fwd == "" { - pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) - } else { - pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) - } - } - } - - if timeout != 0 { - ctx, _ = context.WithTimeout(ctx, timeout) - } - if len(pairs) == 0 { - return ctx, nil, nil - } - md := metadata.Pairs(pairs...) - for _, mda := range mux.metadataAnnotators { - md = metadata.Join(md, mda(ctx, req)) - } - return ctx, md, nil -} - -// ServerMetadata consists of metadata sent from gRPC server. -type ServerMetadata struct { - HeaderMD metadata.MD - TrailerMD metadata.MD -} - -type serverMetadataKey struct{} - -// NewServerMetadataContext creates a new context with ServerMetadata -func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { - return context.WithValue(ctx, serverMetadataKey{}, md) -} - -// ServerMetadataFromContext returns the ServerMetadata in ctx -func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { - md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) - return -} - -// ServerTransportStream implements grpc.ServerTransportStream. -// It should only be used by the generated files to support grpc.SendHeader -// outside of gRPC server use. -type ServerTransportStream struct { - mu sync.Mutex - header metadata.MD - trailer metadata.MD -} - -// Method returns the method for the stream. -func (s *ServerTransportStream) Method() string { - return "" -} - -// Header returns the header metadata of the stream. -func (s *ServerTransportStream) Header() metadata.MD { - s.mu.Lock() - defer s.mu.Unlock() - return s.header.Copy() -} - -// SetHeader sets the header metadata. -func (s *ServerTransportStream) SetHeader(md metadata.MD) error { - if md.Len() == 0 { - return nil - } - - s.mu.Lock() - s.header = metadata.Join(s.header, md) - s.mu.Unlock() - return nil -} - -// SendHeader sets the header metadata. -func (s *ServerTransportStream) SendHeader(md metadata.MD) error { - return s.SetHeader(md) -} - -// Trailer returns the cached trailer metadata. -func (s *ServerTransportStream) Trailer() metadata.MD { - s.mu.Lock() - defer s.mu.Unlock() - return s.trailer.Copy() -} - -// SetTrailer sets the trailer metadata. -func (s *ServerTransportStream) SetTrailer(md metadata.MD) error { - if md.Len() == 0 { - return nil - } - - s.mu.Lock() - s.trailer = metadata.Join(s.trailer, md) - s.mu.Unlock() - return nil -} - -func timeoutDecode(s string) (time.Duration, error) { - size := len(s) - if size < 2 { - return 0, fmt.Errorf("timeout string is too short: %q", s) - } - d, ok := timeoutUnitToDuration(s[size-1]) - if !ok { - return 0, fmt.Errorf("timeout unit is not recognized: %q", s) - } - t, err := strconv.ParseInt(s[:size-1], 10, 64) - if err != nil { - return 0, err - } - return d * time.Duration(t), nil -} - -func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { - switch u { - case 'H': - return time.Hour, true - case 'M': - return time.Minute, true - case 'S': - return time.Second, true - case 'm': - return time.Millisecond, true - case 'u': - return time.Microsecond, true - case 'n': - return time.Nanosecond, true - default: - } - return -} - -// isPermanentHTTPHeader checks whether hdr belongs to the list of -// permanent request headers maintained by IANA. -// http://www.iana.org/assignments/message-headers/message-headers.xml -func isPermanentHTTPHeader(hdr string) bool { - switch hdr { - case - "Accept", - "Accept-Charset", - "Accept-Language", - "Accept-Ranges", - "Authorization", - "Cache-Control", - "Content-Type", - "Cookie", - "Date", - "Expect", - "From", - "Host", - "If-Match", - "If-Modified-Since", - "If-None-Match", - "If-Schedule-Tag-Match", - "If-Unmodified-Since", - "Max-Forwards", - "Origin", - "Pragma", - "Referer", - "User-Agent", - "Via", - "Warning": - return true - } - return false -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go deleted file mode 100644 index b2ce743bddc..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go +++ /dev/null @@ -1,186 +0,0 @@ -package runtime - -import ( - "context" - "io" - "net/http" - "strings" - - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. -// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto -func HTTPStatusFromCode(code codes.Code) int { - switch code { - case codes.OK: - return http.StatusOK - case codes.Canceled: - return http.StatusRequestTimeout - case codes.Unknown: - return http.StatusInternalServerError - case codes.InvalidArgument: - return http.StatusBadRequest - case codes.DeadlineExceeded: - return http.StatusGatewayTimeout - case codes.NotFound: - return http.StatusNotFound - case codes.AlreadyExists: - return http.StatusConflict - case codes.PermissionDenied: - return http.StatusForbidden - case codes.Unauthenticated: - return http.StatusUnauthorized - case codes.ResourceExhausted: - return http.StatusTooManyRequests - case codes.FailedPrecondition: - // Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status. - return http.StatusBadRequest - case codes.Aborted: - return http.StatusConflict - case codes.OutOfRange: - return http.StatusBadRequest - case codes.Unimplemented: - return http.StatusNotImplemented - case codes.Internal: - return http.StatusInternalServerError - case codes.Unavailable: - return http.StatusServiceUnavailable - case codes.DataLoss: - return http.StatusInternalServerError - } - - grpclog.Infof("Unknown gRPC error code: %v", code) - return http.StatusInternalServerError -} - -var ( - // HTTPError replies to the request with an error. - // - // HTTPError is called: - // - From generated per-endpoint gateway handler code, when calling the backend results in an error. - // - From gateway runtime code, when forwarding the response message results in an error. - // - // The default value for HTTPError calls the custom error handler configured on the ServeMux via the - // WithProtoErrorHandler serve option if that option was used, calling GlobalHTTPErrorHandler otherwise. - // - // To customize the error handling of a particular ServeMux instance, use the WithProtoErrorHandler - // serve option. - // - // To customize the error format for all ServeMux instances not using the WithProtoErrorHandler serve - // option, set GlobalHTTPErrorHandler to a custom function. - // - // Setting this variable directly to customize error format is deprecated. - HTTPError = MuxOrGlobalHTTPError - - // GlobalHTTPErrorHandler is the HTTPError handler for all ServeMux instances not using the - // WithProtoErrorHandler serve option. - // - // You can set a custom function to this variable to customize error format. - GlobalHTTPErrorHandler = DefaultHTTPError - - // OtherErrorHandler handles gateway errors from parsing and routing client requests for all - // ServeMux instances not using the WithProtoErrorHandler serve option. - // - // It returns the following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest - // - // To customize parsing and routing error handling of a particular ServeMux instance, use the - // WithProtoErrorHandler serve option. - // - // To customize parsing and routing error handling of all ServeMux instances not using the - // WithProtoErrorHandler serve option, set a custom function to this variable. - OtherErrorHandler = DefaultOtherErrorHandler -) - -// MuxOrGlobalHTTPError uses the mux-configured error handler, falling back to GlobalErrorHandler. -func MuxOrGlobalHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { - if mux.protoErrorHandler != nil { - mux.protoErrorHandler(ctx, mux, marshaler, w, r, err) - } else { - GlobalHTTPErrorHandler(ctx, mux, marshaler, w, r, err) - } -} - -// DefaultHTTPError is the default implementation of HTTPError. -// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. -// If otherwise, it replies with http.StatusInternalServerError. -// -// The response body returned by this function is a JSON object, -// which contains a member whose key is "error" and whose value is err.Error(). -func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { - const fallback = `{"error": "failed to marshal error message"}` - - s, ok := status.FromError(err) - if !ok { - s = status.New(codes.Unknown, err.Error()) - } - - w.Header().Del("Trailer") - w.Header().Del("Transfer-Encoding") - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - pb := s.Proto() - contentType = typeMarshaler.ContentTypeFromMessage(pb) - } - w.Header().Set("Content-Type", contentType) - - body := &internal.Error{ - Error: s.Message(), - Message: s.Message(), - Code: int32(s.Code()), - Details: s.Proto().GetDetails(), - } - - buf, merr := marshaler.Marshal(body) - if merr != nil { - grpclog.Infof("Failed to marshal error message %q: %v", body, merr) - w.WriteHeader(http.StatusInternalServerError) - if _, err := io.WriteString(w, fallback); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - - // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 - // Unless the request includes a TE header field indicating "trailers" - // is acceptable, as described in Section 4.3, a server SHOULD NOT - // generate trailer fields that it believes are necessary for the user - // agent to receive. - var wantsTrailers bool - - if te := r.Header.Get("TE"); strings.Contains(strings.ToLower(te), "trailers") { - wantsTrailers = true - handleForwardResponseTrailerHeader(w, md) - w.Header().Set("Transfer-Encoding", "chunked") - } - - st := HTTPStatusFromCode(s.Code()) - w.WriteHeader(st) - if _, err := w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - if wantsTrailers { - handleForwardResponseTrailer(w, md) - } -} - -// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler. -// It simply writes a string representation of the given error into "w". -func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) { - http.Error(w, msg, code) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go deleted file mode 100644 index aef645e40b9..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go +++ /dev/null @@ -1,89 +0,0 @@ -package runtime - -import ( - "encoding/json" - "io" - "strings" - - descriptor2 "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/protoc-gen-go/descriptor" - "google.golang.org/genproto/protobuf/field_mask" -) - -func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) { - // TODO - should really gate this with a test that the marshaller has used json names - if md != nil { - for _, f := range md.Field { - if f.JsonName != nil && f.Name != nil && *f.JsonName == name { - var subType *descriptor.DescriptorProto - - // If the field has a TypeName then we retrieve the nested type for translating the embedded message names. - if f.TypeName != nil { - typeSplit := strings.Split(*f.TypeName, ".") - typeName := typeSplit[len(typeSplit)-1] - for _, t := range md.NestedType { - if typeName == *t.Name { - subType = t - } - } - } - return *f.Name, subType - } - } - } - return name, nil -} - -// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body. -func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) { - fm := &field_mask.FieldMask{} - var root interface{} - if err := json.NewDecoder(r).Decode(&root); err != nil { - if err == io.EOF { - return fm, nil - } - return nil, err - } - - queue := []fieldMaskPathItem{{node: root, md: md}} - for len(queue) > 0 { - // dequeue an item - item := queue[0] - queue = queue[1:] - - if m, ok := item.node.(map[string]interface{}); ok { - // if the item is an object, then enqueue all of its children - for k, v := range m { - protoName, subMd := translateName(k, item.md) - if subMsg, ok := v.(descriptor2.Message); ok { - _, subMd = descriptor2.ForMessage(subMsg) - } - - var path string - if item.path == "" { - path = protoName - } else { - path = item.path + "." + protoName - } - queue = append(queue, fieldMaskPathItem{path: path, node: v, md: subMd}) - } - } else if len(item.path) > 0 { - // otherwise, it's a leaf node so print its path - fm.Paths = append(fm.Paths, item.path) - } - } - - return fm, nil -} - -// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask -type fieldMaskPathItem struct { - // the list of prior fields leading up to node connected by dots - path string - - // a generic decoded json object the current item to inspect for further path extraction - node interface{} - - // descriptor for parent message - md *descriptor.DescriptorProto -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go deleted file mode 100644 index e6e8f286e12..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go +++ /dev/null @@ -1,212 +0,0 @@ -package runtime - -import ( - "context" - "errors" - "fmt" - "io" - "net/http" - "net/textproto" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/grpclog" -) - -var errEmptyResponse = errors.New("empty response") - -// ForwardResponseStream forwards the stream from gRPC server to REST client. -func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { - f, ok := w.(http.Flusher) - if !ok { - grpclog.Infof("Flush not supported in %T", w) - http.Error(w, "unexpected type of web server", http.StatusInternalServerError) - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - http.Error(w, "unexpected error", http.StatusInternalServerError) - return - } - handleForwardResponseServerMetadata(w, mux, md) - - w.Header().Set("Transfer-Encoding", "chunked") - w.Header().Set("Content-Type", marshaler.ContentType()) - if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - - var delimiter []byte - if d, ok := marshaler.(Delimited); ok { - delimiter = d.Delimiter() - } else { - delimiter = []byte("\n") - } - - var wroteHeader bool - for { - resp, err := recv() - if err == io.EOF { - return - } - if err != nil { - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - - var buf []byte - switch { - case resp == nil: - buf, err = marshaler.Marshal(errorChunk(streamError(ctx, mux.streamErrorHandler, errEmptyResponse))) - default: - result := map[string]interface{}{"result": resp} - if rb, ok := resp.(responseBody); ok { - result["result"] = rb.XXX_ResponseBody() - } - - buf, err = marshaler.Marshal(result) - } - - if err != nil { - grpclog.Infof("Failed to marshal response chunk: %v", err) - handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err) - return - } - if _, err = w.Write(buf); err != nil { - grpclog.Infof("Failed to send response chunk: %v", err) - return - } - wroteHeader = true - if _, err = w.Write(delimiter); err != nil { - grpclog.Infof("Failed to send delimiter chunk: %v", err) - return - } - f.Flush() - } -} - -func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) { - for k, vs := range md.HeaderMD { - if h, ok := mux.outgoingHeaderMatcher(k); ok { - for _, v := range vs { - w.Header().Add(h, v) - } - } - } -} - -func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { - for k := range md.TrailerMD { - tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) - w.Header().Add("Trailer", tKey) - } -} - -func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { - for k, vs := range md.TrailerMD { - tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) - for _, v := range vs { - w.Header().Add(tKey, v) - } - } -} - -// responseBody interface contains method for getting field for marshaling to the response body -// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule` -type responseBody interface { - XXX_ResponseBody() interface{} -} - -// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. -func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - handleForwardResponseTrailerHeader(w, md) - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - contentType = typeMarshaler.ContentTypeFromMessage(resp) - } - w.Header().Set("Content-Type", contentType) - - if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - var buf []byte - var err error - if rb, ok := resp.(responseBody); ok { - buf, err = marshaler.Marshal(rb.XXX_ResponseBody()) - } else { - buf, err = marshaler.Marshal(resp) - } - if err != nil { - grpclog.Infof("Marshal error: %v", err) - HTTPError(ctx, mux, marshaler, w, req, err) - return - } - - if _, err = w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - handleForwardResponseTrailer(w, md) -} - -func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { - if len(opts) == 0 { - return nil - } - for _, opt := range opts { - if err := opt(ctx, w, resp); err != nil { - grpclog.Infof("Error handling ForwardResponseOptions: %v", err) - return err - } - } - return nil -} - -func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) { - serr := streamError(ctx, mux.streamErrorHandler, err) - if !wroteHeader { - w.WriteHeader(int(serr.HttpCode)) - } - buf, merr := marshaler.Marshal(errorChunk(serr)) - if merr != nil { - grpclog.Infof("Failed to marshal an error: %v", merr) - return - } - if _, werr := w.Write(buf); werr != nil { - grpclog.Infof("Failed to notify error to client: %v", werr) - return - } -} - -// streamError returns the payload for the final message in a response stream -// that represents the given err. -func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError { - serr := errHandler(ctx, err) - if serr != nil { - return serr - } - // TODO: log about misbehaving stream error handler? - return DefaultHTTPStreamErrorHandler(ctx, err) -} - -func errorChunk(err *StreamError) map[string]proto.Message { - return map[string]proto.Message{"error": (*internal.StreamError)(err)} -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go deleted file mode 100644 index 525b0338c74..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go +++ /dev/null @@ -1,43 +0,0 @@ -package runtime - -import ( - "google.golang.org/genproto/googleapis/api/httpbody" -) - -// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler -func SetHTTPBodyMarshaler(serveMux *ServeMux) { - serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{ - Marshaler: &JSONPb{OrigName: true}, - } -} - -// HTTPBodyMarshaler is a Marshaler which supports marshaling of a -// google.api.HttpBody message as the full response body if it is -// the actual message used as the response. If not, then this will -// simply fallback to the Marshaler specified as its default Marshaler. -type HTTPBodyMarshaler struct { - Marshaler -} - -// ContentType implementation to keep backwards compatibility with marshal interface -func (h *HTTPBodyMarshaler) ContentType() string { - return h.ContentTypeFromMessage(nil) -} - -// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns -// its specified content type otherwise fall back to the default Marshaler. -func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string { - if httpBody, ok := v.(*httpbody.HttpBody); ok { - return httpBody.GetContentType() - } - return h.Marshaler.ContentType() -} - -// Marshal marshals "v" by returning the body bytes if v is a -// google.api.HttpBody message, otherwise it falls back to the default Marshaler. -func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { - if httpBody, ok := v.(*httpbody.HttpBody); ok { - return httpBody.Data, nil - } - return h.Marshaler.Marshal(v) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go deleted file mode 100644 index f0de351b212..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go +++ /dev/null @@ -1,262 +0,0 @@ -package runtime - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "reflect" - - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/proto" -) - -// JSONPb is a Marshaler which marshals/unmarshals into/from JSON -// with the "github.com/golang/protobuf/jsonpb". -// It supports fully functionality of protobuf unlike JSONBuiltin. -// -// The NewDecoder method returns a DecoderWrapper, so the underlying -// *json.Decoder methods can be used. -type JSONPb jsonpb.Marshaler - -// ContentType always returns "application/json". -func (*JSONPb) ContentType() string { - return "application/json" -} - -// Marshal marshals "v" into JSON. -func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { - if _, ok := v.(proto.Message); !ok { - return j.marshalNonProtoField(v) - } - - var buf bytes.Buffer - if err := j.marshalTo(&buf, v); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { - p, ok := v.(proto.Message) - if !ok { - buf, err := j.marshalNonProtoField(v) - if err != nil { - return err - } - _, err = w.Write(buf) - return err - } - return (*jsonpb.Marshaler)(j).Marshal(w, p) -} - -var ( - // protoMessageType is stored to prevent constant lookup of the same type at runtime. - protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() -) - -// marshalNonProto marshals a non-message field of a protobuf message. -// This function does not correctly marshals arbitrary data structure into JSON, -// but it is only capable of marshaling non-message field values of protobuf, -// i.e. primitive types, enums; pointers to primitives or enums; maps from -// integer/string types to primitives/enums/pointers to messages. -func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { - if v == nil { - return []byte("null"), nil - } - rv := reflect.ValueOf(v) - for rv.Kind() == reflect.Ptr { - if rv.IsNil() { - return []byte("null"), nil - } - rv = rv.Elem() - } - - if rv.Kind() == reflect.Slice { - if rv.IsNil() { - if j.EmitDefaults { - return []byte("[]"), nil - } - return []byte("null"), nil - } - - if rv.Type().Elem().Implements(protoMessageType) { - var buf bytes.Buffer - err := buf.WriteByte('[') - if err != nil { - return nil, err - } - for i := 0; i < rv.Len(); i++ { - if i != 0 { - err = buf.WriteByte(',') - if err != nil { - return nil, err - } - } - if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { - return nil, err - } - } - err = buf.WriteByte(']') - if err != nil { - return nil, err - } - - return buf.Bytes(), nil - } - } - - if rv.Kind() == reflect.Map { - m := make(map[string]*json.RawMessage) - for _, k := range rv.MapKeys() { - buf, err := j.Marshal(rv.MapIndex(k).Interface()) - if err != nil { - return nil, err - } - m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) - } - if j.Indent != "" { - return json.MarshalIndent(m, "", j.Indent) - } - return json.Marshal(m) - } - if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts { - return json.Marshal(enum.String()) - } - return json.Marshal(rv.Interface()) -} - -// Unmarshal unmarshals JSON "data" into "v" -func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { - return unmarshalJSONPb(data, v) -} - -// NewDecoder returns a Decoder which reads JSON stream from "r". -func (j *JSONPb) NewDecoder(r io.Reader) Decoder { - d := json.NewDecoder(r) - return DecoderWrapper{Decoder: d} -} - -// DecoderWrapper is a wrapper around a *json.Decoder that adds -// support for protos to the Decode method. -type DecoderWrapper struct { - *json.Decoder -} - -// Decode wraps the embedded decoder's Decode method to support -// protos using a jsonpb.Unmarshaler. -func (d DecoderWrapper) Decode(v interface{}) error { - return decodeJSONPb(d.Decoder, v) -} - -// NewEncoder returns an Encoder which writes JSON stream into "w". -func (j *JSONPb) NewEncoder(w io.Writer) Encoder { - return EncoderFunc(func(v interface{}) error { - if err := j.marshalTo(w, v); err != nil { - return err - } - // mimic json.Encoder by adding a newline (makes output - // easier to read when it contains multiple encoded items) - _, err := w.Write(j.Delimiter()) - return err - }) -} - -func unmarshalJSONPb(data []byte, v interface{}) error { - d := json.NewDecoder(bytes.NewReader(data)) - return decodeJSONPb(d, v) -} - -func decodeJSONPb(d *json.Decoder, v interface{}) error { - p, ok := v.(proto.Message) - if !ok { - return decodeNonProtoField(d, v) - } - unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields} - return unmarshaler.UnmarshalNext(d, p) -} - -func decodeNonProtoField(d *json.Decoder, v interface{}) error { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return fmt.Errorf("%T is not a pointer", v) - } - for rv.Kind() == reflect.Ptr { - if rv.IsNil() { - rv.Set(reflect.New(rv.Type().Elem())) - } - if rv.Type().ConvertibleTo(typeProtoMessage) { - unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields} - return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message)) - } - rv = rv.Elem() - } - if rv.Kind() == reflect.Map { - if rv.IsNil() { - rv.Set(reflect.MakeMap(rv.Type())) - } - conv, ok := convFromType[rv.Type().Key().Kind()] - if !ok { - return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) - } - - m := make(map[string]*json.RawMessage) - if err := d.Decode(&m); err != nil { - return err - } - for k, v := range m { - result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - bk := result[0] - bv := reflect.New(rv.Type().Elem()) - if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil { - return err - } - rv.SetMapIndex(bk, bv.Elem()) - } - return nil - } - if _, ok := rv.Interface().(protoEnum); ok { - var repr interface{} - if err := d.Decode(&repr); err != nil { - return err - } - switch repr.(type) { - case string: - // TODO(yugui) Should use proto.StructProperties? - return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) - case float64: - rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type())) - return nil - default: - return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) - } - } - return d.Decode(v) -} - -type protoEnum interface { - fmt.Stringer - EnumDescriptor() ([]byte, []int) -} - -var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() - -// Delimiter for newline encoded JSON streams. -func (j *JSONPb) Delimiter() []byte { - return []byte("\n") -} - -// allowUnknownFields helps not to return an error when the destination -// is a struct and the input contains object keys which do not match any -// non-ignored, exported fields in the destination. -var allowUnknownFields = true - -// DisallowUnknownFields enables option in decoder (unmarshaller) to -// return an error when it finds an unknown field. This function must be -// called before using the JSON marshaller. -func DisallowUnknownFields() { - allowUnknownFields = false -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go deleted file mode 100644 index 523a9cb43c9..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go +++ /dev/null @@ -1,300 +0,0 @@ -package runtime - -import ( - "context" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/golang/protobuf/proto" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// A HandlerFunc handles a specific pair of path pattern and HTTP method. -type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) - -// ErrUnknownURI is the error supplied to a custom ProtoErrorHandlerFunc when -// a request is received with a URI path that does not match any registered -// service method. -// -// Since gRPC servers return an "Unimplemented" code for requests with an -// unrecognized URI path, this error also has a gRPC "Unimplemented" code. -var ErrUnknownURI = status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented)) - -// ServeMux is a request multiplexer for grpc-gateway. -// It matches http requests to patterns and invokes the corresponding handler. -type ServeMux struct { - // handlers maps HTTP method to a list of handlers. - handlers map[string][]handler - forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error - marshalers marshalerRegistry - incomingHeaderMatcher HeaderMatcherFunc - outgoingHeaderMatcher HeaderMatcherFunc - metadataAnnotators []func(context.Context, *http.Request) metadata.MD - streamErrorHandler StreamErrorHandlerFunc - protoErrorHandler ProtoErrorHandlerFunc - disablePathLengthFallback bool - lastMatchWins bool -} - -// ServeMuxOption is an option that can be given to a ServeMux on construction. -type ServeMuxOption func(*ServeMux) - -// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. -// -// forwardResponseOption is an option that will be called on the relevant context.Context, -// http.ResponseWriter, and proto.Message before every forwarded response. -// -// The message may be nil in the case where just a header is being sent. -func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) - } -} - -// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters. -// Configuring this will mean the generated swagger output is no longer correct, and it should be -// done with careful consideration. -func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption { - return func(serveMux *ServeMux) { - currentQueryParser = queryParameterParser - } -} - -// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context. -type HeaderMatcherFunc func(string) (string, bool) - -// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header -// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with -// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. -func DefaultHeaderMatcher(key string) (string, bool) { - key = textproto.CanonicalMIMEHeaderKey(key) - if isPermanentHTTPHeader(key) { - return MetadataPrefix + key, true - } else if strings.HasPrefix(key, MetadataHeaderPrefix) { - return key[len(MetadataHeaderPrefix):], true - } - return "", false -} - -// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway. -// -// This matcher will be called with each header in http.Request. If matcher returns true, that header will be -// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. -func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { - return func(mux *ServeMux) { - mux.incomingHeaderMatcher = fn - } -} - -// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. -// -// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be -// passed to http response returned from gateway. To transform the header before passing to response, -// matcher should return modified header. -func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { - return func(mux *ServeMux) { - mux.outgoingHeaderMatcher = fn - } -} - -// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context. -// -// This can be used by services that need to read from http.Request and modify gRPC context. A common use case -// is reading token from cookie and adding it in gRPC context. -func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator) - } -} - -// WithProtoErrorHandler returns a ServeMuxOption for configuring a custom error handler. -// -// This can be used to handle an error as general proto message defined by gRPC. -// When this option is used, the mux uses the configured error handler instead of HTTPError and -// OtherErrorHandler. -func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.protoErrorHandler = fn - } -} - -// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback. -func WithDisablePathLengthFallback() ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.disablePathLengthFallback = true - } -} - -// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream -// error handler, which allows for customizing the error trailer for server-streaming -// calls. -// -// For stream errors that occur before any response has been written, the mux's -// ProtoErrorHandler will be invoked. However, once data has been written, the errors must -// be handled differently: they must be included in the response body. The response body's -// final message will include the error details returned by the stream error handler. -func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.streamErrorHandler = fn - } -} - -// WithLastMatchWins returns a ServeMuxOption that will enable "last -// match wins" behavior, where if multiple path patterns match a -// request path, the last one defined in the .proto file will be used. -func WithLastMatchWins() ServeMuxOption { - return func(serveMux *ServeMux) { - serveMux.lastMatchWins = true - } -} - -// NewServeMux returns a new ServeMux whose internal mapping is empty. -func NewServeMux(opts ...ServeMuxOption) *ServeMux { - serveMux := &ServeMux{ - handlers: make(map[string][]handler), - forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), - marshalers: makeMarshalerMIMERegistry(), - streamErrorHandler: DefaultHTTPStreamErrorHandler, - } - - for _, opt := range opts { - opt(serveMux) - } - - if serveMux.incomingHeaderMatcher == nil { - serveMux.incomingHeaderMatcher = DefaultHeaderMatcher - } - - if serveMux.outgoingHeaderMatcher == nil { - serveMux.outgoingHeaderMatcher = func(key string) (string, bool) { - return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true - } - } - - return serveMux -} - -// Handle associates "h" to the pair of HTTP method and path pattern. -func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { - if s.lastMatchWins { - s.handlers[meth] = append([]handler{handler{pat: pat, h: h}}, s.handlers[meth]...) - } else { - s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h}) - } -} - -// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. -func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - path := r.URL.Path - if !strings.HasPrefix(path, "/") { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest)) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) - } - return - } - - components := strings.Split(path[1:], "/") - l := len(components) - var verb string - if idx := strings.LastIndex(components[l-1], ":"); idx == 0 { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } - return - } else if idx > 0 { - c := components[l-1] - components[l-1], verb = c[:idx], c[idx+1:] - } - - if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { - r.Method = strings.ToUpper(override) - if err := r.ParseForm(); err != nil { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, err.Error()) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) - } - return - } - } - for _, h := range s.handlers[r.Method] { - pathParams, err := h.pat.Match(components, verb) - if err != nil { - continue - } - h.h(w, r, pathParams) - return - } - - // lookup other methods to handle fallback from GET to POST and - // to determine if it is MethodNotAllowed or NotFound. - for m, handlers := range s.handlers { - if m == r.Method { - continue - } - for _, h := range handlers { - pathParams, err := h.pat.Match(components, verb) - if err != nil { - continue - } - // X-HTTP-Method-Override is optional. Always allow fallback to POST. - if s.isPathLengthFallback(r) { - if err := r.ParseForm(); err != nil { - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - sterr := status.Error(codes.InvalidArgument, err.Error()) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) - } else { - OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) - } - return - } - h.h(w, r, pathParams) - return - } - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) - } - return - } - } - - if s.protoErrorHandler != nil { - _, outboundMarshaler := MarshalerForRequest(s, r) - s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI) - } else { - OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) - } -} - -// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. -func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { - return s.forwardResponseOptions -} - -func (s *ServeMux) isPathLengthFallback(r *http.Request) bool { - return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" -} - -type handler struct { - pat Pattern - h HandlerFunc -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go deleted file mode 100644 index 09053695da7..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go +++ /dev/null @@ -1,262 +0,0 @@ -package runtime - -import ( - "errors" - "fmt" - "strings" - - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc/grpclog" -) - -var ( - // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. - ErrNotMatch = errors.New("not match to the path pattern") - // ErrInvalidPattern indicates that the given definition of Pattern is not valid. - ErrInvalidPattern = errors.New("invalid pattern") -) - -type op struct { - code utilities.OpCode - operand int -} - -// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto. -type Pattern struct { - // ops is a list of operations - ops []op - // pool is a constant pool indexed by the operands or vars. - pool []string - // vars is a list of variables names to be bound by this pattern - vars []string - // stacksize is the max depth of the stack - stacksize int - // tailLen is the length of the fixed-size segments after a deep wildcard - tailLen int - // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. - verb string - // assumeColonVerb indicates whether a path suffix after a final - // colon may only be interpreted as a verb. - assumeColonVerb bool -} - -type patternOptions struct { - assumeColonVerb bool -} - -// PatternOpt is an option for creating Patterns. -type PatternOpt func(*patternOptions) - -// NewPattern returns a new Pattern from the given definition values. -// "ops" is a sequence of op codes. "pool" is a constant pool. -// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. -// "version" must be 1 for now. -// It returns an error if the given definition is invalid. -func NewPattern(version int, ops []int, pool []string, verb string, opts ...PatternOpt) (Pattern, error) { - options := patternOptions{ - assumeColonVerb: true, - } - for _, o := range opts { - o(&options) - } - - if version != 1 { - grpclog.Infof("unsupported version: %d", version) - return Pattern{}, ErrInvalidPattern - } - - l := len(ops) - if l%2 != 0 { - grpclog.Infof("odd number of ops codes: %d", l) - return Pattern{}, ErrInvalidPattern - } - - var ( - typedOps []op - stack, maxstack int - tailLen int - pushMSeen bool - vars []string - ) - for i := 0; i < l; i += 2 { - op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush: - if pushMSeen { - tailLen++ - } - stack++ - case utilities.OpPushM: - if pushMSeen { - grpclog.Infof("pushM appears twice") - return Pattern{}, ErrInvalidPattern - } - pushMSeen = true - stack++ - case utilities.OpLitPush: - if op.operand < 0 || len(pool) <= op.operand { - grpclog.Infof("negative literal index: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - if pushMSeen { - tailLen++ - } - stack++ - case utilities.OpConcatN: - if op.operand <= 0 { - grpclog.Infof("negative concat size: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - stack -= op.operand - if stack < 0 { - grpclog.Print("stack underflow") - return Pattern{}, ErrInvalidPattern - } - stack++ - case utilities.OpCapture: - if op.operand < 0 || len(pool) <= op.operand { - grpclog.Infof("variable name index out of bound: %d", op.operand) - return Pattern{}, ErrInvalidPattern - } - v := pool[op.operand] - op.operand = len(vars) - vars = append(vars, v) - stack-- - if stack < 0 { - grpclog.Infof("stack underflow") - return Pattern{}, ErrInvalidPattern - } - default: - grpclog.Infof("invalid opcode: %d", op.code) - return Pattern{}, ErrInvalidPattern - } - - if maxstack < stack { - maxstack = stack - } - typedOps = append(typedOps, op) - } - return Pattern{ - ops: typedOps, - pool: pool, - vars: vars, - stacksize: maxstack, - tailLen: tailLen, - verb: verb, - assumeColonVerb: options.assumeColonVerb, - }, nil -} - -// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. -func MustPattern(p Pattern, err error) Pattern { - if err != nil { - grpclog.Fatalf("Pattern initialization failed: %v", err) - } - return p -} - -// Match examines components if it matches to the Pattern. -// If it matches, the function returns a mapping from field paths to their captured values. -// If otherwise, the function returns an error. -func (p Pattern) Match(components []string, verb string) (map[string]string, error) { - if p.verb != verb { - if p.assumeColonVerb || p.verb != "" { - return nil, ErrNotMatch - } - if len(components) == 0 { - components = []string{":" + verb} - } else { - components = append([]string{}, components...) - components[len(components)-1] += ":" + verb - } - verb = "" - } - - var pos int - stack := make([]string, 0, p.stacksize) - captured := make([]string, len(p.vars)) - l := len(components) - for _, op := range p.ops { - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush, utilities.OpLitPush: - if pos >= l { - return nil, ErrNotMatch - } - c := components[pos] - if op.code == utilities.OpLitPush { - if lit := p.pool[op.operand]; c != lit { - return nil, ErrNotMatch - } - } - stack = append(stack, c) - pos++ - case utilities.OpPushM: - end := len(components) - if end < pos+p.tailLen { - return nil, ErrNotMatch - } - end -= p.tailLen - stack = append(stack, strings.Join(components[pos:end], "/")) - pos = end - case utilities.OpConcatN: - n := op.operand - l := len(stack) - n - stack = append(stack[:l], strings.Join(stack[l:], "/")) - case utilities.OpCapture: - n := len(stack) - 1 - captured[op.operand] = stack[n] - stack = stack[:n] - } - } - if pos < l { - return nil, ErrNotMatch - } - bindings := make(map[string]string) - for i, val := range captured { - bindings[p.vars[i]] = val - } - return bindings, nil -} - -// Verb returns the verb part of the Pattern. -func (p Pattern) Verb() string { return p.verb } - -func (p Pattern) String() string { - var stack []string - for _, op := range p.ops { - switch op.code { - case utilities.OpNop: - continue - case utilities.OpPush: - stack = append(stack, "*") - case utilities.OpLitPush: - stack = append(stack, p.pool[op.operand]) - case utilities.OpPushM: - stack = append(stack, "**") - case utilities.OpConcatN: - n := op.operand - l := len(stack) - n - stack = append(stack[:l], strings.Join(stack[l:], "/")) - case utilities.OpCapture: - n := len(stack) - 1 - stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) - } - } - segs := strings.Join(stack, "/") - if p.verb != "" { - return fmt.Sprintf("/%s:%s", segs, p.verb) - } - return "/" + segs -} - -// AssumeColonVerbOpt indicates whether a path suffix after a final -// colon may only be interpreted as a verb. -func AssumeColonVerbOpt(val bool) PatternOpt { - return PatternOpt(func(o *patternOptions) { - o.assumeColonVerb = val - }) -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go deleted file mode 100644 index 3fd30da22a7..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go +++ /dev/null @@ -1,106 +0,0 @@ -package runtime - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/ptypes/any" - "github.com/grpc-ecosystem/grpc-gateway/internal" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a -// a proto struct used to represent error at the end of a stream. -type StreamErrorHandlerFunc func(context.Context, error) *StreamError - -// StreamError is the payload for the final message in a server stream in the event that the server returns an -// error after a response message has already been sent. -type StreamError internal.StreamError - -// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request. -type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) - -var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler - -// DefaultHTTPProtoErrorHandler is an implementation of HTTPError. -// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. -// If otherwise, it replies with http.StatusInternalServerError. -// -// The response body returned by this function is a Status message marshaled by a Marshaler. -// -// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead. -func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) { - // return Internal when Marshal failed - const fallback = `{"code": 13, "message": "failed to marshal error message"}` - - s, ok := status.FromError(err) - if !ok { - s = status.New(codes.Unknown, err.Error()) - } - - w.Header().Del("Trailer") - - contentType := marshaler.ContentType() - // Check marshaler on run time in order to keep backwards compatibility - // An interface param needs to be added to the ContentType() function on - // the Marshal interface to be able to remove this check - if typeMarshaler, ok := marshaler.(contentTypeMarshaler); ok { - pb := s.Proto() - contentType = typeMarshaler.ContentTypeFromMessage(pb) - } - w.Header().Set("Content-Type", contentType) - - buf, merr := marshaler.Marshal(s.Proto()) - if merr != nil { - grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr) - w.WriteHeader(http.StatusInternalServerError) - if _, err := io.WriteString(w, fallback); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - return - } - - md, ok := ServerMetadataFromContext(ctx) - if !ok { - grpclog.Infof("Failed to extract ServerMetadata from context") - } - - handleForwardResponseServerMetadata(w, mux, md) - handleForwardResponseTrailerHeader(w, md) - st := HTTPStatusFromCode(s.Code()) - w.WriteHeader(st) - if _, err := w.Write(buf); err != nil { - grpclog.Infof("Failed to write response: %v", err) - } - - handleForwardResponseTrailer(w, md) -} - -// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via -// default logic. -// -// It extracts the gRPC status from err if possible. The fields of the status are -// used to populate the returned StreamError, and the HTTP status code is derived -// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a -// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code. -func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError { - grpcCode := codes.Unknown - grpcMessage := err.Error() - var grpcDetails []*any.Any - if s, ok := status.FromError(err); ok { - grpcCode = s.Code() - grpcMessage = s.Message() - grpcDetails = s.Proto().GetDetails() - } - httpCode := HTTPStatusFromCode(grpcCode) - return &StreamError{ - GrpcCode: int32(grpcCode), - HttpCode: int32(httpCode), - Message: grpcMessage, - HttpStatus: http.StatusText(httpCode), - Details: grpcDetails, - } -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go deleted file mode 100644 index ba66842c330..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go +++ /dev/null @@ -1,406 +0,0 @@ -package runtime - -import ( - "encoding/base64" - "fmt" - "net/url" - "reflect" - "regexp" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc/grpclog" -) - -var valuesKeyRegexp = regexp.MustCompile("^(.*)\\[(.*)\\]$") - -var currentQueryParser QueryParameterParser = &defaultQueryParser{} - -// QueryParameterParser defines interface for all query parameter parsers -type QueryParameterParser interface { - Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error -} - -// PopulateQueryParameters parses query parameters -// into "msg" using current query parser -func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { - return currentQueryParser.Parse(msg, values, filter) -} - -type defaultQueryParser struct{} - -// Parse populates "values" into "msg". -// A value is ignored if its key starts with one of the elements in "filter". -func (*defaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { - for key, values := range values { - match := valuesKeyRegexp.FindStringSubmatch(key) - if len(match) == 3 { - key = match[1] - values = append([]string{match[2]}, values...) - } - fieldPath := strings.Split(key, ".") - if filter.HasCommonPrefix(fieldPath) { - continue - } - if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil { - return err - } - } - return nil -} - -// PopulateFieldFromPath sets a value in a nested Protobuf structure. -// It instantiates missing protobuf fields as it goes. -func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { - fieldPath := strings.Split(fieldPathString, ".") - return populateFieldValueFromPath(msg, fieldPath, []string{value}) -} - -func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error { - m := reflect.ValueOf(msg) - if m.Kind() != reflect.Ptr { - return fmt.Errorf("unexpected type %T: %v", msg, msg) - } - var props *proto.Properties - m = m.Elem() - for i, fieldName := range fieldPath { - isLast := i == len(fieldPath)-1 - if !isLast && m.Kind() != reflect.Struct { - return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, ".")) - } - var f reflect.Value - var err error - f, props, err = fieldByProtoName(m, fieldName) - if err != nil { - return err - } else if !f.IsValid() { - grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, ".")) - return nil - } - - switch f.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: - if !isLast { - return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) - } - m = f - case reflect.Slice: - if !isLast { - return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, ".")) - } - // Handle []byte - if f.Type().Elem().Kind() == reflect.Uint8 { - m = f - break - } - return populateRepeatedField(f, values, props) - case reflect.Ptr: - if f.IsNil() { - m = reflect.New(f.Type().Elem()) - f.Set(m.Convert(f.Type())) - } - m = f.Elem() - continue - case reflect.Struct: - m = f - continue - case reflect.Map: - if !isLast { - return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) - } - return populateMapField(f, values, props) - default: - return fmt.Errorf("unexpected type %s in %T", f.Type(), msg) - } - } - switch len(values) { - case 0: - return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, ".")) - case 1: - default: - grpclog.Infof("too many field values: %s", strings.Join(fieldPath, ".")) - } - return populateField(m, values[0], props) -} - -// fieldByProtoName looks up a field whose corresponding protobuf field name is "name". -// "m" must be a struct value. It returns zero reflect.Value if no such field found. -func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) { - props := proto.GetProperties(m.Type()) - - // look up field name in oneof map - for _, op := range props.OneofTypes { - if name == op.Prop.OrigName || name == op.Prop.JSONName { - v := reflect.New(op.Type.Elem()) - field := m.Field(op.Field) - if !field.IsNil() { - return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName) - } - field.Set(v) - return v.Elem().Field(0), op.Prop, nil - } - } - - for _, p := range props.Prop { - if p.OrigName == name { - return m.FieldByName(p.Name), p, nil - } - if p.JSONName == name { - return m.FieldByName(p.Name), p, nil - } - } - return reflect.Value{}, nil, nil -} - -func populateMapField(f reflect.Value, values []string, props *proto.Properties) error { - if len(values) != 2 { - return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name) - } - - key, value := values[0], values[1] - keyType := f.Type().Key() - valueType := f.Type().Elem() - if f.IsNil() { - f.Set(reflect.MakeMap(f.Type())) - } - - keyConv, ok := convFromType[keyType.Kind()] - if !ok { - return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name) - } - valueConv, ok := convFromType[valueType.Kind()] - if !ok { - return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name) - } - - keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)}) - if err := keyV[1].Interface(); err != nil { - return err.(error) - } - valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)}) - if err := valueV[1].Interface(); err != nil { - return err.(error) - } - - f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType)) - - return nil -} - -func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error { - elemType := f.Type().Elem() - - // is the destination field a slice of an enumeration type? - if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { - return populateFieldEnumRepeated(f, values, enumValMap) - } - - conv, ok := convFromType[elemType.Kind()] - if !ok { - return fmt.Errorf("unsupported field type %s", elemType) - } - f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) - for i, v := range values { - result := conv.Call([]reflect.Value{reflect.ValueOf(v)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - f.Index(i).Set(result[0].Convert(f.Index(i).Type())) - } - return nil -} - -func populateField(f reflect.Value, value string, props *proto.Properties) error { - i := f.Addr().Interface() - - // Handle protobuf well known types - var name string - switch m := i.(type) { - case interface{ XXX_WellKnownType() string }: - name = m.XXX_WellKnownType() - case proto.Message: - const wktPrefix = "google.protobuf." - if fullName := proto.MessageName(m); strings.HasPrefix(fullName, wktPrefix) { - name = fullName[len(wktPrefix):] - } - } - switch name { - case "Timestamp": - if value == "null" { - f.FieldByName("Seconds").SetInt(0) - f.FieldByName("Nanos").SetInt(0) - return nil - } - - t, err := time.Parse(time.RFC3339Nano, value) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - f.FieldByName("Seconds").SetInt(int64(t.Unix())) - f.FieldByName("Nanos").SetInt(int64(t.Nanosecond())) - return nil - case "Duration": - if value == "null" { - f.FieldByName("Seconds").SetInt(0) - f.FieldByName("Nanos").SetInt(0) - return nil - } - d, err := time.ParseDuration(value) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - ns := d.Nanoseconds() - s := ns / 1e9 - ns %= 1e9 - f.FieldByName("Seconds").SetInt(s) - f.FieldByName("Nanos").SetInt(ns) - return nil - case "DoubleValue": - fallthrough - case "FloatValue": - float64Val, err := strconv.ParseFloat(value, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetFloat(float64Val) - return nil - case "Int64Value": - fallthrough - case "Int32Value": - int64Val, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetInt(int64Val) - return nil - case "UInt64Value": - fallthrough - case "UInt32Value": - uint64Val, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return fmt.Errorf("bad DoubleValue: %s", value) - } - f.FieldByName("Value").SetUint(uint64Val) - return nil - case "BoolValue": - if value == "true" { - f.FieldByName("Value").SetBool(true) - } else if value == "false" { - f.FieldByName("Value").SetBool(false) - } else { - return fmt.Errorf("bad BoolValue: %s", value) - } - return nil - case "StringValue": - f.FieldByName("Value").SetString(value) - return nil - case "BytesValue": - bytesVal, err := base64.StdEncoding.DecodeString(value) - if err != nil { - return fmt.Errorf("bad BytesValue: %s", value) - } - f.FieldByName("Value").SetBytes(bytesVal) - return nil - case "FieldMask": - p := f.FieldByName("Paths") - for _, v := range strings.Split(value, ",") { - if v != "" { - p.Set(reflect.Append(p, reflect.ValueOf(v))) - } - } - return nil - } - - // Handle Time and Duration stdlib types - switch t := i.(type) { - case *time.Time: - pt, err := time.Parse(time.RFC3339Nano, value) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - *t = pt - return nil - case *time.Duration: - d, err := time.ParseDuration(value) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - *t = d - return nil - } - - // is the destination field an enumeration type? - if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { - return populateFieldEnum(f, value, enumValMap) - } - - conv, ok := convFromType[f.Kind()] - if !ok { - return fmt.Errorf("field type %T is not supported in query parameters", i) - } - result := conv.Call([]reflect.Value{reflect.ValueOf(value)}) - if err := result[1].Interface(); err != nil { - return err.(error) - } - f.Set(result[0].Convert(f.Type())) - return nil -} - -func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) { - // see if it's an enumeration string - if enumVal, ok := enumValMap[value]; ok { - return reflect.ValueOf(enumVal).Convert(t), nil - } - - // check for an integer that matches an enumeration value - eVal, err := strconv.Atoi(value) - if err != nil { - return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) - } - for _, v := range enumValMap { - if v == int32(eVal) { - return reflect.ValueOf(eVal).Convert(t), nil - } - } - return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) -} - -func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error { - cval, err := convertEnum(value, f.Type(), enumValMap) - if err != nil { - return err - } - f.Set(cval) - return nil -} - -func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error { - elemType := f.Type().Elem() - f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) - for i, v := range values { - result, err := convertEnum(v, elemType, enumValMap) - if err != nil { - return err - } - f.Index(i).Set(result) - } - return nil -} - -var ( - convFromType = map[reflect.Kind]reflect.Value{ - reflect.String: reflect.ValueOf(String), - reflect.Bool: reflect.ValueOf(Bool), - reflect.Float64: reflect.ValueOf(Float64), - reflect.Float32: reflect.ValueOf(Float32), - reflect.Int64: reflect.ValueOf(Int64), - reflect.Int32: reflect.ValueOf(Int32), - reflect.Uint64: reflect.ValueOf(Uint64), - reflect.Uint32: reflect.ValueOf(Uint32), - reflect.Slice: reflect.ValueOf(Bytes), - } -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel deleted file mode 100644 index 7109d793231..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -package(default_visibility = ["//visibility:public"]) - -go_library( - name = "go_default_library", - srcs = [ - "doc.go", - "pattern.go", - "readerfactory.go", - "trie.go", - ], - importpath = "github.com/grpc-ecosystem/grpc-gateway/utilities", -) - -go_test( - name = "go_default_test", - size = "small", - srcs = ["trie_test.go"], - embed = [":go_default_library"], -) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go deleted file mode 100644 index c2b7b30dd91..00000000000 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go +++ /dev/null @@ -1,177 +0,0 @@ -package utilities - -import ( - "sort" -) - -// DoubleArray is a Double Array implementation of trie on sequences of strings. -type DoubleArray struct { - // Encoding keeps an encoding from string to int - Encoding map[string]int - // Base is the base array of Double Array - Base []int - // Check is the check array of Double Array - Check []int -} - -// NewDoubleArray builds a DoubleArray from a set of sequences of strings. -func NewDoubleArray(seqs [][]string) *DoubleArray { - da := &DoubleArray{Encoding: make(map[string]int)} - if len(seqs) == 0 { - return da - } - - encoded := registerTokens(da, seqs) - sort.Sort(byLex(encoded)) - - root := node{row: -1, col: -1, left: 0, right: len(encoded)} - addSeqs(da, encoded, 0, root) - - for i := len(da.Base); i > 0; i-- { - if da.Check[i-1] != 0 { - da.Base = da.Base[:i] - da.Check = da.Check[:i] - break - } - } - return da -} - -func registerTokens(da *DoubleArray, seqs [][]string) [][]int { - var result [][]int - for _, seq := range seqs { - var encoded []int - for _, token := range seq { - if _, ok := da.Encoding[token]; !ok { - da.Encoding[token] = len(da.Encoding) - } - encoded = append(encoded, da.Encoding[token]) - } - result = append(result, encoded) - } - for i := range result { - result[i] = append(result[i], len(da.Encoding)) - } - return result -} - -type node struct { - row, col int - left, right int -} - -func (n node) value(seqs [][]int) int { - return seqs[n.row][n.col] -} - -func (n node) children(seqs [][]int) []*node { - var result []*node - lastVal := int(-1) - last := new(node) - for i := n.left; i < n.right; i++ { - if lastVal == seqs[i][n.col+1] { - continue - } - last.right = i - last = &node{ - row: i, - col: n.col + 1, - left: i, - } - result = append(result, last) - } - last.right = n.right - return result -} - -func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) { - ensureSize(da, pos) - - children := n.children(seqs) - var i int - for i = 1; ; i++ { - ok := func() bool { - for _, child := range children { - code := child.value(seqs) - j := i + code - ensureSize(da, j) - if da.Check[j] != 0 { - return false - } - } - return true - }() - if ok { - break - } - } - da.Base[pos] = i - for _, child := range children { - code := child.value(seqs) - j := i + code - da.Check[j] = pos + 1 - } - terminator := len(da.Encoding) - for _, child := range children { - code := child.value(seqs) - if code == terminator { - continue - } - j := i + code - addSeqs(da, seqs, j, *child) - } -} - -func ensureSize(da *DoubleArray, i int) { - for i >= len(da.Base) { - da.Base = append(da.Base, make([]int, len(da.Base)+1)...) - da.Check = append(da.Check, make([]int, len(da.Check)+1)...) - } -} - -type byLex [][]int - -func (l byLex) Len() int { return len(l) } -func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l byLex) Less(i, j int) bool { - si := l[i] - sj := l[j] - var k int - for k = 0; k < len(si) && k < len(sj); k++ { - if si[k] < sj[k] { - return true - } - if si[k] > sj[k] { - return false - } - } - if k < len(sj) { - return true - } - return false -} - -// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence. -func (da *DoubleArray) HasCommonPrefix(seq []string) bool { - if len(da.Base) == 0 { - return false - } - - var i int - for _, t := range seq { - code, ok := da.Encoding[t] - if !ok { - break - } - j := da.Base[i] + code - if len(da.Check) <= j || da.Check[j] != i+1 { - break - } - i = j - } - j := da.Base[i] + len(da.Encoding) - if len(da.Check) <= j || da.Check[j] != i+1 { - return false - } - return true -} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE.txt similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE.txt diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel new file mode 100644 index 00000000000..f694f3c0d03 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "httprule", + srcs = [ + "compile.go", + "parse.go", + "types.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule", + deps = ["//utilities"], +) + +go_test( + name = "httprule_test", + size = "small", + srcs = [ + "compile_test.go", + "parse_test.go", + "types_test.go", + ], + embed = [":httprule"], + deps = [ + "//utilities", + "@com_github_golang_glog//:glog", + ], +) + +alias( + name = "go_default_library", + actual = ":httprule", + visibility = ["//:__subpackages__"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go new file mode 100644 index 00000000000..3cd9372959d --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go @@ -0,0 +1,121 @@ +package httprule + +import ( + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" +) + +const ( + opcodeVersion = 1 +) + +// Template is a compiled representation of path templates. +type Template struct { + // Version is the version number of the format. + Version int + // OpCodes is a sequence of operations. + OpCodes []int + // Pool is a constant pool + Pool []string + // Verb is a VERB part in the template. + Verb string + // Fields is a list of field paths bound in this template. + Fields []string + // Original template (example: /v1/a_bit_of_everything) + Template string +} + +// Compiler compiles utilities representation of path templates into marshallable operations. +// They can be unmarshalled by runtime.NewPattern. +type Compiler interface { + Compile() Template +} + +type op struct { + // code is the opcode of the operation + code utilities.OpCode + + // str is a string operand of the code. + // num is ignored if str is not empty. + str string + + // num is a numeric operand of the code. + num int +} + +func (w wildcard) compile() []op { + return []op{ + {code: utilities.OpPush}, + } +} + +func (w deepWildcard) compile() []op { + return []op{ + {code: utilities.OpPushM}, + } +} + +func (l literal) compile() []op { + return []op{ + { + code: utilities.OpLitPush, + str: string(l), + }, + } +} + +func (v variable) compile() []op { + var ops []op + for _, s := range v.segments { + ops = append(ops, s.compile()...) + } + ops = append(ops, op{ + code: utilities.OpConcatN, + num: len(v.segments), + }, op{ + code: utilities.OpCapture, + str: v.path, + }) + + return ops +} + +func (t template) Compile() Template { + var rawOps []op + for _, s := range t.segments { + rawOps = append(rawOps, s.compile()...) + } + + var ( + ops []int + pool []string + fields []string + ) + consts := make(map[string]int) + for _, op := range rawOps { + ops = append(ops, int(op.code)) + if op.str == "" { + ops = append(ops, op.num) + } else { + // eof segment literal represents the "/" path pattern + if op.str == eof { + op.str = "" + } + if _, ok := consts[op.str]; !ok { + consts[op.str] = len(pool) + pool = append(pool, op.str) + } + ops = append(ops, consts[op.str]) + } + if op.code == utilities.OpCapture { + fields = append(fields, op.str) + } + } + return Template{ + Version: opcodeVersion, + OpCodes: ops, + Pool: pool, + Verb: t.verb, + Fields: fields, + Template: t.template, + } +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go new file mode 100644 index 00000000000..c056bd3058a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go @@ -0,0 +1,11 @@ +//go:build gofuzz +// +build gofuzz + +package httprule + +func Fuzz(data []byte) int { + if _, err := Parse(string(data)); err != nil { + return 0 + } + return 0 +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go new file mode 100644 index 00000000000..65ffcf5cf87 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go @@ -0,0 +1,368 @@ +package httprule + +import ( + "errors" + "fmt" + "strings" +) + +// InvalidTemplateError indicates that the path template is not valid. +type InvalidTemplateError struct { + tmpl string + msg string +} + +func (e InvalidTemplateError) Error() string { + return fmt.Sprintf("%s: %s", e.msg, e.tmpl) +} + +// Parse parses the string representation of path template +func Parse(tmpl string) (Compiler, error) { + if !strings.HasPrefix(tmpl, "/") { + return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"} + } + tokens, verb := tokenize(tmpl[1:]) + + p := parser{tokens: tokens} + segs, err := p.topLevelSegments() + if err != nil { + return template{}, InvalidTemplateError{tmpl: tmpl, msg: err.Error()} + } + + return template{ + segments: segs, + verb: verb, + template: tmpl, + }, nil +} + +func tokenize(path string) (tokens []string, verb string) { + if path == "" { + return []string{eof}, "" + } + + const ( + init = iota + field + nested + ) + st := init + for path != "" { + var idx int + switch st { + case init: + idx = strings.IndexAny(path, "/{") + case field: + idx = strings.IndexAny(path, ".=}") + case nested: + idx = strings.IndexAny(path, "/}") + } + if idx < 0 { + tokens = append(tokens, path) + break + } + switch r := path[idx]; r { + case '/', '.': + case '{': + st = field + case '=': + st = nested + case '}': + st = init + } + if idx == 0 { + tokens = append(tokens, path[idx:idx+1]) + } else { + tokens = append(tokens, path[:idx], path[idx:idx+1]) + } + path = path[idx+1:] + } + + l := len(tokens) + // See + // https://github.com/grpc-ecosystem/grpc-gateway/pull/1947#issuecomment-774523693 ; + // although normal and backwards-compat logic here is to use the last index + // of a colon, if the final segment is a variable followed by a colon, the + // part following the colon must be a verb. Hence if the previous token is + // an end var marker, we switch the index we're looking for to Index instead + // of LastIndex, so that we correctly grab the remaining part of the path as + // the verb. + var penultimateTokenIsEndVar bool + switch l { + case 0, 1: + // Not enough to be variable so skip this logic and don't result in an + // invalid index + default: + penultimateTokenIsEndVar = tokens[l-2] == "}" + } + t := tokens[l-1] + var idx int + if penultimateTokenIsEndVar { + idx = strings.Index(t, ":") + } else { + idx = strings.LastIndex(t, ":") + } + if idx == 0 { + tokens, verb = tokens[:l-1], t[1:] + } else if idx > 0 { + tokens[l-1], verb = t[:idx], t[idx+1:] + } + tokens = append(tokens, eof) + return tokens, verb +} + +// parser is a parser of the template syntax defined in github.com/googleapis/googleapis/google/api/http.proto. +type parser struct { + tokens []string + accepted []string +} + +// topLevelSegments is the target of this parser. +func (p *parser) topLevelSegments() ([]segment, error) { + if _, err := p.accept(typeEOF); err == nil { + p.tokens = p.tokens[:0] + return []segment{literal(eof)}, nil + } + segs, err := p.segments() + if err != nil { + return nil, err + } + if _, err := p.accept(typeEOF); err != nil { + return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, "")) + } + return segs, nil +} + +func (p *parser) segments() ([]segment, error) { + s, err := p.segment() + if err != nil { + return nil, err + } + + segs := []segment{s} + for { + if _, err := p.accept("/"); err != nil { + return segs, nil + } + s, err := p.segment() + if err != nil { + return segs, err + } + segs = append(segs, s) + } +} + +func (p *parser) segment() (segment, error) { + if _, err := p.accept("*"); err == nil { + return wildcard{}, nil + } + if _, err := p.accept("**"); err == nil { + return deepWildcard{}, nil + } + if l, err := p.literal(); err == nil { + return l, nil + } + + v, err := p.variable() + if err != nil { + return nil, fmt.Errorf("segment neither wildcards, literal or variable: %w", err) + } + return v, nil +} + +func (p *parser) literal() (segment, error) { + lit, err := p.accept(typeLiteral) + if err != nil { + return nil, err + } + return literal(lit), nil +} + +func (p *parser) variable() (segment, error) { + if _, err := p.accept("{"); err != nil { + return nil, err + } + + path, err := p.fieldPath() + if err != nil { + return nil, err + } + + var segs []segment + if _, err := p.accept("="); err == nil { + segs, err = p.segments() + if err != nil { + return nil, fmt.Errorf("invalid segment in variable %q: %w", path, err) + } + } else { + segs = []segment{wildcard{}} + } + + if _, err := p.accept("}"); err != nil { + return nil, fmt.Errorf("unterminated variable segment: %s", path) + } + return variable{ + path: path, + segments: segs, + }, nil +} + +func (p *parser) fieldPath() (string, error) { + c, err := p.accept(typeIdent) + if err != nil { + return "", err + } + components := []string{c} + for { + if _, err := p.accept("."); err != nil { + return strings.Join(components, "."), nil + } + c, err := p.accept(typeIdent) + if err != nil { + return "", fmt.Errorf("invalid field path component: %w", err) + } + components = append(components, c) + } +} + +// A termType is a type of terminal symbols. +type termType string + +// These constants define some of valid values of termType. +// They improve readability of parse functions. +// +// You can also use "/", "*", "**", "." or "=" as valid values. +const ( + typeIdent = termType("ident") + typeLiteral = termType("literal") + typeEOF = termType("$") +) + +// eof is the terminal symbol which always appears at the end of token sequence. +const eof = "\u0000" + +// accept tries to accept a token in "p". +// This function consumes a token and returns it if it matches to the specified "term". +// If it doesn't match, the function does not consume any tokens and return an error. +func (p *parser) accept(term termType) (string, error) { + t := p.tokens[0] + switch term { + case "/", "*", "**", ".", "=", "{", "}": + if t != string(term) && t != "/" { + return "", fmt.Errorf("expected %q but got %q", term, t) + } + case typeEOF: + if t != eof { + return "", fmt.Errorf("expected EOF but got %q", t) + } + case typeIdent: + if err := expectIdent(t); err != nil { + return "", err + } + case typeLiteral: + if err := expectPChars(t); err != nil { + return "", err + } + default: + return "", fmt.Errorf("unknown termType %q", term) + } + p.tokens = p.tokens[1:] + p.accepted = append(p.accepted, t) + return t, nil +} + +// expectPChars determines if "t" consists of only pchars defined in RFC3986. +// +// https://www.ietf.org/rfc/rfc3986.txt, P.49 +// +// pchar = unreserved / pct-encoded / sub-delims / ":" / "@" +// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" +// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" +// / "*" / "+" / "," / ";" / "=" +// pct-encoded = "%" HEXDIG HEXDIG +func expectPChars(t string) error { + const ( + init = iota + pct1 + pct2 + ) + st := init + for _, r := range t { + if st != init { + if !isHexDigit(r) { + return fmt.Errorf("invalid hexdigit: %c(%U)", r, r) + } + switch st { + case pct1: + st = pct2 + case pct2: + st = init + } + continue + } + + // unreserved + switch { + case 'A' <= r && r <= 'Z': + continue + case 'a' <= r && r <= 'z': + continue + case '0' <= r && r <= '9': + continue + } + switch r { + case '-', '.', '_', '~': + // unreserved + case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': + // sub-delims + case ':', '@': + // rest of pchar + case '%': + // pct-encoded + st = pct1 + default: + return fmt.Errorf("invalid character in path segment: %q(%U)", r, r) + } + } + if st != init { + return fmt.Errorf("invalid percent-encoding in %q", t) + } + return nil +} + +// expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*). +func expectIdent(ident string) error { + if ident == "" { + return errors.New("empty identifier") + } + for pos, r := range ident { + switch { + case '0' <= r && r <= '9': + if pos == 0 { + return fmt.Errorf("identifier starting with digit: %s", ident) + } + continue + case 'A' <= r && r <= 'Z': + continue + case 'a' <= r && r <= 'z': + continue + case r == '_': + continue + default: + return fmt.Errorf("invalid character %q(%U) in identifier: %s", r, r, ident) + } + } + return nil +} + +func isHexDigit(r rune) bool { + switch { + case '0' <= r && r <= '9': + return true + case 'A' <= r && r <= 'F': + return true + case 'a' <= r && r <= 'f': + return true + } + return false +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go new file mode 100644 index 00000000000..5a814a0004c --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go @@ -0,0 +1,60 @@ +package httprule + +import ( + "fmt" + "strings" +) + +type template struct { + segments []segment + verb string + template string +} + +type segment interface { + fmt.Stringer + compile() (ops []op) +} + +type wildcard struct{} + +type deepWildcard struct{} + +type literal string + +type variable struct { + path string + segments []segment +} + +func (wildcard) String() string { + return "*" +} + +func (deepWildcard) String() string { + return "**" +} + +func (l literal) String() string { + return string(l) +} + +func (v variable) String() string { + var segs []string + for _, s := range v.segments { + segs = append(segs, s.String()) + } + return fmt.Sprintf("{%s=%s}", v.path, strings.Join(segs, "/")) +} + +func (t template) String() string { + var segs []string + for _, s := range t.segments { + segs = append(segs, s.String()) + } + str := strings.Join(segs, "/") + if t.verb != "" { + str = fmt.Sprintf("%s:%s", str, t.verb) + } + return "/" + str +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel new file mode 100644 index 00000000000..a8789f17022 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel @@ -0,0 +1,97 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "runtime", + srcs = [ + "context.go", + "convert.go", + "doc.go", + "errors.go", + "fieldmask.go", + "handler.go", + "marshal_httpbodyproto.go", + "marshal_json.go", + "marshal_jsonpb.go", + "marshal_proto.go", + "marshaler.go", + "marshaler_registry.go", + "mux.go", + "pattern.go", + "proto2_convert.go", + "query.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/runtime", + deps = [ + "//internal/httprule", + "//utilities", + "@go_googleapis//google/api:httpbody_go_proto", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//grpclog", + "@org_golang_google_grpc//health/grpc_health_v1", + "@org_golang_google_grpc//metadata", + "@org_golang_google_grpc//status", + "@org_golang_google_protobuf//encoding/protojson", + "@org_golang_google_protobuf//proto", + "@org_golang_google_protobuf//reflect/protoreflect", + "@org_golang_google_protobuf//reflect/protoregistry", + "@org_golang_google_protobuf//types/known/durationpb", + "@org_golang_google_protobuf//types/known/fieldmaskpb", + "@org_golang_google_protobuf//types/known/structpb", + "@org_golang_google_protobuf//types/known/timestamppb", + "@org_golang_google_protobuf//types/known/wrapperspb", + ], +) + +go_test( + name = "runtime_test", + size = "small", + srcs = [ + "context_test.go", + "convert_test.go", + "errors_test.go", + "fieldmask_test.go", + "handler_test.go", + "marshal_httpbodyproto_test.go", + "marshal_json_test.go", + "marshal_jsonpb_test.go", + "marshal_proto_test.go", + "marshaler_registry_test.go", + "mux_internal_test.go", + "mux_test.go", + "pattern_test.go", + "query_fuzz_test.go", + "query_test.go", + ], + embed = [":runtime"], + deps = [ + "//runtime/internal/examplepb", + "//utilities", + "@com_github_google_go_cmp//cmp", + "@com_github_google_go_cmp//cmp/cmpopts", + "@go_googleapis//google/api:httpbody_go_proto", + "@go_googleapis//google/rpc:errdetails_go_proto", + "@go_googleapis//google/rpc:status_go_proto", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//health/grpc_health_v1", + "@org_golang_google_grpc//metadata", + "@org_golang_google_grpc//status", + "@org_golang_google_protobuf//encoding/protojson", + "@org_golang_google_protobuf//proto", + "@org_golang_google_protobuf//testing/protocmp", + "@org_golang_google_protobuf//types/known/durationpb", + "@org_golang_google_protobuf//types/known/emptypb", + "@org_golang_google_protobuf//types/known/fieldmaskpb", + "@org_golang_google_protobuf//types/known/structpb", + "@org_golang_google_protobuf//types/known/timestamppb", + "@org_golang_google_protobuf//types/known/wrapperspb", + ], +) + +alias( + name = "go_default_library", + actual = ":runtime", + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go new file mode 100644 index 00000000000..31553e7848a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go @@ -0,0 +1,401 @@ +package runtime + +import ( + "context" + "encoding/base64" + "fmt" + "net" + "net/http" + "net/textproto" + "strconv" + "strings" + "sync" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// MetadataHeaderPrefix is the http prefix that represents custom metadata +// parameters to or from a gRPC call. +const MetadataHeaderPrefix = "Grpc-Metadata-" + +// MetadataPrefix is prepended to permanent HTTP header keys (as specified +// by the IANA) when added to the gRPC context. +const MetadataPrefix = "grpcgateway-" + +// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to +// HTTP headers in a response handled by grpc-gateway +const MetadataTrailerPrefix = "Grpc-Trailer-" + +const metadataGrpcTimeout = "Grpc-Timeout" +const metadataHeaderBinarySuffix = "-Bin" + +const xForwardedFor = "X-Forwarded-For" +const xForwardedHost = "X-Forwarded-Host" + +// DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound +// header isn't present. If the value is 0 the sent `context` will not have a timeout. +var DefaultContextTimeout = 0 * time.Second + +// malformedHTTPHeaders lists the headers that the gRPC server may reject outright as malformed. +// See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more context. +var malformedHTTPHeaders = map[string]struct{}{ + "connection": {}, +} + +type ( + rpcMethodKey struct{} + httpPathPatternKey struct{} + + AnnotateContextOption func(ctx context.Context) context.Context +) + +func WithHTTPPathPattern(pattern string) AnnotateContextOption { + return func(ctx context.Context) context.Context { + return withHTTPPathPattern(ctx, pattern) + } +} + +func decodeBinHeader(v string) ([]byte, error) { + if len(v)%4 == 0 { + // Input was padded, or padding was not necessary. + return base64.StdEncoding.DecodeString(v) + } + return base64.RawStdEncoding.DecodeString(v) +} + +/* +AnnotateContext adds context information such as metadata from the request. + +At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", +except that the forwarded destination is not another HTTP service but rather +a gRPC service. +*/ +func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) { + ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...) + if err != nil { + return nil, err + } + if md == nil { + return ctx, nil + } + + return metadata.NewOutgoingContext(ctx, md), nil +} + +// AnnotateIncomingContext adds context information such as metadata from the request. +// Attach metadata as incoming context. +func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) { + ctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...) + if err != nil { + return nil, err + } + if md == nil { + return ctx, nil + } + + return metadata.NewIncomingContext(ctx, md), nil +} + +func isValidGRPCMetadataKey(key string) bool { + // Must be a valid gRPC "Header-Name" as defined here: + // https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md + // This means 0-9 a-z _ - . + // Only lowercase letters are valid in the wire protocol, but the client library will normalize + // uppercase ASCII to lowercase, so uppercase ASCII is also acceptable. + bytes := []byte(key) // gRPC validates strings on the byte level, not Unicode. + for _, ch := range bytes { + validLowercaseLetter := ch >= 'a' && ch <= 'z' + validUppercaseLetter := ch >= 'A' && ch <= 'Z' + validDigit := ch >= '0' && ch <= '9' + validOther := ch == '.' || ch == '-' || ch == '_' + if !validLowercaseLetter && !validUppercaseLetter && !validDigit && !validOther { + return false + } + } + return true +} + +func isValidGRPCMetadataTextValue(textValue string) bool { + // Must be a valid gRPC "ASCII-Value" as defined here: + // https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md + // This means printable ASCII (including/plus spaces); 0x20 to 0x7E inclusive. + bytes := []byte(textValue) // gRPC validates strings on the byte level, not Unicode. + for _, ch := range bytes { + if ch < 0x20 || ch > 0x7E { + return false + } + } + return true +} + +func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) { + ctx = withRPCMethod(ctx, rpcMethodName) + for _, o := range options { + ctx = o(ctx) + } + timeout := DefaultContextTimeout + if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { + var err error + timeout, err = timeoutDecode(tm) + if err != nil { + return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) + } + } + var pairs []string + for key, vals := range req.Header { + key = textproto.CanonicalMIMEHeaderKey(key) + for _, val := range vals { + // For backwards-compatibility, pass through 'authorization' header with no prefix. + if key == "Authorization" { + pairs = append(pairs, "authorization", val) + } + if h, ok := mux.incomingHeaderMatcher(key); ok { + if !isValidGRPCMetadataKey(h) { + grpclog.Errorf("HTTP header name %q is not valid as gRPC metadata key; skipping", h) + continue + } + // Handles "-bin" metadata in grpc, since grpc will do another base64 + // encode before sending to server, we need to decode it first. + if strings.HasSuffix(key, metadataHeaderBinarySuffix) { + b, err := decodeBinHeader(val) + if err != nil { + return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err) + } + + val = string(b) + } else if !isValidGRPCMetadataTextValue(val) { + grpclog.Errorf("Value of HTTP header %q contains non-ASCII value (not valid as gRPC metadata): skipping", h) + continue + } + pairs = append(pairs, h, val) + } + } + } + if host := req.Header.Get(xForwardedHost); host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), host) + } else if req.Host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) + } + + if addr := req.RemoteAddr; addr != "" { + if remoteIP, _, err := net.SplitHostPort(addr); err == nil { + if fwd := req.Header.Get(xForwardedFor); fwd == "" { + pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) + } else { + pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) + } + } + } + + if timeout != 0 { + //nolint:govet // The context outlives this function + ctx, _ = context.WithTimeout(ctx, timeout) + } + if len(pairs) == 0 { + return ctx, nil, nil + } + md := metadata.Pairs(pairs...) + for _, mda := range mux.metadataAnnotators { + md = metadata.Join(md, mda(ctx, req)) + } + return ctx, md, nil +} + +// ServerMetadata consists of metadata sent from gRPC server. +type ServerMetadata struct { + HeaderMD metadata.MD + TrailerMD metadata.MD +} + +type serverMetadataKey struct{} + +// NewServerMetadataContext creates a new context with ServerMetadata +func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { + if ctx == nil { + ctx = context.Background() + } + return context.WithValue(ctx, serverMetadataKey{}, md) +} + +// ServerMetadataFromContext returns the ServerMetadata in ctx +func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { + if ctx == nil { + return md, false + } + md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) + return +} + +// ServerTransportStream implements grpc.ServerTransportStream. +// It should only be used by the generated files to support grpc.SendHeader +// outside of gRPC server use. +type ServerTransportStream struct { + mu sync.Mutex + header metadata.MD + trailer metadata.MD +} + +// Method returns the method for the stream. +func (s *ServerTransportStream) Method() string { + return "" +} + +// Header returns the header metadata of the stream. +func (s *ServerTransportStream) Header() metadata.MD { + s.mu.Lock() + defer s.mu.Unlock() + return s.header.Copy() +} + +// SetHeader sets the header metadata. +func (s *ServerTransportStream) SetHeader(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + + s.mu.Lock() + s.header = metadata.Join(s.header, md) + s.mu.Unlock() + return nil +} + +// SendHeader sets the header metadata. +func (s *ServerTransportStream) SendHeader(md metadata.MD) error { + return s.SetHeader(md) +} + +// Trailer returns the cached trailer metadata. +func (s *ServerTransportStream) Trailer() metadata.MD { + s.mu.Lock() + defer s.mu.Unlock() + return s.trailer.Copy() +} + +// SetTrailer sets the trailer metadata. +func (s *ServerTransportStream) SetTrailer(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + + s.mu.Lock() + s.trailer = metadata.Join(s.trailer, md) + s.mu.Unlock() + return nil +} + +func timeoutDecode(s string) (time.Duration, error) { + size := len(s) + if size < 2 { + return 0, fmt.Errorf("timeout string is too short: %q", s) + } + d, ok := timeoutUnitToDuration(s[size-1]) + if !ok { + return 0, fmt.Errorf("timeout unit is not recognized: %q", s) + } + t, err := strconv.ParseInt(s[:size-1], 10, 64) + if err != nil { + return 0, err + } + return d * time.Duration(t), nil +} + +func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { + switch u { + case 'H': + return time.Hour, true + case 'M': + return time.Minute, true + case 'S': + return time.Second, true + case 'm': + return time.Millisecond, true + case 'u': + return time.Microsecond, true + case 'n': + return time.Nanosecond, true + default: + return + } +} + +// isPermanentHTTPHeader checks whether hdr belongs to the list of +// permanent request headers maintained by IANA. +// http://www.iana.org/assignments/message-headers/message-headers.xml +func isPermanentHTTPHeader(hdr string) bool { + switch hdr { + case + "Accept", + "Accept-Charset", + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Cache-Control", + "Content-Type", + "Cookie", + "Date", + "Expect", + "From", + "Host", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Schedule-Tag-Match", + "If-Unmodified-Since", + "Max-Forwards", + "Origin", + "Pragma", + "Referer", + "User-Agent", + "Via", + "Warning": + return true + } + return false +} + +// isMalformedHTTPHeader checks whether header belongs to the list of +// "malformed headers" and would be rejected by the gRPC server. +func isMalformedHTTPHeader(header string) bool { + _, isMalformed := malformedHTTPHeaders[strings.ToLower(header)] + return isMalformed +} + +// RPCMethod returns the method string for the server context. The returned +// string is in the format of "/package.service/method". +func RPCMethod(ctx context.Context) (string, bool) { + m := ctx.Value(rpcMethodKey{}) + if m == nil { + return "", false + } + ms, ok := m.(string) + if !ok { + return "", false + } + return ms, true +} + +func withRPCMethod(ctx context.Context, rpcMethodName string) context.Context { + return context.WithValue(ctx, rpcMethodKey{}, rpcMethodName) +} + +// HTTPPathPattern returns the HTTP path pattern string relating to the HTTP handler, if one exists. +// The format of the returned string is defined by the google.api.http path template type. +func HTTPPathPattern(ctx context.Context) (string, bool) { + m := ctx.Value(httpPathPatternKey{}) + if m == nil { + return "", false + } + ms, ok := m.(string) + if !ok { + return "", false + } + return ms, true +} + +func withHTTPPathPattern(ctx context.Context, httpPathPattern string) context.Context { + return context.WithValue(ctx, httpPathPatternKey{}, httpPathPattern) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go similarity index 78% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go index 2c279344dc4..d7b15fcfb3f 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go @@ -6,10 +6,10 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/ptypes/duration" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" ) // String just returns the given string. @@ -37,7 +37,7 @@ func BoolSlice(val, sep string) ([]bool, error) { for i, v := range s { value, err := Bool(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -57,7 +57,7 @@ func Float64Slice(val, sep string) ([]float64, error) { for i, v := range s { value, err := Float64(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -81,7 +81,7 @@ func Float32Slice(val, sep string) ([]float32, error) { for i, v := range s { value, err := Float32(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -101,7 +101,7 @@ func Int64Slice(val, sep string) ([]int64, error) { for i, v := range s { value, err := Int64(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -125,7 +125,7 @@ func Int32Slice(val, sep string) ([]int32, error) { for i, v := range s { value, err := Int32(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -145,7 +145,7 @@ func Uint64Slice(val, sep string) ([]uint64, error) { for i, v := range s { value, err := Uint64(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -169,7 +169,7 @@ func Uint32Slice(val, sep string) ([]uint32, error) { for i, v := range s { value, err := Uint32(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -197,7 +197,7 @@ func BytesSlice(val, sep string) ([][]byte, error) { for i, v := range s { value, err := Bytes(v) if err != nil { - return values, err + return nil, err } values[i] = value } @@ -205,20 +205,22 @@ func BytesSlice(val, sep string) ([][]byte, error) { } // Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp. -func Timestamp(val string) (*timestamp.Timestamp, error) { - var r timestamp.Timestamp - err := jsonpb.UnmarshalString(val, &r) - if err != nil { +func Timestamp(val string) (*timestamppb.Timestamp, error) { + var r timestamppb.Timestamp + val = strconv.Quote(strings.Trim(val, `"`)) + unmarshaler := &protojson.UnmarshalOptions{} + if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { return nil, err } return &r, nil } // Duration converts the given string into a timestamp.Duration. -func Duration(val string) (*duration.Duration, error) { - var r duration.Duration - err := jsonpb.UnmarshalString(val, &r) - if err != nil { +func Duration(val string) (*durationpb.Duration, error) { + var r durationpb.Duration + val = strconv.Quote(strings.Trim(val, `"`)) + unmarshaler := &protojson.UnmarshalOptions{} + if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { return nil, err } return &r, nil @@ -253,66 +255,64 @@ func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) { for i, v := range s { value, err := Enum(v, enumValMap) if err != nil { - return values, err + return nil, err } values[i] = value } return values, nil } -/* - Support fot google.protobuf.wrappers on top of primitive types -*/ +// Support for google.protobuf.wrappers on top of primitive types // StringValue well-known type support as wrapper around string type -func StringValue(val string) (*wrappers.StringValue, error) { - return &wrappers.StringValue{Value: val}, nil +func StringValue(val string) (*wrapperspb.StringValue, error) { + return wrapperspb.String(val), nil } // FloatValue well-known type support as wrapper around float32 type -func FloatValue(val string) (*wrappers.FloatValue, error) { +func FloatValue(val string) (*wrapperspb.FloatValue, error) { parsedVal, err := Float32(val) - return &wrappers.FloatValue{Value: parsedVal}, err + return wrapperspb.Float(parsedVal), err } // DoubleValue well-known type support as wrapper around float64 type -func DoubleValue(val string) (*wrappers.DoubleValue, error) { +func DoubleValue(val string) (*wrapperspb.DoubleValue, error) { parsedVal, err := Float64(val) - return &wrappers.DoubleValue{Value: parsedVal}, err + return wrapperspb.Double(parsedVal), err } // BoolValue well-known type support as wrapper around bool type -func BoolValue(val string) (*wrappers.BoolValue, error) { +func BoolValue(val string) (*wrapperspb.BoolValue, error) { parsedVal, err := Bool(val) - return &wrappers.BoolValue{Value: parsedVal}, err + return wrapperspb.Bool(parsedVal), err } // Int32Value well-known type support as wrapper around int32 type -func Int32Value(val string) (*wrappers.Int32Value, error) { +func Int32Value(val string) (*wrapperspb.Int32Value, error) { parsedVal, err := Int32(val) - return &wrappers.Int32Value{Value: parsedVal}, err + return wrapperspb.Int32(parsedVal), err } // UInt32Value well-known type support as wrapper around uint32 type -func UInt32Value(val string) (*wrappers.UInt32Value, error) { +func UInt32Value(val string) (*wrapperspb.UInt32Value, error) { parsedVal, err := Uint32(val) - return &wrappers.UInt32Value{Value: parsedVal}, err + return wrapperspb.UInt32(parsedVal), err } // Int64Value well-known type support as wrapper around int64 type -func Int64Value(val string) (*wrappers.Int64Value, error) { +func Int64Value(val string) (*wrapperspb.Int64Value, error) { parsedVal, err := Int64(val) - return &wrappers.Int64Value{Value: parsedVal}, err + return wrapperspb.Int64(parsedVal), err } // UInt64Value well-known type support as wrapper around uint64 type -func UInt64Value(val string) (*wrappers.UInt64Value, error) { +func UInt64Value(val string) (*wrapperspb.UInt64Value, error) { parsedVal, err := Uint64(val) - return &wrappers.UInt64Value{Value: parsedVal}, err + return wrapperspb.UInt64(parsedVal), err } // BytesValue well-known type support as wrapper around bytes[] type -func BytesValue(val string) (*wrappers.BytesValue, error) { +func BytesValue(val string) (*wrapperspb.BytesValue, error) { parsedVal, err := Bytes(val) - return &wrappers.BytesValue{Value: parsedVal}, err + return wrapperspb.Bytes(parsedVal), err } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go new file mode 100644 index 00000000000..d2bcbb7d2a2 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go @@ -0,0 +1,181 @@ +package runtime + +import ( + "context" + "errors" + "io" + "net/http" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// ErrorHandlerFunc is the signature used to configure error handling. +type ErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) + +// StreamErrorHandlerFunc is the signature used to configure stream error handling. +type StreamErrorHandlerFunc func(context.Context, error) *status.Status + +// RoutingErrorHandlerFunc is the signature used to configure error handling for routing errors. +type RoutingErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, int) + +// HTTPStatusError is the error to use when needing to provide a different HTTP status code for an error +// passed to the DefaultRoutingErrorHandler. +type HTTPStatusError struct { + HTTPStatus int + Err error +} + +func (e *HTTPStatusError) Error() string { + return e.Err.Error() +} + +// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. +// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +func HTTPStatusFromCode(code codes.Code) int { + switch code { + case codes.OK: + return http.StatusOK + case codes.Canceled: + return 499 + case codes.Unknown: + return http.StatusInternalServerError + case codes.InvalidArgument: + return http.StatusBadRequest + case codes.DeadlineExceeded: + return http.StatusGatewayTimeout + case codes.NotFound: + return http.StatusNotFound + case codes.AlreadyExists: + return http.StatusConflict + case codes.PermissionDenied: + return http.StatusForbidden + case codes.Unauthenticated: + return http.StatusUnauthorized + case codes.ResourceExhausted: + return http.StatusTooManyRequests + case codes.FailedPrecondition: + // Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status. + return http.StatusBadRequest + case codes.Aborted: + return http.StatusConflict + case codes.OutOfRange: + return http.StatusBadRequest + case codes.Unimplemented: + return http.StatusNotImplemented + case codes.Internal: + return http.StatusInternalServerError + case codes.Unavailable: + return http.StatusServiceUnavailable + case codes.DataLoss: + return http.StatusInternalServerError + default: + grpclog.Infof("Unknown gRPC error code: %v", code) + return http.StatusInternalServerError + } +} + +// HTTPError uses the mux-configured error handler. +func HTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { + mux.errorHandler(ctx, mux, marshaler, w, r, err) +} + +// DefaultHTTPErrorHandler is the default error handler. +// If "err" is a gRPC Status, the function replies with the status code mapped by HTTPStatusFromCode. +// If "err" is a HTTPStatusError, the function replies with the status code provide by that struct. This is +// intended to allow passing through of specific statuses via the function set via WithRoutingErrorHandler +// for the ServeMux constructor to handle edge cases which the standard mappings in HTTPStatusFromCode +// are insufficient for. +// If otherwise, it replies with http.StatusInternalServerError. +// +// The response body written by this function is a Status message marshaled by the Marshaler. +func DefaultHTTPErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) { + // return Internal when Marshal failed + const fallback = `{"code": 13, "message": "failed to marshal error message"}` + + var customStatus *HTTPStatusError + if errors.As(err, &customStatus) { + err = customStatus.Err + } + + s := status.Convert(err) + pb := s.Proto() + + w.Header().Del("Trailer") + w.Header().Del("Transfer-Encoding") + + contentType := marshaler.ContentType(pb) + w.Header().Set("Content-Type", contentType) + + if s.Code() == codes.Unauthenticated { + w.Header().Set("WWW-Authenticate", s.Message()) + } + + buf, merr := marshaler.Marshal(pb) + if merr != nil { + grpclog.Infof("Failed to marshal error message %q: %v", s, merr) + w.WriteHeader(http.StatusInternalServerError) + if _, err := io.WriteString(w, fallback); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + + // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 + // Unless the request includes a TE header field indicating "trailers" + // is acceptable, as described in Section 4.3, a server SHOULD NOT + // generate trailer fields that it believes are necessary for the user + // agent to receive. + doForwardTrailers := requestAcceptsTrailers(r) + + if doForwardTrailers { + handleForwardResponseTrailerHeader(w, md) + w.Header().Set("Transfer-Encoding", "chunked") + } + + st := HTTPStatusFromCode(s.Code()) + if customStatus != nil { + st = customStatus.HTTPStatus + } + + w.WriteHeader(st) + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + if doForwardTrailers { + handleForwardResponseTrailer(w, md) + } +} + +func DefaultStreamErrorHandler(_ context.Context, err error) *status.Status { + return status.Convert(err) +} + +// DefaultRoutingErrorHandler is our default handler for routing errors. +// By default http error codes mapped on the following error codes: +// +// NotFound -> grpc.NotFound +// StatusBadRequest -> grpc.InvalidArgument +// MethodNotAllowed -> grpc.Unimplemented +// Other -> grpc.Internal, method is not expecting to be called for anything else +func DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) { + sterr := status.Error(codes.Internal, "Unexpected routing error") + switch httpStatus { + case http.StatusBadRequest: + sterr = status.Error(codes.InvalidArgument, http.StatusText(httpStatus)) + case http.StatusMethodNotAllowed: + sterr = status.Error(codes.Unimplemented, http.StatusText(httpStatus)) + case http.StatusNotFound: + sterr = status.Error(codes.NotFound, http.StatusText(httpStatus)) + } + mux.errorHandler(ctx, mux, marshaler, w, r, sterr) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go new file mode 100644 index 00000000000..a03dd166bd7 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go @@ -0,0 +1,166 @@ +package runtime + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "sort" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + field_mask "google.golang.org/protobuf/types/known/fieldmaskpb" +) + +func getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { + fd := fields.ByName(protoreflect.Name(name)) + if fd != nil { + return fd + } + + return fields.ByJSONName(name) +} + +// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body. +func FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.FieldMask, error) { + fm := &field_mask.FieldMask{} + var root interface{} + + if err := json.NewDecoder(r).Decode(&root); err != nil { + if err == io.EOF { + return fm, nil + } + return nil, err + } + + queue := []fieldMaskPathItem{{node: root, msg: msg.ProtoReflect()}} + for len(queue) > 0 { + // dequeue an item + item := queue[0] + queue = queue[1:] + + m, ok := item.node.(map[string]interface{}) + switch { + case ok: + // if the item is an object, then enqueue all of its children + for k, v := range m { + if item.msg == nil { + return nil, errors.New("JSON structure did not match request type") + } + + fd := getFieldByName(item.msg.Descriptor().Fields(), k) + if fd == nil { + return nil, fmt.Errorf("could not find field %q in %q", k, item.msg.Descriptor().FullName()) + } + + if isDynamicProtoMessage(fd.Message()) { + for _, p := range buildPathsBlindly(string(fd.FullName().Name()), v) { + newPath := p + if item.path != "" { + newPath = item.path + "." + newPath + } + queue = append(queue, fieldMaskPathItem{path: newPath}) + } + continue + } + + if isProtobufAnyMessage(fd.Message()) && !fd.IsList() { + _, hasTypeField := v.(map[string]interface{})["@type"] + if hasTypeField { + queue = append(queue, fieldMaskPathItem{path: k}) + continue + } else { + return nil, fmt.Errorf("could not find field @type in %q in message %q", k, item.msg.Descriptor().FullName()) + } + + } + + child := fieldMaskPathItem{ + node: v, + } + if item.path == "" { + child.path = string(fd.FullName().Name()) + } else { + child.path = item.path + "." + string(fd.FullName().Name()) + } + + switch { + case fd.IsList(), fd.IsMap(): + // As per: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/field_mask.proto#L85-L86 + // Do not recurse into repeated fields. The repeated field goes on the end of the path and we stop. + fm.Paths = append(fm.Paths, child.path) + case fd.Message() != nil: + child.msg = item.msg.Get(fd).Message() + fallthrough + default: + queue = append(queue, child) + } + } + case len(item.path) > 0: + // otherwise, it's a leaf node so print its path + fm.Paths = append(fm.Paths, item.path) + } + } + + // Sort for deterministic output in the presence + // of repeated fields. + sort.Strings(fm.Paths) + + return fm, nil +} + +func isProtobufAnyMessage(md protoreflect.MessageDescriptor) bool { + return md != nil && (md.FullName() == "google.protobuf.Any") +} + +func isDynamicProtoMessage(md protoreflect.MessageDescriptor) bool { + return md != nil && (md.FullName() == "google.protobuf.Struct" || md.FullName() == "google.protobuf.Value") +} + +// buildPathsBlindly does not attempt to match proto field names to the +// json value keys. Instead it relies completely on the structure of +// the unmarshalled json contained within in. +// Returns a slice containing all subpaths with the root at the +// passed in name and json value. +func buildPathsBlindly(name string, in interface{}) []string { + m, ok := in.(map[string]interface{}) + if !ok { + return []string{name} + } + + var paths []string + queue := []fieldMaskPathItem{{path: name, node: m}} + for len(queue) > 0 { + cur := queue[0] + queue = queue[1:] + + m, ok := cur.node.(map[string]interface{}) + if !ok { + // This should never happen since we should always check that we only add + // nodes of type map[string]interface{} to the queue. + continue + } + for k, v := range m { + if mi, ok := v.(map[string]interface{}); ok { + queue = append(queue, fieldMaskPathItem{path: cur.path + "." + k, node: mi}) + } else { + // This is not a struct, so there are no more levels to descend. + curPath := cur.path + "." + k + paths = append(paths, curPath) + } + } + } + return paths +} + +// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask +type fieldMaskPathItem struct { + // the list of prior fields leading up to node connected by dots + path string + + // a generic decoded json object the current item to inspect for further path extraction + node interface{} + + // parent message + msg protoreflect.Message +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go new file mode 100644 index 00000000000..945f3a5ebf3 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go @@ -0,0 +1,227 @@ +package runtime + +import ( + "context" + "fmt" + "io" + "net/http" + "net/textproto" + "strings" + + "google.golang.org/genproto/googleapis/api/httpbody" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// ForwardResponseStream forwards the stream from gRPC server to REST client. +func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + f, ok := w.(http.Flusher) + if !ok { + grpclog.Infof("Flush not supported in %T", w) + http.Error(w, "unexpected type of web server", http.StatusInternalServerError) + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + http.Error(w, "unexpected error", http.StatusInternalServerError) + return + } + handleForwardResponseServerMetadata(w, mux, md) + + w.Header().Set("Transfer-Encoding", "chunked") + if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + var delimiter []byte + if d, ok := marshaler.(Delimited); ok { + delimiter = d.Delimiter() + } else { + delimiter = []byte("\n") + } + + var wroteHeader bool + for { + resp, err := recv() + if err == io.EOF { + return + } + if err != nil { + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) + return + } + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) + return + } + + if !wroteHeader { + w.Header().Set("Content-Type", marshaler.ContentType(resp)) + } + + var buf []byte + httpBody, isHTTPBody := resp.(*httpbody.HttpBody) + switch { + case resp == nil: + buf, err = marshaler.Marshal(errorChunk(status.New(codes.Internal, "empty response"))) + case isHTTPBody: + buf = httpBody.GetData() + default: + result := map[string]interface{}{"result": resp} + if rb, ok := resp.(responseBody); ok { + result["result"] = rb.XXX_ResponseBody() + } + + buf, err = marshaler.Marshal(result) + } + + if err != nil { + grpclog.Infof("Failed to marshal response chunk: %v", err) + handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter) + return + } + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to send response chunk: %v", err) + return + } + wroteHeader = true + if _, err := w.Write(delimiter); err != nil { + grpclog.Infof("Failed to send delimiter chunk: %v", err) + return + } + f.Flush() + } +} + +func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) { + for k, vs := range md.HeaderMD { + if h, ok := mux.outgoingHeaderMatcher(k); ok { + for _, v := range vs { + w.Header().Add(h, v) + } + } + } +} + +func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { + for k := range md.TrailerMD { + tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) + w.Header().Add("Trailer", tKey) + } +} + +func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { + for k, vs := range md.TrailerMD { + tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) + for _, v := range vs { + w.Header().Add(tKey, v) + } + } +} + +// responseBody interface contains method for getting field for marshaling to the response body +// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule` +type responseBody interface { + XXX_ResponseBody() interface{} +} + +// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. +func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + + // RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2 + // Unless the request includes a TE header field indicating "trailers" + // is acceptable, as described in Section 4.3, a server SHOULD NOT + // generate trailer fields that it believes are necessary for the user + // agent to receive. + doForwardTrailers := requestAcceptsTrailers(req) + + if doForwardTrailers { + handleForwardResponseTrailerHeader(w, md) + w.Header().Set("Transfer-Encoding", "chunked") + } + + handleForwardResponseTrailerHeader(w, md) + + contentType := marshaler.ContentType(resp) + w.Header().Set("Content-Type", contentType) + + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + var buf []byte + var err error + if rb, ok := resp.(responseBody); ok { + buf, err = marshaler.Marshal(rb.XXX_ResponseBody()) + } else { + buf, err = marshaler.Marshal(resp) + } + if err != nil { + grpclog.Infof("Marshal error: %v", err) + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + if _, err = w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + if doForwardTrailers { + handleForwardResponseTrailer(w, md) + } +} + +func requestAcceptsTrailers(req *http.Request) bool { + te := req.Header.Get("TE") + return strings.Contains(strings.ToLower(te), "trailers") +} + +func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { + if len(opts) == 0 { + return nil + } + for _, opt := range opts { + if err := opt(ctx, w, resp); err != nil { + grpclog.Infof("Error handling ForwardResponseOptions: %v", err) + return err + } + } + return nil +} + +func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error, delimiter []byte) { + st := mux.streamErrorHandler(ctx, err) + msg := errorChunk(st) + if !wroteHeader { + w.Header().Set("Content-Type", marshaler.ContentType(msg)) + w.WriteHeader(HTTPStatusFromCode(st.Code())) + } + buf, err := marshaler.Marshal(msg) + if err != nil { + grpclog.Infof("Failed to marshal an error: %v", err) + return + } + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to notify error to client: %v", err) + return + } + if _, err := w.Write(delimiter); err != nil { + grpclog.Infof("Failed to send delimiter chunk: %v", err) + return + } +} + +func errorChunk(st *status.Status) map[string]proto.Message { + return map[string]proto.Message{"error": st.Proto()} +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go new file mode 100644 index 00000000000..b86135c889b --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go @@ -0,0 +1,32 @@ +package runtime + +import ( + "google.golang.org/genproto/googleapis/api/httpbody" +) + +// HTTPBodyMarshaler is a Marshaler which supports marshaling of a +// google.api.HttpBody message as the full response body if it is +// the actual message used as the response. If not, then this will +// simply fallback to the Marshaler specified as its default Marshaler. +type HTTPBodyMarshaler struct { + Marshaler +} + +// ContentType returns its specified content type in case v is a +// google.api.HttpBody message, otherwise it will fall back to the default Marshalers +// content type. +func (h *HTTPBodyMarshaler) ContentType(v interface{}) string { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.GetContentType() + } + return h.Marshaler.ContentType(v) +} + +// Marshal marshals "v" by returning the body bytes if v is a +// google.api.HttpBody message, otherwise it falls back to the default Marshaler. +func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.Data, nil + } + return h.Marshaler.Marshal(v) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go similarity index 95% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go index f9d3a585a4c..d6aa8257836 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go @@ -15,7 +15,7 @@ import ( type JSONBuiltin struct{} // ContentType always Returns "application/json". -func (*JSONBuiltin) ContentType() string { +func (*JSONBuiltin) ContentType(_ interface{}) string { return "application/json" } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go new file mode 100644 index 00000000000..51b8247da2a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go @@ -0,0 +1,348 @@ +package runtime + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "reflect" + "strconv" + + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" +) + +// JSONPb is a Marshaler which marshals/unmarshals into/from JSON +// with the "google.golang.org/protobuf/encoding/protojson" marshaler. +// It supports the full functionality of protobuf unlike JSONBuiltin. +// +// The NewDecoder method returns a DecoderWrapper, so the underlying +// *json.Decoder methods can be used. +type JSONPb struct { + protojson.MarshalOptions + protojson.UnmarshalOptions +} + +// ContentType always returns "application/json". +func (*JSONPb) ContentType(_ interface{}) string { + return "application/json" +} + +// Marshal marshals "v" into JSON. +func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { + if _, ok := v.(proto.Message); !ok { + return j.marshalNonProtoField(v) + } + + var buf bytes.Buffer + if err := j.marshalTo(&buf, v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + buf, err := j.marshalNonProtoField(v) + if err != nil { + return err + } + _, err = w.Write(buf) + return err + } + b, err := j.MarshalOptions.Marshal(p) + if err != nil { + return err + } + + _, err = w.Write(b) + return err +} + +var ( + // protoMessageType is stored to prevent constant lookup of the same type at runtime. + protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() +) + +// marshalNonProto marshals a non-message field of a protobuf message. +// This function does not correctly marshal arbitrary data structures into JSON, +// it is only capable of marshaling non-message field values of protobuf, +// i.e. primitive types, enums; pointers to primitives or enums; maps from +// integer/string types to primitives/enums/pointers to messages. +func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { + if v == nil { + return []byte("null"), nil + } + rv := reflect.ValueOf(v) + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return []byte("null"), nil + } + rv = rv.Elem() + } + + if rv.Kind() == reflect.Slice { + if rv.IsNil() { + if j.EmitUnpopulated { + return []byte("[]"), nil + } + return []byte("null"), nil + } + + if rv.Type().Elem().Implements(protoMessageType) { + var buf bytes.Buffer + if err := buf.WriteByte('['); err != nil { + return nil, err + } + for i := 0; i < rv.Len(); i++ { + if i != 0 { + if err := buf.WriteByte(','); err != nil { + return nil, err + } + } + if err := j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { + return nil, err + } + } + if err := buf.WriteByte(']'); err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + + if rv.Type().Elem().Implements(typeProtoEnum) { + var buf bytes.Buffer + if err := buf.WriteByte('['); err != nil { + return nil, err + } + for i := 0; i < rv.Len(); i++ { + if i != 0 { + if err := buf.WriteByte(','); err != nil { + return nil, err + } + } + var err error + if j.UseEnumNumbers { + _, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10)) + } else { + _, err = buf.WriteString("\"" + rv.Index(i).Interface().(protoEnum).String() + "\"") + } + if err != nil { + return nil, err + } + } + if err := buf.WriteByte(']'); err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + } + + if rv.Kind() == reflect.Map { + m := make(map[string]*json.RawMessage) + for _, k := range rv.MapKeys() { + buf, err := j.Marshal(rv.MapIndex(k).Interface()) + if err != nil { + return nil, err + } + m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) + } + if j.Indent != "" { + return json.MarshalIndent(m, "", j.Indent) + } + return json.Marshal(m) + } + if enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers { + return json.Marshal(enum.String()) + } + return json.Marshal(rv.Interface()) +} + +// Unmarshal unmarshals JSON "data" into "v" +func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { + return unmarshalJSONPb(data, j.UnmarshalOptions, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONPb) NewDecoder(r io.Reader) Decoder { + d := json.NewDecoder(r) + return DecoderWrapper{ + Decoder: d, + UnmarshalOptions: j.UnmarshalOptions, + } +} + +// DecoderWrapper is a wrapper around a *json.Decoder that adds +// support for protos to the Decode method. +type DecoderWrapper struct { + *json.Decoder + protojson.UnmarshalOptions +} + +// Decode wraps the embedded decoder's Decode method to support +// protos using a jsonpb.Unmarshaler. +func (d DecoderWrapper) Decode(v interface{}) error { + return decodeJSONPb(d.Decoder, d.UnmarshalOptions, v) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONPb) NewEncoder(w io.Writer) Encoder { + return EncoderFunc(func(v interface{}) error { + if err := j.marshalTo(w, v); err != nil { + return err + } + // mimic json.Encoder by adding a newline (makes output + // easier to read when it contains multiple encoded items) + _, err := w.Write(j.Delimiter()) + return err + }) +} + +func unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + d := json.NewDecoder(bytes.NewReader(data)) + return decodeJSONPb(d, unmarshaler, v) +} + +func decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + return decodeNonProtoField(d, unmarshaler, v) + } + + // Decode into bytes for marshalling + var b json.RawMessage + if err := d.Decode(&b); err != nil { + return err + } + + return unmarshaler.Unmarshal([]byte(b), p) +} + +func decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("%T is not a pointer", v) + } + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + rv.Set(reflect.New(rv.Type().Elem())) + } + if rv.Type().ConvertibleTo(typeProtoMessage) { + // Decode into bytes for marshalling + var b json.RawMessage + if err := d.Decode(&b); err != nil { + return err + } + + return unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message)) + } + rv = rv.Elem() + } + if rv.Kind() == reflect.Map { + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + conv, ok := convFromType[rv.Type().Key().Kind()] + if !ok { + return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) + } + + m := make(map[string]*json.RawMessage) + if err := d.Decode(&m); err != nil { + return err + } + for k, v := range m { + result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + bk := result[0] + bv := reflect.New(rv.Type().Elem()) + if v == nil { + null := json.RawMessage("null") + v = &null + } + if err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil { + return err + } + rv.SetMapIndex(bk, bv.Elem()) + } + return nil + } + if rv.Kind() == reflect.Slice { + if rv.Type().Elem().Kind() == reflect.Uint8 { + var sl []byte + if err := d.Decode(&sl); err != nil { + return err + } + if sl != nil { + rv.SetBytes(sl) + } + return nil + } + + var sl []json.RawMessage + if err := d.Decode(&sl); err != nil { + return err + } + if sl != nil { + rv.Set(reflect.MakeSlice(rv.Type(), 0, 0)) + } + for _, item := range sl { + bv := reflect.New(rv.Type().Elem()) + if err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil { + return err + } + rv.Set(reflect.Append(rv, bv.Elem())) + } + return nil + } + if _, ok := rv.Interface().(protoEnum); ok { + var repr interface{} + if err := d.Decode(&repr); err != nil { + return err + } + switch v := repr.(type) { + case string: + // TODO(yugui) Should use proto.StructProperties? + return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) + case float64: + rv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type())) + return nil + default: + return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) + } + } + return d.Decode(v) +} + +type protoEnum interface { + fmt.Stringer + EnumDescriptor() ([]byte, []int) +} + +var typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem() + +var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() + +// Delimiter for newline encoded JSON streams. +func (j *JSONPb) Delimiter() []byte { + return []byte("\n") +} + +var ( + convFromType = map[reflect.Kind]reflect.Value{ + reflect.String: reflect.ValueOf(String), + reflect.Bool: reflect.ValueOf(Bool), + reflect.Float64: reflect.ValueOf(Float64), + reflect.Float32: reflect.ValueOf(Float32), + reflect.Int64: reflect.ValueOf(Int64), + reflect.Int32: reflect.ValueOf(Int32), + reflect.Uint64: reflect.ValueOf(Uint64), + reflect.Uint32: reflect.ValueOf(Uint32), + reflect.Slice: reflect.ValueOf(Bytes), + } +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go similarity index 88% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go index f65d1a2676b..398c780dc22 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go @@ -1,18 +1,17 @@ package runtime import ( + "errors" "io" - "errors" - "github.com/golang/protobuf/proto" - "io/ioutil" + "google.golang.org/protobuf/proto" ) // ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes type ProtoMarshaller struct{} // ContentType always returns "application/octet-stream". -func (*ProtoMarshaller) ContentType() string { +func (*ProtoMarshaller) ContentType(_ interface{}) string { return "application/octet-stream" } @@ -37,7 +36,7 @@ func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error { // NewDecoder returns a Decoder which reads proto stream from "reader". func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { return DecoderFunc(func(value interface{}) error { - buffer, err := ioutil.ReadAll(reader) + buffer, err := io.ReadAll(reader) if err != nil { return err } @@ -52,8 +51,7 @@ func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder { if err != nil { return err } - _, err = writer.Write(buffer) - if err != nil { + if _, err := writer.Write(buffer); err != nil { return err } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go similarity index 80% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go index 46153294217..2c0d25ff493 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go @@ -16,14 +16,9 @@ type Marshaler interface { // NewEncoder returns an Encoder which writes bytes sequence into "w". NewEncoder(w io.Writer) Encoder // ContentType returns the Content-Type which this marshaler is responsible for. - ContentType() string -} - -// Marshalers that implement contentTypeMarshaler will have their ContentTypeFromMessage method called -// to set the Content-Type header on the response -type contentTypeMarshaler interface { - // ContentTypeFromMessage returns the Content-Type this marshaler produces from the provided message - ContentTypeFromMessage(v interface{}) string + // The parameter describes the type which is being marshalled, which can sometimes + // affect the content type returned. + ContentType(v interface{}) string } // Decoder decodes a byte sequence diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go similarity index 91% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go index 8dd5c24db42..a714de02406 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go @@ -6,6 +6,7 @@ import ( "net/http" "google.golang.org/grpc/grpclog" + "google.golang.org/protobuf/encoding/protojson" ) // MIMEWildcard is the fallback MIME type used for requests which do not match @@ -16,7 +17,16 @@ var ( acceptHeader = http.CanonicalHeaderKey("Accept") contentTypeHeader = http.CanonicalHeaderKey("Content-Type") - defaultMarshaler = &JSONPb{OrigName: true} + defaultMarshaler = &HTTPBodyMarshaler{ + Marshaler: &JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + EmitUnpopulated: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: true, + }, + }, + } ) // MarshalerForRequest returns the inbound/outbound marshalers for this request. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go new file mode 100644 index 00000000000..f451cb441f4 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go @@ -0,0 +1,466 @@ +package runtime + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/textproto" + "regexp" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// UnescapingMode defines the behavior of ServeMux when unescaping path parameters. +type UnescapingMode int + +const ( + // UnescapingModeLegacy is the default V2 behavior, which escapes the entire + // path string before doing any routing. + UnescapingModeLegacy UnescapingMode = iota + + // UnescapingModeAllExceptReserved unescapes all path parameters except RFC 6570 + // reserved characters. + UnescapingModeAllExceptReserved + + // UnescapingModeAllExceptSlash unescapes URL path parameters except path + // separators, which will be left as "%2F". + UnescapingModeAllExceptSlash + + // UnescapingModeAllCharacters unescapes all URL path parameters. + UnescapingModeAllCharacters + + // UnescapingModeDefault is the default escaping type. + // TODO(v3): default this to UnescapingModeAllExceptReserved per grpc-httpjson-transcoding's + // reference implementation + UnescapingModeDefault = UnescapingModeLegacy +) + +var encodedPathSplitter = regexp.MustCompile("(/|%2F)") + +// A HandlerFunc handles a specific pair of path pattern and HTTP method. +type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) + +// ServeMux is a request multiplexer for grpc-gateway. +// It matches http requests to patterns and invokes the corresponding handler. +type ServeMux struct { + // handlers maps HTTP method to a list of handlers. + handlers map[string][]handler + forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error + marshalers marshalerRegistry + incomingHeaderMatcher HeaderMatcherFunc + outgoingHeaderMatcher HeaderMatcherFunc + metadataAnnotators []func(context.Context, *http.Request) metadata.MD + errorHandler ErrorHandlerFunc + streamErrorHandler StreamErrorHandlerFunc + routingErrorHandler RoutingErrorHandlerFunc + disablePathLengthFallback bool + unescapingMode UnescapingMode +} + +// ServeMuxOption is an option that can be given to a ServeMux on construction. +type ServeMuxOption func(*ServeMux) + +// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. +// +// forwardResponseOption is an option that will be called on the relevant context.Context, +// http.ResponseWriter, and proto.Message before every forwarded response. +// +// The message may be nil in the case where just a header is being sent. +func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) + } +} + +// WithUnescapingMode sets the escaping type. See the definitions of UnescapingMode +// for more information. +func WithUnescapingMode(mode UnescapingMode) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.unescapingMode = mode + } +} + +// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters. +// Configuring this will mean the generated OpenAPI output is no longer correct, and it should be +// done with careful consideration. +func SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption { + return func(serveMux *ServeMux) { + currentQueryParser = queryParameterParser + } +} + +// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context. +type HeaderMatcherFunc func(string) (string, bool) + +// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header +// keys (as specified by the IANA, e.g: Accept, Cookie, Host) to the gRPC metadata with the grpcgateway- prefix. If you want to know which headers are considered permanent, you can view the isPermanentHTTPHeader function. +// HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata after removing the prefix 'Grpc-Metadata-'. +// Other headers are not added to the gRPC metadata. +func DefaultHeaderMatcher(key string) (string, bool) { + switch key = textproto.CanonicalMIMEHeaderKey(key); { + case isPermanentHTTPHeader(key): + return MetadataPrefix + key, true + case strings.HasPrefix(key, MetadataHeaderPrefix): + return key[len(MetadataHeaderPrefix):], true + } + return "", false +} + +// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway. +// +// This matcher will be called with each header in http.Request. If matcher returns true, that header will be +// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. +func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + for _, header := range fn.matchedMalformedHeaders() { + grpclog.Warningf("The configured forwarding filter would allow %q to be sent to the gRPC server, which will likely cause errors. See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more information.", header) + } + + return func(mux *ServeMux) { + mux.incomingHeaderMatcher = fn + } +} + +// matchedMalformedHeaders returns the malformed headers that would be forwarded to gRPC server. +func (fn HeaderMatcherFunc) matchedMalformedHeaders() []string { + if fn == nil { + return nil + } + headers := make([]string, 0) + for header := range malformedHTTPHeaders { + out, accept := fn(header) + if accept && isMalformedHTTPHeader(out) { + headers = append(headers, out) + } + } + return headers +} + +// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. +// +// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be +// passed to http response returned from gateway. To transform the header before passing to response, +// matcher should return modified header. +func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + return func(mux *ServeMux) { + mux.outgoingHeaderMatcher = fn + } +} + +// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context. +// +// This can be used by services that need to read from http.Request and modify gRPC context. A common use case +// is reading token from cookie and adding it in gRPC context. +func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator) + } +} + +// WithErrorHandler returns a ServeMuxOption for configuring a custom error handler. +// +// This can be used to configure a custom error response. +func WithErrorHandler(fn ErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.errorHandler = fn + } +} + +// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream +// error handler, which allows for customizing the error trailer for server-streaming +// calls. +// +// For stream errors that occur before any response has been written, the mux's +// ErrorHandler will be invoked. However, once data has been written, the errors must +// be handled differently: they must be included in the response body. The response body's +// final message will include the error details returned by the stream error handler. +func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.streamErrorHandler = fn + } +} + +// WithRoutingErrorHandler returns a ServeMuxOption for configuring a custom error handler to handle http routing errors. +// +// Method called for errors which can happen before gRPC route selected or executed. +// The following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest +func WithRoutingErrorHandler(fn RoutingErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.routingErrorHandler = fn + } +} + +// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback. +func WithDisablePathLengthFallback() ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.disablePathLengthFallback = true + } +} + +// WithHealthEndpointAt returns a ServeMuxOption that will add an endpoint to the created ServeMux at the path specified by endpointPath. +// When called the handler will forward the request to the upstream grpc service health check (defined in the +// gRPC Health Checking Protocol). +// +// See here https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/health_check/ for more information on how +// to setup the protocol in the grpc server. +// +// If you define a service as query parameter, this will also be forwarded as service in the HealthCheckRequest. +func WithHealthEndpointAt(healthCheckClient grpc_health_v1.HealthClient, endpointPath string) ServeMuxOption { + return func(s *ServeMux) { + // error can be ignored since pattern is definitely valid + _ = s.HandlePath( + http.MethodGet, endpointPath, func(w http.ResponseWriter, r *http.Request, _ map[string]string, + ) { + _, outboundMarshaler := MarshalerForRequest(s, r) + + resp, err := healthCheckClient.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{ + Service: r.URL.Query().Get("service"), + }) + if err != nil { + s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) + return + } + + w.Header().Set("Content-Type", "application/json") + + if resp.GetStatus() != grpc_health_v1.HealthCheckResponse_SERVING { + switch resp.GetStatus() { + case grpc_health_v1.HealthCheckResponse_NOT_SERVING, grpc_health_v1.HealthCheckResponse_UNKNOWN: + err = status.Error(codes.Unavailable, resp.String()) + case grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN: + err = status.Error(codes.NotFound, resp.String()) + } + + s.errorHandler(r.Context(), s, outboundMarshaler, w, r, err) + return + } + + _ = outboundMarshaler.NewEncoder(w).Encode(resp) + }) + } +} + +// WithHealthzEndpoint returns a ServeMuxOption that will add a /healthz endpoint to the created ServeMux. +// +// See WithHealthEndpointAt for the general implementation. +func WithHealthzEndpoint(healthCheckClient grpc_health_v1.HealthClient) ServeMuxOption { + return WithHealthEndpointAt(healthCheckClient, "/healthz") +} + +// NewServeMux returns a new ServeMux whose internal mapping is empty. +func NewServeMux(opts ...ServeMuxOption) *ServeMux { + serveMux := &ServeMux{ + handlers: make(map[string][]handler), + forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), + marshalers: makeMarshalerMIMERegistry(), + errorHandler: DefaultHTTPErrorHandler, + streamErrorHandler: DefaultStreamErrorHandler, + routingErrorHandler: DefaultRoutingErrorHandler, + unescapingMode: UnescapingModeDefault, + } + + for _, opt := range opts { + opt(serveMux) + } + + if serveMux.incomingHeaderMatcher == nil { + serveMux.incomingHeaderMatcher = DefaultHeaderMatcher + } + + if serveMux.outgoingHeaderMatcher == nil { + serveMux.outgoingHeaderMatcher = func(key string) (string, bool) { + return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true + } + } + + return serveMux +} + +// Handle associates "h" to the pair of HTTP method and path pattern. +func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { + s.handlers[meth] = append([]handler{{pat: pat, h: h}}, s.handlers[meth]...) +} + +// HandlePath allows users to configure custom path handlers. +// refer: https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/inject_router/ +func (s *ServeMux) HandlePath(meth string, pathPattern string, h HandlerFunc) error { + compiler, err := httprule.Parse(pathPattern) + if err != nil { + return fmt.Errorf("parsing path pattern: %w", err) + } + tp := compiler.Compile() + pattern, err := NewPattern(tp.Version, tp.OpCodes, tp.Pool, tp.Verb) + if err != nil { + return fmt.Errorf("creating new pattern: %w", err) + } + s.Handle(meth, pattern, h) + return nil +} + +// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.URL.Path. +func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + path := r.URL.Path + if !strings.HasPrefix(path, "/") { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusBadRequest) + return + } + + // TODO(v3): remove UnescapingModeLegacy + if s.unescapingMode != UnescapingModeLegacy && r.URL.RawPath != "" { + path = r.URL.RawPath + } + + if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { + r.Method = strings.ToUpper(override) + if err := r.ParseForm(); err != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr) + return + } + } + + var pathComponents []string + // since in UnescapeModeLegacy, the URL will already have been fully unescaped, if we also split on "%2F" + // in this escaping mode we would be double unescaping but in UnescapingModeAllCharacters, we still do as the + // path is the RawPath (i.e. unescaped). That does mean that the behavior of this function will change its default + // behavior when the UnescapingModeDefault gets changed from UnescapingModeLegacy to UnescapingModeAllExceptReserved + if s.unescapingMode == UnescapingModeAllCharacters { + pathComponents = encodedPathSplitter.Split(path[1:], -1) + } else { + pathComponents = strings.Split(path[1:], "/") + } + + lastPathComponent := pathComponents[len(pathComponents)-1] + + for _, h := range s.handlers[r.Method] { + // If the pattern has a verb, explicitly look for a suffix in the last + // component that matches a colon plus the verb. This allows us to + // handle some cases that otherwise can't be correctly handled by the + // former LastIndex case, such as when the verb literal itself contains + // a colon. This should work for all cases that have run through the + // parser because we know what verb we're looking for, however, there + // are still some cases that the parser itself cannot disambiguate. See + // the comment there if interested. + + var verb string + patVerb := h.pat.Verb() + + idx := -1 + if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { + idx = len(lastPathComponent) - len(patVerb) - 1 + } + if idx == 0 { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) + return + } + + comps := make([]string, len(pathComponents)) + copy(comps, pathComponents) + + if idx > 0 { + comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] + } + + pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) + if err != nil { + var mse MalformedSequenceError + if ok := errors.As(err, &mse); ok { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{ + HTTPStatus: http.StatusBadRequest, + Err: mse, + }) + } + continue + } + h.h(w, r, pathParams) + return + } + + // if no handler has found for the request, lookup for other methods + // to handle POST -> GET fallback if the request is subject to path + // length fallback. + // Note we are not eagerly checking the request here as we want to return the + // right HTTP status code, and we need to process the fallback candidates in + // order to do that. + for m, handlers := range s.handlers { + if m == r.Method { + continue + } + for _, h := range handlers { + var verb string + patVerb := h.pat.Verb() + + idx := -1 + if patVerb != "" && strings.HasSuffix(lastPathComponent, ":"+patVerb) { + idx = len(lastPathComponent) - len(patVerb) - 1 + } + + comps := make([]string, len(pathComponents)) + copy(comps, pathComponents) + + if idx > 0 { + comps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:] + } + + pathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode) + if err != nil { + var mse MalformedSequenceError + if ok := errors.As(err, &mse); ok { + _, outboundMarshaler := MarshalerForRequest(s, r) + s.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{ + HTTPStatus: http.StatusBadRequest, + Err: mse, + }) + } + continue + } + + // X-HTTP-Method-Override is optional. Always allow fallback to POST. + // Also, only consider POST -> GET fallbacks, and avoid falling back to + // potentially dangerous operations like DELETE. + if s.isPathLengthFallback(r) && m == http.MethodGet { + if err := r.ParseForm(); err != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.errorHandler(ctx, s, outboundMarshaler, w, r, sterr) + return + } + h.h(w, r, pathParams) + return + } + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusMethodNotAllowed) + return + } + } + + _, outboundMarshaler := MarshalerForRequest(s, r) + s.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound) +} + +// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. +func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { + return s.forwardResponseOptions +} + +func (s *ServeMux) isPathLengthFallback(r *http.Request) bool { + return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" +} + +type handler struct { + pat Pattern + h HandlerFunc +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go new file mode 100644 index 00000000000..8f90d15a562 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go @@ -0,0 +1,381 @@ +package runtime + +import ( + "errors" + "fmt" + "strconv" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc/grpclog" +) + +var ( + // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. + ErrNotMatch = errors.New("not match to the path pattern") + // ErrInvalidPattern indicates that the given definition of Pattern is not valid. + ErrInvalidPattern = errors.New("invalid pattern") +) + +type MalformedSequenceError string + +func (e MalformedSequenceError) Error() string { + return "malformed path escape " + strconv.Quote(string(e)) +} + +type op struct { + code utilities.OpCode + operand int +} + +// Pattern is a template pattern of http request paths defined in +// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto +type Pattern struct { + // ops is a list of operations + ops []op + // pool is a constant pool indexed by the operands or vars. + pool []string + // vars is a list of variables names to be bound by this pattern + vars []string + // stacksize is the max depth of the stack + stacksize int + // tailLen is the length of the fixed-size segments after a deep wildcard + tailLen int + // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. + verb string +} + +// NewPattern returns a new Pattern from the given definition values. +// "ops" is a sequence of op codes. "pool" is a constant pool. +// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. +// "version" must be 1 for now. +// It returns an error if the given definition is invalid. +func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) { + if version != 1 { + grpclog.Infof("unsupported version: %d", version) + return Pattern{}, ErrInvalidPattern + } + + l := len(ops) + if l%2 != 0 { + grpclog.Infof("odd number of ops codes: %d", l) + return Pattern{}, ErrInvalidPattern + } + + var ( + typedOps []op + stack, maxstack int + tailLen int + pushMSeen bool + vars []string + ) + for i := 0; i < l; i += 2 { + op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpPushM: + if pushMSeen { + grpclog.Infof("pushM appears twice") + return Pattern{}, ErrInvalidPattern + } + pushMSeen = true + stack++ + case utilities.OpLitPush: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("negative literal index: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpConcatN: + if op.operand <= 0 { + grpclog.Infof("negative concat size: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + stack -= op.operand + if stack < 0 { + grpclog.Info("stack underflow") + return Pattern{}, ErrInvalidPattern + } + stack++ + case utilities.OpCapture: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("variable name index out of bound: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + v := pool[op.operand] + op.operand = len(vars) + vars = append(vars, v) + stack-- + if stack < 0 { + grpclog.Infof("stack underflow") + return Pattern{}, ErrInvalidPattern + } + default: + grpclog.Infof("invalid opcode: %d", op.code) + return Pattern{}, ErrInvalidPattern + } + + if maxstack < stack { + maxstack = stack + } + typedOps = append(typedOps, op) + } + return Pattern{ + ops: typedOps, + pool: pool, + vars: vars, + stacksize: maxstack, + tailLen: tailLen, + verb: verb, + }, nil +} + +// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. +func MustPattern(p Pattern, err error) Pattern { + if err != nil { + grpclog.Fatalf("Pattern initialization failed: %v", err) + } + return p +} + +// MatchAndEscape examines components to determine if they match to a Pattern. +// MatchAndEscape will return an error if no Patterns matched or if a pattern +// matched but contained malformed escape sequences. If successful, the function +// returns a mapping from field paths to their captured values. +func (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) { + if p.verb != verb { + if p.verb != "" { + return nil, ErrNotMatch + } + if len(components) == 0 { + components = []string{":" + verb} + } else { + components = append([]string{}, components...) + components[len(components)-1] += ":" + verb + } + } + + var pos int + stack := make([]string, 0, p.stacksize) + captured := make([]string, len(p.vars)) + l := len(components) + for _, op := range p.ops { + var err error + + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush, utilities.OpLitPush: + if pos >= l { + return nil, ErrNotMatch + } + c := components[pos] + if op.code == utilities.OpLitPush { + if lit := p.pool[op.operand]; c != lit { + return nil, ErrNotMatch + } + } else if op.code == utilities.OpPush { + if c, err = unescape(c, unescapingMode, false); err != nil { + return nil, err + } + } + stack = append(stack, c) + pos++ + case utilities.OpPushM: + end := len(components) + if end < pos+p.tailLen { + return nil, ErrNotMatch + } + end -= p.tailLen + c := strings.Join(components[pos:end], "/") + if c, err = unescape(c, unescapingMode, true); err != nil { + return nil, err + } + stack = append(stack, c) + pos = end + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + captured[op.operand] = stack[n] + stack = stack[:n] + } + } + if pos < l { + return nil, ErrNotMatch + } + bindings := make(map[string]string) + for i, val := range captured { + bindings[p.vars[i]] = val + } + return bindings, nil +} + +// MatchAndEscape examines components to determine if they match to a Pattern. +// It will never perform per-component unescaping (see: UnescapingModeLegacy). +// MatchAndEscape will return an error if no Patterns matched. If successful, +// the function returns a mapping from field paths to their captured values. +// +// Deprecated: Use MatchAndEscape. +func (p Pattern) Match(components []string, verb string) (map[string]string, error) { + return p.MatchAndEscape(components, verb, UnescapingModeDefault) +} + +// Verb returns the verb part of the Pattern. +func (p Pattern) Verb() string { return p.verb } + +func (p Pattern) String() string { + var stack []string + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + stack = append(stack, "*") + case utilities.OpLitPush: + stack = append(stack, p.pool[op.operand]) + case utilities.OpPushM: + stack = append(stack, "**") + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) + } + } + segs := strings.Join(stack, "/") + if p.verb != "" { + return fmt.Sprintf("/%s:%s", segs, p.verb) + } + return "/" + segs +} + +/* + * The following code is adopted and modified from Go's standard library + * and carries the attached license. + * + * Copyright 2009 The Go Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +// ishex returns whether or not the given byte is a valid hex character +func ishex(c byte) bool { + switch { + case '0' <= c && c <= '9': + return true + case 'a' <= c && c <= 'f': + return true + case 'A' <= c && c <= 'F': + return true + } + return false +} + +func isRFC6570Reserved(c byte) bool { + switch c { + case '!', '#', '$', '&', '\'', '(', ')', '*', + '+', ',', '/', ':', ';', '=', '?', '@', '[', ']': + return true + default: + return false + } +} + +// unhex converts a hex point to the bit representation +func unhex(c byte) byte { + switch { + case '0' <= c && c <= '9': + return c - '0' + case 'a' <= c && c <= 'f': + return c - 'a' + 10 + case 'A' <= c && c <= 'F': + return c - 'A' + 10 + } + return 0 +} + +// shouldUnescapeWithMode returns true if the character is escapable with the +// given mode +func shouldUnescapeWithMode(c byte, mode UnescapingMode) bool { + switch mode { + case UnescapingModeAllExceptReserved: + if isRFC6570Reserved(c) { + return false + } + case UnescapingModeAllExceptSlash: + if c == '/' { + return false + } + case UnescapingModeAllCharacters: + return true + } + return true +} + +// unescape unescapes a path string using the provided mode +func unescape(s string, mode UnescapingMode, multisegment bool) (string, error) { + // TODO(v3): remove UnescapingModeLegacy + if mode == UnescapingModeLegacy { + return s, nil + } + + if !multisegment { + mode = UnescapingModeAllCharacters + } + + // Count %, check that they're well-formed. + n := 0 + for i := 0; i < len(s); { + if s[i] == '%' { + n++ + if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) { + s = s[i:] + if len(s) > 3 { + s = s[:3] + } + + return "", MalformedSequenceError(s) + } + i += 3 + } else { + i++ + } + } + + if n == 0 { + return s, nil + } + + var t strings.Builder + t.Grow(len(s)) + for i := 0; i < len(s); i++ { + switch s[i] { + case '%': + c := unhex(s[i+1])<<4 | unhex(s[i+2]) + if shouldUnescapeWithMode(c, mode) { + t.WriteByte(c) + i += 2 + continue + } + fallthrough + default: + t.WriteByte(s[i]) + } + } + + return t.String(), nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go similarity index 98% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go index a3151e2a552..d549407f20f 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go @@ -1,7 +1,7 @@ package runtime import ( - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // StringP returns a pointer to a string whose pointee is same as the given string value. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go new file mode 100644 index 00000000000..d01933c4fd2 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go @@ -0,0 +1,338 @@ +package runtime + +import ( + "errors" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + "time" + + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc/grpclog" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/known/durationpb" + field_mask "google.golang.org/protobuf/types/known/fieldmaskpb" + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`) + +var currentQueryParser QueryParameterParser = &DefaultQueryParser{} + +// QueryParameterParser defines interface for all query parameter parsers +type QueryParameterParser interface { + Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error +} + +// PopulateQueryParameters parses query parameters +// into "msg" using current query parser +func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + return currentQueryParser.Parse(msg, values, filter) +} + +// DefaultQueryParser is a QueryParameterParser which implements the default +// query parameters parsing behavior. +// +// See https://github.com/grpc-ecosystem/grpc-gateway/issues/2632 for more context. +type DefaultQueryParser struct{} + +// Parse populates "values" into "msg". +// A value is ignored if its key starts with one of the elements in "filter". +func (*DefaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + for key, values := range values { + if match := valuesKeyRegexp.FindStringSubmatch(key); len(match) == 3 { + key = match[1] + values = append([]string{match[2]}, values...) + } + fieldPath := strings.Split(key, ".") + if filter.HasCommonPrefix(fieldPath) { + continue + } + if err := populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, values); err != nil { + return err + } + } + return nil +} + +// PopulateFieldFromPath sets a value in a nested Protobuf structure. +func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { + fieldPath := strings.Split(fieldPathString, ".") + return populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, []string{value}) +} + +func populateFieldValueFromPath(msgValue protoreflect.Message, fieldPath []string, values []string) error { + if len(fieldPath) < 1 { + return errors.New("no field path") + } + if len(values) < 1 { + return errors.New("no value provided") + } + + var fieldDescriptor protoreflect.FieldDescriptor + for i, fieldName := range fieldPath { + fields := msgValue.Descriptor().Fields() + + // Get field by name + fieldDescriptor = fields.ByName(protoreflect.Name(fieldName)) + if fieldDescriptor == nil { + fieldDescriptor = fields.ByJSONName(fieldName) + if fieldDescriptor == nil { + // We're not returning an error here because this could just be + // an extra query parameter that isn't part of the request. + grpclog.Infof("field not found in %q: %q", msgValue.Descriptor().FullName(), strings.Join(fieldPath, ".")) + return nil + } + } + + // If this is the last element, we're done + if i == len(fieldPath)-1 { + break + } + + // Only singular message fields are allowed + if fieldDescriptor.Message() == nil || fieldDescriptor.Cardinality() == protoreflect.Repeated { + return fmt.Errorf("invalid path: %q is not a message", fieldName) + } + + // Get the nested message + msgValue = msgValue.Mutable(fieldDescriptor).Message() + } + + // Check if oneof already set + if of := fieldDescriptor.ContainingOneof(); of != nil { + if f := msgValue.WhichOneof(of); f != nil { + return fmt.Errorf("field already set for oneof %q", of.FullName().Name()) + } + } + + switch { + case fieldDescriptor.IsList(): + return populateRepeatedField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).List(), values) + case fieldDescriptor.IsMap(): + return populateMapField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).Map(), values) + } + + if len(values) > 1 { + return fmt.Errorf("too many values for field %q: %s", fieldDescriptor.FullName().Name(), strings.Join(values, ", ")) + } + + return populateField(fieldDescriptor, msgValue, values[0]) +} + +func populateField(fieldDescriptor protoreflect.FieldDescriptor, msgValue protoreflect.Message, value string) error { + v, err := parseField(fieldDescriptor, value) + if err != nil { + return fmt.Errorf("parsing field %q: %w", fieldDescriptor.FullName().Name(), err) + } + + msgValue.Set(fieldDescriptor, v) + return nil +} + +func populateRepeatedField(fieldDescriptor protoreflect.FieldDescriptor, list protoreflect.List, values []string) error { + for _, value := range values { + v, err := parseField(fieldDescriptor, value) + if err != nil { + return fmt.Errorf("parsing list %q: %w", fieldDescriptor.FullName().Name(), err) + } + list.Append(v) + } + + return nil +} + +func populateMapField(fieldDescriptor protoreflect.FieldDescriptor, mp protoreflect.Map, values []string) error { + if len(values) != 2 { + return fmt.Errorf("more than one value provided for key %q in map %q", values[0], fieldDescriptor.FullName()) + } + + key, err := parseField(fieldDescriptor.MapKey(), values[0]) + if err != nil { + return fmt.Errorf("parsing map key %q: %w", fieldDescriptor.FullName().Name(), err) + } + + value, err := parseField(fieldDescriptor.MapValue(), values[1]) + if err != nil { + return fmt.Errorf("parsing map value %q: %w", fieldDescriptor.FullName().Name(), err) + } + + mp.Set(key.MapKey(), value) + + return nil +} + +func parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (protoreflect.Value, error) { + switch fieldDescriptor.Kind() { + case protoreflect.BoolKind: + v, err := strconv.ParseBool(value) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfBool(v), nil + case protoreflect.EnumKind: + enum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName()) + if err != nil { + if errors.Is(err, protoregistry.NotFound) { + return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fieldDescriptor.Enum().FullName()) + } + return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err) + } + // Look for enum by name + v := enum.Descriptor().Values().ByName(protoreflect.Name(value)) + if v == nil { + i, err := strconv.Atoi(value) + if err != nil { + return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) + } + // Look for enum by number + if v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i)); v == nil { + return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value) + } + } + return protoreflect.ValueOfEnum(v.Number()), nil + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfInt32(int32(v)), nil + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfInt64(v), nil + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfUint32(uint32(v)), nil + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfUint64(v), nil + case protoreflect.FloatKind: + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfFloat32(float32(v)), nil + case protoreflect.DoubleKind: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfFloat64(v), nil + case protoreflect.StringKind: + return protoreflect.ValueOfString(value), nil + case protoreflect.BytesKind: + v, err := Bytes(value) + if err != nil { + return protoreflect.Value{}, err + } + return protoreflect.ValueOfBytes(v), nil + case protoreflect.MessageKind, protoreflect.GroupKind: + return parseMessage(fieldDescriptor.Message(), value) + default: + panic(fmt.Sprintf("unknown field kind: %v", fieldDescriptor.Kind())) + } +} + +func parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (protoreflect.Value, error) { + var msg proto.Message + switch msgDescriptor.FullName() { + case "google.protobuf.Timestamp": + t, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return protoreflect.Value{}, err + } + msg = timestamppb.New(t) + case "google.protobuf.Duration": + d, err := time.ParseDuration(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = durationpb.New(d) + case "google.protobuf.DoubleValue": + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Double(v) + case "google.protobuf.FloatValue": + v, err := strconv.ParseFloat(value, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Float(float32(v)) + case "google.protobuf.Int64Value": + v, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Int64(v) + case "google.protobuf.Int32Value": + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Int32(int32(v)) + case "google.protobuf.UInt64Value": + v, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.UInt64(v) + case "google.protobuf.UInt32Value": + v, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.UInt32(uint32(v)) + case "google.protobuf.BoolValue": + v, err := strconv.ParseBool(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Bool(v) + case "google.protobuf.StringValue": + msg = wrapperspb.String(value) + case "google.protobuf.BytesValue": + v, err := Bytes(value) + if err != nil { + return protoreflect.Value{}, err + } + msg = wrapperspb.Bytes(v) + case "google.protobuf.FieldMask": + fm := &field_mask.FieldMask{} + fm.Paths = append(fm.Paths, strings.Split(value, ",")...) + msg = fm + case "google.protobuf.Value": + var v structpb.Value + if err := protojson.Unmarshal([]byte(value), &v); err != nil { + return protoreflect.Value{}, err + } + msg = &v + case "google.protobuf.Struct": + var v structpb.Struct + if err := protojson.Unmarshal([]byte(value), &v); err != nil { + return protoreflect.Value{}, err + } + msg = &v + default: + return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName())) + } + + return protoreflect.ValueOfMessage(msg.ProtoReflect()), nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel new file mode 100644 index 00000000000..b8940946577 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "utilities", + srcs = [ + "doc.go", + "pattern.go", + "readerfactory.go", + "string_array_flag.go", + "trie.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", +) + +go_test( + name = "utilities_test", + size = "small", + srcs = [ + "string_array_flag_test.go", + "trie_test.go", + ], + deps = [":utilities"], +) + +alias( + name = "go_default_library", + actual = ":utilities", + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go similarity index 100% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go similarity index 89% rename from vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go rename to vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go index 6dd3854665f..01d26edae3c 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go @@ -3,13 +3,12 @@ package utilities import ( "bytes" "io" - "io/ioutil" ) // IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins // at the start of the stream func IOReaderFactory(r io.Reader) (func() io.Reader, error) { - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return nil, err } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go new file mode 100644 index 00000000000..d224ab776c0 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go @@ -0,0 +1,33 @@ +package utilities + +import ( + "flag" + "strings" +) + +// flagInterface is an cut down interface to `flag` +type flagInterface interface { + Var(value flag.Value, name string, usage string) +} + +// StringArrayFlag defines a flag with the specified name and usage string. +// The return value is the address of a `StringArrayFlags` variable that stores the repeated values of the flag. +func StringArrayFlag(f flagInterface, name string, usage string) *StringArrayFlags { + value := &StringArrayFlags{} + f.Var(value, name, usage) + return value +} + +// StringArrayFlags is a wrapper of `[]string` to provider an interface for `flag.Var` +type StringArrayFlags []string + +// String returns a string representation of `StringArrayFlags` +func (i *StringArrayFlags) String() string { + return strings.Join(*i, ",") +} + +// Set appends a value to `StringArrayFlags` +func (i *StringArrayFlags) Set(value string) error { + *i = append(*i, value) + return nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go new file mode 100644 index 00000000000..dd99b0ed256 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go @@ -0,0 +1,174 @@ +package utilities + +import ( + "sort" +) + +// DoubleArray is a Double Array implementation of trie on sequences of strings. +type DoubleArray struct { + // Encoding keeps an encoding from string to int + Encoding map[string]int + // Base is the base array of Double Array + Base []int + // Check is the check array of Double Array + Check []int +} + +// NewDoubleArray builds a DoubleArray from a set of sequences of strings. +func NewDoubleArray(seqs [][]string) *DoubleArray { + da := &DoubleArray{Encoding: make(map[string]int)} + if len(seqs) == 0 { + return da + } + + encoded := registerTokens(da, seqs) + sort.Sort(byLex(encoded)) + + root := node{row: -1, col: -1, left: 0, right: len(encoded)} + addSeqs(da, encoded, 0, root) + + for i := len(da.Base); i > 0; i-- { + if da.Check[i-1] != 0 { + da.Base = da.Base[:i] + da.Check = da.Check[:i] + break + } + } + return da +} + +func registerTokens(da *DoubleArray, seqs [][]string) [][]int { + var result [][]int + for _, seq := range seqs { + encoded := make([]int, 0, len(seq)) + for _, token := range seq { + if _, ok := da.Encoding[token]; !ok { + da.Encoding[token] = len(da.Encoding) + } + encoded = append(encoded, da.Encoding[token]) + } + result = append(result, encoded) + } + for i := range result { + result[i] = append(result[i], len(da.Encoding)) + } + return result +} + +type node struct { + row, col int + left, right int +} + +func (n node) value(seqs [][]int) int { + return seqs[n.row][n.col] +} + +func (n node) children(seqs [][]int) []*node { + var result []*node + lastVal := int(-1) + last := new(node) + for i := n.left; i < n.right; i++ { + if lastVal == seqs[i][n.col+1] { + continue + } + last.right = i + last = &node{ + row: i, + col: n.col + 1, + left: i, + } + result = append(result, last) + } + last.right = n.right + return result +} + +func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) { + ensureSize(da, pos) + + children := n.children(seqs) + var i int + for i = 1; ; i++ { + ok := func() bool { + for _, child := range children { + code := child.value(seqs) + j := i + code + ensureSize(da, j) + if da.Check[j] != 0 { + return false + } + } + return true + }() + if ok { + break + } + } + da.Base[pos] = i + for _, child := range children { + code := child.value(seqs) + j := i + code + da.Check[j] = pos + 1 + } + terminator := len(da.Encoding) + for _, child := range children { + code := child.value(seqs) + if code == terminator { + continue + } + j := i + code + addSeqs(da, seqs, j, *child) + } +} + +func ensureSize(da *DoubleArray, i int) { + for i >= len(da.Base) { + da.Base = append(da.Base, make([]int, len(da.Base)+1)...) + da.Check = append(da.Check, make([]int, len(da.Check)+1)...) + } +} + +type byLex [][]int + +func (l byLex) Len() int { return len(l) } +func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l byLex) Less(i, j int) bool { + si := l[i] + sj := l[j] + var k int + for k = 0; k < len(si) && k < len(sj); k++ { + if si[k] < sj[k] { + return true + } + if si[k] > sj[k] { + return false + } + } + return k < len(sj) +} + +// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence. +func (da *DoubleArray) HasCommonPrefix(seq []string) bool { + if len(da.Base) == 0 { + return false + } + + var i int + for _, t := range seq { + code, ok := da.Encoding[t] + if !ok { + break + } + j := da.Base[i] + code + if len(da.Check) <= j || da.Check[j] != i+1 { + break + } + i = j + } + j := da.Base[i] + len(da.Encoding) + if len(da.Check) <= j || da.Check[j] != i+1 { + return false + } + return true +} diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go index 9d2d8a4bab9..06a91f0868b 100644 --- a/vendor/github.com/inconshreveable/mousetrap/trap_others.go +++ b/vendor/github.com/inconshreveable/mousetrap/trap_others.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package mousetrap diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go index 336142a5e3e..0c568802164 100644 --- a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go +++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go @@ -1,81 +1,32 @@ -// +build windows -// +build !go1.4 - package mousetrap import ( - "fmt" - "os" "syscall" "unsafe" ) -const ( - // defined by the Win32 API - th32cs_snapprocess uintptr = 0x2 -) - -var ( - kernel = syscall.MustLoadDLL("kernel32.dll") - CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot") - Process32First = kernel.MustFindProc("Process32FirstW") - Process32Next = kernel.MustFindProc("Process32NextW") -) - -// ProcessEntry32 structure defined by the Win32 API -type processEntry32 struct { - dwSize uint32 - cntUsage uint32 - th32ProcessID uint32 - th32DefaultHeapID int - th32ModuleID uint32 - cntThreads uint32 - th32ParentProcessID uint32 - pcPriClassBase int32 - dwFlags uint32 - szExeFile [syscall.MAX_PATH]uint16 -} - -func getProcessEntry(pid int) (pe *processEntry32, err error) { - snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0)) - if snapshot == uintptr(syscall.InvalidHandle) { - err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1) - return +func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) { + snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err } - defer syscall.CloseHandle(syscall.Handle(snapshot)) - - var processEntry processEntry32 - processEntry.dwSize = uint32(unsafe.Sizeof(processEntry)) - ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) - if ok == 0 { - err = fmt.Errorf("Process32First: %v", e1) - return + defer syscall.CloseHandle(snapshot) + var procEntry syscall.ProcessEntry32 + procEntry.Size = uint32(unsafe.Sizeof(procEntry)) + if err = syscall.Process32First(snapshot, &procEntry); err != nil { + return nil, err } - for { - if processEntry.th32ProcessID == uint32(pid) { - pe = &processEntry - return + if procEntry.ProcessID == uint32(pid) { + return &procEntry, nil } - - ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) - if ok == 0 { - err = fmt.Errorf("Process32Next: %v", e1) - return + err = syscall.Process32Next(snapshot, &procEntry) + if err != nil { + return nil, err } } } -func getppid() (pid int, err error) { - pe, err := getProcessEntry(os.Getpid()) - if err != nil { - return - } - - pid = int(pe.th32ParentProcessID) - return -} - // StartedByExplorer returns true if the program was invoked by the user double-clicking // on the executable from explorer.exe // @@ -83,16 +34,9 @@ func getppid() (pid int, err error) { // It does not guarantee that the program was run from a terminal. It only can tell you // whether it was launched from explorer.exe func StartedByExplorer() bool { - ppid, err := getppid() + pe, err := getProcessEntry(syscall.Getppid()) if err != nil { return false } - - pe, err := getProcessEntry(ppid) - if err != nil { - return false - } - - name := syscall.UTF16ToString(pe.szExeFile[:]) - return name == "explorer.exe" + return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:]) } diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go deleted file mode 100644 index 9a28e57c3c3..00000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build windows -// +build go1.4 - -package mousetrap - -import ( - "os" - "syscall" - "unsafe" -) - -func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) { - snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) - if err != nil { - return nil, err - } - defer syscall.CloseHandle(snapshot) - var procEntry syscall.ProcessEntry32 - procEntry.Size = uint32(unsafe.Sizeof(procEntry)) - if err = syscall.Process32First(snapshot, &procEntry); err != nil { - return nil, err - } - for { - if procEntry.ProcessID == uint32(pid) { - return &procEntry, nil - } - err = syscall.Process32Next(snapshot, &procEntry) - if err != nil { - return nil, err - } - } -} - -// StartedByExplorer returns true if the program was invoked by the user double-clicking -// on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -func StartedByExplorer() bool { - pe, err := getProcessEntry(os.Getppid()) - if err != nil { - return false - } - return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:]) -} diff --git a/vendor/github.com/klauspost/compress/.gitignore b/vendor/github.com/klauspost/compress/.gitignore index b35f8449bf2..d31b3781527 100644 --- a/vendor/github.com/klauspost/compress/.gitignore +++ b/vendor/github.com/klauspost/compress/.gitignore @@ -23,3 +23,10 @@ _testmain.go *.test *.prof /s2/cmd/_s2sx/sfx-exe + +# Linux perf files +perf.data +perf.data.old + +# gdb history +.gdb_history diff --git a/vendor/github.com/klauspost/compress/.goreleaser.yml b/vendor/github.com/klauspost/compress/.goreleaser.yml index 0af08e65e68..7a008a4d23e 100644 --- a/vendor/github.com/klauspost/compress/.goreleaser.yml +++ b/vendor/github.com/klauspost/compress/.goreleaser.yml @@ -3,7 +3,7 @@ before: hooks: - ./gen.sh - - go install mvdan.cc/garble@latest + - go install mvdan.cc/garble@v0.9.3 builds: - diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index 0e2dc116ad2..958666ed891 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -9,7 +9,6 @@ This package provides various compression algorithms. * [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding. * [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped requests efficiently. * [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation. -* [fuzz package](https://github.com/klauspost/compress-fuzz) for fuzz testing all compressors/decompressors here. [![Go Reference](https://pkg.go.dev/badge/klauspost/compress.svg)](https://pkg.go.dev/github.com/klauspost/compress?tab=subdirectories) [![Go](https://github.com/klauspost/compress/actions/workflows/go.yml/badge.svg)](https://github.com/klauspost/compress/actions/workflows/go.yml) @@ -17,6 +16,118 @@ This package provides various compression algorithms. # changelog +* Jan 21st, 2023 (v1.15.15) + * deflate: Improve level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/739 + * zstd: Add delta encoding support by @greatroar in https://github.com/klauspost/compress/pull/728 + * zstd: Various speed improvements by @greatroar https://github.com/klauspost/compress/pull/741 https://github.com/klauspost/compress/pull/734 https://github.com/klauspost/compress/pull/736 https://github.com/klauspost/compress/pull/744 https://github.com/klauspost/compress/pull/743 https://github.com/klauspost/compress/pull/745 + * gzhttp: Add SuffixETag() and DropETag() options to prevent ETag collisions on compressed responses by @willbicks in https://github.com/klauspost/compress/pull/740 + +* Jan 3rd, 2023 (v1.15.14) + + * flate: Improve speed in big stateless blocks https://github.com/klauspost/compress/pull/718 + * zstd: Minor speed tweaks by @greatroar in https://github.com/klauspost/compress/pull/716 https://github.com/klauspost/compress/pull/720 + * export NoGzipResponseWriter for custom ResponseWriter wrappers by @harshavardhana in https://github.com/klauspost/compress/pull/722 + * s2: Add example for indexing and existing stream https://github.com/klauspost/compress/pull/723 + +* Dec 11, 2022 (v1.15.13) + * zstd: Add [MaxEncodedSize](https://pkg.go.dev/github.com/klauspost/compress@v1.15.13/zstd#Encoder.MaxEncodedSize) to encoder https://github.com/klauspost/compress/pull/691 + * zstd: Various tweaks and improvements https://github.com/klauspost/compress/pull/693 https://github.com/klauspost/compress/pull/695 https://github.com/klauspost/compress/pull/696 https://github.com/klauspost/compress/pull/701 https://github.com/klauspost/compress/pull/702 https://github.com/klauspost/compress/pull/703 https://github.com/klauspost/compress/pull/704 https://github.com/klauspost/compress/pull/705 https://github.com/klauspost/compress/pull/706 https://github.com/klauspost/compress/pull/707 https://github.com/klauspost/compress/pull/708 + +* Oct 26, 2022 (v1.15.12) + + * zstd: Tweak decoder allocs. https://github.com/klauspost/compress/pull/680 + * gzhttp: Always delete `HeaderNoCompression` https://github.com/klauspost/compress/pull/683 + +* Sept 26, 2022 (v1.15.11) + + * flate: Improve level 1-3 compression https://github.com/klauspost/compress/pull/678 + * zstd: Improve "best" compression by @nightwolfz in https://github.com/klauspost/compress/pull/677 + * zstd: Fix+reduce decompression allocations https://github.com/klauspost/compress/pull/668 + * zstd: Fix non-effective noescape tag https://github.com/klauspost/compress/pull/667 + +* Sept 16, 2022 (v1.15.10) + + * zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649 + * Add Go 1.19 - deprecate Go 1.16 https://github.com/klauspost/compress/pull/651 + * flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656 + * zstd: Improve "better" compresssion https://github.com/klauspost/compress/pull/657 + * s2: Improve "best" compression https://github.com/klauspost/compress/pull/658 + * s2: Improve "better" compression. https://github.com/klauspost/compress/pull/635 + * s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646 + * Use arrays for constant size copies https://github.com/klauspost/compress/pull/659 + +* July 21, 2022 (v1.15.9) + + * zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645 + * zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644 + * zstd: Allow single segments up to "max decoded size" by @klauspost in https://github.com/klauspost/compress/pull/643 + +* July 13, 2022 (v1.15.8) + + * gzip: fix stack exhaustion bug in Reader.Read https://github.com/klauspost/compress/pull/641 + * s2: Add Index header trim/restore https://github.com/klauspost/compress/pull/638 + * zstd: Optimize seqdeq amd64 asm by @greatroar in https://github.com/klauspost/compress/pull/636 + * zstd: Improve decoder memcopy https://github.com/klauspost/compress/pull/637 + * huff0: Pass a single bitReader pointer to asm by @greatroar in https://github.com/klauspost/compress/pull/634 + * zstd: Branchless getBits for amd64 w/o BMI2 by @greatroar in https://github.com/klauspost/compress/pull/640 + * gzhttp: Remove header before writing https://github.com/klauspost/compress/pull/639 + +* June 29, 2022 (v1.15.7) + + * s2: Fix absolute forward seeks https://github.com/klauspost/compress/pull/633 + * zip: Merge upstream https://github.com/klauspost/compress/pull/631 + * zip: Re-add zip64 fix https://github.com/klauspost/compress/pull/624 + * zstd: translate fseDecoder.buildDtable into asm by @WojciechMula in https://github.com/klauspost/compress/pull/598 + * flate: Faster histograms https://github.com/klauspost/compress/pull/620 + * deflate: Use compound hcode https://github.com/klauspost/compress/pull/622 + +* June 3, 2022 (v1.15.6) + * s2: Improve coding for long, close matches https://github.com/klauspost/compress/pull/613 + * s2c: Add Snappy/S2 stream recompression https://github.com/klauspost/compress/pull/611 + * zstd: Always use configured block size https://github.com/klauspost/compress/pull/605 + * zstd: Fix incorrect hash table placement for dict encoding in default https://github.com/klauspost/compress/pull/606 + * zstd: Apply default config to ZipDecompressor without options https://github.com/klauspost/compress/pull/608 + * gzhttp: Exclude more common archive formats https://github.com/klauspost/compress/pull/612 + * s2: Add ReaderIgnoreCRC https://github.com/klauspost/compress/pull/609 + * s2: Remove sanity load on index creation https://github.com/klauspost/compress/pull/607 + * snappy: Use dedicated function for scoring https://github.com/klauspost/compress/pull/614 + * s2c+s2d: Use official snappy framed extension https://github.com/klauspost/compress/pull/610 + +* May 25, 2022 (v1.15.5) + * s2: Add concurrent stream decompression https://github.com/klauspost/compress/pull/602 + * s2: Fix final emit oob read crash on amd64 https://github.com/klauspost/compress/pull/601 + * huff0: asm implementation of Decompress1X by @WojciechMula https://github.com/klauspost/compress/pull/596 + * zstd: Use 1 less goroutine for stream decoding https://github.com/klauspost/compress/pull/588 + * zstd: Copy literal in 16 byte blocks when possible https://github.com/klauspost/compress/pull/592 + * zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599 + * zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593 + * huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586 + * flate: Inplace hashing for level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/590 + + +* May 11, 2022 (v1.15.4) + * huff0: decompress directly into output by @WojciechMula in [#577](https://github.com/klauspost/compress/pull/577) + * inflate: Keep dict on stack [#581](https://github.com/klauspost/compress/pull/581) + * zstd: Faster decoding memcopy in asm [#583](https://github.com/klauspost/compress/pull/583) + * zstd: Fix ignored crc [#580](https://github.com/klauspost/compress/pull/580) + +* May 5, 2022 (v1.15.3) + * zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572) + * s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575) + +* Apr 26, 2022 (v1.15.2) + * zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster. [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537) + * zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539) + * s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555) + * Minimum version is Go 1.16, added CI test on 1.18. + +* Mar 11, 2022 (v1.15.1) + * huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512) + * zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514) + * zstd: Detect extra block data and report as corrupted in [#520](https://github.com/klauspost/compress/pull/520) + * zstd: Handle zero sized frame content size stricter in [#521](https://github.com/klauspost/compress/pull/521) + * zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523) + * Mar 3, 2022 (v1.15.0) * zstd: Refactor decoder by @klauspost in [#498](https://github.com/klauspost/compress/pull/498) * zstd: Add stream encoding without goroutines by @klauspost in [#505](https://github.com/klauspost/compress/pull/505) @@ -25,15 +136,15 @@ This package provides various compression algorithms. * gzhttp: Add zstd to transport by @klauspost in [#400](https://github.com/klauspost/compress/pull/400) * gzhttp: Make content-type optional by @klauspost in [#510](https://github.com/klauspost/compress/pull/510) -
- See Details Both compression and decompression now supports "synchronous" stream operations. This means that whenever "concurrency" is set to 1, they will operate without spawning goroutines. Stream decompression is now faster on asynchronous, since the goroutine allocation much more effectively splits the workload. On typical streams this will typically use 2 cores fully for decompression. When a stream has finished decoding no goroutines will be left over, so decoders can now safely be pooled and still be garbage collected. While the release has been extensively tested, it is recommended to testing when upgrading. -
+
+ See changes to v1.14.x + * Feb 22, 2022 (v1.14.4) * flate: Fix rare huffman only (-2) corruption. [#503](https://github.com/klauspost/compress/pull/503) * zip: Update deprecated CreateHeaderRaw to correctly call CreateRaw by @saracen in [#502](https://github.com/klauspost/compress/pull/502) @@ -59,7 +170,11 @@ While the release has been extensively tested, it is recommended to testing when * zstd: Performance improvement in [#420]( https://github.com/klauspost/compress/pull/420) [#456](https://github.com/klauspost/compress/pull/456) [#437](https://github.com/klauspost/compress/pull/437) [#467](https://github.com/klauspost/compress/pull/467) [#468](https://github.com/klauspost/compress/pull/468) * zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464) * Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445) +
+
+ See changes to v1.13.x + * Aug 30, 2021 (v1.13.5) * gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425) * s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413) @@ -88,6 +203,8 @@ While the release has been extensively tested, it is recommended to testing when * Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors. * zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382) * zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380) +
+
See changes to v1.12.x diff --git a/vendor/github.com/klauspost/compress/fse/compress.go b/vendor/github.com/klauspost/compress/fse/compress.go index 6f341914c67..dac97e58a2d 100644 --- a/vendor/github.com/klauspost/compress/fse/compress.go +++ b/vendor/github.com/klauspost/compress/fse/compress.go @@ -146,54 +146,51 @@ func (s *Scratch) compress(src []byte) error { c1.encodeZero(tt[src[ip-2]]) ip -= 2 } + src = src[:ip] // Main compression loop. switch { case !s.zeroBits && s.actualTableLog <= 8: // We can encode 4 symbols without requiring a flush. // We do not need to check if any output is 0 bits. - for ip >= 4 { + for ; len(src) >= 4; src = src[:len(src)-4] { s.bw.flush32() - v3, v2, v1, v0 := src[ip-4], src[ip-3], src[ip-2], src[ip-1] + v3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1] c2.encode(tt[v0]) c1.encode(tt[v1]) c2.encode(tt[v2]) c1.encode(tt[v3]) - ip -= 4 } case !s.zeroBits: // We do not need to check if any output is 0 bits. - for ip >= 4 { + for ; len(src) >= 4; src = src[:len(src)-4] { s.bw.flush32() - v3, v2, v1, v0 := src[ip-4], src[ip-3], src[ip-2], src[ip-1] + v3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1] c2.encode(tt[v0]) c1.encode(tt[v1]) s.bw.flush32() c2.encode(tt[v2]) c1.encode(tt[v3]) - ip -= 4 } case s.actualTableLog <= 8: // We can encode 4 symbols without requiring a flush - for ip >= 4 { + for ; len(src) >= 4; src = src[:len(src)-4] { s.bw.flush32() - v3, v2, v1, v0 := src[ip-4], src[ip-3], src[ip-2], src[ip-1] + v3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1] c2.encodeZero(tt[v0]) c1.encodeZero(tt[v1]) c2.encodeZero(tt[v2]) c1.encodeZero(tt[v3]) - ip -= 4 } default: - for ip >= 4 { + for ; len(src) >= 4; src = src[:len(src)-4] { s.bw.flush32() - v3, v2, v1, v0 := src[ip-4], src[ip-3], src[ip-2], src[ip-1] + v3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1] c2.encodeZero(tt[v0]) c1.encodeZero(tt[v1]) s.bw.flush32() c2.encodeZero(tt[v2]) c1.encodeZero(tt[v3]) - ip -= 4 } } @@ -459,15 +456,17 @@ func (s *Scratch) countSimple(in []byte) (max int) { for _, v := range in { s.count[v]++ } - m := uint32(0) + m, symlen := uint32(0), s.symbolLen for i, v := range s.count[:] { + if v == 0 { + continue + } if v > m { m = v } - if v > 0 { - s.symbolLen = uint16(i) + 1 - } + symlen = uint16(i) + 1 } + s.symbolLen = symlen return int(m) } diff --git a/vendor/github.com/klauspost/compress/huff0/autogen.go b/vendor/github.com/klauspost/compress/huff0/autogen.go deleted file mode 100644 index ff2c69d60cf..00000000000 --- a/vendor/github.com/klauspost/compress/huff0/autogen.go +++ /dev/null @@ -1,5 +0,0 @@ -package huff0 - -//go:generate go run generate.go -//go:generate asmfmt -w decompress_amd64.s -//go:generate asmfmt -w decompress_8b_amd64.s diff --git a/vendor/github.com/klauspost/compress/huff0/bitreader.go b/vendor/github.com/klauspost/compress/huff0/bitreader.go index 451160edda3..e36d9742f94 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitreader.go +++ b/vendor/github.com/klauspost/compress/huff0/bitreader.go @@ -67,7 +67,6 @@ func (b *bitReaderBytes) fillFast() { // 2 bounds checks. v := b.in[b.off-4 : b.off] - v = v[:4] low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) b.value |= uint64(low) << (b.bitsRead - 32) b.bitsRead -= 32 @@ -88,8 +87,7 @@ func (b *bitReaderBytes) fill() { return } if b.off > 4 { - v := b.in[b.off-4:] - v = v[:4] + v := b.in[b.off-4 : b.off] low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) b.value |= uint64(low) << (b.bitsRead - 32) b.bitsRead -= 32 @@ -165,11 +163,6 @@ func (b *bitReaderShifted) peekBitsFast(n uint8) uint16 { return uint16(b.value >> ((64 - n) & 63)) } -// peekTopBits(n) is equvialent to peekBitFast(64 - n) -func (b *bitReaderShifted) peekTopBits(n uint8) uint16 { - return uint16(b.value >> n) -} - func (b *bitReaderShifted) advance(n uint8) { b.bitsRead += n b.value <<= n & 63 @@ -184,7 +177,6 @@ func (b *bitReaderShifted) fillFast() { // 2 bounds checks. v := b.in[b.off-4 : b.off] - v = v[:4] low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) b.value |= uint64(low) << ((b.bitsRead - 32) & 63) b.bitsRead -= 32 @@ -205,8 +197,7 @@ func (b *bitReaderShifted) fill() { return } if b.off > 4 { - v := b.in[b.off-4:] - v = v[:4] + v := b.in[b.off-4 : b.off] low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) b.value |= uint64(low) << ((b.bitsRead - 32) & 63) b.bitsRead -= 32 @@ -220,11 +211,6 @@ func (b *bitReaderShifted) fill() { } } -// finished returns true if all bits have been read from the bit stream. -func (b *bitReaderShifted) finished() bool { - return b.off == 0 && b.bitsRead >= 64 -} - func (b *bitReaderShifted) remaining() uint { return b.off*8 + uint(64-b.bitsRead) } diff --git a/vendor/github.com/klauspost/compress/huff0/bitwriter.go b/vendor/github.com/klauspost/compress/huff0/bitwriter.go index 6bce4e87d4f..ec71f7a349a 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitwriter.go +++ b/vendor/github.com/klauspost/compress/huff0/bitwriter.go @@ -5,8 +5,6 @@ package huff0 -import "fmt" - // bitWriter will write bits. // First bit will be LSB of the first byte of output. type bitWriter struct { @@ -23,14 +21,6 @@ var bitMask16 = [32]uint16{ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF} /* up to 16 bits */ -// addBits16NC will add up to 16 bits. -// It will not check if there is space for them, -// so the caller must ensure that it has flushed recently. -func (b *bitWriter) addBits16NC(value uint16, bits uint8) { - b.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63) - b.nBits += bits -} - // addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated. // It will not check if there is space for them, so the caller must ensure that it has flushed recently. func (b *bitWriter) addBits16Clean(value uint16, bits uint8) { @@ -70,104 +60,6 @@ func (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) { b.nBits += encA.nBits + encB.nBits } -// addBits16ZeroNC will add up to 16 bits. -// It will not check if there is space for them, -// so the caller must ensure that it has flushed recently. -// This is fastest if bits can be zero. -func (b *bitWriter) addBits16ZeroNC(value uint16, bits uint8) { - if bits == 0 { - return - } - value <<= (16 - bits) & 15 - value >>= (16 - bits) & 15 - b.bitContainer |= uint64(value) << (b.nBits & 63) - b.nBits += bits -} - -// flush will flush all pending full bytes. -// There will be at least 56 bits available for writing when this has been called. -// Using flush32 is faster, but leaves less space for writing. -func (b *bitWriter) flush() { - v := b.nBits >> 3 - switch v { - case 0: - return - case 1: - b.out = append(b.out, - byte(b.bitContainer), - ) - b.bitContainer >>= 1 << 3 - case 2: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - ) - b.bitContainer >>= 2 << 3 - case 3: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - ) - b.bitContainer >>= 3 << 3 - case 4: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - ) - b.bitContainer >>= 4 << 3 - case 5: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - ) - b.bitContainer >>= 5 << 3 - case 6: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - ) - b.bitContainer >>= 6 << 3 - case 7: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - ) - b.bitContainer >>= 7 << 3 - case 8: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - byte(b.bitContainer>>56), - ) - b.bitContainer = 0 - b.nBits = 0 - return - default: - panic(fmt.Errorf("bits (%d) > 64", b.nBits)) - } - b.nBits &= 7 -} - // flush32 will flush out, so there are at least 32 bits available for writing. func (b *bitWriter) flush32() { if b.nBits < 32 { @@ -201,10 +93,3 @@ func (b *bitWriter) close() error { b.flushAlign() return nil } - -// reset and continue writing by appending to out. -func (b *bitWriter) reset(out []byte) { - b.bitContainer = 0 - b.nBits = 0 - b.out = out -} diff --git a/vendor/github.com/klauspost/compress/huff0/bytereader.go b/vendor/github.com/klauspost/compress/huff0/bytereader.go index 50bcdf6ea99..4dcab8d2327 100644 --- a/vendor/github.com/klauspost/compress/huff0/bytereader.go +++ b/vendor/github.com/klauspost/compress/huff0/bytereader.go @@ -20,11 +20,6 @@ func (b *byteReader) init(in []byte) { b.off = 0 } -// advance the stream b n bytes. -func (b *byteReader) advance(n uint) { - b.off += int(n) -} - // Int32 returns a little endian int32 starting at current offset. func (b byteReader) Int32() int32 { v3 := int32(b.b[b.off+3]) @@ -43,11 +38,6 @@ func (b byteReader) Uint32() uint32 { return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0 } -// unread returns the unread portion of the input. -func (b byteReader) unread() []byte { - return b.b[b.off:] -} - // remain will return the number of bytes remaining. func (b byteReader) remain() int { return len(b.b) - b.off diff --git a/vendor/github.com/klauspost/compress/huff0/compress.go b/vendor/github.com/klauspost/compress/huff0/compress.go index bc95ac623bd..cdc94856f2c 100644 --- a/vendor/github.com/klauspost/compress/huff0/compress.go +++ b/vendor/github.com/klauspost/compress/huff0/compress.go @@ -365,29 +365,29 @@ func (s *Scratch) countSimple(in []byte) (max int, reuse bool) { m := uint32(0) if len(s.prevTable) > 0 { for i, v := range s.count[:] { + if v == 0 { + continue + } if v > m { m = v } - if v > 0 { - s.symbolLen = uint16(i) + 1 - if i >= len(s.prevTable) { - reuse = false - } else { - if s.prevTable[i].nBits == 0 { - reuse = false - } - } + s.symbolLen = uint16(i) + 1 + if i >= len(s.prevTable) { + reuse = false + } else if s.prevTable[i].nBits == 0 { + reuse = false } } return int(m), reuse } for i, v := range s.count[:] { + if v == 0 { + continue + } if v > m { m = v } - if v > 0 { - s.symbolLen = uint16(i) + 1 - } + s.symbolLen = uint16(i) + 1 } return int(m), false } @@ -404,6 +404,7 @@ func (s *Scratch) canUseTable(c cTable) bool { return true } +//lint:ignore U1000 used for debugging func (s *Scratch) validateTable(c cTable) bool { if len(c) < int(s.symbolLen) { return false @@ -483,34 +484,35 @@ func (s *Scratch) buildCTable() error { // Different from reference implementation. huffNode0 := s.nodes[0 : huffNodesLen+1] - for huffNode[nonNullRank].count == 0 { + for huffNode[nonNullRank].count() == 0 { nonNullRank-- } lowS := int16(nonNullRank) nodeRoot := nodeNb + lowS - 1 lowN := nodeNb - huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count - huffNode[lowS].parent, huffNode[lowS-1].parent = uint16(nodeNb), uint16(nodeNb) + huffNode[nodeNb].setCount(huffNode[lowS].count() + huffNode[lowS-1].count()) + huffNode[lowS].setParent(nodeNb) + huffNode[lowS-1].setParent(nodeNb) nodeNb++ lowS -= 2 for n := nodeNb; n <= nodeRoot; n++ { - huffNode[n].count = 1 << 30 + huffNode[n].setCount(1 << 30) } // fake entry, strong barrier - huffNode0[0].count = 1 << 31 + huffNode0[0].setCount(1 << 31) // create parents for nodeNb <= nodeRoot { var n1, n2 int16 - if huffNode0[lowS+1].count < huffNode0[lowN+1].count { + if huffNode0[lowS+1].count() < huffNode0[lowN+1].count() { n1 = lowS lowS-- } else { n1 = lowN lowN++ } - if huffNode0[lowS+1].count < huffNode0[lowN+1].count { + if huffNode0[lowS+1].count() < huffNode0[lowN+1].count() { n2 = lowS lowS-- } else { @@ -518,18 +520,19 @@ func (s *Scratch) buildCTable() error { lowN++ } - huffNode[nodeNb].count = huffNode0[n1+1].count + huffNode0[n2+1].count - huffNode0[n1+1].parent, huffNode0[n2+1].parent = uint16(nodeNb), uint16(nodeNb) + huffNode[nodeNb].setCount(huffNode0[n1+1].count() + huffNode0[n2+1].count()) + huffNode0[n1+1].setParent(nodeNb) + huffNode0[n2+1].setParent(nodeNb) nodeNb++ } // distribute weights (unlimited tree height) - huffNode[nodeRoot].nbBits = 0 + huffNode[nodeRoot].setNbBits(0) for n := nodeRoot - 1; n >= startNode; n-- { - huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1 + huffNode[n].setNbBits(huffNode[huffNode[n].parent()].nbBits() + 1) } for n := uint16(0); n <= nonNullRank; n++ { - huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1 + huffNode[n].setNbBits(huffNode[huffNode[n].parent()].nbBits() + 1) } s.actualTableLog = s.setMaxHeight(int(nonNullRank)) maxNbBits := s.actualTableLog @@ -541,7 +544,7 @@ func (s *Scratch) buildCTable() error { var nbPerRank [tableLogMax + 1]uint16 var valPerRank [16]uint16 for _, v := range huffNode[:nonNullRank+1] { - nbPerRank[v.nbBits]++ + nbPerRank[v.nbBits()]++ } // determine stating value per rank { @@ -556,7 +559,7 @@ func (s *Scratch) buildCTable() error { // push nbBits per symbol, symbol order for _, v := range huffNode[:nonNullRank+1] { - s.cTable[v.symbol].nBits = v.nbBits + s.cTable[v.symbol()].nBits = v.nbBits() } // assign value within rank, symbol order @@ -602,12 +605,12 @@ func (s *Scratch) huffSort() { pos := rank[r].current rank[r].current++ prev := nodes[(pos-1)&huffNodesMask] - for pos > rank[r].base && c > prev.count { + for pos > rank[r].base && c > prev.count() { nodes[pos&huffNodesMask] = prev pos-- prev = nodes[(pos-1)&huffNodesMask] } - nodes[pos&huffNodesMask] = nodeElt{count: c, symbol: byte(n)} + nodes[pos&huffNodesMask] = makeNodeElt(c, byte(n)) } } @@ -616,7 +619,7 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { huffNode := s.nodes[1 : huffNodesLen+1] //huffNode = huffNode[: huffNodesLen] - largestBits := huffNode[lastNonNull].nbBits + largestBits := huffNode[lastNonNull].nbBits() // early exit : no elt > maxNbBits if largestBits <= maxNbBits { @@ -626,14 +629,14 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { baseCost := int(1) << (largestBits - maxNbBits) n := uint32(lastNonNull) - for huffNode[n].nbBits > maxNbBits { - totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)) - huffNode[n].nbBits = maxNbBits + for huffNode[n].nbBits() > maxNbBits { + totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits())) + huffNode[n].setNbBits(maxNbBits) n-- } // n stops at huffNode[n].nbBits <= maxNbBits - for huffNode[n].nbBits == maxNbBits { + for huffNode[n].nbBits() == maxNbBits { n-- } // n end at index of smallest symbol using < maxNbBits @@ -654,10 +657,10 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { { currentNbBits := maxNbBits for pos := int(n); pos >= 0; pos-- { - if huffNode[pos].nbBits >= currentNbBits { + if huffNode[pos].nbBits() >= currentNbBits { continue } - currentNbBits = huffNode[pos].nbBits // < maxNbBits + currentNbBits = huffNode[pos].nbBits() // < maxNbBits rankLast[maxNbBits-currentNbBits] = uint32(pos) } } @@ -674,8 +677,8 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { if lowPos == noSymbol { break } - highTotal := huffNode[highPos].count - lowTotal := 2 * huffNode[lowPos].count + highTotal := huffNode[highPos].count() + lowTotal := 2 * huffNode[lowPos].count() if highTotal <= lowTotal { break } @@ -691,13 +694,14 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { // this rank is no longer empty rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease] } - huffNode[rankLast[nBitsToDecrease]].nbBits++ + huffNode[rankLast[nBitsToDecrease]].setNbBits(1 + + huffNode[rankLast[nBitsToDecrease]].nbBits()) if rankLast[nBitsToDecrease] == 0 { /* special case, reached largest symbol */ rankLast[nBitsToDecrease] = noSymbol } else { rankLast[nBitsToDecrease]-- - if huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease { + if huffNode[rankLast[nBitsToDecrease]].nbBits() != maxNbBits-nBitsToDecrease { rankLast[nBitsToDecrease] = noSymbol /* this rank is now empty */ } } @@ -705,15 +709,15 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { for totalCost < 0 { /* Sometimes, cost correction overshoot */ if rankLast[1] == noSymbol { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */ - for huffNode[n].nbBits == maxNbBits { + for huffNode[n].nbBits() == maxNbBits { n-- } - huffNode[n+1].nbBits-- + huffNode[n+1].setNbBits(huffNode[n+1].nbBits() - 1) rankLast[1] = n + 1 totalCost++ continue } - huffNode[rankLast[1]+1].nbBits-- + huffNode[rankLast[1]+1].setNbBits(huffNode[rankLast[1]+1].nbBits() - 1) rankLast[1]++ totalCost++ } @@ -721,9 +725,26 @@ func (s *Scratch) setMaxHeight(lastNonNull int) uint8 { return maxNbBits } -type nodeElt struct { - count uint32 - parent uint16 - symbol byte - nbBits uint8 +// A nodeElt is the fields +// +// count uint32 +// parent uint16 +// symbol byte +// nbBits uint8 +// +// in some order, all squashed into an integer so that the compiler +// always loads and stores entire nodeElts instead of separate fields. +type nodeElt uint64 + +func makeNodeElt(count uint32, symbol byte) nodeElt { + return nodeElt(count) | nodeElt(symbol)<<48 } + +func (e *nodeElt) count() uint32 { return uint32(*e) } +func (e *nodeElt) parent() uint16 { return uint16(*e >> 32) } +func (e *nodeElt) symbol() byte { return byte(*e >> 48) } +func (e *nodeElt) nbBits() uint8 { return uint8(*e >> 56) } + +func (e *nodeElt) setCount(c uint32) { *e = (*e)&0xffffffff00000000 | nodeElt(c) } +func (e *nodeElt) setParent(p int16) { *e = (*e)&0xffff0000ffffffff | nodeElt(uint16(p))<<32 } +func (e *nodeElt) setNbBits(n uint8) { *e = (*e)&0x00ffffffffffffff | nodeElt(n)<<56 } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go index 04f6529955e..3c0b398c72e 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress.go @@ -11,7 +11,6 @@ import ( type dTable struct { single []dEntrySingle - double []dEntryDouble } // single-symbols decoding @@ -19,13 +18,6 @@ type dEntrySingle struct { entry uint16 } -// double-symbols decoding -type dEntryDouble struct { - seq [4]byte - nBits uint8 - len uint8 -} - // Uses special code for all tables that are < 8 bits. const use8BitTables = true @@ -35,7 +27,7 @@ const use8BitTables = true // If no Scratch is provided a new one is allocated. // The returned Scratch can be used for encoding or decoding input using this table. func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) { - s, err = s.prepare(in) + s, err = s.prepare(nil) if err != nil { return s, nil, err } @@ -69,7 +61,7 @@ func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) { b, err := fse.Decompress(in[:iSize], s.fse) s.fse.Out = nil if err != nil { - return s, nil, err + return s, nil, fmt.Errorf("fse decompress returned: %w", err) } if len(b) > 255 { return s, nil, errors.New("corrupt input: output table too large") @@ -236,108 +228,6 @@ func (d *Decoder) buffer() *[4][256]byte { return &[4][256]byte{} } -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if use8BitTables && d.actualTableLog <= 8 { - return d.decompress1X8Bit(dst, src) - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:0] - - // Avoid bounds check by always having full sized table. - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - dt := d.dt.single[:tlSize] - - // Use temp table to avoid bound checks/append penalty. - bufs := d.buffer() - buf := &bufs[0] - var off uint8 - - for br.off >= 8 { - br.fillFast() - v := dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+0] = uint8(v.entry >> 8) - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+1] = uint8(v.entry >> 8) - - // Refill - br.fillFast() - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+2] = uint8(v.entry >> 8) - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+3] = uint8(v.entry >> 8) - - off += 4 - if off == 0 { - if len(dst)+256 > maxDecodedSize { - br.close() - d.bufs.Put(bufs) - return nil, ErrMaxDecodedSizeExceeded - } - dst = append(dst, buf[:]...) - } - } - - if len(dst)+int(off) > maxDecodedSize { - d.bufs.Put(bufs) - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - dst = append(dst, buf[:off]...) - - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if false && br.bitsRead >= 32 { - if br.off >= 4 { - v := br.in[br.off-4:] - v = v[:4] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - br.value = (br.value << 32) | uint64(low) - br.bitsRead -= 32 - br.off -= 4 - } else { - for br.off > 0 { - br.value = (br.value << 8) | uint64(br.in[br.off-1]) - br.bitsRead -= 8 - br.off-- - } - } - } - if len(dst) >= maxDecodedSize { - d.bufs.Put(bufs) - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) - } - d.bufs.Put(bufs) - return dst, br.close() -} - // decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8. // The cap of the output buffer will be the maximum decompressed size. // The length of the supplied input must match the end of a block exactly. @@ -873,17 +763,20 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { @@ -995,7 +888,6 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { const shift = 56 const tlSize = 1 << 8 - const tlMask = tlSize - 1 single := d.dt.single[:tlSize] // Use temp table to avoid bound checks/append penalty. @@ -1108,17 +1000,22 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + // copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s deleted file mode 100644 index 0d6cb1a962b..00000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s +++ /dev/null @@ -1,488 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: - - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill0: - - // val0 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) - - // SECOND PART: - // val2 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 0+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) - - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill1: - - // val0 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) - - // SECOND PART: - // val2 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 256+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) - - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill2: - - // val0 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) - - // SECOND PART: - // val2 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 512+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) - - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill3 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill3: - - // val0 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) - - // SECOND PART: - // val2 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 768+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop - -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET - -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in deleted file mode 100644 index 6d477a2c11e..00000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in +++ /dev/null @@ -1,197 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // SECOND PART: - // val2 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, {{ var "bufofs" }}+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index d47f6644f3f..ba7e8e6b027 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -2,30 +2,42 @@ // +build amd64,!appengine,!noasm,gc // This file contains the specialisation of Decoder.Decompress4X -// that uses an asm implementation of its main loop. +// and Decoder.Decompress1X that use an asm implementation of thir main loops. package huff0 import ( "errors" "fmt" + + "github.com/klauspost/compress/internal/cpuinfo" ) // decompress4x_main_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog > 8. -// go:noescape -func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +// +//go:noescape +func decompress4x_main_loop_amd64(ctx *decompress4xContext) // decompress4x_8b_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. -// go:noescape -func decompress4x_8b_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +// +//go:noescape +func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) // fallback8BitSize is the size where using Go version is faster. const fallback8BitSize = 800 +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + // Decompress4X will decompress a 4X encoded stream. // The length of the supplied input must match the end of a block exactly. // The *capacity* of the dst slice must match the destination size of @@ -42,6 +54,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { if cap(dst) < fallback8BitSize && use8BitTables { return d.decompress4X8bit(dst, src) } + var br [4]bitReaderShifted // Decode "jump table" start := 6 @@ -71,70 +84,25 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { const tlMask = tlSize - 1 single := d.dt.single[:tlSize] - // Use temp table to avoid bound checks/append penalty. - buf := d.buffer() - var off uint8 var decoded int - const debug = false - - // see: bitReaderShifted.peekBitsFast() - peekBits := uint8((64 - d.actualTableLog) & 63) - - // Decode 2 values from each decoder/loop. - const bufoff = 256 - for { - if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 { - break + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. } - if use8BitTables { - off = decompress4x_8b_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) + decompress4x_8b_main_loop_amd64(&ctx) } else { - off = decompress4x_main_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) - } - if debug { - fmt.Print("DEBUG: ") - fmt.Printf("off=%d,", off) - for i := 0; i < 4; i++ { - fmt.Printf(" br[%d]={bitsRead=%d, value=%x, off=%d}", - i, br[i].bitsRead, br[i].value, br[i].off) - } - fmt.Println("") - } - - if off != 0 { - break + decompress4x_main_loop_amd64(&ctx) } - if bufoff > dstEvery { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 1") - } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 - // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 2") - } - } - if off > 0 { - ioff := int(off) - if len(out) < dstEvery*3+ioff { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 3") - } - copy(out, buf[0][:off]) - copy(out[dstEvery:], buf[1][:off]) - copy(out[dstEvery*2:], buf[2][:off]) - copy(out[dstEvery*3:], buf[3][:off]) - decoded += int(off) * 4 - out = out[off:] + decoded = ctx.decoded + out = out[decoded/4:] } // Decode remaining. @@ -150,7 +118,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { for bitsLeft > 0 { br.fill() if offset >= endsAt { - d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 4") } @@ -164,7 +131,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { offset++ } if offset != endsAt { - d.bufs.Put(buf) return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) } decoded += offset - dstEvery*i @@ -173,9 +139,88 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { return nil, err } } - d.bufs.Put(buf) if dstSize != decoded { return nil, errors.New("corruption detected: short output block") } return dst, nil } + +// decompress4x_main_loop_x86 is an x86 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_amd64(ctx *decompress1xContext) + +// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_bmi2(ctx *decompress1xContext) + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(&ctx) + } else { + decompress1x_main_loop_amd64(&ctx) + } + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index 2edad3ea5a4..c4c7ab2d1fe 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,506 +1,830 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - +// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. + +//go:build amd64 && !appengine && !noasm && gc + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_amd64(SB), $0-8 + // Preload values + MOVQ ctx+0(FP), AX + MOVBQZX 8(AX), DI + MOVQ 16(AX), BX + MOVQ 48(AX), SI + MOVQ 24(AX), R8 + MOVQ 32(AX), R9 + MOVQ (AX), R10 + + // Main loop main_loop: - - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX + XORL DX, DX + CMPQ BX, SI + SETGE DL + + // br0.fillFast32() + MOVQ 32(R10), R11 + MOVBQZX 40(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill0 + MOVQ 24(R10), AX + SUBQ $0x20, R12 + SUBQ $0x04, AX + MOVQ (R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif + MOVL (AX)(R13*1), R13 + MOVQ R12, CX + SHLQ CL, R13 + MOVQ AX, 24(R10) + ORQ R13, R11 - ORQ AX, br_value + // exhausted += (br0.off < 4) + CMPQ AX, $0x04 + ADCB $+0, DL - // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } skip_fill0: - // val0 := br0.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + MOVW (R9)(R13*2), CX -#endif + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R11, R13 + SHRQ CL, R13 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(R13*2), CX // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) - - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (BX) + + // update the bitreader structure + MOVQ R11, 32(R10) + MOVB R12, 40(R10) + + // br1.fillFast32() + MOVQ 80(R10), R11 + MOVBQZX 88(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill1 + MOVQ 72(R10), AX + SUBQ $0x20, R12 + SUBQ $0x04, AX + MOVQ 48(R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX + MOVL (AX)(R13*1), R13 + MOVQ R12, CX + SHLQ CL, R13 + MOVQ AX, 72(R10) + ORQ R13, R11 -#endif + // exhausted += (br1.off < 4) + CMPQ AX, $0x04 + ADCB $+0, DL - ORQ AX, br_value - - // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } skip_fill1: - // val0 := br1.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + MOVW (R9)(R13*2), CX -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R11, R13 + SHRQ CL, R13 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(R13*2), CX // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) - - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (BX)(R8*1) + + // update the bitreader structure + MOVQ R11, 80(R10) + MOVB R12, 88(R10) + + // br2.fillFast32() + MOVQ 128(R10), R11 + MOVBQZX 136(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill2 + MOVQ 120(R10), AX + SUBQ $0x20, R12 + SUBQ $0x04, AX + MOVQ 96(R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) + MOVL (AX)(R13*1), R13 + MOVQ R12, CX + SHLQ CL, R13 + MOVQ AX, 120(R10) + ORQ R13, R11 -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX + // exhausted += (br2.off < 4) + CMPQ AX, $0x04 + ADCB $+0, DL -#endif - - ORQ AX, br_value - - // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } skip_fill2: - // val0 := br2.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R9)(R13*2), CX - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R11, R13 + SHRQ CL, R13 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R9)(R13*2), CX // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (BX)(R8*2) + + // update the bitreader structure + MOVQ R11, 128(R10) + MOVB R12, 136(R10) + + // br3.fillFast32() + MOVQ 176(R10), R11 + MOVBQZX 184(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill3 + MOVQ 168(R10), AX + SUBQ $0x20, R12 + SUBQ $0x04, AX + MOVQ 144(R10), R13 -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (AX)(R13*1), R13 + MOVQ R12, CX + SHLQ CL, R13 + MOVQ AX, 168(R10) + ORQ R13, R11 -#endif + // exhausted += (br3.off < 4) + CMPQ AX, $0x04 + ADCB $+0, DL - ADDQ CX, br_bits_read // bits_read += n +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) + // v0 := table[val0&mask] + MOVW (R9)(R13*2), CX - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset + // val1 := br3.peekTopBits(peekBits) + MOVQ DI, CX + MOVQ R11, R13 + SHRQ CL, R13 - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill3 + // v1 := table[val1&mask] + MOVW (R9)(R13*2), CX - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 + // br3.advance(uint8(v1.entry)) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + LEAQ (R8)(R8*2), CX + MOVW AX, (BX)(CX*1) + + // update the bitreader structure + MOVQ R11, 176(R10) + MOVB R12, 184(R10) + ADDQ $0x02, BX + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + SUBQ 16(AX), BX + SHLQ $0x02, BX + MOVQ BX, 40(AX) + RET + +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_amd64(SB), $0-8 + // Preload values + MOVQ ctx+0(FP), CX + MOVBQZX 8(CX), DI + MOVQ 16(CX), BX + MOVQ 48(CX), SI + MOVQ 24(CX), R8 + MOVQ 32(CX), R9 + MOVQ (CX), R10 + + // Main loop +main_loop: + XORL DX, DX + CMPQ BX, SI + SETGE DL + + // br0.fillFast32() + MOVQ 32(R10), R11 + MOVBQZX 40(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill0 + MOVQ 24(R10), R13 + SUBQ $0x20, R12 + SUBQ $0x04, R13 + MOVQ (R10), R14 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) + MOVL (R13)(R14*1), R14 + MOVQ R12, CX + SHLQ CL, R14 + MOVQ R13, 24(R10) + ORQ R14, R11 -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX + // exhausted += (br0.off < 4) + CMPQ R13, $0x04 + ADCB $+0, DL -#endif +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 - ORQ AX, br_value + // v0 := table[val0&mask] + MOVW (R9)(R13*2), CX - // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 - // } -skip_fill3: + // val1 := br0.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v1 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br0.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // val2 := br0.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v2 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br0.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + + // val3 := br0.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v3 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br0.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (BX) + + // update the bitreader structure + MOVQ R11, 32(R10) + MOVB R12, 40(R10) + + // br1.fillFast32() + MOVQ 80(R10), R11 + MOVBQZX 88(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill1 + MOVQ 72(R10), R13 + SUBQ $0x20, R12 + SUBQ $0x04, R13 + MOVQ 48(R10), R14 - // val0 := br3.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R13)(R14*1), R14 + MOVQ R12, CX + SHLQ CL, R14 + MOVQ R13, 72(R10) + ORQ R14, R11 -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask + // exhausted += (br1.off < 4) + CMPQ R13, $0x04 + ADCB $+0, DL -#endif +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + MOVW (R9)(R13*2), CX -#endif + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask + // val1 := br1.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v1 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br1.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // val2 := br1.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v2 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br1.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + + // val3 := br1.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v3 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br1.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (BX)(R8*1) + + // update the bitreader structure + MOVQ R11, 80(R10) + MOVB R12, 88(R10) + + // br2.fillFast32() + MOVQ 128(R10), R11 + MOVBQZX 136(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill2 + MOVQ 120(R10), R13 + SUBQ $0x20, R12 + SUBQ $0x04, R13 + MOVQ 96(R10), R14 -#else - // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R13)(R14*1), R14 + MOVQ R12, CX + SHLQ CL, R14 + MOVQ R13, 120(R10) + ORQ R14, R11 -#endif + // exhausted += (br2.off < 4) + CMPQ R13, $0x04 + ADCB $+0, DL - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) + // v0 := table[val0&mask] + MOVW (R9)(R13*2), CX -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n + // val1 := br2.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v1 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br2.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // val2 := br2.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v2 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br2.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + + // val3 := br2.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v3 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br2.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (BX)(R8*2) + + // update the bitreader structure + MOVQ R11, 128(R10) + MOVB R12, 136(R10) + + // br3.fillFast32() + MOVQ 176(R10), R11 + MOVBQZX 184(R10), R12 + CMPQ R12, $0x20 + JBE skip_fill3 + MOVQ 168(R10), R13 + SUBQ $0x20, R12 + SUBQ $0x04, R13 + MOVQ 144(R10), R14 -#endif + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R13)(R14*1), R14 + MOVQ R12, CX + SHLQ CL, R14 + MOVQ R13, 168(R10) + ORQ R14, R11 - ADDQ CX, br_bits_read // bits_read += n + // exhausted += (br3.off < 4) + CMPQ R13, $0x04 + ADCB $+0, DL - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) + // v0 := table[val0&mask] + MOVW (R9)(R13*2), CX - ADDQ $2, off // off += 2 + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 - TESTB DH, DH // any br[i].ofs < 4? - JNZ end + // val1 := br3.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v1 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br3.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // val2 := br3.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v2 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br3.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R11 + ADDB CL, R12 + + // val3 := br3.peekTopBits(peekBits) + MOVQ R11, R13 + MOVQ DI, CX + SHRQ CL, R13 + + // v3 := table[val0&mask] + MOVW (R9)(R13*2), CX + + // br3.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R11 + ADDB CL, R12 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + LEAQ (R8)(R8*2), CX + MOVL AX, (BX)(CX*1) + + // update the bitreader structure + MOVQ R11, 176(R10) + MOVB R12, 184(R10) + ADDQ $0x04, BX + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + SUBQ 16(AX), BX + SHLQ $0x02, BX + MOVQ BX, 40(AX) + RET - CMPQ off, $bufoff - JL main_loop +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_amd64(SB), $0-8 + MOVQ ctx+0(FP), CX + MOVQ 16(CX), DX + MOVQ 24(CX), BX + CMPQ BX, $0x04 + JB error_max_decoded_size_exceeded + LEAQ (DX)(BX*1), BX + MOVQ (CX), SI + MOVQ (SI), R8 + MOVQ 24(SI), R9 + MOVQ 32(SI), R10 + MOVBQZX 40(SI), R11 + MOVQ 32(CX), SI + MOVBQZX 8(CX), DI + JMP loop_condition -end: - MOVQ 0(SP), BP +main_loop: + // Check if we have room for 4 bytes in the output buffer + LEAQ 4(DX), CX + CMPQ CX, BX + JGE error_max_decoded_size_exceeded + + // Decode 4 values + CMPQ R11, $0x20 + JL bitReader_fillFast_1_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), R12 + MOVQ R11, CX + SHLQ CL, R12 + ORQ R12, R10 + +bitReader_fillFast_1_end: + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + BSWAPL AX + CMPQ R11, $0x20 + JL bitReader_fillFast_2_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), R12 + MOVQ R11, CX + SHLQ CL, R12 + ORQ R12, R10 + +bitReader_fillFast_2_end: + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + BSWAPL AX + + // Store the decoded values + MOVL AX, (DX) + ADDQ $0x04, DX + +loop_condition: + CMPQ R9, $0x08 + JGE main_loop + + // Update ctx structure + MOVQ ctx+0(FP), AX + SUBQ 16(AX), DX + MOVQ DX, 40(AX) + MOVQ (AX), AX + MOVQ R9, 24(AX) + MOVQ R10, 32(AX) + MOVB R11, 40(AX) + RET - MOVB off, ret+56(FP) + // Report error +error_max_decoded_size_exceeded: + MOVQ ctx+0(FP), AX + MOVQ $-1, CX + MOVQ CX, 40(AX) RET -#undef off -#undef buffer -#undef table +// func decompress1x_main_loop_bmi2(ctx *decompress1xContext) +// Requires: BMI2 +TEXT ·decompress1x_main_loop_bmi2(SB), $0-8 + MOVQ ctx+0(FP), CX + MOVQ 16(CX), DX + MOVQ 24(CX), BX + CMPQ BX, $0x04 + JB error_max_decoded_size_exceeded + LEAQ (DX)(BX*1), BX + MOVQ (CX), SI + MOVQ (SI), R8 + MOVQ 24(SI), R9 + MOVQ 32(SI), R10 + MOVBQZX 40(SI), R11 + MOVQ 32(CX), SI + MOVBQZX 8(CX), DI + JMP loop_condition -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted +main_loop: + // Check if we have room for 4 bytes in the output buffer + LEAQ 4(DX), CX + CMPQ CX, BX + JGE error_max_decoded_size_exceeded + + // Decode 4 values + CMPQ R11, $0x20 + JL bitReader_fillFast_1_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), CX + SHLXQ R11, CX, CX + ORQ CX, R10 + +bitReader_fillFast_1_end: + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + BSWAPL AX + CMPQ R11, $0x20 + JL bitReader_fillFast_2_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), CX + SHLXQ R11, CX, CX + ORQ CX, R10 + +bitReader_fillFast_2_end: + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + BSWAPL AX + + // Store the decoded values + MOVL AX, (DX) + ADDQ $0x04, DX + +loop_condition: + CMPQ R9, $0x08 + JGE main_loop + + // Update ctx structure + MOVQ ctx+0(FP), AX + SUBQ 16(AX), DX + MOVQ DX, 40(AX) + MOVQ (AX), AX + MOVQ R9, 24(AX) + MOVQ R10, 32(AX) + MOVB R11, 40(AX) + RET -#undef br0 -#undef br1 -#undef br2 -#undef br3 + // Report error +error_max_decoded_size_exceeded: + MOVQ ctx+0(FP), AX + MOVQ $-1, CX + MOVQ CX, 40(AX) + RET diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in deleted file mode 100644 index 330d86ae155..00000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in +++ /dev/null @@ -1,195 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - - // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX -#endif - - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $2, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 126b4d68a94..908c17de63f 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -122,17 +122,21 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + //copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { @@ -191,3 +195,105 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { } return dst, nil } + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if use8BitTables && d.actualTableLog <= 8 { + return d.decompress1X8Bit(dst, src) + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:0] + + // Avoid bounds check by always having full sized table. + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + dt := d.dt.single[:tlSize] + + // Use temp table to avoid bound checks/append penalty. + bufs := d.buffer() + buf := &bufs[0] + var off uint8 + + for br.off >= 8 { + br.fillFast() + v := dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + // Refill + br.fillFast() + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + d.bufs.Put(bufs) + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + + if len(dst)+int(off) > maxDecodedSize { + d.bufs.Put(bufs) + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:off]...) + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if false && br.bitsRead >= 32 { + if br.off >= 4 { + v := br.in[br.off-4:] + v = v[:4] + low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + br.value = (br.value << 32) | uint64(low) + br.bitsRead -= 32 + br.off -= 4 + } else { + for br.off > 0 { + br.value = (br.value << 8) | uint64(br.in[br.off-1]) + br.bitsRead -= 8 + br.off-- + } + } + } + if len(dst) >= maxDecodedSize { + d.bufs.Put(bufs) + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + d.bufs.Put(bufs) + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go new file mode 100644 index 00000000000..3954c51219b --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go @@ -0,0 +1,34 @@ +// Package cpuinfo gives runtime info about the current CPU. +// +// This is a very limited module meant for use internally +// in this project. For more versatile solution check +// https://github.com/klauspost/cpuid. +package cpuinfo + +// HasBMI1 checks whether an x86 CPU supports the BMI1 extension. +func HasBMI1() bool { + return hasBMI1 +} + +// HasBMI2 checks whether an x86 CPU supports the BMI2 extension. +func HasBMI2() bool { + return hasBMI2 +} + +// DisableBMI2 will disable BMI2, for testing purposes. +// Call returned function to restore previous state. +func DisableBMI2() func() { + old := hasBMI2 + hasBMI2 = false + return func() { + hasBMI2 = old + } +} + +// HasBMI checks whether an x86 CPU supports both BMI1 and BMI2 extensions. +func HasBMI() bool { + return HasBMI1() && HasBMI2() +} + +var hasBMI1 bool +var hasBMI2 bool diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go new file mode 100644 index 00000000000..e802579c4f9 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go @@ -0,0 +1,11 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package cpuinfo + +// go:noescape +func x86extensions() (bmi1, bmi2 bool) + +func init() { + hasBMI1, hasBMI2 = x86extensions() +} diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s new file mode 100644 index 00000000000..4465fbe9e90 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s @@ -0,0 +1,36 @@ +// +build !appengine +// +build gc +// +build !noasm + +#include "textflag.h" +#include "funcdata.h" +#include "go_asm.h" + +TEXT ·x86extensions(SB), NOSPLIT, $0 + // 1. determine max EAX value + XORQ AX, AX + CPUID + + CMPQ AX, $7 + JB unsupported + + // 2. EAX = 7, ECX = 0 --- see Table 3-8 "Information Returned by CPUID Instruction" + MOVQ $7, AX + MOVQ $0, CX + CPUID + + BTQ $3, BX // bit 3 = BMI1 + SETCS AL + + BTQ $8, BX // bit 8 = BMI2 + SETCS AH + + MOVB AL, bmi1+0(FP) + MOVB AH, bmi2+1(FP) + RET + +unsupported: + XORQ AX, AX + MOVB AL, bmi1+0(FP) + MOVB AL, bmi2+1(FP) + RET diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go index 511bba65db8..05db94d39a4 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go @@ -18,6 +18,7 @@ func load64(b []byte, i int) uint64 { // emitLiteral writes a literal chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= len(lit) && len(lit) <= 65536 func emitLiteral(dst, lit []byte) int { @@ -42,6 +43,7 @@ func emitLiteral(dst, lit []byte) int { // emitCopy writes a copy chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= offset && offset <= 65535 // 4 <= length && length <= 65535 @@ -89,6 +91,7 @@ func emitCopy(dst []byte, offset, length int) int { // src[i:i+k-j] and src[j:k] have the same contents. // // It assumes that: +// // 0 <= i && i < j && j <= len(src) func extendMatch(src []byte, i, j int) int { for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 { @@ -100,13 +103,36 @@ func hash(u, shift uint32) uint32 { return (u * 0x1e35a7bd) >> shift } +// EncodeBlockInto exposes encodeBlock but checks dst size. +func EncodeBlockInto(dst, src []byte) (d int) { + if MaxEncodedLen(len(src)) > len(dst) { + return 0 + } + + // encodeBlock breaks on too big blocks, so split. + for len(src) > 0 { + p := src + src = nil + if len(p) > maxBlockSize { + p, src = p[:maxBlockSize], p[maxBlockSize:] + } + if len(p) < minNonLiteralBlockSize { + d += emitLiteral(dst[d:], p) + } else { + d += encodeBlock(dst[d:], p) + } + } + return d +} + // encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It // assumes that the varint-encoded length of the decompressed bytes has already // been written. // // It also assumes that: +// // len(dst) >= MaxEncodedLen(len(src)) && -// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize +// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize func encodeBlock(dst, src []byte) (d int) { // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. // The table element type is uint16, as s < sLimit and sLimit < len(src) diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index e3445ac194e..65b38abed80 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -12,6 +12,8 @@ The `zstd` package is provided as open source software using a Go standard licen Currently the package is heavily optimized for 64 bit processors and will be significantly slower on 32 bit processors. +For seekable zstd streams, see [this excellent package](https://github.com/SaveTheRbtz/zstd-seekable-format-go). + ## Installation Install using `go get -u github.com/klauspost/compress`. The package is located in `github.com/klauspost/compress/zstd`. @@ -386,47 +388,31 @@ In practice this means that concurrency is often limited to utilizing about 3 co ### Benchmarks -These are some examples of performance compared to [datadog cgo library](https://github.com/DataDog/zstd). - The first two are streaming decodes and the last are smaller inputs. - + +Running on AMD Ryzen 9 3950X 16-Core Processor. AMD64 assembly used. + ``` -BenchmarkDecoderSilesia-8 3 385000067 ns/op 550.51 MB/s 5498 B/op 8 allocs/op -BenchmarkDecoderSilesiaCgo-8 6 197666567 ns/op 1072.25 MB/s 270672 B/op 8 allocs/op - -BenchmarkDecoderEnwik9-8 1 2027001600 ns/op 493.34 MB/s 10496 B/op 18 allocs/op -BenchmarkDecoderEnwik9Cgo-8 2 979499200 ns/op 1020.93 MB/s 270672 B/op 8 allocs/op - -Concurrent performance: - -BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-16 28915 42469 ns/op 4340.07 MB/s 114 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-16 116505 9965 ns/op 11900.16 MB/s 16 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-16 8952 134272 ns/op 3588.70 MB/s 915 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-16 11820 102538 ns/op 4161.90 MB/s 594 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-16 34782 34184 ns/op 3661.88 MB/s 60 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-16 27712 43447 ns/op 3500.58 MB/s 99 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-16 62826 18750 ns/op 21845.10 MB/s 104 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-16 631545 1794 ns/op 57078.74 MB/s 2 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-16 1690140 712 ns/op 172938.13 MB/s 1 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-16 10432 113593 ns/op 6180.73 MB/s 1143 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/html.zst-16 113206 10671 ns/op 9596.27 MB/s 15 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-16 1530615 779 ns/op 5229.49 MB/s 0 B/op 0 allocs/op - -BenchmarkDecoder_DecodeAllParallelCgo/kppkn.gtb.zst-16 65217 16192 ns/op 11383.34 MB/s 46 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/geo.protodata.zst-16 292671 4039 ns/op 29363.19 MB/s 6 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/plrabn12.txt.zst-16 26314 46021 ns/op 10470.43 MB/s 293 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/lcet10.txt.zst-16 33897 34900 ns/op 12227.96 MB/s 205 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/asyoulik.txt.zst-16 104348 11433 ns/op 10949.01 MB/s 20 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/alice29.txt.zst-16 75949 15510 ns/op 9805.60 MB/s 32 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/html_x_4.zst-16 173910 6756 ns/op 60624.29 MB/s 37 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/paper-100k.pdf.zst-16 923076 1339 ns/op 76474.87 MB/s 1 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/fireworks.jpeg.zst-16 922920 1351 ns/op 91102.57 MB/s 2 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/urls.10K.zst-16 27649 43618 ns/op 16096.19 MB/s 407 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/html.zst-16 279073 4160 ns/op 24614.18 MB/s 6 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/comp-data.bin.zst-16 749938 1579 ns/op 2581.71 MB/s 0 B/op 0 allocs/op +BenchmarkDecoderSilesia-32 5 206878840 ns/op 1024.50 MB/s 49808 B/op 43 allocs/op +BenchmarkDecoderEnwik9-32 1 1271809000 ns/op 786.28 MB/s 72048 B/op 52 allocs/op + +Concurrent blocks, performance: + +BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-32 67356 17857 ns/op 10321.96 MB/s 22.48 pct 102 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-32 266656 4421 ns/op 26823.21 MB/s 11.89 pct 19 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-32 20992 56842 ns/op 8477.17 MB/s 39.90 pct 754 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-32 27456 43932 ns/op 9714.01 MB/s 33.27 pct 524 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-32 78432 15047 ns/op 8319.15 MB/s 40.34 pct 66 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-32 65800 18436 ns/op 8249.63 MB/s 37.75 pct 88 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-32 102993 11523 ns/op 35546.09 MB/s 3.637 pct 143 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-32 1000000 1070 ns/op 95720.98 MB/s 80.53 pct 3 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-32 749802 1752 ns/op 70272.35 MB/s 100.0 pct 5 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-32 22640 52934 ns/op 13263.37 MB/s 26.25 pct 1014 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/html.zst-32 226412 5232 ns/op 19572.27 MB/s 14.49 pct 20 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-32 923041 1276 ns/op 3194.71 MB/s 31.26 pct 0 B/op 0 allocs/op ``` -This reflects the performance around May 2020, but this may be out of date. +This reflects the performance around May 2022, but this may be out of date. ## Zstd inside ZIP files diff --git a/vendor/github.com/klauspost/compress/zstd/bitreader.go b/vendor/github.com/klauspost/compress/zstd/bitreader.go index d7cd15ba29d..97299d499cf 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitreader.go +++ b/vendor/github.com/klauspost/compress/zstd/bitreader.go @@ -63,13 +63,6 @@ func (b *bitReader) get32BitsFast(n uint8) uint32 { return v } -func (b *bitReader) get16BitsFast(n uint8) uint16 { - const regMask = 64 - 1 - v := uint16((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask)) - b.bitsRead += n - return v -} - // fillFast() will make sure at least 32 bits are available. // There must be at least 4 bytes available. func (b *bitReader) fillFast() { diff --git a/vendor/github.com/klauspost/compress/zstd/bitwriter.go b/vendor/github.com/klauspost/compress/zstd/bitwriter.go index b3661828509..78b3c61be3e 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitwriter.go +++ b/vendor/github.com/klauspost/compress/zstd/bitwriter.go @@ -5,8 +5,6 @@ package zstd -import "fmt" - // bitWriter will write bits. // First bit will be LSB of the first byte of output. type bitWriter struct { @@ -73,80 +71,6 @@ func (b *bitWriter) addBits16Clean(value uint16, bits uint8) { b.nBits += bits } -// flush will flush all pending full bytes. -// There will be at least 56 bits available for writing when this has been called. -// Using flush32 is faster, but leaves less space for writing. -func (b *bitWriter) flush() { - v := b.nBits >> 3 - switch v { - case 0: - case 1: - b.out = append(b.out, - byte(b.bitContainer), - ) - case 2: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - ) - case 3: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - ) - case 4: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - ) - case 5: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - ) - case 6: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - ) - case 7: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - ) - case 8: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - byte(b.bitContainer>>56), - ) - default: - panic(fmt.Errorf("bits (%d) > 64", b.nBits)) - } - b.bitContainer >>= v << 3 - b.nBits &= 7 -} - // flush32 will flush out, so there are at least 32 bits available for writing. func (b *bitWriter) flush32() { if b.nBits < 32 { diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 7d567a54a05..2445bb4fe5b 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -5,9 +5,13 @@ package zstd import ( + "bytes" + "encoding/binary" "errors" "fmt" "io" + "os" + "path/filepath" "sync" "github.com/klauspost/compress/huff0" @@ -38,14 +42,14 @@ const ( // maxCompressedBlockSize is the biggest allowed compressed block size (128KB) maxCompressedBlockSize = 128 << 10 + compressedBlockOverAlloc = 16 + maxCompressedBlockSizeAlloc = 128<<10 + compressedBlockOverAlloc + // Maximum possible block size (all Raw+Uncompressed). maxBlockSize = (1 << 21) - 1 - // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#literals_section_header - maxCompressedLiteralSize = 1 << 18 - maxRLELiteralSize = 1 << 20 - maxMatchLen = 131074 - maxSequences = 0x7f00 + 0xffff + maxMatchLen = 131074 + maxSequences = 0x7f00 + 0xffff // We support slightly less than the reference decoder to be able to // use ints on 32 bit archs. @@ -78,8 +82,9 @@ type blockDec struct { err error - // Check against this crc - checkCRC []byte + // Check against this crc, if hasCRC is true. + checkCRC uint32 + hasCRC bool // Frame to use for singlethreaded decoding. // Should not be used by the decoder itself since parent may be another frame. @@ -97,7 +102,6 @@ type blockDec struct { // Block is RLE, this is the size. RLESize uint32 - tmp [4]byte Type blockType @@ -136,7 +140,7 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { b.Type = blockType((bh >> 1) & 3) // find size. cSize := int(bh >> 3) - maxSize := maxBlockSize + maxSize := maxCompressedBlockSizeAlloc switch b.Type { case blockTypeReserved: return ErrReservedBlockType @@ -157,9 +161,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { println("Data size on stream:", cSize) } b.RLESize = 0 - maxSize = maxCompressedBlockSize + maxSize = maxCompressedBlockSizeAlloc if windowSize < maxCompressedBlockSize && b.lowMem { - maxSize = int(windowSize) + maxSize = int(windowSize) + compressedBlockOverAlloc } if cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize { if debugDecoder { @@ -188,16 +192,14 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { } // Read block data. - if cap(b.dataStorage) < cSize { + if _, ok := br.(*byteBuf); !ok && cap(b.dataStorage) < cSize { + // byteBuf doesn't need a destination buffer. if b.lowMem || cSize > maxCompressedBlockSize { - b.dataStorage = make([]byte, 0, cSize) + b.dataStorage = make([]byte, 0, cSize+compressedBlockOverAlloc) } else { - b.dataStorage = make([]byte, 0, maxCompressedBlockSize) + b.dataStorage = make([]byte, 0, maxCompressedBlockSizeAlloc) } } - if cap(b.dst) <= maxSize { - b.dst = make([]byte, 0, maxSize+1) - } b.data, err = br.readBig(cSize, b.dataStorage) if err != nil { if debugDecoder { @@ -206,6 +208,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { } return err } + if cap(b.dst) <= maxSize { + b.dst = make([]byte, 0, maxSize+1) + } return nil } @@ -229,7 +234,7 @@ func (b *blockDec) decodeBuf(hist *history) error { if b.lowMem { b.dst = make([]byte, b.RLESize) } else { - b.dst = make([]byte, maxBlockSize) + b.dst = make([]byte, maxCompressedBlockSize) } } b.dst = b.dst[:b.RLESize] @@ -360,14 +365,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, litRegenSize) + b.literalBuf = make([]byte, litRegenSize, litRegenSize+compressedBlockOverAlloc) } else { - if litRegenSize > maxCompressedLiteralSize { - // Exceptional - b.literalBuf = make([]byte, litRegenSize) - } else { - b.literalBuf = make([]byte, litRegenSize, maxCompressedLiteralSize) - } + b.literalBuf = make([]byte, litRegenSize, maxCompressedBlockSize+compressedBlockOverAlloc) } } literals = b.literalBuf[:litRegenSize] @@ -397,14 +397,14 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err // Ensure we have space to store it. if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, 0, litRegenSize) + b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc) } else { - b.literalBuf = make([]byte, 0, maxCompressedLiteralSize) + b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc) } } var err error // Use our out buffer. - huff.MaxDecodedSize = maxCompressedBlockSize + huff.MaxDecodedSize = litRegenSize if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -429,9 +429,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err // Ensure we have space to store it. if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, 0, litRegenSize) + b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc) } else { - b.literalBuf = make([]byte, 0, maxCompressedBlockSize) + b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc) } } huff := hist.huffTree @@ -448,7 +448,7 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err return in, err } hist.huffTree = huff - huff.MaxDecodedSize = maxCompressedBlockSize + huff.MaxDecodedSize = litRegenSize // Use our out buffer. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) @@ -463,6 +463,8 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err if len(literals) != litRegenSize { return in, fmt.Errorf("literal output size mismatch want %d, got %d", litRegenSize, len(literals)) } + // Re-cap to get extra size. + literals = b.literalBuf[:len(literals)] if debugDecoder { printf("Decompressed %d literals into %d bytes\n", litCompSize, litRegenSize) } @@ -486,10 +488,15 @@ func (b *blockDec) decodeCompressed(hist *history) error { b.dst = append(b.dst, hist.decoders.literals...) return nil } - err = hist.decoders.decodeSync(hist) + before := len(hist.decoders.out) + err = hist.decoders.decodeSync(hist.b[hist.ignoreBuffer:]) if err != nil { return err } + if hist.decoders.maxSyncLen > 0 { + hist.decoders.maxSyncLen += uint64(before) + hist.decoders.maxSyncLen -= uint64(len(hist.decoders.out)) + } b.dst = hist.decoders.out hist.recentOffsets = hist.decoders.prevOffset return nil @@ -632,6 +639,22 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) { println("initializing sequences:", err) return err } + // Extract blocks... + if false && hist.dict == nil { + fatalErr := func(err error) { + if err != nil { + panic(err) + } + } + fn := fmt.Sprintf("n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize) + var buf bytes.Buffer + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse)) + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse)) + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse)) + buf.Write(in) + os.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm) + } + return nil } @@ -650,6 +673,7 @@ func (b *blockDec) decodeSequences(hist *history) error { } hist.decoders.windowSize = hist.windowSize hist.decoders.prevOffset = hist.recentOffsets + err := hist.decoders.decode(b.sequence) hist.recentOffsets = hist.decoders.prevOffset return err diff --git a/vendor/github.com/klauspost/compress/zstd/bytebuf.go b/vendor/github.com/klauspost/compress/zstd/bytebuf.go index b80191e4b1e..176788f2597 100644 --- a/vendor/github.com/klauspost/compress/zstd/bytebuf.go +++ b/vendor/github.com/klauspost/compress/zstd/bytebuf.go @@ -7,7 +7,6 @@ package zstd import ( "fmt" "io" - "io/ioutil" ) type byteBuffer interface { @@ -23,7 +22,7 @@ type byteBuffer interface { readByte() (byte, error) // Skip n bytes. - skipN(n int) error + skipN(n int64) error } // in-memory buffer @@ -52,10 +51,6 @@ func (b *byteBuf) readBig(n int, dst []byte) ([]byte, error) { return r, nil } -func (b *byteBuf) remain() []byte { - return *b -} - func (b *byteBuf) readByte() (byte, error) { bb := *b if len(bb) < 1 { @@ -66,9 +61,12 @@ func (b *byteBuf) readByte() (byte, error) { return r, nil } -func (b *byteBuf) skipN(n int) error { +func (b *byteBuf) skipN(n int64) error { bb := *b - if len(bb) < n { + if n < 0 { + return fmt.Errorf("negative skip (%d) requested", n) + } + if int64(len(bb)) < n { return io.ErrUnexpectedEOF } *b = bb[n:] @@ -124,9 +122,9 @@ func (r *readerWrapper) readByte() (byte, error) { return r.tmp[0], nil } -func (r *readerWrapper) skipN(n int) error { - n2, err := io.CopyN(ioutil.Discard, r.r, int64(n)) - if n2 != int64(n) { +func (r *readerWrapper) skipN(n int64) error { + n2, err := io.CopyN(io.Discard, r.r, n) + if n2 != n { err = io.ErrUnexpectedEOF } return err diff --git a/vendor/github.com/klauspost/compress/zstd/bytereader.go b/vendor/github.com/klauspost/compress/zstd/bytereader.go index 2c4fca17fa1..0e59a242d8d 100644 --- a/vendor/github.com/klauspost/compress/zstd/bytereader.go +++ b/vendor/github.com/klauspost/compress/zstd/bytereader.go @@ -13,12 +13,6 @@ type byteReader struct { off int } -// init will initialize the reader and set the input. -func (b *byteReader) init(in []byte) { - b.b = in - b.off = 0 -} - // advance the stream b n bytes. func (b *byteReader) advance(n uint) { b.off += int(n) diff --git a/vendor/github.com/klauspost/compress/zstd/decodeheader.go b/vendor/github.com/klauspost/compress/zstd/decodeheader.go index 5022e71c836..f6a240970d4 100644 --- a/vendor/github.com/klauspost/compress/zstd/decodeheader.go +++ b/vendor/github.com/klauspost/compress/zstd/decodeheader.go @@ -4,7 +4,6 @@ package zstd import ( - "bytes" "encoding/binary" "errors" "io" @@ -102,8 +101,8 @@ func (h *Header) Decode(in []byte) error { } h.HeaderSize += 4 b, in := in[:4], in[4:] - if !bytes.Equal(b, frameMagic) { - if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 { + if string(b) != frameMagic { + if string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 { return ErrMagicMismatch } if len(in) < 4 { @@ -153,7 +152,7 @@ func (h *Header) Decode(in []byte) error { } b, in = in[:size], in[size:] h.HeaderSize += int(size) - switch size { + switch len(b) { case 1: h.DictionaryID = uint32(b[0]) case 2: @@ -183,7 +182,7 @@ func (h *Header) Decode(in []byte) error { } b, in = in[:fcsSize], in[fcsSize:] h.HeaderSize += int(fcsSize) - switch fcsSize { + switch len(b) { case 1: h.FrameContentSize = uint64(b[0]) case 2: diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index 9fcdaac1dc7..7113e69ee3a 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -5,7 +5,6 @@ package zstd import ( - "bytes" "context" "encoding/binary" "io" @@ -35,13 +34,13 @@ type Decoder struct { br readerWrapper enabled bool inFrame bool + dstBuf []byte } frame *frameDec // Custom dictionaries. - // Always uses copies. - dicts map[uint32]dict + dicts map[uint32]*dict // streamWg is the waitgroup for all streams streamWg sync.WaitGroup @@ -103,7 +102,7 @@ func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) { } // Transfer option dicts. - d.dicts = make(map[uint32]dict, len(d.o.dicts)) + d.dicts = make(map[uint32]*dict, len(d.o.dicts)) for _, dc := range d.o.dicts { d.dicts[dc.id] = dc } @@ -187,21 +186,23 @@ func (d *Decoder) Reset(r io.Reader) error { } // If bytes buffer and < 5MB, do sync decoding anyway. - if bb, ok := r.(byter); ok && bb.Len() < 5<<20 { + if bb, ok := r.(byter); ok && bb.Len() < d.o.decodeBufsBelow && !d.o.limitToCap { bb2 := bb if debugDecoder { println("*bytes.Buffer detected, doing sync decode, len:", bb.Len()) } b := bb2.Bytes() var dst []byte - if cap(d.current.b) > 0 { - dst = d.current.b + if cap(d.syncStream.dstBuf) > 0 { + dst = d.syncStream.dstBuf[:0] } - dst, err := d.DecodeAll(b, dst[:0]) + dst, err := d.DecodeAll(b, dst) if err == nil { err = io.EOF } + // Save output buffer + d.syncStream.dstBuf = dst d.current.b = dst d.current.err = err d.current.flushed = true @@ -216,6 +217,7 @@ func (d *Decoder) Reset(r io.Reader) error { d.current.err = nil d.current.flushed = false d.current.d = nil + d.syncStream.dstBuf = nil // Ensure no-one else is still running... d.streamWg.Wait() @@ -312,6 +314,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { // Grab a block decoder and frame decoder. block := <-d.decoders frame := block.localFrame + initialSize := len(dst) defer func() { if debugDecoder { printf("re-adding decoder: %p", block) @@ -337,29 +340,36 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { } return dst, err } - if frame.DictionaryID != nil { - dict, ok := d.dicts[*frame.DictionaryID] - if !ok { - return nil, ErrUnknownDictionary - } + if err = d.setDict(frame); err != nil { + return nil, err + } + if frame.WindowSize > d.o.maxWindowSize { if debugDecoder { - println("setting dict", frame.DictionaryID) + println("window size exceeded:", frame.WindowSize, ">", d.o.maxWindowSize) } - frame.history.setDict(&dict) + return dst, ErrWindowSizeExceeded } - - if frame.FrameContentSize != fcsUnknown && frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)) { - return dst, ErrDecoderSizeExceeded - } - if frame.FrameContentSize < 1<<30 { - // Never preallocate more than 1 GB up front. + if frame.FrameContentSize != fcsUnknown { + if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)-initialSize) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> mcs:", d.o.maxDecodedSize-uint64(len(dst)-initialSize), "len:", len(dst)) + } + return dst, ErrDecoderSizeExceeded + } + if d.o.limitToCap && frame.FrameContentSize > uint64(cap(dst)-len(dst)) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> (cap-len)", cap(dst)-len(dst)) + } + return dst, ErrDecoderSizeExceeded + } if cap(dst)-len(dst) < int(frame.FrameContentSize) { - dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)) + dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)+compressedBlockOverAlloc) copy(dst2, dst) dst = dst2 } } - if cap(dst) == 0 { + + if cap(dst) == 0 && !d.o.limitToCap { // Allocate len(input) * 2 by default if nothing is provided // and we didn't get frame content size. size := len(input) * 2 @@ -377,6 +387,9 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { if err != nil { return dst, err } + if uint64(len(dst)-initialSize) > d.o.maxDecodedSize { + return dst, ErrDecoderSizeExceeded + } if len(frame.bBuf) == 0 { if debugDecoder { println("frame dbuf empty") @@ -437,6 +450,10 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { println("got", len(d.current.b), "bytes, error:", d.current.err, "data crc:", tmp) } + if d.o.ignoreChecksum { + return true + } + if len(next.b) > 0 { n, err := d.current.crc.Write(next.b) if err == nil { @@ -445,18 +462,16 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { } } } - if next.err == nil && next.d != nil && len(next.d.checkCRC) != 0 { - got := d.current.crc.Sum64() - var tmp [4]byte - binary.LittleEndian.PutUint32(tmp[:], uint32(got)) - if !bytes.Equal(tmp[:], next.d.checkCRC) && !ignoreCRC { + if next.err == nil && next.d != nil && next.d.hasCRC { + got := uint32(d.current.crc.Sum64()) + if got != next.d.checkCRC { if debugDecoder { - println("CRC Check Failed:", tmp[:], " (got) !=", next.d.checkCRC, "(on stream)") + printf("CRC Check Failed: %08x (got) != %08x (on stream)\n", got, next.d.checkCRC) } d.current.err = ErrCRCMismatch } else { if debugDecoder { - println("CRC ok", tmp[:]) + printf("CRC ok %08x\n", got) } } } @@ -472,18 +487,12 @@ func (d *Decoder) nextBlockSync() (ok bool) { if !d.syncStream.inFrame { d.frame.history.reset() d.current.err = d.frame.reset(&d.syncStream.br) + if d.current.err == nil { + d.current.err = d.setDict(d.frame) + } if d.current.err != nil { return false } - if d.frame.DictionaryID != nil { - dict, ok := d.dicts[*d.frame.DictionaryID] - if !ok { - d.current.err = ErrUnknownDictionary - return false - } else { - d.frame.history.setDict(&dict) - } - } if d.frame.WindowSize > d.o.maxDecodedSize || d.frame.WindowSize > d.o.maxWindowSize { d.current.err = ErrDecoderSizeExceeded return false @@ -533,9 +542,15 @@ func (d *Decoder) nextBlockSync() (ok bool) { // Update/Check CRC if d.frame.HasCheckSum { - d.frame.crc.Write(d.current.b) + if !d.o.ignoreChecksum { + d.frame.crc.Write(d.current.b) + } if d.current.d.Last { - d.current.err = d.frame.checkCRC() + if !d.o.ignoreChecksum { + d.current.err = d.frame.checkCRC() + } else { + d.current.err = d.frame.consumeCRC() + } if d.current.err != nil { println("CRC error:", d.current.err) return false @@ -629,60 +644,18 @@ func (d *Decoder) startSyncDecoder(r io.Reader) error { // Create Decoder: // ASYNC: -// Spawn 4 go routines. -// 0: Read frames and decode blocks. -// 1: Decode block and literals. Receives hufftree and seqdecs, returns seqdecs and huff tree. -// 2: Wait for recentOffsets if needed. Decode sequences, send recentOffsets. -// 3: Wait for stream history, execute sequences, send stream history. +// Spawn 3 go routines. +// 0: Read frames and decode block literals. +// 1: Decode sequences. +// 2: Execute sequences, send to output. func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output chan decodeOutput) { defer d.streamWg.Done() br := readerWrapper{r: r} - var seqPrepare = make(chan *blockDec, d.o.concurrent) var seqDecode = make(chan *blockDec, d.o.concurrent) var seqExecute = make(chan *blockDec, d.o.concurrent) - // Async 1: Prepare blocks... - go func() { - var hist history - var hasErr bool - for block := range seqPrepare { - if hasErr { - if block != nil { - seqDecode <- block - } - continue - } - if block.async.newHist != nil { - if debugDecoder { - println("Async 1: new history") - } - hist.reset() - if block.async.newHist.dict != nil { - hist.setDict(block.async.newHist.dict) - } - } - if block.err != nil || block.Type != blockTypeCompressed { - hasErr = block.err != nil - seqDecode <- block - continue - } - - remain, err := block.decodeLiterals(block.data, &hist) - block.err = err - hasErr = block.err != nil - if err == nil { - block.async.literals = hist.decoders.literals - block.async.seqData = remain - } else if debugDecoder { - println("decodeLiterals error:", err) - } - seqDecode <- block - } - close(seqDecode) - }() - - // Async 2: Decode sequences... + // Async 1: Decode sequences... go func() { var hist history var hasErr bool @@ -696,8 +669,9 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch } if block.async.newHist != nil { if debugDecoder { - println("Async 2: new history, recent:", block.async.newHist.recentOffsets) + println("Async 1: new history, recent:", block.async.newHist.recentOffsets) } + hist.reset() hist.decoders = block.async.newHist.decoders hist.recentOffsets = block.async.newHist.recentOffsets hist.windowSize = block.async.newHist.windowSize @@ -729,6 +703,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch seqExecute <- block } close(seqExecute) + hist.reset() }() var wg sync.WaitGroup @@ -750,8 +725,9 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch } if block.async.newHist != nil { if debugDecoder { - println("Async 3: new history") + println("Async 2: new history") } + hist.reset() hist.windowSize = block.async.newHist.windowSize hist.allocFrameBuffer = block.async.newHist.allocFrameBuffer if block.async.newHist.dict != nil { @@ -781,7 +757,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch if block.lowMem { block.dst = make([]byte, block.RLESize) } else { - block.dst = make([]byte, maxBlockSize) + block.dst = make([]byte, maxCompressedBlockSize) } } block.dst = block.dst[:block.RLESize] @@ -833,10 +809,38 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch if debugDecoder { println("decoder goroutines finished") } + hist.reset() }() + var hist history decodeStream: for { + var hasErr bool + hist.reset() + decodeBlock := func(block *blockDec) { + if hasErr { + if block != nil { + seqDecode <- block + } + return + } + if block.err != nil || block.Type != blockTypeCompressed { + hasErr = block.err != nil + seqDecode <- block + return + } + + remain, err := block.decodeLiterals(block.data, &hist) + block.err = err + hasErr = block.err != nil + if err == nil { + block.async.literals = hist.decoders.literals + block.async.seqData = remain + } else if debugDecoder { + println("decodeLiterals error:", err) + } + seqDecode <- block + } frame := d.frame if debugDecoder { println("New frame...") @@ -847,15 +851,14 @@ decodeStream: if debugDecoder && err != nil { println("Frame decoder returned", err) } - if err == nil && frame.DictionaryID != nil { - dict, ok := d.dicts[*frame.DictionaryID] - if !ok { - err = ErrUnknownDictionary - } else { - frame.history.setDict(&dict) - } + if err == nil { + err = d.setDict(frame) } if err == nil && d.frame.WindowSize > d.o.maxWindowSize { + if debugDecoder { + println("decoder size exceeded, fws:", d.frame.WindowSize, "> mws:", d.o.maxWindowSize) + } + err = ErrDecoderSizeExceeded } if err != nil { @@ -863,7 +866,7 @@ decodeStream: case <-ctx.Done(): case dec := <-d.decoders: dec.sendErr(err) - seqPrepare <- dec + decodeBlock(dec) } break decodeStream } @@ -883,6 +886,10 @@ decodeStream: if debugDecoder { println("Alloc History:", h.allocFrameBuffer) } + hist.reset() + if h.dict != nil { + hist.setDict(h.dict) + } dec.async.newHist = &h dec.async.fcs = frame.FrameContentSize historySent = true @@ -893,23 +900,27 @@ decodeStream: println("next block returned error:", err) } dec.err = err - dec.checkCRC = nil + dec.hasCRC = false if dec.Last && frame.HasCheckSum && err == nil { crc, err := frame.rawInput.readSmall(4) - if err != nil { + if len(crc) < 4 { + if err == nil { + err = io.ErrUnexpectedEOF + + } println("CRC missing?", err) dec.err = err - } - var tmp [4]byte - copy(tmp[:], crc) - dec.checkCRC = tmp[:] - if debugDecoder { - println("found crc to check:", dec.checkCRC) + } else { + dec.checkCRC = binary.LittleEndian.Uint32(crc) + dec.hasCRC = true + if debugDecoder { + printf("found crc to check: %08x\n", dec.checkCRC) + } } } err = dec.err last := dec.Last - seqPrepare <- dec + decodeBlock(dec) if err != nil { break decodeStream } @@ -918,7 +929,25 @@ decodeStream: } } } - close(seqPrepare) + close(seqDecode) wg.Wait() + hist.reset() d.frame.history.b = frameHistCache } + +func (d *Decoder) setDict(frame *frameDec) (err error) { + dict, ok := d.dicts[frame.DictionaryID] + if ok { + if debugDecoder { + println("setting dict", frame.DictionaryID) + } + frame.history.setDict(dict) + } else if frame.DictionaryID != 0 { + // A zero or missing dictionary id is ambiguous: + // either dictionary zero, or no dictionary. In particular, + // zstd --patch-from uses this id for the source file, + // so only return an error if the dictionary id is not zero. + err = ErrUnknownDictionary + } + return err +} diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go index fd05c9bb012..07a90dd7af3 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go @@ -6,6 +6,8 @@ package zstd import ( "errors" + "fmt" + "math/bits" "runtime" ) @@ -14,24 +16,28 @@ type DOption func(*decoderOptions) error // options retains accumulated state of multiple options. type decoderOptions struct { - lowMem bool - concurrent int - maxDecodedSize uint64 - maxWindowSize uint64 - dicts []dict + lowMem bool + concurrent int + maxDecodedSize uint64 + maxWindowSize uint64 + dicts []*dict + ignoreChecksum bool + limitToCap bool + decodeBufsBelow int } func (o *decoderOptions) setDefault() { *o = decoderOptions{ // use less ram: true for now, but may change. - lowMem: true, - concurrent: runtime.GOMAXPROCS(0), - maxWindowSize: MaxWindowSize, + lowMem: true, + concurrent: runtime.GOMAXPROCS(0), + maxWindowSize: MaxWindowSize, + decodeBufsBelow: 128 << 10, } if o.concurrent > 4 { o.concurrent = 4 } - o.maxDecodedSize = 1 << 63 + o.maxDecodedSize = 64 << 30 } // WithDecoderLowmem will set whether to use a lower amount of memory, @@ -66,7 +72,7 @@ func WithDecoderConcurrency(n int) DOption { // WithDecoderMaxMemory allows to set a maximum decoded size for in-memory // non-streaming operations or maximum window size for streaming operations. // This can be used to control memory usage of potentially hostile content. -// Maximum and default is 1 << 63 bytes. +// Maximum is 1 << 63 bytes. Default is 64GiB. func WithDecoderMaxMemory(n uint64) DOption { return func(o *decoderOptions) error { if n == 0 { @@ -81,7 +87,13 @@ func WithDecoderMaxMemory(n uint64) DOption { } // WithDecoderDicts allows to register one or more dictionaries for the decoder. -// If several dictionaries with the same ID is provided the last one will be used. +// +// Each slice in dict must be in the [dictionary format] produced by +// "zstd --train" from the Zstandard reference implementation. +// +// If several dictionaries with the same ID are provided, the last one will be used. +// +// [dictionary format]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format func WithDecoderDicts(dicts ...[]byte) DOption { return func(o *decoderOptions) error { for _, b := range dicts { @@ -89,12 +101,24 @@ func WithDecoderDicts(dicts ...[]byte) DOption { if err != nil { return err } - o.dicts = append(o.dicts, *d) + o.dicts = append(o.dicts, d) } return nil } } +// WithEncoderDictRaw registers a dictionary that may be used by the decoder. +// The slice content can be arbitrary data. +func WithDecoderDictRaw(id uint32, content []byte) DOption { + return func(o *decoderOptions) error { + if bits.UintSize > 32 && uint(len(content)) > dictMaxLength { + return fmt.Errorf("dictionary of size %d > 2GiB too large", len(content)) + } + o.dicts = append(o.dicts, &dict{id: id, content: content, offsets: [3]int{1, 4, 8}}) + return nil + } +} + // WithDecoderMaxWindow allows to set a maximum window size for decodes. // This allows rejecting packets that will cause big memory usage. // The Decoder will likely allocate more memory based on the WithDecoderLowmem setting. @@ -112,3 +136,34 @@ func WithDecoderMaxWindow(size uint64) DOption { return nil } } + +// WithDecodeAllCapLimit will limit DecodeAll to decoding cap(dst)-len(dst) bytes, +// or any size set in WithDecoderMaxMemory. +// This can be used to limit decoding to a specific maximum output size. +// Disabled by default. +func WithDecodeAllCapLimit(b bool) DOption { + return func(o *decoderOptions) error { + o.limitToCap = b + return nil + } +} + +// WithDecodeBuffersBelow will fully decode readers that have a +// `Bytes() []byte` and `Len() int` interface similar to bytes.Buffer. +// This typically uses less allocations but will have the full decompressed object in memory. +// Note that DecodeAllCapLimit will disable this, as well as giving a size of 0 or less. +// Default is 128KiB. +func WithDecodeBuffersBelow(size int) DOption { + return func(o *decoderOptions) error { + o.decodeBufsBelow = size + return nil + } +} + +// IgnoreChecksum allows to forcibly ignore checksum checking. +func IgnoreChecksum(b bool) DOption { + return func(o *decoderOptions) error { + o.ignoreChecksum = b + return nil + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go index a36ae83ef57..ca0951452e6 100644 --- a/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/vendor/github.com/klauspost/compress/zstd/dict.go @@ -1,7 +1,6 @@ package zstd import ( - "bytes" "encoding/binary" "errors" "fmt" @@ -20,7 +19,10 @@ type dict struct { content []byte } -var dictMagic = [4]byte{0x37, 0xa4, 0x30, 0xec} +const dictMagic = "\x37\xa4\x30\xec" + +// Maximum dictionary size for the reference implementation (1.5.3) is 2 GiB. +const dictMaxLength = 1 << 31 // ID returns the dictionary id or 0 if d is nil. func (d *dict) ID() uint32 { @@ -30,14 +32,38 @@ func (d *dict) ID() uint32 { return d.id } -// DictContentSize returns the dictionary content size or 0 if d is nil. -func (d *dict) DictContentSize() int { +// ContentSize returns the dictionary content size or 0 if d is nil. +func (d *dict) ContentSize() int { if d == nil { return 0 } return len(d.content) } +// Content returns the dictionary content. +func (d *dict) Content() []byte { + if d == nil { + return nil + } + return d.content +} + +// Offsets returns the initial offsets. +func (d *dict) Offsets() [3]int { + if d == nil { + return [3]int{} + } + return d.offsets +} + +// LitEncoder returns the literal encoder. +func (d *dict) LitEncoder() *huff0.Scratch { + if d == nil { + return nil + } + return d.litEnc +} + // Load a dictionary as described in // https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format func loadDict(b []byte) (*dict, error) { @@ -50,7 +76,7 @@ func loadDict(b []byte) (*dict, error) { ofDec: sequenceDec{fse: &fseDecoder{}}, mlDec: sequenceDec{fse: &fseDecoder{}}, } - if !bytes.Equal(b[:4], dictMagic[:]) { + if string(b[:4]) != dictMagic { return nil, ErrMagicMismatch } d.id = binary.LittleEndian.Uint32(b[4:8]) @@ -62,7 +88,7 @@ func loadDict(b []byte) (*dict, error) { var err error d.litEnc, b, err = huff0.ReadTable(b[8:], nil) if err != nil { - return nil, err + return nil, fmt.Errorf("loading literal table: %w", err) } d.litEnc.Reuse = huff0.ReusePolicyMust @@ -120,3 +146,16 @@ func loadDict(b []byte) (*dict, error) { return &d, nil } + +// InspectDictionary loads a zstd dictionary and provides functions to inspect the content. +func InspectDictionary(b []byte) (interface { + ID() uint32 + ContentSize() int + Content() []byte + Offsets() [3]int + LitEncoder() *huff0.Scratch +}, error) { + initPredefined() + d, err := loadDict(b) + return d, err +} diff --git a/vendor/github.com/klauspost/compress/zstd/enc_base.go b/vendor/github.com/klauspost/compress/zstd/enc_base.go index 15ae8ee8077..e008b99298a 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_base.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_base.go @@ -16,6 +16,7 @@ type fastBase struct { cur int32 // maximum offset. Should be at least 2x block size. maxMatchOff int32 + bufferReset int32 hist []byte crc *xxhash.Digest tmp [8]byte @@ -56,8 +57,8 @@ func (e *fastBase) Block() *blockEnc { } func (e *fastBase) addBlock(src []byte) int32 { - if debugAsserts && e.cur > bufferReset { - panic(fmt.Sprintf("ecur (%d) > buffer reset (%d)", e.cur, bufferReset)) + if debugAsserts && e.cur > e.bufferReset { + panic(fmt.Sprintf("ecur (%d) > buffer reset (%d)", e.cur, e.bufferReset)) } // check if we have space already if len(e.hist)+len(src) > cap(e.hist) { @@ -126,24 +127,7 @@ func (e *fastBase) matchlen(s, t int32, src []byte) int32 { panic(fmt.Sprintf("len(src)-s (%d) > maxCompressedBlockSize (%d)", len(src)-int(s), maxCompressedBlockSize)) } } - a := src[s:] - b := src[t:] - b = b[:len(a)] - end := int32((len(a) >> 3) << 3) - for i := int32(0); i < end; i += 8 { - if diff := load6432(a, i) ^ load6432(b, i); diff != 0 { - return i + int32(bits.TrailingZeros64(diff)>>3) - } - } - - a = a[end:] - b = b[end:] - for i := range a { - if a[i] != b[i] { - return int32(i) + end - } - } - return int32(len(a)) + end + return int32(matchLen(src[s:], src[t:])) } // Reset the encoding table. @@ -165,13 +149,13 @@ func (e *fastBase) resetBase(d *dict, singleBlock bool) { if singleBlock { e.lowMem = true } - e.ensureHist(d.DictContentSize() + maxCompressedBlockSize) + e.ensureHist(d.ContentSize() + maxCompressedBlockSize) e.lowMem = low } // We offset current position so everything will be out of reach. // If above reset line, history will be purged. - if e.cur < bufferReset { + if e.cur < e.bufferReset { e.cur += e.maxMatchOff + int32(len(e.hist)) } e.hist = e.hist[:0] diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go index 96028ecd836..830f5ba74a2 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_best.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -32,6 +32,7 @@ type match struct { length int32 rep int32 est int32 + _ [12]byte // Aligned size to cache line: 4+4+4+4+4 bytes + 12 bytes padding = 32 bytes } const highScore = 25000 @@ -84,14 +85,10 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = prevEntry{} - } - for i := range e.longTable[:] { - e.longTable[i] = prevEntry{} - } + e.table = [bestShortTableSize]prevEntry{} + e.longTable = [bestLongTableSize]prevEntry{} e.cur = e.maxMatchOff break } @@ -192,8 +189,8 @@ encodeLoop: panic("offset0 was 0") } - bestOf := func(a, b match) match { - if a.est+(a.s-b.s)*bitsPerByte>>10 < b.est+(b.s-a.s)*bitsPerByte>>10 { + bestOf := func(a, b *match) *match { + if a.est-b.est+(a.s-b.s)*bitsPerByte>>10 < 0 { return a } return b @@ -219,22 +216,26 @@ encodeLoop: return m } - best := bestOf(matchAt(candidateL.offset-e.cur, s, uint32(cv), -1), matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) - best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) - best = bestOf(best, matchAt(candidateS.prev-e.cur, s, uint32(cv), -1)) + m1 := matchAt(candidateL.offset-e.cur, s, uint32(cv), -1) + m2 := matchAt(candidateL.prev-e.cur, s, uint32(cv), -1) + m3 := matchAt(candidateS.offset-e.cur, s, uint32(cv), -1) + m4 := matchAt(candidateS.prev-e.cur, s, uint32(cv), -1) + best := bestOf(bestOf(&m1, &m2), bestOf(&m3, &m4)) if canRepeat && best.length < goodEnough { cv32 := uint32(cv >> 8) spp := s + 1 - best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1)) - best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2)) - best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3)) + m1 := matchAt(spp-offset1, spp, cv32, 1) + m2 := matchAt(spp-offset2, spp, cv32, 2) + m3 := matchAt(spp-offset3, spp, cv32, 3) + best = bestOf(bestOf(best, &m1), bestOf(&m2, &m3)) if best.length > 0 { cv32 = uint32(cv >> 24) spp += 2 - best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1)) - best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2)) - best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3)) + m1 := matchAt(spp-offset1, spp, cv32, 1) + m2 := matchAt(spp-offset2, spp, cv32, 2) + m3 := matchAt(spp-offset3, spp, cv32, 3) + best = bestOf(bestOf(best, &m1), bestOf(&m2, &m3)) } } // Load next and check... @@ -261,26 +262,33 @@ encodeLoop: candidateL2 := e.longTable[hashLen(cv2, bestLongTableBits, bestLongLen)] // Short at s+1 - best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) + m1 := matchAt(candidateS.offset-e.cur, s, uint32(cv), -1) // Long at s+1, s+2 - best = bestOf(best, matchAt(candidateL.offset-e.cur, s, uint32(cv), -1)) - best = bestOf(best, matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) - best = bestOf(best, matchAt(candidateL2.offset-e.cur, s+1, uint32(cv2), -1)) - best = bestOf(best, matchAt(candidateL2.prev-e.cur, s+1, uint32(cv2), -1)) + m2 := matchAt(candidateL.offset-e.cur, s, uint32(cv), -1) + m3 := matchAt(candidateL.prev-e.cur, s, uint32(cv), -1) + m4 := matchAt(candidateL2.offset-e.cur, s+1, uint32(cv2), -1) + m5 := matchAt(candidateL2.prev-e.cur, s+1, uint32(cv2), -1) + best = bestOf(bestOf(bestOf(best, &m1), &m2), bestOf(bestOf(&m3, &m4), &m5)) if false { // Short at s+3. // Too often worse... - best = bestOf(best, matchAt(e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+2, uint32(cv2>>8), -1)) + m := matchAt(e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+2, uint32(cv2>>8), -1) + best = bestOf(best, &m) } // See if we can find a better match by checking where the current best ends. // Use that offset to see if we can find a better full match. if sAt := best.s + best.length; sAt < sLimit { nextHashL := hashLen(load6432(src, sAt), bestLongTableBits, bestLongLen) candidateEnd := e.longTable[nextHashL] - if pos := candidateEnd.offset - e.cur - best.length; pos >= 0 { - bestEnd := bestOf(best, matchAt(pos, best.s, load3232(src, best.s), -1)) - if pos := candidateEnd.prev - e.cur - best.length; pos >= 0 { - bestEnd = bestOf(bestEnd, matchAt(pos, best.s, load3232(src, best.s), -1)) + // Start check at a fixed offset to allow for a few mismatches. + // For this compression level 2 yields the best results. + const skipBeginning = 2 + if pos := candidateEnd.offset - e.cur - best.length + skipBeginning; pos >= 0 { + m := matchAt(pos, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1) + bestEnd := bestOf(best, &m) + if pos := candidateEnd.prev - e.cur - best.length + skipBeginning; pos >= 0 { + m := matchAt(pos, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1) + bestEnd = bestOf(bestEnd, &m) } best = bestEnd } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index 602c05ee0c4..8582f31a7cc 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -62,14 +62,10 @@ func (e *betterFastEncoder) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - for i := range e.longTable[:] { - e.longTable[i] = prevEntry{} - } + e.table = [betterShortTableSize]tableEntry{} + e.longTable = [betterLongTableSize]prevEntry{} e.cur = e.maxMatchOff break } @@ -156,8 +152,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -416,15 +412,23 @@ encodeLoop: // Try to find a better match by searching for a long match at the end of the current best match if s+matched < sLimit { + // Allow some bytes at the beginning to mismatch. + // Sweet spot is around 3 bytes, but depends on input. + // The skipped bytes are tested in Extend backwards, + // and still picked up as part of the match if they do. + const skipBeginning = 3 + nextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen) - cv := load3232(src, s) + s2 := s + skipBeginning + cv := load3232(src, s2) candidateL := e.longTable[nextHashL] - coffsetL := candidateL.offset - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL := candidateL.offset - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("long match at end-of-match") @@ -434,12 +438,13 @@ encodeLoop: // Check prev long... if true { - coffsetL = candidateL.prev - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL = candidateL.prev - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("prev long match at end-of-match") @@ -518,8 +523,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -578,7 +583,7 @@ func (e *betterFastEncoderDict) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { for i := range e.table[:] { e.table[i] = tableEntry{} @@ -674,8 +679,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -1047,8 +1052,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index d6b3104240b..7d425109adb 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -44,14 +44,10 @@ func (e *doubleFastEncoder) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - for i := range e.longTable[:] { - e.longTable[i] = tableEntry{} - } + e.table = [dFastShortTableSize]tableEntry{} + e.longTable = [dFastLongTableSize]tableEntry{} e.cur = e.maxMatchOff break } @@ -127,8 +123,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -388,7 +384,7 @@ func (e *doubleFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - if e.cur >= bufferReset { + if e.cur >= e.bufferReset { for i := range e.table[:] { e.table[i] = tableEntry{} } @@ -439,8 +435,8 @@ encodeLoop: var t int32 for { - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -685,7 +681,7 @@ encodeLoop: } // We do not store history, so we must offset e.cur to avoid false matches for next user. - if e.cur < bufferReset { + if e.cur < e.bufferReset { e.cur += int32(len(src)) } } @@ -700,7 +696,7 @@ func (e *doubleFastEncoderDict) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { for i := range e.table[:] { e.table[i] = tableEntry{} @@ -785,8 +781,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -969,7 +965,7 @@ encodeLoop: te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)} te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)} longHash1 := hashLen(cv0, dFastLongTableBits, dFastLongLen) - longHash2 := hashLen(cv0, dFastLongTableBits, dFastLongLen) + longHash2 := hashLen(cv1, dFastLongTableBits, dFastLongLen) e.longTable[longHash1] = te0 e.longTable[longHash2] = te1 e.markLongShardDirty(longHash1) @@ -1002,8 +998,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -1103,7 +1099,8 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { } if allDirty || dirtyShardCnt > dLongTableShardCnt/2 { - copy(e.longTable[:], e.dictLongTable) + //copy(e.longTable[:], e.dictLongTable) + e.longTable = *(*[dFastLongTableSize]tableEntry)(e.dictLongTable) for i := range e.longTableShardDirty { e.longTableShardDirty[i] = false } @@ -1114,7 +1111,9 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + // copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + *(*[dLongTableShardSize]tableEntry)(e.longTable[i*dLongTableShardSize:]) = *(*[dLongTableShardSize]tableEntry)(e.dictLongTable[i*dLongTableShardSize:]) + e.longTableShardDirty[i] = false } } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index f51ab529a0b..315b1a8f2f6 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -43,7 +43,7 @@ func (e *fastEncoder) Encode(blk *blockEnc, src []byte) { ) // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { for i := range e.table[:] { e.table[i] = tableEntry{} @@ -304,13 +304,13 @@ func (e *fastEncoder) EncodeNoHist(blk *blockEnc, src []byte) { minNonLiteralBlockSize = 1 + 1 + inputMargin ) if debugEncoder { - if len(src) > maxBlockSize { + if len(src) > maxCompressedBlockSize { panic("src too big") } } // Protect against e.cur wraparound. - if e.cur >= bufferReset { + if e.cur >= e.bufferReset { for i := range e.table[:] { e.table[i] = tableEntry{} } @@ -538,7 +538,7 @@ encodeLoop: println("returning, recent offsets:", blk.recentOffsets, "extra literals:", blk.extraLits) } // We do not store history, so we must offset e.cur to avoid false matches for next user. - if e.cur < bufferReset { + if e.cur < e.bufferReset { e.cur += int32(len(src)) } } @@ -555,11 +555,9 @@ func (e *fastEncoderDict) Encode(blk *blockEnc, src []byte) { return } // Protect against e.cur wraparound. - for e.cur >= bufferReset { + for e.cur >= e.bufferReset-int32(len(e.hist)) { if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } + e.table = [tableSize]tableEntry{} e.cur = e.maxMatchOff break } @@ -871,7 +869,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { const shardCnt = tableShardCnt const shardSize = tableShardSize if e.allDirty || dirtyShardCnt > shardCnt*4/6 { - copy(e.table[:], e.dictTable) + //copy(e.table[:], e.dictTable) + e.table = *(*[tableSize]tableEntry)(e.dictTable) for i := range e.tableShardDirty { e.tableShardDirty[i] = false } @@ -883,7 +882,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + //copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + *(*[shardSize]tableEntry)(e.table[i*shardSize:]) = *(*[shardSize]tableEntry)(e.dictTable[i*shardSize:]) e.tableShardDirty[i] = false } e.allDirty = false diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go index dcc987a7cb6..65c6c36dc13 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "fmt" "io" + "math" rdebug "runtime/debug" "sync" @@ -528,8 +529,8 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { // If a non-single block is needed the encoder will reset again. e.encoders <- enc }() - // Use single segments when above minimum window and below 1MB. - single := len(src) < 1<<20 && len(src) > MinWindowSize + // Use single segments when above minimum window and below window size. + single := len(src) <= e.o.windowSize && len(src) > MinWindowSize if e.o.single != nil { single = *e.o.single } @@ -551,7 +552,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { } // If we can do everything in one block, prefer that. - if len(src) <= maxCompressedBlockSize { + if len(src) <= e.o.blockSize { enc.Reset(e.o.dict, true) // Slightly faster with no history and everything in one block. if e.o.crc { @@ -639,3 +640,37 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { } return dst } + +// MaxEncodedSize returns the expected maximum +// size of an encoded block or stream. +func (e *Encoder) MaxEncodedSize(size int) int { + frameHeader := 4 + 2 // magic + frame header & window descriptor + if e.o.dict != nil { + frameHeader += 4 + } + // Frame content size: + if size < 256 { + frameHeader++ + } else if size < 65536+256 { + frameHeader += 2 + } else if size < math.MaxInt32 { + frameHeader += 4 + } else { + frameHeader += 8 + } + // Final crc + if e.o.crc { + frameHeader += 4 + } + + // Max overhead is 3 bytes/block. + // There cannot be 0 blocks. + blocks := (size + e.o.blockSize) / e.o.blockSize + + // Combine, add padding. + maxSz := frameHeader + 3*blocks + size + if e.o.pad > 1 { + maxSz += calcSkippableFrame(int64(maxSz), int64(e.o.pad)) + } + return maxSz +} diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index 44d8dbd199a..8e15be2f7f8 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -3,6 +3,8 @@ package zstd import ( "errors" "fmt" + "math" + "math/bits" "runtime" "strings" ) @@ -47,22 +49,22 @@ func (o encoderOptions) encoder() encoder { switch o.level { case SpeedFastest: if o.dict != nil { - return &fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}} + return &fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}} } - return &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}} + return &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}} case SpeedDefault: if o.dict != nil { - return &doubleFastEncoderDict{fastEncoderDict: fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}}} + return &doubleFastEncoderDict{fastEncoderDict: fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}}} } - return &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}} + return &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}} case SpeedBetterCompression: if o.dict != nil { - return &betterFastEncoderDict{betterFastEncoder: betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}}} + return &betterFastEncoderDict{betterFastEncoder: betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}} } - return &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}} + return &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}} case SpeedBestCompression: - return &bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), lowMem: o.lowMem}} + return &bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}} } panic("unknown compression level") } @@ -283,7 +285,7 @@ func WithNoEntropyCompression(b bool) EOption { // a decoder is allowed to reject a compressed frame which requests a memory size beyond decoder's authorized range. // For broader compatibility, decoders are recommended to support memory sizes of at least 8 MB. // This is only a recommendation, each decoder is free to support higher or lower limits, depending on local limitations. -// If this is not specified, block encodes will automatically choose this based on the input size. +// If this is not specified, block encodes will automatically choose this based on the input size and the window size. // This setting has no effect on streamed encodes. func WithSingleSegment(b bool) EOption { return func(o *encoderOptions) error { @@ -304,7 +306,13 @@ func WithLowerEncoderMem(b bool) EOption { } // WithEncoderDict allows to register a dictionary that will be used for the encode. +// +// The slice dict must be in the [dictionary format] produced by +// "zstd --train" from the Zstandard reference implementation. +// // The encoder *may* choose to use no dictionary instead for certain payloads. +// +// [dictionary format]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format func WithEncoderDict(dict []byte) EOption { return func(o *encoderOptions) error { d, err := loadDict(dict) @@ -315,3 +323,17 @@ func WithEncoderDict(dict []byte) EOption { return nil } } + +// WithEncoderDictRaw registers a dictionary that may be used by the encoder. +// +// The slice content may contain arbitrary data. It will be used as an initial +// history. +func WithEncoderDictRaw(id uint32, content []byte) EOption { + return func(o *encoderOptions) error { + if bits.UintSize > 32 && uint(len(content)) > dictMaxLength { + return fmt.Errorf("dictionary of size %d > 2GiB too large", len(content)) + } + o.dict = &dict{id: id, content: content, offsets: [3]int{1, 4, 8}} + return nil + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index 11089d22328..d8e8a05bd73 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -5,7 +5,7 @@ package zstd import ( - "bytes" + "encoding/binary" "encoding/hex" "errors" "io" @@ -29,7 +29,7 @@ type frameDec struct { FrameContentSize uint64 - DictionaryID *uint32 + DictionaryID uint32 HasCheckSum bool SingleSegment bool } @@ -43,9 +43,9 @@ const ( MaxWindowSize = 1 << 29 ) -var ( - frameMagic = []byte{0x28, 0xb5, 0x2f, 0xfd} - skippableFrameMagic = []byte{0x2a, 0x4d, 0x18} +const ( + frameMagic = "\x28\xb5\x2f\xfd" + skippableFrameMagic = "\x2a\x4d\x18" ) func newFrameDec(o decoderOptions) *frameDec { @@ -89,9 +89,9 @@ func (d *frameDec) reset(br byteBuffer) error { copy(signature[1:], b) } - if !bytes.Equal(signature[1:4], skippableFrameMagic) || signature[0]&0xf0 != 0x50 { + if string(signature[1:4]) != skippableFrameMagic || signature[0]&0xf0 != 0x50 { if debugDecoder { - println("Not skippable", hex.EncodeToString(signature[:]), hex.EncodeToString(skippableFrameMagic)) + println("Not skippable", hex.EncodeToString(signature[:]), hex.EncodeToString([]byte(skippableFrameMagic))) } // Break if not skippable frame. break @@ -106,7 +106,7 @@ func (d *frameDec) reset(br byteBuffer) error { } n := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24) println("Skipping frame with", n, "bytes.") - err = br.skipN(int(n)) + err = br.skipN(int64(n)) if err != nil { if debugDecoder { println("Reading discarded frame", err) @@ -114,9 +114,9 @@ func (d *frameDec) reset(br byteBuffer) error { return err } } - if !bytes.Equal(signature[:], frameMagic) { + if string(signature[:]) != frameMagic { if debugDecoder { - println("Got magic numbers: ", signature, "want:", frameMagic) + println("Got magic numbers: ", signature, "want:", []byte(frameMagic)) } return ErrMagicMismatch } @@ -155,7 +155,7 @@ func (d *frameDec) reset(br byteBuffer) error { // Read Dictionary_ID // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary_id - d.DictionaryID = nil + d.DictionaryID = 0 if size := fhd & 3; size != 0 { if size == 3 { size = 4 @@ -167,7 +167,7 @@ func (d *frameDec) reset(br byteBuffer) error { return err } var id uint32 - switch size { + switch len(b) { case 1: id = uint32(b[0]) case 2: @@ -178,11 +178,7 @@ func (d *frameDec) reset(br byteBuffer) error { if debugDecoder { println("Dict size", size, "ID:", id) } - if id > 0 { - // ID 0 means "sorry, no dictionary anyway". - // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format - d.DictionaryID = &id - } + d.DictionaryID = id } // Read Frame_Content_Size @@ -204,7 +200,7 @@ func (d *frameDec) reset(br byteBuffer) error { println("Reading Frame content", err) return err } - switch fcsSize { + switch len(b) { case 1: d.FrameContentSize = uint64(b[0]) case 2: @@ -231,20 +227,27 @@ func (d *frameDec) reset(br byteBuffer) error { d.crc.Reset() } + if d.WindowSize > d.o.maxWindowSize { + if debugDecoder { + printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + } + return ErrWindowSizeExceeded + } + if d.WindowSize == 0 && d.SingleSegment { // We may not need window in this case. d.WindowSize = d.FrameContentSize if d.WindowSize < MinWindowSize { d.WindowSize = MinWindowSize } - } - - if d.WindowSize > uint64(d.o.maxWindowSize) { - if debugDecoder { - printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + if d.WindowSize > d.o.maxDecodedSize { + if debugDecoder { + printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + } + return ErrDecoderSizeExceeded } - return ErrWindowSizeExceeded } + // The minimum Window_Size is 1 KB. if d.WindowSize < MinWindowSize { if debugDecoder { @@ -253,11 +256,17 @@ func (d *frameDec) reset(br byteBuffer) error { return ErrWindowSizeTooSmall } d.history.windowSize = int(d.WindowSize) - if d.o.lowMem && d.history.windowSize < maxBlockSize { + if !d.o.lowMem || d.history.windowSize < maxBlockSize { + // Alloc 2x window size if not low-mem, or window size below 2MB. d.history.allocFrameBuffer = d.history.windowSize * 2 - // TODO: Maybe use FrameContent size } else { - d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize + if d.o.lowMem { + // Alloc with 1MB extra. + d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize/2 + } else { + // Alloc with 2MB extra. + d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize + } } if debugDecoder { @@ -290,34 +299,47 @@ func (d *frameDec) checkCRC() error { if !d.HasCheckSum { return nil } - var tmp [4]byte - got := d.crc.Sum64() - // Flip to match file order. - tmp[0] = byte(got >> 0) - tmp[1] = byte(got >> 8) - tmp[2] = byte(got >> 16) - tmp[3] = byte(got >> 24) // We can overwrite upper tmp now - want, err := d.rawInput.readSmall(4) + buf, err := d.rawInput.readSmall(4) if err != nil { println("CRC missing?", err) return err } - if !bytes.Equal(tmp[:], want) && !ignoreCRC { + if d.o.ignoreChecksum { + return nil + } + + want := binary.LittleEndian.Uint32(buf[:4]) + got := uint32(d.crc.Sum64()) + + if got != want { if debugDecoder { - println("CRC Check Failed:", tmp[:], "!=", want) + printf("CRC check failed: got %08x, want %08x\n", got, want) } return ErrCRCMismatch } if debugDecoder { - println("CRC ok", tmp[:]) + printf("CRC ok %08x\n", got) } return nil } -// runDecoder will create a sync decoder that will decode a block of data. +// consumeCRC reads the checksum data if the frame has one. +func (d *frameDec) consumeCRC() error { + if d.HasCheckSum { + _, err := d.rawInput.readSmall(4) + if err != nil { + println("CRC missing?", err) + return err + } + } + + return nil +} + +// runDecoder will run the decoder for the remainder of the frame. func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { saved := d.history.b @@ -326,6 +348,30 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { d.history.ignoreBuffer = len(dst) // Store input length, so we only check new data. crcStart := len(dst) + d.history.decoders.maxSyncLen = 0 + if d.o.limitToCap { + d.history.decoders.maxSyncLen = uint64(cap(dst) - len(dst)) + } + if d.FrameContentSize != fcsUnknown { + if !d.o.limitToCap || d.FrameContentSize+uint64(len(dst)) < d.history.decoders.maxSyncLen { + d.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst)) + } + if d.history.decoders.maxSyncLen > d.o.maxDecodedSize { + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen, "> maxDecodedSize:", d.o.maxDecodedSize) + } + return dst, ErrDecoderSizeExceeded + } + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen) + } + if !d.o.limitToCap && uint64(cap(dst)) < d.history.decoders.maxSyncLen { + // Alloc for output + dst2 := make([]byte, len(dst), d.history.decoders.maxSyncLen+compressedBlockOverAlloc) + copy(dst2, dst) + dst = dst2 + } + } var err error for { err = dec.reset(d.rawInput, d.WindowSize) @@ -339,7 +385,13 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if err != nil { break } - if uint64(len(d.history.b)) > d.o.maxDecodedSize { + if uint64(len(d.history.b)-crcStart) > d.o.maxDecodedSize { + println("runDecoder: maxDecodedSize exceeded", uint64(len(d.history.b)-crcStart), ">", d.o.maxDecodedSize) + err = ErrDecoderSizeExceeded + break + } + if d.o.limitToCap && len(d.history.b) > cap(dst) { + println("runDecoder: cap exceeded", uint64(len(d.history.b)), ">", cap(dst)) err = ErrDecoderSizeExceeded break } @@ -360,13 +412,17 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if d.FrameContentSize != fcsUnknown && uint64(len(d.history.b)-crcStart) != d.FrameContentSize { err = ErrFrameSizeMismatch } else if d.HasCheckSum { - var n int - n, err = d.crc.Write(dst[crcStart:]) - if err == nil { - if n != len(dst)-crcStart { - err = io.ErrShortWrite - } else { - err = d.checkCRC() + if d.o.ignoreChecksum { + err = d.consumeCRC() + } else { + var n int + n, err = d.crc.Write(dst[crcStart:]) + if err == nil { + if n != len(dst)-crcStart { + err = io.ErrShortWrite + } else { + err = d.checkCRC() + } } } } diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go index bb3d4fd6c31..2f8860a722b 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go @@ -5,8 +5,10 @@ package zstd import ( + "encoding/binary" "errors" "fmt" + "io" ) const ( @@ -178,10 +180,32 @@ func (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error { return fmt.Errorf("corruption detected (total %d != %d)", gotTotal, 1<> 3) - // println(s.norm[:s.symbolLen], s.symbolLen) return s.buildDtable() } +func (s *fseDecoder) mustReadFrom(r io.Reader) { + fatalErr := func(err error) { + if err != nil { + panic(err) + } + } + // dt [maxTablesize]decSymbol // Decompression table. + // symbolLen uint16 // Length of active part of the symbol table. + // actualTableLog uint8 // Selected tablelog. + // maxBits uint8 // Maximum number of additional bits + // // used for table creation to avoid allocations. + // stateTable [256]uint16 + // norm [maxSymbolValue + 1]int16 + // preDefined bool + fatalErr(binary.Read(r, binary.LittleEndian, &s.dt)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.symbolLen)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.actualTableLog)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.maxBits)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.stateTable)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.norm)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.preDefined)) +} + // decSymbol contains information about a state entry, // Including the state offset base, the output symbol and // the number of bits to read for the low part of the destination state. @@ -204,18 +228,10 @@ func (d decSymbol) newState() uint16 { return uint16(d >> 16) } -func (d decSymbol) baseline() uint32 { - return uint32(d >> 32) -} - func (d decSymbol) baselineInt() int { return int(d >> 32) } -func (d *decSymbol) set(nbits, addBits uint8, newState uint16, baseline uint32) { - *d = decSymbol(nbits) | (decSymbol(addBits) << 8) | (decSymbol(newState) << 16) | (decSymbol(baseline) << 32) -} - func (d *decSymbol) setNBits(nBits uint8) { const mask = 0xffffffffffffff00 *d = (*d & mask) | decSymbol(nBits) @@ -231,11 +247,6 @@ func (d *decSymbol) setNewState(state uint16) { *d = (*d & mask) | decSymbol(state)<<16 } -func (d *decSymbol) setBaseline(baseline uint32) { - const mask = 0xffffffff - *d = (*d & mask) | decSymbol(baseline)<<32 -} - func (d *decSymbol) setExt(addBits uint8, baseline uint32) { const mask = 0xffff00ff *d = (*d & mask) | (decSymbol(addBits) << 8) | (decSymbol(baseline) << 32) @@ -257,68 +268,6 @@ func (s *fseDecoder) setRLE(symbol decSymbol) { s.dt[0] = symbol } -// buildDtable will build the decoding table. -func (s *fseDecoder) buildDtable() error { - tableSize := uint32(1 << s.actualTableLog) - highThreshold := tableSize - 1 - symbolNext := s.stateTable[:256] - - // Init, lay down lowprob symbols - { - for i, v := range s.norm[:s.symbolLen] { - if v == -1 { - s.dt[highThreshold].setAddBits(uint8(i)) - highThreshold-- - symbolNext[i] = 1 - } else { - symbolNext[i] = uint16(v) - } - } - } - // Spread symbols - { - tableMask := tableSize - 1 - step := tableStep(tableSize) - position := uint32(0) - for ss, v := range s.norm[:s.symbolLen] { - for i := 0; i < int(v); i++ { - s.dt[position].setAddBits(uint8(ss)) - position = (position + step) & tableMask - for position > highThreshold { - // lowprob area - position = (position + step) & tableMask - } - } - } - if position != 0 { - // position must reach all cells once, otherwise normalizedCounter is incorrect - return errors.New("corrupted input (position != 0)") - } - } - - // Build Decoding table - { - tableSize := uint16(1 << s.actualTableLog) - for u, v := range s.dt[:tableSize] { - symbol := v.addBits() - nextState := symbolNext[symbol] - symbolNext[symbol] = nextState + 1 - nBits := s.actualTableLog - byte(highBits(uint32(nextState))) - s.dt[u&maxTableMask].setNBits(nBits) - newState := (nextState << nBits) - tableSize - if newState > tableSize { - return fmt.Errorf("newState (%d) outside table size (%d)", newState, tableSize) - } - if newState == uint16(u) && nBits == 0 { - // Seems weird that this is possible with nbits > 0. - return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, u) - } - s.dt[u&maxTableMask].setNewState(newState) - } - } - return nil -} - // transform will transform the decoder table into a table usable for // decoding without having to apply the transformation while decoding. // The state will contain the base value and the number of bits to read. @@ -352,34 +301,7 @@ func (s *fseState) init(br *bitReader, tableLog uint8, dt []decSymbol) { s.state = dt[br.getBits(tableLog)] } -// next returns the current symbol and sets the next state. -// At least tablelog bits must be available in the bit reader. -func (s *fseState) next(br *bitReader) { - lowBits := uint16(br.getBits(s.state.nbBits())) - s.state = s.dt[s.state.newState()+lowBits] -} - -// finished returns true if all bits have been read from the bitstream -// and the next state would require reading bits from the input. -func (s *fseState) finished(br *bitReader) bool { - return br.finished() && s.state.nbBits() > 0 -} - -// final returns the current state symbol without decoding the next. -func (s *fseState) final() (int, uint8) { - return s.state.baselineInt(), s.state.addBits() -} - // final returns the current state symbol without decoding the next. func (s decSymbol) final() (int, uint8) { return s.baselineInt(), s.addBits() } - -// nextFast returns the next symbol and sets the next state. -// This can only be used if no symbols are 0 bits. -// At least tablelog bits must be available in the bit reader. -func (s *fseState) nextFast(br *bitReader) (uint32, uint8) { - lowBits := br.get16BitsFast(s.state.nbBits()) - s.state = s.dt[s.state.newState()+lowBits] - return s.state.baseline(), s.state.addBits() -} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go new file mode 100644 index 00000000000..d04a829b0a0 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go @@ -0,0 +1,65 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package zstd + +import ( + "fmt" +) + +type buildDtableAsmContext struct { + // inputs + stateTable *uint16 + norm *int16 + dt *uint64 + + // outputs --- set by the procedure in the case of error; + // for interpretation please see the error handling part below + errParam1 uint64 + errParam2 uint64 +} + +// buildDtable_asm is an x86 assembly implementation of fseDecoder.buildDtable. +// Function returns non-zero exit code on error. +// +//go:noescape +func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int + +// please keep in sync with _generate/gen_fse.go +const ( + errorCorruptedNormalizedCounter = 1 + errorNewStateTooBig = 2 + errorNewStateNoBits = 3 +) + +// buildDtable will build the decoding table. +func (s *fseDecoder) buildDtable() error { + ctx := buildDtableAsmContext{ + stateTable: &s.stateTable[0], + norm: &s.norm[0], + dt: (*uint64)(&s.dt[0]), + } + code := buildDtable_asm(s, &ctx) + + if code != 0 { + switch code { + case errorCorruptedNormalizedCounter: + position := ctx.errParam1 + return fmt.Errorf("corrupted input (position=%d, expected 0)", position) + + case errorNewStateTooBig: + newState := decSymbol(ctx.errParam1) + size := ctx.errParam2 + return fmt.Errorf("newState (%d) outside table size (%d)", newState, size) + + case errorNewStateNoBits: + newState := decSymbol(ctx.errParam1) + oldState := decSymbol(ctx.errParam2) + return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, oldState) + + default: + return fmt.Errorf("buildDtable_asm returned unhandled nonzero code = %d", code) + } + } + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s new file mode 100644 index 00000000000..bcde3986953 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s @@ -0,0 +1,126 @@ +// Code generated by command: go run gen_fse.go -out ../fse_decoder_amd64.s -pkg=zstd. DO NOT EDIT. + +//go:build !appengine && !noasm && gc && !noasm + +// func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int +TEXT ·buildDtable_asm(SB), $0-24 + MOVQ ctx+8(FP), CX + MOVQ s+0(FP), DI + + // Load values + MOVBQZX 4098(DI), DX + XORQ AX, AX + BTSQ DX, AX + MOVQ (CX), BX + MOVQ 16(CX), SI + LEAQ -1(AX), R8 + MOVQ 8(CX), CX + MOVWQZX 4096(DI), DI + + // End load values + // Init, lay down lowprob symbols + XORQ R9, R9 + JMP init_main_loop_condition + +init_main_loop: + MOVWQSX (CX)(R9*2), R10 + CMPW R10, $-1 + JNE do_not_update_high_threshold + MOVB R9, 1(SI)(R8*8) + DECQ R8 + MOVQ $0x0000000000000001, R10 + +do_not_update_high_threshold: + MOVW R10, (BX)(R9*2) + INCQ R9 + +init_main_loop_condition: + CMPQ R9, DI + JL init_main_loop + + // Spread symbols + // Calculate table step + MOVQ AX, R9 + SHRQ $0x01, R9 + MOVQ AX, R10 + SHRQ $0x03, R10 + LEAQ 3(R9)(R10*1), R9 + + // Fill add bits values + LEAQ -1(AX), R10 + XORQ R11, R11 + XORQ R12, R12 + JMP spread_main_loop_condition + +spread_main_loop: + XORQ R13, R13 + MOVWQSX (CX)(R12*2), R14 + JMP spread_inner_loop_condition + +spread_inner_loop: + MOVB R12, 1(SI)(R11*8) + +adjust_position: + ADDQ R9, R11 + ANDQ R10, R11 + CMPQ R11, R8 + JG adjust_position + INCQ R13 + +spread_inner_loop_condition: + CMPQ R13, R14 + JL spread_inner_loop + INCQ R12 + +spread_main_loop_condition: + CMPQ R12, DI + JL spread_main_loop + TESTQ R11, R11 + JZ spread_check_ok + MOVQ ctx+8(FP), AX + MOVQ R11, 24(AX) + MOVQ $+1, ret+16(FP) + RET + +spread_check_ok: + // Build Decoding table + XORQ DI, DI + +build_table_main_table: + MOVBQZX 1(SI)(DI*8), CX + MOVWQZX (BX)(CX*2), R8 + LEAQ 1(R8), R9 + MOVW R9, (BX)(CX*2) + MOVQ R8, R9 + BSRQ R9, R9 + MOVQ DX, CX + SUBQ R9, CX + SHLQ CL, R8 + SUBQ AX, R8 + MOVB CL, (SI)(DI*8) + MOVW R8, 2(SI)(DI*8) + CMPQ R8, AX + JLE build_table_check1_ok + MOVQ ctx+8(FP), CX + MOVQ R8, 24(CX) + MOVQ AX, 32(CX) + MOVQ $+2, ret+16(FP) + RET + +build_table_check1_ok: + TESTB CL, CL + JNZ build_table_check2_ok + CMPW R8, DI + JNE build_table_check2_ok + MOVQ ctx+8(FP), AX + MOVQ R8, 24(AX) + MOVQ DI, 32(AX) + MOVQ $+3, ret+16(FP) + RET + +build_table_check2_ok: + INCQ DI + CMPQ DI, AX + JL build_table_main_table + MOVQ $+0, ret+16(FP) + RET diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go new file mode 100644 index 00000000000..332e51fe44f --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go @@ -0,0 +1,72 @@ +//go:build !amd64 || appengine || !gc || noasm +// +build !amd64 appengine !gc noasm + +package zstd + +import ( + "errors" + "fmt" +) + +// buildDtable will build the decoding table. +func (s *fseDecoder) buildDtable() error { + tableSize := uint32(1 << s.actualTableLog) + highThreshold := tableSize - 1 + symbolNext := s.stateTable[:256] + + // Init, lay down lowprob symbols + { + for i, v := range s.norm[:s.symbolLen] { + if v == -1 { + s.dt[highThreshold].setAddBits(uint8(i)) + highThreshold-- + symbolNext[i] = 1 + } else { + symbolNext[i] = uint16(v) + } + } + } + + // Spread symbols + { + tableMask := tableSize - 1 + step := tableStep(tableSize) + position := uint32(0) + for ss, v := range s.norm[:s.symbolLen] { + for i := 0; i < int(v); i++ { + s.dt[position].setAddBits(uint8(ss)) + position = (position + step) & tableMask + for position > highThreshold { + // lowprob area + position = (position + step) & tableMask + } + } + } + if position != 0 { + // position must reach all cells once, otherwise normalizedCounter is incorrect + return errors.New("corrupted input (position != 0)") + } + } + + // Build Decoding table + { + tableSize := uint16(1 << s.actualTableLog) + for u, v := range s.dt[:tableSize] { + symbol := v.addBits() + nextState := symbolNext[symbol] + symbolNext[symbol] = nextState + 1 + nBits := s.actualTableLog - byte(highBits(uint32(nextState))) + s.dt[u&maxTableMask].setNBits(nBits) + newState := (nextState << nBits) - tableSize + if newState > tableSize { + return fmt.Errorf("newState (%d) outside table size (%d)", newState, tableSize) + } + if newState == uint16(u) && nBits == 0 { + // Seems weird that this is possible with nbits > 0. + return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, u) + } + s.dt[u&maxTableMask].setNewState(newState) + } + } + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go index 5442061b18d..ab26326a8ff 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go @@ -76,21 +76,6 @@ func (s *fseEncoder) HistogramFinished(maxSymbol uint8, maxCount int) { s.clearCount = maxCount != 0 } -// prepare will prepare and allocate scratch tables used for both compression and decompression. -func (s *fseEncoder) prepare() (*fseEncoder, error) { - if s == nil { - s = &fseEncoder{} - } - s.useRLE = false - if s.clearCount && s.maxCount == 0 { - for i := range s.count { - s.count[i] = 0 - } - s.clearCount = false - } - return s, nil -} - // allocCtable will allocate tables needed for compression. // If existing tables a re big enough, they are simply re-used. func (s *fseEncoder) allocCtable() { @@ -709,14 +694,6 @@ func (c *cState) init(bw *bitWriter, ct *cTable, first symbolTransform) { c.state = c.stateTable[lu] } -// encode the output symbol provided and write it to the bitstream. -func (c *cState) encode(symbolTT symbolTransform) { - nbBitsOut := (uint32(c.state) + symbolTT.deltaNbBits) >> 16 - dstState := int32(c.state>>(nbBitsOut&15)) + int32(symbolTT.deltaFindState) - c.bw.addBits16NC(c.state, uint8(nbBitsOut)) - c.state = c.stateTable[dstState] -} - // flush will write the tablelog to the output and flush the remaining full bytes. func (c *cState) flush(tableLog uint8) { c.bw.flush32() diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz.go b/vendor/github.com/klauspost/compress/zstd/fuzz.go deleted file mode 100644 index 7f2210e0530..00000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build ignorecrc -// +build ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = true diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go b/vendor/github.com/klauspost/compress/zstd/fuzz_none.go deleted file mode 100644 index 6811c68a893..00000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !ignorecrc -// +build !ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = false diff --git a/vendor/github.com/klauspost/compress/zstd/hash.go b/vendor/github.com/klauspost/compress/zstd/hash.go index cf33f29a1b4..5d73c21ebdd 100644 --- a/vendor/github.com/klauspost/compress/zstd/hash.go +++ b/vendor/github.com/klauspost/compress/zstd/hash.go @@ -33,9 +33,3 @@ func hashLen(u uint64, length, mls uint8) uint32 { return (uint32(u) * prime4bytes) >> (32 - length) } } - -// hash3 returns the hash of the lower 3 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash3(u uint32, h uint8) uint32 { - return ((u << (32 - 24)) * prime3bytes) >> ((32 - h) & 31) -} diff --git a/vendor/github.com/klauspost/compress/zstd/history.go b/vendor/github.com/klauspost/compress/zstd/history.go index 28b40153cc2..09164856d22 100644 --- a/vendor/github.com/klauspost/compress/zstd/history.go +++ b/vendor/github.com/klauspost/compress/zstd/history.go @@ -37,24 +37,21 @@ func (h *history) reset() { h.ignoreBuffer = 0 h.error = false h.recentOffsets = [3]int{1, 4, 8} - if f := h.decoders.litLengths.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } - if f := h.decoders.offsets.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } - if f := h.decoders.matchLengths.fse; f != nil && !f.preDefined { - fseDecoderPool.Put(f) - } + h.decoders.freeDecoders() h.decoders = sequenceDecs{br: h.decoders.br} + h.freeHuffDecoder() + h.huffTree = nil + h.dict = nil + //printf("history created: %+v (l: %d, c: %d)", *h, len(h.b), cap(h.b)) +} + +func (h *history) freeHuffDecoder() { if h.huffTree != nil { if h.dict == nil || h.dict.litEnc != h.huffTree { huffDecoderPool.Put(h.huffTree) + h.huffTree = nil } } - h.huffTree = nil - h.dict = nil - //printf("history created: %+v (l: %d, c: %d)", *h, len(h.b), cap(h.b)) } func (h *history) setDict(dict *dict) { diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md index 69aa3bb587c..777290d44ce 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md @@ -2,12 +2,7 @@ VENDORED: Go to [github.com/cespare/xxhash](https://github.com/cespare/xxhash) for original package. - -[![GoDoc](https://godoc.org/github.com/cespare/xxhash?status.svg)](https://godoc.org/github.com/cespare/xxhash) -[![Build Status](https://travis-ci.org/cespare/xxhash.svg?branch=master)](https://travis-ci.org/cespare/xxhash) - -xxhash is a Go implementation of the 64-bit -[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a +xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a high-quality hashing algorithm that is much faster than anything in the Go standard library. @@ -28,31 +23,49 @@ func (*Digest) WriteString(string) (int, error) func (*Digest) Sum64() uint64 ``` -This implementation provides a fast pure-Go implementation and an even faster -assembly implementation for amd64. +The package is written with optimized pure Go and also contains even faster +assembly implementations for amd64 and arm64. If desired, the `purego` build tag +opts into using the Go code even on those architectures. + +[xxHash]: http://cyan4973.github.io/xxHash/ + +## Compatibility + +This package is in a module and the latest code is in version 2 of the module. +You need a version of Go with at least "minimal module compatibility" to use +github.com/cespare/xxhash/v2: + +* 1.9.7+ for Go 1.9 +* 1.10.3+ for Go 1.10 +* Go 1.11 or later + +I recommend using the latest release of Go. ## Benchmarks Here are some quick benchmarks comparing the pure-Go and assembly implementations of Sum64. -| input size | purego | asm | -| --- | --- | --- | -| 5 B | 979.66 MB/s | 1291.17 MB/s | -| 100 B | 7475.26 MB/s | 7973.40 MB/s | -| 4 KB | 17573.46 MB/s | 17602.65 MB/s | -| 10 MB | 17131.46 MB/s | 17142.16 MB/s | +| input size | purego | asm | +| ---------- | --------- | --------- | +| 4 B | 1.3 GB/s | 1.2 GB/s | +| 16 B | 2.9 GB/s | 3.5 GB/s | +| 100 B | 6.9 GB/s | 8.1 GB/s | +| 4 KB | 11.7 GB/s | 16.7 GB/s | +| 10 MB | 12.0 GB/s | 17.3 GB/s | -These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using -the following commands under Go 1.11.2: +These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C +CPU using the following commands under Go 1.19.2: ``` -$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes' -$ go test -benchtime 10s -bench '/xxhash,direct,bytes' +benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$') +benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') ``` ## Projects using this package - [InfluxDB](https://github.com/influxdata/influxdb) - [Prometheus](https://github.com/prometheus/prometheus) +- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) - [FreeCache](https://github.com/coocood/freecache) +- [FastCache](https://github.com/VictoriaMetrics/fastcache) diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go index 2c112a0ab1c..fc40c820016 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go @@ -18,19 +18,11 @@ const ( prime5 uint64 = 2870177450012600261 ) -// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where -// possible in the Go code is worth a small (but measurable) performance boost -// by avoiding some MOVQs. Vars are needed for the asm and also are useful for -// convenience in the Go code in a few places where we need to intentionally -// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the -// result overflows a uint64). -var ( - prime1v = prime1 - prime2v = prime2 - prime3v = prime3 - prime4v = prime4 - prime5v = prime5 -) +// Store the primes in an array as well. +// +// The consts are used when possible in Go code to avoid MOVs but we need a +// contiguous array of the assembly code. +var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} // Digest implements hash.Hash64. type Digest struct { @@ -52,10 +44,10 @@ func New() *Digest { // Reset clears the Digest's state so that it can be reused. func (d *Digest) Reset() { - d.v1 = prime1v + prime2 + d.v1 = primes[0] + prime2 d.v2 = prime2 d.v3 = 0 - d.v4 = -prime1v + d.v4 = -primes[0] d.total = 0 d.n = 0 } @@ -71,21 +63,23 @@ func (d *Digest) Write(b []byte) (n int, err error) { n = len(b) d.total += uint64(n) + memleft := d.mem[d.n&(len(d.mem)-1):] + if d.n+n < 32 { // This new data doesn't even fill the current block. - copy(d.mem[d.n:], b) + copy(memleft, b) d.n += n return } if d.n > 0 { // Finish off the partial block. - copy(d.mem[d.n:], b) + c := copy(memleft, b) d.v1 = round(d.v1, u64(d.mem[0:8])) d.v2 = round(d.v2, u64(d.mem[8:16])) d.v3 = round(d.v3, u64(d.mem[16:24])) d.v4 = round(d.v4, u64(d.mem[24:32])) - b = b[32-d.n:] + b = b[c:] d.n = 0 } @@ -135,21 +129,20 @@ func (d *Digest) Sum64() uint64 { h += d.total - i, end := 0, d.n - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(d.mem[i:i+8])) + b := d.mem[:d.n&(len(d.mem)-1)] + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(d.mem[i:i+4])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for i < end { - h ^= uint64(d.mem[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 - i++ } h ^= h >> 33 diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s index cea17856197..ddb63aa91b1 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s @@ -1,3 +1,4 @@ +//go:build !appengine && gc && !purego && !noasm // +build !appengine // +build gc // +build !purego @@ -5,212 +6,205 @@ #include "textflag.h" -// Register allocation: -// AX h -// SI pointer to advance through b -// DX n -// BX loop end -// R8 v1, k1 -// R9 v2 -// R10 v3 -// R11 v4 -// R12 tmp -// R13 prime1v -// R14 prime2v -// DI prime4v - -// round reads from and advances the buffer pointer in SI. -// It assumes that R13 has prime1v and R14 has prime2v. -#define round(r) \ - MOVQ (SI), R12 \ - ADDQ $8, SI \ - IMULQ R14, R12 \ - ADDQ R12, r \ - ROLQ $31, r \ - IMULQ R13, r - -// mergeRound applies a merge round on the two registers acc and val. -// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v. -#define mergeRound(acc, val) \ - IMULQ R14, val \ - ROLQ $31, val \ - IMULQ R13, val \ - XORQ val, acc \ - IMULQ R13, acc \ - ADDQ DI, acc +// Registers: +#define h AX +#define d AX +#define p SI // pointer to advance through b +#define n DX +#define end BX // loop end +#define v1 R8 +#define v2 R9 +#define v3 R10 +#define v4 R11 +#define x R12 +#define prime1 R13 +#define prime2 R14 +#define prime4 DI + +#define round(acc, x) \ + IMULQ prime2, x \ + ADDQ x, acc \ + ROLQ $31, acc \ + IMULQ prime1, acc + +// round0 performs the operation x = round(0, x). +#define round0(x) \ + IMULQ prime2, x \ + ROLQ $31, x \ + IMULQ prime1, x + +// mergeRound applies a merge round on the two registers acc and x. +// It assumes that prime1, prime2, and prime4 have been loaded. +#define mergeRound(acc, x) \ + round0(x) \ + XORQ x, acc \ + IMULQ prime1, acc \ + ADDQ prime4, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that there is at least one block +// to process. +#define blockLoop() \ +loop: \ + MOVQ +0(p), x \ + round(v1, x) \ + MOVQ +8(p), x \ + round(v2, x) \ + MOVQ +16(p), x \ + round(v3, x) \ + MOVQ +24(p), x \ + round(v4, x) \ + ADDQ $32, p \ + CMPQ p, end \ + JLE loop // func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT, $0-32 +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 // Load fixed primes. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 - MOVQ ·prime4v(SB), DI + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 + MOVQ ·primes+24(SB), prime4 // Load slice. - MOVQ b_base+0(FP), SI - MOVQ b_len+8(FP), DX - LEAQ (SI)(DX*1), BX + MOVQ b_base+0(FP), p + MOVQ b_len+8(FP), n + LEAQ (p)(n*1), end // The first loop limit will be len(b)-32. - SUBQ $32, BX + SUBQ $32, end // Check whether we have at least one block. - CMPQ DX, $32 + CMPQ n, $32 JLT noBlocks // Set up initial state (v1, v2, v3, v4). - MOVQ R13, R8 - ADDQ R14, R8 - MOVQ R14, R9 - XORQ R10, R10 - XORQ R11, R11 - SUBQ R13, R11 - - // Loop until SI > BX. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop - - MOVQ R8, AX - ROLQ $1, AX - MOVQ R9, R12 - ROLQ $7, R12 - ADDQ R12, AX - MOVQ R10, R12 - ROLQ $12, R12 - ADDQ R12, AX - MOVQ R11, R12 - ROLQ $18, R12 - ADDQ R12, AX - - mergeRound(AX, R8) - mergeRound(AX, R9) - mergeRound(AX, R10) - mergeRound(AX, R11) + MOVQ prime1, v1 + ADDQ prime2, v1 + MOVQ prime2, v2 + XORQ v3, v3 + XORQ v4, v4 + SUBQ prime1, v4 + + blockLoop() + + MOVQ v1, h + ROLQ $1, h + MOVQ v2, x + ROLQ $7, x + ADDQ x, h + MOVQ v3, x + ROLQ $12, x + ADDQ x, h + MOVQ v4, x + ROLQ $18, x + ADDQ x, h + + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) JMP afterBlocks noBlocks: - MOVQ ·prime5v(SB), AX + MOVQ ·primes+32(SB), h afterBlocks: - ADDQ DX, AX - - // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8. - ADDQ $24, BX - - CMPQ SI, BX - JG fourByte - -wordLoop: - // Calculate k1. - MOVQ (SI), R8 - ADDQ $8, SI - IMULQ R14, R8 - ROLQ $31, R8 - IMULQ R13, R8 - - XORQ R8, AX - ROLQ $27, AX - IMULQ R13, AX - ADDQ DI, AX - - CMPQ SI, BX - JLE wordLoop - -fourByte: - ADDQ $4, BX - CMPQ SI, BX - JG singles - - MOVL (SI), R8 - ADDQ $4, SI - IMULQ R13, R8 - XORQ R8, AX - - ROLQ $23, AX - IMULQ R14, AX - ADDQ ·prime3v(SB), AX - -singles: - ADDQ $4, BX - CMPQ SI, BX + ADDQ n, h + + ADDQ $24, end + CMPQ p, end + JG try4 + +loop8: + MOVQ (p), x + ADDQ $8, p + round0(x) + XORQ x, h + ROLQ $27, h + IMULQ prime1, h + ADDQ prime4, h + + CMPQ p, end + JLE loop8 + +try4: + ADDQ $4, end + CMPQ p, end + JG try1 + + MOVL (p), x + ADDQ $4, p + IMULQ prime1, x + XORQ x, h + + ROLQ $23, h + IMULQ prime2, h + ADDQ ·primes+16(SB), h + +try1: + ADDQ $4, end + CMPQ p, end JGE finalize -singlesLoop: - MOVBQZX (SI), R12 - ADDQ $1, SI - IMULQ ·prime5v(SB), R12 - XORQ R12, AX +loop1: + MOVBQZX (p), x + ADDQ $1, p + IMULQ ·primes+32(SB), x + XORQ x, h + ROLQ $11, h + IMULQ prime1, h - ROLQ $11, AX - IMULQ R13, AX - - CMPQ SI, BX - JL singlesLoop + CMPQ p, end + JL loop1 finalize: - MOVQ AX, R12 - SHRQ $33, R12 - XORQ R12, AX - IMULQ R14, AX - MOVQ AX, R12 - SHRQ $29, R12 - XORQ R12, AX - IMULQ ·prime3v(SB), AX - MOVQ AX, R12 - SHRQ $32, R12 - XORQ R12, AX - - MOVQ AX, ret+24(FP) + MOVQ h, x + SHRQ $33, x + XORQ x, h + IMULQ prime2, h + MOVQ h, x + SHRQ $29, x + XORQ x, h + IMULQ ·primes+16(SB), h + MOVQ h, x + SHRQ $32, x + XORQ x, h + + MOVQ h, ret+24(FP) RET -// writeBlocks uses the same registers as above except that it uses AX to store -// the d pointer. - // func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT, $0-40 +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 // Load fixed primes needed for round. - MOVQ ·prime1v(SB), R13 - MOVQ ·prime2v(SB), R14 + MOVQ ·primes+0(SB), prime1 + MOVQ ·primes+8(SB), prime2 // Load slice. - MOVQ b_base+8(FP), SI - MOVQ b_len+16(FP), DX - LEAQ (SI)(DX*1), BX - SUBQ $32, BX + MOVQ b_base+8(FP), p + MOVQ b_len+16(FP), n + LEAQ (p)(n*1), end + SUBQ $32, end // Load vN from d. - MOVQ d+0(FP), AX - MOVQ 0(AX), R8 // v1 - MOVQ 8(AX), R9 // v2 - MOVQ 16(AX), R10 // v3 - MOVQ 24(AX), R11 // v4 + MOVQ s+0(FP), d + MOVQ 0(d), v1 + MOVQ 8(d), v2 + MOVQ 16(d), v3 + MOVQ 24(d), v4 // We don't need to check the loop condition here; this function is // always called with at least one block of data to process. -blockLoop: - round(R8) - round(R9) - round(R10) - round(R11) - - CMPQ SI, BX - JLE blockLoop + blockLoop() // Copy vN back to d. - MOVQ R8, 0(AX) - MOVQ R9, 8(AX) - MOVQ R10, 16(AX) - MOVQ R11, 24(AX) - - // The number of bytes written is SI minus the old base pointer. - SUBQ b_base+8(FP), SI - MOVQ SI, ret+32(FP) + MOVQ v1, 0(d) + MOVQ v2, 8(d) + MOVQ v3, 16(d) + MOVQ v4, 24(d) + + // The number of bytes written is p minus the old base pointer. + SUBQ b_base+8(FP), p + MOVQ p, ret+32(FP) RET diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s index 4d64a17d69c..17901e08040 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s @@ -1,13 +1,17 @@ -// +build gc,!purego,!noasm +//go:build !appengine && gc && !purego && !noasm +// +build !appengine +// +build gc +// +build !purego +// +build !noasm #include "textflag.h" -// Register allocation. +// Registers: #define digest R1 -#define h R2 // Return value. -#define p R3 // Input pointer. -#define len R4 -#define nblocks R5 // len / 32. +#define h R2 // return value +#define p R3 // input pointer +#define n R4 // input length +#define nblocks R5 // n / 32 #define prime1 R7 #define prime2 R8 #define prime3 R9 @@ -25,60 +29,52 @@ #define round(acc, x) \ MADD prime2, acc, x, acc \ ROR $64-31, acc \ - MUL prime1, acc \ + MUL prime1, acc -// x = round(0, x). +// round0 performs the operation x = round(0, x). #define round0(x) \ MUL prime2, x \ ROR $64-31, x \ - MUL prime1, x \ - -#define mergeRound(x) \ - round0(x) \ - EOR x, h \ - MADD h, prime4, prime1, h \ - -// Update v[1-4] with 32-byte blocks. Assumes len >= 32. -#define blocksLoop() \ - LSR $5, len, nblocks \ - PCALIGN $16 \ - loop: \ - LDP.P 32(p), (x1, x2) \ - round(v1, x1) \ - LDP -16(p), (x3, x4) \ - round(v2, x2) \ - SUB $1, nblocks \ - round(v3, x3) \ - round(v4, x4) \ - CBNZ nblocks, loop \ - -// The primes are repeated here to ensure that they're stored -// in a contiguous array, so we can load them with LDP. -DATA primes<> +0(SB)/8, $11400714785074694791 -DATA primes<> +8(SB)/8, $14029467366897019727 -DATA primes<>+16(SB)/8, $1609587929392839161 -DATA primes<>+24(SB)/8, $9650029242287828579 -DATA primes<>+32(SB)/8, $2870177450012600261 -GLOBL primes<>(SB), NOPTR+RODATA, $40 + MUL prime1, x + +#define mergeRound(acc, x) \ + round0(x) \ + EOR x, acc \ + MADD acc, prime4, prime1, acc + +// blockLoop processes as many 32-byte blocks as possible, +// updating v1, v2, v3, and v4. It assumes that n >= 32. +#define blockLoop() \ + LSR $5, n, nblocks \ + PCALIGN $16 \ + loop: \ + LDP.P 16(p), (x1, x2) \ + LDP.P 16(p), (x3, x4) \ + round(v1, x1) \ + round(v2, x2) \ + round(v3, x3) \ + round(v4, x4) \ + SUB $1, nblocks \ + CBNZ nblocks, loop // func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOFRAME+NOSPLIT, $0-32 - LDP b_base+0(FP), (p, len) +TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 + LDP b_base+0(FP), (p, n) - LDP primes<> +0(SB), (prime1, prime2) - LDP primes<>+16(SB), (prime3, prime4) - MOVD primes<>+32(SB), prime5 + LDP ·primes+0(SB), (prime1, prime2) + LDP ·primes+16(SB), (prime3, prime4) + MOVD ·primes+32(SB), prime5 - CMP $32, len - CSEL LO, prime5, ZR, h // if len < 32 { h = prime5 } else { h = 0 } - BLO afterLoop + CMP $32, n + CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 } + BLT afterLoop ADD prime1, prime2, v1 MOVD prime2, v2 MOVD $0, v3 NEG prime1, v4 - blocksLoop() + blockLoop() ROR $64-1, v1, x1 ROR $64-7, v2, x2 @@ -88,71 +84,75 @@ TEXT ·Sum64(SB), NOFRAME+NOSPLIT, $0-32 ADD x3, x4 ADD x2, x4, h - mergeRound(v1) - mergeRound(v2) - mergeRound(v3) - mergeRound(v4) + mergeRound(h, v1) + mergeRound(h, v2) + mergeRound(h, v3) + mergeRound(h, v4) afterLoop: - ADD len, h + ADD n, h - TBZ $4, len, try8 + TBZ $4, n, try8 LDP.P 16(p), (x1, x2) round0(x1) + + // NOTE: here and below, sequencing the EOR after the ROR (using a + // rotated register) is worth a small but measurable speedup for small + // inputs. ROR $64-27, h EOR x1 @> 64-27, h, h MADD h, prime4, prime1, h round0(x2) ROR $64-27, h - EOR x2 @> 64-27, h + EOR x2 @> 64-27, h, h MADD h, prime4, prime1, h try8: - TBZ $3, len, try4 + TBZ $3, n, try4 MOVD.P 8(p), x1 round0(x1) ROR $64-27, h - EOR x1 @> 64-27, h + EOR x1 @> 64-27, h, h MADD h, prime4, prime1, h try4: - TBZ $2, len, try2 + TBZ $2, n, try2 MOVWU.P 4(p), x2 MUL prime1, x2 ROR $64-23, h - EOR x2 @> 64-23, h + EOR x2 @> 64-23, h, h MADD h, prime3, prime2, h try2: - TBZ $1, len, try1 + TBZ $1, n, try1 MOVHU.P 2(p), x3 AND $255, x3, x1 LSR $8, x3, x2 MUL prime5, x1 ROR $64-11, h - EOR x1 @> 64-11, h + EOR x1 @> 64-11, h, h MUL prime1, h MUL prime5, x2 ROR $64-11, h - EOR x2 @> 64-11, h + EOR x2 @> 64-11, h, h MUL prime1, h try1: - TBZ $0, len, end + TBZ $0, n, finalize MOVBU (p), x4 MUL prime5, x4 ROR $64-11, h - EOR x4 @> 64-11, h + EOR x4 @> 64-11, h, h MUL prime1, h -end: +finalize: EOR h >> 33, h MUL prime2, h EOR h >> 29, h @@ -163,24 +163,22 @@ end: RET // func writeBlocks(d *Digest, b []byte) int -// -// Assumes len(b) >= 32. -TEXT ·writeBlocks(SB), NOFRAME+NOSPLIT, $0-40 - LDP primes<>(SB), (prime1, prime2) +TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 + LDP ·primes+0(SB), (prime1, prime2) // Load state. Assume v[1-4] are stored contiguously. MOVD d+0(FP), digest LDP 0(digest), (v1, v2) LDP 16(digest), (v3, v4) - LDP b_base+8(FP), (p, len) + LDP b_base+8(FP), (p, n) - blocksLoop() + blockLoop() // Store updated state. STP (v1, v2), 0(digest) STP (v3, v4), 16(digest) - BIC $31, len - MOVD len, ret+32(FP) + BIC $31, n + MOVD n, ret+32(FP) RET diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go index 1a1fac9c261..d4221edf4fd 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go @@ -13,4 +13,4 @@ package xxhash func Sum64(b []byte) uint64 //go:noescape -func writeBlocks(d *Digest, b []byte) int +func writeBlocks(s *Digest, b []byte) int diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go index 209cb4a999c..0be16cefc7f 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go @@ -15,10 +15,10 @@ func Sum64(b []byte) uint64 { var h uint64 if n >= 32 { - v1 := prime1v + prime2 + v1 := primes[0] + prime2 v2 := prime2 v3 := uint64(0) - v4 := -prime1v + v4 := -primes[0] for len(b) >= 32 { v1 = round(v1, u64(b[0:8:len(b)])) v2 = round(v2, u64(b[8:16:len(b)])) @@ -37,19 +37,18 @@ func Sum64(b []byte) uint64 { h += uint64(n) - i, end := 0, len(b) - for ; i+8 <= end; i += 8 { - k1 := round(0, u64(b[i:i+8:len(b)])) + for ; len(b) >= 8; b = b[8:] { + k1 := round(0, u64(b[:8])) h ^= k1 h = rol27(h)*prime1 + prime4 } - if i+4 <= end { - h ^= uint64(u32(b[i:i+4:len(b)])) * prime1 + if len(b) >= 4 { + h ^= uint64(u32(b[:4])) * prime1 h = rol23(h)*prime2 + prime3 - i += 4 + b = b[4:] } - for ; i < end; i++ { - h ^= uint64(b[i]) * prime5 + for ; len(b) > 0; b = b[1:] { + h ^= uint64(b[0]) * prime5 h = rol11(h) * prime1 } diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go index 819f1461b70..f833d1541f9 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go @@ -73,6 +73,7 @@ type sequenceDecs struct { seqSize int windowSize int maxBits uint8 + maxSyncLen uint64 } // initialize all 3 decoders from the stream input. @@ -98,153 +99,28 @@ func (s *sequenceDecs) initialize(br *bitReader, hist *history, out []byte) erro return nil } -// decode sequences from the stream with the provided history. -func (s *sequenceDecs) decode(seqs []seqVals) error { - br := s.br - - // Grab full sizes tables, to avoid bounds checks. - llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] - llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - s.seqSize = 0 - litRemain := len(s.literals) - maxBlockSize := maxCompressedBlockSize - if s.windowSize < maxBlockSize { - maxBlockSize = s.windowSize +func (s *sequenceDecs) freeDecoders() { + if f := s.litLengths.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.litLengths.fse = nil } - for i := range seqs { - var ll, mo, ml int - if br.off > 4+((maxOffsetBits+16+16)>>3) { - // inlined function: - // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) - - // Final will not read from stream. - var llB, mlB, moB uint8 - ll, llB = llState.final() - ml, mlB = mlState.final() - mo, moB = ofState.final() - - // extra bits are stored in reverse order. - br.fillFast() - mo += br.getBits(moB) - if s.maxBits > 32 { - br.fillFast() - } - ml += br.getBits(mlB) - ll += br.getBits(llB) - - if moB > 1 { - s.prevOffset[2] = s.prevOffset[1] - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = mo - } else { - // mo = s.adjustOffset(mo, ll, moB) - // Inlined for rather big speedup - if ll == 0 { - // There is an exception though, when current sequence's literals_length = 0. - // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, - // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. - mo++ - } - - if mo == 0 { - mo = s.prevOffset[0] - } else { - var temp int - if mo == 3 { - temp = s.prevOffset[0] - 1 - } else { - temp = s.prevOffset[mo] - } - - if temp == 0 { - // 0 is not valid; input is corrupted; force offset to 1 - println("WARNING: temp was 0") - temp = 1 - } - - if mo != 1 { - s.prevOffset[2] = s.prevOffset[1] - } - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = temp - mo = temp - } - } - br.fillFast() - } else { - if br.overread() { - if debugDecoder { - printf("reading sequence %d, exceeded available data\n", i) - } - return io.ErrUnexpectedEOF - } - ll, mo, ml = s.next(br, llState, mlState, ofState) - br.fill() - } - - if debugSequences { - println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml) - } - // Evaluate. - // We might be doing this async, so do it early. - if mo == 0 && ml > 0 { - return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) - } - if ml > maxMatchLen { - return fmt.Errorf("match len (%d) bigger than max allowed length", ml) - } - s.seqSize += ll + ml - if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) - } - litRemain -= ll - if litRemain < 0 { - return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll) - } - seqs[i] = seqVals{ - ll: ll, - ml: ml, - mo: mo, - } - if i == len(seqs)-1 { - // This is the last sequence, so we shouldn't update state. - break - } - - // Manually inlined, ~ 5-20% faster - // Update all 3 states at once. Approx 20% faster. - nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits() - if nBits == 0 { - llState = llTable[llState.newState()&maxTableMask] - mlState = mlTable[mlState.newState()&maxTableMask] - ofState = ofTable[ofState.newState()&maxTableMask] - } else { - bits := br.get32BitsFast(nBits) - lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) - llState = llTable[(llState.newState()+lowBits)&maxTableMask] - - lowBits = uint16(bits >> (ofState.nbBits() & 31)) - lowBits &= bitMask[mlState.nbBits()&15] - mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask] - - lowBits = uint16(bits) & bitMask[ofState.nbBits()&15] - ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask] - } - } - s.seqSize += litRemain - if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + if f := s.offsets.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.offsets.fse = nil } - err := br.close() - if err != nil { - printf("Closing sequences: %v, %+v\n", err, *br) + if f := s.matchLengths.fse; f != nil && !f.preDefined { + fseDecoderPool.Put(f) + s.matchLengths.fse = nil } - return err } // execute will execute the decoded sequence with the provided history. // The sequence must be evaluated before being sent. func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { + if len(s.dict) == 0 { + return s.executeSimple(seqs, hist) + } + // Ensure we have enough output size... if len(s.out)+s.seqSize > cap(s.out) { addBytes := s.seqSize + len(s.out) @@ -327,6 +203,7 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { } } } + // Add final literals copy(out[t:], s.literals) if debugDecoder { @@ -341,14 +218,18 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { } // decode sequences from the stream with the provided history. -func (s *sequenceDecs) decodeSync(history *history) error { +func (s *sequenceDecs) decodeSync(hist []byte) error { + supported, err := s.decodeSyncSimple(hist) + if supported { + return err + } + br := s.br seqs := s.nSeqs startSize := len(s.out) // Grab full sizes tables, to avoid bounds checks. llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - hist := history.b[history.ignoreBuffer:] out := s.out maxBlockSize := maxCompressedBlockSize if s.windowSize < maxBlockSize { @@ -433,7 +314,10 @@ func (s *sequenceDecs) decodeSync(history *history) error { } size := ll + ml + len(out) if size-startSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize) + if size-startSize == 424242 { + panic("here") + } + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } if size > cap(out) { // Not enough size, which can happen under high volume block streaming conditions @@ -463,13 +347,13 @@ func (s *sequenceDecs) decodeSync(history *history) error { if mo > len(out)+len(hist) || mo > s.windowSize { if len(s.dict) == 0 { - return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)) + return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize) } // we may be in dictionary. dictO := len(s.dict) - (mo - (len(out) + len(hist))) if dictO < 0 || dictO >= len(s.dict) { - return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)) + return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize) } end := dictO + ml if end > len(s.dict) { @@ -530,6 +414,7 @@ func (s *sequenceDecs) decodeSync(history *history) error { ofState = ofTable[ofState.newState()&maxTableMask] } else { bits := br.get32BitsFast(nBits) + lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) llState = llTable[(llState.newState()+lowBits)&maxTableMask] @@ -543,8 +428,8 @@ func (s *sequenceDecs) decodeSync(history *history) error { } // Check if space for literals - if len(s.literals)+len(s.out)-startSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", len(s.out), maxBlockSize) + if size := len(s.literals) + len(s.out) - startSize; size > maxBlockSize { + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) } // Add final literals @@ -552,16 +437,6 @@ func (s *sequenceDecs) decodeSync(history *history) error { return br.close() } -// update states, at least 27 bits must be available. -func (s *sequenceDecs) update(br *bitReader) { - // Max 8 bits - s.litLengths.state.next(br) - // Max 9 bits - s.matchLengths.state.next(br) - // Max 8 bits - s.offsets.state.next(br) -} - var bitMask [16]uint16 func init() { @@ -570,87 +445,6 @@ func init() { } } -// update states, at least 27 bits must be available. -func (s *sequenceDecs) updateAlt(br *bitReader) { - // Update all 3 states at once. Approx 20% faster. - a, b, c := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - - nBits := a.nbBits() + b.nbBits() + c.nbBits() - if nBits == 0 { - s.litLengths.state.state = s.litLengths.state.dt[a.newState()] - s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()] - s.offsets.state.state = s.offsets.state.dt[c.newState()] - return - } - bits := br.get32BitsFast(nBits) - lowBits := uint16(bits >> ((c.nbBits() + b.nbBits()) & 31)) - s.litLengths.state.state = s.litLengths.state.dt[a.newState()+lowBits] - - lowBits = uint16(bits >> (c.nbBits() & 31)) - lowBits &= bitMask[b.nbBits()&15] - s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()+lowBits] - - lowBits = uint16(bits) & bitMask[c.nbBits()&15] - s.offsets.state.state = s.offsets.state.dt[c.newState()+lowBits] -} - -// nextFast will return new states when there are at least 4 unused bytes left on the stream when done. -func (s *sequenceDecs) nextFast(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) { - // Final will not read from stream. - ll, llB := llState.final() - ml, mlB := mlState.final() - mo, moB := ofState.final() - - // extra bits are stored in reverse order. - br.fillFast() - mo += br.getBits(moB) - if s.maxBits > 32 { - br.fillFast() - } - ml += br.getBits(mlB) - ll += br.getBits(llB) - - if moB > 1 { - s.prevOffset[2] = s.prevOffset[1] - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = mo - return - } - // mo = s.adjustOffset(mo, ll, moB) - // Inlined for rather big speedup - if ll == 0 { - // There is an exception though, when current sequence's literals_length = 0. - // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, - // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. - mo++ - } - - if mo == 0 { - mo = s.prevOffset[0] - return - } - var temp int - if mo == 3 { - temp = s.prevOffset[0] - 1 - } else { - temp = s.prevOffset[mo] - } - - if temp == 0 { - // 0 is not valid; input is corrupted; force offset to 1 - println("temp was 0") - temp = 1 - } - - if mo != 1 { - s.prevOffset[2] = s.prevOffset[1] - } - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = temp - mo = temp - return -} - func (s *sequenceDecs) next(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) { // Final will not read from stream. ll, llB := llState.final() diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go new file mode 100644 index 00000000000..191384adfd0 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go @@ -0,0 +1,379 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package zstd + +import ( + "fmt" + + "github.com/klauspost/compress/internal/cpuinfo" +) + +type decodeSyncAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + litRemain int + out []byte + outPosition int + literals []byte + litPosition int + history []byte + windowSize int + ll int // set on error (not for all errors, please refer to _generate/gen.go) + ml int // set on error (not for all errors, please refer to _generate/gen.go) + mo int // set on error (not for all errors, please refer to _generate/gen.go) +} + +// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer. +// +//go:noescape +func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer. +// +//go:noescape +func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// decode sequences from the stream with the provided history but without a dictionary. +func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { + if len(s.dict) > 0 { + return false, nil + } + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize { + return false, nil + } + + // FIXME: Using unsafe memory copies leads to rare, random crashes + // with fuzz testing. It is therefore disabled for now. + const useSafe = true + /* + useSafe := false + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + useSafe = true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + useSafe = true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + useSafe = true + } + */ + + br := s.br + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + + ctx := decodeSyncAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + iteration: s.nSeqs - 1, + litRemain: len(s.literals), + out: s.out, + outPosition: len(s.out), + literals: s.literals, + windowSize: s.windowSize, + history: hist, + } + + s.seqSize = 0 + startSize := len(s.out) + + var errCode int + if cpuinfo.HasBMI2() { + if useSafe { + errCode = sequenceDecs_decodeSync_safe_bmi2(s, br, &ctx) + } else { + errCode = sequenceDecs_decodeSync_bmi2(s, br, &ctx) + } + } else { + if useSafe { + errCode = sequenceDecs_decodeSync_safe_amd64(s, br, &ctx) + } else { + errCode = sequenceDecs_decodeSync_amd64(s, br, &ctx) + } + } + switch errCode { + case noError: + break + + case errorMatchLenOfsMismatch: + return true, fmt.Errorf("zero matchoff and matchlen (%d) > 0", ctx.ml) + + case errorMatchLenTooBig: + return true, fmt.Errorf("match len (%d) bigger than max allowed length", ctx.ml) + + case errorMatchOffTooBig: + return true, fmt.Errorf("match offset (%d) bigger than current history (%d)", + ctx.mo, ctx.outPosition+len(hist)-startSize) + + case errorNotEnoughLiterals: + return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", + ctx.ll, ctx.litRemain+ctx.ll) + + case errorNotEnoughSpace: + size := ctx.outPosition + ctx.ll + ctx.ml + if debugDecoder { + println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize) + } + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + + default: + return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + return true, err + } + + s.literals = s.literals[ctx.litPosition:] + t := ctx.outPosition + s.out = s.out[:t] + + // Add final literals + s.out = append(s.out, s.literals...) + if debugDecoder { + t += len(s.literals) + if t != len(s.out) { + panic(fmt.Errorf("length mismatch, want %d, got %d", len(s.out), t)) + } + } + + return true, nil +} + +// -------------------------------------------------------------------------------- + +type decodeAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + seqs []seqVals + litRemain int +} + +const noError = 0 + +// error reported when mo == 0 && ml > 0 +const errorMatchLenOfsMismatch = 1 + +// error reported when ml > maxMatchLen +const errorMatchLenTooBig = 2 + +// error reported when mo > available history or mo > s.windowSize +const errorMatchOffTooBig = 3 + +// error reported when the sum of literal lengths exeeceds the literal buffer size +const errorNotEnoughLiterals = 4 + +// error reported when capacity of `out` is too small +const errorNotEnoughSpace = 5 + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// decode sequences from the stream without the provided history. +func (s *sequenceDecs) decode(seqs []seqVals) error { + br := s.br + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + + ctx := decodeAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + seqs: seqs, + iteration: len(seqs) - 1, + litRemain: len(s.literals), + } + + s.seqSize = 0 + lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56 + var errCode int + if cpuinfo.HasBMI2() { + if lte56bits { + errCode = sequenceDecs_decode_56_bmi2(s, br, &ctx) + } else { + errCode = sequenceDecs_decode_bmi2(s, br, &ctx) + } + } else { + if lte56bits { + errCode = sequenceDecs_decode_56_amd64(s, br, &ctx) + } else { + errCode = sequenceDecs_decode_amd64(s, br, &ctx) + } + } + if errCode != 0 { + i := len(seqs) - ctx.iteration - 1 + switch errCode { + case errorMatchLenOfsMismatch: + ml := ctx.seqs[i].ml + return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) + + case errorMatchLenTooBig: + ml := ctx.seqs[i].ml + return fmt.Errorf("match len (%d) bigger than max allowed length", ml) + + case errorNotEnoughLiterals: + ll := ctx.seqs[i].ll + return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll) + } + + return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode) + } + + if ctx.litRemain < 0 { + return fmt.Errorf("literal count is too big: total available %d, total requested %d", + len(s.literals), len(s.literals)-ctx.litRemain) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + } + return err +} + +// -------------------------------------------------------------------------------- + +type executeAsmContext struct { + seqs []seqVals + seqIndex int + out []byte + history []byte + literals []byte + outPosition int + litPosition int + windowSize int +} + +// sequenceDecs_executeSimple_amd64 implements the main loop of sequenceDecs.executeSimple in x86 asm. +// +// Returns false if a match offset is too big. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool + +// Same as above, but with safe memcopies +// +//go:noescape +func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool + +// executeSimple handles cases when dictionary is not used. +func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { + // Ensure we have enough output size... + if len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) { + addBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] + } + + if debugDecoder { + printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) + } + + var t = len(s.out) + out := s.out[:t+s.seqSize] + + ctx := executeAsmContext{ + seqs: seqs, + seqIndex: 0, + out: out, + history: hist, + outPosition: t, + litPosition: 0, + literals: s.literals, + windowSize: s.windowSize, + } + var ok bool + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + ok = sequenceDecs_executeSimple_safe_amd64(&ctx) + } else { + ok = sequenceDecs_executeSimple_amd64(&ctx) + } + if !ok { + return fmt.Errorf("match offset (%d) bigger than current history (%d)", + seqs[ctx.seqIndex].mo, ctx.outPosition+len(hist)) + } + s.literals = s.literals[ctx.litPosition:] + t = ctx.outPosition + + // Add final literals + copy(out[t:], s.literals) + if debugDecoder { + t += len(s.literals) + if t != len(out) { + panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) + } + } + s.out = out + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s new file mode 100644 index 00000000000..b94993a0727 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -0,0 +1,4079 @@ +// Code generated by command: go run gen.go -out ../seqdec_amd64.s -pkg=zstd. DO NOT EDIT. + +//go:build !appengine && !noasm && gc && !noasm + +// func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_amd64(SB), $8-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + MOVQ 104(AX), R10 + MOVQ s+0(FP), AX + MOVQ 144(AX), R11 + MOVQ 152(AX), R12 + MOVQ 160(AX), R13 + +sequenceDecs_decode_amd64_main_loop: + MOVQ (SP), R14 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decode_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_amd64_fill_end + +sequenceDecs_decode_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_amd64_fill_byte_by_byte + +sequenceDecs_decode_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_of_update_zero: + MOVQ AX, 16(R10) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_ml_update_zero: + MOVQ AX, 8(R10) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decode_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_amd64_fill_2_end + +sequenceDecs_decode_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte + +sequenceDecs_decode_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_ll_update_zero: + MOVQ AX, (R10) + + // Fill bitreader for state updates + MOVQ R14, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R14 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R14 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R14 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decode_amd64_skip_update: + // Adjust offset + MOVQ 16(R10), CX + CMPQ AX, $0x01 + JBE sequenceDecs_decode_amd64_adjust_offsetB_1_or_0 + MOVQ R12, R13 + MOVQ R11, R12 + MOVQ CX, R11 + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offsetB_1_or_0: + CMPQ (R10), $0x00000000 + JNE sequenceDecs_decode_amd64_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_amd64_adjust_offset_nonzero + +sequenceDecs_decode_amd64_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_amd64_adjust_offset_nonzero + MOVQ R11, CX + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_amd64_adjust_zero + JEQ sequenceDecs_decode_amd64_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_amd64_adjust_three + JMP sequenceDecs_decode_amd64_adjust_two + +sequenceDecs_decode_amd64_adjust_zero: + MOVQ R11, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_one: + MOVQ R12, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_two: + MOVQ R13, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_three: + LEAQ -1(R11), AX + +sequenceDecs_decode_amd64_adjust_test_temp_valid: + TESTQ AX, AX + JNZ sequenceDecs_decode_amd64_adjust_temp_valid + MOVQ $0x00000001, AX + +sequenceDecs_decode_amd64_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R12, R13 + MOVQ R11, R12 + MOVQ AX, R11 + MOVQ AX, CX + +sequenceDecs_decode_amd64_after_adjust: + MOVQ CX, 16(R10) + + // Check values + MOVQ 8(R10), AX + MOVQ (R10), R14 + LEAQ (AX)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decode_amd64_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decode_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_amd64_match_len_ofs_ok: + ADDQ $0x18, R10 + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decode_amd64_main_loop + MOVQ s+0(FP), AX + MOVQ R11, 144(AX) + MOVQ R12, 152(AX) + MOVQ R13, 160(AX) + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_amd64_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_amd64_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + +// func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_56_amd64(SB), $8-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + MOVQ 104(AX), R10 + MOVQ s+0(FP), AX + MOVQ 144(AX), R11 + MOVQ 152(AX), R12 + MOVQ 160(AX), R13 + +sequenceDecs_decode_56_amd64_main_loop: + MOVQ (SP), R14 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decode_56_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_56_amd64_fill_end + +sequenceDecs_decode_56_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_56_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_56_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte + +sequenceDecs_decode_56_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_of_update_zero: + MOVQ AX, 16(R10) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_ml_update_zero: + MOVQ AX, 8(R10) + + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_ll_update_zero: + MOVQ AX, (R10) + + // Fill bitreader for state updates + MOVQ R14, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_56_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R14 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R14 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R14 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decode_56_amd64_skip_update: + // Adjust offset + MOVQ 16(R10), CX + CMPQ AX, $0x01 + JBE sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0 + MOVQ R12, R13 + MOVQ R11, R12 + MOVQ CX, R11 + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0: + CMPQ (R10), $0x00000000 + JNE sequenceDecs_decode_56_amd64_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_56_amd64_adjust_offset_nonzero + +sequenceDecs_decode_56_amd64_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_56_amd64_adjust_offset_nonzero + MOVQ R11, CX + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_56_amd64_adjust_zero + JEQ sequenceDecs_decode_56_amd64_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_56_amd64_adjust_three + JMP sequenceDecs_decode_56_amd64_adjust_two + +sequenceDecs_decode_56_amd64_adjust_zero: + MOVQ R11, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_one: + MOVQ R12, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_two: + MOVQ R13, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_three: + LEAQ -1(R11), AX + +sequenceDecs_decode_56_amd64_adjust_test_temp_valid: + TESTQ AX, AX + JNZ sequenceDecs_decode_56_amd64_adjust_temp_valid + MOVQ $0x00000001, AX + +sequenceDecs_decode_56_amd64_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R12, R13 + MOVQ R11, R12 + MOVQ AX, R11 + MOVQ AX, CX + +sequenceDecs_decode_56_amd64_after_adjust: + MOVQ CX, 16(R10) + + // Check values + MOVQ 8(R10), AX + MOVQ (R10), R14 + LEAQ (AX)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decode_56_amd64_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_56_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_56_amd64_match_len_ofs_ok: + ADDQ $0x18, R10 + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decode_56_amd64_main_loop + MOVQ s+0(FP), AX + MOVQ R11, 144(AX) + MOVQ R12, 152(AX) + MOVQ R13, 160(AX) + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_56_amd64_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + +// func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: BMI, BMI2, CMOV +TEXT ·sequenceDecs_decode_bmi2(SB), $8-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + MOVQ 104(CX), R9 + MOVQ s+0(FP), CX + MOVQ 144(CX), R10 + MOVQ 152(CX), R11 + MOVQ 160(CX), R12 + +sequenceDecs_decode_bmi2_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decode_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_bmi2_fill_end + +sequenceDecs_decode_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_bmi2_fill_byte_by_byte + +sequenceDecs_decode_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 16(R9) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 8(R9) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decode_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_bmi2_fill_2_end + +sequenceDecs_decode_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_bmi2_fill_2_byte_by_byte + +sequenceDecs_decode_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, (R9) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_bmi2_skip_update + LEAQ (SI)(DI*1), R14 + ADDQ R8, R14 + MOVBQZX R14, R14 + LEAQ (DX)(R14*1), CX + MOVQ AX, R15 + MOVQ CX, DX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + + // Update Offset State + BZHIQ R8, R15, CX + SHRXQ R8, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R15, CX + SHRXQ DI, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R15, CX + MOVQ $0x00001010, R14 + BEXTRQ R14, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decode_bmi2_skip_update: + // Adjust offset + MOVQ 16(R9), CX + CMPQ R13, $0x01 + JBE sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0 + MOVQ R11, R12 + MOVQ R10, R11 + MOVQ CX, R10 + JMP sequenceDecs_decode_bmi2_after_adjust + +sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0: + CMPQ (R9), $0x00000000 + JNE sequenceDecs_decode_bmi2_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_bmi2_adjust_offset_nonzero + +sequenceDecs_decode_bmi2_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_bmi2_adjust_offset_nonzero + MOVQ R10, CX + JMP sequenceDecs_decode_bmi2_after_adjust + +sequenceDecs_decode_bmi2_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_bmi2_adjust_zero + JEQ sequenceDecs_decode_bmi2_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_bmi2_adjust_three + JMP sequenceDecs_decode_bmi2_adjust_two + +sequenceDecs_decode_bmi2_adjust_zero: + MOVQ R10, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_one: + MOVQ R11, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_two: + MOVQ R12, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_three: + LEAQ -1(R10), R13 + +sequenceDecs_decode_bmi2_adjust_test_temp_valid: + TESTQ R13, R13 + JNZ sequenceDecs_decode_bmi2_adjust_temp_valid + MOVQ $0x00000001, R13 + +sequenceDecs_decode_bmi2_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R11, R12 + MOVQ R10, R11 + MOVQ R13, R10 + MOVQ R13, CX + +sequenceDecs_decode_bmi2_after_adjust: + MOVQ CX, 16(R9) + + // Check values + MOVQ 8(R9), R13 + MOVQ (R9), R14 + LEAQ (R13)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ R13, $0x00020002 + JA sequenceDecs_decode_bmi2_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_bmi2_match_len_ofs_ok + TESTQ R13, R13 + JNZ sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decode_bmi2_match_len_ofs_ok: + ADDQ $0x18, R9 + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decode_bmi2_main_loop + MOVQ s+0(FP), CX + MOVQ R10, 144(CX) + MOVQ R11, 152(CX) + MOVQ R12, 160(CX) + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_bmi2_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + +// func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: BMI, BMI2, CMOV +TEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + MOVQ 104(CX), R9 + MOVQ s+0(FP), CX + MOVQ 144(CX), R10 + MOVQ 152(CX), R11 + MOVQ 160(CX), R12 + +sequenceDecs_decode_56_bmi2_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decode_56_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_56_bmi2_fill_end + +sequenceDecs_decode_56_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_56_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_56_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_56_bmi2_fill_byte_by_byte + +sequenceDecs_decode_56_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 16(R9) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 8(R9) + + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, (R9) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_56_bmi2_skip_update + LEAQ (SI)(DI*1), R14 + ADDQ R8, R14 + MOVBQZX R14, R14 + LEAQ (DX)(R14*1), CX + MOVQ AX, R15 + MOVQ CX, DX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + + // Update Offset State + BZHIQ R8, R15, CX + SHRXQ R8, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R15, CX + SHRXQ DI, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R15, CX + MOVQ $0x00001010, R14 + BEXTRQ R14, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decode_56_bmi2_skip_update: + // Adjust offset + MOVQ 16(R9), CX + CMPQ R13, $0x01 + JBE sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0 + MOVQ R11, R12 + MOVQ R10, R11 + MOVQ CX, R10 + JMP sequenceDecs_decode_56_bmi2_after_adjust + +sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0: + CMPQ (R9), $0x00000000 + JNE sequenceDecs_decode_56_bmi2_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_56_bmi2_adjust_offset_nonzero + +sequenceDecs_decode_56_bmi2_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_56_bmi2_adjust_offset_nonzero + MOVQ R10, CX + JMP sequenceDecs_decode_56_bmi2_after_adjust + +sequenceDecs_decode_56_bmi2_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_56_bmi2_adjust_zero + JEQ sequenceDecs_decode_56_bmi2_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_56_bmi2_adjust_three + JMP sequenceDecs_decode_56_bmi2_adjust_two + +sequenceDecs_decode_56_bmi2_adjust_zero: + MOVQ R10, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_one: + MOVQ R11, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_two: + MOVQ R12, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_three: + LEAQ -1(R10), R13 + +sequenceDecs_decode_56_bmi2_adjust_test_temp_valid: + TESTQ R13, R13 + JNZ sequenceDecs_decode_56_bmi2_adjust_temp_valid + MOVQ $0x00000001, R13 + +sequenceDecs_decode_56_bmi2_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R11, R12 + MOVQ R10, R11 + MOVQ R13, R10 + MOVQ R13, CX + +sequenceDecs_decode_56_bmi2_after_adjust: + MOVQ CX, 16(R9) + + // Check values + MOVQ 8(R9), R13 + MOVQ (R9), R14 + LEAQ (R13)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ R13, $0x00020002 + JA sequenceDecs_decode_56_bmi2_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_56_bmi2_match_len_ofs_ok + TESTQ R13, R13 + JNZ sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decode_56_bmi2_match_len_ofs_ok: + ADDQ $0x18, R9 + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decode_56_bmi2_main_loop + MOVQ s+0(FP), CX + MOVQ R10, 144(CX) + MOVQ R11, 152(CX) + MOVQ R12, 160(CX) + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_56_bmi2_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + +// func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9 + MOVQ ctx+0(FP), R10 + MOVQ 8(R10), CX + TESTQ CX, CX + JZ empty_seqs + MOVQ (R10), AX + MOVQ 24(R10), DX + MOVQ 32(R10), BX + MOVQ 80(R10), SI + MOVQ 104(R10), DI + MOVQ 120(R10), R8 + MOVQ 56(R10), R9 + MOVQ 64(R10), R10 + ADDQ R10, R9 + + // seqsBase += 24 * seqIndex + LEAQ (DX)(DX*2), R11 + SHLQ $0x03, R11 + ADDQ R11, AX + + // outBase += outPosition + ADDQ DI, BX + +main_loop: + MOVQ (AX), R11 + MOVQ 16(AX), R12 + MOVQ 8(AX), R13 + + // Copy literals + TESTQ R11, R11 + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (SI)(R14*1), X0 + MOVUPS X0, (BX)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, R11 + JB copy_1 + ADDQ R11, SI + ADDQ R11, BX + ADDQ R11, DI + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + LEAQ (DI)(R10*1), R11 + CMPQ R12, R11 + JG error_match_off_too_big + CMPQ R12, R8 + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, R11 + SUBQ DI, R11 + JLS copy_match + MOVQ R9, R14 + SUBQ R11, R14 + CMPQ R13, R11 + JG copy_all_from_history + MOVQ R13, R11 + SUBQ $0x10, R11 + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R11 + JAE copy_4_loop + LEAQ 16(R14)(R11*1), R14 + LEAQ 16(BX)(R11*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), R11 + MOVL -4(R14)(R13*1), R12 + MOVL R11, (BX) + MOVL R12, -4(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), R11 + MOVQ -8(R14)(R13*1), R12 + MOVQ R11, (BX) + MOVQ R12, -8(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + +copy_4_end: + ADDQ R13, DI + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + JMP loop_finished + +copy_all_from_history: + MOVQ R11, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(BX)(R15*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_5_end + +copy_5_small: + CMPQ R11, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ R11, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(R11*1), BP + MOVB R15, (BX) + MOVB BP, -1(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(R11*1), BP + MOVL R15, (BX) + MOVL BP, -4(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(R11*1), BP + MOVQ R15, (BX) + MOVQ BP, -8(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + +copy_5_end: + ADDQ R11, DI + SUBQ R11, R13 + + // Copy match from the current buffer +copy_match: + MOVQ BX, R11 + SUBQ R12, R11 + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, DI + MOVQ BX, R12 + ADDQ R13, BX + +copy_2: + MOVUPS (R11), X0 + MOVUPS X0, (R12) + ADDQ $0x10, R11 + ADDQ $0x10, R12 + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, DI + +copy_slow_3: + MOVB (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + +loop_finished: + // Return value + MOVB $0x01, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + SUBQ 80(AX), SI + MOVQ SI, 112(AX) + RET + +error_match_off_too_big: + // Return value + MOVB $0x00, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + SUBQ 80(AX), SI + MOVQ SI, 112(AX) + RET + +empty_seqs: + // Return value + MOVB $0x01, ret+8(FP) + RET + +// func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_safe_amd64(SB), $8-9 + MOVQ ctx+0(FP), R10 + MOVQ 8(R10), CX + TESTQ CX, CX + JZ empty_seqs + MOVQ (R10), AX + MOVQ 24(R10), DX + MOVQ 32(R10), BX + MOVQ 80(R10), SI + MOVQ 104(R10), DI + MOVQ 120(R10), R8 + MOVQ 56(R10), R9 + MOVQ 64(R10), R10 + ADDQ R10, R9 + + // seqsBase += 24 * seqIndex + LEAQ (DX)(DX*2), R11 + SHLQ $0x03, R11 + ADDQ R11, AX + + // outBase += outPosition + ADDQ DI, BX + +main_loop: + MOVQ (AX), R11 + MOVQ 16(AX), R12 + MOVQ 8(AX), R13 + + // Copy literals + TESTQ R11, R11 + JZ check_offset + MOVQ R11, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (SI), X0 + MOVUPS X0, (BX) + ADDQ $0x10, SI + ADDQ $0x10, BX + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(SI)(R14*1), SI + LEAQ 16(BX)(R14*1), BX + MOVUPS -16(SI), X0 + MOVUPS X0, -16(BX) + JMP copy_1_end + +copy_1_small: + CMPQ R11, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ R11, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (SI), R14 + MOVB -1(SI)(R11*1), R15 + MOVB R14, (BX) + MOVB R15, -1(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_3: + MOVW (SI), R14 + MOVB 2(SI), R15 + MOVW R14, (BX) + MOVB R15, 2(BX) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_4through7: + MOVL (SI), R14 + MOVL -4(SI)(R11*1), R15 + MOVL R14, (BX) + MOVL R15, -4(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (SI), R14 + MOVQ -8(SI)(R11*1), R15 + MOVQ R14, (BX) + MOVQ R15, -8(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + +copy_1_end: + ADDQ R11, DI + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + LEAQ (DI)(R10*1), R11 + CMPQ R12, R11 + JG error_match_off_too_big + CMPQ R12, R8 + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, R11 + SUBQ DI, R11 + JLS copy_match + MOVQ R9, R14 + SUBQ R11, R14 + CMPQ R13, R11 + JG copy_all_from_history + MOVQ R13, R11 + SUBQ $0x10, R11 + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R11 + JAE copy_4_loop + LEAQ 16(R14)(R11*1), R14 + LEAQ 16(BX)(R11*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), R11 + MOVL -4(R14)(R13*1), R12 + MOVL R11, (BX) + MOVL R12, -4(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), R11 + MOVQ -8(R14)(R13*1), R12 + MOVQ R11, (BX) + MOVQ R12, -8(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + +copy_4_end: + ADDQ R13, DI + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + JMP loop_finished + +copy_all_from_history: + MOVQ R11, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(BX)(R15*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_5_end + +copy_5_small: + CMPQ R11, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ R11, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(R11*1), BP + MOVB R15, (BX) + MOVB BP, -1(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(R11*1), BP + MOVL R15, (BX) + MOVL BP, -4(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(R11*1), BP + MOVQ R15, (BX) + MOVQ BP, -8(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + +copy_5_end: + ADDQ R11, DI + SUBQ R11, R13 + + // Copy match from the current buffer +copy_match: + MOVQ BX, R11 + SUBQ R12, R11 + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, DI + MOVQ R13, R12 + SUBQ $0x10, R12 + JB copy_2_small + +copy_2_loop: + MOVUPS (R11), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R11 + ADDQ $0x10, BX + SUBQ $0x10, R12 + JAE copy_2_loop + LEAQ 16(R11)(R12*1), R11 + LEAQ 16(BX)(R12*1), BX + MOVUPS -16(R11), X0 + MOVUPS X0, -16(BX) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (R11), R12 + MOVB -1(R11)(R13*1), R14 + MOVB R12, (BX) + MOVB R14, -1(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_3: + MOVW (R11), R12 + MOVB 2(R11), R14 + MOVW R12, (BX) + MOVB R14, 2(BX) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_4through7: + MOVL (R11), R12 + MOVL -4(R11)(R13*1), R14 + MOVL R12, (BX) + MOVL R14, -4(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (R11), R12 + MOVQ -8(R11)(R13*1), R14 + MOVQ R12, (BX) + MOVQ R14, -8(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, DI + +copy_slow_3: + MOVB (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + +loop_finished: + // Return value + MOVB $0x01, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + SUBQ 80(AX), SI + MOVQ SI, 112(AX) + RET + +error_match_off_too_big: + // Return value + MOVB $0x00, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + SUBQ 80(AX), SI + MOVQ SI, 112(AX) + RET + +empty_seqs: + // Return value + MOVB $0x01, ret+8(FP) + RET + +// func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_amd64(SB), $64-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + XORQ CX, CX + MOVQ CX, 8(SP) + MOVQ CX, 16(SP) + MOVQ CX, 24(SP) + MOVQ 112(AX), R10 + MOVQ 128(AX), CX + MOVQ CX, 32(SP) + MOVQ 144(AX), R11 + MOVQ 136(AX), R12 + MOVQ 200(AX), CX + MOVQ CX, 56(SP) + MOVQ 176(AX), CX + MOVQ CX, 48(SP) + MOVQ 184(AX), AX + MOVQ AX, 40(SP) + MOVQ 40(SP), AX + ADDQ AX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R10, 32(SP) + + // outBase += outPosition + ADDQ R12, R10 + +sequenceDecs_decodeSync_amd64_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_amd64_fill_end + +sequenceDecs_decodeSync_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_of_update_zero: + MOVQ AX, 8(SP) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_ml_update_zero: + MOVQ AX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_amd64_fill_2_end + +sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_ll_update_zero: + MOVQ AX, 24(SP) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R13 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R13 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R13 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decodeSync_amd64_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ AX, $0x01 + JBE sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_amd64_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offset_nonzero: + MOVQ R13, AX + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, AX + CMOVQEQ R15, R14 + ADDQ 144(CX)(AX*8), R14 + JNZ sequenceDecs_decodeSync_amd64_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_amd64_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_amd64_adjust_skip + MOVQ 152(CX), AX + MOVQ AX, 160(CX) + +sequenceDecs_decodeSync_amd64_adjust_skip: + MOVQ 144(CX), AX + MOVQ AX, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_amd64_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), AX + MOVQ 24(SP), CX + LEAQ (AX)(CX*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ CX, 104(R14) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decodeSync_amd64_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_amd64_match_len_ofs_ok: + MOVQ 24(SP), AX + MOVQ 8(SP), CX + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (AX)(R13*1), R14 + ADDQ R10, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ AX, AX + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (R11)(R14*1), X0 + MOVUPS X0, (R10)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, AX + JB copy_1 + ADDQ AX, R11 + ADDQ AX, R10 + ADDQ AX, R12 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R12, AX + ADDQ 40(SP), AX + CMPQ CX, AX + JG error_match_off_too_big + CMPQ CX, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ CX, AX + SUBQ R12, AX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ AX, R14 + CMPQ R13, AX + JG copy_all_from_history + MOVQ R13, AX + SUBQ $0x10, AX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, AX + JAE copy_4_loop + LEAQ 16(R14)(AX*1), R14 + LEAQ 16(R10)(AX*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), AX + MOVL -4(R14)(R13*1), CX + MOVL AX, (R10) + MOVL CX, -4(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), AX + MOVQ -8(R14)(R13*1), CX + MOVQ AX, (R10) + MOVQ CX, -8(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + +copy_4_end: + ADDQ R13, R12 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ AX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R10)(R15*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_5_end + +copy_5_small: + CMPQ AX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ AX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(AX*1), BP + MOVB R15, (R10) + MOVB BP, -1(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(AX*1), BP + MOVL R15, (R10) + MOVL BP, -4(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(AX*1), BP + MOVQ R15, (R10) + MOVQ BP, -8(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + +copy_5_end: + ADDQ AX, R12 + SUBQ AX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R10, AX + SUBQ CX, AX + + // ml <= mo + CMPQ R13, CX + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R12 + MOVQ R10, CX + ADDQ R13, R10 + +copy_2: + MOVUPS (AX), X0 + MOVUPS X0, (CX) + ADDQ $0x10, AX + ADDQ $0x10, CX + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R12 + +copy_slow_3: + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decodeSync_amd64_main_loop + +loop_finished: + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R12, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R11 + MOVQ R11, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_amd64_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: BMI, BMI2, CMOV, SSE +TEXT ·sequenceDecs_decodeSync_bmi2(SB), $64-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + XORQ R9, R9 + MOVQ R9, 8(SP) + MOVQ R9, 16(SP) + MOVQ R9, 24(SP) + MOVQ 112(CX), R9 + MOVQ 128(CX), R10 + MOVQ R10, 32(SP) + MOVQ 144(CX), R10 + MOVQ 136(CX), R11 + MOVQ 200(CX), R12 + MOVQ R12, 56(SP) + MOVQ 176(CX), R12 + MOVQ R12, 48(SP) + MOVQ 184(CX), CX + MOVQ CX, 40(SP) + MOVQ 40(SP), CX + ADDQ CX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R9, 32(SP) + + // outBase += outPosition + ADDQ R11, R9 + +sequenceDecs_decodeSync_bmi2_main_loop: + MOVQ (SP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_bmi2_fill_end + +sequenceDecs_decodeSync_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_bmi2_fill_byte_by_byte + +sequenceDecs_decodeSync_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 8(SP) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_bmi2_fill_2_end + +sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte + +sequenceDecs_decodeSync_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 24(SP) + + // Fill bitreader for state updates + MOVQ R12, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R12 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_bmi2_skip_update + LEAQ (SI)(DI*1), R13 + ADDQ R8, R13 + MOVBQZX R13, R13 + LEAQ (DX)(R13*1), CX + MOVQ AX, R14 + MOVQ CX, DX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + + // Update Offset State + BZHIQ R8, R14, CX + SHRXQ R8, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R14, CX + SHRXQ DI, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R14, CX + MOVQ $0x00001010, R13 + BEXTRQ R13, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decodeSync_bmi2_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ R12, $0x01 + JBE sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_bmi2_after_adjust + +sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero + +sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_bmi2_after_adjust + +sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero: + MOVQ R13, R12 + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, R12 + CMOVQEQ R15, R14 + ADDQ 144(CX)(R12*8), R14 + JNZ sequenceDecs_decodeSync_bmi2_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_bmi2_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_bmi2_adjust_skip + MOVQ 152(CX), R12 + MOVQ R12, 160(CX) + +sequenceDecs_decodeSync_bmi2_adjust_skip: + MOVQ 144(CX), R12 + MOVQ R12, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_bmi2_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), CX + MOVQ 24(SP), R12 + LEAQ (CX)(R12*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ R12, 104(R14) + JS error_not_enough_literals + CMPQ CX, $0x00020002 + JA sequenceDecs_decodeSync_bmi2_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok + TESTQ CX, CX + JNZ sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: + MOVQ 24(SP), CX + MOVQ 8(SP), R12 + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (CX)(R13*1), R14 + ADDQ R9, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ CX, CX + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (R10)(R14*1), X0 + MOVUPS X0, (R9)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, CX + JB copy_1 + ADDQ CX, R10 + ADDQ CX, R9 + ADDQ CX, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R11, CX + ADDQ 40(SP), CX + CMPQ R12, CX + JG error_match_off_too_big + CMPQ R12, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, CX + SUBQ R11, CX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ CX, R14 + CMPQ R13, CX + JG copy_all_from_history + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, CX + JAE copy_4_loop + LEAQ 16(R14)(CX*1), R14 + LEAQ 16(R9)(CX*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), CX + MOVL -4(R14)(R13*1), R12 + MOVL CX, (R9) + MOVL R12, -4(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), CX + MOVQ -8(R14)(R13*1), R12 + MOVQ CX, (R9) + MOVQ R12, -8(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + +copy_4_end: + ADDQ R13, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ CX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R9)(R15*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_5_end + +copy_5_small: + CMPQ CX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ CX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(CX*1), BP + MOVB R15, (R9) + MOVB BP, -1(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(CX*1), BP + MOVL R15, (R9) + MOVL BP, -4(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(CX*1), BP + MOVQ R15, (R9) + MOVQ BP, -8(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + +copy_5_end: + ADDQ CX, R11 + SUBQ CX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R9, CX + SUBQ R12, CX + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R11 + MOVQ R9, R12 + ADDQ R13, R9 + +copy_2: + MOVUPS (CX), X0 + MOVUPS X0, (R12) + ADDQ $0x10, CX + ADDQ $0x10, R12 + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R11 + +copy_slow_3: + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decodeSync_bmi2_main_loop + +loop_finished: + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R11, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R10 + MOVQ R10, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_bmi2_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $64-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + XORQ CX, CX + MOVQ CX, 8(SP) + MOVQ CX, 16(SP) + MOVQ CX, 24(SP) + MOVQ 112(AX), R10 + MOVQ 128(AX), CX + MOVQ CX, 32(SP) + MOVQ 144(AX), R11 + MOVQ 136(AX), R12 + MOVQ 200(AX), CX + MOVQ CX, 56(SP) + MOVQ 176(AX), CX + MOVQ CX, 48(SP) + MOVQ 184(AX), AX + MOVQ AX, 40(SP) + MOVQ 40(SP), AX + ADDQ AX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R10, 32(SP) + + // outBase += outPosition + ADDQ R12, R10 + +sequenceDecs_decodeSync_safe_amd64_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_safe_amd64_fill_end + +sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_safe_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_safe_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_of_update_zero: + MOVQ AX, 8(SP) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_ml_update_zero: + MOVQ AX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_end + +sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_ll_update_zero: + MOVQ AX, 24(SP) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_safe_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R13 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R13 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R13 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decodeSync_safe_amd64_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ AX, $0x01 + JBE sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero: + MOVQ R13, AX + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, AX + CMOVQEQ R15, R14 + ADDQ 144(CX)(AX*8), R14 + JNZ sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_safe_amd64_adjust_skip + MOVQ 152(CX), AX + MOVQ AX, 160(CX) + +sequenceDecs_decodeSync_safe_amd64_adjust_skip: + MOVQ 144(CX), AX + MOVQ AX, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_safe_amd64_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), AX + MOVQ 24(SP), CX + LEAQ (AX)(CX*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ CX, 104(R14) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: + MOVQ 24(SP), AX + MOVQ 8(SP), CX + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (AX)(R13*1), R14 + ADDQ R10, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ AX, AX + JZ check_offset + MOVQ AX, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (R11), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R11 + ADDQ $0x10, R10 + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(R11)(R14*1), R11 + LEAQ 16(R10)(R14*1), R10 + MOVUPS -16(R11), X0 + MOVUPS X0, -16(R10) + JMP copy_1_end + +copy_1_small: + CMPQ AX, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ AX, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (R11), R14 + MOVB -1(R11)(AX*1), R15 + MOVB R14, (R10) + MOVB R15, -1(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_3: + MOVW (R11), R14 + MOVB 2(R11), R15 + MOVW R14, (R10) + MOVB R15, 2(R10) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_4through7: + MOVL (R11), R14 + MOVL -4(R11)(AX*1), R15 + MOVL R14, (R10) + MOVL R15, -4(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (R11), R14 + MOVQ -8(R11)(AX*1), R15 + MOVQ R14, (R10) + MOVQ R15, -8(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + +copy_1_end: + ADDQ AX, R12 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R12, AX + ADDQ 40(SP), AX + CMPQ CX, AX + JG error_match_off_too_big + CMPQ CX, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ CX, AX + SUBQ R12, AX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ AX, R14 + CMPQ R13, AX + JG copy_all_from_history + MOVQ R13, AX + SUBQ $0x10, AX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, AX + JAE copy_4_loop + LEAQ 16(R14)(AX*1), R14 + LEAQ 16(R10)(AX*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), AX + MOVL -4(R14)(R13*1), CX + MOVL AX, (R10) + MOVL CX, -4(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), AX + MOVQ -8(R14)(R13*1), CX + MOVQ AX, (R10) + MOVQ CX, -8(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + +copy_4_end: + ADDQ R13, R12 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ AX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R10)(R15*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_5_end + +copy_5_small: + CMPQ AX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ AX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(AX*1), BP + MOVB R15, (R10) + MOVB BP, -1(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(AX*1), BP + MOVL R15, (R10) + MOVL BP, -4(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(AX*1), BP + MOVQ R15, (R10) + MOVQ BP, -8(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + +copy_5_end: + ADDQ AX, R12 + SUBQ AX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R10, AX + SUBQ CX, AX + + // ml <= mo + CMPQ R13, CX + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R12 + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_2_small + +copy_2_loop: + MOVUPS (AX), X0 + MOVUPS X0, (R10) + ADDQ $0x10, AX + ADDQ $0x10, R10 + SUBQ $0x10, CX + JAE copy_2_loop + LEAQ 16(AX)(CX*1), AX + LEAQ 16(R10)(CX*1), R10 + MOVUPS -16(AX), X0 + MOVUPS X0, -16(R10) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (AX), CL + MOVB -1(AX)(R13*1), R14 + MOVB CL, (R10) + MOVB R14, -1(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_3: + MOVW (AX), CX + MOVB 2(AX), R14 + MOVW CX, (R10) + MOVB R14, 2(R10) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_4through7: + MOVL (AX), CX + MOVL -4(AX)(R13*1), R14 + MOVL CX, (R10) + MOVL R14, -4(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (AX), CX + MOVQ -8(AX)(R13*1), R14 + MOVQ CX, (R10) + MOVQ R14, -8(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R12 + +copy_slow_3: + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decodeSync_safe_amd64_main_loop + +loop_finished: + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R12, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R11 + MOVQ R11, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: BMI, BMI2, CMOV, SSE +TEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $64-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + XORQ R9, R9 + MOVQ R9, 8(SP) + MOVQ R9, 16(SP) + MOVQ R9, 24(SP) + MOVQ 112(CX), R9 + MOVQ 128(CX), R10 + MOVQ R10, 32(SP) + MOVQ 144(CX), R10 + MOVQ 136(CX), R11 + MOVQ 200(CX), R12 + MOVQ R12, 56(SP) + MOVQ 176(CX), R12 + MOVQ R12, 48(SP) + MOVQ 184(CX), CX + MOVQ CX, 40(SP) + MOVQ 40(SP), CX + ADDQ CX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R9, 32(SP) + + // outBase += outPosition + ADDQ R11, R9 + +sequenceDecs_decodeSync_safe_bmi2_main_loop: + MOVQ (SP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_end + +sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte + +sequenceDecs_decodeSync_safe_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 8(SP) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_end + +sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte + +sequenceDecs_decodeSync_safe_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 24(SP) + + // Fill bitreader for state updates + MOVQ R12, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R12 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_safe_bmi2_skip_update + LEAQ (SI)(DI*1), R13 + ADDQ R8, R13 + MOVBQZX R13, R13 + LEAQ (DX)(R13*1), CX + MOVQ AX, R14 + MOVQ CX, DX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + + // Update Offset State + BZHIQ R8, R14, CX + SHRXQ R8, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R14, CX + SHRXQ DI, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R14, CX + MOVQ $0x00001010, R13 + BEXTRQ R13, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decodeSync_safe_bmi2_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ R12, $0x01 + JBE sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust + +sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero + +sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust + +sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero: + MOVQ R13, R12 + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, R12 + CMOVQEQ R15, R14 + ADDQ 144(CX)(R12*8), R14 + JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_safe_bmi2_adjust_skip + MOVQ 152(CX), R12 + MOVQ R12, 160(CX) + +sequenceDecs_decodeSync_safe_bmi2_adjust_skip: + MOVQ 144(CX), R12 + MOVQ R12, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_safe_bmi2_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), CX + MOVQ 24(SP), R12 + LEAQ (CX)(R12*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ R12, 104(R14) + JS error_not_enough_literals + CMPQ CX, $0x00020002 + JA sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok + TESTQ CX, CX + JNZ sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok: + MOVQ 24(SP), CX + MOVQ 8(SP), R12 + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (CX)(R13*1), R14 + ADDQ R9, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ CX, CX + JZ check_offset + MOVQ CX, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (R10), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R10 + ADDQ $0x10, R9 + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(R10)(R14*1), R10 + LEAQ 16(R9)(R14*1), R9 + MOVUPS -16(R10), X0 + MOVUPS X0, -16(R9) + JMP copy_1_end + +copy_1_small: + CMPQ CX, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ CX, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (R10), R14 + MOVB -1(R10)(CX*1), R15 + MOVB R14, (R9) + MOVB R15, -1(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_3: + MOVW (R10), R14 + MOVB 2(R10), R15 + MOVW R14, (R9) + MOVB R15, 2(R9) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_4through7: + MOVL (R10), R14 + MOVL -4(R10)(CX*1), R15 + MOVL R14, (R9) + MOVL R15, -4(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (R10), R14 + MOVQ -8(R10)(CX*1), R15 + MOVQ R14, (R9) + MOVQ R15, -8(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + +copy_1_end: + ADDQ CX, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R11, CX + ADDQ 40(SP), CX + CMPQ R12, CX + JG error_match_off_too_big + CMPQ R12, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, CX + SUBQ R11, CX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ CX, R14 + CMPQ R13, CX + JG copy_all_from_history + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, CX + JAE copy_4_loop + LEAQ 16(R14)(CX*1), R14 + LEAQ 16(R9)(CX*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), CX + MOVL -4(R14)(R13*1), R12 + MOVL CX, (R9) + MOVL R12, -4(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), CX + MOVQ -8(R14)(R13*1), R12 + MOVQ CX, (R9) + MOVQ R12, -8(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + +copy_4_end: + ADDQ R13, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ CX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R9)(R15*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_5_end + +copy_5_small: + CMPQ CX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ CX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(CX*1), BP + MOVB R15, (R9) + MOVB BP, -1(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(CX*1), BP + MOVL R15, (R9) + MOVL BP, -4(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(CX*1), BP + MOVQ R15, (R9) + MOVQ BP, -8(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + +copy_5_end: + ADDQ CX, R11 + SUBQ CX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R9, CX + SUBQ R12, CX + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R11 + MOVQ R13, R12 + SUBQ $0x10, R12 + JB copy_2_small + +copy_2_loop: + MOVUPS (CX), X0 + MOVUPS X0, (R9) + ADDQ $0x10, CX + ADDQ $0x10, R9 + SUBQ $0x10, R12 + JAE copy_2_loop + LEAQ 16(CX)(R12*1), CX + LEAQ 16(R9)(R12*1), R9 + MOVUPS -16(CX), X0 + MOVUPS X0, -16(R9) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (CX), R12 + MOVB -1(CX)(R13*1), R14 + MOVB R12, (R9) + MOVB R14, -1(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_3: + MOVW (CX), R12 + MOVB 2(CX), R14 + MOVW R12, (R9) + MOVB R14, 2(R9) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_4through7: + MOVL (CX), R12 + MOVL -4(CX)(R13*1), R14 + MOVL R12, (R9) + MOVL R14, -4(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (CX), R12 + MOVQ -8(CX)(R13*1), R14 + MOVQ R12, (R9) + MOVQ R14, -8(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R11 + +copy_slow_3: + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decodeSync_safe_bmi2_main_loop + +loop_finished: + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R11, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R10 + MOVQ R10, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go new file mode 100644 index 00000000000..ac2a80d2911 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go @@ -0,0 +1,237 @@ +//go:build !amd64 || appengine || !gc || noasm +// +build !amd64 appengine !gc noasm + +package zstd + +import ( + "fmt" + "io" +) + +// decode sequences from the stream with the provided history but without dictionary. +func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { + return false, nil +} + +// decode sequences from the stream without the provided history. +func (s *sequenceDecs) decode(seqs []seqVals) error { + br := s.br + + // Grab full sizes tables, to avoid bounds checks. + llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] + llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state + s.seqSize = 0 + litRemain := len(s.literals) + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + for i := range seqs { + var ll, mo, ml int + if br.off > 4+((maxOffsetBits+16+16)>>3) { + // inlined function: + // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) + + // Final will not read from stream. + var llB, mlB, moB uint8 + ll, llB = llState.final() + ml, mlB = mlState.final() + mo, moB = ofState.final() + + // extra bits are stored in reverse order. + br.fillFast() + mo += br.getBits(moB) + if s.maxBits > 32 { + br.fillFast() + } + ml += br.getBits(mlB) + ll += br.getBits(llB) + + if moB > 1 { + s.prevOffset[2] = s.prevOffset[1] + s.prevOffset[1] = s.prevOffset[0] + s.prevOffset[0] = mo + } else { + // mo = s.adjustOffset(mo, ll, moB) + // Inlined for rather big speedup + if ll == 0 { + // There is an exception though, when current sequence's literals_length = 0. + // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, + // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. + mo++ + } + + if mo == 0 { + mo = s.prevOffset[0] + } else { + var temp int + if mo == 3 { + temp = s.prevOffset[0] - 1 + } else { + temp = s.prevOffset[mo] + } + + if temp == 0 { + // 0 is not valid; input is corrupted; force offset to 1 + println("WARNING: temp was 0") + temp = 1 + } + + if mo != 1 { + s.prevOffset[2] = s.prevOffset[1] + } + s.prevOffset[1] = s.prevOffset[0] + s.prevOffset[0] = temp + mo = temp + } + } + br.fillFast() + } else { + if br.overread() { + if debugDecoder { + printf("reading sequence %d, exceeded available data\n", i) + } + return io.ErrUnexpectedEOF + } + ll, mo, ml = s.next(br, llState, mlState, ofState) + br.fill() + } + + if debugSequences { + println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml) + } + // Evaluate. + // We might be doing this async, so do it early. + if mo == 0 && ml > 0 { + return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) + } + if ml > maxMatchLen { + return fmt.Errorf("match len (%d) bigger than max allowed length", ml) + } + s.seqSize += ll + ml + if s.seqSize > maxBlockSize { + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } + litRemain -= ll + if litRemain < 0 { + return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll) + } + seqs[i] = seqVals{ + ll: ll, + ml: ml, + mo: mo, + } + if i == len(seqs)-1 { + // This is the last sequence, so we shouldn't update state. + break + } + + // Manually inlined, ~ 5-20% faster + // Update all 3 states at once. Approx 20% faster. + nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits() + if nBits == 0 { + llState = llTable[llState.newState()&maxTableMask] + mlState = mlTable[mlState.newState()&maxTableMask] + ofState = ofTable[ofState.newState()&maxTableMask] + } else { + bits := br.get32BitsFast(nBits) + lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) + llState = llTable[(llState.newState()+lowBits)&maxTableMask] + + lowBits = uint16(bits >> (ofState.nbBits() & 31)) + lowBits &= bitMask[mlState.nbBits()&15] + mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask] + + lowBits = uint16(bits) & bitMask[ofState.nbBits()&15] + ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask] + } + } + s.seqSize += litRemain + if s.seqSize > maxBlockSize { + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + } + return err +} + +// executeSimple handles cases when a dictionary is not used. +func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { + // Ensure we have enough output size... + if len(s.out)+s.seqSize > cap(s.out) { + addBytes := s.seqSize + len(s.out) + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] + } + + if debugDecoder { + printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) + } + + var t = len(s.out) + out := s.out[:t+s.seqSize] + + for _, seq := range seqs { + // Add literals + copy(out[t:], s.literals[:seq.ll]) + t += seq.ll + s.literals = s.literals[seq.ll:] + + // Malformed input + if seq.mo > t+len(hist) || seq.mo > s.windowSize { + return fmt.Errorf("match offset (%d) bigger than current history (%d)", seq.mo, t+len(hist)) + } + + // Copy from history. + if v := seq.mo - t; v > 0 { + // v is the start position in history from end. + start := len(hist) - v + if seq.ml > v { + // Some goes into the current block. + // Copy remainder of history + copy(out[t:], hist[start:]) + t += v + seq.ml -= v + } else { + copy(out[t:], hist[start:start+seq.ml]) + t += seq.ml + continue + } + } + + // We must be in the current buffer now + if seq.ml > 0 { + start := t - seq.mo + if seq.ml <= t-start { + // No overlap + copy(out[t:], out[start:start+seq.ml]) + t += seq.ml + } else { + // Overlapping copy + // Extend destination slice and copy one byte at the time. + src := out[start : start+seq.ml] + dst := out[t:] + dst = dst[:len(src)] + t += len(src) + // Destination is the space we just added. + for i := range src { + dst[i] = src[i] + } + } + } + } + // Add final literals + copy(out[t:], s.literals) + if debugDecoder { + t += len(s.literals) + if t != len(out) { + panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) + } + } + s.out = out + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/zip.go b/vendor/github.com/klauspost/compress/zstd/zip.go index ffffcbc254e..29c15c8c4ef 100644 --- a/vendor/github.com/klauspost/compress/zstd/zip.go +++ b/vendor/github.com/klauspost/compress/zstd/zip.go @@ -18,26 +18,44 @@ const ZipMethodWinZip = 93 // See https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.9.TXT const ZipMethodPKWare = 20 -var zipReaderPool sync.Pool +// zipReaderPool is the default reader pool. +var zipReaderPool = sync.Pool{New: func() interface{} { + z, err := NewReader(nil, WithDecoderLowmem(true), WithDecoderMaxWindow(128<<20), WithDecoderConcurrency(1)) + if err != nil { + panic(err) + } + return z +}} // newZipReader creates a pooled zip decompressor. -func newZipReader(r io.Reader) io.ReadCloser { - dec, ok := zipReaderPool.Get().(*Decoder) - if ok { - dec.Reset(r) - } else { - d, err := NewReader(r, WithDecoderConcurrency(1), WithDecoderLowmem(true)) - if err != nil { - panic(err) +func newZipReader(opts ...DOption) func(r io.Reader) io.ReadCloser { + pool := &zipReaderPool + if len(opts) > 0 { + opts = append([]DOption{WithDecoderLowmem(true), WithDecoderMaxWindow(128 << 20)}, opts...) + // Force concurrency 1 + opts = append(opts, WithDecoderConcurrency(1)) + // Create our own pool + pool = &sync.Pool{} + } + return func(r io.Reader) io.ReadCloser { + dec, ok := pool.Get().(*Decoder) + if ok { + dec.Reset(r) + } else { + d, err := NewReader(r, opts...) + if err != nil { + panic(err) + } + dec = d } - dec = d + return &pooledZipReader{dec: dec, pool: pool} } - return &pooledZipReader{dec: dec} } type pooledZipReader struct { - mu sync.Mutex // guards Close and Read - dec *Decoder + mu sync.Mutex // guards Close and Read + pool *sync.Pool + dec *Decoder } func (r *pooledZipReader) Read(p []byte) (n int, err error) { @@ -48,8 +66,8 @@ func (r *pooledZipReader) Read(p []byte) (n int, err error) { } dec, err := r.dec.Read(p) if err == io.EOF { - err = r.dec.Reset(nil) - zipReaderPool.Put(r.dec) + r.dec.Reset(nil) + r.pool.Put(r.dec) r.dec = nil } return dec, err @@ -61,7 +79,7 @@ func (r *pooledZipReader) Close() error { var err error if r.dec != nil { err = r.dec.Reset(nil) - zipReaderPool.Put(r.dec) + r.pool.Put(r.dec) r.dec = nil } return err @@ -115,6 +133,9 @@ func ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) { // ZipDecompressor returns a decompressor that can be registered with zip libraries. // See ZipCompressor for example. -func ZipDecompressor() func(r io.Reader) io.ReadCloser { - return newZipReader +// Options can be specified. WithDecoderConcurrency(1) is forced, +// and by default a 128MB maximum decompression window is specified. +// The window size can be overridden if required. +func ZipDecompressor(opts ...DOption) func(r io.Reader) io.ReadCloser { + return newZipReader(opts...) } diff --git a/vendor/github.com/klauspost/compress/zstd/zstd.go b/vendor/github.com/klauspost/compress/zstd/zstd.go index c1c90b4a072..5ffa82f5ac1 100644 --- a/vendor/github.com/klauspost/compress/zstd/zstd.go +++ b/vendor/github.com/klauspost/compress/zstd/zstd.go @@ -36,9 +36,6 @@ const forcePreDef = false // zstdMinMatch is the minimum zstd match length. const zstdMinMatch = 3 -// Reset the buffer offset when reaching this. -const bufferReset = math.MaxInt32 - MaxWindowSize - // fcsUnknown is used for unknown frame content size. const fcsUnknown = math.MaxUint64 @@ -75,7 +72,6 @@ var ( ErrDecoderSizeExceeded = errors.New("decompressed size exceeds configured limit") // ErrUnknownDictionary is returned if the dictionary ID is unknown. - // For the time being dictionaries are not supported. ErrUnknownDictionary = errors.New("unknown dictionary") // ErrFrameSizeExceeded is returned if the stated frame size is exceeded. @@ -110,37 +106,25 @@ func printf(format string, a ...interface{}) { } } -// matchLenFast does matching, but will not match the last up to 7 bytes. -func matchLenFast(a, b []byte) int { - endI := len(a) & (math.MaxInt32 - 7) - for i := 0; i < endI; i += 8 { - if diff := load64(a, i) ^ load64(b, i); diff != 0 { - return i + bits.TrailingZeros64(diff)>>3 - } - } - return endI -} - -// matchLen returns the maximum length. +// matchLen returns the maximum common prefix length of a and b. // a must be the shortest of the two. -// The function also returns whether all bytes matched. -func matchLen(a, b []byte) int { - b = b[:len(a)] - for i := 0; i < len(a)-7; i += 8 { - if diff := load64(a, i) ^ load64(b, i); diff != 0 { - return i + (bits.TrailingZeros64(diff) >> 3) +func matchLen(a, b []byte) (n int) { + for ; len(a) >= 8 && len(b) >= 8; a, b = a[8:], b[8:] { + diff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b) + if diff != 0 { + return n + bits.TrailingZeros64(diff)>>3 } + n += 8 } - checked := (len(a) >> 3) << 3 - a = a[checked:] - b = b[checked:] for i := range a { if a[i] != b[i] { - return i + checked + break } + n++ } - return len(a) + checked + return n + } func load3232(b []byte, i int32) uint32 { @@ -151,10 +135,6 @@ func load6432(b []byte, i int32) uint64 { return binary.LittleEndian.Uint64(b[i:]) } -func load64(b []byte, i int) uint64 { - return binary.LittleEndian.Uint64(b[i:]) -} - type byter interface { Bytes() []byte Len() int diff --git a/vendor/github.com/nxadm/tail/.gitignore b/vendor/github.com/nxadm/tail/.gitignore deleted file mode 100644 index 35d9351d385..00000000000 --- a/vendor/github.com/nxadm/tail/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.idea/ -.test/ -examples/_* \ No newline at end of file diff --git a/vendor/github.com/nxadm/tail/CHANGES.md b/vendor/github.com/nxadm/tail/CHANGES.md deleted file mode 100644 index 224e54b44de..00000000000 --- a/vendor/github.com/nxadm/tail/CHANGES.md +++ /dev/null @@ -1,56 +0,0 @@ -# Version v1.4.7-v1.4.8 -* Documentation updates. -* Small linter cleanups. -* Added example in test. - -# Version v1.4.6 - -* Document the usage of Cleanup when re-reading a file (thanks to @lesovsky) for issue #18. -* Add example directories with example and tests for issues. - -# Version v1.4.4-v1.4.5 - -* Fix of checksum problem because of forced tag. No changes to the code. - -# Version v1.4.1 - -* Incorporated PR 162 by by Mohammed902: "Simplify non-Windows build tag". - -# Version v1.4.0 - -* Incorporated PR 9 by mschneider82: "Added seekinfo to Tail". - -# Version v1.3.1 - -* Incorporated PR 7: "Fix deadlock when stopping on non-empty file/buffer", -fixes upstream issue 93. - - -# Version v1.3.0 - -* Incorporated changes of unmerged upstream PR 149 by mezzi: "added line num -to Line struct". - -# Version v1.2.1 - -* Incorporated changes of unmerged upstream PR 128 by jadekler: "Compile-able -code in readme". -* Incorporated changes of unmerged upstream PR 130 by fgeller: "small change -to comment wording". -* Incorporated changes of unmerged upstream PR 133 by sm3142: "removed -spurious newlines from log messages". - -# Version v1.2.0 - -* Incorporated changes of unmerged upstream PR 126 by Code-Hex: "Solved the - problem for never return the last line if it's not followed by a newline". -* Incorporated changes of unmerged upstream PR 131 by StoicPerlman: "Remove -deprecated os.SEEK consts". The changes bumped the minimal supported Go -release to 1.9. - -# Version v1.1.0 - -* migration to go modules. -* release of master branch of the dormant upstream, because it contains -fixes and improvement no present in the tagged release. - diff --git a/vendor/github.com/nxadm/tail/Dockerfile b/vendor/github.com/nxadm/tail/Dockerfile deleted file mode 100644 index d9633891c00..00000000000 --- a/vendor/github.com/nxadm/tail/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM golang - -RUN mkdir -p $GOPATH/src/github.com/nxadm/tail/ -ADD . $GOPATH/src/github.com/nxadm/tail/ - -# expecting to fetch dependencies successfully. -RUN go get -v github.com/nxadm/tail - -# expecting to run the test successfully. -RUN go test -v github.com/nxadm/tail - -# expecting to install successfully -RUN go install -v github.com/nxadm/tail -RUN go install -v github.com/nxadm/tail/cmd/gotail - -RUN $GOPATH/bin/gotail -h || true - -ENV PATH $GOPATH/bin:$PATH -CMD ["gotail"] diff --git a/vendor/github.com/nxadm/tail/LICENSE b/vendor/github.com/nxadm/tail/LICENSE deleted file mode 100644 index 818d802a59a..00000000000 --- a/vendor/github.com/nxadm/tail/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -# The MIT License (MIT) - -# © Copyright 2015 Hewlett Packard Enterprise Development LP -Copyright (c) 2014 ActiveState - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/nxadm/tail/README.md b/vendor/github.com/nxadm/tail/README.md deleted file mode 100644 index f47939c749d..00000000000 --- a/vendor/github.com/nxadm/tail/README.md +++ /dev/null @@ -1,44 +0,0 @@ -![ci](https://github.com/nxadm/tail/workflows/ci/badge.svg)[![Go Reference](https://pkg.go.dev/badge/github.com/nxadm/tail.svg)](https://pkg.go.dev/github.com/nxadm/tail) - -# tail functionality in Go - -nxadm/tail provides a Go library that emulates the features of the BSD `tail` -program. The library comes with full support for truncation/move detection as -it is designed to work with log rotation tools. The library works on all -operating systems supported by Go, including POSIX systems like Linux and -*BSD, and MS Windows. Go 1.9 is the oldest compiler release supported. - -A simple example: - -```Go -// Create a tail -t, err := tail.TailFile( - "/var/log/nginx.log", tail.Config{Follow: true, ReOpen: true}) -if err != nil { - panic(err) -} - -// Print the text of each received line -for line := range t.Lines { - fmt.Println(line.Text) -} -``` - -See [API documentation](https://pkg.go.dev/github.com/nxadm/tail). - -## Installing - - go get github.com/nxadm/tail/... - -## History - -This project is an active, drop-in replacement for the -[abandoned](https://en.wikipedia.org/wiki/HPE_Helion) Go tail library at -[hpcloud](https://github.com/hpcloud/tail). Next to -[addressing open issues/PRs of the original project](https://github.com/nxadm/tail/issues/6), -nxadm/tail continues the development by keeping up to date with the Go toolchain -(e.g. go modules) and dependencies, completing the documentation, adding features -and fixing bugs. - -## Examples -Examples, e.g. used to debug an issue, are kept in the [examples directory](/examples). \ No newline at end of file diff --git a/vendor/github.com/nxadm/tail/ratelimiter/Licence b/vendor/github.com/nxadm/tail/ratelimiter/Licence deleted file mode 100644 index 434aab19f1a..00000000000 --- a/vendor/github.com/nxadm/tail/ratelimiter/Licence +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (C) 2013 99designs - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/nxadm/tail/ratelimiter/leakybucket.go b/vendor/github.com/nxadm/tail/ratelimiter/leakybucket.go deleted file mode 100644 index 358b69e7f5c..00000000000 --- a/vendor/github.com/nxadm/tail/ratelimiter/leakybucket.go +++ /dev/null @@ -1,97 +0,0 @@ -// Package ratelimiter implements the Leaky Bucket ratelimiting algorithm with memcached and in-memory backends. -package ratelimiter - -import ( - "time" -) - -type LeakyBucket struct { - Size uint16 - Fill float64 - LeakInterval time.Duration // time.Duration for 1 unit of size to leak - Lastupdate time.Time - Now func() time.Time -} - -func NewLeakyBucket(size uint16, leakInterval time.Duration) *LeakyBucket { - bucket := LeakyBucket{ - Size: size, - Fill: 0, - LeakInterval: leakInterval, - Now: time.Now, - Lastupdate: time.Now(), - } - - return &bucket -} - -func (b *LeakyBucket) updateFill() { - now := b.Now() - if b.Fill > 0 { - elapsed := now.Sub(b.Lastupdate) - - b.Fill -= float64(elapsed) / float64(b.LeakInterval) - if b.Fill < 0 { - b.Fill = 0 - } - } - b.Lastupdate = now -} - -func (b *LeakyBucket) Pour(amount uint16) bool { - b.updateFill() - - var newfill float64 = b.Fill + float64(amount) - - if newfill > float64(b.Size) { - return false - } - - b.Fill = newfill - - return true -} - -// The time at which this bucket will be completely drained -func (b *LeakyBucket) DrainedAt() time.Time { - return b.Lastupdate.Add(time.Duration(b.Fill * float64(b.LeakInterval))) -} - -// The duration until this bucket is completely drained -func (b *LeakyBucket) TimeToDrain() time.Duration { - return b.DrainedAt().Sub(b.Now()) -} - -func (b *LeakyBucket) TimeSinceLastUpdate() time.Duration { - return b.Now().Sub(b.Lastupdate) -} - -type LeakyBucketSer struct { - Size uint16 - Fill float64 - LeakInterval time.Duration // time.Duration for 1 unit of size to leak - Lastupdate time.Time -} - -func (b *LeakyBucket) Serialise() *LeakyBucketSer { - bucket := LeakyBucketSer{ - Size: b.Size, - Fill: b.Fill, - LeakInterval: b.LeakInterval, - Lastupdate: b.Lastupdate, - } - - return &bucket -} - -func (b *LeakyBucketSer) DeSerialise() *LeakyBucket { - bucket := LeakyBucket{ - Size: b.Size, - Fill: b.Fill, - LeakInterval: b.LeakInterval, - Lastupdate: b.Lastupdate, - Now: time.Now, - } - - return &bucket -} diff --git a/vendor/github.com/nxadm/tail/ratelimiter/memory.go b/vendor/github.com/nxadm/tail/ratelimiter/memory.go deleted file mode 100644 index bf3c2131b1e..00000000000 --- a/vendor/github.com/nxadm/tail/ratelimiter/memory.go +++ /dev/null @@ -1,60 +0,0 @@ -package ratelimiter - -import ( - "errors" - "time" -) - -const ( - GC_SIZE int = 100 - GC_PERIOD time.Duration = 60 * time.Second -) - -type Memory struct { - store map[string]LeakyBucket - lastGCCollected time.Time -} - -func NewMemory() *Memory { - m := new(Memory) - m.store = make(map[string]LeakyBucket) - m.lastGCCollected = time.Now() - return m -} - -func (m *Memory) GetBucketFor(key string) (*LeakyBucket, error) { - - bucket, ok := m.store[key] - if !ok { - return nil, errors.New("miss") - } - - return &bucket, nil -} - -func (m *Memory) SetBucketFor(key string, bucket LeakyBucket) error { - - if len(m.store) > GC_SIZE { - m.GarbageCollect() - } - - m.store[key] = bucket - - return nil -} - -func (m *Memory) GarbageCollect() { - now := time.Now() - - // rate limit GC to once per minute - if now.Unix() >= m.lastGCCollected.Add(GC_PERIOD).Unix() { - for key, bucket := range m.store { - // if the bucket is drained, then GC - if bucket.DrainedAt().Unix() < now.Unix() { - delete(m.store, key) - } - } - - m.lastGCCollected = now - } -} diff --git a/vendor/github.com/nxadm/tail/ratelimiter/storage.go b/vendor/github.com/nxadm/tail/ratelimiter/storage.go deleted file mode 100644 index 89b2fe8826e..00000000000 --- a/vendor/github.com/nxadm/tail/ratelimiter/storage.go +++ /dev/null @@ -1,6 +0,0 @@ -package ratelimiter - -type Storage interface { - GetBucketFor(string) (*LeakyBucket, error) - SetBucketFor(string, LeakyBucket) error -} diff --git a/vendor/github.com/nxadm/tail/tail.go b/vendor/github.com/nxadm/tail/tail.go deleted file mode 100644 index 37ea4411e9d..00000000000 --- a/vendor/github.com/nxadm/tail/tail.go +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -//nxadm/tail provides a Go library that emulates the features of the BSD `tail` -//program. The library comes with full support for truncation/move detection as -//it is designed to work with log rotation tools. The library works on all -//operating systems supported by Go, including POSIX systems like Linux and -//*BSD, and MS Windows. Go 1.9 is the oldest compiler release supported. -package tail - -import ( - "bufio" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "strings" - "sync" - "time" - - "github.com/nxadm/tail/ratelimiter" - "github.com/nxadm/tail/util" - "github.com/nxadm/tail/watch" - "gopkg.in/tomb.v1" -) - -var ( - // ErrStop is returned when the tail of a file has been marked to be stopped. - ErrStop = errors.New("tail should now stop") -) - -type Line struct { - Text string // The contents of the file - Num int // The line number - SeekInfo SeekInfo // SeekInfo - Time time.Time // Present time - Err error // Error from tail -} - -// Deprecated: this function is no longer used internally and it has little of no -// use in the API. As such, it will be removed from the API in a future major -// release. -// -// NewLine returns a * pointer to a Line struct. -func NewLine(text string, lineNum int) *Line { - return &Line{text, lineNum, SeekInfo{}, time.Now(), nil} -} - -// SeekInfo represents arguments to io.Seek. See: https://golang.org/pkg/io/#SectionReader.Seek -type SeekInfo struct { - Offset int64 - Whence int -} - -type logger interface { - Fatal(v ...interface{}) - Fatalf(format string, v ...interface{}) - Fatalln(v ...interface{}) - Panic(v ...interface{}) - Panicf(format string, v ...interface{}) - Panicln(v ...interface{}) - Print(v ...interface{}) - Printf(format string, v ...interface{}) - Println(v ...interface{}) -} - -// Config is used to specify how a file must be tailed. -type Config struct { - // File-specifc - Location *SeekInfo // Tail from this location. If nil, start at the beginning of the file - ReOpen bool // Reopen recreated files (tail -F) - MustExist bool // Fail early if the file does not exist - Poll bool // Poll for file changes instead of using the default inotify - Pipe bool // The file is a named pipe (mkfifo) - - // Generic IO - Follow bool // Continue looking for new lines (tail -f) - MaxLineSize int // If non-zero, split longer lines into multiple lines - - // Optionally, use a ratelimiter (e.g. created by the ratelimiter/NewLeakyBucket function) - RateLimiter *ratelimiter.LeakyBucket - - // Optionally use a Logger. When nil, the Logger is set to tail.DefaultLogger. - // To disable logging, set it to tail.DiscardingLogger - Logger logger -} - -type Tail struct { - Filename string // The filename - Lines chan *Line // A consumable channel of *Line - Config // Tail.Configuration - - file *os.File - reader *bufio.Reader - lineNum int - - watcher watch.FileWatcher - changes *watch.FileChanges - - tomb.Tomb // provides: Done, Kill, Dying - - lk sync.Mutex -} - -var ( - // DefaultLogger logs to os.Stderr and it is used when Config.Logger == nil - DefaultLogger = log.New(os.Stderr, "", log.LstdFlags) - // DiscardingLogger can be used to disable logging output - DiscardingLogger = log.New(ioutil.Discard, "", 0) -) - -// TailFile begins tailing the file. And returns a pointer to a Tail struct -// and an error. An output stream is made available via the Tail.Lines -// channel (e.g. to be looped and printed). To handle errors during tailing, -// after finishing reading from the Lines channel, invoke the `Wait` or `Err` -// method on the returned *Tail. -func TailFile(filename string, config Config) (*Tail, error) { - if config.ReOpen && !config.Follow { - util.Fatal("cannot set ReOpen without Follow.") - } - - t := &Tail{ - Filename: filename, - Lines: make(chan *Line), - Config: config, - } - - // when Logger was not specified in config, use default logger - if t.Logger == nil { - t.Logger = DefaultLogger - } - - if t.Poll { - t.watcher = watch.NewPollingFileWatcher(filename) - } else { - t.watcher = watch.NewInotifyFileWatcher(filename) - } - - if t.MustExist { - var err error - t.file, err = OpenFile(t.Filename) - if err != nil { - return nil, err - } - } - - go t.tailFileSync() - - return t, nil -} - -// Tell returns the file's current position, like stdio's ftell() and an error. -// Beware that this value may not be completely accurate because one line from -// the chan(tail.Lines) may have been read already. -func (tail *Tail) Tell() (offset int64, err error) { - if tail.file == nil { - return - } - offset, err = tail.file.Seek(0, io.SeekCurrent) - if err != nil { - return - } - - tail.lk.Lock() - defer tail.lk.Unlock() - if tail.reader == nil { - return - } - - offset -= int64(tail.reader.Buffered()) - return -} - -// Stop stops the tailing activity. -func (tail *Tail) Stop() error { - tail.Kill(nil) - return tail.Wait() -} - -// StopAtEOF stops tailing as soon as the end of the file is reached. The function -// returns an error, -func (tail *Tail) StopAtEOF() error { - tail.Kill(errStopAtEOF) - return tail.Wait() -} - -var errStopAtEOF = errors.New("tail: stop at eof") - -func (tail *Tail) close() { - close(tail.Lines) - tail.closeFile() -} - -func (tail *Tail) closeFile() { - if tail.file != nil { - tail.file.Close() - tail.file = nil - } -} - -func (tail *Tail) reopen() error { - tail.closeFile() - tail.lineNum = 0 - for { - var err error - tail.file, err = OpenFile(tail.Filename) - if err != nil { - if os.IsNotExist(err) { - tail.Logger.Printf("Waiting for %s to appear...", tail.Filename) - if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil { - if err == tomb.ErrDying { - return err - } - return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err) - } - continue - } - return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err) - } - break - } - return nil -} - -func (tail *Tail) readLine() (string, error) { - tail.lk.Lock() - line, err := tail.reader.ReadString('\n') - tail.lk.Unlock() - if err != nil { - // Note ReadString "returns the data read before the error" in - // case of an error, including EOF, so we return it as is. The - // caller is expected to process it if err is EOF. - return line, err - } - - line = strings.TrimRight(line, "\n") - - return line, err -} - -func (tail *Tail) tailFileSync() { - defer tail.Done() - defer tail.close() - - if !tail.MustExist { - // deferred first open. - err := tail.reopen() - if err != nil { - if err != tomb.ErrDying { - tail.Kill(err) - } - return - } - } - - // Seek to requested location on first open of the file. - if tail.Location != nil { - _, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence) - if err != nil { - tail.Killf("Seek error on %s: %s", tail.Filename, err) - return - } - } - - tail.openReader() - - // Read line by line. - for { - // do not seek in named pipes - if !tail.Pipe { - // grab the position in case we need to back up in the event of a half-line - if _, err := tail.Tell(); err != nil { - tail.Kill(err) - return - } - } - - line, err := tail.readLine() - - // Process `line` even if err is EOF. - if err == nil { - cooloff := !tail.sendLine(line) - if cooloff { - // Wait a second before seeking till the end of - // file when rate limit is reached. - msg := ("Too much log activity; waiting a second before resuming tailing") - offset, _ := tail.Tell() - tail.Lines <- &Line{msg, tail.lineNum, SeekInfo{Offset: offset}, time.Now(), errors.New(msg)} - select { - case <-time.After(time.Second): - case <-tail.Dying(): - return - } - if err := tail.seekEnd(); err != nil { - tail.Kill(err) - return - } - } - } else if err == io.EOF { - if !tail.Follow { - if line != "" { - tail.sendLine(line) - } - return - } - - if tail.Follow && line != "" { - tail.sendLine(line) - if err := tail.seekEnd(); err != nil { - tail.Kill(err) - return - } - } - - // When EOF is reached, wait for more data to become - // available. Wait strategy is based on the `tail.watcher` - // implementation (inotify or polling). - err := tail.waitForChanges() - if err != nil { - if err != ErrStop { - tail.Kill(err) - } - return - } - } else { - // non-EOF error - tail.Killf("Error reading %s: %s", tail.Filename, err) - return - } - - select { - case <-tail.Dying(): - if tail.Err() == errStopAtEOF { - continue - } - return - default: - } - } -} - -// waitForChanges waits until the file has been appended, deleted, -// moved or truncated. When moved or deleted - the file will be -// reopened if ReOpen is true. Truncated files are always reopened. -func (tail *Tail) waitForChanges() error { - if tail.changes == nil { - pos, err := tail.file.Seek(0, io.SeekCurrent) - if err != nil { - return err - } - tail.changes, err = tail.watcher.ChangeEvents(&tail.Tomb, pos) - if err != nil { - return err - } - } - - select { - case <-tail.changes.Modified: - return nil - case <-tail.changes.Deleted: - tail.changes = nil - if tail.ReOpen { - // XXX: we must not log from a library. - tail.Logger.Printf("Re-opening moved/deleted file %s ...", tail.Filename) - if err := tail.reopen(); err != nil { - return err - } - tail.Logger.Printf("Successfully reopened %s", tail.Filename) - tail.openReader() - return nil - } - tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename) - return ErrStop - case <-tail.changes.Truncated: - // Always reopen truncated files (Follow is true) - tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename) - if err := tail.reopen(); err != nil { - return err - } - tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename) - tail.openReader() - return nil - case <-tail.Dying(): - return ErrStop - } -} - -func (tail *Tail) openReader() { - tail.lk.Lock() - if tail.MaxLineSize > 0 { - // add 2 to account for newline characters - tail.reader = bufio.NewReaderSize(tail.file, tail.MaxLineSize+2) - } else { - tail.reader = bufio.NewReader(tail.file) - } - tail.lk.Unlock() -} - -func (tail *Tail) seekEnd() error { - return tail.seekTo(SeekInfo{Offset: 0, Whence: io.SeekEnd}) -} - -func (tail *Tail) seekTo(pos SeekInfo) error { - _, err := tail.file.Seek(pos.Offset, pos.Whence) - if err != nil { - return fmt.Errorf("Seek error on %s: %s", tail.Filename, err) - } - // Reset the read buffer whenever the file is re-seek'ed - tail.reader.Reset(tail.file) - return nil -} - -// sendLine sends the line(s) to Lines channel, splitting longer lines -// if necessary. Return false if rate limit is reached. -func (tail *Tail) sendLine(line string) bool { - now := time.Now() - lines := []string{line} - - // Split longer lines - if tail.MaxLineSize > 0 && len(line) > tail.MaxLineSize { - lines = util.PartitionString(line, tail.MaxLineSize) - } - - for _, line := range lines { - tail.lineNum++ - offset, _ := tail.Tell() - select { - case tail.Lines <- &Line{line, tail.lineNum, SeekInfo{Offset: offset}, now, nil}: - case <-tail.Dying(): - return true - } - } - - if tail.Config.RateLimiter != nil { - ok := tail.Config.RateLimiter.Pour(uint16(len(lines))) - if !ok { - tail.Logger.Printf("Leaky bucket full (%v); entering 1s cooloff period.", - tail.Filename) - return false - } - } - - return true -} - -// Cleanup removes inotify watches added by the tail package. This function is -// meant to be invoked from a process's exit handler. Linux kernel may not -// automatically remove inotify watches after the process exits. -// If you plan to re-read a file, don't call Cleanup in between. -func (tail *Tail) Cleanup() { - watch.Cleanup(tail.Filename) -} diff --git a/vendor/github.com/nxadm/tail/tail_posix.go b/vendor/github.com/nxadm/tail/tail_posix.go deleted file mode 100644 index 23e071dea16..00000000000 --- a/vendor/github.com/nxadm/tail/tail_posix.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// +build !windows - -package tail - -import ( - "os" -) - -// Deprecated: this function is only useful internally and, as such, -// it will be removed from the API in a future major release. -// -// OpenFile proxies a os.Open call for a file so it can be correctly tailed -// on POSIX and non-POSIX OSes like MS Windows. -func OpenFile(name string) (file *os.File, err error) { - return os.Open(name) -} diff --git a/vendor/github.com/nxadm/tail/tail_windows.go b/vendor/github.com/nxadm/tail/tail_windows.go deleted file mode 100644 index da0d2f39c97..00000000000 --- a/vendor/github.com/nxadm/tail/tail_windows.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// +build windows - -package tail - -import ( - "os" - - "github.com/nxadm/tail/winfile" -) - -// Deprecated: this function is only useful internally and, as such, -// it will be removed from the API in a future major release. -// -// OpenFile proxies a os.Open call for a file so it can be correctly tailed -// on POSIX and non-POSIX OSes like MS Windows. -func OpenFile(name string) (file *os.File, err error) { - return winfile.OpenFile(name, os.O_RDONLY, 0) -} diff --git a/vendor/github.com/nxadm/tail/util/util.go b/vendor/github.com/nxadm/tail/util/util.go deleted file mode 100644 index b64caa21269..00000000000 --- a/vendor/github.com/nxadm/tail/util/util.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -package util - -import ( - "fmt" - "log" - "os" - "runtime/debug" -) - -type Logger struct { - *log.Logger -} - -var LOGGER = &Logger{log.New(os.Stderr, "", log.LstdFlags)} - -// fatal is like panic except it displays only the current goroutine's stack. -func Fatal(format string, v ...interface{}) { - // https://github.com/nxadm/log/blob/master/log.go#L45 - LOGGER.Output(2, fmt.Sprintf("FATAL -- "+format, v...)+"\n"+string(debug.Stack())) - os.Exit(1) -} - -// partitionString partitions the string into chunks of given size, -// with the last chunk of variable size. -func PartitionString(s string, chunkSize int) []string { - if chunkSize <= 0 { - panic("invalid chunkSize") - } - length := len(s) - chunks := 1 + length/chunkSize - start := 0 - end := chunkSize - parts := make([]string, 0, chunks) - for { - if end > length { - end = length - } - parts = append(parts, s[start:end]) - if end == length { - break - } - start, end = end, end+chunkSize - } - return parts -} diff --git a/vendor/github.com/nxadm/tail/watch/filechanges.go b/vendor/github.com/nxadm/tail/watch/filechanges.go deleted file mode 100644 index 5b65f42ae58..00000000000 --- a/vendor/github.com/nxadm/tail/watch/filechanges.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -package watch - -type FileChanges struct { - Modified chan bool // Channel to get notified of modifications - Truncated chan bool // Channel to get notified of truncations - Deleted chan bool // Channel to get notified of deletions/renames -} - -func NewFileChanges() *FileChanges { - return &FileChanges{ - make(chan bool, 1), make(chan bool, 1), make(chan bool, 1)} -} - -func (fc *FileChanges) NotifyModified() { - sendOnlyIfEmpty(fc.Modified) -} - -func (fc *FileChanges) NotifyTruncated() { - sendOnlyIfEmpty(fc.Truncated) -} - -func (fc *FileChanges) NotifyDeleted() { - sendOnlyIfEmpty(fc.Deleted) -} - -// sendOnlyIfEmpty sends on a bool channel only if the channel has no -// backlog to be read by other goroutines. This concurrency pattern -// can be used to notify other goroutines if and only if they are -// looking for it (i.e., subsequent notifications can be compressed -// into one). -func sendOnlyIfEmpty(ch chan bool) { - select { - case ch <- true: - default: - } -} diff --git a/vendor/github.com/nxadm/tail/watch/inotify.go b/vendor/github.com/nxadm/tail/watch/inotify.go deleted file mode 100644 index cbd11ad8d03..00000000000 --- a/vendor/github.com/nxadm/tail/watch/inotify.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -package watch - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/nxadm/tail/util" - - "github.com/fsnotify/fsnotify" - "gopkg.in/tomb.v1" -) - -// InotifyFileWatcher uses inotify to monitor file changes. -type InotifyFileWatcher struct { - Filename string - Size int64 -} - -func NewInotifyFileWatcher(filename string) *InotifyFileWatcher { - fw := &InotifyFileWatcher{filepath.Clean(filename), 0} - return fw -} - -func (fw *InotifyFileWatcher) BlockUntilExists(t *tomb.Tomb) error { - err := WatchCreate(fw.Filename) - if err != nil { - return err - } - defer RemoveWatchCreate(fw.Filename) - - // Do a real check now as the file might have been created before - // calling `WatchFlags` above. - if _, err = os.Stat(fw.Filename); !os.IsNotExist(err) { - // file exists, or stat returned an error. - return err - } - - events := Events(fw.Filename) - - for { - select { - case evt, ok := <-events: - if !ok { - return fmt.Errorf("inotify watcher has been closed") - } - evtName, err := filepath.Abs(evt.Name) - if err != nil { - return err - } - fwFilename, err := filepath.Abs(fw.Filename) - if err != nil { - return err - } - if evtName == fwFilename { - return nil - } - case <-t.Dying(): - return tomb.ErrDying - } - } - panic("unreachable") -} - -func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChanges, error) { - err := Watch(fw.Filename) - if err != nil { - return nil, err - } - - changes := NewFileChanges() - fw.Size = pos - - go func() { - - events := Events(fw.Filename) - - for { - prevSize := fw.Size - - var evt fsnotify.Event - var ok bool - - select { - case evt, ok = <-events: - if !ok { - RemoveWatch(fw.Filename) - return - } - case <-t.Dying(): - RemoveWatch(fw.Filename) - return - } - - switch { - case evt.Op&fsnotify.Remove == fsnotify.Remove: - fallthrough - - case evt.Op&fsnotify.Rename == fsnotify.Rename: - RemoveWatch(fw.Filename) - changes.NotifyDeleted() - return - - //With an open fd, unlink(fd) - inotify returns IN_ATTRIB (==fsnotify.Chmod) - case evt.Op&fsnotify.Chmod == fsnotify.Chmod: - fallthrough - - case evt.Op&fsnotify.Write == fsnotify.Write: - fi, err := os.Stat(fw.Filename) - if err != nil { - if os.IsNotExist(err) { - RemoveWatch(fw.Filename) - changes.NotifyDeleted() - return - } - // XXX: report this error back to the user - util.Fatal("Failed to stat file %v: %v", fw.Filename, err) - } - fw.Size = fi.Size() - - if prevSize > 0 && prevSize > fw.Size { - changes.NotifyTruncated() - } else { - changes.NotifyModified() - } - prevSize = fw.Size - } - } - }() - - return changes, nil -} diff --git a/vendor/github.com/nxadm/tail/watch/inotify_tracker.go b/vendor/github.com/nxadm/tail/watch/inotify_tracker.go deleted file mode 100644 index cb9572a0302..00000000000 --- a/vendor/github.com/nxadm/tail/watch/inotify_tracker.go +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -package watch - -import ( - "log" - "os" - "path/filepath" - "sync" - "syscall" - - "github.com/nxadm/tail/util" - - "github.com/fsnotify/fsnotify" -) - -type InotifyTracker struct { - mux sync.Mutex - watcher *fsnotify.Watcher - chans map[string]chan fsnotify.Event - done map[string]chan bool - watchNums map[string]int - watch chan *watchInfo - remove chan *watchInfo - error chan error -} - -type watchInfo struct { - op fsnotify.Op - fname string -} - -func (this *watchInfo) isCreate() bool { - return this.op == fsnotify.Create -} - -var ( - // globally shared InotifyTracker; ensures only one fsnotify.Watcher is used - shared *InotifyTracker - - // these are used to ensure the shared InotifyTracker is run exactly once - once = sync.Once{} - goRun = func() { - shared = &InotifyTracker{ - mux: sync.Mutex{}, - chans: make(map[string]chan fsnotify.Event), - done: make(map[string]chan bool), - watchNums: make(map[string]int), - watch: make(chan *watchInfo), - remove: make(chan *watchInfo), - error: make(chan error), - } - go shared.run() - } - - logger = log.New(os.Stderr, "", log.LstdFlags) -) - -// Watch signals the run goroutine to begin watching the input filename -func Watch(fname string) error { - return watch(&watchInfo{ - fname: fname, - }) -} - -// Watch create signals the run goroutine to begin watching the input filename -// if call the WatchCreate function, don't call the Cleanup, call the RemoveWatchCreate -func WatchCreate(fname string) error { - return watch(&watchInfo{ - op: fsnotify.Create, - fname: fname, - }) -} - -func watch(winfo *watchInfo) error { - // start running the shared InotifyTracker if not already running - once.Do(goRun) - - winfo.fname = filepath.Clean(winfo.fname) - shared.watch <- winfo - return <-shared.error -} - -// RemoveWatch signals the run goroutine to remove the watch for the input filename -func RemoveWatch(fname string) error { - return remove(&watchInfo{ - fname: fname, - }) -} - -// RemoveWatch create signals the run goroutine to remove the watch for the input filename -func RemoveWatchCreate(fname string) error { - return remove(&watchInfo{ - op: fsnotify.Create, - fname: fname, - }) -} - -func remove(winfo *watchInfo) error { - // start running the shared InotifyTracker if not already running - once.Do(goRun) - - winfo.fname = filepath.Clean(winfo.fname) - shared.mux.Lock() - done := shared.done[winfo.fname] - if done != nil { - delete(shared.done, winfo.fname) - close(done) - } - shared.mux.Unlock() - - shared.remove <- winfo - return <-shared.error -} - -// Events returns a channel to which FileEvents corresponding to the input filename -// will be sent. This channel will be closed when removeWatch is called on this -// filename. -func Events(fname string) <-chan fsnotify.Event { - shared.mux.Lock() - defer shared.mux.Unlock() - - return shared.chans[fname] -} - -// Cleanup removes the watch for the input filename if necessary. -func Cleanup(fname string) error { - return RemoveWatch(fname) -} - -// watchFlags calls fsnotify.WatchFlags for the input filename and flags, creating -// a new Watcher if the previous Watcher was closed. -func (shared *InotifyTracker) addWatch(winfo *watchInfo) error { - shared.mux.Lock() - defer shared.mux.Unlock() - - if shared.chans[winfo.fname] == nil { - shared.chans[winfo.fname] = make(chan fsnotify.Event) - } - if shared.done[winfo.fname] == nil { - shared.done[winfo.fname] = make(chan bool) - } - - fname := winfo.fname - if winfo.isCreate() { - // Watch for new files to be created in the parent directory. - fname = filepath.Dir(fname) - } - - var err error - // already in inotify watch - if shared.watchNums[fname] == 0 { - err = shared.watcher.Add(fname) - } - if err == nil { - shared.watchNums[fname]++ - } - return err -} - -// removeWatch calls fsnotify.RemoveWatch for the input filename and closes the -// corresponding events channel. -func (shared *InotifyTracker) removeWatch(winfo *watchInfo) error { - shared.mux.Lock() - - ch := shared.chans[winfo.fname] - if ch != nil { - delete(shared.chans, winfo.fname) - close(ch) - } - - fname := winfo.fname - if winfo.isCreate() { - // Watch for new files to be created in the parent directory. - fname = filepath.Dir(fname) - } - shared.watchNums[fname]-- - watchNum := shared.watchNums[fname] - if watchNum == 0 { - delete(shared.watchNums, fname) - } - shared.mux.Unlock() - - var err error - // If we were the last ones to watch this file, unsubscribe from inotify. - // This needs to happen after releasing the lock because fsnotify waits - // synchronously for the kernel to acknowledge the removal of the watch - // for this file, which causes us to deadlock if we still held the lock. - if watchNum == 0 { - err = shared.watcher.Remove(fname) - } - - return err -} - -// sendEvent sends the input event to the appropriate Tail. -func (shared *InotifyTracker) sendEvent(event fsnotify.Event) { - name := filepath.Clean(event.Name) - - shared.mux.Lock() - ch := shared.chans[name] - done := shared.done[name] - shared.mux.Unlock() - - if ch != nil && done != nil { - select { - case ch <- event: - case <-done: - } - } -} - -// run starts the goroutine in which the shared struct reads events from its -// Watcher's Event channel and sends the events to the appropriate Tail. -func (shared *InotifyTracker) run() { - watcher, err := fsnotify.NewWatcher() - if err != nil { - util.Fatal("failed to create Watcher") - } - shared.watcher = watcher - - for { - select { - case winfo := <-shared.watch: - shared.error <- shared.addWatch(winfo) - - case winfo := <-shared.remove: - shared.error <- shared.removeWatch(winfo) - - case event, open := <-shared.watcher.Events: - if !open { - return - } - shared.sendEvent(event) - - case err, open := <-shared.watcher.Errors: - if !open { - return - } else if err != nil { - sysErr, ok := err.(*os.SyscallError) - if !ok || sysErr.Err != syscall.EINTR { - logger.Printf("Error in Watcher Error channel: %s", err) - } - } - } - } -} diff --git a/vendor/github.com/nxadm/tail/watch/polling.go b/vendor/github.com/nxadm/tail/watch/polling.go deleted file mode 100644 index 74e10aa427c..00000000000 --- a/vendor/github.com/nxadm/tail/watch/polling.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -package watch - -import ( - "os" - "runtime" - "time" - - "github.com/nxadm/tail/util" - "gopkg.in/tomb.v1" -) - -// PollingFileWatcher polls the file for changes. -type PollingFileWatcher struct { - Filename string - Size int64 -} - -func NewPollingFileWatcher(filename string) *PollingFileWatcher { - fw := &PollingFileWatcher{filename, 0} - return fw -} - -var POLL_DURATION time.Duration - -func (fw *PollingFileWatcher) BlockUntilExists(t *tomb.Tomb) error { - for { - if _, err := os.Stat(fw.Filename); err == nil { - return nil - } else if !os.IsNotExist(err) { - return err - } - select { - case <-time.After(POLL_DURATION): - continue - case <-t.Dying(): - return tomb.ErrDying - } - } - panic("unreachable") -} - -func (fw *PollingFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChanges, error) { - origFi, err := os.Stat(fw.Filename) - if err != nil { - return nil, err - } - - changes := NewFileChanges() - var prevModTime time.Time - - // XXX: use tomb.Tomb to cleanly manage these goroutines. replace - // the fatal (below) with tomb's Kill. - - fw.Size = pos - - go func() { - prevSize := fw.Size - for { - select { - case <-t.Dying(): - return - default: - } - - time.Sleep(POLL_DURATION) - fi, err := os.Stat(fw.Filename) - if err != nil { - // Windows cannot delete a file if a handle is still open (tail keeps one open) - // so it gives access denied to anything trying to read it until all handles are released. - if os.IsNotExist(err) || (runtime.GOOS == "windows" && os.IsPermission(err)) { - // File does not exist (has been deleted). - changes.NotifyDeleted() - return - } - - // XXX: report this error back to the user - util.Fatal("Failed to stat file %v: %v", fw.Filename, err) - } - - // File got moved/renamed? - if !os.SameFile(origFi, fi) { - changes.NotifyDeleted() - return - } - - // File got truncated? - fw.Size = fi.Size() - if prevSize > 0 && prevSize > fw.Size { - changes.NotifyTruncated() - prevSize = fw.Size - continue - } - // File got bigger? - if prevSize > 0 && prevSize < fw.Size { - changes.NotifyModified() - prevSize = fw.Size - continue - } - prevSize = fw.Size - - // File was appended to (changed)? - modTime := fi.ModTime() - if modTime != prevModTime { - prevModTime = modTime - changes.NotifyModified() - } - } - }() - - return changes, nil -} - -func init() { - POLL_DURATION = 250 * time.Millisecond -} diff --git a/vendor/github.com/nxadm/tail/watch/watch.go b/vendor/github.com/nxadm/tail/watch/watch.go deleted file mode 100644 index 2b5112805a1..00000000000 --- a/vendor/github.com/nxadm/tail/watch/watch.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// Copyright (c) 2015 HPE Software Inc. All rights reserved. -// Copyright (c) 2013 ActiveState Software Inc. All rights reserved. - -package watch - -import "gopkg.in/tomb.v1" - -// FileWatcher monitors file-level events. -type FileWatcher interface { - // BlockUntilExists blocks until the file comes into existence. - BlockUntilExists(*tomb.Tomb) error - - // ChangeEvents reports on changes to a file, be it modification, - // deletion, renames or truncations. Returned FileChanges group of - // channels will be closed, thus become unusable, after a deletion - // or truncation event. - // In order to properly report truncations, ChangeEvents requires - // the caller to pass their current offset in the file. - ChangeEvents(*tomb.Tomb, int64) (*FileChanges, error) -} diff --git a/vendor/github.com/nxadm/tail/winfile/winfile.go b/vendor/github.com/nxadm/tail/winfile/winfile.go deleted file mode 100644 index 4562ac7c25c..00000000000 --- a/vendor/github.com/nxadm/tail/winfile/winfile.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail -// +build windows - -package winfile - -import ( - "os" - "syscall" - "unsafe" -) - -// issue also described here -//https://codereview.appspot.com/8203043/ - -// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L218 -func Open(path string, mode int, perm uint32) (fd syscall.Handle, err error) { - if len(path) == 0 { - return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND - } - pathp, err := syscall.UTF16PtrFromString(path) - if err != nil { - return syscall.InvalidHandle, err - } - var access uint32 - switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) { - case syscall.O_RDONLY: - access = syscall.GENERIC_READ - case syscall.O_WRONLY: - access = syscall.GENERIC_WRITE - case syscall.O_RDWR: - access = syscall.GENERIC_READ | syscall.GENERIC_WRITE - } - if mode&syscall.O_CREAT != 0 { - access |= syscall.GENERIC_WRITE - } - if mode&syscall.O_APPEND != 0 { - access &^= syscall.GENERIC_WRITE - access |= syscall.FILE_APPEND_DATA - } - sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_DELETE) - var sa *syscall.SecurityAttributes - if mode&syscall.O_CLOEXEC == 0 { - sa = makeInheritSa() - } - var createmode uint32 - switch { - case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL): - createmode = syscall.CREATE_NEW - case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC): - createmode = syscall.CREATE_ALWAYS - case mode&syscall.O_CREAT == syscall.O_CREAT: - createmode = syscall.OPEN_ALWAYS - case mode&syscall.O_TRUNC == syscall.O_TRUNC: - createmode = syscall.TRUNCATE_EXISTING - default: - createmode = syscall.OPEN_EXISTING - } - h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, syscall.FILE_ATTRIBUTE_NORMAL, 0) - return h, e -} - -// https://github.com/jnwhiteh/golang/blob/master/src/pkg/syscall/syscall_windows.go#L211 -func makeInheritSa() *syscall.SecurityAttributes { - var sa syscall.SecurityAttributes - sa.Length = uint32(unsafe.Sizeof(sa)) - sa.InheritHandle = 1 - return &sa -} - -// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_windows.go#L133 -func OpenFile(name string, flag int, perm os.FileMode) (file *os.File, err error) { - r, e := Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm)) - if e != nil { - return nil, e - } - return os.NewFile(uintptr(r), name), nil -} - -// https://github.com/jnwhiteh/golang/blob/master/src/pkg/os/file_posix.go#L61 -func syscallMode(i os.FileMode) (o uint32) { - o |= uint32(i.Perm()) - if i&os.ModeSetuid != 0 { - o |= syscall.S_ISUID - } - if i&os.ModeSetgid != 0 { - o |= syscall.S_ISGID - } - if i&os.ModeSticky != 0 { - o |= syscall.S_ISVTX - } - // No mapping for Go's ModeTemporary (plan9 only). - return -} diff --git a/vendor/github.com/onsi/ginkgo/.gitignore b/vendor/github.com/onsi/ginkgo/.gitignore deleted file mode 100644 index b9f9659d29a..00000000000 --- a/vendor/github.com/onsi/ginkgo/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.DS_Store -TODO -tmp/**/* -*.coverprofile -.vscode -.idea/ -*.log diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml deleted file mode 100644 index ea0966d5bd6..00000000000 --- a/vendor/github.com/onsi/ginkgo/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: go -go: - - tip - - 1.16.x - - 1.15.x - -cache: - directories: - - $GOPATH/pkg/mod - -# allow internal package imports, necessary for forked repositories -go_import_path: github.com/onsi/ginkgo - -install: - - GO111MODULE="off" go get -v -t ./... - - GO111MODULE="off" go get golang.org/x/tools/cmd/cover - - GO111MODULE="off" go get github.com/onsi/gomega - - GO111MODULE="off" go install github.com/onsi/ginkgo/ginkgo - - export PATH=$GOPATH/bin:$PATH - -script: - - GO111MODULE="on" go mod tidy && git diff --exit-code go.mod go.sum - - go vet - - ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md deleted file mode 100644 index a26bc530f1c..00000000000 --- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md +++ /dev/null @@ -1,393 +0,0 @@ -## 1.16.5 - -Ginkgo 2.0 now has a Release Candidate. 1.16.5 advertises the existence of the RC. -1.16.5 deprecates GinkgoParallelNode in favor of GinkgoParallelProcess - -You can silence the RC advertisement by setting an `ACK_GINKG_RC=true` environment variable or creating a file in your home directory called `.ack-ginkgo-rc` - -## 1.16.4 - -### Fixes -1.16.4 retracts 1.16.3. There are no code changes. The 1.16.3 tag was associated with the wrong commit and an attempt to change it after-the-fact has proven problematic. 1.16.4 retracts 1.16.3 in Ginkgo's go.mod and creates a new, correctly tagged, release. - -## 1.16.3 - -### Features -- Measure is now deprecated and emits a deprecation warning. - -## 1.16.2 - -### Fixes -- Deprecations can be suppressed by setting an `ACK_GINKGO_DEPRECATIONS=` environment variable. - -## 1.16.1 - -### Fixes -- Supress --stream deprecation warning on windows (#793) - -## 1.16.0 - -### Features -- Advertise Ginkgo 2.0. Introduce deprecations. [9ef1913] - - Update README.md to advertise that Ginkgo 2.0 is coming. - - Backport the 2.0 DeprecationTracker and start alerting users - about upcoming deprecations. - -- Add slim-sprig template functions to bootstrap/generate (#775) [9162b86] - -### Fixes -- Fix accidental reference to 1488 (#784) [9fb7fe4] - -## 1.15.2 - -### Fixes -- ignore blank `-focus` and `-skip` flags (#780) [e90a4a0] - -## 1.15.1 - -### Fixes -- reporters/junit: Use `system-out` element instead of `passed` (#769) [9eda305] - -## 1.15.0 - -### Features -- Adds 'outline' command to print the outline of specs/containers in a file (#754) [071c369] [6803cc3] [935b538] [06744e8] [0c40583] -- Add support for using template to generate tests (#752) [efb9e69] -- Add a Chinese Doc #755 (#756) [5207632] -- cli: allow multiple -focus and -skip flags (#736) [9a782fb] - -### Fixes -- Add _internal to filename of tests created with internal flag (#751) [43c12da] - -## 1.14.2 - -### Fixes -- correct handling windows backslash in import path (#721) [97f3d51] -- Add additional methods to GinkgoT() to improve compatibility with the testing.TB interface [b5fe44d] - -## 1.14.1 - -### Fixes -- Discard exported method declaration when running ginkgo bootstrap (#558) [f4b0240] - -## 1.14.0 - -### Features -- Defer running top-level container nodes until RunSpecs is called [d44dedf] -- [Document Ginkgo lifecycle](http://onsi.github.io/ginkgo/#understanding-ginkgos-lifecycle) -- Add `extensions/globals` package (#692) [3295c8f] - this can be helpful in contexts where you are test-driving your test-generation code (see [#692](https://github.com/onsi/ginkgo/pull/692)) -- Print Skip reason in JUnit reporter if one was provided [820dfab] - -## 1.13.0 - -### Features -- Add a version of table.Entry that allows dumping the entry parameters. (#689) [21eaef2] - -### Fixes -- Ensure integration tests pass in an environment sans GOPATH [606fba2] -- Add books package (#568) [fc0e44e] -- doc(readme): installation via "tools package" (#677) [83bb20e] -- Solve the undefined: unix.Dup2 compile error on mips64le (#680) [0624f75] -- Import package without dot (#687) [6321024] -- Fix integration tests to stop require GOPATH (#686) [a912ec5] - -## 1.12.3 - -### Fixes -- Print correct code location of failing table test (#666) [c6d7afb] - -## 1.12.2 - -### Fixes -- Update dependencies [ea4a036] - -## 1.12.1 - -### Fixes -- Make unfocus ("blur") much faster (#674) [8b18061] -- Fix typo (#673) [7fdcbe8] -- Test against 1.14 and remove 1.12 [d5c2ad6] -- Test if a coverprofile content is empty before checking its latest character (#670) [14d9fa2] -- replace tail package with maintained one. this fixes go get errors (#667) [4ba33d4] -- improve ginkgo performance - makes progress on #644 [a14f98e] -- fix convert integration tests [1f8ba69] -- fix typo succesful -> successful (#663) [1ea49cf] -- Fix invalid link (#658) [b886136] -- convert utility : Include comments from source (#657) [1077c6d] -- Explain what BDD means [d79e7fb] -- skip race detector test on unsupported platform (#642) [f8ab89d] -- Use Dup2 from golang.org/x/sys/unix instead of syscallDup (#638) [5d53c55] -- Fix missing newline in combined coverage file (#641) [6a07ea2] -- check if a spec is run before returning SpecSummary (#645) [8850000] - -## 1.12.0 - -### Features -- Add module definition (#630) [78916ab] - -## 1.11.0 - -### Features -- Add syscall for riscv64 architecture [f66e896] -- teamcity reporter: output location of test failure as well as test definition (#626) [9869142] -- teamcity reporter: output newline after every service message (#625) [3cfa02d] -- Add support for go module when running `generate` command (#578) [9c89e3f] - -## 1.10.3 - -### Fixes -- Set go_import_path in travis.yml to allow internal packages in forks (#607) [3b721db] -- Add integration test [d90e0dc] -- Fix coverage files combining [e5dde8c] -- A new CLI option: -ginkgo.reportFile (#601) [034fd25] - -## 1.10.2 - -### Fixes -- speed up table entry generateIt() (#609) [5049dc5] -- Fix. Write errors to stderr instead of stdout (#610) [7bb3091] - -## 1.10.1 - -### Fixes -- stack backtrace: fix skipping (#600) [2a4c0bd] - -## 1.10.0 - -### Fixes -- stack backtrace: fix alignment and skipping [66915d6] -- fix typo in documentation [8f97b93] - -## 1.9.0 - -### Features -- Option to print output into report, when tests have passed [0545415] - -### Fixes -- Fixed typos in comments [0ecbc58] -- gofmt code [a7f8bfb] -- Simplify code [7454d00] -- Simplify concatenation, incrementation and function assignment [4825557] -- Avoid unnecessary conversions [9d9403c] -- JUnit: include more detailed information about panic [19cca4b] -- Print help to stdout when the user asks for help [4cb7441] - - -## 1.8.0 - -### New Features -- allow config of the vet flag for `go test` (#562) [3cd45fa] -- Support projects using go modules [d56ee76] - -### Fixes and Minor Improvements -- chore(godoc): fixes typos in Measurement funcs [dbaca8e] -- Optimize focus to avoid allocations [f493786] -- Ensure generated test file names are underscored [505cc35] - -## 1.7.0 - -### New Features -- Add JustAfterEach (#484) [0d4f080] - -### Fixes -- Correctly round suite time in junit reporter [2445fc1] -- Avoid using -i argument to go test for Golang 1.10+ [46bbc26] - -## 1.6.0 - -### New Features -- add --debug flag to emit node output to files (#499) [39febac] - -### Fixes -- fix: for `go vet` to pass [69338ec] -- docs: fix for contributing instructions [7004cb1] -- consolidate and streamline contribution docs (#494) [d848015] -- Make generated Junit file compatable with "Maven Surefire" (#488) [e51bee6] -- all: gofmt [000d317] -- Increase eventually timeout to 30s [c73579c] -- Clarify asynchronous test behaviour [294d8f4] -- Travis badge should only show master [26d2143] - -## 1.5.0 5/10/2018 - -### New Features -- Supports go v1.10 (#443, #446, #451) [e873237, 468e89e, e37dbfe, a37f4c0, c0b857d, bca5260, 4177ca8] -- Add a When() synonym for Context() (#386) [747514b, 7484dad, 7354a07, dd826c8] -- Re-add noisySkippings flag [652e15c] -- Allow coverage to be displayed for focused specs (#367) [11459a8] -- Handle -outputdir flag (#364) [228e3a8] -- Handle -coverprofile flag (#355) [43392d5] - -### Fixes -- When using custom reporters register the custom reporters *before* the default reporter. This allows users to see the output of any print statements in their customer reporters. (#365) [8382b23] -- When running a test and calculating the coverage using the `-coverprofile` and `-outputdir` flags, Ginkgo fails with an error if the directory does not exist. This is due to an [issue in go 1.10](https://github.com/golang/go/issues/24588) (#446) [b36a6e0] -- `unfocus` command ignores vendor folder (#459) [e5e551c, c556e43, a3b6351, 9a820dd] -- Ignore packages whose tests are all ignored by go (#456) [7430ca7, 6d8be98] -- Increase the threshold when checking time measuments (#455) [2f714bf, 68f622c] -- Fix race condition in coverage tests (#423) [a5a8ff7, ab9c08b] -- Add an extra new line after reporting spec run completion for test2json [874520d] -- added name name field to junit reported testsuite [ae61c63] -- Do not set the run time of a spec when the dryRun flag is used (#438) [457e2d9, ba8e856] -- Process FWhen and FSpecify when unfocusing (#434) [9008c7b, ee65bd, df87dfe] -- Synchronise the access to the state of specs to avoid race conditions (#430) [7d481bc, ae6829d] -- Added Duration on GinkgoTestDescription (#383) [5f49dad, 528417e, 0747408, 329d7ed] -- Fix Ginkgo stack trace on failure for Specify (#415) [b977ede, 65ca40e, 6c46eb8] -- Update README with Go 1.6+, Golang -> Go (#409) [17f6b97, bc14b66, 20d1598] -- Use fmt.Errorf instead of errors.New(fmt.Sprintf (#401) [a299f56, 44e2eaa] -- Imports in generated code should follow conventions (#398) [0bec0b0, e8536d8] -- Prevent data race error when Recording a benchmark value from multiple go routines (#390) [c0c4881, 7a241e9] -- Replace GOPATH in Environment [4b883f0] - - -## 1.4.0 7/16/2017 - -- `ginkgo` now provides a hint if you accidentally forget to run `ginkgo bootstrap` to generate a `*_suite_test.go` file that actually invokes the Ginkgo test runner. [#345](https://github.com/onsi/ginkgo/pull/345) -- thanks to improvements in `go test -c` `ginkgo` no longer needs to fix Go's compilation output to ensure compilation errors are expressed relative to the CWD. [#357] -- `ginkgo watch -watchRegExp=...` allows you to specify a custom regular expression to watch. Only files matching the regular expression are watched for changes (the default is `\.go$`) [#356] -- `ginkgo` now always emits compilation output. Previously, only failed compilation output was printed out. [#277] -- `ginkgo -requireSuite` now fails the test run if there are `*_test.go` files but `go test` fails to detect any tests. Typically this means you forgot to run `ginkgo bootstrap` to generate a suite file. [#344] -- `ginkgo -timeout=DURATION` allows you to adjust the timeout for the entire test suite (default is 24 hours) [#248] - -## 1.3.0 3/28/2017 - -Improvements: - -- Significantly improved parallel test distribution. Now instead of pre-sharding test cases across workers (which can result in idle workers and poor test performance) Ginkgo uses a shared queue to keep all workers busy until all tests are complete. This improves test-time performance and consistency. -- `Skip(message)` can be used to skip the current test. -- Added `extensions/table` - a Ginkgo DSL for [Table Driven Tests](http://onsi.github.io/ginkgo/#table-driven-tests) -- Add `GinkgoRandomSeed()` - shorthand for `config.GinkgoConfig.RandomSeed` -- Support for retrying flaky tests with `--flakeAttempts` -- `ginkgo ./...` now recurses as you'd expect -- Added `Specify` a synonym for `It` -- Support colorise on Windows -- Broader support for various go compilation flags in the `ginkgo` CLI - -Bug Fixes: - -- Ginkgo tests now fail when you `panic(nil)` (#167) - -## 1.2.0 5/31/2015 - -Improvements - -- `ginkgo -coverpkg` calls down to `go test -coverpkg` (#160) -- `ginkgo -afterSuiteHook COMMAND` invokes the passed-in `COMMAND` after a test suite completes (#152) -- Relaxed requirement for Go 1.4+. `ginkgo` now works with Go v1.3+ (#166) - -## 1.2.0-beta - -Ginkgo now requires Go 1.4+ - -Improvements: - -- Call reporters in reverse order when announcing spec completion -- allows custom reporters to emit output before the default reporter does. -- Improved focus behavior. Now, this: - - ```golang - FDescribe("Some describe", func() { - It("A", func() {}) - - FIt("B", func() {}) - }) - ``` - - will run `B` but *not* `A`. This tends to be a common usage pattern when in the thick of writing and debugging tests. -- When `SIGINT` is received, Ginkgo will emit the contents of the `GinkgoWriter` before running the `AfterSuite`. Useful for debugging stuck tests. -- When `--progress` is set, Ginkgo will write test progress (in particular, Ginkgo will say when it is about to run a BeforeEach, AfterEach, It, etc...) to the `GinkgoWriter`. This is useful for debugging stuck tests and tests that generate many logs. -- Improved output when an error occurs in a setup or teardown block. -- When `--dryRun` is set, Ginkgo will walk the spec tree and emit to its reporter *without* actually running anything. Best paired with `-v` to understand which specs will run in which order. -- Add `By` to help document long `It`s. `By` simply writes to the `GinkgoWriter`. -- Add support for precompiled tests: - - `ginkgo build ` will now compile the package, producing a file named `package.test` - - The compiled `package.test` file can be run directly. This runs the tests in series. - - To run precompiled tests in parallel, you can run: `ginkgo -p package.test` -- Support `bootstrap`ping and `generate`ing [Agouti](http://agouti.org) specs. -- `ginkgo generate` and `ginkgo bootstrap` now honor the package name already defined in a given directory -- The `ginkgo` CLI ignores `SIGQUIT`. Prevents its stack dump from interlacing with the underlying test suite's stack dump. -- The `ginkgo` CLI now compiles tests into a temporary directory instead of the package directory. This necessitates upgrading to Go v1.4+. -- `ginkgo -notify` now works on Linux - -Bug Fixes: - -- If --skipPackages is used and all packages are skipped, Ginkgo should exit 0. -- Fix tempfile leak when running in parallel -- Fix incorrect failure message when a panic occurs during a parallel test run -- Fixed an issue where a pending test within a focused context (or a focused test within a pending context) would skip all other tests. -- Be more consistent about handling SIGTERM as well as SIGINT -- When interupted while concurrently compiling test suites in the background, Ginkgo now cleans up the compiled artifacts. -- Fixed a long standing bug where `ginkgo -p` would hang if a process spawned by one of the Ginkgo parallel nodes does not exit. (Hooray!) - -## 1.1.0 (8/2/2014) - -No changes, just dropping the beta. - -## 1.1.0-beta (7/22/2014) -New Features: - -- `ginkgo watch` now monitors packages *and their dependencies* for changes. The depth of the dependency tree can be modified with the `-depth` flag. -- Test suites with a programmatic focus (`FIt`, `FDescribe`, etc...) exit with non-zero status code, even when they pass. This allows CI systems to detect accidental commits of focused test suites. -- `ginkgo -p` runs the testsuite in parallel with an auto-detected number of nodes. -- `ginkgo -tags=TAG_LIST` passes a list of tags down to the `go build` command. -- `ginkgo --failFast` aborts the test suite after the first failure. -- `ginkgo generate file_1 file_2` can take multiple file arguments. -- Ginkgo now summarizes any spec failures that occurred at the end of the test run. -- `ginkgo --randomizeSuites` will run tests *suites* in random order using the generated/passed-in seed. - -Improvements: - -- `ginkgo -skipPackage` now takes a comma-separated list of strings. If the *relative path* to a package matches one of the entries in the comma-separated list, that package is skipped. -- `ginkgo --untilItFails` no longer recompiles between attempts. -- Ginkgo now panics when a runnable node (`It`, `BeforeEach`, `JustBeforeEach`, `AfterEach`, `Measure`) is nested within another runnable node. This is always a mistake. Any test suites that panic because of this change should be fixed. - -Bug Fixes: - -- `ginkgo boostrap` and `ginkgo generate` no longer fail when dealing with `hyphen-separated-packages`. -- parallel specs are now better distributed across nodes - fixed a crashing bug where (for example) distributing 11 tests across 7 nodes would panic - -## 1.0.0 (5/24/2014) -New Features: - -- Add `GinkgoParallelNode()` - shorthand for `config.GinkgoConfig.ParallelNode` - -Improvements: - -- When compilation fails, the compilation output is rewritten to present a correct *relative* path. Allows ⌘-clicking in iTerm open the file in your text editor. -- `--untilItFails` and `ginkgo watch` now generate new random seeds between test runs, unless a particular random seed is specified. - -Bug Fixes: - -- `-cover` now generates a correctly combined coverprofile when running with in parallel with multiple `-node`s. -- Print out the contents of the `GinkgoWriter` when `BeforeSuite` or `AfterSuite` fail. -- Fix all remaining race conditions in Ginkgo's test suite. - -## 1.0.0-beta (4/14/2014) -Breaking changes: - -- `thirdparty/gomocktestreporter` is gone. Use `GinkgoT()` instead -- Modified the Reporter interface -- `watch` is now a subcommand, not a flag. - -DSL changes: - -- `BeforeSuite` and `AfterSuite` for setting up and tearing down test suites. -- `AfterSuite` is triggered on interrupt (`^C`) as well as exit. -- `SynchronizedBeforeSuite` and `SynchronizedAfterSuite` for setting up and tearing down singleton resources across parallel nodes. - -CLI changes: - -- `watch` is now a subcommand, not a flag -- `--nodot` flag can be passed to `ginkgo generate` and `ginkgo bootstrap` to avoid dot imports. This explicitly imports all exported identifiers in Ginkgo and Gomega. Refreshing this list can be done by running `ginkgo nodot` -- Additional arguments can be passed to specs. Pass them after the `--` separator -- `--skipPackage` flag takes a regexp and ignores any packages with package names passing said regexp. -- `--trace` flag prints out full stack traces when errors occur, not just the line at which the error occurs. - -Misc: - -- Start using semantic versioning -- Start maintaining changelog - -Major refactor: - -- Pull out Ginkgo's internal to `internal` -- Rename `example` everywhere to `spec` -- Much more! diff --git a/vendor/github.com/onsi/ginkgo/CONTRIBUTING.md b/vendor/github.com/onsi/ginkgo/CONTRIBUTING.md deleted file mode 100644 index 908b95c2c12..00000000000 --- a/vendor/github.com/onsi/ginkgo/CONTRIBUTING.md +++ /dev/null @@ -1,33 +0,0 @@ -# Contributing to Ginkgo - -Your contributions to Ginkgo are essential for its long-term maintenance and improvement. - -- Please **open an issue first** - describe what problem you are trying to solve and give the community a forum for input and feedback ahead of investing time in writing code! -- Ensure adequate test coverage: - - When adding to the Ginkgo library, add unit and/or integration tests (under the `integration` folder). - - When adding to the Ginkgo CLI, note that there are very few unit tests. Please add an integration test. -- Update the documentation. Ginko uses `godoc` comments and documentation on the `gh-pages` branch. - If relevant, please submit a docs PR to that branch alongside your code PR. - -Thanks for supporting Ginkgo! - -## Setup - -Fork the repo, then: - -``` -go get github.com/onsi/ginkgo -go get github.com/onsi/gomega/... -cd $GOPATH/src/github.com/onsi/ginkgo -git remote add fork git@github.com:/ginkgo.git - -ginkgo -r -p # ensure tests are green -go vet ./... # ensure linter is happy -``` - -## Making the PR - - go to a new branch `git checkout -b my-feature` - - make your changes - - run tests and linter again (see above) - - `git push fork` - - open PR 🎉 diff --git a/vendor/github.com/onsi/ginkgo/LICENSE b/vendor/github.com/onsi/ginkgo/LICENSE deleted file mode 100644 index 9415ee72c17..00000000000 --- a/vendor/github.com/onsi/ginkgo/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2013-2014 Onsi Fakhouri - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/onsi/ginkgo/README.md b/vendor/github.com/onsi/ginkgo/README.md deleted file mode 100644 index a25ca5e03a4..00000000000 --- a/vendor/github.com/onsi/ginkgo/README.md +++ /dev/null @@ -1,169 +0,0 @@ -![Ginkgo: A Go BDD Testing Framework](https://onsi.github.io/ginkgo/images/ginkgo.png) - -[![test](https://github.com/onsi/ginkgo/workflows/test/badge.svg?branch=master)](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) - -Jump to the [docs](https://onsi.github.io/ginkgo/) | [中文文档](https://ke-chain.github.io/ginkgodoc) to learn more. To start rolling your Ginkgo tests *now* [keep reading](#set-me-up)! - -If you have a question, comment, bug report, feature request, etc. please open a GitHub issue, or visit the [Ginkgo Slack channel](https://app.slack.com/client/T029RQSE6/CQQ50BBNW). - -# Ginkgo 2.0 Release Candidate is available! - -An effort is underway to develop and deliver Ginkgo 2.0. The work is happening in the [ver2](https://github.com/onsi/ginkgo/tree/ver2) branch and a changelog and migration guide is being maintained on that branch [here](https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md). Issue [#711](https://github.com/onsi/ginkgo/issues/711) is the central place for discussion. - -As described in the [changelog](https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md) and [proposal](https://docs.google.com/document/d/1h28ZknXRsTLPNNiOjdHIO-F2toCzq4xoZDXbfYaBdoQ/edit#), Ginkgo 2.0 will clean up the Ginkgo codebase, deprecate and remove some v1 functionality, and add several new much-requested features. To help users get ready for the migration, Ginkgo v1 has started emitting deprecation warnings for features that will no longer be supported with links to documentation for how to migrate away from these features. If you have concerns or comments please chime in on [#711](https://github.com/onsi/ginkgo/issues/711). - -Please start exploring and using the V2 release! To get started follow the [Using the Release Candidate](https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md#using-the-beta) directions in the migration guide. - -## TLDR -Ginkgo builds on Go's `testing` package, allowing expressive [Behavior-Driven Development](https://en.wikipedia.org/wiki/Behavior-driven_development) ("BDD") style tests. -It is typically (and optionally) paired with the [Gomega](https://github.com/onsi/gomega) matcher library. - -```go -Describe("the strings package", func() { - Context("strings.Contains()", func() { - When("the string contains the substring in the middle", func() { - It("returns `true`", func() { - Expect(strings.Contains("Ginkgo is awesome", "is")).To(BeTrue()) - }) - }) - }) -}) -``` - -## Feature List - -- Ginkgo uses Go's `testing` package and can live alongside your existing `testing` tests. It's easy to [bootstrap](https://onsi.github.io/ginkgo/#bootstrapping-a-suite) and start writing your [first tests](https://onsi.github.io/ginkgo/#adding-specs-to-a-suite) - -- Ginkgo allows you to write tests in Go using expressive [Behavior-Driven Development](https://en.wikipedia.org/wiki/Behavior-driven_development) ("BDD") style: - - Nestable [`Describe`, `Context` and `When` container blocks](https://onsi.github.io/ginkgo/#organizing-specs-with-containers-describe-and-context) - - [`BeforeEach` and `AfterEach` blocks](https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach) for setup and teardown - - [`It` and `Specify` blocks](https://onsi.github.io/ginkgo/#individual-specs-it) that hold your assertions - - [`JustBeforeEach` blocks](https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach) that separate creation from configuration (also known as the subject action pattern). - - [`BeforeSuite` and `AfterSuite` blocks](https://onsi.github.io/ginkgo/#global-setup-and-teardown-beforesuite-and-aftersuite) to prep for and cleanup after a suite. - -- A comprehensive test runner that lets you: - - Mark specs as [pending](https://onsi.github.io/ginkgo/#pending-specs) - - [Focus](https://onsi.github.io/ginkgo/#focused-specs) individual specs, and groups of specs, either programmatically or on the command line - - Run your tests in [random order](https://onsi.github.io/ginkgo/#spec-permutation), and then reuse random seeds to replicate the same order. - - Break up your test suite into parallel processes for straightforward [test parallelization](https://onsi.github.io/ginkgo/#parallel-specs) - -- `ginkgo`: a command line interface with plenty of handy command line arguments for [running your tests](https://onsi.github.io/ginkgo/#running-tests) and [generating](https://onsi.github.io/ginkgo/#generators) test files. Here are a few choice examples: - - `ginkgo -nodes=N` runs your tests in `N` parallel processes and print out coherent output in realtime - - `ginkgo -cover` runs your tests using Go's code coverage tool - - `ginkgo convert` converts an XUnit-style `testing` package to a Ginkgo-style package - - `ginkgo -focus="REGEXP"` and `ginkgo -skip="REGEXP"` allow you to specify a subset of tests to run via regular expression - - `ginkgo -r` runs all tests suites under the current directory - - `ginkgo -v` prints out identifying information for each tests just before it runs - - And much more: run `ginkgo help` for details! - - The `ginkgo` CLI is convenient, but purely optional -- Ginkgo works just fine with `go test` - -- `ginkgo watch` [watches](https://onsi.github.io/ginkgo/#watching-for-changes) packages *and their dependencies* for changes, then reruns tests. Run tests immediately as you develop! - -- Built-in support for testing [asynchronicity](https://onsi.github.io/ginkgo/#asynchronous-tests) - -- Built-in support for [benchmarking](https://onsi.github.io/ginkgo/#benchmark-tests) your code. Control the number of benchmark samples as you gather runtimes and other, arbitrary, bits of numerical information about your code. - -- [Completions for Sublime Text](https://github.com/onsi/ginkgo-sublime-completions): just use [Package Control](https://sublime.wbond.net/) to install `Ginkgo Completions`. - -- [Completions for VSCode](https://github.com/onsi/vscode-ginkgo): just use VSCode's extension installer to install `vscode-ginkgo`. - -- [Ginkgo tools for VSCode](https://marketplace.visualstudio.com/items?itemName=joselitofilho.ginkgotestexplorer): just use VSCode's extension installer to install `ginkgoTestExplorer`. - -- Straightforward support for third-party testing libraries such as [Gomock](https://code.google.com/p/gomock/) and [Testify](https://github.com/stretchr/testify). Check out the [docs](https://onsi.github.io/ginkgo/#third-party-integrations) for details. - -- A modular architecture that lets you easily: - - Write [custom reporters](https://onsi.github.io/ginkgo/#writing-custom-reporters) (for example, Ginkgo comes with a [JUnit XML reporter](https://onsi.github.io/ginkgo/#generating-junit-xml-output) and a TeamCity reporter). - - [Adapt an existing matcher library (or write your own!)](https://onsi.github.io/ginkgo/#using-other-matcher-libraries) to work with Ginkgo - -## [Gomega](https://github.com/onsi/gomega): Ginkgo's Preferred Matcher Library - -Ginkgo is best paired with Gomega. Learn more about Gomega [here](https://onsi.github.io/gomega/) - -## [Agouti](https://github.com/sclevine/agouti): A Go Acceptance Testing Framework - -Agouti allows you run WebDriver integration tests. Learn more about Agouti [here](https://agouti.org) - -## Getting Started - -You'll need the Go command-line tools. Follow the [installation instructions](https://golang.org/doc/install) if you don't have it installed. - -### Global installation -To install the Ginkgo command line interface: -```bash -go get -u github.com/onsi/ginkgo/ginkgo -``` -Note that this will install it to `$GOBIN`, which will need to be in the `$PATH` (or equivalent). Run `go help install` for more information. - -### Go module ["tools package"](https://github.com/golang/go/issues/25922): -Create (or update) a file called `tools/tools.go` with the following contents: -```go -// +build tools - -package tools - -import ( - _ "github.com/onsi/ginkgo/ginkgo" -) - -// This file imports packages that are used when running go generate, or used -// during the development process but not otherwise depended on by built code. -``` -The Ginkgo command can then be run via `go run github.com/onsi/ginkgo/ginkgo`. -This approach allows the version of Ginkgo to be maintained under source control for reproducible results, -and is well suited to automated test pipelines. - -### Bootstrapping -```bash -cd path/to/package/you/want/to/test - -ginkgo bootstrap # set up a new ginkgo suite -ginkgo generate # will create a sample test file. edit this file and add your tests then... - -go test # to run your tests - -ginkgo # also runs your tests - -``` - -## I'm new to Go: What are my testing options? - -Of course, I heartily recommend [Ginkgo](https://github.com/onsi/ginkgo) and [Gomega](https://github.com/onsi/gomega). Both packages are seeing heavy, daily, production use on a number of projects and boast a mature and comprehensive feature-set. - -With that said, it's great to know what your options are :) - -### What Go gives you out of the box - -Testing is a first class citizen in Go, however Go's built-in testing primitives are somewhat limited: The [testing](https://golang.org/pkg/testing) package provides basic XUnit style tests and no assertion library. - -### Matcher libraries for Go's XUnit style tests - -A number of matcher libraries have been written to augment Go's built-in XUnit style tests. Here are two that have gained traction: - -- [testify](https://github.com/stretchr/testify) -- [gocheck](https://labix.org/gocheck) - -You can also use Ginkgo's matcher library [Gomega](https://github.com/onsi/gomega) in [XUnit style tests](https://onsi.github.io/gomega/#using-gomega-with-golangs-xunitstyle-tests) - -### BDD style testing frameworks - -There are a handful of BDD-style testing frameworks written for Go. Here are a few: - -- [Ginkgo](https://github.com/onsi/ginkgo) ;) -- [GoConvey](https://github.com/smartystreets/goconvey) -- [Goblin](https://github.com/franela/goblin) -- [Mao](https://github.com/azer/mao) -- [Zen](https://github.com/pranavraja/zen) - -Finally, @shageman has [put together](https://github.com/shageman/gotestit) a comprehensive comparison of Go testing libraries. - -Go explore! - -## License - -Ginkgo is MIT-Licensed - -## Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md) diff --git a/vendor/github.com/onsi/ginkgo/RELEASING.md b/vendor/github.com/onsi/ginkgo/RELEASING.md deleted file mode 100644 index db3d234c1c2..00000000000 --- a/vendor/github.com/onsi/ginkgo/RELEASING.md +++ /dev/null @@ -1,17 +0,0 @@ -A Ginkgo release is a tagged git sha and a GitHub release. To cut a release: - -1. Ensure CHANGELOG.md is up to date. - - Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release - - Categorize the changes into - - Breaking Changes (requires a major version) - - New Features (minor version) - - Fixes (fix version) - - Maintenance (which in general should not be mentioned in `CHANGELOG.md` as they have no user impact) -1. Update `VERSION` in `config/config.go` -1. Commit, push, and release: - ``` - git commit -m "vM.m.p" - git push - gh release create "vM.m.p" - git fetch --tags origin master - ``` \ No newline at end of file diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go deleted file mode 100644 index 3130c778974..00000000000 --- a/vendor/github.com/onsi/ginkgo/config/config.go +++ /dev/null @@ -1,232 +0,0 @@ -/* -Ginkgo accepts a number of configuration options. - -These are documented [here](http://onsi.github.io/ginkgo/#the-ginkgo-cli) - -You can also learn more via - - ginkgo help - -or (I kid you not): - - go test -asdf -*/ -package config - -import ( - "flag" - "time" - - "fmt" -) - -const VERSION = "1.16.5" - -type GinkgoConfigType struct { - RandomSeed int64 - RandomizeAllSpecs bool - RegexScansFilePath bool - FocusStrings []string - SkipStrings []string - SkipMeasurements bool - FailOnPending bool - FailFast bool - FlakeAttempts int - EmitSpecProgress bool - DryRun bool - DebugParallel bool - - ParallelNode int - ParallelTotal int - SyncHost string - StreamHost string -} - -var GinkgoConfig = GinkgoConfigType{} - -type DefaultReporterConfigType struct { - NoColor bool - SlowSpecThreshold float64 - NoisyPendings bool - NoisySkippings bool - Succinct bool - Verbose bool - FullTrace bool - ReportPassed bool - ReportFile string -} - -var DefaultReporterConfig = DefaultReporterConfigType{} - -func processPrefix(prefix string) string { - if prefix != "" { - prefix += "." - } - return prefix -} - -type flagFunc func(string) - -func (f flagFunc) String() string { return "" } -func (f flagFunc) Set(s string) error { f(s); return nil } - -func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) { - prefix = processPrefix(prefix) - flagSet.Int64Var(&(GinkgoConfig.RandomSeed), prefix+"seed", time.Now().Unix(), "The seed used to randomize the spec suite.") - flagSet.BoolVar(&(GinkgoConfig.RandomizeAllSpecs), prefix+"randomizeAllSpecs", false, "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When groups.") - flagSet.BoolVar(&(GinkgoConfig.SkipMeasurements), prefix+"skipMeasurements", false, "If set, ginkgo will skip any measurement specs.") - flagSet.BoolVar(&(GinkgoConfig.FailOnPending), prefix+"failOnPending", false, "If set, ginkgo will mark the test suite as failed if any specs are pending.") - flagSet.BoolVar(&(GinkgoConfig.FailFast), prefix+"failFast", false, "If set, ginkgo will stop running a test suite after a failure occurs.") - - flagSet.BoolVar(&(GinkgoConfig.DryRun), prefix+"dryRun", false, "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v.") - - flagSet.Var(flagFunc(flagFocus), prefix+"focus", "If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed.") - flagSet.Var(flagFunc(flagSkip), prefix+"skip", "If set, ginkgo will only run specs that do not match this regular expression. Can be specified multiple times, values are ORed.") - - flagSet.BoolVar(&(GinkgoConfig.RegexScansFilePath), prefix+"regexScansFilePath", false, "If set, ginkgo regex matching also will look at the file path (code location).") - - flagSet.IntVar(&(GinkgoConfig.FlakeAttempts), prefix+"flakeAttempts", 1, "Make up to this many attempts to run each spec. Please note that if any of the attempts succeed, the suite will not be failed. But any failures will still be recorded.") - - flagSet.BoolVar(&(GinkgoConfig.EmitSpecProgress), prefix+"progress", false, "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter.") - - flagSet.BoolVar(&(GinkgoConfig.DebugParallel), prefix+"debug", false, "If set, ginkgo will emit node output to files when running in parallel.") - - if includeParallelFlags { - flagSet.IntVar(&(GinkgoConfig.ParallelNode), prefix+"parallel.node", 1, "This worker node's (one-indexed) node number. For running specs in parallel.") - flagSet.IntVar(&(GinkgoConfig.ParallelTotal), prefix+"parallel.total", 1, "The total number of worker nodes. For running specs in parallel.") - flagSet.StringVar(&(GinkgoConfig.SyncHost), prefix+"parallel.synchost", "", "The address for the server that will synchronize the running nodes.") - flagSet.StringVar(&(GinkgoConfig.StreamHost), prefix+"parallel.streamhost", "", "The address for the server that the running nodes should stream data to.") - } - - flagSet.BoolVar(&(DefaultReporterConfig.NoColor), prefix+"noColor", false, "If set, suppress color output in default reporter.") - flagSet.Float64Var(&(DefaultReporterConfig.SlowSpecThreshold), prefix+"slowSpecThreshold", 5.0, "(in seconds) Specs that take longer to run than this threshold are flagged as slow by the default reporter.") - flagSet.BoolVar(&(DefaultReporterConfig.NoisyPendings), prefix+"noisyPendings", true, "If set, default reporter will shout about pending tests.") - flagSet.BoolVar(&(DefaultReporterConfig.NoisySkippings), prefix+"noisySkippings", true, "If set, default reporter will shout about skipping tests.") - flagSet.BoolVar(&(DefaultReporterConfig.Verbose), prefix+"v", false, "If set, default reporter print out all specs as they begin.") - flagSet.BoolVar(&(DefaultReporterConfig.Succinct), prefix+"succinct", false, "If set, default reporter prints out a very succinct report") - flagSet.BoolVar(&(DefaultReporterConfig.FullTrace), prefix+"trace", false, "If set, default reporter prints out the full stack trace when a failure occurs") - flagSet.BoolVar(&(DefaultReporterConfig.ReportPassed), prefix+"reportPassed", false, "If set, default reporter prints out captured output of passed tests.") - flagSet.StringVar(&(DefaultReporterConfig.ReportFile), prefix+"reportFile", "", "Override the default reporter output file path.") - -} - -func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultReporterConfigType) []string { - prefix = processPrefix(prefix) - result := make([]string, 0) - - if ginkgo.RandomSeed > 0 { - result = append(result, fmt.Sprintf("--%sseed=%d", prefix, ginkgo.RandomSeed)) - } - - if ginkgo.RandomizeAllSpecs { - result = append(result, fmt.Sprintf("--%srandomizeAllSpecs", prefix)) - } - - if ginkgo.SkipMeasurements { - result = append(result, fmt.Sprintf("--%sskipMeasurements", prefix)) - } - - if ginkgo.FailOnPending { - result = append(result, fmt.Sprintf("--%sfailOnPending", prefix)) - } - - if ginkgo.FailFast { - result = append(result, fmt.Sprintf("--%sfailFast", prefix)) - } - - if ginkgo.DryRun { - result = append(result, fmt.Sprintf("--%sdryRun", prefix)) - } - - for _, s := range ginkgo.FocusStrings { - result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, s)) - } - - for _, s := range ginkgo.SkipStrings { - result = append(result, fmt.Sprintf("--%sskip=%s", prefix, s)) - } - - if ginkgo.FlakeAttempts > 1 { - result = append(result, fmt.Sprintf("--%sflakeAttempts=%d", prefix, ginkgo.FlakeAttempts)) - } - - if ginkgo.EmitSpecProgress { - result = append(result, fmt.Sprintf("--%sprogress", prefix)) - } - - if ginkgo.DebugParallel { - result = append(result, fmt.Sprintf("--%sdebug", prefix)) - } - - if ginkgo.ParallelNode != 0 { - result = append(result, fmt.Sprintf("--%sparallel.node=%d", prefix, ginkgo.ParallelNode)) - } - - if ginkgo.ParallelTotal != 0 { - result = append(result, fmt.Sprintf("--%sparallel.total=%d", prefix, ginkgo.ParallelTotal)) - } - - if ginkgo.StreamHost != "" { - result = append(result, fmt.Sprintf("--%sparallel.streamhost=%s", prefix, ginkgo.StreamHost)) - } - - if ginkgo.SyncHost != "" { - result = append(result, fmt.Sprintf("--%sparallel.synchost=%s", prefix, ginkgo.SyncHost)) - } - - if ginkgo.RegexScansFilePath { - result = append(result, fmt.Sprintf("--%sregexScansFilePath", prefix)) - } - - if reporter.NoColor { - result = append(result, fmt.Sprintf("--%snoColor", prefix)) - } - - if reporter.SlowSpecThreshold > 0 { - result = append(result, fmt.Sprintf("--%sslowSpecThreshold=%.5f", prefix, reporter.SlowSpecThreshold)) - } - - if !reporter.NoisyPendings { - result = append(result, fmt.Sprintf("--%snoisyPendings=false", prefix)) - } - - if !reporter.NoisySkippings { - result = append(result, fmt.Sprintf("--%snoisySkippings=false", prefix)) - } - - if reporter.Verbose { - result = append(result, fmt.Sprintf("--%sv", prefix)) - } - - if reporter.Succinct { - result = append(result, fmt.Sprintf("--%ssuccinct", prefix)) - } - - if reporter.FullTrace { - result = append(result, fmt.Sprintf("--%strace", prefix)) - } - - if reporter.ReportPassed { - result = append(result, fmt.Sprintf("--%sreportPassed", prefix)) - } - - if reporter.ReportFile != "" { - result = append(result, fmt.Sprintf("--%sreportFile=%s", prefix, reporter.ReportFile)) - } - - return result -} - -// flagFocus implements the -focus flag. -func flagFocus(arg string) { - if arg != "" { - GinkgoConfig.FocusStrings = append(GinkgoConfig.FocusStrings, arg) - } -} - -// flagSkip implements the -skip flag. -func flagSkip(arg string) { - if arg != "" { - GinkgoConfig.SkipStrings = append(GinkgoConfig.SkipStrings, arg) - } -} diff --git a/vendor/github.com/onsi/ginkgo/extensions/table/table.go b/vendor/github.com/onsi/ginkgo/extensions/table/table.go deleted file mode 100644 index 4b002780732..00000000000 --- a/vendor/github.com/onsi/ginkgo/extensions/table/table.go +++ /dev/null @@ -1,110 +0,0 @@ -/* - -Table provides a simple DSL for Ginkgo-native Table-Driven Tests - -The godoc documentation describes Table's API. More comprehensive documentation (with examples!) is available at http://onsi.github.io/ginkgo#table-driven-tests - -*/ - -package table - -import ( - "fmt" - "reflect" - - "github.com/onsi/ginkgo/internal/codelocation" - "github.com/onsi/ginkgo/internal/global" - "github.com/onsi/ginkgo/types" -) - -/* -DescribeTable describes a table-driven test. - -For example: - - DescribeTable("a simple table", - func(x int, y int, expected bool) { - Ω(x > y).Should(Equal(expected)) - }, - Entry("x > y", 1, 0, true), - Entry("x == y", 0, 0, false), - Entry("x < y", 0, 1, false), - ) - -The first argument to `DescribeTable` is a string description. -The second argument is a function that will be run for each table entry. Your assertions go here - the function is equivalent to a Ginkgo It. -The subsequent arguments must be of type `TableEntry`. We recommend using the `Entry` convenience constructors. - -The `Entry` constructor takes a string description followed by an arbitrary set of parameters. These parameters are passed into your function. - -Under the hood, `DescribeTable` simply generates a new Ginkgo `Describe`. Each `Entry` is turned into an `It` within the `Describe`. - -It's important to understand that the `Describe`s and `It`s are generated at evaluation time (i.e. when Ginkgo constructs the tree of tests and before the tests run). - -Individual Entries can be focused (with FEntry) or marked pending (with PEntry or XEntry). In addition, the entire table can be focused or marked pending with FDescribeTable and PDescribeTable/XDescribeTable. - -A description function can be passed to Entry in place of the description. The function is then fed with the entry parameters to generate the description of the It corresponding to that particular Entry. - -For example: - - describe := func(desc string) func(int, int, bool) string { - return func(x, y int, expected bool) string { - return fmt.Sprintf("%s x=%d y=%d expected:%t", desc, x, y, expected) - } - } - - DescribeTable("a simple table", - func(x int, y int, expected bool) { - Ω(x > y).Should(Equal(expected)) - }, - Entry(describe("x > y"), 1, 0, true), - Entry(describe("x == y"), 0, 0, false), - Entry(describe("x < y"), 0, 1, false), - ) -*/ -func DescribeTable(description string, itBody interface{}, entries ...TableEntry) bool { - describeTable(description, itBody, entries, types.FlagTypeNone) - return true -} - -/* -You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`. -*/ -func FDescribeTable(description string, itBody interface{}, entries ...TableEntry) bool { - describeTable(description, itBody, entries, types.FlagTypeFocused) - return true -} - -/* -You can mark a table as pending with `PDescribeTable`. This is equivalent to `PDescribe`. -*/ -func PDescribeTable(description string, itBody interface{}, entries ...TableEntry) bool { - describeTable(description, itBody, entries, types.FlagTypePending) - return true -} - -/* -You can mark a table as pending with `XDescribeTable`. This is equivalent to `XDescribe`. -*/ -func XDescribeTable(description string, itBody interface{}, entries ...TableEntry) bool { - describeTable(description, itBody, entries, types.FlagTypePending) - return true -} - -func describeTable(description string, itBody interface{}, entries []TableEntry, flag types.FlagType) { - itBodyValue := reflect.ValueOf(itBody) - if itBodyValue.Kind() != reflect.Func { - panic(fmt.Sprintf("DescribeTable expects a function, got %#v", itBody)) - } - - global.Suite.PushContainerNode( - description, - func() { - for _, entry := range entries { - entry.generateIt(itBodyValue) - } - }, - flag, - codelocation.New(2), - ) -} diff --git a/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go b/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go deleted file mode 100644 index 4d9c237ad72..00000000000 --- a/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go +++ /dev/null @@ -1,129 +0,0 @@ -package table - -import ( - "fmt" - "reflect" - - "github.com/onsi/ginkgo/internal/codelocation" - "github.com/onsi/ginkgo/internal/global" - "github.com/onsi/ginkgo/types" -) - -/* -TableEntry represents an entry in a table test. You generally use the `Entry` constructor. -*/ -type TableEntry struct { - Description interface{} - Parameters []interface{} - Pending bool - Focused bool - codeLocation types.CodeLocation -} - -func (t TableEntry) generateIt(itBody reflect.Value) { - var description string - descriptionValue := reflect.ValueOf(t.Description) - switch descriptionValue.Kind() { - case reflect.String: - description = descriptionValue.String() - case reflect.Func: - values := castParameters(descriptionValue, t.Parameters) - res := descriptionValue.Call(values) - if len(res) != 1 { - panic(fmt.Sprintf("The describe function should return only a value, returned %d", len(res))) - } - if res[0].Kind() != reflect.String { - panic(fmt.Sprintf("The describe function should return a string, returned %#v", res[0])) - } - description = res[0].String() - default: - panic(fmt.Sprintf("Description can either be a string or a function, got %#v", descriptionValue)) - } - - if t.Pending { - global.Suite.PushItNode(description, func() {}, types.FlagTypePending, t.codeLocation, 0) - return - } - - values := castParameters(itBody, t.Parameters) - body := func() { - itBody.Call(values) - } - - if t.Focused { - global.Suite.PushItNode(description, body, types.FlagTypeFocused, t.codeLocation, global.DefaultTimeout) - } else { - global.Suite.PushItNode(description, body, types.FlagTypeNone, t.codeLocation, global.DefaultTimeout) - } -} - -func castParameters(function reflect.Value, parameters []interface{}) []reflect.Value { - res := make([]reflect.Value, len(parameters)) - funcType := function.Type() - for i, param := range parameters { - if param == nil { - inType := funcType.In(i) - res[i] = reflect.Zero(inType) - } else { - res[i] = reflect.ValueOf(param) - } - } - return res -} - -/* -Entry constructs a TableEntry. - -The first argument is a required description (this becomes the content of the generated Ginkgo `It`). -Subsequent parameters are saved off and sent to the callback passed in to `DescribeTable`. - -Each Entry ends up generating an individual Ginkgo It. -*/ -func Entry(description interface{}, parameters ...interface{}) TableEntry { - return TableEntry{ - Description: description, - Parameters: parameters, - Pending: false, - Focused: false, - codeLocation: codelocation.New(1), - } -} - -/* -You can focus a particular entry with FEntry. This is equivalent to FIt. -*/ -func FEntry(description interface{}, parameters ...interface{}) TableEntry { - return TableEntry{ - Description: description, - Parameters: parameters, - Pending: false, - Focused: true, - codeLocation: codelocation.New(1), - } -} - -/* -You can mark a particular entry as pending with PEntry. This is equivalent to PIt. -*/ -func PEntry(description interface{}, parameters ...interface{}) TableEntry { - return TableEntry{ - Description: description, - Parameters: parameters, - Pending: true, - Focused: false, - codeLocation: codelocation.New(1), - } -} - -/* -You can mark a particular entry as pending with XEntry. This is equivalent to XIt. -*/ -func XEntry(description interface{}, parameters ...interface{}) TableEntry { - return TableEntry{ - Description: description, - Parameters: parameters, - Pending: true, - Focused: false, - codeLocation: codelocation.New(1), - } -} diff --git a/vendor/github.com/onsi/ginkgo/formatter/formatter.go b/vendor/github.com/onsi/ginkgo/formatter/formatter.go deleted file mode 100644 index 30d7cbe1297..00000000000 --- a/vendor/github.com/onsi/ginkgo/formatter/formatter.go +++ /dev/null @@ -1,190 +0,0 @@ -package formatter - -import ( - "fmt" - "regexp" - "strings" -) - -const COLS = 80 - -type ColorMode uint8 - -const ( - ColorModeNone ColorMode = iota - ColorModeTerminal - ColorModePassthrough -) - -var SingletonFormatter = New(ColorModeTerminal) - -func F(format string, args ...interface{}) string { - return SingletonFormatter.F(format, args...) -} - -func Fi(indentation uint, format string, args ...interface{}) string { - return SingletonFormatter.Fi(indentation, format, args...) -} - -func Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string { - return SingletonFormatter.Fiw(indentation, maxWidth, format, args...) -} - -type Formatter struct { - ColorMode ColorMode - colors map[string]string - styleRe *regexp.Regexp - preserveColorStylingTags bool -} - -func NewWithNoColorBool(noColor bool) Formatter { - if noColor { - return New(ColorModeNone) - } - return New(ColorModeTerminal) -} - -func New(colorMode ColorMode) Formatter { - f := Formatter{ - ColorMode: colorMode, - colors: map[string]string{ - "/": "\x1b[0m", - "bold": "\x1b[1m", - "underline": "\x1b[4m", - - "red": "\x1b[38;5;9m", - "orange": "\x1b[38;5;214m", - "coral": "\x1b[38;5;204m", - "magenta": "\x1b[38;5;13m", - "green": "\x1b[38;5;10m", - "dark-green": "\x1b[38;5;28m", - "yellow": "\x1b[38;5;11m", - "light-yellow": "\x1b[38;5;228m", - "cyan": "\x1b[38;5;14m", - "gray": "\x1b[38;5;243m", - "light-gray": "\x1b[38;5;246m", - "blue": "\x1b[38;5;12m", - }, - } - colors := []string{} - for color := range f.colors { - colors = append(colors, color) - } - f.styleRe = regexp.MustCompile("{{(" + strings.Join(colors, "|") + ")}}") - return f -} - -func (f Formatter) F(format string, args ...interface{}) string { - return f.Fi(0, format, args...) -} - -func (f Formatter) Fi(indentation uint, format string, args ...interface{}) string { - return f.Fiw(indentation, 0, format, args...) -} - -func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string { - out := fmt.Sprintf(f.style(format), args...) - - if indentation == 0 && maxWidth == 0 { - return out - } - - lines := strings.Split(out, "\n") - - if maxWidth != 0 { - outLines := []string{} - - maxWidth = maxWidth - indentation*2 - for _, line := range lines { - if f.length(line) <= maxWidth { - outLines = append(outLines, line) - continue - } - outWords := []string{} - length := uint(0) - words := strings.Split(line, " ") - for _, word := range words { - wordLength := f.length(word) - if length+wordLength <= maxWidth { - length += wordLength - outWords = append(outWords, word) - continue - } - outLines = append(outLines, strings.Join(outWords, " ")) - outWords = []string{word} - length = wordLength - } - if len(outWords) > 0 { - outLines = append(outLines, strings.Join(outWords, " ")) - } - } - - lines = outLines - } - - if indentation == 0 { - return strings.Join(lines, "\n") - } - - padding := strings.Repeat(" ", int(indentation)) - for i := range lines { - if lines[i] != "" { - lines[i] = padding + lines[i] - } - } - - return strings.Join(lines, "\n") -} - -func (f Formatter) length(styled string) uint { - n := uint(0) - inStyle := false - for _, b := range styled { - if inStyle { - if b == 'm' { - inStyle = false - } - continue - } - if b == '\x1b' { - inStyle = true - continue - } - n += 1 - } - return n -} - -func (f Formatter) CycleJoin(elements []string, joiner string, cycle []string) string { - if len(elements) == 0 { - return "" - } - n := len(cycle) - out := "" - for i, text := range elements { - out += cycle[i%n] + text - if i < len(elements)-1 { - out += joiner - } - } - out += "{{/}}" - return f.style(out) -} - -func (f Formatter) style(s string) string { - switch f.ColorMode { - case ColorModeNone: - return f.styleRe.ReplaceAllString(s, "") - case ColorModePassthrough: - return s - case ColorModeTerminal: - return f.styleRe.ReplaceAllStringFunc(s, func(match string) string { - if out, ok := f.colors[strings.Trim(match, "{}")]; ok { - return out - } - return match - }) - } - - return "" -} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go deleted file mode 100644 index ccd7685e38e..00000000000 --- a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go +++ /dev/null @@ -1,681 +0,0 @@ -/* -Ginkgo is a BDD-style testing framework for Golang - -The godoc documentation describes Ginkgo's API. More comprehensive documentation (with examples!) is available at http://onsi.github.io/ginkgo/ - -Ginkgo's preferred matcher library is [Gomega](http://github.com/onsi/gomega) - -Ginkgo on Github: http://github.com/onsi/ginkgo - -Ginkgo is MIT-Licensed -*/ -package ginkgo - -import ( - "flag" - "fmt" - "io" - "net/http" - "os" - "reflect" - "strings" - "time" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/internal/codelocation" - "github.com/onsi/ginkgo/internal/global" - "github.com/onsi/ginkgo/internal/remote" - "github.com/onsi/ginkgo/internal/testingtproxy" - "github.com/onsi/ginkgo/internal/writer" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/reporters/stenographer" - colorable "github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable" - "github.com/onsi/ginkgo/types" -) - -var deprecationTracker = types.NewDeprecationTracker() - -const GINKGO_VERSION = config.VERSION -const GINKGO_PANIC = ` -Your test failed. -Ginkgo panics to prevent subsequent assertions from running. -Normally Ginkgo rescues this panic so you shouldn't see it. - -But, if you make an assertion in a goroutine, Ginkgo can't capture the panic. -To circumvent this, you should call - - defer GinkgoRecover() - -at the top of the goroutine that caused this panic. -` - -func init() { - config.Flags(flag.CommandLine, "ginkgo", true) - GinkgoWriter = writer.New(os.Stdout) -} - -//GinkgoWriter implements an io.Writer -//When running in verbose mode any writes to GinkgoWriter will be immediately printed -//to stdout. Otherwise, GinkgoWriter will buffer any writes produced during the current test and flush them to screen -//only if the current test fails. -var GinkgoWriter io.Writer - -//The interface by which Ginkgo receives *testing.T -type GinkgoTestingT interface { - Fail() -} - -//GinkgoRandomSeed returns the seed used to randomize spec execution order. It is -//useful for seeding your own pseudorandom number generators (PRNGs) to ensure -//consistent executions from run to run, where your tests contain variability (for -//example, when selecting random test data). -func GinkgoRandomSeed() int64 { - return config.GinkgoConfig.RandomSeed -} - -//GinkgoParallelNode is deprecated, use GinkgoParallelProcess instead -func GinkgoParallelNode() int { - deprecationTracker.TrackDeprecation(types.Deprecations.ParallelNode(), codelocation.New(1)) - return GinkgoParallelProcess() -} - -//GinkgoParallelProcess returns the parallel process number for the current ginkgo process -//The process number is 1-indexed -func GinkgoParallelProcess() int { - return config.GinkgoConfig.ParallelNode -} - -//Some matcher libraries or legacy codebases require a *testing.T -//GinkgoT implements an interface analogous to *testing.T and can be used if -//the library in question accepts *testing.T through an interface -// -// For example, with testify: -// assert.Equal(GinkgoT(), 123, 123, "they should be equal") -// -// Or with gomock: -// gomock.NewController(GinkgoT()) -// -// GinkgoT() takes an optional offset argument that can be used to get the -// correct line number associated with the failure. -func GinkgoT(optionalOffset ...int) GinkgoTInterface { - offset := 3 - if len(optionalOffset) > 0 { - offset = optionalOffset[0] - } - failedFunc := func() bool { - return CurrentGinkgoTestDescription().Failed - } - nameFunc := func() string { - return CurrentGinkgoTestDescription().FullTestText - } - return testingtproxy.New(GinkgoWriter, Fail, Skip, failedFunc, nameFunc, offset) -} - -//The interface returned by GinkgoT(). This covers most of the methods -//in the testing package's T. -type GinkgoTInterface interface { - Cleanup(func()) - Setenv(key, value string) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Fail() - FailNow() - Failed() bool - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Helper() - Log(args ...interface{}) - Logf(format string, args ...interface{}) - Name() string - Parallel() - Skip(args ...interface{}) - SkipNow() - Skipf(format string, args ...interface{}) - Skipped() bool - TempDir() string -} - -//Custom Ginkgo test reporters must implement the Reporter interface. -// -//The custom reporter is passed in a SuiteSummary when the suite begins and ends, -//and a SpecSummary just before a spec begins and just after a spec ends -type Reporter reporters.Reporter - -//Asynchronous specs are given a channel of the Done type. You must close or write to the channel -//to tell Ginkgo that your async test is done. -type Done chan<- interface{} - -//GinkgoTestDescription represents the information about the current running test returned by CurrentGinkgoTestDescription -// FullTestText: a concatenation of ComponentTexts and the TestText -// ComponentTexts: a list of all texts for the Describes & Contexts leading up to the current test -// TestText: the text in the actual It or Measure node -// IsMeasurement: true if the current test is a measurement -// FileName: the name of the file containing the current test -// LineNumber: the line number for the current test -// Failed: if the current test has failed, this will be true (useful in an AfterEach) -type GinkgoTestDescription struct { - FullTestText string - ComponentTexts []string - TestText string - - IsMeasurement bool - - FileName string - LineNumber int - - Failed bool - Duration time.Duration -} - -//CurrentGinkgoTestDescripton returns information about the current running test. -func CurrentGinkgoTestDescription() GinkgoTestDescription { - summary, ok := global.Suite.CurrentRunningSpecSummary() - if !ok { - return GinkgoTestDescription{} - } - - subjectCodeLocation := summary.ComponentCodeLocations[len(summary.ComponentCodeLocations)-1] - - return GinkgoTestDescription{ - ComponentTexts: summary.ComponentTexts[1:], - FullTestText: strings.Join(summary.ComponentTexts[1:], " "), - TestText: summary.ComponentTexts[len(summary.ComponentTexts)-1], - IsMeasurement: summary.IsMeasurement, - FileName: subjectCodeLocation.FileName, - LineNumber: subjectCodeLocation.LineNumber, - Failed: summary.HasFailureState(), - Duration: summary.RunTime, - } -} - -//Measurement tests receive a Benchmarker. -// -//You use the Time() function to time how long the passed in body function takes to run -//You use the RecordValue() function to track arbitrary numerical measurements. -//The RecordValueWithPrecision() function can be used alternatively to provide the unit -//and resolution of the numeric measurement. -//The optional info argument is passed to the test reporter and can be used to -// provide the measurement data to a custom reporter with context. -// -//See http://onsi.github.io/ginkgo/#benchmark_tests for more details -type Benchmarker interface { - Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration) - RecordValue(name string, value float64, info ...interface{}) - RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{}) -} - -//RunSpecs is the entry point for the Ginkgo test runner. -//You must call this within a Golang testing TestX(t *testing.T) function. -// -//To bootstrap a test suite you can use the Ginkgo CLI: -// -// ginkgo bootstrap -func RunSpecs(t GinkgoTestingT, description string) bool { - specReporters := []Reporter{buildDefaultReporter()} - if config.DefaultReporterConfig.ReportFile != "" { - reportFile := config.DefaultReporterConfig.ReportFile - specReporters[0] = reporters.NewJUnitReporter(reportFile) - specReporters = append(specReporters, buildDefaultReporter()) - } - return runSpecsWithCustomReporters(t, description, specReporters) -} - -//To run your tests with Ginkgo's default reporter and your custom reporter(s), replace -//RunSpecs() with this method. -func RunSpecsWithDefaultAndCustomReporters(t GinkgoTestingT, description string, specReporters []Reporter) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.CustomReporter()) - specReporters = append(specReporters, buildDefaultReporter()) - return runSpecsWithCustomReporters(t, description, specReporters) -} - -//To run your tests with your custom reporter(s) (and *not* Ginkgo's default reporter), replace -//RunSpecs() with this method. Note that parallel tests will not work correctly without the default reporter -func RunSpecsWithCustomReporters(t GinkgoTestingT, description string, specReporters []Reporter) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.CustomReporter()) - return runSpecsWithCustomReporters(t, description, specReporters) -} - -func runSpecsWithCustomReporters(t GinkgoTestingT, description string, specReporters []Reporter) bool { - writer := GinkgoWriter.(*writer.Writer) - writer.SetStream(config.DefaultReporterConfig.Verbose) - reporters := make([]reporters.Reporter, len(specReporters)) - for i, reporter := range specReporters { - reporters[i] = reporter - } - passed, hasFocusedTests := global.Suite.Run(t, description, reporters, writer, config.GinkgoConfig) - - if deprecationTracker.DidTrackDeprecations() { - fmt.Fprintln(colorable.NewColorableStderr(), deprecationTracker.DeprecationsReport()) - } - - if passed && hasFocusedTests && strings.TrimSpace(os.Getenv("GINKGO_EDITOR_INTEGRATION")) == "" { - fmt.Println("PASS | FOCUSED") - os.Exit(types.GINKGO_FOCUS_EXIT_CODE) - } - return passed -} - -func buildDefaultReporter() Reporter { - remoteReportingServer := config.GinkgoConfig.StreamHost - if remoteReportingServer == "" { - stenographer := stenographer.New(!config.DefaultReporterConfig.NoColor, config.GinkgoConfig.FlakeAttempts > 1, colorable.NewColorableStdout()) - return reporters.NewDefaultReporter(config.DefaultReporterConfig, stenographer) - } else { - debugFile := "" - if config.GinkgoConfig.DebugParallel { - debugFile = fmt.Sprintf("ginkgo-node-%d.log", config.GinkgoConfig.ParallelNode) - } - return remote.NewForwardingReporter(config.DefaultReporterConfig, remoteReportingServer, &http.Client{}, remote.NewOutputInterceptor(), GinkgoWriter.(*writer.Writer), debugFile) - } -} - -//Skip notifies Ginkgo that the current spec was skipped. -func Skip(message string, callerSkip ...int) { - skip := 0 - if len(callerSkip) > 0 { - skip = callerSkip[0] - } - - global.Failer.Skip(message, codelocation.New(skip+1)) - panic(GINKGO_PANIC) -} - -//Fail notifies Ginkgo that the current spec has failed. (Gomega will call Fail for you automatically when an assertion fails.) -func Fail(message string, callerSkip ...int) { - skip := 0 - if len(callerSkip) > 0 { - skip = callerSkip[0] - } - - global.Failer.Fail(message, codelocation.New(skip+1)) - panic(GINKGO_PANIC) -} - -//GinkgoRecover should be deferred at the top of any spawned goroutine that (may) call `Fail` -//Since Gomega assertions call fail, you should throw a `defer GinkgoRecover()` at the top of any goroutine that -//calls out to Gomega -// -//Here's why: Ginkgo's `Fail` method records the failure and then panics to prevent -//further assertions from running. This panic must be recovered. Ginkgo does this for you -//if the panic originates in a Ginkgo node (an It, BeforeEach, etc...) -// -//Unfortunately, if a panic originates on a goroutine *launched* from one of these nodes there's no -//way for Ginkgo to rescue the panic. To do this, you must remember to `defer GinkgoRecover()` at the top of such a goroutine. -func GinkgoRecover() { - e := recover() - if e != nil { - global.Failer.Panic(codelocation.New(1), e) - } -} - -//Describe blocks allow you to organize your specs. A Describe block can contain any number of -//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. -// -//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally -//equivalent. The difference is purely semantic -- you typically Describe the behavior of an object -//or method and, within that Describe, outline a number of Contexts and Whens. -func Describe(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypeNone, codelocation.New(1)) - return true -} - -//You can focus the tests within a describe block using FDescribe -func FDescribe(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypeFocused, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using PDescribe -func PDescribe(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using XDescribe -func XDescribe(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//Context blocks allow you to organize your specs. A Context block can contain any number of -//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. -// -//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally -//equivalent. The difference is purely semantic -- you typical Describe the behavior of an object -//or method and, within that Describe, outline a number of Contexts and Whens. -func Context(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypeNone, codelocation.New(1)) - return true -} - -//You can focus the tests within a describe block using FContext -func FContext(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypeFocused, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using PContext -func PContext(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using XContext -func XContext(text string, body func()) bool { - global.Suite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//When blocks allow you to organize your specs. A When block can contain any number of -//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. -// -//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally -//equivalent. The difference is purely semantic -- you typical Describe the behavior of an object -//or method and, within that Describe, outline a number of Contexts and Whens. -func When(text string, body func()) bool { - global.Suite.PushContainerNode("when "+text, body, types.FlagTypeNone, codelocation.New(1)) - return true -} - -//You can focus the tests within a describe block using FWhen -func FWhen(text string, body func()) bool { - global.Suite.PushContainerNode("when "+text, body, types.FlagTypeFocused, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using PWhen -func PWhen(text string, body func()) bool { - global.Suite.PushContainerNode("when "+text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//You can mark the tests within a describe block as pending using XWhen -func XWhen(text string, body func()) bool { - global.Suite.PushContainerNode("when "+text, body, types.FlagTypePending, codelocation.New(1)) - return true -} - -//It blocks contain your test code and assertions. You cannot nest any other Ginkgo blocks -//within an It block. -// -//Ginkgo will normally run It blocks synchronously. To perform asynchronous tests, pass a -//function that accepts a Done channel. When you do this, you can also provide an optional timeout. -func It(text string, body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushItNode(text, body, types.FlagTypeNone, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//You can focus individual Its using FIt -func FIt(text string, body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushItNode(text, body, types.FlagTypeFocused, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//You can mark Its as pending using PIt -func PIt(text string, _ ...interface{}) bool { - global.Suite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//You can mark Its as pending using XIt -func XIt(text string, _ ...interface{}) bool { - global.Suite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//Specify blocks are aliases for It blocks and allow for more natural wording in situations -//which "It" does not fit into a natural sentence flow. All the same protocols apply for Specify blocks -//which apply to It blocks. -func Specify(text string, body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushItNode(text, body, types.FlagTypeNone, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//You can focus individual Specifys using FSpecify -func FSpecify(text string, body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushItNode(text, body, types.FlagTypeFocused, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//You can mark Specifys as pending using PSpecify -func PSpecify(text string, is ...interface{}) bool { - global.Suite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//You can mark Specifys as pending using XSpecify -func XSpecify(text string, is ...interface{}) bool { - global.Suite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//By allows you to better document large Its. -// -//Generally you should try to keep your Its short and to the point. This is not always possible, however, -//especially in the context of integration tests that capture a particular workflow. -// -//By allows you to document such flows. By must be called within a runnable node (It, BeforeEach, Measure, etc...) -//By will simply log the passed in text to the GinkgoWriter. If By is handed a function it will immediately run the function. -func By(text string, callbacks ...func()) { - preamble := "\x1b[1mSTEP\x1b[0m" - if config.DefaultReporterConfig.NoColor { - preamble = "STEP" - } - fmt.Fprintln(GinkgoWriter, preamble+": "+text) - if len(callbacks) == 1 { - callbacks[0]() - } - if len(callbacks) > 1 { - panic("just one callback per By, please") - } -} - -//Measure blocks run the passed in body function repeatedly (determined by the samples argument) -//and accumulate metrics provided to the Benchmarker by the body function. -// -//The body function must have the signature: -// func(b Benchmarker) -func Measure(text string, body interface{}, samples int) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), codelocation.New(1)) - global.Suite.PushMeasureNode(text, body, types.FlagTypeNone, codelocation.New(1), samples) - return true -} - -//You can focus individual Measures using FMeasure -func FMeasure(text string, body interface{}, samples int) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), codelocation.New(1)) - global.Suite.PushMeasureNode(text, body, types.FlagTypeFocused, codelocation.New(1), samples) - return true -} - -//You can mark Measurements as pending using PMeasure -func PMeasure(text string, _ ...interface{}) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), codelocation.New(1)) - global.Suite.PushMeasureNode(text, func(b Benchmarker) {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//You can mark Measurements as pending using XMeasure -func XMeasure(text string, _ ...interface{}) bool { - deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), codelocation.New(1)) - global.Suite.PushMeasureNode(text, func(b Benchmarker) {}, types.FlagTypePending, codelocation.New(1), 0) - return true -} - -//BeforeSuite blocks are run just once before any specs are run. When running in parallel, each -//parallel node process will call BeforeSuite. -// -//BeforeSuite blocks can be made asynchronous by providing a body function that accepts a Done channel -// -//You may only register *one* BeforeSuite handler per test suite. You typically do so in your bootstrap file at the top level. -func BeforeSuite(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.SetBeforeSuiteNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//AfterSuite blocks are *always* run after all the specs regardless of whether specs have passed or failed. -//Moreover, if Ginkgo receives an interrupt signal (^C) it will attempt to run the AfterSuite before exiting. -// -//When running in parallel, each parallel node process will call AfterSuite. -// -//AfterSuite blocks can be made asynchronous by providing a body function that accepts a Done channel -// -//You may only register *one* AfterSuite handler per test suite. You typically do so in your bootstrap file at the top level. -func AfterSuite(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.SetAfterSuiteNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//SynchronizedBeforeSuite blocks are primarily meant to solve the problem of setting up singleton external resources shared across -//nodes when running tests in parallel. For example, say you have a shared database that you can only start one instance of that -//must be used in your tests. When running in parallel, only one node should set up the database and all other nodes should wait -//until that node is done before running. -// -//SynchronizedBeforeSuite accomplishes this by taking *two* function arguments. The first is only run on parallel node #1. The second is -//run on all nodes, but *only* after the first function completes successfully. Ginkgo also makes it possible to send data from the first function (on Node 1) -//to the second function (on all the other nodes). -// -//The functions have the following signatures. The first function (which only runs on node 1) has the signature: -// -// func() []byte -// -//or, to run asynchronously: -// -// func(done Done) []byte -// -//The byte array returned by the first function is then passed to the second function, which has the signature: -// -// func(data []byte) -// -//or, to run asynchronously: -// -// func(data []byte, done Done) -// -//Here's a simple pseudo-code example that starts a shared database on Node 1 and shares the database's address with the other nodes: -// -// var dbClient db.Client -// var dbRunner db.Runner -// -// var _ = SynchronizedBeforeSuite(func() []byte { -// dbRunner = db.NewRunner() -// err := dbRunner.Start() -// Ω(err).ShouldNot(HaveOccurred()) -// return []byte(dbRunner.URL) -// }, func(data []byte) { -// dbClient = db.NewClient() -// err := dbClient.Connect(string(data)) -// Ω(err).ShouldNot(HaveOccurred()) -// }) -func SynchronizedBeforeSuite(node1Body interface{}, allNodesBody interface{}, timeout ...float64) bool { - global.Suite.SetSynchronizedBeforeSuiteNode( - node1Body, - allNodesBody, - codelocation.New(1), - parseTimeout(timeout...), - ) - return true -} - -//SynchronizedAfterSuite blocks complement the SynchronizedBeforeSuite blocks in solving the problem of setting up -//external singleton resources shared across nodes when running tests in parallel. -// -//SynchronizedAfterSuite accomplishes this by taking *two* function arguments. The first runs on all nodes. The second runs only on parallel node #1 -//and *only* after all other nodes have finished and exited. This ensures that node 1, and any resources it is running, remain alive until -//all other nodes are finished. -// -//Both functions have the same signature: either func() or func(done Done) to run asynchronously. -// -//Here's a pseudo-code example that complements that given in SynchronizedBeforeSuite. Here, SynchronizedAfterSuite is used to tear down the shared database -//only after all nodes have finished: -// -// var _ = SynchronizedAfterSuite(func() { -// dbClient.Cleanup() -// }, func() { -// dbRunner.Stop() -// }) -func SynchronizedAfterSuite(allNodesBody interface{}, node1Body interface{}, timeout ...float64) bool { - global.Suite.SetSynchronizedAfterSuiteNode( - allNodesBody, - node1Body, - codelocation.New(1), - parseTimeout(timeout...), - ) - return true -} - -//BeforeEach blocks are run before It blocks. When multiple BeforeEach blocks are defined in nested -//Describe and Context blocks the outermost BeforeEach blocks are run first. -// -//Like It blocks, BeforeEach blocks can be made asynchronous by providing a body function that accepts -//a Done channel -func BeforeEach(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushBeforeEachNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//JustBeforeEach blocks are run before It blocks but *after* all BeforeEach blocks. For more details, -//read the [documentation](http://onsi.github.io/ginkgo/#separating_creation_and_configuration_) -// -//Like It blocks, BeforeEach blocks can be made asynchronous by providing a body function that accepts -//a Done channel -func JustBeforeEach(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushJustBeforeEachNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//JustAfterEach blocks are run after It blocks but *before* all AfterEach blocks. For more details, -//read the [documentation](http://onsi.github.io/ginkgo/#separating_creation_and_configuration_) -// -//Like It blocks, JustAfterEach blocks can be made asynchronous by providing a body function that accepts -//a Done channel -func JustAfterEach(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushJustAfterEachNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -//AfterEach blocks are run after It blocks. When multiple AfterEach blocks are defined in nested -//Describe and Context blocks the innermost AfterEach blocks are run first. -// -//Like It blocks, AfterEach blocks can be made asynchronous by providing a body function that accepts -//a Done channel -func AfterEach(body interface{}, timeout ...float64) bool { - validateBodyFunc(body, codelocation.New(1)) - global.Suite.PushAfterEachNode(body, codelocation.New(1), parseTimeout(timeout...)) - return true -} - -func validateBodyFunc(body interface{}, cl types.CodeLocation) { - t := reflect.TypeOf(body) - if t.Kind() != reflect.Func { - return - } - - if t.NumOut() > 0 { - return - } - - if t.NumIn() == 0 { - return - } - - if t.In(0) == reflect.TypeOf(make(Done)) { - deprecationTracker.TrackDeprecation(types.Deprecations.Async(), cl) - } -} - -func parseTimeout(timeout ...float64) time.Duration { - if len(timeout) == 0 { - return global.DefaultTimeout - } else { - return time.Duration(timeout[0] * float64(time.Second)) - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go b/vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go deleted file mode 100644 index aa89d6cba8a..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go +++ /dev/null @@ -1,48 +0,0 @@ -package codelocation - -import ( - "regexp" - "runtime" - "runtime/debug" - "strings" - - "github.com/onsi/ginkgo/types" -) - -func New(skip int) types.CodeLocation { - _, file, line, _ := runtime.Caller(skip + 1) - stackTrace := PruneStack(string(debug.Stack()), skip+1) - return types.CodeLocation{FileName: file, LineNumber: line, FullStackTrace: stackTrace} -} - -// PruneStack removes references to functions that are internal to Ginkgo -// and the Go runtime from a stack string and a certain number of stack entries -// at the beginning of the stack. The stack string has the format -// as returned by runtime/debug.Stack. The leading goroutine information is -// optional and always removed if present. Beware that runtime/debug.Stack -// adds itself as first entry, so typically skip must be >= 1 to remove that -// entry. -func PruneStack(fullStackTrace string, skip int) string { - stack := strings.Split(fullStackTrace, "\n") - // Ensure that the even entries are the method names and the - // the odd entries the source code information. - if len(stack) > 0 && strings.HasPrefix(stack[0], "goroutine ") { - // Ignore "goroutine 29 [running]:" line. - stack = stack[1:] - } - // The "+1" is for skipping over the initial entry, which is - // runtime/debug.Stack() itself. - if len(stack) > 2*(skip+1) { - stack = stack[2*(skip+1):] - } - prunedStack := []string{} - re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`) - for i := 0; i < len(stack)/2; i++ { - // We filter out based on the source code file name. - if !re.Match([]byte(stack[i*2+1])) { - prunedStack = append(prunedStack, stack[i*2]) - prunedStack = append(prunedStack, stack[i*2+1]) - } - } - return strings.Join(prunedStack, "\n") -} diff --git a/vendor/github.com/onsi/ginkgo/internal/containernode/container_node.go b/vendor/github.com/onsi/ginkgo/internal/containernode/container_node.go deleted file mode 100644 index 0737746dcfe..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/containernode/container_node.go +++ /dev/null @@ -1,151 +0,0 @@ -package containernode - -import ( - "math/rand" - "sort" - - "github.com/onsi/ginkgo/internal/leafnodes" - "github.com/onsi/ginkgo/types" -) - -type subjectOrContainerNode struct { - containerNode *ContainerNode - subjectNode leafnodes.SubjectNode -} - -func (n subjectOrContainerNode) text() string { - if n.containerNode != nil { - return n.containerNode.Text() - } else { - return n.subjectNode.Text() - } -} - -type CollatedNodes struct { - Containers []*ContainerNode - Subject leafnodes.SubjectNode -} - -type ContainerNode struct { - text string - flag types.FlagType - codeLocation types.CodeLocation - - setupNodes []leafnodes.BasicNode - subjectAndContainerNodes []subjectOrContainerNode -} - -func New(text string, flag types.FlagType, codeLocation types.CodeLocation) *ContainerNode { - return &ContainerNode{ - text: text, - flag: flag, - codeLocation: codeLocation, - } -} - -func (container *ContainerNode) Shuffle(r *rand.Rand) { - sort.Sort(container) - permutation := r.Perm(len(container.subjectAndContainerNodes)) - shuffledNodes := make([]subjectOrContainerNode, len(container.subjectAndContainerNodes)) - for i, j := range permutation { - shuffledNodes[i] = container.subjectAndContainerNodes[j] - } - container.subjectAndContainerNodes = shuffledNodes -} - -func (node *ContainerNode) BackPropagateProgrammaticFocus() bool { - if node.flag == types.FlagTypePending { - return false - } - - shouldUnfocus := false - for _, subjectOrContainerNode := range node.subjectAndContainerNodes { - if subjectOrContainerNode.containerNode != nil { - shouldUnfocus = subjectOrContainerNode.containerNode.BackPropagateProgrammaticFocus() || shouldUnfocus - } else { - shouldUnfocus = (subjectOrContainerNode.subjectNode.Flag() == types.FlagTypeFocused) || shouldUnfocus - } - } - - if shouldUnfocus { - if node.flag == types.FlagTypeFocused { - node.flag = types.FlagTypeNone - } - return true - } - - return node.flag == types.FlagTypeFocused -} - -func (node *ContainerNode) Collate() []CollatedNodes { - return node.collate([]*ContainerNode{}) -} - -func (node *ContainerNode) collate(enclosingContainers []*ContainerNode) []CollatedNodes { - collated := make([]CollatedNodes, 0) - - containers := make([]*ContainerNode, len(enclosingContainers)) - copy(containers, enclosingContainers) - containers = append(containers, node) - - for _, subjectOrContainer := range node.subjectAndContainerNodes { - if subjectOrContainer.containerNode != nil { - collated = append(collated, subjectOrContainer.containerNode.collate(containers)...) - } else { - collated = append(collated, CollatedNodes{ - Containers: containers, - Subject: subjectOrContainer.subjectNode, - }) - } - } - - return collated -} - -func (node *ContainerNode) PushContainerNode(container *ContainerNode) { - node.subjectAndContainerNodes = append(node.subjectAndContainerNodes, subjectOrContainerNode{containerNode: container}) -} - -func (node *ContainerNode) PushSubjectNode(subject leafnodes.SubjectNode) { - node.subjectAndContainerNodes = append(node.subjectAndContainerNodes, subjectOrContainerNode{subjectNode: subject}) -} - -func (node *ContainerNode) PushSetupNode(setupNode leafnodes.BasicNode) { - node.setupNodes = append(node.setupNodes, setupNode) -} - -func (node *ContainerNode) SetupNodesOfType(nodeType types.SpecComponentType) []leafnodes.BasicNode { - nodes := []leafnodes.BasicNode{} - for _, setupNode := range node.setupNodes { - if setupNode.Type() == nodeType { - nodes = append(nodes, setupNode) - } - } - return nodes -} - -func (node *ContainerNode) Text() string { - return node.text -} - -func (node *ContainerNode) CodeLocation() types.CodeLocation { - return node.codeLocation -} - -func (node *ContainerNode) Flag() types.FlagType { - return node.flag -} - -//sort.Interface - -func (node *ContainerNode) Len() int { - return len(node.subjectAndContainerNodes) -} - -func (node *ContainerNode) Less(i, j int) bool { - return node.subjectAndContainerNodes[i].text() < node.subjectAndContainerNodes[j].text() -} - -func (node *ContainerNode) Swap(i, j int) { - node.subjectAndContainerNodes[i], node.subjectAndContainerNodes[j] = node.subjectAndContainerNodes[j], node.subjectAndContainerNodes[i] -} diff --git a/vendor/github.com/onsi/ginkgo/internal/failer/failer.go b/vendor/github.com/onsi/ginkgo/internal/failer/failer.go deleted file mode 100644 index 678ea2514a6..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/failer/failer.go +++ /dev/null @@ -1,92 +0,0 @@ -package failer - -import ( - "fmt" - "sync" - - "github.com/onsi/ginkgo/types" -) - -type Failer struct { - lock *sync.Mutex - failure types.SpecFailure - state types.SpecState -} - -func New() *Failer { - return &Failer{ - lock: &sync.Mutex{}, - state: types.SpecStatePassed, - } -} - -func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) { - f.lock.Lock() - defer f.lock.Unlock() - - if f.state == types.SpecStatePassed { - f.state = types.SpecStatePanicked - f.failure = types.SpecFailure{ - Message: "Test Panicked", - Location: location, - ForwardedPanic: fmt.Sprintf("%v", forwardedPanic), - } - } -} - -func (f *Failer) Timeout(location types.CodeLocation) { - f.lock.Lock() - defer f.lock.Unlock() - - if f.state == types.SpecStatePassed { - f.state = types.SpecStateTimedOut - f.failure = types.SpecFailure{ - Message: "Timed out", - Location: location, - } - } -} - -func (f *Failer) Fail(message string, location types.CodeLocation) { - f.lock.Lock() - defer f.lock.Unlock() - - if f.state == types.SpecStatePassed { - f.state = types.SpecStateFailed - f.failure = types.SpecFailure{ - Message: message, - Location: location, - } - } -} - -func (f *Failer) Drain(componentType types.SpecComponentType, componentIndex int, componentCodeLocation types.CodeLocation) (types.SpecFailure, types.SpecState) { - f.lock.Lock() - defer f.lock.Unlock() - - failure := f.failure - outcome := f.state - if outcome != types.SpecStatePassed { - failure.ComponentType = componentType - failure.ComponentIndex = componentIndex - failure.ComponentCodeLocation = componentCodeLocation - } - - f.state = types.SpecStatePassed - f.failure = types.SpecFailure{} - - return failure, outcome -} - -func (f *Failer) Skip(message string, location types.CodeLocation) { - f.lock.Lock() - defer f.lock.Unlock() - - if f.state == types.SpecStatePassed { - f.state = types.SpecStateSkipped - f.failure = types.SpecFailure{ - Message: message, - Location: location, - } - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/global/init.go b/vendor/github.com/onsi/ginkgo/internal/global/init.go deleted file mode 100644 index 109f617a5e1..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/global/init.go +++ /dev/null @@ -1,22 +0,0 @@ -package global - -import ( - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/internal/suite" -) - -const DefaultTimeout = time.Duration(1 * time.Second) - -var Suite *suite.Suite -var Failer *failer.Failer - -func init() { - InitializeGlobals() -} - -func InitializeGlobals() { - Failer = failer.New() - Suite = suite.New(Failer) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go deleted file mode 100644 index 393901e11c3..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go +++ /dev/null @@ -1,103 +0,0 @@ -package leafnodes - -import ( - "math" - "time" - - "sync" - - "github.com/onsi/ginkgo/types" -) - -type benchmarker struct { - mu sync.Mutex - measurements map[string]*types.SpecMeasurement - orderCounter int -} - -func newBenchmarker() *benchmarker { - return &benchmarker{ - measurements: make(map[string]*types.SpecMeasurement), - } -} - -func (b *benchmarker) Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration) { - t := time.Now() - body() - elapsedTime = time.Since(t) - - b.mu.Lock() - defer b.mu.Unlock() - measurement := b.getMeasurement(name, "Fastest Time", "Slowest Time", "Average Time", "s", 3, info...) - measurement.Results = append(measurement.Results, elapsedTime.Seconds()) - - return -} - -func (b *benchmarker) RecordValue(name string, value float64, info ...interface{}) { - b.mu.Lock() - measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", "", 3, info...) - defer b.mu.Unlock() - measurement.Results = append(measurement.Results, value) -} - -func (b *benchmarker) RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{}) { - b.mu.Lock() - measurement := b.getMeasurement(name, "Smallest", " Largest", " Average", units, precision, info...) - defer b.mu.Unlock() - measurement.Results = append(measurement.Results, value) -} - -func (b *benchmarker) getMeasurement(name string, smallestLabel string, largestLabel string, averageLabel string, units string, precision int, info ...interface{}) *types.SpecMeasurement { - measurement, ok := b.measurements[name] - if !ok { - var computedInfo interface{} - computedInfo = nil - if len(info) > 0 { - computedInfo = info[0] - } - measurement = &types.SpecMeasurement{ - Name: name, - Info: computedInfo, - Order: b.orderCounter, - SmallestLabel: smallestLabel, - LargestLabel: largestLabel, - AverageLabel: averageLabel, - Units: units, - Precision: precision, - Results: make([]float64, 0), - } - b.measurements[name] = measurement - b.orderCounter++ - } - - return measurement -} - -func (b *benchmarker) measurementsReport() map[string]*types.SpecMeasurement { - b.mu.Lock() - defer b.mu.Unlock() - for _, measurement := range b.measurements { - measurement.Smallest = math.MaxFloat64 - measurement.Largest = -math.MaxFloat64 - sum := float64(0) - sumOfSquares := float64(0) - - for _, result := range measurement.Results { - if result > measurement.Largest { - measurement.Largest = result - } - if result < measurement.Smallest { - measurement.Smallest = result - } - sum += result - sumOfSquares += result * result - } - - n := float64(len(measurement.Results)) - measurement.Average = sum / n - measurement.StdDeviation = math.Sqrt(sumOfSquares/n - (sum/n)*(sum/n)) - } - - return b.measurements -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go deleted file mode 100644 index 8c3902d601c..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go +++ /dev/null @@ -1,19 +0,0 @@ -package leafnodes - -import ( - "github.com/onsi/ginkgo/types" -) - -type BasicNode interface { - Type() types.SpecComponentType - Run() (types.SpecState, types.SpecFailure) - CodeLocation() types.CodeLocation -} - -type SubjectNode interface { - BasicNode - - Text() string - Flag() types.FlagType - Samples() int -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go deleted file mode 100644 index 6eded7b763e..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go +++ /dev/null @@ -1,47 +0,0 @@ -package leafnodes - -import ( - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type ItNode struct { - runner *runner - - flag types.FlagType - text string -} - -func NewItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *ItNode { - return &ItNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeIt, componentIndex), - flag: flag, - text: text, - } -} - -func (node *ItNode) Run() (outcome types.SpecState, failure types.SpecFailure) { - return node.runner.run() -} - -func (node *ItNode) Type() types.SpecComponentType { - return types.SpecComponentTypeIt -} - -func (node *ItNode) Text() string { - return node.text -} - -func (node *ItNode) Flag() types.FlagType { - return node.flag -} - -func (node *ItNode) CodeLocation() types.CodeLocation { - return node.runner.codeLocation -} - -func (node *ItNode) Samples() int { - return 1 -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go deleted file mode 100644 index 3ab9a6d5524..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go +++ /dev/null @@ -1,62 +0,0 @@ -package leafnodes - -import ( - "reflect" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type MeasureNode struct { - runner *runner - - text string - flag types.FlagType - samples int - benchmarker *benchmarker -} - -func NewMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int, failer *failer.Failer, componentIndex int) *MeasureNode { - benchmarker := newBenchmarker() - - wrappedBody := func() { - reflect.ValueOf(body).Call([]reflect.Value{reflect.ValueOf(benchmarker)}) - } - - return &MeasureNode{ - runner: newRunner(wrappedBody, codeLocation, 0, failer, types.SpecComponentTypeMeasure, componentIndex), - - text: text, - flag: flag, - samples: samples, - benchmarker: benchmarker, - } -} - -func (node *MeasureNode) Run() (outcome types.SpecState, failure types.SpecFailure) { - return node.runner.run() -} - -func (node *MeasureNode) MeasurementsReport() map[string]*types.SpecMeasurement { - return node.benchmarker.measurementsReport() -} - -func (node *MeasureNode) Type() types.SpecComponentType { - return types.SpecComponentTypeMeasure -} - -func (node *MeasureNode) Text() string { - return node.text -} - -func (node *MeasureNode) Flag() types.FlagType { - return node.flag -} - -func (node *MeasureNode) CodeLocation() types.CodeLocation { - return node.runner.codeLocation -} - -func (node *MeasureNode) Samples() int { - return node.samples -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go deleted file mode 100644 index 16cb66c3e49..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go +++ /dev/null @@ -1,117 +0,0 @@ -package leafnodes - -import ( - "fmt" - "reflect" - "time" - - "github.com/onsi/ginkgo/internal/codelocation" - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type runner struct { - isAsync bool - asyncFunc func(chan<- interface{}) - syncFunc func() - codeLocation types.CodeLocation - timeoutThreshold time.Duration - nodeType types.SpecComponentType - componentIndex int - failer *failer.Failer -} - -func newRunner(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, nodeType types.SpecComponentType, componentIndex int) *runner { - bodyType := reflect.TypeOf(body) - if bodyType.Kind() != reflect.Func { - panic(fmt.Sprintf("Expected a function but got something else at %v", codeLocation)) - } - - runner := &runner{ - codeLocation: codeLocation, - timeoutThreshold: timeout, - failer: failer, - nodeType: nodeType, - componentIndex: componentIndex, - } - - switch bodyType.NumIn() { - case 0: - runner.syncFunc = body.(func()) - return runner - case 1: - if !(bodyType.In(0).Kind() == reflect.Chan && bodyType.In(0).Elem().Kind() == reflect.Interface) { - panic(fmt.Sprintf("Must pass a Done channel to function at %v", codeLocation)) - } - - wrappedBody := func(done chan<- interface{}) { - bodyValue := reflect.ValueOf(body) - bodyValue.Call([]reflect.Value{reflect.ValueOf(done)}) - } - - runner.isAsync = true - runner.asyncFunc = wrappedBody - return runner - } - - panic(fmt.Sprintf("Too many arguments to function at %v", codeLocation)) -} - -func (r *runner) run() (outcome types.SpecState, failure types.SpecFailure) { - if r.isAsync { - return r.runAsync() - } else { - return r.runSync() - } -} - -func (r *runner) runAsync() (outcome types.SpecState, failure types.SpecFailure) { - done := make(chan interface{}, 1) - - go func() { - finished := false - - defer func() { - if e := recover(); e != nil || !finished { - r.failer.Panic(codelocation.New(2), e) - select { - case <-done: - break - default: - close(done) - } - } - }() - - r.asyncFunc(done) - finished = true - }() - - // If this goroutine gets no CPU time before the select block, - // the <-done case may complete even if the test took longer than the timeoutThreshold. - // This can cause flaky behaviour, but we haven't seen it in the wild. - select { - case <-done: - case <-time.After(r.timeoutThreshold): - r.failer.Timeout(r.codeLocation) - } - - failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation) - return -} -func (r *runner) runSync() (outcome types.SpecState, failure types.SpecFailure) { - finished := false - - defer func() { - if e := recover(); e != nil || !finished { - r.failer.Panic(codelocation.New(2), e) - } - - failure, outcome = r.failer.Drain(r.nodeType, r.componentIndex, r.codeLocation) - }() - - r.syncFunc() - finished = true - - return -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go deleted file mode 100644 index e3e9cb7c588..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go +++ /dev/null @@ -1,48 +0,0 @@ -package leafnodes - -import ( - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type SetupNode struct { - runner *runner -} - -func (node *SetupNode) Run() (outcome types.SpecState, failure types.SpecFailure) { - return node.runner.run() -} - -func (node *SetupNode) Type() types.SpecComponentType { - return node.runner.nodeType -} - -func (node *SetupNode) CodeLocation() types.CodeLocation { - return node.runner.codeLocation -} - -func NewBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { - return &SetupNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeEach, componentIndex), - } -} - -func NewAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { - return &SetupNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterEach, componentIndex), - } -} - -func NewJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { - return &SetupNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustBeforeEach, componentIndex), - } -} - -func NewJustAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { - return &SetupNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustAfterEach, componentIndex), - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go deleted file mode 100644 index 80f16ed7861..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go +++ /dev/null @@ -1,55 +0,0 @@ -package leafnodes - -import ( - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type SuiteNode interface { - Run(parallelNode int, parallelTotal int, syncHost string) bool - Passed() bool - Summary() *types.SetupSummary -} - -type simpleSuiteNode struct { - runner *runner - outcome types.SpecState - failure types.SpecFailure - runTime time.Duration -} - -func (node *simpleSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool { - t := time.Now() - node.outcome, node.failure = node.runner.run() - node.runTime = time.Since(t) - - return node.outcome == types.SpecStatePassed -} - -func (node *simpleSuiteNode) Passed() bool { - return node.outcome == types.SpecStatePassed -} - -func (node *simpleSuiteNode) Summary() *types.SetupSummary { - return &types.SetupSummary{ - ComponentType: node.runner.nodeType, - CodeLocation: node.runner.codeLocation, - State: node.outcome, - RunTime: node.runTime, - Failure: node.failure, - } -} - -func NewBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { - return &simpleSuiteNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0), - } -} - -func NewAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { - return &simpleSuiteNode{ - runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go deleted file mode 100644 index a721d0cf7f2..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go +++ /dev/null @@ -1,90 +0,0 @@ -package leafnodes - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type synchronizedAfterSuiteNode struct { - runnerA *runner - runnerB *runner - - outcome types.SpecState - failure types.SpecFailure - runTime time.Duration -} - -func NewSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { - return &synchronizedAfterSuiteNode{ - runnerA: newRunner(bodyA, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), - runnerB: newRunner(bodyB, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0), - } -} - -func (node *synchronizedAfterSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool { - node.outcome, node.failure = node.runnerA.run() - - if parallelNode == 1 { - if parallelTotal > 1 { - node.waitUntilOtherNodesAreDone(syncHost) - } - - outcome, failure := node.runnerB.run() - - if node.outcome == types.SpecStatePassed { - node.outcome, node.failure = outcome, failure - } - } - - return node.outcome == types.SpecStatePassed -} - -func (node *synchronizedAfterSuiteNode) Passed() bool { - return node.outcome == types.SpecStatePassed -} - -func (node *synchronizedAfterSuiteNode) Summary() *types.SetupSummary { - return &types.SetupSummary{ - ComponentType: node.runnerA.nodeType, - CodeLocation: node.runnerA.codeLocation, - State: node.outcome, - RunTime: node.runTime, - Failure: node.failure, - } -} - -func (node *synchronizedAfterSuiteNode) waitUntilOtherNodesAreDone(syncHost string) { - for { - if node.canRun(syncHost) { - return - } - - time.Sleep(50 * time.Millisecond) - } -} - -func (node *synchronizedAfterSuiteNode) canRun(syncHost string) bool { - resp, err := http.Get(syncHost + "/RemoteAfterSuiteData") - if err != nil || resp.StatusCode != http.StatusOK { - return false - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return false - } - resp.Body.Close() - - afterSuiteData := types.RemoteAfterSuiteData{} - err = json.Unmarshal(body, &afterSuiteData) - if err != nil { - return false - } - - return afterSuiteData.CanRun -} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go deleted file mode 100644 index d5c88931940..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go +++ /dev/null @@ -1,181 +0,0 @@ -package leafnodes - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - "reflect" - "time" - - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/types" -) - -type synchronizedBeforeSuiteNode struct { - runnerA *runner - runnerB *runner - - data []byte - - outcome types.SpecState - failure types.SpecFailure - runTime time.Duration -} - -func NewSynchronizedBeforeSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode { - node := &synchronizedBeforeSuiteNode{} - - node.runnerA = newRunner(node.wrapA(bodyA), codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0) - node.runnerB = newRunner(node.wrapB(bodyB), codeLocation, timeout, failer, types.SpecComponentTypeBeforeSuite, 0) - - return node -} - -func (node *synchronizedBeforeSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool { - t := time.Now() - defer func() { - node.runTime = time.Since(t) - }() - - if parallelNode == 1 { - node.outcome, node.failure = node.runA(parallelTotal, syncHost) - } else { - node.outcome, node.failure = node.waitForA(syncHost) - } - - if node.outcome != types.SpecStatePassed { - return false - } - node.outcome, node.failure = node.runnerB.run() - - return node.outcome == types.SpecStatePassed -} - -func (node *synchronizedBeforeSuiteNode) runA(parallelTotal int, syncHost string) (types.SpecState, types.SpecFailure) { - outcome, failure := node.runnerA.run() - - if parallelTotal > 1 { - state := types.RemoteBeforeSuiteStatePassed - if outcome != types.SpecStatePassed { - state = types.RemoteBeforeSuiteStateFailed - } - json := (types.RemoteBeforeSuiteData{ - Data: node.data, - State: state, - }).ToJSON() - http.Post(syncHost+"/BeforeSuiteState", "application/json", bytes.NewBuffer(json)) - } - - return outcome, failure -} - -func (node *synchronizedBeforeSuiteNode) waitForA(syncHost string) (types.SpecState, types.SpecFailure) { - failure := func(message string) types.SpecFailure { - return types.SpecFailure{ - Message: message, - Location: node.runnerA.codeLocation, - ComponentType: node.runnerA.nodeType, - ComponentIndex: node.runnerA.componentIndex, - ComponentCodeLocation: node.runnerA.codeLocation, - } - } - for { - resp, err := http.Get(syncHost + "/BeforeSuiteState") - if err != nil || resp.StatusCode != http.StatusOK { - return types.SpecStateFailed, failure("Failed to fetch BeforeSuite state") - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return types.SpecStateFailed, failure("Failed to read BeforeSuite state") - } - resp.Body.Close() - - beforeSuiteData := types.RemoteBeforeSuiteData{} - err = json.Unmarshal(body, &beforeSuiteData) - if err != nil { - return types.SpecStateFailed, failure("Failed to decode BeforeSuite state") - } - - switch beforeSuiteData.State { - case types.RemoteBeforeSuiteStatePassed: - node.data = beforeSuiteData.Data - return types.SpecStatePassed, types.SpecFailure{} - case types.RemoteBeforeSuiteStateFailed: - return types.SpecStateFailed, failure("BeforeSuite on Node 1 failed") - case types.RemoteBeforeSuiteStateDisappeared: - return types.SpecStateFailed, failure("Node 1 disappeared before completing BeforeSuite") - } - - time.Sleep(50 * time.Millisecond) - } -} - -func (node *synchronizedBeforeSuiteNode) Passed() bool { - return node.outcome == types.SpecStatePassed -} - -func (node *synchronizedBeforeSuiteNode) Summary() *types.SetupSummary { - return &types.SetupSummary{ - ComponentType: node.runnerA.nodeType, - CodeLocation: node.runnerA.codeLocation, - State: node.outcome, - RunTime: node.runTime, - Failure: node.failure, - } -} - -func (node *synchronizedBeforeSuiteNode) wrapA(bodyA interface{}) interface{} { - typeA := reflect.TypeOf(bodyA) - if typeA.Kind() != reflect.Func { - panic("SynchronizedBeforeSuite expects a function as its first argument") - } - - takesNothing := typeA.NumIn() == 0 - takesADoneChannel := typeA.NumIn() == 1 && typeA.In(0).Kind() == reflect.Chan && typeA.In(0).Elem().Kind() == reflect.Interface - returnsBytes := typeA.NumOut() == 1 && typeA.Out(0).Kind() == reflect.Slice && typeA.Out(0).Elem().Kind() == reflect.Uint8 - - if !((takesNothing || takesADoneChannel) && returnsBytes) { - panic("SynchronizedBeforeSuite's first argument should be a function that returns []byte and either takes no arguments or takes a Done channel.") - } - - if takesADoneChannel { - return func(done chan<- interface{}) { - out := reflect.ValueOf(bodyA).Call([]reflect.Value{reflect.ValueOf(done)}) - node.data = out[0].Interface().([]byte) - } - } - - return func() { - out := reflect.ValueOf(bodyA).Call([]reflect.Value{}) - node.data = out[0].Interface().([]byte) - } -} - -func (node *synchronizedBeforeSuiteNode) wrapB(bodyB interface{}) interface{} { - typeB := reflect.TypeOf(bodyB) - if typeB.Kind() != reflect.Func { - panic("SynchronizedBeforeSuite expects a function as its second argument") - } - - returnsNothing := typeB.NumOut() == 0 - takesBytesOnly := typeB.NumIn() == 1 && typeB.In(0).Kind() == reflect.Slice && typeB.In(0).Elem().Kind() == reflect.Uint8 - takesBytesAndDone := typeB.NumIn() == 2 && - typeB.In(0).Kind() == reflect.Slice && typeB.In(0).Elem().Kind() == reflect.Uint8 && - typeB.In(1).Kind() == reflect.Chan && typeB.In(1).Elem().Kind() == reflect.Interface - - if !((takesBytesOnly || takesBytesAndDone) && returnsNothing) { - panic("SynchronizedBeforeSuite's second argument should be a function that returns nothing and either takes []byte or ([]byte, Done)") - } - - if takesBytesAndDone { - return func(done chan<- interface{}) { - reflect.ValueOf(bodyB).Call([]reflect.Value{reflect.ValueOf(node.data), reflect.ValueOf(done)}) - } - } - - return func() { - reflect.ValueOf(bodyB).Call([]reflect.Value{reflect.ValueOf(node.data)}) - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/aggregator.go b/vendor/github.com/onsi/ginkgo/internal/remote/aggregator.go deleted file mode 100644 index 992437d9e0b..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/aggregator.go +++ /dev/null @@ -1,249 +0,0 @@ -/* - -Aggregator is a reporter used by the Ginkgo CLI to aggregate and present parallel test output -coherently as tests complete. You shouldn't need to use this in your code. To run tests in parallel: - - ginkgo -nodes=N - -where N is the number of nodes you desire. -*/ -package remote - -import ( - "time" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/reporters/stenographer" - "github.com/onsi/ginkgo/types" -) - -type configAndSuite struct { - config config.GinkgoConfigType - summary *types.SuiteSummary -} - -type Aggregator struct { - nodeCount int - config config.DefaultReporterConfigType - stenographer stenographer.Stenographer - result chan bool - - suiteBeginnings chan configAndSuite - aggregatedSuiteBeginnings []configAndSuite - - beforeSuites chan *types.SetupSummary - aggregatedBeforeSuites []*types.SetupSummary - - afterSuites chan *types.SetupSummary - aggregatedAfterSuites []*types.SetupSummary - - specCompletions chan *types.SpecSummary - completedSpecs []*types.SpecSummary - - suiteEndings chan *types.SuiteSummary - aggregatedSuiteEndings []*types.SuiteSummary - specs []*types.SpecSummary - - startTime time.Time -} - -func NewAggregator(nodeCount int, result chan bool, config config.DefaultReporterConfigType, stenographer stenographer.Stenographer) *Aggregator { - aggregator := &Aggregator{ - nodeCount: nodeCount, - result: result, - config: config, - stenographer: stenographer, - - suiteBeginnings: make(chan configAndSuite), - beforeSuites: make(chan *types.SetupSummary), - afterSuites: make(chan *types.SetupSummary), - specCompletions: make(chan *types.SpecSummary), - suiteEndings: make(chan *types.SuiteSummary), - } - - go aggregator.mux() - - return aggregator -} - -func (aggregator *Aggregator) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { - aggregator.suiteBeginnings <- configAndSuite{config, summary} -} - -func (aggregator *Aggregator) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - aggregator.beforeSuites <- setupSummary -} - -func (aggregator *Aggregator) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - aggregator.afterSuites <- setupSummary -} - -func (aggregator *Aggregator) SpecWillRun(specSummary *types.SpecSummary) { - //noop -} - -func (aggregator *Aggregator) SpecDidComplete(specSummary *types.SpecSummary) { - aggregator.specCompletions <- specSummary -} - -func (aggregator *Aggregator) SpecSuiteDidEnd(summary *types.SuiteSummary) { - aggregator.suiteEndings <- summary -} - -func (aggregator *Aggregator) mux() { -loop: - for { - select { - case configAndSuite := <-aggregator.suiteBeginnings: - aggregator.registerSuiteBeginning(configAndSuite) - case setupSummary := <-aggregator.beforeSuites: - aggregator.registerBeforeSuite(setupSummary) - case setupSummary := <-aggregator.afterSuites: - aggregator.registerAfterSuite(setupSummary) - case specSummary := <-aggregator.specCompletions: - aggregator.registerSpecCompletion(specSummary) - case suite := <-aggregator.suiteEndings: - finished, passed := aggregator.registerSuiteEnding(suite) - if finished { - aggregator.result <- passed - break loop - } - } - } -} - -func (aggregator *Aggregator) registerSuiteBeginning(configAndSuite configAndSuite) { - aggregator.aggregatedSuiteBeginnings = append(aggregator.aggregatedSuiteBeginnings, configAndSuite) - - if len(aggregator.aggregatedSuiteBeginnings) == 1 { - aggregator.startTime = time.Now() - } - - if len(aggregator.aggregatedSuiteBeginnings) != aggregator.nodeCount { - return - } - - aggregator.stenographer.AnnounceSuite(configAndSuite.summary.SuiteDescription, configAndSuite.config.RandomSeed, configAndSuite.config.RandomizeAllSpecs, aggregator.config.Succinct) - - totalNumberOfSpecs := 0 - if len(aggregator.aggregatedSuiteBeginnings) > 0 { - totalNumberOfSpecs = configAndSuite.summary.NumberOfSpecsBeforeParallelization - } - - aggregator.stenographer.AnnounceTotalNumberOfSpecs(totalNumberOfSpecs, aggregator.config.Succinct) - aggregator.stenographer.AnnounceAggregatedParallelRun(aggregator.nodeCount, aggregator.config.Succinct) - aggregator.flushCompletedSpecs() -} - -func (aggregator *Aggregator) registerBeforeSuite(setupSummary *types.SetupSummary) { - aggregator.aggregatedBeforeSuites = append(aggregator.aggregatedBeforeSuites, setupSummary) - aggregator.flushCompletedSpecs() -} - -func (aggregator *Aggregator) registerAfterSuite(setupSummary *types.SetupSummary) { - aggregator.aggregatedAfterSuites = append(aggregator.aggregatedAfterSuites, setupSummary) - aggregator.flushCompletedSpecs() -} - -func (aggregator *Aggregator) registerSpecCompletion(specSummary *types.SpecSummary) { - aggregator.completedSpecs = append(aggregator.completedSpecs, specSummary) - aggregator.specs = append(aggregator.specs, specSummary) - aggregator.flushCompletedSpecs() -} - -func (aggregator *Aggregator) flushCompletedSpecs() { - if len(aggregator.aggregatedSuiteBeginnings) != aggregator.nodeCount { - return - } - - for _, setupSummary := range aggregator.aggregatedBeforeSuites { - aggregator.announceBeforeSuite(setupSummary) - } - - for _, specSummary := range aggregator.completedSpecs { - aggregator.announceSpec(specSummary) - } - - for _, setupSummary := range aggregator.aggregatedAfterSuites { - aggregator.announceAfterSuite(setupSummary) - } - - aggregator.aggregatedBeforeSuites = []*types.SetupSummary{} - aggregator.completedSpecs = []*types.SpecSummary{} - aggregator.aggregatedAfterSuites = []*types.SetupSummary{} -} - -func (aggregator *Aggregator) announceBeforeSuite(setupSummary *types.SetupSummary) { - aggregator.stenographer.AnnounceCapturedOutput(setupSummary.CapturedOutput) - if setupSummary.State != types.SpecStatePassed { - aggregator.stenographer.AnnounceBeforeSuiteFailure(setupSummary, aggregator.config.Succinct, aggregator.config.FullTrace) - } -} - -func (aggregator *Aggregator) announceAfterSuite(setupSummary *types.SetupSummary) { - aggregator.stenographer.AnnounceCapturedOutput(setupSummary.CapturedOutput) - if setupSummary.State != types.SpecStatePassed { - aggregator.stenographer.AnnounceAfterSuiteFailure(setupSummary, aggregator.config.Succinct, aggregator.config.FullTrace) - } -} - -func (aggregator *Aggregator) announceSpec(specSummary *types.SpecSummary) { - if aggregator.config.Verbose && specSummary.State != types.SpecStatePending && specSummary.State != types.SpecStateSkipped { - aggregator.stenographer.AnnounceSpecWillRun(specSummary) - } - - aggregator.stenographer.AnnounceCapturedOutput(specSummary.CapturedOutput) - - switch specSummary.State { - case types.SpecStatePassed: - if specSummary.IsMeasurement { - aggregator.stenographer.AnnounceSuccessfulMeasurement(specSummary, aggregator.config.Succinct) - } else if specSummary.RunTime.Seconds() >= aggregator.config.SlowSpecThreshold { - aggregator.stenographer.AnnounceSuccessfulSlowSpec(specSummary, aggregator.config.Succinct) - } else { - aggregator.stenographer.AnnounceSuccessfulSpec(specSummary) - } - - case types.SpecStatePending: - aggregator.stenographer.AnnouncePendingSpec(specSummary, aggregator.config.NoisyPendings && !aggregator.config.Succinct) - case types.SpecStateSkipped: - aggregator.stenographer.AnnounceSkippedSpec(specSummary, aggregator.config.Succinct || !aggregator.config.NoisySkippings, aggregator.config.FullTrace) - case types.SpecStateTimedOut: - aggregator.stenographer.AnnounceSpecTimedOut(specSummary, aggregator.config.Succinct, aggregator.config.FullTrace) - case types.SpecStatePanicked: - aggregator.stenographer.AnnounceSpecPanicked(specSummary, aggregator.config.Succinct, aggregator.config.FullTrace) - case types.SpecStateFailed: - aggregator.stenographer.AnnounceSpecFailed(specSummary, aggregator.config.Succinct, aggregator.config.FullTrace) - } -} - -func (aggregator *Aggregator) registerSuiteEnding(suite *types.SuiteSummary) (finished bool, passed bool) { - aggregator.aggregatedSuiteEndings = append(aggregator.aggregatedSuiteEndings, suite) - if len(aggregator.aggregatedSuiteEndings) < aggregator.nodeCount { - return false, false - } - - aggregatedSuiteSummary := &types.SuiteSummary{} - aggregatedSuiteSummary.SuiteSucceeded = true - - for _, suiteSummary := range aggregator.aggregatedSuiteEndings { - if !suiteSummary.SuiteSucceeded { - aggregatedSuiteSummary.SuiteSucceeded = false - } - - aggregatedSuiteSummary.NumberOfSpecsThatWillBeRun += suiteSummary.NumberOfSpecsThatWillBeRun - aggregatedSuiteSummary.NumberOfTotalSpecs += suiteSummary.NumberOfTotalSpecs - aggregatedSuiteSummary.NumberOfPassedSpecs += suiteSummary.NumberOfPassedSpecs - aggregatedSuiteSummary.NumberOfFailedSpecs += suiteSummary.NumberOfFailedSpecs - aggregatedSuiteSummary.NumberOfPendingSpecs += suiteSummary.NumberOfPendingSpecs - aggregatedSuiteSummary.NumberOfSkippedSpecs += suiteSummary.NumberOfSkippedSpecs - aggregatedSuiteSummary.NumberOfFlakedSpecs += suiteSummary.NumberOfFlakedSpecs - } - - aggregatedSuiteSummary.RunTime = time.Since(aggregator.startTime) - - aggregator.stenographer.SummarizeFailures(aggregator.specs) - aggregator.stenographer.AnnounceSpecRunCompletion(aggregatedSuiteSummary, aggregator.config.Succinct) - - return true, aggregatedSuiteSummary.SuiteSucceeded -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go b/vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go deleted file mode 100644 index 284bc62e5e8..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go +++ /dev/null @@ -1,147 +0,0 @@ -package remote - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - - "github.com/onsi/ginkgo/internal/writer" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/reporters/stenographer" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -//An interface to net/http's client to allow the injection of fakes under test -type Poster interface { - Post(url string, bodyType string, body io.Reader) (resp *http.Response, err error) -} - -/* -The ForwardingReporter is a Ginkgo reporter that forwards information to -a Ginkgo remote server. - -When streaming parallel test output, this repoter is automatically installed by Ginkgo. - -This is accomplished by passing in the GINKGO_REMOTE_REPORTING_SERVER environment variable to `go test`, the Ginkgo test runner -detects this environment variable (which should contain the host of the server) and automatically installs a ForwardingReporter -in place of Ginkgo's DefaultReporter. -*/ - -type ForwardingReporter struct { - serverHost string - poster Poster - outputInterceptor OutputInterceptor - debugMode bool - debugFile *os.File - nestedReporter *reporters.DefaultReporter -} - -func NewForwardingReporter(config config.DefaultReporterConfigType, serverHost string, poster Poster, outputInterceptor OutputInterceptor, ginkgoWriter *writer.Writer, debugFile string) *ForwardingReporter { - reporter := &ForwardingReporter{ - serverHost: serverHost, - poster: poster, - outputInterceptor: outputInterceptor, - } - - if debugFile != "" { - var err error - reporter.debugMode = true - reporter.debugFile, err = os.Create(debugFile) - if err != nil { - fmt.Println(err.Error()) - os.Exit(1) - } - - if !config.Verbose { - //if verbose is true then the GinkgoWriter emits to stdout. Don't _also_ redirect GinkgoWriter output as that will result in duplication. - ginkgoWriter.AndRedirectTo(reporter.debugFile) - } - outputInterceptor.StreamTo(reporter.debugFile) //This is not working - - stenographer := stenographer.New(false, true, reporter.debugFile) - config.Succinct = false - config.Verbose = true - config.FullTrace = true - reporter.nestedReporter = reporters.NewDefaultReporter(config, stenographer) - } - - return reporter -} - -func (reporter *ForwardingReporter) post(path string, data interface{}) { - encoded, _ := json.Marshal(data) - buffer := bytes.NewBuffer(encoded) - reporter.poster.Post(reporter.serverHost+path, "application/json", buffer) -} - -func (reporter *ForwardingReporter) SpecSuiteWillBegin(conf config.GinkgoConfigType, summary *types.SuiteSummary) { - data := struct { - Config config.GinkgoConfigType `json:"config"` - Summary *types.SuiteSummary `json:"suite-summary"` - }{ - conf, - summary, - } - - reporter.outputInterceptor.StartInterceptingOutput() - if reporter.debugMode { - reporter.nestedReporter.SpecSuiteWillBegin(conf, summary) - reporter.debugFile.Sync() - } - reporter.post("/SpecSuiteWillBegin", data) -} - -func (reporter *ForwardingReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() - reporter.outputInterceptor.StartInterceptingOutput() - setupSummary.CapturedOutput = output - if reporter.debugMode { - reporter.nestedReporter.BeforeSuiteDidRun(setupSummary) - reporter.debugFile.Sync() - } - reporter.post("/BeforeSuiteDidRun", setupSummary) -} - -func (reporter *ForwardingReporter) SpecWillRun(specSummary *types.SpecSummary) { - if reporter.debugMode { - reporter.nestedReporter.SpecWillRun(specSummary) - reporter.debugFile.Sync() - } - reporter.post("/SpecWillRun", specSummary) -} - -func (reporter *ForwardingReporter) SpecDidComplete(specSummary *types.SpecSummary) { - output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() - reporter.outputInterceptor.StartInterceptingOutput() - specSummary.CapturedOutput = output - if reporter.debugMode { - reporter.nestedReporter.SpecDidComplete(specSummary) - reporter.debugFile.Sync() - } - reporter.post("/SpecDidComplete", specSummary) -} - -func (reporter *ForwardingReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput() - reporter.outputInterceptor.StartInterceptingOutput() - setupSummary.CapturedOutput = output - if reporter.debugMode { - reporter.nestedReporter.AfterSuiteDidRun(setupSummary) - reporter.debugFile.Sync() - } - reporter.post("/AfterSuiteDidRun", setupSummary) -} - -func (reporter *ForwardingReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - reporter.outputInterceptor.StopInterceptingAndReturnOutput() - if reporter.debugMode { - reporter.nestedReporter.SpecSuiteDidEnd(summary) - reporter.debugFile.Sync() - } - reporter.post("/SpecSuiteDidEnd", summary) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor.go deleted file mode 100644 index 5154abe87d5..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor.go +++ /dev/null @@ -1,13 +0,0 @@ -package remote - -import "os" - -/* -The OutputInterceptor is used by the ForwardingReporter to -intercept and capture all stdin and stderr output during a test run. -*/ -type OutputInterceptor interface { - StartInterceptingOutput() error - StopInterceptingAndReturnOutput() (string, error) - StreamTo(*os.File) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go deleted file mode 100644 index 774967db66b..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build freebsd openbsd netbsd dragonfly darwin linux solaris - -package remote - -import ( - "errors" - "io/ioutil" - "os" - - "github.com/nxadm/tail" - "golang.org/x/sys/unix" -) - -func NewOutputInterceptor() OutputInterceptor { - return &outputInterceptor{} -} - -type outputInterceptor struct { - redirectFile *os.File - streamTarget *os.File - intercepting bool - tailer *tail.Tail - doneTailing chan bool -} - -func (interceptor *outputInterceptor) StartInterceptingOutput() error { - if interceptor.intercepting { - return errors.New("Already intercepting output!") - } - interceptor.intercepting = true - - var err error - - interceptor.redirectFile, err = ioutil.TempFile("", "ginkgo-output") - if err != nil { - return err - } - - // This might call Dup3 if the dup2 syscall is not available, e.g. on - // linux/arm64 or linux/riscv64 - unix.Dup2(int(interceptor.redirectFile.Fd()), 1) - unix.Dup2(int(interceptor.redirectFile.Fd()), 2) - - if interceptor.streamTarget != nil { - interceptor.tailer, _ = tail.TailFile(interceptor.redirectFile.Name(), tail.Config{Follow: true}) - interceptor.doneTailing = make(chan bool) - - go func() { - for line := range interceptor.tailer.Lines { - interceptor.streamTarget.Write([]byte(line.Text + "\n")) - } - close(interceptor.doneTailing) - }() - } - - return nil -} - -func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string, error) { - if !interceptor.intercepting { - return "", errors.New("Not intercepting output!") - } - - interceptor.redirectFile.Close() - output, err := ioutil.ReadFile(interceptor.redirectFile.Name()) - os.Remove(interceptor.redirectFile.Name()) - - interceptor.intercepting = false - - if interceptor.streamTarget != nil { - interceptor.tailer.Stop() - interceptor.tailer.Cleanup() - <-interceptor.doneTailing - interceptor.streamTarget.Sync() - } - - return string(output), err -} - -func (interceptor *outputInterceptor) StreamTo(out *os.File) { - interceptor.streamTarget = out -} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_win.go b/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_win.go deleted file mode 100644 index 40c790336cc..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_win.go +++ /dev/null @@ -1,36 +0,0 @@ -// +build windows - -package remote - -import ( - "errors" - "os" -) - -func NewOutputInterceptor() OutputInterceptor { - return &outputInterceptor{} -} - -type outputInterceptor struct { - intercepting bool -} - -func (interceptor *outputInterceptor) StartInterceptingOutput() error { - if interceptor.intercepting { - return errors.New("Already intercepting output!") - } - interceptor.intercepting = true - - // not working on windows... - - return nil -} - -func (interceptor *outputInterceptor) StopInterceptingAndReturnOutput() (string, error) { - // not working on windows... - interceptor.intercepting = false - - return "", nil -} - -func (interceptor *outputInterceptor) StreamTo(*os.File) {} diff --git a/vendor/github.com/onsi/ginkgo/internal/remote/server.go b/vendor/github.com/onsi/ginkgo/internal/remote/server.go deleted file mode 100644 index 93e9dac057d..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/remote/server.go +++ /dev/null @@ -1,224 +0,0 @@ -/* - -The remote package provides the pieces to allow Ginkgo test suites to report to remote listeners. -This is used, primarily, to enable streaming parallel test output but has, in principal, broader applications (e.g. streaming test output to a browser). - -*/ - -package remote - -import ( - "encoding/json" - "io/ioutil" - "net" - "net/http" - "sync" - - "github.com/onsi/ginkgo/internal/spec_iterator" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/types" -) - -/* -Server spins up on an automatically selected port and listens for communication from the forwarding reporter. -It then forwards that communication to attached reporters. -*/ -type Server struct { - listener net.Listener - reporters []reporters.Reporter - alives []func() bool - lock *sync.Mutex - beforeSuiteData types.RemoteBeforeSuiteData - parallelTotal int - counter int -} - -//Create a new server, automatically selecting a port -func NewServer(parallelTotal int) (*Server, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - return &Server{ - listener: listener, - lock: &sync.Mutex{}, - alives: make([]func() bool, parallelTotal), - beforeSuiteData: types.RemoteBeforeSuiteData{Data: nil, State: types.RemoteBeforeSuiteStatePending}, - parallelTotal: parallelTotal, - }, nil -} - -//Start the server. You don't need to `go s.Start()`, just `s.Start()` -func (server *Server) Start() { - httpServer := &http.Server{} - mux := http.NewServeMux() - httpServer.Handler = mux - - //streaming endpoints - mux.HandleFunc("/SpecSuiteWillBegin", server.specSuiteWillBegin) - mux.HandleFunc("/BeforeSuiteDidRun", server.beforeSuiteDidRun) - mux.HandleFunc("/AfterSuiteDidRun", server.afterSuiteDidRun) - mux.HandleFunc("/SpecWillRun", server.specWillRun) - mux.HandleFunc("/SpecDidComplete", server.specDidComplete) - mux.HandleFunc("/SpecSuiteDidEnd", server.specSuiteDidEnd) - - //synchronization endpoints - mux.HandleFunc("/BeforeSuiteState", server.handleBeforeSuiteState) - mux.HandleFunc("/RemoteAfterSuiteData", server.handleRemoteAfterSuiteData) - mux.HandleFunc("/counter", server.handleCounter) - mux.HandleFunc("/has-counter", server.handleHasCounter) //for backward compatibility - - go httpServer.Serve(server.listener) -} - -//Stop the server -func (server *Server) Close() { - server.listener.Close() -} - -//The address the server can be reached it. Pass this into the `ForwardingReporter`. -func (server *Server) Address() string { - return "http://" + server.listener.Addr().String() -} - -// -// Streaming Endpoints -// - -//The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters` -func (server *Server) readAll(request *http.Request) []byte { - defer request.Body.Close() - body, _ := ioutil.ReadAll(request.Body) - return body -} - -func (server *Server) RegisterReporters(reporters ...reporters.Reporter) { - server.reporters = reporters -} - -func (server *Server) specSuiteWillBegin(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - - var data struct { - Config config.GinkgoConfigType `json:"config"` - Summary *types.SuiteSummary `json:"suite-summary"` - } - - json.Unmarshal(body, &data) - - for _, reporter := range server.reporters { - reporter.SpecSuiteWillBegin(data.Config, data.Summary) - } -} - -func (server *Server) beforeSuiteDidRun(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - var setupSummary *types.SetupSummary - json.Unmarshal(body, &setupSummary) - - for _, reporter := range server.reporters { - reporter.BeforeSuiteDidRun(setupSummary) - } -} - -func (server *Server) afterSuiteDidRun(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - var setupSummary *types.SetupSummary - json.Unmarshal(body, &setupSummary) - - for _, reporter := range server.reporters { - reporter.AfterSuiteDidRun(setupSummary) - } -} - -func (server *Server) specWillRun(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - var specSummary *types.SpecSummary - json.Unmarshal(body, &specSummary) - - for _, reporter := range server.reporters { - reporter.SpecWillRun(specSummary) - } -} - -func (server *Server) specDidComplete(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - var specSummary *types.SpecSummary - json.Unmarshal(body, &specSummary) - - for _, reporter := range server.reporters { - reporter.SpecDidComplete(specSummary) - } -} - -func (server *Server) specSuiteDidEnd(writer http.ResponseWriter, request *http.Request) { - body := server.readAll(request) - var suiteSummary *types.SuiteSummary - json.Unmarshal(body, &suiteSummary) - - for _, reporter := range server.reporters { - reporter.SpecSuiteDidEnd(suiteSummary) - } -} - -// -// Synchronization Endpoints -// - -func (server *Server) RegisterAlive(node int, alive func() bool) { - server.lock.Lock() - defer server.lock.Unlock() - server.alives[node-1] = alive -} - -func (server *Server) nodeIsAlive(node int) bool { - server.lock.Lock() - defer server.lock.Unlock() - alive := server.alives[node-1] - if alive == nil { - return true - } - return alive() -} - -func (server *Server) handleBeforeSuiteState(writer http.ResponseWriter, request *http.Request) { - if request.Method == "POST" { - dec := json.NewDecoder(request.Body) - dec.Decode(&(server.beforeSuiteData)) - } else { - beforeSuiteData := server.beforeSuiteData - if beforeSuiteData.State == types.RemoteBeforeSuiteStatePending && !server.nodeIsAlive(1) { - beforeSuiteData.State = types.RemoteBeforeSuiteStateDisappeared - } - enc := json.NewEncoder(writer) - enc.Encode(beforeSuiteData) - } -} - -func (server *Server) handleRemoteAfterSuiteData(writer http.ResponseWriter, request *http.Request) { - afterSuiteData := types.RemoteAfterSuiteData{ - CanRun: true, - } - for i := 2; i <= server.parallelTotal; i++ { - afterSuiteData.CanRun = afterSuiteData.CanRun && !server.nodeIsAlive(i) - } - - enc := json.NewEncoder(writer) - enc.Encode(afterSuiteData) -} - -func (server *Server) handleCounter(writer http.ResponseWriter, request *http.Request) { - c := spec_iterator.Counter{} - server.lock.Lock() - c.Index = server.counter - server.counter++ - server.lock.Unlock() - - json.NewEncoder(writer).Encode(c) -} - -func (server *Server) handleHasCounter(writer http.ResponseWriter, request *http.Request) { - writer.Write([]byte("")) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/spec.go b/vendor/github.com/onsi/ginkgo/internal/spec/spec.go deleted file mode 100644 index 6eef40a0e0c..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec/spec.go +++ /dev/null @@ -1,247 +0,0 @@ -package spec - -import ( - "fmt" - "io" - "time" - - "sync" - - "github.com/onsi/ginkgo/internal/containernode" - "github.com/onsi/ginkgo/internal/leafnodes" - "github.com/onsi/ginkgo/types" -) - -type Spec struct { - subject leafnodes.SubjectNode - focused bool - announceProgress bool - - containers []*containernode.ContainerNode - - state types.SpecState - runTime time.Duration - startTime time.Time - failure types.SpecFailure - previousFailures bool - - stateMutex *sync.Mutex -} - -func New(subject leafnodes.SubjectNode, containers []*containernode.ContainerNode, announceProgress bool) *Spec { - spec := &Spec{ - subject: subject, - containers: containers, - focused: subject.Flag() == types.FlagTypeFocused, - announceProgress: announceProgress, - stateMutex: &sync.Mutex{}, - } - - spec.processFlag(subject.Flag()) - for i := len(containers) - 1; i >= 0; i-- { - spec.processFlag(containers[i].Flag()) - } - - return spec -} - -func (spec *Spec) processFlag(flag types.FlagType) { - if flag == types.FlagTypeFocused { - spec.focused = true - } else if flag == types.FlagTypePending { - spec.setState(types.SpecStatePending) - } -} - -func (spec *Spec) Skip() { - spec.setState(types.SpecStateSkipped) -} - -func (spec *Spec) Failed() bool { - return spec.getState() == types.SpecStateFailed || spec.getState() == types.SpecStatePanicked || spec.getState() == types.SpecStateTimedOut -} - -func (spec *Spec) Passed() bool { - return spec.getState() == types.SpecStatePassed -} - -func (spec *Spec) Flaked() bool { - return spec.getState() == types.SpecStatePassed && spec.previousFailures -} - -func (spec *Spec) Pending() bool { - return spec.getState() == types.SpecStatePending -} - -func (spec *Spec) Skipped() bool { - return spec.getState() == types.SpecStateSkipped -} - -func (spec *Spec) Focused() bool { - return spec.focused -} - -func (spec *Spec) IsMeasurement() bool { - return spec.subject.Type() == types.SpecComponentTypeMeasure -} - -func (spec *Spec) Summary(suiteID string) *types.SpecSummary { - componentTexts := make([]string, len(spec.containers)+1) - componentCodeLocations := make([]types.CodeLocation, len(spec.containers)+1) - - for i, container := range spec.containers { - componentTexts[i] = container.Text() - componentCodeLocations[i] = container.CodeLocation() - } - - componentTexts[len(spec.containers)] = spec.subject.Text() - componentCodeLocations[len(spec.containers)] = spec.subject.CodeLocation() - - runTime := spec.runTime - if runTime == 0 && !spec.startTime.IsZero() { - runTime = time.Since(spec.startTime) - } - - return &types.SpecSummary{ - IsMeasurement: spec.IsMeasurement(), - NumberOfSamples: spec.subject.Samples(), - ComponentTexts: componentTexts, - ComponentCodeLocations: componentCodeLocations, - State: spec.getState(), - RunTime: runTime, - Failure: spec.failure, - Measurements: spec.measurementsReport(), - SuiteID: suiteID, - } -} - -func (spec *Spec) ConcatenatedString() string { - s := "" - for _, container := range spec.containers { - s += container.Text() + " " - } - - return s + spec.subject.Text() -} - -func (spec *Spec) Run(writer io.Writer) { - if spec.getState() == types.SpecStateFailed { - spec.previousFailures = true - } - - spec.startTime = time.Now() - defer func() { - spec.runTime = time.Since(spec.startTime) - }() - - for sample := 0; sample < spec.subject.Samples(); sample++ { - spec.runSample(sample, writer) - - if spec.getState() != types.SpecStatePassed { - return - } - } -} - -func (spec *Spec) getState() types.SpecState { - spec.stateMutex.Lock() - defer spec.stateMutex.Unlock() - return spec.state -} - -func (spec *Spec) setState(state types.SpecState) { - spec.stateMutex.Lock() - defer spec.stateMutex.Unlock() - spec.state = state -} - -func (spec *Spec) runSample(sample int, writer io.Writer) { - spec.setState(types.SpecStatePassed) - spec.failure = types.SpecFailure{} - innerMostContainerIndexToUnwind := -1 - - defer func() { - for i := innerMostContainerIndexToUnwind; i >= 0; i-- { - container := spec.containers[i] - for _, justAfterEach := range container.SetupNodesOfType(types.SpecComponentTypeJustAfterEach) { - spec.announceSetupNode(writer, "JustAfterEach", container, justAfterEach) - justAfterEachState, justAfterEachFailure := justAfterEach.Run() - if justAfterEachState != types.SpecStatePassed && spec.state == types.SpecStatePassed { - spec.state = justAfterEachState - spec.failure = justAfterEachFailure - } - } - } - - for i := innerMostContainerIndexToUnwind; i >= 0; i-- { - container := spec.containers[i] - for _, afterEach := range container.SetupNodesOfType(types.SpecComponentTypeAfterEach) { - spec.announceSetupNode(writer, "AfterEach", container, afterEach) - afterEachState, afterEachFailure := afterEach.Run() - if afterEachState != types.SpecStatePassed && spec.getState() == types.SpecStatePassed { - spec.setState(afterEachState) - spec.failure = afterEachFailure - } - } - } - }() - - for i, container := range spec.containers { - innerMostContainerIndexToUnwind = i - for _, beforeEach := range container.SetupNodesOfType(types.SpecComponentTypeBeforeEach) { - spec.announceSetupNode(writer, "BeforeEach", container, beforeEach) - s, f := beforeEach.Run() - spec.failure = f - spec.setState(s) - if spec.getState() != types.SpecStatePassed { - return - } - } - } - - for _, container := range spec.containers { - for _, justBeforeEach := range container.SetupNodesOfType(types.SpecComponentTypeJustBeforeEach) { - spec.announceSetupNode(writer, "JustBeforeEach", container, justBeforeEach) - s, f := justBeforeEach.Run() - spec.failure = f - spec.setState(s) - if spec.getState() != types.SpecStatePassed { - return - } - } - } - - spec.announceSubject(writer, spec.subject) - s, f := spec.subject.Run() - spec.failure = f - spec.setState(s) -} - -func (spec *Spec) announceSetupNode(writer io.Writer, nodeType string, container *containernode.ContainerNode, setupNode leafnodes.BasicNode) { - if spec.announceProgress { - s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, container.Text(), setupNode.CodeLocation().String()) - writer.Write([]byte(s)) - } -} - -func (spec *Spec) announceSubject(writer io.Writer, subject leafnodes.SubjectNode) { - if spec.announceProgress { - nodeType := "" - switch subject.Type() { - case types.SpecComponentTypeIt: - nodeType = "It" - case types.SpecComponentTypeMeasure: - nodeType = "Measure" - } - s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, subject.Text(), subject.CodeLocation().String()) - writer.Write([]byte(s)) - } -} - -func (spec *Spec) measurementsReport() map[string]*types.SpecMeasurement { - if !spec.IsMeasurement() || spec.Failed() { - return map[string]*types.SpecMeasurement{} - } - - return spec.subject.(*leafnodes.MeasureNode).MeasurementsReport() -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go deleted file mode 100644 index 0a24139fb1c..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go +++ /dev/null @@ -1,144 +0,0 @@ -package spec - -import ( - "math/rand" - "regexp" - "sort" - "strings" -) - -type Specs struct { - specs []*Spec - names []string - - hasProgrammaticFocus bool - RegexScansFilePath bool -} - -func NewSpecs(specs []*Spec) *Specs { - names := make([]string, len(specs)) - for i, spec := range specs { - names[i] = spec.ConcatenatedString() - } - return &Specs{ - specs: specs, - names: names, - } -} - -func (e *Specs) Specs() []*Spec { - return e.specs -} - -func (e *Specs) HasProgrammaticFocus() bool { - return e.hasProgrammaticFocus -} - -func (e *Specs) Shuffle(r *rand.Rand) { - sort.Sort(e) - permutation := r.Perm(len(e.specs)) - shuffledSpecs := make([]*Spec, len(e.specs)) - names := make([]string, len(e.specs)) - for i, j := range permutation { - shuffledSpecs[i] = e.specs[j] - names[i] = e.names[j] - } - e.specs = shuffledSpecs - e.names = names -} - -func (e *Specs) ApplyFocus(description string, focus, skip []string) { - if len(focus)+len(skip) == 0 { - e.applyProgrammaticFocus() - } else { - e.applyRegExpFocusAndSkip(description, focus, skip) - } -} - -func (e *Specs) applyProgrammaticFocus() { - e.hasProgrammaticFocus = false - for _, spec := range e.specs { - if spec.Focused() && !spec.Pending() { - e.hasProgrammaticFocus = true - break - } - } - - if e.hasProgrammaticFocus { - for _, spec := range e.specs { - if !spec.Focused() { - spec.Skip() - } - } - } -} - -// toMatch returns a byte[] to be used by regex matchers. When adding new behaviours to the matching function, -// this is the place which we append to. -func (e *Specs) toMatch(description string, i int) []byte { - if i > len(e.names) { - return nil - } - if e.RegexScansFilePath { - return []byte( - description + " " + - e.names[i] + " " + - e.specs[i].subject.CodeLocation().FileName) - } else { - return []byte( - description + " " + - e.names[i]) - } -} - -func (e *Specs) applyRegExpFocusAndSkip(description string, focus, skip []string) { - var focusFilter, skipFilter *regexp.Regexp - if len(focus) > 0 { - focusFilter = regexp.MustCompile(strings.Join(focus, "|")) - } - if len(skip) > 0 { - skipFilter = regexp.MustCompile(strings.Join(skip, "|")) - } - - for i, spec := range e.specs { - matchesFocus := true - matchesSkip := false - - toMatch := e.toMatch(description, i) - - if focusFilter != nil { - matchesFocus = focusFilter.Match(toMatch) - } - - if skipFilter != nil { - matchesSkip = skipFilter.Match(toMatch) - } - - if !matchesFocus || matchesSkip { - spec.Skip() - } - } -} - -func (e *Specs) SkipMeasurements() { - for _, spec := range e.specs { - if spec.IsMeasurement() { - spec.Skip() - } - } -} - -//sort.Interface - -func (e *Specs) Len() int { - return len(e.specs) -} - -func (e *Specs) Less(i, j int) bool { - return e.names[i] < e.names[j] -} - -func (e *Specs) Swap(i, j int) { - e.names[i], e.names[j] = e.names[j], e.names[i] - e.specs[i], e.specs[j] = e.specs[j], e.specs[i] -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/index_computer.go b/vendor/github.com/onsi/ginkgo/internal/spec_iterator/index_computer.go deleted file mode 100644 index 82272554aa8..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/index_computer.go +++ /dev/null @@ -1,55 +0,0 @@ -package spec_iterator - -func ParallelizedIndexRange(length int, parallelTotal int, parallelNode int) (startIndex int, count int) { - if length == 0 { - return 0, 0 - } - - // We have more nodes than tests. Trivial case. - if parallelTotal >= length { - if parallelNode > length { - return 0, 0 - } else { - return parallelNode - 1, 1 - } - } - - // This is the minimum amount of tests that a node will be required to run - minTestsPerNode := length / parallelTotal - - // This is the maximum amount of tests that a node will be required to run - // The algorithm guarantees that this would be equal to at least the minimum amount - // and at most one more - maxTestsPerNode := minTestsPerNode - if length%parallelTotal != 0 { - maxTestsPerNode++ - } - - // Number of nodes that will have to run the maximum amount of tests per node - numMaxLoadNodes := length % parallelTotal - - // Number of nodes that precede the current node and will have to run the maximum amount of tests per node - var numPrecedingMaxLoadNodes int - if parallelNode > numMaxLoadNodes { - numPrecedingMaxLoadNodes = numMaxLoadNodes - } else { - numPrecedingMaxLoadNodes = parallelNode - 1 - } - - // Number of nodes that precede the current node and will have to run the minimum amount of tests per node - var numPrecedingMinLoadNodes int - if parallelNode <= numMaxLoadNodes { - numPrecedingMinLoadNodes = 0 - } else { - numPrecedingMinLoadNodes = parallelNode - numMaxLoadNodes - 1 - } - - // Evaluate the test start index and number of tests to run - startIndex = numPrecedingMaxLoadNodes*maxTestsPerNode + numPrecedingMinLoadNodes*minTestsPerNode - if parallelNode > numMaxLoadNodes { - count = minTestsPerNode - } else { - count = maxTestsPerNode - } - return -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/parallel_spec_iterator.go b/vendor/github.com/onsi/ginkgo/internal/spec_iterator/parallel_spec_iterator.go deleted file mode 100644 index 99f548bca43..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/parallel_spec_iterator.go +++ /dev/null @@ -1,59 +0,0 @@ -package spec_iterator - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/onsi/ginkgo/internal/spec" -) - -type ParallelIterator struct { - specs []*spec.Spec - host string - client *http.Client -} - -func NewParallelIterator(specs []*spec.Spec, host string) *ParallelIterator { - return &ParallelIterator{ - specs: specs, - host: host, - client: &http.Client{}, - } -} - -func (s *ParallelIterator) Next() (*spec.Spec, error) { - resp, err := s.client.Get(s.host + "/counter") - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) - } - - var counter Counter - err = json.NewDecoder(resp.Body).Decode(&counter) - if err != nil { - return nil, err - } - - if counter.Index >= len(s.specs) { - return nil, ErrClosed - } - - return s.specs[counter.Index], nil -} - -func (s *ParallelIterator) NumberOfSpecsPriorToIteration() int { - return len(s.specs) -} - -func (s *ParallelIterator) NumberOfSpecsToProcessIfKnown() (int, bool) { - return -1, false -} - -func (s *ParallelIterator) NumberOfSpecsThatWillBeRunIfKnown() (int, bool) { - return -1, false -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/serial_spec_iterator.go b/vendor/github.com/onsi/ginkgo/internal/spec_iterator/serial_spec_iterator.go deleted file mode 100644 index a51c93b8b61..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/serial_spec_iterator.go +++ /dev/null @@ -1,45 +0,0 @@ -package spec_iterator - -import ( - "github.com/onsi/ginkgo/internal/spec" -) - -type SerialIterator struct { - specs []*spec.Spec - index int -} - -func NewSerialIterator(specs []*spec.Spec) *SerialIterator { - return &SerialIterator{ - specs: specs, - index: 0, - } -} - -func (s *SerialIterator) Next() (*spec.Spec, error) { - if s.index >= len(s.specs) { - return nil, ErrClosed - } - - spec := s.specs[s.index] - s.index += 1 - return spec, nil -} - -func (s *SerialIterator) NumberOfSpecsPriorToIteration() int { - return len(s.specs) -} - -func (s *SerialIterator) NumberOfSpecsToProcessIfKnown() (int, bool) { - return len(s.specs), true -} - -func (s *SerialIterator) NumberOfSpecsThatWillBeRunIfKnown() (int, bool) { - count := 0 - for _, s := range s.specs { - if !s.Skipped() && !s.Pending() { - count += 1 - } - } - return count, true -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/sharded_parallel_spec_iterator.go b/vendor/github.com/onsi/ginkgo/internal/spec_iterator/sharded_parallel_spec_iterator.go deleted file mode 100644 index ad4a3ea3c64..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/sharded_parallel_spec_iterator.go +++ /dev/null @@ -1,47 +0,0 @@ -package spec_iterator - -import "github.com/onsi/ginkgo/internal/spec" - -type ShardedParallelIterator struct { - specs []*spec.Spec - index int - maxIndex int -} - -func NewShardedParallelIterator(specs []*spec.Spec, total int, node int) *ShardedParallelIterator { - startIndex, count := ParallelizedIndexRange(len(specs), total, node) - - return &ShardedParallelIterator{ - specs: specs, - index: startIndex, - maxIndex: startIndex + count, - } -} - -func (s *ShardedParallelIterator) Next() (*spec.Spec, error) { - if s.index >= s.maxIndex { - return nil, ErrClosed - } - - spec := s.specs[s.index] - s.index += 1 - return spec, nil -} - -func (s *ShardedParallelIterator) NumberOfSpecsPriorToIteration() int { - return len(s.specs) -} - -func (s *ShardedParallelIterator) NumberOfSpecsToProcessIfKnown() (int, bool) { - return s.maxIndex - s.index, true -} - -func (s *ShardedParallelIterator) NumberOfSpecsThatWillBeRunIfKnown() (int, bool) { - count := 0 - for i := s.index; i < s.maxIndex; i += 1 { - if !s.specs[i].Skipped() && !s.specs[i].Pending() { - count += 1 - } - } - return count, true -} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/spec_iterator.go b/vendor/github.com/onsi/ginkgo/internal/spec_iterator/spec_iterator.go deleted file mode 100644 index 74bffad6464..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/spec_iterator/spec_iterator.go +++ /dev/null @@ -1,20 +0,0 @@ -package spec_iterator - -import ( - "errors" - - "github.com/onsi/ginkgo/internal/spec" -) - -var ErrClosed = errors.New("no more specs to run") - -type SpecIterator interface { - Next() (*spec.Spec, error) - NumberOfSpecsPriorToIteration() int - NumberOfSpecsToProcessIfKnown() (int, bool) - NumberOfSpecsThatWillBeRunIfKnown() (int, bool) -} - -type Counter struct { - Index int `json:"index"` -} diff --git a/vendor/github.com/onsi/ginkgo/internal/specrunner/random_id.go b/vendor/github.com/onsi/ginkgo/internal/specrunner/random_id.go deleted file mode 100644 index a0b8b62d525..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/specrunner/random_id.go +++ /dev/null @@ -1,15 +0,0 @@ -package specrunner - -import ( - "crypto/rand" - "fmt" -) - -func randomID() string { - b := make([]byte, 8) - _, err := rand.Read(b) - if err != nil { - return "" - } - return fmt.Sprintf("%x-%x-%x-%x", b[0:2], b[2:4], b[4:6], b[6:8]) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go b/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go deleted file mode 100644 index c9a0a60d84c..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go +++ /dev/null @@ -1,411 +0,0 @@ -package specrunner - -import ( - "fmt" - "os" - "os/signal" - "sync" - "syscall" - - "github.com/onsi/ginkgo/internal/spec_iterator" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/internal/leafnodes" - "github.com/onsi/ginkgo/internal/spec" - Writer "github.com/onsi/ginkgo/internal/writer" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/types" - - "time" -) - -type SpecRunner struct { - description string - beforeSuiteNode leafnodes.SuiteNode - iterator spec_iterator.SpecIterator - afterSuiteNode leafnodes.SuiteNode - reporters []reporters.Reporter - startTime time.Time - suiteID string - runningSpec *spec.Spec - writer Writer.WriterInterface - config config.GinkgoConfigType - interrupted bool - processedSpecs []*spec.Spec - lock *sync.Mutex -} - -func New(description string, beforeSuiteNode leafnodes.SuiteNode, iterator spec_iterator.SpecIterator, afterSuiteNode leafnodes.SuiteNode, reporters []reporters.Reporter, writer Writer.WriterInterface, config config.GinkgoConfigType) *SpecRunner { - return &SpecRunner{ - description: description, - beforeSuiteNode: beforeSuiteNode, - iterator: iterator, - afterSuiteNode: afterSuiteNode, - reporters: reporters, - writer: writer, - config: config, - suiteID: randomID(), - lock: &sync.Mutex{}, - } -} - -func (runner *SpecRunner) Run() bool { - if runner.config.DryRun { - runner.performDryRun() - return true - } - - runner.reportSuiteWillBegin() - signalRegistered := make(chan struct{}) - go runner.registerForInterrupts(signalRegistered) - <-signalRegistered - - suitePassed := runner.runBeforeSuite() - - if suitePassed { - suitePassed = runner.runSpecs() - } - - runner.blockForeverIfInterrupted() - - suitePassed = runner.runAfterSuite() && suitePassed - - runner.reportSuiteDidEnd(suitePassed) - - return suitePassed -} - -func (runner *SpecRunner) performDryRun() { - runner.reportSuiteWillBegin() - - if runner.beforeSuiteNode != nil { - summary := runner.beforeSuiteNode.Summary() - summary.State = types.SpecStatePassed - runner.reportBeforeSuite(summary) - } - - for { - spec, err := runner.iterator.Next() - if err == spec_iterator.ErrClosed { - break - } - if err != nil { - fmt.Println("failed to iterate over tests:\n" + err.Error()) - break - } - - runner.processedSpecs = append(runner.processedSpecs, spec) - - summary := spec.Summary(runner.suiteID) - runner.reportSpecWillRun(summary) - if summary.State == types.SpecStateInvalid { - summary.State = types.SpecStatePassed - } - runner.reportSpecDidComplete(summary, false) - } - - if runner.afterSuiteNode != nil { - summary := runner.afterSuiteNode.Summary() - summary.State = types.SpecStatePassed - runner.reportAfterSuite(summary) - } - - runner.reportSuiteDidEnd(true) -} - -func (runner *SpecRunner) runBeforeSuite() bool { - if runner.beforeSuiteNode == nil || runner.wasInterrupted() { - return true - } - - runner.writer.Truncate() - conf := runner.config - passed := runner.beforeSuiteNode.Run(conf.ParallelNode, conf.ParallelTotal, conf.SyncHost) - if !passed { - runner.writer.DumpOut() - } - runner.reportBeforeSuite(runner.beforeSuiteNode.Summary()) - return passed -} - -func (runner *SpecRunner) runAfterSuite() bool { - if runner.afterSuiteNode == nil { - return true - } - - runner.writer.Truncate() - conf := runner.config - passed := runner.afterSuiteNode.Run(conf.ParallelNode, conf.ParallelTotal, conf.SyncHost) - if !passed { - runner.writer.DumpOut() - } - runner.reportAfterSuite(runner.afterSuiteNode.Summary()) - return passed -} - -func (runner *SpecRunner) runSpecs() bool { - suiteFailed := false - skipRemainingSpecs := false - for { - spec, err := runner.iterator.Next() - if err == spec_iterator.ErrClosed { - break - } - if err != nil { - fmt.Println("failed to iterate over tests:\n" + err.Error()) - suiteFailed = true - break - } - - runner.processedSpecs = append(runner.processedSpecs, spec) - - if runner.wasInterrupted() { - break - } - if skipRemainingSpecs { - spec.Skip() - } - - if !spec.Skipped() && !spec.Pending() { - if passed := runner.runSpec(spec); !passed { - suiteFailed = true - } - } else if spec.Pending() && runner.config.FailOnPending { - runner.reportSpecWillRun(spec.Summary(runner.suiteID)) - suiteFailed = true - runner.reportSpecDidComplete(spec.Summary(runner.suiteID), spec.Failed()) - } else { - runner.reportSpecWillRun(spec.Summary(runner.suiteID)) - runner.reportSpecDidComplete(spec.Summary(runner.suiteID), spec.Failed()) - } - - if spec.Failed() && runner.config.FailFast { - skipRemainingSpecs = true - } - } - - return !suiteFailed -} - -func (runner *SpecRunner) runSpec(spec *spec.Spec) (passed bool) { - maxAttempts := 1 - if runner.config.FlakeAttempts > 0 { - // uninitialized configs count as 1 - maxAttempts = runner.config.FlakeAttempts - } - - for i := 0; i < maxAttempts; i++ { - runner.reportSpecWillRun(spec.Summary(runner.suiteID)) - runner.runningSpec = spec - spec.Run(runner.writer) - runner.runningSpec = nil - runner.reportSpecDidComplete(spec.Summary(runner.suiteID), spec.Failed()) - if !spec.Failed() { - return true - } - } - return false -} - -func (runner *SpecRunner) CurrentSpecSummary() (*types.SpecSummary, bool) { - if runner.runningSpec == nil { - return nil, false - } - - return runner.runningSpec.Summary(runner.suiteID), true -} - -func (runner *SpecRunner) registerForInterrupts(signalRegistered chan struct{}) { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) - close(signalRegistered) - - <-c - signal.Stop(c) - runner.markInterrupted() - go runner.registerForHardInterrupts() - runner.writer.DumpOutWithHeader(` -Received interrupt. Emitting contents of GinkgoWriter... ---------------------------------------------------------- -`) - if runner.afterSuiteNode != nil { - fmt.Fprint(os.Stderr, ` ---------------------------------------------------------- -Received interrupt. Running AfterSuite... -^C again to terminate immediately -`) - runner.runAfterSuite() - } - runner.reportSuiteDidEnd(false) - os.Exit(1) -} - -func (runner *SpecRunner) registerForHardInterrupts() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) - - <-c - fmt.Fprintln(os.Stderr, "\nReceived second interrupt. Shutting down.") - os.Exit(1) -} - -func (runner *SpecRunner) blockForeverIfInterrupted() { - runner.lock.Lock() - interrupted := runner.interrupted - runner.lock.Unlock() - - if interrupted { - select {} - } -} - -func (runner *SpecRunner) markInterrupted() { - runner.lock.Lock() - defer runner.lock.Unlock() - runner.interrupted = true -} - -func (runner *SpecRunner) wasInterrupted() bool { - runner.lock.Lock() - defer runner.lock.Unlock() - return runner.interrupted -} - -func (runner *SpecRunner) reportSuiteWillBegin() { - runner.startTime = time.Now() - summary := runner.suiteWillBeginSummary() - for _, reporter := range runner.reporters { - reporter.SpecSuiteWillBegin(runner.config, summary) - } -} - -func (runner *SpecRunner) reportBeforeSuite(summary *types.SetupSummary) { - for _, reporter := range runner.reporters { - reporter.BeforeSuiteDidRun(summary) - } -} - -func (runner *SpecRunner) reportAfterSuite(summary *types.SetupSummary) { - for _, reporter := range runner.reporters { - reporter.AfterSuiteDidRun(summary) - } -} - -func (runner *SpecRunner) reportSpecWillRun(summary *types.SpecSummary) { - runner.writer.Truncate() - - for _, reporter := range runner.reporters { - reporter.SpecWillRun(summary) - } -} - -func (runner *SpecRunner) reportSpecDidComplete(summary *types.SpecSummary, failed bool) { - if len(summary.CapturedOutput) == 0 { - summary.CapturedOutput = string(runner.writer.Bytes()) - } - for i := len(runner.reporters) - 1; i >= 1; i-- { - runner.reporters[i].SpecDidComplete(summary) - } - - if failed { - runner.writer.DumpOut() - } - - runner.reporters[0].SpecDidComplete(summary) -} - -func (runner *SpecRunner) reportSuiteDidEnd(success bool) { - summary := runner.suiteDidEndSummary(success) - summary.RunTime = time.Since(runner.startTime) - for _, reporter := range runner.reporters { - reporter.SpecSuiteDidEnd(summary) - } -} - -func (runner *SpecRunner) countSpecsThatRanSatisfying(filter func(ex *spec.Spec) bool) (count int) { - count = 0 - - for _, spec := range runner.processedSpecs { - if filter(spec) { - count++ - } - } - - return count -} - -func (runner *SpecRunner) suiteDidEndSummary(success bool) *types.SuiteSummary { - numberOfSpecsThatWillBeRun := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return !ex.Skipped() && !ex.Pending() - }) - - numberOfPendingSpecs := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return ex.Pending() - }) - - numberOfSkippedSpecs := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return ex.Skipped() - }) - - numberOfPassedSpecs := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return ex.Passed() - }) - - numberOfFlakedSpecs := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return ex.Flaked() - }) - - numberOfFailedSpecs := runner.countSpecsThatRanSatisfying(func(ex *spec.Spec) bool { - return ex.Failed() - }) - - if runner.beforeSuiteNode != nil && !runner.beforeSuiteNode.Passed() && !runner.config.DryRun { - var known bool - numberOfSpecsThatWillBeRun, known = runner.iterator.NumberOfSpecsThatWillBeRunIfKnown() - if !known { - numberOfSpecsThatWillBeRun = runner.iterator.NumberOfSpecsPriorToIteration() - } - numberOfFailedSpecs = numberOfSpecsThatWillBeRun - } - - return &types.SuiteSummary{ - SuiteDescription: runner.description, - SuiteSucceeded: success, - SuiteID: runner.suiteID, - - NumberOfSpecsBeforeParallelization: runner.iterator.NumberOfSpecsPriorToIteration(), - NumberOfTotalSpecs: len(runner.processedSpecs), - NumberOfSpecsThatWillBeRun: numberOfSpecsThatWillBeRun, - NumberOfPendingSpecs: numberOfPendingSpecs, - NumberOfSkippedSpecs: numberOfSkippedSpecs, - NumberOfPassedSpecs: numberOfPassedSpecs, - NumberOfFailedSpecs: numberOfFailedSpecs, - NumberOfFlakedSpecs: numberOfFlakedSpecs, - } -} - -func (runner *SpecRunner) suiteWillBeginSummary() *types.SuiteSummary { - numTotal, known := runner.iterator.NumberOfSpecsToProcessIfKnown() - if !known { - numTotal = -1 - } - - numToRun, known := runner.iterator.NumberOfSpecsThatWillBeRunIfKnown() - if !known { - numToRun = -1 - } - - return &types.SuiteSummary{ - SuiteDescription: runner.description, - SuiteID: runner.suiteID, - - NumberOfSpecsBeforeParallelization: runner.iterator.NumberOfSpecsPriorToIteration(), - NumberOfTotalSpecs: numTotal, - NumberOfSpecsThatWillBeRun: numToRun, - NumberOfPendingSpecs: -1, - NumberOfSkippedSpecs: -1, - NumberOfPassedSpecs: -1, - NumberOfFailedSpecs: -1, - NumberOfFlakedSpecs: -1, - } -} diff --git a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go deleted file mode 100644 index b4a83c432dd..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go +++ /dev/null @@ -1,227 +0,0 @@ -package suite - -import ( - "math/rand" - "net/http" - "time" - - "github.com/onsi/ginkgo/internal/spec_iterator" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/internal/containernode" - "github.com/onsi/ginkgo/internal/failer" - "github.com/onsi/ginkgo/internal/leafnodes" - "github.com/onsi/ginkgo/internal/spec" - "github.com/onsi/ginkgo/internal/specrunner" - "github.com/onsi/ginkgo/internal/writer" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/types" -) - -type ginkgoTestingT interface { - Fail() -} - -type deferredContainerNode struct { - text string - body func() - flag types.FlagType - codeLocation types.CodeLocation -} - -type Suite struct { - topLevelContainer *containernode.ContainerNode - currentContainer *containernode.ContainerNode - - deferredContainerNodes []deferredContainerNode - - containerIndex int - beforeSuiteNode leafnodes.SuiteNode - afterSuiteNode leafnodes.SuiteNode - runner *specrunner.SpecRunner - failer *failer.Failer - running bool - expandTopLevelNodes bool -} - -func New(failer *failer.Failer) *Suite { - topLevelContainer := containernode.New("[Top Level]", types.FlagTypeNone, types.CodeLocation{}) - - return &Suite{ - topLevelContainer: topLevelContainer, - currentContainer: topLevelContainer, - failer: failer, - containerIndex: 1, - deferredContainerNodes: []deferredContainerNode{}, - } -} - -func (suite *Suite) Run(t ginkgoTestingT, description string, reporters []reporters.Reporter, writer writer.WriterInterface, config config.GinkgoConfigType) (bool, bool) { - if config.ParallelTotal < 1 { - panic("ginkgo.parallel.total must be >= 1") - } - - if config.ParallelNode > config.ParallelTotal || config.ParallelNode < 1 { - panic("ginkgo.parallel.node is one-indexed and must be <= ginkgo.parallel.total") - } - - suite.expandTopLevelNodes = true - for _, deferredNode := range suite.deferredContainerNodes { - suite.PushContainerNode(deferredNode.text, deferredNode.body, deferredNode.flag, deferredNode.codeLocation) - } - - r := rand.New(rand.NewSource(config.RandomSeed)) - suite.topLevelContainer.Shuffle(r) - iterator, hasProgrammaticFocus := suite.generateSpecsIterator(description, config) - suite.runner = specrunner.New(description, suite.beforeSuiteNode, iterator, suite.afterSuiteNode, reporters, writer, config) - - suite.running = true - success := suite.runner.Run() - if !success { - t.Fail() - } - return success, hasProgrammaticFocus -} - -func (suite *Suite) generateSpecsIterator(description string, config config.GinkgoConfigType) (spec_iterator.SpecIterator, bool) { - specsSlice := []*spec.Spec{} - suite.topLevelContainer.BackPropagateProgrammaticFocus() - for _, collatedNodes := range suite.topLevelContainer.Collate() { - specsSlice = append(specsSlice, spec.New(collatedNodes.Subject, collatedNodes.Containers, config.EmitSpecProgress)) - } - - specs := spec.NewSpecs(specsSlice) - specs.RegexScansFilePath = config.RegexScansFilePath - - if config.RandomizeAllSpecs { - specs.Shuffle(rand.New(rand.NewSource(config.RandomSeed))) - } - - specs.ApplyFocus(description, config.FocusStrings, config.SkipStrings) - - if config.SkipMeasurements { - specs.SkipMeasurements() - } - - var iterator spec_iterator.SpecIterator - - if config.ParallelTotal > 1 { - iterator = spec_iterator.NewParallelIterator(specs.Specs(), config.SyncHost) - resp, err := http.Get(config.SyncHost + "/has-counter") - if err != nil || resp.StatusCode != http.StatusOK { - iterator = spec_iterator.NewShardedParallelIterator(specs.Specs(), config.ParallelTotal, config.ParallelNode) - } - } else { - iterator = spec_iterator.NewSerialIterator(specs.Specs()) - } - - return iterator, specs.HasProgrammaticFocus() -} - -func (suite *Suite) CurrentRunningSpecSummary() (*types.SpecSummary, bool) { - if !suite.running { - return nil, false - } - return suite.runner.CurrentSpecSummary() -} - -func (suite *Suite) SetBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.beforeSuiteNode != nil { - panic("You may only call BeforeSuite once!") - } - suite.beforeSuiteNode = leafnodes.NewBeforeSuiteNode(body, codeLocation, timeout, suite.failer) -} - -func (suite *Suite) SetAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.afterSuiteNode != nil { - panic("You may only call AfterSuite once!") - } - suite.afterSuiteNode = leafnodes.NewAfterSuiteNode(body, codeLocation, timeout, suite.failer) -} - -func (suite *Suite) SetSynchronizedBeforeSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.beforeSuiteNode != nil { - panic("You may only call BeforeSuite once!") - } - suite.beforeSuiteNode = leafnodes.NewSynchronizedBeforeSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer) -} - -func (suite *Suite) SetSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.afterSuiteNode != nil { - panic("You may only call AfterSuite once!") - } - suite.afterSuiteNode = leafnodes.NewSynchronizedAfterSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer) -} - -func (suite *Suite) PushContainerNode(text string, body func(), flag types.FlagType, codeLocation types.CodeLocation) { - /* - We defer walking the container nodes (which immediately evaluates the `body` function) - until `RunSpecs` is called. We do this by storing off the deferred container nodes. Then, when - `RunSpecs` is called we actually go through and add the container nodes to the test structure. - - This allows us to defer calling all the `body` functions until _after_ the top level functions - have been walked, _after_ func init()s have been called, and _after_ `go test` has called `flag.Parse()`. - - This allows users to load up configuration information in the `TestX` go test hook just before `RunSpecs` - is invoked and solves issues like #693 and makes the lifecycle easier to reason about. - - */ - if !suite.expandTopLevelNodes { - suite.deferredContainerNodes = append(suite.deferredContainerNodes, deferredContainerNode{text, body, flag, codeLocation}) - return - } - - container := containernode.New(text, flag, codeLocation) - suite.currentContainer.PushContainerNode(container) - - previousContainer := suite.currentContainer - suite.currentContainer = container - suite.containerIndex++ - - body() - - suite.containerIndex-- - suite.currentContainer = previousContainer -} - -func (suite *Suite) PushItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.running { - suite.failer.Fail("You may only call It from within a Describe, Context or When", codeLocation) - } - suite.currentContainer.PushSubjectNode(leafnodes.NewItNode(text, body, flag, codeLocation, timeout, suite.failer, suite.containerIndex)) -} - -func (suite *Suite) PushMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int) { - if suite.running { - suite.failer.Fail("You may only call Measure from within a Describe, Context or When", codeLocation) - } - suite.currentContainer.PushSubjectNode(leafnodes.NewMeasureNode(text, body, flag, codeLocation, samples, suite.failer, suite.containerIndex)) -} - -func (suite *Suite) PushBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.running { - suite.failer.Fail("You may only call BeforeEach from within a Describe, Context or When", codeLocation) - } - suite.currentContainer.PushSetupNode(leafnodes.NewBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) -} - -func (suite *Suite) PushJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.running { - suite.failer.Fail("You may only call JustBeforeEach from within a Describe, Context or When", codeLocation) - } - suite.currentContainer.PushSetupNode(leafnodes.NewJustBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) -} - -func (suite *Suite) PushJustAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.running { - suite.failer.Fail("You may only call JustAfterEach from within a Describe or Context", codeLocation) - } - suite.currentContainer.PushSetupNode(leafnodes.NewJustAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) -} - -func (suite *Suite) PushAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { - if suite.running { - suite.failer.Fail("You may only call AfterEach from within a Describe, Context or When", codeLocation) - } - suite.currentContainer.PushSetupNode(leafnodes.NewAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) -} diff --git a/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go deleted file mode 100644 index 4dcfaf4cd88..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go +++ /dev/null @@ -1,109 +0,0 @@ -package testingtproxy - -import ( - "fmt" - "io" -) - -type failFunc func(message string, callerSkip ...int) -type skipFunc func(message string, callerSkip ...int) -type failedFunc func() bool -type nameFunc func() string - -func New(writer io.Writer, fail failFunc, skip skipFunc, failed failedFunc, name nameFunc, offset int) *ginkgoTestingTProxy { - return &ginkgoTestingTProxy{ - fail: fail, - offset: offset, - writer: writer, - skip: skip, - failed: failed, - name: name, - } -} - -type ginkgoTestingTProxy struct { - fail failFunc - skip skipFunc - failed failedFunc - name nameFunc - offset int - writer io.Writer -} - -func (t *ginkgoTestingTProxy) Cleanup(func()) { - // No-op -} - -func (t *ginkgoTestingTProxy) Setenv(kev, value string) { - fmt.Println("Setenv is a noop for Ginkgo at the moment but will be implemented in V2") - // No-op until Cleanup is implemented -} - -func (t *ginkgoTestingTProxy) Error(args ...interface{}) { - t.fail(fmt.Sprintln(args...), t.offset) -} - -func (t *ginkgoTestingTProxy) Errorf(format string, args ...interface{}) { - t.fail(fmt.Sprintf(format, args...), t.offset) -} - -func (t *ginkgoTestingTProxy) Fail() { - t.fail("failed", t.offset) -} - -func (t *ginkgoTestingTProxy) FailNow() { - t.fail("failed", t.offset) -} - -func (t *ginkgoTestingTProxy) Failed() bool { - return t.failed() -} - -func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) { - t.fail(fmt.Sprintln(args...), t.offset) -} - -func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) { - t.fail(fmt.Sprintf(format, args...), t.offset) -} - -func (t *ginkgoTestingTProxy) Helper() { - // No-op -} - -func (t *ginkgoTestingTProxy) Log(args ...interface{}) { - fmt.Fprintln(t.writer, args...) -} - -func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) { - t.Log(fmt.Sprintf(format, args...)) -} - -func (t *ginkgoTestingTProxy) Name() string { - return t.name() -} - -func (t *ginkgoTestingTProxy) Parallel() { - // No-op -} - -func (t *ginkgoTestingTProxy) Skip(args ...interface{}) { - t.skip(fmt.Sprintln(args...), t.offset) -} - -func (t *ginkgoTestingTProxy) SkipNow() { - t.skip("skip", t.offset) -} - -func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) { - t.skip(fmt.Sprintf(format, args...), t.offset) -} - -func (t *ginkgoTestingTProxy) Skipped() bool { - return false -} - -func (t *ginkgoTestingTProxy) TempDir() string { - // No-op - return "" -} diff --git a/vendor/github.com/onsi/ginkgo/internal/writer/fake_writer.go b/vendor/github.com/onsi/ginkgo/internal/writer/fake_writer.go deleted file mode 100644 index 6739c3f605e..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/writer/fake_writer.go +++ /dev/null @@ -1,36 +0,0 @@ -package writer - -type FakeGinkgoWriter struct { - EventStream []string -} - -func NewFake() *FakeGinkgoWriter { - return &FakeGinkgoWriter{ - EventStream: []string{}, - } -} - -func (writer *FakeGinkgoWriter) AddEvent(event string) { - writer.EventStream = append(writer.EventStream, event) -} - -func (writer *FakeGinkgoWriter) Truncate() { - writer.EventStream = append(writer.EventStream, "TRUNCATE") -} - -func (writer *FakeGinkgoWriter) DumpOut() { - writer.EventStream = append(writer.EventStream, "DUMP") -} - -func (writer *FakeGinkgoWriter) DumpOutWithHeader(header string) { - writer.EventStream = append(writer.EventStream, "DUMP_WITH_HEADER: "+header) -} - -func (writer *FakeGinkgoWriter) Bytes() []byte { - writer.EventStream = append(writer.EventStream, "BYTES") - return nil -} - -func (writer *FakeGinkgoWriter) Write(data []byte) (n int, err error) { - return 0, nil -} diff --git a/vendor/github.com/onsi/ginkgo/internal/writer/writer.go b/vendor/github.com/onsi/ginkgo/internal/writer/writer.go deleted file mode 100644 index 98eca3bdd25..00000000000 --- a/vendor/github.com/onsi/ginkgo/internal/writer/writer.go +++ /dev/null @@ -1,89 +0,0 @@ -package writer - -import ( - "bytes" - "io" - "sync" -) - -type WriterInterface interface { - io.Writer - - Truncate() - DumpOut() - DumpOutWithHeader(header string) - Bytes() []byte -} - -type Writer struct { - buffer *bytes.Buffer - outWriter io.Writer - lock *sync.Mutex - stream bool - redirector io.Writer -} - -func New(outWriter io.Writer) *Writer { - return &Writer{ - buffer: &bytes.Buffer{}, - lock: &sync.Mutex{}, - outWriter: outWriter, - stream: true, - } -} - -func (w *Writer) AndRedirectTo(writer io.Writer) { - w.redirector = writer -} - -func (w *Writer) SetStream(stream bool) { - w.lock.Lock() - defer w.lock.Unlock() - w.stream = stream -} - -func (w *Writer) Write(b []byte) (n int, err error) { - w.lock.Lock() - defer w.lock.Unlock() - - n, err = w.buffer.Write(b) - if w.redirector != nil { - w.redirector.Write(b) - } - if w.stream { - return w.outWriter.Write(b) - } - return n, err -} - -func (w *Writer) Truncate() { - w.lock.Lock() - defer w.lock.Unlock() - w.buffer.Reset() -} - -func (w *Writer) DumpOut() { - w.lock.Lock() - defer w.lock.Unlock() - if !w.stream { - w.buffer.WriteTo(w.outWriter) - } -} - -func (w *Writer) Bytes() []byte { - w.lock.Lock() - defer w.lock.Unlock() - b := w.buffer.Bytes() - copied := make([]byte, len(b)) - copy(copied, b) - return copied -} - -func (w *Writer) DumpOutWithHeader(header string) { - w.lock.Lock() - defer w.lock.Unlock() - if !w.stream && w.buffer.Len() > 0 { - w.outWriter.Write([]byte(header)) - w.buffer.WriteTo(w.outWriter) - } -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go deleted file mode 100644 index f0c9f61410b..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Ginkgo's Default Reporter - -A number of command line flags are available to tweak Ginkgo's default output. - -These are documented [here](http://onsi.github.io/ginkgo/#running_tests) -*/ -package reporters - -import ( - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/reporters/stenographer" - "github.com/onsi/ginkgo/types" -) - -type DefaultReporter struct { - config config.DefaultReporterConfigType - stenographer stenographer.Stenographer - specSummaries []*types.SpecSummary -} - -func NewDefaultReporter(config config.DefaultReporterConfigType, stenographer stenographer.Stenographer) *DefaultReporter { - return &DefaultReporter{ - config: config, - stenographer: stenographer, - } -} - -func (reporter *DefaultReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { - reporter.stenographer.AnnounceSuite(summary.SuiteDescription, config.RandomSeed, config.RandomizeAllSpecs, reporter.config.Succinct) - if config.ParallelTotal > 1 { - reporter.stenographer.AnnounceParallelRun(config.ParallelNode, config.ParallelTotal, reporter.config.Succinct) - } else { - reporter.stenographer.AnnounceNumberOfSpecs(summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, reporter.config.Succinct) - } -} - -func (reporter *DefaultReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - if setupSummary.State != types.SpecStatePassed { - reporter.stenographer.AnnounceBeforeSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace) - } -} - -func (reporter *DefaultReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - if setupSummary.State != types.SpecStatePassed { - reporter.stenographer.AnnounceAfterSuiteFailure(setupSummary, reporter.config.Succinct, reporter.config.FullTrace) - } -} - -func (reporter *DefaultReporter) SpecWillRun(specSummary *types.SpecSummary) { - if reporter.config.Verbose && !reporter.config.Succinct && specSummary.State != types.SpecStatePending && specSummary.State != types.SpecStateSkipped { - reporter.stenographer.AnnounceSpecWillRun(specSummary) - } -} - -func (reporter *DefaultReporter) SpecDidComplete(specSummary *types.SpecSummary) { - switch specSummary.State { - case types.SpecStatePassed: - if specSummary.IsMeasurement { - reporter.stenographer.AnnounceSuccessfulMeasurement(specSummary, reporter.config.Succinct) - } else if specSummary.RunTime.Seconds() >= reporter.config.SlowSpecThreshold { - reporter.stenographer.AnnounceSuccessfulSlowSpec(specSummary, reporter.config.Succinct) - } else { - reporter.stenographer.AnnounceSuccessfulSpec(specSummary) - if reporter.config.ReportPassed { - reporter.stenographer.AnnounceCapturedOutput(specSummary.CapturedOutput) - } - } - case types.SpecStatePending: - reporter.stenographer.AnnouncePendingSpec(specSummary, reporter.config.NoisyPendings && !reporter.config.Succinct) - case types.SpecStateSkipped: - reporter.stenographer.AnnounceSkippedSpec(specSummary, reporter.config.Succinct || !reporter.config.NoisySkippings, reporter.config.FullTrace) - case types.SpecStateTimedOut: - reporter.stenographer.AnnounceSpecTimedOut(specSummary, reporter.config.Succinct, reporter.config.FullTrace) - case types.SpecStatePanicked: - reporter.stenographer.AnnounceSpecPanicked(specSummary, reporter.config.Succinct, reporter.config.FullTrace) - case types.SpecStateFailed: - reporter.stenographer.AnnounceSpecFailed(specSummary, reporter.config.Succinct, reporter.config.FullTrace) - } - - reporter.specSummaries = append(reporter.specSummaries, specSummary) -} - -func (reporter *DefaultReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - reporter.stenographer.SummarizeFailures(reporter.specSummaries) - reporter.stenographer.AnnounceSpecRunCompletion(summary, reporter.config.Succinct) -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go deleted file mode 100644 index 27db4794908..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go +++ /dev/null @@ -1,59 +0,0 @@ -package reporters - -import ( - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -//FakeReporter is useful for testing purposes -type FakeReporter struct { - Config config.GinkgoConfigType - - BeginSummary *types.SuiteSummary - BeforeSuiteSummary *types.SetupSummary - SpecWillRunSummaries []*types.SpecSummary - SpecSummaries []*types.SpecSummary - AfterSuiteSummary *types.SetupSummary - EndSummary *types.SuiteSummary - - SpecWillRunStub func(specSummary *types.SpecSummary) - SpecDidCompleteStub func(specSummary *types.SpecSummary) -} - -func NewFakeReporter() *FakeReporter { - return &FakeReporter{ - SpecWillRunSummaries: make([]*types.SpecSummary, 0), - SpecSummaries: make([]*types.SpecSummary, 0), - } -} - -func (fakeR *FakeReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { - fakeR.Config = config - fakeR.BeginSummary = summary -} - -func (fakeR *FakeReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - fakeR.BeforeSuiteSummary = setupSummary -} - -func (fakeR *FakeReporter) SpecWillRun(specSummary *types.SpecSummary) { - if fakeR.SpecWillRunStub != nil { - fakeR.SpecWillRunStub(specSummary) - } - fakeR.SpecWillRunSummaries = append(fakeR.SpecWillRunSummaries, specSummary) -} - -func (fakeR *FakeReporter) SpecDidComplete(specSummary *types.SpecSummary) { - if fakeR.SpecDidCompleteStub != nil { - fakeR.SpecDidCompleteStub(specSummary) - } - fakeR.SpecSummaries = append(fakeR.SpecSummaries, specSummary) -} - -func (fakeR *FakeReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - fakeR.AfterSuiteSummary = setupSummary -} - -func (fakeR *FakeReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - fakeR.EndSummary = summary -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go deleted file mode 100644 index 01ddca6e1df..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go +++ /dev/null @@ -1,178 +0,0 @@ -/* - -JUnit XML Reporter for Ginkgo - -For usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output - -*/ - -package reporters - -import ( - "encoding/xml" - "fmt" - "math" - "os" - "path/filepath" - "strings" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -type JUnitTestSuite struct { - XMLName xml.Name `xml:"testsuite"` - TestCases []JUnitTestCase `xml:"testcase"` - Name string `xml:"name,attr"` - Tests int `xml:"tests,attr"` - Failures int `xml:"failures,attr"` - Errors int `xml:"errors,attr"` - Time float64 `xml:"time,attr"` -} - -type JUnitTestCase struct { - Name string `xml:"name,attr"` - ClassName string `xml:"classname,attr"` - FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"` - Skipped *JUnitSkipped `xml:"skipped,omitempty"` - Time float64 `xml:"time,attr"` - SystemOut string `xml:"system-out,omitempty"` -} - -type JUnitFailureMessage struct { - Type string `xml:"type,attr"` - Message string `xml:",chardata"` -} - -type JUnitSkipped struct { - Message string `xml:",chardata"` -} - -type JUnitReporter struct { - suite JUnitTestSuite - filename string - testSuiteName string - ReporterConfig config.DefaultReporterConfigType -} - -//NewJUnitReporter creates a new JUnit XML reporter. The XML will be stored in the passed in filename. -func NewJUnitReporter(filename string) *JUnitReporter { - return &JUnitReporter{ - filename: filename, - } -} - -func (reporter *JUnitReporter) SpecSuiteWillBegin(ginkgoConfig config.GinkgoConfigType, summary *types.SuiteSummary) { - reporter.suite = JUnitTestSuite{ - Name: summary.SuiteDescription, - TestCases: []JUnitTestCase{}, - } - reporter.testSuiteName = summary.SuiteDescription - reporter.ReporterConfig = config.DefaultReporterConfig -} - -func (reporter *JUnitReporter) SpecWillRun(specSummary *types.SpecSummary) { -} - -func (reporter *JUnitReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - reporter.handleSetupSummary("BeforeSuite", setupSummary) -} - -func (reporter *JUnitReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - reporter.handleSetupSummary("AfterSuite", setupSummary) -} - -func failureMessage(failure types.SpecFailure) string { - return fmt.Sprintf("%s\n%s\n%s", failure.ComponentCodeLocation.String(), failure.Message, failure.Location.String()) -} - -func (reporter *JUnitReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) { - if setupSummary.State != types.SpecStatePassed { - testCase := JUnitTestCase{ - Name: name, - ClassName: reporter.testSuiteName, - } - - testCase.FailureMessage = &JUnitFailureMessage{ - Type: reporter.failureTypeForState(setupSummary.State), - Message: failureMessage(setupSummary.Failure), - } - testCase.SystemOut = setupSummary.CapturedOutput - testCase.Time = setupSummary.RunTime.Seconds() - reporter.suite.TestCases = append(reporter.suite.TestCases, testCase) - } -} - -func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) { - testCase := JUnitTestCase{ - Name: strings.Join(specSummary.ComponentTexts[1:], " "), - ClassName: reporter.testSuiteName, - } - if reporter.ReporterConfig.ReportPassed && specSummary.State == types.SpecStatePassed { - testCase.SystemOut = specSummary.CapturedOutput - } - if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked { - testCase.FailureMessage = &JUnitFailureMessage{ - Type: reporter.failureTypeForState(specSummary.State), - Message: failureMessage(specSummary.Failure), - } - if specSummary.State == types.SpecStatePanicked { - testCase.FailureMessage.Message += fmt.Sprintf("\n\nPanic: %s\n\nFull stack:\n%s", - specSummary.Failure.ForwardedPanic, - specSummary.Failure.Location.FullStackTrace) - } - testCase.SystemOut = specSummary.CapturedOutput - } - if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending { - testCase.Skipped = &JUnitSkipped{} - if specSummary.Failure.Message != "" { - testCase.Skipped.Message = failureMessage(specSummary.Failure) - } - } - testCase.Time = specSummary.RunTime.Seconds() - reporter.suite.TestCases = append(reporter.suite.TestCases, testCase) -} - -func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - reporter.suite.Tests = summary.NumberOfSpecsThatWillBeRun - reporter.suite.Time = math.Trunc(summary.RunTime.Seconds()*1000) / 1000 - reporter.suite.Failures = summary.NumberOfFailedSpecs - reporter.suite.Errors = 0 - if reporter.ReporterConfig.ReportFile != "" { - reporter.filename = reporter.ReporterConfig.ReportFile - fmt.Printf("\nJUnit path was configured: %s\n", reporter.filename) - } - filePath, _ := filepath.Abs(reporter.filename) - dirPath := filepath.Dir(filePath) - err := os.MkdirAll(dirPath, os.ModePerm) - if err != nil { - fmt.Printf("\nFailed to create JUnit directory: %s\n\t%s", filePath, err.Error()) - } - file, err := os.Create(filePath) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to create JUnit report file: %s\n\t%s", filePath, err.Error()) - } - defer file.Close() - file.WriteString(xml.Header) - encoder := xml.NewEncoder(file) - encoder.Indent(" ", " ") - err = encoder.Encode(reporter.suite) - if err == nil { - fmt.Fprintf(os.Stdout, "\nJUnit report was created: %s\n", filePath) - } else { - fmt.Fprintf(os.Stderr,"\nFailed to generate JUnit report data:\n\t%s", err.Error()) - } -} - -func (reporter *JUnitReporter) failureTypeForState(state types.SpecState) string { - switch state { - case types.SpecStateFailed: - return "Failure" - case types.SpecStateTimedOut: - return "Timeout" - case types.SpecStatePanicked: - return "Panic" - default: - return "" - } -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/reporter.go b/vendor/github.com/onsi/ginkgo/reporters/reporter.go deleted file mode 100644 index 348b9dfce1f..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/reporter.go +++ /dev/null @@ -1,15 +0,0 @@ -package reporters - -import ( - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -type Reporter interface { - SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) - BeforeSuiteDidRun(setupSummary *types.SetupSummary) - SpecWillRun(specSummary *types.SpecSummary) - SpecDidComplete(specSummary *types.SpecSummary) - AfterSuiteDidRun(setupSummary *types.SetupSummary) - SpecSuiteDidEnd(summary *types.SuiteSummary) -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go deleted file mode 100644 index 45b8f88690e..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go +++ /dev/null @@ -1,64 +0,0 @@ -package stenographer - -import ( - "fmt" - "strings" -) - -func (s *consoleStenographer) colorize(colorCode string, format string, args ...interface{}) string { - var out string - - if len(args) > 0 { - out = fmt.Sprintf(format, args...) - } else { - out = format - } - - if s.color { - return fmt.Sprintf("%s%s%s", colorCode, out, defaultStyle) - } else { - return out - } -} - -func (s *consoleStenographer) printBanner(text string, bannerCharacter string) { - fmt.Fprintln(s.w, text) - fmt.Fprintln(s.w, strings.Repeat(bannerCharacter, len(text))) -} - -func (s *consoleStenographer) printNewLine() { - fmt.Fprintln(s.w, "") -} - -func (s *consoleStenographer) printDelimiter() { - fmt.Fprintln(s.w, s.colorize(grayColor, "%s", strings.Repeat("-", 30))) -} - -func (s *consoleStenographer) print(indentation int, format string, args ...interface{}) { - fmt.Fprint(s.w, s.indent(indentation, format, args...)) -} - -func (s *consoleStenographer) println(indentation int, format string, args ...interface{}) { - fmt.Fprintln(s.w, s.indent(indentation, format, args...)) -} - -func (s *consoleStenographer) indent(indentation int, format string, args ...interface{}) string { - var text string - - if len(args) > 0 { - text = fmt.Sprintf(format, args...) - } else { - text = format - } - - stringArray := strings.Split(text, "\n") - padding := "" - if indentation >= 0 { - padding = strings.Repeat(" ", indentation) - } - for i, s := range stringArray { - stringArray[i] = fmt.Sprintf("%s%s", padding, s) - } - - return strings.Join(stringArray, "\n") -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go deleted file mode 100644 index 1aa5b9db0fe..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go +++ /dev/null @@ -1,142 +0,0 @@ -package stenographer - -import ( - "sync" - - "github.com/onsi/ginkgo/types" -) - -func NewFakeStenographerCall(method string, args ...interface{}) FakeStenographerCall { - return FakeStenographerCall{ - Method: method, - Args: args, - } -} - -type FakeStenographer struct { - calls []FakeStenographerCall - lock *sync.Mutex -} - -type FakeStenographerCall struct { - Method string - Args []interface{} -} - -func NewFakeStenographer() *FakeStenographer { - stenographer := &FakeStenographer{ - lock: &sync.Mutex{}, - } - stenographer.Reset() - return stenographer -} - -func (stenographer *FakeStenographer) Calls() []FakeStenographerCall { - stenographer.lock.Lock() - defer stenographer.lock.Unlock() - - return stenographer.calls -} - -func (stenographer *FakeStenographer) Reset() { - stenographer.lock.Lock() - defer stenographer.lock.Unlock() - - stenographer.calls = make([]FakeStenographerCall, 0) -} - -func (stenographer *FakeStenographer) CallsTo(method string) []FakeStenographerCall { - stenographer.lock.Lock() - defer stenographer.lock.Unlock() - - results := make([]FakeStenographerCall, 0) - for _, call := range stenographer.calls { - if call.Method == method { - results = append(results, call) - } - } - - return results -} - -func (stenographer *FakeStenographer) registerCall(method string, args ...interface{}) { - stenographer.lock.Lock() - defer stenographer.lock.Unlock() - - stenographer.calls = append(stenographer.calls, NewFakeStenographerCall(method, args...)) -} - -func (stenographer *FakeStenographer) AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool) { - stenographer.registerCall("AnnounceSuite", description, randomSeed, randomizingAll, succinct) -} - -func (stenographer *FakeStenographer) AnnounceAggregatedParallelRun(nodes int, succinct bool) { - stenographer.registerCall("AnnounceAggregatedParallelRun", nodes, succinct) -} - -func (stenographer *FakeStenographer) AnnounceParallelRun(node int, nodes int, succinct bool) { - stenographer.registerCall("AnnounceParallelRun", node, nodes, succinct) -} - -func (stenographer *FakeStenographer) AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool) { - stenographer.registerCall("AnnounceNumberOfSpecs", specsToRun, total, succinct) -} - -func (stenographer *FakeStenographer) AnnounceTotalNumberOfSpecs(total int, succinct bool) { - stenographer.registerCall("AnnounceTotalNumberOfSpecs", total, succinct) -} - -func (stenographer *FakeStenographer) AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool) { - stenographer.registerCall("AnnounceSpecRunCompletion", summary, succinct) -} - -func (stenographer *FakeStenographer) AnnounceSpecWillRun(spec *types.SpecSummary) { - stenographer.registerCall("AnnounceSpecWillRun", spec) -} - -func (stenographer *FakeStenographer) AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceBeforeSuiteFailure", summary, succinct, fullTrace) -} - -func (stenographer *FakeStenographer) AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceAfterSuiteFailure", summary, succinct, fullTrace) -} -func (stenographer *FakeStenographer) AnnounceCapturedOutput(output string) { - stenographer.registerCall("AnnounceCapturedOutput", output) -} - -func (stenographer *FakeStenographer) AnnounceSuccessfulSpec(spec *types.SpecSummary) { - stenographer.registerCall("AnnounceSuccessfulSpec", spec) -} - -func (stenographer *FakeStenographer) AnnounceSuccessfulSlowSpec(spec *types.SpecSummary, succinct bool) { - stenographer.registerCall("AnnounceSuccessfulSlowSpec", spec, succinct) -} - -func (stenographer *FakeStenographer) AnnounceSuccessfulMeasurement(spec *types.SpecSummary, succinct bool) { - stenographer.registerCall("AnnounceSuccessfulMeasurement", spec, succinct) -} - -func (stenographer *FakeStenographer) AnnouncePendingSpec(spec *types.SpecSummary, noisy bool) { - stenographer.registerCall("AnnouncePendingSpec", spec, noisy) -} - -func (stenographer *FakeStenographer) AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceSkippedSpec", spec, succinct, fullTrace) -} - -func (stenographer *FakeStenographer) AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceSpecTimedOut", spec, succinct, fullTrace) -} - -func (stenographer *FakeStenographer) AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceSpecPanicked", spec, succinct, fullTrace) -} - -func (stenographer *FakeStenographer) AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool) { - stenographer.registerCall("AnnounceSpecFailed", spec, succinct, fullTrace) -} - -func (stenographer *FakeStenographer) SummarizeFailures(summaries []*types.SpecSummary) { - stenographer.registerCall("SummarizeFailures", summaries) -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go deleted file mode 100644 index 638d6fbb1a9..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go +++ /dev/null @@ -1,572 +0,0 @@ -/* -The stenographer is used by Ginkgo's reporters to generate output. - -Move along, nothing to see here. -*/ - -package stenographer - -import ( - "fmt" - "io" - "runtime" - "strings" - - "github.com/onsi/ginkgo/types" -) - -const defaultStyle = "\x1b[0m" -const boldStyle = "\x1b[1m" -const redColor = "\x1b[91m" -const greenColor = "\x1b[32m" -const yellowColor = "\x1b[33m" -const cyanColor = "\x1b[36m" -const grayColor = "\x1b[90m" -const lightGrayColor = "\x1b[37m" - -type cursorStateType int - -const ( - cursorStateTop cursorStateType = iota - cursorStateStreaming - cursorStateMidBlock - cursorStateEndBlock -) - -type Stenographer interface { - AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool) - AnnounceAggregatedParallelRun(nodes int, succinct bool) - AnnounceParallelRun(node int, nodes int, succinct bool) - AnnounceTotalNumberOfSpecs(total int, succinct bool) - AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool) - AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool) - - AnnounceSpecWillRun(spec *types.SpecSummary) - AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) - AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) - - AnnounceCapturedOutput(output string) - - AnnounceSuccessfulSpec(spec *types.SpecSummary) - AnnounceSuccessfulSlowSpec(spec *types.SpecSummary, succinct bool) - AnnounceSuccessfulMeasurement(spec *types.SpecSummary, succinct bool) - - AnnouncePendingSpec(spec *types.SpecSummary, noisy bool) - AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool) - - AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool) - AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool) - AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool) - - SummarizeFailures(summaries []*types.SpecSummary) -} - -func New(color bool, enableFlakes bool, writer io.Writer) Stenographer { - denoter := "•" - if runtime.GOOS == "windows" { - denoter = "+" - } - return &consoleStenographer{ - color: color, - denoter: denoter, - cursorState: cursorStateTop, - enableFlakes: enableFlakes, - w: writer, - } -} - -type consoleStenographer struct { - color bool - denoter string - cursorState cursorStateType - enableFlakes bool - w io.Writer -} - -var alternatingColors = []string{defaultStyle, grayColor} - -func (s *consoleStenographer) AnnounceSuite(description string, randomSeed int64, randomizingAll bool, succinct bool) { - if succinct { - s.print(0, "[%d] %s ", randomSeed, s.colorize(boldStyle, description)) - return - } - s.printBanner(fmt.Sprintf("Running Suite: %s", description), "=") - s.print(0, "Random Seed: %s", s.colorize(boldStyle, "%d", randomSeed)) - if randomizingAll { - s.print(0, " - Will randomize all specs") - } - s.printNewLine() -} - -func (s *consoleStenographer) AnnounceParallelRun(node int, nodes int, succinct bool) { - if succinct { - s.print(0, "- node #%d ", node) - return - } - s.println(0, - "Parallel test node %s/%s.", - s.colorize(boldStyle, "%d", node), - s.colorize(boldStyle, "%d", nodes), - ) - s.printNewLine() -} - -func (s *consoleStenographer) AnnounceAggregatedParallelRun(nodes int, succinct bool) { - if succinct { - s.print(0, "- %d nodes ", nodes) - return - } - s.println(0, - "Running in parallel across %s nodes", - s.colorize(boldStyle, "%d", nodes), - ) - s.printNewLine() -} - -func (s *consoleStenographer) AnnounceNumberOfSpecs(specsToRun int, total int, succinct bool) { - if succinct { - s.print(0, "- %d/%d specs ", specsToRun, total) - s.stream() - return - } - s.println(0, - "Will run %s of %s specs", - s.colorize(boldStyle, "%d", specsToRun), - s.colorize(boldStyle, "%d", total), - ) - - s.printNewLine() -} - -func (s *consoleStenographer) AnnounceTotalNumberOfSpecs(total int, succinct bool) { - if succinct { - s.print(0, "- %d specs ", total) - s.stream() - return - } - s.println(0, - "Will run %s specs", - s.colorize(boldStyle, "%d", total), - ) - - s.printNewLine() -} - -func (s *consoleStenographer) AnnounceSpecRunCompletion(summary *types.SuiteSummary, succinct bool) { - if succinct && summary.SuiteSucceeded { - s.print(0, " %s %s ", s.colorize(greenColor, "SUCCESS!"), summary.RunTime) - return - } - s.printNewLine() - color := greenColor - if !summary.SuiteSucceeded { - color = redColor - } - s.println(0, s.colorize(boldStyle+color, "Ran %d of %d Specs in %.3f seconds", summary.NumberOfSpecsThatWillBeRun, summary.NumberOfTotalSpecs, summary.RunTime.Seconds())) - - status := "" - if summary.SuiteSucceeded { - status = s.colorize(boldStyle+greenColor, "SUCCESS!") - } else { - status = s.colorize(boldStyle+redColor, "FAIL!") - } - - flakes := "" - if s.enableFlakes { - flakes = " | " + s.colorize(yellowColor+boldStyle, "%d Flaked", summary.NumberOfFlakedSpecs) - } - - s.print(0, - "%s -- %s | %s | %s | %s\n", - status, - s.colorize(greenColor+boldStyle, "%d Passed", summary.NumberOfPassedSpecs), - s.colorize(redColor+boldStyle, "%d Failed", summary.NumberOfFailedSpecs)+flakes, - s.colorize(yellowColor+boldStyle, "%d Pending", summary.NumberOfPendingSpecs), - s.colorize(cyanColor+boldStyle, "%d Skipped", summary.NumberOfSkippedSpecs), - ) -} - -func (s *consoleStenographer) AnnounceSpecWillRun(spec *types.SpecSummary) { - s.startBlock() - for i, text := range spec.ComponentTexts[1 : len(spec.ComponentTexts)-1] { - s.print(0, s.colorize(alternatingColors[i%2], text)+" ") - } - - indentation := 0 - if len(spec.ComponentTexts) > 2 { - indentation = 1 - s.printNewLine() - } - index := len(spec.ComponentTexts) - 1 - s.print(indentation, s.colorize(boldStyle, spec.ComponentTexts[index])) - s.printNewLine() - s.print(indentation, s.colorize(lightGrayColor, spec.ComponentCodeLocations[index].String())) - s.printNewLine() - s.midBlock() -} - -func (s *consoleStenographer) AnnounceBeforeSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) { - s.announceSetupFailure("BeforeSuite", summary, succinct, fullTrace) -} - -func (s *consoleStenographer) AnnounceAfterSuiteFailure(summary *types.SetupSummary, succinct bool, fullTrace bool) { - s.announceSetupFailure("AfterSuite", summary, succinct, fullTrace) -} - -func (s *consoleStenographer) announceSetupFailure(name string, summary *types.SetupSummary, succinct bool, fullTrace bool) { - s.startBlock() - var message string - switch summary.State { - case types.SpecStateFailed: - message = "Failure" - case types.SpecStatePanicked: - message = "Panic" - case types.SpecStateTimedOut: - message = "Timeout" - } - - s.println(0, s.colorize(redColor+boldStyle, "%s [%.3f seconds]", message, summary.RunTime.Seconds())) - - indentation := s.printCodeLocationBlock([]string{name}, []types.CodeLocation{summary.CodeLocation}, summary.ComponentType, 0, summary.State, true) - - s.printNewLine() - s.printFailure(indentation, summary.State, summary.Failure, fullTrace) - - s.endBlock() -} - -func (s *consoleStenographer) AnnounceCapturedOutput(output string) { - if output == "" { - return - } - - s.startBlock() - s.println(0, output) - s.midBlock() -} - -func (s *consoleStenographer) AnnounceSuccessfulSpec(spec *types.SpecSummary) { - s.print(0, s.colorize(greenColor, s.denoter)) - s.stream() -} - -func (s *consoleStenographer) AnnounceSuccessfulSlowSpec(spec *types.SpecSummary, succinct bool) { - s.printBlockWithMessage( - s.colorize(greenColor, "%s [SLOW TEST:%.3f seconds]", s.denoter, spec.RunTime.Seconds()), - "", - spec, - succinct, - ) -} - -func (s *consoleStenographer) AnnounceSuccessfulMeasurement(spec *types.SpecSummary, succinct bool) { - s.printBlockWithMessage( - s.colorize(greenColor, "%s [MEASUREMENT]", s.denoter), - s.measurementReport(spec, succinct), - spec, - succinct, - ) -} - -func (s *consoleStenographer) AnnouncePendingSpec(spec *types.SpecSummary, noisy bool) { - if noisy { - s.printBlockWithMessage( - s.colorize(yellowColor, "P [PENDING]"), - "", - spec, - false, - ) - } else { - s.print(0, s.colorize(yellowColor, "P")) - s.stream() - } -} - -func (s *consoleStenographer) AnnounceSkippedSpec(spec *types.SpecSummary, succinct bool, fullTrace bool) { - // Skips at runtime will have a non-empty spec.Failure. All others should be succinct. - if succinct || spec.Failure == (types.SpecFailure{}) { - s.print(0, s.colorize(cyanColor, "S")) - s.stream() - } else { - s.startBlock() - s.println(0, s.colorize(cyanColor+boldStyle, "S [SKIPPING]%s [%.3f seconds]", s.failureContext(spec.Failure.ComponentType), spec.RunTime.Seconds())) - - indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, spec.Failure.ComponentType, spec.Failure.ComponentIndex, spec.State, succinct) - - s.printNewLine() - s.printSkip(indentation, spec.Failure) - s.endBlock() - } -} - -func (s *consoleStenographer) AnnounceSpecTimedOut(spec *types.SpecSummary, succinct bool, fullTrace bool) { - s.printSpecFailure(fmt.Sprintf("%s... Timeout", s.denoter), spec, succinct, fullTrace) -} - -func (s *consoleStenographer) AnnounceSpecPanicked(spec *types.SpecSummary, succinct bool, fullTrace bool) { - s.printSpecFailure(fmt.Sprintf("%s! Panic", s.denoter), spec, succinct, fullTrace) -} - -func (s *consoleStenographer) AnnounceSpecFailed(spec *types.SpecSummary, succinct bool, fullTrace bool) { - s.printSpecFailure(fmt.Sprintf("%s Failure", s.denoter), spec, succinct, fullTrace) -} - -func (s *consoleStenographer) SummarizeFailures(summaries []*types.SpecSummary) { - failingSpecs := []*types.SpecSummary{} - - for _, summary := range summaries { - if summary.HasFailureState() { - failingSpecs = append(failingSpecs, summary) - } - } - - if len(failingSpecs) == 0 { - return - } - - s.printNewLine() - s.printNewLine() - plural := "s" - if len(failingSpecs) == 1 { - plural = "" - } - s.println(0, s.colorize(redColor+boldStyle, "Summarizing %d Failure%s:", len(failingSpecs), plural)) - for _, summary := range failingSpecs { - s.printNewLine() - if summary.HasFailureState() { - if summary.TimedOut() { - s.print(0, s.colorize(redColor+boldStyle, "[Timeout...] ")) - } else if summary.Panicked() { - s.print(0, s.colorize(redColor+boldStyle, "[Panic!] ")) - } else if summary.Failed() { - s.print(0, s.colorize(redColor+boldStyle, "[Fail] ")) - } - s.printSpecContext(summary.ComponentTexts, summary.ComponentCodeLocations, summary.Failure.ComponentType, summary.Failure.ComponentIndex, summary.State, true) - s.printNewLine() - s.println(0, s.colorize(lightGrayColor, summary.Failure.Location.String())) - } - } -} - -func (s *consoleStenographer) startBlock() { - if s.cursorState == cursorStateStreaming { - s.printNewLine() - s.printDelimiter() - } else if s.cursorState == cursorStateMidBlock { - s.printNewLine() - } -} - -func (s *consoleStenographer) midBlock() { - s.cursorState = cursorStateMidBlock -} - -func (s *consoleStenographer) endBlock() { - s.printDelimiter() - s.cursorState = cursorStateEndBlock -} - -func (s *consoleStenographer) stream() { - s.cursorState = cursorStateStreaming -} - -func (s *consoleStenographer) printBlockWithMessage(header string, message string, spec *types.SpecSummary, succinct bool) { - s.startBlock() - s.println(0, header) - - indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, types.SpecComponentTypeInvalid, 0, spec.State, succinct) - - if message != "" { - s.printNewLine() - s.println(indentation, message) - } - - s.endBlock() -} - -func (s *consoleStenographer) printSpecFailure(message string, spec *types.SpecSummary, succinct bool, fullTrace bool) { - s.startBlock() - s.println(0, s.colorize(redColor+boldStyle, "%s%s [%.3f seconds]", message, s.failureContext(spec.Failure.ComponentType), spec.RunTime.Seconds())) - - indentation := s.printCodeLocationBlock(spec.ComponentTexts, spec.ComponentCodeLocations, spec.Failure.ComponentType, spec.Failure.ComponentIndex, spec.State, succinct) - - s.printNewLine() - s.printFailure(indentation, spec.State, spec.Failure, fullTrace) - s.endBlock() -} - -func (s *consoleStenographer) failureContext(failedComponentType types.SpecComponentType) string { - switch failedComponentType { - case types.SpecComponentTypeBeforeSuite: - return " in Suite Setup (BeforeSuite)" - case types.SpecComponentTypeAfterSuite: - return " in Suite Teardown (AfterSuite)" - case types.SpecComponentTypeBeforeEach: - return " in Spec Setup (BeforeEach)" - case types.SpecComponentTypeJustBeforeEach: - return " in Spec Setup (JustBeforeEach)" - case types.SpecComponentTypeAfterEach: - return " in Spec Teardown (AfterEach)" - } - - return "" -} - -func (s *consoleStenographer) printSkip(indentation int, spec types.SpecFailure) { - s.println(indentation, s.colorize(cyanColor, spec.Message)) - s.printNewLine() - s.println(indentation, spec.Location.String()) -} - -func (s *consoleStenographer) printFailure(indentation int, state types.SpecState, failure types.SpecFailure, fullTrace bool) { - if state == types.SpecStatePanicked { - s.println(indentation, s.colorize(redColor+boldStyle, failure.Message)) - s.println(indentation, s.colorize(redColor, failure.ForwardedPanic)) - s.println(indentation, failure.Location.String()) - s.printNewLine() - s.println(indentation, s.colorize(redColor, "Full Stack Trace")) - s.println(indentation, failure.Location.FullStackTrace) - } else { - s.println(indentation, s.colorize(redColor, failure.Message)) - s.printNewLine() - s.println(indentation, failure.Location.String()) - if fullTrace { - s.printNewLine() - s.println(indentation, s.colorize(redColor, "Full Stack Trace")) - s.println(indentation, failure.Location.FullStackTrace) - } - } -} - -func (s *consoleStenographer) printSpecContext(componentTexts []string, componentCodeLocations []types.CodeLocation, failedComponentType types.SpecComponentType, failedComponentIndex int, state types.SpecState, succinct bool) int { - startIndex := 1 - indentation := 0 - - if len(componentTexts) == 1 { - startIndex = 0 - } - - for i := startIndex; i < len(componentTexts); i++ { - if (state.IsFailure() || state == types.SpecStateSkipped) && i == failedComponentIndex { - color := redColor - if state == types.SpecStateSkipped { - color = cyanColor - } - blockType := "" - switch failedComponentType { - case types.SpecComponentTypeBeforeSuite: - blockType = "BeforeSuite" - case types.SpecComponentTypeAfterSuite: - blockType = "AfterSuite" - case types.SpecComponentTypeBeforeEach: - blockType = "BeforeEach" - case types.SpecComponentTypeJustBeforeEach: - blockType = "JustBeforeEach" - case types.SpecComponentTypeAfterEach: - blockType = "AfterEach" - case types.SpecComponentTypeIt: - blockType = "It" - case types.SpecComponentTypeMeasure: - blockType = "Measurement" - } - if succinct { - s.print(0, s.colorize(color+boldStyle, "[%s] %s ", blockType, componentTexts[i])) - } else { - s.println(indentation, s.colorize(color+boldStyle, "%s [%s]", componentTexts[i], blockType)) - s.println(indentation, s.colorize(grayColor, "%s", componentCodeLocations[i])) - } - } else { - if succinct { - s.print(0, s.colorize(alternatingColors[i%2], "%s ", componentTexts[i])) - } else { - s.println(indentation, componentTexts[i]) - s.println(indentation, s.colorize(grayColor, "%s", componentCodeLocations[i])) - } - } - indentation++ - } - - return indentation -} - -func (s *consoleStenographer) printCodeLocationBlock(componentTexts []string, componentCodeLocations []types.CodeLocation, failedComponentType types.SpecComponentType, failedComponentIndex int, state types.SpecState, succinct bool) int { - indentation := s.printSpecContext(componentTexts, componentCodeLocations, failedComponentType, failedComponentIndex, state, succinct) - - if succinct { - if len(componentTexts) > 0 { - s.printNewLine() - s.print(0, s.colorize(lightGrayColor, "%s", componentCodeLocations[len(componentCodeLocations)-1])) - } - s.printNewLine() - indentation = 1 - } else { - indentation-- - } - - return indentation -} - -func (s *consoleStenographer) orderedMeasurementKeys(measurements map[string]*types.SpecMeasurement) []string { - orderedKeys := make([]string, len(measurements)) - for key, measurement := range measurements { - orderedKeys[measurement.Order] = key - } - return orderedKeys -} - -func (s *consoleStenographer) measurementReport(spec *types.SpecSummary, succinct bool) string { - if len(spec.Measurements) == 0 { - return "Found no measurements" - } - - message := []string{} - orderedKeys := s.orderedMeasurementKeys(spec.Measurements) - - if succinct { - message = append(message, fmt.Sprintf("%s samples:", s.colorize(boldStyle, "%d", spec.NumberOfSamples))) - for _, key := range orderedKeys { - measurement := spec.Measurements[key] - message = append(message, fmt.Sprintf(" %s - %s: %s%s, %s: %s%s ± %s%s, %s: %s%s", - s.colorize(boldStyle, "%s", measurement.Name), - measurement.SmallestLabel, - s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest), - measurement.Units, - measurement.AverageLabel, - s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average), - measurement.Units, - s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation), - measurement.Units, - measurement.LargestLabel, - s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest), - measurement.Units, - )) - } - } else { - message = append(message, fmt.Sprintf("Ran %s samples:", s.colorize(boldStyle, "%d", spec.NumberOfSamples))) - for _, key := range orderedKeys { - measurement := spec.Measurements[key] - info := "" - if measurement.Info != nil { - message = append(message, fmt.Sprintf("%v", measurement.Info)) - } - - message = append(message, fmt.Sprintf("%s:\n%s %s: %s%s\n %s: %s%s\n %s: %s%s ± %s%s", - s.colorize(boldStyle, "%s", measurement.Name), - info, - measurement.SmallestLabel, - s.colorize(greenColor, measurement.PrecisionFmt(), measurement.Smallest), - measurement.Units, - measurement.LargestLabel, - s.colorize(redColor, measurement.PrecisionFmt(), measurement.Largest), - measurement.Units, - measurement.AverageLabel, - s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.Average), - measurement.Units, - s.colorize(cyanColor, measurement.PrecisionFmt(), measurement.StdDeviation), - measurement.Units, - )) - } - } - - return strings.Join(message, "\n") -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE deleted file mode 100644 index 91b5cef30eb..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md deleted file mode 100644 index e84226a7358..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# go-colorable - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go deleted file mode 100644 index 52d6653b34b..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_others.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build !windows - -package colorable - -import ( - "io" - "os" -) - -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -func NewColorableStdout() io.Writer { - return os.Stdout -} - -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go deleted file mode 100644 index 1088009230b..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/colorable_windows.go +++ /dev/null @@ -1,783 +0,0 @@ -package colorable - -import ( - "bytes" - "fmt" - "io" - "math" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - "github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") -) - -type Writer struct { - out io.Writer - handle syscall.Handle - lastbuf bytes.Buffer - oldattr word -} - -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isatty.IsTerminal(file.Fd()) { - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: file, handle: handle, oldattr: csbi.attributes} - } else { - return file - } -} - -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -func NewColorableStderr() io.Writer { - return NewColorable(os.Stderr) -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -func (w *Writer) Write(data []byte) (n int, err error) { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - er := bytes.NewBuffer(data) -loop: - for { - r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if r1 == 0 { - break loop - } - - c1, _, err := er.ReadRune() - if err != nil { - break loop - } - if c1 != 0x1b { - fmt.Fprint(w.out, string(c1)) - continue - } - c2, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - break loop - } - if c2 != 0x5b { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - continue - } - - var buf bytes.Buffer - var m rune - for { - c, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - w.lastbuf.Write(buf.Bytes()) - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - break - } - buf.Write([]byte(string(c))) - } - - var csbi consoleScreenBufferInfo - switch m { - case 'A': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - if n, err = strconv.Atoi(buf.String()); err == nil { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - } - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H': - token := strings.Split(buf.String(), ";") - if len(token) != 2 { - continue - } - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2) - csbi.cursorPosition.x = short(n1) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue - } - var cursor coord - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue - } - var cursor coord - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x) - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i += 1 { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case 1 <= n && n <= 5: - attr |= foregroundIntensity - case n == 7: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 22 == n || n == 25 || n == 25: - attr |= foregroundIntensity - case n == 27: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 30 <= n && n <= 37: - attr = (attr & backgroundMask) - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr = (attr & foregroundMask) - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) - } - } - } - } - return len(data) - w.lastbuf.Len(), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - consoleColor{0x000000, false, false, false, false}, - consoleColor{0x000080, false, false, true, false}, - consoleColor{0x008000, false, true, false, false}, - consoleColor{0x008080, false, true, true, false}, - consoleColor{0x800000, true, false, false, false}, - consoleColor{0x800080, true, false, true, false}, - consoleColor{0x808000, true, true, false, false}, - consoleColor{0xc0c0c0, true, true, true, false}, - consoleColor{0x808080, false, false, false, true}, - consoleColor{0x0000ff, false, false, true, true}, - consoleColor{0x00ff00, false, true, false, true}, - consoleColor{0x00ffff, false, true, true, true}, - consoleColor{0xff0000, true, false, false, true}, - consoleColor{0xff00ff, true, false, true, true}, - consoleColor{0xffff00, true, true, false, true}, - consoleColor{0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go deleted file mode 100644 index fb976dbd8b7..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable/noncolorable.go +++ /dev/null @@ -1,57 +0,0 @@ -package colorable - -import ( - "bytes" - "fmt" - "io" -) - -type NonColorable struct { - out io.Writer - lastbuf bytes.Buffer -} - -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewBuffer(data) -loop: - for { - c1, _, err := er.ReadRune() - if err != nil { - break loop - } - if c1 != 0x1b { - fmt.Fprint(w.out, string(c1)) - continue - } - c2, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - break loop - } - if c2 != 0x5b { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - continue - } - - var buf bytes.Buffer - for { - c, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - w.lastbuf.Write(buf.Bytes()) - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - buf.Write([]byte(string(c))) - } - } - return len(data) - w.lastbuf.Len(), nil -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE deleted file mode 100644 index 65dc692b6b1..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md deleted file mode 100644 index 74845de4a24..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# go-isatty - -isatty for golang - -## Usage - -```go -package main - -import ( - "fmt" - "github.com/mattn/go-isatty" - "os" -) - -func main() { - if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Println("Is Terminal") - } else { - fmt.Println("Is Not Terminal") - } -} -``` - -## Installation - -``` -$ go get github.com/mattn/go-isatty -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go deleted file mode 100644 index 17d4f90ebcc..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package isatty implements interface to isatty -package isatty diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go deleted file mode 100644 index 83c588773cf..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_appengine.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build appengine - -package isatty - -// IsTerminal returns true if the file descriptor is terminal which -// is always false on on appengine classic which is a sandboxed PaaS. -func IsTerminal(fd uintptr) bool { - return false -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go deleted file mode 100644 index 98ffe86a4ba..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_bsd.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build darwin freebsd openbsd netbsd -// +build !appengine - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TIOCGETA - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go deleted file mode 100644 index 9d24bac1db3..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_linux.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build linux -// +build !appengine - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TCGETS - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go deleted file mode 100644 index 1f0c6bf53dc..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_solaris.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build solaris -// +build !appengine - -package isatty - -import ( - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c -func IsTerminal(fd uintptr) bool { - var termio unix.Termio - err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) - return err == nil -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go b/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go deleted file mode 100644 index 83c398b16db..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty/isatty_windows.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build windows -// +build !appengine - -package isatty - -import ( - "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") -var procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} diff --git a/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go deleted file mode 100644 index 84fd8aff878..00000000000 --- a/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - -TeamCity Reporter for Ginkgo - -Makes use of TeamCity's support for Service Messages -http://confluence.jetbrains.com/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests -*/ - -package reporters - -import ( - "fmt" - "io" - "strings" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -const ( - messageId = "##teamcity" -) - -type TeamCityReporter struct { - writer io.Writer - testSuiteName string - ReporterConfig config.DefaultReporterConfigType -} - -func NewTeamCityReporter(writer io.Writer) *TeamCityReporter { - return &TeamCityReporter{ - writer: writer, - } -} - -func (reporter *TeamCityReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { - reporter.testSuiteName = escape(summary.SuiteDescription) - fmt.Fprintf(reporter.writer, "%s[testSuiteStarted name='%s']\n", messageId, reporter.testSuiteName) -} - -func (reporter *TeamCityReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - reporter.handleSetupSummary("BeforeSuite", setupSummary) -} - -func (reporter *TeamCityReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - reporter.handleSetupSummary("AfterSuite", setupSummary) -} - -func (reporter *TeamCityReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) { - if setupSummary.State != types.SpecStatePassed { - testName := escape(name) - fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']\n", messageId, testName) - message := reporter.failureMessage(setupSummary.Failure) - details := reporter.failureDetails(setupSummary.Failure) - fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']\n", messageId, testName, message, details) - durationInMilliseconds := setupSummary.RunTime.Seconds() * 1000 - fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']\n", messageId, testName, durationInMilliseconds) - } -} - -func (reporter *TeamCityReporter) SpecWillRun(specSummary *types.SpecSummary) { - testName := escape(strings.Join(specSummary.ComponentTexts[1:], " ")) - fmt.Fprintf(reporter.writer, "%s[testStarted name='%s']\n", messageId, testName) -} - -func (reporter *TeamCityReporter) SpecDidComplete(specSummary *types.SpecSummary) { - testName := escape(strings.Join(specSummary.ComponentTexts[1:], " ")) - - if reporter.ReporterConfig.ReportPassed && specSummary.State == types.SpecStatePassed { - details := escape(specSummary.CapturedOutput) - fmt.Fprintf(reporter.writer, "%s[testPassed name='%s' details='%s']\n", messageId, testName, details) - } - if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked { - message := reporter.failureMessage(specSummary.Failure) - details := reporter.failureDetails(specSummary.Failure) - fmt.Fprintf(reporter.writer, "%s[testFailed name='%s' message='%s' details='%s']\n", messageId, testName, message, details) - } - if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending { - fmt.Fprintf(reporter.writer, "%s[testIgnored name='%s']\n", messageId, testName) - } - - durationInMilliseconds := specSummary.RunTime.Seconds() * 1000 - fmt.Fprintf(reporter.writer, "%s[testFinished name='%s' duration='%v']\n", messageId, testName, durationInMilliseconds) -} - -func (reporter *TeamCityReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - fmt.Fprintf(reporter.writer, "%s[testSuiteFinished name='%s']\n", messageId, reporter.testSuiteName) -} - -func (reporter *TeamCityReporter) failureMessage(failure types.SpecFailure) string { - return escape(failure.ComponentCodeLocation.String()) -} - -func (reporter *TeamCityReporter) failureDetails(failure types.SpecFailure) string { - return escape(fmt.Sprintf("%s\n%s", failure.Message, failure.Location.String())) -} - -func escape(output string) string { - output = strings.Replace(output, "|", "||", -1) - output = strings.Replace(output, "'", "|'", -1) - output = strings.Replace(output, "\n", "|n", -1) - output = strings.Replace(output, "\r", "|r", -1) - output = strings.Replace(output, "[", "|[", -1) - output = strings.Replace(output, "]", "|]", -1) - return output -} diff --git a/vendor/github.com/onsi/ginkgo/types/code_location.go b/vendor/github.com/onsi/ginkgo/types/code_location.go deleted file mode 100644 index 935a89e136a..00000000000 --- a/vendor/github.com/onsi/ginkgo/types/code_location.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -import ( - "fmt" -) - -type CodeLocation struct { - FileName string - LineNumber int - FullStackTrace string -} - -func (codeLocation CodeLocation) String() string { - return fmt.Sprintf("%s:%d", codeLocation.FileName, codeLocation.LineNumber) -} diff --git a/vendor/github.com/onsi/ginkgo/types/deprecation_support.go b/vendor/github.com/onsi/ginkgo/types/deprecation_support.go deleted file mode 100644 index d5a6658f35f..00000000000 --- a/vendor/github.com/onsi/ginkgo/types/deprecation_support.go +++ /dev/null @@ -1,160 +0,0 @@ -package types - -import ( - "os" - "strconv" - "strings" - "unicode" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/formatter" -) - -type Deprecation struct { - Message string - DocLink string - Version string -} - -type deprecations struct{} - -var Deprecations = deprecations{} - -func (d deprecations) CustomReporter() Deprecation { - return Deprecation{ - Message: "You are using a custom reporter. Support for custom reporters will likely be removed in V2. Most users were using them to generate junit or teamcity reports and this functionality will be merged into the core reporter. In addition, Ginkgo 2.0 will support emitting a JSON-formatted report that users can then manipulate to generate custom reports.\n\n{{red}}{{bold}}If this change will be impactful to you please leave a comment on {{cyan}}{{underline}}https://github.com/onsi/ginkgo/issues/711{{/}}", - DocLink: "removed-custom-reporters", - Version: "1.16.0", - } -} - -func (d deprecations) V1Reporter() Deprecation { - return Deprecation{ - Message: "You are using a V1 Ginkgo Reporter. Please update your custom reporter to the new V2 Reporter interface.", - DocLink: "changed-reporter-interface", - Version: "1.16.0", - } -} - -func (d deprecations) Async() Deprecation { - return Deprecation{ - Message: "You are passing a Done channel to a test node to test asynchronous behavior. This is deprecated in Ginkgo V2. Your test will run synchronously and the timeout will be ignored.", - DocLink: "removed-async-testing", - Version: "1.16.0", - } -} - -func (d deprecations) Measure() Deprecation { - return Deprecation{ - Message: "Measure is deprecated and will be removed in Ginkgo V2. Please migrate to gomega/gmeasure.", - DocLink: "removed-measure", - Version: "1.16.3", - } -} - -func (d deprecations) ParallelNode() Deprecation { - return Deprecation{ - Message: "GinkgoParallelNode is deprecated and will be removed in Ginkgo V2. Please use GinkgoParallelProcess instead.", - DocLink: "renamed-ginkgoparallelnode", - Version: "1.16.5", - } -} - -func (d deprecations) Convert() Deprecation { - return Deprecation{ - Message: "The convert command is deprecated in Ginkgo V2", - DocLink: "removed-ginkgo-convert", - Version: "1.16.0", - } -} - -func (d deprecations) Blur() Deprecation { - return Deprecation{ - Message: "The blur command is deprecated in Ginkgo V2. Use 'ginkgo unfocus' instead.", - Version: "1.16.0", - } -} - -type DeprecationTracker struct { - deprecations map[Deprecation][]CodeLocation -} - -func NewDeprecationTracker() *DeprecationTracker { - return &DeprecationTracker{ - deprecations: map[Deprecation][]CodeLocation{}, - } -} - -func (d *DeprecationTracker) TrackDeprecation(deprecation Deprecation, cl ...CodeLocation) { - ackVersion := os.Getenv("ACK_GINKGO_DEPRECATIONS") - if deprecation.Version != "" && ackVersion != "" { - ack := ParseSemVer(ackVersion) - version := ParseSemVer(deprecation.Version) - if ack.GreaterThanOrEqualTo(version) { - return - } - } - - if len(cl) == 1 { - d.deprecations[deprecation] = append(d.deprecations[deprecation], cl[0]) - } else { - d.deprecations[deprecation] = []CodeLocation{} - } -} - -func (d *DeprecationTracker) DidTrackDeprecations() bool { - return len(d.deprecations) > 0 -} - -func (d *DeprecationTracker) DeprecationsReport() string { - out := formatter.F("\n{{light-yellow}}You're using deprecated Ginkgo functionality:{{/}}\n") - out += formatter.F("{{light-yellow}}============================================={{/}}\n") - out += formatter.F("{{bold}}{{green}}Ginkgo 2.0{{/}} is under active development and will introduce several new features, improvements, and a small handful of breaking changes.\n") - out += formatter.F("A release candidate for 2.0 is now available and 2.0 should GA in Fall 2021. {{bold}}Please give the RC a try and send us feedback!{{/}}\n") - out += formatter.F(" - To learn more, view the migration guide at {{cyan}}{{underline}}https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md{{/}}\n") - out += formatter.F(" - For instructions on using the Release Candidate visit {{cyan}}{{underline}}https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md#using-the-beta{{/}}\n") - out += formatter.F(" - To comment, chime in at {{cyan}}{{underline}}https://github.com/onsi/ginkgo/issues/711{{/}}\n\n") - - for deprecation, locations := range d.deprecations { - out += formatter.Fi(1, "{{yellow}}"+deprecation.Message+"{{/}}\n") - if deprecation.DocLink != "" { - out += formatter.Fi(1, "{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}https://github.com/onsi/ginkgo/blob/ver2/docs/MIGRATING_TO_V2.md#%s{{/}}\n", deprecation.DocLink) - } - for _, location := range locations { - out += formatter.Fi(2, "{{gray}}%s{{/}}\n", location) - } - } - out += formatter.F("\n{{gray}}To silence deprecations that can be silenced set the following environment variable:{{/}}\n") - out += formatter.Fi(1, "{{gray}}ACK_GINKGO_DEPRECATIONS=%s{{/}}\n", config.VERSION) - return out -} - -type SemVer struct { - Major int - Minor int - Patch int -} - -func (s SemVer) GreaterThanOrEqualTo(o SemVer) bool { - return (s.Major > o.Major) || - (s.Major == o.Major && s.Minor > o.Minor) || - (s.Major == o.Major && s.Minor == o.Minor && s.Patch >= o.Patch) -} - -func ParseSemVer(semver string) SemVer { - out := SemVer{} - semver = strings.TrimFunc(semver, func(r rune) bool { - return !(unicode.IsNumber(r) || r == '.') - }) - components := strings.Split(semver, ".") - if len(components) > 0 { - out.Major, _ = strconv.Atoi(components[0]) - } - if len(components) > 1 { - out.Minor, _ = strconv.Atoi(components[1]) - } - if len(components) > 2 { - out.Patch, _ = strconv.Atoi(components[2]) - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/types/synchronization.go b/vendor/github.com/onsi/ginkgo/types/synchronization.go deleted file mode 100644 index fdd6ed5bdf8..00000000000 --- a/vendor/github.com/onsi/ginkgo/types/synchronization.go +++ /dev/null @@ -1,30 +0,0 @@ -package types - -import ( - "encoding/json" -) - -type RemoteBeforeSuiteState int - -const ( - RemoteBeforeSuiteStateInvalid RemoteBeforeSuiteState = iota - - RemoteBeforeSuiteStatePending - RemoteBeforeSuiteStatePassed - RemoteBeforeSuiteStateFailed - RemoteBeforeSuiteStateDisappeared -) - -type RemoteBeforeSuiteData struct { - Data []byte - State RemoteBeforeSuiteState -} - -func (r RemoteBeforeSuiteData) ToJSON() []byte { - data, _ := json.Marshal(r) - return data -} - -type RemoteAfterSuiteData struct { - CanRun bool -} diff --git a/vendor/github.com/onsi/ginkgo/types/types.go b/vendor/github.com/onsi/ginkgo/types/types.go deleted file mode 100644 index c143e02d845..00000000000 --- a/vendor/github.com/onsi/ginkgo/types/types.go +++ /dev/null @@ -1,174 +0,0 @@ -package types - -import ( - "strconv" - "time" -) - -const GINKGO_FOCUS_EXIT_CODE = 197 - -/* -SuiteSummary represents the a summary of the test suite and is passed to both -Reporter.SpecSuiteWillBegin -Reporter.SpecSuiteDidEnd - -this is unfortunate as these two methods should receive different objects. When running in parallel -each node does not deterministically know how many specs it will end up running. - -Unfortunately making such a change would break backward compatibility. - -Until Ginkgo 2.0 comes out we will continue to reuse this struct but populate unknown fields -with -1. -*/ -type SuiteSummary struct { - SuiteDescription string - SuiteSucceeded bool - SuiteID string - - NumberOfSpecsBeforeParallelization int - NumberOfTotalSpecs int - NumberOfSpecsThatWillBeRun int - NumberOfPendingSpecs int - NumberOfSkippedSpecs int - NumberOfPassedSpecs int - NumberOfFailedSpecs int - // Flaked specs are those that failed initially, but then passed on a - // subsequent try. - NumberOfFlakedSpecs int - RunTime time.Duration -} - -type SpecSummary struct { - ComponentTexts []string - ComponentCodeLocations []CodeLocation - - State SpecState - RunTime time.Duration - Failure SpecFailure - IsMeasurement bool - NumberOfSamples int - Measurements map[string]*SpecMeasurement - - CapturedOutput string - SuiteID string -} - -func (s SpecSummary) HasFailureState() bool { - return s.State.IsFailure() -} - -func (s SpecSummary) TimedOut() bool { - return s.State == SpecStateTimedOut -} - -func (s SpecSummary) Panicked() bool { - return s.State == SpecStatePanicked -} - -func (s SpecSummary) Failed() bool { - return s.State == SpecStateFailed -} - -func (s SpecSummary) Passed() bool { - return s.State == SpecStatePassed -} - -func (s SpecSummary) Skipped() bool { - return s.State == SpecStateSkipped -} - -func (s SpecSummary) Pending() bool { - return s.State == SpecStatePending -} - -type SetupSummary struct { - ComponentType SpecComponentType - CodeLocation CodeLocation - - State SpecState - RunTime time.Duration - Failure SpecFailure - - CapturedOutput string - SuiteID string -} - -type SpecFailure struct { - Message string - Location CodeLocation - ForwardedPanic string - - ComponentIndex int - ComponentType SpecComponentType - ComponentCodeLocation CodeLocation -} - -type SpecMeasurement struct { - Name string - Info interface{} - Order int - - Results []float64 - - Smallest float64 - Largest float64 - Average float64 - StdDeviation float64 - - SmallestLabel string - LargestLabel string - AverageLabel string - Units string - Precision int -} - -func (s SpecMeasurement) PrecisionFmt() string { - if s.Precision == 0 { - return "%f" - } - - str := strconv.Itoa(s.Precision) - - return "%." + str + "f" -} - -type SpecState uint - -const ( - SpecStateInvalid SpecState = iota - - SpecStatePending - SpecStateSkipped - SpecStatePassed - SpecStateFailed - SpecStatePanicked - SpecStateTimedOut -) - -func (state SpecState) IsFailure() bool { - return state == SpecStateTimedOut || state == SpecStatePanicked || state == SpecStateFailed -} - -type SpecComponentType uint - -const ( - SpecComponentTypeInvalid SpecComponentType = iota - - SpecComponentTypeContainer - SpecComponentTypeBeforeSuite - SpecComponentTypeAfterSuite - SpecComponentTypeBeforeEach - SpecComponentTypeJustBeforeEach - SpecComponentTypeJustAfterEach - SpecComponentTypeAfterEach - SpecComponentTypeIt - SpecComponentTypeMeasure -) - -type FlagType uint - -const ( - FlagTypeNone FlagType = iota - FlagTypeFocused - FlagTypePending -) diff --git a/vendor/github.com/onsi/gomega/.gitignore b/vendor/github.com/onsi/gomega/.gitignore index 720c13cba84..425d0a509fe 100644 --- a/vendor/github.com/onsi/gomega/.gitignore +++ b/vendor/github.com/onsi/gomega/.gitignore @@ -3,3 +3,5 @@ . .idea gomega.iml +TODO +.vscode \ No newline at end of file diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 4375bbc6461..07a3a5a82b4 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,257 @@ +## 1.27.7 + +### Fixes +- fix: gcustom.MakeMatcher accepts nil as actual value (#666) [57054d5] + +### Maintenance +- update gitignore [05c1bc6] +- Bump github.com/onsi/ginkgo/v2 from 2.9.4 to 2.9.5 (#663) [7cadcf6] +- Bump golang.org/x/net from 0.9.0 to 0.10.0 (#662) [b524839] +- Bump github.com/onsi/ginkgo/v2 from 2.9.2 to 2.9.4 (#661) [5f44694] +- Bump commonmarker from 0.23.8 to 0.23.9 in /docs (#657) [05dc99a] +- Bump nokogiri from 1.14.1 to 1.14.3 in /docs (#658) [3a033d1] +- Replace deprecated NewGomegaWithT with NewWithT (#659) [a19238f] +- Bump golang.org/x/net from 0.8.0 to 0.9.0 (#656) [29ed041] +- Bump actions/setup-go from 3 to 4 (#651) [11b2080] + +## 1.27.6 + +### Fixes +- Allow collections matchers to work correctly when expected has nil elements [60e7cf3] + +### Maintenance +- updates MatchError godoc comment to also accept a Gomega matcher (#654) [67b869d] + +## 1.27.5 + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.9.1 to 2.9.2 (#653) [a215021] +- Bump github.com/go-task/slim-sprig (#652) [a26fed8] + +## 1.27.4 + +### Fixes +- improve error formatting and remove duplication of error message in Eventually/Consistently [854f075] + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.9.0 to 2.9.1 (#650) [ccebd9b] + +## 1.27.3 + +### Fixes +- format.Object now always includes err.Error() when passed an error [86d97ef] +- Fix HaveExactElements to work inside ContainElement or other collection matchers (#648) [636757e] + +### Maintenance +- Bump github.com/golang/protobuf from 1.5.2 to 1.5.3 (#649) [cc16689] +- Bump github.com/onsi/ginkgo/v2 from 2.8.4 to 2.9.0 (#646) [e783366] + +## 1.27.2 + +### Fixes +- improve poll progress message when polling a consistently that has been passing [28a319b] + +### Maintenance +- bump ginkgo +- remove tools.go hack as Ginkgo 2.8.2 automatically pulls in the cli dependencies [81443b3] + +## 1.27.1 + +### Maintenance + +- Bump golang.org/x/net from 0.6.0 to 0.7.0 (#640) [bc686cd] + +## 1.27.0 + +### Features +- Add HaveExactElements matcher (#634) [9d50783] +- update Gomega docs to discuss GinkgoHelper() [be32774] + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.8.0 to 2.8.1 (#639) [296a68b] +- Bump golang.org/x/net from 0.5.0 to 0.6.0 (#638) [c2b098b] +- Bump github-pages from 227 to 228 in /docs (#636) [a9069ab] +- test: update matrix for Go 1.20 (#635) [6bd25c8] +- Bump github.com/onsi/ginkgo/v2 from 2.7.0 to 2.8.0 (#631) [5445f8b] +- Bump webrick from 1.7.0 to 1.8.1 in /docs (#630) [03e93bb] +- codeql: add ruby language (#626) [63c7d21] +- dependabot: add bundler package-ecosystem for docs (#625) [d92f963] + +## 1.26.0 + +### Features +- When a polled function returns an error, keep track of the actual and report on the matcher state of the last non-errored actual [21f3090] +- improve eventually failure message output [c530fb3] + +### Fixes +- fix several documentation spelling issues [e2eff1f] + + +## 1.25.0 + +### Features +- add `MustPassRepeatedly(int)` to asyncAssertion (#619) [4509f72] +- compare unwrapped errors using DeepEqual (#617) [aaeaa5d] + +### Maintenance +- Bump golang.org/x/net from 0.4.0 to 0.5.0 (#614) [c7cfea4] +- Bump github.com/onsi/ginkgo/v2 from 2.6.1 to 2.7.0 (#615) [71b8adb] +- Docs: Fix typo "MUltiple" -> "Multiple" (#616) [9351dda] +- clean up go.sum [cd1dc1d] + +## 1.24.2 + +### Fixes +- Correctly handle assertion failure panics for eventually/consistnetly "g Gomega"s in a goroutine [78f1660] +- docs:Fix typo "you an" -> "you can" (#607) [3187c1f] +- fixes issue #600 (#606) [808d192] + +### Maintenance +- Bump golang.org/x/net from 0.2.0 to 0.4.0 (#611) [6ebc0bf] +- Bump nokogiri from 1.13.9 to 1.13.10 in /docs (#612) [258cfc8] +- Bump github.com/onsi/ginkgo/v2 from 2.5.0 to 2.5.1 (#609) [e6c3eb9] + +## 1.24.1 + +### Fixes +- maintain backward compatibility for Eventually and Consisntetly's signatures [4c7df5e] +- fix small typo (#601) [ea0ebe6] + +### Maintenance +- Bump golang.org/x/net from 0.1.0 to 0.2.0 (#603) [1ba8372] +- Bump github.com/onsi/ginkgo/v2 from 2.4.0 to 2.5.0 (#602) [f9426cb] +- fix label-filter in test.yml [d795db6] +- stop running flakey tests and rely on external network dependencies in CI [7133290] + +## 1.24.0 + +### Features + +Introducting [gcustom](https://onsi.github.io/gomega/#gcustom-a-convenient-mechanism-for-buildling-custom-matchers) - a convenient mechanism for building custom matchers. + +This is an RC release for `gcustom`. The external API may be tweaked in response to feedback however it is expected to remain mostly stable. + +### Maintenance + +- Update BeComparableTo documentation [756eaa0] + +## 1.23.0 + +### Features +- Custom formatting on a per-type basis can be provided using `format.RegisterCustomFormatter()` -- see the docs [here](https://onsi.github.io/gomega/#adjusting-output) + +- Substantial improvement have been made to `StopTrying()`: + - Users can now use `StopTrying().Wrap(err)` to wrap errors and `StopTrying().Attach(description, object)` to attach arbitrary objects to the `StopTrying()` error + - `StopTrying()` is now always interpreted as a failure. If you are an early adopter of `StopTrying()` you may need to change your code as the prior version would match against the returned value even if `StopTrying()` was returned. Going forward the `StopTrying()` api should remain stable. + - `StopTrying()` and `StopTrying().Now()` can both be used in matchers - not just polled functions. + +- `TryAgainAfter(duration)` is used like `StopTrying()` but instructs `Eventually` and `Consistently` that the poll should be tried again after the specified duration. This allows you to dynamically adjust the polling duration. + +- `ctx` can now be passed-in as the first argument to `Eventually` and `Consistently`. + +## Maintenance + +- Bump github.com/onsi/ginkgo/v2 from 2.3.0 to 2.3.1 (#597) [afed901] +- Bump nokogiri from 1.13.8 to 1.13.9 in /docs (#599) [7c691b3] +- Bump github.com/google/go-cmp from 0.5.8 to 0.5.9 (#587) [ff22665] + +## 1.22.1 + +## Fixes +- When passed a context and no explicit timeout, Eventually will only timeout when the context is cancelled [e5105cf] +- Allow StopTrying() to be wrapped [bf3cba9] + +## Maintenance +- bump to ginkgo v2.3.0 [c5d5c39] + +## 1.22.0 + +### Features + +Several improvements have been made to `Eventually` and `Consistently` in this and the most recent releases: + +- Eventually and Consistently can take a context.Context [65c01bc] + This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts. +- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9] +- Eventually/Consistently will forward an attached context to functions that ask for one [e2091c5] +- Eventually/Consistently supports passing arguments to functions via WithArguments() [a2dc7c3] +- Eventually and Consistently can now be stopped early with StopTrying(message) and StopTrying(message).Now() [52976bb] + +These improvements are all documented in [Gomega's docs](https://onsi.github.io/gomega/#making-asynchronous-assertions) + +## Fixes + +## Maintenance + +## 1.21.1 + +### Features +- Eventually and Consistently that are passed a SpecContext can provide reports when an interrupt occurs [0d063c9] + +## 1.21.0 + +### Features +- Eventually and Consistently can take a context.Context [65c01bc] + This enables integration with Ginkgo 2.3.0's interruptible nodes and node timeouts. +- Introduces Eventually.Within.ProbeEvery with tests and documentation (#591) [f633800] +- New BeKeyOf matcher with documentation and unit tests (#590) [fb586b3] + +## Fixes +- Cover the entire gmeasure suite with leak detection [8c54344] +- Fix gmeasure leak [119d4ce] +- Ignore new Ginkgo ProgressSignal goroutine in gleak [ba548e2] + +## Maintenance + +- Fixes crashes on newer Ruby 3 installations by upgrading github-pages gem dependency (#596) [12469a0] + + +## 1.20.2 + +## Fixes +- label specs that rely on remote access; bump timeout on short-circuit test to make it less flaky [35eeadf] +- gexec: allow more headroom for SIGABRT-related unit tests (#581) [5b78f40] +- Enable reading from a closed gbytes.Buffer (#575) [061fd26] + +## Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.1.5 to 2.1.6 (#583) [55d895b] +- Bump github.com/onsi/ginkgo/v2 from 2.1.4 to 2.1.5 (#582) [346de7c] + +## 1.20.1 + +## Fixes +- fix false positive gleaks when using ginkgo -p (#577) [cb46517] +- Fix typos in gomega_dsl.go (#569) [5f71ed2] +- don't panic on Eventually(nil), fixing #555 (#567) [9d1186f] +- vet optional description args in assertions, fixing #560 (#566) [8e37808] + +## Maintenance +- test: add new Go 1.19 to test matrix (#571) [40d7efe] +- Bump tzinfo from 1.2.9 to 1.2.10 in /docs (#564) [5f26371] + +## 1.20.0 + +## Features +- New [`gleak`](https://onsi.github.io/gomega/#codegleakcode-finding-leaked-goroutines) experimental goroutine leak detection package! (#538) [85ba7bc] +- New `BeComparableTo` matcher(#546) that uses `gocmp` to make comparisons [e77ea75] +- New `HaveExistingField` matcher (#553) [fd130e1] +- Document how to wrap Gomega (#539) [56714a4] + +## Fixes +- Support pointer receivers in HaveField; fixes #543 (#544) [8dab36e] + +## Maintenance +- Bump various dependencies: + - Upgrade to yaml.v3 (#556) [f5a83b1] + - Bump github/codeql-action from 1 to 2 (#549) [52f5adf] + - Bump github.com/google/go-cmp from 0.5.7 to 0.5.8 (#551) [5f3942d] + - Bump nokogiri from 1.13.4 to 1.13.6 in /docs (#554) [eb4b4c2] + - Use latest ginkgo (#535) [1c29028] + - Bump nokogiri from 1.13.3 to 1.13.4 in /docs (#541) [1ce84d5] + - Bump actions/setup-go from 2 to 3 (#540) [755485e] + - Bump nokogiri from 1.12.5 to 1.13.3 in /docs (#522) [4fbb0dc] + - Bump actions/checkout from 2 to 3 (#526) [ac49202] + ## 1.19.0 ## Features diff --git a/vendor/github.com/onsi/gomega/RELEASING.md b/vendor/github.com/onsi/gomega/RELEASING.md index 2d30d9992f3..9973fff49e0 100644 --- a/vendor/github.com/onsi/gomega/RELEASING.md +++ b/vendor/github.com/onsi/gomega/RELEASING.md @@ -1,7 +1,13 @@ A Gomega release is a tagged sha and a GitHub release. To cut a release: 1. Ensure CHANGELOG.md is up to date. - - Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release + - Use + ```bash + LAST_VERSION=$(git tag --sort=version:refname | tail -n1) + CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) + echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md + ``` + to update the changelog - Categorize the changes into - Breaking Changes (requires a major version) - New Features (minor version) diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go index 6e78c391df2..56bdd053bbc 100644 --- a/vendor/github.com/onsi/gomega/format/format.go +++ b/vendor/github.com/onsi/gomega/format/format.go @@ -52,7 +52,7 @@ var CharactersAroundMismatchToInclude uint = 5 var contextType = reflect.TypeOf((*context.Context)(nil)).Elem() var timeType = reflect.TypeOf(time.Time{}) -//The default indentation string emitted by the format package +// The default indentation string emitted by the format package var Indent = " " var longFormThreshold = 20 @@ -65,6 +65,52 @@ type GomegaStringer interface { GomegaString() string } +/* +CustomFormatters can be registered with Gomega via RegisterCustomFormatter() +Any value to be rendered by Gomega is passed to each registered CustomFormatters. +The CustomFormatter signals that it will handle formatting the value by returning (formatted-string, true) +If the CustomFormatter does not want to handle the object it should return ("", false) + +Strings returned by CustomFormatters are not truncated +*/ +type CustomFormatter func(value interface{}) (string, bool) +type CustomFormatterKey uint + +var customFormatterKey CustomFormatterKey = 1 + +type customFormatterKeyPair struct { + CustomFormatter + CustomFormatterKey +} + +/* +RegisterCustomFormatter registers a CustomFormatter and returns a CustomFormatterKey + +You can call UnregisterCustomFormatter with the returned key to unregister the associated CustomFormatter +*/ +func RegisterCustomFormatter(customFormatter CustomFormatter) CustomFormatterKey { + key := customFormatterKey + customFormatterKey += 1 + customFormatters = append(customFormatters, customFormatterKeyPair{customFormatter, key}) + return key +} + +/* +UnregisterCustomFormatter unregisters a previously registered CustomFormatter. You should pass in the key returned by RegisterCustomFormatter +*/ +func UnregisterCustomFormatter(key CustomFormatterKey) { + formatters := []customFormatterKeyPair{} + for _, f := range customFormatters { + if f.CustomFormatterKey == key { + continue + } + formatters = append(formatters, f) + } + customFormatters = formatters +} + +var customFormatters = []customFormatterKeyPair{} + /* Generates a formatted matcher success/failure message of the form: @@ -212,24 +258,35 @@ Set PrintContextObjects to true to print the content of objects implementing con func Object(object interface{}, indentation uint) string { indent := strings.Repeat(Indent, int(indentation)) value := reflect.ValueOf(object) - return fmt.Sprintf("%s<%s>: %s", indent, formatType(value), formatValue(value, indentation)) + commonRepresentation := "" + if err, ok := object.(error); ok { + commonRepresentation += "\n" + IndentString(err.Error(), indentation) + "\n" + indent + } + return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation)) } /* IndentString takes a string and indents each line by the specified amount. */ func IndentString(s string, indentation uint) string { + return indentString(s, indentation, true) +} + +func indentString(s string, indentation uint, indentFirstLine bool) string { + result := &strings.Builder{} components := strings.Split(s, "\n") - result := "" indent := strings.Repeat(Indent, int(indentation)) for i, component := range components { - result += indent + component + if i > 0 || indentFirstLine { + result.WriteString(indent) + } + result.WriteString(component) if i < len(components)-1 { - result += "\n" + result.WriteString("\n") } } - return result + return result.String() } func formatType(v reflect.Value) string { @@ -261,18 +318,27 @@ func formatValue(value reflect.Value, indentation uint) string { if value.CanInterface() { obj := value.Interface() + // if a CustomFormatter handles this values, we'll go with that + for _, customFormatter := range customFormatters { + formatted, handled := customFormatter.CustomFormatter(obj) + // do not truncate a user-provided CustomFormatter() + if handled { + return indentString(formatted, indentation+1, false) + } + } + // GomegaStringer will take precedence to other representations and disregards UseStringerRepresentation if x, ok := obj.(GomegaStringer); ok { - // do not truncate a user-defined GoMegaString() value - return x.GomegaString() + // do not truncate a user-defined GomegaString() value + return indentString(x.GomegaString(), indentation+1, false) } if UseStringerRepresentation { switch x := obj.(type) { case fmt.GoStringer: - return truncateLongStrings(x.GoString()) + return indentString(truncateLongStrings(x.GoString()), indentation+1, false) case fmt.Stringer: - return truncateLongStrings(x.String()) + return indentString(truncateLongStrings(x.String()), indentation+1, false) } } } diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index dcb7e8879d3..82ef5244513 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.19.0" +const GOMEGA_VERSION = "1.27.7" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). @@ -34,7 +34,7 @@ Depending on your vendoring solution you may be inadvertently importing gomega a // to abstract between the standard package-level function implementations // and alternatives like *WithT. // -// The types in the top-level DSL have gotten a bit messy due to earlier depracations that avoid stuttering +// The types in the top-level DSL have gotten a bit messy due to earlier deprecations that avoid stuttering // and due to an accidental use of a concrete type (*WithT) in an earlier release. // // As of 1.15 both the WithT and Ginkgo variants of Gomega are implemented by the same underlying object @@ -83,15 +83,15 @@ func internalGomega(g Gomega) *internal.Gomega { return g.(*internal.Gomega) } -// NewWithT takes a *testing.T and returngs a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with +// NewWithT takes a *testing.T and returns a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with // Gomega's rich ecosystem of matchers in standard `testing` test suits. // -// func TestFarmHasCow(t *testing.T) { -// g := gomega.NewWithT(t) +// func TestFarmHasCow(t *testing.T) { +// g := gomega.NewWithT(t) // -// f := farm.New([]string{"Cow", "Horse"}) -// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") -// } +// f := farm.New([]string{"Cow", "Horse"}) +// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") +// } func NewWithT(t types.GomegaTestingT) *WithT { return internal.NewGomega(internalGomega(Default).DurationBundle).ConfigureWithT(t) } @@ -120,7 +120,7 @@ func RegisterTestingT(t types.GomegaTestingT) { // InterceptGomegaFailures runs a given callback and returns an array of // failure messages generated by any Gomega assertions within the callback. -// Exeuction continues after the first failure allowing users to collect all failures +// Execution continues after the first failure allowing users to collect all failures // in the callback. // // This is most useful when testing custom matchers, but can also be used to check @@ -171,7 +171,8 @@ func ensureDefaultGomegaIsConfigured() { } // Ω wraps an actual value allowing assertions to be made on it: -// Ω("foo").Should(Equal("foo")) +// +// Ω("foo").Should(Equal("foo")) // // If Ω is passed more than one argument it will pass the *first* argument to the matcher. // All subsequent arguments will be required to be nil/zero. @@ -180,10 +181,13 @@ func ensureDefaultGomegaIsConfigured() { // a value and an error - a common patter in Go. // // For example, given a function with signature: -// func MyAmazingThing() (int, error) +// +// func MyAmazingThing() (int, error) // // Then: -// Ω(MyAmazingThing()).Should(Equal(3)) +// +// Ω(MyAmazingThing()).Should(Equal(3)) +// // Will succeed only if `MyAmazingThing()` returns `(3, nil)` // // Ω and Expect are identical @@ -193,19 +197,23 @@ func Ω(actual interface{}, extra ...interface{}) Assertion { } // Expect wraps an actual value allowing assertions to be made on it: -// Expect("foo").To(Equal("foo")) +// +// Expect("foo").To(Equal("foo")) // // If Expect is passed more than one argument it will pass the *first* argument to the matcher. // All subsequent arguments will be required to be nil/zero. // // This is convenient if you want to make an assertion on a method/function that returns -// a value and an error - a common patter in Go. +// a value and an error - a common pattern in Go. // // For example, given a function with signature: -// func MyAmazingThing() (int, error) +// +// func MyAmazingThing() (int, error) // // Then: -// Expect(MyAmazingThing()).Should(Equal(3)) +// +// Expect(MyAmazingThing()).Should(Equal(3)) +// // Will succeed only if `MyAmazingThing()` returns `(3, nil)` // // Expect and Ω are identical @@ -215,7 +223,8 @@ func Expect(actual interface{}, extra ...interface{}) Assertion { } // ExpectWithOffset wraps an actual value allowing assertions to be made on it: -// ExpectWithOffset(1, "foo").To(Equal("foo")) +// +// ExpectWithOffset(1, "foo").To(Equal("foo")) // // Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument // that is used to modify the call-stack offset when computing line numbers. It is @@ -233,7 +242,7 @@ func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Asse Eventually enables making assertions on asynchronous behavior. Eventually checks that an assertion *eventually* passes. Eventually blocks when called and attempts an assertion periodically until it passes or a timeout occurs. Both the timeout and polling interval are configurable as optional arguments. -The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). +The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). In addition an optional context.Context can be passed in - Eventually will keep trying until either the timeout epxires or the context is cancelled, whichever comes first. Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value: @@ -241,15 +250,15 @@ Eventually works with any Gomega compatible matcher and supports making assertio There are several examples of values that can change over time. These can be passed in to Eventually and will be passed to the matcher repeatedly until a match occurs. For example: - c := make(chan bool) - go DoStuff(c) - Eventually(c, "50ms").Should(BeClosed()) + c := make(chan bool) + go DoStuff(c) + Eventually(c, "50ms").Should(BeClosed()) will poll the channel repeatedly until it is closed. In this example `Eventually` will block until either the specified timeout of 50ms has elapsed or the channel is closed, whichever comes first. -Several Gomega libraries allow you to use Eventually in this way. For example, the gomega/gexec package allows you to block until a *gexec.Session exits successfuly via: +Several Gomega libraries allow you to use Eventually in this way. For example, the gomega/gexec package allows you to block until a *gexec.Session exits successfully via: - Eventually(session).Should(gexec.Exit(0)) + Eventually(session).Should(gexec.Exit(0)) And the gomega/gbytes package allows you to monitor a streaming *gbytes.Buffer until a given string is seen: @@ -266,33 +275,57 @@ this will trigger Go's race detector as the goroutine polling via Eventually wil **Category 2: Make Eventually assertions on functions** -Eventually can be passed functions that **take no arguments** and **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher. +Eventually can be passed functions that **return at least one value**. When configured this way, Eventually will poll the function repeatedly and pass the first returned value to the matcher. For example: - Eventually(func() int { - return client.FetchCount() - }).Should(BeNumerically(">=", 17)) + Eventually(func() int { + return client.FetchCount() + }).Should(BeNumerically(">=", 17)) - will repeatedly poll client.FetchCount until the BeNumerically matcher is satisfied. (Note that this example could have been written as Eventually(client.FetchCount).Should(BeNumerically(">=", 17))) + will repeatedly poll client.FetchCount until the BeNumerically matcher is satisfied. (Note that this example could have been written as Eventually(client.FetchCount).Should(BeNumerically(">=", 17))) -If multple values are returned by the function, Eventually will pass the first value to the matcher and require that all others are zero-valued. This allows you to pass Eventually a function that returns a value and an error - a common patternin Go. +If multiple values are returned by the function, Eventually will pass the first value to the matcher and require that all others are zero-valued. This allows you to pass Eventually a function that returns a value and an error - a common pattern in Go. For example, consider a method that returns a value and an error: - func FetchFromDB() (string, error) + + func FetchFromDB() (string, error) Then - Eventually(FetchFromDB).Should(Equal("got it")) + + Eventually(FetchFromDB).Should(Equal("got it")) will pass only if and when the returned error is nil *and* the returned string satisfies the matcher. -It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. You should design your functions with this in mind. +Eventually can also accept functions that take arguments, however you must provide those arguments using .WithArguments(). For example, consider a function that takes a user-id and makes a network request to fetch a full name: + + func FetchFullName(userId int) (string, error) + +You can poll this function like so: + + Eventually(FetchFullName).WithArguments(1138).Should(Equal("Wookie")) + +It is important to note that the function passed into Eventually is invoked *synchronously* when polled. Eventually does not (in fact, it cannot) kill the function if it takes longer to return than Eventually's configured timeout. A common practice here is to use a context. Here's an example that combines Ginkgo's spec timeout support with Eventually: + + It("fetches the correct count", func(ctx SpecContext) { + Eventually(ctx, func() int { + return client.FetchCount(ctx, "/users") + }).Should(BeNumerically(">=", 17)) + }, SpecTimeout(time.Second)) + +you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in contexts play nicely with paseed-in arguments as long as the context appears first. You can rewrite the above example as: + + It("fetches the correct count", func(ctx SpecContext) { + Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17)) + }, SpecTimeout(time.Second)) + +Either way the context passd to Eventually is also passed to the underlying funciton. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit. **Category 3: Making assertions _in_ the function passed into Eventually** When testing complex systems it can be valuable to assert that a _set_ of assertions passes Eventually. Eventually supports this by accepting functions that take a single Gomega argument and return zero or more values. -Here's an example that makes some asssertions and returns a value and error: +Here's an example that makes some assertions and returns a value and error: Eventually(func(g Gomega) (Widget, error) { ids, err := client.FetchIDs() @@ -306,22 +339,48 @@ will pass only if all the assertions in the polled function pass and the return Eventually also supports a special case polling function that takes a single Gomega argument and returns no values. Eventually assumes such a function is making assertions and is designed to work with the Succeed matcher to validate that all assertions have passed. For example: - Eventually(func(g Gomega) { - model, err := client.Find(1138) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(model.Reticulate()).To(Succeed()) - g.Expect(model.IsReticulated()).To(BeTrue()) - g.Expect(model.Save()).To(Succeed()) - }).Should(Succeed()) + Eventually(func(g Gomega) { + model, err := client.Find(1138) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(model.Reticulate()).To(Succeed()) + g.Expect(model.IsReticulated()).To(BeTrue()) + g.Expect(model.Save()).To(Succeed()) + }).Should(Succeed()) will rerun the function until all assertions pass. -`Eventually` specifying a timeout interval (and an optional polling interval) are -the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`. +You can also pass additional arugments to functions that take a Gomega. The only rule is that the Gomega argument must be first. If you also want to pass the context attached to Eventually you must ensure that is the second argument. For example: + + Eventually(func(g Gomega, ctx context.Context, path string, expected ...string){ + tok, err := client.GetToken(ctx) + g.Expect(err).NotTo(HaveOccurred()) + + elements, err := client.Fetch(ctx, tok, path) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(elements).To(ConsistOf(expected)) + }).WithContext(ctx).WithArguments("/names", "Joe", "Jane", "Sam").Should(Succeed()) + +You can ensure that you get a number of consecutive successful tries before succeeding using `MustPassRepeatedly(int)`. For Example: + + int count := 0 + Eventually(func() bool { + count++ + return count > 2 + }).MustPassRepeatedly(2).Should(BeTrue()) + // Because we had to wait for 2 calls that returned true + Expect(count).To(Equal(3)) + +Finally, in addition to passing timeouts and a context to Eventually you can be more explicit with Eventually's chaining configuration methods: + + Eventually(..., "1s", "2s", ctx).Should(...) + +is equivalent to + + Eventually(...).WithTimeout(time.Second).WithPolling(2*time.Second).WithContext(ctx).Should(...) */ -func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { +func Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.Eventually(actual, intervals...) + return Default.Eventually(actualOrCtx, args...) } // EventuallyWithOffset operates like Eventually but takes an additional @@ -333,9 +392,9 @@ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { // `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are // the same as `Eventually(...).WithOffset(...).WithTimeout` or // `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`. -func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { +func EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.EventuallyWithOffset(offset, actual, intervals...) + return Default.EventuallyWithOffset(offset, actualOrCtx, args...) } /* @@ -343,19 +402,19 @@ Consistently, like Eventually, enables making assertions on asynchronous behavio Consistently blocks when called for a specified duration. During that duration Consistently repeatedly polls its matcher and ensures that it is satisfied. If the matcher is consistently satisfied, then Consistently will pass. Otherwise Consistently will fail. -Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional arugment is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds. +Both the total waiting duration and the polling interval are configurable as optional arguments. The first optional argument is the duration that Consistently will run for (defaults to 100ms), and the second argument is the polling interval (defaults to 10ms). As with Eventually, these intervals can be passed in as time.Duration, parsable duration strings or an integer or float number of seconds. You can also pass in an optional context.Context - Consistently will exit early (with a failure) if the context is cancelled before the waiting duration expires. Consistently accepts the same three categories of actual as Eventually, check the Eventually docs to learn more. Consistently is useful in cases where you want to assert that something *does not happen* for a period of time. For example, you may want to assert that a goroutine does *not* send data down a channel. In this case you could write: - Consistently(channel, "200ms").ShouldNot(Receive()) + Consistently(channel, "200ms").ShouldNot(Receive()) This will block for 200 milliseconds and repeatedly check the channel and ensure nothing has been received. */ -func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { +func Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.Consistently(actual, intervals...) + return Default.Consistently(actualOrCtx, args...) } // ConsistentlyWithOffset operates like Consistently but takes an additional @@ -364,11 +423,54 @@ func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { // // `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and // optional `WithTimeout` and `WithPolling`. -func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { +func ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() - return Default.ConsistentlyWithOffset(offset, actual, intervals...) + return Default.ConsistentlyWithOffset(offset, actualOrCtx, args...) } +/* +StopTrying can be used to signal to Eventually and Consistentlythat they should abort and stop trying. This always results in a failure of the assertion - and the failure message is the content of the StopTrying signal. + +You can send the StopTrying signal by either returning StopTrying("message") as an error from your passed-in function _or_ by calling StopTrying("message").Now() to trigger a panic and end execution. + +You can also wrap StopTrying around an error with `StopTrying("message").Wrap(err)` and can attach additional objects via `StopTrying("message").Attach("description", object). When rendered, the signal will include the wrapped error and any attached objects rendered using Gomega's default formatting. + +Here are a couple of examples. This is how you might use StopTrying() as an error to signal that Eventually should stop: + + playerIndex, numPlayers := 0, 11 + Eventually(func() (string, error) { + if playerIndex == numPlayers { + return "", StopTrying("no more players left") + } + name := client.FetchPlayer(playerIndex) + playerIndex += 1 + return name, nil + }).Should(Equal("Patrick Mahomes")) + +And here's an example where `StopTrying().Now()` is called to halt execution immediately: + + Eventually(func() []string { + names, err := client.FetchAllPlayers() + if err == client.IRRECOVERABLE_ERROR { + StopTrying("Irrecoverable error occurred").Wrap(err).Now() + } + return names + }).Should(ContainElement("Patrick Mahomes")) +*/ +var StopTrying = internal.StopTrying + +/* +TryAgainAfter() allows you to adjust the polling interval for the _next_ iteration of `Eventually` or `Consistently`. Like `StopTrying` you can either return `TryAgainAfter` as an error or trigger it immedieately with `.Now()` + +When `TryAgainAfter(` is triggered `Eventually` and `Consistently` will wait for that duration. If a timeout occurs before the next poll is triggered both `Eventually` and `Consistently` will always fail with the content of the TryAgainAfter message. As with StopTrying you can `.Wrap()` and error and `.Attach()` additional objects to `TryAgainAfter`. +*/ +var TryAgainAfter = internal.TryAgainAfter + +/* +PollingSignalError is the error returned by StopTrying() and TryAgainAfter() +*/ +type PollingSignalError = internal.PollingSignalError + // SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses. func SetDefaultEventuallyTimeout(t time.Duration) { Default.SetDefaultEventuallyTimeout(t) @@ -402,8 +504,8 @@ func SetDefaultConsistentlyPollingInterval(t time.Duration) { // // Example: // -// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.") -// Consistently(myChannel).ShouldNot(Receive(), func() string { return "Nothing should have come down the pipe." }) +// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.") +// Consistently(myChannel).ShouldNot(Receive(), func() string { return "Nothing should have come down the pipe." }) type AsyncAssertion = types.AsyncAssertion // GomegaAsyncAssertion is deprecated in favor of AsyncAssertion, which does not stutter. @@ -425,7 +527,7 @@ type GomegaAsyncAssertion = types.AsyncAssertion // // Example: // -// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm) +// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm) type Assertion = types.Assertion // GomegaAssertion is deprecated in favor of Assertion, which does not stutter. diff --git a/vendor/github.com/onsi/gomega/internal/assertion.go b/vendor/github.com/onsi/gomega/internal/assertion.go index b3c26889a10..08356a610bb 100644 --- a/vendor/github.com/onsi/gomega/internal/assertion.go +++ b/vendor/github.com/onsi/gomega/internal/assertion.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" + "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" ) @@ -45,26 +46,31 @@ func (assertion *Assertion) Error() types.Assertion { func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Assertion", optionalDescription...) return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...) } func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Assertion", optionalDescription...) return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Assertion", optionalDescription...) return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, true, optionalDescription...) } func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Assertion", optionalDescription...) return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Assertion", optionalDescription...) return assertion.vet(assertion, optionalDescription...) && assertion.match(matcher, false, optionalDescription...) } @@ -141,7 +147,12 @@ func vetActuals(actuals []interface{}, skipIndex int) (bool, string) { if actual != nil { zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface() if !reflect.DeepEqual(zeroValue, actual) { - message := fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual) + var message string + if err, ok := actual.(error); ok { + message = fmt.Sprintf("Unexpected error: %s\n%s", err, format.Object(err, 1)) + } else { + message = fmt.Sprintf("Unexpected non-nil/non-zero argument at index %d:\n\t<%T>: %#v", i, actual, actual) + } return false, message } } diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go index 99f4ebcfe71..1188b0bce37 100644 --- a/vendor/github.com/onsi/gomega/internal/async_assertion.go +++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go @@ -1,15 +1,53 @@ package internal import ( + "context" "errors" "fmt" "reflect" "runtime" + "sync" "time" + "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" ) +var errInterface = reflect.TypeOf((*error)(nil)).Elem() +var gomegaType = reflect.TypeOf((*types.Gomega)(nil)).Elem() +var contextType = reflect.TypeOf(new(context.Context)).Elem() + +type formattedGomegaError interface { + FormattedGomegaError() string +} + +type asyncPolledActualError struct { + message string +} + +func (err *asyncPolledActualError) Error() string { + return err.message +} + +func (err *asyncPolledActualError) FormattedGomegaError() string { + return err.message +} + +type contextWithAttachProgressReporter interface { + AttachProgressReporter(func() string) func() +} + +type asyncGomegaHaltExecutionError struct{} + +func (a asyncGomegaHaltExecutionError) GinkgoRecoverShouldIgnoreThisPanic() {} +func (a asyncGomegaHaltExecutionError) Error() string { + return `An assertion has failed in a goroutine. You should call + + defer GinkgoRecover() + +at the top of the goroutine that caused this panic. This will allow Ginkgo and Gomega to correctly capture and manage this panic.` +} + type AsyncAssertionType uint const ( @@ -17,71 +55,45 @@ const ( AsyncAssertionTypeConsistently ) +func (at AsyncAssertionType) String() string { + switch at { + case AsyncAssertionTypeEventually: + return "Eventually" + case AsyncAssertionTypeConsistently: + return "Consistently" + } + return "INVALID ASYNC ASSERTION TYPE" +} + type AsyncAssertion struct { asyncType AsyncAssertionType - actualIsFunc bool - actualValue interface{} - actualFunc func() ([]reflect.Value, error) + actualIsFunc bool + actual interface{} + argsToForward []interface{} - timeoutInterval time.Duration - pollingInterval time.Duration - offset int - g *Gomega + timeoutInterval time.Duration + pollingInterval time.Duration + mustPassRepeatedly int + ctx context.Context + offset int + g *Gomega } -func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, offset int) *AsyncAssertion { +func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g *Gomega, timeoutInterval time.Duration, pollingInterval time.Duration, mustPassRepeatedly int, ctx context.Context, offset int) *AsyncAssertion { out := &AsyncAssertion{ - asyncType: asyncType, - timeoutInterval: timeoutInterval, - pollingInterval: pollingInterval, - offset: offset, - g: g, + asyncType: asyncType, + timeoutInterval: timeoutInterval, + pollingInterval: pollingInterval, + mustPassRepeatedly: mustPassRepeatedly, + offset: offset, + ctx: ctx, + g: g, } - switch actualType := reflect.TypeOf(actualInput); { - case actualType.Kind() != reflect.Func: - out.actualValue = actualInput - case actualType.NumIn() == 0 && actualType.NumOut() > 0: + out.actual = actualInput + if actualInput != nil && reflect.TypeOf(actualInput).Kind() == reflect.Func { out.actualIsFunc = true - out.actualFunc = func() ([]reflect.Value, error) { - return reflect.ValueOf(actualInput).Call([]reflect.Value{}), nil - } - case actualType.NumIn() == 1 && actualType.In(0).Implements(reflect.TypeOf((*types.Gomega)(nil)).Elem()): - out.actualIsFunc = true - out.actualFunc = func() (values []reflect.Value, err error) { - var assertionFailure error - assertionCapturingGomega := NewGomega(g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) { - skip := 0 - if len(callerSkip) > 0 { - skip = callerSkip[0] - } - _, file, line, _ := runtime.Caller(skip + 1) - assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message) - panic("stop execution") - }) - - defer func() { - if actualType.NumOut() == 0 { - if assertionFailure == nil { - values = []reflect.Value{reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())} - } else { - values = []reflect.Value{reflect.ValueOf(assertionFailure)} - } - } else { - err = assertionFailure - } - if e := recover(); e != nil && assertionFailure == nil { - panic(e) - } - }() - - values = reflect.ValueOf(actualInput).Call([]reflect.Value{reflect.ValueOf(assertionCapturingGomega)}) - return - } - default: - msg := fmt.Sprintf("The function passed to Gomega's async assertions should either take no arguments and return values, or take a single Gomega interface that it can use to make assertions within the body of the function. When taking a Gomega interface the function can optionally return values or return nothing. The function you passed takes %d arguments and returns %d values.", actualType.NumIn(), actualType.NumOut()) - g.Fail(msg, offset+4) } return out @@ -102,13 +114,40 @@ func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.Async return assertion } +func (assertion *AsyncAssertion) Within(timeout time.Duration) types.AsyncAssertion { + assertion.timeoutInterval = timeout + return assertion +} + +func (assertion *AsyncAssertion) ProbeEvery(interval time.Duration) types.AsyncAssertion { + assertion.pollingInterval = interval + return assertion +} + +func (assertion *AsyncAssertion) WithContext(ctx context.Context) types.AsyncAssertion { + assertion.ctx = ctx + return assertion +} + +func (assertion *AsyncAssertion) WithArguments(argsToForward ...interface{}) types.AsyncAssertion { + assertion.argsToForward = argsToForward + return assertion +} + +func (assertion *AsyncAssertion) MustPassRepeatedly(count int) types.AsyncAssertion { + assertion.mustPassRepeatedly = count + return assertion +} + func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Asynchronous assertion", optionalDescription...) return assertion.match(matcher, true, optionalDescription...) } func (assertion *AsyncAssertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() + vetOptionalDescription("Asynchronous assertion", optionalDescription...) return assertion.match(matcher, false, optionalDescription...) } @@ -124,112 +163,409 @@ func (assertion *AsyncAssertion) buildDescription(optionalDescription ...interfa return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n" } -func (assertion *AsyncAssertion) pollActual() (interface{}, error) { +func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (interface{}, error) { + if len(values) == 0 { + return nil, &asyncPolledActualError{ + message: fmt.Sprintf("The function passed to %s did not return any values", assertion.asyncType), + } + } + + actual := values[0].Interface() + if _, ok := AsPollingSignalError(actual); ok { + return actual, actual.(error) + } + + var err error + for i, extraValue := range values[1:] { + extra := extraValue.Interface() + if extra == nil { + continue + } + if _, ok := AsPollingSignalError(extra); ok { + return actual, extra.(error) + } + extraType := reflect.TypeOf(extra) + zero := reflect.Zero(extraType).Interface() + if reflect.DeepEqual(extra, zero) { + continue + } + if i == len(values)-2 && extraType.Implements(errInterface) { + err = extra.(error) + } + if err == nil { + err = &asyncPolledActualError{ + message: fmt.Sprintf("The function passed to %s had an unexpected non-nil/non-zero return value at index %d:\n%s", assertion.asyncType, i+1, format.Object(extra, 1)), + } + } + } + + return actual, err +} + +func (assertion *AsyncAssertion) invalidFunctionError(t reflect.Type) error { + return fmt.Errorf(`The function passed to %s had an invalid signature of %s. Functions passed to %s must either: + + (a) have return values or + (b) take a Gomega interface as their first argument and use that Gomega instance to make assertions. + +You can learn more at https://onsi.github.io/gomega/#eventually +`, assertion.asyncType, t, assertion.asyncType) +} + +func (assertion *AsyncAssertion) noConfiguredContextForFunctionError() error { + return fmt.Errorf(`The function passed to %s requested a context.Context, but no context has been provided. Please pass one in using %s().WithContext(). + +You can learn more at https://onsi.github.io/gomega/#eventually +`, assertion.asyncType, assertion.asyncType) +} + +func (assertion *AsyncAssertion) argumentMismatchError(t reflect.Type, numProvided int) error { + have := "have" + if numProvided == 1 { + have = "has" + } + return fmt.Errorf(`The function passed to %s has signature %s takes %d arguments but %d %s been provided. Please use %s().WithArguments() to pass the corect set of arguments. + +You can learn more at https://onsi.github.io/gomega/#eventually +`, assertion.asyncType, t, t.NumIn(), numProvided, have, assertion.asyncType) +} + +func (assertion *AsyncAssertion) invalidMustPassRepeatedlyError(reason string) error { + return fmt.Errorf(`Invalid use of MustPassRepeatedly with %s %s + +You can learn more at https://onsi.github.io/gomega/#eventually +`, assertion.asyncType, reason) +} + +func (assertion *AsyncAssertion) buildActualPoller() (func() (interface{}, error), error) { if !assertion.actualIsFunc { - return assertion.actualValue, nil + return func() (interface{}, error) { return assertion.actual, nil }, nil } + actualValue := reflect.ValueOf(assertion.actual) + actualType := reflect.TypeOf(assertion.actual) + numIn, numOut, isVariadic := actualType.NumIn(), actualType.NumOut(), actualType.IsVariadic() - values, err := assertion.actualFunc() - if err != nil { - return nil, err + if numIn == 0 && numOut == 0 { + return nil, assertion.invalidFunctionError(actualType) } - extras := []interface{}{nil} - for _, value := range values[1:] { - extras = append(extras, value.Interface()) + takesGomega, takesContext := false, false + if numIn > 0 { + takesGomega, takesContext = actualType.In(0).Implements(gomegaType), actualType.In(0).Implements(contextType) } - success, message := vetActuals(extras, 0) - if !success { - return nil, errors.New(message) + if takesGomega && numIn > 1 && actualType.In(1).Implements(contextType) { + takesContext = true + } + if takesContext && len(assertion.argsToForward) > 0 && reflect.TypeOf(assertion.argsToForward[0]).Implements(contextType) { + takesContext = false + } + if !takesGomega && numOut == 0 { + return nil, assertion.invalidFunctionError(actualType) + } + if takesContext && assertion.ctx == nil { + return nil, assertion.noConfiguredContextForFunctionError() + } + + var assertionFailure error + inValues := []reflect.Value{} + if takesGomega { + inValues = append(inValues, reflect.ValueOf(NewGomega(assertion.g.DurationBundle).ConfigureWithFailHandler(func(message string, callerSkip ...int) { + skip := 0 + if len(callerSkip) > 0 { + skip = callerSkip[0] + } + _, file, line, _ := runtime.Caller(skip + 1) + assertionFailure = &asyncPolledActualError{ + message: fmt.Sprintf("The function passed to %s failed at %s:%d with:\n%s", assertion.asyncType, file, line, message), + } + // we throw an asyncGomegaHaltExecutionError so that defer GinkgoRecover() can catch this error if the user makes an assertion in a goroutine + panic(asyncGomegaHaltExecutionError{}) + }))) + } + if takesContext { + inValues = append(inValues, reflect.ValueOf(assertion.ctx)) + } + for _, arg := range assertion.argsToForward { + inValues = append(inValues, reflect.ValueOf(arg)) + } + + if !isVariadic && numIn != len(inValues) { + return nil, assertion.argumentMismatchError(actualType, len(inValues)) + } else if isVariadic && len(inValues) < numIn-1 { + return nil, assertion.argumentMismatchError(actualType, len(inValues)) } - return values[0].Interface(), nil + if assertion.mustPassRepeatedly != 1 && assertion.asyncType != AsyncAssertionTypeEventually { + return nil, assertion.invalidMustPassRepeatedlyError("it can only be used with Eventually") + } + if assertion.mustPassRepeatedly < 1 { + return nil, assertion.invalidMustPassRepeatedlyError("parameter can't be < 1") + } + + return func() (actual interface{}, err error) { + var values []reflect.Value + assertionFailure = nil + defer func() { + if numOut == 0 && takesGomega { + actual = assertionFailure + } else { + actual, err = assertion.processReturnValues(values) + _, isAsyncError := AsPollingSignalError(err) + if assertionFailure != nil && !isAsyncError { + err = assertionFailure + } + } + if e := recover(); e != nil { + if _, isAsyncError := AsPollingSignalError(e); isAsyncError { + err = e.(error) + } else if assertionFailure == nil { + panic(e) + } + } + }() + values = actualValue.Call(inValues) + return + }, nil +} + +func (assertion *AsyncAssertion) afterTimeout() <-chan time.Time { + if assertion.timeoutInterval >= 0 { + return time.After(assertion.timeoutInterval) + } + + if assertion.asyncType == AsyncAssertionTypeConsistently { + return time.After(assertion.g.DurationBundle.ConsistentlyDuration) + } else { + if assertion.ctx == nil { + return time.After(assertion.g.DurationBundle.EventuallyTimeout) + } else { + return nil + } + } } -func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool { - if assertion.actualIsFunc { - return true +func (assertion *AsyncAssertion) afterPolling() <-chan time.Time { + if assertion.pollingInterval >= 0 { + return time.After(assertion.pollingInterval) } - return types.MatchMayChangeInTheFuture(matcher, value) + if assertion.asyncType == AsyncAssertionTypeConsistently { + return time.After(assertion.g.DurationBundle.ConsistentlyPollingInterval) + } else { + return time.After(assertion.g.DurationBundle.EventuallyPollingInterval) + } +} + +func (assertion *AsyncAssertion) matcherSaysStopTrying(matcher types.GomegaMatcher, value interface{}) bool { + if assertion.actualIsFunc || types.MatchMayChangeInTheFuture(matcher, value) { + return false + } + return true +} + +func (assertion *AsyncAssertion) pollMatcher(matcher types.GomegaMatcher, value interface{}) (matches bool, err error) { + defer func() { + if e := recover(); e != nil { + if _, isAsyncError := AsPollingSignalError(e); isAsyncError { + err = e.(error) + } else { + panic(e) + } + } + }() + + matches, err = matcher.Match(value) + + return } func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool { timer := time.Now() - timeout := time.After(assertion.timeoutInterval) + timeout := assertion.afterTimeout() + lock := sync.Mutex{} - var matches bool - var err error - mayChange := true - value, err := assertion.pollActual() - if err == nil { - mayChange = assertion.matcherMayChange(matcher, value) - matches, err = matcher.Match(value) - } + var matches, hasLastValidActual bool + var actual, lastValidActual interface{} + var actualErr, matcherErr error + var oracleMatcherSaysStop bool assertion.g.THelper() - fail := func(preamble string) { - errMsg := "" + pollActual, buildActualPollerErr := assertion.buildActualPoller() + if buildActualPollerErr != nil { + assertion.g.Fail(buildActualPollerErr.Error(), 2+assertion.offset) + return false + } + + actual, actualErr = pollActual() + if actualErr == nil { + lastValidActual = actual + hasLastValidActual = true + oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, actual) + matches, matcherErr = assertion.pollMatcher(matcher, actual) + } + + renderError := func(preamble string, err error) string { message := "" - if err != nil { - errMsg = "Error: " + err.Error() + if pollingSignalErr, ok := AsPollingSignalError(err); ok { + message = err.Error() + for _, attachment := range pollingSignalErr.Attachments { + message += fmt.Sprintf("\n%s:\n", attachment.Description) + message += format.Object(attachment.Object, 1) + } } else { - if desiredMatch { - message = matcher.FailureMessage(value) + message = preamble + "\n" + format.Object(err, 1) + } + return message + } + + messageGenerator := func() string { + // can be called out of band by Ginkgo if the user requests a progress report + lock.Lock() + defer lock.Unlock() + message := "" + + if actualErr == nil { + if matcherErr == nil { + if desiredMatch != matches { + if desiredMatch { + message += matcher.FailureMessage(actual) + } else { + message += matcher.NegatedFailureMessage(actual) + } + } else { + if assertion.asyncType == AsyncAssertionTypeConsistently { + message += "There is no failure as the matcher passed to Consistently has not yet failed" + } else { + message += "There is no failure as the matcher passed to Eventually succeeded on its most recent iteration" + } + } } else { - message = matcher.NegatedFailureMessage(value) + var fgErr formattedGomegaError + if errors.As(actualErr, &fgErr) { + message += fgErr.FormattedGomegaError() + "\n" + } else { + message += renderError(fmt.Sprintf("The matcher passed to %s returned the following error:", assertion.asyncType), matcherErr) + } + } + } else { + var fgErr formattedGomegaError + if errors.As(actualErr, &fgErr) { + message += fgErr.FormattedGomegaError() + "\n" + } else { + message += renderError(fmt.Sprintf("The function passed to %s returned the following error:", assertion.asyncType), actualErr) + } + if hasLastValidActual { + message += fmt.Sprintf("\nAt one point, however, the function did return successfully.\nYet, %s failed because", assertion.asyncType) + _, e := matcher.Match(lastValidActual) + if e != nil { + message += renderError(" the matcher returned the following error:", e) + } else { + message += " the matcher was not satisfied:\n" + if desiredMatch { + message += matcher.FailureMessage(lastValidActual) + } else { + message += matcher.NegatedFailureMessage(lastValidActual) + } + } } } - assertion.g.THelper() + description := assertion.buildDescription(optionalDescription...) - assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s%s%s", preamble, time.Since(timer).Seconds(), description, message, errMsg), 3+assertion.offset) + return fmt.Sprintf("%s%s", description, message) } - if assertion.asyncType == AsyncAssertionTypeEventually { - for { - if err == nil && matches == desiredMatch { - return true - } + fail := func(preamble string) { + assertion.g.THelper() + assertion.g.Fail(fmt.Sprintf("%s after %.3fs.\n%s", preamble, time.Since(timer).Seconds(), messageGenerator()), 3+assertion.offset) + } - if !mayChange { - fail("No future change is possible. Bailing out early") - return false - } + var contextDone <-chan struct{} + if assertion.ctx != nil { + contextDone = assertion.ctx.Done() + if v, ok := assertion.ctx.Value("GINKGO_SPEC_CONTEXT").(contextWithAttachProgressReporter); ok { + detach := v.AttachProgressReporter(messageGenerator) + defer detach() + } + } - select { - case <-time.After(assertion.pollingInterval): - value, err = assertion.pollActual() - if err == nil { - mayChange = assertion.matcherMayChange(matcher, value) - matches, err = matcher.Match(value) + // Used to count the number of times in a row a step passed + passedRepeatedlyCount := 0 + for { + var nextPoll <-chan time.Time = nil + var isTryAgainAfterError = false + + for _, err := range []error{actualErr, matcherErr} { + if pollingSignalErr, ok := AsPollingSignalError(err); ok { + if pollingSignalErr.IsStopTrying() { + fail("Told to stop trying") + return false + } + if pollingSignalErr.IsTryAgainAfter() { + nextPoll = time.After(pollingSignalErr.TryAgainDuration()) + isTryAgainAfterError = true } - case <-timeout: - fail("Timed out") - return false } } - } else if assertion.asyncType == AsyncAssertionTypeConsistently { - for { - if !(err == nil && matches == desiredMatch) { + + if actualErr == nil && matcherErr == nil && matches == desiredMatch { + if assertion.asyncType == AsyncAssertionTypeEventually { + passedRepeatedlyCount += 1 + if passedRepeatedlyCount == assertion.mustPassRepeatedly { + return true + } + } + } else if !isTryAgainAfterError { + if assertion.asyncType == AsyncAssertionTypeConsistently { fail("Failed") return false } + // Reset the consecutive pass count + passedRepeatedlyCount = 0 + } - if !mayChange { + if oracleMatcherSaysStop { + if assertion.asyncType == AsyncAssertionTypeEventually { + fail("No future change is possible. Bailing out early") + return false + } else { return true } + } + + if nextPoll == nil { + nextPoll = assertion.afterPolling() + } - select { - case <-time.After(assertion.pollingInterval): - value, err = assertion.pollActual() - if err == nil { - mayChange = assertion.matcherMayChange(matcher, value) - matches, err = matcher.Match(value) + select { + case <-nextPoll: + a, e := pollActual() + lock.Lock() + actual, actualErr = a, e + lock.Unlock() + if actualErr == nil { + lock.Lock() + lastValidActual = actual + hasLastValidActual = true + lock.Unlock() + oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, actual) + m, e := assertion.pollMatcher(matcher, actual) + lock.Lock() + matches, matcherErr = m, e + lock.Unlock() + } + case <-contextDone: + fail("Context was cancelled") + return false + case <-timeout: + if assertion.asyncType == AsyncAssertionTypeEventually { + fail("Timed out") + return false + } else { + if isTryAgainAfterError { + fail("Timed out while waiting on TryAgainAfter") + return false } - case <-timeout: return true } } } - - return false } diff --git a/vendor/github.com/onsi/gomega/internal/duration_bundle.go b/vendor/github.com/onsi/gomega/internal/duration_bundle.go index af8d989fa98..6e0d90d3a1a 100644 --- a/vendor/github.com/onsi/gomega/internal/duration_bundle.go +++ b/vendor/github.com/onsi/gomega/internal/duration_bundle.go @@ -44,28 +44,28 @@ func durationFromEnv(key string, defaultDuration time.Duration) time.Duration { return duration } -func toDuration(input interface{}) time.Duration { +func toDuration(input interface{}) (time.Duration, error) { duration, ok := input.(time.Duration) if ok { - return duration + return duration, nil } value := reflect.ValueOf(input) kind := reflect.TypeOf(input).Kind() if reflect.Int <= kind && kind <= reflect.Int64 { - return time.Duration(value.Int()) * time.Second + return time.Duration(value.Int()) * time.Second, nil } else if reflect.Uint <= kind && kind <= reflect.Uint64 { - return time.Duration(value.Uint()) * time.Second + return time.Duration(value.Uint()) * time.Second, nil } else if reflect.Float32 <= kind && kind <= reflect.Float64 { - return time.Duration(value.Float() * float64(time.Second)) + return time.Duration(value.Float() * float64(time.Second)), nil } else if reflect.String == kind { duration, err := time.ParseDuration(value.String()) if err != nil { - panic(fmt.Sprintf("%#v is not a valid parsable duration string.", input)) + return 0, fmt.Errorf("%#v is not a valid parsable duration string: %w", input, err) } - return duration + return duration, nil } - panic(fmt.Sprintf("%v is not a valid interval. Must be time.Duration, parsable duration string or a number.", input)) + return 0, fmt.Errorf("%#v is not a valid interval. Must be a time.Duration, a parsable duration string, or a number.", input) } diff --git a/vendor/github.com/onsi/gomega/internal/gomega.go b/vendor/github.com/onsi/gomega/internal/gomega.go index d26a67485f1..de1f4f336e8 100644 --- a/vendor/github.com/onsi/gomega/internal/gomega.go +++ b/vendor/github.com/onsi/gomega/internal/gomega.go @@ -1,6 +1,7 @@ package internal import ( + "context" "time" "github.com/onsi/gomega/types" @@ -51,38 +52,64 @@ func (g *Gomega) ExpectWithOffset(offset int, actual interface{}, extra ...inter return NewAssertion(actual, g, offset, extra...) } -func (g *Gomega) Eventually(actual interface{}, intervals ...interface{}) types.AsyncAssertion { - return g.EventuallyWithOffset(0, actual, intervals...) +func (g *Gomega) Eventually(actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { + return g.makeAsyncAssertion(AsyncAssertionTypeEventually, 0, actualOrCtx, args...) } -func (g *Gomega) EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion { - timeoutInterval := g.DurationBundle.EventuallyTimeout - pollingInterval := g.DurationBundle.EventuallyPollingInterval - if len(intervals) > 0 { - timeoutInterval = toDuration(intervals[0]) - } - if len(intervals) > 1 { - pollingInterval = toDuration(intervals[1]) - } +func (g *Gomega) EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { + return g.makeAsyncAssertion(AsyncAssertionTypeEventually, offset, actualOrCtx, args...) +} - return NewAsyncAssertion(AsyncAssertionTypeEventually, actual, g, timeoutInterval, pollingInterval, offset) +func (g *Gomega) Consistently(actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { + return g.makeAsyncAssertion(AsyncAssertionTypeConsistently, 0, actualOrCtx, args...) } -func (g *Gomega) Consistently(actual interface{}, intervals ...interface{}) types.AsyncAssertion { - return g.ConsistentlyWithOffset(0, actual, intervals...) +func (g *Gomega) ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { + return g.makeAsyncAssertion(AsyncAssertionTypeConsistently, offset, actualOrCtx, args...) } -func (g *Gomega) ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) types.AsyncAssertion { - timeoutInterval := g.DurationBundle.ConsistentlyDuration - pollingInterval := g.DurationBundle.ConsistentlyPollingInterval +func (g *Gomega) makeAsyncAssertion(asyncAssertionType AsyncAssertionType, offset int, actualOrCtx interface{}, args ...interface{}) types.AsyncAssertion { + baseOffset := 3 + timeoutInterval := -time.Duration(1) + pollingInterval := -time.Duration(1) + intervals := []interface{}{} + var ctx context.Context + + actual := actualOrCtx + startingIndex := 0 + if _, isCtx := actualOrCtx.(context.Context); isCtx && len(args) > 0 { + // the first argument is a context, we should accept it as the context _only if_ it is **not** the only argumnent **and** the second argument is not a parseable duration + // this is due to an unfortunate ambiguity in early version of Gomega in which multi-type durations are allowed after the actual + if _, err := toDuration(args[0]); err != nil { + ctx = actualOrCtx.(context.Context) + actual = args[0] + startingIndex = 1 + } + } + + for _, arg := range args[startingIndex:] { + switch v := arg.(type) { + case context.Context: + ctx = v + default: + intervals = append(intervals, arg) + } + } + var err error if len(intervals) > 0 { - timeoutInterval = toDuration(intervals[0]) + timeoutInterval, err = toDuration(intervals[0]) + if err != nil { + g.Fail(err.Error(), offset+baseOffset) + } } if len(intervals) > 1 { - pollingInterval = toDuration(intervals[1]) + pollingInterval, err = toDuration(intervals[1]) + if err != nil { + g.Fail(err.Error(), offset+baseOffset) + } } - return NewAsyncAssertion(AsyncAssertionTypeConsistently, actual, g, timeoutInterval, pollingInterval, offset) + return NewAsyncAssertion(asyncAssertionType, actual, g, timeoutInterval, pollingInterval, 1, ctx, offset) } func (g *Gomega) SetDefaultEventuallyTimeout(t time.Duration) { diff --git a/vendor/github.com/onsi/gomega/internal/polling_signal_error.go b/vendor/github.com/onsi/gomega/internal/polling_signal_error.go new file mode 100644 index 00000000000..83b04b1a4c9 --- /dev/null +++ b/vendor/github.com/onsi/gomega/internal/polling_signal_error.go @@ -0,0 +1,106 @@ +package internal + +import ( + "errors" + "fmt" + "time" +) + +type PollingSignalErrorType int + +const ( + PollingSignalErrorTypeStopTrying PollingSignalErrorType = iota + PollingSignalErrorTypeTryAgainAfter +) + +type PollingSignalError interface { + error + Wrap(err error) PollingSignalError + Attach(description string, obj any) PollingSignalError + Now() +} + +var StopTrying = func(message string) PollingSignalError { + return &PollingSignalErrorImpl{ + message: message, + pollingSignalErrorType: PollingSignalErrorTypeStopTrying, + } +} + +var TryAgainAfter = func(duration time.Duration) PollingSignalError { + return &PollingSignalErrorImpl{ + message: fmt.Sprintf("told to try again after %s", duration), + duration: duration, + pollingSignalErrorType: PollingSignalErrorTypeTryAgainAfter, + } +} + +type PollingSignalErrorAttachment struct { + Description string + Object any +} + +type PollingSignalErrorImpl struct { + message string + wrappedErr error + pollingSignalErrorType PollingSignalErrorType + duration time.Duration + Attachments []PollingSignalErrorAttachment +} + +func (s *PollingSignalErrorImpl) Wrap(err error) PollingSignalError { + s.wrappedErr = err + return s +} + +func (s *PollingSignalErrorImpl) Attach(description string, obj any) PollingSignalError { + s.Attachments = append(s.Attachments, PollingSignalErrorAttachment{description, obj}) + return s +} + +func (s *PollingSignalErrorImpl) Error() string { + if s.wrappedErr == nil { + return s.message + } else { + return s.message + ": " + s.wrappedErr.Error() + } +} + +func (s *PollingSignalErrorImpl) Unwrap() error { + if s == nil { + return nil + } + return s.wrappedErr +} + +func (s *PollingSignalErrorImpl) Now() { + panic(s) +} + +func (s *PollingSignalErrorImpl) IsStopTrying() bool { + return s.pollingSignalErrorType == PollingSignalErrorTypeStopTrying +} + +func (s *PollingSignalErrorImpl) IsTryAgainAfter() bool { + return s.pollingSignalErrorType == PollingSignalErrorTypeTryAgainAfter +} + +func (s *PollingSignalErrorImpl) TryAgainDuration() time.Duration { + return s.duration +} + +func AsPollingSignalError(actual interface{}) (*PollingSignalErrorImpl, bool) { + if actual == nil { + return nil, false + } + if actualErr, ok := actual.(error); ok { + var target *PollingSignalErrorImpl + if errors.As(actualErr, &target) { + return target, true + } else { + return nil, false + } + } + + return nil, false +} diff --git a/vendor/github.com/onsi/gomega/internal/vetoptdesc.go b/vendor/github.com/onsi/gomega/internal/vetoptdesc.go new file mode 100644 index 00000000000..f2958764171 --- /dev/null +++ b/vendor/github.com/onsi/gomega/internal/vetoptdesc.go @@ -0,0 +1,22 @@ +package internal + +import ( + "fmt" + + "github.com/onsi/gomega/types" +) + +// vetOptionalDescription vets the optional description args: if it finds any +// Gomega matcher at the beginning it panics. This allows for rendering Gomega +// matchers as part of an optional Description, as long as they're not in the +// first slot. +func vetOptionalDescription(assertion string, optionalDescription ...interface{}) { + if len(optionalDescription) == 0 { + return + } + if _, isGomegaMatcher := optionalDescription[0].(types.GomegaMatcher); isGomegaMatcher { + panic(fmt.Sprintf("%s has a GomegaMatcher as the first element of optionalDescription.\n\t"+ + "Do you mean to use And/Or/SatisfyAll/SatisfyAny to combine multiple matchers?", + assertion)) + } +} diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index b58dd67cb8c..b832f3dbaf6 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -3,139 +3,161 @@ package gomega import ( "time" + "github.com/google/go-cmp/cmp" "github.com/onsi/gomega/matchers" "github.com/onsi/gomega/types" ) -//Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about -//types when performing comparisons. -//It is an error for both actual and expected to be nil. Use BeNil() instead. +// Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about +// types when performing comparisons. +// It is an error for both actual and expected to be nil. Use BeNil() instead. func Equal(expected interface{}) types.GomegaMatcher { return &matchers.EqualMatcher{ Expected: expected, } } -//BeEquivalentTo is more lax than Equal, allowing equality between different types. -//This is done by converting actual to have the type of expected before -//attempting equality with reflect.DeepEqual. -//It is an error for actual and expected to be nil. Use BeNil() instead. +// BeEquivalentTo is more lax than Equal, allowing equality between different types. +// This is done by converting actual to have the type of expected before +// attempting equality with reflect.DeepEqual. +// It is an error for actual and expected to be nil. Use BeNil() instead. func BeEquivalentTo(expected interface{}) types.GomegaMatcher { return &matchers.BeEquivalentToMatcher{ Expected: expected, } } -//BeIdenticalTo uses the == operator to compare actual with expected. -//BeIdenticalTo is strict about types when performing comparisons. -//It is an error for both actual and expected to be nil. Use BeNil() instead. +// BeComparableTo uses gocmp.Equal from github.com/google/go-cmp (instead of reflect.DeepEqual) to perform a deep comparison. +// You can pass cmp.Option as options. +// It is an error for actual and expected to be nil. Use BeNil() instead. +func BeComparableTo(expected interface{}, opts ...cmp.Option) types.GomegaMatcher { + return &matchers.BeComparableToMatcher{ + Expected: expected, + Options: opts, + } +} + +// BeIdenticalTo uses the == operator to compare actual with expected. +// BeIdenticalTo is strict about types when performing comparisons. +// It is an error for both actual and expected to be nil. Use BeNil() instead. func BeIdenticalTo(expected interface{}) types.GomegaMatcher { return &matchers.BeIdenticalToMatcher{ Expected: expected, } } -//BeNil succeeds if actual is nil +// BeNil succeeds if actual is nil func BeNil() types.GomegaMatcher { return &matchers.BeNilMatcher{} } -//BeTrue succeeds if actual is true +// BeTrue succeeds if actual is true func BeTrue() types.GomegaMatcher { return &matchers.BeTrueMatcher{} } -//BeFalse succeeds if actual is false +// BeFalse succeeds if actual is false func BeFalse() types.GomegaMatcher { return &matchers.BeFalseMatcher{} } -//HaveOccurred succeeds if actual is a non-nil error -//The typical Go error checking pattern looks like: -// err := SomethingThatMightFail() -// Expect(err).ShouldNot(HaveOccurred()) +// HaveOccurred succeeds if actual is a non-nil error +// The typical Go error checking pattern looks like: +// +// err := SomethingThatMightFail() +// Expect(err).ShouldNot(HaveOccurred()) func HaveOccurred() types.GomegaMatcher { return &matchers.HaveOccurredMatcher{} } -//Succeed passes if actual is a nil error -//Succeed is intended to be used with functions that return a single error value. Instead of -// err := SomethingThatMightFail() -// Expect(err).ShouldNot(HaveOccurred()) +// Succeed passes if actual is a nil error +// Succeed is intended to be used with functions that return a single error value. Instead of +// +// err := SomethingThatMightFail() +// Expect(err).ShouldNot(HaveOccurred()) // -//You can write: -// Expect(SomethingThatMightFail()).Should(Succeed()) +// You can write: // -//It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect -//functions automatically trigger failure if any return values after the first return value are non-zero/non-nil. -//This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass. +// Expect(SomethingThatMightFail()).Should(Succeed()) +// +// It is a mistake to use Succeed with a function that has multiple return values. Gomega's Ω and Expect +// functions automatically trigger failure if any return values after the first return value are non-zero/non-nil. +// This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass. func Succeed() types.GomegaMatcher { return &matchers.SucceedMatcher{} } -//MatchError succeeds if actual is a non-nil error that matches the passed in string/error. +// MatchError succeeds if actual is a non-nil error that matches the passed in +// string, error, or matcher. +// +// These are valid use-cases: // -//These are valid use-cases: // Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" // Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) +// Expect(err).Should(MatchError(ContainsSubstring("sprocket not found"))) // asserts that edrr.Error() contains substring "sprocket not found" // -//It is an error for err to be nil or an object that does not implement the Error interface +// It is an error for err to be nil or an object that does not implement the +// Error interface func MatchError(expected interface{}) types.GomegaMatcher { return &matchers.MatchErrorMatcher{ Expected: expected, } } -//BeClosed succeeds if actual is a closed channel. -//It is an error to pass a non-channel to BeClosed, it is also an error to pass nil +// BeClosed succeeds if actual is a closed channel. +// It is an error to pass a non-channel to BeClosed, it is also an error to pass nil // -//In order to check whether or not the channel is closed, Gomega must try to read from the channel -//(even in the `ShouldNot(BeClosed())` case). You should keep this in mind if you wish to make subsequent assertions about -//values coming down the channel. +// In order to check whether or not the channel is closed, Gomega must try to read from the channel +// (even in the `ShouldNot(BeClosed())` case). You should keep this in mind if you wish to make subsequent assertions about +// values coming down the channel. // -//Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before -//asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read). +// Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before +// asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read). // -//Finally, as a corollary: it is an error to check whether or not a send-only channel is closed. +// Finally, as a corollary: it is an error to check whether or not a send-only channel is closed. func BeClosed() types.GomegaMatcher { return &matchers.BeClosedMatcher{} } -//Receive succeeds if there is a value to be received on actual. -//Actual must be a channel (and cannot be a send-only channel) -- anything else is an error. +// Receive succeeds if there is a value to be received on actual. +// Actual must be a channel (and cannot be a send-only channel) -- anything else is an error. +// +// Receive returns immediately and never blocks: +// +// - If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. +// +// - If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. +// +// - If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail. // -//Receive returns immediately and never blocks: +// If you have a go-routine running in the background that will write to channel `c` you can: // -//- If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. +// Eventually(c).Should(Receive()) // -//- If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass. +// This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`) // -//- If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail. +// A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`: // -//If you have a go-routine running in the background that will write to channel `c` you can: -// Eventually(c).Should(Receive()) +// Consistently(c).ShouldNot(Receive()) // -//This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`) +// You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example: // -//A similar use-case is to assert that no go-routine writes to a channel (for a period of time). You can do this with `Consistently`: -// Consistently(c).ShouldNot(Receive()) +// Expect(c).Should(Receive(Equal("foo"))) // -//You can pass `Receive` a matcher. If you do so, it will match the received object against the matcher. For example: -// Expect(c).Should(Receive(Equal("foo"))) +// When given a matcher, `Receive` will always fail if there is nothing to be received on the channel. // -//When given a matcher, `Receive` will always fail if there is nothing to be received on the channel. +// Passing Receive a matcher is especially useful when paired with Eventually: // -//Passing Receive a matcher is especially useful when paired with Eventually: +// Eventually(c).Should(Receive(ContainSubstring("bar"))) // -// Eventually(c).Should(Receive(ContainSubstring("bar"))) +// will repeatedly attempt to pull values out of `c` until a value matching "bar" is received. // -//will repeatedly attempt to pull values out of `c` until a value matching "bar" is received. +// Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type: // -//Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type: -// var myThing thing -// Eventually(thingChan).Should(Receive(&myThing)) -// Expect(myThing.Sprocket).Should(Equal("foo")) -// Expect(myThing.IsValid()).Should(BeTrue()) +// var myThing thing +// Eventually(thingChan).Should(Receive(&myThing)) +// Expect(myThing.Sprocket).Should(Equal("foo")) +// Expect(myThing.IsValid()).Should(BeTrue()) func Receive(args ...interface{}) types.GomegaMatcher { var arg interface{} if len(args) > 0 { @@ -147,27 +169,27 @@ func Receive(args ...interface{}) types.GomegaMatcher { } } -//BeSent succeeds if a value can be sent to actual. -//Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error. -//In addition, actual must not be closed. +// BeSent succeeds if a value can be sent to actual. +// Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error. +// In addition, actual must not be closed. // -//BeSent never blocks: +// BeSent never blocks: // -//- If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately -//- If the channel `c` is eventually ready to receive then Eventually(c).Should(BeSent("foo")) will succeed.. presuming the channel becomes ready to receive before Eventually's timeout -//- If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately +// - If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately +// - If the channel `c` is eventually ready to receive then Eventually(c).Should(BeSent("foo")) will succeed.. presuming the channel becomes ready to receive before Eventually's timeout +// - If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately // -//Of course, the value is actually sent to the channel. The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with). -//Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends. +// Of course, the value is actually sent to the channel. The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with). +// Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends. func BeSent(arg interface{}) types.GomegaMatcher { return &matchers.BeSentMatcher{ Arg: arg, } } -//MatchRegexp succeeds if actual is a string or stringer that matches the -//passed-in regexp. Optional arguments can be provided to construct a regexp -//via fmt.Sprintf(). +// MatchRegexp succeeds if actual is a string or stringer that matches the +// passed-in regexp. Optional arguments can be provided to construct a regexp +// via fmt.Sprintf(). func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher { return &matchers.MatchRegexpMatcher{ Regexp: regexp, @@ -175,9 +197,9 @@ func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher { } } -//ContainSubstring succeeds if actual is a string or stringer that contains the -//passed-in substring. Optional arguments can be provided to construct the substring -//via fmt.Sprintf(). +// ContainSubstring succeeds if actual is a string or stringer that contains the +// passed-in substring. Optional arguments can be provided to construct the substring +// via fmt.Sprintf(). func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher { return &matchers.ContainSubstringMatcher{ Substr: substr, @@ -185,9 +207,9 @@ func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher { } } -//HavePrefix succeeds if actual is a string or stringer that contains the -//passed-in string as a prefix. Optional arguments can be provided to construct -//via fmt.Sprintf(). +// HavePrefix succeeds if actual is a string or stringer that contains the +// passed-in string as a prefix. Optional arguments can be provided to construct +// via fmt.Sprintf(). func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher { return &matchers.HavePrefixMatcher{ Prefix: prefix, @@ -195,9 +217,9 @@ func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher { } } -//HaveSuffix succeeds if actual is a string or stringer that contains the -//passed-in string as a suffix. Optional arguments can be provided to construct -//via fmt.Sprintf(). +// HaveSuffix succeeds if actual is a string or stringer that contains the +// passed-in string as a suffix. Optional arguments can be provided to construct +// via fmt.Sprintf(). func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher { return &matchers.HaveSuffixMatcher{ Suffix: suffix, @@ -205,73 +227,74 @@ func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher { } } -//MatchJSON succeeds if actual is a string or stringer of JSON that matches -//the expected JSON. The JSONs are decoded and the resulting objects are compared via -//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. +// MatchJSON succeeds if actual is a string or stringer of JSON that matches +// the expected JSON. The JSONs are decoded and the resulting objects are compared via +// reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. func MatchJSON(json interface{}) types.GomegaMatcher { return &matchers.MatchJSONMatcher{ JSONToMatch: json, } } -//MatchXML succeeds if actual is a string or stringer of XML that matches -//the expected XML. The XMLs are decoded and the resulting objects are compared via -//reflect.DeepEqual so things like whitespaces shouldn't matter. +// MatchXML succeeds if actual is a string or stringer of XML that matches +// the expected XML. The XMLs are decoded and the resulting objects are compared via +// reflect.DeepEqual so things like whitespaces shouldn't matter. func MatchXML(xml interface{}) types.GomegaMatcher { return &matchers.MatchXMLMatcher{ XMLToMatch: xml, } } -//MatchYAML succeeds if actual is a string or stringer of YAML that matches -//the expected YAML. The YAML's are decoded and the resulting objects are compared via -//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. +// MatchYAML succeeds if actual is a string or stringer of YAML that matches +// the expected YAML. The YAML's are decoded and the resulting objects are compared via +// reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter. func MatchYAML(yaml interface{}) types.GomegaMatcher { return &matchers.MatchYAMLMatcher{ YAMLToMatch: yaml, } } -//BeEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice. +// BeEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice. func BeEmpty() types.GomegaMatcher { return &matchers.BeEmptyMatcher{} } -//HaveLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice. +// HaveLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice. func HaveLen(count int) types.GomegaMatcher { return &matchers.HaveLenMatcher{ Count: count, } } -//HaveCap succeeds if actual has the passed-in capacity. Actual must be of type array, chan, or slice. +// HaveCap succeeds if actual has the passed-in capacity. Actual must be of type array, chan, or slice. func HaveCap(count int) types.GomegaMatcher { return &matchers.HaveCapMatcher{ Count: count, } } -//BeZero succeeds if actual is the zero value for its type or if actual is nil. +// BeZero succeeds if actual is the zero value for its type or if actual is nil. func BeZero() types.GomegaMatcher { return &matchers.BeZeroMatcher{} } -//ContainElement succeeds if actual contains the passed in element. By default -//ContainElement() uses Equal() to perform the match, however a matcher can be -//passed in instead: -// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) +// ContainElement succeeds if actual contains the passed in element. By default +// ContainElement() uses Equal() to perform the match, however a matcher can be +// passed in instead: // -//Actual must be an array, slice or map. For maps, ContainElement searches -//through the map's values. +// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar"))) // -//If you want to have a copy of the matching element(s) found you can pass a -//pointer to a variable of the appropriate type. If the variable isn't a slice -//or map, then exactly one match will be expected and returned. If the variable -//is a slice or map, then at least one match is expected and all matches will be -//stored in the variable. +// Actual must be an array, slice or map. For maps, ContainElement searches +// through the map's values. // -// var findings []string -// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubString("Bar", &findings))) +// If you want to have a copy of the matching element(s) found you can pass a +// pointer to a variable of the appropriate type. If the variable isn't a slice +// or map, then exactly one match will be expected and returned. If the variable +// is a slice or map, then at least one match is expected and all matches will be +// stored in the variable. +// +// var findings []string +// Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubString("Bar", &findings))) func ContainElement(element interface{}, result ...interface{}) types.GomegaMatcher { return &matchers.ContainElementMatcher{ Element: element, @@ -279,86 +302,116 @@ func ContainElement(element interface{}, result ...interface{}) types.GomegaMatc } } -//BeElementOf succeeds if actual is contained in the passed in elements. -//BeElementOf() always uses Equal() to perform the match. -//When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves -//as the reverse of ContainElement() that operates with Equal() to perform the match. -// Expect(2).Should(BeElementOf([]int{1, 2})) -// Expect(2).Should(BeElementOf([2]int{1, 2})) -//Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...): -// Expect(2).Should(BeElementOf(1, 2)) +// BeElementOf succeeds if actual is contained in the passed in elements. +// BeElementOf() always uses Equal() to perform the match. +// When the passed in elements are comprised of a single element that is either an Array or Slice, BeElementOf() behaves +// as the reverse of ContainElement() that operates with Equal() to perform the match. +// +// Expect(2).Should(BeElementOf([]int{1, 2})) +// Expect(2).Should(BeElementOf([2]int{1, 2})) +// +// Otherwise, BeElementOf() provides a syntactic sugar for Or(Equal(_), Equal(_), ...): // -//Actual must be typed. +// Expect(2).Should(BeElementOf(1, 2)) +// +// Actual must be typed. func BeElementOf(elements ...interface{}) types.GomegaMatcher { return &matchers.BeElementOfMatcher{ Elements: elements, } } -//ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter. -//By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: +// BeKeyOf succeeds if actual is contained in the keys of the passed in map. +// BeKeyOf() always uses Equal() to perform the match between actual and the map keys. +// +// Expect("foo").Should(BeKeyOf(map[string]bool{"foo": true, "bar": false})) +func BeKeyOf(element interface{}) types.GomegaMatcher { + return &matchers.BeKeyOfMatcher{ + Map: element, + } +} + +// ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter. +// By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: // -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo")) -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo")) -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo"))) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo"))) // -//Actual must be an array, slice or map. For maps, ConsistOf matches against the map's values. +// Actual must be an array, slice or map. For maps, ConsistOf matches against the map's values. // -//You typically pass variadic arguments to ConsistOf (as in the examples above). However, if you need to pass in a slice you can provided that it -//is the only element passed in to ConsistOf: +// You typically pass variadic arguments to ConsistOf (as in the examples above). However, if you need to pass in a slice you can provided that it +// is the only element passed in to ConsistOf: // -// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"})) +// Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"})) // -//Note that Go's type system does not allow you to write this as ConsistOf([]string{"FooBar", "Foo"}...) as []string and []interface{} are different types - hence the need for this special rule. +// Note that Go's type system does not allow you to write this as ConsistOf([]string{"FooBar", "Foo"}...) as []string and []interface{} are different types - hence the need for this special rule. func ConsistOf(elements ...interface{}) types.GomegaMatcher { return &matchers.ConsistOfMatcher{ Elements: elements, } } -//ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter. -//By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: +// HaveExactElemets succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter. +// By default HaveExactElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: // -// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar")) -// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo")) +// Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", "FooBar")) +// Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", ContainSubstring("Bar"))) +// Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements(ContainSubstring("Foo"), ContainSubstring("Foo"))) // -//Actual must be an array, slice or map. -//For maps, ContainElements searches through the map's values. +// Actual must be an array or slice. +func HaveExactElements(elements ...interface{}) types.GomegaMatcher { + return &matchers.HaveExactElementsMatcher{ + Elements: elements, + } +} + +// ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter. +// By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: +// +// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar")) +// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo")) +// +// Actual must be an array, slice or map. +// For maps, ContainElements searches through the map's values. func ContainElements(elements ...interface{}) types.GomegaMatcher { return &matchers.ContainElementsMatcher{ Elements: elements, } } -//HaveEach succeeds if actual solely contains elements that match the passed in element. -//Please note that if actual is empty, HaveEach always will succeed. -//By default HaveEach() uses Equal() to perform the match, however a -//matcher can be passed in instead: -// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo"))) +// HaveEach succeeds if actual solely contains elements that match the passed in element. +// Please note that if actual is empty, HaveEach always will succeed. +// By default HaveEach() uses Equal() to perform the match, however a +// matcher can be passed in instead: +// +// Expect([]string{"Foo", "FooBar"}).Should(HaveEach(ContainSubstring("Foo"))) // -//Actual must be an array, slice or map. -//For maps, HaveEach searches through the map's values. +// Actual must be an array, slice or map. +// For maps, HaveEach searches through the map's values. func HaveEach(element interface{}) types.GomegaMatcher { return &matchers.HaveEachMatcher{ Element: element, } } -//HaveKey succeeds if actual is a map with the passed in key. -//By default HaveKey uses Equal() to perform the match, however a -//matcher can be passed in instead: -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`))) +// HaveKey succeeds if actual is a map with the passed in key. +// By default HaveKey uses Equal() to perform the match, however a +// matcher can be passed in instead: +// +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`))) func HaveKey(key interface{}) types.GomegaMatcher { return &matchers.HaveKeyMatcher{ Key: key, } } -//HaveKeyWithValue succeeds if actual is a map with the passed in key and value. -//By default HaveKeyWithValue uses Equal() to perform the match, however a -//matcher can be passed in instead: -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar")) -// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar")) +// HaveKeyWithValue succeeds if actual is a map with the passed in key and value. +// By default HaveKeyWithValue uses Equal() to perform the match, however a +// matcher can be passed in instead: +// +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar")) +// Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar")) func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { return &matchers.HaveKeyWithValueMatcher{ Key: key, @@ -366,27 +419,27 @@ func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher { } } -//HaveField succeeds if actual is a struct and the value at the passed in field -//matches the passed in matcher. By default HaveField used Equal() to perform the match, -//however a matcher can be passed in in stead. -// -//The field must be a string that resolves to the name of a field in the struct. Structs can be traversed -//using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked. -//Such methods must take no arguments and return a single value: -// -// type Book struct { -// Title string -// Author Person -// } -// type Person struct { -// FirstName string -// LastName string -// DOB time.Time -// } -// Expect(book).To(HaveField("Title", "Les Miserables")) -// Expect(book).To(HaveField("Title", ContainSubstring("Les")) -// Expect(book).To(HaveField("Author.FirstName", Equal("Victor")) -// Expect(book).To(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)) +// HaveField succeeds if actual is a struct and the value at the passed in field +// matches the passed in matcher. By default HaveField used Equal() to perform the match, +// however a matcher can be passed in in stead. +// +// The field must be a string that resolves to the name of a field in the struct. Structs can be traversed +// using the '.' delimiter. If the field ends with '()' a method named field is assumed to exist on the struct and is invoked. +// Such methods must take no arguments and return a single value: +// +// type Book struct { +// Title string +// Author Person +// } +// type Person struct { +// FirstName string +// LastName string +// DOB time.Time +// } +// Expect(book).To(HaveField("Title", "Les Miserables")) +// Expect(book).To(HaveField("Title", ContainSubstring("Les")) +// Expect(book).To(HaveField("Author.FirstName", Equal("Victor")) +// Expect(book).To(HaveField("Author.DOB.Year()", BeNumerically("<", 1900)) func HaveField(field string, expected interface{}) types.GomegaMatcher { return &matchers.HaveFieldMatcher{ Field: field, @@ -394,6 +447,19 @@ func HaveField(field string, expected interface{}) types.GomegaMatcher { } } +// HaveExistingField succeeds if actual is a struct and the specified field +// exists. +// +// HaveExistingField can be combined with HaveField in order to cover use cases +// with optional fields. HaveField alone would trigger an error in such situations. +// +// Expect(MrHarmless).NotTo(And(HaveExistingField("Title"), HaveField("Title", "Supervillain"))) +func HaveExistingField(field string) types.GomegaMatcher { + return &matchers.HaveExistingFieldMatcher{ + Field: field, + } +} + // HaveValue applies the given matcher to the value of actual, optionally and // repeatedly dereferencing pointers or taking the concrete value of interfaces. // Thus, the matcher will always be applied to non-pointer and non-interface @@ -405,26 +471,27 @@ func HaveField(field string, expected interface{}) types.GomegaMatcher { // be a pointer (as gstruct.PointTo does) but instead also accepts non-pointer // and even interface values. // -// actual := 42 -// Expect(actual).To(HaveValue(42)) -// Expect(&actual).To(HaveValue(42)) +// actual := 42 +// Expect(actual).To(HaveValue(42)) +// Expect(&actual).To(HaveValue(42)) func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher { return &matchers.HaveValueMatcher{ Matcher: matcher, } } -//BeNumerically performs numerical assertions in a type-agnostic way. -//Actual and expected should be numbers, though the specific type of -//number is irrelevant (float32, float64, uint8, etc...). +// BeNumerically performs numerical assertions in a type-agnostic way. +// Actual and expected should be numbers, though the specific type of +// number is irrelevant (float32, float64, uint8, etc...). +// +// There are six, self-explanatory, supported comparators: // -//There are six, self-explanatory, supported comparators: -// Expect(1.0).Should(BeNumerically("==", 1)) -// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01)) -// Expect(1.0).Should(BeNumerically(">", 0.9)) -// Expect(1.0).Should(BeNumerically(">=", 1.0)) -// Expect(1.0).Should(BeNumerically("<", 3)) -// Expect(1.0).Should(BeNumerically("<=", 1.0)) +// Expect(1.0).Should(BeNumerically("==", 1)) +// Expect(1.0).Should(BeNumerically("~", 0.999, 0.01)) +// Expect(1.0).Should(BeNumerically(">", 0.9)) +// Expect(1.0).Should(BeNumerically(">=", 1.0)) +// Expect(1.0).Should(BeNumerically("<", 3)) +// Expect(1.0).Should(BeNumerically("<=", 1.0)) func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatcher { return &matchers.BeNumericallyMatcher{ Comparator: comparator, @@ -432,10 +499,11 @@ func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatc } } -//BeTemporally compares time.Time's like BeNumerically -//Actual and expected must be time.Time. The comparators are the same as for BeNumerically -// Expect(time.Now()).Should(BeTemporally(">", time.Time{})) -// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second)) +// BeTemporally compares time.Time's like BeNumerically +// Actual and expected must be time.Time. The comparators are the same as for BeNumerically +// +// Expect(time.Now()).Should(BeTemporally(">", time.Time{})) +// Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second)) func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher { return &matchers.BeTemporallyMatcher{ Comparator: comparator, @@ -444,58 +512,61 @@ func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Dura } } -//BeAssignableToTypeOf succeeds if actual is assignable to the type of expected. -//It will return an error when one of the values is nil. -// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values -// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type -// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type -// Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{})) +// BeAssignableToTypeOf succeeds if actual is assignable to the type of expected. +// It will return an error when one of the values is nil. +// +// Expect(0).Should(BeAssignableToTypeOf(0)) // Same values +// Expect(5).Should(BeAssignableToTypeOf(-1)) // different values same type +// Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type +// Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{})) func BeAssignableToTypeOf(expected interface{}) types.GomegaMatcher { return &matchers.AssignableToTypeOfMatcher{ Expected: expected, } } -//Panic succeeds if actual is a function that, when invoked, panics. -//Actual must be a function that takes no arguments and returns no results. +// Panic succeeds if actual is a function that, when invoked, panics. +// Actual must be a function that takes no arguments and returns no results. func Panic() types.GomegaMatcher { return &matchers.PanicMatcher{} } -//PanicWith succeeds if actual is a function that, when invoked, panics with a specific value. -//Actual must be a function that takes no arguments and returns no results. +// PanicWith succeeds if actual is a function that, when invoked, panics with a specific value. +// Actual must be a function that takes no arguments and returns no results. +// +// By default PanicWith uses Equal() to perform the match, however a +// matcher can be passed in instead: // -//By default PanicWith uses Equal() to perform the match, however a -//matcher can be passed in instead: -// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`))) +// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`))) func PanicWith(expected interface{}) types.GomegaMatcher { return &matchers.PanicMatcher{Expected: expected} } -//BeAnExistingFile succeeds if a file exists. -//Actual must be a string representing the abs path to the file being checked. +// BeAnExistingFile succeeds if a file exists. +// Actual must be a string representing the abs path to the file being checked. func BeAnExistingFile() types.GomegaMatcher { return &matchers.BeAnExistingFileMatcher{} } -//BeARegularFile succeeds if a file exists and is a regular file. -//Actual must be a string representing the abs path to the file being checked. +// BeARegularFile succeeds if a file exists and is a regular file. +// Actual must be a string representing the abs path to the file being checked. func BeARegularFile() types.GomegaMatcher { return &matchers.BeARegularFileMatcher{} } -//BeADirectory succeeds if a file exists and is a directory. -//Actual must be a string representing the abs path to the file being checked. +// BeADirectory succeeds if a file exists and is a directory. +// Actual must be a string representing the abs path to the file being checked. func BeADirectory() types.GomegaMatcher { return &matchers.BeADirectoryMatcher{} } -//HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches. -//Actual must be either a *http.Response or *httptest.ResponseRecorder. -//Expected must be either an int or a string. -// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200 -// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found" -// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204 +// HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches. +// Actual must be either a *http.Response or *httptest.ResponseRecorder. +// Expected must be either an int or a string. +// +// Expect(resp).Should(HaveHTTPStatus(http.StatusOK)) // asserts that resp.StatusCode == 200 +// Expect(resp).Should(HaveHTTPStatus("404 Not Found")) // asserts that resp.Status == "404 Not Found" +// Expect(resp).Should(HaveHTTPStatus(http.StatusOK, http.StatusNoContent)) // asserts that resp.StatusCode == 200 || resp.StatusCode == 204 func HaveHTTPStatus(expected ...interface{}) types.GomegaMatcher { return &matchers.HaveHTTPStatusMatcher{Expected: expected} } @@ -518,63 +589,70 @@ func HaveHTTPBody(expected interface{}) types.GomegaMatcher { return &matchers.HaveHTTPBodyMatcher{Expected: expected} } -//And succeeds only if all of the given matchers succeed. -//The matchers are tried in order, and will fail-fast if one doesn't succeed. -// Expect("hi").To(And(HaveLen(2), Equal("hi")) +// And succeeds only if all of the given matchers succeed. +// The matchers are tried in order, and will fail-fast if one doesn't succeed. +// +// Expect("hi").To(And(HaveLen(2), Equal("hi")) // -//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func And(ms ...types.GomegaMatcher) types.GomegaMatcher { return &matchers.AndMatcher{Matchers: ms} } -//SatisfyAll is an alias for And(). -// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi"))) +// SatisfyAll is an alias for And(). +// +// Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi"))) func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher { return And(matchers...) } -//Or succeeds if any of the given matchers succeed. -//The matchers are tried in order and will return immediately upon the first successful match. -// Expect("hi").To(Or(HaveLen(3), HaveLen(2)) +// Or succeeds if any of the given matchers succeed. +// The matchers are tried in order and will return immediately upon the first successful match. // -//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +// Expect("hi").To(Or(HaveLen(3), HaveLen(2)) +// +// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func Or(ms ...types.GomegaMatcher) types.GomegaMatcher { return &matchers.OrMatcher{Matchers: ms} } -//SatisfyAny is an alias for Or(). -// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2)) +// SatisfyAny is an alias for Or(). +// +// Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2)) func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher { return Or(matchers...) } -//Not negates the given matcher; it succeeds if the given matcher fails. -// Expect(1).To(Not(Equal(2)) +// Not negates the given matcher; it succeeds if the given matcher fails. +// +// Expect(1).To(Not(Equal(2)) // -//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func Not(matcher types.GomegaMatcher) types.GomegaMatcher { return &matchers.NotMatcher{Matcher: matcher} } -//WithTransform applies the `transform` to the actual value and matches it against `matcher`. -//The given transform must be either a function of one parameter that returns one value or a +// WithTransform applies the `transform` to the actual value and matches it against `matcher`. +// The given transform must be either a function of one parameter that returns one value or a // function of one parameter that returns two values, where the second value must be of the // error type. -// var plus1 = func(i int) int { return i + 1 } -// Expect(1).To(WithTransform(plus1, Equal(2)) // -// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" } -// Expect(1).To(WithTransform(failingplus1, Equal(2))) +// var plus1 = func(i int) int { return i + 1 } +// Expect(1).To(WithTransform(plus1, Equal(2)) // -//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. +// var failingplus1 = func(i int) (int, error) { return 42, "this does not compute" } +// Expect(1).To(WithTransform(failingplus1, Equal(2))) +// +// And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions. func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher { return matchers.NewWithTransformMatcher(transform, matcher) } -//Satisfy matches the actual value against the `predicate` function. -//The given predicate must be a function of one paramter that returns bool. -// var isEven = func(i int) bool { return i%2 == 0 } -// Expect(2).To(Satisfy(isEven)) +// Satisfy matches the actual value against the `predicate` function. +// The given predicate must be a function of one paramter that returns bool. +// +// var isEven = func(i int) bool { return i%2 == 0 } +// Expect(2).To(Satisfy(isEven)) func Satisfy(predicate interface{}) types.GomegaMatcher { return matchers.NewSatisfyMatcher(predicate) } diff --git a/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go new file mode 100644 index 00000000000..8ab4bb91949 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go @@ -0,0 +1,49 @@ +package matchers + +import ( + "bytes" + "fmt" + + "github.com/google/go-cmp/cmp" + "github.com/onsi/gomega/format" +) + +type BeComparableToMatcher struct { + Expected interface{} + Options cmp.Options +} + +func (matcher *BeComparableToMatcher) Match(actual interface{}) (success bool, matchErr error) { + if actual == nil && matcher.Expected == nil { + return false, fmt.Errorf("Refusing to compare to .\nBe explicit and use BeNil() instead. This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.") + } + // Shortcut for byte slices. + // Comparing long byte slices with reflect.DeepEqual is very slow, + // so use bytes.Equal if actual and expected are both byte slices. + if actualByteSlice, ok := actual.([]byte); ok { + if expectedByteSlice, ok := matcher.Expected.([]byte); ok { + return bytes.Equal(actualByteSlice, expectedByteSlice), nil + } + } + + defer func() { + if r := recover(); r != nil { + success = false + if err, ok := r.(error); ok { + matchErr = err + } else if errMsg, ok := r.(string); ok { + matchErr = fmt.Errorf(errMsg) + } + } + }() + + return cmp.Equal(actual, matcher.Expected, matcher.Options...), nil +} + +func (matcher *BeComparableToMatcher) FailureMessage(actual interface{}) (message string) { + return cmp.Diff(matcher.Expected, actual, matcher.Options) +} + +func (matcher *BeComparableToMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "not to equal", matcher.Expected) +} diff --git a/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go new file mode 100644 index 00000000000..449a291ef9a --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go @@ -0,0 +1,45 @@ +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type BeKeyOfMatcher struct { + Map interface{} +} + +func (matcher *BeKeyOfMatcher) Match(actual interface{}) (success bool, err error) { + if !isMap(matcher.Map) { + return false, fmt.Errorf("BeKeyOf matcher needs expected to be a map type") + } + + if reflect.TypeOf(actual) == nil { + return false, fmt.Errorf("BeKeyOf matcher expects actual to be typed") + } + + var lastError error + for _, key := range reflect.ValueOf(matcher.Map).MapKeys() { + matcher := &EqualMatcher{Expected: key.Interface()} + success, err := matcher.Match(actual) + if err != nil { + lastError = err + continue + } + if success { + return true, nil + } + } + + return false, lastError +} + +func (matcher *BeKeyOfMatcher) FailureMessage(actual interface{}) (message string) { + return format.Message(actual, "to be a key of", presentable(valuesOf(matcher.Map))) +} + +func (matcher *BeKeyOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "not to be a key of", presentable(valuesOf(matcher.Map))) +} diff --git a/vendor/github.com/onsi/gomega/matchers/consist_of.go b/vendor/github.com/onsi/gomega/matchers/consist_of.go index e8ef0dee1f4..f69037a4f0e 100644 --- a/vendor/github.com/onsi/gomega/matchers/consist_of.go +++ b/vendor/github.com/onsi/gomega/matchers/consist_of.go @@ -48,11 +48,13 @@ func neighbours(value, matcher interface{}) (bool, error) { func equalMatchersToElements(matchers []interface{}) (elements []interface{}) { for _, matcher := range matchers { - equalMatcher, ok := matcher.(*EqualMatcher) - if ok { - matcher = equalMatcher.Expected + if equalMatcher, ok := matcher.(*EqualMatcher); ok { + elements = append(elements, equalMatcher.Expected) + } else if _, ok := matcher.(*BeNilMatcher); ok { + elements = append(elements, nil) + } else { + elements = append(elements, matcher) } - elements = append(elements, matcher) } return } @@ -72,11 +74,13 @@ func flatten(elems []interface{}) []interface{} { func matchers(expectedElems []interface{}) (matchers []interface{}) { for _, e := range flatten(expectedElems) { - matcher, isMatcher := e.(omegaMatcher) - if !isMatcher { - matcher = &EqualMatcher{Expected: e} + if e == nil { + matchers = append(matchers, &BeNilMatcher{}) + } else if matcher, isMatcher := e.(omegaMatcher); isMatcher { + matchers = append(matchers, matcher) + } else { + matchers = append(matchers, &EqualMatcher{Expected: e}) } - matchers = append(matchers, matcher) } return } @@ -89,9 +93,14 @@ func presentable(elems []interface{}) interface{} { } sv := reflect.ValueOf(elems) - tt := sv.Index(0).Elem().Type() + firstEl := sv.Index(0) + if firstEl.IsNil() { + return elems + } + tt := firstEl.Elem().Type() for i := 1; i < sv.Len(); i++ { - if sv.Index(i).Elem().Type() != tt { + el := sv.Index(i) + if el.IsNil() || (sv.Index(i).Elem().Type() != tt) { return elems } } diff --git a/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go new file mode 100644 index 00000000000..7cce776c184 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go @@ -0,0 +1,83 @@ +package matchers + +import ( + "fmt" + + "github.com/onsi/gomega/format" +) + +type mismatchFailure struct { + failure string + index int +} + +type HaveExactElementsMatcher struct { + Elements []interface{} + mismatchFailures []mismatchFailure + missingIndex int + extraIndex int +} + +func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool, err error) { + matcher.resetState() + + if isMap(actual) { + return false, fmt.Errorf("error") + } + + matchers := matchers(matcher.Elements) + values := valuesOf(actual) + + lenMatchers := len(matchers) + lenValues := len(values) + + for i := 0; i < lenMatchers || i < lenValues; i++ { + if i >= lenMatchers { + matcher.extraIndex = i + continue + } + + if i >= lenValues { + matcher.missingIndex = i + return + } + + elemMatcher := matchers[i].(omegaMatcher) + match, err := elemMatcher.Match(values[i]) + if err != nil || !match { + matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ + index: i, + failure: elemMatcher.FailureMessage(values[i]), + }) + } + } + + return matcher.missingIndex+matcher.extraIndex+len(matcher.mismatchFailures) == 0, nil +} + +func (matcher *HaveExactElementsMatcher) FailureMessage(actual interface{}) (message string) { + message = format.Message(actual, "to have exact elements with", presentable(matcher.Elements)) + if matcher.missingIndex > 0 { + message = fmt.Sprintf("%s\nthe missing elements start from index %d", message, matcher.missingIndex) + } + if matcher.extraIndex > 0 { + message = fmt.Sprintf("%s\nthe extra elements start from index %d", message, matcher.extraIndex) + } + if len(matcher.mismatchFailures) != 0 { + message = fmt.Sprintf("%s\nthe mismatch indexes were:", message) + } + for _, mismatch := range matcher.mismatchFailures { + message = fmt.Sprintf("%s\n%d: %s", message, mismatch.index, mismatch.failure) + } + return +} + +func (matcher *HaveExactElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "not to contain elements", presentable(matcher.Elements)) +} + +func (matcher *HaveExactElementsMatcher) resetState() { + matcher.mismatchFailures = nil + matcher.missingIndex = 0 + matcher.extraIndex = 0 +} diff --git a/vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go new file mode 100644 index 00000000000..b57018745fa --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go @@ -0,0 +1,36 @@ +package matchers + +import ( + "errors" + "fmt" + + "github.com/onsi/gomega/format" +) + +type HaveExistingFieldMatcher struct { + Field string +} + +func (matcher *HaveExistingFieldMatcher) Match(actual interface{}) (success bool, err error) { + // we don't care about the field's actual value, just about any error in + // trying to find the field (or method). + _, err = extractField(actual, matcher.Field, "HaveExistingField") + if err == nil { + return true, nil + } + var mferr missingFieldError + if errors.As(err, &mferr) { + // missing field errors aren't errors in this context, but instead + // unsuccessful matches. + return false, nil + } + return false, err +} + +func (matcher *HaveExistingFieldMatcher) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Expected\n%s\nto have field '%s'", format.Object(actual, 1), matcher.Field) +} + +func (matcher *HaveExistingFieldMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Expected\n%s\nnot to have field '%s'", format.Object(actual, 1), matcher.Field) +} diff --git a/vendor/github.com/onsi/gomega/matchers/have_field.go b/vendor/github.com/onsi/gomega/matchers/have_field.go index e1fe934d558..6989f78c4b4 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_field.go +++ b/vendor/github.com/onsi/gomega/matchers/have_field.go @@ -8,7 +8,16 @@ import ( "github.com/onsi/gomega/format" ) -func extractField(actual interface{}, field string) (interface{}, error) { +// missingFieldError represents a missing field extraction error that +// HaveExistingFieldMatcher can ignore, as opposed to other, sever field +// extraction errors, such as nil pointers, et cetera. +type missingFieldError string + +func (e missingFieldError) Error() string { + return string(e) +} + +func extractField(actual interface{}, field string, matchername string) (interface{}, error) { fields := strings.SplitN(field, ".", 2) actualValue := reflect.ValueOf(actual) @@ -16,36 +25,39 @@ func extractField(actual interface{}, field string) (interface{}, error) { actualValue = actualValue.Elem() } if actualValue == (reflect.Value{}) { - return nil, fmt.Errorf("HaveField encountered nil while dereferencing a pointer of type %T.", actual) + return nil, fmt.Errorf("%s encountered nil while dereferencing a pointer of type %T.", matchername, actual) } if actualValue.Kind() != reflect.Struct { - return nil, fmt.Errorf("HaveField encountered:\n%s\nWhich is not a struct.", format.Object(actual, 1)) + return nil, fmt.Errorf("%s encountered:\n%s\nWhich is not a struct.", matchername, format.Object(actual, 1)) } var extractedValue reflect.Value if strings.HasSuffix(fields[0], "()") { extractedValue = actualValue.MethodByName(strings.TrimSuffix(fields[0], "()")) + if extractedValue == (reflect.Value{}) && actualValue.CanAddr() { + extractedValue = actualValue.Addr().MethodByName(strings.TrimSuffix(fields[0], "()")) + } if extractedValue == (reflect.Value{}) { - return nil, fmt.Errorf("HaveField could not find method named '%s' in struct of type %T.", fields[0], actual) + return nil, missingFieldError(fmt.Sprintf("%s could not find method named '%s' in struct of type %T.", matchername, fields[0], actual)) } t := extractedValue.Type() if t.NumIn() != 0 || t.NumOut() != 1 { - return nil, fmt.Errorf("HaveField found an invalid method named '%s' in struct of type %T.\nMethods must take no arguments and return exactly one value.", fields[0], actual) + return nil, fmt.Errorf("%s found an invalid method named '%s' in struct of type %T.\nMethods must take no arguments and return exactly one value.", matchername, fields[0], actual) } extractedValue = extractedValue.Call([]reflect.Value{})[0] } else { extractedValue = actualValue.FieldByName(fields[0]) if extractedValue == (reflect.Value{}) { - return nil, fmt.Errorf("HaveField could not find field named '%s' in struct:\n%s", fields[0], format.Object(actual, 1)) + return nil, missingFieldError(fmt.Sprintf("%s could not find field named '%s' in struct:\n%s", matchername, fields[0], format.Object(actual, 1))) } } if len(fields) == 1 { return extractedValue.Interface(), nil } else { - return extractField(extractedValue.Interface(), fields[1]) + return extractField(extractedValue.Interface(), fields[1], matchername) } } @@ -58,7 +70,7 @@ type HaveFieldMatcher struct { } func (matcher *HaveFieldMatcher) Match(actual interface{}) (success bool, err error) { - matcher.extractedField, err = extractField(actual, matcher.Field) + matcher.extractedField, err = extractField(actual, matcher.Field, "HaveField") if err != nil { return false, err } diff --git a/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go index 5bcfdd2ade9..22a1b67306f 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go @@ -31,5 +31,5 @@ func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message } func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("Unexpected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "occurred") + return fmt.Sprintf("Unexpected error:\n%s\n%s", format.Object(actual, 1), "occurred") } diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go index c8993a86d9f..827475ea51c 100644 --- a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go @@ -25,7 +25,17 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e expected := matcher.Expected if isError(expected) { - return reflect.DeepEqual(actualErr, expected) || errors.Is(actualErr, expected.(error)), nil + // first try the built-in errors.Is + if errors.Is(actualErr, expected.(error)) { + return true, nil + } + // if not, try DeepEqual along the error chain + for unwrapped := actualErr; unwrapped != nil; unwrapped = errors.Unwrap(unwrapped) { + if reflect.DeepEqual(unwrapped, expected) { + return true, nil + } + } + return false, nil } if isString(expected) { diff --git a/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go index 0c83c2b638a..2cb6b47db95 100644 --- a/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/onsi/gomega/format" - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" ) type MatchYAMLMatcher struct { diff --git a/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go b/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go index 721ed5529bc..327350f7b71 100644 --- a/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go @@ -1,11 +1,16 @@ package matchers import ( + "errors" "fmt" "github.com/onsi/gomega/format" ) +type formattedGomegaError interface { + FormattedGomegaError() string +} + type SucceedMatcher struct { } @@ -25,7 +30,11 @@ func (matcher *SucceedMatcher) Match(actual interface{}) (success bool, err erro } func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1)) + var fgErr formattedGomegaError + if errors.As(actual.(error), &fgErr) { + return fgErr.FormattedGomegaError() + } + return fmt.Sprintf("Expected success, but got an error:\n%s", format.Object(actual, 1)) } func (matcher *SucceedMatcher) NegatedFailureMessage(actual interface{}) (message string) { diff --git a/vendor/github.com/onsi/gomega/tools b/vendor/github.com/onsi/gomega/tools deleted file mode 100644 index e4195cf362f..00000000000 --- a/vendor/github.com/onsi/gomega/tools +++ /dev/null @@ -1,8 +0,0 @@ -//go:build tools -// +build tools - -package main - -import ( - _ "github.com/onsi/ginkgo/v2/ginkgo" -) diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go index c315ef06567..7c7adb9415d 100644 --- a/vendor/github.com/onsi/gomega/types/types.go +++ b/vendor/github.com/onsi/gomega/types/types.go @@ -1,12 +1,13 @@ package types import ( + "context" "time" ) type GomegaFailHandler func(message string, callerSkip ...int) -//A simple *testing.T interface wrapper +// A simple *testing.T interface wrapper type GomegaTestingT interface { Helper() Fatalf(format string, args ...interface{}) @@ -18,11 +19,11 @@ type Gomega interface { Expect(actual interface{}, extra ...interface{}) Assertion ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Assertion - Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion - EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion + Eventually(actualOrCtx interface{}, args ...interface{}) AsyncAssertion + EventuallyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion - Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion - ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion + Consistently(actualOrCtx interface{}, args ...interface{}) AsyncAssertion + ConsistentlyWithOffset(offset int, actualOrCtx interface{}, args ...interface{}) AsyncAssertion SetDefaultEventuallyTimeout(time.Duration) SetDefaultEventuallyPollingInterval(time.Duration) @@ -30,9 +31,9 @@ type Gomega interface { SetDefaultConsistentlyPollingInterval(time.Duration) } -//All Gomega matchers must implement the GomegaMatcher interface +// All Gomega matchers must implement the GomegaMatcher interface // -//For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers +// For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers type GomegaMatcher interface { Match(actual interface{}) (success bool, err error) FailureMessage(actual interface{}) (message string) @@ -70,6 +71,11 @@ type AsyncAssertion interface { WithOffset(offset int) AsyncAssertion WithTimeout(interval time.Duration) AsyncAssertion WithPolling(interval time.Duration) AsyncAssertion + Within(timeout time.Duration) AsyncAssertion + ProbeEvery(interval time.Duration) AsyncAssertion + WithContext(ctx context.Context) AsyncAssertion + WithArguments(argsToForward ...interface{}) AsyncAssertion + MustPassRepeatedly(count int) AsyncAssertion } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers diff --git a/vendor/github.com/open-policy-agent/cert-controller/pkg/rotator/rotator.go b/vendor/github.com/open-policy-agent/cert-controller/pkg/rotator/rotator.go index 52dc348322b..f51ae59d53f 100644 --- a/vendor/github.com/open-policy-agent/cert-controller/pkg/rotator/rotator.go +++ b/vendor/github.com/open-policy-agent/cert-controller/pkg/rotator/rotator.go @@ -35,46 +35,63 @@ import ( ) const ( - certName = "tls.crt" - keyName = "tls.key" - caCertName = "ca.crt" - caKeyName = "ca.key" - rotationCheckFrequency = 12 * time.Hour - certValidityDuration = 10 * 365 * 24 * time.Hour - lookaheadInterval = 90 * 24 * time.Hour + certName = "tls.crt" + keyName = "tls.key" + caCertName = "ca.crt" + caKeyName = "ca.key" + rotationCheckFrequency = 12 * time.Hour + defaultCertValidityDuration = 10 * 365 * 24 * time.Hour + lookaheadInterval = 90 * 24 * time.Hour ) var crLog = logf.Log.WithName("cert-rotation") -//WebhookType it the type of webhook, either validating/mutating webhook, a CRD conversion webhook, or an extension API server +// WebhookType it the type of webhook, either validating/mutating webhook, a CRD conversion webhook, or an extension API server. type WebhookType int const ( - //ValidatingWebhook indicates the webhook is a ValidatingWebhook + // ValidatingWebhook indicates the webhook is a ValidatingWebhook. Validating WebhookType = iota - //MutingWebhook indicates the webhook is a MutatingWebhook + // MutingWebhook indicates the webhook is a MutatingWebhook. Mutating - //CRDConversionWebhook indicates the webhook is a conversion webhook + // CRDConversionWebhook indicates the webhook is a conversion webhook. CRDConversion - //APIServiceWebhook indicates the webhook is an extension API server + // APIServiceWebhook indicates the webhook is an extension API server. APIService + // ExternalDataProvider indicates the webhook is a Gatekeeper External Data Provider. + ExternalDataProvider ) -var _ manager.Runnable = &CertRotator{} +var ( + _ manager.Runnable = &CertRotator{} + _ manager.LeaderElectionRunnable = &CertRotator{} + _ manager.Runnable = controllerWrapper{} + _ manager.LeaderElectionRunnable = controllerWrapper{} +) + +type controllerWrapper struct { + controller.Controller + needLeaderElection bool +} + +func (cw controllerWrapper) NeedLeaderElection() bool { + return cw.needLeaderElection +} -//WebhookInfo is used by the rotator to receive info about resources to be updated with certificates +// WebhookInfo is used by the rotator to receive info about resources to be updated with certificates. type WebhookInfo struct { - //Name is the name of the webhook for a validating or mutating webhook, or the CRD name in case of a CRD conversion webhook + // Name is the name of the webhook for a validating or mutating webhook, or the CRD name in case of a CRD conversion webhook Name string Type WebhookType } func (w WebhookInfo) gvk() schema.GroupVersionKind { t2g := map[WebhookType]schema.GroupVersionKind{ - Validating: {Group: "admissionregistration.k8s.io", Version: "v1", Kind: "ValidatingWebhookConfiguration"}, - Mutating: {Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfiguration"}, - CRDConversion: {Group: "apiextensions.k8s.io", Version: "v1", Kind: "CustomResourceDefinition"}, - APIService: {Group: "apiregistration.k8s.io", Version: "v1", Kind: "APIService"}, + Validating: {Group: "admissionregistration.k8s.io", Version: "v1", Kind: "ValidatingWebhookConfiguration"}, + Mutating: {Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfiguration"}, + CRDConversion: {Group: "apiextensions.k8s.io", Version: "v1", Kind: "CustomResourceDefinition"}, + APIService: {Group: "apiregistration.k8s.io", Version: "v1", Kind: "APIService"}, + ExternalDataProvider: {Group: "externaldata.gatekeeper.sh", Version: "v1beta1", Kind: "Provider"}, } return t2g[w.Type] } @@ -99,18 +116,22 @@ func AddRotator(mgr manager.Manager, cr *CertRotator) error { cr.certsNotMounted = make(chan struct{}) cr.wasCAInjected = atomic.NewBool(false) cr.caNotInjected = make(chan struct{}) - if err := mgr.Add(cr); err != nil { - return err + if !cr.testNoBackgroundRotation { + if err := mgr.Add(cr); err != nil { + return err + } } reconciler := &ReconcileWH{ - cache: cache, - writer: mgr.GetClient(), // TODO - scheme: mgr.GetScheme(), - ctx: context.Background(), - secretKey: cr.SecretKey, - wasCAInjected: cr.wasCAInjected, - webhooks: cr.Webhooks, + cache: cache, + writer: mgr.GetClient(), // TODO + scheme: mgr.GetScheme(), + ctx: context.Background(), + secretKey: cr.SecretKey, + wasCAInjected: cr.wasCAInjected, + webhooks: cr.Webhooks, + needLeaderElection: cr.RequireLeaderElection, + refreshCertIfNeededDelegate: cr.refreshCertIfNeeded, } if err := addController(mgr, reconciler); err != nil { return err @@ -126,9 +147,11 @@ func AddRotator(mgr manager.Manager, cr *CertRotator) error { func addNamespacedCache(mgr manager.Manager, namespace string) (cache.Cache, error) { c, err := cache.New(mgr.GetConfig(), cache.Options{ - Scheme: mgr.GetScheme(), - Mapper: mgr.GetRESTMapper(), - Namespace: namespace, + Scheme: mgr.GetScheme(), + Mapper: mgr.GetRESTMapper(), + Namespaces: []string{ + namespace, + }, }) if err != nil { return nil, err @@ -147,21 +170,37 @@ type SyncingReader interface { // CertRotator contains cert artifacts and a channel to close when the certs are ready. type CertRotator struct { - reader SyncingReader - writer client.Writer + reader SyncingReader + writer client.Writer + SecretKey types.NamespacedName CertDir string CAName string CAOrganization string DNSName string + ExtraDNSNames []string IsReady chan struct{} Webhooks []WebhookInfo RestartOnSecretRefresh bool ExtKeyUsages *[]x509.ExtKeyUsage - certsMounted chan struct{} - certsNotMounted chan struct{} - wasCAInjected *atomic.Bool - caNotInjected chan struct{} + // RequireLeaderElection should be set to true if the CertRotator needs to + // be run in the leader election mode. + RequireLeaderElection bool + + certsMounted chan struct{} + certsNotMounted chan struct{} + wasCAInjected *atomic.Bool + caNotInjected chan struct{} + + // testNoBackgroundRotation doesn't actually start the rotator in the background. + // This should only be used for testing. + testNoBackgroundRotation bool + // caCertDuration sets how long a CA cert will be valid for. + caCertDuration time.Duration +} + +func (cr *CertRotator) NeedLeaderElection() bool { + return cr.RequireLeaderElection } // Start starts the CertRotator runnable to rotate certs and ensure the certs are ready. @@ -176,12 +215,15 @@ func (cr *CertRotator) Start(ctx context.Context) error { if cr.ExtKeyUsages == nil { cr.ExtKeyUsages = &[]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} } + if cr.caCertDuration == time.Duration(0) { + cr.caCertDuration = defaultCertValidityDuration + } // explicitly rotate on the first round so that the certificate // can be bootstrapped, otherwise manager exits before a cert can be written crLog.Info("starting cert rotator controller") defer crLog.Info("stopping cert rotator controller") - if err := cr.refreshCertIfNeeded(); err != nil { + if _, err := cr.refreshCertIfNeeded(); err != nil { crLog.Error(err, "could not refresh cert on startup") return err } @@ -196,7 +238,7 @@ tickerLoop: for { select { case <-ticker.C: - if err := cr.refreshCertIfNeeded(); err != nil { + if _, err := cr.refreshCertIfNeeded(); err != nil { crLog.Error(err, "error rotating certs") } case <-ctx.Done(): @@ -212,8 +254,11 @@ tickerLoop: return nil } -// refreshCertIfNeeded returns whether there's any error when refreshing the certs if needed. -func (cr *CertRotator) refreshCertIfNeeded() error { +// refreshCertIfNeeded returns true if the CA was rotated +// and if there's any error when rotating the CA or refreshing the certs. +func (cr *CertRotator) refreshCertIfNeeded() (bool, error) { + var rotatedCA bool + refreshFn := func() (bool, error) { secret := &corev1.Secret{} if err := cr.reader.Get(context.Background(), cr.SecretKey, secret); err != nil { @@ -225,6 +270,7 @@ func (cr *CertRotator) refreshCertIfNeeded() error { crLog.Error(err, "could not refresh CA and server certs") return false, nil } + rotatedCA = true crLog.Info("server certs refreshed") if cr.RestartOnSecretRefresh { crLog.Info("Secrets have been updated; exiting so pod can be restarted (This behaviour can be changed with the option RestartOnSecretRefresh)") @@ -255,16 +301,16 @@ func (cr *CertRotator) refreshCertIfNeeded() error { Jitter: 1, Steps: 10, }, refreshFn); err != nil { - return err + return rotatedCA, err } - return nil + return rotatedCA, nil } func (cr *CertRotator) refreshCerts(refreshCA bool, secret *corev1.Secret) error { var caArtifacts *KeyPairArtifacts now := time.Now() begin := now.Add(-1 * time.Hour) - end := now.Add(certValidityDuration) + end := now.Add(cr.caCertDuration) if refreshCA { var err error caArtifacts, err = cr.CreateCACert(begin, end) @@ -298,8 +344,10 @@ func injectCert(updatedResource *unstructured.Unstructured, certPem []byte, webh return injectCertToConversionWebhook(updatedResource, certPem) case APIService: return injectCertToApiService(updatedResource, certPem) + case ExternalDataProvider: + return injectCertToExternalDataProvider(updatedResource, certPem) } - return fmt.Errorf("Incorrect webhook type") + return fmt.Errorf("incorrect webhook type") } func injectCertToWebhook(wh *unstructured.Unstructured, certPem []byte) error { @@ -308,7 +356,7 @@ func injectCertToWebhook(wh *unstructured.Unstructured, certPem []byte) error { return err } if !found { - return errors.New("`webhooks` field not found in ValidatingWebhookConfiguration") + return nil } for i, h := range webhooks { hook, ok := h.(map[string]interface{}) @@ -356,6 +404,21 @@ func injectCertToApiService(apiService *unstructured.Unstructured, certPem []byt return nil } +func injectCertToExternalDataProvider(externalDataProvider *unstructured.Unstructured, certPem []byte) error { + _, found, err := unstructured.NestedMap(externalDataProvider.Object, "spec") + if err != nil { + return err + } + if !found { + return errors.New("`spec` field not found in Provider") + } + if err := unstructured.SetNestedField(externalDataProvider.Object, base64.StdEncoding.EncodeToString(certPem), "spec", "caBundle"); err != nil { + return err + } + + return nil +} + func (cr *CertRotator) writeSecret(cert, key []byte, caArtifacts *KeyPairArtifacts, secret *corev1.Secret) error { populateSecret(cert, key, caArtifacts, secret) return cr.writer.Update(context.Background(), secret) @@ -413,7 +476,7 @@ func buildArtifactsFromSecret(secret *corev1.Secret) (*KeyPairArtifacts, error) } // CreateCACert creates the self-signed CA cert and private key that will -// be used to sign the server certificate +// be used to sign the server certificate. func (cr *CertRotator) CreateCACert(begin, end time.Time) (*KeyPairArtifacts, error) { templ := &x509.Certificate{ SerialNumber: big.NewInt(0), @@ -451,16 +514,16 @@ func (cr *CertRotator) CreateCACert(begin, end time.Time) (*KeyPairArtifacts, er } // CreateCertPEM takes the results of CreateCACert and uses it to create the -// PEM-encoded public certificate and private key, respectively +// PEM-encoded public certificate and private key, respectively. func (cr *CertRotator) CreateCertPEM(ca *KeyPairArtifacts, begin, end time.Time) ([]byte, []byte, error) { + dnsNames := []string{cr.DNSName} + dnsNames = append(dnsNames, cr.ExtraDNSNames...) templ := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: cr.DNSName, }, - DNSNames: []string{ - cr.DNSName, - }, + DNSNames: dnsNames, NotBefore: begin, NotAfter: end, KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, @@ -482,7 +545,7 @@ func (cr *CertRotator) CreateCertPEM(ca *KeyPairArtifacts, begin, end time.Time) return certPEM, keyPEM, nil } -// pemEncode takes a certificate and encodes it as PEM +// pemEncode takes a certificate and encodes it as PEM. func pemEncode(certificateDER []byte, key *rsa.PrivateKey) ([]byte, []byte, error) { certBuf := &bytes.Buffer{} if err := pem.Encode(certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: certificateDER}); err != nil { @@ -562,8 +625,8 @@ func ValidCert(caCert, cert, key []byte, dnsName string, keyUsages *[]x509.ExtKe return true, nil } -func reconcileSecretAndWebhookMapFunc(webhook WebhookInfo, r *ReconcileWH) func(object client.Object) []reconcile.Request { - return func(object client.Object) []reconcile.Request { +func reconcileSecretAndWebhookMapFunc(webhook WebhookInfo, r *ReconcileWH) func(ctx context.Context, object client.Object) []reconcile.Request { + return func(ctx context.Context, object client.Object) []reconcile.Request { whKey := types.NamespacedName{Name: webhook.Name} if object.GetNamespace() != whKey.Namespace { return nil @@ -575,16 +638,19 @@ func reconcileSecretAndWebhookMapFunc(webhook WebhookInfo, r *ReconcileWH) func( } } -// add adds a new Controller to mgr with r as the reconcile.Reconciler +// add adds a new Controller to mgr with r as the reconcile.Reconciler. func addController(mgr manager.Manager, r *ReconcileWH) error { // Create a new controller - c, err := controller.New("cert-rotator", mgr, controller.Options{Reconciler: r}) + c, err := controller.NewUnmanaged("cert-rotator", mgr, controller.Options{Reconciler: r}) if err != nil { return err } + if err := mgr.Add(controllerWrapper{c, r.needLeaderElection}); err != nil { + return err + } err = c.Watch( - source.NewKindWithCache(&corev1.Secret{}, r.cache), + source.Kind(r.cache, &corev1.Secret{}), &handler.EnqueueRequestForObject{}, ) if err != nil { @@ -595,7 +661,7 @@ func addController(mgr manager.Manager, r *ReconcileWH) error { wh := &unstructured.Unstructured{} wh.SetGroupVersionKind(webhook.gvk()) err = c.Watch( - source.NewKindWithCache(wh, r.cache), + source.Kind(r.cache, wh), handler.EnqueueRequestsFromMapFunc(reconcileSecretAndWebhookMapFunc(webhook, r)), ) if err != nil { @@ -609,19 +675,21 @@ func addController(mgr manager.Manager, r *ReconcileWH) error { var _ reconcile.Reconciler = &ReconcileWH{} // ReconcileWH reconciles a validatingwebhookconfiguration, making sure it -// has the appropriate CA cert +// has the appropriate CA cert. type ReconcileWH struct { - writer client.Writer - cache cache.Cache - scheme *runtime.Scheme - ctx context.Context - secretKey types.NamespacedName - webhooks []WebhookInfo - wasCAInjected *atomic.Bool + writer client.Writer + cache cache.Cache + scheme *runtime.Scheme + ctx context.Context + secretKey types.NamespacedName + webhooks []WebhookInfo + wasCAInjected *atomic.Bool + needLeaderElection bool + refreshCertIfNeededDelegate func() (bool, error) } // Reconcile reads that state of the cluster for a validatingwebhookconfiguration -// object and makes sure the most recent CA cert is included +// object and makes sure the most recent CA cert is included. func (r *ReconcileWH) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { if request.NamespacedName != r.secretKey { return reconcile.Result{}, nil @@ -643,6 +711,19 @@ func (r *ReconcileWH) Reconcile(ctx context.Context, request reconcile.Request) } if secret.GetDeletionTimestamp().IsZero() { + if r.refreshCertIfNeededDelegate != nil { + rotatedCA, err := r.refreshCertIfNeededDelegate() + if err != nil { + crLog.Error(err, "error rotating certs on secret reconcile") + return reconcile.Result{}, err + } + + // if we did rotate the CA, the secret is stale so let's return + if rotatedCA { + return reconcile.Result{}, nil + } + } + artifacts, err := buildArtifactsFromSecret(secret) if err != nil { crLog.Error(err, "secret is not well-formed, cannot update webhook configurations") diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/deploy/crds.yaml b/vendor/github.com/open-policy-agent/frameworks/constraint/deploy/crds.yaml index 9ae0cb7e2c6..3015bcad338 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/deploy/crds.yaml +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/deploy/crds.yaml @@ -2,7 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null name: constrainttemplates.templates.gatekeeper.sh spec: group: templates.gatekeeper.sh @@ -17,13 +18,18 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -59,6 +65,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -75,11 +102,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -93,7 +122,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 @@ -112,13 +142,18 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -154,6 +189,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -170,11 +226,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -188,7 +246,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 @@ -207,13 +266,18 @@ spec: - name: v1beta1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -249,6 +313,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -265,11 +350,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -283,7 +370,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 @@ -304,7 +392,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 creationTimestamp: null name: providers.externaldata.gatekeeper.sh spec: @@ -317,17 +405,22 @@ spec: scope: Cluster versions: - deprecated: true - deprecationWarning: externaldata.gatekeeper.sh/v1alpha1 is deprecated. Use externaldata.gatekeeper.sh/v1beta1 instead. + deprecationWarning: externaldata.gatekeeper.sh/v1alpha1 is deprecated. Use externaldata.gatekeeper.sh/v1beta1 + instead. name: v1alpha1 schema: openAPIV3Schema: description: Provider is the Schema for the Provider API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -335,28 +428,35 @@ spec: description: Spec defines the Provider specifications. properties: caBundle: - description: CABundle is a base64-encoded string that contains the TLS CA bundle in PEM format. It is used to verify the signature of the provider's certificate. + description: CABundle is a base64-encoded string that contains the + TLS CA bundle in PEM format. It is used to verify the signature + of the provider's certificate. type: string timeout: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with + https://. type: string type: object type: object served: true - storage: true + storage: false - name: v1beta1 schema: openAPIV3Schema: description: Provider is the Schema for the providers API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -364,15 +464,18 @@ spec: description: Spec defines the Provider specifications. properties: caBundle: - description: CABundle is a base64-encoded string that contains the TLS CA bundle in PEM format. It is used to verify the signature of the provider's certificate. + description: CABundle is a base64-encoded string that contains the + TLS CA bundle in PEM format. It is used to verify the signature + of the provider's certificate. type: string timeout: description: Timeout is the timeout when querying the provider. type: integer url: - description: URL is the url for the provider. URL is prefixed with http:// or https://. + description: URL is the url for the provider. URL is prefixed with + https://. type: string type: object type: object served: true - storage: false + storage: true diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned/provider_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned/provider_types.go index be865e26f94..46b4a411860 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned/provider_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned/provider_types.go @@ -23,7 +23,7 @@ import ( // ProviderSpec defines the desired state of Provider. type ProviderSpec struct { - // URL is the url for the provider. URL is prefixed with http:// or https://. + // URL is the url for the provider. URL is prefixed with https://. URL string `json:"url,omitempty"` // Timeout is the timeout when querying the provider. Timeout int `json:"timeout,omitempty"` diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1alpha1/provider_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1alpha1/provider_types.go index 71da1d9c940..6245b3d1ad6 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1alpha1/provider_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1alpha1/provider_types.go @@ -21,7 +21,7 @@ import ( // ProviderSpec defines the desired state of Provider. type ProviderSpec struct { - // URL is the url for the provider. URL is prefixed with http:// or https://. + // URL is the url for the provider. URL is prefixed with https://. URL string `json:"url,omitempty"` // Timeout is the timeout when querying the provider. Timeout int `json:"timeout,omitempty"` @@ -38,7 +38,6 @@ type ProviderSpec struct { // Provider is the Schema for the Provider API // +k8s:openapi-gen=true -// +kubebuilder:storageversion // +k8s:conversion-gen-external-types=github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata type Provider struct { metav1.TypeMeta `json:",inline"` diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1/provider_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1/provider_types.go index 03682572fe7..767ca4237aa 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1/provider_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/v1beta1/provider_types.go @@ -21,7 +21,7 @@ import ( // ProviderSpec defines the desired state of Provider. type ProviderSpec struct { - // URL is the url for the provider. URL is prefixed with http:// or https://. + // URL is the url for the provider. URL is prefixed with https://. URL string `json:"url,omitempty"` // Timeout is the timeout when querying the provider. Timeout int `json:"timeout,omitempty"` @@ -34,6 +34,7 @@ type ProviderSpec struct { // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:resource:scope=Cluster +// +kubebuilder:storageversion // +k8s:conversion-gen-external-types=github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata // Provider is the Schema for the providers API // +k8s:openapi-gen=true diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/constrainttemplate_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/constrainttemplate_types.go index 3d71846de68..ca272adbf10 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/constrainttemplate_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/constrainttemplate_types.go @@ -16,6 +16,7 @@ limitations under the License. package v1 import ( + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -48,6 +49,7 @@ type Validation struct { // +kubebuilder:validation:Schemaless // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields + // +k8s:conversion-gen=false OpenAPIV3Schema *apiextensionsv1.JSONSchemaProps `json:"openAPIV3Schema,omitempty"` // +kubebuilder:default=false LegacySchema *bool `json:"legacySchema,omitempty"` // *bool allows for "unset" state which we need to apply appropriate defaults @@ -57,6 +59,24 @@ type Target struct { Target string `json:"target,omitempty"` Rego string `json:"rego,omitempty"` Libs []string `json:"libs,omitempty"` + // The source code options for the constraint template. "Rego" can only + // be specified in one place (either here or in the "rego" field) + // +listType=map + // +listMapKey=engine + // +kubebuilder:validation:Required + Code []Code `json:"code,omitempty"` +} + +type Code struct { + // The engine used to evaluate the code. Example: "Rego". Required. + // +kubebuilder:validation:Required + Engine string `json:"engine"` + + // +kubebuilder:validation:Required + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // The source code for the template. Required. + Source *templates.Anything `json:"source"` } // CreateCRDError represents a single error caught during parsing, compiling, etc. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/conversion.go index 7081c15e95e..0c448123b1b 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/conversion.go @@ -16,6 +16,9 @@ limitations under the License. package v1 import ( + "unsafe" + + regoSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" coreTemplates "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/schema" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -61,3 +64,41 @@ func Convert_v1_Validation_To_templates_Validation(in *Validation, out *coreTemp return nil } + +func Convert_v1_Target_To_templates_Target(in *Target, out *coreTemplates.Target, s conversion.Scope) error { // nolint:revive // Required exact function name. + out.Target = in.Target + out.Rego = in.Rego + out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + + out.Code = make([]coreTemplates.Code, len(in.Code)) + for i := range in.Code { + if err := Convert_v1_Code_To_templates_Code(&(in.Code[i]), &(out.Code[i]), s); err != nil { + return err + } + } + + if in.Rego == "" { + return nil + } + + regoSource := ®oSchema.Source{} + regoSource.Rego = in.Rego + regoSource.Libs = append(regoSource.Libs, in.Libs...) + + injected := false + for i := range out.Code { + if out.Code[i].Engine == regoSchema.Name { + out.Code[i].Source.Value = regoSource.ToUnstructured() + injected = true + break + } + } + if !injected { + out.Code = append(out.Code, coreTemplates.Code{ + Engine: regoSchema.Name, + Source: &coreTemplates.Anything{Value: regoSource.ToUnstructured()}, + }) + } + + return nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.conversion.go index 4bacd6c3c56..453cd658c17 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.conversion.go @@ -65,6 +65,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*Code)(nil), (*templates.Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_Code_To_templates_Code(a.(*Code), b.(*templates.Code), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*templates.Code)(nil), (*Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_templates_Code_To_v1_Code(a.(*templates.Code), b.(*Code), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*ConstraintTemplate)(nil), (*templates.ConstraintTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_ConstraintTemplate_To_templates_ConstraintTemplate(a.(*ConstraintTemplate), b.(*templates.ConstraintTemplate), scope) }); err != nil { @@ -125,11 +135,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*templates.Target)(nil), (*Target)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_templates_Target_To_v1_Target(a.(*templates.Target), b.(*Target), scope) }); err != nil { @@ -140,6 +145,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*Validation)(nil), (*templates.Validation)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_Validation_To_templates_Validation(a.(*Validation), b.(*templates.Validation), scope) }); err != nil { @@ -238,6 +248,28 @@ func Convert_templates_CRDSpec_To_v1_CRDSpec(in *templates.CRDSpec, out *CRDSpec return autoConvert_templates_CRDSpec_To_v1_CRDSpec(in, out, s) } +func autoConvert_v1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_v1_Code_To_templates_Code is an autogenerated conversion function. +func Convert_v1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + return autoConvert_v1_Code_To_templates_Code(in, out, s) +} + +func autoConvert_templates_Code_To_v1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_templates_Code_To_v1_Code is an autogenerated conversion function. +func Convert_templates_Code_To_v1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + return autoConvert_templates_Code_To_v1_Code(in, out, s) +} + func autoConvert_v1_ConstraintTemplate_To_templates_ConstraintTemplate(in *ConstraintTemplate, out *templates.ConstraintTemplate, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1_ConstraintTemplateSpec_To_templates_ConstraintTemplateSpec(&in.Spec, &out.Spec, s); err != nil { @@ -316,7 +348,17 @@ func autoConvert_v1_ConstraintTemplateSpec_To_templates_ConstraintTemplateSpec(i if err := Convert_v1_CRD_To_templates_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]templates.Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]templates.Target, len(*in)) + for i := range *in { + if err := Convert_v1_Target_To_templates_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -329,7 +371,17 @@ func autoConvert_templates_ConstraintTemplateSpec_To_v1_ConstraintTemplateSpec(i if err := Convert_templates_CRD_To_v1_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]Target, len(*in)) + for i := range *in { + if err := Convert_templates_Target_To_v1_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -410,18 +462,15 @@ func autoConvert_v1_Target_To_templates_Target(in *Target, out *templates.Target out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]templates.Code)(unsafe.Pointer(&in.Code)) return nil } -// Convert_v1_Target_To_templates_Target is an autogenerated conversion function. -func Convert_v1_Target_To_templates_Target(in *Target, out *templates.Target, s conversion.Scope) error { - return autoConvert_v1_Target_To_templates_Target(in, out, s) -} - func autoConvert_templates_Target_To_v1_Target(in *templates.Target, out *Target, s conversion.Scope) error { out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]Code)(unsafe.Pointer(&in.Code)) return nil } @@ -430,6 +479,12 @@ func Convert_templates_Target_To_v1_Target(in *templates.Target, out *Target, s return autoConvert_templates_Target_To_v1_Target(in, out, s) } +func autoConvert_v1_Validation_To_templates_Validation(in *Validation, out *templates.Validation, s conversion.Scope) error { + // INFO: in.OpenAPIV3Schema opted out of conversion generation + out.LegacySchema = (*bool)(unsafe.Pointer(in.LegacySchema)) + return nil +} + func autoConvert_templates_Validation_To_v1_Validation(in *templates.Validation, out *Validation, s conversion.Scope) error { if in.OpenAPIV3Schema != nil { in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.deepcopy.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.deepcopy.go index 00df042db11..797b58ef42a 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1/zz_generated.deepcopy.go @@ -81,6 +81,25 @@ func (in *CRDSpec) DeepCopy() *CRDSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Code) DeepCopyInto(out *Code) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Code. +func (in *Code) DeepCopy() *Code { + if in == nil { + return nil + } + out := new(Code) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConstraintTemplate) DeepCopyInto(out *ConstraintTemplate) { *out = *in @@ -228,6 +247,13 @@ func (in *Target) DeepCopyInto(out *Target) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Code != nil { + in, out := &in.Code, &out.Code + *out = make([]Code, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/constrainttemplate_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/constrainttemplate_types.go index 061926cf5b9..71f337e2622 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/constrainttemplate_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/constrainttemplate_types.go @@ -16,6 +16,7 @@ limitations under the License. package v1alpha1 import ( + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -48,6 +49,7 @@ type Validation struct { // +kubebuilder:validation:Schemaless // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields + // +k8s:conversion-gen=false OpenAPIV3Schema *apiextensionsv1.JSONSchemaProps `json:"openAPIV3Schema,omitempty"` // +kubebuilder:default=true LegacySchema *bool `json:"legacySchema,omitempty"` // *bool allows for "unset" state which we need to apply appropriate defaults @@ -57,6 +59,23 @@ type Target struct { Target string `json:"target,omitempty"` Rego string `json:"rego,omitempty"` Libs []string `json:"libs,omitempty"` + // The source code options for the constraint template. "Rego" can only + // be specified in one place (either here or in the "rego" field) + // +listType=map + // +listMapKey=engine + Code []Code `json:"code,omitempty"` +} + +type Code struct { + // The engine used to evaluate the code. Example: "Rego". Required. + // +kubebuilder:validation:Required + Engine string `json:"engine"` + + // +kubebuilder:validation:Required + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // The source code for the template. Required. + Source *templates.Anything `json:"source"` } // CreateCRDError represents a single error caught during parsing, compiling, etc. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/conversion.go index 68cf0201462..bdfaef9751d 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/conversion.go @@ -16,6 +16,9 @@ limitations under the License. package v1alpha1 import ( + "unsafe" + + regoSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" coreTemplates "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/schema" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -61,3 +64,41 @@ func Convert_v1alpha1_Validation_To_templates_Validation(in *Validation, out *co return nil } + +func Convert_v1alpha1_Target_To_templates_Target(in *Target, out *coreTemplates.Target, s conversion.Scope) error { // nolint:revive // Required exact function name. + out.Target = in.Target + out.Rego = in.Rego + out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + + out.Code = make([]coreTemplates.Code, len(in.Code)) + for i := range in.Code { + if err := Convert_v1alpha1_Code_To_templates_Code(&(in.Code[i]), &(out.Code[i]), s); err != nil { + return err + } + } + + if in.Rego == "" { + return nil + } + + regoSource := ®oSchema.Source{} + regoSource.Rego = in.Rego + regoSource.Libs = append(regoSource.Libs, in.Libs...) + + injected := false + for i := range out.Code { + if out.Code[i].Engine == regoSchema.Name { + out.Code[i].Source.Value = regoSource.ToUnstructured() + injected = true + break + } + } + if !injected { + out.Code = append(out.Code, coreTemplates.Code{ + Engine: regoSchema.Name, + Source: &coreTemplates.Anything{Value: regoSource.ToUnstructured()}, + }) + } + + return nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.conversion.go index ef3792ae516..38fe6f4cd88 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.conversion.go @@ -65,6 +65,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*Code)(nil), (*templates.Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Code_To_templates_Code(a.(*Code), b.(*templates.Code), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*templates.Code)(nil), (*Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_templates_Code_To_v1alpha1_Code(a.(*templates.Code), b.(*Code), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*ConstraintTemplate)(nil), (*templates.ConstraintTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_ConstraintTemplate_To_templates_ConstraintTemplate(a.(*ConstraintTemplate), b.(*templates.ConstraintTemplate), scope) }); err != nil { @@ -125,11 +135,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*templates.Target)(nil), (*Target)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_templates_Target_To_v1alpha1_Target(a.(*templates.Target), b.(*Target), scope) }); err != nil { @@ -140,6 +145,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*Validation)(nil), (*templates.Validation)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_Validation_To_templates_Validation(a.(*Validation), b.(*templates.Validation), scope) }); err != nil { @@ -238,6 +248,28 @@ func Convert_templates_CRDSpec_To_v1alpha1_CRDSpec(in *templates.CRDSpec, out *C return autoConvert_templates_CRDSpec_To_v1alpha1_CRDSpec(in, out, s) } +func autoConvert_v1alpha1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_v1alpha1_Code_To_templates_Code is an autogenerated conversion function. +func Convert_v1alpha1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + return autoConvert_v1alpha1_Code_To_templates_Code(in, out, s) +} + +func autoConvert_templates_Code_To_v1alpha1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_templates_Code_To_v1alpha1_Code is an autogenerated conversion function. +func Convert_templates_Code_To_v1alpha1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + return autoConvert_templates_Code_To_v1alpha1_Code(in, out, s) +} + func autoConvert_v1alpha1_ConstraintTemplate_To_templates_ConstraintTemplate(in *ConstraintTemplate, out *templates.ConstraintTemplate, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1alpha1_ConstraintTemplateSpec_To_templates_ConstraintTemplateSpec(&in.Spec, &out.Spec, s); err != nil { @@ -316,7 +348,17 @@ func autoConvert_v1alpha1_ConstraintTemplateSpec_To_templates_ConstraintTemplate if err := Convert_v1alpha1_CRD_To_templates_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]templates.Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]templates.Target, len(*in)) + for i := range *in { + if err := Convert_v1alpha1_Target_To_templates_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -329,7 +371,17 @@ func autoConvert_templates_ConstraintTemplateSpec_To_v1alpha1_ConstraintTemplate if err := Convert_templates_CRD_To_v1alpha1_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]Target, len(*in)) + for i := range *in { + if err := Convert_templates_Target_To_v1alpha1_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -410,18 +462,15 @@ func autoConvert_v1alpha1_Target_To_templates_Target(in *Target, out *templates. out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]templates.Code)(unsafe.Pointer(&in.Code)) return nil } -// Convert_v1alpha1_Target_To_templates_Target is an autogenerated conversion function. -func Convert_v1alpha1_Target_To_templates_Target(in *Target, out *templates.Target, s conversion.Scope) error { - return autoConvert_v1alpha1_Target_To_templates_Target(in, out, s) -} - func autoConvert_templates_Target_To_v1alpha1_Target(in *templates.Target, out *Target, s conversion.Scope) error { out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]Code)(unsafe.Pointer(&in.Code)) return nil } @@ -430,6 +479,12 @@ func Convert_templates_Target_To_v1alpha1_Target(in *templates.Target, out *Targ return autoConvert_templates_Target_To_v1alpha1_Target(in, out, s) } +func autoConvert_v1alpha1_Validation_To_templates_Validation(in *Validation, out *templates.Validation, s conversion.Scope) error { + // INFO: in.OpenAPIV3Schema opted out of conversion generation + out.LegacySchema = (*bool)(unsafe.Pointer(in.LegacySchema)) + return nil +} + func autoConvert_templates_Validation_To_v1alpha1_Validation(in *templates.Validation, out *Validation, s conversion.Scope) error { if in.OpenAPIV3Schema != nil { in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.deepcopy.go index 1ce321d28ef..6720c01f769 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1alpha1/zz_generated.deepcopy.go @@ -81,6 +81,25 @@ func (in *CRDSpec) DeepCopy() *CRDSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Code) DeepCopyInto(out *Code) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Code. +func (in *Code) DeepCopy() *Code { + if in == nil { + return nil + } + out := new(Code) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConstraintTemplate) DeepCopyInto(out *ConstraintTemplate) { *out = *in @@ -228,6 +247,13 @@ func (in *Target) DeepCopyInto(out *Target) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Code != nil { + in, out := &in.Code, &out.Code + *out = make([]Code, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/constrainttemplate_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/constrainttemplate_types.go index 51167178b96..8eda89973b4 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/constrainttemplate_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/constrainttemplate_types.go @@ -16,6 +16,7 @@ limitations under the License. package v1beta1 import ( + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -48,6 +49,7 @@ type Validation struct { // +kubebuilder:validation:Schemaless // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields + // +k8s:conversion-gen=false OpenAPIV3Schema *apiextensionsv1.JSONSchemaProps `json:"openAPIV3Schema,omitempty"` // +kubebuilder:default=true LegacySchema *bool `json:"legacySchema,omitempty"` // *bool allows for "unset" state which we need to apply appropriate defaults @@ -57,6 +59,23 @@ type Target struct { Target string `json:"target,omitempty"` Rego string `json:"rego,omitempty"` Libs []string `json:"libs,omitempty"` + // The source code options for the constraint template. "Rego" can only + // be specified in one place (either here or in the "rego" field) + // +listType=map + // +listMapKey=engine + Code []Code `json:"code,omitempty"` +} + +type Code struct { + // The engine used to evaluate the code. Example: "Rego". Required. + // +kubebuilder:validation:Required + Engine string `json:"engine"` + + // +kubebuilder:validation:Required + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // The source code for the template. Required. + Source *templates.Anything `json:"source"` } // CreateCRDError represents a single error caught during parsing, compiling, etc. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/conversion.go index 9bb69b0c74e..915782b83fd 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/conversion.go @@ -16,6 +16,9 @@ limitations under the License. package v1beta1 import ( + "unsafe" + + regoSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" coreTemplates "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/schema" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -61,3 +64,41 @@ func Convert_v1beta1_Validation_To_templates_Validation(in *Validation, out *cor return nil } + +func Convert_v1beta1_Target_To_templates_Target(in *Target, out *coreTemplates.Target, s conversion.Scope) error { // nolint:revive // Required exact function name. + out.Target = in.Target + out.Rego = in.Rego + out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + + out.Code = make([]coreTemplates.Code, len(in.Code)) + for i := range in.Code { + if err := Convert_v1beta1_Code_To_templates_Code(&(in.Code[i]), &(out.Code[i]), s); err != nil { + return err + } + } + + if in.Rego == "" { + return nil + } + + regoSource := ®oSchema.Source{} + regoSource.Rego = in.Rego + regoSource.Libs = append(regoSource.Libs, in.Libs...) + + injected := false + for i := range out.Code { + if out.Code[i].Engine == regoSchema.Name { + out.Code[i].Source.Value = regoSource.ToUnstructured() + injected = true + break + } + } + if !injected { + out.Code = append(out.Code, coreTemplates.Code{ + Engine: regoSchema.Name, + Source: &coreTemplates.Anything{Value: regoSource.ToUnstructured()}, + }) + } + + return nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.conversion.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.conversion.go index 2a46ec4b1e2..b992505278b 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.conversion.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.conversion.go @@ -65,6 +65,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*Code)(nil), (*templates.Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Code_To_templates_Code(a.(*Code), b.(*templates.Code), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*templates.Code)(nil), (*Code)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_templates_Code_To_v1beta1_Code(a.(*templates.Code), b.(*Code), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*ConstraintTemplate)(nil), (*templates.ConstraintTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_ConstraintTemplate_To_templates_ConstraintTemplate(a.(*ConstraintTemplate), b.(*templates.ConstraintTemplate), scope) }); err != nil { @@ -125,11 +135,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*templates.Target)(nil), (*Target)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_templates_Target_To_v1beta1_Target(a.(*templates.Target), b.(*Target), scope) }); err != nil { @@ -140,6 +145,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*Target)(nil), (*templates.Target)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Target_To_templates_Target(a.(*Target), b.(*templates.Target), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*Validation)(nil), (*templates.Validation)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_Validation_To_templates_Validation(a.(*Validation), b.(*templates.Validation), scope) }); err != nil { @@ -238,6 +248,28 @@ func Convert_templates_CRDSpec_To_v1beta1_CRDSpec(in *templates.CRDSpec, out *CR return autoConvert_templates_CRDSpec_To_v1beta1_CRDSpec(in, out, s) } +func autoConvert_v1beta1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_v1beta1_Code_To_templates_Code is an autogenerated conversion function. +func Convert_v1beta1_Code_To_templates_Code(in *Code, out *templates.Code, s conversion.Scope) error { + return autoConvert_v1beta1_Code_To_templates_Code(in, out, s) +} + +func autoConvert_templates_Code_To_v1beta1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + out.Engine = in.Engine + out.Source = (*templates.Anything)(unsafe.Pointer(in.Source)) + return nil +} + +// Convert_templates_Code_To_v1beta1_Code is an autogenerated conversion function. +func Convert_templates_Code_To_v1beta1_Code(in *templates.Code, out *Code, s conversion.Scope) error { + return autoConvert_templates_Code_To_v1beta1_Code(in, out, s) +} + func autoConvert_v1beta1_ConstraintTemplate_To_templates_ConstraintTemplate(in *ConstraintTemplate, out *templates.ConstraintTemplate, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta if err := Convert_v1beta1_ConstraintTemplateSpec_To_templates_ConstraintTemplateSpec(&in.Spec, &out.Spec, s); err != nil { @@ -316,7 +348,17 @@ func autoConvert_v1beta1_ConstraintTemplateSpec_To_templates_ConstraintTemplateS if err := Convert_v1beta1_CRD_To_templates_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]templates.Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]templates.Target, len(*in)) + for i := range *in { + if err := Convert_v1beta1_Target_To_templates_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -329,7 +371,17 @@ func autoConvert_templates_ConstraintTemplateSpec_To_v1beta1_ConstraintTemplateS if err := Convert_templates_CRD_To_v1beta1_CRD(&in.CRD, &out.CRD, s); err != nil { return err } - out.Targets = *(*[]Target)(unsafe.Pointer(&in.Targets)) + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]Target, len(*in)) + for i := range *in { + if err := Convert_templates_Target_To_v1beta1_Target(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Targets = nil + } return nil } @@ -410,18 +462,15 @@ func autoConvert_v1beta1_Target_To_templates_Target(in *Target, out *templates.T out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]templates.Code)(unsafe.Pointer(&in.Code)) return nil } -// Convert_v1beta1_Target_To_templates_Target is an autogenerated conversion function. -func Convert_v1beta1_Target_To_templates_Target(in *Target, out *templates.Target, s conversion.Scope) error { - return autoConvert_v1beta1_Target_To_templates_Target(in, out, s) -} - func autoConvert_templates_Target_To_v1beta1_Target(in *templates.Target, out *Target, s conversion.Scope) error { out.Target = in.Target out.Rego = in.Rego out.Libs = *(*[]string)(unsafe.Pointer(&in.Libs)) + out.Code = *(*[]Code)(unsafe.Pointer(&in.Code)) return nil } @@ -430,6 +479,12 @@ func Convert_templates_Target_To_v1beta1_Target(in *templates.Target, out *Targe return autoConvert_templates_Target_To_v1beta1_Target(in, out, s) } +func autoConvert_v1beta1_Validation_To_templates_Validation(in *Validation, out *templates.Validation, s conversion.Scope) error { + // INFO: in.OpenAPIV3Schema opted out of conversion generation + out.LegacySchema = (*bool)(unsafe.Pointer(in.LegacySchema)) + return nil +} + func autoConvert_templates_Validation_To_v1beta1_Validation(in *templates.Validation, out *Validation, s conversion.Scope) error { if in.OpenAPIV3Schema != nil { in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.deepcopy.go index 593de641923..27a564e25ca 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.deepcopy.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1/zz_generated.deepcopy.go @@ -81,6 +81,25 @@ func (in *CRDSpec) DeepCopy() *CRDSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Code) DeepCopyInto(out *Code) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Code. +func (in *Code) DeepCopy() *Code { + if in == nil { + return nil + } + out := new(Code) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConstraintTemplate) DeepCopyInto(out *ConstraintTemplate) { *out = *in @@ -228,6 +247,13 @@ func (in *Target) DeepCopyInto(out *Target) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Code != nil { + in, out := &in.Code, &out.Code + *out = make([]Code, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client.go index e0b9b3adf4a..5a2a1468c2c 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client.go @@ -11,9 +11,12 @@ import ( apiconstraints "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" "github.com/open-policy-agent/frameworks/constraint/pkg/client/crds" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" + regoSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" clienterrors "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/handler" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "github.com/open-policy-agent/frameworks/constraint/pkg/types" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -31,9 +34,22 @@ const statusField = "status" // allowed to continue running. Thus, this problem can only safely be handled // by the caller. type Client struct { - // driver contains the Rego runtime environments to run queries against. - // Does not require mutex locking as Driver is threadsafe. - driver drivers.Driver + // driver priority specifies the preference for which driver should + // be preferred if a template specifies multiple kinds of source + // code. It is determined by the order with which drivers are + // added to the client. + driverPriority map[string]int + + // ignoreNoReferentialDriverWarning toggles whether we warn the user + // when there is no registered driver that supports referential data when + // they call AddData() + ignoreNoReferentialDriverWarning bool + + // drivers contains the drivers for policy engines understood + // by the constraint framework client. + // Does not require mutex locking as Driver is threadsafe + // and the map should be created during bootstrapping. + drivers map[string]drivers.Driver // targets are the targets supported by this Client. // Assumed to be constant after initialization. targets map[string]handler.TargetHandler @@ -45,6 +61,26 @@ type Client struct { templates map[string]*templateClient } +// driverForTemplate returns the driver to be used for a template according +// to the driver priority in the client. An empty string means the constraint +// template does not contain a language the client has a driver for. +func (c *Client) driverForTemplate(template *templates.ConstraintTemplate) string { + if len(template.Spec.Targets) == 0 { + return "" + } + language := "" + for _, v := range template.Spec.Targets[0].Code { + priority, ok := c.driverPriority[v.Engine] + if !ok { + continue + } + if priority < c.driverPriority[language] || c.driverPriority[language] == 0 { + language = v.Engine + } + } + return language +} + // CreateCRD creates a CRD from template. func (c *Client) CreateCRD(ctx context.Context, templ *templates.ConstraintTemplate) (*apiextensions.CustomResourceDefinition, error) { if templ == nil { @@ -93,7 +129,9 @@ func (c *Client) AddTemplate(ctx context.Context, templ *templates.ConstraintTem } } - if cachedCpy != nil && cachedCpy.SemanticEqual(templ) { + // if there is more than one active driver for the template, there is some cleanup to do + // from a botched driver swap. + if cachedCpy != nil && cachedCpy.SemanticEqual(templ) && len(cached.activeDrivers) == 1 { resp.Handled[targetName] = true return resp, nil } @@ -135,29 +173,72 @@ func (c *Client) AddTemplate(ctx context.Context, templ *templates.ConstraintTem return resp, err } - if err := c.driver.AddTemplate(ctx, templ); err != nil { + newDriverN := c.driverForTemplate(templ) + + driver, ok := c.drivers[newDriverN] + if !ok { + return resp, fmt.Errorf("%w: available drivers: %v, wanted %q", clienterrors.ErrNoDriver, c.driverPriority, c.driverForTemplate(templ)) + } + + // TODO: because different targets may have different code sets, + // the driver should be told which targets to load code for. + // this is moot right now, since templates only have one target + if err := driver.AddTemplate(ctx, templ); err != nil { return resp, err } templateName := templ.GetName() - template := c.templates[templateName] + cacheEntry := c.templates[templateName] // We don't want to use the usual "if found/ok" idiom here - if the value // stored for templateName is nil, we need to update it to be non-nil to avoid // a panic. - if template == nil { - template = &templateClient{ - constraints: make(map[string]*constraintClient), + if cacheEntry == nil { + cacheEntry = newTemplateClient() + c.templates[templateName] = cacheEntry + } + + cacheEntry.activeDrivers[newDriverN] = true + + // For drivers that require a local cache of constraints, we ensure that + // cache is current if the active driver has changed. + if cachedCpy != nil { + oldDriverN := c.driverForTemplate(cachedCpy) + if oldDriverN != newDriverN { + cacheEntry.needsConstraintReplay = true } + } - c.templates[templateName] = template + if cacheEntry.needsConstraintReplay { + for _, constraintEntry := range cacheEntry.constraints { + cstr := constraintEntry.getConstraint() + if err := driver.AddConstraint(ctx, cstr); err != nil { + return resp, fmt.Errorf("%w: while replaying constraints", err) + } + } + cacheEntry.needsConstraintReplay = false } - // This state mutation needs to happen last so that the semantic equal check - // at the beginning does not incorrectly return true when updating did not - // succeed previously. - template.Update(templ, crd, target) + // This state mutation needs to happen after the new driver is fully ready + // to enforce the template + cacheEntry.Update(templ, crd, target) + + // Remove old drivers last so that templates can be enforced + // despite a botched update + for oldDriverN := range cacheEntry.activeDrivers { + if oldDriverN == newDriverN { + continue + } + oldDriver, ok := c.drivers[oldDriverN] + if !ok { + return resp, fmt.Errorf("%w: while changing drivers", clienterrors.ErrNoDriver) + } + if err := oldDriver.RemoveTemplate(ctx, cachedCpy); err != nil { + return resp, fmt.Errorf("%w: while changing drivers", err) + } + delete(cacheEntry.activeDrivers, oldDriverN) + } resp.Handled[targetName] = true return resp, nil @@ -189,22 +270,33 @@ func (c *Client) RemoveTemplate(ctx context.Context, templ *templates.Constraint c.mtx.Lock() defer c.mtx.Unlock() - err := c.driver.RemoveTemplate(ctx, templ) - if err != nil { - return resp, err - } - name := templ.GetName() - template, found := c.templates[name] - + cached, found := c.templates[name] if !found { return resp, nil } + template := cached.getTemplate() + + // remove the template from all active drivers + // to ensure cleanup in case of a botched update + for driverN := range cached.activeDrivers { + driver, ok := c.drivers[driverN] + if !ok { + return resp, fmt.Errorf("%w: could not clean up %q", clienterrors.ErrNoDriver, driverN) + } + + err := driver.RemoveTemplate(ctx, template) + if err != nil { + return resp, err + } + delete(cached.activeDrivers, driverN) + } + delete(c.templates, name) - for _, target := range template.targets { + for _, target := range cached.targets { resp.Handled[target.GetName()] = true } @@ -231,8 +323,8 @@ func (c *Client) GetTemplate(templ *templates.ConstraintTemplate) (*templates.Co return template.getTemplate(), nil } -// getTemplateEntry returns the template entry for a given constraint. -func (c *Client) getTemplateForKind(kind string) *templateClient { +// getTemplateClientForKind returns the template entry for a given constraint. +func (c *Client) getTemplateClientForKind(kind string) *templateClient { name := strings.ToLower(kind) return c.templates[name] @@ -253,25 +345,37 @@ func (c *Client) AddConstraint(ctx context.Context, constraint *unstructured.Uns } kind := constraint.GetKind() - template := c.getTemplateForKind(kind) - if template == nil { + cached := c.getTemplateClientForKind(kind) + if cached == nil { templateName := strings.ToLower(kind) return resp, templateNotFound(templateName) } - changed, err := template.AddConstraint(constraint) + template := cached.getTemplate() + + driver, ok := c.drivers[c.driverForTemplate(template)] + if !ok { + return resp, clienterrors.ErrNoDriver + } + + constraintWithDefaults, err := cached.ApplyDefaultParams(constraint) + if err != nil { + return resp, err + } + + changed, err := cached.AddConstraint(constraintWithDefaults) if err != nil { return resp, err } if changed { - err = c.driver.AddConstraint(ctx, constraint) + err = driver.AddConstraint(ctx, constraintWithDefaults) if err != nil { return resp, err } } - for _, target := range template.targets { + for _, target := range cached.targets { resp.Handled[target.GetName()] = true } @@ -291,25 +395,34 @@ func (c *Client) RemoveConstraint(ctx context.Context, constraint *unstructured. return resp, err } - err = c.driver.RemoveConstraint(ctx, constraint) - if err != nil { - return nil, err - } - kind := constraint.GetKind() - template := c.getTemplateForKind(kind) - if template == nil { + cached := c.getTemplateClientForKind(kind) + if cached == nil { // The Template has been deleted, so nothing to do and no reason to return // error. return resp, nil } - for _, target := range template.targets { + // Remove the constraint from all active drivers + // in case we are in the middle of a botched update + for driverN := range cached.activeDrivers { + driver, ok := c.drivers[driverN] + if !ok { + return resp, clienterrors.ErrNoDriver + } + + err = driver.RemoveConstraint(ctx, constraint) + if err != nil { + return nil, err + } + } + + for _, target := range cached.targets { resp.Handled[target.GetName()] = true } - template.RemoveConstraint(constraint.GetName()) + cached.RemoveConstraint(constraint.GetName()) return resp, nil } @@ -325,7 +438,7 @@ func (c *Client) GetConstraint(constraint *unstructured.Unstructured) (*unstruct defer c.mtx.RUnlock() kind := constraint.GetKind() - template := c.getTemplateForKind(kind) + template := c.getTemplateClientForKind(kind) if template == nil { templateName := strings.ToLower(kind) return nil, templateNotFound(templateName) @@ -359,7 +472,7 @@ func (c *Client) validateConstraint(constraint *unstructured.Unstructured) error } kind := constraint.GetKind() - template := c.getTemplateForKind(kind) + template := c.getTemplateClientForKind(kind) if template == nil { templateName := strings.ToLower(kind) return templateNotFound(templateName) @@ -431,14 +544,22 @@ func (c *Client) AddData(ctx context.Context, data interface{}) (*types.Response continue } - err = c.driver.AddData(ctx, name, key, processedDataCpy) - if err != nil { - errMap[name] = err + // To avoid maintaining duplicate caches, only Rego should get its own + // storage. We should work to remove the need for this special case + // by building a global storage object. Right now Rego needs its own + // cache to cache constraints. + if _, ok := c.drivers[regoSchema.Name]; ok { + err = c.drivers[regoSchema.Name].AddData(ctx, name, key, processedDataCpy) + if err != nil { + errMap[name] = err - if cache != nil { - cache.Remove(key) + if cache != nil { + cache.Remove(key) + } + continue } - continue + } else if !c.ignoreNoReferentialDriverWarning { + errMap[name] = ErrNoReferentialDriver } resp.Handled[name] = true @@ -468,10 +589,18 @@ func (c *Client) RemoveData(ctx context.Context, data interface{}) (*types.Respo continue } - err = c.driver.RemoveData(ctx, target, relPath) - if err != nil { - errMap[target] = err - continue + // To avoid maintaining duplicate caches, only Rego should get its own + // storage. We should work to remove the need for this special case + // by building a global storage object. Right now Rego needs its own + // cache to cache constraints. + if _, ok := c.drivers[regoSchema.Name]; ok { + err = c.drivers[regoSchema.Name].RemoveData(ctx, target, relPath) + if err != nil { + errMap[target] = err + continue + } + } else if !c.ignoreNoReferentialDriverWarning { + errMap[target] = ErrNoReferentialDriver } resp.Handled[target] = true @@ -547,7 +676,7 @@ func (c *Client) Review(ctx context.Context, obj interface{}, opts ...drivers.Qu for target, review := range reviews { constraints := constraintsByTarget[target] - resp, err := c.review(ctx, target, constraints, review, opts...) + resp, stats, err := c.review(ctx, target, constraints, review, opts...) if err != nil { errMap.Add(target, err) continue @@ -561,6 +690,18 @@ func (c *Client) Review(ctx context.Context, obj interface{}, opts ...drivers.Qu resp.Sort() responses.ByTarget[target] = resp + if stats != nil { + // add the target label to these stats for future collation. + targetLabel := &instrumentation.Label{Name: "target", Value: target} + for _, stat := range stats { + if stat.Labels == nil || len(stat.Labels) == 0 { + stat.Labels = []*instrumentation.Label{targetLabel} + } else { + stat.Labels = append(stat.Labels, targetLabel) + } + } + responses.StatsEntries = append(responses.StatsEntries, stats...) + } } if len(errMap) == 0 { @@ -570,30 +711,102 @@ func (c *Client) Review(ctx context.Context, obj interface{}, opts ...drivers.Qu return responses, &errMap } -func (c *Client) review(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...drivers.QueryOpt) (*types.Response, error) { +func (c *Client) review(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...drivers.QueryOpt) (*types.Response, []*instrumentation.StatsEntry, error) { var results []*types.Result + var stats []*instrumentation.StatsEntry var tracesBuilder strings.Builder + errs := &errors.ErrorMap{} - results, trace, err := c.driver.Query(ctx, target, constraints, review, opts...) - if err != nil { - return nil, err + driverToConstraints := map[string][]*unstructured.Unstructured{} + + for _, constraint := range constraints { + template, ok := c.templates[strings.ToLower(constraint.GetObjectKind().GroupVersionKind().Kind)] + if !ok { + return nil, nil, fmt.Errorf("%w: while loading driver for constraint %s", ErrMissingConstraintTemplate, constraint.GetName()) + } + driver := c.driverForTemplate(template.template) + if driver == "" { + return nil, nil, fmt.Errorf("%w: while loading driver for constraint %s", clienterrors.ErrNoDriver, constraint.GetName()) + } + driverToConstraints[driver] = append(driverToConstraints[driver], constraint) } - if trace != nil { - tracesBuilder.WriteString(*trace) - tracesBuilder.WriteString("\n\n") + for driverName, driver := range c.drivers { + if len(driverToConstraints[driverName]) == 0 { + continue + } + qr, err := driver.Query(ctx, target, driverToConstraints[driverName], review, opts...) + if err != nil { + errs.Add(driverName, err) + continue + } + if qr != nil { + results = append(results, qr.Results...) + + stats = append(stats, qr.StatsEntries...) + + if qr.Trace != nil { + tracesBuilder.WriteString(fmt.Sprintf("DRIVER %s:\n\n", driverName)) + tracesBuilder.WriteString(*qr.Trace) + tracesBuilder.WriteString("\n\n") + } + } + } + + traceStr := tracesBuilder.String() + var trace *string + if len(traceStr) != 0 { + trace = &traceStr + } + + // golang idiom is nil on no errors, so we should + // only return errs if it is non-empty, otherwise + // we get a non-nil interface (even if errs is nil, since + // the interface would still hold type info). + var errRet error + if len(*errs) > 0 { + errRet = errs } return &types.Response{ Trace: trace, Target: target, Results: results, - }, nil + }, stats, errRet } // Dump dumps the state of OPA to aid in debugging. func (c *Client) Dump(ctx context.Context) (string, error) { - return c.driver.Dump(ctx) + var dumpBuilder strings.Builder + for driverName, driver := range c.drivers { + dump, err := driver.Dump(ctx) + if err != nil { + return "", err + } + dumpBuilder.WriteString(fmt.Sprintf("DRIVER: %s:\n\n", driverName)) + dumpBuilder.WriteString(dump) + dumpBuilder.WriteString("\n\n") + } + return dumpBuilder.String(), nil +} + +func (c *Client) GetDescriptionForStat(source instrumentation.Source, statName string) string { + if source.Type != instrumentation.EngineSourceType { + // only handle engine source for now + return instrumentation.UnknownDescription + } + + driver, ok := c.drivers[source.Value] + if !ok { + return instrumentation.UnknownDescription + } + + desc, err := driver.GetDescriptionForStat(statName) + if err != nil { + return instrumentation.UnknownDescription + } + + return desc } // knownTargets returns a sorted list of known target names. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client_opts.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client_opts.go index e1a16d53433..0a70fb9b59a 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client_opts.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/client_opts.go @@ -54,7 +54,21 @@ func validateTargetNames(ts []handler.TargetHandler) []string { // Driver defines the Rego execution environment. func Driver(d drivers.Driver) Opt { return func(client *Client) error { - client.driver = d + if d.Name() == "" { + return ErrNoDriverName + } + if _, ok := client.drivers[d.Name()]; ok { + return fmt.Errorf("%w: %s", ErrDuplicateDriver, d.Name()) + } + client.drivers[d.Name()] = d + client.driverPriority[d.Name()] = len(client.drivers) + return nil + } +} + +func IgnoreNoReferentialDriverWarning(ignore bool) Opt { + return func(client *Client) error { + client.ignoreNoReferentialDriverWarning = ignore return nil } } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go index 9a486fdf8c7..30d001accf2 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/schema.go @@ -36,7 +36,7 @@ func CreateSchema(templ *templates.ConstraintTemplate, target MatchSchemaProvide Properties: props, }, "status": { - XPreserveUnknownFields: pointer.BoolPtr(true), + XPreserveUnknownFields: pointer.Bool(true), }, }, } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/validate.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/validate.go index da120eb1fe6..1f6d998dd73 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/validate.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/crds/validate.go @@ -12,6 +12,8 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiextensionsvalidation "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" + structuralpruning "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning" "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" apivalidation "k8s.io/apimachinery/pkg/util/validation" @@ -84,5 +86,16 @@ func ValidateCR(cr *unstructured.Unstructured, crd *apiextensions.CustomResource return fmt.Errorf("%w: %v", constraints.ErrSchema, err.ToAggregate()) } + // validate that there are no unknown fields in the CR + // NewStructural assumes the schema is valid + structural, err := schema.NewStructural(crd.Spec.Validation.OpenAPIV3Schema) + if err != nil { + return fmt.Errorf("%w: %v", constraints.ErrInvalidConstraint, err) + } + unknownFields := structuralpruning.PruneWithOptions(cr.DeepCopy().Object, structural, true, schema.UnknownFieldPathOptions{TrackUnknownFieldPaths: true}) + if len(unknownFields) > 0 { + return fmt.Errorf("%w: %v", constraints.ErrInvalidConstraint, fmt.Sprintf("unknown fields: %v", unknownFields)) + } + return nil } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/interface.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/interface.go index 1a1754d1faa..090c732a53c 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/interface.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/interface.go @@ -4,13 +4,16 @@ import ( "context" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - "github.com/open-policy-agent/frameworks/constraint/pkg/types" "github.com/open-policy-agent/opa/storage" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) // A Driver implements Rego query execution of Templates and Constraints. type Driver interface { + // Name returns the name of the driver, used to uniquely identify a driver + // and in errors returned to the user. + Name() string + // AddTemplate compiles a Template's code to be specified by // Constraints and referenced in Query. Replaces the existing Template if it // already exists. @@ -29,22 +32,26 @@ type Driver interface { RemoveConstraint(ctx context.Context, constraint *unstructured.Unstructured) error // AddData caches data to be used for referential Constraints. Replaces data - // if it already exists at the specified path. + // if it already exists at the specified path. This is a deprecated method that + // will only be called for the "Rego" driver. AddData(ctx context.Context, target string, path storage.Path, data interface{}) error // RemoveData removes cached data, so the data at the specified path can no - // longer be used in referential Constraints. + // longer be used in referential Constraints. This is a deprecated method that + // will only be called for the "Rego" driver. RemoveData(ctx context.Context, target string, path storage.Path) error // Query runs the passed target's Constraints against review. - // - // Returns results for each violated Constraint. - // Returns a trace if specified in query options or enabled at Driver creation. + // Returns a QueryResponse type. // Returns an error if there was a problem executing the Query. - Query(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...QueryOpt) ([]*types.Result, *string, error) + Query(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...QueryOpt) (*QueryResponse, error) // Dump outputs the entire state of compiled Templates, added Constraints, and // cached data used for referential Constraints. Dump(ctx context.Context) (string, error) + + // GetDescriptionForStat returns the description for a given stat name + // or errors out for an unknown stat. + GetDescriptionForStat(statName string) (string, error) } // ConstraintKey uniquely identifies a Constraint. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/args.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/args.go new file mode 100644 index 00000000000..c63efe85289 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/args.go @@ -0,0 +1,13 @@ +package k8scel + +type Arg func(*Driver) error + +// GatherStats starts collecting various stats around the +// underlying engine's calls. +func GatherStats() Arg { + return func(driver *Driver) error { + driver.gatherStats = true + + return nil + } +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/driver.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/driver.go new file mode 100644 index 00000000000..6cd6a670aa4 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/driver.go @@ -0,0 +1,442 @@ +package k8scel + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + "sync" + "time" + + rawCEL "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + celInterpreter "github.com/google/cel-go/interpreter" + apiconstraints "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" + pSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme" + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + "github.com/open-policy-agent/frameworks/constraint/pkg/types" + "github.com/open-policy-agent/opa/storage" + admissionv1 "k8s.io/api/admission/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + celAPI "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authentication/user" +) + +// NOTE: This is a PROTOTYPE driver. Do not use this for any critical work +// and be aware that its behavior may change at any time. + +// Friction log: +// there is no way to re-use the matcher interface here, as it requires an informer... not sure we need to use +// the matchers, as match Criteria should take care of things. + +// "Expression" is a bit confusing, since it doesn't tell me whether "true" implies violation or not: "requirement", "mustSatisfy"? +// +// +// From the Validation help text: +// Equality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. +// Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type: +// Is this type metadata available shift-left? Likely not. Can the expectation be built into the operators? +// +// Other friction points are commented with the keyword FRICTION. + +const ( + variablesKey = ctxKey("variables") + + runTimeNS = "runTimeNS" + runTimeNSDescription = "the number of nanoseconds it took to evaluate the constraint" +) + +type ctxKey string + +var _ drivers.Driver = &Driver{} + +type Driver struct { + mux sync.RWMutex + validators map[string]validatingadmissionpolicy.Validator + gatherStats bool +} + +func (d *Driver) Name() string { + return pSchema.Name +} + +func (d *Driver) AddTemplate(_ context.Context, ct *templates.ConstraintTemplate) error { + if len(ct.Spec.Targets) != 1 { + return errors.New("wrong number of targets defined, only 1 target allowed") + } + + var source *pSchema.Source + for _, code := range ct.Spec.Targets[0].Code { + if code.Engine != pSchema.Name { + continue + } + var err error + source, err = pSchema.GetSource(code) + if err != nil { + return err + } + break + } + if source == nil { + return errors.New("K8sNativeValidation code not defined") + } + + // FRICTION: Note that compilation errors are possible, but we cannot introspect to see whether any + // occurred + celVars := cel.OptionalVariableDeclarations{} + + failurePolicy, err := source.GetFailurePolicy() + if err != nil { + return err + } + + matchAccessors, err := source.GetMatchConditions() + if err != nil { + return err + } + matcher := matchconditions.NewMatcher(compileWrappedFilter(matchAccessors, celVars, celAPI.PerCallLimit), nil, failurePolicy, "validatingadmissionpolicy", ct.GetName()) + + validationAccessors, err := source.GetValidations() + if err != nil { + return err + } + + messageAccessors, err := source.GetMessageExpressions() + if err != nil { + return err + } + + validator := validatingadmissionpolicy.NewValidator( + compileWrappedFilter(validationAccessors, celVars, celAPI.PerCallLimit), + matcher, + compileWrappedFilter(nil, celVars, celAPI.PerCallLimit), + compileWrappedFilter(messageAccessors, celVars, celAPI.PerCallLimit), + failurePolicy, + nil, + ) + + d.mux.Lock() + defer d.mux.Unlock() + d.validators[ct.GetName()] = validator + return nil +} + +func (d *Driver) RemoveTemplate(_ context.Context, ct *templates.ConstraintTemplate) error { + d.mux.Lock() + defer d.mux.Unlock() + delete(d.validators, ct.GetName()) + return nil +} + +func (d *Driver) AddConstraint(_ context.Context, _ *unstructured.Unstructured) error { + return nil +} + +func (d *Driver) RemoveConstraint(_ context.Context, _ *unstructured.Unstructured) error { + return nil +} + +func (d *Driver) AddData(_ context.Context, _ string, _ storage.Path, _ interface{}) error { + return nil +} + +func (d *Driver) RemoveData(_ context.Context, _ string, _ storage.Path) error { + return nil +} + +func (d *Driver) Query(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...drivers.QueryOpt) (*drivers.QueryResponse, error) { + cfg := &drivers.QueryCfg{} + for _, opt := range opts { + opt(cfg) + } + + d.mux.RLock() + defer d.mux.RUnlock() + + var statsEntries []*instrumentation.StatsEntry + + arGetter, ok := review.(ARGetter) + if !ok { + return nil, errors.New("cannot convert review to ARGetter") + } + aRequest := arGetter.GetAdmissionRequest() + request, err := NewWrapper(aRequest) + if err != nil { + return nil, err + } + + results := []*types.Result{} + + for _, constraint := range constraints { + evalStartTime := time.Now() + // FRICTION/design question: should parameters be created as a "mock" object so that users don't have to type `params.spec.parameters`? How do we prevent visibility into other, + // non-parameter fields, such as `spec.match`? Does it matter? Note that creating a special "parameters" object means that we'd need to copy the constraint contents to + // a special "parameters" object for on-server enforcement with a clean value for "params", which is non-ideal. Could we provide the field of the parameters object and limit scoping to that? + // Then how would we implement custom matchers? Maybe adding variable assignments to the Policy Definition is a better idea? That would at least allow for a convenience handle, even if + // it doesn't scope visibility. + + // template name is the lowercase of its kind + validator := d.validators[strings.ToLower(constraint.GetKind())] + if validator == nil { + return nil, fmt.Errorf("unknown constraint template validator: %s", constraint.GetKind()) + } + versionedAttr := &admission.VersionedAttributes{ + Attributes: request, + VersionedKind: request.GetKind(), + VersionedOldObject: request.GetOldObject(), + VersionedObject: request.GetObject(), + } + parameters, _, err := unstructured.NestedMap(constraint.Object, "spec", "parameters") + if err != nil { + return nil, err + } + ctx := context.WithValue(ctx, variablesKey, map[string]interface{}{"params": parameters}) + response := validator.Validate(ctx, versionedAttr, constraint, celAPI.PerCallLimit) + + enforcementAction, found, err := unstructured.NestedString(constraint.Object, "spec", "enforcementAction") + if err != nil { + return nil, err + } + if !found { + enforcementAction = apiconstraints.EnforcementActionDeny + } + for _, decision := range response.Decisions { + if decision.Action == validatingadmissionpolicy.ActionDeny { + results = append(results, &types.Result{ + Target: target, + Msg: decision.Message, + Constraint: constraint, + EnforcementAction: enforcementAction, + }) + } + } + evalElapsedTime := time.Since(evalStartTime) + if d.gatherStats || (cfg != nil && cfg.StatsEnabled) { + statsEntries = append(statsEntries, + &instrumentation.StatsEntry{ + Scope: instrumentation.ConstraintScope, + StatsFor: fmt.Sprintf("%s/%s", constraint.GetKind(), constraint.GetName()), + Stats: []*instrumentation.Stat{ + { + Name: runTimeNS, + Value: uint64(evalElapsedTime.Nanoseconds()), + Source: instrumentation.Source{ + Type: instrumentation.EngineSourceType, + Value: pSchema.Name, + }, + }, + }, + }) + } + } + return &drivers.QueryResponse{Results: results, StatsEntries: statsEntries}, nil +} + +func (d *Driver) Dump(_ context.Context) (string, error) { + return "", nil +} + +func (d *Driver) GetDescriptionForStat(statName string) (string, error) { + switch statName { + case runTimeNS: + return runTimeNSDescription, nil + default: + return "", fmt.Errorf("unknown stat name for K8sNativeValidation: %s", statName) + } +} + +type ARGetter interface { + GetAdmissionRequest() *admissionv1.AdmissionRequest +} + +// FRICTION this wrapper class is excessive. Validator code should define an interface that only requires the methods it needs. +type RequestWrapper struct { + ar *admissionv1.AdmissionRequest + object runtime.Object + oldObject runtime.Object + operationOptions runtime.Object +} + +func NewWrapper(req *admissionv1.AdmissionRequest) (*RequestWrapper, error) { + var object runtime.Object + if len(req.Object.Raw) != 0 { + object = &unstructured.Unstructured{} + if err := json.Unmarshal(req.Object.Raw, object); err != nil { + return nil, fmt.Errorf("%w: could not unmarshal object", err) + } + } + + var oldObject runtime.Object + if len(req.OldObject.Raw) != 0 { + oldObject = &unstructured.Unstructured{} + if err := json.Unmarshal(req.OldObject.Raw, oldObject); err != nil { + return nil, fmt.Errorf("%w: could not unmarshal old object", err) + } + } + + // this may be unnecessary, since GetOptions() may not be used by downstream + // code, but is better than doing this lazily and needing to panic if GetOptions() + // fails. + var options runtime.Object + if len(req.Options.Raw) != 0 { + options = &unstructured.Unstructured{} + if err := json.Unmarshal(req.Options.Raw, options); err != nil { + return nil, fmt.Errorf("%w: could not unmarshal options", err) + } + } + return &RequestWrapper{ + ar: req, + object: object, + oldObject: oldObject, + operationOptions: options, + }, nil +} + +func (w *RequestWrapper) GetName() string { + return w.ar.Name +} + +func (w *RequestWrapper) GetNamespace() string { + return w.ar.Namespace +} + +func (w *RequestWrapper) GetResource() schema.GroupVersionResource { + return schema.GroupVersionResource{ + Group: w.ar.Resource.Group, + Version: w.ar.Resource.Version, + Resource: w.ar.Resource.Resource, + } +} + +func (w *RequestWrapper) GetSubresource() string { + return w.ar.SubResource +} + +var opMap = map[admissionv1.Operation]admission.Operation{ + admissionv1.Create: admission.Create, + admissionv1.Update: admission.Update, + admissionv1.Delete: admission.Delete, + admissionv1.Connect: admission.Connect, +} + +func (w *RequestWrapper) GetOperation() admission.Operation { + return opMap[w.ar.Operation] +} + +func (w *RequestWrapper) GetOperationOptions() runtime.Object { + return w.operationOptions +} + +func (w *RequestWrapper) IsDryRun() bool { + if w.ar.DryRun == nil { + return false + } + return *w.ar.DryRun +} + +func (w *RequestWrapper) GetObject() runtime.Object { + return w.object +} + +func (w *RequestWrapper) GetOldObject() runtime.Object { + return w.oldObject +} + +func (w *RequestWrapper) GetKind() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: w.ar.Kind.Group, + Version: w.ar.Kind.Version, + Kind: w.ar.Kind.Kind, + } +} + +func (w *RequestWrapper) GetUserInfo() user.Info { + extra := map[string][]string{} + for k := range w.ar.UserInfo.Extra { + vals := make([]string, len(w.ar.UserInfo.Extra[k])) + copy(vals, w.ar.UserInfo.Extra[k]) + extra[k] = vals + } + + return &user.DefaultInfo{ + Name: w.ar.UserInfo.Username, + UID: w.ar.UserInfo.UID, + Groups: w.ar.UserInfo.Groups, + Extra: extra, + } +} + +func (w *RequestWrapper) AddAnnotation(_, _ string) error { + return errors.New("AddAnnotation not implemented") +} + +func (w *RequestWrapper) AddAnnotationWithLevel(_, _ string, _ auditinternal.Level) error { + return errors.New("AddAnnotationWithLevel not implemented") +} + +func (w *RequestWrapper) GetReinvocationContext() admission.ReinvocationContext { + return nil +} + +// temporary code that can go away after `variables` functionality is included (comes with k8s 1.28). + +var _ rawCEL.Program = &wrappedProgram{} + +// wrapProgram injects the ability to extract the value of the CEL environment variable `variables` from a golang context. +type wrappedProgram struct { + rawCEL.Program +} + +func (w *wrappedProgram) ContextEval(ctx context.Context, vars interface{}) (ref.Val, *rawCEL.EvalDetails, error) { + activation, ok := vars.(celInterpreter.Activation) + if !ok { + return nil, nil, errors.New("not an activation") + } + variables := ctx.Value(variablesKey) + if variables == nil { + return nil, nil, errors.New("No variables were provided to the CEL invocation") + } + mergedActivation := celInterpreter.NewHierarchicalActivation(activation, &varsActivation{vars: variables}) + return w.Program.ContextEval(ctx, mergedActivation) +} + +var _ celInterpreter.Activation = &varsActivation{} + +type varsActivation struct { + vars interface{} +} + +func (a *varsActivation) ResolveName(name string) (interface{}, bool) { + if name == temporarydeleteme.VariablesName { + return a.vars, true + } + return nil, false +} + +func (a *varsActivation) Parent() celInterpreter.Activation { + return nil +} + +func compileWrappedFilter(expressionAccessors []cel.ExpressionAccessor, options cel.OptionalVariableDeclarations, perCallLimit uint64) cel.Filter { + compilationResults := make([]cel.CompilationResult, len(expressionAccessors)) + for i, expressionAccessor := range expressionAccessors { + if expressionAccessor == nil { + continue + } + result := temporarydeleteme.CompileCELExpression(expressionAccessor, options, perCallLimit) + result.Program = &wrappedProgram{Program: result.Program} + compilationResults[i] = result + } + return cel.NewFilter(compilationResults) +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/new.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/new.go new file mode 100644 index 00000000000..72ff24687ae --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/new.go @@ -0,0 +1,17 @@ +package k8scel + +import ( + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" +) + +func New(args ...Arg) (*Driver, error) { + driver := &Driver{ + validators: map[string]validatingadmissionpolicy.Validator{}, + } + for _, arg := range args { + if err := arg(driver); err != nil { + return nil, err + } + } + return driver, nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go new file mode 100644 index 00000000000..62cb9b7cd89 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go @@ -0,0 +1,158 @@ +package schema + +import ( + "errors" + "fmt" + "strings" + + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + admissionv1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" +) + +const ( + // Name is the name of the driver. + Name = "K8sNativeValidation" + ReservedPrefix = "g8r-" +) + +var ( + ErrBadType = errors.New("Could not recognize the type") + ErrMissingField = errors.New("K8sNativeValidation source missing required field") +) + +type Validation struct { + // A CEL expression. Maps to ValidationAdmissionPolicy's spec.validations.expression + Expression string + Message string + MessageExpression string +} + +type MatchCondition struct { + Name string `json:"name"` + + Expression string `json:"expression"` +} + +type Source struct { + // Validations maps to ValidatingAdmissionPolicy's spec.validations. + Validations []Validation `json:"validations,omitempty"` + + // FailurePolicy maps to ValidatingAdmissionPolicy's spec.failurePolicy + FailurePolicy *string `json:"failurePolicy,omitempty"` + + // MatchConditions maps to ValidatingAdmissionPolicy's spec.matchConditions + MatchConditions []MatchCondition `json:"matchCondition,omitempty"` +} + +func (in *Source) GetMatchConditions() ([]cel.ExpressionAccessor, error) { + for _, condition := range in.MatchConditions { + if strings.HasPrefix(condition.Name, ReservedPrefix) { + return nil, fmt.Errorf("%s is not a valid match condition; cannot have %q as a prefix", condition.Name, ReservedPrefix) + } + } + + matchConditions := make([]cel.ExpressionAccessor, len(in.MatchConditions)) + for i, mc := range in.MatchConditions { + matchConditions[i] = &matchconditions.MatchCondition{ + Name: mc.Name, + Expression: mc.Expression, + } + } + return matchConditions, nil +} + +func (in *Source) GetValidations() ([]cel.ExpressionAccessor, error) { + validations := make([]cel.ExpressionAccessor, len(in.Validations)) + for i, validation := range in.Validations { + celValidation := validatingadmissionpolicy.ValidationCondition{ + Expression: validation.Expression, + Message: validation.Message, + } + validations[i] = &celValidation + } + return validations, nil +} + +func (in *Source) GetMessageExpressions() ([]cel.ExpressionAccessor, error) { + messageExpressions := make([]cel.ExpressionAccessor, len(in.Validations)) + for i, validation := range in.Validations { + if validation.MessageExpression != "" { + condition := validatingadmissionpolicy.MessageExpressionCondition{ + MessageExpression: validation.MessageExpression, + } + messageExpressions[i] = &condition + } + } + return messageExpressions, nil +} + +func (in *Source) GetFailurePolicy() (*admissionv1.FailurePolicyType, error) { + if in.FailurePolicy == nil { + return nil, nil + } + + var out admissionv1.FailurePolicyType + + switch *in.FailurePolicy { + case string(admissionv1.Fail): + out = admissionv1.Fail + case string(admissionv1.Ignore): + out = admissionv1.Ignore + default: + return nil, fmt.Errorf("unrecognized failure policy: %s", *in.FailurePolicy) + } + + return &out, nil +} + +func (in *Source) Validate() error { + if _, err := in.GetMatchConditions(); err != nil { + return err + } + if _, err := in.GetFailurePolicy(); err != nil { + return err + } + return nil +} + +// ToUnstructured() is a convenience method for converting to unstructured. +// Intended for testing. It will panic on error. TODO: rename to MustToUnstructured()? +func (in *Source) ToUnstructured() map[string]interface{} { + if in == nil { + return nil + } + + out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(in) + if err != nil { + panic(fmt.Errorf("cannot cast as unstructured: %w", err)) + } + + return out +} + +// TODO: things to validate: +// * once variables can be defined, disallow `params` as a variable name + +func GetSource(code templates.Code) (*Source, error) { + rawCode := code.Source + v, ok := rawCode.Value.(map[string]interface{}) + if !ok { + return nil, ErrBadType + } + + out := &Source{} + + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(v, out); err != nil { + return nil, err + } + + if err := out.Validate(); err != nil { + return nil, err + } + + return out, nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/README.md b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/README.md new file mode 100644 index 00000000000..e4de2db8ed8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/README.md @@ -0,0 +1,7 @@ +This file holds a fork of the Kubernetes CEL compiler code. + +It is needed because there is no way to add arbitrary new CEL environment variables +the way the K8s CEL library is structured in 1.27. Because `variables` did not exist in +k8s 1.27, this means we would be unable to use that feature without this fork. + +Maintaining a fork will be unnecessary as of K8s v1.28. \ No newline at end of file diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/compile.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/compile.go new file mode 100644 index 00000000000..08dd0eddebf --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme/compile.go @@ -0,0 +1,285 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// forked from k8s.io/apiserver/pkg/admission/plugin/cel/compile.go @ Kubernetes version 1.27.2 + +//nolint:all do not lint K8s code +package temporarydeleteme + +import ( + "fmt" + "sync" + + celconfig "k8s.io/apiserver/pkg/apis/cel" + + "github.com/google/cel-go/cel" + + originalCEL "k8s.io/apiserver/pkg/admission/plugin/cel" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/library" +) + +const ( + ObjectVarName = "object" + OldObjectVarName = "oldObject" + ParamsVarName = "params" + RequestVarName = "request" + AuthorizerVarName = "authorizer" + RequestResourceAuthorizerVarName = "authorizer.requestResource" + // BEGIN forked code. + VariablesName = "variables" + // END forked code. +) + +var ( + initEnvsOnce sync.Once + initEnvs envs + initEnvsErr error +) + +func getEnvs() (envs, error) { + initEnvsOnce.Do(func() { + requiredVarsEnv, err := buildRequiredVarsEnv() + if err != nil { + initEnvsErr = err + return + } + + initEnvs, err = buildWithOptionalVarsEnvs(requiredVarsEnv) + if err != nil { + initEnvsErr = err + return + } + }) + return initEnvs, initEnvsErr +} + +// This is a similar code as in k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go +// If any changes are made here, consider to make the same changes there as well. +func buildBaseEnv() (*cel.Env, error) { + var opts []cel.EnvOption + opts = append(opts, cel.HomogeneousAggregateLiterals()) + // Validate function declarations once during base env initialization, + // so they don't need to be evaluated each time a CEL rule is compiled. + // This is a relatively expensive operation. + opts = append(opts, cel.EagerlyValidateDeclarations(true), cel.DefaultUTCTimeZone(true)) + opts = append(opts, library.ExtensionLibs...) + + return cel.NewEnv(opts...) +} + +func buildRequiredVarsEnv() (*cel.Env, error) { + baseEnv, err := buildBaseEnv() + if err != nil { + return nil, err + } + var propDecls []cel.EnvOption + reg := apiservercel.NewRegistry(baseEnv) + + requestType := BuildRequestType() + rt, err := apiservercel.NewRuleTypes(requestType.TypeName(), requestType, reg) + if err != nil { + return nil, err + } + if rt == nil { + return nil, nil + } + opts, err := rt.EnvOptions(baseEnv.TypeProvider()) + if err != nil { + return nil, err + } + propDecls = append(propDecls, cel.Variable(ObjectVarName, cel.DynType)) + propDecls = append(propDecls, cel.Variable(OldObjectVarName, cel.DynType)) + propDecls = append(propDecls, cel.Variable(RequestVarName, requestType.CelType())) + // BEGIN forked code. + propDecls = append(propDecls, cel.Variable(VariablesName, cel.DynType)) + // END forked code. + + opts = append(opts, propDecls...) + env, err := baseEnv.Extend(opts...) + if err != nil { + return nil, err + } + return env, nil +} + +type envs map[originalCEL.OptionalVariableDeclarations]*cel.Env + +func buildEnvWithVars(baseVarsEnv *cel.Env, options originalCEL.OptionalVariableDeclarations) (*cel.Env, error) { + var opts []cel.EnvOption + if options.HasParams { + opts = append(opts, cel.Variable(ParamsVarName, cel.DynType)) + } + if options.HasAuthorizer { + opts = append(opts, cel.Variable(AuthorizerVarName, library.AuthorizerType)) + opts = append(opts, cel.Variable(RequestResourceAuthorizerVarName, library.ResourceCheckType)) + } + return baseVarsEnv.Extend(opts...) +} + +func buildWithOptionalVarsEnvs(requiredVarsEnv *cel.Env) (envs, error) { + envs := make(envs, 4) // since the number of variable combinations is small, pre-build a environment for each + for _, hasParams := range []bool{false, true} { + for _, hasAuthorizer := range []bool{false, true} { + opts := originalCEL.OptionalVariableDeclarations{HasParams: hasParams, HasAuthorizer: hasAuthorizer} + env, err := buildEnvWithVars(requiredVarsEnv, opts) + if err != nil { + return nil, err + } + envs[opts] = env + } + } + return envs, nil +} + +// BuildRequestType generates a DeclType for AdmissionRequest. This may be replaced with a utility that +// converts the native type definition to apiservercel.DeclType once such a utility becomes available. +// The 'uid' field is omitted since it is not needed for in-process admission review. +// The 'object' and 'oldObject' fields are omitted since they are exposed as root level CEL variables. +func BuildRequestType() *apiservercel.DeclType { + field := func(name string, declType *apiservercel.DeclType, required bool) *apiservercel.DeclField { + return apiservercel.NewDeclField(name, declType, required, nil, nil) + } + fields := func(fields ...*apiservercel.DeclField) map[string]*apiservercel.DeclField { + result := make(map[string]*apiservercel.DeclField, len(fields)) + for _, f := range fields { + result[f.Name] = f + } + return result + } + gvkType := apiservercel.NewObjectType("kubernetes.GroupVersionKind", fields( + field("group", apiservercel.StringType, true), + field("version", apiservercel.StringType, true), + field("kind", apiservercel.StringType, true), + )) + gvrType := apiservercel.NewObjectType("kubernetes.GroupVersionResource", fields( + field("group", apiservercel.StringType, true), + field("version", apiservercel.StringType, true), + field("resource", apiservercel.StringType, true), + )) + userInfoType := apiservercel.NewObjectType("kubernetes.UserInfo", fields( + field("username", apiservercel.StringType, false), + field("uid", apiservercel.StringType, false), + field("groups", apiservercel.NewListType(apiservercel.StringType, -1), false), + field("extra", apiservercel.NewMapType(apiservercel.StringType, apiservercel.NewListType(apiservercel.StringType, -1), -1), false), + )) + return apiservercel.NewObjectType("kubernetes.AdmissionRequest", fields( + field("kind", gvkType, true), + field("resource", gvrType, true), + field("subResource", apiservercel.StringType, false), + field("requestKind", gvkType, true), + field("requestResource", gvrType, true), + field("requestSubResource", apiservercel.StringType, false), + field("name", apiservercel.StringType, true), + field("namespace", apiservercel.StringType, false), + field("operation", apiservercel.StringType, true), + field("userInfo", userInfoType, true), + field("dryRun", apiservercel.BoolType, false), + field("options", apiservercel.DynType, false), + )) +} + +// CompileCELExpression returns a compiled CEL expression. +// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func CompileCELExpression(expressionAccessor originalCEL.ExpressionAccessor, optionalVars originalCEL.OptionalVariableDeclarations, perCallLimit uint64) originalCEL.CompilationResult { + var env *cel.Env + envs, err := getEnvs() + if err != nil { + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInternal, + Detail: "compiler initialization failed: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + env, ok := envs[optionalVars] + if !ok { + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: fmt.Sprintf("compiler initialization failed: failed to load environment for %v", optionalVars), + }, + ExpressionAccessor: expressionAccessor, + } + } + + ast, issues := env.Compile(expressionAccessor.GetExpression()) + if issues != nil { + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: "compilation failed: " + issues.String(), + }, + ExpressionAccessor: expressionAccessor, + } + } + found := false + returnTypes := expressionAccessor.ReturnTypes() + for _, returnType := range returnTypes { + if ast.OutputType() == returnType { + found = true + break + } + } + if !found { + var reason string + if len(returnTypes) == 1 { + reason = fmt.Sprintf("must evaluate to %v", returnTypes[0].String()) + } else { + reason = fmt.Sprintf("must evaluate to one of %v", returnTypes) + } + + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: reason, + }, + ExpressionAccessor: expressionAccessor, + } + } + + _, err = cel.AstToCheckedExpr(ast) + if err != nil { + // should be impossible since env.Compile returned no issues + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInternal, + Detail: "unexpected compilation error: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + prog, err := env.Program(ast, + cel.EvalOptions(cel.OptOptimize, cel.OptTrackCost), + cel.OptimizeRegex(library.ExtensionLibRegexOptimizations...), + cel.InterruptCheckFrequency(celconfig.CheckFrequency), + cel.CostLimit(perCallLimit), + ) + if err != nil { + return originalCEL.CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: "program instantiation failed: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + return originalCEL.CompilationResult{ + Program: prog, + ExpressionAccessor: expressionAccessor, + } +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/args.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/args.go deleted file mode 100644 index 8a4d8794e58..00000000000 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/args.go +++ /dev/null @@ -1,160 +0,0 @@ -package local - -import ( - "fmt" - - "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/topdown/print" - opatypes "github.com/open-policy-agent/opa/types" - "sigs.k8s.io/controller-runtime/pkg/certwatcher" -) - -type Arg func(*Driver) error - -func Defaults() Arg { - return func(d *Driver) error { - if d.storage.storage == nil { - d.storage.storage = make(map[string]storage.Store) - } - - if d.compilers.capabilities == nil { - d.compilers.capabilities = ast.CapabilitiesForThisVersion() - } - - if d.compilers.externs == nil { - for allowed := range validDataFields { - d.compilers.externs = append(d.compilers.externs, fmt.Sprintf("data.%s", allowed)) - } - } - - if d.targets == nil { - d.targets = make(map[string][]string) - } - - // adding external_data builtin otherwise capabilities get overridden - // if a capability, like http.send, is disabled - if d.providerCache != nil { - newBuiltin := &ast.Builtin{ - Name: "external_data", - Decl: opatypes.NewFunction(opatypes.Args(opatypes.A), opatypes.A), - } - d.compilers.capabilities.Builtins = append(d.compilers.capabilities.Builtins, newBuiltin) - } - - if d.sendRequestToProvider == nil { - d.sendRequestToProvider = externaldata.DefaultSendRequestToProvider - } - - return nil - } -} - -func Tracing(enabled bool) Arg { - return func(d *Driver) error { - d.traceEnabled = enabled - - return nil - } -} - -func PrintEnabled(enabled bool) Arg { - return func(d *Driver) error { - d.printEnabled = enabled - - return nil - } -} - -func PrintHook(hook print.Hook) Arg { - return func(d *Driver) error { - d.printHook = hook - - return nil - } -} - -func Storage(s map[string]storage.Store) Arg { - return func(d *Driver) error { - d.storage = storages{storage: s} - - return nil - } -} - -func AddExternalDataProviderCache(providerCache *externaldata.ProviderCache) Arg { - return func(d *Driver) error { - d.providerCache = providerCache - - return nil - } -} - -func DisableBuiltins(builtins ...string) Arg { - return func(d *Driver) error { - if d.compilers.capabilities == nil { - d.compilers.capabilities = ast.CapabilitiesForThisVersion() - } - - disableBuiltins := make(map[string]bool) - for _, b := range builtins { - disableBuiltins[b] = true - } - - var newBuiltins []*ast.Builtin - for _, b := range d.compilers.capabilities.Builtins { - if !disableBuiltins[b.Name] { - newBuiltins = append(newBuiltins, b) - } - } - - d.compilers.capabilities.Builtins = newBuiltins - - return nil - } -} - -func AddExternalDataClientCertWatcher(clientCertWatcher *certwatcher.CertWatcher) Arg { - return func(d *Driver) error { - d.clientCertWatcher = clientCertWatcher - - return nil - } -} - -func EnableExternalDataClientAuth() Arg { - return func(d *Driver) error { - d.enableExternalDataClientAuth = true - - return nil - } -} - -// Externs sets the fields under `data` that Rego in ConstraintTemplates -// can access. If unset, all fields can be accessed. Only fields recognized by -// the system can be enabled. -func Externs(externs ...string) Arg { - return func(driver *Driver) error { - fields := make([]string, len(externs)) - - for i, field := range externs { - if !validDataFields[field] { - return fmt.Errorf("%w: invalid data field %q; allowed fields are: %v", - errors.ErrCreatingDriver, field, validDataFields) - } - - fields[i] = fmt.Sprintf("data.%s", field) - } - - driver.compilers.externs = fields - - return nil - } -} - -// Currently rules should only access data.inventory. -var validDataFields = map[string]bool{ - "inventory": true, -} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/builtin.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/builtin.go deleted file mode 100644 index ee27249f3da..00000000000 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/builtin.go +++ /dev/null @@ -1,36 +0,0 @@ -package local - -import ( - "net/http" - - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/rego" -) - -func externalDataBuiltin(d *Driver) func(bctx rego.BuiltinContext, regorequest *ast.Term) (*ast.Term, error) { - return func(bctx rego.BuiltinContext, regorequest *ast.Term) (*ast.Term, error) { - var regoReq externaldata.RegoRequest - if err := ast.As(regorequest.Value, ®oReq); err != nil { - return nil, err - } - - provider, err := d.providerCache.Get(regoReq.ProviderName) - if err != nil { - return externaldata.HandleError(http.StatusBadRequest, err) - } - - clientCert, err := d.getTLSCertificate() - if err != nil { - return externaldata.HandleError(http.StatusBadRequest, err) - } - - externaldataResponse, statusCode, err := d.sendRequestToProvider(bctx.Context, &provider, regoReq.Keys, clientCert) - if err != nil { - return externaldata.HandleError(statusCode, err) - } - - regoResponse := externaldata.NewRegoResponse(statusCode, externaldataResponse) - return externaldata.PrepareRegoResponse(regoResponse) - } -} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/driver.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/driver.go deleted file mode 100644 index 62223fcc09a..00000000000 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/driver.go +++ /dev/null @@ -1,449 +0,0 @@ -package local - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "fmt" - "sort" - "strings" - "sync" - "time" - - "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" - "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" - clienterrors "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" - "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" - "github.com/open-policy-agent/frameworks/constraint/pkg/types" - "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/rego" - "github.com/open-policy-agent/opa/storage" - "github.com/open-policy-agent/opa/topdown" - "github.com/open-policy-agent/opa/topdown/print" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/certwatcher" -) - -const ( - libRoot = "data.lib" - violation = "violation" -) - -var _ drivers.Driver = &Driver{} - -// Driver is a threadsafe Rego environment for compiling Rego in ConstraintTemplates, -// registering Constraints, and executing queries. -type Driver struct { - // compilers is a store of Rego Compilers for each Template. - compilers Compilers - - // mtx guards access to the storage and target maps. - mtx sync.RWMutex - - storage storages - - // targets is a map from each Template's kind to the targets for that Template. - targets map[string][]string - - // traceEnabled is whether tracing is enabled for Rego queries by default. - // If enabled, individual queries cannot disable tracing. - traceEnabled bool - - // printEnabled is whether print statements are allowed in Rego. If disabled, - // print statements are removed from modules at compile-time. - printEnabled bool - - // printHook specifies where to send the output of Rego print() statements. - printHook print.Hook - - // providerCache allows Rego to read from external_data in Rego queries. - providerCache *externaldata.ProviderCache - - // sendRequestToProvider allows Rego to send requests to the provider specified in external_data. - sendRequestToProvider externaldata.SendRequestToProvider - - // enableExternalDataClientAuth enables the injection of a TLS certificate into an HTTP client - // that is used to communicate with providers. - enableExternalDataClientAuth bool - - // clientCertWatcher is a watcher for the TLS certificate used to communicate with providers. - clientCertWatcher *certwatcher.CertWatcher -} - -// RegoEvaluationMeta has rego specific metadata from evaluation. -type RegoEvaluationMeta struct { - // TemplateRunTime is the number of milliseconds it took to evaluate all constraints for a template. - TemplateRunTime float64 `json:"templateRunTime"` - // ConstraintCount indicates how many constraints were evaluated for an underlying rego engine eval call. - ConstraintCount uint `json:"constraintCount"` -} - -// AddTemplate adds templ to Driver. Normalizes modules into usable forms for -// use in queries. -func (d *Driver) AddTemplate(ctx context.Context, templ *templates.ConstraintTemplate) error { - var targets []string - for _, target := range templ.Spec.Targets { - // Ensure storage for each of this Template's targets exists. - _, err := d.storage.getStorage(ctx, target.Target) - if err != nil { - return err - } - targets = append(targets, target.Target) - } - - kind := templ.Spec.CRD.Spec.Names.Kind - - d.mtx.Lock() - defer d.mtx.Unlock() - - d.targets[kind] = targets - return d.compilers.addTemplate(templ, d.printEnabled) -} - -// RemoveTemplate removes all Compilers and Constraints for templ. -// Returns nil if templ does not exist. -func (d *Driver) RemoveTemplate(ctx context.Context, templ *templates.ConstraintTemplate) error { - kind := templ.Spec.CRD.Spec.Names.Kind - - constraintParent := storage.Path{"constraints", kind} - - d.mtx.Lock() - defer d.mtx.Unlock() - - d.compilers.removeTemplate(kind) - delete(d.targets, kind) - return d.storage.removeDataEach(ctx, constraintParent) -} - -// AddConstraint adds Constraint to Rego storage. Future calls to Query will -// be evaluated against Constraint if the Constraint's key is passed. -func (d *Driver) AddConstraint(ctx context.Context, constraint *unstructured.Unstructured) error { - // Note that this discards "status" as we only copy spec.parameters. - params, _, err := unstructured.NestedFieldNoCopy(constraint.Object, "spec", "parameters") - if err != nil { - return fmt.Errorf("%w: %v", constraints.ErrInvalidConstraint, err) - } - - // default .spec.parameters so that we don't need to default this in Rego. - if params == nil { - params = make(map[string]interface{}) - } - - key := drivers.ConstraintKeyFrom(constraint) - path := key.StoragePath() - - d.mtx.Lock() - defer d.mtx.Unlock() - - targets := d.targets[key.Kind] - for _, target := range targets { - err := d.storage.addData(ctx, target, path, params) - if err != nil { - return err - } - } - - return nil -} - -// RemoveConstraint removes Constraint from Rego storage. Future calls to Query -// will not be evaluated against the constraint. Queries which specify the -// constraint's key will silently not evaluate the Constraint. -func (d *Driver) RemoveConstraint(ctx context.Context, constraint *unstructured.Unstructured) error { - path := drivers.ConstraintKeyFrom(constraint).StoragePath() - - d.mtx.Lock() - defer d.mtx.Unlock() - - return d.storage.removeDataEach(ctx, path) -} - -// AddData adds data to Rego storage at data.inventory.path. -func (d *Driver) AddData(ctx context.Context, target string, path storage.Path, data interface{}) error { - path = inventoryPath(path) - return d.storage.addData(ctx, target, path, data) -} - -// RemoveData deletes data from Rego storage at data.inventory.path. -func (d *Driver) RemoveData(ctx context.Context, target string, path storage.Path) error { - path = inventoryPath(path) - return d.storage.removeData(ctx, target, path) -} - -// eval runs a query against compiler. -// path is the path to evaluate. -// input is the already-parsed Rego Value to use as input. -// Returns the Rego results, the trace if requested, or an error if there was -// a problem executing the query. -func (d *Driver) eval(ctx context.Context, compiler *ast.Compiler, target string, path []string, input ast.Value, opts ...drivers.QueryOpt) (rego.ResultSet, *string, error) { - cfg := &drivers.QueryCfg{} - for _, opt := range opts { - opt(cfg) - } - - queryPath := strings.Builder{} - queryPath.WriteString("data") - for _, p := range path { - queryPath.WriteString(".") - queryPath.WriteString(p) - } - - store, err := d.storage.getStorage(ctx, target) - if err != nil { - return nil, nil, err - } - - args := []func(*rego.Rego){ - rego.Compiler(compiler), - rego.Store(store), - rego.ParsedInput(input), - rego.Query(queryPath.String()), - rego.EnablePrintStatements(d.printEnabled), - rego.PrintHook(d.printHook), - } - - buf := topdown.NewBufferTracer() - if d.traceEnabled || cfg.TracingEnabled { - args = append(args, rego.QueryTracer(buf)) - } - - r := rego.New(args...) - res, err := r.Eval(ctx) - - var t *string - if d.traceEnabled || cfg.TracingEnabled { - b := &bytes.Buffer{} - topdown.PrettyTrace(b, *buf) - t = pointer.StringPtr(b.String()) - } - - return res, t, err -} - -func (d *Driver) Query(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...drivers.QueryOpt) ([]*types.Result, *string, error) { - if len(constraints) == 0 { - return nil, nil, nil - } - - constraintsByKind := toConstraintsByKind(constraints) - - traceBuilder := strings.Builder{} - constraintsMap := drivers.KeyMap(constraints) - path := []string{"hooks", "violation[result]"} - - var results []*types.Result - - // Round-trip review through JSON so that the review object is round-tripped - // once per call to Query instead of once per compiler. - reviewMap, err := toInterfaceMap(review) - if err != nil { - return nil, nil, err - } - - d.mtx.RLock() - defer d.mtx.RUnlock() - - for kind, kindConstraints := range constraintsByKind { - evalStartTime := time.Now() - compiler := d.compilers.getCompiler(target, kind) - if compiler == nil { - // The Template was just removed, so the Driver is in an inconsistent - // state with Client. Raise this as an error rather than attempting to - // continue. - return nil, nil, fmt.Errorf("missing Template %q for target %q", kind, target) - } - - // Parse input into an ast.Value to avoid round-tripping through JSON when - // possible. - parsedInput, err := toParsedInput(target, kindConstraints, reviewMap) - if err != nil { - return nil, nil, err - } - - resultSet, trace, err := d.eval(ctx, compiler, target, path, parsedInput, opts...) - evalEndTime := time.Since(evalStartTime) - if err != nil { - resultSet = make(rego.ResultSet, 0, len(kindConstraints)) - for _, constraint := range kindConstraints { - resultSet = append(resultSet, rego.Result{ - Bindings: map[string]interface{}{ - "result": map[string]interface{}{ - "msg": err.Error(), - "key": map[string]interface{}{ - "kind": constraint.GetKind(), - "name": constraint.GetName(), - }, - }, - }, - }) - } - } - if trace != nil { - traceBuilder.WriteString(*trace) - } - - kindResults, err := drivers.ToResults(constraintsMap, resultSet) - if err != nil { - return nil, nil, err - } - - for _, result := range kindResults { - result.EvaluationMeta = RegoEvaluationMeta{ - TemplateRunTime: float64(evalEndTime.Nanoseconds()) / 1000000, - ConstraintCount: uint(len(kindResults)), - } - } - - results = append(results, kindResults...) - } - - traceString := traceBuilder.String() - if len(traceString) != 0 { - return results, &traceString, nil - } - - return results, nil, nil -} - -func (d *Driver) Dump(ctx context.Context) (string, error) { - // we want to create: - // targetName.modules.kind.moduleName = contents - // targetName.data = data - dt := make(map[string]map[string]interface{}) - - compilers := d.compilers.list() - for targetName, targetCompilers := range compilers { - targetModules := make(map[string]map[string]string) - - for kind, compiler := range targetCompilers { - kindModules := make(map[string]string) - for modname, contents := range compiler.Modules { - kindModules[modname] = contents.String() - } - targetModules[kind] = kindModules - } - dt[targetName] = map[string]interface{}{} - dt[targetName]["modules"] = targetModules - - emptyCompiler := ast.NewCompiler().WithCapabilities(d.compilers.capabilities) - - rs, _, err := d.eval(ctx, emptyCompiler, targetName, []string{}, nil) - if err != nil { - return "", err - } - - if len(rs) != 0 && len(rs[0].Expressions) != 0 { - dt[targetName]["data"] = rs[0].Expressions[0].Value - } - } - - b, err := json.MarshalIndent(dt, "", " ") - if err != nil { - return "", err - } - - return string(b), nil -} - -func (d *Driver) getTLSCertificate() (*tls.Certificate, error) { - if !d.enableExternalDataClientAuth { - return nil, nil - } - - if d.clientCertWatcher == nil { - return nil, fmt.Errorf("certWatcher should not be nil when enableExternalDataClientAuth is true") - } - - return d.clientCertWatcher.GetCertificate(nil) -} - -// rewriteModulePackage rewrites the module's package path to path. -func rewriteModulePackage(module *ast.Module) error { - pathParts := ast.Ref([]*ast.Term{ast.VarTerm(templatePath)}) - - packageRef := ast.Ref([]*ast.Term{ast.VarTerm("data")}) - newPath := packageRef.Extend(pathParts) - module.Package.Path = newPath - return nil -} - -// requireModuleRules makes sure the module contains all of the specified -// requiredRules. -func requireModuleRules(module *ast.Module, requiredRules map[string]struct{}) error { - ruleSets := make(map[string]struct{}, len(module.Rules)) - for _, rule := range module.Rules { - ruleSets[string(rule.Head.Name)] = struct{}{} - } - - var missing []string - for name := range requiredRules { - _, ok := ruleSets[name] - if !ok { - missing = append(missing, name) - } - } - sort.Strings(missing) - - if len(missing) > 0 { - return fmt.Errorf("%w: missing required rules: %v", - clienterrors.ErrInvalidModule, missing) - } - - return nil -} - -func toInterfaceMap(obj interface{}) (map[string]interface{}, error) { - jsn, err := json.Marshal(obj) - if err != nil { - return nil, err - } - result := make(map[string]interface{}) - err = json.Unmarshal(jsn, &result) - if err != nil { - return nil, err - } - - return result, nil -} - -func toKeySlice(constraints []*unstructured.Unstructured) []interface{} { - var keys []interface{} - for _, constraint := range constraints { - key := drivers.ConstraintKeyFrom(constraint) - keys = append(keys, map[string]interface{}{ - "kind": key.Kind, - "name": key.Name, - }) - } - - return keys -} - -func toConstraintsByKind(constraints []*unstructured.Unstructured) map[string][]*unstructured.Unstructured { - constraintsByKind := make(map[string][]*unstructured.Unstructured) - for _, constraint := range constraints { - kind := constraint.GetKind() - constraintsByKind[kind] = append(constraintsByKind[kind], constraint) - } - - return constraintsByKind -} - -func toParsedInput(target string, constraints []*unstructured.Unstructured, review map[string]interface{}) (ast.Value, error) { - // Store constraint keys in a format InterfaceToValue does not need to - // round-trip through JSON. - constraintKeys := toKeySlice(constraints) - - input := map[string]interface{}{ - "target": target, - "constraints": constraintKeys, - "review": review, - } - - // Parse input into an ast.Value to avoid round-tripping through JSON when - // possible. - return ast.InterfaceToValue(input) -} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/new.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/new.go deleted file mode 100644 index 654e1fe1d0a..00000000000 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/new.go +++ /dev/null @@ -1,36 +0,0 @@ -package local - -import ( - "github.com/open-policy-agent/opa/rego" - opatypes "github.com/open-policy-agent/opa/types" -) - -// New constructs a new Driver and registers the built-in external_data function -// to OPA. -func New(args ...Arg) (*Driver, error) { - d := &Driver{} - for _, arg := range args { - err := arg(d) - if err != nil { - return nil, err - } - } - - err := Defaults()(d) - if err != nil { - return nil, err - } - - if d.providerCache != nil { - rego.RegisterBuiltin1( - ®o.Function{ - Name: "external_data", - Decl: opatypes.NewFunction(opatypes.Args(opatypes.A), opatypes.A), - Memoize: true, - }, - externalDataBuiltin(d), - ) - } - - return d, nil -} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/query_opts.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/query_opts.go index 404c32ebbb1..4b244cc2fc3 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/query_opts.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/query_opts.go @@ -2,9 +2,10 @@ package drivers type QueryCfg struct { TracingEnabled bool + StatsEnabled bool } -// QueryOpt specifies optional arguments for Rego queries. +// QueryOpt specifies optional arguments for Query driver calls. type QueryOpt func(*QueryCfg) // Tracing enables Rego tracing for a single query. @@ -14,3 +15,12 @@ func Tracing(enabled bool) QueryOpt { cfg.TracingEnabled = enabled } } + +// Stats(true) enables the driver to return evaluation stats for a single +// query. If stats is enabled for the Driver at construction time, then +// Stats(false) does not disable Stats for this single query. +func Stats(enabled bool) QueryOpt { + return func(cfg *QueryCfg) { + cfg.StatsEnabled = enabled + } +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/args.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/args.go new file mode 100644 index 00000000000..9a7ab8a3e37 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/args.go @@ -0,0 +1,178 @@ +package rego + +import ( + "fmt" + + "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" + "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/topdown/print" + opatypes "github.com/open-policy-agent/opa/types" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" +) + +type Arg func(*Driver) error + +func Defaults() Arg { + return func(d *Driver) error { + if d.storage.storage == nil { + d.storage.storage = make(map[string]storage.Store) + } + + if d.compilers.capabilities == nil { + d.compilers.capabilities = ast.CapabilitiesForThisVersion() + } + + if d.compilers.externs == nil { + for allowed := range validDataFields { + d.compilers.externs = append(d.compilers.externs, fmt.Sprintf("data.%s", allowed)) + } + } + + if d.targets == nil { + d.targets = make(map[string][]string) + } + + // adding external_data builtin otherwise capabilities get overridden + // if a capability, like http.send, is disabled + if d.providerCache != nil { + newBuiltin := &ast.Builtin{ + Name: "external_data", + Decl: opatypes.NewFunction(opatypes.Args(opatypes.A), opatypes.A), + } + d.compilers.capabilities.Builtins = append(d.compilers.capabilities.Builtins, newBuiltin) + } + + if d.sendRequestToProvider == nil { + d.sendRequestToProvider = externaldata.DefaultSendRequestToProvider + } + + return nil + } +} + +func Tracing(enabled bool) Arg { + return func(d *Driver) error { + d.traceEnabled = enabled + + return nil + } +} + +func PrintEnabled(enabled bool) Arg { + return func(d *Driver) error { + d.printEnabled = enabled + + return nil + } +} + +func PrintHook(hook print.Hook) Arg { + return func(d *Driver) error { + d.printHook = hook + + return nil + } +} + +func Storage(s map[string]storage.Store) Arg { + return func(d *Driver) error { + d.storage = storages{storage: s} + + return nil + } +} + +func AddExternalDataProviderCache(providerCache *externaldata.ProviderCache) Arg { + return func(d *Driver) error { + d.providerCache = providerCache + + return nil + } +} + +func AddExternalDataProviderResponseCache(providerResponseCache *externaldata.ProviderResponseCache) Arg { + return func(d *Driver) error { + d.providerResponseCache = providerResponseCache + + return nil + } +} + +func DisableBuiltins(builtins ...string) Arg { + return func(d *Driver) error { + if d.compilers.capabilities == nil { + d.compilers.capabilities = ast.CapabilitiesForThisVersion() + } + + disableBuiltins := make(map[string]bool) + for _, b := range builtins { + disableBuiltins[b] = true + } + + var newBuiltins []*ast.Builtin + for _, b := range d.compilers.capabilities.Builtins { + if !disableBuiltins[b.Name] { + newBuiltins = append(newBuiltins, b) + } + } + + d.compilers.capabilities.Builtins = newBuiltins + + return nil + } +} + +func AddExternalDataClientCertWatcher(clientCertWatcher *certwatcher.CertWatcher) Arg { + return func(d *Driver) error { + d.clientCertWatcher = clientCertWatcher + + return nil + } +} + +func EnableExternalDataClientAuth() Arg { + return func(d *Driver) error { + d.enableExternalDataClientAuth = true + + return nil + } +} + +// Externs sets the fields under `data` that Rego in ConstraintTemplates +// can access. If unset, all fields can be accessed. Only fields recognized by +// the system can be enabled. +func Externs(externs ...string) Arg { + return func(driver *Driver) error { + fields := make([]string, len(externs)) + + for i, field := range externs { + if !validDataFields[field] { + return fmt.Errorf("%w: invalid data field %q; allowed fields are: %v", + errors.ErrCreatingDriver, field, validDataFields) + } + + fields[i] = fmt.Sprintf("data.%s", field) + } + + driver.compilers.externs = fields + + return nil + } +} + +// GatherStats starts collecting various stats around the +// underlying engine's calls. +func GatherStats() Arg { + return func(driver *Driver) error { + driver.gatherStats = true + + return nil + } +} + +// Currently rules should only access data.inventory. +var validDataFields = map[string]bool{ + "inventory": true, +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/builtin.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/builtin.go new file mode 100644 index 00000000000..7ea46eb6f3e --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/builtin.go @@ -0,0 +1,117 @@ +package rego + +import ( + "net/http" + "time" + + "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/rego" +) + +const ( + providerResponseAPIVersion = "externaldata.gatekeeper.sh/v1beta1" + providerResponseKind = "ProviderResponse" +) + +func externalDataBuiltin(d *Driver) func(bctx rego.BuiltinContext, regorequest *ast.Term) (*ast.Term, error) { + return func(bctx rego.BuiltinContext, regorequest *ast.Term) (*ast.Term, error) { + var regoReq externaldata.RegoRequest + if err := ast.As(regorequest.Value, ®oReq); err != nil { + return nil, err + } + + provider, err := d.providerCache.Get(regoReq.ProviderName) + if err != nil { + return externaldata.HandleError(http.StatusBadRequest, err) + } + + clientCert, err := d.getTLSCertificate() + if err != nil { + return externaldata.HandleError(http.StatusBadRequest, err) + } + + // check provider response cache + var providerRequestKeys []string + var providerResponseStatusCode int + var prepareResponse externaldata.Response + + prepareResponse.Idempotent = true + for _, k := range regoReq.Keys { + if d.providerResponseCache == nil { + // external data response cache is not enabled, add key to call provider + providerRequestKeys = append(providerRequestKeys, k) + continue + } + + cachedResponse, err := d.providerResponseCache.Get( + externaldata.CacheKey{ + ProviderName: regoReq.ProviderName, + Key: k, + }, + ) + if err != nil || time.Since(time.Unix(cachedResponse.Received, 0)) > d.providerResponseCache.TTL { + // key is not found or cache entry is stale, add key to the provider request keys + providerRequestKeys = append(providerRequestKeys, k) + } else { + prepareResponse.Items = append( + prepareResponse.Items, externaldata.Item{ + Key: k, + Value: cachedResponse.Value, + Error: cachedResponse.Error, + }, + ) + + // we are taking conservative approach here, if any of the cached response is not idempotent + // we will mark the whole response as not idempotent + if !cachedResponse.Idempotent { + prepareResponse.Idempotent = false + } + } + } + + if len(providerRequestKeys) > 0 { + externaldataResponse, statusCode, err := d.sendRequestToProvider(bctx.Context, &provider, providerRequestKeys, clientCert) + if err != nil { + return externaldata.HandleError(statusCode, err) + } + + // update provider response cache if it is enabled + if d.providerResponseCache != nil { + for _, item := range externaldataResponse.Response.Items { + d.providerResponseCache.Upsert( + externaldata.CacheKey{ + ProviderName: regoReq.ProviderName, + Key: item.Key, + }, + externaldata.CacheValue{ + Received: time.Now().Unix(), + Value: item.Value, + Error: item.Error, + Idempotent: externaldataResponse.Response.Idempotent, + }, + ) + } + } + + // we are taking conservative approach here, if any of the response is not idempotent + // we will mark the whole response as not idempotent + if !externaldataResponse.Response.Idempotent { + prepareResponse.Idempotent = false + } + + prepareResponse.Items = append(prepareResponse.Items, externaldataResponse.Response.Items...) + prepareResponse.SystemError = externaldataResponse.Response.SystemError + providerResponseStatusCode = statusCode + } + + providerResponse := &externaldata.ProviderResponse{ + APIVersion: providerResponseAPIVersion, + Kind: providerResponseKind, + Response: prepareResponse, + } + + regoResponse := externaldata.NewRegoResponse(providerResponseStatusCode, providerResponse) + return externaldata.PrepareRegoResponse(regoResponse) + } +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/compilers.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/compilers.go similarity index 88% rename from vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/compilers.go rename to vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/compilers.go index 908513a9e94..0fc072deae8 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/compilers.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/compilers.go @@ -1,15 +1,19 @@ -package local +package rego import ( + "errors" "fmt" "sync" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" clienterrors "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/regorewriter" "github.com/open-policy-agent/opa/ast" ) +var ErrNoRego = errors.New("Could not extract Rego from the constraint template") + // Compilers is a threadsafe store of Compilers for ConstraintTemplates. type Compilers struct { mtx sync.RWMutex @@ -125,8 +129,9 @@ func parseConstraintTemplate(templ *templates.ConstraintTemplate, externs []stri } mods := make(map[string][]*ast.Module) - for _, target := range templ.Spec.Targets { - targetMods, err := parseConstraintTemplateTarget(rr, target) + for i := range templ.Spec.Targets { + target := templ.Spec.Targets[i] + targetMods, err := parseConstraintTemplateTarget(rr, &target) if err != nil { return nil, err } @@ -137,8 +142,24 @@ func parseConstraintTemplate(templ *templates.ConstraintTemplate, externs []stri return mods, nil } -func parseConstraintTemplateTarget(rr *regorewriter.RegoRewriter, targetSpec templates.Target) ([]*ast.Module, error) { - entryPoint, err := parseModule(templatePath, targetSpec.Rego) +func parseConstraintTemplateTarget(rr *regorewriter.RegoRewriter, targetSpec *templates.Target) ([]*ast.Module, error) { + var regoCode templates.Code + found := false + for _, code := range targetSpec.Code { + if code.Engine == schema.Name { + found = true + regoCode = code + break + } + } + if !found { + return nil, ErrNoRego + } + regoSrc, err := schema.GetSource(regoCode) + if err != nil { + return nil, err + } + entryPoint, err := parseModule(templatePath, regoSrc.Rego) if err != nil { return nil, fmt.Errorf("%w: %v", clienterrors.ErrInvalidConstraintTemplate, err) } @@ -160,7 +181,7 @@ func parseConstraintTemplateTarget(rr *regorewriter.RegoRewriter, targetSpec tem } rr.AddEntryPointModule(templatePath, entryPoint) - for idx, libSrc := range targetSpec.Libs { + for idx, libSrc := range regoSrc.Libs { libPath := fmt.Sprintf(`%s["lib_%d"]`, templateLibPrefix, idx) m, err := parseModule(libPath, libSrc) diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/driver.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/driver.go new file mode 100644 index 00000000000..514bb4f7a2c --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/driver.go @@ -0,0 +1,514 @@ +package rego + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/json" + "fmt" + "sort" + "strings" + "sync" + "time" + + "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" + clienterrors "github.com/open-policy-agent/frameworks/constraint/pkg/client/errors" + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "github.com/open-policy-agent/frameworks/constraint/pkg/externaldata" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + "github.com/open-policy-agent/frameworks/constraint/pkg/types" + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/rego" + "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/topdown" + "github.com/open-policy-agent/opa/topdown/print" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" +) + +const ( + libRoot = "data.lib" + violation = "violation" + + templateRunTimeNS = "templateRunTimeNS" + templateRunTimeNsDesc = "the number of nanoseconds it took to evaluate all constraints for a template" + + constraintCountName = "constraintCount" + constraintCountDescription = "the number of constraints that were evaluated for the given constraint kind" + + tracingEnabledLabelName = "TracingEnabled" + printEnabledLabelName = "PrintEnabled" +) + +var _ drivers.Driver = &Driver{} + +// Driver is a threadsafe Rego environment for compiling Rego in ConstraintTemplates, +// registering Constraints, and executing queries. +type Driver struct { + // compilers is a store of Rego Compilers for each Template. + compilers Compilers + + // mtx guards access to the storage and target maps. + mtx sync.RWMutex + + storage storages + + // targets is a map from each Template's kind to the targets for that Template. + targets map[string][]string + + // traceEnabled is whether tracing is enabled for Rego queries by default. + // If enabled, individual queries cannot disable tracing. + traceEnabled bool + + // printEnabled is whether print statements are allowed in Rego. If disabled, + // print statements are removed from modules at compile-time. + printEnabled bool + + // printHook specifies where to send the output of Rego print() statements. + printHook print.Hook + + // providerCache allows Rego to read from external_data in Rego queries. + providerCache *externaldata.ProviderCache + + // providerResponseCache allows to cache responses from external_data providers. + providerResponseCache *externaldata.ProviderResponseCache + + // sendRequestToProvider allows Rego to send requests to the provider specified in external_data. + sendRequestToProvider externaldata.SendRequestToProvider + + // enableExternalDataClientAuth enables the injection of a TLS certificate into an HTTP client + // that is used to communicate with providers. + enableExternalDataClientAuth bool + + // clientCertWatcher is a watcher for the TLS certificate used to communicate with providers. + clientCertWatcher *certwatcher.CertWatcher + + // gatherStats controls whether the driver gathers any stats around its API calls. + gatherStats bool +} + +// Name returns the name of the driver. +func (d *Driver) Name() string { + return schema.Name +} + +// AddTemplate adds templ to Driver. Normalizes modules into usable forms for +// use in queries. +func (d *Driver) AddTemplate(ctx context.Context, templ *templates.ConstraintTemplate) error { + var targets []string + for _, target := range templ.Spec.Targets { + // Ensure storage for each of this Template's targets exists. + _, err := d.storage.getStorage(ctx, target.Target) + if err != nil { + return err + } + targets = append(targets, target.Target) + } + + kind := templ.Spec.CRD.Spec.Names.Kind + + d.mtx.Lock() + defer d.mtx.Unlock() + + d.targets[kind] = targets + return d.compilers.addTemplate(templ, d.printEnabled) +} + +// RemoveTemplate removes all Compilers and Constraints for templ. +// Returns nil if templ does not exist. +func (d *Driver) RemoveTemplate(ctx context.Context, templ *templates.ConstraintTemplate) error { + kind := templ.Spec.CRD.Spec.Names.Kind + + constraintParent := storage.Path{"constraints", kind} + + d.mtx.Lock() + defer d.mtx.Unlock() + + if err := d.storage.removeDataEach(ctx, constraintParent); err != nil { + return err + } + + d.compilers.removeTemplate(kind) + delete(d.targets, kind) + return nil +} + +// AddConstraint adds Constraint to Rego storage. Future calls to Query will +// be evaluated against Constraint if the Constraint's key is passed. +func (d *Driver) AddConstraint(ctx context.Context, constraint *unstructured.Unstructured) error { + // Note that this discards "status" as we only copy spec.parameters. + params, _, err := unstructured.NestedFieldNoCopy(constraint.Object, "spec", "parameters") + if err != nil { + return fmt.Errorf("%w: %v", constraints.ErrInvalidConstraint, err) + } + + // default .spec.parameters so that we don't need to default this in Rego. + if params == nil { + params = make(map[string]interface{}) + } + + key := drivers.ConstraintKeyFrom(constraint) + path := key.StoragePath() + + d.mtx.Lock() + defer d.mtx.Unlock() + + targets := d.targets[key.Kind] + for _, target := range targets { + err := d.storage.addData(ctx, target, path, params) + if err != nil { + return err + } + } + + return nil +} + +// RemoveConstraint removes Constraint from Rego storage. Future calls to Query +// will not be evaluated against the constraint. Queries which specify the +// constraint's key will silently not evaluate the Constraint. +func (d *Driver) RemoveConstraint(ctx context.Context, constraint *unstructured.Unstructured) error { + path := drivers.ConstraintKeyFrom(constraint).StoragePath() + + d.mtx.Lock() + defer d.mtx.Unlock() + + return d.storage.removeDataEach(ctx, path) +} + +// AddData adds data to Rego storage at data.inventory.path. +func (d *Driver) AddData(ctx context.Context, target string, path storage.Path, data interface{}) error { + path = inventoryPath(path) + return d.storage.addData(ctx, target, path, data) +} + +// RemoveData deletes data from Rego storage at data.inventory.path. +func (d *Driver) RemoveData(ctx context.Context, target string, path storage.Path) error { + path = inventoryPath(path) + return d.storage.removeData(ctx, target, path) +} + +// eval runs a query against compiler. +// path is the path to evaluate. +// input is the already-parsed Rego Value to use as input. +// Returns the Rego results, the trace if requested, or an error if there was +// a problem executing the query. +func (d *Driver) eval(ctx context.Context, compiler *ast.Compiler, target string, path []string, input ast.Value, opts ...drivers.QueryOpt) (rego.ResultSet, *string, error) { + cfg := &drivers.QueryCfg{} + for _, opt := range opts { + opt(cfg) + } + + queryPath := strings.Builder{} + queryPath.WriteString("data") + for _, p := range path { + queryPath.WriteString(".") + queryPath.WriteString(p) + } + + store, err := d.storage.getStorage(ctx, target) + if err != nil { + return nil, nil, err + } + + args := []func(*rego.Rego){ + rego.Compiler(compiler), + rego.Store(store), + rego.ParsedInput(input), + rego.Query(queryPath.String()), + rego.EnablePrintStatements(d.printEnabled), + rego.PrintHook(d.printHook), + } + + buf := topdown.NewBufferTracer() + if d.traceEnabled || cfg.TracingEnabled { + args = append(args, rego.QueryTracer(buf)) + } + + r := rego.New(args...) + res, err := r.Eval(ctx) + + var t *string + if d.traceEnabled || cfg.TracingEnabled { + b := &bytes.Buffer{} + topdown.PrettyTrace(b, *buf) + t = pointer.String(b.String()) + } + + return res, t, err +} + +func (d *Driver) Query(ctx context.Context, target string, constraints []*unstructured.Unstructured, review interface{}, opts ...drivers.QueryOpt) (*drivers.QueryResponse, error) { + if len(constraints) == 0 { + return nil, nil + } + + constraintsByKind := toConstraintsByKind(constraints) + + traceBuilder := strings.Builder{} + constraintsMap := drivers.KeyMap(constraints) + path := []string{"hooks", "violation[result]"} + + var results []*types.Result + + // Round-trip review through JSON so that the review object is round-tripped + // once per call to Query instead of once per compiler. + reviewMap, err := toInterfaceMap(review) + if err != nil { + return nil, err + } + + d.mtx.RLock() + defer d.mtx.RUnlock() + + cfg := &drivers.QueryCfg{} + for _, opt := range opts { + opt(cfg) + } + + var statsEntries []*instrumentation.StatsEntry + + for kind, kindConstraints := range constraintsByKind { + evalStartTime := time.Now() + compiler := d.compilers.getCompiler(target, kind) + if compiler == nil { + // The Template was just removed, so the Driver is in an inconsistent + // state with Client. Raise this as an error rather than attempting to + // continue. + return nil, fmt.Errorf("missing Template %q for target %q", kind, target) + } + + // Parse input into an ast.Value to avoid round-tripping through JSON when + // possible. + parsedInput, err := toParsedInput(target, kindConstraints, reviewMap) + if err != nil { + return nil, err + } + + resultSet, trace, err := d.eval(ctx, compiler, target, path, parsedInput, opts...) + evalEndTime := time.Since(evalStartTime) + if err != nil { + resultSet = make(rego.ResultSet, 0, len(kindConstraints)) + for _, constraint := range kindConstraints { + resultSet = append(resultSet, rego.Result{ + Bindings: map[string]interface{}{ + "result": map[string]interface{}{ + "msg": err.Error(), + "key": map[string]interface{}{ + "kind": constraint.GetKind(), + "name": constraint.GetName(), + }, + }, + }, + }) + } + } + if trace != nil { + traceBuilder.WriteString(*trace) + } + + kindResults, err := drivers.ToResults(constraintsMap, resultSet) + if err != nil { + return nil, err + } + + results = append(results, kindResults...) + + if d.gatherStats || (cfg != nil && cfg.StatsEnabled) { + statsEntries = append(statsEntries, + &instrumentation.StatsEntry{ + Scope: instrumentation.TemplateScope, + StatsFor: kind, + Stats: []*instrumentation.Stat{ + { + Name: templateRunTimeNS, + Value: uint64(evalEndTime.Nanoseconds()), + Source: instrumentation.Source{ + Type: instrumentation.EngineSourceType, + Value: schema.Name, + }, + }, + { + Name: constraintCountName, + Value: len(kindConstraints), + Source: instrumentation.Source{ + Type: instrumentation.EngineSourceType, + Value: schema.Name, + }, + }, + }, + Labels: []*instrumentation.Label{ + { + Name: tracingEnabledLabelName, + Value: d.traceEnabled || cfg.TracingEnabled, + }, + { + Name: printEnabledLabelName, + Value: d.printEnabled, + }, + }, + }) + } + } + + traceString := traceBuilder.String() + if len(traceString) != 0 { + return &drivers.QueryResponse{Results: results, Trace: &traceString, StatsEntries: statsEntries}, nil + } + + return &drivers.QueryResponse{Results: results, StatsEntries: statsEntries}, nil +} + +func (d *Driver) Dump(ctx context.Context) (string, error) { + // we want to create: + // targetName.modules.kind.moduleName = contents + // targetName.data = data + dt := make(map[string]map[string]interface{}) + + compilers := d.compilers.list() + for targetName, targetCompilers := range compilers { + targetModules := make(map[string]map[string]string) + + for kind, compiler := range targetCompilers { + kindModules := make(map[string]string) + for modname, contents := range compiler.Modules { + kindModules[modname] = contents.String() + } + targetModules[kind] = kindModules + } + dt[targetName] = map[string]interface{}{} + dt[targetName]["modules"] = targetModules + + emptyCompiler := ast.NewCompiler().WithCapabilities(d.compilers.capabilities) + + rs, _, err := d.eval(ctx, emptyCompiler, targetName, []string{}, nil) + if err != nil { + return "", err + } + + if len(rs) != 0 && len(rs[0].Expressions) != 0 { + dt[targetName]["data"] = rs[0].Expressions[0].Value + } + } + + b, err := json.MarshalIndent(dt, "", " ") + if err != nil { + return "", err + } + + return string(b), nil +} + +func (d *Driver) GetDescriptionForStat(statName string) (string, error) { + switch statName { + case templateRunTimeNS: + return templateRunTimeNsDesc, nil + case constraintCountName: + return constraintCountDescription, nil + default: + return "", fmt.Errorf("unknown stat name") + } +} + +func (d *Driver) getTLSCertificate() (*tls.Certificate, error) { + if !d.enableExternalDataClientAuth { + return nil, nil + } + + if d.clientCertWatcher == nil { + return nil, fmt.Errorf("certWatcher should not be nil when enableExternalDataClientAuth is true") + } + + return d.clientCertWatcher.GetCertificate(nil) +} + +// rewriteModulePackage rewrites the module's package path to path. +func rewriteModulePackage(module *ast.Module) error { + pathParts := ast.Ref([]*ast.Term{ast.VarTerm(templatePath)}) + + packageRef := ast.Ref([]*ast.Term{ast.VarTerm("data")}) + newPath := packageRef.Extend(pathParts) + module.Package.Path = newPath + return nil +} + +// requireModuleRules makes sure the module contains all of the specified +// requiredRules. +func requireModuleRules(module *ast.Module, requiredRules map[string]struct{}) error { + ruleSets := make(map[string]struct{}, len(module.Rules)) + for _, rule := range module.Rules { + ruleSets[string(rule.Head.Name)] = struct{}{} + } + + var missing []string + for name := range requiredRules { + _, ok := ruleSets[name] + if !ok { + missing = append(missing, name) + } + } + sort.Strings(missing) + + if len(missing) > 0 { + return fmt.Errorf("%w: missing required rules: %v", + clienterrors.ErrInvalidModule, missing) + } + + return nil +} + +func toInterfaceMap(obj interface{}) (map[string]interface{}, error) { + jsn, err := json.Marshal(obj) + if err != nil { + return nil, err + } + result := make(map[string]interface{}) + err = json.Unmarshal(jsn, &result) + if err != nil { + return nil, err + } + + return result, nil +} + +func toKeySlice(constraints []*unstructured.Unstructured) []interface{} { + var keys []interface{} + for _, constraint := range constraints { + key := drivers.ConstraintKeyFrom(constraint) + keys = append(keys, map[string]interface{}{ + "kind": key.Kind, + "name": key.Name, + }) + } + + return keys +} + +func toConstraintsByKind(constraints []*unstructured.Unstructured) map[string][]*unstructured.Unstructured { + constraintsByKind := make(map[string][]*unstructured.Unstructured) + for _, constraint := range constraints { + kind := constraint.GetKind() + constraintsByKind[kind] = append(constraintsByKind[kind], constraint) + } + + return constraintsByKind +} + +func toParsedInput(target string, constraints []*unstructured.Unstructured, review map[string]interface{}) (ast.Value, error) { + // Store constraint keys in a format InterfaceToValue does not need to + // round-trip through JSON. + constraintKeys := toKeySlice(constraints) + + input := map[string]interface{}{ + "target": target, + "constraints": constraintKeys, + "review": review, + } + + // Parse input into an ast.Value to avoid round-tripping through JSON when + // possible. + return ast.InterfaceToValue(input) +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/new.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/new.go new file mode 100644 index 00000000000..de433764b93 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/new.go @@ -0,0 +1,36 @@ +package rego + +import ( + "github.com/open-policy-agent/opa/rego" + opatypes "github.com/open-policy-agent/opa/types" +) + +// New constructs a new Driver and registers the built-in external_data function +// to OPA. +func New(args ...Arg) (*Driver, error) { + d := &Driver{} + for _, arg := range args { + err := arg(d) + if err != nil { + return nil, err + } + } + + err := Defaults()(d) + if err != nil { + return nil, err + } + + if d.providerCache != nil { + rego.RegisterBuiltin1( + ®o.Function{ + Name: "external_data", + Decl: opatypes.NewFunction(opatypes.Args(opatypes.A), opatypes.A), + Memoize: true, + }, + externalDataBuiltin(d), + ) + } + + return d, nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/rego.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/rego.go similarity index 99% rename from vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/rego.go rename to vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/rego.go index 00df19ed182..2037bc028fe 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/rego.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/rego.go @@ -1,4 +1,4 @@ -package local +package rego import "github.com/open-policy-agent/opa/ast" diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema/schema.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema/schema.go new file mode 100644 index 00000000000..da1bd4c0434 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema/schema.go @@ -0,0 +1,70 @@ +package schema + +import ( + "errors" + "fmt" + + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// Name is the name of the driver. +const Name = "Rego" + +var ( + ErrBadType = errors.New("Could not recognize the type") + ErrMissingField = errors.New("Rego source missing required field") +) + +type Source struct { + // Rego holds the main code for the constraint template. The `Violations` rule is the entry point. + Rego string `json:"rego,omitempty"` + // Libs holds supporting code for the main rego library. Modules can be imported from `data.libs`. + Libs []string `json:"libs,omitempty"` +} + +func (in *Source) ToUnstructured() map[string]interface{} { + if in == nil { + return nil + } + + out := map[string]interface{}{} + + out["rego"] = in.Rego + + if in.Libs != nil { + var libs []interface{} + for _, v := range in.Libs { + libs = append(libs, v) + } + out["libs"] = libs + } + + return out +} + +func GetSource(code templates.Code) (*Source, error) { + rawCode := code.Source + v, ok := rawCode.Value.(map[string]interface{}) + if !ok { + return nil, ErrBadType + } + source := &Source{} + rego, found, err := unstructured.NestedString(v, "rego") + if err != nil { + return nil, fmt.Errorf("%w: while extracting Rego source", err) + } + if !found { + return nil, fmt.Errorf("%w: rego", ErrMissingField) + } + source.Rego = rego + + libs, found, err := unstructured.NestedStringSlice(v, "libs") + if err != nil { + return nil, fmt.Errorf("%w: while extracting Rego libs", err) + } + if found { + source.Libs = libs + } + return source, nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/storages.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/storages.go similarity index 99% rename from vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/storages.go rename to vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/storages.go index 7b6738ee7e5..26361a1bbb8 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local/storages.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/storages.go @@ -1,4 +1,4 @@ -package local +package rego import ( "context" diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/types.go new file mode 100644 index 00000000000..7e0b9738b18 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/types.go @@ -0,0 +1,16 @@ +package drivers + +import ( + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" + "github.com/open-policy-agent/frameworks/constraint/pkg/types" +) + +// QueryResponse encapsulates the values returned on Query: +// - Results includes a Result for each violated Constraint. +// - Trace is the evaluation trace on Query if specified in query options or enabled at Driver creation. +// - StatsEntries include any Stats that the engine gathered on Query. +type QueryResponse struct { + Results []*types.Result + Trace *string + StatsEntries []*instrumentation.StatsEntry +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors.go index d5271c91a17..b6c918df40c 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors.go @@ -6,6 +6,9 @@ import ( var ( ErrCreatingBackend = errors.New("unable to create backend") + ErrNoDriverName = errors.New("driver has no name") + ErrNoReferentialDriver = errors.New("no driver that supports referential constraints added") + ErrDuplicateDriver = errors.New("duplicate drivers of the same name") ErrCreatingClient = errors.New("unable to create client") ErrMissingConstraint = errors.New("missing Constraint") ErrMissingConstraintTemplate = errors.New("missing ConstraintTemplate") diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/error_map.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/error_map.go index 4b1d901a2b4..3f2276ba077 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/error_map.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/error_map.go @@ -26,7 +26,7 @@ func (e *ErrorMap) Error() string { sort.Strings(keys) for _, k := range keys { - b.WriteString(fmt.Sprintf("%s: %s\n", k, (*e)[k])) + fmt.Fprintf(b, "%s: %s\n", k, (*e)[k]) } return b.String() } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/errors.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/errors.go index 294599c375a..25a6f211b41 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/errors.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/errors/errors.go @@ -19,4 +19,5 @@ var ( ErrMissingConstraintTemplate = errors.New("missing ConstraintTemplate") ErrInvalidModule = errors.New("invalid module") ErrChangeTargets = errors.New("ConstraintTemplates with Constraints may not change targets") + ErrNoDriver = errors.New("No language driver is installed that handles this constraint template") ) diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/new_client.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/new_client.go index e19d15a36e7..64d153e17dc 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/new_client.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/new_client.go @@ -2,12 +2,16 @@ package client import ( "fmt" + + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers" ) // NewClient creates a new client. func NewClient(opts ...Opt) (*Client, error) { c := &Client{ - templates: make(map[string]*templateClient), + templates: make(map[string]*templateClient), + drivers: make(map[string]drivers.Driver), + driverPriority: make(map[string]int), } for _, opt := range opts { diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/template_client.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/template_client.go index b2975bc3375..a5ef56c36a8 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/template_client.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/template_client.go @@ -10,6 +10,8 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" "github.com/open-policy-agent/frameworks/constraint/pkg/handler" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -30,6 +32,23 @@ type templateClient struct { // this Template. This is used to validate incoming Constraints before adding // them. crd *apiextensions.CustomResourceDefinition + + // if, for some reason, there was an error adding a pre-cached constraint after + // a driver switch, AddTemplate returns an error. We should preserve that state + // so that we know a constraint replay should be attempted the next time AddTemplate + // is called. + needsConstraintReplay bool + + // activeDrivers keeps track of drivers that are in an ambiguous state due to a failed + // cross-driver update. This allows us to clean up stale state on old drivers. + activeDrivers map[string]bool +} + +func newTemplateClient() *templateClient { + return &templateClient{ + constraints: make(map[string]*constraintClient), + activeDrivers: make(map[string]bool), + } } func (e *templateClient) ValidateConstraint(constraint *unstructured.Unstructured) error { @@ -43,6 +62,19 @@ func (e *templateClient) ValidateConstraint(constraint *unstructured.Unstructure return crds.ValidateCR(constraint, e.crd) } +// ApplyDefaultParams will apply any default parameters defined in the CRD of the constraint's +// corresponding template. +// Assumes ValidateConstraint() is called so the constraint is a valid CRD. +func (e *templateClient) ApplyDefaultParams(constraint *unstructured.Unstructured) (*unstructured.Unstructured, error) { + structural, err := schema.NewStructural(e.crd.Spec.Validation.OpenAPIV3Schema) + if err != nil { + return nil, err + } + + defaulting.Default(constraint.Object, structural) + return constraint, nil +} + func (e *templateClient) getTemplate() *templates.ConstraintTemplate { return e.template.DeepCopy() } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go index b19b66f465d..5e0a7ef019c 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go @@ -16,10 +16,13 @@ limitations under the License. package templates import ( + "bytes" + "encoding/json" "reflect" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" ) // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! @@ -55,6 +58,21 @@ type Target struct { Target string `json:"target,omitempty"` Rego string `json:"rego,omitempty"` Libs []string `json:"libs,omitempty"` + // The source code options for the constraint template, only one of this + // or "rego" can be specified. + Code []Code `json:"code,omitempty"` +} + +type Code struct { + // +kubebuilder:validation:Required + // The engine used to evaluate the code. Example: "Rego". Required. + Engine string `json:"engine,omitempty"` + + // +kubebuilder:validation:Required + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // The source code for the template. Required. + Source *Anything `json:"source,omitempty"` } // CreateCRDError represents a single error caught during parsing, compiling, etc. @@ -105,6 +123,51 @@ type ConstraintTemplateList struct { Items []ConstraintTemplate `json:"items"` } +// Anything is a struct wrapper around a field of type `interface{}` +// that plays nicely with controller-gen +// +kubebuilder:object:generate=false +// +kubebuilder:validation:Type="" +type Anything struct { + Value interface{} `json:"-"` +} + +func (in *Anything) GetValue() interface{} { + return runtime.DeepCopyJSONValue(in.Value) +} + +func (in *Anything) UnmarshalJSON(val []byte) error { + if bytes.Equal(val, []byte("null")) { + return nil + } + return json.Unmarshal(val, &in.Value) +} + +// MarshalJSON should be implemented against a value +// per http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go +// credit to K8s api machinery's RawExtension for finding this. +func (in Anything) MarshalJSON() ([]byte, error) { + if in.Value == nil { + return []byte("null"), nil + } + return json.Marshal(in.Value) +} + +func (in *Anything) DeepCopy() *Anything { + if in == nil { + return nil + } + + return &Anything{Value: runtime.DeepCopyJSONValue(in.Value)} +} + +func (in *Anything) DeepCopyInto(out *Anything) { + *out = *in + + if in.Value != nil { + out.Value = runtime.DeepCopyJSONValue(in.Value) + } +} + // SemanticEqual returns whether there have been changes to a constraint that // the framework should know about. It can ignore metadata as it assumes the // two comparables share the same identity. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/zz_generated.deepcopy.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/zz_generated.deepcopy.go index 3fca590ed89..3e0d52bdefb 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/zz_generated.deepcopy.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ limitations under the License. package templates import ( - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -81,6 +81,25 @@ func (in *CRDSpec) DeepCopy() *CRDSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Code) DeepCopyInto(out *Code) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Code. +func (in *Code) DeepCopy() *Code { + if in == nil { + return nil + } + out := new(Code) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConstraintTemplate) DeepCopyInto(out *ConstraintTemplate) { *out = *in @@ -228,6 +247,13 @@ func (in *Target) DeepCopyInto(out *Target) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Code != nil { + in, out := &in.Code, &out.Code + *out = make([]Code, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/externaldata/cache.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/externaldata/cache.go index d69f1e2688c..effa7b2131e 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/externaldata/cache.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/externaldata/cache.go @@ -1,14 +1,17 @@ package externaldata import ( + "context" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "net/url" "sync" + "time" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/externaldata/unversioned" + "k8s.io/apimachinery/pkg/util/wait" ) type ProviderCache struct { @@ -16,6 +19,73 @@ type ProviderCache struct { mux sync.RWMutex } +type ProviderResponseCache struct { + cache sync.Map + TTL time.Duration +} + +type CacheKey struct { + ProviderName string + Key string +} + +type CacheValue struct { + Received int64 + Value interface{} + Error string + Idempotent bool +} + +func NewProviderResponseCache(ctx context.Context, ttl time.Duration) *ProviderResponseCache { + providerResponseCache := &ProviderResponseCache{ + cache: sync.Map{}, + TTL: ttl, + } + + go wait.UntilWithContext(ctx, func(ctx context.Context) { + providerResponseCache.invalidateProviderResponseCache(providerResponseCache.TTL) + }, ttl) + + return providerResponseCache +} + +func (c *ProviderResponseCache) Get(key CacheKey) (*CacheValue, error) { + if v, ok := c.cache.Load(key); ok { + value, ok := v.(*CacheValue) + if !ok { + return nil, fmt.Errorf("value is not of type CacheValue") + } + return value, nil + } + return nil, fmt.Errorf("key '%s:%s' is not found in provider response cache", key.ProviderName, key.Key) +} + +func (c *ProviderResponseCache) Upsert(key CacheKey, value CacheValue) { + c.cache.Store(key, &value) +} + +func (c *ProviderResponseCache) Remove(key CacheKey) { + c.cache.Delete(key) +} + +func (c *ProviderResponseCache) invalidateProviderResponseCache(ttl time.Duration) { + c.cache.Range(func(k, v interface{}) bool { + value, ok := v.(*CacheValue) + if !ok { + return false + } + + if time.Since(time.Unix(value.Received, 0)) > ttl { + key, ok := k.(CacheKey) + if !ok { + return false + } + c.Remove(key) + } + return true + }) +} + func NewCache() *ProviderCache { return &ProviderCache{ cache: make(map[string]unversioned.Provider), diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/handler/cache.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/handler/cache.go index 9148a93f733..b1dd4b6625c 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/handler/cache.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/handler/cache.go @@ -31,14 +31,14 @@ type Cache interface { type NoCache struct{} -func (n NoCache) Add(relPath []string, object interface{}) error { +func (n NoCache) Add(_ []string, _ interface{}) error { return nil } -func (n NoCache) Get(relPath []string) (interface{}, error) { +func (n NoCache) Get(_ []string) (interface{}, error) { return nil, nil } -func (n NoCache) Remove(relPath []string) {} +func (n NoCache) Remove(_ []string) {} var _ Cache = NoCache{} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation/instrumentation.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation/instrumentation.go new file mode 100644 index 00000000000..7eedb77f817 --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation/instrumentation.go @@ -0,0 +1,59 @@ +// package instrumentation defines primitives to +// support more observability throughout the constraint framework. +package instrumentation + +import "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema" + +const ( + // scope constants. + + // TemplateScope means the stat is associated with a template. + TemplateScope = "template" + // ConstraintScope means the state is associated with a constraint. + ConstraintScope = "constraint" + + // description constants. + UnknownDescription = "unknown description" + + // source constants. + EngineSourceType = "engine" +) + +var RegoSource = Source{ + Type: EngineSourceType, + Value: schema.Name, +} + +// Label is a name/value tuple to add metadata +// about a StatsEntry. +type Label struct { + Name string `json:"name"` + Value interface{} `json:"value"` +} + +// Source is a special Stat level label of the form type/value +// that is meant to be used to identify where a Stat is coming from. +type Source struct { + Type string `json:"type"` + Value string `json:"value"` +} + +// Stat is a Name, Value, Description tuple that may contain +// metrics or aggregations of metrics. +type Stat struct { + Name string `json:"name"` + Value interface{} `json:"value"` + Source Source `json:"source"` +} + +// StatsEntry comprises of a generalized Key for all associated Stats. +type StatsEntry struct { + // Scope is the level of granularity that the Stats + // were created at. + Scope string `json:"scope"` + // StatsFor is the specific kind of Scope type that Stats + // were created for. + StatsFor string `json:"statsFor"` + Stats []*Stat `json:"stats"` + Labels []*Label `json:"labels,omitempty"` +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/schema/yaml_constant.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/schema/yaml_constant.go index f93fe25f0ed..b67a7deb4a8 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/schema/yaml_constant.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/schema/yaml_constant.go @@ -7,7 +7,8 @@ const constraintTemplateCRDYaml = `apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null name: constrainttemplates.templates.gatekeeper.sh spec: group: templates.gatekeeper.sh @@ -22,13 +23,18 @@ spec: - name: v1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -64,6 +70,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -80,11 +107,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -98,7 +127,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 @@ -117,13 +147,18 @@ spec: - name: v1alpha1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -159,6 +194,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -175,11 +231,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -193,7 +251,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 @@ -212,13 +271,18 @@ spec: - name: v1beta1 schema: openAPIV3Schema: - description: ConstraintTemplate is the Schema for the constrainttemplates API + description: ConstraintTemplate is the Schema for the constrainttemplates + API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -254,6 +318,27 @@ spec: targets: items: properties: + code: + description: The source code options for the constraint template. + "Rego" can only be specified in one place (either here or + in the "rego" field) + items: + properties: + engine: + description: 'The engine used to evaluate the code. Example: + "Rego". Required.' + type: string + source: + description: The source code for the template. Required. + x-kubernetes-preserve-unknown-fields: true + required: + - engine + - source + type: object + type: array + x-kubernetes-list-map-keys: + - engine + x-kubernetes-list-type: map libs: items: type: string @@ -270,11 +355,13 @@ spec: properties: byPod: items: - description: ByPodStatus defines the observed state of ConstraintTemplate as seen by an individual controller + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller properties: errors: items: - description: CreateCRDError represents a single error caught during parsing, compiling, etc. + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. properties: code: type: string @@ -288,7 +375,8 @@ spec: type: object type: array id: - description: a unique identifier for the pod that wrote the status + description: a unique identifier for the pod that wrote the + status type: string observedGeneration: format: int64 diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/types/validation.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/types/validation.go index 0c79de7e419..f6a5ea4042d 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/types/validation.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/types/validation.go @@ -6,9 +6,14 @@ import ( "strings" "github.com/davecgh/go-spew/spew" + "github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) +const ( + TracingDisabledHeader = "Trace: TRACING DISABLED" +) + type Result struct { // Target is the target this violation is for. Target string `json:"target"` @@ -23,13 +28,10 @@ type Result struct { // The enforcement action of the constraint EnforcementAction string `json:"enforcementAction,omitempty"` - - // EvaluationMeta has metadata for a Result's evaluation. - EvaluationMeta interface{} `json:"evaluationMeta,omitempty"` } // Response is a collection of Constraint violations for a particular Target. -// Each Result is for a distinct Constraint. +// Each Result represents a violation for a distinct Constraint. type Response struct { Trace *string Target string @@ -65,7 +67,16 @@ func (r *Response) TraceDump() string { b := &strings.Builder{} _, _ = fmt.Fprintf(b, "Target: %s\n", r.Target) if r.Trace == nil { - _, _ = fmt.Fprintf(b, "Trace: TRACING DISABLED\n\n") + if r.Results != nil { + // only say "Trace: TRACING DISABLED" if there are results + // otherwise, we risk to confuse consumers who see the msg + // and think that evaluation did not happen. + + // Note that if there were NO violating results AND the trace + // was turned on, then r.Trace != nil. + b.WriteString(TracingDisabledHeader) + b.WriteString("\n\n") + } } else { _, _ = fmt.Fprintf(b, "Trace:\n%s\n\n", *r.Trace) } @@ -77,14 +88,16 @@ func (r *Response) TraceDump() string { func NewResponses() *Responses { return &Responses{ - ByTarget: make(map[string]*Response), - Handled: make(map[string]bool), + ByTarget: make(map[string]*Response), + Handled: make(map[string]bool), + StatsEntries: make([]*instrumentation.StatsEntry, 0), } } type Responses struct { - ByTarget map[string]*Response - Handled map[string]bool + ByTarget map[string]*Response + Handled map[string]bool + StatsEntries []*instrumentation.StatsEntry } func (r *Responses) Results() []*Result { diff --git a/vendor/github.com/open-policy-agent/opa/ast/annotations.go b/vendor/github.com/open-policy-agent/opa/ast/annotations.go index b50635299b5..fe5e3219979 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/annotations.go +++ b/vendor/github.com/open-policy-agent/opa/ast/annotations.go @@ -11,6 +11,7 @@ import ( "sort" "strings" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/internal/deepcopy" "github.com/open-policy-agent/opa/util" ) @@ -26,7 +27,6 @@ const ( type ( // Annotations represents metadata attached to other AST nodes such as rules. Annotations struct { - Location *Location `json:"-"` Scope string `json:"scope"` Title string `json:"title,omitempty"` Entrypoint bool `json:"entrypoint,omitempty"` @@ -36,7 +36,11 @@ type ( Authors []*AuthorAnnotation `json:"authors,omitempty"` Schemas []*SchemaAnnotation `json:"schemas,omitempty"` Custom map[string]interface{} `json:"custom,omitempty"` - node Node + Location *Location `json:"location,omitempty"` + + comments []*Comment + node Node + jsonOptions astJSON.Options } // SchemaAnnotation contains a schema declaration for the document identified by the path. @@ -58,7 +62,7 @@ type ( AnnotationSet struct { byRule map[*Rule][]*Annotations - byPackage map[*Package]*Annotations + byPackage map[int]*Annotations byPath *annotationTreeNode modules []*Module // Modules this set was constructed from } @@ -69,15 +73,22 @@ type ( } AnnotationsRef struct { - Location *Location `json:"location"` // The location of the node the annotations are applied to - Path Ref `json:"path"` // The path of the node the annotations are applied to + Path Ref `json:"path"` // The path of the node the annotations are applied to Annotations *Annotations `json:"annotations,omitempty"` - node Node // The node the annotations are applied to + Location *Location `json:"location,omitempty"` // The location of the node the annotations are applied to + + jsonOptions astJSON.Options + + node Node // The node the annotations are applied to } + + AnnotationsRefSet []*AnnotationsRef + + FlatAnnotationsRefSet AnnotationsRefSet ) func (a *Annotations) String() string { - bs, _ := json.Marshal(a) + bs, _ := a.MarshalJSON() return string(bs) } @@ -91,6 +102,15 @@ func (a *Annotations) SetLoc(l *Location) { a.Location = l } +// EndLoc returns the location of this annotation's last comment line. +func (a *Annotations) EndLoc() *Location { + count := len(a.comments) + if count == 0 { + return a.Location + } + return a.comments[count-1].Location +} + // Compare returns an integer indicating if a is less than, equal to, or greater // than other. func (a *Annotations) Compare(other *Annotations) int { @@ -161,12 +181,75 @@ func (a *Annotations) GetTargetPath() Ref { } } +func (a *Annotations) setJSONOptions(opts astJSON.Options) { + a.jsonOptions = opts + if a.Location != nil { + a.Location.JSONOptions = opts + } +} + +func (a *Annotations) MarshalJSON() ([]byte, error) { + if a == nil { + return []byte(`{"scope":""}`), nil + } + + data := map[string]interface{}{ + "scope": a.Scope, + } + + if a.Title != "" { + data["title"] = a.Title + } + + if a.Description != "" { + data["description"] = a.Description + } + + if a.Entrypoint { + data["entrypoint"] = a.Entrypoint + } + + if len(a.Organizations) > 0 { + data["organizations"] = a.Organizations + } + + if len(a.RelatedResources) > 0 { + data["related_resources"] = a.RelatedResources + } + + if len(a.Authors) > 0 { + data["authors"] = a.Authors + } + + if len(a.Schemas) > 0 { + data["schemas"] = a.Schemas + } + + if len(a.Custom) > 0 { + data["custom"] = a.Custom + } + + if a.jsonOptions.MarshalOptions.IncludeLocation.Annotations { + if a.Location != nil { + data["location"] = a.Location + } + } + + return json.Marshal(data) +} + func NewAnnotationsRef(a *Annotations) *AnnotationsRef { + var loc *Location + if a.node != nil { + loc = a.node.Loc() + } + return &AnnotationsRef{ - Location: a.node.Loc(), + Location: loc, Path: a.GetTargetPath(), Annotations: a, node: a.node, + jsonOptions: a.jsonOptions, } } @@ -190,6 +273,24 @@ func (ar *AnnotationsRef) GetRule() *Rule { } } +func (ar *AnnotationsRef) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "path": ar.Path, + } + + if ar.Annotations != nil { + data["annotations"] = ar.Annotations + } + + if ar.jsonOptions.MarshalOptions.IncludeLocation.AnnotationsRef { + if ar.Location != nil { + data["location"] = ar.Location + } + } + + return json.Marshal(data) +} + func scopeCompare(s1, s2 string) int { o1 := scopeOrder(s1) @@ -462,7 +563,8 @@ func validateAnnotationScopeAttachment(a *Annotations) *Error { return newScopeAttachmentErr(a, "package") } - return NewError(ParseErr, a.Loc(), "invalid annotation scope '%v'", a.Scope) + return NewError(ParseErr, a.Loc(), "invalid annotation scope '%v'. Use one of '%s', '%s', '%s', or '%s'", + a.Scope, annotationScopeRule, annotationScopeDocument, annotationScopePackage, annotationScopeSubpackages) } func validateAnnotationEntrypointAttachment(a *Annotations) *Error { @@ -576,7 +678,7 @@ func (s *SchemaAnnotation) String() string { func newAnnotationSet() *AnnotationSet { return &AnnotationSet{ byRule: map[*Rule][]*Annotations{}, - byPackage: map[*Package]*Annotations{}, + byPackage: map[int]*Annotations{}, byPath: newAnnotationTree(), } } @@ -609,10 +711,11 @@ func (as *AnnotationSet) add(a *Annotations) *Error { } case annotationScopePackage: if pkg, ok := a.node.(*Package); ok { - if exist, ok := as.byPackage[pkg]; ok { + hash := pkg.Path.Hash() + if exist, ok := as.byPackage[hash]; ok { return errAnnotationRedeclared(a, exist.Location) } - as.byPackage[pkg] = a + as.byPackage[hash] = a } case annotationScopeDocument: if rule, ok := a.node.(*Rule); ok { @@ -663,12 +766,12 @@ func (as *AnnotationSet) GetPackageScope(pkg *Package) *Annotations { if as == nil { return nil } - return as.byPackage[pkg] + return as.byPackage[pkg.Path.Hash()] } // Flatten returns a flattened list view of this AnnotationSet. // The returned slice is sorted, first by the annotations' target path, then by their target location -func (as *AnnotationSet) Flatten() []*AnnotationsRef { +func (as *AnnotationSet) Flatten() FlatAnnotationsRefSet { // This preallocation often won't be optimal, but it's superior to starting with a nil slice. refs := make([]*AnnotationsRef, 0, len(as.byPath.Children)+len(as.byRule)+len(as.byPackage)) @@ -686,13 +789,7 @@ func (as *AnnotationSet) Flatten() []*AnnotationsRef { // Sort by path, then annotation location, for stable output sort.SliceStable(refs, func(i, j int) bool { - if refs[i].Path.Compare(refs[j].Path) < 0 { - return true - } - if refs[i].Annotations.Location.Compare(refs[j].Annotations.Location) < 0 { - return true - } - return false + return refs[i].Compare(refs[j]) < 0 }) return refs @@ -705,7 +802,7 @@ func (as *AnnotationSet) Flatten() []*AnnotationsRef { // 2. The 'package' scope entry, if any // 3. Entries for the 'subpackages' scope, if any; ordered from the closest package path to the fartest. E.g.: 'do.re.mi', 'do.re', 'do' // The returned slice is guaranteed to always contain at least one entry, corresponding to the given rule. -func (as *AnnotationSet) Chain(rule *Rule) []*AnnotationsRef { +func (as *AnnotationSet) Chain(rule *Rule) AnnotationsRefSet { var refs []*AnnotationsRef ruleAnnots := as.GetRuleScope(rule) @@ -751,6 +848,26 @@ func (as *AnnotationSet) Chain(rule *Rule) []*AnnotationsRef { return refs } +func (ars FlatAnnotationsRefSet) Insert(ar *AnnotationsRef) FlatAnnotationsRefSet { + result := make(FlatAnnotationsRefSet, 0, len(ars)+1) + + // insertion sort, first by path, then location + for i, current := range ars { + if ar.Compare(current) < 0 { + result = append(result, ar) + result = append(result, ars[i:]...) + break + } + result = append(result, current) + } + + if len(result) < len(ars)+1 { + result = append(result, ar) + } + + return result +} + func newAnnotationTree() *annotationTreeNode { return &annotationTreeNode{ Value: nil, @@ -814,3 +931,15 @@ func (t *annotationTreeNode) flatten(refs []*AnnotationsRef) []*AnnotationsRef { } return refs } + +func (ar *AnnotationsRef) Compare(other *AnnotationsRef) int { + if c := ar.Path.Compare(other.Path); c != 0 { + return c + } + + if c := ar.Annotations.Location.Compare(other.Annotations.Location); c != 0 { + return c + } + + return ar.Annotations.Compare(other.Annotations) +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/builtins.go b/vendor/github.com/open-policy-agent/opa/ast/builtins.go index 0287432e8ac..3af0d8cd906 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/ast/builtins.go @@ -136,6 +136,7 @@ var DefaultBuiltins = [...]*Builtin{ // Numbers NumbersRange, + NumbersRangeStep, RandIntn, // Encoding @@ -195,6 +196,7 @@ var DefaultBuiltins = [...]*Builtin{ ParseNanos, ParseRFC3339Nanos, ParseDurationNanos, + Format, Date, Clock, Weekday, @@ -209,10 +211,13 @@ var DefaultBuiltins = [...]*Builtin{ CryptoSha256, CryptoX509ParseCertificateRequest, CryptoX509ParseRSAPrivateKey, + CryptoX509ParseKeyPair, + CryptoParsePrivateKeys, CryptoHmacMd5, CryptoHmacSha1, CryptoHmacSha256, CryptoHmacSha512, + CryptoHmacEqual, // Graphs WalkBuiltin, @@ -243,6 +248,10 @@ var DefaultBuiltins = [...]*Builtin{ GraphQLIsValid, GraphQLSchemaIsValid, + // JSON Schema + JSONSchemaVerify, + JSONMatchSchema, + // Cloud Provider Helpers ProvidersAWSSignReqObj, @@ -277,6 +286,7 @@ var DefaultBuiltins = [...]*Builtin{ // UUIDs UUIDRFC4122, + UUIDParse, // SemVers SemVerIsValid, @@ -1339,6 +1349,23 @@ var NumbersRange = &Builtin{ ), } +var NumbersRangeStep = &Builtin{ + Name: "numbers.range_step", + Description: `Returns an array of numbers in the given (inclusive) range incremented by a positive step. + If "a==b", then "range == [a]"; if "a > b", then "range" is in descending order. + If the provided "step" is less then 1, an error will be thrown. + If "b" is not in the range of the provided "step", "b" won't be included in the result. + `, + Decl: types.NewFunction( + types.Args( + types.Named("a", types.N), + types.Named("b", types.N), + types.Named("step", types.N), + ), + types.Named("range", types.NewArray(nil, types.N)).Description("the range between `a` and `b` in `step` increments"), + ), +} + /** * Units */ @@ -1392,6 +1419,19 @@ var UUIDRFC4122 = &Builtin{ Nondeterministic: true, } +var UUIDParse = &Builtin{ + Name: "uuid.parse", + Description: "Parses the string value as an UUID and returns an object with the well-defined fields of the UUID if valid.", + Categories: nil, + Decl: types.NewFunction( + types.Args( + types.Named("uuid", types.S), + ), + types.Named("result", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))).Description("Properties of UUID if valid (version, variant, etc). Undefined otherwise."), + ), + Relation: false, +} + /** * JSON */ @@ -2144,6 +2184,21 @@ var ParseDurationNanos = &Builtin{ ), } +var Format = &Builtin{ + Name: "time.format", + Description: "Returns the formatted timestamp for the nanoseconds since epoch.", + Decl: types.NewFunction( + types.Args( + types.Named("x", types.NewAny( + types.N, + types.NewArray([]types.Type{types.N, types.S}, nil), + types.NewArray([]types.Type{types.N, types.S, types.S}, nil), + )).Description("a number representing the nanoseconds since the epoch (UTC); or a two-element array of the nanoseconds, and a timezone string; or a three-element array of ns, timezone string and a layout string or golang defined formatting constant (see golang supported time formats)"), + ), + types.Named("formatted timestamp", types.S).Description("the formatted timestamp represented for the nanoseconds since the epoch in the supplied timezone (or UTC)"), + ), +} + var Date = &Builtin{ Name: "time.date", Description: "Returns the `[year, month, day]` for the nanoseconds since epoch.", @@ -2189,7 +2244,7 @@ var Weekday = &Builtin{ var AddDate = &Builtin{ Name: "time.add_date", - Description: "Returns the nanoseconds since epoch after adding years, months and days to nanoseconds. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", + Description: "Returns the nanoseconds since epoch after adding years, months and days to nanoseconds. Month & day values outside their usual ranges after the operation and will be normalized - for example, October 32 would become November 1. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", Decl: types.NewFunction( types.Args( types.Named("ns", types.N).Description("nanoseconds since the epoch"), @@ -2224,8 +2279,12 @@ var Diff = &Builtin{ */ var CryptoX509ParseCertificates = &Builtin{ - Name: "crypto.x509.parse_certificates", - Description: "Returns one or more certificates from the given base64 encoded string containing DER encoded certificates that have been concatenated.", + Name: "crypto.x509.parse_certificates", + Description: `Returns zero or more certificates from the given encoded string containing +DER certificate data. + +If the input is empty, the function will return null. The input string should be a list of one or more +concatenated PEM blocks. The whole input of concatenated PEM blocks can optionally be Base64 encoded.`, Decl: types.NewFunction( types.Args( types.Named("certs", types.S).Description("base64 encoded DER or PEM data containing one or more certificates or a PEM string of one or more certificates"), @@ -2264,6 +2323,17 @@ var CryptoX509ParseCertificateRequest = &Builtin{ ), } +var CryptoX509ParseKeyPair = &Builtin{ + Name: "crypto.x509.parse_keypair", + Description: "Returns a valid key pair", + Decl: types.NewFunction( + types.Args( + types.Named("cert", types.S).Description("string containing PEM or base64 encoded DER certificates"), + types.Named("pem", types.S).Description("string containing PEM or base64 encoded DER keys"), + ), + types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))).Description("if key pair is valid, returns the tls.certificate(https://pkg.go.dev/crypto/tls#Certificate) as an object. If the key pair is invalid, nil and an error are returned."), + ), +} var CryptoX509ParseRSAPrivateKey = &Builtin{ Name: "crypto.x509.parse_rsa_private_key", Description: "Returns a JWK for signing a JWT from the given PEM-encoded RSA private key.", @@ -2275,6 +2345,19 @@ var CryptoX509ParseRSAPrivateKey = &Builtin{ ), } +var CryptoParsePrivateKeys = &Builtin{ + Name: "crypto.parse_private_keys", + Description: `Returns zero or more private keys from the given encoded string containing DER certificate data. + +If the input is empty, the function will return null. The input string should be a list of one or more concatenated PEM blocks. The whole input of concatenated PEM blocks can optionally be Base64 encoded.`, + Decl: types.NewFunction( + types.Args( + types.Named("keys", types.S).Description("PEM encoded data containing one or more private keys as concatenated blocks. Optionally Base64 encoded."), + ), + types.Named("output", types.NewArray(nil, types.NewObject(nil, types.NewDynamicProperty(types.S, types.A)))).Description("parsed private keys represented as objects"), + ), +} + var CryptoMd5 = &Builtin{ Name: "crypto.md5", Description: "Returns a string representing the input string hashed with the MD5 function", @@ -2356,6 +2439,18 @@ var CryptoHmacSha512 = &Builtin{ ), } +var CryptoHmacEqual = &Builtin{ + Name: "crypto.hmac.equal", + Description: "Returns a boolean representing the result of comparing two MACs for equality without leaking timing information.", + Decl: types.NewFunction( + types.Args( + types.Named("mac1", types.S).Description("mac1 to compare"), + types.Named("mac2", types.S).Description("mac2 to compare"), + ), + types.Named("result", types.B).Description("`true` if the MACs are equals, `false` otherwise"), + ), +} + /** * Graphs. */ @@ -2633,6 +2728,60 @@ var GraphQLSchemaIsValid = &Builtin{ ), } +/** + * JSON Schema + */ + +// JSONSchemaVerify returns empty string if the input is valid JSON schema +// and returns error string for all other inputs. +var JSONSchemaVerify = &Builtin{ + Name: "json.verify_schema", + Description: "Checks that the input is a valid JSON schema object. The schema can be either a JSON string or an JSON object.", + Decl: types.NewFunction( + types.Args( + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the schema to verify"), + ), + types.Named("output", types.NewArray([]types.Type{ + types.B, + types.NewAny(types.S, types.Null{}), + }, nil)). + Description("`output` is of the form `[valid, error]`. If the schema is valid, then `valid` is `true`, and `error` is `null`. Otherwise, `valid` is `false` and `error` is a string describing the error."), + ), + Categories: objectCat, +} + +// JSONMatchSchema returns empty array if the document matches the JSON schema, +// and returns non-empty array with error objects otherwise. +var JSONMatchSchema = &Builtin{ + Name: "json.match_schema", + Description: "Checks that the document matches the JSON schema.", + Decl: types.NewFunction( + types.Args( + types.Named("document", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("document to verify by schema"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("schema to verify document by"), + ), + types.Named("output", types.NewArray([]types.Type{ + types.B, + types.NewArray( + nil, types.NewObject( + []*types.StaticProperty{ + {Key: "error", Value: types.S}, + {Key: "type", Value: types.S}, + {Key: "field", Value: types.S}, + {Key: "desc", Value: types.S}, + }, + nil, + ), + ), + }, nil)). + Description("`output` is of the form `[match, errors]`. If the document is valid given the schema, then `match` is `true`, and `errors` is an empty array. Otherwise, `match` is `false` and `errors` is an array of objects describing the error(s)."), + ), + Categories: objectCat, +} + /** * Cloud Provider Helper Functions */ diff --git a/vendor/github.com/open-policy-agent/opa/ast/check.go b/vendor/github.com/open-policy-agent/opa/ast/check.go index b671e829990..73eacfacd2f 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/check.go +++ b/vendor/github.com/open-policy-agent/opa/ast/check.go @@ -177,24 +177,26 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { env = env.wrap() - if schemaAnnots := getRuleAnnotation(as, rule); schemaAnnots != nil { - for _, schemaAnnot := range schemaAnnots { - ref, refType, err := processAnnotation(tc.ss, schemaAnnot, rule, tc.allowNet) + schemaAnnots := getRuleAnnotation(as, rule) + for _, schemaAnnot := range schemaAnnots { + ref, refType, err := processAnnotation(tc.ss, schemaAnnot, rule, tc.allowNet) + if err != nil { + tc.err([]*Error{err}) + continue + } + if ref == nil && refType == nil { + continue + } + prefixRef, t := getPrefix(env, ref) + if t == nil || len(prefixRef) == len(ref) { + env.tree.Put(ref, refType) + } else { + newType, err := override(ref[len(prefixRef):], t, refType, rule) if err != nil { tc.err([]*Error{err}) continue } - prefixRef, t := getPrefix(env, ref) - if t == nil || len(prefixRef) == len(ref) { - env.tree.Put(ref, refType) - } else { - newType, err := override(ref[len(prefixRef):], t, refType, rule) - if err != nil { - tc.err([]*Error{err}) - continue - } - env.tree.Put(prefixRef, newType) - } + env.tree.Put(prefixRef, newType) } } @@ -213,7 +215,6 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { var tpe types.Type if len(rule.Head.Args) > 0 { - // If args are not referred to in body, infer as any. WalkVars(rule.Head.Args, func(v Var) bool { if cpy.Get(v) == nil { @@ -230,47 +231,66 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { f := types.NewFunction(args, cpy.Get(rule.Head.Value)) - // Union with existing. - exist := env.tree.Get(path) - tpe = types.Or(exist, f) - + tpe = f } else { switch rule.Head.RuleKind() { case SingleValue: typeV := cpy.Get(rule.Head.Value) - if last := path[len(path)-1]; !last.IsGround() { - - // e.g. store object[string: whatever] at data.p.q.r, not data.p.q.r[x] + if !path.IsGround() { + // e.g. store object[string: whatever] at data.p.q.r, not data.p.q.r[x] or data.p.q.r[x].y[z] + objPath := path.DynamicSuffix() path = path.GroundPrefix() - typeK := cpy.Get(last) - if typeK != nil && typeV != nil { - exist := env.tree.Get(path) - typeV = types.Or(types.Values(exist), typeV) - typeK = types.Or(types.Keys(exist), typeK) - tpe = types.NewObject(nil, types.NewDynamicProperty(typeK, typeV)) + var err error + tpe, err = nestedObject(cpy, objPath, typeV) + if err != nil { + tc.err([]*Error{NewError(TypeErr, rule.Head.Location, err.Error())}) + tpe = nil } } else { if typeV != nil { - exist := env.tree.Get(path) - tpe = types.Or(typeV, exist) + tpe = typeV } } case MultiValue: typeK := cpy.Get(rule.Head.Key) if typeK != nil { - exist := env.tree.Get(path) - typeK = types.Or(types.Keys(exist), typeK) tpe = types.NewSet(typeK) } } } if tpe != nil { - env.tree.Put(path, tpe) + env.tree.Insert(path, tpe, env) } } +// nestedObject creates a nested structure of object types, where each term on path corresponds to a level in the +// nesting. Each term in the path only contributes to the dynamic portion of its corresponding object. +func nestedObject(env *TypeEnv, path Ref, tpe types.Type) (types.Type, error) { + if len(path) == 0 { + return tpe, nil + } + + k := path[0] + typeV, err := nestedObject(env, path[1:], tpe) + if err != nil { + return nil, err + } + if typeV == nil { + return nil, nil + } + + var dynamicProperty *types.DynamicProperty + typeK := env.Get(k) + if typeK == nil { + return nil, nil + } + dynamicProperty = types.NewDynamicProperty(typeK, typeV) + + return types.NewObject(nil, dynamicProperty), nil +} + func (tc *typeChecker) checkExpr(env *TypeEnv, expr *Expr) *Error { if err := tc.checkExprWith(env, expr, 0); err != nil { return err @@ -1214,6 +1234,9 @@ func processAnnotation(ss *SchemaSet, annot *SchemaAnnotation, rule *Rule, allow var schema interface{} if annot.Schema != nil { + if ss == nil { + return nil, nil, nil + } schema = ss.Get(annot.Schema) if schema == nil { return nil, nil, NewError(TypeErr, rule.Location, "undefined schema: %v", annot.Schema) diff --git a/vendor/github.com/open-policy-agent/opa/ast/compile.go b/vendor/github.com/open-policy-agent/opa/ast/compile.go index e2f52bdbaa0..b577d9e47da 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/compile.go +++ b/vendor/github.com/open-policy-agent/opa/ast/compile.go @@ -81,6 +81,28 @@ type Compiler struct { // +--- b // | // +--- c (1 rule) + // + // Another example with general refs containing vars at arbitrary locations: + // + // package ex + // a.b[x].d { x := "c" } # R1 + // a.b.c[x] { x := "d" } # R2 + // a.b[x][y] { x := "c"; y := "d" } # R3 + // p := true # R4 + // + // root + // | + // +--- data (no rules) + // | + // +--- ex (no rules) + // | + // +--- a + // | | + // | +--- b (R1, R3) + // | | + // | +--- c (R2) + // | + // +--- p (R4) RuleTree *TreeNode // Graph contains dependencies between rules. An edge (u,v) is added to the @@ -102,26 +124,27 @@ type Compiler struct { metricName string f func() } - maxErrs int - sorted []string // list of sorted module names - pathExists func([]string) (bool, error) - after map[string][]CompilerStageDefinition - metrics metrics.Metrics - capabilities *Capabilities // user-supplied capabilities - builtins map[string]*Builtin // universe of built-in functions - customBuiltins map[string]*Builtin // user-supplied custom built-in functions (deprecated: use capabilities) - unsafeBuiltinsMap map[string]struct{} // user-supplied set of unsafe built-ins functions to block (deprecated: use capabilities) - deprecatedBuiltinsMap map[string]struct{} // set of deprecated, but not removed, built-in functions - enablePrintStatements bool // indicates if print statements should be elided (default) - comprehensionIndices map[*Term]*ComprehensionIndex // comprehension key index - initialized bool // indicates if init() has been called - debug debug.Debug // emits debug information produced during compilation - schemaSet *SchemaSet // user-supplied schemas for input and data documents - inputType types.Type // global input type retrieved from schema set - annotationSet *AnnotationSet // hierarchical set of annotations - strict bool // enforce strict compilation checks - keepModules bool // whether to keep the unprocessed, parse modules (below) - parsedModules map[string]*Module // parsed, but otherwise unprocessed modules, kept track of when keepModules is true + maxErrs int + sorted []string // list of sorted module names + pathExists func([]string) (bool, error) + after map[string][]CompilerStageDefinition + metrics metrics.Metrics + capabilities *Capabilities // user-supplied capabilities + builtins map[string]*Builtin // universe of built-in functions + customBuiltins map[string]*Builtin // user-supplied custom built-in functions (deprecated: use capabilities) + unsafeBuiltinsMap map[string]struct{} // user-supplied set of unsafe built-ins functions to block (deprecated: use capabilities) + deprecatedBuiltinsMap map[string]struct{} // set of deprecated, but not removed, built-in functions + enablePrintStatements bool // indicates if print statements should be elided (default) + comprehensionIndices map[*Term]*ComprehensionIndex // comprehension key index + initialized bool // indicates if init() has been called + debug debug.Debug // emits debug information produced during compilation + schemaSet *SchemaSet // user-supplied schemas for input and data documents + inputType types.Type // global input type retrieved from schema set + annotationSet *AnnotationSet // hierarchical set of annotations + strict bool // enforce strict compilation checks + keepModules bool // whether to keep the unprocessed, parse modules (below) + parsedModules map[string]*Module // parsed, but otherwise unprocessed modules, kept track of when keepModules is true + useTypeCheckAnnotations bool // whether to provide annotated information (schemas) to the type checker } // CompilerStage defines the interface for stages in the compiler. @@ -407,6 +430,12 @@ func (c *Compiler) WithKeepModules(y bool) *Compiler { return c } +// WithUseTypeCheckAnnotations use schema annotations during type checking +func (c *Compiler) WithUseTypeCheckAnnotations(enabled bool) *Compiler { + c.useTypeCheckAnnotations = enabled + return c +} + // ParsedModules returns the parsed, unprocessed modules from the compiler. // It is `nil` if keeping modules wasn't enabled via `WithKeepModules(true)`. // The map includes all modules loaded via the ModuleLoader, if one was used. @@ -691,15 +720,15 @@ func (c *Compiler) GetRulesDynamicWithOpts(ref Ref, opts RulesOptions) []*Rule { // The head of the ref is always grounded. In case another part of the // ref is also grounded, we can lookup the exact child. If it's not found // we can immediately return... - if child := node.Child(ref[i].Value); child == nil { - return - } else if len(child.Values) > 0 { - // If there are any rules at this position, it's what the ref would - // refer to. We can just append those and stop here. - insertRules(set, child.Values) - } else { - // Otherwise, we continue using the child node. + if child := node.Child(ref[i].Value); child != nil { + if len(child.Values) > 0 { + // Add any rules at this position + insertRules(set, child.Values) + } + // There might still be "sub-rules" contributing key-value "overrides" for e.g. partial object rules, continue walking walk(child, i+1) + } else { + return } default: @@ -750,6 +779,60 @@ func (c *Compiler) PassesTypeCheck(body Body) bool { return len(errs) == 0 } +// PassesTypeCheckRules determines whether the given rules passes type checking +func (c *Compiler) PassesTypeCheckRules(rules []*Rule) Errors { + elems := []util.T{} + + for _, rule := range rules { + elems = append(elems, rule) + } + + // Load the global input schema if one was provided. + if c.schemaSet != nil { + if schema := c.schemaSet.Get(SchemaRootRef); schema != nil { + + var allowNet []string + if c.capabilities != nil { + allowNet = c.capabilities.AllowNet + } + + tpe, err := loadSchema(schema, allowNet) + if err != nil { + return Errors{NewError(TypeErr, nil, err.Error())} + } + c.inputType = tpe + } + } + + var as *AnnotationSet + if c.useTypeCheckAnnotations { + as = c.annotationSet + } + + checker := newTypeChecker().WithSchemaSet(c.schemaSet).WithInputType(c.inputType) + + if c.TypeEnv == nil { + if c.capabilities == nil { + c.capabilities = CapabilitiesForThisVersion() + } + + c.builtins = make(map[string]*Builtin, len(c.capabilities.Builtins)+len(c.customBuiltins)) + + for _, bi := range c.capabilities.Builtins { + c.builtins[bi.Name] = bi + } + + for name, bi := range c.customBuiltins { + c.builtins[name] = bi + } + + c.TypeEnv = checker.Env(c.builtins) + } + + _, errs := checker.CheckTypes(c.TypeEnv, elems, as) + return errs +} + // ModuleLoader defines the interface that callers can implement to enable lazy // loading of modules during compilation. type ModuleLoader func(resolved map[string]*Module) (parsed map[string]*Module, err error) @@ -781,19 +864,23 @@ func (c *Compiler) buildRuleIndices() { return false } rules := extractRules(node.Values) - hasNonGroundKey := false + hasNonGroundRef := false for _, r := range rules { - if ref := r.Head.Ref(); len(ref) > 1 { - if !ref[len(ref)-1].IsGround() { - hasNonGroundKey = true - } - } + hasNonGroundRef = !r.Head.Ref().IsGround() } - if hasNonGroundKey { - // collect children: as of now, this cannot go deeper than one level, - // so we grab those, and abort the DepthFirst processing for this branch - for _, n := range node.Children { - rules = append(rules, extractRules(n.Values)...) + if hasNonGroundRef { + // Collect children to ensure that all rules within the extent of a rule with a general ref + // are found on the same index. E.g. the following rules should be indexed under data.a.b.c: + // + // package a + // b.c[x].e := 1 { x := input.x } + // b.c.d := 2 + // b.c.d2.e[x] := 3 { x := input.x } + for _, child := range node.Children { + child.DepthFirst(func(c *TreeNode) bool { + rules = append(rules, extractRules(c.Values)...) + return false + }) } } @@ -803,7 +890,7 @@ func (c *Compiler) buildRuleIndices() { if index.Build(rules) { c.ruleIndices.Put(rules[0].Ref().GroundPrefix(), index) } - return hasNonGroundKey // currently, we don't allow those branches to go deeper + return hasNonGroundRef // currently, we don't allow those branches to go deeper }) } @@ -861,11 +948,13 @@ func (c *Compiler) checkRuleConflicts() { return false // go deeper } - kinds := map[RuleKind]struct{}{} + kinds := make(map[RuleKind]struct{}, len(node.Values)) defaultRules := 0 - arities := map[int]struct{}{} + completeRules := 0 + partialRules := 0 + arities := make(map[int]struct{}, len(node.Values)) name := "" - var singleValueConflicts []Ref + var conflicts []Ref for _, rule := range node.Values { r := rule.(*Rule) @@ -877,37 +966,57 @@ func (c *Compiler) checkRuleConflicts() { defaultRules++ } - // Single-value rules may not have any other rules in their extent: these pairs are invalid: + // Single-value rules may not have any other rules in their extent. + // Rules with vars in their ref are allowed to have rules inside their extent. + // Only the ground portion (terms before the first var term) of a rule's ref is considered when determining + // whether it's inside the extent of another (c.RuleTree is organized this way already). + // These pairs are invalid: // // data.p.q.r { true } # data.p.q is { "r": true } // data.p.q.r.s { true } // - // data.p.q[r] { r := input.r } # data.p.q could be { "r": true } - // data.p.q.r.s { true } - + // data.p.q.r { true } + // data.p.q.r[s].t { s = input.key } + // // But this is allowed: + // + // data.p.q.r { true } + // data.p.q[r].s.t { r = input.key } + // + // data.p[r] := x { r = input.key; x = input.bar } + // data.p.q[r] := x { r = input.key; x = input.bar } + // + // data.p.q[r] { r := input.r } + // data.p.q.r.s { true } + // // data.p.q[r] = 1 { r := "r" } // data.p.q.s = 2 + // + // data.p[q][r] { q := input.q; r := input.r } + // data.p.q.r { true } + // + // data.p.q[r] { r := input.r } + // data.p[q].r { q := input.q } + // + // data.p.q[r][s] { r := input.r; s := input.s } + // data.p[q].r.s { q := input.q } - if r.Head.RuleKind() == SingleValue && len(node.Children) > 0 { - if len(ref) > 1 && !ref[len(ref)-1].IsGround() { // p.q[x] and p.q.s.t => check grandchildren - for _, c := range node.Children { - if len(c.Children) > 0 { - singleValueConflicts = node.flattenChildren() - break - } - } - } else { // p.q.s and p.q.s.t => any children are in conflict - singleValueConflicts = node.flattenChildren() - } + if r.Ref().IsGround() && len(node.Children) > 0 { + conflicts = node.flattenChildren() + } + + if r.Head.RuleKind() == SingleValue && r.Head.Ref().IsGround() { + completeRules++ + } else { + partialRules++ } } switch { - case singleValueConflicts != nil: - c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "single-value rule %v conflicts with %v", name, singleValueConflicts)) + case conflicts != nil: + c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "rule %v conflicts with %v", name, conflicts)) - case len(kinds) > 1 || len(arities) > 1: + case len(kinds) > 1 || len(arities) > 1 || (completeRules >= 1 && partialRules >= 1): c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "conflicting rules %v found", name)) case defaultRules > 1: @@ -929,15 +1038,14 @@ func (c *Compiler) checkRuleConflicts() { for _, rule := range mod.Rules { ref := rule.Head.Ref().GroundPrefix() childNode, tail := node.find(ref) - if childNode != nil { + if childNode != nil && len(tail) == 0 { for _, childMod := range childNode.Modules { + // Avoid recursively checking a module for equality unless we know it's a possible self-match. if childMod.Equal(mod) { continue // don't self-conflict } - if len(tail) == 0 { - msg := fmt.Sprintf("%v conflicts with rule %v defined at %v", childMod.Package, rule.Head.Ref(), rule.Loc()) - c.err(NewError(TypeErr, mod.Package.Loc(), msg)) - } + msg := fmt.Sprintf("%v conflicts with rule %v defined at %v", childMod.Package, rule.Head.Ref(), rule.Loc()) + c.err(NewError(TypeErr, mod.Package.Loc(), msg)) } } } @@ -1302,10 +1410,15 @@ func (c *Compiler) checkTypes() { // Recursion is caught in earlier step, so this cannot fail. sorted, _ := c.Graph.Sort() checker := newTypeChecker(). + WithAllowNet(c.capabilities.AllowNet). WithSchemaSet(c.schemaSet). WithInputType(c.inputType). WithVarRewriter(rewriteVarsInRef(c.RewrittenVars)) - env, errs := checker.CheckTypes(c.TypeEnv, sorted, c.annotationSet) + var as *AnnotationSet + if c.useTypeCheckAnnotations { + as = c.annotationSet + } + env, errs := checker.CheckTypes(c.TypeEnv, sorted, as) for _, err := range errs { c.err(err) } @@ -1652,19 +1765,6 @@ func (c *Compiler) rewriteRuleHeadRefs() { } for i := 1; i < len(ref); i++ { - // NOTE(sr): In the first iteration, non-string values in the refs are forbidden - // except for the last position, e.g. - // OK: p.q.r[s] - // NOT OK: p[q].r.s - // TODO(sr): This is stricter than necessary. We could allow any non-var values there, - // but we'll also have to adjust the type tree, for example. - if i != len(ref)-1 { // last - if _, ok := ref[i].Value.(String); !ok { - c.err(NewError(TypeErr, rule.Loc(), "rule head must only contain string terms (except for last): %v", ref[i])) - continue - } - } - // Rewrite so that any non-scalar elements that in the last position of // the rule are vars: // p.q.r[y.z] { ... } => p.q.r[__local0__] { __local0__ = y.z } @@ -1879,7 +1979,7 @@ func isPrintCall(x *Expr) bool { return x.IsCall() && x.Operator().Equal(Print.Ref()) } -// rewriteTermsInHead will rewrite rules so that the head does not contain any +// rewriteRefsInHead will rewrite rules so that the head does not contain any // terms that require evaluation (e.g., refs or comprehensions). If the key or // value contains one or more of these terms, the key or value will be moved // into the body and assigned to a new variable. The new variable will replace @@ -2160,81 +2260,121 @@ func (c *Compiler) rewriteLocalVars() { gen := c.localvargen WalkRules(mod, func(rule *Rule) bool { + argsStack := newLocalDeclaredVars() - // Rewrite assignments contained in head of rule. Assignments can - // occur in rule head if they're inside a comprehension. Note, - // assigned vars in comprehensions in the head will be rewritten - // first to preserve scoping rules. For example: - // - // p = [x | x := 1] { x := 2 } becomes p = [__local0__ | __local0__ = 1] { __local1__ = 2 } - // - // This behaviour is consistent scoping inside the body. For example: - // - // p = xs { x := 2; xs = [x | x := 1] } becomes p = xs { __local0__ = 2; xs = [__local1__ | __local1__ = 1] } - nestedXform := &rewriteNestedHeadVarLocalTransform{ - gen: gen, - RewrittenVars: c.RewrittenVars, - strict: c.strict, + args := NewVarVisitor() + if c.strict { + args.Walk(rule.Head.Args) } + unusedArgs := args.Vars() - NewGenericVisitor(nestedXform.Visit).Walk(rule.Head) + c.rewriteLocalArgVars(gen, argsStack, rule) - for _, err := range nestedXform.errs { - c.err(err) - } + // Rewrite local vars in each else-branch of the rule. + // Note: this is done instead of a walk so that we can capture any unused function arguments + // across else-branches. + for rule := rule; rule != nil; rule = rule.Else { + stack, errs := c.rewriteLocalVarsInRule(rule, unusedArgs, argsStack, gen) - // Rewrite assignments in body. - used := NewVarSet() - - last := rule.Head.Ref()[len(rule.Head.Ref())-1] - used.Update(last.Vars()) + for arg := range unusedArgs { + if stack.Count(arg) > 1 { + delete(unusedArgs, arg) + } + } - if rule.Head.Key != nil { - used.Update(rule.Head.Key.Vars()) + for _, err := range errs { + c.err(err) + } } - if rule.Head.Value != nil { - used.Update(rule.Head.Value.Vars()) + if c.strict { + // Report an error for each unused function argument + for arg := range unusedArgs { + if !arg.IsWildcard() { + c.err(NewError(CompileErr, rule.Head.Location, "unused argument %v. (hint: use _ (wildcard variable) instead)", arg)) + } + } } - stack := newLocalDeclaredVars() + return true + }) + } +} - c.rewriteLocalArgVars(gen, stack, rule) +func (c *Compiler) rewriteLocalVarsInRule(rule *Rule, unusedArgs VarSet, argsStack *localDeclaredVars, gen *localVarGenerator) (*localDeclaredVars, Errors) { + // Rewrite assignments contained in head of rule. Assignments can + // occur in rule head if they're inside a comprehension. Note, + // assigned vars in comprehensions in the head will be rewritten + // first to preserve scoping rules. For example: + // + // p = [x | x := 1] { x := 2 } becomes p = [__local0__ | __local0__ = 1] { __local1__ = 2 } + // + // This behaviour is consistent scoping inside the body. For example: + // + // p = xs { x := 2; xs = [x | x := 1] } becomes p = xs { __local0__ = 2; xs = [__local1__ | __local1__ = 1] } + nestedXform := &rewriteNestedHeadVarLocalTransform{ + gen: gen, + RewrittenVars: c.RewrittenVars, + strict: c.strict, + } - body, declared, errs := rewriteLocalVars(gen, stack, used, rule.Body, c.strict) - for _, err := range errs { - c.err(err) - } + NewGenericVisitor(nestedXform.Visit).Walk(rule.Head) - // For rewritten vars use the collection of all variables that - // were in the stack at some point in time. - for k, v := range stack.rewritten { - c.RewrittenVars[k] = v - } + for _, err := range nestedXform.errs { + c.err(err) + } - rule.Body = body + // Rewrite assignments in body. + used := NewVarSet() - // Rewrite vars in head that refer to locally declared vars in the body. - localXform := rewriteHeadVarLocalTransform{declared: declared} + for _, t := range rule.Head.Ref()[1:] { + used.Update(t.Vars()) + } - for i := range rule.Head.Args { - rule.Head.Args[i], _ = transformTerm(localXform, rule.Head.Args[i]) - } + if rule.Head.Key != nil { + used.Update(rule.Head.Key.Vars()) + } - for i := 1; i < len(rule.Head.Ref()); i++ { - rule.Head.Reference[i], _ = transformTerm(localXform, rule.Head.Ref()[i]) - } - if rule.Head.Key != nil { - rule.Head.Key, _ = transformTerm(localXform, rule.Head.Key) + if rule.Head.Value != nil { + valueVars := rule.Head.Value.Vars() + used.Update(valueVars) + for arg := range unusedArgs { + if valueVars.Contains(arg) { + delete(unusedArgs, arg) } + } + } - if rule.Head.Value != nil { - rule.Head.Value, _ = transformTerm(localXform, rule.Head.Value) - } + stack := argsStack.Copy() - return false - }) + body, declared, errs := rewriteLocalVars(gen, stack, used, rule.Body, c.strict) + + // For rewritten vars use the collection of all variables that + // were in the stack at some point in time. + for k, v := range stack.rewritten { + c.RewrittenVars[k] = v + } + + rule.Body = body + + // Rewrite vars in head that refer to locally declared vars in the body. + localXform := rewriteHeadVarLocalTransform{declared: declared} + + for i := range rule.Head.Args { + rule.Head.Args[i], _ = transformTerm(localXform, rule.Head.Args[i]) + } + + for i := 1; i < len(rule.Head.Ref()); i++ { + rule.Head.Reference[i], _ = transformTerm(localXform, rule.Head.Ref()[i]) + } + if rule.Head.Key != nil { + rule.Head.Key, _ = transformTerm(localXform, rule.Head.Key) + } + + if rule.Head.Value != nil { + rule.Head.Value, _ = transformTerm(localXform, rule.Head.Value) } + return stack, errs } type rewriteNestedHeadVarLocalTransform struct { @@ -3133,6 +3273,10 @@ func (n *TreeNode) Find(ref Ref) *TreeNode { return node } +// Iteratively dereferences ref along the node's subtree. +// - If matching fails immediately, the tail will contain the full ref. +// - Partial matching will result in a tail of non-zero length. +// - A complete match will result in a 0 length tail. func (n *TreeNode) find(ref Ref) (*TreeNode, Ref) { node := n for i := range ref { @@ -4592,6 +4736,35 @@ func newLocalDeclaredVars() *localDeclaredVars { } } +func (s *localDeclaredVars) Copy() *localDeclaredVars { + stack := &localDeclaredVars{ + vars: []*declaredVarSet{}, + rewritten: map[Var]Var{}, + } + + for i := range s.vars { + stack.vars = append(stack.vars, newDeclaredVarSet()) + for k, v := range s.vars[i].vs { + stack.vars[0].vs[k] = v + } + for k, v := range s.vars[i].reverse { + stack.vars[0].reverse[k] = v + } + for k, v := range s.vars[i].count { + stack.vars[0].count[k] = v + } + for k, v := range s.vars[i].occurrence { + stack.vars[0].occurrence[k] = v + } + } + + for k, v := range s.rewritten { + stack.rewritten[k] = v + } + + return stack +} + func (s *localDeclaredVars) Push() { s.vars = append(s.vars, newDeclaredVarSet()) } @@ -4686,7 +4859,7 @@ func (s localDeclaredVars) Count(x Var) int { func rewriteLocalVars(g *localVarGenerator, stack *localDeclaredVars, used VarSet, body Body, strict bool) (Body, map[Var]Var, Errors) { var errs Errors body, errs = rewriteDeclaredVarsInBody(g, stack, used, body, errs, strict) - return body, stack.Pop().vs, errs + return body, stack.Peek().vs, errs } func rewriteDeclaredVarsInBody(g *localVarGenerator, stack *localDeclaredVars, used VarSet, body Body, errs Errors, strict bool) (Body, Errors) { @@ -4717,11 +4890,11 @@ func rewriteDeclaredVarsInBody(g *localVarGenerator, stack *localDeclaredVars, u cpy.Append(NewExpr(BooleanTerm(true))) } - errs = checkUnusedAssignedVars(body[0].Loc(), stack, used, errs, strict) + errs = checkUnusedAssignedVars(body, stack, used, errs, strict) return cpy, checkUnusedDeclaredVars(body, stack, used, cpy, errs) } -func checkUnusedAssignedVars(loc *Location, stack *localDeclaredVars, used VarSet, errs Errors, strict bool) Errors { +func checkUnusedAssignedVars(body Body, stack *localDeclaredVars, used VarSet, errs Errors, strict bool) Errors { if !strict || len(errs) > 0 { return errs @@ -4733,7 +4906,7 @@ func checkUnusedAssignedVars(loc *Location, stack *localDeclaredVars, used VarSe for v, occ := range dvs.occurrence { // A var that was assigned in this scope must have been seen (used) more than once (the time of assignment) in // the same, or nested, scope to be counted as used. - if !v.IsWildcard() && occ == assignedVar && stack.Count(v) <= 1 { + if !v.IsWildcard() && stack.Count(v) <= 1 && occ == assignedVar { unused.Add(dvs.vs[v]) } } @@ -4750,7 +4923,17 @@ func checkUnusedAssignedVars(loc *Location, stack *localDeclaredVars, used VarSe unused = unused.Diff(rewrittenUsed) for _, gv := range unused.Sorted() { - errs = append(errs, NewError(CompileErr, loc, "assigned var %v unused", dvs.reverse[gv])) + found := false + for i := range body { + if body[i].Vars(VarVisitorParams{}).Contains(gv) { + errs = append(errs, NewError(CompileErr, body[i].Loc(), "assigned var %v unused", dvs.reverse[gv])) + found = true + break + } + } + if !found { + errs = append(errs, NewError(CompileErr, body[0].Loc(), "assigned var %v unused", dvs.reverse[gv])) + } } return errs diff --git a/vendor/github.com/open-policy-agent/opa/ast/env.go b/vendor/github.com/open-policy-agent/opa/ast/env.go index e3a4e442843..784a34c0470 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/env.go +++ b/vendor/github.com/open-policy-agent/opa/ast/env.go @@ -6,6 +6,7 @@ package ast import ( "fmt" + "strings" "github.com/open-policy-agent/opa/types" "github.com/open-policy-agent/opa/util" @@ -171,6 +172,11 @@ func (env *TypeEnv) getRefRec(node *typeTreeNode, ref, tail Ref) types.Type { } if node.Leaf() { + if node.children.Len() > 0 { + if child := node.Child(tail[0].Value); child != nil { + return env.getRefRec(child, ref, tail[1:]) + } + } return selectRef(node.Value(), tail) } @@ -304,6 +310,187 @@ func (n *typeTreeNode) Put(path Ref, tpe types.Type) { curr.value = tpe } +// Insert inserts tpe at path in the tree, but also merges the value into any types.Object present along that path. +// If a types.Object is inserted, any leafs already present further down the tree are merged into the inserted object. +// path must be ground. +func (n *typeTreeNode) Insert(path Ref, tpe types.Type, env *TypeEnv) { + curr := n + for i, term := range path { + c, ok := curr.children.Get(term.Value) + + var child *typeTreeNode + if !ok { + child = newTypeTree() + child.key = term.Value + curr.children.Put(child.key, child) + } else { + child = c.(*typeTreeNode) + + if child.value != nil && i+1 < len(path) { + // If child has an object value, merge the new value into it. + if o, ok := child.value.(*types.Object); ok { + var err error + child.value, err = insertIntoObject(o, path[i+1:], tpe, env) + if err != nil { + panic(fmt.Errorf("unreachable, insertIntoObject: %w", err)) + } + } + } + } + + curr = child + } + + curr.value = mergeTypes(curr.value, tpe) + + if _, ok := tpe.(*types.Object); ok && curr.children.Len() > 0 { + // merge all leafs into the inserted object + leafs := curr.Leafs() + for p, t := range leafs { + var err error + curr.value, err = insertIntoObject(curr.value.(*types.Object), *p, t, env) + if err != nil { + panic(fmt.Errorf("unreachable, insertIntoObject: %w", err)) + } + } + } +} + +// mergeTypes merges the types of 'a' and 'b'. If both are sets, their 'of' types are joined with an types.Or. +// If both are objects, the key types of their dynamic properties are joined with types.Or:s, and their value types +// are recursively merged (using mergeTypes). +// If 'a' and 'b' are both objects, and at least one of them have static properties, they are joined +// with an types.Or, instead of being merged. +// If 'a' is an Any containing an Object, and 'b' is an Object (or vice versa); AND both objects have no +// static properties, they are merged. +// If 'a' and 'b' are different types, they are joined with an types.Or. +func mergeTypes(a, b types.Type) types.Type { + if a == nil { + return b + } + + if b == nil { + return a + } + + switch a := a.(type) { + case *types.Object: + if bObj, ok := b.(*types.Object); ok && len(a.StaticProperties()) == 0 && len(bObj.StaticProperties()) == 0 { + if len(a.StaticProperties()) > 0 || len(bObj.StaticProperties()) > 0 { + return types.Or(a, bObj) + } + + aDynProps := a.DynamicProperties() + bDynProps := bObj.DynamicProperties() + dynProps := types.NewDynamicProperty( + types.Or(aDynProps.Key, bDynProps.Key), + mergeTypes(aDynProps.Value, bDynProps.Value)) + return types.NewObject(nil, dynProps) + } else if bAny, ok := b.(types.Any); ok && len(a.StaticProperties()) == 0 { + // If a is an object type with no static components ... + for _, t := range bAny { + if tObj, ok := t.(*types.Object); ok && len(tObj.StaticProperties()) == 0 { + // ... and b is a types.Any containing an object with no static components, we merge them. + aDynProps := a.DynamicProperties() + tDynProps := tObj.DynamicProperties() + tDynProps.Key = types.Or(tDynProps.Key, aDynProps.Key) + tDynProps.Value = types.Or(tDynProps.Value, aDynProps.Value) + return bAny + } + } + } + case *types.Set: + if bSet, ok := b.(*types.Set); ok { + return types.NewSet(types.Or(a.Of(), bSet.Of())) + } + case types.Any: + if _, ok := b.(types.Any); !ok { + return mergeTypes(b, a) + } + } + + return types.Or(a, b) +} + +func (n *typeTreeNode) String() string { + b := strings.Builder{} + + if k := n.key; k != nil { + b.WriteString(k.String()) + } else { + b.WriteString("-") + } + + if v := n.value; v != nil { + b.WriteString(": ") + b.WriteString(v.String()) + } + + n.children.Iter(func(_, v util.T) bool { + if child, ok := v.(*typeTreeNode); ok { + b.WriteString("\n\t+ ") + s := child.String() + s = strings.ReplaceAll(s, "\n", "\n\t") + b.WriteString(s) + } + return false + }) + + return b.String() +} + +func insertIntoObject(o *types.Object, path Ref, tpe types.Type, env *TypeEnv) (*types.Object, error) { + if len(path) == 0 { + return o, nil + } + + key := env.Get(path[0].Value) + + if len(path) == 1 { + var dynamicProps *types.DynamicProperty + if dp := o.DynamicProperties(); dp != nil { + dynamicProps = types.NewDynamicProperty(types.Or(o.DynamicProperties().Key, key), types.Or(o.DynamicProperties().Value, tpe)) + } else { + dynamicProps = types.NewDynamicProperty(key, tpe) + } + return types.NewObject(o.StaticProperties(), dynamicProps), nil + } + + child, err := insertIntoObject(types.NewObject(nil, nil), path[1:], tpe, env) + if err != nil { + return nil, err + } + + var dynamicProps *types.DynamicProperty + if dp := o.DynamicProperties(); dp != nil { + dynamicProps = types.NewDynamicProperty(types.Or(o.DynamicProperties().Key, key), types.Or(o.DynamicProperties().Value, child)) + } else { + dynamicProps = types.NewDynamicProperty(key, child) + } + return types.NewObject(o.StaticProperties(), dynamicProps), nil +} + +func (n *typeTreeNode) Leafs() map[*Ref]types.Type { + leafs := map[*Ref]types.Type{} + n.children.Iter(func(k, v util.T) bool { + collectLeafs(v.(*typeTreeNode), nil, leafs) + return false + }) + return leafs +} + +func collectLeafs(n *typeTreeNode, path Ref, leafs map[*Ref]types.Type) { + nPath := append(path, NewTerm(n.key)) + if n.Leaf() { + leafs[&nPath] = n.Value() + return + } + n.children.Iter(func(k, v util.T) bool { + collectLeafs(v.(*typeTreeNode), nPath, leafs) + return false + }) +} + func (n *typeTreeNode) Value() types.Type { return n.value } diff --git a/vendor/github.com/open-policy-agent/opa/ast/index.go b/vendor/github.com/open-policy-agent/opa/ast/index.go index c30625178f2..e14bb72eefc 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/index.go +++ b/vendor/github.com/open-policy-agent/opa/ast/index.go @@ -32,11 +32,12 @@ type RuleIndex interface { // IndexResult contains the result of an index lookup. type IndexResult struct { - Kind RuleKind - Rules []*Rule - Else map[*Rule][]*Rule - Default *Rule - EarlyExit bool + Kind RuleKind + Rules []*Rule + Else map[*Rule][]*Rule + Default *Rule + EarlyExit bool + OnlyGroundRefs bool } // NewIndexResult returns a new IndexResult object. @@ -53,18 +54,20 @@ func (ir *IndexResult) Empty() bool { } type baseDocEqIndex struct { - skipIndexing Set - isVirtual func(Ref) bool - root *trieNode - defaultRule *Rule - kind RuleKind + skipIndexing Set + isVirtual func(Ref) bool + root *trieNode + defaultRule *Rule + kind RuleKind + onlyGroundRefs bool } func newBaseDocEqIndex(isVirtual func(Ref) bool) *baseDocEqIndex { return &baseDocEqIndex{ - skipIndexing: NewSet(NewTerm(InternalPrint.Ref())), - isVirtual: isVirtual, - root: newTrieNodeImpl(), + skipIndexing: NewSet(NewTerm(InternalPrint.Ref())), + isVirtual: isVirtual, + root: newTrieNodeImpl(), + onlyGroundRefs: true, } } @@ -83,6 +86,9 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool { i.defaultRule = rule return false } + if i.onlyGroundRefs { + i.onlyGroundRefs = rule.Head.Reference.IsGround() + } var skip bool for _, expr := range rule.Body { if op := expr.OperatorTerm(); op != nil && i.skipIndexing.Contains(op) { @@ -134,6 +140,7 @@ func (i *baseDocEqIndex) Lookup(resolver ValueResolver) (*IndexResult, error) { result := NewIndexResult(i.kind) result.Default = i.defaultRule + result.OnlyGroundRefs = i.onlyGroundRefs result.Rules = make([]*Rule, 0, len(tr.ordering)) for _, pos := range tr.ordering { @@ -166,6 +173,7 @@ func (i *baseDocEqIndex) AllRules(resolver ValueResolver) (*IndexResult, error) result := NewIndexResult(i.kind) result.Default = i.defaultRule + result.OnlyGroundRefs = i.onlyGroundRefs result.Rules = make([]*Rule, 0, len(tr.ordering)) for _, pos := range tr.ordering { @@ -435,7 +443,7 @@ type trieNode struct { next *trieNode any *trieNode undefined *trieNode - scalars map[Value]*trieNode + scalars *util.HashMap array *trieNode rules []*ruleNode } @@ -458,11 +466,14 @@ func (node *trieNode) String() string { if node.array != nil { flags = append(flags, fmt.Sprintf("array:%p", node.array)) } - if len(node.scalars) > 0 { - buf := make([]string, 0, len(node.scalars)) - for k, v := range node.scalars { - buf = append(buf, fmt.Sprintf("scalar(%v):%p", k, v)) - } + if node.scalars.Len() > 0 { + buf := make([]string, 0, node.scalars.Len()) + node.scalars.Iter(func(k, v util.T) bool { + key := k.(Value) + val := v.(*trieNode) + buf = append(buf, fmt.Sprintf("scalar(%v):%p", key, val)) + return false + }) sort.Strings(buf) flags = append(flags, strings.Join(buf, " ")) } @@ -472,8 +483,10 @@ func (node *trieNode) String() string { if len(node.mappers) > 0 { flags = append(flags, fmt.Sprintf("%d mapper(s)", len(node.mappers))) } - if l := node.values.Len(); l > 0 { - flags = append(flags, fmt.Sprintf("%d value(s)", l)) + if node.values != nil { + if l := node.values.Len(); l > 0 { + flags = append(flags, fmt.Sprintf("%d value(s)", l)) + } } return strings.Join(flags, " ") } @@ -498,7 +511,7 @@ type ruleNode struct { func newTrieNodeImpl() *trieNode { return &trieNode{ - scalars: map[Value]*trieNode{}, + scalars: util.NewHashMap(valueEq, valueHash), } } @@ -513,9 +526,13 @@ func (node *trieNode) Do(walker trieWalker) { if node.undefined != nil { node.undefined.Do(next) } - for _, child := range node.scalars { + + node.scalars.Iter(func(_, v util.T) bool { + child := v.(*trieNode) child.Do(next) - } + return false + }) + if node.array != nil { node.array.Do(next) } @@ -572,12 +589,12 @@ func (node *trieNode) insertValue(value Value) *trieNode { } return node.any case Null, Boolean, Number, String: - child, ok := node.scalars[value] + child, ok := node.scalars.Get(value) if !ok { child = newTrieNodeImpl() - node.scalars[value] = child + node.scalars.Put(value, child) } - return child + return child.(*trieNode) case *Array: if node.array == nil { node.array = newTrieNodeImpl() @@ -601,12 +618,12 @@ func (node *trieNode) insertArray(arr *Array) *trieNode { } return node.any.insertArray(arr.Slice(1, -1)) case Null, Boolean, Number, String: - child, ok := node.scalars[head] + child, ok := node.scalars.Get(head) if !ok { child = newTrieNodeImpl() - node.scalars[head] = child + node.scalars.Put(head, child) } - return child.insertArray(arr.Slice(1, -1)) + return child.(*trieNode).insertArray(arr.Slice(1, -1)) } panic("illegal value") @@ -667,11 +684,11 @@ func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalRes return node.array.traverseArray(resolver, tr, value) case Null, Boolean, Number, String: - child, ok := node.scalars[value] + child, ok := node.scalars.Get(value) if !ok { return nil } - return child.Traverse(resolver, tr) + return child.(*trieNode).Traverse(resolver, tr) } return nil @@ -683,12 +700,6 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes return node.Traverse(resolver, tr) } - head := arr.Elem(0).Value - - if !IsScalar(head) { - return nil - } - if node.any != nil { err := node.any.traverseArray(resolver, tr, arr.Slice(1, -1)) if err != nil { @@ -696,12 +707,17 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes } } - child, ok := node.scalars[head] - if !ok { + head := arr.Elem(0).Value + + if !IsScalar(head) { return nil } - return child.traverseArray(resolver, tr, arr.Slice(1, -1)) + child, ok := node.scalars.Get(head) + if !ok { + return nil + } + return child.(*trieNode).traverseArray(resolver, tr, arr.Slice(1, -1)) } func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalResult) error { @@ -726,13 +742,16 @@ func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalR return err } - for _, child := range node.scalars { - if err := child.traverseUnknown(resolver, tr); err != nil { - return err + var iterErr error + node.scalars.Iter(func(_, v util.T) bool { + child := v.(*trieNode) + if iterErr = child.traverseUnknown(resolver, tr); iterErr != nil { + return true } - } + return false + }) - return nil + return iterErr } // If term `a` is one of the function's operands, we store a Ref: `args[0]` diff --git a/vendor/github.com/open-policy-agent/opa/ast/json/json.go b/vendor/github.com/open-policy-agent/opa/ast/json/json.go new file mode 100644 index 00000000000..2a72a9dbd6e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/ast/json/json.go @@ -0,0 +1,33 @@ +package json + +// Options defines the options for JSON operations, +// currently only marshaling can be configured +type Options struct { + MarshalOptions MarshalOptions +} + +// MarshalOptions defines the options for JSON marshaling, +// currently only toggling the marshaling of location information is supported +type MarshalOptions struct { + // IncludeLocation toggles the marshaling of location information + IncludeLocation NodeToggle + // IncludeLocationText additionally/optionally includes the text of the location + IncludeLocationText bool +} + +// NodeToggle is a generic struct to allow the toggling of +// settings for different ast node types +type NodeToggle struct { + Term bool + Package bool + Comment bool + Import bool + Rule bool + Head bool + Expr bool + SomeDecl bool + Every bool + With bool + Annotations bool + AnnotationsRef bool +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/location/location.go b/vendor/github.com/open-policy-agent/opa/ast/location/location.go index 5bdce013c88..1ac4d15282b 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/location/location.go +++ b/vendor/github.com/open-policy-agent/opa/ast/location/location.go @@ -3,9 +3,11 @@ package location import ( "bytes" + "encoding/json" + "errors" "fmt" - "github.com/pkg/errors" + astJSON "github.com/open-policy-agent/opa/ast/json" ) // Location records a position in source code @@ -15,6 +17,9 @@ type Location struct { Row int `json:"row"` // The line in the source. Col int `json:"col"` // The column in the row. Offset int `json:"-"` // The byte offset for the location in the source. + + // JSONOptions specifies options for marshaling and unmarshaling of locations + JSONOptions astJSON.Options } // NewLocation returns a new Location object. @@ -88,3 +93,23 @@ func (loc *Location) Compare(other *Location) int { } return 0 } + +func (loc *Location) MarshalJSON() ([]byte, error) { + // structs are used here to preserve the field ordering of the original Location struct + data := struct { + File string `json:"file"` + Row int `json:"row"` + Col int `json:"col"` + Text []byte `json:"text,omitempty"` + }{ + File: loc.File, + Row: loc.Row, + Col: loc.Col, + } + + if loc.JSONOptions.MarshalOptions.IncludeLocationText { + data.Text = loc.Text + } + + return json.Marshal(data) +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/marshal.go b/vendor/github.com/open-policy-agent/opa/ast/marshal.go new file mode 100644 index 00000000000..53fb1120443 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/ast/marshal.go @@ -0,0 +1,11 @@ +package ast + +import ( + astJSON "github.com/open-policy-agent/opa/ast/json" +) + +// customJSON is an interface that can be implemented by AST nodes that +// allows the parser to set options for JSON operations on that node. +type customJSON interface { + setJSONOptions(astJSON.Options) +} diff --git a/vendor/github.com/open-policy-agent/opa/ast/parser.go b/vendor/github.com/open-policy-agent/opa/ast/parser.go index 0b523d372cc..7cbc0b2892e 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/parser.go +++ b/vendor/github.com/open-policy-agent/opa/ast/parser.go @@ -15,11 +15,13 @@ import ( "sort" "strconv" "strings" + "unicode/utf8" "gopkg.in/yaml.v2" "github.com/open-policy-agent/opa/ast/internal/scanner" "github.com/open-policy-agent/opa/ast/internal/tokens" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/ast/location" ) @@ -100,6 +102,7 @@ type ParserOptions struct { AllFutureKeywords bool FutureKeywords []string SkipRules bool + JSONOptions *astJSON.Options unreleasedKeywords bool // TODO(sr): cleanup } @@ -176,6 +179,13 @@ func (p *Parser) WithSkipRules(skip bool) *Parser { return p } +// WithJSONOptions sets the Options which will be set on nodes to configure +// their JSON marshaling behavior. +func (p *Parser) WithJSONOptions(jsonOptions *astJSON.Options) *Parser { + p.po.JSONOptions = jsonOptions + return p +} + func (p *Parser) parsedTermCacheLookup() (*Term, *state) { l := p.s.loc.Offset // stop comparing once the cached offsets are lower than l @@ -356,6 +366,19 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { stmts = p.parseAnnotations(stmts) } + if p.po.JSONOptions != nil { + for i := range stmts { + vis := NewGenericVisitor(func(x interface{}) bool { + if x, ok := x.(customJSON); ok { + x.setJSONOptions(*p.po.JSONOptions) + } + return false + }) + + vis.Walk(stmts[i]) + } + } + return stmts, p.s.comments, p.s.errors } @@ -563,15 +586,16 @@ func (p *Parser) parseRules() []*Rule { return nil } + if len(rule.Head.Args) > 0 { + if !p.validateDefaultRuleArgs(&rule) { + return nil + } + } + rule.Body = NewBody(NewExpr(BooleanTerm(true).SetLocation(rule.Location)).SetLocation(rule.Location)) return []*Rule{&rule} } - if usesContains && !rule.Head.Reference.IsGround() { - p.error(p.s.Loc(), "multi-value rules need ground refs") - return nil - } - // back-compat with `p[x] { ... }`` hasIf := p.s.tok == tokens.If @@ -644,7 +668,7 @@ func (p *Parser) parseRules() []*Rule { } if p.s.tok == tokens.Else { - if r := rule.Head.Ref(); len(r) > 1 && !r[len(r)-1].Value.IsGround() { + if r := rule.Head.Ref(); len(r) > 1 && !r.IsGround() { p.error(p.s.Loc(), "else keyword cannot be used on rules with variables in head") return nil } @@ -735,43 +759,36 @@ func (p *Parser) parseElse(head *Head) *Rule { } hasIf := p.s.tok == tokens.If + hasLBrace := p.s.tok == tokens.LBrace - if hasIf { - p.scan() - s := p.save() - if expr := p.parseLiteral(); expr != nil { - // NOTE(sr): set literals are never false or undefined, so parsing this as - // p if false else if { true } - // ^^^^^^^^ set of one element, `true` - // isn't valid. - isSetLiteral := false - if t, ok := expr.Terms.(*Term); ok { - _, isSetLiteral = t.Value.(Set) - } - // expr.Term is []*Term or Every - if !isSetLiteral { - rule.Body.Append(expr) - setLocRecursive(rule.Body, rule.Location) - return &rule - } - } - p.restore(s) - } - - if p.s.tok != tokens.LBrace { + if !hasIf && !hasLBrace { rule.Body = NewBody(NewExpr(BooleanTerm(true))) setLocRecursive(rule.Body, rule.Location) return &rule } - p.scan() + if hasIf { + p.scan() + } - if rule.Body = p.parseBody(tokens.RBrace); rule.Body == nil { + if p.s.tok == tokens.LBrace { + p.scan() + if rule.Body = p.parseBody(tokens.RBrace); rule.Body == nil { + return nil + } + p.scan() + } else if p.s.tok != tokens.EOF { + expr := p.parseLiteral() + if expr == nil { + return nil + } + rule.Body.Append(expr) + setLocRecursive(rule.Body, rule.Location) + } else { + p.illegal("rule body expected") return nil } - p.scan() - if p.s.tok == tokens.Else { if rule.Else = p.parseElse(head); rule.Else == nil { return nil @@ -781,7 +798,6 @@ func (p *Parser) parseElse(head *Head) *Rule { } func (p *Parser) parseHead(defaultRule bool) (*Head, bool) { - head := &Head{} loc := p.s.Loc() defer func() { @@ -804,7 +820,9 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) { switch x := ref.Value.(type) { case Var: - head = NewHead(x) + // Modify the code to add the location to the head ref + // and set the head ref's jsonOptions. + head = VarHead(x, ref.Location, p.po.JSONOptions) case Ref: head = RefHead(x) case Call: @@ -831,6 +849,10 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) { switch p.s.tok { case tokens.Contains: // NOTE: no Value for `contains` heads, we return here + // Catch error case of using 'contains' with a function definition rule head. + if head.Args != nil { + p.illegal("the contains keyword can only be used with multi-value rule definitions (e.g., %s contains { ... })", name) + } p.scan() head.Key = p.parseTermInfixCall() if head.Key == nil { @@ -886,7 +908,6 @@ func (p *Parser) parseQuery(requireSemi bool, end tokens.Token) Body { } for { - expr := p.parseLiteral() if expr == nil { return nil @@ -2122,6 +2143,38 @@ func (p *Parser) validateDefaultRuleValue(rule *Rule) bool { return valid } +func (p *Parser) validateDefaultRuleArgs(rule *Rule) bool { + + valid := true + vars := NewVarSet() + + vis := NewGenericVisitor(func(x interface{}) bool { + switch x := x.(type) { + case Var: + if vars.Contains(x) { + p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot be repeated %v)", x)) + valid = false + return true + } + vars.Add(x) + + case *Term: + switch v := x.Value.(type) { + case Var: // do nothing + default: + p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot contain %v)", TypeName(v))) + valid = false + return true + } + } + + return false + }) + + vis.Walk(rule.Head.Args) + return valid +} + // We explicitly use yaml unmarshalling, to accommodate for the '_' in 'related_resources', // which isn't handled properly by json for some reason. type rawAnnotation struct { @@ -2154,7 +2207,7 @@ func (b *metadataParser) Append(c *Comment) { b.comments = append(b.comments, c) } -var yamlLineErrRegex = regexp.MustCompile(`^yaml: line ([[:digit:]]+):`) +var yamlLineErrRegex = regexp.MustCompile(`^yaml:(?: unmarshal errors:[\n\s]*)? line ([[:digit:]]+):`) func (b *metadataParser) Parse() (*Annotations, error) { @@ -2165,22 +2218,25 @@ func (b *metadataParser) Parse() (*Annotations, error) { } if err := yaml.Unmarshal(b.buf.Bytes(), &raw); err != nil { + var comment *Comment match := yamlLineErrRegex.FindStringSubmatch(err.Error()) if len(match) == 2 { n, err2 := strconv.Atoi(match[1]) if err2 == nil { index := n - 1 // line numbering is 1-based so subtract one from row if index >= len(b.comments) { - b.loc = b.comments[len(b.comments)-1].Location + comment = b.comments[len(b.comments)-1] } else { - b.loc = b.comments[index].Location + comment = b.comments[index] } + b.loc = comment.Location } } - return nil, err + return nil, augmentYamlError(err, b.comments) } var result Annotations + result.comments = b.comments result.Scope = raw.Scope result.Entrypoint = raw.Entrypoint result.Title = raw.Title @@ -2246,6 +2302,40 @@ func (b *metadataParser) Parse() (*Annotations, error) { return &result, nil } +// augmentYamlError augments a YAML error with hints intended to help the user figure out the cause of an otherwise cryptic error. +// These are hints, instead of proper errors, because they are educated guesses, and aren't guaranteed to be correct. +func augmentYamlError(err error, comments []*Comment) error { + // Adding hints for when key/value ':' separator isn't suffixed with a legal YAML space symbol + for _, comment := range comments { + txt := string(comment.Text) + parts := strings.Split(txt, ":") + if len(parts) > 1 { + parts = parts[1:] + var invalidSpaces []string + for partIndex, part := range parts { + if len(part) == 0 && partIndex == len(parts)-1 { + invalidSpaces = []string{} + break + } + + r, _ := utf8.DecodeRuneInString(part) + if r == ' ' || r == '\t' { + invalidSpaces = []string{} + break + } + + invalidSpaces = append(invalidSpaces, fmt.Sprintf("%+q", r)) + } + if len(invalidSpaces) > 0 { + err = fmt.Errorf( + "%s\n Hint: on line %d, symbol(s) %v immediately following a key/value separator ':' is not a legal yaml space character", + err.Error(), comment.Location.Row, invalidSpaces) + } + } + } + return err +} + func unwrapPair(pair map[string]interface{}) (k string, v interface{}) { for k, v = range pair { } diff --git a/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go b/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go index ce25c3a91b1..9226a9059a7 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go +++ b/vendor/github.com/open-policy-agent/opa/ast/parser_ext.go @@ -16,6 +16,8 @@ import ( "fmt" "strings" "unicode" + + astJSON "github.com/open-policy-agent/opa/ast/json" ) // MustParseBody returns a parsed body. @@ -244,7 +246,9 @@ func ParseCompleteDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, erro var head *Head if v, ok := lhs.Value.(Var); ok { - head = NewHead(v) + // Modify the code to add the location to the head ref + // and set the head ref's jsonOptions. + head = VarHead(v, lhs.Location, &lhs.jsonOptions) } else if r, ok := lhs.Value.(Ref); ok { // groundness ? if _, ok := r[0].Value.(Var); !ok { return nil, fmt.Errorf("invalid rule head: %v", r) @@ -258,14 +262,17 @@ func ParseCompleteDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, erro } head.Value = rhs head.Location = lhs.Location + head.setJSONOptions(lhs.jsonOptions) + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) + setJSONOptions(body, &rhs.jsonOptions) return &Rule{ - Location: lhs.Location, - Head: head, - Body: NewBody( - NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location), - ), - Module: module, + Location: lhs.Location, + Head: head, + Body: body, + Module: module, + jsonOptions: lhs.jsonOptions, }, nil } @@ -280,14 +287,18 @@ func ParseCompleteDocRuleWithDotsFromTerm(module *Module, term *Term) (*Rule, er } head := RefHead(ref, BooleanTerm(true).SetLocation(term.Location)) head.Location = term.Location + head.jsonOptions = term.jsonOptions + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location)) + setJSONOptions(body, &term.jsonOptions) return &Rule{ Location: term.Location, Head: head, - Body: NewBody( - NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location), - ), - Module: module, + Body: body, + Module: module, + + jsonOptions: term.jsonOptions, }, nil } @@ -309,14 +320,17 @@ func ParsePartialObjectDocRuleFromEqExpr(module *Module, lhs, rhs *Term) (*Rule, head.Key = ref[1] } head.Location = rhs.Location + head.jsonOptions = rhs.jsonOptions + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) + setJSONOptions(body, &rhs.jsonOptions) rule := &Rule{ - Location: rhs.Location, - Head: head, - Body: NewBody( - NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location), - ), - Module: module, + Location: rhs.Location, + Head: head, + Body: body, + Module: module, + jsonOptions: rhs.jsonOptions, } return rule, nil @@ -340,18 +354,23 @@ func ParsePartialSetDocRuleFromTerm(module *Module, term *Term) (*Rule, error) { if !ok { return nil, fmt.Errorf("%vs cannot be used for rule head", TypeName(term.Value)) } - head = NewHead(v) + // Modify the code to add the location to the head ref + // and set the head ref's jsonOptions. + head = VarHead(v, ref[0].Location, &ref[0].jsonOptions) head.Key = ref[1] } head.Location = term.Location + head.jsonOptions = term.jsonOptions + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location)) + setJSONOptions(body, &term.jsonOptions) rule := &Rule{ - Location: term.Location, - Head: head, - Body: NewBody( - NewExpr(BooleanTerm(true).SetLocation(term.Location)).SetLocation(term.Location), - ), - Module: module, + Location: term.Location, + Head: head, + Body: body, + Module: module, + jsonOptions: term.jsonOptions, } return rule, nil @@ -377,12 +396,17 @@ func ParseRuleFromCallEqExpr(module *Module, lhs, rhs *Term) (*Rule, error) { head := RefHead(ref, rhs) head.Location = lhs.Location head.Args = Args(call[1:]) + head.jsonOptions = lhs.jsonOptions + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)) + setJSONOptions(body, &rhs.jsonOptions) rule := &Rule{ - Location: lhs.Location, - Head: head, - Body: NewBody(NewExpr(BooleanTerm(true).SetLocation(rhs.Location)).SetLocation(rhs.Location)), - Module: module, + Location: lhs.Location, + Head: head, + Body: body, + Module: module, + jsonOptions: lhs.jsonOptions, } return rule, nil @@ -404,12 +428,17 @@ func ParseRuleFromCallExpr(module *Module, terms []*Term) (*Rule, error) { head := RefHead(ref, BooleanTerm(true).SetLocation(loc)) head.Location = loc head.Args = terms[1:] + head.jsonOptions = terms[0].jsonOptions + + body := NewBody(NewExpr(BooleanTerm(true).SetLocation(loc)).SetLocation(loc)) + setJSONOptions(body, &terms[0].jsonOptions) rule := &Rule{ - Location: loc, - Head: head, - Module: module, - Body: NewBody(NewExpr(BooleanTerm(true).SetLocation(loc)).SetLocation(loc)), + Location: loc, + Head: head, + Module: module, + Body: body, + jsonOptions: terms[0].jsonOptions, } return rule, nil } @@ -594,6 +623,7 @@ func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Sta WithAllFutureKeywords(popts.AllFutureKeywords). WithCapabilities(popts.Capabilities). WithSkipRules(popts.SkipRules). + WithJSONOptions(popts.JSONOptions). withUnreleasedKeywords(popts.unreleasedKeywords) stmts, comments, errs := parser.Parse() @@ -685,6 +715,16 @@ func setRuleModule(rule *Rule, module *Module) { } } +func setJSONOptions(x interface{}, jsonOptions *astJSON.Options) { + vis := NewGenericVisitor(func(x interface{}) bool { + if x, ok := x.(customJSON); ok { + x.setJSONOptions(*jsonOptions) + } + return false + }) + vis.Walk(x) +} + // ParserErrorDetail holds additional details for parser errors. type ParserErrorDetail struct { Line string `json:"line"` diff --git a/vendor/github.com/open-policy-agent/opa/ast/policy.go b/vendor/github.com/open-policy-agent/opa/ast/policy.go index 4f56aa7edbc..fedc738ff22 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/policy.go +++ b/vendor/github.com/open-policy-agent/opa/ast/policy.go @@ -12,6 +12,7 @@ import ( "strings" "time" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/util" ) @@ -149,50 +150,61 @@ type ( // Comment contains the raw text from the comment in the definition. Comment struct { + // TODO: these fields have inconsistent JSON keys with other structs in this package. Text []byte Location *Location + + jsonOptions astJSON.Options } // Package represents the namespace of the documents produced // by rules inside the module. Package struct { - Location *Location `json:"-"` Path Ref `json:"path"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } // Import represents a dependency on a document outside of the policy // namespace. Imports are optional. Import struct { - Location *Location `json:"-"` Path *Term `json:"path"` Alias Var `json:"alias,omitempty"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } // Rule represents a rule as defined in the language. Rules define the // content of documents that represent policy decisions. Rule struct { - Location *Location `json:"-"` Default bool `json:"default,omitempty"` Head *Head `json:"head"` Body Body `json:"body"` Else *Rule `json:"else,omitempty"` + Location *Location `json:"location,omitempty"` // Module is a pointer to the module containing this rule. If the rule // was NOT created while parsing/constructing a module, this should be // left unset. The pointer is not included in any standard operations // on the rule (e.g., printing, comparison, visiting, etc.) Module *Module `json:"-"` + + jsonOptions astJSON.Options } // Head represents the head of a rule. Head struct { - Location *Location `json:"-"` Name Var `json:"name,omitempty"` Reference Ref `json:"ref,omitempty"` Args Args `json:"args,omitempty"` Key *Term `json:"key,omitempty"` Value *Term `json:"value,omitempty"` Assign bool `json:"assign,omitempty"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } // Args represents zero or more arguments to a rule. @@ -206,31 +218,39 @@ type ( Expr struct { With []*With `json:"with,omitempty"` Terms interface{} `json:"terms"` - Location *Location `json:"-"` Index int `json:"index"` Generated bool `json:"generated,omitempty"` Negated bool `json:"negated,omitempty"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } // SomeDecl represents a variable declaration statement. The symbols are variables. SomeDecl struct { - Location *Location `json:"-"` Symbols []*Term `json:"symbols"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } Every struct { - Location *Location `json:"-"` Key *Term `json:"key"` Value *Term `json:"value"` Domain *Term `json:"domain"` Body Body `json:"body"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } // With represents a modifier on an expression. With struct { - Location *Location `json:"-"` Target *Term `json:"target"` Value *Term `json:"value"` + Location *Location `json:"location,omitempty"` + + jsonOptions astJSON.Options } ) @@ -409,6 +429,15 @@ func (c *Comment) Equal(other *Comment) bool { return c.Location.Equal(other.Location) && bytes.Equal(c.Text, other.Text) } +func (c *Comment) setJSONOptions(opts astJSON.Options) { + // Note: this is not used for location since Comments use default JSON marshaling + // behavior with struct field names in JSON. + c.jsonOptions = opts + if c.Location != nil { + c.Location.JSONOptions = opts + } +} + // Compare returns an integer indicating whether pkg is less than, equal to, // or greater than other. func (pkg *Package) Compare(other *Package) int { @@ -453,6 +482,27 @@ func (pkg *Package) String() string { return fmt.Sprintf("package %v", path) } +func (pkg *Package) setJSONOptions(opts astJSON.Options) { + pkg.jsonOptions = opts + if pkg.Location != nil { + pkg.Location.JSONOptions = opts + } +} + +func (pkg *Package) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "path": pkg.Path, + } + + if pkg.jsonOptions.MarshalOptions.IncludeLocation.Package { + if pkg.Location != nil { + data["location"] = pkg.Location + } + } + + return json.Marshal(data) +} + // IsValidImportPath returns an error indicating if the import path is invalid. // If the import path is invalid, err is nil. func IsValidImportPath(v Value) (err error) { @@ -545,6 +595,31 @@ func (imp *Import) String() string { return strings.Join(buf, " ") } +func (imp *Import) setJSONOptions(opts astJSON.Options) { + imp.jsonOptions = opts + if imp.Location != nil { + imp.Location.JSONOptions = opts + } +} + +func (imp *Import) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "path": imp.Path, + } + + if len(imp.Alias) != 0 { + data["alias"] = imp.Alias + } + + if imp.jsonOptions.MarshalOptions.IncludeLocation.Import { + if imp.Location != nil { + data["location"] = imp.Location + } + } + + return json.Marshal(data) +} + // Compare returns an integer indicating whether rule is less than, equal to, // or greater than other. func (rule *Rule) Compare(other *Rule) int { @@ -634,6 +709,36 @@ func (rule *Rule) String() string { return strings.Join(buf, " ") } +func (rule *Rule) setJSONOptions(opts astJSON.Options) { + rule.jsonOptions = opts + if rule.Location != nil { + rule.Location.JSONOptions = opts + } +} + +func (rule *Rule) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "head": rule.Head, + "body": rule.Body, + } + + if rule.Default { + data["default"] = true + } + + if rule.Else != nil { + data["else"] = rule.Else + } + + if rule.jsonOptions.MarshalOptions.IncludeLocation.Rule { + if rule.Location != nil { + data["location"] = rule.Location + } + } + + return json.Marshal(data) +} + func (rule *Rule) elseString() string { var buf []string @@ -677,6 +782,17 @@ func NewHead(name Var, args ...*Term) *Head { return head } +// VarHead creates a head object, initializes its Name, Location, and Options, +// and returns the new head. +func VarHead(name Var, location *Location, jsonOpts *astJSON.Options) *Head { + h := NewHead(name) + h.Reference[0].Location = location + if jsonOpts != nil { + h.Reference[0].setJSONOptions(*jsonOpts) + } + return h +} + // RefHead returns a new Head object with the passed Ref. If args are provided, // the first will be used for the value. func RefHead(ref Ref, args ...*Term) *Head { @@ -823,17 +939,34 @@ func (head *Head) String() string { return buf.String() } +func (head *Head) setJSONOptions(opts astJSON.Options) { + head.jsonOptions = opts + if head.Location != nil { + head.Location.JSONOptions = opts + } +} + func (head *Head) MarshalJSON() ([]byte, error) { + var loc *Location + if head.jsonOptions.MarshalOptions.IncludeLocation.Head { + if head.Location != nil { + loc = head.Location + } + } + // NOTE(sr): we do this to override the rendering of `head.Reference`. // It's still what'll be used via the default means of encoding/json // for unmarshaling a json object into a Head struct! + // NOTE(charlieegan3): we also need to optionally include the location type h Head return json.Marshal(struct { h - Ref Ref `json:"ref"` + Ref Ref `json:"ref"` + Location *Location `json:"location,omitempty"` }{ - h: h(*head), - Ref: head.Ref(), + h: h(*head), + Ref: head.Ref(), + Location: loc, }) } @@ -869,6 +1002,12 @@ func (head *Head) SetLoc(loc *Location) { head.Location = loc } +func (head *Head) HasDynamicRef() bool { + pos := head.Reference.Dynamic() + // Ref is dynamic if it has one non-constant term that isn't the first or last term or if it's a partial set rule. + return pos > 0 && (pos < len(head.Reference)-1 || head.RuleKind() == MultiValue) +} + // Copy returns a deep copy of a. func (a Args) Copy() Args { cpy := Args{} @@ -924,7 +1063,8 @@ func (body Body) MarshalJSON() ([]byte, error) { if len(body) == 0 { return []byte(`[]`), nil } - return json.Marshal([]*Expr(body)) + ret, err := json.Marshal([]*Expr(body)) + return ret, err } // Append adds the expr to the body and updates the expr's index accordingly. @@ -1352,6 +1492,40 @@ func (expr *Expr) String() string { return strings.Join(buf, " ") } +func (expr *Expr) setJSONOptions(opts astJSON.Options) { + expr.jsonOptions = opts + if expr.Location != nil { + expr.Location.JSONOptions = opts + } +} + +func (expr *Expr) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "terms": expr.Terms, + "index": expr.Index, + } + + if len(expr.With) > 0 { + data["with"] = expr.With + } + + if expr.Generated { + data["generated"] = true + } + + if expr.Negated { + data["negated"] = true + } + + if expr.jsonOptions.MarshalOptions.IncludeLocation.Expr { + if expr.Location != nil { + data["location"] = expr.Location + } + } + + return json.Marshal(data) +} + // UnmarshalJSON parses the byte array and stores the result in expr. func (expr *Expr) UnmarshalJSON(bs []byte) error { v := map[string]interface{}{} @@ -1417,6 +1591,27 @@ func (d *SomeDecl) Hash() int { return termSliceHash(d.Symbols) } +func (d *SomeDecl) setJSONOptions(opts astJSON.Options) { + d.jsonOptions = opts + if d.Location != nil { + d.Location.JSONOptions = opts + } +} + +func (d *SomeDecl) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "symbols": d.Symbols, + } + + if d.jsonOptions.MarshalOptions.IncludeLocation.SomeDecl { + if d.Location != nil { + data["location"] = d.Location + } + } + + return json.Marshal(data) +} + func (q *Every) String() string { if q.Key != nil { return fmt.Sprintf("every %s, %s in %s { %s }", @@ -1473,6 +1668,30 @@ func (q *Every) KeyValueVars() VarSet { return vis.vars } +func (q *Every) setJSONOptions(opts astJSON.Options) { + q.jsonOptions = opts + if q.Location != nil { + q.Location.JSONOptions = opts + } +} + +func (q *Every) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "key": q.Key, + "value": q.Value, + "domain": q.Domain, + "body": q.Body, + } + + if q.jsonOptions.MarshalOptions.IncludeLocation.Every { + if q.Location != nil { + data["location"] = q.Location + } + } + + return json.Marshal(data) +} + func (w *With) String() string { return "with " + w.Target.String() + " as " + w.Value.String() } @@ -1531,6 +1750,28 @@ func (w *With) SetLoc(loc *Location) { w.Location = loc } +func (w *With) setJSONOptions(opts astJSON.Options) { + w.jsonOptions = opts + if w.Location != nil { + w.Location.JSONOptions = opts + } +} + +func (w *With) MarshalJSON() ([]byte, error) { + data := map[string]interface{}{ + "target": w.Target, + "value": w.Value, + } + + if w.jsonOptions.MarshalOptions.IncludeLocation.With { + if w.Location != nil { + data["location"] = w.Location + } + } + + return json.Marshal(data) +} + // Copy returns a deep copy of the AST node x. If x is not an AST node, x is returned unmodified. func Copy(x interface{}) interface{} { switch x := x.(type) { diff --git a/vendor/github.com/open-policy-agent/opa/ast/term.go b/vendor/github.com/open-policy-agent/opa/ast/term.go index a96262263d4..9ef8ae74740 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/term.go +++ b/vendor/github.com/open-policy-agent/opa/ast/term.go @@ -8,6 +8,7 @@ package ast import ( "bytes" "encoding/json" + "errors" "fmt" "io" "math" @@ -20,8 +21,8 @@ import ( "sync" "github.com/OneOfOne/xxhash" - "github.com/pkg/errors" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/ast/location" "github.com/open-policy-agent/opa/util" ) @@ -291,8 +292,10 @@ func MustInterfaceToValue(x interface{}) Value { // Term is an argument to a function. type Term struct { - Value Value `json:"value"` // the value of the Term as represented in Go - Location *Location `json:"-"` // the location of the Term in the source + Value Value `json:"value"` // the value of the Term as represented in Go + Location *Location `json:"location,omitempty"` // the location of the Term in the source + + jsonOptions astJSON.Options } // NewTerm returns a new Term object. @@ -417,6 +420,13 @@ func (term *Term) IsGround() bool { return term.Value.IsGround() } +func (term *Term) setJSONOptions(opts astJSON.Options) { + term.jsonOptions = opts + if term.Location != nil { + term.Location.JSONOptions = opts + } +} + // MarshalJSON returns the JSON encoding of the term. // // Specialized marshalling logic is required to include a type hint for Value. @@ -425,6 +435,11 @@ func (term *Term) MarshalJSON() ([]byte, error) { "type": TypeName(term.Value), "value": term.Value, } + if term.jsonOptions.MarshalOptions.IncludeLocation.Term { + if term.Location != nil { + d["location"] = term.Location + } + } return json.Marshal(d) } @@ -433,7 +448,7 @@ func (term *Term) String() string { } // UnmarshalJSON parses the byte array and stores the result in term. -// Specialized unmarshalling is required to handle Value. +// Specialized unmarshalling is required to handle Value and Location. func (term *Term) UnmarshalJSON(bs []byte) error { v := map[string]interface{}{} if err := util.UnmarshalJSON(bs, &v); err != nil { @@ -444,6 +459,14 @@ func (term *Term) UnmarshalJSON(bs []byte) error { return err } term.Value = val + + if loc, ok := v["location"].(map[string]interface{}); ok { + term.Location = &Location{} + err := unmarshalLocation(term.Location, loc) + if err != nil { + return err + } + } return nil } @@ -1009,6 +1032,20 @@ func (ref Ref) ConstantPrefix() Ref { return ref[:i] } +func (ref Ref) StringPrefix() Ref { + r := ref.Copy() + + for i := 1; i < len(ref); i++ { + switch r[i].Value.(type) { + case String: // pass + default: // cut off + return r[:i] + } + } + + return r +} + // GroundPrefix returns the ground portion of the ref starting from the head. By // definition, the head of the reference is always ground. func (ref Ref) GroundPrefix() Ref { @@ -1024,6 +1061,14 @@ func (ref Ref) GroundPrefix() Ref { return prefix } +func (ref Ref) DynamicSuffix() Ref { + i := ref.Dynamic() + if i < 0 { + return nil + } + return ref[i:] +} + // IsGround returns true if all of the parts of the Ref are ground. func (ref Ref) IsGround() bool { if len(ref) == 0 { @@ -1821,22 +1866,34 @@ func ObjectTerm(o ...[2]*Term) *Term { } func LazyObject(blob map[string]interface{}) Object { - return &lazyObj{native: blob} + return &lazyObj{native: blob, cache: map[string]Value{}} } type lazyObj struct { strict Object + cache map[string]Value native map[string]interface{} } func (l *lazyObj) force() Object { if l.strict == nil { l.strict = MustInterfaceToValue(l.native).(Object) + // NOTE(jf): a possible performance improvement here would be to check how many + // entries have been realized to AST in the cache, and if some threshold compared to the + // total number of keys is exceeded, realize the remaining entries and set l.strict to l.cache. + l.cache = map[string]Value{} // We don't need the cache anymore; drop it to free up memory. } return l.strict } func (l *lazyObj) Compare(other Value) int { + o1 := sortOrder(l) + o2 := sortOrder(other) + if o1 < o2 { + return -1 + } else if o2 < o1 { + return 1 + } return l.force().Compare(other) } @@ -1905,13 +1962,20 @@ func (l *lazyObj) Get(k *Term) *Term { return l.strict.Get(k) } if s, ok := k.Value.(String); ok { + if v, ok := l.cache[string(s)]; ok { + return NewTerm(v) + } + if val, ok := l.native[string(s)]; ok { + var converted Value switch val := val.(type) { case map[string]interface{}: - return NewTerm(&lazyObj{native: val}) + converted = LazyObject(val) default: - return NewTerm(MustInterfaceToValue(val)) + converted = MustInterfaceToValue(val) } + l.cache[string(s)] = converted + return NewTerm(converted) } } return nil @@ -1966,13 +2030,20 @@ func (l *lazyObj) Find(path Ref) (Value, error) { return l, nil } if p0, ok := path[0].Value.(String); ok { + if v, ok := l.cache[string(p0)]; ok { + return v.Find(path[1:]) + } + if v, ok := l.native[string(p0)]; ok { + var converted Value switch v := v.(type) { case map[string]interface{}: - return (&lazyObj{native: v}).Find(path[1:]) + converted = LazyObject(v) default: - return MustInterfaceToValue(v).Find(path[1:]) + converted = MustInterfaceToValue(v) } + l.cache[string(p0)] = converted + return converted.Find(path[1:]) } } return nil, errFindNotFound @@ -2897,6 +2968,14 @@ func unmarshalExpr(expr *Expr, v map[string]interface{}) error { return fmt.Errorf("ast: unable to unmarshal negated field with type: %T (expected true or false)", v["negated"]) } } + if generatedRaw, ok := v["generated"]; ok { + if b, ok := generatedRaw.(bool); ok { + expr.Generated = b + } else { + return fmt.Errorf("ast: unable to unmarshal generated field with type: %T (expected true or false)", v["generated"]) + } + } + if err := unmarshalExprIndex(expr, v); err != nil { return err } @@ -2929,6 +3008,46 @@ func unmarshalExpr(expr *Expr, v map[string]interface{}) error { expr.With = ws } } + if loc, ok := v["location"].(map[string]interface{}); ok { + expr.Location = &Location{} + if err := unmarshalLocation(expr.Location, loc); err != nil { + return err + } + } + return nil +} + +func unmarshalLocation(loc *Location, v map[string]interface{}) error { + if x, ok := v["file"]; ok { + if s, ok := x.(string); ok { + loc.File = s + } else { + return fmt.Errorf("ast: unable to unmarshal file field with type: %T (expected string)", v["file"]) + } + } + if x, ok := v["row"]; ok { + if n, ok := x.(json.Number); ok { + i64, err := n.Int64() + if err != nil { + return err + } + loc.Row = int(i64) + } else { + return fmt.Errorf("ast: unable to unmarshal row field with type: %T (expected number)", v["row"]) + } + } + if x, ok := v["col"]; ok { + if n, ok := x.(json.Number); ok { + i64, err := n.Int64() + if err != nil { + return err + } + loc.Col = int(i64) + } else { + return fmt.Errorf("ast: unable to unmarshal col field with type: %T (expected number)", v["col"]) + } + } + return nil } @@ -2946,11 +3065,22 @@ func unmarshalExprIndex(expr *Expr, v map[string]interface{}) error { } func unmarshalTerm(m map[string]interface{}) (*Term, error) { + var term Term + v, err := unmarshalValue(m) if err != nil { return nil, err } - return &Term{Value: v}, nil + term.Value = v + + if loc, ok := m["location"].(map[string]interface{}); ok { + term.Location = &Location{} + if err := unmarshalLocation(term.Location, loc); err != nil { + return nil, err + } + } + + return &term, nil } func unmarshalTermSlice(s []interface{}) ([]*Term, error) { diff --git a/vendor/github.com/open-policy-agent/opa/ast/visit.go b/vendor/github.com/open-policy-agent/opa/ast/visit.go index 1d72f97fa46..7b0d3b08e76 100644 --- a/vendor/github.com/open-policy-agent/opa/ast/visit.go +++ b/vendor/github.com/open-policy-agent/opa/ast/visit.go @@ -7,13 +7,15 @@ package ast // Visitor defines the interface for iterating AST elements. The Visit function // can return a Visitor w which will be used to visit the children of the AST // element v. If the Visit function returns nil, the children will not be -// visited. This is deprecated. +// visited. +// Deprecated: use GenericVisitor or another visitor implementation type Visitor interface { Visit(v interface{}) (w Visitor) } // BeforeAndAfterVisitor wraps Visitor to provide hooks for being called before -// and after the AST has been visited. This is deprecated. +// and after the AST has been visited. +// Deprecated: use GenericVisitor or another visitor implementation type BeforeAndAfterVisitor interface { Visitor Before(x interface{}) @@ -21,7 +23,8 @@ type BeforeAndAfterVisitor interface { } // Walk iterates the AST by calling the Visit function on the Visitor -// v for x before recursing. This is deprecated. +// v for x before recursing. +// Deprecated: use GenericVisitor.Walk func Walk(v Visitor, x interface{}) { if bav, ok := v.(BeforeAndAfterVisitor); !ok { walk(v, x) @@ -33,7 +36,8 @@ func Walk(v Visitor, x interface{}) { } // WalkBeforeAndAfter iterates the AST by calling the Visit function on the -// Visitor v for x before recursing. This is deprecated. +// Visitor v for x before recursing. +// Deprecated: use GenericVisitor.Walk func WalkBeforeAndAfter(v BeforeAndAfterVisitor, x interface{}) { Walk(v, x) } @@ -141,6 +145,10 @@ func walk(v Visitor, x interface{}) { Walk(w, x.Value) Walk(w, x.Domain) Walk(w, x.Body) + case *SomeDecl: + for i := range x.Symbols { + Walk(w, x.Symbols[i]) + } } } @@ -348,6 +356,11 @@ func (vis *GenericVisitor) Walk(x interface{}) { vis.Walk(k) vis.Walk(x.Get(k)) }) + case Object: + x.Foreach(func(k, v *Term) { + vis.Walk(k) + vis.Walk(x.Get(k)) + }) case *Array: x.Foreach(func(t *Term) { vis.Walk(t) @@ -378,6 +391,10 @@ func (vis *GenericVisitor) Walk(x interface{}) { vis.Walk(x.Value) vis.Walk(x.Domain) vis.Walk(x.Body) + case *SomeDecl: + for i := range x.Symbols { + vis.Walk(x.Symbols[i]) + } } } @@ -479,6 +496,11 @@ func (vis *BeforeAfterVisitor) Walk(x interface{}) { vis.Walk(k) vis.Walk(x.Get(k)) }) + case Object: + x.Foreach(func(k, v *Term) { + vis.Walk(k) + vis.Walk(x.Get(k)) + }) case *Array: x.Foreach(func(t *Term) { vis.Walk(t) @@ -509,6 +531,10 @@ func (vis *BeforeAfterVisitor) Walk(x interface{}) { vis.Walk(x.Value) vis.Walk(x.Domain) vis.Walk(x.Body) + case *SomeDecl: + for i := range x.Symbols { + vis.Walk(x.Symbols[i]) + } } } @@ -749,5 +775,9 @@ func (vis *VarVisitor) Walk(x interface{}) { vis.Walk(x.Value) vis.Walk(x.Domain) vis.Walk(x.Body) + case *SomeDecl: + for i := range x.Symbols { + vis.Walk(x.Symbols[i]) + } } } diff --git a/vendor/github.com/open-policy-agent/opa/bundle/bundle.go b/vendor/github.com/open-policy-agent/opa/bundle/bundle.go index b5ff532fbfb..66c8ce37c63 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/bundle.go +++ b/vendor/github.com/open-policy-agent/opa/bundle/bundle.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/open-policy-agent/opa/ast" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/format" "github.com/open-policy-agent/opa/internal/file/archive" "github.com/open-policy-agent/opa/internal/merge" @@ -127,8 +128,9 @@ type Manifest struct { // WasmResolver maps a wasm module to an entrypoint ref. type WasmResolver struct { - Entrypoint string `json:"entrypoint,omitempty"` - Module string `json:"module,omitempty"` + Entrypoint string `json:"entrypoint,omitempty"` + Module string `json:"module,omitempty"` + Annotations []*ast.Annotations `json:"annotations,omitempty"` } // Init initializes the manifest. If you instantiate a manifest @@ -166,6 +168,10 @@ func (m Manifest) Equal(other Manifest) bool { return m.equalWasmResolversAndRoots(other) } +func (m Manifest) Empty() bool { + return m.Equal(Manifest{}) +} + // Copy returns a deep copy of the manifest. func (m Manifest) Copy() Manifest { m.Init() @@ -210,7 +216,7 @@ func (m Manifest) equalWasmResolversAndRoots(other Manifest) bool { } for i := 0; i < len(m.WasmResolvers); i++ { - if m.WasmResolvers[i] != other.WasmResolvers[i] { + if !m.WasmResolvers[i].Equal(&other.WasmResolvers[i]) { return false } } @@ -218,6 +224,37 @@ func (m Manifest) equalWasmResolversAndRoots(other Manifest) bool { return m.rootSet().Equal(other.rootSet()) } +func (wr *WasmResolver) Equal(other *WasmResolver) bool { + if wr == nil && other == nil { + return true + } + + if wr == nil || other == nil { + return false + } + + if wr.Module != other.Module { + return false + } + + if wr.Entrypoint != other.Entrypoint { + return false + } + + annotLen := len(wr.Annotations) + if annotLen != len(other.Annotations) { + return false + } + + for i := 0; i < annotLen; i++ { + if wr.Annotations[i].Compare(other.Annotations[i]) != 0 { + return false + } + } + + return true +} + type stringSet map[string]struct{} func (ss stringSet) Equal(other stringSet) bool { @@ -355,12 +392,14 @@ type Reader struct { verificationConfig *VerificationConfig skipVerify bool processAnnotations bool + jsonOptions *astJSON.Options capabilities *ast.Capabilities files map[string]FileInfo // files in the bundle signature payload sizeLimitBytes int64 etag string lazyLoadingMode bool name string + persist bool } // NewReader is deprecated. Use NewCustomReader instead. @@ -424,6 +463,12 @@ func (r *Reader) WithCapabilities(caps *ast.Capabilities) *Reader { return r } +// WithJSONOptions sets the JSONOptions to use when parsing policy files +func (r *Reader) WithJSONOptions(opts *astJSON.Options) *Reader { + r.jsonOptions = opts + return r +} + // WithSizeLimitBytes sets the size limit to apply to files in the bundle. If files are larger // than this, an error will be returned by the reader. func (r *Reader) WithSizeLimitBytes(n int64) *Reader { @@ -452,10 +497,17 @@ func (r *Reader) WithLazyLoadingMode(yes bool) *Reader { return r } +// WithBundlePersistence specifies if the downloaded bundle will eventually be persisted to disk. +func (r *Reader) WithBundlePersistence(persist bool) *Reader { + r.persist = persist + return r +} + func (r *Reader) ParserOptions() ast.ParserOptions { return ast.ParserOptions{ ProcessAnnotation: r.processAnnotations, Capabilities: r.capabilities, + JSONOptions: r.jsonOptions, } } @@ -559,7 +611,7 @@ func (r *Reader) Read() (Bundle, error) { var value interface{} r.metrics.Timer(metrics.RegoDataParse).Start() - err := util.NewJSONDecoder(&buf).Decode(&value) + err := util.UnmarshalJSON(buf.Bytes(), &value) r.metrics.Timer(metrics.RegoDataParse).Stop() if err != nil { @@ -609,6 +661,10 @@ func (r *Reader) Read() (Bundle, error) { if len(bundle.WasmModules) != 0 { return bundle, fmt.Errorf("delta bundle expected to contain only patch file but wasm files found") } + + if r.persist { + return bundle, fmt.Errorf("'persist' property is true in config. persisting delta bundle to disk is not supported") + } } // check if the bundle signatures specify any files that weren't found in the bundle @@ -849,7 +905,7 @@ func (w *Writer) writePlan(tw *tar.Writer, bundle Bundle) error { func writeManifest(tw *tar.Writer, bundle Bundle) error { - if bundle.Manifest.Equal(Manifest{}) { + if bundle.Manifest.Empty() { return nil } @@ -926,7 +982,7 @@ func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) { // parse the manifest into a JSON structure; // then recursively order the fields of all objects alphabetically and then apply // the hash function to result to compute the hash. - if !b.Manifest.Equal(Manifest{}) { + if !b.Manifest.Empty() { mbs, err := json.Marshal(b.Manifest) if err != nil { return files, err @@ -1046,10 +1102,14 @@ func (b Bundle) Equal(other Bundle) bool { return false } for i := range b.Modules { - if b.Modules[i].URL != other.Modules[i].URL { + // To support bundles built from rootless filesystems we ignore a "/" prefix + // for URLs and Paths, such that "/file" and "file" are equivalent + if strings.TrimPrefix(b.Modules[i].URL, string(filepath.Separator)) != + strings.TrimPrefix(other.Modules[i].URL, string(filepath.Separator)) { return false } - if b.Modules[i].Path != other.Modules[i].Path { + if strings.TrimPrefix(b.Modules[i].Path, string(filepath.Separator)) != + strings.TrimPrefix(other.Modules[i].Path, string(filepath.Separator)) { return false } if !b.Modules[i].Parsed.Equal(other.Modules[i].Parsed) { @@ -1218,6 +1278,10 @@ func Merge(bundles []*Bundle) (*Bundle, error) { } + if result.Data == nil { + result.Data = map[string]interface{}{} + } + result.Manifest.Roots = &roots if err := result.Manifest.validateAndInjectDefaults(result); err != nil { @@ -1282,7 +1346,7 @@ func getNormalizedPath(path string) []string { // other hand, if the path is empty, filepath.Dir will return '.'. // Note: filepath.Dir can return paths with '\' separators, always use // filepath.ToSlash to keep them normalized. - dirpath := strings.TrimLeft(filepath.ToSlash(filepath.Dir(path)), "/.") + dirpath := strings.TrimLeft(normalizePath(filepath.Dir(path)), "/.") var key []string if dirpath != "" { key = strings.Split(dirpath, "/") @@ -1319,7 +1383,9 @@ func modulePathWithPrefix(bundleName string, modulePath string) string { prefix = filepath.Join(parsed.Host, parsed.Path) } - return filepath.Join(prefix, modulePath) + // Note: filepath.Join can return paths with '\' separators, always use + // filepath.ToSlash to keep them normalized. + return normalizePath(filepath.Join(prefix, modulePath)) } // IsStructuredDoc checks if the file name equals a structured file extension ex. ".json" @@ -1391,3 +1457,7 @@ func readFile(f *Descriptor, sizeLimitBytes int64) (bytes.Buffer, error) { return buf, nil } + +func normalizePath(p string) string { + return filepath.ToSlash(p) +} diff --git a/vendor/github.com/open-policy-agent/opa/bundle/file.go b/vendor/github.com/open-policy-agent/opa/bundle/file.go index 5793a48f892..4892b686316 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/file.go +++ b/vendor/github.com/open-policy-agent/opa/bundle/file.go @@ -7,7 +7,6 @@ import ( "fmt" "io" "os" - "path" "path/filepath" "sort" "strings" @@ -108,6 +107,14 @@ func (d *Descriptor) Close() error { return err } +type PathFormat int64 + +const ( + Chrooted PathFormat = iota + SlashRooted + Passthrough +) + // DirectoryLoader defines an interface which can be used to load // files from a directory by iterating over each one in the tree. type DirectoryLoader interface { @@ -115,23 +122,22 @@ type DirectoryLoader interface { // descriptor should *always* be closed when no longer needed. NextFile() (*Descriptor, error) WithFilter(filter filter.LoaderFilter) DirectoryLoader + WithPathFormat(PathFormat) DirectoryLoader } type dirLoader struct { - root string - files []string - idx int - filter filter.LoaderFilter + root string + files []string + idx int + filter filter.LoaderFilter + pathFormat PathFormat } -// NewDirectoryLoader returns a basic DirectoryLoader implementation -// that will load files from a given root directory path. -func NewDirectoryLoader(root string) DirectoryLoader { - +// Normalize root directory, ex "./src/bundle" -> "src/bundle" +// We don't need an absolute path, but this makes the joined/trimmed +// paths more uniform. +func normalizeRootDirectory(root string) string { if len(root) > 1 { - // Normalize relative directories, ex "./src/bundle" -> "src/bundle" - // We don't need an absolute path, but this makes the joined/trimmed - // paths more uniform. if root[0] == '.' && root[1] == filepath.Separator { if len(root) == 2 { root = root[:1] // "./" -> "." @@ -140,9 +146,15 @@ func NewDirectoryLoader(root string) DirectoryLoader { } } } + return root +} +// NewDirectoryLoader returns a basic DirectoryLoader implementation +// that will load files from a given root directory path. +func NewDirectoryLoader(root string) DirectoryLoader { d := dirLoader{ - root: root, + root: normalizeRootDirectory(root), + pathFormat: Chrooted, } return &d } @@ -153,6 +165,36 @@ func (d *dirLoader) WithFilter(filter filter.LoaderFilter) DirectoryLoader { return d } +// WithPathFormat specifies how a path is formatted in a Descriptor +func (d *dirLoader) WithPathFormat(pathFormat PathFormat) DirectoryLoader { + d.pathFormat = pathFormat + return d +} + +func formatPath(fileName string, root string, pathFormat PathFormat) string { + switch pathFormat { + case SlashRooted: + if !strings.HasPrefix(fileName, string(filepath.Separator)) { + return string(filepath.Separator) + fileName + } + return fileName + case Chrooted: + // Trim off the root directory and return path as if chrooted + result := strings.TrimPrefix(fileName, filepath.FromSlash(root)) + if root == "." && filepath.Base(fileName) == ManifestExt { + result = fileName + } + if !strings.HasPrefix(result, string(filepath.Separator)) { + result = string(filepath.Separator) + result + } + return result + case Passthrough: + fallthrough + default: + return fileName + } +} + // NextFile iterates to the next file in the directory tree // and returns a file Descriptor for the file. func (d *dirLoader) NextFile() (*Descriptor, error) { @@ -164,7 +206,7 @@ func (d *dirLoader) NextFile() (*Descriptor, error) { if d.filter != nil && d.filter(filepath.ToSlash(path), info, getdepth(path, false)) { return nil } - d.files = append(d.files, filepath.ToSlash(path)) + d.files = append(d.files, path) } else if info != nil && info.Mode().IsDir() { if d.filter != nil && d.filter(filepath.ToSlash(path), info, getdepth(path, true)) { return filepath.SkipDir @@ -187,28 +229,20 @@ func (d *dirLoader) NextFile() (*Descriptor, error) { d.idx++ fh := newLazyFile(fileName) - // Trim off the root directory and return path as if chrooted - cleanedPath := strings.TrimPrefix(fileName, d.root) - if d.root == "." && filepath.Base(fileName) == ManifestExt { - cleanedPath = fileName - } - - if !strings.HasPrefix(cleanedPath, "/") { - cleanedPath = "/" + cleanedPath - } - - f := newDescriptor(path.Join(d.root, cleanedPath), cleanedPath, fh).withCloser(fh) + cleanedPath := formatPath(fileName, d.root, d.pathFormat) + f := newDescriptor(filepath.Join(d.root, cleanedPath), cleanedPath, fh).withCloser(fh) return f, nil } type tarballLoader struct { - baseURL string - r io.Reader - tr *tar.Reader - files []file - idx int - filter filter.LoaderFilter - skipDir map[string]struct{} + baseURL string + r io.Reader + tr *tar.Reader + files []file + idx int + filter filter.LoaderFilter + skipDir map[string]struct{} + pathFormat PathFormat } type file struct { @@ -221,7 +255,8 @@ type file struct { // NewTarballLoader is deprecated. Use NewTarballLoaderWithBaseURL instead. func NewTarballLoader(r io.Reader) DirectoryLoader { l := tarballLoader{ - r: r, + r: r, + pathFormat: Passthrough, } return &l } @@ -231,8 +266,9 @@ func NewTarballLoader(r io.Reader) DirectoryLoader { // with the baseURL. func NewTarballLoaderWithBaseURL(r io.Reader, baseURL string) DirectoryLoader { l := tarballLoader{ - baseURL: strings.TrimSuffix(baseURL, "/"), - r: r, + baseURL: strings.TrimSuffix(baseURL, "/"), + r: r, + pathFormat: Passthrough, } return &l } @@ -243,6 +279,12 @@ func (t *tarballLoader) WithFilter(filter filter.LoaderFilter) DirectoryLoader { return t } +// WithPathFormat specifies how a path is formatted in a Descriptor +func (t *tarballLoader) WithPathFormat(pathFormat PathFormat) DirectoryLoader { + t.pathFormat = pathFormat + return t +} + // NextFile iterates to the next file in the directory tree // and returns a file Descriptor for the file. func (t *tarballLoader) NextFile() (*Descriptor, error) { @@ -329,7 +371,10 @@ func (t *tarballLoader) NextFile() (*Descriptor, error) { f := t.files[t.idx] t.idx++ - return newDescriptor(path.Join(t.baseURL, f.name), f.name, f.reader), nil + cleanedPath := formatPath(f.name, "", t.pathFormat) + d := newDescriptor(filepath.Join(t.baseURL, cleanedPath), cleanedPath, f.reader) + return d, nil + } // Next implements the storage.Iterator interface. @@ -343,9 +388,9 @@ func (it *iterator) Next() (*storage.Update, error) { for _, item := range it.raw { f := file{name: item.Path} - fpath := strings.TrimLeft(filepath.ToSlash(filepath.Dir(f.name)), "/.") + fpath := strings.TrimLeft(normalizePath(filepath.Dir(f.name)), "/.") if strings.HasSuffix(f.name, RegoExt) { - fpath = strings.Trim(f.name, "/") + fpath = strings.Trim(normalizePath(f.name), "/") } p, ok := storage.ParsePathEscaped("/" + fpath) diff --git a/vendor/github.com/open-policy-agent/opa/bundle/filefs.go b/vendor/github.com/open-policy-agent/opa/bundle/filefs.go index 5f3317392ea..3aa253ee190 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/filefs.go +++ b/vendor/github.com/open-policy-agent/opa/bundle/filefs.go @@ -23,16 +23,26 @@ type dirLoaderFS struct { files []string idx int filter filter.LoaderFilter + root string + pathFormat PathFormat } // NewFSLoader returns a basic DirectoryLoader implementation // that will load files from a fs.FS interface func NewFSLoader(filesystem fs.FS) (DirectoryLoader, error) { + return NewFSLoaderWithRoot(filesystem, defaultFSLoaderRoot), nil +} + +// NewFSLoaderWithRoot returns a basic DirectoryLoader implementation +// that will load files from a fs.FS interface at the supplied root +func NewFSLoaderWithRoot(filesystem fs.FS, root string) DirectoryLoader { d := dirLoaderFS{ filesystem: filesystem, + root: normalizeRootDirectory(root), + pathFormat: Chrooted, } - return &d, nil + return &d } func (d *dirLoaderFS) walkDir(path string, dirEntry fs.DirEntry, err error) error { @@ -67,6 +77,12 @@ func (d *dirLoaderFS) WithFilter(filter filter.LoaderFilter) DirectoryLoader { return d } +// WithPathFormat specifies how a path is formatted in a Descriptor +func (d *dirLoaderFS) WithPathFormat(pathFormat PathFormat) DirectoryLoader { + d.pathFormat = pathFormat + return d +} + // NextFile iterates to the next file in the directory tree // and returns a file Descriptor for the file. func (d *dirLoaderFS) NextFile() (*Descriptor, error) { @@ -74,7 +90,7 @@ func (d *dirLoaderFS) NextFile() (*Descriptor, error) { defer d.Unlock() if d.files == nil { - err := fs.WalkDir(d.filesystem, defaultFSLoaderRoot, d.walkDir) + err := fs.WalkDir(d.filesystem, d.root, d.walkDir) if err != nil { return nil, fmt.Errorf("failed to list files: %w", err) } @@ -94,7 +110,7 @@ func (d *dirLoaderFS) NextFile() (*Descriptor, error) { return nil, fmt.Errorf("failed to open file %s: %w", fileName, err) } - fileNameWithSlash := fmt.Sprintf("/%s", fileName) - f := newDescriptor(fileNameWithSlash, fileNameWithSlash, fh).withCloser(fh) + cleanedPath := formatPath(fileName, d.root, d.pathFormat) + f := newDescriptor(cleanedPath, cleanedPath, fh).withCloser(fh) return f, nil } diff --git a/vendor/github.com/open-policy-agent/opa/bundle/store.go b/vendor/github.com/open-policy-agent/opa/bundle/store.go index ab8af205894..d93d147c054 100644 --- a/vendor/github.com/open-policy-agent/opa/bundle/store.go +++ b/vendor/github.com/open-policy-agent/opa/bundle/store.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/open-policy-agent/opa/ast" + iCompiler "github.com/open-policy-agent/opa/internal/compiler" "github.com/open-policy-agent/opa/internal/json/patch" "github.com/open-policy-agent/opa/metrics" "github.com/open-policy-agent/opa/storage" @@ -291,14 +292,15 @@ func readEtagFromStore(ctx context.Context, store storage.Store, txn storage.Tra // ActivateOpts defines options for the Activate API call. type ActivateOpts struct { - Ctx context.Context - Store storage.Store - Txn storage.Transaction - TxnCtx *storage.Context - Compiler *ast.Compiler - Metrics metrics.Metrics - Bundles map[string]*Bundle // Optional - ExtraModules map[string]*ast.Module // Optional + Ctx context.Context + Store storage.Store + Txn storage.Transaction + TxnCtx *storage.Context + Compiler *ast.Compiler + Metrics metrics.Metrics + Bundles map[string]*Bundle // Optional + ExtraModules map[string]*ast.Module // Optional + AuthorizationDecisionRef ast.Ref legacy bool } @@ -450,7 +452,7 @@ func activateBundles(opts *ActivateOpts) error { remainingAndExtra[name] = mod } - err = compileModules(opts.Compiler, opts.Metrics, snapshotBundles, remainingAndExtra, opts.legacy) + err = compileModules(opts.Compiler, opts.Metrics, snapshotBundles, remainingAndExtra, opts.legacy, opts.AuthorizationDecisionRef) if err != nil { return err } @@ -491,7 +493,7 @@ func doDFS(obj map[string]json.RawMessage, path string, roots []string) error { // Note: filepath.Join can return paths with '\' separators, always use // filepath.ToSlash to keep them normalized. - newPath = strings.TrimLeft(filepath.ToSlash(newPath), "/.") + newPath = strings.TrimLeft(normalizePath(newPath), "/.") contains := false prefix := false @@ -755,7 +757,7 @@ func writeData(ctx context.Context, store storage.Store, txn storage.Transaction return nil } -func compileModules(compiler *ast.Compiler, m metrics.Metrics, bundles map[string]*Bundle, extraModules map[string]*ast.Module, legacy bool) error { +func compileModules(compiler *ast.Compiler, m metrics.Metrics, bundles map[string]*Bundle, extraModules map[string]*ast.Module, legacy bool, authorizationDecisionRef ast.Ref) error { m.Timer(metrics.RegoModuleCompile).Start() defer m.Timer(metrics.RegoModuleCompile).Stop() @@ -789,7 +791,11 @@ func compileModules(compiler *ast.Compiler, m metrics.Metrics, bundles map[strin return compiler.Errors } - return nil + if authorizationDecisionRef.Equal(ast.EmptyRef()) { + return nil + } + + return iCompiler.VerifyAuthorizationPolicySchema(compiler, authorizationDecisionRef) } func writeModules(ctx context.Context, store storage.Store, txn storage.Transaction, compiler *ast.Compiler, m metrics.Metrics, bundles map[string]*Bundle, extraModules map[string]*ast.Module, legacy bool) error { diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.3.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.3.json new file mode 100644 index 00000000000..69d7284a112 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.3.json @@ -0,0 +1,4422 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.4.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.4.json new file mode 100644 index 00000000000..69d7284a112 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.47.4.json @@ -0,0 +1,4422 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.48.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.48.0.json new file mode 100644 index 00000000000..a0746f5c139 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.48.0.json @@ -0,0 +1,4466 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.0.json new file mode 100644 index 00000000000..a0746f5c139 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.0.json @@ -0,0 +1,4466 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.1.json new file mode 100644 index 00000000000..a0746f5c139 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.1.json @@ -0,0 +1,4466 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.2.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.2.json new file mode 100644 index 00000000000..a0746f5c139 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.49.2.json @@ -0,0 +1,4466 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.0.json new file mode 100644 index 00000000000..4fe0c2b7fec --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.0.json @@ -0,0 +1,4598 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.1.json new file mode 100644 index 00000000000..4fe0c2b7fec --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.1.json @@ -0,0 +1,4598 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.2.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.2.json new file mode 100644 index 00000000000..4fe0c2b7fec --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.50.2.json @@ -0,0 +1,4598 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.51.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.51.0.json new file mode 100644 index 00000000000..4fe0c2b7fec --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.51.0.json @@ -0,0 +1,4598 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.52.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.52.0.json new file mode 100644 index 00000000000..bfa43f4a597 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.52.0.json @@ -0,0 +1,4615 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.0.json new file mode 100644 index 00000000000..a89d1f859e8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.0.json @@ -0,0 +1,4640 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.1.json new file mode 100644 index 00000000000..a89d1f859e8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.53.1.json @@ -0,0 +1,4640 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.54.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.54.0.json new file mode 100644 index 00000000000..a89d1f859e8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.54.0.json @@ -0,0 +1,4640 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.55.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.55.0.json new file mode 100644 index 00000000000..1b0b80322be --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.55.0.json @@ -0,0 +1,4665 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.56.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.56.0.json new file mode 100644 index 00000000000..50b9a1969c2 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.56.0.json @@ -0,0 +1,4688 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.0.json new file mode 100644 index 00000000000..0ffa520514f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.0.json @@ -0,0 +1,4710 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.1.json new file mode 100644 index 00000000000..0ffa520514f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v0.57.1.json @@ -0,0 +1,4710 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/config/config.go b/vendor/github.com/open-policy-agent/opa/config/config.go new file mode 100644 index 00000000000..bb914d8376e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/config/config.go @@ -0,0 +1,257 @@ +// Copyright 2018 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package config implements OPA configuration file parsing and validation. +package config + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "reflect" + "sort" + "strings" + + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/internal/ref" + "github.com/open-policy-agent/opa/util" + "github.com/open-policy-agent/opa/version" +) + +// Config represents the configuration file that OPA can be started with. +type Config struct { + Services json.RawMessage `json:"services,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Discovery json.RawMessage `json:"discovery,omitempty"` + Bundle json.RawMessage `json:"bundle,omitempty"` // Deprecated: Use `bundles` instead + Bundles json.RawMessage `json:"bundles,omitempty"` + DecisionLogs json.RawMessage `json:"decision_logs,omitempty"` + Status json.RawMessage `json:"status,omitempty"` + Plugins map[string]json.RawMessage `json:"plugins,omitempty"` + Keys json.RawMessage `json:"keys,omitempty"` + DefaultDecision *string `json:"default_decision,omitempty"` + DefaultAuthorizationDecision *string `json:"default_authorization_decision,omitempty"` + Caching json.RawMessage `json:"caching,omitempty"` + NDBuiltinCache bool `json:"nd_builtin_cache,omitempty"` + PersistenceDirectory *string `json:"persistence_directory,omitempty"` + DistributedTracing json.RawMessage `json:"distributed_tracing,omitempty"` + Server *struct { + Encoding json.RawMessage `json:"encoding,omitempty"` + } `json:"server,omitempty"` + Storage *struct { + Disk json.RawMessage `json:"disk,omitempty"` + } `json:"storage,omitempty"` + Extra map[string]json.RawMessage `json:"-"` +} + +// ParseConfig returns a valid Config object with defaults injected. The id +// and version parameters will be set in the labels map. +func ParseConfig(raw []byte, id string) (*Config, error) { + // NOTE(sr): based on https://stackoverflow.com/a/33499066/993018 + var result Config + objValue := reflect.ValueOf(&result).Elem() + knownFields := map[string]reflect.Value{} + for i := 0; i != objValue.NumField(); i++ { + jsonName := strings.Split(objValue.Type().Field(i).Tag.Get("json"), ",")[0] + knownFields[jsonName] = objValue.Field(i) + } + + if err := util.Unmarshal(raw, &result.Extra); err != nil { + return nil, err + } + + for key, chunk := range result.Extra { + if field, found := knownFields[key]; found { + if err := util.Unmarshal(chunk, field.Addr().Interface()); err != nil { + return nil, err + } + delete(result.Extra, key) + } + } + if len(result.Extra) == 0 { + result.Extra = nil + } + return &result, result.validateAndInjectDefaults(id) +} + +// PluginNames returns a sorted list of names of enabled plugins. +func (c Config) PluginNames() (result []string) { + if c.Bundle != nil || c.Bundles != nil { + result = append(result, "bundles") + } + if c.Status != nil { + result = append(result, "status") + } + if c.DecisionLogs != nil { + result = append(result, "decision_logs") + } + for name := range c.Plugins { + result = append(result, name) + } + sort.Strings(result) + return result +} + +// PluginsEnabled returns true if one or more plugin features are enabled. +// +// Deprecated. Use PluginNames instead. +func (c Config) PluginsEnabled() bool { + return c.Bundle != nil || c.Bundles != nil || c.DecisionLogs != nil || c.Status != nil || len(c.Plugins) > 0 +} + +// DefaultDecisionRef returns the default decision as a reference. +func (c Config) DefaultDecisionRef() ast.Ref { + r, _ := ref.ParseDataPath(*c.DefaultDecision) + return r +} + +// DefaultAuthorizationDecisionRef returns the default authorization decision +// as a reference. +func (c Config) DefaultAuthorizationDecisionRef() ast.Ref { + r, _ := ref.ParseDataPath(*c.DefaultAuthorizationDecision) + return r +} + +// NDBuiltinCacheEnabled returns if the ND builtins cache should be used. +func (c Config) NDBuiltinCacheEnabled() bool { + return c.NDBuiltinCache +} + +func (c *Config) validateAndInjectDefaults(id string) error { + + if c.DefaultDecision == nil { + s := defaultDecisionPath + c.DefaultDecision = &s + } + + _, err := ref.ParseDataPath(*c.DefaultDecision) + if err != nil { + return err + } + + if c.DefaultAuthorizationDecision == nil { + s := defaultAuthorizationDecisionPath + c.DefaultAuthorizationDecision = &s + } + + _, err = ref.ParseDataPath(*c.DefaultAuthorizationDecision) + if err != nil { + return err + } + + if c.Labels == nil { + c.Labels = map[string]string{} + } + + c.Labels["id"] = id + c.Labels["version"] = version.Version + + return nil +} + +// GetPersistenceDirectory returns the configured persistence directory, or $PWD/.opa if none is configured +func (c Config) GetPersistenceDirectory() (string, error) { + if c.PersistenceDirectory == nil { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + return filepath.Join(pwd, ".opa"), nil + } + return *c.PersistenceDirectory, nil +} + +// ActiveConfig returns OPA's active configuration +// with the credentials and crypto keys removed +func (c *Config) ActiveConfig() (interface{}, error) { + bs, err := json.Marshal(c) + if err != nil { + return nil, err + } + + var result map[string]interface{} + if err := util.UnmarshalJSON(bs, &result); err != nil { + return nil, err + } + for k, e := range c.Extra { + var v any + if err := util.UnmarshalJSON(e, &v); err != nil { + return nil, err + } + result[k] = v + } + + if err := removeServiceCredentials(result["services"]); err != nil { + return nil, err + } + + if err := removeCryptoKeys(result["keys"]); err != nil { + return nil, err + } + + return result, nil +} + +func removeServiceCredentials(x interface{}) error { + switch x := x.(type) { + case nil: + return nil + case []interface{}: + for _, v := range x { + err := removeKey(v, "credentials") + if err != nil { + return err + } + } + + case map[string]interface{}: + for _, v := range x { + err := removeKey(v, "credentials") + if err != nil { + return err + } + } + default: + return fmt.Errorf("illegal service config type: %T", x) + } + + return nil +} + +func removeCryptoKeys(x interface{}) error { + switch x := x.(type) { + case nil: + return nil + case map[string]interface{}: + for _, v := range x { + err := removeKey(v, "key", "private_key") + if err != nil { + return err + } + } + default: + return fmt.Errorf("illegal keys config type: %T", x) + } + + return nil +} + +func removeKey(x interface{}, keys ...string) error { + val, ok := x.(map[string]interface{}) + if !ok { + return fmt.Errorf("type assertion error") + } + + for _, key := range keys { + delete(val, key) + } + + return nil +} + +const ( + defaultDecisionPath = "/system/main" + defaultAuthorizationDecisionPath = "/system/authz/allow" +) diff --git a/vendor/github.com/open-policy-agent/opa/format/format.go b/vendor/github.com/open-policy-agent/opa/format/format.go index 078933295c2..edd287ca83c 100644 --- a/vendor/github.com/open-policy-agent/opa/format/format.go +++ b/vendor/github.com/open-policy-agent/opa/format/format.go @@ -10,9 +10,12 @@ import ( "fmt" "regexp" "sort" + "strings" + "unicode" "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/future" + "github.com/open-policy-agent/opa/types" ) // Opts lets you control the code formatting via `AstWithOpts()`. @@ -37,6 +40,7 @@ func Source(filename string, src []byte) ([]byte, error) { if err != nil { return nil, err } + formatted, err := Ast(module) if err != nil { return nil, fmt.Errorf("%s: %v", filename, err) @@ -142,6 +146,7 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { w := &writer{ indent: "\t", + errs: make([]*ast.Error, 0), } switch x := x.(type) { @@ -178,6 +183,9 @@ func AstWithOpts(x interface{}, opts Opts) ([]byte, error) { return nil, fmt.Errorf("not an ast element: %v", x) } + if len(w.errs) > 0 { + return nil, w.errs + } return squashTrailingNewlines(w.buf.Bytes()), nil } @@ -228,6 +236,7 @@ type writer struct { inline bool beforeEnd *ast.Comment delay bool + errs ast.Errors } func (w *writer) writeModule(module *ast.Module, o fmtOpts) { @@ -255,13 +264,12 @@ func (w *writer) writeModule(module *ast.Module, o fmtOpts) { return locLess(comments[i], comments[j]) }) - // XXX: The parser currently duplicates comments for some reason, so we need - // to remove duplicates here. - comments = dedupComments(comments) sort.Slice(others, func(i, j int) bool { return locLess(others[i], others[j]) }) + comments = trimTrailingWhitespaceInComments(comments) + comments = w.writePackage(pkg, comments) var imports []*ast.Import var rules []*ast.Rule @@ -280,6 +288,14 @@ func (w *writer) writeModule(module *ast.Module, o fmtOpts) { } } +func trimTrailingWhitespaceInComments(comments []*ast.Comment) []*ast.Comment { + for _, c := range comments { + c.Text = bytes.TrimRightFunc(c.Text, unicode.IsSpace) + } + + return comments +} + func (w *writer) writePackage(pkg *ast.Package, comments []*ast.Comment) []*ast.Comment { comments = w.insertComments(comments, pkg.Location) @@ -445,7 +461,7 @@ func (w *writer) writeElse(rule *ast.Rule, o fmtOpts, comments []*ast.Comment) [ func (w *writer) writeHead(head *ast.Head, isDefault, isExpandedConst bool, o fmtOpts, comments []*ast.Comment) []*ast.Comment { ref := head.Ref() - if head.Key != nil && head.Value == nil { + if head.Key != nil && head.Value == nil && !head.HasDynamicRef() { ref = ref.GroundPrefix() } if o.refHeads || len(ref) == 1 { @@ -587,7 +603,7 @@ func (w *writer) writeSomeDecl(decl *ast.SomeDecl, comments []*ast.Comment) []*a w.write(",") } case ast.Call: - comments = w.writeInOperator(false, val[1:], comments) + comments = w.writeInOperator(false, val[1:], comments, decl.Location, ast.BuiltinMap[val[0].String()].Decl) } } @@ -622,7 +638,7 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a switch operator { case ast.Member.Name, ast.MemberWithKey.Name: - return w.writeInOperator(false, terms[1:], comments) + return w.writeInOperator(false, terms[1:], comments, terms[0].Location, ast.BuiltinMap[terms[0].String()].Decl) } bi, ok := ast.BuiltinMap[operator] @@ -647,6 +663,9 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) []*a comments = w.writeTerm(terms[2], comments) return comments } + // NOTE(Trolloldem): in this point we are operating with a built-in function with the + // wrong arity even when the assignment notation is used + w.errs = append(w.errs, ArityFormatMismatchError(terms[1:], terms[0].String(), terms[0].Location, bi.Decl)) return w.writeFunctionCallPlain(terms, comments) } @@ -708,7 +727,7 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co case ast.Var: w.write(w.formatVar(x)) case ast.Call: - comments = w.writeCall(parens, x, comments) + comments = w.writeCall(parens, x, term.Location, comments) case fmt.Stringer: w.write(x.String()) } @@ -721,7 +740,12 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co func (w *writer) writeRef(x ast.Ref) { if len(x) > 0 { - w.writeTerm(x[0], nil) + parens := false + _, ok := x[0].Value.(ast.Call) + if ok { + parens = x[0].Location.Text[0] == 40 // Starts with "(" + } + w.writeTermParens(parens, x[0], nil) path := x[1:] for _, t := range path { switch p := t.Value.(type) { @@ -760,7 +784,7 @@ func (w *writer) formatVar(v ast.Var) string { return v.String() } -func (w *writer) writeCall(parens bool, x ast.Call, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeCall(parens bool, x ast.Call, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { bi, ok := ast.BuiltinMap[x[0].String()] if !ok || bi.Infix == "" { return w.writeFunctionCallPlain(x, comments) @@ -769,13 +793,22 @@ func (w *writer) writeCall(parens bool, x ast.Call, comments []*ast.Comment) []* if bi.Infix == "in" { // NOTE(sr): `in` requires special handling, mirroring what happens in the parser, // since there can be one or two lhs arguments. - return w.writeInOperator(true, x[1:], comments) + return w.writeInOperator(true, x[1:], comments, loc, bi.Decl) } // TODO(tsandall): improve to consider precedence? if parens { w.write("(") } + + // NOTE(Trolloldem): writeCall is only invoked when the function call is a term + // of another function. The only valid arity is the one of the + // built-in function + if len(bi.Decl.Args()) != len(x)-1 { + w.errs = append(w.errs, ArityFormatMismatchError(x[1:], x[0].String(), loc, bi.Decl)) + return comments + } + comments = w.writeTermParens(true, x[1], comments) w.write(" " + bi.Infix + " ") comments = w.writeTermParens(true, x[2], comments) @@ -786,7 +819,16 @@ func (w *writer) writeCall(parens bool, x ast.Call, comments []*ast.Comment) []* return comments } -func (w *writer) writeInOperator(parens bool, operands []*ast.Term, comments []*ast.Comment) []*ast.Comment { +func (w *writer) writeInOperator(parens bool, operands []*ast.Term, comments []*ast.Comment, loc *ast.Location, f *types.Function) []*ast.Comment { + if len(operands) != len(f.Args()) { + // The number of operands does not math the arity of the `in` operator + operator := ast.Member.Name + if len(f.Args()) == 3 { + operator = ast.MemberWithKey.Name + } + w.errs = append(w.errs, ArityFormatMismatchError(operands, operator, loc, f)) + return comments + } kw := "in" switch len(operands) { case 2: @@ -880,12 +922,17 @@ func (w *writer) writeObjectComprehension(object *ast.ObjectComprehension, loc * } func (w *writer) writeComprehension(open, close byte, term *ast.Term, body ast.Body, loc *ast.Location, comments []*ast.Comment) []*ast.Comment { - if term.Location.Row-loc.Row > 1 { + if term.Location.Row-loc.Row >= 1 { w.endLine() w.startLine() } - comments = w.writeTerm(term, comments) + parens := false + _, ok := term.Value.(ast.Call) + if ok { + parens = term.Location.Text[0] == 40 // Starts with "(" + } + comments = w.writeTermParens(parens, term, comments) w.write(" |") return w.writeComprehensionBody(open, close, body, term.Location, loc, comments) @@ -1251,21 +1298,6 @@ func skipPast(open, close byte, loc *ast.Location) (int, int) { return i, offset } -func dedupComments(comments []*ast.Comment) []*ast.Comment { - if len(comments) == 0 { - return nil - } - - filtered := []*ast.Comment{comments[0]} - for i := 1; i < len(comments); i++ { - if comments[i].Location.Equal(comments[i-1].Location) { - continue - } - filtered = append(filtered, comments[i]) - } - return filtered -} - // startLine begins a line with the current indentation level. func (w *writer) startLine() { w.inline = true @@ -1356,3 +1388,36 @@ func ensureFutureKeywordImport(imps []*ast.Import, kw string) []*ast.Import { imp.Location = defaultLocation(imp) return append(imps, imp) } + +// ArgErrDetail but for `fmt` checks since compiler has not run yet. +type ArityFormatErrDetail struct { + Have []string `json:"have"` + Want []string `json:"want"` +} + +// arityMismatchError but for `fmt` checks since the compiler has not run yet. +func ArityFormatMismatchError(operands []*ast.Term, operator string, loc *ast.Location, f *types.Function) *ast.Error { + want := make([]string, len(f.Args())) + for i := range f.Args() { + want[i] = types.Sprint(f.Args()[i]) + } + + have := make([]string, len(operands)) + for i := 0; i < len(operands); i++ { + have[i] = ast.TypeName(operands[i].Value) + } + err := ast.NewError(ast.TypeErr, loc, "%s: %s", operator, "arity mismatch") + err.Details = &ArityFormatErrDetail{ + Have: have, + Want: want, + } + return err +} + +// Lines returns the string representation of the detail. +func (d *ArityFormatErrDetail) Lines() []string { + return []string{ + "have: " + "(" + strings.Join(d.Have, ",") + ")", + "want: " + "(" + strings.Join(d.Want, ",") + ")", + } +} diff --git a/vendor/github.com/open-policy-agent/opa/hooks/hooks.go b/vendor/github.com/open-policy-agent/opa/hooks/hooks.go new file mode 100644 index 00000000000..9659d7b4997 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/hooks/hooks.go @@ -0,0 +1,77 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package hooks + +import ( + "context" + "fmt" + + "github.com/open-policy-agent/opa/config" +) + +// Hook is a hook to be called in some select places in OPA's operation. +// +// The base Hook interface is any, and wherever a hook can occur, the calling code +// will check if your hook implements an appropriate interface. If so, your hook +// is called. +// +// This allows you to only hook in to behavior you care about, and it allows the +// OPA to add more hooks in the future. +// +// All hook interfaces in this package have Hook in the name. Hooks must be safe +// for concurrent use. It is expected that hooks are fast; if a hook needs to take +// time, then copy what you need and ensure the hook is async. +// +// When multiple instances of a hook are provided, they are all going to be executed +// in an unspecified order (it's a map-range call underneath). If you need hooks to +// be run in order, you can wrap them into another hook, and configure that one. +type Hook any + +// Hooks is the type used for every struct in OPA that can work with hooks. +type Hooks struct { + m map[Hook]struct{} // we are NOT providing a stable invocation ordering +} + +// New creates a new instance of Hooks. +func New(hs ...Hook) Hooks { + h := Hooks{m: make(map[Hook]struct{}, len(hs))} + for i := range hs { + h.m[hs[i]] = struct{}{} + } + return h +} + +func (hs Hooks) Each(fn func(Hook)) { + for h := range hs.m { + fn(h) + } +} + +// ConfigHook allows inspecting or rewriting the configuration when the plugin +// manager is processing it. +// Note that this hook is not run when the plugin manager is reconfigured. This +// usually only happens when there's a new config from a discovery bundle, and +// for processing _that_, there's `ConfigDiscoveryHook`. +type ConfigHook interface { + OnConfig(context.Context, *config.Config) (*config.Config, error) +} + +// ConfigHook allows inspecting or rewriting the discovered configuration when +// the discovery plugin is processing it. +type ConfigDiscoveryHook interface { + OnConfigDiscovery(context.Context, *config.Config) (*config.Config, error) +} + +func (hs Hooks) Validate() error { + for h := range hs.m { + switch h.(type) { + case ConfigHook, + ConfigDiscoveryHook: // OK + default: + return fmt.Errorf("unknown hook type %T", h) + } + } + return nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go b/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go index 0e0775b1fd9..a541c45f1f2 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go +++ b/vendor/github.com/open-policy-agent/opa/internal/bundle/utils.go @@ -7,6 +7,9 @@ package bundle import ( "context" "fmt" + "io" + "os" + "path/filepath" "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/bundle" @@ -83,3 +86,55 @@ func LoadWasmResolversFromStore(ctx context.Context, store storage.Store, txn st } return resolvers, nil } + +// LoadBundleFromDisk loads a previously persisted activated bundle from disk +func LoadBundleFromDisk(path, name string, bvc *bundle.VerificationConfig) (*bundle.Bundle, error) { + bundlePath := filepath.Join(path, name, "bundle.tar.gz") + + if _, err := os.Stat(bundlePath); err == nil { + f, err := os.Open(filepath.Join(bundlePath)) + if err != nil { + return nil, err + } + defer f.Close() + + r := bundle.NewCustomReader(bundle.NewTarballLoaderWithBaseURL(f, "")) + + if bvc != nil { + r = r.WithBundleVerificationConfig(bvc) + } + + b, err := r.Read() + if err != nil { + return nil, err + } + return &b, nil + } else if os.IsNotExist(err) { + return nil, nil + } else { + return nil, err + } +} + +// SaveBundleToDisk saves the given raw bytes representing the bundle's content to disk +func SaveBundleToDisk(path string, raw io.Reader) (string, error) { + if _, err := os.Stat(path); os.IsNotExist(err) { + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return "", err + } + } + + if raw == nil { + return "", fmt.Errorf("no raw bundle bytes to persist to disk") + } + + dest, err := os.CreateTemp(path, ".bundle.tar.gz.*.tmp") + if err != nil { + return "", err + } + defer dest.Close() + + _, err = io.Copy(dest, raw) + return dest.Name(), err +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go b/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go new file mode 100644 index 00000000000..4d80aeeef98 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/utils.go @@ -0,0 +1,89 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package compiler + +import ( + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/schemas" + "github.com/open-policy-agent/opa/util" +) + +type SchemaFile string + +const ( + AuthorizationPolicySchema SchemaFile = "authorizationPolicy.json" +) + +var schemaDefinitions = map[SchemaFile]interface{}{} + +// VerifyAuthorizationPolicySchema performs type checking on rules against the schema for the Authorization Policy +// Input document. +// NOTE: The provided compiler should have already run the compilation process on the input modules +func VerifyAuthorizationPolicySchema(compiler *ast.Compiler, ref ast.Ref) error { + + rules := getRulesWithDependencies(compiler, ref) + + if len(rules) == 0 { + return nil + } + + schemaSet := ast.NewSchemaSet() + schemaSet.Put(ast.SchemaRootRef, schemaDefinitions[AuthorizationPolicySchema]) + + errs := ast.NewCompiler().WithSchemas(schemaSet).PassesTypeCheckRules(rules) + + if len(errs) > 0 { + return errs + } + + return nil +} + +// getRulesWithDependencies returns a slice of rules that are referred to by ref along with their dependencies +func getRulesWithDependencies(compiler *ast.Compiler, ref ast.Ref) []*ast.Rule { + allRules := compiler.GetRules(ref) + + deps := map[*ast.Rule]struct{}{} + for _, rule := range allRules { + transitiveDependencies(compiler, rule, deps) + } + + for dep := range deps { + allRules = append(allRules, dep) + } + + return allRules +} + +func transitiveDependencies(compiler *ast.Compiler, rule *ast.Rule, deps map[*ast.Rule]struct{}) { + for x := range compiler.Graph.Dependencies(rule) { + other := x.(*ast.Rule) + deps[other] = struct{}{} + transitiveDependencies(compiler, other, deps) + } +} + +func loadAuthorizationPolicySchema() { + + cont, err := schemas.FS.ReadFile(string(AuthorizationPolicySchema)) + if err != nil { + panic(err) + } + + if len(cont) == 0 { + panic("expected authorization policy schema file to be present") + } + + var schema interface{} + if err := util.Unmarshal(cont, &schema); err != nil { + panic(err) + } + + schemaDefinitions[AuthorizationPolicySchema] = schema +} + +func init() { + loadAuthorizationPolicySchema() +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv index 1ac25c0572b..aca89887eb9 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv @@ -344,12 +344,18 @@ opa_json_writer_write,opa_json_writer_emit_value opa_json_writer_write,opa_free opa_json_dump,opa_json_writer_write opa_value_dump,opa_json_writer_write +move_freelists,opa_abort +opa_heap_blocks_stash,move_freelists +opa_heap_blocks_restore,move_freelists +opa_malloc,opa_free_bulk_commit opa_malloc,opa_abort +opa_free_bulk_commit,merge_sort_blocks opa_realloc,opa_malloc opa_realloc,memcpy opa_realloc,opa_free opa_builtin_cache_get,opa_abort opa_builtin_cache_set,opa_abort +merge_sort_blocks,merge_sort_blocks opa_memoize_init,opa_malloc opa_memoize_init,opa_object opa_memoize_push,opa_malloc @@ -545,6 +551,10 @@ __merge,opa_value_type __merge,__merge __merge,opa_object_insert __merge,opa_value_get +builtin_object_union_n,opa_value_iter +builtin_object_union_n,opa_value_get +builtin_object_union_n,opa_value_type +builtin_object_union_n,__merge builtin_json_remove,opa_value_type builtin_json_remove,__get_json_paths builtin_json_remove,__paths_to_object @@ -565,14 +575,14 @@ opa_sets_intersection,opa_value_type opa_sets_intersection,opa_set opa_sets_intersection,opa_set_union opa_sets_intersection,opa_set_intersection -opa_sets_intersection,opa_value_free +opa_sets_intersection,opa_value_free_shallow opa_set_union,opa_value_type opa_set_union,opa_set opa_set_union,opa_set_add opa_sets_union,opa_value_type opa_sets_union,opa_set opa_sets_union,opa_set_add -opa_sets_union,opa_value_free +opa_sets_union,opa_value_free_shallow opa_strings_any_prefix_match,opa_value_type opa_strings_any_prefix_match,opa_value_iter opa_strings_any_prefix_match,opa_value_get @@ -781,10 +791,31 @@ opa_object_keys,opa_strncmp opa_object_keys,opa_value_compare_object opa_object_keys,opa_abort opa_object_keys,opa_value_compare_set -opa_value_free,opa_free +opa_array_free,__opa_value_free +opa_array_free,opa_free +opa_array_free,opa_free_bulk +__opa_value_free,opa_free_bulk +__opa_value_free,opa_free +__opa_value_free,opa_array_free +__opa_value_free,__opa_object_buckets_free +__opa_value_free,__opa_set_buckets_free +__opa_object_buckets_free,opa_free +__opa_object_buckets_free,opa_array_free +__opa_object_buckets_free,__opa_object_buckets_free +__opa_object_buckets_free,__opa_set_buckets_free +__opa_object_buckets_free,__opa_value_free +__opa_object_buckets_free,opa_free_bulk +__opa_set_buckets_free,opa_free +__opa_set_buckets_free,opa_array_free +__opa_set_buckets_free,__opa_object_buckets_free +__opa_set_buckets_free,__opa_set_buckets_free +__opa_set_buckets_free,__opa_value_free +__opa_set_buckets_free,opa_free_bulk +opa_value_free,__opa_value_free +opa_value_free_shallow,__opa_value_free opa_value_merge,opa_malloc opa_value_merge,opa_value_get -opa_value_merge,opa_object_insert +opa_value_merge,__opa_object_insert opa_value_merge,opa_value_merge opa_value_merge,opa_abort opa_value_merge,opa_atoi64 @@ -794,19 +825,12 @@ opa_value_merge,opa_strncmp opa_value_merge,opa_value_compare opa_value_merge,opa_value_compare_object opa_value_merge,opa_value_compare_set -opa_object_insert,opa_value_hash -opa_object_insert,opa_value_compare -opa_object_insert,__opa_object_grow -opa_object_insert,opa_malloc -__opa_object_grow,opa_malloc -__opa_object_grow,opa_value_hash -__opa_object_grow,opa_value_compare_number -__opa_object_grow,opa_strncmp -__opa_object_grow,opa_value_compare -__opa_object_grow,opa_value_compare_object -__opa_object_grow,opa_value_compare_set -__opa_object_grow,opa_abort -__opa_object_grow,opa_free +__opa_object_insert,opa_value_hash +__opa_object_insert,opa_value_compare +__opa_object_insert,__opa_value_free +__opa_object_insert,__opa_object_grow +__opa_object_insert,opa_malloc +opa_object_insert,__opa_object_insert opa_boolean,opa_malloc opa_number_ref,opa_malloc opa_number_int,opa_malloc @@ -814,7 +838,7 @@ opa_string,opa_malloc opa_value_shallow_copy_object,opa_malloc opa_value_shallow_copy_object,opa_value_iter opa_value_shallow_copy_object,opa_value_get -opa_value_shallow_copy_object,opa_object_insert +opa_value_shallow_copy_object,__opa_object_insert opa_value_shallow_copy_set,opa_malloc opa_value_shallow_copy_set,opa_value_iter opa_value_shallow_copy_set,opa_set_add @@ -857,15 +881,27 @@ opa_array_with_cap,opa_free opa_object,opa_malloc opa_set,opa_malloc opa_set_with_cap,opa_malloc +__opa_object_grow,opa_malloc +__opa_object_grow,opa_value_hash +__opa_object_grow,opa_value_compare_number +__opa_object_grow,opa_strncmp +__opa_object_grow,opa_value_compare +__opa_object_grow,opa_value_compare_object +__opa_object_grow,opa_value_compare_set +__opa_object_grow,opa_abort +__opa_object_grow,opa_free +opa_object_remove,opa_value_hash +opa_object_remove,opa_value_compare +opa_object_remove,__opa_value_free +opa_object_remove,opa_free_bulk +opa_object_remove,opa_free +opa_string_copy,opa_malloc opa_value_add_path,opa_value_get opa_value_add_path,opa_malloc -opa_value_add_path,opa_object_insert -opa_value_add_path,opa_value_free +opa_value_add_path,__opa_object_insert +opa_value_add_path,__opa_value_free opa_value_remove_path,opa_value_get -opa_value_remove_path,opa_value_hash -opa_value_remove_path,opa_value_compare -opa_value_remove_path,opa_value_free -opa_value_remove_path,opa_free +opa_value_remove_path,opa_object_remove opa_lookup,opa_value_get opa_lookup,opa_value_iter opa_lookup,opa_atoi64 diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm index 0b25bb53d92..70aba781e7b 100644 Binary files a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm and b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm differ diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go index 3e397925203..72e4940dba3 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go @@ -28,7 +28,7 @@ import ( const ( opaWasmABIVersionVal = 1 opaWasmABIVersionVar = "opa_wasm_abi_version" - opaWasmABIMinorVersionVal = 2 + opaWasmABIMinorVersionVal = 3 opaWasmABIMinorVersionVar = "opa_wasm_abi_minor_version" ) @@ -142,6 +142,7 @@ var builtinsFunctions = map[string]string{ ast.ObjectKeys.Name: "builtin_object_keys", ast.ObjectRemove.Name: "builtin_object_remove", ast.ObjectUnion.Name: "builtin_object_union", + ast.ObjectUnionN.Name: "builtin_object_union_n", ast.Concat.Name: "opa_strings_concat", ast.FormatInt.Name: "opa_strings_format_int", ast.IndexOf.Name: "opa_strings_indexof", diff --git a/vendor/github.com/open-policy-agent/opa/internal/config/config.go b/vendor/github.com/open-policy-agent/opa/internal/config/config.go new file mode 100644 index 00000000000..b1a9731f65d --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/config/config.go @@ -0,0 +1,168 @@ +// Copyright 2020 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package config implements helper functions to parse OPA's configuration. +package config + +import ( + "encoding/json" + "fmt" + "os" + "regexp" + "strings" + + "sigs.k8s.io/yaml" + + "github.com/open-policy-agent/opa/internal/strvals" + "github.com/open-policy-agent/opa/keys" + "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/plugins/rest" + "github.com/open-policy-agent/opa/tracing" + "github.com/open-policy-agent/opa/util" +) + +// ServiceOptions stores the options passed to ParseServicesConfig +type ServiceOptions struct { + Raw json.RawMessage + AuthPlugin rest.AuthPluginLookupFunc + Keys map[string]*keys.Config + Logger logging.Logger + DistributedTacingOpts tracing.Options +} + +// ParseServicesConfig returns a set of named service clients. The service +// clients can be specified either as an array or as a map. Some systems (e.g., +// Helm) do not have proper support for configuration values nested under +// arrays, so just support both here. +func ParseServicesConfig(opts ServiceOptions) (map[string]rest.Client, error) { + + services := map[string]rest.Client{} + + var arr []json.RawMessage + var obj map[string]json.RawMessage + + if err := util.Unmarshal(opts.Raw, &arr); err == nil { + for _, s := range arr { + client, err := rest.New(s, opts.Keys, rest.AuthPluginLookup(opts.AuthPlugin), rest.Logger(opts.Logger), rest.DistributedTracingOpts(opts.DistributedTacingOpts)) + if err != nil { + return nil, err + } + services[client.Service()] = client + } + } else if util.Unmarshal(opts.Raw, &obj) == nil { + for k := range obj { + client, err := rest.New(obj[k], opts.Keys, rest.Name(k), rest.AuthPluginLookup(opts.AuthPlugin), rest.Logger(opts.Logger), rest.DistributedTracingOpts(opts.DistributedTacingOpts)) + if err != nil { + return nil, err + } + services[client.Service()] = client + } + } else { + // Return error from array decode as that is the default format. + return nil, err + } + + return services, nil +} + +// Load implements configuration file loading. The supplied config file will be +// read from disk (if specified) and overrides will be applied. If no config file is +// specified, the overrides can still be applied to an empty config. +func Load(configFile string, overrides []string, overrideFiles []string) ([]byte, error) { + baseConf := map[string]interface{}{} + + // User specified config file + if configFile != "" { + var bytes []byte + var err error + bytes, err = os.ReadFile(configFile) + if err != nil { + return nil, err + } + + processedConf := subEnvVars(string(bytes)) + + if err := yaml.Unmarshal([]byte(processedConf), &baseConf); err != nil { + return nil, fmt.Errorf("failed to parse %s: %s", configFile, err) + } + } + + overrideConf := map[string]interface{}{} + + // User specified a config override via --set + for _, override := range overrides { + processedOverride := subEnvVars(override) + if err := strvals.ParseInto(processedOverride, overrideConf); err != nil { + return nil, fmt.Errorf("failed parsing --set data: %s", err) + } + } + + // User specified a config override value via --set-file + for _, override := range overrideFiles { + reader := func(rs []rune) (interface{}, error) { + bytes, err := os.ReadFile(string(rs)) + value := strings.TrimSpace(string(bytes)) + return value, err + } + if err := strvals.ParseIntoFile(override, overrideConf, reader); err != nil { + return nil, fmt.Errorf("failed parsing --set-file data: %s", err) + } + } + + // Merge together base config file and overrides, prefer the overrides + conf := mergeValues(baseConf, overrideConf) + + // Take the patched config and marshal back to YAML + return yaml.Marshal(conf) +} + +// regex looking for ${...} notation strings +var envRegex = regexp.MustCompile(`(?U:\${.*})`) + +// subEnvVars will look for any environment variables in the passed in string +// with the syntax of ${VAR_NAME} and replace that string with ENV[VAR_NAME] +func subEnvVars(s string) string { + updatedConfig := envRegex.ReplaceAllStringFunc(s, func(s string) string { + // Trim off the '${' and '}' + if len(s) <= 3 { + // This should never happen.. + return "" + } + varName := s[2 : len(s)-1] + + // Lookup the variable in the environment. We play by + // bash rules.. if its undefined we'll treat it as an + // empty string instead of raising an error. + return os.Getenv(varName) + }) + + return updatedConfig +} + +// mergeValues will merge source and destination map, preferring values from the source map +func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[string]interface{} { + for k, v := range src { + // If the key doesn't exist already, then just set the key to that value + if _, exists := dest[k]; !exists { + dest[k] = v + continue + } + nextMap, ok := v.(map[string]interface{}) + // If it isn't another map, overwrite the value + if !ok { + dest[k] = v + continue + } + // Edge case: If the key exists in the destination, but isn't a map + destMap, isMap := dest[k].(map[string]interface{}) + // If the source map has a map for this key, prefer it + if !isMap { + dest[k] = v + continue + } + // If we got to this point, it is a map in both, so merge them + dest[k] = mergeValues(destMap, nextMap) + } + return dest +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/README.md b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/README.md new file mode 100644 index 00000000000..c98de9ee435 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/README.md @@ -0,0 +1,15 @@ +# godropbox [![GoDoc](https://godoc.org/github.com/dropbox/godropbox?status.svg)](https://godoc.org/github.com/dropbox/godropbox) [![Actions Status](https://github.com/dropbox/godropbox/workflows/Test/badge.svg)](https://github.com/dropbox/godropbox/actions) [![Actions Status](https://github.com/dropbox/godropbox/workflows/Lint/badge.svg)](https://github.com/dropbox/godropbox/actions) + +Common libraries for writing go services/applications on Linux servers. + +### Requirements + * Go 1.13+ + * Linux/x64 + +### Installation +``go get github.com/dropbox/godropbox`` + +### Documentation + +See https://pkg.go.dev/github.com/dropbox/godropbox for modules documentation. + diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go new file mode 100644 index 00000000000..89e7e137b74 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/bitvector.go @@ -0,0 +1,206 @@ +// Package bitvector provides the implementation of a variable sized compact vector of bits +// which supports lookups, sets, appends, insertions, and deletions. +package bitvector + +// A BitVector is a variable sized vector of bits. It supports +// lookups, sets, appends, insertions, and deletions. +// +// This class is not thread safe. +type BitVector struct { + data []byte + length int +} + +// NewBitVector creates and initializes a new bit vector with length +// elements, using data as its initial contents. +func NewBitVector(data []byte, length int) *BitVector { + return &BitVector{ + data: data, + length: length, + } +} + +// Bytes returns a slice of the contents of the bit vector. If the caller changes the returned slice, +// the contents of the bit vector may change. +func (vector *BitVector) Bytes() []byte { + return vector.data +} + +// Length returns the current number of elements in the bit vector. +func (vector *BitVector) Length() int { + return vector.length +} + +// This function shifts a byte slice one bit lower (less significant). +// bit (either 1 or 0) contains the bit to put in the most significant +// position of the last byte in the slice. +// This returns the bit that was shifted off of the last byte. +func shiftLower(bit byte, b []byte) byte { + bit = bit << 7 + for i := len(b) - 1; i >= 0; i-- { + newByte := b[i] >> 1 + newByte |= bit + bit = (b[i] & 1) << 7 + b[i] = newByte + } + return bit >> 7 +} + +// This function shifts a byte slice one bit higher (more significant). +// bit (either 1 or 0) contains the bit to put in the least significant +// position of the first byte in the slice. +// This returns the bit that was shifted off the last byte. +func shiftHigher(bit byte, b []byte) byte { + for i := 0; i < len(b); i++ { + newByte := b[i] << 1 + newByte |= bit + bit = (b[i] & 0x80) >> 7 + b[i] = newByte + } + return bit +} + +// Returns the minimum number of bytes needed for storing the bit vector. +func (vector *BitVector) bytesLength() int { + lastBitIndex := vector.length - 1 + lastByteIndex := lastBitIndex >> 3 + return lastByteIndex + 1 +} + +// Panics if the given index is not within the bounds of the bit vector. +func (vector *BitVector) indexAssert(i int) { + if i < 0 || i >= vector.length { + panic("Attempted to access element outside buffer") + } +} + +// Append adds a bit to the end of a bit vector. +func (vector *BitVector) Append(bit byte) { + index := uint32(vector.length) + vector.length++ + + if vector.bytesLength() > len(vector.data) { + vector.data = append(vector.data, 0) + } + + byteIndex := index >> 3 + byteOffset := index % 8 + oldByte := vector.data[byteIndex] + var newByte byte + if bit == 1 { + newByte = oldByte | 1<> 3 + byteOffset := uint32(i % 8) + b := vector.data[byteIndex] + // Check the offset bit + return (b >> byteOffset) & 1 +} + +// Set changes the bit in the ith index of the bit vector to the value specified in +// bit. +func (vector *BitVector) Set(bit byte, index int) { + vector.indexAssert(index) + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + + oldByte := vector.data[byteIndex] + + var newByte byte + if bit == 1 { + // turn on the byteOffset'th bit + newByte = oldByte | 1< len(vector.data) { + vector.data = append(vector.data, 0) + } + + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + var bitToInsert byte + if bit == 1 { + bitToInsert = 1 << byteOffset + } + + oldByte := vector.data[byteIndex] + // This bit will need to be shifted into the next byte + leftoverBit := (oldByte & 0x80) >> 7 + // Make masks to pull off the bits below and above byteOffset + // This mask has the byteOffset lowest bits set. + bottomMask := byte((1 << byteOffset) - 1) + // This mask has the 8 - byteOffset top bits set. + topMask := ^bottomMask + top := (oldByte & topMask) << 1 + newByte := bitToInsert | (oldByte & bottomMask) | top + + vector.data[byteIndex] = newByte + // Shift the rest of the bytes in the slice one higher, append + // the leftoverBit obtained above. + shiftHigher(leftoverBit, vector.data[byteIndex+1:]) +} + +// Delete removes the bit in the supplied index of the bit vector. All +// bits in positions greater than or equal to index before the call will +// be shifted down by one. +func (vector *BitVector) Delete(index int) { + vector.indexAssert(index) + vector.length-- + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + + oldByte := vector.data[byteIndex] + + // Shift all the bytes above the byte we're modifying, return the + // leftover bit to include in the byte we're modifying. + bit := shiftLower(0, vector.data[byteIndex+1:]) + + // Modify oldByte. + // At a high level, we want to select the bits above byteOffset, + // and shift them down by one, removing the bit at byteOffset. + + // This selects the bottom bits + bottomMask := byte((1 << byteOffset) - 1) + // This selects the top (8 - byteOffset - 1) bits + topMask := byte(^((1 << (byteOffset + 1)) - 1)) + // newTop is the top bits, shifted down one, combined with the leftover bit from shifting + // the other bytes. + newTop := (oldByte&topMask)>>1 | (bit << 7) + // newByte takes the bottom bits and combines with the new top. + newByte := (bottomMask & oldByte) | newTop + vector.data[byteIndex] = newByte + + // The desired length is the byte index of the last element plus one, + // where the byte index of the last element is the bit index of the last + // element divided by 8. + byteLength := vector.bytesLength() + if byteLength < len(vector.data) { + vector.data = vector.data[:byteLength] + } +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/license.txt b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/license.txt new file mode 100644 index 00000000000..04d42108eeb --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/bitvector/license.txt @@ -0,0 +1,27 @@ +Copyright (c) 2014 Dropbox, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go b/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go new file mode 100644 index 00000000000..9cfaee8bafc --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/edittree/edittree.go @@ -0,0 +1,1185 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package EditTree implements a specialized tree data structure that +// allows for cheap edits and modifications of nested Term structures. +// +// # Overview +// +// The EditTree data structure exists to solve an ugly problem in Rego: +// modification/deletion of a Term can be very expensive, because we have +// to rebuild the whole Term, sans the modified/deleted parts. +// +// To work around that problem, the EditTree allows simple add, modify, or +// delete operations on Term structures, and then at the end of a series of +// edits, the caller can pay the cost of generating a new Term from the +// tree of edits relatively efficiently. (Essentially a recursive, DFS +// traversal of the tree.) +// +// The data structure preserves basic type/safety properties, the same as +// working on the real underlying Term values. To do this, recursive +// lookups are used. On average, these are fairly straightforward and +// cheap to do. +// +// Basic Operations: +// - Insert/update EditTree node +// - Delete EditTree node +// - Unfold EditTree nodes along a path +// - Render EditTree node +// +// These operations provide all of the basic utilities required to +// recursively construct the tree. Ref-based convenience functions are also +// provided, to make rendering subtrees at a particular JSON path easier. +// +// Path-Based Convenience Functions: +// - InsertAtPath +// - DeleteAtPath +// - RenderAtPath +// +// Additionally, a few "optional" (but nice to have) functions have been +// added, to allow replacing slower/less-efficient equivalents elsewhere. +// +// Optional Functions: +// - Exists (a more efficient boolean alternative to Unfold) +// - Filter (an alternative to Object.Filter that efficiently renders +// paths out of an EditTree) +// +// # Storing scalar children "inline" +// +// The original design for the EditTree allocated a new EditTree node for +// each Term stored in the tree, but this was found to be inefficient when +// dealing with large arrays and objects. The current design of the +// EditTree separates children based on their types, with scalars stored in +// a hash -> Term map, and composites stored in a hash -> EditTree map. +// +// This results in dramatically fewer heap allocations and faster access +// times for "shallow" Term structures, without penalizing nested Term +// structures noticeably. +// +// # Object operations +// +// Objects are the most straightforward composite type, as their key-value +// structure maps naturally onto trees. Their inserts/deletes are recorded +// directly in the appropriate child maps, with almost no additional +// complexity required. +// +// Object EditTree nodes use the child key and value maps, and will not +// initialize the bit-vectors, since those are only used for Arrays. +// +// # Set operations +// +// Set data types have a major problem: they're *content-addressed*. This +// means that we often have to render/materialize the sub-terms before +// carrying out inserts or deletes, in order to know if the path to the +// destination Term exists. This forces a tree collapse at the Set's +// EditTree node, and is brutally inefficient. +// +// Example: +// +// Source set: {[0], "a"} +// {"op": "add", "path": [[0], 1], "value": 1} -> result value: {[0, 1], "a"} +// {"op": "add", "path": [[0, 1], 3], "value": 3} -> result value: {[0, 1, 3], "a"} +// +// We mitigate this somewhat by only collapsing a Set when a composite +// value is being used for indexing. Scalars imply a shallow access, which +// we can look up directly in the appropriate child map. +// +// Set EditTree nodes use the child key and value maps, and will not +// initialize the bit-vectors, since those are only used for Arrays. +// +// # Array operations +// +// Arrays can have elements inserted/replaced/deleted, and this requires +// some bookkeeping work to keep everything straight. We do this +// bookkeeping work using two bit vectors to track all the +// insertions/deletions. +// +// One bit-vector tracks which indexes are preserved/eliminated from the +// original Array, and the second bit-vector tracks which indexes have +// insertions. We can record inserts and deletes *directly* on the second +// bit-vector, "bleeding through" deletions to the preserved/eliminated bit +// vector when there's not an insert to wipe out first. +// +// For bleed-through deletes, a linear scan is required to find the index +// of which original element will be knocked out. We then mark that bit in +// the preserved/eliminated bit-vector. This is a fair bit of bookkeeping, +// but greatly reduces the cost and complexity of tracking Array state. +// There can only be insertions, or original values present. Any other +// "deletion" is an error. +// +// Insert and Delete operations also imply a linear "index rewriting" pass +// for an Array's child maps, where indexes that occur above the affected +// index of the insertion/deletion must be incremented or decremented +// appropriately. This ensures that when rendered later, the +// original/inserted values will be spliced in at the correct offsets in +// the final Array value. +// +// Due to optimizations discussed later, Array EditTree nodes do not use +// the child key map (leaving it uninitialized), but will initialize and +// use the child value maps normally. Array EditTree nodes are the only +// types of EditTree nodes that should ever be expected to have initialized +// bit-vectors present. +// +// # Scalar operations +// +// Scalars are fairly simple: just a term stored in an EditTree node, or in +// the scalar child map of a composite type's EditTree node. They cannot +// have children, and normally do not exist as independent EditTree nodes, +// except to satisfy certain EditTree APIs. +// +// Scalar EditTree nodes can only be expected to have a valid Term value; +// all other fields will be left uninitialized. +// +// # Optimization: Direct Array Indexing with ints +// +// Arrays are unique in Rego, because the only valid Terms that can index +// into them are integer, numeric values. When processing the key Terms for +// Objects and Sets, we have to identify children by their hash values +// (which hash to integers). Because the only valid key Terms for Arrays +// work as ints as well, we can skip the hashing step entirely, and just +// use the int indexes *directly*. +// +// This provides a substantial CPU savings in benchmarks, because the +// "index rewriting" passes become much cheaper from not having to rehash +// every child's index. +package edittree + +import ( + "encoding/json" + "fmt" + "math/big" + "sort" + "strings" + + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/internal/edittree/bitvector" +) + +// Deletions are encoded with a nil value pointer. +type EditTree struct { + value *ast.Term + childKeys map[int]*ast.Term + childScalarValues map[int]*ast.Term + childCompositeValues map[int]*EditTree + eliminated *bitvector.BitVector // Which original indexes have been knocked out? + insertions *bitvector.BitVector // Which indexes have a new value inserted at them? (also used for "live" bookkeeping) +} + +// Creates a new EditTree node from term. +func NewEditTree(term *ast.Term) *EditTree { + if term == nil { + return nil + } + + var tree EditTree + switch x := term.Value.(type) { + case ast.Object, ast.Set: + tree = EditTree{ + value: term, + childKeys: map[int]*ast.Term{}, + childScalarValues: map[int]*ast.Term{}, + childCompositeValues: map[int]*EditTree{}, + } + case *ast.Array: + tree = EditTree{ + value: term, + childScalarValues: map[int]*ast.Term{}, + childCompositeValues: map[int]*EditTree{}, + } + bytesLength := ((x.Len() - 1) / 8) + 1 // How many bytes to use for the bit-vectors. + tree.eliminated = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) + tree.insertions = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) + default: + tree = EditTree{ + value: term, + } + } + + return &tree +} + +// Returns correct (collision-resolved) hash for this term + whether or not +// it was found in the table already. +func (e *EditTree) getKeyHash(key *ast.Term) (int, bool) { + hash := key.Hash() + // This `equal` utility is duplicated and manually inlined a number of + // time in this file. Inlining it avoids heap allocations, so it makes + // a big performance difference: some operations like lookup become twice + // as slow without it. + var equal func(v ast.Value) bool + + switch x := key.Value.(type) { + case ast.Null, ast.Boolean, ast.String, ast.Var: + equal = func(y ast.Value) bool { return x == y } + case ast.Number: + if xi, err := json.Number(x).Int64(); err == nil { + equal = func(y ast.Value) bool { + if y, ok := y.(ast.Number); ok { + if yi, err := json.Number(y).Int64(); err == nil { + return xi == yi + } + } + + return false + } + break + } + + // We use big.Rat for comparing big numbers. + // It replaces big.Float due to following reason: + // big.Float comes with a default precision of 64, and setting a + // larger precision results in more memory being allocated + // (regardless of the actual number we are parsing with SetString). + // + // Note: If we're so close to zero that big.Float says we are zero, do + // *not* big.Rat).SetString on the original string it'll potentially + // take very long. + var a *big.Rat + fa, ok := new(big.Float).SetString(string(x)) + if !ok { + panic("illegal value") + } + if fa.IsInt() { + if i, _ := fa.Int64(); i == 0 { + a = new(big.Rat).SetInt64(0) + } + } + if a == nil { + a, ok = new(big.Rat).SetString(string(x)) + if !ok { + panic("illegal value") + } + } + + equal = func(b ast.Value) bool { + if bNum, ok := b.(ast.Number); ok { + var b *big.Rat + fb, ok := new(big.Float).SetString(string(bNum)) + if !ok { + panic("illegal value") + } + if fb.IsInt() { + if i, _ := fb.Int64(); i == 0 { + b = new(big.Rat).SetInt64(0) + } + } + if b == nil { + b, ok = new(big.Rat).SetString(string(bNum)) + if !ok { + panic("illegal value") + } + } + + return a.Cmp(b) == 0 + } + return false + } + + default: + equal = func(y ast.Value) bool { return ast.Compare(x, y) == 0 } + } + + // Look through childKeys, looking up the original hash + // value first, and then use linear-probing to iter + // through the keys until we either find the Term we're + // after, or run out of candidates. + for curr, ok := e.childKeys[hash]; ok; { + if equal(curr.Value) { + return hash, true + } + + hash++ + curr, ok = e.childKeys[hash] + } + + // Didn't find any matches in childKeys. Hash will be + // the first open slot after the linear probing loop. + return hash, false +} + +//gcassert:inline +func isComposite(t *ast.Term) bool { + switch t.Value.(type) { + case ast.Object, ast.Set, *ast.Array: + return true + default: + return false + } +} + +//gcassert:inline +func (e *EditTree) setChildKey(hash int, key *ast.Term) { + e.childKeys[hash] = key +} + +//gcassert:inline +func (e *EditTree) setChildScalarValue(hash int, value *ast.Term) { + e.childScalarValues[hash] = value +} + +//gcassert:inline +func (e *EditTree) setChildCompositeValue(hash int, child *EditTree) { + e.childCompositeValues[hash] = child +} + +// We don't have a deleteChildKeys method, because once a key is inserted, +// it can only be replaced with either another value, or a delete node from +// then on. +// +//gcassert:inline +func (e *EditTree) deleteChildValue(hash int) { + delete(e.childScalarValues, hash) + delete(e.childCompositeValues, hash) +} + +// Insert creates a new child of e, and returns the new child EditTree node. +func (e *EditTree) Insert(key, value *ast.Term) (*EditTree, error) { + if e.value == nil { + return nil, fmt.Errorf("deleted node encountered during insert operation") + } + if key == nil { + return nil, fmt.Errorf("nil key provided for insert operation") + } + if value == nil { + return nil, fmt.Errorf("nil value provided for insert operation") + } + + switch x := e.value.Value.(type) { + case ast.Object: + return e.unsafeInsertObject(key, value), nil + case ast.Set: + if !key.Equal(value) { + return nil, fmt.Errorf("set key %v does not equal value to be inserted %v", key, value) + } + // We only collapse this Set-typed node if a composite type is involved. + if isComposite(key) { + // TODO: Investigate re-rendering *only* the immediate composite children. + collapsed := e.Render() + e.value = collapsed + e.childKeys = map[int]*ast.Term{} + e.childScalarValues = map[int]*ast.Term{} + e.childCompositeValues = map[int]*EditTree{} + } + return e.unsafeInsertSet(key, value), nil + case *ast.Array: + idx, err := toIndex(e.insertions.Length(), key) + if err != nil { + return nil, err + } + if idx < 0 || idx > e.insertions.Length() { + return nil, fmt.Errorf("index for array insertion out of bounds") + } + return e.unsafeInsertArray(idx, value), nil + default: + // Catch all primitive types. + return nil, fmt.Errorf("expected composite type, found value: %v (type: %T)", x, x) + } +} + +func (e *EditTree) unsafeInsertObject(key, value *ast.Term) *EditTree { + child := NewEditTree(value) + keyHash, found := e.getKeyHash(key) + if found { + e.deleteChildValue(keyHash) + } + e.setChildKey(keyHash, key) + if isComposite(value) { + e.setChildCompositeValue(keyHash, child) + } else { + e.setChildScalarValue(keyHash, value) + } + return child +} + +func (e *EditTree) unsafeInsertSet(key, value *ast.Term) *EditTree { + child := NewEditTree(value) + keyHash, found := e.getKeyHash(key) + if found { + e.deleteChildValue(keyHash) + } + e.setChildKey(keyHash, key) + if isComposite(value) { + e.setChildCompositeValue(keyHash, child) + } else { + e.setChildScalarValue(keyHash, value) + } + return child +} + +func (e *EditTree) unsafeInsertArray(idx int, value *ast.Term) *EditTree { + child := NewEditTree(value) + // Collect insertion indexes above the insertion site for rewriting. + rewritesScalars := []int{} + rewritesComposites := []int{} + for i := idx; i < e.insertions.Length(); i++ { + if e.insertions.Element(i) == 1 { + if _, ok := e.childScalarValues[i]; ok { + rewritesScalars = append(rewritesScalars, i) + continue + } + if _, ok := e.childCompositeValues[i]; ok { + rewritesComposites = append(rewritesComposites, i) + continue + } + panic(fmt.Errorf("invalid index %d during Insert operation", i)) + } + } + // Do rewrites in reverse order to make room for the newly-inserted element. + for i := len(rewritesScalars) - 1; i >= 0; i-- { + originalIdx := rewritesScalars[i] + rewriteIdx := rewritesScalars[i] + 1 + v := e.childScalarValues[originalIdx] + e.deleteChildValue(originalIdx) + e.setChildScalarValue(rewriteIdx, v) + } + for i := len(rewritesComposites) - 1; i >= 0; i-- { + originalIdx := rewritesComposites[i] + rewriteIdx := rewritesComposites[i] + 1 + v := e.childCompositeValues[originalIdx] + e.deleteChildValue(originalIdx) + e.setChildCompositeValue(rewriteIdx, v) + } + // Insert new element in children array, bump bit-vector over by 1. + if idx == e.insertions.Length() { + e.insertions.Append(1) + } else { + e.insertions.Insert(1, idx) + } + if isComposite(value) { + e.setChildCompositeValue(idx, child) + } else { + e.setChildScalarValue(idx, value) + } + return child +} + +// Delete removes a child of e, or else creates a delete node for a term +// already present in e. It then returns the deleted child EditTree node. +func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { + if e.value == nil { + return nil, fmt.Errorf("deleted node encountered during delete operation") + } + if key == nil { + return nil, fmt.Errorf("nil key provided for delete operation") + } + + switch e.value.Value.(type) { + case ast.Object: + keyHash, found := e.getKeyHash(key) + // If child found, replace with delete node. If delete node already existed, error. + if found { + if child, ok := e.childScalarValues[keyHash]; ok { + if child == nil { + return nil, fmt.Errorf("cannot delete the already deleted scalar node for key %v", key) + } + e.setChildKey(keyHash, key) + e.setChildScalarValue(keyHash, nil) + return NewEditTree(child), nil + } + if child, ok := e.childCompositeValues[keyHash]; ok { + if child == nil { + return nil, fmt.Errorf("cannot delete the already deleted composite node for key %v", key) + } + e.setChildKey(keyHash, key) + e.setChildCompositeValue(keyHash, nil) + return child, nil + } + // Note(philipc): We panic here, because the only way to reach + // this panic is to have broken the bookkeeping around the key + // and child maps in a way that is not recoverable. + // For example, if we have an Object EditTree node, and mess up + // the bookkeeping elsewhere by deleting just the value from + // the child maps, *without* also deleting the key from the key + // map, we would reach this place, where the data structure + // *expects* a value to exist, but nothing is present. + panic(fmt.Errorf("hash value %d not found in scalar or composite child maps", keyHash)) + } + // No child, lookup the key in e.value, and put in a delete if present. + // Error if key does not exist in e.value. + return e.fallbackDelete(key) + case ast.Set: + // We only collapse this Set-typed node if a composite type is involved. + if isComposite(key) { + // TODO: Investigate re-rendering *only* the immediate composite children. + collapsed := e.Render() + e.value = collapsed + e.childKeys = map[int]*ast.Term{} + e.childScalarValues = map[int]*ast.Term{} + e.childCompositeValues = map[int]*EditTree{} + } else { + keyHash, found := e.getKeyHash(key) + // If child found, replace with delete node. If delete node already existed, error. + if found { + if child, ok := e.childScalarValues[keyHash]; ok { + if child == nil { + return nil, fmt.Errorf("cannot delete the already deleted scalar node for key %v", key) + } + if key.Equal(child) { + e.setChildKey(keyHash, key) + e.setChildScalarValue(keyHash, nil) + return NewEditTree(child), nil + } + } + } + } + // No child, lookup the key in e.value, and put in a delete if present. + // Error if key does not exist in e.value. + return e.fallbackDelete(key) + case *ast.Array: + idx, err := toIndex(e.insertions.Length(), key) + if err != nil { + return nil, err + } + if idx < 0 || idx > e.insertions.Length()-1 { + return nil, fmt.Errorf("index for array delete out of bounds") + } + + // Collect insertion indexes above the delete site for rewriting. + rewritesScalars := []int{} + rewritesComposites := []int{} + for i := idx + 1; i < e.insertions.Length(); i++ { + if e.insertions.Element(i) == 1 { + if _, ok := e.childScalarValues[i]; ok { + rewritesScalars = append(rewritesScalars, i) + continue + } + if _, ok := e.childCompositeValues[i]; ok { + rewritesComposites = append(rewritesComposites, i) + continue + } + panic(fmt.Errorf("invalid index %d during Insert operation", i)) + } + } + // Do rewrites to clear out the newly-removed element. + e.deleteChildValue(idx) + for i := 0; i < len(rewritesScalars); i++ { + originalIdx := rewritesScalars[i] + rewriteIdx := rewritesScalars[i] - 1 + v := e.childScalarValues[originalIdx] + e.deleteChildValue(originalIdx) + e.setChildScalarValue(rewriteIdx, v) + } + for i := 0; i < len(rewritesComposites); i++ { + originalIdx := rewritesComposites[i] + rewriteIdx := rewritesComposites[i] - 1 + v := e.childCompositeValues[originalIdx] + e.deleteChildValue(originalIdx) + e.setChildCompositeValue(rewriteIdx, v) + } + + // "bleed through" to the underlying array if needed. + // To do this, we sum up the zeroes below the current index, and use that value + // to index through the `eliminated` array until we find a surviving index. + if e.insertions.Element(idx) == 0 { + zeroesSeen := 1 + sumZeroesBelowIndex(idx, e.insertions) + // Mark appropriate position in `eliminated` array, or error. + elimIdx, found := findIndexOfNthZero(zeroesSeen, e.eliminated) + if !found { + panic(fmt.Errorf("could not successfully eliminate index %d from array", idx)) + } + e.eliminated.Set(1, elimIdx) + } + // Delete element from insertions array, bump bit-vec over by 1. + e.insertions.Delete(idx) + return e, nil + default: + // Catch all primitive types. + return nil, fmt.Errorf("expected composite type, found value: %v (type: %T)", e.value.Value, e.value.Value) + } +} + +//gcassert:inline +func sumZeroesBelowIndex(index int, bv *bitvector.BitVector) int { + zeroesSeen := 0 + for i := 0; i < index; i++ { + if bv.Element(i) == 0 { + zeroesSeen++ + } + } + return zeroesSeen +} + +func findIndexOfNthZero(n int, bv *bitvector.BitVector) (int, bool) { + zeroesSeen := 0 + for i := 0; i < bv.Length(); i++ { + if bv.Element(i) == 0 { + zeroesSeen++ + } + if zeroesSeen == n { + return i, true + } + } + return 0, false +} + +// Helper function for sets/objects when the key isn't present in either +// child map. +func (e *EditTree) fallbackDelete(key *ast.Term) (*EditTree, error) { + value, err := e.value.Value.Find(ast.Ref{key}) + if err != nil { + return nil, fmt.Errorf("cannot delete child key %v that does not exist", key) + } + keyHash, _ := e.getKeyHash(key) + e.setChildKey(keyHash, key) + if isComposite(ast.NewTerm(value)) { + e.setChildCompositeValue(keyHash, nil) + } else { + e.setChildScalarValue(keyHash, nil) + } + return NewEditTree(ast.NewTerm(value)), nil +} + +// Unfurls a chain of EditTree nodes down a given path, or else returns an error. +func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { + // 0 path segments base case. (Root hits this.) + if len(path) == 0 { + return e, nil + } + // 1+ path segment case. + if e.value == nil { + return nil, fmt.Errorf("nil value encountered where composite value was expected") + } + + // Switch behavior based on types. + key := path[0] + switch x := e.value.Value.(type) { + case ast.Object: + keyHash, found := e.getKeyHash(key) + if found { + if term, ok := e.childScalarValues[keyHash]; ok { + if term == nil { + return nil, fmt.Errorf("cannot unfold the already deleted scalar node for key %v", key) + } + child := NewEditTree(term) + return child.Unfold(path[1:]) + } + if child, ok := e.childCompositeValues[keyHash]; ok { + if child == nil { + return nil, fmt.Errorf("cannot unfold the already deleted composite node for key %v", key) + } + return child.Unfold(path[1:]) + } + // Note(philipc): We panic here, because the only way to reach + // this panic is to have broken the bookkeeping around the key + // and child maps in a way that is not recoverable. + // For example, if we have an Object EditTree node, and mess up + // the bookkeeping elsewhere by deleting just the value from + // the child maps, *without* also deleting the key from the key + // map, we would reach this place, where the data structure + // *expects* a value to exist, but nothing is present. + panic(fmt.Errorf("hash value %d not found in scalar or composite child maps", keyHash)) + } + // Fall back to looking up the key in e.value. + // Extend the tree if key is present. Error otherwise. + if v, err := x.Find(ast.Ref{path[0]}); err == nil { + child, err := e.Insert(path[0], ast.NewTerm(v)) + if err != nil { + return nil, err + } + return child.Unfold(path[1:]) + } + return nil, fmt.Errorf("path %v does not exist in object term %v", ast.Ref{path[0]}, e.value.Value) + case ast.Set: + // Sets' keys *are* their values, so in order to allow accurate + // traversal, we have to collapse the tree beneath this node, + // so that we can accurately unfold it again for an update, + // once we know that the key we care about is present. + if isComposite(key) { + collapsed := e.Render() + e.value = collapsed + e.childKeys = map[int]*ast.Term{} + e.childScalarValues = map[int]*ast.Term{} + e.childCompositeValues = map[int]*EditTree{} + } else { + keyHash, found := e.getKeyHash(key) + if found { + if term, ok := e.childScalarValues[keyHash]; ok { + child := NewEditTree(term) + return child.Unfold(path[1:]) + } + } + } + // Fall back to looking up the key in e.value. + // Extend the tree if key is present. Error otherwise. + if v, err := e.value.Value.Find(ast.Ref{path[0]}); err == nil { + child, err := e.Insert(path[0], ast.NewTerm(v)) + if err != nil { + return nil, err + } + return child.Unfold(path[1:]) + } + return nil, fmt.Errorf("path %v does not exist in set term %v", ast.Ref{path[0]}, e.value.Value) + case *ast.Array: + idx, err := toIndex(e.insertions.Length(), path[0]) + if err != nil { + return nil, err + } + if term, ok := e.childScalarValues[idx]; ok { + child := NewEditTree(term) + return child.Unfold(path[1:]) + } + if child, ok := e.childCompositeValues[idx]; ok { + return child.Unfold(path[1:]) + } + + // Fall back to looking up the key in e.value. + // Extend the tree if key is present. Error otherwise. + if v, err := x.Find(ast.Ref{ast.IntNumberTerm(idx)}); err == nil { + // TODO: Consider a more efficient "Replace" function that special-cases this for arrays instead? + _, err := e.Delete(ast.IntNumberTerm(idx)) + if err != nil { + return nil, err + } + child, err := e.Insert(ast.IntNumberTerm(idx), ast.NewTerm(v)) + if err != nil { + return nil, err + } + return child.Unfold(path[1:]) + } + return nil, fmt.Errorf("path %v does not exist in array term %v", ast.Ref{ast.IntNumberTerm(idx)}, e.value.Value) + default: + // Catch all primitive types. + return nil, fmt.Errorf("expected composite type for path %v, found value: %v (type: %T)", ast.Ref{path[0]}, x, x) + } +} + +// Render generates the effective value for the term at e by recursively +// rendering the children of e, and then copying over any leftover keys +// from the original term stored at e. +func (e *EditTree) Render() *ast.Term { + if e.value == nil { + return nil + } + + switch x := e.value.Value.(type) { + case ast.Object: + // Early exit if no modifications. + if len(e.childKeys) == 0 { + return e.value + } + // Build a new Object with modified/deleted keys. + // We do this by adding the modified/deleted keys first, then + // skipping those keys later when iterating over the original base + // term in e.value. + skipKeysList := make([]*ast.Term, 0, len(e.childKeys)) + out := make([][2]*ast.Term, 0, len(e.childKeys)+x.Len()) + for hash, term := range e.childScalarValues { + skipKeysList = append(skipKeysList, e.childKeys[hash]) + if term == nil { + continue // Delete case. + } + // Normal value case. + out = append(out, [2]*ast.Term{e.childKeys[hash], term}) + } + for hash, child := range e.childCompositeValues { + skipKeysList = append(skipKeysList, e.childKeys[hash]) + if child == nil { + continue // Delete case. + } + // Normal value case. + subtreeResult := child.Render() + out = append(out, [2]*ast.Term{e.childKeys[hash], subtreeResult}) + } + skipKeys := ast.NewSet(skipKeysList...) + // Copy over all keys that weren't deleted/modified. + x.Foreach(func(k, v *ast.Term) { + if skipKeys.Contains(k) { + return + } + out = append(out, [2]*ast.Term{k, v}) + }) + return ast.ObjectTerm(out...) + case ast.Set: + // Early exit if no modifications. + if len(e.childKeys) == 0 { + return e.value + } + // Build a new Set. + // Sets only can have deletions/new insertions, because the value + // *is* its own key. + skipKeysList := make([]*ast.Term, 0, len(e.childKeys)) + out := make([]*ast.Term, 0, x.Len()+len(e.childKeys)) + for hash, term := range e.childScalarValues { + skipKeysList = append(skipKeysList, e.childKeys[hash]) + if term == nil { + continue // Delete case. + } + // Normal value case. + out = append(out, e.childScalarValues[hash]) + } + // Only happens when this set hasn't been collapsed yet. + for hash, child := range e.childCompositeValues { + skipKeysList = append(skipKeysList, e.childKeys[hash]) + if child == nil { + continue // Delete case. + } + // Normal value case. + subtreeResult := child.Render() + out = append(out, subtreeResult) + } + skipKeys := ast.NewSet(skipKeysList...) + // Copy over all keys that weren't deleted/modified. + x.Foreach(func(key *ast.Term) { + if skipKeys.Contains(key) { + return + } + out = append(out, key) + }) + return ast.SetTerm(out...) + case *ast.Array: + // No early exit here, because we might have just deletes on the + // original array. We build a new Array with modified/deleted keys. + out := make([]*ast.Term, 0, e.insertions.Length()) + eIdx := 0 + for i := 0; i < e.insertions.Length(); i++ { + // If the index == 0, that indicates we should look up the next + // surviving original element. + // If the index == 1, that indicates we should look up that + // index in the child maps. + if e.insertions.Element(i) == 0 { + // Scan through the e.eliminated bit-vec, pick the + // first non-zero index. The then use that index to + // look up the element we should append from e.value. + foundIdx := false + for j := eIdx; j < e.eliminated.Length(); j++ { + if e.eliminated.Element(j) == 0 { + foundIdx = true + eIdx = j + break + } + } + if !foundIdx { + panic(fmt.Errorf("too many eliminated indexes in array, expected to find uneliminated index %d", i)) + } + // Append element from original term. + out = append(out, x.Elem(eIdx)) + eIdx++ // Bump the counter, so that we monotonically advance through the array. + } else { + // Append value from rendered child index. + // Since deletions are not possible as children for an Array, + // we don't need to check for nils here. + if t, ok := e.childScalarValues[i]; ok { + out = append(out, t) + } else if child, ok := e.childCompositeValues[i]; ok { + t := child.Render() + out = append(out, t) + } else { + panic(fmt.Errorf("invalid index %d does not exist in array", i)) + } + } + } + return ast.ArrayTerm(out...) + default: + return e.value + } +} + +// InsertAtPath traverses down the tree from e and uses the last path +// segment as the key to insert value into the tree. +// Returns the inserted EditTree node. +func (e *EditTree) InsertAtPath(path ast.Ref, value *ast.Term) (*EditTree, error) { + if value == nil { + return nil, fmt.Errorf("cannot insert nil value into EditTree") + } + + if len(path) == 0 { + e.value = value + e.childKeys = map[int]*ast.Term{} + e.childScalarValues = map[int]*ast.Term{} + e.childCompositeValues = map[int]*EditTree{} + if v, ok := value.Value.(*ast.Array); ok { + bytesLength := ((v.Len() - 1) / 8) + 1 // How many bytes to use for the bit-vectors. + e.eliminated = bitvector.NewBitVector(make([]byte, bytesLength), v.Len()) + e.insertions = bitvector.NewBitVector(make([]byte, bytesLength), v.Len()) + } + return e, nil + } + + dest, err := e.Unfold(path[:len(path)-1]) + if err != nil { + return nil, err + } + + return dest.Insert(path[len(path)-1], value) +} + +// DeleteAtPath traverses down the tree from e and uses the last path +// segment as the key to delete a node from the tree. +// Returns the deleted EditTree node. +func (e *EditTree) DeleteAtPath(path ast.Ref) (*EditTree, error) { + // Root document case: + if len(path) == 0 { + if e.value == nil { + return nil, fmt.Errorf("deleted node encountered during delete operation") + } + e.value = nil + e.childKeys = nil + e.childScalarValues = nil + e.childCompositeValues = nil + e.eliminated = nil + e.insertions = nil + return e, nil + } + + dest, err := e.Unfold(path[:len(path)-1]) + if err != nil { + return nil, err + } + + return dest.Delete(path[len(path)-1]) +} + +// RenderAtPath traverses down the tree from e and renders the EditTree +// node at the end of path. +func (e *EditTree) RenderAtPath(path ast.Ref) (*ast.Term, error) { + dest, err := e.Unfold(path) + if err != nil { + return nil, err + } + + return dest.Render(), nil +} + +func (e *EditTree) String() string { + if t := e.Render(); t != nil { + return "EditTree[" + t.String() + "]" + } + return "" +} + +func (e *EditTree) Exists(path ast.Ref) bool { + if e.value == nil { + return false + } + + switch { + // 0 path segments base case. (Root hits this.) + case len(path) == 0: + return true + // 1+ path segments case. + case len(path) >= 1: + // Switch behavior based on types. + key := path[0] + switch x := e.value.Value.(type) { + case ast.Object: + keyHash, found := e.getKeyHash(key) + if found { + if term, ok := e.childScalarValues[keyHash]; ok { + if term == nil { + return false + } + return len(path) == 1 + } + if child, ok := e.childCompositeValues[keyHash]; ok { + if child == nil { + return false + } + return child.Exists(path[1:]) + } + // Note(philipc): We panic here, because the only way to reach + // this panic is to have broken the bookkeeping around the key + // and child maps in a way that is not recoverable. + // For example, if we have an Object EditTree node, and mess up + // the bookkeeping elsewhere by deleting just the value from + // the child maps, *without* also deleting the key from the key + // map, we would reach this place, where the data structure + // *expects* a value to exist, but nothing is present. + panic(fmt.Errorf("hash value %d not found in scalar or composite child maps", keyHash)) + } + // Fallback if child lookup failed. + _, err := x.Find(path) + return err == nil + case ast.Set: + // Sets' keys *are* their values, so in order to allow accurate + // traversal, we have to collapse the tree beneath this node, + // so that we can accurately unfold it again for an update, + // once we know that the key we care about is present. + if isComposite(key) { + collapsed := e.Render() + e.value = collapsed + e.childKeys = map[int]*ast.Term{} + e.childScalarValues = map[int]*ast.Term{} + e.childCompositeValues = map[int]*EditTree{} + } else { + keyHash, found := e.getKeyHash(key) + if found { + if _, ok := e.childScalarValues[keyHash]; ok { + return len(path) == 1 + } + } + } + // Fallback if child lookup failed. + _, err := e.value.Value.Find(path) + return err == nil + case *ast.Array: + var idx int + idx, err := toIndex(e.insertions.Length(), path[0]) + if err != nil { + return false + } + if _, ok := e.childScalarValues[idx]; ok { + return len(path) == 1 + } + if child, ok := e.childCompositeValues[idx]; ok { + return child.Exists(path[1:]) + } + // Fallback if child lookup failed. + // We have to ensure that the lookup term is a number here, or Find will fail. + k := ast.Ref{ast.IntNumberTerm(idx)}.Concat(path[1:]) + _, err = x.Find(k) + return err == nil + default: + // Catch all primitive types. + return false + } + } + return false +} + +// -------------------------------------------------------------------- +// Utility functions + +// toIndex tries to convert path elements (that may be strings) into indexes +// into an array. +func toIndex(arrayLength int, term *ast.Term) (int, error) { + i := 0 + var ok bool + switch v := term.Value.(type) { + case ast.Number: + if i, ok = v.Int(); !ok { + return 0, fmt.Errorf("invalid number type for indexing") + } + case ast.String: + if v == "-" { + return arrayLength, nil + } + num := ast.Number(v) + if i, ok = num.Int(); !ok { + return 0, fmt.Errorf("invalid string for indexing") + } + if v != "0" && strings.HasPrefix(string(v), "0") { + return 0, fmt.Errorf("leading zeros are not allowed in JSON paths") + } + default: + return 0, fmt.Errorf("invalid type for indexing") + } + + return i, nil +} + +// -------------------------------------------------------------------- +// Term-level utility functions + +// Filter pulls out only the values selected by paths. +// This is done recursively by plucking off one level from the paths each time we descend a level. +// Note: Values pulled from arrays will have the same approximate +// ordering in the final term. +func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { + if e.value == nil { + return nil + } + + // Separate out keys for this level. + // In the event of paths like "a", "a/b", "a/b/c", the "a" path will win out. + // Nil keys, such as "" or [], are not permitted. (legacy behavior) + pathMap := make(map[ast.Value][]ast.Ref, len(paths)) + renderNowList := []*ast.Term{} + for i := range paths { + path := paths[i] + switch { + case len(path) == 0: + continue // ignore nil paths, such as "" and []. + case len(path) == 1: + renderNowList = append(renderNowList, path[0]) + default: // len(path) > 1 + if _, ok := pathMap[path[0].Value]; !ok { + pathMap[path[0].Value] = []ast.Ref{} + } + pathMap[path[0].Value] = append(pathMap[path[0].Value], path[1:]) + } + } + renderNow := ast.NewSet(renderNowList...) + // Clear everything out of the pathMap that has a renderNow candidate. + for k := range pathMap { + if renderNow.Contains(ast.NewTerm(k)) { + delete(pathMap, k) + } + } + + // Now that we've reached the target, we can start rendering everything beneath us in the tree. + switch e.value.Value.(type) { + case ast.Object: + out := make([][2]*ast.Term, 0, renderNow.Len()+len(pathMap)) + // Render any finished paths. + renderNow.Foreach(func(k *ast.Term) { + if e.Exists(ast.Ref{k}) { + subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + out = append(out, [2]*ast.Term{k, subtreeResult}) + } + }) + // Recursively descend remaining paths. + for k, p := range pathMap { + if e.Exists(ast.Ref{ast.NewTerm(k)}) { + child, _ := e.Unfold(ast.Ref{ast.NewTerm(k)}) + subtreeResult := child.Filter(p) + out = append(out, [2]*ast.Term{ast.NewTerm(k), subtreeResult}) + } + } + return ast.ObjectTerm(out...) + case ast.Set: + out := make([]*ast.Term, 0, renderNow.Len()+len(pathMap)) + // Render any finished paths. + renderNow.Foreach(func(k *ast.Term) { + if e.Exists(ast.Ref{k}) { + subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + out = append(out, subtreeResult) + } + }) + // Recursively descend remaining paths. + for k, p := range pathMap { + if e.Exists(ast.Ref{ast.NewTerm(k)}) { + child, _ := e.Unfold(ast.Ref{ast.NewTerm(k)}) + subtreeResult := child.Filter(p) + out = append(out, subtreeResult) + } + } + return ast.SetTerm(out...) + case *ast.Array: + // No early exit here, because we might have just deletes on the + // original array. We build a new Array with modified/deleted keys. + out := make([]*ast.Term, 0, renderNow.Len()+len(pathMap)) + // Sort array indexes before descending. + idxList := make([]*ast.Term, 0, len(pathMap)) + renderNow.Foreach(func(k *ast.Term) { + idxList = append(idxList, k) + }) + for k := range pathMap { + idxList = append(idxList, ast.NewTerm(k)) + } + sort.Sort(termSlice(idxList)) + // Render child or recursively descend as needed. + for i := range idxList { + k := idxList[i] + if renderNow.Contains(k) { + if e.Exists(ast.Ref{k}) { + subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + out = append(out, subtreeResult) + } + } else if e.Exists(ast.Ref{k}) { + child, _ := e.Unfold(ast.Ref{k}) + subtreeResult := child.Filter(pathMap[k.Value]) + out = append(out, subtreeResult) + } + } + return ast.ArrayTerm(out...) + default: + return e.value + } +} + +type termSlice []*ast.Term + +func (s termSlice) Less(i, j int) bool { return ast.Compare(s[i].Value, s[j].Value) < 0 } +func (s termSlice) Swap(i, j int) { x := s[i]; s[i] = s[j]; s[j] = x } +func (s termSlice) Len() int { return len(s) } diff --git a/vendor/github.com/open-policy-agent/opa/internal/errors/join.go b/vendor/github.com/open-policy-agent/opa/internal/errors/join.go new file mode 100644 index 00000000000..8d8e1f301db --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/errors/join.go @@ -0,0 +1,53 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.20 + +package errors + +// Join returns an error that wraps the given errors. +// Any nil error values are discarded. +// Join returns nil if errs contains no non-nil values. +// The error formats as the concatenation of the strings obtained +// by calling the Error method of each element of errs, with a newline +// between each string. +func Join(errs ...error) error { + n := 0 + for _, err := range errs { + if err != nil { + n++ + } + } + if n == 0 { + return nil + } + e := &joinError{ + errs: make([]error, 0, n), + } + for _, err := range errs { + if err != nil { + e.errs = append(e.errs, err) + } + } + return e +} + +type joinError struct { + errs []error +} + +func (e *joinError) Error() string { + var b []byte + for i, err := range e.errs { + if i > 0 { + b = append(b, '\n') + } + b = append(b, err.Error()...) + } + return string(b) +} + +func (e *joinError) Unwrap() []error { + return e.errs +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/errors/join_go1.20.go b/vendor/github.com/open-policy-agent/opa/internal/errors/join_go1.20.go new file mode 100644 index 00000000000..666f3c783e7 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/errors/join_go1.20.go @@ -0,0 +1,7 @@ +//go:build go1.20 + +package errors + +import "errors" + +var Join = errors.Join diff --git a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/README.md b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/README.md index 53fdef965e8..8308e79dd76 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/README.md +++ b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/README.md @@ -38,7 +38,8 @@ go get github.com/xeipuuv/gojsonschema Dependencies : * [github.com/xeipuuv/gojsonpointer](https://github.com/xeipuuv/gojsonpointer) * [github.com/xeipuuv/gojsonreference](https://github.com/xeipuuv/gojsonreference) -* [github.com/stretchr/testify/assert](https://github.com/stretchr/testify#assert-package) +* [github.com/stretchr/testify/assert](https://github.com/stretchr/testify#assert-package) - (Note, this dependency has + been removed to reduce dependencies in OPA) ## Usage diff --git a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go index 889f0fda456..58d10c1f76e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/validation.go @@ -716,7 +716,7 @@ func (v *SubSchema) validateString(currentSubSchema *SubSchema, value interface{ // minLength & maxLength: if currentSubSchema.minLength != nil { - if utf8.RuneCount([]byte(stringValue)) < *currentSubSchema.minLength { + if utf8.RuneCountInString(stringValue) < *currentSubSchema.minLength { result.addInternalError( new(StringLengthGTEError), context, @@ -726,7 +726,7 @@ func (v *SubSchema) validateString(currentSubSchema *SubSchema, value interface{ } } if currentSubSchema.maxLength != nil { - if utf8.RuneCount([]byte(stringValue)) > *currentSubSchema.maxLength { + if utf8.RuneCountInString(stringValue) > *currentSubSchema.maxLength { result.addInternalError( new(StringLengthLTEError), context, diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go index 36d4dd3eab8..e8fe4cd8541 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go @@ -3,8 +3,6 @@ package jwk import ( "encoding/json" "fmt" - - "github.com/pkg/errors" ) // KeyUsageType is used to denote what this key should be used for @@ -46,7 +44,7 @@ func (keyOperationList *KeyOperationList) Accept(v interface{}) error { *keyOperationList = x return nil default: - return errors.Errorf(`invalid value %T`, v) + return fmt.Errorf(`invalid value %T`, v) } } diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go index cbf7b9f0a12..a4fad4208b0 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go @@ -4,11 +4,11 @@ import ( "crypto/hmac" "crypto/sha256" "crypto/sha512" + "errors" + "fmt" "hash" "github.com/open-policy-agent/opa/internal/jwx/jwa" - - "github.com/pkg/errors" ) var hmacSignFuncs = map[jwa.SignatureAlgorithm]hmacSignFunc{} @@ -29,7 +29,7 @@ func init() { func newHMAC(alg jwa.SignatureAlgorithm) (*HMACSigner, error) { signer, ok := hmacSignFuncs[alg] if !ok { - return nil, errors.Errorf(`unsupported algorithm while trying to create HMAC signer: %s`, alg) + return nil, fmt.Errorf(`unsupported algorithm while trying to create HMAC signer: %s`, alg) } return &HMACSigner{ @@ -55,7 +55,7 @@ func (s HMACSigner) Algorithm() jwa.SignatureAlgorithm { func (s HMACSigner) Sign(payload []byte, key interface{}) ([]byte, error) { hmackey, ok := key.([]byte) if !ok { - return nil, errors.Errorf(`invalid key type %T. []byte is required`, key) + return nil, fmt.Errorf(`invalid key type %T. []byte is required`, key) } if len(hmackey) == 0 { diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go index bc51dbcd033..1e02993eb07 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go @@ -4,10 +4,10 @@ import ( "crypto" "crypto/rand" "crypto/rsa" + "errors" + "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" - - "github.com/pkg/errors" ) var rsaSignFuncs = map[jwa.SignatureAlgorithm]rsaSignFunc{} @@ -69,7 +69,7 @@ func makeSignPSS(hash crypto.Hash) rsaSignFunc { func newRSA(alg jwa.SignatureAlgorithm) (*RSASigner, error) { signfn, ok := rsaSignFuncs[alg] if !ok { - return nil, errors.Errorf(`unsupported algorithm while trying to create RSA signer: %s`, alg) + return nil, fmt.Errorf(`unsupported algorithm while trying to create RSA signer: %s`, alg) } return &RSASigner{ alg: alg, @@ -90,7 +90,7 @@ func (s RSASigner) Sign(payload []byte, key interface{}) ([]byte, error) { } rsakey, ok := key.(*rsa.PrivateKey) if !ok { - return nil, errors.Errorf(`invalid key type %T. *rsa.PrivateKey is required`, key) + return nil, fmt.Errorf(`invalid key type %T. *rsa.PrivateKey is required`, key) } return s.sign(payload, rsakey) diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go index ec88060681f..7db7bbd69cb 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go @@ -5,8 +5,6 @@ import ( "encoding/pem" "fmt" - "github.com/pkg/errors" - "github.com/open-policy-agent/opa/internal/jwx/jwa" ) @@ -20,7 +18,7 @@ func New(alg jwa.SignatureAlgorithm) (Signer, error) { case jwa.HS256, jwa.HS384, jwa.HS512: return newHMAC(alg) default: - return nil, errors.Errorf(`unsupported signature algorithm %s`, alg) + return nil, fmt.Errorf(`unsupported signature algorithm %s`, alg) } } @@ -62,6 +60,6 @@ func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) case jwa.HS256, jwa.HS384, jwa.HS512: return []byte(key), nil default: - return nil, errors.Errorf("unsupported signature algorithm: %s", alg) + return nil, fmt.Errorf("unsupported signature algorithm: %s", alg) } } diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go index e71dc6f8f51..0d4971dc194 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go @@ -3,10 +3,10 @@ package verify import ( "crypto" "crypto/ecdsa" + "errors" + "fmt" "math/big" - "github.com/pkg/errors" - "github.com/open-policy-agent/opa/internal/jwx/jwa" ) @@ -45,7 +45,7 @@ func makeECDSAVerifyFunc(hash crypto.Hash) ecdsaVerifyFunc { func newECDSA(alg jwa.SignatureAlgorithm) (*ECDSAVerifier, error) { verifyfn, ok := ecdsaVerifyFuncs[alg] if !ok { - return nil, errors.Errorf(`unsupported algorithm while trying to create ECDSA verifier: %s`, alg) + return nil, fmt.Errorf(`unsupported algorithm while trying to create ECDSA verifier: %s`, alg) } return &ECDSAVerifier{ @@ -60,7 +60,7 @@ func (v ECDSAVerifier) Verify(payload []byte, signature []byte, key interface{}) } ecdsakey, ok := key.(*ecdsa.PublicKey) if !ok { - return errors.Errorf(`invalid key type %T. *ecdsa.PublicKey is required`, key) + return fmt.Errorf(`invalid key type %T. *ecdsa.PublicKey is required`, key) } return v.verify(payload, signature, ecdsakey) diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go index 1f8d04984c4..d8498f50f28 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go @@ -2,11 +2,11 @@ package verify import ( "crypto/hmac" + "errors" "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" "github.com/open-policy-agent/opa/internal/jwx/jws/sign" - "github.com/pkg/errors" ) func newHMAC(alg jwa.SignatureAlgorithm) (*HMACVerifier, error) { diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go index 8188ceb1fef..edc560dfa62 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go @@ -3,10 +3,10 @@ package verify import ( "crypto" "crypto/rsa" + "errors" + "fmt" "github.com/open-policy-agent/opa/internal/jwx/jwa" - - "github.com/pkg/errors" ) var rsaVerifyFuncs = map[jwa.SignatureAlgorithm]rsaVerifyFunc{} @@ -66,7 +66,7 @@ func makeVerifyPSS(hash crypto.Hash) rsaVerifyFunc { func newRSA(alg jwa.SignatureAlgorithm) (*RSAVerifier, error) { verifyfn, ok := rsaVerifyFuncs[alg] if !ok { - return nil, errors.Errorf(`unsupported algorithm while trying to create RSA verifier: %s`, alg) + return nil, fmt.Errorf(`unsupported algorithm while trying to create RSA verifier: %s`, alg) } return &RSAVerifier{ @@ -81,7 +81,7 @@ func (v RSAVerifier) Verify(payload, signature []byte, key interface{}) error { } rsaKey, ok := key.(*rsa.PublicKey) if !ok { - return errors.Errorf(`invalid key type %T. *rsa.PublicKey is required`, key) + return fmt.Errorf(`invalid key type %T. *rsa.PublicKey is required`, key) } return v.verify(payload, signature, rsaKey) diff --git a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go index 1bb3bf83a91..05720a64e05 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go +++ b/vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go @@ -7,8 +7,6 @@ import ( "encoding/pem" "fmt" - "github.com/pkg/errors" - "github.com/open-policy-agent/opa/internal/jwx/jwa" ) @@ -23,7 +21,7 @@ func New(alg jwa.SignatureAlgorithm) (Verifier, error) { case jwa.HS256, jwa.HS384, jwa.HS512: return newHMAC(alg) default: - return nil, errors.Errorf(`unsupported signature algorithm: %s`, alg) + return nil, fmt.Errorf(`unsupported signature algorithm: %s`, alg) } } @@ -52,6 +50,6 @@ func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) case jwa.HS256, jwa.HS384, jwa.HS512: return []byte(key), nil default: - return nil, errors.Errorf("unsupported signature algorithm: %s", alg) + return nil, fmt.Errorf("unsupported signature algorithm: %s", alg) } } diff --git a/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go b/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go index 93c935b3526..61addb2efd8 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go +++ b/vendor/github.com/open-policy-agent/opa/internal/planner/planner.go @@ -25,6 +25,8 @@ type QuerySet struct { } type planiter func() error +type planLocalIter func(ir.Local) error +type stmtFactory func(ir.Local) ir.Stmt // Planner implements a query planner for Rego queries. type Planner struct { @@ -147,32 +149,31 @@ func (p *Planner) buildFunctrie() error { } for _, rule := range module.Rules { - r := rule.Ref() - switch r[len(r)-1].Value.(type) { - case ast.String: // pass - default: // cut off - r = r[:len(r)-1] - } + r := rule.Ref().StringPrefix() val := p.rules.LookupOrInsert(r) + + val.rules = val.DescendantRules() val.rules = append(val.rules, rule) + val.children = nil } } return nil } func (p *Planner) planRules(rules []*ast.Rule) (string, error) { + // We know the rules with closer to the root (shorter static path) are ordered first. pathRef := rules[0].Ref() // figure out what our rules' collective name/path is: // if we're planning both p.q.r and p.q[s], we'll name // the function p.q (for the mapping table) - // TODO(sr): this has to change when allowing `p[v].q.r[w]` ref rules - // including the mapping lookup structure and lookup functions pieces := len(pathRef) for i := range rules { r := rules[i].Ref() - if _, ok := r[len(r)-1].Value.(ast.String); !ok { - pieces = len(r) - 1 + for j, t := range r { + if _, ok := t.Value.(ast.String); !ok && j > 0 && j < pieces { + pieces = j + } } } // control if p.a = 1 is to return 1 directly; or insert 1 under key "a" into an object @@ -236,7 +237,11 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { fn.Blocks = append(fn.Blocks, p.blockWithStmt(&ir.MakeObjectStmt{Target: fn.Return})) } case ast.MultiValue: - fn.Blocks = append(fn.Blocks, p.blockWithStmt(&ir.MakeSetStmt{Target: fn.Return})) + if buildObject { + fn.Blocks = append(fn.Blocks, p.blockWithStmt(&ir.MakeObjectStmt{Target: fn.Return})) + } else { + fn.Blocks = append(fn.Blocks, p.blockWithStmt(&ir.MakeSetStmt{Target: fn.Return})) + } } // For complete document rules, allocate one local variable for output @@ -252,6 +257,12 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { var defaultRule *ast.Rule var ruleLoc *location.Location + // We sort rules by ref length, to ensure that when merged, we can detect conflicts when one + // rule attempts to override values (deep and shallow) defined by another rule. + sort.Slice(rules, func(i, j int) bool { + return len(rules[i].Ref()) > len(rules[j].Ref()) + }) + // Generate function blocks for rules. for i := range rules { @@ -320,18 +331,19 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { switch rule.Head.RuleKind() { case ast.SingleValue: if buildObject { - ref := rule.Head.Ref() - last := ref[len(ref)-1] - return p.planTerm(last, func() error { - key := p.ltarget - return p.planTerm(rule.Head.Value, func() error { - value := p.ltarget - p.appendStmt(&ir.ObjectInsertOnceStmt{ - Object: fn.Return, - Key: key, - Value: value, + ref := rule.Ref() + return p.planTerm(rule.Head.Value, func() error { + value := p.ltarget + return p.planNestedObjects(fn.Return, ref[pieces:len(ref)-1], func(obj ir.Local) error { + return p.planTerm(ref[len(ref)-1], func() error { + key := p.ltarget + p.appendStmt(&ir.ObjectInsertOnceStmt{ + Object: obj, + Key: key, + Value: value, + }) + return nil }) - return nil }) }) } @@ -343,6 +355,28 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { return nil }) case ast.MultiValue: + if buildObject { + ref := rule.Ref() + // we drop the trailing set key from the ref + return p.planNestedObjects(fn.Return, ref[pieces:len(ref)-1], func(obj ir.Local) error { + // Last term on rule ref is the key an which the set is assigned in the deepest nested object + return p.planTerm(ref[len(ref)-1], func() error { + key := p.ltarget + return p.planTerm(rule.Head.Key, func() error { + value := p.ltarget + factory := func(v ir.Local) ir.Stmt { return &ir.MakeSetStmt{Target: v} } + return p.planDotOr(obj, key, factory, func(set ir.Local) error { + p.appendStmt(&ir.SetAddStmt{ + Set: set, + Value: value, + }) + p.appendStmt(&ir.ObjectInsertStmt{Key: key, Value: op(set), Object: obj}) + return nil + }) + }) + }) + }) + } return p.planTerm(rule.Head.Key, func() error { p.appendStmt(&ir.SetAddStmt{ Set: fn.Return, @@ -422,6 +456,59 @@ func (p *Planner) planRules(rules []*ast.Rule) (string, error) { return fn.Name, nil } +func (p *Planner) planDotOr(obj ir.Local, key ir.Operand, or stmtFactory, iter planLocalIter) error { + // We're constructing the following plan: + // + // | block a + // | | block b + // | | | dot &{Source:Local Key:{Value:Local} Target:Local} + // | | | break 1 + // | | or &{Target:Local} + // | | *ir.ObjectInsertOnceStmt &{Key:{Value:Local} Value:{Value:Local} Object:Local} + + prev := p.curr + dotBlock := &ir.Block{} + p.curr = dotBlock + + val := p.newLocal() + p.appendStmt(&ir.DotStmt{ + Source: op(obj), + Key: key, + Target: val, + }) + p.appendStmt(&ir.BreakStmt{Index: 1}) + + outerBlock := &ir.Block{ + Stmts: []ir.Stmt{ + &ir.BlockStmt{Blocks: []*ir.Block{dotBlock}}, // FIXME: Set Location + or(val), + &ir.ObjectInsertOnceStmt{Key: key, Value: op(val), Object: obj}, + }, + } + + p.curr = prev + p.appendStmt(&ir.BlockStmt{Blocks: []*ir.Block{outerBlock}}) + return iter(val) +} + +func (p *Planner) planNestedObjects(obj ir.Local, ref ast.Ref, iter planLocalIter) error { + if len(ref) == 0 { + //return fmt.Errorf("nested object construction didn't create object") + return iter(obj) + } + + t := ref[0] + + return p.planTerm(t, func() error { + key := p.ltarget + + factory := func(v ir.Local) ir.Stmt { return &ir.MakeObjectStmt{Target: v} } + return p.planDotOr(obj, key, factory, func(childObj ir.Local) error { + return p.planNestedObjects(childObj, ref[1:], iter) + }) + }) +} + func (p *Planner) planFuncParams(params []ir.Local, args ast.Args, idx int, iter planiter) error { if idx >= len(args) { return iter() @@ -1565,16 +1652,14 @@ func (p *Planner) planComprehension(body ast.Body, closureIter planiter, target // below. p.vars.Push(map[ast.Var]ir.Local{}) prev := p.curr - p.curr = &ir.Block{} + block := &ir.Block{} + p.curr = block ploc := p.loc - if err := p.planQuery(body, 0, func() error { - return closureIter() - }); err != nil { + if err := p.planQuery(body, 0, closureIter); err != nil { return err } - block := p.curr p.curr = prev p.loc = ploc p.vars.Pop() @@ -1737,11 +1822,12 @@ func (p *Planner) planRefData(virtual *ruletrie, base *baseptr, ref ast.Ref, ind }}, }} p.curr = outerBlock - return p.planRefRec(ref, index+1, func() error { // rest of the ref - p.curr = prev - p.appendStmt(&ir.BlockStmt{Blocks: []*ir.Block{outerBlock}}) - return iter() - }) + if err := p.planRefRec(ref, index+1, iter); err != nil { // rest of the ref + return err + } + p.curr = prev + p.appendStmt(&ir.BlockStmt{Blocks: []*ir.Block{outerBlock}}) + return nil }) } } @@ -2236,6 +2322,7 @@ func (p *Planner) optimizeLookup(t *ruletrie, ref ast.Ref) ([][]*ast.Rule, []ir. var index int // ref[0] is data, ignore +outer: for i := 1; i < len(ref); i++ { index = i r := ref[i] @@ -2259,7 +2346,7 @@ func (p *Planner) optimizeLookup(t *ruletrie, ref ast.Ref) ([][]*ast.Rule, []ir. } } case ast.String: - // take matching children + // take all children that either match or have a var key for _, node := range nodes { if node := node.Get(r); node != nil { nextNodes = append(nextNodes, node) @@ -2272,15 +2359,44 @@ func (p *Planner) optimizeLookup(t *ruletrie, ref ast.Ref) ([][]*ast.Rule, []ir. nodes = nextNodes - // if all nodes have 0 children, abort ref check and optimize - all := true + // if all nodes have rules() > 0, abort ref check and optimize + // NOTE(sr): for a.b[c] = ... and a.b.d = ..., we stop at a.b, as its rules() + // will collect the children rules + // We keep the "all nodes have 0 children" check since it's cheaper and might + // let us break, too. + all := 0 for _, node := range nodes { - all = all && len(node.Children()) == 0 + all += node.ChildrenCount() } - if all { + if all == 0 { p.debugf("ref %s: all nodes have 0 children, break", ref[0:index+1]) break } + + // NOTE(sr): we only need this check for the penultimate part: + // When planning the ref data.pkg.a[input.x][input.y], + // We want to capture this situation: + // a.b[c] := "x" if c := "c" + // a.b.d := "y" + // + // Not this: + // a.b[c] := "x" if c := "c" + // a.d := "y" + // since the length doesn't add up. Even if input.x was "d", the second + // rule (a.d) wouldn't contribute anything to the result, since we cannot + // "dot it". + if index == len(ref)-2 { + for _, node := range nodes { + anyNonGround := false + for _, r := range node.Rules() { + anyNonGround = anyNonGround || !r.Ref().IsGround() + } + if anyNonGround { + p.debugf("ref %s: at least one node has 1+ non-ground ref rules, break", ref[0:index+1]) + break outer + } + } + } } var res [][]*ast.Rule @@ -2295,7 +2411,7 @@ func (p *Planner) optimizeLookup(t *ruletrie, ref ast.Ref) ([][]*ast.Rule, []ir. for _, node := range nodes { // we're done with ref, check if there's only ruleset leaves; collect rules if index == len(ref)-1 { - if len(node.Rules()) == 0 && len(node.Children()) > 0 { + if len(node.Rules()) == 0 && node.ChildrenCount() > 0 { p.debugf("no optimization of %s: unbalanced ruletrie", ref) return dont() } diff --git a/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go b/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go index 114a25ae2be..f5d6f3fc6c5 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go +++ b/vendor/github.com/open-policy-agent/opa/internal/planner/rules.go @@ -98,6 +98,7 @@ func (t *ruletrie) Rules() []*ast.Rule { // // and we're retrieving a.b, we want Rules() to include the rule body // of a.b.c. + // FIXME: We need to go deeper than just immediate children (?) for _, rs := range t.children { if r := rs[len(rs)-1].rules; r != nil { rules = append(rules, r...) @@ -157,13 +158,50 @@ func (t *ruletrie) Lookup(key ast.Ref) *ruletrie { return node } +func (t *ruletrie) LookupShallowest(key ast.Ref) *ruletrie { + node := t + for _, elem := range key { + node = node.Get(elem.Value) + if node == nil { + return nil + } + if len(node.rules) > 0 { + return node + } + } + return node +} + +// TODO: Collapse rules with overlapping extent to same node(?) func (t *ruletrie) LookupOrInsert(key ast.Ref) *ruletrie { - if val := t.Lookup(key); val != nil { + if val := t.LookupShallowest(key); val != nil { + return val } return t.Insert(key) } +func (t *ruletrie) DescendantRules() []*ast.Rule { + if len(t.children) == 0 { + return t.rules + } + + rules := make([]*ast.Rule, len(t.rules), len(t.rules)+len(t.children)) // could be too little + copy(rules, t.rules) + + for _, cs := range t.children { + for _, c := range cs { + rules = append(rules, c.DescendantRules()...) + } + } + + return rules +} + +func (t *ruletrie) ChildrenCount() int { + return len(t.children) +} + func (t *ruletrie) Children() []ast.Value { if t == nil { return nil diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws.go deleted file mode 100644 index 0d40a66879c..00000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/providers/aws.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2022 The OPA Authors. All rights reserved. -// Use of this source code is governed by an Apache2 -// license that can be found in the LICENSE file. - -package providers - -import ( - "crypto/hmac" - "crypto/sha256" - "fmt" - "net/url" - "sort" - "strings" - "time" - - "github.com/open-policy-agent/opa/ast" -) - -func stringFromTerm(t *ast.Term) string { - if v, ok := t.Value.(ast.String); ok { - return string(v) - } - return "" -} - -// Headers that may be mutated before reaching an aws service (eg by a proxy) should be added here to omit them from -// the sigv4 canonical request -// ref. https://github.com/aws/aws-sdk-go/blob/master/aws/signer/v4/v4.go#L92 -var awsSigv4IgnoredHeaders = map[string]struct{}{ - "authorization": {}, - "user-agent": {}, - "x-amzn-trace-id": {}, -} - -type AWSCredentials struct { - AccessKey string - SecretKey string - RegionName string - SessionToken string -} - -func AWSCredentialsFromObject(v ast.Object) AWSCredentials { - var creds AWSCredentials - awsAccessKey := v.Get(ast.StringTerm("aws_access_key")) - awsSecretKey := v.Get(ast.StringTerm("aws_secret_access_key")) - awsRegion := v.Get(ast.StringTerm("aws_region")) - awsSessionToken := v.Get(ast.StringTerm("aws_session_token")) - - creds.AccessKey = stringFromTerm(awsAccessKey) - creds.SecretKey = stringFromTerm(awsSecretKey) - creds.RegionName = stringFromTerm(awsRegion) - if awsSessionToken != nil { - creds.SessionToken = stringFromTerm(awsSessionToken) - } - return creds -} - -func sha256MAC(message string, key []byte) []byte { - mac := hmac.New(sha256.New, key) - mac.Write([]byte(message)) - return mac.Sum(nil) -} - -func sortKeys(strMap map[string][]string) []string { - keys := make([]string, len(strMap)) - - i := 0 - for k := range strMap { - keys[i] = k - i++ - } - sort.Strings(keys) - - return keys -} - -// AWSSignV4 modifies a map[string][]string of headers to include an AWS V4 signature based on the config/credentials provided. -func AWSSignV4(headers map[string][]string, method string, theURL *url.URL, body []byte, service string, awsCreds AWSCredentials, theTime time.Time) map[string][]string { - // General ref. https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html - // S3 ref. https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html - // APIGateway ref. https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/ - bodyHexHash := fmt.Sprintf("%x", sha256.Sum256(body)) - - now := theTime.UTC() - - // V4 signing has specific ideas of how it wants to see dates/times encoded - dateNow := now.Format("20060102") - iso8601Now := now.Format("20060102T150405Z") - - awsHeaders := map[string]string{ - "host": theURL.Host, - "x-amz-date": iso8601Now, - } - - // s3 and glacier require the extra x-amz-content-sha256 header. other services do not. - if service == "s3" || service == "glacier" { - awsHeaders["x-amz-content-sha256"] = bodyHexHash - } - - // the security token header is necessary for ephemeral credentials, e.g. from - // the EC2 metadata service - if awsCreds.SessionToken != "" { - awsHeaders["x-amz-security-token"] = awsCreds.SessionToken - } - - headersToSign := map[string][]string{} - // sign all of the aws headers that aren't on the ignore list. - for k, v := range headers { - lowercaseHeader := strings.ToLower(k) - if _, ok := awsSigv4IgnoredHeaders[lowercaseHeader]; !ok { - headersToSign[lowercaseHeader] = v - } - } - for k, v := range awsHeaders { - headersToSign[k] = []string{v} - } - - // the "canonical request" is the normalized version of the AWS service access - // that we're attempting to perform; in this case, a GET from an S3 bucket - canonicalReq := method + "\n" // HTTP method - canonicalReq += theURL.EscapedPath() + "\n" // URI-escaped path - canonicalReq += theURL.RawQuery + "\n" // RAW Query String - - // include the values for the signed headers - orderedKeys := sortKeys(headersToSign) - for _, k := range orderedKeys { - canonicalReq += k + ":" + strings.Join(headersToSign[k], ",") + "\n" - } - canonicalReq += "\n" // linefeed to terminate headers - - // include the list of the signed headers - headerList := strings.Join(orderedKeys, ";") - canonicalReq += headerList + "\n" - canonicalReq += bodyHexHash - - // the "string to sign" is a time-bounded, scoped request token which - // is linked to the "canonical request" by inclusion of its SHA-256 hash - strToSign := "AWS4-HMAC-SHA256\n" // V4 signing with SHA-256 HMAC - strToSign += iso8601Now + "\n" // ISO 8601 time - strToSign += dateNow + "/" + awsCreds.RegionName + "/" + service + "/aws4_request\n" // scoping for signature - strToSign += fmt.Sprintf("%x", sha256.Sum256([]byte(canonicalReq))) // SHA-256 of canonical request - - // the "signing key" is generated by repeated HMAC-SHA256 based on the same - // scoping that's included in the "string to sign"; but including the secret key - // to allow AWS to validate it - signingKey := sha256MAC(dateNow, []byte("AWS4"+awsCreds.SecretKey)) - signingKey = sha256MAC(awsCreds.RegionName, signingKey) - signingKey = sha256MAC(service, signingKey) - signingKey = sha256MAC("aws4_request", signingKey) - - // the "signature" is finally the "string to sign" signed by the "signing key" - signature := sha256MAC(strToSign, signingKey) - - // required format of Authorization header; n.b. the access key corresponding to - // the secret key is included here - authHdr := "AWS4-HMAC-SHA256 Credential=" + awsCreds.AccessKey + "/" + dateNow - authHdr += "/" + awsCreds.RegionName + "/" + service + "/aws4_request," - authHdr += "SignedHeaders=" + headerList + "," - authHdr += "Signature=" + fmt.Sprintf("%x", signature) - - // add the computed Authorization - out := make(map[string][]string, len(awsHeaders)+1) - out["Authorization"] = []string{authHdr} - - // populate the other signed headers into the request - for k, v := range awsHeaders { - out[k] = []string{v} - } - - return out -} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/NOTICE.txt b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/NOTICE.txt new file mode 100644 index 00000000000..5f14d1162ed --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/NOTICE.txt @@ -0,0 +1,3 @@ +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go new file mode 100644 index 00000000000..1d0f25f8c20 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/compare.go @@ -0,0 +1,30 @@ +package crypto + +import "fmt" + +// ConstantTimeByteCompare is a constant-time byte comparison of x and y. This function performs an absolute comparison +// if the two byte slices assuming they represent a big-endian number. +// +// error if len(x) != len(y) +// -1 if x < y +// 0 if x == y +// +1 if x > y +func ConstantTimeByteCompare(x, y []byte) (int, error) { + if len(x) != len(y) { + return 0, fmt.Errorf("slice lengths do not match") + } + + xLarger, yLarger := 0, 0 + + for i := 0; i < len(x); i++ { + xByte, yByte := int(x[i]), int(y[i]) + + x := ((yByte - xByte) >> 8) & 1 + y := ((xByte - yByte) >> 8) & 1 + + xLarger |= x &^ yLarger + yLarger |= y &^ xLarger + } + + return xLarger - yLarger, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go new file mode 100644 index 00000000000..758c73fcb3e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go @@ -0,0 +1,113 @@ +package crypto + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/hmac" + "encoding/asn1" + "encoding/binary" + "fmt" + "hash" + "math" + "math/big" +) + +type ecdsaSignature struct { + R, S *big.Int +} + +// ECDSAKey takes the given elliptic curve, and private key (d) byte slice +// and returns the private ECDSA key. +func ECDSAKey(curve elliptic.Curve, d []byte) *ecdsa.PrivateKey { + return ECDSAKeyFromPoint(curve, (&big.Int{}).SetBytes(d)) +} + +// ECDSAKeyFromPoint takes the given elliptic curve and point and returns the +// private and public keypair +func ECDSAKeyFromPoint(curve elliptic.Curve, d *big.Int) *ecdsa.PrivateKey { + pX, pY := curve.ScalarBaseMult(d.Bytes()) + + privKey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: curve, + X: pX, + Y: pY, + }, + D: d, + } + + return privKey +} + +// ECDSAPublicKey takes the provide curve and (x, y) coordinates and returns +// *ecdsa.PublicKey. Returns an error if the given points are not on the curve. +func ECDSAPublicKey(curve elliptic.Curve, x, y []byte) (*ecdsa.PublicKey, error) { + xPoint := (&big.Int{}).SetBytes(x) + yPoint := (&big.Int{}).SetBytes(y) + + if !curve.IsOnCurve(xPoint, yPoint) { + return nil, fmt.Errorf("point(%v, %v) is not on the given curve", xPoint.String(), yPoint.String()) + } + + return &ecdsa.PublicKey{ + Curve: curve, + X: xPoint, + Y: yPoint, + }, nil +} + +// VerifySignature takes the provided public key, hash, and asn1 encoded signature and returns +// whether the given signature is valid. +func VerifySignature(key *ecdsa.PublicKey, hash []byte, signature []byte) (bool, error) { + var ecdsaSignature ecdsaSignature + + _, err := asn1.Unmarshal(signature, &ecdsaSignature) + if err != nil { + return false, err + } + + return ecdsa.Verify(key, hash, ecdsaSignature.R, ecdsaSignature.S), nil +} + +// HMACKeyDerivation provides an implementation of a NIST-800-108 of a KDF (Key Derivation Function) in Counter Mode. +// For the purposes of this implantation HMAC is used as the PRF (Pseudorandom function), where the value of +// `r` is defined as a 4 byte counter. +func HMACKeyDerivation(hash func() hash.Hash, bitLen int, key []byte, label, context []byte) ([]byte, error) { + // verify that we won't overflow the counter + n := int64(math.Ceil((float64(bitLen) / 8) / float64(hash().Size()))) + if n > 0x7FFFFFFF { + return nil, fmt.Errorf("unable to derive key of size %d using 32-bit counter", bitLen) + } + + // verify the requested bit length is not larger then the length encoding size + if int64(bitLen) > 0x7FFFFFFF { + return nil, fmt.Errorf("bitLen is greater than 32-bits") + } + + fixedInput := bytes.NewBuffer(nil) + fixedInput.Write(label) + fixedInput.WriteByte(0x00) + fixedInput.Write(context) + if err := binary.Write(fixedInput, binary.BigEndian, int32(bitLen)); err != nil { + return nil, fmt.Errorf("failed to write bit length to fixed input string: %v", err) + } + + var output []byte + + h := hmac.New(hash, key) + + for i := int64(1); i <= n; i++ { + h.Reset() + if err := binary.Write(h, binary.BigEndian, int32(i)); err != nil { + return nil, err + } + _, err := h.Write(fixedInput.Bytes()) + if err != nil { + return nil, err + } + output = append(output, h.Sum(nil)...) + } + + return output[:bitLen/8], nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go new file mode 100644 index 00000000000..179b5b5d5e7 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/ecr.go @@ -0,0 +1,148 @@ +package aws + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "net/http" + "strings" + "time" + + "github.com/open-policy-agent/opa/internal/version" + "github.com/open-policy-agent/opa/logging" +) + +// Values taken from +// https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html +const ( + ecrGetAuthorizationTokenTarget = "AmazonEC2ContainerRegistry_V20150921.GetAuthorizationToken" + ecrEndpointFmt = "https://ecr.%s.amazonaws.com/" +) + +// ECR is used to request tokens from Elastic Container Registry. +type ECR struct { + // endpoint returns the region-specifc ECR endpoint. + // It can be overridden by tests. + endpoint func(region string) string + + // client is used to send authorization tokens requests. + client *http.Client + + logger logging.Logger +} + +func NewECR(logger logging.Logger) *ECR { + return &ECR{ + endpoint: func(region string) string { + return fmt.Sprintf(ecrEndpointFmt, region) + }, + client: &http.Client{}, + logger: logger, + } +} + +// GetAuthorizationToken requests a token that can be used to authenticate image pull requests. +func (e *ECR) GetAuthorizationToken(ctx context.Context, creds Credentials, signatureVersion string) (ECRAuthorizationToken, error) { + endpoint := e.endpoint(creds.RegionName) + body := strings.NewReader("{}") + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body) + if err != nil { + return ECRAuthorizationToken{}, fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("X-Amz-Target", ecrGetAuthorizationTokenTarget) + req.Header.Set("Accept-Encoding", "identity") + req.Header.Set("Content-Type", "application/x-amz-json-1.1") + req.Header.Set("User-Agent", version.UserAgent) + + e.logger.Debug("Signing ECR authorization token request") + + if err := SignRequest(req, "ecr", creds, time.Now(), signatureVersion); err != nil { + return ECRAuthorizationToken{}, fmt.Errorf("failed to sign request: %w", err) + } + + resp, err := DoRequestWithClient(req, e.client, "ecr get authorization token", e.logger) + if err != nil { + return ECRAuthorizationToken{}, err + } + + var data struct { + AuthorizationData []struct { + AuthorizationToken string `json:"authorizationToken"` + ExpiresAt json.Number `json:"expiresAt"` + } `json:"authorizationData"` + } + if err := json.Unmarshal(resp, &data); err != nil { + return ECRAuthorizationToken{}, fmt.Errorf("failed to unmarshal response: %w", err) + } + + if len(data.AuthorizationData) < 1 { + return ECRAuthorizationToken{}, errors.New("empty authorization data") + } + + // The GetAuthorizationToken request returns a list of tokens for + // backwards compatibility reasons. We should only ever get one token back + // because we don't define any registryIDs in the request. + // See https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html#API_GetAuthorizationToken_ResponseSyntax + resultToken := data.AuthorizationData[0] + + expiresAt, err := parseTimestamp(resultToken.ExpiresAt) + if err != nil { + return ECRAuthorizationToken{}, fmt.Errorf("failed to parse expiresAt: %w", err) + } + + return ECRAuthorizationToken{ + AuthorizationToken: resultToken.AuthorizationToken, + ExpiresAt: expiresAt, + }, nil +} + +// ECRAuthorizationToken can sign requests to AWS ECR. +// +// It corresponds to data returned by the AWS GetAuthorizationToken API. +// See https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_AuthorizationData.html +type ECRAuthorizationToken struct { + AuthorizationToken string + ExpiresAt time.Time +} + +// IsValid returns true if the token is set and not expired. +// It respects a margin of error for time handling and will mark it as expired early. +func (t *ECRAuthorizationToken) IsValid() bool { + const tokenExpirationMargin = 5 * time.Minute + + expired := time.Now().Add(tokenExpirationMargin).After(t.ExpiresAt) + return t.AuthorizationToken != "" && !expired +} + +var millisecondsFloat = new(big.Float).SetInt64(1e3) + +// parseTimestamp parses the AWS format for timestamps. +// The time precision is in milliseconds. +// +// The logic is taken from +// https://github.com/aws/aws-sdk-go/blob/41717ba2c04d3fd03f94d09ea984a10899574935/private/protocol/json/jsonutil/unmarshal.go#L294-L302 +func parseTimestamp(raw json.Number) (time.Time, error) { + s := raw.String() + + float, ok := new(big.Float).SetString(s) + if !ok { + return time.Time{}, fmt.Errorf("not a float: %q", raw) + } + + // The float is expected to be in second resolution with millisecond + // decimal places. + // Multiply by millisecondsFloat to obtain an integer in millisecond + // resolution + ms, _ := float.Mul(float, millisecondsFloat).Int64() + + // Multiply again to obtain nanosecond resolution for time.Unix + ns := ms * 1e6 + + t := time.Unix(0, ns).UTC() + + return t, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go new file mode 100644 index 00000000000..77c0bc93491 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/kms.go @@ -0,0 +1,106 @@ +package aws + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/open-policy-agent/opa/internal/version" + "github.com/open-policy-agent/opa/logging" +) + +// Values taken from +// https://docs.aws.amazon.com/kms/latest/APIReference/Welcome.html +// https://docs.aws.amazon.com/general/latest/gr/kms.html +const ( + kmsSignTarget = "TrentService.Sign" + kmsEndpointFmt = "https://kms.%s.amazonaws.com/" +) + +// KMS is used to sign payloads using AWS Key Management Service. +type KMS struct { + // endpoint returns the region-specifc KMS endpoint. + // It can be overridden by tests. + endpoint func(region string) string + + // client is used to send authorization tokens requests. + client *http.Client + + logger logging.Logger +} + +func NewKMS(logger logging.Logger) *KMS { + return &KMS{ + endpoint: func(region string) string { + return fmt.Sprintf(kmsEndpointFmt, region) + }, + client: &http.Client{}, + logger: logger, + } +} + +func NewKMSWithURLClient(url string, client *http.Client, logger logging.Logger) *KMS { + return &KMS{ + endpoint: func(string) string { return url }, + client: client, + logger: logger, + } +} + +type KMSSignRequest struct { + KeyID string `json:"KeyId"` + Message string `json:"Message"` + MessageType string `json:"MessageType"` + SigningAlgorithm string `json:"SigningAlgorithm"` +} +type KMSSignResponse struct { + KeyID string `json:"KeyId"` + Signature string `json:"Signature"` + SigningAlgorithm string `json:"SigningAlgorithm"` +} + +// SignDigest signs a digest using KMS. +func (k *KMS) SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string, creds Credentials, signatureVersion string) (string, error) { + endpoint := k.endpoint(creds.RegionName) + + kmsRequest := KMSSignRequest{ + KeyID: keyID, + Message: base64.StdEncoding.EncodeToString(digest), + MessageType: "DIGEST", + SigningAlgorithm: signingAlgorithm, + } + requestJSONBytes, err := json.Marshal(kmsRequest) + if err != nil { + return "", fmt.Errorf("failed to marshall request: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewBuffer(requestJSONBytes)) + if err != nil { + return "", fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("X-Amz-Target", kmsSignTarget) + req.Header.Set("Accept-Encoding", "identity") + req.Header.Set("Content-Type", "application/x-amz-json-1.1") + req.Header.Set("User-Agent", version.UserAgent) + + if err := SignRequest(req, "kms", creds, time.Now(), signatureVersion); err != nil { + return "", fmt.Errorf("failed to sign request: %w", err) + } + + resp, err := DoRequestWithClient(req, k.client, "kms sign digest", k.logger) + if err != nil { + return "", err + } + + var data KMSSignResponse + if err := json.Unmarshal(resp, &data); err != nil { + return "", fmt.Errorf("failed to unmarshal response: %w", err) + } + + return data.Signature, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go new file mode 100644 index 00000000000..79662b10ff1 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4.go @@ -0,0 +1,204 @@ +// Copyright 2022 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package aws + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strings" + "time" + + "github.com/open-policy-agent/opa/ast" +) + +func stringFromTerm(t *ast.Term) string { + if v, ok := t.Value.(ast.String); ok { + return string(v) + } + return "" +} + +// Headers that may be mutated before reaching an aws service (eg by a proxy) should be added here to omit them from +// the sigv4 canonical request +// ref. https://github.com/aws/aws-sdk-go/blob/master/aws/signer/v4/v4.go#L92 +var awsSigv4IgnoredHeaders = map[string]struct{}{ + "authorization": {}, + "user-agent": {}, + "x-amzn-trace-id": {}, +} + +type Credentials struct { + AccessKey string + SecretKey string + RegionName string + SessionToken string +} + +func CredentialsFromObject(v ast.Object) Credentials { + var creds Credentials + awsAccessKey := v.Get(ast.StringTerm("aws_access_key")) + awsSecretKey := v.Get(ast.StringTerm("aws_secret_access_key")) + awsRegion := v.Get(ast.StringTerm("aws_region")) + awsSessionToken := v.Get(ast.StringTerm("aws_session_token")) + + creds.AccessKey = stringFromTerm(awsAccessKey) + creds.SecretKey = stringFromTerm(awsSecretKey) + creds.RegionName = stringFromTerm(awsRegion) + if awsSessionToken != nil { + creds.SessionToken = stringFromTerm(awsSessionToken) + } + return creds +} + +func sha256MAC(message string, key []byte) []byte { + mac := hmac.New(sha256.New, key) + mac.Write([]byte(message)) + return mac.Sum(nil) +} + +func sortKeys(strMap map[string][]string) []string { + keys := make([]string, len(strMap)) + + i := 0 + for k := range strMap { + keys[i] = k + i++ + } + sort.Strings(keys) + + return keys +} + +// SignRequest modifies an http.Request to include an AWS V4 signature based on the provided credentials. +func SignRequest(req *http.Request, service string, creds Credentials, theTime time.Time, sigVersion string) error { + // General ref. https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html + // S3 ref. https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html + // APIGateway ref. https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/ + + var body []byte + if req.Body == nil { + body = []byte("") + } else { + var err error + body, err = io.ReadAll(req.Body) + if err != nil { + return errors.New("error getting request body: " + err.Error()) + } + // Since ReadAll consumed the body ReadCloser, we must create a new ReadCloser for the request so that the + // subsequent read starts from the beginning + req.Body = io.NopCloser(bytes.NewReader(body)) + } + + now := theTime.UTC() + + if sigVersion == "4a" { + signedHeaders := SignV4a(req.Header, req.Method, req.URL, body, service, creds, now) + req.Header = signedHeaders + } else { + authHeader, awsHeaders := SignV4(req.Header, req.Method, req.URL, body, service, creds, now) + req.Header.Set("Authorization", authHeader) + for k, v := range awsHeaders { + req.Header.Add(k, v) + } + } + + return nil +} + +// SignV4 modifies a map[string][]string of headers to generate an AWS V4 signature + headers based on the config/credentials provided. +func SignV4(headers map[string][]string, method string, theURL *url.URL, body []byte, service string, awsCreds Credentials, theTime time.Time) (string, map[string]string) { + // General ref. https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html + // S3 ref. https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html + // APIGateway ref. https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/ + bodyHexHash := fmt.Sprintf("%x", sha256.Sum256(body)) + + now := theTime.UTC() + + // V4 signing has specific ideas of how it wants to see dates/times encoded + dateNow := now.Format("20060102") + iso8601Now := now.Format("20060102T150405Z") + + awsHeaders := map[string]string{ + "host": theURL.Host, + "x-amz-date": iso8601Now, + } + + // s3 and glacier require the extra x-amz-content-sha256 header. other services do not. + if service == "s3" || service == "glacier" { + awsHeaders["x-amz-content-sha256"] = bodyHexHash + } + + // the security token header is necessary for ephemeral credentials, e.g. from + // the EC2 metadata service + if awsCreds.SessionToken != "" { + awsHeaders["x-amz-security-token"] = awsCreds.SessionToken + } + + headersToSign := map[string][]string{} + // sign all of the aws headers. + for k, v := range awsHeaders { + headersToSign[k] = []string{v} + } + + // sign all of the request's headers, except for those in the ignore list + for k, v := range headers { + lowercaseHeader := strings.ToLower(k) + if _, ok := awsSigv4IgnoredHeaders[lowercaseHeader]; !ok { + headersToSign[lowercaseHeader] = v + } + } + + // the "canonical request" is the normalized version of the AWS service access + // that we're attempting to perform + canonicalReq := method + "\n" // HTTP method + canonicalReq += theURL.EscapedPath() + "\n" // URI-escaped path + canonicalReq += theURL.RawQuery + "\n" // RAW Query String + + // include the values for the signed headers + orderedKeys := sortKeys(headersToSign) + for _, k := range orderedKeys { + canonicalReq += k + ":" + strings.Join(headersToSign[k], ",") + "\n" + } + canonicalReq += "\n" // linefeed to terminate headers + + // include the list of the signed headers + headerList := strings.Join(orderedKeys, ";") + canonicalReq += headerList + "\n" + canonicalReq += bodyHexHash + + // the "string to sign" is a time-bounded, scoped request token which + // is linked to the "canonical request" by inclusion of its SHA-256 hash + strToSign := "AWS4-HMAC-SHA256\n" // V4 signing with SHA-256 HMAC + strToSign += iso8601Now + "\n" // ISO 8601 time + strToSign += dateNow + "/" + awsCreds.RegionName + "/" + service + "/aws4_request\n" // scoping for signature + strToSign += fmt.Sprintf("%x", sha256.Sum256([]byte(canonicalReq))) // SHA-256 of canonical request + + // the "signing key" is generated by repeated HMAC-SHA256 based on the same + // scoping that's included in the "string to sign"; but including the secret key + // to allow AWS to validate it + signingKey := sha256MAC(dateNow, []byte("AWS4"+awsCreds.SecretKey)) + signingKey = sha256MAC(awsCreds.RegionName, signingKey) + signingKey = sha256MAC(service, signingKey) + signingKey = sha256MAC("aws4_request", signingKey) + + // the "signature" is finally the "string to sign" signed by the "signing key" + signature := sha256MAC(strToSign, signingKey) + + // required format of Authorization header; n.b. the access key corresponding to + // the secret key is included here + authHeader := "AWS4-HMAC-SHA256 Credential=" + awsCreds.AccessKey + "/" + dateNow + authHeader += "/" + awsCreds.RegionName + "/" + service + "/aws4_request," + authHeader += "SignedHeaders=" + headerList + "," + authHeader += "Signature=" + fmt.Sprintf("%x", signature) + + return authHeader, awsHeaders +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go new file mode 100644 index 00000000000..f1235a68b67 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go @@ -0,0 +1,410 @@ +// modified from github.com/aws/aws-sdk-go-v2/internal/v4a@7a32d707af +package aws + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "fmt" + "hash" + "io" + "math/big" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + signerCrypto "github.com/open-policy-agent/opa/internal/providers/aws/crypto" + v4Internal "github.com/open-policy-agent/opa/internal/providers/aws/v4" +) + +const ( + // AmzRegionSetKey represents the region set header used for sigv4a + AmzRegionSetKey = "X-Amz-Region-Set" + amzSecurityTokenKey = v4Internal.AmzSecurityTokenKey + amzDateKey = v4Internal.AmzDateKey + authorizationHeader = "Authorization" + + signingAlgorithm = "AWS4-ECDSA-P256-SHA256" + + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" +) + +var ( + p256 elliptic.Curve + nMinusTwoP256 *big.Int + + one = new(big.Int).SetInt64(1) + + cache = credsCache{} + + randomSource = rand.Reader +) + +func init() { + // Ensure the elliptic curve parameters are initialized on package import rather then on first usage + p256 = elliptic.P256() + + nMinusTwoP256 = new(big.Int).SetBytes(p256.Params().N.Bytes()) + nMinusTwoP256 = nMinusTwoP256.Sub(nMinusTwoP256, new(big.Int).SetInt64(2)) +} + +type credsCache struct { + asymmetric atomic.Value + m sync.Mutex +} + +// SetRandomSource used for testing to override rand so tests can expect stable output +func SetRandomSource(reader io.Reader) { + randomSource = reader +} + +// deriveKeyFromAccessKeyPair derives a NIST P-256 PrivateKey from the given +// IAM AccessKey and SecretKey pair. +// +// Based on FIPS.186-4 Appendix B.4.2 +func deriveKeyFromAccessKeyPair(accessKey, secretKey string) (*ecdsa.PrivateKey, error) { + params := p256.Params() + bitLen := params.BitSize // Testing random candidates does not require an additional 64 bits + counter := 0x01 + + buffer := make([]byte, 1+len(accessKey)) // 1 byte counter + len(accessKey) + kdfContext := bytes.NewBuffer(buffer) + + inputKey := append([]byte("AWS4A"), []byte(secretKey)...) + + d := new(big.Int) + for { + kdfContext.Reset() + kdfContext.WriteString(accessKey) + kdfContext.WriteByte(byte(counter)) + + key, err := signerCrypto.HMACKeyDerivation(sha256.New, bitLen, inputKey, []byte(signingAlgorithm), kdfContext.Bytes()) + if err != nil { + return nil, err + } + + // Check key first before calling SetBytes if key is in fact a valid candidate. + // This ensures the byte slice is the correct length (32-bytes) to compare in constant-time + cmp, err := signerCrypto.ConstantTimeByteCompare(key, nMinusTwoP256.Bytes()) + if err != nil { + return nil, err + } + if cmp == -1 { + d.SetBytes(key) + break + } + + counter++ + if counter > 0xFF { + return nil, fmt.Errorf("exhausted single byte external counter") + } + } + d = d.Add(d, one) + + priv := new(ecdsa.PrivateKey) + priv.PublicKey.Curve = p256 + priv.D = d + priv.PublicKey.X, priv.PublicKey.Y = p256.ScalarBaseMult(d.Bytes()) + + return priv, nil +} + +// v4aCredentials is Context, ECDSA, and Optional Session Token that can be used +// to sign requests using SigV4a +type v4aCredentials struct { + Context string + PrivateKey *ecdsa.PrivateKey + SessionToken string +} + +// retrievePrivateKey returns credentials suitable for SigV4a signing +func retrievePrivateKey(symmetric Credentials) (v4aCredentials, error) { + cache.m.Lock() + defer cache.m.Unlock() + + // try to get creds from cache + v := cache.asymmetric.Load() + if v != nil { + c := v.(*v4aCredentials) + // if the cached Context matches the symmetric AccessKey ID, then use cached value. Otherwise, creds have + // changed and we need to derive new asymmetric creds + if c != nil && c.Context == symmetric.AccessKey { + return *c, nil + } + } + + privateKey, err := deriveKeyFromAccessKeyPair(symmetric.AccessKey, symmetric.SecretKey) + if err != nil { + return v4aCredentials{}, fmt.Errorf("failed to derive asymmetric key from credentials") + } + + creds := v4aCredentials{ + Context: symmetric.AccessKey, + PrivateKey: privateKey, + SessionToken: symmetric.SessionToken, + } + + // cache derived asymmetric creds so we don't derive new ones until symmetric creds change + cache.asymmetric.Store(&creds) + + return creds, nil +} + +type httpSigner struct { + Request *http.Request + ServiceName string + RegionSet []string + Time time.Time + Credentials v4aCredentials + + // PayloadHash is the hex encoded SHA-256 hash of the request payload + // If len(PayloadHash) == 0 the signer will attempt to send the request + // as an unsigned payload. Note: Unsigned payloads only work for a subset of services. + PayloadHash string +} + +func (s *httpSigner) setRequiredSigningFields(headers http.Header, query url.Values) { + amzDate := s.Time.Format(timeFormat) + + headers.Set(AmzRegionSetKey, strings.Join(s.RegionSet, ",")) + headers.Set(amzDateKey, amzDate) + if len(s.Credentials.SessionToken) > 0 { + headers.Set(amzSecurityTokenKey, s.Credentials.SessionToken) + } +} + +// Build modifies the Request attribute of the httpSigner, adding an Authorization header +func (s *httpSigner) Build() (signedRequest, error) { + req := s.Request + + query := req.URL.Query() + headers := req.Header + + // seemingly required by S3/MRAP -- 403 Forbidden otherwise + headers.Set("host", req.URL.Host) + headers.Set("x-amz-content-sha256", s.PayloadHash) + + s.setRequiredSigningFields(headers, query) + + // Sort Each Query Key's Values + for key := range query { + sort.Strings(query[key]) + } + + v4Internal.SanitizeHostForHeader(req) + + credentialScope := s.buildCredentialScope() + credentialStr := s.Credentials.Context + "/" + credentialScope + + unsignedHeaders := headers + + host := req.URL.Host + if len(req.Host) > 0 { + host = req.Host + } + + signedHeaders, signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(host, v4Internal.IgnoredHeaders, unsignedHeaders, s.Request.ContentLength) + + rawQuery := strings.Replace(query.Encode(), "+", "%20", -1) + + canonicalURI := v4Internal.GetURIPath(req.URL) + + canonicalString := s.buildCanonicalString( + req.Method, + canonicalURI, + rawQuery, + signedHeadersStr, + canonicalHeaderStr, + ) + + strToSign := s.buildStringToSign(credentialScope, canonicalString) + signingSignature, err := s.buildSignature(strToSign) + if err != nil { + return signedRequest{}, err + } + + headers[authorizationHeader] = append(headers[authorizationHeader][:0], buildAuthorizationHeader(credentialStr, signedHeadersStr, signingSignature)) + + req.URL.RawQuery = rawQuery + + return signedRequest{ + Request: req, + SignedHeaders: signedHeaders, + CanonicalString: canonicalString, + StringToSign: strToSign, + }, nil +} + +func (s *httpSigner) buildCredentialScope() string { + return strings.Join([]string{ + s.Time.Format(shortTimeFormat), + s.ServiceName, + "aws4_request", + }, "/") + +} + +func buildAuthorizationHeader(credentialStr, signedHeadersStr, signingSignature string) string { + const credential = "Credential=" + const signedHeaders = "SignedHeaders=" + const signature = "Signature=" + const commaSpace = ", " + + var parts strings.Builder + parts.Grow(len(signingAlgorithm) + 1 + + len(credential) + len(credentialStr) + len(commaSpace) + + len(signedHeaders) + len(signedHeadersStr) + len(commaSpace) + + len(signature) + len(signingSignature), + ) + parts.WriteString(signingAlgorithm) + parts.WriteRune(' ') + parts.WriteString(credential) + parts.WriteString(credentialStr) + parts.WriteString(commaSpace) + parts.WriteString(signedHeaders) + parts.WriteString(signedHeadersStr) + parts.WriteString(commaSpace) + parts.WriteString(signature) + parts.WriteString(signingSignature) + return parts.String() +} + +func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, header http.Header, length int64) (signed http.Header, signedHeaders, canonicalHeadersStr string) { + signed = make(http.Header) + + const hostHeader = "host" + headers := make([]string, 0) + + if length > 0 { + const contentLengthHeader = "content-length" + headers = append(headers, contentLengthHeader) + signed[contentLengthHeader] = append(signed[contentLengthHeader], strconv.FormatInt(length, 10)) + } + + for k, v := range header { + if !rule.IsValid(k) { + continue // ignored header + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := signed[lowerCaseKey]; ok { + // include additional values + signed[lowerCaseKey] = append(signed[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + signed[lowerCaseKey] = v + } + sort.Strings(headers) + + signedHeaders = strings.Join(headers, ";") + + var canonicalHeaders strings.Builder + n := len(headers) + const colon = ':' + for i := 0; i < n; i++ { + if headers[i] == hostHeader { + canonicalHeaders.WriteString(hostHeader) + canonicalHeaders.WriteRune(colon) + canonicalHeaders.WriteString(v4Internal.StripExcessSpaces(host)) + } else { + canonicalHeaders.WriteString(headers[i]) + canonicalHeaders.WriteRune(colon) + // Trim out leading, trailing, and dedup inner spaces from signed header values. + values := signed[headers[i]] + for j, v := range values { + cleanedValue := strings.TrimSpace(v4Internal.StripExcessSpaces(v)) + canonicalHeaders.WriteString(cleanedValue) + if j < len(values)-1 { + canonicalHeaders.WriteRune(',') + } + } + } + canonicalHeaders.WriteRune('\n') + } + canonicalHeadersStr = canonicalHeaders.String() + + return signed, signedHeaders, canonicalHeadersStr +} + +func (s *httpSigner) buildCanonicalString(method, uri, query, signedHeaders, canonicalHeaders string) string { + return strings.Join([]string{ + method, + uri, + query, + canonicalHeaders, + signedHeaders, + s.PayloadHash, + }, "\n") +} + +func (s *httpSigner) buildStringToSign(credentialScope, canonicalRequestString string) string { + return strings.Join([]string{ + signingAlgorithm, + s.Time.Format(timeFormat), + credentialScope, + hex.EncodeToString(makeHash(sha256.New(), []byte(canonicalRequestString))), + }, "\n") +} + +func makeHash(hash hash.Hash, b []byte) []byte { + hash.Reset() + hash.Write(b) + return hash.Sum(nil) +} + +func (s *httpSigner) buildSignature(strToSign string) (string, error) { + sig, err := s.Credentials.PrivateKey.Sign(randomSource, makeHash(sha256.New(), []byte(strToSign)), crypto.SHA256) + if err != nil { + return "", err + } + return hex.EncodeToString(sig), nil +} + +type signedRequest struct { + Request *http.Request + SignedHeaders http.Header + CanonicalString string + StringToSign string +} + +// SignV4a returns a map[string][]string of headers, including an added AWS V4a signature based on the config/credentials provided. +func SignV4a(headers map[string][]string, method string, theURL *url.URL, body []byte, service string, awsCreds Credentials, theTime time.Time) map[string][]string { + bodyHexHash := fmt.Sprintf("%x", sha256.Sum256(body)) + + key, err := retrievePrivateKey(awsCreds) + if err != nil { + return map[string][]string{} + } + + bodyReader := bytes.NewReader(body) + req, _ := http.NewRequest(method, theURL.String(), bodyReader) + req.Header = headers + + signer := &httpSigner{ + Request: req, + PayloadHash: bodyHexHash, + ServiceName: service, + RegionSet: []string{"*"}, + Credentials: key, + Time: theTime, + } + + _, err = signer.Build() + if err != nil { + return map[string][]string{} + } + + return req.Header +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go new file mode 100644 index 00000000000..e1e8a949f50 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/util.go @@ -0,0 +1,45 @@ +package aws + +import ( + "errors" + "io" + "net/http" + + "github.com/open-policy-agent/opa/logging" +) + +// DoRequestWithClient is a convenience function to get the body of an http response with +// appropriate error-handling boilerplate and logging. +func DoRequestWithClient(req *http.Request, client *http.Client, desc string, logger logging.Logger) ([]byte, error) { + resp, err := client.Do(req) + if err != nil { + // some kind of catastrophe talking to the service + return nil, errors.New(desc + " HTTP request failed: " + err.Error()) + } + defer resp.Body.Close() + + logger.WithFields(map[string]interface{}{ + "url": req.URL.String(), + "status": resp.Status, + "headers": resp.Header, + }).Debug("Received response from " + desc + " service.") + + if resp.StatusCode != 200 { + if logger.GetLevel() == logging.Debug { + body, err := io.ReadAll(resp.Body) + if err == nil { + logger.Debug("Error response with response body: %s", body) + } + } + // could be 404 for role that's not available, but cover all the bases + return nil, errors.New(desc + " HTTP request returned unexpected status: " + resp.Status) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + // deal with problems reading the body, whatever those might be + return nil, errors.New(desc + " HTTP response body could not be read: " + err.Error()) + } + + return body, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/const.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/const.go new file mode 100644 index 00000000000..89a76e2eaab --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/const.go @@ -0,0 +1,36 @@ +package v4 + +const ( + // EmptyStringSHA256 is the hex encoded sha256 value of an empty string + EmptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` + + // UnsignedPayload indicates that the request payload body is unsigned + UnsignedPayload = "UNSIGNED-PAYLOAD" + + // AmzAlgorithmKey indicates the signing algorithm + AmzAlgorithmKey = "X-Amz-Algorithm" + + // AmzSecurityTokenKey indicates the security token to be used with temporary credentials + AmzSecurityTokenKey = "X-Amz-Security-Token" + + // AmzDateKey is the UTC timestamp for the request in the format YYYYMMDD'T'HHMMSS'Z' + AmzDateKey = "X-Amz-Date" + + // AmzCredentialKey is the access key ID and credential scope + AmzCredentialKey = "X-Amz-Credential" + + // AmzSignedHeadersKey is the set of headers signed for the request + AmzSignedHeadersKey = "X-Amz-SignedHeaders" + + // AmzSignatureKey is the query parameter to store the SigV4 signature + AmzSignatureKey = "X-Amz-Signature" + + // TimeFormat is the time format to be used in the X-Amz-Date header or query parameter + TimeFormat = "20060102T150405Z" + + // ShortTimeFormat is the shorten time format used in the credential scope + ShortTimeFormat = "20060102" + + // ContentSHAKey is the SHA256 of request body + ContentSHAKey = "X-Amz-Content-Sha256" +) diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/header_rules.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/header_rules.go new file mode 100644 index 00000000000..baf6d12cc65 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/header_rules.go @@ -0,0 +1,87 @@ +package v4 + +import ( + "strings" +) + +// Rules houses a set of Rule needed for validation of a +// string value +type Rules []Rule + +// Rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that Rule +type Rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r Rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// MapRule generic Rule for maps +type MapRule map[string]struct{} + +// IsValid for the map Rule satisfies whether it exists in the map +func (m MapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// AllowList is a generic Rule for whitelisting +type AllowList struct { + Rule +} + +// IsValid for AllowList checks if the value is within the AllowList +func (w AllowList) IsValid(value string) bool { + return w.Rule.IsValid(value) +} + +// DenyList is a generic Rule for blacklisting +type DenyList struct { + Rule +} + +// IsValid for AllowList checks if the value is within the AllowList +func (b DenyList) IsValid(value string) bool { + return !b.Rule.IsValid(value) +} + +// Patterns is a list of strings to match against +type Patterns []string + +// FORK: copied from aws-sdk-go-v2/internal/strings +func hasPrefixFold(s, prefix string) bool { + return len(s) >= len(prefix) && strings.EqualFold(s[0:len(prefix)], prefix) +} + +// IsValid for Patterns checks each pattern and returns if a match has +// been found +func (p Patterns) IsValid(value string) bool { + for _, pattern := range p { + if hasPrefixFold(value, pattern) { + return true + } + } + return false +} + +// InclusiveRules rules allow for rules to depend on one another +type InclusiveRules []Rule + +// IsValid will return true if all rules are true +func (r InclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/headers.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/headers.go new file mode 100644 index 00000000000..3487dc3352d --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/headers.go @@ -0,0 +1,67 @@ +package v4 + +// IgnoredHeaders is a list of headers that are ignored during signing +var IgnoredHeaders = Rules{ + DenyList{ + MapRule{ + "Authorization": struct{}{}, + "User-Agent": struct{}{}, + "X-Amzn-Trace-Id": struct{}{}, + }, + }, +} + +// RequiredSignedHeaders is a whitelist for Build canonical headers. +var RequiredSignedHeaders = Rules{ + AllowList{ + MapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + "X-Amz-Content-Sha256": struct{}{}, + "X-Amz-Tagging": struct{}{}, + }, + }, + Patterns{"X-Amz-Meta-"}, +} + +// AllowedQueryHoisting is a whitelist for Build query headers. The boolean value +// represents whether or not it is a pattern. +var AllowedQueryHoisting = InclusiveRules{ + DenyList{RequiredSignedHeaders}, + Patterns{"X-Amz-"}, +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/host.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/host.go new file mode 100644 index 00000000000..bf93659a43f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/host.go @@ -0,0 +1,75 @@ +package v4 + +import ( + "net/http" + "strings" +) + +// SanitizeHostForHeader removes default port from host and updates request.Host +func SanitizeHostForHeader(r *http.Request) { + host := getHost(r) + port := portOnly(host) + if port != "" && isDefaultPort(r.URL.Scheme, port) { + r.Host = stripPort(host) + } +} + +// Returns host from request +func getHost(r *http.Request) string { + if r.Host != "" { + return r.Host + } + + return r.URL.Host +} + +// Hostname returns u.Host, without any port number. +// +// If Host is an IPv6 literal with a port number, Hostname returns the +// IPv6 literal without the square brackets. IPv6 literals may include +// a zone identifier. +// +// Copied from the Go 1.8 standard library (net/url) +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} + +// Port returns the port part of u.Host, without the leading colon. +// If u.Host doesn't contain a port, Port returns an empty string. +// +// Copied from the Go 1.8 standard library (net/url) +func portOnly(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return "" + } + if i := strings.Index(hostport, "]:"); i != -1 { + return hostport[i+len("]:"):] + } + if strings.Contains(hostport, "]") { + return "" + } + return hostport[colon+len(":"):] +} + +// Returns true if the specified URI is using the standard port +// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) +func isDefaultPort(scheme, port string) bool { + if port == "" { + return true + } + + lowerCaseScheme := strings.ToLower(scheme) + if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { + return true + } + + return false +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/util.go b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/util.go new file mode 100644 index 00000000000..0cb9cffaf51 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/providers/aws/v4/util.go @@ -0,0 +1,64 @@ +package v4 + +import ( + "net/url" + "strings" +) + +const doubleSpace = " " + +// StripExcessSpaces will rewrite the passed in slice's string values to not +// contain multiple side-by-side spaces. +func StripExcessSpaces(str string) string { + var j, k, l, m, spaces int + // Trim trailing spaces + for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { + } + + // Trim leading spaces + for k = 0; k < j && str[k] == ' '; k++ { + } + str = str[k : j+1] + + // Strip multiple spaces. + j = strings.Index(str, doubleSpace) + if j < 0 { + return str + } + + buf := []byte(str) + for k, m, l = j, j, len(buf); k < l; k++ { + if buf[k] == ' ' { + if spaces == 0 { + // First space. + buf[m] = buf[k] + m++ + } + spaces++ + } else { + // End of multiple spaces. + spaces = 0 + buf[m] = buf[k] + m++ + } + } + + return string(buf[:m]) +} + +// GetURIPath returns the escaped URI component from the provided URL +func GetURIPath(u *url.URL) string { + var uri string + + if len(u.Opaque) > 0 { + uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") + } else { + uri = u.EscapedPath() + } + + if len(uri) == 0 { + uri = "/" + } + + return uri +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go b/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go new file mode 100644 index 00000000000..bd72e1bd0c8 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go @@ -0,0 +1,236 @@ +// Copyright 2020 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package init is an internal package with helpers for data and policy loading during initialization. +package init + +import ( + "context" + "fmt" + "io/fs" + "path/filepath" + "strings" + + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/bundle" + storedversion "github.com/open-policy-agent/opa/internal/version" + "github.com/open-policy-agent/opa/loader" + "github.com/open-policy-agent/opa/metrics" + "github.com/open-policy-agent/opa/storage" +) + +// InsertAndCompileOptions contains the input for the operation. +type InsertAndCompileOptions struct { + Store storage.Store + Txn storage.Transaction + Files loader.Result + Bundles map[string]*bundle.Bundle + MaxErrors int + EnablePrintStatements bool +} + +// InsertAndCompileResult contains the output of the operation. +type InsertAndCompileResult struct { + Compiler *ast.Compiler + Metrics metrics.Metrics +} + +// InsertAndCompile writes data and policy into the store and returns a compiler for the +// store contents. +func InsertAndCompile(ctx context.Context, opts InsertAndCompileOptions) (*InsertAndCompileResult, error) { + if len(opts.Files.Documents) > 0 { + if err := opts.Store.Write(ctx, opts.Txn, storage.AddOp, storage.Path{}, opts.Files.Documents); err != nil { + return nil, fmt.Errorf("storage error: %w", err) + } + } + + policies := make(map[string]*ast.Module, len(opts.Files.Modules)) + + for id, parsed := range opts.Files.Modules { + policies[id] = parsed.Parsed + } + + compiler := ast.NewCompiler(). + SetErrorLimit(opts.MaxErrors). + WithPathConflictsCheck(storage.NonEmpty(ctx, opts.Store, opts.Txn)). + WithEnablePrintStatements(opts.EnablePrintStatements) + m := metrics.New() + + activation := &bundle.ActivateOpts{ + Ctx: ctx, + Store: opts.Store, + Txn: opts.Txn, + Compiler: compiler, + Metrics: m, + Bundles: opts.Bundles, + ExtraModules: policies, + } + + err := bundle.Activate(activation) + if err != nil { + return nil, err + } + + // Policies in bundles will have already been added to the store, but + // modules loaded outside of bundles will need to be added manually. + for id, parsed := range opts.Files.Modules { + if err := opts.Store.UpsertPolicy(ctx, opts.Txn, id, parsed.Raw); err != nil { + return nil, fmt.Errorf("storage error: %w", err) + } + } + + // Set the version in the store last to prevent data files from overwriting. + if err := storedversion.Write(ctx, opts.Store, opts.Txn); err != nil { + return nil, fmt.Errorf("storage error: %w", err) + } + + return &InsertAndCompileResult{Compiler: compiler, Metrics: m}, nil +} + +// LoadPathsResult contains the output loading a set of paths. +type LoadPathsResult struct { + Bundles map[string]*bundle.Bundle + Files loader.Result +} + +// WalkPathsResult contains the output loading a set of paths. +type WalkPathsResult struct { + BundlesLoader []BundleLoader + FileDescriptors []*Descriptor +} + +// BundleLoader contains information about files in a bundle +type BundleLoader struct { + DirectoryLoader bundle.DirectoryLoader + IsDir bool +} + +// Descriptor contains information about a file +type Descriptor struct { + Root string + Path string +} + +// LoadPaths reads data and policy from the given paths and returns a set of bundles or +// raw loader file results. +func LoadPaths(paths []string, + filter loader.Filter, + asBundle bool, + bvc *bundle.VerificationConfig, + skipVerify bool, + processAnnotations bool, + caps *ast.Capabilities, + fsys fs.FS) (*LoadPathsResult, error) { + + if caps == nil { + caps = ast.CapabilitiesForThisVersion() + } + + // tar.gz files are automatically loaded as bundles + var likelyBundles, nonBundlePaths []string + if !asBundle { + likelyBundles, nonBundlePaths = splitByTarGzExt(paths) + paths = likelyBundles + } + + var result LoadPathsResult + var err error + if asBundle || len(likelyBundles) > 0 { + result.Bundles = make(map[string]*bundle.Bundle, len(paths)) + for _, path := range paths { + result.Bundles[path], err = loader.NewFileLoader(). + WithFS(fsys). + WithBundleVerificationConfig(bvc). + WithSkipBundleVerification(skipVerify). + WithFilter(filter). + WithProcessAnnotation(processAnnotations). + WithCapabilities(caps). + AsBundle(path) + if err != nil { + return nil, err + } + } + } + + if len(nonBundlePaths) == 0 { + return &result, nil + } + + files, err := loader.NewFileLoader(). + WithFS(fsys). + WithProcessAnnotation(processAnnotations). + WithCapabilities(caps). + Filtered(nonBundlePaths, filter) + + if err != nil { + return nil, err + } + + result.Files = *files + + return &result, nil +} + +// splitByTarGzExt splits the paths in 2 groups. Ones with .tar.gz and another with +// non .tar.gz extensions. +func splitByTarGzExt(paths []string) (targzs []string, nonTargzs []string) { + for _, path := range paths { + if strings.HasSuffix(path, ".tar.gz") { + targzs = append(targzs, path) + } else { + nonTargzs = append(nonTargzs, path) + } + } + return +} + +// WalkPaths reads data and policy from the given paths and returns a set of bundle directory loaders +// or descriptors that contain information about files. +func WalkPaths(paths []string, filter loader.Filter, asBundle bool) (*WalkPathsResult, error) { + + var result WalkPathsResult + + if asBundle { + result.BundlesLoader = make([]BundleLoader, len(paths)) + for i, path := range paths { + bundleLoader, isDir, err := loader.GetBundleDirectoryLoader(path) + if err != nil { + return nil, err + } + + result.BundlesLoader[i] = BundleLoader{ + DirectoryLoader: bundleLoader, + IsDir: isDir, + } + } + return &result, nil + } + + result.FileDescriptors = []*Descriptor{} + for _, path := range paths { + filePaths, err := loader.FilteredPaths([]string{path}, filter) + if err != nil { + return nil, err + } + + for _, fp := range filePaths { + // Trim off the root directory and return path as if chrooted + cleanedPath := strings.TrimPrefix(fp, path) + if path == "." && filepath.Base(fp) == bundle.ManifestExt { + cleanedPath = fp + } + + if !strings.HasPrefix(cleanedPath, "/") { + cleanedPath = "/" + cleanedPath + } + + result.FileDescriptors = append(result.FileDescriptors, &Descriptor{ + Root: path, + Path: cleanedPath, + }) + } + } + + return &result, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go b/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go new file mode 100644 index 00000000000..019dc87bb9b --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go @@ -0,0 +1,33 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package strvals provides tools for working with strval lines. + +OPA runtime config supports a compressed format for YAML settings which we call strvals. +The format is roughly like this: + + name=value,topname.subname=value + +The above is equivalent to the YAML document + + name: value + topname: + subname: value + +This package provides a parser and utilities for converting the strvals format +to other formats. +*/ +package strvals diff --git a/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go b/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go new file mode 100644 index 00000000000..1fc07f68c36 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go @@ -0,0 +1,431 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package strvals + +import ( + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + + "sigs.k8s.io/yaml" +) + +// ErrNotList indicates that a non-list was treated as a list. +var ErrNotList = errors.New("not a list") + +// MaxIndex is the maximum index that will be allowed by setIndex. +// The default value 65536 = 1024 * 64 +var MaxIndex = 65536 + +// ToYAML takes a string of arguments and converts to a YAML document. +func ToYAML(s string) (string, error) { + m, err := Parse(s) + if err != nil { + return "", err + } + d, err := yaml.Marshal(m) + return string(d), err +} + +// Parse parses a set line. +// +// A set line is of the form name1=value1,name2=value2 +func Parse(s string) (map[string]interface{}, error) { + vals := map[string]interface{}{} + scanner := bytes.NewBufferString(s) + t := newParser(scanner, vals, false) + err := t.parse() + return vals, err +} + +// ParseString parses a set line and forces a string value. +// +// A set line is of the form name1=value1,name2=value2 +func ParseString(s string) (map[string]interface{}, error) { + vals := map[string]interface{}{} + scanner := bytes.NewBufferString(s) + t := newParser(scanner, vals, true) + err := t.parse() + return vals, err +} + +// ParseInto parses a strvals line and merges the result into dest. +// +// If the strval string has a key that exists in dest, it overwrites the +// dest version. +func ParseInto(s string, dest map[string]interface{}) error { + scanner := bytes.NewBufferString(s) + t := newParser(scanner, dest, false) + return t.parse() +} + +// ParseIntoFile parses a filevals line and merges the result into dest. +// +// This method always returns a string as the value. +func ParseIntoFile(s string, dest map[string]interface{}, runesToVal runesToVal) error { + scanner := bytes.NewBufferString(s) + t := newFileParser(scanner, dest, runesToVal) + return t.parse() +} + +// ParseIntoString parses a strvals line and merges the result into dest. +// +// This method always returns a string as the value. +func ParseIntoString(s string, dest map[string]interface{}) error { + scanner := bytes.NewBufferString(s) + t := newParser(scanner, dest, true) + return t.parse() +} + +// parser is a simple parser that takes a strvals line and parses it into a +// map representation. +// +// where sc is the source of the original data being parsed +// where data is the final parsed data from the parses with correct types +// where st is a boolean to figure out if we're forcing it to parse values as string +type parser struct { + sc *bytes.Buffer + data map[string]interface{} + runesToVal runesToVal +} + +type runesToVal func([]rune) (interface{}, error) + +func newParser(sc *bytes.Buffer, data map[string]interface{}, stringBool bool) *parser { + rs2v := func(rs []rune) (interface{}, error) { + return typedVal(rs, stringBool), nil + } + return &parser{sc: sc, data: data, runesToVal: rs2v} +} + +func newFileParser(sc *bytes.Buffer, data map[string]interface{}, runesToVal runesToVal) *parser { + return &parser{sc: sc, data: data, runesToVal: runesToVal} +} + +func (t *parser) parse() error { + for { + err := t.key(t.data) + if err == nil { + continue + } + if err == io.EOF { + return nil + } + return err + } +} + +func runeSet(r []rune) map[rune]bool { + s := make(map[rune]bool, len(r)) + for _, rr := range r { + s[rr] = true + } + return s +} + +func (t *parser) key(data map[string]interface{}) error { + stop := runeSet([]rune{'=', '[', ',', '.'}) + for { + switch k, last, err := runesUntil(t.sc, stop); { + case err != nil: + if len(k) == 0 { + return err + } + return fmt.Errorf("key %q has no value", string(k)) + //set(data, string(k), "") + //return err + case last == '[': + // We are in a list index context, so we need to set an index. + i, err := t.keyIndex() + if err != nil { + return fmt.Errorf("error parsing index: %s", err) + } + kk := string(k) + // Find or create target list + list := []interface{}{} + if _, ok := data[kk]; ok { + list = data[kk].([]interface{}) + } + + // Now we need to get the value after the ]. + list, err = t.listItem(list, i) + set(data, kk, list) + return err + case last == '=': + //End of key. Consume =, Get value. + // FIXME: Get value list first + vl, e := t.valList() + switch e { + case nil: + set(data, string(k), vl) + return nil + case io.EOF: + set(data, string(k), "") + return e + case ErrNotList: + rs, e := t.val() + if e != nil && e != io.EOF { + return e + } + v, e := t.runesToVal(rs) + set(data, string(k), v) + return e + default: + return e + } + + case last == ',': + // No value given. Set the value to empty string. Return error. + set(data, string(k), "") + return fmt.Errorf("key %q has no value (cannot end with ,)", string(k)) + case last == '.': + // First, create or find the target map. + inner := map[string]interface{}{} + if _, ok := data[string(k)]; ok { + inner = data[string(k)].(map[string]interface{}) + } + + // Recurse + e := t.key(inner) + if len(inner) == 0 { + return fmt.Errorf("key map %q has no value", string(k)) + } + set(data, string(k), inner) + return e + } + } +} + +func set(data map[string]interface{}, key string, val interface{}) { + // If key is empty, don't set it. + if len(key) == 0 { + return + } + data[key] = val +} + +func setIndex(list []interface{}, index int, val interface{}) (l2 []interface{}, err error) { + // There are possible index values that are out of range on a target system + // causing a panic. This will catch the panic and return an error instead. + // The value of the index that causes a panic varies from system to system. + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("error processing index %d: %s", index, r) + } + }() + + if index < 0 { + return list, fmt.Errorf("negative %d index not allowed", index) + } + if index > MaxIndex { + return list, fmt.Errorf("index of %d is greater than maximum supported index of %d", index, MaxIndex) + } + if len(list) <= index { + newlist := make([]interface{}, index+1) + copy(newlist, list) + list = newlist + } + list[index] = val + return list, nil +} + +func (t *parser) keyIndex() (int, error) { + // First, get the key. + stop := runeSet([]rune{']'}) + v, _, err := runesUntil(t.sc, stop) + if err != nil { + return 0, err + } + // v should be the index + return strconv.Atoi(string(v)) + +} +func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { + if i < 0 { + return list, fmt.Errorf("negative %d index not allowed", i) + } + stop := runeSet([]rune{'[', '.', '='}) + switch k, last, err := runesUntil(t.sc, stop); { + case len(k) > 0: + return list, fmt.Errorf("unexpected data at end of array index: %q", k) + case err != nil: + return list, err + case last == '=': + vl, e := t.valList() + switch e { + case nil: + return setIndex(list, i, vl) + case io.EOF: + return setIndex(list, i, "") + case ErrNotList: + rs, e := t.val() + if e != nil && e != io.EOF { + return list, e + } + v, e := t.runesToVal(rs) + if e != nil { + return nil, e + } + return setIndex(list, i, v) + default: + return list, e + } + case last == '[': + // now we have a nested list. Read the index and handle. + i, err := t.keyIndex() + if err != nil { + return list, fmt.Errorf("error parsing index: %s", err) + } + // Now we need to get the value after the ]. + list2, err := t.listItem(list, i) + if err != nil { + return nil, err + } + return setIndex(list, i, list2) + case last == '.': + // We have a nested object. Send to t.key + inner := map[string]interface{}{} + if len(list) > i { + var ok bool + inner, ok = list[i].(map[string]interface{}) + if !ok { + // We have indices out of order. Initialize empty value. + list[i] = map[string]interface{}{} + inner = list[i].(map[string]interface{}) + } + } + + // Recurse + e := t.key(inner) + if e != nil { + return list, e + } + return setIndex(list, i, inner) + default: + return nil, fmt.Errorf("parse error: unexpected token %v", last) + } +} + +func (t *parser) val() ([]rune, error) { + stop := runeSet([]rune{','}) + v, _, err := runesUntil(t.sc, stop) + return v, err +} + +func (t *parser) valList() ([]interface{}, error) { + r, _, e := t.sc.ReadRune() + if e != nil { + return []interface{}{}, e + } + + if r != '{' { + e = t.sc.UnreadRune() + if e != nil { + return []interface{}{}, e + } + return []interface{}{}, ErrNotList + } + + list := []interface{}{} + stop := runeSet([]rune{',', '}'}) + for { + switch rs, last, err := runesUntil(t.sc, stop); { + case err != nil: + if err == io.EOF { + err = errors.New("list must terminate with '}'") + } + return list, err + case last == '}': + // If this is followed by ',', consume it. + if r, _, e := t.sc.ReadRune(); e == nil && r != ',' { + e = t.sc.UnreadRune() + if e != nil { + return []interface{}{}, e + } + } + v, e := t.runesToVal(rs) + list = append(list, v) + return list, e + case last == ',': + v, e := t.runesToVal(rs) + if e != nil { + return list, e + } + list = append(list, v) + } + } +} + +func runesUntil(in io.RuneReader, stop map[rune]bool) ([]rune, rune, error) { + var v []rune + for { + switch r, _, e := in.ReadRune(); { + case e != nil: + return v, r, e + case inMap(r, stop): + return v, r, nil + case r == '\\': + next, _, e := in.ReadRune() + if e != nil { + return v, next, e + } + v = append(v, next) + default: + v = append(v, r) + } + } +} + +func inMap(k rune, m map[rune]bool) bool { + _, ok := m[k] + return ok +} + +func typedVal(v []rune, st bool) interface{} { + val := string(v) + + if st { + return val + } + + if strings.EqualFold(val, "true") { + return true + } + + if strings.EqualFold(val, "false") { + return false + } + + if strings.EqualFold(val, "null") { + return struct{}{} + } + + if strings.EqualFold(val, "0") { + return int64(0) + } + + // If this value does not start with zero, try parsing it to an int + if len(val) != 0 && val[0] != '0' { + if iv, err := strconv.ParseInt(val, 10, 64); err == nil { + return iv + } + } + + return val +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go b/vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go index e79e73375cc..5d925e68df2 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go +++ b/vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go @@ -7,6 +7,13 @@ package uuid import ( "fmt" "io" + "strings" + + "github.com/google/uuid" +) + +const ( + BILLION = 1000000000 ) // New Create a version 4 random UUID @@ -20,3 +27,89 @@ func New(r io.Reader) (string, error) { bs[6] = bs[6]&^0xf0 | 0x40 return fmt.Sprintf("%x-%x-%x-%x-%x", bs[0:4], bs[4:6], bs[6:8], bs[8:10], bs[10:]), nil } + +// Parse will use the google/uuid library to parse the string into a uuid +// if parsing fails, it will return an empty map. It will fill the map +// with some decoded values with fillMap +// ref: https://datatracker.ietf.org/doc/html/rfc4122 +func Parse(s string) (map[string]interface{}, error) { + uuid, err := uuid.Parse(s) + if err != nil { + return nil, err + } + out := make(map[string]interface{}, getVersionLen(int(uuid.Version()))) + fillMap(out, uuid) + return out, nil +} + +// Fills the map with values from the uuid. Version and variant for every version. +// Version 1-2 has decodable values that could be of use, version 4 is random, +// and version 3,5 is not feasible to extract data. Generated with either MD5 or SHA1 hash +// ref: https://datatracker.ietf.org/doc/html/rfc4122 about creation of UUIDs +func fillMap(m map[string]interface{}, u uuid.UUID) { + m["version"] = int(u.Version()) + m["variant"] = u.Variant().String() + switch version := m["version"]; version { + case 1, 2: + m["time"] = nanoUnix(u.Time()) + m["nodeid"] = byteDecimalToHexMAC(u.NodeID(), "-") + m["macvariables"] = macVars(u.NodeID()[0]) + m["clocksequence"] = u.ClockSequence() + if version == 2 { + m["id"] = int(u.ID()) + m["domain"] = u.Domain().String() + } + } +} + +// macVars will take the first byte of a MAC-address and check for the +// local/global bit and check for the unicast/multicast bit of the byte, +// and return a string with this info. +// ref: https://datatracker.ietf.org/doc/html/rfc7042#section-2.1 +func macVars(inpb byte) string { + switch { + case inpb&byte(0b11) == byte(0b11): + return "local:multicast" + case inpb&byte(0b01) == byte(0b01): + return "global:multicast" + case inpb&byte(0b10) == byte(0b10): + return "local:unicast" + } + return "global:unicast" +} + +// loops through the byte array to convert all bytes to hexes. +// It will also put the separator between every other to make it human-readable +func byteDecimalToHexMAC(bytes []byte, sep string) string { + hexs := strings.Builder{} + l := len(bytes) + hexs.Grow((l * 3) - 1) // 1 byte -> 2 hexes + 1 separator (if one char) + + for i, b := range bytes { + hexs.WriteString(fmt.Sprintf("%02x", b)) + if i < l-1 { + hexs.WriteString(sep) + } + } + + return hexs.String() +} + +// nanoUnix Converts the uuids encoded time into unix represented time in nanoseconds +func nanoUnix(t uuid.Time) int64 { + unixsec, unixnsec := t.UnixTime() + return unixsec*BILLION + unixnsec +} + +// Helper function to make map with length based on version of uuid +// Most are 2 in length (version, variant), but version 1 and 2 have more. +func getVersionLen(version int) int { + switch version { + case 1: + return 5 + case 2: + return 7 + default: + return 2 + } +} diff --git a/vendor/github.com/open-policy-agent/opa/loader/extension/extension.go b/vendor/github.com/open-policy-agent/opa/loader/extension/extension.go new file mode 100644 index 00000000000..905c4863428 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/loader/extension/extension.go @@ -0,0 +1,40 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package extension + +import ( + "sync" +) + +var pluginMtx sync.Mutex +var bundleExtensions map[string]Handler + +// Handler is used to unmarshal a byte slice of a registered extension +// EXPERIMENTAL: Please don't rely on this functionality, it may go +// away or change in the future. +type Handler func([]byte, any) error + +// RegisterExtension registers a Handler for a certain file extension, including +// the dot: ".json", not "json". +// EXPERIMENTAL: Please don't rely on this functionality, it may go +// away or change in the future. +func RegisterExtension(name string, handler Handler) { + pluginMtx.Lock() + defer pluginMtx.Unlock() + + if bundleExtensions == nil { + bundleExtensions = map[string]Handler{} + } + bundleExtensions[name] = handler +} + +// FindExtension ios used to look up a registered extension Handler +// EXPERIMENTAL: Please don't rely on this functionality, it may go +// away or change in the future. +func FindExtension(ext string) Handler { + pluginMtx.Lock() + defer pluginMtx.Unlock() + return bundleExtensions[ext] +} diff --git a/vendor/github.com/open-policy-agent/opa/loader/loader.go b/vendor/github.com/open-policy-agent/opa/loader/loader.go index 1c2a04d06ba..4583f21b446 100644 --- a/vendor/github.com/open-policy-agent/opa/loader/loader.go +++ b/vendor/github.com/open-policy-agent/opa/loader/loader.go @@ -8,15 +8,17 @@ package loader import ( "bytes" "fmt" + "io" "io/fs" "os" "path/filepath" "sort" "strings" - "github.com/ghodss/yaml" + "sigs.k8s.io/yaml" "github.com/open-policy-agent/opa/ast" + astJSON "github.com/open-policy-agent/opa/ast/json" "github.com/open-policy-agent/opa/bundle" fileurl "github.com/open-policy-agent/opa/internal/file/url" "github.com/open-policy-agent/opa/internal/merge" @@ -91,6 +93,7 @@ type FileLoader interface { All(paths []string) (*Result, error) Filtered(paths []string, filter Filter) (*Result, error) AsBundle(path string) (*bundle.Bundle, error) + WithReader(io.Reader) FileLoader WithFS(fs.FS) FileLoader WithMetrics(metrics.Metrics) FileLoader WithFilter(Filter) FileLoader @@ -98,6 +101,7 @@ type FileLoader interface { WithSkipBundleVerification(bool) FileLoader WithProcessAnnotation(bool) FileLoader WithCapabilities(*ast.Capabilities) FileLoader + WithJSONOptions(*astJSON.Options) FileLoader } // NewFileLoader returns a new FileLoader instance. @@ -116,6 +120,7 @@ type fileLoader struct { files map[string]bundle.FileInfo opts ast.ParserOptions fsys fs.FS + reader io.Reader } // WithFS provides an fs.FS to use for loading files. You can pass nil to @@ -126,6 +131,14 @@ func (fl *fileLoader) WithFS(fsys fs.FS) FileLoader { return fl } +// WithReader provides an io.Reader to use for loading the bundle tarball. +// An io.Reader passed via WithReader takes precedence over an fs.FS passed +// via WithFS. +func (fl *fileLoader) WithReader(rdr io.Reader) FileLoader { + fl.reader = rdr + return fl +} + // WithMetrics provides the metrics instance to use while loading func (fl *fileLoader) WithMetrics(m metrics.Metrics) FileLoader { fl.metrics = m @@ -162,6 +175,12 @@ func (fl *fileLoader) WithCapabilities(caps *ast.Capabilities) FileLoader { return fl } +// WithJSONOptions sets the JSONOptions for use when parsing files +func (fl *fileLoader) WithJSONOptions(opts *astJSON.Options) FileLoader { + fl.opts.JSONOptions = opts + return fl +} + // All returns a Result object loaded (recursively) from the specified paths. func (fl fileLoader) All(paths []string) (*Result, error) { return fl.Filtered(paths, nil) @@ -212,7 +231,14 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) { if err != nil { return nil, err } - bundleLoader, isDir, err := GetBundleDirectoryLoaderWithFilter(path, fl.filter) + + var bundleLoader bundle.DirectoryLoader + var isDir bool + if fl.reader != nil { + bundleLoader = bundle.NewTarballLoaderWithBaseURL(fl.reader, path).WithFilter(fl.filter) + } else { + bundleLoader, isDir, err = GetBundleDirectoryLoaderFS(fl.fsys, path, fl.filter) + } if err != nil { return nil, err } @@ -222,7 +248,8 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) { WithBundleVerificationConfig(fl.bvc). WithSkipBundleVerification(fl.skipVerify). WithProcessAnnotations(fl.opts.ProcessAnnotation). - WithCapabilities(fl.opts.Capabilities) + WithCapabilities(fl.opts.Capabilities). + WithJSONOptions(fl.opts.JSONOptions) // For bundle directories add the full path in front of module file names // to simplify debugging. @@ -239,55 +266,57 @@ func (fl fileLoader) AsBundle(path string) (*bundle.Bundle, error) { } // GetBundleDirectoryLoader returns a bundle directory loader which can be used to load -// files in the directory. +// files in the directory func GetBundleDirectoryLoader(path string) (bundle.DirectoryLoader, bool, error) { - path, err := fileurl.Clean(path) - if err != nil { - return nil, false, err - } - - fi, err := os.Stat(path) - if err != nil { - return nil, false, fmt.Errorf("error reading %q: %s", path, err) - } - - var bundleLoader bundle.DirectoryLoader - - if fi.IsDir() { - bundleLoader = bundle.NewDirectoryLoader(path) - } else { - fh, err := os.Open(path) - if err != nil { - return nil, false, err - } - bundleLoader = bundle.NewTarballLoaderWithBaseURL(fh, path) - } - return bundleLoader, fi.IsDir(), nil + return GetBundleDirectoryLoaderFS(nil, path, nil) } // GetBundleDirectoryLoaderWithFilter returns a bundle directory loader which can be used to load // files in the directory after applying the given filter. func GetBundleDirectoryLoaderWithFilter(path string, filter Filter) (bundle.DirectoryLoader, bool, error) { + return GetBundleDirectoryLoaderFS(nil, path, filter) +} + +// GetBundleDirectoryLoaderFS returns a bundle directory loader which can be used to load +// files in the directory. +func GetBundleDirectoryLoaderFS(fsys fs.FS, path string, filter Filter) (bundle.DirectoryLoader, bool, error) { path, err := fileurl.Clean(path) if err != nil { return nil, false, err } - fi, err := os.Stat(path) + var fi fs.FileInfo + if fsys != nil { + fi, err = fs.Stat(fsys, path) + } else { + fi, err = os.Stat(path) + } if err != nil { return nil, false, fmt.Errorf("error reading %q: %s", path, err) } var bundleLoader bundle.DirectoryLoader - if fi.IsDir() { - bundleLoader = bundle.NewDirectoryLoader(path).WithFilter(filter) + if fsys != nil { + bundleLoader = bundle.NewFSLoaderWithRoot(fsys, path) + } else { + bundleLoader = bundle.NewDirectoryLoader(path) + } } else { - fh, err := os.Open(path) + var fh fs.File + if fsys != nil { + fh, err = fsys.Open(path) + } else { + fh, err = os.Open(path) + } if err != nil { return nil, false, err } - bundleLoader = bundle.NewTarballLoaderWithBaseURL(fh, path).WithFilter(filter) + bundleLoader = bundle.NewTarballLoaderWithBaseURL(fh, path) + } + + if filter != nil { + bundleLoader = bundleLoader.WithFilter(filter) } return bundleLoader, fi.IsDir(), nil } @@ -721,11 +750,10 @@ func loadRego(path string, bs []byte, m metrics.Metrics, opts ast.ParserOptions) func loadJSON(path string, bs []byte, m metrics.Metrics) (interface{}, error) { m.Timer(metrics.RegoDataParse).Start() - buf := bytes.NewBuffer(bs) - decoder := util.NewJSONDecoder(buf) var x interface{} - err := decoder.Decode(&x) + err := util.UnmarshalJSON(bs, &x) m.Timer(metrics.RegoDataParse).Stop() + if err != nil { return nil, fmt.Errorf("%s: %w", path, err) } diff --git a/vendor/github.com/open-policy-agent/opa/logging/logging.go b/vendor/github.com/open-policy-agent/opa/logging/logging.go new file mode 100644 index 00000000000..3ce76da468b --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/logging/logging.go @@ -0,0 +1,233 @@ +package logging + +import ( + "context" + "io" + + "github.com/sirupsen/logrus" +) + +// Level log level for Logger +type Level uint8 + +const ( + // Error error log level + Error Level = iota + // Warn warn log level + Warn + // Info info log level + Info + // Debug debug log level + Debug +) + +// Logger provides interface for OPA logger implementations +type Logger interface { + Debug(fmt string, a ...interface{}) + Info(fmt string, a ...interface{}) + Error(fmt string, a ...interface{}) + Warn(fmt string, a ...interface{}) + + WithFields(map[string]interface{}) Logger + + GetLevel() Level + SetLevel(Level) +} + +// StandardLogger is the default OPA logger implementation. +type StandardLogger struct { + logger *logrus.Logger + fields map[string]interface{} +} + +// New returns a new standard logger. +func New() *StandardLogger { + return &StandardLogger{ + logger: logrus.New(), + } +} + +// Get returns the standard logger used throughout OPA. +// +// Deprecated. Do not rely on the global logger. +func Get() *StandardLogger { + return &StandardLogger{ + logger: logrus.StandardLogger(), + } +} + +// SetOutput sets the underlying logrus output. +func (l *StandardLogger) SetOutput(w io.Writer) { + l.logger.SetOutput(w) +} + +// SetFormatter sets the underlying logrus formatter. +func (l *StandardLogger) SetFormatter(formatter logrus.Formatter) { + l.logger.SetFormatter(formatter) +} + +// WithFields provides additional fields to include in log output +func (l *StandardLogger) WithFields(fields map[string]interface{}) Logger { + cp := *l + cp.fields = make(map[string]interface{}) + for k, v := range l.fields { + cp.fields[k] = v + } + for k, v := range fields { + cp.fields[k] = v + } + return &cp +} + +// getFields returns additional fields of this logger +func (l *StandardLogger) getFields() map[string]interface{} { + return l.fields +} + +// SetLevel sets the standard logger level. +func (l *StandardLogger) SetLevel(level Level) { + var logrusLevel logrus.Level + switch level { + case Error: // set logging level report Warn or higher (includes Error) + logrusLevel = logrus.WarnLevel + case Warn: + logrusLevel = logrus.WarnLevel + case Info: + logrusLevel = logrus.InfoLevel + case Debug: + logrusLevel = logrus.DebugLevel + default: + l.Warn("unknown log level %v", level) + logrusLevel = logrus.InfoLevel + } + + l.logger.SetLevel(logrusLevel) +} + +// GetLevel returns the standard logger level. +func (l *StandardLogger) GetLevel() Level { + logrusLevel := l.logger.GetLevel() + + var level Level + switch logrusLevel { + case logrus.WarnLevel: + level = Error + case logrus.InfoLevel: + level = Info + case logrus.DebugLevel: + level = Debug + default: + l.Warn("unknown log level %v", logrusLevel) + level = Info + } + + return level +} + +// Debug logs at debug level +func (l *StandardLogger) Debug(fmt string, a ...interface{}) { + l.logger.WithFields(l.getFields()).Debugf(fmt, a...) +} + +// Info logs at info level +func (l *StandardLogger) Info(fmt string, a ...interface{}) { + l.logger.WithFields(l.getFields()).Infof(fmt, a...) +} + +// Error logs at error level +func (l *StandardLogger) Error(fmt string, a ...interface{}) { + l.logger.WithFields(l.getFields()).Errorf(fmt, a...) +} + +// Warn logs at warn level +func (l *StandardLogger) Warn(fmt string, a ...interface{}) { + l.logger.WithFields(l.getFields()).Warnf(fmt, a...) +} + +// NoOpLogger logging implementation that does nothing +type NoOpLogger struct { + level Level + fields map[string]interface{} +} + +// NewNoOpLogger instantiates new NoOpLogger +func NewNoOpLogger() *NoOpLogger { + return &NoOpLogger{ + level: Info, + } +} + +// WithFields provides additional fields to include in log output. +// Implemented here primarily to be able to switch between implementations without loss of data. +func (l *NoOpLogger) WithFields(fields map[string]interface{}) Logger { + cp := *l + cp.fields = fields + return &cp +} + +// Debug noop +func (*NoOpLogger) Debug(string, ...interface{}) {} + +// Info noop +func (*NoOpLogger) Info(string, ...interface{}) {} + +// Error noop +func (*NoOpLogger) Error(string, ...interface{}) {} + +// Warn noop +func (*NoOpLogger) Warn(string, ...interface{}) {} + +// SetLevel set log level +func (l *NoOpLogger) SetLevel(level Level) { + l.level = level +} + +// GetLevel get log level +func (l *NoOpLogger) GetLevel() Level { + return l.level +} + +type requestContextKey string + +const reqCtxKey = requestContextKey("request-context-key") + +// RequestContext represents the request context used to store data +// related to the request that could be used on logs. +type RequestContext struct { + ClientAddr string + ReqID uint64 + ReqMethod string + ReqPath string +} + +// Fields adapts the RequestContext fields to logrus.Fields. +func (rctx RequestContext) Fields() logrus.Fields { + return logrus.Fields{ + "client_addr": rctx.ClientAddr, + "req_id": rctx.ReqID, + "req_method": rctx.ReqMethod, + "req_path": rctx.ReqPath, + } +} + +// NewContext returns a copy of parent with an associated RequestContext. +func NewContext(parent context.Context, val *RequestContext) context.Context { + return context.WithValue(parent, reqCtxKey, val) +} + +// FromContext returns the RequestContext associated with ctx, if any. +func FromContext(ctx context.Context) (*RequestContext, bool) { + requestContext, ok := ctx.Value(reqCtxKey).(*RequestContext) + return requestContext, ok +} + +const decisionCtxKey = requestContextKey("decision_id") + +func WithDecisionID(parent context.Context, id string) context.Context { + return context.WithValue(parent, decisionCtxKey, id) +} + +func DecisionIDFromContext(ctx context.Context) (string, bool) { + s, ok := ctx.Value(decisionCtxKey).(string) + return s, ok +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/plugins.go b/vendor/github.com/open-policy-agent/opa/plugins/plugins.go new file mode 100644 index 00000000000..ef4d31ceebc --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/plugins.go @@ -0,0 +1,983 @@ +// Copyright 2018 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package plugins implements plugin management for the policy engine. +package plugins + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + "go.opentelemetry.io/otel/sdk/trace" + + "github.com/gorilla/mux" + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/bundle" + "github.com/open-policy-agent/opa/config" + "github.com/open-policy-agent/opa/hooks" + bundleUtils "github.com/open-policy-agent/opa/internal/bundle" + cfg "github.com/open-policy-agent/opa/internal/config" + "github.com/open-policy-agent/opa/internal/errors" + initload "github.com/open-policy-agent/opa/internal/runtime/init" + "github.com/open-policy-agent/opa/keys" + "github.com/open-policy-agent/opa/loader" + "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/plugins/rest" + "github.com/open-policy-agent/opa/resolver/wasm" + "github.com/open-policy-agent/opa/storage" + "github.com/open-policy-agent/opa/topdown/cache" + "github.com/open-policy-agent/opa/topdown/print" + "github.com/open-policy-agent/opa/tracing" +) + +// Factory defines the interface OPA uses to instantiate your plugin. +// +// When OPA processes it's configuration it looks for factories that +// have been registered by calling runtime.RegisterPlugin. Factories +// are registered to a name which is used to key into the +// configuration blob. If your plugin has not been configured, your +// factory will not be invoked. +// +// plugins: +// my_plugin1: +// some_key: foo +// # my_plugin2: +// # some_key2: bar +// +// If OPA was started with the configuration above and received two +// calls to runtime.RegisterPlugins (one with NAME "my_plugin1" and +// one with NAME "my_plugin2"), it would only invoke the factory for +// for my_plugin1. +// +// OPA instantiates and reconfigures plugins in two steps. First, OPA +// will call Validate to check the configuration. Assuming the +// configuration is valid, your factory should return a configuration +// value that can be used to construct your plugin. Second, OPA will +// call New to instantiate your plugin providing the configuration +// value returned from the Validate call. +// +// Validate receives a slice of bytes representing plugin +// configuration and returns a configuration value that can be used to +// instantiate your plugin. The manager is provided to give access to +// the OPA's compiler, storage layer, and global configuration. Your +// Validate function will typically: +// +// 1. Deserialize the raw config bytes +// 2. Validate the deserialized config for semantic errors +// 3. Inject default values +// 4. Return a deserialized/parsed config +// +// New receives a valid configuration for your plugin and returns a +// plugin object. Your New function will typically: +// +// 1. Cast the config value to it's own type +// 2. Instantiate a plugin object +// 3. Return the plugin object +// 4. Update status via `plugins.Manager#UpdatePluginStatus` +// +// After a plugin has been created subsequent status updates can be +// send anytime the plugin enters a ready or error state. +type Factory interface { + Validate(manager *Manager, config []byte) (interface{}, error) + New(manager *Manager, config interface{}) Plugin +} + +// Plugin defines the interface OPA uses to manage your plugin. +// +// When OPA starts it will start all of the plugins it was configured +// to instantiate. Each time a new plugin is configured (via +// discovery), OPA will start it. You can use the Start call to spawn +// additional goroutines or perform initialization tasks. +// +// Currently OPA will not call Stop on plugins. +// +// When OPA receives new configuration for your plugin via discovery +// it will first Validate the configuration using your factory and +// then call Reconfigure. +type Plugin interface { + Start(ctx context.Context) error + Stop(ctx context.Context) + Reconfigure(ctx context.Context, config interface{}) +} + +// Triggerable defines the interface plugins use for manual plugin triggers. +type Triggerable interface { + Trigger(context.Context) error +} + +// State defines the state that a Plugin instance is currently +// in with pre-defined states. +type State string + +const ( + // StateNotReady indicates that the Plugin is not in an error state, but isn't + // ready for normal operation yet. This should only happen at + // initialization time. + StateNotReady State = "NOT_READY" + + // StateOK signifies that the Plugin is operating normally. + StateOK State = "OK" + + // StateErr indicates that the Plugin is in an error state and should not + // be considered as functional. + StateErr State = "ERROR" + + // StateWarn indicates the Plugin is operating, but in a potentially dangerous or + // degraded state. It may be used to indicate manual remediation is needed, or to + // alert admins of some other noteworthy state. + StateWarn State = "WARN" +) + +// TriggerMode defines the trigger mode utilized by a Plugin for bundle download, +// log upload etc. +type TriggerMode string + +const ( + // TriggerPeriodic represents periodic polling mechanism + TriggerPeriodic TriggerMode = "periodic" + + // TriggerManual represents manual triggering mechanism + TriggerManual TriggerMode = "manual" + + // DefaultTriggerMode represents default trigger mechanism + DefaultTriggerMode TriggerMode = "periodic" +) + +// Status has a Plugin's current status plus an optional Message. +type Status struct { + State State `json:"state"` + Message string `json:"message,omitempty"` +} + +func (s *Status) String() string { + return fmt.Sprintf("{%v %q}", s.State, s.Message) +} + +// StatusListener defines a handler to register for status updates. +type StatusListener func(status map[string]*Status) + +// Manager implements lifecycle management of plugins and gives plugins access +// to engine-wide components like storage. +type Manager struct { + Store storage.Store + Config *config.Config + Info *ast.Term + ID string + + compiler *ast.Compiler + compilerMux sync.RWMutex + wasmResolvers []*wasm.Resolver + wasmResolversMtx sync.RWMutex + services map[string]rest.Client + keys map[string]*keys.Config + plugins []namedplugin + registeredTriggers []func(storage.Transaction) + mtx sync.Mutex + pluginStatus map[string]*Status + pluginStatusListeners map[string]StatusListener + initBundles map[string]*bundle.Bundle + initFiles loader.Result + maxErrors int + initialized bool + interQueryBuiltinCacheConfig *cache.Config + gracefulShutdownPeriod int + registeredCacheTriggers []func(*cache.Config) + logger logging.Logger + consoleLogger logging.Logger + serverInitialized chan struct{} + serverInitializedOnce sync.Once + printHook print.Hook + enablePrintStatements bool + router *mux.Router + prometheusRegister prometheus.Registerer + tracerProvider *trace.TracerProvider + distributedTacingOpts tracing.Options + registeredNDCacheTriggers []func(bool) + bootstrapConfigLabels map[string]string + hooks hooks.Hooks +} + +type managerContextKey string +type managerWasmResolverKey string + +const managerCompilerContextKey = managerContextKey("compiler") +const managerWasmResolverContextKey = managerWasmResolverKey("wasmResolvers") + +// SetCompilerOnContext puts the compiler into the storage context. Calling this +// function before committing updated policies to storage allows the manager to +// skip parsing and compiling of modules. Instead, the manager will use the +// compiler that was stored on the context. +func SetCompilerOnContext(context *storage.Context, compiler *ast.Compiler) { + context.Put(managerCompilerContextKey, compiler) +} + +// GetCompilerOnContext gets the compiler cached on the storage context. +func GetCompilerOnContext(context *storage.Context) *ast.Compiler { + compiler, ok := context.Get(managerCompilerContextKey).(*ast.Compiler) + if !ok { + return nil + } + return compiler +} + +// SetWasmResolversOnContext puts a set of Wasm Resolvers into the storage +// context. Calling this function before committing updated wasm modules to +// storage allows the manager to skip initializing modules before using them. +// Instead, the manager will use the compiler that was stored on the context. +func SetWasmResolversOnContext(context *storage.Context, rs []*wasm.Resolver) { + context.Put(managerWasmResolverContextKey, rs) +} + +// getWasmResolversOnContext gets the resolvers cached on the storage context. +func getWasmResolversOnContext(context *storage.Context) []*wasm.Resolver { + resolvers, ok := context.Get(managerWasmResolverContextKey).([]*wasm.Resolver) + if !ok { + return nil + } + return resolvers +} + +func validateTriggerMode(mode TriggerMode) error { + switch mode { + case TriggerPeriodic, TriggerManual: + return nil + default: + return fmt.Errorf("invalid trigger mode %q (want %q or %q)", mode, TriggerPeriodic, TriggerManual) + } +} + +// ValidateAndInjectDefaultsForTriggerMode validates the trigger mode and injects default values +func ValidateAndInjectDefaultsForTriggerMode(a, b *TriggerMode) (*TriggerMode, error) { + + if a == nil && b != nil { + err := validateTriggerMode(*b) + if err != nil { + return nil, err + } + return b, nil + } else if a != nil && b == nil { + err := validateTriggerMode(*a) + if err != nil { + return nil, err + } + return a, nil + } else if a != nil && b != nil { + if *a != *b { + return nil, fmt.Errorf("trigger mode mismatch: %s and %s (hint: check discovery configuration)", *a, *b) + } + err := validateTriggerMode(*a) + if err != nil { + return nil, err + } + return a, nil + + } else { + t := DefaultTriggerMode + return &t, nil + } +} + +type namedplugin struct { + name string + plugin Plugin +} + +// Info sets the runtime information on the manager. The runtime information is +// propagated to opa.runtime() built-in function calls. +func Info(term *ast.Term) func(*Manager) { + return func(m *Manager) { + m.Info = term + } +} + +// InitBundles provides the initial set of bundles to load. +func InitBundles(b map[string]*bundle.Bundle) func(*Manager) { + return func(m *Manager) { + m.initBundles = b + } +} + +// InitFiles provides the initial set of other data/policy files to load. +func InitFiles(f loader.Result) func(*Manager) { + return func(m *Manager) { + m.initFiles = f + } +} + +// MaxErrors sets the error limit for the manager's shared compiler. +func MaxErrors(n int) func(*Manager) { + return func(m *Manager) { + m.maxErrors = n + } +} + +// GracefulShutdownPeriod passes the configured graceful shutdown period to plugins +func GracefulShutdownPeriod(gracefulShutdownPeriod int) func(*Manager) { + return func(m *Manager) { + m.gracefulShutdownPeriod = gracefulShutdownPeriod + } +} + +// Logger configures the passed logger on the plugin manager (useful to +// configure default fields) +func Logger(logger logging.Logger) func(*Manager) { + return func(m *Manager) { + m.logger = logger + } +} + +// ConsoleLogger sets the passed logger to be used by plugins that are +// configured with console logging enabled. +func ConsoleLogger(logger logging.Logger) func(*Manager) { + return func(m *Manager) { + m.consoleLogger = logger + } +} + +func EnablePrintStatements(yes bool) func(*Manager) { + return func(m *Manager) { + m.enablePrintStatements = yes + } +} + +func PrintHook(h print.Hook) func(*Manager) { + return func(m *Manager) { + m.printHook = h + } +} + +func WithRouter(r *mux.Router) func(*Manager) { + return func(m *Manager) { + m.router = r + } +} + +// WithPrometheusRegister sets the passed prometheus.Registerer to be used by plugins +func WithPrometheusRegister(prometheusRegister prometheus.Registerer) func(*Manager) { + return func(m *Manager) { + m.prometheusRegister = prometheusRegister + } +} + +// WithTracerProvider sets the passed *trace.TracerProvider to be used by plugins +func WithTracerProvider(tracerProvider *trace.TracerProvider) func(*Manager) { + return func(m *Manager) { + m.tracerProvider = tracerProvider + } +} + +// WithDistributedTracingOpts sets the options to be used by distributed tracing. +func WithDistributedTracingOpts(tr tracing.Options) func(*Manager) { + return func(m *Manager) { + m.distributedTacingOpts = tr + } +} + +// WithHooks allows passing hooks to the plugin manager. +func WithHooks(hs hooks.Hooks) func(*Manager) { + return func(m *Manager) { + m.hooks = hs + } +} + +// New creates a new Manager using config. +func New(raw []byte, id string, store storage.Store, opts ...func(*Manager)) (*Manager, error) { + + parsedConfig, err := config.ParseConfig(raw, id) + if err != nil { + return nil, err + } + + m := &Manager{ + Store: store, + Config: parsedConfig, + ID: id, + pluginStatus: map[string]*Status{}, + pluginStatusListeners: map[string]StatusListener{}, + maxErrors: -1, + serverInitialized: make(chan struct{}), + bootstrapConfigLabels: parsedConfig.Labels, + } + + for _, f := range opts { + f(m) + } + + if m.logger == nil { + m.logger = logging.Get() + } + + if m.consoleLogger == nil { + m.consoleLogger = logging.New() + } + + m.hooks.Each(func(h hooks.Hook) { + if f, ok := h.(hooks.ConfigHook); ok { + if c, e := f.OnConfig(context.Background(), parsedConfig); e != nil { + err = errors.Join(err, e) + } else { + parsedConfig = c + } + } + }) + if err != nil { + return nil, err + } + + // do after options and overrides + m.keys, err = keys.ParseKeysConfig(parsedConfig.Keys) + if err != nil { + return nil, err + } + + m.interQueryBuiltinCacheConfig, err = cache.ParseCachingConfig(parsedConfig.Caching) + if err != nil { + return nil, err + } + + serviceOpts := cfg.ServiceOptions{ + Raw: parsedConfig.Services, + AuthPlugin: m.AuthPlugin, + Keys: m.keys, + Logger: m.logger, + DistributedTacingOpts: m.distributedTacingOpts, + } + + m.services, err = cfg.ParseServicesConfig(serviceOpts) + if err != nil { + return nil, err + } + + return m, nil +} + +// Init returns an error if the manager could not initialize itself. Init() should +// be called before Start(). Init() is idempotent. +func (m *Manager) Init(ctx context.Context) error { + + if m.initialized { + return nil + } + + params := storage.TransactionParams{ + Write: true, + Context: storage.NewContext(), + } + + err := storage.Txn(ctx, m.Store, params, func(txn storage.Transaction) error { + + result, err := initload.InsertAndCompile(ctx, initload.InsertAndCompileOptions{ + Store: m.Store, + Txn: txn, + Files: m.initFiles, + Bundles: m.initBundles, + MaxErrors: m.maxErrors, + EnablePrintStatements: m.enablePrintStatements, + }) + + if err != nil { + return err + } + + SetCompilerOnContext(params.Context, result.Compiler) + + resolvers, err := bundleUtils.LoadWasmResolversFromStore(ctx, m.Store, txn, nil) + if err != nil { + return err + } + SetWasmResolversOnContext(params.Context, resolvers) + + _, err = m.Store.Register(ctx, txn, storage.TriggerConfig{OnCommit: m.onCommit}) + return err + }) + + if err != nil { + return err + } + + m.initialized = true + return nil +} + +// Labels returns the set of labels from the configuration. +func (m *Manager) Labels() map[string]string { + m.mtx.Lock() + defer m.mtx.Unlock() + return m.Config.Labels +} + +// InterQueryBuiltinCacheConfig returns the configuration for the inter-query cache. +func (m *Manager) InterQueryBuiltinCacheConfig() *cache.Config { + m.mtx.Lock() + defer m.mtx.Unlock() + return m.interQueryBuiltinCacheConfig +} + +// Register adds a plugin to the manager. When the manager is started, all of +// the plugins will be started. +func (m *Manager) Register(name string, plugin Plugin) { + m.mtx.Lock() + defer m.mtx.Unlock() + m.plugins = append(m.plugins, namedplugin{ + name: name, + plugin: plugin, + }) + if _, ok := m.pluginStatus[name]; !ok { + m.pluginStatus[name] = &Status{State: StateNotReady} + } +} + +// Plugins returns the list of plugins registered with the manager. +func (m *Manager) Plugins() []string { + m.mtx.Lock() + defer m.mtx.Unlock() + result := make([]string, len(m.plugins)) + for i := range m.plugins { + result[i] = m.plugins[i].name + } + return result +} + +// Plugin returns the plugin registered with name or nil if name is not found. +func (m *Manager) Plugin(name string) Plugin { + m.mtx.Lock() + defer m.mtx.Unlock() + for i := range m.plugins { + if m.plugins[i].name == name { + return m.plugins[i].plugin + } + } + return nil +} + +// AuthPlugin returns the HTTPAuthPlugin registered with name or nil if name is not found. +func (m *Manager) AuthPlugin(name string) rest.HTTPAuthPlugin { + m.mtx.Lock() + defer m.mtx.Unlock() + for i := range m.plugins { + if m.plugins[i].name == name { + return m.plugins[i].plugin.(rest.HTTPAuthPlugin) + } + } + return nil +} + +// GetCompiler returns the manager's compiler. +func (m *Manager) GetCompiler() *ast.Compiler { + m.compilerMux.RLock() + defer m.compilerMux.RUnlock() + return m.compiler +} + +func (m *Manager) setCompiler(compiler *ast.Compiler) { + m.compilerMux.Lock() + defer m.compilerMux.Unlock() + m.compiler = compiler +} + +// GetRouter returns the managers router if set +func (m *Manager) GetRouter() *mux.Router { + m.mtx.Lock() + defer m.mtx.Unlock() + return m.router +} + +// RegisterCompilerTrigger registers for change notifications when the compiler +// is changed. +func (m *Manager) RegisterCompilerTrigger(f func(storage.Transaction)) { + m.mtx.Lock() + defer m.mtx.Unlock() + m.registeredTriggers = append(m.registeredTriggers, f) +} + +// GetWasmResolvers returns the manager's set of Wasm Resolvers. +func (m *Manager) GetWasmResolvers() []*wasm.Resolver { + m.wasmResolversMtx.RLock() + defer m.wasmResolversMtx.RUnlock() + return m.wasmResolvers +} + +func (m *Manager) setWasmResolvers(rs []*wasm.Resolver) { + m.wasmResolversMtx.Lock() + defer m.wasmResolversMtx.Unlock() + m.wasmResolvers = rs +} + +// Start starts the manager. Init() should be called once before Start(). +func (m *Manager) Start(ctx context.Context) error { + + if m == nil { + return nil + } + + if !m.initialized { + if err := m.Init(ctx); err != nil { + return err + } + } + + var toStart []Plugin + + func() { + m.mtx.Lock() + defer m.mtx.Unlock() + toStart = make([]Plugin, len(m.plugins)) + for i := range m.plugins { + toStart[i] = m.plugins[i].plugin + } + }() + + for i := range toStart { + if err := toStart[i].Start(ctx); err != nil { + return err + } + } + + return nil +} + +// Stop stops the manager, stopping all the plugins registered with it. +// Any plugin that needs to perform cleanup should do so within the duration +// of the graceful shutdown period passed with the context as a timeout. +// Note that a graceful shutdown period configured with the Manager instance +// will override the timeout of the passed in context (if applicable). +func (m *Manager) Stop(ctx context.Context) { + var toStop []Plugin + + func() { + m.mtx.Lock() + defer m.mtx.Unlock() + toStop = make([]Plugin, len(m.plugins)) + for i := range m.plugins { + toStop[i] = m.plugins[i].plugin + } + }() + + var cancel context.CancelFunc + if m.gracefulShutdownPeriod > 0 { + ctx, cancel = context.WithTimeout(ctx, time.Duration(m.gracefulShutdownPeriod)*time.Second) + } else { + ctx, cancel = context.WithCancel(ctx) + } + defer cancel() + for i := range toStop { + toStop[i].Stop(ctx) + } + if c, ok := m.Store.(interface{ Close(context.Context) error }); ok { + if err := c.Close(ctx); err != nil { + m.logger.Error("Error closing store: %v", err) + } + } +} + +// Reconfigure updates the configuration on the manager. +func (m *Manager) Reconfigure(config *config.Config) error { + opts := cfg.ServiceOptions{ + Raw: config.Services, + AuthPlugin: m.AuthPlugin, + Logger: m.logger, + DistributedTacingOpts: m.distributedTacingOpts, + } + + keys, err := keys.ParseKeysConfig(config.Keys) + if err != nil { + return err + } + opts.Keys = keys + + services, err := cfg.ParseServicesConfig(opts) + if err != nil { + return err + } + + interQueryBuiltinCacheConfig, err := cache.ParseCachingConfig(config.Caching) + if err != nil { + return err + } + + m.mtx.Lock() + defer m.mtx.Unlock() + + // don't overwrite existing labels, only allow additions - always based on the boostrap config + if config.Labels == nil { + config.Labels = m.bootstrapConfigLabels + } else { + for label, value := range m.bootstrapConfigLabels { + config.Labels[label] = value + } + } + + // don't erase persistence directory + if config.PersistenceDirectory == nil { + config.PersistenceDirectory = m.Config.PersistenceDirectory + } + + m.Config = config + m.interQueryBuiltinCacheConfig = interQueryBuiltinCacheConfig + for name, client := range services { + m.services[name] = client + } + + for name, key := range keys { + m.keys[name] = key + } + + for _, trigger := range m.registeredCacheTriggers { + trigger(interQueryBuiltinCacheConfig) + } + + for _, trigger := range m.registeredNDCacheTriggers { + trigger(config.NDBuiltinCache) + } + + return nil +} + +// PluginStatus returns the current statuses of any plugins registered. +func (m *Manager) PluginStatus() map[string]*Status { + m.mtx.Lock() + defer m.mtx.Unlock() + + return m.copyPluginStatus() +} + +// RegisterPluginStatusListener registers a StatusListener to be +// called when plugin status updates occur. +func (m *Manager) RegisterPluginStatusListener(name string, listener StatusListener) { + m.mtx.Lock() + defer m.mtx.Unlock() + + m.pluginStatusListeners[name] = listener +} + +// UnregisterPluginStatusListener removes a StatusListener registered with the +// same name. +func (m *Manager) UnregisterPluginStatusListener(name string) { + m.mtx.Lock() + defer m.mtx.Unlock() + + delete(m.pluginStatusListeners, name) +} + +// UpdatePluginStatus updates a named plugins status. Any registered +// listeners will be called with a copy of the new state of all +// plugins. +func (m *Manager) UpdatePluginStatus(pluginName string, status *Status) { + + var toNotify map[string]StatusListener + var statuses map[string]*Status + + func() { + m.mtx.Lock() + defer m.mtx.Unlock() + m.pluginStatus[pluginName] = status + toNotify = make(map[string]StatusListener, len(m.pluginStatusListeners)) + for k, v := range m.pluginStatusListeners { + toNotify[k] = v + } + statuses = m.copyPluginStatus() + }() + + for _, l := range toNotify { + l(statuses) + } +} + +func (m *Manager) copyPluginStatus() map[string]*Status { + statusCpy := map[string]*Status{} + for k, v := range m.pluginStatus { + var cpy *Status + if v != nil { + cpy = &Status{ + State: v.State, + Message: v.Message, + } + } + statusCpy[k] = cpy + } + return statusCpy +} + +func (m *Manager) onCommit(ctx context.Context, txn storage.Transaction, event storage.TriggerEvent) { + + compiler := GetCompilerOnContext(event.Context) + + // If the context does not contain the compiler fallback to loading the + // compiler from the store. Currently the bundle plugin sets the + // compiler on the context but the server does not (nor would users + // implementing their own policy loading.) + if compiler == nil && event.PolicyChanged() { + compiler, _ = loadCompilerFromStore(ctx, m.Store, txn, m.enablePrintStatements) + } + + if compiler != nil { + m.setCompiler(compiler) + for _, f := range m.registeredTriggers { + f(txn) + } + } + + // Similar to the compiler, look for a set of resolvers on the transaction + // context. If they are not set we may need to reload from the store. + resolvers := getWasmResolversOnContext(event.Context) + if resolvers != nil { + m.setWasmResolvers(resolvers) + + } else if event.DataChanged() { + if requiresWasmResolverReload(event) { + resolvers, err := bundleUtils.LoadWasmResolversFromStore(ctx, m.Store, txn, nil) + if err != nil { + panic(err) + } + m.setWasmResolvers(resolvers) + } else { + err := m.updateWasmResolversData(ctx, event) + if err != nil { + panic(err) + } + } + } +} + +func loadCompilerFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, enablePrintStatements bool) (*ast.Compiler, error) { + policies, err := store.ListPolicies(ctx, txn) + if err != nil { + return nil, err + } + modules := map[string]*ast.Module{} + + for _, policy := range policies { + bs, err := store.GetPolicy(ctx, txn, policy) + if err != nil { + return nil, err + } + module, err := ast.ParseModule(policy, string(bs)) + if err != nil { + return nil, err + } + modules[policy] = module + } + + compiler := ast.NewCompiler().WithEnablePrintStatements(enablePrintStatements) + compiler.Compile(modules) + return compiler, nil +} + +func requiresWasmResolverReload(event storage.TriggerEvent) bool { + // If the data changes touched the bundle path (which includes + // the wasm modules) we will reload them. Otherwise update + // data for each module already on the manager. + for _, dataEvent := range event.Data { + if dataEvent.Path.HasPrefix(bundle.BundlesBasePath) { + return true + } + } + return false +} + +func (m *Manager) updateWasmResolversData(ctx context.Context, event storage.TriggerEvent) error { + m.wasmResolversMtx.Lock() + defer m.wasmResolversMtx.Unlock() + + for _, resolver := range m.wasmResolvers { + for _, dataEvent := range event.Data { + var err error + if dataEvent.Removed { + err = resolver.RemoveDataPath(ctx, dataEvent.Path) + } else { + err = resolver.SetDataPath(ctx, dataEvent.Path, dataEvent.Data) + } + if err != nil { + return fmt.Errorf("failed to update wasm runtime data: %s", err) + } + } + } + return nil +} + +// PublicKeys returns a public keys that can be used for verifying signed bundles. +func (m *Manager) PublicKeys() map[string]*keys.Config { + m.mtx.Lock() + defer m.mtx.Unlock() + return m.keys +} + +// Client returns a client for communicating with a remote service. +func (m *Manager) Client(name string) rest.Client { + m.mtx.Lock() + defer m.mtx.Unlock() + return m.services[name] +} + +// Services returns a list of services that m can provide clients for. +func (m *Manager) Services() []string { + m.mtx.Lock() + defer m.mtx.Unlock() + s := make([]string, 0, len(m.services)) + for name := range m.services { + s = append(s, name) + } + return s +} + +// Logger gets the standard logger for this plugin manager. +func (m *Manager) Logger() logging.Logger { + return m.logger +} + +// ConsoleLogger gets the console logger for this plugin manager. +func (m *Manager) ConsoleLogger() logging.Logger { + return m.consoleLogger +} + +func (m *Manager) PrintHook() print.Hook { + return m.printHook +} + +func (m *Manager) EnablePrintStatements() bool { + return m.enablePrintStatements +} + +// ServerInitialized signals a channel indicating that the OPA +// server has finished initialization. +func (m *Manager) ServerInitialized() { + m.serverInitializedOnce.Do(func() { close(m.serverInitialized) }) +} + +// ServerInitializedChannel returns a receive-only channel that +// is closed when the OPA server has finished initialization. +// Be aware that the socket of the server listener may not be +// open by the time this channel is closed. There is a very +// small window where the socket may still be closed, due to +// a race condition. +func (m *Manager) ServerInitializedChannel() <-chan struct{} { + return m.serverInitialized +} + +// RegisterCacheTrigger accepts a func that receives new inter-query cache config generated by +// a reconfigure of the plugin manager, so that it can be propagated to existing inter-query caches. +func (m *Manager) RegisterCacheTrigger(trigger func(*cache.Config)) { + m.mtx.Lock() + defer m.mtx.Unlock() + m.registeredCacheTriggers = append(m.registeredCacheTriggers, trigger) +} + +// PrometheusRegister gets the prometheus.Registerer for this plugin manager. +func (m *Manager) PrometheusRegister() prometheus.Registerer { + return m.prometheusRegister +} + +// TracerProvider gets the *trace.TracerProvider for this plugin manager. +func (m *Manager) TracerProvider() *trace.TracerProvider { + return m.tracerProvider +} + +func (m *Manager) RegisterNDCacheTrigger(trigger func(bool)) { + m.mtx.Lock() + defer m.mtx.Unlock() + m.registeredNDCacheTriggers = append(m.registeredNDCacheTriggers, trigger) +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go b/vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go new file mode 100644 index 00000000000..f69496f08bf --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/rest/auth.go @@ -0,0 +1,915 @@ +// Copyright 2019 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package rest + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/sha512" + "crypto/tls" + "crypto/x509" + "encoding/asn1" + "encoding/base64" + "encoding/hex" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "hash" + "io" + "math/big" + "net/http" + "net/url" + "os" + "strings" + "time" + + "github.com/open-policy-agent/opa/internal/jwx/jwa" + "github.com/open-policy-agent/opa/internal/jwx/jws" + "github.com/open-policy-agent/opa/internal/jwx/jws/sign" + "github.com/open-policy-agent/opa/internal/providers/aws" + "github.com/open-policy-agent/opa/internal/uuid" + "github.com/open-policy-agent/opa/keys" + "github.com/open-policy-agent/opa/logging" +) + +const ( + // Default to s3 when the service for sigv4 signing is not specified for backwards compatibility + awsSigv4SigningDefaultService = "s3" +) + +// DefaultTLSConfig defines standard TLS configurations based on the Config +func DefaultTLSConfig(c Config) (*tls.Config, error) { + t := &tls.Config{} + url, err := url.Parse(c.URL) + if err != nil { + return nil, err + } + if url.Scheme == "https" { + t.InsecureSkipVerify = c.AllowInsecureTLS + } + + if c.TLS != nil && c.TLS.CACert != "" { + caCert, err := os.ReadFile(c.TLS.CACert) + if err != nil { + return nil, err + } + + var rootCAs *x509.CertPool + if c.TLS.SystemCARequired { + rootCAs, err = x509.SystemCertPool() + if err != nil { + return nil, err + } + } else { + rootCAs = x509.NewCertPool() + } + + ok := rootCAs.AppendCertsFromPEM(caCert) + if !ok { + return nil, errors.New("unable to parse and append CA certificate to certificate pool") + } + t.RootCAs = rootCAs + } + + return t, nil +} + +// DefaultRoundTripperClient is a reasonable set of defaults for HTTP auth plugins +func DefaultRoundTripperClient(t *tls.Config, timeout int64) *http.Client { + // Ensure we use a http.Transport with proper settings: the zero values are not + // a good choice, as they cause leaking connections: + // https://github.com/golang/go/issues/19620 + + // copy, we don't want to alter the default client's Transport + tr := http.DefaultTransport.(*http.Transport).Clone() + tr.ResponseHeaderTimeout = time.Duration(timeout) * time.Second + tr.TLSClientConfig = t + + c := *http.DefaultClient + c.Transport = tr + return &c +} + +// defaultAuthPlugin represents baseline 'no auth' behavior if no alternative plugin is specified for a service +type defaultAuthPlugin struct{} + +func (*defaultAuthPlugin) NewClient(c Config) (*http.Client, error) { + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +func (*defaultAuthPlugin) Prepare(*http.Request) error { + return nil +} + +type serverTLSConfig struct { + CACert string `json:"ca_cert,omitempty"` + SystemCARequired bool `json:"system_ca_required,omitempty"` +} + +// bearerAuthPlugin represents authentication via a bearer token in the HTTP Authorization header +type bearerAuthPlugin struct { + Token string `json:"token"` + TokenPath string `json:"token_path"` + Scheme string `json:"scheme,omitempty"` + + // encode is set to true for the OCIDownloader because + // it expects tokens in plain text but needs them in base64. + encode bool +} + +func (ap *bearerAuthPlugin) NewClient(c Config) (*http.Client, error) { + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + if ap.Token != "" && ap.TokenPath != "" { + return nil, errors.New("invalid config: specify a value for either the \"token\" or \"token_path\" field") + } + + if ap.Scheme == "" { + ap.Scheme = "Bearer" + } + + if c.Type == "oci" { + // Standard rest clients use the bearer token as it is defined in the Config + // but the OCIDownloader needs it encoded to base64 before using to sign a request. + ap.encode = true + } + + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +func (ap *bearerAuthPlugin) Prepare(req *http.Request) error { + token := ap.Token + + if ap.TokenPath != "" { + bytes, err := os.ReadFile(ap.TokenPath) + if err != nil { + return err + } + token = strings.TrimSpace(string(bytes)) + } + + if ap.encode { + token = base64.StdEncoding.EncodeToString([]byte(token)) + } + + req.Header.Add("Authorization", fmt.Sprintf("%v %v", ap.Scheme, token)) + return nil +} + +type tokenEndpointResponse struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + ExpiresIn int64 `json:"expires_in"` +} + +type awsKmsKeyConfig struct { + Name string `json:"name"` + Algorithm string `json:"algorithm"` +} + +func convertSignatureToBase64(alg string, der []byte) (string, error) { + r, s, derErr := pointsFromDER(der) + if derErr != nil { + return "", fmt.Errorf("failed to read points from der %v", derErr) + } + + signatureData, err := convertPointsToBase64(alg, r.Bytes(), s.Bytes()) + if err != nil { + return "", err + } + return signatureData, nil +} + +func pointsFromDER(der []byte) (R, S *big.Int, err error) { + R, S = &big.Int{}, &big.Int{} + data := asn1.RawValue{} + if _, err := asn1.Unmarshal(der, &data); err != nil { + return nil, nil, fmt.Errorf("failed to unmarshall the signature from DER format %v", err) + + } + // https://docs.aws.amazon.com/kms/latest/APIReference/API_Sign.html#API_Sign_ResponseSyntax + // https://datatracker.ietf.org/doc/html/rfc3279#section-2.2.3 + // The format of our DER string is 0x02 + rlen + r + 0x02 + slen + s + rLen := data.Bytes[1] // The entire length of R + offset of 2 for 0x02 and rlen + r := data.Bytes[2 : rLen+2] + // Ignore the next 0x02 and slen bytes and just take the start of S to the end of the byte array + s := data.Bytes[rLen+4:] + R.SetBytes(r) + S.SetBytes(s) + return +} + +func convertPointsToBase64(alg string, r, s []byte) (string, error) { + curveBits, err := retrieveCurveBits(alg) + if err != nil { + return "", err + } + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes++ + } + // We serialize the outputs (r and s) into big-endian byte arrays and pad + // them with zeros on the left to make sure the sizes work out. Both arrays + // must be keyBytes long, and the output must be 2*keyBytes long. + rBytesPadded := make([]byte, keyBytes) + copy(rBytesPadded[keyBytes-len(r):], r) + sBytesPadded := make([]byte, keyBytes) + copy(sBytesPadded[keyBytes-len(s):], s) + signatureEnc := append(rBytesPadded, sBytesPadded...) + + return base64.RawURLEncoding.EncodeToString(signatureEnc), nil +} + +func retrieveCurveBits(alg string) (int, error) { + var curveBits int + switch alg { + case "ECDSA_SHA_256": + curveBits = 256 + case "ECDSA_SHA_384": + curveBits = 384 + case "ECDSA_SHA_512": + curveBits = 512 + default: + return 0, fmt.Errorf("unsupported sign algorithm %s", alg) + } + return curveBits, nil +} + +func messageDigest(message []byte, alg string) ([]byte, error) { + var digest hash.Hash + + switch alg { + case "ECDSA_SHA_256": + digest = sha256.New() + case "ECDSA_SHA_384": + digest = sha512.New384() + case "ECDSA_SHA_512": + digest = sha512.New() + default: + return []byte{}, fmt.Errorf("unsupported sign algorithm %s", alg) + } + + digest.Write(message) + return digest.Sum(nil), nil +} + +// oauth2ClientCredentialsAuthPlugin represents authentication via a bearer token in the HTTP Authorization header +// obtained through the OAuth2 client credentials flow +type oauth2ClientCredentialsAuthPlugin struct { + GrantType string `json:"grant_type"` + TokenURL string `json:"token_url"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + SigningKeyID string `json:"signing_key"` + Thumbprint string `json:"thumbprint"` + Claims map[string]interface{} `json:"additional_claims"` + IncludeJti bool `json:"include_jti_claim"` + Scopes []string `json:"scopes,omitempty"` + AdditionalHeaders map[string]string `json:"additional_headers,omitempty"` + AdditionalParameters map[string]string `json:"additional_parameters,omitempty"` + AWSKmsKey *awsKmsKeyConfig `json:"aws_kms,omitempty"` + AWSSigningPlugin *awsSigningAuthPlugin `json:"aws_signing,omitempty"` + + signingKey *keys.Config + signingKeyParsed interface{} + tokenCache *oauth2Token + tlsSkipVerify bool + logger logging.Logger +} + +type oauth2Token struct { + Token string + ExpiresAt time.Time +} + +func (ap *oauth2ClientCredentialsAuthPlugin) createAuthJWT(ctx context.Context, claims map[string]interface{}, signingKey interface{}) (*string, error) { + now := time.Now() + baseClaims := map[string]interface{}{ + "iat": now.Unix(), + "exp": now.Add(10 * time.Minute).Unix(), + } + if claims == nil { + claims = make(map[string]interface{}) + } + for k, v := range baseClaims { + claims[k] = v + } + + if len(ap.Scopes) > 0 { + claims["scope"] = strings.Join(ap.Scopes, " ") + } + + if ap.IncludeJti { + jti, err := uuid.New(rand.Reader) + if err != nil { + return nil, err + } + claims["jti"] = jti + } + + payload, err := json.Marshal(claims) + if err != nil { + return nil, err + } + + var jwsHeaders []byte + var signatureAlg string + if ap.AWSKmsKey == nil { + signatureAlg = ap.signingKey.Algorithm + } else { + signatureAlg, err = ap.mapKMSAlgToSign(ap.AWSKmsKey.Algorithm) + if err != nil { + return nil, err + } + } + if ap.Thumbprint != "" { + bytes, err := hex.DecodeString(ap.Thumbprint) + if err != nil { + return nil, err + } + x5t := base64.URLEncoding.EncodeToString(bytes) + jwsHeaders = []byte(fmt.Sprintf(`{"typ":"JWT","alg":"%s","x5t":"%s"}`, signatureAlg, x5t)) + } else { + jwsHeaders = []byte(fmt.Sprintf(`{"typ":"JWT","alg":"%s"}`, signatureAlg)) + } + var jwsCompact []byte + if ap.AWSKmsKey == nil { + jwsCompact, err = jws.SignLiteral(payload, + jwa.SignatureAlgorithm(signatureAlg), + signingKey, + jwsHeaders, + rand.Reader) + } else { + jwsCompact, err = ap.SignWithKMS(ctx, payload, jwsHeaders) + } + if err != nil { + return nil, err + } + jwt := string(jwsCompact) + + return &jwt, nil +} + +func (ap *oauth2ClientCredentialsAuthPlugin) mapKMSAlgToSign(alg string) (string, error) { + switch alg { + case "ECDSA_SHA_256": + return "ES256", nil + case "ECDSA_SHA_384": + return "ES384", nil + case "ECDSA_SHA_512": + return "ES512", nil + default: + return "", fmt.Errorf("unsupported sign algorithm %s", alg) + } +} + +// SignWithKMS will sign the JWT in AWS using the key stored in the supplied kmsArn +func (ap *oauth2ClientCredentialsAuthPlugin) SignWithKMS(ctx context.Context, payload []byte, hdrBuf []byte) ([]byte, error) { + + encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf) + encodedPayload := base64.RawURLEncoding.EncodeToString(payload) + input := strings.Join( + []string{ + encodedHdr, + encodedPayload, + }, ".", + ) + digest, err := messageDigest([]byte(input), ap.AWSKmsKey.Algorithm) + if err != nil { + return nil, err + } + if ap.AWSSigningPlugin != nil { + signature, err := ap.AWSSigningPlugin.SignDigest(ctx, digest, ap.AWSKmsKey.Name, ap.AWSKmsKey.Algorithm) + if err != nil { + return nil, err + } + der, err := base64.StdEncoding.DecodeString(signature) + if err != nil { + return nil, err + } + signatureData, err := convertSignatureToBase64(ap.AWSKmsKey.Algorithm, der) + if err != nil { + return nil, err + } + + signedAssertion := input + "." + signatureData + + return []byte(signedAssertion), nil + } + return nil, errors.New("missing AWS credentials, failed to sign the assertion with kms") +} + +func (ap *oauth2ClientCredentialsAuthPlugin) parseSigningKey(c Config) (err error) { + if ap.SigningKeyID == "" { + return errors.New("signing_key required for jwt_bearer grant type") + } + + if val, ok := c.keys[ap.SigningKeyID]; ok { + if val.PrivateKey == "" { + return errors.New("referenced signing_key does not include a private key") + } + ap.signingKey = val + } else { + return errors.New("signing_key refers to non-existent key") + } + + alg := jwa.SignatureAlgorithm(ap.signingKey.Algorithm) + ap.signingKeyParsed, err = sign.GetSigningKey(ap.signingKey.PrivateKey, alg) + if err != nil { + return err + } + + return nil +} + +func (ap *oauth2ClientCredentialsAuthPlugin) NewClient(c Config) (*http.Client, error) { + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + if ap.GrantType == "" { + // Use client_credentials as default to not break existing config + ap.GrantType = grantTypeClientCredentials + } else if ap.GrantType != grantTypeClientCredentials && ap.GrantType != grantTypeJwtBearer { + return nil, errors.New("grant_type must be either client_credentials or jwt_bearer") + } + + if ap.GrantType == grantTypeJwtBearer || (ap.GrantType == grantTypeClientCredentials && ap.SigningKeyID != "") { + if err = ap.parseSigningKey(c); err != nil { + return nil, err + } + } + + // Inherit skip verify from the "parent" settings. Should this be configurable on the credentials too? + ap.tlsSkipVerify = c.AllowInsecureTLS + + ap.logger = c.logger + + if !strings.HasPrefix(ap.TokenURL, "https://") { + return nil, errors.New("token_url required to use https scheme") + } + if ap.GrantType == grantTypeClientCredentials { + if ap.AWSKmsKey != nil && (ap.ClientSecret != "" || ap.SigningKeyID != "") || + (ap.ClientSecret != "" && ap.SigningKeyID != "") { + return nil, errors.New("can only use one of client_secret, signing_key or signing_kms_key for client_credentials") + } + if ap.SigningKeyID == "" && ap.AWSKmsKey == nil && (ap.ClientID == "" || ap.ClientSecret == "") { + return nil, errors.New("client_id and client_secret required") + } + if ap.AWSKmsKey != nil { + if ap.AWSSigningPlugin == nil { + return nil, errors.New("aws_kms and aws_signing required") + } + // initialize the awsSigningAuthPlugin + _, err = ap.AWSSigningPlugin.NewClient(c) + if err != nil { + return nil, err + } + } + } + + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +// requestToken tries to obtain an access token using either the client credentials flow +// https://tools.ietf.org/html/rfc6749#section-4.4 +// or the JWT authorization grant +// https://tools.ietf.org/html/rfc7523 +func (ap *oauth2ClientCredentialsAuthPlugin) requestToken(ctx context.Context) (*oauth2Token, error) { + body := url.Values{} + if ap.GrantType == grantTypeJwtBearer { + authJwt, err := ap.createAuthJWT(ctx, ap.Claims, ap.signingKeyParsed) + if err != nil { + return nil, err + } + body.Add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer") + body.Add("assertion", *authJwt) + } else { + body.Add("grant_type", grantTypeClientCredentials) + + if ap.SigningKeyID != "" || ap.AWSKmsKey != nil { + authJwt, err := ap.createAuthJWT(ctx, ap.Claims, ap.signingKeyParsed) + if err != nil { + return nil, err + } + body.Add("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + body.Add("client_assertion", *authJwt) + + if ap.ClientID != "" { + body.Add("client_id", ap.ClientID) + } + } + } + + if len(ap.Scopes) > 0 { + body.Add("scope", strings.Join(ap.Scopes, " ")) + } + + for k, v := range ap.AdditionalParameters { + body.Set(k, v) + } + + r, err := http.NewRequestWithContext(ctx, "POST", ap.TokenURL, strings.NewReader(body.Encode())) + if err != nil { + return nil, err + } + r.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + if ap.GrantType == grantTypeClientCredentials && ap.ClientSecret != "" { + r.SetBasicAuth(ap.ClientID, ap.ClientSecret) + } + + for k, v := range ap.AdditionalHeaders { + r.Header.Add(k, v) + } + + client := DefaultRoundTripperClient(&tls.Config{InsecureSkipVerify: ap.tlsSkipVerify}, 10) + response, err := client.Do(r) + if err != nil { + return nil, err + } + + bodyRaw, err := io.ReadAll(response.Body) + if err != nil { + return nil, err + } + + if response.StatusCode != 200 { + return nil, fmt.Errorf("error in response from OAuth2 token endpoint: %v", string(bodyRaw)) + } + + var tokenResponse tokenEndpointResponse + err = json.Unmarshal(bodyRaw, &tokenResponse) + if err != nil { + return nil, err + } + + if strings.ToLower(tokenResponse.TokenType) != "bearer" { + return nil, errors.New("unknown token type returned from token endpoint") + } + + return &oauth2Token{ + Token: strings.TrimSpace(tokenResponse.AccessToken), + ExpiresAt: time.Now().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second), + }, nil +} + +func (ap *oauth2ClientCredentialsAuthPlugin) Prepare(req *http.Request) error { + minTokenLifetime := float64(10) + if ap.tokenCache == nil || time.Until(ap.tokenCache.ExpiresAt).Seconds() < minTokenLifetime { + ap.logger.Debug("Requesting token from token_url %v", ap.TokenURL) + token, err := ap.requestToken(req.Context()) + if err != nil { + return err + } + ap.tokenCache = token + } + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", ap.tokenCache.Token)) + return nil +} + +// clientTLSAuthPlugin represents authentication via client certificate on a TLS connection +type clientTLSAuthPlugin struct { + Cert string `json:"cert"` + PrivateKey string `json:"private_key"` + PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"` + CACert string `json:"ca_cert,omitempty"` // Deprecated: Use `services[_].tls.ca_cert` instead + SystemCARequired bool `json:"system_ca_required,omitempty"` // Deprecated: Use `services[_].tls.system_ca_required` instead +} + +func (ap *clientTLSAuthPlugin) NewClient(c Config) (*http.Client, error) { + tlsConfig, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + if ap.Cert == "" { + return nil, errors.New("client certificate is needed when client TLS is enabled") + } + if ap.PrivateKey == "" { + return nil, errors.New("private key is needed when client TLS is enabled") + } + + var keyPEMBlock []byte + data, err := os.ReadFile(ap.PrivateKey) + if err != nil { + return nil, err + } + + block, _ := pem.Decode(data) + if block == nil { + return nil, errors.New("PEM data could not be found") + } + + // nolint: staticcheck // We don't want to forbid users from using this encryption. + if x509.IsEncryptedPEMBlock(block) { + if ap.PrivateKeyPassphrase == "" { + return nil, errors.New("client certificate passphrase is needed, because the certificate is password encrypted") + } + // nolint: staticcheck // We don't want to forbid users from using this encryption. + block, err := x509.DecryptPEMBlock(block, []byte(ap.PrivateKeyPassphrase)) + if err != nil { + return nil, err + } + key, err := x509.ParsePKCS8PrivateKey(block) + if err != nil { + key, err = x509.ParsePKCS1PrivateKey(block) + if err != nil { + return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err) + } + } + rsa, ok := key.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("private key is invalid") + } + keyPEMBlock = pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(rsa), + }, + ) + } else { + keyPEMBlock = data + } + + certPEMBlock, err := os.ReadFile(ap.Cert) + if err != nil { + return nil, err + } + + cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) + if err != nil { + return nil, err + } + tlsConfig.Certificates = []tls.Certificate{cert} + + var client *http.Client + + if c.TLS != nil && c.TLS.CACert != "" { + client = DefaultRoundTripperClient(tlsConfig, *c.ResponseHeaderTimeoutSeconds) + } else { + if ap.CACert != "" { + c.logger.Warn("Deprecated 'services[_].credentials.client_tls.ca_cert' configuration specified. Use 'services[_].tls.ca_cert' instead. See https://www.openpolicyagent.org/docs/latest/configuration/#services") + caCert, err := os.ReadFile(ap.CACert) + if err != nil { + return nil, err + } + + var caCertPool *x509.CertPool + if ap.SystemCARequired { + caCertPool, err = x509.SystemCertPool() + if err != nil { + return nil, err + } + } else { + caCertPool = x509.NewCertPool() + } + + ok := caCertPool.AppendCertsFromPEM(caCert) + if !ok { + return nil, errors.New("unable to parse and append CA certificate to certificate pool") + } + tlsConfig.RootCAs = caCertPool + } + + client = DefaultRoundTripperClient(tlsConfig, *c.ResponseHeaderTimeoutSeconds) + } + + return client, nil +} + +func (ap *clientTLSAuthPlugin) Prepare(req *http.Request) error { + return nil +} + +// awsSigningAuthPlugin represents authentication using AWS V4 HMAC signing in the Authorization header +type awsSigningAuthPlugin struct { + AWSEnvironmentCredentials *awsEnvironmentCredentialService `json:"environment_credentials,omitempty"` + AWSMetadataCredentials *awsMetadataCredentialService `json:"metadata_credentials,omitempty"` + AWSWebIdentityCredentials *awsWebIdentityCredentialService `json:"web_identity_credentials,omitempty"` + AWSProfileCredentials *awsProfileCredentialService `json:"profile_credentials,omitempty"` + + AWSService string `json:"service,omitempty"` + AWSSignatureVersion string `json:"signature_version,omitempty"` + + ecrAuthPlugin *ecrAuthPlugin + kmsSignPlugin *awsKMSSignPlugin + + logger logging.Logger +} + +type awsCredentialServiceChain struct { + awsCredentialServices []awsCredentialService + logger logging.Logger +} + +func (acs *awsCredentialServiceChain) addService(service awsCredentialService) { + acs.awsCredentialServices = append(acs.awsCredentialServices, service) +} + +type awsCredentialCheckErrors []*awsCredentialCheckError + +func (e awsCredentialCheckErrors) Error() string { + + if len(e) == 0 { + return "no error(s)" + } + + if len(e) == 1 { + return fmt.Sprintf("1 error occurred: %v", e[0].Error()) + } + + s := make([]string, len(e)) + for i, err := range e { + s[i] = err.Error() + } + + return fmt.Sprintf("%d errors occurred:\n%s", len(e), strings.Join(s, "\n")) +} + +type awsCredentialCheckError struct { + message string +} + +func newAWSCredentialError(message string) *awsCredentialCheckError { + return &awsCredentialCheckError{ + message: message, + } +} + +func (e *awsCredentialCheckError) Error() string { + return e.message +} + +func (acs *awsCredentialServiceChain) credentials(ctx context.Context) (aws.Credentials, error) { + var errs awsCredentialCheckErrors + + for _, service := range acs.awsCredentialServices { + credential, err := service.credentials(ctx) + if err != nil { + acs.logger.Debug("awsSigningAuthPlugin:%T failed: %v", service, err) + + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return aws.Credentials{}, err + } + + errs = append(errs, newAWSCredentialError(err.Error())) + continue + } + + acs.logger.Debug("awsSigningAuthPlugin:%T successful", service) + return credential, nil + } + + return aws.Credentials{}, fmt.Errorf("all AWS credential providers failed: %v", errs) +} + +func (ap *awsSigningAuthPlugin) awsCredentialService() awsCredentialService { + chain := awsCredentialServiceChain{ + logger: ap.logger, + } + + /* + Here we maintain the order of addition to the chain inline with + the order of credential providers followed by default by the + AWS SDK. For example + + https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html + */ + + if ap.AWSEnvironmentCredentials != nil { + ap.AWSEnvironmentCredentials.logger = ap.logger + chain.addService(ap.AWSEnvironmentCredentials) + } + + if ap.AWSWebIdentityCredentials != nil { + ap.AWSWebIdentityCredentials.logger = ap.logger + chain.addService(ap.AWSWebIdentityCredentials) + } + + if ap.AWSProfileCredentials != nil { + ap.AWSProfileCredentials.logger = ap.logger + chain.addService(ap.AWSProfileCredentials) + } + + if ap.AWSMetadataCredentials != nil { + ap.AWSMetadataCredentials.logger = ap.logger + chain.addService(ap.AWSMetadataCredentials) + } + + return &chain +} + +func (ap *awsSigningAuthPlugin) NewClient(c Config) (*http.Client, error) { + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + if ap.logger == nil { + ap.logger = c.logger + } + + if err := ap.validateAndSetDefaults(c.Type); err != nil { + return nil, err + } + + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +func (ap *awsSigningAuthPlugin) Prepare(req *http.Request) error { + switch ap.AWSService { + case "ecr": + return ap.ecrAuthPlugin.Prepare(req) + default: + creds, err := ap.awsCredentialService().credentials(req.Context()) + if err != nil { + return fmt.Errorf("failed to get aws credentials: %w", err) + } + + ap.logger.Debug("Signing request with AWS credentials.") + + return aws.SignRequest(req, ap.AWSService, creds, time.Now(), ap.AWSSignatureVersion) + } +} + +func (ap *awsSigningAuthPlugin) validateAndSetDefaults(serviceType string) error { + cfgs := map[bool]int{} + cfgs[ap.AWSEnvironmentCredentials != nil]++ + cfgs[ap.AWSMetadataCredentials != nil]++ + cfgs[ap.AWSWebIdentityCredentials != nil]++ + cfgs[ap.AWSProfileCredentials != nil]++ + + if cfgs[true] == 0 { + return errors.New("a AWS credential service must be specified when S3 signing is enabled") + } + + if ap.AWSMetadataCredentials != nil { + if ap.AWSMetadataCredentials.RegionName == "" { + return errors.New("at least aws_region must be specified for AWS metadata credential service") + } + } + + if ap.AWSWebIdentityCredentials != nil { + if err := ap.AWSWebIdentityCredentials.populateFromEnv(); err != nil { + return err + } + } + + ap.AWSService = strings.ToLower(ap.AWSService) + + // Only allow ECR for OCI service types + if serviceType == "oci" { + if ap.AWSService == "" { + ap.AWSService = "ecr" + } + + if ap.AWSService != "ecr" { + return fmt.Errorf(`cannot use aws service %q with service type "oci"`, ap.AWSService) + } + + // We need to setup a special auth plugin for ECR. + ap.ecrAuthPlugin = newECRAuthPlugin(ap) + } else { + // Disallow ECR for non-OCI service types + if ap.AWSService == "ecr" { + return errors.New(`aws service "ecr" must be used with service type "oci"`) + } + if ap.AWSService == "kms" && ap.kmsSignPlugin == nil { + // We need a special plugin for KMS. + ap.kmsSignPlugin = newKMSSignPlugin(ap) + } + if ap.AWSService == "" { + ap.AWSService = awsSigv4SigningDefaultService + } + } + + if ap.AWSSignatureVersion == "" { + ap.AWSSignatureVersion = "4" + } + + return nil +} + +func (ap *awsSigningAuthPlugin) SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string) (string, error) { + switch ap.AWSService { + case "kms": + return ap.kmsSignPlugin.SignDigest(ctx, digest, keyID, signingAlgorithm) + default: + return "", fmt.Errorf(`cannot use SignDigest with aws service %q`, ap.AWSService) + } +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go b/vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go new file mode 100644 index 00000000000..3e78b1fad21 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/rest/aws.go @@ -0,0 +1,557 @@ +// Copyright 2019 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package rest + +import ( + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + "time" + + "github.com/go-ini/ini" + "github.com/open-policy-agent/opa/internal/providers/aws" + "github.com/open-policy-agent/opa/logging" +) + +const ( + // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html + ec2DefaultCredServicePath = "http://169.254.169.254/latest/meta-data/iam/security-credentials/" + + // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html + ec2DefaultTokenPath = "http://169.254.169.254/latest/api/token" + + // ref. https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html + ecsDefaultCredServicePath = "http://169.254.170.2" + ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" + + // ref. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html + stsDefaultDomain = "amazonaws.com" + stsDefaultPath = "https://sts.%s" + stsRegionPath = "https://sts.%s.%s" + + // ref. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html + accessKeyEnvVar = "AWS_ACCESS_KEY_ID" + secretKeyEnvVar = "AWS_SECRET_ACCESS_KEY" + securityTokenEnvVar = "AWS_SECURITY_TOKEN" + sessionTokenEnvVar = "AWS_SESSION_TOKEN" + awsRegionEnvVar = "AWS_REGION" + awsDomainEnvVar = "AWS_DOMAIN" + awsRoleArnEnvVar = "AWS_ROLE_ARN" + awsWebIdentityTokenFileEnvVar = "AWS_WEB_IDENTITY_TOKEN_FILE" + awsCredentialsFileEnvVar = "AWS_SHARED_CREDENTIALS_FILE" + awsProfileEnvVar = "AWS_PROFILE" + + // ref. https://docs.aws.amazon.com/sdkref/latest/guide/settings-global.html + accessKeyGlobalSetting = "aws_access_key_id" + secretKeyGlobalSetting = "aws_secret_access_key" + securityTokenGlobalSetting = "aws_session_token" +) + +// awsCredentialService represents the interface for AWS credential providers +type awsCredentialService interface { + credentials(context.Context) (aws.Credentials, error) +} + +// awsEnvironmentCredentialService represents an static environment-variable credential provider for AWS +type awsEnvironmentCredentialService struct { + logger logging.Logger +} + +func (cs *awsEnvironmentCredentialService) credentials(context.Context) (aws.Credentials, error) { + var creds aws.Credentials + creds.AccessKey = os.Getenv(accessKeyEnvVar) + if creds.AccessKey == "" { + return creds, errors.New("no " + accessKeyEnvVar + " set in environment") + } + creds.SecretKey = os.Getenv(secretKeyEnvVar) + if creds.SecretKey == "" { + return creds, errors.New("no " + secretKeyEnvVar + " set in environment") + } + creds.RegionName = os.Getenv(awsRegionEnvVar) + if creds.RegionName == "" { + return creds, errors.New("no " + awsRegionEnvVar + " set in environment") + } + // SessionToken is required if using temporary ENV credentials from assumed IAM role + // Missing SessionToken results with 403 s3 error. + creds.SessionToken = os.Getenv(sessionTokenEnvVar) + if creds.SessionToken == "" { + // In case of missing SessionToken try to get SecurityToken + // AWS switched to use SessionToken, but SecurityToken was left for backward compatibility + creds.SessionToken = os.Getenv(securityTokenEnvVar) + } + + return creds, nil +} + +// awsProfileCredentialService represents a credential provider for AWS that extracts credentials from the AWS +// credentials file +type awsProfileCredentialService struct { + + // Path to the credentials file. + // + // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the + // env value is empty will default to current user's home directory. + // Linux/OSX: "$HOME/.aws/credentials" + // Windows: "%USERPROFILE%\.aws\credentials" + Path string `json:"path,omitempty"` + + // AWS Profile to extract credentials from the credentials file. If empty + // will default to environment variable "AWS_PROFILE" or "default" if + // environment variable is also not set. + Profile string `json:"profile,omitempty"` + + RegionName string `json:"aws_region"` + + logger logging.Logger +} + +func (cs *awsProfileCredentialService) credentials(context.Context) (aws.Credentials, error) { + var creds aws.Credentials + + filename, err := cs.path() + if err != nil { + return creds, err + } + + cfg, err := ini.Load(filename) + if err != nil { + return creds, fmt.Errorf("failed to read credentials file: %v", err) + } + + profile, err := cfg.GetSection(cs.profile()) + if err != nil { + return creds, fmt.Errorf("failed to get profile: %v", err) + } + + creds.AccessKey = profile.Key(accessKeyGlobalSetting).String() + if creds.AccessKey == "" { + return creds, fmt.Errorf("profile \"%v\" in credentials file %v does not contain \"%v\"", cs.Profile, cs.Path, accessKeyGlobalSetting) + } + + creds.SecretKey = profile.Key(secretKeyGlobalSetting).String() + if creds.SecretKey == "" { + return creds, fmt.Errorf("profile \"%v\" in credentials file %v does not contain \"%v\"", cs.Profile, cs.Path, secretKeyGlobalSetting) + } + + creds.SessionToken = profile.Key(securityTokenGlobalSetting).String() // default to empty string + + if cs.RegionName == "" { + if cs.RegionName = os.Getenv(awsRegionEnvVar); cs.RegionName == "" { + return creds, errors.New("no " + awsRegionEnvVar + " set in environment or configuration") + } + } + creds.RegionName = cs.RegionName + + return creds, nil +} + +func (cs *awsProfileCredentialService) path() (string, error) { + if len(cs.Path) != 0 { + return cs.Path, nil + } + + if cs.Path = os.Getenv(awsCredentialsFileEnvVar); len(cs.Path) != 0 { + return cs.Path, nil + } + + homeDir, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("user home directory not found: %w", err) + } + + cs.Path = filepath.Join(homeDir, ".aws", "credentials") + + return cs.Path, nil +} + +func (cs *awsProfileCredentialService) profile() string { + if cs.Profile != "" { + return cs.Profile + } + + cs.Profile = os.Getenv(awsProfileEnvVar) + + if cs.Profile == "" { + cs.Profile = "default" + } + + return cs.Profile +} + +// awsMetadataCredentialService represents an EC2 metadata service credential provider for AWS +type awsMetadataCredentialService struct { + RoleName string `json:"iam_role,omitempty"` + RegionName string `json:"aws_region"` + creds aws.Credentials + expiration time.Time + credServicePath string + tokenPath string + logger logging.Logger +} + +func (cs *awsMetadataCredentialService) urlForMetadataService() (string, error) { + // override default path for testing + if cs.credServicePath != "" { + return cs.credServicePath + cs.RoleName, nil + } + // otherwise, normal flow + // if a role name is provided, look up via the EC2 credential service + if cs.RoleName != "" { + return ec2DefaultCredServicePath + cs.RoleName, nil + } + // otherwise, check environment to see if it looks like we're in an ECS + // container (with implied role association) + if isECS() { + return ecsDefaultCredServicePath + os.Getenv(ecsRelativePathEnvVar), nil + } + // if there's no role name and we don't appear to have a path to the + // ECS container service, then the configuration is invalid + return "", errors.New("metadata endpoint cannot be determined from settings and environment") +} + +func (cs *awsMetadataCredentialService) tokenRequest(ctx context.Context) (*http.Request, error) { + tokenURL := ec2DefaultTokenPath + if cs.tokenPath != "" { + // override for testing + tokenURL = cs.tokenPath + } + req, err := http.NewRequestWithContext(ctx, http.MethodPut, tokenURL, nil) + if err != nil { + return nil, err + } + + // we are going to use the token in the immediate future, so a long TTL is not necessary + req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "60") + return req, nil +} + +func (cs *awsMetadataCredentialService) refreshFromService(ctx context.Context) error { + // define the expected JSON payload from the EC2 credential service + // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html + type metadataPayload struct { + Code string + AccessKeyID string `json:"AccessKeyId"` + SecretAccessKey string + Token string + Expiration time.Time + } + + // Short circuit if a reasonable amount of time until credential expiration remains + const tokenExpirationMargin = 5 * time.Minute + + if time.Now().Add(tokenExpirationMargin).Before(cs.expiration) { + cs.logger.Debug("Credentials previously obtained from metadata service still valid.") + return nil + } + + cs.logger.Debug("Obtaining credentials from metadata service.") + metaDataURL, err := cs.urlForMetadataService() + if err != nil { + // configuration issue or missing ECS environment + return err + } + + // construct an HTTP client with a reasonably short timeout + client := &http.Client{Timeout: time.Second * 10} + req, err := http.NewRequestWithContext(ctx, http.MethodGet, metaDataURL, nil) + if err != nil { + return errors.New("unable to construct metadata HTTP request: " + err.Error()) + } + + // if in the EC2 environment, we will use IMDSv2, which requires a session cookie from a + // PUT request on the token endpoint before it will give the credentials, this provides + // protection from SSRF attacks + if !isECS() { + tokenReq, err := cs.tokenRequest(ctx) + if err != nil { + return errors.New("unable to construct metadata token HTTP request: " + err.Error()) + } + body, err := aws.DoRequestWithClient(tokenReq, client, "metadata token", cs.logger) + if err != nil { + return err + } + // token is the body of response; add to header of metadata request + req.Header.Set("X-aws-ec2-metadata-token", string(body)) + } + + body, err := aws.DoRequestWithClient(req, client, "metadata", cs.logger) + if err != nil { + return err + } + + var payload metadataPayload + err = json.Unmarshal(body, &payload) + if err != nil { + return errors.New("failed to parse credential response from metadata service: " + err.Error()) + } + + // Only the EC2 endpoint returns the "Code" element which indicates whether the query was + // successful; the ECS endpoint does not! Some other fields are missing in the ECS payload + // but we do not depend on them. + if cs.RoleName != "" && payload.Code != "Success" { + return errors.New("metadata service query did not succeed: " + payload.Code) + } + + cs.expiration = payload.Expiration + cs.creds.AccessKey = payload.AccessKeyID + cs.creds.SecretKey = payload.SecretAccessKey + cs.creds.SessionToken = payload.Token + cs.creds.RegionName = cs.RegionName + + return nil +} + +func (cs *awsMetadataCredentialService) credentials(ctx context.Context) (aws.Credentials, error) { + err := cs.refreshFromService(ctx) + if err != nil { + return cs.creds, err + } + return cs.creds, nil +} + +// awsWebIdentityCredentialService represents an STS WebIdentity credential services +type awsWebIdentityCredentialService struct { + RoleArn string + WebIdentityTokenFile string + RegionName string `json:"aws_region"` + SessionName string `json:"session_name"` + Domain string `json:"aws_domain"` + stsURL string + creds aws.Credentials + expiration time.Time + logger logging.Logger +} + +func (cs *awsWebIdentityCredentialService) populateFromEnv() error { + cs.RoleArn = os.Getenv(awsRoleArnEnvVar) + if cs.RoleArn == "" { + return errors.New("no " + awsRoleArnEnvVar + " set in environment") + } + cs.WebIdentityTokenFile = os.Getenv(awsWebIdentityTokenFileEnvVar) + if cs.WebIdentityTokenFile == "" { + return errors.New("no " + awsWebIdentityTokenFileEnvVar + " set in environment") + } + + if cs.Domain == "" { + cs.Domain = os.Getenv(awsDomainEnvVar) + } + + if cs.RegionName == "" { + if cs.RegionName = os.Getenv(awsRegionEnvVar); cs.RegionName == "" { + return errors.New("no " + awsRegionEnvVar + " set in environment or configuration") + } + } + return nil +} + +func (cs *awsWebIdentityCredentialService) stsPath() string { + var domain string + if cs.Domain != "" { + domain = strings.ToLower(cs.Domain) + } else { + domain = stsDefaultDomain + } + + var stsPath string + switch { + case cs.stsURL != "": + stsPath = cs.stsURL + case cs.RegionName != "": + stsPath = fmt.Sprintf(stsRegionPath, strings.ToLower(cs.RegionName), domain) + default: + stsPath = fmt.Sprintf(stsDefaultPath, domain) + } + return stsPath +} + +func (cs *awsWebIdentityCredentialService) refreshFromService(ctx context.Context) error { + // define the expected JSON payload from the EC2 credential service + // ref. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html + type responsePayload struct { + Result struct { + Credentials struct { + SessionToken string + SecretAccessKey string + Expiration time.Time + AccessKeyID string `xml:"AccessKeyId"` + } + } `xml:"AssumeRoleWithWebIdentityResult"` + } + + // short circuit if a reasonable amount of time until credential expiration remains + if time.Now().Add(time.Minute * 5).Before(cs.expiration) { + cs.logger.Debug("Credentials previously obtained from sts service still valid.") + return nil + } + + cs.logger.Debug("Obtaining credentials from sts for role %s.", cs.RoleArn) + + var sessionName string + if cs.SessionName == "" { + sessionName = "open-policy-agent" + } else { + sessionName = cs.SessionName + } + + tokenData, err := os.ReadFile(cs.WebIdentityTokenFile) + if err != nil { + return errors.New("unable to read web token for sts HTTP request: " + err.Error()) + } + + token := string(tokenData) + + queryVals := url.Values{ + "Action": []string{"AssumeRoleWithWebIdentity"}, + "RoleSessionName": []string{sessionName}, + "RoleArn": []string{cs.RoleArn}, + "WebIdentityToken": []string{token}, + "Version": []string{"2011-06-15"}, + } + stsRequestURL, _ := url.Parse(cs.stsPath()) + + // construct an HTTP client with a reasonably short timeout + client := &http.Client{Timeout: time.Second * 10} + req, err := http.NewRequestWithContext(ctx, http.MethodPost, stsRequestURL.String(), strings.NewReader(queryVals.Encode())) + if err != nil { + return errors.New("unable to construct STS HTTP request: " + err.Error()) + } + + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + body, err := aws.DoRequestWithClient(req, client, "STS", cs.logger) + if err != nil { + return err + } + + var payload responsePayload + err = xml.Unmarshal(body, &payload) + if err != nil { + return errors.New("failed to parse credential response from STS service: " + err.Error()) + } + + cs.expiration = payload.Result.Credentials.Expiration + cs.creds.AccessKey = payload.Result.Credentials.AccessKeyID + cs.creds.SecretKey = payload.Result.Credentials.SecretAccessKey + cs.creds.SessionToken = payload.Result.Credentials.SessionToken + cs.creds.RegionName = cs.RegionName + + return nil +} + +func (cs *awsWebIdentityCredentialService) credentials(ctx context.Context) (aws.Credentials, error) { + err := cs.refreshFromService(ctx) + if err != nil { + return cs.creds, err + } + return cs.creds, nil +} + +func isECS() bool { + // the special relative path URI is set by the container agent in the ECS environment only + _, isECS := os.LookupEnv(ecsRelativePathEnvVar) + return isECS +} + +// ecrAuthPlugin authorizes requests to AWS ECR. +type ecrAuthPlugin struct { + token aws.ECRAuthorizationToken + + // awsAuthPlugin is used to sign ecr authorization token requests. + awsAuthPlugin *awsSigningAuthPlugin + + // ecr represents the service we request tokens from. + ecr ecr + + logger logging.Logger +} + +type ecr interface { + GetAuthorizationToken(context.Context, aws.Credentials, string) (aws.ECRAuthorizationToken, error) +} + +func newECRAuthPlugin(ap *awsSigningAuthPlugin) *ecrAuthPlugin { + return &ecrAuthPlugin{ + awsAuthPlugin: ap, + ecr: aws.NewECR(ap.logger), + logger: ap.logger, + } +} + +// Prepare should be called with any request to AWS ECR. +// It takes care of retrieving an ECR authorization token to sign +// the request with. +func (ap *ecrAuthPlugin) Prepare(r *http.Request) error { + if !ap.token.IsValid() { + ap.logger.Debug("Refreshing ECR auth token") + if err := ap.refreshAuthorizationToken(r.Context()); err != nil { + return err + } + } + + ap.logger.Debug("Signing request with ECR authorization token") + + r.Header.Set("Authorization", fmt.Sprintf("Basic %s", ap.token.AuthorizationToken)) + return nil +} + +func (ap *ecrAuthPlugin) refreshAuthorizationToken(ctx context.Context) error { + creds, err := ap.awsAuthPlugin.awsCredentialService().credentials(ctx) + if err != nil { + return fmt.Errorf("failed to get aws credentials: %w", err) + } + + token, err := ap.ecr.GetAuthorizationToken(ctx, creds, ap.awsAuthPlugin.AWSSignatureVersion) + if err != nil { + return fmt.Errorf("ecr: failed to get authorization token: %w", err) + } + + ap.token = token + return nil +} + +// awsKMSSignPlugin signs digests using AWS KMS. +type awsKMSSignPlugin struct { + + // awsAuthPlugin is used to sign kms sign requests. + awsAuthPlugin *awsSigningAuthPlugin + + // kms represents the service for signing digests. + kms awskms + + logger logging.Logger +} + +type awskms interface { + SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string, creds aws.Credentials, signatureVersion string) (string, error) +} + +func newKMSSignPlugin(ap *awsSigningAuthPlugin) *awsKMSSignPlugin { + return &awsKMSSignPlugin{ + awsAuthPlugin: ap, + kms: aws.NewKMS(ap.logger), + logger: ap.logger, + } +} + +func (ap *awsKMSSignPlugin) SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string) (string, error) { + creds, err := ap.awsAuthPlugin.awsCredentialService().credentials(ctx) + if err != nil { + return "", fmt.Errorf("failed to get aws credentials: %w", err) + } + + signature, err := ap.kms.SignDigest(ctx, digest, keyID, signingAlgorithm, creds, ap.awsAuthPlugin.AWSSignatureVersion) + if err != nil { + return "", fmt.Errorf("kms: failed to sign digest: %w", err) + } + + return signature, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/azure.go b/vendor/github.com/open-policy-agent/opa/plugins/rest/azure.go new file mode 100644 index 00000000000..6a85dea6816 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/rest/azure.go @@ -0,0 +1,157 @@ +package rest + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "time" +) + +var ( + azureIMDSEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" + defaultAPIVersion = "2018-02-01" + defaultResource = "https://storage.azure.com/" + timeout = 5 * time.Second +) + +// azureManagedIdentitiesToken holds a token for managed identities for Azure resources +type azureManagedIdentitiesToken struct { + AccessToken string `json:"access_token"` + ExpiresIn string `json:"expires_in"` + ExpiresOn string `json:"expires_on"` + NotBefore string `json:"not_before"` + Resource string `json:"resource"` + TokenType string `json:"token_type"` +} + +// azureManagedIdentitiesError represents an error fetching an azureManagedIdentitiesToken +type azureManagedIdentitiesError struct { + Err string `json:"error"` + Description string `json:"error_description"` + Endpoint string + StatusCode int +} + +func (e *azureManagedIdentitiesError) Error() string { + return fmt.Sprintf("%v %s retrieving azure token from %s: %s", e.StatusCode, e.Err, e.Endpoint, e.Description) +} + +// azureManagedIdentitiesAuthPlugin uses an azureManagedIdentitiesToken.AccessToken for bearer authorization +type azureManagedIdentitiesAuthPlugin struct { + Endpoint string `json:"endpoint"` + APIVersion string `json:"api_version"` + Resource string `json:"resource"` + ObjectID string `json:"object_id"` + ClientID string `json:"client_id"` + MiResID string `json:"mi_res_id"` +} + +func (ap *azureManagedIdentitiesAuthPlugin) NewClient(c Config) (*http.Client, error) { + if c.Type == "oci" { + return nil, errors.New("azure managed identities auth: OCI service not supported") + } + + if ap.Endpoint == "" { + ap.Endpoint = azureIMDSEndpoint + } + + if ap.Resource == "" { + ap.Resource = defaultResource + } + + if ap.APIVersion == "" { + ap.APIVersion = defaultAPIVersion + } + + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +func (ap *azureManagedIdentitiesAuthPlugin) Prepare(req *http.Request) error { + token, err := azureManagedIdentitiesTokenRequest( + ap.Endpoint, ap.APIVersion, ap.Resource, + ap.ObjectID, ap.ClientID, ap.MiResID, + ) + if err != nil { + return err + } + + req.Header.Add("Authorization", "Bearer "+token.AccessToken) + return nil +} + +// azureManagedIdentitiesTokenRequest fetches an azureManagedIdentitiesToken +func azureManagedIdentitiesTokenRequest( + endpoint, apiVersion, resource, objectID, clientID, miResID string, +) (azureManagedIdentitiesToken, error) { + var token azureManagedIdentitiesToken + e := buildAzureManagedIdentitiesRequestPath(endpoint, apiVersion, resource, objectID, clientID, miResID) + + request, err := http.NewRequest("GET", e, nil) + if err != nil { + return token, err + } + request.Header.Add("Metadata", "true") + + httpClient := http.Client{Timeout: timeout} + response, err := httpClient.Do(request) + if err != nil { + return token, err + } + defer response.Body.Close() + + data, err := io.ReadAll(response.Body) + if err != nil { + return token, err + } + + if s := response.StatusCode; s != http.StatusOK { + var azureError azureManagedIdentitiesError + err = json.Unmarshal(data, &azureError) + if err != nil { + return token, err + } + + azureError.Endpoint = e + azureError.StatusCode = s + return token, &azureError + } + + err = json.Unmarshal(data, &token) + if err != nil { + return token, err + } + + return token, nil +} + +// buildAzureManagedIdentitiesRequestPath constructs the request URL for an Azure managed identities token request +func buildAzureManagedIdentitiesRequestPath( + endpoint, apiVersion, resource, objectID, clientID, miResID string, +) string { + params := url.Values{ + "api-version": []string{apiVersion}, + "resource": []string{resource}, + } + + if objectID != "" { + params.Add("object_id", objectID) + } + + if clientID != "" { + params.Add("client_id", clientID) + } + + if miResID != "" { + params.Add("mi_res_id", miResID) + } + + return endpoint + "?" + params.Encode() +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go b/vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go new file mode 100644 index 00000000000..c717105c7f3 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/rest/gcp.go @@ -0,0 +1,173 @@ +// Copyright 2020 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package rest + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "strings" + "time" +) + +var ( + defaultGCPMetadataEndpoint = "http://metadata.google.internal" + defaultAccessTokenPath = "/computeMetadata/v1/instance/service-accounts/default/token" + defaultIdentityTokenPath = "/computeMetadata/v1/instance/service-accounts/default/identity" +) + +// AccessToken holds a GCP access token. +type AccessToken struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + TokenType string `json:"token_type"` +} + +type gcpMetadataError struct { + err error + endpoint string + statusCode int +} + +func (e *gcpMetadataError) Error() string { + return fmt.Sprintf("error retrieving gcp ID token from %s %d: %v", e.endpoint, e.statusCode, e.err) +} + +func (e *gcpMetadataError) Unwrap() error { return e.err } + +var ( + errGCPMetadataNotFound = errors.New("not found") + errGCPMetadataInvalidRequest = errors.New("invalid request") + errGCPMetadataUnexpected = errors.New("unexpected error") +) + +// gcpMetadataAuthPlugin represents authentication via GCP metadata service. +type gcpMetadataAuthPlugin struct { + AccessTokenPath string `json:"access_token_path"` + Audience string `json:"audience"` + Endpoint string `json:"endpoint"` + IdentityTokenPath string `json:"identity_token_path"` + Scopes []string `json:"scopes"` +} + +func (ap *gcpMetadataAuthPlugin) NewClient(c Config) (*http.Client, error) { + if ap.Audience == "" && len(ap.Scopes) == 0 { + return nil, errors.New("audience or scopes is required when gcp metadata is enabled") + } + + if ap.Audience != "" && len(ap.Scopes) > 0 { + return nil, errors.New("either audience or scopes can be set, not both, when gcp metadata is enabled") + } + + if ap.Endpoint == "" { + ap.Endpoint = defaultGCPMetadataEndpoint + } + + if ap.AccessTokenPath == "" { + ap.AccessTokenPath = defaultAccessTokenPath + } + + if ap.IdentityTokenPath == "" { + ap.IdentityTokenPath = defaultIdentityTokenPath + } + + t, err := DefaultTLSConfig(c) + if err != nil { + return nil, err + } + + return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil +} + +func (ap *gcpMetadataAuthPlugin) Prepare(req *http.Request) error { + var err error + var token string + + if ap.Audience != "" { + token, err = identityTokenFromMetadataService(ap.Endpoint, ap.IdentityTokenPath, ap.Audience) + if err != nil { + return fmt.Errorf("error retrieving identity token from gcp metadata service: %w", err) + } + } + + if len(ap.Scopes) != 0 { + token, err = accessTokenFromMetadataService(ap.Endpoint, ap.AccessTokenPath, ap.Scopes) + if err != nil { + return fmt.Errorf("error retrieving access token from gcp metadata service: %w", err) + } + } + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", token)) + return nil +} + +// accessTokenFromMetadataService returns an access token based on the scopes. +func accessTokenFromMetadataService(endpoint, path string, scopes []string) (string, error) { + s := strings.Join(scopes, ",") + + e := fmt.Sprintf("%s%s?scopes=%s", endpoint, path, s) + + data, err := gcpMetadataServiceRequest(e) + if err != nil { + return "", err + } + + var accessToken AccessToken + err = json.Unmarshal(data, &accessToken) + if err != nil { + return "", err + } + + return accessToken.AccessToken, nil +} + +// identityTokenFromMetadataService returns an identity token based on the audience. +func identityTokenFromMetadataService(endpoint, path, audience string) (string, error) { + e := fmt.Sprintf("%s%s?audience=%s", endpoint, path, audience) + + data, err := gcpMetadataServiceRequest(e) + if err != nil { + return "", err + } + return string(data), nil +} + +func gcpMetadataServiceRequest(endpoint string) ([]byte, error) { + request, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return nil, err + } + + request.Header.Add("Metadata-Flavor", "Google") + + timeout := time.Duration(5) * time.Second + httpClient := http.Client{Timeout: timeout} + + response, err := httpClient.Do(request) + if err != nil { + return nil, err + } + defer response.Body.Close() + + switch s := response.StatusCode; s { + case 200: + break + case 400: + return nil, &gcpMetadataError{errGCPMetadataInvalidRequest, endpoint, s} + case 404: + return nil, &gcpMetadataError{errGCPMetadataNotFound, endpoint, s} + default: + return nil, &gcpMetadataError{errGCPMetadataUnexpected, endpoint, s} + } + + data, err := io.ReadAll(response.Body) + if err != nil { + return nil, err + } + + return data, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go b/vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go new file mode 100644 index 00000000000..62164580b4b --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/plugins/rest/rest.go @@ -0,0 +1,368 @@ +// Copyright 2018 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Package rest implements a REST client for communicating with remote services. +package rest + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/http/httputil" + "reflect" + "strings" + + "github.com/open-policy-agent/opa/internal/version" + "github.com/open-policy-agent/opa/keys" + "github.com/open-policy-agent/opa/logging" + "github.com/open-policy-agent/opa/tracing" + "github.com/open-policy-agent/opa/util" +) + +const ( + defaultResponseHeaderTimeoutSeconds = int64(10) + defaultResponseSizeLimitBytes = 1024 + + grantTypeClientCredentials = "client_credentials" + grantTypeJwtBearer = "jwt_bearer" +) + +// An HTTPAuthPlugin represents a mechanism to construct and configure HTTP authentication for a REST service +type HTTPAuthPlugin interface { + // implementations can assume NewClient will be called before Prepare + NewClient(Config) (*http.Client, error) + Prepare(*http.Request) error +} + +// Config represents configuration for a REST client. +type Config struct { + Name string `json:"name"` + URL string `json:"url"` + Headers map[string]string `json:"headers"` + AllowInsecureTLS bool `json:"allow_insecure_tls,omitempty"` + ResponseHeaderTimeoutSeconds *int64 `json:"response_header_timeout_seconds,omitempty"` + TLS *serverTLSConfig `json:"tls,omitempty"` + Credentials struct { + Bearer *bearerAuthPlugin `json:"bearer,omitempty"` + OAuth2 *oauth2ClientCredentialsAuthPlugin `json:"oauth2,omitempty"` + ClientTLS *clientTLSAuthPlugin `json:"client_tls,omitempty"` + S3Signing *awsSigningAuthPlugin `json:"s3_signing,omitempty"` + GCPMetadata *gcpMetadataAuthPlugin `json:"gcp_metadata,omitempty"` + AzureManagedIdentity *azureManagedIdentitiesAuthPlugin `json:"azure_managed_identity,omitempty"` + Plugin *string `json:"plugin,omitempty"` + } `json:"credentials"` + Type string `json:"type,omitempty"` + keys map[string]*keys.Config + logger logging.Logger +} + +// Equal returns true if this client config is equal to the other. +func (c *Config) Equal(other *Config) bool { + otherWithoutLogger := *other + otherWithoutLogger.logger = c.logger + return reflect.DeepEqual(c, &otherWithoutLogger) +} + +// An AuthPluginLookupFunc can lookup auth plugins by their name. +type AuthPluginLookupFunc func(name string) HTTPAuthPlugin + +// AuthPlugin should be used to get an authentication method from the config. +func (c *Config) AuthPlugin(lookup AuthPluginLookupFunc) (HTTPAuthPlugin, error) { + var candidate HTTPAuthPlugin + if c.Credentials.Plugin != nil { + if lookup == nil { + // if no authPluginLookup function is passed we can't resolve the plugin + return nil, errors.New("missing auth plugin lookup function") + } + + candidate := lookup(*c.Credentials.Plugin) + if candidate == nil { + return nil, fmt.Errorf("auth plugin %q not found", *c.Credentials.Plugin) + } + + return candidate, nil + } + // reflection avoids need for this code to change as auth plugins are added + s := reflect.ValueOf(c.Credentials) + for i := 0; i < s.NumField(); i++ { + if s.Field(i).IsNil() { + continue + } + + if candidate != nil { + return nil, errors.New("a maximum one credential method must be specified") + } + + candidate = s.Field(i).Interface().(HTTPAuthPlugin) + } + + if candidate == nil { + return &defaultAuthPlugin{}, nil + } + return candidate, nil +} + +func (c *Config) authHTTPClient(lookup AuthPluginLookupFunc) (*http.Client, error) { + plugin, err := c.AuthPlugin(lookup) + if err != nil { + return nil, err + } + return plugin.NewClient(*c) +} + +func (c *Config) authPrepare(req *http.Request, lookup AuthPluginLookupFunc) error { + plugin, err := c.AuthPlugin(lookup) + if err != nil { + return err + } + return plugin.Prepare(req) +} + +// Client implements an HTTP/REST client for communicating with remote +// services. +type Client struct { + bytes *[]byte + json *interface{} + config Config + headers map[string]string + authPluginLookup AuthPluginLookupFunc + logger logging.Logger + loggerFields map[string]interface{} + distributedTacingOpts tracing.Options +} + +// Name returns an option that overrides the service name on the client. +func Name(s string) func(*Client) { + return func(c *Client) { + c.config.Name = s + } +} + +// AuthPluginLookup assigns a function to lookup an HTTPAuthPlugin to a new Client. +// It's intended to be used when creating a Client using New(). Usually this is passed +// the plugins.AuthPlugin func, which retrieves a registered HTTPAuthPlugin from the +// plugin manager. +func AuthPluginLookup(l AuthPluginLookupFunc) func(*Client) { + return func(c *Client) { + c.authPluginLookup = l + } +} + +// Logger assigns a logger to the client +func Logger(l logging.Logger) func(*Client) { + return func(c *Client) { + c.logger = l + } +} + +// DistributedTracingOpts sets the options to be used by distributed tracing. +func DistributedTracingOpts(tr tracing.Options) func(*Client) { + return func(c *Client) { + c.distributedTacingOpts = tr + } +} + +// New returns a new Client for config. +func New(config []byte, keys map[string]*keys.Config, opts ...func(*Client)) (Client, error) { + var parsedConfig Config + if err := util.Unmarshal(config, &parsedConfig); err != nil { + return Client{}, err + } + + parsedConfig.URL = strings.TrimRight(parsedConfig.URL, "/") + + if parsedConfig.ResponseHeaderTimeoutSeconds == nil { + timeout := defaultResponseHeaderTimeoutSeconds + parsedConfig.ResponseHeaderTimeoutSeconds = &timeout + } + + parsedConfig.keys = keys + + client := Client{ + config: parsedConfig, + } + + for _, f := range opts { + f(&client) + } + + if client.logger == nil { + client.logger = logging.Get() + } + + client.config.logger = client.logger + + return client, nil +} + +// AuthPluginLookup returns the lookup function to find a custom registered +// auth plugin by its name. +func (c Client) AuthPluginLookup() AuthPluginLookupFunc { + return c.authPluginLookup +} + +// Service returns the name of the service this Client is configured for. +func (c Client) Service() string { + return c.config.Name +} + +// Config returns this Client's configuration +func (c Client) Config() *Config { + return &c.config +} + +// SetResponseHeaderTimeout sets the "ResponseHeaderTimeout" in the http client's Transport +func (c Client) SetResponseHeaderTimeout(timeout *int64) Client { + c.config.ResponseHeaderTimeoutSeconds = timeout + return c +} + +// Logger returns the logger assigned to the Client +func (c Client) Logger() logging.Logger { + return c.logger +} + +// LoggerFields returns the fields used for log statements used by Client +func (c Client) LoggerFields() map[string]interface{} { + return c.loggerFields +} + +// WithHeader returns a shallow copy of the client with a header to include the +// requests. +func (c Client) WithHeader(k, v string) Client { + if v == "" { + return c + } + if c.headers == nil { + c.headers = map[string]string{} + } + c.headers[k] = v + return c +} + +// WithJSON returns a shallow copy of the client with the JSON value set as the +// message body to include the requests. This function sets the Content-Type +// header. +func (c Client) WithJSON(body interface{}) Client { + c = c.WithHeader("Content-Type", "application/json") + c.json = &body + return c +} + +// WithBytes returns a shallow copy of the client with the bytes set as the +// message body to include in the requests. +func (c Client) WithBytes(body []byte) Client { + c.bytes = &body + return c +} + +// Do executes a request using the client. +func (c Client) Do(ctx context.Context, method, path string) (*http.Response, error) { + + httpClient, err := c.config.authHTTPClient(c.authPluginLookup) + if err != nil { + return nil, err + } + + if len(c.distributedTacingOpts) > 0 { + httpClient.Transport = tracing.NewTransport(httpClient.Transport, c.distributedTacingOpts) + } + + path = strings.Trim(path, "/") + + var body io.Reader + + if c.bytes != nil { + body = bytes.NewReader(*c.bytes) + } else if c.json != nil { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(*c.json); err != nil { + return nil, err + } + body = &buf + } + + url := c.config.URL + "/" + path + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + headers := map[string]string{ + "User-Agent": version.UserAgent, + } + + // Copy custom headers from config. + for key, value := range c.config.Headers { + headers[key] = value + } + + // Overwrite with headers set directly on client. + for key, value := range c.headers { + headers[key] = value + } + + for key, value := range headers { + req.Header.Add(key, value) + } + + req = req.WithContext(ctx) + + err = c.config.authPrepare(req, c.authPluginLookup) + if err != nil { + return nil, err + } + + if c.logger.GetLevel() >= logging.Debug { + c.loggerFields = map[string]interface{}{ + "method": method, + "url": url, + "headers": withMaskedAuthorizationHeader(req.Header), + } + + c.logger.WithFields(c.loggerFields).Debug("Sending request.") + } + + resp, err := httpClient.Do(req) + + if resp != nil && c.logger.GetLevel() >= logging.Debug { + // Only log for debug purposes. If an error occurred, the caller should handle + // that. In the non-error case, the caller may not do anything. + c.loggerFields["status"] = resp.Status + c.loggerFields["headers"] = resp.Header + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + return nil, err + } + + if len(string(dump)) < defaultResponseSizeLimitBytes { + c.loggerFields["response"] = string(dump) + } else { + c.loggerFields["response"] = fmt.Sprintf("%v...", string(dump[:defaultResponseSizeLimitBytes])) + } + } + c.logger.WithFields(c.loggerFields).Debug("Received response.") + } + + return resp, err +} + +func withMaskedAuthorizationHeader(headers http.Header) http.Header { + authzHeader := headers.Get("Authorization") + if authzHeader != "" { + masked := make(http.Header) + for k, v := range headers { + masked[k] = v + } + masked.Set("Authorization", "REDACTED") + return masked + } + return headers +} diff --git a/vendor/github.com/open-policy-agent/opa/rego/plugins.go b/vendor/github.com/open-policy-agent/opa/rego/plugins.go new file mode 100644 index 00000000000..abaa910341e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/rego/plugins.go @@ -0,0 +1,43 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package rego + +import ( + "context" + "sync" + + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/ir" +) + +var targetPlugins = map[string]TargetPlugin{} +var pluginMtx sync.Mutex + +type TargetPlugin interface { + IsTarget(string) bool + PrepareForEval(context.Context, *ir.Policy, ...PrepareOption) (TargetPluginEval, error) +} + +type TargetPluginEval interface { + Eval(context.Context, *EvalContext, ast.Value) (ast.Value, error) +} + +func (r *Rego) targetPlugin(tgt string) TargetPlugin { + for _, p := range targetPlugins { + if p.IsTarget(tgt) { + return p + } + } + return nil +} + +func RegisterPlugin(name string, p TargetPlugin) { + pluginMtx.Lock() + defer pluginMtx.Unlock() + if _, ok := targetPlugins[name]; ok { + panic("plugin already registered " + name) + } + targetPlugins[name] = p +} diff --git a/vendor/github.com/open-policy-agent/opa/rego/rego.go b/vendor/github.com/open-policy-agent/opa/rego/rego.go index c07e5018e54..5ad2af71ec0 100644 --- a/vendor/github.com/open-policy-agent/opa/rego/rego.go +++ b/vendor/github.com/open-policy-agent/opa/rego/rego.go @@ -25,6 +25,7 @@ import ( "github.com/open-policy-agent/opa/ir" "github.com/open-policy-agent/opa/loader" "github.com/open-policy-agent/opa/metrics" + "github.com/open-policy-agent/opa/plugins" "github.com/open-policy-agent/opa/resolver" "github.com/open-policy-agent/opa/storage" "github.com/open-policy-agent/opa/storage/inmem" @@ -122,6 +123,55 @@ type EvalContext struct { copyMaps bool printHook print.Hook capabilities *ast.Capabilities + strictBuiltinErrors bool +} + +func (e *EvalContext) RawInput() *interface{} { + return e.rawInput +} + +func (e *EvalContext) ParsedInput() ast.Value { + return e.parsedInput +} + +func (e *EvalContext) Time() time.Time { + return e.time +} + +func (e *EvalContext) Seed() io.Reader { + return e.seed +} + +func (e *EvalContext) InterQueryBuiltinCache() cache.InterQueryCache { + return e.interQueryBuiltinCache +} + +func (e *EvalContext) PrintHook() print.Hook { + return e.printHook +} + +func (e *EvalContext) Metrics() metrics.Metrics { + return e.metrics +} + +func (e *EvalContext) StrictBuiltinErrors() bool { + return e.strictBuiltinErrors +} + +func (e *EvalContext) NDBCache() builtins.NDBCache { + return e.ndBuiltinCache +} + +func (e *EvalContext) CompiledQuery() ast.Body { + return e.compiledQuery.query +} + +func (e *EvalContext) Capabilities() *ast.Capabilities { + return e.capabilities +} + +func (e *EvalContext) Transaction() storage.Transaction { + return e.txn } // EvalOption defines a function to set an option on an EvalConfig @@ -314,23 +364,24 @@ func (pq preparedQuery) Modules() map[string]*ast.Module { // been opened. func (pq preparedQuery) newEvalContext(ctx context.Context, options []EvalOption) (*EvalContext, func(context.Context), error) { ectx := &EvalContext{ - hasInput: false, - rawInput: nil, - parsedInput: nil, - metrics: nil, - txn: nil, - instrument: false, - instrumentation: nil, - partialNamespace: pq.r.partialNamespace, - queryTracers: nil, - unknowns: pq.r.unknowns, - parsedUnknowns: pq.r.parsedUnknowns, - compiledQuery: compiledQuery{}, - indexing: true, - earlyExit: true, - resolvers: pq.r.resolvers, - printHook: pq.r.printHook, - capabilities: pq.r.capabilities, + hasInput: false, + rawInput: nil, + parsedInput: nil, + metrics: nil, + txn: nil, + instrument: false, + instrumentation: nil, + partialNamespace: pq.r.partialNamespace, + queryTracers: nil, + unknowns: pq.r.unknowns, + parsedUnknowns: pq.r.parsedUnknowns, + compiledQuery: compiledQuery{}, + indexing: true, + earlyExit: true, + resolvers: pq.r.resolvers, + printHook: pq.r.printHook, + capabilities: pq.r.capabilities, + strictBuiltinErrors: pq.r.strictBuiltinErrors, } for _, o := range options { @@ -377,7 +428,9 @@ func (pq preparedQuery) newEvalContext(ctx context.Context, options []EvalOption // Note that it could still be nil ectx.rawInput = pq.r.rawInput } - if pq.r.target != targetWasm { + + if pq.r.targetPlugin(pq.r.target) == nil && // no plugin claims this target + pq.r.target != targetWasm { ectx.parsedInput, err = pq.r.parseRawInput(ectx.rawInput, ectx.metrics) if err != nil { return nil, finishFunc, err @@ -471,10 +524,10 @@ type queryType int // Define a query type for each of the top level Rego // API's that compile queries differently. const ( - evalQueryType queryType = iota - partialResultQueryType queryType = iota - partialQueryType queryType = iota - compileQueryType queryType = iota + evalQueryType queryType = iota + partialResultQueryType + partialQueryType + compileQueryType ) type loadPaths struct { @@ -528,6 +581,7 @@ type Rego struct { interQueryBuiltinCache cache.InterQueryCache ndBuiltinCache builtins.NDBCache strictBuiltinErrors bool + builtinErrorList *[]topdown.Error resolvers []refResolver schemaSet *ast.SchemaSet target string // target type (wasm, rego, etc.) @@ -537,6 +591,9 @@ type Rego struct { enablePrintStatements bool distributedTacingOpts tracing.Options strict bool + pluginMgr *plugins.Manager + plugins []TargetPlugin + targetPrepState TargetPluginEval } // Function represents a built-in function that is callable in Rego. @@ -1055,6 +1112,13 @@ func StrictBuiltinErrors(yes bool) func(r *Rego) { } } +// BuiltinErrorList supplies an error slice to store built-in function errors. +func BuiltinErrorList(list *[]topdown.Error) func(r *Rego) { + return func(r *Rego) { + r.builtinErrorList = list + } +} + // Resolver sets a Resolver for a specified ref path. func Resolver(ref ast.Ref, r resolver.Resolver) func(r *Rego) { return func(rego *Rego) { @@ -1147,7 +1211,8 @@ func New(options ...func(r *Rego)) *Rego { WithSchemas(r.schemaSet). WithCapabilities(r.capabilities). WithEnablePrintStatements(r.enablePrintStatements). - WithStrict(r.strict) + WithStrict(r.strict). + WithUseTypeCheckAnnotations(true) } if r.store == nil { @@ -1179,6 +1244,14 @@ func New(options ...func(r *Rego)) *Rego { r.generateJSON = generateJSON } + if r.pluginMgr != nil { + for _, name := range r.pluginMgr.Plugins() { + p := r.pluginMgr.Plugin(name) + if p0, ok := p.(TargetPlugin); ok { + r.plugins = append(r.plugins, p0) + } + } + } return r } @@ -1392,64 +1465,32 @@ func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*CompileResu queries = []ast.Body{r.compiledQueries[compileQueryType].query} } - return r.compileWasm(modules, queries, compileQueryType) -} - -func (r *Rego) compileWasm(modules []*ast.Module, queries []ast.Body, qType queryType) (*CompileResult, error) { - decls := make(map[string]*ast.Builtin, len(r.builtinDecls)+len(ast.BuiltinMap)) - - for k, v := range ast.BuiltinMap { - decls[k] = v - } - - for k, v := range r.builtinDecls { - decls[k] = v + if tgt := r.targetPlugin(r.target); tgt != nil { + return nil, fmt.Errorf("unsupported for rego target plugins") } - const queryName = "eval" // NOTE(tsandall): the query name is arbitrary + return r.compileWasm(modules, queries, compileQueryType) // TODO(sr) control flow is funky here +} - p := planner.New(). - WithQueries([]planner.QuerySet{ - { - Name: queryName, - Queries: queries, - RewrittenVars: r.compiledQueries[qType].compiler.RewrittenVars(), - }, - }). - WithModules(modules). - WithBuiltinDecls(decls). - WithDebug(r.dump) - policy, err := p.Plan() +func (r *Rego) compileWasm(modules []*ast.Module, queries []ast.Body, qType queryType) (*CompileResult, error) { + policy, err := r.planQuery(queries, qType) if err != nil { return nil, err } - if r.dump != nil { - fmt.Fprintln(r.dump, "PLAN:") - fmt.Fprintln(r.dump, "-----") - err = ir.Pretty(r.dump, policy) - if err != nil { - return nil, err - } - fmt.Fprintln(r.dump) - } - m, err := wasm.New().WithPolicy(policy).Compile() if err != nil { return nil, err } var out bytes.Buffer - if err := encoding.WriteModule(&out, m); err != nil { return nil, err } - result := &CompileResult{ + return &CompileResult{ Bytes: out.Bytes(), - } - - return result, nil + }, nil } // PrepareOption defines a function to set an option to control @@ -1461,6 +1502,7 @@ type PrepareOption func(*PrepareConfig) type PrepareConfig struct { doPartialEval bool disableInlining *[]string + builtinFuncs map[string]*topdown.Builtin } // WithPartialEval configures an option for PrepareForEval @@ -1479,6 +1521,25 @@ func WithNoInline(paths []string) PrepareOption { } } +// WithBuiltinFuncs carries the rego.Function{1,2,3} per-query function definitions +// to the target plugins. +func WithBuiltinFuncs(bis map[string]*topdown.Builtin) PrepareOption { + return func(p *PrepareConfig) { + if p.builtinFuncs == nil { + p.builtinFuncs = make(map[string]*topdown.Builtin, len(bis)) + } + for k, v := range bis { + p.builtinFuncs[k] = v + } + } +} + +// BuiltinFuncs allows retrieving the builtin funcs set via PrepareOption +// WithBuiltinFuncs. +func (p *PrepareConfig) BuiltinFuncs() map[string]*topdown.Builtin { + return p.builtinFuncs +} + // PrepareForEval will parse inputs, modules, and query arguments in preparation // of evaluating them. func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error) { @@ -1532,7 +1593,8 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa return PreparedEvalQuery{}, err } - if r.target == targetWasm { + switch r.target { + case targetWasm: // TODO(sr): make wasm a target plugin, too if r.hasWasmModule() { _ = txnClose(ctx, err) // Ignore error @@ -1571,6 +1633,22 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa return PreparedEvalQuery{}, err } r.opa = o + + case targetRego: // do nothing, don't lookup default plugin + default: // either a specific plugin target, or one that is default + if tgt := r.targetPlugin(r.target); tgt != nil { + queries := []ast.Body{r.compiledQueries[evalQueryType].query} + pol, err := r.planQuery(queries, evalQueryType) + if err != nil { + return PreparedEvalQuery{}, err + } + // always add the builtins provided via rego.FunctionN options + opts = append(opts, WithBuiltinFuncs(r.builtinFuncs)) + r.targetPrepState, err = tgt.PrepareForEval(ctx, pol, opts...) + if err != nil { + return PreparedEvalQuery{}, err + } + } } txnErr := txnClose(ctx, err) // Always call closer @@ -1684,18 +1762,18 @@ func (r *Rego) parseModules(ctx context.Context, txn storage.Transaction, m metr return nil } + ids, err := r.store.ListPolicies(ctx, txn) + if err != nil { + return err + } + m.Timer(metrics.RegoModuleParse).Start() defer m.Timer(metrics.RegoModuleParse).Stop() var errs Errors - // Parse any modules in the are saved to the store, but only if + // Parse any modules that are saved to the store, but only if // another compile step is going to occur (ie. we have parsed modules // that need to be compiled). - ids, err := r.store.ListPolicies(ctx, txn) - if err != nil { - return err - } - for _, id := range ids { // if it is already on the compiler we're using // then don't bother to re-parse it from source @@ -1720,7 +1798,14 @@ func (r *Rego) parseModules(ctx context.Context, txn storage.Transaction, m metr for _, module := range r.modules { p, err := module.Parse() if err != nil { - errs = append(errs, err) + switch errorWithType := err.(type) { + case ast.Errors: + for _, e := range errorWithType { + errs = append(errs, e) + } + default: + errs = append(errs, errorWithType) + } } r.parsedModules[module.filename] = p } @@ -1742,7 +1827,7 @@ func (r *Rego) loadFiles(ctx context.Context, txn storage.Transaction, m metrics result, err := loader.NewFileLoader(). WithMetrics(m). - WithProcessAnnotation(r.schemaSet != nil). + WithProcessAnnotation(true). Filtered(r.loadPaths.paths, r.loadPaths.filter) if err != nil { return err @@ -1771,7 +1856,7 @@ func (r *Rego) loadBundles(ctx context.Context, txn storage.Transaction, m metri for _, path := range r.bundlePaths { bndl, err := loader.NewFileLoader(). WithMetrics(m). - WithProcessAnnotation(r.schemaSet != nil). + WithProcessAnnotation(true). WithSkipBundleVerification(r.skipBundleVerification). AsBundle(path) if err != nil { @@ -1941,8 +2026,20 @@ func (r *Rego) compileQuery(query ast.Body, imports []*ast.Import, m metrics.Met } func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) { - if r.opa != nil { + switch { + case r.targetPrepState != nil: // target plugin flow + var val ast.Value + if r.runtime != nil { + val = r.runtime.Value + } + s, err := r.targetPrepState.Eval(ctx, ectx, val) + if err != nil { + return nil, err + } + return r.valueToQueryResult(s, ectx) + case r.target == targetWasm: return r.evalWasm(ctx, ectx) + case r.target == targetRego: // continue } q := topdown.NewQuery(ectx.compiledQuery.query). @@ -1958,6 +2055,7 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) { WithEarlyExit(ectx.earlyExit). WithInterQueryBuiltinCache(ectx.interQueryBuiltinCache). WithStrictBuiltinErrors(r.strictBuiltinErrors). + WithBuiltinErrorList(r.builtinErrorList). WithSeed(ectx.seed). WithPrintHook(ectx.printHook). WithDistributedTracingOpts(r.distributedTacingOpts) @@ -2038,7 +2136,11 @@ func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, erro return nil, err } - resultSet, ok := parsed.Value.(ast.Set) + return r.valueToQueryResult(parsed.Value, ectx) +} + +func (r *Rego) valueToQueryResult(res ast.Value, ectx *EvalContext) (ResultSet, error) { + resultSet, ok := res.(ast.Set) if !ok { return nil, fmt.Errorf("illegal result type") } @@ -2048,7 +2150,7 @@ func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, erro } var rs ResultSet - err = resultSet.Iter(func(term *ast.Term) error { + err := resultSet.Iter(func(term *ast.Term) error { obj, ok := term.Value.(ast.Object) if !ok { return fmt.Errorf("illegal result type") @@ -2125,16 +2227,17 @@ func (r *Rego) partialResult(ctx context.Context, pCfg *PrepareConfig) (PartialR } ectx := &EvalContext{ - parsedInput: r.parsedInput, - metrics: r.metrics, - txn: r.txn, - partialNamespace: r.partialNamespace, - queryTracers: r.queryTracers, - compiledQuery: r.compiledQueries[partialResultQueryType], - instrumentation: r.instrumentation, - indexing: true, - resolvers: r.resolvers, - capabilities: r.capabilities, + parsedInput: r.parsedInput, + metrics: r.metrics, + txn: r.txn, + partialNamespace: r.partialNamespace, + queryTracers: r.queryTracers, + compiledQuery: r.compiledQueries[partialResultQueryType], + instrumentation: r.instrumentation, + indexing: true, + resolvers: r.resolvers, + capabilities: r.capabilities, + strictBuiltinErrors: r.strictBuiltinErrors, } disableInlining := r.disableInlining @@ -2237,7 +2340,7 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries, WithSkipPartialNamespace(r.skipPartialNamespace). WithShallowInlining(r.shallowInlining). WithInterQueryBuiltinCache(ectx.interQueryBuiltinCache). - WithStrictBuiltinErrors(r.strictBuiltinErrors). + WithStrictBuiltinErrors(ectx.strictBuiltinErrors). WithSeed(ectx.seed). WithPrintHook(ectx.printHook) @@ -2371,11 +2474,13 @@ func (r *Rego) rewriteEqualsForPartialQueryCompile(_ ast.QueryCompiler, query as func (r *Rego) generateTermVar() *ast.Term { r.termVarID++ - - if r.target == targetWasm { - return ast.VarTerm(wasmVarPrefix + fmt.Sprintf("term%v", r.termVarID)) + prefix := ast.WildcardPrefix + if p := r.targetPlugin(r.target); p != nil { + prefix = wasmVarPrefix + } else if r.target == targetWasm { + prefix = wasmVarPrefix } - return ast.VarTerm(ast.WildcardPrefix + fmt.Sprintf("term%v", r.termVarID)) + return ast.VarTerm(fmt.Sprintf("%sterm%v", prefix, r.termVarID)) } func (r Rego) hasQuery() bool { @@ -2558,17 +2663,19 @@ func finishFunction(name string, bctx topdown.BuiltinContext, result *ast.Term, if err != nil { var e *HaltError if errors.As(err, &e) { - return topdown.Halt{Err: &topdown.Error{ + tdErr := &topdown.Error{ Code: topdown.BuiltinErr, Message: fmt.Sprintf("%v: %v", name, e.Error()), Location: bctx.Location, - }} + } + return topdown.Halt{Err: tdErr.Wrap(e)} } - return &topdown.Error{ + tdErr := &topdown.Error{ Code: topdown.BuiltinErr, Message: fmt.Sprintf("%v: %v", name, err.Error()), Location: bctx.Location, } + return tdErr.Wrap(err) } if result == nil { return nil @@ -2598,3 +2705,49 @@ func generateJSON(term *ast.Term, ectx *EvalContext) (interface{}, error) { CopyMaps: ectx.copyMaps, }) } + +func (r *Rego) planQuery(queries []ast.Body, evalQueryType queryType) (*ir.Policy, error) { + modules := make([]*ast.Module, 0, len(r.compiler.Modules)) + for _, module := range r.compiler.Modules { + modules = append(modules, module) + } + + decls := make(map[string]*ast.Builtin, len(r.builtinDecls)+len(ast.BuiltinMap)) + + for k, v := range ast.BuiltinMap { + decls[k] = v + } + + for k, v := range r.builtinDecls { + decls[k] = v + } + + const queryName = "eval" // NOTE(tsandall): the query name is arbitrary + + p := planner.New(). + WithQueries([]planner.QuerySet{ + { + Name: queryName, + Queries: queries, + RewrittenVars: r.compiledQueries[evalQueryType].compiler.RewrittenVars(), + }, + }). + WithModules(modules). + WithBuiltinDecls(decls). + WithDebug(r.dump) + + policy, err := p.Plan() + if err != nil { + return nil, err + } + if r.dump != nil { + fmt.Fprintln(r.dump, "PLAN:") + fmt.Fprintln(r.dump, "-----") + err = ir.Pretty(r.dump, policy) + if err != nil { + return nil, err + } + fmt.Fprintln(r.dump) + } + return policy, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/schemas/authorizationPolicy.json b/vendor/github.com/open-policy-agent/opa/schemas/authorizationPolicy.json new file mode 100644 index 00000000000..639a3c303f1 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/schemas/authorizationPolicy.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Schema for the OPA Authorization Policy Input document", + "type": "object", + "properties": { + "identity": { + "type": "string" + }, + "client_certificates": { + "type": "array", + "items": { + "type": "object" + } + }, + "method": { + "type": "string" + }, + "path": { + "type": "array", + "items": { + "type": "string" + } + }, + "params": { + "type": "object" + }, + "headers": { + "type": "object" + }, + "body": { + "type": "object" + } + }, + "required": [ + "identity", + "client_certificates", + "method", + "path", + "params", + "headers", + "body" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/schemas/schemas.go b/vendor/github.com/open-policy-agent/opa/schemas/schemas.go new file mode 100644 index 00000000000..82f387aee81 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/schemas/schemas.go @@ -0,0 +1,15 @@ +// Copyright 2023 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package schemas + +import ( + "embed" +) + +// FS contains the known schemas for OPA's Authorization Policy etc. +// "authorizationPolicy.json" contains the input schema for OPA's Authorization Policy +// +//go:embed *.json +var FS embed.FS diff --git a/vendor/github.com/open-policy-agent/opa/topdown/builtins.go b/vendor/github.com/open-policy-agent/opa/topdown/builtins.go index 5a7f2bc9107..30c488050fa 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/builtins.go @@ -182,17 +182,19 @@ func handleBuiltinErr(name string, loc *ast.Location, err error) error { case *Error, Halt: return err case builtins.ErrOperand: - return &Error{ + e := &Error{ Code: TypeErr, Message: fmt.Sprintf("%v: %v", name, err.Error()), Location: loc, } + return e.Wrap(err) default: - return &Error{ + e := &Error{ Code: BuiltinErr, Message: fmt.Sprintf("%v: %v", name, err.Error()), Location: loc, } + return e.Wrap(err) } } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go b/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go index d7c3afbd893..353f9568405 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/builtins/builtins.go @@ -249,7 +249,11 @@ func NumberToFloat(n ast.Number) *big.Float { // FloatToNumber converts f to a number. func FloatToNumber(f *big.Float) ast.Number { - return ast.Number(f.Text('g', -1)) + var format byte = 'g' + if f.IsInt() { + format = 'f' + } + return ast.Number(f.Text(format, -1)) } // NumberToInt converts n to a big int. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cache.go b/vendor/github.com/open-policy-agent/opa/topdown/cache.go index 1b7c455eec6..710efee475f 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/cache.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/cache.go @@ -14,8 +14,9 @@ type virtualCache struct { } type virtualCacheElem struct { - value *ast.Term - children *util.HashMap + value *ast.Term + children *util.HashMap + undefined bool } func newVirtualCache() *virtualCache { @@ -32,18 +33,31 @@ func (c *virtualCache) Pop() { c.stack = c.stack[:len(c.stack)-1] } -func (c *virtualCache) Get(ref ast.Ref) *ast.Term { +// Returns the resolved value of the AST term and a flag indicating if the value +// should be interpretted as undefined: +// +// nil, true indicates the ref is undefined +// ast.Term, false indicates the ref is defined +// nil, false indicates the ref has not been cached +// ast.Term, true is impossible +func (c *virtualCache) Get(ref ast.Ref) (*ast.Term, bool) { node := c.stack[len(c.stack)-1] for i := 0; i < len(ref); i++ { x, ok := node.children.Get(ref[i]) if !ok { - return nil + return nil, false } node = x.(*virtualCacheElem) } - return node.value + if node.undefined { + return nil, true + } + + return node.value, false } +// If value is a nil pointer, set the 'undefined' flag on the cache element to +// indicate that the Ref has resolved to undefined. func (c *virtualCache) Put(ref ast.Ref, value *ast.Term) { node := c.stack[len(c.stack)-1] for i := 0; i < len(ref); i++ { @@ -56,7 +70,11 @@ func (c *virtualCache) Put(ref ast.Ref, value *ast.Term) { node = next } } - node.value = value + if value != nil { + node.value = value + } else { + node.undefined = true + } } func newVirtualCacheElem() *virtualCacheElem { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go b/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go index c46c540abd0..f9d2bcff752 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/cache/cache.go @@ -7,11 +7,10 @@ package cache import ( "container/list" + "sync" "github.com/open-policy-agent/opa/ast" - "sync" - "github.com/open-policy-agent/opa/util" ) @@ -62,6 +61,7 @@ func (c *Config) validateAndInjectDefaults() error { // InterQueryCacheValue defines the interface for the data that the inter-query cache holds. type InterQueryCacheValue interface { SizeInBytes() int64 + Clone() (InterQueryCacheValue, error) } // InterQueryCache defines the interface for the inter-query cache. @@ -70,20 +70,26 @@ type InterQueryCache interface { Insert(key ast.Value, value InterQueryCacheValue) int Delete(key ast.Value) UpdateConfig(config *Config) + Clone(value InterQueryCacheValue) (InterQueryCacheValue, error) } // NewInterQueryCache returns a new inter-query cache. func NewInterQueryCache(config *Config) InterQueryCache { return &cache{ - items: map[string]InterQueryCacheValue{}, + items: map[string]cacheItem{}, usage: 0, config: config, l: list.New(), } } +type cacheItem struct { + value InterQueryCacheValue + keyElement *list.Element +} + type cache struct { - items map[string]InterQueryCacheValue + items map[string]cacheItem usage int64 config *Config l *list.List @@ -101,7 +107,12 @@ func (c *cache) Insert(k ast.Value, v InterQueryCacheValue) (dropped int) { func (c *cache) Get(k ast.Value) (InterQueryCacheValue, bool) { c.mtx.Lock() defer c.mtx.Unlock() - return c.unsafeGet(k) + cacheItem, ok := c.unsafeGet(k) + + if ok { + return cacheItem.value, true + } + return nil, false } // Delete deletes the value in the cache for k. @@ -120,6 +131,12 @@ func (c *cache) UpdateConfig(config *Config) { c.config = config } +func (c *cache) Clone(value InterQueryCacheValue) (InterQueryCacheValue, error) { + c.mtx.Lock() + defer c.mtx.Unlock() + return c.unsafeClone(value) +} + func (c *cache) unsafeInsert(k ast.Value, v InterQueryCacheValue) (dropped int) { size := v.SizeInBytes() limit := c.maxSizeBytes() @@ -133,7 +150,6 @@ func (c *cache) unsafeInsert(k ast.Value, v InterQueryCacheValue) (dropped int) for key := c.l.Front(); key != nil && (c.usage+size > limit); key = c.l.Front() { dropKey := key.Value.(ast.Value) c.unsafeDelete(dropKey) - c.l.Remove(key) dropped++ } } @@ -141,25 +157,32 @@ func (c *cache) unsafeInsert(k ast.Value, v InterQueryCacheValue) (dropped int) // By deleting the old value, if it exists, we ensure the usage variable stays correct c.unsafeDelete(k) - c.items[k.String()] = v - c.l.PushBack(k) + c.items[k.String()] = cacheItem{ + value: v, + keyElement: c.l.PushBack(k), + } c.usage += size return dropped } -func (c *cache) unsafeGet(k ast.Value) (InterQueryCacheValue, bool) { +func (c *cache) unsafeGet(k ast.Value) (cacheItem, bool) { value, ok := c.items[k.String()] return value, ok } func (c *cache) unsafeDelete(k ast.Value) { - value, ok := c.unsafeGet(k) + cacheItem, ok := c.unsafeGet(k) if !ok { return } - c.usage -= value.SizeInBytes() + c.usage -= cacheItem.value.SizeInBytes() delete(c.items, k.String()) + c.l.Remove(cacheItem.keyElement) +} + +func (c *cache) unsafeClone(value InterQueryCacheValue) (InterQueryCacheValue, error) { + return value.Clone() } func (c *cache) maxSizeBytes() int64 { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/crypto.go b/vendor/github.com/open-policy-agent/opa/topdown/crypto.go index 3181ab89b7c..c33abb2c93c 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/crypto.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/crypto.go @@ -6,11 +6,13 @@ package topdown import ( "bytes" + "crypto" "crypto/hmac" "crypto/md5" "crypto/sha1" "crypto/sha256" "crypto/sha512" + "crypto/tls" "crypto/x509" "encoding/base64" "encoding/json" @@ -20,8 +22,9 @@ import ( "os" "strings" - "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/jwx/jwk" + + "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/topdown/builtins" "github.com/open-policy-agent/opa/util" ) @@ -38,7 +41,8 @@ const ( blockTypeRSAPrivateKey = "RSA PRIVATE KEY" // blockTypeRSAPrivateKey indicates this PEM block contains a RSA private key. // Exported for tests. - blockTypePrivateKey = "PRIVATE KEY" + blockTypePrivateKey = "PRIVATE KEY" + blockTypeEcPrivateKey = "EC PRIVATE KEY" ) func builtinCryptoX509ParseCertificates(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -96,6 +100,29 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a return iter(valid) } +func builtinCryptoX509ParseKeyPair(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + certificate, err := builtins.StringOperand(operands[0].Value, 1) + if err != nil { + return err + } + + key, err := builtins.StringOperand(operands[1].Value, 1) + if err != nil { + return err + } + + certs, err := getTLSx509KeyPairFromString([]byte(certificate), []byte(key)) + if err != nil { + return err + } + v, err := ast.InterfaceToValue(certs) + if err != nil { + return err + } + + return iter(ast.NewTerm(v)) +} + func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { input, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { @@ -144,7 +171,8 @@ func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast. return iter(ast.NewTerm(v)) } -func builtinCryptoX509ParseRSAPrivateKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + var x interface{} a := operands[0].Value input, err := builtins.StringOperand(a, 1) @@ -153,22 +181,42 @@ func builtinCryptoX509ParseRSAPrivateKey(_ BuiltinContext, operands []*ast.Term, } // get the raw private key - rawKey, err := getRSAPrivateKeyFromString(string(input)) + pemDataString := string(input) + + if pemDataString == "" { + return fmt.Errorf("input PEM data was empty") + } + + // This built in must be supplied a valid PEM or base64 encoded string. + // If the input is not a PEM string, attempt to decode b64. + // If the base64 decode fails - this is an error + if !strings.HasPrefix(pemDataString, "-----BEGIN") { + bs, err := base64.StdEncoding.DecodeString(pemDataString) + if err != nil { + return err + } + pemDataString = string(bs) + } + + rawKeys, err := getPrivateKeysFromPEMData(pemDataString) if err != nil { return err } - rsaPrivateKey, err := jwk.New(rawKey) + if len(rawKeys) == 0 { + return iter(ast.NullTerm()) + } + + key, err := jwk.New(rawKeys[0]) if err != nil { return err } - jsonKey, err := json.Marshal(rsaPrivateKey) + jsonKey, err := json.Marshal(key) if err != nil { return err } - var x interface{} if err := util.UnmarshalJSON(jsonKey, &x); err != nil { return err } @@ -181,6 +229,46 @@ func builtinCryptoX509ParseRSAPrivateKey(_ BuiltinContext, operands []*ast.Term, return iter(ast.NewTerm(value)) } +func builtinCryptoParsePrivateKeys(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + + a := operands[0].Value + input, err := builtins.StringOperand(a, 1) + if err != nil { + return err + } + + if string(input) == "" { + return iter(ast.NullTerm()) + } + + // get the raw private key + rawKeys, err := getPrivateKeysFromPEMData(string(input)) + if err != nil { + return err + } + + if len(rawKeys) == 0 { + return iter(ast.NewTerm(ast.NewArray())) + } + + bs, err := json.Marshal(rawKeys) + if err != nil { + return err + } + + var x interface{} + if err := util.UnmarshalJSON(bs, &x); err != nil { + return err + } + + value, err := ast.InterfaceToValue(x) + if err != nil { + return err + } + + return iter(ast.NewTerm(value)) +} + func hashHelper(a ast.Value, h func(ast.String) string) (ast.Value, error) { s, err := builtins.StringOperand(a, 1) if err != nil { @@ -249,6 +337,24 @@ func builtinCryptoHmacSha512(_ BuiltinContext, operands []*ast.Term, iter func(* return hmacHelper(operands, iter, sha512.New) } +func builtinCryptoHmacEqual(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + a1 := operands[0].Value + mac1, err := builtins.StringOperand(a1, 1) + if err != nil { + return err + } + + a2 := operands[1].Value + mac2, err := builtins.StringOperand(a2, 2) + if err != nil { + return err + } + + res := hmac.Equal([]byte(mac1), []byte(mac2)) + + return iter(ast.BooleanTerm(res)) +} + func init() { RegisterBuiltinFunc(ast.CryptoX509ParseCertificates.Name, builtinCryptoX509ParseCertificates) RegisterBuiltinFunc(ast.CryptoX509ParseAndVerifyCertificates.Name, builtinCryptoX509ParseAndVerifyCertificates) @@ -256,11 +362,14 @@ func init() { RegisterBuiltinFunc(ast.CryptoSha1.Name, builtinCryptoSha1) RegisterBuiltinFunc(ast.CryptoSha256.Name, builtinCryptoSha256) RegisterBuiltinFunc(ast.CryptoX509ParseCertificateRequest.Name, builtinCryptoX509ParseCertificateRequest) - RegisterBuiltinFunc(ast.CryptoX509ParseRSAPrivateKey.Name, builtinCryptoX509ParseRSAPrivateKey) + RegisterBuiltinFunc(ast.CryptoX509ParseRSAPrivateKey.Name, builtinCryptoJWKFromPrivateKey) + RegisterBuiltinFunc(ast.CryptoParsePrivateKeys.Name, builtinCryptoParsePrivateKeys) + RegisterBuiltinFunc(ast.CryptoX509ParseKeyPair.Name, builtinCryptoX509ParseKeyPair) RegisterBuiltinFunc(ast.CryptoHmacMd5.Name, builtinCryptoHmacMd5) RegisterBuiltinFunc(ast.CryptoHmacSha1.Name, builtinCryptoHmacSha1) RegisterBuiltinFunc(ast.CryptoHmacSha256.Name, builtinCryptoHmacSha256) RegisterBuiltinFunc(ast.CryptoHmacSha512.Name, builtinCryptoHmacSha512) + RegisterBuiltinFunc(ast.CryptoHmacEqual.Name, builtinCryptoHmacEqual) } func verifyX509CertificateChain(certs []*x509.Certificate) ([]*x509.Certificate, error) { @@ -334,43 +443,56 @@ func getX509CertsFromPem(pemBlocks []byte) ([]*x509.Certificate, error) { return x509.ParseCertificates(decodedCerts) } -func getRSAPrivateKeyFromString(key string) (interface{}, error) { - // if the input is PEM handle that - if strings.HasPrefix(key, "-----BEGIN") { - return getRSAPrivateKeyFromPEM([]byte(key)) - } +func getPrivateKeysFromPEMData(pemData string) ([]crypto.PrivateKey, error) { + pemBlockString := pemData - // assume input is base64 if not PEM - b64, err := base64.StdEncoding.DecodeString(key) - if err != nil { - return nil, err - } + var validPrivateKeys []crypto.PrivateKey - return getRSAPrivateKeyFromPEM(b64) -} - -func getRSAPrivateKeyFromPEM(pemBlocks []byte) (interface{}, error) { - - // decode the pem into the Block struct - p, _ := pem.Decode(pemBlocks) - if p == nil { - return nil, fmt.Errorf("failed to parse PEM block containing the key") + // if the input is base64, decode it + bs, err := base64.StdEncoding.DecodeString(pemBlockString) + if err == nil { + pemBlockString = string(bs) } + bs = []byte(pemBlockString) - // if the key is in PKCS1 format - if p.Type == blockTypeRSAPrivateKey { - return x509.ParsePKCS1PrivateKey(p.Bytes) - } - - // if the key is in PKCS8 format - if p.Type == blockTypePrivateKey { - return x509.ParsePKCS8PrivateKey(p.Bytes) - } + for len(bs) > 0 { + inputLen := len(bs) + var block *pem.Block + block, bs = pem.Decode(bs) + if block == nil && len(bs) == 0 { + break + } + // should only happen if end of input is not a valid PEM block. See TestParseRSAPrivateKeyVariedPemInput. + if inputLen == len(bs) { + break + } - // unsupported key format - return nil, fmt.Errorf("PEM block type is '%s', expected %s or %s", p.Type, blockTypeRSAPrivateKey, - blockTypePrivateKey) + if block == nil { + continue + } + switch block.Type { + case blockTypeRSAPrivateKey: + parsedKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + validPrivateKeys = append(validPrivateKeys, parsedKey) + case blockTypePrivateKey: + parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + validPrivateKeys = append(validPrivateKeys, parsedKey) + case blockTypeEcPrivateKey: + parsedKey, err := x509.ParseECPrivateKey(block.Bytes) + if err != nil { + return nil, err + } + validPrivateKeys = append(validPrivateKeys, parsedKey) + } + } + return validPrivateKeys, nil } // addCACertsFromFile adds CA certificates from filePath into the given pool. @@ -406,7 +528,7 @@ func addCACertsFromBytes(pool *x509.CertPool, pemBytes []byte) (*x509.CertPool, return pool, nil } -// addCACertsFromBytes adds CA certificates from the environment variable named +// addCACertsFromEnv adds CA certificates from the environment variable named // by envName into the given pool. If pool is nil, it creates a new x509.CertPool. // pool is returned. func addCACertsFromEnv(pool *x509.CertPool, envName string) (*x509.CertPool, error) { @@ -428,6 +550,60 @@ func readCertFromFile(localCertFile string) ([]byte, error) { return certPEM, nil } +func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls.Certificate, error) { + + if !strings.HasPrefix(string(certPemBlock), "-----BEGIN") { + s, err := base64.StdEncoding.DecodeString(string(certPemBlock)) + if err != nil { + return nil, err + } + certPemBlock = s + } + + if !strings.HasPrefix(string(keyPemBlock), "-----BEGIN") { + s, err := base64.StdEncoding.DecodeString(string(keyPemBlock)) + if err != nil { + return nil, err + } + keyPemBlock = s + } + + // we assume it a DER certificate and try to convert it to a PEM. + if !bytes.HasPrefix(certPemBlock, []byte("-----BEGIN")) { + + pemBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: certPemBlock, + } + + var buf bytes.Buffer + if err := pem.Encode(&buf, pemBlock); err != nil { + return nil, err + } + certPemBlock = buf.Bytes() + + } + // we assume it a DER key and try to convert it to a PEM. + if !bytes.HasPrefix(keyPemBlock, []byte("-----BEGIN")) { + pemBlock := &pem.Block{ + Type: "PRIVATE KEY", + Bytes: keyPemBlock, + } + var buf bytes.Buffer + if err := pem.Encode(&buf, pemBlock); err != nil { + return nil, err + } + keyPemBlock = buf.Bytes() + } + + cert, err := tls.X509KeyPair(certPemBlock, keyPemBlock) + if err != nil { + return nil, err + } + + return &cert, nil +} + // ReadKeyFromFile reads a key from file func readKeyFromFile(localKeyFile string) ([]byte, error) { // Read in the cert file diff --git a/vendor/github.com/open-policy-agent/opa/topdown/encoding.go b/vendor/github.com/open-policy-agent/opa/topdown/encoding.go index f2129d8cd01..19ba323d199 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/encoding.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/encoding.go @@ -13,7 +13,7 @@ import ( "net/url" "strings" - ghodss "github.com/ghodss/yaml" + "sigs.k8s.io/yaml" "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/topdown/builtins" @@ -232,7 +232,7 @@ func builtinYAMLMarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T return err } - bs, err := ghodss.JSONToYAML(buf.Bytes()) + bs, err := yaml.JSONToYAML(buf.Bytes()) if err != nil { return err } @@ -247,7 +247,7 @@ func builtinYAMLUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast return err } - bs, err := ghodss.YAMLToJSON([]byte(str)) + bs, err := yaml.YAMLToJSON([]byte(str)) if err != nil { return err } @@ -273,7 +273,7 @@ func builtinYAMLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T } var x interface{} - err = ghodss.Unmarshal([]byte(str), &x) + err = yaml.Unmarshal([]byte(str), &x) return iter(ast.BooleanTerm(err == nil)) } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/errors.go b/vendor/github.com/open-policy-agent/opa/topdown/errors.go index f2459d2ad71..918df6c853a 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/errors.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/errors.go @@ -29,6 +29,7 @@ type Error struct { Code string `json:"code"` Message string `json:"message"` Location *ast.Location `json:"location,omitempty"` + err error `json:"-"` } const ( @@ -90,6 +91,15 @@ func (e *Error) Error() string { return msg } +func (e *Error) Wrap(err error) *Error { + e.err = err + return e +} + +func (e *Error) Unwrap() error { + return e.err +} + func functionConflictErr(loc *ast.Location) error { return &Error{ Code: ConflictErr, diff --git a/vendor/github.com/open-policy-agent/opa/topdown/eval.go b/vendor/github.com/open-policy-agent/opa/topdown/eval.go index 64f4dccf89b..73926583239 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/eval.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/eval.go @@ -17,13 +17,14 @@ import ( "github.com/open-policy-agent/opa/topdown/print" "github.com/open-policy-agent/opa/tracing" "github.com/open-policy-agent/opa/types" - "github.com/open-policy-agent/opa/util" ) type evalIterator func(*eval) error type unifyIterator func() error +type unifyRefIterator func(pos int) error + type queryIDFactory struct { curr uint64 } @@ -331,7 +332,6 @@ func (e *eval) evalExpr(iter evalIterator) error { } return nil } - expr := e.query[e.index] e.traceEval(expr) @@ -1697,7 +1697,7 @@ func (e evalBuiltin) eval(iter unifyIterator) error { operands := make([]*ast.Term, len(e.terms)) - for i := 0; i < len(e.terms); i++ { + for i := range e.terms { operands[i] = e.e.bindings.Plug(e.terms[i]) } @@ -1724,25 +1724,19 @@ func (e evalBuiltin) eval(iter unifyIterator) error { if v, ok := e.bctx.NDBuiltinCache.Get(e.bi.Name, ast.NewArray(operands[:endIndex]...)); ok { switch { case e.bi.Decl.Result() == nil: - err = iter() + return iter() case len(operands) == numDeclArgs: - if v.Compare(ast.Boolean(false)) != 0 { - err = iter() - } // else: nothing to do, don't iter() + if v.Compare(ast.Boolean(false)) == 0 { + return nil // nothing to do + } + return iter() default: - err = e.e.unify(e.terms[endIndex], ast.NewTerm(v), iter) + return e.e.unify(e.terms[endIndex], ast.NewTerm(v), iter) } - - if err != nil { - return Halt{Err: err} - } - - return nil } - e.e.instr.startTimer(evalOpBuiltinCall) - // Otherwise, we'll need to go through the normal unify flow. + e.e.instr.startTimer(evalOpBuiltinCall) } // Normal unification flow for builtins: @@ -1771,6 +1765,9 @@ func (e evalBuiltin) eval(iter unifyIterator) error { } if err != nil { + // NOTE(sr): We wrap the errors here into Halt{} because we don't want to + // record them into builtinErrors below. The errors set here are coming from + // the call to iter(), not from the builtin implementation. err = Halt{Err: err} } @@ -1800,13 +1797,16 @@ type evalFunc struct { func (e evalFunc) eval(iter unifyIterator) error { - // default functions aren't supported: - // https://github.com/open-policy-agent/opa/issues/2445 - if len(e.ir.Rules) == 0 { + if e.ir.Empty() { return nil } - argCount := len(e.ir.Rules[0].Head.Args) + var argCount int + if len(e.ir.Rules) > 0 { + argCount = len(e.ir.Rules[0].Head.Args) + } else if e.ir.Default != nil { + argCount = len(e.ir.Default.Head.Args) + } if len(e.ir.Else) > 0 && e.e.unknown(e.e.query[e.e.index], e.e.bindings) { // Partial evaluation of ordered rules is not supported currently. Save the @@ -1825,6 +1825,7 @@ func (e evalFunc) eval(iter unifyIterator) error { return e.partialEvalSupport(argCount, iter) } } + return suppressEarlyExit(e.evalValue(iter, argCount, e.ir.EarlyExit)) } @@ -1864,6 +1865,11 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro } } + if e.ir.Default != nil && prev == nil { + _, err := e.evalOneRule(iter, e.ir.Default, cacheKey, prev, findOne) + return err + } + return nil } @@ -1879,7 +1885,7 @@ func (e evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, er cacheKey[i] = e.e.bindings.Plug(e.terms[i]) } - cached := e.e.virtualCache.Get(cacheKey) + cached, _ := e.e.virtualCache.Get(cacheKey) if cached != nil { e.e.instr.counterIncr(evalOpVirtualCacheHit) if argCount == len(e.terms)-1 { // f(x) @@ -2094,14 +2100,13 @@ func (e evalTree) next(iter unifyIterator, plugged *ast.Term) error { node = e.node.Child(plugged.Value) if node != nil && len(node.Values) > 0 { r := evalVirtual{ - onlyGroundRefs: onlyGroundRefs(node.Values), - e: e.e, - ref: e.ref, - plugged: e.plugged, - pos: e.pos, - bindings: e.bindings, - rterm: e.rterm, - rbindings: e.rbindings, + e: e.e, + ref: e.ref, + plugged: e.plugged, + pos: e.pos, + bindings: e.bindings, + rterm: e.rterm, + rbindings: e.rbindings, } r.plugged[e.pos] = plugged return r.eval(iter) @@ -2113,16 +2118,6 @@ func (e evalTree) next(iter unifyIterator, plugged *ast.Term) error { return cpy.eval(iter) } -func onlyGroundRefs(values []util.T) bool { - for _, v := range values { - rule := v.(*ast.Rule) - if !rule.Head.Reference.IsGround() { - return false - } - } - return true -} - func (e evalTree) enumerate(iter unifyIterator) error { if e.e.inliningControl.Disabled(e.plugged[:e.pos], true) { @@ -2261,14 +2256,13 @@ func (e evalTree) leaves(plugged ast.Ref, node *ast.TreeNode) (ast.Object, error } type evalVirtual struct { - onlyGroundRefs bool - e *eval - ref ast.Ref - plugged ast.Ref - pos int - bindings *bindings - rterm *ast.Term - rbindings *bindings + e *eval + ref ast.Ref + plugged ast.Ref + pos int + bindings *bindings + rterm *ast.Term + rbindings *bindings } func (e evalVirtual) eval(iter unifyIterator) error { @@ -2286,6 +2280,14 @@ func (e evalVirtual) eval(iter unifyIterator) error { switch ir.Kind { case ast.MultiValue: + var empty *ast.Term + if ir.OnlyGroundRefs { + // rule ref contains no vars, so we're building a set + empty = ast.SetTerm() + } else { + // rule ref contains vars, so we're building an object containing a set leaf + empty = ast.ObjectTerm() + } eval := evalVirtualPartial{ e: e.e, ref: e.ref, @@ -2295,13 +2297,11 @@ func (e evalVirtual) eval(iter unifyIterator) error { bindings: e.bindings, rterm: e.rterm, rbindings: e.rbindings, - empty: ast.SetTerm(), + empty: empty, } return eval.eval(iter) case ast.SingleValue: - // NOTE(sr): If we allow vars in others than the last position of a ref, we need - // to start reworking things here - if e.onlyGroundRefs { + if ir.OnlyGroundRefs { eval := evalVirtualComplete{ e: e.e, ref: e.ref, @@ -2367,9 +2367,31 @@ func (e evalVirtualPartial) eval(iter unifyIterator) error { return e.evalEachRule(iter, unknown) } +// returns the maximum length a ref can be without being longer than the longest rule ref in rules. +func maxRefLength(rules []*ast.Rule, ceil int) int { + var l int + for _, r := range rules { + rl := len(r.Ref()) + if r.Head.RuleKind() == ast.MultiValue { + rl = rl + 1 + } + if rl >= ceil { + return ceil + } else if rl > l { + l = rl + } + } + return l +} + func (e evalVirtualPartial) evalEachRule(iter unifyIterator, unknown bool) error { - if e.e.unknown(e.ref[e.pos+1], e.bindings) { + if e.ir.Empty() { + return nil + } + + m := maxRefLength(e.ir.Rules, len(e.ref)) + if e.e.unknown(e.ref[e.pos+1:m], e.bindings) { for _, rule := range e.ir.Rules { if err := e.evalOneRulePostUnify(iter, rule); err != nil { return err @@ -2395,19 +2417,32 @@ func (e evalVirtualPartial) evalEachRule(iter unifyIterator, unknown bool) error } result := e.empty + var visitedRefs []ast.Ref + for _, rule := range e.ir.Rules { - if err := e.evalOneRulePreUnify(iter, rule, hint, result, unknown); err != nil { + result, err = e.evalOneRulePreUnify(iter, rule, result, unknown, &visitedRefs) + if err != nil { return err } } + if hint.key != nil { + if v, err := result.Value.Find(hint.key[e.pos+1:]); err == nil && v != nil { + e.e.virtualCache.Put(hint.key, ast.NewTerm(v)) + } + } + + if !unknown { + return e.evalTerm(iter, e.pos+1, result, e.bindings) + } + return nil } func (e evalVirtualPartial) evalAllRules(iter unifyIterator, rules []*ast.Rule) error { cacheKey := e.plugged[:e.pos+1] - result := e.e.virtualCache.Get(cacheKey) + result, _ := e.e.virtualCache.Get(cacheKey) if result != nil { e.e.instr.counterIncr(evalOpVirtualCacheHit) return e.e.biunify(result, e.rterm, e.bindings, e.rbindings, iter) @@ -2430,13 +2465,15 @@ func (e evalVirtualPartial) evalAllRules(iter unifyIterator, rules []*ast.Rule) func (e evalVirtualPartial) evalAllRulesNoCache(rules []*ast.Rule) (*ast.Term, error) { result := e.empty + var visitedRefs []ast.Ref + for _, rule := range rules { child := e.e.child(rule.Body) child.traceEnter(rule) err := child.eval(func(*eval) error { child.traceExit(rule) var err error - result, _, err = e.reduce(rule.Head, child.bindings, result) + result, _, err = e.reduce(rule, child.bindings, result, &visitedRefs) if err != nil { return err } @@ -2453,9 +2490,18 @@ func (e evalVirtualPartial) evalAllRulesNoCache(rules []*ast.Rule) (*ast.Term, e return result, nil } -func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Rule, hint evalVirtualPartialCacheHint, result *ast.Term, unknown bool) error { +func wrapInObjects(leaf *ast.Term, ref ast.Ref) *ast.Term { + // We build the nested objects leaf-to-root to preserve ground:ness + if len(ref) == 0 { + return leaf + } + key := ref[0] + val := wrapInObjects(leaf, ref[1:]) + return ast.ObjectTerm(ast.Item(key, val)) +} + +func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Rule, result *ast.Term, unknown bool, visitedRefs *[]ast.Ref) (*ast.Term, error) { - key := e.ref[e.pos+1] child := e.e.child(rule.Body) child.traceEnter(rule) @@ -2465,63 +2511,89 @@ func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Ru if headKey == nil { headKey = rule.Head.Reference[len(rule.Head.Reference)-1] } - err := child.biunify(headKey, key, child.bindings, e.bindings, func() error { + + // Walk the dynamic portion of rule ref and key to unify vars + err := child.biunifyRuleHead(e.pos+1, e.ref, rule, e.bindings, child.bindings, func(pos int) error { defined = true return child.eval(func(child *eval) error { + child.traceExit(rule) + term := rule.Head.Value if term == nil { term = headKey } - if hint.key != nil { - result := child.bindings.Plug(term) - e.e.virtualCache.Put(hint.key, result) - } + if unknown { + term, termbindings := child.bindings.apply(term) - // NOTE(tsandall): if the rule set depends on any unknowns then do - // not perform the duplicate check because evaluation of the ruleset - // may not produce a definitive result. This is a bit strict--we - // could improve by skipping only when saves occur. - if !unknown { + if rule.Head.RuleKind() == ast.MultiValue { + term = ast.SetTerm(term) + } + + objRef := rule.Ref()[e.pos+1:] + term = wrapInObjects(term, objRef) + + err := e.evalTerm(iter, e.pos+1, term, termbindings) + if err != nil { + return err + } + } else { var dup bool var err error - result, dup, err = e.reduce(rule.Head, child.bindings, result) + result, dup, err = e.reduce(rule, child.bindings, result, visitedRefs) if err != nil { return err - } else if dup { + } else if !unknown && dup { child.traceDuplicate(rule) return nil } } - child.traceExit(rule) - term, termbindings := child.bindings.apply(term) - err := e.evalTerm(iter, e.pos+2, term, termbindings) - if err != nil { - return err - } - child.traceRedo(rule) + return nil }) }) if err != nil { - return err + return nil, err } - // TODO(tsandall): why are we tracing here? this looks wrong. if !defined { child.traceFail(rule) } - return nil + return result, nil } -func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.Rule) error { +func (e *eval) biunifyRuleHead(pos int, ref ast.Ref, rule *ast.Rule, refBindings, ruleBindings *bindings, iter unifyRefIterator) error { + return e.biunifyDynamicRef(pos, ref, rule.Ref(), refBindings, ruleBindings, func(pos int) error { + // FIXME: Is there a simpler, more robust way of figuring out that we should biunify the rule key? + if rule.Head.RuleKind() == ast.MultiValue && pos < len(ref) && len(rule.Ref()) <= len(ref) { + headKey := rule.Head.Key + if headKey == nil { + headKey = rule.Head.Reference[len(rule.Head.Reference)-1] + } + return e.biunify(ref[pos], headKey, refBindings, ruleBindings, func() error { + return iter(pos + 1) + }) + } + return iter(pos) + }) +} - key := e.ref[e.pos+1] +func (e *eval) biunifyDynamicRef(pos int, a, b ast.Ref, b1, b2 *bindings, iter unifyRefIterator) error { + if pos >= len(a) || pos >= len(b) { + return iter(pos) + } + + return e.biunify(a[pos], b[pos], b1, b2, func() error { + return e.biunifyDynamicRef(pos+1, a, b, b1, b2, iter) + }) +} + +func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.Rule) error { child := e.e.child(rule.Body) child.traceEnter(rule) @@ -2529,7 +2601,7 @@ func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.R err := child.eval(func(child *eval) error { defined = true - return e.e.biunify(rule.Head.Key, key, child.bindings, e.bindings, func() error { + return e.e.biunifyRuleHead(e.pos+1, e.ref, rule, e.bindings, child.bindings, func(pos int) error { return e.evalOneRuleContinue(iter, rule, child) }) }) @@ -2555,7 +2627,15 @@ func (e evalVirtualPartial) evalOneRuleContinue(iter unifyIterator, rule *ast.Ru } term, termbindings := child.bindings.apply(term) - err := e.evalTerm(iter, e.pos+2, term, termbindings) + + if rule.Head.RuleKind() == ast.MultiValue { + term = ast.SetTerm(term) + } + + objRef := rule.Ref()[e.pos+1:] + term = wrapInObjects(term, objRef) + + err := e.evalTerm(iter, e.pos+1, term, termbindings) if err != nil { return err } @@ -2626,6 +2706,25 @@ func (e evalVirtualPartial) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) head := ast.NewHead(rule.Head.Name, key, value) + ruleRef := e.e.namespaceRef(rule.Ref()) + l := len(path) + if l <= len(ruleRef) { + ruleRef = ruleRef[l-1:] // safe; path always has the data document prefix + if s, ok := ruleRef[0].Value.(ast.String); ok { + ruleRef[0].Value = ast.Var(s) + } + for i := 1; i < len(ruleRef); i++ { + ruleRef[i] = child.bindings.plugNamespaced(ruleRef[i], e.e.caller.bindings) + } + head.Reference = ruleRef + if head.Name.Equal(ast.Var("")) && (len(ruleRef) == 1 || (len(ruleRef) == 2 && head.Key == nil)) { + head.Name = ruleRef[0].Value.(ast.Var) + } + if len(ruleRef) == 2 && head.Key == nil { + head.Key = ruleRef[len(ruleRef)-1] + } + } + if !e.e.inliningControl.shallow { cp := copypropagation.New(head.Vars()). WithEnsureNonEmptyBody(true). @@ -2666,10 +2765,11 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac var hint evalVirtualPartialCacheHint if e.e.unknown(e.ref[:e.pos+1], e.bindings) { + // FIXME: Return empty hint if unknowns in any e.ref elem overlapping with applicable rule refs? return hint, nil } - if cached := e.e.virtualCache.Get(e.plugged[:e.pos+1]); cached != nil { // have full extent cached + if cached, _ := e.e.virtualCache.Get(e.plugged[:e.pos+1]); cached != nil { // have full extent cached e.e.instr.counterIncr(evalOpVirtualCacheHit) hint.hit = true return hint, e.evalTerm(iter, e.pos+1, cached, e.bindings) @@ -2677,17 +2777,29 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac plugged := e.bindings.Plug(e.ref[e.pos+1]) - if plugged.IsGround() { - hint.key = append(e.plugged[:e.pos+1], plugged) + if _, ok := plugged.Value.(ast.Var); ok { + hint.full = true + hint.key = e.plugged[:e.pos+1] + e.e.instr.counterIncr(evalOpVirtualCacheMiss) + return hint, nil + } + + m := maxRefLength(e.ir.Rules, len(e.ref)) + + for i := e.pos + 1; i < m; i++ { + plugged = e.bindings.Plug(e.ref[i]) - if cached := e.e.virtualCache.Get(hint.key); cached != nil { + if !plugged.IsGround() { + break + } + + hint.key = append(e.plugged[:i], plugged) + + if cached, _ := e.e.virtualCache.Get(hint.key); cached != nil { e.e.instr.counterIncr(evalOpVirtualCacheHit) hint.hit = true - return hint, e.evalTerm(iter, e.pos+2, cached, e.bindings) + return hint, e.evalTerm(iter, i+1, cached, e.bindings) } - } else if _, ok := plugged.Value.(ast.Var); ok { - hint.full = true - hint.key = e.plugged[:e.pos+1] } e.e.instr.counterIncr(evalOpVirtualCacheMiss) @@ -2695,26 +2807,99 @@ func (e evalVirtualPartial) evalCache(iter unifyIterator) (evalVirtualPartialCac return hint, nil } -func (e evalVirtualPartial) reduce(head *ast.Head, b *bindings, result *ast.Term) (*ast.Term, bool, error) { +func getNestedObject(ref ast.Ref, rootObj *ast.Object, b *bindings, l *ast.Location) (*ast.Object, error) { + current := rootObj + for _, term := range ref { + key := b.Plug(term) + if child := (*current).Get(key); child != nil { + if val, ok := child.Value.(ast.Object); ok { + current = &val + } else { + return nil, objectDocKeyConflictErr(l) + } + } else { + child := ast.NewObject() + (*current).Insert(key, ast.NewTerm(child)) + current = &child + } + } + + return current, nil +} + +func hasCollisions(path ast.Ref, visitedRefs *[]ast.Ref, b *bindings) bool { + collisionPathTerm := b.Plug(ast.NewTerm(path)) + collisionPath := collisionPathTerm.Value.(ast.Ref) + for _, c := range *visitedRefs { + if collisionPath.HasPrefix(c) && !collisionPath.Equal(c) { + return true + } + } + *visitedRefs = append(*visitedRefs, collisionPath) + return false +} + +func (e evalVirtualPartial) reduce(rule *ast.Rule, b *bindings, result *ast.Term, visitedRefs *[]ast.Ref) (*ast.Term, bool, error) { var exists bool + head := rule.Head switch v := result.Value.(type) { - case ast.Set: // MultiValue + case ast.Set: key := b.Plug(head.Key) exists = v.Contains(key) v.Add(key) - case ast.Object: // SingleValue - key := head.Reference[len(head.Reference)-1] // NOTE(sr): multiple vars in ref heads need to deal with this better - key = b.Plug(key) - value := b.Plug(head.Value) - if curr := v.Get(key); curr != nil { - if !curr.Equal(value) { - return nil, false, objectDocKeyConflictErr(head.Location) - } - exists = true + case ast.Object: + // data.p.q[r].s.t := 42 {...} + // |----|-| + // ^ ^ + // | leafKey + // objPath + fullPath := rule.Ref() + + collisionPath := fullPath[e.pos+1:] + if hasCollisions(collisionPath, visitedRefs, b) { + return nil, false, objectDocKeyConflictErr(head.Location) + } + + objPath := fullPath[e.pos+1 : len(fullPath)-1] // the portion of the ref that generates nested objects + leafKey := b.Plug(fullPath[len(fullPath)-1]) // the portion of the ref that is the deepest nested key for the value + + leafObj, err := getNestedObject(objPath, &v, b, head.Location) + if err != nil { + return nil, false, err + } + + if kind := head.RuleKind(); kind == ast.SingleValue { + // We're inserting into an object + val := b.Plug(head.Value) // head.Value instance is shared between rule enumerations;but this is ok, as we don't allow rules to modify each others values. + + if curr := (*leafObj).Get(leafKey); curr != nil { + if !curr.Equal(val) { + return nil, false, objectDocKeyConflictErr(head.Location) + } + exists = true + } else { + (*leafObj).Insert(leafKey, val) + } } else { - v.Insert(key, value) + // We're inserting into a set + var set *ast.Set + if leaf := (*leafObj).Get(leafKey); leaf != nil { + if s, ok := leaf.Value.(ast.Set); ok { + set = &s + } else { + return nil, false, objectDocKeyConflictErr(head.Location) + } + } else { + s := ast.NewSet() + (*leafObj).Insert(leafKey, ast.NewTerm(s)) + set = &s + } + + key := b.Plug(head.Key) + exists = (*set).Contains(key) + (*set).Add(key) } } @@ -2768,7 +2953,12 @@ func (e evalVirtualComplete) eval(iter unifyIterator) error { } func (e evalVirtualComplete) evalValue(iter unifyIterator, findOne bool) error { - cached := e.e.virtualCache.Get(e.plugged[:e.pos+1]) + cached, undefined := e.e.virtualCache.Get(e.plugged[:e.pos+1]) + if undefined { + e.e.instr.counterIncr(evalOpVirtualCacheHit) + return nil + } + if cached != nil { e.e.instr.counterIncr(evalOpVirtualCacheHit) return e.evalTerm(iter, cached, e.bindings) @@ -2804,6 +2994,10 @@ func (e evalVirtualComplete) evalValue(iter unifyIterator, findOne bool) error { return err } + if prev == nil { + e.e.virtualCache.Put(e.plugged[:e.pos+1], nil) + } + return nil } @@ -2932,6 +3126,7 @@ func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, path ast.Ref s := ref[len(ref)-1].Value.(ast.String) name = ast.Var(s) } + // TODO: Do we need to deal with general refs here? head := ast.NewHead(name, nil, child.bindings.PlugNamespaced(rule.Head.Value, e.e.caller.bindings)) if !e.e.inliningControl.shallow { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/http.go b/vendor/github.com/open-policy-agent/opa/topdown/http.go index 71547e5bf78..bf5dbb55d30 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/http.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/http.go @@ -67,10 +67,27 @@ var allowedKeyNames = [...]string{ "force_cache_duration_seconds", "raise_error", "caching_mode", + "max_retry_attempts", +} + +// ref: https://www.rfc-editor.org/rfc/rfc7231#section-6.1 +var cacheableHTTPStatusCodes = [...]int{ + http.StatusOK, + http.StatusNonAuthoritativeInfo, + http.StatusNoContent, + http.StatusPartialContent, + http.StatusMultipleChoices, + http.StatusMovedPermanently, + http.StatusNotFound, + http.StatusMethodNotAllowed, + http.StatusGone, + http.StatusRequestURITooLong, + http.StatusNotImplemented, } var ( allowedKeys = ast.NewSet() + cacheableCodes = ast.NewSet() requiredKeys = ast.NewSet(ast.StringTerm("method"), ast.StringTerm("url")) httpSendLatencyMetricKey = "rego_builtin_" + strings.ReplaceAll(ast.HTTPSend.Name, ".", "_") httpSendInterQueryCacheHits = httpSendLatencyMetricKey + "_interquery_cache_hits" @@ -88,6 +105,12 @@ const ( // HTTPSendNetworkErr represents a network error. HTTPSendNetworkErr string = "eval_http_send_network_error" + + // minRetryDelay is amount of time to backoff after the first failure. + minRetryDelay = time.Millisecond * 100 + + // maxRetryDelay is the upper bound of backoff delay. + maxRetryDelay = time.Second * 60 ) func builtinHTTPSend(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -145,6 +168,7 @@ func getHTTPResponse(bctx BuiltinContext, req ast.Object) (*ast.Term, error) { if resp == nil { httpResp, err := reqExecutor.ExecuteHTTPRequest() if err != nil { + reqExecutor.InsertErrorIntoCache(err) return nil, err } defer util.Close(httpResp) @@ -162,6 +186,7 @@ func getHTTPResponse(bctx BuiltinContext, req ast.Object) (*ast.Term, error) { func init() { createAllowedKeys() + createCacheableHTTPStatusCodes() initDefaults() RegisterBuiltinFunc(ast.HTTPSend.Name, builtinHTTPSend) } @@ -443,7 +468,7 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt case "cache", "caching_mode", "force_cache", "force_cache_duration_seconds", "force_json_decode", "force_yaml_decode", - "raise_error": // no-op + "raise_error", "max_retry_attempts": // no-op default: return nil, nil, fmt.Errorf("invalid parameter %q", key) } @@ -452,6 +477,9 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt isTLS := false client := &http.Client{ Timeout: timeout, + CheckRedirect: func(*http.Request, []*http.Request) error { + return http.ErrUseLastResponse + }, } if tlsInsecureSkipVerify { @@ -560,9 +588,9 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt } // check if redirects are enabled - if !enableRedirect { - client.CheckRedirect = func(*http.Request, []*http.Request) error { - return http.ErrUseLastResponse + if enableRedirect { + client.CheckRedirect = func(req *http.Request, _ []*http.Request) error { + return verifyURLHost(bctx, req.URL.String()) } } @@ -626,8 +654,39 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt return req, client, nil } -func executeHTTPRequest(req *http.Request, client *http.Client) (*http.Response, error) { - return client.Do(req) +func executeHTTPRequest(req *http.Request, client *http.Client, inputReqObj ast.Object) (*http.Response, error) { + var err error + var retry int + + retry, err = getNumberValFromReqObj(inputReqObj, ast.StringTerm("max_retry_attempts")) + if err != nil { + return nil, err + } + + for i := 0; true; i++ { + + var resp *http.Response + resp, err = client.Do(req) + if err == nil { + return resp, nil + } + + // final attempt + if i == retry { + break + } + + if err == context.Canceled { + return nil, err + } + + select { + case <-time.After(util.DefaultBackoff(float64(minRetryDelay), float64(maxRetryDelay), i)): + case <-req.Context().Done(): + return nil, context.Canceled + } + } + return nil, err } func isContentType(header http.Header, typ ...string) bool { @@ -639,51 +698,121 @@ func isContentType(header http.Header, typ ...string) bool { return false } +type httpSendCacheEntry struct { + response *ast.Value + error error +} + +// The httpSendCache is used for intra-query caching of http.send results. +type httpSendCache struct { + entries *util.HashMap +} + +func newHTTPSendCache() *httpSendCache { + return &httpSendCache{ + entries: util.NewHashMap(valueEq, valueHash), + } +} + +func valueHash(v util.T) int { + return v.(ast.Value).Hash() +} + +func valueEq(a, b util.T) bool { + av := a.(ast.Value) + bv := b.(ast.Value) + return av.Compare(bv) == 0 +} + +func (cache *httpSendCache) get(k ast.Value) *httpSendCacheEntry { + if v, ok := cache.entries.Get(k); ok { + v := v.(httpSendCacheEntry) + return &v + } + return nil +} + +func (cache *httpSendCache) putResponse(k ast.Value, v *ast.Value) { + cache.entries.Put(k, httpSendCacheEntry{response: v}) +} + +func (cache *httpSendCache) putError(k ast.Value, v error) { + cache.entries.Put(k, httpSendCacheEntry{error: v}) +} + // In the BuiltinContext cache we only store a single entry that points to // our ValueMap which is the "real" http.send() cache. -func getHTTPSendCache(bctx BuiltinContext) *ast.ValueMap { +func getHTTPSendCache(bctx BuiltinContext) *httpSendCache { raw, ok := bctx.Cache.Get(httpSendBuiltinCacheKey) if !ok { // Initialize if it isn't there - cache := ast.NewValueMap() - bctx.Cache.Put(httpSendBuiltinCacheKey, cache) - return cache + c := newHTTPSendCache() + bctx.Cache.Put(httpSendBuiltinCacheKey, c) + return c } - cache, ok := raw.(*ast.ValueMap) + c, ok := raw.(*httpSendCache) if !ok { return nil } - return cache + return c } // checkHTTPSendCache checks for the given key's value in the cache -func checkHTTPSendCache(bctx BuiltinContext, key ast.Object) ast.Value { +func checkHTTPSendCache(bctx BuiltinContext, key ast.Object) (ast.Value, error) { requestCache := getHTTPSendCache(bctx) if requestCache == nil { - return nil + return nil, nil } - return requestCache.Get(key) + v := requestCache.get(key) + if v != nil { + if v.error != nil { + return nil, v.error + } + if v.response != nil { + return *v.response, nil + } + // This should never happen + } + + return nil, nil } func insertIntoHTTPSendCache(bctx BuiltinContext, key ast.Object, value ast.Value) { requestCache := getHTTPSendCache(bctx) if requestCache == nil { // Should never happen.. if it does just skip caching the value + // FIXME: return error instead, to prevent inconsistencies? + return + } + requestCache.putResponse(key, &value) +} + +func insertErrorIntoHTTPSendCache(bctx BuiltinContext, key ast.Object, err error) { + requestCache := getHTTPSendCache(bctx) + if requestCache == nil { + // Should never happen.. if it does just skip caching the value + // FIXME: return error instead, to prevent inconsistencies? return } - requestCache.Put(key, value) + requestCache.putError(key, err) } // checkHTTPSendInterQueryCache checks for the given key's value in the inter-query cache func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) { requestCache := c.bctx.InterQueryBuiltinCache - value, found := requestCache.Get(c.key) + cachedValue, found := requestCache.Get(c.key) if !found { return nil, nil } + + value, cerr := requestCache.Clone(cachedValue) + if cerr != nil { + return nil, handleHTTPSendErr(c.bctx, cerr) + } + c.bctx.Metrics.Counter(httpSendInterQueryCacheHits).Incr() var cachedRespData *interQueryCacheData @@ -710,15 +839,12 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) { return nil, handleHTTPSendErr(c.bctx, err) } - headers, err := parseResponseHeaders(cachedRespData.Headers) - if err != nil { - return nil, err - } + headers := parseResponseHeaders(cachedRespData.Headers) // check with the server if the stale response is still up-to-date. // If server returns a new response (ie. status_code=200), update the cache with the new response // If server returns an unmodified response (ie. status_code=304), update the headers for the existing response - result, modified, err := revalidateCachedResponse(c.httpReq, c.httpClient, headers) + result, modified, err := revalidateCachedResponse(c.httpReq, c.httpClient, c.key, headers) requestCache.Delete(c.key) if err != nil || result == nil { return nil, err @@ -735,11 +861,16 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) { } } - expiresAt, err := expiryFromHeaders(result.Header) - if err != nil { - return nil, err + if forceCaching(c.forceCacheParams) { + createdAt := getCurrentTime(c.bctx) + cachedRespData.ExpiresAt = createdAt.Add(time.Second * time.Duration(c.forceCacheParams.forceCacheDurationSeconds)) + } else { + expiresAt, err := expiryFromHeaders(result.Header) + if err != nil { + return nil, err + } + cachedRespData.ExpiresAt = expiresAt } - cachedRespData.ExpiresAt = expiresAt cachingMode, err := getCachingMode(c.key) if err != nil { @@ -776,7 +907,7 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) { // insertIntoHTTPSendInterQueryCache inserts given key and value in the inter-query cache func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp *http.Response, respBody []byte, cacheParams *forceCacheParams) error { - if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) { + if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) || !cacheableCodes.Contains(ast.IntNumberTerm(resp.StatusCode)) { return nil } @@ -814,6 +945,12 @@ func createAllowedKeys() { } } +func createCacheableHTTPStatusCodes() { + for _, element := range cacheableHTTPStatusCodes { + cacheableCodes.Add(ast.IntNumberTerm(element)) + } +} + func parseTimeout(timeoutVal ast.Value) (time.Duration, error) { var timeout time.Duration switch t := timeoutVal.(type) { @@ -853,6 +990,23 @@ func getBoolValFromReqObj(req ast.Object, key *ast.Term) (bool, error) { return bool(b), nil } +func getNumberValFromReqObj(req ast.Object, key *ast.Term) (int, error) { + term := req.Get(key) + if term == nil { + return 0, nil + } + + if t, ok := term.Value.(ast.Number); ok { + num, ok := t.Int() + if !ok || num < 0 { + return 0, fmt.Errorf("invalid value %v for field %v", t.String(), key.String()) + } + return num, nil + } + + return 0, fmt.Errorf("invalid value %v for field %v", term.String(), key.String()) +} + func getCachingMode(req ast.Object) (cachingMode, error) { key := ast.StringTerm("caching_mode") var s ast.String @@ -889,6 +1043,12 @@ func newInterQueryCacheValue(bctx BuiltinContext, resp *http.Response, respBody return &interQueryCacheValue{Data: b}, nil } +func (cb interQueryCacheValue) Clone() (cache.InterQueryCacheValue, error) { + dup := make([]byte, len(cb.Data)) + copy(dup, cb.Data) + return &interQueryCacheValue{Data: dup}, nil +} + func (cb interQueryCacheValue) SizeInBytes() int64 { return int64(len(cb.Data)) } @@ -972,44 +1132,38 @@ func (c *interQueryCacheData) SizeInBytes() int64 { return 0 } +func (c *interQueryCacheData) Clone() (cache.InterQueryCacheValue, error) { + dup := make([]byte, len(c.RespBody)) + copy(dup, c.RespBody) + + return &interQueryCacheData{ + ExpiresAt: c.ExpiresAt, + RespBody: dup, + Status: c.Status, + StatusCode: c.StatusCode, + Headers: c.Headers.Clone()}, nil +} + type responseHeaders struct { - date time.Time // origination date and time of response - cacheControl map[string]string // response cache-control header - maxAge deltaSeconds // max-age cache control directive - expires time.Time // date/time after which the response is considered stale - etag string // identifier for a specific version of the response - lastModified string // date and time response was last modified as per origin server + etag string // identifier for a specific version of the response + lastModified string // date and time response was last modified as per origin server } // deltaSeconds specifies a non-negative integer, representing // time in seconds: http://tools.ietf.org/html/rfc7234#section-1.2.1 type deltaSeconds int32 -func parseResponseHeaders(headers http.Header) (*responseHeaders, error) { - var err error +func parseResponseHeaders(headers http.Header) *responseHeaders { result := responseHeaders{} - result.date, err = getResponseHeaderDate(headers) - if err != nil { - return nil, err - } - - result.cacheControl = parseCacheControlHeader(headers) - result.maxAge, err = parseMaxAgeCacheDirective(result.cacheControl) - if err != nil { - return nil, err - } - - result.expires = getResponseHeaderExpires(headers) - result.etag = headers.Get("etag") result.lastModified = headers.Get("last-modified") - return &result, nil + return &result } -func revalidateCachedResponse(req *http.Request, client *http.Client, headers *responseHeaders) (*http.Response, bool, error) { +func revalidateCachedResponse(req *http.Request, client *http.Client, inputReqObj ast.Object, headers *responseHeaders) (*http.Response, bool, error) { etag := headers.etag lastModified := headers.lastModified @@ -1027,7 +1181,7 @@ func revalidateCachedResponse(req *http.Request, client *http.Client, headers *r cloneReq.Header.Set("if-modified-since", lastModified) } - response, err := client.Do(cloneReq) + response, err := executeHTTPRequest(cloneReq, client, inputReqObj) if err != nil { return nil, false, err } @@ -1207,6 +1361,7 @@ func getResponseHeaders(headers http.Header) map[string]interface{} { type httpRequestExecutor interface { CheckCache() (ast.Value, error) InsertIntoCache(value *http.Response) (ast.Value, error) + InsertErrorIntoCache(err error) ExecuteHTTPRequest() (*http.Response, error) } @@ -1242,6 +1397,15 @@ func newInterQueryCache(bctx BuiltinContext, key ast.Object, forceCacheParams *f func (c *interQueryCache) CheckCache() (ast.Value, error) { var err error + // Checking the intra-query cache first ensures consistency of errors and HTTP responses within a query. + resp, err := checkHTTPSendCache(c.bctx, c.key) + if err != nil { + return nil, err + } + if resp != nil { + return resp, nil + } + c.forceJSONDecode, err = getBoolValFromReqObj(c.key, ast.StringTerm("force_json_decode")) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) @@ -1251,14 +1415,14 @@ func (c *interQueryCache) CheckCache() (ast.Value, error) { return nil, handleHTTPSendErr(c.bctx, err) } - resp, err := c.checkHTTPSendInterQueryCache() - - // fallback to the http send cache if response not found in the inter-query cache or inter-query cache look-up results - // in an error - if resp == nil || err != nil { - return checkHTTPSendCache(c.bctx, c.key), nil + resp, err = c.checkHTTPSendInterQueryCache() + // Always insert the result of the inter-query cache into the intra-query cache, to maintain consistency within the same query. + if err != nil { + insertErrorIntoHTTPSendCache(c.bctx, c.key, err) + } + if resp != nil { + insertIntoHTTPSendCache(c.bctx, c.key, resp) } - return resp, err } @@ -1269,14 +1433,19 @@ func (c *interQueryCache) InsertIntoCache(value *http.Response) (ast.Value, erro return nil, handleHTTPSendErr(c.bctx, err) } - // fallback to the http send cache if error encountered while inserting response in inter-query cache - err = insertIntoHTTPSendInterQueryCache(c.bctx, c.key, value, respBody, c.forceCacheParams) - if err != nil { - insertIntoHTTPSendCache(c.bctx, c.key, result) - } + // Always insert into the intra-query cache, to maintain consistency within the same query. + insertIntoHTTPSendCache(c.bctx, c.key, result) + + // We ignore errors when populating the inter-query cache, because we've already populated the intra-cache, + // and query consistency is our primary concern. + _ = insertIntoHTTPSendInterQueryCache(c.bctx, c.key, value, respBody, c.forceCacheParams) return result, nil } +func (c *interQueryCache) InsertErrorIntoCache(err error) { + insertErrorIntoHTTPSendCache(c.bctx, c.key, err) +} + // ExecuteHTTPRequest executes a HTTP request func (c *interQueryCache) ExecuteHTTPRequest() (*http.Response, error) { var err error @@ -1285,7 +1454,7 @@ func (c *interQueryCache) ExecuteHTTPRequest() (*http.Response, error) { return nil, handleHTTPSendErr(c.bctx, err) } - return executeHTTPRequest(c.httpReq, c.httpClient) + return executeHTTPRequest(c.httpReq, c.httpClient, c.key) } type intraQueryCache struct { @@ -1299,7 +1468,7 @@ func newIntraQueryCache(bctx BuiltinContext, key ast.Object) (*intraQueryCache, // CheckCache checks the cache for the value of the key set on this object func (c *intraQueryCache) CheckCache() (ast.Value, error) { - return checkHTTPSendCache(c.bctx, c.key), nil + return checkHTTPSendCache(c.bctx, c.key) } // InsertIntoCache inserts the key set on this object into the cache with the given value @@ -1318,17 +1487,24 @@ func (c *intraQueryCache) InsertIntoCache(value *http.Response) (ast.Value, erro return nil, handleHTTPSendErr(c.bctx, err) } - insertIntoHTTPSendCache(c.bctx, c.key, result) + if cacheableCodes.Contains(ast.IntNumberTerm(value.StatusCode)) { + insertIntoHTTPSendCache(c.bctx, c.key, result) + } + return result, nil } +func (c *intraQueryCache) InsertErrorIntoCache(err error) { + insertErrorIntoHTTPSendCache(c.bctx, c.key, err) +} + // ExecuteHTTPRequest executes a HTTP request func (c *intraQueryCache) ExecuteHTTPRequest() (*http.Response, error) { httpReq, httpClient, err := createHTTPRequest(c.bctx, c.key) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } - return executeHTTPRequest(httpReq, httpClient) + return executeHTTPRequest(httpReq, httpClient, c.key) } func useInterQueryCache(req ast.Object) (bool, *forceCacheParams, error) { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/json.go b/vendor/github.com/open-policy-agent/opa/topdown/json.go index d1d8897e4d0..8a5d2328360 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/json.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/json.go @@ -11,10 +11,11 @@ import ( "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/topdown/builtins" + + "github.com/open-policy-agent/opa/internal/edittree" ) func builtinJSONRemove(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // Expect an object and a string or array/set of strings _, err := builtins.ObjectOperand(operands[0].Value, 1) if err != nil { @@ -116,7 +117,6 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { } func builtinJSONFilter(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // Ensure we have the right parameters, expect an object and a string or array/set of strings obj, err := builtins.ObjectOperand(operands[0].Value, 1) if err != nil { @@ -196,7 +196,6 @@ func parsePath(path *ast.Term) (ast.Ref, error) { } func pathsToObject(paths []ast.Ref) ast.Object { - root := ast.NewObject() for _, path := range paths { @@ -239,288 +238,147 @@ func pathsToObject(paths []ast.Ref) ast.Object { return root } -// toIndex tries to convert path elements (that may be strings) into indices into -// an array. -func toIndex(arr *ast.Array, term *ast.Term) (int, error) { - i := 0 +type jsonPatch struct { + op string + path *ast.Term + from *ast.Term + value *ast.Term +} + +func getPatch(o ast.Object) (jsonPatch, error) { + validOps := map[string]struct{}{"add": {}, "remove": {}, "replace": {}, "move": {}, "copy": {}, "test": {}} + var out jsonPatch var ok bool - switch v := term.Value.(type) { - case ast.Number: - if i, ok = v.Int(); !ok { - return 0, fmt.Errorf("Invalid number type for indexing") - } - case ast.String: - if v == "-" { - return arr.Len(), nil - } - num := ast.Number(v) - if i, ok = num.Int(); !ok { - return 0, fmt.Errorf("Invalid string for indexing") + getAttribute := func(attr string) (*ast.Term, error) { + if term := o.Get(ast.StringTerm(attr)); term != nil { + return term, nil } - if v != "0" && strings.HasPrefix(string(v), "0") { - return 0, fmt.Errorf("Leading zeros are not allowed in JSON paths") - } - default: - return 0, fmt.Errorf("Invalid type for indexing") - } - - return i, nil -} -// patchWorkerris a worker that modifies a direct child of a term located -// at the given key. It returns the new term, and optionally a result that -// is passed back to the caller. -type patchWorker = func(parent, key *ast.Term) (updated, result *ast.Term) - -func jsonPatchTraverse( - target *ast.Term, - path ast.Ref, - worker patchWorker, -) (*ast.Term, *ast.Term) { - if len(path) < 1 { - return nil, nil + return nil, fmt.Errorf("missing '%s' attribute", attr) } - key := path[0] - if len(path) == 1 { - return worker(target, key) + opTerm, err := getAttribute("op") + if err != nil { + return out, err + } + op, ok := opTerm.Value.(ast.String) + if !ok { + return out, fmt.Errorf("attribute 'op' must be a string") + } + out.op = string(op) + if _, found := validOps[out.op]; !found { + out.op = "" + return out, fmt.Errorf("unrecognized op '%s'", string(op)) } - success := false - var updated, result *ast.Term - switch parent := target.Value.(type) { - case ast.Object: - obj := ast.NewObject() - parent.Foreach(func(k, v *ast.Term) { - if k.Equal(key) { - if v, result = jsonPatchTraverse(v, path[1:], worker); v != nil { - obj.Insert(k, v) - success = true - } - } else { - obj.Insert(k, v) - } - }) - updated = ast.NewTerm(obj) + pathTerm, err := getAttribute("path") + if err != nil { + return out, err + } + out.path = pathTerm - case *ast.Array: - idx, err := toIndex(parent, key) + // Only fetch the "from" parameter for move/copy ops. + switch out.op { + case "move", "copy": + fromTerm, err := getAttribute("from") if err != nil { - return nil, nil - } - arr := ast.NewArray() - for i := 0; i < parent.Len(); i++ { - v := parent.Elem(i) - if idx == i { - if v, result = jsonPatchTraverse(v, path[1:], worker); v != nil { - arr = arr.Append(v) - success = true - } - } else { - arr = arr.Append(v) - } + return out, err } - updated = ast.NewTerm(arr) - - case ast.Set: - set := ast.NewSet() - parent.Foreach(func(k *ast.Term) { - if k.Equal(key) { - if k, result = jsonPatchTraverse(k, path[1:], worker); k != nil { - set.Add(k) - success = true - } - } else { - set.Add(k) - } - }) - updated = ast.NewTerm(set) + out.from = fromTerm } - if success { - return updated, result + // Only fetch the "value" parameter for add/replace/test ops. + switch out.op { + case "add", "replace", "test": + valueTerm, err := getAttribute("value") + if err != nil { + return out, err + } + out.value = valueTerm } - return nil, nil + return out, nil } -// jsonPatchGet goes one step further than jsonPatchTraverse and returns the -// term at the location specified by the path. It is used in functions -// where we want to read a value but not manipulate its parent: for example -// jsonPatchTest and jsonPatchCopy. -// -// Because it uses jsonPatchTraverse, it makes shallow copies of the objects -// along the path. We could possibly add a signaling mechanism that we didn't -// make any changes to avoid this. -func jsonPatchGet(target *ast.Term, path ast.Ref) *ast.Term { - // Special case: get entire document. - if len(path) == 0 { - return target - } +func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { + et := edittree.NewEditTree(source) + for i := 0; i < operations.Len(); i++ { + object, ok := operations.Elem(i).Value.(ast.Object) + if !ok { + return nil, fmt.Errorf("must be an array of JSON-Patch objects, but at least one element is not an object") + } + patch, err := getPatch(object) + if err != nil { + return nil, err + } + path, err := parsePath(patch.path) + if err != nil { + return nil, err + } - _, result := jsonPatchTraverse(target, path, func(parent, key *ast.Term) (*ast.Term, *ast.Term) { - switch v := parent.Value.(type) { - case ast.Object: - return parent, v.Get(key) - case *ast.Array: - i, err := toIndex(v, key) - if err == nil { - return parent, v.Elem(i) + switch patch.op { + case "add": + _, err = et.InsertAtPath(path, patch.value) + if err != nil { + return nil, err } - case ast.Set: - if v.Contains(key) { - return parent, key + case "remove": + _, err = et.DeleteAtPath(path) + if err != nil { + return nil, err } - } - return nil, nil - }) - return result -} - -func jsonPatchAdd(target *ast.Term, path ast.Ref, value *ast.Term) *ast.Term { - // Special case: replacing root document. - if len(path) == 0 { - return value - } - - target, _ = jsonPatchTraverse(target, path, func(parent *ast.Term, key *ast.Term) (*ast.Term, *ast.Term) { - switch original := parent.Value.(type) { - case ast.Object: - obj := ast.NewObject() - original.Foreach(func(k, v *ast.Term) { - obj.Insert(k, v) - }) - obj.Insert(key, value) - return ast.NewTerm(obj), nil - case *ast.Array: - idx, err := toIndex(original, key) - if err != nil || idx < 0 || idx > original.Len() { - return nil, nil + case "replace": + _, err = et.DeleteAtPath(path) + if err != nil { + return nil, err } - arr := ast.NewArray() - for i := 0; i < idx; i++ { - arr = arr.Append(original.Elem(i)) + _, err = et.InsertAtPath(path, patch.value) + if err != nil { + return nil, err } - arr = arr.Append(value) - for i := idx; i < original.Len(); i++ { - arr = arr.Append(original.Elem(i)) + case "move": + from, err := parsePath(patch.from) + if err != nil { + return nil, err } - return ast.NewTerm(arr), nil - case ast.Set: - if !key.Equal(value) { - return nil, nil + chunk, err := et.RenderAtPath(from) + if err != nil { + return nil, err } - set := ast.NewSet() - original.Foreach(func(k *ast.Term) { - set.Add(k) - }) - set.Add(key) - return ast.NewTerm(set), nil - } - return nil, nil - }) - - return target -} - -func jsonPatchRemove(target *ast.Term, path ast.Ref) (*ast.Term, *ast.Term) { - // Special case: replacing root document. - if len(path) == 0 { - return nil, nil - } - - target, removed := jsonPatchTraverse(target, path, func(parent *ast.Term, key *ast.Term) (*ast.Term, *ast.Term) { - var removed *ast.Term - switch original := parent.Value.(type) { - case ast.Object: - obj := ast.NewObject() - original.Foreach(func(k, v *ast.Term) { - if k.Equal(key) { - removed = v - } else { - obj.Insert(k, v) - } - }) - return ast.NewTerm(obj), removed - case *ast.Array: - idx, err := toIndex(original, key) - if err != nil || idx < 0 || idx >= original.Len() { - return nil, nil + _, err = et.DeleteAtPath(from) + if err != nil { + return nil, err } - arr := ast.NewArray() - for i := 0; i < idx; i++ { - arr = arr.Append(original.Elem(i)) + _, err = et.InsertAtPath(path, chunk) + if err != nil { + return nil, err } - removed = original.Elem(idx) - for i := idx + 1; i < original.Len(); i++ { - arr = arr.Append(original.Elem(i)) + case "copy": + from, err := parsePath(patch.from) + if err != nil { + return nil, err + } + chunk, err := et.RenderAtPath(from) + if err != nil { + return nil, err + } + _, err = et.InsertAtPath(path, chunk) + if err != nil { + return nil, err + } + case "test": + chunk, err := et.RenderAtPath(path) + if err != nil { + return nil, err + } + if !chunk.Equal(patch.value) { + return nil, fmt.Errorf("value from EditTree != patch value.\n\nExpected: %v\n\nFound: %v", patch.value, chunk) } - return ast.NewTerm(arr), removed - case ast.Set: - set := ast.NewSet() - original.Foreach(func(k *ast.Term) { - if k.Equal(key) { - removed = k - } else { - set.Add(k) - } - }) - return ast.NewTerm(set), removed } - return nil, nil - }) - - if target != nil && removed != nil { - return target, removed - } - - return nil, nil -} - -func jsonPatchReplace(target *ast.Term, path ast.Ref, value *ast.Term) *ast.Term { - // Special case: replacing the whole document. - if len(path) == 0 { - return value } - - // Replace is specified as `remove` followed by `add`. - if target, _ = jsonPatchRemove(target, path); target == nil { - return nil - } - - return jsonPatchAdd(target, path, value) -} - -func jsonPatchMove(target *ast.Term, path ast.Ref, from ast.Ref) *ast.Term { - // Move is specified as `remove` followed by `add`. - target, removed := jsonPatchRemove(target, from) - if target == nil || removed == nil { - return nil - } - - return jsonPatchAdd(target, path, removed) -} - -func jsonPatchCopy(target *ast.Term, path ast.Ref, from ast.Ref) *ast.Term { - value := jsonPatchGet(target, from) - if value == nil { - return nil - } - - return jsonPatchAdd(target, path, value) -} - -func jsonPatchTest(target *ast.Term, path ast.Ref, value *ast.Term) *ast.Term { - actual := jsonPatchGet(target, path) - if actual == nil { - return nil - } - - if actual.Equal(value) { - return target - } - - return nil + final := et.Render() + // TODO: Nil check here? + return final, nil } func builtinJSONPatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -533,93 +391,11 @@ func builtinJSONPatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter return err } - // Apply operations one by one. - for i := 0; i < operations.Len(); i++ { - if object, ok := operations.Elem(i).Value.(ast.Object); ok { - getAttribute := func(attr string) (*ast.Term, error) { - if term := object.Get(ast.StringTerm(attr)); term != nil { - return term, nil - } - - return nil, builtins.NewOperandErr(2, fmt.Sprintf("patch is missing '%s' attribute", attr)) - } - - getPathAttribute := func(attr string) (ast.Ref, error) { - term, err := getAttribute(attr) - if err != nil { - return ast.Ref{}, err - } - path, err := parsePath(term) - if err != nil { - return ast.Ref{}, err - } - return path, nil - } - - // Parse operation. - opTerm, err := getAttribute("op") - if err != nil { - return err - } - op, ok := opTerm.Value.(ast.String) - if !ok { - return builtins.NewOperandErr(2, "patch attribute 'op' must be a string") - } - - // Parse path. - path, err := getPathAttribute("path") - if err != nil { - return err - } - - switch op { - case "add": - value, err := getAttribute("value") - if err != nil { - return err - } - target = jsonPatchAdd(target, path, value) - case "remove": - target, _ = jsonPatchRemove(target, path) - case "replace": - value, err := getAttribute("value") - if err != nil { - return err - } - target = jsonPatchReplace(target, path, value) - case "move": - from, err := getPathAttribute("from") - if err != nil { - return err - } - target = jsonPatchMove(target, path, from) - case "copy": - from, err := getPathAttribute("from") - if err != nil { - return err - } - target = jsonPatchCopy(target, path, from) - case "test": - value, err := getAttribute("value") - if err != nil { - return err - } - target = jsonPatchTest(target, path, value) - default: - return builtins.NewOperandErr(2, "must be an array of JSON-Patch objects") - } - } else { - return builtins.NewOperandErr(2, "must be an array of JSON-Patch objects") - } - - // JSON patches should work atomically; and if one of them fails, - // we should not try to continue. - if target == nil { - return nil - } + patched, err := applyPatches(target, operations) + if err != nil { + return nil } - - return iter(target) + return iter(patched) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go b/vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go new file mode 100644 index 00000000000..f44398f1e70 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/topdown/jsonschema.go @@ -0,0 +1,109 @@ +// Copyright 2022 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package topdown + +import ( + "encoding/json" + "errors" + + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/internal/gojsonschema" +) + +// astValueToJSONSchemaLoader converts a value to JSON Loader. +// Value can be ast.String or ast.Object. +func astValueToJSONSchemaLoader(value ast.Value) (gojsonschema.JSONLoader, error) { + var loader gojsonschema.JSONLoader + var err error + + // ast.Value type selector. + switch x := value.(type) { + case ast.String: + // In case of string pass it as is as a raw JSON string. + // Make pre-check that it's a valid JSON at all because gojsonschema won't do that. + if !json.Valid([]byte(x)) { + return nil, errors.New("invalid JSON string") + } + loader = gojsonschema.NewStringLoader(string(x)) + case ast.Object: + // In case of object serialize it to JSON representation. + var data interface{} + data, err = ast.JSON(value) + if err != nil { + return nil, err + } + loader = gojsonschema.NewGoLoader(data) + default: + // Any other cases will produce an error. + return nil, errors.New("wrong type, expected string or object") + } + + return loader, nil +} + +func newResultTerm(valid bool, data *ast.Term) *ast.Term { + return ast.ArrayTerm(ast.BooleanTerm(valid), data) +} + +// builtinJSONSchemaVerify accepts 1 argument which can be string or object and checks if it is valid JSON schema. +// Returns array [false, ] with error string at index 1, or [true, ""] with empty string at index 1 otherwise. +func builtinJSONSchemaVerify(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + // Take first argument and make JSON Loader from it. + loader, err := astValueToJSONSchemaLoader(operands[0].Value) + if err != nil { + return iter(newResultTerm(false, ast.StringTerm("jsonschema: "+err.Error()))) + } + + // Check that schema is correct and parses without errors. + if _, err = gojsonschema.NewSchema(loader); err != nil { + return iter(newResultTerm(false, ast.StringTerm("jsonschema: "+err.Error()))) + } + + return iter(newResultTerm(true, ast.NullTerm())) +} + +// builtinJSONMatchSchema accepts 2 arguments both can be string or object and verifies if the document matches the JSON schema. +// Returns an array where first element is a boolean indicating a successful match, and the second is an array of errors that is empty on success and populated on failure. +// In case of internal error returns empty array. +func builtinJSONMatchSchema(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + // Take first argument and make JSON Loader from it. + // This is a JSON document made from Rego JSON string or object. + documentLoader, err := astValueToJSONSchemaLoader(operands[0].Value) + if err != nil { + return err + } + + // Take second argument and make JSON Loader from it. + // This is a JSON schema made from Rego JSON string or object. + schemaLoader, err := astValueToJSONSchemaLoader(operands[1].Value) + if err != nil { + return err + } + + // Use schema to validate document. + result, err := gojsonschema.Validate(schemaLoader, documentLoader) + if err != nil { + return err + } + + // In case of validation errors produce Rego array of objects to describe the errors. + arr := ast.NewArray() + for _, re := range result.Errors() { + o := ast.NewObject( + [...]*ast.Term{ast.StringTerm("error"), ast.StringTerm(re.String())}, + [...]*ast.Term{ast.StringTerm("type"), ast.StringTerm(re.Type())}, + [...]*ast.Term{ast.StringTerm("field"), ast.StringTerm(re.Field())}, + [...]*ast.Term{ast.StringTerm("desc"), ast.StringTerm(re.Description())}, + ) + arr = arr.Append(ast.NewTerm(o)) + } + + return iter(newResultTerm(result.Valid(), ast.NewTerm(arr))) +} + +func init() { + RegisterBuiltinFunc(ast.JSONSchemaVerify.Name, builtinJSONSchemaVerify) + RegisterBuiltinFunc(ast.JSONMatchSchema.Name, builtinJSONMatchSchema) +} diff --git a/vendor/github.com/open-policy-agent/opa/topdown/numbers.go b/vendor/github.com/open-policy-agent/opa/topdown/numbers.go index b0953b0fdbc..27f3156b8ad 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/numbers.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/numbers.go @@ -28,32 +28,71 @@ func builtinNumbersRange(bctx BuiltinContext, operands []*ast.Term, iter func(*a return err } - result := ast.NewArray() + ast, err := generateRange(bctx, x, y, one, "numbers.range") + if err != nil { + return err + } + + return iter(ast) +} + +func builtinNumbersRangeStep(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + + x, err := builtins.BigIntOperand(operands[0].Value, 1) + if err != nil { + return err + } + + y, err := builtins.BigIntOperand(operands[1].Value, 2) + if err != nil { + return err + } + + step, err := builtins.BigIntOperand(operands[2].Value, 3) + if err != nil { + return err + } + + if step.Cmp(big.NewInt(0)) <= 0 { + return fmt.Errorf("numbers.range_step: step must be a positive number above zero") + } + + ast, err := generateRange(bctx, x, y, step, "numbers.range_step") + if err != nil { + return err + } + + return iter(ast) +} + +func generateRange(bctx BuiltinContext, x *big.Int, y *big.Int, step *big.Int, funcName string) (*ast.Term, error) { + cmp := x.Cmp(y) + + comp := func(i *big.Int, y *big.Int) bool { return i.Cmp(y) <= 0 } + iter := func(i *big.Int) *big.Int { return i.Add(i, step) } + + if cmp > 0 { + comp = func(i *big.Int, y *big.Int) bool { return i.Cmp(y) >= 0 } + iter = func(i *big.Int) *big.Int { return i.Sub(i, step) } + } + + result := ast.NewArray() haltErr := Halt{ Err: &Error{ Code: CancelErr, - Message: "numbers.range: timed out before generating all numbers in range", + Message: fmt.Sprintf("%s: timed out before generating all numbers in range", funcName), }, } - if cmp <= 0 { - for i := new(big.Int).Set(x); i.Cmp(y) <= 0; i = i.Add(i, one) { - if bctx.Cancel != nil && bctx.Cancel.Cancelled() { - return haltErr - } - result = result.Append(ast.NewTerm(builtins.IntToNumber(i))) - } - } else { - for i := new(big.Int).Set(x); i.Cmp(y) >= 0; i = i.Sub(i, one) { - if bctx.Cancel != nil && bctx.Cancel.Cancelled() { - return haltErr - } - result = result.Append(ast.NewTerm(builtins.IntToNumber(i))) + for i := new(big.Int).Set(x); comp(i, y); i = iter(i) { + if bctx.Cancel != nil && bctx.Cancel.Cancelled() { + return nil, haltErr } + result = result.Append(ast.NewTerm(builtins.IntToNumber(i))) } - return iter(ast.NewTerm(result)) + return ast.NewTerm(result), nil } func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -95,5 +134,6 @@ func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T func init() { RegisterBuiltinFunc(ast.NumbersRange.Name, builtinNumbersRange) + RegisterBuiltinFunc(ast.NumbersRangeStep.Name, builtinNumbersRangeStep) RegisterBuiltinFunc(ast.RandIntn.Name, builtinRandIntn) } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/object.go b/vendor/github.com/open-policy-agent/opa/topdown/object.go index e3baf1fecce..ba5d77ff371 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/object.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/object.go @@ -200,7 +200,16 @@ func mergewithOverwriteInPlace(obj, other ast.Object, frozenKeys map[*ast.Term]s v2 := obj.Get(k) // The key didn't exist in other, keep the original value. if v2 == nil { - obj.Insert(k, v) + nestedObj, ok := v.Value.(ast.Object) + if !ok { + // v is not an object + obj.Insert(k, v) + } else { + // Copy the nested object so the original object would not be modified + nestedObjCopy := nestedObj.Copy() + obj.Insert(k, ast.NewTerm(nestedObjCopy)) + } + return } // The key exists in both. Merge or reject change. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/providers.go b/vendor/github.com/open-policy-agent/opa/topdown/providers.go index 8d988eab2c3..0b9e012268f 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/providers.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/providers.go @@ -7,11 +7,10 @@ package topdown import ( "encoding/json" "net/url" - "strings" "time" "github.com/open-policy-agent/opa/ast" - "github.com/open-policy-agent/opa/internal/providers" + "github.com/open-policy-agent/opa/internal/providers/aws" "github.com/open-policy-agent/opa/topdown/builtins" ) @@ -54,7 +53,7 @@ func getReqBodyBytes(body, rawBody *ast.Term) ([]byte, error) { } func objectToMap(o ast.Object) map[string][]string { - var out map[string][]string + out := make(map[string][]string, o.Len()) o.Foreach(func(k, v *ast.Term) { ks := stringFromTerm(k) vs := stringFromTerm(v) @@ -105,7 +104,7 @@ func builtinAWSSigV4SignReq(ctx BuiltinContext, operands []*ast.Term, iter func( return err } service := stringFromTerm(awsConfigObj.Get(ast.StringTerm("aws_service"))) - awsCreds := providers.AWSCredentialsFromObject(awsConfigObj) + awsCreds := aws.CredentialsFromObject(awsConfigObj) // Timestamp for signing. var signingTimestamp time.Time @@ -173,10 +172,11 @@ func builtinAWSSigV4SignReq(ctx BuiltinContext, operands []*ast.Term, iter func( } // Sign the request object's headers, and reconstruct the headers map. - signedHeadersMap := providers.AWSSignV4(objectToMap(headers), method, theURL, body, service, awsCreds, signingTimestamp) + authHeader, signedHeadersMap := aws.SignV4(objectToMap(headers), method, theURL, body, service, awsCreds, signingTimestamp) signedHeadersObj := ast.NewObject() + signedHeadersObj.Insert(ast.StringTerm("Authorization"), ast.StringTerm(authHeader)) for k, v := range signedHeadersMap { - signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(strings.Join(v, ","))) + signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(v)) } // Create new request object with updated headers. diff --git a/vendor/github.com/open-policy-agent/opa/topdown/query.go b/vendor/github.com/open-policy-agent/opa/topdown/query.go index 462463019a0..2b540c58a51 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/query.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/query.go @@ -54,6 +54,7 @@ type Query struct { interQueryBuiltinCache cache.InterQueryCache ndBuiltinCache builtins.NDBCache strictBuiltinErrors bool + builtinErrorList *[]Error strictObjects bool printHook print.Hook tracingOpts tracing.Options @@ -256,6 +257,14 @@ func (q *Query) WithStrictBuiltinErrors(yes bool) *Query { return q } +// WithBuiltinErrorList supplies a pointer to an Error slice to store built-in function errors +// encountered during evaluation. This error slice can be inspected after evaluation to determine +// which built-in function errors occurred. +func (q *Query) WithBuiltinErrorList(list *[]Error) *Query { + q.builtinErrorList = list + return q +} + // WithResolver configures an external resolver to use for the given ref. func (q *Query) WithResolver(ref ast.Ref, r resolver.Resolver) *Query { q.external.Put(ref, r) @@ -419,8 +428,25 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support [] support = e.saveSupport.List() - if q.strictBuiltinErrors && len(e.builtinErrors.errs) > 0 { - err = e.builtinErrors.errs[0] + if len(e.builtinErrors.errs) > 0 { + if q.strictBuiltinErrors { + err = e.builtinErrors.errs[0] + } else if q.builtinErrorList != nil { + // If a builtinErrorList has been supplied, we must use pointer indirection + // to append to it. builtinErrorList is a slice pointer so that errors can be + // appended to it without returning a new slice and changing the interface + // of PartialRun. + for _, err := range e.builtinErrors.errs { + if tdError, ok := err.(*Error); ok { + *(q.builtinErrorList) = append(*(q.builtinErrorList), *tdError) + } else { + *(q.builtinErrorList) = append(*(q.builtinErrorList), Error{ + Code: BuiltinErr, + Message: err.Error(), + }) + } + } + } } for i := range support { @@ -445,6 +471,14 @@ func (q *Query) Run(ctx context.Context) (QueryResultSet, error) { // Iter executes the query and invokes the iter function with query results // produced by evaluating the query. func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error { + // Query evaluation must not be allowed if the compiler has errors and is in an undefined, possibly inconsistent state + if q.compiler != nil && len(q.compiler.Errors) > 0 { + return &Error{ + Code: InternalErr, + Message: "compiler has errors", + } + } + if q.seed == nil { q.seed = rand.Reader } @@ -504,8 +538,25 @@ func (q *Query) Iter(ctx context.Context, iter func(QueryResult) error) error { return iter(qr) }) - if q.strictBuiltinErrors && err == nil && len(e.builtinErrors.errs) > 0 { - err = e.builtinErrors.errs[0] + if len(e.builtinErrors.errs) > 0 { + if q.strictBuiltinErrors { + err = e.builtinErrors.errs[0] + } else if q.builtinErrorList != nil { + // If a builtinErrorList has been supplied, we must use pointer indirection + // to append to it. builtinErrorList is a slice pointer so that errors can be + // appended to it without returning a new slice and changing the interface + // of Iter. + for _, err := range e.builtinErrors.errs { + if tdError, ok := err.(*Error); ok { + *(q.builtinErrorList) = append(*(q.builtinErrorList), *tdError) + } else { + *(q.builtinErrorList) = append(*(q.builtinErrorList), Error{ + Code: BuiltinErr, + Message: err.Error(), + }) + } + } + } } q.metrics.Timer(metrics.RegoQueryEval).Stop() diff --git a/vendor/github.com/open-policy-agent/opa/topdown/regex.go b/vendor/github.com/open-policy-agent/opa/topdown/regex.go index b1902a5e7b5..aa818f2dc99 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/regex.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/regex.go @@ -46,7 +46,7 @@ func builtinRegexMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te if err != nil { return err } - return iter(ast.BooleanTerm(re.Match([]byte(s2)))) + return iter(ast.BooleanTerm(re.MatchString(string(s2)))) } func builtinRegexMatchTemplate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/topdown/subset.go b/vendor/github.com/open-policy-agent/opa/topdown/subset.go index 19c6571c024..7b152a5ef97 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/subset.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/subset.go @@ -193,12 +193,12 @@ func arraySubset(super, sub *ast.Array) bool { return true } - if superCursor == super.Len() { + if superCursor+subCursor == super.Len() { return false } subElem := sub.Elem(subCursor) - superElem := sub.Elem(superCursor + subCursor) + superElem := super.Elem(superCursor + subCursor) if superElem == nil { return false } diff --git a/vendor/github.com/open-policy-agent/opa/topdown/time.go b/vendor/github.com/open-policy-agent/opa/topdown/time.go index bcaa1c55f6c..ba3efc75dc0 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/time.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/time.go @@ -12,6 +12,7 @@ import ( "strconv" "sync" "time" + _ "time/tzdata" // this is needed to have LoadLocation when no filesystem tzdata is available "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/topdown/builtins" @@ -49,7 +50,13 @@ func builtinTimeParseNanos(_ BuiltinContext, operands []*ast.Term, iter func(*as return err } - result, err := time.Parse(string(format), string(value)) + formatStr := string(format) + // look for the formatStr in our acceptedTimeFormats and + // use the constant instead if it matches + if f, ok := acceptedTimeFormats[formatStr]; ok { + formatStr = f + } + result, err := time.Parse(formatStr, string(value)) if err != nil { return err } @@ -82,8 +89,40 @@ func builtinParseDurationNanos(_ BuiltinContext, operands []*ast.Term, iter func return iter(ast.NumberTerm(int64ToJSONNumber(int64(value)))) } +// Represent exposed constants for formatting from the stdlib time pkg +var acceptedTimeFormats = map[string]string{ + "ANSIC": time.ANSIC, + "UnixDate": time.UnixDate, + "RubyDate": time.RubyDate, + "RFC822": time.RFC822, + "RFC822Z": time.RFC822Z, + "RFC850": time.RFC850, + "RFC1123": time.RFC1123, + "RFC1123Z": time.RFC1123Z, + "RFC3339": time.RFC3339, + "RFC3339Nano": time.RFC3339Nano, +} + +func builtinFormat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + t, layout, err := tzTime(operands[0].Value) + if err != nil { + return err + } + // Using RFC3339Nano time formatting as default + if layout == "" { + layout = time.RFC3339Nano + } else if layoutStr, ok := acceptedTimeFormats[layout]; ok { + // if we can find a constant specified, use the constant + layout = layoutStr + } + // otherwise try to treat the fmt string as a datetime fmt string + + timestamp := t.Format(layout) + return iter(ast.StringTerm(timestamp)) +} + func builtinDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - t, err := tzTime(operands[0].Value) + t, _, err := tzTime(operands[0].Value) if err != nil { return err } @@ -93,7 +132,7 @@ func builtinDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er } func builtinClock(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - t, err := tzTime(operands[0].Value) + t, _, err := tzTime(operands[0].Value) if err != nil { return err } @@ -103,7 +142,7 @@ func builtinClock(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e } func builtinWeekday(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - t, err := tzTime(operands[0].Value) + t, _, err := tzTime(operands[0].Value) if err != nil { return err } @@ -112,7 +151,7 @@ func builtinWeekday(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } func builtinAddDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - t, err := tzTime(operands[0].Value) + t, _, err := tzTime(operands[0].Value) if err != nil { return err } @@ -138,11 +177,11 @@ func builtinAddDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } func builtinDiff(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - t1, err := tzTime(operands[0].Value) + t1, _, err := tzTime(operands[0].Value) if err != nil { return err } - t2, err := tzTime(operands[1].Value) + t2, _, err := tzTime(operands[1].Value) if err != nil { return err } @@ -203,25 +242,25 @@ func builtinDiff(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er ast.IntNumberTerm(hour), ast.IntNumberTerm(min), ast.IntNumberTerm(sec))) } -func tzTime(a ast.Value) (t time.Time, err error) { +func tzTime(a ast.Value) (t time.Time, lay string, err error) { var nVal ast.Value loc := time.UTC - + layout := "" switch va := a.(type) { case *ast.Array: if va.Len() == 0 { - return time.Time{}, builtins.NewOperandTypeErr(1, a, "either number (ns) or [number (ns), string (tz)]") + return time.Time{}, layout, builtins.NewOperandTypeErr(1, a, "either number (ns) or [number (ns), string (tz)]") } nVal, err = builtins.NumberOperand(va.Elem(0).Value, 1) if err != nil { - return time.Time{}, err + return time.Time{}, layout, err } if va.Len() > 1 { tzVal, err := builtins.StringOperand(va.Elem(1).Value, 1) if err != nil { - return time.Time{}, err + return time.Time{}, layout, err } tzName := string(tzVal) @@ -243,7 +282,7 @@ func tzTime(a ast.Value) (t time.Time, err error) { loc, err = time.LoadLocation(tzName) if err != nil { tzCacheMutex.Unlock() - return time.Time{}, err + return time.Time{}, layout, err } tzCache[tzName] = loc } @@ -251,27 +290,35 @@ func tzTime(a ast.Value) (t time.Time, err error) { } } + if va.Len() > 2 { + lay, err := builtins.StringOperand(va.Elem(2).Value, 1) + if err != nil { + return time.Time{}, layout, err + } + layout = string(lay) + } + case ast.Number: nVal = a default: - return time.Time{}, builtins.NewOperandTypeErr(1, a, "either number (ns) or [number (ns), string (tz)]") + return time.Time{}, layout, builtins.NewOperandTypeErr(1, a, "either number (ns) or [number (ns), string (tz)]") } value, err := builtins.NumberOperand(nVal, 1) if err != nil { - return time.Time{}, err + return time.Time{}, layout, err } f := builtins.NumberToFloat(value) i64, acc := f.Int64() if acc != big.Exact { - return time.Time{}, fmt.Errorf("timestamp too big") + return time.Time{}, layout, fmt.Errorf("timestamp too big") } t = time.Unix(0, i64).In(loc) - return t, nil + return t, layout, nil } func int64ToJSONNumber(i int64) json.Number { @@ -283,6 +330,7 @@ func init() { RegisterBuiltinFunc(ast.ParseRFC3339Nanos.Name, builtinTimeParseRFC3339Nanos) RegisterBuiltinFunc(ast.ParseNanos.Name, builtinTimeParseNanos) RegisterBuiltinFunc(ast.ParseDurationNanos.Name, builtinParseDurationNanos) + RegisterBuiltinFunc(ast.Format.Name, builtinFormat) RegisterBuiltinFunc(ast.Date.Name, builtinDate) RegisterBuiltinFunc(ast.Clock.Name, builtinClock) RegisterBuiltinFunc(ast.Weekday.Name, builtinWeekday) diff --git a/vendor/github.com/open-policy-agent/opa/topdown/tokens.go b/vendor/github.com/open-policy-agent/opa/topdown/tokens.go index 0134e820751..b69f3f2d24a 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/tokens.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/tokens.go @@ -1065,6 +1065,8 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func if constraints.iss != issVal { return iter(unverified) } + } else { + return iter(unverified) } } // RFC7159 4.1.3 aud diff --git a/vendor/github.com/open-policy-agent/opa/topdown/uuid.go b/vendor/github.com/open-policy-agent/opa/topdown/uuid.go index 2fdbd369833..d3a7a5f900c 100644 --- a/vendor/github.com/open-policy-agent/opa/topdown/uuid.go +++ b/vendor/github.com/open-policy-agent/opa/topdown/uuid.go @@ -7,6 +7,7 @@ package topdown import ( "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/internal/uuid" + "github.com/open-policy-agent/opa/topdown/builtins" ) type uuidCachingKey string @@ -31,6 +32,25 @@ func builtinUUIDRFC4122(bctx BuiltinContext, operands []*ast.Term, iter func(*as return iter(result) } +func builtinUUIDParse(_ BuiltinContext, operands []*ast.Term, iter func(term *ast.Term) error) error { + str, err := builtins.StringOperand(operands[0].Value, 1) + if err != nil { + return err + } + + parsed, err := uuid.Parse(string(str)) + if err != nil { + return nil + } + val, err := ast.InterfaceToValue(parsed) + if err != nil { + return err + } + + return iter(ast.NewTerm(val)) +} + func init() { RegisterBuiltinFunc(ast.UUIDRFC4122.Name, builtinUUIDRFC4122) + RegisterBuiltinFunc(ast.UUIDParse.Name, builtinUUIDParse) } diff --git a/vendor/github.com/open-policy-agent/opa/types/types.go b/vendor/github.com/open-policy-agent/opa/types/types.go index bab53f9e091..a4b87cd5540 100644 --- a/vendor/github.com/open-policy-agent/opa/types/types.go +++ b/vendor/github.com/open-policy-agent/opa/types/types.go @@ -48,6 +48,8 @@ func NewNull() Null { return Null{} } +// NamedType represents a type alias with an arbitrary name and description. +// This is useful for generating documentation for built-in functions. type NamedType struct { Name, Descr string Type Type @@ -77,6 +79,9 @@ func (n *NamedType) Description(d string) *NamedType { return n } +// Named returns the passed type as a named type. +// Named types are only valid at the top level of built-in functions. +// Note that nested named types cause panic. func Named(name string, t Type) *NamedType { return &NamedType{ Type: t, @@ -209,7 +214,7 @@ func (t *Array) String() string { for _, tpe := range t.static { buf = append(buf, Sprint(tpe)) } - var repr = prefix + repr := prefix if len(buf) > 0 { repr += "<" + strings.Join(buf, ", ") + ">" } @@ -254,6 +259,10 @@ func NewSet(of Type) *Set { } } +func (t *Set) Of() Type { + return t.of +} + // MarshalJSON returns the JSON encoding of t. func (t *Set) MarshalJSON() ([]byte, error) { return json.Marshal(t.toMap()) @@ -346,7 +355,7 @@ func (t *Object) String() string { for _, p := range t.static { buf = append(buf, fmt.Sprintf("%v: %v", p.Key, Sprint(p.Value))) } - var repr = prefix + repr := prefix if len(buf) > 0 { repr += "<" + strings.Join(buf, ", ") + ">" } @@ -403,7 +412,6 @@ func (t *Object) toMap() map[string]interface{} { // Select returns the type of the named property. func (t *Object) Select(name interface{}) Type { - pos := sort.Search(len(t.static), func(x int) bool { return util.Compare(t.static[x].Key, name) >= 0 }) @@ -421,6 +429,77 @@ func (t *Object) Select(name interface{}) Type { return nil } +func (t *Object) Merge(other Type) *Object { + if otherObj, ok := other.(*Object); ok { + return mergeObjects(t, otherObj) + } + + var typeK Type + var typeV Type + dynProps := t.DynamicProperties() + if dynProps != nil { + typeK = Or(Keys(other), dynProps.Key) + typeV = Or(Values(other), dynProps.Value) + dynProps = NewDynamicProperty(typeK, typeV) + } else { + typeK = Keys(other) + typeV = Values(other) + if typeK != nil && typeV != nil { + dynProps = NewDynamicProperty(typeK, typeV) + } + } + + return NewObject(t.StaticProperties(), dynProps) +} + +func mergeObjects(a, b *Object) *Object { + var dynamicProps *DynamicProperty + if a.dynamic != nil && b.dynamic != nil { + typeK := Or(a.dynamic.Key, b.dynamic.Key) + var typeV Type + aObj, aIsObj := a.dynamic.Value.(*Object) + bObj, bIsObj := b.dynamic.Value.(*Object) + if aIsObj && bIsObj { + typeV = mergeObjects(aObj, bObj) + } else { + typeV = Or(a.dynamic.Value, b.dynamic.Value) + } + dynamicProps = NewDynamicProperty(typeK, typeV) + } else if a.dynamic != nil { + dynamicProps = a.dynamic + } else { + dynamicProps = b.dynamic + } + + staticPropsMap := make(map[interface{}]Type) + + for _, sp := range a.static { + staticPropsMap[sp.Key] = sp.Value + } + + for _, sp := range b.static { + currV := staticPropsMap[sp.Key] + if currV != nil { + currVObj, currVIsObj := currV.(*Object) + spVObj, spVIsObj := sp.Value.(*Object) + if currVIsObj && spVIsObj { + staticPropsMap[sp.Key] = mergeObjects(currVObj, spVObj) + } else { + staticPropsMap[sp.Key] = Or(currV, sp.Value) + } + } else { + staticPropsMap[sp.Key] = sp.Value + } + } + + staticProps := make([]*StaticProperty, 0, len(staticPropsMap)) + for k, v := range staticPropsMap { + staticProps = append(staticProps, NewStaticProperty(k, v)) + } + + return NewObject(staticProps, dynamicProps) +} + // Any represents a dynamic type. type Any []Type @@ -486,22 +565,73 @@ func (t Any) Merge(other Type) Any { } // Union returns a new Any type that is the union of the two Any types. +// Note(philipc): The two Any slices MUST be sorted before running Union, +// or else this method will fail to merge the two slices correctly. func (t Any) Union(other Any) Any { - if len(t) == 0 { + lenT := len(t) + lenOther := len(other) + // Return the more general (blank) Any type if present. + if lenT == 0 { return t } - if len(other) == 0 { + if lenOther == 0 { return other } - cpy := make(Any, len(t)) - copy(cpy, t) - for i := range other { - if !cpy.Contains(other[i]) { - cpy = append(cpy, other[i]) + // Prealloc the output list. + maxLen := lenT + if lenT < lenOther { + maxLen = lenOther + } + merged := make(Any, 0, maxLen) + // Note(philipc): Create a merged slice, doing the minimum number of + // comparisons along the way. We treat this as a problem of merging two + // sorted lists that might have duplicates. This specifically saves us + // from cases where one list might be *much* longer than the other. + // Algorithm: + // Assume: + // - List A + // - List B + // - List Output + // - Idx_a, Idx_b + // Procedure: + // - While Idx_a < len(A) and Idx_b < len(B) + // - Compare head(A) and head(B) + // - Cases: + // - A < B: Append head(A) to Output, advance Idx_a + // - A == B: Append head(A) to Output, advance Idx_a, Idx_b + // - A > B: Append head(B) to Output, advance Idx_b + // - Return output + idxA := 0 + idxB := 0 + for idxA < lenT || idxB < lenOther { + // Early-exit cases: + if idxA == lenT { + // Ran out of elements in t. Copy over what's left from other. + merged = append(merged, other[idxB:]...) + break + } else if idxB == lenOther { + // Ran out of elements in other. Copy over what's left from t. + merged = append(merged, t[idxA:]...) + break + } + // Normal selection of next element to merge: + switch Compare(t[idxA], other[idxB]) { + // A < B: + case -1: + merged = append(merged, t[idxA]) + idxA++ + // A == B: + case 0: + merged = append(merged, t[idxA]) + idxA++ + idxB++ + // A > B: + case 1: + merged = append(merged, other[idxB]) + idxB++ } } - sort.Sort(typeSlice(cpy)) - return cpy + return merged } func (t Any) String() string { @@ -626,7 +756,6 @@ func (t *Function) MarshalJSON() ([]byte, error) { // UnmarshalJSON decodes the JSON serialized function declaration. func (t *Function) UnmarshalJSON(bs []byte) error { - tpe, err := Unmarshal(bs) if err != nil { return err diff --git a/vendor/github.com/open-policy-agent/opa/util/backoff.go b/vendor/github.com/open-policy-agent/opa/util/backoff.go index 944b5728057..6fbf63ef773 100644 --- a/vendor/github.com/open-policy-agent/opa/util/backoff.go +++ b/vendor/github.com/open-policy-agent/opa/util/backoff.go @@ -15,7 +15,9 @@ func init() { // a call to rand.Seed() we'd get the same stream of numbers for each program // run. (Or not, if some other packages happens to seed the global randomness // source.) - rand.Seed(time.Now().UnixNano()) + // Note(philipc): rand.Seed() was deprecated in Go 1.20, so we've switched to + // using the recommended rand.New(rand.NewSource(seed)) style. + rand.New(rand.NewSource(time.Now().UnixNano())) } // DefaultBackoff returns a delay with an exponential backoff based on the diff --git a/vendor/github.com/open-policy-agent/opa/util/json.go b/vendor/github.com/open-policy-agent/opa/util/json.go index 283c496973b..4f1e14513f9 100644 --- a/vendor/github.com/open-policy-agent/opa/util/json.go +++ b/vendor/github.com/open-policy-agent/opa/util/json.go @@ -11,7 +11,9 @@ import ( "io" "reflect" - "github.com/ghodss/yaml" + "sigs.k8s.io/yaml" + + "github.com/open-policy-agent/opa/loader/extension" ) // UnmarshalJSON parses the JSON encoded data and stores the result in the value @@ -19,10 +21,17 @@ import ( // // This function is intended to be used in place of the standard json.Marshal // function when json.Number is required. -func UnmarshalJSON(bs []byte, x interface{}) (err error) { +func UnmarshalJSON(bs []byte, x interface{}) error { + return unmarshalJSON(bs, x, true) +} + +func unmarshalJSON(bs []byte, x interface{}, ext bool) error { buf := bytes.NewBuffer(bs) decoder := NewJSONDecoder(buf) if err := decoder.Decode(x); err != nil { + if handler := extension.FindExtension(".json"); handler != nil && ext { + return handler(bs, x) + } return err } @@ -103,14 +112,18 @@ func Reference(x interface{}) *interface{} { return &x } -// Unmarshal decodes a YAML or JSON value into the specified type. +// Unmarshal decodes a YAML, JSON or JSON extension value into the specified type. func Unmarshal(bs []byte, v interface{}) error { if json.Valid(bs) { - return UnmarshalJSON(bs, v) + return unmarshalJSON(bs, v, false) } - bs, err := yaml.YAMLToJSON(bs) - if err != nil { - return err + nbs, err := yaml.YAMLToJSON(bs) + if err == nil { + return unmarshalJSON(nbs, v, false) + } + // not json or yaml: try extensions + if handler := extension.FindExtension(".json"); handler != nil { + return handler(bs, v) } - return UnmarshalJSON(bs, v) + return err } diff --git a/vendor/github.com/open-policy-agent/opa/version/version.go b/vendor/github.com/open-policy-agent/opa/version/version.go index 92939524097..56770e4e67a 100644 --- a/vendor/github.com/open-policy-agent/opa/version/version.go +++ b/vendor/github.com/open-policy-agent/opa/version/version.go @@ -7,10 +7,11 @@ package version import ( "runtime" + "runtime/debug" ) // Version is the canonical version of OPA. -var Version = "0.47.2" +var Version = "0.57.1" // GoVersion is the version of Go this was built with var GoVersion = runtime.Version() @@ -25,3 +26,24 @@ var ( Timestamp = "" Hostname = "" ) + +func init() { + bi, ok := debug.ReadBuildInfo() + if !ok { + return + } + dirty := false + for _, s := range bi.Settings { + switch s.Key { + case "vcs.time": + Timestamp = s.Value + case "vcs.revision": + Vcs = s.Value + case "vcs.modified": + dirty = s.Value == "true" + } + } + if dirty { + Vcs = Vcs + "-dirty" + } +} diff --git a/vendor/github.com/open-policy-agent/opa/version/version_go1.18.go b/vendor/github.com/open-policy-agent/opa/version/version_go1.18.go index 8c02ca49d2a..aa6eec85562 100644 --- a/vendor/github.com/open-policy-agent/opa/version/version_go1.18.go +++ b/vendor/github.com/open-policy-agent/opa/version/version_go1.18.go @@ -6,28 +6,3 @@ // +build go1.18 package version - -import ( - "runtime/debug" -) - -func init() { - bi, ok := debug.ReadBuildInfo() - if !ok { - return - } - dirty := false - for _, s := range bi.Settings { - switch s.Key { - case "vcs.time": - Timestamp = s.Value - case "vcs.revision": - Vcs = s.Value - case "vcs.modified": - dirty = s.Value == "true" - } - } - if dirty { - Vcs = Vcs + "-dirty" - } -} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go index 6f9e6fd3abf..581cf7cdfad 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go @@ -59,13 +59,4 @@ const ( // AnnotationBaseImageName is the annotation key for the image reference of the image's base image. AnnotationBaseImageName = "org.opencontainers.image.base.name" - - // AnnotationArtifactCreated is the annotation key for the date and time on which the artifact was built, conforming to RFC 3339. - AnnotationArtifactCreated = "org.opencontainers.artifact.created" - - // AnnotationArtifactDescription is the annotation key for the human readable description for the artifact. - AnnotationArtifactDescription = "org.opencontainers.artifact.description" - - // AnnotationReferrersFiltersApplied is the annotation key for the comma separated list of filters applied by the registry in the referrers listing. - AnnotationReferrersFiltersApplied = "org.opencontainers.referrers.filtersApplied" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go deleted file mode 100644 index 03d76ce437a..00000000000 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/artifact.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2022 The Linux Foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v1 - -// Artifact describes an artifact manifest. -// This structure provides `application/vnd.oci.artifact.manifest.v1+json` mediatype when marshalled to JSON. -type Artifact struct { - // MediaType is the media type of the object this schema refers to. - MediaType string `json:"mediaType"` - - // ArtifactType is the IANA media type of the artifact this schema refers to. - ArtifactType string `json:"artifactType"` - - // Blobs is a collection of blobs referenced by this manifest. - Blobs []Descriptor `json:"blobs,omitempty"` - - // Subject (reference) is an optional link from the artifact to another manifest forming an association between the artifact and the other manifest. - Subject *Descriptor `json:"subject,omitempty"` - - // Annotations contains arbitrary metadata for the artifact manifest. - Annotations map[string]string `json:"annotations,omitempty"` -} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go index ffff4b6d186..36b0aeb8f1f 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go @@ -48,6 +48,17 @@ type ImageConfig struct { // StopSignal contains the system call signal that will be sent to the container to exit. StopSignal string `json:"StopSignal,omitempty"` + + // ArgsEscaped + // + // Deprecated: This field is present only for legacy compatibility with + // Docker and should not be used by new image builders. It is used by Docker + // for Windows images to indicate that the `Entrypoint` or `Cmd` or both, + // contains only a single element array, that is a pre-escaped, and combined + // into a single string `CommandLine`. If `true` the value in `Entrypoint` or + // `Cmd` should be used as-is to avoid double escaping. + // https://github.com/opencontainers/image-spec/pull/892 + ArgsEscaped bool `json:"ArgsEscaped,omitempty"` } // RootFS describes a layer content addresses @@ -86,22 +97,8 @@ type Image struct { // Author defines the name and/or email address of the person or entity which created and is responsible for maintaining the image. Author string `json:"author,omitempty"` - // Architecture is the CPU architecture which the binaries in this image are built to run on. - Architecture string `json:"architecture"` - - // Variant is the variant of the specified CPU architecture which image binaries are intended to run on. - Variant string `json:"variant,omitempty"` - - // OS is the name of the operating system which the image is built to run on. - OS string `json:"os"` - - // OSVersion is an optional field specifying the operating system - // version, for example on Windows `10.0.14393.1066`. - OSVersion string `json:"os.version,omitempty"` - - // OSFeatures is an optional field specifying an array of strings, - // each listing a required OS feature (for example on Windows `win32k`). - OSFeatures []string `json:"os.features,omitempty"` + // Platform describes the platform which the image in the manifest runs on. + Platform // Config defines the execution parameters which should be used as a base when running a container using the image. Config ImageConfig `json:"config,omitempty"` diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go index 9654aa5af68..1881b11814b 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go @@ -21,7 +21,7 @@ import digest "github.com/opencontainers/go-digest" // when marshalled to JSON. type Descriptor struct { // MediaType is the media type of the object this schema refers to. - MediaType string `json:"mediaType,omitempty"` + MediaType string `json:"mediaType"` // Digest is the digest of the targeted content. Digest digest.Digest `json:"digest"` @@ -52,7 +52,7 @@ type Descriptor struct { // Platform describes the platform which the image in the manifest runs on. type Platform struct { // Architecture field specifies the CPU architecture, for example - // `amd64` or `ppc64`. + // `amd64` or `ppc64le`. Architecture string `json:"architecture"` // OS specifies the operating system, for example `linux` or `windows`. @@ -70,3 +70,11 @@ type Platform struct { // example `v7` to specify ARMv7 when architecture is `arm`. Variant string `json:"variant,omitempty"` } + +// DescriptorEmptyJSON is the descriptor of a blob with content of `{}`. +var DescriptorEmptyJSON = Descriptor{ + MediaType: MediaTypeEmptyJSON, + Digest: `sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a`, + Size: 2, + Data: []byte(`{}`), +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go index ed4a56e59e8..e2bed9d4e46 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go @@ -24,9 +24,15 @@ type Index struct { // MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json` MediaType string `json:"mediaType,omitempty"` + // ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact. + ArtifactType string `json:"artifactType,omitempty"` + // Manifests references platform specific manifests. Manifests []Descriptor `json:"manifests"` + // Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest. + Subject *Descriptor `json:"subject,omitempty"` + // Annotations contains arbitrary metadata for the image index. Annotations map[string]string `json:"annotations,omitempty"` } diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go index fc79e9e0d14..c5503cb3053 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go @@ -15,10 +15,14 @@ package v1 const ( - // ImageLayoutFile is the file name of oci image layout file + // ImageLayoutFile is the file name containing ImageLayout in an OCI Image Layout ImageLayoutFile = "oci-layout" // ImageLayoutVersion is the version of ImageLayout ImageLayoutVersion = "1.0.0" + // ImageIndexFile is the file name of the entry point for references and descriptors in an OCI Image Layout + ImageIndexFile = "index.json" + // ImageBlobsDir is the directory name containing content addressable blobs in an OCI Image Layout + ImageBlobsDir = "blobs" ) // ImageLayout is the structure in the "oci-layout" file, found in the root diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go index 730a09359b1..26fec52a6bc 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go @@ -23,6 +23,9 @@ type Manifest struct { // MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json` MediaType string `json:"mediaType,omitempty"` + // ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact. + ArtifactType string `json:"artifactType,omitempty"` + // Config references a configuration object for a container, by digest. // The referenced configuration object is a JSON blob that the runtime uses to set up the container. Config Descriptor `json:"config"` diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go index 935b481e3ed..892ba3de9de 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go @@ -40,21 +40,36 @@ const ( // MediaTypeImageLayerNonDistributable is the media type for layers referenced by // the manifest but with distribution restrictions. + // + // Deprecated: Non-distributable layers are deprecated, and not recommended + // for future use. Implementations SHOULD NOT produce new non-distributable + // layers. + // https://github.com/opencontainers/image-spec/pull/965 MediaTypeImageLayerNonDistributable = "application/vnd.oci.image.layer.nondistributable.v1.tar" // MediaTypeImageLayerNonDistributableGzip is the media type for // gzipped layers referenced by the manifest but with distribution // restrictions. + // + // Deprecated: Non-distributable layers are deprecated, and not recommended + // for future use. Implementations SHOULD NOT produce new non-distributable + // layers. + // https://github.com/opencontainers/image-spec/pull/965 MediaTypeImageLayerNonDistributableGzip = "application/vnd.oci.image.layer.nondistributable.v1.tar+gzip" // MediaTypeImageLayerNonDistributableZstd is the media type for zstd // compressed layers referenced by the manifest but with distribution // restrictions. + // + // Deprecated: Non-distributable layers are deprecated, and not recommended + // for future use. Implementations SHOULD NOT produce new non-distributable + // layers. + // https://github.com/opencontainers/image-spec/pull/965 MediaTypeImageLayerNonDistributableZstd = "application/vnd.oci.image.layer.nondistributable.v1.tar+zstd" // MediaTypeImageConfig specifies the media type for the image configuration. MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" - // MediaTypeArtifactManifest specifies the media type for a content descriptor. - MediaTypeArtifactManifest = "application/vnd.oci.artifact.manifest.v1+json" + // MediaTypeEmptyJSON specifies the media type for an unused blob containing the value `{}` + MediaTypeEmptyJSON = "application/vnd.oci.empty.v1+json" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index d2790357964..11e09b58467 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -25,7 +25,7 @@ const ( VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-rc2" + VersionDev = "-rc.5" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go index 246c5ea943c..2f5616894e7 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go @@ -28,6 +28,8 @@ var ( MetricsAll = GoRuntimeMetricsRule{regexp.MustCompile("/.*")} // MetricsGC allows only GC metrics to be collected from Go runtime. // e.g. go_gc_cycles_automatic_gc_cycles_total + // NOTE: This does not include new class of "/cpu/classes/gc/..." metrics. + // Use custom metric rule to access those. MetricsGC = GoRuntimeMetricsRule{regexp.MustCompile(`^/gc/.*`)} // MetricsMemory allows only memory metrics to be collected from Go runtime. // e.g. go_memory_classes_heap_free_bytes diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go index a912b75a05b..62de4dc59aa 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go @@ -59,6 +59,18 @@ type ExemplarAdder interface { // CounterOpts is an alias for Opts. See there for doc comments. type CounterOpts Opts +// CounterVecOpts bundles the options to create a CounterVec metric. +// It is mandatory to set CounterOpts, see there for mandatory fields. VariableLabels +// is optional and can safely be left to its default value. +type CounterVecOpts struct { + CounterOpts + + // VariableLabels are used to partition the metric vector by the given set + // of labels. Each label value will be constrained with the optional Contraint + // function, if provided. + VariableLabels ConstrainableLabels +} + // NewCounter creates a new Counter based on the provided CounterOpts. // // The returned implementation also implements ExemplarAdder. It is safe to @@ -174,16 +186,24 @@ type CounterVec struct { // NewCounterVec creates a new CounterVec based on the provided CounterOpts and // partitioned by the given label names. func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { - desc := NewDesc( + return V2.NewCounterVec(CounterVecOpts{ + CounterOpts: opts, + VariableLabels: UnconstrainedLabels(labelNames), + }) +} + +// NewCounterVec creates a new CounterVec based on the provided CounterVecOpts. +func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec { + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - labelNames, + opts.VariableLabels, opts.ConstLabels, ) return &CounterVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs)) + panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), lvs)) } result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: time.Now} result.init(result) // Init self-collection. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go index 8bc5e44e2fc..deedc2dfbe7 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go @@ -14,20 +14,16 @@ package prometheus import ( - "errors" "fmt" "sort" "strings" "github.com/cespare/xxhash/v2" - - "github.com/prometheus/client_golang/prometheus/internal" - - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" + dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/model" + "google.golang.org/protobuf/proto" - dto "github.com/prometheus/client_model/go" + "github.com/prometheus/client_golang/prometheus/internal" ) // Desc is the descriptor used by every Prometheus Metric. It is essentially @@ -54,9 +50,9 @@ type Desc struct { // constLabelPairs contains precalculated DTO label pairs based on // the constant labels. constLabelPairs []*dto.LabelPair - // variableLabels contains names of labels for which the metric - // maintains variable values. - variableLabels []string + // variableLabels contains names of labels and normalization function for + // which the metric maintains variable values. + variableLabels ConstrainedLabels // id is a hash of the values of the ConstLabels and fqName. This // must be unique among all registered descriptors and can therefore be // used as an identifier of the descriptor. @@ -80,10 +76,24 @@ type Desc struct { // For constLabels, the label values are constant. Therefore, they are fully // specified in the Desc. See the Collector example for a usage pattern. func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc { + return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels) +} + +// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc +// and will be reported on registration time. variableLabels and constLabels can +// be nil if no such labels should be set. fqName must not be empty. +// +// variableLabels only contain the label names and normalization functions. Their +// label values are variable and therefore not part of the Desc. (They are managed +// within the Metric.) +// +// For constLabels, the label values are constant. Therefore, they are fully +// specified in the Desc. See the Collector example for a usage pattern. +func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc { d := &Desc{ fqName: fqName, help: help, - variableLabels: variableLabels, + variableLabels: variableLabels.constrainedLabels(), } if !model.IsValidMetricName(model.LabelValue(fqName)) { d.err = fmt.Errorf("%q is not a valid metric name", fqName) @@ -93,7 +103,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * // their sorted label names) plus the fqName (at position 0). labelValues := make([]string, 1, len(constLabels)+1) labelValues[0] = fqName - labelNames := make([]string, 0, len(constLabels)+len(variableLabels)) + labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels)) labelNameSet := map[string]struct{}{} // First add only the const label names and sort them... for labelName := range constLabels { @@ -118,16 +128,16 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * // Now add the variable label names, but prefix them with something that // cannot be in a regular label name. That prevents matching the label // dimension with a different mix between preset and variable labels. - for _, labelName := range variableLabels { - if !checkLabelName(labelName) { - d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName) + for _, label := range d.variableLabels { + if !checkLabelName(label.Name) { + d.err = fmt.Errorf("%q is not a valid label name for metric %q", label.Name, fqName) return d } - labelNames = append(labelNames, "$"+labelName) - labelNameSet[labelName] = struct{}{} + labelNames = append(labelNames, "$"+label.Name) + labelNameSet[label.Name] = struct{}{} } if len(labelNames) != len(labelNameSet) { - d.err = errors.New("duplicate label names") + d.err = fmt.Errorf("duplicate label names in constant and variable labels for metric %q", fqName) return d } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go index 811072cbd54..962608f02c6 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/doc.go @@ -37,35 +37,35 @@ // // type metrics struct { // cpuTemp prometheus.Gauge -// hdFailures *prometheus.CounterVec +// hdFailures *prometheus.CounterVec // } // // func NewMetrics(reg prometheus.Registerer) *metrics { -// m := &metrics{ -// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ -// Name: "cpu_temperature_celsius", -// Help: "Current temperature of the CPU.", -// }), -// hdFailures: prometheus.NewCounterVec( -// prometheus.CounterOpts{ -// Name: "hd_errors_total", -// Help: "Number of hard-disk errors.", -// }, -// []string{"device"}, -// ), -// } -// reg.MustRegister(m.cpuTemp) -// reg.MustRegister(m.hdFailures) -// return m +// m := &metrics{ +// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ +// Name: "cpu_temperature_celsius", +// Help: "Current temperature of the CPU.", +// }), +// hdFailures: prometheus.NewCounterVec( +// prometheus.CounterOpts{ +// Name: "hd_errors_total", +// Help: "Number of hard-disk errors.", +// }, +// []string{"device"}, +// ), +// } +// reg.MustRegister(m.cpuTemp) +// reg.MustRegister(m.hdFailures) +// return m // } // // func main() { -// // Create a non-global registry. -// reg := prometheus.NewRegistry() +// // Create a non-global registry. +// reg := prometheus.NewRegistry() // -// // Create new metrics and register them using the custom registry. -// m := NewMetrics(reg) -// // Set values for the new created metrics. +// // Create new metrics and register them using the custom registry. +// m := NewMetrics(reg) +// // Set values for the new created metrics. // m.cpuTemp.Set(65.3) // m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() // diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go index 21271a5bb46..f1ea6c76f75 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go @@ -55,6 +55,18 @@ type Gauge interface { // GaugeOpts is an alias for Opts. See there for doc comments. type GaugeOpts Opts +// GaugeVecOpts bundles the options to create a GaugeVec metric. +// It is mandatory to set GaugeOpts, see there for mandatory fields. VariableLabels +// is optional and can safely be left to its default value. +type GaugeVecOpts struct { + GaugeOpts + + // VariableLabels are used to partition the metric vector by the given set + // of labels. Each label value will be constrained with the optional Contraint + // function, if provided. + VariableLabels ConstrainableLabels +} + // NewGauge creates a new Gauge based on the provided GaugeOpts. // // The returned implementation is optimized for a fast Set method. If you have a @@ -138,16 +150,24 @@ type GaugeVec struct { // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and // partitioned by the given label names. func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { - desc := NewDesc( + return V2.NewGaugeVec(GaugeVecOpts{ + GaugeOpts: opts, + VariableLabels: UnconstrainedLabels(labelNames), + }) +} + +// NewGaugeVec creates a new GaugeVec based on the provided GaugeVecOpts. +func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec { + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - labelNames, + opts.VariableLabels, opts.ConstLabels, ) return &GaugeVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs)) + panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), lvs)) } result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)} result.init(result) // Init self-collection. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go index 3a2d55e84b1..2d8d9f64f43 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go @@ -23,11 +23,10 @@ import ( "strings" "sync" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" - "github.com/prometheus/client_golang/prometheus/internal" + + dto "github.com/prometheus/client_model/go" + "google.golang.org/protobuf/proto" ) const ( diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index 4c873a01c3d..8d818afe90d 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -22,10 +22,9 @@ import ( "sync/atomic" "time" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" + + "google.golang.org/protobuf/proto" ) // nativeHistogramBounds for the frac of observed values. Only relevant for @@ -402,7 +401,7 @@ type HistogramOpts struct { // Histogram by a Prometheus server with that feature enabled (requires // Prometheus v2.40+). Sparse buckets are exponential buckets covering // the whole float64 range (with the exception of the “zero” bucket, see - // SparseBucketsZeroThreshold below). From any one bucket to the next, + // NativeHistogramZeroThreshold below). From any one bucket to the next, // the width of the bucket grows by a constant // factor. NativeHistogramBucketFactor provides an upper bound for this // factor (exception see below). The smaller @@ -433,7 +432,7 @@ type HistogramOpts struct { // bucket. For best results, this should be close to a bucket // boundary. This is usually the case if picking a power of two. If // NativeHistogramZeroThreshold is left at zero, - // DefSparseBucketsZeroThreshold is used as the threshold. To configure + // DefNativeHistogramZeroThreshold is used as the threshold. To configure // a zero bucket with an actual threshold of zero (i.e. only // observations of precisely zero will go into the zero bucket), set // NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero @@ -469,6 +468,18 @@ type HistogramOpts struct { NativeHistogramMaxZeroThreshold float64 } +// HistogramVecOpts bundles the options to create a HistogramVec metric. +// It is mandatory to set HistogramOpts, see there for mandatory fields. VariableLabels +// is optional and can safely be left to its default value. +type HistogramVecOpts struct { + HistogramOpts + + // VariableLabels are used to partition the metric vector by the given set + // of labels. Each label value will be constrained with the optional Contraint + // function, if provided. + VariableLabels ConstrainableLabels +} + // NewHistogram creates a new Histogram based on the provided HistogramOpts. It // panics if the buckets in HistogramOpts are not in strictly increasing order. // @@ -489,11 +500,11 @@ func NewHistogram(opts HistogramOpts) Histogram { func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram { if len(desc.variableLabels) != len(labelValues) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, labelValues)) + panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), labelValues)) } for _, n := range desc.variableLabels { - if n == bucketLabel { + if n.Name == bucketLabel { panic(errBucketLabelNotAllowed) } } @@ -544,16 +555,12 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr } // Finally we know the final length of h.upperBounds and can make buckets // for both counts as well as exemplars: - h.counts[0] = &histogramCounts{ - buckets: make([]uint64, len(h.upperBounds)), - nativeHistogramZeroThresholdBits: math.Float64bits(h.nativeHistogramZeroThreshold), - nativeHistogramSchema: h.nativeHistogramSchema, - } - h.counts[1] = &histogramCounts{ - buckets: make([]uint64, len(h.upperBounds)), - nativeHistogramZeroThresholdBits: math.Float64bits(h.nativeHistogramZeroThreshold), - nativeHistogramSchema: h.nativeHistogramSchema, - } + h.counts[0] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} + atomic.StoreUint64(&h.counts[0].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) + atomic.StoreInt32(&h.counts[0].nativeHistogramSchema, h.nativeHistogramSchema) + h.counts[1] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} + atomic.StoreUint64(&h.counts[1].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) + atomic.StoreInt32(&h.counts[1].nativeHistogramSchema, h.nativeHistogramSchema) h.exemplars = make([]atomic.Value, len(h.upperBounds)+1) h.init(h) // Init self-collection. @@ -632,8 +639,8 @@ func (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) { if frac == 0.5 { key-- } - div := 1 << -schema - key = (key + div - 1) / div + offset := (1 << -schema) - 1 + key = (key + offset) >> -schema } if isInf { key++ @@ -810,7 +817,7 @@ func (h *histogram) observe(v float64, bucket int) { } } -// limitSparsebuckets applies a strategy to limit the number of populated sparse +// limitBuckets applies a strategy to limit the number of populated sparse // buckets. It's generally best effort, and there are situations where the // number can go higher (if even the lowest resolution isn't enough to reduce // the number sufficiently, or if the provided counts aren't fully updated yet @@ -1034,15 +1041,23 @@ type HistogramVec struct { // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and // partitioned by the given label names. func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { - desc := NewDesc( + return V2.NewHistogramVec(HistogramVecOpts{ + HistogramOpts: opts, + VariableLabels: UnconstrainedLabels(labelNames), + }) +} + +// NewHistogramVec creates a new HistogramVec based on the provided HistogramVecOpts. +func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec { + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - labelNames, + opts.VariableLabels, opts.ConstLabels, ) return &HistogramVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - return newHistogram(desc, opts, lvs...) + return newHistogram(desc, opts.HistogramOpts, lvs...) }), } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go index c1b8fad36ae..63ff8683ce5 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go @@ -32,6 +32,78 @@ import ( // create a Desc. type Labels map[string]string +// ConstrainedLabels represents a label name and its constrain function +// to normalize label values. This type is commonly used when constructing +// metric vector Collectors. +type ConstrainedLabel struct { + Name string + Constraint func(string) string +} + +func (cl ConstrainedLabel) Constrain(v string) string { + if cl.Constraint == nil { + return v + } + return cl.Constraint(v) +} + +// ConstrainableLabels is an interface that allows creating of labels that can +// be optionally constrained. +// +// prometheus.V2().NewCounterVec(CounterVecOpts{ +// CounterOpts: {...}, // Usual CounterOpts fields +// VariableLabels: []ConstrainedLabels{ +// {Name: "A"}, +// {Name: "B", Constraint: func(v string) string { ... }}, +// }, +// }) +type ConstrainableLabels interface { + constrainedLabels() ConstrainedLabels + labelNames() []string +} + +// ConstrainedLabels represents a collection of label name -> constrain function +// to normalize label values. This type is commonly used when constructing +// metric vector Collectors. +type ConstrainedLabels []ConstrainedLabel + +func (cls ConstrainedLabels) constrainedLabels() ConstrainedLabels { + return cls +} + +func (cls ConstrainedLabels) labelNames() []string { + names := make([]string, len(cls)) + for i, label := range cls { + names[i] = label.Name + } + return names +} + +// UnconstrainedLabels represents collection of label without any constraint on +// their value. Thus, it is simply a collection of label names. +// +// UnconstrainedLabels([]string{ "A", "B" }) +// +// is equivalent to +// +// ConstrainedLabels { +// { Name: "A" }, +// { Name: "B" }, +// } +type UnconstrainedLabels []string + +func (uls UnconstrainedLabels) constrainedLabels() ConstrainedLabels { + constrainedLabels := make([]ConstrainedLabel, len(uls)) + for i, l := range uls { + constrainedLabels[i] = ConstrainedLabel{Name: l} + } + return constrainedLabels +} + +func (uls UnconstrainedLabels) labelNames() []string { + return uls +} + // reservedLabelPrefix is a prefix which is not legal in user-supplied // label names. const reservedLabelPrefix = "__" diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go index b5119c50410..07bbc9d7687 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -20,11 +20,9 @@ import ( "strings" "time" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - "github.com/prometheus/common/model" - dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/model" + "google.golang.org/protobuf/proto" ) var separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index a4cc9810b07..09b8d2fbead 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -37,6 +37,7 @@ import ( "fmt" "io" "net/http" + "strconv" "strings" "sync" "time" @@ -47,9 +48,10 @@ import ( ) const ( - contentTypeHeader = "Content-Type" - contentEncodingHeader = "Content-Encoding" - acceptEncodingHeader = "Accept-Encoding" + contentTypeHeader = "Content-Type" + contentEncodingHeader = "Content-Encoding" + acceptEncodingHeader = "Accept-Encoding" + processStartTimeHeader = "Process-Start-Time-Unix" ) var gzipPool = sync.Pool{ @@ -121,6 +123,9 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO } h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) { + if !opts.ProcessStartTime.IsZero() { + rsp.Header().Set(processStartTimeHeader, strconv.FormatInt(opts.ProcessStartTime.Unix(), 10)) + } if inFlightSem != nil { select { case inFlightSem <- struct{}{}: // All good, carry on. @@ -366,6 +371,14 @@ type HandlerOpts struct { // (which changes the identity of the resulting series on the Prometheus // server). EnableOpenMetrics bool + // ProcessStartTime allows setting process start timevalue that will be exposed + // with "Process-Start-Time-Unix" response header along with the metrics + // payload. This allow callers to have efficient transformations to cumulative + // counters (e.g. OpenTelemetry) or generally _created timestamp estimation per + // scrape target. + // NOTE: This feature is experimental and not covered by OpenMetrics or Prometheus + // exposition format. + ProcessStartTime time.Time } // gzipAccepted returns whether the client will accept gzip-encoded content. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go index 21086781621..d3482c40ca7 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go @@ -68,16 +68,17 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou o.apply(rtOpts) } - code, method := checkLabels(counter) + // Curry the counter with dynamic labels before checking the remaining labels. + code, method := checkLabels(counter.MustCurryWith(rtOpts.emptyDynamicLabels())) return func(r *http.Request) (*http.Response, error) { resp, err := next.RoundTrip(r) if err == nil { - addWithExemplar( - counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), - 1, - rtOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) + for label, resolve := range rtOpts.extraLabelsFromCtx { + l[label] = resolve(resp.Request.Context()) + } + addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context())) } return resp, err } @@ -110,17 +111,18 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT o.apply(rtOpts) } - code, method := checkLabels(obs) + // Curry the observer with dynamic labels before checking the remaining labels. + code, method := checkLabels(obs.MustCurryWith(rtOpts.emptyDynamicLabels())) return func(r *http.Request) (*http.Response, error) { start := time.Now() resp, err := next.RoundTrip(r) if err == nil { - observeWithExemplar( - obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), - time.Since(start).Seconds(), - rtOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) + for label, resolve := range rtOpts.extraLabelsFromCtx { + l[label] = resolve(resp.Request.Context()) + } + observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context())) } return resp, err } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go index cca67a78a90..3793036ad09 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go @@ -87,7 +87,8 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op o.apply(hOpts) } - code, method := checkLabels(obs) + // Curry the observer with dynamic labels before checking the remaining labels. + code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) if code { return func(w http.ResponseWriter, r *http.Request) { @@ -95,23 +96,22 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op d := newDelegator(w, nil) next.ServeHTTP(d, r) - observeWithExemplar( - obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), - time.Since(now).Seconds(), - hOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { now := time.Now() next.ServeHTTP(w, r) - - observeWithExemplar( - obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), - time.Since(now).Seconds(), - hOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, 0, hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } @@ -138,28 +138,30 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, o.apply(hOpts) } - code, method := checkLabels(counter) + // Curry the counter with dynamic labels before checking the remaining labels. + code, method := checkLabels(counter.MustCurryWith(hOpts.emptyDynamicLabels())) if code { return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - addWithExemplar( - counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), - 1, - hOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) - addWithExemplar( - counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), - 1, - hOpts.getExemplarFn(r.Context()), - ) + + l := labels(code, method, r.Method, 0, hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } @@ -191,16 +193,17 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha o.apply(hOpts) } - code, method := checkLabels(obs) + // Curry the observer with dynamic labels before checking the remaining labels. + code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, func(status int) { - observeWithExemplar( - obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), - time.Since(now).Seconds(), - hOpts.getExemplarFn(r.Context()), - ) + l := labels(code, method, r.Method, status, hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) }) next.ServeHTTP(d, r) } @@ -231,28 +234,32 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, o.apply(hOpts) } - code, method := checkLabels(obs) + // Curry the observer with dynamic labels before checking the remaining labels. + code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) + if code { return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) size := computeApproximateRequestSize(r) - observeWithExemplar( - obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), - float64(size), - hOpts.getExemplarFn(r.Context()), - ) + + l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) size := computeApproximateRequestSize(r) - observeWithExemplar( - obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), - float64(size), - hOpts.getExemplarFn(r.Context()), - ) + + l := labels(code, method, r.Method, 0, hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } @@ -281,16 +288,18 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler o.apply(hOpts) } - code, method := checkLabels(obs) + // Curry the observer with dynamic labels before checking the remaining labels. + code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - observeWithExemplar( - obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), - float64(d.Written()), - hOpts.getExemplarFn(r.Context()), - ) + + l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) + for label, resolve := range hOpts.extraLabelsFromCtx { + l[label] = resolve(r.Context()) + } + observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context())) }) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go index c590d912c94..5d4383aa14a 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go @@ -24,14 +24,32 @@ type Option interface { apply(*options) } +// LabelValueFromCtx are used to compute the label value from request context. +// Context can be filled with values from request through middleware. +type LabelValueFromCtx func(ctx context.Context) string + // options store options for both a handler or round tripper. type options struct { - extraMethods []string - getExemplarFn func(requestCtx context.Context) prometheus.Labels + extraMethods []string + getExemplarFn func(requestCtx context.Context) prometheus.Labels + extraLabelsFromCtx map[string]LabelValueFromCtx } func defaultOptions() *options { - return &options{getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }} + return &options{ + getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }, + extraLabelsFromCtx: map[string]LabelValueFromCtx{}, + } +} + +func (o *options) emptyDynamicLabels() prometheus.Labels { + labels := prometheus.Labels{} + + for label := range o.extraLabelsFromCtx { + labels[label] = "" + } + + return labels } type optionApplyFunc func(*options) @@ -48,11 +66,19 @@ func WithExtraMethods(methods ...string) Option { }) } -// WithExemplarFromContext adds allows to put a hook to all counter and histogram metrics. -// If the hook function returns non-nil labels, exemplars will be added for that request, otherwise metric -// will get instrumented without exemplar. +// WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics. +// If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but +// metric will continue to observe/increment. func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { return optionApplyFunc(func(o *options) { o.getExemplarFn = getExemplarFn }) } + +// WithLabelFromCtx registers a label for dynamic resolution with access to context. +// See the example for ExampleInstrumentHandlerWithLabelResolver for example usage +func WithLabelFromCtx(name string, valueFn LabelValueFromCtx) Option { + return optionApplyFunc(func(o *options) { + o.extraLabelsFromCtx[name] = valueFn + }) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index 09e34d307c9..44da9433bee 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -21,18 +21,17 @@ import ( "path/filepath" "runtime" "sort" + "strconv" "strings" "sync" "unicode/utf8" - "github.com/cespare/xxhash/v2" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - "github.com/prometheus/common/expfmt" + "github.com/prometheus/client_golang/prometheus/internal" + "github.com/cespare/xxhash/v2" dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/client_golang/prometheus/internal" + "github.com/prometheus/common/expfmt" + "google.golang.org/protobuf/proto" ) const ( @@ -933,6 +932,10 @@ func checkMetricConsistency( h.WriteString(lp.GetValue()) h.Write(separatorByteSlice) } + if dtoMetric.TimestampMs != nil { + h.WriteString(strconv.FormatInt(*(dtoMetric.TimestampMs), 10)) + h.Write(separatorByteSlice) + } hSum := h.Sum64() if _, exists := metricHashes[hSum]; exists { return fmt.Errorf( @@ -962,7 +965,7 @@ func checkDescConsistency( copy(lpsFromDesc, desc.constLabelPairs) for _, l := range desc.variableLabels { lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ - Name: proto.String(l), + Name: proto.String(l.Name), }) } if len(lpsFromDesc) != len(dtoMetric.Label) { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go index 7bc448a8939..dd359264e59 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go @@ -22,11 +22,10 @@ import ( "sync/atomic" "time" - "github.com/beorn7/perks/quantile" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - dto "github.com/prometheus/client_model/go" + + "github.com/beorn7/perks/quantile" + "google.golang.org/protobuf/proto" ) // quantileLabel is used for the label that defines the quantile in a @@ -148,6 +147,18 @@ type SummaryOpts struct { BufCap uint32 } +// SummaryVecOpts bundles the options to create a SummaryVec metric. +// It is mandatory to set SummaryOpts, see there for mandatory fields. VariableLabels +// is optional and can safely be left to its default value. +type SummaryVecOpts struct { + SummaryOpts + + // VariableLabels are used to partition the metric vector by the given set + // of labels. Each label value will be constrained with the optional Contraint + // function, if provided. + VariableLabels ConstrainableLabels +} + // Problem with the sliding-window decay algorithm... The Merge method of // perk/quantile is actually not working as advertised - and it might be // unfixable, as the underlying algorithm is apparently not capable of merging @@ -178,11 +189,11 @@ func NewSummary(opts SummaryOpts) Summary { func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { if len(desc.variableLabels) != len(labelValues) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, labelValues)) + panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), labelValues)) } for _, n := range desc.variableLabels { - if n == quantileLabel { + if n.Name == quantileLabel { panic(errQuantileLabelNotAllowed) } } @@ -530,20 +541,28 @@ type SummaryVec struct { // it is handled by the Prometheus server internally, “quantile” is an illegal // label name. NewSummaryVec will panic if this label name is used. func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { - for _, ln := range labelNames { + return V2.NewSummaryVec(SummaryVecOpts{ + SummaryOpts: opts, + VariableLabels: UnconstrainedLabels(labelNames), + }) +} + +// NewSummaryVec creates a new SummaryVec based on the provided SummaryVecOpts. +func (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec { + for _, ln := range opts.VariableLabels.labelNames() { if ln == quantileLabel { panic(errQuantileLabelNotAllowed) } } - desc := NewDesc( + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - labelNames, + opts.VariableLabels, opts.ConstLabels, ) return &SummaryVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - return newSummary(desc, opts, lvs...) + return newSummary(desc, opts.SummaryOpts, lvs...) }), } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go index f28a76f3a62..52344fef53f 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/timer.go @@ -23,7 +23,9 @@ type Timer struct { } // NewTimer creates a new Timer. The provided Observer is used to observe a -// duration in seconds. Timer is usually used to time a function call in the +// duration in seconds. If the Observer implements ExemplarObserver, passing exemplar +// later on will be also supported. +// Timer is usually used to time a function call in the // following way: // // func TimeMe() { @@ -31,6 +33,14 @@ type Timer struct { // defer timer.ObserveDuration() // // Do actual work. // } +// +// or +// +// func TimeMeWithExemplar() { +// timer := NewTimer(myHistogram) +// defer timer.ObserveDurationWithExemplar(exemplar) +// // Do actual work. +// } func NewTimer(o Observer) *Timer { return &Timer{ begin: time.Now(), @@ -53,3 +63,19 @@ func (t *Timer) ObserveDuration() time.Duration { } return d } + +// ObserveDurationWithExemplar is like ObserveDuration, but it will also +// observe exemplar with the duration unless exemplar is nil or provided Observer can't +// be casted to ExemplarObserver. +func (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration { + d := time.Since(t.begin) + eo, ok := t.observer.(ExemplarObserver) + if ok && exemplar != nil { + eo.ObserveWithExemplar(d.Seconds(), exemplar) + return d + } + if t.observer != nil { + t.observer.Observe(d.Seconds()) + } + return d +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go index 2d3abc1cbd6..5f6bb80014d 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/value.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go @@ -19,13 +19,11 @@ import ( "time" "unicode/utf8" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" - "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" ) // ValueType is an enumeration of metric types that represent a simple value. @@ -188,9 +186,9 @@ func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { return desc.constLabelPairs } labelPairs := make([]*dto.LabelPair, 0, totalLen) - for i, n := range desc.variableLabels { + for i, l := range desc.variableLabels { labelPairs = append(labelPairs, &dto.LabelPair{ - Name: proto.String(n), + Name: proto.String(l.Name), Value: proto.String(labelValues[i]), }) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go index 7ae322590c8..f0d0015a0ff 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -20,6 +20,24 @@ import ( "github.com/prometheus/common/model" ) +var labelsPool = &sync.Pool{ + New: func() interface{} { + return make(Labels) + }, +} + +func getLabelsFromPool() Labels { + return labelsPool.Get().(Labels) +} + +func putLabelsToPool(labels Labels) { + for k := range labels { + delete(labels, k) + } + + labelsPool.Put(labels) +} + // MetricVec is a Collector to bundle metrics of the same name that differ in // their label values. MetricVec is not used directly but as a building block // for implementations of vectors of a given metric type, like GaugeVec, @@ -72,6 +90,7 @@ func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec { // with a performance overhead (for creating and processing the Labels map). // See also the CounterVec example. func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { + lvs = constrainLabelValues(m.desc, lvs, m.curry) h, err := m.hashLabelValues(lvs) if err != nil { return false @@ -91,6 +110,9 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { // This method is used for the same purpose as DeleteLabelValues(...string). See // there for pros and cons of the two methods. func (m *MetricVec) Delete(labels Labels) bool { + labels = constrainLabels(m.desc, labels) + defer putLabelsToPool(labels) + h, err := m.hashLabels(labels) if err != nil { return false @@ -106,6 +128,9 @@ func (m *MetricVec) Delete(labels Labels) bool { // Note that curried labels will never be matched if deleting from the curried vector. // To match curried labels with DeletePartialMatch, it must be called on the base vector. func (m *MetricVec) DeletePartialMatch(labels Labels) int { + labels = constrainLabels(m.desc, labels) + defer putLabelsToPool(labels) + return m.metricMap.deleteByLabels(labels, m.curry) } @@ -145,10 +170,10 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { iCurry int ) for i, label := range m.desc.variableLabels { - val, ok := labels[label] + val, ok := labels[label.Name] if iCurry < len(oldCurry) && oldCurry[iCurry].index == i { if ok { - return nil, fmt.Errorf("label name %q is already curried", label) + return nil, fmt.Errorf("label name %q is already curried", label.Name) } newCurry = append(newCurry, oldCurry[iCurry]) iCurry++ @@ -156,7 +181,7 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { if !ok { continue // Label stays uncurried. } - newCurry = append(newCurry, curriedLabelValue{i, val}) + newCurry = append(newCurry, curriedLabelValue{i, label.Constrain(val)}) } } if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 { @@ -199,6 +224,7 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { // a wrapper around MetricVec, implementing a vector for a specific Metric // implementation, for example GaugeVec. func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { + lvs = constrainLabelValues(m.desc, lvs, m.curry) h, err := m.hashLabelValues(lvs) if err != nil { return nil, err @@ -224,6 +250,9 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { // around MetricVec, implementing a vector for a specific Metric implementation, // for example GaugeVec. func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { + labels = constrainLabels(m.desc, labels) + defer putLabelsToPool(labels) + h, err := m.hashLabels(labels) if err != nil { return nil, err @@ -266,16 +295,16 @@ func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { iCurry int ) for i, label := range m.desc.variableLabels { - val, ok := labels[label] + val, ok := labels[label.Name] if iCurry < len(curry) && curry[iCurry].index == i { if ok { - return 0, fmt.Errorf("label name %q is already curried", label) + return 0, fmt.Errorf("label name %q is already curried", label.Name) } h = m.hashAdd(h, curry[iCurry].value) iCurry++ } else { if !ok { - return 0, fmt.Errorf("label name %q missing in label map", label) + return 0, fmt.Errorf("label name %q missing in label map", label.Name) } h = m.hashAdd(h, val) } @@ -453,7 +482,7 @@ func valueMatchesVariableOrCurriedValue(targetValue string, index int, values [] func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { for l, v := range labels { // Check if the target label exists in our metrics and get the index. - varLabelIndex, validLabel := indexOf(l, desc.variableLabels) + varLabelIndex, validLabel := indexOf(l, desc.variableLabels.labelNames()) if validLabel { // Check the value of that label against the target value. // We don't consider curried values in partial matches. @@ -605,7 +634,7 @@ func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabe iCurry++ continue } - if values[i] != labels[k] { + if values[i] != labels[k.Name] { return false } } @@ -621,7 +650,7 @@ func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) [] iCurry++ continue } - labelValues[i] = labels[k] + labelValues[i] = labels[k.Name] } return labelValues } @@ -640,3 +669,35 @@ func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string { } return labelValues } + +func constrainLabels(desc *Desc, labels Labels) Labels { + constrainedLabels := getLabelsFromPool() + for l, v := range labels { + if i, ok := indexOf(l, desc.variableLabels.labelNames()); ok { + v = desc.variableLabels[i].Constrain(v) + } + + constrainedLabels[l] = v + } + + return constrainedLabels +} + +func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string { + constrainedValues := make([]string, len(lvs)) + var iCurry, iLVs int + for i := 0; i < len(lvs)+len(curry); i++ { + if iCurry < len(curry) && curry[iCurry].index == i { + iCurry++ + continue + } + + if i < len(desc.variableLabels) { + constrainedValues[iLVs] = desc.variableLabels[i].Constrain(lvs[iLVs]) + } else { + constrainedValues[iLVs] = lvs[iLVs] + } + iLVs++ + } + return constrainedValues +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vnext.go b/vendor/github.com/prometheus/client_golang/prometheus/vnext.go new file mode 100644 index 00000000000..42bc3a8f066 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/vnext.go @@ -0,0 +1,23 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package prometheus + +type v2 struct{} + +// V2 is a struct that can be referenced to access experimental API that might +// be present in v2 of client golang someday. It offers extended functionality +// of v1 with slightly changed API. It is acceptable to use some pieces from v1 +// and e.g `prometheus.NewGauge` and some from v2 e.g. `prometheus.V2.NewDesc` +// in the same codebase. +var V2 = v2{} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go index 1498ee144cb..25da157f152 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go @@ -17,12 +17,10 @@ import ( "fmt" "sort" - //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. - "github.com/golang/protobuf/proto" + "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/client_golang/prometheus/internal" + "google.golang.org/protobuf/proto" ) // WrapRegistererWith returns a Registerer wrapping the provided @@ -206,7 +204,7 @@ func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { constLabels[ln] = lv } // NewDesc will do remaining validations. - newDesc := NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) + newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) // Propagate errors if there was any. This will override any errer // created by NewDesc above, i.e. earlier errors get precedence. if desc.err != nil { diff --git a/vendor/github.com/prometheus/client_model/go/metrics.pb.go b/vendor/github.com/prometheus/client_model/go/metrics.pb.go index 35904ea1986..2b5bca4b999 100644 --- a/vendor/github.com/prometheus/client_model/go/metrics.pb.go +++ b/vendor/github.com/prometheus/client_model/go/metrics.pb.go @@ -1,25 +1,38 @@ +// Copyright 2013 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.20.3 // source: io/prometheus/client/metrics.proto package io_prometheus_client import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - timestamp "github.com/golang/protobuf/ptypes/timestamp" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type MetricType int32 @@ -38,23 +51,25 @@ const ( MetricType_GAUGE_HISTOGRAM MetricType = 5 ) -var MetricType_name = map[int32]string{ - 0: "COUNTER", - 1: "GAUGE", - 2: "SUMMARY", - 3: "UNTYPED", - 4: "HISTOGRAM", - 5: "GAUGE_HISTOGRAM", -} - -var MetricType_value = map[string]int32{ - "COUNTER": 0, - "GAUGE": 1, - "SUMMARY": 2, - "UNTYPED": 3, - "HISTOGRAM": 4, - "GAUGE_HISTOGRAM": 5, -} +// Enum value maps for MetricType. +var ( + MetricType_name = map[int32]string{ + 0: "COUNTER", + 1: "GAUGE", + 2: "SUMMARY", + 3: "UNTYPED", + 4: "HISTOGRAM", + 5: "GAUGE_HISTOGRAM", + } + MetricType_value = map[string]int32{ + "COUNTER": 0, + "GAUGE": 1, + "SUMMARY": 2, + "UNTYPED": 3, + "HISTOGRAM": 4, + "GAUGE_HISTOGRAM": 5, + } +) func (x MetricType) Enum() *MetricType { p := new(MetricType) @@ -63,449 +78,519 @@ func (x MetricType) Enum() *MetricType { } func (x MetricType) String() string { - return proto.EnumName(MetricType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *MetricType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(MetricType_value, data, "MetricType") +func (MetricType) Descriptor() protoreflect.EnumDescriptor { + return file_io_prometheus_client_metrics_proto_enumTypes[0].Descriptor() +} + +func (MetricType) Type() protoreflect.EnumType { + return &file_io_prometheus_client_metrics_proto_enumTypes[0] +} + +func (x MetricType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *MetricType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = MetricType(value) + *x = MetricType(num) return nil } +// Deprecated: Use MetricType.Descriptor instead. func (MetricType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{0} + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0} } type LabelPair struct { - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *LabelPair) Reset() { *m = LabelPair{} } -func (m *LabelPair) String() string { return proto.CompactTextString(m) } -func (*LabelPair) ProtoMessage() {} -func (*LabelPair) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{0} + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` } -func (m *LabelPair) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LabelPair.Unmarshal(m, b) -} -func (m *LabelPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LabelPair.Marshal(b, m, deterministic) -} -func (m *LabelPair) XXX_Merge(src proto.Message) { - xxx_messageInfo_LabelPair.Merge(m, src) +func (x *LabelPair) Reset() { + *x = LabelPair{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *LabelPair) XXX_Size() int { - return xxx_messageInfo_LabelPair.Size(m) + +func (x *LabelPair) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *LabelPair) XXX_DiscardUnknown() { - xxx_messageInfo_LabelPair.DiscardUnknown(m) + +func (*LabelPair) ProtoMessage() {} + +func (x *LabelPair) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_LabelPair proto.InternalMessageInfo +// Deprecated: Use LabelPair.ProtoReflect.Descriptor instead. +func (*LabelPair) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0} +} -func (m *LabelPair) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (x *LabelPair) GetName() string { + if x != nil && x.Name != nil { + return *x.Name } return "" } -func (m *LabelPair) GetValue() string { - if m != nil && m.Value != nil { - return *m.Value +func (x *LabelPair) GetValue() string { + if x != nil && x.Value != nil { + return *x.Value } return "" } type Gauge struct { - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Gauge) Reset() { *m = Gauge{} } -func (m *Gauge) String() string { return proto.CompactTextString(m) } -func (*Gauge) ProtoMessage() {} -func (*Gauge) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{1} + Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` } -func (m *Gauge) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Gauge.Unmarshal(m, b) -} -func (m *Gauge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Gauge.Marshal(b, m, deterministic) -} -func (m *Gauge) XXX_Merge(src proto.Message) { - xxx_messageInfo_Gauge.Merge(m, src) +func (x *Gauge) Reset() { + *x = Gauge{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Gauge) XXX_Size() int { - return xxx_messageInfo_Gauge.Size(m) + +func (x *Gauge) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Gauge) XXX_DiscardUnknown() { - xxx_messageInfo_Gauge.DiscardUnknown(m) + +func (*Gauge) ProtoMessage() {} + +func (x *Gauge) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Gauge proto.InternalMessageInfo +// Deprecated: Use Gauge.ProtoReflect.Descriptor instead. +func (*Gauge) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{1} +} -func (m *Gauge) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value +func (x *Gauge) GetValue() float64 { + if x != nil && x.Value != nil { + return *x.Value } return 0 } type Counter struct { - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` - Exemplar *Exemplar `protobuf:"bytes,2,opt,name=exemplar" json:"exemplar,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Counter) Reset() { *m = Counter{} } -func (m *Counter) String() string { return proto.CompactTextString(m) } -func (*Counter) ProtoMessage() {} -func (*Counter) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{2} + Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` + Exemplar *Exemplar `protobuf:"bytes,2,opt,name=exemplar" json:"exemplar,omitempty"` } -func (m *Counter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Counter.Unmarshal(m, b) -} -func (m *Counter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Counter.Marshal(b, m, deterministic) -} -func (m *Counter) XXX_Merge(src proto.Message) { - xxx_messageInfo_Counter.Merge(m, src) +func (x *Counter) Reset() { + *x = Counter{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Counter) XXX_Size() int { - return xxx_messageInfo_Counter.Size(m) + +func (x *Counter) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Counter) XXX_DiscardUnknown() { - xxx_messageInfo_Counter.DiscardUnknown(m) + +func (*Counter) ProtoMessage() {} + +func (x *Counter) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Counter proto.InternalMessageInfo +// Deprecated: Use Counter.ProtoReflect.Descriptor instead. +func (*Counter) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{2} +} -func (m *Counter) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value +func (x *Counter) GetValue() float64 { + if x != nil && x.Value != nil { + return *x.Value } return 0 } -func (m *Counter) GetExemplar() *Exemplar { - if m != nil { - return m.Exemplar +func (x *Counter) GetExemplar() *Exemplar { + if x != nil { + return x.Exemplar } return nil } type Quantile struct { - Quantile *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"` - Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Quantile) Reset() { *m = Quantile{} } -func (m *Quantile) String() string { return proto.CompactTextString(m) } -func (*Quantile) ProtoMessage() {} -func (*Quantile) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{3} + Quantile *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"` + Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` } -func (m *Quantile) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Quantile.Unmarshal(m, b) -} -func (m *Quantile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Quantile.Marshal(b, m, deterministic) -} -func (m *Quantile) XXX_Merge(src proto.Message) { - xxx_messageInfo_Quantile.Merge(m, src) +func (x *Quantile) Reset() { + *x = Quantile{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Quantile) XXX_Size() int { - return xxx_messageInfo_Quantile.Size(m) + +func (x *Quantile) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Quantile) XXX_DiscardUnknown() { - xxx_messageInfo_Quantile.DiscardUnknown(m) + +func (*Quantile) ProtoMessage() {} + +func (x *Quantile) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Quantile proto.InternalMessageInfo +// Deprecated: Use Quantile.ProtoReflect.Descriptor instead. +func (*Quantile) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{3} +} -func (m *Quantile) GetQuantile() float64 { - if m != nil && m.Quantile != nil { - return *m.Quantile +func (x *Quantile) GetQuantile() float64 { + if x != nil && x.Quantile != nil { + return *x.Quantile } return 0 } -func (m *Quantile) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value +func (x *Quantile) GetValue() float64 { + if x != nil && x.Value != nil { + return *x.Value } return 0 } type Summary struct { - SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` - SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` - Quantile []*Quantile `protobuf:"bytes,3,rep,name=quantile" json:"quantile,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Summary) Reset() { *m = Summary{} } -func (m *Summary) String() string { return proto.CompactTextString(m) } -func (*Summary) ProtoMessage() {} -func (*Summary) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{4} + SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` + SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` + Quantile []*Quantile `protobuf:"bytes,3,rep,name=quantile" json:"quantile,omitempty"` } -func (m *Summary) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Summary.Unmarshal(m, b) -} -func (m *Summary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Summary.Marshal(b, m, deterministic) -} -func (m *Summary) XXX_Merge(src proto.Message) { - xxx_messageInfo_Summary.Merge(m, src) +func (x *Summary) Reset() { + *x = Summary{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Summary) XXX_Size() int { - return xxx_messageInfo_Summary.Size(m) + +func (x *Summary) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Summary) XXX_DiscardUnknown() { - xxx_messageInfo_Summary.DiscardUnknown(m) + +func (*Summary) ProtoMessage() {} + +func (x *Summary) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Summary proto.InternalMessageInfo +// Deprecated: Use Summary.ProtoReflect.Descriptor instead. +func (*Summary) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{4} +} -func (m *Summary) GetSampleCount() uint64 { - if m != nil && m.SampleCount != nil { - return *m.SampleCount +func (x *Summary) GetSampleCount() uint64 { + if x != nil && x.SampleCount != nil { + return *x.SampleCount } return 0 } -func (m *Summary) GetSampleSum() float64 { - if m != nil && m.SampleSum != nil { - return *m.SampleSum +func (x *Summary) GetSampleSum() float64 { + if x != nil && x.SampleSum != nil { + return *x.SampleSum } return 0 } -func (m *Summary) GetQuantile() []*Quantile { - if m != nil { - return m.Quantile +func (x *Summary) GetQuantile() []*Quantile { + if x != nil { + return x.Quantile } return nil } type Untyped struct { - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Untyped) Reset() { *m = Untyped{} } -func (m *Untyped) String() string { return proto.CompactTextString(m) } -func (*Untyped) ProtoMessage() {} -func (*Untyped) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{5} + Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` } -func (m *Untyped) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Untyped.Unmarshal(m, b) -} -func (m *Untyped) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Untyped.Marshal(b, m, deterministic) -} -func (m *Untyped) XXX_Merge(src proto.Message) { - xxx_messageInfo_Untyped.Merge(m, src) +func (x *Untyped) Reset() { + *x = Untyped{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Untyped) XXX_Size() int { - return xxx_messageInfo_Untyped.Size(m) + +func (x *Untyped) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Untyped) XXX_DiscardUnknown() { - xxx_messageInfo_Untyped.DiscardUnknown(m) + +func (*Untyped) ProtoMessage() {} + +func (x *Untyped) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Untyped proto.InternalMessageInfo +// Deprecated: Use Untyped.ProtoReflect.Descriptor instead. +func (*Untyped) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{5} +} -func (m *Untyped) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value +func (x *Untyped) GetValue() float64 { + if x != nil && x.Value != nil { + return *x.Value } return 0 } type Histogram struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` - SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"` + SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"` // Overrides sample_count if > 0. SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` // Buckets for the conventional histogram. - Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"` + Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"` // Ordered in increasing order of upper_bound, +Inf bucket is optional. // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8. // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and // then each power of two is divided into 2^n logarithmic buckets. // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n). // In the future, more bucket schemas may be added using numbers < -4 or > 8. Schema *int32 `protobuf:"zigzag32,5,opt,name=schema" json:"schema,omitempty"` - ZeroThreshold *float64 `protobuf:"fixed64,6,opt,name=zero_threshold,json=zeroThreshold" json:"zero_threshold,omitempty"` - ZeroCount *uint64 `protobuf:"varint,7,opt,name=zero_count,json=zeroCount" json:"zero_count,omitempty"` - ZeroCountFloat *float64 `protobuf:"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat" json:"zero_count_float,omitempty"` + ZeroThreshold *float64 `protobuf:"fixed64,6,opt,name=zero_threshold,json=zeroThreshold" json:"zero_threshold,omitempty"` // Breadth of the zero bucket. + ZeroCount *uint64 `protobuf:"varint,7,opt,name=zero_count,json=zeroCount" json:"zero_count,omitempty"` // Count in zero bucket. + ZeroCountFloat *float64 `protobuf:"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat" json:"zero_count_float,omitempty"` // Overrides sb_zero_count if > 0. // Negative buckets for the native histogram. NegativeSpan []*BucketSpan `protobuf:"bytes,9,rep,name=negative_span,json=negativeSpan" json:"negative_span,omitempty"` // Use either "negative_delta" or "negative_count", the former for // regular histograms with integer counts, the latter for float // histograms. - NegativeDelta []int64 `protobuf:"zigzag64,10,rep,name=negative_delta,json=negativeDelta" json:"negative_delta,omitempty"` - NegativeCount []float64 `protobuf:"fixed64,11,rep,name=negative_count,json=negativeCount" json:"negative_count,omitempty"` + NegativeDelta []int64 `protobuf:"zigzag64,10,rep,name=negative_delta,json=negativeDelta" json:"negative_delta,omitempty"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket). + NegativeCount []float64 `protobuf:"fixed64,11,rep,name=negative_count,json=negativeCount" json:"negative_count,omitempty"` // Absolute count of each bucket. // Positive buckets for the native histogram. PositiveSpan []*BucketSpan `protobuf:"bytes,12,rep,name=positive_span,json=positiveSpan" json:"positive_span,omitempty"` // Use either "positive_delta" or "positive_count", the former for // regular histograms with integer counts, the latter for float // histograms. - PositiveDelta []int64 `protobuf:"zigzag64,13,rep,name=positive_delta,json=positiveDelta" json:"positive_delta,omitempty"` - PositiveCount []float64 `protobuf:"fixed64,14,rep,name=positive_count,json=positiveCount" json:"positive_count,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + PositiveDelta []int64 `protobuf:"zigzag64,13,rep,name=positive_delta,json=positiveDelta" json:"positive_delta,omitempty"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket). + PositiveCount []float64 `protobuf:"fixed64,14,rep,name=positive_count,json=positiveCount" json:"positive_count,omitempty"` // Absolute count of each bucket. } -func (m *Histogram) Reset() { *m = Histogram{} } -func (m *Histogram) String() string { return proto.CompactTextString(m) } -func (*Histogram) ProtoMessage() {} -func (*Histogram) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{6} +func (x *Histogram) Reset() { + *x = Histogram{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Histogram) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Histogram.Unmarshal(m, b) +func (x *Histogram) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Histogram) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Histogram.Marshal(b, m, deterministic) -} -func (m *Histogram) XXX_Merge(src proto.Message) { - xxx_messageInfo_Histogram.Merge(m, src) -} -func (m *Histogram) XXX_Size() int { - return xxx_messageInfo_Histogram.Size(m) -} -func (m *Histogram) XXX_DiscardUnknown() { - xxx_messageInfo_Histogram.DiscardUnknown(m) + +func (*Histogram) ProtoMessage() {} + +func (x *Histogram) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Histogram proto.InternalMessageInfo +// Deprecated: Use Histogram.ProtoReflect.Descriptor instead. +func (*Histogram) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{6} +} -func (m *Histogram) GetSampleCount() uint64 { - if m != nil && m.SampleCount != nil { - return *m.SampleCount +func (x *Histogram) GetSampleCount() uint64 { + if x != nil && x.SampleCount != nil { + return *x.SampleCount } return 0 } -func (m *Histogram) GetSampleCountFloat() float64 { - if m != nil && m.SampleCountFloat != nil { - return *m.SampleCountFloat +func (x *Histogram) GetSampleCountFloat() float64 { + if x != nil && x.SampleCountFloat != nil { + return *x.SampleCountFloat } return 0 } -func (m *Histogram) GetSampleSum() float64 { - if m != nil && m.SampleSum != nil { - return *m.SampleSum +func (x *Histogram) GetSampleSum() float64 { + if x != nil && x.SampleSum != nil { + return *x.SampleSum } return 0 } -func (m *Histogram) GetBucket() []*Bucket { - if m != nil { - return m.Bucket +func (x *Histogram) GetBucket() []*Bucket { + if x != nil { + return x.Bucket } return nil } -func (m *Histogram) GetSchema() int32 { - if m != nil && m.Schema != nil { - return *m.Schema +func (x *Histogram) GetSchema() int32 { + if x != nil && x.Schema != nil { + return *x.Schema } return 0 } -func (m *Histogram) GetZeroThreshold() float64 { - if m != nil && m.ZeroThreshold != nil { - return *m.ZeroThreshold +func (x *Histogram) GetZeroThreshold() float64 { + if x != nil && x.ZeroThreshold != nil { + return *x.ZeroThreshold } return 0 } -func (m *Histogram) GetZeroCount() uint64 { - if m != nil && m.ZeroCount != nil { - return *m.ZeroCount +func (x *Histogram) GetZeroCount() uint64 { + if x != nil && x.ZeroCount != nil { + return *x.ZeroCount } return 0 } -func (m *Histogram) GetZeroCountFloat() float64 { - if m != nil && m.ZeroCountFloat != nil { - return *m.ZeroCountFloat +func (x *Histogram) GetZeroCountFloat() float64 { + if x != nil && x.ZeroCountFloat != nil { + return *x.ZeroCountFloat } return 0 } -func (m *Histogram) GetNegativeSpan() []*BucketSpan { - if m != nil { - return m.NegativeSpan +func (x *Histogram) GetNegativeSpan() []*BucketSpan { + if x != nil { + return x.NegativeSpan } return nil } -func (m *Histogram) GetNegativeDelta() []int64 { - if m != nil { - return m.NegativeDelta +func (x *Histogram) GetNegativeDelta() []int64 { + if x != nil { + return x.NegativeDelta } return nil } -func (m *Histogram) GetNegativeCount() []float64 { - if m != nil { - return m.NegativeCount +func (x *Histogram) GetNegativeCount() []float64 { + if x != nil { + return x.NegativeCount } return nil } -func (m *Histogram) GetPositiveSpan() []*BucketSpan { - if m != nil { - return m.PositiveSpan +func (x *Histogram) GetPositiveSpan() []*BucketSpan { + if x != nil { + return x.PositiveSpan } return nil } -func (m *Histogram) GetPositiveDelta() []int64 { - if m != nil { - return m.PositiveDelta +func (x *Histogram) GetPositiveDelta() []int64 { + if x != nil { + return x.PositiveDelta } return nil } -func (m *Histogram) GetPositiveCount() []float64 { - if m != nil { - return m.PositiveCount +func (x *Histogram) GetPositiveCount() []float64 { + if x != nil { + return x.PositiveCount } return nil } @@ -513,64 +598,72 @@ func (m *Histogram) GetPositiveCount() []float64 { // A Bucket of a conventional histogram, each of which is treated as // an individual counter-like time series by Prometheus. type Bucket struct { - CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"` - CumulativeCountFloat *float64 `protobuf:"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat" json:"cumulative_count_float,omitempty"` - UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"` // Cumulative in increasing order. + CumulativeCountFloat *float64 `protobuf:"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat" json:"cumulative_count_float,omitempty"` // Overrides cumulative_count if > 0. + UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"` // Inclusive. Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` } -func (m *Bucket) Reset() { *m = Bucket{} } -func (m *Bucket) String() string { return proto.CompactTextString(m) } -func (*Bucket) ProtoMessage() {} -func (*Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{7} +func (x *Bucket) Reset() { + *x = Bucket{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Bucket) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Bucket.Unmarshal(m, b) -} -func (m *Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Bucket.Marshal(b, m, deterministic) -} -func (m *Bucket) XXX_Merge(src proto.Message) { - xxx_messageInfo_Bucket.Merge(m, src) -} -func (m *Bucket) XXX_Size() int { - return xxx_messageInfo_Bucket.Size(m) +func (x *Bucket) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Bucket) XXX_DiscardUnknown() { - xxx_messageInfo_Bucket.DiscardUnknown(m) + +func (*Bucket) ProtoMessage() {} + +func (x *Bucket) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Bucket proto.InternalMessageInfo +// Deprecated: Use Bucket.ProtoReflect.Descriptor instead. +func (*Bucket) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{7} +} -func (m *Bucket) GetCumulativeCount() uint64 { - if m != nil && m.CumulativeCount != nil { - return *m.CumulativeCount +func (x *Bucket) GetCumulativeCount() uint64 { + if x != nil && x.CumulativeCount != nil { + return *x.CumulativeCount } return 0 } -func (m *Bucket) GetCumulativeCountFloat() float64 { - if m != nil && m.CumulativeCountFloat != nil { - return *m.CumulativeCountFloat +func (x *Bucket) GetCumulativeCountFloat() float64 { + if x != nil && x.CumulativeCountFloat != nil { + return *x.CumulativeCountFloat } return 0 } -func (m *Bucket) GetUpperBound() float64 { - if m != nil && m.UpperBound != nil { - return *m.UpperBound +func (x *Bucket) GetUpperBound() float64 { + if x != nil && x.UpperBound != nil { + return *x.UpperBound } return 0 } -func (m *Bucket) GetExemplar() *Exemplar { - if m != nil { - return m.Exemplar +func (x *Bucket) GetExemplar() *Exemplar { + if x != nil { + return x.Exemplar } return nil } @@ -582,333 +675,658 @@ func (m *Bucket) GetExemplar() *Exemplar { // structured here (with all the buckets in a single array separate // from the Spans). type BucketSpan struct { - Offset *int32 `protobuf:"zigzag32,1,opt,name=offset" json:"offset,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *BucketSpan) Reset() { *m = BucketSpan{} } -func (m *BucketSpan) String() string { return proto.CompactTextString(m) } -func (*BucketSpan) ProtoMessage() {} -func (*BucketSpan) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{8} + Offset *int32 `protobuf:"zigzag32,1,opt,name=offset" json:"offset,omitempty"` // Gap to previous span, or starting point for 1st span (which can be negative). + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` // Length of consecutive buckets. } -func (m *BucketSpan) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BucketSpan.Unmarshal(m, b) -} -func (m *BucketSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BucketSpan.Marshal(b, m, deterministic) -} -func (m *BucketSpan) XXX_Merge(src proto.Message) { - xxx_messageInfo_BucketSpan.Merge(m, src) +func (x *BucketSpan) Reset() { + *x = BucketSpan{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *BucketSpan) XXX_Size() int { - return xxx_messageInfo_BucketSpan.Size(m) + +func (x *BucketSpan) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *BucketSpan) XXX_DiscardUnknown() { - xxx_messageInfo_BucketSpan.DiscardUnknown(m) + +func (*BucketSpan) ProtoMessage() {} + +func (x *BucketSpan) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_BucketSpan proto.InternalMessageInfo +// Deprecated: Use BucketSpan.ProtoReflect.Descriptor instead. +func (*BucketSpan) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{8} +} -func (m *BucketSpan) GetOffset() int32 { - if m != nil && m.Offset != nil { - return *m.Offset +func (x *BucketSpan) GetOffset() int32 { + if x != nil && x.Offset != nil { + return *x.Offset } return 0 } -func (m *BucketSpan) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length +func (x *BucketSpan) GetLength() uint32 { + if x != nil && x.Length != nil { + return *x.Length } return 0 } type Exemplar struct { - Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` - Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` - Timestamp *timestamp.Timestamp `protobuf:"bytes,3,opt,name=timestamp" json:"timestamp,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Exemplar) Reset() { *m = Exemplar{} } -func (m *Exemplar) String() string { return proto.CompactTextString(m) } -func (*Exemplar) ProtoMessage() {} -func (*Exemplar) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{9} + Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` + Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp" json:"timestamp,omitempty"` // OpenMetrics-style. } -func (m *Exemplar) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Exemplar.Unmarshal(m, b) -} -func (m *Exemplar) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Exemplar.Marshal(b, m, deterministic) -} -func (m *Exemplar) XXX_Merge(src proto.Message) { - xxx_messageInfo_Exemplar.Merge(m, src) +func (x *Exemplar) Reset() { + *x = Exemplar{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Exemplar) XXX_Size() int { - return xxx_messageInfo_Exemplar.Size(m) + +func (x *Exemplar) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Exemplar) XXX_DiscardUnknown() { - xxx_messageInfo_Exemplar.DiscardUnknown(m) + +func (*Exemplar) ProtoMessage() {} + +func (x *Exemplar) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Exemplar proto.InternalMessageInfo +// Deprecated: Use Exemplar.ProtoReflect.Descriptor instead. +func (*Exemplar) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{9} +} -func (m *Exemplar) GetLabel() []*LabelPair { - if m != nil { - return m.Label +func (x *Exemplar) GetLabel() []*LabelPair { + if x != nil { + return x.Label } return nil } -func (m *Exemplar) GetValue() float64 { - if m != nil && m.Value != nil { - return *m.Value +func (x *Exemplar) GetValue() float64 { + if x != nil && x.Value != nil { + return *x.Value } return 0 } -func (m *Exemplar) GetTimestamp() *timestamp.Timestamp { - if m != nil { - return m.Timestamp +func (x *Exemplar) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp } return nil } type Metric struct { - Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` - Gauge *Gauge `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"` - Counter *Counter `protobuf:"bytes,3,opt,name=counter" json:"counter,omitempty"` - Summary *Summary `protobuf:"bytes,4,opt,name=summary" json:"summary,omitempty"` - Untyped *Untyped `protobuf:"bytes,5,opt,name=untyped" json:"untyped,omitempty"` - Histogram *Histogram `protobuf:"bytes,7,opt,name=histogram" json:"histogram,omitempty"` - TimestampMs *int64 `protobuf:"varint,6,opt,name=timestamp_ms,json=timestampMs" json:"timestamp_ms,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Metric) Reset() { *m = Metric{} } -func (m *Metric) String() string { return proto.CompactTextString(m) } -func (*Metric) ProtoMessage() {} -func (*Metric) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{10} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` + Gauge *Gauge `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"` + Counter *Counter `protobuf:"bytes,3,opt,name=counter" json:"counter,omitempty"` + Summary *Summary `protobuf:"bytes,4,opt,name=summary" json:"summary,omitempty"` + Untyped *Untyped `protobuf:"bytes,5,opt,name=untyped" json:"untyped,omitempty"` + Histogram *Histogram `protobuf:"bytes,7,opt,name=histogram" json:"histogram,omitempty"` + TimestampMs *int64 `protobuf:"varint,6,opt,name=timestamp_ms,json=timestampMs" json:"timestamp_ms,omitempty"` +} + +func (x *Metric) Reset() { + *x = Metric{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Metric) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Metric.Unmarshal(m, b) +func (x *Metric) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Metric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Metric.Marshal(b, m, deterministic) -} -func (m *Metric) XXX_Merge(src proto.Message) { - xxx_messageInfo_Metric.Merge(m, src) -} -func (m *Metric) XXX_Size() int { - return xxx_messageInfo_Metric.Size(m) -} -func (m *Metric) XXX_DiscardUnknown() { - xxx_messageInfo_Metric.DiscardUnknown(m) + +func (*Metric) ProtoMessage() {} + +func (x *Metric) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Metric proto.InternalMessageInfo +// Deprecated: Use Metric.ProtoReflect.Descriptor instead. +func (*Metric) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{10} +} -func (m *Metric) GetLabel() []*LabelPair { - if m != nil { - return m.Label +func (x *Metric) GetLabel() []*LabelPair { + if x != nil { + return x.Label } return nil } -func (m *Metric) GetGauge() *Gauge { - if m != nil { - return m.Gauge +func (x *Metric) GetGauge() *Gauge { + if x != nil { + return x.Gauge } return nil } -func (m *Metric) GetCounter() *Counter { - if m != nil { - return m.Counter +func (x *Metric) GetCounter() *Counter { + if x != nil { + return x.Counter } return nil } -func (m *Metric) GetSummary() *Summary { - if m != nil { - return m.Summary +func (x *Metric) GetSummary() *Summary { + if x != nil { + return x.Summary } return nil } -func (m *Metric) GetUntyped() *Untyped { - if m != nil { - return m.Untyped +func (x *Metric) GetUntyped() *Untyped { + if x != nil { + return x.Untyped } return nil } -func (m *Metric) GetHistogram() *Histogram { - if m != nil { - return m.Histogram +func (x *Metric) GetHistogram() *Histogram { + if x != nil { + return x.Histogram } return nil } -func (m *Metric) GetTimestampMs() int64 { - if m != nil && m.TimestampMs != nil { - return *m.TimestampMs +func (x *Metric) GetTimestampMs() int64 { + if x != nil && x.TimestampMs != nil { + return *x.TimestampMs } return 0 } type MetricFamily struct { - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Help *string `protobuf:"bytes,2,opt,name=help" json:"help,omitempty"` - Type *MetricType `protobuf:"varint,3,opt,name=type,enum=io.prometheus.client.MetricType" json:"type,omitempty"` - Metric []*Metric `protobuf:"bytes,4,rep,name=metric" json:"metric,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MetricFamily) Reset() { *m = MetricFamily{} } -func (m *MetricFamily) String() string { return proto.CompactTextString(m) } -func (*MetricFamily) ProtoMessage() {} -func (*MetricFamily) Descriptor() ([]byte, []int) { - return fileDescriptor_d1e5ddb18987a258, []int{11} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Help *string `protobuf:"bytes,2,opt,name=help" json:"help,omitempty"` + Type *MetricType `protobuf:"varint,3,opt,name=type,enum=io.prometheus.client.MetricType" json:"type,omitempty"` + Metric []*Metric `protobuf:"bytes,4,rep,name=metric" json:"metric,omitempty"` +} + +func (x *MetricFamily) Reset() { + *x = MetricFamily{} + if protoimpl.UnsafeEnabled { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *MetricFamily) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MetricFamily.Unmarshal(m, b) -} -func (m *MetricFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MetricFamily.Marshal(b, m, deterministic) -} -func (m *MetricFamily) XXX_Merge(src proto.Message) { - xxx_messageInfo_MetricFamily.Merge(m, src) -} -func (m *MetricFamily) XXX_Size() int { - return xxx_messageInfo_MetricFamily.Size(m) +func (x *MetricFamily) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *MetricFamily) XXX_DiscardUnknown() { - xxx_messageInfo_MetricFamily.DiscardUnknown(m) + +func (*MetricFamily) ProtoMessage() {} + +func (x *MetricFamily) ProtoReflect() protoreflect.Message { + mi := &file_io_prometheus_client_metrics_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_MetricFamily proto.InternalMessageInfo +// Deprecated: Use MetricFamily.ProtoReflect.Descriptor instead. +func (*MetricFamily) Descriptor() ([]byte, []int) { + return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{11} +} -func (m *MetricFamily) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (x *MetricFamily) GetName() string { + if x != nil && x.Name != nil { + return *x.Name } return "" } -func (m *MetricFamily) GetHelp() string { - if m != nil && m.Help != nil { - return *m.Help +func (x *MetricFamily) GetHelp() string { + if x != nil && x.Help != nil { + return *x.Help } return "" } -func (m *MetricFamily) GetType() MetricType { - if m != nil && m.Type != nil { - return *m.Type +func (x *MetricFamily) GetType() MetricType { + if x != nil && x.Type != nil { + return *x.Type } return MetricType_COUNTER } -func (m *MetricFamily) GetMetric() []*Metric { - if m != nil { - return m.Metric +func (x *MetricFamily) GetMetric() []*Metric { + if x != nil { + return x.Metric } return nil } -func init() { - proto.RegisterEnum("io.prometheus.client.MetricType", MetricType_name, MetricType_value) - proto.RegisterType((*LabelPair)(nil), "io.prometheus.client.LabelPair") - proto.RegisterType((*Gauge)(nil), "io.prometheus.client.Gauge") - proto.RegisterType((*Counter)(nil), "io.prometheus.client.Counter") - proto.RegisterType((*Quantile)(nil), "io.prometheus.client.Quantile") - proto.RegisterType((*Summary)(nil), "io.prometheus.client.Summary") - proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped") - proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram") - proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket") - proto.RegisterType((*BucketSpan)(nil), "io.prometheus.client.BucketSpan") - proto.RegisterType((*Exemplar)(nil), "io.prometheus.client.Exemplar") - proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric") - proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily") -} - -func init() { - proto.RegisterFile("io/prometheus/client/metrics.proto", fileDescriptor_d1e5ddb18987a258) -} - -var fileDescriptor_d1e5ddb18987a258 = []byte{ - // 896 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0xdb, 0x44, - 0x18, 0xc5, 0x9b, 0x5f, 0x7f, 0xd9, 0x6c, 0xd3, 0x61, 0x55, 0x59, 0x0b, 0xcb, 0x06, 0x4b, 0x48, - 0x0b, 0x42, 0x8e, 0x40, 0x5b, 0x81, 0x0a, 0x5c, 0xec, 0xb6, 0xe9, 0x16, 0x89, 0xb4, 0x65, 0x92, - 0x5c, 0x14, 0x2e, 0xac, 0x49, 0x32, 0xeb, 0x58, 0x78, 0x3c, 0xc6, 0x1e, 0x57, 0x2c, 0x2f, 0xc0, - 0x35, 0xaf, 0xc0, 0xc3, 0xf0, 0x22, 0x3c, 0x08, 0x68, 0xfe, 0xec, 0xdd, 0xe2, 0x94, 0xd2, 0x3b, - 0x7f, 0x67, 0xce, 0xf7, 0xcd, 0x39, 0xe3, 0xc9, 0x71, 0xc0, 0x8f, 0xf9, 0x24, 0xcb, 0x39, 0xa3, - 0x62, 0x4b, 0xcb, 0x62, 0xb2, 0x4e, 0x62, 0x9a, 0x8a, 0x09, 0xa3, 0x22, 0x8f, 0xd7, 0x45, 0x90, - 0xe5, 0x5c, 0x70, 0x74, 0x18, 0xf3, 0xa0, 0xe6, 0x04, 0x9a, 0x73, 0x74, 0x12, 0x71, 0x1e, 0x25, - 0x74, 0xa2, 0x38, 0xab, 0xf2, 0x6a, 0x22, 0x62, 0x46, 0x0b, 0x41, 0x58, 0xa6, 0xdb, 0xfc, 0xfb, - 0xe0, 0x7e, 0x47, 0x56, 0x34, 0x79, 0x4e, 0xe2, 0x1c, 0x21, 0x68, 0xa7, 0x84, 0x51, 0xcf, 0x19, - 0x3b, 0xa7, 0x2e, 0x56, 0xcf, 0xe8, 0x10, 0x3a, 0x2f, 0x49, 0x52, 0x52, 0x6f, 0x4f, 0x81, 0xba, - 0xf0, 0x8f, 0xa1, 0x73, 0x49, 0xca, 0xe8, 0xc6, 0xb2, 0xec, 0x71, 0xec, 0xf2, 0x8f, 0xd0, 0x7b, - 0xc8, 0xcb, 0x54, 0xd0, 0xbc, 0x99, 0x80, 0x1e, 0x40, 0x9f, 0xfe, 0x42, 0x59, 0x96, 0x90, 0x5c, - 0x0d, 0x1e, 0x7c, 0xfe, 0x41, 0xd0, 0x64, 0x20, 0x98, 0x1a, 0x16, 0xae, 0xf8, 0xfe, 0xd7, 0xd0, - 0xff, 0xbe, 0x24, 0xa9, 0x88, 0x13, 0x8a, 0x8e, 0xa0, 0xff, 0xb3, 0x79, 0x36, 0x1b, 0x54, 0xf5, - 0x6d, 0xe5, 0x95, 0xb4, 0xdf, 0x1c, 0xe8, 0xcd, 0x4b, 0xc6, 0x48, 0x7e, 0x8d, 0x3e, 0x84, 0xfd, - 0x82, 0xb0, 0x2c, 0xa1, 0xe1, 0x5a, 0xaa, 0x55, 0x13, 0xda, 0x78, 0xa0, 0x31, 0x65, 0x00, 0x1d, - 0x03, 0x18, 0x4a, 0x51, 0x32, 0x33, 0xc9, 0xd5, 0xc8, 0xbc, 0x64, 0xd2, 0x47, 0xb5, 0x7f, 0x6b, - 0xdc, 0xda, 0xed, 0xc3, 0x2a, 0xae, 0xf5, 0xf9, 0x27, 0xd0, 0x5b, 0xa6, 0xe2, 0x3a, 0xa3, 0x9b, - 0x1d, 0xa7, 0xf8, 0x57, 0x1b, 0xdc, 0x27, 0x71, 0x21, 0x78, 0x94, 0x13, 0xf6, 0x26, 0x62, 0x3f, - 0x05, 0x74, 0x93, 0x12, 0x5e, 0x25, 0x9c, 0x08, 0xaf, 0xad, 0x66, 0x8e, 0x6e, 0x10, 0x1f, 0x4b, - 0xfc, 0xbf, 0xac, 0x9d, 0x41, 0x77, 0x55, 0xae, 0x7f, 0xa2, 0xc2, 0x18, 0x7b, 0xbf, 0xd9, 0xd8, - 0x85, 0xe2, 0x60, 0xc3, 0x45, 0xf7, 0xa0, 0x5b, 0xac, 0xb7, 0x94, 0x11, 0xaf, 0x33, 0x76, 0x4e, - 0xef, 0x62, 0x53, 0xa1, 0x8f, 0xe0, 0xe0, 0x57, 0x9a, 0xf3, 0x50, 0x6c, 0x73, 0x5a, 0x6c, 0x79, - 0xb2, 0xf1, 0xba, 0x6a, 0xc3, 0xa1, 0x44, 0x17, 0x16, 0x94, 0x9a, 0x14, 0x4d, 0x5b, 0xec, 0x29, - 0x8b, 0xae, 0x44, 0xb4, 0xc1, 0x53, 0x18, 0xd5, 0xcb, 0xc6, 0x5e, 0x5f, 0xcd, 0x39, 0xa8, 0x48, - 0xda, 0xdc, 0x14, 0x86, 0x29, 0x8d, 0x88, 0x88, 0x5f, 0xd2, 0xb0, 0xc8, 0x48, 0xea, 0xb9, 0xca, - 0xc4, 0xf8, 0x75, 0x26, 0xe6, 0x19, 0x49, 0xf1, 0xbe, 0x6d, 0x93, 0x95, 0x94, 0x5d, 0x8d, 0xd9, - 0xd0, 0x44, 0x10, 0x0f, 0xc6, 0xad, 0x53, 0x84, 0xab, 0xe1, 0x8f, 0x24, 0x78, 0x8b, 0xa6, 0xa5, - 0x0f, 0xc6, 0x2d, 0xe9, 0xce, 0xa2, 0x5a, 0xfe, 0x14, 0x86, 0x19, 0x2f, 0xe2, 0x5a, 0xd4, 0xfe, - 0x9b, 0x8a, 0xb2, 0x6d, 0x56, 0x54, 0x35, 0x46, 0x8b, 0x1a, 0x6a, 0x51, 0x16, 0xad, 0x44, 0x55, - 0x34, 0x2d, 0xea, 0x40, 0x8b, 0xb2, 0xa8, 0x12, 0xe5, 0xff, 0xe9, 0x40, 0x57, 0x6f, 0x85, 0x3e, - 0x86, 0xd1, 0xba, 0x64, 0x65, 0x72, 0xd3, 0x88, 0xbe, 0x66, 0x77, 0x6a, 0x5c, 0x5b, 0x39, 0x83, - 0x7b, 0xaf, 0x52, 0x6f, 0x5d, 0xb7, 0xc3, 0x57, 0x1a, 0xf4, 0x5b, 0x39, 0x81, 0x41, 0x99, 0x65, - 0x34, 0x0f, 0x57, 0xbc, 0x4c, 0x37, 0xe6, 0xce, 0x81, 0x82, 0x2e, 0x24, 0x72, 0x2b, 0x17, 0x5a, - 0xff, 0x3b, 0x17, 0xa0, 0x3e, 0x32, 0x79, 0x11, 0xf9, 0xd5, 0x55, 0x41, 0xb5, 0x83, 0xbb, 0xd8, - 0x54, 0x12, 0x4f, 0x68, 0x1a, 0x89, 0xad, 0xda, 0x7d, 0x88, 0x4d, 0xe5, 0xff, 0xee, 0x40, 0xdf, - 0x0e, 0x45, 0xf7, 0xa1, 0x93, 0xc8, 0x54, 0xf4, 0x1c, 0xf5, 0x82, 0x4e, 0x9a, 0x35, 0x54, 0xc1, - 0x89, 0x35, 0xbb, 0x39, 0x71, 0xd0, 0x97, 0xe0, 0x56, 0xa9, 0x6b, 0x4c, 0x1d, 0x05, 0x3a, 0x97, - 0x03, 0x9b, 0xcb, 0xc1, 0xc2, 0x32, 0x70, 0x4d, 0xf6, 0xff, 0xde, 0x83, 0xee, 0x4c, 0xa5, 0xfc, - 0xdb, 0x2a, 0xfa, 0x0c, 0x3a, 0x91, 0xcc, 0x69, 0x13, 0xb2, 0xef, 0x35, 0xb7, 0xa9, 0x28, 0xc7, - 0x9a, 0x89, 0xbe, 0x80, 0xde, 0x5a, 0x67, 0xb7, 0x11, 0x7b, 0xdc, 0xdc, 0x64, 0x02, 0x1e, 0x5b, - 0xb6, 0x6c, 0x2c, 0x74, 0xb0, 0xaa, 0x3b, 0xb0, 0xb3, 0xd1, 0xa4, 0x2f, 0xb6, 0x6c, 0xd9, 0x58, - 0xea, 0x20, 0x54, 0xa1, 0xb1, 0xb3, 0xd1, 0xa4, 0x25, 0xb6, 0x6c, 0xf4, 0x0d, 0xb8, 0x5b, 0x9b, - 0x8f, 0x2a, 0x2c, 0x76, 0x1e, 0x4c, 0x15, 0xa3, 0xb8, 0xee, 0x90, 0x89, 0x5a, 0x9d, 0x75, 0xc8, - 0x0a, 0x95, 0x48, 0x2d, 0x3c, 0xa8, 0xb0, 0x59, 0xe1, 0xff, 0xe1, 0xc0, 0xbe, 0x7e, 0x03, 0x8f, - 0x09, 0x8b, 0x93, 0xeb, 0xc6, 0x4f, 0x24, 0x82, 0xf6, 0x96, 0x26, 0x99, 0xf9, 0x42, 0xaa, 0x67, - 0x74, 0x06, 0x6d, 0xa9, 0x51, 0x1d, 0xe1, 0xc1, 0xae, 0x5f, 0xb8, 0x9e, 0xbc, 0xb8, 0xce, 0x28, - 0x56, 0x6c, 0x99, 0xb9, 0xfa, 0xab, 0xee, 0xb5, 0x5f, 0x97, 0xb9, 0xba, 0x0f, 0x1b, 0xee, 0x27, - 0x2b, 0x80, 0x7a, 0x12, 0x1a, 0x40, 0xef, 0xe1, 0xb3, 0xe5, 0xd3, 0xc5, 0x14, 0x8f, 0xde, 0x41, - 0x2e, 0x74, 0x2e, 0xcf, 0x97, 0x97, 0xd3, 0x91, 0x23, 0xf1, 0xf9, 0x72, 0x36, 0x3b, 0xc7, 0x2f, - 0x46, 0x7b, 0xb2, 0x58, 0x3e, 0x5d, 0xbc, 0x78, 0x3e, 0x7d, 0x34, 0x6a, 0xa1, 0x21, 0xb8, 0x4f, - 0xbe, 0x9d, 0x2f, 0x9e, 0x5d, 0xe2, 0xf3, 0xd9, 0xa8, 0x8d, 0xde, 0x85, 0x3b, 0xaa, 0x27, 0xac, - 0xc1, 0xce, 0x05, 0x86, 0xc6, 0x3f, 0x18, 0x3f, 0x3c, 0x88, 0x62, 0xb1, 0x2d, 0x57, 0xc1, 0x9a, - 0xb3, 0x7f, 0xff, 0x45, 0x09, 0x19, 0xdf, 0xd0, 0x64, 0x12, 0xf1, 0xaf, 0x62, 0x1e, 0xd6, 0xab, - 0xa1, 0x5e, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x16, 0x77, 0x81, 0x98, 0xd7, 0x08, 0x00, 0x00, +var File_io_prometheus_client_metrics_proto protoreflect.FileDescriptor + +var file_io_prometheus_client_metrics_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2f, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, + 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x1d, 0x0a, 0x05, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x5b, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, + 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x22, 0x3c, + 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, + 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x71, 0x75, + 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x87, 0x01, 0x0a, + 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x08, 0x71, 0x75, + 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x71, 0x75, + 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x22, 0x1f, 0x0a, 0x07, 0x55, 0x6e, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xe3, 0x04, 0x0a, 0x09, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x34, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, + 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x63, + 0x6b, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x7a, 0x65, 0x72, + 0x6f, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x7a, 0x65, + 0x72, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, + 0x7a, 0x65, 0x72, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x7a, 0x65, 0x72, + 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, + 0x6f, 0x61, 0x74, 0x12, 0x45, 0x0a, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x73, 0x70, 0x61, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x6f, 0x2e, + 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x0c, 0x6e, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x03, + 0x28, 0x12, 0x52, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x74, + 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0d, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, + 0x6e, 0x52, 0x0c, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, + 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, + 0x61, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x12, 0x52, 0x0d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc6, 0x01, + 0x0a, 0x06, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x75, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0f, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x14, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x70, + 0x65, 0x72, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, + 0x75, 0x70, 0x70, 0x65, 0x72, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x22, 0x3c, 0x0a, 0x0a, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x53, 0x70, 0x61, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x22, 0x91, 0x01, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x72, 0x12, 0x35, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, + 0x72, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xff, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x12, 0x35, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, + 0x61, 0x69, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x31, 0x0a, 0x05, 0x67, 0x61, + 0x75, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x69, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x47, 0x61, 0x75, 0x67, 0x65, 0x52, 0x05, 0x67, 0x61, 0x75, 0x67, 0x65, 0x12, 0x37, 0x0a, + 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, + 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x37, 0x0a, 0x07, 0x75, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x52, + 0x07, 0x75, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x69, 0x73, 0x74, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, + 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x09, 0x68, 0x69, + 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0c, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, + 0x65, 0x6c, 0x70, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x20, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, + 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2a, + 0x62, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, + 0x55, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, 0x59, + 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x54, 0x59, 0x50, 0x45, 0x44, 0x10, 0x03, 0x12, + 0x0d, 0x0a, 0x09, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10, 0x04, 0x12, 0x13, + 0x0a, 0x0f, 0x47, 0x41, 0x55, 0x47, 0x45, 0x5f, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, + 0x4d, 0x10, 0x05, 0x42, 0x52, 0x0a, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, + 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5a, 0x3a, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, + 0x67, 0x6f, 0x3b, 0x69, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, + 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, +} + +var ( + file_io_prometheus_client_metrics_proto_rawDescOnce sync.Once + file_io_prometheus_client_metrics_proto_rawDescData = file_io_prometheus_client_metrics_proto_rawDesc +) + +func file_io_prometheus_client_metrics_proto_rawDescGZIP() []byte { + file_io_prometheus_client_metrics_proto_rawDescOnce.Do(func() { + file_io_prometheus_client_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_io_prometheus_client_metrics_proto_rawDescData) + }) + return file_io_prometheus_client_metrics_proto_rawDescData +} + +var file_io_prometheus_client_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_io_prometheus_client_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_io_prometheus_client_metrics_proto_goTypes = []interface{}{ + (MetricType)(0), // 0: io.prometheus.client.MetricType + (*LabelPair)(nil), // 1: io.prometheus.client.LabelPair + (*Gauge)(nil), // 2: io.prometheus.client.Gauge + (*Counter)(nil), // 3: io.prometheus.client.Counter + (*Quantile)(nil), // 4: io.prometheus.client.Quantile + (*Summary)(nil), // 5: io.prometheus.client.Summary + (*Untyped)(nil), // 6: io.prometheus.client.Untyped + (*Histogram)(nil), // 7: io.prometheus.client.Histogram + (*Bucket)(nil), // 8: io.prometheus.client.Bucket + (*BucketSpan)(nil), // 9: io.prometheus.client.BucketSpan + (*Exemplar)(nil), // 10: io.prometheus.client.Exemplar + (*Metric)(nil), // 11: io.prometheus.client.Metric + (*MetricFamily)(nil), // 12: io.prometheus.client.MetricFamily + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp +} +var file_io_prometheus_client_metrics_proto_depIdxs = []int32{ + 10, // 0: io.prometheus.client.Counter.exemplar:type_name -> io.prometheus.client.Exemplar + 4, // 1: io.prometheus.client.Summary.quantile:type_name -> io.prometheus.client.Quantile + 8, // 2: io.prometheus.client.Histogram.bucket:type_name -> io.prometheus.client.Bucket + 9, // 3: io.prometheus.client.Histogram.negative_span:type_name -> io.prometheus.client.BucketSpan + 9, // 4: io.prometheus.client.Histogram.positive_span:type_name -> io.prometheus.client.BucketSpan + 10, // 5: io.prometheus.client.Bucket.exemplar:type_name -> io.prometheus.client.Exemplar + 1, // 6: io.prometheus.client.Exemplar.label:type_name -> io.prometheus.client.LabelPair + 13, // 7: io.prometheus.client.Exemplar.timestamp:type_name -> google.protobuf.Timestamp + 1, // 8: io.prometheus.client.Metric.label:type_name -> io.prometheus.client.LabelPair + 2, // 9: io.prometheus.client.Metric.gauge:type_name -> io.prometheus.client.Gauge + 3, // 10: io.prometheus.client.Metric.counter:type_name -> io.prometheus.client.Counter + 5, // 11: io.prometheus.client.Metric.summary:type_name -> io.prometheus.client.Summary + 6, // 12: io.prometheus.client.Metric.untyped:type_name -> io.prometheus.client.Untyped + 7, // 13: io.prometheus.client.Metric.histogram:type_name -> io.prometheus.client.Histogram + 0, // 14: io.prometheus.client.MetricFamily.type:type_name -> io.prometheus.client.MetricType + 11, // 15: io.prometheus.client.MetricFamily.metric:type_name -> io.prometheus.client.Metric + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name +} + +func init() { file_io_prometheus_client_metrics_proto_init() } +func file_io_prometheus_client_metrics_proto_init() { + if File_io_prometheus_client_metrics_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_io_prometheus_client_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LabelPair); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Gauge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Counter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Quantile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Summary); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Untyped); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Histogram); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Bucket); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BucketSpan); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Exemplar); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Metric); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_io_prometheus_client_metrics_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetricFamily); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_io_prometheus_client_metrics_proto_rawDesc, + NumEnums: 1, + NumMessages: 12, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_io_prometheus_client_metrics_proto_goTypes, + DependencyIndexes: file_io_prometheus_client_metrics_proto_depIdxs, + EnumInfos: file_io_prometheus_client_metrics_proto_enumTypes, + MessageInfos: file_io_prometheus_client_metrics_proto_msgTypes, + }.Build() + File_io_prometheus_client_metrics_proto = out.File + file_io_prometheus_client_metrics_proto_rawDesc = nil + file_io_prometheus_client_metrics_proto_goTypes = nil + file_io_prometheus_client_metrics_proto_depIdxs = nil } diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index 7657f841d63..f4fc8845522 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -115,32 +115,28 @@ func (d *protoDecoder) Decode(v *dto.MetricFamily) error { // textDecoder implements the Decoder interface for the text protocol. type textDecoder struct { r io.Reader - p TextParser - fams []*dto.MetricFamily + fams map[string]*dto.MetricFamily + err error } // Decode implements the Decoder interface. func (d *textDecoder) Decode(v *dto.MetricFamily) error { - // TODO(fabxc): Wrap this as a line reader to make streaming safer. - if len(d.fams) == 0 { - // No cached metric families, read everything and parse metrics. - fams, err := d.p.TextToMetricFamilies(d.r) - if err != nil { - return err - } - if len(fams) == 0 { - return io.EOF - } - d.fams = make([]*dto.MetricFamily, 0, len(fams)) - for _, f := range fams { - d.fams = append(d.fams, f) + if d.err == nil { + // Read all metrics in one shot. + var p TextParser + d.fams, d.err = p.TextToMetricFamilies(d.r) + // If we don't get an error, store io.EOF for the end. + if d.err == nil { + d.err = io.EOF } } - - *v = *d.fams[0] - d.fams = d.fams[1:] - - return nil + // Pick off one MetricFamily per Decode until there's nothing left. + for key, fam := range d.fams { + *v = *fam + delete(d.fams, key) + return nil + } + return d.err } // SampleDecoder wraps a Decoder to extract samples from the metric families diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index f819e4f8b54..dfac962a4e7 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -21,8 +21,8 @@ import "bytes" // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: // -// go-fuzz-build github.com/prometheus/common/expfmt -// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz +// go-fuzz-build github.com/prometheus/common/expfmt +// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz // // Further input samples should go in the folder fuzz/corpus. func Fuzz(in []byte) int { diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go index 9d94ae9effe..21cdddcf054 100644 --- a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go @@ -46,20 +46,20 @@ import ( // missing features and peculiarities to avoid complications when switching from // Prometheus to OpenMetrics or vice versa: // -// - Counters are expected to have the `_total` suffix in their metric name. In -// the output, the suffix will be truncated from the `# TYPE` and `# HELP` -// line. A counter with a missing `_total` suffix is not an error. However, -// its type will be set to `unknown` in that case to avoid invalid OpenMetrics -// output. +// - Counters are expected to have the `_total` suffix in their metric name. In +// the output, the suffix will be truncated from the `# TYPE` and `# HELP` +// line. A counter with a missing `_total` suffix is not an error. However, +// its type will be set to `unknown` in that case to avoid invalid OpenMetrics +// output. // -// - No support for the following (optional) features: `# UNIT` line, `_created` -// line, info type, stateset type, gaugehistogram type. +// - No support for the following (optional) features: `# UNIT` line, `_created` +// line, info type, stateset type, gaugehistogram type. // -// - The size of exemplar labels is not checked (i.e. it's possible to create -// exemplars that are larger than allowed by the OpenMetrics specification). +// - The size of exemplar labels is not checked (i.e. it's possible to create +// exemplars that are larger than allowed by the OpenMetrics specification). // -// - The value of Counters is not checked. (OpenMetrics doesn't allow counters -// with a `NaN` value.) +// - The value of Counters is not checked. (OpenMetrics doesn't allow counters +// with a `NaN` value.) func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily) (written int, err error) { name := in.GetName() if name == "" { diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go index 5ba503b0654..2946b8f1a64 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_create.go +++ b/vendor/github.com/prometheus/common/expfmt/text_create.go @@ -17,7 +17,6 @@ import ( "bufio" "fmt" "io" - "io/ioutil" "math" "strconv" "strings" @@ -44,7 +43,7 @@ const ( var ( bufPool = sync.Pool{ New: func() interface{} { - return bufio.NewWriter(ioutil.Discard) + return bufio.NewWriter(io.Discard) }, } numBufPool = sync.Pool{ diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index 84be0643ec6..ac2482782c7 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -142,9 +142,13 @@ func (p *TextParser) reset(in io.Reader) { func (p *TextParser) startOfLine() stateFn { p.lineCount++ if p.skipBlankTab(); p.err != nil { - // End of input reached. This is the only case where - // that is not an error but a signal that we are done. - p.err = nil + // This is the only place that we expect to see io.EOF, + // which is not an error but the signal that we are done. + // Any other error that happens to align with the start of + // a line is still an error. + if p.err == io.EOF { + p.err = nil + } return nil } switch p.currentByte { diff --git a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go index 26e92288c7c..a21b9d15dd8 100644 --- a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go +++ b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go @@ -11,18 +11,18 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. - Neither the name of the Open Knowledge Foundation Ltd. nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. + Neither the name of the Open Knowledge Foundation Ltd. nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -35,8 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - */ package goautoneg diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index c909b8aa8c5..5727452c1ee 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -18,7 +18,6 @@ import ( "errors" "fmt" "math" - "regexp" "strconv" "strings" "time" @@ -183,54 +182,78 @@ func (d *Duration) Type() string { return "duration" } -var durationRE = regexp.MustCompile("^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$") +func isdigit(c byte) bool { return c >= '0' && c <= '9' } + +// Units are required to go in order from biggest to smallest. +// This guards against confusion from "1m1d" being 1 minute + 1 day, not 1 month + 1 day. +var unitMap = map[string]struct { + pos int + mult uint64 +}{ + "ms": {7, uint64(time.Millisecond)}, + "s": {6, uint64(time.Second)}, + "m": {5, uint64(time.Minute)}, + "h": {4, uint64(time.Hour)}, + "d": {3, uint64(24 * time.Hour)}, + "w": {2, uint64(7 * 24 * time.Hour)}, + "y": {1, uint64(365 * 24 * time.Hour)}, +} // ParseDuration parses a string into a time.Duration, assuming that a year // always has 365d, a week always has 7d, and a day always has 24h. -func ParseDuration(durationStr string) (Duration, error) { - switch durationStr { +func ParseDuration(s string) (Duration, error) { + switch s { case "0": // Allow 0 without a unit. return 0, nil case "": return 0, errors.New("empty duration string") } - matches := durationRE.FindStringSubmatch(durationStr) - if matches == nil { - return 0, fmt.Errorf("not a valid duration string: %q", durationStr) - } - var dur time.Duration - // Parse the match at pos `pos` in the regex and use `mult` to turn that - // into ms, then add that value to the total parsed duration. - var overflowErr error - m := func(pos int, mult time.Duration) { - if matches[pos] == "" { - return + orig := s + var dur uint64 + lastUnitPos := 0 + + for s != "" { + if !isdigit(s[0]) { + return 0, fmt.Errorf("not a valid duration string: %q", orig) + } + // Consume [0-9]* + i := 0 + for ; i < len(s) && isdigit(s[i]); i++ { + } + v, err := strconv.ParseUint(s[:i], 10, 0) + if err != nil { + return 0, fmt.Errorf("not a valid duration string: %q", orig) } - n, _ := strconv.Atoi(matches[pos]) + s = s[i:] + // Consume unit. + for i = 0; i < len(s) && !isdigit(s[i]); i++ { + } + if i == 0 { + return 0, fmt.Errorf("not a valid duration string: %q", orig) + } + u := s[:i] + s = s[i:] + unit, ok := unitMap[u] + if !ok { + return 0, fmt.Errorf("unknown unit %q in duration %q", u, orig) + } + if unit.pos <= lastUnitPos { // Units must go in order from biggest to smallest. + return 0, fmt.Errorf("not a valid duration string: %q", orig) + } + lastUnitPos = unit.pos // Check if the provided duration overflows time.Duration (> ~ 290years). - if n > int((1<<63-1)/mult/time.Millisecond) { - overflowErr = errors.New("duration out of range") + if v > 1<<63/unit.mult { + return 0, errors.New("duration out of range") } - d := time.Duration(n) * time.Millisecond - dur += d * mult - - if dur < 0 { - overflowErr = errors.New("duration out of range") + dur += v * unit.mult + if dur > 1<<63-1 { + return 0, errors.New("duration out of range") } } - - m(2, 1000*60*60*24*365) // y - m(4, 1000*60*60*24*7) // w - m(6, 1000*60*60*24) // d - m(8, 1000*60*60) // h - m(10, 1000*60) // m - m(12, 1000) // s - m(14, 1) // ms - - return Duration(dur), overflowErr + return Duration(dur), nil } func (d Duration) String() string { diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go index c9d8fb1a283..9eb440413fd 100644 --- a/vendor/github.com/prometheus/common/model/value.go +++ b/vendor/github.com/prometheus/common/model/value.go @@ -16,20 +16,12 @@ package model import ( "encoding/json" "fmt" - "math" "sort" "strconv" "strings" ) var ( - // ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a - // non-existing sample pair. It is a SamplePair with timestamp Earliest and - // value 0.0. Note that the natural zero value of SamplePair has a timestamp - // of 0, which is possible to appear in a real SamplePair and thus not - // suitable to signal a non-existing SamplePair. - ZeroSamplePair = SamplePair{Timestamp: Earliest} - // ZeroSample is the pseudo zero-value of Sample used to signal a // non-existing sample. It is a Sample with timestamp Earliest, value 0.0, // and metric nil. Note that the natural zero value of Sample has a timestamp @@ -38,82 +30,14 @@ var ( ZeroSample = Sample{Timestamp: Earliest} ) -// A SampleValue is a representation of a value for a given sample at a given -// time. -type SampleValue float64 - -// MarshalJSON implements json.Marshaler. -func (v SampleValue) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (v *SampleValue) UnmarshalJSON(b []byte) error { - if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { - return fmt.Errorf("sample value must be a quoted string") - } - f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) - if err != nil { - return err - } - *v = SampleValue(f) - return nil -} - -// Equal returns true if the value of v and o is equal or if both are NaN. Note -// that v==o is false if both are NaN. If you want the conventional float -// behavior, use == to compare two SampleValues. -func (v SampleValue) Equal(o SampleValue) bool { - if v == o { - return true - } - return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) -} - -func (v SampleValue) String() string { - return strconv.FormatFloat(float64(v), 'f', -1, 64) -} - -// SamplePair pairs a SampleValue with a Timestamp. -type SamplePair struct { - Timestamp Time - Value SampleValue -} - -// MarshalJSON implements json.Marshaler. -func (s SamplePair) MarshalJSON() ([]byte, error) { - t, err := json.Marshal(s.Timestamp) - if err != nil { - return nil, err - } - v, err := json.Marshal(s.Value) - if err != nil { - return nil, err - } - return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *SamplePair) UnmarshalJSON(b []byte) error { - v := [...]json.Unmarshaler{&s.Timestamp, &s.Value} - return json.Unmarshal(b, &v) -} - -// Equal returns true if this SamplePair and o have equal Values and equal -// Timestamps. The semantics of Value equality is defined by SampleValue.Equal. -func (s *SamplePair) Equal(o *SamplePair) bool { - return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) -} - -func (s SamplePair) String() string { - return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp) -} - -// Sample is a sample pair associated with a metric. +// Sample is a sample pair associated with a metric. A single sample must either +// define Value or Histogram but not both. Histogram == nil implies the Value +// field is used, otherwise it should be ignored. type Sample struct { - Metric Metric `json:"metric"` - Value SampleValue `json:"value"` - Timestamp Time `json:"timestamp"` + Metric Metric `json:"metric"` + Value SampleValue `json:"value"` + Timestamp Time `json:"timestamp"` + Histogram *SampleHistogram `json:"histogram"` } // Equal compares first the metrics, then the timestamp, then the value. The @@ -129,11 +53,19 @@ func (s *Sample) Equal(o *Sample) bool { if !s.Timestamp.Equal(o.Timestamp) { return false } - + if s.Histogram != nil { + return s.Histogram.Equal(o.Histogram) + } return s.Value.Equal(o.Value) } func (s Sample) String() string { + if s.Histogram != nil { + return fmt.Sprintf("%s => %s", s.Metric, SampleHistogramPair{ + Timestamp: s.Timestamp, + Histogram: s.Histogram, + }) + } return fmt.Sprintf("%s => %s", s.Metric, SamplePair{ Timestamp: s.Timestamp, Value: s.Value, @@ -142,6 +74,19 @@ func (s Sample) String() string { // MarshalJSON implements json.Marshaler. func (s Sample) MarshalJSON() ([]byte, error) { + if s.Histogram != nil { + v := struct { + Metric Metric `json:"metric"` + Histogram SampleHistogramPair `json:"histogram"` + }{ + Metric: s.Metric, + Histogram: SampleHistogramPair{ + Timestamp: s.Timestamp, + Histogram: s.Histogram, + }, + } + return json.Marshal(&v) + } v := struct { Metric Metric `json:"metric"` Value SamplePair `json:"value"` @@ -152,21 +97,25 @@ func (s Sample) MarshalJSON() ([]byte, error) { Value: s.Value, }, } - return json.Marshal(&v) } // UnmarshalJSON implements json.Unmarshaler. func (s *Sample) UnmarshalJSON(b []byte) error { v := struct { - Metric Metric `json:"metric"` - Value SamplePair `json:"value"` + Metric Metric `json:"metric"` + Value SamplePair `json:"value"` + Histogram SampleHistogramPair `json:"histogram"` }{ Metric: s.Metric, Value: SamplePair{ Timestamp: s.Timestamp, Value: s.Value, }, + Histogram: SampleHistogramPair{ + Timestamp: s.Timestamp, + Histogram: s.Histogram, + }, } if err := json.Unmarshal(b, &v); err != nil { @@ -174,8 +123,13 @@ func (s *Sample) UnmarshalJSON(b []byte) error { } s.Metric = v.Metric - s.Timestamp = v.Value.Timestamp - s.Value = v.Value.Value + if v.Histogram.Histogram != nil { + s.Timestamp = v.Histogram.Timestamp + s.Histogram = v.Histogram.Histogram + } else { + s.Timestamp = v.Value.Timestamp + s.Value = v.Value.Value + } return nil } @@ -221,80 +175,76 @@ func (s Samples) Equal(o Samples) bool { // SampleStream is a stream of Values belonging to an attached COWMetric. type SampleStream struct { - Metric Metric `json:"metric"` - Values []SamplePair `json:"values"` + Metric Metric `json:"metric"` + Values []SamplePair `json:"values"` + Histograms []SampleHistogramPair `json:"histograms"` } func (ss SampleStream) String() string { - vals := make([]string, len(ss.Values)) + valuesLength := len(ss.Values) + vals := make([]string, valuesLength+len(ss.Histograms)) for i, v := range ss.Values { vals[i] = v.String() } + for i, v := range ss.Histograms { + vals[i+valuesLength] = v.String() + } return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n")) } -// Value is a generic interface for values resulting from a query evaluation. -type Value interface { - Type() ValueType - String() string +func (ss SampleStream) MarshalJSON() ([]byte, error) { + if len(ss.Histograms) > 0 && len(ss.Values) > 0 { + v := struct { + Metric Metric `json:"metric"` + Values []SamplePair `json:"values"` + Histograms []SampleHistogramPair `json:"histograms"` + }{ + Metric: ss.Metric, + Values: ss.Values, + Histograms: ss.Histograms, + } + return json.Marshal(&v) + } else if len(ss.Histograms) > 0 { + v := struct { + Metric Metric `json:"metric"` + Histograms []SampleHistogramPair `json:"histograms"` + }{ + Metric: ss.Metric, + Histograms: ss.Histograms, + } + return json.Marshal(&v) + } else { + v := struct { + Metric Metric `json:"metric"` + Values []SamplePair `json:"values"` + }{ + Metric: ss.Metric, + Values: ss.Values, + } + return json.Marshal(&v) + } } -func (Matrix) Type() ValueType { return ValMatrix } -func (Vector) Type() ValueType { return ValVector } -func (*Scalar) Type() ValueType { return ValScalar } -func (*String) Type() ValueType { return ValString } - -type ValueType int - -const ( - ValNone ValueType = iota - ValScalar - ValVector - ValMatrix - ValString -) - -// MarshalJSON implements json.Marshaler. -func (et ValueType) MarshalJSON() ([]byte, error) { - return json.Marshal(et.String()) -} +func (ss *SampleStream) UnmarshalJSON(b []byte) error { + v := struct { + Metric Metric `json:"metric"` + Values []SamplePair `json:"values"` + Histograms []SampleHistogramPair `json:"histograms"` + }{ + Metric: ss.Metric, + Values: ss.Values, + Histograms: ss.Histograms, + } -func (et *ValueType) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { + if err := json.Unmarshal(b, &v); err != nil { return err } - switch s { - case "": - *et = ValNone - case "scalar": - *et = ValScalar - case "vector": - *et = ValVector - case "matrix": - *et = ValMatrix - case "string": - *et = ValString - default: - return fmt.Errorf("unknown value type %q", s) - } - return nil -} -func (e ValueType) String() string { - switch e { - case ValNone: - return "" - case ValScalar: - return "scalar" - case ValVector: - return "vector" - case ValMatrix: - return "matrix" - case ValString: - return "string" - } - panic("ValueType.String: unhandled value type") + ss.Metric = v.Metric + ss.Values = v.Values + ss.Histograms = v.Histograms + + return nil } // Scalar is a scalar value evaluated at the set timestamp. diff --git a/vendor/github.com/prometheus/common/model/value_float.go b/vendor/github.com/prometheus/common/model/value_float.go new file mode 100644 index 00000000000..0f615a70530 --- /dev/null +++ b/vendor/github.com/prometheus/common/model/value_float.go @@ -0,0 +1,100 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" + "math" + "strconv" +) + +var ( + // ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a + // non-existing sample pair. It is a SamplePair with timestamp Earliest and + // value 0.0. Note that the natural zero value of SamplePair has a timestamp + // of 0, which is possible to appear in a real SamplePair and thus not + // suitable to signal a non-existing SamplePair. + ZeroSamplePair = SamplePair{Timestamp: Earliest} +) + +// A SampleValue is a representation of a value for a given sample at a given +// time. +type SampleValue float64 + +// MarshalJSON implements json.Marshaler. +func (v SampleValue) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON implements json.Unmarshaler. +func (v *SampleValue) UnmarshalJSON(b []byte) error { + if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { + return fmt.Errorf("sample value must be a quoted string") + } + f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) + if err != nil { + return err + } + *v = SampleValue(f) + return nil +} + +// Equal returns true if the value of v and o is equal or if both are NaN. Note +// that v==o is false if both are NaN. If you want the conventional float +// behavior, use == to compare two SampleValues. +func (v SampleValue) Equal(o SampleValue) bool { + if v == o { + return true + } + return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) +} + +func (v SampleValue) String() string { + return strconv.FormatFloat(float64(v), 'f', -1, 64) +} + +// SamplePair pairs a SampleValue with a Timestamp. +type SamplePair struct { + Timestamp Time + Value SampleValue +} + +func (s SamplePair) MarshalJSON() ([]byte, error) { + t, err := json.Marshal(s.Timestamp) + if err != nil { + return nil, err + } + v, err := json.Marshal(s.Value) + if err != nil { + return nil, err + } + return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (s *SamplePair) UnmarshalJSON(b []byte) error { + v := [...]json.Unmarshaler{&s.Timestamp, &s.Value} + return json.Unmarshal(b, &v) +} + +// Equal returns true if this SamplePair and o have equal Values and equal +// Timestamps. The semantics of Value equality is defined by SampleValue.Equal. +func (s *SamplePair) Equal(o *SamplePair) bool { + return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) +} + +func (s SamplePair) String() string { + return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp) +} diff --git a/vendor/github.com/prometheus/common/model/value_histogram.go b/vendor/github.com/prometheus/common/model/value_histogram.go new file mode 100644 index 00000000000..54bb038cfff --- /dev/null +++ b/vendor/github.com/prometheus/common/model/value_histogram.go @@ -0,0 +1,178 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" +) + +type FloatString float64 + +func (v FloatString) String() string { + return strconv.FormatFloat(float64(v), 'f', -1, 64) +} + +func (v FloatString) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +func (v *FloatString) UnmarshalJSON(b []byte) error { + if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { + return fmt.Errorf("float value must be a quoted string") + } + f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) + if err != nil { + return err + } + *v = FloatString(f) + return nil +} + +type HistogramBucket struct { + Boundaries int32 + Lower FloatString + Upper FloatString + Count FloatString +} + +func (s HistogramBucket) MarshalJSON() ([]byte, error) { + b, err := json.Marshal(s.Boundaries) + if err != nil { + return nil, err + } + l, err := json.Marshal(s.Lower) + if err != nil { + return nil, err + } + u, err := json.Marshal(s.Upper) + if err != nil { + return nil, err + } + c, err := json.Marshal(s.Count) + if err != nil { + return nil, err + } + return []byte(fmt.Sprintf("[%s,%s,%s,%s]", b, l, u, c)), nil +} + +func (s *HistogramBucket) UnmarshalJSON(buf []byte) error { + tmp := []interface{}{&s.Boundaries, &s.Lower, &s.Upper, &s.Count} + wantLen := len(tmp) + if err := json.Unmarshal(buf, &tmp); err != nil { + return err + } + if gotLen := len(tmp); gotLen != wantLen { + return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen) + } + return nil +} + +func (s *HistogramBucket) Equal(o *HistogramBucket) bool { + return s == o || (s.Boundaries == o.Boundaries && s.Lower == o.Lower && s.Upper == o.Upper && s.Count == o.Count) +} + +func (b HistogramBucket) String() string { + var sb strings.Builder + lowerInclusive := b.Boundaries == 1 || b.Boundaries == 3 + upperInclusive := b.Boundaries == 0 || b.Boundaries == 3 + if lowerInclusive { + sb.WriteRune('[') + } else { + sb.WriteRune('(') + } + fmt.Fprintf(&sb, "%g,%g", b.Lower, b.Upper) + if upperInclusive { + sb.WriteRune(']') + } else { + sb.WriteRune(')') + } + fmt.Fprintf(&sb, ":%v", b.Count) + return sb.String() +} + +type HistogramBuckets []*HistogramBucket + +func (s HistogramBuckets) Equal(o HistogramBuckets) bool { + if len(s) != len(o) { + return false + } + + for i, bucket := range s { + if !bucket.Equal(o[i]) { + return false + } + } + return true +} + +type SampleHistogram struct { + Count FloatString `json:"count"` + Sum FloatString `json:"sum"` + Buckets HistogramBuckets `json:"buckets"` +} + +func (s SampleHistogram) String() string { + return fmt.Sprintf("Count: %f, Sum: %f, Buckets: %v", s.Count, s.Sum, s.Buckets) +} + +func (s *SampleHistogram) Equal(o *SampleHistogram) bool { + return s == o || (s.Count == o.Count && s.Sum == o.Sum && s.Buckets.Equal(o.Buckets)) +} + +type SampleHistogramPair struct { + Timestamp Time + // Histogram should never be nil, it's only stored as pointer for efficiency. + Histogram *SampleHistogram +} + +func (s SampleHistogramPair) MarshalJSON() ([]byte, error) { + if s.Histogram == nil { + return nil, fmt.Errorf("histogram is nil") + } + t, err := json.Marshal(s.Timestamp) + if err != nil { + return nil, err + } + v, err := json.Marshal(s.Histogram) + if err != nil { + return nil, err + } + return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil +} + +func (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error { + tmp := []interface{}{&s.Timestamp, &s.Histogram} + wantLen := len(tmp) + if err := json.Unmarshal(buf, &tmp); err != nil { + return err + } + if gotLen := len(tmp); gotLen != wantLen { + return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen) + } + if s.Histogram == nil { + return fmt.Errorf("histogram is null") + } + return nil +} + +func (s SampleHistogramPair) String() string { + return fmt.Sprintf("%s @[%s]", s.Histogram, s.Timestamp) +} + +func (s *SampleHistogramPair) Equal(o *SampleHistogramPair) bool { + return s == o || (s.Histogram.Equal(o.Histogram) && s.Timestamp.Equal(o.Timestamp)) +} diff --git a/vendor/github.com/prometheus/common/model/value_type.go b/vendor/github.com/prometheus/common/model/value_type.go new file mode 100644 index 00000000000..726c50ee638 --- /dev/null +++ b/vendor/github.com/prometheus/common/model/value_type.go @@ -0,0 +1,83 @@ +// Copyright 2013 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "encoding/json" + "fmt" +) + +// Value is a generic interface for values resulting from a query evaluation. +type Value interface { + Type() ValueType + String() string +} + +func (Matrix) Type() ValueType { return ValMatrix } +func (Vector) Type() ValueType { return ValVector } +func (*Scalar) Type() ValueType { return ValScalar } +func (*String) Type() ValueType { return ValString } + +type ValueType int + +const ( + ValNone ValueType = iota + ValScalar + ValVector + ValMatrix + ValString +) + +// MarshalJSON implements json.Marshaler. +func (et ValueType) MarshalJSON() ([]byte, error) { + return json.Marshal(et.String()) +} + +func (et *ValueType) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + switch s { + case "": + *et = ValNone + case "scalar": + *et = ValScalar + case "vector": + *et = ValVector + case "matrix": + *et = ValMatrix + case "string": + *et = ValString + default: + return fmt.Errorf("unknown value type %q", s) + } + return nil +} + +func (e ValueType) String() string { + switch e { + case ValNone: + return "" + case ValScalar: + return "scalar" + case ValVector: + return "vector" + case ValMatrix: + return "matrix" + case ValString: + return "string" + } + panic("ValueType.String: unhandled value type") +} diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index 6c8e3e21979..b111d256200 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -55,19 +55,22 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.13.0 +PROMU_VERSION ?= 0.14.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz +SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.45.2 +GOLANGCI_LINT_VERSION ?= v1.51.2 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) # If we're in CI and there is an Actions file, that means the linter # is being run in Actions, so we don't need to run it here. - ifeq (,$(CIRCLE_JOB)) + ifneq (,$(SKIP_GOLANGCI_LINT)) + GOLANGCI_LINT := + else ifeq (,$(CIRCLE_JOB)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint @@ -88,6 +91,8 @@ BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) +SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG)) + ifeq ($(GOHOSTARCH),amd64) ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) # Only supported on amd64 @@ -202,7 +207,7 @@ common-tarball: promu .PHONY: common-docker $(BUILD_DOCKER_ARCHS) common-docker: $(BUILD_DOCKER_ARCHS) $(BUILD_DOCKER_ARCHS): common-docker-%: - docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \ + docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ -f $(DOCKERFILE_PATH) \ --build-arg ARCH="$*" \ --build-arg OS="linux" \ @@ -211,19 +216,19 @@ $(BUILD_DOCKER_ARCHS): common-docker-%: .PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) common-docker-publish: $(PUBLISH_DOCKER_ARCHS) $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" + docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) common-docker-tag-latest: $(TAG_DOCKER_ARCHS) $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" .PHONY: common-docker-manifest common-docker-manifest: - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG)) - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)) + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" .PHONY: promu promu: $(PROMU) diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go index ff6b927da15..06968ca2ed4 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo.go @@ -380,6 +380,42 @@ func parseCPUInfoMips(info []byte) ([]CPUInfo, error) { return cpuinfo, nil } +func parseCPUInfoLoong(info []byte) ([]CPUInfo, error) { + scanner := bufio.NewScanner(bytes.NewReader(info)) + // find the first "processor" line + firstLine := firstNonEmptyLine(scanner) + if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") { + return nil, errors.New("invalid cpuinfo file: " + firstLine) + } + field := strings.SplitN(firstLine, ": ", 2) + cpuinfo := []CPUInfo{} + systemType := field[1] + i := 0 + for scanner.Scan() { + line := scanner.Text() + if !strings.Contains(line, ":") { + continue + } + field := strings.SplitN(line, ": ", 2) + switch strings.TrimSpace(field[0]) { + case "processor": + v, err := strconv.ParseUint(field[1], 0, 32) + if err != nil { + return nil, err + } + i = int(v) + cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor + cpuinfo[i].Processor = uint(v) + cpuinfo[i].VendorID = systemType + case "CPU Family": + cpuinfo[i].CPUFamily = field[1] + case "Model Name": + cpuinfo[i].ModelName = field[1] + } + } + return cpuinfo, nil +} + func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) { scanner := bufio.NewScanner(bytes.NewReader(info)) diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go new file mode 100644 index 00000000000..d88442f0edf --- /dev/null +++ b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go @@ -0,0 +1,19 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux +// +build linux + +package procfs + +var parseCPUInfo = parseCPUInfoLoong diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go index ea41bf2ca1e..a6b2b3127cb 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_others.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x -// +build linux,!386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x +//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x +// +build linux,!386,!amd64,!arm,!arm64,!loong64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x package procfs diff --git a/vendor/github.com/prometheus/procfs/doc.go b/vendor/github.com/prometheus/procfs/doc.go index d31a82600f6..f9d961e4417 100644 --- a/vendor/github.com/prometheus/procfs/doc.go +++ b/vendor/github.com/prometheus/procfs/doc.go @@ -16,30 +16,29 @@ // // Example: // -// package main -// -// import ( -// "fmt" -// "log" -// -// "github.com/prometheus/procfs" -// ) -// -// func main() { -// p, err := procfs.Self() -// if err != nil { -// log.Fatalf("could not get process: %s", err) -// } -// -// stat, err := p.Stat() -// if err != nil { -// log.Fatalf("could not get process stat: %s", err) -// } -// -// fmt.Printf("command: %s\n", stat.Comm) -// fmt.Printf("cpu time: %fs\n", stat.CPUTime()) -// fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) -// fmt.Printf("rss: %dB\n", stat.ResidentMemory()) -// } -// +// package main +// +// import ( +// "fmt" +// "log" +// +// "github.com/prometheus/procfs" +// ) +// +// func main() { +// p, err := procfs.Self() +// if err != nil { +// log.Fatalf("could not get process: %s", err) +// } +// +// stat, err := p.Stat() +// if err != nil { +// log.Fatalf("could not get process stat: %s", err) +// } +// +// fmt.Printf("command: %s\n", stat.Comm) +// fmt.Printf("cpu time: %fs\n", stat.CPUTime()) +// fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) +// fmt.Printf("rss: %dB\n", stat.ResidentMemory()) +// } package procfs diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go index 0102ab0fd85..60c551e026b 100644 --- a/vendor/github.com/prometheus/procfs/fs.go +++ b/vendor/github.com/prometheus/procfs/fs.go @@ -21,6 +21,7 @@ import ( // kernel data structures. type FS struct { proc fs.FS + real bool } // DefaultMountPoint is the common mount point of the proc filesystem. @@ -39,5 +40,11 @@ func NewFS(mountPoint string) (FS, error) { if err != nil { return FS{}, err } - return FS{fs}, nil + + real, err := isRealProc(mountPoint) + if err != nil { + return FS{}, err + } + + return FS{fs, real}, nil } diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go new file mode 100644 index 00000000000..80057696896 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go @@ -0,0 +1,23 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build netbsd || openbsd || solaris || windows +// +build netbsd openbsd solaris windows + +package procfs + +// isRealProc returns true on architectures that don't have a Type argument +// in their Statfs_t struct +func isRealProc(mountPoint string) (bool, error) { + return true, nil +} diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_type.go b/vendor/github.com/prometheus/procfs/fs_statfs_type.go new file mode 100644 index 00000000000..6233217ad29 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/fs_statfs_type.go @@ -0,0 +1,33 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !netbsd && !openbsd && !solaris && !windows +// +build !netbsd,!openbsd,!solaris,!windows + +package procfs + +import ( + "syscall" +) + +// isRealProc determines whether supplied mountpoint is really a proc filesystem. +func isRealProc(mountPoint string) (bool, error) { + stat := syscall.Statfs_t{} + err := syscall.Statfs(mountPoint, &stat) + if err != nil { + return false, err + } + + // 0x9fa0 is PROC_SUPER_MAGIC: https://elixir.bootlin.com/linux/v6.1/source/include/uapi/linux/magic.h#L87 + return stat.Type == 0x9fa0, nil +} diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go index b030951faf9..14272dc7885 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/parse.go +++ b/vendor/github.com/prometheus/procfs/internal/util/parse.go @@ -64,6 +64,21 @@ func ParsePInt64s(ss []string) ([]*int64, error) { return us, nil } +// Parses a uint64 from given hex in string. +func ParseHexUint64s(ss []string) ([]*uint64, error) { + us := make([]*uint64, 0, len(ss)) + for _, s := range ss { + u, err := strconv.ParseUint(s, 16, 64) + if err != nil { + return nil, err + } + + us = append(us, &u) + } + + return us, nil +} + // ReadUintFromFile reads a file and attempts to parse a uint64 from it. func ReadUintFromFile(path string) (uint64, error) { data, err := os.ReadFile(path) diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go index f7a828bb1da..7f68890cff1 100644 --- a/vendor/github.com/prometheus/procfs/mountstats.go +++ b/vendor/github.com/prometheus/procfs/mountstats.go @@ -186,6 +186,8 @@ type NFSOperationStats struct { CumulativeTotalResponseMilliseconds uint64 // Duration from when a request was enqueued to when it was completely handled. CumulativeTotalRequestMilliseconds uint64 + // The average time from the point the client sends RPC requests until it receives the response. + AverageRTTMilliseconds float64 // The count of operations that complete with tk_status < 0. These statuses usually indicate error conditions. Errors uint64 } @@ -284,7 +286,8 @@ func parseMountStats(r io.Reader) ([]*Mount, error) { } // parseMount parses an entry in /proc/[pid]/mountstats in the format: -// device [device] mounted on [mount] with fstype [type] +// +// device [device] mounted on [mount] with fstype [type] func parseMount(ss []string) (*Mount, error) { if len(ss) < deviceEntryLen { return nil, fmt.Errorf("invalid device entry: %v", ss) @@ -533,7 +536,6 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) { ns = append(ns, n) } - opStats := NFSOperationStats{ Operation: strings.TrimSuffix(ss[0], ":"), Requests: ns[0], @@ -545,6 +547,9 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) { CumulativeTotalResponseMilliseconds: ns[6], CumulativeTotalRequestMilliseconds: ns[7], } + if ns[0] != 0 { + opStats.AverageRTTMilliseconds = float64(ns[6]) / float64(ns[0]) + } if len(ns) > 8 { opStats.Errors = ns[8] diff --git a/vendor/github.com/prometheus/procfs/net_conntrackstat.go b/vendor/github.com/prometheus/procfs/net_conntrackstat.go index 8300daca054..64a0e946068 100644 --- a/vendor/github.com/prometheus/procfs/net_conntrackstat.go +++ b/vendor/github.com/prometheus/procfs/net_conntrackstat.go @@ -18,7 +18,6 @@ import ( "bytes" "fmt" "io" - "strconv" "strings" "github.com/prometheus/procfs/internal/util" @@ -28,9 +27,13 @@ import ( // and contains netfilter conntrack statistics at one CPU core. type ConntrackStatEntry struct { Entries uint64 + Searched uint64 Found uint64 + New uint64 Invalid uint64 Ignore uint64 + Delete uint64 + DeleteList uint64 Insert uint64 InsertFailed uint64 Drop uint64 @@ -81,73 +84,34 @@ func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { // Parses a ConntrackStatEntry from given array of fields. func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { - if len(fields) != 17 { - return nil, fmt.Errorf("invalid conntrackstat entry, missing fields") - } - entry := &ConntrackStatEntry{} - - entries, err := parseConntrackStatField(fields[0]) - if err != nil { - return nil, err - } - entry.Entries = entries - - found, err := parseConntrackStatField(fields[2]) - if err != nil { - return nil, err - } - entry.Found = found - - invalid, err := parseConntrackStatField(fields[4]) - if err != nil { - return nil, err - } - entry.Invalid = invalid - - ignore, err := parseConntrackStatField(fields[5]) - if err != nil { - return nil, err - } - entry.Ignore = ignore - - insert, err := parseConntrackStatField(fields[8]) + entries, err := util.ParseHexUint64s(fields) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid conntrackstat entry, couldn't parse fields: %s", err) } - entry.Insert = insert - - insertFailed, err := parseConntrackStatField(fields[9]) - if err != nil { - return nil, err + numEntries := len(entries) + if numEntries < 16 || numEntries > 17 { + return nil, fmt.Errorf("invalid conntrackstat entry, invalid number of fields: %d", numEntries) } - entry.InsertFailed = insertFailed - drop, err := parseConntrackStatField(fields[10]) - if err != nil { - return nil, err + stats := &ConntrackStatEntry{ + Entries: *entries[0], + Searched: *entries[1], + Found: *entries[2], + New: *entries[3], + Invalid: *entries[4], + Ignore: *entries[5], + Delete: *entries[6], + DeleteList: *entries[7], + Insert: *entries[8], + InsertFailed: *entries[9], + Drop: *entries[10], + EarlyDrop: *entries[11], } - entry.Drop = drop - earlyDrop, err := parseConntrackStatField(fields[11]) - if err != nil { - return nil, err + // Ignore missing search_restart on Linux < 2.6.35. + if numEntries == 17 { + stats.SearchRestart = *entries[16] } - entry.EarlyDrop = earlyDrop - searchRestart, err := parseConntrackStatField(fields[16]) - if err != nil { - return nil, err - } - entry.SearchRestart = searchRestart - - return entry, nil -} - -// Parses a uint64 from given hex in string. -func parseConntrackStatField(field string) (uint64, error) { - val, err := strconv.ParseUint(field, 16, 64) - if err != nil { - return 0, fmt.Errorf("couldn't parse %q field: %w", field, err) - } - return val, err + return stats, nil } diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go index a94f86dc4ae..540cea52c6f 100644 --- a/vendor/github.com/prometheus/procfs/net_softnet.go +++ b/vendor/github.com/prometheus/procfs/net_softnet.go @@ -27,8 +27,9 @@ import ( // For the proc file format details, // See: // * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343 -// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 -// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. +// * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 +// * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 +// * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 // SoftnetStat contains a single row of data from /proc/net/softnet_stat. type SoftnetStat struct { @@ -38,6 +39,18 @@ type SoftnetStat struct { Dropped uint32 // Number of times processing packets ran out of quota. TimeSqueezed uint32 + // Number of collision occur while obtaining device lock while transmitting. + CPUCollision uint32 + // Number of times cpu woken up received_rps. + ReceivedRps uint32 + // number of times flow limit has been reached. + FlowLimitCount uint32 + // Softnet backlog status. + SoftnetBacklogLen uint32 + // CPU id owning this softnet_data. + Index uint32 + // softnet_data's Width. + Width int } var softNetProcFile = "net/softnet_stat" @@ -63,25 +76,65 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) { s := bufio.NewScanner(r) var stats []SoftnetStat + cpuIndex := 0 for s.Scan() { columns := strings.Fields(s.Text()) width := len(columns) + softnetStat := SoftnetStat{} if width < minColumns { return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns) } - // We only parse the first three columns at the moment. - us, err := parseHexUint32s(columns[0:3]) - if err != nil { - return nil, err + // Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347 + if width >= minColumns { + us, err := parseHexUint32s(columns[0:9]) + if err != nil { + return nil, err + } + + softnetStat.Processed = us[0] + softnetStat.Dropped = us[1] + softnetStat.TimeSqueezed = us[2] + softnetStat.CPUCollision = us[8] + } + + // Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 + if width >= 10 { + us, err := parseHexUint32s(columns[9:10]) + if err != nil { + return nil, err + } + + softnetStat.ReceivedRps = us[0] } - stats = append(stats, SoftnetStat{ - Processed: us[0], - Dropped: us[1], - TimeSqueezed: us[2], - }) + // Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 + if width >= 11 { + us, err := parseHexUint32s(columns[10:11]) + if err != nil { + return nil, err + } + + softnetStat.FlowLimitCount = us[0] + } + + // Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 + if width >= 13 { + us, err := parseHexUint32s(columns[11:13]) + if err != nil { + return nil, err + } + + softnetStat.SoftnetBacklogLen = us[0] + softnetStat.Index = us[1] + } else { + // For older kernels, create the Index based on the scan line number. + softnetStat.Index = uint32(cpuIndex) + } + softnetStat.Width = width + stats = append(stats, softnetStat) + cpuIndex++ } return stats, nil diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go new file mode 100644 index 00000000000..c80fb154247 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/net_wireless.go @@ -0,0 +1,182 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// Wireless models the content of /proc/net/wireless. +type Wireless struct { + Name string + + // Status is the current 4-digit hex value status of the interface. + Status uint64 + + // QualityLink is the link quality. + QualityLink int + + // QualityLevel is the signal gain (dBm). + QualityLevel int + + // QualityNoise is the signal noise baseline (dBm). + QualityNoise int + + // DiscardedNwid is the number of discarded packets with wrong nwid/essid. + DiscardedNwid int + + // DiscardedCrypt is the number of discarded packets with wrong code/decode (WEP). + DiscardedCrypt int + + // DiscardedFrag is the number of discarded packets that can't perform MAC reassembly. + DiscardedFrag int + + // DiscardedRetry is the number of discarded packets that reached max MAC retries. + DiscardedRetry int + + // DiscardedMisc is the number of discarded packets for other reasons. + DiscardedMisc int + + // MissedBeacon is the number of missed beacons/superframe. + MissedBeacon int +} + +// Wireless returns kernel wireless statistics. +func (fs FS) Wireless() ([]*Wireless, error) { + b, err := util.ReadFileNoStat(fs.proc.Path("net/wireless")) + if err != nil { + return nil, err + } + + m, err := parseWireless(bytes.NewReader(b)) + if err != nil { + return nil, fmt.Errorf("failed to parse wireless: %w", err) + } + + return m, nil +} + +// parseWireless parses the contents of /proc/net/wireless. +/* +Inter-| sta-| Quality | Discarded packets | Missed | WE +face | tus | link level noise | nwid crypt frag retry misc | beacon | 22 + eth1: 0000 5. -256. -10. 0 1 0 3 0 0 + eth2: 0000 5. -256. -20. 0 2 0 4 0 0 +*/ +func parseWireless(r io.Reader) ([]*Wireless, error) { + var ( + interfaces []*Wireless + scanner = bufio.NewScanner(r) + ) + + for n := 0; scanner.Scan(); n++ { + // Skip the 2 header lines. + if n < 2 { + continue + } + + line := scanner.Text() + + parts := strings.Split(line, ":") + if len(parts) != 2 { + return nil, fmt.Errorf("expected 2 parts after splitting line by ':', got %d for line %q", len(parts), line) + } + + name := strings.TrimSpace(parts[0]) + stats := strings.Fields(parts[1]) + + if len(stats) < 10 { + return nil, fmt.Errorf("invalid number of fields in line %d, expected at least 10, got %d: %q", n, len(stats), line) + } + + status, err := strconv.ParseUint(stats[0], 16, 16) + if err != nil { + return nil, fmt.Errorf("invalid status in line %d: %q", n, line) + } + + qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], ".")) + if err != nil { + return nil, fmt.Errorf("failed to parse Quality:link as integer %q: %w", qlink, err) + } + + qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], ".")) + if err != nil { + return nil, fmt.Errorf("failed to parse Quality:level as integer %q: %w", qlevel, err) + } + + qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], ".")) + if err != nil { + return nil, fmt.Errorf("failed to parse Quality:noise as integer %q: %w", qnoise, err) + } + + dnwid, err := strconv.Atoi(stats[4]) + if err != nil { + return nil, fmt.Errorf("failed to parse Discarded:nwid as integer %q: %w", dnwid, err) + } + + dcrypt, err := strconv.Atoi(stats[5]) + if err != nil { + return nil, fmt.Errorf("failed to parse Discarded:crypt as integer %q: %w", dcrypt, err) + } + + dfrag, err := strconv.Atoi(stats[6]) + if err != nil { + return nil, fmt.Errorf("failed to parse Discarded:frag as integer %q: %w", dfrag, err) + } + + dretry, err := strconv.Atoi(stats[7]) + if err != nil { + return nil, fmt.Errorf("failed to parse Discarded:retry as integer %q: %w", dretry, err) + } + + dmisc, err := strconv.Atoi(stats[8]) + if err != nil { + return nil, fmt.Errorf("failed to parse Discarded:misc as integer %q: %w", dmisc, err) + } + + mbeacon, err := strconv.Atoi(stats[9]) + if err != nil { + return nil, fmt.Errorf("failed to parse Missed:beacon as integer %q: %w", mbeacon, err) + } + + w := &Wireless{ + Name: name, + Status: status, + QualityLink: qlink, + QualityLevel: qlevel, + QualityNoise: qnoise, + DiscardedNwid: dnwid, + DiscardedCrypt: dcrypt, + DiscardedFrag: dfrag, + DiscardedRetry: dretry, + DiscardedMisc: dmisc, + MissedBeacon: mbeacon, + } + + interfaces = append(interfaces, w) + } + + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("failed to scan /proc/net/wireless: %w", err) + } + + return interfaces, nil +} diff --git a/vendor/github.com/prometheus/procfs/netstat.go b/vendor/github.com/prometheus/procfs/netstat.go index dcea9c5a671..742dff453ba 100644 --- a/vendor/github.com/prometheus/procfs/netstat.go +++ b/vendor/github.com/prometheus/procfs/netstat.go @@ -37,32 +37,46 @@ func (fs FS) NetStat() ([]NetStat, error) { var netStatsTotal []NetStat for _, filePath := range statFiles { - file, err := os.Open(filePath) + procNetstat, err := parseNetstat(filePath) if err != nil { return nil, err } + procNetstat.Filename = filepath.Base(filePath) - netStatFile := NetStat{ - Filename: filepath.Base(filePath), - Stats: make(map[string][]uint64), - } - scanner := bufio.NewScanner(file) - scanner.Scan() - // First string is always a header for stats - var headers []string - headers = append(headers, strings.Fields(scanner.Text())...) + netStatsTotal = append(netStatsTotal, procNetstat) + } + return netStatsTotal, nil +} + +// parseNetstat parses the metrics from `/proc/net/stat/` file +// and returns a NetStat structure. +func parseNetstat(filePath string) (NetStat, error) { + netStat := NetStat{ + Stats: make(map[string][]uint64), + } + file, err := os.Open(filePath) + if err != nil { + return netStat, err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + scanner.Scan() - // Other strings represent per-CPU counters - for scanner.Scan() { - for num, counter := range strings.Fields(scanner.Text()) { - value, err := strconv.ParseUint(counter, 16, 64) - if err != nil { - return nil, err - } - netStatFile.Stats[headers[num]] = append(netStatFile.Stats[headers[num]], value) + // First string is always a header for stats + var headers []string + headers = append(headers, strings.Fields(scanner.Text())...) + + // Other strings represent per-CPU counters + for scanner.Scan() { + for num, counter := range strings.Fields(scanner.Text()) { + value, err := strconv.ParseUint(counter, 16, 64) + if err != nil { + return NetStat{}, err } + netStat.Stats[headers[num]] = append(netStat.Stats[headers[num]], value) } - netStatsTotal = append(netStatsTotal, netStatFile) } - return netStatsTotal, nil + + return netStat, nil } diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index c30223af72a..48f39dafd2a 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -21,7 +21,6 @@ import ( "strconv" "strings" - "github.com/prometheus/procfs/internal/fs" "github.com/prometheus/procfs/internal/util" ) @@ -30,7 +29,7 @@ type Proc struct { // The process ID. PID int - fs fs.FS + fs FS } // Procs represents a list of Proc structs. @@ -92,7 +91,7 @@ func (fs FS) Proc(pid int) (Proc, error) { if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil { return Proc{}, err } - return Proc{PID: pid, fs: fs.proc}, nil + return Proc{PID: pid, fs: fs}, nil } // AllProcs returns a list of all currently available processes. @@ -114,7 +113,7 @@ func (fs FS) AllProcs() (Procs, error) { if err != nil { continue } - p = append(p, Proc{PID: int(pid), fs: fs.proc}) + p = append(p, Proc{PID: int(pid), fs: fs}) } return p, nil @@ -237,6 +236,19 @@ func (p Proc) FileDescriptorTargets() ([]string, error) { // FileDescriptorsLen returns the number of currently open file descriptors of // a process. func (p Proc) FileDescriptorsLen() (int, error) { + // Use fast path if available (Linux v6.2): https://github.com/torvalds/linux/commit/f1f1f2569901 + if p.fs.real { + stat, err := os.Stat(p.path("fd")) + if err != nil { + return 0, err + } + + size := stat.Size() + if size > 0 { + return int(size), nil + } + } + fds, err := p.fileDescriptors() if err != nil { return 0, err @@ -285,7 +297,7 @@ func (p Proc) fileDescriptors() ([]string, error) { } func (p Proc) path(pa ...string) string { - return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) + return p.fs.proc.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) } // FileDescriptorsInfo retrieves information about all file descriptors of diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index cca03327c3f..ea83a75ffc4 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -23,7 +23,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the the placement of a PID inside a +// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the placement of a PID inside a // specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource // controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies // contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in diff --git a/vendor/github.com/prometheus/procfs/proc_interrupts.go b/vendor/github.com/prometheus/procfs/proc_interrupts.go new file mode 100644 index 00000000000..9df79c23799 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_interrupts.go @@ -0,0 +1,98 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// Interrupt represents a single interrupt line. +type Interrupt struct { + // Info is the type of interrupt. + Info string + // Devices is the name of the device that is located at that IRQ + Devices string + // Values is the number of interrupts per CPU. + Values []string +} + +// Interrupts models the content of /proc/interrupts. Key is the IRQ number. +// - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-interrupts +// - https://raspberrypi.stackexchange.com/questions/105802/explanation-of-proc-interrupts-output +type Interrupts map[string]Interrupt + +// Interrupts creates a new instance from a given Proc instance. +func (p Proc) Interrupts() (Interrupts, error) { + data, err := util.ReadFileNoStat(p.path("interrupts")) + if err != nil { + return nil, err + } + return parseInterrupts(bytes.NewReader(data)) +} + +func parseInterrupts(r io.Reader) (Interrupts, error) { + var ( + interrupts = Interrupts{} + scanner = bufio.NewScanner(r) + ) + + if !scanner.Scan() { + return nil, errors.New("interrupts empty") + } + cpuNum := len(strings.Fields(scanner.Text())) // one header per cpu + + for scanner.Scan() { + parts := strings.Fields(scanner.Text()) + if len(parts) == 0 { // skip empty lines + continue + } + if len(parts) < 2 { + return nil, fmt.Errorf("not enough fields in interrupts (expected at least 2 fields but got %d): %s", len(parts), parts) + } + intName := parts[0][:len(parts[0])-1] // remove trailing : + + if len(parts) == 2 { + interrupts[intName] = Interrupt{ + Info: "", + Devices: "", + Values: []string{ + parts[1], + }, + } + continue + } + + intr := Interrupt{ + Values: parts[1 : cpuNum+1], + } + + if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt + intr.Info = parts[cpuNum+1] + intr.Devices = strings.Join(parts[cpuNum+2:], " ") + } else { + intr.Info = strings.Join(parts[cpuNum+1:], " ") + } + interrupts[intName] = intr + } + + return interrupts, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_netstat.go b/vendor/github.com/prometheus/procfs/proc_netstat.go index 48b5238194e..6a43bb24595 100644 --- a/vendor/github.com/prometheus/procfs/proc_netstat.go +++ b/vendor/github.com/prometheus/procfs/proc_netstat.go @@ -33,139 +33,140 @@ type ProcNetstat struct { } type TcpExt struct { // nolint:revive - SyncookiesSent float64 - SyncookiesRecv float64 - SyncookiesFailed float64 - EmbryonicRsts float64 - PruneCalled float64 - RcvPruned float64 - OfoPruned float64 - OutOfWindowIcmps float64 - LockDroppedIcmps float64 - ArpFilter float64 - TW float64 - TWRecycled float64 - TWKilled float64 - PAWSActive float64 - PAWSEstab float64 - DelayedACKs float64 - DelayedACKLocked float64 - DelayedACKLost float64 - ListenOverflows float64 - ListenDrops float64 - TCPHPHits float64 - TCPPureAcks float64 - TCPHPAcks float64 - TCPRenoRecovery float64 - TCPSackRecovery float64 - TCPSACKReneging float64 - TCPSACKReorder float64 - TCPRenoReorder float64 - TCPTSReorder float64 - TCPFullUndo float64 - TCPPartialUndo float64 - TCPDSACKUndo float64 - TCPLossUndo float64 - TCPLostRetransmit float64 - TCPRenoFailures float64 - TCPSackFailures float64 - TCPLossFailures float64 - TCPFastRetrans float64 - TCPSlowStartRetrans float64 - TCPTimeouts float64 - TCPLossProbes float64 - TCPLossProbeRecovery float64 - TCPRenoRecoveryFail float64 - TCPSackRecoveryFail float64 - TCPRcvCollapsed float64 - TCPDSACKOldSent float64 - TCPDSACKOfoSent float64 - TCPDSACKRecv float64 - TCPDSACKOfoRecv float64 - TCPAbortOnData float64 - TCPAbortOnClose float64 - TCPAbortOnMemory float64 - TCPAbortOnTimeout float64 - TCPAbortOnLinger float64 - TCPAbortFailed float64 - TCPMemoryPressures float64 - TCPMemoryPressuresChrono float64 - TCPSACKDiscard float64 - TCPDSACKIgnoredOld float64 - TCPDSACKIgnoredNoUndo float64 - TCPSpuriousRTOs float64 - TCPMD5NotFound float64 - TCPMD5Unexpected float64 - TCPMD5Failure float64 - TCPSackShifted float64 - TCPSackMerged float64 - TCPSackShiftFallback float64 - TCPBacklogDrop float64 - PFMemallocDrop float64 - TCPMinTTLDrop float64 - TCPDeferAcceptDrop float64 - IPReversePathFilter float64 - TCPTimeWaitOverflow float64 - TCPReqQFullDoCookies float64 - TCPReqQFullDrop float64 - TCPRetransFail float64 - TCPRcvCoalesce float64 - TCPOFOQueue float64 - TCPOFODrop float64 - TCPOFOMerge float64 - TCPChallengeACK float64 - TCPSYNChallenge float64 - TCPFastOpenActive float64 - TCPFastOpenActiveFail float64 - TCPFastOpenPassive float64 - TCPFastOpenPassiveFail float64 - TCPFastOpenListenOverflow float64 - TCPFastOpenCookieReqd float64 - TCPFastOpenBlackhole float64 - TCPSpuriousRtxHostQueues float64 - BusyPollRxPackets float64 - TCPAutoCorking float64 - TCPFromZeroWindowAdv float64 - TCPToZeroWindowAdv float64 - TCPWantZeroWindowAdv float64 - TCPSynRetrans float64 - TCPOrigDataSent float64 - TCPHystartTrainDetect float64 - TCPHystartTrainCwnd float64 - TCPHystartDelayDetect float64 - TCPHystartDelayCwnd float64 - TCPACKSkippedSynRecv float64 - TCPACKSkippedPAWS float64 - TCPACKSkippedSeq float64 - TCPACKSkippedFinWait2 float64 - TCPACKSkippedTimeWait float64 - TCPACKSkippedChallenge float64 - TCPWinProbe float64 - TCPKeepAlive float64 - TCPMTUPFail float64 - TCPMTUPSuccess float64 - TCPWqueueTooBig float64 + SyncookiesSent *float64 + SyncookiesRecv *float64 + SyncookiesFailed *float64 + EmbryonicRsts *float64 + PruneCalled *float64 + RcvPruned *float64 + OfoPruned *float64 + OutOfWindowIcmps *float64 + LockDroppedIcmps *float64 + ArpFilter *float64 + TW *float64 + TWRecycled *float64 + TWKilled *float64 + PAWSActive *float64 + PAWSEstab *float64 + DelayedACKs *float64 + DelayedACKLocked *float64 + DelayedACKLost *float64 + ListenOverflows *float64 + ListenDrops *float64 + TCPHPHits *float64 + TCPPureAcks *float64 + TCPHPAcks *float64 + TCPRenoRecovery *float64 + TCPSackRecovery *float64 + TCPSACKReneging *float64 + TCPSACKReorder *float64 + TCPRenoReorder *float64 + TCPTSReorder *float64 + TCPFullUndo *float64 + TCPPartialUndo *float64 + TCPDSACKUndo *float64 + TCPLossUndo *float64 + TCPLostRetransmit *float64 + TCPRenoFailures *float64 + TCPSackFailures *float64 + TCPLossFailures *float64 + TCPFastRetrans *float64 + TCPSlowStartRetrans *float64 + TCPTimeouts *float64 + TCPLossProbes *float64 + TCPLossProbeRecovery *float64 + TCPRenoRecoveryFail *float64 + TCPSackRecoveryFail *float64 + TCPRcvCollapsed *float64 + TCPDSACKOldSent *float64 + TCPDSACKOfoSent *float64 + TCPDSACKRecv *float64 + TCPDSACKOfoRecv *float64 + TCPAbortOnData *float64 + TCPAbortOnClose *float64 + TCPAbortOnMemory *float64 + TCPAbortOnTimeout *float64 + TCPAbortOnLinger *float64 + TCPAbortFailed *float64 + TCPMemoryPressures *float64 + TCPMemoryPressuresChrono *float64 + TCPSACKDiscard *float64 + TCPDSACKIgnoredOld *float64 + TCPDSACKIgnoredNoUndo *float64 + TCPSpuriousRTOs *float64 + TCPMD5NotFound *float64 + TCPMD5Unexpected *float64 + TCPMD5Failure *float64 + TCPSackShifted *float64 + TCPSackMerged *float64 + TCPSackShiftFallback *float64 + TCPBacklogDrop *float64 + PFMemallocDrop *float64 + TCPMinTTLDrop *float64 + TCPDeferAcceptDrop *float64 + IPReversePathFilter *float64 + TCPTimeWaitOverflow *float64 + TCPReqQFullDoCookies *float64 + TCPReqQFullDrop *float64 + TCPRetransFail *float64 + TCPRcvCoalesce *float64 + TCPRcvQDrop *float64 + TCPOFOQueue *float64 + TCPOFODrop *float64 + TCPOFOMerge *float64 + TCPChallengeACK *float64 + TCPSYNChallenge *float64 + TCPFastOpenActive *float64 + TCPFastOpenActiveFail *float64 + TCPFastOpenPassive *float64 + TCPFastOpenPassiveFail *float64 + TCPFastOpenListenOverflow *float64 + TCPFastOpenCookieReqd *float64 + TCPFastOpenBlackhole *float64 + TCPSpuriousRtxHostQueues *float64 + BusyPollRxPackets *float64 + TCPAutoCorking *float64 + TCPFromZeroWindowAdv *float64 + TCPToZeroWindowAdv *float64 + TCPWantZeroWindowAdv *float64 + TCPSynRetrans *float64 + TCPOrigDataSent *float64 + TCPHystartTrainDetect *float64 + TCPHystartTrainCwnd *float64 + TCPHystartDelayDetect *float64 + TCPHystartDelayCwnd *float64 + TCPACKSkippedSynRecv *float64 + TCPACKSkippedPAWS *float64 + TCPACKSkippedSeq *float64 + TCPACKSkippedFinWait2 *float64 + TCPACKSkippedTimeWait *float64 + TCPACKSkippedChallenge *float64 + TCPWinProbe *float64 + TCPKeepAlive *float64 + TCPMTUPFail *float64 + TCPMTUPSuccess *float64 + TCPWqueueTooBig *float64 } type IpExt struct { // nolint:revive - InNoRoutes float64 - InTruncatedPkts float64 - InMcastPkts float64 - OutMcastPkts float64 - InBcastPkts float64 - OutBcastPkts float64 - InOctets float64 - OutOctets float64 - InMcastOctets float64 - OutMcastOctets float64 - InBcastOctets float64 - OutBcastOctets float64 - InCsumErrors float64 - InNoECTPkts float64 - InECT1Pkts float64 - InECT0Pkts float64 - InCEPkts float64 - ReasmOverlaps float64 + InNoRoutes *float64 + InTruncatedPkts *float64 + InMcastPkts *float64 + OutMcastPkts *float64 + InBcastPkts *float64 + OutBcastPkts *float64 + InOctets *float64 + OutOctets *float64 + InMcastOctets *float64 + OutMcastOctets *float64 + InBcastOctets *float64 + OutBcastOctets *float64 + InCsumErrors *float64 + InNoECTPkts *float64 + InECT1Pkts *float64 + InECT0Pkts *float64 + InCEPkts *float64 + ReasmOverlaps *float64 } func (p Proc) Netstat() (ProcNetstat, error) { @@ -174,14 +175,14 @@ func (p Proc) Netstat() (ProcNetstat, error) { if err != nil { return ProcNetstat{PID: p.PID}, err } - procNetstat, err := parseNetstat(bytes.NewReader(data), filename) + procNetstat, err := parseProcNetstat(bytes.NewReader(data), filename) procNetstat.PID = p.PID return procNetstat, err } -// parseNetstat parses the metrics from proc//net/netstat file +// parseProcNetstat parses the metrics from proc//net/netstat file // and returns a ProcNetstat structure. -func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) { +func parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) { var ( scanner = bufio.NewScanner(r) procNetstat = ProcNetstat{} @@ -208,230 +209,232 @@ func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) { case "TcpExt": switch key { case "SyncookiesSent": - procNetstat.TcpExt.SyncookiesSent = value + procNetstat.TcpExt.SyncookiesSent = &value case "SyncookiesRecv": - procNetstat.TcpExt.SyncookiesRecv = value + procNetstat.TcpExt.SyncookiesRecv = &value case "SyncookiesFailed": - procNetstat.TcpExt.SyncookiesFailed = value + procNetstat.TcpExt.SyncookiesFailed = &value case "EmbryonicRsts": - procNetstat.TcpExt.EmbryonicRsts = value + procNetstat.TcpExt.EmbryonicRsts = &value case "PruneCalled": - procNetstat.TcpExt.PruneCalled = value + procNetstat.TcpExt.PruneCalled = &value case "RcvPruned": - procNetstat.TcpExt.RcvPruned = value + procNetstat.TcpExt.RcvPruned = &value case "OfoPruned": - procNetstat.TcpExt.OfoPruned = value + procNetstat.TcpExt.OfoPruned = &value case "OutOfWindowIcmps": - procNetstat.TcpExt.OutOfWindowIcmps = value + procNetstat.TcpExt.OutOfWindowIcmps = &value case "LockDroppedIcmps": - procNetstat.TcpExt.LockDroppedIcmps = value + procNetstat.TcpExt.LockDroppedIcmps = &value case "ArpFilter": - procNetstat.TcpExt.ArpFilter = value + procNetstat.TcpExt.ArpFilter = &value case "TW": - procNetstat.TcpExt.TW = value + procNetstat.TcpExt.TW = &value case "TWRecycled": - procNetstat.TcpExt.TWRecycled = value + procNetstat.TcpExt.TWRecycled = &value case "TWKilled": - procNetstat.TcpExt.TWKilled = value + procNetstat.TcpExt.TWKilled = &value case "PAWSActive": - procNetstat.TcpExt.PAWSActive = value + procNetstat.TcpExt.PAWSActive = &value case "PAWSEstab": - procNetstat.TcpExt.PAWSEstab = value + procNetstat.TcpExt.PAWSEstab = &value case "DelayedACKs": - procNetstat.TcpExt.DelayedACKs = value + procNetstat.TcpExt.DelayedACKs = &value case "DelayedACKLocked": - procNetstat.TcpExt.DelayedACKLocked = value + procNetstat.TcpExt.DelayedACKLocked = &value case "DelayedACKLost": - procNetstat.TcpExt.DelayedACKLost = value + procNetstat.TcpExt.DelayedACKLost = &value case "ListenOverflows": - procNetstat.TcpExt.ListenOverflows = value + procNetstat.TcpExt.ListenOverflows = &value case "ListenDrops": - procNetstat.TcpExt.ListenDrops = value + procNetstat.TcpExt.ListenDrops = &value case "TCPHPHits": - procNetstat.TcpExt.TCPHPHits = value + procNetstat.TcpExt.TCPHPHits = &value case "TCPPureAcks": - procNetstat.TcpExt.TCPPureAcks = value + procNetstat.TcpExt.TCPPureAcks = &value case "TCPHPAcks": - procNetstat.TcpExt.TCPHPAcks = value + procNetstat.TcpExt.TCPHPAcks = &value case "TCPRenoRecovery": - procNetstat.TcpExt.TCPRenoRecovery = value + procNetstat.TcpExt.TCPRenoRecovery = &value case "TCPSackRecovery": - procNetstat.TcpExt.TCPSackRecovery = value + procNetstat.TcpExt.TCPSackRecovery = &value case "TCPSACKReneging": - procNetstat.TcpExt.TCPSACKReneging = value + procNetstat.TcpExt.TCPSACKReneging = &value case "TCPSACKReorder": - procNetstat.TcpExt.TCPSACKReorder = value + procNetstat.TcpExt.TCPSACKReorder = &value case "TCPRenoReorder": - procNetstat.TcpExt.TCPRenoReorder = value + procNetstat.TcpExt.TCPRenoReorder = &value case "TCPTSReorder": - procNetstat.TcpExt.TCPTSReorder = value + procNetstat.TcpExt.TCPTSReorder = &value case "TCPFullUndo": - procNetstat.TcpExt.TCPFullUndo = value + procNetstat.TcpExt.TCPFullUndo = &value case "TCPPartialUndo": - procNetstat.TcpExt.TCPPartialUndo = value + procNetstat.TcpExt.TCPPartialUndo = &value case "TCPDSACKUndo": - procNetstat.TcpExt.TCPDSACKUndo = value + procNetstat.TcpExt.TCPDSACKUndo = &value case "TCPLossUndo": - procNetstat.TcpExt.TCPLossUndo = value + procNetstat.TcpExt.TCPLossUndo = &value case "TCPLostRetransmit": - procNetstat.TcpExt.TCPLostRetransmit = value + procNetstat.TcpExt.TCPLostRetransmit = &value case "TCPRenoFailures": - procNetstat.TcpExt.TCPRenoFailures = value + procNetstat.TcpExt.TCPRenoFailures = &value case "TCPSackFailures": - procNetstat.TcpExt.TCPSackFailures = value + procNetstat.TcpExt.TCPSackFailures = &value case "TCPLossFailures": - procNetstat.TcpExt.TCPLossFailures = value + procNetstat.TcpExt.TCPLossFailures = &value case "TCPFastRetrans": - procNetstat.TcpExt.TCPFastRetrans = value + procNetstat.TcpExt.TCPFastRetrans = &value case "TCPSlowStartRetrans": - procNetstat.TcpExt.TCPSlowStartRetrans = value + procNetstat.TcpExt.TCPSlowStartRetrans = &value case "TCPTimeouts": - procNetstat.TcpExt.TCPTimeouts = value + procNetstat.TcpExt.TCPTimeouts = &value case "TCPLossProbes": - procNetstat.TcpExt.TCPLossProbes = value + procNetstat.TcpExt.TCPLossProbes = &value case "TCPLossProbeRecovery": - procNetstat.TcpExt.TCPLossProbeRecovery = value + procNetstat.TcpExt.TCPLossProbeRecovery = &value case "TCPRenoRecoveryFail": - procNetstat.TcpExt.TCPRenoRecoveryFail = value + procNetstat.TcpExt.TCPRenoRecoveryFail = &value case "TCPSackRecoveryFail": - procNetstat.TcpExt.TCPSackRecoveryFail = value + procNetstat.TcpExt.TCPSackRecoveryFail = &value case "TCPRcvCollapsed": - procNetstat.TcpExt.TCPRcvCollapsed = value + procNetstat.TcpExt.TCPRcvCollapsed = &value case "TCPDSACKOldSent": - procNetstat.TcpExt.TCPDSACKOldSent = value + procNetstat.TcpExt.TCPDSACKOldSent = &value case "TCPDSACKOfoSent": - procNetstat.TcpExt.TCPDSACKOfoSent = value + procNetstat.TcpExt.TCPDSACKOfoSent = &value case "TCPDSACKRecv": - procNetstat.TcpExt.TCPDSACKRecv = value + procNetstat.TcpExt.TCPDSACKRecv = &value case "TCPDSACKOfoRecv": - procNetstat.TcpExt.TCPDSACKOfoRecv = value + procNetstat.TcpExt.TCPDSACKOfoRecv = &value case "TCPAbortOnData": - procNetstat.TcpExt.TCPAbortOnData = value + procNetstat.TcpExt.TCPAbortOnData = &value case "TCPAbortOnClose": - procNetstat.TcpExt.TCPAbortOnClose = value + procNetstat.TcpExt.TCPAbortOnClose = &value case "TCPDeferAcceptDrop": - procNetstat.TcpExt.TCPDeferAcceptDrop = value + procNetstat.TcpExt.TCPDeferAcceptDrop = &value case "IPReversePathFilter": - procNetstat.TcpExt.IPReversePathFilter = value + procNetstat.TcpExt.IPReversePathFilter = &value case "TCPTimeWaitOverflow": - procNetstat.TcpExt.TCPTimeWaitOverflow = value + procNetstat.TcpExt.TCPTimeWaitOverflow = &value case "TCPReqQFullDoCookies": - procNetstat.TcpExt.TCPReqQFullDoCookies = value + procNetstat.TcpExt.TCPReqQFullDoCookies = &value case "TCPReqQFullDrop": - procNetstat.TcpExt.TCPReqQFullDrop = value + procNetstat.TcpExt.TCPReqQFullDrop = &value case "TCPRetransFail": - procNetstat.TcpExt.TCPRetransFail = value + procNetstat.TcpExt.TCPRetransFail = &value case "TCPRcvCoalesce": - procNetstat.TcpExt.TCPRcvCoalesce = value + procNetstat.TcpExt.TCPRcvCoalesce = &value + case "TCPRcvQDrop": + procNetstat.TcpExt.TCPRcvQDrop = &value case "TCPOFOQueue": - procNetstat.TcpExt.TCPOFOQueue = value + procNetstat.TcpExt.TCPOFOQueue = &value case "TCPOFODrop": - procNetstat.TcpExt.TCPOFODrop = value + procNetstat.TcpExt.TCPOFODrop = &value case "TCPOFOMerge": - procNetstat.TcpExt.TCPOFOMerge = value + procNetstat.TcpExt.TCPOFOMerge = &value case "TCPChallengeACK": - procNetstat.TcpExt.TCPChallengeACK = value + procNetstat.TcpExt.TCPChallengeACK = &value case "TCPSYNChallenge": - procNetstat.TcpExt.TCPSYNChallenge = value + procNetstat.TcpExt.TCPSYNChallenge = &value case "TCPFastOpenActive": - procNetstat.TcpExt.TCPFastOpenActive = value + procNetstat.TcpExt.TCPFastOpenActive = &value case "TCPFastOpenActiveFail": - procNetstat.TcpExt.TCPFastOpenActiveFail = value + procNetstat.TcpExt.TCPFastOpenActiveFail = &value case "TCPFastOpenPassive": - procNetstat.TcpExt.TCPFastOpenPassive = value + procNetstat.TcpExt.TCPFastOpenPassive = &value case "TCPFastOpenPassiveFail": - procNetstat.TcpExt.TCPFastOpenPassiveFail = value + procNetstat.TcpExt.TCPFastOpenPassiveFail = &value case "TCPFastOpenListenOverflow": - procNetstat.TcpExt.TCPFastOpenListenOverflow = value + procNetstat.TcpExt.TCPFastOpenListenOverflow = &value case "TCPFastOpenCookieReqd": - procNetstat.TcpExt.TCPFastOpenCookieReqd = value + procNetstat.TcpExt.TCPFastOpenCookieReqd = &value case "TCPFastOpenBlackhole": - procNetstat.TcpExt.TCPFastOpenBlackhole = value + procNetstat.TcpExt.TCPFastOpenBlackhole = &value case "TCPSpuriousRtxHostQueues": - procNetstat.TcpExt.TCPSpuriousRtxHostQueues = value + procNetstat.TcpExt.TCPSpuriousRtxHostQueues = &value case "BusyPollRxPackets": - procNetstat.TcpExt.BusyPollRxPackets = value + procNetstat.TcpExt.BusyPollRxPackets = &value case "TCPAutoCorking": - procNetstat.TcpExt.TCPAutoCorking = value + procNetstat.TcpExt.TCPAutoCorking = &value case "TCPFromZeroWindowAdv": - procNetstat.TcpExt.TCPFromZeroWindowAdv = value + procNetstat.TcpExt.TCPFromZeroWindowAdv = &value case "TCPToZeroWindowAdv": - procNetstat.TcpExt.TCPToZeroWindowAdv = value + procNetstat.TcpExt.TCPToZeroWindowAdv = &value case "TCPWantZeroWindowAdv": - procNetstat.TcpExt.TCPWantZeroWindowAdv = value + procNetstat.TcpExt.TCPWantZeroWindowAdv = &value case "TCPSynRetrans": - procNetstat.TcpExt.TCPSynRetrans = value + procNetstat.TcpExt.TCPSynRetrans = &value case "TCPOrigDataSent": - procNetstat.TcpExt.TCPOrigDataSent = value + procNetstat.TcpExt.TCPOrigDataSent = &value case "TCPHystartTrainDetect": - procNetstat.TcpExt.TCPHystartTrainDetect = value + procNetstat.TcpExt.TCPHystartTrainDetect = &value case "TCPHystartTrainCwnd": - procNetstat.TcpExt.TCPHystartTrainCwnd = value + procNetstat.TcpExt.TCPHystartTrainCwnd = &value case "TCPHystartDelayDetect": - procNetstat.TcpExt.TCPHystartDelayDetect = value + procNetstat.TcpExt.TCPHystartDelayDetect = &value case "TCPHystartDelayCwnd": - procNetstat.TcpExt.TCPHystartDelayCwnd = value + procNetstat.TcpExt.TCPHystartDelayCwnd = &value case "TCPACKSkippedSynRecv": - procNetstat.TcpExt.TCPACKSkippedSynRecv = value + procNetstat.TcpExt.TCPACKSkippedSynRecv = &value case "TCPACKSkippedPAWS": - procNetstat.TcpExt.TCPACKSkippedPAWS = value + procNetstat.TcpExt.TCPACKSkippedPAWS = &value case "TCPACKSkippedSeq": - procNetstat.TcpExt.TCPACKSkippedSeq = value + procNetstat.TcpExt.TCPACKSkippedSeq = &value case "TCPACKSkippedFinWait2": - procNetstat.TcpExt.TCPACKSkippedFinWait2 = value + procNetstat.TcpExt.TCPACKSkippedFinWait2 = &value case "TCPACKSkippedTimeWait": - procNetstat.TcpExt.TCPACKSkippedTimeWait = value + procNetstat.TcpExt.TCPACKSkippedTimeWait = &value case "TCPACKSkippedChallenge": - procNetstat.TcpExt.TCPACKSkippedChallenge = value + procNetstat.TcpExt.TCPACKSkippedChallenge = &value case "TCPWinProbe": - procNetstat.TcpExt.TCPWinProbe = value + procNetstat.TcpExt.TCPWinProbe = &value case "TCPKeepAlive": - procNetstat.TcpExt.TCPKeepAlive = value + procNetstat.TcpExt.TCPKeepAlive = &value case "TCPMTUPFail": - procNetstat.TcpExt.TCPMTUPFail = value + procNetstat.TcpExt.TCPMTUPFail = &value case "TCPMTUPSuccess": - procNetstat.TcpExt.TCPMTUPSuccess = value + procNetstat.TcpExt.TCPMTUPSuccess = &value case "TCPWqueueTooBig": - procNetstat.TcpExt.TCPWqueueTooBig = value + procNetstat.TcpExt.TCPWqueueTooBig = &value } case "IpExt": switch key { case "InNoRoutes": - procNetstat.IpExt.InNoRoutes = value + procNetstat.IpExt.InNoRoutes = &value case "InTruncatedPkts": - procNetstat.IpExt.InTruncatedPkts = value + procNetstat.IpExt.InTruncatedPkts = &value case "InMcastPkts": - procNetstat.IpExt.InMcastPkts = value + procNetstat.IpExt.InMcastPkts = &value case "OutMcastPkts": - procNetstat.IpExt.OutMcastPkts = value + procNetstat.IpExt.OutMcastPkts = &value case "InBcastPkts": - procNetstat.IpExt.InBcastPkts = value + procNetstat.IpExt.InBcastPkts = &value case "OutBcastPkts": - procNetstat.IpExt.OutBcastPkts = value + procNetstat.IpExt.OutBcastPkts = &value case "InOctets": - procNetstat.IpExt.InOctets = value + procNetstat.IpExt.InOctets = &value case "OutOctets": - procNetstat.IpExt.OutOctets = value + procNetstat.IpExt.OutOctets = &value case "InMcastOctets": - procNetstat.IpExt.InMcastOctets = value + procNetstat.IpExt.InMcastOctets = &value case "OutMcastOctets": - procNetstat.IpExt.OutMcastOctets = value + procNetstat.IpExt.OutMcastOctets = &value case "InBcastOctets": - procNetstat.IpExt.InBcastOctets = value + procNetstat.IpExt.InBcastOctets = &value case "OutBcastOctets": - procNetstat.IpExt.OutBcastOctets = value + procNetstat.IpExt.OutBcastOctets = &value case "InCsumErrors": - procNetstat.IpExt.InCsumErrors = value + procNetstat.IpExt.InCsumErrors = &value case "InNoECTPkts": - procNetstat.IpExt.InNoECTPkts = value + procNetstat.IpExt.InNoECTPkts = &value case "InECT1Pkts": - procNetstat.IpExt.InECT1Pkts = value + procNetstat.IpExt.InECT1Pkts = &value case "InECT0Pkts": - procNetstat.IpExt.InECT0Pkts = value + procNetstat.IpExt.InECT0Pkts = &value case "InCEPkts": - procNetstat.IpExt.InCEPkts = value + procNetstat.IpExt.InCEPkts = &value case "ReasmOverlaps": - procNetstat.IpExt.ReasmOverlaps = value + procNetstat.IpExt.ReasmOverlaps = &value } } } diff --git a/vendor/github.com/prometheus/procfs/proc_snmp.go b/vendor/github.com/prometheus/procfs/proc_snmp.go index ae191896cbd..6c46b718849 100644 --- a/vendor/github.com/prometheus/procfs/proc_snmp.go +++ b/vendor/github.com/prometheus/procfs/proc_snmp.go @@ -37,100 +37,100 @@ type ProcSnmp struct { } type Ip struct { // nolint:revive - Forwarding float64 - DefaultTTL float64 - InReceives float64 - InHdrErrors float64 - InAddrErrors float64 - ForwDatagrams float64 - InUnknownProtos float64 - InDiscards float64 - InDelivers float64 - OutRequests float64 - OutDiscards float64 - OutNoRoutes float64 - ReasmTimeout float64 - ReasmReqds float64 - ReasmOKs float64 - ReasmFails float64 - FragOKs float64 - FragFails float64 - FragCreates float64 + Forwarding *float64 + DefaultTTL *float64 + InReceives *float64 + InHdrErrors *float64 + InAddrErrors *float64 + ForwDatagrams *float64 + InUnknownProtos *float64 + InDiscards *float64 + InDelivers *float64 + OutRequests *float64 + OutDiscards *float64 + OutNoRoutes *float64 + ReasmTimeout *float64 + ReasmReqds *float64 + ReasmOKs *float64 + ReasmFails *float64 + FragOKs *float64 + FragFails *float64 + FragCreates *float64 } -type Icmp struct { - InMsgs float64 - InErrors float64 - InCsumErrors float64 - InDestUnreachs float64 - InTimeExcds float64 - InParmProbs float64 - InSrcQuenchs float64 - InRedirects float64 - InEchos float64 - InEchoReps float64 - InTimestamps float64 - InTimestampReps float64 - InAddrMasks float64 - InAddrMaskReps float64 - OutMsgs float64 - OutErrors float64 - OutDestUnreachs float64 - OutTimeExcds float64 - OutParmProbs float64 - OutSrcQuenchs float64 - OutRedirects float64 - OutEchos float64 - OutEchoReps float64 - OutTimestamps float64 - OutTimestampReps float64 - OutAddrMasks float64 - OutAddrMaskReps float64 +type Icmp struct { // nolint:revive + InMsgs *float64 + InErrors *float64 + InCsumErrors *float64 + InDestUnreachs *float64 + InTimeExcds *float64 + InParmProbs *float64 + InSrcQuenchs *float64 + InRedirects *float64 + InEchos *float64 + InEchoReps *float64 + InTimestamps *float64 + InTimestampReps *float64 + InAddrMasks *float64 + InAddrMaskReps *float64 + OutMsgs *float64 + OutErrors *float64 + OutDestUnreachs *float64 + OutTimeExcds *float64 + OutParmProbs *float64 + OutSrcQuenchs *float64 + OutRedirects *float64 + OutEchos *float64 + OutEchoReps *float64 + OutTimestamps *float64 + OutTimestampReps *float64 + OutAddrMasks *float64 + OutAddrMaskReps *float64 } type IcmpMsg struct { - InType3 float64 - OutType3 float64 + InType3 *float64 + OutType3 *float64 } type Tcp struct { // nolint:revive - RtoAlgorithm float64 - RtoMin float64 - RtoMax float64 - MaxConn float64 - ActiveOpens float64 - PassiveOpens float64 - AttemptFails float64 - EstabResets float64 - CurrEstab float64 - InSegs float64 - OutSegs float64 - RetransSegs float64 - InErrs float64 - OutRsts float64 - InCsumErrors float64 + RtoAlgorithm *float64 + RtoMin *float64 + RtoMax *float64 + MaxConn *float64 + ActiveOpens *float64 + PassiveOpens *float64 + AttemptFails *float64 + EstabResets *float64 + CurrEstab *float64 + InSegs *float64 + OutSegs *float64 + RetransSegs *float64 + InErrs *float64 + OutRsts *float64 + InCsumErrors *float64 } type Udp struct { // nolint:revive - InDatagrams float64 - NoPorts float64 - InErrors float64 - OutDatagrams float64 - RcvbufErrors float64 - SndbufErrors float64 - InCsumErrors float64 - IgnoredMulti float64 + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 } type UdpLite struct { // nolint:revive - InDatagrams float64 - NoPorts float64 - InErrors float64 - OutDatagrams float64 - RcvbufErrors float64 - SndbufErrors float64 - InCsumErrors float64 - IgnoredMulti float64 + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 } func (p Proc) Snmp() (ProcSnmp, error) { @@ -173,178 +173,178 @@ func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) { case "Ip": switch key { case "Forwarding": - procSnmp.Ip.Forwarding = value + procSnmp.Ip.Forwarding = &value case "DefaultTTL": - procSnmp.Ip.DefaultTTL = value + procSnmp.Ip.DefaultTTL = &value case "InReceives": - procSnmp.Ip.InReceives = value + procSnmp.Ip.InReceives = &value case "InHdrErrors": - procSnmp.Ip.InHdrErrors = value + procSnmp.Ip.InHdrErrors = &value case "InAddrErrors": - procSnmp.Ip.InAddrErrors = value + procSnmp.Ip.InAddrErrors = &value case "ForwDatagrams": - procSnmp.Ip.ForwDatagrams = value + procSnmp.Ip.ForwDatagrams = &value case "InUnknownProtos": - procSnmp.Ip.InUnknownProtos = value + procSnmp.Ip.InUnknownProtos = &value case "InDiscards": - procSnmp.Ip.InDiscards = value + procSnmp.Ip.InDiscards = &value case "InDelivers": - procSnmp.Ip.InDelivers = value + procSnmp.Ip.InDelivers = &value case "OutRequests": - procSnmp.Ip.OutRequests = value + procSnmp.Ip.OutRequests = &value case "OutDiscards": - procSnmp.Ip.OutDiscards = value + procSnmp.Ip.OutDiscards = &value case "OutNoRoutes": - procSnmp.Ip.OutNoRoutes = value + procSnmp.Ip.OutNoRoutes = &value case "ReasmTimeout": - procSnmp.Ip.ReasmTimeout = value + procSnmp.Ip.ReasmTimeout = &value case "ReasmReqds": - procSnmp.Ip.ReasmReqds = value + procSnmp.Ip.ReasmReqds = &value case "ReasmOKs": - procSnmp.Ip.ReasmOKs = value + procSnmp.Ip.ReasmOKs = &value case "ReasmFails": - procSnmp.Ip.ReasmFails = value + procSnmp.Ip.ReasmFails = &value case "FragOKs": - procSnmp.Ip.FragOKs = value + procSnmp.Ip.FragOKs = &value case "FragFails": - procSnmp.Ip.FragFails = value + procSnmp.Ip.FragFails = &value case "FragCreates": - procSnmp.Ip.FragCreates = value + procSnmp.Ip.FragCreates = &value } case "Icmp": switch key { case "InMsgs": - procSnmp.Icmp.InMsgs = value + procSnmp.Icmp.InMsgs = &value case "InErrors": - procSnmp.Icmp.InErrors = value + procSnmp.Icmp.InErrors = &value case "InCsumErrors": - procSnmp.Icmp.InCsumErrors = value + procSnmp.Icmp.InCsumErrors = &value case "InDestUnreachs": - procSnmp.Icmp.InDestUnreachs = value + procSnmp.Icmp.InDestUnreachs = &value case "InTimeExcds": - procSnmp.Icmp.InTimeExcds = value + procSnmp.Icmp.InTimeExcds = &value case "InParmProbs": - procSnmp.Icmp.InParmProbs = value + procSnmp.Icmp.InParmProbs = &value case "InSrcQuenchs": - procSnmp.Icmp.InSrcQuenchs = value + procSnmp.Icmp.InSrcQuenchs = &value case "InRedirects": - procSnmp.Icmp.InRedirects = value + procSnmp.Icmp.InRedirects = &value case "InEchos": - procSnmp.Icmp.InEchos = value + procSnmp.Icmp.InEchos = &value case "InEchoReps": - procSnmp.Icmp.InEchoReps = value + procSnmp.Icmp.InEchoReps = &value case "InTimestamps": - procSnmp.Icmp.InTimestamps = value + procSnmp.Icmp.InTimestamps = &value case "InTimestampReps": - procSnmp.Icmp.InTimestampReps = value + procSnmp.Icmp.InTimestampReps = &value case "InAddrMasks": - procSnmp.Icmp.InAddrMasks = value + procSnmp.Icmp.InAddrMasks = &value case "InAddrMaskReps": - procSnmp.Icmp.InAddrMaskReps = value + procSnmp.Icmp.InAddrMaskReps = &value case "OutMsgs": - procSnmp.Icmp.OutMsgs = value + procSnmp.Icmp.OutMsgs = &value case "OutErrors": - procSnmp.Icmp.OutErrors = value + procSnmp.Icmp.OutErrors = &value case "OutDestUnreachs": - procSnmp.Icmp.OutDestUnreachs = value + procSnmp.Icmp.OutDestUnreachs = &value case "OutTimeExcds": - procSnmp.Icmp.OutTimeExcds = value + procSnmp.Icmp.OutTimeExcds = &value case "OutParmProbs": - procSnmp.Icmp.OutParmProbs = value + procSnmp.Icmp.OutParmProbs = &value case "OutSrcQuenchs": - procSnmp.Icmp.OutSrcQuenchs = value + procSnmp.Icmp.OutSrcQuenchs = &value case "OutRedirects": - procSnmp.Icmp.OutRedirects = value + procSnmp.Icmp.OutRedirects = &value case "OutEchos": - procSnmp.Icmp.OutEchos = value + procSnmp.Icmp.OutEchos = &value case "OutEchoReps": - procSnmp.Icmp.OutEchoReps = value + procSnmp.Icmp.OutEchoReps = &value case "OutTimestamps": - procSnmp.Icmp.OutTimestamps = value + procSnmp.Icmp.OutTimestamps = &value case "OutTimestampReps": - procSnmp.Icmp.OutTimestampReps = value + procSnmp.Icmp.OutTimestampReps = &value case "OutAddrMasks": - procSnmp.Icmp.OutAddrMasks = value + procSnmp.Icmp.OutAddrMasks = &value case "OutAddrMaskReps": - procSnmp.Icmp.OutAddrMaskReps = value + procSnmp.Icmp.OutAddrMaskReps = &value } case "IcmpMsg": switch key { case "InType3": - procSnmp.IcmpMsg.InType3 = value + procSnmp.IcmpMsg.InType3 = &value case "OutType3": - procSnmp.IcmpMsg.OutType3 = value + procSnmp.IcmpMsg.OutType3 = &value } case "Tcp": switch key { case "RtoAlgorithm": - procSnmp.Tcp.RtoAlgorithm = value + procSnmp.Tcp.RtoAlgorithm = &value case "RtoMin": - procSnmp.Tcp.RtoMin = value + procSnmp.Tcp.RtoMin = &value case "RtoMax": - procSnmp.Tcp.RtoMax = value + procSnmp.Tcp.RtoMax = &value case "MaxConn": - procSnmp.Tcp.MaxConn = value + procSnmp.Tcp.MaxConn = &value case "ActiveOpens": - procSnmp.Tcp.ActiveOpens = value + procSnmp.Tcp.ActiveOpens = &value case "PassiveOpens": - procSnmp.Tcp.PassiveOpens = value + procSnmp.Tcp.PassiveOpens = &value case "AttemptFails": - procSnmp.Tcp.AttemptFails = value + procSnmp.Tcp.AttemptFails = &value case "EstabResets": - procSnmp.Tcp.EstabResets = value + procSnmp.Tcp.EstabResets = &value case "CurrEstab": - procSnmp.Tcp.CurrEstab = value + procSnmp.Tcp.CurrEstab = &value case "InSegs": - procSnmp.Tcp.InSegs = value + procSnmp.Tcp.InSegs = &value case "OutSegs": - procSnmp.Tcp.OutSegs = value + procSnmp.Tcp.OutSegs = &value case "RetransSegs": - procSnmp.Tcp.RetransSegs = value + procSnmp.Tcp.RetransSegs = &value case "InErrs": - procSnmp.Tcp.InErrs = value + procSnmp.Tcp.InErrs = &value case "OutRsts": - procSnmp.Tcp.OutRsts = value + procSnmp.Tcp.OutRsts = &value case "InCsumErrors": - procSnmp.Tcp.InCsumErrors = value + procSnmp.Tcp.InCsumErrors = &value } case "Udp": switch key { case "InDatagrams": - procSnmp.Udp.InDatagrams = value + procSnmp.Udp.InDatagrams = &value case "NoPorts": - procSnmp.Udp.NoPorts = value + procSnmp.Udp.NoPorts = &value case "InErrors": - procSnmp.Udp.InErrors = value + procSnmp.Udp.InErrors = &value case "OutDatagrams": - procSnmp.Udp.OutDatagrams = value + procSnmp.Udp.OutDatagrams = &value case "RcvbufErrors": - procSnmp.Udp.RcvbufErrors = value + procSnmp.Udp.RcvbufErrors = &value case "SndbufErrors": - procSnmp.Udp.SndbufErrors = value + procSnmp.Udp.SndbufErrors = &value case "InCsumErrors": - procSnmp.Udp.InCsumErrors = value + procSnmp.Udp.InCsumErrors = &value case "IgnoredMulti": - procSnmp.Udp.IgnoredMulti = value + procSnmp.Udp.IgnoredMulti = &value } case "UdpLite": switch key { case "InDatagrams": - procSnmp.UdpLite.InDatagrams = value + procSnmp.UdpLite.InDatagrams = &value case "NoPorts": - procSnmp.UdpLite.NoPorts = value + procSnmp.UdpLite.NoPorts = &value case "InErrors": - procSnmp.UdpLite.InErrors = value + procSnmp.UdpLite.InErrors = &value case "OutDatagrams": - procSnmp.UdpLite.OutDatagrams = value + procSnmp.UdpLite.OutDatagrams = &value case "RcvbufErrors": - procSnmp.UdpLite.RcvbufErrors = value + procSnmp.UdpLite.RcvbufErrors = &value case "SndbufErrors": - procSnmp.UdpLite.SndbufErrors = value + procSnmp.UdpLite.SndbufErrors = &value case "InCsumErrors": - procSnmp.UdpLite.InCsumErrors = value + procSnmp.UdpLite.InCsumErrors = &value case "IgnoredMulti": - procSnmp.UdpLite.IgnoredMulti = value + procSnmp.UdpLite.IgnoredMulti = &value } } } diff --git a/vendor/github.com/prometheus/procfs/proc_snmp6.go b/vendor/github.com/prometheus/procfs/proc_snmp6.go index f611992d52c..3059cc6a136 100644 --- a/vendor/github.com/prometheus/procfs/proc_snmp6.go +++ b/vendor/github.com/prometheus/procfs/proc_snmp6.go @@ -36,106 +36,106 @@ type ProcSnmp6 struct { } type Ip6 struct { // nolint:revive - InReceives float64 - InHdrErrors float64 - InTooBigErrors float64 - InNoRoutes float64 - InAddrErrors float64 - InUnknownProtos float64 - InTruncatedPkts float64 - InDiscards float64 - InDelivers float64 - OutForwDatagrams float64 - OutRequests float64 - OutDiscards float64 - OutNoRoutes float64 - ReasmTimeout float64 - ReasmReqds float64 - ReasmOKs float64 - ReasmFails float64 - FragOKs float64 - FragFails float64 - FragCreates float64 - InMcastPkts float64 - OutMcastPkts float64 - InOctets float64 - OutOctets float64 - InMcastOctets float64 - OutMcastOctets float64 - InBcastOctets float64 - OutBcastOctets float64 - InNoECTPkts float64 - InECT1Pkts float64 - InECT0Pkts float64 - InCEPkts float64 + InReceives *float64 + InHdrErrors *float64 + InTooBigErrors *float64 + InNoRoutes *float64 + InAddrErrors *float64 + InUnknownProtos *float64 + InTruncatedPkts *float64 + InDiscards *float64 + InDelivers *float64 + OutForwDatagrams *float64 + OutRequests *float64 + OutDiscards *float64 + OutNoRoutes *float64 + ReasmTimeout *float64 + ReasmReqds *float64 + ReasmOKs *float64 + ReasmFails *float64 + FragOKs *float64 + FragFails *float64 + FragCreates *float64 + InMcastPkts *float64 + OutMcastPkts *float64 + InOctets *float64 + OutOctets *float64 + InMcastOctets *float64 + OutMcastOctets *float64 + InBcastOctets *float64 + OutBcastOctets *float64 + InNoECTPkts *float64 + InECT1Pkts *float64 + InECT0Pkts *float64 + InCEPkts *float64 } type Icmp6 struct { - InMsgs float64 - InErrors float64 - OutMsgs float64 - OutErrors float64 - InCsumErrors float64 - InDestUnreachs float64 - InPktTooBigs float64 - InTimeExcds float64 - InParmProblems float64 - InEchos float64 - InEchoReplies float64 - InGroupMembQueries float64 - InGroupMembResponses float64 - InGroupMembReductions float64 - InRouterSolicits float64 - InRouterAdvertisements float64 - InNeighborSolicits float64 - InNeighborAdvertisements float64 - InRedirects float64 - InMLDv2Reports float64 - OutDestUnreachs float64 - OutPktTooBigs float64 - OutTimeExcds float64 - OutParmProblems float64 - OutEchos float64 - OutEchoReplies float64 - OutGroupMembQueries float64 - OutGroupMembResponses float64 - OutGroupMembReductions float64 - OutRouterSolicits float64 - OutRouterAdvertisements float64 - OutNeighborSolicits float64 - OutNeighborAdvertisements float64 - OutRedirects float64 - OutMLDv2Reports float64 - InType1 float64 - InType134 float64 - InType135 float64 - InType136 float64 - InType143 float64 - OutType133 float64 - OutType135 float64 - OutType136 float64 - OutType143 float64 + InMsgs *float64 + InErrors *float64 + OutMsgs *float64 + OutErrors *float64 + InCsumErrors *float64 + InDestUnreachs *float64 + InPktTooBigs *float64 + InTimeExcds *float64 + InParmProblems *float64 + InEchos *float64 + InEchoReplies *float64 + InGroupMembQueries *float64 + InGroupMembResponses *float64 + InGroupMembReductions *float64 + InRouterSolicits *float64 + InRouterAdvertisements *float64 + InNeighborSolicits *float64 + InNeighborAdvertisements *float64 + InRedirects *float64 + InMLDv2Reports *float64 + OutDestUnreachs *float64 + OutPktTooBigs *float64 + OutTimeExcds *float64 + OutParmProblems *float64 + OutEchos *float64 + OutEchoReplies *float64 + OutGroupMembQueries *float64 + OutGroupMembResponses *float64 + OutGroupMembReductions *float64 + OutRouterSolicits *float64 + OutRouterAdvertisements *float64 + OutNeighborSolicits *float64 + OutNeighborAdvertisements *float64 + OutRedirects *float64 + OutMLDv2Reports *float64 + InType1 *float64 + InType134 *float64 + InType135 *float64 + InType136 *float64 + InType143 *float64 + OutType133 *float64 + OutType135 *float64 + OutType136 *float64 + OutType143 *float64 } type Udp6 struct { // nolint:revive - InDatagrams float64 - NoPorts float64 - InErrors float64 - OutDatagrams float64 - RcvbufErrors float64 - SndbufErrors float64 - InCsumErrors float64 - IgnoredMulti float64 + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 + IgnoredMulti *float64 } type UdpLite6 struct { // nolint:revive - InDatagrams float64 - NoPorts float64 - InErrors float64 - OutDatagrams float64 - RcvbufErrors float64 - SndbufErrors float64 - InCsumErrors float64 + InDatagrams *float64 + NoPorts *float64 + InErrors *float64 + OutDatagrams *float64 + RcvbufErrors *float64 + SndbufErrors *float64 + InCsumErrors *float64 } func (p Proc) Snmp6() (ProcSnmp6, error) { @@ -182,197 +182,197 @@ func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { case "Ip6": switch key { case "InReceives": - procSnmp6.Ip6.InReceives = value + procSnmp6.Ip6.InReceives = &value case "InHdrErrors": - procSnmp6.Ip6.InHdrErrors = value + procSnmp6.Ip6.InHdrErrors = &value case "InTooBigErrors": - procSnmp6.Ip6.InTooBigErrors = value + procSnmp6.Ip6.InTooBigErrors = &value case "InNoRoutes": - procSnmp6.Ip6.InNoRoutes = value + procSnmp6.Ip6.InNoRoutes = &value case "InAddrErrors": - procSnmp6.Ip6.InAddrErrors = value + procSnmp6.Ip6.InAddrErrors = &value case "InUnknownProtos": - procSnmp6.Ip6.InUnknownProtos = value + procSnmp6.Ip6.InUnknownProtos = &value case "InTruncatedPkts": - procSnmp6.Ip6.InTruncatedPkts = value + procSnmp6.Ip6.InTruncatedPkts = &value case "InDiscards": - procSnmp6.Ip6.InDiscards = value + procSnmp6.Ip6.InDiscards = &value case "InDelivers": - procSnmp6.Ip6.InDelivers = value + procSnmp6.Ip6.InDelivers = &value case "OutForwDatagrams": - procSnmp6.Ip6.OutForwDatagrams = value + procSnmp6.Ip6.OutForwDatagrams = &value case "OutRequests": - procSnmp6.Ip6.OutRequests = value + procSnmp6.Ip6.OutRequests = &value case "OutDiscards": - procSnmp6.Ip6.OutDiscards = value + procSnmp6.Ip6.OutDiscards = &value case "OutNoRoutes": - procSnmp6.Ip6.OutNoRoutes = value + procSnmp6.Ip6.OutNoRoutes = &value case "ReasmTimeout": - procSnmp6.Ip6.ReasmTimeout = value + procSnmp6.Ip6.ReasmTimeout = &value case "ReasmReqds": - procSnmp6.Ip6.ReasmReqds = value + procSnmp6.Ip6.ReasmReqds = &value case "ReasmOKs": - procSnmp6.Ip6.ReasmOKs = value + procSnmp6.Ip6.ReasmOKs = &value case "ReasmFails": - procSnmp6.Ip6.ReasmFails = value + procSnmp6.Ip6.ReasmFails = &value case "FragOKs": - procSnmp6.Ip6.FragOKs = value + procSnmp6.Ip6.FragOKs = &value case "FragFails": - procSnmp6.Ip6.FragFails = value + procSnmp6.Ip6.FragFails = &value case "FragCreates": - procSnmp6.Ip6.FragCreates = value + procSnmp6.Ip6.FragCreates = &value case "InMcastPkts": - procSnmp6.Ip6.InMcastPkts = value + procSnmp6.Ip6.InMcastPkts = &value case "OutMcastPkts": - procSnmp6.Ip6.OutMcastPkts = value + procSnmp6.Ip6.OutMcastPkts = &value case "InOctets": - procSnmp6.Ip6.InOctets = value + procSnmp6.Ip6.InOctets = &value case "OutOctets": - procSnmp6.Ip6.OutOctets = value + procSnmp6.Ip6.OutOctets = &value case "InMcastOctets": - procSnmp6.Ip6.InMcastOctets = value + procSnmp6.Ip6.InMcastOctets = &value case "OutMcastOctets": - procSnmp6.Ip6.OutMcastOctets = value + procSnmp6.Ip6.OutMcastOctets = &value case "InBcastOctets": - procSnmp6.Ip6.InBcastOctets = value + procSnmp6.Ip6.InBcastOctets = &value case "OutBcastOctets": - procSnmp6.Ip6.OutBcastOctets = value + procSnmp6.Ip6.OutBcastOctets = &value case "InNoECTPkts": - procSnmp6.Ip6.InNoECTPkts = value + procSnmp6.Ip6.InNoECTPkts = &value case "InECT1Pkts": - procSnmp6.Ip6.InECT1Pkts = value + procSnmp6.Ip6.InECT1Pkts = &value case "InECT0Pkts": - procSnmp6.Ip6.InECT0Pkts = value + procSnmp6.Ip6.InECT0Pkts = &value case "InCEPkts": - procSnmp6.Ip6.InCEPkts = value + procSnmp6.Ip6.InCEPkts = &value } case "Icmp6": switch key { case "InMsgs": - procSnmp6.Icmp6.InMsgs = value + procSnmp6.Icmp6.InMsgs = &value case "InErrors": - procSnmp6.Icmp6.InErrors = value + procSnmp6.Icmp6.InErrors = &value case "OutMsgs": - procSnmp6.Icmp6.OutMsgs = value + procSnmp6.Icmp6.OutMsgs = &value case "OutErrors": - procSnmp6.Icmp6.OutErrors = value + procSnmp6.Icmp6.OutErrors = &value case "InCsumErrors": - procSnmp6.Icmp6.InCsumErrors = value + procSnmp6.Icmp6.InCsumErrors = &value case "InDestUnreachs": - procSnmp6.Icmp6.InDestUnreachs = value + procSnmp6.Icmp6.InDestUnreachs = &value case "InPktTooBigs": - procSnmp6.Icmp6.InPktTooBigs = value + procSnmp6.Icmp6.InPktTooBigs = &value case "InTimeExcds": - procSnmp6.Icmp6.InTimeExcds = value + procSnmp6.Icmp6.InTimeExcds = &value case "InParmProblems": - procSnmp6.Icmp6.InParmProblems = value + procSnmp6.Icmp6.InParmProblems = &value case "InEchos": - procSnmp6.Icmp6.InEchos = value + procSnmp6.Icmp6.InEchos = &value case "InEchoReplies": - procSnmp6.Icmp6.InEchoReplies = value + procSnmp6.Icmp6.InEchoReplies = &value case "InGroupMembQueries": - procSnmp6.Icmp6.InGroupMembQueries = value + procSnmp6.Icmp6.InGroupMembQueries = &value case "InGroupMembResponses": - procSnmp6.Icmp6.InGroupMembResponses = value + procSnmp6.Icmp6.InGroupMembResponses = &value case "InGroupMembReductions": - procSnmp6.Icmp6.InGroupMembReductions = value + procSnmp6.Icmp6.InGroupMembReductions = &value case "InRouterSolicits": - procSnmp6.Icmp6.InRouterSolicits = value + procSnmp6.Icmp6.InRouterSolicits = &value case "InRouterAdvertisements": - procSnmp6.Icmp6.InRouterAdvertisements = value + procSnmp6.Icmp6.InRouterAdvertisements = &value case "InNeighborSolicits": - procSnmp6.Icmp6.InNeighborSolicits = value + procSnmp6.Icmp6.InNeighborSolicits = &value case "InNeighborAdvertisements": - procSnmp6.Icmp6.InNeighborAdvertisements = value + procSnmp6.Icmp6.InNeighborAdvertisements = &value case "InRedirects": - procSnmp6.Icmp6.InRedirects = value + procSnmp6.Icmp6.InRedirects = &value case "InMLDv2Reports": - procSnmp6.Icmp6.InMLDv2Reports = value + procSnmp6.Icmp6.InMLDv2Reports = &value case "OutDestUnreachs": - procSnmp6.Icmp6.OutDestUnreachs = value + procSnmp6.Icmp6.OutDestUnreachs = &value case "OutPktTooBigs": - procSnmp6.Icmp6.OutPktTooBigs = value + procSnmp6.Icmp6.OutPktTooBigs = &value case "OutTimeExcds": - procSnmp6.Icmp6.OutTimeExcds = value + procSnmp6.Icmp6.OutTimeExcds = &value case "OutParmProblems": - procSnmp6.Icmp6.OutParmProblems = value + procSnmp6.Icmp6.OutParmProblems = &value case "OutEchos": - procSnmp6.Icmp6.OutEchos = value + procSnmp6.Icmp6.OutEchos = &value case "OutEchoReplies": - procSnmp6.Icmp6.OutEchoReplies = value + procSnmp6.Icmp6.OutEchoReplies = &value case "OutGroupMembQueries": - procSnmp6.Icmp6.OutGroupMembQueries = value + procSnmp6.Icmp6.OutGroupMembQueries = &value case "OutGroupMembResponses": - procSnmp6.Icmp6.OutGroupMembResponses = value + procSnmp6.Icmp6.OutGroupMembResponses = &value case "OutGroupMembReductions": - procSnmp6.Icmp6.OutGroupMembReductions = value + procSnmp6.Icmp6.OutGroupMembReductions = &value case "OutRouterSolicits": - procSnmp6.Icmp6.OutRouterSolicits = value + procSnmp6.Icmp6.OutRouterSolicits = &value case "OutRouterAdvertisements": - procSnmp6.Icmp6.OutRouterAdvertisements = value + procSnmp6.Icmp6.OutRouterAdvertisements = &value case "OutNeighborSolicits": - procSnmp6.Icmp6.OutNeighborSolicits = value + procSnmp6.Icmp6.OutNeighborSolicits = &value case "OutNeighborAdvertisements": - procSnmp6.Icmp6.OutNeighborAdvertisements = value + procSnmp6.Icmp6.OutNeighborAdvertisements = &value case "OutRedirects": - procSnmp6.Icmp6.OutRedirects = value + procSnmp6.Icmp6.OutRedirects = &value case "OutMLDv2Reports": - procSnmp6.Icmp6.OutMLDv2Reports = value + procSnmp6.Icmp6.OutMLDv2Reports = &value case "InType1": - procSnmp6.Icmp6.InType1 = value + procSnmp6.Icmp6.InType1 = &value case "InType134": - procSnmp6.Icmp6.InType134 = value + procSnmp6.Icmp6.InType134 = &value case "InType135": - procSnmp6.Icmp6.InType135 = value + procSnmp6.Icmp6.InType135 = &value case "InType136": - procSnmp6.Icmp6.InType136 = value + procSnmp6.Icmp6.InType136 = &value case "InType143": - procSnmp6.Icmp6.InType143 = value + procSnmp6.Icmp6.InType143 = &value case "OutType133": - procSnmp6.Icmp6.OutType133 = value + procSnmp6.Icmp6.OutType133 = &value case "OutType135": - procSnmp6.Icmp6.OutType135 = value + procSnmp6.Icmp6.OutType135 = &value case "OutType136": - procSnmp6.Icmp6.OutType136 = value + procSnmp6.Icmp6.OutType136 = &value case "OutType143": - procSnmp6.Icmp6.OutType143 = value + procSnmp6.Icmp6.OutType143 = &value } case "Udp6": switch key { case "InDatagrams": - procSnmp6.Udp6.InDatagrams = value + procSnmp6.Udp6.InDatagrams = &value case "NoPorts": - procSnmp6.Udp6.NoPorts = value + procSnmp6.Udp6.NoPorts = &value case "InErrors": - procSnmp6.Udp6.InErrors = value + procSnmp6.Udp6.InErrors = &value case "OutDatagrams": - procSnmp6.Udp6.OutDatagrams = value + procSnmp6.Udp6.OutDatagrams = &value case "RcvbufErrors": - procSnmp6.Udp6.RcvbufErrors = value + procSnmp6.Udp6.RcvbufErrors = &value case "SndbufErrors": - procSnmp6.Udp6.SndbufErrors = value + procSnmp6.Udp6.SndbufErrors = &value case "InCsumErrors": - procSnmp6.Udp6.InCsumErrors = value + procSnmp6.Udp6.InCsumErrors = &value case "IgnoredMulti": - procSnmp6.Udp6.IgnoredMulti = value + procSnmp6.Udp6.IgnoredMulti = &value } case "UdpLite6": switch key { case "InDatagrams": - procSnmp6.UdpLite6.InDatagrams = value + procSnmp6.UdpLite6.InDatagrams = &value case "NoPorts": - procSnmp6.UdpLite6.NoPorts = value + procSnmp6.UdpLite6.NoPorts = &value case "InErrors": - procSnmp6.UdpLite6.InErrors = value + procSnmp6.UdpLite6.InErrors = &value case "OutDatagrams": - procSnmp6.UdpLite6.OutDatagrams = value + procSnmp6.UdpLite6.OutDatagrams = &value case "RcvbufErrors": - procSnmp6.UdpLite6.RcvbufErrors = value + procSnmp6.UdpLite6.RcvbufErrors = &value case "SndbufErrors": - procSnmp6.UdpLite6.SndbufErrors = value + procSnmp6.UdpLite6.SndbufErrors = &value case "InCsumErrors": - procSnmp6.UdpLite6.InCsumErrors = value + procSnmp6.UdpLite6.InCsumErrors = &value } } } diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go index 06c556ef962..14b249f4fc6 100644 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ b/vendor/github.com/prometheus/procfs/proc_stat.go @@ -18,7 +18,6 @@ import ( "fmt" "os" - "github.com/prometheus/procfs/internal/fs" "github.com/prometheus/procfs/internal/util" ) @@ -102,6 +101,8 @@ type ProcStat struct { RSS int // Soft limit in bytes on the rss of the process. RSSLimit uint64 + // CPU number last executed on. + Processor uint // Real-time scheduling priority, a number in the range 1 to 99 for processes // scheduled under a real-time policy, or 0, for non-real-time processes. RTPriority uint @@ -110,7 +111,7 @@ type ProcStat struct { // Aggregated block I/O delays, measured in clock ticks (centiseconds). DelayAcctBlkIOTicks uint64 - proc fs.FS + proc FS } // NewStat returns the current status information of the process. @@ -184,7 +185,7 @@ func (p Proc) Stat() (ProcStat, error) { &ignoreUint64, &ignoreUint64, &ignoreInt64, - &ignoreInt64, + &s.Processor, &s.RTPriority, &s.Policy, &s.DelayAcctBlkIOTicks, @@ -208,8 +209,7 @@ func (s ProcStat) ResidentMemory() int { // StartTime returns the unix timestamp of the process in seconds. func (s ProcStat) StartTime() (float64, error) { - fs := FS{proc: s.proc} - stat, err := fs.Stat() + stat, err := s.proc.Stat() if err != nil { return 0, err } diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go index 594022ded48..c055d075db0 100644 --- a/vendor/github.com/prometheus/procfs/proc_status.go +++ b/vendor/github.com/prometheus/procfs/proc_status.go @@ -15,6 +15,7 @@ package procfs import ( "bytes" + "sort" "strconv" "strings" @@ -76,6 +77,9 @@ type ProcStatus struct { UIDs [4]string // GIDs of the process (Real, effective, saved set, and filesystem GIDs) GIDs [4]string + + // CpusAllowedList: List of cpu cores processes are allowed to run on. + CpusAllowedList []uint64 } // NewStatus returns the current status information of the process. @@ -96,10 +100,10 @@ func (p Proc) NewStatus() (ProcStatus, error) { kv := strings.SplitN(line, ":", 2) // removes spaces - k := string(strings.TrimSpace(kv[0])) - v := string(strings.TrimSpace(kv[1])) + k := strings.TrimSpace(kv[0]) + v := strings.TrimSpace(kv[1]) // removes "kB" - v = string(bytes.Trim([]byte(v), " kB")) + v = strings.TrimSuffix(v, " kB") // value to int when possible // we can skip error check here, 'cause vKBytes is not used when value is a string @@ -161,10 +165,38 @@ func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintByt s.VoluntaryCtxtSwitches = vUint case "nonvoluntary_ctxt_switches": s.NonVoluntaryCtxtSwitches = vUint + case "Cpus_allowed_list": + s.CpusAllowedList = calcCpusAllowedList(vString) } + } // TotalCtxtSwitches returns the total context switch. func (s ProcStatus) TotalCtxtSwitches() uint64 { return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches } + +func calcCpusAllowedList(cpuString string) []uint64 { + s := strings.Split(cpuString, ",") + + var g []uint64 + + for _, cpu := range s { + // parse cpu ranges, example: 1-3=[1,2,3] + if l := strings.Split(strings.TrimSpace(cpu), "-"); len(l) > 1 { + startCPU, _ := strconv.ParseUint(l[0], 10, 64) + endCPU, _ := strconv.ParseUint(l[1], 10, 64) + + for i := startCPU; i <= endCPU; i++ { + g = append(g, i) + } + } else if len(l) == 1 { + cpu, _ := strconv.ParseUint(l[0], 10, 64) + g = append(g, cpu) + } + + } + + sort.Slice(g, func(i, j int) bool { return g[i] < g[j] }) + return g +} diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go index 33f97caa08d..586af48af9f 100644 --- a/vendor/github.com/prometheus/procfs/stat.go +++ b/vendor/github.com/prometheus/procfs/stat.go @@ -62,7 +62,7 @@ type Stat struct { // Summed up cpu statistics. CPUTotal CPUStat // Per-CPU statistics. - CPU []CPUStat + CPU map[int64]CPUStat // Number of times interrupts were handled, which contains numbered and unnumbered IRQs. IRQTotal uint64 // Number of times a numbered IRQ was triggered. @@ -170,10 +170,23 @@ func (fs FS) Stat() (Stat, error) { if err != nil { return Stat{}, err } + procStat, err := parseStat(bytes.NewReader(data), fileName) + if err != nil { + return Stat{}, err + } + return procStat, nil +} - stat := Stat{} +// parseStat parses the metrics from /proc/[pid]/stat. +func parseStat(r io.Reader, fileName string) (Stat, error) { + var ( + scanner = bufio.NewScanner(r) + stat = Stat{ + CPU: make(map[int64]CPUStat), + } + err error + ) - scanner := bufio.NewScanner(bytes.NewReader(data)) for scanner.Scan() { line := scanner.Text() parts := strings.Fields(scanner.Text()) @@ -228,9 +241,6 @@ func (fs FS) Stat() (Stat, error) { if cpuID == -1 { stat.CPUTotal = cpuStat } else { - for int64(len(stat.CPU)) <= cpuID { - stat.CPU = append(stat.CPU, CPUStat{}) - } stat.CPU[cpuID] = cpuStat } } diff --git a/vendor/github.com/prometheus/procfs/thread.go b/vendor/github.com/prometheus/procfs/thread.go new file mode 100644 index 00000000000..490c14708d4 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/thread.go @@ -0,0 +1,80 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "fmt" + "os" + "strconv" + + fsi "github.com/prometheus/procfs/internal/fs" +) + +// Provide access to /proc/PID/task/TID files, for thread specific values. Since +// such files have the same structure as /proc/PID/ ones, the data structures +// and the parsers for the latter may be reused. + +// AllThreads returns a list of all currently available threads under /proc/PID. +func AllThreads(pid int) (Procs, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return Procs{}, err + } + return fs.AllThreads(pid) +} + +// AllThreads returns a list of all currently available threads for PID. +func (fs FS) AllThreads(pid int) (Procs, error) { + taskPath := fs.proc.Path(strconv.Itoa(pid), "task") + d, err := os.Open(taskPath) + if err != nil { + return Procs{}, err + } + defer d.Close() + + names, err := d.Readdirnames(-1) + if err != nil { + return Procs{}, fmt.Errorf("could not read %q: %w", d.Name(), err) + } + + t := Procs{} + for _, n := range names { + tid, err := strconv.ParseInt(n, 10, 64) + if err != nil { + continue + } + + t = append(t, Proc{PID: int(tid), fs: FS{fsi.FS(taskPath), fs.real}}) + } + + return t, nil +} + +// Thread returns a process for a given PID, TID. +func (fs FS) Thread(pid, tid int) (Proc, error) { + taskPath := fs.proc.Path(strconv.Itoa(pid), "task") + if _, err := os.Stat(taskPath); err != nil { + return Proc{}, err + } + return Proc{PID: tid, fs: FS{fsi.FS(taskPath), fs.real}}, nil +} + +// Thread returns a process for a given TID of Proc. +func (proc Proc) Thread(tid int) (Proc, error) { + tfs := FS{fsi.FS(proc.path("task")), proc.fs.real} + if _, err := os.Stat(tfs.proc.Path(strconv.Itoa(tid))); err != nil { + return Proc{}, err + } + return Proc{PID: tid, fs: tfs}, nil +} diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go index 20ceb77e2df..cdedcae996d 100644 --- a/vendor/github.com/prometheus/procfs/vm.go +++ b/vendor/github.com/prometheus/procfs/vm.go @@ -26,7 +26,9 @@ import ( ) // The VM interface is described at -// https://www.kernel.org/doc/Documentation/sysctl/vm.txt +// +// https://www.kernel.org/doc/Documentation/sysctl/vm.txt +// // Each setting is exposed as a single file. // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array // and numa_zonelist_order (deprecated) which is a string. diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index b042c896f25..d1d4a85fd75 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -9,7 +9,7 @@ the last thing you want from your Logging library (again...). This does not mean Logrus is dead. Logrus will continue to be maintained for security, (backwards compatible) bug fixes, and performance (where we are -limited by the interface). +limited by the interface). I believe Logrus' biggest contribution is to have played a part in today's widespread use of structured logging in Golang. There doesn't seem to be a @@ -43,7 +43,7 @@ plain text): With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash or Splunk: -```json +```text {"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} @@ -99,7 +99,7 @@ time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcr ``` Note that this does add measurable overhead - the cost will depend on the version of Go, but is between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your -environment via benchmarks: +environment via benchmarks: ``` go test -bench=.*CallerTracing ``` @@ -317,6 +317,8 @@ log.SetLevel(log.InfoLevel) It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose environment if your application has that. +Note: If you want different log levels for global (`log.SetLevel(...)`) and syslog logging, please check the [syslog hook README](hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging). + #### Entries Besides the fields added with `WithField` or `WithFields` some fields are diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go index 72e8e3a1b65..074fd4b8bd7 100644 --- a/vendor/github.com/sirupsen/logrus/writer.go +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -4,6 +4,7 @@ import ( "bufio" "io" "runtime" + "strings" ) // Writer at INFO level. See WriterLevel for details. @@ -20,15 +21,18 @@ func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { return NewEntry(logger).WriterLevel(level) } +// Writer returns an io.Writer that writes to the logger at the info log level func (entry *Entry) Writer() *io.PipeWriter { return entry.WriterLevel(InfoLevel) } +// WriterLevel returns an io.Writer that writes to the logger at the given log level func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { reader, writer := io.Pipe() var printFunc func(args ...interface{}) + // Determine which log function to use based on the specified log level switch level { case TraceLevel: printFunc = entry.Trace @@ -48,23 +52,51 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { printFunc = entry.Print } + // Start a new goroutine to scan the input and write it to the logger using the specified print function. + // It splits the input into chunks of up to 64KB to avoid buffer overflows. go entry.writerScanner(reader, printFunc) + + // Set a finalizer function to close the writer when it is garbage collected runtime.SetFinalizer(writer, writerFinalizer) return writer } +// writerScanner scans the input from the reader and writes it to the logger func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { scanner := bufio.NewScanner(reader) + + // Set the buffer size to the maximum token size to avoid buffer overflows + scanner.Buffer(make([]byte, bufio.MaxScanTokenSize), bufio.MaxScanTokenSize) + + // Define a split function to split the input into chunks of up to 64KB + chunkSize := bufio.MaxScanTokenSize // 64KB + splitFunc := func(data []byte, atEOF bool) (int, []byte, error) { + if len(data) >= chunkSize { + return chunkSize, data[:chunkSize], nil + } + + return bufio.ScanLines(data, atEOF) + } + + // Use the custom split function to split the input + scanner.Split(splitFunc) + + // Scan the input and write it to the logger using the specified print function for scanner.Scan() { - printFunc(scanner.Text()) + printFunc(strings.TrimRight(scanner.Text(), "\r\n")) } + + // If there was an error while scanning the input, log an error if err := scanner.Err(); err != nil { entry.Errorf("Error while reading from Writer: %s", err) } + + // Close the reader when we are done reader.Close() } +// WriterFinalizer is a finalizer function that closes then given writer when it is garbage collected func writerFinalizer(writer *io.PipeWriter) { writer.Close() } diff --git a/vendor/github.com/spf13/cobra/.golangci.yml b/vendor/github.com/spf13/cobra/.golangci.yml index 439d3e1de4e..2578d94b5eb 100644 --- a/vendor/github.com/spf13/cobra/.golangci.yml +++ b/vendor/github.com/spf13/cobra/.golangci.yml @@ -1,4 +1,4 @@ -# Copyright 2013-2022 The Cobra Authors +# Copyright 2013-2023 The Cobra Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/Makefile b/vendor/github.com/spf13/cobra/Makefile index c433a01bced..0da8d7aa08a 100644 --- a/vendor/github.com/spf13/cobra/Makefile +++ b/vendor/github.com/spf13/cobra/Makefile @@ -5,10 +5,6 @@ ifeq (, $(shell which golangci-lint)) $(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh") endif -ifeq (, $(shell which richgo)) -$(warning "could not find richgo in $(PATH), run: go install github.com/kyoh86/richgo@latest") -endif - .PHONY: fmt lint test install_deps clean default: all @@ -25,6 +21,10 @@ lint: test: install_deps $(info ******************** running tests ********************) + go test -v ./... + +richtest: install_deps + $(info ******************** running tests with kyoh86/richgo ********************) richgo test -v ./... install_deps: diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 7cc726beb42..592c0b8ab05 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -1,4 +1,4 @@ -![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png) +![cobra logo](assets/CobraMain.png) Cobra is a library for creating powerful modern CLI applications. @@ -6,7 +6,7 @@ Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/), [Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra. -[![](https://img.shields.io/github/workflow/status/spf13/cobra/Test?longCache=tru&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest) +[![](https://img.shields.io/github/actions/workflow/status/spf13/cobra/test.yml?branch=main&longCache=true&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest) [![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra) [![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra) [![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199) diff --git a/vendor/github.com/spf13/cobra/active_help.go b/vendor/github.com/spf13/cobra/active_help.go index 95e03aecb60..2d0239437a8 100644 --- a/vendor/github.com/spf13/cobra/active_help.go +++ b/vendor/github.com/spf13/cobra/active_help.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go index 2c1f99e7870..e79ec33a81d 100644 --- a/vendor/github.com/spf13/cobra/args.go +++ b/vendor/github.com/spf13/cobra/args.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import ( type PositionalArgs func(cmd *Command, args []string) error -// Legacy arg validation has the following behaviour: +// legacyArgs validation has the following behaviour: // - root commands with no subcommands can take arbitrary arguments // - root commands with subcommands will do subcommand validity checking // - subcommands will always accept arbitrary arguments diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go index 3acdb27974e..10c78847de2 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.go +++ b/vendor/github.com/spf13/cobra/bash_completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -532,7 +532,7 @@ func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) { } } -// Setup annotations for go completions for registered flags +// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags func prepareCustomAnnotationsForFlags(cmd *Command) { flagCompletionMutex.RLock() defer flagCompletionMutex.RUnlock() diff --git a/vendor/github.com/spf13/cobra/bash_completionsV2.go b/vendor/github.com/spf13/cobra/bash_completionsV2.go index bb4b71892c2..19b09560c1e 100644 --- a/vendor/github.com/spf13/cobra/bash_completionsV2.go +++ b/vendor/github.com/spf13/cobra/bash_completionsV2.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ func genBashComp(buf io.StringWriter, name string, includeDesc bool) { __%[1]s_debug() { - if [[ -n ${BASH_COMP_DEBUG_FILE:-} ]]; then + if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then echo "$*" >> "${BASH_COMP_DEBUG_FILE}" fi } @@ -65,7 +65,7 @@ __%[1]s_get_completion_results() { lastChar=${lastParam:$((${#lastParam}-1)):1} __%[1]s_debug "lastParam ${lastParam}, lastChar ${lastChar}" - if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then + if [[ -z ${cur} && ${lastChar} != = ]]; then # If the last parameter is complete (there is a space following it) # We add an extra empty parameter so we can indicate this to the go method. __%[1]s_debug "Adding extra empty parameter" @@ -75,7 +75,7 @@ __%[1]s_get_completion_results() { # When completing a flag with an = (e.g., %[1]s -n=) # bash focuses on the part after the =, so we need to remove # the flag part from $cur - if [[ "${cur}" == -*=* ]]; then + if [[ ${cur} == -*=* ]]; then cur="${cur#*=}" fi @@ -87,7 +87,7 @@ __%[1]s_get_completion_results() { directive=${out##*:} # Remove the directive out=${out%%:*} - if [ "${directive}" = "${out}" ]; then + if [[ ${directive} == "${out}" ]]; then # There is not directive specified directive=0 fi @@ -101,22 +101,36 @@ __%[1]s_process_completion_results() { local shellCompDirectiveNoFileComp=%[5]d local shellCompDirectiveFilterFileExt=%[6]d local shellCompDirectiveFilterDirs=%[7]d + local shellCompDirectiveKeepOrder=%[8]d - if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + if (((directive & shellCompDirectiveError) != 0)); then # Error code. No completion. __%[1]s_debug "Received error from custom completion go code" return else - if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then + if (((directive & shellCompDirectiveNoSpace) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then __%[1]s_debug "Activating no space" compopt -o nospace else __%[1]s_debug "No space directive not supported in this version of bash" fi fi - if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then - if [[ $(type -t compopt) = "builtin" ]]; then + if (((directive & shellCompDirectiveKeepOrder) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then + # no sort isn't supported for bash less than < 4.4 + if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then + __%[1]s_debug "No sort directive not supported in this version of bash" + else + __%[1]s_debug "Activating keep order" + compopt -o nosort + fi + else + __%[1]s_debug "No sort directive not supported in this version of bash" + fi + fi + if (((directive & shellCompDirectiveNoFileComp) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then __%[1]s_debug "Activating no file completion" compopt +o default else @@ -130,7 +144,7 @@ __%[1]s_process_completion_results() { local activeHelp=() __%[1]s_extract_activeHelp - if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + if (((directive & shellCompDirectiveFilterFileExt) != 0)); then # File extension filtering local fullFilter filter filteringCmd @@ -143,13 +157,12 @@ __%[1]s_process_completion_results() { filteringCmd="_filedir $fullFilter" __%[1]s_debug "File filtering command: $filteringCmd" $filteringCmd - elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + elif (((directive & shellCompDirectiveFilterDirs) != 0)); then # File completion for directories only - # Use printf to strip any trailing newline local subdir - subdir=$(printf "%%s" "${completions[0]}") - if [ -n "$subdir" ]; then + subdir=${completions[0]} + if [[ -n $subdir ]]; then __%[1]s_debug "Listing directories in $subdir" pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return else @@ -164,7 +177,7 @@ __%[1]s_process_completion_results() { __%[1]s_handle_special_char "$cur" = # Print the activeHelp statements before we finish - if [ ${#activeHelp[*]} -ne 0 ]; then + if ((${#activeHelp[*]} != 0)); then printf "\n"; printf "%%s\n" "${activeHelp[@]}" printf "\n" @@ -184,21 +197,21 @@ __%[1]s_process_completion_results() { # Separate activeHelp lines from real completions. # Fills the $activeHelp and $completions arrays. __%[1]s_extract_activeHelp() { - local activeHelpMarker="%[8]s" + local activeHelpMarker="%[9]s" local endIndex=${#activeHelpMarker} while IFS='' read -r comp; do - if [ "${comp:0:endIndex}" = "$activeHelpMarker" ]; then + if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then comp=${comp:endIndex} __%[1]s_debug "ActiveHelp found: $comp" - if [ -n "$comp" ]; then + if [[ -n $comp ]]; then activeHelp+=("$comp") fi else # Not an activeHelp line but a normal completion completions+=("$comp") fi - done < <(printf "%%s\n" "${out}") + done <<<"${out}" } __%[1]s_handle_completion_types() { @@ -254,7 +267,7 @@ __%[1]s_handle_standard_completion_case() { done < <(printf "%%s\n" "${completions[@]}") # If there is a single completion left, remove the description text - if [ ${#COMPREPLY[*]} -eq 1 ]; then + if ((${#COMPREPLY[*]} == 1)); then __%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}" comp="${COMPREPLY[0]%%%%$tab*}" __%[1]s_debug "Removed description from single completion, which is now: ${comp}" @@ -271,8 +284,8 @@ __%[1]s_handle_special_char() if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then local word=${comp%%"${comp##*${char}}"} local idx=${#COMPREPLY[*]} - while [[ $((--idx)) -ge 0 ]]; do - COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"} + while ((--idx >= 0)); do + COMPREPLY[idx]=${COMPREPLY[idx]#"$word"} done fi } @@ -298,7 +311,7 @@ __%[1]s_format_comp_descriptions() # Make sure we can fit a description of at least 8 characters # if we are to align the descriptions. - if [[ $maxdesclength -gt 8 ]]; then + if ((maxdesclength > 8)); then # Add the proper number of spaces to align the descriptions for ((i = ${#comp} ; i < longest ; i++)); do comp+=" " @@ -310,8 +323,8 @@ __%[1]s_format_comp_descriptions() # If there is enough space for any description text, # truncate the descriptions that are too long for the shell width - if [ $maxdesclength -gt 0 ]; then - if [ ${#desc} -gt $maxdesclength ]; then + if ((maxdesclength > 0)); then + if ((${#desc} > maxdesclength)); then desc=${desc:0:$(( maxdesclength - 1 ))} desc+="…" fi @@ -332,9 +345,9 @@ __start_%[1]s() # Call _init_completion from the bash-completion package # to prepare the arguments properly if declare -F _init_completion >/dev/null 2>&1; then - _init_completion -n "=:" || return + _init_completion -n =: || return else - __%[1]s_init_completion -n "=:" || return + __%[1]s_init_completion -n =: || return fi __%[1]s_debug @@ -361,7 +374,7 @@ fi # ex: ts=4 sw=4 et filetype=sh `, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpMarker)) } diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go index fe44bc8a07e..b07b44a0ce2 100644 --- a/vendor/github.com/spf13/cobra/cobra.go +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -167,8 +167,8 @@ func appendIfNotPresent(s, stringToAppend string) string { // rpad adds padding to the right of a string. func rpad(s string, padding int) string { - template := fmt.Sprintf("%%-%ds", padding) - return fmt.Sprintf(template, s) + formattedString := fmt.Sprintf("%%-%ds", padding) + return fmt.Sprintf(formattedString, s) } // tmpl executes the given template text on data, writing the result to w. diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index 6ff47dd5c35..01f7c6f1c5e 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ const FlagSetByCobraAnnotation = "cobra_annotation_flag_set_by_cobra" // FParseErrWhitelist configures Flag parse errors to be ignored type FParseErrWhitelist flag.ParseErrorsWhitelist -// Structure to manage groups for commands +// Group Structure to manage groups for commands type Group struct { ID string Title string @@ -47,7 +47,7 @@ type Group struct { // definition to ensure usability. type Command struct { // Use is the one-line usage message. - // Recommended syntax is as follow: + // Recommended syntax is as follows: // [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required. // ... indicates that you can specify multiple values for the previous argument. // | indicates mutually exclusive information. You can use the argument to the left of the separator or the @@ -321,7 +321,7 @@ func (c *Command) SetHelpCommand(cmd *Command) { c.helpCommand = cmd } -// SetHelpCommandGroup sets the group id of the help command. +// SetHelpCommandGroupID sets the group id of the help command. func (c *Command) SetHelpCommandGroupID(groupID string) { if c.helpCommand != nil { c.helpCommand.GroupID = groupID @@ -330,7 +330,7 @@ func (c *Command) SetHelpCommandGroupID(groupID string) { c.helpCommandGroupID = groupID } -// SetCompletionCommandGroup sets the group id of the completion command. +// SetCompletionCommandGroupID sets the group id of the completion command. func (c *Command) SetCompletionCommandGroupID(groupID string) { // completionCommandGroupID is used if no completion command is defined by the user c.Root().completionCommandGroupID = groupID @@ -655,20 +655,44 @@ Loop: // argsMinusFirstX removes only the first x from args. Otherwise, commands that look like // openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]). -func argsMinusFirstX(args []string, x string) []string { - for i, y := range args { - if x == y { - ret := []string{} - ret = append(ret, args[:i]...) - ret = append(ret, args[i+1:]...) - return ret +// Special care needs to be taken not to remove a flag value. +func (c *Command) argsMinusFirstX(args []string, x string) []string { + if len(args) == 0 { + return args + } + c.mergePersistentFlags() + flags := c.Flags() + +Loop: + for pos := 0; pos < len(args); pos++ { + s := args[pos] + switch { + case s == "--": + // -- means we have reached the end of the parseable args. Break out of the loop now. + break Loop + case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags): + fallthrough + case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): + // This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip + // over the next arg, because that is the value of this flag. + pos++ + continue + case !strings.HasPrefix(s, "-"): + // This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so, + // return the args, excluding the one at this position. + if s == x { + ret := []string{} + ret = append(ret, args[:pos]...) + ret = append(ret, args[pos+1:]...) + return ret + } } } return args } func isFlagArg(arg string) bool { - return ((len(arg) >= 3 && arg[1] == '-') || + return ((len(arg) >= 3 && arg[0:2] == "--") || (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-')) } @@ -686,7 +710,7 @@ func (c *Command) Find(args []string) (*Command, []string, error) { cmd := c.findNext(nextSubCmd) if cmd != nil { - return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd)) + return innerfind(cmd, c.argsMinusFirstX(innerArgs, nextSubCmd)) } return c, innerArgs } @@ -1272,7 +1296,7 @@ func (c *Command) AllChildCommandsHaveGroup() bool { return true } -// ContainGroups return if groupID exists in the list of command groups. +// ContainsGroup return if groupID exists in the list of command groups. func (c *Command) ContainsGroup(groupID string) bool { for _, x := range c.commandgroups { if x.ID == groupID { diff --git a/vendor/github.com/spf13/cobra/command_notwin.go b/vendor/github.com/spf13/cobra/command_notwin.go index 2b77f8f0190..307f0c127fd 100644 --- a/vendor/github.com/spf13/cobra/command_notwin.go +++ b/vendor/github.com/spf13/cobra/command_notwin.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/command_win.go b/vendor/github.com/spf13/cobra/command_win.go index 520f23abf09..adbef395c25 100644 --- a/vendor/github.com/spf13/cobra/command_win.go +++ b/vendor/github.com/spf13/cobra/command_win.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/completions.go b/vendor/github.com/spf13/cobra/completions.go index e8a0206db10..ee38c4d0b86 100644 --- a/vendor/github.com/spf13/cobra/completions.go +++ b/vendor/github.com/spf13/cobra/completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -77,6 +77,10 @@ const ( // obtain the same behavior but only for flags. ShellCompDirectiveFilterDirs + // ShellCompDirectiveKeepOrder indicates that the shell should preserve the order + // in which the completions are provided + ShellCompDirectiveKeepOrder + // =========================================================================== // All directives using iota should be above this one. @@ -159,6 +163,9 @@ func (d ShellCompDirective) string() string { if d&ShellCompDirectiveFilterDirs != 0 { directives = append(directives, "ShellCompDirectiveFilterDirs") } + if d&ShellCompDirectiveKeepOrder != 0 { + directives = append(directives, "ShellCompDirectiveKeepOrder") + } if len(directives) == 0 { directives = append(directives, "ShellCompDirectiveDefault") } @@ -169,7 +176,7 @@ func (d ShellCompDirective) string() string { return strings.Join(directives, ", ") } -// Adds a special hidden command that can be used to request custom completions. +// initCompleteCmd adds a special hidden command that can be used to request custom completions. func (c *Command) initCompleteCmd(args []string) { completeCmd := &Command{ Use: fmt.Sprintf("%s [command-line]", ShellCompRequestCmd), @@ -727,7 +734,7 @@ to enable it. You can execute the following once: To load completions in your current shell session: - source <(%[1]s completion zsh); compdef _%[1]s %[1]s + source <(%[1]s completion zsh) To load completions for every new session, execute once: diff --git a/vendor/github.com/spf13/cobra/fish_completions.go b/vendor/github.com/spf13/cobra/fish_completions.go index 97112a17b29..12ca0d2b11c 100644 --- a/vendor/github.com/spf13/cobra/fish_completions.go +++ b/vendor/github.com/spf13/cobra/fish_completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ function __%[1]s_perform_completion __%[1]s_debug "last arg: $lastArg" # Disable ActiveHelp which is not supported for fish shell - set -l requestComp "%[9]s=0 $args[1] %[3]s $args[2..-1] $lastArg" + set -l requestComp "%[10]s=0 $args[1] %[3]s $args[2..-1] $lastArg" __%[1]s_debug "Calling $requestComp" set -l results (eval $requestComp 2> /dev/null) @@ -89,6 +89,60 @@ function __%[1]s_perform_completion printf "%%s\n" "$directiveLine" end +# this function limits calls to __%[1]s_perform_completion, by caching the result behind $__%[1]s_perform_completion_once_result +function __%[1]s_perform_completion_once + __%[1]s_debug "Starting __%[1]s_perform_completion_once" + + if test -n "$__%[1]s_perform_completion_once_result" + __%[1]s_debug "Seems like a valid result already exists, skipping __%[1]s_perform_completion" + return 0 + end + + set --global __%[1]s_perform_completion_once_result (__%[1]s_perform_completion) + if test -z "$__%[1]s_perform_completion_once_result" + __%[1]s_debug "No completions, probably due to a failure" + return 1 + end + + __%[1]s_debug "Performed completions and set __%[1]s_perform_completion_once_result" + return 0 +end + +# this function is used to clear the $__%[1]s_perform_completion_once_result variable after completions are run +function __%[1]s_clear_perform_completion_once_result + __%[1]s_debug "" + __%[1]s_debug "========= clearing previously set __%[1]s_perform_completion_once_result variable ==========" + set --erase __%[1]s_perform_completion_once_result + __%[1]s_debug "Succesfully erased the variable __%[1]s_perform_completion_once_result" +end + +function __%[1]s_requires_order_preservation + __%[1]s_debug "" + __%[1]s_debug "========= checking if order preservation is required ==========" + + __%[1]s_perform_completion_once + if test -z "$__%[1]s_perform_completion_once_result" + __%[1]s_debug "Error determining if order preservation is required" + return 1 + end + + set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1]) + __%[1]s_debug "Directive is: $directive" + + set -l shellCompDirectiveKeepOrder %[9]d + set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) %% 2) + __%[1]s_debug "Keeporder is: $keeporder" + + if test $keeporder -ne 0 + __%[1]s_debug "This does require order preservation" + return 0 + end + + __%[1]s_debug "This doesn't require order preservation" + return 1 +end + + # This function does two things: # - Obtain the completions and store them in the global __%[1]s_comp_results # - Return false if file completion should be performed @@ -99,17 +153,17 @@ function __%[1]s_prepare_completions # Start fresh set --erase __%[1]s_comp_results - set -l results (__%[1]s_perform_completion) - __%[1]s_debug "Completion results: $results" + __%[1]s_perform_completion_once + __%[1]s_debug "Completion results: $__%[1]s_perform_completion_once_result" - if test -z "$results" + if test -z "$__%[1]s_perform_completion_once_result" __%[1]s_debug "No completion, probably due to a failure" # Might as well do file completion, in case it helps return 1 end - set -l directive (string sub --start 2 $results[-1]) - set --global __%[1]s_comp_results $results[1..-2] + set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1]) + set --global __%[1]s_comp_results $__%[1]s_perform_completion_once_result[1..-2] __%[1]s_debug "Completions are: $__%[1]s_comp_results" __%[1]s_debug "Directive is: $directive" @@ -205,13 +259,17 @@ end # Remove any pre-existing completions for the program since we will be handling all of them. complete -c %[2]s -e +# this will get called after the two calls below and clear the $__%[1]s_perform_completion_once_result global +complete -c %[2]s -n '__%[1]s_clear_perform_completion_once_result' # The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results # which provides the program's completion choices. -complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results' - +# If this doesn't require order preservation, we don't use the -k flag +complete -c %[2]s -n 'not __%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results' +# otherwise we use the -k flag +complete -k -c %[2]s -n '__%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results' `, nameForVar, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name))) + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name))) } // GenFishCompletion generates fish completion file and writes to the passed writer. diff --git a/vendor/github.com/spf13/cobra/flag_groups.go b/vendor/github.com/spf13/cobra/flag_groups.go index 9c377aaf9c9..b35fde15548 100644 --- a/vendor/github.com/spf13/cobra/flag_groups.go +++ b/vendor/github.com/spf13/cobra/flag_groups.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/powershell_completions.go b/vendor/github.com/spf13/cobra/powershell_completions.go index 004de42e41e..177d2755f21 100644 --- a/vendor/github.com/spf13/cobra/powershell_completions.go +++ b/vendor/github.com/spf13/cobra/powershell_completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -77,6 +77,7 @@ filter __%[1]s_escapeStringWithSpecialChars { $ShellCompDirectiveNoFileComp=%[6]d $ShellCompDirectiveFilterFileExt=%[7]d $ShellCompDirectiveFilterDirs=%[8]d + $ShellCompDirectiveKeepOrder=%[9]d # Prepare the command to request completions for the program. # Split the command at the first space to separate the program and arguments. @@ -106,13 +107,22 @@ filter __%[1]s_escapeStringWithSpecialChars { # If the last parameter is complete (there is a space following it) # We add an extra empty parameter so we can indicate this to the go method. __%[1]s_debug "Adding extra empty parameter" -`+" # We need to use `\"`\" to pass an empty argument a \"\" or '' does not work!!!"+` -`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+` + # PowerShell 7.2+ changed the way how the arguments are passed to executables, + # so for pre-7.2 or when Legacy argument passing is enabled we need to use +`+" # `\"`\" to pass an empty argument, a \"\" or '' does not work!!!"+` + if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or + ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or + (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and + $PSNativeCommandArgumentPassing -eq 'Legacy')) { +`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+` + } else { + $RequestComp="$RequestComp" + ' ""' + } } __%[1]s_debug "Calling $RequestComp" # First disable ActiveHelp which is not supported for Powershell - $env:%[9]s=0 + $env:%[10]s=0 #call the command store the output in $out and redirect stderr and stdout to null # $Out is an array contains each line per element @@ -137,7 +147,7 @@ filter __%[1]s_escapeStringWithSpecialChars { } $Longest = 0 - $Values = $Out | ForEach-Object { + [Array]$Values = $Out | ForEach-Object { #Split the output in name and description `+" $Name, $Description = $_.Split(\"`t\",2)"+` __%[1]s_debug "Name: $Name Description: $Description" @@ -182,6 +192,11 @@ filter __%[1]s_escapeStringWithSpecialChars { } } + # we sort the values in ascending order by name if keep order isn't passed + if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) { + $Values = $Values | Sort-Object -Property Name + } + if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) { __%[1]s_debug "ShellCompDirectiveNoFileComp is called" @@ -267,7 +282,7 @@ filter __%[1]s_escapeStringWithSpecialChars { Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock `, name, nameForVar, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name))) + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name))) } func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error { diff --git a/vendor/github.com/spf13/cobra/projects_using_cobra.md b/vendor/github.com/spf13/cobra/projects_using_cobra.md index 6865f88e79a..8a291eb20e8 100644 --- a/vendor/github.com/spf13/cobra/projects_using_cobra.md +++ b/vendor/github.com/spf13/cobra/projects_using_cobra.md @@ -1,11 +1,13 @@ ## Projects using Cobra - [Allero](https://github.com/allero-io/allero) +- [Arewefastyet](https://benchmark.vitess.io) - [Arduino CLI](https://github.com/arduino/arduino-cli) - [Bleve](https://blevesearch.com/) - [Cilium](https://cilium.io/) - [CloudQuery](https://github.com/cloudquery/cloudquery) - [CockroachDB](https://www.cockroachlabs.com/) +- [Constellation](https://github.com/edgelesssys/constellation) - [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) - [Datree](https://github.com/datreeio/datree) - [Delve](https://github.com/derekparker/delve) @@ -25,7 +27,7 @@ - [Istio](https://istio.io) - [Kool](https://github.com/kool-dev/kool) - [Kubernetes](https://kubernetes.io/) -- [Kubescape](https://github.com/armosec/kubescape) +- [Kubescape](https://github.com/kubescape/kubescape) - [KubeVirt](https://github.com/kubevirt/kubevirt) - [Linkerd](https://linkerd.io/) - [Mattermost-server](https://github.com/mattermost/mattermost-server) @@ -51,10 +53,12 @@ - [Random](https://github.com/erdaltsksn/random) - [Rclone](https://rclone.org/) - [Scaleway CLI](https://github.com/scaleway/scaleway-cli) +- [Sia](https://github.com/SiaFoundation/siad) - [Skaffold](https://skaffold.dev/) - [Tendermint](https://github.com/tendermint/tendermint) - [Twitch CLI](https://github.com/twitchdev/twitch-cli) - [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli) +- [Vitess](https://vitess.io) - VMware's [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) & [Tanzu Framework](https://github.com/vmware-tanzu/tanzu-framework) - [Werf](https://werf.io/) - [ZITADEL](https://github.com/zitadel/zitadel) diff --git a/vendor/github.com/spf13/cobra/shell_completions.go b/vendor/github.com/spf13/cobra/shell_completions.go index 126e83c307e..b035742d399 100644 --- a/vendor/github.com/spf13/cobra/shell_completions.go +++ b/vendor/github.com/spf13/cobra/shell_completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/spf13/cobra/shell_completions.md b/vendor/github.com/spf13/cobra/shell_completions.md index 553ee5df8a7..065c0621d4c 100644 --- a/vendor/github.com/spf13/cobra/shell_completions.md +++ b/vendor/github.com/spf13/cobra/shell_completions.md @@ -71,7 +71,7 @@ PowerShell: `,cmd.Root().Name()), DisableFlagsInUseLine: true, ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), + Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { switch args[0] { case "bash": @@ -162,16 +162,7 @@ cmd := &cobra.Command{ } ``` -The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by -the completion algorithm if entered manually, e.g. in: - -```bash -$ kubectl get rc [tab][tab] -backend frontend database -``` - -Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of -replication controllers following `rc`. +The aliases are shown to the user on tab completion only if no completions were found within sub-commands or `ValidArgs`. ### Dynamic completion of nouns @@ -237,6 +228,10 @@ ShellCompDirectiveFilterFileExt // return []string{"themes"}, ShellCompDirectiveFilterDirs // ShellCompDirectiveFilterDirs + +// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order +// in which the completions are provided +ShellCompDirectiveKeepOrder ``` ***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function. @@ -385,6 +380,19 @@ or ```go ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"} ``` + +If you don't want to show descriptions in the completions, you can add `--no-descriptions` to the default `completion` command to disable them, like: + +```bash +$ source <(helm completion bash) +$ helm completion [tab][tab] +bash (generate autocompletion script for bash) powershell (generate autocompletion script for powershell) +fish (generate autocompletion script for fish) zsh (generate autocompletion script for zsh) + +$ source <(helm completion bash --no-descriptions) +$ helm completion [tab][tab] +bash fish powershell zsh +``` ## Bash completions ### Dependencies diff --git a/vendor/github.com/spf13/cobra/user_guide.md b/vendor/github.com/spf13/cobra/user_guide.md index e55367e853f..85201d840c8 100644 --- a/vendor/github.com/spf13/cobra/user_guide.md +++ b/vendor/github.com/spf13/cobra/user_guide.md @@ -188,6 +188,37 @@ var versionCmd = &cobra.Command{ } ``` +### Organizing subcommands + +A command may have subcommands which in turn may have other subcommands. This is achieved by using +`AddCommand`. In some cases, especially in larger applications, each subcommand may be defined in +its own go package. + +The suggested approach is for the parent command to use `AddCommand` to add its most immediate +subcommands. For example, consider the following directory structure: + +```text +├── cmd +│   ├── root.go +│   └── sub1 +│   ├── sub1.go +│   └── sub2 +│   ├── leafA.go +│   ├── leafB.go +│   └── sub2.go +└── main.go +``` + +In this case: + +* The `init` function of `root.go` adds the command defined in `sub1.go` to the root command. +* The `init` function of `sub1.go` adds the command defined in `sub2.go` to the sub1 command. +* The `init` function of `sub2.go` adds the commands defined in `leafA.go` and `leafB.go` to the + sub2 command. + +This approach ensures the subcommands are always included at compile time while avoiding cyclic +references. + ### Returning and handling errors If you wish to return an error to the caller of a command, `RunE` can be used. @@ -313,8 +344,8 @@ rootCmd.MarkFlagsRequiredTogether("username", "password") You can also prevent different flags from being provided together if they represent mutually exclusive options such as specifying an output format as either `--json` or `--yaml` but never both: ```go -rootCmd.Flags().BoolVar(&u, "json", false, "Output in JSON") -rootCmd.Flags().BoolVar(&pw, "yaml", false, "Output in YAML") +rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON") +rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML") rootCmd.MarkFlagsMutuallyExclusive("json", "yaml") ``` @@ -349,7 +380,7 @@ shown below: ```go var cmd = &cobra.Command{ Short: "hello", - Args: MatchAll(ExactArgs(2), OnlyValidArgs), + Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { fmt.Println("Hello, World!") }, diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go index 84cec76fde3..1856e4c7f68 100644 --- a/vendor/github.com/spf13/cobra/zsh_completions.go +++ b/vendor/github.com/spf13/cobra/zsh_completions.go @@ -1,4 +1,4 @@ -// Copyright 2013-2022 The Cobra Authors +// Copyright 2013-2023 The Cobra Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -90,6 +90,7 @@ func genZshComp(buf io.StringWriter, name string, includeDesc bool) { compCmd = ShellCompNoDescRequestCmd } WriteStringAndCheck(buf, fmt.Sprintf(`#compdef %[1]s +compdef _%[1]s %[1]s # zsh completion for %-36[1]s -*- shell-script -*- @@ -108,8 +109,9 @@ _%[1]s() local shellCompDirectiveNoFileComp=%[5]d local shellCompDirectiveFilterFileExt=%[6]d local shellCompDirectiveFilterDirs=%[7]d + local shellCompDirectiveKeepOrder=%[8]d - local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace + local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder local -a completions __%[1]s_debug "\n========= starting completion logic ==========" @@ -177,7 +179,7 @@ _%[1]s() return fi - local activeHelpMarker="%[8]s" + local activeHelpMarker="%[9]s" local endIndex=${#activeHelpMarker} local startIndex=$((${#activeHelpMarker}+1)) local hasActiveHelp=0 @@ -227,6 +229,11 @@ _%[1]s() noSpace="-S ''" fi + if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then + __%[1]s_debug "Activating keep order." + keepOrder="-V" + fi + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then # File extension filtering local filteringCmd @@ -262,7 +269,7 @@ _%[1]s() return $result else __%[1]s_debug "Calling _describe" - if eval _describe "completions" completions $flagPrefix $noSpace; then + if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then __%[1]s_debug "_describe found some completions" # Return the success of having called _describe @@ -296,6 +303,6 @@ if [ "$funcstack[1]" = "_%[1]s" ]; then fi `, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpMarker)) } diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go index 95d8e59da69..b774da88d86 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go @@ -352,9 +352,9 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// assert.Greater(t, 2, 1) +// assert.Greater(t, float64(2), float64(1)) +// assert.Greater(t, "b", "a") func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -364,10 +364,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// assert.GreaterOrEqual(t, 2, 1) +// assert.GreaterOrEqual(t, 2, 2) +// assert.GreaterOrEqual(t, "b", "a") +// assert.GreaterOrEqual(t, "b", "b") func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -377,9 +377,9 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// assert.Less(t, 1, 2) +// assert.Less(t, float64(1), float64(2)) +// assert.Less(t, "a", "b") func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -389,10 +389,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// assert.LessOrEqual(t, 1, 2) +// assert.LessOrEqual(t, 2, 2) +// assert.LessOrEqual(t, "a", "b") +// assert.LessOrEqual(t, "b", "b") func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -402,8 +402,8 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// assert.Positive(t, 1) +// assert.Positive(t, 1.23) func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -414,8 +414,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// assert.Negative(t, -1) +// assert.Negative(t, -1.23) func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go index 7880b8f9433..84dbd6c790b 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -22,9 +22,9 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -56,7 +56,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// assert.Emptyf(t, obj, "error message %s", "formatted") func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -66,7 +66,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// assert.Equalf(t, 123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -81,8 +81,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -90,10 +90,27 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) } +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -103,10 +120,10 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -126,8 +143,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -147,7 +164,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -155,9 +172,34 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) } +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) +} + // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -183,7 +225,7 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// assert.Falsef(t, myBool, "error message %s", "formatted") func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -202,9 +244,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// assert.Greaterf(t, "b", "a", "error message %s", "formatted") func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -214,10 +256,10 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -228,7 +270,7 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -241,7 +283,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -253,7 +295,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPErrorf asserts that a specified handler returns an error status code. // -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -265,7 +307,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -277,7 +319,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { @@ -289,7 +331,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -301,7 +343,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -311,7 +353,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -353,9 +395,9 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -365,9 +407,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -377,9 +419,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -389,9 +431,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -409,7 +451,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -420,7 +462,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -430,9 +472,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// assert.Lessf(t, 1, 2, "error message %s", "formatted") +// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// assert.Lessf(t, "a", "b", "error message %s", "formatted") func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -442,10 +484,10 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -455,8 +497,8 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// assert.Negativef(t, -1, "error message %s", "formatted") +// assert.Negativef(t, -1.23, "error message %s", "formatted") func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -467,7 +509,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -477,7 +519,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// assert.Nilf(t, err, "error message %s", "formatted") func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -496,10 +538,10 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -519,9 +561,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) boo // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -532,9 +574,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -544,7 +586,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -557,7 +599,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -576,7 +618,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// assert.NotNilf(t, err, "error message %s", "formatted") func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -586,7 +628,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -596,8 +638,8 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -607,7 +649,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -621,7 +663,7 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -639,7 +681,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -651,7 +693,7 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -662,7 +704,7 @@ func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -672,8 +714,8 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// assert.Positivef(t, 1, "error message %s", "formatted") +// assert.Positivef(t, 1.23, "error message %s", "formatted") func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -683,8 +725,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -694,7 +736,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -708,7 +750,7 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -718,7 +760,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// assert.Truef(t, myBool, "error message %s", "formatted") func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -728,7 +770,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -738,7 +780,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 339515b8bfb..b1d94aec53c 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -30,9 +30,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{} // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -43,9 +43,9 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs .. // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -98,7 +98,7 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Empty(obj) +// a.Empty(obj) func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -109,7 +109,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Emptyf(obj, "error message %s", "formatted") +// a.Emptyf(obj, "error message %s", "formatted") func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -119,7 +119,7 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Equal asserts that two objects are equal. // -// a.Equal(123, 123) +// a.Equal(123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -134,8 +134,8 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -146,8 +146,8 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -155,10 +155,44 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a return EqualErrorf(a.t, theError, errString, msg, args...) } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true +// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false +func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualExportedValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualExportedValuesf(a.t, expected, actual, msg, args...) +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValues(uint32(123), int32(123)) +// a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -169,7 +203,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") +// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -179,7 +213,7 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Equalf asserts that two objects are equal. // -// a.Equalf(123, 123, "error message %s", "formatted") +// a.Equalf(123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -193,10 +227,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -225,8 +259,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// a.ErrorContains(err, expectedErrorSubString) func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -237,8 +271,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -266,10 +300,10 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -280,7 +314,7 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) +// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -288,10 +322,60 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti return Eventually(a.t, condition, waitFor, tick, msgAndArgs...) } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithT(func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -301,7 +385,7 @@ func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, t // Exactly asserts that two objects are equal in value and type. // -// a.Exactly(int32(123), int64(123)) +// a.Exactly(int32(123), int64(123)) func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -311,7 +395,7 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg // Exactlyf asserts that two objects are equal in value and type. // -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") +// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -353,7 +437,7 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{ // False asserts that the specified value is false. // -// a.False(myBool) +// a.False(myBool) func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -363,7 +447,7 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { // Falsef asserts that the specified value is false. // -// a.Falsef(myBool, "error message %s", "formatted") +// a.Falsef(myBool, "error message %s", "formatted") func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -391,9 +475,9 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) b // Greater asserts that the first element is greater than the second // -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") +// a.Greater(2, 1) +// a.Greater(float64(2), float64(1)) +// a.Greater("b", "a") func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -403,10 +487,10 @@ func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...inter // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") +// a.GreaterOrEqual(2, 1) +// a.GreaterOrEqual(2, 2) +// a.GreaterOrEqual("b", "a") +// a.GreaterOrEqual("b", "b") func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -416,10 +500,10 @@ func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs . // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") +// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") +// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") +// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") +// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -429,9 +513,9 @@ func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, // Greaterf asserts that the first element is greater than the second // -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") +// a.Greaterf(2, 1, "error message %s", "formatted") +// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") +// a.Greaterf("b", "a", "error message %s", "formatted") func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -442,7 +526,7 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -455,7 +539,7 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -468,7 +552,7 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -481,7 +565,7 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -493,7 +577,7 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -505,7 +589,7 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -517,7 +601,7 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -529,7 +613,7 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -541,7 +625,7 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) +// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { @@ -553,7 +637,7 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { @@ -565,7 +649,7 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -577,7 +661,7 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -589,7 +673,7 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s // Implements asserts that an object is implemented by the specified interface. // -// a.Implements((*MyInterface)(nil), new(MyObject)) +// a.Implements((*MyInterface)(nil), new(MyObject)) func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -599,7 +683,7 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, // Implementsf asserts that an object is implemented by the specified interface. // -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -609,7 +693,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{} // InDelta asserts that the two numerals are within delta of each other. // -// a.InDelta(math.Pi, 22/7.0, 0.01) +// a.InDelta(math.Pi, 22/7.0, 0.01) func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -651,7 +735,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del // InDeltaf asserts that the two numerals are within delta of each other. // -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -693,9 +777,9 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo // IsDecreasing asserts that the collection is decreasing // -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) +// a.IsDecreasing([]int{2, 1, 0}) +// a.IsDecreasing([]float{2, 1}) +// a.IsDecreasing([]string{"b", "a"}) func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -705,9 +789,9 @@ func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) // IsDecreasingf asserts that the collection is decreasing // -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") +// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -717,9 +801,9 @@ func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...inter // IsIncreasing asserts that the collection is increasing // -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) +// a.IsIncreasing([]int{1, 2, 3}) +// a.IsIncreasing([]float{1, 2}) +// a.IsIncreasing([]string{"a", "b"}) func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -729,9 +813,9 @@ func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) // IsIncreasingf asserts that the collection is increasing // -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") +// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -741,9 +825,9 @@ func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...inter // IsNonDecreasing asserts that the collection is not decreasing // -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) +// a.IsNonDecreasing([]int{1, 1, 2}) +// a.IsNonDecreasing([]float{1, 2}) +// a.IsNonDecreasing([]string{"a", "b"}) func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -753,9 +837,9 @@ func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -765,9 +849,9 @@ func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...in // IsNonIncreasing asserts that the collection is not increasing // -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) +// a.IsNonIncreasing([]int{2, 1, 1}) +// a.IsNonIncreasing([]float{2, 1}) +// a.IsNonIncreasing([]string{"b", "a"}) func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -777,9 +861,9 @@ func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface // IsNonIncreasingf asserts that the collection is not increasing // -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -805,7 +889,7 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s // JSONEq asserts that two JSON strings are equivalent. // -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -815,7 +899,7 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf // JSONEqf asserts that two JSON strings are equivalent. // -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -826,7 +910,7 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// a.Len(mySlice, 3) +// a.Len(mySlice, 3) func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -837,7 +921,7 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// a.Lenf(mySlice, 3, "error message %s", "formatted") +// a.Lenf(mySlice, 3, "error message %s", "formatted") func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -847,9 +931,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in // Less asserts that the first element is less than the second // -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") +// a.Less(1, 2) +// a.Less(float64(1), float64(2)) +// a.Less("a", "b") func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -859,10 +943,10 @@ func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interfac // LessOrEqual asserts that the first element is less than or equal to the second // -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") +// a.LessOrEqual(1, 2) +// a.LessOrEqual(2, 2) +// a.LessOrEqual("a", "b") +// a.LessOrEqual("b", "b") func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -872,10 +956,10 @@ func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...i // LessOrEqualf asserts that the first element is less than or equal to the second // -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") +// a.LessOrEqualf(1, 2, "error message %s", "formatted") +// a.LessOrEqualf(2, 2, "error message %s", "formatted") +// a.LessOrEqualf("a", "b", "error message %s", "formatted") +// a.LessOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -885,9 +969,9 @@ func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, ar // Lessf asserts that the first element is less than the second // -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") +// a.Lessf(1, 2, "error message %s", "formatted") +// a.Lessf(float64(1), float64(2), "error message %s", "formatted") +// a.Lessf("a", "b", "error message %s", "formatted") func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -897,8 +981,8 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i // Negative asserts that the specified element is negative // -// a.Negative(-1) -// a.Negative(-1.23) +// a.Negative(-1) +// a.Negative(-1.23) func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -908,8 +992,8 @@ func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool { // Negativef asserts that the specified element is negative // -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") +// a.Negativef(-1, "error message %s", "formatted") +// a.Negativef(-1.23, "error message %s", "formatted") func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -920,7 +1004,7 @@ func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) b // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) +// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -931,7 +1015,7 @@ func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick ti // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -941,7 +1025,7 @@ func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick t // Nil asserts that the specified object is nil. // -// a.Nil(err) +// a.Nil(err) func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -951,7 +1035,7 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { // Nilf asserts that the specified object is nil. // -// a.Nilf(err, "error message %s", "formatted") +// a.Nilf(err, "error message %s", "formatted") func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -979,10 +1063,10 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -992,10 +1076,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1024,9 +1108,9 @@ func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1037,9 +1121,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1050,9 +1134,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1063,9 +1147,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1075,7 +1159,7 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface // NotEqual asserts that the specified values are NOT equal. // -// a.NotEqual(obj1, obj2) +// a.NotEqual(obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1088,7 +1172,7 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValues(obj1, obj2) +// a.NotEqualValues(obj1, obj2) func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1098,7 +1182,7 @@ func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, ms // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1108,7 +1192,7 @@ func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, m // NotEqualf asserts that the specified values are NOT equal. // -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1139,7 +1223,7 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in // NotNil asserts that the specified object is not nil. // -// a.NotNil(err) +// a.NotNil(err) func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1149,7 +1233,7 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool // NotNilf asserts that the specified object is not nil. // -// a.NotNilf(err, "error message %s", "formatted") +// a.NotNilf(err, "error message %s", "formatted") func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1159,7 +1243,7 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{} // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanics(func(){ RemainCalm() }) +// a.NotPanics(func(){ RemainCalm() }) func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1169,7 +1253,7 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1179,8 +1263,8 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{} // NotRegexp asserts that a specified regexp does not match a string. // -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1190,8 +1274,8 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in // NotRegexpf asserts that a specified regexp does not match a string. // -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1201,7 +1285,7 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg // NotSame asserts that two pointers do not reference the same object. // -// a.NotSame(ptr1, ptr2) +// a.NotSame(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1214,7 +1298,7 @@ func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArg // NotSamef asserts that two pointers do not reference the same object. // -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") +// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1228,7 +1312,7 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1239,7 +1323,7 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1265,7 +1349,7 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo // Panics asserts that the code inside the specified PanicTestFunc panics. // -// a.Panics(func(){ GoCrazy() }) +// a.Panics(func(){ GoCrazy() }) func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1277,7 +1361,7 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) +// a.PanicsWithError("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1289,7 +1373,7 @@ func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndAr // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1300,7 +1384,7 @@ func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg str // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1311,7 +1395,7 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1321,7 +1405,7 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1331,8 +1415,8 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b // Positive asserts that the specified element is positive // -// a.Positive(1) -// a.Positive(1.23) +// a.Positive(1) +// a.Positive(1.23) func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1342,8 +1426,8 @@ func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool { // Positivef asserts that the specified element is positive // -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") +// a.Positivef(1, "error message %s", "formatted") +// a.Positivef(1.23, "error message %s", "formatted") func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1353,8 +1437,8 @@ func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) b // Regexp asserts that a specified regexp matches a string. // -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1364,8 +1448,8 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter // Regexpf asserts that a specified regexp matches a string. // -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1375,7 +1459,7 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args . // Same asserts that two pointers reference the same object. // -// a.Same(ptr1, ptr2) +// a.Same(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1388,7 +1472,7 @@ func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs . // Samef asserts that two pointers reference the same object. // -// a.Samef(ptr1, ptr2, "error message %s", "formatted") +// a.Samef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1402,7 +1486,7 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1413,7 +1497,7 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ... // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1423,7 +1507,7 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a // True asserts that the specified value is true. // -// a.True(myBool) +// a.True(myBool) func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1433,7 +1517,7 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { // Truef asserts that the specified value is true. // -// a.Truef(myBool, "error message %s", "formatted") +// a.Truef(myBool, "error message %s", "formatted") func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1443,7 +1527,7 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { // WithinDuration asserts that the two times are within duration delta of each other. // -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1453,7 +1537,7 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta // WithinDurationf asserts that the two times are within duration delta of each other. // -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1463,7 +1547,7 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta // WithinRange asserts that a time is within a time range (inclusive). // -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1473,7 +1557,7 @@ func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Tim // WithinRangef asserts that a time is within a time range (inclusive). // -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go index 75944878358..00df62a0599 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -46,36 +46,36 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// assert.IsIncreasing(t, []int{1, 2, 3}) +// assert.IsIncreasing(t, []float{1, 2}) +// assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// assert.IsNonIncreasing(t, []int{2, 1, 1}) +// assert.IsNonIncreasing(t, []float{2, 1}) +// assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// assert.IsDecreasing(t, []int{2, 1, 0}) +// assert.IsDecreasing(t, []float{2, 1}) +// assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// assert.IsNonDecreasing(t, []int{1, 1, 2}) +// assert.IsNonDecreasing(t, []float{1, 2}) +// assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index fa1245b1897..a55d1bba926 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -8,7 +8,6 @@ import ( "fmt" "math" "os" - "path/filepath" "reflect" "regexp" "runtime" @@ -76,6 +75,77 @@ func ObjectsAreEqual(expected, actual interface{}) bool { return bytes.Equal(exp, act) } +// copyExportedFields iterates downward through nested data structures and creates a copy +// that only contains the exported struct fields. +func copyExportedFields(expected interface{}) interface{} { + if isNil(expected) { + return expected + } + + expectedType := reflect.TypeOf(expected) + expectedKind := expectedType.Kind() + expectedValue := reflect.ValueOf(expected) + + switch expectedKind { + case reflect.Struct: + result := reflect.New(expectedType).Elem() + for i := 0; i < expectedType.NumField(); i++ { + field := expectedType.Field(i) + isExported := field.IsExported() + if isExported { + fieldValue := expectedValue.Field(i) + if isNil(fieldValue) || isNil(fieldValue.Interface()) { + continue + } + newValue := copyExportedFields(fieldValue.Interface()) + result.Field(i).Set(reflect.ValueOf(newValue)) + } + } + return result.Interface() + + case reflect.Ptr: + result := reflect.New(expectedType.Elem()) + unexportedRemoved := copyExportedFields(expectedValue.Elem().Interface()) + result.Elem().Set(reflect.ValueOf(unexportedRemoved)) + return result.Interface() + + case reflect.Array, reflect.Slice: + result := reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len()) + for i := 0; i < expectedValue.Len(); i++ { + index := expectedValue.Index(i) + if isNil(index) { + continue + } + unexportedRemoved := copyExportedFields(index.Interface()) + result.Index(i).Set(reflect.ValueOf(unexportedRemoved)) + } + return result.Interface() + + case reflect.Map: + result := reflect.MakeMap(expectedType) + for _, k := range expectedValue.MapKeys() { + index := expectedValue.MapIndex(k) + unexportedRemoved := copyExportedFields(index.Interface()) + result.SetMapIndex(k, reflect.ValueOf(unexportedRemoved)) + } + return result.Interface() + + default: + return expected + } +} + +// ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are +// considered equal. This comparison of only exported fields is applied recursively to nested data +// structures. +// +// This function does no assertion of any kind. +func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool { + expectedCleaned := copyExportedFields(expected) + actualCleaned := copyExportedFields(actual) + return ObjectsAreEqualValues(expectedCleaned, actualCleaned) +} + // ObjectsAreEqualValues gets whether two objects are equal, or if their // values are equal. func ObjectsAreEqualValues(expected, actual interface{}) bool { @@ -141,12 +211,11 @@ func CallerInfo() []string { } parts := strings.Split(file, "/") - file = parts[len(parts)-1] if len(parts) > 1 { + filename := parts[len(parts)-1] dir := parts[len(parts)-2] - if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { - path, _ := filepath.Abs(file) - callers = append(callers, fmt.Sprintf("%s:%d", path, line)) + if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) } } @@ -273,7 +342,7 @@ type labeledContent struct { // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: // -// \t{{label}}:{{align_spaces}}\t{{content}}\n +// \t{{label}}:{{align_spaces}}\t{{content}}\n // // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this @@ -296,7 +365,7 @@ func labeledOutput(content ...labeledContent) string { // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -328,7 +397,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// assert.Equal(t, 123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -369,7 +438,7 @@ func validateEqualArgs(expected, actual interface{}) error { // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// assert.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -389,7 +458,7 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// assert.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -457,7 +526,7 @@ func truncatingFormat(data interface{}) string { // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -475,9 +544,53 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) + } + + if aType.Kind() != reflect.Struct { + return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) + } + + if bType.Kind() != reflect.Struct { + return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) + } + + expected = copyExportedFields(expected) + actual = copyExportedFields(actual) + + if !ObjectsAreEqualValues(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal (comparing only exported fields): \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true +} + // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// assert.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -496,7 +609,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// assert.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if !isNil(object) { return true @@ -530,7 +643,7 @@ func isNil(object interface{}) bool { []reflect.Kind{ reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, - reflect.Ptr, reflect.Slice}, + reflect.Ptr, reflect.Slice, reflect.UnsafePointer}, kind) if isNilableKind && value.IsNil() { @@ -542,7 +655,7 @@ func isNil(object interface{}) bool { // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// assert.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if isNil(object) { return true @@ -585,7 +698,7 @@ func isEmpty(object interface{}) bool { // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// assert.Empty(t, obj) func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := isEmpty(object) if !pass { @@ -602,9 +715,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := !isEmpty(object) if !pass { @@ -633,7 +746,7 @@ func getLen(x interface{}) (ok bool, length int) { // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// assert.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -651,7 +764,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // True asserts that the specified value is true. // -// assert.True(t, myBool) +// assert.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { if !value { if h, ok := t.(tHelper); ok { @@ -666,7 +779,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// assert.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { if value { if h, ok := t.(tHelper); ok { @@ -681,7 +794,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// assert.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -704,7 +817,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// assert.NotEqualValues(t, obj1, obj2) func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -763,9 +876,9 @@ func containsElement(list interface{}, element interface{}) (ok, found bool) { // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -786,9 +899,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -796,10 +909,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) } return true @@ -809,7 +922,7 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { if h, ok := t.(tHelper); ok { h.Helper() @@ -818,49 +931,44 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return true // we consider nil to be equal to the nil set } - defer func() { - if e := recover(); e != nil { - ok = false - } - }() - listKind := reflect.TypeOf(list).Kind() - subsetKind := reflect.TypeOf(subset).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) } + subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) } - subsetValue := reflect.ValueOf(subset) if subsetKind == reflect.Map && listKind == reflect.Map { - listValue := reflect.ValueOf(list) - subsetKeys := subsetValue.MapKeys() + subsetMap := reflect.ValueOf(subset) + actualMap := reflect.ValueOf(list) - for i := 0; i < len(subsetKeys); i++ { - subsetKey := subsetKeys[i] - subsetElement := subsetValue.MapIndex(subsetKey).Interface() - listElement := listValue.MapIndex(subsetKey).Interface() + for _, k := range subsetMap.MapKeys() { + ev := subsetMap.MapIndex(k) + av := actualMap.MapIndex(k) - if !ObjectsAreEqual(subsetElement, listElement) { - return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, subsetElement), msgAndArgs...) + if !av.IsValid() { + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + } + if !ObjectsAreEqual(ev.Interface(), av.Interface()) { + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) } } return true } - for i := 0; i < subsetValue.Len(); i++ { - element := subsetValue.Index(i).Interface() + subsetList := reflect.ValueOf(subset) + for i := 0; i < subsetList.Len(); i++ { + element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) } } @@ -870,7 +978,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { if h, ok := t.(tHelper); ok { h.Helper() @@ -879,34 +987,28 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...) } - defer func() { - if e := recover(); e != nil { - ok = false - } - }() - listKind := reflect.TypeOf(list).Kind() - subsetKind := reflect.TypeOf(subset).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) } + subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) } - subsetValue := reflect.ValueOf(subset) if subsetKind == reflect.Map && listKind == reflect.Map { - listValue := reflect.ValueOf(list) - subsetKeys := subsetValue.MapKeys() + subsetMap := reflect.ValueOf(subset) + actualMap := reflect.ValueOf(list) - for i := 0; i < len(subsetKeys); i++ { - subsetKey := subsetKeys[i] - subsetElement := subsetValue.MapIndex(subsetKey).Interface() - listElement := listValue.MapIndex(subsetKey).Interface() + for _, k := range subsetMap.MapKeys() { + ev := subsetMap.MapIndex(k) + av := actualMap.MapIndex(k) - if !ObjectsAreEqual(subsetElement, listElement) { + if !av.IsValid() { + return true + } + if !ObjectsAreEqual(ev.Interface(), av.Interface()) { return true } } @@ -914,8 +1016,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) } - for i := 0; i < subsetValue.Len(); i++ { - element := subsetValue.Index(i).Interface() + subsetList := reflect.ValueOf(subset) + for i := 0; i < subsetList.Len(); i++ { + element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) @@ -1060,7 +1163,7 @@ func didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// assert.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1076,7 +1179,7 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1097,7 +1200,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1117,7 +1220,7 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// assert.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1132,7 +1235,7 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1148,7 +1251,7 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1207,7 +1310,7 @@ func toFloat(x interface{}) (float64, bool) { // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// assert.InDelta(t, math.Pi, 22/7.0, 0.01) func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1380,10 +1483,10 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if err != nil { if h, ok := t.(tHelper); ok { @@ -1397,10 +1500,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { if err == nil { if h, ok := t.(tHelper); ok { @@ -1415,8 +1518,8 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1438,8 +1541,8 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// assert.ErrorContains(t, err, expectedErrorSubString) func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1472,8 +1575,8 @@ func matchRegexp(rx interface{}, str interface{}) bool { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1490,8 +1593,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1603,7 +1706,7 @@ func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1726,7 +1829,7 @@ type tHelper interface { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1756,10 +1859,93 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t } } +// CollectT implements the TestingT interface and collects all errors. +type CollectT struct { + errors []error +} + +// Errorf collects the error. +func (c *CollectT) Errorf(format string, args ...interface{}) { + c.errors = append(c.errors, fmt.Errorf(format, args...)) +} + +// FailNow panics. +func (c *CollectT) FailNow() { + panic("Assertion failed") +} + +// Reset clears the collected errors. +func (c *CollectT) Reset() { + c.errors = nil +} + +// Copy copies the collected errors to the supplied t. +func (c *CollectT) Copy(t TestingT) { + if tt, ok := t.(tHelper); ok { + tt.Helper() + } + for _, err := range c.errors { + t.Errorf("%v", err) + } +} + +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + collect := new(CollectT) + ch := make(chan bool, 1) + + timer := time.NewTimer(waitFor) + defer timer.Stop() + + ticker := time.NewTicker(tick) + defer ticker.Stop() + + for tick := ticker.C; ; { + select { + case <-timer.C: + collect.Copy(t) + return Fail(t, "Condition never satisfied", msgAndArgs...) + case <-tick: + tick = nil + collect.Reset() + go func() { + condition(collect) + ch <- len(collect.errors) == 0 + }() + case v := <-ch: + if v { + return true + } + tick = ticker.C + } + } +} + // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go index c9dccc4d6cd..4953981d387 100644 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -1,39 +1,40 @@ // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. // -// Example Usage +// # Example Usage // // The following is a complete example using assert in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) // -// func TestSomething(t *testing.T) { +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) // -// var a string = "Hello" -// var b string = "Hello" +// func TestSomething(t *testing.T) { // -// assert.Equal(t, a, b, "The two words should be the same.") +// var a string = "Hello" +// var b string = "Hello" // -// } +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } // // if you assert many times, use the format below: // -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) // -// func TestSomething(t *testing.T) { -// assert := assert.New(t) +// func TestSomething(t *testing.T) { +// assert := assert.New(t) // -// var a string = "Hello" -// var b string = "Hello" +// var a string = "Hello" +// var b string = "Hello" // -// assert.Equal(a, b, "The two words should be the same.") -// } +// assert.Equal(a, b, "The two words should be the same.") +// } // -// Assertions +// # Assertions // // Assertions allow you to easily write test code, and are global funcs in the `assert` package. // All assertion functions take, as the first argument, the `*testing.T` object provided by the diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go index 4ed341dd289..d8038c28a75 100644 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -23,7 +23,7 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) ( // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -45,7 +45,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -67,7 +67,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -89,7 +89,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { @@ -124,7 +124,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -144,7 +144,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { diff --git a/vendor/github.com/stretchr/testify/require/doc.go b/vendor/github.com/stretchr/testify/require/doc.go index 169de39221c..96843472455 100644 --- a/vendor/github.com/stretchr/testify/require/doc.go +++ b/vendor/github.com/stretchr/testify/require/doc.go @@ -1,24 +1,25 @@ // Package require implements the same assertions as the `assert` package but // stops test execution when a test fails. // -// Example Usage +// # Example Usage // // The following is a complete example using require in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/require" -// ) // -// func TestSomething(t *testing.T) { +// import ( +// "testing" +// "github.com/stretchr/testify/require" +// ) // -// var a string = "Hello" -// var b string = "Hello" +// func TestSomething(t *testing.T) { // -// require.Equal(t, a, b, "The two words should be the same.") +// var a string = "Hello" +// var b string = "Hello" // -// } +// require.Equal(t, a, b, "The two words should be the same.") // -// Assertions +// } +// +// # Assertions // // The `require` package have same global functions as in the `assert` package, // but instead of returning a boolean result they call `t.FailNow()`. diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go index 880853f5a2c..63f85214767 100644 --- a/vendor/github.com/stretchr/testify/require/require.go +++ b/vendor/github.com/stretchr/testify/require/require.go @@ -37,9 +37,9 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -53,9 +53,9 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -123,7 +123,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// assert.Empty(t, obj) func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -137,7 +137,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// assert.Emptyf(t, obj, "error message %s", "formatted") func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -150,7 +150,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// assert.Equal(t, 123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -168,8 +168,8 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -183,8 +183,8 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -195,10 +195,50 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args t.FailNow() } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EqualExportedValues(t, expected, actual, msgAndArgs...) { + return + } + t.FailNow() +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EqualExportedValuesf(t, expected, actual, msg, args...) { + return + } + t.FailNow() +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -212,7 +252,7 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -225,7 +265,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// assert.Equalf(t, 123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -242,10 +282,10 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -283,8 +323,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// assert.ErrorContains(t, err, expectedErrorSubString) func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -298,8 +338,8 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -336,10 +376,10 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -353,7 +393,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -364,10 +404,66 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t t.FailNow() } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EventuallyWithT(t, condition, waitFor, tick, msgAndArgs...) { + return + } + t.FailNow() +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EventuallyWithTf(t, condition, waitFor, tick, msg, args...) { + return + } + t.FailNow() +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -380,7 +476,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// assert.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -393,7 +489,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -450,7 +546,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// assert.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -463,7 +559,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// assert.Falsef(t, myBool, "error message %s", "formatted") func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -500,9 +596,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// assert.Greater(t, 2, 1) +// assert.Greater(t, float64(2), float64(1)) +// assert.Greater(t, "b", "a") func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -515,10 +611,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// assert.GreaterOrEqual(t, 2, 1) +// assert.GreaterOrEqual(t, 2, 2) +// assert.GreaterOrEqual(t, "b", "a") +// assert.GreaterOrEqual(t, "b", "b") func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -531,10 +627,10 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -547,9 +643,9 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// assert.Greaterf(t, "b", "a", "error message %s", "formatted") func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -563,7 +659,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -579,7 +675,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -595,7 +691,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -611,7 +707,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -626,7 +722,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -641,7 +737,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPErrorf asserts that a specified handler returns an error status code. // -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -656,7 +752,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -671,7 +767,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -686,7 +782,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { @@ -701,7 +797,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { @@ -716,7 +812,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -731,7 +827,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // HTTPSuccessf asserts that a specified handler returns a success status code. // -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -746,7 +842,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -759,7 +855,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -772,7 +868,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// assert.InDelta(t, math.Pi, 22/7.0, 0.01) func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -829,7 +925,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -886,9 +982,9 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// assert.IsDecreasing(t, []int{2, 1, 0}) +// assert.IsDecreasing(t, []float{2, 1}) +// assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -901,9 +997,9 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -916,9 +1012,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// assert.IsIncreasing(t, []int{1, 2, 3}) +// assert.IsIncreasing(t, []float{1, 2}) +// assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -931,9 +1027,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -946,9 +1042,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// assert.IsNonDecreasing(t, []int{1, 1, 2}) +// assert.IsNonDecreasing(t, []float{1, 2}) +// assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -961,9 +1057,9 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -976,9 +1072,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// assert.IsNonIncreasing(t, []int{2, 1, 1}) +// assert.IsNonIncreasing(t, []float{2, 1}) +// assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -991,9 +1087,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1028,7 +1124,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1041,7 +1137,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1055,7 +1151,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// assert.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1069,7 +1165,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1082,9 +1178,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// assert.Less(t, 1, 2) +// assert.Less(t, float64(1), float64(2)) +// assert.Less(t, "a", "b") func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1097,10 +1193,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// assert.LessOrEqual(t, 1, 2) +// assert.LessOrEqual(t, 2, 2) +// assert.LessOrEqual(t, "a", "b") +// assert.LessOrEqual(t, "b", "b") func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1113,10 +1209,10 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1129,9 +1225,9 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// assert.Lessf(t, 1, 2, "error message %s", "formatted") +// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// assert.Lessf(t, "a", "b", "error message %s", "formatted") func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1144,8 +1240,8 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// assert.Negative(t, -1) +// assert.Negative(t, -1.23) func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1158,8 +1254,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// assert.Negativef(t, -1, "error message %s", "formatted") +// assert.Negativef(t, -1.23, "error message %s", "formatted") func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1173,7 +1269,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1187,7 +1283,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1200,7 +1296,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// assert.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1213,7 +1309,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// assert.Nilf(t, err, "error message %s", "formatted") func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1250,10 +1346,10 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1266,10 +1362,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1307,9 +1403,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1323,9 +1419,9 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1339,9 +1435,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1355,9 +1451,9 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1370,7 +1466,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// assert.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1386,7 +1482,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// assert.NotEqualValues(t, obj1, obj2) func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1399,7 +1495,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1412,7 +1508,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1452,7 +1548,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// assert.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1465,7 +1561,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// assert.NotNilf(t, err, "error message %s", "formatted") func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1478,7 +1574,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// assert.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1491,7 +1587,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1504,8 +1600,8 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1518,8 +1614,8 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1532,7 +1628,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// assert.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1548,7 +1644,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1565,7 +1661,7 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1579,7 +1675,7 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1614,7 +1710,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// assert.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1629,7 +1725,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1644,7 +1740,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1658,7 +1754,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1672,7 +1768,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1685,7 +1781,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1698,8 +1794,8 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// assert.Positive(t, 1) +// assert.Positive(t, 1.23) func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1712,8 +1808,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// assert.Positivef(t, 1, "error message %s", "formatted") +// assert.Positivef(t, 1.23, "error message %s", "formatted") func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1726,8 +1822,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1740,8 +1836,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1754,7 +1850,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// assert.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1770,7 +1866,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1787,7 +1883,7 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1801,7 +1897,7 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1814,7 +1910,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // True asserts that the specified value is true. // -// assert.True(t, myBool) +// assert.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1827,7 +1923,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// assert.Truef(t, myBool, "error message %s", "formatted") func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1840,7 +1936,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1853,7 +1949,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1866,7 +1962,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1879,7 +1975,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go index 960bf6f2cab..3b5b09330a4 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go +++ b/vendor/github.com/stretchr/testify/require/require_forward.go @@ -31,9 +31,9 @@ func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...inte // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -44,9 +44,9 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs .. // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -99,7 +99,7 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Empty(obj) +// a.Empty(obj) func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -110,7 +110,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Emptyf(obj, "error message %s", "formatted") +// a.Emptyf(obj, "error message %s", "formatted") func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -120,7 +120,7 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Equal asserts that two objects are equal. // -// a.Equal(123, 123) +// a.Equal(123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -135,8 +135,8 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -147,8 +147,8 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -156,10 +156,44 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a EqualErrorf(a.t, theError, errString, msg, args...) } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true +// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false +func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EqualExportedValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EqualExportedValuesf(a.t, expected, actual, msg, args...) +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValues(uint32(123), int32(123)) +// a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -170,7 +204,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") +// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -180,7 +214,7 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Equalf asserts that two objects are equal. // -// a.Equalf(123, 123, "error message %s", "formatted") +// a.Equalf(123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -194,10 +228,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } func (a *Assertions) Error(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -226,8 +260,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// a.ErrorContains(err, expectedErrorSubString) func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -238,8 +272,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -267,10 +301,10 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func (a *Assertions) Errorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -281,7 +315,7 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) +// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -289,10 +323,60 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti Eventually(a.t, condition, waitFor, tick, msgAndArgs...) } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithT(func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -302,7 +386,7 @@ func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, t // Exactly asserts that two objects are equal in value and type. // -// a.Exactly(int32(123), int64(123)) +// a.Exactly(int32(123), int64(123)) func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -312,7 +396,7 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg // Exactlyf asserts that two objects are equal in value and type. // -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") +// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -354,7 +438,7 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{ // False asserts that the specified value is false. // -// a.False(myBool) +// a.False(myBool) func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -364,7 +448,7 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// a.Falsef(myBool, "error message %s", "formatted") +// a.Falsef(myBool, "error message %s", "formatted") func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -392,9 +476,9 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") +// a.Greater(2, 1) +// a.Greater(float64(2), float64(1)) +// a.Greater("b", "a") func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -404,10 +488,10 @@ func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...inter // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") +// a.GreaterOrEqual(2, 1) +// a.GreaterOrEqual(2, 2) +// a.GreaterOrEqual("b", "a") +// a.GreaterOrEqual("b", "b") func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -417,10 +501,10 @@ func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs . // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") +// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") +// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") +// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") +// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -430,9 +514,9 @@ func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, // Greaterf asserts that the first element is greater than the second // -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") +// a.Greaterf(2, 1, "error message %s", "formatted") +// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") +// a.Greaterf("b", "a", "error message %s", "formatted") func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -443,7 +527,7 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -456,7 +540,7 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -469,7 +553,7 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -482,7 +566,7 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -494,7 +578,7 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -506,7 +590,7 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -518,7 +602,7 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -530,7 +614,7 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -542,7 +626,7 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) +// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { @@ -554,7 +638,7 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { @@ -566,7 +650,7 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -578,7 +662,7 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -590,7 +674,7 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s // Implements asserts that an object is implemented by the specified interface. // -// a.Implements((*MyInterface)(nil), new(MyObject)) +// a.Implements((*MyInterface)(nil), new(MyObject)) func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -600,7 +684,7 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, // Implementsf asserts that an object is implemented by the specified interface. // -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -610,7 +694,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{} // InDelta asserts that the two numerals are within delta of each other. // -// a.InDelta(math.Pi, 22/7.0, 0.01) +// a.InDelta(math.Pi, 22/7.0, 0.01) func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -652,7 +736,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del // InDeltaf asserts that the two numerals are within delta of each other. // -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -694,9 +778,9 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo // IsDecreasing asserts that the collection is decreasing // -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) +// a.IsDecreasing([]int{2, 1, 0}) +// a.IsDecreasing([]float{2, 1}) +// a.IsDecreasing([]string{"b", "a"}) func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -706,9 +790,9 @@ func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) // IsDecreasingf asserts that the collection is decreasing // -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") +// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -718,9 +802,9 @@ func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...inter // IsIncreasing asserts that the collection is increasing // -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) +// a.IsIncreasing([]int{1, 2, 3}) +// a.IsIncreasing([]float{1, 2}) +// a.IsIncreasing([]string{"a", "b"}) func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -730,9 +814,9 @@ func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) // IsIncreasingf asserts that the collection is increasing // -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") +// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -742,9 +826,9 @@ func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...inter // IsNonDecreasing asserts that the collection is not decreasing // -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) +// a.IsNonDecreasing([]int{1, 1, 2}) +// a.IsNonDecreasing([]float{1, 2}) +// a.IsNonDecreasing([]string{"a", "b"}) func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -754,9 +838,9 @@ func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -766,9 +850,9 @@ func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...in // IsNonIncreasing asserts that the collection is not increasing // -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) +// a.IsNonIncreasing([]int{2, 1, 1}) +// a.IsNonIncreasing([]float{2, 1}) +// a.IsNonIncreasing([]string{"b", "a"}) func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -778,9 +862,9 @@ func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface // IsNonIncreasingf asserts that the collection is not increasing // -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -806,7 +890,7 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s // JSONEq asserts that two JSON strings are equivalent. // -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -816,7 +900,7 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf // JSONEqf asserts that two JSON strings are equivalent. // -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -827,7 +911,7 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// a.Len(mySlice, 3) +// a.Len(mySlice, 3) func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -838,7 +922,7 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// a.Lenf(mySlice, 3, "error message %s", "formatted") +// a.Lenf(mySlice, 3, "error message %s", "formatted") func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -848,9 +932,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in // Less asserts that the first element is less than the second // -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") +// a.Less(1, 2) +// a.Less(float64(1), float64(2)) +// a.Less("a", "b") func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -860,10 +944,10 @@ func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interfac // LessOrEqual asserts that the first element is less than or equal to the second // -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") +// a.LessOrEqual(1, 2) +// a.LessOrEqual(2, 2) +// a.LessOrEqual("a", "b") +// a.LessOrEqual("b", "b") func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -873,10 +957,10 @@ func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...i // LessOrEqualf asserts that the first element is less than or equal to the second // -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") +// a.LessOrEqualf(1, 2, "error message %s", "formatted") +// a.LessOrEqualf(2, 2, "error message %s", "formatted") +// a.LessOrEqualf("a", "b", "error message %s", "formatted") +// a.LessOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -886,9 +970,9 @@ func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, ar // Lessf asserts that the first element is less than the second // -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") +// a.Lessf(1, 2, "error message %s", "formatted") +// a.Lessf(float64(1), float64(2), "error message %s", "formatted") +// a.Lessf("a", "b", "error message %s", "formatted") func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -898,8 +982,8 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i // Negative asserts that the specified element is negative // -// a.Negative(-1) -// a.Negative(-1.23) +// a.Negative(-1) +// a.Negative(-1.23) func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -909,8 +993,8 @@ func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") +// a.Negativef(-1, "error message %s", "formatted") +// a.Negativef(-1.23, "error message %s", "formatted") func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -921,7 +1005,7 @@ func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) +// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -932,7 +1016,7 @@ func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick ti // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -942,7 +1026,7 @@ func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick t // Nil asserts that the specified object is nil. // -// a.Nil(err) +// a.Nil(err) func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -952,7 +1036,7 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// a.Nilf(err, "error message %s", "formatted") +// a.Nilf(err, "error message %s", "formatted") func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -980,10 +1064,10 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -993,10 +1077,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1025,9 +1109,9 @@ func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1038,9 +1122,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1051,9 +1135,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1064,9 +1148,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1076,7 +1160,7 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface // NotEqual asserts that the specified values are NOT equal. // -// a.NotEqual(obj1, obj2) +// a.NotEqual(obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1089,7 +1173,7 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValues(obj1, obj2) +// a.NotEqualValues(obj1, obj2) func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1099,7 +1183,7 @@ func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, ms // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1109,7 +1193,7 @@ func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, m // NotEqualf asserts that the specified values are NOT equal. // -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1140,7 +1224,7 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in // NotNil asserts that the specified object is not nil. // -// a.NotNil(err) +// a.NotNil(err) func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1150,7 +1234,7 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// a.NotNilf(err, "error message %s", "formatted") +// a.NotNilf(err, "error message %s", "formatted") func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1160,7 +1244,7 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{} // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanics(func(){ RemainCalm() }) +// a.NotPanics(func(){ RemainCalm() }) func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1170,7 +1254,7 @@ func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{} // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1180,8 +1264,8 @@ func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...inte // NotRegexp asserts that a specified regexp does not match a string. // -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1191,8 +1275,8 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in // NotRegexpf asserts that a specified regexp does not match a string. // -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1202,7 +1286,7 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg // NotSame asserts that two pointers do not reference the same object. // -// a.NotSame(ptr1, ptr2) +// a.NotSame(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1215,7 +1299,7 @@ func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArg // NotSamef asserts that two pointers do not reference the same object. // -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") +// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1229,7 +1313,7 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1240,7 +1324,7 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1266,7 +1350,7 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// a.Panics(func(){ GoCrazy() }) +// a.Panics(func(){ GoCrazy() }) func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1278,7 +1362,7 @@ func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) +// a.PanicsWithError("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1290,7 +1374,7 @@ func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, m // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1301,7 +1385,7 @@ func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1312,7 +1396,7 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFun // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1322,7 +1406,7 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFu // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1332,8 +1416,8 @@ func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interfa // Positive asserts that the specified element is positive // -// a.Positive(1) -// a.Positive(1.23) +// a.Positive(1) +// a.Positive(1.23) func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1343,8 +1427,8 @@ func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") +// a.Positivef(1, "error message %s", "formatted") +// a.Positivef(1.23, "error message %s", "formatted") func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1354,8 +1438,8 @@ func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1365,8 +1449,8 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter // Regexpf asserts that a specified regexp matches a string. // -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1376,7 +1460,7 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args . // Same asserts that two pointers reference the same object. // -// a.Same(ptr1, ptr2) +// a.Same(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1389,7 +1473,7 @@ func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs . // Samef asserts that two pointers reference the same object. // -// a.Samef(ptr1, ptr2, "error message %s", "formatted") +// a.Samef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1403,7 +1487,7 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1414,7 +1498,7 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ... // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1424,7 +1508,7 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a // True asserts that the specified value is true. // -// a.True(myBool) +// a.True(myBool) func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1434,7 +1518,7 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// a.Truef(myBool, "error message %s", "formatted") +// a.Truef(myBool, "error message %s", "formatted") func (a *Assertions) Truef(value bool, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1444,7 +1528,7 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1454,7 +1538,7 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta // WithinDurationf asserts that the two times are within duration delta of each other. // -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1464,7 +1548,7 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta // WithinRange asserts that a time is within a time range (inclusive). // -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1474,7 +1558,7 @@ func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Tim // WithinRangef asserts that a time is within a time range (inclusive). // -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/yashtewari/glob-intersection/glob.go b/vendor/github.com/yashtewari/glob-intersection/glob.go index 54d4729be03..98dfa476846 100644 --- a/vendor/github.com/yashtewari/glob-intersection/glob.go +++ b/vendor/github.com/yashtewari/glob-intersection/glob.go @@ -119,11 +119,7 @@ func NewDot() Token { } func (d dot) Equal(other Token) bool { - if d.Type() != other.Type() { - return false - } - - return true + return d.Type() == other.Type() } func (d dot) String() string { diff --git a/vendor/github.com/yashtewari/glob-intersection/non_empty.go b/vendor/github.com/yashtewari/glob-intersection/non_empty.go index 91cbdbde5bf..30f819b1f33 100644 --- a/vendor/github.com/yashtewari/glob-intersection/non_empty.go +++ b/vendor/github.com/yashtewari/glob-intersection/non_empty.go @@ -102,12 +102,17 @@ func intersectSpecial(g1, g2 Glob) bool { // intersectPlus accepts two globs such that plussed[0].Flag() == FlagPlus. // It returns a boolean describing whether their intersection exists. -// It ensures that at least one token in other maches plussed[0], before handing flow of control to intersectSpecial. +// It ensures that at least one token in other maches plussed[0]. func intersectPlus(plussed, other Glob) bool { if !Match(plussed[0], other[0]) { return false } - return intersectStar(plussed, other[1:]) + // Either the plussed has gobbled up other[0]... + if intersectStar(plussed, other[1:]) { + return true + } + // ...or if other[0] has a flag, it may completely gobble up plussed[0]. + return other[0].Flag() != FlagNone && intersectNormal(plussed[1:], other) } // intersectStar accepts two globs such that starred[0].Flag() == FlagStar. @@ -145,10 +150,6 @@ func intersectStar(starred, other Glob) bool { } // If there was no token following starToken, and everything from other was gobbled, the Globs intersect. - if nextToken == nil { - return true - } - - // If everything from other was gobbles but there was a nextToken to match, they don't intersect. - return false + //If everything from other was gobbles but there was a nextToken to match, they don't intersect. + return nextToken == nil } diff --git a/vendor/go.opencensus.io/Makefile b/vendor/go.opencensus.io/Makefile index b3ce3df3032..d896edc9968 100644 --- a/vendor/go.opencensus.io/Makefile +++ b/vendor/go.opencensus.io/Makefile @@ -91,7 +91,7 @@ embedmd: .PHONY: install-tools install-tools: - go get -u golang.org/x/lint/golint - go get -u golang.org/x/tools/cmd/cover - go get -u golang.org/x/tools/cmd/goimports - go get -u github.com/rakyll/embedmd + go install golang.org/x/lint/golint@latest + go install golang.org/x/tools/cmd/cover@latest + go install golang.org/x/tools/cmd/goimports@latest + go install github.com/rakyll/embedmd@latest diff --git a/vendor/go.opencensus.io/opencensus.go b/vendor/go.opencensus.io/opencensus.go index e5e4b4368c1..11e31f421c5 100644 --- a/vendor/go.opencensus.io/opencensus.go +++ b/vendor/go.opencensus.io/opencensus.go @@ -17,5 +17,5 @@ package opencensus // import "go.opencensus.io" // Version is the current release version of OpenCensus in use. func Version() string { - return "0.23.0" + return "0.24.0" } diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go b/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go index 49fde3d8c82..fb3c19d6b64 100644 --- a/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go +++ b/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go @@ -28,6 +28,7 @@ var ( ClientReceivedMessagesPerRPC = stats.Int64("grpc.io/client/received_messages_per_rpc", "Number of response messages received per RPC (always 1 for non-streaming RPCs).", stats.UnitDimensionless) ClientReceivedBytesPerRPC = stats.Int64("grpc.io/client/received_bytes_per_rpc", "Total bytes received across all response messages per RPC.", stats.UnitBytes) ClientRoundtripLatency = stats.Float64("grpc.io/client/roundtrip_latency", "Time between first byte of request sent to last byte of response received, or terminal error.", stats.UnitMilliseconds) + ClientStartedRPCs = stats.Int64("grpc.io/client/started_rpcs", "Number of started client RPCs.", stats.UnitDimensionless) ClientServerLatency = stats.Float64("grpc.io/client/server_latency", `Propagated from the server and should have the same value as "grpc.io/server/latency".`, stats.UnitMilliseconds) ) @@ -70,6 +71,14 @@ var ( Aggregation: view.Count(), } + ClientStartedRPCsView = &view.View{ + Measure: ClientStartedRPCs, + Name: "grpc.io/client/started_rpcs", + Description: "Number of started client RPCs.", + TagKeys: []tag.Key{KeyClientMethod}, + Aggregation: view.Count(), + } + ClientSentMessagesPerRPCView = &view.View{ Measure: ClientSentMessagesPerRPC, Name: "grpc.io/client/sent_messages_per_rpc", diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go b/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go index b2059824a85..fe0e971086e 100644 --- a/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go +++ b/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go @@ -27,6 +27,7 @@ var ( ServerReceivedBytesPerRPC = stats.Int64("grpc.io/server/received_bytes_per_rpc", "Total bytes received across all messages per RPC.", stats.UnitBytes) ServerSentMessagesPerRPC = stats.Int64("grpc.io/server/sent_messages_per_rpc", "Number of messages sent in each RPC. Has value 1 for non-streaming RPCs.", stats.UnitDimensionless) ServerSentBytesPerRPC = stats.Int64("grpc.io/server/sent_bytes_per_rpc", "Total bytes sent in across all response messages per RPC.", stats.UnitBytes) + ServerStartedRPCs = stats.Int64("grpc.io/server/started_rpcs", "Number of started server RPCs.", stats.UnitDimensionless) ServerLatency = stats.Float64("grpc.io/server/server_latency", "Time between first byte of request received to last byte of response sent, or terminal error.", stats.UnitMilliseconds) ) @@ -73,6 +74,14 @@ var ( Aggregation: view.Count(), } + ServerStartedRPCsView = &view.View{ + Measure: ServerStartedRPCs, + Name: "grpc.io/server/started_rpcs", + Description: "Number of started server RPCs.", + TagKeys: []tag.Key{KeyServerMethod}, + Aggregation: view.Count(), + } + ServerReceivedMessagesPerRPCView = &view.View{ Name: "grpc.io/server/received_messages_per_rpc", Description: "Distribution of messages received count per RPC, by method.", diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go b/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go index 89cac9c4ec0..9cb27320ca1 100644 --- a/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go +++ b/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go @@ -82,8 +82,10 @@ func methodName(fullname string) string { // statsHandleRPC processes the RPC events. func statsHandleRPC(ctx context.Context, s stats.RPCStats) { switch st := s.(type) { - case *stats.Begin, *stats.OutHeader, *stats.InHeader, *stats.InTrailer, *stats.OutTrailer: + case *stats.OutHeader, *stats.InHeader, *stats.InTrailer, *stats.OutTrailer: // do nothing for client + case *stats.Begin: + handleRPCBegin(ctx, st) case *stats.OutPayload: handleRPCOutPayload(ctx, st) case *stats.InPayload: @@ -95,6 +97,25 @@ func statsHandleRPC(ctx context.Context, s stats.RPCStats) { } } +func handleRPCBegin(ctx context.Context, s *stats.Begin) { + d, ok := ctx.Value(rpcDataKey).(*rpcData) + if !ok { + if grpclog.V(2) { + grpclog.Infoln("Failed to retrieve *rpcData from context.") + } + } + + if s.IsClient() { + ocstats.RecordWithOptions(ctx, + ocstats.WithTags(tag.Upsert(KeyClientMethod, methodName(d.method))), + ocstats.WithMeasurements(ClientStartedRPCs.M(1))) + } else { + ocstats.RecordWithOptions(ctx, + ocstats.WithTags(tag.Upsert(KeyClientMethod, methodName(d.method))), + ocstats.WithMeasurements(ServerStartedRPCs.M(1))) + } +} + func handleRPCOutPayload(ctx context.Context, s *stats.OutPayload) { d, ok := ctx.Value(rpcDataKey).(*rpcData) if !ok { diff --git a/vendor/go.opencensus.io/plugin/ochttp/server.go b/vendor/go.opencensus.io/plugin/ochttp/server.go index c7ea6423572..f7c8434be06 100644 --- a/vendor/go.opencensus.io/plugin/ochttp/server.go +++ b/vendor/go.opencensus.io/plugin/ochttp/server.go @@ -31,14 +31,14 @@ import ( // Handler is an http.Handler wrapper to instrument your HTTP server with // OpenCensus. It supports both stats and tracing. // -// Tracing +// # Tracing // // This handler is aware of the incoming request's span, reading it from request // headers as configured using the Propagation field. // The extracted span can be accessed from the incoming request's // context. // -// span := trace.FromContext(r.Context()) +// span := trace.FromContext(r.Context()) // // The server span will be automatically ended at the end of ServeHTTP. type Handler struct { @@ -224,7 +224,9 @@ func (t *trackingResponseWriter) WriteHeader(statusCode int) { } // wrappedResponseWriter returns a wrapped version of the original -// ResponseWriter and only implements the same combination of additional +// +// ResponseWriter and only implements the same combination of additional +// // interfaces as the original. // This implementation is based on https://github.com/felixge/httpsnoop. func (t *trackingResponseWriter) wrappedResponseWriter() http.ResponseWriter { diff --git a/vendor/go.opencensus.io/stats/doc.go b/vendor/go.opencensus.io/stats/doc.go index 00d473ee029..31477a464fd 100644 --- a/vendor/go.opencensus.io/stats/doc.go +++ b/vendor/go.opencensus.io/stats/doc.go @@ -19,7 +19,7 @@ Package stats contains support for OpenCensus stats recording. OpenCensus allows users to create typed measures, record measurements, aggregate the collected data, and export the aggregated data. -Measures +# Measures A measure represents a type of data point to be tracked and recorded. For example, latency, request Mb/s, and response Mb/s are measures @@ -33,7 +33,7 @@ Libraries can define and export measures. Application authors can then create views and collect and break down measures by the tags they are interested in. -Recording measurements +# Recording measurements Measurement is a data point to be collected for a measure. For example, for a latency (ms) measure, 100 is a measurement that represents a 100ms @@ -49,7 +49,7 @@ Libraries can always record measurements, and applications can later decide on which measurements they want to collect by registering views. This allows libraries to turn on the instrumentation by default. -Exemplars +# Exemplars For a given recorded measurement, the associated exemplar is a diagnostic map that gives more information about the measurement. @@ -64,6 +64,5 @@ then the trace span will be added to the exemplar associated with the measuremen When exported to a supporting back end, you should be able to easily navigate to example traces that fell into each bucket in the Distribution. - */ package stats // import "go.opencensus.io/stats" diff --git a/vendor/go.opencensus.io/stats/internal/record.go b/vendor/go.opencensus.io/stats/internal/record.go index 36935e629b6..436dc791f83 100644 --- a/vendor/go.opencensus.io/stats/internal/record.go +++ b/vendor/go.opencensus.io/stats/internal/record.go @@ -21,5 +21,11 @@ import ( // DefaultRecorder will be called for each Record call. var DefaultRecorder func(tags *tag.Map, measurement interface{}, attachments map[string]interface{}) +// MeasurementRecorder will be called for each Record call. This is the same as DefaultRecorder but +// avoids interface{} conversion. +// This will be a func(tags *tag.Map, measurement []Measurement, attachments map[string]interface{}) type, +// but is interface{} here to avoid import loops +var MeasurementRecorder interface{} + // SubscriptionReporter reports when a view subscribed with a measure. var SubscriptionReporter func(measure string) diff --git a/vendor/go.opencensus.io/stats/record.go b/vendor/go.opencensus.io/stats/record.go index 2b97283462e..8b5b99803ce 100644 --- a/vendor/go.opencensus.io/stats/record.go +++ b/vendor/go.opencensus.io/stats/record.go @@ -86,10 +86,29 @@ func createRecordOption(ros ...Options) *recordOptions { return o } +type measurementRecorder = func(tags *tag.Map, measurement []Measurement, attachments map[string]interface{}) + // Record records one or multiple measurements with the same context at once. // If there are any tags in the context, measurements will be tagged with them. func Record(ctx context.Context, ms ...Measurement) { - RecordWithOptions(ctx, WithMeasurements(ms...)) + // Record behaves the same as RecordWithOptions, but because we do not have to handle generic functionality + // (RecordOptions) we can reduce some allocations to speed up this hot path + if len(ms) == 0 { + return + } + recorder := internal.MeasurementRecorder.(measurementRecorder) + record := false + for _, m := range ms { + if m.desc.subscribed() { + record = true + break + } + } + if !record { + return + } + recorder(tag.FromContext(ctx), ms, nil) + return } // RecordWithTags records one or multiple measurements at once. diff --git a/vendor/go.opencensus.io/stats/view/aggregation.go b/vendor/go.opencensus.io/stats/view/aggregation.go index 748bd568cda..61f72d20da3 100644 --- a/vendor/go.opencensus.io/stats/view/aggregation.go +++ b/vendor/go.opencensus.io/stats/view/aggregation.go @@ -90,9 +90,9 @@ func Sum() *Aggregation { // // If len(bounds) >= 2 then the boundaries for bucket index i are: // -// [-infinity, bounds[i]) for i = 0 -// [bounds[i-1], bounds[i]) for 0 < i < length -// [bounds[i-1], +infinity) for i = length +// [-infinity, bounds[i]) for i = 0 +// [bounds[i-1], bounds[i]) for 0 < i < length +// [bounds[i-1], +infinity) for i = length // // If len(bounds) is 0 then there is no histogram associated with the // distribution. There will be a single bucket with boundaries diff --git a/vendor/go.opencensus.io/stats/view/collector.go b/vendor/go.opencensus.io/stats/view/collector.go index ac22c93a2b5..bcd6e08c748 100644 --- a/vendor/go.opencensus.io/stats/view/collector.go +++ b/vendor/go.opencensus.io/stats/view/collector.go @@ -59,8 +59,15 @@ func (c *collector) clearRows() { // encodeWithKeys encodes the map by using values // only associated with the keys provided. func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte { + // Compute the buffer length we will need ahead of time to avoid resizing later + reqLen := 0 + for _, k := range keys { + s, _ := m.Value(k) + // We will store each key + its length + reqLen += len(s) + 1 + } vb := &tagencoding.Values{ - Buffer: make([]byte, len(keys)), + Buffer: make([]byte, reqLen), } for _, k := range keys { v, _ := m.Value(k) diff --git a/vendor/go.opencensus.io/stats/view/doc.go b/vendor/go.opencensus.io/stats/view/doc.go index 7bbedfe1ff2..60bf0e39254 100644 --- a/vendor/go.opencensus.io/stats/view/doc.go +++ b/vendor/go.opencensus.io/stats/view/doc.go @@ -34,7 +34,7 @@ // Libraries can define views but it is recommended that in most cases registering // views be left up to applications. // -// Exporting +// # Exporting // // Collected and aggregated data can be exported to a metric collection // backend by registering its exporter. diff --git a/vendor/go.opencensus.io/stats/view/worker.go b/vendor/go.opencensus.io/stats/view/worker.go index 6e8d18b7f6d..6a79cd8a34c 100644 --- a/vendor/go.opencensus.io/stats/view/worker.go +++ b/vendor/go.opencensus.io/stats/view/worker.go @@ -33,6 +33,7 @@ func init() { defaultWorker = NewMeter().(*worker) go defaultWorker.start() internal.DefaultRecorder = record + internal.MeasurementRecorder = recordMeasurement } type measureRef struct { @@ -199,11 +200,21 @@ func record(tags *tag.Map, ms interface{}, attachments map[string]interface{}) { defaultWorker.Record(tags, ms, attachments) } +func recordMeasurement(tags *tag.Map, ms []stats.Measurement, attachments map[string]interface{}) { + defaultWorker.recordMeasurement(tags, ms, attachments) +} + // Record records a set of measurements ms associated with the given tags and attachments. func (w *worker) Record(tags *tag.Map, ms interface{}, attachments map[string]interface{}) { + w.recordMeasurement(tags, ms.([]stats.Measurement), attachments) +} + +// recordMeasurement records a set of measurements ms associated with the given tags and attachments. +// This is the same as Record but without an interface{} type to avoid allocations +func (w *worker) recordMeasurement(tags *tag.Map, ms []stats.Measurement, attachments map[string]interface{}) { req := &recordReq{ tm: tags, - ms: ms.([]stats.Measurement), + ms: ms, attachments: attachments, t: time.Now(), } @@ -221,6 +232,11 @@ func SetReportingPeriod(d time.Duration) { defaultWorker.SetReportingPeriod(d) } +// Stop stops the default worker. +func Stop() { + defaultWorker.Stop() +} + // SetReportingPeriod sets the interval between reporting aggregated views in // the program. If duration is less than or equal to zero, it enables the // default behavior. @@ -281,7 +297,7 @@ func (w *worker) start() { case <-w.quit: w.timer.Stop() close(w.c) - w.done <- true + close(w.done) return } } @@ -290,8 +306,11 @@ func (w *worker) start() { func (w *worker) Stop() { prodMgr := metricproducer.GlobalManager() prodMgr.DeleteProducer(w) - - w.quit <- true + select { + case <-w.quit: + default: + close(w.quit) + } <-w.done } diff --git a/vendor/go.opencensus.io/tag/profile_19.go b/vendor/go.opencensus.io/tag/profile_19.go index b34d95e34a2..8fb17226fe3 100644 --- a/vendor/go.opencensus.io/tag/profile_19.go +++ b/vendor/go.opencensus.io/tag/profile_19.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build go1.9 // +build go1.9 package tag diff --git a/vendor/go.opencensus.io/tag/profile_not19.go b/vendor/go.opencensus.io/tag/profile_not19.go index 83adbce56b7..e28cf13cde9 100644 --- a/vendor/go.opencensus.io/tag/profile_not19.go +++ b/vendor/go.opencensus.io/tag/profile_not19.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !go1.9 // +build !go1.9 package tag diff --git a/vendor/go.opencensus.io/trace/doc.go b/vendor/go.opencensus.io/trace/doc.go index 04b1ee4f38e..7a1616a55c5 100644 --- a/vendor/go.opencensus.io/trace/doc.go +++ b/vendor/go.opencensus.io/trace/doc.go @@ -18,24 +18,23 @@ Package trace contains support for OpenCensus distributed tracing. The following assumes a basic familiarity with OpenCensus concepts. See http://opencensus.io - -Exporting Traces +# Exporting Traces To export collected tracing data, register at least one exporter. You can use one of the provided exporters or write your own. - trace.RegisterExporter(exporter) + trace.RegisterExporter(exporter) By default, traces will be sampled relatively rarely. To change the sampling frequency for your entire program, call ApplyConfig. Use a ProbabilitySampler to sample a subset of traces, or use AlwaysSample to collect a trace on every run: - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) Be careful about using trace.AlwaysSample in a production application with significant traffic: a new trace will be started and exported for every request. -Adding Spans to a Trace +# Adding Spans to a Trace A trace consists of a tree of spans. In Go, the current span is carried in a context.Context. @@ -44,8 +43,8 @@ It is common to want to capture all the activity of a function call in a span. F this to work, the function must take a context.Context as a parameter. Add these two lines to the top of the function: - ctx, span := trace.StartSpan(ctx, "example.com/Run") - defer span.End() + ctx, span := trace.StartSpan(ctx, "example.com/Run") + defer span.End() StartSpan will create a new top-level span if the context doesn't contain another span, otherwise it will create a child span. diff --git a/vendor/go.opencensus.io/trace/lrumap.go b/vendor/go.opencensus.io/trace/lrumap.go index 908c2497ed5..80095a5f6c0 100644 --- a/vendor/go.opencensus.io/trace/lrumap.go +++ b/vendor/go.opencensus.io/trace/lrumap.go @@ -44,7 +44,7 @@ func (lm lruMap) len() int { } func (lm lruMap) keys() []interface{} { - keys := make([]interface{}, len(lm.cacheKeys)) + keys := make([]interface{}, 0, len(lm.cacheKeys)) for k := range lm.cacheKeys { keys = append(keys, k) } diff --git a/vendor/go.opencensus.io/trace/trace_go11.go b/vendor/go.opencensus.io/trace/trace_go11.go index b7d8aaf2847..b8fc1e495a9 100644 --- a/vendor/go.opencensus.io/trace/trace_go11.go +++ b/vendor/go.opencensus.io/trace/trace_go11.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build go1.11 // +build go1.11 package trace diff --git a/vendor/go.opencensus.io/trace/trace_nongo11.go b/vendor/go.opencensus.io/trace/trace_nongo11.go index e25419859c0..da488fc8740 100644 --- a/vendor/go.opencensus.io/trace/trace_nongo11.go +++ b/vendor/go.opencensus.io/trace/trace_nongo11.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !go1.11 // +build !go1.11 package trace diff --git a/vendor/go.opentelemetry.io/contrib/.gitignore b/vendor/go.opentelemetry.io/contrib/.gitignore deleted file mode 100644 index 21ab270fe08..00000000000 --- a/vendor/go.opentelemetry.io/contrib/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -.DS_Store -Thumbs.db - -.tools/ -.idea/ -.vscode/ -*.iml -*.so -coverage.* -example - -instrumentation/google.golang.org/grpc/otelgrpc/example/server/server -instrumentation/google.golang.org/grpc/otelgrpc/example/client/client \ No newline at end of file diff --git a/vendor/go.opentelemetry.io/contrib/.golangci.yml b/vendor/go.opentelemetry.io/contrib/.golangci.yml deleted file mode 100644 index cef170f7c7f..00000000000 --- a/vendor/go.opentelemetry.io/contrib/.golangci.yml +++ /dev/null @@ -1,32 +0,0 @@ -# See https://github.com/golangci/golangci-lint#config-file -run: - issues-exit-code: 1 #Default - tests: true #Default - -linters: - enable: - - misspell - - goimports - - golint - - gofmt - -issues: - exclude-rules: - # helpers in tests often (rightfully) pass a *testing.T as their first argument - - path: _test\.go - text: "context.Context should be the first parameter of a function" - linters: - - golint - # Yes, they are, but it's okay in a test - - path: _test\.go - text: "exported func.*returns unexported type.*which can be annoying to use" - linters: - - golint - -linters-settings: - misspell: - locale: US - #ignore-words: - # - someword - goimports: - local-prefixes: go.opentelemetry.io diff --git a/vendor/go.opentelemetry.io/contrib/CHANGELOG.md b/vendor/go.opentelemetry.io/contrib/CHANGELOG.md deleted file mode 100644 index 1fcf34b2abb..00000000000 --- a/vendor/go.opentelemetry.io/contrib/CHANGELOG.md +++ /dev/null @@ -1,319 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.20.0] - 2021-04-23 - -### Changed - -- The `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo` instrumentation now accepts a `WithCommandAttributeDisabled`, - so the caller can specify whether to opt-out of tracing the mongo command. (#712) -- Upgrade to v0.20.0 of `go.opentelemetry.io/otel`. (#758) -- The B3 and Jaeger propagators now store their debug or deferred state in the context.Context instead of the SpanContext. (#758) - -## [0.19.0] - 2021-03-19 - -### Changed - -- Upgrade to v0.19.0 of `go.opentelemetry.io/otel`. - -## [0.18.0] - 2021-03-04 - -### Fixed - -- `otelmemcache` no longer sets span status to OK instead of leaving it unset. (#477) -- Fix goroutine leak in gRPC `StreamClientInterceptor`. (#581) - -### Removed - -- Remove service name from `otelmemcache` configuration and span attributes. (#477) - -## [0.17.0] - 2021-02-15 - -### Added - -- Add `ot-tracer` propagator (#562) - -### Changed - -- Rename project default branch from `master` to `main`. - -### Fixed - -- Added failure message for AWS ECS resource detector for better debugging (#568) -- Goroutine leak in gRPC StreamClientInterceptor while streamer returns an error. (#581) - -## [0.16.0] - 2021-01-13 - -### Fixed - -- Fix module path for AWS ECS resource detector (#517) - -## [0.15.1] - 2020-12-14 - -### Added - -- Add registry link check to `Makefile` and pre-release script. (#446) -- A new AWS X-Ray ID Generator (#459) -- Migrate CircleCI jobs to GitHub Actions (#476) -- Add CodeQL GitHub Action (#506) -- Add gosec workflow to GitHub Actions (#507) - -### Fixed - -- Fixes the body replacement in otelhttp to not to mutate a nil body. (#484) - -## [0.15.0] - 2020-12-11 - -### Added - -- A new Amazon EKS resource detector. (#465) -- A new `gcp.CloudRun` detector for detecting resource from a Cloud Run instance. (#455) - -## [0.14.0] - 2020-11-20 - -### Added - -- `otelhttp.{Get,Head,Post,PostForm}` convenience wrappers for their `http` counterparts. (#390) -- The AWS detector now adds the cloud zone, host image ID, host type, and host name to the returned `Resource`. (#410) -- Add Amazon ECS Resource Detector for AWS X-Ray. (#466) -- Add propagator for AWS X-Ray (#462) - -### Changed - -- Add semantic version to `Tracer` / `Meter` created by instrumentation packages `otelsaram`, `otelrestful`, `otelmongo`, `otelhttp` and `otelhttptrace`. (#412) -- Update instrumentation guidelines about tracer / meter semantic version. (#412) -- Replace internal tracer and meter helpers by helpers from `go.opentelemetry.io/otel`. (#414) -- gRPC instrumentation sets span attribute `rpc.grpc.status_code`. (#453) - -## Fixed - -- `/detectors/aws` no longer fails if instance metadata is not available (e.g. not running in AWS) (#401) -- The AWS detector now returns a partial resource and an appropriate error if it encounters an error part way through determining a `Resource` identity. (#410) -- The `host` instrumentation unit test has been updated to not depend on the system it runs on. (#426) - -## [0.13.0] - 2020-10-09 - -## Added - -- A Jaeger propagator. (#375) - -## Changed - -- The `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc` package instrumentation no longer accepts a `Tracer` as an argument to the interceptor function. - Instead, a new `WithTracerProvider` option is added to configure the `TracerProvider` used when creating the `Tracer` for the instrumentation. (#373) -- The `go.opentelemetry.io/contrib/instrumentation/gopkg.in/macaron.v1/otelmacaron` instrumentation now accepts a `TracerProvider` rather than a `Tracer`. (#374) -- Remove `go.opentelemetry.io/otel/sdk` dependency from instrumentation. (#381) -- Use `httpsnoop` in `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux` to ensure `http.ResponseWriter` additional interfaces are preserved. (#388) - -### Fixed - -- The `go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho.Middleware` no longer sends duplicate errors to the global `ErrorHandler`. (#377, #364) -- The import comment in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` is now correctly quoted. (#379) -- The B3 propagator sets the sample bitmask when the sampling decision is `debug`. (#369) - -## [0.12.0] - 2020-09-25 - -### Changed - -- Replace `WithTracer` with `WithTracerProvider` in the `go.opentelemetry.io/contrib/instrumentation/gopkg.in/macaron.v1/otelmacaron` instrumentation. (#374) - -### Added - -- Benchmark tests for the gRPC instrumentation. (#296) -- Integration testing for the gRPC instrumentation. (#297) -- Allow custom labels to be added to net/http metrics. (#306) -- Added B3 propagator, moving it out of open.telemetry.io/otel repo. (#344) - -### Changed - -- Unify instrumentation about provider options for `go.mongodb.org/mongo-driver`, `gin-gonic/gin`, `gorilla/mux`, - `labstack/echo`, `emicklei/go-restful`, `bradfitz/gomemcache`, `Shopify/sarama`, `net/http` and `beego`. (#303) -- Update instrumentation guidelines about uniform provider options. Also, update style guide. (#303) -- Make config struct of instrumentation unexported. (#303) -- Instrumentations have been updated to adhere to the [configuration style guide's](https://github.com/open-telemetry/opentelemetry-go/blob/master/CONTRIBUTING.md#config) - updated recommendation to use `newConfig()` instead of `configure()`. (#336) -- A new instrumentation naming scheme is implemented to avoid package name conflicts for instrumented packages while still remaining discoverable. (#359) - - `google.golang.org/grpc` -> `google.golang.org/grpc/otelgrpc` - - `go.mongodb.org/mongo-driver` -> `go.mongodb.org/mongo-driver/mongo/otelmongo` - - `net/http` -> `net/http/otelhttp` - - `net/http/httptrace` -> `net/http/httptrace/otelhttptrace` - - `github.com/labstack/echo` -> `github.com/labstack/echo/otelecho` - - `github.com/bradfitz/gomemcache` -> `github.com/bradfitz/gomemcache/memcache/otelmemcache` - - `github.com/gin-gonic/gin` -> `github.com/gin-gonic/gin/otelgin` - - `github.com/gocql/gocql` -> `github.com/gocql/gocql/otelgocql` - - `github.com/emicklei/go-restful` -> `github.com/emicklei/go-restful/otelrestful` - - `github.com/Shopify/sarama` -> `github.com/Shopify/sarama/otelsarama` - - `github.com/gorilla/mux` -> `github.com/gorilla/mux/otelmux` - - `github.com/astaxie/beego` -> `github.com/astaxie/beego/otelbeego` - - `gopkg.in/macaron.v1` -> `gopkg.in/macaron.v1/otelmacaron` -- Rename `OTelBeegoHandler` to `Handler` in the `go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego` package. (#359) - -## [0.11.0] - 2020-08-25 - -### Added - -- Top-level `Version()` and `SemVersion()` functions defining the current version of the contrib package. (#225) -- Instrumentation for the `github.com/astaxie/beego` package. (#200) -- Instrumentation for the `github.com/bradfitz/gomemcache` package. (#204) -- Host metrics instrumentation. (#231) -- Cortex histogram and distribution support. (#237) -- Cortex example project. (#238) -- Cortex HTTP authentication. (#246) - -### Changed - -- Remove service name as a parameter of Sarama instrumentation. (#221) -- Replace `WithTracer` with `WithTracerProvider` in Sarama instrumentation. (#221) -- Switch to use common top-level module `SemVersion()` when creating versioned tracer in `bradfitz/gomemcache`. (#226) -- Use `IntegrationShouldRun` in `gomemcache_test`. (#254) -- Use Go 1.15 for CI builds. (#236) -- Improved configuration for `runtime` instrumentation. (#224) - -### Fixed - -- Update dependabot configuration to include newly added `bradfitz/gomemcache` package. (#226) -- Correct `runtime` instrumentation name. (#241) - -## [0.10.1] - 2020-08-13 - -### Added - -- The `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc` module has been added to replace the instrumentation that had previoiusly existed in the `go.opentelemetry.io/otel/instrumentation/grpctrace` package. (#189) -- Instrumentation for the stdlib `net/http` and `net/http/httptrace` packages. (#190) -- Initial Cortex exporter. (#202, #205, #210, #211, #215) - -### Fixed - -- Bump google.golang.org/grpc from 1.30.0 to 1.31.0. (#166) -- Bump go.mongodb.org/mongo-driver from 1.3.5 to 1.4.0 in /instrumentation/go.mongodb.org/mongo-driver. (#170) -- Bump google.golang.org/grpc in /instrumentation/github.com/gin-gonic/gin. (#173) -- Bump google.golang.org/grpc in /instrumentation/github.com/labstack/echo. (#176) -- Bump google.golang.org/grpc from 1.30.0 to 1.31.0 in /instrumentation/github.com/Shopify/sarama. (#179) -- Bump cloud.google.com/go from 0.61.0 to 0.63.0 in /detectors/gcp. (#181, #199) -- Bump github.com/aws/aws-sdk-go from 1.33.15 to 1.34.1 in /detectors/aws. (#184, #192, #193, #198, #201, #203) -- Bump github.com/golangci/golangci-lint from 1.29.0 to 1.30.0 in /tools. (#186) -- Setup CI to run tests that require external resources (Cassandra and MongoDB). (#191) -- Bump github.com/Shopify/sarama from 1.26.4 to 1.27.0 in /instrumentation/github.com/Shopify/sarama. (#206) - -## [0.10.0] - 2020-07-31 - -This release upgrades its [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.10.0) dependency to v0.10.0 and includes new instrumentation for popular Kafka and Cassandra clients. - -### Added - -- A detector that generate resources from GCE instance. (#132) -- A detector that generate resources from AWS instances. (#139) -- Instrumentation for the Kafka client github.com/Shopify/sarama. (#134, #153) -- Links and status message for mock span in the internal testing library. (#134) -- Instrumentation for the Cassandra client github.com/gocql/gocql. (#137) -- A detector that generate resources from GKE clusters. (#154) - -### Fixed - -- Bump github.com/aws/aws-sdk-go from 1.33.8 to 1.33.15 in /detectors/aws. (#155, #157, #159, #162) -- Bump github.com/golangci/golangci-lint from 1.28.3 to 1.29.0 in /tools. (#146) - -## [0.9.0] - 2020-07-20 - -This release upgrades its [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.9.0) dependency to v0.9.0. - -### Fixed - -- Bump github.com/emicklei/go-restful/v3 from 3.0.0 to 3.2.0 in /instrumentation/github.com/emicklei/go-restful. (#133) -- Update dependabot configuration to correctly check all included packages. (#131) -- Update `RELEASING.md` with correct `tag.sh` command. (#130) - -## [0.8.0] - 2020-07-10 - -This release upgrades its [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.8.0) dependency to v0.8.0, includes minor fixes, and new instrumentation. - -### Added - -- Create this `CHANGELOG.md`. (#114) -- Add `emicklei/go-restful/v3` trace instrumentation. (#115) - -### Changed - -- Update `CONTRIBUTING.md` to ask for updates to `CHANGELOG.md` with each pull request. (#114) -- Move all `github.com` package instrumentation under a `github.com` directory. (#118) - -### Fixed - -- Update README to include information about external instrumentation. - To start, this includes native instrumentation found in the `go-redis/redis` package. (#117) -- Bump github.com/golangci/golangci-lint from 1.27.0 to 1.28.2 in /tools. (#122, #123, #125) -- Bump go.mongodb.org/mongo-driver from 1.3.4 to 1.3.5 in /instrumentation/go.mongodb.org/mongo-driver. (#124) - -## [0.7.0] - 2020-06-29 - -This release upgrades its [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.7.0) dependency to v0.7.0. - -### Added - -- Create `RELEASING.md` instructions. (#101) -- Apply transitive dependabot go.mod updates as part of a new automatic Github workflow. (#94) -- New dependabot integration to automate package upgrades. (#61) -- Add automatic tag generation script for release. (#60) - -### Changed - -- Upgrade Datadog metrics exporter to include Resource tags. (#46) -- Added output validation to Datadog example. (#96) -- Move Macaron package to match layout guidelines. (#92) -- Update top-level README and instrumentation README. (#92) -- Bump google.golang.org/grpc from 1.29.1 to 1.30.0. (#99) -- Bump github.com/golangci/golangci-lint from 1.21.0 to 1.27.0 in /tools. (#77) -- Bump go.mongodb.org/mongo-driver from 1.3.2 to 1.3.4 in /instrumentation/go.mongodb.org/mongo-driver. (#76) -- Bump github.com/stretchr/testify from 1.5.1 to 1.6.1. (#74) -- Bump gopkg.in/macaron.v1 from 1.3.5 to 1.3.9 in /instrumentation/macaron. (#68) -- Bump github.com/gin-gonic/gin from 1.6.2 to 1.6.3 in /instrumentation/gin-gonic/gin. (#73) -- Bump github.com/DataDog/datadog-go from 3.5.0+incompatible to 3.7.2+incompatible in /exporters/metric/datadog. (#78) -- Replaced `internal/trace/http.go` helpers with `api/standard` helpers from otel-go repo. (#112) - -## [0.6.1] - 2020-06-08 - -First official tagged release of `contrib` repository. - -### Added - -- `labstack/echo` trace instrumentation (#42) -- `mongodb` trace instrumentation (#26) -- Go Runtime metrics (#9) -- `gorilla/mux` trace instrumentation (#19) -- `gin-gonic` trace instrumentation (#15) -- `macaron` trace instrumentation (#20) -- `dogstatsd` metrics exporter (#10) -- `datadog` metrics exporter (#22) -- Tags to all modules in repository -- Repository folder structure and automated build (#3) - -### Changes - -- Prefix support for dogstatsd (#34) -- Update Go Runtime package to use batch observer (#44) - -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go-contrib/compare/v0.20.0...HEAD -[0.20.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.20.0 -[0.19.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.19.0 -[0.18.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.18.0 -[0.17.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.17.0 -[0.16.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.16.0 -[0.15.1]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.15.1 -[0.15.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.15.0 -[0.14.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.14.0 -[0.13.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.13.0 -[0.12.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.12.0 -[0.11.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.11.0 -[0.10.1]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.10.1 -[0.10.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.10.0 -[0.9.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.9.0 -[0.8.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.8.0 -[0.7.0]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.7.0 -[0.6.1]: https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v0.6.1 diff --git a/vendor/go.opentelemetry.io/contrib/CODEOWNERS b/vendor/go.opentelemetry.io/contrib/CODEOWNERS deleted file mode 100644 index 196df9cfd89..00000000000 --- a/vendor/go.opentelemetry.io/contrib/CODEOWNERS +++ /dev/null @@ -1,17 +0,0 @@ -##################################################### -# -# List of approvers for this repository -# -##################################################### -# -# Learn about membership in OpenTelemetry community: -# https://github.com/open-telemetry/community/blob/main/community-membership.md -# -# -# Learn about CODEOWNERS file format: -# https://help.github.com/en/articles/about-code-owners -# - -* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo - -CODEOWNERS @MrAlias @Aneurysm9 diff --git a/vendor/go.opentelemetry.io/contrib/CONTRIBUTING.md b/vendor/go.opentelemetry.io/contrib/CONTRIBUTING.md deleted file mode 100644 index 0c7bb21bd0f..00000000000 --- a/vendor/go.opentelemetry.io/contrib/CONTRIBUTING.md +++ /dev/null @@ -1,135 +0,0 @@ -# Contributing to opentelemetry-go-contrib - -The Go special interest group (SIG) meets regularly. See the -OpenTelemetry -[community](https://github.com/open-telemetry/community#golang-sdk) -repo for information on this and other language SIGs. - -See the [public meeting -notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b) -for a summary description of past meetings. To request edit access, -join the meeting or get in touch on -[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT). - -## Development - -There are some generated files checked into the repo. To make sure -that the generated files are up-to-date, run `make` (or `make -precommit` - the `precommit` target is the default). - -The `precommit` target also fixes the formatting of the code and -checks the status of the go module files. - -If after running `make precommit` the output of `git status` contains -`nothing to commit, working tree clean` then it means that everything -is up-to-date and properly formatted. - -## Pull Requests - -### How to Send Pull Requests - -Everyone is welcome to contribute code to `opentelemetry-go-contrib` via -GitHub pull requests (PRs). - -To create a new PR, fork the project in GitHub and clone the upstream -repo: - -```sh -$ git clone https://github.com/open-telemetry/opentelemetry-go-contrib -``` -This would put the project in the `opentelemetry-go-contrib` directory in -current working directory. - -Enter the newly created directory and add your fork as a new remote: - -```sh -$ git remote add git@github.com:/opentelemetry-go -``` - -Check out a new branch, make modifications, run linters and tests, update -`CHANGELOG.md` and push the branch to your fork: - -```sh -$ git checkout -b -# edit files -# update changelog -$ make precommit -$ git add -p -$ git commit -$ git push -``` - -Open a pull request against the main `opentelemetry-go-contrib` repo. Be sure to add the pull -request ID to the entry you added to `CHANGELOG.md`. - -### How to Receive Comments - -* If the PR is not ready for review, please put `[WIP]` in the title, - tag it as `work-in-progress`, or mark it as - [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). -* Make sure CLA is signed and CI is clear. - -### How to Get PRs Merged - -A PR is considered to be **ready to merge** when: - -* It has received two approvals from Approvers/Maintainers (at - different companies). -* Feedback has been addressed. -* Any substantive changes to your PR will require that you clear any prior - Approval reviews, this includes changes resulting from other feedback. Unless - the approver explicitly stated that their approval will persist across - changes it should be assumed that the PR needs their review again. Other - project members (e.g. approvers, maintainers) can help with this if there are - any questions or if you forget to clear reviews. -* It has been open for review for at least one working day. This gives - people reasonable time to review. -* Trivial change (typo, cosmetic, doc, etc.) doesn't have to wait for - one day. -* `CHANGELOG.md` has been updated to reflect what has been - added, changed, removed, or fixed. -* Urgent fix can take exception as long as it has been actively - communicated. - -Any Maintainer can merge the PR once it is **ready to merge**. - -## Style Guide - -* Make sure to run `make precommit` - this will find and fix the code - formatting. -* Check [opentelemetry-go Style Guide](https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md#style-guide) - -## Adding a new Contrib package - -To add a new contrib package follow an existing one. An empty Sample instrumentation -provides base structure with an example and a test. Each contrib package -should be its own module. A contrib package may contain more than one go package. - -### Folder Structure -- instrumentation/\ (**Common**) -- instrumentation/\/trace (**specific to trace**) -- instrumentation/\/metrics (**specific to metrics**) - -#### Example -- instrumentation/gorm/trace -- instrumentation/kafka/metrics - -## Approvers and Maintainers - -Approvers: - -- [Evan Torrie](https://github.com/evantorrie), Verizon Media -- [Josh MacDonald](https://github.com/jmacd), LightStep -- [Sam Xie](https://github.com/XSAM) -- [David Ashpole](https://github.com/dashpole), Google -- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep - -Maintainers: - -- [Anthony Mirabella](https://github.com/Aneurysm9), Centene -- [Tyler Yahn](https://github.com/MrAlias), New Relic - -### Become an Approver or a Maintainer - -See the [community membership document in OpenTelemetry community -repo](https://github.com/open-telemetry/community/blob/main/community-membership.md). diff --git a/vendor/go.opentelemetry.io/contrib/Makefile b/vendor/go.opentelemetry.io/contrib/Makefile deleted file mode 100644 index 4ad59562cc3..00000000000 --- a/vendor/go.opentelemetry.io/contrib/Makefile +++ /dev/null @@ -1,203 +0,0 @@ -TOOLS_MOD_DIR := ./tools - -# All source code and documents. Used in spell check. -ALL_DOCS := $(shell find . -name '*.md' -type f | sort) -# All directories with go.mod files related to opentelemetry library. Used for building, testing and linting. -ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)) -ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort) - -# URLs to check if all contrib entries exist in the registry. -REGISTRY_BASE_URL = https://raw.githubusercontent.com/open-telemetry/opentelemetry.io/main/content/en/registry -CONTRIB_REPO_URL = https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main - -# Mac OS Catalina 10.5.x doesn't support 386. Hence skip 386 test -SKIP_386_TEST = false -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Darwin) - SW_VERS := $(shell sw_vers -productVersion) - ifeq ($(shell echo $(SW_VERS) | egrep '^(10.1[5-9]|1[1-9]|[2-9])'), $(SW_VERS)) - SKIP_386_TEST = true - endif -endif - - -GOTEST_MIN = go test -v -timeout 30s -GOTEST = $(GOTEST_MIN) -race -GOTEST_WITH_COVERAGE = $(GOTEST) -coverprofile=coverage.out -covermode=atomic -coverpkg=./... - -.DEFAULT_GOAL := precommit - -.PHONY: precommit - -TOOLS_DIR := $(abspath ./.tools) - -$(TOOLS_DIR)/golangci-lint: $(TOOLS_MOD_DIR)/go.mod $(TOOLS_MOD_DIR)/go.sum $(TOOLS_MOD_DIR)/tools.go - cd $(TOOLS_MOD_DIR) && \ - go build -o $(TOOLS_DIR)/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint - -$(TOOLS_DIR)/misspell: $(TOOLS_MOD_DIR)/go.mod $(TOOLS_MOD_DIR)/go.sum $(TOOLS_MOD_DIR)/tools.go - cd $(TOOLS_MOD_DIR) && \ - go build -o $(TOOLS_DIR)/misspell github.com/client9/misspell/cmd/misspell - -$(TOOLS_DIR)/stringer: $(TOOLS_MOD_DIR)/go.mod $(TOOLS_MOD_DIR)/go.sum $(TOOLS_MOD_DIR)/tools.go - cd $(TOOLS_MOD_DIR) && \ - go build -o $(TOOLS_DIR)/stringer golang.org/x/tools/cmd/stringer - -precommit: dependabot-check license-check generate build lint test - -.PHONY: test-with-coverage -test-with-coverage: - set -e; \ - printf "" > coverage.txt; \ - for dir in $(ALL_COVERAGE_MOD_DIRS); do \ - echo "go test ./... + coverage in $${dir}"; \ - (cd "$${dir}" && \ - $(GOTEST_WITH_COVERAGE) ./... && \ - go tool cover -html=coverage.out -o coverage.html); \ - [ -f "$${dir}/coverage.out" ] && cat "$${dir}/coverage.out" >> coverage.txt; \ - done; \ - sed -i.bak -e '2,$$ { /^mode: /d; }' coverage.txt && rm coverage.txt.bak - -.PHONY: ci -ci: precommit check-clean-work-tree test-with-coverage test-386 - -.PHONY: test-gocql -test-gocql: - @if ./tools/should_build.sh gocql; then \ - set -e; \ - docker run --name cass-integ --rm -p 9042:9042 -d cassandra:3; \ - CMD=cassandra IMG_NAME=cass-integ ./tools/wait.sh; \ - (cd instrumentation/github.com/gocql/gocql/otelgocql && \ - $(GOTEST_WITH_COVERAGE) . && \ - go tool cover -html=coverage.out -o coverage.html); \ - docker stop cass-integ; \ - fi - -.PHONY: test-mongo-driver -test-mongo-driver: - @if ./tools/should_build.sh mongo-driver; then \ - set -e; \ - docker run --name mongo-integ --rm -p 27017:27017 -d mongo; \ - CMD=mongo IMG_NAME=mongo-integ ./tools/wait.sh; \ - (cd instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo && \ - $(GOTEST_WITH_COVERAGE) . && \ - go tool cover -html=coverage.out -o coverage.html); \ - docker stop mongo-integ; \ - fi - -.PHONY: test-gomemcache -test-gomemcache: - @if ./tools/should_build.sh gomemcache; then \ - set -e; \ - docker run --name gomemcache-integ --rm -p 11211:11211 -d memcached; \ - CMD=gomemcache IMG_NAME=gomemcache-integ ./tools/wait.sh; \ - (cd instrumentation/github.com/bradfitz/gomemcache/memcache/otelmemcache && \ - $(GOTEST_WITH_COVERAGE) . && \ - go tool cover -html=coverage.out -o coverage.html); \ - docker stop gomemcache-integ ; \ - fi - -.PHONY: check-clean-work-tree -check-clean-work-tree: - @if ! git diff --quiet; then \ - echo; \ - echo 'Working tree is not clean, did you forget to run "make precommit"?'; \ - echo; \ - git status; \ - exit 1; \ - fi - -.PHONY: build -build: - # TODO: Fix this on windows. - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "compiling all packages in $${dir}"; \ - (cd "$${dir}" && \ - go build ./... && \ - go test -run xxxxxMatchNothingxxxxx ./... >/dev/null); \ - done - -.PHONY: test -test: - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "go test ./... + race in $${dir}"; \ - (cd "$${dir}" && \ - $(GOTEST) ./...); \ - done - -.PHONY: test-386 -test-386: - if [ $(SKIP_386_TEST) = true ] ; then \ - echo "skipping the test for GOARCH 386 as it is not supported on the current OS"; \ - else \ - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "go test ./... GOARCH 386 in $${dir}"; \ - (cd "$${dir}" && \ - GOARCH=386 $(GOTEST_MIN) ./...); \ - done; \ - fi - -.PHONY: lint -lint: $(TOOLS_DIR)/golangci-lint $(TOOLS_DIR)/misspell - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "golangci-lint in $${dir}"; \ - (cd "$${dir}" && \ - $(TOOLS_DIR)/golangci-lint run --fix && \ - $(TOOLS_DIR)/golangci-lint run); \ - done - $(TOOLS_DIR)/misspell -w $(ALL_DOCS) - set -e; for dir in $(ALL_GO_MOD_DIRS) $(TOOLS_MOD_DIR); do \ - echo "go mod tidy in $${dir}"; \ - (cd "$${dir}" && \ - go mod tidy); \ - done - -.PHONY: generate -generate: $(TOOLS_DIR)/stringer - PATH="$(TOOLS_DIR):$${PATH}" go generate ./... - -.PHONY: license-check -license-check: - @licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path './vendor/*' ! -path './exporters/otlp/internal/opentelemetry-proto/*') ; do \ - awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \ - done); \ - if [ -n "$${licRes}" ]; then \ - echo "license header checking failed:"; echo "$${licRes}"; \ - exit 1; \ - fi - -.PHONY: registry-links-check -registry-links-check: - @checkRes=$$( \ - for f in $$( find ./instrumentation ./exporters ./detectors ! -path './instrumentation/net/*' -type f -name 'go.mod' -exec dirname {} \; | egrep -v '/example|/utils' | sort ) \ - ./instrumentation/net/http; do \ - TYPE="instrumentation"; \ - if $$(echo "$$f" | grep -q "exporters"); then \ - TYPE="exporter"; \ - fi; \ - if $$(echo "$$f" | grep -q "detectors"); then \ - TYPE="detector"; \ - fi; \ - NAME=$$(echo "$$f" | sed -e 's/.*\///' -e 's/.*otel//'); \ - LINK=$(CONTRIB_REPO_URL)/$$(echo "$$f" | sed -e 's/..//' -e 's/\/otel.*$$//'); \ - if ! $$(curl -s $(REGISTRY_BASE_URL)/$${TYPE}-go-$${NAME}.md | grep -q "$${LINK}"); then \ - echo "$$f"; \ - fi \ - done; \ - ); \ - if [ -n "$$checkRes" ]; then \ - echo "WARNING: registry link check failed for the following packages:"; echo "$${checkRes}"; \ - fi - -.PHONY: dependabot-check -dependabot-check: - @result=$$( \ - for f in $$( find . -type f -name go.mod -exec dirname {} \; | sed 's/^.\/\?/\//' ); \ - do grep -q "$$f" .github/dependabot.yml \ - || echo "$$f"; \ - done; \ - ); \ - if [ -n "$$result" ]; then \ - echo "missing go.mod dependabot check:"; echo "$$result"; \ - exit 1; \ - fi diff --git a/vendor/go.opentelemetry.io/contrib/README.md b/vendor/go.opentelemetry.io/contrib/README.md deleted file mode 100644 index 28585affe92..00000000000 --- a/vendor/go.opentelemetry.io/contrib/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# OpenTelemetry-Go Contrib - -[![build_and_test](https://github.com/open-telemetry/opentelemetry-go-contrib/workflows/build_and_test/badge.svg)](https://github.com/open-telemetry/opentelemetry-go-contrib/actions?query=workflow%3Abuild_and_test+branch%3Amain) -[![Docs](https://godoc.org/go.opentelemetry.io/contrib?status.svg)](https://pkg.go.dev/go.opentelemetry.io/contrib) -[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/contrib)](https://goreportcard.com/report/go.opentelemetry.io/contrib) -[![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT) - -Collection of 3rd-party instrumentation and exporters for [OpenTelemetry-Go](https://github.com/open-telemetry/opentelemetry-go). - -## Contents - -- [Instrumentation](./instrumentation/): Packages providing OpenTelemetry instrumentation for 3rd-party libraries. -- [Exporters](./exporters/): Packages providing OpenTelemetry exporters for 3rd-party telemetry systems. -- [Propagators](./propagators/): Packages providing OpenTelemetry context propagators for 3rd-party propagation formats. -- [Detectors](./detectors/): Packages providing OpenTelemetry resource detectors for 3rd-party cloud computing environments. - -## Project Status - -This project is currently in a pre-GA phase. Our progress towards a GA release -candidate is tracked in [this project -board](https://github.com/orgs/open-telemetry/projects/5). - -## Contributing - -For information on how to contribute, consult [the contributing guidelines](./CONTRIBUTING.md) diff --git a/vendor/go.opentelemetry.io/contrib/RELEASING.md b/vendor/go.opentelemetry.io/contrib/RELEASING.md deleted file mode 100644 index f7fd359c477..00000000000 --- a/vendor/go.opentelemetry.io/contrib/RELEASING.md +++ /dev/null @@ -1,96 +0,0 @@ -# Release Process - -There are two types of release for the `go.opentelemetry.io/contrib` repo -and submodules. - -1. **Case 1** A release due to changes independent of the -`go.opentelemetry.io/otel` module, e.g. perhaps a critical bug fix in -one of the contrib modules. - -2. **Case 2** A release due to a breaking API change in -`go.opentelemetry.io/otel` which all modules in this repo -depend on. - -## Pre-Release - -Update go.mod for submodules to depend on the upcoming new release of -the module in this repo, `go.opentelemetry.io/contrib`. Decide on the -next version of the semantic tag to apply to the contrib -module based on whether you fall into Case 1 or Case 2. - -### Case 1 - -If the changes are all internal to this repo, then the new tag will -most often be a patch or minor version upgrade to the existing tag on -this module. Let's call this ``. - -### Case 2 - -If a new release is required due to breaking changes in -`go.opentelemetry.io/otel`, then the new semantic tag for this repo -should be bumped to match the `go.opentelemetry.io/otel` new tag. -Let's call this ``. The script checks that -`go.opentelemetry.io/otel@v` is a valid tag, so you need -to wait until that tag has been pushed in the main repo. - -In nearly all cases, `` should be the same as -``. - -1. Run `pre_release.sh` script to create a branch `pre_release_`. - The script will also run `go mod tidy` and `make ci`. - - * **Case 1** `./pre_release.sh -t ` - * **Case 2** `./pre_release.sh -o [-t ]` - -2. If you used `-o ` to rewrite the modules to depend on - a new version of `go.opentelemetry.io/otel`, there will likely be - breaking changes that require fixes to the files in this - `contrib` repo. Make the appropriate fixes to address any API - breaks and run through the - - ``` - git commit -m "fixes due to API changes" - make precommit - ``` - - cycle until everything passes - -4. Push the changes to upstream. - - ``` - git diff main - git push - ``` - -5. Create a PR on github and merge the PR once approved. - - -### Tag -Now create a `` on the commit hash of the changes made in pre-release step, - -1. Run the tag.sh script. - - ``` - ./tag.sh - ``` -2. Push tags upstream. Make sure you push upstream for all the sub-module tags as well. - - ``` - git push upstream - git push upstream - ... - ``` - -## Release -Now create a release for the new `` on github. -The release body should include all the release notes in the Changelog for this release. -Additionally, the `tag.sh` script generates commit logs since last release which can be used to suppliment the release notes. - - - - - - - - - diff --git a/vendor/go.opentelemetry.io/contrib/contrib.go b/vendor/go.opentelemetry.io/contrib/contrib.go deleted file mode 100644 index 92c1ddfee98..00000000000 --- a/vendor/go.opentelemetry.io/contrib/contrib.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package contrib contains common values used across all -// instrumentation, exporter, and detector contributions. -package contrib // import "go.opentelemetry.io/contrib" - -// Version is the current release version of OpenTelemetry Contrib in use. -func Version() string { - return "0.20.0" - // This string is updated by the pre_release.sh script during release -} - -// SemVersion is the semantic version to be supplied to tracer/meter creation. -func SemVersion() string { - return "semver:" + Version() -} diff --git a/vendor/go.opentelemetry.io/contrib/doc.go b/vendor/go.opentelemetry.io/contrib/doc.go deleted file mode 100644 index 6c55ff6a2b6..00000000000 --- a/vendor/go.opentelemetry.io/contrib/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This package provides all of its functionality through its -// submodules. The submodules in the exporters directory provide -// implementations for trace and metric exporters for third-party -// collectors, and submodules in the instrumentation directory provide the -// instrumentation for the popular go libraries. -package contrib diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go index 0816b9f5daa..92b8cf73c97 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "context" @@ -24,12 +24,12 @@ import ( // DefaultClient is the default Client and is used by Get, Head, Post and PostForm. // Please be careful of intitialization order - for example, if you change -// the global propagator, the DefaultClient might still be using the old one +// the global propagator, the DefaultClient might still be using the old one. var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} // Get is a convenient replacement for http.Get that adds a span around the request. -func Get(ctx context.Context, url string) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) +func Get(ctx context.Context, targetURL string) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "GET", targetURL, nil) if err != nil { return nil, err } @@ -37,8 +37,8 @@ func Get(ctx context.Context, url string) (resp *http.Response, err error) { } // Head is a convenient replacement for http.Head that adds a span around the request. -func Head(ctx context.Context, url string) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) +func Head(ctx context.Context, targetURL string) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "HEAD", targetURL, nil) if err != nil { return nil, err } @@ -46,8 +46,8 @@ func Head(ctx context.Context, url string) (resp *http.Response, err error) { } // Post is a convenient replacement for http.Post that adds a span around the request. -func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, "POST", url, body) +func Post(ctx context.Context, targetURL, contentType string, body io.Reader) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "POST", targetURL, body) if err != nil { return nil, err } @@ -56,6 +56,6 @@ func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *h } // PostForm is a convenient replacement for http.PostForm that adds a span around the request. -func PostForm(ctx context.Context, url string, data url.Values) (resp *http.Response, err error) { - return Post(ctx, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +func PostForm(ctx context.Context, targetURL string, data url.Values) (resp *http.Response, err error) { + return Post(ctx, targetURL, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go index a5b356289ce..303e5505e41 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "net/http" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // Attribute keys that can be added to a span. @@ -28,7 +29,7 @@ const ( WriteErrorKey = attribute.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded) ) -// Server HTTP metrics +// Server HTTP metrics. const ( RequestCount = "http.server.request_count" // Incoming request count total RequestContentLength = "http.server.request_content_length" // Incoming request bytes total @@ -39,3 +40,7 @@ const ( // Filter is a predicate used to determine whether a given http.request should // be traced. A Filter must return true if the request should be traced. type Filter func(*http.Request) bool + +func newTracer(tp trace.TracerProvider) trace.Tracer { + return tp.Tracer(instrumentationName, trace.WithInstrumentationVersion(Version())) +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go index 3bc203c451d..e4fa1b8d9d6 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( + "context" "net/http" + "net/http/httptrace" - "go.opentelemetry.io/contrib" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" ) @@ -32,50 +32,52 @@ const ( // config represents the configuration options available for the http.Handler // and http.Transport types. type config struct { + ServerName string Tracer trace.Tracer Meter metric.Meter Propagators propagation.TextMapPropagator - SpanStartOptions []trace.SpanOption + SpanStartOptions []trace.SpanStartOption + PublicEndpoint bool + PublicEndpointFn func(*http.Request) bool ReadEvent bool WriteEvent bool Filters []Filter SpanNameFormatter func(string, *http.Request) string + ClientTrace func(context.Context) *httptrace.ClientTrace TracerProvider trace.TracerProvider MeterProvider metric.MeterProvider } -// Option Interface used for setting *optional* config properties +// Option interface used for setting optional config properties. type Option interface { - Apply(*config) + apply(*config) } -// OptionFunc provides a convenience wrapper for simple Options -// that can be represented as functions. -type OptionFunc func(*config) +type optionFunc func(*config) -func (o OptionFunc) Apply(c *config) { +func (o optionFunc) apply(c *config) { o(c) } // newConfig creates a new config struct and applies opts to it. func newConfig(opts ...Option) *config { c := &config{ - Propagators: otel.GetTextMapPropagator(), - TracerProvider: otel.GetTracerProvider(), - MeterProvider: global.GetMeterProvider(), + Propagators: otel.GetTextMapPropagator(), + MeterProvider: otel.GetMeterProvider(), } for _, opt := range opts { - opt.Apply(c) + opt.apply(c) + } + + // Tracer is only initialized if manually specified. Otherwise, can be passed with the tracing context. + if c.TracerProvider != nil { + c.Tracer = newTracer(c.TracerProvider) } - c.Tracer = c.TracerProvider.Tracer( - instrumentationName, - trace.WithInstrumentationVersion(contrib.SemVersion()), - ) c.Meter = c.MeterProvider.Meter( instrumentationName, - metric.WithInstrumentationVersion(contrib.SemVersion()), + metric.WithInstrumentationVersion(Version()), ) return c @@ -84,16 +86,20 @@ func newConfig(opts ...Option) *config { // WithTracerProvider specifies a tracer provider to use for creating a tracer. // If none is specified, the global provider is used. func WithTracerProvider(provider trace.TracerProvider) Option { - return OptionFunc(func(cfg *config) { - cfg.TracerProvider = provider + return optionFunc(func(cfg *config) { + if provider != nil { + cfg.TracerProvider = provider + } }) } // WithMeterProvider specifies a meter provider to use for creating a meter. // If none is specified, the global provider is used. func WithMeterProvider(provider metric.MeterProvider) Option { - return OptionFunc(func(cfg *config) { - cfg.MeterProvider = provider + return optionFunc(func(cfg *config) { + if provider != nil { + cfg.MeterProvider = provider + } }) } @@ -101,23 +107,36 @@ func WithMeterProvider(provider metric.MeterProvider) Option { // span context. If this option is not provided, then the association is a child // association instead of a link. func WithPublicEndpoint() Option { - return OptionFunc(func(c *config) { - c.SpanStartOptions = append(c.SpanStartOptions, trace.WithNewRoot()) + return optionFunc(func(c *config) { + c.PublicEndpoint = true + }) +} + +// WithPublicEndpointFn runs with every request, and allows conditionnally +// configuring the Handler to link the span with an incoming span context. If +// this option is not provided or returns false, then the association is a +// child association instead of a link. +// Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn. +func WithPublicEndpointFn(fn func(*http.Request) bool) Option { + return optionFunc(func(c *config) { + c.PublicEndpointFn = fn }) } // WithPropagators configures specific propagators. If this -// option isn't specified then +// option isn't specified, then the global TextMapPropagator is used. func WithPropagators(ps propagation.TextMapPropagator) Option { - return OptionFunc(func(c *config) { - c.Propagators = ps + return optionFunc(func(c *config) { + if ps != nil { + c.Propagators = ps + } }) } // WithSpanOptions configures an additional set of // trace.SpanOptions, which are applied to each new span. -func WithSpanOptions(opts ...trace.SpanOption) Option { - return OptionFunc(func(c *config) { +func WithSpanOptions(opts ...trace.SpanStartOption) Option { + return optionFunc(func(c *config) { c.SpanStartOptions = append(c.SpanStartOptions, opts...) }) } @@ -129,14 +148,14 @@ func WithSpanOptions(opts ...trace.SpanOption) Option { // Filters will be invoked for each processed request, it is advised to make them // simple and fast. func WithFilter(f Filter) Option { - return OptionFunc(func(c *config) { + return optionFunc(func(c *config) { c.Filters = append(c.Filters, f) }) } type event int -// Different types of events that can be recorded, see WithMessageEvents +// Different types of events that can be recorded, see WithMessageEvents. const ( ReadEvents event = iota WriteEvents @@ -147,12 +166,12 @@ const ( // end of the request. // // Valid events are: -// * ReadEvents: Record the number of bytes read after every http.Request.Body.Read -// using the ReadBytesKey -// * WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write -// using the WriteBytesKey +// - ReadEvents: Record the number of bytes read after every http.Request.Body.Read +// using the ReadBytesKey +// - WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write +// using the WriteBytesKey func WithMessageEvents(events ...event) Option { - return OptionFunc(func(c *config) { + return optionFunc(func(c *config) { for _, e := range events { switch e { case ReadEvents: @@ -165,9 +184,25 @@ func WithMessageEvents(events ...event) Option { } // WithSpanNameFormatter takes a function that will be called on every -// request and the returned string will become the Span Name +// request and the returned string will become the Span Name. func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option { - return OptionFunc(func(c *config) { + return optionFunc(func(c *config) { c.SpanNameFormatter = f }) } + +// WithClientTrace takes a function that returns client trace instance that will be +// applied to the requests sent through the otelhttp Transport. +func WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option { + return optionFunc(func(c *config) { + c.ClientTrace = f + }) +} + +// WithServerName returns an Option that sets the name of the (virtual) server +// handling requests. +func WithServerName(server string) Option { + return optionFunc(func(c *config) { + c.ServerName = server + }) +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go index c912548b066..b2fbe07841c 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "io" @@ -21,45 +21,49 @@ import ( "github.com/felixge/httpsnoop" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/semconv" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" "go.opentelemetry.io/otel/trace" ) -var _ http.Handler = &Handler{} - -// Handler is http middleware that corresponds to the http.Handler interface and -// is designed to wrap a http.Mux (or equivalent), while individual routes on -// the mux are wrapped with WithRouteTag. A Handler will add various attributes -// to the span using the attribute.Keys defined in this package. -type Handler struct { +// middleware is an http middleware which wraps the next handler in a span. +type middleware struct { operation string - handler http.Handler + server string tracer trace.Tracer meter metric.Meter propagators propagation.TextMapPropagator - spanStartOptions []trace.SpanOption + spanStartOptions []trace.SpanStartOption readEvent bool writeEvent bool filters []Filter spanNameFormatter func(string, *http.Request) string counters map[string]metric.Int64Counter - valueRecorders map[string]metric.Int64ValueRecorder + valueRecorders map[string]metric.Float64Histogram + publicEndpoint bool + publicEndpointFn func(*http.Request) bool } func defaultHandlerFormatter(operation string, _ *http.Request) string { return operation } -// NewHandler wraps the passed handler, functioning like middleware, in a span -// named after the operation and with any provided Options. +// NewHandler wraps the passed handler in a span named after the operation and +// enriches it with metrics. func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler { - h := Handler{ - handler: handler, + return NewMiddleware(operation, opts...)(handler) +} + +// NewMiddleware returns a tracing and metrics instrumentation middleware. +// The handler returned by the middleware wraps a handler +// in a span named after the operation and enriches it with metrics. +func NewMiddleware(operation string, opts ...Option) func(http.Handler) http.Handler { + h := middleware{ operation: operation, } @@ -72,10 +76,14 @@ func NewHandler(handler http.Handler, operation string, opts ...Option) http.Han h.configure(c) h.createMeasures() - return &h + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h.serveHTTP(w, r, next) + }) + } } -func (h *Handler) configure(c *config) { +func (h *middleware) configure(c *config) { h.tracer = c.Tracer h.meter = c.Meter h.propagators = c.Propagators @@ -84,6 +92,9 @@ func (h *Handler) configure(c *config) { h.writeEvent = c.WriteEvent h.filters = c.Filters h.spanNameFormatter = c.SpanNameFormatter + h.publicEndpoint = c.PublicEndpoint + h.publicEndpointFn = c.PublicEndpointFn + h.server = c.ServerName } func handleErr(err error) { @@ -92,17 +103,17 @@ func handleErr(err error) { } } -func (h *Handler) createMeasures() { +func (h *middleware) createMeasures() { h.counters = make(map[string]metric.Int64Counter) - h.valueRecorders = make(map[string]metric.Int64ValueRecorder) + h.valueRecorders = make(map[string]metric.Float64Histogram) - requestBytesCounter, err := h.meter.NewInt64Counter(RequestContentLength) + requestBytesCounter, err := h.meter.Int64Counter(RequestContentLength) handleErr(err) - responseBytesCounter, err := h.meter.NewInt64Counter(ResponseContentLength) + responseBytesCounter, err := h.meter.Int64Counter(ResponseContentLength) handleErr(err) - serverLatencyMeasure, err := h.meter.NewInt64ValueRecorder(ServerLatency) + serverLatencyMeasure, err := h.meter.Float64Histogram(ServerLatency) handleErr(err) h.counters[RequestContentLength] = requestBytesCounter @@ -110,25 +121,46 @@ func (h *Handler) createMeasures() { h.valueRecorders[ServerLatency] = serverLatencyMeasure } -// ServeHTTP serves HTTP requests (http.Handler) -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// serveHTTP sets up tracing and calls the given next http.Handler with the span +// context injected into the request context. +func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http.Handler) { requestStartTime := time.Now() for _, f := range h.filters { if !f(r) { // Simply pass through to the handler if a filter rejects the request - h.handler.ServeHTTP(w, r) + next.ServeHTTP(w, r) return } } - opts := append([]trace.SpanOption{ - trace.WithAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...), - trace.WithAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...), - trace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(h.operation, "", r)...), - }, h.spanStartOptions...) // start with the configured options - ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) - ctx, span := h.tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...) + opts := []trace.SpanStartOption{ + trace.WithAttributes(semconvutil.HTTPServerRequest(h.server, r)...), + } + if h.server != "" { + hostAttr := semconv.NetHostName(h.server) + opts = append(opts, trace.WithAttributes(hostAttr)) + } + opts = append(opts, h.spanStartOptions...) + if h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) { + opts = append(opts, trace.WithNewRoot()) + // Linking incoming span context if any for public endpoint. + if s := trace.SpanContextFromContext(ctx); s.IsValid() && s.IsRemote() { + opts = append(opts, trace.WithLinks(trace.Link{SpanContext: s})) + } + } + + tracer := h.tracer + + if tracer == nil { + if span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() { + tracer = newTracer(span.TracerProvider()) + } else { + tracer = newTracer(otel.GetTracerProvider()) + } + } + + ctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...) defer span.End() readRecordFunc := func(int64) {} @@ -139,10 +171,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } var bw bodyWrapper - // if request body is nil we don't want to mutate the body as it will affect - // the identity of it in a unforeseeable way because we assert ReadCloser - // fullfills a certain interface and it is indeed nil. - if r.Body != nil { + // if request body is nil or NoBody, we don't want to mutate the body as it + // will affect the identity of it in an unforeseeable way because we assert + // ReadCloser fulfills a certain interface and it is indeed nil or NoBody. + if r.Body != nil && r.Body != http.NoBody { bw.ReadCloser = r.Body bw.record = readRecordFunc r.Body = &bw @@ -155,7 +187,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } - rww := &respWriterWrapper{ResponseWriter: w, record: writeRecordFunc, ctx: ctx, props: h.propagators} + rww := &respWriterWrapper{ + ResponseWriter: w, + record: writeRecordFunc, + ctx: ctx, + props: h.propagators, + statusCode: http.StatusOK, // default status code in case the Handler doesn't write anything + } // Wrap w to use our ResponseWriter methods while also exposing // other interfaces that w may implement (http.CloseNotifier, @@ -176,18 +214,23 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { labeler := &Labeler{} ctx = injectLabeler(ctx, labeler) - h.handler.ServeHTTP(w, r.WithContext(ctx)) + next.ServeHTTP(w, r.WithContext(ctx)) setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err) // Add metrics - attributes := append(labeler.Get(), semconv.HTTPServerMetricAttributesFromHTTPRequest(h.operation, r)...) - h.counters[RequestContentLength].Add(ctx, bw.read, attributes...) - h.counters[ResponseContentLength].Add(ctx, rww.written, attributes...) + attributes := append(labeler.Get(), semconvutil.HTTPServerRequestMetrics(h.server, r)...) + if rww.statusCode > 0 { + attributes = append(attributes, semconv.HTTPStatusCode(rww.statusCode)) + } + o := metric.WithAttributes(attributes...) + h.counters[RequestContentLength].Add(ctx, bw.read, o) + h.counters[ResponseContentLength].Add(ctx, rww.written, o) - elapsedTime := time.Since(requestStartTime).Microseconds() + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond) - h.valueRecorders[ServerLatency].Record(ctx, elapsedTime, attributes...) + h.valueRecorders[ServerLatency].Record(ctx, elapsedTime, o) } func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, rerr, werr error) { @@ -205,21 +248,28 @@ func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, attributes = append(attributes, WroteBytesKey.Int64(wrote)) } if statusCode > 0 { - attributes = append(attributes, semconv.HTTPAttributesFromHTTPStatusCode(statusCode)...) - span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(statusCode)) + attributes = append(attributes, semconv.HTTPStatusCode(statusCode)) } + span.SetStatus(semconvutil.HTTPServerStatus(statusCode)) + if werr != nil && werr != io.EOF { attributes = append(attributes, WriteErrorKey.String(werr.Error())) } span.SetAttributes(attributes...) } -// WithRouteTag annotates a span with the provided route name using the -// RouteKey Tag. +// WithRouteTag annotates spans and metrics with the provided route name +// with HTTP route attribute. func WithRouteTag(route string, h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + attr := semconv.HTTPRouteKey.String(route) + span := trace.SpanFromContext(r.Context()) - span.SetAttributes(semconv.HTTPRouteKey.String(route)) + span.SetAttributes(attr) + + labeler, _ := LabelerFromContext(r.Context()) + labeler.Add(attr) + h.ServeHTTP(w, r) }) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/gen.go new file mode 100644 index 00000000000..edf4ce3d315 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/gen.go @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconvutil // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" + +// Generate semconvutil package: +//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/httpconv_test.go.tmpl "--data={}" --out=httpconv_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/httpconv.go.tmpl "--data={}" --out=httpconv.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/netconv_test.go.tmpl "--data={}" --out=netconv_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/netconv.go.tmpl "--data={}" --out=netconv.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go new file mode 100644 index 00000000000..d3dede9ebbd --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go @@ -0,0 +1,552 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconvutil/httpconv.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconvutil // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" + +import ( + "fmt" + "net/http" + "strings" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" +) + +// HTTPClientResponse returns trace attributes for an HTTP response received by a +// client from a server. It will return the following attributes if the related +// values are defined in resp: "http.status.code", +// "http.response_content_length". +// +// This does not add all OpenTelemetry required attributes for an HTTP event, +// it assumes ClientRequest was used to create the span with a complete set of +// attributes. If a complete set of attributes can be generated using the +// request contained in resp. For example: +// +// append(HTTPClientResponse(resp), ClientRequest(resp.Request)...) +func HTTPClientResponse(resp *http.Response) []attribute.KeyValue { + return hc.ClientResponse(resp) +} + +// HTTPClientRequest returns trace attributes for an HTTP request made by a client. +// The following attributes are always returned: "http.url", "http.flavor", +// "http.method", "net.peer.name". The following attributes are returned if the +// related values are defined in req: "net.peer.port", "http.user_agent", +// "http.request_content_length", "enduser.id". +func HTTPClientRequest(req *http.Request) []attribute.KeyValue { + return hc.ClientRequest(req) +} + +// HTTPClientStatus returns a span status code and message for an HTTP status code +// value received by a client. +func HTTPClientStatus(code int) (codes.Code, string) { + return hc.ClientStatus(code) +} + +// HTTPServerRequest returns trace attributes for an HTTP request received by a +// server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "http.target", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port", +// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", +// "http.client_ip". +func HTTPServerRequest(server string, req *http.Request) []attribute.KeyValue { + return hc.ServerRequest(server, req) +} + +// HTTPServerRequestMetrics returns metric attributes for an HTTP request received by a +// server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port". +func HTTPServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue { + return hc.ServerRequestMetrics(server, req) +} + +// HTTPServerStatus returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func HTTPServerStatus(code int) (codes.Code, string) { + return hc.ServerStatus(code) +} + +// HTTPRequestHeader returns the contents of h as attributes. +// +// Instrumentation should require an explicit configuration of which headers to +// captured and then prune what they pass here. Including all headers can be a +// security risk - explicit configuration helps avoid leaking sensitive +// information. +// +// The User-Agent header is already captured in the http.user_agent attribute +// from ClientRequest and ServerRequest. Instrumentation may provide an option +// to capture that header here even though it is not recommended. Otherwise, +// instrumentation should filter that out of what is passed. +func HTTPRequestHeader(h http.Header) []attribute.KeyValue { + return hc.RequestHeader(h) +} + +// HTTPResponseHeader returns the contents of h as attributes. +// +// Instrumentation should require an explicit configuration of which headers to +// captured and then prune what they pass here. Including all headers can be a +// security risk - explicit configuration helps avoid leaking sensitive +// information. +// +// The User-Agent header is already captured in the http.user_agent attribute +// from ClientRequest and ServerRequest. Instrumentation may provide an option +// to capture that header here even though it is not recommended. Otherwise, +// instrumentation should filter that out of what is passed. +func HTTPResponseHeader(h http.Header) []attribute.KeyValue { + return hc.ResponseHeader(h) +} + +// httpConv are the HTTP semantic convention attributes defined for a version +// of the OpenTelemetry specification. +type httpConv struct { + NetConv *netConv + + EnduserIDKey attribute.Key + HTTPClientIPKey attribute.Key + HTTPFlavorKey attribute.Key + HTTPMethodKey attribute.Key + HTTPRequestContentLengthKey attribute.Key + HTTPResponseContentLengthKey attribute.Key + HTTPRouteKey attribute.Key + HTTPSchemeHTTP attribute.KeyValue + HTTPSchemeHTTPS attribute.KeyValue + HTTPStatusCodeKey attribute.Key + HTTPTargetKey attribute.Key + HTTPURLKey attribute.Key + HTTPUserAgentKey attribute.Key +} + +var hc = &httpConv{ + NetConv: nc, + + EnduserIDKey: semconv.EnduserIDKey, + HTTPClientIPKey: semconv.HTTPClientIPKey, + HTTPFlavorKey: semconv.HTTPFlavorKey, + HTTPMethodKey: semconv.HTTPMethodKey, + HTTPRequestContentLengthKey: semconv.HTTPRequestContentLengthKey, + HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey, + HTTPRouteKey: semconv.HTTPRouteKey, + HTTPSchemeHTTP: semconv.HTTPSchemeHTTP, + HTTPSchemeHTTPS: semconv.HTTPSchemeHTTPS, + HTTPStatusCodeKey: semconv.HTTPStatusCodeKey, + HTTPTargetKey: semconv.HTTPTargetKey, + HTTPURLKey: semconv.HTTPURLKey, + HTTPUserAgentKey: semconv.HTTPUserAgentKey, +} + +// ClientResponse returns attributes for an HTTP response received by a client +// from a server. The following attributes are returned if the related values +// are defined in resp: "http.status.code", "http.response_content_length". +// +// This does not add all OpenTelemetry required attributes for an HTTP event, +// it assumes ClientRequest was used to create the span with a complete set of +// attributes. If a complete set of attributes can be generated using the +// request contained in resp. For example: +// +// append(ClientResponse(resp), ClientRequest(resp.Request)...) +func (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue { + var n int + if resp.StatusCode > 0 { + n++ + } + if resp.ContentLength > 0 { + n++ + } + + attrs := make([]attribute.KeyValue, 0, n) + if resp.StatusCode > 0 { + attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode)) + } + if resp.ContentLength > 0 { + attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength))) + } + return attrs +} + +// ClientRequest returns attributes for an HTTP request made by a client. The +// following attributes are always returned: "http.url", "http.flavor", +// "http.method", "net.peer.name". The following attributes are returned if the +// related values are defined in req: "net.peer.port", "http.user_agent", +// "http.request_content_length", "enduser.id". +func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue { + n := 3 // URL, peer name, proto, and method. + var h string + if req.URL != nil { + h = req.URL.Host + } + peer, p := firstHostPort(h, req.Header.Get("Host")) + port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p) + if port > 0 { + n++ + } + useragent := req.UserAgent() + if useragent != "" { + n++ + } + if req.ContentLength > 0 { + n++ + } + userID, _, hasUserID := req.BasicAuth() + if hasUserID { + n++ + } + attrs := make([]attribute.KeyValue, 0, n) + + attrs = append(attrs, c.method(req.Method)) + attrs = append(attrs, c.flavor(req.Proto)) + + var u string + if req.URL != nil { + // Remove any username/password info that may be in the URL. + userinfo := req.URL.User + req.URL.User = nil + u = req.URL.String() + // Restore any username/password info that was removed. + req.URL.User = userinfo + } + attrs = append(attrs, c.HTTPURLKey.String(u)) + + attrs = append(attrs, c.NetConv.PeerName(peer)) + if port > 0 { + attrs = append(attrs, c.NetConv.PeerPort(port)) + } + + if useragent != "" { + attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) + } + + if l := req.ContentLength; l > 0 { + attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l)) + } + + if hasUserID { + attrs = append(attrs, c.EnduserIDKey.String(userID)) + } + + return attrs +} + +// ServerRequest returns attributes for an HTTP request received by a server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "http.target", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port", +// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", +// "http.client_ip". +func (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue { + // TODO: This currently does not add the specification required + // `http.target` attribute. It has too high of a cardinality to safely be + // added. An alternate should be added, or this comment removed, when it is + // addressed by the specification. If it is ultimately decided to continue + // not including the attribute, the HTTPTargetKey field of the httpConv + // should be removed as well. + + n := 4 // Method, scheme, proto, and host name. + var host string + var p int + if server == "" { + host, p = splitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = splitHostPort(server) + if p < 0 { + _, p = splitHostPort(req.Host) + } + } + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + n++ + } + peer, peerPort := splitHostPort(req.RemoteAddr) + if peer != "" { + n++ + if peerPort > 0 { + n++ + } + } + useragent := req.UserAgent() + if useragent != "" { + n++ + } + userID, _, hasUserID := req.BasicAuth() + if hasUserID { + n++ + } + clientIP := serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP != "" { + n++ + } + attrs := make([]attribute.KeyValue, 0, n) + + attrs = append(attrs, c.method(req.Method)) + attrs = append(attrs, c.scheme(req.TLS != nil)) + attrs = append(attrs, c.flavor(req.Proto)) + attrs = append(attrs, c.NetConv.HostName(host)) + + if hostPort > 0 { + attrs = append(attrs, c.NetConv.HostPort(hostPort)) + } + + if peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + attrs = append(attrs, c.NetConv.SockPeerAddr(peer)) + if peerPort > 0 { + attrs = append(attrs, c.NetConv.SockPeerPort(peerPort)) + } + } + + if useragent != "" { + attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) + } + + if hasUserID { + attrs = append(attrs, c.EnduserIDKey.String(userID)) + } + + if clientIP != "" { + attrs = append(attrs, c.HTTPClientIPKey.String(clientIP)) + } + + return attrs +} + +// ServerRequestMetrics returns metric attributes for an HTTP request received +// by a server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port". +func (c *httpConv) ServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue { + // TODO: This currently does not add the specification required + // `http.target` attribute. It has too high of a cardinality to safely be + // added. An alternate should be added, or this comment removed, when it is + // addressed by the specification. If it is ultimately decided to continue + // not including the attribute, the HTTPTargetKey field of the httpConv + // should be removed as well. + + n := 4 // Method, scheme, proto, and host name. + var host string + var p int + if server == "" { + host, p = splitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = splitHostPort(server) + if p < 0 { + _, p = splitHostPort(req.Host) + } + } + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + n++ + } + attrs := make([]attribute.KeyValue, 0, n) + + attrs = append(attrs, c.methodMetric(req.Method)) + attrs = append(attrs, c.scheme(req.TLS != nil)) + attrs = append(attrs, c.flavor(req.Proto)) + attrs = append(attrs, c.NetConv.HostName(host)) + + if hostPort > 0 { + attrs = append(attrs, c.NetConv.HostPort(hostPort)) + } + + return attrs +} + +func (c *httpConv) method(method string) attribute.KeyValue { + if method == "" { + return c.HTTPMethodKey.String(http.MethodGet) + } + return c.HTTPMethodKey.String(method) +} + +func (c *httpConv) methodMetric(method string) attribute.KeyValue { + method = strings.ToUpper(method) + switch method { + case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace: + default: + method = "_OTHER" + } + return c.HTTPMethodKey.String(method) +} + +func (c *httpConv) scheme(https bool) attribute.KeyValue { // nolint:revive + if https { + return c.HTTPSchemeHTTPS + } + return c.HTTPSchemeHTTP +} + +func (c *httpConv) flavor(proto string) attribute.KeyValue { + switch proto { + case "HTTP/1.0": + return c.HTTPFlavorKey.String("1.0") + case "HTTP/1.1": + return c.HTTPFlavorKey.String("1.1") + case "HTTP/2": + return c.HTTPFlavorKey.String("2.0") + case "HTTP/3": + return c.HTTPFlavorKey.String("3.0") + default: + return c.HTTPFlavorKey.String(proto) + } +} + +func serverClientIP(xForwardedFor string) string { + if idx := strings.Index(xForwardedFor, ","); idx >= 0 { + xForwardedFor = xForwardedFor[:idx] + } + return xForwardedFor +} + +func requiredHTTPPort(https bool, port int) int { // nolint:revive + if https { + if port > 0 && port != 443 { + return port + } + } else { + if port > 0 && port != 80 { + return port + } + } + return -1 +} + +// Return the request host and port from the first non-empty source. +func firstHostPort(source ...string) (host string, port int) { + for _, hostport := range source { + host, port = splitHostPort(hostport) + if host != "" || port > 0 { + break + } + } + return +} + +// RequestHeader returns the contents of h as OpenTelemetry attributes. +func (c *httpConv) RequestHeader(h http.Header) []attribute.KeyValue { + return c.header("http.request.header", h) +} + +// ResponseHeader returns the contents of h as OpenTelemetry attributes. +func (c *httpConv) ResponseHeader(h http.Header) []attribute.KeyValue { + return c.header("http.response.header", h) +} + +func (c *httpConv) header(prefix string, h http.Header) []attribute.KeyValue { + key := func(k string) attribute.Key { + k = strings.ToLower(k) + k = strings.ReplaceAll(k, "-", "_") + k = fmt.Sprintf("%s.%s", prefix, k) + return attribute.Key(k) + } + + attrs := make([]attribute.KeyValue, 0, len(h)) + for k, v := range h { + attrs = append(attrs, key(k).StringSlice(v)) + } + return attrs +} + +// ClientStatus returns a span status code and message for an HTTP status code +// value received by a client. +func (c *httpConv) ClientStatus(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 400 { + return codes.Error, "" + } + return codes.Unset, "" +} + +// ServerStatus returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func (c *httpConv) ServerStatus(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 500 { + return codes.Error, "" + } + return codes.Unset, "" +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go new file mode 100644 index 00000000000..bde8893437d --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go @@ -0,0 +1,368 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconvutil/netconv.go.tmpl + +// Copyright The OpenTelemetry Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconvutil // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" + +import ( + "net" + "strconv" + "strings" + + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" +) + +// NetTransport returns a trace attribute describing the transport protocol of the +// passed network. See the net.Dial for information about acceptable network +// values. +func NetTransport(network string) attribute.KeyValue { + return nc.Transport(network) +} + +// NetClient returns trace attributes for a client network connection to address. +// See net.Dial for information about acceptable address values, address should +// be the same as the one used to create conn. If conn is nil, only network +// peer attributes will be returned that describe address. Otherwise, the +// socket level information about conn will also be included. +func NetClient(address string, conn net.Conn) []attribute.KeyValue { + return nc.Client(address, conn) +} + +// NetServer returns trace attributes for a network listener listening at address. +// See net.Listen for information about acceptable address values, address +// should be the same as the one used to create ln. If ln is nil, only network +// host attributes will be returned that describe address. Otherwise, the +// socket level information about ln will also be included. +func NetServer(address string, ln net.Listener) []attribute.KeyValue { + return nc.Server(address, ln) +} + +// netConv are the network semantic convention attributes defined for a version +// of the OpenTelemetry specification. +type netConv struct { + NetHostNameKey attribute.Key + NetHostPortKey attribute.Key + NetPeerNameKey attribute.Key + NetPeerPortKey attribute.Key + NetSockFamilyKey attribute.Key + NetSockPeerAddrKey attribute.Key + NetSockPeerPortKey attribute.Key + NetSockHostAddrKey attribute.Key + NetSockHostPortKey attribute.Key + NetTransportOther attribute.KeyValue + NetTransportTCP attribute.KeyValue + NetTransportUDP attribute.KeyValue + NetTransportInProc attribute.KeyValue +} + +var nc = &netConv{ + NetHostNameKey: semconv.NetHostNameKey, + NetHostPortKey: semconv.NetHostPortKey, + NetPeerNameKey: semconv.NetPeerNameKey, + NetPeerPortKey: semconv.NetPeerPortKey, + NetSockFamilyKey: semconv.NetSockFamilyKey, + NetSockPeerAddrKey: semconv.NetSockPeerAddrKey, + NetSockPeerPortKey: semconv.NetSockPeerPortKey, + NetSockHostAddrKey: semconv.NetSockHostAddrKey, + NetSockHostPortKey: semconv.NetSockHostPortKey, + NetTransportOther: semconv.NetTransportOther, + NetTransportTCP: semconv.NetTransportTCP, + NetTransportUDP: semconv.NetTransportUDP, + NetTransportInProc: semconv.NetTransportInProc, +} + +func (c *netConv) Transport(network string) attribute.KeyValue { + switch network { + case "tcp", "tcp4", "tcp6": + return c.NetTransportTCP + case "udp", "udp4", "udp6": + return c.NetTransportUDP + case "unix", "unixgram", "unixpacket": + return c.NetTransportInProc + default: + // "ip:*", "ip4:*", and "ip6:*" all are considered other. + return c.NetTransportOther + } +} + +// Host returns attributes for a network host address. +func (c *netConv) Host(address string) []attribute.KeyValue { + h, p := splitHostPort(address) + var n int + if h != "" { + n++ + if p > 0 { + n++ + } + } + + if n == 0 { + return nil + } + + attrs := make([]attribute.KeyValue, 0, n) + attrs = append(attrs, c.HostName(h)) + if p > 0 { + attrs = append(attrs, c.HostPort(int(p))) + } + return attrs +} + +// Server returns attributes for a network listener listening at address. See +// net.Listen for information about acceptable address values, address should +// be the same as the one used to create ln. If ln is nil, only network host +// attributes will be returned that describe address. Otherwise, the socket +// level information about ln will also be included. +func (c *netConv) Server(address string, ln net.Listener) []attribute.KeyValue { + if ln == nil { + return c.Host(address) + } + + lAddr := ln.Addr() + if lAddr == nil { + return c.Host(address) + } + + hostName, hostPort := splitHostPort(address) + sockHostAddr, sockHostPort := splitHostPort(lAddr.String()) + network := lAddr.Network() + sockFamily := family(network, sockHostAddr) + + n := nonZeroStr(hostName, network, sockHostAddr, sockFamily) + n += positiveInt(hostPort, sockHostPort) + attr := make([]attribute.KeyValue, 0, n) + if hostName != "" { + attr = append(attr, c.HostName(hostName)) + if hostPort > 0 { + // Only if net.host.name is set should net.host.port be. + attr = append(attr, c.HostPort(hostPort)) + } + } + if network != "" { + attr = append(attr, c.Transport(network)) + } + if sockFamily != "" { + attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) + } + if sockHostAddr != "" { + attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) + if sockHostPort > 0 { + // Only if net.sock.host.addr is set should net.sock.host.port be. + attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) + } + } + return attr +} + +func (c *netConv) HostName(name string) attribute.KeyValue { + return c.NetHostNameKey.String(name) +} + +func (c *netConv) HostPort(port int) attribute.KeyValue { + return c.NetHostPortKey.Int(port) +} + +// Client returns attributes for a client network connection to address. See +// net.Dial for information about acceptable address values, address should be +// the same as the one used to create conn. If conn is nil, only network peer +// attributes will be returned that describe address. Otherwise, the socket +// level information about conn will also be included. +func (c *netConv) Client(address string, conn net.Conn) []attribute.KeyValue { + if conn == nil { + return c.Peer(address) + } + + lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr() + + var network string + switch { + case lAddr != nil: + network = lAddr.Network() + case rAddr != nil: + network = rAddr.Network() + default: + return c.Peer(address) + } + + peerName, peerPort := splitHostPort(address) + var ( + sockFamily string + sockPeerAddr string + sockPeerPort int + sockHostAddr string + sockHostPort int + ) + + if lAddr != nil { + sockHostAddr, sockHostPort = splitHostPort(lAddr.String()) + } + + if rAddr != nil { + sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String()) + } + + switch { + case sockHostAddr != "": + sockFamily = family(network, sockHostAddr) + case sockPeerAddr != "": + sockFamily = family(network, sockPeerAddr) + } + + n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily) + n += positiveInt(peerPort, sockPeerPort, sockHostPort) + attr := make([]attribute.KeyValue, 0, n) + if peerName != "" { + attr = append(attr, c.PeerName(peerName)) + if peerPort > 0 { + // Only if net.peer.name is set should net.peer.port be. + attr = append(attr, c.PeerPort(peerPort)) + } + } + if network != "" { + attr = append(attr, c.Transport(network)) + } + if sockFamily != "" { + attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) + } + if sockPeerAddr != "" { + attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr)) + if sockPeerPort > 0 { + // Only if net.sock.peer.addr is set should net.sock.peer.port be. + attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort)) + } + } + if sockHostAddr != "" { + attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) + if sockHostPort > 0 { + // Only if net.sock.host.addr is set should net.sock.host.port be. + attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) + } + } + return attr +} + +func family(network, address string) string { + switch network { + case "unix", "unixgram", "unixpacket": + return "unix" + default: + if ip := net.ParseIP(address); ip != nil { + if ip.To4() == nil { + return "inet6" + } + return "inet" + } + } + return "" +} + +func nonZeroStr(strs ...string) int { + var n int + for _, str := range strs { + if str != "" { + n++ + } + } + return n +} + +func positiveInt(ints ...int) int { + var n int + for _, i := range ints { + if i > 0 { + n++ + } + } + return n +} + +// Peer returns attributes for a network peer address. +func (c *netConv) Peer(address string) []attribute.KeyValue { + h, p := splitHostPort(address) + var n int + if h != "" { + n++ + if p > 0 { + n++ + } + } + + if n == 0 { + return nil + } + + attrs := make([]attribute.KeyValue, 0, n) + attrs = append(attrs, c.PeerName(h)) + if p > 0 { + attrs = append(attrs, c.PeerPort(int(p))) + } + return attrs +} + +func (c *netConv) PeerName(name string) attribute.KeyValue { + return c.NetPeerNameKey.String(name) +} + +func (c *netConv) PeerPort(port int) attribute.KeyValue { + return c.NetPeerPortKey.Int(port) +} + +func (c *netConv) SockPeerAddr(addr string) attribute.KeyValue { + return c.NetSockPeerAddrKey.String(addr) +} + +func (c *netConv) SockPeerPort(port int) attribute.KeyValue { + return c.NetSockPeerPortKey.Int(port) +} + +// splitHostPort splits a network address hostport of the form "host", +// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port", +// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and +// port. +// +// An empty host is returned if it is not provided or unparsable. A negative +// port is returned if it is not provided or unparsable. +func splitHostPort(hostport string) (host string, port int) { + port = -1 + + if strings.HasPrefix(hostport, "[") { + addrEnd := strings.LastIndex(hostport, "]") + if addrEnd < 0 { + // Invalid hostport. + return + } + if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 { + host = hostport[1:addrEnd] + return + } + } else { + if i := strings.LastIndex(hostport, ":"); i < 0 { + host = hostport + return + } + } + + host, pStr, err := net.SplitHostPort(hostport) + if err != nil { + return + } + + p, err := strconv.ParseUint(pStr, 10, 16) + if err != nil { + return + } + return host, int(p) +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go index a1d102e769e..26a51a18050 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "context" @@ -35,7 +35,7 @@ func (l *Labeler) Add(ls ...attribute.KeyValue) { l.attributes = append(l.attributes, ls...) } -// Labels returns a copy of the attributes added to the Labeler. +// Get returns a copy of the attributes added to the Labeler. func (l *Labeler) Get() []attribute.KeyValue { l.mu.Lock() defer l.mu.Unlock() diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go index 4c855bfb477..e835cac12e4 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go @@ -12,15 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "context" "io" "net/http" + "net/http/httptrace" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/semconv" "go.opentelemetry.io/otel/trace" ) @@ -31,9 +34,10 @@ type Transport struct { tracer trace.Tracer propagators propagation.TextMapPropagator - spanStartOptions []trace.SpanOption + spanStartOptions []trace.SpanStartOption filters []Filter spanNameFormatter func(string, *http.Request) string + clientTrace func(context.Context) *httptrace.ClientTrace } var _ http.RoundTripper = &Transport{} @@ -42,7 +46,7 @@ var _ http.RoundTripper = &Transport{} // starts a span and injects the span context into the outbound request headers. // // If the provided http.RoundTripper is nil, http.DefaultTransport will be used -// as the base http.RoundTripper +// as the base http.RoundTripper. func NewTransport(base http.RoundTripper, opts ...Option) *Transport { if base == nil { base = http.DefaultTransport @@ -69,10 +73,11 @@ func (t *Transport) applyConfig(c *config) { t.spanStartOptions = c.SpanStartOptions t.filters = c.Filters t.spanNameFormatter = c.SpanNameFormatter + t.clientTrace = c.ClientTrace } func defaultTransportFormatter(_ string, r *http.Request) string { - return r.Method + return "HTTP " + r.Method } // RoundTrip creates a Span and propagates its context via the provided request's headers @@ -86,35 +91,83 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { } } - opts := append([]trace.SpanOption{}, t.spanStartOptions...) // start with the configured options + tracer := t.tracer - ctx, span := t.tracer.Start(r.Context(), t.spanNameFormatter("", r), opts...) + if tracer == nil { + if span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() { + tracer = newTracer(span.TracerProvider()) + } else { + tracer = newTracer(otel.GetTracerProvider()) + } + } + + opts := append([]trace.SpanStartOption{}, t.spanStartOptions...) // start with the configured options + + ctx, span := tracer.Start(r.Context(), t.spanNameFormatter("", r), opts...) + + if t.clientTrace != nil { + ctx = httptrace.WithClientTrace(ctx, t.clientTrace(ctx)) + } - r = r.WithContext(ctx) - span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest(r)...) + r = r.Clone(ctx) // According to RoundTripper spec, we shouldn't modify the origin request. + span.SetAttributes(semconvutil.HTTPClientRequest(r)...) t.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header)) res, err := t.rt.RoundTrip(r) if err != nil { span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) span.End() return res, err } - span.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(res.StatusCode)...) - span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(res.StatusCode)) - res.Body = &wrappedBody{ctx: ctx, span: span, body: res.Body} + span.SetAttributes(semconvutil.HTTPClientResponse(res)...) + span.SetStatus(semconvutil.HTTPClientStatus(res.StatusCode)) + res.Body = newWrappedBody(span, res.Body) return res, err } +// newWrappedBody returns a new and appropriately scoped *wrappedBody as an +// io.ReadCloser. If the passed body implements io.Writer, the returned value +// will implement io.ReadWriteCloser. +func newWrappedBody(span trace.Span, body io.ReadCloser) io.ReadCloser { + // The successful protocol switch responses will have a body that + // implement an io.ReadWriteCloser. Ensure this interface type continues + // to be satisfied if that is the case. + if _, ok := body.(io.ReadWriteCloser); ok { + return &wrappedBody{span: span, body: body} + } + + // Remove the implementation of the io.ReadWriteCloser and only implement + // the io.ReadCloser. + return struct{ io.ReadCloser }{&wrappedBody{span: span, body: body}} +} + +// wrappedBody is the response body type returned by the transport +// instrumentation to complete a span. Errors encountered when using the +// response body are recorded in span tracking the response. +// +// The span tracking the response is ended when this body is closed. +// +// If the response body implements the io.Writer interface (i.e. for +// successful protocol switches), the wrapped body also will. type wrappedBody struct { - ctx context.Context span trace.Span body io.ReadCloser } -var _ io.ReadCloser = &wrappedBody{} +var _ io.ReadWriteCloser = &wrappedBody{} + +func (wb *wrappedBody) Write(p []byte) (int, error) { + // This will not panic given the guard in newWrappedBody. + n, err := wb.body.(io.Writer).Write(p) + if err != nil { + wb.span.RecordError(err) + wb.span.SetStatus(codes.Error, err.Error()) + } + return n, err +} func (wb *wrappedBody) Read(b []byte) (int, error) { n, err := wb.body.Read(b) @@ -126,11 +179,15 @@ func (wb *wrappedBody) Read(b []byte) (int, error) { wb.span.End() default: wb.span.RecordError(err) + wb.span.SetStatus(codes.Error, err.Error()) } return n, err } func (wb *wrappedBody) Close() error { wb.span.End() - return wb.body.Close() + if wb.body != nil { + return wb.body.Close() + } + return nil } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go new file mode 100644 index 00000000000..6eace875cfe --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + +// Version is the current release version of the otelhttp instrumentation. +func Version() string { + return "0.45.0" + // This string is updated by the pre_release.sh script during release +} + +// SemVersion is the semantic version to be supplied to tracer/meter creation. +// +// Deprecated: Use [Version] instead. +func SemVersion() string { + return Version() +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go index ec787c820a0..11a35ed167f 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package otelhttp +package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" import ( "context" @@ -25,7 +25,7 @@ import ( var _ io.ReadCloser = &bodyWrapper{} // bodyWrapper wraps a http.Request.Body (an io.ReadCloser) to track the number -// of bytes read and the last error +// of bytes read and the last error. type bodyWrapper struct { io.ReadCloser record func(n int64) // must not be nil @@ -50,7 +50,7 @@ func (w *bodyWrapper) Close() error { var _ http.ResponseWriter = &respWriterWrapper{} // respWriterWrapper wraps a http.ResponseWriter in order to track the number of -// bytes written, the last error, and to catch the returned statusCode +// bytes written, the last error, and to catch the first written statusCode. // TODO: The wrapped http.ResponseWriter doesn't implement any of the optional // types (http.Hijacker, http.Pusher, http.CloseNotifier, http.Flusher, etc) // that may be useful when using it in real life situations. @@ -85,12 +85,15 @@ func (w *respWriterWrapper) Write(p []byte) (int, error) { return n, err } +// WriteHeader persists initial statusCode for span attribution. +// All calls to WriteHeader will be propagated to the underlying ResponseWriter +// and will persist the statusCode from the first call. +// Blocking consecutive calls to WriteHeader alters expected behavior and will +// remove warning logs from net/http where developers will notice incorrect handler implementations. func (w *respWriterWrapper) WriteHeader(statusCode int) { - if w.wroteHeader { - return + if !w.wroteHeader { + w.wroteHeader = true + w.statusCode = statusCode } - w.wroteHeader = true - w.statusCode = statusCode - w.props.Inject(w.ctx, propagation.HeaderCarrier(w.Header())) w.ResponseWriter.WriteHeader(statusCode) } diff --git a/vendor/go.opentelemetry.io/contrib/pre_release.sh b/vendor/go.opentelemetry.io/contrib/pre_release.sh deleted file mode 100644 index 971e86b4db2..00000000000 --- a/vendor/go.opentelemetry.io/contrib/pre_release.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash - -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# This script is used for -# a) creating a new tagged release of go.opentelemetry.io/contrib -# b) bumping the referenced version of go.opentelemetry.io/otel -# -# The options can be used together or individually. -# -set -e - -declare CONTRIB_TAG -declare OTEL_TAG - -help() { - printf "\n" - printf "Usage: %s [-o otel_tag] [-t tag]\n" "$0" - printf "\t-o Otel release tag. Update all go.mod to reference go.opentelemetry.io/otel .\n" - printf "\t-t New Contrib unreleased tag. Update all go.mod files with this tag.\n" - exit 1 # Exit script after printing help -} - -while getopts "t:o:" opt -do - case "$opt" in - t ) CONTRIB_TAG="$OPTARG" ;; - o ) OTEL_TAG="$OPTARG" ;; - ? ) help ;; # Print help - esac -done - -declare -r SEMVER_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" - -validate_tag() { - local tag_=$1 - if [[ "${tag_}" =~ ${SEMVER_REGEX} ]]; then - printf "%s is valid semver tag.\n" "${tag_}" - else - printf "%s is not a valid semver tag.\n" "${tag_}" - return 1 - fi -} - -# Print help in case parameters are empty -if [[ -z "$CONTRIB_TAG" && -z "$OTEL_TAG" ]] -then - printf "At least one of '-o' or '-t' must be specified.\n" - help -fi - - -## Validate tags first -if [ -n "${OTEL_TAG}" ]; then - validate_tag "${OTEL_TAG}" || exit $? - - # check that OTEL_TAG is a currently released tag for go.opentelemetry.io/otel - TMPDIR=$(mktemp -d "/tmp/otel-contrib.XXXXXX") || exit 1 - trap "rm -fr ${TMPDIR}" EXIT - (cd "${TMPDIR}" && go mod init tagtest) - # requires go 1.14 for support of '-modfile' - if ! go get -modfile="${TMPDIR}/go.mod" -d -v "go.opentelemetry.io/otel@${OTEL_TAG}"; then - printf "go.opentelemetry.io/otel %s does not exist. Please supply a valid tag\n" "${OTEL_TAG}" - exit 1 - fi -fi -if [ -n "${CONTRIB_TAG}" ]; then - validate_tag "${CONTRIB_TAG}" || exit $? - TAG_FOUND=$(git tag --list "${CONTRIB_TAG}") - if [[ ${TAG_FOUND} = "${CONTRIB_TAG}" ]] ; then - printf "Tag %s already exists in this repo\n" "${CONTRIB_TAG}" - exit 1 - fi -else - CONTRIB_TAG=${OTEL_TAG} # if contrib_tag not specified, but OTEL_TAG is, then set it to OTEL_TAG -fi - -# Get version for contrib.go -OTEL_CONTRIB_VERSION=$(echo "${CONTRIB_TAG}" | egrep -o "${SEMVER_REGEX}") -# Strip leading v -OTEL_CONTRIB_VERSION="${OTEL_CONTRIB_VERSION#v}" - -cd "$(dirname "$0")" - -if ! git diff --quiet; then \ - printf "Working tree is not clean, can't proceed\n" - git status - git diff - exit 1 -fi - -# Update contrib.go version definition -cp contrib.go contrib.go.bak -sed "s/\(return \"\)[0-9]*\.[0-9]*\.[0-9]*\"/\1${OTEL_CONTRIB_VERSION}\"/" ./contrib.go.bak > ./contrib.go -rm -f ./contrib.go.bak - -declare -r BRANCH_NAME=pre_release_${CONTRIB_TAG} - -patch_gomods() { - local pkg_=$1 - local tag_=$2 - # now do the same for all the directories underneath - PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | egrep -v 'tools' | sed 's|^\.\/||' | sort) - # quote any '.' characters in the pkg name - local quoted_pkg_=${pkg_//./\\.} - for dir in $PACKAGE_DIRS; do - cp "${dir}/go.mod" "${dir}/go.mod.bak" - sed "s|${quoted_pkg_}\([^ ]*\) v[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*[^0-9]*.*$|${pkg_}\1 ${tag_}|" "${dir}/go.mod.bak" >"${dir}/go.mod" - rm -f "${dir}/go.mod.bak" - done -} - -# branch off from existing main -git checkout -b "${BRANCH_NAME}" main - -# Update go.mods -if [ -n "${OTEL_TAG}" ]; then - # first update the top most module - go get "go.opentelemetry.io/otel@${OTEL_TAG}" - patch_gomods go.opentelemetry.io/otel "${OTEL_TAG}" -fi - -if [ -n "${CONTRIB_TAG}" ]; then - patch_gomods go.opentelemetry.io/contrib "${CONTRIB_TAG}" -fi - -git diff -# Run lint to update go.sum -make lint - -# Add changes and commit. -git add . -make ci -# Check whether registry links are up to date -make registry-links-check - -declare COMMIT_MSG="" -if [ -n "${OTEL_TAG}" ]; then - COMMIT_MSG+="Bumping otel version to ${OTEL_TAG}" -fi -COMMIT_MSG+=". Prepare for releasing ${CONTRIB_TAG}" -git commit -m "${COMMIT_MSG}" - -printf "Now run following to verify the changes.\ngit diff main\n" -printf "\nThen push the changes to upstream\n" diff --git a/vendor/go.opentelemetry.io/contrib/tag.sh b/vendor/go.opentelemetry.io/contrib/tag.sh deleted file mode 100644 index 2a0ef1d26c2..00000000000 --- a/vendor/go.opentelemetry.io/contrib/tag.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash - -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly PROGNAME=$(basename "$0") -readonly PROGDIR=$(readlink -m "$(dirname "$0")") - -readonly EXCLUDE_PACKAGES="tools" -readonly SEMVER_REGEX="v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?" - -usage() { - cat <<- EOF -Usage: $PROGNAME [OPTIONS] SEMVER_TAG COMMIT_HASH - -Creates git tag for all Go packages in project. - -OPTIONS: - -h --help Show this help. - -ARGUMENTS: - SEMVER_TAG Semantic version to tag with. - COMMIT_HASH Git commit hash to tag. -EOF -} - -cmdline() { - local arg commit - - for arg - do - local delim="" - case "$arg" in - # Translate long form options to short form. - --help) args="${args}-h ";; - # Pass through for everything else. - *) [[ "${arg:0:1}" == "-" ]] || delim="\"" - args="${args}${delim}${arg}${delim} ";; - esac - done - - # Reset and process short form options. - eval set -- "$args" - - while getopts "h" OPTION - do - case $OPTION in - h) - usage - exit 0 - ;; - *) - echo "unknown option: $OPTION" - usage - exit 1 - ;; - esac - done - - # Positional arguments. - shift $((OPTIND-1)) - readonly TAG="$1" - if [ -z "$TAG" ] - then - echo "missing SEMVER_TAG" - usage - exit 1 - fi - if [[ ! "$TAG" =~ $SEMVER_REGEX ]] - then - printf "invalid semantic version: %s\n" "$TAG" - exit 2 - fi - if [[ "$( git tag --list "$TAG" )" ]] - then - printf "tag already exists: %s\n" "$TAG" - exit 2 - fi - - shift - commit="$1" - if [ -z "$commit" ] - then - echo "missing COMMIT_HASH" - usage - exit 1 - fi - # Verify rev is for a commit and unify hashes into a complete SHA1. - readonly SHA="$( git rev-parse --quiet --verify "${commit}^{commit}" )" - if [ -z "$SHA" ] - then - printf "invalid commit hash: %s\n" "$commit" - exit 2 - fi - if [ "$( git merge-base "$SHA" HEAD )" != "$SHA" ] - then - printf "commit '%s' not found on this branch\n" "$commit" - exit 2 - fi -} - -package_dirs() { - # Return a list of package directories in the form: - # - # package/directory/a - # package/directory/b - # deeper/package/directory/a - # ... - # - # Making sure to exclude any packages in the EXCLUDE_PACKAGES regexp. - find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ - | grep -E -v "$EXCLUDE_PACKAGES" \ - | sed 's/^\.\///' \ - | sort -} - -git_tag() { - local tag="$1" - local commit="$2" - - git tag -a "$tag" -s -m "Version $tag" "$commit" -} - -previous_version() { - local current="$1" - - # Requires git > 2.0 - git tag -l --sort=v:refname \ - | grep -E "^${SEMVER_REGEX}$" \ - | grep -v "$current" \ - | tail -1 -} - -print_changes() { - local tag="$1" - local previous - - previous="$( previous_version "$tag" )" - if [ -n "$previous" ] - then - printf "\nRaw changes made between %s and %s\n" "$previous" "$tag" - printf "======================================\n" - git --no-pager log --pretty=oneline "${previous}..$tag" - fi -} - -main() { - local dir - - cmdline "$@" - - cd "$PROGDIR" || exit 3 - - # Create tag for root package. - git_tag "$TAG" "$SHA" - printf "created tag: %s\n" "$TAG" - - # Create tag for all sub-packages. - for dir in $( package_dirs ) - do - git_tag "${dir}/$TAG" "$SHA" - printf "created tag: %s\n" "${dir}/$TAG" - done - - print_changes "$TAG" -} -main "$@" diff --git a/vendor/go.opentelemetry.io/otel/.codespellignore b/vendor/go.opentelemetry.io/otel/.codespellignore new file mode 100644 index 00000000000..ae6a3bcf12c --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/.codespellignore @@ -0,0 +1,5 @@ +ot +fo +te +collison +consequentially diff --git a/vendor/go.opentelemetry.io/otel/.codespellrc b/vendor/go.opentelemetry.io/otel/.codespellrc new file mode 100644 index 00000000000..4afbb1fb3bd --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/.codespellrc @@ -0,0 +1,10 @@ +# https://github.com/codespell-project/codespell +[codespell] +builtin = clear,rare,informal +check-filenames = +check-hidden = +ignore-words = .codespellignore +interactive = 1 +skip = .git,go.mod,go.sum,semconv,venv,.tools +uri-ignore-words-list = * +write = diff --git a/vendor/go.opentelemetry.io/otel/.gitattributes b/vendor/go.opentelemetry.io/otel/.gitattributes new file mode 100644 index 00000000000..314766e91bf --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf diff --git a/vendor/go.opentelemetry.io/otel/.gitignore b/vendor/go.opentelemetry.io/otel/.gitignore index 69f09e575fc..f3355c852be 100644 --- a/vendor/go.opentelemetry.io/otel/.gitignore +++ b/vendor/go.opentelemetry.io/otel/.gitignore @@ -2,18 +2,24 @@ Thumbs.db .tools/ +venv/ .idea/ .vscode/ *.iml *.so coverage.* +go.work +go.work.sum gen/ +/example/dice/dice +/example/fib/fib +/example/fib/traces.txt /example/jaeger/jaeger /example/namedtracer/namedtracer /example/opencensus/opencensus +/example/passthrough/passthrough /example/prometheus/prometheus -/example/prom-collector/prom-collector /example/zipkin/zipkin /example/otel-collector/otel-collector diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 2ef168198c2..6e8eeec00fa 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -4,29 +4,278 @@ run: tests: true #Default linters: + # Disable everything by default so upgrades to not include new "default + # enabled" linters. + disable-all: true + # Specifically enable linters we want to use. enable: - - misspell - - goimports - - golint + - depguard + - errcheck + - godot - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - revive + - staticcheck + - typecheck + - unused issues: + # Maximum issues count per one linter. + # Set to 0 to disable. + # Default: 50 + # Setting to unlimited so the linter only is run once to debug all issues. + max-issues-per-linter: 0 + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + # Setting to unlimited so the linter only is run once to debug all issues. + max-same-issues: 0 + # Excluding configuration per-path, per-linter, per-text and per-source. exclude-rules: - # helpers in tests often (rightfully) pass a *testing.T as their first argument - - path: _test\.go - text: "context.Context should be the first parameter of a function" + # TODO: Having appropriate comments for exported objects helps development, + # even for objects in internal packages. Appropriate comments for all + # exported objects should be added and this exclusion removed. + - path: '.*internal/.*' + text: "exported (method|function|type|const) (.+) should have comment or be unexported" linters: - - golint - # Yes, they are, but it's okay in a test + - revive + # Yes, they are, but it's okay in a test. - path: _test\.go text: "exported func.*returns unexported type.*which can be annoying to use" linters: - - golint + - revive + # Example test functions should be treated like main. + - path: example.*_test\.go + text: "calls to (.+) only in main[(][)] or init[(][)] functions" + linters: + - revive + include: + # revive exported should have comment or be unexported. + - EXC0012 + # revive package comment should be of the form ... + - EXC0013 linters-settings: + depguard: + rules: + non-tests: + files: + - "!$test" + - "!**/*test/*.go" + - "!**/internal/matchers/*.go" + deny: + - pkg: "testing" + - pkg: "github.com/stretchr/testify" + - pkg: "crypto/md5" + - pkg: "crypto/sha1" + - pkg: "crypto/**/pkix" + otlp-internal: + files: + - "!**/exporters/otlp/internal/**/*.go" + deny: + - pkg: "go.opentelemetry.io/otel/exporters/otlp/internal" + desc: Do not use cross-module internal packages. + otlptrace-internal: + files: + - "!**/exporters/otlp/otlptrace/*.go" + - "!**/exporters/otlp/otlptrace/internal/**.go" + deny: + - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal" + desc: Do not use cross-module internal packages. + otlpmetric-internal: + files: + - "!**/exporters/otlp/otlpmetric/internal/*.go" + - "!**/exporters/otlp/otlpmetric/internal/**/*.go" + deny: + - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal" + desc: Do not use cross-module internal packages. + otel-internal: + files: + - "**/sdk/*.go" + - "**/sdk/**/*.go" + - "**/exporters/*.go" + - "**/exporters/**/*.go" + - "**/schema/*.go" + - "**/schema/**/*.go" + - "**/metric/*.go" + - "**/metric/**/*.go" + - "**/bridge/*.go" + - "**/bridge/**/*.go" + - "**/example/*.go" + - "**/example/**/*.go" + - "**/trace/*.go" + - "**/trace/**/*.go" + deny: + - pkg: "go.opentelemetry.io/otel/internal$" + desc: Do not use cross-module internal packages. + - pkg: "go.opentelemetry.io/otel/internal/attribute" + desc: Do not use cross-module internal packages. + - pkg: "go.opentelemetry.io/otel/internal/internaltest" + desc: Do not use cross-module internal packages. + - pkg: "go.opentelemetry.io/otel/internal/matchers" + desc: Do not use cross-module internal packages. + godot: + exclude: + # Exclude links. + - '^ *\[[^]]+\]:' + # Exclude sentence fragments for lists. + - '^[ ]*[-•]' + # Exclude sentences prefixing a list. + - ':$' + goimports: + local-prefixes: go.opentelemetry.io misspell: locale: US ignore-words: - cancelled - goimports: - local-prefixes: go.opentelemetry.io + revive: + # Sets the default failure confidence. + # This means that linting errors with less than 0.8 confidence will be ignored. + # Default: 0.8 + confidence: 0.01 + rules: + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports + - name: blank-imports + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr + - name: bool-literal-in-expr + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr + - name: constant-logical-expr + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument + # TODO (#3372) re-enable linter when it is compatible. https://github.com/golangci/golangci-lint/issues/3280 + - name: context-as-argument + disabled: true + arguments: + allowTypesBefore: "*testing.T" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type + - name: context-keys-type + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit + - name: deep-exit + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer + - name: defer + disabled: false + arguments: + - ["call-chain", "loop"] + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports + - name: dot-imports + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports + - name: duplicated-imports + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return + - name: early-return + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block + - name: empty-block + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines + - name: empty-lines + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming + - name: error-naming + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return + - name: error-return + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings + - name: error-strings + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf + - name: errorf + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported + - name: exported + disabled: false + arguments: + - "sayRepetitiveInsteadOfStutters" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter + - name: flag-parameter + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches + - name: identical-branches + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return + - name: if-return + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement + - name: increment-decrement + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow + - name: indent-error-flow + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing + - name: import-shadowing + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments + - name: package-comments + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range + - name: range + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure + - name: range-val-in-closure + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address + - name: range-val-address + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id + - name: redefines-builtin-id + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format + - name: string-format + disabled: false + arguments: + - - panic + - '/^[^\n]*$/' + - must not contain line breaks + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag + - name: struct-tag + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else + - name: superfluous-else + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal + - name: time-equal + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming + - name: var-naming + disabled: false + arguments: + - ["ID"] # AllowList + - ["Otel", "Aws", "Gcp"] # DenyList + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration + - name: var-declaration + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion + - name: unconditional-recursion + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return + - name: unexported-return + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error + - name: unhandled-error + disabled: false + arguments: + - "fmt.Fprint" + - "fmt.Fprintf" + - "fmt.Fprintln" + - "fmt.Print" + - "fmt.Printf" + - "fmt.Println" + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt + - name: unnecessary-stmt + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break + - name: useless-break + disabled: false + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value + - name: waitgroup-by-value + disabled: false diff --git a/vendor/go.opentelemetry.io/otel/.lycheeignore b/vendor/go.opentelemetry.io/otel/.lycheeignore new file mode 100644 index 00000000000..40d62fa2eb8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/.lycheeignore @@ -0,0 +1,6 @@ +http://localhost +http://jaeger-collector +https://github.com/open-telemetry/opentelemetry-go/milestone/ +https://github.com/open-telemetry/opentelemetry-go/projects +file:///home/runner/work/opentelemetry-go/opentelemetry-go/libraries +file:///home/runner/work/opentelemetry-go/opentelemetry-go/manual diff --git a/vendor/go.opentelemetry.io/otel/.markdownlint.yaml b/vendor/go.opentelemetry.io/otel/.markdownlint.yaml new file mode 100644 index 00000000000..3202496c357 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/.markdownlint.yaml @@ -0,0 +1,29 @@ +# Default state for all rules +default: true + +# ul-style +MD004: false + +# hard-tabs +MD010: false + +# line-length +MD013: false + +# no-duplicate-header +MD024: + siblings_only: true + +#single-title +MD025: false + +# ol-prefix +MD029: + style: ordered + +# no-inline-html +MD033: false + +# fenced-code-language +MD040: false + diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 2702ccda255..3e5c35b5dcc 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -8,16 +8,1386 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [1.19.0/0.42.0/0.0.7] 2023-09-28 + +This release contains the first stable release of the OpenTelemetry Go [metric SDK]. +Our project stability guarantees now apply to the `go.opentelemetry.io/otel/sdk/metric` package. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Added + +- Add the "Roll the dice" getting started application example in `go.opentelemetry.io/otel/example/dice`. (#4539) +- The `WithWriter` and `WithPrettyPrint` options to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to set a custom `io.Writer`, and allow displaying the output in human-readable JSON. (#4507) + +### Changed + +- Allow '/' characters in metric instrument names. (#4501) +- The exporter in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` does not prettify its output by default anymore. (#4507) +- Upgrade `gopkg.io/yaml` from `v2` to `v3` in `go.opentelemetry.io/otel/schema`. (#4535) + +### Fixed + +- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the Prometheus metric on every `Collect` if we know the scope is invalid. (#4499) + +### Removed + +- Remove `"go.opentelemetry.io/otel/bridge/opencensus".NewMetricExporter`, which is replaced by `NewMetricProducer`. (#4566) + +## [1.19.0-rc.1/0.42.0-rc.1] 2023-09-14 + +This is a release candidate for the v1.19.0/v0.42.0 release. +That release is expected to include the `v1` release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Changed + +- Allow '/' characters in metric instrument names. (#4501) + +### Fixed + +- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the prometheus metric on every `Collect` if we know the scope is invalid. (#4499) + +## [1.18.0/0.41.0/0.0.6] 2023-09-12 + +This release drops the compatibility guarantee of [Go 1.19]. + +### Added + +- Add `WithProducer` option in `go.opentelemetry.op/otel/exporters/prometheus` to restore the ability to register producers on the prometheus exporter's manual reader. (#4473) +- Add `IgnoreValue` option in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest` to allow ignoring values when comparing metrics. (#4447) + +### Changed + +- Use a `TestingT` interface instead of `*testing.T` struct in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#4483) + +### Deprecated + +- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` was deprecated in `v0.35.0` (#3541). + The deprecation notice format for the function has been corrected to trigger Go documentation and build tooling. (#4470) + +### Removed + +- Removed the deprecated `go.opentelemetry.io/otel/exporters/jaeger` package. (#4467) +- Removed the deprecated `go.opentelemetry.io/otel/example/jaeger` package. (#4467) +- Removed the deprecated `go.opentelemetry.io/otel/sdk/metric/aggregation` package. (#4468) +- Removed the deprecated internal packages in `go.opentelemetry.io/otel/exporters/otlp` and its sub-packages. (#4469) +- Dropped guaranteed support for versions of Go less than 1.20. (#4481) + +## [1.17.0/0.40.0/0.0.5] 2023-08-28 + +### Added + +- Export the `ManualReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244) +- Export the `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244) +- Add support for exponential histogram aggregations. + A histogram can be configured as an exponential histogram using a view with `"go.opentelemetry.io/otel/sdk/metric".ExponentialHistogram` as the aggregation. (#4245) +- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272) +- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272) +- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287) +- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306) +- Add info and debug logging to the metric SDK in `go.opentelemetry.io/otel/sdk/metric`. (#4315) +- The `go.opentelemetry.io/otel/semconv/v1.21.0` package. + The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362) +- Accept 201 to 299 HTTP status as success in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4365) +- Document the `Temporality` and `Aggregation` methods of the `"go.opentelemetry.io/otel/sdk/metric".Exporter"` need to be concurrent safe. (#4381) +- Expand the set of units supported by the Prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374) +- Move the `Aggregation` interface and its implementations from `go.opentelemetry.io/otel/sdk/metric/aggregation` to `go.opentelemetry.io/otel/sdk/metric`. (#4435) +- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` environment variable. (#4437) +- Add the `NewAllowKeysFilter` and `NewDenyKeysFilter` functions to `go.opentelemetry.io/otel/attribute` to allow convenient creation of allow-keys and deny-keys filters. (#4444) +- Support Go 1.21. (#4463) + +### Changed + +- Starting from `v1.21.0` of semantic conventions, `go.opentelemetry.io/otel/semconv/{version}/httpconv` and `go.opentelemetry.io/otel/semconv/{version}/netconv` packages will no longer be published. (#4145) +- Log duplicate instrument conflict at a warning level instead of info in `go.opentelemetry.io/otel/sdk/metric`. (#4202) +- Return an error on the creation of new instruments in `go.opentelemetry.io/otel/sdk/metric` if their name doesn't pass regexp validation. (#4210) +- `NewManualReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*ManualReader` instead of `Reader`. (#4244) +- `NewPeriodicReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*PeriodicReader` instead of `Reader`. (#4244) +- Count the Collect time in the `PeriodicReader` timeout in `go.opentelemetry.io/otel/sdk/metric`. (#4221) +- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272) +- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272) +- If an attribute set is omitted from an async callback, the previous value will no longer be exported in `go.opentelemetry.io/otel/sdk/metric`. (#4290) +- If an attribute set is observed multiple times in an async callback in `go.opentelemetry.io/otel/sdk/metric`, the values will be summed instead of the last observation winning. (#4289) +- Allow the explicit bucket histogram aggregation to be used for the up-down counter, observable counter, observable up-down counter, and observable gauge in the `go.opentelemetry.io/otel/sdk/metric` package. (#4332) +- Restrict `Meter`s in `go.opentelemetry.io/otel/sdk/metric` to only register and collect instruments it created. (#4333) +- `PeriodicReader.Shutdown` and `PeriodicReader.ForceFlush` in `go.opentelemetry.io/otel/sdk/metric` now apply the periodic reader's timeout to the operation if the user provided context does not contain a deadline. (#4356, #4377) +- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.21.0`. (#4408) +- Increase instrument name maximum length from 63 to 255 characters in `go.opentelemetry.io/otel/sdk/metric`. (#4434) +- Add `go.opentelemetry.op/otel/sdk/metric.WithProducer` as an `Option` for `"go.opentelemetry.io/otel/sdk/metric".NewManualReader` and `"go.opentelemetry.io/otel/sdk/metric".NewPeriodicReader`. (#4346) + +### Removed + +- Remove `Reader.RegisterProducer` in `go.opentelemetry.io/otel/metric`. + Use the added `WithProducer` option instead. (#4346) +- Remove `Reader.ForceFlush` in `go.opentelemetry.io/otel/metric`. + Notice that `PeriodicReader.ForceFlush` is still available. (#4375) + +### Fixed + +- Correctly format log messages from the `go.opentelemetry.io/otel/exporters/zipkin` exporter. (#4143) +- Log an error for calls to `NewView` in `go.opentelemetry.io/otel/sdk/metric` that have empty criteria. (#4307) +- Fix `"go.opentelemetry.io/otel/sdk/resource".WithHostID()` to not set an empty `host.id`. (#4317) +- Use the instrument identifying fields to cache aggregators and determine duplicate instrument registrations in `go.opentelemetry.io/otel/sdk/metric`. (#4337) +- Detect duplicate instruments for case-insensitive names in `go.opentelemetry.io/otel/sdk/metric`. (#4338) +- The `ManualReader` will not panic if `AggregationSelector` returns `nil` in `go.opentelemetry.io/otel/sdk/metric`. (#4350) +- If a `Reader`'s `AggregationSelector` returns `nil` or `DefaultAggregation` the pipeline will use the default aggregation. (#4350) +- Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349) +- Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353) +- Improve context cancellation handling in batch span processor's `ForceFlush` in `go.opentelemetry.io/otel/sdk/trace`. (#4369) +- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` using gotmpl. (#4397, #3846) +- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4404, #3846) +- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4407, #3846) +- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4400, #3846) +- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4401, #3846) +- Do not block the metric SDK when OTLP metric exports are blocked in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#3925, #4395) +- Do not append `_total` if the counter already has that suffix for the Prometheus exproter in `go.opentelemetry.io/otel/exporter/prometheus`. (#4373) +- Fix resource detection data race in `go.opentelemetry.io/otel/sdk/resource`. (#4409) +- Use the first-seen instrument name during instrument name conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4428) + +### Deprecated + +- The `go.opentelemetry.io/otel/exporters/jaeger` package is deprecated. + OpenTelemetry dropped support for Jaeger exporter in July 2023. + Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` + or `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` instead. (#4423) +- The `go.opentelemetry.io/otel/example/jaeger` package is deprecated. (#4423) +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` package is deprecated. (#4420) +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/oconf` package is deprecated. (#4420) +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otest` package is deprecated. (#4420) +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/transform` package is deprecated. (#4420) +- The `go.opentelemetry.io/otel/exporters/otlp/internal` package is deprecated. (#4421) +- The `go.opentelemetry.io/otel/exporters/otlp/internal/envconfig` package is deprecated. (#4421) +- The `go.opentelemetry.io/otel/exporters/otlp/internal/retry` package is deprecated. (#4421) +- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` package is deprecated. (#4425) +- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/envconfig` package is deprecated. (#4425) +- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig` package is deprecated. (#4425) +- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest` package is deprecated. (#4425) +- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry` package is deprecated. (#4425) +- The `go.opentelemetry.io/otel/sdk/metric/aggregation` package is deprecated. + Use the aggregation types added to `go.opentelemetry.io/otel/sdk/metric` instead. (#4435) + +## [1.16.0/0.39.0] 2023-05-18 + +This release contains the first stable release of the OpenTelemetry Go [metric API]. +Our project stability guarantees now apply to the `go.opentelemetry.io/otel/metric` package. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Added + +- The `go.opentelemetry.io/otel/semconv/v1.19.0` package. + The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848) +- The `go.opentelemetry.io/otel/semconv/v1.20.0` package. + The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078) +- The Exponential Histogram data types in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#4165) +- OTLP metrics exporter now supports the Exponential Histogram Data Type. (#4222) +- Fix serialization of `time.Time` zero values in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` packages. (#4271) + +### Changed + +- Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049) +- `MeterProvider` returns noop meters once it has been shutdown. (#4154) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/instrument` package is removed. + Use `go.opentelemetry.io/otel/metric` instead. (#4055) + +### Fixed + +- Fix build for BSD based systems in `go.opentelemetry.io/otel/sdk/resource`. (#4077) + +## [1.16.0-rc.1/0.39.0-rc.1] 2023-05-03 + +This is a release candidate for the v1.16.0/v0.39.0 release. +That release is expected to include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Added + +- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#4039) + - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`. + - Use `GetMeterProivder` for a global `metric.MeterProvider`. + - Use `SetMeterProivder` to set the global `metric.MeterProvider`. + +### Changed + +- Move the `go.opentelemetry.io/otel/metric` module to the `stable-v1` module set. + This stages the metric API to be released as a stable module. (#4038) + +### Removed + +- The `go.opentelemetry.io/otel/metric/global` package is removed. + Use `go.opentelemetry.io/otel` instead. (#4039) + +## [1.15.1/0.38.1] 2023-05-02 + +### Fixed + +- Remove unused imports from `sdk/resource/host_id_bsd.go` which caused build failures. (#4040, #4041) + +## [1.15.0/0.38.0] 2023-04-27 + +### Added + +- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916) +- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949) +- Add a `WithNamespace` option to `go.opentelemetry.io/otel/exporters/prometheus` to allow users to prefix metrics with a namespace. (#3970) +- The following configuration types were added to `go.opentelemetry.io/otel/metric/instrument` to be used in the configuration of measurement methods. (#3971) + - The `AddConfig` used to hold configuration for addition measurements + - `NewAddConfig` used to create a new `AddConfig` + - `AddOption` used to configure an `AddConfig` + - The `RecordConfig` used to hold configuration for recorded measurements + - `NewRecordConfig` used to create a new `RecordConfig` + - `RecordOption` used to configure a `RecordConfig` + - The `ObserveConfig` used to hold configuration for observed measurements + - `NewObserveConfig` used to create a new `ObserveConfig` + - `ObserveOption` used to configure an `ObserveConfig` +- `WithAttributeSet` and `WithAttributes` are added to `go.opentelemetry.io/otel/metric/instrument`. + They return an option used during a measurement that defines the attribute Set associated with the measurement. (#3971) +- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` to return the OTLP metrics client version. (#3956) +- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlptrace` to return the OTLP trace client version. (#3956) + +### Changed + +- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870) +- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`. + This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916) +- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941) + - `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider` +- Add all the methods from `"go.opentelemetry.io/otel/trace".SpanContext` to `bridgeSpanContext` by embedding `otel.SpanContext` in `bridgeSpanContext`. (#3966) +- Wrap `UploadMetrics` error in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/` to improve error message when encountering generic grpc errors. (#3974) +- The measurement methods for all instruments in `go.opentelemetry.io/otel/metric/instrument` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971) + - The `Int64Counter.Add` method now accepts `...AddOption` + - The `Float64Counter.Add` method now accepts `...AddOption` + - The `Int64UpDownCounter.Add` method now accepts `...AddOption` + - The `Float64UpDownCounter.Add` method now accepts `...AddOption` + - The `Int64Histogram.Record` method now accepts `...RecordOption` + - The `Float64Histogram.Record` method now accepts `...RecordOption` + - The `Int64Observer.Observe` method now accepts `...ObserveOption` + - The `Float64Observer.Observe` method now accepts `...ObserveOption` +- The `Observer` methods in `go.opentelemetry.io/otel/metric` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971) + - The `Observer.ObserveInt64` method now accepts `...ObserveOption` + - The `Observer.ObserveFloat64` method now accepts `...ObserveOption` +- Move global metric back to `go.opentelemetry.io/otel/metric/global` from `go.opentelemetry.io/otel`. (#3986) + +### Fixed + +- `TracerProvider` allows calling `Tracer()` while it's shutting down. + It used to deadlock. (#3924) +- Use the SDK version for the Telemetry SDK resource detector in `go.opentelemetry.io/otel/sdk/resource`. (#3949) +- Fix a data race in `SpanProcessor` returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#3951) +- Automatically figure out the default aggregation with `aggregation.Default`. (#3967) + +### Deprecated + +- The `go.opentelemetry.io/otel/metric/instrument` package is deprecated. + Use the equivalent types added to `go.opentelemetry.io/otel/metric` instead. (#4018) + +## [1.15.0-rc.2/0.38.0-rc.2] 2023-03-23 + +This is a release candidate for the v1.15.0/v0.38.0 release. +That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Added + +- The `WithHostID` option to `go.opentelemetry.io/otel/sdk/resource`. (#3812) +- The `WithoutTimestamps` option to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to sets all timestamps to zero. (#3828) +- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`. + Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849) +- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895) +- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900) +- Added a log message warning about usage of `SimpleSpanProcessor` in production environments. (#3854) + +### Changed + +- Optimize memory allocation when creation a new `Set` using `NewSet` or `NewSetWithFiltered` in `go.opentelemetry.io/otel/attribute`. (#3832) +- Optimize memory allocation when creation new metric instruments in `go.opentelemetry.io/otel/sdk/metric`. (#3832) +- Avoid creating new objects on all calls to `WithDeferredSetup` and `SkipContextSetup` in OpenTracing bridge. (#3833) +- The `New` and `Detect` functions from `go.opentelemetry.io/otel/sdk/resource` return errors that wrap underlying errors instead of just containing the underlying error strings. (#3844) +- Both the `Histogram` and `HistogramDataPoint` are redefined with a generic argument of `[N int64 | float64]` in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#3849) +- The metric `Export` interface from `go.opentelemetry.io/otel/sdk/metric` accepts a `*ResourceMetrics` instead of `ResourceMetrics`. (#3853) +- Rename `Asynchronous` to `Observable` in `go.opentelemetry.io/otel/metric/instrument`. (#3892) +- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895) +- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895) +- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900) + +### Fixed + +- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829) +- The unneeded `Synchronous` interface in `go.opentelemetry.io/otel/metric/instrument` was removed. (#3892) +- The `Float64ObserverConfig` and `NewFloat64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`. + Use the added `float64` instrument configuration instead. (#3895) +- The `Int64ObserverConfig` and `NewInt64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`. + Use the added `int64` instrument configuration instead. (#3895) +- The `NewNoopMeter` function in `go.opentelemetry.io/otel/metric`, use `NewMeterProvider().Meter("")` instead. (#3893) + +## [1.15.0-rc.1/0.38.0-rc.1] 2023-03-01 + +This is a release candidate for the v1.15.0/v0.38.0 release. +That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +This release drops the compatibility guarantee of [Go 1.18]. + +### Added + +- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#3818) + - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`. + - Use `GetMeterProivder` for a global `metric.MeterProvider`. + - Use `SetMeterProivder` to set the global `metric.MeterProvider`. + +### Changed + +- Dropped compatibility testing for [Go 1.18]. + The project no longer guarantees support for this version of Go. (#3813) + +### Fixed + +- Handle empty environment variable as it they were not set. (#3764) +- Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823) +- Fix race conditions in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic. (#3899) +- Fix sending nil `scopeInfo` to metrics channel in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic in `github.com/prometheus/client_golang/prometheus`. (#3899) + +### Deprecated + +- The `go.opentelemetry.io/otel/metric/global` package is deprecated. + Use `go.opentelemetry.io/otel` instead. (#3818) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/unit` package is removed. (#3814) + +## [1.14.0/0.37.0/0.0.4] 2023-02-27 + +This release is the last to support [Go 1.18]. +The next release will require at least [Go 1.19]. + +### Added + +- The `event` type semantic conventions are added to `go.opentelemetry.io/otel/semconv/v1.17.0`. (#3697) +- Support [Go 1.20]. (#3693) +- The `go.opentelemetry.io/otel/semconv/v1.18.0` package. + The package contains semantic conventions from the `v1.18.0` version of the OpenTelemetry specification. (#3719) + - The following `const` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included: + - `OtelScopeNameKey` -> `OTelScopeNameKey` + - `OtelScopeVersionKey` -> `OTelScopeVersionKey` + - `OtelLibraryNameKey` -> `OTelLibraryNameKey` + - `OtelLibraryVersionKey` -> `OTelLibraryVersionKey` + - `OtelStatusCodeKey` -> `OTelStatusCodeKey` + - `OtelStatusDescriptionKey` -> `OTelStatusDescriptionKey` + - `OtelStatusCodeOk` -> `OTelStatusCodeOk` + - `OtelStatusCodeError` -> `OTelStatusCodeError` + - The following `func` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included: + - `OtelScopeName` -> `OTelScopeName` + - `OtelScopeVersion` -> `OTelScopeVersion` + - `OtelLibraryName` -> `OTelLibraryName` + - `OtelLibraryVersion` -> `OTelLibraryVersion` + - `OtelStatusDescription` -> `OTelStatusDescription` +- A `IsSampled` method is added to the `SpanContext` implementation in `go.opentelemetry.io/otel/bridge/opentracing` to expose the span sampled state. + See the [README](./bridge/opentracing/README.md) for more information. (#3570) +- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/metric`. (#3738) +- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/trace`. (#3739) +- The following environment variables are supported by the periodic `Reader` in `go.opentelemetry.io/otel/sdk/metric`. (#3763) + - `OTEL_METRIC_EXPORT_INTERVAL` sets the time between collections and exports. + - `OTEL_METRIC_EXPORT_TIMEOUT` sets the timeout an export is attempted. + +### Changed + +- Fall-back to `TextMapCarrier` when it's not `HttpHeader`s in `go.opentelemetry.io/otel/bridge/opentracing`. (#3679) +- The `Collect` method of the `"go.opentelemetry.io/otel/sdk/metric".Reader` interface is updated to accept the `metricdata.ResourceMetrics` value the collection will be made into. + This change is made to enable memory reuse by SDK users. (#3732) +- The `WithUnit` option in `go.opentelemetry.io/otel/sdk/metric/instrument` is updated to accept a `string` for the unit value. (#3776) + +### Fixed + +- Ensure `go.opentelemetry.io/otel` does not use generics. (#3723, #3725) +- Multi-reader `MeterProvider`s now export metrics for all readers, instead of just the first reader. (#3720, #3724) +- Remove use of deprecated `"math/rand".Seed` in `go.opentelemetry.io/otel/example/prometheus`. (#3733) +- Do not silently drop unknown schema data with `Parse` in `go.opentelemetry.io/otel/schema/v1.1`. (#3743) +- Data race issue in OTLP exporter retry mechanism. (#3755, #3756) +- Wrapping empty errors when exporting in `go.opentelemetry.io/otel/sdk/metric`. (#3698, #3772) +- Incorrect "all" and "resource" definition for schema files in `go.opentelemetry.io/otel/schema/v1.1`. (#3777) + +### Deprecated + +- The `go.opentelemetry.io/otel/metric/unit` package is deprecated. + Use the equivalent unit string instead. (#3776) + - Use `"1"` instead of `unit.Dimensionless` + - Use `"By"` instead of `unit.Bytes` + - Use `"ms"` instead of `unit.Milliseconds` + +## [1.13.0/0.36.0] 2023-02-07 + +### Added + +- Attribute `KeyValue` creations functions to `go.opentelemetry.io/otel/semconv/v1.17.0` for all non-enum semantic conventions. + These functions ensure semantic convention type correctness. (#3675) + +### Fixed + +- Removed the `http.target` attribute from being added by `ServerRequest` in the following packages. (#3687) + - `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv` + - `go.opentelemetry.io/otel/semconv/v1.14.0/httpconv` + - `go.opentelemetry.io/otel/semconv/v1.15.0/httpconv` + - `go.opentelemetry.io/otel/semconv/v1.16.0/httpconv` + - `go.opentelemetry.io/otel/semconv/v1.17.0/httpconv` + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is removed. (#3631) +- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is removed. (#3631) +- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is removed. (#3631) +- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncint64` package is removed. (#3631) + +## [1.12.0/0.35.0] 2023-01-28 + +### Added + +- The `WithInt64Callback` option to `go.opentelemetry.io/otel/metric/instrument`. + This options is used to configure `int64` Observer callbacks during their creation. (#3507) +- The `WithFloat64Callback` option to `go.opentelemetry.io/otel/metric/instrument`. + This options is used to configure `float64` Observer callbacks during their creation. (#3507) +- The `Producer` interface and `Reader.RegisterProducer(Producer)` to `go.opentelemetry.io/otel/sdk/metric`. + These additions are used to enable external metric Producers. (#3524) +- The `Callback` function type to `go.opentelemetry.io/otel/metric`. + This new named function type is registered with a `Meter`. (#3564) +- The `go.opentelemetry.io/otel/semconv/v1.13.0` package. + The package contains semantic conventions from the `v1.13.0` version of the OpenTelemetry specification. (#3499) + - The `EndUserAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientRequest` and `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `HTTPAttributesFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientResponse` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `HTTPClientAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `HTTPServerAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `HTTPServerMetricAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `NetAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `Transport` in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` and `ClientRequest` or `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `SpanStatusFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `SpanStatusFromHTTPStatusCodeAndSpanKind` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `ClientStatus` and `ServerStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`. + - The `Client` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Conn`. + - The `Server` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Listener`. +- The `go.opentelemetry.io/otel/semconv/v1.14.0` package. + The package contains semantic conventions from the `v1.14.0` version of the OpenTelemetry specification. (#3566) +- The `go.opentelemetry.io/otel/semconv/v1.15.0` package. + The package contains semantic conventions from the `v1.15.0` version of the OpenTelemetry specification. (#3578) +- The `go.opentelemetry.io/otel/semconv/v1.16.0` package. + The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579) +- Metric instruments to `go.opentelemetry.io/otel/metric/instrument`. + These instruments are use as replacements of the deprecated `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586) + - `Float64ObservableCounter` replaces the `asyncfloat64.Counter` + - `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter` + - `Float64ObservableGauge` replaces the `asyncfloat64.Gauge` + - `Int64ObservableCounter` replaces the `asyncint64.Counter` + - `Int64ObservableUpDownCounter` replaces the `asyncint64.UpDownCounter` + - `Int64ObservableGauge` replaces the `asyncint64.Gauge` + - `Float64Counter` replaces the `syncfloat64.Counter` + - `Float64UpDownCounter` replaces the `syncfloat64.UpDownCounter` + - `Float64Histogram` replaces the `syncfloat64.Histogram` + - `Int64Counter` replaces the `syncint64.Counter` + - `Int64UpDownCounter` replaces the `syncint64.UpDownCounter` + - `Int64Histogram` replaces the `syncint64.Histogram` +- `NewTracerProvider` to `go.opentelemetry.io/otel/bridge/opentracing`. + This is used to create `WrapperTracer` instances from a `TracerProvider`. (#3116) +- The `Extrema` type to `go.opentelemetry.io/otel/sdk/metric/metricdata`. + This type is used to represent min/max values and still be able to distinguish unset and zero values. (#3487) +- The `go.opentelemetry.io/otel/semconv/v1.17.0` package. + The package contains semantic conventions from the `v1.17.0` version of the OpenTelemetry specification. (#3599) + +### Changed + +- Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500) +- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and configuration based on the instrument type. (#3507) + - Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`. + - Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`. + - Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`. + - Use the added `Float64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncfloat64`. +- Return a `Registration` from the `RegisterCallback` method of a `Meter` in the `go.opentelemetry.io/otel/metric` package. + This `Registration` can be used to unregister callbacks. (#3522) +- Global error handler uses an atomic value instead of a mutex. (#3543) +- Add `NewMetricProducer` to `go.opentelemetry.io/otel/bridge/opencensus`, which can be used to pass OpenCensus metrics to an OpenTelemetry Reader. (#3541) +- Global logger uses an atomic value instead of a mutex. (#3545) +- The `Shutdown` method of the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` releases all computational resources when called the first time. (#3551) +- The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions. + This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557) +- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in errors identifying their signal name. + Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516) +- Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514) +- The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562) + - `InstrumentKindSyncCounter` is renamed to `InstrumentKindCounter` + - `InstrumentKindSyncUpDownCounter` is renamed to `InstrumentKindUpDownCounter` + - `InstrumentKindSyncHistogram` is renamed to `InstrumentKindHistogram` + - `InstrumentKindAsyncCounter` is renamed to `InstrumentKindObservableCounter` + - `InstrumentKindAsyncUpDownCounter` is renamed to `InstrumentKindObservableUpDownCounter` + - `InstrumentKindAsyncGauge` is renamed to `InstrumentKindObservableGauge` +- The `RegisterCallback` method of the `Meter` in `go.opentelemetry.io/otel/metric` changed. + - The named `Callback` replaces the inline function parameter. (#3564) + - `Callback` is required to return an error. (#3576) + - `Callback` accepts the added `Observer` parameter added. + This new parameter is used by `Callback` implementations to observe values for asynchronous instruments instead of calling the `Observe` method of the instrument directly. (#3584) + - The slice of `instrument.Asynchronous` is now passed as a variadic argument. (#3587) +- The exporter from `go.opentelemetry.io/otel/exporters/zipkin` is updated to use the `v1.16.0` version of semantic conventions. + This means it no longer uses the removed `net.peer.ip` or `http.host` attributes to determine the remote endpoint. + Instead it uses the `net.sock.peer` attributes. (#3581) +- The `Min` and `Max` fields of the `HistogramDataPoint` in `go.opentelemetry.io/otel/sdk/metric/metricdata` are now defined with the added `Extrema` type instead of a `*float64`. (#3487) + +### Fixed + +- Asynchronous instruments that use sum aggregators and attribute filters correctly add values from equivalent attribute sets that have been filtered. (#3439, #3549) +- The `RegisterCallback` method of the `Meter` from `go.opentelemetry.io/otel/sdk/metric` only registers a callback for instruments created by that meter. + Trying to register a callback with instruments from a different meter will result in an error being returned. (#3584) + +### Deprecated + +- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` is deprecated. + Use `NewMetricProducer` instead. (#3541) +- The `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is deprecated. + Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575) +- The `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is deprecated. + Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575) +- The `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is deprecated. + Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575) +- The `go.opentelemetry.io/otel/metric/instrument/syncint64` package is deprecated. + Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575) +- The `NewWrappedTracerProvider` in `go.opentelemetry.io/otel/bridge/opentracing` is now deprecated. + Use `NewTracerProvider` instead. (#3116) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/sdk/metric/view` package is removed. (#3520) +- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncint64` is removed. + Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530) + - The `Counter` method is replaced by `Meter.Int64ObservableCounter` + - The `UpDownCounter` method is replaced by `Meter.Int64ObservableUpDownCounter` + - The `Gauge` method is replaced by `Meter.Int64ObservableGauge` +- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncfloat64` is removed. + Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530) + - The `Counter` method is replaced by `Meter.Float64ObservableCounter` + - The `UpDownCounter` method is replaced by `Meter.Float64ObservableUpDownCounter` + - The `Gauge` method is replaced by `Meter.Float64ObservableGauge` +- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncint64` is removed. + Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530) + - The `Counter` method is replaced by `Meter.Int64Counter` + - The `UpDownCounter` method is replaced by `Meter.Int64UpDownCounter` + - The `Histogram` method is replaced by `Meter.Int64Histogram` +- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncfloat64` is removed. + Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530) + - The `Counter` method is replaced by `Meter.Float64Counter` + - The `UpDownCounter` method is replaced by `Meter.Float64UpDownCounter` + - The `Histogram` method is replaced by `Meter.Float64Histogram` + +## [1.11.2/0.34.0] 2022-12-05 + +### Added + +- The `WithView` `Option` is added to the `go.opentelemetry.io/otel/sdk/metric` package. + This option is used to configure the view(s) a `MeterProvider` will use for all `Reader`s that are registered with it. (#3387) +- Add Instrumentation Scope and Version as info metric and label in Prometheus exporter. + This can be disabled using the `WithoutScopeInfo()` option added to that package.(#3273, #3357) +- OTLP exporters now recognize: (#3363) + - `OTEL_EXPORTER_OTLP_INSECURE` + - `OTEL_EXPORTER_OTLP_TRACES_INSECURE` + - `OTEL_EXPORTER_OTLP_METRICS_INSECURE` + - `OTEL_EXPORTER_OTLP_CLIENT_KEY` + - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY` + - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` + - `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` + - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE` + - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` +- The `View` type and related `NewView` function to create a view according to the OpenTelemetry specification are added to `go.opentelemetry.io/otel/sdk/metric`. + These additions are replacements for the `View` type and `New` function from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459) +- The `Instrument` and `InstrumentKind` type are added to `go.opentelemetry.io/otel/sdk/metric`. + These additions are replacements for the `Instrument` and `InstrumentKind` types from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459) +- The `Stream` type is added to `go.opentelemetry.io/otel/sdk/metric` to define a metric data stream a view will produce. (#3459) +- The `AssertHasAttributes` allows instrument authors to test that datapoints returned have appropriate attributes. (#3487) + +### Changed + +- The `"go.opentelemetry.io/otel/sdk/metric".WithReader` option no longer accepts views to associate with the `Reader`. + Instead, views are now registered directly with the `MeterProvider` via the new `WithView` option. + The views registered with the `MeterProvider` apply to all `Reader`s. (#3387) +- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `"go.opentelemetry.io/otel/sdk/metric".Exporter` interface. (#3260) +- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `"go.opentelemetry.io/otel/exporters/otlp/otlpmetric".Client` interface. (#3260) +- The `WithTemporalitySelector` and `WithAggregationSelector` `ReaderOption`s have been changed to `ManualReaderOption`s in the `go.opentelemetry.io/otel/sdk/metric` package. (#3260) +- The periodic reader in the `go.opentelemetry.io/otel/sdk/metric` package now uses the temporality and aggregation selectors from its configured exporter instead of accepting them as options. (#3260) + +### Fixed + +- The `go.opentelemetry.io/otel/exporters/prometheus` exporter fixes duplicated `_total` suffixes. (#3369) +- Remove comparable requirement for `Reader`s. (#3387) +- Cumulative metrics from the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) are defined as monotonic sums, instead of non-monotonic. (#3389) +- Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398) +- Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340) +- `Aggregation`s from `go.opentelemetry.io/otel/sdk/metric` with no data are not exported. (#3394, #3436) +- Re-enabled Attribute Filters in the Metric SDK. (#3396) +- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggragation. (#3408) +- Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432) +- Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440) +- Prevent duplicate Prometheus description, unit, and type. (#3469) +- Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489) + +### Removed + +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.Client` interface is removed. (#3486) +- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.New` function is removed. Use the `otlpmetric[http|grpc].New` directly. (#3486) + +### Deprecated + +- The `go.opentelemetry.io/otel/sdk/metric/view` package is deprecated. + Use `Instrument`, `InstrumentKind`, `View`, and `NewView` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3476) + +## [1.11.1/0.33.0] 2022-10-19 + +### Added + +- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` registers with a Prometheus registerer on creation. + By default, it will register with the default Prometheus registerer. + A non-default registerer can be used by passing the `WithRegisterer` option. (#3239) +- Added the `WithAggregationSelector` option to the `go.opentelemetry.io/otel/exporters/prometheus` package to change the default `AggregationSelector` used. (#3341) +- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` converts the `Resource` associated with metric exports into a `target_info` metric. (#3285) + +### Changed + +- The `"go.opentelemetry.io/otel/exporters/prometheus".New` function is updated to return an error. + It will return an error if the exporter fails to register with Prometheus. (#3239) + +### Fixed + +- The URL-encoded values from the `OTEL_RESOURCE_ATTRIBUTES` environment variable are decoded. (#2963) +- The `baggage.NewMember` function decodes the `value` parameter instead of directly using it. + This fixes the implementation to be compliant with the W3C specification. (#3226) +- Slice attributes of the `attribute` package are now comparable based on their value, not instance. (#3108 #3252) +- The `Shutdown` and `ForceFlush` methods of the `"go.opentelemetry.io/otel/sdk/trace".TraceProvider` no longer return an error when no processor is registered. (#3268) +- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` cumulatively sums histogram buckets. (#3281) +- The sum of each histogram data point is now uniquely exported by the `go.opentelemetry.io/otel/exporters/otlpmetric` exporters. (#3284, #3293) +- Recorded values for asynchronous counters (`Counter` and `UpDownCounter`) are interpreted as exact, not incremental, sum values by the metric SDK. (#3350, #3278) +- `UpDownCounters` are now correctly output as Prometheus gauges in the `go.opentelemetry.io/otel/exporters/prometheus` exporter. (#3358) +- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` no longer describes the metrics it will send to Prometheus on startup. + Instead the exporter is defined as an "unchecked" collector for Prometheus. + This fixes the `reader is not registered` warning currently emitted on startup. (#3291 #3342) +- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now correctly adds `_total` suffixes to counter metrics. (#3360) +- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now adds a unit suffix to metric names. + This can be disabled using the `WithoutUnits()` option added to that package. (#3352) + +## [1.11.0/0.32.3] 2022-10-12 + +### Added + +- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlptrace/otlptracegrpc` and `go.opentelemetry.io/otel/exporters/otlptrace/otlptracehttp`). (#3261) + +### Changed + +- `span.SetStatus` has been updated such that calls that lower the status are now no-ops. (#3214) +- Upgrade `golang.org/x/sys/unix` from `v0.0.0-20210423185535-09eb48e85fd7` to `v0.0.0-20220919091848-fb04ddd9f9c8`. + This addresses [GO-2022-0493](https://pkg.go.dev/vuln/GO-2022-0493). (#3235) + +## [0.32.2] Metric SDK (Alpha) - 2022-10-11 + +### Added + +- Added an example of using metric views to customize instruments. (#3177) +- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetrichttp`). (#3261) + +### Changed + +- Flush pending measurements with the `PeriodicReader` in the `go.opentelemetry.io/otel/sdk/metric` when `ForceFlush` or `Shutdown` are called. (#3220) +- Update histogram default bounds to match the requirements of the latest specification. (#3222) +- Encode the HTTP status code in the OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`) as an integer. (#3265) + +### Fixed + +- Use default view if instrument does not match any registered view of a reader. (#3224, #3237) +- Return the same instrument every time a user makes the exact same instrument creation call. (#3229, #3251) +- Return the existing instrument when a view transforms a creation call to match an existing instrument. (#3240, #3251) +- Log a warning when a conflicting instrument (e.g. description, unit, data-type) is created instead of returning an error. (#3251) +- The OpenCensus bridge no longer sends empty batches of metrics. (#3263) + +## [0.32.1] Metric SDK (Alpha) - 2022-09-22 + +### Changed + +- The Prometheus exporter sanitizes OpenTelemetry instrument names when exporting. + Invalid characters are replaced with `_`. (#3212) + +### Added + +- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been reintroduced. (#3192) +- The OpenCensus bridge example (`go.opentelemetry.io/otel/example/opencensus`) has been reintroduced. (#3206) + +### Fixed + +- Updated go.mods to point to valid versions of the sdk. (#3216) +- Set the `MeterProvider` resource on all exported metric data. (#3218) + +## [0.32.0] Revised Metric SDK (Alpha) - 2022-09-18 + +### Changed + +- The metric SDK in `go.opentelemetry.io/otel/sdk/metric` is completely refactored to comply with the OpenTelemetry specification. + Please see the package documentation for how the new SDK is initialized and configured. (#3175) +- Update the minimum supported go version to go1.18. Removes support for go1.17 (#3179) + +### Removed + +- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been removed. + A new bridge compliant with the revised metric SDK will be added back in a future release. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/aggregator/histogram` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/aggregator/sum` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/aggregator` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/controller/basic` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/controller/controllertest` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/controller/time` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/export/aggregation` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/export` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/metrictest` package is removed. + A replacement package that supports the new metric SDK will be added back in a future release. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/number` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/processor/basic` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/processor/processortest` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/processor/reducer` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/registry` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/sdkapi` package is removed, see the new metric SDK. (#3175) +- The `go.opentelemetry.io/otel/sdk/metric/selector/simple` package is removed, see the new metric SDK. (#3175) +- The `"go.opentelemetry.io/otel/sdk/metric".ErrUninitializedInstrument` variable was removed. (#3175) +- The `"go.opentelemetry.io/otel/sdk/metric".ErrBadInstrument` variable was removed. (#3175) +- The `"go.opentelemetry.io/otel/sdk/metric".Accumulator` type was removed, see the `MeterProvider`in the new metric SDK. (#3175) +- The `"go.opentelemetry.io/otel/sdk/metric".NewAccumulator` function was removed, see `NewMeterProvider`in the new metric SDK. (#3175) +- The deprecated `"go.opentelemetry.io/otel/sdk/metric".AtomicFieldOffsets` function was removed. (#3175) + +## [1.10.0] - 2022-09-09 + ### Added +- Support Go 1.19. (#3077) + Include compatibility testing and document support. (#3077) +- Support the OTLP ExportTracePartialSuccess response; these are passed to the registered error handler. (#3106) +- Upgrade go.opentelemetry.io/proto/otlp from v0.18.0 to v0.19.0 (#3107) + +### Changed + +- Fix misidentification of OpenTelemetry `SpanKind` in OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`). (#3096) +- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110) +- All exporters will be shutdown even if one reports an error (#3091) +- Ensure valid UTF-8 when truncating over-length attribute values. (#3156) + +## [1.9.0/0.0.3] - 2022-08-01 + +### Added + +- Add support for Schema Files format 1.1.x (metric "split" transform) with the new `go.opentelemetry.io/otel/schema/v1.1` package. (#2999) +- Add the `go.opentelemetry.io/otel/semconv/v1.11.0` package. + The package contains semantic conventions from the `v1.11.0` version of the OpenTelemetry specification. (#3009) +- Add the `go.opentelemetry.io/otel/semconv/v1.12.0` package. + The package contains semantic conventions from the `v1.12.0` version of the OpenTelemetry specification. (#3010) +- Add the `http.method` attribute to HTTP server metric from all `go.opentelemetry.io/otel/semconv/*` packages. (#3018) + +### Fixed + +- Invalid warning for context setup being deferred in `go.opentelemetry.io/otel/bridge/opentracing` package. (#3029) + +## [1.8.0/0.31.0] - 2022-07-08 + +### Added + +- Add support for `opentracing.TextMap` format in the `Inject` and `Extract` methods +of the `"go.opentelemetry.io/otel/bridge/opentracing".BridgeTracer` type. (#2911) + +### Changed + +- The `crosslink` make target has been updated to use the `go.opentelemetry.io/build-tools/crosslink` package. (#2886) +- In the `go.opentelemetry.io/otel/sdk/instrumentation` package rename `Library` to `Scope` and alias `Library` as `Scope` (#2976) +- Move metric no-op implementation form `nonrecording` to `metric` package. (#2866) + +### Removed + +- Support for go1.16. Support is now only for go1.17 and go1.18 (#2917) + +### Deprecated + +- The `Library` struct in the `go.opentelemetry.io/otel/sdk/instrumentation` package is deprecated. + Use the equivalent `Scope` struct instead. (#2977) +- The `ReadOnlySpan.InstrumentationLibrary` method from the `go.opentelemetry.io/otel/sdk/trace` package is deprecated. + Use the equivalent `ReadOnlySpan.InstrumentationScope` method instead. (#2977) + +## [1.7.0/0.30.0] - 2022-04-28 + +### Added + +- Add the `go.opentelemetry.io/otel/semconv/v1.8.0` package. + The package contains semantic conventions from the `v1.8.0` version of the OpenTelemetry specification. (#2763) +- Add the `go.opentelemetry.io/otel/semconv/v1.9.0` package. + The package contains semantic conventions from the `v1.9.0` version of the OpenTelemetry specification. (#2792) +- Add the `go.opentelemetry.io/otel/semconv/v1.10.0` package. + The package contains semantic conventions from the `v1.10.0` version of the OpenTelemetry specification. (#2842) +- Added an in-memory exporter to metrictest to aid testing with a full SDK. (#2776) + +### Fixed + +- Globally delegated instruments are unwrapped before delegating asynchronous callbacks. (#2784) +- Remove import of `testing` package in non-tests builds of the `go.opentelemetry.io/otel` package. (#2786) + +### Changed + +- The `WithLabelEncoder` option from the `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` package is renamed to `WithAttributeEncoder`. (#2790) +- The `LabelFilterSelector` interface from `go.opentelemetry.io/otel/sdk/metric/processor/reducer` is renamed to `AttributeFilterSelector`. + The method included in the renamed interface also changed from `LabelFilterFor` to `AttributeFilterFor`. (#2790) +- The `Metadata.Labels` method from the `go.opentelemetry.io/otel/sdk/metric/export` package is renamed to `Metadata.Attributes`. + Consequentially, the `Record` type from the same package also has had the embedded method renamed. (#2790) + +### Deprecated + +- The `Iterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated. + Use the equivalent `Iterator.Attribute` method instead. (#2790) +- The `Iterator.IndexedLabel` method in the `go.opentelemetry.io/otel/attribute` package is deprecated. + Use the equivalent `Iterator.IndexedAttribute` method instead. (#2790) +- The `MergeIterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated. + Use the equivalent `MergeIterator.Attribute` method instead. (#2790) + +### Removed + +- Removed the `Batch` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864) +- Removed the `Measurement` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864) + +## [0.29.0] - 2022-04-11 + +### Added + +- The metrics global package was added back into several test files. (#2764) +- The `Meter` function is added back to the `go.opentelemetry.io/otel/metric/global` package. + This function is a convenience function equivalent to calling `global.MeterProvider().Meter(...)`. (#2750) + +### Removed + +- Removed module the `go.opentelemetry.io/otel/sdk/export/metric`. + Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2720) + +### Changed + +- Don't panic anymore when setting a global MeterProvider to itself. (#2749) +- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` from `v0.12.1` to `v0.15.0`. + This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibraryMetrics` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeMetrics`. (#2748) + +## [1.6.3] - 2022-04-07 + +### Fixed + +- Allow non-comparable global `MeterProvider`, `TracerProvider`, and `TextMapPropagator` types to be set. (#2772, #2773) + +## [1.6.2] - 2022-04-06 + +### Changed + +- Don't panic anymore when setting a global TracerProvider or TextMapPropagator to itself. (#2749) +- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace` from `v0.12.1` to `v0.15.0`. + This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibrarySpans` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeSpans`. (#2748) + +## [1.6.1] - 2022-03-28 + +### Fixed + +- The `go.opentelemetry.io/otel/schema/*` packages now use the correct schema URL for their `SchemaURL` constant. + Instead of using `"https://opentelemetry.io/schemas/v"` they now use the correct URL without a `v` prefix, `"https://opentelemetry.io/schemas/"`. (#2743, #2744) + +### Security + +- Upgrade `go.opentelemetry.io/proto/otlp` from `v0.12.0` to `v0.12.1`. + This includes an indirect upgrade of `github.com/grpc-ecosystem/grpc-gateway` which resolves [a vulnerability](https://nvd.nist.gov/vuln/detail/CVE-2019-11254) from `gopkg.in/yaml.v2` in version `v2.2.3`. (#2724, #2728) + +## [1.6.0/0.28.0] - 2022-03-23 + +### ⚠️ Notice ⚠️ + +This update is a breaking change of the unstable Metrics API. +Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be modified. + +### Added + +- Add metrics exponential histogram support. + New mapping functions have been made available in `sdk/metric/aggregator/exponential/mapping` for other OpenTelemetry projects to take dependencies on. (#2502) +- Add Go 1.18 to our compatibility tests. (#2679) +- Allow configuring the Sampler with the `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` environment variables. (#2305, #2517) +- Add the `metric/global` for obtaining and setting the global `MeterProvider`. (#2660) + +### Changed + +- The metrics API has been significantly changed to match the revised OpenTelemetry specification. + High-level changes include: + + - Synchronous and asynchronous instruments are now handled by independent `InstrumentProvider`s. + These `InstrumentProvider`s are managed with a `Meter`. + - Synchronous and asynchronous instruments are grouped into their own packages based on value types. + - Asynchronous callbacks can now be registered with a `Meter`. + + Be sure to check out the metric module documentation for more information on how to use the revised API. (#2587, #2660) + +### Fixed + +- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677) + +## [1.5.0] - 2022-03-16 + +### Added + +- Log the Exporters configuration in the TracerProviders message. (#2578) +- Added support to configure the span limits with environment variables. + The following environment variables are supported. (#2606, #2637) + - `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` + - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` + - `OTEL_SPAN_EVENT_COUNT_LIMIT` + - `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT` + - `OTEL_SPAN_LINK_COUNT_LIMIT` + - `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT` + + If the provided environment variables are invalid (negative), the default values would be used. +- Rename the `gc` runtime name to `go` (#2560) +- Add resource container ID detection. (#2418) +- Add span attribute value length limit. + The new `AttributeValueLengthLimit` field is added to the `"go.opentelemetry.io/otel/sdk/trace".SpanLimits` type to configure this limit for a `TracerProvider`. + The default limit for this resource is "unlimited". (#2637) +- Add the `WithRawSpanLimits` option to `go.opentelemetry.io/otel/sdk/trace`. + This option replaces the `WithSpanLimits` option. + Zero or negative values will not be changed to the default value like `WithSpanLimits` does. + Setting a limit to zero will effectively disable the related resource it limits and setting to a negative value will mean that resource is unlimited. + Consequentially, limits should be constructed using `NewSpanLimits` and updated accordingly. (#2637) + +### Changed + +- Drop oldest tracestate `Member` when capacity is reached. (#2592) +- Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) +- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` configuration. (#2639) +- Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) +- Introduce new internal `envconfig` package for OTLP exporters. (#2608) +- If `http.Request.Host` is empty, fall back to use `URL.Host` when populating `http.host` in the `semconv` packages. (#2661) + +### Fixed + +- Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616) +- Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) +- Unlimited span limits are now supported (negative values). (#2636, #2637) + +### Deprecated + +- Deprecated `"go.opentelemetry.io/otel/sdk/trace".WithSpanLimits`. + Use `WithRawSpanLimits` instead. + That option allows setting unlimited and zero limits, this option does not. + This option will be kept until the next major version incremented release. (#2637) + +## [1.4.1] - 2022-02-16 + +### Fixed + +- Fix race condition in reading the dropped spans number for the `BatchSpanProcessor`. (#2615) + +## [1.4.0] - 2022-02-11 + +### Added + +- Use `OTEL_EXPORTER_ZIPKIN_ENDPOINT` environment variable to specify zipkin collector endpoint. (#2490) +- Log the configuration of `TracerProvider`s, and `Tracer`s for debugging. + To enable use a logger with Verbosity (V level) `>=1`. (#2500) +- Added support to configure the batch span-processor with environment variables. + The following environment variables are used. (#2515) + - `OTEL_BSP_SCHEDULE_DELAY` + - `OTEL_BSP_EXPORT_TIMEOUT` + - `OTEL_BSP_MAX_QUEUE_SIZE`. + - `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` + +### Changed + +- Zipkin exporter exports `Resource` attributes in the `Tags` field. (#2589) + +### Deprecated + +- Deprecate module the `go.opentelemetry.io/otel/sdk/export/metric`. + Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2382) +- Deprecate `"go.opentelemetry.io/otel/sdk/metric".AtomicFieldOffsets`. (#2445) + +### Fixed + +- Fixed the instrument kind for noop async instruments to correctly report an implementation. (#2461) +- Fix UDP packets overflowing with Jaeger payloads. (#2489, #2512) +- Change the `otlpmetric.Client` interface's `UploadMetrics` method to accept a single `ResourceMetrics` instead of a slice of them. (#2491) +- Specify explicit buckets in Prometheus example, fixing issue where example only has `+inf` bucket. (#2419, #2493) +- W3C baggage will now decode urlescaped values. (#2529) +- Baggage members are now only validated once, when calling `NewMember` and not also when adding it to the baggage itself. (#2522) +- The order attributes are dropped from spans in the `go.opentelemetry.io/otel/sdk/trace` package when capacity is reached is fixed to be in compliance with the OpenTelemetry specification. + Instead of dropping the least-recently-used attribute, the last added attribute is dropped. + This drop order still only applies to attributes with unique keys not already contained in the span. + If an attribute is added with a key already contained in the span, that attribute is updated to the new value being added. (#2576) + +### Removed + +- Updated `go.opentelemetry.io/proto/otlp` from `v0.11.0` to `v0.12.0`. This version removes a number of deprecated methods. (#2546) + - [`Metric.GetIntGauge()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntGauge) + - [`Metric.GetIntHistogram()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntHistogram) + - [`Metric.GetIntSum()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntSum) + +## [1.3.0] - 2021-12-10 + +### ⚠️ Notice ⚠️ + +We have updated the project minimum supported Go version to 1.16 + +### Added + +- Added an internal Logger. + This can be used by the SDK and API to provide users with feedback of the internal state. + To enable verbose logs configure the logger which will print V(1) logs. For debugging information configure to print V(5) logs. (#2343) +- Add the `WithRetry` `Option` and the `RetryConfig` type to the `go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp` package to specify retry behavior consistently. (#2425) +- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296) + ### Changed +- The `"go.opentelemetry.io/otel/exporter/otel/otlptrace/otlptracegrpc".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2329) +- The `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2425) +- The `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc".RetrySettings` type is renamed to `RetryConfig`. (#2425) +- The `go.opentelemetry.io/otel/exporter/otel/*` gRPC exporters now default to using the host's root CA set if none are provided by the user and `WithInsecure` is not specified. (#2432) +- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371) + +### Fixed + +- The `go.opentelemetry.io/otel/exporter/otel/*` exporters are updated to handle per-signal and universal endpoints according to the OpenTelemetry specification. + Any per-signal endpoint set via an `OTEL_EXPORTER_OTLP__ENDPOINT` environment variable is now used without modification of the path. + When `OTEL_EXPORTER_OTLP_ENDPOINT` is set, if it contains a path, that path is used as a base path which per-signal paths are appended to. (#2433) +- Basic metric controller updated to use sync.Map to avoid blocking calls (#2381) +- The `go.opentelemetry.io/otel/exporter/jaeger` correctly sets the `otel.status_code` value to be a string of `ERROR` or `OK` instead of an integer code. (#2439, #2440) + ### Deprecated +- Deprecated the `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp".WithMaxAttempts` `Option`, use the new `WithRetry` `Option` instead. (#2425) +- Deprecated the `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp".WithBackoff` `Option`, use the new `WithRetry` `Option` instead. (#2425) + ### Removed +- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350) +- Remove the metric Bound Instruments interface and implementations. (#2399) +- Remove the metric MinMaxSumCount kind aggregation and the corresponding OTLP export path. (#2423) +- Metric SDK removes the "exact" aggregator for histogram instruments, as it performed a non-standard aggregation for OTLP export (creating repeated Gauge points) and worked its way into a number of confusing examples. (#2348) + +## [1.2.0] - 2021-11-12 + +### Changed + +- Metric SDK `export.ExportKind`, `export.ExportKindSelector` types have been renamed to `aggregation.Temporality` and `aggregation.TemporalitySelector` respectively to keep in line with current specification and protocol along with built-in selectors (e.g., `aggregation.CumulativeTemporalitySelector`, ...). (#2274) +- The Metric `Exporter` interface now requires a `TemporalitySelector` method instead of an `ExportKindSelector`. (#2274) +- Metrics API cleanup. The `metric/sdkapi` package has been created to relocate the API-to-SDK interface: + - The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner` + - The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`. + - The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271) +- Update the SDK `BatchSpanProcessor` to export all queued spans when `ForceFlush` is called. (#2080, #2335) + +### Added + +- Add the `"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002) +- Added a new `schema` module to help parse Schema Files in OTEP 0152 format. (#2267) +- Added a new `MapCarrier` to the `go.opentelemetry.io/otel/propagation` package to hold propagated cross-cutting concerns as a `map[string]string` held in memory. (#2334) + +## [1.1.0] - 2021-10-27 + +### Added + +- Add the `"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002) +- Add the `go.opentelemetry.io/otel/semconv/v1.7.0` package. + The package contains semantic conventions from the `v1.7.0` version of the OpenTelemetry specification. (#2320) +- Add the `go.opentelemetry.io/otel/semconv/v1.6.1` package. + The package contains semantic conventions from the `v1.6.1` version of the OpenTelemetry specification. (#2321) +- Add the `go.opentelemetry.io/otel/semconv/v1.5.0` package. + The package contains semantic conventions from the `v1.5.0` version of the OpenTelemetry specification. (#2322) + - When upgrading from the `semconv/v1.4.0` package note the following name changes: + - `K8SReplicasetUIDKey` -> `K8SReplicaSetUIDKey` + - `K8SReplicasetNameKey` -> `K8SReplicaSetNameKey` + - `K8SStatefulsetUIDKey` -> `K8SStatefulSetUIDKey` + - `k8SStatefulsetNameKey` -> `K8SStatefulSetNameKey` + - `K8SDaemonsetUIDKey` -> `K8SDaemonSetUIDKey` + - `K8SDaemonsetNameKey` -> `K8SDaemonSetNameKey` + +### Changed + +- Links added to a span will be dropped by the SDK if they contain an invalid span context (#2275). + +### Fixed + +- The `"go.opentelemetry.io/otel/semconv/v1.4.0".HTTPServerAttributesFromHTTPRequest` now correctly only sets the HTTP client IP attribute even if the connection was routed with proxies and there are multiple addresses in the `X-Forwarded-For` header. (#2282, #2284) +- The `"go.opentelemetry.io/otel/semconv/v1.4.0".NetAttributesFromHTTPRequest` function correctly handles IPv6 addresses as IP addresses and sets the correct net peer IP instead of the net peer hostname attribute. (#2283, #2285) +- The simple span processor shutdown method deterministically returns the exporter error status if it simultaneously finishes when the deadline is reached. (#2290, #2289) + +## [1.0.1] - 2021-10-01 + +### Fixed + +- json stdout exporter no longer crashes due to concurrency bug. (#2265) + +## [Metrics 0.24.0] - 2021-10-01 + +### Changed + +- NoopMeterProvider is now private and NewNoopMeterProvider must be used to obtain a noopMeterProvider. (#2237) +- The Metric SDK `Export()` function takes a new two-level reader interface for iterating over results one instrumentation library at a time. (#2197) + - The former `"go.opentelemetry.io/otel/sdk/export/metric".CheckpointSet` is renamed `Reader`. + - The new interface is named `"go.opentelemetry.io/otel/sdk/export/metric".InstrumentationLibraryReader`. + +## [1.0.0] - 2021-09-20 + +This is the first stable release for the project. +This release includes an API and SDK for the tracing signal that will comply with the stability guarantees defined by the projects [versioning policy](./VERSIONING.md). + +### Added + +- OTLP trace exporter now sets the `SchemaURL` field in the exported telemetry if the Tracer has `WithSchemaURL` option. (#2242) + ### Fixed +- Slice-valued attributes can correctly be used as map keys. (#2223) + +### Removed + +- Removed the `"go.opentelemetry.io/otel/exporters/zipkin".WithSDKOptions` function. (#2248) +- Removed the deprecated package `go.opentelemetry.io/otel/oteltest`. (#2234) +- Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233) +- Removed deprecated functions, types, and methods from `go.opentelemetry.io/otel/attribute` package. + Use the typed functions and methods added to the package instead. (#2235) + - The `Key.Array` method is removed. + - The `Array` function is removed. + - The `Any` function is removed. + - The `ArrayValue` function is removed. + - The `AsArray` function is removed. + +## [1.0.0-RC3] - 2021-09-02 + +### Added + +- Added `ErrorHandlerFunc` to use a function as an `"go.opentelemetry.io/otel".ErrorHandler`. (#2149) +- Added `"go.opentelemetry.io/otel/trace".WithStackTrace` option to add a stack trace when using `span.RecordError` or when panic is handled in `span.End`. (#2163) +- Added typed slice attribute types and functionality to the `go.opentelemetry.io/otel/attribute` package to replace the existing array type and functions. (#2162) + - `BoolSlice`, `IntSlice`, `Int64Slice`, `Float64Slice`, and `StringSlice` replace the use of the `Array` function in the package. +- Added the `go.opentelemetry.io/otel/example/fib` example package. + Included is an example application that computes Fibonacci numbers. (#2203) + +### Changed + +- Metric instruments have been renamed to match the (feature-frozen) metric API specification: + - ValueRecorder becomes Histogram + - ValueObserver becomes Gauge + - SumObserver becomes CounterObserver + - UpDownSumObserver becomes UpDownCounterObserver + The API exported from this project is still considered experimental. (#2202) +- Metric SDK/API implementation type `InstrumentKind` moves into `sdkapi` sub-package. (#2091) +- The Metrics SDK export record no longer contains a Resource pointer, the SDK `"go.opentelemetry.io/otel/sdk/trace/export/metric".Exporter.Export()` function for push-based exporters now takes a single Resource argument, pull-based exporters use `"go.opentelemetry.io/otel/sdk/metric/controller/basic".Controller.Resource()`. (#2120) +- The JSON output of the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` is harmonized now such that the output is "plain" JSON objects after each other of the form `{ ... } { ... } { ... }`. Earlier the JSON objects describing a span were wrapped in a slice for each `Exporter.ExportSpans` call, like `[ { ... } ][ { ... } { ... } ]`. Outputting JSON object directly after each other is consistent with JSON loggers, and a bit easier to parse and read. (#2196) +- Update the `NewTracerConfig`, `NewSpanStartConfig`, `NewSpanEndConfig`, and `NewEventConfig` function in the `go.opentelemetry.io/otel/trace` package to return their respective configurations as structs instead of pointers to the struct. (#2212) + +### Deprecated + +- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated. + All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package. + The functions from that package should be used instead. (#2166) +- The `"go.opentelemetry.io/otel/attribute".Array` function and the related `ARRAY` value type is deprecated. + Use the typed `*Slice` functions and types added to the package instead. (#2162) +- The `"go.opentelemetry.io/otel/attribute".Any` function is deprecated. + Use the typed functions instead. (#2181) +- The `go.opentelemetry.io/otel/oteltest` package is deprecated. + The `"go.opentelemetry.io/otel/sdk/trace/tracetest".SpanRecorder` can be registered with the default SDK (`go.opentelemetry.io/otel/sdk/trace`) as a `SpanProcessor` and used as a replacement for this deprecated package. (#2188) + +### Removed + +- Removed metrics test package `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#2105) + +### Fixed + +- The `fromEnv` detector no longer throws an error when `OTEL_RESOURCE_ATTRIBUTES` environment variable is not set or empty. (#2138) +- Setting the global `ErrorHandler` with `"go.opentelemetry.io/otel".SetErrorHandler` multiple times is now supported. (#2160, #2140) +- The `"go.opentelemetry.io/otel/attribute".Any` function now supports `int32` values. (#2169) +- Multiple calls to `"go.opentelemetry.io/otel/sdk/metric/controller/basic".WithResource()` are handled correctly, and when no resources are provided `"go.opentelemetry.io/otel/sdk/resource".Default()` is used. (#2120) +- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly omit timestamps. (#2195) +- Fixed typos in resources.go. (#2201) + +## [1.0.0-RC2] - 2021-07-26 + +### Added + +- Added `WithOSDescription` resource configuration option to set OS (Operating System) description resource attribute (`os.description`). (#1840) +- Added `WithOS` resource configuration option to set all OS (Operating System) resource attributes at once. (#1840) +- Added the `WithRetry` option to the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package. + This option is a replacement for the removed `WithMaxAttempts` and `WithBackoff` options. (#2095) +- Added API `LinkFromContext` to return Link which encapsulates SpanContext from provided context and also encapsulates attributes. (#2115) +- Added a new `Link` type under the SDK `otel/sdk/trace` package that counts the number of attributes that were dropped for surpassing the `AttributePerLinkCountLimit` configured in the Span's `SpanLimits`. + This new type replaces the equal-named API `Link` type found in the `otel/trace` package for most usages within the SDK. + For example, instances of this type are now returned by the `Links()` function of `ReadOnlySpan`s provided in places like the `OnEnd` function of `SpanProcessor` implementations. (#2118) +- Added the `SpanRecorder` type to the `go.opentelemetry.io/otel/skd/trace/tracetest` package. + This type can be used with the default SDK as a `SpanProcessor` during testing. (#2132) + +### Changed + +- The `SpanModels` function is now exported from the `go.opentelemetry.io/otel/exporters/zipkin` package to convert OpenTelemetry spans into Zipkin model spans. (#2027) +- Rename the `"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc".RetrySettings` to `RetryConfig`. (#2095) + +### Deprecated + +- The `TextMapCarrier` and `TextMapPropagator` from the `go.opentelemetry.io/otel/oteltest` package and their associated creation functions (`TextMapCarrier`, `NewTextMapPropagator`) are deprecated. (#2114) +- The `Harness` type from the `go.opentelemetry.io/otel/oteltest` package and its associated creation function, `NewHarness` are deprecated and will be removed in the next release. (#2123) +- The `TraceStateFromKeyValues` function from the `go.opentelemetry.io/otel/oteltest` package is deprecated. + Use the `trace.ParseTraceState` function instead. (#2122) + +### Removed + +- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/jaeger`. (#2020) +- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/zipkin`. (#2020) +- Removed the `"go.opentelemetry.io/otel/sdk/resource".WithBuiltinDetectors` function. + The explicit `With*` options for every built-in detector should be used instead. (#2026 #2097) +- Removed the `WithMaxAttempts` and `WithBackoff` options from the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package. + The retry logic of the package has been updated to match the `otlptracegrpc` package and accordingly a `WithRetry` option is added that should be used instead. (#2095) +- Removed `DroppedAttributeCount` field from `otel/trace.Link` struct. (#2118) + +### Fixed + +- When using WithNewRoot, don't use the parent context for making sampling decisions. (#2032) +- `oteltest.Tracer` now creates a valid `SpanContext` when using `WithNewRoot`. (#2073) +- OS type detector now sets the correct `dragonflybsd` value for DragonFly BSD. (#2092) +- The OTel span status is correctly transformed into the OTLP status in the `go.opentelemetry.io/otel/exporters/otlp/otlptrace` package. + This fix will by default set the status to `Unset` if it is not explicitly set to `Ok` or `Error`. (#2099 #2102) +- The `Inject` method for the `"go.opentelemetry.io/otel/propagation".TraceContext` type no longer injects empty `tracestate` values. (#2108) +- Use `6831` as default Jaeger agent port instead of `6832`. (#2131) + +## [Experimental Metrics v0.22.0] - 2021-07-19 + +### Added + +- Adds HTTP support for OTLP metrics exporter. (#2022) + +### Removed + +- Removed the deprecated package `go.opentelemetry.io/otel/exporters/metric/prometheus`. (#2020) + +## [1.0.0-RC1] / 0.21.0 - 2021-06-18 + +With this release we are introducing a split in module versions. The tracing API and SDK are entering the `v1.0.0` Release Candidate phase with `v1.0.0-RC1` +while the experimental metrics API and SDK continue with `v0.x` releases at `v0.21.0`. Modules at major version 1 or greater will not depend on modules +with major version 0. + +### Added + +- Adds `otlpgrpc.WithRetry`option for configuring the retry policy for transient errors on the otlp/gRPC exporter. (#1832) + - The following status codes are defined as transient errors: + | gRPC Status Code | Description | + | ---------------- | ----------- | + | 1 | Cancelled | + | 4 | Deadline Exceeded | + | 8 | Resource Exhausted | + | 10 | Aborted | + | 10 | Out of Range | + | 14 | Unavailable | + | 15 | Data Loss | +- Added `Status` type to the `go.opentelemetry.io/otel/sdk/trace` package to represent the status of a span. (#1874) +- Added `SpanStub` type and its associated functions to the `go.opentelemetry.io/otel/sdk/trace/tracetest` package. + This type can be used as a testing replacement for the `SpanSnapshot` that was removed from the `go.opentelemetry.io/otel/sdk/trace` package. (#1873) +- Adds support for scheme in `OTEL_EXPORTER_OTLP_ENDPOINT` according to the spec. (#1886) +- Adds `trace.WithSchemaURL` option for configuring the tracer with a Schema URL. (#1889) +- Added an example of using OpenTelemetry Go as a trace context forwarder. (#1912) +- `ParseTraceState` is added to the `go.opentelemetry.io/otel/trace` package. + It can be used to decode a `TraceState` from a `tracestate` header string value. (#1937) +- Added `Len` method to the `TraceState` type in the `go.opentelemetry.io/otel/trace` package. + This method returns the number of list-members the `TraceState` holds. (#1937) +- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace` that defines a trace exporter that uses a `otlptrace.Client` to send data. + Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` implementing a gRPC `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing .(#1922) +- Added `Baggage`, `Member`, and `Property` types to the `go.opentelemetry.io/otel/baggage` package along with their related functions. (#1967) +- Added `ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext` functions to the `go.opentelemetry.io/otel/baggage` package. + These functions replace the `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions from that package and directly work with the new `Baggage` type. (#1967) +- The `OTEL_SERVICE_NAME` environment variable is the preferred source for `service.name`, used by the environment resource detector if a service name is present both there and in `OTEL_RESOURCE_ATTRIBUTES`. (#1969) +- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` implementing an HTTP `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing. (#1963) +- Changes `go.opentelemetry.io/otel/sdk/resource.NewWithAttributes` to require a schema URL. The old function is still available as `resource.NewSchemaless`. This is a breaking change. (#1938) +- Several builtin resource detectors now correctly populate the schema URL. (#1938) +- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` that defines a metrics exporter that uses a `otlpmetric.Client` to send data. +- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` implementing a gRPC `otlpmetric.Client` and offers convenience functions, `New` and `NewUnstarted`, to create an `otlpmetric.Exporter`.(#1991) +- Added `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter. (#2005) +- Added `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` exporter. (#2005) +- Added a `TracerProvider()` method to the `"go.opentelemetry.io/otel/trace".Span` interface. This can be used to obtain a `TracerProvider` from a given span that utilizes the same trace processing pipeline. (#2009) + +### Changed + +- Make `NewSplitDriver` from `go.opentelemetry.io/otel/exporters/otlp` take variadic arguments instead of a `SplitConfig` item. + `NewSplitDriver` now automatically implements an internal `noopDriver` for `SplitConfig` fields that are not initialized. (#1798) +- `resource.New()` now creates a Resource without builtin detectors. Previous behavior is now achieved by using `WithBuiltinDetectors` Option. (#1810) +- Move the `Event` type from the `go.opentelemetry.io/otel` package to the `go.opentelemetry.io/otel/sdk/trace` package. (#1846) +- CI builds validate against last two versions of Go, dropping 1.14 and adding 1.16. (#1865) +- BatchSpanProcessor now report export failures when calling `ForceFlush()` method. (#1860) +- `Set.Encoded(Encoder)` no longer caches the result of an encoding. (#1855) +- Renamed `CloudZoneKey` to `CloudAvailabilityZoneKey` in Resource semantic conventions according to spec. (#1871) +- The `StatusCode` and `StatusMessage` methods of the `ReadOnlySpan` interface and the `Span` produced by the `go.opentelemetry.io/otel/sdk/trace` package have been replaced with a single `Status` method. + This method returns the status of a span using the new `Status` type. (#1874) +- Updated `ExportSpans` method of the`SpanExporter` interface type to accept `ReadOnlySpan`s instead of the removed `SpanSnapshot`. + This brings the export interface into compliance with the specification in that it now accepts an explicitly immutable type instead of just an implied one. (#1873) +- Unembed `SpanContext` in `Link`. (#1877) +- Generate Semantic conventions from the specification YAML. (#1891) +- Spans created by the global `Tracer` obtained from `go.opentelemetry.io/otel`, prior to a functioning `TracerProvider` being set, now propagate the span context from their parent if one exists. (#1901) +- The `"go.opentelemetry.io/otel".Tracer` function now accepts tracer options. (#1902) +- Move the `go.opentelemetry.io/otel/unit` package to `go.opentelemetry.io/otel/metric/unit`. (#1903) +- Changed `go.opentelemetry.io/otel/trace.TracerConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config.) (#1921) +- Changed `go.opentelemetry.io/otel/trace.SpanConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921) +- Changed `span.End()` now only accepts Options that are allowed at `End()`. (#1921) +- Changed `go.opentelemetry.io/otel/metric.InstrumentConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921) +- Changed `go.opentelemetry.io/otel/metric.MeterConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921) +- Refactored option types according to the contribution style guide. (#1882) +- Move the `go.opentelemetry.io/otel/trace.TraceStateFromKeyValues` function to the `go.opentelemetry.io/otel/oteltest` package. + This function is preserved for testing purposes where it may be useful to create a `TraceState` from `attribute.KeyValue`s, but it is not intended for production use. + The new `ParseTraceState` function should be used to create a `TraceState`. (#1931) +- Updated `MarshalJSON` method of the `go.opentelemetry.io/otel/trace.TraceState` type to marshal the type into the string representation of the `TraceState`. (#1931) +- The `TraceState.Delete` method from the `go.opentelemetry.io/otel/trace` package no longer returns an error in addition to a `TraceState`. (#1931) +- Updated `Get` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931) +- Updated `Insert` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a pair of `string`s instead of an `attribute.KeyValue` type. (#1931) +- Updated `Delete` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931) +- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/stdout` package. (#1985) +- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/metric/prometheus` package. (#1985) +- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1985) +- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1985) +- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985) +- Renamed `NewUnstartedExporter` to `NewUnstarted` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985) +- The `go.opentelemetry.io/otel/semconv` package has been moved to `go.opentelemetry.io/otel/semconv/v1.4.0` to allow for multiple [telemetry schema](https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md) versions to be used concurrently. (#1987) +- Metrics test helpers in `go.opentelemetry.io/otel/oteltest` have been moved to `go.opentelemetry.io/otel/metric/metrictest`. (#1988) + +### Deprecated + +- The `go.opentelemetry.io/otel/exporters/metric/prometheus` is deprecated, use `go.opentelemetry.io/otel/exporters/prometheus` instead. (#1993) +- The `go.opentelemetry.io/otel/exporters/trace/jaeger` is deprecated, use `go.opentelemetry.io/otel/exporters/jaeger` instead. (#1993) +- The `go.opentelemetry.io/otel/exporters/trace/zipkin` is deprecated, use `go.opentelemetry.io/otel/exporters/zipkin` instead. (#1993) + +### Removed + +- Removed `resource.WithoutBuiltin()`. Use `resource.New()`. (#1810) +- Unexported types `resource.FromEnv`, `resource.Host`, and `resource.TelemetrySDK`, Use the corresponding `With*()` to use individually. (#1810) +- Removed the `Tracer` and `IsRecording` method from the `ReadOnlySpan` in the `go.opentelemetry.io/otel/sdk/trace`. + The `Tracer` method is not a required to be included in this interface and given the mutable nature of the tracer that is associated with a span, this method is not appropriate. + The `IsRecording` method returns if the span is recording or not. + A read-only span value does not need to know if updates to it will be recorded or not. + By definition, it cannot be updated so there is no point in communicating if an update is recorded. (#1873) +- Removed the `SpanSnapshot` type from the `go.opentelemetry.io/otel/sdk/trace` package. + The use of this type has been replaced with the use of the explicitly immutable `ReadOnlySpan` type. + When a concrete representation of a read-only span is needed for testing, the newly added `SpanStub` in the `go.opentelemetry.io/otel/sdk/trace/tracetest` package should be used. (#1873) +- Removed the `Tracer` method from the `Span` interface in the `go.opentelemetry.io/otel/trace` package. + Using the same tracer that created a span introduces the error where an instrumentation library's `Tracer` is used by other code instead of their own. + The `"go.opentelemetry.io/otel".Tracer` function or a `TracerProvider` should be used to acquire a library specific `Tracer` instead. (#1900) + - The `TracerProvider()` method on the `Span` interface may also be used to obtain a `TracerProvider` using the same trace processing pipeline. (#2009) +- The `http.url` attribute generated by `HTTPClientAttributesFromHTTPRequest` will no longer include username or password information. (#1919) +- Removed `IsEmpty` method of the `TraceState` type in the `go.opentelemetry.io/otel/trace` package in favor of using the added `TraceState.Len` method. (#1931) +- Removed `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions in the `go.opentelemetry.io/otel/baggage` package. + Handling of baggage is now done using the added `Baggage` type and related context functions (`ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext`) in that package. (#1967) +- The `InstallNewPipeline` and `NewExportPipeline` creation functions in all the exporters (prometheus, otlp, stdout, jaeger, and zipkin) have been removed. + These functions were deemed premature attempts to provide convenience that did not achieve this aim. (#1985) +- The `go.opentelemetry.io/otel/exporters/otlp` exporter has been removed. Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace` instead. (#1990) +- The `go.opentelemetry.io/otel/exporters/stdout` exporter has been removed. Use `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` or `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` instead. (#2005) + +### Fixed + +- Only report errors from the `"go.opentelemetry.io/otel/sdk/resource".Environment` function when they are not `nil`. (#1850, #1851) +- The `Shutdown` method of the simple `SpanProcessor` in the `go.opentelemetry.io/otel/sdk/trace` package now honors the context deadline or cancellation. (#1616, #1856) +- BatchSpanProcessor now drops span batches that failed to be exported. (#1860) +- Use `http://localhost:14268/api/traces` as default Jaeger collector endpoint instead of `http://localhost:14250`. (#1898) +- Allow trailing and leading whitespace in the parsing of a `tracestate` header. (#1931) +- Add logic to determine if the channel is closed to fix Jaeger exporter test panic with close closed channel. (#1870, #1973) +- Avoid transport security when OTLP endpoint is a Unix socket. (#2001) + ### Security ## [0.20.0] - 2021-04-23 @@ -62,6 +1432,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` - `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE` - Adds `otlpgrpc.WithTimeout` option for configuring timeout to the otlp/gRPC exporter. (#1821) +- Adds `jaeger.WithMaxPacketSize` option for configuring maximum UDP packet size used when connecting to the Jaeger agent. (#1853) ### Fixed @@ -73,6 +1444,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Zipkin Exporter: Ensure mapping between OTel and Zipkin span data complies with the specification. (#1688) - Fixed typo for default service name in Jaeger Exporter. (#1797) - Fix flaky OTLP for the reconnnection of the client connection. (#1527, #1814) +- Fix Jaeger exporter dropping of span batches that exceed the UDP packet size limit. + Instead, the exporter now splits the batch into smaller sendable batches. (#1828) ### Changed @@ -89,19 +1462,18 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - The `ParentContext` field of the `"go.opentelemetry.io/otel/sdk/trace".SamplingParameters` is updated to hold a `context.Context` containing the parent span. This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749) - Updated Jaeger Environment Variables: `JAEGER_ENDPOINT`, `JAEGER_USER`, `JAEGER_PASSWORD` - to `OTEL_EXPORTER_JAEGER_ENDPOINT`, `OTEL_EXPORTER_JAEGER_USER`, `OTEL_EXPORTER_JAEGER_PASSWORD` - in compliance with OTel spec (#1752) + to `OTEL_EXPORTER_JAEGER_ENDPOINT`, `OTEL_EXPORTER_JAEGER_USER`, `OTEL_EXPORTER_JAEGER_PASSWORD` in compliance with OTel specification. (#1752) - Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757) - The `DroppedAttributeCount` field of the `Span` in the `go.opentelemetry.io/otel` package now only represents the number of attributes dropped for the span itself. It no longer is a conglomerate of itself, events, and link attributes that have been dropped. (#1771) - Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773) -- Modify Zipkin Exporter default service name, use default resouce's serviceName instead of empty. (#1777) +- Modify Zipkin Exporter default service name, use default resource's serviceName instead of empty. (#1777) - The `go.opentelemetry.io/otel/sdk/export/trace` package is merged into the `go.opentelemetry.io/otel/sdk/trace` package. (#1778) - The prometheus.InstallNewPipeline example is moved from comment to example test (#1796) - The convenience functions for the stdout exporter have been updated to return the `TracerProvider` implementation and enable the shutdown of the exporter. (#1800) - Replace the flush function returned from the Jaeger exporter's convenience creation functions (`InstallNewPipeline` and `NewExportPipeline`) with the `TracerProvider` implementation they create. This enables the caller to shutdown and flush using the related `TracerProvider` methods. (#1822) -- Updated the Jaeger exporter to have a default enpoint, `http://localhost:14250`, for the collector. (#1824) +- Updated the Jaeger exporter to have a default endpoint, `http://localhost:14250`, for the collector. (#1824) - Changed the function `WithCollectorEndpoint` in the Jaeger exporter to no longer accept an endpoint as an argument. The endpoint can be passed with the `CollectorEndpointOption` using the `WithEndpoint` function or by setting the `OTEL_EXPORTER_JAEGER_ENDPOINT` environment variable value appropriately. (#1824) - The Jaeger exporter no longer batches exported spans itself, instead it relies on the SDK's `BatchSpanProcessor` for this functionality. (#1830) @@ -137,8 +1509,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The exporter no longer batches exports, instead relying on the SDK's `BatchSpanProcessor` for this functionality. (#1830) - The Jaeger exporter `Option` type is removed. The type is no longer used by the exporter to configure anything. - All of the previous configuration these options provided were duplicates of SDK configuration. - They have all been removed in favor of using the SDK configuration and focuses the exporter configuration to be only about the endpoints it will send telemetry to. (#1830) + All the previous configurations these options provided were duplicates of SDK configuration. + They have been removed in favor of using the SDK configuration and focuses the exporter configuration to be only about the endpoints it will send telemetry to. (#1830) ## [0.19.0] - 2021-03-18 @@ -220,7 +1592,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Stagger timestamps in exact aggregator tests. (#1569) - Changed all examples to use `WithBatchTimeout(5 * time.Second)` rather than `WithBatchTimeout(5)`. (#1621) - Prevent end-users from implementing some interfaces (#1575) -``` + + ``` "otel/exporters/otlp/otlphttp".Option "otel/exporters/stdout".Option "otel/oteltest".Option @@ -233,7 +1606,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm "otel/sdk/trace".ParentBasedSamplerOption "otel/sdk/trace".ReadOnlySpan "otel/sdk/trace".ReadWriteSpan -``` + ``` + ### Removed - Removed attempt to resample spans upon changing the span name with `span.SetName()`. (#1545) @@ -273,7 +1647,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `NewGRPCDriver` function returns a `ProtocolDriver` that maintains a single gRPC connection to the collector. (#1369) - Added documentation about the project's versioning policy. (#1388) - Added `NewSplitDriver` for OTLP exporter that allows sending traces and metrics to different endpoints. (#1418) -- Added codeql worfklow to GitHub Actions (#1428) +- Added codeql workflow to GitHub Actions (#1428) - Added Gosec workflow to GitHub Actions (#1429) - Add new HTTP driver for OTLP exporter in `exporters/otlp/otlphttp`. Currently it only supports the binary protobuf payloads. (#1420) - Add an OpenCensus exporter bridge. (#1444) @@ -815,7 +2189,7 @@ This release implements the v0.5.0 version of the OpenTelemetry specification. - Rename `Observer` instrument to `ValueObserver`. (#734) - The push controller now has a method (`Provider()`) to return a `metric.Provider` instead of the old `Meter` method that acted as a `metric.Provider`. (#738) - Replace `Measure` instrument by `ValueRecorder` instrument. (#732) -- Rename correlation context header from `"Correlation-Context"` to `"otcorrelations"` to match the OpenTelemetry specification. 727) +- Rename correlation context header from `"Correlation-Context"` to `"otcorrelations"` to match the OpenTelemetry specification. (#727) ### Fixed @@ -918,7 +2292,6 @@ This release implements the v0.5.0 version of the OpenTelemetry specification. - Create a new recorder rather than reuse when multiple observations in same epoch for asynchronous instruments. #610 - The default port the OTLP exporter uses to connect to the OpenTelemetry collector is updated to match the one the collector listens on by default. (#611) - ## [0.4.2] - 2020-03-31 ### Fixed @@ -978,7 +2351,7 @@ There is still a possibility of breaking changes. - Simplified export setup pipeline for the jaeger exporter to match other exporters. (#459) - The zipkin trace exporter. (#495) - The OTLP exporter to export metric and trace telemetry to the OpenTelemetry collector. (#497) (#544) (#545) -- The `StatusMessage` field was add to the trace `Span`. (#524) +- Add `StatusMessage` field to the trace `Span`. (#524) - Context propagation in OpenTracing bridge in terms of OpenTelemetry context propagation. (#525) - The `Resource` type was added to the SDK. (#528) - The global API now supports a `Tracer` and `Meter` function as shortcuts to getting a global `*Provider` and calling these methods directly. (#538) @@ -1071,14 +2444,12 @@ There is still a possibility of breaking changes. - `AlwaysParentSample` sampler to the trace API. (#455) - `WithNewRoot` option function to the trace API to specify the created span should be considered a root span. (#451) - ### Changed - Renamed `WithMap` to `ContextWithMap` in the correlation package. (#481) - Renamed `FromContext` to `MapFromContext` in the correlation package. (#481) - Move correlation context propagation to correlation package. (#479) - Do not default to putting remote span context into links. (#480) -- Propagators extrac - `Tracer.WithSpan` updated to accept `StartOptions`. (#472) - Renamed `MetricKind` to `Kind` to not stutter in the type usage. (#432) - Renamed the `export` package to `metric` to match directory structure. (#432) @@ -1119,7 +2490,7 @@ There is still a possibility of breaking changes. ### Fixed -- Use stateful batcher on Prometheus exporter fixing regresion introduced in #395. (#428) +- Use stateful batcher on Prometheus exporter fixing regression introduced in #395. (#428) ## [0.2.1] - 2020-01-08 @@ -1226,7 +2597,6 @@ There is still a possibility of breaking changes. This allowed distinct label sets through, but any metrics sharing a label set could be overwritten or merged incorrectly. This was corrected. (#333) - ## [0.1.2] - 2019-11-18 ### Fixed @@ -1286,8 +2656,48 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. - -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v0.20.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.19.0...HEAD +[1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0 +[1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1 +[1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0 +[1.17.0/0.40.0/0.0.5]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.17.0 +[1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0 +[1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1 +[1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1 +[1.15.0/0.38.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0 +[1.15.0-rc.2/0.38.0-rc.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.2 +[1.15.0-rc.1/0.38.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.1 +[1.14.0/0.37.0/0.0.4]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.14.0 +[1.13.0/0.36.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.13.0 +[1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0 +[1.11.2/0.34.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.2 +[1.11.1/0.33.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.1 +[1.11.0/0.32.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.0 +[0.32.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.2 +[0.32.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.1 +[0.32.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.0 +[1.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.10.0 +[1.9.0/0.0.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.9.0 +[1.8.0/0.31.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.8.0 +[1.7.0/0.30.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.7.0 +[0.29.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.29.0 +[1.6.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.3 +[1.6.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.2 +[1.6.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.1 +[1.6.0/0.28.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.0 +[1.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.5.0 +[1.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.1 +[1.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.0 +[1.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.3.0 +[1.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.2.0 +[1.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.1.0 +[1.0.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.1 +[Metrics 0.24.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.24.0 +[1.0.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0 +[1.0.0-RC3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC3 +[1.0.0-RC2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC2 +[Experimental Metrics v0.22.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.22.0 +[1.0.0-RC1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC1 [0.20.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.20.0 [0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.19.0 [0.18.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.18.0 @@ -1317,3 +2727,11 @@ It contains api and sdk for trace and meter. [0.1.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.2 [0.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.1 [0.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.0 + +[Go 1.20]: https://go.dev/doc/go1.20 +[Go 1.19]: https://go.dev/doc/go1.19 +[Go 1.18]: https://go.dev/doc/go1.18 +[Go 1.19]: https://go.dev/doc/go1.19 + +[metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric +[metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric diff --git a/vendor/go.opentelemetry.io/otel/CODEOWNERS b/vendor/go.opentelemetry.io/otel/CODEOWNERS index 196df9cfd89..623740007d4 100644 --- a/vendor/go.opentelemetry.io/otel/CODEOWNERS +++ b/vendor/go.opentelemetry.io/otel/CODEOWNERS @@ -12,6 +12,6 @@ # https://help.github.com/en/articles/about-code-owners # -* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo +* @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu -CODEOWNERS @MrAlias @Aneurysm9 +CODEOWNERS @MrAlias @MadVikingGod @pellared \ No newline at end of file diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md index 51ab52c6384..a00dbca7b08 100644 --- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md +++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md @@ -6,7 +6,7 @@ OpenTelemetry repo for information on this and other language SIGs. See the [public meeting -notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b) +notes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit) for a summary description of past meetings. To request edit access, join the meeting or get in touch on [Slack](https://cloud-native.slack.com/archives/C01NPAXACKT). @@ -15,11 +15,11 @@ join the meeting or get in touch on You can view and edit the source code by cloning this repository: -```bash +```sh git clone https://github.com/open-telemetry/opentelemetry-go.git ``` -Run `make test` to run the tests instead of `go test`. +Run `make test` to run the tests instead of `go test`. There are some generated files checked into the repo. To make sure that the generated files are up-to-date, run `make` (or `make @@ -28,6 +28,11 @@ precommit` - the `precommit` target is the default). The `precommit` target also fixes the formatting of the code and checks the status of the go module files. +Additionally, there is a `codespell` target that checks for common +typos in the code. It is not run by default, but you can run it +manually with `make codespell`. It will set up a virtual environment +in `venv` and install `codespell` there. + If after running `make precommit` the output of `git status` contains `nothing to commit, working tree clean` then it means that everything is up-to-date and properly formatted. @@ -43,7 +48,7 @@ To create a new PR, fork the project in GitHub and clone the upstream repo: ```sh -$ go get -d go.opentelemetry.io/otel +go get -d go.opentelemetry.io/otel ``` (This may print some warning about "build constraints exclude all Go @@ -53,7 +58,7 @@ This will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`. You can alternatively use `git` directly with: ```sh -$ git clone https://github.com/open-telemetry/opentelemetry-go +git clone https://github.com/open-telemetry/opentelemetry-go ``` (Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name - @@ -66,20 +71,20 @@ current working directory. Enter the newly created directory and add your fork as a new remote: ```sh -$ git remote add git@github.com:/opentelemetry-go +git remote add git@github.com:/opentelemetry-go ``` Check out a new branch, make modifications, run linters and tests, update `CHANGELOG.md`, and push the branch to your fork: ```sh -$ git checkout -b +git checkout -b # edit files # update changelog -$ make precommit -$ git add -p -$ git commit -$ git push +make precommit +git add -p +git commit +git push ``` Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull @@ -94,37 +99,66 @@ request ID to the entry you added to `CHANGELOG.md`. ### How to Get PRs Merged -A PR is considered to be **ready to merge** when: - -* It has received two approvals from Collaborators/Maintainers (at - different companies). This is not enforced through technical means - and a PR may be **ready to merge** with a single approval if the change - and its approach have been discussed and consensus reached. -* Feedback has been addressed. -* Any substantive changes to your PR will require that you clear any prior - Approval reviews, this includes changes resulting from other feedback. Unless - the approver explicitly stated that their approval will persist across - changes it should be assumed that the PR needs their review again. Other - project members (e.g. approvers, maintainers) can help with this if there are - any questions or if you forget to clear reviews. -* It has been open for review for at least one working day. This gives - people reasonable time to review. -* Trivial changes (typo, cosmetic, doc, etc.) do not have to wait for - one day and may be merged with a single Maintainer's approval. -* `CHANGELOG.md` has been updated to reflect what has been - added, changed, removed, or fixed. -* Urgent fix can take exception as long as it has been actively - communicated. - -Any Maintainer can merge the PR once it is **ready to merge**. +A PR is considered **ready to merge** when: + +* It has received two qualified approvals[^1]. + + This is not enforced through automation, but needs to be validated by the + maintainer merging. + * The qualified approvals need to be from [Approver]s/[Maintainer]s + affiliated with different companies. Two qualified approvals from + [Approver]s or [Maintainer]s affiliated with the same company counts as a + single qualified approval. + * PRs introducing changes that have already been discussed and consensus + reached only need one qualified approval. The discussion and resolution + needs to be linked to the PR. + * Trivial changes[^2] only need one qualified approval. + +* All feedback has been addressed. + * All PR comments and suggestions are resolved. + * All GitHub Pull Request reviews with a status of "Request changes" have + been addressed. Another review by the objecting reviewer with a different + status can be submitted to clear the original review, or the review can be + dismissed by a [Maintainer] when the issues from the original review have + been addressed. + * Any comments or reviews that cannot be resolved between the PR author and + reviewers can be submitted to the community [Approver]s and [Maintainer]s + during the weekly SIG meeting. If consensus is reached among the + [Approver]s and [Maintainer]s during the SIG meeting the objections to the + PR may be dismissed or resolved or the PR closed by a [Maintainer]. + * Any substantive changes to the PR require existing Approval reviews be + cleared unless the approver explicitly states that their approval persists + across changes. This includes changes resulting from other feedback. + [Approver]s and [Maintainer]s can help in clearing reviews and they should + be consulted if there are any questions. + +* The PR branch is up to date with the base branch it is merging into. + * To ensure this does not block the PR, it should be configured to allow + maintainers to update it. + +* It has been open for review for at least one working day. This gives people + reasonable time to review. + * Trivial changes[^2] do not have to wait for one day and may be merged with + a single [Maintainer]'s approval. + +* All required GitHub workflows have succeeded. +* Urgent fix can take exception as long as it has been actively communicated + among [Maintainer]s. + +Any [Maintainer] can merge the PR once the above criteria have been met. + +[^1]: A qualified approval is a GitHub Pull Request review with "Approve" + status from an OpenTelemetry Go [Approver] or [Maintainer]. +[^2]: Trivial changes include: typo corrections, cosmetic non-substantive + changes, documentation corrections or updates, dependency updates, etc. ## Design Choices As with other OpenTelemetry clients, opentelemetry-go follows the -[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification). +[OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel). It's especially valuable to read through the [library -guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md). +guidelines](https://opentelemetry.io/docs/specs/otel/library-guidelines). ### Focus on Capabilities, Not Structure Compliance @@ -140,8 +174,28 @@ It is preferable to have contributions follow the idioms of the language rather than conform to specific API names or argument patterns in the spec. -For a deeper discussion, see: -https://github.com/open-telemetry/opentelemetry-specification/issues/165 +For a deeper discussion, see +[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165). + +## Documentation + +Each (non-internal, non-test) package must be documented using +[Go Doc Comments](https://go.dev/doc/comment), +preferably in a `doc.go` file. + +Prefer using [Examples](https://pkg.go.dev/testing#hdr-Examples) +instead of putting code snippets in Go doc comments. +In some cases, you can even create [Testable Examples](https://go.dev/blog/examples). + +You can install and run a "local Go Doc site" in the following way: + + ```sh + go install golang.org/x/pkgsite/cmd/pkgsite@latest + pkgsite + ``` + +[`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric) +is an example of a very well-documented package. ## Style Guide @@ -166,32 +220,40 @@ to the reasons why. ### Configuration -When creating an instantiation function for a complex `struct` it is useful -to allow variable number of options to be applied. However, the strong type -system of Go restricts the function design options. There are a few ways to -solve this problem, but we have landed on the following design. +When creating an instantiation function for a complex `type T struct`, it is +useful to allow variable number of options to be applied. However, the strong +type system of Go restricts the function design options. There are a few ways +to solve this problem, but we have landed on the following design. #### `config` Configuration should be held in a `struct` named `config`, or prefixed with specific type name this Configuration applies to if there are multiple -`config` in the package. This `struct` must contain configuration options. +`config` in the package. This type must contain configuration options. ```go // config contains configuration options for a thing. type config struct { - // options ... + // options ... } ``` -In general the `config` `struct` will not need to be used externally to the +In general the `config` type will not need to be used externally to the package and should be unexported. If, however, it is expected that the user will likely want to build custom options for the configuration, the `config` should be exported. Please, include in the documentation for the `config` how the user can extend the configuration. -It is important that `config` are not shared across package boundaries. -Meaning a `config` from one package should not be directly used by another. +It is important that internal `config` are not shared across package boundaries. +Meaning a `config` from one package should not be directly used by another. The +one exception is the API packages. The configs from the base API, eg. +`go.opentelemetry.io/otel/trace.TracerConfig` and +`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed +by the SDK therefore it is expected that these are exported. + +When a config is exported we want to maintain forward and backward +compatibility, to achieve this no fields should be exported but should +instead be accessed by methods. Optionally, it is common to include a `newConfig` function (with the same naming scheme). This function wraps any defaults setting and looping over @@ -199,18 +261,18 @@ all options to create a configured `config`. ```go // newConfig returns an appropriately configured config. -func newConfig([]Option) config { - // Set default values for config. - config := config{/* […] */} - for _, option := range options { - option.Apply(&config) - } - // Preform any validation here. - return config +func newConfig(options ...Option) config { + // Set default values for config. + config := config{/* […] */} + for _, option := range options { + config = option.apply(config) + } + // Perform any validation here. + return config } ``` -If validation of the `config` options is also preformed this can return an +If validation of the `config` options is also performed this can return an error as well that is expected to be handled by the instantiation function or propagated to the user. @@ -224,10 +286,17 @@ To set the value of the options a `config` contains, a corresponding ```go type Option interface { - Apply(*config) + apply(config) config } ``` +Having `apply` unexported makes sure that it will not be used externally. +Moreover, the interface becomes sealed so the user cannot easily implement +the interface on its own. + +The `apply` method should return a modified version of the passed config. +This approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap. + The name of the interface should be prefixed in the same way the corresponding `config` is (if at all). @@ -250,53 +319,74 @@ func With*(…) Option { … } ```go type defaultFalseOption bool -func (o defaultFalseOption) Apply(c *config) { - c.Bool = bool(o) +func (o defaultFalseOption) apply(c config) config { + c.Bool = bool(o) + return c } -// WithOption sets a T* to have an option included. +// WithOption sets a T to have an option included. func WithOption() Option { - return defaultFalseOption(true) + return defaultFalseOption(true) } ``` ```go type defaultTrueOption bool -func (o defaultTrueOption) Apply(c *config) { - c.Bool = bool(o) +func (o defaultTrueOption) apply(c config) config { + c.Bool = bool(o) + return c } -// WithoutOption sets a T* to have Bool option excluded. +// WithoutOption sets a T to have Bool option excluded. func WithoutOption() Option { - return defaultTrueOption(false) + return defaultTrueOption(false) } -```` +``` ##### Declared Type Options ```go type myTypeOption struct { - MyType MyType + MyType MyType +} + +func (o myTypeOption) apply(c config) config { + c.MyType = o.MyType + return c +} + +// WithMyType sets T to have include MyType. +func WithMyType(t MyType) Option { + return myTypeOption{t} } +``` + +##### Functional Options + +```go +type optionFunc func(config) config -func (o myTypeOption) Apply(c *config) { - c.MyType = o.MyType +func (fn optionFunc) apply(c config) config { + return fn(c) } -// WithMyType sets T* to have include MyType. +// WithMyType sets t as MyType. func WithMyType(t MyType) Option { - return myTypeOption{t} + return optionFunc(func(c config) config { + c.MyType = t + return c + }) } ``` #### Instantiation -Using this configuration pattern to configure instantiation with a `New*` +Using this configuration pattern to configure instantiation with a `NewT` function. ```go -func NewT*(options ...Option) T* {…} +func NewT(options ...Option) T {…} ``` Any required parameters can be declared before the variadic `options`. @@ -320,12 +410,12 @@ type config struct { // DogOption apply Dog specific options. type DogOption interface { - ApplyDog(*config) + applyDog(config) config } // BirdOption apply Bird specific options. type BirdOption interface { - ApplyBird(*config) + applyBird(config) config } // Option apply options for all animals. @@ -335,23 +425,42 @@ type Option interface { } type weightOption float64 -func (o weightOption) ApplyDog(c *config) { c.Weight = float64(o) } -func (o weightOption) ApplyBird(c *config) { c.Weight = float64(o) } -func WithWeight(w float64) Option { return weightOption(w) } + +func (o weightOption) applyDog(c config) config { + c.Weight = float64(o) + return c +} + +func (o weightOption) applyBird(c config) config { + c.Weight = float64(o) + return c +} + +func WithWeight(w float64) Option { return weightOption(w) } type furColorOption string -func (o furColorOption) ApplyDog(c *config) { c.Color = string(o) } -func WithFurColor(c string) DogOption { return furColorOption(c) } + +func (o furColorOption) applyDog(c config) config { + c.Color = string(o) + return c +} + +func WithFurColor(c string) DogOption { return furColorOption(c) } type maxAltitudeOption float64 -func (o maxAltitudeOption) ApplyBird(c *config) { c.MaxAltitude = float64(o) } -func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) } + +func (o maxAltitudeOption) applyBird(c config) config { + c.MaxAltitude = float64(o) + return c +} + +func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) } func NewDog(name string, o ...DogOption) Dog {…} func NewBird(name string, o ...BirdOption) Bird {…} ``` -### Interface Type +### Interfaces To allow other developers to better comprehend the code, it is important to ensure it is sufficiently documented. One simple measure that contributes @@ -359,22 +468,153 @@ to this aim is self-documenting by naming method parameters. Therefore, where appropriate, methods of every exported interface type should have their parameters appropriately named. +#### Interface Stability + +All exported stable interfaces that include the following warning in their +documentation are allowed to be extended with additional methods. + +> Warning: methods may be added to this interface in minor releases. + +These interfaces are defined by the OpenTelemetry specification and will be +updated as the specification evolves. + +Otherwise, stable interfaces MUST NOT be modified. + +#### How to Change Specification Interfaces + +When an API change must be made, we will update the SDK with the new method one +release before the API change. This will allow the SDK one version before the +API change to work seamlessly with the new API. + +If an incompatible version of the SDK is used with the new API the application +will fail to compile. + +#### How Not to Change Specification Interfaces + +We have explored using a v2 of the API to change interfaces and found that there +was no way to introduce a v2 and have it work seamlessly with the v1 of the API. +Problems happened with libraries that upgraded to v2 when an application did not, +and would not produce any telemetry. + +More detail of the approaches considered and their limitations can be found in +the [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920) +issue. + +#### How to Change Other Interfaces + +If new functionality is needed for an interface that cannot be changed it MUST +be added by including an additional interface. That added interface can be a +simple interface for the specific functionality that you want to add or it can +be a super-set of the original interface. For example, if you wanted to a +`Close` method to the `Exporter` interface: + +```go +type Exporter interface { + Export() +} +``` + +A new interface, `Closer`, can be added: + +```go +type Closer interface { + Close() +} +``` + +Code that is passed the `Exporter` interface can now check to see if the passed +value also satisfies the new interface. E.g. + +```go +func caller(e Exporter) { + /* ... */ + if c, ok := e.(Closer); ok { + c.Close() + } + /* ... */ +} +``` + +Alternatively, a new type that is the super-set of an `Exporter` can be created. + +```go +type ClosingExporter struct { + Exporter + Close() +} +``` + +This new type can be used similar to the simple interface above in that a +passed `Exporter` type can be asserted to satisfy the `ClosingExporter` type +and the `Close` method called. + +This super-set approach can be useful if there is explicit behavior that needs +to be coupled with the original type and passed as a unified type to a new +function, but, because of this coupling, it also limits the applicability of +the added functionality. If there exist other interfaces where this +functionality should be added, each one will need their own super-set +interfaces and will duplicate the pattern. For this reason, the simple targeted +interface that defines the specific functionality should be preferred. + +### Testing + +The tests should never leak goroutines. + +Use the term `ConcurrentSafe` in the test name when it aims to verify the +absence of race conditions. + +### Internal packages + +The use of internal packages should be scoped to a single module. A sub-module +should never import from a parent internal package. This creates a coupling +between the two modules where a user can upgrade the parent without the child +and if the internal package API has changed it will fail to upgrade[^3]. + +There are two known exceptions to this rule: + +- `go.opentelemetry.io/otel/internal/global` + - This package manages global state for all of opentelemetry-go. It needs to + be a single package in order to ensure the uniqueness of the global state. +- `go.opentelemetry.io/otel/internal/baggage` + - This package provides values in a `context.Context` that need to be + recognized by `go.opentelemetry.io/otel/baggage` and + `go.opentelemetry.io/otel/bridge/opentracing` but remain private. + +If you have duplicate code in multiple modules, make that code into a Go +template stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl] +to render the templates in the desired locations. See [#4404] for an example of +this. + +[^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548 + ## Approvers and Maintainers -Approvers: +### Approvers - [Evan Torrie](https://github.com/evantorrie), Verizon Media -- [Josh MacDonald](https://github.com/jmacd), LightStep -- [Sam Xie](https://github.com/XSAM) +- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics - [David Ashpole](https://github.com/dashpole), Google -- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep +- [Chester Cheung](https://github.com/hanyuancheung), Tencent +- [Damien Mathieu](https://github.com/dmathieu), Elastic +- [Anthony Mirabella](https://github.com/Aneurysm9), AWS -Maintainers: +### Maintainers -- [Anthony Mirabella](https://github.com/Aneurysm9), AWS +- [Aaron Clawson](https://github.com/MadVikingGod), LightStep +- [Robert Pająk](https://github.com/pellared), Splunk - [Tyler Yahn](https://github.com/MrAlias), Splunk +### Emeritus + +- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep +- [Josh MacDonald](https://github.com/jmacd), LightStep + ### Become an Approver or a Maintainer See the [community membership document in OpenTelemetry community repo](https://github.com/open-telemetry/community/blob/main/community-membership.md). + +[Approver]: #approvers +[Maintainer]: #maintainers +[gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl +[#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404 diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index b290b667101..5c311706b0c 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -12,14 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -EXAMPLES := $(shell ./get_main_pkgs.sh ./example) TOOLS_MOD_DIR := ./internal/tools -# All source code and documents. Used in spell check. ALL_DOCS := $(shell find . -name '*.md' -type f | sort) -# All directories with go.mod files related to opentelemetry library. Used for building, testing and linting. -ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example' | sort)) $(shell find ./example -type f -name 'go.mod' -exec dirname {} \; | sort) -ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort) +ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort) +OTEL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(ALL_GO_MOD_DIRS)) +ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | grep -E -v '^./example|^$(TOOLS_MOD_DIR)' | sort) GO = go TIMEOUT = 60 @@ -27,8 +25,8 @@ TIMEOUT = 60 .DEFAULT_GOAL := precommit .PHONY: precommit ci -precommit: dependabot-check license-check lint build examples test-default -ci: precommit check-clean-work-tree test-coverage +precommit: generate dependabot-generate license-check misspell go-mod-tidy golangci-lint-fix test-default +ci: generate dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage # Tools @@ -40,133 +38,216 @@ $(TOOLS)/%: | $(TOOLS) cd $(TOOLS_MOD_DIR) && \ $(GO) build -o $@ $(PACKAGE) +MULTIMOD = $(TOOLS)/multimod +$(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod + +SEMCONVGEN = $(TOOLS)/semconvgen +$(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen + CROSSLINK = $(TOOLS)/crosslink -$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink +$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink + +SEMCONVKIT = $(TOOLS)/semconvkit +$(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit + +DBOTCONF = $(TOOLS)/dbotconf +$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf GOLANGCI_LINT = $(TOOLS)/golangci-lint $(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint MISSPELL = $(TOOLS)/misspell -$(TOOLS)/misspell: PACKAGE= github.com/client9/misspell/cmd/misspell +$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell + +GOCOVMERGE = $(TOOLS)/gocovmerge +$(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge STRINGER = $(TOOLS)/stringer $(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer +PORTO = $(TOOLS)/porto +$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto + +GOJQ = $(TOOLS)/gojq $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq +GOTMPL = $(TOOLS)/gotmpl +$(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl + +GORELEASE = $(TOOLS)/gorelease +$(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease + .PHONY: tools -tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(STRINGER) $(TOOLS)/gojq +tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) + +# Virtualized python tools via docker + +# The directory where the virtual environment is created. +VENVDIR := venv + +# The directory where the python tools are installed. +PYTOOLS := $(VENVDIR)/bin + +# The pip executable in the virtual environment. +PIP := $(PYTOOLS)/pip + +# The directory in the docker image where the current directory is mounted. +WORKDIR := /workdir + +# The python image to use for the virtual environment. +PYTHONIMAGE := python:3.11.3-slim-bullseye + +# Run the python image with the current directory mounted. +DOCKERPY := docker run --rm -v "$(CURDIR):$(WORKDIR)" -w $(WORKDIR) $(PYTHONIMAGE) + +# Create a virtual environment for Python tools. +$(PYTOOLS): +# The `--upgrade` flag is needed to ensure that the virtual environment is +# created with the latest pip version. + @$(DOCKERPY) bash -c "python3 -m venv $(VENVDIR) && $(PIP) install --upgrade pip" + +# Install python packages into the virtual environment. +$(PYTOOLS)/%: | $(PYTOOLS) + @$(DOCKERPY) $(PIP) install -r requirements.txt + +CODESPELL = $(PYTOOLS)/codespell +$(CODESPELL): PACKAGE=codespell + +# Generate + +.PHONY: generate +generate: go-generate vanity-import-fix + +.PHONY: go-generate +go-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%) +go-generate/%: DIR=$* +go-generate/%: | $(STRINGER) $(GOTMPL) + @echo "$(GO) generate $(DIR)/..." \ + && cd $(DIR) \ + && PATH="$(TOOLS):$${PATH}" $(GO) generate ./... +.PHONY: vanity-import-fix +vanity-import-fix: | $(PORTO) + @$(PORTO) --include-internal -w . + +# Generate go.work file for local development. +.PHONY: go-work +go-work: | $(CROSSLINK) + $(CROSSLINK) work --root=$(shell pwd) # Build -.PHONY: examples generate build -examples: - @set -e; for dir in $(EXAMPLES); do \ - echo "$(GO) build $${dir}/..."; \ - (cd "$${dir}" && \ - $(GO) build .); \ - done +.PHONY: build -generate: $(STRINGER) - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "$(GO) generate $${dir}/..."; \ - (cd "$${dir}" && \ - PATH="$(TOOLS):$${PATH}" $(GO) generate ./...); \ - done +build: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%) +build/%: DIR=$* +build/%: + @echo "$(GO) build $(DIR)/..." \ + && cd $(DIR) \ + && $(GO) build ./... -build: generate - # Build all package code including testing code. - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "$(GO) build $${dir}/..."; \ - (cd "$${dir}" && \ - $(GO) build ./... && \ - $(GO) list ./... \ - | grep -v third_party \ - | xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null); \ - done +build-tests/%: DIR=$* +build-tests/%: + @echo "$(GO) build tests $(DIR)/..." \ + && cd $(DIR) \ + && $(GO) list ./... \ + | grep -v third_party \ + | xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null # Tests TEST_TARGETS := test-default test-bench test-short test-verbose test-race .PHONY: $(TEST_TARGETS) test -test-default: ARGS=-v -race +test-default test-race: ARGS=-race test-bench: ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=. test-short: ARGS=-short -test-verbose: ARGS=-v -test-race: ARGS=-race +test-verbose: ARGS=-v -race $(TEST_TARGETS): test -test: - @set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $${dir}/..."; \ - (cd "$${dir}" && \ - $(GO) list ./... \ - | grep -v third_party \ - | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)); \ - done +test: $(OTEL_GO_MOD_DIRS:%=test/%) +test/%: DIR=$* +test/%: + @echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $(DIR)/..." \ + && cd $(DIR) \ + && $(GO) list ./... \ + | grep -v third_party \ + | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS) COVERAGE_MODE = atomic COVERAGE_PROFILE = coverage.out .PHONY: test-coverage -test-coverage: +test-coverage: | $(GOCOVMERGE) @set -e; \ printf "" > coverage.txt; \ for dir in $(ALL_COVERAGE_MOD_DIRS); do \ - echo "$(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \ + echo "$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \ (cd "$${dir}" && \ $(GO) list ./... \ | grep -v third_party \ + | grep -v 'semconv/v.*' \ | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \ $(GO) tool cover -html=coverage.out -o coverage.html); \ - [ -f "$${dir}/coverage.out" ] && cat "$${dir}/coverage.out" >> coverage.txt; \ done; \ - sed -i.bak -e '2,$$ { /^mode: /d; }' coverage.txt + $(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt + +.PHONY: golangci-lint golangci-lint-fix +golangci-lint-fix: ARGS=--fix +golangci-lint-fix: golangci-lint +golangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%) +golangci-lint/%: DIR=$* +golangci-lint/%: | $(GOLANGCI_LINT) + @echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \ + && cd $(DIR) \ + && $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS) + +.PHONY: crosslink +crosslink: | $(CROSSLINK) + @echo "Updating intra-repository dependencies in all go modules" \ + && $(CROSSLINK) --root=$(shell pwd) --prune + +.PHONY: go-mod-tidy +go-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%) +go-mod-tidy/%: DIR=$* +go-mod-tidy/%: | crosslink + @echo "$(GO) mod tidy in $(DIR)" \ + && cd $(DIR) \ + && $(GO) mod tidy -compat=1.20 + +.PHONY: lint-modules +lint-modules: go-mod-tidy .PHONY: lint -lint: misspell lint-modules | $(GOLANGCI_LINT) - set -e; for dir in $(ALL_GO_MOD_DIRS); do \ - echo "golangci-lint in $${dir}"; \ - (cd "$${dir}" && \ - $(GOLANGCI_LINT) run --fix && \ - $(GOLANGCI_LINT) run); \ - done +lint: misspell lint-modules golangci-lint + +.PHONY: vanity-import-check +vanity-import-check: | $(PORTO) + @$(PORTO) --include-internal -l . || ( echo "(run: make vanity-import-fix)"; exit 1 ) .PHONY: misspell misspell: | $(MISSPELL) - $(MISSPELL) -w $(ALL_DOCS) + @$(MISSPELL) -w $(ALL_DOCS) -.PHONY: lint-modules -lint-modules: | $(CROSSLINK) - set -e; for dir in $(ALL_GO_MOD_DIRS) $(TOOLS_MOD_DIR); do \ - echo "$(GO) mod tidy in $${dir}"; \ - (cd "$${dir}" && \ - $(GO) mod tidy); \ - done - echo "cross-linking all go modules" - $(CROSSLINK) +.PHONY: codespell +codespell: | $(CODESPELL) + @$(DOCKERPY) $(CODESPELL) .PHONY: license-check license-check: - @licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './exporters/otlp/internal/opentelemetry-proto/*') ; do \ - awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \ + @licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \ + awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=4 { found=1; next } END { if (!found) print FILENAME }' $$f; \ done); \ if [ -n "$${licRes}" ]; then \ echo "license header checking failed:"; echo "$${licRes}"; \ exit 1; \ fi +DEPENDABOT_CONFIG = .github/dependabot.yml .PHONY: dependabot-check -dependabot-check: - @result=$$( \ - for f in $$( find . -type f -name go.mod -exec dirname {} \; | sed 's/^.\/\?/\//' ); \ - do grep -q "$$f" .github/dependabot.yml \ - || echo "$$f"; \ - done; \ - ); \ - if [ -n "$$result" ]; then \ - echo "missing go.mod dependabot check:"; echo "$$result"; \ - exit 1; \ - fi +dependabot-check: | $(DBOTCONF) + @$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || ( echo "(run: make dependabot-generate)"; exit 1 ) + +.PHONY: dependabot-generate +dependabot-generate: | $(DBOTCONF) + @$(DBOTCONF) generate > $(DEPENDABOT_CONFIG) .PHONY: check-clean-work-tree check-clean-work-tree: @@ -177,3 +258,34 @@ check-clean-work-tree: git status; \ exit 1; \ fi + +SEMCONVPKG ?= "semconv/" +.PHONY: semconv-generate +semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT) + [ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry semantic-conventions tag"; exit 1 ) + [ "$(OTEL_SEMCONV_REPO)" ] || ( echo "OTEL_SEMCONV_REPO unset: missing path to opentelemetry semantic-conventions repo"; exit 1 ) + $(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=span -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" + $(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=attribute_group -p conventionType=trace -f attribute_group.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" + $(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=event -p conventionType=event -f event.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" + $(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" + $(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)" + +.PHONY: gorelease +gorelease: $(OTEL_GO_MOD_DIRS:%=gorelease/%) +gorelease/%: DIR=$* +gorelease/%:| $(GORELEASE) + @echo "gorelease in $(DIR):" \ + && cd $(DIR) \ + && $(GORELEASE) \ + || echo "" + +.PHONY: prerelease +prerelease: | $(MULTIMOD) + @[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) + $(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET} + +COMMIT ?= "HEAD" +.PHONY: add-tags +add-tags: | $(MULTIMOD) + @[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) + $(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT} diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index c841ba896e5..634326ef833 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -1,48 +1,68 @@ # OpenTelemetry-Go [![CI](https://github.com/open-telemetry/opentelemetry-go/workflows/ci/badge.svg)](https://github.com/open-telemetry/opentelemetry-go/actions?query=workflow%3Aci+branch%3Amain) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-go/coverage.svg?branch=main)](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main) [![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel)](https://pkg.go.dev/go.opentelemetry.io/otel) [![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/otel)](https://goreportcard.com/report/go.opentelemetry.io/otel) [![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT) - -The Go [OpenTelemetry](https://opentelemetry.io/) implementation. +OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/). +It provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms. ## Project Status -**Warning**: this project is currently in a pre-GA phase. Backwards -incompatible changes may be introduced in subsequent minor version releases as -we work to track the evolving OpenTelemetry specification and user feedback. +| Signal | Status | Project | +|---------|------------|-----------------------| +| Traces | Stable | N/A | +| Metrics | Mixed [1] | [Go: Metric SDK (GA)] | +| Logs | Frozen [2] | N/A | + +[Go: Metric SDK (GA)]: https://github.com/orgs/open-telemetry/projects/34 -Our progress towards a GA release candidate is tracked in [this project -board](https://github.com/orgs/open-telemetry/projects/5). This release -candidate will follow semantic versioning and will be released with a major -version greater than zero. +- [1]: [Metrics API](https://pkg.go.dev/go.opentelemetry.io/otel/metric) is Stable. [Metrics SDK](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) is Beta. +- [2]: The Logs signal development is halted for this project while we stabilize the Metrics SDK. + No Logs Pull Requests are currently being accepted. -Progress and status specific to this repository is tracked in our local +Progress and status specific to this repository is tracked in our [project boards](https://github.com/open-telemetry/opentelemetry-go/projects) and [milestones](https://github.com/open-telemetry/opentelemetry-go/milestones). Project versioning information and stability guarantees can be found in the -[versioning documentation](./VERSIONING.md). +[versioning documentation](VERSIONING.md). ### Compatibility -This project is tested on the following systems. +OpenTelemetry-Go ensures compatibility with the current supported versions of +the [Go language](https://golang.org/doc/devel/release#policy): + +> Each major Go release is supported until there are two newer major releases. +> For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release. + +For versions of Go that are no longer supported upstream, opentelemetry-go will +stop ensuring compatibility with these versions in the following manner: + +- A minor release of opentelemetry-go will be made to add support for the new + supported release of Go. +- The following minor release of opentelemetry-go will remove compatibility + testing for the oldest (now archived upstream) version of Go. This, and + future, releases of opentelemetry-go may include features only supported by + the currently supported versions of Go. + +Currently, this project supports the following environments. | OS | Go Version | Architecture | -| ------- | ---------- | ------------ | -| Ubuntu | 1.15 | amd64 | -| Ubuntu | 1.14 | amd64 | -| Ubuntu | 1.15 | 386 | -| Ubuntu | 1.14 | 386 | -| MacOS | 1.15 | amd64 | -| MacOS | 1.14 | amd64 | -| Windows | 1.15 | amd64 | -| Windows | 1.14 | amd64 | -| Windows | 1.15 | 386 | -| Windows | 1.14 | 386 | +|---------|------------|--------------| +| Ubuntu | 1.21 | amd64 | +| Ubuntu | 1.20 | amd64 | +| Ubuntu | 1.21 | 386 | +| Ubuntu | 1.20 | 386 | +| MacOS | 1.21 | amd64 | +| MacOS | 1.20 | amd64 | +| Windows | 1.21 | amd64 | +| Windows | 1.20 | amd64 | +| Windows | 1.21 | 386 | +| Windows | 1.20 | 386 | While this project should work for other systems, no compatibility guarantees are made for those systems currently. @@ -68,7 +88,7 @@ libraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/ If you need to extend the telemetry an instrumentation library provides or want to build your own instrumentation for your application directly you will need to use the -[go.opentelemetry.io/otel/api](https://pkg.go.dev/go.opentelemetry.io/otel/api) +[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel) package. The included [examples](./example/) are a good way to see some practical uses of this process. @@ -77,15 +97,14 @@ practical uses of this process. Now that your application is instrumented to collect telemetry, it needs an export pipeline to send that telemetry to an observability platform. -You can find officially supported exporters [here](./exporters/) and in the -companion [contrib -repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/exporters/metric). -Additionally, there are many vendor specific or 3rd party exporters for -OpenTelemetry. These exporters are broken down by -[trace](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/export/trace?tab=importedby) -and -[metric](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/export/metric?tab=importedby) -support. +All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters). + +| Exporter | Metrics | Traces | +|---------------------------------------|:-------:|:------:| +| [OTLP](./exporters/otlp/) | ✓ | ✓ | +| [Prometheus](./exporters/prometheus/) | ✓ | | +| [stdout](./exporters/stdout/) | ✓ | ✓ | +| [Zipkin](./exporters/zipkin/) | | ✓ | ## Contributing diff --git a/vendor/go.opentelemetry.io/otel/RELEASING.md b/vendor/go.opentelemetry.io/otel/RELEASING.md index 71d23b47a54..82ce3ee46a1 100644 --- a/vendor/go.opentelemetry.io/otel/RELEASING.md +++ b/vendor/go.opentelemetry.io/otel/RELEASING.md @@ -1,22 +1,58 @@ # Release Process +## Semantic Convention Generation + +New versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated. +The `semconv-generate` make target is used for this. + +1. Checkout a local copy of the [OpenTelemetry Semantic Conventions] to the desired release tag. +2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest` +3. Run the `make semconv-generate ...` target from this repository. + +For example, + +```sh +export TAG="v1.21.0" # Change to the release version you are generating. +export OTEL_SEMCONV_REPO="/absolute/path/to/opentelemetry/semantic-conventions" +docker pull otel/semconvgen:latest +make semconv-generate # Uses the exported TAG and OTEL_SEMCONV_REPO. +``` + +This should create a new sub-package of [`semconv`](./semconv). +Ensure things look correct before submitting a pull request to include the addition. + +## Breaking changes validation + +You can run `make gorelease` that runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes done in the public API. + +You can check/report problems with `gorelease` [here](https://golang.org/issues/26420). + ## Pre-Release +First, decide which module sets will be released and update their versions +in `versions.yaml`. Commit this change to a new branch. + Update go.mod for submodules to depend on the new release which will happen in the next step. -1. Run the pre-release script. It creates a branch `pre_release_` that will contain all release changes. +1. Run the `prerelease` make target. It creates a branch + `prerelease__` that will contain all release changes. ``` - ./pre_release.sh -t + make prerelease MODSET= ``` 2. Verify the changes. ``` - git diff main + git diff ...prerelease__ ``` This should have changed the version for all modules to be ``. + If these changes look correct, merge them into your pre-release branch: + + ```go + git merge prerelease__ + ``` 3. Update the [Changelog](./CHANGELOG.md). - Make sure all relevant changes for this release are included and are in language that non-contributors to the project can understand. @@ -32,24 +68,28 @@ Update go.mod for submodules to depend on the new release which will happen in t 4. Push the changes to upstream and create a Pull Request on GitHub. Be sure to include the curated changes from the [Changelog](./CHANGELOG.md) in the description. - ## Tag Once the Pull Request with all the version changes has been approved and merged it is time to tag the merged commit. ***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step! -Failure to do so will leave things in a broken state. +Failure to do so will leave things in a broken state. As long as you do not +change `versions.yaml` between pre-release and this step, things should be fine. ***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189). It is critical you make sure the version you push upstream is correct. [Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331). -1. Run the tag.sh script using the `` of the commit on the main branch for the merged Pull Request. +1. For each module set that will be released, run the `add-tags` make target + using the `` of the commit on the main branch for the merged Pull Request. ``` - ./tag.sh + make add-tags MODSET= COMMIT= ``` + It should only be necessary to provide an explicit `COMMIT` value if the + current `HEAD` of your working directory is not the correct commit. + 2. Push tags to the upstream remote (not your fork: `github.com/open-telemetry/opentelemetry-go.git`). Make sure you push all sub-modules as well. @@ -63,7 +103,6 @@ It is critical you make sure the version you push upstream is correct. Finally create a Release for the new `` on GitHub. The release body should include all the release notes from the Changelog for this release. -Additionally, the `tag.sh` script generates commit logs since last release which can be used to supplement the release notes. ## Verify Examples @@ -76,6 +115,25 @@ After releasing verify that examples build outside of the repository. The script copies examples into a different directory removes any `replace` declarations in `go.mod` and builds them. This ensures they build with the published release, not the local copy. -## Contrib Repository +## Post-Release + +### Contrib Repository Once verified be sure to [make a release for the `contrib` repository](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md) that uses this release. + +### Website Documentation + +Update the [Go instrumentation documentation] in the OpenTelemetry website under [content/en/docs/instrumentation/go]. +Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate. + +[OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions +[Go instrumentation documentation]: https://opentelemetry.io/docs/instrumentation/go/ +[content/en/docs/instrumentation/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/go + +### Demo Repository + +Bump the dependencies in the following Go services: + +- [`accountingservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/accountingservice) +- [`checkoutservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/checkoutservice) +- [`productcatalogservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice) diff --git a/vendor/go.opentelemetry.io/otel/VERSIONING.md b/vendor/go.opentelemetry.io/otel/VERSIONING.md index 3579b794ee9..412f1e362bb 100644 --- a/vendor/go.opentelemetry.io/otel/VERSIONING.md +++ b/vendor/go.opentelemetry.io/otel/VERSIONING.md @@ -12,7 +12,14 @@ is designed so the following goals can be achieved. * [Semantic import versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning) will be used. - * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html). + * Versions will comply with [semver + 2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions. + * New methods may be added to exported API interfaces. All exported + interfaces that fall within this exception will include the following + paragraph in their public documentation. + + > Warning: methods may be added to this interface in minor releases. + * If a module is version `v2` or higher, the major version of the module must be included as a `/vN` at the end of the module paths used in `go.mod` files (e.g., `module go.opentelemetry.io/otel/v2`, `require @@ -143,10 +150,10 @@ The `otel` package is refactored to remove its dependencies on `otel/metric` so it can be released as stable as well. With that done the following release candidates are made: -* `otel`: `v1.0.0-rc.1` -* `otel/trace`: `v1.0.0-rc.1` -* `otel/baggage`: `v1.0.0-rc.1` -* `otel/sdk/trace`: `v1.0.0-rc.1` +* `otel`: `v1.0.0-RC1` +* `otel/trace`: `v1.0.0-RC1` +* `otel/baggage`: `v1.0.0-RC1` +* `otel/sdk/trace`: `v1.0.0-RC1` The `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`. @@ -154,10 +161,10 @@ A few minor issues are discovered in the `otel/trace` package. These issues are resolved with some minor, but backwards incompatible, changes and are released as a second release candidate: -* `otel`: `v1.0.0-rc.2` -* `otel/trace`: `v1.0.0-rc.2` -* `otel/baggage`: `v1.0.0-rc.2` -* `otel/sdk/trace`: `v1.0.0-rc.2` +* `otel`: `v1.0.0-RC2` +* `otel/trace`: `v1.0.0-RC2` +* `otel/baggage`: `v1.0.0-RC2` +* `otel/sdk/trace`: `v1.0.0-RC2` Notice that all module version numbers are incremented to adhere to our versioning policy. @@ -198,12 +205,12 @@ As we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a point where they should be evaluated for stability. The `otel` module is reintegrated with the `otel/metric` package and the following release is made: -* `otel`: `v1.1.0-rc.1` -* `otel/trace`: `v1.1.0-rc.1` -* `otel/metric`: `v1.1.0-rc.1` -* `otel/baggage`: `v1.1.0-rc.1` -* `otel/sdk/trace`: `v1.1.0-rc.1` -* `otel/sdk/metric`: `v1.1.0-rc.1` +* `otel`: `v1.1.0-RC1` +* `otel/trace`: `v1.1.0-RC1` +* `otel/metric`: `v1.1.0-RC1` +* `otel/baggage`: `v1.1.0-RC1` +* `otel/sdk/trace`: `v1.1.0-RC1` +* `otel/sdk/metric`: `v1.1.0-RC1` All the modules are evaluated and determined to a viable stable release. They are then released as version `v1.1.0` (the minor version is incremented to diff --git a/vendor/go.opentelemetry.io/otel/attribute/doc.go b/vendor/go.opentelemetry.io/otel/attribute/doc.go index 44bc32c9e07..dafe7424dfb 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/doc.go +++ b/vendor/go.opentelemetry.io/otel/attribute/doc.go @@ -12,9 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// package attribute provides key and value attributes. -// -// This package is currently in a pre-GA phase. Backwards incompatible changes -// may be introduced in subsequent minor version releases as we work to track -// the evolving OpenTelemetry specification and user feedback. +// Package attribute provides key and value attributes. package attribute // import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/vendor/go.opentelemetry.io/otel/attribute/encoder.go index 8b940f78dc4..fe2bc5766cf 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/encoder.go +++ b/vendor/go.opentelemetry.io/otel/attribute/encoder.go @@ -21,19 +21,17 @@ import ( ) type ( - // Encoder is a mechanism for serializing a label set into a - // specific string representation that supports caching, to - // avoid repeated serialization. An example could be an - // exporter encoding the label set into a wire representation. + // Encoder is a mechanism for serializing an attribute set into a specific + // string representation that supports caching, to avoid repeated + // serialization. An example could be an exporter encoding the attribute + // set into a wire representation. Encoder interface { - // Encode returns the serialized encoding of the label - // set using its Iterator. This result may be cached - // by a attribute.Set. + // Encode returns the serialized encoding of the attribute set using + // its Iterator. This result may be cached by a attribute.Set. Encode(iterator Iterator) string - // ID returns a value that is unique for each class of - // label encoder. Label encoders allocate these using - // `NewEncoderID`. + // ID returns a value that is unique for each class of attribute + // encoder. Attribute encoders allocate these using `NewEncoderID`. ID() EncoderID } @@ -43,54 +41,53 @@ type ( value uint64 } - // defaultLabelEncoder uses a sync.Pool of buffers to reduce - // the number of allocations used in encoding labels. This - // implementation encodes a comma-separated list of key=value, - // with '/'-escaping of '=', ',', and '\'. - defaultLabelEncoder struct { - // pool is a pool of labelset builders. The buffers in this - // pool grow to a size that most label encodings will not - // allocate new memory. + // defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of + // allocations used in encoding attributes. This implementation encodes a + // comma-separated list of key=value, with '/'-escaping of '=', ',', and + // '\'. + defaultAttrEncoder struct { + // pool is a pool of attribute set builders. The buffers in this pool + // grow to a size that most attribute encodings will not allocate new + // memory. pool sync.Pool // *bytes.Buffer } ) -// escapeChar is used to ensure uniqueness of the label encoding where -// keys or values contain either '=' or ','. Since there is no parser -// needed for this encoding and its only requirement is to be unique, -// this choice is arbitrary. Users will see these in some exporters -// (e.g., stdout), so the backslash ('\') is used as a conventional choice. +// escapeChar is used to ensure uniqueness of the attribute encoding where +// keys or values contain either '=' or ','. Since there is no parser needed +// for this encoding and its only requirement is to be unique, this choice is +// arbitrary. Users will see these in some exporters (e.g., stdout), so the +// backslash ('\') is used as a conventional choice. const escapeChar = '\\' var ( - _ Encoder = &defaultLabelEncoder{} + _ Encoder = &defaultAttrEncoder{} - // encoderIDCounter is for generating IDs for other label - // encoders. + // encoderIDCounter is for generating IDs for other attribute encoders. encoderIDCounter uint64 defaultEncoderOnce sync.Once defaultEncoderID = NewEncoderID() - defaultEncoderInstance *defaultLabelEncoder + defaultEncoderInstance *defaultAttrEncoder ) -// NewEncoderID returns a unique label encoder ID. It should be -// called once per each type of label encoder. Preferably in init() or -// in var definition. +// NewEncoderID returns a unique attribute encoder ID. It should be called +// once per each type of attribute encoder. Preferably in init() or in var +// definition. func NewEncoderID() EncoderID { return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)} } -// DefaultEncoder returns a label encoder that encodes labels -// in such a way that each escaped label's key is followed by an equal -// sign and then by an escaped label's value. All key-value pairs are -// separated by a comma. +// DefaultEncoder returns an attribute encoder that encodes attributes in such +// a way that each escaped attribute's key is followed by an equal sign and +// then by an escaped attribute's value. All key-value pairs are separated by +// a comma. // -// Escaping is done by prepending a backslash before either a -// backslash, equal sign or a comma. +// Escaping is done by prepending a backslash before either a backslash, equal +// sign or a comma. func DefaultEncoder() Encoder { defaultEncoderOnce.Do(func() { - defaultEncoderInstance = &defaultLabelEncoder{ + defaultEncoderInstance = &defaultAttrEncoder{ pool: sync.Pool{ New: func() interface{} { return &bytes.Buffer{} @@ -101,15 +98,14 @@ func DefaultEncoder() Encoder { return defaultEncoderInstance } -// Encode is a part of an implementation of the LabelEncoder -// interface. -func (d *defaultLabelEncoder) Encode(iter Iterator) string { +// Encode is a part of an implementation of the AttributeEncoder interface. +func (d *defaultAttrEncoder) Encode(iter Iterator) string { buf := d.pool.Get().(*bytes.Buffer) defer d.pool.Put(buf) buf.Reset() for iter.Next() { - i, keyValue := iter.IndexedLabel() + i, keyValue := iter.IndexedAttribute() if i > 0 { _, _ = buf.WriteRune(',') } @@ -126,8 +122,8 @@ func (d *defaultLabelEncoder) Encode(iter Iterator) string { return buf.String() } -// ID is a part of an implementation of the LabelEncoder interface. -func (*defaultLabelEncoder) ID() EncoderID { +// ID is a part of an implementation of the AttributeEncoder interface. +func (*defaultAttrEncoder) ID() EncoderID { return defaultEncoderID } @@ -137,9 +133,9 @@ func copyAndEscape(buf *bytes.Buffer, val string) { for _, ch := range val { switch ch { case '=', ',', escapeChar: - buf.WriteRune(escapeChar) + _, _ = buf.WriteRune(escapeChar) } - buf.WriteRune(ch) + _, _ = buf.WriteRune(ch) } } diff --git a/vendor/go.opentelemetry.io/otel/attribute/filter.go b/vendor/go.opentelemetry.io/otel/attribute/filter.go new file mode 100644 index 00000000000..638c213d59a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/attribute/filter.go @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package attribute // import "go.opentelemetry.io/otel/attribute" + +// Filter supports removing certain attributes from attribute sets. When +// the filter returns true, the attribute will be kept in the filtered +// attribute set. When the filter returns false, the attribute is excluded +// from the filtered attribute set, and the attribute instead appears in +// the removed list of excluded attributes. +type Filter func(KeyValue) bool + +// NewAllowKeysFilter returns a Filter that only allows attributes with one of +// the provided keys. +// +// If keys is empty a deny-all filter is returned. +func NewAllowKeysFilter(keys ...Key) Filter { + if len(keys) <= 0 { + return func(kv KeyValue) bool { return false } + } + + allowed := make(map[Key]struct{}) + for _, k := range keys { + allowed[k] = struct{}{} + } + return func(kv KeyValue) bool { + _, ok := allowed[kv.Key] + return ok + } +} + +// NewDenyKeysFilter returns a Filter that only allows attributes +// that do not have one of the provided keys. +// +// If keys is empty an allow-all filter is returned. +func NewDenyKeysFilter(keys ...Key) Filter { + if len(keys) <= 0 { + return func(kv KeyValue) bool { return true } + } + + forbid := make(map[Key]struct{}) + for _, k := range keys { + forbid[k] = struct{}{} + } + return func(kv KeyValue) bool { + _, ok := forbid[kv.Key] + return !ok + } +} diff --git a/vendor/go.opentelemetry.io/otel/attribute/iterator.go b/vendor/go.opentelemetry.io/otel/attribute/iterator.go index e03aabb62bd..841b271fb7d 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/iterator.go +++ b/vendor/go.opentelemetry.io/otel/attribute/iterator.go @@ -14,16 +14,16 @@ package attribute // import "go.opentelemetry.io/otel/attribute" -// Iterator allows iterating over the set of labels in order, -// sorted by key. +// Iterator allows iterating over the set of attributes in order, sorted by +// key. type Iterator struct { storage *Set idx int } -// MergeIterator supports iterating over two sets of labels while -// eliminating duplicate values from the combined set. The first -// iterator value takes precedence. +// MergeIterator supports iterating over two sets of attributes while +// eliminating duplicate values from the combined set. The first iterator +// value takes precedence. type MergeIterator struct { one oneIterator two oneIterator @@ -31,13 +31,13 @@ type MergeIterator struct { } type oneIterator struct { - iter Iterator - done bool - label KeyValue + iter Iterator + done bool + attr KeyValue } -// Next moves the iterator to the next position. Returns false if there -// are no more labels. +// Next moves the iterator to the next position. Returns false if there are no +// more attributes. func (i *Iterator) Next() bool { i.idx++ return i.idx < i.Len() @@ -45,30 +45,41 @@ func (i *Iterator) Next() bool { // Label returns current KeyValue. Must be called only after Next returns // true. +// +// Deprecated: Use Attribute instead. func (i *Iterator) Label() KeyValue { - kv, _ := i.storage.Get(i.idx) - return kv + return i.Attribute() } -// Attribute is a synonym for Label(). +// Attribute returns the current KeyValue of the Iterator. It must be called +// only after Next returns true. func (i *Iterator) Attribute() KeyValue { - return i.Label() + kv, _ := i.storage.Get(i.idx) + return kv } // IndexedLabel returns current index and attribute. Must be called only // after Next returns true. +// +// Deprecated: Use IndexedAttribute instead. func (i *Iterator) IndexedLabel() (int, KeyValue) { - return i.idx, i.Label() + return i.idx, i.Attribute() } -// Len returns a number of labels in the iterator's `*Set`. +// IndexedAttribute returns current index and attribute. Must be called only +// after Next returns true. +func (i *Iterator) IndexedAttribute() (int, KeyValue) { + return i.idx, i.Attribute() +} + +// Len returns a number of attributes in the iterated set. func (i *Iterator) Len() int { return i.storage.Len() } -// ToSlice is a convenience function that creates a slice of labels -// from the passed iterator. The iterator is set up to start from the -// beginning before creating the slice. +// ToSlice is a convenience function that creates a slice of attributes from +// the passed iterator. The iterator is set up to start from the beginning +// before creating the slice. func (i *Iterator) ToSlice() []KeyValue { l := i.Len() if l == 0 { @@ -77,12 +88,12 @@ func (i *Iterator) ToSlice() []KeyValue { i.idx = -1 slice := make([]KeyValue, 0, l) for i.Next() { - slice = append(slice, i.Label()) + slice = append(slice, i.Attribute()) } return slice } -// NewMergeIterator returns a MergeIterator for merging two label sets +// NewMergeIterator returns a MergeIterator for merging two attribute sets. // Duplicates are resolved by taking the value from the first set. func NewMergeIterator(s1, s2 *Set) MergeIterator { mi := MergeIterator{ @@ -102,42 +113,49 @@ func makeOne(iter Iterator) oneIterator { func (oi *oneIterator) advance() { if oi.done = !oi.iter.Next(); !oi.done { - oi.label = oi.iter.Label() + oi.attr = oi.iter.Attribute() } } -// Next returns true if there is another label available. +// Next returns true if there is another attribute available. func (m *MergeIterator) Next() bool { if m.one.done && m.two.done { return false } if m.one.done { - m.current = m.two.label + m.current = m.two.attr m.two.advance() return true } if m.two.done { - m.current = m.one.label + m.current = m.one.attr m.one.advance() return true } - if m.one.label.Key == m.two.label.Key { - m.current = m.one.label // first iterator label value wins + if m.one.attr.Key == m.two.attr.Key { + m.current = m.one.attr // first iterator attribute value wins m.one.advance() m.two.advance() return true } - if m.one.label.Key < m.two.label.Key { - m.current = m.one.label + if m.one.attr.Key < m.two.attr.Key { + m.current = m.one.attr m.one.advance() return true } - m.current = m.two.label + m.current = m.two.attr m.two.advance() return true } // Label returns the current value after Next() returns true. +// +// Deprecated: Use Attribute instead. func (m *MergeIterator) Label() KeyValue { return m.current } + +// Attribute returns the current value after Next() returns true. +func (m *MergeIterator) Attribute() KeyValue { + return m.current +} diff --git a/vendor/go.opentelemetry.io/otel/attribute/key.go b/vendor/go.opentelemetry.io/otel/attribute/key.go index 492c438a9f5..0656a04e43b 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/key.go +++ b/vendor/go.opentelemetry.io/otel/attribute/key.go @@ -20,10 +20,8 @@ type Key string // Bool creates a KeyValue instance with a BOOL Value. // -// If creating both key and a bool value at the same time, then -// instead of calling Key(name).Bool(value) consider using a -// convenience function provided by the api/key package - -// key.Bool(name, value). +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Bool(name, value). func (k Key) Bool(v bool) KeyValue { return KeyValue{ Key: k, @@ -31,12 +29,43 @@ func (k Key) Bool(v bool) KeyValue { } } +// BoolSlice creates a KeyValue instance with a BOOLSLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- BoolSlice(name, value). +func (k Key) BoolSlice(v []bool) KeyValue { + return KeyValue{ + Key: k, + Value: BoolSliceValue(v), + } +} + +// Int creates a KeyValue instance with an INT64 Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int(name, value). +func (k Key) Int(v int) KeyValue { + return KeyValue{ + Key: k, + Value: IntValue(v), + } +} + +// IntSlice creates a KeyValue instance with an INT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- IntSlice(name, value). +func (k Key) IntSlice(v []int) KeyValue { + return KeyValue{ + Key: k, + Value: IntSliceValue(v), + } +} + // Int64 creates a KeyValue instance with an INT64 Value. // -// If creating both key and an int64 value at the same time, then -// instead of calling Key(name).Int64(value) consider using a -// convenience function provided by the api/key package - -// key.Int64(name, value). +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int64(name, value). func (k Key) Int64(v int64) KeyValue { return KeyValue{ Key: k, @@ -44,12 +73,21 @@ func (k Key) Int64(v int64) KeyValue { } } +// Int64Slice creates a KeyValue instance with an INT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int64Slice(name, value). +func (k Key) Int64Slice(v []int64) KeyValue { + return KeyValue{ + Key: k, + Value: Int64SliceValue(v), + } +} + // Float64 creates a KeyValue instance with a FLOAT64 Value. // -// If creating both key and a float64 value at the same time, then -// instead of calling Key(name).Float64(value) consider using a -// convenience function provided by the api/key package - -// key.Float64(name, value). +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Float64(name, value). func (k Key) Float64(v float64) KeyValue { return KeyValue{ Key: k, @@ -57,12 +95,21 @@ func (k Key) Float64(v float64) KeyValue { } } +// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Float64(name, value). +func (k Key) Float64Slice(v []float64) KeyValue { + return KeyValue{ + Key: k, + Value: Float64SliceValue(v), + } +} + // String creates a KeyValue instance with a STRING Value. // -// If creating both key and a string value at the same time, then -// instead of calling Key(name).String(value) consider using a -// convenience function provided by the api/key package - -// key.String(name, value). +// If creating both a key and value at the same time, use the provided +// convenience function instead -- String(name, value). func (k Key) String(v string) KeyValue { return KeyValue{ Key: k, @@ -70,16 +117,14 @@ func (k Key) String(v string) KeyValue { } } -// Int creates a KeyValue instance with an INT64 Value. +// StringSlice creates a KeyValue instance with a STRINGSLICE Value. // -// If creating both key and an int value at the same time, then -// instead of calling Key(name).Int(value) consider using a -// convenience function provided by the api/key package - -// key.Int(name, value). -func (k Key) Int(v int) KeyValue { +// If creating both a key and value at the same time, use the provided +// convenience function instead -- StringSlice(name, value). +func (k Key) StringSlice(v []string) KeyValue { return KeyValue{ Key: k, - Value: IntValue(v), + Value: StringSliceValue(v), } } @@ -87,16 +132,3 @@ func (k Key) Int(v int) KeyValue { func (k Key) Defined() bool { return len(k) != 0 } - -// Array creates a KeyValue instance with a ARRAY Value. -// -// If creating both key and a array value at the same time, then -// instead of calling Key(name).String(value) consider using a -// convenience function provided by the api/key package - -// key.Array(name, value). -func (k Key) Array(v interface{}) KeyValue { - return KeyValue{ - Key: k, - Value: ArrayValue(v), - } -} diff --git a/vendor/go.opentelemetry.io/otel/attribute/kv.go b/vendor/go.opentelemetry.io/otel/attribute/kv.go index 2fcc8863f73..1ddf3ce0580 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/kv.go +++ b/vendor/go.opentelemetry.io/otel/attribute/kv.go @@ -15,9 +15,7 @@ package attribute // import "go.opentelemetry.io/otel/attribute" import ( - "encoding/json" "fmt" - "reflect" ) // KeyValue holds a key and value pair. @@ -28,81 +26,61 @@ type KeyValue struct { // Valid returns if kv is a valid OpenTelemetry attribute. func (kv KeyValue) Valid() bool { - return kv.Key != "" && kv.Value.Type() != INVALID + return kv.Key.Defined() && kv.Value.Type() != INVALID } -// Bool creates a new key-value pair with a passed name and a bool -// value. +// Bool creates a KeyValue with a BOOL Value type. func Bool(k string, v bool) KeyValue { return Key(k).Bool(v) } -// Int64 creates a new key-value pair with a passed name and an int64 -// value. +// BoolSlice creates a KeyValue with a BOOLSLICE Value type. +func BoolSlice(k string, v []bool) KeyValue { + return Key(k).BoolSlice(v) +} + +// Int creates a KeyValue with an INT64 Value type. +func Int(k string, v int) KeyValue { + return Key(k).Int(v) +} + +// IntSlice creates a KeyValue with an INT64SLICE Value type. +func IntSlice(k string, v []int) KeyValue { + return Key(k).IntSlice(v) +} + +// Int64 creates a KeyValue with an INT64 Value type. func Int64(k string, v int64) KeyValue { return Key(k).Int64(v) } -// Float64 creates a new key-value pair with a passed name and a float64 -// value. +// Int64Slice creates a KeyValue with an INT64SLICE Value type. +func Int64Slice(k string, v []int64) KeyValue { + return Key(k).Int64Slice(v) +} + +// Float64 creates a KeyValue with a FLOAT64 Value type. func Float64(k string, v float64) KeyValue { return Key(k).Float64(v) } -// String creates a new key-value pair with a passed name and a string -// value. +// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type. +func Float64Slice(k string, v []float64) KeyValue { + return Key(k).Float64Slice(v) +} + +// String creates a KeyValue with a STRING Value type. func String(k, v string) KeyValue { return Key(k).String(v) } +// StringSlice creates a KeyValue with a STRINGSLICE Value type. +func StringSlice(k string, v []string) KeyValue { + return Key(k).StringSlice(v) +} + // Stringer creates a new key-value pair with a passed name and a string // value generated by the passed Stringer interface. func Stringer(k string, v fmt.Stringer) KeyValue { return Key(k).String(v.String()) } - -// Int creates a new key-value pair instance with a passed name and -// either an int32 or an int64 value, depending on whether the int -// type is 32 or 64 bits wide. -func Int(k string, v int) KeyValue { - return Key(k).Int(v) -} - -// Array creates a new key-value pair with a passed name and a array. -// Only arrays of primitive type are supported. -func Array(k string, v interface{}) KeyValue { - return Key(k).Array(v) -} - -// Any creates a new key-value pair instance with a passed name and -// automatic type inference. This is slower, and not type-safe. -func Any(k string, value interface{}) KeyValue { - if value == nil { - return String(k, "") - } - - if stringer, ok := value.(fmt.Stringer); ok { - return String(k, stringer.String()) - } - - rv := reflect.ValueOf(value) - - switch rv.Kind() { - case reflect.Array, reflect.Slice: - return Array(k, value) - case reflect.Bool: - return Bool(k, rv.Bool()) - case reflect.Int, reflect.Int8, reflect.Int16: - return Int(k, int(rv.Int())) - case reflect.Int64: - return Int64(k, rv.Int()) - case reflect.Float64: - return Float64(k, rv.Float()) - case reflect.String: - return String(k, rv.String()) - } - if b, err := json.Marshal(value); b != nil && err == nil { - return String(k, string(b)) - } - return String(k, fmt.Sprint(value)) -} diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index 882dc112f72..9f9303d4f15 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -22,61 +22,47 @@ import ( ) type ( - // Set is the representation for a distinct label set. It - // manages an immutable set of labels, with an internal cache - // for storing label encodings. + // Set is the representation for a distinct attribute set. It manages an + // immutable set of attributes, with an internal cache for storing + // attribute encodings. // - // This type supports the `Equivalent` method of comparison - // using values of type `Distinct`. - // - // This type is used to implement: - // 1. Metric labels - // 2. Resource sets - // 3. Correlation map (TODO) + // This type supports the Equivalent method of comparison using values of + // type Distinct. Set struct { equivalent Distinct - - lock sync.Mutex - encoders [maxConcurrentEncoders]EncoderID - encoded [maxConcurrentEncoders]string } - // Distinct wraps a variable-size array of `KeyValue`, - // constructed with keys in sorted order. This can be used as - // a map key or for equality checking between Sets. + // Distinct wraps a variable-size array of KeyValue, constructed with keys + // in sorted order. This can be used as a map key or for equality checking + // between Sets. Distinct struct { iface interface{} } - // Filter supports removing certain labels from label sets. - // When the filter returns true, the label will be kept in - // the filtered label set. When the filter returns false, the - // label is excluded from the filtered label set, and the - // label instead appears in the `removed` list of excluded labels. - Filter func(KeyValue) bool - - // Sortable implements `sort.Interface`, used for sorting - // `KeyValue`. This is an exported type to support a - // memory optimization. A pointer to one of these is needed - // for the call to `sort.Stable()`, which the caller may - // provide in order to avoid an allocation. See - // `NewSetWithSortable()`. + // Sortable implements sort.Interface, used for sorting KeyValue. This is + // an exported type to support a memory optimization. A pointer to one of + // these is needed for the call to sort.Stable(), which the caller may + // provide in order to avoid an allocation. See NewSetWithSortable(). Sortable []KeyValue ) var ( - // keyValueType is used in `computeDistinctReflect`. + // keyValueType is used in computeDistinctReflect. keyValueType = reflect.TypeOf(KeyValue{}) - // emptySet is returned for empty label sets. + // emptySet is returned for empty attribute sets. emptySet = &Set{ equivalent: Distinct{ iface: [0]KeyValue{}, }, } -) -const maxConcurrentEncoders = 3 + // sortables is a pool of Sortables used to create Sets with a user does + // not provide one. + sortables = sync.Pool{ + New: func() interface{} { return new(Sortable) }, + } +) // EmptySet returns a reference to a Set with no elements. // @@ -85,30 +71,30 @@ func EmptySet() *Set { return emptySet } -// reflect abbreviates `reflect.ValueOf`. -func (d Distinct) reflect() reflect.Value { +// reflectValue abbreviates reflect.ValueOf(d). +func (d Distinct) reflectValue() reflect.Value { return reflect.ValueOf(d.iface) } -// Valid returns true if this value refers to a valid `*Set`. +// Valid returns true if this value refers to a valid Set. func (d Distinct) Valid() bool { return d.iface != nil } -// Len returns the number of labels in this set. +// Len returns the number of attributes in this set. func (l *Set) Len() int { if l == nil || !l.equivalent.Valid() { return 0 } - return l.equivalent.reflect().Len() + return l.equivalent.reflectValue().Len() } -// Get returns the KeyValue at ordered position `idx` in this set. +// Get returns the KeyValue at ordered position idx in this set. func (l *Set) Get(idx int) (KeyValue, bool) { - if l == nil { + if l == nil || !l.equivalent.Valid() { return KeyValue{}, false } - value := l.equivalent.reflect() + value := l.equivalent.reflectValue() if idx >= 0 && idx < value.Len() { // Note: The Go compiler successfully avoids an allocation for @@ -121,10 +107,10 @@ func (l *Set) Get(idx int) (KeyValue, bool) { // Value returns the value of a specified key in this set. func (l *Set) Value(k Key) (Value, bool) { - if l == nil { + if l == nil || !l.equivalent.Valid() { return Value{}, false } - rValue := l.equivalent.reflect() + rValue := l.equivalent.reflectValue() vlen := rValue.Len() idx := sort.Search(vlen, func(idx int) bool { @@ -149,7 +135,7 @@ func (l *Set) HasValue(k Key) bool { return ok } -// Iter returns an iterator for visiting the labels in this set. +// Iter returns an iterator for visiting the attributes in this set. func (l *Set) Iter() Iterator { return Iterator{ storage: l, @@ -157,18 +143,17 @@ func (l *Set) Iter() Iterator { } } -// ToSlice returns the set of labels belonging to this set, sorted, -// where keys appear no more than once. +// ToSlice returns the set of attributes belonging to this set, sorted, where +// keys appear no more than once. func (l *Set) ToSlice() []KeyValue { iter := l.Iter() return iter.ToSlice() } -// Equivalent returns a value that may be used as a map key. The -// Distinct type guarantees that the result will equal the equivalent -// Distinct value of any label set with the same elements as this, -// where sets are made unique by choosing the last value in the input -// for any given key. +// Equivalent returns a value that may be used as a map key. The Distinct type +// guarantees that the result will equal the equivalent. Distinct value of any +// attribute set with the same elements as this, where sets are made unique by +// choosing the last value in the input for any given key. func (l *Set) Equivalent() Distinct { if l == nil || !l.equivalent.Valid() { return emptySet.equivalent @@ -181,52 +166,13 @@ func (l *Set) Equals(o *Set) bool { return l.Equivalent() == o.Equivalent() } -// Encoded returns the encoded form of this set, according to -// `encoder`. The result will be cached in this `*Set`. +// Encoded returns the encoded form of this set, according to encoder. func (l *Set) Encoded(encoder Encoder) string { if l == nil || encoder == nil { return "" } - id := encoder.ID() - if !id.Valid() { - // Invalid IDs are not cached. - return encoder.Encode(l.Iter()) - } - - var lookup *string - l.lock.Lock() - for idx := 0; idx < maxConcurrentEncoders; idx++ { - if l.encoders[idx] == id { - lookup = &l.encoded[idx] - break - } - } - l.lock.Unlock() - - if lookup != nil { - return *lookup - } - - r := encoder.Encode(l.Iter()) - - l.lock.Lock() - defer l.lock.Unlock() - - for idx := 0; idx < maxConcurrentEncoders; idx++ { - if l.encoders[idx] == id { - return l.encoded[idx] - } - if !l.encoders[idx].Valid() { - l.encoders[idx] = id - l.encoded[idx] = r - return r - } - } - - // TODO: This is a performance cliff. Find a way for this to - // generate a warning. - return r + return encoder.Encode(l.Iter()) } func empty() Set { @@ -235,48 +181,52 @@ func empty() Set { } } -// NewSet returns a new `Set`. See the documentation for -// `NewSetWithSortableFiltered` for more details. +// NewSet returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. // -// Except for empty sets, this method adds an additional allocation -// compared with calls that include a `*Sortable`. +// Except for empty sets, this method adds an additional allocation compared +// with calls that include a Sortable. func NewSet(kvs ...KeyValue) Set { // Check for empty set. if len(kvs) == 0 { return empty() } - s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil) - return s //nolint + srt := sortables.Get().(*Sortable) + s, _ := NewSetWithSortableFiltered(kvs, srt, nil) + sortables.Put(srt) + return s } -// NewSetWithSortable returns a new `Set`. See the documentation for -// `NewSetWithSortableFiltered` for more details. +// NewSetWithSortable returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. // -// This call includes a `*Sortable` option as a memory optimization. +// This call includes a Sortable option as a memory optimization. func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set { // Check for empty set. if len(kvs) == 0 { return empty() } s, _ := NewSetWithSortableFiltered(kvs, tmp, nil) - return s //nolint + return s } -// NewSetWithFiltered returns a new `Set`. See the documentation for -// `NewSetWithSortableFiltered` for more details. +// NewSetWithFiltered returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. // -// This call includes a `Filter` to include/exclude label keys from -// the return value. Excluded keys are returned as a slice of label -// values. +// This call includes a Filter to include/exclude attribute keys from the +// return value. Excluded keys are returned as a slice of attribute values. func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) { // Check for empty set. if len(kvs) == 0 { return empty(), nil } - return NewSetWithSortableFiltered(kvs, new(Sortable), filter) + srt := sortables.Get().(*Sortable) + s, filtered := NewSetWithSortableFiltered(kvs, srt, filter) + sortables.Put(srt) + return s, filtered } -// NewSetWithSortableFiltered returns a new `Set`. +// NewSetWithSortableFiltered returns a new Set. // // Duplicate keys are eliminated by taking the last value. This // re-orders the input slice so that unique last-values are contiguous @@ -288,17 +238,16 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) { // - Caller sees the reordering, but doesn't lose values // - Repeated call preserve last-value wins. // -// Note that methods are defined on `*Set`, although this returns `Set`. -// Callers can avoid memory allocations by: +// Note that methods are defined on Set, although this returns Set. Callers +// can avoid memory allocations by: // -// - allocating a `Sortable` for use as a temporary in this method -// - allocating a `Set` for storing the return value of this -// constructor. +// - allocating a Sortable for use as a temporary in this method +// - allocating a Set for storing the return value of this constructor. // -// The result maintains a cache of encoded labels, by attribute.EncoderID. +// The result maintains a cache of encoded attributes, by attribute.EncoderID. // This value should not be copied after its first use. // -// The second `[]KeyValue` return value is a list of labels that were +// The second []KeyValue return value is a list of attributes that were // excluded by the Filter (if non-nil). func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) { // Check for empty set. @@ -338,13 +287,13 @@ func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (S }, nil } -// filterSet reorders `kvs` so that included keys are contiguous at -// the end of the slice, while excluded keys precede the included keys. +// filterSet reorders kvs so that included keys are contiguous at the end of +// the slice, while excluded keys precede the included keys. func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) { var excluded []KeyValue - // Move labels that do not match the filter so - // they're adjacent before calling computeDistinct(). + // Move attributes that do not match the filter so they're adjacent before + // calling computeDistinct(). distinctPosition := len(kvs) // Swap indistinct keys forward and distinct keys toward the @@ -364,8 +313,8 @@ func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) { }, excluded } -// Filter returns a filtered copy of this `Set`. See the -// documentation for `NewSetWithSortableFiltered` for more details. +// Filter returns a filtered copy of this Set. See the documentation for +// NewSetWithSortableFiltered for more details. func (l *Set) Filter(re Filter) (Set, []KeyValue) { if re == nil { return Set{ @@ -378,9 +327,9 @@ func (l *Set) Filter(re Filter) (Set, []KeyValue) { return filterSet(l.ToSlice(), re) } -// computeDistinct returns a `Distinct` using either the fixed- or -// reflect-oriented code path, depending on the size of the input. -// The input slice is assumed to already be sorted and de-duplicated. +// computeDistinct returns a Distinct using either the fixed- or +// reflect-oriented code path, depending on the size of the input. The input +// slice is assumed to already be sorted and de-duplicated. func computeDistinct(kvs []KeyValue) Distinct { iface := computeDistinctFixed(kvs) if iface == nil { @@ -391,8 +340,8 @@ func computeDistinct(kvs []KeyValue) Distinct { } } -// computeDistinctFixed computes a `Distinct` for small slices. It -// returns nil if the input is too large for this code path. +// computeDistinctFixed computes a Distinct for small slices. It returns nil +// if the input is too large for this code path. func computeDistinctFixed(kvs []KeyValue) interface{} { switch len(kvs) { case 1: @@ -440,8 +389,8 @@ func computeDistinctFixed(kvs []KeyValue) interface{} { } } -// computeDistinctReflect computes a `Distinct` using reflection, -// works for any size input. +// computeDistinctReflect computes a Distinct using reflection, works for any +// size input. func computeDistinctReflect(kvs []KeyValue) interface{} { at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem() for i, keyValue := range kvs { @@ -450,22 +399,31 @@ func computeDistinctReflect(kvs []KeyValue) interface{} { return at.Interface() } -// MarshalJSON returns the JSON encoding of the `*Set`. +// MarshalJSON returns the JSON encoding of the Set. func (l *Set) MarshalJSON() ([]byte, error) { return json.Marshal(l.equivalent.iface) } -// Len implements `sort.Interface`. +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (l Set) MarshalLog() interface{} { + kvs := make(map[string]string) + for _, kv := range l.ToSlice() { + kvs[string(kv.Key)] = kv.Value.Emit() + } + return kvs +} + +// Len implements sort.Interface. func (l *Sortable) Len() int { return len(*l) } -// Swap implements `sort.Interface`. +// Swap implements sort.Interface. func (l *Sortable) Swap(i, j int) { (*l)[i], (*l)[j] = (*l)[j], (*l)[i] } -// Less implements `sort.Interface`. +// Less implements sort.Interface. func (l *Sortable) Less(i, j int) bool { return (*l)[i].Key < (*l)[j].Key } diff --git a/vendor/go.opentelemetry.io/otel/attribute/type_string.go b/vendor/go.opentelemetry.io/otel/attribute/type_string.go index 1f2c7dccfa5..e584b24776b 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/type_string.go +++ b/vendor/go.opentelemetry.io/otel/attribute/type_string.go @@ -13,12 +13,15 @@ func _() { _ = x[INT64-2] _ = x[FLOAT64-3] _ = x[STRING-4] - _ = x[ARRAY-5] + _ = x[BOOLSLICE-5] + _ = x[INT64SLICE-6] + _ = x[FLOAT64SLICE-7] + _ = x[STRINGSLICE-8] } -const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGARRAY" +const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE" -var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 34} +var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71} func (i Type) String() string { if i < 0 || i >= Type(len(_Type_index)-1) { diff --git a/vendor/go.opentelemetry.io/otel/attribute/value.go b/vendor/go.opentelemetry.io/otel/attribute/value.go index 7b979409e30..cb21dd5c096 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/value.go +++ b/vendor/go.opentelemetry.io/otel/attribute/value.go @@ -21,21 +21,20 @@ import ( "strconv" "go.opentelemetry.io/otel/internal" + "go.opentelemetry.io/otel/internal/attribute" ) //go:generate stringer -type=Type // Type describes the type of the data Value holds. -type Type int +type Type int // nolint: revive // redefines builtin Type. // Value represents the value part in key-value pairs. type Value struct { vtype Type numeric uint64 stringly string - // TODO Lazy value type? - - array interface{} + slice interface{} } const ( @@ -49,10 +48,14 @@ const ( FLOAT64 // STRING is a string Type Value. STRING - // ARRAY is an array Type Value used to store 1-dimensional slices or - // arrays of bool, int, int32, int64, uint, uint32, uint64, float, - // float32, float64, or string types. - ARRAY + // BOOLSLICE is a slice of booleans Type Value. + BOOLSLICE + // INT64SLICE is a slice of 64-bit signed integral numbers Type Value. + INT64SLICE + // FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value. + FLOAT64SLICE + // STRINGSLICE is a slice of strings Type Value. + STRINGSLICE ) // BoolValue creates a BOOL Value. @@ -63,6 +66,29 @@ func BoolValue(v bool) Value { } } +// BoolSliceValue creates a BOOLSLICE Value. +func BoolSliceValue(v []bool) Value { + return Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)} +} + +// IntValue creates an INT64 Value. +func IntValue(v int) Value { + return Int64Value(int64(v)) +} + +// IntSliceValue creates an INTSLICE Value. +func IntSliceValue(v []int) Value { + var int64Val int64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(int64Val))) + for i, val := range v { + cp.Elem().Index(i).SetInt(int64(val)) + } + return Value{ + vtype: INT64SLICE, + slice: cp.Elem().Interface(), + } +} + // Int64Value creates an INT64 Value. func Int64Value(v int64) Value { return Value{ @@ -71,6 +97,11 @@ func Int64Value(v int64) Value { } } +// Int64SliceValue creates an INT64SLICE Value. +func Int64SliceValue(v []int64) Value { + return Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)} +} + // Float64Value creates a FLOAT64 Value. func Float64Value(v float64) Value { return Value{ @@ -79,6 +110,11 @@ func Float64Value(v float64) Value { } } +// Float64SliceValue creates a FLOAT64SLICE Value. +func Float64SliceValue(v []float64) Value { + return Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)} +} + // StringValue creates a STRING Value. func StringValue(v string) Value { return Value{ @@ -87,38 +123,9 @@ func StringValue(v string) Value { } } -// IntValue creates an INT64 Value. -func IntValue(v int) Value { - return Int64Value(int64(v)) -} - -// ArrayValue creates an ARRAY value from an array or slice. -// Only arrays or slices of bool, int, int64, float, float64, or string types are allowed. -// Specifically, arrays and slices can not contain other arrays, slices, structs, or non-standard -// types. If the passed value is not an array or slice of these types an -// INVALID value is returned. -func ArrayValue(v interface{}) Value { - switch reflect.TypeOf(v).Kind() { - case reflect.Array, reflect.Slice: - // get array type regardless of dimensions - typ := reflect.TypeOf(v).Elem() - kind := typ.Kind() - switch kind { - case reflect.Bool, reflect.Int, reflect.Int64, - reflect.Float64, reflect.String: - val := reflect.ValueOf(v) - length := val.Len() - frozen := reflect.Indirect(reflect.New(reflect.ArrayOf(length, typ))) - reflect.Copy(frozen, val) - return Value{ - vtype: ARRAY, - array: frozen.Interface(), - } - default: - return Value{vtype: INVALID} - } - } - return Value{vtype: INVALID} +// StringSliceValue creates a STRINGSLICE Value. +func StringSliceValue(v []string) Value { + return Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)} } // Type returns a type of the Value. @@ -132,27 +139,74 @@ func (v Value) AsBool() bool { return internal.RawToBool(v.numeric) } +// AsBoolSlice returns the []bool value. Make sure that the Value's type is +// BOOLSLICE. +func (v Value) AsBoolSlice() []bool { + if v.vtype != BOOLSLICE { + return nil + } + return v.asBoolSlice() +} + +func (v Value) asBoolSlice() []bool { + return attribute.AsBoolSlice(v.slice) +} + // AsInt64 returns the int64 value. Make sure that the Value's type is // INT64. func (v Value) AsInt64() int64 { return internal.RawToInt64(v.numeric) } +// AsInt64Slice returns the []int64 value. Make sure that the Value's type is +// INT64SLICE. +func (v Value) AsInt64Slice() []int64 { + if v.vtype != INT64SLICE { + return nil + } + return v.asInt64Slice() +} + +func (v Value) asInt64Slice() []int64 { + return attribute.AsInt64Slice(v.slice) +} + // AsFloat64 returns the float64 value. Make sure that the Value's // type is FLOAT64. func (v Value) AsFloat64() float64 { return internal.RawToFloat64(v.numeric) } +// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is +// FLOAT64SLICE. +func (v Value) AsFloat64Slice() []float64 { + if v.vtype != FLOAT64SLICE { + return nil + } + return v.asFloat64Slice() +} + +func (v Value) asFloat64Slice() []float64 { + return attribute.AsFloat64Slice(v.slice) +} + // AsString returns the string value. Make sure that the Value's type // is STRING. func (v Value) AsString() string { return v.stringly } -// AsArray returns the array Value as an interface{}. -func (v Value) AsArray() interface{} { - return v.array +// AsStringSlice returns the []string value. Make sure that the Value's type is +// STRINGSLICE. +func (v Value) AsStringSlice() []string { + if v.vtype != STRINGSLICE { + return nil + } + return v.asStringSlice() +} + +func (v Value) asStringSlice() []string { + return attribute.AsStringSlice(v.slice) } type unknownValueType struct{} @@ -160,16 +214,22 @@ type unknownValueType struct{} // AsInterface returns Value's data as interface{}. func (v Value) AsInterface() interface{} { switch v.Type() { - case ARRAY: - return v.AsArray() case BOOL: return v.AsBool() + case BOOLSLICE: + return v.asBoolSlice() case INT64: return v.AsInt64() + case INT64SLICE: + return v.asInt64Slice() case FLOAT64: return v.AsFloat64() + case FLOAT64SLICE: + return v.asFloat64Slice() case STRING: return v.stringly + case STRINGSLICE: + return v.asStringSlice() } return unknownValueType{} } @@ -177,14 +237,20 @@ func (v Value) AsInterface() interface{} { // Emit returns a string representation of Value's data. func (v Value) Emit() string { switch v.Type() { - case ARRAY: - return fmt.Sprint(v.array) + case BOOLSLICE: + return fmt.Sprint(v.asBoolSlice()) case BOOL: return strconv.FormatBool(v.AsBool()) + case INT64SLICE: + return fmt.Sprint(v.asInt64Slice()) case INT64: return strconv.FormatInt(v.AsInt64(), 10) + case FLOAT64SLICE: + return fmt.Sprint(v.asFloat64Slice()) case FLOAT64: return fmt.Sprint(v.AsFloat64()) + case STRINGSLICE: + return fmt.Sprint(v.asStringSlice()) case STRING: return v.stringly default: diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go new file mode 100644 index 00000000000..9e6b3b7b52a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go @@ -0,0 +1,552 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package baggage // import "go.opentelemetry.io/otel/baggage" + +import ( + "errors" + "fmt" + "net/url" + "regexp" + "strings" + + "go.opentelemetry.io/otel/internal/baggage" +) + +const ( + maxMembers = 180 + maxBytesPerMembers = 4096 + maxBytesPerBaggageString = 8192 + + listDelimiter = "," + keyValueDelimiter = "=" + propertyDelimiter = ";" + + keyDef = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+)` + valueDef = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)` + keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + valueDef + `\s*` +) + +var ( + keyRe = regexp.MustCompile(`^` + keyDef + `$`) + valueRe = regexp.MustCompile(`^` + valueDef + `$`) + propertyRe = regexp.MustCompile(`^(?:\s*` + keyDef + `\s*|` + keyValueDef + `)$`) +) + +var ( + errInvalidKey = errors.New("invalid key") + errInvalidValue = errors.New("invalid value") + errInvalidProperty = errors.New("invalid baggage list-member property") + errInvalidMember = errors.New("invalid baggage list-member") + errMemberNumber = errors.New("too many list-members in baggage-string") + errMemberBytes = errors.New("list-member too large") + errBaggageBytes = errors.New("baggage-string too large") +) + +// Property is an additional metadata entry for a baggage list-member. +type Property struct { + key, value string + + // hasValue indicates if a zero-value value means the property does not + // have a value or if it was the zero-value. + hasValue bool +} + +// NewKeyProperty returns a new Property for key. +// +// If key is invalid, an error will be returned. +func NewKeyProperty(key string) (Property, error) { + if !keyRe.MatchString(key) { + return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) + } + + p := Property{key: key} + return p, nil +} + +// NewKeyValueProperty returns a new Property for key with value. +// +// If key or value are invalid, an error will be returned. +func NewKeyValueProperty(key, value string) (Property, error) { + if !keyRe.MatchString(key) { + return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) + } + if !valueRe.MatchString(value) { + return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidValue, value) + } + + p := Property{ + key: key, + value: value, + hasValue: true, + } + return p, nil +} + +func newInvalidProperty() Property { + return Property{} +} + +// parseProperty attempts to decode a Property from the passed string. It +// returns an error if the input is invalid according to the W3C Baggage +// specification. +func parseProperty(property string) (Property, error) { + if property == "" { + return newInvalidProperty(), nil + } + + match := propertyRe.FindStringSubmatch(property) + if len(match) != 4 { + return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property) + } + + var p Property + if match[1] != "" { + p.key = match[1] + } else { + p.key = match[2] + p.value = match[3] + p.hasValue = true + } + + return p, nil +} + +// validate ensures p conforms to the W3C Baggage specification, returning an +// error otherwise. +func (p Property) validate() error { + errFunc := func(err error) error { + return fmt.Errorf("invalid property: %w", err) + } + + if !keyRe.MatchString(p.key) { + return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key)) + } + if p.hasValue && !valueRe.MatchString(p.value) { + return errFunc(fmt.Errorf("%w: %q", errInvalidValue, p.value)) + } + if !p.hasValue && p.value != "" { + return errFunc(errors.New("inconsistent value")) + } + return nil +} + +// Key returns the Property key. +func (p Property) Key() string { + return p.key +} + +// Value returns the Property value. Additionally, a boolean value is returned +// indicating if the returned value is the empty if the Property has a value +// that is empty or if the value is not set. +func (p Property) Value() (string, bool) { + return p.value, p.hasValue +} + +// String encodes Property into a string compliant with the W3C Baggage +// specification. +func (p Property) String() string { + if p.hasValue { + return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, p.value) + } + return p.key +} + +type properties []Property + +func fromInternalProperties(iProps []baggage.Property) properties { + if len(iProps) == 0 { + return nil + } + + props := make(properties, len(iProps)) + for i, p := range iProps { + props[i] = Property{ + key: p.Key, + value: p.Value, + hasValue: p.HasValue, + } + } + return props +} + +func (p properties) asInternal() []baggage.Property { + if len(p) == 0 { + return nil + } + + iProps := make([]baggage.Property, len(p)) + for i, prop := range p { + iProps[i] = baggage.Property{ + Key: prop.key, + Value: prop.value, + HasValue: prop.hasValue, + } + } + return iProps +} + +func (p properties) Copy() properties { + if len(p) == 0 { + return nil + } + + props := make(properties, len(p)) + copy(props, p) + return props +} + +// validate ensures each Property in p conforms to the W3C Baggage +// specification, returning an error otherwise. +func (p properties) validate() error { + for _, prop := range p { + if err := prop.validate(); err != nil { + return err + } + } + return nil +} + +// String encodes properties into a string compliant with the W3C Baggage +// specification. +func (p properties) String() string { + props := make([]string, len(p)) + for i, prop := range p { + props[i] = prop.String() + } + return strings.Join(props, propertyDelimiter) +} + +// Member is a list-member of a baggage-string as defined by the W3C Baggage +// specification. +type Member struct { + key, value string + properties properties + + // hasData indicates whether the created property contains data or not. + // Properties that do not contain data are invalid with no other check + // required. + hasData bool +} + +// NewMember returns a new Member from the passed arguments. The key will be +// used directly while the value will be url decoded after validation. An error +// is returned if the created Member would be invalid according to the W3C +// Baggage specification. +func NewMember(key, value string, props ...Property) (Member, error) { + m := Member{ + key: key, + value: value, + properties: properties(props).Copy(), + hasData: true, + } + if err := m.validate(); err != nil { + return newInvalidMember(), err + } + decodedValue, err := url.QueryUnescape(value) + if err != nil { + return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value) + } + m.value = decodedValue + return m, nil +} + +func newInvalidMember() Member { + return Member{} +} + +// parseMember attempts to decode a Member from the passed string. It returns +// an error if the input is invalid according to the W3C Baggage +// specification. +func parseMember(member string) (Member, error) { + if n := len(member); n > maxBytesPerMembers { + return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n) + } + + var ( + key, value string + props properties + ) + + keyValue, properties, found := strings.Cut(member, propertyDelimiter) + if found { + // Parse the member properties. + for _, pStr := range strings.Split(properties, propertyDelimiter) { + p, err := parseProperty(pStr) + if err != nil { + return newInvalidMember(), err + } + props = append(props, p) + } + } + // Parse the member key/value pair. + + // Take into account a value can contain equal signs (=). + k, v, found := strings.Cut(keyValue, keyValueDelimiter) + if !found { + return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidMember, member) + } + // "Leading and trailing whitespaces are allowed but MUST be trimmed + // when converting the header into a data structure." + key = strings.TrimSpace(k) + var err error + value, err = url.QueryUnescape(strings.TrimSpace(v)) + if err != nil { + return newInvalidMember(), fmt.Errorf("%w: %q", err, value) + } + if !keyRe.MatchString(key) { + return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key) + } + if !valueRe.MatchString(value) { + return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value) + } + + return Member{key: key, value: value, properties: props, hasData: true}, nil +} + +// validate ensures m conforms to the W3C Baggage specification. +// A key is just an ASCII string, but a value must be URL encoded UTF-8, +// returning an error otherwise. +func (m Member) validate() error { + if !m.hasData { + return fmt.Errorf("%w: %q", errInvalidMember, m) + } + + if !keyRe.MatchString(m.key) { + return fmt.Errorf("%w: %q", errInvalidKey, m.key) + } + if !valueRe.MatchString(m.value) { + return fmt.Errorf("%w: %q", errInvalidValue, m.value) + } + return m.properties.validate() +} + +// Key returns the Member key. +func (m Member) Key() string { return m.key } + +// Value returns the Member value. +func (m Member) Value() string { return m.value } + +// Properties returns a copy of the Member properties. +func (m Member) Properties() []Property { return m.properties.Copy() } + +// String encodes Member into a string compliant with the W3C Baggage +// specification. +func (m Member) String() string { + // A key is just an ASCII string, but a value is URL encoded UTF-8. + s := fmt.Sprintf("%s%s%s", m.key, keyValueDelimiter, url.QueryEscape(m.value)) + if len(m.properties) > 0 { + s = fmt.Sprintf("%s%s%s", s, propertyDelimiter, m.properties.String()) + } + return s +} + +// Baggage is a list of baggage members representing the baggage-string as +// defined by the W3C Baggage specification. +type Baggage struct { //nolint:golint + list baggage.List +} + +// New returns a new valid Baggage. It returns an error if it results in a +// Baggage exceeding limits set in that specification. +// +// It expects all the provided members to have already been validated. +func New(members ...Member) (Baggage, error) { + if len(members) == 0 { + return Baggage{}, nil + } + + b := make(baggage.List) + for _, m := range members { + if !m.hasData { + return Baggage{}, errInvalidMember + } + + // OpenTelemetry resolves duplicates by last-one-wins. + b[m.key] = baggage.Item{ + Value: m.value, + Properties: m.properties.asInternal(), + } + } + + // Check member numbers after deduplication. + if len(b) > maxMembers { + return Baggage{}, errMemberNumber + } + + bag := Baggage{b} + if n := len(bag.String()); n > maxBytesPerBaggageString { + return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) + } + + return bag, nil +} + +// Parse attempts to decode a baggage-string from the passed string. It +// returns an error if the input is invalid according to the W3C Baggage +// specification. +// +// If there are duplicate list-members contained in baggage, the last one +// defined (reading left-to-right) will be the only one kept. This diverges +// from the W3C Baggage specification which allows duplicate list-members, but +// conforms to the OpenTelemetry Baggage specification. +func Parse(bStr string) (Baggage, error) { + if bStr == "" { + return Baggage{}, nil + } + + if n := len(bStr); n > maxBytesPerBaggageString { + return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) + } + + b := make(baggage.List) + for _, memberStr := range strings.Split(bStr, listDelimiter) { + m, err := parseMember(memberStr) + if err != nil { + return Baggage{}, err + } + // OpenTelemetry resolves duplicates by last-one-wins. + b[m.key] = baggage.Item{ + Value: m.value, + Properties: m.properties.asInternal(), + } + } + + // OpenTelemetry does not allow for duplicate list-members, but the W3C + // specification does. Now that we have deduplicated, ensure the baggage + // does not exceed list-member limits. + if len(b) > maxMembers { + return Baggage{}, errMemberNumber + } + + return Baggage{b}, nil +} + +// Member returns the baggage list-member identified by key. +// +// If there is no list-member matching the passed key the returned Member will +// be a zero-value Member. +// The returned member is not validated, as we assume the validation happened +// when it was added to the Baggage. +func (b Baggage) Member(key string) Member { + v, ok := b.list[key] + if !ok { + // We do not need to worry about distinguishing between the situation + // where a zero-valued Member is included in the Baggage because a + // zero-valued Member is invalid according to the W3C Baggage + // specification (it has an empty key). + return newInvalidMember() + } + + return Member{ + key: key, + value: v.Value, + properties: fromInternalProperties(v.Properties), + hasData: true, + } +} + +// Members returns all the baggage list-members. +// The order of the returned list-members does not have significance. +// +// The returned members are not validated, as we assume the validation happened +// when they were added to the Baggage. +func (b Baggage) Members() []Member { + if len(b.list) == 0 { + return nil + } + + members := make([]Member, 0, len(b.list)) + for k, v := range b.list { + members = append(members, Member{ + key: k, + value: v.Value, + properties: fromInternalProperties(v.Properties), + hasData: true, + }) + } + return members +} + +// SetMember returns a copy the Baggage with the member included. If the +// baggage contains a Member with the same key the existing Member is +// replaced. +// +// If member is invalid according to the W3C Baggage specification, an error +// is returned with the original Baggage. +func (b Baggage) SetMember(member Member) (Baggage, error) { + if !member.hasData { + return b, errInvalidMember + } + + n := len(b.list) + if _, ok := b.list[member.key]; !ok { + n++ + } + list := make(baggage.List, n) + + for k, v := range b.list { + // Do not copy if we are just going to overwrite. + if k == member.key { + continue + } + list[k] = v + } + + list[member.key] = baggage.Item{ + Value: member.value, + Properties: member.properties.asInternal(), + } + + return Baggage{list: list}, nil +} + +// DeleteMember returns a copy of the Baggage with the list-member identified +// by key removed. +func (b Baggage) DeleteMember(key string) Baggage { + n := len(b.list) + if _, ok := b.list[key]; ok { + n-- + } + list := make(baggage.List, n) + + for k, v := range b.list { + if k == key { + continue + } + list[k] = v + } + + return Baggage{list: list} +} + +// Len returns the number of list-members in the Baggage. +func (b Baggage) Len() int { + return len(b.list) +} + +// String encodes Baggage into a string compliant with the W3C Baggage +// specification. The returned string will be invalid if the Baggage contains +// any invalid list-members. +func (b Baggage) String() string { + members := make([]string, 0, len(b.list)) + for k, v := range b.list { + members = append(members, Member{ + key: k, + value: v.Value, + properties: fromInternalProperties(v.Properties), + }.String()) + } + return strings.Join(members, listDelimiter) +} diff --git a/vendor/go.opentelemetry.io/otel/baggage/context.go b/vendor/go.opentelemetry.io/otel/baggage/context.go new file mode 100644 index 00000000000..24b34b7564a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/baggage/context.go @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package baggage // import "go.opentelemetry.io/otel/baggage" + +import ( + "context" + + "go.opentelemetry.io/otel/internal/baggage" +) + +// ContextWithBaggage returns a copy of parent with baggage. +func ContextWithBaggage(parent context.Context, b Baggage) context.Context { + // Delegate so any hooks for the OpenTracing bridge are handled. + return baggage.ContextWithList(parent, b.list) +} + +// ContextWithoutBaggage returns a copy of parent with no baggage. +func ContextWithoutBaggage(parent context.Context) context.Context { + // Delegate so any hooks for the OpenTracing bridge are handled. + return baggage.ContextWithList(parent, nil) +} + +// FromContext returns the baggage contained in ctx. +func FromContext(ctx context.Context) Baggage { + // Delegate so any hooks for the OpenTracing bridge are handled. + return Baggage{list: baggage.ListFromContext(ctx)} +} diff --git a/vendor/go.opentelemetry.io/otel/baggage/doc.go b/vendor/go.opentelemetry.io/otel/baggage/doc.go new file mode 100644 index 00000000000..4545100df67 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/baggage/doc.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package baggage provides functionality for storing and retrieving +baggage items in Go context. For propagating the baggage, see the +go.opentelemetry.io/otel/propagation package. +*/ +package baggage // import "go.opentelemetry.io/otel/baggage" diff --git a/vendor/go.opentelemetry.io/otel/codes/codes.go b/vendor/go.opentelemetry.io/otel/codes/codes.go index 064a9279fd1..587ebae4e30 100644 --- a/vendor/go.opentelemetry.io/otel/codes/codes.go +++ b/vendor/go.opentelemetry.io/otel/codes/codes.go @@ -23,10 +23,20 @@ import ( const ( // Unset is the default status code. Unset Code = 0 + // Error indicates the operation contains an error. + // + // NOTE: The error code in OTLP is 2. + // The value of this enum is only relevant to the internals + // of the Go SDK. Error Code = 1 + // Ok indicates operation has been validated by an Application developers // or Operator to have completed successfully, or contain no error. + // + // NOTE: The Ok code in OTLP is 1. + // The value of this enum is only relevant to the internals + // of the Go SDK. Ok Code = 2 maxCode = 3 diff --git a/vendor/go.opentelemetry.io/otel/codes/doc.go b/vendor/go.opentelemetry.io/otel/codes/doc.go index fcf89ba1ac0..4e328fbb4b3 100644 --- a/vendor/go.opentelemetry.io/otel/codes/doc.go +++ b/vendor/go.opentelemetry.io/otel/codes/doc.go @@ -15,11 +15,7 @@ /* Package codes defines the canonical error codes used by OpenTelemetry. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track -the evolving OpenTelemetry specification and user feedback. - It conforms to [the OpenTelemetry -specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode). +specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status). */ package codes // import "go.opentelemetry.io/otel/codes" diff --git a/vendor/go.opentelemetry.io/otel/doc.go b/vendor/go.opentelemetry.io/otel/doc.go index 771ce81cc2f..daa36c89dc6 100644 --- a/vendor/go.opentelemetry.io/otel/doc.go +++ b/vendor/go.opentelemetry.io/otel/doc.go @@ -16,10 +16,6 @@ Package otel provides global access to the OpenTelemetry API. The subpackages of the otel package provide an implementation of the OpenTelemetry API. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - The provided API is used to instrument code and measure data about that code's performance and operation. The measured data, by default, is not processed or transmitted anywhere. An implementation of the OpenTelemetry SDK, like the diff --git a/vendor/go.opentelemetry.io/otel/error_handler.go b/vendor/go.opentelemetry.io/otel/error_handler.go index ac42f8be072..72fad85412b 100644 --- a/vendor/go.opentelemetry.io/otel/error_handler.go +++ b/vendor/go.opentelemetry.io/otel/error_handler.go @@ -16,7 +16,23 @@ package otel // import "go.opentelemetry.io/otel" // ErrorHandler handles irremediable events. type ErrorHandler interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Handle handles any error deemed irremediable by an OpenTelemetry // component. Handle(error) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. +} + +// ErrorHandlerFunc is a convenience adapter to allow the use of a function +// as an ErrorHandler. +type ErrorHandlerFunc func(error) + +var _ ErrorHandler = ErrorHandlerFunc(nil) + +// Handle handles the irremediable error by calling the ErrorHandlerFunc itself. +func (f ErrorHandlerFunc) Handle(err error) { + f(err) } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/README.md b/vendor/go.opentelemetry.io/otel/exporters/otlp/README.md deleted file mode 100644 index 0cd71f330bc..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# OpenTelemetry Collector Go Exporter - -[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/exporters/otlp)](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp) - -This exporter exports OpenTelemetry spans and metrics to the OpenTelemetry Collector. - - -## Installation and Setup - -The exporter can be installed using standard `go` functionality. - -```bash -$ go get -u go.opentelemetry.io/otel/exporters/otlp -``` - -A new exporter can be created using the `NewExporter` function. - -## Retries - -The exporter will not, by default, retry failed requests to the collector. -However, it is configured in a way that it can be easily enabled. - -To enable retries, the `GRPC_GO_RETRY` environment variable needs to be set to `on`. For example, - -``` -GRPC_GO_RETRY=on go run . -``` - -The [default service config](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) used by default is defined to retry failed requests with exponential backoff (`0.3seconds * (2)^retry`) with [a max of `5` retries](https://github.com/open-telemetry/oteps/blob/be2a3fcbaa417ebbf5845cd485d34fdf0ab4a2a4/text/0035-opentelemetry-protocol.md#export-response)). - -These retries are only attempted for reponses that are [deemed "retry-able" by the collector](https://github.com/grpc/proposal/blob/master/A6-client-retries.md#validation-of-retrypolicy). diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/doc.go deleted file mode 100644 index d0897bc8cf2..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package otlp contains an exporter for the OpenTelemetry protocol buffers. -// -// This package is currently in a pre-GA phase. Backwards incompatible changes -// may be introduced in subsequent minor version releases as we work to track -// the evolving OpenTelemetry specification and user feedback. -package otlp // import "go.opentelemetry.io/otel/exporters/otlp" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/envconfig.go deleted file mode 100644 index b52f3dc537a..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/envconfig.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpconfig - -import ( - "crypto/tls" - "fmt" - "io/ioutil" - "net/url" - "os" - "strconv" - "strings" - "time" - - "go.opentelemetry.io/otel/exporters/otlp" - - "go.opentelemetry.io/otel" -) - -func ApplyGRPCEnvConfigs(cfg *Config) { - e := EnvOptionsReader{ - GetEnv: os.Getenv, - ReadFile: ioutil.ReadFile, - } - - e.ApplyGRPCEnvConfigs(cfg) -} - -func ApplyHTTPEnvConfigs(cfg *Config) { - e := EnvOptionsReader{ - GetEnv: os.Getenv, - ReadFile: ioutil.ReadFile, - } - - e.ApplyHTTPEnvConfigs(cfg) -} - -type EnvOptionsReader struct { - GetEnv func(string) string - ReadFile func(filename string) ([]byte, error) -} - -func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg *Config) { - opts := e.GetOptionsFromEnv() - for _, opt := range opts { - opt.ApplyHTTPOption(cfg) - } -} - -func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg *Config) { - opts := e.GetOptionsFromEnv() - for _, opt := range opts { - opt.ApplyGRPCOption(cfg) - } -} - -func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { - var opts []GenericOption - - // Endpoint - if v, ok := e.getEnvValue("ENDPOINT"); ok { - opts = append(opts, WithEndpoint(v)) - } - if v, ok := e.getEnvValue("TRACES_ENDPOINT"); ok { - opts = append(opts, WithTracesEndpoint(v)) - } - if v, ok := e.getEnvValue("METRICS_ENDPOINT"); ok { - opts = append(opts, WithMetricsEndpoint(v)) - } - - // Certificate File - if path, ok := e.getEnvValue("CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp exporter certificate '%s': %w", path, err)) - } - } - if path, ok := e.getEnvValue("TRACES_CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTracesTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp traces exporter certificate '%s': %w", path, err)) - } - } - if path, ok := e.getEnvValue("METRICS_CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithMetricsTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp metrics exporter certificate '%s': %w", path, err)) - } - } - - // Headers - if h, ok := e.getEnvValue("HEADERS"); ok { - opts = append(opts, WithHeaders(stringToHeader(h))) - } - if h, ok := e.getEnvValue("TRACES_HEADERS"); ok { - opts = append(opts, WithTracesHeaders(stringToHeader(h))) - } - if h, ok := e.getEnvValue("METRICS_HEADERS"); ok { - opts = append(opts, WithMetricsHeaders(stringToHeader(h))) - } - - // Compression - if c, ok := e.getEnvValue("COMPRESSION"); ok { - opts = append(opts, WithCompression(stringToCompression(c))) - } - if c, ok := e.getEnvValue("TRACES_COMPRESSION"); ok { - opts = append(opts, WithTracesCompression(stringToCompression(c))) - } - if c, ok := e.getEnvValue("METRICS_COMPRESSION"); ok { - opts = append(opts, WithMetricsCompression(stringToCompression(c))) - } - - // Timeout - if t, ok := e.getEnvValue("TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond)) - } - } - if t, ok := e.getEnvValue("TRACES_TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTracesTimeout(time.Duration(d)*time.Millisecond)) - } - } - if t, ok := e.getEnvValue("METRICS_TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithMetricsTimeout(time.Duration(d)*time.Millisecond)) - } - } - - return opts -} - -// getEnvValue gets an OTLP environment variable value of the specified key using the GetEnv function. -// This function already prepends the OTLP prefix to all key lookup. -func (e *EnvOptionsReader) getEnvValue(key string) (string, bool) { - v := strings.TrimSpace(e.GetEnv(fmt.Sprintf("OTEL_EXPORTER_OTLP_%s", key))) - return v, v != "" -} - -func (e *EnvOptionsReader) readTLSConfig(path string) (*tls.Config, error) { - b, err := e.ReadFile(path) - if err != nil { - return nil, err - } - return CreateTLSConfig(b) -} - -func stringToCompression(value string) otlp.Compression { - switch value { - case "gzip": - return otlp.GzipCompression - } - - return otlp.NoCompression -} - -func stringToHeader(value string) map[string]string { - headersPairs := strings.Split(value, ",") - headers := make(map[string]string) - - for _, header := range headersPairs { - nameValue := strings.SplitN(header, "=", 2) - if len(nameValue) < 2 { - continue - } - name, err := url.QueryUnescape(nameValue[0]) - if err != nil { - continue - } - trimmedName := strings.TrimSpace(name) - value, err := url.QueryUnescape(nameValue[1]) - if err != nil { - continue - } - trimmedValue := strings.TrimSpace(value) - - headers[trimmedName] = trimmedValue - } - - return headers -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/options.go deleted file mode 100644 index 3fd4a30dd38..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/options.go +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig" - -import ( - "crypto/tls" - "fmt" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - - "go.opentelemetry.io/otel/exporters/otlp" -) - -const ( - // DefaultMaxAttempts describes how many times the driver - // should retry the sending of the payload in case of a - // retryable error. - DefaultMaxAttempts int = 5 - // DefaultTracesPath is a default URL path for endpoint that - // receives spans. - DefaultTracesPath string = "/v1/traces" - // DefaultMetricsPath is a default URL path for endpoint that - // receives metrics. - DefaultMetricsPath string = "/v1/metrics" - // DefaultBackoff is a default base backoff time used in the - // exponential backoff strategy. - DefaultBackoff time.Duration = 300 * time.Millisecond - // DefaultTimeout is a default max waiting time for the backend to process - // each span or metrics batch. - DefaultTimeout time.Duration = 10 * time.Second - // DefaultServiceConfig is the gRPC service config used if none is - // provided by the user. - DefaultServiceConfig = `{ - "methodConfig":[{ - "name":[ - { "service":"opentelemetry.proto.collector.metrics.v1.MetricsService" }, - { "service":"opentelemetry.proto.collector.trace.v1.TraceService" } - ], - "retryPolicy":{ - "MaxAttempts":5, - "InitialBackoff":"0.3s", - "MaxBackoff":"5s", - "BackoffMultiplier":2, - "RetryableStatusCodes":[ - "CANCELLED", - "DEADLINE_EXCEEDED", - "RESOURCE_EXHAUSTED", - "ABORTED", - "OUT_OF_RANGE", - "UNAVAILABLE", - "DATA_LOSS" - ] - } - }] -}` -) - -type ( - SignalConfig struct { - Endpoint string - Insecure bool - TLSCfg *tls.Config - Headers map[string]string - Compression otlp.Compression - Timeout time.Duration - URLPath string - - // gRPC configurations - GRPCCredentials credentials.TransportCredentials - } - - Config struct { - // Signal specific configurations - Metrics SignalConfig - Traces SignalConfig - - // General configurations - MaxAttempts int - Backoff time.Duration - - // HTTP configuration - Marshaler otlp.Marshaler - - // gRPC configurations - ReconnectionPeriod time.Duration - ServiceConfig string - DialOptions []grpc.DialOption - } -) - -func NewDefaultConfig() Config { - c := Config{ - Traces: SignalConfig{ - Endpoint: fmt.Sprintf("%s:%d", otlp.DefaultCollectorHost, otlp.DefaultCollectorPort), - URLPath: DefaultTracesPath, - Compression: otlp.NoCompression, - Timeout: DefaultTimeout, - }, - Metrics: SignalConfig{ - Endpoint: fmt.Sprintf("%s:%d", otlp.DefaultCollectorHost, otlp.DefaultCollectorPort), - URLPath: DefaultMetricsPath, - Compression: otlp.NoCompression, - Timeout: DefaultTimeout, - }, - MaxAttempts: DefaultMaxAttempts, - Backoff: DefaultBackoff, - ServiceConfig: DefaultServiceConfig, - } - - return c -} - -type ( - // GenericOption applies an option to the HTTP or gRPC driver. - GenericOption interface { - ApplyHTTPOption(*Config) - ApplyGRPCOption(*Config) - - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() - } - - // HTTPOption applies an option to the HTTP driver. - HTTPOption interface { - ApplyHTTPOption(*Config) - - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() - } - - // GRPCOption applies an option to the gRPC driver. - GRPCOption interface { - ApplyGRPCOption(*Config) - - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() - } -) - -// genericOption is an option that applies the same logic -// for both gRPC and HTTP. -type genericOption struct { - fn func(*Config) -} - -func (g *genericOption) ApplyGRPCOption(cfg *Config) { - g.fn(cfg) -} - -func (g *genericOption) ApplyHTTPOption(cfg *Config) { - g.fn(cfg) -} - -func (genericOption) private() {} - -func newGenericOption(fn func(cfg *Config)) GenericOption { - return &genericOption{fn: fn} -} - -// splitOption is an option that applies different logics -// for gRPC and HTTP. -type splitOption struct { - httpFn func(*Config) - grpcFn func(*Config) -} - -func (g *splitOption) ApplyGRPCOption(cfg *Config) { - g.grpcFn(cfg) -} - -func (g *splitOption) ApplyHTTPOption(cfg *Config) { - g.httpFn(cfg) -} - -func (splitOption) private() {} - -func newSplitOption(httpFn func(cfg *Config), grpcFn func(cfg *Config)) GenericOption { - return &splitOption{httpFn: httpFn, grpcFn: grpcFn} -} - -// httpOption is an option that is only applied to the HTTP driver. -type httpOption struct { - fn func(*Config) -} - -func (h *httpOption) ApplyHTTPOption(cfg *Config) { - h.fn(cfg) -} - -func (httpOption) private() {} - -func NewHTTPOption(fn func(cfg *Config)) HTTPOption { - return &httpOption{fn: fn} -} - -// grpcOption is an option that is only applied to the gRPC driver. -type grpcOption struct { - fn func(*Config) -} - -func (h *grpcOption) ApplyGRPCOption(cfg *Config) { - h.fn(cfg) -} - -func (grpcOption) private() {} - -func NewGRPCOption(fn func(cfg *Config)) GRPCOption { - return &grpcOption{fn: fn} -} - -// Generic Options - -func WithEndpoint(endpoint string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Endpoint = endpoint - cfg.Metrics.Endpoint = endpoint - }) -} - -func WithTracesEndpoint(endpoint string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Endpoint = endpoint - }) -} - -func WithMetricsEndpoint(endpoint string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.Endpoint = endpoint - }) -} - -func WithCompression(compression otlp.Compression) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Compression = compression - cfg.Metrics.Compression = compression - }) -} - -func WithTracesCompression(compression otlp.Compression) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Compression = compression - }) -} - -func WithMetricsCompression(compression otlp.Compression) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.Compression = compression - }) -} - -func WithTracesURLPath(urlPath string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.URLPath = urlPath - }) -} - -func WithMetricsURLPath(urlPath string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.URLPath = urlPath - }) -} - -func WithMaxAttempts(maxAttempts int) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.MaxAttempts = maxAttempts - }) -} - -func WithBackoff(duration time.Duration) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Backoff = duration - }) -} - -func WithTLSClientConfig(tlsCfg *tls.Config) GenericOption { - return newSplitOption(func(cfg *Config) { - cfg.Traces.TLSCfg = tlsCfg.Clone() - cfg.Metrics.TLSCfg = tlsCfg.Clone() - }, func(cfg *Config) { - cfg.Traces.GRPCCredentials = credentials.NewTLS(tlsCfg) - cfg.Metrics.GRPCCredentials = credentials.NewTLS(tlsCfg) - }) -} - -func WithTracesTLSClientConfig(tlsCfg *tls.Config) GenericOption { - return newSplitOption(func(cfg *Config) { - cfg.Traces.TLSCfg = tlsCfg.Clone() - }, func(cfg *Config) { - cfg.Traces.GRPCCredentials = credentials.NewTLS(tlsCfg) - }) -} - -func WithMetricsTLSClientConfig(tlsCfg *tls.Config) GenericOption { - return newSplitOption(func(cfg *Config) { - cfg.Metrics.TLSCfg = tlsCfg.Clone() - }, func(cfg *Config) { - cfg.Metrics.GRPCCredentials = credentials.NewTLS(tlsCfg) - }) -} - -func WithInsecure() GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Insecure = true - cfg.Metrics.Insecure = true - }) -} - -func WithInsecureTraces() GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Insecure = true - }) -} - -func WithInsecureMetrics() GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.Insecure = true - }) -} - -func WithHeaders(headers map[string]string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Headers = headers - cfg.Metrics.Headers = headers - }) -} - -func WithTracesHeaders(headers map[string]string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Headers = headers - }) -} - -func WithMetricsHeaders(headers map[string]string) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.Headers = headers - }) -} - -func WithTimeout(duration time.Duration) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Timeout = duration - cfg.Metrics.Timeout = duration - }) -} - -func WithTracesTimeout(duration time.Duration) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Traces.Timeout = duration - }) -} - -func WithMetricsTimeout(duration time.Duration) GenericOption { - return newGenericOption(func(cfg *Config) { - cfg.Metrics.Timeout = duration - }) -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/tls.go deleted file mode 100644 index 0cbddb86533..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig/tls.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpconfig - -import ( - "crypto/tls" - "crypto/x509" - "errors" - "io/ioutil" -) - -const ( - WeakCertificate = ` ------BEGIN CERTIFICATE----- -MIIBhzCCASygAwIBAgIRANHpHgAWeTnLZpTSxCKs0ggwCgYIKoZIzj0EAwIwEjEQ -MA4GA1UEChMHb3RlbC1nbzAeFw0yMTA0MDExMzU5MDNaFw0yMTA0MDExNDU5MDNa -MBIxEDAOBgNVBAoTB290ZWwtZ28wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS9 -nWSkmPCxShxnp43F+PrOtbGV7sNfkbQ/kxzi9Ego0ZJdiXxkmv/C05QFddCW7Y0Z -sJCLHGogQsYnWJBXUZOVo2MwYTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI -KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAsBgNVHREEJTAjgglsb2NhbGhvc3SHEAAA -AAAAAAAAAAAAAAAAAAGHBH8AAAEwCgYIKoZIzj0EAwIDSQAwRgIhANwZVVKvfvQ/ -1HXsTvgH+xTQswOwSSKYJ1cVHQhqK7ZbAiEAus8NxpTRnp5DiTMuyVmhVNPB+bVH -Lhnm4N/QDk5rek0= ------END CERTIFICATE----- -` - WeakPrivateKey = ` ------BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgN8HEXiXhvByrJ1zK -SFT6Y2l2KqDWwWzKf+t4CyWrNKehRANCAAS9nWSkmPCxShxnp43F+PrOtbGV7sNf -kbQ/kxzi9Ego0ZJdiXxkmv/C05QFddCW7Y0ZsJCLHGogQsYnWJBXUZOV ------END PRIVATE KEY----- -` -) - -// ReadTLSConfigFromFile reads a PEM certificate file and creates -// a tls.Config that will use this certifate to verify a server certificate. -func ReadTLSConfigFromFile(path string) (*tls.Config, error) { - b, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - - return CreateTLSConfig(b) -} - -// CreateTLSConfig creates a tls.Config from a raw certificate bytes -// to verify a server certificate. -func CreateTLSConfig(certBytes []byte) (*tls.Config, error) { - cp := x509.NewCertPool() - if ok := cp.AppendCertsFromPEM(certBytes); !ok { - return nil, errors.New("failed to append certificate to the cert pool") - } - - return &tls.Config{ - RootCAs: cp, - }, nil -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/attribute.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/attribute.go deleted file mode 100644 index 5902cad6ae2..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/attribute.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transform - -import ( - "reflect" - - "go.opentelemetry.io/otel/attribute" - commonpb "go.opentelemetry.io/proto/otlp/common/v1" - - "go.opentelemetry.io/otel/sdk/resource" -) - -// Attributes transforms a slice of KeyValues into a slice of OTLP attribute key-values. -func Attributes(attrs []attribute.KeyValue) []*commonpb.KeyValue { - if len(attrs) == 0 { - return nil - } - - out := make([]*commonpb.KeyValue, 0, len(attrs)) - for _, kv := range attrs { - out = append(out, toAttribute(kv)) - } - return out -} - -// ResourceAttributes transforms a Resource into a slice of OTLP attribute key-values. -func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue { - if resource.Len() == 0 { - return nil - } - - out := make([]*commonpb.KeyValue, 0, resource.Len()) - for iter := resource.Iter(); iter.Next(); { - out = append(out, toAttribute(iter.Attribute())) - } - - return out -} - -func toAttribute(v attribute.KeyValue) *commonpb.KeyValue { - result := &commonpb.KeyValue{ - Key: string(v.Key), - Value: new(commonpb.AnyValue), - } - switch v.Value.Type() { - case attribute.BOOL: - result.Value.Value = &commonpb.AnyValue_BoolValue{ - BoolValue: v.Value.AsBool(), - } - case attribute.INT64: - result.Value.Value = &commonpb.AnyValue_IntValue{ - IntValue: v.Value.AsInt64(), - } - case attribute.FLOAT64: - result.Value.Value = &commonpb.AnyValue_DoubleValue{ - DoubleValue: v.Value.AsFloat64(), - } - case attribute.STRING: - result.Value.Value = &commonpb.AnyValue_StringValue{ - StringValue: v.Value.AsString(), - } - case attribute.ARRAY: - result.Value.Value = &commonpb.AnyValue_ArrayValue{ - ArrayValue: &commonpb.ArrayValue{ - Values: arrayValues(v), - }, - } - default: - result.Value.Value = &commonpb.AnyValue_StringValue{ - StringValue: "INVALID", - } - } - return result -} - -func arrayValues(kv attribute.KeyValue) []*commonpb.AnyValue { - a := kv.Value.AsArray() - aType := reflect.TypeOf(a) - var valueFunc func(reflect.Value) *commonpb.AnyValue - switch aType.Elem().Kind() { - case reflect.Bool: - valueFunc = func(v reflect.Value) *commonpb.AnyValue { - return &commonpb.AnyValue{ - Value: &commonpb.AnyValue_BoolValue{ - BoolValue: v.Bool(), - }, - } - } - case reflect.Int, reflect.Int64: - valueFunc = func(v reflect.Value) *commonpb.AnyValue { - return &commonpb.AnyValue{ - Value: &commonpb.AnyValue_IntValue{ - IntValue: v.Int(), - }, - } - } - case reflect.Uintptr: - valueFunc = func(v reflect.Value) *commonpb.AnyValue { - return &commonpb.AnyValue{ - Value: &commonpb.AnyValue_IntValue{ - IntValue: int64(v.Uint()), - }, - } - } - case reflect.Float64: - valueFunc = func(v reflect.Value) *commonpb.AnyValue { - return &commonpb.AnyValue{ - Value: &commonpb.AnyValue_DoubleValue{ - DoubleValue: v.Float(), - }, - } - } - case reflect.String: - valueFunc = func(v reflect.Value) *commonpb.AnyValue { - return &commonpb.AnyValue{ - Value: &commonpb.AnyValue_StringValue{ - StringValue: v.String(), - }, - } - } - } - - results := make([]*commonpb.AnyValue, aType.Len()) - for i, aValue := 0, reflect.ValueOf(a); i < aValue.Len(); i++ { - results[i] = valueFunc(aValue.Index(i)) - } - return results -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/instrumentation.go deleted file mode 100644 index 4ed5f96646c..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/instrumentation.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transform - -import ( - commonpb "go.opentelemetry.io/proto/otlp/common/v1" - - "go.opentelemetry.io/otel/sdk/instrumentation" -) - -func instrumentationLibrary(il instrumentation.Library) *commonpb.InstrumentationLibrary { - if il == (instrumentation.Library{}) { - return nil - } - return &commonpb.InstrumentationLibrary{ - Name: il.Name, - Version: il.Version, - } -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/metric.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/metric.go deleted file mode 100644 index 1922b9b9c69..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/metric.go +++ /dev/null @@ -1,631 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package transform provides translations for opentelemetry-go concepts and -// structures to otlp structures. -package transform - -import ( - "context" - "errors" - "fmt" - "strings" - "sync" - "time" - - "go.opentelemetry.io/otel/attribute" - commonpb "go.opentelemetry.io/proto/otlp/common/v1" - metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" - resourcepb "go.opentelemetry.io/proto/otlp/resource/v1" - - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/instrumentation" - "go.opentelemetry.io/otel/sdk/resource" -) - -var ( - // ErrUnimplementedAgg is returned when a transformation of an unimplemented - // aggregator is attempted. - ErrUnimplementedAgg = errors.New("unimplemented aggregator") - - // ErrIncompatibleAgg is returned when - // aggregation.Kind implies an interface conversion that has - // failed - ErrIncompatibleAgg = errors.New("incompatible aggregation type") - - // ErrUnknownValueType is returned when a transformation of an unknown value - // is attempted. - ErrUnknownValueType = errors.New("invalid value type") - - // ErrContextCanceled is returned when a context cancellation halts a - // transformation. - ErrContextCanceled = errors.New("context canceled") - - // ErrTransforming is returned when an unexected error is encoutered transforming. - ErrTransforming = errors.New("transforming failed") -) - -// result is the product of transforming Records into OTLP Metrics. -type result struct { - Resource *resource.Resource - InstrumentationLibrary instrumentation.Library - Metric *metricpb.Metric - Err error -} - -// toNanos returns the number of nanoseconds since the UNIX epoch. -func toNanos(t time.Time) uint64 { - if t.IsZero() { - return 0 - } - return uint64(t.UnixNano()) -} - -// CheckpointSet transforms all records contained in a checkpoint into -// batched OTLP ResourceMetrics. -func CheckpointSet(ctx context.Context, exportSelector export.ExportKindSelector, cps export.CheckpointSet, numWorkers uint) ([]*metricpb.ResourceMetrics, error) { - records, errc := source(ctx, exportSelector, cps) - - // Start a fixed number of goroutines to transform records. - transformed := make(chan result) - var wg sync.WaitGroup - wg.Add(int(numWorkers)) - for i := uint(0); i < numWorkers; i++ { - go func() { - defer wg.Done() - transformer(ctx, exportSelector, records, transformed) - }() - } - go func() { - wg.Wait() - close(transformed) - }() - - // Synchronously collect the transformed records and transmit. - rms, err := sink(ctx, transformed) - if err != nil { - return nil, err - } - - // source is complete, check for any errors. - if err := <-errc; err != nil { - return nil, err - } - return rms, nil -} - -// source starts a goroutine that sends each one of the Records yielded by -// the CheckpointSet on the returned chan. Any error encoutered will be sent -// on the returned error chan after seeding is complete. -func source(ctx context.Context, exportSelector export.ExportKindSelector, cps export.CheckpointSet) (<-chan export.Record, <-chan error) { - errc := make(chan error, 1) - out := make(chan export.Record) - // Seed records into process. - go func() { - defer close(out) - // No select is needed since errc is buffered. - errc <- cps.ForEach(exportSelector, func(r export.Record) error { - select { - case <-ctx.Done(): - return ErrContextCanceled - case out <- r: - } - return nil - }) - }() - return out, errc -} - -// transformer transforms records read from the passed in chan into -// OTLP Metrics which are sent on the out chan. -func transformer(ctx context.Context, exportSelector export.ExportKindSelector, in <-chan export.Record, out chan<- result) { - for r := range in { - m, err := Record(exportSelector, r) - // Propagate errors, but do not send empty results. - if err == nil && m == nil { - continue - } - res := result{ - Resource: r.Resource(), - InstrumentationLibrary: instrumentation.Library{ - Name: r.Descriptor().InstrumentationName(), - Version: r.Descriptor().InstrumentationVersion(), - }, - Metric: m, - Err: err, - } - select { - case <-ctx.Done(): - return - case out <- res: - } - } -} - -// sink collects transformed Records and batches them. -// -// Any errors encoutered transforming input will be reported with an -// ErrTransforming as well as the completed ResourceMetrics. It is up to the -// caller to handle any incorrect data in these ResourceMetrics. -func sink(ctx context.Context, in <-chan result) ([]*metricpb.ResourceMetrics, error) { - var errStrings []string - - type resourceBatch struct { - Resource *resourcepb.Resource - // Group by instrumentation library name and then the MetricDescriptor. - InstrumentationLibraryBatches map[instrumentation.Library]map[string]*metricpb.Metric - } - - // group by unique Resource string. - grouped := make(map[attribute.Distinct]resourceBatch) - for res := range in { - if res.Err != nil { - errStrings = append(errStrings, res.Err.Error()) - continue - } - - rID := res.Resource.Equivalent() - rb, ok := grouped[rID] - if !ok { - rb = resourceBatch{ - Resource: Resource(res.Resource), - InstrumentationLibraryBatches: make(map[instrumentation.Library]map[string]*metricpb.Metric), - } - grouped[rID] = rb - } - - mb, ok := rb.InstrumentationLibraryBatches[res.InstrumentationLibrary] - if !ok { - mb = make(map[string]*metricpb.Metric) - rb.InstrumentationLibraryBatches[res.InstrumentationLibrary] = mb - } - - mID := res.Metric.GetName() - m, ok := mb[mID] - if !ok { - mb[mID] = res.Metric - continue - } - switch res.Metric.Data.(type) { - case *metricpb.Metric_IntGauge: - m.GetIntGauge().DataPoints = append(m.GetIntGauge().DataPoints, res.Metric.GetIntGauge().DataPoints...) - case *metricpb.Metric_IntHistogram: - m.GetIntHistogram().DataPoints = append(m.GetIntHistogram().DataPoints, res.Metric.GetIntHistogram().DataPoints...) - case *metricpb.Metric_IntSum: - m.GetIntSum().DataPoints = append(m.GetIntSum().DataPoints, res.Metric.GetIntSum().DataPoints...) - case *metricpb.Metric_DoubleGauge: - m.GetDoubleGauge().DataPoints = append(m.GetDoubleGauge().DataPoints, res.Metric.GetDoubleGauge().DataPoints...) - case *metricpb.Metric_DoubleHistogram: - m.GetDoubleHistogram().DataPoints = append(m.GetDoubleHistogram().DataPoints, res.Metric.GetDoubleHistogram().DataPoints...) - case *metricpb.Metric_DoubleSum: - m.GetDoubleSum().DataPoints = append(m.GetDoubleSum().DataPoints, res.Metric.GetDoubleSum().DataPoints...) - default: - } - } - - if len(grouped) == 0 { - return nil, nil - } - - var rms []*metricpb.ResourceMetrics - for _, rb := range grouped { - rm := &metricpb.ResourceMetrics{Resource: rb.Resource} - for il, mb := range rb.InstrumentationLibraryBatches { - ilm := &metricpb.InstrumentationLibraryMetrics{ - Metrics: make([]*metricpb.Metric, 0, len(mb)), - } - if il != (instrumentation.Library{}) { - ilm.InstrumentationLibrary = &commonpb.InstrumentationLibrary{ - Name: il.Name, - Version: il.Version, - } - } - for _, m := range mb { - ilm.Metrics = append(ilm.Metrics, m) - } - rm.InstrumentationLibraryMetrics = append(rm.InstrumentationLibraryMetrics, ilm) - } - rms = append(rms, rm) - } - - // Report any transform errors. - if len(errStrings) > 0 { - return rms, fmt.Errorf("%w:\n -%s", ErrTransforming, strings.Join(errStrings, "\n -")) - } - return rms, nil -} - -// Record transforms a Record into an OTLP Metric. An ErrIncompatibleAgg -// error is returned if the Record Aggregator is not supported. -func Record(exportSelector export.ExportKindSelector, r export.Record) (*metricpb.Metric, error) { - agg := r.Aggregation() - switch agg.Kind() { - case aggregation.MinMaxSumCountKind: - mmsc, ok := agg.(aggregation.MinMaxSumCount) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrIncompatibleAgg, agg) - } - return minMaxSumCount(r, mmsc) - - case aggregation.HistogramKind: - h, ok := agg.(aggregation.Histogram) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrIncompatibleAgg, agg) - } - return histogramPoint(r, exportSelector.ExportKindFor(r.Descriptor(), aggregation.HistogramKind), h) - - case aggregation.SumKind: - s, ok := agg.(aggregation.Sum) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrIncompatibleAgg, agg) - } - sum, err := s.Sum() - if err != nil { - return nil, err - } - return sumPoint(r, sum, r.StartTime(), r.EndTime(), exportSelector.ExportKindFor(r.Descriptor(), aggregation.SumKind), r.Descriptor().InstrumentKind().Monotonic()) - - case aggregation.LastValueKind: - lv, ok := agg.(aggregation.LastValue) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrIncompatibleAgg, agg) - } - value, tm, err := lv.LastValue() - if err != nil { - return nil, err - } - return gaugePoint(r, value, time.Time{}, tm) - - case aggregation.ExactKind: - e, ok := agg.(aggregation.Points) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrIncompatibleAgg, agg) - } - pts, err := e.Points() - if err != nil { - return nil, err - } - - return gaugeArray(r, pts) - - default: - return nil, fmt.Errorf("%w: %T", ErrUnimplementedAgg, agg) - } -} - -func gaugeArray(record export.Record, points []aggregation.Point) (*metricpb.Metric, error) { - desc := record.Descriptor() - labels := record.Labels() - m := &metricpb.Metric{ - Name: desc.Name(), - Description: desc.Description(), - Unit: string(desc.Unit()), - } - - pbLabels := stringKeyValues(labels.Iter()) - - switch nk := desc.NumberKind(); nk { - case number.Int64Kind: - var pts []*metricpb.IntDataPoint - for _, s := range points { - pts = append(pts, &metricpb.IntDataPoint{ - Labels: pbLabels, - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Value: s.Number.CoerceToInt64(nk), - }) - } - m.Data = &metricpb.Metric_IntGauge{ - IntGauge: &metricpb.IntGauge{ - DataPoints: pts, - }, - } - - case number.Float64Kind: - var pts []*metricpb.DoubleDataPoint - for _, s := range points { - pts = append(pts, &metricpb.DoubleDataPoint{ - Labels: pbLabels, - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Value: s.Number.CoerceToFloat64(nk), - }) - } - m.Data = &metricpb.Metric_DoubleGauge{ - DoubleGauge: &metricpb.DoubleGauge{ - DataPoints: pts, - }, - } - - default: - return nil, fmt.Errorf("%w: %v", ErrUnknownValueType, nk) - } - - return m, nil -} - -func gaugePoint(record export.Record, num number.Number, start, end time.Time) (*metricpb.Metric, error) { - desc := record.Descriptor() - labels := record.Labels() - - m := &metricpb.Metric{ - Name: desc.Name(), - Description: desc.Description(), - Unit: string(desc.Unit()), - } - - switch n := desc.NumberKind(); n { - case number.Int64Kind: - m.Data = &metricpb.Metric_IntGauge{ - IntGauge: &metricpb.IntGauge{ - DataPoints: []*metricpb.IntDataPoint{ - { - Value: num.CoerceToInt64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(start), - TimeUnixNano: toNanos(end), - }, - }, - }, - } - case number.Float64Kind: - m.Data = &metricpb.Metric_DoubleGauge{ - DoubleGauge: &metricpb.DoubleGauge{ - DataPoints: []*metricpb.DoubleDataPoint{ - { - Value: num.CoerceToFloat64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(start), - TimeUnixNano: toNanos(end), - }, - }, - }, - } - default: - return nil, fmt.Errorf("%w: %v", ErrUnknownValueType, n) - } - - return m, nil -} - -func exportKindToTemporality(ek export.ExportKind) metricpb.AggregationTemporality { - switch ek { - case export.DeltaExportKind: - return metricpb.AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA - case export.CumulativeExportKind: - return metricpb.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE - } - return metricpb.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED -} - -func sumPoint(record export.Record, num number.Number, start, end time.Time, ek export.ExportKind, monotonic bool) (*metricpb.Metric, error) { - desc := record.Descriptor() - labels := record.Labels() - - m := &metricpb.Metric{ - Name: desc.Name(), - Description: desc.Description(), - Unit: string(desc.Unit()), - } - - switch n := desc.NumberKind(); n { - case number.Int64Kind: - m.Data = &metricpb.Metric_IntSum{ - IntSum: &metricpb.IntSum{ - IsMonotonic: monotonic, - AggregationTemporality: exportKindToTemporality(ek), - DataPoints: []*metricpb.IntDataPoint{ - { - Value: num.CoerceToInt64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(start), - TimeUnixNano: toNanos(end), - }, - }, - }, - } - case number.Float64Kind: - m.Data = &metricpb.Metric_DoubleSum{ - DoubleSum: &metricpb.DoubleSum{ - IsMonotonic: monotonic, - AggregationTemporality: exportKindToTemporality(ek), - DataPoints: []*metricpb.DoubleDataPoint{ - { - Value: num.CoerceToFloat64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(start), - TimeUnixNano: toNanos(end), - }, - }, - }, - } - default: - return nil, fmt.Errorf("%w: %v", ErrUnknownValueType, n) - } - - return m, nil -} - -// minMaxSumCountValue returns the values of the MinMaxSumCount Aggregator -// as discrete values. -func minMaxSumCountValues(a aggregation.MinMaxSumCount) (min, max, sum number.Number, count uint64, err error) { - if min, err = a.Min(); err != nil { - return - } - if max, err = a.Max(); err != nil { - return - } - if sum, err = a.Sum(); err != nil { - return - } - if count, err = a.Count(); err != nil { - return - } - return -} - -// minMaxSumCount transforms a MinMaxSumCount Aggregator into an OTLP Metric. -func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metricpb.Metric, error) { - desc := record.Descriptor() - labels := record.Labels() - min, max, sum, count, err := minMaxSumCountValues(a) - if err != nil { - return nil, err - } - - m := &metricpb.Metric{ - Name: desc.Name(), - Description: desc.Description(), - Unit: string(desc.Unit()), - } - - buckets := []uint64{min.AsRaw(), max.AsRaw()} - bounds := []float64{0.0, 100.0} - - switch n := desc.NumberKind(); n { - case number.Int64Kind: - m.Data = &metricpb.Metric_IntHistogram{ - IntHistogram: &metricpb.IntHistogram{ - DataPoints: []*metricpb.IntHistogramDataPoint{ - { - Sum: sum.CoerceToInt64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Count: uint64(count), - BucketCounts: buckets, - ExplicitBounds: bounds, - }, - }, - }, - } - case number.Float64Kind: - m.Data = &metricpb.Metric_DoubleHistogram{ - DoubleHistogram: &metricpb.DoubleHistogram{ - DataPoints: []*metricpb.DoubleHistogramDataPoint{ - { - Sum: sum.CoerceToFloat64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Count: uint64(count), - BucketCounts: buckets, - ExplicitBounds: bounds, - }, - }, - }, - } - default: - return nil, fmt.Errorf("%w: %v", ErrUnknownValueType, n) - } - return m, nil -} - -func histogramValues(a aggregation.Histogram) (boundaries []float64, counts []uint64, err error) { - var buckets aggregation.Buckets - if buckets, err = a.Histogram(); err != nil { - return - } - boundaries, counts = buckets.Boundaries, buckets.Counts - if len(counts) != len(boundaries)+1 { - err = ErrTransforming - return - } - return -} - -// histogram transforms a Histogram Aggregator into an OTLP Metric. -func histogramPoint(record export.Record, ek export.ExportKind, a aggregation.Histogram) (*metricpb.Metric, error) { - desc := record.Descriptor() - labels := record.Labels() - boundaries, counts, err := histogramValues(a) - if err != nil { - return nil, err - } - - count, err := a.Count() - if err != nil { - return nil, err - } - - sum, err := a.Sum() - if err != nil { - return nil, err - } - - m := &metricpb.Metric{ - Name: desc.Name(), - Description: desc.Description(), - Unit: string(desc.Unit()), - } - switch n := desc.NumberKind(); n { - case number.Int64Kind: - m.Data = &metricpb.Metric_IntHistogram{ - IntHistogram: &metricpb.IntHistogram{ - AggregationTemporality: exportKindToTemporality(ek), - DataPoints: []*metricpb.IntHistogramDataPoint{ - { - Sum: sum.CoerceToInt64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Count: uint64(count), - BucketCounts: counts, - ExplicitBounds: boundaries, - }, - }, - }, - } - case number.Float64Kind: - m.Data = &metricpb.Metric_DoubleHistogram{ - DoubleHistogram: &metricpb.DoubleHistogram{ - AggregationTemporality: exportKindToTemporality(ek), - DataPoints: []*metricpb.DoubleHistogramDataPoint{ - { - Sum: sum.CoerceToFloat64(n), - Labels: stringKeyValues(labels.Iter()), - StartTimeUnixNano: toNanos(record.StartTime()), - TimeUnixNano: toNanos(record.EndTime()), - Count: uint64(count), - BucketCounts: counts, - ExplicitBounds: boundaries, - }, - }, - }, - } - default: - return nil, fmt.Errorf("%w: %v", ErrUnknownValueType, n) - } - - return m, nil -} - -// stringKeyValues transforms a label iterator into an OTLP StringKeyValues. -func stringKeyValues(iter attribute.Iterator) []*commonpb.StringKeyValue { - l := iter.Len() - if l == 0 { - return nil - } - result := make([]*commonpb.StringKeyValue, 0, l) - for iter.Next() { - kv := iter.Label() - result = append(result, &commonpb.StringKeyValue{ - Key: string(kv.Key), - Value: kv.Value.Emit(), - }) - } - return result -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/resource.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/resource.go deleted file mode 100644 index 5be53566bf8..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/resource.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transform - -import ( - resourcepb "go.opentelemetry.io/proto/otlp/resource/v1" - - "go.opentelemetry.io/otel/sdk/resource" -) - -// Resource transforms a Resource into an OTLP Resource. -func Resource(r *resource.Resource) *resourcepb.Resource { - if r == nil { - return nil - } - return &resourcepb.Resource{Attributes: ResourceAttributes(r)} -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/span.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/span.go deleted file mode 100644 index d24cb1e6e59..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/transform/span.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transform - -import ( - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - tracepb "go.opentelemetry.io/proto/otlp/trace/v1" - - "go.opentelemetry.io/otel/sdk/instrumentation" - tracesdk "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" -) - -const ( - maxMessageEventsPerSpan = 128 -) - -// SpanData transforms a slice of SpanSnapshot into a slice of OTLP -// ResourceSpans. -func SpanData(sdl []*tracesdk.SpanSnapshot) []*tracepb.ResourceSpans { - if len(sdl) == 0 { - return nil - } - - rsm := make(map[attribute.Distinct]*tracepb.ResourceSpans) - - type ilsKey struct { - r attribute.Distinct - il instrumentation.Library - } - ilsm := make(map[ilsKey]*tracepb.InstrumentationLibrarySpans) - - var resources int - for _, sd := range sdl { - if sd == nil { - continue - } - - rKey := sd.Resource.Equivalent() - iKey := ilsKey{ - r: rKey, - il: sd.InstrumentationLibrary, - } - ils, iOk := ilsm[iKey] - if !iOk { - // Either the resource or instrumentation library were unknown. - ils = &tracepb.InstrumentationLibrarySpans{ - InstrumentationLibrary: instrumentationLibrary(sd.InstrumentationLibrary), - Spans: []*tracepb.Span{}, - } - } - ils.Spans = append(ils.Spans, span(sd)) - ilsm[iKey] = ils - - rs, rOk := rsm[rKey] - if !rOk { - resources++ - // The resource was unknown. - rs = &tracepb.ResourceSpans{ - Resource: Resource(sd.Resource), - InstrumentationLibrarySpans: []*tracepb.InstrumentationLibrarySpans{ils}, - } - rsm[rKey] = rs - continue - } - - // The resource has been seen before. Check if the instrumentation - // library lookup was unknown because if so we need to add it to the - // ResourceSpans. Otherwise, the instrumentation library has already - // been seen and the append we did above will be included it in the - // InstrumentationLibrarySpans reference. - if !iOk { - rs.InstrumentationLibrarySpans = append(rs.InstrumentationLibrarySpans, ils) - } - } - - // Transform the categorized map into a slice - rss := make([]*tracepb.ResourceSpans, 0, resources) - for _, rs := range rsm { - rss = append(rss, rs) - } - return rss -} - -// span transforms a Span into an OTLP span. -func span(sd *tracesdk.SpanSnapshot) *tracepb.Span { - if sd == nil { - return nil - } - - tid := sd.SpanContext.TraceID() - sid := sd.SpanContext.SpanID() - - s := &tracepb.Span{ - TraceId: tid[:], - SpanId: sid[:], - TraceState: sd.SpanContext.TraceState().String(), - Status: status(sd.StatusCode, sd.StatusMessage), - StartTimeUnixNano: uint64(sd.StartTime.UnixNano()), - EndTimeUnixNano: uint64(sd.EndTime.UnixNano()), - Links: links(sd.Links), - Kind: spanKind(sd.SpanKind), - Name: sd.Name, - Attributes: Attributes(sd.Attributes), - Events: spanEvents(sd.MessageEvents), - DroppedAttributesCount: uint32(sd.DroppedAttributeCount), - DroppedEventsCount: uint32(sd.DroppedMessageEventCount), - DroppedLinksCount: uint32(sd.DroppedLinkCount), - } - - if psid := sd.Parent.SpanID(); psid.IsValid() { - s.ParentSpanId = psid[:] - } - - return s -} - -// status transform a span code and message into an OTLP span status. -func status(status codes.Code, message string) *tracepb.Status { - var c tracepb.Status_StatusCode - switch status { - case codes.Error: - c = tracepb.Status_STATUS_CODE_ERROR - default: - c = tracepb.Status_STATUS_CODE_OK - } - return &tracepb.Status{ - Code: c, - Message: message, - } -} - -// links transforms span Links to OTLP span links. -func links(links []trace.Link) []*tracepb.Span_Link { - if len(links) == 0 { - return nil - } - - sl := make([]*tracepb.Span_Link, 0, len(links)) - for _, otLink := range links { - // This redefinition is necessary to prevent otLink.*ID[:] copies - // being reused -- in short we need a new otLink per iteration. - otLink := otLink - - tid := otLink.TraceID() - sid := otLink.SpanID() - - sl = append(sl, &tracepb.Span_Link{ - TraceId: tid[:], - SpanId: sid[:], - Attributes: Attributes(otLink.Attributes), - }) - } - return sl -} - -// spanEvents transforms span Events to an OTLP span events. -func spanEvents(es []trace.Event) []*tracepb.Span_Event { - if len(es) == 0 { - return nil - } - - evCount := len(es) - if evCount > maxMessageEventsPerSpan { - evCount = maxMessageEventsPerSpan - } - events := make([]*tracepb.Span_Event, 0, evCount) - messageEvents := 0 - - // Transform message events - for _, e := range es { - if messageEvents >= maxMessageEventsPerSpan { - break - } - messageEvents++ - events = append(events, - &tracepb.Span_Event{ - Name: e.Name, - TimeUnixNano: uint64(e.Time.UnixNano()), - Attributes: Attributes(e.Attributes), - // TODO (rghetia) : Add Drop Counts when supported. - }, - ) - } - - return events -} - -// spanKind transforms a SpanKind to an OTLP span kind. -func spanKind(kind trace.SpanKind) tracepb.Span_SpanKind { - switch kind { - case trace.SpanKindInternal: - return tracepb.Span_SPAN_KIND_INTERNAL - case trace.SpanKindClient: - return tracepb.Span_SPAN_KIND_CLIENT - case trace.SpanKindServer: - return tracepb.Span_SPAN_KIND_SERVER - case trace.SpanKindProducer: - return tracepb.Span_SPAN_KIND_PRODUCER - case trace.SpanKindConsumer: - return tracepb.Span_SPAN_KIND_CONSUMER - default: - return tracepb.Span_SPAN_KIND_UNSPECIFIED - } -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/options.go deleted file mode 100644 index 7cfaa35d3cc..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/options.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlp // import "go.opentelemetry.io/otel/exporters/otlp" - -import ( - metricsdk "go.opentelemetry.io/otel/sdk/export/metric" -) - -const ( - // DefaultCollectorPort is the port the Exporter will attempt connect to - // if no collector port is provided. - DefaultCollectorPort uint16 = 4317 - // DefaultCollectorHost is the host address the Exporter will attempt - // connect to if no collector address is provided. - DefaultCollectorHost string = "localhost" -) - -// ExporterOption are setting options passed to an Exporter on creation. -type ExporterOption func(*config) - -type config struct { - exportKindSelector metricsdk.ExportKindSelector -} - -// WithMetricExportKindSelector defines the ExportKindSelector used -// for selecting AggregationTemporality (i.e., Cumulative vs. Delta -// aggregation). If not specified otherwise, exporter will use a -// cumulative export kind selector. -func WithMetricExportKindSelector(selector metricsdk.ExportKindSelector) ExporterOption { - return func(cfg *config) { - cfg.exportKindSelector = selector - } -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/optiontypes.go deleted file mode 100644 index 682625f4548..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/optiontypes.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlp // import "go.opentelemetry.io/otel/exporters/otlp" - -// Compression describes the compression used for payloads sent to the -// collector. -type Compression int - -const ( - // NoCompression tells the driver to send payloads without - // compression. - NoCompression Compression = iota - // GzipCompression tells the driver to send payloads after - // compressing them with gzip. - GzipCompression -) - -// Marshaler describes the kind of message format sent to the collector -type Marshaler int - -const ( - // MarshalProto tells the driver to send using the protobuf binary format. - MarshalProto Marshaler = iota - // MarshalJSON tells the driver to send using json format. - MarshalJSON -) diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlp.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlp.go deleted file mode 100644 index 098d93b423a..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlp.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlp // import "go.opentelemetry.io/otel/exporters/otlp" - -import ( - "context" - "errors" - "sync" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - metricsdk "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/selector/simple" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - - "go.opentelemetry.io/otel/sdk/metric/controller/basic" - processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" - tracesdk "go.opentelemetry.io/otel/sdk/trace" -) - -// Exporter is an OpenTelemetry exporter. It exports both traces and metrics -// from OpenTelemetry instrumented to code using OpenTelemetry protocol -// buffers to a configurable receiver. -type Exporter struct { - cfg config - driver ProtocolDriver - - mu sync.RWMutex - started bool - - startOnce sync.Once - stopOnce sync.Once -} - -var _ tracesdk.SpanExporter = (*Exporter)(nil) -var _ metricsdk.Exporter = (*Exporter)(nil) - -// NewExporter constructs a new Exporter and starts it. -func NewExporter(ctx context.Context, driver ProtocolDriver, opts ...ExporterOption) (*Exporter, error) { - exp := NewUnstartedExporter(driver, opts...) - if err := exp.Start(ctx); err != nil { - return nil, err - } - return exp, nil -} - -// NewUnstartedExporter constructs a new Exporter and does not start it. -func NewUnstartedExporter(driver ProtocolDriver, opts ...ExporterOption) *Exporter { - cfg := config{ - // Note: the default ExportKindSelector is specified - // as Cumulative: - // https://github.com/open-telemetry/opentelemetry-specification/issues/731 - exportKindSelector: metricsdk.CumulativeExportKindSelector(), - } - for _, opt := range opts { - opt(&cfg) - } - return &Exporter{ - cfg: cfg, - driver: driver, - } -} - -var ( - errAlreadyStarted = errors.New("already started") -) - -// Start establishes connections to the OpenTelemetry collector. Starting an -// already started exporter returns an error. -func (e *Exporter) Start(ctx context.Context) error { - var err = errAlreadyStarted - e.startOnce.Do(func() { - e.mu.Lock() - e.started = true - e.mu.Unlock() - err = e.driver.Start(ctx) - }) - - return err -} - -// Shutdown closes all connections and releases resources currently being used -// by the exporter. If the exporter is not started this does nothing. A shut -// down exporter can't be started again. Shutting down an already shut down -// exporter does nothing. -func (e *Exporter) Shutdown(ctx context.Context) error { - e.mu.RLock() - started := e.started - e.mu.RUnlock() - - if !started { - return nil - } - - var err error - - e.stopOnce.Do(func() { - err = e.driver.Stop(ctx) - e.mu.Lock() - e.started = false - e.mu.Unlock() - }) - - return err -} - -// Export transforms and batches metric Records into OTLP Metrics and -// transmits them to the configured collector. -func (e *Exporter) Export(parent context.Context, cps metricsdk.CheckpointSet) error { - return e.driver.ExportMetrics(parent, cps, e.cfg.exportKindSelector) -} - -// ExportKindFor reports back to the OpenTelemetry SDK sending this Exporter -// metric telemetry that it needs to be provided in a configured format. -func (e *Exporter) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) metricsdk.ExportKind { - return e.cfg.exportKindSelector.ExportKindFor(desc, kind) -} - -// ExportSpans transforms and batches trace SpanSnapshots into OTLP Trace and -// transmits them to the configured collector. -func (e *Exporter) ExportSpans(ctx context.Context, ss []*tracesdk.SpanSnapshot) error { - return e.driver.ExportTraces(ctx, ss) -} - -// NewExportPipeline sets up a complete export pipeline -// with the recommended TracerProvider setup. -func NewExportPipeline(ctx context.Context, driver ProtocolDriver, exporterOpts ...ExporterOption) (*Exporter, - *sdktrace.TracerProvider, *basic.Controller, error) { - - exp, err := NewExporter(ctx, driver, exporterOpts...) - if err != nil { - return nil, nil, nil, err - } - - tracerProvider := sdktrace.NewTracerProvider( - sdktrace.WithBatcher(exp), - ) - - cntr := basic.New( - processor.New( - simple.NewWithInexpensiveDistribution(), - exp, - ), - ) - - return exp, tracerProvider, cntr, nil -} - -// InstallNewPipeline instantiates a NewExportPipeline with the -// recommended configuration and registers it globally. -func InstallNewPipeline(ctx context.Context, driver ProtocolDriver, exporterOpts ...ExporterOption) (*Exporter, - *sdktrace.TracerProvider, *basic.Controller, error) { - - exp, tp, cntr, err := NewExportPipeline(ctx, driver, exporterOpts...) - if err != nil { - return nil, nil, nil, err - } - - otel.SetTracerProvider(tp) - err = cntr.Start(ctx) - if err != nil { - return nil, nil, nil, err - } - - return exp, tp, cntr, err -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/connection.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/connection.go deleted file mode 100644 index d904b56e058..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/connection.go +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpgrpc - -import ( - "context" - "math/rand" - "sync" - "sync/atomic" - "time" - "unsafe" - - "google.golang.org/grpc/encoding/gzip" - - "go.opentelemetry.io/otel/exporters/otlp" - "go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig" - - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" -) - -type connection struct { - // Ensure pointer is 64-bit aligned for atomic operations on both 32 and 64 bit machines. - lastConnectErrPtr unsafe.Pointer - - // mu protects the connection as it is accessed by the - // exporter goroutines and background connection goroutine - mu sync.Mutex - cc *grpc.ClientConn - - // these fields are read-only after constructor is finished - cfg otlpconfig.Config - sCfg otlpconfig.SignalConfig - metadata metadata.MD - newConnectionHandler func(cc *grpc.ClientConn) - - // these channels are created once - disconnectedCh chan bool - backgroundConnectionDoneCh chan struct{} - stopCh chan struct{} - - // this is for tests, so they can replace the closing - // routine without a worry of modifying some global variable - // or changing it back to original after the test is done - closeBackgroundConnectionDoneCh func(ch chan struct{}) -} - -func newConnection(cfg otlpconfig.Config, sCfg otlpconfig.SignalConfig, handler func(cc *grpc.ClientConn)) *connection { - c := new(connection) - c.newConnectionHandler = handler - c.cfg = cfg - c.sCfg = sCfg - if len(c.sCfg.Headers) > 0 { - c.metadata = metadata.New(c.sCfg.Headers) - } - c.closeBackgroundConnectionDoneCh = func(ch chan struct{}) { - close(ch) - } - return c -} - -func (c *connection) startConnection(ctx context.Context) { - c.stopCh = make(chan struct{}) - c.disconnectedCh = make(chan bool, 1) - c.backgroundConnectionDoneCh = make(chan struct{}) - - if err := c.connect(ctx); err == nil { - c.setStateConnected() - } else { - c.setStateDisconnected(err) - } - go c.indefiniteBackgroundConnection() -} - -func (c *connection) lastConnectError() error { - errPtr := (*error)(atomic.LoadPointer(&c.lastConnectErrPtr)) - if errPtr == nil { - return nil - } - return *errPtr -} - -func (c *connection) saveLastConnectError(err error) { - var errPtr *error - if err != nil { - errPtr = &err - } - atomic.StorePointer(&c.lastConnectErrPtr, unsafe.Pointer(errPtr)) -} - -func (c *connection) setStateDisconnected(err error) { - c.saveLastConnectError(err) - select { - case c.disconnectedCh <- true: - default: - } - c.newConnectionHandler(nil) -} - -func (c *connection) setStateConnected() { - c.saveLastConnectError(nil) -} - -func (c *connection) connected() bool { - return c.lastConnectError() == nil -} - -const defaultConnReattemptPeriod = 10 * time.Second - -func (c *connection) indefiniteBackgroundConnection() { - defer func() { - c.closeBackgroundConnectionDoneCh(c.backgroundConnectionDoneCh) - }() - - connReattemptPeriod := c.cfg.ReconnectionPeriod - if connReattemptPeriod <= 0 { - connReattemptPeriod = defaultConnReattemptPeriod - } - - // No strong seeding required, nano time can - // already help with pseudo uniqueness. - rng := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63n(1024))) - - // maxJitterNanos: 70% of the connectionReattemptPeriod - maxJitterNanos := int64(0.7 * float64(connReattemptPeriod)) - - for { - // Otherwise these will be the normal scenarios to enable - // reconnection if we trip out. - // 1. If we've stopped, return entirely - // 2. Otherwise block until we are disconnected, and - // then retry connecting - select { - case <-c.stopCh: - return - - case <-c.disconnectedCh: - // Quickly check if we haven't stopped at the - // same time. - select { - case <-c.stopCh: - return - - default: - } - - // Normal scenario that we'll wait for - } - - if err := c.connect(context.Background()); err == nil { - c.setStateConnected() - } else { - // this code is unreachable in most cases - // c.connect does not establish connection - c.setStateDisconnected(err) - } - - // Apply some jitter to avoid lockstep retrials of other - // collector-exporters. Lockstep retrials could result in an - // innocent DDOS, by clogging the machine's resources and network. - jitter := time.Duration(rng.Int63n(maxJitterNanos)) - select { - case <-c.stopCh: - return - case <-time.After(connReattemptPeriod + jitter): - } - } -} - -func (c *connection) connect(ctx context.Context) error { - cc, err := c.dialToCollector(ctx) - if err != nil { - return err - } - c.setConnection(cc) - c.newConnectionHandler(cc) - return nil -} - -// setConnection sets cc as the client connection and returns true if -// the connection state changed. -func (c *connection) setConnection(cc *grpc.ClientConn) bool { - c.mu.Lock() - defer c.mu.Unlock() - - // If previous clientConn is same as the current then just return. - // This doesn't happen right now as this func is only called with new ClientConn. - // It is more about future-proofing. - if c.cc == cc { - return false - } - - // If the previous clientConn was non-nil, close it - if c.cc != nil { - _ = c.cc.Close() - } - c.cc = cc - return true -} - -func (c *connection) dialToCollector(ctx context.Context) (*grpc.ClientConn, error) { - dialOpts := []grpc.DialOption{} - if c.cfg.ServiceConfig != "" { - dialOpts = append(dialOpts, grpc.WithDefaultServiceConfig(c.cfg.ServiceConfig)) - } - if c.sCfg.GRPCCredentials != nil { - dialOpts = append(dialOpts, grpc.WithTransportCredentials(c.sCfg.GRPCCredentials)) - } else if c.sCfg.Insecure { - dialOpts = append(dialOpts, grpc.WithInsecure()) - } - if c.sCfg.Compression == otlp.GzipCompression { - dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name))) - } - if len(c.cfg.DialOptions) != 0 { - dialOpts = append(dialOpts, c.cfg.DialOptions...) - } - - ctx, cancel := c.contextWithStop(ctx) - defer cancel() - ctx = c.contextWithMetadata(ctx) - return grpc.DialContext(ctx, c.sCfg.Endpoint, dialOpts...) -} - -func (c *connection) contextWithMetadata(ctx context.Context) context.Context { - if c.metadata.Len() > 0 { - return metadata.NewOutgoingContext(ctx, c.metadata) - } - return ctx -} - -func (c *connection) shutdown(ctx context.Context) error { - close(c.stopCh) - // Ensure that the backgroundConnector returns - select { - case <-c.backgroundConnectionDoneCh: - case <-ctx.Done(): - return ctx.Err() - } - - c.mu.Lock() - cc := c.cc - c.cc = nil - c.mu.Unlock() - - if cc != nil { - return cc.Close() - } - - return nil -} - -func (c *connection) contextWithStop(ctx context.Context) (context.Context, context.CancelFunc) { - // Unify the parent context Done signal with the connection's - // stop channel. - ctx, cancel := context.WithCancel(ctx) - go func(ctx context.Context, cancel context.CancelFunc) { - select { - case <-ctx.Done(): - // Nothing to do, either cancelled or deadline - // happened. - case <-c.stopCh: - cancel() - } - }(ctx, cancel) - return ctx, cancel -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/doc.go deleted file mode 100644 index 68f53fb0aab..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package otlpgrpc provides an implementation of otlp.ProtocolDriver -that connects to the collector and sends traces and metrics using -gRPC. - -This package is currently in a pre-GA phase. Backwards incompatible -changes may be introduced in subsequent minor version releases as we -work to track the evolving OpenTelemetry specification and user -feedback. -*/ -package otlpgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpgrpc" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/driver.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/driver.go deleted file mode 100644 index c5df20566c7..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/driver.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpgrpc" - -import ( - "context" - "errors" - "fmt" - "sync" - - "go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig" - - "google.golang.org/grpc" - - "go.opentelemetry.io/otel/exporters/otlp" - "go.opentelemetry.io/otel/exporters/otlp/internal/transform" - metricsdk "go.opentelemetry.io/otel/sdk/export/metric" - tracesdk "go.opentelemetry.io/otel/sdk/trace" - colmetricpb "go.opentelemetry.io/proto/otlp/collector/metrics/v1" - coltracepb "go.opentelemetry.io/proto/otlp/collector/trace/v1" - metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" - tracepb "go.opentelemetry.io/proto/otlp/trace/v1" -) - -type driver struct { - metricsDriver metricsDriver - tracesDriver tracesDriver -} - -type metricsDriver struct { - connection *connection - - lock sync.Mutex - metricsClient colmetricpb.MetricsServiceClient -} - -type tracesDriver struct { - connection *connection - - lock sync.Mutex - tracesClient coltracepb.TraceServiceClient -} - -var ( - errNoClient = errors.New("no client") -) - -// NewDriver creates a new gRPC protocol driver. -func NewDriver(opts ...Option) otlp.ProtocolDriver { - cfg := otlpconfig.NewDefaultConfig() - otlpconfig.ApplyGRPCEnvConfigs(&cfg) - for _, opt := range opts { - opt.ApplyGRPCOption(&cfg) - } - - d := &driver{} - - d.tracesDriver = tracesDriver{ - connection: newConnection(cfg, cfg.Traces, d.tracesDriver.handleNewConnection), - } - - d.metricsDriver = metricsDriver{ - connection: newConnection(cfg, cfg.Metrics, d.metricsDriver.handleNewConnection), - } - return d -} - -func (md *metricsDriver) handleNewConnection(cc *grpc.ClientConn) { - md.lock.Lock() - defer md.lock.Unlock() - if cc != nil { - md.metricsClient = colmetricpb.NewMetricsServiceClient(cc) - } else { - md.metricsClient = nil - } -} - -func (td *tracesDriver) handleNewConnection(cc *grpc.ClientConn) { - td.lock.Lock() - defer td.lock.Unlock() - if cc != nil { - td.tracesClient = coltracepb.NewTraceServiceClient(cc) - } else { - td.tracesClient = nil - } -} - -// Start implements otlp.ProtocolDriver. It establishes a connection -// to the collector. -func (d *driver) Start(ctx context.Context) error { - d.tracesDriver.connection.startConnection(ctx) - d.metricsDriver.connection.startConnection(ctx) - return nil -} - -// Stop implements otlp.ProtocolDriver. It shuts down the connection -// to the collector. -func (d *driver) Stop(ctx context.Context) error { - if err := d.tracesDriver.connection.shutdown(ctx); err != nil { - return err - } - - return d.metricsDriver.connection.shutdown(ctx) -} - -// ExportMetrics implements otlp.ProtocolDriver. It transforms metrics -// to protobuf binary format and sends the result to the collector. -func (d *driver) ExportMetrics(ctx context.Context, cps metricsdk.CheckpointSet, selector metricsdk.ExportKindSelector) error { - if !d.metricsDriver.connection.connected() { - return fmt.Errorf("metrics exporter is disconnected from the server %s: %w", d.metricsDriver.connection.sCfg.Endpoint, d.metricsDriver.connection.lastConnectError()) - } - ctx, cancel := d.metricsDriver.connection.contextWithStop(ctx) - defer cancel() - ctx, tCancel := context.WithTimeout(ctx, d.metricsDriver.connection.sCfg.Timeout) - defer tCancel() - - rms, err := transform.CheckpointSet(ctx, selector, cps, 1) - if err != nil { - return err - } - if len(rms) == 0 { - return nil - } - - return d.metricsDriver.uploadMetrics(ctx, rms) -} - -func (md *metricsDriver) uploadMetrics(ctx context.Context, protoMetrics []*metricpb.ResourceMetrics) error { - ctx = md.connection.contextWithMetadata(ctx) - err := func() error { - md.lock.Lock() - defer md.lock.Unlock() - if md.metricsClient == nil { - return errNoClient - } - _, err := md.metricsClient.Export(ctx, &colmetricpb.ExportMetricsServiceRequest{ - ResourceMetrics: protoMetrics, - }) - return err - }() - if err != nil { - md.connection.setStateDisconnected(err) - } - return err -} - -// ExportTraces implements otlp.ProtocolDriver. It transforms spans to -// protobuf binary format and sends the result to the collector. -func (d *driver) ExportTraces(ctx context.Context, ss []*tracesdk.SpanSnapshot) error { - if !d.tracesDriver.connection.connected() { - return fmt.Errorf("traces exporter is disconnected from the server %s: %w", d.tracesDriver.connection.sCfg.Endpoint, d.tracesDriver.connection.lastConnectError()) - } - ctx, cancel := d.tracesDriver.connection.contextWithStop(ctx) - defer cancel() - ctx, tCancel := context.WithTimeout(ctx, d.tracesDriver.connection.sCfg.Timeout) - defer tCancel() - - protoSpans := transform.SpanData(ss) - if len(protoSpans) == 0 { - return nil - } - - return d.tracesDriver.uploadTraces(ctx, protoSpans) -} - -func (td *tracesDriver) uploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error { - ctx = td.connection.contextWithMetadata(ctx) - err := func() error { - td.lock.Lock() - defer td.lock.Unlock() - if td.tracesClient == nil { - return errNoClient - } - _, err := td.tracesClient.Export(ctx, &coltracepb.ExportTraceServiceRequest{ - ResourceSpans: protoSpans, - }) - return err - }() - if err != nil { - td.connection.setStateDisconnected(err) - } - return err -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/options.go deleted file mode 100644 index dd7201f94a7..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpgrpc/options.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlpgrpc - -import ( - "fmt" - "time" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/otlp" - "go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig" - - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -// Option applies an option to the gRPC driver. -type Option interface { - otlpconfig.GRPCOption -} - -// WithInsecure disables client transport security for the exporter's gRPC connection -// just like grpc.WithInsecure() https://pkg.go.dev/google.golang.org/grpc#WithInsecure -// does. Note, by default, client security is required unless WithInsecure is used. -func WithInsecure() Option { - return otlpconfig.WithInsecure() -} - -// WithTracesInsecure disables client transport security for the traces exporter's gRPC connection -// just like grpc.WithInsecure() https://pkg.go.dev/google.golang.org/grpc#WithInsecure -// does. Note, by default, client security is required unless WithInsecure is used. -func WithTracesInsecure() Option { - return otlpconfig.WithInsecureTraces() -} - -// WithInsecureMetrics disables client transport security for the metrics exporter's gRPC connection -// just like grpc.WithInsecure() https://pkg.go.dev/google.golang.org/grpc#WithInsecure -// does. Note, by default, client security is required unless WithInsecure is used. -func WithInsecureMetrics() Option { - return otlpconfig.WithInsecureMetrics() -} - -// WithEndpoint allows one to set the endpoint that the exporter will -// connect to the collector on. If unset, it will instead try to use -// connect to DefaultCollectorHost:DefaultCollectorPort. -func WithEndpoint(endpoint string) Option { - return otlpconfig.WithEndpoint(endpoint) -} - -// WithTracesEndpoint allows one to set the traces endpoint that the exporter will -// connect to the collector on. If unset, it will instead try to use -// connect to DefaultCollectorHost:DefaultCollectorPort. -func WithTracesEndpoint(endpoint string) Option { - return otlpconfig.WithTracesEndpoint(endpoint) -} - -// WithMetricsEndpoint allows one to set the metrics endpoint that the exporter will -// connect to the collector on. If unset, it will instead try to use -// connect to DefaultCollectorHost:DefaultCollectorPort. -func WithMetricsEndpoint(endpoint string) Option { - return otlpconfig.WithMetricsEndpoint(endpoint) -} - -// WithReconnectionPeriod allows one to set the delay between next connection attempt -// after failing to connect with the collector. -func WithReconnectionPeriod(rp time.Duration) otlpconfig.GRPCOption { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.ReconnectionPeriod = rp - }) -} - -func compressorToCompression(compressor string) otlp.Compression { - switch compressor { - case "gzip": - return otlp.GzipCompression - } - - otel.Handle(fmt.Errorf("invalid compression type: '%s', using no compression as default", compressor)) - return otlp.NoCompression -} - -// WithCompressor will set the compressor for the gRPC client to use when sending requests. -// It is the responsibility of the caller to ensure that the compressor set has been registered -// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some -// compressors auto-register on import, such as gzip, which can be registered by calling -// `import _ "google.golang.org/grpc/encoding/gzip"`. -func WithCompressor(compressor string) Option { - return otlpconfig.WithCompression(compressorToCompression(compressor)) -} - -// WithTracesCompression will set the compressor for the gRPC client to use when sending traces requests. -// It is the responsibility of the caller to ensure that the compressor set has been registered -// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some -// compressors auto-register on import, such as gzip, which can be registered by calling -// `import _ "google.golang.org/grpc/encoding/gzip"`. -func WithTracesCompression(compressor string) Option { - return otlpconfig.WithTracesCompression(compressorToCompression(compressor)) -} - -// WithMetricsCompression will set the compressor for the gRPC client to use when sending metrics requests. -// It is the responsibility of the caller to ensure that the compressor set has been registered -// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some -// compressors auto-register on import, such as gzip, which can be registered by calling -// `import _ "google.golang.org/grpc/encoding/gzip"`. -func WithMetricsCompression(compressor string) Option { - return otlpconfig.WithMetricsCompression(compressorToCompression(compressor)) -} - -// WithHeaders will send the provided headers with gRPC requests. -func WithHeaders(headers map[string]string) Option { - return otlpconfig.WithHeaders(headers) -} - -// WithTracesHeaders will send the provided headers with gRPC traces requests. -func WithTracesHeaders(headers map[string]string) Option { - return otlpconfig.WithTracesHeaders(headers) -} - -// WithMetricsHeaders will send the provided headers with gRPC metrics requests. -func WithMetricsHeaders(headers map[string]string) Option { - return otlpconfig.WithMetricsHeaders(headers) -} - -// WithTLSCredentials allows the connection to use TLS credentials -// when talking to the server. It takes in grpc.TransportCredentials instead -// of say a Certificate file or a tls.Certificate, because the retrieving of -// these credentials can be done in many ways e.g. plain file, in code tls.Config -// or by certificate rotation, so it is up to the caller to decide what to use. -func WithTLSCredentials(creds credentials.TransportCredentials) Option { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.Traces.GRPCCredentials = creds - cfg.Metrics.GRPCCredentials = creds - }) -} - -// WithTracesTLSCredentials allows the connection to use TLS credentials -// when talking to the traces server. It takes in grpc.TransportCredentials instead -// of say a Certificate file or a tls.Certificate, because the retrieving of -// these credentials can be done in many ways e.g. plain file, in code tls.Config -// or by certificate rotation, so it is up to the caller to decide what to use. -func WithTracesTLSCredentials(creds credentials.TransportCredentials) Option { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.Traces.GRPCCredentials = creds - }) -} - -// WithMetricsTLSCredentials allows the connection to use TLS credentials -// when talking to the metrics server. It takes in grpc.TransportCredentials instead -// of say a Certificate file or a tls.Certificate, because the retrieving of -// these credentials can be done in many ways e.g. plain file, in code tls.Config -// or by certificate rotation, so it is up to the caller to decide what to use. -func WithMetricsTLSCredentials(creds credentials.TransportCredentials) Option { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.Metrics.GRPCCredentials = creds - }) -} - -// WithServiceConfig defines the default gRPC service config used. -func WithServiceConfig(serviceConfig string) Option { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.ServiceConfig = serviceConfig - }) -} - -// WithDialOption opens support to any grpc.DialOption to be used. If it conflicts -// with some other configuration the GRPC specified via the collector the ones here will -// take preference since they are set last. -func WithDialOption(opts ...grpc.DialOption) Option { - return otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) { - cfg.DialOptions = opts - }) -} - -// WithTimeout tells the driver the max waiting time for the backend to process -// each spans or metrics batch. If unset, the default will be 10 seconds. -func WithTimeout(duration time.Duration) Option { - return otlpconfig.WithTimeout(duration) -} - -// WithTracesTimeout tells the driver the max waiting time for the backend to process -// each spans batch. If unset, the default will be 10 seconds. -func WithTracesTimeout(duration time.Duration) Option { - return otlpconfig.WithTracesTimeout(duration) -} - -// WithMetricsTimeout tells the driver the max waiting time for the backend to process -// each metrics batch. If unset, the default will be 10 seconds. -func WithMetricsTimeout(duration time.Duration) Option { - return otlpconfig.WithMetricsTimeout(duration) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/LICENSE similarity index 100% rename from vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE rename to vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/LICENSE diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md new file mode 100644 index 00000000000..50295223182 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md @@ -0,0 +1,51 @@ +# OpenTelemetry-Go OTLP Span Exporter + +[![Go Reference](https://pkg.go.dev/badge/go.opentelemetry.io/otel/exporters/otlp/otlptrace.svg)](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace) + +[OpenTelemetry Protocol Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/protocol/exporter.md) implementation. + +## Installation + +``` +go get -u go.opentelemetry.io/otel/exporters/otlp/otlptrace +``` + +## Examples + +- [HTTP Exporter setup and examples](./otlptracehttp/example_test.go) +- [Full example of gRPC Exporter sending telemetry to a local collector](../../../example/otel-collector) + +## [`otlptrace`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace) + +The `otlptrace` package provides an exporter implementing the OTel span exporter interface. +This exporter is configured using a client satisfying the `otlptrace.Client` interface. +This client handles the transformation of data into wire format and the transmission of that data to the collector. + +## [`otlptracegrpc`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc) + +The `otlptracegrpc` package implements a client for the span exporter that sends trace telemetry data to the collector using gRPC with protobuf-encoded payloads. + +## [`otlptracehttp`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp) + +The `otlptracehttp` package implements a client for the span exporter that sends trace telemetry data to the collector using HTTP with protobuf-encoded payloads. + +## Configuration + +### Environment Variables + +The following environment variables can be used (instead of options objects) to +override the default configuration. For more information about how each of +these environment variables is interpreted, see [the OpenTelemetry +specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/protocol/exporter.md). + +| Environment variable | Option | Default value | +| ------------------------------------------------------------------------ |------------------------------ | -------------------------------------------------------- | +| `OTEL_EXPORTER_OTLP_ENDPOINT` `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `WithEndpoint` `WithInsecure` | `https://localhost:4317` or `https://localhost:4318`[^1] | +| `OTEL_EXPORTER_OTLP_CERTIFICATE` `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | `WithTLSClientConfig` | | +| `OTEL_EXPORTER_OTLP_HEADERS` `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `WithHeaders` | | +| `OTEL_EXPORTER_OTLP_COMPRESSION` `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | `WithCompression` | | +| `OTEL_EXPORTER_OTLP_TIMEOUT` `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `WithTimeout` | `10s` | + +[^1]: The gRPC client defaults to `https://localhost:4317` and the HTTP client `https://localhost:4318`. + +Configuration using options have precedence over the environment variables. diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go new file mode 100644 index 00000000000..dbb40cf5820 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + +import ( + "context" + + tracepb "go.opentelemetry.io/proto/otlp/trace/v1" +) + +// Client manages connections to the collector, handles the +// transformation of data into wire format, and the transmission of that +// data to the collector. +type Client interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // Start should establish connection(s) to endpoint(s). It is + // called just once by the exporter, so the implementation + // does not need to worry about idempotence and locking. + Start(ctx context.Context) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // Stop should close the connections. The function is called + // only once by the exporter, so the implementation does not + // need to worry about idempotence, but it may be called + // concurrently with UploadTraces, so proper + // locking is required. The function serves as a + // synchronization point - after the function returns, the + // process of closing connections is assumed to be finished. + Stop(ctx context.Context) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // UploadTraces should transform the passed traces to the wire + // format and send it to the collector. May be called + // concurrently. + UploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go new file mode 100644 index 00000000000..0dbe15555b3 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + +import ( + "context" + "errors" + "fmt" + "sync" + + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" + tracesdk "go.opentelemetry.io/otel/sdk/trace" +) + +var ( + errAlreadyStarted = errors.New("already started") +) + +// Exporter exports trace data in the OTLP wire format. +type Exporter struct { + client Client + + mu sync.RWMutex + started bool + + startOnce sync.Once + stopOnce sync.Once +} + +// ExportSpans exports a batch of spans. +func (e *Exporter) ExportSpans(ctx context.Context, ss []tracesdk.ReadOnlySpan) error { + protoSpans := tracetransform.Spans(ss) + if len(protoSpans) == 0 { + return nil + } + + err := e.client.UploadTraces(ctx, protoSpans) + if err != nil { + return fmt.Errorf("traces export: %w", err) + } + return nil +} + +// Start establishes a connection to the receiving endpoint. +func (e *Exporter) Start(ctx context.Context) error { + var err = errAlreadyStarted + e.startOnce.Do(func() { + e.mu.Lock() + e.started = true + e.mu.Unlock() + err = e.client.Start(ctx) + }) + + return err +} + +// Shutdown flushes all exports and closes all connections to the receiving endpoint. +func (e *Exporter) Shutdown(ctx context.Context) error { + e.mu.RLock() + started := e.started + e.mu.RUnlock() + + if !started { + return nil + } + + var err error + + e.stopOnce.Do(func() { + err = e.client.Stop(ctx) + e.mu.Lock() + e.started = false + e.mu.Unlock() + }) + + return err +} + +var _ tracesdk.SpanExporter = (*Exporter)(nil) + +// New constructs a new Exporter and starts it. +func New(ctx context.Context, client Client) (*Exporter, error) { + exp := NewUnstarted(client) + if err := exp.Start(ctx); err != nil { + return nil, err + } + return exp, nil +} + +// NewUnstarted constructs a new Exporter and does not start it. +func NewUnstarted(client Client) *Exporter { + return &Exporter{ + client: client, + } +} + +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (e *Exporter) MarshalLog() interface{} { + return struct { + Type string + Client Client + }{ + Type: "otlptrace", + Client: e.client, + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go new file mode 100644 index 00000000000..ec74f1aad75 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go @@ -0,0 +1,158 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" + +import ( + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/resource" + commonpb "go.opentelemetry.io/proto/otlp/common/v1" +) + +// KeyValues transforms a slice of attribute KeyValues into OTLP key-values. +func KeyValues(attrs []attribute.KeyValue) []*commonpb.KeyValue { + if len(attrs) == 0 { + return nil + } + + out := make([]*commonpb.KeyValue, 0, len(attrs)) + for _, kv := range attrs { + out = append(out, KeyValue(kv)) + } + return out +} + +// Iterator transforms an attribute iterator into OTLP key-values. +func Iterator(iter attribute.Iterator) []*commonpb.KeyValue { + l := iter.Len() + if l == 0 { + return nil + } + + out := make([]*commonpb.KeyValue, 0, l) + for iter.Next() { + out = append(out, KeyValue(iter.Attribute())) + } + return out +} + +// ResourceAttributes transforms a Resource OTLP key-values. +func ResourceAttributes(res *resource.Resource) []*commonpb.KeyValue { + return Iterator(res.Iter()) +} + +// KeyValue transforms an attribute KeyValue into an OTLP key-value. +func KeyValue(kv attribute.KeyValue) *commonpb.KeyValue { + return &commonpb.KeyValue{Key: string(kv.Key), Value: Value(kv.Value)} +} + +// Value transforms an attribute Value into an OTLP AnyValue. +func Value(v attribute.Value) *commonpb.AnyValue { + av := new(commonpb.AnyValue) + switch v.Type() { + case attribute.BOOL: + av.Value = &commonpb.AnyValue_BoolValue{ + BoolValue: v.AsBool(), + } + case attribute.BOOLSLICE: + av.Value = &commonpb.AnyValue_ArrayValue{ + ArrayValue: &commonpb.ArrayValue{ + Values: boolSliceValues(v.AsBoolSlice()), + }, + } + case attribute.INT64: + av.Value = &commonpb.AnyValue_IntValue{ + IntValue: v.AsInt64(), + } + case attribute.INT64SLICE: + av.Value = &commonpb.AnyValue_ArrayValue{ + ArrayValue: &commonpb.ArrayValue{ + Values: int64SliceValues(v.AsInt64Slice()), + }, + } + case attribute.FLOAT64: + av.Value = &commonpb.AnyValue_DoubleValue{ + DoubleValue: v.AsFloat64(), + } + case attribute.FLOAT64SLICE: + av.Value = &commonpb.AnyValue_ArrayValue{ + ArrayValue: &commonpb.ArrayValue{ + Values: float64SliceValues(v.AsFloat64Slice()), + }, + } + case attribute.STRING: + av.Value = &commonpb.AnyValue_StringValue{ + StringValue: v.AsString(), + } + case attribute.STRINGSLICE: + av.Value = &commonpb.AnyValue_ArrayValue{ + ArrayValue: &commonpb.ArrayValue{ + Values: stringSliceValues(v.AsStringSlice()), + }, + } + default: + av.Value = &commonpb.AnyValue_StringValue{ + StringValue: "INVALID", + } + } + return av +} + +func boolSliceValues(vals []bool) []*commonpb.AnyValue { + converted := make([]*commonpb.AnyValue, len(vals)) + for i, v := range vals { + converted[i] = &commonpb.AnyValue{ + Value: &commonpb.AnyValue_BoolValue{ + BoolValue: v, + }, + } + } + return converted +} + +func int64SliceValues(vals []int64) []*commonpb.AnyValue { + converted := make([]*commonpb.AnyValue, len(vals)) + for i, v := range vals { + converted[i] = &commonpb.AnyValue{ + Value: &commonpb.AnyValue_IntValue{ + IntValue: v, + }, + } + } + return converted +} + +func float64SliceValues(vals []float64) []*commonpb.AnyValue { + converted := make([]*commonpb.AnyValue, len(vals)) + for i, v := range vals { + converted[i] = &commonpb.AnyValue{ + Value: &commonpb.AnyValue_DoubleValue{ + DoubleValue: v, + }, + } + } + return converted +} + +func stringSliceValues(vals []string) []*commonpb.AnyValue { + converted := make([]*commonpb.AnyValue, len(vals)) + for i, v := range vals { + converted[i] = &commonpb.AnyValue{ + Value: &commonpb.AnyValue_StringValue{ + StringValue: v, + }, + } + } + return converted +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go new file mode 100644 index 00000000000..7aaec38d22a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" + +import ( + "go.opentelemetry.io/otel/sdk/instrumentation" + commonpb "go.opentelemetry.io/proto/otlp/common/v1" +) + +func InstrumentationScope(il instrumentation.Scope) *commonpb.InstrumentationScope { + if il == (instrumentation.Scope{}) { + return nil + } + return &commonpb.InstrumentationScope{ + Name: il.Name, + Version: il.Version, + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go new file mode 100644 index 00000000000..05a1f78adbc --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" + +import ( + "go.opentelemetry.io/otel/sdk/resource" + resourcepb "go.opentelemetry.io/proto/otlp/resource/v1" +) + +// Resource transforms a Resource into an OTLP Resource. +func Resource(r *resource.Resource) *resourcepb.Resource { + if r == nil { + return nil + } + return &resourcepb.Resource{Attributes: ResourceAttributes(r)} +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go new file mode 100644 index 00000000000..b83cbd72478 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go @@ -0,0 +1,205 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" + +import ( + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/sdk/instrumentation" + tracesdk "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" + tracepb "go.opentelemetry.io/proto/otlp/trace/v1" +) + +// Spans transforms a slice of OpenTelemetry spans into a slice of OTLP +// ResourceSpans. +func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans { + if len(sdl) == 0 { + return nil + } + + rsm := make(map[attribute.Distinct]*tracepb.ResourceSpans) + + type key struct { + r attribute.Distinct + is instrumentation.Scope + } + ssm := make(map[key]*tracepb.ScopeSpans) + + var resources int + for _, sd := range sdl { + if sd == nil { + continue + } + + rKey := sd.Resource().Equivalent() + k := key{ + r: rKey, + is: sd.InstrumentationScope(), + } + scopeSpan, iOk := ssm[k] + if !iOk { + // Either the resource or instrumentation scope were unknown. + scopeSpan = &tracepb.ScopeSpans{ + Scope: InstrumentationScope(sd.InstrumentationScope()), + Spans: []*tracepb.Span{}, + SchemaUrl: sd.InstrumentationScope().SchemaURL, + } + } + scopeSpan.Spans = append(scopeSpan.Spans, span(sd)) + ssm[k] = scopeSpan + + rs, rOk := rsm[rKey] + if !rOk { + resources++ + // The resource was unknown. + rs = &tracepb.ResourceSpans{ + Resource: Resource(sd.Resource()), + ScopeSpans: []*tracepb.ScopeSpans{scopeSpan}, + SchemaUrl: sd.Resource().SchemaURL(), + } + rsm[rKey] = rs + continue + } + + // The resource has been seen before. Check if the instrumentation + // library lookup was unknown because if so we need to add it to the + // ResourceSpans. Otherwise, the instrumentation library has already + // been seen and the append we did above will be included it in the + // ScopeSpans reference. + if !iOk { + rs.ScopeSpans = append(rs.ScopeSpans, scopeSpan) + } + } + + // Transform the categorized map into a slice + rss := make([]*tracepb.ResourceSpans, 0, resources) + for _, rs := range rsm { + rss = append(rss, rs) + } + return rss +} + +// span transforms a Span into an OTLP span. +func span(sd tracesdk.ReadOnlySpan) *tracepb.Span { + if sd == nil { + return nil + } + + tid := sd.SpanContext().TraceID() + sid := sd.SpanContext().SpanID() + + s := &tracepb.Span{ + TraceId: tid[:], + SpanId: sid[:], + TraceState: sd.SpanContext().TraceState().String(), + Status: status(sd.Status().Code, sd.Status().Description), + StartTimeUnixNano: uint64(sd.StartTime().UnixNano()), + EndTimeUnixNano: uint64(sd.EndTime().UnixNano()), + Links: links(sd.Links()), + Kind: spanKind(sd.SpanKind()), + Name: sd.Name(), + Attributes: KeyValues(sd.Attributes()), + Events: spanEvents(sd.Events()), + DroppedAttributesCount: uint32(sd.DroppedAttributes()), + DroppedEventsCount: uint32(sd.DroppedEvents()), + DroppedLinksCount: uint32(sd.DroppedLinks()), + } + + if psid := sd.Parent().SpanID(); psid.IsValid() { + s.ParentSpanId = psid[:] + } + + return s +} + +// status transform a span code and message into an OTLP span status. +func status(status codes.Code, message string) *tracepb.Status { + var c tracepb.Status_StatusCode + switch status { + case codes.Ok: + c = tracepb.Status_STATUS_CODE_OK + case codes.Error: + c = tracepb.Status_STATUS_CODE_ERROR + default: + c = tracepb.Status_STATUS_CODE_UNSET + } + return &tracepb.Status{ + Code: c, + Message: message, + } +} + +// links transforms span Links to OTLP span links. +func links(links []tracesdk.Link) []*tracepb.Span_Link { + if len(links) == 0 { + return nil + } + + sl := make([]*tracepb.Span_Link, 0, len(links)) + for _, otLink := range links { + // This redefinition is necessary to prevent otLink.*ID[:] copies + // being reused -- in short we need a new otLink per iteration. + otLink := otLink + + tid := otLink.SpanContext.TraceID() + sid := otLink.SpanContext.SpanID() + + sl = append(sl, &tracepb.Span_Link{ + TraceId: tid[:], + SpanId: sid[:], + Attributes: KeyValues(otLink.Attributes), + DroppedAttributesCount: uint32(otLink.DroppedAttributeCount), + }) + } + return sl +} + +// spanEvents transforms span Events to an OTLP span events. +func spanEvents(es []tracesdk.Event) []*tracepb.Span_Event { + if len(es) == 0 { + return nil + } + + events := make([]*tracepb.Span_Event, len(es)) + // Transform message events + for i := 0; i < len(es); i++ { + events[i] = &tracepb.Span_Event{ + Name: es[i].Name, + TimeUnixNano: uint64(es[i].Time.UnixNano()), + Attributes: KeyValues(es[i].Attributes), + DroppedAttributesCount: uint32(es[i].DroppedAttributeCount), + } + } + return events +} + +// spanKind transforms a SpanKind to an OTLP span kind. +func spanKind(kind trace.SpanKind) tracepb.Span_SpanKind { + switch kind { + case trace.SpanKindInternal: + return tracepb.Span_SPAN_KIND_INTERNAL + case trace.SpanKindClient: + return tracepb.Span_SPAN_KIND_CLIENT + case trace.SpanKindServer: + return tracepb.Span_SPAN_KIND_SERVER + case trace.SpanKindProducer: + return tracepb.Span_SPAN_KIND_PRODUCER + case trace.SpanKindConsumer: + return tracepb.Span_SPAN_KIND_CONSUMER + default: + return tracepb.Span_SPAN_KIND_UNSPECIFIED + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/LICENSE b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go new file mode 100644 index 00000000000..86fb61a0dec --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go @@ -0,0 +1,298 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + +import ( + "context" + "errors" + "sync" + "time" + + "google.golang.org/genproto/googleapis/rpc/errdetails" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" + coltracepb "go.opentelemetry.io/proto/otlp/collector/trace/v1" + tracepb "go.opentelemetry.io/proto/otlp/trace/v1" +) + +type client struct { + endpoint string + dialOpts []grpc.DialOption + metadata metadata.MD + exportTimeout time.Duration + requestFunc retry.RequestFunc + + // stopCtx is used as a parent context for all exports. Therefore, when it + // is canceled with the stopFunc all exports are canceled. + stopCtx context.Context + // stopFunc cancels stopCtx, stopping any active exports. + stopFunc context.CancelFunc + + // ourConn keeps track of where conn was created: true if created here on + // Start, or false if passed with an option. This is important on Shutdown + // as the conn should only be closed if created here on start. Otherwise, + // it is up to the processes that passed the conn to close it. + ourConn bool + conn *grpc.ClientConn + tscMu sync.RWMutex + tsc coltracepb.TraceServiceClient +} + +// Compile time check *client implements otlptrace.Client. +var _ otlptrace.Client = (*client)(nil) + +// NewClient creates a new gRPC trace client. +func NewClient(opts ...Option) otlptrace.Client { + return newClient(opts...) +} + +func newClient(opts ...Option) *client { + cfg := otlpconfig.NewGRPCConfig(asGRPCOptions(opts)...) + + ctx, cancel := context.WithCancel(context.Background()) + + c := &client{ + endpoint: cfg.Traces.Endpoint, + exportTimeout: cfg.Traces.Timeout, + requestFunc: cfg.RetryConfig.RequestFunc(retryable), + dialOpts: cfg.DialOptions, + stopCtx: ctx, + stopFunc: cancel, + conn: cfg.GRPCConn, + } + + if len(cfg.Traces.Headers) > 0 { + c.metadata = metadata.New(cfg.Traces.Headers) + } + + return c +} + +// Start establishes a gRPC connection to the collector. +func (c *client) Start(ctx context.Context) error { + if c.conn == nil { + // If the caller did not provide a ClientConn when the client was + // created, create one using the configuration they did provide. + conn, err := grpc.DialContext(ctx, c.endpoint, c.dialOpts...) + if err != nil { + return err + } + // Keep track that we own the lifecycle of this conn and need to close + // it on Shutdown. + c.ourConn = true + c.conn = conn + } + + // The otlptrace.Client interface states this method is called just once, + // so no need to check if already started. + c.tscMu.Lock() + c.tsc = coltracepb.NewTraceServiceClient(c.conn) + c.tscMu.Unlock() + + return nil +} + +var errAlreadyStopped = errors.New("the client is already stopped") + +// Stop shuts down the client. +// +// Any active connections to a remote endpoint are closed if they were created +// by the client. Any gRPC connection passed during creation using +// WithGRPCConn will not be closed. It is the caller's responsibility to +// handle cleanup of that resource. +// +// This method synchronizes with the UploadTraces method of the client. It +// will wait for any active calls to that method to complete unimpeded, or it +// will cancel any active calls if ctx expires. If ctx expires, the context +// error will be forwarded as the returned error. All client held resources +// will still be released in this situation. +// +// If the client has already stopped, an error will be returned describing +// this. +func (c *client) Stop(ctx context.Context) error { + // Make sure to return context error if the context is done when calling this method. + err := ctx.Err() + + // Acquire the c.tscMu lock within the ctx lifetime. + acquired := make(chan struct{}) + go func() { + c.tscMu.Lock() + close(acquired) + }() + + select { + case <-ctx.Done(): + // The Stop timeout is reached. Kill any remaining exports to force + // the clear of the lock and save the timeout error to return and + // signal the shutdown timed out before cleanly stopping. + c.stopFunc() + err = ctx.Err() + + // To ensure the client is not left in a dirty state c.tsc needs to be + // set to nil. To avoid the race condition when doing this, ensure + // that all the exports are killed (initiated by c.stopFunc). + <-acquired + case <-acquired: + } + // Hold the tscMu lock for the rest of the function to ensure no new + // exports are started. + defer c.tscMu.Unlock() + + // The otlptrace.Client interface states this method is called only + // once, but there is no guarantee it is called after Start. Ensure the + // client is started before doing anything and let the called know if they + // made a mistake. + if c.tsc == nil { + return errAlreadyStopped + } + + // Clear c.tsc to signal the client is stopped. + c.tsc = nil + + if c.ourConn { + closeErr := c.conn.Close() + // A context timeout error takes precedence over this error. + if err == nil && closeErr != nil { + err = closeErr + } + } + return err +} + +var errShutdown = errors.New("the client is shutdown") + +// UploadTraces sends a batch of spans. +// +// Retryable errors from the server will be handled according to any +// RetryConfig the client was created with. +func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error { + // Hold a read lock to ensure a shut down initiated after this starts does + // not abandon the export. This read lock acquire has less priority than a + // write lock acquire (i.e. Stop), meaning if the client is shutting down + // this will come after the shut down. + c.tscMu.RLock() + defer c.tscMu.RUnlock() + + if c.tsc == nil { + return errShutdown + } + + ctx, cancel := c.exportContext(ctx) + defer cancel() + + return c.requestFunc(ctx, func(iCtx context.Context) error { + resp, err := c.tsc.Export(iCtx, &coltracepb.ExportTraceServiceRequest{ + ResourceSpans: protoSpans, + }) + if resp != nil && resp.PartialSuccess != nil { + msg := resp.PartialSuccess.GetErrorMessage() + n := resp.PartialSuccess.GetRejectedSpans() + if n != 0 || msg != "" { + err := internal.TracePartialSuccessError(n, msg) + otel.Handle(err) + } + } + // nil is converted to OK. + if status.Code(err) == codes.OK { + // Success. + return nil + } + return err + }) +} + +// exportContext returns a copy of parent with an appropriate deadline and +// cancellation function. +// +// It is the callers responsibility to cancel the returned context once its +// use is complete, via the parent or directly with the returned CancelFunc, to +// ensure all resources are correctly released. +func (c *client) exportContext(parent context.Context) (context.Context, context.CancelFunc) { + var ( + ctx context.Context + cancel context.CancelFunc + ) + + if c.exportTimeout > 0 { + ctx, cancel = context.WithTimeout(parent, c.exportTimeout) + } else { + ctx, cancel = context.WithCancel(parent) + } + + if c.metadata.Len() > 0 { + ctx = metadata.NewOutgoingContext(ctx, c.metadata) + } + + // Unify the client stopCtx with the parent. + go func() { + select { + case <-ctx.Done(): + case <-c.stopCtx.Done(): + // Cancel the export as the shutdown has timed out. + cancel() + } + }() + + return ctx, cancel +} + +// retryable returns if err identifies a request that can be retried and a +// duration to wait for if an explicit throttle time is included in err. +func retryable(err error) (bool, time.Duration) { + s := status.Convert(err) + switch s.Code() { + case codes.Canceled, + codes.DeadlineExceeded, + codes.ResourceExhausted, + codes.Aborted, + codes.OutOfRange, + codes.Unavailable, + codes.DataLoss: + return true, throttleDelay(s) + } + + // Not a retry-able error. + return false, 0 +} + +// throttleDelay returns a duration to wait for if an explicit throttle time +// is included in the response status. +func throttleDelay(s *status.Status) time.Duration { + for _, detail := range s.Details() { + if t, ok := detail.(*errdetails.RetryInfo); ok { + return t.RetryDelay.AsDuration() + } + } + return 0 +} + +// MarshalLog is the marshaling function used by the logging system to represent this Client. +func (c *client) MarshalLog() interface{} { + return struct { + Type string + Endpoint string + }{ + Type: "otlphttpgrpc", + Endpoint: c.endpoint, + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go new file mode 100644 index 00000000000..89af41002f7 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + +import ( + "context" + + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +) + +// New constructs a new Exporter and starts it. +func New(ctx context.Context, opts ...Option) (*otlptrace.Exporter, error) { + return otlptrace.New(ctx, NewClient(opts...)) +} + +// NewUnstarted constructs a new Exporter and does not start it. +func NewUnstarted(opts ...Option) *otlptrace.Exporter { + return otlptrace.NewUnstarted(NewClient(opts...)) +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go new file mode 100644 index 00000000000..becb1f0fbbe --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go @@ -0,0 +1,202 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/envconfig/envconfig.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package envconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig" + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net/url" + "strconv" + "strings" + "time" + + "go.opentelemetry.io/otel/internal/global" +) + +// ConfigFn is the generic function used to set a config. +type ConfigFn func(*EnvOptionsReader) + +// EnvOptionsReader reads the required environment variables. +type EnvOptionsReader struct { + GetEnv func(string) string + ReadFile func(string) ([]byte, error) + Namespace string +} + +// Apply runs every ConfigFn. +func (e *EnvOptionsReader) Apply(opts ...ConfigFn) { + for _, o := range opts { + o(e) + } +} + +// GetEnvValue gets an OTLP environment variable value of the specified key +// using the GetEnv function. +// This function prepends the OTLP specified namespace to all key lookups. +func (e *EnvOptionsReader) GetEnvValue(key string) (string, bool) { + v := strings.TrimSpace(e.GetEnv(keyWithNamespace(e.Namespace, key))) + return v, v != "" +} + +// WithString retrieves the specified config and passes it to ConfigFn as a string. +func WithString(n string, fn func(string)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + fn(v) + } + } +} + +// WithBool returns a ConfigFn that reads the environment variable n and if it exists passes its parsed bool value to fn. +func WithBool(n string, fn func(bool)) ConfigFn { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + b := strings.ToLower(v) == "true" + fn(b) + } + } +} + +// WithDuration retrieves the specified config and passes it to ConfigFn as a duration. +func WithDuration(n string, fn func(time.Duration)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + d, err := strconv.Atoi(v) + if err != nil { + global.Error(err, "parse duration", "input", v) + return + } + fn(time.Duration(d) * time.Millisecond) + } + } +} + +// WithHeaders retrieves the specified config and passes it to ConfigFn as a map of HTTP headers. +func WithHeaders(n string, fn func(map[string]string)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + fn(stringToHeader(v)) + } + } +} + +// WithURL retrieves the specified config and passes it to ConfigFn as a net/url.URL. +func WithURL(n string, fn func(*url.URL)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + u, err := url.Parse(v) + if err != nil { + global.Error(err, "parse url", "input", v) + return + } + fn(u) + } + } +} + +// WithCertPool returns a ConfigFn that reads the environment variable n as a filepath to a TLS certificate pool. If it exists, it is parsed as a crypto/x509.CertPool and it is passed to fn. +func WithCertPool(n string, fn func(*x509.CertPool)) ConfigFn { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + b, err := e.ReadFile(v) + if err != nil { + global.Error(err, "read tls ca cert file", "file", v) + return + } + c, err := createCertPool(b) + if err != nil { + global.Error(err, "create tls cert pool") + return + } + fn(c) + } + } +} + +// WithClientCert returns a ConfigFn that reads the environment variable nc and nk as filepaths to a client certificate and key pair. If they exists, they are parsed as a crypto/tls.Certificate and it is passed to fn. +func WithClientCert(nc, nk string, fn func(tls.Certificate)) ConfigFn { + return func(e *EnvOptionsReader) { + vc, okc := e.GetEnvValue(nc) + vk, okk := e.GetEnvValue(nk) + if !okc || !okk { + return + } + cert, err := e.ReadFile(vc) + if err != nil { + global.Error(err, "read tls client cert", "file", vc) + return + } + key, err := e.ReadFile(vk) + if err != nil { + global.Error(err, "read tls client key", "file", vk) + return + } + crt, err := tls.X509KeyPair(cert, key) + if err != nil { + global.Error(err, "create tls client key pair") + return + } + fn(crt) + } +} + +func keyWithNamespace(ns, key string) string { + if ns == "" { + return key + } + return fmt.Sprintf("%s_%s", ns, key) +} + +func stringToHeader(value string) map[string]string { + headersPairs := strings.Split(value, ",") + headers := make(map[string]string) + + for _, header := range headersPairs { + n, v, found := strings.Cut(header, "=") + if !found { + global.Error(errors.New("missing '="), "parse headers", "input", header) + continue + } + name, err := url.QueryUnescape(n) + if err != nil { + global.Error(err, "escape header key", "key", n) + continue + } + trimmedName := strings.TrimSpace(name) + value, err := url.QueryUnescape(v) + if err != nil { + global.Error(err, "escape header value", "value", v) + continue + } + trimmedValue := strings.TrimSpace(value) + + headers[trimmedName] = trimmedValue + } + + return headers +} + +func createCertPool(certBytes []byte) (*x509.CertPool, error) { + cp := x509.NewCertPool() + if ok := cp.AppendCertsFromPEM(certBytes); !ok { + return nil, errors.New("failed to append certificate to the cert pool") + } + return cp, nil +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go new file mode 100644 index 00000000000..1fb29061894 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go @@ -0,0 +1,35 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" + +//go:generate gotmpl --body=../../../../../internal/shared/otlp/partialsuccess.go.tmpl "--data={}" --out=partialsuccess.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/partialsuccess_test.go.tmpl "--data={}" --out=partialsuccess_test.go + +//go:generate gotmpl --body=../../../../../internal/shared/otlp/retry/retry.go.tmpl "--data={}" --out=retry/retry.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/retry/retry_test.go.tmpl "--data={}" --out=retry/retry_test.go + +//go:generate gotmpl --body=../../../../../internal/shared/otlp/envconfig/envconfig.go.tmpl "--data={}" --out=envconfig/envconfig.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/envconfig/envconfig_test.go.tmpl "--data={}" --out=envconfig/envconfig_test.go + +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlpconfig/envconfig.go.tmpl "--data={\"envconfigImportPath\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig\"}" --out=otlpconfig/envconfig.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlpconfig/options.go.tmpl "--data={\"retryImportPath\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry\"}" --out=otlpconfig/options.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlpconfig/options_test.go.tmpl "--data={\"envconfigImportPath\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig\"}" --out=otlpconfig/options_test.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlpconfig/optiontypes.go.tmpl "--data={}" --out=otlpconfig/optiontypes.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlpconfig/tls.go.tmpl "--data={}" --out=otlpconfig/tls.go + +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlptracetest/client.go.tmpl "--data={}" --out=otlptracetest/client.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlptracetest/collector.go.tmpl "--data={}" --out=otlptracetest/collector.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlptracetest/data.go.tmpl "--data={}" --out=otlptracetest/data.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/otlptrace/otlptracetest/otlptest.go.tmpl "--data={}" --out=otlptracetest/otlptest.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go new file mode 100644 index 00000000000..32f6dddb4f6 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go @@ -0,0 +1,153 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/otlptrace/otlpconfig/envconfig.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + +import ( + "crypto/tls" + "crypto/x509" + "net/url" + "os" + "path" + "strings" + "time" + + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig" +) + +// DefaultEnvOptionsReader is the default environments reader. +var DefaultEnvOptionsReader = envconfig.EnvOptionsReader{ + GetEnv: os.Getenv, + ReadFile: os.ReadFile, + Namespace: "OTEL_EXPORTER_OTLP", +} + +// ApplyGRPCEnvConfigs applies the env configurations for gRPC. +func ApplyGRPCEnvConfigs(cfg Config) Config { + opts := getOptionsFromEnv() + for _, opt := range opts { + cfg = opt.ApplyGRPCOption(cfg) + } + return cfg +} + +// ApplyHTTPEnvConfigs applies the env configurations for HTTP. +func ApplyHTTPEnvConfigs(cfg Config) Config { + opts := getOptionsFromEnv() + for _, opt := range opts { + cfg = opt.ApplyHTTPOption(cfg) + } + return cfg +} + +func getOptionsFromEnv() []GenericOption { + opts := []GenericOption{} + + tlsConf := &tls.Config{} + DefaultEnvOptionsReader.Apply( + envconfig.WithURL("ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) + opts = append(opts, newSplitOption(func(cfg Config) Config { + cfg.Traces.Endpoint = u.Host + // For OTLP/HTTP endpoint URLs without a per-signal + // configuration, the passed endpoint is used as a base URL + // and the signals are sent to these paths relative to that. + cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) + return cfg + }, withEndpointForGRPC(u))) + }), + envconfig.WithURL("TRACES_ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) + opts = append(opts, newSplitOption(func(cfg Config) Config { + cfg.Traces.Endpoint = u.Host + // For endpoint URLs for OTLP/HTTP per-signal variables, the + // URL MUST be used as-is without any modification. The only + // exception is that if an URL contains no path part, the root + // path / MUST be used. + path := u.Path + if path == "" { + path = "/" + } + cfg.Traces.URLPath = path + return cfg + }, withEndpointForGRPC(u))) + }), + envconfig.WithCertPool("CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), + envconfig.WithCertPool("TRACES_CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), + envconfig.WithClientCert("CLIENT_CERTIFICATE", "CLIENT_KEY", func(c tls.Certificate) { tlsConf.Certificates = []tls.Certificate{c} }), + envconfig.WithClientCert("TRACES_CLIENT_CERTIFICATE", "TRACES_CLIENT_KEY", func(c tls.Certificate) { tlsConf.Certificates = []tls.Certificate{c} }), + withTLSConfig(tlsConf, func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }), + envconfig.WithBool("INSECURE", func(b bool) { opts = append(opts, withInsecure(b)) }), + envconfig.WithBool("TRACES_INSECURE", func(b bool) { opts = append(opts, withInsecure(b)) }), + envconfig.WithHeaders("HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + envconfig.WithHeaders("TRACES_HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + WithEnvCompression("COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + WithEnvCompression("TRACES_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + envconfig.WithDuration("TRACES_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + ) + + return opts +} + +func withEndpointScheme(u *url.URL) GenericOption { + switch strings.ToLower(u.Scheme) { + case "http", "unix": + return WithInsecure() + default: + return WithSecure() + } +} + +func withEndpointForGRPC(u *url.URL) func(cfg Config) Config { + return func(cfg Config) Config { + // For OTLP/gRPC endpoints, this is the target to which the + // exporter is going to send telemetry. + cfg.Traces.Endpoint = path.Join(u.Host, u.Path) + return cfg + } +} + +// WithEnvCompression retrieves the specified config and passes it to ConfigFn as a Compression. +func WithEnvCompression(n string, fn func(Compression)) func(e *envconfig.EnvOptionsReader) { + return func(e *envconfig.EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + cp := NoCompression + if v == "gzip" { + cp = GzipCompression + } + + fn(cp) + } + } +} + +// revive:disable-next-line:flag-parameter +func withInsecure(b bool) GenericOption { + if b { + return WithInsecure() + } + return WithSecure() +} + +func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOptionsReader) { + return func(e *envconfig.EnvOptionsReader) { + if c.RootCAs != nil || len(c.Certificates) > 0 { + fn(c) + } + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go new file mode 100644 index 00000000000..19b8434d4d2 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go @@ -0,0 +1,328 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/otlptrace/otlpconfig/options.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + +import ( + "crypto/tls" + "fmt" + "path" + "strings" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/backoff" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/encoding/gzip" + + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" +) + +const ( + // DefaultTracesPath is a default URL path for endpoint that + // receives spans. + DefaultTracesPath string = "/v1/traces" + // DefaultTimeout is a default max waiting time for the backend to process + // each span batch. + DefaultTimeout time.Duration = 10 * time.Second +) + +type ( + SignalConfig struct { + Endpoint string + Insecure bool + TLSCfg *tls.Config + Headers map[string]string + Compression Compression + Timeout time.Duration + URLPath string + + // gRPC configurations + GRPCCredentials credentials.TransportCredentials + } + + Config struct { + // Signal specific configurations + Traces SignalConfig + + RetryConfig retry.Config + + // gRPC configurations + ReconnectionPeriod time.Duration + ServiceConfig string + DialOptions []grpc.DialOption + GRPCConn *grpc.ClientConn + } +) + +// NewHTTPConfig returns a new Config with all settings applied from opts and +// any unset setting using the default HTTP config values. +func NewHTTPConfig(opts ...HTTPOption) Config { + cfg := Config{ + Traces: SignalConfig{ + Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorHTTPPort), + URLPath: DefaultTracesPath, + Compression: NoCompression, + Timeout: DefaultTimeout, + }, + RetryConfig: retry.DefaultConfig, + } + cfg = ApplyHTTPEnvConfigs(cfg) + for _, opt := range opts { + cfg = opt.ApplyHTTPOption(cfg) + } + cfg.Traces.URLPath = cleanPath(cfg.Traces.URLPath, DefaultTracesPath) + return cfg +} + +// cleanPath returns a path with all spaces trimmed and all redundancies +// removed. If urlPath is empty or cleaning it results in an empty string, +// defaultPath is returned instead. +func cleanPath(urlPath string, defaultPath string) string { + tmp := path.Clean(strings.TrimSpace(urlPath)) + if tmp == "." { + return defaultPath + } + if !path.IsAbs(tmp) { + tmp = fmt.Sprintf("/%s", tmp) + } + return tmp +} + +// NewGRPCConfig returns a new Config with all settings applied from opts and +// any unset setting using the default gRPC config values. +func NewGRPCConfig(opts ...GRPCOption) Config { + userAgent := "OTel OTLP Exporter Go/" + otlptrace.Version() + cfg := Config{ + Traces: SignalConfig{ + Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort), + URLPath: DefaultTracesPath, + Compression: NoCompression, + Timeout: DefaultTimeout, + }, + RetryConfig: retry.DefaultConfig, + DialOptions: []grpc.DialOption{grpc.WithUserAgent(userAgent)}, + } + cfg = ApplyGRPCEnvConfigs(cfg) + for _, opt := range opts { + cfg = opt.ApplyGRPCOption(cfg) + } + + if cfg.ServiceConfig != "" { + cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultServiceConfig(cfg.ServiceConfig)) + } + // Priroritize GRPCCredentials over Insecure (passing both is an error). + if cfg.Traces.GRPCCredentials != nil { + cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Traces.GRPCCredentials)) + } else if cfg.Traces.Insecure { + cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) + } else { + // Default to using the host's root CA. + creds := credentials.NewTLS(nil) + cfg.Traces.GRPCCredentials = creds + cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(creds)) + } + if cfg.Traces.Compression == GzipCompression { + cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name))) + } + if len(cfg.DialOptions) != 0 { + cfg.DialOptions = append(cfg.DialOptions, cfg.DialOptions...) + } + if cfg.ReconnectionPeriod != 0 { + p := grpc.ConnectParams{ + Backoff: backoff.DefaultConfig, + MinConnectTimeout: cfg.ReconnectionPeriod, + } + cfg.DialOptions = append(cfg.DialOptions, grpc.WithConnectParams(p)) + } + + return cfg +} + +type ( + // GenericOption applies an option to the HTTP or gRPC driver. + GenericOption interface { + ApplyHTTPOption(Config) Config + ApplyGRPCOption(Config) Config + + // A private method to prevent users implementing the + // interface and so future additions to it will not + // violate compatibility. + private() + } + + // HTTPOption applies an option to the HTTP driver. + HTTPOption interface { + ApplyHTTPOption(Config) Config + + // A private method to prevent users implementing the + // interface and so future additions to it will not + // violate compatibility. + private() + } + + // GRPCOption applies an option to the gRPC driver. + GRPCOption interface { + ApplyGRPCOption(Config) Config + + // A private method to prevent users implementing the + // interface and so future additions to it will not + // violate compatibility. + private() + } +) + +// genericOption is an option that applies the same logic +// for both gRPC and HTTP. +type genericOption struct { + fn func(Config) Config +} + +func (g *genericOption) ApplyGRPCOption(cfg Config) Config { + return g.fn(cfg) +} + +func (g *genericOption) ApplyHTTPOption(cfg Config) Config { + return g.fn(cfg) +} + +func (genericOption) private() {} + +func newGenericOption(fn func(cfg Config) Config) GenericOption { + return &genericOption{fn: fn} +} + +// splitOption is an option that applies different logics +// for gRPC and HTTP. +type splitOption struct { + httpFn func(Config) Config + grpcFn func(Config) Config +} + +func (g *splitOption) ApplyGRPCOption(cfg Config) Config { + return g.grpcFn(cfg) +} + +func (g *splitOption) ApplyHTTPOption(cfg Config) Config { + return g.httpFn(cfg) +} + +func (splitOption) private() {} + +func newSplitOption(httpFn func(cfg Config) Config, grpcFn func(cfg Config) Config) GenericOption { + return &splitOption{httpFn: httpFn, grpcFn: grpcFn} +} + +// httpOption is an option that is only applied to the HTTP driver. +type httpOption struct { + fn func(Config) Config +} + +func (h *httpOption) ApplyHTTPOption(cfg Config) Config { + return h.fn(cfg) +} + +func (httpOption) private() {} + +func NewHTTPOption(fn func(cfg Config) Config) HTTPOption { + return &httpOption{fn: fn} +} + +// grpcOption is an option that is only applied to the gRPC driver. +type grpcOption struct { + fn func(Config) Config +} + +func (h *grpcOption) ApplyGRPCOption(cfg Config) Config { + return h.fn(cfg) +} + +func (grpcOption) private() {} + +func NewGRPCOption(fn func(cfg Config) Config) GRPCOption { + return &grpcOption{fn: fn} +} + +// Generic Options + +func WithEndpoint(endpoint string) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Endpoint = endpoint + return cfg + }) +} + +func WithCompression(compression Compression) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Compression = compression + return cfg + }) +} + +func WithURLPath(urlPath string) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.URLPath = urlPath + return cfg + }) +} + +func WithRetry(rc retry.Config) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.RetryConfig = rc + return cfg + }) +} + +func WithTLSClientConfig(tlsCfg *tls.Config) GenericOption { + return newSplitOption(func(cfg Config) Config { + cfg.Traces.TLSCfg = tlsCfg.Clone() + return cfg + }, func(cfg Config) Config { + cfg.Traces.GRPCCredentials = credentials.NewTLS(tlsCfg) + return cfg + }) +} + +func WithInsecure() GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Insecure = true + return cfg + }) +} + +func WithSecure() GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Insecure = false + return cfg + }) +} + +func WithHeaders(headers map[string]string) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Headers = headers + return cfg + }) +} + +func WithTimeout(duration time.Duration) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Traces.Timeout = duration + return cfg + }) +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go new file mode 100644 index 00000000000..d9dcdc96e7d --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go @@ -0,0 +1,51 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/otlptrace/otlpconfig/optiontypes.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + +const ( + // DefaultCollectorGRPCPort is the default gRPC port of the collector. + DefaultCollectorGRPCPort uint16 = 4317 + // DefaultCollectorHTTPPort is the default HTTP port of the collector. + DefaultCollectorHTTPPort uint16 = 4318 + // DefaultCollectorHost is the host address the Exporter will attempt + // connect to if no collector address is provided. + DefaultCollectorHost string = "localhost" +) + +// Compression describes the compression used for payloads sent to the +// collector. +type Compression int + +const ( + // NoCompression tells the driver to send payloads without + // compression. + NoCompression Compression = iota + // GzipCompression tells the driver to send payloads after + // compressing them with gzip. + GzipCompression +) + +// Marshaler describes the kind of message format sent to the collector. +type Marshaler int + +const ( + // MarshalProto tells the driver to send using the protobuf binary format. + MarshalProto Marshaler = iota + // MarshalJSON tells the driver to send using json format. + MarshalJSON +) diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go new file mode 100644 index 00000000000..19b6d4b21f9 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go @@ -0,0 +1,37 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/otlptrace/otlpconfig/tls.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + +import ( + "crypto/tls" + "crypto/x509" + "errors" +) + +// CreateTLSConfig creates a tls.Config from a raw certificate bytes +// to verify a server certificate. +func CreateTLSConfig(certBytes []byte) (*tls.Config, error) { + cp := x509.NewCertPool() + if ok := cp.AppendCertsFromPEM(certBytes); !ok { + return nil, errors.New("failed to append certificate to the cert pool") + } + + return &tls.Config{ + RootCAs: cp, + }, nil +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go new file mode 100644 index 00000000000..076905e54bf --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go @@ -0,0 +1,67 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/partialsuccess.go + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" + +import "fmt" + +// PartialSuccess represents the underlying error for all handling +// OTLP partial success messages. Use `errors.Is(err, +// PartialSuccess{})` to test whether an error passed to the OTel +// error handler belongs to this category. +type PartialSuccess struct { + ErrorMessage string + RejectedItems int64 + RejectedKind string +} + +var _ error = PartialSuccess{} + +// Error implements the error interface. +func (ps PartialSuccess) Error() string { + msg := ps.ErrorMessage + if msg == "" { + msg = "empty message" + } + return fmt.Sprintf("OTLP partial success: %s (%d %s rejected)", msg, ps.RejectedItems, ps.RejectedKind) +} + +// Is supports the errors.Is() interface. +func (ps PartialSuccess) Is(err error) bool { + _, ok := err.(PartialSuccess) + return ok +} + +// TracePartialSuccessError returns an error describing a partial success +// response for the trace signal. +func TracePartialSuccessError(itemsRejected int64, errorMessage string) error { + return PartialSuccess{ + ErrorMessage: errorMessage, + RejectedItems: itemsRejected, + RejectedKind: "spans", + } +} + +// MetricPartialSuccessError returns an error describing a partial success +// response for the metric signal. +func MetricPartialSuccessError(itemsRejected int64, errorMessage string) error { + return PartialSuccess{ + ErrorMessage: errorMessage, + RejectedItems: itemsRejected, + RejectedKind: "metric data points", + } +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go new file mode 100644 index 00000000000..3ce7d6632b8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go @@ -0,0 +1,156 @@ +// Code created by gotmpl. DO NOT MODIFY. +// source: internal/shared/otlp/retry/retry.go.tmpl + +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package retry provides request retry functionality that can perform +// configurable exponential backoff for transient errors and honor any +// explicit throttle responses received. +package retry // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" + +import ( + "context" + "fmt" + "time" + + "github.com/cenkalti/backoff/v4" +) + +// DefaultConfig are the recommended defaults to use. +var DefaultConfig = Config{ + Enabled: true, + InitialInterval: 5 * time.Second, + MaxInterval: 30 * time.Second, + MaxElapsedTime: time.Minute, +} + +// Config defines configuration for retrying batches in case of export failure +// using an exponential backoff. +type Config struct { + // Enabled indicates whether to not retry sending batches in case of + // export failure. + Enabled bool + // InitialInterval the time to wait after the first failure before + // retrying. + InitialInterval time.Duration + // MaxInterval is the upper bound on backoff interval. Once this value is + // reached the delay between consecutive retries will always be + // `MaxInterval`. + MaxInterval time.Duration + // MaxElapsedTime is the maximum amount of time (including retries) spent + // trying to send a request/batch. Once this value is reached, the data + // is discarded. + MaxElapsedTime time.Duration +} + +// RequestFunc wraps a request with retry logic. +type RequestFunc func(context.Context, func(context.Context) error) error + +// EvaluateFunc returns if an error is retry-able and if an explicit throttle +// duration should be honored that was included in the error. +// +// The function must return true if the error argument is retry-able, +// otherwise it must return false for the first return parameter. +// +// The function must return a non-zero time.Duration if the error contains +// explicit throttle duration that should be honored, otherwise it must return +// a zero valued time.Duration. +type EvaluateFunc func(error) (bool, time.Duration) + +// RequestFunc returns a RequestFunc using the evaluate function to determine +// if requests can be retried and based on the exponential backoff +// configuration of c. +func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { + if !c.Enabled { + return func(ctx context.Context, fn func(context.Context) error) error { + return fn(ctx) + } + } + + return func(ctx context.Context, fn func(context.Context) error) error { + // Do not use NewExponentialBackOff since it calls Reset and the code here + // must call Reset after changing the InitialInterval (this saves an + // unnecessary call to Now). + b := &backoff.ExponentialBackOff{ + InitialInterval: c.InitialInterval, + RandomizationFactor: backoff.DefaultRandomizationFactor, + Multiplier: backoff.DefaultMultiplier, + MaxInterval: c.MaxInterval, + MaxElapsedTime: c.MaxElapsedTime, + Stop: backoff.Stop, + Clock: backoff.SystemClock, + } + b.Reset() + + for { + err := fn(ctx) + if err == nil { + return nil + } + + retryable, throttle := evaluate(err) + if !retryable { + return err + } + + bOff := b.NextBackOff() + if bOff == backoff.Stop { + return fmt.Errorf("max retry time elapsed: %w", err) + } + + // Wait for the greater of the backoff or throttle delay. + var delay time.Duration + if bOff > throttle { + delay = bOff + } else { + elapsed := b.GetElapsedTime() + if b.MaxElapsedTime != 0 && elapsed+throttle > b.MaxElapsedTime { + return fmt.Errorf("max retry time would elapse: %w", err) + } + delay = throttle + } + + if ctxErr := waitFunc(ctx, delay); ctxErr != nil { + return fmt.Errorf("%w: %s", ctxErr, err) + } + } + } +} + +// Allow override for testing. +var waitFunc = wait + +// wait takes the caller's context, and the amount of time to wait. It will +// return nil if the timer fires before or at the same time as the context's +// deadline. This indicates that the call can be retried. +func wait(ctx context.Context, delay time.Duration) error { + timer := time.NewTimer(delay) + defer timer.Stop() + + select { + case <-ctx.Done(): + // Handle the case where the timer and context deadline end + // simultaneously by prioritizing the timer expiration nil value + // response. + select { + case <-timer.C: + default: + return ctx.Err() + } + case <-timer.C: + } + + return nil +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go new file mode 100644 index 00000000000..78ce9ad8f0b --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go @@ -0,0 +1,189 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + +import ( + "fmt" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" +) + +// Option applies an option to the gRPC driver. +type Option interface { + applyGRPCOption(otlpconfig.Config) otlpconfig.Config +} + +func asGRPCOptions(opts []Option) []otlpconfig.GRPCOption { + converted := make([]otlpconfig.GRPCOption, len(opts)) + for i, o := range opts { + converted[i] = otlpconfig.NewGRPCOption(o.applyGRPCOption) + } + return converted +} + +// RetryConfig defines configuration for retrying export of span batches that +// failed to be received by the target endpoint. +// +// This configuration does not define any network retry strategy. That is +// entirely handled by the gRPC ClientConn. +type RetryConfig retry.Config + +type wrappedOption struct { + otlpconfig.GRPCOption +} + +func (w wrappedOption) applyGRPCOption(cfg otlpconfig.Config) otlpconfig.Config { + return w.ApplyGRPCOption(cfg) +} + +// WithInsecure disables client transport security for the exporter's gRPC +// connection just like grpc.WithInsecure() +// (https://pkg.go.dev/google.golang.org/grpc#WithInsecure) does. Note, by +// default, client security is required unless WithInsecure is used. +// +// This option has no effect if WithGRPCConn is used. +func WithInsecure() Option { + return wrappedOption{otlpconfig.WithInsecure()} +} + +// WithEndpoint sets the target endpoint the exporter will connect to. If +// unset, localhost:4317 will be used as a default. +// +// This option has no effect if WithGRPCConn is used. +func WithEndpoint(endpoint string) Option { + return wrappedOption{otlpconfig.WithEndpoint(endpoint)} +} + +// WithReconnectionPeriod set the minimum amount of time between connection +// attempts to the target endpoint. +// +// This option has no effect if WithGRPCConn is used. +func WithReconnectionPeriod(rp time.Duration) Option { + return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { + cfg.ReconnectionPeriod = rp + return cfg + })} +} + +func compressorToCompression(compressor string) otlpconfig.Compression { + if compressor == "gzip" { + return otlpconfig.GzipCompression + } + + otel.Handle(fmt.Errorf("invalid compression type: '%s', using no compression as default", compressor)) + return otlpconfig.NoCompression +} + +// WithCompressor sets the compressor for the gRPC client to use when sending +// requests. It is the responsibility of the caller to ensure that the +// compressor set has been registered with google.golang.org/grpc/encoding. +// This can be done by encoding.RegisterCompressor. Some compressors +// auto-register on import, such as gzip, which can be registered by calling +// `import _ "google.golang.org/grpc/encoding/gzip"`. +// +// This option has no effect if WithGRPCConn is used. +func WithCompressor(compressor string) Option { + return wrappedOption{otlpconfig.WithCompression(compressorToCompression(compressor))} +} + +// WithHeaders will send the provided headers with each gRPC requests. +func WithHeaders(headers map[string]string) Option { + return wrappedOption{otlpconfig.WithHeaders(headers)} +} + +// WithTLSCredentials allows the connection to use TLS credentials when +// talking to the server. It takes in grpc.TransportCredentials instead of say +// a Certificate file or a tls.Certificate, because the retrieving of these +// credentials can be done in many ways e.g. plain file, in code tls.Config or +// by certificate rotation, so it is up to the caller to decide what to use. +// +// This option has no effect if WithGRPCConn is used. +func WithTLSCredentials(creds credentials.TransportCredentials) Option { + return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { + cfg.Traces.GRPCCredentials = creds + return cfg + })} +} + +// WithServiceConfig defines the default gRPC service config used. +// +// This option has no effect if WithGRPCConn is used. +func WithServiceConfig(serviceConfig string) Option { + return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { + cfg.ServiceConfig = serviceConfig + return cfg + })} +} + +// WithDialOption sets explicit grpc.DialOptions to use when making a +// connection. The options here are appended to the internal grpc.DialOptions +// used so they will take precedence over any other internal grpc.DialOptions +// they might conflict with. +// +// This option has no effect if WithGRPCConn is used. +func WithDialOption(opts ...grpc.DialOption) Option { + return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { + cfg.DialOptions = opts + return cfg + })} +} + +// WithGRPCConn sets conn as the gRPC ClientConn used for all communication. +// +// This option takes precedence over any other option that relates to +// establishing or persisting a gRPC connection to a target endpoint. Any +// other option of those types passed will be ignored. +// +// It is the callers responsibility to close the passed conn. The client +// Shutdown method will not close this connection. +func WithGRPCConn(conn *grpc.ClientConn) Option { + return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { + cfg.GRPCConn = conn + return cfg + })} +} + +// WithTimeout sets the max amount of time a client will attempt to export a +// batch of spans. This takes precedence over any retry settings defined with +// WithRetry, once this time limit has been reached the export is abandoned +// and the batch of spans is dropped. +// +// If unset, the default timeout will be set to 10 seconds. +func WithTimeout(duration time.Duration) Option { + return wrappedOption{otlpconfig.WithTimeout(duration)} +} + +// WithRetry sets the retry policy for transient retryable errors that may be +// returned by the target endpoint when exporting a batch of spans. +// +// If the target endpoint responds with not only a retryable error, but +// explicitly returns a backoff time in the response. That time will take +// precedence over these settings. +// +// These settings do not define any network retry strategy. That is entirely +// handled by the gRPC ClientConn. +// +// If unset, the default retry policy will be used. It will retry the export +// 5 seconds after receiving a retryable error and increase exponentially +// after each error for no more than a total time of 1 minute. +func WithRetry(settings RetryConfig) Option { + return wrappedOption{otlpconfig.WithRetry(retry.Config(settings))} +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go new file mode 100644 index 00000000000..10ac73ee3b8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + +// Version is the current release version of the OpenTelemetry OTLP trace exporter in use. +func Version() string { + return "1.19.0" +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/protocoldriver.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/protocoldriver.go deleted file mode 100644 index 7c45cefb9fd..00000000000 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/protocoldriver.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otlp // import "go.opentelemetry.io/otel/exporters/otlp" - -import ( - "context" - "sync" - - metricsdk "go.opentelemetry.io/otel/sdk/export/metric" - tracesdk "go.opentelemetry.io/otel/sdk/trace" -) - -// ProtocolDriver is an interface used by OTLP exporter. It's -// responsible for connecting to and disconnecting from the collector, -// and for transforming traces and metrics into wire format and -// transmitting them to the collector. -type ProtocolDriver interface { - // Start should establish connection(s) to endpoint(s). It is - // called just once by the exporter, so the implementation - // does not need to worry about idempotence and locking. - Start(ctx context.Context) error - // Stop should close the connections. The function is called - // only once by the exporter, so the implementation does not - // need to worry about idempotence, but it may be called - // concurrently with ExportMetrics or ExportTraces, so proper - // locking is required. The function serves as a - // synchronization point - after the function returns, the - // process of closing connections is assumed to be finished. - Stop(ctx context.Context) error - // ExportMetrics should transform the passed metrics to the - // wire format and send it to the collector. May be called - // concurrently with ExportTraces, so the manager needs to - // take this into account by doing proper locking. - ExportMetrics(ctx context.Context, cps metricsdk.CheckpointSet, selector metricsdk.ExportKindSelector) error - // ExportTraces should transform the passed traces to the wire - // format and send it to the collector. May be called - // concurrently with ExportMetrics, so the manager needs to - // take this into account by doing proper locking. - ExportTraces(ctx context.Context, ss []*tracesdk.SpanSnapshot) error -} - -// SplitConfig is used to configure a split driver. -type SplitConfig struct { - // ForMetrics driver will be used for sending metrics to the - // collector. - ForMetrics ProtocolDriver - // ForTraces driver will be used for sending spans to the - // collector. - ForTraces ProtocolDriver -} - -type splitDriver struct { - metric ProtocolDriver - trace ProtocolDriver -} - -var _ ProtocolDriver = (*splitDriver)(nil) - -// NewSplitDriver creates a protocol driver which contains two other -// protocol drivers and will forward traces to one of them and metrics -// to another. -func NewSplitDriver(cfg SplitConfig) ProtocolDriver { - return &splitDriver{ - metric: cfg.ForMetrics, - trace: cfg.ForTraces, - } -} - -// Start implements ProtocolDriver. It starts both drivers at the same -// time. -func (d *splitDriver) Start(ctx context.Context) error { - wg := sync.WaitGroup{} - wg.Add(2) - var ( - metricErr error - traceErr error - ) - go func() { - defer wg.Done() - metricErr = d.metric.Start(ctx) - }() - go func() { - defer wg.Done() - traceErr = d.trace.Start(ctx) - }() - wg.Wait() - if metricErr != nil { - return metricErr - } - if traceErr != nil { - return traceErr - } - return nil -} - -// Stop implements ProtocolDriver. It stops both drivers at the same -// time. -func (d *splitDriver) Stop(ctx context.Context) error { - wg := sync.WaitGroup{} - wg.Add(2) - var ( - metricErr error - traceErr error - ) - go func() { - defer wg.Done() - metricErr = d.metric.Stop(ctx) - }() - go func() { - defer wg.Done() - traceErr = d.trace.Stop(ctx) - }() - wg.Wait() - if metricErr != nil { - return metricErr - } - if traceErr != nil { - return traceErr - } - return nil -} - -// ExportMetrics implements ProtocolDriver. It forwards the call to -// the driver used for sending metrics. -func (d *splitDriver) ExportMetrics(ctx context.Context, cps metricsdk.CheckpointSet, selector metricsdk.ExportKindSelector) error { - return d.metric.ExportMetrics(ctx, cps, selector) -} - -// ExportTraces implements ProtocolDriver. It forwards the call to the -// driver used for sending spans. -func (d *splitDriver) ExportTraces(ctx context.Context, ss []*tracesdk.SpanSnapshot) error { - return d.trace.ExportTraces(ctx, ss) -} diff --git a/vendor/go.opentelemetry.io/otel/handler.go b/vendor/go.opentelemetry.io/otel/handler.go index 27e1caa30d9..4115fe3bbb5 100644 --- a/vendor/go.opentelemetry.io/otel/handler.go +++ b/vendor/go.opentelemetry.io/otel/handler.go @@ -15,75 +15,34 @@ package otel // import "go.opentelemetry.io/otel" import ( - "log" - "os" - "sync" - "sync/atomic" + "go.opentelemetry.io/otel/internal/global" ) var ( - // globalErrorHandler provides an ErrorHandler that can be used - // throughout an OpenTelemetry instrumented project. When a user - // specified ErrorHandler is registered (`SetErrorHandler`) all calls to - // `Handle` and will be delegated to the registered ErrorHandler. - globalErrorHandler = &loggingErrorHandler{ - l: log.New(os.Stderr, "", log.LstdFlags), - } - - // delegateErrorHandlerOnce ensures that a user provided ErrorHandler is - // only ever registered once. - delegateErrorHandlerOnce sync.Once - - // Comiple time check that loggingErrorHandler implements ErrorHandler. - _ ErrorHandler = (*loggingErrorHandler)(nil) + // Compile-time check global.ErrDelegator implements ErrorHandler. + _ ErrorHandler = (*global.ErrDelegator)(nil) + // Compile-time check global.ErrLogger implements ErrorHandler. + _ ErrorHandler = (*global.ErrLogger)(nil) ) -// loggingErrorHandler logs all errors to STDERR. -type loggingErrorHandler struct { - delegate atomic.Value - - l *log.Logger -} - -// setDelegate sets the ErrorHandler delegate if one is not already set. -func (h *loggingErrorHandler) setDelegate(d ErrorHandler) { - if h.delegate.Load() != nil { - // Delegate already registered - return - } - h.delegate.Store(d) -} - -// Handle implements ErrorHandler. -func (h *loggingErrorHandler) Handle(err error) { - if d := h.delegate.Load(); d != nil { - d.(ErrorHandler).Handle(err) - return - } - h.l.Print(err) -} - -// GetErrorHandler returns the global ErrorHandler instance. If no ErrorHandler -// instance has been set (`SetErrorHandler`), the default ErrorHandler which -// logs errors to STDERR is returned. -func GetErrorHandler() ErrorHandler { - return globalErrorHandler -} - -// SetErrorHandler sets the global ErrorHandler to be h. -func SetErrorHandler(h ErrorHandler) { - delegateErrorHandlerOnce.Do(func() { - current := GetErrorHandler() - if current == h { - return - } - if internalHandler, ok := current.(*loggingErrorHandler); ok { - internalHandler.setDelegate(h) - } - }) -} +// GetErrorHandler returns the global ErrorHandler instance. +// +// The default ErrorHandler instance returned will log all errors to STDERR +// until an override ErrorHandler is set with SetErrorHandler. All +// ErrorHandler returned prior to this will automatically forward errors to +// the set instance instead of logging. +// +// Subsequent calls to SetErrorHandler after the first will not forward errors +// to the new ErrorHandler for prior returned instances. +func GetErrorHandler() ErrorHandler { return global.GetErrorHandler() } -// Handle is a convience function for ErrorHandler().Handle(err) -func Handle(err error) { - GetErrorHandler().Handle(err) -} +// SetErrorHandler sets the global ErrorHandler to h. +// +// The first time this is called all ErrorHandler previously returned from +// GetErrorHandler will send errors to h instead of the default logging +// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not +// delegate errors to h. +func SetErrorHandler(h ErrorHandler) { global.SetErrorHandler(h) } + +// Handle is a convenience function for ErrorHandler().Handle(err). +func Handle(err error) { global.Handle(err) } diff --git a/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go b/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go new file mode 100644 index 00000000000..622c3ee3f27 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go @@ -0,0 +1,111 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package attribute provide several helper functions for some commonly used +logic of processing attributes. +*/ +package attribute // import "go.opentelemetry.io/otel/internal/attribute" + +import ( + "reflect" +) + +// BoolSliceValue converts a bool slice into an array with same elements as slice. +func BoolSliceValue(v []bool) interface{} { + var zero bool + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))) + copy(cp.Elem().Slice(0, len(v)).Interface().([]bool), v) + return cp.Elem().Interface() +} + +// Int64SliceValue converts an int64 slice into an array with same elements as slice. +func Int64SliceValue(v []int64) interface{} { + var zero int64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))) + copy(cp.Elem().Slice(0, len(v)).Interface().([]int64), v) + return cp.Elem().Interface() +} + +// Float64SliceValue converts a float64 slice into an array with same elements as slice. +func Float64SliceValue(v []float64) interface{} { + var zero float64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))) + copy(cp.Elem().Slice(0, len(v)).Interface().([]float64), v) + return cp.Elem().Interface() +} + +// StringSliceValue converts a string slice into an array with same elements as slice. +func StringSliceValue(v []string) interface{} { + var zero string + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))) + copy(cp.Elem().Slice(0, len(v)).Interface().([]string), v) + return cp.Elem().Interface() +} + +// AsBoolSlice converts a bool array into a slice into with same elements as array. +func AsBoolSlice(v interface{}) []bool { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + var zero bool + correctLen := rv.Len() + correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero)) + cpy := reflect.New(correctType) + _ = reflect.Copy(cpy.Elem(), rv) + return cpy.Elem().Slice(0, correctLen).Interface().([]bool) +} + +// AsInt64Slice converts an int64 array into a slice into with same elements as array. +func AsInt64Slice(v interface{}) []int64 { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + var zero int64 + correctLen := rv.Len() + correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero)) + cpy := reflect.New(correctType) + _ = reflect.Copy(cpy.Elem(), rv) + return cpy.Elem().Slice(0, correctLen).Interface().([]int64) +} + +// AsFloat64Slice converts a float64 array into a slice into with same elements as array. +func AsFloat64Slice(v interface{}) []float64 { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + var zero float64 + correctLen := rv.Len() + correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero)) + cpy := reflect.New(correctType) + _ = reflect.Copy(cpy.Elem(), rv) + return cpy.Elem().Slice(0, correctLen).Interface().([]float64) +} + +// AsStringSlice converts a string array into a slice into with same elements as array. +func AsStringSlice(v interface{}) []string { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + var zero string + correctLen := rv.Len() + correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero)) + cpy := reflect.New(correctType) + _ = reflect.Copy(cpy.Elem(), rv) + return cpy.Elem().Slice(0, correctLen).Interface().([]string) +} diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go index b1f7daf8d86..b96e5408e69 100644 --- a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go @@ -12,327 +12,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package baggage provides types and functions to manage W3C Baggage. -package baggage - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" -) - -type rawMap map[attribute.Key]attribute.Value -type keySet map[attribute.Key]struct{} - -// Map is an immutable storage for correlations. -type Map struct { - m rawMap -} - -// MapUpdate contains information about correlation changes to be -// made. -type MapUpdate struct { - // DropSingleK contains a single key to be dropped from - // correlations. Use this to avoid an overhead of a slice - // allocation if there is only one key to drop. - DropSingleK attribute.Key - // DropMultiK contains all the keys to be dropped from - // correlations. - DropMultiK []attribute.Key - - // SingleKV contains a single key-value pair to be added to - // correlations. Use this to avoid an overhead of a slice - // allocation if there is only one key-value pair to add. - SingleKV attribute.KeyValue - // MultiKV contains all the key-value pairs to be added to - // correlations. - MultiKV []attribute.KeyValue -} - -func newMap(raw rawMap) Map { - return Map{ - m: raw, - } -} - -// NewEmptyMap creates an empty correlations map. -func NewEmptyMap() Map { - return newMap(nil) -} - -// NewMap creates a map with the contents of the update applied. In -// this function, having an update with DropSingleK or DropMultiK -// makes no sense - those fields are effectively ignored. -func NewMap(update MapUpdate) Map { - return NewEmptyMap().Apply(update) -} - -// Apply creates a copy of the map with the contents of the update -// applied. Apply will first drop the keys from DropSingleK and -// DropMultiK, then add key-value pairs from SingleKV and MultiKV. -func (m Map) Apply(update MapUpdate) Map { - delSet, addSet := getModificationSets(update) - mapSize := getNewMapSize(m.m, delSet, addSet) - - r := make(rawMap, mapSize) - for k, v := range m.m { - // do not copy items we want to drop - if _, ok := delSet[k]; ok { - continue - } - // do not copy items we would overwrite - if _, ok := addSet[k]; ok { - continue - } - r[k] = v - } - if update.SingleKV.Key.Defined() { - r[update.SingleKV.Key] = update.SingleKV.Value - } - for _, kv := range update.MultiKV { - r[kv.Key] = kv.Value - } - if len(r) == 0 { - r = nil - } - return newMap(r) -} - -func getModificationSets(update MapUpdate) (delSet, addSet keySet) { - deletionsCount := len(update.DropMultiK) - if update.DropSingleK.Defined() { - deletionsCount++ - } - if deletionsCount > 0 { - delSet = make(map[attribute.Key]struct{}, deletionsCount) - for _, k := range update.DropMultiK { - delSet[k] = struct{}{} - } - if update.DropSingleK.Defined() { - delSet[update.DropSingleK] = struct{}{} - } - } - - additionsCount := len(update.MultiKV) - if update.SingleKV.Key.Defined() { - additionsCount++ - } - if additionsCount > 0 { - addSet = make(map[attribute.Key]struct{}, additionsCount) - for _, k := range update.MultiKV { - addSet[k.Key] = struct{}{} - } - if update.SingleKV.Key.Defined() { - addSet[update.SingleKV.Key] = struct{}{} - } - } - - return -} - -func getNewMapSize(m rawMap, delSet, addSet keySet) int { - mapSizeDiff := 0 - for k := range addSet { - if _, ok := m[k]; !ok { - mapSizeDiff++ - } - } - for k := range delSet { - if _, ok := m[k]; ok { - if _, inAddSet := addSet[k]; !inAddSet { - mapSizeDiff-- - } - } - } - return len(m) + mapSizeDiff -} - -// Value gets a value from correlations map and returns a boolean -// value indicating whether the key exist in the map. -func (m Map) Value(k attribute.Key) (attribute.Value, bool) { - value, ok := m.m[k] - return value, ok -} - -// HasValue returns a boolean value indicating whether the key exist -// in the map. -func (m Map) HasValue(k attribute.Key) bool { - _, has := m.Value(k) - return has -} - -// Len returns a length of the map. -func (m Map) Len() int { - return len(m.m) -} - -// Foreach calls a passed callback once on each key-value pair until -// all the key-value pairs of the map were iterated or the callback -// returns false, whichever happens first. -func (m Map) Foreach(f func(attribute.KeyValue) bool) { - for k, v := range m.m { - if !f(attribute.KeyValue{ - Key: k, - Value: v, - }) { - return - } - } -} - -type correlationsType struct{} - -// SetHookFunc describes a type of a callback that is called when -// storing baggage in the context. -type SetHookFunc func(context.Context) context.Context - -// GetHookFunc describes a type of a callback that is called when -// getting baggage from the context. -type GetHookFunc func(context.Context, Map) Map - -// value under this key is either of type Map or correlationsData -var correlationsKey = &correlationsType{} - -type correlationsData struct { - m Map - setHook SetHookFunc - getHook GetHookFunc -} - -func (d correlationsData) isHookless() bool { - return d.setHook == nil && d.getHook == nil -} - -type hookKind int - -const ( - hookKindSet hookKind = iota - hookKindGet -) - -func (d *correlationsData) overrideHook(kind hookKind, setHook SetHookFunc, getHook GetHookFunc) { - switch kind { - case hookKindSet: - d.setHook = setHook - case hookKindGet: - d.getHook = getHook - } -} - -// ContextWithSetHook installs a hook function that will be invoked -// every time ContextWithMap is called. To avoid unnecessary callback -// invocations (recursive or not), the callback can temporarily clear -// the hooks from the context with the ContextWithNoHooks function. -// -// Note that NewContext also calls ContextWithMap, so the hook will be -// invoked. -// -// Passing nil SetHookFunc creates a context with no set hook to call. -// -// This function should not be used by applications or libraries. It -// is mostly for interoperation with other observability APIs. -func ContextWithSetHook(ctx context.Context, hook SetHookFunc) context.Context { - return contextWithHook(ctx, hookKindSet, hook, nil) -} - -// ContextWithGetHook installs a hook function that will be invoked -// every time MapFromContext is called. To avoid unnecessary callback -// invocations (recursive or not), the callback can temporarily clear -// the hooks from the context with the ContextWithNoHooks function. -// -// Note that NewContext also calls MapFromContext, so the hook will be -// invoked. -// -// Passing nil GetHookFunc creates a context with no get hook to call. -// -// This function should not be used by applications or libraries. It -// is mostly for interoperation with other observability APIs. -func ContextWithGetHook(ctx context.Context, hook GetHookFunc) context.Context { - return contextWithHook(ctx, hookKindGet, nil, hook) -} - -func contextWithHook(ctx context.Context, kind hookKind, setHook SetHookFunc, getHook GetHookFunc) context.Context { - switch v := ctx.Value(correlationsKey).(type) { - case correlationsData: - v.overrideHook(kind, setHook, getHook) - if v.isHookless() { - return context.WithValue(ctx, correlationsKey, v.m) - } - return context.WithValue(ctx, correlationsKey, v) - case Map: - return contextWithOneHookAndMap(ctx, kind, setHook, getHook, v) - default: - m := NewEmptyMap() - return contextWithOneHookAndMap(ctx, kind, setHook, getHook, m) - } -} - -func contextWithOneHookAndMap(ctx context.Context, kind hookKind, setHook SetHookFunc, getHook GetHookFunc, m Map) context.Context { - d := correlationsData{m: m} - d.overrideHook(kind, setHook, getHook) - if d.isHookless() { - return ctx - } - return context.WithValue(ctx, correlationsKey, d) -} - -// ContextWithNoHooks creates a context with all the hooks -// disabled. Also returns old set and get hooks. This function can be -// used to temporarily clear the context from hooks and then reinstate -// them by calling ContextWithSetHook and ContextWithGetHook functions -// passing the hooks returned by this function. -// -// This function should not be used by applications or libraries. It -// is mostly for interoperation with other observability APIs. -func ContextWithNoHooks(ctx context.Context) (context.Context, SetHookFunc, GetHookFunc) { - switch v := ctx.Value(correlationsKey).(type) { - case correlationsData: - return context.WithValue(ctx, correlationsKey, v.m), v.setHook, v.getHook - default: - return ctx, nil, nil - } -} - -// ContextWithMap returns a context with the Map entered into it. -func ContextWithMap(ctx context.Context, m Map) context.Context { - switch v := ctx.Value(correlationsKey).(type) { - case correlationsData: - v.m = m - ctx = context.WithValue(ctx, correlationsKey, v) - if v.setHook != nil { - ctx = v.setHook(ctx) - } - return ctx - default: - return context.WithValue(ctx, correlationsKey, m) - } -} - -// ContextWithNoCorrelationData returns a context stripped of correlation -// data. -func ContextWithNoCorrelationData(ctx context.Context) context.Context { - return context.WithValue(ctx, correlationsKey, nil) -} - -// NewContext returns a context with the map from passed context -// updated with the passed key-value pairs. -func NewContext(ctx context.Context, keyvalues ...attribute.KeyValue) context.Context { - return ContextWithMap(ctx, MapFromContext(ctx).Apply(MapUpdate{ - MultiKV: keyvalues, - })) -} - -// MapFromContext gets the current Map from a Context. -func MapFromContext(ctx context.Context) Map { - switch v := ctx.Value(correlationsKey).(type) { - case correlationsData: - if v.getHook != nil { - return v.getHook(ctx, v.m) - } - return v.m - case Map: - return v - default: - return NewEmptyMap() - } +/* +Package baggage provides base types and functionality to store and retrieve +baggage in Go context. This package exists because the OpenTracing bridge to +OpenTelemetry needs to synchronize state whenever baggage for a context is +modified and that context contains an OpenTracing span. If it were not for +this need this package would not need to exist and the +`go.opentelemetry.io/otel/baggage` package would be the singular place where +W3C baggage is handled. +*/ +package baggage // import "go.opentelemetry.io/otel/internal/baggage" + +// List is the collection of baggage members. The W3C allows for duplicates, +// but OpenTelemetry does not, therefore, this is represented as a map. +type List map[string]Item + +// Item is the value and metadata properties part of a list-member. +type Item struct { + Value string + Properties []Property +} + +// Property is a metadata entry for a list-member. +type Property struct { + Key, Value string + + // HasValue indicates if a zero-value value means the property does not + // have a value or if it was the zero-value. + HasValue bool } diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go new file mode 100644 index 00000000000..4469700d9cb --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go @@ -0,0 +1,92 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package baggage // import "go.opentelemetry.io/otel/internal/baggage" + +import "context" + +type baggageContextKeyType int + +const baggageKey baggageContextKeyType = iota + +// SetHookFunc is a callback called when storing baggage in the context. +type SetHookFunc func(context.Context, List) context.Context + +// GetHookFunc is a callback called when getting baggage from the context. +type GetHookFunc func(context.Context, List) List + +type baggageState struct { + list List + + setHook SetHookFunc + getHook GetHookFunc +} + +// ContextWithSetHook returns a copy of parent with hook configured to be +// invoked every time ContextWithBaggage is called. +// +// Passing nil SetHookFunc creates a context with no set hook to call. +func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context { + var s baggageState + if v, ok := parent.Value(baggageKey).(baggageState); ok { + s = v + } + + s.setHook = hook + return context.WithValue(parent, baggageKey, s) +} + +// ContextWithGetHook returns a copy of parent with hook configured to be +// invoked every time FromContext is called. +// +// Passing nil GetHookFunc creates a context with no get hook to call. +func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context { + var s baggageState + if v, ok := parent.Value(baggageKey).(baggageState); ok { + s = v + } + + s.getHook = hook + return context.WithValue(parent, baggageKey, s) +} + +// ContextWithList returns a copy of parent with baggage. Passing nil list +// returns a context without any baggage. +func ContextWithList(parent context.Context, list List) context.Context { + var s baggageState + if v, ok := parent.Value(baggageKey).(baggageState); ok { + s = v + } + + s.list = list + ctx := context.WithValue(parent, baggageKey, s) + if s.setHook != nil { + ctx = s.setHook(ctx, list) + } + + return ctx +} + +// ListFromContext returns the baggage contained in ctx. +func ListFromContext(ctx context.Context) List { + switch v := ctx.Value(baggageKey).(type) { + case baggageState: + if v.getHook != nil { + return v.getHook(ctx, v.list) + } + return v.list + default: + return nil + } +} diff --git a/vendor/go.opentelemetry.io/otel/internal/gen.go b/vendor/go.opentelemetry.io/otel/internal/gen.go new file mode 100644 index 00000000000..f532f07e9e5 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/gen.go @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/internal" + +//go:generate gotmpl --body=./shared/matchers/expectation.go.tmpl "--data={}" --out=matchers/expectation.go +//go:generate gotmpl --body=./shared/matchers/expecter.go.tmpl "--data={}" --out=matchers/expecter.go +//go:generate gotmpl --body=./shared/matchers/temporal_matcher.go.tmpl "--data={}" --out=matchers/temporal_matcher.go + +//go:generate gotmpl --body=./shared/internaltest/alignment.go.tmpl "--data={}" --out=internaltest/alignment.go +//go:generate gotmpl --body=./shared/internaltest/env.go.tmpl "--data={}" --out=internaltest/env.go +//go:generate gotmpl --body=./shared/internaltest/env_test.go.tmpl "--data={}" --out=internaltest/env_test.go +//go:generate gotmpl --body=./shared/internaltest/errors.go.tmpl "--data={}" --out=internaltest/errors.go +//go:generate gotmpl --body=./shared/internaltest/harness.go.tmpl "--data={\"matchersImportPath\": \"go.opentelemetry.io/otel/internal/matchers\"}" --out=internaltest/harness.go +//go:generate gotmpl --body=./shared/internaltest/text_map_carrier.go.tmpl "--data={}" --out=internaltest/text_map_carrier.go +//go:generate gotmpl --body=./shared/internaltest/text_map_carrier_test.go.tmpl "--data={}" --out=internaltest/text_map_carrier_test.go +//go:generate gotmpl --body=./shared/internaltest/text_map_propagator.go.tmpl "--data={}" --out=internaltest/text_map_propagator.go +//go:generate gotmpl --body=./shared/internaltest/text_map_propagator_test.go.tmpl "--data={}" --out=internaltest/text_map_propagator_test.go diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go new file mode 100644 index 00000000000..5e9b8304792 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go @@ -0,0 +1,102 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/internal/global" + +import ( + "log" + "os" + "sync/atomic" +) + +var ( + // GlobalErrorHandler provides an ErrorHandler that can be used + // throughout an OpenTelemetry instrumented project. When a user + // specified ErrorHandler is registered (`SetErrorHandler`) all calls to + // `Handle` and will be delegated to the registered ErrorHandler. + GlobalErrorHandler = defaultErrorHandler() + + // Compile-time check that delegator implements ErrorHandler. + _ ErrorHandler = (*ErrDelegator)(nil) + // Compile-time check that errLogger implements ErrorHandler. + _ ErrorHandler = (*ErrLogger)(nil) +) + +// ErrorHandler handles irremediable events. +type ErrorHandler interface { + // Handle handles any error deemed irremediable by an OpenTelemetry + // component. + Handle(error) +} + +type ErrDelegator struct { + delegate atomic.Pointer[ErrorHandler] +} + +func (d *ErrDelegator) Handle(err error) { + d.getDelegate().Handle(err) +} + +func (d *ErrDelegator) getDelegate() ErrorHandler { + return *d.delegate.Load() +} + +// setDelegate sets the ErrorHandler delegate. +func (d *ErrDelegator) setDelegate(eh ErrorHandler) { + d.delegate.Store(&eh) +} + +func defaultErrorHandler() *ErrDelegator { + d := &ErrDelegator{} + d.setDelegate(&ErrLogger{l: log.New(os.Stderr, "", log.LstdFlags)}) + return d +} + +// ErrLogger logs errors if no delegate is set, otherwise they are delegated. +type ErrLogger struct { + l *log.Logger +} + +// Handle logs err if no delegate is set, otherwise it is delegated. +func (h *ErrLogger) Handle(err error) { + h.l.Print(err) +} + +// GetErrorHandler returns the global ErrorHandler instance. +// +// The default ErrorHandler instance returned will log all errors to STDERR +// until an override ErrorHandler is set with SetErrorHandler. All +// ErrorHandler returned prior to this will automatically forward errors to +// the set instance instead of logging. +// +// Subsequent calls to SetErrorHandler after the first will not forward errors +// to the new ErrorHandler for prior returned instances. +func GetErrorHandler() ErrorHandler { + return GlobalErrorHandler +} + +// SetErrorHandler sets the global ErrorHandler to h. +// +// The first time this is called all ErrorHandler previously returned from +// GetErrorHandler will send errors to h instead of the default logging +// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not +// delegate errors to h. +func SetErrorHandler(h ErrorHandler) { + GlobalErrorHandler.setDelegate(h) +} + +// Handle is a convenience function for ErrorHandler().Handle(err). +func Handle(err error) { + GetErrorHandler().Handle(err) +} diff --git a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go new file mode 100644 index 00000000000..a33eded872a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go @@ -0,0 +1,359 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/internal/global" + +import ( + "context" + "sync/atomic" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/embedded" +) + +// unwrapper unwraps to return the underlying instrument implementation. +type unwrapper interface { + Unwrap() metric.Observable +} + +type afCounter struct { + embedded.Float64ObservableCounter + metric.Float64Observable + + name string + opts []metric.Float64ObservableCounterOption + + delegate atomic.Value //metric.Float64ObservableCounter +} + +var _ unwrapper = (*afCounter)(nil) +var _ metric.Float64ObservableCounter = (*afCounter)(nil) + +func (i *afCounter) setDelegate(m metric.Meter) { + ctr, err := m.Float64ObservableCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *afCounter) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Float64ObservableCounter) + } + return nil +} + +type afUpDownCounter struct { + embedded.Float64ObservableUpDownCounter + metric.Float64Observable + + name string + opts []metric.Float64ObservableUpDownCounterOption + + delegate atomic.Value //metric.Float64ObservableUpDownCounter +} + +var _ unwrapper = (*afUpDownCounter)(nil) +var _ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil) + +func (i *afUpDownCounter) setDelegate(m metric.Meter) { + ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *afUpDownCounter) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Float64ObservableUpDownCounter) + } + return nil +} + +type afGauge struct { + embedded.Float64ObservableGauge + metric.Float64Observable + + name string + opts []metric.Float64ObservableGaugeOption + + delegate atomic.Value //metric.Float64ObservableGauge +} + +var _ unwrapper = (*afGauge)(nil) +var _ metric.Float64ObservableGauge = (*afGauge)(nil) + +func (i *afGauge) setDelegate(m metric.Meter) { + ctr, err := m.Float64ObservableGauge(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *afGauge) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Float64ObservableGauge) + } + return nil +} + +type aiCounter struct { + embedded.Int64ObservableCounter + metric.Int64Observable + + name string + opts []metric.Int64ObservableCounterOption + + delegate atomic.Value //metric.Int64ObservableCounter +} + +var _ unwrapper = (*aiCounter)(nil) +var _ metric.Int64ObservableCounter = (*aiCounter)(nil) + +func (i *aiCounter) setDelegate(m metric.Meter) { + ctr, err := m.Int64ObservableCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *aiCounter) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Int64ObservableCounter) + } + return nil +} + +type aiUpDownCounter struct { + embedded.Int64ObservableUpDownCounter + metric.Int64Observable + + name string + opts []metric.Int64ObservableUpDownCounterOption + + delegate atomic.Value //metric.Int64ObservableUpDownCounter +} + +var _ unwrapper = (*aiUpDownCounter)(nil) +var _ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil) + +func (i *aiUpDownCounter) setDelegate(m metric.Meter) { + ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *aiUpDownCounter) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Int64ObservableUpDownCounter) + } + return nil +} + +type aiGauge struct { + embedded.Int64ObservableGauge + metric.Int64Observable + + name string + opts []metric.Int64ObservableGaugeOption + + delegate atomic.Value //metric.Int64ObservableGauge +} + +var _ unwrapper = (*aiGauge)(nil) +var _ metric.Int64ObservableGauge = (*aiGauge)(nil) + +func (i *aiGauge) setDelegate(m metric.Meter) { + ctr, err := m.Int64ObservableGauge(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *aiGauge) Unwrap() metric.Observable { + if ctr := i.delegate.Load(); ctr != nil { + return ctr.(metric.Int64ObservableGauge) + } + return nil +} + +// Sync Instruments. +type sfCounter struct { + embedded.Float64Counter + + name string + opts []metric.Float64CounterOption + + delegate atomic.Value //metric.Float64Counter +} + +var _ metric.Float64Counter = (*sfCounter)(nil) + +func (i *sfCounter) setDelegate(m metric.Meter) { + ctr, err := m.Float64Counter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *sfCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Float64Counter).Add(ctx, incr, opts...) + } +} + +type sfUpDownCounter struct { + embedded.Float64UpDownCounter + + name string + opts []metric.Float64UpDownCounterOption + + delegate atomic.Value //metric.Float64UpDownCounter +} + +var _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil) + +func (i *sfUpDownCounter) setDelegate(m metric.Meter) { + ctr, err := m.Float64UpDownCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Float64UpDownCounter).Add(ctx, incr, opts...) + } +} + +type sfHistogram struct { + embedded.Float64Histogram + + name string + opts []metric.Float64HistogramOption + + delegate atomic.Value //metric.Float64Histogram +} + +var _ metric.Float64Histogram = (*sfHistogram)(nil) + +func (i *sfHistogram) setDelegate(m metric.Meter) { + ctr, err := m.Float64Histogram(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *sfHistogram) Record(ctx context.Context, x float64, opts ...metric.RecordOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Float64Histogram).Record(ctx, x, opts...) + } +} + +type siCounter struct { + embedded.Int64Counter + + name string + opts []metric.Int64CounterOption + + delegate atomic.Value //metric.Int64Counter +} + +var _ metric.Int64Counter = (*siCounter)(nil) + +func (i *siCounter) setDelegate(m metric.Meter) { + ctr, err := m.Int64Counter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *siCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Int64Counter).Add(ctx, x, opts...) + } +} + +type siUpDownCounter struct { + embedded.Int64UpDownCounter + + name string + opts []metric.Int64UpDownCounterOption + + delegate atomic.Value //metric.Int64UpDownCounter +} + +var _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil) + +func (i *siUpDownCounter) setDelegate(m metric.Meter) { + ctr, err := m.Int64UpDownCounter(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *siUpDownCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Int64UpDownCounter).Add(ctx, x, opts...) + } +} + +type siHistogram struct { + embedded.Int64Histogram + + name string + opts []metric.Int64HistogramOption + + delegate atomic.Value //metric.Int64Histogram +} + +var _ metric.Int64Histogram = (*siHistogram)(nil) + +func (i *siHistogram) setDelegate(m metric.Meter) { + ctr, err := m.Int64Histogram(i.name, i.opts...) + if err != nil { + GetErrorHandler().Handle(err) + return + } + i.delegate.Store(ctr) +} + +func (i *siHistogram) Record(ctx context.Context, x int64, opts ...metric.RecordOption) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(metric.Int64Histogram).Record(ctx, x, opts...) + } +} diff --git a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go new file mode 100644 index 00000000000..c6f305a2b76 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/internal/global" + +import ( + "log" + "os" + "sync/atomic" + + "github.com/go-logr/logr" + "github.com/go-logr/stdr" +) + +// globalLogger is the logging interface used within the otel api and sdk provide details of the internals. +// +// The default logger uses stdr which is backed by the standard `log.Logger` +// interface. This logger will only show messages at the Error Level. +var globalLogger atomic.Pointer[logr.Logger] + +func init() { + SetLogger(stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))) +} + +// SetLogger overrides the globalLogger with l. +// +// To see Warn messages use a logger with `l.V(1).Enabled() == true` +// To see Info messages use a logger with `l.V(4).Enabled() == true` +// To see Debug messages use a logger with `l.V(8).Enabled() == true`. +func SetLogger(l logr.Logger) { + globalLogger.Store(&l) +} + +func getLogger() logr.Logger { + return *globalLogger.Load() +} + +// Info prints messages about the general state of the API or SDK. +// This should usually be less than 5 messages a minute. +func Info(msg string, keysAndValues ...interface{}) { + getLogger().V(4).Info(msg, keysAndValues...) +} + +// Error prints messages about exceptional states of the API or SDK. +func Error(err error, msg string, keysAndValues ...interface{}) { + getLogger().Error(err, msg, keysAndValues...) +} + +// Debug prints messages about all internal changes in the API or SDK. +func Debug(msg string, keysAndValues ...interface{}) { + getLogger().V(8).Info(msg, keysAndValues...) +} + +// Warn prints messages about warnings in the API or SDK. +// Not an error but is likely more important than an informational event. +func Warn(msg string, keysAndValues ...interface{}) { + getLogger().V(1).Info(msg, keysAndValues...) +} diff --git a/vendor/go.opentelemetry.io/otel/internal/global/meter.go b/vendor/go.opentelemetry.io/otel/internal/global/meter.go index 36f9edeb8c6..0097db478c6 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/meter.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/meter.go @@ -12,337 +12,343 @@ // See the License for the specific language governing permissions and // limitations under the License. -package global +package global // import "go.opentelemetry.io/otel/internal/global" import ( - "context" + "container/list" "sync" "sync/atomic" - "unsafe" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/registry" + "go.opentelemetry.io/otel/metric/embedded" ) -// This file contains the forwarding implementation of MeterProvider used as -// the default global instance. Metric events using instruments provided by -// this implementation are no-ops until the first Meter implementation is set -// as the global provider. +// meterProvider is a placeholder for a configured SDK MeterProvider. // -// The implementation here uses Mutexes to maintain a list of active Meters in -// the MeterProvider and Instruments in each Meter, under the assumption that -// these interfaces are not performance-critical. -// -// We have the invariant that setDelegate() will be called before a new -// MeterProvider implementation is registered as the global provider. Mutexes -// in the MeterProvider and Meters ensure that each instrument has a delegate -// before the global provider is set. +// All MeterProvider functionality is forwarded to a delegate once +// configured. +type meterProvider struct { + embedded.MeterProvider + + mtx sync.Mutex + meters map[il]*meter + + delegate metric.MeterProvider +} + +// setDelegate configures p to delegate all MeterProvider functionality to +// provider. // -// Bound instrument operations are implemented by delegating to the -// instrument after it is registered, with a sync.Once initializer to -// protect against races with Release(). +// All Meters provided prior to this function call are switched out to be +// Meters provided by provider. All instruments and callbacks are recreated and +// delegated. // -// Metric uniqueness checking is implemented by calling the exported -// methods of the api/metric/registry package. +// It is guaranteed by the caller that this happens only once. +func (p *meterProvider) setDelegate(provider metric.MeterProvider) { + p.mtx.Lock() + defer p.mtx.Unlock() -type meterKey struct { - Name, Version string -} + p.delegate = provider -type meterProvider struct { - delegate metric.MeterProvider + if len(p.meters) == 0 { + return + } - // lock protects `delegate` and `meters`. - lock sync.Mutex + for _, meter := range p.meters { + meter.setDelegate(provider) + } - // meters maintains a unique entry for every named Meter - // that has been registered through the global instance. - meters map[meterKey]*meterEntry + p.meters = nil } -type meterImpl struct { - delegate unsafe.Pointer // (*metric.MeterImpl) +// Meter implements MeterProvider. +func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { + p.mtx.Lock() + defer p.mtx.Unlock() - lock sync.Mutex - syncInsts []*syncImpl - asyncInsts []*asyncImpl -} + if p.delegate != nil { + return p.delegate.Meter(name, opts...) + } -type meterEntry struct { - unique metric.MeterImpl - impl meterImpl -} + // At this moment it is guaranteed that no sdk is installed, save the meter in the meters map. -type instrument struct { - descriptor metric.Descriptor -} + c := metric.NewMeterConfig(opts...) + key := il{ + name: name, + version: c.InstrumentationVersion(), + } -type syncImpl struct { - delegate unsafe.Pointer // (*metric.SyncImpl) + if p.meters == nil { + p.meters = make(map[il]*meter) + } + + if val, ok := p.meters[key]; ok { + return val + } - instrument + t := &meter{name: name, opts: opts} + p.meters[key] = t + return t } -type asyncImpl struct { - delegate unsafe.Pointer // (*metric.AsyncImpl) +// meter is a placeholder for a metric.Meter. +// +// All Meter functionality is forwarded to a delegate once configured. +// Otherwise, all functionality is forwarded to a NoopMeter. +type meter struct { + embedded.Meter - instrument + name string + opts []metric.MeterOption - runner metric.AsyncRunner -} + mtx sync.Mutex + instruments []delegatedInstrument + + registry list.List -// SyncImpler is implemented by all of the sync metric -// instruments. -type SyncImpler interface { - SyncImpl() metric.SyncImpl + delegate atomic.Value // metric.Meter } -// AsyncImpler is implemented by all of the async -// metric instruments. -type AsyncImpler interface { - AsyncImpl() metric.AsyncImpl +type delegatedInstrument interface { + setDelegate(metric.Meter) } -type syncHandle struct { - delegate unsafe.Pointer // (*metric.BoundInstrumentImpl) +// setDelegate configures m to delegate all Meter functionality to Meters +// created by provider. +// +// All subsequent calls to the Meter methods will be passed to the delegate. +// +// It is guaranteed by the caller that this happens only once. +func (m *meter) setDelegate(provider metric.MeterProvider) { + meter := provider.Meter(m.name, m.opts...) + m.delegate.Store(meter) - inst *syncImpl - labels []attribute.KeyValue + m.mtx.Lock() + defer m.mtx.Unlock() - initialize sync.Once -} + for _, inst := range m.instruments { + inst.setDelegate(meter) + } -var _ metric.MeterProvider = &meterProvider{} -var _ metric.MeterImpl = &meterImpl{} -var _ metric.InstrumentImpl = &syncImpl{} -var _ metric.BoundSyncImpl = &syncHandle{} -var _ metric.AsyncImpl = &asyncImpl{} + for e := m.registry.Front(); e != nil; e = e.Next() { + r := e.Value.(*registration) + r.setDelegate(meter) + m.registry.Remove(e) + } -func (inst *instrument) Descriptor() metric.Descriptor { - return inst.descriptor + m.instruments = nil + m.registry.Init() } -// MeterProvider interface and delegation - -func newMeterProvider() *meterProvider { - return &meterProvider{ - meters: map[meterKey]*meterEntry{}, +func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64Counter(name, options...) } + m.mtx.Lock() + defer m.mtx.Unlock() + i := &siCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (p *meterProvider) setDelegate(provider metric.MeterProvider) { - p.lock.Lock() - defer p.lock.Unlock() - - p.delegate = provider - for key, entry := range p.meters { - entry.impl.setDelegate(key.Name, key.Version, provider) +func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64UpDownCounter(name, options...) } - p.meters = nil + m.mtx.Lock() + defer m.mtx.Unlock() + i := &siUpDownCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { - p.lock.Lock() - defer p.lock.Unlock() - - if p.delegate != nil { - return p.delegate.Meter(instrumentationName, opts...) +func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64Histogram(name, options...) } + m.mtx.Lock() + defer m.mtx.Unlock() + i := &siHistogram{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil +} - key := meterKey{ - Name: instrumentationName, - Version: metric.NewMeterConfig(opts...).InstrumentationVersion, +func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64ObservableCounter(name, options...) } - entry, ok := p.meters[key] - if !ok { - entry = &meterEntry{} - entry.unique = registry.NewUniqueInstrumentMeterImpl(&entry.impl) - p.meters[key] = entry + m.mtx.Lock() + defer m.mtx.Unlock() + i := &aiCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil +} +func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64ObservableUpDownCounter(name, options...) } - return metric.WrapMeterImpl(entry.unique, key.Name, metric.WithInstrumentationVersion(key.Version)) + m.mtx.Lock() + defer m.mtx.Unlock() + i := &aiUpDownCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -// Meter interface and delegation - -func (m *meterImpl) setDelegate(name, version string, provider metric.MeterProvider) { - m.lock.Lock() - defer m.lock.Unlock() - - d := new(metric.MeterImpl) - *d = provider.Meter(name, metric.WithInstrumentationVersion(version)).MeterImpl() - m.delegate = unsafe.Pointer(d) - - for _, inst := range m.syncInsts { - inst.setDelegate(*d) - } - m.syncInsts = nil - for _, obs := range m.asyncInsts { - obs.setDelegate(*d) +func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Int64ObservableGauge(name, options...) } - m.asyncInsts = nil + m.mtx.Lock() + defer m.mtx.Unlock() + i := &aiGauge{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (m *meterImpl) NewSyncInstrument(desc metric.Descriptor) (metric.SyncImpl, error) { - m.lock.Lock() - defer m.lock.Unlock() - - if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { - return (*meterPtr).NewSyncInstrument(desc) +func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64Counter(name, options...) } + m.mtx.Lock() + defer m.mtx.Unlock() + i := &sfCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil +} - inst := &syncImpl{ - instrument: instrument{ - descriptor: desc, - }, +func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64UpDownCounter(name, options...) } - m.syncInsts = append(m.syncInsts, inst) - return inst, nil + m.mtx.Lock() + defer m.mtx.Unlock() + i := &sfUpDownCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -// Synchronous delegation - -func (inst *syncImpl) setDelegate(d metric.MeterImpl) { - implPtr := new(metric.SyncImpl) - - var err error - *implPtr, err = d.NewSyncInstrument(inst.descriptor) - - if err != nil { - // TODO: There is no standard way to deliver this error to the user. - // See https://github.com/open-telemetry/opentelemetry-go/issues/514 - // Note that the default SDK will not generate any errors yet, this is - // only for added safety. - panic(err) +func (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64Histogram(name, options...) } - - atomic.StorePointer(&inst.delegate, unsafe.Pointer(implPtr)) + m.mtx.Lock() + defer m.mtx.Unlock() + i := &sfHistogram{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (inst *syncImpl) Implementation() interface{} { - if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil { - return (*implPtr).Implementation() +func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64ObservableCounter(name, options...) } - return inst + m.mtx.Lock() + defer m.mtx.Unlock() + i := &afCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (inst *syncImpl) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl { - if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil { - return (*implPtr).Bind(labels) - } - return &syncHandle{ - inst: inst, - labels: labels, +func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64ObservableUpDownCounter(name, options...) } + m.mtx.Lock() + defer m.mtx.Unlock() + i := &afUpDownCounter{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -func (bound *syncHandle) Unbind() { - bound.initialize.Do(func() {}) - - implPtr := (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate)) - - if implPtr == nil { - return +func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.Float64ObservableGauge(name, options...) } - - (*implPtr).Unbind() + m.mtx.Lock() + defer m.mtx.Unlock() + i := &afGauge{name: name, opts: options} + m.instruments = append(m.instruments, i) + return i, nil } -// Async delegation - -func (m *meterImpl) NewAsyncInstrument( - desc metric.Descriptor, - runner metric.AsyncRunner, -) (metric.AsyncImpl, error) { - - m.lock.Lock() - defer m.lock.Unlock() - - if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { - return (*meterPtr).NewAsyncInstrument(desc, runner) +// RegisterCallback captures the function that will be called during Collect. +func (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) { + if del, ok := m.delegate.Load().(metric.Meter); ok { + insts = unwrapInstruments(insts) + return del.RegisterCallback(f, insts...) } - inst := &asyncImpl{ - instrument: instrument{ - descriptor: desc, - }, - runner: runner, - } - m.asyncInsts = append(m.asyncInsts, inst) - return inst, nil -} + m.mtx.Lock() + defer m.mtx.Unlock() -func (obs *asyncImpl) Implementation() interface{} { - if implPtr := (*metric.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil { - return (*implPtr).Implementation() + reg := ®istration{instruments: insts, function: f} + e := m.registry.PushBack(reg) + reg.unreg = func() error { + m.mtx.Lock() + _ = m.registry.Remove(e) + m.mtx.Unlock() + return nil } - return obs + return reg, nil } -func (obs *asyncImpl) setDelegate(d metric.MeterImpl) { - implPtr := new(metric.AsyncImpl) +type wrapped interface { + unwrap() metric.Observable +} - var err error - *implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner) +func unwrapInstruments(instruments []metric.Observable) []metric.Observable { + out := make([]metric.Observable, 0, len(instruments)) - if err != nil { - // TODO: There is no standard way to deliver this error to the user. - // See https://github.com/open-telemetry/opentelemetry-go/issues/514 - // Note that the default SDK will not generate any errors yet, this is - // only for added safety. - panic(err) + for _, inst := range instruments { + if in, ok := inst.(wrapped); ok { + out = append(out, in.unwrap()) + } else { + out = append(out, inst) + } } - atomic.StorePointer(&obs.delegate, unsafe.Pointer(implPtr)) + return out } -// Metric updates +type registration struct { + embedded.Registration -func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...metric.Measurement) { - if delegatePtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil { - (*delegatePtr).RecordBatch(ctx, labels, measurements...) - } -} + instruments []metric.Observable + function metric.Callback -func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) { - if instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil { - (*instPtr).RecordOne(ctx, number, labels) - } + unreg func() error + unregMu sync.Mutex } -// Bound instrument initialization +func (c *registration) setDelegate(m metric.Meter) { + insts := unwrapInstruments(c.instruments) + + c.unregMu.Lock() + defer c.unregMu.Unlock() -func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) { - instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate)) - if instPtr == nil { + if c.unreg == nil { + // Unregister already called. return } - var implPtr *metric.BoundSyncImpl - bound.initialize.Do(func() { - implPtr = new(metric.BoundSyncImpl) - *implPtr = (*instPtr).Bind(bound.labels) - atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr)) - }) - if implPtr == nil { - implPtr = (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate)) - } - // This may still be nil if instrument was created and bound - // without a delegate, then the instrument was set to have a - // delegate and unbound. - if implPtr == nil { - return + + reg, err := m.RegisterCallback(c.function, insts...) + if err != nil { + GetErrorHandler().Handle(err) } - (*implPtr).RecordOne(ctx, number) + + c.unreg = reg.Unregister } -func AtomicFieldOffsets() map[string]uintptr { - return map[string]uintptr{ - "meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate), - "meterImpl.delegate": unsafe.Offsetof(meterImpl{}.delegate), - "syncImpl.delegate": unsafe.Offsetof(syncImpl{}.delegate), - "asyncImpl.delegate": unsafe.Offsetof(asyncImpl{}.delegate), - "syncHandle.delegate": unsafe.Offsetof(syncHandle{}.delegate), +func (c *registration) Unregister() error { + c.unregMu.Lock() + defer c.unregMu.Unlock() + if c.unreg == nil { + // Unregister already called. + return nil } + + var err error + err, c.unreg = c.unreg(), nil + return err } diff --git a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go index 1c8b8589b08..06bac35c2fe 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package global +package global // import "go.opentelemetry.io/otel/internal/global" import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/state.go b/vendor/go.opentelemetry.io/otel/internal/global/state.go index f3bf0035100..7985005bcb6 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/state.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/state.go @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package global +package global // import "go.opentelemetry.io/otel/internal/global" import ( + "errors" "sync" "sync/atomic" @@ -28,23 +29,23 @@ type ( tp trace.TracerProvider } - meterProviderHolder struct { - mp metric.MeterProvider - } - propagatorsHolder struct { tm propagation.TextMapPropagator } + + meterProviderHolder struct { + mp metric.MeterProvider + } ) var ( - globalTracer = defaultTracerValue() - globalMeter = defaultMeterValue() - globalPropagators = defaultPropagatorsValue() + globalTracer = defaultTracerValue() + globalPropagators = defaultPropagatorsValue() + globalMeterProvider = defaultMeterProvider() - delegateMeterOnce sync.Once delegateTraceOnce sync.Once delegateTextMapPropagatorOnce sync.Once + delegateMeterOnce sync.Once ) // TracerProvider is the internal implementation for global.TracerProvider. @@ -54,43 +55,28 @@ func TracerProvider() trace.TracerProvider { // SetTracerProvider is the internal implementation for global.SetTracerProvider. func SetTracerProvider(tp trace.TracerProvider) { + current := TracerProvider() + + if _, cOk := current.(*tracerProvider); cOk { + if _, tpOk := tp.(*tracerProvider); tpOk && current == tp { + // Do not assign the default delegating TracerProvider to delegate + // to itself. + Error( + errors.New("no delegate configured in tracer provider"), + "Setting tracer provider to it's current value. No delegate will be configured", + ) + return + } + } + delegateTraceOnce.Do(func() { - current := TracerProvider() - if current == tp { - // Setting the provider to the prior default is nonsense, panic. - // Panic is acceptable because we are likely still early in the - // process lifetime. - panic("invalid TracerProvider, the global instance cannot be reinstalled") - } else if def, ok := current.(*tracerProvider); ok { + if def, ok := current.(*tracerProvider); ok { def.setDelegate(tp) } - }) globalTracer.Store(tracerProviderHolder{tp: tp}) } -// MeterProvider is the internal implementation for global.MeterProvider. -func MeterProvider() metric.MeterProvider { - return globalMeter.Load().(meterProviderHolder).mp -} - -// SetMeterProvider is the internal implementation for global.SetMeterProvider. -func SetMeterProvider(mp metric.MeterProvider) { - delegateMeterOnce.Do(func() { - current := MeterProvider() - - if current == mp { - // Setting the provider to the prior default is nonsense, panic. - // Panic is acceptable because we are likely still early in the - // process lifetime. - panic("invalid MeterProvider, the global instance cannot be reinstalled") - } else if def, ok := current.(*meterProvider); ok { - def.setDelegate(mp) - } - }) - globalMeter.Store(meterProviderHolder{mp: mp}) -} - // TextMapPropagator is the internal implementation for global.TextMapPropagator. func TextMapPropagator() propagation.TextMapPropagator { return globalPropagators.Load().(propagatorsHolder).tm @@ -98,15 +84,24 @@ func TextMapPropagator() propagation.TextMapPropagator { // SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator. func SetTextMapPropagator(p propagation.TextMapPropagator) { + current := TextMapPropagator() + + if _, cOk := current.(*textMapPropagator); cOk { + if _, pOk := p.(*textMapPropagator); pOk && current == p { + // Do not assign the default delegating TextMapPropagator to + // delegate to itself. + Error( + errors.New("no delegate configured in text map propagator"), + "Setting text map propagator to it's current value. No delegate will be configured", + ) + return + } + } + // For the textMapPropagator already returned by TextMapPropagator // delegate to p. delegateTextMapPropagatorOnce.Do(func() { - if current := TextMapPropagator(); current == p { - // Setting the provider to the prior default is nonsense, panic. - // Panic is acceptable because we are likely still early in the - // process lifetime. - panic("invalid TextMapPropagator, the global instance cannot be reinstalled") - } else if def, ok := current.(*textMapPropagator); ok { + if def, ok := current.(*textMapPropagator); ok { def.SetDelegate(p) } }) @@ -114,15 +109,37 @@ func SetTextMapPropagator(p propagation.TextMapPropagator) { globalPropagators.Store(propagatorsHolder{tm: p}) } -func defaultTracerValue() *atomic.Value { - v := &atomic.Value{} - v.Store(tracerProviderHolder{tp: &tracerProvider{}}) - return v +// MeterProvider is the internal implementation for global.MeterProvider. +func MeterProvider() metric.MeterProvider { + return globalMeterProvider.Load().(meterProviderHolder).mp } -func defaultMeterValue() *atomic.Value { +// SetMeterProvider is the internal implementation for global.SetMeterProvider. +func SetMeterProvider(mp metric.MeterProvider) { + current := MeterProvider() + if _, cOk := current.(*meterProvider); cOk { + if _, mpOk := mp.(*meterProvider); mpOk && current == mp { + // Do not assign the default delegating MeterProvider to delegate + // to itself. + Error( + errors.New("no delegate configured in meter provider"), + "Setting meter provider to it's current value. No delegate will be configured", + ) + return + } + } + + delegateMeterOnce.Do(func() { + if def, ok := current.(*meterProvider); ok { + def.setDelegate(mp) + } + }) + globalMeterProvider.Store(meterProviderHolder{mp: mp}) +} + +func defaultTracerValue() *atomic.Value { v := &atomic.Value{} - v.Store(meterProviderHolder{mp: newMeterProvider()}) + v.Store(tracerProviderHolder{tp: &tracerProvider{}}) return v } @@ -132,12 +149,8 @@ func defaultPropagatorsValue() *atomic.Value { return v } -// ResetForTest restores the initial global state, for testing purposes. -func ResetForTest() { - globalTracer = defaultTracerValue() - globalMeter = defaultMeterValue() - globalPropagators = defaultPropagatorsValue() - delegateMeterOnce = sync.Once{} - delegateTraceOnce = sync.Once{} - delegateTextMapPropagatorOnce = sync.Once{} +func defaultMeterProvider() *atomic.Value { + v := &atomic.Value{} + v.Store(meterProviderHolder{mp: &meterProvider{}}) + return v } diff --git a/vendor/go.opentelemetry.io/otel/internal/global/trace.go b/vendor/go.opentelemetry.io/otel/internal/global/trace.go index d7f71dc06c6..5f008d0982b 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/trace.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/trace.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package global +package global // import "go.opentelemetry.io/otel/internal/global" /* This file contains the forwarding implementation of the TracerProvider used as @@ -36,7 +36,8 @@ import ( "sync" "sync/atomic" - "go.opentelemetry.io/otel/internal/trace/noop" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" ) @@ -89,9 +90,10 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T // At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map. + c := trace.NewTracerConfig(opts...) key := il{ name: name, - version: trace.NewTracerConfig(opts...).InstrumentationVersion, + version: c.InstrumentationVersion(), } if p.tracers == nil { @@ -102,7 +104,7 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T return val } - t := &tracer{name: name, opts: opts} + t := &tracer{name: name, opts: opts, provider: p} p.tracers[key] = t return t } @@ -117,8 +119,9 @@ type il struct { // All Tracer functionality is forwarded to a delegate once configured. // Otherwise, all functionality is forwarded to a NoopTracer. type tracer struct { - name string - opts []trace.TracerOption + name string + opts []trace.TracerOption + provider *tracerProvider delegate atomic.Value } @@ -138,10 +141,52 @@ func (t *tracer) setDelegate(provider trace.TracerProvider) { // Start implements trace.Tracer by forwarding the call to t.delegate if // set, otherwise it forwards the call to a NoopTracer. -func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanOption) (context.Context, trace.Span) { +func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { delegate := t.delegate.Load() if delegate != nil { return delegate.(trace.Tracer).Start(ctx, name, opts...) } - return noop.Tracer.Start(ctx, name, opts...) + + s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t} + ctx = trace.ContextWithSpan(ctx, s) + return ctx, s +} + +// nonRecordingSpan is a minimal implementation of a Span that wraps a +// SpanContext. It performs no operations other than to return the wrapped +// SpanContext. +type nonRecordingSpan struct { + sc trace.SpanContext + tracer *tracer } + +var _ trace.Span = nonRecordingSpan{} + +// SpanContext returns the wrapped SpanContext. +func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc } + +// IsRecording always returns false. +func (nonRecordingSpan) IsRecording() bool { return false } + +// SetStatus does nothing. +func (nonRecordingSpan) SetStatus(codes.Code, string) {} + +// SetError does nothing. +func (nonRecordingSpan) SetError(bool) {} + +// SetAttributes does nothing. +func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {} + +// End does nothing. +func (nonRecordingSpan) End(...trace.SpanEndOption) {} + +// RecordError does nothing. +func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {} + +// AddEvent does nothing. +func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {} + +// SetName does nothing. +func (nonRecordingSpan) SetName(string) {} + +func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider } diff --git a/vendor/go.opentelemetry.io/otel/internal/metric/async.go b/vendor/go.opentelemetry.io/otel/internal/metric/async.go deleted file mode 100644 index f05faca8a90..00000000000 --- a/vendor/go.opentelemetry.io/otel/internal/metric/async.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric - -import ( - "context" - "errors" - "fmt" - "sync" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" -) - -var ErrInvalidAsyncRunner = errors.New("unknown async runner type") - -// AsyncCollector is an interface used between the MeterImpl and the -// AsyncInstrumentState helper below. This interface is implemented by -// the SDK to provide support for running observer callbacks. -type AsyncCollector interface { - // CollectAsync passes a batch of observations to the MeterImpl. - CollectAsync(labels []attribute.KeyValue, observation ...metric.Observation) -} - -// AsyncInstrumentState manages an ordered set of asynchronous -// instruments and the distinct runners, taking into account batch -// observer callbacks. -type AsyncInstrumentState struct { - lock sync.Mutex - - // errorOnce will use the otel.Handler to report an error - // once in case of an invalid runner attempting to run. - errorOnce sync.Once - - // runnerMap keeps the set of runners that will run each - // collection interval. Singletons are entered with a real - // instrument each, batch observers are entered with a nil - // instrument, ensuring that when a singleton callback is used - // repeatedly, it is executed repeatedly in the interval, while - // when a batch callback is used repeatedly, it only executes - // once per interval. - runnerMap map[asyncRunnerPair]struct{} - - // runners maintains the set of runners in the order they were - // registered. - runners []asyncRunnerPair - - // instruments maintains the set of instruments in the order - // they were registered. - instruments []metric.AsyncImpl -} - -// asyncRunnerPair is a map entry for Observer callback runners. -type asyncRunnerPair struct { - // runner is used as a map key here. The API ensures - // that all callbacks are pointers for this reason. - runner metric.AsyncRunner - - // inst refers to a non-nil instrument when `runner` is a - // AsyncSingleRunner. - inst metric.AsyncImpl -} - -// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for -// use by MeterImpl to manage running the set of observer callbacks in -// the correct order. -func NewAsyncInstrumentState() *AsyncInstrumentState { - return &AsyncInstrumentState{ - runnerMap: map[asyncRunnerPair]struct{}{}, - } -} - -// Instruments returns the asynchronous instruments managed by this -// object, the set that should be checkpointed after observers are -// run. -func (a *AsyncInstrumentState) Instruments() []metric.AsyncImpl { - a.lock.Lock() - defer a.lock.Unlock() - return a.instruments -} - -// Register adds a new asynchronous instrument to by managed by this -// object. This should be called during NewAsyncInstrument() and -// assumes that errors (e.g., duplicate registration) have already -// been checked. -func (a *AsyncInstrumentState) Register(inst metric.AsyncImpl, runner metric.AsyncRunner) { - a.lock.Lock() - defer a.lock.Unlock() - - a.instruments = append(a.instruments, inst) - - // asyncRunnerPair reflects this callback in the asyncRunners - // list. If this is a batch runner, the instrument is nil. - // If this is a single-Observer runner, the instrument is - // included. This ensures that batch callbacks are called - // once and single callbacks are called once per instrument. - rp := asyncRunnerPair{ - runner: runner, - } - if _, ok := runner.(metric.AsyncSingleRunner); ok { - rp.inst = inst - } - - if _, ok := a.runnerMap[rp]; !ok { - a.runnerMap[rp] = struct{}{} - a.runners = append(a.runners, rp) - } -} - -// Run executes the complete set of observer callbacks. -func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector) { - a.lock.Lock() - runners := a.runners - a.lock.Unlock() - - for _, rp := range runners { - // The runner must be a single or batch runner, no - // other implementations are possible because the - // interface has un-exported methods. - - if singleRunner, ok := rp.runner.(metric.AsyncSingleRunner); ok { - singleRunner.Run(ctx, rp.inst, collector.CollectAsync) - continue - } - - if multiRunner, ok := rp.runner.(metric.AsyncBatchRunner); ok { - multiRunner.Run(ctx, collector.CollectAsync) - continue - } - - a.errorOnce.Do(func() { - otel.Handle(fmt.Errorf("%w: type %T (reported once)", ErrInvalidAsyncRunner, rp)) - }) - } -} diff --git a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go b/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go index 0d806b1c897..e07e7940004 100644 --- a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go +++ b/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package internal +package internal // import "go.opentelemetry.io/otel/internal" import ( "math" "unsafe" ) -func BoolToRaw(b bool) uint64 { +func BoolToRaw(b bool) uint64 { // nolint:revive // b is not a control flag. if b { return 1 } diff --git a/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go b/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go deleted file mode 100644 index 765c21a289c..00000000000 --- a/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package noop provides noop tracing implementations for tracer and span. -package noop - -import ( - "context" - - "go.opentelemetry.io/otel/trace" -) - -var ( - // Tracer is a noop tracer that starts noop spans. - Tracer trace.Tracer - - // Span is a noop Span. - Span trace.Span -) - -func init() { - Tracer = trace.NewNoopTracerProvider().Tracer("") - _, Span = Tracer.Start(context.Background(), "") -} diff --git a/vendor/go.opentelemetry.io/otel/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal_logging.go new file mode 100644 index 00000000000..c4f8acd5d83 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal_logging.go @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otel // import "go.opentelemetry.io/otel" + +import ( + "github.com/go-logr/logr" + + "go.opentelemetry.io/otel/internal/global" +) + +// SetLogger configures the logger used internally to opentelemetry. +func SetLogger(logger logr.Logger) { + global.SetLogger(logger) +} diff --git a/vendor/go.opentelemetry.io/otel/metric.go b/vendor/go.opentelemetry.io/otel/metric.go new file mode 100644 index 00000000000..f955171951f --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric.go @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otel // import "go.opentelemetry.io/otel" + +import ( + "go.opentelemetry.io/otel/internal/global" + "go.opentelemetry.io/otel/metric" +) + +// Meter returns a Meter from the global MeterProvider. The name must be the +// name of the library providing instrumentation. This name may be the same as +// the instrumented code only if that code provides built-in instrumentation. +// If the name is empty, then a implementation defined default name will be +// used instead. +// +// If this is called before a global MeterProvider is registered the returned +// Meter will be a No-op implementation of a Meter. When a global MeterProvider +// is registered for the first time, the returned Meter, and all the +// instruments it has created or will create, are recreated automatically from +// the new MeterProvider. +// +// This is short for GetMeterProvider().Meter(name). +func Meter(name string, opts ...metric.MeterOption) metric.Meter { + return GetMeterProvider().Meter(name, opts...) +} + +// GetMeterProvider returns the registered global meter provider. +// +// If no global GetMeterProvider has been registered, a No-op GetMeterProvider +// implementation is returned. When a global GetMeterProvider is registered for +// the first time, the returned GetMeterProvider, and all the Meters it has +// created or will create, are recreated automatically from the new +// GetMeterProvider. +func GetMeterProvider() metric.MeterProvider { + return global.MeterProvider() +} + +// SetMeterProvider registers mp as the global MeterProvider. +func SetMeterProvider(mp metric.MeterProvider) { + global.SetMeterProvider(mp) +} diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go new file mode 100644 index 00000000000..072baa8e8d0 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go @@ -0,0 +1,271 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/embedded" +) + +// Float64Observable describes a set of instruments used asynchronously to +// record float64 measurements once per collection cycle. Observations of +// these instruments are only made within a callback. +// +// Warning: Methods may be added to this interface in minor releases. +type Float64Observable interface { + Observable + + float64Observable() +} + +// Float64ObservableCounter is an instrument used to asynchronously record +// increasing float64 measurements once per collection cycle. Observations are +// only made within a callback for this instrument. The value observed is +// assumed the to be the cumulative sum of the count. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for +// unimplemented methods. +type Float64ObservableCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64ObservableCounter + + Float64Observable +} + +// Float64ObservableCounterConfig contains options for asynchronous counter +// instruments that record int64 values. +type Float64ObservableCounterConfig struct { + description string + unit string + callbacks []Float64Callback +} + +// NewFloat64ObservableCounterConfig returns a new +// [Float64ObservableCounterConfig] with all opts applied. +func NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig { + var config Float64ObservableCounterConfig + for _, o := range opts { + config = o.applyFloat64ObservableCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Float64ObservableCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64ObservableCounterConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Float64ObservableCounterConfig) Callbacks() []Float64Callback { + return c.callbacks +} + +// Float64ObservableCounterOption applies options to a +// [Float64ObservableCounterConfig]. See [Float64ObservableOption] and +// [InstrumentOption] for other options that can be used as a +// Float64ObservableCounterOption. +type Float64ObservableCounterOption interface { + applyFloat64ObservableCounter(Float64ObservableCounterConfig) Float64ObservableCounterConfig +} + +// Float64ObservableUpDownCounter is an instrument used to asynchronously +// record float64 measurements once per collection cycle. Observations are only +// made within a callback for this instrument. The value observed is assumed +// the to be the cumulative sum of the count. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64ObservableUpDownCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64ObservableUpDownCounter + + Float64Observable +} + +// Float64ObservableUpDownCounterConfig contains options for asynchronous +// counter instruments that record int64 values. +type Float64ObservableUpDownCounterConfig struct { + description string + unit string + callbacks []Float64Callback +} + +// NewFloat64ObservableUpDownCounterConfig returns a new +// [Float64ObservableUpDownCounterConfig] with all opts applied. +func NewFloat64ObservableUpDownCounterConfig(opts ...Float64ObservableUpDownCounterOption) Float64ObservableUpDownCounterConfig { + var config Float64ObservableUpDownCounterConfig + for _, o := range opts { + config = o.applyFloat64ObservableUpDownCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Float64ObservableUpDownCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64ObservableUpDownCounterConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Float64ObservableUpDownCounterConfig) Callbacks() []Float64Callback { + return c.callbacks +} + +// Float64ObservableUpDownCounterOption applies options to a +// [Float64ObservableUpDownCounterConfig]. See [Float64ObservableOption] and +// [InstrumentOption] for other options that can be used as a +// Float64ObservableUpDownCounterOption. +type Float64ObservableUpDownCounterOption interface { + applyFloat64ObservableUpDownCounter(Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig +} + +// Float64ObservableGauge is an instrument used to asynchronously record +// instantaneous float64 measurements once per collection cycle. Observations +// are only made within a callback for this instrument. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64ObservableGauge interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64ObservableGauge + + Float64Observable +} + +// Float64ObservableGaugeConfig contains options for asynchronous counter +// instruments that record int64 values. +type Float64ObservableGaugeConfig struct { + description string + unit string + callbacks []Float64Callback +} + +// NewFloat64ObservableGaugeConfig returns a new [Float64ObservableGaugeConfig] +// with all opts applied. +func NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig { + var config Float64ObservableGaugeConfig + for _, o := range opts { + config = o.applyFloat64ObservableGauge(config) + } + return config +} + +// Description returns the configured description. +func (c Float64ObservableGaugeConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64ObservableGaugeConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Float64ObservableGaugeConfig) Callbacks() []Float64Callback { + return c.callbacks +} + +// Float64ObservableGaugeOption applies options to a +// [Float64ObservableGaugeConfig]. See [Float64ObservableOption] and +// [InstrumentOption] for other options that can be used as a +// Float64ObservableGaugeOption. +type Float64ObservableGaugeOption interface { + applyFloat64ObservableGauge(Float64ObservableGaugeConfig) Float64ObservableGaugeConfig +} + +// Float64Observer is a recorder of float64 measurements. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64Observer interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64Observer + + // Observe records the float64 value. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Observe(value float64, options ...ObserveOption) +} + +// Float64Callback is a function registered with a Meter that makes +// observations for a Float64Observerable instrument it is registered with. +// Calls to the Float64Observer record measurement values for the +// Float64Observable. +// +// The function needs to complete in a finite amount of time and the deadline +// of the passed context is expected to be honored. +// +// The function needs to make unique observations across all registered +// Float64Callbacks. Meaning, it should not report measurements with the same +// attributes as another Float64Callbacks also registered for the same +// instrument. +// +// The function needs to be concurrent safe. +type Float64Callback func(context.Context, Float64Observer) error + +// Float64ObservableOption applies options to float64 Observer instruments. +type Float64ObservableOption interface { + Float64ObservableCounterOption + Float64ObservableUpDownCounterOption + Float64ObservableGaugeOption +} + +type float64CallbackOpt struct { + cback Float64Callback +} + +func (o float64CallbackOpt) applyFloat64ObservableCounter(cfg Float64ObservableCounterConfig) Float64ObservableCounterConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +func (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(cfg Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +func (o float64CallbackOpt) applyFloat64ObservableGauge(cfg Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +// WithFloat64Callback adds callback to be called for an instrument. +func WithFloat64Callback(callback Float64Callback) Float64ObservableOption { + return float64CallbackOpt{callback} +} diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go new file mode 100644 index 00000000000..9bd6ebf0205 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go @@ -0,0 +1,269 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/embedded" +) + +// Int64Observable describes a set of instruments used asynchronously to record +// int64 measurements once per collection cycle. Observations of these +// instruments are only made within a callback. +// +// Warning: Methods may be added to this interface in minor releases. +type Int64Observable interface { + Observable + + int64Observable() +} + +// Int64ObservableCounter is an instrument used to asynchronously record +// increasing int64 measurements once per collection cycle. Observations are +// only made within a callback for this instrument. The value observed is +// assumed the to be the cumulative sum of the count. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64ObservableCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64ObservableCounter + + Int64Observable +} + +// Int64ObservableCounterConfig contains options for asynchronous counter +// instruments that record int64 values. +type Int64ObservableCounterConfig struct { + description string + unit string + callbacks []Int64Callback +} + +// NewInt64ObservableCounterConfig returns a new [Int64ObservableCounterConfig] +// with all opts applied. +func NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig { + var config Int64ObservableCounterConfig + for _, o := range opts { + config = o.applyInt64ObservableCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Int64ObservableCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64ObservableCounterConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Int64ObservableCounterConfig) Callbacks() []Int64Callback { + return c.callbacks +} + +// Int64ObservableCounterOption applies options to a +// [Int64ObservableCounterConfig]. See [Int64ObservableOption] and +// [InstrumentOption] for other options that can be used as an +// Int64ObservableCounterOption. +type Int64ObservableCounterOption interface { + applyInt64ObservableCounter(Int64ObservableCounterConfig) Int64ObservableCounterConfig +} + +// Int64ObservableUpDownCounter is an instrument used to asynchronously record +// int64 measurements once per collection cycle. Observations are only made +// within a callback for this instrument. The value observed is assumed the to +// be the cumulative sum of the count. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64ObservableUpDownCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64ObservableUpDownCounter + + Int64Observable +} + +// Int64ObservableUpDownCounterConfig contains options for asynchronous counter +// instruments that record int64 values. +type Int64ObservableUpDownCounterConfig struct { + description string + unit string + callbacks []Int64Callback +} + +// NewInt64ObservableUpDownCounterConfig returns a new +// [Int64ObservableUpDownCounterConfig] with all opts applied. +func NewInt64ObservableUpDownCounterConfig(opts ...Int64ObservableUpDownCounterOption) Int64ObservableUpDownCounterConfig { + var config Int64ObservableUpDownCounterConfig + for _, o := range opts { + config = o.applyInt64ObservableUpDownCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Int64ObservableUpDownCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64ObservableUpDownCounterConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Int64ObservableUpDownCounterConfig) Callbacks() []Int64Callback { + return c.callbacks +} + +// Int64ObservableUpDownCounterOption applies options to a +// [Int64ObservableUpDownCounterConfig]. See [Int64ObservableOption] and +// [InstrumentOption] for other options that can be used as an +// Int64ObservableUpDownCounterOption. +type Int64ObservableUpDownCounterOption interface { + applyInt64ObservableUpDownCounter(Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig +} + +// Int64ObservableGauge is an instrument used to asynchronously record +// instantaneous int64 measurements once per collection cycle. Observations are +// only made within a callback for this instrument. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64ObservableGauge interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64ObservableGauge + + Int64Observable +} + +// Int64ObservableGaugeConfig contains options for asynchronous counter +// instruments that record int64 values. +type Int64ObservableGaugeConfig struct { + description string + unit string + callbacks []Int64Callback +} + +// NewInt64ObservableGaugeConfig returns a new [Int64ObservableGaugeConfig] +// with all opts applied. +func NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig { + var config Int64ObservableGaugeConfig + for _, o := range opts { + config = o.applyInt64ObservableGauge(config) + } + return config +} + +// Description returns the configured description. +func (c Int64ObservableGaugeConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64ObservableGaugeConfig) Unit() string { + return c.unit +} + +// Callbacks returns the configured callbacks. +func (c Int64ObservableGaugeConfig) Callbacks() []Int64Callback { + return c.callbacks +} + +// Int64ObservableGaugeOption applies options to a +// [Int64ObservableGaugeConfig]. See [Int64ObservableOption] and +// [InstrumentOption] for other options that can be used as an +// Int64ObservableGaugeOption. +type Int64ObservableGaugeOption interface { + applyInt64ObservableGauge(Int64ObservableGaugeConfig) Int64ObservableGaugeConfig +} + +// Int64Observer is a recorder of int64 measurements. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64Observer interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64Observer + + // Observe records the int64 value. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Observe(value int64, options ...ObserveOption) +} + +// Int64Callback is a function registered with a Meter that makes observations +// for an Int64Observerable instrument it is registered with. Calls to the +// Int64Observer record measurement values for the Int64Observable. +// +// The function needs to complete in a finite amount of time and the deadline +// of the passed context is expected to be honored. +// +// The function needs to make unique observations across all registered +// Int64Callbacks. Meaning, it should not report measurements with the same +// attributes as another Int64Callbacks also registered for the same +// instrument. +// +// The function needs to be concurrent safe. +type Int64Callback func(context.Context, Int64Observer) error + +// Int64ObservableOption applies options to int64 Observer instruments. +type Int64ObservableOption interface { + Int64ObservableCounterOption + Int64ObservableUpDownCounterOption + Int64ObservableGaugeOption +} + +type int64CallbackOpt struct { + cback Int64Callback +} + +func (o int64CallbackOpt) applyInt64ObservableCounter(cfg Int64ObservableCounterConfig) Int64ObservableCounterConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +func (o int64CallbackOpt) applyInt64ObservableUpDownCounter(cfg Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +func (o int64CallbackOpt) applyInt64ObservableGauge(cfg Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { + cfg.callbacks = append(cfg.callbacks, o.cback) + return cfg +} + +// WithInt64Callback adds callback to be called for an instrument. +func WithInt64Callback(callback Int64Callback) Int64ObservableOption { + return int64CallbackOpt{callback} +} diff --git a/vendor/go.opentelemetry.io/otel/metric/config.go b/vendor/go.opentelemetry.io/otel/metric/config.go index 02f0ff8e0cb..778ad2d748b 100644 --- a/vendor/go.opentelemetry.io/otel/metric/config.go +++ b/vendor/go.opentelemetry.io/otel/metric/config.go @@ -14,85 +14,39 @@ package metric // import "go.opentelemetry.io/otel/metric" -import ( - "go.opentelemetry.io/otel/unit" -) +import "go.opentelemetry.io/otel/attribute" -// InstrumentConfig contains options for metric instrument descriptors. -type InstrumentConfig struct { - // Description describes the instrument in human-readable terms. - Description string - // Unit describes the measurement unit for a instrument. - Unit unit.Unit - // InstrumentationName is the name of the library providing - // instrumentation. - InstrumentationName string - // InstrumentationVersion is the version of the library providing - // instrumentation. - InstrumentationVersion string -} - -// InstrumentOption is an interface for applying metric instrument options. -type InstrumentOption interface { - // ApplyMeter is used to set a InstrumentOption value of a - // InstrumentConfig. - ApplyInstrument(*InstrumentConfig) -} - -// NewInstrumentConfig creates a new InstrumentConfig -// and applies all the given options. -func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig { - var config InstrumentConfig - for _, o := range opts { - o.ApplyInstrument(&config) - } - return config -} - -// WithDescription applies provided description. -func WithDescription(desc string) InstrumentOption { - return descriptionOption(desc) -} - -type descriptionOption string - -func (d descriptionOption) ApplyInstrument(config *InstrumentConfig) { - config.Description = string(d) -} +// MeterConfig contains options for Meters. +type MeterConfig struct { + instrumentationVersion string + schemaURL string + attrs attribute.Set -// WithUnit applies provided unit. -func WithUnit(unit unit.Unit) InstrumentOption { - return unitOption(unit) + // Ensure forward compatibility by explicitly making this not comparable. + noCmp [0]func() //nolint: unused // This is indeed used. } -type unitOption unit.Unit - -func (u unitOption) ApplyInstrument(config *InstrumentConfig) { - config.Unit = unit.Unit(u) +// InstrumentationVersion returns the version of the library providing +// instrumentation. +func (cfg MeterConfig) InstrumentationVersion() string { + return cfg.instrumentationVersion } -// WithInstrumentationName sets the instrumentation name. -func WithInstrumentationName(name string) InstrumentOption { - return instrumentationNameOption(name) +// InstrumentationAttributes returns the attributes associated with the library +// providing instrumentation. +func (cfg MeterConfig) InstrumentationAttributes() attribute.Set { + return cfg.attrs } -type instrumentationNameOption string - -func (i instrumentationNameOption) ApplyInstrument(config *InstrumentConfig) { - config.InstrumentationName = string(i) -} - -// MeterConfig contains options for Meters. -type MeterConfig struct { - // InstrumentationVersion is the version of the library providing - // instrumentation. - InstrumentationVersion string +// SchemaURL is the schema_url of the library providing instrumentation. +func (cfg MeterConfig) SchemaURL() string { + return cfg.schemaURL } // MeterOption is an interface for applying Meter options. type MeterOption interface { - // ApplyMeter is used to set a MeterOption value of a MeterConfig. - ApplyMeter(*MeterConfig) + // applyMeter is used to set a MeterOption value of a MeterConfig. + applyMeter(MeterConfig) MeterConfig } // NewMeterConfig creates a new MeterConfig and applies @@ -100,29 +54,39 @@ type MeterOption interface { func NewMeterConfig(opts ...MeterOption) MeterConfig { var config MeterConfig for _, o := range opts { - o.ApplyMeter(&config) + config = o.applyMeter(config) } return config } -// InstrumentationOption is an interface for applying instrumentation specific -// options. -type InstrumentationOption interface { - InstrumentOption - MeterOption -} +type meterOptionFunc func(MeterConfig) MeterConfig -// WithInstrumentationVersion sets the instrumentation version. -func WithInstrumentationVersion(version string) InstrumentationOption { - return instrumentationVersionOption(version) +func (fn meterOptionFunc) applyMeter(cfg MeterConfig) MeterConfig { + return fn(cfg) } -type instrumentationVersionOption string - -func (i instrumentationVersionOption) ApplyMeter(config *MeterConfig) { - config.InstrumentationVersion = string(i) +// WithInstrumentationVersion sets the instrumentation version. +func WithInstrumentationVersion(version string) MeterOption { + return meterOptionFunc(func(config MeterConfig) MeterConfig { + config.instrumentationVersion = version + return config + }) } -func (i instrumentationVersionOption) ApplyInstrument(config *InstrumentConfig) { - config.InstrumentationVersion = string(i) +// WithInstrumentationAttributes sets the instrumentation attributes. +// +// The passed attributes will be de-duplicated. +func WithInstrumentationAttributes(attr ...attribute.KeyValue) MeterOption { + return meterOptionFunc(func(config MeterConfig) MeterConfig { + config.attrs = attribute.NewSet(attr...) + return config + }) +} + +// WithSchemaURL sets the schema URL. +func WithSchemaURL(schemaURL string) MeterOption { + return meterOptionFunc(func(config MeterConfig) MeterConfig { + config.schemaURL = schemaURL + return config + }) } diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go index 7889ff000f7..ae24e448d91 100644 --- a/vendor/go.opentelemetry.io/otel/metric/doc.go +++ b/vendor/go.opentelemetry.io/otel/metric/doc.go @@ -13,55 +13,158 @@ // limitations under the License. /* -Package metric provides an implementation of the metrics part of the -OpenTelemetry API. +Package metric provides the OpenTelemetry API used to measure metrics about +source code operation. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. +This API is separate from its implementation so the instrumentation built from +it is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official +OpenTelemetry implementation of this API. -Measurements can be made about an operation being performed or the state of a -system in general. These measurements can be crucial to the reliable operation -of code and provide valuable insights about the inner workings of a system. +All measurements made with this package are made via instruments. These +instruments are created by a [Meter] which itself is created by a +[MeterProvider]. Applications need to accept a [MeterProvider] implementation +as a starting point when instrumenting. This can be done directly, or by using +the OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an +appropriately named [Meter] from the accepted [MeterProvider], instrumentation +can then be built from the [Meter]'s instruments. -Measurements are made using instruments provided by this package. The type of -instrument used will depend on the type of measurement being made and of what -part of a system is being measured. +# Instruments -Instruments are categorized as Synchronous or Asynchronous and independently -as Adding or Grouping. Synchronous instruments are called by the user with a -Context. Asynchronous instruments are called by the SDK during collection. -Additive instruments are semantically intended for capturing a sum. Grouping -instruments are intended for capturing a distribution. +Each instrument is designed to make measurements of a particular type. Broadly, +all instruments fall into two overlapping logical categories: asynchronous or +synchronous, and int64 or float64. -Additive instruments may be monotonic, in which case they are non-decreasing -and naturally define a rate. +All synchronous instruments ([Int64Counter], [Int64UpDownCounter], +[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and +[Float64Histogram]) are used to measure the operation and performance of source +code during the source code execution. These instruments only make measurements +when the source code they instrument is run. -The synchronous instrument names are: +All asynchronous instruments ([Int64ObservableCounter], +[Int64ObservableUpDownCounter], [Int64ObservableGauge], +[Float64ObservableCounter], [Float64ObservableUpDownCounter], and +[Float64ObservableGauge]) are used to measure metrics outside of the execution +of source code. They are said to make "observations" via a callback function +called once every measurement collection cycle. - Counter: additive, monotonic - UpDownCounter: additive - ValueRecorder: grouping +Each instrument is also grouped by the value type it measures. Either int64 or +float64. The value being measured will dictate which instrument in these +categories to use. -and the asynchronous instruments are: +Outside of these two broad categories, instruments are described by the +function they are designed to serve. All Counters ([Int64Counter], +[Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are +designed to measure values that never decrease in value, but instead only +incrementally increase in value. UpDownCounters ([Int64UpDownCounter], +[Float64UpDownCounter], [Int64ObservableUpDownCounter], and +[Float64ObservableUpDownCounter]) on the other hand, are designed to measure +values that can increase and decrease. When more information needs to be +conveyed about all the synchronous measurements made during a collection cycle, +a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally, +when just the most recent measurement needs to be conveyed about an +asynchronous measurement, a Gauge ([Int64ObservableGauge] and +[Float64ObservableGauge]) should be used. - SumObserver: additive, monotonic - UpDownSumObserver: additive - ValueObserver: grouping +See the [OpenTelemetry documentation] for more information about instruments +and their intended use. -All instruments are provided with support for either float64 or int64 input -values. +# Measurements -An instrument is created using a Meter. Additionally, a Meter is used to -record batches of synchronous measurements or asynchronous observations. A -Meter is obtained using a MeterProvider. A Meter, like a Tracer, is unique to -the instrumentation it instruments and must be named and versioned when -created with a MeterProvider with the name and version of the instrumentation -library. +Measurements are made by recording values and information about the values with +an instrument. How these measurements are recorded depends on the instrument. -Instrumentation should be designed to accept a MeterProvider from which it can -create its own unique Meter. Alternatively, the registered global -MeterProvider from the go.opentelemetry.io/otel package can be used as a -default. +Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter], +[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and +[Float64Histogram]) are recorded using the instrument methods directly. All +counter instruments have an Add method that is used to measure an increment +value, and all histogram instruments have a Record method to measure a data +point. + +Asynchronous instruments ([Int64ObservableCounter], +[Int64ObservableUpDownCounter], [Int64ObservableGauge], +[Float64ObservableCounter], [Float64ObservableUpDownCounter], and +[Float64ObservableGauge]) record measurements within a callback function. The +callback is registered with the Meter which ensures the callback is called once +per collection cycle. A callback can be registered two ways: during the +instrument's creation using an option, or later using the RegisterCallback +method of the [Meter] that created the instrument. + +If the following criteria are met, an option ([WithInt64Callback] or +[WithFloat64Callback]) can be used during the asynchronous instrument's +creation to register a callback ([Int64Callback] or [Float64Callback], +respectively): + + - The measurement process is known when the instrument is created + - Only that instrument will make a measurement within the callback + - The callback never needs to be unregistered + +If the criteria are not met, use the RegisterCallback method of the [Meter] that +created the instrument to register a [Callback]. + +# API Implementations + +This package does not conform to the standard Go versioning policy, all of its +interfaces may have methods added to them without a package major version bump. +This non-standard API evolution could surprise an uninformed implementation +author. They could unknowingly build their implementation in a way that would +result in a runtime panic for their users that update to the new API. + +The API is designed to help inform an instrumentation author about this +non-standard API evolution. It requires them to choose a default behavior for +unimplemented interface methods. There are three behavior choices they can +make: + + - Compilation failure + - Panic + - Default to another implementation + +All interfaces in this API embed a corresponding interface from +[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default +behavior of their implementations to be a compilation failure, signaling to +their users they need to update to the latest version of that implementation, +they need to embed the corresponding interface from +[go.opentelemetry.io/otel/metric/embedded] in their implementation. For +example, + + import "go.opentelemetry.io/otel/metric/embedded" + + type MeterProvider struct { + embedded.MeterProvider + // ... + } + +If an author wants the default behavior of their implementations to a panic, +they need to embed the API interface directly. + + import "go.opentelemetry.io/otel/metric" + + type MeterProvider struct { + metric.MeterProvider + // ... + } + +This is not a recommended behavior as it could lead to publishing packages that +contain runtime panics when users update other package that use newer versions +of [go.opentelemetry.io/otel/metric]. + +Finally, an author can embed another implementation in theirs. The embedded +implementation will be used for methods not defined by the author. For example, +an author who want to default to silently dropping the call can use +[go.opentelemetry.io/otel/metric/noop]: + + import "go.opentelemetry.io/otel/metric/noop" + + type MeterProvider struct { + noop.MeterProvider + // ... + } + +It is strongly recommended that authors only embed +[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior. +That implementation is the only one OpenTelemetry authors can guarantee will +fully implement all the API interfaces when a user updates their API. + +[OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/ +[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider */ package metric // import "go.opentelemetry.io/otel/metric" diff --git a/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go new file mode 100644 index 00000000000..ae0bdbd2e64 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go @@ -0,0 +1,234 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package embedded provides interfaces embedded within the [OpenTelemetry +// metric API]. +// +// Implementers of the [OpenTelemetry metric API] can embed the relevant type +// from this package into their implementation directly. Doing so will result +// in a compilation error for users when the [OpenTelemetry metric API] is +// extended (which is something that can happen without a major version bump of +// the API package). +// +// [OpenTelemetry metric API]: https://pkg.go.dev/go.opentelemetry.io/otel/metric +package embedded // import "go.opentelemetry.io/otel/metric/embedded" + +// MeterProvider is embedded in +// [go.opentelemetry.io/otel/metric.MeterProvider]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.MeterProvider] if you want users to +// experience a compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/metric.MeterProvider] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type MeterProvider interface{ meterProvider() } + +// Meter is embedded in [go.opentelemetry.io/otel/metric.Meter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Meter] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/metric.Meter] interface +// is extended (which is something that can happen without a major version bump +// of the API package). +type Meter interface{ meter() } + +// Float64Observer is embedded in +// [go.opentelemetry.io/otel/metric.Float64Observer]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64Observer] if you want +// users to experience a compilation error, signaling they need to update to +// your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64Observer] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Float64Observer interface{ float64Observer() } + +// Int64Observer is embedded in +// [go.opentelemetry.io/otel/metric.Int64Observer]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64Observer] if you want users +// to experience a compilation error, signaling they need to update to your +// latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64Observer] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Int64Observer interface{ int64Observer() } + +// Observer is embedded in [go.opentelemetry.io/otel/metric.Observer]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Observer] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/metric.Observer] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Observer interface{ observer() } + +// Registration is embedded in [go.opentelemetry.io/otel/metric.Registration]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Registration] if you want users to +// experience a compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/metric.Registration] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Registration interface{ registration() } + +// Float64Counter is embedded in +// [go.opentelemetry.io/otel/metric.Float64Counter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64Counter] if you want +// users to experience a compilation error, signaling they need to update to +// your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64Counter] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Float64Counter interface{ float64Counter() } + +// Float64Histogram is embedded in +// [go.opentelemetry.io/otel/metric.Float64Histogram]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64Histogram] if you want +// users to experience a compilation error, signaling they need to update to +// your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64Histogram] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Float64Histogram interface{ float64Histogram() } + +// Float64ObservableCounter is embedded in +// [go.opentelemetry.io/otel/metric.Float64ObservableCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64ObservableCounter] if you +// want users to experience a compilation error, signaling they need to update +// to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64ObservableCounter] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Float64ObservableCounter interface{ float64ObservableCounter() } + +// Float64ObservableGauge is embedded in +// [go.opentelemetry.io/otel/metric.Float64ObservableGauge]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64ObservableGauge] if you +// want users to experience a compilation error, signaling they need to update +// to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64ObservableGauge] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Float64ObservableGauge interface{ float64ObservableGauge() } + +// Float64ObservableUpDownCounter is embedded in +// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter] +// if you want users to experience a compilation error, signaling they need to +// update to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Float64ObservableUpDownCounter interface{ float64ObservableUpDownCounter() } + +// Float64UpDownCounter is embedded in +// [go.opentelemetry.io/otel/metric.Float64UpDownCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] if you +// want users to experience a compilation error, signaling they need to update +// to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] interface +// is extended (which is something that can happen without a major version bump +// of the API package). +type Float64UpDownCounter interface{ float64UpDownCounter() } + +// Int64Counter is embedded in +// [go.opentelemetry.io/otel/metric.Int64Counter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64Counter] if you want users +// to experience a compilation error, signaling they need to update to your +// latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64Counter] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Int64Counter interface{ int64Counter() } + +// Int64Histogram is embedded in +// [go.opentelemetry.io/otel/metric.Int64Histogram]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64Histogram] if you want +// users to experience a compilation error, signaling they need to update to +// your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64Histogram] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Int64Histogram interface{ int64Histogram() } + +// Int64ObservableCounter is embedded in +// [go.opentelemetry.io/otel/metric.Int64ObservableCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64ObservableCounter] if you +// want users to experience a compilation error, signaling they need to update +// to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64ObservableCounter] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Int64ObservableCounter interface{ int64ObservableCounter() } + +// Int64ObservableGauge is embedded in +// [go.opentelemetry.io/otel/metric.Int64ObservableGauge]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] if you +// want users to experience a compilation error, signaling they need to update +// to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] interface +// is extended (which is something that can happen without a major version bump +// of the API package). +type Int64ObservableGauge interface{ int64ObservableGauge() } + +// Int64ObservableUpDownCounter is embedded in +// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter] if +// you want users to experience a compilation error, signaling they need to +// update to your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type Int64ObservableUpDownCounter interface{ int64ObservableUpDownCounter() } + +// Int64UpDownCounter is embedded in +// [go.opentelemetry.io/otel/metric.Int64UpDownCounter]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] if you want +// users to experience a compilation error, signaling they need to update to +// your latest implementation, when the +// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Int64UpDownCounter interface{ int64UpDownCounter() } diff --git a/vendor/go.opentelemetry.io/otel/metric/global/metric.go b/vendor/go.opentelemetry.io/otel/metric/global/metric.go deleted file mode 100644 index 8d16d34d486..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/global/metric.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global // import "go.opentelemetry.io/otel/metric/global" - -import ( - "go.opentelemetry.io/otel/internal/global" - "go.opentelemetry.io/otel/metric" -) - -// Meter creates an implementation of the Meter interface from the global -// MeterProvider. The instrumentationName must be the name of the library -// providing instrumentation. This name may be the same as the instrumented -// code only if that code provides built-in instrumentation. If the -// instrumentationName is empty, then a implementation defined default name -// will be used instead. -// -// This is short for MeterProvider().Meter(name) -func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { - return GetMeterProvider().Meter(instrumentationName, opts...) -} - -// GetMeterProvider returns the registered global meter provider. If -// none is registered then a default meter provider is returned that -// forwards the Meter interface to the first registered Meter. -// -// Use the meter provider to create a named meter. E.g. -// meter := global.MeterProvider().Meter("example.com/foo") -// or -// meter := global.Meter("example.com/foo") -func GetMeterProvider() metric.MeterProvider { - return global.MeterProvider() -} - -// SetMeterProvider registers `mp` as the global meter provider. -func SetMeterProvider(mp metric.MeterProvider) { - global.SetMeterProvider(mp) -} diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go new file mode 100644 index 00000000000..cdca00058c6 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go @@ -0,0 +1,334 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import "go.opentelemetry.io/otel/attribute" + +// Observable is used as a grouping mechanism for all instruments that are +// updated within a Callback. +type Observable interface { + observable() +} + +// InstrumentOption applies options to all instruments. +type InstrumentOption interface { + Int64CounterOption + Int64UpDownCounterOption + Int64HistogramOption + Int64ObservableCounterOption + Int64ObservableUpDownCounterOption + Int64ObservableGaugeOption + + Float64CounterOption + Float64UpDownCounterOption + Float64HistogramOption + Float64ObservableCounterOption + Float64ObservableUpDownCounterOption + Float64ObservableGaugeOption +} + +type descOpt string + +func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig { + c.description = string(o) + return c +} + +func (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { + c.description = string(o) + return c +} + +// WithDescription sets the instrument description. +func WithDescription(desc string) InstrumentOption { return descOpt(desc) } + +type unitOpt string + +func (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig { + c.unit = string(o) + return c +} + +func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { + c.unit = string(o) + return c +} + +// WithUnit sets the instrument unit. +// +// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code. +func WithUnit(u string) InstrumentOption { return unitOpt(u) } + +// AddOption applies options to an addition measurement. See +// [MeasurementOption] for other options that can be used as an AddOption. +type AddOption interface { + applyAdd(AddConfig) AddConfig +} + +// AddConfig contains options for an addition measurement. +type AddConfig struct { + attrs attribute.Set +} + +// NewAddConfig returns a new [AddConfig] with all opts applied. +func NewAddConfig(opts []AddOption) AddConfig { + config := AddConfig{attrs: *attribute.EmptySet()} + for _, o := range opts { + config = o.applyAdd(config) + } + return config +} + +// Attributes returns the configured attribute set. +func (c AddConfig) Attributes() attribute.Set { + return c.attrs +} + +// RecordOption applies options to an addition measurement. See +// [MeasurementOption] for other options that can be used as a RecordOption. +type RecordOption interface { + applyRecord(RecordConfig) RecordConfig +} + +// RecordConfig contains options for a recorded measurement. +type RecordConfig struct { + attrs attribute.Set +} + +// NewRecordConfig returns a new [RecordConfig] with all opts applied. +func NewRecordConfig(opts []RecordOption) RecordConfig { + config := RecordConfig{attrs: *attribute.EmptySet()} + for _, o := range opts { + config = o.applyRecord(config) + } + return config +} + +// Attributes returns the configured attribute set. +func (c RecordConfig) Attributes() attribute.Set { + return c.attrs +} + +// ObserveOption applies options to an addition measurement. See +// [MeasurementOption] for other options that can be used as a ObserveOption. +type ObserveOption interface { + applyObserve(ObserveConfig) ObserveConfig +} + +// ObserveConfig contains options for an observed measurement. +type ObserveConfig struct { + attrs attribute.Set +} + +// NewObserveConfig returns a new [ObserveConfig] with all opts applied. +func NewObserveConfig(opts []ObserveOption) ObserveConfig { + config := ObserveConfig{attrs: *attribute.EmptySet()} + for _, o := range opts { + config = o.applyObserve(config) + } + return config +} + +// Attributes returns the configured attribute set. +func (c ObserveConfig) Attributes() attribute.Set { + return c.attrs +} + +// MeasurementOption applies options to all instrument measurement. +type MeasurementOption interface { + AddOption + RecordOption + ObserveOption +} + +type attrOpt struct { + set attribute.Set +} + +// mergeSets returns the union of keys between a and b. Any duplicate keys will +// use the value associated with b. +func mergeSets(a, b attribute.Set) attribute.Set { + // NewMergeIterator uses the first value for any duplicates. + iter := attribute.NewMergeIterator(&b, &a) + merged := make([]attribute.KeyValue, 0, a.Len()+b.Len()) + for iter.Next() { + merged = append(merged, iter.Attribute()) + } + return attribute.NewSet(merged...) +} + +func (o attrOpt) applyAdd(c AddConfig) AddConfig { + switch { + case o.set.Len() == 0: + case c.attrs.Len() == 0: + c.attrs = o.set + default: + c.attrs = mergeSets(c.attrs, o.set) + } + return c +} + +func (o attrOpt) applyRecord(c RecordConfig) RecordConfig { + switch { + case o.set.Len() == 0: + case c.attrs.Len() == 0: + c.attrs = o.set + default: + c.attrs = mergeSets(c.attrs, o.set) + } + return c +} + +func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig { + switch { + case o.set.Len() == 0: + case c.attrs.Len() == 0: + c.attrs = o.set + default: + c.attrs = mergeSets(c.attrs, o.set) + } + return c +} + +// WithAttributeSet sets the attribute Set associated with a measurement is +// made with. +// +// If multiple WithAttributeSet or WithAttributes options are passed the +// attributes will be merged together in the order they are passed. Attributes +// with duplicate keys will use the last value passed. +func WithAttributeSet(attributes attribute.Set) MeasurementOption { + return attrOpt{set: attributes} +} + +// WithAttributes converts attributes into an attribute Set and sets the Set to +// be associated with a measurement. This is shorthand for: +// +// cp := make([]attribute.KeyValue, len(attributes)) +// copy(cp, attributes) +// WithAttributes(attribute.NewSet(cp...)) +// +// [attribute.NewSet] may modify the passed attributes so this will make a copy +// of attributes before creating a set in order to ensure this function is +// concurrent safe. This makes this option function less optimized in +// comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be +// preferred for performance sensitive code. +// +// See [WithAttributeSet] for information about how multiple WithAttributes are +// merged. +func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption { + cp := make([]attribute.KeyValue, len(attributes)) + copy(cp, attributes) + return attrOpt{set: attribute.NewSet(cp...)} +} diff --git a/vendor/go.opentelemetry.io/otel/metric/instrumentkind_string.go b/vendor/go.opentelemetry.io/otel/metric/instrumentkind_string.go deleted file mode 100644 index 2805e22500c..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/instrumentkind_string.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by "stringer -type=InstrumentKind"; DO NOT EDIT. - -package metric - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[ValueRecorderInstrumentKind-0] - _ = x[ValueObserverInstrumentKind-1] - _ = x[CounterInstrumentKind-2] - _ = x[UpDownCounterInstrumentKind-3] - _ = x[SumObserverInstrumentKind-4] - _ = x[UpDownSumObserverInstrumentKind-5] -} - -const _InstrumentKind_name = "ValueRecorderInstrumentKindValueObserverInstrumentKindCounterInstrumentKindUpDownCounterInstrumentKindSumObserverInstrumentKindUpDownSumObserverInstrumentKind" - -var _InstrumentKind_index = [...]uint8{0, 27, 54, 75, 102, 127, 158} - -func (i InstrumentKind) String() string { - if i < 0 || i >= InstrumentKind(len(_InstrumentKind_index)-1) { - return "InstrumentKind(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _InstrumentKind_name[_InstrumentKind_index[i]:_InstrumentKind_index[i+1]] -} diff --git a/vendor/go.opentelemetry.io/otel/metric/meter.go b/vendor/go.opentelemetry.io/otel/metric/meter.go new file mode 100644 index 00000000000..2520bc74af1 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/meter.go @@ -0,0 +1,212 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/embedded" +) + +// MeterProvider provides access to named Meter instances, for instrumenting +// an application or package. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type MeterProvider interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.MeterProvider + + // Meter returns a new Meter with the provided name and configuration. + // + // A Meter should be scoped at most to a single package. The name needs to + // be unique so it does not collide with other names used by + // an application, nor other applications. To achieve this, the import path + // of the instrumentation package is recommended to be used as name. + // + // If the name is empty, then an implementation defined default name will + // be used instead. + Meter(name string, opts ...MeterOption) Meter +} + +// Meter provides access to instrument instances for recording metrics. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Meter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Meter + + // Int64Counter returns a new Int64Counter instrument identified by name + // and configured with options. The instrument is used to synchronously + // record increasing int64 measurements during a computational operation. + Int64Counter(name string, options ...Int64CounterOption) (Int64Counter, error) + // Int64UpDownCounter returns a new Int64UpDownCounter instrument + // identified by name and configured with options. The instrument is used + // to synchronously record int64 measurements during a computational + // operation. + Int64UpDownCounter(name string, options ...Int64UpDownCounterOption) (Int64UpDownCounter, error) + // Int64Histogram returns a new Int64Histogram instrument identified by + // name and configured with options. The instrument is used to + // synchronously record the distribution of int64 measurements during a + // computational operation. + Int64Histogram(name string, options ...Int64HistogramOption) (Int64Histogram, error) + // Int64ObservableCounter returns a new Int64ObservableCounter identified + // by name and configured with options. The instrument is used to + // asynchronously record increasing int64 measurements once per a + // measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithInt64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Int64ObservableCounter(name string, options ...Int64ObservableCounterOption) (Int64ObservableCounter, error) + // Int64ObservableUpDownCounter returns a new Int64ObservableUpDownCounter + // instrument identified by name and configured with options. The + // instrument is used to asynchronously record int64 measurements once per + // a measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithInt64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Int64ObservableUpDownCounter(name string, options ...Int64ObservableUpDownCounterOption) (Int64ObservableUpDownCounter, error) + // Int64ObservableGauge returns a new Int64ObservableGauge instrument + // identified by name and configured with options. The instrument is used + // to asynchronously record instantaneous int64 measurements once per a + // measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithInt64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Int64ObservableGauge(name string, options ...Int64ObservableGaugeOption) (Int64ObservableGauge, error) + + // Float64Counter returns a new Float64Counter instrument identified by + // name and configured with options. The instrument is used to + // synchronously record increasing float64 measurements during a + // computational operation. + Float64Counter(name string, options ...Float64CounterOption) (Float64Counter, error) + // Float64UpDownCounter returns a new Float64UpDownCounter instrument + // identified by name and configured with options. The instrument is used + // to synchronously record float64 measurements during a computational + // operation. + Float64UpDownCounter(name string, options ...Float64UpDownCounterOption) (Float64UpDownCounter, error) + // Float64Histogram returns a new Float64Histogram instrument identified by + // name and configured with options. The instrument is used to + // synchronously record the distribution of float64 measurements during a + // computational operation. + Float64Histogram(name string, options ...Float64HistogramOption) (Float64Histogram, error) + // Float64ObservableCounter returns a new Float64ObservableCounter + // instrument identified by name and configured with options. The + // instrument is used to asynchronously record increasing float64 + // measurements once per a measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithFloat64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Float64ObservableCounter(name string, options ...Float64ObservableCounterOption) (Float64ObservableCounter, error) + // Float64ObservableUpDownCounter returns a new + // Float64ObservableUpDownCounter instrument identified by name and + // configured with options. The instrument is used to asynchronously record + // float64 measurements once per a measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithFloat64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Float64ObservableUpDownCounter(name string, options ...Float64ObservableUpDownCounterOption) (Float64ObservableUpDownCounter, error) + // Float64ObservableGauge returns a new Float64ObservableGauge instrument + // identified by name and configured with options. The instrument is used + // to asynchronously record instantaneous float64 measurements once per a + // measurement collection cycle. + // + // Measurements for the returned instrument are made via a callback. Use + // the WithFloat64Callback option to register the callback here, or use the + // RegisterCallback method of this Meter to register one later. See the + // Measurements section of the package documentation for more information. + Float64ObservableGauge(name string, options ...Float64ObservableGaugeOption) (Float64ObservableGauge, error) + + // RegisterCallback registers f to be called during the collection of a + // measurement cycle. + // + // If Unregister of the returned Registration is called, f needs to be + // unregistered and not called during collection. + // + // The instruments f is registered with are the only instruments that f may + // observe values for. + // + // If no instruments are passed, f should not be registered nor called + // during collection. + // + // The function f needs to be concurrent safe. + RegisterCallback(f Callback, instruments ...Observable) (Registration, error) +} + +// Callback is a function registered with a Meter that makes observations for +// the set of instruments it is registered with. The Observer parameter is used +// to record measurement observations for these instruments. +// +// The function needs to complete in a finite amount of time and the deadline +// of the passed context is expected to be honored. +// +// The function needs to make unique observations across all registered +// Callbacks. Meaning, it should not report measurements for an instrument with +// the same attributes as another Callback will report. +// +// The function needs to be concurrent safe. +type Callback func(context.Context, Observer) error + +// Observer records measurements for multiple instruments in a Callback. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Observer interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Observer + + // ObserveFloat64 records the float64 value for obsrv. + ObserveFloat64(obsrv Float64Observable, value float64, opts ...ObserveOption) + // ObserveInt64 records the int64 value for obsrv. + ObserveInt64(obsrv Int64Observable, value int64, opts ...ObserveOption) +} + +// Registration is an token representing the unique registration of a callback +// for a set of instruments with a Meter. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Registration interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Registration + + // Unregister removes the callback registration from a Meter. + // + // This method needs to be idempotent and concurrent safe. + Unregister() error +} diff --git a/vendor/go.opentelemetry.io/otel/metric/metric.go b/vendor/go.opentelemetry.io/otel/metric/metric.go deleted file mode 100644 index b591985df68..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/metric.go +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/unit" -) - -// MeterProvider supports named Meter instances. -type MeterProvider interface { - // Meter creates an implementation of the Meter interface. - // The instrumentationName must be the name of the library providing - // instrumentation. This name may be the same as the instrumented code - // only if that code provides built-in instrumentation. If the - // instrumentationName is empty, then a implementation defined default - // name will be used instead. - Meter(instrumentationName string, opts ...MeterOption) Meter -} - -// Meter is the creator of metric instruments. -// -// An uninitialized Meter is a no-op implementation. -type Meter struct { - impl MeterImpl - name, version string -} - -// RecordBatch atomically records a batch of measurements. -func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) { - if m.impl == nil { - return - } - m.impl.RecordBatch(ctx, ls, ms...) -} - -// NewBatchObserver creates a new BatchObserver that supports -// making batches of observations for multiple instruments. -func (m Meter) NewBatchObserver(callback BatchObserverFunc) BatchObserver { - return BatchObserver{ - meter: m, - runner: newBatchAsyncRunner(callback), - } -} - -// NewInt64Counter creates a new integer Counter instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) { - return wrapInt64CounterInstrument( - m.newSync(name, CounterInstrumentKind, number.Int64Kind, options)) -} - -// NewFloat64Counter creates a new floating point Counter with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) { - return wrapFloat64CounterInstrument( - m.newSync(name, CounterInstrumentKind, number.Float64Kind, options)) -} - -// NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) { - return wrapInt64UpDownCounterInstrument( - m.newSync(name, UpDownCounterInstrumentKind, number.Int64Kind, options)) -} - -// NewFloat64UpDownCounter creates a new floating point UpDownCounter with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) { - return wrapFloat64UpDownCounterInstrument( - m.newSync(name, UpDownCounterInstrumentKind, number.Float64Kind, options)) -} - -// NewInt64ValueRecorder creates a new integer ValueRecorder instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64ValueRecorder(name string, opts ...InstrumentOption) (Int64ValueRecorder, error) { - return wrapInt64ValueRecorderInstrument( - m.newSync(name, ValueRecorderInstrumentKind, number.Int64Kind, opts)) -} - -// NewFloat64ValueRecorder creates a new floating point ValueRecorder with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64ValueRecorder(name string, opts ...InstrumentOption) (Float64ValueRecorder, error) { - return wrapFloat64ValueRecorderInstrument( - m.newSync(name, ValueRecorderInstrumentKind, number.Float64Kind, opts)) -} - -// NewInt64ValueObserver creates a new integer ValueObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64ValueObserver, error) { - if callback == nil { - return wrapInt64ValueObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64ValueObserverInstrument( - m.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64ValueObserver creates a new floating point ValueObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64ValueObserver, error) { - if callback == nil { - return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64ValueObserverInstrument( - m.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64SumObserver creates a new integer SumObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64SumObserver, error) { - if callback == nil { - return wrapInt64SumObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64SumObserverInstrument( - m.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64SumObserver creates a new floating point SumObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64SumObserver, error) { - if callback == nil { - return wrapFloat64SumObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64SumObserverInstrument( - m.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownSumObserver, error) { - if callback == nil { - return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64UpDownSumObserverInstrument( - m.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownSumObserver, error) { - if callback == nil { - return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64UpDownSumObserverInstrument( - m.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64ValueObserver creates a new integer ValueObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64ValueObserver(name string, opts ...InstrumentOption) (Int64ValueObserver, error) { - if b.runner == nil { - return wrapInt64ValueObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64ValueObserverInstrument( - b.meter.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64ValueObserver creates a new floating point ValueObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...InstrumentOption) (Float64ValueObserver, error) { - if b.runner == nil { - return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64ValueObserverInstrument( - b.meter.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// NewInt64SumObserver creates a new integer SumObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64SumObserver(name string, opts ...InstrumentOption) (Int64SumObserver, error) { - if b.runner == nil { - return wrapInt64SumObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64SumObserverInstrument( - b.meter.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64SumObserver creates a new floating point SumObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64SumObserver(name string, opts ...InstrumentOption) (Float64SumObserver, error) { - if b.runner == nil { - return wrapFloat64SumObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64SumObserverInstrument( - b.meter.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...InstrumentOption) (Int64UpDownSumObserver, error) { - if b.runner == nil { - return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil) - } - return wrapInt64UpDownSumObserverInstrument( - b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64UpDownSumObserver(name string, opts ...InstrumentOption) (Float64UpDownSumObserver, error) { - if b.runner == nil { - return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil) - } - return wrapFloat64UpDownSumObserverInstrument( - b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// MeterImpl returns the underlying MeterImpl of this Meter. -func (m Meter) MeterImpl() MeterImpl { - return m.impl -} - -// newAsync constructs one new asynchronous instrument. -func (m Meter) newAsync( - name string, - mkind InstrumentKind, - nkind number.Kind, - opts []InstrumentOption, - runner AsyncRunner, -) ( - AsyncImpl, - error, -) { - if m.impl == nil { - return NoopAsync{}, nil - } - desc := NewDescriptor(name, mkind, nkind, opts...) - desc.config.InstrumentationName = m.name - desc.config.InstrumentationVersion = m.version - return m.impl.NewAsyncInstrument(desc, runner) -} - -// newSync constructs one new synchronous instrument. -func (m Meter) newSync( - name string, - metricKind InstrumentKind, - numberKind number.Kind, - opts []InstrumentOption, -) ( - SyncImpl, - error, -) { - if m.impl == nil { - return NoopSync{}, nil - } - desc := NewDescriptor(name, metricKind, numberKind, opts...) - desc.config.InstrumentationName = m.name - desc.config.InstrumentationVersion = m.version - return m.impl.NewSyncInstrument(desc) -} - -// MeterMust is a wrapper for Meter interfaces that panics when any -// instrument constructor encounters an error. -type MeterMust struct { - meter Meter -} - -// BatchObserverMust is a wrapper for BatchObserver that panics when -// any instrument constructor encounters an error. -type BatchObserverMust struct { - batch BatchObserver -} - -// Must constructs a MeterMust implementation from a Meter, allowing -// the application to panic when any instrument constructor yields an -// error. -func Must(meter Meter) MeterMust { - return MeterMust{meter: meter} -} - -// NewInt64Counter calls `Meter.NewInt64Counter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter { - if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter { - if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter { - if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter { - if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64ValueRecorder calls `Meter.NewInt64ValueRecorder` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...InstrumentOption) Int64ValueRecorder { - if inst, err := mm.meter.NewInt64ValueRecorder(name, mos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64ValueRecorder calls `Meter.NewFloat64ValueRecorder` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...InstrumentOption) Float64ValueRecorder { - if inst, err := mm.meter.NewFloat64ValueRecorder(name, mos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64ValueObserver calls `Meter.NewInt64ValueObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64ValueObserver { - if inst, err := mm.meter.NewInt64ValueObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64ValueObserver calls `Meter.NewFloat64ValueObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64ValueObserver { - if inst, err := mm.meter.NewFloat64ValueObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64SumObserver calls `Meter.NewInt64SumObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64SumObserver { - if inst, err := mm.meter.NewInt64SumObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64SumObserver calls `Meter.NewFloat64SumObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64SumObserver { - if inst, err := mm.meter.NewFloat64SumObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownSumObserver calls `Meter.NewInt64UpDownSumObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownSumObserver { - if inst, err := mm.meter.NewInt64UpDownSumObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownSumObserver calls `Meter.NewFloat64UpDownSumObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownSumObserver { - if inst, err := mm.meter.NewFloat64UpDownSumObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewBatchObserver returns a wrapper around BatchObserver that panics -// when any instrument constructor returns an error. -func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust { - return BatchObserverMust{ - batch: mm.meter.NewBatchObserver(callback), - } -} - -// NewInt64ValueObserver calls `BatchObserver.NewInt64ValueObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...InstrumentOption) Int64ValueObserver { - if inst, err := bm.batch.NewInt64ValueObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64ValueObserver calls `BatchObserver.NewFloat64ValueObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...InstrumentOption) Float64ValueObserver { - if inst, err := bm.batch.NewFloat64ValueObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64SumObserver calls `BatchObserver.NewInt64SumObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...InstrumentOption) Int64SumObserver { - if inst, err := bm.batch.NewInt64SumObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64SumObserver calls `BatchObserver.NewFloat64SumObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...InstrumentOption) Float64SumObserver { - if inst, err := bm.batch.NewFloat64SumObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownSumObserver calls `BatchObserver.NewInt64UpDownSumObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...InstrumentOption) Int64UpDownSumObserver { - if inst, err := bm.batch.NewInt64UpDownSumObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownSumObserver calls `BatchObserver.NewFloat64UpDownSumObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...InstrumentOption) Float64UpDownSumObserver { - if inst, err := bm.batch.NewFloat64UpDownSumObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// Descriptor contains all the settings that describe an instrument, -// including its name, metric kind, number kind, and the configurable -// options. -type Descriptor struct { - name string - instrumentKind InstrumentKind - numberKind number.Kind - config InstrumentConfig -} - -// NewDescriptor returns a Descriptor with the given contents. -func NewDescriptor(name string, ikind InstrumentKind, nkind number.Kind, opts ...InstrumentOption) Descriptor { - return Descriptor{ - name: name, - instrumentKind: ikind, - numberKind: nkind, - config: NewInstrumentConfig(opts...), - } -} - -// Name returns the metric instrument's name. -func (d Descriptor) Name() string { - return d.name -} - -// InstrumentKind returns the specific kind of instrument. -func (d Descriptor) InstrumentKind() InstrumentKind { - return d.instrumentKind -} - -// Description provides a human-readable description of the metric -// instrument. -func (d Descriptor) Description() string { - return d.config.Description -} - -// Unit describes the units of the metric instrument. Unitless -// metrics return the empty string. -func (d Descriptor) Unit() unit.Unit { - return d.config.Unit -} - -// NumberKind returns whether this instrument is declared over int64, -// float64, or uint64 values. -func (d Descriptor) NumberKind() number.Kind { - return d.numberKind -} - -// InstrumentationName returns the name of the library that provided -// instrumentation for this instrument. -func (d Descriptor) InstrumentationName() string { - return d.config.InstrumentationName -} - -// InstrumentationVersion returns the version of the library that provided -// instrumentation for this instrument. -func (d Descriptor) InstrumentationVersion() string { - return d.config.InstrumentationVersion -} diff --git a/vendor/go.opentelemetry.io/otel/metric/metric_instrument.go b/vendor/go.opentelemetry.io/otel/metric/metric_instrument.go deleted file mode 100644 index 6f3fc997cb9..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/metric_instrument.go +++ /dev/null @@ -1,777 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:generate stringer -type=InstrumentKind - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - "errors" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" -) - -// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil. -var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation") - -// InstrumentKind describes the kind of instrument. -type InstrumentKind int8 - -const ( - // ValueRecorderInstrumentKind indicates a ValueRecorder instrument. - ValueRecorderInstrumentKind InstrumentKind = iota - // ValueObserverInstrumentKind indicates an ValueObserver instrument. - ValueObserverInstrumentKind - - // CounterInstrumentKind indicates a Counter instrument. - CounterInstrumentKind - // UpDownCounterInstrumentKind indicates a UpDownCounter instrument. - UpDownCounterInstrumentKind - - // SumObserverInstrumentKind indicates a SumObserver instrument. - SumObserverInstrumentKind - // UpDownSumObserverInstrumentKind indicates a UpDownSumObserver - // instrument. - UpDownSumObserverInstrumentKind -) - -// Synchronous returns whether this is a synchronous kind of instrument. -func (k InstrumentKind) Synchronous() bool { - switch k { - case CounterInstrumentKind, UpDownCounterInstrumentKind, ValueRecorderInstrumentKind: - return true - } - return false -} - -// Asynchronous returns whether this is an asynchronous kind of instrument. -func (k InstrumentKind) Asynchronous() bool { - return !k.Synchronous() -} - -// Adding returns whether this kind of instrument adds its inputs (as opposed to Grouping). -func (k InstrumentKind) Adding() bool { - switch k { - case CounterInstrumentKind, UpDownCounterInstrumentKind, SumObserverInstrumentKind, UpDownSumObserverInstrumentKind: - return true - } - return false -} - -// Grouping returns whether this kind of instrument groups its inputs (as opposed to Adding). -func (k InstrumentKind) Grouping() bool { - return !k.Adding() -} - -// Monotonic returns whether this kind of instrument exposes a non-decreasing sum. -func (k InstrumentKind) Monotonic() bool { - switch k { - case CounterInstrumentKind, SumObserverInstrumentKind: - return true - } - return false -} - -// PrecomputedSum returns whether this kind of instrument receives precomputed sums. -func (k InstrumentKind) PrecomputedSum() bool { - return k.Adding() && k.Asynchronous() -} - -// Observation is used for reporting an asynchronous batch of metric -// values. Instances of this type should be created by asynchronous -// instruments (e.g., Int64ValueObserver.Observation()). -type Observation struct { - // number needs to be aligned for 64-bit atomic operations. - number number.Number - instrument AsyncImpl -} - -// Int64ObserverFunc is a type of callback that integral -// observers run. -type Int64ObserverFunc func(context.Context, Int64ObserverResult) - -// Float64ObserverFunc is a type of callback that floating point -// observers run. -type Float64ObserverFunc func(context.Context, Float64ObserverResult) - -// BatchObserverFunc is a callback argument for use with any -// Observer instrument that will be reported as a batch of -// observations. -type BatchObserverFunc func(context.Context, BatchObserverResult) - -// Int64ObserverResult is passed to an observer callback to capture -// observations for one asynchronous integer metric instrument. -type Int64ObserverResult struct { - instrument AsyncImpl - function func([]attribute.KeyValue, ...Observation) -} - -// Float64ObserverResult is passed to an observer callback to capture -// observations for one asynchronous floating point metric instrument. -type Float64ObserverResult struct { - instrument AsyncImpl - function func([]attribute.KeyValue, ...Observation) -} - -// BatchObserverResult is passed to a batch observer callback to -// capture observations for multiple asynchronous instruments. -type BatchObserverResult struct { - function func([]attribute.KeyValue, ...Observation) -} - -// Observe captures a single integer value from the associated -// instrument callback, with the given labels. -func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) { - ir.function(labels, Observation{ - instrument: ir.instrument, - number: number.NewInt64Number(value), - }) -} - -// Observe captures a single floating point value from the associated -// instrument callback, with the given labels. -func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) { - fr.function(labels, Observation{ - instrument: fr.instrument, - number: number.NewFloat64Number(value), - }) -} - -// Observe captures a multiple observations from the associated batch -// instrument callback, with the given labels. -func (br BatchObserverResult) Observe(labels []attribute.KeyValue, obs ...Observation) { - br.function(labels, obs...) -} - -// AsyncRunner is expected to convert into an AsyncSingleRunner or an -// AsyncBatchRunner. SDKs will encounter an error if the AsyncRunner -// does not satisfy one of these interfaces. -type AsyncRunner interface { - // AnyRunner() is a non-exported method with no functional use - // other than to make this a non-empty interface. - AnyRunner() -} - -// AsyncSingleRunner is an interface implemented by single-observer -// callbacks. -type AsyncSingleRunner interface { - // Run accepts a single instrument and function for capturing - // observations of that instrument. Each call to the function - // receives one captured observation. (The function accepts - // multiple observations so the same implementation can be - // used for batch runners.) - Run(ctx context.Context, single AsyncImpl, capture func([]attribute.KeyValue, ...Observation)) - - AsyncRunner -} - -// AsyncBatchRunner is an interface implemented by batch-observer -// callbacks. -type AsyncBatchRunner interface { - // Run accepts a function for capturing observations of - // multiple instruments. - Run(ctx context.Context, capture func([]attribute.KeyValue, ...Observation)) - - AsyncRunner -} - -var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil) -var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil) -var _ AsyncBatchRunner = (*BatchObserverFunc)(nil) - -// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments. -func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner { - return &c -} - -// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments. -func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner { - return &c -} - -// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments. -func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner { - return &c -} - -// AnyRunner implements AsyncRunner. -func (*Int64ObserverFunc) AnyRunner() {} - -// AnyRunner implements AsyncRunner. -func (*Float64ObserverFunc) AnyRunner() {} - -// AnyRunner implements AsyncRunner. -func (*BatchObserverFunc) AnyRunner() {} - -// Run implements AsyncSingleRunner. -func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { - (*i)(ctx, Int64ObserverResult{ - instrument: impl, - function: function, - }) -} - -// Run implements AsyncSingleRunner. -func (f *Float64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { - (*f)(ctx, Float64ObserverResult{ - instrument: impl, - function: function, - }) -} - -// Run implements AsyncBatchRunner. -func (b *BatchObserverFunc) Run(ctx context.Context, function func([]attribute.KeyValue, ...Observation)) { - (*b)(ctx, BatchObserverResult{ - function: function, - }) -} - -// wrapInt64ValueObserverInstrument converts an AsyncImpl into Int64ValueObserver. -func wrapInt64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Int64ValueObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64ValueObserver{asyncInstrument: common}, err -} - -// wrapFloat64ValueObserverInstrument converts an AsyncImpl into Float64ValueObserver. -func wrapFloat64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Float64ValueObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64ValueObserver{asyncInstrument: common}, err -} - -// wrapInt64SumObserverInstrument converts an AsyncImpl into Int64SumObserver. -func wrapInt64SumObserverInstrument(asyncInst AsyncImpl, err error) (Int64SumObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64SumObserver{asyncInstrument: common}, err -} - -// wrapFloat64SumObserverInstrument converts an AsyncImpl into Float64SumObserver. -func wrapFloat64SumObserverInstrument(asyncInst AsyncImpl, err error) (Float64SumObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64SumObserver{asyncInstrument: common}, err -} - -// wrapInt64UpDownSumObserverInstrument converts an AsyncImpl into Int64UpDownSumObserver. -func wrapInt64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Int64UpDownSumObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64UpDownSumObserver{asyncInstrument: common}, err -} - -// wrapFloat64UpDownSumObserverInstrument converts an AsyncImpl into Float64UpDownSumObserver. -func wrapFloat64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Float64UpDownSumObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64UpDownSumObserver{asyncInstrument: common}, err -} - -// BatchObserver represents an Observer callback that can report -// observations for multiple instruments. -type BatchObserver struct { - meter Meter - runner AsyncBatchRunner -} - -// Int64ValueObserver is a metric that captures a set of int64 values at a -// point in time. -type Int64ValueObserver struct { - asyncInstrument -} - -// Float64ValueObserver is a metric that captures a set of float64 values -// at a point in time. -type Float64ValueObserver struct { - asyncInstrument -} - -// Int64SumObserver is a metric that captures a precomputed sum of -// int64 values at a point in time. -type Int64SumObserver struct { - asyncInstrument -} - -// Float64SumObserver is a metric that captures a precomputed sum of -// float64 values at a point in time. -type Float64SumObserver struct { - asyncInstrument -} - -// Int64UpDownSumObserver is a metric that captures a precomputed sum of -// int64 values at a point in time. -type Int64UpDownSumObserver struct { - asyncInstrument -} - -// Float64UpDownSumObserver is a metric that captures a precomputed sum of -// float64 values at a point in time. -type Float64UpDownSumObserver struct { - asyncInstrument -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64ValueObserver) Observation(v int64) Observation { - return Observation{ - number: number.NewInt64Number(v), - instrument: i.instrument, - } -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64ValueObserver) Observation(v float64) Observation { - return Observation{ - number: number.NewFloat64Number(v), - instrument: f.instrument, - } -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64SumObserver) Observation(v int64) Observation { - return Observation{ - number: number.NewInt64Number(v), - instrument: i.instrument, - } -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64SumObserver) Observation(v float64) Observation { - return Observation{ - number: number.NewFloat64Number(v), - instrument: f.instrument, - } -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64UpDownSumObserver) Observation(v int64) Observation { - return Observation{ - number: number.NewInt64Number(v), - instrument: i.instrument, - } -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64UpDownSumObserver) Observation(v float64) Observation { - return Observation{ - number: number.NewFloat64Number(v), - instrument: f.instrument, - } -} - -// Measurement is used for reporting a synchronous batch of metric -// values. Instances of this type should be created by synchronous -// instruments (e.g., Int64Counter.Measurement()). -type Measurement struct { - // number needs to be aligned for 64-bit atomic operations. - number number.Number - instrument SyncImpl -} - -// syncInstrument contains a SyncImpl. -type syncInstrument struct { - instrument SyncImpl -} - -// syncBoundInstrument contains a BoundSyncImpl. -type syncBoundInstrument struct { - boundInstrument BoundSyncImpl -} - -// asyncInstrument contains a AsyncImpl. -type asyncInstrument struct { - instrument AsyncImpl -} - -// SyncImpl returns the instrument that created this measurement. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (m Measurement) SyncImpl() SyncImpl { - return m.instrument -} - -// Number returns a number recorded in this measurement. -func (m Measurement) Number() number.Number { - return m.number -} - -// AsyncImpl returns the instrument that created this observation. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (m Observation) AsyncImpl() AsyncImpl { - return m.instrument -} - -// Number returns a number recorded in this observation. -func (m Observation) Number() number.Number { - return m.number -} - -// AsyncImpl implements AsyncImpl. -func (a asyncInstrument) AsyncImpl() AsyncImpl { - return a.instrument -} - -// SyncImpl returns the implementation object for synchronous instruments. -func (s syncInstrument) SyncImpl() SyncImpl { - return s.instrument -} - -func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument { - return newSyncBoundInstrument(s.instrument.Bind(labels)) -} - -func (s syncInstrument) float64Measurement(value float64) Measurement { - return newMeasurement(s.instrument, number.NewFloat64Number(value)) -} - -func (s syncInstrument) int64Measurement(value int64) Measurement { - return newMeasurement(s.instrument, number.NewInt64Number(value)) -} - -func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []attribute.KeyValue) { - s.instrument.RecordOne(ctx, number, labels) -} - -func (h syncBoundInstrument) directRecord(ctx context.Context, number number.Number) { - h.boundInstrument.RecordOne(ctx, number) -} - -// Unbind calls SyncImpl.Unbind. -func (h syncBoundInstrument) Unbind() { - h.boundInstrument.Unbind() -} - -// checkNewAsync receives an AsyncImpl and potential -// error, and returns the same types, checking for and ensuring that -// the returned interface is not nil. -func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) { - if instrument == nil { - if err == nil { - err = ErrSDKReturnedNilImpl - } - instrument = NoopAsync{} - } - return asyncInstrument{ - instrument: instrument, - }, err -} - -// checkNewSync receives an SyncImpl and potential -// error, and returns the same types, checking for and ensuring that -// the returned interface is not nil. -func checkNewSync(instrument SyncImpl, err error) (syncInstrument, error) { - if instrument == nil { - if err == nil { - err = ErrSDKReturnedNilImpl - } - // Note: an alternate behavior would be to synthesize a new name - // or group all duplicately-named instruments of a certain type - // together and use a tag for the original name, e.g., - // name = 'invalid.counter.int64' - // label = 'original-name=duplicate-counter-name' - instrument = NoopSync{} - } - return syncInstrument{ - instrument: instrument, - }, err -} - -func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument { - return syncBoundInstrument{ - boundInstrument: boundInstrument, - } -} - -func newMeasurement(instrument SyncImpl, number number.Number) Measurement { - return Measurement{ - instrument: instrument, - number: number, - } -} - -// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter. -func wrapInt64CounterInstrument(syncInst SyncImpl, err error) (Int64Counter, error) { - common, err := checkNewSync(syncInst, err) - return Int64Counter{syncInstrument: common}, err -} - -// wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter. -func wrapFloat64CounterInstrument(syncInst SyncImpl, err error) (Float64Counter, error) { - common, err := checkNewSync(syncInst, err) - return Float64Counter{syncInstrument: common}, err -} - -// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter. -func wrapInt64UpDownCounterInstrument(syncInst SyncImpl, err error) (Int64UpDownCounter, error) { - common, err := checkNewSync(syncInst, err) - return Int64UpDownCounter{syncInstrument: common}, err -} - -// wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter. -func wrapFloat64UpDownCounterInstrument(syncInst SyncImpl, err error) (Float64UpDownCounter, error) { - common, err := checkNewSync(syncInst, err) - return Float64UpDownCounter{syncInstrument: common}, err -} - -// wrapInt64ValueRecorderInstrument converts a SyncImpl into Int64ValueRecorder. -func wrapInt64ValueRecorderInstrument(syncInst SyncImpl, err error) (Int64ValueRecorder, error) { - common, err := checkNewSync(syncInst, err) - return Int64ValueRecorder{syncInstrument: common}, err -} - -// wrapFloat64ValueRecorderInstrument converts a SyncImpl into Float64ValueRecorder. -func wrapFloat64ValueRecorderInstrument(syncInst SyncImpl, err error) (Float64ValueRecorder, error) { - common, err := checkNewSync(syncInst, err) - return Float64ValueRecorder{syncInstrument: common}, err -} - -// Float64Counter is a metric that accumulates float64 values. -type Float64Counter struct { - syncInstrument -} - -// Int64Counter is a metric that accumulates int64 values. -type Int64Counter struct { - syncInstrument -} - -// BoundFloat64Counter is a bound instrument for Float64Counter. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundFloat64Counter struct { - syncBoundInstrument -} - -// BoundInt64Counter is a boundInstrument for Int64Counter. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundInt64Counter struct { - syncBoundInstrument -} - -// Bind creates a bound instrument for this counter. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Float64Counter) Bind(labels ...attribute.KeyValue) (h BoundFloat64Counter) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Bind creates a bound instrument for this counter. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Int64Counter) Bind(labels ...attribute.KeyValue) (h BoundInt64Counter) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64Counter) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64Counter) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Float64Counter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Int64Counter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} - -// Add adds the value to the counter's sum using the labels -// previously bound to this counter via Bind() -func (b BoundFloat64Counter) Add(ctx context.Context, value float64) { - b.directRecord(ctx, number.NewFloat64Number(value)) -} - -// Add adds the value to the counter's sum using the labels -// previously bound to this counter via Bind() -func (b BoundInt64Counter) Add(ctx context.Context, value int64) { - b.directRecord(ctx, number.NewInt64Number(value)) -} - -// Float64UpDownCounter is a metric instrument that sums floating -// point values. -type Float64UpDownCounter struct { - syncInstrument -} - -// Int64UpDownCounter is a metric instrument that sums integer values. -type Int64UpDownCounter struct { - syncInstrument -} - -// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundFloat64UpDownCounter struct { - syncBoundInstrument -} - -// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundInt64UpDownCounter struct { - syncBoundInstrument -} - -// Bind creates a bound instrument for this counter. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Float64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundFloat64UpDownCounter) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Bind creates a bound instrument for this counter. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Int64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundInt64UpDownCounter) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64UpDownCounter) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64UpDownCounter) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} - -// Add adds the value to the counter's sum using the labels -// previously bound to this counter via Bind() -func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) { - b.directRecord(ctx, number.NewFloat64Number(value)) -} - -// Add adds the value to the counter's sum using the labels -// previously bound to this counter via Bind() -func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) { - b.directRecord(ctx, number.NewInt64Number(value)) -} - -// Float64ValueRecorder is a metric that records float64 values. -type Float64ValueRecorder struct { - syncInstrument -} - -// Int64ValueRecorder is a metric that records int64 values. -type Int64ValueRecorder struct { - syncInstrument -} - -// BoundFloat64ValueRecorder is a bound instrument for Float64ValueRecorder. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundFloat64ValueRecorder struct { - syncBoundInstrument -} - -// BoundInt64ValueRecorder is a bound instrument for Int64ValueRecorder. -// -// It inherits the Unbind function from syncBoundInstrument. -type BoundInt64ValueRecorder struct { - syncBoundInstrument -} - -// Bind creates a bound instrument for this ValueRecorder. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Float64ValueRecorder) Bind(labels ...attribute.KeyValue) (h BoundFloat64ValueRecorder) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Bind creates a bound instrument for this ValueRecorder. The labels are -// associated with values recorded via subsequent calls to Record. -func (c Int64ValueRecorder) Bind(labels ...attribute.KeyValue) (h BoundInt64ValueRecorder) { - h.syncBoundInstrument = c.bind(labels) - return -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64ValueRecorder) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64ValueRecorder) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Record adds a new value to the list of ValueRecorder's records. The -// labels should contain the keys and values to be associated with -// this value. -func (c Float64ValueRecorder) Record(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Record adds a new value to the ValueRecorder's distribution. The -// labels should contain the keys and values to be associated with -// this value. -func (c Int64ValueRecorder) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} - -// Record adds a new value to the ValueRecorder's distribution using the labels -// previously bound to the ValueRecorder via Bind(). -func (b BoundFloat64ValueRecorder) Record(ctx context.Context, value float64) { - b.directRecord(ctx, number.NewFloat64Number(value)) -} - -// Record adds a new value to the ValueRecorder's distribution using the labels -// previously bound to the ValueRecorder via Bind(). -func (b BoundInt64ValueRecorder) Record(ctx context.Context, value int64) { - b.directRecord(ctx, number.NewInt64Number(value)) -} diff --git a/vendor/go.opentelemetry.io/otel/metric/metric_noop.go b/vendor/go.opentelemetry.io/otel/metric/metric_noop.go deleted file mode 100644 index 30e57b6945b..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/metric_noop.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" -) - -type NoopMeterProvider struct{} - -type noopInstrument struct{} -type noopBoundInstrument struct{} -type NoopSync struct{ noopInstrument } -type NoopAsync struct{ noopInstrument } - -var _ MeterProvider = NoopMeterProvider{} -var _ SyncImpl = NoopSync{} -var _ BoundSyncImpl = noopBoundInstrument{} -var _ AsyncImpl = NoopAsync{} - -func (NoopMeterProvider) Meter(_ string, _ ...MeterOption) Meter { - return Meter{} -} - -func (noopInstrument) Implementation() interface{} { - return nil -} - -func (noopInstrument) Descriptor() Descriptor { - return Descriptor{} -} - -func (noopBoundInstrument) RecordOne(context.Context, number.Number) { -} - -func (noopBoundInstrument) Unbind() { -} - -func (NoopSync) Bind([]attribute.KeyValue) BoundSyncImpl { - return noopBoundInstrument{} -} - -func (NoopSync) RecordOne(context.Context, number.Number, []attribute.KeyValue) { -} diff --git a/vendor/go.opentelemetry.io/otel/metric/metric_sdkapi.go b/vendor/go.opentelemetry.io/otel/metric/metric_sdkapi.go deleted file mode 100644 index 94164f7b485..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/metric_sdkapi.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" -) - -// MeterImpl is the interface an SDK must implement to supply a Meter -// implementation. -type MeterImpl interface { - // RecordBatch atomically records a batch of measurements. - RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurement ...Measurement) - - // NewSyncInstrument returns a newly constructed - // synchronous instrument implementation or an error, should - // one occur. - NewSyncInstrument(descriptor Descriptor) (SyncImpl, error) - - // NewAsyncInstrument returns a newly constructed - // asynchronous instrument implementation or an error, should - // one occur. - NewAsyncInstrument( - descriptor Descriptor, - runner AsyncRunner, - ) (AsyncImpl, error) -} - -// InstrumentImpl is a common interface for synchronous and -// asynchronous instruments. -type InstrumentImpl interface { - // Implementation returns the underlying implementation of the - // instrument, which allows the implementation to gain access - // to its own representation especially from a `Measurement`. - Implementation() interface{} - - // Descriptor returns a copy of the instrument's Descriptor. - Descriptor() Descriptor -} - -// SyncImpl is the implementation-level interface to a generic -// synchronous instrument (e.g., ValueRecorder and Counter instruments). -type SyncImpl interface { - InstrumentImpl - - // Bind creates an implementation-level bound instrument, - // binding a label set with this instrument implementation. - Bind(labels []attribute.KeyValue) BoundSyncImpl - - // RecordOne captures a single synchronous metric event. - RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) -} - -// BoundSyncImpl is the implementation-level interface to a -// generic bound synchronous instrument -type BoundSyncImpl interface { - - // RecordOne captures a single synchronous metric event. - RecordOne(ctx context.Context, number number.Number) - - // Unbind frees the resources associated with this bound instrument. It - // does not affect the metric this bound instrument was created through. - Unbind() -} - -// AsyncImpl is an implementation-level interface to an -// asynchronous instrument (e.g., Observer instruments). -type AsyncImpl interface { - InstrumentImpl -} - -// WrapMeterImpl constructs a `Meter` implementation from a -// `MeterImpl` implementation. -func WrapMeterImpl(impl MeterImpl, instrumentationName string, opts ...MeterOption) Meter { - return Meter{ - impl: impl, - name: instrumentationName, - version: NewMeterConfig(opts...).InstrumentationVersion, - } -} diff --git a/vendor/go.opentelemetry.io/otel/metric/number/doc.go b/vendor/go.opentelemetry.io/otel/metric/number/doc.go deleted file mode 100644 index 0649ff875e7..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/number/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package number provides a number abstraction for instruments that -either support int64 or float64 input values. - -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. -*/ -package number // import "go.opentelemetry.io/otel/metric/number" diff --git a/vendor/go.opentelemetry.io/otel/metric/number/kind_string.go b/vendor/go.opentelemetry.io/otel/metric/number/kind_string.go deleted file mode 100644 index 6288c7ea295..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/number/kind_string.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by "stringer -type=Kind"; DO NOT EDIT. - -package number - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Int64Kind-0] - _ = x[Float64Kind-1] -} - -const _Kind_name = "Int64KindFloat64Kind" - -var _Kind_index = [...]uint8{0, 9, 20} - -func (i Kind) String() string { - if i < 0 || i >= Kind(len(_Kind_index)-1) { - return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] -} diff --git a/vendor/go.opentelemetry.io/otel/metric/number/number.go b/vendor/go.opentelemetry.io/otel/metric/number/number.go deleted file mode 100644 index 3ec95e2014d..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/number/number.go +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package number // import "go.opentelemetry.io/otel/metric/number" - -//go:generate stringer -type=Kind - -import ( - "fmt" - "math" - "sync/atomic" - - "go.opentelemetry.io/otel/internal" -) - -// Kind describes the data type of the Number. -type Kind int8 - -const ( - // Int64Kind means that the Number stores int64. - Int64Kind Kind = iota - // Float64Kind means that the Number stores float64. - Float64Kind -) - -// Zero returns a zero value for a given Kind -func (k Kind) Zero() Number { - switch k { - case Int64Kind: - return NewInt64Number(0) - case Float64Kind: - return NewFloat64Number(0.) - default: - return Number(0) - } -} - -// Minimum returns the minimum representable value -// for a given Kind -func (k Kind) Minimum() Number { - switch k { - case Int64Kind: - return NewInt64Number(math.MinInt64) - case Float64Kind: - return NewFloat64Number(-1. * math.MaxFloat64) - default: - return Number(0) - } -} - -// Maximum returns the maximum representable value -// for a given Kind -func (k Kind) Maximum() Number { - switch k { - case Int64Kind: - return NewInt64Number(math.MaxInt64) - case Float64Kind: - return NewFloat64Number(math.MaxFloat64) - default: - return Number(0) - } -} - -// Number represents either an integral or a floating point value. It -// needs to be accompanied with a source of Kind that describes -// the actual type of the value stored within Number. -type Number uint64 - -// - constructors - -// NewNumberFromRaw creates a new Number from a raw value. -func NewNumberFromRaw(r uint64) Number { - return Number(r) -} - -// NewInt64Number creates an integral Number. -func NewInt64Number(i int64) Number { - return NewNumberFromRaw(internal.Int64ToRaw(i)) -} - -// NewFloat64Number creates a floating point Number. -func NewFloat64Number(f float64) Number { - return NewNumberFromRaw(internal.Float64ToRaw(f)) -} - -// NewNumberSignChange returns a number with the same magnitude and -// the opposite sign. `kind` must describe the kind of number in `nn`. -func NewNumberSignChange(kind Kind, nn Number) Number { - switch kind { - case Int64Kind: - return NewInt64Number(-nn.AsInt64()) - case Float64Kind: - return NewFloat64Number(-nn.AsFloat64()) - } - return nn -} - -// - as x - -// AsNumber gets the Number. -func (n *Number) AsNumber() Number { - return *n -} - -// AsRaw gets the uninterpreted raw value. Might be useful for some -// atomic operations. -func (n *Number) AsRaw() uint64 { - return uint64(*n) -} - -// AsInt64 assumes that the value contains an int64 and returns it as -// such. -func (n *Number) AsInt64() int64 { - return internal.RawToInt64(n.AsRaw()) -} - -// AsFloat64 assumes that the measurement value contains a float64 and -// returns it as such. -func (n *Number) AsFloat64() float64 { - return internal.RawToFloat64(n.AsRaw()) -} - -// - as x atomic - -// AsNumberAtomic gets the Number atomically. -func (n *Number) AsNumberAtomic() Number { - return NewNumberFromRaw(n.AsRawAtomic()) -} - -// AsRawAtomic gets the uninterpreted raw value atomically. Might be -// useful for some atomic operations. -func (n *Number) AsRawAtomic() uint64 { - return atomic.LoadUint64(n.AsRawPtr()) -} - -// AsInt64Atomic assumes that the number contains an int64 and returns -// it as such atomically. -func (n *Number) AsInt64Atomic() int64 { - return atomic.LoadInt64(n.AsInt64Ptr()) -} - -// AsFloat64Atomic assumes that the measurement value contains a -// float64 and returns it as such atomically. -func (n *Number) AsFloat64Atomic() float64 { - return internal.RawToFloat64(n.AsRawAtomic()) -} - -// - as x ptr - -// AsRawPtr gets the pointer to the raw, uninterpreted raw -// value. Might be useful for some atomic operations. -func (n *Number) AsRawPtr() *uint64 { - return (*uint64)(n) -} - -// AsInt64Ptr assumes that the number contains an int64 and returns a -// pointer to it. -func (n *Number) AsInt64Ptr() *int64 { - return internal.RawPtrToInt64Ptr(n.AsRawPtr()) -} - -// AsFloat64Ptr assumes that the number contains a float64 and returns a -// pointer to it. -func (n *Number) AsFloat64Ptr() *float64 { - return internal.RawPtrToFloat64Ptr(n.AsRawPtr()) -} - -// - coerce - -// CoerceToInt64 casts the number to int64. May result in -// data/precision loss. -func (n *Number) CoerceToInt64(kind Kind) int64 { - switch kind { - case Int64Kind: - return n.AsInt64() - case Float64Kind: - return int64(n.AsFloat64()) - default: - // you get what you deserve - return 0 - } -} - -// CoerceToFloat64 casts the number to float64. May result in -// data/precision loss. -func (n *Number) CoerceToFloat64(kind Kind) float64 { - switch kind { - case Int64Kind: - return float64(n.AsInt64()) - case Float64Kind: - return n.AsFloat64() - default: - // you get what you deserve - return 0 - } -} - -// - set - -// SetNumber sets the number to the passed number. Both should be of -// the same kind. -func (n *Number) SetNumber(nn Number) { - *n.AsRawPtr() = nn.AsRaw() -} - -// SetRaw sets the number to the passed raw value. Both number and the -// raw number should represent the same kind. -func (n *Number) SetRaw(r uint64) { - *n.AsRawPtr() = r -} - -// SetInt64 assumes that the number contains an int64 and sets it to -// the passed value. -func (n *Number) SetInt64(i int64) { - *n.AsInt64Ptr() = i -} - -// SetFloat64 assumes that the number contains a float64 and sets it -// to the passed value. -func (n *Number) SetFloat64(f float64) { - *n.AsFloat64Ptr() = f -} - -// - set atomic - -// SetNumberAtomic sets the number to the passed number -// atomically. Both should be of the same kind. -func (n *Number) SetNumberAtomic(nn Number) { - atomic.StoreUint64(n.AsRawPtr(), nn.AsRaw()) -} - -// SetRawAtomic sets the number to the passed raw value -// atomically. Both number and the raw number should represent the -// same kind. -func (n *Number) SetRawAtomic(r uint64) { - atomic.StoreUint64(n.AsRawPtr(), r) -} - -// SetInt64Atomic assumes that the number contains an int64 and sets -// it to the passed value atomically. -func (n *Number) SetInt64Atomic(i int64) { - atomic.StoreInt64(n.AsInt64Ptr(), i) -} - -// SetFloat64Atomic assumes that the number contains a float64 and -// sets it to the passed value atomically. -func (n *Number) SetFloat64Atomic(f float64) { - atomic.StoreUint64(n.AsRawPtr(), internal.Float64ToRaw(f)) -} - -// - swap - -// SwapNumber sets the number to the passed number and returns the old -// number. Both this number and the passed number should be of the -// same kind. -func (n *Number) SwapNumber(nn Number) Number { - old := *n - n.SetNumber(nn) - return old -} - -// SwapRaw sets the number to the passed raw value and returns the old -// raw value. Both number and the raw number should represent the same -// kind. -func (n *Number) SwapRaw(r uint64) uint64 { - old := n.AsRaw() - n.SetRaw(r) - return old -} - -// SwapInt64 assumes that the number contains an int64, sets it to the -// passed value and returns the old int64 value. -func (n *Number) SwapInt64(i int64) int64 { - old := n.AsInt64() - n.SetInt64(i) - return old -} - -// SwapFloat64 assumes that the number contains an float64, sets it to -// the passed value and returns the old float64 value. -func (n *Number) SwapFloat64(f float64) float64 { - old := n.AsFloat64() - n.SetFloat64(f) - return old -} - -// - swap atomic - -// SwapNumberAtomic sets the number to the passed number and returns -// the old number atomically. Both this number and the passed number -// should be of the same kind. -func (n *Number) SwapNumberAtomic(nn Number) Number { - return NewNumberFromRaw(atomic.SwapUint64(n.AsRawPtr(), nn.AsRaw())) -} - -// SwapRawAtomic sets the number to the passed raw value and returns -// the old raw value atomically. Both number and the raw number should -// represent the same kind. -func (n *Number) SwapRawAtomic(r uint64) uint64 { - return atomic.SwapUint64(n.AsRawPtr(), r) -} - -// SwapInt64Atomic assumes that the number contains an int64, sets it -// to the passed value and returns the old int64 value atomically. -func (n *Number) SwapInt64Atomic(i int64) int64 { - return atomic.SwapInt64(n.AsInt64Ptr(), i) -} - -// SwapFloat64Atomic assumes that the number contains an float64, sets -// it to the passed value and returns the old float64 value -// atomically. -func (n *Number) SwapFloat64Atomic(f float64) float64 { - return internal.RawToFloat64(atomic.SwapUint64(n.AsRawPtr(), internal.Float64ToRaw(f))) -} - -// - add - -// AddNumber assumes that this and the passed number are of the passed -// kind and adds the passed number to this number. -func (n *Number) AddNumber(kind Kind, nn Number) { - switch kind { - case Int64Kind: - n.AddInt64(nn.AsInt64()) - case Float64Kind: - n.AddFloat64(nn.AsFloat64()) - } -} - -// AddRaw assumes that this number and the passed raw value are of the -// passed kind and adds the passed raw value to this number. -func (n *Number) AddRaw(kind Kind, r uint64) { - n.AddNumber(kind, NewNumberFromRaw(r)) -} - -// AddInt64 assumes that the number contains an int64 and adds the -// passed int64 to it. -func (n *Number) AddInt64(i int64) { - *n.AsInt64Ptr() += i -} - -// AddFloat64 assumes that the number contains a float64 and adds the -// passed float64 to it. -func (n *Number) AddFloat64(f float64) { - *n.AsFloat64Ptr() += f -} - -// - add atomic - -// AddNumberAtomic assumes that this and the passed number are of the -// passed kind and adds the passed number to this number atomically. -func (n *Number) AddNumberAtomic(kind Kind, nn Number) { - switch kind { - case Int64Kind: - n.AddInt64Atomic(nn.AsInt64()) - case Float64Kind: - n.AddFloat64Atomic(nn.AsFloat64()) - } -} - -// AddRawAtomic assumes that this number and the passed raw value are -// of the passed kind and adds the passed raw value to this number -// atomically. -func (n *Number) AddRawAtomic(kind Kind, r uint64) { - n.AddNumberAtomic(kind, NewNumberFromRaw(r)) -} - -// AddInt64Atomic assumes that the number contains an int64 and adds -// the passed int64 to it atomically. -func (n *Number) AddInt64Atomic(i int64) { - atomic.AddInt64(n.AsInt64Ptr(), i) -} - -// AddFloat64Atomic assumes that the number contains a float64 and -// adds the passed float64 to it atomically. -func (n *Number) AddFloat64Atomic(f float64) { - for { - o := n.AsFloat64Atomic() - if n.CompareAndSwapFloat64(o, o+f) { - break - } - } -} - -// - compare and swap (atomic only) - -// CompareAndSwapNumber does the atomic CAS operation on this -// number. This number and passed old and new numbers should be of the -// same kind. -func (n *Number) CompareAndSwapNumber(on, nn Number) bool { - return atomic.CompareAndSwapUint64(n.AsRawPtr(), on.AsRaw(), nn.AsRaw()) -} - -// CompareAndSwapRaw does the atomic CAS operation on this -// number. This number and passed old and new raw values should be of -// the same kind. -func (n *Number) CompareAndSwapRaw(or, nr uint64) bool { - return atomic.CompareAndSwapUint64(n.AsRawPtr(), or, nr) -} - -// CompareAndSwapInt64 assumes that this number contains an int64 and -// does the atomic CAS operation on it. -func (n *Number) CompareAndSwapInt64(oi, ni int64) bool { - return atomic.CompareAndSwapInt64(n.AsInt64Ptr(), oi, ni) -} - -// CompareAndSwapFloat64 assumes that this number contains a float64 and -// does the atomic CAS operation on it. -func (n *Number) CompareAndSwapFloat64(of, nf float64) bool { - return atomic.CompareAndSwapUint64(n.AsRawPtr(), internal.Float64ToRaw(of), internal.Float64ToRaw(nf)) -} - -// - compare - -// CompareNumber compares two Numbers given their kind. Both numbers -// should have the same kind. This returns: -// 0 if the numbers are equal -// -1 if the subject `n` is less than the argument `nn` -// +1 if the subject `n` is greater than the argument `nn` -func (n *Number) CompareNumber(kind Kind, nn Number) int { - switch kind { - case Int64Kind: - return n.CompareInt64(nn.AsInt64()) - case Float64Kind: - return n.CompareFloat64(nn.AsFloat64()) - default: - // you get what you deserve - return 0 - } -} - -// CompareRaw compares two numbers, where one is input as a raw -// uint64, interpreting both values as a `kind` of number. -func (n *Number) CompareRaw(kind Kind, r uint64) int { - return n.CompareNumber(kind, NewNumberFromRaw(r)) -} - -// CompareInt64 assumes that the Number contains an int64 and performs -// a comparison between the value and the other value. It returns the -// typical result of the compare function: -1 if the value is less -// than the other, 0 if both are equal, 1 if the value is greater than -// the other. -func (n *Number) CompareInt64(i int64) int { - this := n.AsInt64() - if this < i { - return -1 - } else if this > i { - return 1 - } - return 0 -} - -// CompareFloat64 assumes that the Number contains a float64 and -// performs a comparison between the value and the other value. It -// returns the typical result of the compare function: -1 if the value -// is less than the other, 0 if both are equal, 1 if the value is -// greater than the other. -// -// Do not compare NaN values. -func (n *Number) CompareFloat64(f float64) int { - this := n.AsFloat64() - if this < f { - return -1 - } else if this > f { - return 1 - } - return 0 -} - -// - relations to zero - -// IsPositive returns true if the actual value is greater than zero. -func (n *Number) IsPositive(kind Kind) bool { - return n.compareWithZero(kind) > 0 -} - -// IsNegative returns true if the actual value is less than zero. -func (n *Number) IsNegative(kind Kind) bool { - return n.compareWithZero(kind) < 0 -} - -// IsZero returns true if the actual value is equal to zero. -func (n *Number) IsZero(kind Kind) bool { - return n.compareWithZero(kind) == 0 -} - -// - misc - -// Emit returns a string representation of the raw value of the -// Number. A %d is used for integral values, %f for floating point -// values. -func (n *Number) Emit(kind Kind) string { - switch kind { - case Int64Kind: - return fmt.Sprintf("%d", n.AsInt64()) - case Float64Kind: - return fmt.Sprintf("%f", n.AsFloat64()) - default: - return "" - } -} - -// AsInterface returns the number as an interface{}, typically used -// for Kind-correct JSON conversion. -func (n *Number) AsInterface(kind Kind) interface{} { - switch kind { - case Int64Kind: - return n.AsInt64() - case Float64Kind: - return n.AsFloat64() - default: - return math.NaN() - } -} - -// - private stuff - -func (n *Number) compareWithZero(kind Kind) int { - switch kind { - case Int64Kind: - return n.CompareInt64(0) - case Float64Kind: - return n.CompareFloat64(0.) - default: - // you get what you deserve - return 0 - } -} diff --git a/vendor/go.opentelemetry.io/otel/metric/registry/doc.go b/vendor/go.opentelemetry.io/otel/metric/registry/doc.go deleted file mode 100644 index a53ba455455..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/registry/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package registry provides a non-standalone implementation of -MeterProvider that adds uniqueness checking for instrument descriptors -on top of other MeterProvider it wraps. - -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. -*/ -package registry // import "go.opentelemetry.io/otel/metric/registry" diff --git a/vendor/go.opentelemetry.io/otel/metric/registry/registry.go b/vendor/go.opentelemetry.io/otel/metric/registry/registry.go deleted file mode 100644 index 0a42a0fdf8d..00000000000 --- a/vendor/go.opentelemetry.io/otel/metric/registry/registry.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package registry // import "go.opentelemetry.io/otel/metric/registry" - -import ( - "context" - "fmt" - "sync" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" -) - -// MeterProvider is a standard MeterProvider for wrapping `MeterImpl` -type MeterProvider struct { - impl metric.MeterImpl -} - -var _ metric.MeterProvider = (*MeterProvider)(nil) - -// uniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding -// uniqueness checking for instrument descriptors. Use NewUniqueInstrumentMeter -// to wrap an implementation with uniqueness checking. -type uniqueInstrumentMeterImpl struct { - lock sync.Mutex - impl metric.MeterImpl - state map[key]metric.InstrumentImpl -} - -var _ metric.MeterImpl = (*uniqueInstrumentMeterImpl)(nil) - -type key struct { - instrumentName string - instrumentationName string - InstrumentationVersion string -} - -// NewMeterProvider returns a new provider that implements instrument -// name-uniqueness checking. -func NewMeterProvider(impl metric.MeterImpl) *MeterProvider { - return &MeterProvider{ - impl: NewUniqueInstrumentMeterImpl(impl), - } -} - -// Meter implements MeterProvider. -func (p *MeterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { - return metric.WrapMeterImpl(p.impl, instrumentationName, opts...) -} - -// ErrMetricKindMismatch is the standard error for mismatched metric -// instrument definitions. -var ErrMetricKindMismatch = fmt.Errorf( - "a metric was already registered by this name with another kind or number type") - -// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl with -// the addition of uniqueness checking. -func NewUniqueInstrumentMeterImpl(impl metric.MeterImpl) metric.MeterImpl { - return &uniqueInstrumentMeterImpl{ - impl: impl, - state: map[key]metric.InstrumentImpl{}, - } -} - -// RecordBatch implements metric.MeterImpl. -func (u *uniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...metric.Measurement) { - u.impl.RecordBatch(ctx, labels, ms...) -} - -func keyOf(descriptor metric.Descriptor) key { - return key{ - descriptor.Name(), - descriptor.InstrumentationName(), - descriptor.InstrumentationVersion(), - } -} - -// NewMetricKindMismatchError formats an error that describes a -// mismatched metric instrument definition. -func NewMetricKindMismatchError(desc metric.Descriptor) error { - return fmt.Errorf("metric was %s (%s %s)registered as a %s %s: %w", - desc.Name(), - desc.InstrumentationName(), - desc.InstrumentationVersion(), - desc.NumberKind(), - desc.InstrumentKind(), - ErrMetricKindMismatch) -} - -// Compatible determines whether two metric.Descriptors are considered -// the same for the purpose of uniqueness checking. -func Compatible(candidate, existing metric.Descriptor) bool { - return candidate.InstrumentKind() == existing.InstrumentKind() && - candidate.NumberKind() == existing.NumberKind() -} - -// checkUniqueness returns an ErrMetricKindMismatch error if there is -// a conflict between a descriptor that was already registered and the -// `descriptor` argument. If there is an existing compatible -// registration, this returns the already-registered instrument. If -// there is no conflict and no prior registration, returns (nil, nil). -func (u *uniqueInstrumentMeterImpl) checkUniqueness(descriptor metric.Descriptor) (metric.InstrumentImpl, error) { - impl, ok := u.state[keyOf(descriptor)] - if !ok { - return nil, nil - } - - if !Compatible(descriptor, impl.Descriptor()) { - return nil, NewMetricKindMismatchError(impl.Descriptor()) - } - - return impl, nil -} - -// NewSyncInstrument implements metric.MeterImpl. -func (u *uniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) { - u.lock.Lock() - defer u.lock.Unlock() - - impl, err := u.checkUniqueness(descriptor) - - if err != nil { - return nil, err - } else if impl != nil { - return impl.(metric.SyncImpl), nil - } - - syncInst, err := u.impl.NewSyncInstrument(descriptor) - if err != nil { - return nil, err - } - u.state[keyOf(descriptor)] = syncInst - return syncInst, nil -} - -// NewAsyncInstrument implements metric.MeterImpl. -func (u *uniqueInstrumentMeterImpl) NewAsyncInstrument( - descriptor metric.Descriptor, - runner metric.AsyncRunner, -) (metric.AsyncImpl, error) { - u.lock.Lock() - defer u.lock.Unlock() - - impl, err := u.checkUniqueness(descriptor) - - if err != nil { - return nil, err - } else if impl != nil { - return impl.(metric.AsyncImpl), nil - } - - asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner) - if err != nil { - return nil, err - } - u.state[keyOf(descriptor)] = asyncInst - return asyncInst, nil -} diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go new file mode 100644 index 00000000000..f0b063721d8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go @@ -0,0 +1,179 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/embedded" +) + +// Float64Counter is an instrument that records increasing float64 values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64Counter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64Counter + + // Add records a change to the counter. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Add(ctx context.Context, incr float64, options ...AddOption) +} + +// Float64CounterConfig contains options for synchronous counter instruments that +// record int64 values. +type Float64CounterConfig struct { + description string + unit string +} + +// NewFloat64CounterConfig returns a new [Float64CounterConfig] with all opts +// applied. +func NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig { + var config Float64CounterConfig + for _, o := range opts { + config = o.applyFloat64Counter(config) + } + return config +} + +// Description returns the configured description. +func (c Float64CounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64CounterConfig) Unit() string { + return c.unit +} + +// Float64CounterOption applies options to a [Float64CounterConfig]. See +// [InstrumentOption] for other options that can be used as a +// Float64CounterOption. +type Float64CounterOption interface { + applyFloat64Counter(Float64CounterConfig) Float64CounterConfig +} + +// Float64UpDownCounter is an instrument that records increasing or decreasing +// float64 values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64UpDownCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64UpDownCounter + + // Add records a change to the counter. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Add(ctx context.Context, incr float64, options ...AddOption) +} + +// Float64UpDownCounterConfig contains options for synchronous counter +// instruments that record int64 values. +type Float64UpDownCounterConfig struct { + description string + unit string +} + +// NewFloat64UpDownCounterConfig returns a new [Float64UpDownCounterConfig] +// with all opts applied. +func NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig { + var config Float64UpDownCounterConfig + for _, o := range opts { + config = o.applyFloat64UpDownCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Float64UpDownCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64UpDownCounterConfig) Unit() string { + return c.unit +} + +// Float64UpDownCounterOption applies options to a +// [Float64UpDownCounterConfig]. See [InstrumentOption] for other options that +// can be used as a Float64UpDownCounterOption. +type Float64UpDownCounterOption interface { + applyFloat64UpDownCounter(Float64UpDownCounterConfig) Float64UpDownCounterConfig +} + +// Float64Histogram is an instrument that records a distribution of float64 +// values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Float64Histogram interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Float64Histogram + + // Record adds an additional value to the distribution. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Record(ctx context.Context, incr float64, options ...RecordOption) +} + +// Float64HistogramConfig contains options for synchronous counter instruments +// that record int64 values. +type Float64HistogramConfig struct { + description string + unit string +} + +// NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all +// opts applied. +func NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig { + var config Float64HistogramConfig + for _, o := range opts { + config = o.applyFloat64Histogram(config) + } + return config +} + +// Description returns the configured description. +func (c Float64HistogramConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Float64HistogramConfig) Unit() string { + return c.unit +} + +// Float64HistogramOption applies options to a [Float64HistogramConfig]. See +// [InstrumentOption] for other options that can be used as a +// Float64HistogramOption. +type Float64HistogramOption interface { + applyFloat64Histogram(Float64HistogramConfig) Float64HistogramConfig +} diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go new file mode 100644 index 00000000000..6f508eb66d4 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go @@ -0,0 +1,179 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/embedded" +) + +// Int64Counter is an instrument that records increasing int64 values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64Counter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64Counter + + // Add records a change to the counter. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Add(ctx context.Context, incr int64, options ...AddOption) +} + +// Int64CounterConfig contains options for synchronous counter instruments that +// record int64 values. +type Int64CounterConfig struct { + description string + unit string +} + +// NewInt64CounterConfig returns a new [Int64CounterConfig] with all opts +// applied. +func NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig { + var config Int64CounterConfig + for _, o := range opts { + config = o.applyInt64Counter(config) + } + return config +} + +// Description returns the configured description. +func (c Int64CounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64CounterConfig) Unit() string { + return c.unit +} + +// Int64CounterOption applies options to a [Int64CounterConfig]. See +// [InstrumentOption] for other options that can be used as an +// Int64CounterOption. +type Int64CounterOption interface { + applyInt64Counter(Int64CounterConfig) Int64CounterConfig +} + +// Int64UpDownCounter is an instrument that records increasing or decreasing +// int64 values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64UpDownCounter interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64UpDownCounter + + // Add records a change to the counter. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Add(ctx context.Context, incr int64, options ...AddOption) +} + +// Int64UpDownCounterConfig contains options for synchronous counter +// instruments that record int64 values. +type Int64UpDownCounterConfig struct { + description string + unit string +} + +// NewInt64UpDownCounterConfig returns a new [Int64UpDownCounterConfig] with +// all opts applied. +func NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig { + var config Int64UpDownCounterConfig + for _, o := range opts { + config = o.applyInt64UpDownCounter(config) + } + return config +} + +// Description returns the configured description. +func (c Int64UpDownCounterConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64UpDownCounterConfig) Unit() string { + return c.unit +} + +// Int64UpDownCounterOption applies options to a [Int64UpDownCounterConfig]. +// See [InstrumentOption] for other options that can be used as an +// Int64UpDownCounterOption. +type Int64UpDownCounterOption interface { + applyInt64UpDownCounter(Int64UpDownCounterConfig) Int64UpDownCounterConfig +} + +// Int64Histogram is an instrument that records a distribution of int64 +// values. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Int64Histogram interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Int64Histogram + + // Record adds an additional value to the distribution. + // + // Use the WithAttributeSet (or, if performance is not a concern, + // the WithAttributes) option to include measurement attributes. + Record(ctx context.Context, incr int64, options ...RecordOption) +} + +// Int64HistogramConfig contains options for synchronous counter instruments +// that record int64 values. +type Int64HistogramConfig struct { + description string + unit string +} + +// NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts +// applied. +func NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig { + var config Int64HistogramConfig + for _, o := range opts { + config = o.applyInt64Histogram(config) + } + return config +} + +// Description returns the configured description. +func (c Int64HistogramConfig) Description() string { + return c.description +} + +// Unit returns the configured unit. +func (c Int64HistogramConfig) Unit() string { + return c.unit +} + +// Int64HistogramOption applies options to a [Int64HistogramConfig]. See +// [InstrumentOption] for other options that can be used as an +// Int64HistogramOption. +type Int64HistogramOption interface { + applyInt64Histogram(Int64HistogramConfig) Int64HistogramConfig +} diff --git a/vendor/go.opentelemetry.io/otel/pre_release.sh b/vendor/go.opentelemetry.io/otel/pre_release.sh deleted file mode 100644 index 0de22169cfc..00000000000 --- a/vendor/go.opentelemetry.io/otel/pre_release.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -help() -{ - printf "\n" - printf "Usage: $0 -t tag\n" - printf "\t-t Unreleased tag. Update all go.mod with this tag.\n" - exit 1 # Exit script after printing help -} - -while getopts "t:" opt -do - case "$opt" in - t ) TAG="$OPTARG" ;; - ? ) help ;; # Print help - esac -done - -# Print help in case parameters are empty -if [ -z "$TAG" ] -then - printf "Tag is missing\n"; - help -fi - -# Validate semver -SEMVER_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" -if [[ "${TAG}" =~ ${SEMVER_REGEX} ]]; then - printf "${TAG} is valid semver tag.\n" -else - printf "${TAG} is not a valid semver tag.\n" - exit -1 -fi - -TAG_FOUND=`git tag --list ${TAG}` -if [[ ${TAG_FOUND} = ${TAG} ]] ; then - printf "Tag ${TAG} already exists\n" - exit -1 -fi - -# Get version for version.go -OTEL_VERSION=$(echo "${TAG}" | grep -o '^v[0-9]\+\.[0-9]\+\.[0-9]\+') -# Strip leading v -OTEL_VERSION="${OTEL_VERSION#v}" - -cd $(dirname $0) - -if ! git diff --quiet; then \ - printf "Working tree is not clean, can't proceed with the release process\n" - git status - git diff - exit 1 -fi - -# Update version.go -cp ./version.go ./version.go.bak -sed "s/\(return \"\)[0-9]*\.[0-9]*\.[0-9]*\"/\1${OTEL_VERSION}\"/" ./version.go.bak >./version.go -rm -f ./version.go.bak - -# Update go.mod -git checkout -b pre_release_${TAG} main -PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | egrep -v 'tools' | sed 's/^\.\///' | sort) - -for dir in $PACKAGE_DIRS; do - cp "${dir}/go.mod" "${dir}/go.mod.bak" - sed "s/opentelemetry.io\/otel\([^ ]*\) v[0-9]*\.[0-9]*\.[0-9]/opentelemetry.io\/otel\1 ${TAG}/" "${dir}/go.mod.bak" >"${dir}/go.mod" - rm -f "${dir}/go.mod.bak" -done - -# Run lint to update go.sum -make lint - -# Add changes and commit. -git add . -make ci -git commit -m "Prepare for releasing $TAG" - -printf "Now run following to verify the changes.\ngit diff main\n" -printf "\nThen push the changes to upstream\n" diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go index bc76191892e..303cdf1cbff 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go +++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go @@ -16,11 +16,8 @@ package propagation // import "go.opentelemetry.io/otel/propagation" import ( "context" - "net/url" - "strings" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/internal/baggage" + "go.opentelemetry.io/otel/baggage" ) const baggageHeader = "baggage" @@ -28,81 +25,31 @@ const baggageHeader = "baggage" // Baggage is a propagator that supports the W3C Baggage format. // // This propagates user-defined baggage associated with a trace. The complete -// specification is defined at https://w3c.github.io/baggage/. +// specification is defined at https://www.w3.org/TR/baggage/. type Baggage struct{} var _ TextMapPropagator = Baggage{} // Inject sets baggage key-values from ctx into the carrier. func (b Baggage) Inject(ctx context.Context, carrier TextMapCarrier) { - baggageMap := baggage.MapFromContext(ctx) - firstIter := true - var headerValueBuilder strings.Builder - baggageMap.Foreach(func(kv attribute.KeyValue) bool { - if !firstIter { - headerValueBuilder.WriteRune(',') - } - firstIter = false - headerValueBuilder.WriteString(url.QueryEscape(strings.TrimSpace((string)(kv.Key)))) - headerValueBuilder.WriteRune('=') - headerValueBuilder.WriteString(url.QueryEscape(strings.TrimSpace(kv.Value.Emit()))) - return true - }) - if headerValueBuilder.Len() > 0 { - headerString := headerValueBuilder.String() - carrier.Set(baggageHeader, headerString) + bStr := baggage.FromContext(ctx).String() + if bStr != "" { + carrier.Set(baggageHeader, bStr) } } // Extract returns a copy of parent with the baggage from the carrier added. func (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context { - bVal := carrier.Get(baggageHeader) - if bVal == "" { + bStr := carrier.Get(baggageHeader) + if bStr == "" { return parent } - baggageValues := strings.Split(bVal, ",") - keyValues := make([]attribute.KeyValue, 0, len(baggageValues)) - for _, baggageValue := range baggageValues { - valueAndProps := strings.Split(baggageValue, ";") - if len(valueAndProps) < 1 { - continue - } - nameValue := strings.Split(valueAndProps[0], "=") - if len(nameValue) < 2 { - continue - } - name, err := url.QueryUnescape(nameValue[0]) - if err != nil { - continue - } - trimmedName := strings.TrimSpace(name) - value, err := url.QueryUnescape(nameValue[1]) - if err != nil { - continue - } - trimmedValue := strings.TrimSpace(value) - - // TODO (skaris): properties defiend https://w3c.github.io/correlation-context/, are currently - // just put as part of the value. - var trimmedValueWithProps strings.Builder - trimmedValueWithProps.WriteString(trimmedValue) - for _, prop := range valueAndProps[1:] { - trimmedValueWithProps.WriteRune(';') - trimmedValueWithProps.WriteString(prop) - } - - keyValues = append(keyValues, attribute.String(trimmedName, trimmedValueWithProps.String())) - } - - if len(keyValues) > 0 { - // Only update the context if valid values were found - return baggage.ContextWithMap(parent, baggage.NewMap(baggage.MapUpdate{ - MultiKV: keyValues, - })) + bag, err := baggage.Parse(bStr) + if err != nil { + return parent } - - return parent + return baggage.ContextWithBaggage(parent, bag) } // Fields returns the keys who's values are set with Inject. diff --git a/vendor/go.opentelemetry.io/otel/propagation/doc.go b/vendor/go.opentelemetry.io/otel/propagation/doc.go index 89573f1baa9..c119eb2858b 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/doc.go +++ b/vendor/go.opentelemetry.io/otel/propagation/doc.go @@ -15,14 +15,10 @@ /* Package propagation contains OpenTelemetry context propagators. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - OpenTelemetry propagators are used to extract and inject context data from and into messages exchanged by applications. The propagator supported by this package is the W3C Trace Context encoding (https://www.w3.org/TR/trace-context/), and W3C Baggage -(https://w3c.github.io/baggage/). +(https://www.w3.org/TR/baggage/). */ package propagation // import "go.opentelemetry.io/otel/propagation" diff --git a/vendor/go.opentelemetry.io/otel/propagation/propagation.go b/vendor/go.opentelemetry.io/otel/propagation/propagation.go index 9cfeb347a37..c94438f73a5 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/propagation.go +++ b/vendor/go.opentelemetry.io/otel/propagation/propagation.go @@ -21,12 +21,49 @@ import ( // TextMapCarrier is the storage medium used by a TextMapPropagator. type TextMapCarrier interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Get returns the value associated with the passed key. Get(key string) string + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Set stores the key-value pair. Set(key string, value string) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Keys lists the keys stored in this carrier. Keys() []string + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. +} + +// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage +// medium for propagated key-value pairs. +type MapCarrier map[string]string + +// Compile time check that MapCarrier implements the TextMapCarrier. +var _ TextMapCarrier = MapCarrier{} + +// Get returns the value associated with the passed key. +func (c MapCarrier) Get(key string) string { + return c[key] +} + +// Set stores the key-value pair. +func (c MapCarrier) Set(key, value string) { + c[key] = value +} + +// Keys lists the keys stored in this carrier. +func (c MapCarrier) Keys() []string { + keys := make([]string, 0, len(c)) + for k := range c { + keys = append(keys, k) + } + return keys } // HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface. @@ -54,12 +91,23 @@ func (hc HeaderCarrier) Keys() []string { // TextMapPropagator propagates cross-cutting concerns as key-value text // pairs within a carrier that travels in-band across process boundaries. type TextMapPropagator interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Inject set cross-cutting concerns from the Context into the carrier. Inject(ctx context.Context, carrier TextMapCarrier) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Extract reads cross-cutting concerns from the carrier into a Context. Extract(ctx context.Context, carrier TextMapCarrier) context.Context - // Fields returns the keys who's values are set with Inject. + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // Fields returns the keys whose values are set with Inject. Fields() []string + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } type compositeTextMapPropagator []TextMapPropagator diff --git a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go index 82de416bea6..902692da082 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go +++ b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go @@ -19,9 +19,7 @@ import ( "encoding/hex" "fmt" "regexp" - "strings" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) @@ -52,7 +50,9 @@ func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) { return } - carrier.Set(tracestateHeader, sc.TraceState().String()) + if ts := sc.TraceState().String(); ts != "" { + carrier.Set(tracestateHeader, ts) + } // Clear all flags other than the trace-context supported sampling bit. flags := sc.TraceFlags() & trace.FlagsSampled @@ -139,7 +139,10 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext { // Clear all flags other than the trace-context supported sampling bit. scc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled - scc.TraceState = parseTraceState(carrier.Get(tracestateHeader)) + // Ignore the error returned here. Failure to parse tracestate MUST NOT + // affect the parsing of traceparent according to the W3C tracecontext + // specification. + scc.TraceState, _ = trace.ParseTraceState(carrier.Get(tracestateHeader)) scc.Remote = true sc := trace.NewSpanContext(scc) @@ -154,25 +157,3 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext { func (tc TraceContext) Fields() []string { return []string{traceparentHeader, tracestateHeader} } - -func parseTraceState(in string) trace.TraceState { - if in == "" { - return trace.TraceState{} - } - - kvs := []attribute.KeyValue{} - for _, entry := range strings.Split(in, ",") { - parts := strings.SplitN(entry, "=", 2) - if len(parts) != 2 { - // Parse failure, abort! - return trace.TraceState{} - } - kvs = append(kvs, attribute.String(parts[0], parts[1])) - } - - // Ignoring error here as "failure to parse tracestate MUST NOT - // affect the parsing of traceparent." - // https://www.w3.org/TR/trace-context/#tracestate-header - ts, _ := trace.TraceStateFromKeyValues(kvs...) - return ts -} diff --git a/vendor/go.opentelemetry.io/otel/requirements.txt b/vendor/go.opentelemetry.io/otel/requirements.txt new file mode 100644 index 00000000000..ddff454685c --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/requirements.txt @@ -0,0 +1 @@ +codespell==2.2.5 diff --git a/vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go b/vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go deleted file mode 100644 index 73e98aaa855..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package aggregation // import "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - -import ( - "fmt" - "time" - - "go.opentelemetry.io/otel/metric/number" -) - -// These interfaces describe the various ways to access state from an -// Aggregation. - -type ( - // Aggregation is an interface returned by the Aggregator - // containing an interval of metric data. - Aggregation interface { - // Kind returns a short identifying string to identify - // the Aggregator that was used to produce the - // Aggregation (e.g., "Sum"). - Kind() Kind - } - - // Sum returns an aggregated sum. - Sum interface { - Aggregation - Sum() (number.Number, error) - } - - // Count returns the number of values that were aggregated. - Count interface { - Aggregation - Count() (uint64, error) - } - - // Min returns the minimum value over the set of values that were aggregated. - Min interface { - Aggregation - Min() (number.Number, error) - } - - // Max returns the maximum value over the set of values that were aggregated. - Max interface { - Aggregation - Max() (number.Number, error) - } - - // LastValue returns the latest value that was aggregated. - LastValue interface { - Aggregation - LastValue() (number.Number, time.Time, error) - } - - // Points returns the raw values that were aggregated. - Points interface { - Aggregation - - // Points returns points in the order they were - // recorded. Points are approximately ordered by - // timestamp, but this is not guaranteed. - Points() ([]Point, error) - } - - // Point is a raw data point, consisting of a number and value. - Point struct { - number.Number - time.Time - } - - // Buckets represents histogram buckets boundaries and counts. - // - // For a Histogram with N defined boundaries, e.g, [x, y, z]. - // There are N+1 counts: [-inf, x), [x, y), [y, z), [z, +inf] - Buckets struct { - // Boundaries are floating point numbers, even when - // aggregating integers. - Boundaries []float64 - - // Counts holds the count in each bucket. - Counts []uint64 - } - - // Histogram returns the count of events in pre-determined buckets. - Histogram interface { - Aggregation - Count() (uint64, error) - Sum() (number.Number, error) - Histogram() (Buckets, error) - } - - // MinMaxSumCount supports the Min, Max, Sum, and Count interfaces. - MinMaxSumCount interface { - Aggregation - Min() (number.Number, error) - Max() (number.Number, error) - Sum() (number.Number, error) - Count() (uint64, error) - } -) - -type ( - // Kind is a short name for the Aggregator that produces an - // Aggregation, used for descriptive purpose only. Kind is a - // string to allow user-defined Aggregators. - // - // When deciding how to handle an Aggregation, Exporters are - // encouraged to decide based on conversion to the above - // interfaces based on strength, not on Kind value, when - // deciding how to expose metric data. This enables - // user-supplied Aggregators to replace builtin Aggregators. - // - // For example, test for a Distribution before testing for a - // MinMaxSumCount, test for a Histogram before testing for a - // Sum, and so on. - Kind string -) - -const ( - SumKind Kind = "Sum" - MinMaxSumCountKind Kind = "MinMaxSumCount" - HistogramKind Kind = "Histogram" - LastValueKind Kind = "Lastvalue" - ExactKind Kind = "Exact" -) - -var ( - ErrNegativeInput = fmt.Errorf("negative value is out of range for this instrument") - ErrNaNInput = fmt.Errorf("NaN value is an invalid input") - ErrInconsistentType = fmt.Errorf("inconsistent aggregator types") - ErrNoSubtraction = fmt.Errorf("aggregator does not subtract") - - // ErrNoData is returned when (due to a race with collection) - // the Aggregator is check-pointed before the first value is set. - // The aggregator should simply be skipped in this case. - ErrNoData = fmt.Errorf("no data collected by this aggregator") -) - -// String returns the string value of Kind. -func (k Kind) String() string { - return string(k) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/export/metric/exportkind_string.go b/vendor/go.opentelemetry.io/otel/sdk/export/metric/exportkind_string.go deleted file mode 100644 index a92c1c1f2de..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/export/metric/exportkind_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -type=ExportKind"; DO NOT EDIT. - -package metric - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[CumulativeExportKind-1] - _ = x[DeltaExportKind-2] -} - -const _ExportKind_name = "CumulativeExportKindDeltaExportKind" - -var _ExportKind_index = [...]uint8{0, 20, 35} - -func (i ExportKind) String() string { - i -= 1 - if i < 0 || i >= ExportKind(len(_ExportKind_index)-1) { - return "ExportKind(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _ExportKind_name[_ExportKind_index[i]:_ExportKind_index[i+1]] -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go b/vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go deleted file mode 100644 index 55965a2392a..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:generate stringer -type=ExportKind - -package metric // import "go.opentelemetry.io/otel/sdk/export/metric" - -import ( - "context" - "sync" - "time" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/resource" -) - -// Processor is responsible for deciding which kind of aggregation to -// use (via AggregatorSelector), gathering exported results from the -// SDK during collection, and deciding over which dimensions to group -// the exported data. -// -// The SDK supports binding only one of these interfaces, as it has -// the sole responsibility of determining which Aggregator to use for -// each record. -// -// The embedded AggregatorSelector interface is called (concurrently) -// in instrumentation context to select the appropriate Aggregator for -// an instrument. -// -// The `Process` method is called during collection in a -// single-threaded context from the SDK, after the aggregator is -// checkpointed, allowing the processor to build the set of metrics -// currently being exported. -type Processor interface { - // AggregatorSelector is responsible for selecting the - // concrete type of Aggregator used for a metric in the SDK. - // - // This may be a static decision based on fields of the - // Descriptor, or it could use an external configuration - // source to customize the treatment of each metric - // instrument. - // - // The result from AggregatorSelector.AggregatorFor should be - // the same type for a given Descriptor or else nil. The same - // type should be returned for a given descriptor, because - // Aggregators only know how to Merge with their own type. If - // the result is nil, the metric instrument will be disabled. - // - // Note that the SDK only calls AggregatorFor when new records - // require an Aggregator. This does not provide a way to - // disable metrics with active records. - AggregatorSelector - - // Process is called by the SDK once per internal record, - // passing the export Accumulation (a Descriptor, the corresponding - // Labels, and the checkpointed Aggregator). This call has no - // Context argument because it is expected to perform only - // computation. An SDK is not expected to call exporters from - // with Process, use a controller for that (see - // ./controllers/{pull,push}. - Process(accum Accumulation) error -} - -// AggregatorSelector supports selecting the kind of Aggregator to -// use at runtime for a specific metric instrument. -type AggregatorSelector interface { - // AggregatorFor allocates a variable number of aggregators of - // a kind suitable for the requested export. This method - // initializes a `...*Aggregator`, to support making a single - // allocation. - // - // When the call returns without initializing the *Aggregator - // to a non-nil value, the metric instrument is explicitly - // disabled. - // - // This must return a consistent type to avoid confusion in - // later stages of the metrics export process, i.e., when - // Merging or Checkpointing aggregators for a specific - // instrument. - // - // Note: This is context-free because the aggregator should - // not relate to the incoming context. This call should not - // block. - AggregatorFor(descriptor *metric.Descriptor, aggregator ...*Aggregator) -} - -// Checkpointer is the interface used by a Controller to coordinate -// the Processor with Accumulator(s) and Exporter(s). The -// StartCollection() and FinishCollection() methods start and finish a -// collection interval. Controllers call the Accumulator(s) during -// collection to process Accumulations. -type Checkpointer interface { - // Processor processes metric data for export. The Process - // method is bracketed by StartCollection and FinishCollection - // calls. The embedded AggregatorSelector can be called at - // any time. - Processor - - // CheckpointSet returns the current data set. This may be - // called before and after collection. The - // implementation is required to return the same value - // throughout its lifetime, since CheckpointSet exposes a - // sync.Locker interface. The caller is responsible for - // locking the CheckpointSet before initiating collection. - CheckpointSet() CheckpointSet - - // StartCollection begins a collection interval. - StartCollection() - - // FinishCollection ends a collection interval. - FinishCollection() error -} - -// Aggregator implements a specific aggregation behavior, e.g., a -// behavior to track a sequence of updates to an instrument. Sum-only -// instruments commonly use a simple Sum aggregator, but for the -// distribution instruments (ValueRecorder, ValueObserver) there are a -// number of possible aggregators with different cost and accuracy -// tradeoffs. -// -// Note that any Aggregator may be attached to any instrument--this is -// the result of the OpenTelemetry API/SDK separation. It is possible -// to attach a Sum aggregator to a ValueRecorder instrument or a -// MinMaxSumCount aggregator to a Counter instrument. -type Aggregator interface { - // Aggregation returns an Aggregation interface to access the - // current state of this Aggregator. The caller is - // responsible for synchronization and must not call any the - // other methods in this interface concurrently while using - // the Aggregation. - Aggregation() aggregation.Aggregation - - // Update receives a new measured value and incorporates it - // into the aggregation. Update() calls may be called - // concurrently. - // - // Descriptor.NumberKind() should be consulted to determine - // whether the provided number is an int64 or float64. - // - // The Context argument comes from user-level code and could be - // inspected for a `correlation.Map` or `trace.SpanContext`. - Update(ctx context.Context, number number.Number, descriptor *metric.Descriptor) error - - // SynchronizedMove is called during collection to finish one - // period of aggregation by atomically saving the - // currently-updating state into the argument Aggregator AND - // resetting the current value to the zero state. - // - // SynchronizedMove() is called concurrently with Update(). These - // two methods must be synchronized with respect to each - // other, for correctness. - // - // After saving a synchronized copy, the Aggregator can be converted - // into one or more of the interfaces in the `aggregation` sub-package, - // according to kind of Aggregator that was selected. - // - // This method will return an InconsistentAggregatorError if - // this Aggregator cannot be copied into the destination due - // to an incompatible type. - // - // This call has no Context argument because it is expected to - // perform only computation. - // - // When called with a nil `destination`, this Aggregator is reset - // and the current value is discarded. - SynchronizedMove(destination Aggregator, descriptor *metric.Descriptor) error - - // Merge combines the checkpointed state from the argument - // Aggregator into this Aggregator. Merge is not synchronized - // with respect to Update or SynchronizedMove. - // - // The owner of an Aggregator being merged is responsible for - // synchronization of both Aggregator states. - Merge(aggregator Aggregator, descriptor *metric.Descriptor) error -} - -// Subtractor is an optional interface implemented by some -// Aggregators. An Aggregator must support `Subtract()` in order to -// be configured for a Precomputed-Sum instrument (SumObserver, -// UpDownSumObserver) using a DeltaExporter. -type Subtractor interface { - // Subtract subtracts the `operand` from this Aggregator and - // outputs the value in `result`. - Subtract(operand, result Aggregator, descriptor *metric.Descriptor) error -} - -// Exporter handles presentation of the checkpoint of aggregate -// metrics. This is the final stage of a metrics export pipeline, -// where metric data are formatted for a specific system. -type Exporter interface { - // Export is called immediately after completing a collection - // pass in the SDK. - // - // The Context comes from the controller that initiated - // collection. - // - // The CheckpointSet interface refers to the Processor that just - // completed collection. - Export(ctx context.Context, checkpointSet CheckpointSet) error - - // ExportKindSelector is an interface used by the Processor - // in deciding whether to compute Delta or Cumulative - // Aggregations when passing Records to this Exporter. - ExportKindSelector -} - -// ExportKindSelector is a sub-interface of Exporter used to indicate -// whether the Processor should compute Delta or Cumulative -// Aggregations. -type ExportKindSelector interface { - // ExportKindFor should return the correct ExportKind that - // should be used when exporting data for the given metric - // instrument and Aggregator kind. - ExportKindFor(descriptor *metric.Descriptor, aggregatorKind aggregation.Kind) ExportKind -} - -// CheckpointSet allows a controller to access a complete checkpoint of -// aggregated metrics from the Processor. This is passed to the -// Exporter which may then use ForEach to iterate over the collection -// of aggregated metrics. -type CheckpointSet interface { - // ForEach iterates over aggregated checkpoints for all - // metrics that were updated during the last collection - // period. Each aggregated checkpoint returned by the - // function parameter may return an error. - // - // The ExportKindSelector argument is used to determine - // whether the Record is computed using Delta or Cumulative - // aggregation. - // - // ForEach tolerates ErrNoData silently, as this is - // expected from the Meter implementation. Any other kind - // of error will immediately halt ForEach and return - // the error to the caller. - ForEach(kindSelector ExportKindSelector, recordFunc func(Record) error) error - - // Locker supports locking the checkpoint set. Collection - // into the checkpoint set cannot take place (in case of a - // stateful processor) while it is locked. - // - // The Processor attached to the Accumulator MUST be called - // with the lock held. - sync.Locker - - // RLock acquires a read lock corresponding to this Locker. - RLock() - // RUnlock releases a read lock corresponding to this Locker. - RUnlock() -} - -// Metadata contains the common elements for exported metric data that -// are shared by the Accumulator->Processor and Processor->Exporter -// steps. -type Metadata struct { - descriptor *metric.Descriptor - labels *attribute.Set - resource *resource.Resource -} - -// Accumulation contains the exported data for a single metric instrument -// and label set, as prepared by an Accumulator for the Processor. -type Accumulation struct { - Metadata - aggregator Aggregator -} - -// Record contains the exported data for a single metric instrument -// and label set, as prepared by the Processor for the Exporter. -// This includes the effective start and end time for the aggregation. -type Record struct { - Metadata - aggregation aggregation.Aggregation - start time.Time - end time.Time -} - -// Descriptor describes the metric instrument being exported. -func (m Metadata) Descriptor() *metric.Descriptor { - return m.descriptor -} - -// Labels describes the labels associated with the instrument and the -// aggregated data. -func (m Metadata) Labels() *attribute.Set { - return m.labels -} - -// Resource contains common attributes that apply to this metric event. -func (m Metadata) Resource() *resource.Resource { - return m.resource -} - -// NewAccumulation allows Accumulator implementations to construct new -// Accumulations to send to Processors. The Descriptor, Labels, Resource, -// and Aggregator represent aggregate metric events received over a single -// collection period. -func NewAccumulation(descriptor *metric.Descriptor, labels *attribute.Set, resource *resource.Resource, aggregator Aggregator) Accumulation { - return Accumulation{ - Metadata: Metadata{ - descriptor: descriptor, - labels: labels, - resource: resource, - }, - aggregator: aggregator, - } -} - -// Aggregator returns the checkpointed aggregator. It is safe to -// access the checkpointed state without locking. -func (r Accumulation) Aggregator() Aggregator { - return r.aggregator -} - -// NewRecord allows Processor implementations to construct export -// records. The Descriptor, Labels, and Aggregator represent -// aggregate metric events received over a single collection period. -func NewRecord(descriptor *metric.Descriptor, labels *attribute.Set, resource *resource.Resource, aggregation aggregation.Aggregation, start, end time.Time) Record { - return Record{ - Metadata: Metadata{ - descriptor: descriptor, - labels: labels, - resource: resource, - }, - aggregation: aggregation, - start: start, - end: end, - } -} - -// Aggregation returns the aggregation, an interface to the record and -// its aggregator, dependent on the kind of both the input and exporter. -func (r Record) Aggregation() aggregation.Aggregation { - return r.aggregation -} - -// StartTime is the start time of the interval covered by this aggregation. -func (r Record) StartTime() time.Time { - return r.start -} - -// EndTime is the end time of the interval covered by this aggregation. -func (r Record) EndTime() time.Time { - return r.end -} - -// ExportKind indicates the kind of data exported by an exporter. -// These bits may be OR-d together when multiple exporters are in use. -type ExportKind int - -const ( - // CumulativeExportKind indicates that an Exporter expects a - // Cumulative Aggregation. - CumulativeExportKind ExportKind = 1 - - // DeltaExportKind indicates that an Exporter expects a - // Delta Aggregation. - DeltaExportKind ExportKind = 2 -) - -// Includes tests whether `kind` includes a specific kind of -// exporter. -func (kind ExportKind) Includes(has ExportKind) bool { - return kind&has != 0 -} - -// MemoryRequired returns whether an exporter of this kind requires -// memory to export correctly. -func (kind ExportKind) MemoryRequired(mkind metric.InstrumentKind) bool { - switch mkind { - case metric.ValueRecorderInstrumentKind, metric.ValueObserverInstrumentKind, - metric.CounterInstrumentKind, metric.UpDownCounterInstrumentKind: - // Delta-oriented instruments: - return kind.Includes(CumulativeExportKind) - - case metric.SumObserverInstrumentKind, metric.UpDownSumObserverInstrumentKind: - // Cumulative-oriented instruments: - return kind.Includes(DeltaExportKind) - } - // Something unexpected is happening--we could panic. This - // will become an error when the exporter tries to access a - // checkpoint, presumably, so let it be. - return false -} - -type ( - constantExportKindSelector ExportKind - statelessExportKindSelector struct{} -) - -var ( - _ ExportKindSelector = constantExportKindSelector(0) - _ ExportKindSelector = statelessExportKindSelector{} -) - -// ConstantExportKindSelector returns an ExportKindSelector that returns -// a constant ExportKind, one that is either always cumulative or always delta. -func ConstantExportKindSelector(kind ExportKind) ExportKindSelector { - return constantExportKindSelector(kind) -} - -// CumulativeExportKindSelector returns an ExportKindSelector that -// always returns CumulativeExportKind. -func CumulativeExportKindSelector() ExportKindSelector { - return ConstantExportKindSelector(CumulativeExportKind) -} - -// DeltaExportKindSelector returns an ExportKindSelector that -// always returns DeltaExportKind. -func DeltaExportKindSelector() ExportKindSelector { - return ConstantExportKindSelector(DeltaExportKind) -} - -// StatelessExportKindSelector returns an ExportKindSelector that -// always returns the ExportKind that avoids long-term memory -// requirements. -func StatelessExportKindSelector() ExportKindSelector { - return statelessExportKindSelector{} -} - -// ExportKindFor implements ExportKindSelector. -func (c constantExportKindSelector) ExportKindFor(_ *metric.Descriptor, _ aggregation.Kind) ExportKind { - return ExportKind(c) -} - -// ExportKindFor implements ExportKindSelector. -func (s statelessExportKindSelector) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) ExportKind { - if kind == aggregation.SumKind && desc.InstrumentKind().PrecomputedSum() { - return CumulativeExportKind - } - return DeltaExportKind -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go new file mode 100644 index 00000000000..6e923acab43 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package instrumentation provides types to represent the code libraries that +// provide OpenTelemetry instrumentation. These types are used in the +// OpenTelemetry signal pipelines to identify the source of telemetry. +// +// See +// https://github.com/open-telemetry/oteps/blob/d226b677d73a785523fe9b9701be13225ebc528d/text/0083-component.md +// and +// https://github.com/open-telemetry/oteps/blob/d226b677d73a785523fe9b9701be13225ebc528d/text/0201-scope-attributes.md +// for more information. +package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go index c897c04de37..39f025a1715 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go @@ -12,24 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -/* -Package instrumentation provides an instrumentation library structure to be -passed to both the OpenTelemetry Tracer and Meter components. - -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - -For more information see -[this](https://github.com/open-telemetry/oteps/blob/main/text/0083-component.md). -*/ package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" // Library represents the instrumentation library. -type Library struct { - // Name is the name of the instrumentation library. This should be the - // Go package name of that library. - Name string - // Version is the version of the instrumentation library. - Version string -} +// Deprecated: please use Scope instead. +type Library = Scope diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go new file mode 100644 index 00000000000..09c6d93f6d0 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" + +// Scope represents the instrumentation scope. +type Scope struct { + // Name is the name of the instrumentation scope. This should be the + // Go package name of that scope. + Name string + // Version is the version of the instrumentation scope. + Version string + // SchemaURL of the telemetry emitted by the scope. + SchemaURL string +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go b/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go new file mode 100644 index 00000000000..59dcfab2501 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go @@ -0,0 +1,177 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package env // import "go.opentelemetry.io/otel/sdk/internal/env" + +import ( + "os" + "strconv" + + "go.opentelemetry.io/otel/internal/global" +) + +// Environment variable names. +const ( + // BatchSpanProcessorScheduleDelayKey is the delay interval between two + // consecutive exports (i.e. 5000). + BatchSpanProcessorScheduleDelayKey = "OTEL_BSP_SCHEDULE_DELAY" + // BatchSpanProcessorExportTimeoutKey is the maximum allowed time to + // export data (i.e. 3000). + BatchSpanProcessorExportTimeoutKey = "OTEL_BSP_EXPORT_TIMEOUT" + // BatchSpanProcessorMaxQueueSizeKey is the maximum queue size (i.e. 2048). + BatchSpanProcessorMaxQueueSizeKey = "OTEL_BSP_MAX_QUEUE_SIZE" + // BatchSpanProcessorMaxExportBatchSizeKey is the maximum batch size (i.e. + // 512). Note: it must be less than or equal to + // EnvBatchSpanProcessorMaxQueueSize. + BatchSpanProcessorMaxExportBatchSizeKey = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE" + + // AttributeValueLengthKey is the maximum allowed attribute value size. + AttributeValueLengthKey = "OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT" + + // AttributeCountKey is the maximum allowed span attribute count. + AttributeCountKey = "OTEL_ATTRIBUTE_COUNT_LIMIT" + + // SpanAttributeValueLengthKey is the maximum allowed attribute value size + // for a span. + SpanAttributeValueLengthKey = "OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT" + + // SpanAttributeCountKey is the maximum allowed span attribute count for a + // span. + SpanAttributeCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" + + // SpanEventCountKey is the maximum allowed span event count. + SpanEventCountKey = "OTEL_SPAN_EVENT_COUNT_LIMIT" + + // SpanEventAttributeCountKey is the maximum allowed attribute per span + // event count. + SpanEventAttributeCountKey = "OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT" + + // SpanLinkCountKey is the maximum allowed span link count. + SpanLinkCountKey = "OTEL_SPAN_LINK_COUNT_LIMIT" + + // SpanLinkAttributeCountKey is the maximum allowed attribute per span + // link count. + SpanLinkAttributeCountKey = "OTEL_LINK_ATTRIBUTE_COUNT_LIMIT" +) + +// firstInt returns the value of the first matching environment variable from +// keys. If the value is not an integer or no match is found, defaultValue is +// returned. +func firstInt(defaultValue int, keys ...string) int { + for _, key := range keys { + value := os.Getenv(key) + if value == "" { + continue + } + + intValue, err := strconv.Atoi(value) + if err != nil { + global.Info("Got invalid value, number value expected.", key, value) + return defaultValue + } + + return intValue + } + + return defaultValue +} + +// IntEnvOr returns the int value of the environment variable with name key if +// it exists, it is not empty, and the value is an int. Otherwise, defaultValue is returned. +func IntEnvOr(key string, defaultValue int) int { + value := os.Getenv(key) + if value == "" { + return defaultValue + } + + intValue, err := strconv.Atoi(value) + if err != nil { + global.Info("Got invalid value, number value expected.", key, value) + return defaultValue + } + + return intValue +} + +// BatchSpanProcessorScheduleDelay returns the environment variable value for +// the OTEL_BSP_SCHEDULE_DELAY key if it exists, otherwise defaultValue is +// returned. +func BatchSpanProcessorScheduleDelay(defaultValue int) int { + return IntEnvOr(BatchSpanProcessorScheduleDelayKey, defaultValue) +} + +// BatchSpanProcessorExportTimeout returns the environment variable value for +// the OTEL_BSP_EXPORT_TIMEOUT key if it exists, otherwise defaultValue is +// returned. +func BatchSpanProcessorExportTimeout(defaultValue int) int { + return IntEnvOr(BatchSpanProcessorExportTimeoutKey, defaultValue) +} + +// BatchSpanProcessorMaxQueueSize returns the environment variable value for +// the OTEL_BSP_MAX_QUEUE_SIZE key if it exists, otherwise defaultValue is +// returned. +func BatchSpanProcessorMaxQueueSize(defaultValue int) int { + return IntEnvOr(BatchSpanProcessorMaxQueueSizeKey, defaultValue) +} + +// BatchSpanProcessorMaxExportBatchSize returns the environment variable value for +// the OTEL_BSP_MAX_EXPORT_BATCH_SIZE key if it exists, otherwise defaultValue +// is returned. +func BatchSpanProcessorMaxExportBatchSize(defaultValue int) int { + return IntEnvOr(BatchSpanProcessorMaxExportBatchSizeKey, defaultValue) +} + +// SpanAttributeValueLength returns the environment variable value for the +// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the +// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT is +// returned or defaultValue if that is not set. +func SpanAttributeValueLength(defaultValue int) int { + return firstInt(defaultValue, SpanAttributeValueLengthKey, AttributeValueLengthKey) +} + +// SpanAttributeCount returns the environment variable value for the +// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the +// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT is returned or +// defaultValue if that is not set. +func SpanAttributeCount(defaultValue int) int { + return firstInt(defaultValue, SpanAttributeCountKey, AttributeCountKey) +} + +// SpanEventCount returns the environment variable value for the +// OTEL_SPAN_EVENT_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanEventCount(defaultValue int) int { + return IntEnvOr(SpanEventCountKey, defaultValue) +} + +// SpanEventAttributeCount returns the environment variable value for the +// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue +// is returned. +func SpanEventAttributeCount(defaultValue int) int { + return IntEnvOr(SpanEventAttributeCountKey, defaultValue) +} + +// SpanLinkCount returns the environment variable value for the +// OTEL_SPAN_LINK_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanLinkCount(defaultValue int) int { + return IntEnvOr(SpanLinkCountKey, defaultValue) +} + +// SpanLinkAttributeCount returns the environment variable value for the +// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanLinkAttributeCount(defaultValue int) int { + return IntEnvOr(SpanLinkAttributeCountKey, defaultValue) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/gen.go b/vendor/go.opentelemetry.io/otel/sdk/internal/gen.go new file mode 100644 index 00000000000..bd84f624b45 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/gen.go @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/sdk/internal" + +//go:generate gotmpl --body=../../internal/shared/matchers/expectation.go.tmpl "--data={}" --out=matchers/expectation.go +//go:generate gotmpl --body=../../internal/shared/matchers/expecter.go.tmpl "--data={}" --out=matchers/expecter.go +//go:generate gotmpl --body=../../internal/shared/matchers/temporal_matcher.go.tmpl "--data={}" --out=matchers/temporal_matcher.go + +//go:generate gotmpl --body=../../internal/shared/internaltest/alignment.go.tmpl "--data={}" --out=internaltest/alignment.go +//go:generate gotmpl --body=../../internal/shared/internaltest/env.go.tmpl "--data={}" --out=internaltest/env.go +//go:generate gotmpl --body=../../internal/shared/internaltest/env_test.go.tmpl "--data={}" --out=internaltest/env_test.go +//go:generate gotmpl --body=../../internal/shared/internaltest/errors.go.tmpl "--data={}" --out=internaltest/errors.go +//go:generate gotmpl --body=../../internal/shared/internaltest/harness.go.tmpl "--data={\"matchersImportPath\": \"go.opentelemetry.io/otel/sdk/internal/matchers\"}" --out=internaltest/harness.go +//go:generate gotmpl --body=../../internal/shared/internaltest/text_map_carrier.go.tmpl "--data={}" --out=internaltest/text_map_carrier.go +//go:generate gotmpl --body=../../internal/shared/internaltest/text_map_carrier_test.go.tmpl "--data={}" --out=internaltest/text_map_carrier_test.go +//go:generate gotmpl --body=../../internal/shared/internaltest/text_map_propagator.go.tmpl "--data={}" --out=internaltest/text_map_propagator.go +//go:generate gotmpl --body=../../internal/shared/internaltest/text_map_propagator_test.go.tmpl "--data={}" --out=internaltest/text_map_propagator_test.go diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go b/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go index 84a02306e64..dfeaaa8ca04 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go @@ -14,16 +14,7 @@ package internal // import "go.opentelemetry.io/otel/sdk/internal" -import ( - "fmt" - "time" - - "go.opentelemetry.io/otel" -) - -// UserAgent is the user agent to be added to the outgoing -// requests from the exporters. -var UserAgent = fmt.Sprintf("opentelemetry-go/%s", otel.Version()) +import "time" // MonotonicEndTime returns the end time at present // but offset from start, monotonically. diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/sanitize.go b/vendor/go.opentelemetry.io/otel/sdk/internal/sanitize.go deleted file mode 100644 index e6d8b7d5998..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/sanitize.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package internal - -import ( - "strings" - "unicode" -) - -const labelKeySizeLimit = 100 - -// Sanitize returns a string that is trunacated to 100 characters if it's too -// long, and replaces non-alphanumeric characters to underscores. -func Sanitize(s string) string { - if len(s) == 0 { - return s - } - if len(s) > labelKeySizeLimit { - s = s[:labelKeySizeLimit] - } - s = strings.Map(sanitizeRune, s) - if unicode.IsDigit(rune(s[0])) { - s = "key_" + s - } - if s[0] == '_' { - s = "key" + s - } - return s -} - -// converts anything that is not a letter or digit to an underscore -func sanitizeRune(r rune) rune { - if unicode.IsLetter(r) || unicode.IsDigit(r) { - return r - } - // Everything else turns into an underscore - return '_' -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/aggregator.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/aggregator.go deleted file mode 100644 index afda991e863..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/aggregator.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package aggregator // import "go.opentelemetry.io/otel/sdk/metric/aggregator" - -import ( - "fmt" - "math" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" -) - -// NewInconsistentAggregatorError formats an error describing an attempt to -// Checkpoint or Merge different-type aggregators. The result can be unwrapped as -// an ErrInconsistentType. -func NewInconsistentAggregatorError(a1, a2 export.Aggregator) error { - return fmt.Errorf("%w: %T and %T", aggregation.ErrInconsistentType, a1, a2) -} - -// RangeTest is a common routine for testing for valid input values. -// This rejects NaN values. This rejects negative values when the -// metric instrument does not support negative values, including -// monotonic counter metrics and absolute ValueRecorder metrics. -func RangeTest(num number.Number, descriptor *metric.Descriptor) error { - numberKind := descriptor.NumberKind() - - if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) { - return aggregation.ErrNaNInput - } - - switch descriptor.InstrumentKind() { - case metric.CounterInstrumentKind, metric.SumObserverInstrumentKind: - if num.IsNegative(numberKind) { - return aggregation.ErrNegativeInput - } - } - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go deleted file mode 100644 index c2c7adaf256..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package exact // import "go.opentelemetry.io/otel/sdk/metric/aggregator/exact" - -import ( - "context" - "sync" - "time" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/aggregator" -) - -type ( - // Aggregator aggregates events that form a distribution, keeping - // an array with the exact set of values. - Aggregator struct { - lock sync.Mutex - samples []aggregation.Point - } -) - -var _ export.Aggregator = &Aggregator{} -var _ aggregation.Points = &Aggregator{} -var _ aggregation.Count = &Aggregator{} - -// New returns cnt many new exact aggregators, which aggregate recorded -// measurements by storing them in an array. This type uses a mutex -// for Update() and SynchronizedMove() concurrency. -func New(cnt int) []Aggregator { - return make([]Aggregator, cnt) -} - -// Aggregation returns an interface for reading the state of this aggregator. -func (c *Aggregator) Aggregation() aggregation.Aggregation { - return c -} - -// Kind returns aggregation.ExactKind. -func (c *Aggregator) Kind() aggregation.Kind { - return aggregation.ExactKind -} - -// Count returns the number of values in the checkpoint. -func (c *Aggregator) Count() (uint64, error) { - return uint64(len(c.samples)), nil -} - -// Points returns access to the raw data set. -func (c *Aggregator) Points() ([]aggregation.Point, error) { - return c.samples, nil -} - -// SynchronizedMove saves the current state to oa and resets the current state to -// the empty set, taking a lock to prevent concurrent Update() calls. -func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - - if oa != nil && o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - - c.lock.Lock() - defer c.lock.Unlock() - - if o != nil { - o.samples = c.samples - } - c.samples = nil - - return nil -} - -// Update adds the recorded measurement to the current data set. -// Update takes a lock to prevent concurrent Update() and SynchronizedMove() -// calls. -func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { - now := time.Now() - c.lock.Lock() - defer c.lock.Unlock() - c.samples = append(c.samples, aggregation.Point{ - Number: number, - Time: now, - }) - - return nil -} - -// Merge combines two data sets into one. -func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - - c.samples = combine(c.samples, o.samples) - return nil -} - -func combine(a, b []aggregation.Point) []aggregation.Point { - result := make([]aggregation.Point, 0, len(a)+len(b)) - - for len(a) != 0 && len(b) != 0 { - if a[0].Time.Before(b[0].Time) { - result = append(result, a[0]) - a = a[1:] - } else { - result = append(result, b[0]) - b = b[1:] - } - } - result = append(result, a...) - result = append(result, b...) - return result -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/histogram/histogram.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/histogram/histogram.go deleted file mode 100644 index ea3ecdbb5b2..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/histogram/histogram.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package histogram // import "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" - -import ( - "context" - "sort" - "sync" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/aggregator" -) - -// Note: This code uses a Mutex to govern access to the exclusive -// aggregator state. This is in contrast to a lock-free approach -// (as in the Go prometheus client) that was reverted here: -// https://github.com/open-telemetry/opentelemetry-go/pull/669 - -type ( - // Aggregator observe events and counts them in pre-determined buckets. - // It also calculates the sum and count of all events. - Aggregator struct { - lock sync.Mutex - boundaries []float64 - kind number.Kind - state *state - } - - // config describes how the histogram is aggregated. - config struct { - // explicitBoundaries support arbitrary bucketing schemes. This - // is the general case. - explicitBoundaries []float64 - } - - // Option configures a histogram config. - Option interface { - // apply sets one or more config fields. - apply(*config) - } - - // state represents the state of a histogram, consisting of - // the sum and counts for all observed values and - // the less than equal bucket count for the pre-determined boundaries. - state struct { - bucketCounts []uint64 - sum number.Number - count uint64 - } -) - -// WithExplicitBoundaries sets the ExplicitBoundaries configuration option of a config. -func WithExplicitBoundaries(explicitBoundaries []float64) Option { - return explicitBoundariesOption{explicitBoundaries} -} - -type explicitBoundariesOption struct { - boundaries []float64 -} - -func (o explicitBoundariesOption) apply(config *config) { - config.explicitBoundaries = o.boundaries -} - -// defaultExplicitBoundaries have been copied from prometheus.DefBuckets. -// -// Note we anticipate the use of a high-precision histogram sketch as -// the standard histogram aggregator for OTLP export. -// (https://github.com/open-telemetry/opentelemetry-specification/issues/982). -var defaultFloat64ExplicitBoundaries = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - -// defaultInt64ExplicitBoundaryMultiplier determines the default -// integer histogram boundaries. -const defaultInt64ExplicitBoundaryMultiplier = 1e6 - -// defaultInt64ExplicitBoundaries applies a multiplier to the default -// float64 boundaries: [ 5K, 10K, 25K, ..., 2.5M, 5M, 10M ] -var defaultInt64ExplicitBoundaries = func(bounds []float64) (asint []float64) { - for _, f := range bounds { - asint = append(asint, defaultInt64ExplicitBoundaryMultiplier*f) - } - return -}(defaultFloat64ExplicitBoundaries) - -var _ export.Aggregator = &Aggregator{} -var _ aggregation.Sum = &Aggregator{} -var _ aggregation.Count = &Aggregator{} -var _ aggregation.Histogram = &Aggregator{} - -// New returns a new aggregator for computing Histograms. -// -// A Histogram observe events and counts them in pre-defined buckets. -// And also provides the total sum and count of all observations. -// -// Note that this aggregator maintains each value using independent -// atomic operations, which introduces the possibility that -// checkpoints are inconsistent. -func New(cnt int, desc *metric.Descriptor, opts ...Option) []Aggregator { - var cfg config - - if desc.NumberKind() == number.Int64Kind { - cfg.explicitBoundaries = defaultInt64ExplicitBoundaries - } else { - cfg.explicitBoundaries = defaultFloat64ExplicitBoundaries - } - - for _, opt := range opts { - opt.apply(&cfg) - } - - aggs := make([]Aggregator, cnt) - - // Boundaries MUST be ordered otherwise the histogram could not - // be properly computed. - sortedBoundaries := make([]float64, len(cfg.explicitBoundaries)) - - copy(sortedBoundaries, cfg.explicitBoundaries) - sort.Float64s(sortedBoundaries) - - for i := range aggs { - aggs[i] = Aggregator{ - kind: desc.NumberKind(), - boundaries: sortedBoundaries, - } - aggs[i].state = aggs[i].newState() - } - return aggs -} - -// Aggregation returns an interface for reading the state of this aggregator. -func (c *Aggregator) Aggregation() aggregation.Aggregation { - return c -} - -// Kind returns aggregation.HistogramKind. -func (c *Aggregator) Kind() aggregation.Kind { - return aggregation.HistogramKind -} - -// Sum returns the sum of all values in the checkpoint. -func (c *Aggregator) Sum() (number.Number, error) { - return c.state.sum, nil -} - -// Count returns the number of values in the checkpoint. -func (c *Aggregator) Count() (uint64, error) { - return c.state.count, nil -} - -// Histogram returns the count of events in pre-determined buckets. -func (c *Aggregator) Histogram() (aggregation.Buckets, error) { - return aggregation.Buckets{ - Boundaries: c.boundaries, - Counts: c.state.bucketCounts, - }, nil -} - -// SynchronizedMove saves the current state into oa and resets the current state to -// the empty set. Since no locks are taken, there is a chance that -// the independent Sum, Count and Bucket Count are not consistent with each -// other. -func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - - if oa != nil && o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - - if o != nil { - // Swap case: This is the ordinary case for a - // synchronous instrument, where the SDK allocates two - // Aggregators and lock contention is anticipated. - // Reset the target state before swapping it under the - // lock below. - o.clearState() - } - - c.lock.Lock() - if o != nil { - c.state, o.state = o.state, c.state - } else { - // No swap case: This is the ordinary case for an - // asynchronous instrument, where the SDK allocates a - // single Aggregator and there is no anticipated lock - // contention. - c.clearState() - } - c.lock.Unlock() - - return nil -} - -func (c *Aggregator) newState() *state { - return &state{ - bucketCounts: make([]uint64, len(c.boundaries)+1), - } -} - -func (c *Aggregator) clearState() { - for i := range c.state.bucketCounts { - c.state.bucketCounts[i] = 0 - } - c.state.sum = 0 - c.state.count = 0 -} - -// Update adds the recorded measurement to the current data set. -func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { - kind := desc.NumberKind() - asFloat := number.CoerceToFloat64(kind) - - bucketID := len(c.boundaries) - for i, boundary := range c.boundaries { - if asFloat < boundary { - bucketID = i - break - } - } - // Note: Binary-search was compared using the benchmarks. The following - // code is equivalent to the linear search above: - // - // bucketID := sort.Search(len(c.boundaries), func(i int) bool { - // return asFloat < c.boundaries[i] - // }) - // - // The binary search wins for very large boundary sets, but - // the linear search performs better up through arrays between - // 256 and 512 elements, which is a relatively large histogram, so we - // continue to prefer linear search. - - c.lock.Lock() - defer c.lock.Unlock() - - c.state.count++ - c.state.sum.AddNumber(kind, number) - c.state.bucketCounts[bucketID]++ - - return nil -} - -// Merge combines two histograms that have the same buckets into a single one. -func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - - c.state.sum.AddNumber(desc.NumberKind(), o.state.sum) - c.state.count += o.state.count - - for i := 0; i < len(c.state.bucketCounts); i++ { - c.state.bucketCounts[i] += o.state.bucketCounts[i] - } - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue/lastvalue.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue/lastvalue.go deleted file mode 100644 index 3cc5f7055cf..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue/lastvalue.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package lastvalue // import "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" - -import ( - "context" - "sync/atomic" - "time" - "unsafe" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/aggregator" -) - -type ( - - // Aggregator aggregates lastValue events. - Aggregator struct { - // value is an atomic pointer to *lastValueData. It is never nil. - value unsafe.Pointer - } - - // lastValueData stores the current value of a lastValue along with - // a sequence number to determine the winner of a race. - lastValueData struct { - // value is the int64- or float64-encoded Set() data - // - // value needs to be aligned for 64-bit atomic operations. - value number.Number - - // timestamp indicates when this record was submitted. - // this can be used to pick a winner when multiple - // records contain lastValue data for the same labels due - // to races. - timestamp time.Time - } -) - -var _ export.Aggregator = &Aggregator{} -var _ aggregation.LastValue = &Aggregator{} - -// An unset lastValue has zero timestamp and zero value. -var unsetLastValue = &lastValueData{} - -// New returns a new lastValue aggregator. This aggregator retains the -// last value and timestamp that were recorded. -func New(cnt int) []Aggregator { - aggs := make([]Aggregator, cnt) - for i := range aggs { - aggs[i] = Aggregator{ - value: unsafe.Pointer(unsetLastValue), - } - } - return aggs -} - -// Aggregation returns an interface for reading the state of this aggregator. -func (g *Aggregator) Aggregation() aggregation.Aggregation { - return g -} - -// Kind returns aggregation.LastValueKind. -func (g *Aggregator) Kind() aggregation.Kind { - return aggregation.LastValueKind -} - -// LastValue returns the last-recorded lastValue value and the -// corresponding timestamp. The error value aggregation.ErrNoData -// will be returned if (due to a race condition) the checkpoint was -// computed before the first value was set. -func (g *Aggregator) LastValue() (number.Number, time.Time, error) { - gd := (*lastValueData)(g.value) - if gd == unsetLastValue { - return 0, time.Time{}, aggregation.ErrNoData - } - return gd.value.AsNumber(), gd.timestamp, nil -} - -// SynchronizedMove atomically saves the current value. -func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error { - if oa == nil { - atomic.StorePointer(&g.value, unsafe.Pointer(unsetLastValue)) - return nil - } - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(g, oa) - } - o.value = atomic.SwapPointer(&g.value, unsafe.Pointer(unsetLastValue)) - return nil -} - -// Update atomically sets the current "last" value. -func (g *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { - ngd := &lastValueData{ - value: number, - timestamp: time.Now(), - } - atomic.StorePointer(&g.value, unsafe.Pointer(ngd)) - return nil -} - -// Merge combines state from two aggregators. The most-recently set -// value is chosen. -func (g *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(g, oa) - } - - ggd := (*lastValueData)(atomic.LoadPointer(&g.value)) - ogd := (*lastValueData)(atomic.LoadPointer(&o.value)) - - if ggd.timestamp.After(ogd.timestamp) { - return nil - } - - g.value = unsafe.Pointer(ogd) - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go deleted file mode 100644 index e21fd75ab73..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package minmaxsumcount // import "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" - -import ( - "context" - "sync" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/aggregator" -) - -type ( - // Aggregator aggregates events that form a distribution, - // keeping only the min, max, sum, and count. - Aggregator struct { - lock sync.Mutex - kind number.Kind - state - } - - state struct { - sum number.Number - min number.Number - max number.Number - count uint64 - } -) - -var _ export.Aggregator = &Aggregator{} -var _ aggregation.MinMaxSumCount = &Aggregator{} - -// New returns a new aggregator for computing the min, max, sum, and -// count. -// -// This type uses a mutex for Update() and SynchronizedMove() concurrency. -func New(cnt int, desc *metric.Descriptor) []Aggregator { - kind := desc.NumberKind() - aggs := make([]Aggregator, cnt) - for i := range aggs { - aggs[i] = Aggregator{ - kind: kind, - state: emptyState(kind), - } - } - return aggs -} - -// Aggregation returns an interface for reading the state of this aggregator. -func (c *Aggregator) Aggregation() aggregation.Aggregation { - return c -} - -// Kind returns aggregation.MinMaxSumCountKind. -func (c *Aggregator) Kind() aggregation.Kind { - return aggregation.MinMaxSumCountKind -} - -// Sum returns the sum of values in the checkpoint. -func (c *Aggregator) Sum() (number.Number, error) { - return c.sum, nil -} - -// Count returns the number of values in the checkpoint. -func (c *Aggregator) Count() (uint64, error) { - return c.count, nil -} - -// Min returns the minimum value in the checkpoint. -// The error value aggregation.ErrNoData will be returned -// if there were no measurements recorded during the checkpoint. -func (c *Aggregator) Min() (number.Number, error) { - if c.count == 0 { - return 0, aggregation.ErrNoData - } - return c.min, nil -} - -// Max returns the maximum value in the checkpoint. -// The error value aggregation.ErrNoData will be returned -// if there were no measurements recorded during the checkpoint. -func (c *Aggregator) Max() (number.Number, error) { - if c.count == 0 { - return 0, aggregation.ErrNoData - } - return c.max, nil -} - -// SynchronizedMove saves the current state into oa and resets the current state to -// the empty set. -func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - - if oa != nil && o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - c.lock.Lock() - if o != nil { - o.state = c.state - } - c.state = emptyState(c.kind) - c.lock.Unlock() - - return nil -} - -func emptyState(kind number.Kind) state { - return state{ - count: 0, - sum: 0, - min: kind.Maximum(), - max: kind.Minimum(), - } -} - -// Update adds the recorded measurement to the current data set. -func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { - kind := desc.NumberKind() - - c.lock.Lock() - defer c.lock.Unlock() - c.count++ - c.sum.AddNumber(kind, number) - if number.CompareNumber(kind, c.min) < 0 { - c.min = number - } - if number.CompareNumber(kind, c.max) > 0 { - c.max = number - } - return nil -} - -// Merge combines two data sets into one. -func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - - c.count += o.count - c.sum.AddNumber(desc.NumberKind(), o.sum) - - if c.min.CompareNumber(desc.NumberKind(), o.min) > 0 { - c.min.SetNumber(o.min) - } - if c.max.CompareNumber(desc.NumberKind(), o.max) < 0 { - c.max.SetNumber(o.max) - } - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go deleted file mode 100644 index fc96ddb4cba..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" - -import ( - "context" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/aggregator" -) - -// Aggregator aggregates counter events. -type Aggregator struct { - // current holds current increments to this counter record - // current needs to be aligned for 64-bit atomic operations. - value number.Number -} - -var _ export.Aggregator = &Aggregator{} -var _ export.Subtractor = &Aggregator{} -var _ aggregation.Sum = &Aggregator{} - -// New returns a new counter aggregator implemented by atomic -// operations. This aggregator implements the aggregation.Sum -// export interface. -func New(cnt int) []Aggregator { - return make([]Aggregator, cnt) -} - -// Aggregation returns an interface for reading the state of this aggregator. -func (c *Aggregator) Aggregation() aggregation.Aggregation { - return c -} - -// Kind returns aggregation.SumKind. -func (c *Aggregator) Kind() aggregation.Kind { - return aggregation.SumKind -} - -// Sum returns the last-checkpointed sum. This will never return an -// error. -func (c *Aggregator) Sum() (number.Number, error) { - return c.value, nil -} - -// SynchronizedMove atomically saves the current value into oa and resets the -// current sum to zero. -func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error { - if oa == nil { - c.value.SetRawAtomic(0) - return nil - } - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - o.value = c.value.SwapNumberAtomic(number.Number(0)) - return nil -} - -// Update atomically adds to the current value. -func (c *Aggregator) Update(_ context.Context, num number.Number, desc *metric.Descriptor) error { - c.value.AddNumberAtomic(desc.NumberKind(), num) - return nil -} - -// Merge combines two counters by adding their sums. -func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { - o, _ := oa.(*Aggregator) - if o == nil { - return aggregator.NewInconsistentAggregatorError(c, oa) - } - c.value.AddNumber(desc.NumberKind(), o.value) - return nil -} - -func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *metric.Descriptor) error { - op, _ := opAgg.(*Aggregator) - if op == nil { - return aggregator.NewInconsistentAggregatorError(c, opAgg) - } - - res, _ := resAgg.(*Aggregator) - if res == nil { - return aggregator.NewInconsistentAggregatorError(c, resAgg) - } - - res.value = c.value - res.value.AddNumber(descriptor.NumberKind(), number.NewNumberSignChange(descriptor.NumberKind(), op.value)) - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/atomicfields.go b/vendor/go.opentelemetry.io/otel/sdk/metric/atomicfields.go deleted file mode 100644 index bcb56b7eaa1..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/atomicfields.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/sdk/metric" - -import "unsafe" - -func AtomicFieldOffsets() map[string]uintptr { - return map[string]uintptr{ - "record.refMapped.value": unsafe.Offsetof(record{}.refMapped.value), - "record.updateCount": unsafe.Offsetof(record{}.updateCount), - } -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/config.go b/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/config.go deleted file mode 100644 index 87be85b9000..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/config.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package basic // import "go.opentelemetry.io/otel/sdk/metric/controller/basic" - -import ( - "time" - - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/resource" -) - -// Config contains configuration for a basic Controller. -type Config struct { - // Resource is the OpenTelemetry resource associated with all Meters - // created by the Controller. - Resource *resource.Resource - - // CollectPeriod is the interval between calls to Collect a - // checkpoint. - // - // When pulling metrics and not exporting, this is the minimum - // time between calls to Collect. In a pull-only - // configuration, collection is performed on demand; set - // CollectPeriod to 0 always recompute the export record set. - // - // When exporting metrics, this must be > 0. - // - // Default value is 10s. - CollectPeriod time.Duration - - // CollectTimeout is the timeout of the Context passed to - // Collect() and subsequently to Observer instrument callbacks. - // - // Default value is 10s. If zero, no Collect timeout is applied. - CollectTimeout time.Duration - - // Exporter is used for exporting metric data. - // - // Note: Exporters such as Prometheus that pull data do not implement - // export.Exporter. These will directly call Collect() and ForEach(). - Exporter export.Exporter - - // PushTimeout is the timeout of the Context when a exporter is configured. - // - // Default value is 10s. If zero, no Export timeout is applied. - PushTimeout time.Duration -} - -// Option is the interface that applies the value to a configuration option. -type Option interface { - // Apply sets the Option value of a Config. - Apply(*Config) -} - -// WithResource sets the Resource configuration option of a Config by merging it -// with the Resource configuration in the environment. -func WithResource(r *resource.Resource) Option { - res := resource.Merge(resource.Environment(), r) - return resourceOption{res} -} - -type resourceOption struct{ *resource.Resource } - -func (o resourceOption) Apply(config *Config) { - config.Resource = o.Resource -} - -// WithCollectPeriod sets the CollectPeriod configuration option of a Config. -func WithCollectPeriod(period time.Duration) Option { - return collectPeriodOption(period) -} - -type collectPeriodOption time.Duration - -func (o collectPeriodOption) Apply(config *Config) { - config.CollectPeriod = time.Duration(o) -} - -// WithCollectTimeout sets the CollectTimeout configuration option of a Config. -func WithCollectTimeout(timeout time.Duration) Option { - return collectTimeoutOption(timeout) -} - -type collectTimeoutOption time.Duration - -func (o collectTimeoutOption) Apply(config *Config) { - config.CollectTimeout = time.Duration(o) -} - -// WithExporter sets the exporter configuration option of a Config. -func WithExporter(exporter export.Exporter) Option { - return exporterOption{exporter} -} - -type exporterOption struct{ exporter export.Exporter } - -func (o exporterOption) Apply(config *Config) { - config.Exporter = o.exporter -} - -// WithPushTimeout sets the PushTimeout configuration option of a Config. -func WithPushTimeout(timeout time.Duration) Option { - return pushTimeoutOption(timeout) -} - -type pushTimeoutOption time.Duration - -func (o pushTimeoutOption) Apply(config *Config) { - config.PushTimeout = time.Duration(o) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go b/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go deleted file mode 100644 index 9a2e12777b4..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package basic // import "go.opentelemetry.io/otel/sdk/metric/controller/basic" - -import ( - "context" - "fmt" - "sync" - "time" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/registry" - export "go.opentelemetry.io/otel/sdk/export/metric" - sdk "go.opentelemetry.io/otel/sdk/metric" - controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time" - "go.opentelemetry.io/otel/sdk/resource" -) - -// DefaultPeriod is used for: -// -// - the minimum time between calls to Collect() -// - the timeout for Export() -// - the timeout for Collect(). -const DefaultPeriod = 10 * time.Second - -// ErrControllerStarted indicates that a controller was started more -// than once. -var ErrControllerStarted = fmt.Errorf("controller already started") - -// Controller organizes and synchronizes collection of metric data in -// both "pull" and "push" configurations. This supports two distinct -// modes: -// -// - Push and Pull: Start() must be called to begin calling the exporter; -// Collect() is called periodically by a background thread after starting -// the controller. -// - Pull-Only: Start() is optional in this case, to call Collect periodically. -// If Start() is not called, Collect() can be called manually to initiate -// collection -// -// The controller supports mixing push and pull access to metric data -// using the export.CheckpointSet RWLock interface. Collection will -// be blocked by a pull request in the basic controller. -type Controller struct { - lock sync.Mutex - accumulator *sdk.Accumulator - provider *registry.MeterProvider - checkpointer export.Checkpointer - exporter export.Exporter - wg sync.WaitGroup - stopCh chan struct{} - clock controllerTime.Clock - ticker controllerTime.Ticker - - collectPeriod time.Duration - collectTimeout time.Duration - pushTimeout time.Duration - - // collectedTime is used only in configurations with no - // exporter, when ticker != nil. - collectedTime time.Time -} - -// New constructs a Controller using the provided checkpointer and -// options (including optional exporter) to configure a metric -// export pipeline. -func New(checkpointer export.Checkpointer, opts ...Option) *Controller { - c := &Config{ - CollectPeriod: DefaultPeriod, - CollectTimeout: DefaultPeriod, - PushTimeout: DefaultPeriod, - } - for _, opt := range opts { - opt.Apply(c) - } - if c.Resource == nil { - c.Resource = resource.Default() - } - - impl := sdk.NewAccumulator( - checkpointer, - c.Resource, - ) - return &Controller{ - provider: registry.NewMeterProvider(impl), - accumulator: impl, - checkpointer: checkpointer, - exporter: c.Exporter, - stopCh: nil, - clock: controllerTime.RealClock{}, - - collectPeriod: c.CollectPeriod, - collectTimeout: c.CollectTimeout, - pushTimeout: c.PushTimeout, - } -} - -// SetClock supports setting a mock clock for testing. This must be -// called before Start(). -func (c *Controller) SetClock(clock controllerTime.Clock) { - c.lock.Lock() - defer c.lock.Unlock() - c.clock = clock -} - -// MeterProvider returns a MeterProvider instance for this controller. -func (c *Controller) MeterProvider() metric.MeterProvider { - return c.provider -} - -// Start begins a ticker that periodically collects and exports -// metrics with the configured interval. This is required for calling -// a configured Exporter (see WithExporter) and is otherwise optional -// when only pulling metric data. -// -// The passed context is passed to Collect() and subsequently to -// asynchronous instrument callbacks. Returns an error when the -// controller was already started. -// -// Note that it is not necessary to Start a controller when only -// pulling data; use the Collect() and ForEach() methods directly in -// this case. -func (c *Controller) Start(ctx context.Context) error { - c.lock.Lock() - defer c.lock.Unlock() - - if c.stopCh != nil { - return ErrControllerStarted - } - - c.wg.Add(1) - c.stopCh = make(chan struct{}) - c.ticker = c.clock.Ticker(c.collectPeriod) - go c.runTicker(ctx, c.stopCh) - return nil -} - -// Stop waits for the background goroutine to return and then collects -// and exports metrics one last time before returning. The passed -// context is passed to the final Collect() and subsequently to the -// final asynchronous instruments. -// -// Note that Stop() will not cancel an ongoing collection or export. -func (c *Controller) Stop(ctx context.Context) error { - c.lock.Lock() - defer c.lock.Unlock() - - if c.stopCh == nil { - return nil - } - - close(c.stopCh) - c.stopCh = nil - c.wg.Wait() - c.ticker.Stop() - c.ticker = nil - - return c.collect(ctx) -} - -// runTicker collection on ticker events until the stop channel is closed. -func (c *Controller) runTicker(ctx context.Context, stopCh chan struct{}) { - defer c.wg.Done() - for { - select { - case <-stopCh: - return - case <-c.ticker.C(): - if err := c.collect(ctx); err != nil { - otel.Handle(err) - } - } - } -} - -// collect computes a checkpoint and optionally exports it. -func (c *Controller) collect(ctx context.Context) error { - if err := c.checkpoint(ctx, func() bool { - return true - }); err != nil { - return err - } - if c.exporter == nil { - return nil - } - // Note: this is not subject to collectTimeout. This blocks the next - // collection despite collectTimeout because it holds a lock. - if err := c.export(ctx); err != nil { - return err - } - return nil -} - -// checkpoint calls the Accumulator and Checkpointer interfaces to -// compute the CheckpointSet. This applies the configured collection -// timeout. Note that this does not try to cancel a Collect or Export -// when Stop() is called. -func (c *Controller) checkpoint(ctx context.Context, cond func() bool) error { - ckpt := c.checkpointer.CheckpointSet() - ckpt.Lock() - defer ckpt.Unlock() - - if !cond() { - return nil - } - c.checkpointer.StartCollection() - - if c.collectTimeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.collectTimeout) - defer cancel() - } - - _ = c.accumulator.Collect(ctx) - - var err error - select { - case <-ctx.Done(): - err = ctx.Err() - default: - // The context wasn't done, ok. - } - - // Finish the checkpoint whether the accumulator timed out or not. - if cerr := c.checkpointer.FinishCollection(); cerr != nil { - if err == nil { - err = cerr - } else { - err = fmt.Errorf("%s: %w", cerr.Error(), err) - } - } - - return err -} - -// export calls the exporter with a read lock on the CheckpointSet, -// applying the configured export timeout. -func (c *Controller) export(ctx context.Context) error { - ckpt := c.checkpointer.CheckpointSet() - ckpt.RLock() - defer ckpt.RUnlock() - - if c.pushTimeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.pushTimeout) - defer cancel() - } - - return c.exporter.Export(ctx, ckpt) -} - -// Foreach gives the caller read-locked access to the current -// export.CheckpointSet. -func (c *Controller) ForEach(ks export.ExportKindSelector, f func(export.Record) error) error { - ckpt := c.checkpointer.CheckpointSet() - ckpt.RLock() - defer ckpt.RUnlock() - - return ckpt.ForEach(ks, f) -} - -// IsRunning returns true if the controller was started via Start(), -// indicating that the current export.CheckpointSet is being kept -// up-to-date. -func (c *Controller) IsRunning() bool { - c.lock.Lock() - defer c.lock.Unlock() - return c.ticker != nil -} - -// Collect requests a collection. The collection will be skipped if -// the last collection is aged less than the configured collection -// period. -func (c *Controller) Collect(ctx context.Context) error { - if c.IsRunning() { - // When there's a non-nil ticker, there's a goroutine - // computing checkpoints with the collection period. - return ErrControllerStarted - } - - return c.checkpoint(ctx, c.shouldCollect) -} - -// shouldCollect returns true if the collector should collect now, -// based on the timestamp, the last collection time, and the -// configured period. -func (c *Controller) shouldCollect() bool { - // This is called with the CheckpointSet exclusive - // lock held. - if c.collectPeriod == 0 { - return true - } - now := c.clock.Now() - if now.Sub(c.collectedTime) < c.collectPeriod { - return false - } - c.collectedTime = now - return true -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/time/time.go b/vendor/go.opentelemetry.io/otel/sdk/metric/controller/time/time.go deleted file mode 100644 index 08bc44dbf73..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/controller/time/time.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package time // import "go.opentelemetry.io/otel/sdk/metric/controller/time" - -import ( - "time" - lib "time" -) - -// Several types below are created to match "github.com/benbjohnson/clock" -// so that it remains a test-only dependency. - -type Clock interface { - Now() lib.Time - Ticker(duration lib.Duration) Ticker -} - -type Ticker interface { - Stop() - C() <-chan lib.Time -} - -type RealClock struct { -} - -type RealTicker struct { - ticker *lib.Ticker -} - -var _ Clock = RealClock{} -var _ Ticker = RealTicker{} - -func (RealClock) Now() time.Time { - return time.Now() -} - -func (RealClock) Ticker(period time.Duration) Ticker { - return RealTicker{time.NewTicker(period)} -} - -func (t RealTicker) Stop() { - t.ticker.Stop() -} - -func (t RealTicker) C() <-chan time.Time { - return t.ticker.C -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go deleted file mode 100644 index c6ac21c497a..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package metric implements the OpenTelemetry metric API. - -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - -The Accumulator type supports configurable metrics export behavior through a -collection of export interfaces that support various export strategies, -described below. - -The OpenTelemetry metric API consists of methods for constructing synchronous -and asynchronous instruments. There are two constructors per instrument for -the two kinds of number (int64, float64). - -Synchronous instruments are managed by a sync.Map containing a *record -with the current state for each synchronous instrument. A bound -instrument encapsulates a direct pointer to the record, allowing -bound metric events to bypass a sync.Map lookup. A lock-free -algorithm is used to protect against races when adding and removing -items from the sync.Map. - -Asynchronous instruments are managed by an internal -AsyncInstrumentState, which coordinates calling batch and single -instrument callbacks. - -Internal Structure - -Each observer also has its own kind of record stored in the SDK. This -record contains a set of recorders for every specific label set used in the -callback. - -A sync.Map maintains the mapping of current instruments and label sets to -internal records. To create a new bound instrument, the SDK consults the Map to -locate an existing record, otherwise it constructs a new record. The SDK -maintains a count of the number of references to each record, ensuring -that records are not reclaimed from the Map while they are still active -from the user's perspective. - -Metric collection is performed via a single-threaded call to Collect that -sweeps through all records in the SDK, checkpointing their state. When a -record is discovered that has no references and has not been updated since -the prior collection pass, it is removed from the Map. - -Both synchronous and asynchronous instruments have an associated -aggregator, which maintains the current state resulting from all metric -events since its last checkpoint. Aggregators may be lock-free or they may -use locking, but they should expect to be called concurrently. Aggregators -must be capable of merging with another aggregator of the same type. - -Export Pipeline - -While the SDK serves to maintain a current set of records and -coordinate collection, the behavior of a metrics export pipeline is -configured through the export types in -go.opentelemetry.io/otel/sdk/export/metric. It is important to keep -in mind the context these interfaces are called from. There are two -contexts, instrumentation context, where a user-level goroutine that -enters the SDK resulting in a new record, and collection context, -where a system-level thread performs a collection pass through the -SDK. - -Descriptor is a struct that describes the metric instrument to the -export pipeline, containing the name, units, description, metric kind, -number kind (int64 or float64). A Descriptor accompanies metric data -as it passes through the export pipeline. - -The AggregatorSelector interface supports choosing the method of -aggregation to apply to a particular instrument, by delegating the -construction of an Aggregator to this interface. Given the Descriptor, -the AggregatorFor method returns an implementation of Aggregator. If this -interface returns nil, the metric will be disabled. The aggregator should -be matched to the capabilities of the exporter. Selecting the aggregator -for Adding instruments is relatively straightforward, but many options -are available for aggregating distributions from Grouping instruments. - -Aggregator is an interface which implements a concrete strategy for -aggregating metric updates. Several Aggregator implementations are -provided by the SDK. Aggregators may be lock-free or use locking, -depending on their structure and semantics. Aggregators implement an -Update method, called in instrumentation context, to receive a single -metric event. Aggregators implement a Checkpoint method, called in -collection context, to save a checkpoint of the current state. -Aggregators implement a Merge method, also called in collection -context, that combines state from two aggregators into one. Each SDK -record has an associated aggregator. - -Processor is an interface which sits between the SDK and an exporter. -The Processor embeds an AggregatorSelector, used by the SDK to assign -new Aggregators. The Processor supports a Process() API for submitting -checkpointed aggregators to the processor, and a CheckpointSet() API -for producing a complete checkpoint for the exporter. Two default -Processor implementations are provided, the "defaultkeys" Processor groups -aggregate metrics by their recommended Descriptor.Keys(), the -"simple" Processor aggregates metrics at full dimensionality. - -LabelEncoder is an optional optimization that allows an exporter to -provide the serialization logic for labels. This allows avoiding -duplicate serialization of labels, once as a unique key in the SDK (or -Processor) and once in the exporter. - -CheckpointSet is an interface between the Processor and the Exporter. -After completing a collection pass, the Processor.CheckpointSet() method -returns a CheckpointSet, which the Exporter uses to iterate over all -the updated metrics. - -Record is a struct containing the state of an individual exported -metric. This is the result of one collection interface for one -instrument and one label set. - -Labels is a struct containing an ordered set of labels, the -corresponding unique encoding, and the encoder that produced it. - -Exporter is the final stage of an export pipeline. It is called with -a CheckpointSet capable of enumerating all the updated metrics. - -Controller is not an export interface per se, but it orchestrates the -export pipeline. For example, a "push" controller will establish a -periodic timer to regularly collect and export metrics. A "pull" -controller will await a pull request before initiating metric -collection. Either way, the job of the controller is to call the SDK -Collect() method, then read the checkpoint, then invoke the exporter. -Controllers are expected to implement the public metric.MeterProvider -API, meaning they can be installed as the global Meter provider. - -*/ -package metric // import "go.opentelemetry.io/otel/sdk/metric" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go b/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go deleted file mode 100644 index 39d1972dc9b..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package basic // import "go.opentelemetry.io/otel/sdk/metric/processor/basic" - -import ( - "errors" - "fmt" - "sync" - "time" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/export/metric/aggregation" - "go.opentelemetry.io/otel/sdk/resource" -) - -type ( - Processor struct { - export.ExportKindSelector - export.AggregatorSelector - - state - } - - stateKey struct { - // TODO: This code is organized to support multiple - // accumulators which could theoretically produce the - // data for the same instrument with the same - // resources, and this code has logic to combine data - // properly from multiple accumulators. However, the - // use of *metric.Descriptor in the stateKey makes - // such combination impossible, because each - // accumulator allocates its own instruments. This - // can be fixed by using the instrument name and kind - // instead of the descriptor pointer. See - // https://github.com/open-telemetry/opentelemetry-go/issues/862. - descriptor *metric.Descriptor - distinct attribute.Distinct - resource attribute.Distinct - } - - stateValue struct { - // labels corresponds to the stateKey.distinct field. - labels *attribute.Set - - // resource corresponds to the stateKey.resource field. - resource *resource.Resource - - // updated indicates the last sequence number when this value had - // Process() called by an accumulator. - updated int64 - - // stateful indicates that a cumulative aggregation is - // being maintained, taken from the process start time. - stateful bool - - // currentOwned indicates that "current" was allocated - // by the processor in order to merge results from - // multiple Accumulators during a single collection - // round, which may happen either because: - // (1) multiple Accumulators output the same Accumulation. - // (2) one Accumulator is configured with dimensionality reduction. - currentOwned bool - - // current refers to the output from a single Accumulator - // (if !currentOwned) or it refers to an Aggregator - // owned by the processor used to accumulate multiple - // values in a single collection round. - current export.Aggregator - - // delta, if non-nil, refers to an Aggregator owned by - // the processor used to compute deltas between - // precomputed sums. - delta export.Aggregator - - // cumulative, if non-nil, refers to an Aggregator owned - // by the processor used to store the last cumulative - // value. - cumulative export.Aggregator - } - - state struct { - config Config - - // RWMutex implements locking for the `CheckpointSet` interface. - sync.RWMutex - values map[stateKey]*stateValue - - // Note: the timestamp logic currently assumes all - // exports are deltas. - - processStart time.Time - intervalStart time.Time - intervalEnd time.Time - - // startedCollection and finishedCollection are the - // number of StartCollection() and FinishCollection() - // calls, used to ensure that the sequence of starts - // and finishes are correctly balanced. - - startedCollection int64 - finishedCollection int64 - } -) - -var _ export.Processor = &Processor{} -var _ export.Checkpointer = &Processor{} -var _ export.CheckpointSet = &state{} -var ErrInconsistentState = fmt.Errorf("inconsistent processor state") -var ErrInvalidExportKind = fmt.Errorf("invalid export kind") - -// New returns a basic Processor that is also a Checkpointer using the provided -// AggregatorSelector to select Aggregators. The ExportKindSelector -// is consulted to determine the kind(s) of exporter that will consume -// data, so that this Processor can prepare to compute Delta or -// Cumulative Aggregations as needed. -func New(aselector export.AggregatorSelector, eselector export.ExportKindSelector, opts ...Option) *Processor { - now := time.Now() - p := &Processor{ - AggregatorSelector: aselector, - ExportKindSelector: eselector, - state: state{ - values: map[stateKey]*stateValue{}, - processStart: now, - intervalStart: now, - }, - } - for _, opt := range opts { - opt.ApplyProcessor(&p.config) - } - return p -} - -// Process implements export.Processor. -func (b *Processor) Process(accum export.Accumulation) error { - if b.startedCollection != b.finishedCollection+1 { - return ErrInconsistentState - } - desc := accum.Descriptor() - key := stateKey{ - descriptor: desc, - distinct: accum.Labels().Equivalent(), - resource: accum.Resource().Equivalent(), - } - agg := accum.Aggregator() - - // Check if there is an existing value. - value, ok := b.state.values[key] - if !ok { - stateful := b.ExportKindFor(desc, agg.Aggregation().Kind()).MemoryRequired(desc.InstrumentKind()) - - newValue := &stateValue{ - labels: accum.Labels(), - resource: accum.Resource(), - updated: b.state.finishedCollection, - stateful: stateful, - current: agg, - } - if stateful { - if desc.InstrumentKind().PrecomputedSum() { - // If we know we need to compute deltas, allocate two aggregators. - b.AggregatorFor(desc, &newValue.cumulative, &newValue.delta) - } else { - // In this case we are certain not to need a delta, only allocate - // a cumulative aggregator. - b.AggregatorFor(desc, &newValue.cumulative) - } - } - b.state.values[key] = newValue - return nil - } - - // Advance the update sequence number. - sameCollection := b.state.finishedCollection == value.updated - value.updated = b.state.finishedCollection - - // At this point in the code, we have located an existing - // value for some stateKey. This can be because: - // - // (a) stateful aggregation is being used, the entry was - // entered during a prior collection, and this is the first - // time processing an accumulation for this stateKey in the - // current collection. Since this is the first time - // processing an accumulation for this stateKey during this - // collection, we don't know yet whether there are multiple - // accumulators at work. If there are multiple accumulators, - // they'll hit case (b) the second time through. - // - // (b) multiple accumulators are being used, whether stateful - // or not. - // - // Case (a) occurs when the instrument and the exporter - // require memory to work correctly, either because the - // instrument reports a PrecomputedSum to a DeltaExporter or - // the reverse, a non-PrecomputedSum instrument with a - // CumulativeExporter. This logic is encapsulated in - // ExportKind.MemoryRequired(InstrumentKind). - // - // Case (b) occurs when the variable `sameCollection` is true, - // indicating that the stateKey for Accumulation has already - // been seen in the same collection. When this happens, it - // implies that multiple Accumulators are being used, or that - // a single Accumulator has been configured with a label key - // filter. - - if !sameCollection { - if !value.currentOwned { - // This is the first Accumulation we've seen - // for this stateKey during this collection. - // Just keep a reference to the Accumulator's - // Aggregator. All the other cases copy - // Aggregator state. - value.current = agg - return nil - } - return agg.SynchronizedMove(value.current, desc) - } - - // If the current is not owned, take ownership of a copy - // before merging below. - if !value.currentOwned { - tmp := value.current - b.AggregatorSelector.AggregatorFor(desc, &value.current) - value.currentOwned = true - if err := tmp.SynchronizedMove(value.current, desc); err != nil { - return err - } - } - - // Combine this Accumulation with the prior Accumulation. - return value.current.Merge(agg, desc) -} - -// CheckpointSet returns the associated CheckpointSet. Use the -// CheckpointSet Locker interface to synchronize access to this -// object. The CheckpointSet.ForEach() method cannot be called -// concurrently with Process(). -func (b *Processor) CheckpointSet() export.CheckpointSet { - return &b.state -} - -// StartCollection signals to the Processor one or more Accumulators -// will begin calling Process() calls during collection. -func (b *Processor) StartCollection() { - if b.startedCollection != 0 { - b.intervalStart = b.intervalEnd - } - b.startedCollection++ -} - -// FinishCollection signals to the Processor that a complete -// collection has finished and that ForEach will be called to access -// the CheckpointSet. -func (b *Processor) FinishCollection() error { - b.intervalEnd = time.Now() - if b.startedCollection != b.finishedCollection+1 { - return ErrInconsistentState - } - defer func() { b.finishedCollection++ }() - - for key, value := range b.values { - mkind := key.descriptor.InstrumentKind() - stale := value.updated != b.finishedCollection - stateless := !value.stateful - - // The following branch updates stateful aggregators. Skip - // these updates if the aggregator is not stateful or if the - // aggregator is stale. - if stale || stateless { - // If this processor does not require memeory, - // stale, stateless entries can be removed. - // This implies that they were not updated - // over the previous full collection interval. - if stale && stateless && !b.config.Memory { - delete(b.values, key) - } - continue - } - - // Update Aggregator state to support exporting either a - // delta or a cumulative aggregation. - var err error - if mkind.PrecomputedSum() { - if currentSubtractor, ok := value.current.(export.Subtractor); ok { - // This line is equivalent to: - // value.delta = currentSubtractor - value.cumulative - err = currentSubtractor.Subtract(value.cumulative, value.delta, key.descriptor) - - if err == nil { - err = value.current.SynchronizedMove(value.cumulative, key.descriptor) - } - } else { - err = aggregation.ErrNoSubtraction - } - } else { - // This line is equivalent to: - // value.cumulative = value.cumulative + value.delta - err = value.cumulative.Merge(value.current, key.descriptor) - } - if err != nil { - return err - } - } - return nil -} - -// ForEach iterates through the CheckpointSet, passing an -// export.Record with the appropriate Cumulative or Delta aggregation -// to an exporter. -func (b *state) ForEach(exporter export.ExportKindSelector, f func(export.Record) error) error { - if b.startedCollection != b.finishedCollection { - return ErrInconsistentState - } - for key, value := range b.values { - mkind := key.descriptor.InstrumentKind() - - var agg aggregation.Aggregation - var start time.Time - - // If the processor does not have Config.Memory and it was not updated - // in the prior round, do not visit this value. - if !b.config.Memory && value.updated != (b.finishedCollection-1) { - continue - } - - ekind := exporter.ExportKindFor(key.descriptor, value.current.Aggregation().Kind()) - switch ekind { - case export.CumulativeExportKind: - // If stateful, the sum has been computed. If stateless, the - // input was already cumulative. Either way, use the checkpointed - // value: - if value.stateful { - agg = value.cumulative.Aggregation() - } else { - agg = value.current.Aggregation() - } - start = b.processStart - - case export.DeltaExportKind: - // Precomputed sums are a special case. - if mkind.PrecomputedSum() { - agg = value.delta.Aggregation() - } else { - agg = value.current.Aggregation() - } - start = b.intervalStart - - default: - return fmt.Errorf("%v: %w", ekind, ErrInvalidExportKind) - } - - if err := f(export.NewRecord( - key.descriptor, - value.labels, - value.resource, - agg, - start, - b.intervalEnd, - )); err != nil && !errors.Is(err, aggregation.ErrNoData) { - return err - } - } - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/config.go b/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/config.go deleted file mode 100644 index bf9d976c809..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/config.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package basic // import "go.opentelemetry.io/otel/sdk/metric/processor/basic" - -// Config contains the options for configuring a basic metric processor. -type Config struct { - // Memory controls whether the processor remembers metric - // instruments and label sets that were previously reported. - // When Memory is true, CheckpointSet.ForEach() will visit - // metrics that were not updated in the most recent interval. - Memory bool -} - -type Option interface { - ApplyProcessor(*Config) -} - -// WithMemory sets the memory behavior of a Processor. If this is -// true, the processor will report metric instruments and label sets -// that were previously reported but not updated in the most recent -// interval. -func WithMemory(memory bool) Option { - return memoryOption(memory) -} - -type memoryOption bool - -func (m memoryOption) ApplyProcessor(config *Config) { - config.Memory = bool(m) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/refcount_mapped.go b/vendor/go.opentelemetry.io/otel/sdk/metric/refcount_mapped.go deleted file mode 100644 index 9abfb9cca70..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/refcount_mapped.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/sdk/metric" - -import ( - "sync/atomic" -) - -// refcountMapped atomically counts the number of references (usages) of an entry -// while also keeping a state of mapped/unmapped into a different data structure -// (an external map or list for example). -// -// refcountMapped uses an atomic value where the least significant bit is used to -// keep the state of mapping ('1' is used for unmapped and '0' is for mapped) and -// the rest of the bits are used for refcounting. -type refcountMapped struct { - // refcount has to be aligned for 64-bit atomic operations. - value int64 -} - -// ref returns true if the entry is still mapped and increases the -// reference usages, if unmapped returns false. -func (rm *refcountMapped) ref() bool { - // Check if this entry was marked as unmapped between the moment - // we got a reference to it (or will be removed very soon) and here. - return atomic.AddInt64(&rm.value, 2)&1 == 0 -} - -func (rm *refcountMapped) unref() { - atomic.AddInt64(&rm.value, -2) -} - -// tryUnmap flips the mapped bit to "unmapped" state and returns true if both of the -// following conditions are true upon entry to this function: -// * There are no active references; -// * The mapped bit is in "mapped" state. -// Otherwise no changes are done to mapped bit and false is returned. -func (rm *refcountMapped) tryUnmap() bool { - if atomic.LoadInt64(&rm.value) != 0 { - return false - } - return atomic.CompareAndSwapInt64( - &rm.value, - 0, - 1, - ) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go b/vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go deleted file mode 100644 index 268fa742da7..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go +++ /dev/null @@ -1,555 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/sdk/metric" - -import ( - "context" - "fmt" - "runtime" - "sync" - "sync/atomic" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - internal "go.opentelemetry.io/otel/internal/metric" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/metric/aggregator" - "go.opentelemetry.io/otel/sdk/resource" -) - -type ( - // Accumulator implements the OpenTelemetry Meter API. The - // Accumulator is bound to a single export.Processor in - // `NewAccumulator()`. - // - // The Accumulator supports a Collect() API to gather and export - // current data. Collect() should be arranged according to - // the processor model. Push-based processors will setup a - // timer to call Collect() periodically. Pull-based processors - // will call Collect() when a pull request arrives. - Accumulator struct { - // current maps `mapkey` to *record. - current sync.Map - - // asyncInstruments is a set of - // `*asyncInstrument` instances - asyncLock sync.Mutex - asyncInstruments *internal.AsyncInstrumentState - - // currentEpoch is the current epoch number. It is - // incremented in `Collect()`. - currentEpoch int64 - - // processor is the configured processor+configuration. - processor export.Processor - - // collectLock prevents simultaneous calls to Collect(). - collectLock sync.Mutex - - // asyncSortSlice has a single purpose - as a temporary - // place for sorting during labels creation to avoid - // allocation. It is cleared after use. - asyncSortSlice attribute.Sortable - - // resource is applied to all records in this Accumulator. - resource *resource.Resource - } - - syncInstrument struct { - instrument - } - - // mapkey uniquely describes a metric instrument in terms of - // its InstrumentID and the encoded form of its labels. - mapkey struct { - descriptor *metric.Descriptor - ordered attribute.Distinct - } - - // record maintains the state of one metric instrument. Due - // the use of lock-free algorithms, there may be more than one - // `record` in existence at a time, although at most one can - // be referenced from the `Accumulator.current` map. - record struct { - // refMapped keeps track of refcounts and the mapping state to the - // Accumulator.current map. - refMapped refcountMapped - - // updateCount is incremented on every Update. - updateCount int64 - - // collectedCount is set to updateCount on collection, - // supports checking for no updates during a round. - collectedCount int64 - - // storage is the stored label set for this record, - // except in cases where a label set is shared due to - // batch recording. - storage attribute.Set - - // labels is the processed label set for this record. - // this may refer to the `storage` field in another - // record if this label set is shared resulting from - // `RecordBatch`. - labels *attribute.Set - - // sortSlice has a single purpose - as a temporary - // place for sorting during labels creation to avoid - // allocation. - sortSlice attribute.Sortable - - // inst is a pointer to the corresponding instrument. - inst *syncInstrument - - // current implements the actual RecordOne() API, - // depending on the type of aggregation. If nil, the - // metric was disabled by the exporter. - current export.Aggregator - checkpoint export.Aggregator - } - - instrument struct { - meter *Accumulator - descriptor metric.Descriptor - } - - asyncInstrument struct { - instrument - // recorders maps ordered labels to the pair of - // labelset and recorder - recorders map[attribute.Distinct]*labeledRecorder - } - - labeledRecorder struct { - observedEpoch int64 - labels *attribute.Set - observed export.Aggregator - } -) - -var ( - _ metric.MeterImpl = &Accumulator{} - _ metric.AsyncImpl = &asyncInstrument{} - _ metric.SyncImpl = &syncInstrument{} - _ metric.BoundSyncImpl = &record{} - - ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument") -) - -func (inst *instrument) Descriptor() metric.Descriptor { - return inst.descriptor -} - -func (a *asyncInstrument) Implementation() interface{} { - return a -} - -func (s *syncInstrument) Implementation() interface{} { - return s -} - -func (a *asyncInstrument) observe(num number.Number, labels *attribute.Set) { - if err := aggregator.RangeTest(num, &a.descriptor); err != nil { - otel.Handle(err) - return - } - recorder := a.getRecorder(labels) - if recorder == nil { - // The instrument is disabled according to the - // AggregatorSelector. - return - } - if err := recorder.Update(context.Background(), num, &a.descriptor); err != nil { - otel.Handle(err) - return - } -} - -func (a *asyncInstrument) getRecorder(labels *attribute.Set) export.Aggregator { - lrec, ok := a.recorders[labels.Equivalent()] - if ok { - // Note: SynchronizedMove(nil) can't return an error - _ = lrec.observed.SynchronizedMove(nil, &a.descriptor) - lrec.observedEpoch = a.meter.currentEpoch - a.recorders[labels.Equivalent()] = lrec - return lrec.observed - } - var rec export.Aggregator - a.meter.processor.AggregatorFor(&a.descriptor, &rec) - if a.recorders == nil { - a.recorders = make(map[attribute.Distinct]*labeledRecorder) - } - // This may store nil recorder in the map, thus disabling the - // asyncInstrument for the labelset for good. This is intentional, - // but will be revisited later. - a.recorders[labels.Equivalent()] = &labeledRecorder{ - observed: rec, - labels: labels, - observedEpoch: a.meter.currentEpoch, - } - return rec -} - -// acquireHandle gets or creates a `*record` corresponding to `kvs`, -// the input labels. The second argument `labels` is passed in to -// support re-use of the orderedLabels computed by a previous -// measurement in the same batch. This performs two allocations -// in the common case. -func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attribute.Set) *record { - var rec *record - var equiv attribute.Distinct - - if labelPtr == nil { - // This memory allocation may not be used, but it's - // needed for the `sortSlice` field, to avoid an - // allocation while sorting. - rec = &record{} - rec.storage = attribute.NewSetWithSortable(kvs, &rec.sortSlice) - rec.labels = &rec.storage - equiv = rec.storage.Equivalent() - } else { - equiv = labelPtr.Equivalent() - } - - // Create lookup key for sync.Map (one allocation, as this - // passes through an interface{}) - mk := mapkey{ - descriptor: &s.descriptor, - ordered: equiv, - } - - if actual, ok := s.meter.current.Load(mk); ok { - // Existing record case. - existingRec := actual.(*record) - if existingRec.refMapped.ref() { - // At this moment it is guaranteed that the entry is in - // the map and will not be removed. - return existingRec - } - // This entry is no longer mapped, try to add a new entry. - } - - if rec == nil { - rec = &record{} - rec.labels = labelPtr - } - rec.refMapped = refcountMapped{value: 2} - rec.inst = s - - s.meter.processor.AggregatorFor(&s.descriptor, &rec.current, &rec.checkpoint) - - for { - // Load/Store: there's a memory allocation to place `mk` into - // an interface here. - if actual, loaded := s.meter.current.LoadOrStore(mk, rec); loaded { - // Existing record case. Cannot change rec here because if fail - // will try to add rec again to avoid new allocations. - oldRec := actual.(*record) - if oldRec.refMapped.ref() { - // At this moment it is guaranteed that the entry is in - // the map and will not be removed. - return oldRec - } - // This loaded entry is marked as unmapped (so Collect will remove - // it from the map immediately), try again - this is a busy waiting - // strategy to wait until Collect() removes this entry from the map. - // - // This can be improved by having a list of "Unmapped" entries for - // one time only usages, OR we can make this a blocking path and use - // a Mutex that protects the delete operation (delete only if the old - // record is associated with the key). - - // Let collector get work done to remove the entry from the map. - runtime.Gosched() - continue - } - // The new entry was added to the map, good to go. - return rec - } -} - -// The order of the input array `kvs` may be sorted after the function is called. -func (s *syncInstrument) Bind(kvs []attribute.KeyValue) metric.BoundSyncImpl { - return s.acquireHandle(kvs, nil) -} - -// The order of the input array `kvs` may be sorted after the function is called. -func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) { - h := s.acquireHandle(kvs, nil) - defer h.Unbind() - h.RecordOne(ctx, num) -} - -// NewAccumulator constructs a new Accumulator for the given -// processor. This Accumulator supports only a single processor. -// -// The Accumulator does not start any background process to collect itself -// periodically, this responsibility lies with the processor, typically, -// depending on the type of export. For example, a pull-based -// processor will call Collect() when it receives a request to scrape -// current metric values. A push-based processor should configure its -// own periodic collection. -func NewAccumulator(processor export.Processor, resource *resource.Resource) *Accumulator { - return &Accumulator{ - processor: processor, - asyncInstruments: internal.NewAsyncInstrumentState(), - resource: resource, - } -} - -// NewSyncInstrument implements metric.MetricImpl. -func (m *Accumulator) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) { - return &syncInstrument{ - instrument: instrument{ - descriptor: descriptor, - meter: m, - }, - }, nil -} - -// NewAsyncInstrument implements metric.MetricImpl. -func (m *Accumulator) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (metric.AsyncImpl, error) { - a := &asyncInstrument{ - instrument: instrument{ - descriptor: descriptor, - meter: m, - }, - } - m.asyncLock.Lock() - defer m.asyncLock.Unlock() - m.asyncInstruments.Register(a, runner) - return a, nil -} - -// Collect traverses the list of active records and observers and -// exports data for each active instrument. Collect() may not be -// called concurrently. -// -// During the collection pass, the export.Processor will receive -// one Export() call per current aggregation. -// -// Returns the number of records that were checkpointed. -func (m *Accumulator) Collect(ctx context.Context) int { - m.collectLock.Lock() - defer m.collectLock.Unlock() - - checkpointed := m.observeAsyncInstruments(ctx) - checkpointed += m.collectSyncInstruments() - m.currentEpoch++ - - return checkpointed -} - -func (m *Accumulator) collectSyncInstruments() int { - checkpointed := 0 - - m.current.Range(func(key interface{}, value interface{}) bool { - // Note: always continue to iterate over the entire - // map by returning `true` in this function. - inuse := value.(*record) - - mods := atomic.LoadInt64(&inuse.updateCount) - coll := inuse.collectedCount - - if mods != coll { - // Updates happened in this interval, - // checkpoint and continue. - checkpointed += m.checkpointRecord(inuse) - inuse.collectedCount = mods - return true - } - - // Having no updates since last collection, try to unmap: - if unmapped := inuse.refMapped.tryUnmap(); !unmapped { - // The record is referenced by a binding, continue. - return true - } - - // If any other goroutines are now trying to re-insert this - // entry in the map, they are busy calling Gosched() awaiting - // this deletion: - m.current.Delete(inuse.mapkey()) - - // There's a potential race between `LoadInt64` and - // `tryUnmap` in this function. Since this is the - // last we'll see of this record, checkpoint - mods = atomic.LoadInt64(&inuse.updateCount) - if mods != coll { - checkpointed += m.checkpointRecord(inuse) - } - return true - }) - - return checkpointed -} - -// CollectAsync implements internal.AsyncCollector. -// The order of the input array `kvs` may be sorted after the function is called. -func (m *Accumulator) CollectAsync(kv []attribute.KeyValue, obs ...metric.Observation) { - labels := attribute.NewSetWithSortable(kv, &m.asyncSortSlice) - - for _, ob := range obs { - if a := m.fromAsync(ob.AsyncImpl()); a != nil { - a.observe(ob.Number(), &labels) - } - } -} - -func (m *Accumulator) observeAsyncInstruments(ctx context.Context) int { - m.asyncLock.Lock() - defer m.asyncLock.Unlock() - - asyncCollected := 0 - - m.asyncInstruments.Run(ctx, m) - - for _, inst := range m.asyncInstruments.Instruments() { - if a := m.fromAsync(inst); a != nil { - asyncCollected += m.checkpointAsync(a) - } - } - - return asyncCollected -} - -func (m *Accumulator) checkpointRecord(r *record) int { - if r.current == nil { - return 0 - } - err := r.current.SynchronizedMove(r.checkpoint, &r.inst.descriptor) - if err != nil { - otel.Handle(err) - return 0 - } - - a := export.NewAccumulation(&r.inst.descriptor, r.labels, m.resource, r.checkpoint) - err = m.processor.Process(a) - if err != nil { - otel.Handle(err) - } - return 1 -} - -func (m *Accumulator) checkpointAsync(a *asyncInstrument) int { - if len(a.recorders) == 0 { - return 0 - } - checkpointed := 0 - for encodedLabels, lrec := range a.recorders { - lrec := lrec - epochDiff := m.currentEpoch - lrec.observedEpoch - if epochDiff == 0 { - if lrec.observed != nil { - a := export.NewAccumulation(&a.descriptor, lrec.labels, m.resource, lrec.observed) - err := m.processor.Process(a) - if err != nil { - otel.Handle(err) - } - checkpointed++ - } - } else if epochDiff > 1 { - // This is second collection cycle with no - // observations for this labelset. Remove the - // recorder. - delete(a.recorders, encodedLabels) - } - } - if len(a.recorders) == 0 { - a.recorders = nil - } - return checkpointed -} - -// RecordBatch enters a batch of metric events. -// The order of the input array `kvs` may be sorted after the function is called. -func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue, measurements ...metric.Measurement) { - // Labels will be computed the first time acquireHandle is - // called. Subsequent calls to acquireHandle will re-use the - // previously computed value instead of recomputing the - // ordered labels. - var labelsPtr *attribute.Set - for i, meas := range measurements { - s := m.fromSync(meas.SyncImpl()) - if s == nil { - continue - } - h := s.acquireHandle(kvs, labelsPtr) - - // Re-use labels for the next measurement. - if i == 0 { - labelsPtr = h.labels - } - - defer h.Unbind() - h.RecordOne(ctx, meas.Number()) - } -} - -// RecordOne implements metric.SyncImpl. -func (r *record) RecordOne(ctx context.Context, num number.Number) { - if r.current == nil { - // The instrument is disabled according to the AggregatorSelector. - return - } - if err := aggregator.RangeTest(num, &r.inst.descriptor); err != nil { - otel.Handle(err) - return - } - if err := r.current.Update(ctx, num, &r.inst.descriptor); err != nil { - otel.Handle(err) - return - } - // Record was modified, inform the Collect() that things need - // to be collected while the record is still mapped. - atomic.AddInt64(&r.updateCount, 1) -} - -// Unbind implements metric.SyncImpl. -func (r *record) Unbind() { - r.refMapped.unref() -} - -func (r *record) mapkey() mapkey { - return mapkey{ - descriptor: &r.inst.descriptor, - ordered: r.labels.Equivalent(), - } -} - -// fromSync gets a sync implementation object, checking for -// uninitialized instruments and instruments created by another SDK. -func (m *Accumulator) fromSync(sync metric.SyncImpl) *syncInstrument { - if sync != nil { - if inst, ok := sync.Implementation().(*syncInstrument); ok { - return inst - } - } - otel.Handle(ErrUninitializedInstrument) - return nil -} - -// fromSync gets an async implementation object, checking for -// uninitialized instruments and instruments created by another SDK. -func (m *Accumulator) fromAsync(async metric.AsyncImpl) *asyncInstrument { - if async != nil { - if inst, ok := async.Implementation().(*asyncInstrument); ok { - return inst - } - } - otel.Handle(ErrUninitializedInstrument) - return nil -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go b/vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go deleted file mode 100644 index bb5760994ac..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple" - -import ( - "go.opentelemetry.io/otel/metric" - export "go.opentelemetry.io/otel/sdk/export/metric" - "go.opentelemetry.io/otel/sdk/metric/aggregator/exact" - "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" - "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" - "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" - "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" -) - -type ( - selectorInexpensive struct{} - selectorExact struct{} - selectorHistogram struct { - options []histogram.Option - } -) - -var ( - _ export.AggregatorSelector = selectorInexpensive{} - _ export.AggregatorSelector = selectorExact{} - _ export.AggregatorSelector = selectorHistogram{} -) - -// NewWithInexpensiveDistribution returns a simple aggregator selector -// that uses minmaxsumcount aggregators for `ValueRecorder` -// instruments. This selector is faster and uses less memory than the -// others in this package because minmaxsumcount aggregators maintain -// the least information about the distribution among these choices. -func NewWithInexpensiveDistribution() export.AggregatorSelector { - return selectorInexpensive{} -} - -// NewWithExactDistribution returns a simple aggregator selector that -// uses exact aggregators for `ValueRecorder` instruments. This -// selector uses more memory than the others in this package because -// exact aggregators maintain the most information about the -// distribution among these choices. -func NewWithExactDistribution() export.AggregatorSelector { - return selectorExact{} -} - -// NewWithHistogramDistribution returns a simple aggregator selector -// that uses histogram aggregators for `ValueRecorder` instruments. -// This selector is a good default choice for most metric exporters. -func NewWithHistogramDistribution(options ...histogram.Option) export.AggregatorSelector { - return selectorHistogram{options: options} -} - -func sumAggs(aggPtrs []*export.Aggregator) { - aggs := sum.New(len(aggPtrs)) - for i := range aggPtrs { - *aggPtrs[i] = &aggs[i] - } -} - -func lastValueAggs(aggPtrs []*export.Aggregator) { - aggs := lastvalue.New(len(aggPtrs)) - for i := range aggPtrs { - *aggPtrs[i] = &aggs[i] - } -} - -func (selectorInexpensive) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { - switch descriptor.InstrumentKind() { - case metric.ValueObserverInstrumentKind: - lastValueAggs(aggPtrs) - case metric.ValueRecorderInstrumentKind: - aggs := minmaxsumcount.New(len(aggPtrs), descriptor) - for i := range aggPtrs { - *aggPtrs[i] = &aggs[i] - } - default: - sumAggs(aggPtrs) - } -} - -func (selectorExact) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { - switch descriptor.InstrumentKind() { - case metric.ValueObserverInstrumentKind: - lastValueAggs(aggPtrs) - case metric.ValueRecorderInstrumentKind: - aggs := exact.New(len(aggPtrs)) - for i := range aggPtrs { - *aggPtrs[i] = &aggs[i] - } - default: - sumAggs(aggPtrs) - } -} - -func (s selectorHistogram) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { - switch descriptor.InstrumentKind() { - case metric.ValueObserverInstrumentKind: - lastValueAggs(aggPtrs) - case metric.ValueRecorderInstrumentKind: - aggs := histogram.New(len(aggPtrs), descriptor, s.options...) - for i := range aggPtrs { - *aggPtrs[i] = &aggs[i] - } - default: - sumAggs(aggPtrs) - } -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go index c754e221eea..324dd4baf24 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "strings" ) var ( @@ -27,38 +28,83 @@ var ( ErrPartialResource = errors.New("partial resource") ) -// Detector detects OpenTelemetry resource information +// Detector detects OpenTelemetry resource information. type Detector interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Detect returns an initialized Resource based on gathered information. // If the source information to construct a Resource contains invalid // values, a Resource is returned with the valid parts of the source // information used for initialization along with an appropriately // wrapped ErrPartialResource error. Detect(ctx context.Context) (*Resource, error) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } // Detect calls all input detectors sequentially and merges each result with the previous one. // It returns the merged error too. func Detect(ctx context.Context, detectors ...Detector) (*Resource, error) { - var autoDetectedRes *Resource - var errInfo []string + r := new(Resource) + return r, detect(ctx, r, detectors) +} + +// detect runs all detectors using ctx and merges the result into res. This +// assumes res is allocated and not nil, it will panic otherwise. +func detect(ctx context.Context, res *Resource, detectors []Detector) error { + var ( + r *Resource + errs detectErrs + err error + ) + for _, detector := range detectors { if detector == nil { continue } - res, err := detector.Detect(ctx) + r, err = detector.Detect(ctx) if err != nil { - errInfo = append(errInfo, err.Error()) + errs = append(errs, err) if !errors.Is(err, ErrPartialResource) { continue } } - autoDetectedRes = Merge(autoDetectedRes, res) + r, err = Merge(res, r) + if err != nil { + errs = append(errs, err) + } + *res = *r + } + + if len(errs) == 0 { + return nil + } + return errs +} + +type detectErrs []error + +func (e detectErrs) Error() string { + errStr := make([]string, len(e)) + for i, err := range e { + errStr[i] = fmt.Sprintf("* %s", err) } - var aggregatedError error - if len(errInfo) > 0 { - aggregatedError = fmt.Errorf("detecting resources: %s", errInfo) + format := "%d errors occurred detecting resource:\n\t%s" + return fmt.Sprintf(format, len(e), strings.Join(errStr, "\n\t")) +} + +func (e detectErrs) Unwrap() error { + switch len(e) { + case 0: + return nil + case 1: + return e[0] } - return autoDetectedRes, aggregatedError + return e[1:] +} + +func (e detectErrs) Is(target error) bool { + return len(e) != 0 && errors.Is(e[0], target) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go index c80ab697c6f..c63a0dd1f8c 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go @@ -20,62 +20,66 @@ import ( "os" "path/filepath" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/semconv" + "go.opentelemetry.io/otel/sdk" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) type ( - // TelemetrySDK is a Detector that provides information about + // telemetrySDK is a Detector that provides information about // the OpenTelemetry SDK used. This Detector is included as a // builtin. If these resource attributes are not wanted, use // the WithTelemetrySDK(nil) or WithoutBuiltin() options to // explicitly disable them. - TelemetrySDK struct{} + telemetrySDK struct{} - // Host is a Detector that provides information about the host + // host is a Detector that provides information about the host // being run on. This Detector is included as a builtin. If // these resource attributes are not wanted, use the // WithHost(nil) or WithoutBuiltin() options to explicitly // disable them. - Host struct{} + host struct{} stringDetector struct { - K attribute.Key - F func() (string, error) + schemaURL string + K attribute.Key + F func() (string, error) } defaultServiceNameDetector struct{} ) var ( - _ Detector = TelemetrySDK{} - _ Detector = Host{} + _ Detector = telemetrySDK{} + _ Detector = host{} _ Detector = stringDetector{} _ Detector = defaultServiceNameDetector{} ) // Detect returns a *Resource that describes the OpenTelemetry SDK used. -func (TelemetrySDK) Detect(context.Context) (*Resource, error) { +func (telemetrySDK) Detect(context.Context) (*Resource, error) { return NewWithAttributes( - semconv.TelemetrySDKNameKey.String("opentelemetry"), - semconv.TelemetrySDKLanguageKey.String("go"), - semconv.TelemetrySDKVersionKey.String(otel.Version()), + semconv.SchemaURL, + semconv.TelemetrySDKName("opentelemetry"), + semconv.TelemetrySDKLanguageGo, + semconv.TelemetrySDKVersion(sdk.Version()), ), nil } // Detect returns a *Resource that describes the host being run on. -func (Host) Detect(ctx context.Context) (*Resource, error) { - return StringDetector(semconv.HostNameKey, os.Hostname).Detect(ctx) +func (host) Detect(ctx context.Context) (*Resource, error) { + return StringDetector(semconv.SchemaURL, semconv.HostNameKey, os.Hostname).Detect(ctx) } // StringDetector returns a Detector that will produce a *Resource -// containing the string as a value corresponding to k. -func StringDetector(k attribute.Key, f func() (string, error)) Detector { - return stringDetector{K: k, F: f} +// containing the string as a value corresponding to k. The resulting Resource +// will have the specified schemaURL. +func StringDetector(schemaURL string, k attribute.Key, f func() (string, error)) Detector { + return stringDetector{schemaURL: schemaURL, K: k, F: f} } -// Detect implements Detector. +// Detect returns a *Resource that describes the string as a value +// corresponding to attribute.Key as well as the specific schemaURL. func (sd stringDetector) Detect(ctx context.Context) (*Resource, error) { value, err := sd.F() if err != nil { @@ -85,12 +89,13 @@ func (sd stringDetector) Detect(ctx context.Context) (*Resource, error) { if !a.Valid() { return nil, fmt.Errorf("invalid attribute: %q -> %q", a.Key, a.Value.Emit()) } - return NewWithAttributes(sd.K.String(value)), nil + return NewWithAttributes(sd.schemaURL, sd.K.String(value)), nil } -// Detect implements Detector +// Detect implements Detector. func (defaultServiceNameDetector) Detect(ctx context.Context) (*Resource, error) { return StringDetector( + semconv.SchemaURL, semconv.ServiceNameKey, func() (string, error) { executable, err := os.Executable() diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go index 0365caa26a8..f263919f6ec 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go @@ -24,35 +24,16 @@ import ( type config struct { // detectors that will be evaluated. detectors []Detector - - // telemetrySDK is used to specify non-default - // `telemetry.sdk.*` attributes. - telemetrySDK Detector - - // HostResource is used to specify non-default `host.*` - // attributes. - host Detector - - // FromEnv is used to specify non-default OTEL_RESOURCE_ATTRIBUTES - // attributes. - fromEnv Detector + // SchemaURL to associate with the Resource. + schemaURL string } // Option is the interface that applies a configuration option. type Option interface { - // Apply sets the Option value of a config. - Apply(*config) - - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() + // apply sets the Option value of a config. + apply(config) config } -type option struct{} - -func (option) private() {} - // WithAttributes adds attributes to the configured Resource. func WithAttributes(attributes ...attribute.KeyValue) Option { return WithDetectors(detectAttributes{attributes}) @@ -63,7 +44,7 @@ type detectAttributes struct { } func (d detectAttributes) Detect(context.Context) (*Resource, error) { - return NewWithAttributes(d.attributes...), nil + return NewSchemaless(d.attributes...), nil } // WithDetectors adds detectors to be evaluated for the configured resource. @@ -72,94 +53,154 @@ func WithDetectors(detectors ...Detector) Option { } type detectorsOption struct { - option detectors []Detector } -// Apply implements Option. -func (o detectorsOption) Apply(cfg *config) { +func (o detectorsOption) apply(cfg config) config { cfg.detectors = append(cfg.detectors, o.detectors...) + return cfg +} + +// WithFromEnv adds attributes from environment variables to the configured resource. +func WithFromEnv() Option { + return WithDetectors(fromEnv{}) +} + +// WithHost adds attributes from the host to the configured resource. +func WithHost() Option { + return WithDetectors(host{}) +} + +// WithHostID adds host ID information to the configured resource. +func WithHostID() Option { + return WithDetectors(hostIDDetector{}) +} + +// WithTelemetrySDK adds TelemetrySDK version info to the configured resource. +func WithTelemetrySDK() Option { + return WithDetectors(telemetrySDK{}) } -// WithTelemetrySDK overrides the builtin `telemetry.sdk.*` -// attributes. Use nil to disable these attributes entirely. -func WithTelemetrySDK(d Detector) Option { - return telemetrySDKOption{Detector: d} +// WithSchemaURL sets the schema URL for the configured resource. +func WithSchemaURL(schemaURL string) Option { + return schemaURLOption(schemaURL) } -type telemetrySDKOption struct { - option - Detector +type schemaURLOption string + +func (o schemaURLOption) apply(cfg config) config { + cfg.schemaURL = string(o) + return cfg } -// Apply implements Option. -func (o telemetrySDKOption) Apply(cfg *config) { - cfg.telemetrySDK = o.Detector +// WithOS adds all the OS attributes to the configured Resource. +// See individual WithOS* functions to configure specific attributes. +func WithOS() Option { + return WithDetectors( + osTypeDetector{}, + osDescriptionDetector{}, + ) } -// WithHost overrides the builtin `host.*` attributes. Use nil to -// disable these attributes entirely. -func WithHost(d Detector) Option { - return hostOption{Detector: d} +// WithOSType adds an attribute with the operating system type to the configured Resource. +func WithOSType() Option { + return WithDetectors(osTypeDetector{}) } -type hostOption struct { - option - Detector +// WithOSDescription adds an attribute with the operating system description to the +// configured Resource. The formatted string is equivalent to the output of the +// `uname -snrvm` command. +func WithOSDescription() Option { + return WithDetectors(osDescriptionDetector{}) } -// Apply implements Option. -func (o hostOption) Apply(cfg *config) { - cfg.host = o.Detector +// WithProcess adds all the Process attributes to the configured Resource. +// +// Warning! This option will include process command line arguments. If these +// contain sensitive information it will be included in the exported resource. +// +// This option is equivalent to calling WithProcessPID, +// WithProcessExecutableName, WithProcessExecutablePath, +// WithProcessCommandArgs, WithProcessOwner, WithProcessRuntimeName, +// WithProcessRuntimeVersion, and WithProcessRuntimeDescription. See each +// option function for information about what resource attributes each +// includes. +func WithProcess() Option { + return WithDetectors( + processPIDDetector{}, + processExecutableNameDetector{}, + processExecutablePathDetector{}, + processCommandArgsDetector{}, + processOwnerDetector{}, + processRuntimeNameDetector{}, + processRuntimeVersionDetector{}, + processRuntimeDescriptionDetector{}, + ) } -// WithFromEnv overrides the builtin detector for -// OTEL_RESOURCE_ATTRIBUTES. Use nil to disable environment checking. -func WithFromEnv(d Detector) Option { - return fromEnvOption{Detector: d} +// WithProcessPID adds an attribute with the process identifier (PID) to the +// configured Resource. +func WithProcessPID() Option { + return WithDetectors(processPIDDetector{}) } -type fromEnvOption struct { - option - Detector +// WithProcessExecutableName adds an attribute with the name of the process +// executable to the configured Resource. +func WithProcessExecutableName() Option { + return WithDetectors(processExecutableNameDetector{}) } -// Apply implements Option. -func (o fromEnvOption) Apply(cfg *config) { - cfg.fromEnv = o.Detector +// WithProcessExecutablePath adds an attribute with the full path to the process +// executable to the configured Resource. +func WithProcessExecutablePath() Option { + return WithDetectors(processExecutablePathDetector{}) } -// WithoutBuiltin disables all the builtin detectors, including the -// telemetry.sdk.*, host.*, and the environment detector. -func WithoutBuiltin() Option { - return noBuiltinOption{} +// WithProcessCommandArgs adds an attribute with all the command arguments (including +// the command/executable itself) as received by the process to the configured +// Resource. +// +// Warning! This option will include process command line arguments. If these +// contain sensitive information it will be included in the exported resource. +func WithProcessCommandArgs() Option { + return WithDetectors(processCommandArgsDetector{}) } -type noBuiltinOption struct { - option +// WithProcessOwner adds an attribute with the username of the user that owns the process +// to the configured Resource. +func WithProcessOwner() Option { + return WithDetectors(processOwnerDetector{}) } -// Apply implements Option. -func (o noBuiltinOption) Apply(cfg *config) { - cfg.host = nil - cfg.telemetrySDK = nil - cfg.fromEnv = nil +// WithProcessRuntimeName adds an attribute with the name of the runtime of this +// process to the configured Resource. +func WithProcessRuntimeName() Option { + return WithDetectors(processRuntimeNameDetector{}) } -// New returns a Resource combined from the provided attributes, -// user-provided detectors and builtin detectors. -func New(ctx context.Context, opts ...Option) (*Resource, error) { - cfg := config{ - telemetrySDK: TelemetrySDK{}, - host: Host{}, - fromEnv: FromEnv{}, - } - for _, opt := range opts { - opt.Apply(&cfg) - } - detectors := append( - []Detector{cfg.telemetrySDK, cfg.host, cfg.fromEnv}, - cfg.detectors..., +// WithProcessRuntimeVersion adds an attribute with the version of the runtime of +// this process to the configured Resource. +func WithProcessRuntimeVersion() Option { + return WithDetectors(processRuntimeVersionDetector{}) +} + +// WithProcessRuntimeDescription adds an attribute with an additional description +// about the runtime of the process to the configured Resource. +func WithProcessRuntimeDescription() Option { + return WithDetectors(processRuntimeDescriptionDetector{}) +} + +// WithContainer adds all the Container attributes to the configured Resource. +// See individual WithContainer* functions to configure specific attributes. +func WithContainer() Option { + return WithDetectors( + cgroupContainerIDDetector{}, ) - return Detect(ctx, detectors...) +} + +// WithContainerID adds an attribute with the id of the container to the configured Resource. +// Note: WithContainerID will not extract the correct container ID in an ECS environment. +// Please use the ECS resource detector instead (https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/aws/ecs). +func WithContainerID() Option { + return WithDetectors(cgroupContainerIDDetector{}) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/container.go b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go new file mode 100644 index 00000000000..3d536228283 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go @@ -0,0 +1,100 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "bufio" + "context" + "errors" + "io" + "os" + "regexp" + + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +type containerIDProvider func() (string, error) + +var ( + containerID containerIDProvider = getContainerIDFromCGroup + cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`) +) + +type cgroupContainerIDDetector struct{} + +const cgroupPath = "/proc/self/cgroup" + +// Detect returns a *Resource that describes the id of the container. +// If no container id found, an empty resource will be returned. +func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) { + containerID, err := containerID() + if err != nil { + return nil, err + } + + if containerID == "" { + return Empty(), nil + } + return NewWithAttributes(semconv.SchemaURL, semconv.ContainerID(containerID)), nil +} + +var ( + defaultOSStat = os.Stat + osStat = defaultOSStat + + defaultOSOpen = func(name string) (io.ReadCloser, error) { + return os.Open(name) + } + osOpen = defaultOSOpen +) + +// getContainerIDFromCGroup returns the id of the container from the cgroup file. +// If no container id found, an empty string will be returned. +func getContainerIDFromCGroup() (string, error) { + if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) { + // File does not exist, skip + return "", nil + } + + file, err := osOpen(cgroupPath) + if err != nil { + return "", err + } + defer file.Close() + + return getContainerIDFromReader(file), nil +} + +// getContainerIDFromReader returns the id of the container from reader. +func getContainerIDFromReader(reader io.Reader) string { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + line := scanner.Text() + + if id := getContainerIDFromLine(line); id != "" { + return id + } + } + return "" +} + +// getContainerIDFromLine returns the id of the container from one string line. +func getContainerIDFromLine(line string) string { + matches := cgroupContainerIDRe.FindStringSubmatch(line) + if len(matches) <= 1 { + return "" + } + return matches[1] +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go b/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go index fe34f896af5..d55a50b0dc2 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go @@ -14,10 +14,6 @@ // Package resource provides detecting and representing resources. // -// This package is currently in a pre-GA phase. Backwards incompatible changes -// may be introduced in subsequent minor version releases as we work to track -// the evolving OpenTelemetry specification and user feedback. -// // The fundamental struct is a Resource which holds identifying information // about the entities for which telemetry is exported. // @@ -29,4 +25,7 @@ // OTEL_RESOURCE_ATTRIBUTES the FromEnv Detector can be used. It will interpret // the value as a list of comma delimited key/value pairs // (e.g. `=,=,...`). +// +// While this package provides a stable API, +// the attributes added by resource detectors may change. package resource // import "go.opentelemetry.io/otel/sdk/resource" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go index defb455382b..a847c50622e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go @@ -17,56 +17,92 @@ package resource // import "go.opentelemetry.io/otel/sdk/resource" import ( "context" "fmt" + "net/url" "os" "strings" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) -// envVar is the environment variable name OpenTelemetry Resource information can be assigned to. -const envVar = "OTEL_RESOURCE_ATTRIBUTES" +const ( + // resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from. + resourceAttrKey = "OTEL_RESOURCE_ATTRIBUTES" + + // svcNameKey is the environment variable name that Service Name information will be read from. + svcNameKey = "OTEL_SERVICE_NAME" +) var ( // errMissingValue is returned when a resource value is missing. errMissingValue = fmt.Errorf("%w: missing value", ErrPartialResource) ) -// FromEnv is a Detector that implements the Detector and collects +// fromEnv is a Detector that implements the Detector and collects // resources from environment. This Detector is included as a -// builtin. If these resource attributes are not wanted, use the -// WithFromEnv(nil) or WithoutBuiltin() options to explicitly disable -// them. -type FromEnv struct{} +// builtin. +type fromEnv struct{} -// compile time assertion that FromEnv implements Detector interface -var _ Detector = FromEnv{} +// compile time assertion that FromEnv implements Detector interface. +var _ Detector = fromEnv{} -// Detect collects resources from environment -func (FromEnv) Detect(context.Context) (*Resource, error) { - attrs := strings.TrimSpace(os.Getenv(envVar)) +// Detect collects resources from environment. +func (fromEnv) Detect(context.Context) (*Resource, error) { + attrs := strings.TrimSpace(os.Getenv(resourceAttrKey)) + svcName := strings.TrimSpace(os.Getenv(svcNameKey)) - if attrs == "" { + if attrs == "" && svcName == "" { return Empty(), nil } - return constructOTResources(attrs) + + var res *Resource + + if svcName != "" { + res = NewSchemaless(semconv.ServiceName(svcName)) + } + + r2, err := constructOTResources(attrs) + + // Ensure that the resource with the service name from OTEL_SERVICE_NAME + // takes precedence, if it was defined. + res, err2 := Merge(r2, res) + + if err == nil { + err = err2 + } else if err2 != nil { + err = fmt.Errorf("detecting resources: %s", []string{err.Error(), err2.Error()}) + } + + return res, err } func constructOTResources(s string) (*Resource, error) { + if s == "" { + return Empty(), nil + } pairs := strings.Split(s, ",") - attrs := []attribute.KeyValue{} + var attrs []attribute.KeyValue var invalid []string for _, p := range pairs { - field := strings.SplitN(p, "=", 2) - if len(field) != 2 { + k, v, found := strings.Cut(p, "=") + if !found { invalid = append(invalid, p) continue } - k, v := strings.TrimSpace(field[0]), strings.TrimSpace(field[1]) - attrs = append(attrs, attribute.String(k, v)) + key := strings.TrimSpace(k) + val, err := url.QueryUnescape(strings.TrimSpace(v)) + if err != nil { + // Retain original value if decoding fails, otherwise it will be + // an empty string. + val = v + otel.Handle(err) + } + attrs = append(attrs, attribute.String(key, val)) } var err error if len(invalid) > 0 { err = fmt.Errorf("%w: %v", errMissingValue, invalid) } - return NewWithAttributes(attrs...), err + return NewSchemaless(attrs...), err } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go new file mode 100644 index 00000000000..fb1ebf2cab2 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go @@ -0,0 +1,120 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "context" + "errors" + "strings" + + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +type hostIDProvider func() (string, error) + +var defaultHostIDProvider hostIDProvider = platformHostIDReader.read + +var hostID = defaultHostIDProvider + +type hostIDReader interface { + read() (string, error) +} + +type fileReader func(string) (string, error) + +type commandExecutor func(string, ...string) (string, error) + +// hostIDReaderBSD implements hostIDReader. +type hostIDReaderBSD struct { + execCommand commandExecutor + readFile fileReader +} + +// read attempts to read the machine-id from /etc/hostid. If not found it will +// execute `kenv -q smbios.system.uuid`. If neither location yields an id an +// error will be returned. +func (r *hostIDReaderBSD) read() (string, error) { + if result, err := r.readFile("/etc/hostid"); err == nil { + return strings.TrimSpace(result), nil + } + + if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil { + return strings.TrimSpace(result), nil + } + + return "", errors.New("host id not found in: /etc/hostid or kenv") +} + +// hostIDReaderDarwin implements hostIDReader. +type hostIDReaderDarwin struct { + execCommand commandExecutor +} + +// read executes `ioreg -rd1 -c "IOPlatformExpertDevice"` and parses host id +// from the IOPlatformUUID line. If the command fails or the uuid cannot be +// parsed an error will be returned. +func (r *hostIDReaderDarwin) read() (string, error) { + result, err := r.execCommand("ioreg", "-rd1", "-c", "IOPlatformExpertDevice") + if err != nil { + return "", err + } + + lines := strings.Split(result, "\n") + for _, line := range lines { + if strings.Contains(line, "IOPlatformUUID") { + parts := strings.Split(line, " = ") + if len(parts) == 2 { + return strings.Trim(parts[1], "\""), nil + } + break + } + } + + return "", errors.New("could not parse IOPlatformUUID") +} + +type hostIDReaderLinux struct { + readFile fileReader +} + +// read attempts to read the machine-id from /etc/machine-id followed by +// /var/lib/dbus/machine-id. If neither location yields an ID an error will +// be returned. +func (r *hostIDReaderLinux) read() (string, error) { + if result, err := r.readFile("/etc/machine-id"); err == nil { + return strings.TrimSpace(result), nil + } + + if result, err := r.readFile("/var/lib/dbus/machine-id"); err == nil { + return strings.TrimSpace(result), nil + } + + return "", errors.New("host id not found in: /etc/machine-id or /var/lib/dbus/machine-id") +} + +type hostIDDetector struct{} + +// Detect returns a *Resource containing the platform specific host id. +func (hostIDDetector) Detect(ctx context.Context) (*Resource, error) { + hostID, err := hostID() + if err != nil { + return nil, err + } + + return NewWithAttributes( + semconv.SchemaURL, + semconv.HostID(hostID), + ), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go new file mode 100644 index 00000000000..1778bbacf05 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build dragonfly || freebsd || netbsd || openbsd || solaris +// +build dragonfly freebsd netbsd openbsd solaris + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderBSD{ + execCommand: execCommand, + readFile: readFile, +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go new file mode 100644 index 00000000000..ba41409b23c --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderDarwin{ + execCommand: execCommand, +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go new file mode 100644 index 00000000000..207acb0ed3a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build darwin || dragonfly || freebsd || netbsd || openbsd || solaris + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import "os/exec" + +func execCommand(name string, arg ...string) (string, error) { + cmd := exec.Command(name, arg...) + b, err := cmd.Output() + if err != nil { + return "", err + } + + return string(b), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go new file mode 100644 index 00000000000..410579b8fc9 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux +// +build linux + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderLinux{ + readFile: readFile, +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go new file mode 100644 index 00000000000..721e3ca6e7d --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux || dragonfly || freebsd || netbsd || openbsd || solaris + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import "os" + +func readFile(filename string) (string, error) { + b, err := os.ReadFile(filename) + if err != nil { + return "", err + } + + return string(b), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go new file mode 100644 index 00000000000..89df9d6882e --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !darwin +// +build !dragonfly +// +build !freebsd +// +build !linux +// +build !netbsd +// +build !openbsd +// +build !solaris +// +build !windows + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +// hostIDReaderUnsupported is a placeholder implementation for operating systems +// for which this project currently doesn't support host.id +// attribute detection. See build tags declaration early on this file +// for a list of unsupported OSes. +type hostIDReaderUnsupported struct{} + +func (*hostIDReaderUnsupported) read() (string, error) { + return "", nil +} + +var platformHostIDReader hostIDReader = &hostIDReaderUnsupported{} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go new file mode 100644 index 00000000000..5b431c6ee6e --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build windows +// +build windows + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "golang.org/x/sys/windows/registry" +) + +// implements hostIDReader +type hostIDReaderWindows struct{} + +// read reads MachineGuid from the windows registry key: +// SOFTWARE\Microsoft\Cryptography +func (*hostIDReaderWindows) read() (string, error) { + k, err := registry.OpenKey( + registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Cryptography`, + registry.QUERY_VALUE|registry.WOW64_64KEY, + ) + + if err != nil { + return "", err + } + defer k.Close() + + guid, _, err := k.GetStringValue("MachineGuid") + if err != nil { + return "", err + } + + return guid, nil +} + +var platformHostIDReader hostIDReader = &hostIDReaderWindows{} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go index 816d209217a..84e1c585605 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go @@ -18,22 +18,82 @@ import ( "context" "strings" - "go.opentelemetry.io/otel/semconv" + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) +type osDescriptionProvider func() (string, error) + +var defaultOSDescriptionProvider osDescriptionProvider = platformOSDescription + +var osDescription = defaultOSDescriptionProvider + +func setDefaultOSDescriptionProvider() { + setOSDescriptionProvider(defaultOSDescriptionProvider) +} + +func setOSDescriptionProvider(osDescriptionProvider osDescriptionProvider) { + osDescription = osDescriptionProvider +} + type osTypeDetector struct{} +type osDescriptionDetector struct{} // Detect returns a *Resource that describes the operating system type the // service is running on. func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) { osType := runtimeOS() + osTypeAttribute := mapRuntimeOSToSemconvOSType(osType) + + return NewWithAttributes( + semconv.SchemaURL, + osTypeAttribute, + ), nil +} + +// Detect returns a *Resource that describes the operating system the +// service is running on. +func (osDescriptionDetector) Detect(ctx context.Context) (*Resource, error) { + description, err := osDescription() + + if err != nil { + return nil, err + } + return NewWithAttributes( - semconv.OSTypeKey.String(strings.ToLower(osType)), + semconv.SchemaURL, + semconv.OSDescription(description), ), nil } -// WithOSType adds an attribute with the operating system type to the configured Resource. -func WithOSType() Option { - return WithDetectors(osTypeDetector{}) +// mapRuntimeOSToSemconvOSType translates the OS name as provided by the Go runtime +// into an OS type attribute with the corresponding value defined by the semantic +// conventions. In case the provided OS name isn't mapped, it's transformed to lowercase +// and used as the value for the returned OS type attribute. +func mapRuntimeOSToSemconvOSType(osType string) attribute.KeyValue { + // the elements in this map are the intersection between + // available GOOS values and defined semconv OS types + osTypeAttributeMap := map[string]attribute.KeyValue{ + "aix": semconv.OSTypeAIX, + "darwin": semconv.OSTypeDarwin, + "dragonfly": semconv.OSTypeDragonflyBSD, + "freebsd": semconv.OSTypeFreeBSD, + "linux": semconv.OSTypeLinux, + "netbsd": semconv.OSTypeNetBSD, + "openbsd": semconv.OSTypeOpenBSD, + "solaris": semconv.OSTypeSolaris, + "windows": semconv.OSTypeWindows, + "zos": semconv.OSTypeZOS, + } + + var osTypeAttribute attribute.KeyValue + + if attr, ok := osTypeAttributeMap[osType]; ok { + osTypeAttribute = attr + } else { + osTypeAttribute = semconv.OSTypeKey.String(strings.ToLower(osType)) + } + + return osTypeAttribute } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go new file mode 100644 index 00000000000..24ec85793de --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go @@ -0,0 +1,102 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "encoding/xml" + "fmt" + "io" + "os" +) + +type plist struct { + XMLName xml.Name `xml:"plist"` + Dict dict `xml:"dict"` +} + +type dict struct { + Key []string `xml:"key"` + String []string `xml:"string"` +} + +// osRelease builds a string describing the operating system release based on the +// contents of the property list (.plist) system files. If no .plist files are found, +// or if the required properties to build the release description string are missing, +// an empty string is returned instead. The generated string resembles the output of +// the `sw_vers` commandline program, but in a single-line string. For more information +// about the `sw_vers` program, see: https://www.unix.com/man-page/osx/1/SW_VERS. +func osRelease() string { + file, err := getPlistFile() + if err != nil { + return "" + } + + defer file.Close() + + values, err := parsePlistFile(file) + if err != nil { + return "" + } + + return buildOSRelease(values) +} + +// getPlistFile returns a *os.File pointing to one of the well-known .plist files +// available on macOS. If no file can be opened, it returns an error. +func getPlistFile() (*os.File, error) { + return getFirstAvailableFile([]string{ + "/System/Library/CoreServices/SystemVersion.plist", + "/System/Library/CoreServices/ServerVersion.plist", + }) +} + +// parsePlistFile process the file pointed by `file` as a .plist file and returns +// a map with the key-values for each pair of correlated and elements +// contained in it. +func parsePlistFile(file io.Reader) (map[string]string, error) { + var v plist + + err := xml.NewDecoder(file).Decode(&v) + if err != nil { + return nil, err + } + + if len(v.Dict.Key) != len(v.Dict.String) { + return nil, fmt.Errorf("the number of and elements doesn't match") + } + + properties := make(map[string]string, len(v.Dict.Key)) + for i, key := range v.Dict.Key { + properties[key] = v.Dict.String[i] + } + + return properties, nil +} + +// buildOSRelease builds a string describing the OS release based on the properties +// available on the provided map. It tries to find the `ProductName`, `ProductVersion` +// and `ProductBuildVersion` properties. If some of these properties are not found, +// it returns an empty string. +func buildOSRelease(properties map[string]string) string { + productName := properties["ProductName"] + productVersion := properties["ProductVersion"] + productBuildVersion := properties["ProductBuildVersion"] + + if productName == "" || productVersion == "" || productBuildVersion == "" { + return "" + } + + return fmt.Sprintf("%s %s (%s)", productName, productVersion, productBuildVersion) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go new file mode 100644 index 00000000000..c771942deec --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go @@ -0,0 +1,154 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos +// +build aix dragonfly freebsd linux netbsd openbsd solaris zos + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "bufio" + "fmt" + "io" + "os" + "strings" +) + +// osRelease builds a string describing the operating system release based on the +// properties of the os-release file. If no os-release file is found, or if the +// required properties to build the release description string are missing, an empty +// string is returned instead. For more information about os-release files, see: +// https://www.freedesktop.org/software/systemd/man/os-release.html +func osRelease() string { + file, err := getOSReleaseFile() + if err != nil { + return "" + } + + defer file.Close() + + values := parseOSReleaseFile(file) + + return buildOSRelease(values) +} + +// getOSReleaseFile returns a *os.File pointing to one of the well-known os-release +// files, according to their order of preference. If no file can be opened, it +// returns an error. +func getOSReleaseFile() (*os.File, error) { + return getFirstAvailableFile([]string{"/etc/os-release", "/usr/lib/os-release"}) +} + +// parseOSReleaseFile process the file pointed by `file` as an os-release file and +// returns a map with the key-values contained in it. Empty lines or lines starting +// with a '#' character are ignored, as well as lines with the missing key=value +// separator. Values are unquoted and unescaped. +func parseOSReleaseFile(file io.Reader) map[string]string { + values := make(map[string]string) + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := scanner.Text() + + if skip(line) { + continue + } + + key, value, ok := parse(line) + if ok { + values[key] = value + } + } + + return values +} + +// skip returns true if the line is blank or starts with a '#' character, and +// therefore should be skipped from processing. +func skip(line string) bool { + line = strings.TrimSpace(line) + + return len(line) == 0 || strings.HasPrefix(line, "#") +} + +// parse attempts to split the provided line on the first '=' character, and then +// sanitize each side of the split before returning them as a key-value pair. +func parse(line string) (string, string, bool) { + k, v, found := strings.Cut(line, "=") + + if !found || len(k) == 0 { + return "", "", false + } + + key := strings.TrimSpace(k) + value := unescape(unquote(strings.TrimSpace(v))) + + return key, value, true +} + +// unquote checks whether the string `s` is quoted with double or single quotes +// and, if so, returns a version of the string without them. Otherwise it returns +// the provided string unchanged. +func unquote(s string) string { + if len(s) < 2 { + return s + } + + if (s[0] == '"' || s[0] == '\'') && s[0] == s[len(s)-1] { + return s[1 : len(s)-1] + } + + return s +} + +// unescape removes the `\` prefix from some characters that are expected +// to have it added in front of them for escaping purposes. +func unescape(s string) string { + return strings.NewReplacer( + `\$`, `$`, + `\"`, `"`, + `\'`, `'`, + `\\`, `\`, + "\\`", "`", + ).Replace(s) +} + +// buildOSRelease builds a string describing the OS release based on the properties +// available on the provided map. It favors a combination of the `NAME` and `VERSION` +// properties as first option (falling back to `VERSION_ID` if `VERSION` isn't +// found), and using `PRETTY_NAME` alone if some of the previous are not present. If +// none of these properties are found, it returns an empty string. +// +// The rationale behind not using `PRETTY_NAME` as first choice was that, for some +// Linux distributions, it doesn't include the same detail that can be found on the +// individual `NAME` and `VERSION` properties, and combining `PRETTY_NAME` with +// other properties can produce "pretty" redundant strings in some cases. +func buildOSRelease(values map[string]string) string { + var osRelease string + + name := values["NAME"] + version := values["VERSION"] + + if version == "" { + version = values["VERSION_ID"] + } + + if name != "" && version != "" { + osRelease = fmt.Sprintf("%s %s", name, version) + } else { + osRelease = values["PRETTY_NAME"] + } + + return osRelease +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go new file mode 100644 index 00000000000..1c84afc1852 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +type unameProvider func(buf *unix.Utsname) (err error) + +var defaultUnameProvider unameProvider = unix.Uname + +var currentUnameProvider = defaultUnameProvider + +func setDefaultUnameProvider() { + setUnameProvider(defaultUnameProvider) +} + +func setUnameProvider(unameProvider unameProvider) { + currentUnameProvider = unameProvider +} + +// platformOSDescription returns a human readable OS version information string. +// The final string combines OS release information (where available) and the +// result of the `uname` system call. +func platformOSDescription() (string, error) { + uname, err := uname() + if err != nil { + return "", err + } + + osRelease := osRelease() + if osRelease != "" { + return fmt.Sprintf("%s (%s)", osRelease, uname), nil + } + + return uname, nil +} + +// uname issues a uname(2) system call (or equivalent on systems which doesn't +// have one) and formats the output in a single string, similar to the output +// of the `uname` commandline program. The final string resembles the one +// obtained with a call to `uname -snrvm`. +func uname() (string, error) { + var utsName unix.Utsname + + err := currentUnameProvider(&utsName) + if err != nil { + return "", err + } + + return fmt.Sprintf("%s %s %s %s %s", + unix.ByteSliceToString(utsName.Sysname[:]), + unix.ByteSliceToString(utsName.Nodename[:]), + unix.ByteSliceToString(utsName.Release[:]), + unix.ByteSliceToString(utsName.Version[:]), + unix.ByteSliceToString(utsName.Machine[:]), + ), nil +} + +// getFirstAvailableFile returns an *os.File of the first available +// file from a list of candidate file paths. +func getFirstAvailableFile(candidates []string) (*os.File, error) { + for _, c := range candidates { + file, err := os.Open(c) + if err == nil { + return file, nil + } + } + + return nil, fmt.Errorf("no candidate file available: %v", candidates) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go new file mode 100644 index 00000000000..3ebcb534f28 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !aix +// +build !darwin +// +build !dragonfly +// +build !freebsd +// +build !linux +// +build !netbsd +// +build !openbsd +// +build !solaris +// +build !windows +// +build !zos + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +// platformOSDescription is a placeholder implementation for OSes +// for which this project currently doesn't support os.description +// attribute detection. See build tags declaration early on this file +// for a list of unsupported OSes. +func platformOSDescription() (string, error) { + return "", nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go new file mode 100644 index 00000000000..faad64d8daa --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go @@ -0,0 +1,101 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "fmt" + "strconv" + + "golang.org/x/sys/windows/registry" +) + +// platformOSDescription returns a human readable OS version information string. +// It does so by querying registry values under the +// `SOFTWARE\Microsoft\Windows NT\CurrentVersion` key. The final string +// resembles the one displayed by the Version Reporter Applet (winver.exe). +func platformOSDescription() (string, error) { + k, err := registry.OpenKey( + registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + + if err != nil { + return "", err + } + + defer k.Close() + + var ( + productName = readProductName(k) + displayVersion = readDisplayVersion(k) + releaseID = readReleaseID(k) + currentMajorVersionNumber = readCurrentMajorVersionNumber(k) + currentMinorVersionNumber = readCurrentMinorVersionNumber(k) + currentBuildNumber = readCurrentBuildNumber(k) + ubr = readUBR(k) + ) + + if displayVersion != "" { + displayVersion += " " + } + + return fmt.Sprintf("%s %s(%s) [Version %s.%s.%s.%s]", + productName, + displayVersion, + releaseID, + currentMajorVersionNumber, + currentMinorVersionNumber, + currentBuildNumber, + ubr, + ), nil +} + +func getStringValue(name string, k registry.Key) string { + value, _, _ := k.GetStringValue(name) + + return value +} + +func getIntegerValue(name string, k registry.Key) uint64 { + value, _, _ := k.GetIntegerValue(name) + + return value +} + +func readProductName(k registry.Key) string { + return getStringValue("ProductName", k) +} + +func readDisplayVersion(k registry.Key) string { + return getStringValue("DisplayVersion", k) +} + +func readReleaseID(k registry.Key) string { + return getStringValue("ReleaseID", k) +} + +func readCurrentMajorVersionNumber(k registry.Key) string { + return strconv.FormatUint(getIntegerValue("CurrentMajorVersionNumber", k), 10) +} + +func readCurrentMinorVersionNumber(k registry.Key) string { + return strconv.FormatUint(getIntegerValue("CurrentMinorVersionNumber", k), 10) +} + +func readCurrentBuildNumber(k registry.Key) string { + return getStringValue("CurrentBuildNumber", k) +} + +func readUBR(k registry.Key) string { + return strconv.FormatUint(getIntegerValue("UBR", k), 10) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go index f15f97ec5ac..e67ff29e26d 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go @@ -22,7 +22,7 @@ import ( "path/filepath" "runtime" - "go.opentelemetry.io/otel/semconv" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) type pidProvider func() int @@ -39,7 +39,12 @@ var ( defaultExecutablePathProvider executablePathProvider = os.Executable defaultCommandArgsProvider commandArgsProvider = func() []string { return os.Args } defaultOwnerProvider ownerProvider = user.Current - defaultRuntimeNameProvider runtimeNameProvider = func() string { return runtime.Compiler } + defaultRuntimeNameProvider runtimeNameProvider = func() string { + if runtime.Compiler == "gc" { + return "go" + } + return runtime.Compiler + } defaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version defaultRuntimeOSProvider runtimeOSProvider = func() string { return runtime.GOOS } defaultRuntimeArchProvider runtimeArchProvider = func() string { return runtime.GOARCH } @@ -115,14 +120,14 @@ type processRuntimeDescriptionDetector struct{} // Detect returns a *Resource that describes the process identifier (PID) of the // executing process. func (processPIDDetector) Detect(ctx context.Context) (*Resource, error) { - return NewWithAttributes(semconv.ProcessPIDKey.Int(pid())), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessPID(pid())), nil } // Detect returns a *Resource that describes the name of the process executable. func (processExecutableNameDetector) Detect(ctx context.Context) (*Resource, error) { executableName := filepath.Base(commandArgs()[0]) - return NewWithAttributes(semconv.ProcessExecutableNameKey.String(executableName)), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutableName(executableName)), nil } // Detect returns a *Resource that describes the full path of the process executable. @@ -132,13 +137,13 @@ func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, err return nil, err } - return NewWithAttributes(semconv.ProcessExecutablePathKey.String(executablePath)), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutablePath(executablePath)), nil } // Detect returns a *Resource that describes all the command arguments as received // by the process. func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) { - return NewWithAttributes(semconv.ProcessCommandArgsKey.Array(commandArgs())), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgs(commandArgs()...)), nil } // Detect returns a *Resource that describes the username of the user that owns the @@ -149,18 +154,18 @@ func (processOwnerDetector) Detect(ctx context.Context) (*Resource, error) { return nil, err } - return NewWithAttributes(semconv.ProcessOwnerKey.String(owner.Username)), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessOwner(owner.Username)), nil } // Detect returns a *Resource that describes the name of the compiler used to compile // this process image. func (processRuntimeNameDetector) Detect(ctx context.Context) (*Resource, error) { - return NewWithAttributes(semconv.ProcessRuntimeNameKey.String(runtimeName())), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeName(runtimeName())), nil } // Detect returns a *Resource that describes the version of the runtime of this process. func (processRuntimeVersionDetector) Detect(ctx context.Context) (*Resource, error) { - return NewWithAttributes(semconv.ProcessRuntimeVersionKey.String(runtimeVersion())), nil + return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeVersion(runtimeVersion())), nil } // Detect returns a *Resource that describes the runtime of this process. @@ -169,69 +174,7 @@ func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource, "go version %s %s/%s", runtimeVersion(), runtimeOS(), runtimeArch()) return NewWithAttributes( - semconv.ProcessRuntimeDescriptionKey.String(runtimeDescription), + semconv.SchemaURL, + semconv.ProcessRuntimeDescription(runtimeDescription), ), nil } - -// WithProcessPID adds an attribute with the process identifier (PID) to the -// configured Resource. -func WithProcessPID() Option { - return WithDetectors(processPIDDetector{}) -} - -// WithProcessExecutableName adds an attribute with the name of the process -// executable to the configured Resource. -func WithProcessExecutableName() Option { - return WithDetectors(processExecutableNameDetector{}) -} - -// WithProcessExecutablePath adds an attribute with the full path to the process -// executable to the configured Resource. -func WithProcessExecutablePath() Option { - return WithDetectors(processExecutablePathDetector{}) -} - -// WithProcessCommandArgs adds an attribute with all the command arguments (including -// the command/executable itself) as received by the process the configured Resource. -func WithProcessCommandArgs() Option { - return WithDetectors(processCommandArgsDetector{}) -} - -// WithProcessOwner adds an attribute with the username of the user that owns the process -// to the configured Resource. -func WithProcessOwner() Option { - return WithDetectors(processOwnerDetector{}) -} - -// WithProcessRuntimeName adds an attribute with the name of the runtime of this -// process to the configured Resource. -func WithProcessRuntimeName() Option { - return WithDetectors(processRuntimeNameDetector{}) -} - -// WithProcessRuntimeVersion adds an attribute with the version of the runtime of -// this process to the configured Resource. -func WithProcessRuntimeVersion() Option { - return WithDetectors(processRuntimeVersionDetector{}) -} - -// WithProcessRuntimeDescription adds an attribute with an additional description -// about the runtime of the process to the configured Resource. -func WithProcessRuntimeDescription() Option { - return WithDetectors(processRuntimeDescriptionDetector{}) -} - -// WithProcess adds all the Process attributes to the configured Resource. -// See individual WithProcess* functions to configure specific attributes. -func WithProcess() Option { - return WithDetectors( - processPIDDetector{}, - processExecutableNameDetector{}, - processExecutablePathDetector{}, - processCommandArgsDetector{}, - processOwnerDetector{}, - processRuntimeNameDetector{}, - processRuntimeVersionDetector{}, - processRuntimeDescriptionDetector{}, - ) -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go index 2e5d10151cc..176ff106668 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go @@ -16,6 +16,8 @@ package resource // import "go.opentelemetry.io/otel/sdk/resource" import ( "context" + "errors" + "sync" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -29,40 +31,59 @@ import ( // (`*resource.Resource`). The `nil` value is equivalent to an empty // Resource. type Resource struct { - attrs attribute.Set + attrs attribute.Set + schemaURL string } var ( - emptyResource Resource - - defaultResource *Resource = func(r *Resource, err error) *Resource { - if err != nil { - otel.Handle(err) - } - return r - }(Detect(context.Background(), defaultServiceNameDetector{}, FromEnv{}, TelemetrySDK{})) + defaultResource *Resource + defaultResourceOnce sync.Once ) -// NewWithAttributes creates a resource from attrs. If attrs contains -// duplicate keys, the last value will be used. If attrs contains any invalid -// items those items will be dropped. -func NewWithAttributes(attrs ...attribute.KeyValue) *Resource { +var errMergeConflictSchemaURL = errors.New("cannot merge resource due to conflicting Schema URL") + +// New returns a Resource combined from the user-provided detectors. +func New(ctx context.Context, opts ...Option) (*Resource, error) { + cfg := config{} + for _, opt := range opts { + cfg = opt.apply(cfg) + } + + r := &Resource{schemaURL: cfg.schemaURL} + return r, detect(ctx, r, cfg.detectors) +} + +// NewWithAttributes creates a resource from attrs and associates the resource with a +// schema URL. If attrs contains duplicate keys, the last value will be used. If attrs +// contains any invalid items those items will be dropped. The attrs are assumed to be +// in a schema identified by schemaURL. +func NewWithAttributes(schemaURL string, attrs ...attribute.KeyValue) *Resource { + resource := NewSchemaless(attrs...) + resource.schemaURL = schemaURL + return resource +} + +// NewSchemaless creates a resource from attrs. If attrs contains duplicate keys, +// the last value will be used. If attrs contains any invalid items those items will +// be dropped. The resource will not be associated with a schema URL. If the schema +// of the attrs is known use NewWithAttributes instead. +func NewSchemaless(attrs ...attribute.KeyValue) *Resource { if len(attrs) == 0 { - return &emptyResource + return &Resource{} } // Ensure attributes comply with the specification: - // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.0.1/specification/common/common.md#attributes + // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/common/README.md#attribute s, _ := attribute.NewSetWithFiltered(attrs, func(kv attribute.KeyValue) bool { return kv.Valid() }) // If attrs only contains invalid entries do not allocate a new resource. if s.Len() == 0 { - return &emptyResource + return &Resource{} } - return &Resource{s} //nolint + return &Resource{attrs: s} //nolint } // String implements the Stringer interface and provides a @@ -77,6 +98,17 @@ func (r *Resource) String() string { return r.attrs.Encoded(attribute.DefaultEncoder()) } +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (r *Resource) MarshalLog() interface{} { + return struct { + Attributes attribute.Set + SchemaURL string + }{ + Attributes: r.attrs, + SchemaURL: r.schemaURL, + } +} + // Attributes returns a copy of attributes from the resource in a sorted order. // To avoid allocating a new slice, use an iterator. func (r *Resource) Attributes() []attribute.KeyValue { @@ -86,7 +118,15 @@ func (r *Resource) Attributes() []attribute.KeyValue { return r.attrs.ToSlice() } -// Iter returns an interator of the Resource attributes. +// SchemaURL returns the schema URL associated with Resource r. +func (r *Resource) SchemaURL() string { + if r == nil { + return "" + } + return r.schemaURL +} + +// Iter returns an iterator of the Resource attributes. // This is ideal to use if you do not want a copy of the attributes. func (r *Resource) Iter() attribute.Iterator { if r == nil { @@ -111,15 +151,33 @@ func (r *Resource) Equal(eq *Resource) bool { // If there are common keys between resource a and b, then the value // from resource b will overwrite the value from resource a, even // if resource b's value is empty. -func Merge(a, b *Resource) *Resource { +// +// The SchemaURL of the resources will be merged according to the spec rules: +// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/resource/sdk.md#merge +// If the resources have different non-empty schemaURL an empty resource and an error +// will be returned. +func Merge(a, b *Resource) (*Resource, error) { if a == nil && b == nil { - return Empty() + return Empty(), nil } if a == nil { - return b + return b, nil } if b == nil { - return a + return a, nil + } + + // Merge the schema URL. + var schemaURL string + switch true { + case a.schemaURL == "": + schemaURL = b.schemaURL + case b.schemaURL == "": + schemaURL = a.schemaURL + case a.schemaURL == b.schemaURL: + schemaURL = a.schemaURL + default: + return Empty(), errMergeConflictSchemaURL } // Note: 'b' attributes will overwrite 'a' with last-value-wins in attribute.Key() @@ -127,42 +185,59 @@ func Merge(a, b *Resource) *Resource { mi := attribute.NewMergeIterator(b.Set(), a.Set()) combine := make([]attribute.KeyValue, 0, a.Len()+b.Len()) for mi.Next() { - combine = append(combine, mi.Label()) + combine = append(combine, mi.Attribute()) } - return NewWithAttributes(combine...) + merged := NewWithAttributes(schemaURL, combine...) + return merged, nil } -// Empty returns an instance of Resource with no attributes. It is +// Empty returns an instance of Resource with no attributes. It is // equivalent to a `nil` Resource. func Empty() *Resource { - return &emptyResource + return &Resource{} } // Default returns an instance of Resource with a default -// "service.name" and OpenTelemetrySDK attributes +// "service.name" and OpenTelemetrySDK attributes. func Default() *Resource { + defaultResourceOnce.Do(func() { + var err error + defaultResource, err = Detect( + context.Background(), + defaultServiceNameDetector{}, + fromEnv{}, + telemetrySDK{}, + ) + if err != nil { + otel.Handle(err) + } + // If Detect did not return a valid resource, fall back to emptyResource. + if defaultResource == nil { + defaultResource = &Resource{} + } + }) return defaultResource } // Environment returns an instance of Resource with attributes // extracted from the OTEL_RESOURCE_ATTRIBUTES environment variable. func Environment() *Resource { - detector := &FromEnv{} + detector := &fromEnv{} resource, err := detector.Detect(context.Background()) - if err == nil { + if err != nil { otel.Handle(err) } return resource } // Equivalent returns an object that can be compared for equality -// between two resources. This value is suitable for use as a key in +// between two resources. This value is suitable for use as a key in // a map. func (r *Resource) Equivalent() attribute.Distinct { return r.Set().Equivalent() } -// Set returns the equivalent *attribute.Set of this resources attributes. +// Set returns the equivalent *attribute.Set of this resource's attributes. func (r *Resource) Set() *attribute.Set { if r == nil { r = Empty() diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/attributesmap.go b/vendor/go.opentelemetry.io/otel/sdk/trace/attributesmap.go deleted file mode 100644 index b891c8178b7..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/attributesmap.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package trace // import "go.opentelemetry.io/otel/sdk/trace" - -import ( - "container/list" - - "go.opentelemetry.io/otel/attribute" -) - -// attributesMap is a capped map of attributes, holding the most recent attributes. -// Eviction is done via a LRU method, the oldest entry is removed to create room for a new entry. -// Updates are allowed and they refresh the usage of the key. -// -// This is based from https://github.com/hashicorp/golang-lru/blob/master/simplelru/lru.go -// With a subset of the its operations and specific for holding attribute.KeyValue -type attributesMap struct { - attributes map[attribute.Key]*list.Element - evictList *list.List - droppedCount int - capacity int -} - -func newAttributesMap(capacity int) *attributesMap { - lm := &attributesMap{ - attributes: make(map[attribute.Key]*list.Element), - evictList: list.New(), - capacity: capacity, - } - return lm -} - -func (am *attributesMap) add(kv attribute.KeyValue) { - // Check for existing item - if ent, ok := am.attributes[kv.Key]; ok { - am.evictList.MoveToFront(ent) - ent.Value = &kv - return - } - - // Add new item - entry := am.evictList.PushFront(&kv) - am.attributes[kv.Key] = entry - - // Verify size not exceeded - if am.evictList.Len() > am.capacity { - am.removeOldest() - am.droppedCount++ - } -} - -// toKeyValue copies the attributesMap into a slice of attribute.KeyValue and -// returns it. If the map is empty, a nil is returned. -// TODO: Is it more efficient to return a pointer to the slice? -func (am *attributesMap) toKeyValue() []attribute.KeyValue { - len := am.evictList.Len() - if len == 0 { - return nil - } - - attributes := make([]attribute.KeyValue, 0, len) - for ent := am.evictList.Back(); ent != nil; ent = ent.Prev() { - if value, ok := ent.Value.(*attribute.KeyValue); ok { - attributes = append(attributes, *value) - } - } - - return attributes -} - -// removeOldest removes the oldest item from the cache. -func (am *attributesMap) removeOldest() { - ent := am.evictList.Back() - if ent != nil { - am.evictList.Remove(ent) - kv := ent.Value.(*attribute.KeyValue) - delete(am.attributes, kv.Key) - } -} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go index f63aa7a940f..c9c7effbf38 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go @@ -16,23 +16,29 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" import ( "context" - "runtime" "sync" "sync/atomic" "time" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/internal/global" + "go.opentelemetry.io/otel/sdk/internal/env" + "go.opentelemetry.io/otel/trace" ) +// Defaults for BatchSpanProcessorOptions. const ( DefaultMaxQueueSize = 2048 - DefaultBatchTimeout = 5000 * time.Millisecond - DefaultExportTimeout = 30000 * time.Millisecond + DefaultScheduleDelay = 5000 + DefaultExportTimeout = 30000 DefaultMaxExportBatchSize = 512 ) +// BatchSpanProcessorOption configures a BatchSpanProcessor. type BatchSpanProcessorOption func(o *BatchSpanProcessorOptions) +// BatchSpanProcessorOptions is configuration settings for a +// BatchSpanProcessor. type BatchSpanProcessorOptions struct { // MaxQueueSize is the maximum queue size to buffer spans for delayed processing. If the // queue gets full it drops the spans. Use BlockOnQueueFull to change this behavior. @@ -63,20 +69,21 @@ type BatchSpanProcessorOptions struct { } // batchSpanProcessor is a SpanProcessor that batches asynchronously-received -// SpanSnapshots and sends them to a trace.Exporter when complete. +// spans and sends them to a trace.Exporter when complete. type batchSpanProcessor struct { e SpanExporter o BatchSpanProcessorOptions - queue chan *SpanSnapshot + queue chan ReadOnlySpan dropped uint32 - batch []*SpanSnapshot + batch []ReadOnlySpan batchMutex sync.Mutex timer *time.Timer stopWait sync.WaitGroup stopOnce sync.Once stopCh chan struct{} + stopped atomic.Bool } var _ SpanProcessor = (*batchSpanProcessor)(nil) @@ -84,13 +91,24 @@ var _ SpanProcessor = (*batchSpanProcessor)(nil) // NewBatchSpanProcessor creates a new SpanProcessor that will send completed // span batches to the exporter with the supplied options. // -// If the exporter is nil, the span processor will preform no action. +// If the exporter is nil, the span processor will perform no action. func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor { + maxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize) + maxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize) + + if maxExportBatchSize > maxQueueSize { + if DefaultMaxExportBatchSize > maxQueueSize { + maxExportBatchSize = maxQueueSize + } else { + maxExportBatchSize = DefaultMaxExportBatchSize + } + } + o := BatchSpanProcessorOptions{ - BatchTimeout: DefaultBatchTimeout, - ExportTimeout: DefaultExportTimeout, - MaxQueueSize: DefaultMaxQueueSize, - MaxExportBatchSize: DefaultMaxExportBatchSize, + BatchTimeout: time.Duration(env.BatchSpanProcessorScheduleDelay(DefaultScheduleDelay)) * time.Millisecond, + ExportTimeout: time.Duration(env.BatchSpanProcessorExportTimeout(DefaultExportTimeout)) * time.Millisecond, + MaxQueueSize: maxQueueSize, + MaxExportBatchSize: maxExportBatchSize, } for _, opt := range options { opt(&o) @@ -98,9 +116,9 @@ func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorO bsp := &batchSpanProcessor{ e: exporter, o: o, - batch: make([]*SpanSnapshot, 0, o.MaxExportBatchSize), + batch: make([]ReadOnlySpan, 0, o.MaxExportBatchSize), timer: time.NewTimer(o.BatchTimeout), - queue: make(chan *SpanSnapshot, o.MaxQueueSize), + queue: make(chan ReadOnlySpan, o.MaxQueueSize), stopCh: make(chan struct{}), } @@ -119,11 +137,16 @@ func (bsp *batchSpanProcessor) OnStart(parent context.Context, s ReadWriteSpan) // OnEnd method enqueues a ReadOnlySpan for later processing. func (bsp *batchSpanProcessor) OnEnd(s ReadOnlySpan) { + // Do not enqueue spans after Shutdown. + if bsp.stopped.Load() { + return + } + // Do not enqueue spans if we are just going to drop them. if bsp.e == nil { return } - bsp.enqueue(s.Snapshot()) + bsp.enqueue(s) } // Shutdown flushes the queue and waits until all spans are processed. @@ -131,6 +154,7 @@ func (bsp *batchSpanProcessor) OnEnd(s ReadOnlySpan) { func (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error { var err error bsp.stopOnce.Do(func() { + bsp.stopped.Store(true) wait := make(chan struct{}) go func() { close(bsp.stopCh) @@ -152,20 +176,50 @@ func (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error { return err } +type forceFlushSpan struct { + ReadOnlySpan + flushed chan struct{} +} + +func (f forceFlushSpan) SpanContext() trace.SpanContext { + return trace.NewSpanContext(trace.SpanContextConfig{TraceFlags: trace.FlagsSampled}) +} + // ForceFlush exports all ended spans that have not yet been exported. func (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error { + // Interrupt if context is already canceled. + if err := ctx.Err(); err != nil { + return err + } + + // Do nothing after Shutdown. + if bsp.stopped.Load() { + return nil + } + var err error if bsp.e != nil { - wait := make(chan struct{}) - go func() { - if err := bsp.exportSpans(ctx); err != nil { - otel.Handle(err) + flushCh := make(chan struct{}) + if bsp.enqueueBlockOnQueueFull(ctx, forceFlushSpan{flushed: flushCh}) { + select { + case <-bsp.stopCh: + // The batchSpanProcessor is Shutdown. + return nil + case <-flushCh: + // Processed any items in queue prior to ForceFlush being called + case <-ctx.Done(): + return ctx.Err() } + } + + wait := make(chan error) + go func() { + wait <- bsp.exportSpans(ctx) close(wait) }() // Wait until the export is finished or the context is cancelled/timed out select { - case <-wait: + case err = <-wait: case <-ctx.Done(): err = ctx.Err() } @@ -173,30 +227,43 @@ func (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error { return err } +// WithMaxQueueSize returns a BatchSpanProcessorOption that configures the +// maximum queue size allowed for a BatchSpanProcessor. func WithMaxQueueSize(size int) BatchSpanProcessorOption { return func(o *BatchSpanProcessorOptions) { o.MaxQueueSize = size } } +// WithMaxExportBatchSize returns a BatchSpanProcessorOption that configures +// the maximum export batch size allowed for a BatchSpanProcessor. func WithMaxExportBatchSize(size int) BatchSpanProcessorOption { return func(o *BatchSpanProcessorOptions) { o.MaxExportBatchSize = size } } +// WithBatchTimeout returns a BatchSpanProcessorOption that configures the +// maximum delay allowed for a BatchSpanProcessor before it will export any +// held span (whether the queue is full or not). func WithBatchTimeout(delay time.Duration) BatchSpanProcessorOption { return func(o *BatchSpanProcessorOptions) { o.BatchTimeout = delay } } +// WithExportTimeout returns a BatchSpanProcessorOption that configures the +// amount of time a BatchSpanProcessor waits for an exporter to export before +// abandoning the export. func WithExportTimeout(timeout time.Duration) BatchSpanProcessorOption { return func(o *BatchSpanProcessorOptions) { o.ExportTimeout = timeout } } +// WithBlocking returns a BatchSpanProcessorOption that configures a +// BatchSpanProcessor to wait for enqueue operations to succeed instead of +// dropping data when the queue is full. func WithBlocking() BatchSpanProcessorOption { return func(o *BatchSpanProcessorOptions) { o.BlockOnQueueFull = true @@ -216,11 +283,19 @@ func (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error { defer cancel() } - if len(bsp.batch) > 0 { - if err := bsp.e.ExportSpans(ctx, bsp.batch); err != nil { + if l := len(bsp.batch); l > 0 { + global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", atomic.LoadUint32(&bsp.dropped)) + err := bsp.e.ExportSpans(ctx, bsp.batch) + + // A new batch is always created after exporting, even if the batch failed to be exported. + // + // It is up to the exporter to implement any type of retry logic if a batch is failing + // to be exported, since it is specific to the protocol and backend being sent to. + bsp.batch = bsp.batch[:0] + + if err != nil { return err } - bsp.batch = bsp.batch[:0] } return nil } @@ -242,9 +317,13 @@ func (bsp *batchSpanProcessor) processQueue() { otel.Handle(err) } case sd := <-bsp.queue: + if ffs, ok := sd.(forceFlushSpan); ok { + close(ffs.flushed) + continue + } bsp.batchMutex.Lock() bsp.batch = append(bsp.batch, sd) - shouldExport := len(bsp.batch) == bsp.o.MaxExportBatchSize + shouldExport := len(bsp.batch) >= bsp.o.MaxExportBatchSize bsp.batchMutex.Unlock() if shouldExport { if !bsp.timer.Stop() { @@ -266,11 +345,9 @@ func (bsp *batchSpanProcessor) drainQueue() { for { select { case sd := <-bsp.queue: - if sd == nil { - if err := bsp.exportSpans(ctx); err != nil { - otel.Handle(err) - } - return + if _, ok := sd.(forceFlushSpan); ok { + // Ignore flush requests as they are not valid spans. + continue } bsp.batchMutex.Lock() @@ -284,45 +361,60 @@ func (bsp *batchSpanProcessor) drainQueue() { } } default: - close(bsp.queue) + // There are no more enqueued spans. Make final export. + if err := bsp.exportSpans(ctx); err != nil { + otel.Handle(err) + } + return } } } -func (bsp *batchSpanProcessor) enqueue(sd *SpanSnapshot) { - if !sd.SpanContext.IsSampled() { - return +func (bsp *batchSpanProcessor) enqueue(sd ReadOnlySpan) { + ctx := context.TODO() + if bsp.o.BlockOnQueueFull { + bsp.enqueueBlockOnQueueFull(ctx, sd) + } else { + bsp.enqueueDrop(ctx, sd) } +} - // This ensures the bsp.queue<- below does not panic as the - // processor shuts down. - defer func() { - x := recover() - switch err := x.(type) { - case nil: - return - case runtime.Error: - if err.Error() == "send on closed channel" { - return - } - } - panic(x) - }() +func (bsp *batchSpanProcessor) enqueueBlockOnQueueFull(ctx context.Context, sd ReadOnlySpan) bool { + if !sd.SpanContext().IsSampled() { + return false + } select { - case <-bsp.stopCh: - return - default: + case bsp.queue <- sd: + return true + case <-ctx.Done(): + return false } +} - if bsp.o.BlockOnQueueFull { - bsp.queue <- sd - return +func (bsp *batchSpanProcessor) enqueueDrop(ctx context.Context, sd ReadOnlySpan) bool { + if !sd.SpanContext().IsSampled() { + return false } select { case bsp.queue <- sd: + return true default: atomic.AddUint32(&bsp.dropped, 1) } + return false +} + +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (bsp *batchSpanProcessor) MarshalLog() interface{} { + return struct { + Type string + SpanExporter SpanExporter + Config BatchSpanProcessorOptions + }{ + Type: "BatchSpanProcessor", + SpanExporter: bsp.e, + Config: bsp.o, + } } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/config.go b/vendor/go.opentelemetry.io/otel/sdk/trace/config.go deleted file mode 100644 index 61a30439251..00000000000 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/config.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package trace // import "go.opentelemetry.io/otel/sdk/trace" - -// SpanLimits represents the limits of a span. -type SpanLimits struct { - // AttributeCountLimit is the maximum allowed span attribute count. - AttributeCountLimit int - - // EventCountLimit is the maximum allowed span event count. - EventCountLimit int - - // LinkCountLimit is the maximum allowed span link count. - LinkCountLimit int - - // AttributePerEventCountLimit is the maximum allowed attribute per span event count. - AttributePerEventCountLimit int - - // AttributePerLinkCountLimit is the maximum allowed attribute per span link count. - AttributePerLinkCountLimit int -} - -func (sl *SpanLimits) ensureDefault() { - if sl.EventCountLimit <= 0 { - sl.EventCountLimit = DefaultEventCountLimit - } - if sl.AttributeCountLimit <= 0 { - sl.AttributeCountLimit = DefaultAttributeCountLimit - } - if sl.LinkCountLimit <= 0 { - sl.LinkCountLimit = DefaultLinkCountLimit - } - if sl.AttributePerEventCountLimit <= 0 { - sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit - } - if sl.AttributePerLinkCountLimit <= 0 { - sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit - } -} - -const ( - // DefaultAttributeCountLimit is the default maximum allowed span attribute count. - DefaultAttributeCountLimit = 128 - - // DefaultEventCountLimit is the default maximum allowed span event count. - DefaultEventCountLimit = 128 - - // DefaultLinkCountLimit is the default maximum allowed span link count. - DefaultLinkCountLimit = 128 - - // DefaultAttributePerEventCountLimit is the default maximum allowed attribute per span event count. - DefaultAttributePerEventCountLimit = 128 - - // DefaultAttributePerLinkCountLimit is the default maximum allowed attribute per span link count. - DefaultAttributePerLinkCountLimit = 128 -) diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go b/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go index fd6ead86457..0285e99be07 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go @@ -15,10 +15,6 @@ /* Package trace contains support for OpenTelemetry distributed tracing. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - The following assumes a basic familiarity with OpenTelemetry concepts. See https://opentelemetry.io. */ diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/event.go b/vendor/go.opentelemetry.io/otel/sdk/trace/event.go new file mode 100644 index 00000000000..1e3b426757d --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/event.go @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import ( + "time" + + "go.opentelemetry.io/otel/attribute" +) + +// Event is a thing that happened during a Span's lifetime. +type Event struct { + // Name is the name of this event + Name string + + // Attributes describe the aspects of the event. + Attributes []attribute.KeyValue + + // DroppedAttributeCount is the number of attributes that were not + // recorded due to configured limits being reached. + DroppedAttributeCount int + + // Time at which this event was recorded. + Time time.Time +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go b/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go index 3c5817a6a02..d1c86e59b22 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go @@ -14,24 +14,30 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" +// evictedQueue is a FIFO queue with a configurable capacity. type evictedQueue struct { queue []interface{} capacity int droppedCount int } -func newEvictedQueue(capacity int) *evictedQueue { - eq := &evictedQueue{ - capacity: capacity, - queue: make([]interface{}, 0), - } - - return eq +func newEvictedQueue(capacity int) evictedQueue { + // Do not pre-allocate queue, do this lazily. + return evictedQueue{capacity: capacity} } +// add adds value to the evictedQueue eq. If eq is at capacity, the oldest +// queued value will be discarded and the drop count incremented. func (eq *evictedQueue) add(value interface{}) { - if len(eq.queue) == eq.capacity { - eq.queue = eq.queue[1:] + if eq.capacity == 0 { + eq.droppedCount++ + return + } + + if eq.capacity > 0 && len(eq.queue) == eq.capacity { + // Drop first-in while avoiding allocating more capacity to eq.queue. + copy(eq.queue[:eq.capacity-1], eq.queue[1:]) + eq.queue = eq.queue[:eq.capacity-1] eq.droppedCount++ } eq.queue = append(eq.queue, value) diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go b/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go index e60a421cde9..bba246041a4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go @@ -26,8 +26,18 @@ import ( // IDGenerator allows custom generators for TraceID and SpanID. type IDGenerator interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // NewIDs returns a new trace and span ID. NewIDs(ctx context.Context) (trace.TraceID, trace.SpanID) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // NewSpanID returns a ID for a new span in the trace with traceID. NewSpanID(ctx context.Context, traceID trace.TraceID) trace.SpanID + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } type randomIDGenerator struct { @@ -42,7 +52,7 @@ func (gen *randomIDGenerator) NewSpanID(ctx context.Context, traceID trace.Trace gen.Lock() defer gen.Unlock() sid := trace.SpanID{} - gen.randSource.Read(sid[:]) + _, _ = gen.randSource.Read(sid[:]) return sid } @@ -52,9 +62,9 @@ func (gen *randomIDGenerator) NewIDs(ctx context.Context) (trace.TraceID, trace. gen.Lock() defer gen.Unlock() tid := trace.TraceID{} - gen.randSource.Read(tid[:]) + _, _ = gen.randSource.Read(tid[:]) sid := trace.SpanID{} - gen.randSource.Read(sid[:]) + _, _ = gen.randSource.Read(sid[:]) return tid, sid } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/link.go b/vendor/go.opentelemetry.io/otel/sdk/trace/link.go new file mode 100644 index 00000000000..19cfea4ba45 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/link.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import ( + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +// Link is the relationship between two Spans. The relationship can be within +// the same Trace or across different Traces. +type Link struct { + // SpanContext of the linked Span. + SpanContext trace.SpanContext + + // Attributes describe the aspects of the link. + Attributes []attribute.KeyValue + + // DroppedAttributeCount is the number of attributes that were not + // recorded due to configured limits being reached. + DroppedAttributeCount int +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go index 601c239c0e0..0a018c14ded 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go @@ -21,21 +21,23 @@ import ( "sync/atomic" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/trace" - + "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/trace" ) const ( defaultTracerName = "go.opentelemetry.io/otel/sdk/tracer" ) -// TODO (MrAlias): unify this API option design: -// https://github.com/open-telemetry/opentelemetry-go/issues/536 - -// TracerProviderConfig -type TracerProviderConfig struct { +// tracerProviderConfig. +type tracerProviderConfig struct { + // processors contains collection of SpanProcessors that are processing pipeline + // for spans in the trace signal. + // SpanProcessors registered with a TracerProvider and are called at the start + // and end of a Span's lifecycle, and are called in the order they are + // registered. processors []SpanProcessor // sampler is the default sampler used when creating new spans. @@ -51,16 +53,38 @@ type TracerProviderConfig struct { resource *resource.Resource } -type TracerProviderOption func(*TracerProviderConfig) +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (cfg tracerProviderConfig) MarshalLog() interface{} { + return struct { + SpanProcessors []SpanProcessor + SamplerType string + IDGeneratorType string + SpanLimits SpanLimits + Resource *resource.Resource + }{ + SpanProcessors: cfg.processors, + SamplerType: fmt.Sprintf("%T", cfg.sampler), + IDGeneratorType: fmt.Sprintf("%T", cfg.idGenerator), + SpanLimits: cfg.spanLimits, + Resource: cfg.resource, + } +} +// TracerProvider is an OpenTelemetry TracerProvider. It provides Tracers to +// instrumentation so it can trace operational flow through a system. type TracerProvider struct { mu sync.Mutex - namedTracer map[instrumentation.Library]*tracer - spanProcessors atomic.Value - sampler Sampler - idGenerator IDGenerator - spanLimits SpanLimits - resource *resource.Resource + namedTracer map[instrumentation.Scope]*tracer + spanProcessors atomic.Pointer[spanProcessorStates] + + isShutdown atomic.Bool + + // These fields are not protected by the lock mu. They are assumed to be + // immutable after creation of the TracerProvider. + sampler Sampler + idGenerator IDGenerator + spanLimits SpanLimits + resource *resource.Resource } var _ trace.TracerProvider = &TracerProvider{} @@ -68,33 +92,39 @@ var _ trace.TracerProvider = &TracerProvider{} // NewTracerProvider returns a new and configured TracerProvider. // // By default the returned TracerProvider is configured with: -// - a ParentBased(AlwaysSample) Sampler -// - a random number IDGenerator -// - the resource.Default() Resource -// - the default SpanLimits. +// - a ParentBased(AlwaysSample) Sampler +// - a random number IDGenerator +// - the resource.Default() Resource +// - the default SpanLimits. // // The passed opts are used to override these default values and configure the // returned TracerProvider appropriately. func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { - o := &TracerProviderConfig{} + o := tracerProviderConfig{ + spanLimits: NewSpanLimits(), + } + o = applyTracerProviderEnvConfigs(o) for _, opt := range opts { - opt(o) + o = opt.apply(o) } - ensureValidTracerProviderConfig(o) + o = ensureValidTracerProviderConfig(o) tp := &TracerProvider{ - namedTracer: make(map[instrumentation.Library]*tracer), + namedTracer: make(map[instrumentation.Scope]*tracer), sampler: o.sampler, idGenerator: o.idGenerator, spanLimits: o.spanLimits, resource: o.resource, } + global.Info("TracerProvider created", "config", o) + spss := make(spanProcessorStates, 0, len(o.processors)) for _, sp := range o.processors { - tp.RegisterSpanProcessor(sp) + spss = append(spss, newSpanProcessorState(sp)) } + tp.spanProcessors.Store(&spss) return tp } @@ -107,67 +137,100 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { // // This method is safe to be called concurrently. func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + // This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown(). + if p.isShutdown.Load() { + return trace.NewNoopTracerProvider().Tracer(name, opts...) + } c := trace.NewTracerConfig(opts...) - - p.mu.Lock() - defer p.mu.Unlock() if name == "" { name = defaultTracerName } - il := instrumentation.Library{ - Name: name, - Version: c.InstrumentationVersion, + is := instrumentation.Scope{ + Name: name, + Version: c.InstrumentationVersion(), + SchemaURL: c.SchemaURL(), } - t, ok := p.namedTracer[il] - if !ok { - t = &tracer{ - provider: p, - instrumentationLibrary: il, + + t, ok := func() (trace.Tracer, bool) { + p.mu.Lock() + defer p.mu.Unlock() + // Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran + // after the first check above but before we acquired the mutex. + if p.isShutdown.Load() { + return trace.NewNoopTracerProvider().Tracer(name, opts...), true + } + t, ok := p.namedTracer[is] + if !ok { + t = &tracer{ + provider: p, + instrumentationScope: is, + } + p.namedTracer[is] = t } - p.namedTracer[il] = t + return t, ok + }() + if !ok { + // This code is outside the mutex to not hold the lock while calling third party logging code: + // - That code may do slow things like I/O, which would prolong the duration the lock is held, + // slowing down all tracing consumers. + // - Logging code may be instrumented with tracing and deadlock because it could try + // acquiring the same non-reentrant mutex. + global.Info("Tracer created", "name", name, "version", is.Version, "schemaURL", is.SchemaURL) } return t } -// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors -func (p *TracerProvider) RegisterSpanProcessor(s SpanProcessor) { +// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors. +func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) { + // This check prevents calls during a shutdown. + if p.isShutdown.Load() { + return + } p.mu.Lock() defer p.mu.Unlock() - new := spanProcessorStates{} - if old, ok := p.spanProcessors.Load().(spanProcessorStates); ok { - new = append(new, old...) - } - newSpanSync := &spanProcessorState{ - sp: s, - state: &sync.Once{}, + // This check prevents calls after a shutdown. + if p.isShutdown.Load() { + return } - new = append(new, newSpanSync) - p.spanProcessors.Store(new) + + current := p.getSpanProcessors() + newSPS := make(spanProcessorStates, 0, len(current)+1) + newSPS = append(newSPS, current...) + newSPS = append(newSPS, newSpanProcessorState(sp)) + p.spanProcessors.Store(&newSPS) } -// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors -func (p *TracerProvider) UnregisterSpanProcessor(s SpanProcessor) { +// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors. +func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) { + // This check prevents calls during a shutdown. + if p.isShutdown.Load() { + return + } p.mu.Lock() defer p.mu.Unlock() - spss := spanProcessorStates{} - old, ok := p.spanProcessors.Load().(spanProcessorStates) - if !ok || len(old) == 0 { + // This check prevents calls after a shutdown. + if p.isShutdown.Load() { return } - spss = append(spss, old...) + old := p.getSpanProcessors() + if len(old) == 0 { + return + } + spss := make(spanProcessorStates, len(old)) + copy(spss, old) // stop the span processor if it is started and remove it from the list var stopOnce *spanProcessorState var idx int for i, sps := range spss { - if sps.sp == s { + if sps.sp == sp { stopOnce = sps idx = i } } if stopOnce != nil { stopOnce.state.Do(func() { - if err := s.Shutdown(context.Background()); err != nil { + if err := sp.Shutdown(context.Background()); err != nil { otel.Handle(err) } }) @@ -178,16 +241,13 @@ func (p *TracerProvider) UnregisterSpanProcessor(s SpanProcessor) { spss[len(spss)-1] = nil spss = spss[:len(spss)-1] - p.spanProcessors.Store(spss) + p.spanProcessors.Store(&spss) } // ForceFlush immediately exports all spans that have not yet been exported for // all the registered span processors. func (p *TracerProvider) ForceFlush(ctx context.Context) error { - spss, ok := p.spanProcessors.Load().(spanProcessorStates) - if !ok { - return fmt.Errorf("failed to load span processors") - } + spss := p.getSpanProcessors() if len(spss) == 0 { return nil } @@ -206,17 +266,23 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error { return nil } -// Shutdown shuts down the span processors in the order they were registered. +// Shutdown shuts down TracerProvider. All registered span processors are shut down +// in the order they were registered and any held computational resources are released. +// After Shutdown is called, all methods are no-ops. func (p *TracerProvider) Shutdown(ctx context.Context) error { - spss, ok := p.spanProcessors.Load().(spanProcessorStates) - if !ok { - return fmt.Errorf("failed to load span processors") + // This check prevents deadlocks in case of recursive shutdown. + if p.isShutdown.Load() { + return nil } - if len(spss) == 0 { + p.mu.Lock() + defer p.mu.Unlock() + // This check prevents calls after a shutdown has already been done concurrently. + if !p.isShutdown.CompareAndSwap(false, true) { // did toggle? return nil } - for _, sps := range spss { + var retErr error + for _, sps := range p.getSpanProcessors() { select { case <-ctx.Done(): return ctx.Err() @@ -228,14 +294,41 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error { err = sps.sp.Shutdown(ctx) }) if err != nil { - return err + if retErr == nil { + retErr = err + } else { + // Poor man's list of errors + retErr = fmt.Errorf("%v; %v", retErr, err) + } } } - return nil + p.spanProcessors.Store(&spanProcessorStates{}) + return retErr +} + +func (p *TracerProvider) getSpanProcessors() spanProcessorStates { + return *(p.spanProcessors.Load()) +} + +// TracerProviderOption configures a TracerProvider. +type TracerProviderOption interface { + apply(tracerProviderConfig) tracerProviderConfig +} + +type traceProviderOptionFunc func(tracerProviderConfig) tracerProviderConfig + +func (fn traceProviderOptionFunc) apply(cfg tracerProviderConfig) tracerProviderConfig { + return fn(cfg) } // WithSyncer registers the exporter with the TracerProvider using a // SimpleSpanProcessor. +// +// This is not recommended for production use. The synchronous nature of the +// SimpleSpanProcessor that will wrap the exporter make it good for testing, +// debugging, or showing examples of other feature, but it will be slow and +// have a high computation resource usage overhead. The WithBatcher option is +// recommended for production use instead. func WithSyncer(e SpanExporter) TracerProviderOption { return WithSpanProcessor(NewSimpleSpanProcessor(e)) } @@ -248,9 +341,10 @@ func WithBatcher(e SpanExporter, opts ...BatchSpanProcessorOption) TracerProvide // WithSpanProcessor registers the SpanProcessor with a TracerProvider. func WithSpanProcessor(sp SpanProcessor) TracerProviderOption { - return func(opts *TracerProviderConfig) { - opts.processors = append(opts.processors, sp) - } + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + cfg.processors = append(cfg.processors, sp) + return cfg + }) } // WithResource returns a TracerProviderOption that will configure the @@ -261,9 +355,14 @@ func WithSpanProcessor(sp SpanProcessor) TracerProviderOption { // If this option is not used, the TracerProvider will use the // resource.Default() Resource by default. func WithResource(r *resource.Resource) TracerProviderOption { - return func(opts *TracerProviderConfig) { - opts.resource = resource.Merge(resource.Environment(), r) - } + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + var err error + cfg.resource, err = resource.Merge(resource.Environment(), r) + if err != nil { + otel.Handle(err) + } + return cfg + }) } // WithIDGenerator returns a TracerProviderOption that will configure the @@ -274,11 +373,12 @@ func WithResource(r *resource.Resource) TracerProviderOption { // If this option is not used, the TracerProvider will use a random number // IDGenerator by default. func WithIDGenerator(g IDGenerator) TracerProviderOption { - return func(opts *TracerProviderConfig) { + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { if g != nil { - opts.idGenerator = g + cfg.idGenerator = g } - } + return cfg + }) } // WithSampler returns a TracerProviderOption that will configure the Sampler @@ -286,39 +386,115 @@ func WithIDGenerator(g IDGenerator) TracerProviderOption { // Tracers the TracerProvider creates to make their sampling decisions for the // Spans they create. // -// If this option is not used, the TracerProvider will use a +// This option overrides the Sampler configured through the OTEL_TRACES_SAMPLER +// and OTEL_TRACES_SAMPLER_ARG environment variables. If this option is not used +// and the sampler is not configured through environment variables or the environment +// contains invalid/unsupported configuration, the TracerProvider will use a // ParentBased(AlwaysSample) Sampler by default. func WithSampler(s Sampler) TracerProviderOption { - return func(opts *TracerProviderConfig) { + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { if s != nil { - opts.sampler = s + cfg.sampler = s } - } + return cfg + }) } -// WithSpanLimits returns a TracerProviderOption that will configure the -// SpanLimits sl as a TracerProvider's SpanLimits. The configured SpanLimits -// are used used by the Tracers the TracerProvider and the Spans they create -// to limit tracing resources used. +// WithSpanLimits returns a TracerProviderOption that configures a +// TracerProvider to use the SpanLimits sl. These SpanLimits bound any Span +// created by a Tracer from the TracerProvider. +// +// If any field of sl is zero or negative it will be replaced with the default +// value for that field. // -// If this option is not used, the TracerProvider will use the default -// SpanLimits. +// If this or WithRawSpanLimits are not provided, the TracerProvider will use +// the limits defined by environment variables, or the defaults if unset. +// Refer to the NewSpanLimits documentation for information about this +// relationship. +// +// Deprecated: Use WithRawSpanLimits instead which allows setting unlimited +// and zero limits. This option will be kept until the next major version +// incremented release. func WithSpanLimits(sl SpanLimits) TracerProviderOption { - return func(opts *TracerProviderConfig) { - opts.spanLimits = sl + if sl.AttributeValueLengthLimit <= 0 { + sl.AttributeValueLengthLimit = DefaultAttributeValueLengthLimit + } + if sl.AttributeCountLimit <= 0 { + sl.AttributeCountLimit = DefaultAttributeCountLimit } + if sl.EventCountLimit <= 0 { + sl.EventCountLimit = DefaultEventCountLimit + } + if sl.AttributePerEventCountLimit <= 0 { + sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit + } + if sl.LinkCountLimit <= 0 { + sl.LinkCountLimit = DefaultLinkCountLimit + } + if sl.AttributePerLinkCountLimit <= 0 { + sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit + } + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + cfg.spanLimits = sl + return cfg + }) +} + +// WithRawSpanLimits returns a TracerProviderOption that configures a +// TracerProvider to use these limits. These limits bound any Span created by +// a Tracer from the TracerProvider. +// +// The limits will be used as-is. Zero or negative values will not be changed +// to the default value like WithSpanLimits does. Setting a limit to zero will +// effectively disable the related resource it limits and setting to a +// negative value will mean that resource is unlimited. Consequentially, this +// means that the zero-value SpanLimits will disable all span resources. +// Because of this, limits should be constructed using NewSpanLimits and +// updated accordingly. +// +// If this or WithSpanLimits are not provided, the TracerProvider will use the +// limits defined by environment variables, or the defaults if unset. Refer to +// the NewSpanLimits documentation for information about this relationship. +func WithRawSpanLimits(limits SpanLimits) TracerProviderOption { + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + cfg.spanLimits = limits + return cfg + }) +} + +func applyTracerProviderEnvConfigs(cfg tracerProviderConfig) tracerProviderConfig { + for _, opt := range tracerProviderOptionsFromEnv() { + cfg = opt.apply(cfg) + } + + return cfg +} + +func tracerProviderOptionsFromEnv() []TracerProviderOption { + var opts []TracerProviderOption + + sampler, err := samplerFromEnv() + if err != nil { + otel.Handle(err) + } + + if sampler != nil { + opts = append(opts, WithSampler(sampler)) + } + + return opts } // ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid. -func ensureValidTracerProviderConfig(cfg *TracerProviderConfig) { +func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig { if cfg.sampler == nil { cfg.sampler = ParentBased(AlwaysSample()) } if cfg.idGenerator == nil { cfg.idGenerator = defaultIDGenerator() } - cfg.spanLimits.ensureDefault() if cfg.resource == nil { cfg.resource = resource.Default() } + return cfg } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go b/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go new file mode 100644 index 00000000000..02053b318ae --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go @@ -0,0 +1,108 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import ( + "errors" + "fmt" + "os" + "strconv" + "strings" +) + +const ( + tracesSamplerKey = "OTEL_TRACES_SAMPLER" + tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG" + + samplerAlwaysOn = "always_on" + samplerAlwaysOff = "always_off" + samplerTraceIDRatio = "traceidratio" + samplerParentBasedAlwaysOn = "parentbased_always_on" + samplerParsedBasedAlwaysOff = "parentbased_always_off" + samplerParentBasedTraceIDRatio = "parentbased_traceidratio" +) + +type errUnsupportedSampler string + +func (e errUnsupportedSampler) Error() string { + return fmt.Sprintf("unsupported sampler: %s", string(e)) +} + +var ( + errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0") + errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0") +) + +type samplerArgParseError struct { + parseErr error +} + +func (e samplerArgParseError) Error() string { + return fmt.Sprintf("parsing sampler argument: %s", e.parseErr.Error()) +} + +func (e samplerArgParseError) Unwrap() error { + return e.parseErr +} + +func samplerFromEnv() (Sampler, error) { + sampler, ok := os.LookupEnv(tracesSamplerKey) + if !ok { + return nil, nil + } + + sampler = strings.ToLower(strings.TrimSpace(sampler)) + samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey) + samplerArg = strings.TrimSpace(samplerArg) + + switch sampler { + case samplerAlwaysOn: + return AlwaysSample(), nil + case samplerAlwaysOff: + return NeverSample(), nil + case samplerTraceIDRatio: + if !hasSamplerArg { + return TraceIDRatioBased(1.0), nil + } + return parseTraceIDRatio(samplerArg) + case samplerParentBasedAlwaysOn: + return ParentBased(AlwaysSample()), nil + case samplerParsedBasedAlwaysOff: + return ParentBased(NeverSample()), nil + case samplerParentBasedTraceIDRatio: + if !hasSamplerArg { + return ParentBased(TraceIDRatioBased(1.0)), nil + } + ratio, err := parseTraceIDRatio(samplerArg) + return ParentBased(ratio), err + default: + return nil, errUnsupportedSampler(sampler) + } +} + +func parseTraceIDRatio(arg string) (Sampler, error) { + v, err := strconv.ParseFloat(arg, 64) + if err != nil { + return TraceIDRatioBased(1.0), samplerArgParseError{err} + } + if v < 0.0 { + return TraceIDRatioBased(1.0), errNegativeTraceIDRatio + } + if v > 1.0 { + return TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio + } + + return TraceIDRatioBased(v), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go index 86fc3108dc3..5ee9715d27b 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go @@ -25,8 +25,19 @@ import ( // Sampler decides whether a trace should be sampled and exported. type Sampler interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // ShouldSample returns a SamplingResult based on a decision made from the + // passed parameters. ShouldSample(parameters SamplingParameters) SamplingResult + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // Description returns information describing the Sampler. Description() string + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } // SamplingParameters contains the values passed to a Sampler. @@ -42,17 +53,17 @@ type SamplingParameters struct { // SamplingDecision indicates whether a span is dropped, recorded and/or sampled. type SamplingDecision uint8 -// Valid sampling decisions +// Valid sampling decisions. const ( - // Drop will not record the span and all attributes/events will be dropped + // Drop will not record the span and all attributes/events will be dropped. Drop SamplingDecision = iota // Record indicates the span's `IsRecording() == true`, but `Sampled` flag - // *must not* be set + // *must not* be set. RecordOnly // RecordAndSample has span's `IsRecording() == true` and `Sampled` flag - // *must* be set + // *must* be set. RecordAndSample ) @@ -70,7 +81,7 @@ type traceIDRatioSampler struct { func (ts traceIDRatioSampler) ShouldSample(p SamplingParameters) SamplingResult { psc := trace.SpanContextFromContext(p.ParentContext) - x := binary.BigEndian.Uint64(p.TraceID[0:8]) >> 1 + x := binary.BigEndian.Uint64(p.TraceID[8:16]) >> 1 if x < ts.traceIDUpperBound { return SamplingResult{ Decision: RecordAndSample, @@ -91,7 +102,8 @@ func (ts traceIDRatioSampler) Description() string { // always sample. Fractions < 0 are treated as zero. To respect the // parent trace's `SampledFlag`, the `TraceIDRatioBased` sampler should be used // as a delegate of a `Parent` sampler. -//nolint:golint // golint complains about stutter of `trace.TraceIDRatioBased` +// +//nolint:revive // revive complains about stutter of `trace.TraceIDRatioBased` func TraceIDRatioBased(fraction float64) Sampler { if fraction >= 1 { return AlwaysSample() @@ -151,10 +163,10 @@ func NeverSample() Sampler { // the root(Sampler) is used to make sampling decision. If the span has // a parent, depending on whether the parent is remote and whether it // is sampled, one of the following samplers will apply: -// - remoteParentSampled(Sampler) (default: AlwaysOn) -// - remoteParentNotSampled(Sampler) (default: AlwaysOff) -// - localParentSampled(Sampler) (default: AlwaysOn) -// - localParentNotSampled(Sampler) (default: AlwaysOff) +// - remoteParentSampled(Sampler) (default: AlwaysOn) +// - remoteParentNotSampled(Sampler) (default: AlwaysOff) +// - localParentSampled(Sampler) (default: AlwaysOn) +// - localParentNotSampled(Sampler) (default: AlwaysOff) func ParentBased(root Sampler, samplers ...ParentBasedSamplerOption) Sampler { return parentBased{ root: root, @@ -164,11 +176,11 @@ func ParentBased(root Sampler, samplers ...ParentBasedSamplerOption) Sampler { type parentBased struct { root Sampler - config config + config samplerConfig } -func configureSamplersForParentBased(samplers []ParentBasedSamplerOption) config { - c := config{ +func configureSamplersForParentBased(samplers []ParentBasedSamplerOption) samplerConfig { + c := samplerConfig{ remoteParentSampled: AlwaysSample(), remoteParentNotSampled: NeverSample(), localParentSampled: AlwaysSample(), @@ -176,26 +188,21 @@ func configureSamplersForParentBased(samplers []ParentBasedSamplerOption) config } for _, so := range samplers { - so.Apply(&c) + c = so.apply(c) } return c } -// config is a group of options for parentBased sampler. -type config struct { +// samplerConfig is a group of options for parentBased sampler. +type samplerConfig struct { remoteParentSampled, remoteParentNotSampled Sampler localParentSampled, localParentNotSampled Sampler } // ParentBasedSamplerOption configures the sampler for a particular sampling case. type ParentBasedSamplerOption interface { - Apply(*config) - - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() + apply(samplerConfig) samplerConfig } // WithRemoteParentSampled sets the sampler for the case of sampled remote parent. @@ -207,12 +214,11 @@ type remoteParentSampledOption struct { s Sampler } -func (o remoteParentSampledOption) Apply(config *config) { +func (o remoteParentSampledOption) apply(config samplerConfig) samplerConfig { config.remoteParentSampled = o.s + return config } -func (remoteParentSampledOption) private() {} - // WithRemoteParentNotSampled sets the sampler for the case of remote parent // which is not sampled. func WithRemoteParentNotSampled(s Sampler) ParentBasedSamplerOption { @@ -223,12 +229,11 @@ type remoteParentNotSampledOption struct { s Sampler } -func (o remoteParentNotSampledOption) Apply(config *config) { +func (o remoteParentNotSampledOption) apply(config samplerConfig) samplerConfig { config.remoteParentNotSampled = o.s + return config } -func (remoteParentNotSampledOption) private() {} - // WithLocalParentSampled sets the sampler for the case of sampled local parent. func WithLocalParentSampled(s Sampler) ParentBasedSamplerOption { return localParentSampledOption{s} @@ -238,12 +243,11 @@ type localParentSampledOption struct { s Sampler } -func (o localParentSampledOption) Apply(config *config) { +func (o localParentSampledOption) apply(config samplerConfig) samplerConfig { config.localParentSampled = o.s + return config } -func (localParentSampledOption) private() {} - // WithLocalParentNotSampled sets the sampler for the case of local parent // which is not sampled. func WithLocalParentNotSampled(s Sampler) ParentBasedSamplerOption { @@ -254,12 +258,11 @@ type localParentNotSampledOption struct { s Sampler } -func (o localParentNotSampledOption) Apply(config *config) { +func (o localParentNotSampledOption) apply(config samplerConfig) samplerConfig { config.localParentNotSampled = o.s + return config } -func (localParentNotSampledOption) private() {} - func (pb parentBased) ShouldSample(p SamplingParameters) SamplingResult { psc := trace.SpanContextFromContext(p.ParentContext) if psc.IsValid() { diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go index b66a87a2a3f..f8770fff79b 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go @@ -19,12 +19,13 @@ import ( "sync" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/internal/global" ) // simpleSpanProcessor is a SpanProcessor that synchronously sends all // completed Spans to a trace.Exporter immediately. type simpleSpanProcessor struct { - exporterMu sync.RWMutex + exporterMu sync.Mutex exporter SpanExporter stopOnce sync.Once } @@ -33,10 +34,18 @@ var _ SpanProcessor = (*simpleSpanProcessor)(nil) // NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously // send completed spans to the exporter immediately. +// +// This SpanProcessor is not recommended for production use. The synchronous +// nature of this SpanProcessor make it good for testing, debugging, or +// showing examples of other feature, but it will be slow and have a high +// computation resource usage overhead. The BatchSpanProcessor is recommended +// for production use instead. func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor { ssp := &simpleSpanProcessor{ exporter: exporter, } + global.Warn("SimpleSpanProcessor is not recommended for production use, consider using BatchSpanProcessor instead.") + return ssp } @@ -45,12 +54,11 @@ func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {} // OnEnd immediately exports a ReadOnlySpan. func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { - ssp.exporterMu.RLock() - defer ssp.exporterMu.RUnlock() + ssp.exporterMu.Lock() + defer ssp.exporterMu.Unlock() if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() { - ss := s.Snapshot() - if err := ssp.exporter.ExportSpans(context.Background(), []*SpanSnapshot{ss}); err != nil { + if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil { otel.Handle(err) } } @@ -60,16 +68,48 @@ func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error { var err error ssp.stopOnce.Do(func() { + stopFunc := func(exp SpanExporter) (<-chan error, func()) { + done := make(chan error) + return done, func() { done <- exp.Shutdown(ctx) } + } + + // The exporter field of the simpleSpanProcessor needs to be zeroed to + // signal it is shut down, meaning all subsequent calls to OnEnd will + // be gracefully ignored. This needs to be done synchronously to avoid + // any race condition. + // + // A closure is used to keep reference to the exporter and then the + // field is zeroed. This ensures the simpleSpanProcessor is shut down + // before the exporter. This order is important as it avoids a + // potential deadlock. If the exporter shut down operation generates a + // span, that span would need to be exported. Meaning, OnEnd would be + // called and try acquiring the lock that is held here. ssp.exporterMu.Lock() - exporter := ssp.exporter - // Set exporter to nil so subsequent calls to OnEnd are ignored - // gracefully. + done, shutdown := stopFunc(ssp.exporter) ssp.exporter = nil ssp.exporterMu.Unlock() - // Clear the ssp.exporter prior to shutting it down so if that creates - // a span that needs to be exported there is no deadlock. - err = exporter.Shutdown(ctx) + go shutdown() + + // Wait for the exporter to shut down or the deadline to expire. + select { + case err = <-done: + case <-ctx.Done(): + // It is possible for the exporter to have immediately shut down + // and the context to be done simultaneously. In that case this + // outer select statement will randomly choose a case. This will + // result in a different returned error for similar scenarios. + // Instead, double check if the exporter shut down at the same + // time and return that error if so. This will ensure consistency + // as well as ensure the caller knows the exporter shut down + // successfully (they can already determine if the deadline is + // expired given they passed the context). + select { + case err = <-done: + default: + err = ctx.Err() + } + } }) return err } @@ -78,3 +118,14 @@ func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error { func (ssp *simpleSpanProcessor) ForceFlush(context.Context) error { return nil } + +// MarshalLog is the marshaling function used by the logging system to represent this Span Processor. +func (ssp *simpleSpanProcessor) MarshalLog() interface{} { + return struct { + Type string + Exporter SpanExporter + }{ + Type: "SimpleSpanProcessor", + Exporter: ssp.exporter, + } +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go b/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go new file mode 100644 index 00000000000..0349b2f198e --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go @@ -0,0 +1,144 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import ( + "time" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/trace" +) + +// snapshot is an record of a spans state at a particular checkpointed time. +// It is used as a read-only representation of that state. +type snapshot struct { + name string + spanContext trace.SpanContext + parent trace.SpanContext + spanKind trace.SpanKind + startTime time.Time + endTime time.Time + attributes []attribute.KeyValue + events []Event + links []Link + status Status + childSpanCount int + droppedAttributeCount int + droppedEventCount int + droppedLinkCount int + resource *resource.Resource + instrumentationScope instrumentation.Scope +} + +var _ ReadOnlySpan = snapshot{} + +func (s snapshot) private() {} + +// Name returns the name of the span. +func (s snapshot) Name() string { + return s.name +} + +// SpanContext returns the unique SpanContext that identifies the span. +func (s snapshot) SpanContext() trace.SpanContext { + return s.spanContext +} + +// Parent returns the unique SpanContext that identifies the parent of the +// span if one exists. If the span has no parent the returned SpanContext +// will be invalid. +func (s snapshot) Parent() trace.SpanContext { + return s.parent +} + +// SpanKind returns the role the span plays in a Trace. +func (s snapshot) SpanKind() trace.SpanKind { + return s.spanKind +} + +// StartTime returns the time the span started recording. +func (s snapshot) StartTime() time.Time { + return s.startTime +} + +// EndTime returns the time the span stopped recording. It will be zero if +// the span has not ended. +func (s snapshot) EndTime() time.Time { + return s.endTime +} + +// Attributes returns the defining attributes of the span. +func (s snapshot) Attributes() []attribute.KeyValue { + return s.attributes +} + +// Links returns all the links the span has to other spans. +func (s snapshot) Links() []Link { + return s.links +} + +// Events returns all the events that occurred within in the spans +// lifetime. +func (s snapshot) Events() []Event { + return s.events +} + +// Status returns the spans status. +func (s snapshot) Status() Status { + return s.status +} + +// InstrumentationScope returns information about the instrumentation +// scope that created the span. +func (s snapshot) InstrumentationScope() instrumentation.Scope { + return s.instrumentationScope +} + +// InstrumentationLibrary returns information about the instrumentation +// library that created the span. +func (s snapshot) InstrumentationLibrary() instrumentation.Library { + return s.instrumentationScope +} + +// Resource returns information about the entity that produced the span. +func (s snapshot) Resource() *resource.Resource { + return s.resource +} + +// DroppedAttributes returns the number of attributes dropped by the span +// due to limits being reached. +func (s snapshot) DroppedAttributes() int { + return s.droppedAttributeCount +} + +// DroppedLinks returns the number of links dropped by the span due to limits +// being reached. +func (s snapshot) DroppedLinks() int { + return s.droppedLinkCount +} + +// DroppedEvents returns the number of events dropped by the span due to +// limits being reached. +func (s snapshot) DroppedEvents() int { + return s.droppedEventCount +} + +// ChildSpanCount returns the count of spans that consider the span a +// direct parent. +func (s snapshot) ChildSpanCount() int { + return s.childSpanCount +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go index f13967d2b59..37cdd4a694a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go @@ -18,41 +18,74 @@ import ( "context" "fmt" "reflect" + "runtime" + rt "runtime/trace" + "strings" "sync" "time" + "unicode/utf8" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/semconv" - "go.opentelemetry.io/otel/trace" - "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/internal" "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" + "go.opentelemetry.io/otel/trace" ) // ReadOnlySpan allows reading information from the data structure underlying a // trace.Span. It is used in places where reading information from a span is // necessary but changing the span isn't necessary or allowed. -// TODO: Should we make the methods unexported? The purpose of this interface -// is controlling access to `span` fields, not having multiple implementations. +// +// Warning: methods may be added to this interface in minor releases. type ReadOnlySpan interface { + // Name returns the name of the span. Name() string + // SpanContext returns the unique SpanContext that identifies the span. SpanContext() trace.SpanContext + // Parent returns the unique SpanContext that identifies the parent of the + // span if one exists. If the span has no parent the returned SpanContext + // will be invalid. Parent() trace.SpanContext + // SpanKind returns the role the span plays in a Trace. SpanKind() trace.SpanKind + // StartTime returns the time the span started recording. StartTime() time.Time + // EndTime returns the time the span stopped recording. It will be zero if + // the span has not ended. EndTime() time.Time + // Attributes returns the defining attributes of the span. + // The order of the returned attributes is not guaranteed to be stable across invocations. Attributes() []attribute.KeyValue - Links() []trace.Link - Events() []trace.Event - StatusCode() codes.Code - StatusMessage() string - Tracer() trace.Tracer - IsRecording() bool + // Links returns all the links the span has to other spans. + Links() []Link + // Events returns all the events that occurred within in the spans + // lifetime. + Events() []Event + // Status returns the spans status. + Status() Status + // InstrumentationScope returns information about the instrumentation + // scope that created the span. + InstrumentationScope() instrumentation.Scope + // InstrumentationLibrary returns information about the instrumentation + // library that created the span. + // Deprecated: please use InstrumentationScope instead. InstrumentationLibrary() instrumentation.Library + // Resource returns information about the entity that produced the span. Resource() *resource.Resource - Snapshot() *SpanSnapshot + // DroppedAttributes returns the number of attributes dropped by the span + // due to limits being reached. + DroppedAttributes() int + // DroppedLinks returns the number of links dropped by the span due to + // limits being reached. + DroppedLinks() int + // DroppedEvents returns the number of events dropped by the span due to + // limits being reached. + DroppedEvents() int + // ChildSpanCount returns the count of spans that consider the span a + // direct parent. + ChildSpanCount() int // A private method to prevent users implementing the // interface and so future additions to it will not @@ -65,14 +98,16 @@ type ReadOnlySpan interface { // This interface exposes the union of the methods of trace.Span (which is a // "write-only" span) and ReadOnlySpan. New methods for writing or reading span // information should be added under trace.Span or ReadOnlySpan, respectively. +// +// Warning: methods may be added to this interface in minor releases. type ReadWriteSpan interface { trace.Span ReadOnlySpan } -// span is an implementation of the OpenTelemetry Span API representing the -// individual component of a trace. -type span struct { +// recordingSpan is an implementation of the OpenTelemetry Span API +// representing the individual component of a trace that is sampled. +type recordingSpan struct { // mu protects the contents of this span. mu sync.Mutex @@ -92,50 +127,42 @@ type span struct { // value of time.Time until the span is ended. endTime time.Time - // statusCode represents the status of this span as a codes.Code value. - statusCode codes.Code - - // statusMessage represents the status of this span as a string. - statusMessage string + // status is the status of this span. + status Status // childSpanCount holds the number of child spans created for this span. childSpanCount int - // resource contains attributes representing an entity that produced this - // span. - resource *resource.Resource - - // instrumentationLibrary defines the instrumentation library used to - // provide instrumentation. - instrumentationLibrary instrumentation.Library - // spanContext holds the SpanContext of this span. spanContext trace.SpanContext - // attributes are capped at configured limit. When the capacity is reached - // an oldest entry is removed to create room for a new entry. - attributes *attributesMap + // attributes is a collection of user provided key/values. The collection + // is constrained by a configurable maximum held by the parent + // TracerProvider. When additional attributes are added after this maximum + // is reached these attributes the user is attempting to add are dropped. + // This dropped number of attributes is tracked and reported in the + // ReadOnlySpan exported when the span ends. + attributes []attribute.KeyValue + droppedAttributes int - // messageEvents are stored in FIFO queue capped by configured limit. - messageEvents *evictedQueue + // events are stored in FIFO queue capped by configured limit. + events evictedQueue // links are stored in FIFO queue capped by configured limit. - links *evictedQueue + links evictedQueue // executionTracerTaskEnd ends the execution tracer span. executionTracerTaskEnd func() // tracer is the SDK tracer that created this span. tracer *tracer - - // spanLimits holds the limits to this span. - spanLimits SpanLimits } -var _ trace.Span = &span{} +var _ ReadWriteSpan = (*recordingSpan)(nil) +var _ runtimeTracer = (*recordingSpan)(nil) // SpanContext returns the SpanContext of this span. -func (s *span) SpanContext() trace.SpanContext { +func (s *recordingSpan) SpanContext() trace.SpanContext { if s == nil { return trace.SpanContext{} } @@ -144,30 +171,36 @@ func (s *span) SpanContext() trace.SpanContext { // IsRecording returns if this span is being recorded. If this span has ended // this will return false. -func (s *span) IsRecording() bool { +func (s *recordingSpan) IsRecording() bool { if s == nil { return false } s.mu.Lock() defer s.mu.Unlock() - return !s.startTime.IsZero() && s.endTime.IsZero() + return s.endTime.IsZero() } -// SetStatus sets the status of this span in the form of a code and a -// message. This overrides the existing value of this span's status if one -// exists. Message will be set only if status is error. If this span is not being -// recorded than this method does nothing. -func (s *span) SetStatus(code codes.Code, msg string) { +// SetStatus sets the status of the Span in the form of a code and a +// description, overriding previous values set. The description is only +// included in the set status when the code is for an error. If this span is +// not being recorded than this method does nothing. +func (s *recordingSpan) SetStatus(code codes.Code, description string) { if !s.IsRecording() { return } s.mu.Lock() - s.statusCode = code + defer s.mu.Unlock() + if s.status.Code > code { + return + } + + status := Status{Code: code} if code == codes.Error { - s.statusMessage = msg + status.Description = description } - s.mu.Unlock() + + s.status = status } // SetAttributes sets attributes of this span. @@ -176,11 +209,147 @@ func (s *span) SetStatus(code codes.Code, msg string) { // will be overwritten with the value contained in attributes. // // If this span is not being recorded than this method does nothing. -func (s *span) SetAttributes(attributes ...attribute.KeyValue) { +// +// If adding attributes to the span would exceed the maximum amount of +// attributes the span is configured to have, the last added attributes will +// be dropped. +func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) { if !s.IsRecording() { return } - s.copyToCappedAttributes(attributes...) + + s.mu.Lock() + defer s.mu.Unlock() + + limit := s.tracer.provider.spanLimits.AttributeCountLimit + if limit == 0 { + // No attributes allowed. + s.droppedAttributes += len(attributes) + return + } + + // If adding these attributes could exceed the capacity of s perform a + // de-duplication and truncation while adding to avoid over allocation. + if limit > 0 && len(s.attributes)+len(attributes) > limit { + s.addOverCapAttrs(limit, attributes) + return + } + + // Otherwise, add without deduplication. When attributes are read they + // will be deduplicated, optimizing the operation. + for _, a := range attributes { + if !a.Valid() { + // Drop all invalid attributes. + s.droppedAttributes++ + continue + } + a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) + s.attributes = append(s.attributes, a) + } +} + +// addOverCapAttrs adds the attributes attrs to the span s while +// de-duplicating the attributes of s and attrs and dropping attributes that +// exceed the limit. +// +// This method assumes s.mu.Lock is held by the caller. +// +// This method should only be called when there is a possibility that adding +// attrs to s will exceed the limit. Otherwise, attrs should be added to s +// without checking for duplicates and all retrieval methods of the attributes +// for s will de-duplicate as needed. +// +// This method assumes limit is a value > 0. The argument should be validated +// by the caller. +func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) { + // In order to not allocate more capacity to s.attributes than needed, + // prune and truncate this addition of attributes while adding. + + // Do not set a capacity when creating this map. Benchmark testing has + // showed this to only add unused memory allocations in general use. + exists := make(map[attribute.Key]int) + s.dedupeAttrsFromRecord(&exists) + + // Now that s.attributes is deduplicated, adding unique attributes up to + // the capacity of s will not over allocate s.attributes. + for _, a := range attrs { + if !a.Valid() { + // Drop all invalid attributes. + s.droppedAttributes++ + continue + } + + if idx, ok := exists[a.Key]; ok { + // Perform all updates before dropping, even when at capacity. + s.attributes[idx] = a + continue + } + + if len(s.attributes) >= limit { + // Do not just drop all of the remaining attributes, make sure + // updates are checked and performed. + s.droppedAttributes++ + } else { + a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) + s.attributes = append(s.attributes, a) + exists[a.Key] = len(s.attributes) - 1 + } + } +} + +// truncateAttr returns a truncated version of attr. Only string and string +// slice attribute values are truncated. String values are truncated to at +// most a length of limit. Each string slice value is truncated in this fashion +// (the slice length itself is unaffected). +// +// No truncation is performed for a negative limit. +func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue { + if limit < 0 { + return attr + } + switch attr.Value.Type() { + case attribute.STRING: + if v := attr.Value.AsString(); len(v) > limit { + return attr.Key.String(safeTruncate(v, limit)) + } + case attribute.STRINGSLICE: + v := attr.Value.AsStringSlice() + for i := range v { + if len(v[i]) > limit { + v[i] = safeTruncate(v[i], limit) + } + } + return attr.Key.StringSlice(v) + } + return attr +} + +// safeTruncate truncates the string and guarantees valid UTF-8 is returned. +func safeTruncate(input string, limit int) string { + if trunc, ok := safeTruncateValidUTF8(input, limit); ok { + return trunc + } + trunc, _ := safeTruncateValidUTF8(strings.ToValidUTF8(input, ""), limit) + return trunc +} + +// safeTruncateValidUTF8 returns a copy of the input string safely truncated to +// limit. The truncation is ensured to occur at the bounds of complete UTF-8 +// characters. If invalid encoding of UTF-8 is encountered, input is returned +// with false, otherwise, the truncated input will be returned with true. +func safeTruncateValidUTF8(input string, limit int) (string, bool) { + for cnt := 0; cnt <= limit; { + r, size := utf8.DecodeRuneInString(input[cnt:]) + if r == utf8.RuneError { + return input, false + } + + if cnt+size > limit { + return input[:cnt], true + } + cnt += size + } + return input, true } // End ends the span. This method does nothing if the span is already ended or @@ -191,7 +360,7 @@ func (s *span) SetAttributes(attributes ...attribute.KeyValue) { // // If this method is called while panicking an error event is added to the // Span before ending it and the panic is continued. -func (s *span) End(options ...trace.SpanOption) { +func (s *recordingSpan) End(options ...trace.SpanEndOption) { // Do not start by checking if the span is being recorded which requires // acquiring a lock. Make a minimal check that the span is not nil. if s == nil { @@ -208,39 +377,46 @@ func (s *span) End(options ...trace.SpanOption) { return } + config := trace.NewSpanEndConfig(options...) if recovered := recover(); recovered != nil { // Record but don't stop the panic. defer panic(recovered) - s.addEvent( - semconv.ExceptionEventName, + opts := []trace.EventOption{ trace.WithAttributes( - semconv.ExceptionTypeKey.String(typeStr(recovered)), - semconv.ExceptionMessageKey.String(fmt.Sprint(recovered)), + semconv.ExceptionType(typeStr(recovered)), + semconv.ExceptionMessage(fmt.Sprint(recovered)), ), - ) + } + + if config.StackTrace() { + opts = append(opts, trace.WithAttributes( + semconv.ExceptionStacktrace(recordStackTrace()), + )) + } + + s.addEvent(semconv.ExceptionEventName, opts...) } if s.executionTracerTaskEnd != nil { s.executionTracerTaskEnd() } - config := trace.NewSpanConfig(options...) - s.mu.Lock() // Setting endTime to non-zero marks the span as ended and not recording. - if config.Timestamp.IsZero() { + if config.Timestamp().IsZero() { s.endTime = et } else { - s.endTime = config.Timestamp + s.endTime = config.Timestamp() } s.mu.Unlock() - sps, ok := s.tracer.provider.spanProcessors.Load().(spanProcessorStates) - mustExportOrProcess := ok && len(sps) > 0 - if mustExportOrProcess { - for _, sp := range sps { - sp.sp.OnEnd(s) - } + sps := s.tracer.provider.getSpanProcessors() + if len(sps) == 0 { + return + } + snap := s.snapshot() + for _, sp := range sps { + sp.sp.OnEnd(snap) } } @@ -248,15 +424,23 @@ func (s *span) End(options ...trace.SpanOption) { // SetStatus is required if the Status of the Span should be set to Error, this method // does not change the Span status. If this span is not being recorded or err is nil // than this method does nothing. -func (s *span) RecordError(err error, opts ...trace.EventOption) { +func (s *recordingSpan) RecordError(err error, opts ...trace.EventOption) { if s == nil || err == nil || !s.IsRecording() { return } opts = append(opts, trace.WithAttributes( - semconv.ExceptionTypeKey.String(typeStr(err)), - semconv.ExceptionMessageKey.String(err.Error()), + semconv.ExceptionType(typeStr(err)), + semconv.ExceptionMessage(err.Error()), )) + + c := trace.NewEventConfig(opts...) + if c.StackTrace() { + opts = append(opts, trace.WithAttributes( + semconv.ExceptionStacktrace(recordStackTrace()), + )) + } + s.addEvent(semconv.ExceptionEventName, opts...) } @@ -269,43 +453,46 @@ func typeStr(i interface{}) string { return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) } -// Tracer returns the Tracer that created this span. -func (s *span) Tracer() trace.Tracer { - return s.tracer +func recordStackTrace() string { + stackTrace := make([]byte, 2048) + n := runtime.Stack(stackTrace, false) + + return string(stackTrace[0:n]) } // AddEvent adds an event with the provided name and options. If this span is // not being recorded than this method does nothing. -func (s *span) AddEvent(name string, o ...trace.EventOption) { +func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) { if !s.IsRecording() { return } s.addEvent(name, o...) } -func (s *span) addEvent(name string, o ...trace.EventOption) { +func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) { c := trace.NewEventConfig(o...) + e := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()} - // Discard over limited attributes - var discarded int - if len(c.Attributes) > s.spanLimits.AttributePerEventCountLimit { - discarded = len(c.Attributes) - s.spanLimits.AttributePerEventCountLimit - c.Attributes = c.Attributes[:s.spanLimits.AttributePerEventCountLimit] + // Discard attributes over limit. + limit := s.tracer.provider.spanLimits.AttributePerEventCountLimit + if limit == 0 { + // Drop all attributes. + e.DroppedAttributeCount = len(e.Attributes) + e.Attributes = nil + } else if limit > 0 && len(e.Attributes) > limit { + // Drop over capacity. + e.DroppedAttributeCount = len(e.Attributes) - limit + e.Attributes = e.Attributes[:limit] } s.mu.Lock() - defer s.mu.Unlock() - s.messageEvents.add(trace.Event{ - Name: name, - Attributes: c.Attributes, - DroppedAttributeCount: discarded, - Time: c.Timestamp, - }) + s.events.add(e) + s.mu.Unlock() } // SetName sets the name of this span. If this span is not being recorded than // this method does nothing. -func (s *span) SetName(name string) { +func (s *recordingSpan) SetName(name string) { if !s.IsRecording() { return } @@ -316,28 +503,28 @@ func (s *span) SetName(name string) { } // Name returns the name of this span. -func (s *span) Name() string { +func (s *recordingSpan) Name() string { s.mu.Lock() defer s.mu.Unlock() return s.name } // Name returns the SpanContext of this span's parent span. -func (s *span) Parent() trace.SpanContext { +func (s *recordingSpan) Parent() trace.SpanContext { s.mu.Lock() defer s.mu.Unlock() return s.parent } // SpanKind returns the SpanKind of this span. -func (s *span) SpanKind() trace.SpanKind { +func (s *recordingSpan) SpanKind() trace.SpanKind { s.mu.Lock() defer s.mu.Unlock() return s.spanKind } // StartTime returns the time this span started. -func (s *span) StartTime() time.Time { +func (s *recordingSpan) StartTime() time.Time { s.mu.Lock() defer s.mu.Unlock() return s.startTime @@ -345,151 +532,216 @@ func (s *span) StartTime() time.Time { // EndTime returns the time this span ended. For spans that have not yet // ended, the returned value will be the zero value of time.Time. -func (s *span) EndTime() time.Time { +func (s *recordingSpan) EndTime() time.Time { s.mu.Lock() defer s.mu.Unlock() return s.endTime } // Attributes returns the attributes of this span. -func (s *span) Attributes() []attribute.KeyValue { +// +// The order of the returned attributes is not guaranteed to be stable. +func (s *recordingSpan) Attributes() []attribute.KeyValue { s.mu.Lock() defer s.mu.Unlock() - if s.attributes.evictList.Len() == 0 { - return []attribute.KeyValue{} + s.dedupeAttrs() + return s.attributes +} + +// dedupeAttrs deduplicates the attributes of s to fit capacity. +// +// This method assumes s.mu.Lock is held by the caller. +func (s *recordingSpan) dedupeAttrs() { + // Do not set a capacity when creating this map. Benchmark testing has + // showed this to only add unused memory allocations in general use. + exists := make(map[attribute.Key]int) + s.dedupeAttrsFromRecord(&exists) +} + +// dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity +// using record as the record of unique attribute keys to their index. +// +// This method assumes s.mu.Lock is held by the caller. +func (s *recordingSpan) dedupeAttrsFromRecord(record *map[attribute.Key]int) { + // Use the fact that slices share the same backing array. + unique := s.attributes[:0] + for _, a := range s.attributes { + if idx, ok := (*record)[a.Key]; ok { + unique[idx] = a + } else { + unique = append(unique, a) + (*record)[a.Key] = len(unique) - 1 + } } - return s.attributes.toKeyValue() + // s.attributes have element types of attribute.KeyValue. These types are + // not pointers and they themselves do not contain pointer fields, + // therefore the duplicate values do not need to be zeroed for them to be + // garbage collected. + s.attributes = unique } // Links returns the links of this span. -func (s *span) Links() []trace.Link { +func (s *recordingSpan) Links() []Link { s.mu.Lock() defer s.mu.Unlock() if len(s.links.queue) == 0 { - return []trace.Link{} + return []Link{} } return s.interfaceArrayToLinksArray() } // Events returns the events of this span. -func (s *span) Events() []trace.Event { +func (s *recordingSpan) Events() []Event { s.mu.Lock() defer s.mu.Unlock() - if len(s.messageEvents.queue) == 0 { - return []trace.Event{} + if len(s.events.queue) == 0 { + return []Event{} } - return s.interfaceArrayToMessageEventArray() + return s.interfaceArrayToEventArray() } -// StatusCode returns the status code of this span. -func (s *span) StatusCode() codes.Code { +// Status returns the status of this span. +func (s *recordingSpan) Status() Status { s.mu.Lock() defer s.mu.Unlock() - return s.statusCode + return s.status } -// StatusMessage returns the status message of this span. -func (s *span) StatusMessage() string { +// InstrumentationScope returns the instrumentation.Scope associated with +// the Tracer that created this span. +func (s *recordingSpan) InstrumentationScope() instrumentation.Scope { s.mu.Lock() defer s.mu.Unlock() - return s.statusMessage + return s.tracer.instrumentationScope } // InstrumentationLibrary returns the instrumentation.Library associated with // the Tracer that created this span. -func (s *span) InstrumentationLibrary() instrumentation.Library { +func (s *recordingSpan) InstrumentationLibrary() instrumentation.Library { s.mu.Lock() defer s.mu.Unlock() - return s.instrumentationLibrary + return s.tracer.instrumentationScope } // Resource returns the Resource associated with the Tracer that created this // span. -func (s *span) Resource() *resource.Resource { +func (s *recordingSpan) Resource() *resource.Resource { s.mu.Lock() defer s.mu.Unlock() - return s.resource + return s.tracer.provider.resource } -func (s *span) addLink(link trace.Link) { - if !s.IsRecording() { +func (s *recordingSpan) addLink(link trace.Link) { + if !s.IsRecording() || !link.SpanContext.IsValid() { return } + + l := Link{SpanContext: link.SpanContext, Attributes: link.Attributes} + + // Discard attributes over limit. + limit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit + if limit == 0 { + // Drop all attributes. + l.DroppedAttributeCount = len(l.Attributes) + l.Attributes = nil + } else if limit > 0 && len(l.Attributes) > limit { + l.DroppedAttributeCount = len(l.Attributes) - limit + l.Attributes = l.Attributes[:limit] + } + + s.mu.Lock() + s.links.add(l) + s.mu.Unlock() +} + +// DroppedAttributes returns the number of attributes dropped by the span +// due to limits being reached. +func (s *recordingSpan) DroppedAttributes() int { s.mu.Lock() defer s.mu.Unlock() + return s.droppedAttributes +} - // Discard over limited attributes - if len(link.Attributes) > s.spanLimits.AttributePerLinkCountLimit { - link.DroppedAttributeCount = len(link.Attributes) - s.spanLimits.AttributePerLinkCountLimit - link.Attributes = link.Attributes[:s.spanLimits.AttributePerLinkCountLimit] - } +// DroppedLinks returns the number of links dropped by the span due to limits +// being reached. +func (s *recordingSpan) DroppedLinks() int { + s.mu.Lock() + defer s.mu.Unlock() + return s.links.droppedCount +} + +// DroppedEvents returns the number of events dropped by the span due to +// limits being reached. +func (s *recordingSpan) DroppedEvents() int { + s.mu.Lock() + defer s.mu.Unlock() + return s.events.droppedCount +} + +// ChildSpanCount returns the count of spans that consider the span a +// direct parent. +func (s *recordingSpan) ChildSpanCount() int { + s.mu.Lock() + defer s.mu.Unlock() + return s.childSpanCount +} - s.links.add(link) +// TracerProvider returns a trace.TracerProvider that can be used to generate +// additional Spans on the same telemetry pipeline as the current Span. +func (s *recordingSpan) TracerProvider() trace.TracerProvider { + return s.tracer.provider } -// Snapshot creates a snapshot representing the current state of the span as an -// export.SpanSnapshot and returns a pointer to it. -func (s *span) Snapshot() *SpanSnapshot { - var sd SpanSnapshot +// snapshot creates a read-only copy of the current state of the span. +func (s *recordingSpan) snapshot() ReadOnlySpan { + var sd snapshot s.mu.Lock() defer s.mu.Unlock() - sd.ChildSpanCount = s.childSpanCount - sd.EndTime = s.endTime - sd.InstrumentationLibrary = s.instrumentationLibrary - sd.Name = s.name - sd.Parent = s.parent - sd.Resource = s.resource - sd.SpanContext = s.spanContext - sd.SpanKind = s.spanKind - sd.StartTime = s.startTime - sd.StatusCode = s.statusCode - sd.StatusMessage = s.statusMessage - - if s.attributes.evictList.Len() > 0 { - sd.Attributes = s.attributes.toKeyValue() - sd.DroppedAttributeCount = s.attributes.droppedCount - } - if len(s.messageEvents.queue) > 0 { - sd.MessageEvents = s.interfaceArrayToMessageEventArray() - sd.DroppedMessageEventCount = s.messageEvents.droppedCount + sd.endTime = s.endTime + sd.instrumentationScope = s.tracer.instrumentationScope + sd.name = s.name + sd.parent = s.parent + sd.resource = s.tracer.provider.resource + sd.spanContext = s.spanContext + sd.spanKind = s.spanKind + sd.startTime = s.startTime + sd.status = s.status + sd.childSpanCount = s.childSpanCount + + if len(s.attributes) > 0 { + s.dedupeAttrs() + sd.attributes = s.attributes + } + sd.droppedAttributeCount = s.droppedAttributes + if len(s.events.queue) > 0 { + sd.events = s.interfaceArrayToEventArray() + sd.droppedEventCount = s.events.droppedCount } if len(s.links.queue) > 0 { - sd.Links = s.interfaceArrayToLinksArray() - sd.DroppedLinkCount = s.links.droppedCount + sd.links = s.interfaceArrayToLinksArray() + sd.droppedLinkCount = s.links.droppedCount } return &sd } -func (s *span) interfaceArrayToLinksArray() []trace.Link { - linkArr := make([]trace.Link, 0) +func (s *recordingSpan) interfaceArrayToLinksArray() []Link { + linkArr := make([]Link, 0) for _, value := range s.links.queue { - linkArr = append(linkArr, value.(trace.Link)) + linkArr = append(linkArr, value.(Link)) } return linkArr } -func (s *span) interfaceArrayToMessageEventArray() []trace.Event { - messageEventArr := make([]trace.Event, 0) - for _, value := range s.messageEvents.queue { - messageEventArr = append(messageEventArr, value.(trace.Event)) - } - return messageEventArr -} - -func (s *span) copyToCappedAttributes(attributes ...attribute.KeyValue) { - s.mu.Lock() - defer s.mu.Unlock() - for _, a := range attributes { - // Ensure attributes conform to the specification: - // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.0.1/specification/common/common.md#attributes - if a.Valid() { - s.attributes.add(a) - } +func (s *recordingSpan) interfaceArrayToEventArray() []Event { + eventArr := make([]Event, 0) + for _, value := range s.events.queue { + eventArr = append(eventArr, value.(Event)) } + return eventArr } -func (s *span) addChild() { +func (s *recordingSpan) addChild() { if !s.IsRecording() { return } @@ -498,79 +750,65 @@ func (s *span) addChild() { s.mu.Unlock() } -func (*span) private() {} +func (*recordingSpan) private() {} -func startSpanInternal(ctx context.Context, tr *tracer, name string, o *trace.SpanConfig) *span { - span := &span{} +// runtimeTrace starts a "runtime/trace".Task for the span and returns a +// context containing the task. +func (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context { + if !rt.IsEnabled() { + // Avoid additional overhead if runtime/trace is not enabled. + return ctx + } + nctx, task := rt.NewTask(ctx, s.name) - provider := tr.provider + s.mu.Lock() + s.executionTracerTaskEnd = task.End + s.mu.Unlock() - // If told explicitly to make this a new root use a zero value SpanContext - // as a parent which contains an invalid trace ID and is not remote. - var psc trace.SpanContext - if !o.NewRoot { - psc = trace.SpanContextFromContext(ctx) - } + return nctx +} - // If there is a valid parent trace ID, use it to ensure the continuity of - // the trace. Always generate a new span ID so other components can rely - // on a unique span ID, even if the Span is non-recording. - var tid trace.TraceID - var sid trace.SpanID - if !psc.TraceID().IsValid() { - tid, sid = provider.idGenerator.NewIDs(ctx) - } else { - tid = psc.TraceID() - sid = provider.idGenerator.NewSpanID(ctx, tid) - } - - spanLimits := provider.spanLimits - span.attributes = newAttributesMap(spanLimits.AttributeCountLimit) - span.messageEvents = newEvictedQueue(spanLimits.EventCountLimit) - span.links = newEvictedQueue(spanLimits.LinkCountLimit) - span.spanLimits = spanLimits - - samplingResult := provider.sampler.ShouldSample(SamplingParameters{ - ParentContext: ctx, - TraceID: tid, - Name: name, - Kind: o.SpanKind, - Attributes: o.Attributes, - Links: o.Links, - }) - - scc := trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - TraceState: samplingResult.Tracestate, - } - if isSampled(samplingResult) { - scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled - } else { - scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled - } - span.spanContext = trace.NewSpanContext(scc) +// nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API +// that wraps a SpanContext. It performs no operations other than to return +// the wrapped SpanContext or TracerProvider that created it. +type nonRecordingSpan struct { + // tracer is the SDK tracer that created this span. + tracer *tracer + sc trace.SpanContext +} - if !isRecording(samplingResult) { - return span - } +var _ trace.Span = nonRecordingSpan{} - startTime := o.Timestamp - if startTime.IsZero() { - startTime = time.Now() - } - span.startTime = startTime +// SpanContext returns the wrapped SpanContext. +func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc } - span.spanKind = trace.ValidateSpanKind(o.SpanKind) - span.name = name - span.parent = psc - span.resource = provider.resource - span.instrumentationLibrary = tr.instrumentationLibrary +// IsRecording always returns false. +func (nonRecordingSpan) IsRecording() bool { return false } - span.SetAttributes(samplingResult.Attributes...) +// SetStatus does nothing. +func (nonRecordingSpan) SetStatus(codes.Code, string) {} - return span -} +// SetError does nothing. +func (nonRecordingSpan) SetError(bool) {} + +// SetAttributes does nothing. +func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {} + +// End does nothing. +func (nonRecordingSpan) End(...trace.SpanEndOption) {} + +// RecordError does nothing. +func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {} + +// AddEvent does nothing. +func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {} + +// SetName does nothing. +func (nonRecordingSpan) SetName(string) {} + +// TracerProvider returns the trace.TracerProvider that provided the Tracer +// that created this span. +func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider } func isRecording(s SamplingResult) bool { return s.Decision == RecordOnly || s.Decision == RecordAndSample @@ -580,38 +818,11 @@ func isSampled(s SamplingResult) bool { return s.Decision == RecordAndSample } -// SpanSnapshot is a snapshot of a span which contains all the information -// collected by the span. Its main purpose is exporting completed spans. -// Although SpanSnapshot fields can be accessed and potentially modified, -// SpanSnapshot should be treated as immutable. Changes to the span from which -// the SpanSnapshot was created are NOT reflected in the SpanSnapshot. -type SpanSnapshot struct { - SpanContext trace.SpanContext - Parent trace.SpanContext - SpanKind trace.SpanKind - Name string - StartTime time.Time - // The wall clock time of EndTime will be adjusted to always be offset - // from StartTime by the duration of the span. - EndTime time.Time - Attributes []attribute.KeyValue - MessageEvents []trace.Event - Links []trace.Link - StatusCode codes.Code - StatusMessage string - - // DroppedAttributeCount contains dropped attributes for the span itself. - DroppedAttributeCount int - DroppedMessageEventCount int - DroppedLinkCount int - - // ChildSpanCount holds the number of child span created for this span. - ChildSpanCount int - - // Resource contains attributes representing an entity that produced this span. - Resource *resource.Resource - - // InstrumentationLibrary defines the instrumentation library used to - // provide instrumentation. - InstrumentationLibrary instrumentation.Library +// Status is the classified state of a Span. +type Status struct { + // Code is an identifier of a Spans state classification. + Code codes.Code + // Description is a user hint about why that status was set. It is only + // applicable when Code is Error. + Description string } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go index 40e121069d1..c9bd52f7ad4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go @@ -16,10 +16,13 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" import "context" -// SpanExporter handles the delivery of SpanSnapshot structs to external -// receivers. This is the final component in the trace export pipeline. +// SpanExporter handles the delivery of spans to external receivers. This is +// the final component in the trace export pipeline. type SpanExporter interface { - // ExportSpans exports a batch of SpanSnapshots. + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + + // ExportSpans exports a batch of spans. // // This function is called synchronously, so there is no concurrency // safety requirement. However, due to the synchronous calling pattern, @@ -30,10 +33,15 @@ type SpanExporter interface { // calls this function will not implement any retry logic. All errors // returned by this function are considered unrecoverable and will be // reported to a configured error Handler. - ExportSpans(ctx context.Context, ss []*SpanSnapshot) error + ExportSpans(ctx context.Context, spans []ReadOnlySpan) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // Shutdown notifies the exporter of a pending halt to operations. The - // exporter is expected to preform any cleanup or synchronization it + // exporter is expected to perform any cleanup or synchronization it // requires while honoring all timeouts and cancellations contained in // the passed context. Shutdown(ctx context.Context) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go new file mode 100644 index 00000000000..aa4d4221db3 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go @@ -0,0 +1,125 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import "go.opentelemetry.io/otel/sdk/internal/env" + +const ( + // DefaultAttributeValueLengthLimit is the default maximum allowed + // attribute value length, unlimited. + DefaultAttributeValueLengthLimit = -1 + + // DefaultAttributeCountLimit is the default maximum number of attributes + // a span can have. + DefaultAttributeCountLimit = 128 + + // DefaultEventCountLimit is the default maximum number of events a span + // can have. + DefaultEventCountLimit = 128 + + // DefaultLinkCountLimit is the default maximum number of links a span can + // have. + DefaultLinkCountLimit = 128 + + // DefaultAttributePerEventCountLimit is the default maximum number of + // attributes a span event can have. + DefaultAttributePerEventCountLimit = 128 + + // DefaultAttributePerLinkCountLimit is the default maximum number of + // attributes a span link can have. + DefaultAttributePerLinkCountLimit = 128 +) + +// SpanLimits represents the limits of a span. +type SpanLimits struct { + // AttributeValueLengthLimit is the maximum allowed attribute value length. + // + // This limit only applies to string and string slice attribute values. + // Any string longer than this value will be truncated to this length. + // + // Setting this to a negative value means no limit is applied. + AttributeValueLengthLimit int + + // AttributeCountLimit is the maximum allowed span attribute count. Any + // attribute added to a span once this limit is reached will be dropped. + // + // Setting this to zero means no attributes will be recorded. + // + // Setting this to a negative value means no limit is applied. + AttributeCountLimit int + + // EventCountLimit is the maximum allowed span event count. Any event + // added to a span once this limit is reached means it will be added but + // the oldest event will be dropped. + // + // Setting this to zero means no events we be recorded. + // + // Setting this to a negative value means no limit is applied. + EventCountLimit int + + // LinkCountLimit is the maximum allowed span link count. Any link added + // to a span once this limit is reached means it will be added but the + // oldest link will be dropped. + // + // Setting this to zero means no links we be recorded. + // + // Setting this to a negative value means no limit is applied. + LinkCountLimit int + + // AttributePerEventCountLimit is the maximum number of attributes allowed + // per span event. Any attribute added after this limit reached will be + // dropped. + // + // Setting this to zero means no attributes will be recorded for events. + // + // Setting this to a negative value means no limit is applied. + AttributePerEventCountLimit int + + // AttributePerLinkCountLimit is the maximum number of attributes allowed + // per span link. Any attribute added after this limit reached will be + // dropped. + // + // Setting this to zero means no attributes will be recorded for links. + // + // Setting this to a negative value means no limit is applied. + AttributePerLinkCountLimit int +} + +// NewSpanLimits returns a SpanLimits with all limits set to the value their +// corresponding environment variable holds, or the default if unset. +// +// • AttributeValueLengthLimit: OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT +// (default: unlimited) +// +// • AttributeCountLimit: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT (default: 128) +// +// • EventCountLimit: OTEL_SPAN_EVENT_COUNT_LIMIT (default: 128) +// +// • AttributePerEventCountLimit: OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT (default: +// 128) +// +// • LinkCountLimit: OTEL_SPAN_LINK_COUNT_LIMIT (default: 128) +// +// • AttributePerLinkCountLimit: OTEL_LINK_ATTRIBUTE_COUNT_LIMIT (default: 128) +func NewSpanLimits() SpanLimits { + return SpanLimits{ + AttributeValueLengthLimit: env.SpanAttributeValueLength(DefaultAttributeValueLengthLimit), + AttributeCountLimit: env.SpanAttributeCount(DefaultAttributeCountLimit), + EventCountLimit: env.SpanEventCount(DefaultEventCountLimit), + LinkCountLimit: env.SpanLinkCount(DefaultLinkCountLimit), + AttributePerEventCountLimit: env.SpanEventAttributeCount(DefaultAttributePerEventCountLimit), + AttributePerLinkCountLimit: env.SpanLinkAttributeCount(DefaultAttributePerLinkCountLimit), + } +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go index 73f49815e8e..9c53657a719 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go @@ -24,13 +24,20 @@ import ( // and end of a Span's lifecycle, and are called in the order they are // registered. type SpanProcessor interface { + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. + // OnStart is called when a span is started. It is called synchronously // and should not block. OnStart(parent context.Context, s ReadWriteSpan) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. // OnEnd is called when span is finished. It is called synchronously and // hence not block. OnEnd(s ReadOnlySpan) + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. // Shutdown is called when the SDK shuts down. Any cleanup or release of // resources held by the processor should be done in this call. @@ -41,16 +48,25 @@ type SpanProcessor interface { // All timeouts and cancellations contained in ctx must be honored, this // should not block indefinitely. Shutdown(ctx context.Context) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. // ForceFlush exports all ended spans to the configured Exporter that have not yet // been exported. It should only be called when absolutely necessary, such as when // using a FaaS provider that may suspend the process after an invocation, but before // the Processor can export the completed spans. ForceFlush(ctx context.Context) error + // DO NOT CHANGE: any modification will not be backwards compatible and + // must never be done outside of a new major release. } type spanProcessorState struct { sp SpanProcessor - state *sync.Once + state sync.Once +} + +func newSpanProcessorState(sp SpanProcessor) *spanProcessorState { + return &spanProcessorState{sp: sp} } + type spanProcessorStates []*spanProcessorState diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go index b7869eddd2e..85a71227f3f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go @@ -16,16 +16,15 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" import ( "context" - rt "runtime/trace" - - "go.opentelemetry.io/otel/trace" + "time" "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/trace" ) type tracer struct { - provider *TracerProvider - instrumentationLibrary instrumentation.Library + provider *TracerProvider + instrumentationScope instrumentation.Scope } var _ trace.Tracer = &tracer{} @@ -34,42 +33,129 @@ var _ trace.Tracer = &tracer{} // // The Span is created with the provided name and as a child of any existing // span context found in the passed context. The created Span will be -// configured appropriately by any SpanOption passed. Any Timestamp option -// passed will be used as the start time of the Span's life-cycle. -func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanOption) (context.Context, trace.Span) { - config := trace.NewSpanConfig(options...) +// configured appropriately by any SpanOption passed. +func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) { + config := trace.NewSpanStartConfig(options...) + + if ctx == nil { + // Prevent trace.ContextWithSpan from panicking. + ctx = context.Background() + } // For local spans created by this SDK, track child span count. if p := trace.SpanFromContext(ctx); p != nil { - if sdkSpan, ok := p.(*span); ok { + if sdkSpan, ok := p.(*recordingSpan); ok { sdkSpan.addChild() } } - span := startSpanInternal(ctx, tr, name, config) - for _, l := range config.Links { - span.addLink(l) + s := tr.newSpan(ctx, name, &config) + if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() { + sps := tr.provider.getSpanProcessors() + for _, sp := range sps { + sp.sp.OnStart(ctx, rw) + } + } + if rtt, ok := s.(runtimeTracer); ok { + ctx = rtt.runtimeTrace(ctx) } - span.SetAttributes(config.Attributes...) - span.tracer = tr + return trace.ContextWithSpan(ctx, s), s +} - if span.IsRecording() { - sps, _ := tr.provider.spanProcessors.Load().(spanProcessorStates) - for _, sp := range sps { - sp.sp.OnStart(ctx, span) - } +type runtimeTracer interface { + // runtimeTrace starts a "runtime/trace".Task for the span and + // returns a context containing the task. + runtimeTrace(ctx context.Context) context.Context +} + +// newSpan returns a new configured span. +func (tr *tracer) newSpan(ctx context.Context, name string, config *trace.SpanConfig) trace.Span { + // If told explicitly to make this a new root use a zero value SpanContext + // as a parent which contains an invalid trace ID and is not remote. + var psc trace.SpanContext + if config.NewRoot() { + ctx = trace.ContextWithSpanContext(ctx, psc) + } else { + psc = trace.SpanContextFromContext(ctx) } - ctx, span.executionTracerTaskEnd = func(ctx context.Context) (context.Context, func()) { - if !rt.IsEnabled() { - // Avoid additional overhead if - // runtime/trace is not enabled. - return ctx, func() {} - } - nctx, task := rt.NewTask(ctx, name) - return nctx, task.End - }(ctx) + // If there is a valid parent trace ID, use it to ensure the continuity of + // the trace. Always generate a new span ID so other components can rely + // on a unique span ID, even if the Span is non-recording. + var tid trace.TraceID + var sid trace.SpanID + if !psc.TraceID().IsValid() { + tid, sid = tr.provider.idGenerator.NewIDs(ctx) + } else { + tid = psc.TraceID() + sid = tr.provider.idGenerator.NewSpanID(ctx, tid) + } + + samplingResult := tr.provider.sampler.ShouldSample(SamplingParameters{ + ParentContext: ctx, + TraceID: tid, + Name: name, + Kind: config.SpanKind(), + Attributes: config.Attributes(), + Links: config.Links(), + }) + + scc := trace.SpanContextConfig{ + TraceID: tid, + SpanID: sid, + TraceState: samplingResult.Tracestate, + } + if isSampled(samplingResult) { + scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled + } else { + scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled + } + sc := trace.NewSpanContext(scc) + + if !isRecording(samplingResult) { + return tr.newNonRecordingSpan(sc) + } + return tr.newRecordingSpan(psc, sc, name, samplingResult, config) +} + +// newRecordingSpan returns a new configured recordingSpan. +func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr SamplingResult, config *trace.SpanConfig) *recordingSpan { + startTime := config.Timestamp() + if startTime.IsZero() { + startTime = time.Now() + } + + s := &recordingSpan{ + // Do not pre-allocate the attributes slice here! Doing so will + // allocate memory that is likely never going to be used, or if used, + // will be over-sized. The default Go compiler has been tested to + // dynamically allocate needed space very well. Benchmarking has shown + // it to be more performant than what we can predetermine here, + // especially for the common use case of few to no added + // attributes. + + parent: psc, + spanContext: sc, + spanKind: trace.ValidateSpanKind(config.SpanKind()), + name: name, + startTime: startTime, + events: newEvictedQueue(tr.provider.spanLimits.EventCountLimit), + links: newEvictedQueue(tr.provider.spanLimits.LinkCountLimit), + tracer: tr, + } + + for _, l := range config.Links() { + s.addLink(l) + } + + s.SetAttributes(sr.Attributes...) + s.SetAttributes(config.Attributes()...) + + return s +} - return trace.ContextWithSpan(ctx, span), span +// newNonRecordingSpan returns a new configured nonRecordingSpan. +func (tr *tracer) newNonRecordingSpan(sc trace.SpanContext) nonRecordingSpan { + return nonRecordingSpan{tracer: tr, sc: sc} } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/version.go b/vendor/go.opentelemetry.io/otel/sdk/trace/version.go new file mode 100644 index 00000000000..d3457ed1355 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/version.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +// version is the current release version of the metric SDK in use. +func version() string { + return "1.16.0-rc.1" +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/version.go b/vendor/go.opentelemetry.io/otel/sdk/version.go new file mode 100644 index 00000000000..72d2cb09f7b --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/version.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sdk // import "go.opentelemetry.io/otel/sdk" + +// Version is the current release version of the OpenTelemetry SDK in use. +func Version() string { + return "1.19.0" +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/doc.go b/vendor/go.opentelemetry.io/otel/semconv/doc.go deleted file mode 100644 index 9a729fdecb1..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package semconv implements OpenTelemetry semantic conventions. -// -// This package is currently in a pre-GA phase. Backwards incompatible changes -// may be introduced in subsequent minor version releases as we work to track -// the evolving OpenTelemetry specification and user feedback. -// -// OpenTelemetry semantic conventions are agreed standardized naming -// patterns for OpenTelemetry things. This package aims to be the -// centralized place to interact with these conventions. -package semconv // import "go.opentelemetry.io/otel/semconv" diff --git a/vendor/go.opentelemetry.io/otel/semconv/exception.go b/vendor/go.opentelemetry.io/otel/semconv/exception.go deleted file mode 100644 index 97002611228..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/exception.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package semconv - -import "go.opentelemetry.io/otel/attribute" - -// Semantic conventions for exception attribute keys. -const ( - // The Go type containing the error or exception. - ExceptionTypeKey = attribute.Key("exception.type") - - // The exception message. - ExceptionMessageKey = attribute.Key("exception.message") - - // A stacktrace as a string. This most commonly will come from - // "runtime/debug".Stack. - ExceptionStacktraceKey = attribute.Key("exception.stacktrace") - - // If the exception event is recorded at a point where it is known - // that the exception is escaping the scope of the span this - // attribute is set to true. - ExceptionEscapedKey = attribute.Key("exception.escaped") -) - -const ( - // ExceptionEventName is the name of the Span event representing an exception. - ExceptionEventName = "exception" -) diff --git a/vendor/go.opentelemetry.io/otel/semconv/http.go b/vendor/go.opentelemetry.io/otel/semconv/http.go deleted file mode 100644 index d8160f92425..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/http.go +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package semconv // import "go.opentelemetry.io/otel/semconv" - -import ( - "fmt" - "net" - "net/http" - "strconv" - "strings" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" -) - -// NetAttributesFromHTTPRequest generates attributes of the net -// namespace as specified by the OpenTelemetry specification for a -// span. The network parameter is a string that net.Dial function -// from standard library can understand. -func NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue { - attrs := []attribute.KeyValue{} - - switch network { - case "tcp", "tcp4", "tcp6": - attrs = append(attrs, NetTransportTCP) - case "udp", "udp4", "udp6": - attrs = append(attrs, NetTransportUDP) - case "ip", "ip4", "ip6": - attrs = append(attrs, NetTransportIP) - case "unix", "unixgram", "unixpacket": - attrs = append(attrs, NetTransportUnix) - default: - attrs = append(attrs, NetTransportOther) - } - - peerName, peerIP, peerPort := "", "", 0 - { - hostPart := request.RemoteAddr - portPart := "" - if idx := strings.LastIndex(hostPart, ":"); idx >= 0 { - hostPart = request.RemoteAddr[:idx] - portPart = request.RemoteAddr[idx+1:] - } - if hostPart != "" { - if ip := net.ParseIP(hostPart); ip != nil { - peerIP = ip.String() - } else { - peerName = hostPart - } - - if portPart != "" { - numPort, err := strconv.ParseUint(portPart, 10, 16) - if err == nil { - peerPort = (int)(numPort) - } else { - peerName, peerIP = "", "" - } - } - } - } - if peerName != "" { - attrs = append(attrs, NetPeerNameKey.String(peerName)) - } - if peerIP != "" { - attrs = append(attrs, NetPeerIPKey.String(peerIP)) - } - if peerPort != 0 { - attrs = append(attrs, NetPeerPortKey.Int(peerPort)) - } - - hostIP, hostName, hostPort := "", "", 0 - for _, someHost := range []string{request.Host, request.Header.Get("Host"), request.URL.Host} { - hostPart := "" - if idx := strings.LastIndex(someHost, ":"); idx >= 0 { - strPort := someHost[idx+1:] - numPort, err := strconv.ParseUint(strPort, 10, 16) - if err == nil { - hostPort = (int)(numPort) - } - hostPart = someHost[:idx] - } else { - hostPart = someHost - } - if hostPart != "" { - ip := net.ParseIP(hostPart) - if ip != nil { - hostIP = ip.String() - } else { - hostName = hostPart - } - break - } else { - hostPort = 0 - } - } - if hostIP != "" { - attrs = append(attrs, NetHostIPKey.String(hostIP)) - } - if hostName != "" { - attrs = append(attrs, NetHostNameKey.String(hostName)) - } - if hostPort != 0 { - attrs = append(attrs, NetHostPortKey.Int(hostPort)) - } - - return attrs -} - -// EndUserAttributesFromHTTPRequest generates attributes of the -// enduser namespace as specified by the OpenTelemetry specification -// for a span. -func EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue { - if username, _, ok := request.BasicAuth(); ok { - return []attribute.KeyValue{EnduserIDKey.String(username)} - } - return nil -} - -// HTTPClientAttributesFromHTTPRequest generates attributes of the -// http namespace as specified by the OpenTelemetry specification for -// a span on the client side. -func HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue { - attrs := []attribute.KeyValue{} - - if request.Method != "" { - attrs = append(attrs, HTTPMethodKey.String(request.Method)) - } else { - attrs = append(attrs, HTTPMethodKey.String(http.MethodGet)) - } - - attrs = append(attrs, HTTPURLKey.String(request.URL.String())) - - return append(attrs, httpCommonAttributesFromHTTPRequest(request)...) -} - -func httpCommonAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue { - attrs := []attribute.KeyValue{} - if ua := request.UserAgent(); ua != "" { - attrs = append(attrs, HTTPUserAgentKey.String(ua)) - } - if request.ContentLength > 0 { - attrs = append(attrs, HTTPRequestContentLengthKey.Int64(request.ContentLength)) - } - - return append(attrs, httpBasicAttributesFromHTTPRequest(request)...) -} - -func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue { - // as these attributes are used by HTTPServerMetricAttributesFromHTTPRequest, they should be low-cardinality - attrs := []attribute.KeyValue{} - - if request.TLS != nil { - attrs = append(attrs, HTTPSchemeHTTPS) - } else { - attrs = append(attrs, HTTPSchemeHTTP) - } - - if request.Host != "" { - attrs = append(attrs, HTTPHostKey.String(request.Host)) - } - - flavor := "" - if request.ProtoMajor == 1 { - flavor = fmt.Sprintf("1.%d", request.ProtoMinor) - } else if request.ProtoMajor == 2 { - flavor = "2" - } - if flavor != "" { - attrs = append(attrs, HTTPFlavorKey.String(flavor)) - } - - return attrs -} - -// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes -// to be used with server-side HTTP metrics. -func HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue { - attrs := []attribute.KeyValue{} - if serverName != "" { - attrs = append(attrs, HTTPServerNameKey.String(serverName)) - } - return append(attrs, httpBasicAttributesFromHTTPRequest(request)...) -} - -// HTTPServerAttributesFromHTTPRequest generates attributes of the -// http namespace as specified by the OpenTelemetry specification for -// a span on the server side. Currently, only basic authentication is -// supported. -func HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue { - attrs := []attribute.KeyValue{ - HTTPMethodKey.String(request.Method), - HTTPTargetKey.String(request.RequestURI), - } - - if serverName != "" { - attrs = append(attrs, HTTPServerNameKey.String(serverName)) - } - if route != "" { - attrs = append(attrs, HTTPRouteKey.String(route)) - } - if values, ok := request.Header["X-Forwarded-For"]; ok && len(values) > 0 { - attrs = append(attrs, HTTPClientIPKey.String(values[0])) - } - - return append(attrs, httpCommonAttributesFromHTTPRequest(request)...) -} - -// HTTPAttributesFromHTTPStatusCode generates attributes of the http -// namespace as specified by the OpenTelemetry specification for a -// span. -func HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue { - attrs := []attribute.KeyValue{ - HTTPStatusCodeKey.Int(code), - } - return attrs -} - -type codeRange struct { - fromInclusive int - toInclusive int -} - -func (r codeRange) contains(code int) bool { - return r.fromInclusive <= code && code <= r.toInclusive -} - -var validRangesPerCategory = map[int][]codeRange{ - 1: { - {http.StatusContinue, http.StatusEarlyHints}, - }, - 2: { - {http.StatusOK, http.StatusAlreadyReported}, - {http.StatusIMUsed, http.StatusIMUsed}, - }, - 3: { - {http.StatusMultipleChoices, http.StatusUseProxy}, - {http.StatusTemporaryRedirect, http.StatusPermanentRedirect}, - }, - 4: { - {http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful… - {http.StatusMisdirectedRequest, http.StatusUpgradeRequired}, - {http.StatusPreconditionRequired, http.StatusTooManyRequests}, - {http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge}, - {http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons}, - }, - 5: { - {http.StatusInternalServerError, http.StatusLoopDetected}, - {http.StatusNotExtended, http.StatusNetworkAuthenticationRequired}, - }, -} - -// SpanStatusFromHTTPStatusCode generates a status code and a message -// as specified by the OpenTelemetry specification for a span. -func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) { - spanCode, valid := validateHTTPStatusCode(code) - if !valid { - return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code) - } - return spanCode, "" -} - -// Validates the HTTP status code and returns corresponding span status code. -// If the `code` is not a valid HTTP status code, returns span status Error -// and false. -func validateHTTPStatusCode(code int) (codes.Code, bool) { - category := code / 100 - ranges, ok := validRangesPerCategory[category] - if !ok { - return codes.Error, false - } - ok = false - for _, crange := range ranges { - ok = crange.contains(code) - if ok { - break - } - } - if !ok { - return codes.Error, false - } - if category > 0 && category < 4 { - return codes.Unset, true - } - return codes.Error, true -} diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go new file mode 100644 index 00000000000..12d6b520f52 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go @@ -0,0 +1,404 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/semconv/internal/v2" + +import ( + "fmt" + "net/http" + "strings" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" +) + +// HTTPConv are the HTTP semantic convention attributes defined for a version +// of the OpenTelemetry specification. +type HTTPConv struct { + NetConv *NetConv + + EnduserIDKey attribute.Key + HTTPClientIPKey attribute.Key + HTTPFlavorKey attribute.Key + HTTPMethodKey attribute.Key + HTTPRequestContentLengthKey attribute.Key + HTTPResponseContentLengthKey attribute.Key + HTTPRouteKey attribute.Key + HTTPSchemeHTTP attribute.KeyValue + HTTPSchemeHTTPS attribute.KeyValue + HTTPStatusCodeKey attribute.Key + HTTPTargetKey attribute.Key + HTTPURLKey attribute.Key + HTTPUserAgentKey attribute.Key +} + +// ClientResponse returns attributes for an HTTP response received by a client +// from a server. The following attributes are returned if the related values +// are defined in resp: "http.status.code", "http.response_content_length". +// +// This does not add all OpenTelemetry required attributes for an HTTP event, +// it assumes ClientRequest was used to create the span with a complete set of +// attributes. If a complete set of attributes can be generated using the +// request contained in resp. For example: +// +// append(ClientResponse(resp), ClientRequest(resp.Request)...) +func (c *HTTPConv) ClientResponse(resp *http.Response) []attribute.KeyValue { + var n int + if resp.StatusCode > 0 { + n++ + } + if resp.ContentLength > 0 { + n++ + } + + attrs := make([]attribute.KeyValue, 0, n) + if resp.StatusCode > 0 { + attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode)) + } + if resp.ContentLength > 0 { + attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength))) + } + return attrs +} + +// ClientRequest returns attributes for an HTTP request made by a client. The +// following attributes are always returned: "http.url", "http.flavor", +// "http.method", "net.peer.name". The following attributes are returned if the +// related values are defined in req: "net.peer.port", "http.user_agent", +// "http.request_content_length", "enduser.id". +func (c *HTTPConv) ClientRequest(req *http.Request) []attribute.KeyValue { + n := 3 // URL, peer name, proto, and method. + var h string + if req.URL != nil { + h = req.URL.Host + } + peer, p := firstHostPort(h, req.Header.Get("Host")) + port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p) + if port > 0 { + n++ + } + useragent := req.UserAgent() + if useragent != "" { + n++ + } + if req.ContentLength > 0 { + n++ + } + userID, _, hasUserID := req.BasicAuth() + if hasUserID { + n++ + } + attrs := make([]attribute.KeyValue, 0, n) + + attrs = append(attrs, c.method(req.Method)) + attrs = append(attrs, c.proto(req.Proto)) + + var u string + if req.URL != nil { + // Remove any username/password info that may be in the URL. + userinfo := req.URL.User + req.URL.User = nil + u = req.URL.String() + // Restore any username/password info that was removed. + req.URL.User = userinfo + } + attrs = append(attrs, c.HTTPURLKey.String(u)) + + attrs = append(attrs, c.NetConv.PeerName(peer)) + if port > 0 { + attrs = append(attrs, c.NetConv.PeerPort(port)) + } + + if useragent != "" { + attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) + } + + if l := req.ContentLength; l > 0 { + attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l)) + } + + if hasUserID { + attrs = append(attrs, c.EnduserIDKey.String(userID)) + } + + return attrs +} + +// ServerRequest returns attributes for an HTTP request received by a server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "http.target", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port", +// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", +// "http.client_ip". +func (c *HTTPConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue { + // TODO: This currently does not add the specification required + // `http.target` attribute. It has too high of a cardinality to safely be + // added. An alternate should be added, or this comment removed, when it is + // addressed by the specification. If it is ultimately decided to continue + // not including the attribute, the HTTPTargetKey field of the HTTPConv + // should be removed as well. + + n := 4 // Method, scheme, proto, and host name. + var host string + var p int + if server == "" { + host, p = splitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = splitHostPort(server) + if p < 0 { + _, p = splitHostPort(req.Host) + } + } + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + n++ + } + peer, peerPort := splitHostPort(req.RemoteAddr) + if peer != "" { + n++ + if peerPort > 0 { + n++ + } + } + useragent := req.UserAgent() + if useragent != "" { + n++ + } + userID, _, hasUserID := req.BasicAuth() + if hasUserID { + n++ + } + clientIP := serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP != "" { + n++ + } + attrs := make([]attribute.KeyValue, 0, n) + + attrs = append(attrs, c.method(req.Method)) + attrs = append(attrs, c.scheme(req.TLS != nil)) + attrs = append(attrs, c.proto(req.Proto)) + attrs = append(attrs, c.NetConv.HostName(host)) + + if hostPort > 0 { + attrs = append(attrs, c.NetConv.HostPort(hostPort)) + } + + if peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + attrs = append(attrs, c.NetConv.SockPeerAddr(peer)) + if peerPort > 0 { + attrs = append(attrs, c.NetConv.SockPeerPort(peerPort)) + } + } + + if useragent != "" { + attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) + } + + if hasUserID { + attrs = append(attrs, c.EnduserIDKey.String(userID)) + } + + if clientIP != "" { + attrs = append(attrs, c.HTTPClientIPKey.String(clientIP)) + } + + return attrs +} + +func (c *HTTPConv) method(method string) attribute.KeyValue { + if method == "" { + return c.HTTPMethodKey.String(http.MethodGet) + } + return c.HTTPMethodKey.String(method) +} + +func (c *HTTPConv) scheme(https bool) attribute.KeyValue { // nolint:revive + if https { + return c.HTTPSchemeHTTPS + } + return c.HTTPSchemeHTTP +} + +func (c *HTTPConv) proto(proto string) attribute.KeyValue { + switch proto { + case "HTTP/1.0": + return c.HTTPFlavorKey.String("1.0") + case "HTTP/1.1": + return c.HTTPFlavorKey.String("1.1") + case "HTTP/2": + return c.HTTPFlavorKey.String("2.0") + case "HTTP/3": + return c.HTTPFlavorKey.String("3.0") + default: + return c.HTTPFlavorKey.String(proto) + } +} + +func serverClientIP(xForwardedFor string) string { + if idx := strings.Index(xForwardedFor, ","); idx >= 0 { + xForwardedFor = xForwardedFor[:idx] + } + return xForwardedFor +} + +func requiredHTTPPort(https bool, port int) int { // nolint:revive + if https { + if port > 0 && port != 443 { + return port + } + } else { + if port > 0 && port != 80 { + return port + } + } + return -1 +} + +// Return the request host and port from the first non-empty source. +func firstHostPort(source ...string) (host string, port int) { + for _, hostport := range source { + host, port = splitHostPort(hostport) + if host != "" || port > 0 { + break + } + } + return +} + +// RequestHeader returns the contents of h as OpenTelemetry attributes. +func (c *HTTPConv) RequestHeader(h http.Header) []attribute.KeyValue { + return c.header("http.request.header", h) +} + +// ResponseHeader returns the contents of h as OpenTelemetry attributes. +func (c *HTTPConv) ResponseHeader(h http.Header) []attribute.KeyValue { + return c.header("http.response.header", h) +} + +func (c *HTTPConv) header(prefix string, h http.Header) []attribute.KeyValue { + key := func(k string) attribute.Key { + k = strings.ToLower(k) + k = strings.ReplaceAll(k, "-", "_") + k = fmt.Sprintf("%s.%s", prefix, k) + return attribute.Key(k) + } + + attrs := make([]attribute.KeyValue, 0, len(h)) + for k, v := range h { + attrs = append(attrs, key(k).StringSlice(v)) + } + return attrs +} + +// ClientStatus returns a span status code and message for an HTTP status code +// value received by a client. +func (c *HTTPConv) ClientStatus(code int) (codes.Code, string) { + stat, valid := validateHTTPStatusCode(code) + if !valid { + return stat, fmt.Sprintf("Invalid HTTP status code %d", code) + } + return stat, "" +} + +// ServerStatus returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func (c *HTTPConv) ServerStatus(code int) (codes.Code, string) { + stat, valid := validateHTTPStatusCode(code) + if !valid { + return stat, fmt.Sprintf("Invalid HTTP status code %d", code) + } + + if code/100 == 4 { + return codes.Unset, "" + } + return stat, "" +} + +type codeRange struct { + fromInclusive int + toInclusive int +} + +func (r codeRange) contains(code int) bool { + return r.fromInclusive <= code && code <= r.toInclusive +} + +var validRangesPerCategory = map[int][]codeRange{ + 1: { + {http.StatusContinue, http.StatusEarlyHints}, + }, + 2: { + {http.StatusOK, http.StatusAlreadyReported}, + {http.StatusIMUsed, http.StatusIMUsed}, + }, + 3: { + {http.StatusMultipleChoices, http.StatusUseProxy}, + {http.StatusTemporaryRedirect, http.StatusPermanentRedirect}, + }, + 4: { + {http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful… + {http.StatusMisdirectedRequest, http.StatusUpgradeRequired}, + {http.StatusPreconditionRequired, http.StatusTooManyRequests}, + {http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge}, + {http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons}, + }, + 5: { + {http.StatusInternalServerError, http.StatusLoopDetected}, + {http.StatusNotExtended, http.StatusNetworkAuthenticationRequired}, + }, +} + +// validateHTTPStatusCode validates the HTTP status code and returns +// corresponding span status code. If the `code` is not a valid HTTP status +// code, returns span status Error and false. +func validateHTTPStatusCode(code int) (codes.Code, bool) { + category := code / 100 + ranges, ok := validRangesPerCategory[category] + if !ok { + return codes.Error, false + } + ok = false + for _, crange := range ranges { + ok = crange.contains(code) + if ok { + break + } + } + if !ok { + return codes.Error, false + } + if category > 0 && category < 4 { + return codes.Unset, true + } + return codes.Error, true +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go new file mode 100644 index 00000000000..4a711133a02 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go @@ -0,0 +1,324 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal // import "go.opentelemetry.io/otel/semconv/internal/v2" + +import ( + "net" + "strconv" + "strings" + + "go.opentelemetry.io/otel/attribute" +) + +// NetConv are the network semantic convention attributes defined for a version +// of the OpenTelemetry specification. +type NetConv struct { + NetHostNameKey attribute.Key + NetHostPortKey attribute.Key + NetPeerNameKey attribute.Key + NetPeerPortKey attribute.Key + NetSockFamilyKey attribute.Key + NetSockPeerAddrKey attribute.Key + NetSockPeerPortKey attribute.Key + NetSockHostAddrKey attribute.Key + NetSockHostPortKey attribute.Key + NetTransportOther attribute.KeyValue + NetTransportTCP attribute.KeyValue + NetTransportUDP attribute.KeyValue + NetTransportInProc attribute.KeyValue +} + +func (c *NetConv) Transport(network string) attribute.KeyValue { + switch network { + case "tcp", "tcp4", "tcp6": + return c.NetTransportTCP + case "udp", "udp4", "udp6": + return c.NetTransportUDP + case "unix", "unixgram", "unixpacket": + return c.NetTransportInProc + default: + // "ip:*", "ip4:*", and "ip6:*" all are considered other. + return c.NetTransportOther + } +} + +// Host returns attributes for a network host address. +func (c *NetConv) Host(address string) []attribute.KeyValue { + h, p := splitHostPort(address) + var n int + if h != "" { + n++ + if p > 0 { + n++ + } + } + + if n == 0 { + return nil + } + + attrs := make([]attribute.KeyValue, 0, n) + attrs = append(attrs, c.HostName(h)) + if p > 0 { + attrs = append(attrs, c.HostPort(int(p))) + } + return attrs +} + +// Server returns attributes for a network listener listening at address. See +// net.Listen for information about acceptable address values, address should +// be the same as the one used to create ln. If ln is nil, only network host +// attributes will be returned that describe address. Otherwise, the socket +// level information about ln will also be included. +func (c *NetConv) Server(address string, ln net.Listener) []attribute.KeyValue { + if ln == nil { + return c.Host(address) + } + + lAddr := ln.Addr() + if lAddr == nil { + return c.Host(address) + } + + hostName, hostPort := splitHostPort(address) + sockHostAddr, sockHostPort := splitHostPort(lAddr.String()) + network := lAddr.Network() + sockFamily := family(network, sockHostAddr) + + n := nonZeroStr(hostName, network, sockHostAddr, sockFamily) + n += positiveInt(hostPort, sockHostPort) + attr := make([]attribute.KeyValue, 0, n) + if hostName != "" { + attr = append(attr, c.HostName(hostName)) + if hostPort > 0 { + // Only if net.host.name is set should net.host.port be. + attr = append(attr, c.HostPort(hostPort)) + } + } + if network != "" { + attr = append(attr, c.Transport(network)) + } + if sockFamily != "" { + attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) + } + if sockHostAddr != "" { + attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) + if sockHostPort > 0 { + // Only if net.sock.host.addr is set should net.sock.host.port be. + attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) + } + } + return attr +} + +func (c *NetConv) HostName(name string) attribute.KeyValue { + return c.NetHostNameKey.String(name) +} + +func (c *NetConv) HostPort(port int) attribute.KeyValue { + return c.NetHostPortKey.Int(port) +} + +// Client returns attributes for a client network connection to address. See +// net.Dial for information about acceptable address values, address should be +// the same as the one used to create conn. If conn is nil, only network peer +// attributes will be returned that describe address. Otherwise, the socket +// level information about conn will also be included. +func (c *NetConv) Client(address string, conn net.Conn) []attribute.KeyValue { + if conn == nil { + return c.Peer(address) + } + + lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr() + + var network string + switch { + case lAddr != nil: + network = lAddr.Network() + case rAddr != nil: + network = rAddr.Network() + default: + return c.Peer(address) + } + + peerName, peerPort := splitHostPort(address) + var ( + sockFamily string + sockPeerAddr string + sockPeerPort int + sockHostAddr string + sockHostPort int + ) + + if lAddr != nil { + sockHostAddr, sockHostPort = splitHostPort(lAddr.String()) + } + + if rAddr != nil { + sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String()) + } + + switch { + case sockHostAddr != "": + sockFamily = family(network, sockHostAddr) + case sockPeerAddr != "": + sockFamily = family(network, sockPeerAddr) + } + + n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily) + n += positiveInt(peerPort, sockPeerPort, sockHostPort) + attr := make([]attribute.KeyValue, 0, n) + if peerName != "" { + attr = append(attr, c.PeerName(peerName)) + if peerPort > 0 { + // Only if net.peer.name is set should net.peer.port be. + attr = append(attr, c.PeerPort(peerPort)) + } + } + if network != "" { + attr = append(attr, c.Transport(network)) + } + if sockFamily != "" { + attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) + } + if sockPeerAddr != "" { + attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr)) + if sockPeerPort > 0 { + // Only if net.sock.peer.addr is set should net.sock.peer.port be. + attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort)) + } + } + if sockHostAddr != "" { + attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) + if sockHostPort > 0 { + // Only if net.sock.host.addr is set should net.sock.host.port be. + attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) + } + } + return attr +} + +func family(network, address string) string { + switch network { + case "unix", "unixgram", "unixpacket": + return "unix" + default: + if ip := net.ParseIP(address); ip != nil { + if ip.To4() == nil { + return "inet6" + } + return "inet" + } + } + return "" +} + +func nonZeroStr(strs ...string) int { + var n int + for _, str := range strs { + if str != "" { + n++ + } + } + return n +} + +func positiveInt(ints ...int) int { + var n int + for _, i := range ints { + if i > 0 { + n++ + } + } + return n +} + +// Peer returns attributes for a network peer address. +func (c *NetConv) Peer(address string) []attribute.KeyValue { + h, p := splitHostPort(address) + var n int + if h != "" { + n++ + if p > 0 { + n++ + } + } + + if n == 0 { + return nil + } + + attrs := make([]attribute.KeyValue, 0, n) + attrs = append(attrs, c.PeerName(h)) + if p > 0 { + attrs = append(attrs, c.PeerPort(int(p))) + } + return attrs +} + +func (c *NetConv) PeerName(name string) attribute.KeyValue { + return c.NetPeerNameKey.String(name) +} + +func (c *NetConv) PeerPort(port int) attribute.KeyValue { + return c.NetPeerPortKey.Int(port) +} + +func (c *NetConv) SockPeerAddr(addr string) attribute.KeyValue { + return c.NetSockPeerAddrKey.String(addr) +} + +func (c *NetConv) SockPeerPort(port int) attribute.KeyValue { + return c.NetSockPeerPortKey.Int(port) +} + +// splitHostPort splits a network address hostport of the form "host", +// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port", +// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and +// port. +// +// An empty host is returned if it is not provided or unparsable. A negative +// port is returned if it is not provided or unparsable. +func splitHostPort(hostport string) (host string, port int) { + port = -1 + + if strings.HasPrefix(hostport, "[") { + addrEnd := strings.LastIndex(hostport, "]") + if addrEnd < 0 { + // Invalid hostport. + return + } + if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 { + host = hostport[1:addrEnd] + return + } + } else { + if i := strings.LastIndex(hostport, ":"); i < 0 { + host = hostport + return + } + } + + host, pStr, err := net.SplitHostPort(hostport) + if err != nil { + return + } + + p, err := strconv.ParseUint(pStr, 10, 16) + if err != nil { + return + } + return host, int(p) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/resource.go b/vendor/go.opentelemetry.io/otel/semconv/resource.go deleted file mode 100644 index 69a9b5a6f33..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/resource.go +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package semconv // import "go.opentelemetry.io/otel/semconv" - -import "go.opentelemetry.io/otel/attribute" - -// Semantic conventions for service resource attribute keys. -const ( - // Name of the service. - ServiceNameKey = attribute.Key("service.name") - - // A namespace for `service.name`. This needs to have meaning that helps - // to distinguish a group of services. For example, the team name that - // owns a group of services. `service.name` is expected to be unique - // within the same namespace. - ServiceNamespaceKey = attribute.Key("service.namespace") - - // A unique identifier of the service instance. In conjunction with the - // `service.name` and `service.namespace` this must be unique. - ServiceInstanceIDKey = attribute.Key("service.instance.id") - - // The version of the service API. - ServiceVersionKey = attribute.Key("service.version") -) - -// Semantic conventions for telemetry SDK resource attribute keys. -const ( - // The name of the telemetry SDK. - // - // The default OpenTelemetry SDK provided by the OpenTelemetry project - // MUST set telemetry.sdk.name to the value `opentelemetry`. - // - // If another SDK is used, this attribute MUST be set to the import path - // of that SDK's package. - // - // The value `opentelemetry` is reserved and MUST NOT be used by - // non-OpenTelemetry SDKs. - TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") - - // The language of the telemetry SDK. - TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") - - // The version string of the telemetry SDK. - TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") -) - -// Semantic conventions for telemetry SDK resource attributes. -var ( - TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go") -) - -// Semantic conventions for container resource attribute keys. -const ( - // A uniquely identifying name for the Container. - ContainerNameKey = attribute.Key("container.name") - - // Container ID, usually a UUID, as for example used to - // identify Docker containers. The UUID might be abbreviated. - ContainerIDKey = attribute.Key("container.id") - - // Name of the image the container was built on. - ContainerImageNameKey = attribute.Key("container.image.name") - - // Container image tag. - ContainerImageTagKey = attribute.Key("container.image.tag") -) - -// Semantic conventions for Function-as-a-Service resource attribute keys. -const ( - // A uniquely identifying name for the FaaS. - FaaSNameKey = attribute.Key("faas.name") - - // The unique name of the function being executed. - FaaSIDKey = attribute.Key("faas.id") - - // The version of the function being executed. - FaaSVersionKey = attribute.Key("faas.version") - - // The execution environment identifier. - FaaSInstanceKey = attribute.Key("faas.instance") -) - -// Semantic conventions for operating system process resource attribute keys. -const ( - // Process identifier (PID). - ProcessPIDKey = attribute.Key("process.pid") - // The name of the process executable. On Linux based systems, can be - // set to the `Name` in `proc/[pid]/status`. On Windows, can be set to - // the base name of `GetProcessImageFileNameW`. - ProcessExecutableNameKey = attribute.Key("process.executable.name") - // The full path to the process executable. On Linux based systems, can - // be set to the target of `proc/[pid]/exe`. On Windows, can be set to - // the result of `GetProcessImageFileNameW`. - ProcessExecutablePathKey = attribute.Key("process.executable.path") - // The command used to launch the process (i.e. the command name). On - // Linux based systems, can be set to the zeroth string in - // `proc/[pid]/cmdline`. On Windows, can be set to the first parameter - // extracted from `GetCommandLineW`. - ProcessCommandKey = attribute.Key("process.command") - // The full command used to launch the process. The value can be either - // a list of strings representing the ordered list of arguments, or a - // single string representing the full command. On Linux based systems, - // can be set to the list of null-delimited strings extracted from - // `proc/[pid]/cmdline`. On Windows, can be set to the result of - // `GetCommandLineW`. - ProcessCommandLineKey = attribute.Key("process.command_line") - // All the command arguments (including the command/executable itself) - // as received by the process. On Linux-based systems (and some other - // Unixoid systems supporting procfs), can be set according to the list - // of null-delimited strings extracted from `proc/[pid]/cmdline`. For - // libc-based executables, this would be the full argv vector passed to - // `main`. - ProcessCommandArgsKey = attribute.Key("process.command_args") - // The username of the user that owns the process. - ProcessOwnerKey = attribute.Key("process.owner") - // The name of the runtime of this process. For compiled native - // binaries, this SHOULD be the name of the compiler. - ProcessRuntimeNameKey = attribute.Key("process.runtime.name") - // The version of the runtime of this process, as returned by the - // runtime without modification. - ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") - // An additional description about the runtime of the process, for - // example a specific vendor customization of the runtime environment. - ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") -) - -// Semantic conventions for Kubernetes resource attribute keys. -const ( - // A uniquely identifying name for the Kubernetes cluster. Kubernetes - // does not have cluster names as an internal concept so this may be - // set to any meaningful value within the environment. For example, - // GKE clusters have a name which can be used for this attribute. - K8SClusterNameKey = attribute.Key("k8s.cluster.name") - - // The name of the Node. - K8SNodeNameKey = attribute.Key("k8s.node.name") - - // The UID of the Node. - K8SNodeUIDKey = attribute.Key("k8s.node.uid") - - // The name of the namespace that the pod is running in. - K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") - - // The uid of the Pod. - K8SPodUIDKey = attribute.Key("k8s.pod.uid") - - // The name of the pod. - K8SPodNameKey = attribute.Key("k8s.pod.name") - - // The name of the Container in a Pod template. - K8SContainerNameKey = attribute.Key("k8s.container.name") - - // The uid of the ReplicaSet. - K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") - - // The name of the ReplicaSet. - K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") - - // The uid of the Deployment. - K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") - - // The name of the deployment. - K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") - - // The uid of the StatefulSet. - K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") - - // The name of the StatefulSet. - K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") - - // The uid of the DaemonSet. - K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") - - // The name of the DaemonSet. - K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") - - // The uid of the Job. - K8SJobUIDKey = attribute.Key("k8s.job.uid") - - // The name of the Job. - K8SJobNameKey = attribute.Key("k8s.job.name") - - // The uid of the CronJob. - K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") - - // The name of the CronJob. - K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") -) - -// Semantic conventions for OS resource attribute keys. -const ( - // The operating system type. - OSTypeKey = attribute.Key("os.type") - // Human readable (not intended to be parsed) OS version information. - OSDescriptionKey = attribute.Key("os.description") -) - -// Semantic conventions for host resource attribute keys. -const ( - // A uniquely identifying name for the host: 'hostname', FQDN, or user specified name - HostNameKey = attribute.Key("host.name") - - // Unique host ID. For cloud environments this will be the instance ID. - HostIDKey = attribute.Key("host.id") - - // Type of host. For cloud environments this will be the machine type. - HostTypeKey = attribute.Key("host.type") - - // Name of the OS or VM image the host is running. - HostImageNameKey = attribute.Key("host.image.name") - - // Identifier of the image the host is running. - HostImageIDKey = attribute.Key("host.image.id") - - // Version of the image the host is running. - HostImageVersionKey = attribute.Key("host.image.version") -) - -// Semantic conventions for cloud environment resource attribute keys. -const ( - // Name of the cloud provider. - CloudProviderKey = attribute.Key("cloud.provider") - - // The account ID from the cloud provider used for authorization. - CloudAccountIDKey = attribute.Key("cloud.account.id") - - // Geographical region where this resource is. - CloudRegionKey = attribute.Key("cloud.region") - - // Zone of the region where this resource is. - CloudZoneKey = attribute.Key("cloud.zone") -) - -// Semantic conventions for common cloud provider resource attributes. -var ( - CloudProviderAWS = CloudProviderKey.String("aws") - CloudProviderAzure = CloudProviderKey.String("azure") - CloudProviderGCP = CloudProviderKey.String("gcp") -) - -// Semantic conventions for deployment attributes. -const ( - // Name of the deployment environment (aka deployment tier); e.g. (staging, production). - DeploymentEnvironmentKey = attribute.Key("deployment.environment") -) diff --git a/vendor/go.opentelemetry.io/otel/semconv/trace.go b/vendor/go.opentelemetry.io/otel/semconv/trace.go deleted file mode 100644 index 145fc607689..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/trace.go +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package semconv // import "go.opentelemetry.io/otel/semconv" - -import "go.opentelemetry.io/otel/attribute" - -// Semantic conventions for attribute keys used for network related -// operations. -const ( - // Transport protocol used. - NetTransportKey = attribute.Key("net.transport") - - // Remote address of the peer. - NetPeerIPKey = attribute.Key("net.peer.ip") - - // Remote port number. - NetPeerPortKey = attribute.Key("net.peer.port") - - // Remote hostname or similar. - NetPeerNameKey = attribute.Key("net.peer.name") - - // Local host IP. Useful in case of a multi-IP host. - NetHostIPKey = attribute.Key("net.host.ip") - - // Local host port. - NetHostPortKey = attribute.Key("net.host.port") - - // Local hostname or similar. - NetHostNameKey = attribute.Key("net.host.name") -) - -// Semantic conventions for common transport protocol attributes. -var ( - NetTransportTCP = NetTransportKey.String("IP.TCP") - NetTransportUDP = NetTransportKey.String("IP.UDP") - NetTransportIP = NetTransportKey.String("IP") - NetTransportUnix = NetTransportKey.String("Unix") - NetTransportPipe = NetTransportKey.String("pipe") - NetTransportInProc = NetTransportKey.String("inproc") - NetTransportOther = NetTransportKey.String("other") -) - -// General attribute keys for spans. -const ( - // Service name of the remote service. Should equal the actual - // `service.name` resource attribute of the remote service, if any. - PeerServiceKey = attribute.Key("peer.service") -) - -// Semantic conventions for attribute keys used to identify an authorized -// user. -const ( - // Username or the client identifier extracted from the access token or - // authorization header in the inbound request from outside the system. - EnduserIDKey = attribute.Key("enduser.id") - - // Actual or assumed role the client is making the request with. - EnduserRoleKey = attribute.Key("enduser.role") - - // Scopes or granted authorities the client currently possesses. - EnduserScopeKey = attribute.Key("enduser.scope") -) - -// Semantic conventions for attribute keys for HTTP. -const ( - // HTTP request method. - HTTPMethodKey = attribute.Key("http.method") - - // Full HTTP request URL in the form: - // scheme://host[:port]/path?query[#fragment]. - HTTPURLKey = attribute.Key("http.url") - - // The full request target as passed in a HTTP request line or - // equivalent, e.g. "/path/12314/?q=ddds#123". - HTTPTargetKey = attribute.Key("http.target") - - // The value of the HTTP host header. - HTTPHostKey = attribute.Key("http.host") - - // The URI scheme identifying the used protocol. - HTTPSchemeKey = attribute.Key("http.scheme") - - // HTTP response status code. - HTTPStatusCodeKey = attribute.Key("http.status_code") - - // Kind of HTTP protocol used. - HTTPFlavorKey = attribute.Key("http.flavor") - - // Value of the HTTP User-Agent header sent by the client. - HTTPUserAgentKey = attribute.Key("http.user_agent") - - // The primary server name of the matched virtual host. - HTTPServerNameKey = attribute.Key("http.server_name") - - // The matched route served (path template). For example, - // "/users/:userID?". - HTTPRouteKey = attribute.Key("http.route") - - // The IP address of the original client behind all proxies, if known - // (e.g. from X-Forwarded-For). - HTTPClientIPKey = attribute.Key("http.client_ip") - - // The size of the request payload body in bytes. - HTTPRequestContentLengthKey = attribute.Key("http.request_content_length") - - // The size of the uncompressed request payload body after transport decoding. - // Not set if transport encoding not used. - HTTPRequestContentLengthUncompressedKey = attribute.Key("http.request_content_length_uncompressed") - - // The size of the response payload body in bytes. - HTTPResponseContentLengthKey = attribute.Key("http.response_content_length") - - // The size of the uncompressed response payload body after transport decoding. - // Not set if transport encoding not used. - HTTPResponseContentLengthUncompressedKey = attribute.Key("http.response_content_length_uncompressed") -) - -// Semantic conventions for common HTTP attributes. -var ( - // Semantic conventions for HTTP(S) URI schemes. - HTTPSchemeHTTP = HTTPSchemeKey.String("http") - HTTPSchemeHTTPS = HTTPSchemeKey.String("https") - - // Semantic conventions for HTTP protocols. - HTTPFlavor1_0 = HTTPFlavorKey.String("1.0") - HTTPFlavor1_1 = HTTPFlavorKey.String("1.1") - HTTPFlavor2 = HTTPFlavorKey.String("2") - HTTPFlavorSPDY = HTTPFlavorKey.String("SPDY") - HTTPFlavorQUIC = HTTPFlavorKey.String("QUIC") -) - -// Semantic conventions for attribute keys for database connections. -const ( - // Identifier for the database system (DBMS) being used. - DBSystemKey = attribute.Key("db.system") - - // Database Connection String with embedded credentials removed. - DBConnectionStringKey = attribute.Key("db.connection_string") - - // Username for accessing database. - DBUserKey = attribute.Key("db.user") -) - -// Semantic conventions for common database system attributes. -var ( - DBSystemDB2 = DBSystemKey.String("db2") // IBM DB2 - DBSystemDerby = DBSystemKey.String("derby") // Apache Derby - DBSystemHive = DBSystemKey.String("hive") // Apache Hive - DBSystemMariaDB = DBSystemKey.String("mariadb") // MariaDB - DBSystemMSSql = DBSystemKey.String("mssql") // Microsoft SQL Server - DBSystemMySQL = DBSystemKey.String("mysql") // MySQL - DBSystemOracle = DBSystemKey.String("oracle") // Oracle Database - DBSystemPostgres = DBSystemKey.String("postgresql") // PostgreSQL - DBSystemSqlite = DBSystemKey.String("sqlite") // SQLite - DBSystemTeradata = DBSystemKey.String("teradata") // Teradata - DBSystemOtherSQL = DBSystemKey.String("other_sql") // Some other Sql database. Fallback only - DBSystemCassandra = DBSystemKey.String("cassandra") // Cassandra - DBSystemCosmosDB = DBSystemKey.String("cosmosdb") // Microsoft Azure CosmosDB - DBSystemCouchbase = DBSystemKey.String("couchbase") // Couchbase - DBSystemCouchDB = DBSystemKey.String("couchdb") // CouchDB - DBSystemDynamoDB = DBSystemKey.String("dynamodb") // Amazon DynamoDB - DBSystemHBase = DBSystemKey.String("hbase") // HBase - DBSystemMongodb = DBSystemKey.String("mongodb") // MongoDB - DBSystemNeo4j = DBSystemKey.String("neo4j") // Neo4j - DBSystemRedis = DBSystemKey.String("redis") // Redis -) - -// Semantic conventions for attribute keys for database calls. -const ( - // Database instance name. - DBNameKey = attribute.Key("db.name") - - // A database statement for the given database type. - DBStatementKey = attribute.Key("db.statement") - - // A database operation for the given database type. - DBOperationKey = attribute.Key("db.operation") -) - -// Database technology-specific attributes -const ( - // Name of the Cassandra keyspace accessed. Use instead of `db.name`. - DBCassandraKeyspaceKey = attribute.Key("db.cassandra.keyspace") - - // HBase namespace accessed. Use instead of `db.name`. - DBHBaseNamespaceKey = attribute.Key("db.hbase.namespace") - - // Index of Redis database accessed. Use instead of `db.name`. - DBRedisDBIndexKey = attribute.Key("db.redis.database_index") - - // Collection being accessed within the database in `db.name`. - DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection") -) - -// Semantic conventions for attribute keys for RPC. -const ( - // A string identifying the remoting system. - RPCSystemKey = attribute.Key("rpc.system") - - // The full name of the service being called. - RPCServiceKey = attribute.Key("rpc.service") - - // The name of the method being called. - RPCMethodKey = attribute.Key("rpc.method") - - // Name of message transmitted or received. - RPCNameKey = attribute.Key("name") - - // Type of message transmitted or received. - RPCMessageTypeKey = attribute.Key("message.type") - - // Identifier of message transmitted or received. - RPCMessageIDKey = attribute.Key("message.id") - - // The compressed size of the message transmitted or received in bytes. - RPCMessageCompressedSizeKey = attribute.Key("message.compressed_size") - - // The uncompressed size of the message transmitted or received in - // bytes. - RPCMessageUncompressedSizeKey = attribute.Key("message.uncompressed_size") -) - -// Semantic conventions for common RPC attributes. -var ( - // Semantic convention for gRPC as the remoting system. - RPCSystemGRPC = RPCSystemKey.String("grpc") - - // Semantic convention for a message named message. - RPCNameMessage = RPCNameKey.String("message") - - // Semantic conventions for RPC message types. - RPCMessageTypeSent = RPCMessageTypeKey.String("SENT") - RPCMessageTypeReceived = RPCMessageTypeKey.String("RECEIVED") -) - -// Semantic conventions for attribute keys for messaging systems. -const ( - // A unique identifier describing the messaging system. For example, - // kafka, rabbitmq or activemq. - MessagingSystemKey = attribute.Key("messaging.system") - - // The message destination name, e.g. MyQueue or MyTopic. - MessagingDestinationKey = attribute.Key("messaging.destination") - - // The kind of message destination. - MessagingDestinationKindKey = attribute.Key("messaging.destination_kind") - - // Describes if the destination is temporary or not. - MessagingTempDestinationKey = attribute.Key("messaging.temp_destination") - - // The name of the transport protocol. - MessagingProtocolKey = attribute.Key("messaging.protocol") - - // The version of the transport protocol. - MessagingProtocolVersionKey = attribute.Key("messaging.protocol_version") - - // Messaging service URL. - MessagingURLKey = attribute.Key("messaging.url") - - // Identifier used by the messaging system for a message. - MessagingMessageIDKey = attribute.Key("messaging.message_id") - - // Identifier used by the messaging system for a conversation. - MessagingConversationIDKey = attribute.Key("messaging.conversation_id") - - // The (uncompressed) size of the message payload in bytes. - MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message_payload_size_bytes") - - // The compressed size of the message payload in bytes. - MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message_payload_compressed_size_bytes") - - // Identifies which part and kind of message consumption is being - // preformed. - MessagingOperationKey = attribute.Key("messaging.operation") - - // RabbitMQ specific attribute describing the destination routing key. - MessagingRabbitMQRoutingKeyKey = attribute.Key("messaging.rabbitmq.routing_key") -) - -// Semantic conventions for common messaging system attributes. -var ( - // Semantic conventions for message destinations. - MessagingDestinationKindKeyQueue = MessagingDestinationKindKey.String("queue") - MessagingDestinationKindKeyTopic = MessagingDestinationKindKey.String("topic") - - // Semantic convention for message destinations that are temporary. - MessagingTempDestination = MessagingTempDestinationKey.Bool(true) - - // Semantic convention for the operation parts of message consumption. - // This does not include a "send" attribute as that is explicitly not - // allowed in the OpenTelemetry specification. - MessagingOperationReceive = MessagingOperationKey.String("receive") - MessagingOperationProcess = MessagingOperationKey.String("process") -) - -// Semantic conventions for attribute keys for FaaS systems. -const ( - - // Type of the trigger on which the function is executed. - FaaSTriggerKey = attribute.Key("faas.trigger") - - // String containing the execution identifier of the function. - FaaSExecutionKey = attribute.Key("faas.execution") - - // A boolean indicating that the serverless function is executed - // for the first time (aka cold start). - FaaSColdstartKey = attribute.Key("faas.coldstart") - - // The name of the source on which the operation was performed. - // For example, in Cloud Storage or S3 corresponds to the bucket name, - // and in Cosmos DB to the database name. - FaaSDocumentCollectionKey = attribute.Key("faas.document.collection") - - // The type of the operation that was performed on the data. - FaaSDocumentOperationKey = attribute.Key("faas.document.operation") - - // A string containing the time when the data was accessed. - FaaSDocumentTimeKey = attribute.Key("faas.document.time") - - // The document name/table subjected to the operation. - FaaSDocumentNameKey = attribute.Key("faas.document.name") - - // The function invocation time. - FaaSTimeKey = attribute.Key("faas.time") - - // The schedule period as Cron Expression. - FaaSCronKey = attribute.Key("faas.cron") -) - -// Semantic conventions for common FaaS system attributes. -var ( - // Semantic conventions for the types of triggers. - FaasTriggerDatasource = FaaSTriggerKey.String("datasource") - FaasTriggerHTTP = FaaSTriggerKey.String("http") - FaasTriggerPubSub = FaaSTriggerKey.String("pubsub") - FaasTriggerTimer = FaaSTriggerKey.String("timer") - FaasTriggerOther = FaaSTriggerKey.String("other") - - // Semantic conventions for the types of operations performed. - FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert") - FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit") - FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete") -) - -// Semantic conventions for source code attributes. -const ( - // The method or function name, or equivalent (usually rightmost part of - // the code unit's name). - CodeFunctionKey = attribute.Key("code.function") - - // The "namespace" within which `code.function` is defined. Usually the - // qualified class or module name, such that - // `code.namespace` + some separator + `code.function` form a unique - // identifier for the code unit. - CodeNamespaceKey = attribute.Key("code.namespace") - - // The source code file name that identifies the code unit as uniquely as - // possible (preferably an absolute file path). - CodeFilepathKey = attribute.Key("code.filepath") - - // The line number in `code.filepath` best representing the operation. - // It SHOULD point within the code unit named in `code.function`. - CodeLineNumberKey = attribute.Key("code.lineno") -) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go new file mode 100644 index 00000000000..71a1f7748d5 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package semconv implements OpenTelemetry semantic conventions. +// +// OpenTelemetry semantic conventions are agreed standardized naming +// patterns for OpenTelemetry things. This package represents the conventions +// as of the v1.17.0 version of the OpenTelemetry specification. +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go new file mode 100644 index 00000000000..679c40c4de4 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go @@ -0,0 +1,199 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +import "go.opentelemetry.io/otel/attribute" + +// This semantic convention defines the attributes used to represent a feature +// flag evaluation as an event. +const ( + // FeatureFlagKeyKey is the attribute Key conforming to the + // "feature_flag.key" semantic conventions. It represents the unique + // identifier of the feature flag. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'logo-color' + FeatureFlagKeyKey = attribute.Key("feature_flag.key") + + // FeatureFlagProviderNameKey is the attribute Key conforming to the + // "feature_flag.provider_name" semantic conventions. It represents the + // name of the service provider that performs the flag evaluation. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'Flag Manager' + FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider_name") + + // FeatureFlagVariantKey is the attribute Key conforming to the + // "feature_flag.variant" semantic conventions. It represents the sHOULD be + // a semantic identifier for a value. If one is unavailable, a stringified + // version of the value can be used. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'red', 'true', 'on' + // Note: A semantic identifier, commonly referred to as a variant, provides + // a means + // for referring to a value without including the value itself. This can + // provide additional context for understanding the meaning behind a value. + // For example, the variant `red` maybe be used for the value `#c05543`. + // + // A stringified version of the value can be used in situations where a + // semantic identifier is unavailable. String representation of the value + // should be determined by the implementer. + FeatureFlagVariantKey = attribute.Key("feature_flag.variant") +) + +// FeatureFlagKey returns an attribute KeyValue conforming to the +// "feature_flag.key" semantic conventions. It represents the unique identifier +// of the feature flag. +func FeatureFlagKey(val string) attribute.KeyValue { + return FeatureFlagKeyKey.String(val) +} + +// FeatureFlagProviderName returns an attribute KeyValue conforming to the +// "feature_flag.provider_name" semantic conventions. It represents the name of +// the service provider that performs the flag evaluation. +func FeatureFlagProviderName(val string) attribute.KeyValue { + return FeatureFlagProviderNameKey.String(val) +} + +// FeatureFlagVariant returns an attribute KeyValue conforming to the +// "feature_flag.variant" semantic conventions. It represents the sHOULD be a +// semantic identifier for a value. If one is unavailable, a stringified +// version of the value can be used. +func FeatureFlagVariant(val string) attribute.KeyValue { + return FeatureFlagVariantKey.String(val) +} + +// RPC received/sent message. +const ( + // MessageTypeKey is the attribute Key conforming to the "message.type" + // semantic conventions. It represents the whether this is a received or + // sent message. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessageTypeKey = attribute.Key("message.type") + + // MessageIDKey is the attribute Key conforming to the "message.id" + // semantic conventions. It represents the mUST be calculated as two + // different counters starting from `1` one for sent messages and one for + // received message. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Note: This way we guarantee that the values will be consistent between + // different implementations. + MessageIDKey = attribute.Key("message.id") + + // MessageCompressedSizeKey is the attribute Key conforming to the + // "message.compressed_size" semantic conventions. It represents the + // compressed size of the message in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + MessageCompressedSizeKey = attribute.Key("message.compressed_size") + + // MessageUncompressedSizeKey is the attribute Key conforming to the + // "message.uncompressed_size" semantic conventions. It represents the + // uncompressed size of the message in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + MessageUncompressedSizeKey = attribute.Key("message.uncompressed_size") +) + +var ( + // sent + MessageTypeSent = MessageTypeKey.String("SENT") + // received + MessageTypeReceived = MessageTypeKey.String("RECEIVED") +) + +// MessageID returns an attribute KeyValue conforming to the "message.id" +// semantic conventions. It represents the mUST be calculated as two different +// counters starting from `1` one for sent messages and one for received +// message. +func MessageID(val int) attribute.KeyValue { + return MessageIDKey.Int(val) +} + +// MessageCompressedSize returns an attribute KeyValue conforming to the +// "message.compressed_size" semantic conventions. It represents the compressed +// size of the message in bytes. +func MessageCompressedSize(val int) attribute.KeyValue { + return MessageCompressedSizeKey.Int(val) +} + +// MessageUncompressedSize returns an attribute KeyValue conforming to the +// "message.uncompressed_size" semantic conventions. It represents the +// uncompressed size of the message in bytes. +func MessageUncompressedSize(val int) attribute.KeyValue { + return MessageUncompressedSizeKey.Int(val) +} + +// The attributes used to report a single exception associated with a span. +const ( + // ExceptionEscapedKey is the attribute Key conforming to the + // "exception.escaped" semantic conventions. It represents the sHOULD be + // set to true if the exception event is recorded at a point where it is + // known that the exception is escaping the scope of the span. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + // Note: An exception is considered to have escaped (or left) the scope of + // a span, + // if that span is ended while the exception is still logically "in + // flight". + // This may be actually "in flight" in some languages (e.g. if the + // exception + // is passed to a Context manager's `__exit__` method in Python) but will + // usually be caught at the point of recording the exception in most + // languages. + // + // It is usually not possible to determine at the point where an exception + // is thrown + // whether it will escape the scope of a span. + // However, it is trivial to know that an exception + // will escape, if one checks for an active exception just before ending + // the span, + // as done in the [example above](#recording-an-exception). + // + // It follows that an exception may still escape the scope of the span + // even if the `exception.escaped` attribute was not set or set to false, + // since the event might have been recorded at a time where it was not + // clear whether the exception will escape. + ExceptionEscapedKey = attribute.Key("exception.escaped") +) + +// ExceptionEscaped returns an attribute KeyValue conforming to the +// "exception.escaped" semantic conventions. It represents the sHOULD be set to +// true if the exception event is recorded at a point where it is known that +// the exception is escaping the scope of the span. +func ExceptionEscaped(val bool) attribute.KeyValue { + return ExceptionEscapedKey.Bool(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go new file mode 100644 index 00000000000..9b8c559de42 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +const ( + // ExceptionEventName is the name of the Span event representing an exception. + ExceptionEventName = "exception" +) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go new file mode 100644 index 00000000000..d5c4b5c136a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +// HTTP scheme attributes. +var ( + HTTPSchemeHTTP = HTTPSchemeKey.String("http") + HTTPSchemeHTTPS = HTTPSchemeKey.String("https") +) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go new file mode 100644 index 00000000000..fc43808fe44 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go @@ -0,0 +1,152 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package httpconv provides OpenTelemetry HTTP semantic conventions for +// tracing telemetry. +package httpconv // import "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv" + +import ( + "net/http" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/semconv/internal/v2" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" +) + +var ( + nc = &internal.NetConv{ + NetHostNameKey: semconv.NetHostNameKey, + NetHostPortKey: semconv.NetHostPortKey, + NetPeerNameKey: semconv.NetPeerNameKey, + NetPeerPortKey: semconv.NetPeerPortKey, + NetSockPeerAddrKey: semconv.NetSockPeerAddrKey, + NetSockPeerPortKey: semconv.NetSockPeerPortKey, + NetTransportOther: semconv.NetTransportOther, + NetTransportTCP: semconv.NetTransportTCP, + NetTransportUDP: semconv.NetTransportUDP, + NetTransportInProc: semconv.NetTransportInProc, + } + + hc = &internal.HTTPConv{ + NetConv: nc, + + EnduserIDKey: semconv.EnduserIDKey, + HTTPClientIPKey: semconv.HTTPClientIPKey, + HTTPFlavorKey: semconv.HTTPFlavorKey, + HTTPMethodKey: semconv.HTTPMethodKey, + HTTPRequestContentLengthKey: semconv.HTTPRequestContentLengthKey, + HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey, + HTTPRouteKey: semconv.HTTPRouteKey, + HTTPSchemeHTTP: semconv.HTTPSchemeHTTP, + HTTPSchemeHTTPS: semconv.HTTPSchemeHTTPS, + HTTPStatusCodeKey: semconv.HTTPStatusCodeKey, + HTTPTargetKey: semconv.HTTPTargetKey, + HTTPURLKey: semconv.HTTPURLKey, + HTTPUserAgentKey: semconv.HTTPUserAgentKey, + } +) + +// ClientResponse returns trace attributes for an HTTP response received by a +// client from a server. It will return the following attributes if the related +// values are defined in resp: "http.status.code", +// "http.response_content_length". +// +// This does not add all OpenTelemetry required attributes for an HTTP event, +// it assumes ClientRequest was used to create the span with a complete set of +// attributes. If a complete set of attributes can be generated using the +// request contained in resp. For example: +// +// append(ClientResponse(resp), ClientRequest(resp.Request)...) +func ClientResponse(resp *http.Response) []attribute.KeyValue { + return hc.ClientResponse(resp) +} + +// ClientRequest returns trace attributes for an HTTP request made by a client. +// The following attributes are always returned: "http.url", "http.flavor", +// "http.method", "net.peer.name". The following attributes are returned if the +// related values are defined in req: "net.peer.port", "http.user_agent", +// "http.request_content_length", "enduser.id". +func ClientRequest(req *http.Request) []attribute.KeyValue { + return hc.ClientRequest(req) +} + +// ClientStatus returns a span status code and message for an HTTP status code +// value received by a client. +func ClientStatus(code int) (codes.Code, string) { + return hc.ClientStatus(code) +} + +// ServerRequest returns trace attributes for an HTTP request received by a +// server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +// +// The following attributes are always returned: "http.method", "http.scheme", +// "http.flavor", "http.target", "net.host.name". The following attributes are +// returned if they related values are defined in req: "net.host.port", +// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", +// "http.client_ip". +func ServerRequest(server string, req *http.Request) []attribute.KeyValue { + return hc.ServerRequest(server, req) +} + +// ServerStatus returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func ServerStatus(code int) (codes.Code, string) { + return hc.ServerStatus(code) +} + +// RequestHeader returns the contents of h as attributes. +// +// Instrumentation should require an explicit configuration of which headers to +// captured and then prune what they pass here. Including all headers can be a +// security risk - explicit configuration helps avoid leaking sensitive +// information. +// +// The User-Agent header is already captured in the http.user_agent attribute +// from ClientRequest and ServerRequest. Instrumentation may provide an option +// to capture that header here even though it is not recommended. Otherwise, +// instrumentation should filter that out of what is passed. +func RequestHeader(h http.Header) []attribute.KeyValue { + return hc.RequestHeader(h) +} + +// ResponseHeader returns the contents of h as attributes. +// +// Instrumentation should require an explicit configuration of which headers to +// captured and then prune what they pass here. Including all headers can be a +// security risk - explicit configuration helps avoid leaking sensitive +// information. +// +// The User-Agent header is already captured in the http.user_agent attribute +// from ClientRequest and ServerRequest. Instrumentation may provide an option +// to capture that header here even though it is not recommended. Otherwise, +// instrumentation should filter that out of what is passed. +func ResponseHeader(h http.Header) []attribute.KeyValue { + return hc.ResponseHeader(h) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go new file mode 100644 index 00000000000..39a2eab3a6a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go @@ -0,0 +1,2010 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +import "go.opentelemetry.io/otel/attribute" + +// The web browser in which the application represented by the resource is +// running. The `browser.*` attributes MUST be used only for resources that +// represent applications running in a web browser (regardless of whether +// running on a mobile or desktop device). +const ( + // BrowserBrandsKey is the attribute Key conforming to the "browser.brands" + // semantic conventions. It represents the array of brand name and version + // separated by a space + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99' + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.brands`). + BrowserBrandsKey = attribute.Key("browser.brands") + + // BrowserPlatformKey is the attribute Key conforming to the + // "browser.platform" semantic conventions. It represents the platform on + // which the browser is running + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Windows', 'macOS', 'Android' + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.platform`). If unavailable, the legacy + // `navigator.platform` API SHOULD NOT be used instead and this attribute + // SHOULD be left unset in order for the values to be consistent. + // The list of possible values is defined in the [W3C User-Agent Client + // Hints + // specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). + // Note that some (but not all) of these values can overlap with values in + // the [`os.type` and `os.name` attributes](./os.md). However, for + // consistency, the values in the `browser.platform` attribute should + // capture the exact value that the user agent provides. + BrowserPlatformKey = attribute.Key("browser.platform") + + // BrowserMobileKey is the attribute Key conforming to the "browser.mobile" + // semantic conventions. It represents a boolean that is true if the + // browser is running on a mobile device + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.mobile`). If unavailable, this attribute + // SHOULD be left unset. + BrowserMobileKey = attribute.Key("browser.mobile") + + // BrowserUserAgentKey is the attribute Key conforming to the + // "browser.user_agent" semantic conventions. It represents the full + // user-agent string provided by the browser + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) + // AppleWebKit/537.36 (KHTML, ' + // 'like Gecko) Chrome/95.0.4638.54 Safari/537.36' + // Note: The user-agent value SHOULD be provided only from browsers that do + // not have a mechanism to retrieve brands and platform individually from + // the User-Agent Client Hints API. To retrieve the value, the legacy + // `navigator.userAgent` API can be used. + BrowserUserAgentKey = attribute.Key("browser.user_agent") + + // BrowserLanguageKey is the attribute Key conforming to the + // "browser.language" semantic conventions. It represents the preferred + // language of the user using the browser + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'en', 'en-US', 'fr', 'fr-FR' + // Note: This value is intended to be taken from the Navigator API + // `navigator.language`. + BrowserLanguageKey = attribute.Key("browser.language") +) + +// BrowserBrands returns an attribute KeyValue conforming to the +// "browser.brands" semantic conventions. It represents the array of brand name +// and version separated by a space +func BrowserBrands(val ...string) attribute.KeyValue { + return BrowserBrandsKey.StringSlice(val) +} + +// BrowserPlatform returns an attribute KeyValue conforming to the +// "browser.platform" semantic conventions. It represents the platform on which +// the browser is running +func BrowserPlatform(val string) attribute.KeyValue { + return BrowserPlatformKey.String(val) +} + +// BrowserMobile returns an attribute KeyValue conforming to the +// "browser.mobile" semantic conventions. It represents a boolean that is true +// if the browser is running on a mobile device +func BrowserMobile(val bool) attribute.KeyValue { + return BrowserMobileKey.Bool(val) +} + +// BrowserUserAgent returns an attribute KeyValue conforming to the +// "browser.user_agent" semantic conventions. It represents the full user-agent +// string provided by the browser +func BrowserUserAgent(val string) attribute.KeyValue { + return BrowserUserAgentKey.String(val) +} + +// BrowserLanguage returns an attribute KeyValue conforming to the +// "browser.language" semantic conventions. It represents the preferred +// language of the user using the browser +func BrowserLanguage(val string) attribute.KeyValue { + return BrowserLanguageKey.String(val) +} + +// A cloud environment (e.g. GCP, Azure, AWS) +const ( + // CloudProviderKey is the attribute Key conforming to the "cloud.provider" + // semantic conventions. It represents the name of the cloud provider. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + CloudProviderKey = attribute.Key("cloud.provider") + + // CloudAccountIDKey is the attribute Key conforming to the + // "cloud.account.id" semantic conventions. It represents the cloud account + // ID the resource is assigned to. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '111111111111', 'opentelemetry' + CloudAccountIDKey = attribute.Key("cloud.account.id") + + // CloudRegionKey is the attribute Key conforming to the "cloud.region" + // semantic conventions. It represents the geographical region the resource + // is running. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-central1', 'us-east-1' + // Note: Refer to your provider's docs to see the available regions, for + // example [Alibaba Cloud + // regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS + // regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), + // [Azure + // regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), + // [Google Cloud regions](https://cloud.google.com/about/locations), or + // [Tencent Cloud + // regions](https://intl.cloud.tencent.com/document/product/213/6091). + CloudRegionKey = attribute.Key("cloud.region") + + // CloudAvailabilityZoneKey is the attribute Key conforming to the + // "cloud.availability_zone" semantic conventions. It represents the cloud + // regions often have multiple, isolated locations known as zones to + // increase availability. Availability zone represents the zone where the + // resource is running. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-east-1c' + // Note: Availability zones are called "zones" on Alibaba Cloud and Google + // Cloud. + CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone") + + // CloudPlatformKey is the attribute Key conforming to the "cloud.platform" + // semantic conventions. It represents the cloud platform in use. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: The prefix of the service SHOULD match the one specified in + // `cloud.provider`. + CloudPlatformKey = attribute.Key("cloud.platform") +) + +var ( + // Alibaba Cloud + CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud") + // Amazon Web Services + CloudProviderAWS = CloudProviderKey.String("aws") + // Microsoft Azure + CloudProviderAzure = CloudProviderKey.String("azure") + // Google Cloud Platform + CloudProviderGCP = CloudProviderKey.String("gcp") + // IBM Cloud + CloudProviderIbmCloud = CloudProviderKey.String("ibm_cloud") + // Tencent Cloud + CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud") +) + +var ( + // Alibaba Cloud Elastic Compute Service + CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs") + // Alibaba Cloud Function Compute + CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc") + // Red Hat OpenShift on Alibaba Cloud + CloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String("alibaba_cloud_openshift") + // AWS Elastic Compute Cloud + CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2") + // AWS Elastic Container Service + CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs") + // AWS Elastic Kubernetes Service + CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks") + // AWS Lambda + CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda") + // AWS Elastic Beanstalk + CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk") + // AWS App Runner + CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner") + // Red Hat OpenShift on AWS (ROSA) + CloudPlatformAWSOpenshift = CloudPlatformKey.String("aws_openshift") + // Azure Virtual Machines + CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm") + // Azure Container Instances + CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances") + // Azure Kubernetes Service + CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks") + // Azure Functions + CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions") + // Azure App Service + CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service") + // Azure Red Hat OpenShift + CloudPlatformAzureOpenshift = CloudPlatformKey.String("azure_openshift") + // Google Cloud Compute Engine (GCE) + CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine") + // Google Cloud Run + CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run") + // Google Cloud Kubernetes Engine (GKE) + CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine") + // Google Cloud Functions (GCF) + CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions") + // Google Cloud App Engine (GAE) + CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine") + // Red Hat OpenShift on Google Cloud + CloudPlatformGoogleCloudOpenshift = CloudPlatformKey.String("google_cloud_openshift") + // Red Hat OpenShift on IBM Cloud + CloudPlatformIbmCloudOpenshift = CloudPlatformKey.String("ibm_cloud_openshift") + // Tencent Cloud Cloud Virtual Machine (CVM) + CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm") + // Tencent Cloud Elastic Kubernetes Service (EKS) + CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks") + // Tencent Cloud Serverless Cloud Function (SCF) + CloudPlatformTencentCloudScf = CloudPlatformKey.String("tencent_cloud_scf") +) + +// CloudAccountID returns an attribute KeyValue conforming to the +// "cloud.account.id" semantic conventions. It represents the cloud account ID +// the resource is assigned to. +func CloudAccountID(val string) attribute.KeyValue { + return CloudAccountIDKey.String(val) +} + +// CloudRegion returns an attribute KeyValue conforming to the +// "cloud.region" semantic conventions. It represents the geographical region +// the resource is running. +func CloudRegion(val string) attribute.KeyValue { + return CloudRegionKey.String(val) +} + +// CloudAvailabilityZone returns an attribute KeyValue conforming to the +// "cloud.availability_zone" semantic conventions. It represents the cloud +// regions often have multiple, isolated locations known as zones to increase +// availability. Availability zone represents the zone where the resource is +// running. +func CloudAvailabilityZone(val string) attribute.KeyValue { + return CloudAvailabilityZoneKey.String(val) +} + +// Resources used by AWS Elastic Container Service (ECS). +const ( + // AWSECSContainerARNKey is the attribute Key conforming to the + // "aws.ecs.container.arn" semantic conventions. It represents the Amazon + // Resource Name (ARN) of an [ECS container + // instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9' + AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn") + + // AWSECSClusterARNKey is the attribute Key conforming to the + // "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an + // [ECS + // cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' + AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn") + + // AWSECSLaunchtypeKey is the attribute Key conforming to the + // "aws.ecs.launchtype" semantic conventions. It represents the [launch + // type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) + // for an ECS task. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype") + + // AWSECSTaskARNKey is the attribute Key conforming to the + // "aws.ecs.task.arn" semantic conventions. It represents the ARN of an + // [ECS task + // definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b' + AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn") + + // AWSECSTaskFamilyKey is the attribute Key conforming to the + // "aws.ecs.task.family" semantic conventions. It represents the task + // definition family this task definition is a member of. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-family' + AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family") + + // AWSECSTaskRevisionKey is the attribute Key conforming to the + // "aws.ecs.task.revision" semantic conventions. It represents the revision + // for this task definition. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '8', '26' + AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision") +) + +var ( + // ec2 + AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2") + // fargate + AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate") +) + +// AWSECSContainerARN returns an attribute KeyValue conforming to the +// "aws.ecs.container.arn" semantic conventions. It represents the Amazon +// Resource Name (ARN) of an [ECS container +// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). +func AWSECSContainerARN(val string) attribute.KeyValue { + return AWSECSContainerARNKey.String(val) +} + +// AWSECSClusterARN returns an attribute KeyValue conforming to the +// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an [ECS +// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). +func AWSECSClusterARN(val string) attribute.KeyValue { + return AWSECSClusterARNKey.String(val) +} + +// AWSECSTaskARN returns an attribute KeyValue conforming to the +// "aws.ecs.task.arn" semantic conventions. It represents the ARN of an [ECS +// task +// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). +func AWSECSTaskARN(val string) attribute.KeyValue { + return AWSECSTaskARNKey.String(val) +} + +// AWSECSTaskFamily returns an attribute KeyValue conforming to the +// "aws.ecs.task.family" semantic conventions. It represents the task +// definition family this task definition is a member of. +func AWSECSTaskFamily(val string) attribute.KeyValue { + return AWSECSTaskFamilyKey.String(val) +} + +// AWSECSTaskRevision returns an attribute KeyValue conforming to the +// "aws.ecs.task.revision" semantic conventions. It represents the revision for +// this task definition. +func AWSECSTaskRevision(val string) attribute.KeyValue { + return AWSECSTaskRevisionKey.String(val) +} + +// Resources used by AWS Elastic Kubernetes Service (EKS). +const ( + // AWSEKSClusterARNKey is the attribute Key conforming to the + // "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an + // EKS cluster. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' + AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn") +) + +// AWSEKSClusterARN returns an attribute KeyValue conforming to the +// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS +// cluster. +func AWSEKSClusterARN(val string) attribute.KeyValue { + return AWSEKSClusterARNKey.String(val) +} + +// Resources specific to Amazon Web Services. +const ( + // AWSLogGroupNamesKey is the attribute Key conforming to the + // "aws.log.group.names" semantic conventions. It represents the name(s) of + // the AWS log group(s) an application is writing to. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '/aws/lambda/my-function', 'opentelemetry-service' + // Note: Multiple log groups must be supported for cases like + // multi-container applications, where a single application has sidecar + // containers, and each write to their own log group. + AWSLogGroupNamesKey = attribute.Key("aws.log.group.names") + + // AWSLogGroupARNsKey is the attribute Key conforming to the + // "aws.log.group.arns" semantic conventions. It represents the Amazon + // Resource Name(s) (ARN) of the AWS log group(s). + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*' + // Note: See the [log group ARN format + // documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns") + + // AWSLogStreamNamesKey is the attribute Key conforming to the + // "aws.log.stream.names" semantic conventions. It represents the name(s) + // of the AWS log stream(s) an application is writing to. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' + AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names") + + // AWSLogStreamARNsKey is the attribute Key conforming to the + // "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of + // the AWS log stream(s). + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' + // Note: See the [log stream ARN format + // documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + // One log group can contain several log streams, so these ARNs necessarily + // identify both a log group and a log stream. + AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns") +) + +// AWSLogGroupNames returns an attribute KeyValue conforming to the +// "aws.log.group.names" semantic conventions. It represents the name(s) of the +// AWS log group(s) an application is writing to. +func AWSLogGroupNames(val ...string) attribute.KeyValue { + return AWSLogGroupNamesKey.StringSlice(val) +} + +// AWSLogGroupARNs returns an attribute KeyValue conforming to the +// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource +// Name(s) (ARN) of the AWS log group(s). +func AWSLogGroupARNs(val ...string) attribute.KeyValue { + return AWSLogGroupARNsKey.StringSlice(val) +} + +// AWSLogStreamNames returns an attribute KeyValue conforming to the +// "aws.log.stream.names" semantic conventions. It represents the name(s) of +// the AWS log stream(s) an application is writing to. +func AWSLogStreamNames(val ...string) attribute.KeyValue { + return AWSLogStreamNamesKey.StringSlice(val) +} + +// AWSLogStreamARNs returns an attribute KeyValue conforming to the +// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the +// AWS log stream(s). +func AWSLogStreamARNs(val ...string) attribute.KeyValue { + return AWSLogStreamARNsKey.StringSlice(val) +} + +// A container instance. +const ( + // ContainerNameKey is the attribute Key conforming to the "container.name" + // semantic conventions. It represents the container name used by container + // runtime. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-autoconf' + ContainerNameKey = attribute.Key("container.name") + + // ContainerIDKey is the attribute Key conforming to the "container.id" + // semantic conventions. It represents the container ID. Usually a UUID, as + // for example used to [identify Docker + // containers](https://docs.docker.com/engine/reference/run/#container-identification). + // The UUID might be abbreviated. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'a3bf90e006b2' + ContainerIDKey = attribute.Key("container.id") + + // ContainerRuntimeKey is the attribute Key conforming to the + // "container.runtime" semantic conventions. It represents the container + // runtime managing this container. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'docker', 'containerd', 'rkt' + ContainerRuntimeKey = attribute.Key("container.runtime") + + // ContainerImageNameKey is the attribute Key conforming to the + // "container.image.name" semantic conventions. It represents the name of + // the image the container was built on. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'gcr.io/opentelemetry/operator' + ContainerImageNameKey = attribute.Key("container.image.name") + + // ContainerImageTagKey is the attribute Key conforming to the + // "container.image.tag" semantic conventions. It represents the container + // image tag. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0.1' + ContainerImageTagKey = attribute.Key("container.image.tag") +) + +// ContainerName returns an attribute KeyValue conforming to the +// "container.name" semantic conventions. It represents the container name used +// by container runtime. +func ContainerName(val string) attribute.KeyValue { + return ContainerNameKey.String(val) +} + +// ContainerID returns an attribute KeyValue conforming to the +// "container.id" semantic conventions. It represents the container ID. Usually +// a UUID, as for example used to [identify Docker +// containers](https://docs.docker.com/engine/reference/run/#container-identification). +// The UUID might be abbreviated. +func ContainerID(val string) attribute.KeyValue { + return ContainerIDKey.String(val) +} + +// ContainerRuntime returns an attribute KeyValue conforming to the +// "container.runtime" semantic conventions. It represents the container +// runtime managing this container. +func ContainerRuntime(val string) attribute.KeyValue { + return ContainerRuntimeKey.String(val) +} + +// ContainerImageName returns an attribute KeyValue conforming to the +// "container.image.name" semantic conventions. It represents the name of the +// image the container was built on. +func ContainerImageName(val string) attribute.KeyValue { + return ContainerImageNameKey.String(val) +} + +// ContainerImageTag returns an attribute KeyValue conforming to the +// "container.image.tag" semantic conventions. It represents the container +// image tag. +func ContainerImageTag(val string) attribute.KeyValue { + return ContainerImageTagKey.String(val) +} + +// The software deployment. +const ( + // DeploymentEnvironmentKey is the attribute Key conforming to the + // "deployment.environment" semantic conventions. It represents the name of + // the [deployment + // environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka + // deployment tier). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'staging', 'production' + DeploymentEnvironmentKey = attribute.Key("deployment.environment") +) + +// DeploymentEnvironment returns an attribute KeyValue conforming to the +// "deployment.environment" semantic conventions. It represents the name of the +// [deployment +// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka +// deployment tier). +func DeploymentEnvironment(val string) attribute.KeyValue { + return DeploymentEnvironmentKey.String(val) +} + +// The device on which the process represented by this resource is running. +const ( + // DeviceIDKey is the attribute Key conforming to the "device.id" semantic + // conventions. It represents a unique identifier representing the device + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092' + // Note: The device identifier MUST only be defined using the values + // outlined below. This value is not an advertising identifier and MUST NOT + // be used as such. On iOS (Swift or Objective-C), this value MUST be equal + // to the [vendor + // identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). + // On Android (Java or Kotlin), this value MUST be equal to the Firebase + // Installation ID or a globally unique UUID which is persisted across + // sessions in your application. More information can be found + // [here](https://developer.android.com/training/articles/user-data-ids) on + // best practices and exact implementation details. Caution should be taken + // when storing personal data or anything which can identify a user. GDPR + // and data protection laws may apply, ensure you do your own due + // diligence. + DeviceIDKey = attribute.Key("device.id") + + // DeviceModelIdentifierKey is the attribute Key conforming to the + // "device.model.identifier" semantic conventions. It represents the model + // identifier for the device + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iPhone3,4', 'SM-G920F' + // Note: It's recommended this value represents a machine readable version + // of the model identifier rather than the market or consumer-friendly name + // of the device. + DeviceModelIdentifierKey = attribute.Key("device.model.identifier") + + // DeviceModelNameKey is the attribute Key conforming to the + // "device.model.name" semantic conventions. It represents the marketing + // name for the device model + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6' + // Note: It's recommended this value represents a human readable version of + // the device model rather than a machine readable alternative. + DeviceModelNameKey = attribute.Key("device.model.name") + + // DeviceManufacturerKey is the attribute Key conforming to the + // "device.manufacturer" semantic conventions. It represents the name of + // the device manufacturer + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Apple', 'Samsung' + // Note: The Android OS provides this field via + // [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). + // iOS apps SHOULD hardcode the value `Apple`. + DeviceManufacturerKey = attribute.Key("device.manufacturer") +) + +// DeviceID returns an attribute KeyValue conforming to the "device.id" +// semantic conventions. It represents a unique identifier representing the +// device +func DeviceID(val string) attribute.KeyValue { + return DeviceIDKey.String(val) +} + +// DeviceModelIdentifier returns an attribute KeyValue conforming to the +// "device.model.identifier" semantic conventions. It represents the model +// identifier for the device +func DeviceModelIdentifier(val string) attribute.KeyValue { + return DeviceModelIdentifierKey.String(val) +} + +// DeviceModelName returns an attribute KeyValue conforming to the +// "device.model.name" semantic conventions. It represents the marketing name +// for the device model +func DeviceModelName(val string) attribute.KeyValue { + return DeviceModelNameKey.String(val) +} + +// DeviceManufacturer returns an attribute KeyValue conforming to the +// "device.manufacturer" semantic conventions. It represents the name of the +// device manufacturer +func DeviceManufacturer(val string) attribute.KeyValue { + return DeviceManufacturerKey.String(val) +} + +// A serverless instance. +const ( + // FaaSNameKey is the attribute Key conforming to the "faas.name" semantic + // conventions. It represents the name of the single function that this + // runtime instance executes. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'my-function', 'myazurefunctionapp/some-function-name' + // Note: This is the name of the function as configured/deployed on the + // FaaS + // platform and is usually different from the name of the callback + // function (which may be stored in the + // [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-general.md#source-code-attributes) + // span attributes). + // + // For some cloud providers, the above definition is ambiguous. The + // following + // definition of function name MUST be used for this attribute + // (and consequently the span name) for the listed cloud + // providers/products: + // + // * **Azure:** The full name `/`, i.e., function app name + // followed by a forward slash followed by the function name (this form + // can also be seen in the resource JSON for the function). + // This means that a span attribute MUST be used, as an Azure function + // app can host multiple functions that would usually share + // a TracerProvider (see also the `faas.id` attribute). + FaaSNameKey = attribute.Key("faas.name") + + // FaaSIDKey is the attribute Key conforming to the "faas.id" semantic + // conventions. It represents the unique ID of the single function that + // this runtime instance executes. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function' + // Note: On some cloud providers, it may not be possible to determine the + // full ID at startup, + // so consider setting `faas.id` as a span attribute instead. + // + // The exact value to use for `faas.id` depends on the cloud provider: + // + // * **AWS Lambda:** The function + // [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + // Take care not to use the "invoked ARN" directly but replace any + // [alias + // suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + // with the resolved function version, as the same runtime instance may + // be invokable with + // multiple different aliases. + // * **GCP:** The [URI of the + // resource](https://cloud.google.com/iam/docs/full-resource-names) + // * **Azure:** The [Fully Qualified Resource + // ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) + // of the invoked function, + // *not* the function app, having the form + // `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + // This means that a span attribute MUST be used, as an Azure function + // app can host multiple functions that would usually share + // a TracerProvider. + FaaSIDKey = attribute.Key("faas.id") + + // FaaSVersionKey is the attribute Key conforming to the "faas.version" + // semantic conventions. It represents the immutable version of the + // function being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '26', 'pinkfroid-00002' + // Note: Depending on the cloud provider and platform, use: + // + // * **AWS Lambda:** The [function + // version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + // (an integer represented as a decimal string). + // * **Google Cloud Run:** The + // [revision](https://cloud.google.com/run/docs/managing/revisions) + // (i.e., the function name plus the revision suffix). + // * **Google Cloud Functions:** The value of the + // [`K_REVISION` environment + // variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). + // * **Azure Functions:** Not applicable. Do not set this attribute. + FaaSVersionKey = attribute.Key("faas.version") + + // FaaSInstanceKey is the attribute Key conforming to the "faas.instance" + // semantic conventions. It represents the execution environment ID as a + // string, that will be potentially reused for other invocations to the + // same function/function version. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de' + // Note: * **AWS Lambda:** Use the (full) log stream name. + FaaSInstanceKey = attribute.Key("faas.instance") + + // FaaSMaxMemoryKey is the attribute Key conforming to the + // "faas.max_memory" semantic conventions. It represents the amount of + // memory available to the serverless function in MiB. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 128 + // Note: It's recommended to set this attribute since e.g. too little + // memory can easily stop a Java AWS Lambda function from working + // correctly. On AWS Lambda, the environment variable + // `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information. + FaaSMaxMemoryKey = attribute.Key("faas.max_memory") +) + +// FaaSName returns an attribute KeyValue conforming to the "faas.name" +// semantic conventions. It represents the name of the single function that +// this runtime instance executes. +func FaaSName(val string) attribute.KeyValue { + return FaaSNameKey.String(val) +} + +// FaaSID returns an attribute KeyValue conforming to the "faas.id" semantic +// conventions. It represents the unique ID of the single function that this +// runtime instance executes. +func FaaSID(val string) attribute.KeyValue { + return FaaSIDKey.String(val) +} + +// FaaSVersion returns an attribute KeyValue conforming to the +// "faas.version" semantic conventions. It represents the immutable version of +// the function being executed. +func FaaSVersion(val string) attribute.KeyValue { + return FaaSVersionKey.String(val) +} + +// FaaSInstance returns an attribute KeyValue conforming to the +// "faas.instance" semantic conventions. It represents the execution +// environment ID as a string, that will be potentially reused for other +// invocations to the same function/function version. +func FaaSInstance(val string) attribute.KeyValue { + return FaaSInstanceKey.String(val) +} + +// FaaSMaxMemory returns an attribute KeyValue conforming to the +// "faas.max_memory" semantic conventions. It represents the amount of memory +// available to the serverless function in MiB. +func FaaSMaxMemory(val int) attribute.KeyValue { + return FaaSMaxMemoryKey.Int(val) +} + +// A host is defined as a general computing instance. +const ( + // HostIDKey is the attribute Key conforming to the "host.id" semantic + // conventions. It represents the unique host ID. For Cloud, this must be + // the instance_id assigned by the cloud provider. For non-containerized + // Linux systems, the `machine-id` located in `/etc/machine-id` or + // `/var/lib/dbus/machine-id` may be used. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'fdbf79e8af94cb7f9e8df36789187052' + HostIDKey = attribute.Key("host.id") + + // HostNameKey is the attribute Key conforming to the "host.name" semantic + // conventions. It represents the name of the host. On Unix systems, it may + // contain what the hostname command returns, or the fully qualified + // hostname, or another name specified by the user. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-test' + HostNameKey = attribute.Key("host.name") + + // HostTypeKey is the attribute Key conforming to the "host.type" semantic + // conventions. It represents the type of host. For Cloud, this must be the + // machine type. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'n1-standard-1' + HostTypeKey = attribute.Key("host.type") + + // HostArchKey is the attribute Key conforming to the "host.arch" semantic + // conventions. It represents the CPU architecture the host system is + // running on. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + HostArchKey = attribute.Key("host.arch") + + // HostImageNameKey is the attribute Key conforming to the + // "host.image.name" semantic conventions. It represents the name of the VM + // image or OS install the host was instantiated from. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905' + HostImageNameKey = attribute.Key("host.image.name") + + // HostImageIDKey is the attribute Key conforming to the "host.image.id" + // semantic conventions. It represents the vM image ID. For Cloud, this + // value is from the provider. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'ami-07b06b442921831e5' + HostImageIDKey = attribute.Key("host.image.id") + + // HostImageVersionKey is the attribute Key conforming to the + // "host.image.version" semantic conventions. It represents the version + // string of the VM image as defined in [Version + // Attributes](README.md#version-attributes). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0.1' + HostImageVersionKey = attribute.Key("host.image.version") +) + +var ( + // AMD64 + HostArchAMD64 = HostArchKey.String("amd64") + // ARM32 + HostArchARM32 = HostArchKey.String("arm32") + // ARM64 + HostArchARM64 = HostArchKey.String("arm64") + // Itanium + HostArchIA64 = HostArchKey.String("ia64") + // 32-bit PowerPC + HostArchPPC32 = HostArchKey.String("ppc32") + // 64-bit PowerPC + HostArchPPC64 = HostArchKey.String("ppc64") + // IBM z/Architecture + HostArchS390x = HostArchKey.String("s390x") + // 32-bit x86 + HostArchX86 = HostArchKey.String("x86") +) + +// HostID returns an attribute KeyValue conforming to the "host.id" semantic +// conventions. It represents the unique host ID. For Cloud, this must be the +// instance_id assigned by the cloud provider. For non-containerized Linux +// systems, the `machine-id` located in `/etc/machine-id` or +// `/var/lib/dbus/machine-id` may be used. +func HostID(val string) attribute.KeyValue { + return HostIDKey.String(val) +} + +// HostName returns an attribute KeyValue conforming to the "host.name" +// semantic conventions. It represents the name of the host. On Unix systems, +// it may contain what the hostname command returns, or the fully qualified +// hostname, or another name specified by the user. +func HostName(val string) attribute.KeyValue { + return HostNameKey.String(val) +} + +// HostType returns an attribute KeyValue conforming to the "host.type" +// semantic conventions. It represents the type of host. For Cloud, this must +// be the machine type. +func HostType(val string) attribute.KeyValue { + return HostTypeKey.String(val) +} + +// HostImageName returns an attribute KeyValue conforming to the +// "host.image.name" semantic conventions. It represents the name of the VM +// image or OS install the host was instantiated from. +func HostImageName(val string) attribute.KeyValue { + return HostImageNameKey.String(val) +} + +// HostImageID returns an attribute KeyValue conforming to the +// "host.image.id" semantic conventions. It represents the vM image ID. For +// Cloud, this value is from the provider. +func HostImageID(val string) attribute.KeyValue { + return HostImageIDKey.String(val) +} + +// HostImageVersion returns an attribute KeyValue conforming to the +// "host.image.version" semantic conventions. It represents the version string +// of the VM image as defined in [Version +// Attributes](README.md#version-attributes). +func HostImageVersion(val string) attribute.KeyValue { + return HostImageVersionKey.String(val) +} + +// A Kubernetes Cluster. +const ( + // K8SClusterNameKey is the attribute Key conforming to the + // "k8s.cluster.name" semantic conventions. It represents the name of the + // cluster. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-cluster' + K8SClusterNameKey = attribute.Key("k8s.cluster.name") +) + +// K8SClusterName returns an attribute KeyValue conforming to the +// "k8s.cluster.name" semantic conventions. It represents the name of the +// cluster. +func K8SClusterName(val string) attribute.KeyValue { + return K8SClusterNameKey.String(val) +} + +// A Kubernetes Node object. +const ( + // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name" + // semantic conventions. It represents the name of the Node. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'node-1' + K8SNodeNameKey = attribute.Key("k8s.node.name") + + // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" + // semantic conventions. It represents the UID of the Node. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2' + K8SNodeUIDKey = attribute.Key("k8s.node.uid") +) + +// K8SNodeName returns an attribute KeyValue conforming to the +// "k8s.node.name" semantic conventions. It represents the name of the Node. +func K8SNodeName(val string) attribute.KeyValue { + return K8SNodeNameKey.String(val) +} + +// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid" +// semantic conventions. It represents the UID of the Node. +func K8SNodeUID(val string) attribute.KeyValue { + return K8SNodeUIDKey.String(val) +} + +// A Kubernetes Namespace. +const ( + // K8SNamespaceNameKey is the attribute Key conforming to the + // "k8s.namespace.name" semantic conventions. It represents the name of the + // namespace that the pod is running in. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'default' + K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") +) + +// K8SNamespaceName returns an attribute KeyValue conforming to the +// "k8s.namespace.name" semantic conventions. It represents the name of the +// namespace that the pod is running in. +func K8SNamespaceName(val string) attribute.KeyValue { + return K8SNamespaceNameKey.String(val) +} + +// A Kubernetes Pod object. +const ( + // K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid" + // semantic conventions. It represents the UID of the Pod. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SPodUIDKey = attribute.Key("k8s.pod.uid") + + // K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name" + // semantic conventions. It represents the name of the Pod. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-pod-autoconf' + K8SPodNameKey = attribute.Key("k8s.pod.name") +) + +// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid" +// semantic conventions. It represents the UID of the Pod. +func K8SPodUID(val string) attribute.KeyValue { + return K8SPodUIDKey.String(val) +} + +// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name" +// semantic conventions. It represents the name of the Pod. +func K8SPodName(val string) attribute.KeyValue { + return K8SPodNameKey.String(val) +} + +// A container in a +// [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates). +const ( + // K8SContainerNameKey is the attribute Key conforming to the + // "k8s.container.name" semantic conventions. It represents the name of the + // Container from Pod specification, must be unique within a Pod. Container + // runtime usually uses different globally unique name (`container.name`). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'redis' + K8SContainerNameKey = attribute.Key("k8s.container.name") + + // K8SContainerRestartCountKey is the attribute Key conforming to the + // "k8s.container.restart_count" semantic conventions. It represents the + // number of times the container was restarted. This attribute can be used + // to identify a particular container (running or stopped) within a + // container spec. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 0, 2 + K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") +) + +// K8SContainerName returns an attribute KeyValue conforming to the +// "k8s.container.name" semantic conventions. It represents the name of the +// Container from Pod specification, must be unique within a Pod. Container +// runtime usually uses different globally unique name (`container.name`). +func K8SContainerName(val string) attribute.KeyValue { + return K8SContainerNameKey.String(val) +} + +// K8SContainerRestartCount returns an attribute KeyValue conforming to the +// "k8s.container.restart_count" semantic conventions. It represents the number +// of times the container was restarted. This attribute can be used to identify +// a particular container (running or stopped) within a container spec. +func K8SContainerRestartCount(val int) attribute.KeyValue { + return K8SContainerRestartCountKey.Int(val) +} + +// A Kubernetes ReplicaSet object. +const ( + // K8SReplicaSetUIDKey is the attribute Key conforming to the + // "k8s.replicaset.uid" semantic conventions. It represents the UID of the + // ReplicaSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") + + // K8SReplicaSetNameKey is the attribute Key conforming to the + // "k8s.replicaset.name" semantic conventions. It represents the name of + // the ReplicaSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") +) + +// K8SReplicaSetUID returns an attribute KeyValue conforming to the +// "k8s.replicaset.uid" semantic conventions. It represents the UID of the +// ReplicaSet. +func K8SReplicaSetUID(val string) attribute.KeyValue { + return K8SReplicaSetUIDKey.String(val) +} + +// K8SReplicaSetName returns an attribute KeyValue conforming to the +// "k8s.replicaset.name" semantic conventions. It represents the name of the +// ReplicaSet. +func K8SReplicaSetName(val string) attribute.KeyValue { + return K8SReplicaSetNameKey.String(val) +} + +// A Kubernetes Deployment object. +const ( + // K8SDeploymentUIDKey is the attribute Key conforming to the + // "k8s.deployment.uid" semantic conventions. It represents the UID of the + // Deployment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") + + // K8SDeploymentNameKey is the attribute Key conforming to the + // "k8s.deployment.name" semantic conventions. It represents the name of + // the Deployment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") +) + +// K8SDeploymentUID returns an attribute KeyValue conforming to the +// "k8s.deployment.uid" semantic conventions. It represents the UID of the +// Deployment. +func K8SDeploymentUID(val string) attribute.KeyValue { + return K8SDeploymentUIDKey.String(val) +} + +// K8SDeploymentName returns an attribute KeyValue conforming to the +// "k8s.deployment.name" semantic conventions. It represents the name of the +// Deployment. +func K8SDeploymentName(val string) attribute.KeyValue { + return K8SDeploymentNameKey.String(val) +} + +// A Kubernetes StatefulSet object. +const ( + // K8SStatefulSetUIDKey is the attribute Key conforming to the + // "k8s.statefulset.uid" semantic conventions. It represents the UID of the + // StatefulSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") + + // K8SStatefulSetNameKey is the attribute Key conforming to the + // "k8s.statefulset.name" semantic conventions. It represents the name of + // the StatefulSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") +) + +// K8SStatefulSetUID returns an attribute KeyValue conforming to the +// "k8s.statefulset.uid" semantic conventions. It represents the UID of the +// StatefulSet. +func K8SStatefulSetUID(val string) attribute.KeyValue { + return K8SStatefulSetUIDKey.String(val) +} + +// K8SStatefulSetName returns an attribute KeyValue conforming to the +// "k8s.statefulset.name" semantic conventions. It represents the name of the +// StatefulSet. +func K8SStatefulSetName(val string) attribute.KeyValue { + return K8SStatefulSetNameKey.String(val) +} + +// A Kubernetes DaemonSet object. +const ( + // K8SDaemonSetUIDKey is the attribute Key conforming to the + // "k8s.daemonset.uid" semantic conventions. It represents the UID of the + // DaemonSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") + + // K8SDaemonSetNameKey is the attribute Key conforming to the + // "k8s.daemonset.name" semantic conventions. It represents the name of the + // DaemonSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") +) + +// K8SDaemonSetUID returns an attribute KeyValue conforming to the +// "k8s.daemonset.uid" semantic conventions. It represents the UID of the +// DaemonSet. +func K8SDaemonSetUID(val string) attribute.KeyValue { + return K8SDaemonSetUIDKey.String(val) +} + +// K8SDaemonSetName returns an attribute KeyValue conforming to the +// "k8s.daemonset.name" semantic conventions. It represents the name of the +// DaemonSet. +func K8SDaemonSetName(val string) attribute.KeyValue { + return K8SDaemonSetNameKey.String(val) +} + +// A Kubernetes Job object. +const ( + // K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid" + // semantic conventions. It represents the UID of the Job. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SJobUIDKey = attribute.Key("k8s.job.uid") + + // K8SJobNameKey is the attribute Key conforming to the "k8s.job.name" + // semantic conventions. It represents the name of the Job. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SJobNameKey = attribute.Key("k8s.job.name") +) + +// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid" +// semantic conventions. It represents the UID of the Job. +func K8SJobUID(val string) attribute.KeyValue { + return K8SJobUIDKey.String(val) +} + +// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name" +// semantic conventions. It represents the name of the Job. +func K8SJobName(val string) attribute.KeyValue { + return K8SJobNameKey.String(val) +} + +// A Kubernetes CronJob object. +const ( + // K8SCronJobUIDKey is the attribute Key conforming to the + // "k8s.cronjob.uid" semantic conventions. It represents the UID of the + // CronJob. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") + + // K8SCronJobNameKey is the attribute Key conforming to the + // "k8s.cronjob.name" semantic conventions. It represents the name of the + // CronJob. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") +) + +// K8SCronJobUID returns an attribute KeyValue conforming to the +// "k8s.cronjob.uid" semantic conventions. It represents the UID of the +// CronJob. +func K8SCronJobUID(val string) attribute.KeyValue { + return K8SCronJobUIDKey.String(val) +} + +// K8SCronJobName returns an attribute KeyValue conforming to the +// "k8s.cronjob.name" semantic conventions. It represents the name of the +// CronJob. +func K8SCronJobName(val string) attribute.KeyValue { + return K8SCronJobNameKey.String(val) +} + +// The operating system (OS) on which the process represented by this resource +// is running. +const ( + // OSTypeKey is the attribute Key conforming to the "os.type" semantic + // conventions. It represents the operating system type. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + OSTypeKey = attribute.Key("os.type") + + // OSDescriptionKey is the attribute Key conforming to the "os.description" + // semantic conventions. It represents the human readable (not intended to + // be parsed) OS version information, like e.g. reported by `ver` or + // `lsb_release -a` commands. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 + // LTS' + OSDescriptionKey = attribute.Key("os.description") + + // OSNameKey is the attribute Key conforming to the "os.name" semantic + // conventions. It represents the human readable operating system name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iOS', 'Android', 'Ubuntu' + OSNameKey = attribute.Key("os.name") + + // OSVersionKey is the attribute Key conforming to the "os.version" + // semantic conventions. It represents the version string of the operating + // system as defined in [Version + // Attributes](../../resource/semantic_conventions/README.md#version-attributes). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '14.2.1', '18.04.1' + OSVersionKey = attribute.Key("os.version") +) + +var ( + // Microsoft Windows + OSTypeWindows = OSTypeKey.String("windows") + // Linux + OSTypeLinux = OSTypeKey.String("linux") + // Apple Darwin + OSTypeDarwin = OSTypeKey.String("darwin") + // FreeBSD + OSTypeFreeBSD = OSTypeKey.String("freebsd") + // NetBSD + OSTypeNetBSD = OSTypeKey.String("netbsd") + // OpenBSD + OSTypeOpenBSD = OSTypeKey.String("openbsd") + // DragonFly BSD + OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd") + // HP-UX (Hewlett Packard Unix) + OSTypeHPUX = OSTypeKey.String("hpux") + // AIX (Advanced Interactive eXecutive) + OSTypeAIX = OSTypeKey.String("aix") + // SunOS, Oracle Solaris + OSTypeSolaris = OSTypeKey.String("solaris") + // IBM z/OS + OSTypeZOS = OSTypeKey.String("z_os") +) + +// OSDescription returns an attribute KeyValue conforming to the +// "os.description" semantic conventions. It represents the human readable (not +// intended to be parsed) OS version information, like e.g. reported by `ver` +// or `lsb_release -a` commands. +func OSDescription(val string) attribute.KeyValue { + return OSDescriptionKey.String(val) +} + +// OSName returns an attribute KeyValue conforming to the "os.name" semantic +// conventions. It represents the human readable operating system name. +func OSName(val string) attribute.KeyValue { + return OSNameKey.String(val) +} + +// OSVersion returns an attribute KeyValue conforming to the "os.version" +// semantic conventions. It represents the version string of the operating +// system as defined in [Version +// Attributes](../../resource/semantic_conventions/README.md#version-attributes). +func OSVersion(val string) attribute.KeyValue { + return OSVersionKey.String(val) +} + +// An operating system process. +const ( + // ProcessPIDKey is the attribute Key conforming to the "process.pid" + // semantic conventions. It represents the process identifier (PID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 1234 + ProcessPIDKey = attribute.Key("process.pid") + + // ProcessParentPIDKey is the attribute Key conforming to the + // "process.parent_pid" semantic conventions. It represents the parent + // Process identifier (PID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 111 + ProcessParentPIDKey = attribute.Key("process.parent_pid") + + // ProcessExecutableNameKey is the attribute Key conforming to the + // "process.executable.name" semantic conventions. It represents the name + // of the process executable. On Linux based systems, can be set to the + // `Name` in `proc/[pid]/status`. On Windows, can be set to the base name + // of `GetProcessImageFileNameW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'otelcol' + ProcessExecutableNameKey = attribute.Key("process.executable.name") + + // ProcessExecutablePathKey is the attribute Key conforming to the + // "process.executable.path" semantic conventions. It represents the full + // path to the process executable. On Linux based systems, can be set to + // the target of `proc/[pid]/exe`. On Windows, can be set to the result of + // `GetProcessImageFileNameW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: '/usr/bin/cmd/otelcol' + ProcessExecutablePathKey = attribute.Key("process.executable.path") + + // ProcessCommandKey is the attribute Key conforming to the + // "process.command" semantic conventions. It represents the command used + // to launch the process (i.e. the command name). On Linux based systems, + // can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can + // be set to the first parameter extracted from `GetCommandLineW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'cmd/otelcol' + ProcessCommandKey = attribute.Key("process.command") + + // ProcessCommandLineKey is the attribute Key conforming to the + // "process.command_line" semantic conventions. It represents the full + // command used to launch the process as a single string representing the + // full command. On Windows, can be set to the result of `GetCommandLineW`. + // Do not set this if you have to assemble it just for monitoring; use + // `process.command_args` instead. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"' + ProcessCommandLineKey = attribute.Key("process.command_line") + + // ProcessCommandArgsKey is the attribute Key conforming to the + // "process.command_args" semantic conventions. It represents the all the + // command arguments (including the command/executable itself) as received + // by the process. On Linux-based systems (and some other Unixoid systems + // supporting procfs), can be set according to the list of null-delimited + // strings extracted from `proc/[pid]/cmdline`. For libc-based executables, + // this would be the full argv vector passed to `main`. + // + // Type: string[] + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'cmd/otecol', '--config=config.yaml' + ProcessCommandArgsKey = attribute.Key("process.command_args") + + // ProcessOwnerKey is the attribute Key conforming to the "process.owner" + // semantic conventions. It represents the username of the user that owns + // the process. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'root' + ProcessOwnerKey = attribute.Key("process.owner") +) + +// ProcessPID returns an attribute KeyValue conforming to the "process.pid" +// semantic conventions. It represents the process identifier (PID). +func ProcessPID(val int) attribute.KeyValue { + return ProcessPIDKey.Int(val) +} + +// ProcessParentPID returns an attribute KeyValue conforming to the +// "process.parent_pid" semantic conventions. It represents the parent Process +// identifier (PID). +func ProcessParentPID(val int) attribute.KeyValue { + return ProcessParentPIDKey.Int(val) +} + +// ProcessExecutableName returns an attribute KeyValue conforming to the +// "process.executable.name" semantic conventions. It represents the name of +// the process executable. On Linux based systems, can be set to the `Name` in +// `proc/[pid]/status`. On Windows, can be set to the base name of +// `GetProcessImageFileNameW`. +func ProcessExecutableName(val string) attribute.KeyValue { + return ProcessExecutableNameKey.String(val) +} + +// ProcessExecutablePath returns an attribute KeyValue conforming to the +// "process.executable.path" semantic conventions. It represents the full path +// to the process executable. On Linux based systems, can be set to the target +// of `proc/[pid]/exe`. On Windows, can be set to the result of +// `GetProcessImageFileNameW`. +func ProcessExecutablePath(val string) attribute.KeyValue { + return ProcessExecutablePathKey.String(val) +} + +// ProcessCommand returns an attribute KeyValue conforming to the +// "process.command" semantic conventions. It represents the command used to +// launch the process (i.e. the command name). On Linux based systems, can be +// set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to +// the first parameter extracted from `GetCommandLineW`. +func ProcessCommand(val string) attribute.KeyValue { + return ProcessCommandKey.String(val) +} + +// ProcessCommandLine returns an attribute KeyValue conforming to the +// "process.command_line" semantic conventions. It represents the full command +// used to launch the process as a single string representing the full command. +// On Windows, can be set to the result of `GetCommandLineW`. Do not set this +// if you have to assemble it just for monitoring; use `process.command_args` +// instead. +func ProcessCommandLine(val string) attribute.KeyValue { + return ProcessCommandLineKey.String(val) +} + +// ProcessCommandArgs returns an attribute KeyValue conforming to the +// "process.command_args" semantic conventions. It represents the all the +// command arguments (including the command/executable itself) as received by +// the process. On Linux-based systems (and some other Unixoid systems +// supporting procfs), can be set according to the list of null-delimited +// strings extracted from `proc/[pid]/cmdline`. For libc-based executables, +// this would be the full argv vector passed to `main`. +func ProcessCommandArgs(val ...string) attribute.KeyValue { + return ProcessCommandArgsKey.StringSlice(val) +} + +// ProcessOwner returns an attribute KeyValue conforming to the +// "process.owner" semantic conventions. It represents the username of the user +// that owns the process. +func ProcessOwner(val string) attribute.KeyValue { + return ProcessOwnerKey.String(val) +} + +// The single (language) runtime instance which is monitored. +const ( + // ProcessRuntimeNameKey is the attribute Key conforming to the + // "process.runtime.name" semantic conventions. It represents the name of + // the runtime of this process. For compiled native binaries, this SHOULD + // be the name of the compiler. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'OpenJDK Runtime Environment' + ProcessRuntimeNameKey = attribute.Key("process.runtime.name") + + // ProcessRuntimeVersionKey is the attribute Key conforming to the + // "process.runtime.version" semantic conventions. It represents the + // version of the runtime of this process, as returned by the runtime + // without modification. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '14.0.2' + ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") + + // ProcessRuntimeDescriptionKey is the attribute Key conforming to the + // "process.runtime.description" semantic conventions. It represents an + // additional description about the runtime of the process, for example a + // specific vendor customization of the runtime environment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' + ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") +) + +// ProcessRuntimeName returns an attribute KeyValue conforming to the +// "process.runtime.name" semantic conventions. It represents the name of the +// runtime of this process. For compiled native binaries, this SHOULD be the +// name of the compiler. +func ProcessRuntimeName(val string) attribute.KeyValue { + return ProcessRuntimeNameKey.String(val) +} + +// ProcessRuntimeVersion returns an attribute KeyValue conforming to the +// "process.runtime.version" semantic conventions. It represents the version of +// the runtime of this process, as returned by the runtime without +// modification. +func ProcessRuntimeVersion(val string) attribute.KeyValue { + return ProcessRuntimeVersionKey.String(val) +} + +// ProcessRuntimeDescription returns an attribute KeyValue conforming to the +// "process.runtime.description" semantic conventions. It represents an +// additional description about the runtime of the process, for example a +// specific vendor customization of the runtime environment. +func ProcessRuntimeDescription(val string) attribute.KeyValue { + return ProcessRuntimeDescriptionKey.String(val) +} + +// A service instance. +const ( + // ServiceNameKey is the attribute Key conforming to the "service.name" + // semantic conventions. It represents the logical name of the service. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'shoppingcart' + // Note: MUST be the same for all instances of horizontally scaled + // services. If the value was not specified, SDKs MUST fallback to + // `unknown_service:` concatenated with + // [`process.executable.name`](process.md#process), e.g. + // `unknown_service:bash`. If `process.executable.name` is not available, + // the value MUST be set to `unknown_service`. + ServiceNameKey = attribute.Key("service.name") + + // ServiceNamespaceKey is the attribute Key conforming to the + // "service.namespace" semantic conventions. It represents a namespace for + // `service.name`. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Shop' + // Note: A string value having a meaning that helps to distinguish a group + // of services, for example the team name that owns a group of services. + // `service.name` is expected to be unique within the same namespace. If + // `service.namespace` is not specified in the Resource then `service.name` + // is expected to be unique for all services that have no explicit + // namespace defined (so the empty/unspecified namespace is simply one more + // valid namespace). Zero-length namespace string is assumed equal to + // unspecified namespace. + ServiceNamespaceKey = attribute.Key("service.namespace") + + // ServiceInstanceIDKey is the attribute Key conforming to the + // "service.instance.id" semantic conventions. It represents the string ID + // of the service instance. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '627cc493-f310-47de-96bd-71410b7dec09' + // Note: MUST be unique for each instance of the same + // `service.namespace,service.name` pair (in other words + // `service.namespace,service.name,service.instance.id` triplet MUST be + // globally unique). The ID helps to distinguish instances of the same + // service that exist at the same time (e.g. instances of a horizontally + // scaled service). It is preferable for the ID to be persistent and stay + // the same for the lifetime of the service instance, however it is + // acceptable that the ID is ephemeral and changes during important + // lifetime events for the service (e.g. service restarts). If the service + // has no inherent unique ID that can be used as the value of this + // attribute it is recommended to generate a random Version 1 or Version 4 + // RFC 4122 UUID (services aiming for reproducible UUIDs may also use + // Version 5, see RFC 4122 for more recommendations). + ServiceInstanceIDKey = attribute.Key("service.instance.id") + + // ServiceVersionKey is the attribute Key conforming to the + // "service.version" semantic conventions. It represents the version string + // of the service API or implementation. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2.0.0' + ServiceVersionKey = attribute.Key("service.version") +) + +// ServiceName returns an attribute KeyValue conforming to the +// "service.name" semantic conventions. It represents the logical name of the +// service. +func ServiceName(val string) attribute.KeyValue { + return ServiceNameKey.String(val) +} + +// ServiceNamespace returns an attribute KeyValue conforming to the +// "service.namespace" semantic conventions. It represents a namespace for +// `service.name`. +func ServiceNamespace(val string) attribute.KeyValue { + return ServiceNamespaceKey.String(val) +} + +// ServiceInstanceID returns an attribute KeyValue conforming to the +// "service.instance.id" semantic conventions. It represents the string ID of +// the service instance. +func ServiceInstanceID(val string) attribute.KeyValue { + return ServiceInstanceIDKey.String(val) +} + +// ServiceVersion returns an attribute KeyValue conforming to the +// "service.version" semantic conventions. It represents the version string of +// the service API or implementation. +func ServiceVersion(val string) attribute.KeyValue { + return ServiceVersionKey.String(val) +} + +// The telemetry SDK used to capture data recorded by the instrumentation +// libraries. +const ( + // TelemetrySDKNameKey is the attribute Key conforming to the + // "telemetry.sdk.name" semantic conventions. It represents the name of the + // telemetry SDK as defined above. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") + + // TelemetrySDKLanguageKey is the attribute Key conforming to the + // "telemetry.sdk.language" semantic conventions. It represents the + // language of the telemetry SDK. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") + + // TelemetrySDKVersionKey is the attribute Key conforming to the + // "telemetry.sdk.version" semantic conventions. It represents the version + // string of the telemetry SDK. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.2.3' + TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") + + // TelemetryAutoVersionKey is the attribute Key conforming to the + // "telemetry.auto.version" semantic conventions. It represents the version + // string of the auto instrumentation agent, if used. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.2.3' + TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version") +) + +var ( + // cpp + TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp") + // dotnet + TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet") + // erlang + TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang") + // go + TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go") + // java + TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java") + // nodejs + TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs") + // php + TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php") + // python + TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python") + // ruby + TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby") + // webjs + TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs") + // swift + TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift") +) + +// TelemetrySDKName returns an attribute KeyValue conforming to the +// "telemetry.sdk.name" semantic conventions. It represents the name of the +// telemetry SDK as defined above. +func TelemetrySDKName(val string) attribute.KeyValue { + return TelemetrySDKNameKey.String(val) +} + +// TelemetrySDKVersion returns an attribute KeyValue conforming to the +// "telemetry.sdk.version" semantic conventions. It represents the version +// string of the telemetry SDK. +func TelemetrySDKVersion(val string) attribute.KeyValue { + return TelemetrySDKVersionKey.String(val) +} + +// TelemetryAutoVersion returns an attribute KeyValue conforming to the +// "telemetry.auto.version" semantic conventions. It represents the version +// string of the auto instrumentation agent, if used. +func TelemetryAutoVersion(val string) attribute.KeyValue { + return TelemetryAutoVersionKey.String(val) +} + +// Resource describing the packaged software running the application code. Web +// engines are typically executed using process.runtime. +const ( + // WebEngineNameKey is the attribute Key conforming to the "webengine.name" + // semantic conventions. It represents the name of the web engine. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'WildFly' + WebEngineNameKey = attribute.Key("webengine.name") + + // WebEngineVersionKey is the attribute Key conforming to the + // "webengine.version" semantic conventions. It represents the version of + // the web engine. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '21.0.0' + WebEngineVersionKey = attribute.Key("webengine.version") + + // WebEngineDescriptionKey is the attribute Key conforming to the + // "webengine.description" semantic conventions. It represents the + // additional description of the web engine (e.g. detailed version and + // edition information). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - + // 2.2.2.Final' + WebEngineDescriptionKey = attribute.Key("webengine.description") +) + +// WebEngineName returns an attribute KeyValue conforming to the +// "webengine.name" semantic conventions. It represents the name of the web +// engine. +func WebEngineName(val string) attribute.KeyValue { + return WebEngineNameKey.String(val) +} + +// WebEngineVersion returns an attribute KeyValue conforming to the +// "webengine.version" semantic conventions. It represents the version of the +// web engine. +func WebEngineVersion(val string) attribute.KeyValue { + return WebEngineVersionKey.String(val) +} + +// WebEngineDescription returns an attribute KeyValue conforming to the +// "webengine.description" semantic conventions. It represents the additional +// description of the web engine (e.g. detailed version and edition +// information). +func WebEngineDescription(val string) attribute.KeyValue { + return WebEngineDescriptionKey.String(val) +} + +// Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's +// concepts. +const ( + // OtelScopeNameKey is the attribute Key conforming to the + // "otel.scope.name" semantic conventions. It represents the name of the + // instrumentation scope - (`InstrumentationScope.Name` in OTLP). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'io.opentelemetry.contrib.mongodb' + OtelScopeNameKey = attribute.Key("otel.scope.name") + + // OtelScopeVersionKey is the attribute Key conforming to the + // "otel.scope.version" semantic conventions. It represents the version of + // the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.0.0' + OtelScopeVersionKey = attribute.Key("otel.scope.version") +) + +// OtelScopeName returns an attribute KeyValue conforming to the +// "otel.scope.name" semantic conventions. It represents the name of the +// instrumentation scope - (`InstrumentationScope.Name` in OTLP). +func OtelScopeName(val string) attribute.KeyValue { + return OtelScopeNameKey.String(val) +} + +// OtelScopeVersion returns an attribute KeyValue conforming to the +// "otel.scope.version" semantic conventions. It represents the version of the +// instrumentation scope - (`InstrumentationScope.Version` in OTLP). +func OtelScopeVersion(val string) attribute.KeyValue { + return OtelScopeVersionKey.String(val) +} + +// Span attributes used by non-OTLP exporters to represent OpenTelemetry +// Scope's concepts. +const ( + // OtelLibraryNameKey is the attribute Key conforming to the + // "otel.library.name" semantic conventions. It represents the deprecated, + // use the `otel.scope.name` attribute. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'io.opentelemetry.contrib.mongodb' + OtelLibraryNameKey = attribute.Key("otel.library.name") + + // OtelLibraryVersionKey is the attribute Key conforming to the + // "otel.library.version" semantic conventions. It represents the + // deprecated, use the `otel.scope.version` attribute. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '1.0.0' + OtelLibraryVersionKey = attribute.Key("otel.library.version") +) + +// OtelLibraryName returns an attribute KeyValue conforming to the +// "otel.library.name" semantic conventions. It represents the deprecated, use +// the `otel.scope.name` attribute. +func OtelLibraryName(val string) attribute.KeyValue { + return OtelLibraryNameKey.String(val) +} + +// OtelLibraryVersion returns an attribute KeyValue conforming to the +// "otel.library.version" semantic conventions. It represents the deprecated, +// use the `otel.scope.version` attribute. +func OtelLibraryVersion(val string) attribute.KeyValue { + return OtelLibraryVersionKey.String(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go new file mode 100644 index 00000000000..42fc525d165 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +// SchemaURL is the schema URL that matches the version of the semantic conventions +// that this package defines. Semconv packages starting from v1.4.0 must declare +// non-empty schema URL in the form https://opentelemetry.io/schemas/ +const SchemaURL = "https://opentelemetry.io/schemas/1.17.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go new file mode 100644 index 00000000000..8c4a7299d27 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go @@ -0,0 +1,3375 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0" + +import "go.opentelemetry.io/otel/attribute" + +// The shared attributes used to report a single exception associated with a +// span or log. +const ( + // ExceptionTypeKey is the attribute Key conforming to the "exception.type" + // semantic conventions. It represents the type of the exception (its + // fully-qualified class name, if applicable). The dynamic type of the + // exception should be preferred over the static type in languages that + // support it. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'java.net.ConnectException', 'OSError' + ExceptionTypeKey = attribute.Key("exception.type") + + // ExceptionMessageKey is the attribute Key conforming to the + // "exception.message" semantic conventions. It represents the exception + // message. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Division by zero', "Can't convert 'int' object to str + // implicitly" + ExceptionMessageKey = attribute.Key("exception.message") + + // ExceptionStacktraceKey is the attribute Key conforming to the + // "exception.stacktrace" semantic conventions. It represents a stacktrace + // as a string in the natural representation for the language runtime. The + // representation is to be determined and documented by each language SIG. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Exception in thread "main" java.lang.RuntimeException: Test + // exception\\n at ' + // 'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at ' + // 'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at ' + // 'com.example.GenerateTrace.main(GenerateTrace.java:5)' + ExceptionStacktraceKey = attribute.Key("exception.stacktrace") +) + +// ExceptionType returns an attribute KeyValue conforming to the +// "exception.type" semantic conventions. It represents the type of the +// exception (its fully-qualified class name, if applicable). The dynamic type +// of the exception should be preferred over the static type in languages that +// support it. +func ExceptionType(val string) attribute.KeyValue { + return ExceptionTypeKey.String(val) +} + +// ExceptionMessage returns an attribute KeyValue conforming to the +// "exception.message" semantic conventions. It represents the exception +// message. +func ExceptionMessage(val string) attribute.KeyValue { + return ExceptionMessageKey.String(val) +} + +// ExceptionStacktrace returns an attribute KeyValue conforming to the +// "exception.stacktrace" semantic conventions. It represents a stacktrace as a +// string in the natural representation for the language runtime. The +// representation is to be determined and documented by each language SIG. +func ExceptionStacktrace(val string) attribute.KeyValue { + return ExceptionStacktraceKey.String(val) +} + +// Attributes for Events represented using Log Records. +const ( + // EventNameKey is the attribute Key conforming to the "event.name" + // semantic conventions. It represents the name identifies the event. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'click', 'exception' + EventNameKey = attribute.Key("event.name") + + // EventDomainKey is the attribute Key conforming to the "event.domain" + // semantic conventions. It represents the domain identifies the business + // context for the events. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: Events across different domains may have same `event.name`, yet be + // unrelated events. + EventDomainKey = attribute.Key("event.domain") +) + +var ( + // Events from browser apps + EventDomainBrowser = EventDomainKey.String("browser") + // Events from mobile apps + EventDomainDevice = EventDomainKey.String("device") + // Events from Kubernetes + EventDomainK8S = EventDomainKey.String("k8s") +) + +// EventName returns an attribute KeyValue conforming to the "event.name" +// semantic conventions. It represents the name identifies the event. +func EventName(val string) attribute.KeyValue { + return EventNameKey.String(val) +} + +// Span attributes used by AWS Lambda (in addition to general `faas` +// attributes). +const ( + // AWSLambdaInvokedARNKey is the attribute Key conforming to the + // "aws.lambda.invoked_arn" semantic conventions. It represents the full + // invoked ARN as provided on the `Context` passed to the function + // (`Lambda-Runtime-Invoked-Function-ARN` header on the + // `/runtime/invocation/next` applicable). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias' + // Note: This may be different from `faas.id` if an alias is involved. + AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn") +) + +// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the +// "aws.lambda.invoked_arn" semantic conventions. It represents the full +// invoked ARN as provided on the `Context` passed to the function +// (`Lambda-Runtime-Invoked-Function-ARN` header on the +// `/runtime/invocation/next` applicable). +func AWSLambdaInvokedARN(val string) attribute.KeyValue { + return AWSLambdaInvokedARNKey.String(val) +} + +// Attributes for CloudEvents. CloudEvents is a specification on how to define +// event data in a standard way. These attributes can be attached to spans when +// performing operations with CloudEvents, regardless of the protocol being +// used. +const ( + // CloudeventsEventIDKey is the attribute Key conforming to the + // "cloudevents.event_id" semantic conventions. It represents the + // [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) + // uniquely identifies the event. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: '123e4567-e89b-12d3-a456-426614174000', '0001' + CloudeventsEventIDKey = attribute.Key("cloudevents.event_id") + + // CloudeventsEventSourceKey is the attribute Key conforming to the + // "cloudevents.event_source" semantic conventions. It represents the + // [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) + // identifies the context in which an event happened. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'https://github.com/cloudevents', + // '/cloudevents/spec/pull/123', 'my-service' + CloudeventsEventSourceKey = attribute.Key("cloudevents.event_source") + + // CloudeventsEventSpecVersionKey is the attribute Key conforming to the + // "cloudevents.event_spec_version" semantic conventions. It represents the + // [version of the CloudEvents + // specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) + // which the event uses. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.0' + CloudeventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version") + + // CloudeventsEventTypeKey is the attribute Key conforming to the + // "cloudevents.event_type" semantic conventions. It represents the + // [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) + // contains a value describing the type of event related to the originating + // occurrence. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'com.github.pull_request.opened', + // 'com.example.object.deleted.v2' + CloudeventsEventTypeKey = attribute.Key("cloudevents.event_type") + + // CloudeventsEventSubjectKey is the attribute Key conforming to the + // "cloudevents.event_subject" semantic conventions. It represents the + // [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) + // of the event in the context of the event producer (identified by + // source). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'mynewfile.jpg' + CloudeventsEventSubjectKey = attribute.Key("cloudevents.event_subject") +) + +// CloudeventsEventID returns an attribute KeyValue conforming to the +// "cloudevents.event_id" semantic conventions. It represents the +// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) +// uniquely identifies the event. +func CloudeventsEventID(val string) attribute.KeyValue { + return CloudeventsEventIDKey.String(val) +} + +// CloudeventsEventSource returns an attribute KeyValue conforming to the +// "cloudevents.event_source" semantic conventions. It represents the +// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) +// identifies the context in which an event happened. +func CloudeventsEventSource(val string) attribute.KeyValue { + return CloudeventsEventSourceKey.String(val) +} + +// CloudeventsEventSpecVersion returns an attribute KeyValue conforming to +// the "cloudevents.event_spec_version" semantic conventions. It represents the +// [version of the CloudEvents +// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) +// which the event uses. +func CloudeventsEventSpecVersion(val string) attribute.KeyValue { + return CloudeventsEventSpecVersionKey.String(val) +} + +// CloudeventsEventType returns an attribute KeyValue conforming to the +// "cloudevents.event_type" semantic conventions. It represents the +// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) +// contains a value describing the type of event related to the originating +// occurrence. +func CloudeventsEventType(val string) attribute.KeyValue { + return CloudeventsEventTypeKey.String(val) +} + +// CloudeventsEventSubject returns an attribute KeyValue conforming to the +// "cloudevents.event_subject" semantic conventions. It represents the +// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) +// of the event in the context of the event producer (identified by source). +func CloudeventsEventSubject(val string) attribute.KeyValue { + return CloudeventsEventSubjectKey.String(val) +} + +// Semantic conventions for the OpenTracing Shim +const ( + // OpentracingRefTypeKey is the attribute Key conforming to the + // "opentracing.ref_type" semantic conventions. It represents the + // parent-child Reference type + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: The causal relationship between a child Span and a parent Span. + OpentracingRefTypeKey = attribute.Key("opentracing.ref_type") +) + +var ( + // The parent Span depends on the child Span in some capacity + OpentracingRefTypeChildOf = OpentracingRefTypeKey.String("child_of") + // The parent Span does not depend in any way on the result of the child Span + OpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String("follows_from") +) + +// The attributes used to perform database client calls. +const ( + // DBSystemKey is the attribute Key conforming to the "db.system" semantic + // conventions. It represents an identifier for the database management + // system (DBMS) product being used. See below for a list of well-known + // identifiers. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + DBSystemKey = attribute.Key("db.system") + + // DBConnectionStringKey is the attribute Key conforming to the + // "db.connection_string" semantic conventions. It represents the + // connection string used to connect to the database. It is recommended to + // remove embedded credentials. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;' + DBConnectionStringKey = attribute.Key("db.connection_string") + + // DBUserKey is the attribute Key conforming to the "db.user" semantic + // conventions. It represents the username for accessing the database. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'readonly_user', 'reporting_user' + DBUserKey = attribute.Key("db.user") + + // DBJDBCDriverClassnameKey is the attribute Key conforming to the + // "db.jdbc.driver_classname" semantic conventions. It represents the + // fully-qualified class name of the [Java Database Connectivity + // (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) + // driver used to connect. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'org.postgresql.Driver', + // 'com.microsoft.sqlserver.jdbc.SQLServerDriver' + DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname") + + // DBNameKey is the attribute Key conforming to the "db.name" semantic + // conventions. It represents the this attribute is used to report the name + // of the database being accessed. For commands that switch the database, + // this should be set to the target database (even if the command fails). + // + // Type: string + // RequirementLevel: ConditionallyRequired (If applicable.) + // Stability: stable + // Examples: 'customers', 'main' + // Note: In some SQL databases, the database name to be used is called + // "schema name". In case there are multiple layers that could be + // considered for database name (e.g. Oracle instance name and schema + // name), the database name to be used is the more specific layer (e.g. + // Oracle schema name). + DBNameKey = attribute.Key("db.name") + + // DBStatementKey is the attribute Key conforming to the "db.statement" + // semantic conventions. It represents the database statement being + // executed. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If applicable and not + // explicitly disabled via instrumentation configuration.) + // Stability: stable + // Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"' + // Note: The value may be sanitized to exclude sensitive information. + DBStatementKey = attribute.Key("db.statement") + + // DBOperationKey is the attribute Key conforming to the "db.operation" + // semantic conventions. It represents the name of the operation being + // executed, e.g. the [MongoDB command + // name](https://docs.mongodb.com/manual/reference/command/#database-operations) + // such as `findAndModify`, or the SQL keyword. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If `db.statement` is not + // applicable.) + // Stability: stable + // Examples: 'findAndModify', 'HMSET', 'SELECT' + // Note: When setting this to an SQL keyword, it is not recommended to + // attempt any client-side parsing of `db.statement` just to get this + // property, but it should be set if the operation name is provided by the + // library being instrumented. If the SQL statement has an ambiguous + // operation, or performs more than one operation, this value may be + // omitted. + DBOperationKey = attribute.Key("db.operation") +) + +var ( + // Some other SQL database. Fallback only. See notes + DBSystemOtherSQL = DBSystemKey.String("other_sql") + // Microsoft SQL Server + DBSystemMSSQL = DBSystemKey.String("mssql") + // MySQL + DBSystemMySQL = DBSystemKey.String("mysql") + // Oracle Database + DBSystemOracle = DBSystemKey.String("oracle") + // IBM DB2 + DBSystemDB2 = DBSystemKey.String("db2") + // PostgreSQL + DBSystemPostgreSQL = DBSystemKey.String("postgresql") + // Amazon Redshift + DBSystemRedshift = DBSystemKey.String("redshift") + // Apache Hive + DBSystemHive = DBSystemKey.String("hive") + // Cloudscape + DBSystemCloudscape = DBSystemKey.String("cloudscape") + // HyperSQL DataBase + DBSystemHSQLDB = DBSystemKey.String("hsqldb") + // Progress Database + DBSystemProgress = DBSystemKey.String("progress") + // SAP MaxDB + DBSystemMaxDB = DBSystemKey.String("maxdb") + // SAP HANA + DBSystemHanaDB = DBSystemKey.String("hanadb") + // Ingres + DBSystemIngres = DBSystemKey.String("ingres") + // FirstSQL + DBSystemFirstSQL = DBSystemKey.String("firstsql") + // EnterpriseDB + DBSystemEDB = DBSystemKey.String("edb") + // InterSystems Caché + DBSystemCache = DBSystemKey.String("cache") + // Adabas (Adaptable Database System) + DBSystemAdabas = DBSystemKey.String("adabas") + // Firebird + DBSystemFirebird = DBSystemKey.String("firebird") + // Apache Derby + DBSystemDerby = DBSystemKey.String("derby") + // FileMaker + DBSystemFilemaker = DBSystemKey.String("filemaker") + // Informix + DBSystemInformix = DBSystemKey.String("informix") + // InstantDB + DBSystemInstantDB = DBSystemKey.String("instantdb") + // InterBase + DBSystemInterbase = DBSystemKey.String("interbase") + // MariaDB + DBSystemMariaDB = DBSystemKey.String("mariadb") + // Netezza + DBSystemNetezza = DBSystemKey.String("netezza") + // Pervasive PSQL + DBSystemPervasive = DBSystemKey.String("pervasive") + // PointBase + DBSystemPointbase = DBSystemKey.String("pointbase") + // SQLite + DBSystemSqlite = DBSystemKey.String("sqlite") + // Sybase + DBSystemSybase = DBSystemKey.String("sybase") + // Teradata + DBSystemTeradata = DBSystemKey.String("teradata") + // Vertica + DBSystemVertica = DBSystemKey.String("vertica") + // H2 + DBSystemH2 = DBSystemKey.String("h2") + // ColdFusion IMQ + DBSystemColdfusion = DBSystemKey.String("coldfusion") + // Apache Cassandra + DBSystemCassandra = DBSystemKey.String("cassandra") + // Apache HBase + DBSystemHBase = DBSystemKey.String("hbase") + // MongoDB + DBSystemMongoDB = DBSystemKey.String("mongodb") + // Redis + DBSystemRedis = DBSystemKey.String("redis") + // Couchbase + DBSystemCouchbase = DBSystemKey.String("couchbase") + // CouchDB + DBSystemCouchDB = DBSystemKey.String("couchdb") + // Microsoft Azure Cosmos DB + DBSystemCosmosDB = DBSystemKey.String("cosmosdb") + // Amazon DynamoDB + DBSystemDynamoDB = DBSystemKey.String("dynamodb") + // Neo4j + DBSystemNeo4j = DBSystemKey.String("neo4j") + // Apache Geode + DBSystemGeode = DBSystemKey.String("geode") + // Elasticsearch + DBSystemElasticsearch = DBSystemKey.String("elasticsearch") + // Memcached + DBSystemMemcached = DBSystemKey.String("memcached") + // CockroachDB + DBSystemCockroachdb = DBSystemKey.String("cockroachdb") + // OpenSearch + DBSystemOpensearch = DBSystemKey.String("opensearch") + // ClickHouse + DBSystemClickhouse = DBSystemKey.String("clickhouse") +) + +// DBConnectionString returns an attribute KeyValue conforming to the +// "db.connection_string" semantic conventions. It represents the connection +// string used to connect to the database. It is recommended to remove embedded +// credentials. +func DBConnectionString(val string) attribute.KeyValue { + return DBConnectionStringKey.String(val) +} + +// DBUser returns an attribute KeyValue conforming to the "db.user" semantic +// conventions. It represents the username for accessing the database. +func DBUser(val string) attribute.KeyValue { + return DBUserKey.String(val) +} + +// DBJDBCDriverClassname returns an attribute KeyValue conforming to the +// "db.jdbc.driver_classname" semantic conventions. It represents the +// fully-qualified class name of the [Java Database Connectivity +// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver +// used to connect. +func DBJDBCDriverClassname(val string) attribute.KeyValue { + return DBJDBCDriverClassnameKey.String(val) +} + +// DBName returns an attribute KeyValue conforming to the "db.name" semantic +// conventions. It represents the this attribute is used to report the name of +// the database being accessed. For commands that switch the database, this +// should be set to the target database (even if the command fails). +func DBName(val string) attribute.KeyValue { + return DBNameKey.String(val) +} + +// DBStatement returns an attribute KeyValue conforming to the +// "db.statement" semantic conventions. It represents the database statement +// being executed. +func DBStatement(val string) attribute.KeyValue { + return DBStatementKey.String(val) +} + +// DBOperation returns an attribute KeyValue conforming to the +// "db.operation" semantic conventions. It represents the name of the operation +// being executed, e.g. the [MongoDB command +// name](https://docs.mongodb.com/manual/reference/command/#database-operations) +// such as `findAndModify`, or the SQL keyword. +func DBOperation(val string) attribute.KeyValue { + return DBOperationKey.String(val) +} + +// Connection-level attributes for Microsoft SQL Server +const ( + // DBMSSQLInstanceNameKey is the attribute Key conforming to the + // "db.mssql.instance_name" semantic conventions. It represents the + // Microsoft SQL Server [instance + // name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + // connecting to. This name is used to determine the port of a named + // instance. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MSSQLSERVER' + // Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no + // longer required (but still recommended if non-standard). + DBMSSQLInstanceNameKey = attribute.Key("db.mssql.instance_name") +) + +// DBMSSQLInstanceName returns an attribute KeyValue conforming to the +// "db.mssql.instance_name" semantic conventions. It represents the Microsoft +// SQL Server [instance +// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) +// connecting to. This name is used to determine the port of a named instance. +func DBMSSQLInstanceName(val string) attribute.KeyValue { + return DBMSSQLInstanceNameKey.String(val) +} + +// Call-level attributes for Cassandra +const ( + // DBCassandraPageSizeKey is the attribute Key conforming to the + // "db.cassandra.page_size" semantic conventions. It represents the fetch + // size used for paging, i.e. how many rows will be returned at once. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 5000 + DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size") + + // DBCassandraConsistencyLevelKey is the attribute Key conforming to the + // "db.cassandra.consistency_level" semantic conventions. It represents the + // consistency level of the query. Based on consistency values from + // [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level") + + // DBCassandraTableKey is the attribute Key conforming to the + // "db.cassandra.table" semantic conventions. It represents the name of the + // primary table that the operation is acting upon, including the keyspace + // name (if applicable). + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'mytable' + // Note: This mirrors the db.sql.table attribute but references cassandra + // rather than sql. It is not recommended to attempt any client-side + // parsing of `db.statement` just to get this property, but it should be + // set if it is provided by the library being instrumented. If the + // operation is acting upon an anonymous table, or more than one table, + // this value MUST NOT be set. + DBCassandraTableKey = attribute.Key("db.cassandra.table") + + // DBCassandraIdempotenceKey is the attribute Key conforming to the + // "db.cassandra.idempotence" semantic conventions. It represents the + // whether or not the query is idempotent. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence") + + // DBCassandraSpeculativeExecutionCountKey is the attribute Key conforming + // to the "db.cassandra.speculative_execution_count" semantic conventions. + // It represents the number of times a query was speculatively executed. + // Not set or `0` if the query was not executed speculatively. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 0, 2 + DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count") + + // DBCassandraCoordinatorIDKey is the attribute Key conforming to the + // "db.cassandra.coordinator.id" semantic conventions. It represents the ID + // of the coordinating node for a query. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id") + + // DBCassandraCoordinatorDCKey is the attribute Key conforming to the + // "db.cassandra.coordinator.dc" semantic conventions. It represents the + // data center of the coordinating node for a query. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-west-2' + DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc") +) + +var ( + // all + DBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String("all") + // each_quorum + DBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String("each_quorum") + // quorum + DBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String("quorum") + // local_quorum + DBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String("local_quorum") + // one + DBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String("one") + // two + DBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String("two") + // three + DBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String("three") + // local_one + DBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String("local_one") + // any + DBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String("any") + // serial + DBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String("serial") + // local_serial + DBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String("local_serial") +) + +// DBCassandraPageSize returns an attribute KeyValue conforming to the +// "db.cassandra.page_size" semantic conventions. It represents the fetch size +// used for paging, i.e. how many rows will be returned at once. +func DBCassandraPageSize(val int) attribute.KeyValue { + return DBCassandraPageSizeKey.Int(val) +} + +// DBCassandraTable returns an attribute KeyValue conforming to the +// "db.cassandra.table" semantic conventions. It represents the name of the +// primary table that the operation is acting upon, including the keyspace name +// (if applicable). +func DBCassandraTable(val string) attribute.KeyValue { + return DBCassandraTableKey.String(val) +} + +// DBCassandraIdempotence returns an attribute KeyValue conforming to the +// "db.cassandra.idempotence" semantic conventions. It represents the whether +// or not the query is idempotent. +func DBCassandraIdempotence(val bool) attribute.KeyValue { + return DBCassandraIdempotenceKey.Bool(val) +} + +// DBCassandraSpeculativeExecutionCount returns an attribute KeyValue +// conforming to the "db.cassandra.speculative_execution_count" semantic +// conventions. It represents the number of times a query was speculatively +// executed. Not set or `0` if the query was not executed speculatively. +func DBCassandraSpeculativeExecutionCount(val int) attribute.KeyValue { + return DBCassandraSpeculativeExecutionCountKey.Int(val) +} + +// DBCassandraCoordinatorID returns an attribute KeyValue conforming to the +// "db.cassandra.coordinator.id" semantic conventions. It represents the ID of +// the coordinating node for a query. +func DBCassandraCoordinatorID(val string) attribute.KeyValue { + return DBCassandraCoordinatorIDKey.String(val) +} + +// DBCassandraCoordinatorDC returns an attribute KeyValue conforming to the +// "db.cassandra.coordinator.dc" semantic conventions. It represents the data +// center of the coordinating node for a query. +func DBCassandraCoordinatorDC(val string) attribute.KeyValue { + return DBCassandraCoordinatorDCKey.String(val) +} + +// Call-level attributes for Redis +const ( + // DBRedisDBIndexKey is the attribute Key conforming to the + // "db.redis.database_index" semantic conventions. It represents the index + // of the database being accessed as used in the [`SELECT` + // command](https://redis.io/commands/select), provided as an integer. To + // be used instead of the generic `db.name` attribute. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If other than the default + // database (`0`).) + // Stability: stable + // Examples: 0, 1, 15 + DBRedisDBIndexKey = attribute.Key("db.redis.database_index") +) + +// DBRedisDBIndex returns an attribute KeyValue conforming to the +// "db.redis.database_index" semantic conventions. It represents the index of +// the database being accessed as used in the [`SELECT` +// command](https://redis.io/commands/select), provided as an integer. To be +// used instead of the generic `db.name` attribute. +func DBRedisDBIndex(val int) attribute.KeyValue { + return DBRedisDBIndexKey.Int(val) +} + +// Call-level attributes for MongoDB +const ( + // DBMongoDBCollectionKey is the attribute Key conforming to the + // "db.mongodb.collection" semantic conventions. It represents the + // collection being accessed within the database stated in `db.name`. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'customers', 'products' + DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection") +) + +// DBMongoDBCollection returns an attribute KeyValue conforming to the +// "db.mongodb.collection" semantic conventions. It represents the collection +// being accessed within the database stated in `db.name`. +func DBMongoDBCollection(val string) attribute.KeyValue { + return DBMongoDBCollectionKey.String(val) +} + +// Call-level attributes for SQL databases +const ( + // DBSQLTableKey is the attribute Key conforming to the "db.sql.table" + // semantic conventions. It represents the name of the primary table that + // the operation is acting upon, including the database name (if + // applicable). + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'public.users', 'customers' + // Note: It is not recommended to attempt any client-side parsing of + // `db.statement` just to get this property, but it should be set if it is + // provided by the library being instrumented. If the operation is acting + // upon an anonymous table, or more than one table, this value MUST NOT be + // set. + DBSQLTableKey = attribute.Key("db.sql.table") +) + +// DBSQLTable returns an attribute KeyValue conforming to the "db.sql.table" +// semantic conventions. It represents the name of the primary table that the +// operation is acting upon, including the database name (if applicable). +func DBSQLTable(val string) attribute.KeyValue { + return DBSQLTableKey.String(val) +} + +// Span attributes used by non-OTLP exporters to represent OpenTelemetry Span's +// concepts. +const ( + // OtelStatusCodeKey is the attribute Key conforming to the + // "otel.status_code" semantic conventions. It represents the name of the + // code, either "OK" or "ERROR". MUST NOT be set if the status code is + // UNSET. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + OtelStatusCodeKey = attribute.Key("otel.status_code") + + // OtelStatusDescriptionKey is the attribute Key conforming to the + // "otel.status_description" semantic conventions. It represents the + // description of the Status if it has a value, otherwise not set. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'resource not found' + OtelStatusDescriptionKey = attribute.Key("otel.status_description") +) + +var ( + // The operation has been validated by an Application developer or Operator to have completed successfully + OtelStatusCodeOk = OtelStatusCodeKey.String("OK") + // The operation contains an error + OtelStatusCodeError = OtelStatusCodeKey.String("ERROR") +) + +// OtelStatusDescription returns an attribute KeyValue conforming to the +// "otel.status_description" semantic conventions. It represents the +// description of the Status if it has a value, otherwise not set. +func OtelStatusDescription(val string) attribute.KeyValue { + return OtelStatusDescriptionKey.String(val) +} + +// This semantic convention describes an instance of a function that runs +// without provisioning or managing of servers (also known as serverless +// functions or Function as a Service (FaaS)) with spans. +const ( + // FaaSTriggerKey is the attribute Key conforming to the "faas.trigger" + // semantic conventions. It represents the type of the trigger which caused + // this function execution. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: For the server/consumer span on the incoming side, + // `faas.trigger` MUST be set. + // + // Clients invoking FaaS instances usually cannot set `faas.trigger`, + // since they would typically need to look in the payload to determine + // the event type. If clients set it, it should be the same as the + // trigger that corresponding incoming would have (i.e., this has + // nothing to do with the underlying transport used to make the API + // call to invoke the lambda, which is often HTTP). + FaaSTriggerKey = attribute.Key("faas.trigger") + + // FaaSExecutionKey is the attribute Key conforming to the "faas.execution" + // semantic conventions. It represents the execution ID of the current + // function execution. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' + FaaSExecutionKey = attribute.Key("faas.execution") +) + +var ( + // A response to some data source operation such as a database or filesystem read/write + FaaSTriggerDatasource = FaaSTriggerKey.String("datasource") + // To provide an answer to an inbound HTTP request + FaaSTriggerHTTP = FaaSTriggerKey.String("http") + // A function is set to be executed when messages are sent to a messaging system + FaaSTriggerPubsub = FaaSTriggerKey.String("pubsub") + // A function is scheduled to be executed regularly + FaaSTriggerTimer = FaaSTriggerKey.String("timer") + // If none of the others apply + FaaSTriggerOther = FaaSTriggerKey.String("other") +) + +// FaaSExecution returns an attribute KeyValue conforming to the +// "faas.execution" semantic conventions. It represents the execution ID of the +// current function execution. +func FaaSExecution(val string) attribute.KeyValue { + return FaaSExecutionKey.String(val) +} + +// Semantic Convention for FaaS triggered as a response to some data source +// operation such as a database or filesystem read/write. +const ( + // FaaSDocumentCollectionKey is the attribute Key conforming to the + // "faas.document.collection" semantic conventions. It represents the name + // of the source on which the triggering operation was performed. For + // example, in Cloud Storage or S3 corresponds to the bucket name, and in + // Cosmos DB to the database name. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myBucketName', 'myDBName' + FaaSDocumentCollectionKey = attribute.Key("faas.document.collection") + + // FaaSDocumentOperationKey is the attribute Key conforming to the + // "faas.document.operation" semantic conventions. It represents the + // describes the type of the operation that was performed on the data. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + FaaSDocumentOperationKey = attribute.Key("faas.document.operation") + + // FaaSDocumentTimeKey is the attribute Key conforming to the + // "faas.document.time" semantic conventions. It represents a string + // containing the time when the data was accessed in the [ISO + // 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format + // expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2020-01-23T13:47:06Z' + FaaSDocumentTimeKey = attribute.Key("faas.document.time") + + // FaaSDocumentNameKey is the attribute Key conforming to the + // "faas.document.name" semantic conventions. It represents the document + // name/table subjected to the operation. For example, in Cloud Storage or + // S3 is the name of the file, and in Cosmos DB the table name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'myFile.txt', 'myTableName' + FaaSDocumentNameKey = attribute.Key("faas.document.name") +) + +var ( + // When a new object is created + FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert") + // When an object is modified + FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit") + // When an object is deleted + FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete") +) + +// FaaSDocumentCollection returns an attribute KeyValue conforming to the +// "faas.document.collection" semantic conventions. It represents the name of +// the source on which the triggering operation was performed. For example, in +// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the +// database name. +func FaaSDocumentCollection(val string) attribute.KeyValue { + return FaaSDocumentCollectionKey.String(val) +} + +// FaaSDocumentTime returns an attribute KeyValue conforming to the +// "faas.document.time" semantic conventions. It represents a string containing +// the time when the data was accessed in the [ISO +// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format +// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +func FaaSDocumentTime(val string) attribute.KeyValue { + return FaaSDocumentTimeKey.String(val) +} + +// FaaSDocumentName returns an attribute KeyValue conforming to the +// "faas.document.name" semantic conventions. It represents the document +// name/table subjected to the operation. For example, in Cloud Storage or S3 +// is the name of the file, and in Cosmos DB the table name. +func FaaSDocumentName(val string) attribute.KeyValue { + return FaaSDocumentNameKey.String(val) +} + +// Semantic Convention for FaaS scheduled to be executed regularly. +const ( + // FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic + // conventions. It represents a string containing the function invocation + // time in the [ISO + // 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format + // expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2020-01-23T13:47:06Z' + FaaSTimeKey = attribute.Key("faas.time") + + // FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic + // conventions. It represents a string containing the schedule period as + // [Cron + // Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0/5 * * * ? *' + FaaSCronKey = attribute.Key("faas.cron") +) + +// FaaSTime returns an attribute KeyValue conforming to the "faas.time" +// semantic conventions. It represents a string containing the function +// invocation time in the [ISO +// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format +// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +func FaaSTime(val string) attribute.KeyValue { + return FaaSTimeKey.String(val) +} + +// FaaSCron returns an attribute KeyValue conforming to the "faas.cron" +// semantic conventions. It represents a string containing the schedule period +// as [Cron +// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). +func FaaSCron(val string) attribute.KeyValue { + return FaaSCronKey.String(val) +} + +// Contains additional attributes for incoming FaaS spans. +const ( + // FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart" + // semantic conventions. It represents a boolean that is true if the + // serverless function is executed for the first time (aka cold-start). + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + FaaSColdstartKey = attribute.Key("faas.coldstart") +) + +// FaaSColdstart returns an attribute KeyValue conforming to the +// "faas.coldstart" semantic conventions. It represents a boolean that is true +// if the serverless function is executed for the first time (aka cold-start). +func FaaSColdstart(val bool) attribute.KeyValue { + return FaaSColdstartKey.Bool(val) +} + +// Contains additional attributes for outgoing FaaS spans. +const ( + // FaaSInvokedNameKey is the attribute Key conforming to the + // "faas.invoked_name" semantic conventions. It represents the name of the + // invoked function. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'my-function' + // Note: SHOULD be equal to the `faas.name` resource attribute of the + // invoked function. + FaaSInvokedNameKey = attribute.Key("faas.invoked_name") + + // FaaSInvokedProviderKey is the attribute Key conforming to the + // "faas.invoked_provider" semantic conventions. It represents the cloud + // provider of the invoked function. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: SHOULD be equal to the `cloud.provider` resource attribute of the + // invoked function. + FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider") + + // FaaSInvokedRegionKey is the attribute Key conforming to the + // "faas.invoked_region" semantic conventions. It represents the cloud + // region of the invoked function. + // + // Type: string + // RequirementLevel: ConditionallyRequired (For some cloud providers, like + // AWS or GCP, the region in which a function is hosted is essential to + // uniquely identify the function and also part of its endpoint. Since it's + // part of the endpoint being called, the region is always known to + // clients. In these cases, `faas.invoked_region` MUST be set accordingly. + // If the region is unknown to the client or not required for identifying + // the invoked function, setting `faas.invoked_region` is optional.) + // Stability: stable + // Examples: 'eu-central-1' + // Note: SHOULD be equal to the `cloud.region` resource attribute of the + // invoked function. + FaaSInvokedRegionKey = attribute.Key("faas.invoked_region") +) + +var ( + // Alibaba Cloud + FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud") + // Amazon Web Services + FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws") + // Microsoft Azure + FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure") + // Google Cloud Platform + FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp") + // Tencent Cloud + FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud") +) + +// FaaSInvokedName returns an attribute KeyValue conforming to the +// "faas.invoked_name" semantic conventions. It represents the name of the +// invoked function. +func FaaSInvokedName(val string) attribute.KeyValue { + return FaaSInvokedNameKey.String(val) +} + +// FaaSInvokedRegion returns an attribute KeyValue conforming to the +// "faas.invoked_region" semantic conventions. It represents the cloud region +// of the invoked function. +func FaaSInvokedRegion(val string) attribute.KeyValue { + return FaaSInvokedRegionKey.String(val) +} + +// These attributes may be used for any network related operation. +const ( + // NetTransportKey is the attribute Key conforming to the "net.transport" + // semantic conventions. It represents the transport protocol used. See + // note below. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + NetTransportKey = attribute.Key("net.transport") + + // NetAppProtocolNameKey is the attribute Key conforming to the + // "net.app.protocol.name" semantic conventions. It represents the + // application layer protocol used. The value SHOULD be normalized to + // lowercase. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'amqp', 'http', 'mqtt' + NetAppProtocolNameKey = attribute.Key("net.app.protocol.name") + + // NetAppProtocolVersionKey is the attribute Key conforming to the + // "net.app.protocol.version" semantic conventions. It represents the + // version of the application layer protocol used. See note below. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '3.1.1' + // Note: `net.app.protocol.version` refers to the version of the protocol + // used and might be different from the protocol client's version. If the + // HTTP client used has a version of `0.27.2`, but sends HTTP version + // `1.1`, this attribute should be set to `1.1`. + NetAppProtocolVersionKey = attribute.Key("net.app.protocol.version") + + // NetSockPeerNameKey is the attribute Key conforming to the + // "net.sock.peer.name" semantic conventions. It represents the remote + // socket peer name. + // + // Type: string + // RequirementLevel: Recommended (If available and different from + // `net.peer.name` and if `net.sock.peer.addr` is set.) + // Stability: stable + // Examples: 'proxy.example.com' + NetSockPeerNameKey = attribute.Key("net.sock.peer.name") + + // NetSockPeerAddrKey is the attribute Key conforming to the + // "net.sock.peer.addr" semantic conventions. It represents the remote + // socket peer address: IPv4 or IPv6 for internet protocols, path for local + // communication, + // [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '127.0.0.1', '/tmp/mysql.sock' + NetSockPeerAddrKey = attribute.Key("net.sock.peer.addr") + + // NetSockPeerPortKey is the attribute Key conforming to the + // "net.sock.peer.port" semantic conventions. It represents the remote + // socket peer port. + // + // Type: int + // RequirementLevel: Recommended (If defined for the address family and if + // different than `net.peer.port` and if `net.sock.peer.addr` is set.) + // Stability: stable + // Examples: 16456 + NetSockPeerPortKey = attribute.Key("net.sock.peer.port") + + // NetSockFamilyKey is the attribute Key conforming to the + // "net.sock.family" semantic conventions. It represents the protocol + // [address + // family](https://man7.org/linux/man-pages/man7/address_families.7.html) + // which is used for communication. + // + // Type: Enum + // RequirementLevel: ConditionallyRequired (If different than `inet` and if + // any of `net.sock.peer.addr` or `net.sock.host.addr` are set. Consumers + // of telemetry SHOULD accept both IPv4 and IPv6 formats for the address in + // `net.sock.peer.addr` if `net.sock.family` is not set. This is to support + // instrumentations that follow previous versions of this document.) + // Stability: stable + // Examples: 'inet6', 'bluetooth' + NetSockFamilyKey = attribute.Key("net.sock.family") + + // NetPeerNameKey is the attribute Key conforming to the "net.peer.name" + // semantic conventions. It represents the logical remote hostname, see + // note below. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'example.com' + // Note: `net.peer.name` SHOULD NOT be set if capturing it would require an + // extra DNS lookup. + NetPeerNameKey = attribute.Key("net.peer.name") + + // NetPeerPortKey is the attribute Key conforming to the "net.peer.port" + // semantic conventions. It represents the logical remote port number + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 80, 8080, 443 + NetPeerPortKey = attribute.Key("net.peer.port") + + // NetHostNameKey is the attribute Key conforming to the "net.host.name" + // semantic conventions. It represents the logical local hostname or + // similar, see note below. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'localhost' + NetHostNameKey = attribute.Key("net.host.name") + + // NetHostPortKey is the attribute Key conforming to the "net.host.port" + // semantic conventions. It represents the logical local port number, + // preferably the one that the peer used to connect + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 8080 + NetHostPortKey = attribute.Key("net.host.port") + + // NetSockHostAddrKey is the attribute Key conforming to the + // "net.sock.host.addr" semantic conventions. It represents the local + // socket address. Useful in case of a multi-IP host. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '192.168.0.1' + NetSockHostAddrKey = attribute.Key("net.sock.host.addr") + + // NetSockHostPortKey is the attribute Key conforming to the + // "net.sock.host.port" semantic conventions. It represents the local + // socket port number. + // + // Type: int + // RequirementLevel: Recommended (If defined for the address family and if + // different than `net.host.port` and if `net.sock.host.addr` is set.) + // Stability: stable + // Examples: 35555 + NetSockHostPortKey = attribute.Key("net.sock.host.port") + + // NetHostConnectionTypeKey is the attribute Key conforming to the + // "net.host.connection.type" semantic conventions. It represents the + // internet connection type currently being used by the host. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'wifi' + NetHostConnectionTypeKey = attribute.Key("net.host.connection.type") + + // NetHostConnectionSubtypeKey is the attribute Key conforming to the + // "net.host.connection.subtype" semantic conventions. It represents the + // this describes more details regarding the connection.type. It may be the + // type of cell technology connection, but it could be used for describing + // details about a wifi connection. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'LTE' + NetHostConnectionSubtypeKey = attribute.Key("net.host.connection.subtype") + + // NetHostCarrierNameKey is the attribute Key conforming to the + // "net.host.carrier.name" semantic conventions. It represents the name of + // the mobile carrier. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'sprint' + NetHostCarrierNameKey = attribute.Key("net.host.carrier.name") + + // NetHostCarrierMccKey is the attribute Key conforming to the + // "net.host.carrier.mcc" semantic conventions. It represents the mobile + // carrier country code. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '310' + NetHostCarrierMccKey = attribute.Key("net.host.carrier.mcc") + + // NetHostCarrierMncKey is the attribute Key conforming to the + // "net.host.carrier.mnc" semantic conventions. It represents the mobile + // carrier network code. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '001' + NetHostCarrierMncKey = attribute.Key("net.host.carrier.mnc") + + // NetHostCarrierIccKey is the attribute Key conforming to the + // "net.host.carrier.icc" semantic conventions. It represents the ISO + // 3166-1 alpha-2 2-character country code associated with the mobile + // carrier network. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'DE' + NetHostCarrierIccKey = attribute.Key("net.host.carrier.icc") +) + +var ( + // ip_tcp + NetTransportTCP = NetTransportKey.String("ip_tcp") + // ip_udp + NetTransportUDP = NetTransportKey.String("ip_udp") + // Named or anonymous pipe. See note below + NetTransportPipe = NetTransportKey.String("pipe") + // In-process communication + NetTransportInProc = NetTransportKey.String("inproc") + // Something else (non IP-based) + NetTransportOther = NetTransportKey.String("other") +) + +var ( + // IPv4 address + NetSockFamilyInet = NetSockFamilyKey.String("inet") + // IPv6 address + NetSockFamilyInet6 = NetSockFamilyKey.String("inet6") + // Unix domain socket path + NetSockFamilyUnix = NetSockFamilyKey.String("unix") +) + +var ( + // wifi + NetHostConnectionTypeWifi = NetHostConnectionTypeKey.String("wifi") + // wired + NetHostConnectionTypeWired = NetHostConnectionTypeKey.String("wired") + // cell + NetHostConnectionTypeCell = NetHostConnectionTypeKey.String("cell") + // unavailable + NetHostConnectionTypeUnavailable = NetHostConnectionTypeKey.String("unavailable") + // unknown + NetHostConnectionTypeUnknown = NetHostConnectionTypeKey.String("unknown") +) + +var ( + // GPRS + NetHostConnectionSubtypeGprs = NetHostConnectionSubtypeKey.String("gprs") + // EDGE + NetHostConnectionSubtypeEdge = NetHostConnectionSubtypeKey.String("edge") + // UMTS + NetHostConnectionSubtypeUmts = NetHostConnectionSubtypeKey.String("umts") + // CDMA + NetHostConnectionSubtypeCdma = NetHostConnectionSubtypeKey.String("cdma") + // EVDO Rel. 0 + NetHostConnectionSubtypeEvdo0 = NetHostConnectionSubtypeKey.String("evdo_0") + // EVDO Rev. A + NetHostConnectionSubtypeEvdoA = NetHostConnectionSubtypeKey.String("evdo_a") + // CDMA2000 1XRTT + NetHostConnectionSubtypeCdma20001xrtt = NetHostConnectionSubtypeKey.String("cdma2000_1xrtt") + // HSDPA + NetHostConnectionSubtypeHsdpa = NetHostConnectionSubtypeKey.String("hsdpa") + // HSUPA + NetHostConnectionSubtypeHsupa = NetHostConnectionSubtypeKey.String("hsupa") + // HSPA + NetHostConnectionSubtypeHspa = NetHostConnectionSubtypeKey.String("hspa") + // IDEN + NetHostConnectionSubtypeIden = NetHostConnectionSubtypeKey.String("iden") + // EVDO Rev. B + NetHostConnectionSubtypeEvdoB = NetHostConnectionSubtypeKey.String("evdo_b") + // LTE + NetHostConnectionSubtypeLte = NetHostConnectionSubtypeKey.String("lte") + // EHRPD + NetHostConnectionSubtypeEhrpd = NetHostConnectionSubtypeKey.String("ehrpd") + // HSPAP + NetHostConnectionSubtypeHspap = NetHostConnectionSubtypeKey.String("hspap") + // GSM + NetHostConnectionSubtypeGsm = NetHostConnectionSubtypeKey.String("gsm") + // TD-SCDMA + NetHostConnectionSubtypeTdScdma = NetHostConnectionSubtypeKey.String("td_scdma") + // IWLAN + NetHostConnectionSubtypeIwlan = NetHostConnectionSubtypeKey.String("iwlan") + // 5G NR (New Radio) + NetHostConnectionSubtypeNr = NetHostConnectionSubtypeKey.String("nr") + // 5G NRNSA (New Radio Non-Standalone) + NetHostConnectionSubtypeNrnsa = NetHostConnectionSubtypeKey.String("nrnsa") + // LTE CA + NetHostConnectionSubtypeLteCa = NetHostConnectionSubtypeKey.String("lte_ca") +) + +// NetAppProtocolName returns an attribute KeyValue conforming to the +// "net.app.protocol.name" semantic conventions. It represents the application +// layer protocol used. The value SHOULD be normalized to lowercase. +func NetAppProtocolName(val string) attribute.KeyValue { + return NetAppProtocolNameKey.String(val) +} + +// NetAppProtocolVersion returns an attribute KeyValue conforming to the +// "net.app.protocol.version" semantic conventions. It represents the version +// of the application layer protocol used. See note below. +func NetAppProtocolVersion(val string) attribute.KeyValue { + return NetAppProtocolVersionKey.String(val) +} + +// NetSockPeerName returns an attribute KeyValue conforming to the +// "net.sock.peer.name" semantic conventions. It represents the remote socket +// peer name. +func NetSockPeerName(val string) attribute.KeyValue { + return NetSockPeerNameKey.String(val) +} + +// NetSockPeerAddr returns an attribute KeyValue conforming to the +// "net.sock.peer.addr" semantic conventions. It represents the remote socket +// peer address: IPv4 or IPv6 for internet protocols, path for local +// communication, +// [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). +func NetSockPeerAddr(val string) attribute.KeyValue { + return NetSockPeerAddrKey.String(val) +} + +// NetSockPeerPort returns an attribute KeyValue conforming to the +// "net.sock.peer.port" semantic conventions. It represents the remote socket +// peer port. +func NetSockPeerPort(val int) attribute.KeyValue { + return NetSockPeerPortKey.Int(val) +} + +// NetPeerName returns an attribute KeyValue conforming to the +// "net.peer.name" semantic conventions. It represents the logical remote +// hostname, see note below. +func NetPeerName(val string) attribute.KeyValue { + return NetPeerNameKey.String(val) +} + +// NetPeerPort returns an attribute KeyValue conforming to the +// "net.peer.port" semantic conventions. It represents the logical remote port +// number +func NetPeerPort(val int) attribute.KeyValue { + return NetPeerPortKey.Int(val) +} + +// NetHostName returns an attribute KeyValue conforming to the +// "net.host.name" semantic conventions. It represents the logical local +// hostname or similar, see note below. +func NetHostName(val string) attribute.KeyValue { + return NetHostNameKey.String(val) +} + +// NetHostPort returns an attribute KeyValue conforming to the +// "net.host.port" semantic conventions. It represents the logical local port +// number, preferably the one that the peer used to connect +func NetHostPort(val int) attribute.KeyValue { + return NetHostPortKey.Int(val) +} + +// NetSockHostAddr returns an attribute KeyValue conforming to the +// "net.sock.host.addr" semantic conventions. It represents the local socket +// address. Useful in case of a multi-IP host. +func NetSockHostAddr(val string) attribute.KeyValue { + return NetSockHostAddrKey.String(val) +} + +// NetSockHostPort returns an attribute KeyValue conforming to the +// "net.sock.host.port" semantic conventions. It represents the local socket +// port number. +func NetSockHostPort(val int) attribute.KeyValue { + return NetSockHostPortKey.Int(val) +} + +// NetHostCarrierName returns an attribute KeyValue conforming to the +// "net.host.carrier.name" semantic conventions. It represents the name of the +// mobile carrier. +func NetHostCarrierName(val string) attribute.KeyValue { + return NetHostCarrierNameKey.String(val) +} + +// NetHostCarrierMcc returns an attribute KeyValue conforming to the +// "net.host.carrier.mcc" semantic conventions. It represents the mobile +// carrier country code. +func NetHostCarrierMcc(val string) attribute.KeyValue { + return NetHostCarrierMccKey.String(val) +} + +// NetHostCarrierMnc returns an attribute KeyValue conforming to the +// "net.host.carrier.mnc" semantic conventions. It represents the mobile +// carrier network code. +func NetHostCarrierMnc(val string) attribute.KeyValue { + return NetHostCarrierMncKey.String(val) +} + +// NetHostCarrierIcc returns an attribute KeyValue conforming to the +// "net.host.carrier.icc" semantic conventions. It represents the ISO 3166-1 +// alpha-2 2-character country code associated with the mobile carrier network. +func NetHostCarrierIcc(val string) attribute.KeyValue { + return NetHostCarrierIccKey.String(val) +} + +// Operations that access some remote service. +const ( + // PeerServiceKey is the attribute Key conforming to the "peer.service" + // semantic conventions. It represents the + // [`service.name`](../../resource/semantic_conventions/README.md#service) + // of the remote service. SHOULD be equal to the actual `service.name` + // resource attribute of the remote service if any. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'AuthTokenCache' + PeerServiceKey = attribute.Key("peer.service") +) + +// PeerService returns an attribute KeyValue conforming to the +// "peer.service" semantic conventions. It represents the +// [`service.name`](../../resource/semantic_conventions/README.md#service) of +// the remote service. SHOULD be equal to the actual `service.name` resource +// attribute of the remote service if any. +func PeerService(val string) attribute.KeyValue { + return PeerServiceKey.String(val) +} + +// These attributes may be used for any operation with an authenticated and/or +// authorized enduser. +const ( + // EnduserIDKey is the attribute Key conforming to the "enduser.id" + // semantic conventions. It represents the username or client_id extracted + // from the access token or + // [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header + // in the inbound request from outside the system. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'username' + EnduserIDKey = attribute.Key("enduser.id") + + // EnduserRoleKey is the attribute Key conforming to the "enduser.role" + // semantic conventions. It represents the actual/assumed role the client + // is making the request under extracted from token or application security + // context. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'admin' + EnduserRoleKey = attribute.Key("enduser.role") + + // EnduserScopeKey is the attribute Key conforming to the "enduser.scope" + // semantic conventions. It represents the scopes or granted authorities + // the client currently possesses extracted from token or application + // security context. The value would come from the scope associated with an + // [OAuth 2.0 Access + // Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute + // value in a [SAML 2.0 + // Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'read:message, write:files' + EnduserScopeKey = attribute.Key("enduser.scope") +) + +// EnduserID returns an attribute KeyValue conforming to the "enduser.id" +// semantic conventions. It represents the username or client_id extracted from +// the access token or +// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in +// the inbound request from outside the system. +func EnduserID(val string) attribute.KeyValue { + return EnduserIDKey.String(val) +} + +// EnduserRole returns an attribute KeyValue conforming to the +// "enduser.role" semantic conventions. It represents the actual/assumed role +// the client is making the request under extracted from token or application +// security context. +func EnduserRole(val string) attribute.KeyValue { + return EnduserRoleKey.String(val) +} + +// EnduserScope returns an attribute KeyValue conforming to the +// "enduser.scope" semantic conventions. It represents the scopes or granted +// authorities the client currently possesses extracted from token or +// application security context. The value would come from the scope associated +// with an [OAuth 2.0 Access +// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute +// value in a [SAML 2.0 +// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). +func EnduserScope(val string) attribute.KeyValue { + return EnduserScopeKey.String(val) +} + +// These attributes may be used for any operation to store information about a +// thread that started a span. +const ( + // ThreadIDKey is the attribute Key conforming to the "thread.id" semantic + // conventions. It represents the current "managed" thread ID (as opposed + // to OS thread ID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + ThreadIDKey = attribute.Key("thread.id") + + // ThreadNameKey is the attribute Key conforming to the "thread.name" + // semantic conventions. It represents the current thread name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'main' + ThreadNameKey = attribute.Key("thread.name") +) + +// ThreadID returns an attribute KeyValue conforming to the "thread.id" +// semantic conventions. It represents the current "managed" thread ID (as +// opposed to OS thread ID). +func ThreadID(val int) attribute.KeyValue { + return ThreadIDKey.Int(val) +} + +// ThreadName returns an attribute KeyValue conforming to the "thread.name" +// semantic conventions. It represents the current thread name. +func ThreadName(val string) attribute.KeyValue { + return ThreadNameKey.String(val) +} + +// These attributes allow to report this unit of code and therefore to provide +// more context about the span. +const ( + // CodeFunctionKey is the attribute Key conforming to the "code.function" + // semantic conventions. It represents the method or function name, or + // equivalent (usually rightmost part of the code unit's name). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'serveRequest' + CodeFunctionKey = attribute.Key("code.function") + + // CodeNamespaceKey is the attribute Key conforming to the "code.namespace" + // semantic conventions. It represents the "namespace" within which + // `code.function` is defined. Usually the qualified class or module name, + // such that `code.namespace` + some separator + `code.function` form a + // unique identifier for the code unit. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'com.example.MyHTTPService' + CodeNamespaceKey = attribute.Key("code.namespace") + + // CodeFilepathKey is the attribute Key conforming to the "code.filepath" + // semantic conventions. It represents the source code file name that + // identifies the code unit as uniquely as possible (preferably an absolute + // file path). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/usr/local/MyApplication/content_root/app/index.php' + CodeFilepathKey = attribute.Key("code.filepath") + + // CodeLineNumberKey is the attribute Key conforming to the "code.lineno" + // semantic conventions. It represents the line number in `code.filepath` + // best representing the operation. It SHOULD point within the code unit + // named in `code.function`. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + CodeLineNumberKey = attribute.Key("code.lineno") + + // CodeColumnKey is the attribute Key conforming to the "code.column" + // semantic conventions. It represents the column number in `code.filepath` + // best representing the operation. It SHOULD point within the code unit + // named in `code.function`. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 16 + CodeColumnKey = attribute.Key("code.column") +) + +// CodeFunction returns an attribute KeyValue conforming to the +// "code.function" semantic conventions. It represents the method or function +// name, or equivalent (usually rightmost part of the code unit's name). +func CodeFunction(val string) attribute.KeyValue { + return CodeFunctionKey.String(val) +} + +// CodeNamespace returns an attribute KeyValue conforming to the +// "code.namespace" semantic conventions. It represents the "namespace" within +// which `code.function` is defined. Usually the qualified class or module +// name, such that `code.namespace` + some separator + `code.function` form a +// unique identifier for the code unit. +func CodeNamespace(val string) attribute.KeyValue { + return CodeNamespaceKey.String(val) +} + +// CodeFilepath returns an attribute KeyValue conforming to the +// "code.filepath" semantic conventions. It represents the source code file +// name that identifies the code unit as uniquely as possible (preferably an +// absolute file path). +func CodeFilepath(val string) attribute.KeyValue { + return CodeFilepathKey.String(val) +} + +// CodeLineNumber returns an attribute KeyValue conforming to the "code.lineno" +// semantic conventions. It represents the line number in `code.filepath` best +// representing the operation. It SHOULD point within the code unit named in +// `code.function`. +func CodeLineNumber(val int) attribute.KeyValue { + return CodeLineNumberKey.Int(val) +} + +// CodeColumn returns an attribute KeyValue conforming to the "code.column" +// semantic conventions. It represents the column number in `code.filepath` +// best representing the operation. It SHOULD point within the code unit named +// in `code.function`. +func CodeColumn(val int) attribute.KeyValue { + return CodeColumnKey.Int(val) +} + +// Semantic conventions for HTTP client and server Spans. +const ( + // HTTPMethodKey is the attribute Key conforming to the "http.method" + // semantic conventions. It represents the hTTP request method. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'GET', 'POST', 'HEAD' + HTTPMethodKey = attribute.Key("http.method") + + // HTTPStatusCodeKey is the attribute Key conforming to the + // "http.status_code" semantic conventions. It represents the [HTTP + // response status code](https://tools.ietf.org/html/rfc7231#section-6). + // + // Type: int + // RequirementLevel: ConditionallyRequired (If and only if one was + // received/sent.) + // Stability: stable + // Examples: 200 + HTTPStatusCodeKey = attribute.Key("http.status_code") + + // HTTPFlavorKey is the attribute Key conforming to the "http.flavor" + // semantic conventions. It represents the kind of HTTP protocol used. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: If `net.transport` is not specified, it can be assumed to be + // `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is + // assumed. + HTTPFlavorKey = attribute.Key("http.flavor") + + // HTTPUserAgentKey is the attribute Key conforming to the + // "http.user_agent" semantic conventions. It represents the value of the + // [HTTP + // User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) + // header sent by the client. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'CERN-LineMode/2.15 libwww/2.17b3' + HTTPUserAgentKey = attribute.Key("http.user_agent") + + // HTTPRequestContentLengthKey is the attribute Key conforming to the + // "http.request_content_length" semantic conventions. It represents the + // size of the request payload body in bytes. This is the number of bytes + // transferred excluding headers and is often, but not always, present as + // the + // [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) + // header. For requests using transport encoding, this should be the + // compressed size. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3495 + HTTPRequestContentLengthKey = attribute.Key("http.request_content_length") + + // HTTPResponseContentLengthKey is the attribute Key conforming to the + // "http.response_content_length" semantic conventions. It represents the + // size of the response payload body in bytes. This is the number of bytes + // transferred excluding headers and is often, but not always, present as + // the + // [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) + // header. For requests using transport encoding, this should be the + // compressed size. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3495 + HTTPResponseContentLengthKey = attribute.Key("http.response_content_length") +) + +var ( + // HTTP/1.0 + HTTPFlavorHTTP10 = HTTPFlavorKey.String("1.0") + // HTTP/1.1 + HTTPFlavorHTTP11 = HTTPFlavorKey.String("1.1") + // HTTP/2 + HTTPFlavorHTTP20 = HTTPFlavorKey.String("2.0") + // HTTP/3 + HTTPFlavorHTTP30 = HTTPFlavorKey.String("3.0") + // SPDY protocol + HTTPFlavorSPDY = HTTPFlavorKey.String("SPDY") + // QUIC protocol + HTTPFlavorQUIC = HTTPFlavorKey.String("QUIC") +) + +// HTTPMethod returns an attribute KeyValue conforming to the "http.method" +// semantic conventions. It represents the hTTP request method. +func HTTPMethod(val string) attribute.KeyValue { + return HTTPMethodKey.String(val) +} + +// HTTPStatusCode returns an attribute KeyValue conforming to the +// "http.status_code" semantic conventions. It represents the [HTTP response +// status code](https://tools.ietf.org/html/rfc7231#section-6). +func HTTPStatusCode(val int) attribute.KeyValue { + return HTTPStatusCodeKey.Int(val) +} + +// HTTPUserAgent returns an attribute KeyValue conforming to the +// "http.user_agent" semantic conventions. It represents the value of the [HTTP +// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) +// header sent by the client. +func HTTPUserAgent(val string) attribute.KeyValue { + return HTTPUserAgentKey.String(val) +} + +// HTTPRequestContentLength returns an attribute KeyValue conforming to the +// "http.request_content_length" semantic conventions. It represents the size +// of the request payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) +// header. For requests using transport encoding, this should be the compressed +// size. +func HTTPRequestContentLength(val int) attribute.KeyValue { + return HTTPRequestContentLengthKey.Int(val) +} + +// HTTPResponseContentLength returns an attribute KeyValue conforming to the +// "http.response_content_length" semantic conventions. It represents the size +// of the response payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) +// header. For requests using transport encoding, this should be the compressed +// size. +func HTTPResponseContentLength(val int) attribute.KeyValue { + return HTTPResponseContentLengthKey.Int(val) +} + +// Semantic Convention for HTTP Client +const ( + // HTTPURLKey is the attribute Key conforming to the "http.url" semantic + // conventions. It represents the full HTTP request URL in the form + // `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is + // not transmitted over HTTP, but if it is known, it should be included + // nevertheless. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv' + // Note: `http.url` MUST NOT contain credentials passed via URL in form of + // `https://username:password@www.example.com/`. In such case the + // attribute's value should be `https://www.example.com/`. + HTTPURLKey = attribute.Key("http.url") + + // HTTPResendCountKey is the attribute Key conforming to the + // "http.resend_count" semantic conventions. It represents the ordinal + // number of request resending attempt (for any reason, including + // redirects). + // + // Type: int + // RequirementLevel: Recommended (if and only if request was retried.) + // Stability: stable + // Examples: 3 + // Note: The resend count SHOULD be updated each time an HTTP request gets + // resent by the client, regardless of what was the cause of the resending + // (e.g. redirection, authorization failure, 503 Server Unavailable, + // network issues, or any other). + HTTPResendCountKey = attribute.Key("http.resend_count") +) + +// HTTPURL returns an attribute KeyValue conforming to the "http.url" +// semantic conventions. It represents the full HTTP request URL in the form +// `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not +// transmitted over HTTP, but if it is known, it should be included +// nevertheless. +func HTTPURL(val string) attribute.KeyValue { + return HTTPURLKey.String(val) +} + +// HTTPResendCount returns an attribute KeyValue conforming to the +// "http.resend_count" semantic conventions. It represents the ordinal number +// of request resending attempt (for any reason, including redirects). +func HTTPResendCount(val int) attribute.KeyValue { + return HTTPResendCountKey.Int(val) +} + +// Semantic Convention for HTTP Server +const ( + // HTTPSchemeKey is the attribute Key conforming to the "http.scheme" + // semantic conventions. It represents the URI scheme identifying the used + // protocol. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'http', 'https' + HTTPSchemeKey = attribute.Key("http.scheme") + + // HTTPTargetKey is the attribute Key conforming to the "http.target" + // semantic conventions. It represents the full request target as passed in + // a HTTP request line or equivalent. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: '/path/12314/?q=ddds' + HTTPTargetKey = attribute.Key("http.target") + + // HTTPRouteKey is the attribute Key conforming to the "http.route" + // semantic conventions. It represents the matched route (path template in + // the format used by the respective server framework). See note below + // + // Type: string + // RequirementLevel: ConditionallyRequired (If and only if it's available) + // Stability: stable + // Examples: '/users/:userID?', '{controller}/{action}/{id?}' + // Note: 'http.route' MUST NOT be populated when this is not supported by + // the HTTP server framework as the route attribute should have + // low-cardinality and the URI path can NOT substitute it. + HTTPRouteKey = attribute.Key("http.route") + + // HTTPClientIPKey is the attribute Key conforming to the "http.client_ip" + // semantic conventions. It represents the IP address of the original + // client behind all proxies, if known (e.g. from + // [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '83.164.160.102' + // Note: This is not necessarily the same as `net.sock.peer.addr`, which + // would + // identify the network-level peer, which may be a proxy. + // + // This attribute should be set when a source of information different + // from the one used for `net.sock.peer.addr`, is available even if that + // other + // source just confirms the same value as `net.sock.peer.addr`. + // Rationale: For `net.sock.peer.addr`, one typically does not know if it + // comes from a proxy, reverse proxy, or the actual client. Setting + // `http.client_ip` when it's the same as `net.sock.peer.addr` means that + // one is at least somewhat confident that the address is not that of + // the closest proxy. + HTTPClientIPKey = attribute.Key("http.client_ip") +) + +// HTTPScheme returns an attribute KeyValue conforming to the "http.scheme" +// semantic conventions. It represents the URI scheme identifying the used +// protocol. +func HTTPScheme(val string) attribute.KeyValue { + return HTTPSchemeKey.String(val) +} + +// HTTPTarget returns an attribute KeyValue conforming to the "http.target" +// semantic conventions. It represents the full request target as passed in a +// HTTP request line or equivalent. +func HTTPTarget(val string) attribute.KeyValue { + return HTTPTargetKey.String(val) +} + +// HTTPRoute returns an attribute KeyValue conforming to the "http.route" +// semantic conventions. It represents the matched route (path template in the +// format used by the respective server framework). See note below +func HTTPRoute(val string) attribute.KeyValue { + return HTTPRouteKey.String(val) +} + +// HTTPClientIP returns an attribute KeyValue conforming to the +// "http.client_ip" semantic conventions. It represents the IP address of the +// original client behind all proxies, if known (e.g. from +// [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). +func HTTPClientIP(val string) attribute.KeyValue { + return HTTPClientIPKey.String(val) +} + +// Attributes that exist for multiple DynamoDB request types. +const ( + // AWSDynamoDBTableNamesKey is the attribute Key conforming to the + // "aws.dynamodb.table_names" semantic conventions. It represents the keys + // in the `RequestItems` object field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Users', 'Cats' + AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names") + + // AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the + // "aws.dynamodb.consumed_capacity" semantic conventions. It represents the + // JSON-serialized value of each item in the `ConsumedCapacity` response + // field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": { + // "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : + // { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": + // { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number }, "TableName": "string", + // "WriteCapacityUnits": number }' + AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity") + + // AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to + // the "aws.dynamodb.item_collection_metrics" semantic conventions. It + // represents the JSON-serialized value of the `ItemCollectionMetrics` + // response field. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B": + // blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { + // "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], + // "NULL": boolean, "S": "string", "SS": [ "string" ] } }, + // "SizeEstimateRangeGB": [ number ] } ] }' + AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics") + + // AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to + // the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It + // represents the value of the `ProvisionedThroughput.ReadCapacityUnits` + // request parameter. + // + // Type: double + // RequirementLevel: Optional + // Stability: stable + // Examples: 1.0, 2.0 + AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity") + + // AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming + // to the "aws.dynamodb.provisioned_write_capacity" semantic conventions. + // It represents the value of the + // `ProvisionedThroughput.WriteCapacityUnits` request parameter. + // + // Type: double + // RequirementLevel: Optional + // Stability: stable + // Examples: 1.0, 2.0 + AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity") + + // AWSDynamoDBConsistentReadKey is the attribute Key conforming to the + // "aws.dynamodb.consistent_read" semantic conventions. It represents the + // value of the `ConsistentRead` request parameter. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read") + + // AWSDynamoDBProjectionKey is the attribute Key conforming to the + // "aws.dynamodb.projection" semantic conventions. It represents the value + // of the `ProjectionExpression` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Title', 'Title, Price, Color', 'Title, Description, + // RelatedItems, ProductReviews' + AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection") + + // AWSDynamoDBLimitKey is the attribute Key conforming to the + // "aws.dynamodb.limit" semantic conventions. It represents the value of + // the `Limit` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit") + + // AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the + // "aws.dynamodb.attributes_to_get" semantic conventions. It represents the + // value of the `AttributesToGet` request parameter. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'lives', 'id' + AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get") + + // AWSDynamoDBIndexNameKey is the attribute Key conforming to the + // "aws.dynamodb.index_name" semantic conventions. It represents the value + // of the `IndexName` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'name_to_group' + AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name") + + // AWSDynamoDBSelectKey is the attribute Key conforming to the + // "aws.dynamodb.select" semantic conventions. It represents the value of + // the `Select` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'ALL_ATTRIBUTES', 'COUNT' + AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select") +) + +// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the +// "aws.dynamodb.table_names" semantic conventions. It represents the keys in +// the `RequestItems` object field. +func AWSDynamoDBTableNames(val ...string) attribute.KeyValue { + return AWSDynamoDBTableNamesKey.StringSlice(val) +} + +// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to +// the "aws.dynamodb.consumed_capacity" semantic conventions. It represents the +// JSON-serialized value of each item in the `ConsumedCapacity` response field. +func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue { + return AWSDynamoDBConsumedCapacityKey.StringSlice(val) +} + +// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming +// to the "aws.dynamodb.item_collection_metrics" semantic conventions. It +// represents the JSON-serialized value of the `ItemCollectionMetrics` response +// field. +func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue { + return AWSDynamoDBItemCollectionMetricsKey.String(val) +} + +// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue +// conforming to the "aws.dynamodb.provisioned_read_capacity" semantic +// conventions. It represents the value of the +// `ProvisionedThroughput.ReadCapacityUnits` request parameter. +func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue { + return AWSDynamoDBProvisionedReadCapacityKey.Float64(val) +} + +// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue +// conforming to the "aws.dynamodb.provisioned_write_capacity" semantic +// conventions. It represents the value of the +// `ProvisionedThroughput.WriteCapacityUnits` request parameter. +func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue { + return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val) +} + +// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the +// "aws.dynamodb.consistent_read" semantic conventions. It represents the value +// of the `ConsistentRead` request parameter. +func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue { + return AWSDynamoDBConsistentReadKey.Bool(val) +} + +// AWSDynamoDBProjection returns an attribute KeyValue conforming to the +// "aws.dynamodb.projection" semantic conventions. It represents the value of +// the `ProjectionExpression` request parameter. +func AWSDynamoDBProjection(val string) attribute.KeyValue { + return AWSDynamoDBProjectionKey.String(val) +} + +// AWSDynamoDBLimit returns an attribute KeyValue conforming to the +// "aws.dynamodb.limit" semantic conventions. It represents the value of the +// `Limit` request parameter. +func AWSDynamoDBLimit(val int) attribute.KeyValue { + return AWSDynamoDBLimitKey.Int(val) +} + +// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to +// the "aws.dynamodb.attributes_to_get" semantic conventions. It represents the +// value of the `AttributesToGet` request parameter. +func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue { + return AWSDynamoDBAttributesToGetKey.StringSlice(val) +} + +// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the +// "aws.dynamodb.index_name" semantic conventions. It represents the value of +// the `IndexName` request parameter. +func AWSDynamoDBIndexName(val string) attribute.KeyValue { + return AWSDynamoDBIndexNameKey.String(val) +} + +// AWSDynamoDBSelect returns an attribute KeyValue conforming to the +// "aws.dynamodb.select" semantic conventions. It represents the value of the +// `Select` request parameter. +func AWSDynamoDBSelect(val string) attribute.KeyValue { + return AWSDynamoDBSelectKey.String(val) +} + +// DynamoDB.CreateTable +const ( + // AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to + // the "aws.dynamodb.global_secondary_indexes" semantic conventions. It + // represents the JSON-serialized value of each item of the + // `GlobalSecondaryIndexes` request field + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName": + // "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ + // "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { + // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }' + AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes") + + // AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to + // the "aws.dynamodb.local_secondary_indexes" semantic conventions. It + // represents the JSON-serialized value of each item of the + // `LocalSecondaryIndexes` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "IndexARN": "string", "IndexName": "string", + // "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { + // "AttributeName": "string", "KeyType": "string" } ], "Projection": { + // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }' + AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes") +) + +// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue +// conforming to the "aws.dynamodb.global_secondary_indexes" semantic +// conventions. It represents the JSON-serialized value of each item of the +// `GlobalSecondaryIndexes` request field +func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue { + return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val) +} + +// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming +// to the "aws.dynamodb.local_secondary_indexes" semantic conventions. It +// represents the JSON-serialized value of each item of the +// `LocalSecondaryIndexes` request field. +func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue { + return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val) +} + +// DynamoDB.ListTables +const ( + // AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the + // "aws.dynamodb.exclusive_start_table" semantic conventions. It represents + // the value of the `ExclusiveStartTableName` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Users', 'CatsTable' + AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table") + + // AWSDynamoDBTableCountKey is the attribute Key conforming to the + // "aws.dynamodb.table_count" semantic conventions. It represents the the + // number of items in the `TableNames` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 20 + AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count") +) + +// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming +// to the "aws.dynamodb.exclusive_start_table" semantic conventions. It +// represents the value of the `ExclusiveStartTableName` request parameter. +func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue { + return AWSDynamoDBExclusiveStartTableKey.String(val) +} + +// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.table_count" semantic conventions. It represents the the +// number of items in the `TableNames` response parameter. +func AWSDynamoDBTableCount(val int) attribute.KeyValue { + return AWSDynamoDBTableCountKey.Int(val) +} + +// DynamoDB.Query +const ( + // AWSDynamoDBScanForwardKey is the attribute Key conforming to the + // "aws.dynamodb.scan_forward" semantic conventions. It represents the + // value of the `ScanIndexForward` request parameter. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward") +) + +// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the +// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of +// the `ScanIndexForward` request parameter. +func AWSDynamoDBScanForward(val bool) attribute.KeyValue { + return AWSDynamoDBScanForwardKey.Bool(val) +} + +// DynamoDB.Scan +const ( + // AWSDynamoDBSegmentKey is the attribute Key conforming to the + // "aws.dynamodb.segment" semantic conventions. It represents the value of + // the `Segment` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment") + + // AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the + // "aws.dynamodb.total_segments" semantic conventions. It represents the + // value of the `TotalSegments` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 100 + AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments") + + // AWSDynamoDBCountKey is the attribute Key conforming to the + // "aws.dynamodb.count" semantic conventions. It represents the value of + // the `Count` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count") + + // AWSDynamoDBScannedCountKey is the attribute Key conforming to the + // "aws.dynamodb.scanned_count" semantic conventions. It represents the + // value of the `ScannedCount` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 50 + AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count") +) + +// AWSDynamoDBSegment returns an attribute KeyValue conforming to the +// "aws.dynamodb.segment" semantic conventions. It represents the value of the +// `Segment` request parameter. +func AWSDynamoDBSegment(val int) attribute.KeyValue { + return AWSDynamoDBSegmentKey.Int(val) +} + +// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the +// "aws.dynamodb.total_segments" semantic conventions. It represents the value +// of the `TotalSegments` request parameter. +func AWSDynamoDBTotalSegments(val int) attribute.KeyValue { + return AWSDynamoDBTotalSegmentsKey.Int(val) +} + +// AWSDynamoDBCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.count" semantic conventions. It represents the value of the +// `Count` response parameter. +func AWSDynamoDBCount(val int) attribute.KeyValue { + return AWSDynamoDBCountKey.Int(val) +} + +// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.scanned_count" semantic conventions. It represents the value +// of the `ScannedCount` response parameter. +func AWSDynamoDBScannedCount(val int) attribute.KeyValue { + return AWSDynamoDBScannedCountKey.Int(val) +} + +// DynamoDB.UpdateTable +const ( + // AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to + // the "aws.dynamodb.attribute_definitions" semantic conventions. It + // represents the JSON-serialized value of each item in the + // `AttributeDefinitions` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "AttributeName": "string", "AttributeType": "string" }' + AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions") + + // AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key + // conforming to the "aws.dynamodb.global_secondary_index_updates" semantic + // conventions. It represents the JSON-serialized value of each item in the + // the `GlobalSecondaryIndexUpdates` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ { + // "AttributeName": "string", "KeyType": "string" } ], "Projection": { + // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, + // "ProvisionedThroughput": { "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }' + AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates") +) + +// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming +// to the "aws.dynamodb.attribute_definitions" semantic conventions. It +// represents the JSON-serialized value of each item in the +// `AttributeDefinitions` request field. +func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue { + return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val) +} + +// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue +// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic +// conventions. It represents the JSON-serialized value of each item in the the +// `GlobalSecondaryIndexUpdates` request field. +func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue { + return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val) +} + +// Semantic conventions to apply when instrumenting the GraphQL implementation. +// They map GraphQL operations to attributes on a Span. +const ( + // GraphqlOperationNameKey is the attribute Key conforming to the + // "graphql.operation.name" semantic conventions. It represents the name of + // the operation being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'findBookByID' + GraphqlOperationNameKey = attribute.Key("graphql.operation.name") + + // GraphqlOperationTypeKey is the attribute Key conforming to the + // "graphql.operation.type" semantic conventions. It represents the type of + // the operation being executed. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'query', 'mutation', 'subscription' + GraphqlOperationTypeKey = attribute.Key("graphql.operation.type") + + // GraphqlDocumentKey is the attribute Key conforming to the + // "graphql.document" semantic conventions. It represents the GraphQL + // document being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'query findBookByID { bookByID(id: ?) { name } }' + // Note: The value may be sanitized to exclude sensitive information. + GraphqlDocumentKey = attribute.Key("graphql.document") +) + +var ( + // GraphQL query + GraphqlOperationTypeQuery = GraphqlOperationTypeKey.String("query") + // GraphQL mutation + GraphqlOperationTypeMutation = GraphqlOperationTypeKey.String("mutation") + // GraphQL subscription + GraphqlOperationTypeSubscription = GraphqlOperationTypeKey.String("subscription") +) + +// GraphqlOperationName returns an attribute KeyValue conforming to the +// "graphql.operation.name" semantic conventions. It represents the name of the +// operation being executed. +func GraphqlOperationName(val string) attribute.KeyValue { + return GraphqlOperationNameKey.String(val) +} + +// GraphqlDocument returns an attribute KeyValue conforming to the +// "graphql.document" semantic conventions. It represents the GraphQL document +// being executed. +func GraphqlDocument(val string) attribute.KeyValue { + return GraphqlDocumentKey.String(val) +} + +// Semantic convention describing per-message attributes populated on messaging +// spans or links. +const ( + // MessagingMessageIDKey is the attribute Key conforming to the + // "messaging.message.id" semantic conventions. It represents a value used + // by the messaging system as an identifier for the message, represented as + // a string. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '452a7c7c7c7048c2f887f61572b18fc2' + MessagingMessageIDKey = attribute.Key("messaging.message.id") + + // MessagingMessageConversationIDKey is the attribute Key conforming to the + // "messaging.message.conversation_id" semantic conventions. It represents + // the [conversation ID](#conversations) identifying the conversation to + // which the message belongs, represented as a string. Sometimes called + // "Correlation ID". + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MyConversationID' + MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id") + + // MessagingMessagePayloadSizeBytesKey is the attribute Key conforming to + // the "messaging.message.payload_size_bytes" semantic conventions. It + // represents the (uncompressed) size of the message payload in bytes. Also + // use this attribute if it is unknown whether the compressed or + // uncompressed payload size is reported. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2738 + MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message.payload_size_bytes") + + // MessagingMessagePayloadCompressedSizeBytesKey is the attribute Key + // conforming to the "messaging.message.payload_compressed_size_bytes" + // semantic conventions. It represents the compressed size of the message + // payload in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2048 + MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message.payload_compressed_size_bytes") +) + +// MessagingMessageID returns an attribute KeyValue conforming to the +// "messaging.message.id" semantic conventions. It represents a value used by +// the messaging system as an identifier for the message, represented as a +// string. +func MessagingMessageID(val string) attribute.KeyValue { + return MessagingMessageIDKey.String(val) +} + +// MessagingMessageConversationID returns an attribute KeyValue conforming +// to the "messaging.message.conversation_id" semantic conventions. It +// represents the [conversation ID](#conversations) identifying the +// conversation to which the message belongs, represented as a string. +// Sometimes called "Correlation ID". +func MessagingMessageConversationID(val string) attribute.KeyValue { + return MessagingMessageConversationIDKey.String(val) +} + +// MessagingMessagePayloadSizeBytes returns an attribute KeyValue conforming +// to the "messaging.message.payload_size_bytes" semantic conventions. It +// represents the (uncompressed) size of the message payload in bytes. Also use +// this attribute if it is unknown whether the compressed or uncompressed +// payload size is reported. +func MessagingMessagePayloadSizeBytes(val int) attribute.KeyValue { + return MessagingMessagePayloadSizeBytesKey.Int(val) +} + +// MessagingMessagePayloadCompressedSizeBytes returns an attribute KeyValue +// conforming to the "messaging.message.payload_compressed_size_bytes" semantic +// conventions. It represents the compressed size of the message payload in +// bytes. +func MessagingMessagePayloadCompressedSizeBytes(val int) attribute.KeyValue { + return MessagingMessagePayloadCompressedSizeBytesKey.Int(val) +} + +// Semantic convention for attributes that describe messaging destination on +// broker +const ( + // MessagingDestinationNameKey is the attribute Key conforming to the + // "messaging.destination.name" semantic conventions. It represents the + // message destination name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MyQueue', 'MyTopic' + // Note: Destination name SHOULD uniquely identify a specific queue, topic + // or other entity within the broker. If + // the broker does not have such notion, the destination name SHOULD + // uniquely identify the broker. + MessagingDestinationNameKey = attribute.Key("messaging.destination.name") + + // MessagingDestinationKindKey is the attribute Key conforming to the + // "messaging.destination.kind" semantic conventions. It represents the + // kind of message destination + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingDestinationKindKey = attribute.Key("messaging.destination.kind") + + // MessagingDestinationTemplateKey is the attribute Key conforming to the + // "messaging.destination.template" semantic conventions. It represents the + // low cardinality representation of the messaging destination name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/customers/{customerID}' + // Note: Destination names could be constructed from templates. An example + // would be a destination name involving a user name or product id. + // Although the destination name in this case is of high cardinality, the + // underlying template is of low cardinality and can be effectively used + // for grouping and aggregation. + MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template") + + // MessagingDestinationTemporaryKey is the attribute Key conforming to the + // "messaging.destination.temporary" semantic conventions. It represents a + // boolean that is true if the message destination is temporary and might + // not exist anymore after messages are processed. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary") + + // MessagingDestinationAnonymousKey is the attribute Key conforming to the + // "messaging.destination.anonymous" semantic conventions. It represents a + // boolean that is true if the message destination is anonymous (could be + // unnamed or have auto-generated name). + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous") +) + +var ( + // A message sent to a queue + MessagingDestinationKindQueue = MessagingDestinationKindKey.String("queue") + // A message sent to a topic + MessagingDestinationKindTopic = MessagingDestinationKindKey.String("topic") +) + +// MessagingDestinationName returns an attribute KeyValue conforming to the +// "messaging.destination.name" semantic conventions. It represents the message +// destination name +func MessagingDestinationName(val string) attribute.KeyValue { + return MessagingDestinationNameKey.String(val) +} + +// MessagingDestinationTemplate returns an attribute KeyValue conforming to +// the "messaging.destination.template" semantic conventions. It represents the +// low cardinality representation of the messaging destination name +func MessagingDestinationTemplate(val string) attribute.KeyValue { + return MessagingDestinationTemplateKey.String(val) +} + +// MessagingDestinationTemporary returns an attribute KeyValue conforming to +// the "messaging.destination.temporary" semantic conventions. It represents a +// boolean that is true if the message destination is temporary and might not +// exist anymore after messages are processed. +func MessagingDestinationTemporary(val bool) attribute.KeyValue { + return MessagingDestinationTemporaryKey.Bool(val) +} + +// MessagingDestinationAnonymous returns an attribute KeyValue conforming to +// the "messaging.destination.anonymous" semantic conventions. It represents a +// boolean that is true if the message destination is anonymous (could be +// unnamed or have auto-generated name). +func MessagingDestinationAnonymous(val bool) attribute.KeyValue { + return MessagingDestinationAnonymousKey.Bool(val) +} + +// Semantic convention for attributes that describe messaging source on broker +const ( + // MessagingSourceNameKey is the attribute Key conforming to the + // "messaging.source.name" semantic conventions. It represents the message + // source name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MyQueue', 'MyTopic' + // Note: Source name SHOULD uniquely identify a specific queue, topic, or + // other entity within the broker. If + // the broker does not have such notion, the source name SHOULD uniquely + // identify the broker. + MessagingSourceNameKey = attribute.Key("messaging.source.name") + + // MessagingSourceKindKey is the attribute Key conforming to the + // "messaging.source.kind" semantic conventions. It represents the kind of + // message source + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingSourceKindKey = attribute.Key("messaging.source.kind") + + // MessagingSourceTemplateKey is the attribute Key conforming to the + // "messaging.source.template" semantic conventions. It represents the low + // cardinality representation of the messaging source name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/customers/{customerID}' + // Note: Source names could be constructed from templates. An example would + // be a source name involving a user name or product id. Although the + // source name in this case is of high cardinality, the underlying template + // is of low cardinality and can be effectively used for grouping and + // aggregation. + MessagingSourceTemplateKey = attribute.Key("messaging.source.template") + + // MessagingSourceTemporaryKey is the attribute Key conforming to the + // "messaging.source.temporary" semantic conventions. It represents a + // boolean that is true if the message source is temporary and might not + // exist anymore after messages are processed. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingSourceTemporaryKey = attribute.Key("messaging.source.temporary") + + // MessagingSourceAnonymousKey is the attribute Key conforming to the + // "messaging.source.anonymous" semantic conventions. It represents a + // boolean that is true if the message source is anonymous (could be + // unnamed or have auto-generated name). + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingSourceAnonymousKey = attribute.Key("messaging.source.anonymous") +) + +var ( + // A message received from a queue + MessagingSourceKindQueue = MessagingSourceKindKey.String("queue") + // A message received from a topic + MessagingSourceKindTopic = MessagingSourceKindKey.String("topic") +) + +// MessagingSourceName returns an attribute KeyValue conforming to the +// "messaging.source.name" semantic conventions. It represents the message +// source name +func MessagingSourceName(val string) attribute.KeyValue { + return MessagingSourceNameKey.String(val) +} + +// MessagingSourceTemplate returns an attribute KeyValue conforming to the +// "messaging.source.template" semantic conventions. It represents the low +// cardinality representation of the messaging source name +func MessagingSourceTemplate(val string) attribute.KeyValue { + return MessagingSourceTemplateKey.String(val) +} + +// MessagingSourceTemporary returns an attribute KeyValue conforming to the +// "messaging.source.temporary" semantic conventions. It represents a boolean +// that is true if the message source is temporary and might not exist anymore +// after messages are processed. +func MessagingSourceTemporary(val bool) attribute.KeyValue { + return MessagingSourceTemporaryKey.Bool(val) +} + +// MessagingSourceAnonymous returns an attribute KeyValue conforming to the +// "messaging.source.anonymous" semantic conventions. It represents a boolean +// that is true if the message source is anonymous (could be unnamed or have +// auto-generated name). +func MessagingSourceAnonymous(val bool) attribute.KeyValue { + return MessagingSourceAnonymousKey.Bool(val) +} + +// General attributes used in messaging systems. +const ( + // MessagingSystemKey is the attribute Key conforming to the + // "messaging.system" semantic conventions. It represents a string + // identifying the messaging system. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS' + MessagingSystemKey = attribute.Key("messaging.system") + + // MessagingOperationKey is the attribute Key conforming to the + // "messaging.operation" semantic conventions. It represents a string + // identifying the kind of messaging operation as defined in the [Operation + // names](#operation-names) section above. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: If a custom value is used, it MUST be of low cardinality. + MessagingOperationKey = attribute.Key("messaging.operation") + + // MessagingBatchMessageCountKey is the attribute Key conforming to the + // "messaging.batch.message_count" semantic conventions. It represents the + // number of messages sent, received, or processed in the scope of the + // batching operation. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the span describes an + // operation on a batch of messages.) + // Stability: stable + // Examples: 0, 1, 2 + // Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on + // spans that operate with a single message. When a messaging client + // library supports both batch and single-message API for the same + // operation, instrumentations SHOULD use `messaging.batch.message_count` + // for batching APIs and SHOULD NOT use it for single-message APIs. + MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count") +) + +var ( + // publish + MessagingOperationPublish = MessagingOperationKey.String("publish") + // receive + MessagingOperationReceive = MessagingOperationKey.String("receive") + // process + MessagingOperationProcess = MessagingOperationKey.String("process") +) + +// MessagingSystem returns an attribute KeyValue conforming to the +// "messaging.system" semantic conventions. It represents a string identifying +// the messaging system. +func MessagingSystem(val string) attribute.KeyValue { + return MessagingSystemKey.String(val) +} + +// MessagingBatchMessageCount returns an attribute KeyValue conforming to +// the "messaging.batch.message_count" semantic conventions. It represents the +// number of messages sent, received, or processed in the scope of the batching +// operation. +func MessagingBatchMessageCount(val int) attribute.KeyValue { + return MessagingBatchMessageCountKey.Int(val) +} + +// Semantic convention for a consumer of messages received from a messaging +// system +const ( + // MessagingConsumerIDKey is the attribute Key conforming to the + // "messaging.consumer.id" semantic conventions. It represents the + // identifier for the consumer receiving a message. For Kafka, set it to + // `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if + // both are present, or only `messaging.kafka.consumer.group`. For brokers, + // such as RabbitMQ and Artemis, set it to the `client_id` of the client + // consuming the message. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'mygroup - client-6' + MessagingConsumerIDKey = attribute.Key("messaging.consumer.id") +) + +// MessagingConsumerID returns an attribute KeyValue conforming to the +// "messaging.consumer.id" semantic conventions. It represents the identifier +// for the consumer receiving a message. For Kafka, set it to +// `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if both +// are present, or only `messaging.kafka.consumer.group`. For brokers, such as +// RabbitMQ and Artemis, set it to the `client_id` of the client consuming the +// message. +func MessagingConsumerID(val string) attribute.KeyValue { + return MessagingConsumerIDKey.String(val) +} + +// Attributes for RabbitMQ +const ( + // MessagingRabbitmqDestinationRoutingKeyKey is the attribute Key + // conforming to the "messaging.rabbitmq.destination.routing_key" semantic + // conventions. It represents the rabbitMQ message routing key. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If not empty.) + // Stability: stable + // Examples: 'myKey' + MessagingRabbitmqDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key") +) + +// MessagingRabbitmqDestinationRoutingKey returns an attribute KeyValue +// conforming to the "messaging.rabbitmq.destination.routing_key" semantic +// conventions. It represents the rabbitMQ message routing key. +func MessagingRabbitmqDestinationRoutingKey(val string) attribute.KeyValue { + return MessagingRabbitmqDestinationRoutingKeyKey.String(val) +} + +// Attributes for Apache Kafka +const ( + // MessagingKafkaMessageKeyKey is the attribute Key conforming to the + // "messaging.kafka.message.key" semantic conventions. It represents the + // message keys in Kafka are used for grouping alike messages to ensure + // they're processed on the same partition. They differ from + // `messaging.message.id` in that they're not unique. If the key is `null`, + // the attribute MUST NOT be set. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'myKey' + // Note: If the key type is not string, it's string representation has to + // be supplied for the attribute. If the key has no unambiguous, canonical + // string form, don't include its value. + MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key") + + // MessagingKafkaConsumerGroupKey is the attribute Key conforming to the + // "messaging.kafka.consumer.group" semantic conventions. It represents the + // name of the Kafka Consumer Group that is handling the message. Only + // applies to consumers, not producers. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'my-group' + MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer.group") + + // MessagingKafkaClientIDKey is the attribute Key conforming to the + // "messaging.kafka.client_id" semantic conventions. It represents the + // client ID for the Consumer or Producer that is handling the message. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'client-5' + MessagingKafkaClientIDKey = attribute.Key("messaging.kafka.client_id") + + // MessagingKafkaDestinationPartitionKey is the attribute Key conforming to + // the "messaging.kafka.destination.partition" semantic conventions. It + // represents the partition the message is sent to. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2 + MessagingKafkaDestinationPartitionKey = attribute.Key("messaging.kafka.destination.partition") + + // MessagingKafkaSourcePartitionKey is the attribute Key conforming to the + // "messaging.kafka.source.partition" semantic conventions. It represents + // the partition the message is received from. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2 + MessagingKafkaSourcePartitionKey = attribute.Key("messaging.kafka.source.partition") + + // MessagingKafkaMessageOffsetKey is the attribute Key conforming to the + // "messaging.kafka.message.offset" semantic conventions. It represents the + // offset of a record in the corresponding Kafka partition. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + MessagingKafkaMessageOffsetKey = attribute.Key("messaging.kafka.message.offset") + + // MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the + // "messaging.kafka.message.tombstone" semantic conventions. It represents + // a boolean that is true if the message is a tombstone. + // + // Type: boolean + // RequirementLevel: ConditionallyRequired (If value is `true`. When + // missing, the value is assumed to be `false`.) + // Stability: stable + MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone") +) + +// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the +// "messaging.kafka.message.key" semantic conventions. It represents the +// message keys in Kafka are used for grouping alike messages to ensure they're +// processed on the same partition. They differ from `messaging.message.id` in +// that they're not unique. If the key is `null`, the attribute MUST NOT be +// set. +func MessagingKafkaMessageKey(val string) attribute.KeyValue { + return MessagingKafkaMessageKeyKey.String(val) +} + +// MessagingKafkaConsumerGroup returns an attribute KeyValue conforming to +// the "messaging.kafka.consumer.group" semantic conventions. It represents the +// name of the Kafka Consumer Group that is handling the message. Only applies +// to consumers, not producers. +func MessagingKafkaConsumerGroup(val string) attribute.KeyValue { + return MessagingKafkaConsumerGroupKey.String(val) +} + +// MessagingKafkaClientID returns an attribute KeyValue conforming to the +// "messaging.kafka.client_id" semantic conventions. It represents the client +// ID for the Consumer or Producer that is handling the message. +func MessagingKafkaClientID(val string) attribute.KeyValue { + return MessagingKafkaClientIDKey.String(val) +} + +// MessagingKafkaDestinationPartition returns an attribute KeyValue +// conforming to the "messaging.kafka.destination.partition" semantic +// conventions. It represents the partition the message is sent to. +func MessagingKafkaDestinationPartition(val int) attribute.KeyValue { + return MessagingKafkaDestinationPartitionKey.Int(val) +} + +// MessagingKafkaSourcePartition returns an attribute KeyValue conforming to +// the "messaging.kafka.source.partition" semantic conventions. It represents +// the partition the message is received from. +func MessagingKafkaSourcePartition(val int) attribute.KeyValue { + return MessagingKafkaSourcePartitionKey.Int(val) +} + +// MessagingKafkaMessageOffset returns an attribute KeyValue conforming to +// the "messaging.kafka.message.offset" semantic conventions. It represents the +// offset of a record in the corresponding Kafka partition. +func MessagingKafkaMessageOffset(val int) attribute.KeyValue { + return MessagingKafkaMessageOffsetKey.Int(val) +} + +// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming +// to the "messaging.kafka.message.tombstone" semantic conventions. It +// represents a boolean that is true if the message is a tombstone. +func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue { + return MessagingKafkaMessageTombstoneKey.Bool(val) +} + +// Attributes for Apache RocketMQ +const ( + // MessagingRocketmqNamespaceKey is the attribute Key conforming to the + // "messaging.rocketmq.namespace" semantic conventions. It represents the + // namespace of RocketMQ resources, resources in different namespaces are + // individual. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myNamespace' + MessagingRocketmqNamespaceKey = attribute.Key("messaging.rocketmq.namespace") + + // MessagingRocketmqClientGroupKey is the attribute Key conforming to the + // "messaging.rocketmq.client_group" semantic conventions. It represents + // the name of the RocketMQ producer/consumer group that is handling the + // message. The client type is identified by the SpanKind. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myConsumerGroup' + MessagingRocketmqClientGroupKey = attribute.Key("messaging.rocketmq.client_group") + + // MessagingRocketmqClientIDKey is the attribute Key conforming to the + // "messaging.rocketmq.client_id" semantic conventions. It represents the + // unique identifier for each client. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myhost@8742@s8083jm' + MessagingRocketmqClientIDKey = attribute.Key("messaging.rocketmq.client_id") + + // MessagingRocketmqMessageDeliveryTimestampKey is the attribute Key + // conforming to the "messaging.rocketmq.message.delivery_timestamp" + // semantic conventions. It represents the timestamp in milliseconds that + // the delay message is expected to be delivered to consumer. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the message type is delay + // and delay time level is not specified.) + // Stability: stable + // Examples: 1665987217045 + MessagingRocketmqMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp") + + // MessagingRocketmqMessageDelayTimeLevelKey is the attribute Key + // conforming to the "messaging.rocketmq.message.delay_time_level" semantic + // conventions. It represents the delay time level for delay message, which + // determines the message delay time. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the message type is delay + // and delivery timestamp is not specified.) + // Stability: stable + // Examples: 3 + MessagingRocketmqMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level") + + // MessagingRocketmqMessageGroupKey is the attribute Key conforming to the + // "messaging.rocketmq.message.group" semantic conventions. It represents + // the it is essential for FIFO message. Messages that belong to the same + // message group are always processed one by one within the same consumer + // group. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If the message type is FIFO.) + // Stability: stable + // Examples: 'myMessageGroup' + MessagingRocketmqMessageGroupKey = attribute.Key("messaging.rocketmq.message.group") + + // MessagingRocketmqMessageTypeKey is the attribute Key conforming to the + // "messaging.rocketmq.message.type" semantic conventions. It represents + // the type of message. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingRocketmqMessageTypeKey = attribute.Key("messaging.rocketmq.message.type") + + // MessagingRocketmqMessageTagKey is the attribute Key conforming to the + // "messaging.rocketmq.message.tag" semantic conventions. It represents the + // secondary classifier of message besides topic. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'tagA' + MessagingRocketmqMessageTagKey = attribute.Key("messaging.rocketmq.message.tag") + + // MessagingRocketmqMessageKeysKey is the attribute Key conforming to the + // "messaging.rocketmq.message.keys" semantic conventions. It represents + // the key(s) of message, another way to mark message besides message id. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'keyA', 'keyB' + MessagingRocketmqMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys") + + // MessagingRocketmqConsumptionModelKey is the attribute Key conforming to + // the "messaging.rocketmq.consumption_model" semantic conventions. It + // represents the model of message consumption. This only applies to + // consumer spans. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingRocketmqConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model") +) + +var ( + // Normal message + MessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String("normal") + // FIFO message + MessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String("fifo") + // Delay message + MessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String("delay") + // Transaction message + MessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String("transaction") +) + +var ( + // Clustering consumption model + MessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String("clustering") + // Broadcasting consumption model + MessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String("broadcasting") +) + +// MessagingRocketmqNamespace returns an attribute KeyValue conforming to +// the "messaging.rocketmq.namespace" semantic conventions. It represents the +// namespace of RocketMQ resources, resources in different namespaces are +// individual. +func MessagingRocketmqNamespace(val string) attribute.KeyValue { + return MessagingRocketmqNamespaceKey.String(val) +} + +// MessagingRocketmqClientGroup returns an attribute KeyValue conforming to +// the "messaging.rocketmq.client_group" semantic conventions. It represents +// the name of the RocketMQ producer/consumer group that is handling the +// message. The client type is identified by the SpanKind. +func MessagingRocketmqClientGroup(val string) attribute.KeyValue { + return MessagingRocketmqClientGroupKey.String(val) +} + +// MessagingRocketmqClientID returns an attribute KeyValue conforming to the +// "messaging.rocketmq.client_id" semantic conventions. It represents the +// unique identifier for each client. +func MessagingRocketmqClientID(val string) attribute.KeyValue { + return MessagingRocketmqClientIDKey.String(val) +} + +// MessagingRocketmqMessageDeliveryTimestamp returns an attribute KeyValue +// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic +// conventions. It represents the timestamp in milliseconds that the delay +// message is expected to be delivered to consumer. +func MessagingRocketmqMessageDeliveryTimestamp(val int) attribute.KeyValue { + return MessagingRocketmqMessageDeliveryTimestampKey.Int(val) +} + +// MessagingRocketmqMessageDelayTimeLevel returns an attribute KeyValue +// conforming to the "messaging.rocketmq.message.delay_time_level" semantic +// conventions. It represents the delay time level for delay message, which +// determines the message delay time. +func MessagingRocketmqMessageDelayTimeLevel(val int) attribute.KeyValue { + return MessagingRocketmqMessageDelayTimeLevelKey.Int(val) +} + +// MessagingRocketmqMessageGroup returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.group" semantic conventions. It represents +// the it is essential for FIFO message. Messages that belong to the same +// message group are always processed one by one within the same consumer +// group. +func MessagingRocketmqMessageGroup(val string) attribute.KeyValue { + return MessagingRocketmqMessageGroupKey.String(val) +} + +// MessagingRocketmqMessageTag returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.tag" semantic conventions. It represents the +// secondary classifier of message besides topic. +func MessagingRocketmqMessageTag(val string) attribute.KeyValue { + return MessagingRocketmqMessageTagKey.String(val) +} + +// MessagingRocketmqMessageKeys returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.keys" semantic conventions. It represents +// the key(s) of message, another way to mark message besides message id. +func MessagingRocketmqMessageKeys(val ...string) attribute.KeyValue { + return MessagingRocketmqMessageKeysKey.StringSlice(val) +} + +// Semantic conventions for remote procedure calls. +const ( + // RPCSystemKey is the attribute Key conforming to the "rpc.system" + // semantic conventions. It represents a string identifying the remoting + // system. See below for a list of well-known identifiers. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + RPCSystemKey = attribute.Key("rpc.system") + + // RPCServiceKey is the attribute Key conforming to the "rpc.service" + // semantic conventions. It represents the full (logical) name of the + // service being called, including its package name, if applicable. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'myservice.EchoService' + // Note: This is the logical name of the service from the RPC interface + // perspective, which can be different from the name of any implementing + // class. The `code.namespace` attribute may be used to store the latter + // (despite the attribute name, it may include a class name; e.g., class + // with method actually executing the call on the server side, RPC client + // stub class on the client side). + RPCServiceKey = attribute.Key("rpc.service") + + // RPCMethodKey is the attribute Key conforming to the "rpc.method" + // semantic conventions. It represents the name of the (logical) method + // being called, must be equal to the $method part in the span name. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'exampleMethod' + // Note: This is the logical name of the method from the RPC interface + // perspective, which can be different from the name of any implementing + // method/function. The `code.function` attribute may be used to store the + // latter (e.g., method actually executing the call on the server side, RPC + // client stub method on the client side). + RPCMethodKey = attribute.Key("rpc.method") +) + +var ( + // gRPC + RPCSystemGRPC = RPCSystemKey.String("grpc") + // Java RMI + RPCSystemJavaRmi = RPCSystemKey.String("java_rmi") + // .NET WCF + RPCSystemDotnetWcf = RPCSystemKey.String("dotnet_wcf") + // Apache Dubbo + RPCSystemApacheDubbo = RPCSystemKey.String("apache_dubbo") +) + +// RPCService returns an attribute KeyValue conforming to the "rpc.service" +// semantic conventions. It represents the full (logical) name of the service +// being called, including its package name, if applicable. +func RPCService(val string) attribute.KeyValue { + return RPCServiceKey.String(val) +} + +// RPCMethod returns an attribute KeyValue conforming to the "rpc.method" +// semantic conventions. It represents the name of the (logical) method being +// called, must be equal to the $method part in the span name. +func RPCMethod(val string) attribute.KeyValue { + return RPCMethodKey.String(val) +} + +// Tech-specific attributes for gRPC. +const ( + // RPCGRPCStatusCodeKey is the attribute Key conforming to the + // "rpc.grpc.status_code" semantic conventions. It represents the [numeric + // status + // code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of + // the gRPC request. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code") +) + +var ( + // OK + RPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0) + // CANCELLED + RPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1) + // UNKNOWN + RPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2) + // INVALID_ARGUMENT + RPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3) + // DEADLINE_EXCEEDED + RPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4) + // NOT_FOUND + RPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5) + // ALREADY_EXISTS + RPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6) + // PERMISSION_DENIED + RPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7) + // RESOURCE_EXHAUSTED + RPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8) + // FAILED_PRECONDITION + RPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9) + // ABORTED + RPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10) + // OUT_OF_RANGE + RPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11) + // UNIMPLEMENTED + RPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12) + // INTERNAL + RPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13) + // UNAVAILABLE + RPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14) + // DATA_LOSS + RPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15) + // UNAUTHENTICATED + RPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16) +) + +// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/). +const ( + // RPCJsonrpcVersionKey is the attribute Key conforming to the + // "rpc.jsonrpc.version" semantic conventions. It represents the protocol + // version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 + // does not specify this, the value can be omitted. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If other than the default + // version (`1.0`)) + // Stability: stable + // Examples: '2.0', '1.0' + RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version") + + // RPCJsonrpcRequestIDKey is the attribute Key conforming to the + // "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` + // property of request or response. Since protocol allows id to be int, + // string, `null` or missing (for notifications), value is expected to be + // cast to string for simplicity. Use empty string in case of `null` value. + // Omit entirely if this is a notification. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '10', 'request-7', '' + RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id") + + // RPCJsonrpcErrorCodeKey is the attribute Key conforming to the + // "rpc.jsonrpc.error_code" semantic conventions. It represents the + // `error.code` property of response if it is an error response. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If response is not successful.) + // Stability: stable + // Examples: -32700, 100 + RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code") + + // RPCJsonrpcErrorMessageKey is the attribute Key conforming to the + // "rpc.jsonrpc.error_message" semantic conventions. It represents the + // `error.message` property of response if it is an error response. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Parse error', 'User already exists' + RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message") +) + +// RPCJsonrpcVersion returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.version" semantic conventions. It represents the protocol +// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 +// does not specify this, the value can be omitted. +func RPCJsonrpcVersion(val string) attribute.KeyValue { + return RPCJsonrpcVersionKey.String(val) +} + +// RPCJsonrpcRequestID returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` +// property of request or response. Since protocol allows id to be int, string, +// `null` or missing (for notifications), value is expected to be cast to +// string for simplicity. Use empty string in case of `null` value. Omit +// entirely if this is a notification. +func RPCJsonrpcRequestID(val string) attribute.KeyValue { + return RPCJsonrpcRequestIDKey.String(val) +} + +// RPCJsonrpcErrorCode returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.error_code" semantic conventions. It represents the +// `error.code` property of response if it is an error response. +func RPCJsonrpcErrorCode(val int) attribute.KeyValue { + return RPCJsonrpcErrorCodeKey.Int(val) +} + +// RPCJsonrpcErrorMessage returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.error_message" semantic conventions. It represents the +// `error.message` property of response if it is an error response. +func RPCJsonrpcErrorMessage(val string) attribute.KeyValue { + return RPCJsonrpcErrorMessageKey.String(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go new file mode 100644 index 00000000000..e6cf8951053 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go @@ -0,0 +1,1877 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +import "go.opentelemetry.io/otel/attribute" + +// These attributes may be used to describe the client in a connection-based +// network interaction where there is one side that initiates the connection +// (the client is the side that initiates the connection). This covers all TCP +// network interactions since TCP is connection-based and one side initiates +// the connection (an exception is made for peer-to-peer communication over TCP +// where the "user-facing" surface of the protocol / API does not expose a +// clear notion of client and server). This also covers UDP network +// interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) +// and DNS. +const ( + // ClientAddressKey is the attribute Key conforming to the "client.address" + // semantic conventions. It represents the client address - unix domain + // socket name, IPv4 or IPv6 address. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/tmp/my.sock', '10.1.2.80' + // Note: When observed from the server side, and when communicating through + // an intermediary, `client.address` SHOULD represent client address behind + // any intermediaries (e.g. proxies) if it's available. + ClientAddressKey = attribute.Key("client.address") + + // ClientPortKey is the attribute Key conforming to the "client.port" + // semantic conventions. It represents the client port number + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 65123 + // Note: When observed from the server side, and when communicating through + // an intermediary, `client.port` SHOULD represent client port behind any + // intermediaries (e.g. proxies) if it's available. + ClientPortKey = attribute.Key("client.port") + + // ClientSocketAddressKey is the attribute Key conforming to the + // "client.socket.address" semantic conventions. It represents the + // immediate client peer address - unix domain socket name, IPv4 or IPv6 + // address. + // + // Type: string + // RequirementLevel: Recommended (If different than `client.address`.) + // Stability: stable + // Examples: '/tmp/my.sock', '127.0.0.1' + ClientSocketAddressKey = attribute.Key("client.socket.address") + + // ClientSocketPortKey is the attribute Key conforming to the + // "client.socket.port" semantic conventions. It represents the immediate + // client peer port number + // + // Type: int + // RequirementLevel: Recommended (If different than `client.port`.) + // Stability: stable + // Examples: 35555 + ClientSocketPortKey = attribute.Key("client.socket.port") +) + +// ClientAddress returns an attribute KeyValue conforming to the +// "client.address" semantic conventions. It represents the client address - +// unix domain socket name, IPv4 or IPv6 address. +func ClientAddress(val string) attribute.KeyValue { + return ClientAddressKey.String(val) +} + +// ClientPort returns an attribute KeyValue conforming to the "client.port" +// semantic conventions. It represents the client port number +func ClientPort(val int) attribute.KeyValue { + return ClientPortKey.Int(val) +} + +// ClientSocketAddress returns an attribute KeyValue conforming to the +// "client.socket.address" semantic conventions. It represents the immediate +// client peer address - unix domain socket name, IPv4 or IPv6 address. +func ClientSocketAddress(val string) attribute.KeyValue { + return ClientSocketAddressKey.String(val) +} + +// ClientSocketPort returns an attribute KeyValue conforming to the +// "client.socket.port" semantic conventions. It represents the immediate +// client peer port number +func ClientSocketPort(val int) attribute.KeyValue { + return ClientSocketPortKey.Int(val) +} + +// Describes deprecated HTTP attributes. +const ( + // HTTPMethodKey is the attribute Key conforming to the "http.method" + // semantic conventions. It represents the deprecated, use + // `http.request.method` instead. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'GET', 'POST', 'HEAD' + HTTPMethodKey = attribute.Key("http.method") + + // HTTPStatusCodeKey is the attribute Key conforming to the + // "http.status_code" semantic conventions. It represents the deprecated, + // use `http.response.status_code` instead. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 200 + HTTPStatusCodeKey = attribute.Key("http.status_code") + + // HTTPSchemeKey is the attribute Key conforming to the "http.scheme" + // semantic conventions. It represents the deprecated, use `url.scheme` + // instead. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'http', 'https' + HTTPSchemeKey = attribute.Key("http.scheme") + + // HTTPURLKey is the attribute Key conforming to the "http.url" semantic + // conventions. It represents the deprecated, use `url.full` instead. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv' + HTTPURLKey = attribute.Key("http.url") + + // HTTPTargetKey is the attribute Key conforming to the "http.target" + // semantic conventions. It represents the deprecated, use `url.path` and + // `url.query` instead. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '/search?q=OpenTelemetry#SemConv' + HTTPTargetKey = attribute.Key("http.target") + + // HTTPRequestContentLengthKey is the attribute Key conforming to the + // "http.request_content_length" semantic conventions. It represents the + // deprecated, use `http.request.body.size` instead. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 3495 + HTTPRequestContentLengthKey = attribute.Key("http.request_content_length") + + // HTTPResponseContentLengthKey is the attribute Key conforming to the + // "http.response_content_length" semantic conventions. It represents the + // deprecated, use `http.response.body.size` instead. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 3495 + HTTPResponseContentLengthKey = attribute.Key("http.response_content_length") +) + +// HTTPMethod returns an attribute KeyValue conforming to the "http.method" +// semantic conventions. It represents the deprecated, use +// `http.request.method` instead. +func HTTPMethod(val string) attribute.KeyValue { + return HTTPMethodKey.String(val) +} + +// HTTPStatusCode returns an attribute KeyValue conforming to the +// "http.status_code" semantic conventions. It represents the deprecated, use +// `http.response.status_code` instead. +func HTTPStatusCode(val int) attribute.KeyValue { + return HTTPStatusCodeKey.Int(val) +} + +// HTTPScheme returns an attribute KeyValue conforming to the "http.scheme" +// semantic conventions. It represents the deprecated, use `url.scheme` +// instead. +func HTTPScheme(val string) attribute.KeyValue { + return HTTPSchemeKey.String(val) +} + +// HTTPURL returns an attribute KeyValue conforming to the "http.url" +// semantic conventions. It represents the deprecated, use `url.full` instead. +func HTTPURL(val string) attribute.KeyValue { + return HTTPURLKey.String(val) +} + +// HTTPTarget returns an attribute KeyValue conforming to the "http.target" +// semantic conventions. It represents the deprecated, use `url.path` and +// `url.query` instead. +func HTTPTarget(val string) attribute.KeyValue { + return HTTPTargetKey.String(val) +} + +// HTTPRequestContentLength returns an attribute KeyValue conforming to the +// "http.request_content_length" semantic conventions. It represents the +// deprecated, use `http.request.body.size` instead. +func HTTPRequestContentLength(val int) attribute.KeyValue { + return HTTPRequestContentLengthKey.Int(val) +} + +// HTTPResponseContentLength returns an attribute KeyValue conforming to the +// "http.response_content_length" semantic conventions. It represents the +// deprecated, use `http.response.body.size` instead. +func HTTPResponseContentLength(val int) attribute.KeyValue { + return HTTPResponseContentLengthKey.Int(val) +} + +// These attributes may be used for any network related operation. +const ( + // NetSockPeerNameKey is the attribute Key conforming to the + // "net.sock.peer.name" semantic conventions. It represents the deprecated, + // use `server.socket.domain` on client spans. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '/var/my.sock' + NetSockPeerNameKey = attribute.Key("net.sock.peer.name") + + // NetSockPeerAddrKey is the attribute Key conforming to the + // "net.sock.peer.addr" semantic conventions. It represents the deprecated, + // use `server.socket.address` on client spans and `client.socket.address` + // on server spans. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '192.168.0.1' + NetSockPeerAddrKey = attribute.Key("net.sock.peer.addr") + + // NetSockPeerPortKey is the attribute Key conforming to the + // "net.sock.peer.port" semantic conventions. It represents the deprecated, + // use `server.socket.port` on client spans and `client.socket.port` on + // server spans. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 65531 + NetSockPeerPortKey = attribute.Key("net.sock.peer.port") + + // NetPeerNameKey is the attribute Key conforming to the "net.peer.name" + // semantic conventions. It represents the deprecated, use `server.address` + // on client spans and `client.address` on server spans. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'example.com' + NetPeerNameKey = attribute.Key("net.peer.name") + + // NetPeerPortKey is the attribute Key conforming to the "net.peer.port" + // semantic conventions. It represents the deprecated, use `server.port` on + // client spans and `client.port` on server spans. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 8080 + NetPeerPortKey = attribute.Key("net.peer.port") + + // NetHostNameKey is the attribute Key conforming to the "net.host.name" + // semantic conventions. It represents the deprecated, use + // `server.address`. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'example.com' + NetHostNameKey = attribute.Key("net.host.name") + + // NetHostPortKey is the attribute Key conforming to the "net.host.port" + // semantic conventions. It represents the deprecated, use `server.port`. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 8080 + NetHostPortKey = attribute.Key("net.host.port") + + // NetSockHostAddrKey is the attribute Key conforming to the + // "net.sock.host.addr" semantic conventions. It represents the deprecated, + // use `server.socket.address`. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '/var/my.sock' + NetSockHostAddrKey = attribute.Key("net.sock.host.addr") + + // NetSockHostPortKey is the attribute Key conforming to the + // "net.sock.host.port" semantic conventions. It represents the deprecated, + // use `server.socket.port`. + // + // Type: int + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 8080 + NetSockHostPortKey = attribute.Key("net.sock.host.port") + + // NetTransportKey is the attribute Key conforming to the "net.transport" + // semantic conventions. It represents the deprecated, use + // `network.transport`. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: deprecated + NetTransportKey = attribute.Key("net.transport") + + // NetProtocolNameKey is the attribute Key conforming to the + // "net.protocol.name" semantic conventions. It represents the deprecated, + // use `network.protocol.name`. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'amqp', 'http', 'mqtt' + NetProtocolNameKey = attribute.Key("net.protocol.name") + + // NetProtocolVersionKey is the attribute Key conforming to the + // "net.protocol.version" semantic conventions. It represents the + // deprecated, use `network.protocol.version`. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '3.1.1' + NetProtocolVersionKey = attribute.Key("net.protocol.version") + + // NetSockFamilyKey is the attribute Key conforming to the + // "net.sock.family" semantic conventions. It represents the deprecated, + // use `network.transport` and `network.type`. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: deprecated + NetSockFamilyKey = attribute.Key("net.sock.family") +) + +var ( + // ip_tcp + NetTransportTCP = NetTransportKey.String("ip_tcp") + // ip_udp + NetTransportUDP = NetTransportKey.String("ip_udp") + // Named or anonymous pipe + NetTransportPipe = NetTransportKey.String("pipe") + // In-process communication + NetTransportInProc = NetTransportKey.String("inproc") + // Something else (non IP-based) + NetTransportOther = NetTransportKey.String("other") +) + +var ( + // IPv4 address + NetSockFamilyInet = NetSockFamilyKey.String("inet") + // IPv6 address + NetSockFamilyInet6 = NetSockFamilyKey.String("inet6") + // Unix domain socket path + NetSockFamilyUnix = NetSockFamilyKey.String("unix") +) + +// NetSockPeerName returns an attribute KeyValue conforming to the +// "net.sock.peer.name" semantic conventions. It represents the deprecated, use +// `server.socket.domain` on client spans. +func NetSockPeerName(val string) attribute.KeyValue { + return NetSockPeerNameKey.String(val) +} + +// NetSockPeerAddr returns an attribute KeyValue conforming to the +// "net.sock.peer.addr" semantic conventions. It represents the deprecated, use +// `server.socket.address` on client spans and `client.socket.address` on +// server spans. +func NetSockPeerAddr(val string) attribute.KeyValue { + return NetSockPeerAddrKey.String(val) +} + +// NetSockPeerPort returns an attribute KeyValue conforming to the +// "net.sock.peer.port" semantic conventions. It represents the deprecated, use +// `server.socket.port` on client spans and `client.socket.port` on server +// spans. +func NetSockPeerPort(val int) attribute.KeyValue { + return NetSockPeerPortKey.Int(val) +} + +// NetPeerName returns an attribute KeyValue conforming to the +// "net.peer.name" semantic conventions. It represents the deprecated, use +// `server.address` on client spans and `client.address` on server spans. +func NetPeerName(val string) attribute.KeyValue { + return NetPeerNameKey.String(val) +} + +// NetPeerPort returns an attribute KeyValue conforming to the +// "net.peer.port" semantic conventions. It represents the deprecated, use +// `server.port` on client spans and `client.port` on server spans. +func NetPeerPort(val int) attribute.KeyValue { + return NetPeerPortKey.Int(val) +} + +// NetHostName returns an attribute KeyValue conforming to the +// "net.host.name" semantic conventions. It represents the deprecated, use +// `server.address`. +func NetHostName(val string) attribute.KeyValue { + return NetHostNameKey.String(val) +} + +// NetHostPort returns an attribute KeyValue conforming to the +// "net.host.port" semantic conventions. It represents the deprecated, use +// `server.port`. +func NetHostPort(val int) attribute.KeyValue { + return NetHostPortKey.Int(val) +} + +// NetSockHostAddr returns an attribute KeyValue conforming to the +// "net.sock.host.addr" semantic conventions. It represents the deprecated, use +// `server.socket.address`. +func NetSockHostAddr(val string) attribute.KeyValue { + return NetSockHostAddrKey.String(val) +} + +// NetSockHostPort returns an attribute KeyValue conforming to the +// "net.sock.host.port" semantic conventions. It represents the deprecated, use +// `server.socket.port`. +func NetSockHostPort(val int) attribute.KeyValue { + return NetSockHostPortKey.Int(val) +} + +// NetProtocolName returns an attribute KeyValue conforming to the +// "net.protocol.name" semantic conventions. It represents the deprecated, use +// `network.protocol.name`. +func NetProtocolName(val string) attribute.KeyValue { + return NetProtocolNameKey.String(val) +} + +// NetProtocolVersion returns an attribute KeyValue conforming to the +// "net.protocol.version" semantic conventions. It represents the deprecated, +// use `network.protocol.version`. +func NetProtocolVersion(val string) attribute.KeyValue { + return NetProtocolVersionKey.String(val) +} + +// These attributes may be used to describe the receiver of a network +// exchange/packet. These should be used when there is no client/server +// relationship between the two sides, or when that relationship is unknown. +// This covers low-level network interactions (e.g. packet tracing) where you +// don't know if there was a connection or which side initiated it. This also +// covers unidirectional UDP flows and peer-to-peer communication where the +// "user-facing" surface of the protocol / API does not expose a clear notion +// of client and server. +const ( + // DestinationDomainKey is the attribute Key conforming to the + // "destination.domain" semantic conventions. It represents the domain name + // of the destination system. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'foo.example.com' + // Note: This value may be a host name, a fully qualified domain name, or + // another host naming format. + DestinationDomainKey = attribute.Key("destination.domain") + + // DestinationAddressKey is the attribute Key conforming to the + // "destination.address" semantic conventions. It represents the peer + // address, for example IP address or UNIX socket name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '10.5.3.2' + DestinationAddressKey = attribute.Key("destination.address") + + // DestinationPortKey is the attribute Key conforming to the + // "destination.port" semantic conventions. It represents the peer port + // number + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3389, 2888 + DestinationPortKey = attribute.Key("destination.port") +) + +// DestinationDomain returns an attribute KeyValue conforming to the +// "destination.domain" semantic conventions. It represents the domain name of +// the destination system. +func DestinationDomain(val string) attribute.KeyValue { + return DestinationDomainKey.String(val) +} + +// DestinationAddress returns an attribute KeyValue conforming to the +// "destination.address" semantic conventions. It represents the peer address, +// for example IP address or UNIX socket name. +func DestinationAddress(val string) attribute.KeyValue { + return DestinationAddressKey.String(val) +} + +// DestinationPort returns an attribute KeyValue conforming to the +// "destination.port" semantic conventions. It represents the peer port number +func DestinationPort(val int) attribute.KeyValue { + return DestinationPortKey.Int(val) +} + +// Describes HTTP attributes. +const ( + // HTTPRequestMethodKey is the attribute Key conforming to the + // "http.request.method" semantic conventions. It represents the hTTP + // request method. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Examples: 'GET', 'POST', 'HEAD' + // Note: HTTP request method value SHOULD be "known" to the + // instrumentation. + // By default, this convention defines "known" methods as the ones listed + // in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + // and the PATCH method defined in + // [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + // + // If the HTTP request method is not known to instrumentation, it MUST set + // the `http.request.method` attribute to `_OTHER` and, except if reporting + // a metric, MUST + // set the exact method received in the request line as value of the + // `http.request.method_original` attribute. + // + // If the HTTP instrumentation could end up converting valid HTTP request + // methods to `_OTHER`, then it MUST provide a way to override + // the list of known HTTP methods. If this override is done via environment + // variable, then the environment variable MUST be named + // OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated + // list of case-sensitive known HTTP methods + // (this list MUST be a full override of the default known method, it is + // not a list of known methods in addition to the defaults). + // + // HTTP method names are case-sensitive and `http.request.method` attribute + // value MUST match a known HTTP method name exactly. + // Instrumentations for specific web frameworks that consider HTTP methods + // to be case insensitive, SHOULD populate a canonical equivalent. + // Tracing instrumentations that do so, MUST also set + // `http.request.method_original` to the original value. + HTTPRequestMethodKey = attribute.Key("http.request.method") + + // HTTPResponseStatusCodeKey is the attribute Key conforming to the + // "http.response.status_code" semantic conventions. It represents the + // [HTTP response status + // code](https://tools.ietf.org/html/rfc7231#section-6). + // + // Type: int + // RequirementLevel: ConditionallyRequired (If and only if one was + // received/sent.) + // Stability: stable + // Examples: 200 + HTTPResponseStatusCodeKey = attribute.Key("http.response.status_code") +) + +var ( + // CONNECT method + HTTPRequestMethodConnect = HTTPRequestMethodKey.String("CONNECT") + // DELETE method + HTTPRequestMethodDelete = HTTPRequestMethodKey.String("DELETE") + // GET method + HTTPRequestMethodGet = HTTPRequestMethodKey.String("GET") + // HEAD method + HTTPRequestMethodHead = HTTPRequestMethodKey.String("HEAD") + // OPTIONS method + HTTPRequestMethodOptions = HTTPRequestMethodKey.String("OPTIONS") + // PATCH method + HTTPRequestMethodPatch = HTTPRequestMethodKey.String("PATCH") + // POST method + HTTPRequestMethodPost = HTTPRequestMethodKey.String("POST") + // PUT method + HTTPRequestMethodPut = HTTPRequestMethodKey.String("PUT") + // TRACE method + HTTPRequestMethodTrace = HTTPRequestMethodKey.String("TRACE") + // Any HTTP method that the instrumentation has no prior knowledge of + HTTPRequestMethodOther = HTTPRequestMethodKey.String("_OTHER") +) + +// HTTPResponseStatusCode returns an attribute KeyValue conforming to the +// "http.response.status_code" semantic conventions. It represents the [HTTP +// response status code](https://tools.ietf.org/html/rfc7231#section-6). +func HTTPResponseStatusCode(val int) attribute.KeyValue { + return HTTPResponseStatusCodeKey.Int(val) +} + +// HTTP Server attributes +const ( + // HTTPRouteKey is the attribute Key conforming to the "http.route" + // semantic conventions. It represents the matched route (path template in + // the format used by the respective server framework). See note below + // + // Type: string + // RequirementLevel: ConditionallyRequired (If and only if it's available) + // Stability: stable + // Examples: '/users/:userID?', '{controller}/{action}/{id?}' + // Note: MUST NOT be populated when this is not supported by the HTTP + // server framework as the route attribute should have low-cardinality and + // the URI path can NOT substitute it. + // SHOULD include the [application + // root](/docs/http/http-spans.md#http-server-definitions) if there is one. + HTTPRouteKey = attribute.Key("http.route") +) + +// HTTPRoute returns an attribute KeyValue conforming to the "http.route" +// semantic conventions. It represents the matched route (path template in the +// format used by the respective server framework). See note below +func HTTPRoute(val string) attribute.KeyValue { + return HTTPRouteKey.String(val) +} + +// Attributes for Events represented using Log Records. +const ( + // EventNameKey is the attribute Key conforming to the "event.name" + // semantic conventions. It represents the name identifies the event. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'click', 'exception' + EventNameKey = attribute.Key("event.name") + + // EventDomainKey is the attribute Key conforming to the "event.domain" + // semantic conventions. It represents the domain identifies the business + // context for the events. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: Events across different domains may have same `event.name`, yet be + // unrelated events. + EventDomainKey = attribute.Key("event.domain") +) + +var ( + // Events from browser apps + EventDomainBrowser = EventDomainKey.String("browser") + // Events from mobile apps + EventDomainDevice = EventDomainKey.String("device") + // Events from Kubernetes + EventDomainK8S = EventDomainKey.String("k8s") +) + +// EventName returns an attribute KeyValue conforming to the "event.name" +// semantic conventions. It represents the name identifies the event. +func EventName(val string) attribute.KeyValue { + return EventNameKey.String(val) +} + +// The attributes described in this section are rather generic. They may be +// used in any Log Record they apply to. +const ( + // LogRecordUIDKey is the attribute Key conforming to the "log.record.uid" + // semantic conventions. It represents a unique identifier for the Log + // Record. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '01ARZ3NDEKTSV4RRFFQ69G5FAV' + // Note: If an id is provided, other log records with the same id will be + // considered duplicates and can be removed safely. This means, that two + // distinguishable log records MUST have different values. + // The id MAY be an [Universally Unique Lexicographically Sortable + // Identifier (ULID)](https://github.com/ulid/spec), but other identifiers + // (e.g. UUID) may be used as needed. + LogRecordUIDKey = attribute.Key("log.record.uid") +) + +// LogRecordUID returns an attribute KeyValue conforming to the +// "log.record.uid" semantic conventions. It represents a unique identifier for +// the Log Record. +func LogRecordUID(val string) attribute.KeyValue { + return LogRecordUIDKey.String(val) +} + +// Describes Log attributes +const ( + // LogIostreamKey is the attribute Key conforming to the "log.iostream" + // semantic conventions. It represents the stream associated with the log. + // See below for a list of well-known values. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + LogIostreamKey = attribute.Key("log.iostream") +) + +var ( + // Logs from stdout stream + LogIostreamStdout = LogIostreamKey.String("stdout") + // Events from stderr stream + LogIostreamStderr = LogIostreamKey.String("stderr") +) + +// A file to which log was emitted. +const ( + // LogFileNameKey is the attribute Key conforming to the "log.file.name" + // semantic conventions. It represents the basename of the file. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'audit.log' + LogFileNameKey = attribute.Key("log.file.name") + + // LogFilePathKey is the attribute Key conforming to the "log.file.path" + // semantic conventions. It represents the full path to the file. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/var/log/mysql/audit.log' + LogFilePathKey = attribute.Key("log.file.path") + + // LogFileNameResolvedKey is the attribute Key conforming to the + // "log.file.name_resolved" semantic conventions. It represents the + // basename of the file, with symlinks resolved. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'uuid.log' + LogFileNameResolvedKey = attribute.Key("log.file.name_resolved") + + // LogFilePathResolvedKey is the attribute Key conforming to the + // "log.file.path_resolved" semantic conventions. It represents the full + // path to the file, with symlinks resolved. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/var/lib/docker/uuid.log' + LogFilePathResolvedKey = attribute.Key("log.file.path_resolved") +) + +// LogFileName returns an attribute KeyValue conforming to the +// "log.file.name" semantic conventions. It represents the basename of the +// file. +func LogFileName(val string) attribute.KeyValue { + return LogFileNameKey.String(val) +} + +// LogFilePath returns an attribute KeyValue conforming to the +// "log.file.path" semantic conventions. It represents the full path to the +// file. +func LogFilePath(val string) attribute.KeyValue { + return LogFilePathKey.String(val) +} + +// LogFileNameResolved returns an attribute KeyValue conforming to the +// "log.file.name_resolved" semantic conventions. It represents the basename of +// the file, with symlinks resolved. +func LogFileNameResolved(val string) attribute.KeyValue { + return LogFileNameResolvedKey.String(val) +} + +// LogFilePathResolved returns an attribute KeyValue conforming to the +// "log.file.path_resolved" semantic conventions. It represents the full path +// to the file, with symlinks resolved. +func LogFilePathResolved(val string) attribute.KeyValue { + return LogFilePathResolvedKey.String(val) +} + +// Describes JVM memory metric attributes. +const ( + // TypeKey is the attribute Key conforming to the "type" semantic + // conventions. It represents the type of memory. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'heap', 'non_heap' + TypeKey = attribute.Key("type") + + // PoolKey is the attribute Key conforming to the "pool" semantic + // conventions. It represents the name of the memory pool. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'G1 Old Gen', 'G1 Eden space', 'G1 Survivor Space' + // Note: Pool names are generally obtained via + // [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + PoolKey = attribute.Key("pool") +) + +var ( + // Heap memory + TypeHeap = TypeKey.String("heap") + // Non-heap memory + TypeNonHeap = TypeKey.String("non_heap") +) + +// Pool returns an attribute KeyValue conforming to the "pool" semantic +// conventions. It represents the name of the memory pool. +func Pool(val string) attribute.KeyValue { + return PoolKey.String(val) +} + +// These attributes may be used to describe the server in a connection-based +// network interaction where there is one side that initiates the connection +// (the client is the side that initiates the connection). This covers all TCP +// network interactions since TCP is connection-based and one side initiates +// the connection (an exception is made for peer-to-peer communication over TCP +// where the "user-facing" surface of the protocol / API does not expose a +// clear notion of client and server). This also covers UDP network +// interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) +// and DNS. +const ( + // ServerAddressKey is the attribute Key conforming to the "server.address" + // semantic conventions. It represents the logical server hostname, matches + // server FQDN if available, and IP or socket address if FQDN is not known. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'example.com' + ServerAddressKey = attribute.Key("server.address") + + // ServerPortKey is the attribute Key conforming to the "server.port" + // semantic conventions. It represents the logical server port number + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 80, 8080, 443 + ServerPortKey = attribute.Key("server.port") + + // ServerSocketDomainKey is the attribute Key conforming to the + // "server.socket.domain" semantic conventions. It represents the domain + // name of an immediate peer. + // + // Type: string + // RequirementLevel: Recommended (If different than `server.address`.) + // Stability: stable + // Examples: 'proxy.example.com' + // Note: Typically observed from the client side, and represents a proxy or + // other intermediary domain name. + ServerSocketDomainKey = attribute.Key("server.socket.domain") + + // ServerSocketAddressKey is the attribute Key conforming to the + // "server.socket.address" semantic conventions. It represents the physical + // server IP address or Unix socket address. If set from the client, should + // simply use the socket's peer address, and not attempt to find any actual + // server IP (i.e., if set from client, this may represent some proxy + // server instead of the logical server). + // + // Type: string + // RequirementLevel: Recommended (If different than `server.address`.) + // Stability: stable + // Examples: '10.5.3.2' + ServerSocketAddressKey = attribute.Key("server.socket.address") + + // ServerSocketPortKey is the attribute Key conforming to the + // "server.socket.port" semantic conventions. It represents the physical + // server port. + // + // Type: int + // RequirementLevel: Recommended (If different than `server.port`.) + // Stability: stable + // Examples: 16456 + ServerSocketPortKey = attribute.Key("server.socket.port") +) + +// ServerAddress returns an attribute KeyValue conforming to the +// "server.address" semantic conventions. It represents the logical server +// hostname, matches server FQDN if available, and IP or socket address if FQDN +// is not known. +func ServerAddress(val string) attribute.KeyValue { + return ServerAddressKey.String(val) +} + +// ServerPort returns an attribute KeyValue conforming to the "server.port" +// semantic conventions. It represents the logical server port number +func ServerPort(val int) attribute.KeyValue { + return ServerPortKey.Int(val) +} + +// ServerSocketDomain returns an attribute KeyValue conforming to the +// "server.socket.domain" semantic conventions. It represents the domain name +// of an immediate peer. +func ServerSocketDomain(val string) attribute.KeyValue { + return ServerSocketDomainKey.String(val) +} + +// ServerSocketAddress returns an attribute KeyValue conforming to the +// "server.socket.address" semantic conventions. It represents the physical +// server IP address or Unix socket address. If set from the client, should +// simply use the socket's peer address, and not attempt to find any actual +// server IP (i.e., if set from client, this may represent some proxy server +// instead of the logical server). +func ServerSocketAddress(val string) attribute.KeyValue { + return ServerSocketAddressKey.String(val) +} + +// ServerSocketPort returns an attribute KeyValue conforming to the +// "server.socket.port" semantic conventions. It represents the physical server +// port. +func ServerSocketPort(val int) attribute.KeyValue { + return ServerSocketPortKey.Int(val) +} + +// These attributes may be used to describe the sender of a network +// exchange/packet. These should be used when there is no client/server +// relationship between the two sides, or when that relationship is unknown. +// This covers low-level network interactions (e.g. packet tracing) where you +// don't know if there was a connection or which side initiated it. This also +// covers unidirectional UDP flows and peer-to-peer communication where the +// "user-facing" surface of the protocol / API does not expose a clear notion +// of client and server. +const ( + // SourceDomainKey is the attribute Key conforming to the "source.domain" + // semantic conventions. It represents the domain name of the source + // system. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'foo.example.com' + // Note: This value may be a host name, a fully qualified domain name, or + // another host naming format. + SourceDomainKey = attribute.Key("source.domain") + + // SourceAddressKey is the attribute Key conforming to the "source.address" + // semantic conventions. It represents the source address, for example IP + // address or Unix socket name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '10.5.3.2' + SourceAddressKey = attribute.Key("source.address") + + // SourcePortKey is the attribute Key conforming to the "source.port" + // semantic conventions. It represents the source port number + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3389, 2888 + SourcePortKey = attribute.Key("source.port") +) + +// SourceDomain returns an attribute KeyValue conforming to the +// "source.domain" semantic conventions. It represents the domain name of the +// source system. +func SourceDomain(val string) attribute.KeyValue { + return SourceDomainKey.String(val) +} + +// SourceAddress returns an attribute KeyValue conforming to the +// "source.address" semantic conventions. It represents the source address, for +// example IP address or Unix socket name. +func SourceAddress(val string) attribute.KeyValue { + return SourceAddressKey.String(val) +} + +// SourcePort returns an attribute KeyValue conforming to the "source.port" +// semantic conventions. It represents the source port number +func SourcePort(val int) attribute.KeyValue { + return SourcePortKey.Int(val) +} + +// These attributes may be used for any network related operation. +const ( + // NetworkTransportKey is the attribute Key conforming to the + // "network.transport" semantic conventions. It represents the [OSI + // Transport Layer](https://osi-model.com/transport-layer/) or + // [Inter-process Communication + // method](https://en.wikipedia.org/wiki/Inter-process_communication). The + // value SHOULD be normalized to lowercase. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'tcp', 'udp' + NetworkTransportKey = attribute.Key("network.transport") + + // NetworkTypeKey is the attribute Key conforming to the "network.type" + // semantic conventions. It represents the [OSI Network + // Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The + // value SHOULD be normalized to lowercase. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'ipv4', 'ipv6' + NetworkTypeKey = attribute.Key("network.type") + + // NetworkProtocolNameKey is the attribute Key conforming to the + // "network.protocol.name" semantic conventions. It represents the [OSI + // Application Layer](https://osi-model.com/application-layer/) or non-OSI + // equivalent. The value SHOULD be normalized to lowercase. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'amqp', 'http', 'mqtt' + NetworkProtocolNameKey = attribute.Key("network.protocol.name") + + // NetworkProtocolVersionKey is the attribute Key conforming to the + // "network.protocol.version" semantic conventions. It represents the + // version of the application layer protocol used. See note below. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '3.1.1' + // Note: `network.protocol.version` refers to the version of the protocol + // used and might be different from the protocol client's version. If the + // HTTP client used has a version of `0.27.2`, but sends HTTP version + // `1.1`, this attribute should be set to `1.1`. + NetworkProtocolVersionKey = attribute.Key("network.protocol.version") +) + +var ( + // TCP + NetworkTransportTCP = NetworkTransportKey.String("tcp") + // UDP + NetworkTransportUDP = NetworkTransportKey.String("udp") + // Named or anonymous pipe. See note below + NetworkTransportPipe = NetworkTransportKey.String("pipe") + // Unix domain socket + NetworkTransportUnix = NetworkTransportKey.String("unix") +) + +var ( + // IPv4 + NetworkTypeIpv4 = NetworkTypeKey.String("ipv4") + // IPv6 + NetworkTypeIpv6 = NetworkTypeKey.String("ipv6") +) + +// NetworkProtocolName returns an attribute KeyValue conforming to the +// "network.protocol.name" semantic conventions. It represents the [OSI +// Application Layer](https://osi-model.com/application-layer/) or non-OSI +// equivalent. The value SHOULD be normalized to lowercase. +func NetworkProtocolName(val string) attribute.KeyValue { + return NetworkProtocolNameKey.String(val) +} + +// NetworkProtocolVersion returns an attribute KeyValue conforming to the +// "network.protocol.version" semantic conventions. It represents the version +// of the application layer protocol used. See note below. +func NetworkProtocolVersion(val string) attribute.KeyValue { + return NetworkProtocolVersionKey.String(val) +} + +// These attributes may be used for any network related operation. +const ( + // NetworkConnectionTypeKey is the attribute Key conforming to the + // "network.connection.type" semantic conventions. It represents the + // internet connection type. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'wifi' + NetworkConnectionTypeKey = attribute.Key("network.connection.type") + + // NetworkConnectionSubtypeKey is the attribute Key conforming to the + // "network.connection.subtype" semantic conventions. It represents the + // this describes more details regarding the connection.type. It may be the + // type of cell technology connection, but it could be used for describing + // details about a wifi connection. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'LTE' + NetworkConnectionSubtypeKey = attribute.Key("network.connection.subtype") + + // NetworkCarrierNameKey is the attribute Key conforming to the + // "network.carrier.name" semantic conventions. It represents the name of + // the mobile carrier. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'sprint' + NetworkCarrierNameKey = attribute.Key("network.carrier.name") + + // NetworkCarrierMccKey is the attribute Key conforming to the + // "network.carrier.mcc" semantic conventions. It represents the mobile + // carrier country code. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '310' + NetworkCarrierMccKey = attribute.Key("network.carrier.mcc") + + // NetworkCarrierMncKey is the attribute Key conforming to the + // "network.carrier.mnc" semantic conventions. It represents the mobile + // carrier network code. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '001' + NetworkCarrierMncKey = attribute.Key("network.carrier.mnc") + + // NetworkCarrierIccKey is the attribute Key conforming to the + // "network.carrier.icc" semantic conventions. It represents the ISO 3166-1 + // alpha-2 2-character country code associated with the mobile carrier + // network. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'DE' + NetworkCarrierIccKey = attribute.Key("network.carrier.icc") +) + +var ( + // wifi + NetworkConnectionTypeWifi = NetworkConnectionTypeKey.String("wifi") + // wired + NetworkConnectionTypeWired = NetworkConnectionTypeKey.String("wired") + // cell + NetworkConnectionTypeCell = NetworkConnectionTypeKey.String("cell") + // unavailable + NetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String("unavailable") + // unknown + NetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String("unknown") +) + +var ( + // GPRS + NetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String("gprs") + // EDGE + NetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String("edge") + // UMTS + NetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String("umts") + // CDMA + NetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String("cdma") + // EVDO Rel. 0 + NetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String("evdo_0") + // EVDO Rev. A + NetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String("evdo_a") + // CDMA2000 1XRTT + NetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String("cdma2000_1xrtt") + // HSDPA + NetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String("hsdpa") + // HSUPA + NetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String("hsupa") + // HSPA + NetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String("hspa") + // IDEN + NetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String("iden") + // EVDO Rev. B + NetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String("evdo_b") + // LTE + NetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String("lte") + // EHRPD + NetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String("ehrpd") + // HSPAP + NetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String("hspap") + // GSM + NetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String("gsm") + // TD-SCDMA + NetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String("td_scdma") + // IWLAN + NetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String("iwlan") + // 5G NR (New Radio) + NetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String("nr") + // 5G NRNSA (New Radio Non-Standalone) + NetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String("nrnsa") + // LTE CA + NetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String("lte_ca") +) + +// NetworkCarrierName returns an attribute KeyValue conforming to the +// "network.carrier.name" semantic conventions. It represents the name of the +// mobile carrier. +func NetworkCarrierName(val string) attribute.KeyValue { + return NetworkCarrierNameKey.String(val) +} + +// NetworkCarrierMcc returns an attribute KeyValue conforming to the +// "network.carrier.mcc" semantic conventions. It represents the mobile carrier +// country code. +func NetworkCarrierMcc(val string) attribute.KeyValue { + return NetworkCarrierMccKey.String(val) +} + +// NetworkCarrierMnc returns an attribute KeyValue conforming to the +// "network.carrier.mnc" semantic conventions. It represents the mobile carrier +// network code. +func NetworkCarrierMnc(val string) attribute.KeyValue { + return NetworkCarrierMncKey.String(val) +} + +// NetworkCarrierIcc returns an attribute KeyValue conforming to the +// "network.carrier.icc" semantic conventions. It represents the ISO 3166-1 +// alpha-2 2-character country code associated with the mobile carrier network. +func NetworkCarrierIcc(val string) attribute.KeyValue { + return NetworkCarrierIccKey.String(val) +} + +// Semantic conventions for HTTP client and server Spans. +const ( + // HTTPRequestMethodOriginalKey is the attribute Key conforming to the + // "http.request.method_original" semantic conventions. It represents the + // original HTTP method sent by the client in the request line. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If and only if it's different + // than `http.request.method`.) + // Stability: stable + // Examples: 'GeT', 'ACL', 'foo' + HTTPRequestMethodOriginalKey = attribute.Key("http.request.method_original") + + // HTTPRequestBodySizeKey is the attribute Key conforming to the + // "http.request.body.size" semantic conventions. It represents the size of + // the request payload body in bytes. This is the number of bytes + // transferred excluding headers and is often, but not always, present as + // the + // [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) + // header. For requests using transport encoding, this should be the + // compressed size. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3495 + HTTPRequestBodySizeKey = attribute.Key("http.request.body.size") + + // HTTPResponseBodySizeKey is the attribute Key conforming to the + // "http.response.body.size" semantic conventions. It represents the size + // of the response payload body in bytes. This is the number of bytes + // transferred excluding headers and is often, but not always, present as + // the + // [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) + // header. For requests using transport encoding, this should be the + // compressed size. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3495 + HTTPResponseBodySizeKey = attribute.Key("http.response.body.size") +) + +// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the +// "http.request.method_original" semantic conventions. It represents the +// original HTTP method sent by the client in the request line. +func HTTPRequestMethodOriginal(val string) attribute.KeyValue { + return HTTPRequestMethodOriginalKey.String(val) +} + +// HTTPRequestBodySize returns an attribute KeyValue conforming to the +// "http.request.body.size" semantic conventions. It represents the size of the +// request payload body in bytes. This is the number of bytes transferred +// excluding headers and is often, but not always, present as the +// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) +// header. For requests using transport encoding, this should be the compressed +// size. +func HTTPRequestBodySize(val int) attribute.KeyValue { + return HTTPRequestBodySizeKey.Int(val) +} + +// HTTPResponseBodySize returns an attribute KeyValue conforming to the +// "http.response.body.size" semantic conventions. It represents the size of +// the response payload body in bytes. This is the number of bytes transferred +// excluding headers and is often, but not always, present as the +// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) +// header. For requests using transport encoding, this should be the compressed +// size. +func HTTPResponseBodySize(val int) attribute.KeyValue { + return HTTPResponseBodySizeKey.Int(val) +} + +// Semantic convention describing per-message attributes populated on messaging +// spans or links. +const ( + // MessagingMessageIDKey is the attribute Key conforming to the + // "messaging.message.id" semantic conventions. It represents a value used + // by the messaging system as an identifier for the message, represented as + // a string. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '452a7c7c7c7048c2f887f61572b18fc2' + MessagingMessageIDKey = attribute.Key("messaging.message.id") + + // MessagingMessageConversationIDKey is the attribute Key conforming to the + // "messaging.message.conversation_id" semantic conventions. It represents + // the [conversation ID](#conversations) identifying the conversation to + // which the message belongs, represented as a string. Sometimes called + // "Correlation ID". + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MyConversationID' + MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id") + + // MessagingMessagePayloadSizeBytesKey is the attribute Key conforming to + // the "messaging.message.payload_size_bytes" semantic conventions. It + // represents the (uncompressed) size of the message payload in bytes. Also + // use this attribute if it is unknown whether the compressed or + // uncompressed payload size is reported. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2738 + MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message.payload_size_bytes") + + // MessagingMessagePayloadCompressedSizeBytesKey is the attribute Key + // conforming to the "messaging.message.payload_compressed_size_bytes" + // semantic conventions. It represents the compressed size of the message + // payload in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2048 + MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message.payload_compressed_size_bytes") +) + +// MessagingMessageID returns an attribute KeyValue conforming to the +// "messaging.message.id" semantic conventions. It represents a value used by +// the messaging system as an identifier for the message, represented as a +// string. +func MessagingMessageID(val string) attribute.KeyValue { + return MessagingMessageIDKey.String(val) +} + +// MessagingMessageConversationID returns an attribute KeyValue conforming +// to the "messaging.message.conversation_id" semantic conventions. It +// represents the [conversation ID](#conversations) identifying the +// conversation to which the message belongs, represented as a string. +// Sometimes called "Correlation ID". +func MessagingMessageConversationID(val string) attribute.KeyValue { + return MessagingMessageConversationIDKey.String(val) +} + +// MessagingMessagePayloadSizeBytes returns an attribute KeyValue conforming +// to the "messaging.message.payload_size_bytes" semantic conventions. It +// represents the (uncompressed) size of the message payload in bytes. Also use +// this attribute if it is unknown whether the compressed or uncompressed +// payload size is reported. +func MessagingMessagePayloadSizeBytes(val int) attribute.KeyValue { + return MessagingMessagePayloadSizeBytesKey.Int(val) +} + +// MessagingMessagePayloadCompressedSizeBytes returns an attribute KeyValue +// conforming to the "messaging.message.payload_compressed_size_bytes" semantic +// conventions. It represents the compressed size of the message payload in +// bytes. +func MessagingMessagePayloadCompressedSizeBytes(val int) attribute.KeyValue { + return MessagingMessagePayloadCompressedSizeBytesKey.Int(val) +} + +// Semantic convention for attributes that describe messaging destination on +// broker +const ( + // MessagingDestinationNameKey is the attribute Key conforming to the + // "messaging.destination.name" semantic conventions. It represents the + // message destination name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MyQueue', 'MyTopic' + // Note: Destination name SHOULD uniquely identify a specific queue, topic + // or other entity within the broker. If + // the broker does not have such notion, the destination name SHOULD + // uniquely identify the broker. + MessagingDestinationNameKey = attribute.Key("messaging.destination.name") + + // MessagingDestinationTemplateKey is the attribute Key conforming to the + // "messaging.destination.template" semantic conventions. It represents the + // low cardinality representation of the messaging destination name + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/customers/{customerID}' + // Note: Destination names could be constructed from templates. An example + // would be a destination name involving a user name or product id. + // Although the destination name in this case is of high cardinality, the + // underlying template is of low cardinality and can be effectively used + // for grouping and aggregation. + MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template") + + // MessagingDestinationTemporaryKey is the attribute Key conforming to the + // "messaging.destination.temporary" semantic conventions. It represents a + // boolean that is true if the message destination is temporary and might + // not exist anymore after messages are processed. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary") + + // MessagingDestinationAnonymousKey is the attribute Key conforming to the + // "messaging.destination.anonymous" semantic conventions. It represents a + // boolean that is true if the message destination is anonymous (could be + // unnamed or have auto-generated name). + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous") +) + +// MessagingDestinationName returns an attribute KeyValue conforming to the +// "messaging.destination.name" semantic conventions. It represents the message +// destination name +func MessagingDestinationName(val string) attribute.KeyValue { + return MessagingDestinationNameKey.String(val) +} + +// MessagingDestinationTemplate returns an attribute KeyValue conforming to +// the "messaging.destination.template" semantic conventions. It represents the +// low cardinality representation of the messaging destination name +func MessagingDestinationTemplate(val string) attribute.KeyValue { + return MessagingDestinationTemplateKey.String(val) +} + +// MessagingDestinationTemporary returns an attribute KeyValue conforming to +// the "messaging.destination.temporary" semantic conventions. It represents a +// boolean that is true if the message destination is temporary and might not +// exist anymore after messages are processed. +func MessagingDestinationTemporary(val bool) attribute.KeyValue { + return MessagingDestinationTemporaryKey.Bool(val) +} + +// MessagingDestinationAnonymous returns an attribute KeyValue conforming to +// the "messaging.destination.anonymous" semantic conventions. It represents a +// boolean that is true if the message destination is anonymous (could be +// unnamed or have auto-generated name). +func MessagingDestinationAnonymous(val bool) attribute.KeyValue { + return MessagingDestinationAnonymousKey.Bool(val) +} + +// Attributes for RabbitMQ +const ( + // MessagingRabbitmqDestinationRoutingKeyKey is the attribute Key + // conforming to the "messaging.rabbitmq.destination.routing_key" semantic + // conventions. It represents the rabbitMQ message routing key. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If not empty.) + // Stability: stable + // Examples: 'myKey' + MessagingRabbitmqDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key") +) + +// MessagingRabbitmqDestinationRoutingKey returns an attribute KeyValue +// conforming to the "messaging.rabbitmq.destination.routing_key" semantic +// conventions. It represents the rabbitMQ message routing key. +func MessagingRabbitmqDestinationRoutingKey(val string) attribute.KeyValue { + return MessagingRabbitmqDestinationRoutingKeyKey.String(val) +} + +// Attributes for Apache Kafka +const ( + // MessagingKafkaMessageKeyKey is the attribute Key conforming to the + // "messaging.kafka.message.key" semantic conventions. It represents the + // message keys in Kafka are used for grouping alike messages to ensure + // they're processed on the same partition. They differ from + // `messaging.message.id` in that they're not unique. If the key is `null`, + // the attribute MUST NOT be set. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'myKey' + // Note: If the key type is not string, it's string representation has to + // be supplied for the attribute. If the key has no unambiguous, canonical + // string form, don't include its value. + MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key") + + // MessagingKafkaConsumerGroupKey is the attribute Key conforming to the + // "messaging.kafka.consumer.group" semantic conventions. It represents the + // name of the Kafka Consumer Group that is handling the message. Only + // applies to consumers, not producers. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'my-group' + MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer.group") + + // MessagingKafkaDestinationPartitionKey is the attribute Key conforming to + // the "messaging.kafka.destination.partition" semantic conventions. It + // represents the partition the message is sent to. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 2 + MessagingKafkaDestinationPartitionKey = attribute.Key("messaging.kafka.destination.partition") + + // MessagingKafkaMessageOffsetKey is the attribute Key conforming to the + // "messaging.kafka.message.offset" semantic conventions. It represents the + // offset of a record in the corresponding Kafka partition. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + MessagingKafkaMessageOffsetKey = attribute.Key("messaging.kafka.message.offset") + + // MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the + // "messaging.kafka.message.tombstone" semantic conventions. It represents + // a boolean that is true if the message is a tombstone. + // + // Type: boolean + // RequirementLevel: ConditionallyRequired (If value is `true`. When + // missing, the value is assumed to be `false`.) + // Stability: stable + MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone") +) + +// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the +// "messaging.kafka.message.key" semantic conventions. It represents the +// message keys in Kafka are used for grouping alike messages to ensure they're +// processed on the same partition. They differ from `messaging.message.id` in +// that they're not unique. If the key is `null`, the attribute MUST NOT be +// set. +func MessagingKafkaMessageKey(val string) attribute.KeyValue { + return MessagingKafkaMessageKeyKey.String(val) +} + +// MessagingKafkaConsumerGroup returns an attribute KeyValue conforming to +// the "messaging.kafka.consumer.group" semantic conventions. It represents the +// name of the Kafka Consumer Group that is handling the message. Only applies +// to consumers, not producers. +func MessagingKafkaConsumerGroup(val string) attribute.KeyValue { + return MessagingKafkaConsumerGroupKey.String(val) +} + +// MessagingKafkaDestinationPartition returns an attribute KeyValue +// conforming to the "messaging.kafka.destination.partition" semantic +// conventions. It represents the partition the message is sent to. +func MessagingKafkaDestinationPartition(val int) attribute.KeyValue { + return MessagingKafkaDestinationPartitionKey.Int(val) +} + +// MessagingKafkaMessageOffset returns an attribute KeyValue conforming to +// the "messaging.kafka.message.offset" semantic conventions. It represents the +// offset of a record in the corresponding Kafka partition. +func MessagingKafkaMessageOffset(val int) attribute.KeyValue { + return MessagingKafkaMessageOffsetKey.Int(val) +} + +// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming +// to the "messaging.kafka.message.tombstone" semantic conventions. It +// represents a boolean that is true if the message is a tombstone. +func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue { + return MessagingKafkaMessageTombstoneKey.Bool(val) +} + +// Attributes for Apache RocketMQ +const ( + // MessagingRocketmqNamespaceKey is the attribute Key conforming to the + // "messaging.rocketmq.namespace" semantic conventions. It represents the + // namespace of RocketMQ resources, resources in different namespaces are + // individual. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myNamespace' + MessagingRocketmqNamespaceKey = attribute.Key("messaging.rocketmq.namespace") + + // MessagingRocketmqClientGroupKey is the attribute Key conforming to the + // "messaging.rocketmq.client_group" semantic conventions. It represents + // the name of the RocketMQ producer/consumer group that is handling the + // message. The client type is identified by the SpanKind. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myConsumerGroup' + MessagingRocketmqClientGroupKey = attribute.Key("messaging.rocketmq.client_group") + + // MessagingRocketmqMessageDeliveryTimestampKey is the attribute Key + // conforming to the "messaging.rocketmq.message.delivery_timestamp" + // semantic conventions. It represents the timestamp in milliseconds that + // the delay message is expected to be delivered to consumer. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the message type is delay + // and delay time level is not specified.) + // Stability: stable + // Examples: 1665987217045 + MessagingRocketmqMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp") + + // MessagingRocketmqMessageDelayTimeLevelKey is the attribute Key + // conforming to the "messaging.rocketmq.message.delay_time_level" semantic + // conventions. It represents the delay time level for delay message, which + // determines the message delay time. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the message type is delay + // and delivery timestamp is not specified.) + // Stability: stable + // Examples: 3 + MessagingRocketmqMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level") + + // MessagingRocketmqMessageGroupKey is the attribute Key conforming to the + // "messaging.rocketmq.message.group" semantic conventions. It represents + // the it is essential for FIFO message. Messages that belong to the same + // message group are always processed one by one within the same consumer + // group. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If the message type is FIFO.) + // Stability: stable + // Examples: 'myMessageGroup' + MessagingRocketmqMessageGroupKey = attribute.Key("messaging.rocketmq.message.group") + + // MessagingRocketmqMessageTypeKey is the attribute Key conforming to the + // "messaging.rocketmq.message.type" semantic conventions. It represents + // the type of message. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingRocketmqMessageTypeKey = attribute.Key("messaging.rocketmq.message.type") + + // MessagingRocketmqMessageTagKey is the attribute Key conforming to the + // "messaging.rocketmq.message.tag" semantic conventions. It represents the + // secondary classifier of message besides topic. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'tagA' + MessagingRocketmqMessageTagKey = attribute.Key("messaging.rocketmq.message.tag") + + // MessagingRocketmqMessageKeysKey is the attribute Key conforming to the + // "messaging.rocketmq.message.keys" semantic conventions. It represents + // the key(s) of message, another way to mark message besides message id. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'keyA', 'keyB' + MessagingRocketmqMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys") + + // MessagingRocketmqConsumptionModelKey is the attribute Key conforming to + // the "messaging.rocketmq.consumption_model" semantic conventions. It + // represents the model of message consumption. This only applies to + // consumer spans. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessagingRocketmqConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model") +) + +var ( + // Normal message + MessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String("normal") + // FIFO message + MessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String("fifo") + // Delay message + MessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String("delay") + // Transaction message + MessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String("transaction") +) + +var ( + // Clustering consumption model + MessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String("clustering") + // Broadcasting consumption model + MessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String("broadcasting") +) + +// MessagingRocketmqNamespace returns an attribute KeyValue conforming to +// the "messaging.rocketmq.namespace" semantic conventions. It represents the +// namespace of RocketMQ resources, resources in different namespaces are +// individual. +func MessagingRocketmqNamespace(val string) attribute.KeyValue { + return MessagingRocketmqNamespaceKey.String(val) +} + +// MessagingRocketmqClientGroup returns an attribute KeyValue conforming to +// the "messaging.rocketmq.client_group" semantic conventions. It represents +// the name of the RocketMQ producer/consumer group that is handling the +// message. The client type is identified by the SpanKind. +func MessagingRocketmqClientGroup(val string) attribute.KeyValue { + return MessagingRocketmqClientGroupKey.String(val) +} + +// MessagingRocketmqMessageDeliveryTimestamp returns an attribute KeyValue +// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic +// conventions. It represents the timestamp in milliseconds that the delay +// message is expected to be delivered to consumer. +func MessagingRocketmqMessageDeliveryTimestamp(val int) attribute.KeyValue { + return MessagingRocketmqMessageDeliveryTimestampKey.Int(val) +} + +// MessagingRocketmqMessageDelayTimeLevel returns an attribute KeyValue +// conforming to the "messaging.rocketmq.message.delay_time_level" semantic +// conventions. It represents the delay time level for delay message, which +// determines the message delay time. +func MessagingRocketmqMessageDelayTimeLevel(val int) attribute.KeyValue { + return MessagingRocketmqMessageDelayTimeLevelKey.Int(val) +} + +// MessagingRocketmqMessageGroup returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.group" semantic conventions. It represents +// the it is essential for FIFO message. Messages that belong to the same +// message group are always processed one by one within the same consumer +// group. +func MessagingRocketmqMessageGroup(val string) attribute.KeyValue { + return MessagingRocketmqMessageGroupKey.String(val) +} + +// MessagingRocketmqMessageTag returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.tag" semantic conventions. It represents the +// secondary classifier of message besides topic. +func MessagingRocketmqMessageTag(val string) attribute.KeyValue { + return MessagingRocketmqMessageTagKey.String(val) +} + +// MessagingRocketmqMessageKeys returns an attribute KeyValue conforming to +// the "messaging.rocketmq.message.keys" semantic conventions. It represents +// the key(s) of message, another way to mark message besides message id. +func MessagingRocketmqMessageKeys(val ...string) attribute.KeyValue { + return MessagingRocketmqMessageKeysKey.StringSlice(val) +} + +// Attributes describing URL. +const ( + // URLSchemeKey is the attribute Key conforming to the "url.scheme" + // semantic conventions. It represents the [URI + // scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component + // identifying the used protocol. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'https', 'ftp', 'telnet' + URLSchemeKey = attribute.Key("url.scheme") + + // URLFullKey is the attribute Key conforming to the "url.full" semantic + // conventions. It represents the absolute URL describing a network + // resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv', + // '//localhost' + // Note: For network calls, URL usually has + // `scheme://host[:port][path][?query][#fragment]` format, where the + // fragment is not transmitted over HTTP, but if it is known, it should be + // included nevertheless. + // `url.full` MUST NOT contain credentials passed via URL in form of + // `https://username:password@www.example.com/`. In such case username and + // password should be redacted and attribute's value should be + // `https://REDACTED:REDACTED@www.example.com/`. + // `url.full` SHOULD capture the absolute URL when it is available (or can + // be reconstructed) and SHOULD NOT be validated or modified except for + // sanitizing purposes. + URLFullKey = attribute.Key("url.full") + + // URLPathKey is the attribute Key conforming to the "url.path" semantic + // conventions. It represents the [URI + // path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/search' + // Note: When missing, the value is assumed to be `/` + URLPathKey = attribute.Key("url.path") + + // URLQueryKey is the attribute Key conforming to the "url.query" semantic + // conventions. It represents the [URI + // query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'q=OpenTelemetry' + // Note: Sensitive content provided in query string SHOULD be scrubbed when + // instrumentations can identify it. + URLQueryKey = attribute.Key("url.query") + + // URLFragmentKey is the attribute Key conforming to the "url.fragment" + // semantic conventions. It represents the [URI + // fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'SemConv' + URLFragmentKey = attribute.Key("url.fragment") +) + +// URLScheme returns an attribute KeyValue conforming to the "url.scheme" +// semantic conventions. It represents the [URI +// scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component +// identifying the used protocol. +func URLScheme(val string) attribute.KeyValue { + return URLSchemeKey.String(val) +} + +// URLFull returns an attribute KeyValue conforming to the "url.full" +// semantic conventions. It represents the absolute URL describing a network +// resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) +func URLFull(val string) attribute.KeyValue { + return URLFullKey.String(val) +} + +// URLPath returns an attribute KeyValue conforming to the "url.path" +// semantic conventions. It represents the [URI +// path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component +func URLPath(val string) attribute.KeyValue { + return URLPathKey.String(val) +} + +// URLQuery returns an attribute KeyValue conforming to the "url.query" +// semantic conventions. It represents the [URI +// query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component +func URLQuery(val string) attribute.KeyValue { + return URLQueryKey.String(val) +} + +// URLFragment returns an attribute KeyValue conforming to the +// "url.fragment" semantic conventions. It represents the [URI +// fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component +func URLFragment(val string) attribute.KeyValue { + return URLFragmentKey.String(val) +} + +// Describes user-agent attributes. +const ( + // UserAgentOriginalKey is the attribute Key conforming to the + // "user_agent.original" semantic conventions. It represents the value of + // the [HTTP + // User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) + // header sent by the client. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'CERN-LineMode/2.15 libwww/2.17b3' + UserAgentOriginalKey = attribute.Key("user_agent.original") +) + +// UserAgentOriginal returns an attribute KeyValue conforming to the +// "user_agent.original" semantic conventions. It represents the value of the +// [HTTP +// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) +// header sent by the client. +func UserAgentOriginal(val string) attribute.KeyValue { + return UserAgentOriginalKey.String(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go new file mode 100644 index 00000000000..7cf424855e9 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package semconv implements OpenTelemetry semantic conventions. +// +// OpenTelemetry semantic conventions are agreed standardized naming +// patterns for OpenTelemetry things. This package represents the conventions +// as of the v1.21.0 version of the OpenTelemetry specification. +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go new file mode 100644 index 00000000000..30ae34fe478 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go @@ -0,0 +1,199 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +import "go.opentelemetry.io/otel/attribute" + +// This semantic convention defines the attributes used to represent a feature +// flag evaluation as an event. +const ( + // FeatureFlagKeyKey is the attribute Key conforming to the + // "feature_flag.key" semantic conventions. It represents the unique + // identifier of the feature flag. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'logo-color' + FeatureFlagKeyKey = attribute.Key("feature_flag.key") + + // FeatureFlagProviderNameKey is the attribute Key conforming to the + // "feature_flag.provider_name" semantic conventions. It represents the + // name of the service provider that performs the flag evaluation. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'Flag Manager' + FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider_name") + + // FeatureFlagVariantKey is the attribute Key conforming to the + // "feature_flag.variant" semantic conventions. It represents the sHOULD be + // a semantic identifier for a value. If one is unavailable, a stringified + // version of the value can be used. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'red', 'true', 'on' + // Note: A semantic identifier, commonly referred to as a variant, provides + // a means + // for referring to a value without including the value itself. This can + // provide additional context for understanding the meaning behind a value. + // For example, the variant `red` maybe be used for the value `#c05543`. + // + // A stringified version of the value can be used in situations where a + // semantic identifier is unavailable. String representation of the value + // should be determined by the implementer. + FeatureFlagVariantKey = attribute.Key("feature_flag.variant") +) + +// FeatureFlagKey returns an attribute KeyValue conforming to the +// "feature_flag.key" semantic conventions. It represents the unique identifier +// of the feature flag. +func FeatureFlagKey(val string) attribute.KeyValue { + return FeatureFlagKeyKey.String(val) +} + +// FeatureFlagProviderName returns an attribute KeyValue conforming to the +// "feature_flag.provider_name" semantic conventions. It represents the name of +// the service provider that performs the flag evaluation. +func FeatureFlagProviderName(val string) attribute.KeyValue { + return FeatureFlagProviderNameKey.String(val) +} + +// FeatureFlagVariant returns an attribute KeyValue conforming to the +// "feature_flag.variant" semantic conventions. It represents the sHOULD be a +// semantic identifier for a value. If one is unavailable, a stringified +// version of the value can be used. +func FeatureFlagVariant(val string) attribute.KeyValue { + return FeatureFlagVariantKey.String(val) +} + +// RPC received/sent message. +const ( + // MessageTypeKey is the attribute Key conforming to the "message.type" + // semantic conventions. It represents the whether this is a received or + // sent message. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + MessageTypeKey = attribute.Key("message.type") + + // MessageIDKey is the attribute Key conforming to the "message.id" + // semantic conventions. It represents the mUST be calculated as two + // different counters starting from `1` one for sent messages and one for + // received message. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Note: This way we guarantee that the values will be consistent between + // different implementations. + MessageIDKey = attribute.Key("message.id") + + // MessageCompressedSizeKey is the attribute Key conforming to the + // "message.compressed_size" semantic conventions. It represents the + // compressed size of the message in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + MessageCompressedSizeKey = attribute.Key("message.compressed_size") + + // MessageUncompressedSizeKey is the attribute Key conforming to the + // "message.uncompressed_size" semantic conventions. It represents the + // uncompressed size of the message in bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + MessageUncompressedSizeKey = attribute.Key("message.uncompressed_size") +) + +var ( + // sent + MessageTypeSent = MessageTypeKey.String("SENT") + // received + MessageTypeReceived = MessageTypeKey.String("RECEIVED") +) + +// MessageID returns an attribute KeyValue conforming to the "message.id" +// semantic conventions. It represents the mUST be calculated as two different +// counters starting from `1` one for sent messages and one for received +// message. +func MessageID(val int) attribute.KeyValue { + return MessageIDKey.Int(val) +} + +// MessageCompressedSize returns an attribute KeyValue conforming to the +// "message.compressed_size" semantic conventions. It represents the compressed +// size of the message in bytes. +func MessageCompressedSize(val int) attribute.KeyValue { + return MessageCompressedSizeKey.Int(val) +} + +// MessageUncompressedSize returns an attribute KeyValue conforming to the +// "message.uncompressed_size" semantic conventions. It represents the +// uncompressed size of the message in bytes. +func MessageUncompressedSize(val int) attribute.KeyValue { + return MessageUncompressedSizeKey.Int(val) +} + +// The attributes used to report a single exception associated with a span. +const ( + // ExceptionEscapedKey is the attribute Key conforming to the + // "exception.escaped" semantic conventions. It represents the sHOULD be + // set to true if the exception event is recorded at a point where it is + // known that the exception is escaping the scope of the span. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + // Note: An exception is considered to have escaped (or left) the scope of + // a span, + // if that span is ended while the exception is still logically "in + // flight". + // This may be actually "in flight" in some languages (e.g. if the + // exception + // is passed to a Context manager's `__exit__` method in Python) but will + // usually be caught at the point of recording the exception in most + // languages. + // + // It is usually not possible to determine at the point where an exception + // is thrown + // whether it will escape the scope of a span. + // However, it is trivial to know that an exception + // will escape, if one checks for an active exception just before ending + // the span, + // as done in the [example above](#recording-an-exception). + // + // It follows that an exception may still escape the scope of the span + // even if the `exception.escaped` attribute was not set or set to false, + // since the event might have been recorded at a time where it was not + // clear whether the exception will escape. + ExceptionEscapedKey = attribute.Key("exception.escaped") +) + +// ExceptionEscaped returns an attribute KeyValue conforming to the +// "exception.escaped" semantic conventions. It represents the sHOULD be set to +// true if the exception event is recorded at a point where it is known that +// the exception is escaping the scope of the span. +func ExceptionEscaped(val bool) attribute.KeyValue { + return ExceptionEscapedKey.Bool(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go new file mode 100644 index 00000000000..93d3c1760c9 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +const ( + // ExceptionEventName is the name of the Span event representing an exception. + ExceptionEventName = "exception" +) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go new file mode 100644 index 00000000000..b6d8935cf97 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go @@ -0,0 +1,2310 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +import "go.opentelemetry.io/otel/attribute" + +// The web browser in which the application represented by the resource is +// running. The `browser.*` attributes MUST be used only for resources that +// represent applications running in a web browser (regardless of whether +// running on a mobile or desktop device). +const ( + // BrowserBrandsKey is the attribute Key conforming to the "browser.brands" + // semantic conventions. It represents the array of brand name and version + // separated by a space + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99' + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.brands`). + BrowserBrandsKey = attribute.Key("browser.brands") + + // BrowserPlatformKey is the attribute Key conforming to the + // "browser.platform" semantic conventions. It represents the platform on + // which the browser is running + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Windows', 'macOS', 'Android' + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.platform`). If unavailable, the legacy + // `navigator.platform` API SHOULD NOT be used instead and this attribute + // SHOULD be left unset in order for the values to be consistent. + // The list of possible values is defined in the [W3C User-Agent Client + // Hints + // specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). + // Note that some (but not all) of these values can overlap with values in + // the [`os.type` and `os.name` attributes](./os.md). However, for + // consistency, the values in the `browser.platform` attribute should + // capture the exact value that the user agent provides. + BrowserPlatformKey = attribute.Key("browser.platform") + + // BrowserMobileKey is the attribute Key conforming to the "browser.mobile" + // semantic conventions. It represents a boolean that is true if the + // browser is running on a mobile device + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + // Note: This value is intended to be taken from the [UA client hints + // API](https://wicg.github.io/ua-client-hints/#interface) + // (`navigator.userAgentData.mobile`). If unavailable, this attribute + // SHOULD be left unset. + BrowserMobileKey = attribute.Key("browser.mobile") + + // BrowserLanguageKey is the attribute Key conforming to the + // "browser.language" semantic conventions. It represents the preferred + // language of the user using the browser + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'en', 'en-US', 'fr', 'fr-FR' + // Note: This value is intended to be taken from the Navigator API + // `navigator.language`. + BrowserLanguageKey = attribute.Key("browser.language") +) + +// BrowserBrands returns an attribute KeyValue conforming to the +// "browser.brands" semantic conventions. It represents the array of brand name +// and version separated by a space +func BrowserBrands(val ...string) attribute.KeyValue { + return BrowserBrandsKey.StringSlice(val) +} + +// BrowserPlatform returns an attribute KeyValue conforming to the +// "browser.platform" semantic conventions. It represents the platform on which +// the browser is running +func BrowserPlatform(val string) attribute.KeyValue { + return BrowserPlatformKey.String(val) +} + +// BrowserMobile returns an attribute KeyValue conforming to the +// "browser.mobile" semantic conventions. It represents a boolean that is true +// if the browser is running on a mobile device +func BrowserMobile(val bool) attribute.KeyValue { + return BrowserMobileKey.Bool(val) +} + +// BrowserLanguage returns an attribute KeyValue conforming to the +// "browser.language" semantic conventions. It represents the preferred +// language of the user using the browser +func BrowserLanguage(val string) attribute.KeyValue { + return BrowserLanguageKey.String(val) +} + +// A cloud environment (e.g. GCP, Azure, AWS) +const ( + // CloudProviderKey is the attribute Key conforming to the "cloud.provider" + // semantic conventions. It represents the name of the cloud provider. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + CloudProviderKey = attribute.Key("cloud.provider") + + // CloudAccountIDKey is the attribute Key conforming to the + // "cloud.account.id" semantic conventions. It represents the cloud account + // ID the resource is assigned to. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '111111111111', 'opentelemetry' + CloudAccountIDKey = attribute.Key("cloud.account.id") + + // CloudRegionKey is the attribute Key conforming to the "cloud.region" + // semantic conventions. It represents the geographical region the resource + // is running. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-central1', 'us-east-1' + // Note: Refer to your provider's docs to see the available regions, for + // example [Alibaba Cloud + // regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS + // regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), + // [Azure + // regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), + // [Google Cloud regions](https://cloud.google.com/about/locations), or + // [Tencent Cloud + // regions](https://www.tencentcloud.com/document/product/213/6091). + CloudRegionKey = attribute.Key("cloud.region") + + // CloudResourceIDKey is the attribute Key conforming to the + // "cloud.resource_id" semantic conventions. It represents the cloud + // provider-specific native identifier of the monitored cloud resource + // (e.g. an + // [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // on AWS, a [fully qualified resource + // ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) + // on Azure, a [full resource + // name](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // on GCP) + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function', + // '//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID', + // '/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/' + // Note: On some cloud providers, it may not be possible to determine the + // full ID at startup, + // so it may be necessary to set `cloud.resource_id` as a span attribute + // instead. + // + // The exact value to use for `cloud.resource_id` depends on the cloud + // provider. + // The following well-known definitions MUST be used if you set this + // attribute and they apply: + // + // * **AWS Lambda:** The function + // [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + // Take care not to use the "invoked ARN" directly but replace any + // [alias + // suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + // with the resolved function version, as the same runtime instance may + // be invokable with + // multiple different aliases. + // * **GCP:** The [URI of the + // resource](https://cloud.google.com/iam/docs/full-resource-names) + // * **Azure:** The [Fully Qualified Resource + // ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) + // of the invoked function, + // *not* the function app, having the form + // `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + // This means that a span attribute MUST be used, as an Azure function + // app can host multiple functions that would usually share + // a TracerProvider. + CloudResourceIDKey = attribute.Key("cloud.resource_id") + + // CloudAvailabilityZoneKey is the attribute Key conforming to the + // "cloud.availability_zone" semantic conventions. It represents the cloud + // regions often have multiple, isolated locations known as zones to + // increase availability. Availability zone represents the zone where the + // resource is running. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-east-1c' + // Note: Availability zones are called "zones" on Alibaba Cloud and Google + // Cloud. + CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone") + + // CloudPlatformKey is the attribute Key conforming to the "cloud.platform" + // semantic conventions. It represents the cloud platform in use. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: The prefix of the service SHOULD match the one specified in + // `cloud.provider`. + CloudPlatformKey = attribute.Key("cloud.platform") +) + +var ( + // Alibaba Cloud + CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud") + // Amazon Web Services + CloudProviderAWS = CloudProviderKey.String("aws") + // Microsoft Azure + CloudProviderAzure = CloudProviderKey.String("azure") + // Google Cloud Platform + CloudProviderGCP = CloudProviderKey.String("gcp") + // Heroku Platform as a Service + CloudProviderHeroku = CloudProviderKey.String("heroku") + // IBM Cloud + CloudProviderIbmCloud = CloudProviderKey.String("ibm_cloud") + // Tencent Cloud + CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud") +) + +var ( + // Alibaba Cloud Elastic Compute Service + CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs") + // Alibaba Cloud Function Compute + CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc") + // Red Hat OpenShift on Alibaba Cloud + CloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String("alibaba_cloud_openshift") + // AWS Elastic Compute Cloud + CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2") + // AWS Elastic Container Service + CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs") + // AWS Elastic Kubernetes Service + CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks") + // AWS Lambda + CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda") + // AWS Elastic Beanstalk + CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk") + // AWS App Runner + CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner") + // Red Hat OpenShift on AWS (ROSA) + CloudPlatformAWSOpenshift = CloudPlatformKey.String("aws_openshift") + // Azure Virtual Machines + CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm") + // Azure Container Instances + CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances") + // Azure Kubernetes Service + CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks") + // Azure Functions + CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions") + // Azure App Service + CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service") + // Azure Red Hat OpenShift + CloudPlatformAzureOpenshift = CloudPlatformKey.String("azure_openshift") + // Google Bare Metal Solution (BMS) + CloudPlatformGCPBareMetalSolution = CloudPlatformKey.String("gcp_bare_metal_solution") + // Google Cloud Compute Engine (GCE) + CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine") + // Google Cloud Run + CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run") + // Google Cloud Kubernetes Engine (GKE) + CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine") + // Google Cloud Functions (GCF) + CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions") + // Google Cloud App Engine (GAE) + CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine") + // Red Hat OpenShift on Google Cloud + CloudPlatformGCPOpenshift = CloudPlatformKey.String("gcp_openshift") + // Red Hat OpenShift on IBM Cloud + CloudPlatformIbmCloudOpenshift = CloudPlatformKey.String("ibm_cloud_openshift") + // Tencent Cloud Cloud Virtual Machine (CVM) + CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm") + // Tencent Cloud Elastic Kubernetes Service (EKS) + CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks") + // Tencent Cloud Serverless Cloud Function (SCF) + CloudPlatformTencentCloudScf = CloudPlatformKey.String("tencent_cloud_scf") +) + +// CloudAccountID returns an attribute KeyValue conforming to the +// "cloud.account.id" semantic conventions. It represents the cloud account ID +// the resource is assigned to. +func CloudAccountID(val string) attribute.KeyValue { + return CloudAccountIDKey.String(val) +} + +// CloudRegion returns an attribute KeyValue conforming to the +// "cloud.region" semantic conventions. It represents the geographical region +// the resource is running. +func CloudRegion(val string) attribute.KeyValue { + return CloudRegionKey.String(val) +} + +// CloudResourceID returns an attribute KeyValue conforming to the +// "cloud.resource_id" semantic conventions. It represents the cloud +// provider-specific native identifier of the monitored cloud resource (e.g. an +// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) +// on AWS, a [fully qualified resource +// ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) +// on Azure, a [full resource +// name](https://cloud.google.com/apis/design/resource_names#full_resource_name) +// on GCP) +func CloudResourceID(val string) attribute.KeyValue { + return CloudResourceIDKey.String(val) +} + +// CloudAvailabilityZone returns an attribute KeyValue conforming to the +// "cloud.availability_zone" semantic conventions. It represents the cloud +// regions often have multiple, isolated locations known as zones to increase +// availability. Availability zone represents the zone where the resource is +// running. +func CloudAvailabilityZone(val string) attribute.KeyValue { + return CloudAvailabilityZoneKey.String(val) +} + +// Resources used by AWS Elastic Container Service (ECS). +const ( + // AWSECSContainerARNKey is the attribute Key conforming to the + // "aws.ecs.container.arn" semantic conventions. It represents the Amazon + // Resource Name (ARN) of an [ECS container + // instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9' + AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn") + + // AWSECSClusterARNKey is the attribute Key conforming to the + // "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an + // [ECS + // cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' + AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn") + + // AWSECSLaunchtypeKey is the attribute Key conforming to the + // "aws.ecs.launchtype" semantic conventions. It represents the [launch + // type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) + // for an ECS task. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype") + + // AWSECSTaskARNKey is the attribute Key conforming to the + // "aws.ecs.task.arn" semantic conventions. It represents the ARN of an + // [ECS task + // definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b' + AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn") + + // AWSECSTaskFamilyKey is the attribute Key conforming to the + // "aws.ecs.task.family" semantic conventions. It represents the task + // definition family this task definition is a member of. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-family' + AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family") + + // AWSECSTaskRevisionKey is the attribute Key conforming to the + // "aws.ecs.task.revision" semantic conventions. It represents the revision + // for this task definition. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '8', '26' + AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision") +) + +var ( + // ec2 + AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2") + // fargate + AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate") +) + +// AWSECSContainerARN returns an attribute KeyValue conforming to the +// "aws.ecs.container.arn" semantic conventions. It represents the Amazon +// Resource Name (ARN) of an [ECS container +// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). +func AWSECSContainerARN(val string) attribute.KeyValue { + return AWSECSContainerARNKey.String(val) +} + +// AWSECSClusterARN returns an attribute KeyValue conforming to the +// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an [ECS +// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). +func AWSECSClusterARN(val string) attribute.KeyValue { + return AWSECSClusterARNKey.String(val) +} + +// AWSECSTaskARN returns an attribute KeyValue conforming to the +// "aws.ecs.task.arn" semantic conventions. It represents the ARN of an [ECS +// task +// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). +func AWSECSTaskARN(val string) attribute.KeyValue { + return AWSECSTaskARNKey.String(val) +} + +// AWSECSTaskFamily returns an attribute KeyValue conforming to the +// "aws.ecs.task.family" semantic conventions. It represents the task +// definition family this task definition is a member of. +func AWSECSTaskFamily(val string) attribute.KeyValue { + return AWSECSTaskFamilyKey.String(val) +} + +// AWSECSTaskRevision returns an attribute KeyValue conforming to the +// "aws.ecs.task.revision" semantic conventions. It represents the revision for +// this task definition. +func AWSECSTaskRevision(val string) attribute.KeyValue { + return AWSECSTaskRevisionKey.String(val) +} + +// Resources used by AWS Elastic Kubernetes Service (EKS). +const ( + // AWSEKSClusterARNKey is the attribute Key conforming to the + // "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an + // EKS cluster. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' + AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn") +) + +// AWSEKSClusterARN returns an attribute KeyValue conforming to the +// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS +// cluster. +func AWSEKSClusterARN(val string) attribute.KeyValue { + return AWSEKSClusterARNKey.String(val) +} + +// Resources specific to Amazon Web Services. +const ( + // AWSLogGroupNamesKey is the attribute Key conforming to the + // "aws.log.group.names" semantic conventions. It represents the name(s) of + // the AWS log group(s) an application is writing to. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '/aws/lambda/my-function', 'opentelemetry-service' + // Note: Multiple log groups must be supported for cases like + // multi-container applications, where a single application has sidecar + // containers, and each write to their own log group. + AWSLogGroupNamesKey = attribute.Key("aws.log.group.names") + + // AWSLogGroupARNsKey is the attribute Key conforming to the + // "aws.log.group.arns" semantic conventions. It represents the Amazon + // Resource Name(s) (ARN) of the AWS log group(s). + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*' + // Note: See the [log group ARN format + // documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns") + + // AWSLogStreamNamesKey is the attribute Key conforming to the + // "aws.log.stream.names" semantic conventions. It represents the name(s) + // of the AWS log stream(s) an application is writing to. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' + AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names") + + // AWSLogStreamARNsKey is the attribute Key conforming to the + // "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of + // the AWS log stream(s). + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' + // Note: See the [log stream ARN format + // documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + // One log group can contain several log streams, so these ARNs necessarily + // identify both a log group and a log stream. + AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns") +) + +// AWSLogGroupNames returns an attribute KeyValue conforming to the +// "aws.log.group.names" semantic conventions. It represents the name(s) of the +// AWS log group(s) an application is writing to. +func AWSLogGroupNames(val ...string) attribute.KeyValue { + return AWSLogGroupNamesKey.StringSlice(val) +} + +// AWSLogGroupARNs returns an attribute KeyValue conforming to the +// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource +// Name(s) (ARN) of the AWS log group(s). +func AWSLogGroupARNs(val ...string) attribute.KeyValue { + return AWSLogGroupARNsKey.StringSlice(val) +} + +// AWSLogStreamNames returns an attribute KeyValue conforming to the +// "aws.log.stream.names" semantic conventions. It represents the name(s) of +// the AWS log stream(s) an application is writing to. +func AWSLogStreamNames(val ...string) attribute.KeyValue { + return AWSLogStreamNamesKey.StringSlice(val) +} + +// AWSLogStreamARNs returns an attribute KeyValue conforming to the +// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the +// AWS log stream(s). +func AWSLogStreamARNs(val ...string) attribute.KeyValue { + return AWSLogStreamARNsKey.StringSlice(val) +} + +// Resource used by Google Cloud Run. +const ( + // GCPCloudRunJobExecutionKey is the attribute Key conforming to the + // "gcp.cloud_run.job.execution" semantic conventions. It represents the + // name of the Cloud Run + // [execution](https://cloud.google.com/run/docs/managing/job-executions) + // being run for the Job, as set by the + // [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + // environment variable. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'job-name-xxxx', 'sample-job-mdw84' + GCPCloudRunJobExecutionKey = attribute.Key("gcp.cloud_run.job.execution") + + // GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the + // "gcp.cloud_run.job.task_index" semantic conventions. It represents the + // index for a task within an execution as provided by the + // [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + // environment variable. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 0, 1 + GCPCloudRunJobTaskIndexKey = attribute.Key("gcp.cloud_run.job.task_index") +) + +// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the +// "gcp.cloud_run.job.execution" semantic conventions. It represents the name +// of the Cloud Run +// [execution](https://cloud.google.com/run/docs/managing/job-executions) being +// run for the Job, as set by the +// [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) +// environment variable. +func GCPCloudRunJobExecution(val string) attribute.KeyValue { + return GCPCloudRunJobExecutionKey.String(val) +} + +// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the +// "gcp.cloud_run.job.task_index" semantic conventions. It represents the index +// for a task within an execution as provided by the +// [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) +// environment variable. +func GCPCloudRunJobTaskIndex(val int) attribute.KeyValue { + return GCPCloudRunJobTaskIndexKey.Int(val) +} + +// Resources used by Google Compute Engine (GCE). +const ( + // GCPGceInstanceNameKey is the attribute Key conforming to the + // "gcp.gce.instance.name" semantic conventions. It represents the instance + // name of a GCE instance. This is the value provided by `host.name`, the + // visible name of the instance in the Cloud Console UI, and the prefix for + // the default hostname of the instance as defined by the [default internal + // DNS + // name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'instance-1', 'my-vm-name' + GCPGceInstanceNameKey = attribute.Key("gcp.gce.instance.name") + + // GCPGceInstanceHostnameKey is the attribute Key conforming to the + // "gcp.gce.instance.hostname" semantic conventions. It represents the + // hostname of a GCE instance. This is the full value of the default or + // [custom + // hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'my-host1234.example.com', + // 'sample-vm.us-west1-b.c.my-project.internal' + GCPGceInstanceHostnameKey = attribute.Key("gcp.gce.instance.hostname") +) + +// GCPGceInstanceName returns an attribute KeyValue conforming to the +// "gcp.gce.instance.name" semantic conventions. It represents the instance +// name of a GCE instance. This is the value provided by `host.name`, the +// visible name of the instance in the Cloud Console UI, and the prefix for the +// default hostname of the instance as defined by the [default internal DNS +// name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). +func GCPGceInstanceName(val string) attribute.KeyValue { + return GCPGceInstanceNameKey.String(val) +} + +// GCPGceInstanceHostname returns an attribute KeyValue conforming to the +// "gcp.gce.instance.hostname" semantic conventions. It represents the hostname +// of a GCE instance. This is the full value of the default or [custom +// hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). +func GCPGceInstanceHostname(val string) attribute.KeyValue { + return GCPGceInstanceHostnameKey.String(val) +} + +// Heroku dyno metadata +const ( + // HerokuReleaseCreationTimestampKey is the attribute Key conforming to the + // "heroku.release.creation_timestamp" semantic conventions. It represents + // the time and date the release was created + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2022-10-23T18:00:42Z' + HerokuReleaseCreationTimestampKey = attribute.Key("heroku.release.creation_timestamp") + + // HerokuReleaseCommitKey is the attribute Key conforming to the + // "heroku.release.commit" semantic conventions. It represents the commit + // hash for the current release + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'e6134959463efd8966b20e75b913cafe3f5ec' + HerokuReleaseCommitKey = attribute.Key("heroku.release.commit") + + // HerokuAppIDKey is the attribute Key conforming to the "heroku.app.id" + // semantic conventions. It represents the unique identifier for the + // application + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2daa2797-e42b-4624-9322-ec3f968df4da' + HerokuAppIDKey = attribute.Key("heroku.app.id") +) + +// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming +// to the "heroku.release.creation_timestamp" semantic conventions. It +// represents the time and date the release was created +func HerokuReleaseCreationTimestamp(val string) attribute.KeyValue { + return HerokuReleaseCreationTimestampKey.String(val) +} + +// HerokuReleaseCommit returns an attribute KeyValue conforming to the +// "heroku.release.commit" semantic conventions. It represents the commit hash +// for the current release +func HerokuReleaseCommit(val string) attribute.KeyValue { + return HerokuReleaseCommitKey.String(val) +} + +// HerokuAppID returns an attribute KeyValue conforming to the +// "heroku.app.id" semantic conventions. It represents the unique identifier +// for the application +func HerokuAppID(val string) attribute.KeyValue { + return HerokuAppIDKey.String(val) +} + +// A container instance. +const ( + // ContainerNameKey is the attribute Key conforming to the "container.name" + // semantic conventions. It represents the container name used by container + // runtime. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-autoconf' + ContainerNameKey = attribute.Key("container.name") + + // ContainerIDKey is the attribute Key conforming to the "container.id" + // semantic conventions. It represents the container ID. Usually a UUID, as + // for example used to [identify Docker + // containers](https://docs.docker.com/engine/reference/run/#container-identification). + // The UUID might be abbreviated. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'a3bf90e006b2' + ContainerIDKey = attribute.Key("container.id") + + // ContainerRuntimeKey is the attribute Key conforming to the + // "container.runtime" semantic conventions. It represents the container + // runtime managing this container. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'docker', 'containerd', 'rkt' + ContainerRuntimeKey = attribute.Key("container.runtime") + + // ContainerImageNameKey is the attribute Key conforming to the + // "container.image.name" semantic conventions. It represents the name of + // the image the container was built on. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'gcr.io/opentelemetry/operator' + ContainerImageNameKey = attribute.Key("container.image.name") + + // ContainerImageTagKey is the attribute Key conforming to the + // "container.image.tag" semantic conventions. It represents the container + // image tag. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0.1' + ContainerImageTagKey = attribute.Key("container.image.tag") + + // ContainerImageIDKey is the attribute Key conforming to the + // "container.image.id" semantic conventions. It represents the runtime + // specific image identifier. Usually a hash algorithm followed by a UUID. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f' + // Note: Docker defines a sha256 of the image id; `container.image.id` + // corresponds to the `Image` field from the Docker container inspect + // [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) + // endpoint. + // K8S defines a link to the container registry repository with digest + // `"imageID": "registry.azurecr.io + // /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. + // OCI defines a digest of manifest. + ContainerImageIDKey = attribute.Key("container.image.id") + + // ContainerCommandKey is the attribute Key conforming to the + // "container.command" semantic conventions. It represents the command used + // to run the container (i.e. the command name). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'otelcontribcol' + // Note: If using embedded credentials or sensitive data, it is recommended + // to remove them to prevent potential leakage. + ContainerCommandKey = attribute.Key("container.command") + + // ContainerCommandLineKey is the attribute Key conforming to the + // "container.command_line" semantic conventions. It represents the full + // command run by the container as a single string representing the full + // command. [2] + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'otelcontribcol --config config.yaml' + ContainerCommandLineKey = attribute.Key("container.command_line") + + // ContainerCommandArgsKey is the attribute Key conforming to the + // "container.command_args" semantic conventions. It represents the all the + // command arguments (including the command/executable itself) run by the + // container. [2] + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'otelcontribcol, --config, config.yaml' + ContainerCommandArgsKey = attribute.Key("container.command_args") +) + +// ContainerName returns an attribute KeyValue conforming to the +// "container.name" semantic conventions. It represents the container name used +// by container runtime. +func ContainerName(val string) attribute.KeyValue { + return ContainerNameKey.String(val) +} + +// ContainerID returns an attribute KeyValue conforming to the +// "container.id" semantic conventions. It represents the container ID. Usually +// a UUID, as for example used to [identify Docker +// containers](https://docs.docker.com/engine/reference/run/#container-identification). +// The UUID might be abbreviated. +func ContainerID(val string) attribute.KeyValue { + return ContainerIDKey.String(val) +} + +// ContainerRuntime returns an attribute KeyValue conforming to the +// "container.runtime" semantic conventions. It represents the container +// runtime managing this container. +func ContainerRuntime(val string) attribute.KeyValue { + return ContainerRuntimeKey.String(val) +} + +// ContainerImageName returns an attribute KeyValue conforming to the +// "container.image.name" semantic conventions. It represents the name of the +// image the container was built on. +func ContainerImageName(val string) attribute.KeyValue { + return ContainerImageNameKey.String(val) +} + +// ContainerImageTag returns an attribute KeyValue conforming to the +// "container.image.tag" semantic conventions. It represents the container +// image tag. +func ContainerImageTag(val string) attribute.KeyValue { + return ContainerImageTagKey.String(val) +} + +// ContainerImageID returns an attribute KeyValue conforming to the +// "container.image.id" semantic conventions. It represents the runtime +// specific image identifier. Usually a hash algorithm followed by a UUID. +func ContainerImageID(val string) attribute.KeyValue { + return ContainerImageIDKey.String(val) +} + +// ContainerCommand returns an attribute KeyValue conforming to the +// "container.command" semantic conventions. It represents the command used to +// run the container (i.e. the command name). +func ContainerCommand(val string) attribute.KeyValue { + return ContainerCommandKey.String(val) +} + +// ContainerCommandLine returns an attribute KeyValue conforming to the +// "container.command_line" semantic conventions. It represents the full +// command run by the container as a single string representing the full +// command. [2] +func ContainerCommandLine(val string) attribute.KeyValue { + return ContainerCommandLineKey.String(val) +} + +// ContainerCommandArgs returns an attribute KeyValue conforming to the +// "container.command_args" semantic conventions. It represents the all the +// command arguments (including the command/executable itself) run by the +// container. [2] +func ContainerCommandArgs(val ...string) attribute.KeyValue { + return ContainerCommandArgsKey.StringSlice(val) +} + +// The software deployment. +const ( + // DeploymentEnvironmentKey is the attribute Key conforming to the + // "deployment.environment" semantic conventions. It represents the name of + // the [deployment + // environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka + // deployment tier). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'staging', 'production' + DeploymentEnvironmentKey = attribute.Key("deployment.environment") +) + +// DeploymentEnvironment returns an attribute KeyValue conforming to the +// "deployment.environment" semantic conventions. It represents the name of the +// [deployment +// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka +// deployment tier). +func DeploymentEnvironment(val string) attribute.KeyValue { + return DeploymentEnvironmentKey.String(val) +} + +// The device on which the process represented by this resource is running. +const ( + // DeviceIDKey is the attribute Key conforming to the "device.id" semantic + // conventions. It represents a unique identifier representing the device + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092' + // Note: The device identifier MUST only be defined using the values + // outlined below. This value is not an advertising identifier and MUST NOT + // be used as such. On iOS (Swift or Objective-C), this value MUST be equal + // to the [vendor + // identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). + // On Android (Java or Kotlin), this value MUST be equal to the Firebase + // Installation ID or a globally unique UUID which is persisted across + // sessions in your application. More information can be found + // [here](https://developer.android.com/training/articles/user-data-ids) on + // best practices and exact implementation details. Caution should be taken + // when storing personal data or anything which can identify a user. GDPR + // and data protection laws may apply, ensure you do your own due + // diligence. + DeviceIDKey = attribute.Key("device.id") + + // DeviceModelIdentifierKey is the attribute Key conforming to the + // "device.model.identifier" semantic conventions. It represents the model + // identifier for the device + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iPhone3,4', 'SM-G920F' + // Note: It's recommended this value represents a machine readable version + // of the model identifier rather than the market or consumer-friendly name + // of the device. + DeviceModelIdentifierKey = attribute.Key("device.model.identifier") + + // DeviceModelNameKey is the attribute Key conforming to the + // "device.model.name" semantic conventions. It represents the marketing + // name for the device model + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6' + // Note: It's recommended this value represents a human readable version of + // the device model rather than a machine readable alternative. + DeviceModelNameKey = attribute.Key("device.model.name") + + // DeviceManufacturerKey is the attribute Key conforming to the + // "device.manufacturer" semantic conventions. It represents the name of + // the device manufacturer + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Apple', 'Samsung' + // Note: The Android OS provides this field via + // [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). + // iOS apps SHOULD hardcode the value `Apple`. + DeviceManufacturerKey = attribute.Key("device.manufacturer") +) + +// DeviceID returns an attribute KeyValue conforming to the "device.id" +// semantic conventions. It represents a unique identifier representing the +// device +func DeviceID(val string) attribute.KeyValue { + return DeviceIDKey.String(val) +} + +// DeviceModelIdentifier returns an attribute KeyValue conforming to the +// "device.model.identifier" semantic conventions. It represents the model +// identifier for the device +func DeviceModelIdentifier(val string) attribute.KeyValue { + return DeviceModelIdentifierKey.String(val) +} + +// DeviceModelName returns an attribute KeyValue conforming to the +// "device.model.name" semantic conventions. It represents the marketing name +// for the device model +func DeviceModelName(val string) attribute.KeyValue { + return DeviceModelNameKey.String(val) +} + +// DeviceManufacturer returns an attribute KeyValue conforming to the +// "device.manufacturer" semantic conventions. It represents the name of the +// device manufacturer +func DeviceManufacturer(val string) attribute.KeyValue { + return DeviceManufacturerKey.String(val) +} + +// A serverless instance. +const ( + // FaaSNameKey is the attribute Key conforming to the "faas.name" semantic + // conventions. It represents the name of the single function that this + // runtime instance executes. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'my-function', 'myazurefunctionapp/some-function-name' + // Note: This is the name of the function as configured/deployed on the + // FaaS + // platform and is usually different from the name of the callback + // function (which may be stored in the + // [`code.namespace`/`code.function`](/docs/general/general-attributes.md#source-code-attributes) + // span attributes). + // + // For some cloud providers, the above definition is ambiguous. The + // following + // definition of function name MUST be used for this attribute + // (and consequently the span name) for the listed cloud + // providers/products: + // + // * **Azure:** The full name `/`, i.e., function app name + // followed by a forward slash followed by the function name (this form + // can also be seen in the resource JSON for the function). + // This means that a span attribute MUST be used, as an Azure function + // app can host multiple functions that would usually share + // a TracerProvider (see also the `cloud.resource_id` attribute). + FaaSNameKey = attribute.Key("faas.name") + + // FaaSVersionKey is the attribute Key conforming to the "faas.version" + // semantic conventions. It represents the immutable version of the + // function being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '26', 'pinkfroid-00002' + // Note: Depending on the cloud provider and platform, use: + // + // * **AWS Lambda:** The [function + // version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + // (an integer represented as a decimal string). + // * **Google Cloud Run (Services):** The + // [revision](https://cloud.google.com/run/docs/managing/revisions) + // (i.e., the function name plus the revision suffix). + // * **Google Cloud Functions:** The value of the + // [`K_REVISION` environment + // variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). + // * **Azure Functions:** Not applicable. Do not set this attribute. + FaaSVersionKey = attribute.Key("faas.version") + + // FaaSInstanceKey is the attribute Key conforming to the "faas.instance" + // semantic conventions. It represents the execution environment ID as a + // string, that will be potentially reused for other invocations to the + // same function/function version. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de' + // Note: * **AWS Lambda:** Use the (full) log stream name. + FaaSInstanceKey = attribute.Key("faas.instance") + + // FaaSMaxMemoryKey is the attribute Key conforming to the + // "faas.max_memory" semantic conventions. It represents the amount of + // memory available to the serverless function converted to Bytes. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 134217728 + // Note: It's recommended to set this attribute since e.g. too little + // memory can easily stop a Java AWS Lambda function from working + // correctly. On AWS Lambda, the environment variable + // `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must + // be multiplied by 1,048,576). + FaaSMaxMemoryKey = attribute.Key("faas.max_memory") +) + +// FaaSName returns an attribute KeyValue conforming to the "faas.name" +// semantic conventions. It represents the name of the single function that +// this runtime instance executes. +func FaaSName(val string) attribute.KeyValue { + return FaaSNameKey.String(val) +} + +// FaaSVersion returns an attribute KeyValue conforming to the +// "faas.version" semantic conventions. It represents the immutable version of +// the function being executed. +func FaaSVersion(val string) attribute.KeyValue { + return FaaSVersionKey.String(val) +} + +// FaaSInstance returns an attribute KeyValue conforming to the +// "faas.instance" semantic conventions. It represents the execution +// environment ID as a string, that will be potentially reused for other +// invocations to the same function/function version. +func FaaSInstance(val string) attribute.KeyValue { + return FaaSInstanceKey.String(val) +} + +// FaaSMaxMemory returns an attribute KeyValue conforming to the +// "faas.max_memory" semantic conventions. It represents the amount of memory +// available to the serverless function converted to Bytes. +func FaaSMaxMemory(val int) attribute.KeyValue { + return FaaSMaxMemoryKey.Int(val) +} + +// A host is defined as a computing instance. For example, physical servers, +// virtual machines, switches or disk array. +const ( + // HostIDKey is the attribute Key conforming to the "host.id" semantic + // conventions. It represents the unique host ID. For Cloud, this must be + // the instance_id assigned by the cloud provider. For non-containerized + // systems, this should be the `machine-id`. See the table below for the + // sources to use to determine the `machine-id` based on operating system. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'fdbf79e8af94cb7f9e8df36789187052' + HostIDKey = attribute.Key("host.id") + + // HostNameKey is the attribute Key conforming to the "host.name" semantic + // conventions. It represents the name of the host. On Unix systems, it may + // contain what the hostname command returns, or the fully qualified + // hostname, or another name specified by the user. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-test' + HostNameKey = attribute.Key("host.name") + + // HostTypeKey is the attribute Key conforming to the "host.type" semantic + // conventions. It represents the type of host. For Cloud, this must be the + // machine type. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'n1-standard-1' + HostTypeKey = attribute.Key("host.type") + + // HostArchKey is the attribute Key conforming to the "host.arch" semantic + // conventions. It represents the CPU architecture the host system is + // running on. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + HostArchKey = attribute.Key("host.arch") + + // HostImageNameKey is the attribute Key conforming to the + // "host.image.name" semantic conventions. It represents the name of the VM + // image or OS install the host was instantiated from. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905' + HostImageNameKey = attribute.Key("host.image.name") + + // HostImageIDKey is the attribute Key conforming to the "host.image.id" + // semantic conventions. It represents the vM image ID or host OS image ID. + // For Cloud, this value is from the provider. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'ami-07b06b442921831e5' + HostImageIDKey = attribute.Key("host.image.id") + + // HostImageVersionKey is the attribute Key conforming to the + // "host.image.version" semantic conventions. It represents the version + // string of the VM image or host OS as defined in [Version + // Attributes](README.md#version-attributes). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0.1' + HostImageVersionKey = attribute.Key("host.image.version") +) + +var ( + // AMD64 + HostArchAMD64 = HostArchKey.String("amd64") + // ARM32 + HostArchARM32 = HostArchKey.String("arm32") + // ARM64 + HostArchARM64 = HostArchKey.String("arm64") + // Itanium + HostArchIA64 = HostArchKey.String("ia64") + // 32-bit PowerPC + HostArchPPC32 = HostArchKey.String("ppc32") + // 64-bit PowerPC + HostArchPPC64 = HostArchKey.String("ppc64") + // IBM z/Architecture + HostArchS390x = HostArchKey.String("s390x") + // 32-bit x86 + HostArchX86 = HostArchKey.String("x86") +) + +// HostID returns an attribute KeyValue conforming to the "host.id" semantic +// conventions. It represents the unique host ID. For Cloud, this must be the +// instance_id assigned by the cloud provider. For non-containerized systems, +// this should be the `machine-id`. See the table below for the sources to use +// to determine the `machine-id` based on operating system. +func HostID(val string) attribute.KeyValue { + return HostIDKey.String(val) +} + +// HostName returns an attribute KeyValue conforming to the "host.name" +// semantic conventions. It represents the name of the host. On Unix systems, +// it may contain what the hostname command returns, or the fully qualified +// hostname, or another name specified by the user. +func HostName(val string) attribute.KeyValue { + return HostNameKey.String(val) +} + +// HostType returns an attribute KeyValue conforming to the "host.type" +// semantic conventions. It represents the type of host. For Cloud, this must +// be the machine type. +func HostType(val string) attribute.KeyValue { + return HostTypeKey.String(val) +} + +// HostImageName returns an attribute KeyValue conforming to the +// "host.image.name" semantic conventions. It represents the name of the VM +// image or OS install the host was instantiated from. +func HostImageName(val string) attribute.KeyValue { + return HostImageNameKey.String(val) +} + +// HostImageID returns an attribute KeyValue conforming to the +// "host.image.id" semantic conventions. It represents the vM image ID or host +// OS image ID. For Cloud, this value is from the provider. +func HostImageID(val string) attribute.KeyValue { + return HostImageIDKey.String(val) +} + +// HostImageVersion returns an attribute KeyValue conforming to the +// "host.image.version" semantic conventions. It represents the version string +// of the VM image or host OS as defined in [Version +// Attributes](README.md#version-attributes). +func HostImageVersion(val string) attribute.KeyValue { + return HostImageVersionKey.String(val) +} + +// A Kubernetes Cluster. +const ( + // K8SClusterNameKey is the attribute Key conforming to the + // "k8s.cluster.name" semantic conventions. It represents the name of the + // cluster. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-cluster' + K8SClusterNameKey = attribute.Key("k8s.cluster.name") + + // K8SClusterUIDKey is the attribute Key conforming to the + // "k8s.cluster.uid" semantic conventions. It represents a pseudo-ID for + // the cluster, set to the UID of the `kube-system` namespace. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '218fc5a9-a5f1-4b54-aa05-46717d0ab26d' + // Note: K8S does not have support for obtaining a cluster ID. If this is + // ever + // added, we will recommend collecting the `k8s.cluster.uid` through the + // official APIs. In the meantime, we are able to use the `uid` of the + // `kube-system` namespace as a proxy for cluster ID. Read on for the + // rationale. + // + // Every object created in a K8S cluster is assigned a distinct UID. The + // `kube-system` namespace is used by Kubernetes itself and will exist + // for the lifetime of the cluster. Using the `uid` of the `kube-system` + // namespace is a reasonable proxy for the K8S ClusterID as it will only + // change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are + // UUIDs as standardized by + // [ISO/IEC 9834-8 and ITU-T + // X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). + // Which states: + // + // > If generated according to one of the mechanisms defined in Rec. + // ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + // different from all other UUIDs generated before 3603 A.D., or is + // extremely likely to be different (depending on the mechanism chosen). + // + // Therefore, UIDs between clusters should be extremely unlikely to + // conflict. + K8SClusterUIDKey = attribute.Key("k8s.cluster.uid") +) + +// K8SClusterName returns an attribute KeyValue conforming to the +// "k8s.cluster.name" semantic conventions. It represents the name of the +// cluster. +func K8SClusterName(val string) attribute.KeyValue { + return K8SClusterNameKey.String(val) +} + +// K8SClusterUID returns an attribute KeyValue conforming to the +// "k8s.cluster.uid" semantic conventions. It represents a pseudo-ID for the +// cluster, set to the UID of the `kube-system` namespace. +func K8SClusterUID(val string) attribute.KeyValue { + return K8SClusterUIDKey.String(val) +} + +// A Kubernetes Node object. +const ( + // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name" + // semantic conventions. It represents the name of the Node. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'node-1' + K8SNodeNameKey = attribute.Key("k8s.node.name") + + // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" + // semantic conventions. It represents the UID of the Node. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2' + K8SNodeUIDKey = attribute.Key("k8s.node.uid") +) + +// K8SNodeName returns an attribute KeyValue conforming to the +// "k8s.node.name" semantic conventions. It represents the name of the Node. +func K8SNodeName(val string) attribute.KeyValue { + return K8SNodeNameKey.String(val) +} + +// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid" +// semantic conventions. It represents the UID of the Node. +func K8SNodeUID(val string) attribute.KeyValue { + return K8SNodeUIDKey.String(val) +} + +// A Kubernetes Namespace. +const ( + // K8SNamespaceNameKey is the attribute Key conforming to the + // "k8s.namespace.name" semantic conventions. It represents the name of the + // namespace that the pod is running in. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'default' + K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") +) + +// K8SNamespaceName returns an attribute KeyValue conforming to the +// "k8s.namespace.name" semantic conventions. It represents the name of the +// namespace that the pod is running in. +func K8SNamespaceName(val string) attribute.KeyValue { + return K8SNamespaceNameKey.String(val) +} + +// A Kubernetes Pod object. +const ( + // K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid" + // semantic conventions. It represents the UID of the Pod. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SPodUIDKey = attribute.Key("k8s.pod.uid") + + // K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name" + // semantic conventions. It represents the name of the Pod. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry-pod-autoconf' + K8SPodNameKey = attribute.Key("k8s.pod.name") +) + +// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid" +// semantic conventions. It represents the UID of the Pod. +func K8SPodUID(val string) attribute.KeyValue { + return K8SPodUIDKey.String(val) +} + +// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name" +// semantic conventions. It represents the name of the Pod. +func K8SPodName(val string) attribute.KeyValue { + return K8SPodNameKey.String(val) +} + +// A container in a +// [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates). +const ( + // K8SContainerNameKey is the attribute Key conforming to the + // "k8s.container.name" semantic conventions. It represents the name of the + // Container from Pod specification, must be unique within a Pod. Container + // runtime usually uses different globally unique name (`container.name`). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'redis' + K8SContainerNameKey = attribute.Key("k8s.container.name") + + // K8SContainerRestartCountKey is the attribute Key conforming to the + // "k8s.container.restart_count" semantic conventions. It represents the + // number of times the container was restarted. This attribute can be used + // to identify a particular container (running or stopped) within a + // container spec. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 0, 2 + K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") +) + +// K8SContainerName returns an attribute KeyValue conforming to the +// "k8s.container.name" semantic conventions. It represents the name of the +// Container from Pod specification, must be unique within a Pod. Container +// runtime usually uses different globally unique name (`container.name`). +func K8SContainerName(val string) attribute.KeyValue { + return K8SContainerNameKey.String(val) +} + +// K8SContainerRestartCount returns an attribute KeyValue conforming to the +// "k8s.container.restart_count" semantic conventions. It represents the number +// of times the container was restarted. This attribute can be used to identify +// a particular container (running or stopped) within a container spec. +func K8SContainerRestartCount(val int) attribute.KeyValue { + return K8SContainerRestartCountKey.Int(val) +} + +// A Kubernetes ReplicaSet object. +const ( + // K8SReplicaSetUIDKey is the attribute Key conforming to the + // "k8s.replicaset.uid" semantic conventions. It represents the UID of the + // ReplicaSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") + + // K8SReplicaSetNameKey is the attribute Key conforming to the + // "k8s.replicaset.name" semantic conventions. It represents the name of + // the ReplicaSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") +) + +// K8SReplicaSetUID returns an attribute KeyValue conforming to the +// "k8s.replicaset.uid" semantic conventions. It represents the UID of the +// ReplicaSet. +func K8SReplicaSetUID(val string) attribute.KeyValue { + return K8SReplicaSetUIDKey.String(val) +} + +// K8SReplicaSetName returns an attribute KeyValue conforming to the +// "k8s.replicaset.name" semantic conventions. It represents the name of the +// ReplicaSet. +func K8SReplicaSetName(val string) attribute.KeyValue { + return K8SReplicaSetNameKey.String(val) +} + +// A Kubernetes Deployment object. +const ( + // K8SDeploymentUIDKey is the attribute Key conforming to the + // "k8s.deployment.uid" semantic conventions. It represents the UID of the + // Deployment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") + + // K8SDeploymentNameKey is the attribute Key conforming to the + // "k8s.deployment.name" semantic conventions. It represents the name of + // the Deployment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") +) + +// K8SDeploymentUID returns an attribute KeyValue conforming to the +// "k8s.deployment.uid" semantic conventions. It represents the UID of the +// Deployment. +func K8SDeploymentUID(val string) attribute.KeyValue { + return K8SDeploymentUIDKey.String(val) +} + +// K8SDeploymentName returns an attribute KeyValue conforming to the +// "k8s.deployment.name" semantic conventions. It represents the name of the +// Deployment. +func K8SDeploymentName(val string) attribute.KeyValue { + return K8SDeploymentNameKey.String(val) +} + +// A Kubernetes StatefulSet object. +const ( + // K8SStatefulSetUIDKey is the attribute Key conforming to the + // "k8s.statefulset.uid" semantic conventions. It represents the UID of the + // StatefulSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") + + // K8SStatefulSetNameKey is the attribute Key conforming to the + // "k8s.statefulset.name" semantic conventions. It represents the name of + // the StatefulSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") +) + +// K8SStatefulSetUID returns an attribute KeyValue conforming to the +// "k8s.statefulset.uid" semantic conventions. It represents the UID of the +// StatefulSet. +func K8SStatefulSetUID(val string) attribute.KeyValue { + return K8SStatefulSetUIDKey.String(val) +} + +// K8SStatefulSetName returns an attribute KeyValue conforming to the +// "k8s.statefulset.name" semantic conventions. It represents the name of the +// StatefulSet. +func K8SStatefulSetName(val string) attribute.KeyValue { + return K8SStatefulSetNameKey.String(val) +} + +// A Kubernetes DaemonSet object. +const ( + // K8SDaemonSetUIDKey is the attribute Key conforming to the + // "k8s.daemonset.uid" semantic conventions. It represents the UID of the + // DaemonSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") + + // K8SDaemonSetNameKey is the attribute Key conforming to the + // "k8s.daemonset.name" semantic conventions. It represents the name of the + // DaemonSet. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") +) + +// K8SDaemonSetUID returns an attribute KeyValue conforming to the +// "k8s.daemonset.uid" semantic conventions. It represents the UID of the +// DaemonSet. +func K8SDaemonSetUID(val string) attribute.KeyValue { + return K8SDaemonSetUIDKey.String(val) +} + +// K8SDaemonSetName returns an attribute KeyValue conforming to the +// "k8s.daemonset.name" semantic conventions. It represents the name of the +// DaemonSet. +func K8SDaemonSetName(val string) attribute.KeyValue { + return K8SDaemonSetNameKey.String(val) +} + +// A Kubernetes Job object. +const ( + // K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid" + // semantic conventions. It represents the UID of the Job. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SJobUIDKey = attribute.Key("k8s.job.uid") + + // K8SJobNameKey is the attribute Key conforming to the "k8s.job.name" + // semantic conventions. It represents the name of the Job. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SJobNameKey = attribute.Key("k8s.job.name") +) + +// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid" +// semantic conventions. It represents the UID of the Job. +func K8SJobUID(val string) attribute.KeyValue { + return K8SJobUIDKey.String(val) +} + +// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name" +// semantic conventions. It represents the name of the Job. +func K8SJobName(val string) attribute.KeyValue { + return K8SJobNameKey.String(val) +} + +// A Kubernetes CronJob object. +const ( + // K8SCronJobUIDKey is the attribute Key conforming to the + // "k8s.cronjob.uid" semantic conventions. It represents the UID of the + // CronJob. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' + K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") + + // K8SCronJobNameKey is the attribute Key conforming to the + // "k8s.cronjob.name" semantic conventions. It represents the name of the + // CronJob. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'opentelemetry' + K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") +) + +// K8SCronJobUID returns an attribute KeyValue conforming to the +// "k8s.cronjob.uid" semantic conventions. It represents the UID of the +// CronJob. +func K8SCronJobUID(val string) attribute.KeyValue { + return K8SCronJobUIDKey.String(val) +} + +// K8SCronJobName returns an attribute KeyValue conforming to the +// "k8s.cronjob.name" semantic conventions. It represents the name of the +// CronJob. +func K8SCronJobName(val string) attribute.KeyValue { + return K8SCronJobNameKey.String(val) +} + +// The operating system (OS) on which the process represented by this resource +// is running. +const ( + // OSTypeKey is the attribute Key conforming to the "os.type" semantic + // conventions. It represents the operating system type. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + OSTypeKey = attribute.Key("os.type") + + // OSDescriptionKey is the attribute Key conforming to the "os.description" + // semantic conventions. It represents the human readable (not intended to + // be parsed) OS version information, like e.g. reported by `ver` or + // `lsb_release -a` commands. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 + // LTS' + OSDescriptionKey = attribute.Key("os.description") + + // OSNameKey is the attribute Key conforming to the "os.name" semantic + // conventions. It represents the human readable operating system name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'iOS', 'Android', 'Ubuntu' + OSNameKey = attribute.Key("os.name") + + // OSVersionKey is the attribute Key conforming to the "os.version" + // semantic conventions. It represents the version string of the operating + // system as defined in [Version + // Attributes](/docs/resource/README.md#version-attributes). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '14.2.1', '18.04.1' + OSVersionKey = attribute.Key("os.version") +) + +var ( + // Microsoft Windows + OSTypeWindows = OSTypeKey.String("windows") + // Linux + OSTypeLinux = OSTypeKey.String("linux") + // Apple Darwin + OSTypeDarwin = OSTypeKey.String("darwin") + // FreeBSD + OSTypeFreeBSD = OSTypeKey.String("freebsd") + // NetBSD + OSTypeNetBSD = OSTypeKey.String("netbsd") + // OpenBSD + OSTypeOpenBSD = OSTypeKey.String("openbsd") + // DragonFly BSD + OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd") + // HP-UX (Hewlett Packard Unix) + OSTypeHPUX = OSTypeKey.String("hpux") + // AIX (Advanced Interactive eXecutive) + OSTypeAIX = OSTypeKey.String("aix") + // SunOS, Oracle Solaris + OSTypeSolaris = OSTypeKey.String("solaris") + // IBM z/OS + OSTypeZOS = OSTypeKey.String("z_os") +) + +// OSDescription returns an attribute KeyValue conforming to the +// "os.description" semantic conventions. It represents the human readable (not +// intended to be parsed) OS version information, like e.g. reported by `ver` +// or `lsb_release -a` commands. +func OSDescription(val string) attribute.KeyValue { + return OSDescriptionKey.String(val) +} + +// OSName returns an attribute KeyValue conforming to the "os.name" semantic +// conventions. It represents the human readable operating system name. +func OSName(val string) attribute.KeyValue { + return OSNameKey.String(val) +} + +// OSVersion returns an attribute KeyValue conforming to the "os.version" +// semantic conventions. It represents the version string of the operating +// system as defined in [Version +// Attributes](/docs/resource/README.md#version-attributes). +func OSVersion(val string) attribute.KeyValue { + return OSVersionKey.String(val) +} + +// An operating system process. +const ( + // ProcessPIDKey is the attribute Key conforming to the "process.pid" + // semantic conventions. It represents the process identifier (PID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 1234 + ProcessPIDKey = attribute.Key("process.pid") + + // ProcessParentPIDKey is the attribute Key conforming to the + // "process.parent_pid" semantic conventions. It represents the parent + // Process identifier (PID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 111 + ProcessParentPIDKey = attribute.Key("process.parent_pid") + + // ProcessExecutableNameKey is the attribute Key conforming to the + // "process.executable.name" semantic conventions. It represents the name + // of the process executable. On Linux based systems, can be set to the + // `Name` in `proc/[pid]/status`. On Windows, can be set to the base name + // of `GetProcessImageFileNameW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'otelcol' + ProcessExecutableNameKey = attribute.Key("process.executable.name") + + // ProcessExecutablePathKey is the attribute Key conforming to the + // "process.executable.path" semantic conventions. It represents the full + // path to the process executable. On Linux based systems, can be set to + // the target of `proc/[pid]/exe`. On Windows, can be set to the result of + // `GetProcessImageFileNameW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: '/usr/bin/cmd/otelcol' + ProcessExecutablePathKey = attribute.Key("process.executable.path") + + // ProcessCommandKey is the attribute Key conforming to the + // "process.command" semantic conventions. It represents the command used + // to launch the process (i.e. the command name). On Linux based systems, + // can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can + // be set to the first parameter extracted from `GetCommandLineW`. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'cmd/otelcol' + ProcessCommandKey = attribute.Key("process.command") + + // ProcessCommandLineKey is the attribute Key conforming to the + // "process.command_line" semantic conventions. It represents the full + // command used to launch the process as a single string representing the + // full command. On Windows, can be set to the result of `GetCommandLineW`. + // Do not set this if you have to assemble it just for monitoring; use + // `process.command_args` instead. + // + // Type: string + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"' + ProcessCommandLineKey = attribute.Key("process.command_line") + + // ProcessCommandArgsKey is the attribute Key conforming to the + // "process.command_args" semantic conventions. It represents the all the + // command arguments (including the command/executable itself) as received + // by the process. On Linux-based systems (and some other Unixoid systems + // supporting procfs), can be set according to the list of null-delimited + // strings extracted from `proc/[pid]/cmdline`. For libc-based executables, + // this would be the full argv vector passed to `main`. + // + // Type: string[] + // RequirementLevel: ConditionallyRequired (See alternative attributes + // below.) + // Stability: stable + // Examples: 'cmd/otecol', '--config=config.yaml' + ProcessCommandArgsKey = attribute.Key("process.command_args") + + // ProcessOwnerKey is the attribute Key conforming to the "process.owner" + // semantic conventions. It represents the username of the user that owns + // the process. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'root' + ProcessOwnerKey = attribute.Key("process.owner") +) + +// ProcessPID returns an attribute KeyValue conforming to the "process.pid" +// semantic conventions. It represents the process identifier (PID). +func ProcessPID(val int) attribute.KeyValue { + return ProcessPIDKey.Int(val) +} + +// ProcessParentPID returns an attribute KeyValue conforming to the +// "process.parent_pid" semantic conventions. It represents the parent Process +// identifier (PID). +func ProcessParentPID(val int) attribute.KeyValue { + return ProcessParentPIDKey.Int(val) +} + +// ProcessExecutableName returns an attribute KeyValue conforming to the +// "process.executable.name" semantic conventions. It represents the name of +// the process executable. On Linux based systems, can be set to the `Name` in +// `proc/[pid]/status`. On Windows, can be set to the base name of +// `GetProcessImageFileNameW`. +func ProcessExecutableName(val string) attribute.KeyValue { + return ProcessExecutableNameKey.String(val) +} + +// ProcessExecutablePath returns an attribute KeyValue conforming to the +// "process.executable.path" semantic conventions. It represents the full path +// to the process executable. On Linux based systems, can be set to the target +// of `proc/[pid]/exe`. On Windows, can be set to the result of +// `GetProcessImageFileNameW`. +func ProcessExecutablePath(val string) attribute.KeyValue { + return ProcessExecutablePathKey.String(val) +} + +// ProcessCommand returns an attribute KeyValue conforming to the +// "process.command" semantic conventions. It represents the command used to +// launch the process (i.e. the command name). On Linux based systems, can be +// set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to +// the first parameter extracted from `GetCommandLineW`. +func ProcessCommand(val string) attribute.KeyValue { + return ProcessCommandKey.String(val) +} + +// ProcessCommandLine returns an attribute KeyValue conforming to the +// "process.command_line" semantic conventions. It represents the full command +// used to launch the process as a single string representing the full command. +// On Windows, can be set to the result of `GetCommandLineW`. Do not set this +// if you have to assemble it just for monitoring; use `process.command_args` +// instead. +func ProcessCommandLine(val string) attribute.KeyValue { + return ProcessCommandLineKey.String(val) +} + +// ProcessCommandArgs returns an attribute KeyValue conforming to the +// "process.command_args" semantic conventions. It represents the all the +// command arguments (including the command/executable itself) as received by +// the process. On Linux-based systems (and some other Unixoid systems +// supporting procfs), can be set according to the list of null-delimited +// strings extracted from `proc/[pid]/cmdline`. For libc-based executables, +// this would be the full argv vector passed to `main`. +func ProcessCommandArgs(val ...string) attribute.KeyValue { + return ProcessCommandArgsKey.StringSlice(val) +} + +// ProcessOwner returns an attribute KeyValue conforming to the +// "process.owner" semantic conventions. It represents the username of the user +// that owns the process. +func ProcessOwner(val string) attribute.KeyValue { + return ProcessOwnerKey.String(val) +} + +// The single (language) runtime instance which is monitored. +const ( + // ProcessRuntimeNameKey is the attribute Key conforming to the + // "process.runtime.name" semantic conventions. It represents the name of + // the runtime of this process. For compiled native binaries, this SHOULD + // be the name of the compiler. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'OpenJDK Runtime Environment' + ProcessRuntimeNameKey = attribute.Key("process.runtime.name") + + // ProcessRuntimeVersionKey is the attribute Key conforming to the + // "process.runtime.version" semantic conventions. It represents the + // version of the runtime of this process, as returned by the runtime + // without modification. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '14.0.2' + ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") + + // ProcessRuntimeDescriptionKey is the attribute Key conforming to the + // "process.runtime.description" semantic conventions. It represents an + // additional description about the runtime of the process, for example a + // specific vendor customization of the runtime environment. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' + ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") +) + +// ProcessRuntimeName returns an attribute KeyValue conforming to the +// "process.runtime.name" semantic conventions. It represents the name of the +// runtime of this process. For compiled native binaries, this SHOULD be the +// name of the compiler. +func ProcessRuntimeName(val string) attribute.KeyValue { + return ProcessRuntimeNameKey.String(val) +} + +// ProcessRuntimeVersion returns an attribute KeyValue conforming to the +// "process.runtime.version" semantic conventions. It represents the version of +// the runtime of this process, as returned by the runtime without +// modification. +func ProcessRuntimeVersion(val string) attribute.KeyValue { + return ProcessRuntimeVersionKey.String(val) +} + +// ProcessRuntimeDescription returns an attribute KeyValue conforming to the +// "process.runtime.description" semantic conventions. It represents an +// additional description about the runtime of the process, for example a +// specific vendor customization of the runtime environment. +func ProcessRuntimeDescription(val string) attribute.KeyValue { + return ProcessRuntimeDescriptionKey.String(val) +} + +// A service instance. +const ( + // ServiceNameKey is the attribute Key conforming to the "service.name" + // semantic conventions. It represents the logical name of the service. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'shoppingcart' + // Note: MUST be the same for all instances of horizontally scaled + // services. If the value was not specified, SDKs MUST fallback to + // `unknown_service:` concatenated with + // [`process.executable.name`](process.md#process), e.g. + // `unknown_service:bash`. If `process.executable.name` is not available, + // the value MUST be set to `unknown_service`. + ServiceNameKey = attribute.Key("service.name") + + // ServiceVersionKey is the attribute Key conforming to the + // "service.version" semantic conventions. It represents the version string + // of the service API or implementation. The format is not defined by these + // conventions. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2.0.0', 'a01dbef8a' + ServiceVersionKey = attribute.Key("service.version") +) + +// ServiceName returns an attribute KeyValue conforming to the +// "service.name" semantic conventions. It represents the logical name of the +// service. +func ServiceName(val string) attribute.KeyValue { + return ServiceNameKey.String(val) +} + +// ServiceVersion returns an attribute KeyValue conforming to the +// "service.version" semantic conventions. It represents the version string of +// the service API or implementation. The format is not defined by these +// conventions. +func ServiceVersion(val string) attribute.KeyValue { + return ServiceVersionKey.String(val) +} + +// A service instance. +const ( + // ServiceNamespaceKey is the attribute Key conforming to the + // "service.namespace" semantic conventions. It represents a namespace for + // `service.name`. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Shop' + // Note: A string value having a meaning that helps to distinguish a group + // of services, for example the team name that owns a group of services. + // `service.name` is expected to be unique within the same namespace. If + // `service.namespace` is not specified in the Resource then `service.name` + // is expected to be unique for all services that have no explicit + // namespace defined (so the empty/unspecified namespace is simply one more + // valid namespace). Zero-length namespace string is assumed equal to + // unspecified namespace. + ServiceNamespaceKey = attribute.Key("service.namespace") + + // ServiceInstanceIDKey is the attribute Key conforming to the + // "service.instance.id" semantic conventions. It represents the string ID + // of the service instance. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'my-k8s-pod-deployment-1', + // '627cc493-f310-47de-96bd-71410b7dec09' + // Note: MUST be unique for each instance of the same + // `service.namespace,service.name` pair (in other words + // `service.namespace,service.name,service.instance.id` triplet MUST be + // globally unique). The ID helps to distinguish instances of the same + // service that exist at the same time (e.g. instances of a horizontally + // scaled service). It is preferable for the ID to be persistent and stay + // the same for the lifetime of the service instance, however it is + // acceptable that the ID is ephemeral and changes during important + // lifetime events for the service (e.g. service restarts). If the service + // has no inherent unique ID that can be used as the value of this + // attribute it is recommended to generate a random Version 1 or Version 4 + // RFC 4122 UUID (services aiming for reproducible UUIDs may also use + // Version 5, see RFC 4122 for more recommendations). + ServiceInstanceIDKey = attribute.Key("service.instance.id") +) + +// ServiceNamespace returns an attribute KeyValue conforming to the +// "service.namespace" semantic conventions. It represents a namespace for +// `service.name`. +func ServiceNamespace(val string) attribute.KeyValue { + return ServiceNamespaceKey.String(val) +} + +// ServiceInstanceID returns an attribute KeyValue conforming to the +// "service.instance.id" semantic conventions. It represents the string ID of +// the service instance. +func ServiceInstanceID(val string) attribute.KeyValue { + return ServiceInstanceIDKey.String(val) +} + +// The telemetry SDK used to capture data recorded by the instrumentation +// libraries. +const ( + // TelemetrySDKNameKey is the attribute Key conforming to the + // "telemetry.sdk.name" semantic conventions. It represents the name of the + // telemetry SDK as defined above. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'opentelemetry' + // Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute + // to `opentelemetry`. + // If another SDK, like a fork or a vendor-provided implementation, is + // used, this SDK MUST set the + // `telemetry.sdk.name` attribute to the fully-qualified class or module + // name of this SDK's main entry point + // or another suitable identifier depending on the language. + // The identifier `opentelemetry` is reserved and MUST NOT be used in this + // case. + // All custom identifiers SHOULD be stable across different versions of an + // implementation. + TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") + + // TelemetrySDKLanguageKey is the attribute Key conforming to the + // "telemetry.sdk.language" semantic conventions. It represents the + // language of the telemetry SDK. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") + + // TelemetrySDKVersionKey is the attribute Key conforming to the + // "telemetry.sdk.version" semantic conventions. It represents the version + // string of the telemetry SDK. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: '1.2.3' + TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") +) + +var ( + // cpp + TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp") + // dotnet + TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet") + // erlang + TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang") + // go + TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go") + // java + TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java") + // nodejs + TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs") + // php + TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php") + // python + TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python") + // ruby + TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby") + // rust + TelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String("rust") + // swift + TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift") + // webjs + TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs") +) + +// TelemetrySDKName returns an attribute KeyValue conforming to the +// "telemetry.sdk.name" semantic conventions. It represents the name of the +// telemetry SDK as defined above. +func TelemetrySDKName(val string) attribute.KeyValue { + return TelemetrySDKNameKey.String(val) +} + +// TelemetrySDKVersion returns an attribute KeyValue conforming to the +// "telemetry.sdk.version" semantic conventions. It represents the version +// string of the telemetry SDK. +func TelemetrySDKVersion(val string) attribute.KeyValue { + return TelemetrySDKVersionKey.String(val) +} + +// The telemetry SDK used to capture data recorded by the instrumentation +// libraries. +const ( + // TelemetryAutoVersionKey is the attribute Key conforming to the + // "telemetry.auto.version" semantic conventions. It represents the version + // string of the auto instrumentation agent, if used. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.2.3' + TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version") +) + +// TelemetryAutoVersion returns an attribute KeyValue conforming to the +// "telemetry.auto.version" semantic conventions. It represents the version +// string of the auto instrumentation agent, if used. +func TelemetryAutoVersion(val string) attribute.KeyValue { + return TelemetryAutoVersionKey.String(val) +} + +// Resource describing the packaged software running the application code. Web +// engines are typically executed using process.runtime. +const ( + // WebEngineNameKey is the attribute Key conforming to the "webengine.name" + // semantic conventions. It represents the name of the web engine. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'WildFly' + WebEngineNameKey = attribute.Key("webengine.name") + + // WebEngineVersionKey is the attribute Key conforming to the + // "webengine.version" semantic conventions. It represents the version of + // the web engine. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '21.0.0' + WebEngineVersionKey = attribute.Key("webengine.version") + + // WebEngineDescriptionKey is the attribute Key conforming to the + // "webengine.description" semantic conventions. It represents the + // additional description of the web engine (e.g. detailed version and + // edition information). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - + // 2.2.2.Final' + WebEngineDescriptionKey = attribute.Key("webengine.description") +) + +// WebEngineName returns an attribute KeyValue conforming to the +// "webengine.name" semantic conventions. It represents the name of the web +// engine. +func WebEngineName(val string) attribute.KeyValue { + return WebEngineNameKey.String(val) +} + +// WebEngineVersion returns an attribute KeyValue conforming to the +// "webengine.version" semantic conventions. It represents the version of the +// web engine. +func WebEngineVersion(val string) attribute.KeyValue { + return WebEngineVersionKey.String(val) +} + +// WebEngineDescription returns an attribute KeyValue conforming to the +// "webengine.description" semantic conventions. It represents the additional +// description of the web engine (e.g. detailed version and edition +// information). +func WebEngineDescription(val string) attribute.KeyValue { + return WebEngineDescriptionKey.String(val) +} + +// Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's +// concepts. +const ( + // OTelScopeNameKey is the attribute Key conforming to the + // "otel.scope.name" semantic conventions. It represents the name of the + // instrumentation scope - (`InstrumentationScope.Name` in OTLP). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'io.opentelemetry.contrib.mongodb' + OTelScopeNameKey = attribute.Key("otel.scope.name") + + // OTelScopeVersionKey is the attribute Key conforming to the + // "otel.scope.version" semantic conventions. It represents the version of + // the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.0.0' + OTelScopeVersionKey = attribute.Key("otel.scope.version") +) + +// OTelScopeName returns an attribute KeyValue conforming to the +// "otel.scope.name" semantic conventions. It represents the name of the +// instrumentation scope - (`InstrumentationScope.Name` in OTLP). +func OTelScopeName(val string) attribute.KeyValue { + return OTelScopeNameKey.String(val) +} + +// OTelScopeVersion returns an attribute KeyValue conforming to the +// "otel.scope.version" semantic conventions. It represents the version of the +// instrumentation scope - (`InstrumentationScope.Version` in OTLP). +func OTelScopeVersion(val string) attribute.KeyValue { + return OTelScopeVersionKey.String(val) +} + +// Span attributes used by non-OTLP exporters to represent OpenTelemetry +// Scope's concepts. +const ( + // OTelLibraryNameKey is the attribute Key conforming to the + // "otel.library.name" semantic conventions. It represents the deprecated, + // use the `otel.scope.name` attribute. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: 'io.opentelemetry.contrib.mongodb' + OTelLibraryNameKey = attribute.Key("otel.library.name") + + // OTelLibraryVersionKey is the attribute Key conforming to the + // "otel.library.version" semantic conventions. It represents the + // deprecated, use the `otel.scope.version` attribute. + // + // Type: string + // RequirementLevel: Optional + // Stability: deprecated + // Examples: '1.0.0' + OTelLibraryVersionKey = attribute.Key("otel.library.version") +) + +// OTelLibraryName returns an attribute KeyValue conforming to the +// "otel.library.name" semantic conventions. It represents the deprecated, use +// the `otel.scope.name` attribute. +func OTelLibraryName(val string) attribute.KeyValue { + return OTelLibraryNameKey.String(val) +} + +// OTelLibraryVersion returns an attribute KeyValue conforming to the +// "otel.library.version" semantic conventions. It represents the deprecated, +// use the `otel.scope.version` attribute. +func OTelLibraryVersion(val string) attribute.KeyValue { + return OTelLibraryVersionKey.String(val) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go new file mode 100644 index 00000000000..66ffd5989f3 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +// SchemaURL is the schema URL that matches the version of the semantic conventions +// that this package defines. Semconv packages starting from v1.4.0 must declare +// non-empty schema URL in the form https://opentelemetry.io/schemas/ +const SchemaURL = "https://opentelemetry.io/schemas/1.21.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go new file mode 100644 index 00000000000..b5a91450d42 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go @@ -0,0 +1,2495 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated from semantic convention specification. DO NOT EDIT. + +package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" + +import "go.opentelemetry.io/otel/attribute" + +// The shared attributes used to report a single exception associated with a +// span or log. +const ( + // ExceptionTypeKey is the attribute Key conforming to the "exception.type" + // semantic conventions. It represents the type of the exception (its + // fully-qualified class name, if applicable). The dynamic type of the + // exception should be preferred over the static type in languages that + // support it. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'java.net.ConnectException', 'OSError' + ExceptionTypeKey = attribute.Key("exception.type") + + // ExceptionMessageKey is the attribute Key conforming to the + // "exception.message" semantic conventions. It represents the exception + // message. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Division by zero', "Can't convert 'int' object to str + // implicitly" + ExceptionMessageKey = attribute.Key("exception.message") + + // ExceptionStacktraceKey is the attribute Key conforming to the + // "exception.stacktrace" semantic conventions. It represents a stacktrace + // as a string in the natural representation for the language runtime. The + // representation is to be determined and documented by each language SIG. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Exception in thread "main" java.lang.RuntimeException: Test + // exception\\n at ' + // 'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at ' + // 'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at ' + // 'com.example.GenerateTrace.main(GenerateTrace.java:5)' + ExceptionStacktraceKey = attribute.Key("exception.stacktrace") +) + +// ExceptionType returns an attribute KeyValue conforming to the +// "exception.type" semantic conventions. It represents the type of the +// exception (its fully-qualified class name, if applicable). The dynamic type +// of the exception should be preferred over the static type in languages that +// support it. +func ExceptionType(val string) attribute.KeyValue { + return ExceptionTypeKey.String(val) +} + +// ExceptionMessage returns an attribute KeyValue conforming to the +// "exception.message" semantic conventions. It represents the exception +// message. +func ExceptionMessage(val string) attribute.KeyValue { + return ExceptionMessageKey.String(val) +} + +// ExceptionStacktrace returns an attribute KeyValue conforming to the +// "exception.stacktrace" semantic conventions. It represents a stacktrace as a +// string in the natural representation for the language runtime. The +// representation is to be determined and documented by each language SIG. +func ExceptionStacktrace(val string) attribute.KeyValue { + return ExceptionStacktraceKey.String(val) +} + +// Span attributes used by AWS Lambda (in addition to general `faas` +// attributes). +const ( + // AWSLambdaInvokedARNKey is the attribute Key conforming to the + // "aws.lambda.invoked_arn" semantic conventions. It represents the full + // invoked ARN as provided on the `Context` passed to the function + // (`Lambda-Runtime-Invoked-Function-ARN` header on the + // `/runtime/invocation/next` applicable). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias' + // Note: This may be different from `cloud.resource_id` if an alias is + // involved. + AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn") +) + +// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the +// "aws.lambda.invoked_arn" semantic conventions. It represents the full +// invoked ARN as provided on the `Context` passed to the function +// (`Lambda-Runtime-Invoked-Function-ARN` header on the +// `/runtime/invocation/next` applicable). +func AWSLambdaInvokedARN(val string) attribute.KeyValue { + return AWSLambdaInvokedARNKey.String(val) +} + +// Attributes for CloudEvents. CloudEvents is a specification on how to define +// event data in a standard way. These attributes can be attached to spans when +// performing operations with CloudEvents, regardless of the protocol being +// used. +const ( + // CloudeventsEventIDKey is the attribute Key conforming to the + // "cloudevents.event_id" semantic conventions. It represents the + // [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) + // uniquely identifies the event. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: '123e4567-e89b-12d3-a456-426614174000', '0001' + CloudeventsEventIDKey = attribute.Key("cloudevents.event_id") + + // CloudeventsEventSourceKey is the attribute Key conforming to the + // "cloudevents.event_source" semantic conventions. It represents the + // [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) + // identifies the context in which an event happened. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'https://github.com/cloudevents', + // '/cloudevents/spec/pull/123', 'my-service' + CloudeventsEventSourceKey = attribute.Key("cloudevents.event_source") + + // CloudeventsEventSpecVersionKey is the attribute Key conforming to the + // "cloudevents.event_spec_version" semantic conventions. It represents the + // [version of the CloudEvents + // specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) + // which the event uses. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '1.0' + CloudeventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version") + + // CloudeventsEventTypeKey is the attribute Key conforming to the + // "cloudevents.event_type" semantic conventions. It represents the + // [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) + // contains a value describing the type of event related to the originating + // occurrence. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'com.github.pull_request.opened', + // 'com.example.object.deleted.v2' + CloudeventsEventTypeKey = attribute.Key("cloudevents.event_type") + + // CloudeventsEventSubjectKey is the attribute Key conforming to the + // "cloudevents.event_subject" semantic conventions. It represents the + // [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) + // of the event in the context of the event producer (identified by + // source). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'mynewfile.jpg' + CloudeventsEventSubjectKey = attribute.Key("cloudevents.event_subject") +) + +// CloudeventsEventID returns an attribute KeyValue conforming to the +// "cloudevents.event_id" semantic conventions. It represents the +// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) +// uniquely identifies the event. +func CloudeventsEventID(val string) attribute.KeyValue { + return CloudeventsEventIDKey.String(val) +} + +// CloudeventsEventSource returns an attribute KeyValue conforming to the +// "cloudevents.event_source" semantic conventions. It represents the +// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) +// identifies the context in which an event happened. +func CloudeventsEventSource(val string) attribute.KeyValue { + return CloudeventsEventSourceKey.String(val) +} + +// CloudeventsEventSpecVersion returns an attribute KeyValue conforming to +// the "cloudevents.event_spec_version" semantic conventions. It represents the +// [version of the CloudEvents +// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) +// which the event uses. +func CloudeventsEventSpecVersion(val string) attribute.KeyValue { + return CloudeventsEventSpecVersionKey.String(val) +} + +// CloudeventsEventType returns an attribute KeyValue conforming to the +// "cloudevents.event_type" semantic conventions. It represents the +// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) +// contains a value describing the type of event related to the originating +// occurrence. +func CloudeventsEventType(val string) attribute.KeyValue { + return CloudeventsEventTypeKey.String(val) +} + +// CloudeventsEventSubject returns an attribute KeyValue conforming to the +// "cloudevents.event_subject" semantic conventions. It represents the +// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) +// of the event in the context of the event producer (identified by source). +func CloudeventsEventSubject(val string) attribute.KeyValue { + return CloudeventsEventSubjectKey.String(val) +} + +// Semantic conventions for the OpenTracing Shim +const ( + // OpentracingRefTypeKey is the attribute Key conforming to the + // "opentracing.ref_type" semantic conventions. It represents the + // parent-child Reference type + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: The causal relationship between a child Span and a parent Span. + OpentracingRefTypeKey = attribute.Key("opentracing.ref_type") +) + +var ( + // The parent Span depends on the child Span in some capacity + OpentracingRefTypeChildOf = OpentracingRefTypeKey.String("child_of") + // The parent Span does not depend in any way on the result of the child Span + OpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String("follows_from") +) + +// The attributes used to perform database client calls. +const ( + // DBSystemKey is the attribute Key conforming to the "db.system" semantic + // conventions. It represents an identifier for the database management + // system (DBMS) product being used. See below for a list of well-known + // identifiers. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + DBSystemKey = attribute.Key("db.system") + + // DBConnectionStringKey is the attribute Key conforming to the + // "db.connection_string" semantic conventions. It represents the + // connection string used to connect to the database. It is recommended to + // remove embedded credentials. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;' + DBConnectionStringKey = attribute.Key("db.connection_string") + + // DBUserKey is the attribute Key conforming to the "db.user" semantic + // conventions. It represents the username for accessing the database. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'readonly_user', 'reporting_user' + DBUserKey = attribute.Key("db.user") + + // DBJDBCDriverClassnameKey is the attribute Key conforming to the + // "db.jdbc.driver_classname" semantic conventions. It represents the + // fully-qualified class name of the [Java Database Connectivity + // (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) + // driver used to connect. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'org.postgresql.Driver', + // 'com.microsoft.sqlserver.jdbc.SQLServerDriver' + DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname") + + // DBNameKey is the attribute Key conforming to the "db.name" semantic + // conventions. It represents the this attribute is used to report the name + // of the database being accessed. For commands that switch the database, + // this should be set to the target database (even if the command fails). + // + // Type: string + // RequirementLevel: ConditionallyRequired (If applicable.) + // Stability: stable + // Examples: 'customers', 'main' + // Note: In some SQL databases, the database name to be used is called + // "schema name". In case there are multiple layers that could be + // considered for database name (e.g. Oracle instance name and schema + // name), the database name to be used is the more specific layer (e.g. + // Oracle schema name). + DBNameKey = attribute.Key("db.name") + + // DBStatementKey is the attribute Key conforming to the "db.statement" + // semantic conventions. It represents the database statement being + // executed. + // + // Type: string + // RequirementLevel: Recommended (Should be collected by default only if + // there is sanitization that excludes sensitive information.) + // Stability: stable + // Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"' + DBStatementKey = attribute.Key("db.statement") + + // DBOperationKey is the attribute Key conforming to the "db.operation" + // semantic conventions. It represents the name of the operation being + // executed, e.g. the [MongoDB command + // name](https://docs.mongodb.com/manual/reference/command/#database-operations) + // such as `findAndModify`, or the SQL keyword. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If `db.statement` is not + // applicable.) + // Stability: stable + // Examples: 'findAndModify', 'HMSET', 'SELECT' + // Note: When setting this to an SQL keyword, it is not recommended to + // attempt any client-side parsing of `db.statement` just to get this + // property, but it should be set if the operation name is provided by the + // library being instrumented. If the SQL statement has an ambiguous + // operation, or performs more than one operation, this value may be + // omitted. + DBOperationKey = attribute.Key("db.operation") +) + +var ( + // Some other SQL database. Fallback only. See notes + DBSystemOtherSQL = DBSystemKey.String("other_sql") + // Microsoft SQL Server + DBSystemMSSQL = DBSystemKey.String("mssql") + // Microsoft SQL Server Compact + DBSystemMssqlcompact = DBSystemKey.String("mssqlcompact") + // MySQL + DBSystemMySQL = DBSystemKey.String("mysql") + // Oracle Database + DBSystemOracle = DBSystemKey.String("oracle") + // IBM DB2 + DBSystemDB2 = DBSystemKey.String("db2") + // PostgreSQL + DBSystemPostgreSQL = DBSystemKey.String("postgresql") + // Amazon Redshift + DBSystemRedshift = DBSystemKey.String("redshift") + // Apache Hive + DBSystemHive = DBSystemKey.String("hive") + // Cloudscape + DBSystemCloudscape = DBSystemKey.String("cloudscape") + // HyperSQL DataBase + DBSystemHSQLDB = DBSystemKey.String("hsqldb") + // Progress Database + DBSystemProgress = DBSystemKey.String("progress") + // SAP MaxDB + DBSystemMaxDB = DBSystemKey.String("maxdb") + // SAP HANA + DBSystemHanaDB = DBSystemKey.String("hanadb") + // Ingres + DBSystemIngres = DBSystemKey.String("ingres") + // FirstSQL + DBSystemFirstSQL = DBSystemKey.String("firstsql") + // EnterpriseDB + DBSystemEDB = DBSystemKey.String("edb") + // InterSystems Caché + DBSystemCache = DBSystemKey.String("cache") + // Adabas (Adaptable Database System) + DBSystemAdabas = DBSystemKey.String("adabas") + // Firebird + DBSystemFirebird = DBSystemKey.String("firebird") + // Apache Derby + DBSystemDerby = DBSystemKey.String("derby") + // FileMaker + DBSystemFilemaker = DBSystemKey.String("filemaker") + // Informix + DBSystemInformix = DBSystemKey.String("informix") + // InstantDB + DBSystemInstantDB = DBSystemKey.String("instantdb") + // InterBase + DBSystemInterbase = DBSystemKey.String("interbase") + // MariaDB + DBSystemMariaDB = DBSystemKey.String("mariadb") + // Netezza + DBSystemNetezza = DBSystemKey.String("netezza") + // Pervasive PSQL + DBSystemPervasive = DBSystemKey.String("pervasive") + // PointBase + DBSystemPointbase = DBSystemKey.String("pointbase") + // SQLite + DBSystemSqlite = DBSystemKey.String("sqlite") + // Sybase + DBSystemSybase = DBSystemKey.String("sybase") + // Teradata + DBSystemTeradata = DBSystemKey.String("teradata") + // Vertica + DBSystemVertica = DBSystemKey.String("vertica") + // H2 + DBSystemH2 = DBSystemKey.String("h2") + // ColdFusion IMQ + DBSystemColdfusion = DBSystemKey.String("coldfusion") + // Apache Cassandra + DBSystemCassandra = DBSystemKey.String("cassandra") + // Apache HBase + DBSystemHBase = DBSystemKey.String("hbase") + // MongoDB + DBSystemMongoDB = DBSystemKey.String("mongodb") + // Redis + DBSystemRedis = DBSystemKey.String("redis") + // Couchbase + DBSystemCouchbase = DBSystemKey.String("couchbase") + // CouchDB + DBSystemCouchDB = DBSystemKey.String("couchdb") + // Microsoft Azure Cosmos DB + DBSystemCosmosDB = DBSystemKey.String("cosmosdb") + // Amazon DynamoDB + DBSystemDynamoDB = DBSystemKey.String("dynamodb") + // Neo4j + DBSystemNeo4j = DBSystemKey.String("neo4j") + // Apache Geode + DBSystemGeode = DBSystemKey.String("geode") + // Elasticsearch + DBSystemElasticsearch = DBSystemKey.String("elasticsearch") + // Memcached + DBSystemMemcached = DBSystemKey.String("memcached") + // CockroachDB + DBSystemCockroachdb = DBSystemKey.String("cockroachdb") + // OpenSearch + DBSystemOpensearch = DBSystemKey.String("opensearch") + // ClickHouse + DBSystemClickhouse = DBSystemKey.String("clickhouse") + // Cloud Spanner + DBSystemSpanner = DBSystemKey.String("spanner") + // Trino + DBSystemTrino = DBSystemKey.String("trino") +) + +// DBConnectionString returns an attribute KeyValue conforming to the +// "db.connection_string" semantic conventions. It represents the connection +// string used to connect to the database. It is recommended to remove embedded +// credentials. +func DBConnectionString(val string) attribute.KeyValue { + return DBConnectionStringKey.String(val) +} + +// DBUser returns an attribute KeyValue conforming to the "db.user" semantic +// conventions. It represents the username for accessing the database. +func DBUser(val string) attribute.KeyValue { + return DBUserKey.String(val) +} + +// DBJDBCDriverClassname returns an attribute KeyValue conforming to the +// "db.jdbc.driver_classname" semantic conventions. It represents the +// fully-qualified class name of the [Java Database Connectivity +// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver +// used to connect. +func DBJDBCDriverClassname(val string) attribute.KeyValue { + return DBJDBCDriverClassnameKey.String(val) +} + +// DBName returns an attribute KeyValue conforming to the "db.name" semantic +// conventions. It represents the this attribute is used to report the name of +// the database being accessed. For commands that switch the database, this +// should be set to the target database (even if the command fails). +func DBName(val string) attribute.KeyValue { + return DBNameKey.String(val) +} + +// DBStatement returns an attribute KeyValue conforming to the +// "db.statement" semantic conventions. It represents the database statement +// being executed. +func DBStatement(val string) attribute.KeyValue { + return DBStatementKey.String(val) +} + +// DBOperation returns an attribute KeyValue conforming to the +// "db.operation" semantic conventions. It represents the name of the operation +// being executed, e.g. the [MongoDB command +// name](https://docs.mongodb.com/manual/reference/command/#database-operations) +// such as `findAndModify`, or the SQL keyword. +func DBOperation(val string) attribute.KeyValue { + return DBOperationKey.String(val) +} + +// Connection-level attributes for Microsoft SQL Server +const ( + // DBMSSQLInstanceNameKey is the attribute Key conforming to the + // "db.mssql.instance_name" semantic conventions. It represents the + // Microsoft SQL Server [instance + // name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + // connecting to. This name is used to determine the port of a named + // instance. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'MSSQLSERVER' + // Note: If setting a `db.mssql.instance_name`, `server.port` is no longer + // required (but still recommended if non-standard). + DBMSSQLInstanceNameKey = attribute.Key("db.mssql.instance_name") +) + +// DBMSSQLInstanceName returns an attribute KeyValue conforming to the +// "db.mssql.instance_name" semantic conventions. It represents the Microsoft +// SQL Server [instance +// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) +// connecting to. This name is used to determine the port of a named instance. +func DBMSSQLInstanceName(val string) attribute.KeyValue { + return DBMSSQLInstanceNameKey.String(val) +} + +// Call-level attributes for Cassandra +const ( + // DBCassandraPageSizeKey is the attribute Key conforming to the + // "db.cassandra.page_size" semantic conventions. It represents the fetch + // size used for paging, i.e. how many rows will be returned at once. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 5000 + DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size") + + // DBCassandraConsistencyLevelKey is the attribute Key conforming to the + // "db.cassandra.consistency_level" semantic conventions. It represents the + // consistency level of the query. Based on consistency values from + // [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level") + + // DBCassandraTableKey is the attribute Key conforming to the + // "db.cassandra.table" semantic conventions. It represents the name of the + // primary table that the operation is acting upon, including the keyspace + // name (if applicable). + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'mytable' + // Note: This mirrors the db.sql.table attribute but references cassandra + // rather than sql. It is not recommended to attempt any client-side + // parsing of `db.statement` just to get this property, but it should be + // set if it is provided by the library being instrumented. If the + // operation is acting upon an anonymous table, or more than one table, + // this value MUST NOT be set. + DBCassandraTableKey = attribute.Key("db.cassandra.table") + + // DBCassandraIdempotenceKey is the attribute Key conforming to the + // "db.cassandra.idempotence" semantic conventions. It represents the + // whether or not the query is idempotent. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence") + + // DBCassandraSpeculativeExecutionCountKey is the attribute Key conforming + // to the "db.cassandra.speculative_execution_count" semantic conventions. + // It represents the number of times a query was speculatively executed. + // Not set or `0` if the query was not executed speculatively. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 0, 2 + DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count") + + // DBCassandraCoordinatorIDKey is the attribute Key conforming to the + // "db.cassandra.coordinator.id" semantic conventions. It represents the ID + // of the coordinating node for a query. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id") + + // DBCassandraCoordinatorDCKey is the attribute Key conforming to the + // "db.cassandra.coordinator.dc" semantic conventions. It represents the + // data center of the coordinating node for a query. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'us-west-2' + DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc") +) + +var ( + // all + DBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String("all") + // each_quorum + DBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String("each_quorum") + // quorum + DBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String("quorum") + // local_quorum + DBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String("local_quorum") + // one + DBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String("one") + // two + DBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String("two") + // three + DBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String("three") + // local_one + DBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String("local_one") + // any + DBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String("any") + // serial + DBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String("serial") + // local_serial + DBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String("local_serial") +) + +// DBCassandraPageSize returns an attribute KeyValue conforming to the +// "db.cassandra.page_size" semantic conventions. It represents the fetch size +// used for paging, i.e. how many rows will be returned at once. +func DBCassandraPageSize(val int) attribute.KeyValue { + return DBCassandraPageSizeKey.Int(val) +} + +// DBCassandraTable returns an attribute KeyValue conforming to the +// "db.cassandra.table" semantic conventions. It represents the name of the +// primary table that the operation is acting upon, including the keyspace name +// (if applicable). +func DBCassandraTable(val string) attribute.KeyValue { + return DBCassandraTableKey.String(val) +} + +// DBCassandraIdempotence returns an attribute KeyValue conforming to the +// "db.cassandra.idempotence" semantic conventions. It represents the whether +// or not the query is idempotent. +func DBCassandraIdempotence(val bool) attribute.KeyValue { + return DBCassandraIdempotenceKey.Bool(val) +} + +// DBCassandraSpeculativeExecutionCount returns an attribute KeyValue +// conforming to the "db.cassandra.speculative_execution_count" semantic +// conventions. It represents the number of times a query was speculatively +// executed. Not set or `0` if the query was not executed speculatively. +func DBCassandraSpeculativeExecutionCount(val int) attribute.KeyValue { + return DBCassandraSpeculativeExecutionCountKey.Int(val) +} + +// DBCassandraCoordinatorID returns an attribute KeyValue conforming to the +// "db.cassandra.coordinator.id" semantic conventions. It represents the ID of +// the coordinating node for a query. +func DBCassandraCoordinatorID(val string) attribute.KeyValue { + return DBCassandraCoordinatorIDKey.String(val) +} + +// DBCassandraCoordinatorDC returns an attribute KeyValue conforming to the +// "db.cassandra.coordinator.dc" semantic conventions. It represents the data +// center of the coordinating node for a query. +func DBCassandraCoordinatorDC(val string) attribute.KeyValue { + return DBCassandraCoordinatorDCKey.String(val) +} + +// Call-level attributes for Redis +const ( + // DBRedisDBIndexKey is the attribute Key conforming to the + // "db.redis.database_index" semantic conventions. It represents the index + // of the database being accessed as used in the [`SELECT` + // command](https://redis.io/commands/select), provided as an integer. To + // be used instead of the generic `db.name` attribute. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If other than the default + // database (`0`).) + // Stability: stable + // Examples: 0, 1, 15 + DBRedisDBIndexKey = attribute.Key("db.redis.database_index") +) + +// DBRedisDBIndex returns an attribute KeyValue conforming to the +// "db.redis.database_index" semantic conventions. It represents the index of +// the database being accessed as used in the [`SELECT` +// command](https://redis.io/commands/select), provided as an integer. To be +// used instead of the generic `db.name` attribute. +func DBRedisDBIndex(val int) attribute.KeyValue { + return DBRedisDBIndexKey.Int(val) +} + +// Call-level attributes for MongoDB +const ( + // DBMongoDBCollectionKey is the attribute Key conforming to the + // "db.mongodb.collection" semantic conventions. It represents the + // collection being accessed within the database stated in `db.name`. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'customers', 'products' + DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection") +) + +// DBMongoDBCollection returns an attribute KeyValue conforming to the +// "db.mongodb.collection" semantic conventions. It represents the collection +// being accessed within the database stated in `db.name`. +func DBMongoDBCollection(val string) attribute.KeyValue { + return DBMongoDBCollectionKey.String(val) +} + +// Call-level attributes for SQL databases +const ( + // DBSQLTableKey is the attribute Key conforming to the "db.sql.table" + // semantic conventions. It represents the name of the primary table that + // the operation is acting upon, including the database name (if + // applicable). + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'public.users', 'customers' + // Note: It is not recommended to attempt any client-side parsing of + // `db.statement` just to get this property, but it should be set if it is + // provided by the library being instrumented. If the operation is acting + // upon an anonymous table, or more than one table, this value MUST NOT be + // set. + DBSQLTableKey = attribute.Key("db.sql.table") +) + +// DBSQLTable returns an attribute KeyValue conforming to the "db.sql.table" +// semantic conventions. It represents the name of the primary table that the +// operation is acting upon, including the database name (if applicable). +func DBSQLTable(val string) attribute.KeyValue { + return DBSQLTableKey.String(val) +} + +// Call-level attributes for Cosmos DB. +const ( + // DBCosmosDBClientIDKey is the attribute Key conforming to the + // "db.cosmosdb.client_id" semantic conventions. It represents the unique + // Cosmos client instance id. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '3ba4827d-4422-483f-b59f-85b74211c11d' + DBCosmosDBClientIDKey = attribute.Key("db.cosmosdb.client_id") + + // DBCosmosDBOperationTypeKey is the attribute Key conforming to the + // "db.cosmosdb.operation_type" semantic conventions. It represents the + // cosmosDB Operation Type. + // + // Type: Enum + // RequirementLevel: ConditionallyRequired (when performing one of the + // operations in this list) + // Stability: stable + DBCosmosDBOperationTypeKey = attribute.Key("db.cosmosdb.operation_type") + + // DBCosmosDBConnectionModeKey is the attribute Key conforming to the + // "db.cosmosdb.connection_mode" semantic conventions. It represents the + // cosmos client connection mode. + // + // Type: Enum + // RequirementLevel: ConditionallyRequired (if not `direct` (or pick gw as + // default)) + // Stability: stable + DBCosmosDBConnectionModeKey = attribute.Key("db.cosmosdb.connection_mode") + + // DBCosmosDBContainerKey is the attribute Key conforming to the + // "db.cosmosdb.container" semantic conventions. It represents the cosmos + // DB container name. + // + // Type: string + // RequirementLevel: ConditionallyRequired (if available) + // Stability: stable + // Examples: 'anystring' + DBCosmosDBContainerKey = attribute.Key("db.cosmosdb.container") + + // DBCosmosDBRequestContentLengthKey is the attribute Key conforming to the + // "db.cosmosdb.request_content_length" semantic conventions. It represents + // the request payload size in bytes + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + DBCosmosDBRequestContentLengthKey = attribute.Key("db.cosmosdb.request_content_length") + + // DBCosmosDBStatusCodeKey is the attribute Key conforming to the + // "db.cosmosdb.status_code" semantic conventions. It represents the cosmos + // DB status code. + // + // Type: int + // RequirementLevel: ConditionallyRequired (if response was received) + // Stability: stable + // Examples: 200, 201 + DBCosmosDBStatusCodeKey = attribute.Key("db.cosmosdb.status_code") + + // DBCosmosDBSubStatusCodeKey is the attribute Key conforming to the + // "db.cosmosdb.sub_status_code" semantic conventions. It represents the + // cosmos DB sub status code. + // + // Type: int + // RequirementLevel: ConditionallyRequired (when response was received and + // contained sub-code.) + // Stability: stable + // Examples: 1000, 1002 + DBCosmosDBSubStatusCodeKey = attribute.Key("db.cosmosdb.sub_status_code") + + // DBCosmosDBRequestChargeKey is the attribute Key conforming to the + // "db.cosmosdb.request_charge" semantic conventions. It represents the rU + // consumed for that operation + // + // Type: double + // RequirementLevel: ConditionallyRequired (when available) + // Stability: stable + // Examples: 46.18, 1.0 + DBCosmosDBRequestChargeKey = attribute.Key("db.cosmosdb.request_charge") +) + +var ( + // invalid + DBCosmosDBOperationTypeInvalid = DBCosmosDBOperationTypeKey.String("Invalid") + // create + DBCosmosDBOperationTypeCreate = DBCosmosDBOperationTypeKey.String("Create") + // patch + DBCosmosDBOperationTypePatch = DBCosmosDBOperationTypeKey.String("Patch") + // read + DBCosmosDBOperationTypeRead = DBCosmosDBOperationTypeKey.String("Read") + // read_feed + DBCosmosDBOperationTypeReadFeed = DBCosmosDBOperationTypeKey.String("ReadFeed") + // delete + DBCosmosDBOperationTypeDelete = DBCosmosDBOperationTypeKey.String("Delete") + // replace + DBCosmosDBOperationTypeReplace = DBCosmosDBOperationTypeKey.String("Replace") + // execute + DBCosmosDBOperationTypeExecute = DBCosmosDBOperationTypeKey.String("Execute") + // query + DBCosmosDBOperationTypeQuery = DBCosmosDBOperationTypeKey.String("Query") + // head + DBCosmosDBOperationTypeHead = DBCosmosDBOperationTypeKey.String("Head") + // head_feed + DBCosmosDBOperationTypeHeadFeed = DBCosmosDBOperationTypeKey.String("HeadFeed") + // upsert + DBCosmosDBOperationTypeUpsert = DBCosmosDBOperationTypeKey.String("Upsert") + // batch + DBCosmosDBOperationTypeBatch = DBCosmosDBOperationTypeKey.String("Batch") + // query_plan + DBCosmosDBOperationTypeQueryPlan = DBCosmosDBOperationTypeKey.String("QueryPlan") + // execute_javascript + DBCosmosDBOperationTypeExecuteJavascript = DBCosmosDBOperationTypeKey.String("ExecuteJavaScript") +) + +var ( + // Gateway (HTTP) connections mode + DBCosmosDBConnectionModeGateway = DBCosmosDBConnectionModeKey.String("gateway") + // Direct connection + DBCosmosDBConnectionModeDirect = DBCosmosDBConnectionModeKey.String("direct") +) + +// DBCosmosDBClientID returns an attribute KeyValue conforming to the +// "db.cosmosdb.client_id" semantic conventions. It represents the unique +// Cosmos client instance id. +func DBCosmosDBClientID(val string) attribute.KeyValue { + return DBCosmosDBClientIDKey.String(val) +} + +// DBCosmosDBContainer returns an attribute KeyValue conforming to the +// "db.cosmosdb.container" semantic conventions. It represents the cosmos DB +// container name. +func DBCosmosDBContainer(val string) attribute.KeyValue { + return DBCosmosDBContainerKey.String(val) +} + +// DBCosmosDBRequestContentLength returns an attribute KeyValue conforming +// to the "db.cosmosdb.request_content_length" semantic conventions. It +// represents the request payload size in bytes +func DBCosmosDBRequestContentLength(val int) attribute.KeyValue { + return DBCosmosDBRequestContentLengthKey.Int(val) +} + +// DBCosmosDBStatusCode returns an attribute KeyValue conforming to the +// "db.cosmosdb.status_code" semantic conventions. It represents the cosmos DB +// status code. +func DBCosmosDBStatusCode(val int) attribute.KeyValue { + return DBCosmosDBStatusCodeKey.Int(val) +} + +// DBCosmosDBSubStatusCode returns an attribute KeyValue conforming to the +// "db.cosmosdb.sub_status_code" semantic conventions. It represents the cosmos +// DB sub status code. +func DBCosmosDBSubStatusCode(val int) attribute.KeyValue { + return DBCosmosDBSubStatusCodeKey.Int(val) +} + +// DBCosmosDBRequestCharge returns an attribute KeyValue conforming to the +// "db.cosmosdb.request_charge" semantic conventions. It represents the rU +// consumed for that operation +func DBCosmosDBRequestCharge(val float64) attribute.KeyValue { + return DBCosmosDBRequestChargeKey.Float64(val) +} + +// Span attributes used by non-OTLP exporters to represent OpenTelemetry Span's +// concepts. +const ( + // OTelStatusCodeKey is the attribute Key conforming to the + // "otel.status_code" semantic conventions. It represents the name of the + // code, either "OK" or "ERROR". MUST NOT be set if the status code is + // UNSET. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + OTelStatusCodeKey = attribute.Key("otel.status_code") + + // OTelStatusDescriptionKey is the attribute Key conforming to the + // "otel.status_description" semantic conventions. It represents the + // description of the Status if it has a value, otherwise not set. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'resource not found' + OTelStatusDescriptionKey = attribute.Key("otel.status_description") +) + +var ( + // The operation has been validated by an Application developer or Operator to have completed successfully + OTelStatusCodeOk = OTelStatusCodeKey.String("OK") + // The operation contains an error + OTelStatusCodeError = OTelStatusCodeKey.String("ERROR") +) + +// OTelStatusDescription returns an attribute KeyValue conforming to the +// "otel.status_description" semantic conventions. It represents the +// description of the Status if it has a value, otherwise not set. +func OTelStatusDescription(val string) attribute.KeyValue { + return OTelStatusDescriptionKey.String(val) +} + +// This semantic convention describes an instance of a function that runs +// without provisioning or managing of servers (also known as serverless +// functions or Function as a Service (FaaS)) with spans. +const ( + // FaaSTriggerKey is the attribute Key conforming to the "faas.trigger" + // semantic conventions. It represents the type of the trigger which caused + // this function invocation. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Note: For the server/consumer span on the incoming side, + // `faas.trigger` MUST be set. + // + // Clients invoking FaaS instances usually cannot set `faas.trigger`, + // since they would typically need to look in the payload to determine + // the event type. If clients set it, it should be the same as the + // trigger that corresponding incoming would have (i.e., this has + // nothing to do with the underlying transport used to make the API + // call to invoke the lambda, which is often HTTP). + FaaSTriggerKey = attribute.Key("faas.trigger") + + // FaaSInvocationIDKey is the attribute Key conforming to the + // "faas.invocation_id" semantic conventions. It represents the invocation + // ID of the current function invocation. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' + FaaSInvocationIDKey = attribute.Key("faas.invocation_id") +) + +var ( + // A response to some data source operation such as a database or filesystem read/write + FaaSTriggerDatasource = FaaSTriggerKey.String("datasource") + // To provide an answer to an inbound HTTP request + FaaSTriggerHTTP = FaaSTriggerKey.String("http") + // A function is set to be executed when messages are sent to a messaging system + FaaSTriggerPubsub = FaaSTriggerKey.String("pubsub") + // A function is scheduled to be executed regularly + FaaSTriggerTimer = FaaSTriggerKey.String("timer") + // If none of the others apply + FaaSTriggerOther = FaaSTriggerKey.String("other") +) + +// FaaSInvocationID returns an attribute KeyValue conforming to the +// "faas.invocation_id" semantic conventions. It represents the invocation ID +// of the current function invocation. +func FaaSInvocationID(val string) attribute.KeyValue { + return FaaSInvocationIDKey.String(val) +} + +// Semantic Convention for FaaS triggered as a response to some data source +// operation such as a database or filesystem read/write. +const ( + // FaaSDocumentCollectionKey is the attribute Key conforming to the + // "faas.document.collection" semantic conventions. It represents the name + // of the source on which the triggering operation was performed. For + // example, in Cloud Storage or S3 corresponds to the bucket name, and in + // Cosmos DB to the database name. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'myBucketName', 'myDBName' + FaaSDocumentCollectionKey = attribute.Key("faas.document.collection") + + // FaaSDocumentOperationKey is the attribute Key conforming to the + // "faas.document.operation" semantic conventions. It represents the + // describes the type of the operation that was performed on the data. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + FaaSDocumentOperationKey = attribute.Key("faas.document.operation") + + // FaaSDocumentTimeKey is the attribute Key conforming to the + // "faas.document.time" semantic conventions. It represents a string + // containing the time when the data was accessed in the [ISO + // 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format + // expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2020-01-23T13:47:06Z' + FaaSDocumentTimeKey = attribute.Key("faas.document.time") + + // FaaSDocumentNameKey is the attribute Key conforming to the + // "faas.document.name" semantic conventions. It represents the document + // name/table subjected to the operation. For example, in Cloud Storage or + // S3 is the name of the file, and in Cosmos DB the table name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'myFile.txt', 'myTableName' + FaaSDocumentNameKey = attribute.Key("faas.document.name") +) + +var ( + // When a new object is created + FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert") + // When an object is modified + FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit") + // When an object is deleted + FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete") +) + +// FaaSDocumentCollection returns an attribute KeyValue conforming to the +// "faas.document.collection" semantic conventions. It represents the name of +// the source on which the triggering operation was performed. For example, in +// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the +// database name. +func FaaSDocumentCollection(val string) attribute.KeyValue { + return FaaSDocumentCollectionKey.String(val) +} + +// FaaSDocumentTime returns an attribute KeyValue conforming to the +// "faas.document.time" semantic conventions. It represents a string containing +// the time when the data was accessed in the [ISO +// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format +// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +func FaaSDocumentTime(val string) attribute.KeyValue { + return FaaSDocumentTimeKey.String(val) +} + +// FaaSDocumentName returns an attribute KeyValue conforming to the +// "faas.document.name" semantic conventions. It represents the document +// name/table subjected to the operation. For example, in Cloud Storage or S3 +// is the name of the file, and in Cosmos DB the table name. +func FaaSDocumentName(val string) attribute.KeyValue { + return FaaSDocumentNameKey.String(val) +} + +// Semantic Convention for FaaS scheduled to be executed regularly. +const ( + // FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic + // conventions. It represents a string containing the function invocation + // time in the [ISO + // 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format + // expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '2020-01-23T13:47:06Z' + FaaSTimeKey = attribute.Key("faas.time") + + // FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic + // conventions. It represents a string containing the schedule period as + // [Cron + // Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '0/5 * * * ? *' + FaaSCronKey = attribute.Key("faas.cron") +) + +// FaaSTime returns an attribute KeyValue conforming to the "faas.time" +// semantic conventions. It represents a string containing the function +// invocation time in the [ISO +// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format +// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +func FaaSTime(val string) attribute.KeyValue { + return FaaSTimeKey.String(val) +} + +// FaaSCron returns an attribute KeyValue conforming to the "faas.cron" +// semantic conventions. It represents a string containing the schedule period +// as [Cron +// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). +func FaaSCron(val string) attribute.KeyValue { + return FaaSCronKey.String(val) +} + +// Contains additional attributes for incoming FaaS spans. +const ( + // FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart" + // semantic conventions. It represents a boolean that is true if the + // serverless function is executed for the first time (aka cold-start). + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + FaaSColdstartKey = attribute.Key("faas.coldstart") +) + +// FaaSColdstart returns an attribute KeyValue conforming to the +// "faas.coldstart" semantic conventions. It represents a boolean that is true +// if the serverless function is executed for the first time (aka cold-start). +func FaaSColdstart(val bool) attribute.KeyValue { + return FaaSColdstartKey.Bool(val) +} + +// Contains additional attributes for outgoing FaaS spans. +const ( + // FaaSInvokedNameKey is the attribute Key conforming to the + // "faas.invoked_name" semantic conventions. It represents the name of the + // invoked function. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'my-function' + // Note: SHOULD be equal to the `faas.name` resource attribute of the + // invoked function. + FaaSInvokedNameKey = attribute.Key("faas.invoked_name") + + // FaaSInvokedProviderKey is the attribute Key conforming to the + // "faas.invoked_provider" semantic conventions. It represents the cloud + // provider of the invoked function. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: SHOULD be equal to the `cloud.provider` resource attribute of the + // invoked function. + FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider") + + // FaaSInvokedRegionKey is the attribute Key conforming to the + // "faas.invoked_region" semantic conventions. It represents the cloud + // region of the invoked function. + // + // Type: string + // RequirementLevel: ConditionallyRequired (For some cloud providers, like + // AWS or GCP, the region in which a function is hosted is essential to + // uniquely identify the function and also part of its endpoint. Since it's + // part of the endpoint being called, the region is always known to + // clients. In these cases, `faas.invoked_region` MUST be set accordingly. + // If the region is unknown to the client or not required for identifying + // the invoked function, setting `faas.invoked_region` is optional.) + // Stability: stable + // Examples: 'eu-central-1' + // Note: SHOULD be equal to the `cloud.region` resource attribute of the + // invoked function. + FaaSInvokedRegionKey = attribute.Key("faas.invoked_region") +) + +var ( + // Alibaba Cloud + FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud") + // Amazon Web Services + FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws") + // Microsoft Azure + FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure") + // Google Cloud Platform + FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp") + // Tencent Cloud + FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud") +) + +// FaaSInvokedName returns an attribute KeyValue conforming to the +// "faas.invoked_name" semantic conventions. It represents the name of the +// invoked function. +func FaaSInvokedName(val string) attribute.KeyValue { + return FaaSInvokedNameKey.String(val) +} + +// FaaSInvokedRegion returns an attribute KeyValue conforming to the +// "faas.invoked_region" semantic conventions. It represents the cloud region +// of the invoked function. +func FaaSInvokedRegion(val string) attribute.KeyValue { + return FaaSInvokedRegionKey.String(val) +} + +// Operations that access some remote service. +const ( + // PeerServiceKey is the attribute Key conforming to the "peer.service" + // semantic conventions. It represents the + // [`service.name`](/docs/resource/README.md#service) of the remote + // service. SHOULD be equal to the actual `service.name` resource attribute + // of the remote service if any. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'AuthTokenCache' + PeerServiceKey = attribute.Key("peer.service") +) + +// PeerService returns an attribute KeyValue conforming to the +// "peer.service" semantic conventions. It represents the +// [`service.name`](/docs/resource/README.md#service) of the remote service. +// SHOULD be equal to the actual `service.name` resource attribute of the +// remote service if any. +func PeerService(val string) attribute.KeyValue { + return PeerServiceKey.String(val) +} + +// These attributes may be used for any operation with an authenticated and/or +// authorized enduser. +const ( + // EnduserIDKey is the attribute Key conforming to the "enduser.id" + // semantic conventions. It represents the username or client_id extracted + // from the access token or + // [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header + // in the inbound request from outside the system. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'username' + EnduserIDKey = attribute.Key("enduser.id") + + // EnduserRoleKey is the attribute Key conforming to the "enduser.role" + // semantic conventions. It represents the actual/assumed role the client + // is making the request under extracted from token or application security + // context. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'admin' + EnduserRoleKey = attribute.Key("enduser.role") + + // EnduserScopeKey is the attribute Key conforming to the "enduser.scope" + // semantic conventions. It represents the scopes or granted authorities + // the client currently possesses extracted from token or application + // security context. The value would come from the scope associated with an + // [OAuth 2.0 Access + // Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute + // value in a [SAML 2.0 + // Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'read:message, write:files' + EnduserScopeKey = attribute.Key("enduser.scope") +) + +// EnduserID returns an attribute KeyValue conforming to the "enduser.id" +// semantic conventions. It represents the username or client_id extracted from +// the access token or +// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in +// the inbound request from outside the system. +func EnduserID(val string) attribute.KeyValue { + return EnduserIDKey.String(val) +} + +// EnduserRole returns an attribute KeyValue conforming to the +// "enduser.role" semantic conventions. It represents the actual/assumed role +// the client is making the request under extracted from token or application +// security context. +func EnduserRole(val string) attribute.KeyValue { + return EnduserRoleKey.String(val) +} + +// EnduserScope returns an attribute KeyValue conforming to the +// "enduser.scope" semantic conventions. It represents the scopes or granted +// authorities the client currently possesses extracted from token or +// application security context. The value would come from the scope associated +// with an [OAuth 2.0 Access +// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute +// value in a [SAML 2.0 +// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). +func EnduserScope(val string) attribute.KeyValue { + return EnduserScopeKey.String(val) +} + +// These attributes may be used for any operation to store information about a +// thread that started a span. +const ( + // ThreadIDKey is the attribute Key conforming to the "thread.id" semantic + // conventions. It represents the current "managed" thread ID (as opposed + // to OS thread ID). + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + ThreadIDKey = attribute.Key("thread.id") + + // ThreadNameKey is the attribute Key conforming to the "thread.name" + // semantic conventions. It represents the current thread name. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'main' + ThreadNameKey = attribute.Key("thread.name") +) + +// ThreadID returns an attribute KeyValue conforming to the "thread.id" +// semantic conventions. It represents the current "managed" thread ID (as +// opposed to OS thread ID). +func ThreadID(val int) attribute.KeyValue { + return ThreadIDKey.Int(val) +} + +// ThreadName returns an attribute KeyValue conforming to the "thread.name" +// semantic conventions. It represents the current thread name. +func ThreadName(val string) attribute.KeyValue { + return ThreadNameKey.String(val) +} + +// These attributes allow to report this unit of code and therefore to provide +// more context about the span. +const ( + // CodeFunctionKey is the attribute Key conforming to the "code.function" + // semantic conventions. It represents the method or function name, or + // equivalent (usually rightmost part of the code unit's name). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'serveRequest' + CodeFunctionKey = attribute.Key("code.function") + + // CodeNamespaceKey is the attribute Key conforming to the "code.namespace" + // semantic conventions. It represents the "namespace" within which + // `code.function` is defined. Usually the qualified class or module name, + // such that `code.namespace` + some separator + `code.function` form a + // unique identifier for the code unit. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'com.example.MyHTTPService' + CodeNamespaceKey = attribute.Key("code.namespace") + + // CodeFilepathKey is the attribute Key conforming to the "code.filepath" + // semantic conventions. It represents the source code file name that + // identifies the code unit as uniquely as possible (preferably an absolute + // file path). + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '/usr/local/MyApplication/content_root/app/index.php' + CodeFilepathKey = attribute.Key("code.filepath") + + // CodeLineNumberKey is the attribute Key conforming to the "code.lineno" + // semantic conventions. It represents the line number in `code.filepath` + // best representing the operation. It SHOULD point within the code unit + // named in `code.function`. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 42 + CodeLineNumberKey = attribute.Key("code.lineno") + + // CodeColumnKey is the attribute Key conforming to the "code.column" + // semantic conventions. It represents the column number in `code.filepath` + // best representing the operation. It SHOULD point within the code unit + // named in `code.function`. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 16 + CodeColumnKey = attribute.Key("code.column") +) + +// CodeFunction returns an attribute KeyValue conforming to the +// "code.function" semantic conventions. It represents the method or function +// name, or equivalent (usually rightmost part of the code unit's name). +func CodeFunction(val string) attribute.KeyValue { + return CodeFunctionKey.String(val) +} + +// CodeNamespace returns an attribute KeyValue conforming to the +// "code.namespace" semantic conventions. It represents the "namespace" within +// which `code.function` is defined. Usually the qualified class or module +// name, such that `code.namespace` + some separator + `code.function` form a +// unique identifier for the code unit. +func CodeNamespace(val string) attribute.KeyValue { + return CodeNamespaceKey.String(val) +} + +// CodeFilepath returns an attribute KeyValue conforming to the +// "code.filepath" semantic conventions. It represents the source code file +// name that identifies the code unit as uniquely as possible (preferably an +// absolute file path). +func CodeFilepath(val string) attribute.KeyValue { + return CodeFilepathKey.String(val) +} + +// CodeLineNumber returns an attribute KeyValue conforming to the "code.lineno" +// semantic conventions. It represents the line number in `code.filepath` best +// representing the operation. It SHOULD point within the code unit named in +// `code.function`. +func CodeLineNumber(val int) attribute.KeyValue { + return CodeLineNumberKey.Int(val) +} + +// CodeColumn returns an attribute KeyValue conforming to the "code.column" +// semantic conventions. It represents the column number in `code.filepath` +// best representing the operation. It SHOULD point within the code unit named +// in `code.function`. +func CodeColumn(val int) attribute.KeyValue { + return CodeColumnKey.Int(val) +} + +// Semantic Convention for HTTP Client +const ( + // HTTPResendCountKey is the attribute Key conforming to the + // "http.resend_count" semantic conventions. It represents the ordinal + // number of request resending attempt (for any reason, including + // redirects). + // + // Type: int + // RequirementLevel: Recommended (if and only if request was retried.) + // Stability: stable + // Examples: 3 + // Note: The resend count SHOULD be updated each time an HTTP request gets + // resent by the client, regardless of what was the cause of the resending + // (e.g. redirection, authorization failure, 503 Server Unavailable, + // network issues, or any other). + HTTPResendCountKey = attribute.Key("http.resend_count") +) + +// HTTPResendCount returns an attribute KeyValue conforming to the +// "http.resend_count" semantic conventions. It represents the ordinal number +// of request resending attempt (for any reason, including redirects). +func HTTPResendCount(val int) attribute.KeyValue { + return HTTPResendCountKey.Int(val) +} + +// The `aws` conventions apply to operations using the AWS SDK. They map +// request or response parameters in AWS SDK API calls to attributes on a Span. +// The conventions have been collected over time based on feedback from AWS +// users of tracing and will continue to evolve as new interesting conventions +// are found. +// Some descriptions are also provided for populating general OpenTelemetry +// semantic conventions based on these APIs. +const ( + // AWSRequestIDKey is the attribute Key conforming to the "aws.request_id" + // semantic conventions. It represents the AWS request ID as returned in + // the response headers `x-amz-request-id` or `x-amz-requestid`. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '79b9da39-b7ae-508a-a6bc-864b2829c622', 'C9ER4AJX75574TDJ' + AWSRequestIDKey = attribute.Key("aws.request_id") +) + +// AWSRequestID returns an attribute KeyValue conforming to the +// "aws.request_id" semantic conventions. It represents the AWS request ID as +// returned in the response headers `x-amz-request-id` or `x-amz-requestid`. +func AWSRequestID(val string) attribute.KeyValue { + return AWSRequestIDKey.String(val) +} + +// Attributes that exist for multiple DynamoDB request types. +const ( + // AWSDynamoDBTableNamesKey is the attribute Key conforming to the + // "aws.dynamodb.table_names" semantic conventions. It represents the keys + // in the `RequestItems` object field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Users', 'Cats' + AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names") + + // AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the + // "aws.dynamodb.consumed_capacity" semantic conventions. It represents the + // JSON-serialized value of each item in the `ConsumedCapacity` response + // field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": { + // "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : + // { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": + // { "CapacityUnits": number, "ReadCapacityUnits": number, + // "WriteCapacityUnits": number }, "TableName": "string", + // "WriteCapacityUnits": number }' + AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity") + + // AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to + // the "aws.dynamodb.item_collection_metrics" semantic conventions. It + // represents the JSON-serialized value of the `ItemCollectionMetrics` + // response field. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B": + // blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { + // "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], + // "NULL": boolean, "S": "string", "SS": [ "string" ] } }, + // "SizeEstimateRangeGB": [ number ] } ] }' + AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics") + + // AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to + // the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It + // represents the value of the `ProvisionedThroughput.ReadCapacityUnits` + // request parameter. + // + // Type: double + // RequirementLevel: Optional + // Stability: stable + // Examples: 1.0, 2.0 + AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity") + + // AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming + // to the "aws.dynamodb.provisioned_write_capacity" semantic conventions. + // It represents the value of the + // `ProvisionedThroughput.WriteCapacityUnits` request parameter. + // + // Type: double + // RequirementLevel: Optional + // Stability: stable + // Examples: 1.0, 2.0 + AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity") + + // AWSDynamoDBConsistentReadKey is the attribute Key conforming to the + // "aws.dynamodb.consistent_read" semantic conventions. It represents the + // value of the `ConsistentRead` request parameter. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read") + + // AWSDynamoDBProjectionKey is the attribute Key conforming to the + // "aws.dynamodb.projection" semantic conventions. It represents the value + // of the `ProjectionExpression` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Title', 'Title, Price, Color', 'Title, Description, + // RelatedItems, ProductReviews' + AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection") + + // AWSDynamoDBLimitKey is the attribute Key conforming to the + // "aws.dynamodb.limit" semantic conventions. It represents the value of + // the `Limit` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit") + + // AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the + // "aws.dynamodb.attributes_to_get" semantic conventions. It represents the + // value of the `AttributesToGet` request parameter. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: 'lives', 'id' + AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get") + + // AWSDynamoDBIndexNameKey is the attribute Key conforming to the + // "aws.dynamodb.index_name" semantic conventions. It represents the value + // of the `IndexName` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'name_to_group' + AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name") + + // AWSDynamoDBSelectKey is the attribute Key conforming to the + // "aws.dynamodb.select" semantic conventions. It represents the value of + // the `Select` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'ALL_ATTRIBUTES', 'COUNT' + AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select") +) + +// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the +// "aws.dynamodb.table_names" semantic conventions. It represents the keys in +// the `RequestItems` object field. +func AWSDynamoDBTableNames(val ...string) attribute.KeyValue { + return AWSDynamoDBTableNamesKey.StringSlice(val) +} + +// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to +// the "aws.dynamodb.consumed_capacity" semantic conventions. It represents the +// JSON-serialized value of each item in the `ConsumedCapacity` response field. +func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue { + return AWSDynamoDBConsumedCapacityKey.StringSlice(val) +} + +// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming +// to the "aws.dynamodb.item_collection_metrics" semantic conventions. It +// represents the JSON-serialized value of the `ItemCollectionMetrics` response +// field. +func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue { + return AWSDynamoDBItemCollectionMetricsKey.String(val) +} + +// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue +// conforming to the "aws.dynamodb.provisioned_read_capacity" semantic +// conventions. It represents the value of the +// `ProvisionedThroughput.ReadCapacityUnits` request parameter. +func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue { + return AWSDynamoDBProvisionedReadCapacityKey.Float64(val) +} + +// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue +// conforming to the "aws.dynamodb.provisioned_write_capacity" semantic +// conventions. It represents the value of the +// `ProvisionedThroughput.WriteCapacityUnits` request parameter. +func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue { + return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val) +} + +// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the +// "aws.dynamodb.consistent_read" semantic conventions. It represents the value +// of the `ConsistentRead` request parameter. +func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue { + return AWSDynamoDBConsistentReadKey.Bool(val) +} + +// AWSDynamoDBProjection returns an attribute KeyValue conforming to the +// "aws.dynamodb.projection" semantic conventions. It represents the value of +// the `ProjectionExpression` request parameter. +func AWSDynamoDBProjection(val string) attribute.KeyValue { + return AWSDynamoDBProjectionKey.String(val) +} + +// AWSDynamoDBLimit returns an attribute KeyValue conforming to the +// "aws.dynamodb.limit" semantic conventions. It represents the value of the +// `Limit` request parameter. +func AWSDynamoDBLimit(val int) attribute.KeyValue { + return AWSDynamoDBLimitKey.Int(val) +} + +// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to +// the "aws.dynamodb.attributes_to_get" semantic conventions. It represents the +// value of the `AttributesToGet` request parameter. +func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue { + return AWSDynamoDBAttributesToGetKey.StringSlice(val) +} + +// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the +// "aws.dynamodb.index_name" semantic conventions. It represents the value of +// the `IndexName` request parameter. +func AWSDynamoDBIndexName(val string) attribute.KeyValue { + return AWSDynamoDBIndexNameKey.String(val) +} + +// AWSDynamoDBSelect returns an attribute KeyValue conforming to the +// "aws.dynamodb.select" semantic conventions. It represents the value of the +// `Select` request parameter. +func AWSDynamoDBSelect(val string) attribute.KeyValue { + return AWSDynamoDBSelectKey.String(val) +} + +// DynamoDB.CreateTable +const ( + // AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to + // the "aws.dynamodb.global_secondary_indexes" semantic conventions. It + // represents the JSON-serialized value of each item of the + // `GlobalSecondaryIndexes` request field + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName": + // "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ + // "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { + // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }' + AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes") + + // AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to + // the "aws.dynamodb.local_secondary_indexes" semantic conventions. It + // represents the JSON-serialized value of each item of the + // `LocalSecondaryIndexes` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "IndexARN": "string", "IndexName": "string", + // "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { + // "AttributeName": "string", "KeyType": "string" } ], "Projection": { + // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }' + AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes") +) + +// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue +// conforming to the "aws.dynamodb.global_secondary_indexes" semantic +// conventions. It represents the JSON-serialized value of each item of the +// `GlobalSecondaryIndexes` request field +func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue { + return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val) +} + +// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming +// to the "aws.dynamodb.local_secondary_indexes" semantic conventions. It +// represents the JSON-serialized value of each item of the +// `LocalSecondaryIndexes` request field. +func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue { + return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val) +} + +// DynamoDB.ListTables +const ( + // AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the + // "aws.dynamodb.exclusive_start_table" semantic conventions. It represents + // the value of the `ExclusiveStartTableName` request parameter. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Users', 'CatsTable' + AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table") + + // AWSDynamoDBTableCountKey is the attribute Key conforming to the + // "aws.dynamodb.table_count" semantic conventions. It represents the the + // number of items in the `TableNames` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 20 + AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count") +) + +// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming +// to the "aws.dynamodb.exclusive_start_table" semantic conventions. It +// represents the value of the `ExclusiveStartTableName` request parameter. +func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue { + return AWSDynamoDBExclusiveStartTableKey.String(val) +} + +// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.table_count" semantic conventions. It represents the the +// number of items in the `TableNames` response parameter. +func AWSDynamoDBTableCount(val int) attribute.KeyValue { + return AWSDynamoDBTableCountKey.Int(val) +} + +// DynamoDB.Query +const ( + // AWSDynamoDBScanForwardKey is the attribute Key conforming to the + // "aws.dynamodb.scan_forward" semantic conventions. It represents the + // value of the `ScanIndexForward` request parameter. + // + // Type: boolean + // RequirementLevel: Optional + // Stability: stable + AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward") +) + +// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the +// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of +// the `ScanIndexForward` request parameter. +func AWSDynamoDBScanForward(val bool) attribute.KeyValue { + return AWSDynamoDBScanForwardKey.Bool(val) +} + +// DynamoDB.Scan +const ( + // AWSDynamoDBSegmentKey is the attribute Key conforming to the + // "aws.dynamodb.segment" semantic conventions. It represents the value of + // the `Segment` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment") + + // AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the + // "aws.dynamodb.total_segments" semantic conventions. It represents the + // value of the `TotalSegments` request parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 100 + AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments") + + // AWSDynamoDBCountKey is the attribute Key conforming to the + // "aws.dynamodb.count" semantic conventions. It represents the value of + // the `Count` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 10 + AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count") + + // AWSDynamoDBScannedCountKey is the attribute Key conforming to the + // "aws.dynamodb.scanned_count" semantic conventions. It represents the + // value of the `ScannedCount` response parameter. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 50 + AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count") +) + +// AWSDynamoDBSegment returns an attribute KeyValue conforming to the +// "aws.dynamodb.segment" semantic conventions. It represents the value of the +// `Segment` request parameter. +func AWSDynamoDBSegment(val int) attribute.KeyValue { + return AWSDynamoDBSegmentKey.Int(val) +} + +// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the +// "aws.dynamodb.total_segments" semantic conventions. It represents the value +// of the `TotalSegments` request parameter. +func AWSDynamoDBTotalSegments(val int) attribute.KeyValue { + return AWSDynamoDBTotalSegmentsKey.Int(val) +} + +// AWSDynamoDBCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.count" semantic conventions. It represents the value of the +// `Count` response parameter. +func AWSDynamoDBCount(val int) attribute.KeyValue { + return AWSDynamoDBCountKey.Int(val) +} + +// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the +// "aws.dynamodb.scanned_count" semantic conventions. It represents the value +// of the `ScannedCount` response parameter. +func AWSDynamoDBScannedCount(val int) attribute.KeyValue { + return AWSDynamoDBScannedCountKey.Int(val) +} + +// DynamoDB.UpdateTable +const ( + // AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to + // the "aws.dynamodb.attribute_definitions" semantic conventions. It + // represents the JSON-serialized value of each item in the + // `AttributeDefinitions` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "AttributeName": "string", "AttributeType": "string" }' + AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions") + + // AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key + // conforming to the "aws.dynamodb.global_secondary_index_updates" semantic + // conventions. It represents the JSON-serialized value of each item in the + // the `GlobalSecondaryIndexUpdates` request field. + // + // Type: string[] + // RequirementLevel: Optional + // Stability: stable + // Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ { + // "AttributeName": "string", "KeyType": "string" } ], "Projection": { + // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, + // "ProvisionedThroughput": { "ReadCapacityUnits": number, + // "WriteCapacityUnits": number } }' + AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates") +) + +// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming +// to the "aws.dynamodb.attribute_definitions" semantic conventions. It +// represents the JSON-serialized value of each item in the +// `AttributeDefinitions` request field. +func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue { + return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val) +} + +// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue +// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic +// conventions. It represents the JSON-serialized value of each item in the the +// `GlobalSecondaryIndexUpdates` request field. +func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue { + return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val) +} + +// Attributes that exist for S3 request types. +const ( + // AWSS3BucketKey is the attribute Key conforming to the "aws.s3.bucket" + // semantic conventions. It represents the S3 bucket name the request + // refers to. Corresponds to the `--bucket` parameter of the [S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) + // operations. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'some-bucket-name' + // Note: The `bucket` attribute is applicable to all S3 operations that + // reference a bucket, i.e. that require the bucket name as a mandatory + // parameter. + // This applies to almost all S3 operations except `list-buckets`. + AWSS3BucketKey = attribute.Key("aws.s3.bucket") + + // AWSS3KeyKey is the attribute Key conforming to the "aws.s3.key" semantic + // conventions. It represents the S3 object key the request refers to. + // Corresponds to the `--key` parameter of the [S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) + // operations. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'someFile.yml' + // Note: The `key` attribute is applicable to all object-related S3 + // operations, i.e. that require the object key as a mandatory parameter. + // This applies in particular to the following operations: + // + // - + // [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + // - + // [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) + // - + // [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) + // - + // [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) + // - + // [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) + // - + // [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) + // - + // [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) + // - + // [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + // - + // [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + // - + // [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) + // - + // [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + // - + // [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + // - + // [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + AWSS3KeyKey = attribute.Key("aws.s3.key") + + // AWSS3CopySourceKey is the attribute Key conforming to the + // "aws.s3.copy_source" semantic conventions. It represents the source + // object (in the form `bucket`/`key`) for the copy operation. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'someFile.yml' + // Note: The `copy_source` attribute applies to S3 copy operations and + // corresponds to the `--copy-source` parameter + // of the [copy-object operation within the S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). + // This applies in particular to the following operations: + // + // - + // [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + // - + // [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + AWSS3CopySourceKey = attribute.Key("aws.s3.copy_source") + + // AWSS3UploadIDKey is the attribute Key conforming to the + // "aws.s3.upload_id" semantic conventions. It represents the upload ID + // that identifies the multipart upload. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ' + // Note: The `upload_id` attribute applies to S3 multipart-upload + // operations and corresponds to the `--upload-id` parameter + // of the [S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) + // multipart operations. + // This applies in particular to the following operations: + // + // - + // [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + // - + // [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + // - + // [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + // - + // [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + // - + // [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + AWSS3UploadIDKey = attribute.Key("aws.s3.upload_id") + + // AWSS3DeleteKey is the attribute Key conforming to the "aws.s3.delete" + // semantic conventions. It represents the delete request container that + // specifies the objects to be deleted. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: + // 'Objects=[{Key=string,VersionID=string},{Key=string,VersionID=string}],Quiet=boolean' + // Note: The `delete` attribute is only applicable to the + // [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) + // operation. + // The `delete` attribute corresponds to the `--delete` parameter of the + // [delete-objects operation within the S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). + AWSS3DeleteKey = attribute.Key("aws.s3.delete") + + // AWSS3PartNumberKey is the attribute Key conforming to the + // "aws.s3.part_number" semantic conventions. It represents the part number + // of the part being uploaded in a multipart-upload operation. This is a + // positive integer between 1 and 10,000. + // + // Type: int + // RequirementLevel: Optional + // Stability: stable + // Examples: 3456 + // Note: The `part_number` attribute is only applicable to the + // [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + // and + // [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + // operations. + // The `part_number` attribute corresponds to the `--part-number` parameter + // of the + // [upload-part operation within the S3 + // API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). + AWSS3PartNumberKey = attribute.Key("aws.s3.part_number") +) + +// AWSS3Bucket returns an attribute KeyValue conforming to the +// "aws.s3.bucket" semantic conventions. It represents the S3 bucket name the +// request refers to. Corresponds to the `--bucket` parameter of the [S3 +// API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) +// operations. +func AWSS3Bucket(val string) attribute.KeyValue { + return AWSS3BucketKey.String(val) +} + +// AWSS3Key returns an attribute KeyValue conforming to the "aws.s3.key" +// semantic conventions. It represents the S3 object key the request refers to. +// Corresponds to the `--key` parameter of the [S3 +// API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) +// operations. +func AWSS3Key(val string) attribute.KeyValue { + return AWSS3KeyKey.String(val) +} + +// AWSS3CopySource returns an attribute KeyValue conforming to the +// "aws.s3.copy_source" semantic conventions. It represents the source object +// (in the form `bucket`/`key`) for the copy operation. +func AWSS3CopySource(val string) attribute.KeyValue { + return AWSS3CopySourceKey.String(val) +} + +// AWSS3UploadID returns an attribute KeyValue conforming to the +// "aws.s3.upload_id" semantic conventions. It represents the upload ID that +// identifies the multipart upload. +func AWSS3UploadID(val string) attribute.KeyValue { + return AWSS3UploadIDKey.String(val) +} + +// AWSS3Delete returns an attribute KeyValue conforming to the +// "aws.s3.delete" semantic conventions. It represents the delete request +// container that specifies the objects to be deleted. +func AWSS3Delete(val string) attribute.KeyValue { + return AWSS3DeleteKey.String(val) +} + +// AWSS3PartNumber returns an attribute KeyValue conforming to the +// "aws.s3.part_number" semantic conventions. It represents the part number of +// the part being uploaded in a multipart-upload operation. This is a positive +// integer between 1 and 10,000. +func AWSS3PartNumber(val int) attribute.KeyValue { + return AWSS3PartNumberKey.Int(val) +} + +// Semantic conventions to apply when instrumenting the GraphQL implementation. +// They map GraphQL operations to attributes on a Span. +const ( + // GraphqlOperationNameKey is the attribute Key conforming to the + // "graphql.operation.name" semantic conventions. It represents the name of + // the operation being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'findBookByID' + GraphqlOperationNameKey = attribute.Key("graphql.operation.name") + + // GraphqlOperationTypeKey is the attribute Key conforming to the + // "graphql.operation.type" semantic conventions. It represents the type of + // the operation being executed. + // + // Type: Enum + // RequirementLevel: Optional + // Stability: stable + // Examples: 'query', 'mutation', 'subscription' + GraphqlOperationTypeKey = attribute.Key("graphql.operation.type") + + // GraphqlDocumentKey is the attribute Key conforming to the + // "graphql.document" semantic conventions. It represents the GraphQL + // document being executed. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'query findBookByID { bookByID(id: ?) { name } }' + // Note: The value may be sanitized to exclude sensitive information. + GraphqlDocumentKey = attribute.Key("graphql.document") +) + +var ( + // GraphQL query + GraphqlOperationTypeQuery = GraphqlOperationTypeKey.String("query") + // GraphQL mutation + GraphqlOperationTypeMutation = GraphqlOperationTypeKey.String("mutation") + // GraphQL subscription + GraphqlOperationTypeSubscription = GraphqlOperationTypeKey.String("subscription") +) + +// GraphqlOperationName returns an attribute KeyValue conforming to the +// "graphql.operation.name" semantic conventions. It represents the name of the +// operation being executed. +func GraphqlOperationName(val string) attribute.KeyValue { + return GraphqlOperationNameKey.String(val) +} + +// GraphqlDocument returns an attribute KeyValue conforming to the +// "graphql.document" semantic conventions. It represents the GraphQL document +// being executed. +func GraphqlDocument(val string) attribute.KeyValue { + return GraphqlDocumentKey.String(val) +} + +// General attributes used in messaging systems. +const ( + // MessagingSystemKey is the attribute Key conforming to the + // "messaging.system" semantic conventions. It represents a string + // identifying the messaging system. + // + // Type: string + // RequirementLevel: Required + // Stability: stable + // Examples: 'kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS' + MessagingSystemKey = attribute.Key("messaging.system") + + // MessagingOperationKey is the attribute Key conforming to the + // "messaging.operation" semantic conventions. It represents a string + // identifying the kind of messaging operation as defined in the [Operation + // names](#operation-names) section above. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + // Note: If a custom value is used, it MUST be of low cardinality. + MessagingOperationKey = attribute.Key("messaging.operation") + + // MessagingBatchMessageCountKey is the attribute Key conforming to the + // "messaging.batch.message_count" semantic conventions. It represents the + // number of messages sent, received, or processed in the scope of the + // batching operation. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If the span describes an + // operation on a batch of messages.) + // Stability: stable + // Examples: 0, 1, 2 + // Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on + // spans that operate with a single message. When a messaging client + // library supports both batch and single-message API for the same + // operation, instrumentations SHOULD use `messaging.batch.message_count` + // for batching APIs and SHOULD NOT use it for single-message APIs. + MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count") + + // MessagingClientIDKey is the attribute Key conforming to the + // "messaging.client_id" semantic conventions. It represents a unique + // identifier for the client that consumes or produces a message. + // + // Type: string + // RequirementLevel: Recommended (If a client id is available) + // Stability: stable + // Examples: 'client-5', 'myhost@8742@s8083jm' + MessagingClientIDKey = attribute.Key("messaging.client_id") +) + +var ( + // publish + MessagingOperationPublish = MessagingOperationKey.String("publish") + // receive + MessagingOperationReceive = MessagingOperationKey.String("receive") + // process + MessagingOperationProcess = MessagingOperationKey.String("process") +) + +// MessagingSystem returns an attribute KeyValue conforming to the +// "messaging.system" semantic conventions. It represents a string identifying +// the messaging system. +func MessagingSystem(val string) attribute.KeyValue { + return MessagingSystemKey.String(val) +} + +// MessagingBatchMessageCount returns an attribute KeyValue conforming to +// the "messaging.batch.message_count" semantic conventions. It represents the +// number of messages sent, received, or processed in the scope of the batching +// operation. +func MessagingBatchMessageCount(val int) attribute.KeyValue { + return MessagingBatchMessageCountKey.Int(val) +} + +// MessagingClientID returns an attribute KeyValue conforming to the +// "messaging.client_id" semantic conventions. It represents a unique +// identifier for the client that consumes or produces a message. +func MessagingClientID(val string) attribute.KeyValue { + return MessagingClientIDKey.String(val) +} + +// Semantic conventions for remote procedure calls. +const ( + // RPCSystemKey is the attribute Key conforming to the "rpc.system" + // semantic conventions. It represents a string identifying the remoting + // system. See below for a list of well-known identifiers. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + RPCSystemKey = attribute.Key("rpc.system") + + // RPCServiceKey is the attribute Key conforming to the "rpc.service" + // semantic conventions. It represents the full (logical) name of the + // service being called, including its package name, if applicable. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'myservice.EchoService' + // Note: This is the logical name of the service from the RPC interface + // perspective, which can be different from the name of any implementing + // class. The `code.namespace` attribute may be used to store the latter + // (despite the attribute name, it may include a class name; e.g., class + // with method actually executing the call on the server side, RPC client + // stub class on the client side). + RPCServiceKey = attribute.Key("rpc.service") + + // RPCMethodKey is the attribute Key conforming to the "rpc.method" + // semantic conventions. It represents the name of the (logical) method + // being called, must be equal to the $method part in the span name. + // + // Type: string + // RequirementLevel: Recommended + // Stability: stable + // Examples: 'exampleMethod' + // Note: This is the logical name of the method from the RPC interface + // perspective, which can be different from the name of any implementing + // method/function. The `code.function` attribute may be used to store the + // latter (e.g., method actually executing the call on the server side, RPC + // client stub method on the client side). + RPCMethodKey = attribute.Key("rpc.method") +) + +var ( + // gRPC + RPCSystemGRPC = RPCSystemKey.String("grpc") + // Java RMI + RPCSystemJavaRmi = RPCSystemKey.String("java_rmi") + // .NET WCF + RPCSystemDotnetWcf = RPCSystemKey.String("dotnet_wcf") + // Apache Dubbo + RPCSystemApacheDubbo = RPCSystemKey.String("apache_dubbo") + // Connect RPC + RPCSystemConnectRPC = RPCSystemKey.String("connect_rpc") +) + +// RPCService returns an attribute KeyValue conforming to the "rpc.service" +// semantic conventions. It represents the full (logical) name of the service +// being called, including its package name, if applicable. +func RPCService(val string) attribute.KeyValue { + return RPCServiceKey.String(val) +} + +// RPCMethod returns an attribute KeyValue conforming to the "rpc.method" +// semantic conventions. It represents the name of the (logical) method being +// called, must be equal to the $method part in the span name. +func RPCMethod(val string) attribute.KeyValue { + return RPCMethodKey.String(val) +} + +// Tech-specific attributes for gRPC. +const ( + // RPCGRPCStatusCodeKey is the attribute Key conforming to the + // "rpc.grpc.status_code" semantic conventions. It represents the [numeric + // status + // code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of + // the gRPC request. + // + // Type: Enum + // RequirementLevel: Required + // Stability: stable + RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code") +) + +var ( + // OK + RPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0) + // CANCELLED + RPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1) + // UNKNOWN + RPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2) + // INVALID_ARGUMENT + RPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3) + // DEADLINE_EXCEEDED + RPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4) + // NOT_FOUND + RPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5) + // ALREADY_EXISTS + RPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6) + // PERMISSION_DENIED + RPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7) + // RESOURCE_EXHAUSTED + RPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8) + // FAILED_PRECONDITION + RPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9) + // ABORTED + RPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10) + // OUT_OF_RANGE + RPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11) + // UNIMPLEMENTED + RPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12) + // INTERNAL + RPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13) + // UNAVAILABLE + RPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14) + // DATA_LOSS + RPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15) + // UNAUTHENTICATED + RPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16) +) + +// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/). +const ( + // RPCJsonrpcVersionKey is the attribute Key conforming to the + // "rpc.jsonrpc.version" semantic conventions. It represents the protocol + // version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 + // does not specify this, the value can be omitted. + // + // Type: string + // RequirementLevel: ConditionallyRequired (If other than the default + // version (`1.0`)) + // Stability: stable + // Examples: '2.0', '1.0' + RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version") + + // RPCJsonrpcRequestIDKey is the attribute Key conforming to the + // "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` + // property of request or response. Since protocol allows id to be int, + // string, `null` or missing (for notifications), value is expected to be + // cast to string for simplicity. Use empty string in case of `null` value. + // Omit entirely if this is a notification. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: '10', 'request-7', '' + RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id") + + // RPCJsonrpcErrorCodeKey is the attribute Key conforming to the + // "rpc.jsonrpc.error_code" semantic conventions. It represents the + // `error.code` property of response if it is an error response. + // + // Type: int + // RequirementLevel: ConditionallyRequired (If response is not successful.) + // Stability: stable + // Examples: -32700, 100 + RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code") + + // RPCJsonrpcErrorMessageKey is the attribute Key conforming to the + // "rpc.jsonrpc.error_message" semantic conventions. It represents the + // `error.message` property of response if it is an error response. + // + // Type: string + // RequirementLevel: Optional + // Stability: stable + // Examples: 'Parse error', 'User already exists' + RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message") +) + +// RPCJsonrpcVersion returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.version" semantic conventions. It represents the protocol +// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 +// does not specify this, the value can be omitted. +func RPCJsonrpcVersion(val string) attribute.KeyValue { + return RPCJsonrpcVersionKey.String(val) +} + +// RPCJsonrpcRequestID returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` +// property of request or response. Since protocol allows id to be int, string, +// `null` or missing (for notifications), value is expected to be cast to +// string for simplicity. Use empty string in case of `null` value. Omit +// entirely if this is a notification. +func RPCJsonrpcRequestID(val string) attribute.KeyValue { + return RPCJsonrpcRequestIDKey.String(val) +} + +// RPCJsonrpcErrorCode returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.error_code" semantic conventions. It represents the +// `error.code` property of response if it is an error response. +func RPCJsonrpcErrorCode(val int) attribute.KeyValue { + return RPCJsonrpcErrorCodeKey.Int(val) +} + +// RPCJsonrpcErrorMessage returns an attribute KeyValue conforming to the +// "rpc.jsonrpc.error_message" semantic conventions. It represents the +// `error.message` property of response if it is an error response. +func RPCJsonrpcErrorMessage(val string) attribute.KeyValue { + return RPCJsonrpcErrorMessageKey.String(val) +} + +// Tech-specific attributes for Connect RPC. +const ( + // RPCConnectRPCErrorCodeKey is the attribute Key conforming to the + // "rpc.connect_rpc.error_code" semantic conventions. It represents the + // [error codes](https://connect.build/docs/protocol/#error-codes) of the + // Connect request. Error codes are always string values. + // + // Type: Enum + // RequirementLevel: ConditionallyRequired (If response is not successful + // and if error code available.) + // Stability: stable + RPCConnectRPCErrorCodeKey = attribute.Key("rpc.connect_rpc.error_code") +) + +var ( + // cancelled + RPCConnectRPCErrorCodeCancelled = RPCConnectRPCErrorCodeKey.String("cancelled") + // unknown + RPCConnectRPCErrorCodeUnknown = RPCConnectRPCErrorCodeKey.String("unknown") + // invalid_argument + RPCConnectRPCErrorCodeInvalidArgument = RPCConnectRPCErrorCodeKey.String("invalid_argument") + // deadline_exceeded + RPCConnectRPCErrorCodeDeadlineExceeded = RPCConnectRPCErrorCodeKey.String("deadline_exceeded") + // not_found + RPCConnectRPCErrorCodeNotFound = RPCConnectRPCErrorCodeKey.String("not_found") + // already_exists + RPCConnectRPCErrorCodeAlreadyExists = RPCConnectRPCErrorCodeKey.String("already_exists") + // permission_denied + RPCConnectRPCErrorCodePermissionDenied = RPCConnectRPCErrorCodeKey.String("permission_denied") + // resource_exhausted + RPCConnectRPCErrorCodeResourceExhausted = RPCConnectRPCErrorCodeKey.String("resource_exhausted") + // failed_precondition + RPCConnectRPCErrorCodeFailedPrecondition = RPCConnectRPCErrorCodeKey.String("failed_precondition") + // aborted + RPCConnectRPCErrorCodeAborted = RPCConnectRPCErrorCodeKey.String("aborted") + // out_of_range + RPCConnectRPCErrorCodeOutOfRange = RPCConnectRPCErrorCodeKey.String("out_of_range") + // unimplemented + RPCConnectRPCErrorCodeUnimplemented = RPCConnectRPCErrorCodeKey.String("unimplemented") + // internal + RPCConnectRPCErrorCodeInternal = RPCConnectRPCErrorCodeKey.String("internal") + // unavailable + RPCConnectRPCErrorCodeUnavailable = RPCConnectRPCErrorCodeKey.String("unavailable") + // data_loss + RPCConnectRPCErrorCodeDataLoss = RPCConnectRPCErrorCodeKey.String("data_loss") + // unauthenticated + RPCConnectRPCErrorCodeUnauthenticated = RPCConnectRPCErrorCodeKey.String("unauthenticated") +) diff --git a/vendor/go.opentelemetry.io/otel/tag.sh b/vendor/go.opentelemetry.io/otel/tag.sh deleted file mode 100644 index 70767c70377..00000000000 --- a/vendor/go.opentelemetry.io/otel/tag.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash - -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly PROGNAME=$(basename "$0") -readonly PROGDIR=$(readlink -m "$(dirname "$0")") - -readonly EXCLUDE_PACKAGES="internal/tools" -readonly SEMVER_REGEX="v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?" - -usage() { - cat <<- EOF -Usage: $PROGNAME [OPTIONS] SEMVER_TAG COMMIT_HASH - -Creates git tag for all Go packages in project. - -OPTIONS: - -h --help Show this help. - -ARGUMENTS: - SEMVER_TAG Semantic version to tag with. - COMMIT_HASH Git commit hash to tag. -EOF -} - -cmdline() { - local arg commit - - for arg - do - local delim="" - case "$arg" in - # Translate long form options to short form. - --help) args="${args}-h ";; - # Pass through for everything else. - *) [[ "${arg:0:1}" == "-" ]] || delim="\"" - args="${args}${delim}${arg}${delim} ";; - esac - done - - # Reset and process short form options. - eval set -- "$args" - - while getopts "h" OPTION - do - case $OPTION in - h) - usage - exit 0 - ;; - *) - echo "unknown option: $OPTION" - usage - exit 1 - ;; - esac - done - - # Positional arguments. - shift $((OPTIND-1)) - readonly TAG="$1" - if [ -z "$TAG" ] - then - echo "missing SEMVER_TAG" - usage - exit 1 - fi - if [[ ! "$TAG" =~ $SEMVER_REGEX ]] - then - printf "invalid semantic version: %s\n" "$TAG" - exit 2 - fi - if [[ "$( git tag --list "$TAG" )" ]] - then - printf "tag already exists: %s\n" "$TAG" - exit 2 - fi - - shift - commit="$1" - if [ -z "$commit" ] - then - echo "missing COMMIT_HASH" - usage - exit 1 - fi - # Verify rev is for a commit and unify hashes into a complete SHA1. - readonly SHA="$( git rev-parse --quiet --verify "${commit}^{commit}" )" - if [ -z "$SHA" ] - then - printf "invalid commit hash: %s\n" "$commit" - exit 2 - fi - if [ "$( git merge-base "$SHA" HEAD )" != "$SHA" ] - then - printf "commit '%s' not found on this branch\n" "$commit" - exit 2 - fi -} - -package_dirs() { - # Return a list of package directories in the form: - # - # package/directory/a - # package/directory/b - # deeper/package/directory/a - # ... - # - # Making sure to exclude any packages in the EXCLUDE_PACKAGES regexp. - find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ - | grep -E -v "$EXCLUDE_PACKAGES" \ - | sed 's/^\.\///' \ - | sort -} - -git_tag() { - local tag="$1" - local commit="$2" - - git tag -a "$tag" -s -m "Version $tag" "$commit" -} - -previous_version() { - local current="$1" - - # Requires git > 2.0 - git tag -l --sort=v:refname \ - | grep -E "^${SEMVER_REGEX}$" \ - | grep -v "$current" \ - | tail -1 -} - -print_changes() { - local tag="$1" - local previous - - previous="$( previous_version "$tag" )" - if [ -n "$previous" ] - then - printf "\nRaw changes made between %s and %s\n" "$previous" "$tag" - printf "======================================\n" - git --no-pager log --pretty=oneline "${previous}..$tag" - fi -} - -main() { - local dir - - cmdline "$@" - - cd "$PROGDIR" || exit 3 - - # Create tag for root package. - git_tag "$TAG" "$SHA" - printf "created tag: %s\n" "$TAG" - - # Create tag for all sub-packages. - for dir in $( package_dirs ) - do - git_tag "${dir}/$TAG" "$SHA" - printf "created tag: %s\n" "${dir}/$TAG" - done - - print_changes "$TAG" -} -main "$@" diff --git a/vendor/go.opentelemetry.io/otel/trace.go b/vendor/go.opentelemetry.io/otel/trace.go index 1d5ffb8ea57..caf7249de85 100644 --- a/vendor/go.opentelemetry.io/otel/trace.go +++ b/vendor/go.opentelemetry.io/otel/trace.go @@ -22,18 +22,21 @@ import ( // Tracer creates a named tracer that implements Tracer interface. // If the name is an empty string then provider uses default name. // -// This is short for GetTracerProvider().Tracer(name) -func Tracer(name string) trace.Tracer { - return GetTracerProvider().Tracer(name) +// This is short for GetTracerProvider().Tracer(name, opts...) +func Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + return GetTracerProvider().Tracer(name, opts...) } // GetTracerProvider returns the registered global trace provider. // If none is registered then an instance of NoopTracerProvider is returned. // // Use the trace provider to create a named tracer. E.g. -// tracer := global.GetTracerProvider().Tracer("example.com/foo") +// +// tracer := otel.GetTracerProvider().Tracer("example.com/foo") +// // or -// tracer := global.Tracer("example.com/foo") +// +// tracer := otel.Tracer("example.com/foo") func GetTracerProvider() trace.TracerProvider { return global.TracerProvider() } diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go index ea30ee35f15..cb3efbb9ad8 100644 --- a/vendor/go.opentelemetry.io/otel/trace/config.go +++ b/vendor/go.opentelemetry.io/otel/trace/config.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package trace +package trace // import "go.opentelemetry.io/otel/trace" import ( "time" @@ -22,109 +22,205 @@ import ( // TracerConfig is a group of options for a Tracer. type TracerConfig struct { - // InstrumentationVersion is the version of the library providing - // instrumentation. - InstrumentationVersion string + instrumentationVersion string + // Schema URL of the telemetry emitted by the Tracer. + schemaURL string + attrs attribute.Set +} + +// InstrumentationVersion returns the version of the library providing instrumentation. +func (t *TracerConfig) InstrumentationVersion() string { + return t.instrumentationVersion +} + +// InstrumentationAttributes returns the attributes associated with the library +// providing instrumentation. +func (t *TracerConfig) InstrumentationAttributes() attribute.Set { + return t.attrs +} + +// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer. +func (t *TracerConfig) SchemaURL() string { + return t.schemaURL } // NewTracerConfig applies all the options to a returned TracerConfig. -func NewTracerConfig(options ...TracerOption) *TracerConfig { - config := new(TracerConfig) +func NewTracerConfig(options ...TracerOption) TracerConfig { + var config TracerConfig for _, option := range options { - option.ApplyTracer(config) + config = option.apply(config) } return config } // TracerOption applies an option to a TracerConfig. type TracerOption interface { - ApplyTracer(*TracerConfig) + apply(TracerConfig) TracerConfig +} + +type tracerOptionFunc func(TracerConfig) TracerConfig - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() +func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig { + return fn(cfg) } // SpanConfig is a group of options for a Span. type SpanConfig struct { - // Attributes describe the associated qualities of a Span. - Attributes []attribute.KeyValue - // Timestamp is a time in a Span life-cycle. - Timestamp time.Time - // Links are the associations a Span has with other Spans. - Links []Link - // NewRoot identifies a Span as the root Span for a new trace. This is - // commonly used when an existing trace crosses trust boundaries and the - // remote parent span context should be ignored for security. - NewRoot bool - // SpanKind is the role a Span has in a trace. - SpanKind SpanKind -} - -// NewSpanConfig applies all the options to a returned SpanConfig. + attributes []attribute.KeyValue + timestamp time.Time + links []Link + newRoot bool + spanKind SpanKind + stackTrace bool +} + +// Attributes describe the associated qualities of a Span. +func (cfg *SpanConfig) Attributes() []attribute.KeyValue { + return cfg.attributes +} + +// Timestamp is a time in a Span life-cycle. +func (cfg *SpanConfig) Timestamp() time.Time { + return cfg.timestamp +} + +// StackTrace checks whether stack trace capturing is enabled. +func (cfg *SpanConfig) StackTrace() bool { + return cfg.stackTrace +} + +// Links are the associations a Span has with other Spans. +func (cfg *SpanConfig) Links() []Link { + return cfg.links +} + +// NewRoot identifies a Span as the root Span for a new trace. This is +// commonly used when an existing trace crosses trust boundaries and the +// remote parent span context should be ignored for security. +func (cfg *SpanConfig) NewRoot() bool { + return cfg.newRoot +} + +// SpanKind is the role a Span has in a trace. +func (cfg *SpanConfig) SpanKind() SpanKind { + return cfg.spanKind +} + +// NewSpanStartConfig applies all the options to a returned SpanConfig. // No validation is performed on the returned SpanConfig (e.g. no uniqueness // checking or bounding of data), it is left to the SDK to perform this // action. -func NewSpanConfig(options ...SpanOption) *SpanConfig { - c := new(SpanConfig) +func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { + var c SpanConfig for _, option := range options { - option.ApplySpan(c) + c = option.applySpanStart(c) } return c } -// SpanOption applies an option to a SpanConfig. -type SpanOption interface { - ApplySpan(*SpanConfig) +// NewSpanEndConfig applies all the options to a returned SpanConfig. +// No validation is performed on the returned SpanConfig (e.g. no uniqueness +// checking or bounding of data), it is left to the SDK to perform this +// action. +func NewSpanEndConfig(options ...SpanEndOption) SpanConfig { + var c SpanConfig + for _, option := range options { + c = option.applySpanEnd(c) + } + return c +} - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() +// SpanStartOption applies an option to a SpanConfig. These options are applicable +// only when the span is created. +type SpanStartOption interface { + applySpanStart(SpanConfig) SpanConfig } -// NewEventConfig applies all the EventOptions to a returned SpanConfig. If no -// timestamp option is passed, the returned SpanConfig will have a Timestamp +type spanOptionFunc func(SpanConfig) SpanConfig + +func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig { + return fn(cfg) +} + +// SpanEndOption applies an option to a SpanConfig. These options are +// applicable only when the span is ended. +type SpanEndOption interface { + applySpanEnd(SpanConfig) SpanConfig +} + +// EventConfig is a group of options for an Event. +type EventConfig struct { + attributes []attribute.KeyValue + timestamp time.Time + stackTrace bool +} + +// Attributes describe the associated qualities of an Event. +func (cfg *EventConfig) Attributes() []attribute.KeyValue { + return cfg.attributes +} + +// Timestamp is a time in an Event life-cycle. +func (cfg *EventConfig) Timestamp() time.Time { + return cfg.timestamp +} + +// StackTrace checks whether stack trace capturing is enabled. +func (cfg *EventConfig) StackTrace() bool { + return cfg.stackTrace +} + +// NewEventConfig applies all the EventOptions to a returned EventConfig. If no +// timestamp option is passed, the returned EventConfig will have a Timestamp // set to the call time, otherwise no validation is performed on the returned -// SpanConfig. -func NewEventConfig(options ...EventOption) *SpanConfig { - c := new(SpanConfig) +// EventConfig. +func NewEventConfig(options ...EventOption) EventConfig { + var c EventConfig for _, option := range options { - option.ApplyEvent(c) + c = option.applyEvent(c) } - if c.Timestamp.IsZero() { - c.Timestamp = time.Now() + if c.timestamp.IsZero() { + c.timestamp = time.Now() } return c } -// EventOption applies span event options to a SpanConfig. +// EventOption applies span event options to an EventConfig. type EventOption interface { - ApplyEvent(*SpanConfig) + applyEvent(EventConfig) EventConfig +} - // A private method to prevent users implementing the - // interface and so future additions to it will not - // violate compatibility. - private() +// SpanOption are options that can be used at both the beginning and end of a span. +type SpanOption interface { + SpanStartOption + SpanEndOption } -// LifeCycleOption applies span life-cycle options to a SpanConfig. These -// options set values releated to events in a spans life-cycle like starting, -// ending, experiencing an error and other user defined notable events. -type LifeCycleOption interface { - SpanOption +// SpanStartEventOption are options that can be used at the start of a span, or with an event. +type SpanStartEventOption interface { + SpanStartOption EventOption } -type attributeSpanOption []attribute.KeyValue +// SpanEndEventOption are options that can be used at the end of a span, or with an event. +type SpanEndEventOption interface { + SpanEndOption + EventOption +} -func (o attributeSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) } -func (o attributeSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) } -func (attributeSpanOption) private() {} -func (o attributeSpanOption) apply(c *SpanConfig) { - c.Attributes = append(c.Attributes, []attribute.KeyValue(o)...) +type attributeOption []attribute.KeyValue + +func (o attributeOption) applySpan(c SpanConfig) SpanConfig { + c.attributes = append(c.attributes, []attribute.KeyValue(o)...) + return c } +func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o attributeOption) applyEvent(c EventConfig) EventConfig { + c.attributes = append(c.attributes, []attribute.KeyValue(o)...) + return c +} + +var _ SpanStartEventOption = attributeOption{} // WithAttributes adds the attributes related to a span life-cycle event. // These attributes are used to describe the work a Span represents when this @@ -135,71 +231,103 @@ func (o attributeSpanOption) apply(c *SpanConfig) { // If multiple of these options are passed the attributes of each successive // option will extend the attributes instead of overwriting. There is no // guarantee of uniqueness in the resulting attributes. -func WithAttributes(attributes ...attribute.KeyValue) LifeCycleOption { - return attributeSpanOption(attributes) +func WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption { + return attributeOption(attributes) } -type timestampSpanOption time.Time +// SpanEventOption are options that can be used with an event or a span. +type SpanEventOption interface { + SpanOption + EventOption +} -func (o timestampSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) } -func (o timestampSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) } -func (timestampSpanOption) private() {} -func (o timestampSpanOption) apply(c *SpanConfig) { c.Timestamp = time.Time(o) } +type timestampOption time.Time -// WithTimestamp sets the time of a Span life-cycle moment (e.g. started, -// stopped, errored). -func WithTimestamp(t time.Time) LifeCycleOption { - return timestampSpanOption(t) +func (o timestampOption) applySpan(c SpanConfig) SpanConfig { + c.timestamp = time.Time(o) + return c +} +func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o timestampOption) applyEvent(c EventConfig) EventConfig { + c.timestamp = time.Time(o) + return c } -type linksSpanOption []Link +var _ SpanEventOption = timestampOption{} -func (o linksSpanOption) ApplySpan(c *SpanConfig) { c.Links = append(c.Links, []Link(o)...) } -func (linksSpanOption) private() {} +// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g. +// started, stopped, errored). +func WithTimestamp(t time.Time) SpanEventOption { + return timestampOption(t) +} -// WithLinks adds links to a Span. The links are added to the existing Span -// links, i.e. this does not overwrite. -func WithLinks(links ...Link) SpanOption { - return linksSpanOption(links) +type stackTraceOption bool + +func (o stackTraceOption) applyEvent(c EventConfig) EventConfig { + c.stackTrace = bool(o) + return c +} +func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig { + c.stackTrace = bool(o) + return c } +func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) } -type newRootSpanOption bool +// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false). +func WithStackTrace(b bool) SpanEndEventOption { + return stackTraceOption(b) +} -func (o newRootSpanOption) ApplySpan(c *SpanConfig) { c.NewRoot = bool(o) } -func (newRootSpanOption) private() {} +// WithLinks adds links to a Span. The links are added to the existing Span +// links, i.e. this does not overwrite. Links with invalid span context are ignored. +func WithLinks(links ...Link) SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.links = append(cfg.links, links...) + return cfg + }) +} // WithNewRoot specifies that the Span should be treated as a root Span. Any // existing parent span context will be ignored when defining the Span's trace // identifiers. -func WithNewRoot() SpanOption { - return newRootSpanOption(true) +func WithNewRoot() SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.newRoot = true + return cfg + }) } -type spanKindSpanOption SpanKind - -func (o spanKindSpanOption) ApplySpan(c *SpanConfig) { c.SpanKind = SpanKind(o) } -func (o spanKindSpanOption) private() {} - // WithSpanKind sets the SpanKind of a Span. -func WithSpanKind(kind SpanKind) SpanOption { - return spanKindSpanOption(kind) -} - -// InstrumentationOption is an interface for applying instrumentation specific -// options. -type InstrumentationOption interface { - TracerOption +func WithSpanKind(kind SpanKind) SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.spanKind = kind + return cfg + }) } // WithInstrumentationVersion sets the instrumentation version. -func WithInstrumentationVersion(version string) InstrumentationOption { - return instrumentationVersionOption(version) +func WithInstrumentationVersion(version string) TracerOption { + return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { + cfg.instrumentationVersion = version + return cfg + }) } -type instrumentationVersionOption string - -func (i instrumentationVersionOption) ApplyTracer(config *TracerConfig) { - config.InstrumentationVersion = string(i) +// WithInstrumentationAttributes sets the instrumentation attributes. +// +// The passed attributes will be de-duplicated. +func WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption { + return tracerOptionFunc(func(config TracerConfig) TracerConfig { + config.attrs = attribute.NewSet(attr...) + return config + }) } -func (instrumentationVersionOption) private() {} +// WithSchemaURL sets the schema URL for the Tracer. +func WithSchemaURL(schemaURL string) TracerOption { + return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { + cfg.schemaURL = schemaURL + return cfg + }) +} diff --git a/vendor/go.opentelemetry.io/otel/trace/doc.go b/vendor/go.opentelemetry.io/otel/trace/doc.go index c962f3bc622..ab0346f9664 100644 --- a/vendor/go.opentelemetry.io/otel/trace/doc.go +++ b/vendor/go.opentelemetry.io/otel/trace/doc.go @@ -16,12 +16,8 @@ Package trace provides an implementation of the tracing part of the OpenTelemetry API. -This package is currently in a pre-GA phase. Backwards incompatible changes -may be introduced in subsequent minor version releases as we work to track the -evolving OpenTelemetry specification and user feedback. - To participate in distributed traces a Span needs to be created for the -operation being performed as part of a traced workflow. It its simplest form: +operation being performed as part of a traced workflow. In its simplest form: var tracer trace.Tracer diff --git a/vendor/go.opentelemetry.io/otel/trace/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop.go index 4a20f20cb41..7cf6c7f3ef9 100644 --- a/vendor/go.opentelemetry.io/otel/trace/noop.go +++ b/vendor/go.opentelemetry.io/otel/trace/noop.go @@ -37,18 +37,23 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer { return noopTracer{} } -// noopTracer is an implementation of Tracer that preforms no operations. +// noopTracer is an implementation of Tracer that performs no operations. type noopTracer struct{} var _ Tracer = noopTracer{} -// Start starts a noop span. -func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanOption) (context.Context, Span) { - span := noopSpan{} +// Start carries forward a non-recording Span, if one is present in the context, otherwise it +// creates a no-op Span. +func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption) (context.Context, Span) { + span := SpanFromContext(ctx) + if _, ok := span.(nonRecordingSpan); !ok { + // span is likely already a noopSpan, but let's be sure + span = noopSpan{} + } return ContextWithSpan(ctx, span), span } -// noopSpan is an implementation of Span that preforms no operations. +// noopSpan is an implementation of Span that performs no operations. type noopSpan struct{} var _ Span = noopSpan{} @@ -69,16 +74,16 @@ func (noopSpan) SetError(bool) {} func (noopSpan) SetAttributes(...attribute.KeyValue) {} // End does nothing. -func (noopSpan) End(...SpanOption) {} +func (noopSpan) End(...SpanEndOption) {} // RecordError does nothing. func (noopSpan) RecordError(error, ...EventOption) {} -// Tracer returns the Tracer that created this Span. -func (noopSpan) Tracer() Tracer { return noopTracer{} } - // AddEvent does nothing. func (noopSpan) AddEvent(string, ...EventOption) {} // SetName does nothing. func (noopSpan) SetName(string) {} + +// TracerProvider returns a no-op TracerProvider. +func (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} } diff --git a/vendor/go.opentelemetry.io/otel/trace/trace.go b/vendor/go.opentelemetry.io/otel/trace/trace.go index d372e7d9d72..4aa94f79f46 100644 --- a/vendor/go.opentelemetry.io/otel/trace/trace.go +++ b/vendor/go.opentelemetry.io/otel/trace/trace.go @@ -19,9 +19,6 @@ import ( "context" "encoding/hex" "encoding/json" - "regexp" - "strings" - "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -39,18 +36,6 @@ const ( errInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16" errNilSpanID errorConst = "span-id can't be all zero" - - // based on the W3C Trace Context specification, see https://www.w3.org/TR/trace-context-1/#tracestate-header - traceStateKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}` - traceStateKeyFormatWithMultiTenantVendor = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}` - traceStateValueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]` - - traceStateMaxListMembers = 32 - - errInvalidTraceStateKeyValue errorConst = "provided key or value is not valid according to the" + - " W3C Trace Context specification" - errInvalidTraceStateMembersNumber errorConst = "trace state would exceed the maximum limit of members (32)" - errInvalidTraceStateDuplicate errorConst = "trace state key/value pairs with duplicate keys provided" ) type errorConst string @@ -60,7 +45,7 @@ func (e errorConst) Error() string { } // TraceID is a unique identity of a trace. -// nolint:golint +// nolint:revive // revive complains about stutter of `trace.TraceID`. type TraceID [16]byte var nilTraceID TraceID @@ -78,7 +63,7 @@ func (t TraceID) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } -// String returns the hex string representation form of a TraceID +// String returns the hex string representation form of a TraceID. func (t TraceID) String() string { return hex.EncodeToString(t[:]) } @@ -101,7 +86,7 @@ func (s SpanID) MarshalJSON() ([]byte, error) { return json.Marshal(s.String()) } -// String returns the hex string representation form of a SpanID +// String returns the hex string representation form of a SpanID. func (s SpanID) String() string { return hex.EncodeToString(s[:]) } @@ -109,7 +94,7 @@ func (s SpanID) String() string { // TraceIDFromHex returns a TraceID from a hex string if it is compliant with // the W3C trace-context specification. See more at // https://www.w3.org/TR/trace-context/#trace-id -// nolint:golint +// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`. func TraceIDFromHex(h string) (TraceID, error) { t := TraceID{} if len(h) != 32 { @@ -166,155 +151,8 @@ func decodeHex(h string, b []byte) error { return nil } -// TraceState provides additional vendor-specific trace identification information -// across different distributed tracing systems. It represents an immutable list consisting -// of key/value pairs. There can be a maximum of 32 entries in the list. -// -// Key and value of each list member must be valid according to the W3C Trace Context specification -// (see https://www.w3.org/TR/trace-context-1/#key and https://www.w3.org/TR/trace-context-1/#value -// respectively). -// -// Trace state must be valid according to the W3C Trace Context specification at all times. All -// mutating operations validate their input and, in case of valid parameters, return a new TraceState. -type TraceState struct { //nolint:golint - // TODO @matej-g: Consider implementing this as attribute.Set, see - // comment https://github.com/open-telemetry/opentelemetry-go/pull/1340#discussion_r540599226 - kvs []attribute.KeyValue -} - -var _ json.Marshaler = TraceState{} -var _ json.Marshaler = SpanContext{} - -var keyFormatRegExp = regexp.MustCompile( - `^((` + traceStateKeyFormat + `)|(` + traceStateKeyFormatWithMultiTenantVendor + `))$`, -) -var valueFormatRegExp = regexp.MustCompile(`^(` + traceStateValueFormat + `)$`) - -// MarshalJSON implements a custom marshal function to encode trace state. -func (ts TraceState) MarshalJSON() ([]byte, error) { - return json.Marshal(ts.kvs) -} - -// String returns trace state as a string valid according to the -// W3C Trace Context specification. -func (ts TraceState) String() string { - var sb strings.Builder - - for i, kv := range ts.kvs { - sb.WriteString((string)(kv.Key)) - sb.WriteByte('=') - sb.WriteString(kv.Value.Emit()) - - if i != len(ts.kvs)-1 { - sb.WriteByte(',') - } - } - - return sb.String() -} - -// Get returns a value for given key from the trace state. -// If no key is found or provided key is invalid, returns an empty value. -func (ts TraceState) Get(key attribute.Key) attribute.Value { - if !isTraceStateKeyValid(key) { - return attribute.Value{} - } - - for _, kv := range ts.kvs { - if kv.Key == key { - return kv.Value - } - } - - return attribute.Value{} -} - -// Insert adds a new key/value, if one doesn't exists; otherwise updates the existing entry. -// The new or updated entry is always inserted at the beginning of the TraceState, i.e. -// on the left side, as per the W3C Trace Context specification requirement. -func (ts TraceState) Insert(entry attribute.KeyValue) (TraceState, error) { - if !isTraceStateKeyValueValid(entry) { - return ts, errInvalidTraceStateKeyValue - } - - ckvs := ts.copyKVsAndDeleteEntry(entry.Key) - if len(ckvs)+1 > traceStateMaxListMembers { - return ts, errInvalidTraceStateMembersNumber - } - - ckvs = append(ckvs, attribute.KeyValue{}) - copy(ckvs[1:], ckvs) - ckvs[0] = entry - - return TraceState{ckvs}, nil -} - -// Delete removes specified entry from the trace state. -func (ts TraceState) Delete(key attribute.Key) (TraceState, error) { - if !isTraceStateKeyValid(key) { - return ts, errInvalidTraceStateKeyValue - } - - return TraceState{ts.copyKVsAndDeleteEntry(key)}, nil -} - -// IsEmpty returns true if the TraceState does not contain any entries -func (ts TraceState) IsEmpty() bool { - return len(ts.kvs) == 0 -} - -func (ts TraceState) copyKVsAndDeleteEntry(key attribute.Key) []attribute.KeyValue { - ckvs := make([]attribute.KeyValue, len(ts.kvs)) - copy(ckvs, ts.kvs) - for i, kv := range ts.kvs { - if kv.Key == key { - ckvs = append(ckvs[:i], ckvs[i+1:]...) - break - } - } - - return ckvs -} - -// TraceStateFromKeyValues is a convenience method to create a new TraceState from -// provided key/value pairs. -func TraceStateFromKeyValues(kvs ...attribute.KeyValue) (TraceState, error) { //nolint:golint - if len(kvs) == 0 { - return TraceState{}, nil - } - - if len(kvs) > traceStateMaxListMembers { - return TraceState{}, errInvalidTraceStateMembersNumber - } - - km := make(map[attribute.Key]bool) - for _, kv := range kvs { - if !isTraceStateKeyValueValid(kv) { - return TraceState{}, errInvalidTraceStateKeyValue - } - _, ok := km[kv.Key] - if ok { - return TraceState{}, errInvalidTraceStateDuplicate - } - km[kv.Key] = true - } - - ckvs := make([]attribute.KeyValue, len(kvs)) - copy(ckvs, kvs) - return TraceState{ckvs}, nil -} - -func isTraceStateKeyValid(key attribute.Key) bool { - return keyFormatRegExp.MatchString(string(key)) -} - -func isTraceStateKeyValueValid(kv attribute.KeyValue) bool { - return isTraceStateKeyValid(kv.Key) && - valueFormatRegExp.MatchString(kv.Value.Emit()) -} - -// TraceFlags contains flags that can be set on a SpanContext -type TraceFlags byte //nolint:golint +// TraceFlags contains flags that can be set on a SpanContext. +type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`. // IsSampled returns if the sampling bit is set in the TraceFlags. func (tf TraceFlags) IsSampled() bool { @@ -322,7 +160,7 @@ func (tf TraceFlags) IsSampled() bool { } // WithSampled sets the sampling bit in a new copy of the TraceFlags. -func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { +func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive // sampled is not a control flag. if sampled { return tf | FlagsSampled } @@ -336,7 +174,7 @@ func (tf TraceFlags) MarshalJSON() ([]byte, error) { return json.Marshal(tf.String()) } -// String returns the hex string representation form of TraceFlags +// String returns the hex string representation form of TraceFlags. func (tf TraceFlags) String() string { return hex.EncodeToString([]byte{byte(tf)}[:]) } @@ -372,6 +210,8 @@ type SpanContext struct { remote bool } +var _ json.Marshaler = SpanContext{} + // IsValid returns if the SpanContext is valid. A valid span context has a // valid TraceID and SpanID. func (sc SpanContext) IsValid() bool { @@ -497,16 +337,14 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) { // and timed operation of a workflow that is traced. A Tracer is used to // create a Span and it is then up to the operation the Span represents to // properly end the Span when the operation itself ends. +// +// Warning: methods may be added to this interface in minor releases. type Span interface { - // Tracer returns the Tracer that created the Span. Tracer MUST NOT be - // nil. - Tracer() Tracer - // End completes the Span. The Span is considered complete and ready to be // delivered through the rest of the telemetry pipeline after this method // is called. Therefore, updates to the Span are not allowed after this // method has been called. - End(options ...SpanOption) + End(options ...SpanEndOption) // AddEvent adds an event with the provided name and options. AddEvent(name string, options ...EventOption) @@ -516,19 +354,20 @@ type Span interface { IsRecording() bool // RecordError will record err as an exception span event for this span. An - // additional call toSetStatus is required if the Status of the Span should - // be set to Error, this method does not change the Span status. If this - // span is not being recorded or err is nil than this method does nothing. + // additional call to SetStatus is required if the Status of the Span should + // be set to Error, as this method does not change the Span status. If this + // span is not being recorded or err is nil then this method does nothing. RecordError(err error, options ...EventOption) - // SpanContext returns the SpanContext of the Span. The returned - // SpanContext is usable even after the End has been called for the Span. + // SpanContext returns the SpanContext of the Span. The returned SpanContext + // is usable even after the End method has been called for the Span. SpanContext() SpanContext // SetStatus sets the status of the Span in the form of a code and a - // message. SetStatus overrides the value of previous calls to SetStatus - // on the Span. - SetStatus(code codes.Code, msg string) + // description, provided the status hasn't already been set to a higher + // value before (OK > Error > Unset). The description is only included in a + // status when the code is for an error. + SetStatus(code codes.Code, description string) // SetName sets the Span name. SetName(name string) @@ -537,22 +376,10 @@ type Span interface { // already exists for an attribute of the Span it will be overwritten with // the value contained in kv. SetAttributes(kv ...attribute.KeyValue) -} - -// Event is a thing that happened during a Span's lifetime. -type Event struct { - // Name is the name of this event - Name string - // Attributes describe the aspects of the event. - Attributes []attribute.KeyValue - - // DroppedAttributeCount is the number of attributes that were not - // recorded due to configured limits being reached. - DroppedAttributeCount int - - // Time at which this event was recorded. - Time time.Time + // TracerProvider returns a TracerProvider that can be used to generate + // additional Spans on the same telemetry pipeline as the current Span. + TracerProvider() TracerProvider } // Link is the relationship between two Spans. The relationship can be within @@ -560,26 +387,30 @@ type Event struct { // // For example, a Link is used in the following situations: // -// 1. Batch Processing: A batch of operations may contain operations -// associated with one or more traces/spans. Since there can only be one -// parent SpanContext, a Link is used to keep reference to the -// SpanContext of all operations in the batch. -// 2. Public Endpoint: A SpanContext for an in incoming client request on a -// public endpoint should be considered untrusted. In such a case, a new -// trace with its own identity and sampling decision needs to be created, -// but this new trace needs to be related to the original trace in some -// form. A Link is used to keep reference to the original SpanContext and -// track the relationship. +// 1. Batch Processing: A batch of operations may contain operations +// associated with one or more traces/spans. Since there can only be one +// parent SpanContext, a Link is used to keep reference to the +// SpanContext of all operations in the batch. +// 2. Public Endpoint: A SpanContext for an in incoming client request on a +// public endpoint should be considered untrusted. In such a case, a new +// trace with its own identity and sampling decision needs to be created, +// but this new trace needs to be related to the original trace in some +// form. A Link is used to keep reference to the original SpanContext and +// track the relationship. type Link struct { // SpanContext of the linked Span. - SpanContext + SpanContext SpanContext // Attributes describe the aspects of the link. Attributes []attribute.KeyValue +} - // DroppedAttributeCount is the number of attributes that were not - // recorded due to configured limits being reached. - DroppedAttributeCount int +// LinkFromContext returns a link encapsulating the SpanContext in the provided ctx. +func LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link { + return Link{ + SpanContext: SpanContextFromContext(ctx), + Attributes: attrs, + } } // SpanKind is the role a Span plays in a Trace. @@ -654,20 +485,67 @@ func (sk SpanKind) String() string { } // Tracer is the creator of Spans. +// +// Warning: methods may be added to this interface in minor releases. type Tracer interface { - // Start creates a span. - Start(ctx context.Context, spanName string, opts ...SpanOption) (context.Context, Span) + // Start creates a span and a context.Context containing the newly-created span. + // + // If the context.Context provided in `ctx` contains a Span then the newly-created + // Span will be a child of that span, otherwise it will be a root span. This behavior + // can be overridden by providing `WithNewRoot()` as a SpanOption, causing the + // newly-created Span to be a root span even if `ctx` contains a Span. + // + // When creating a Span it is recommended to provide all known span attributes using + // the `WithAttributes()` SpanOption as samplers will only have access to the + // attributes provided when a Span is created. + // + // Any Span that is created MUST also be ended. This is the responsibility of the user. + // Implementations of this API may leak memory or other resources if Spans are not ended. + Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span) } -// TracerProvider provides access to instrumentation Tracers. +// TracerProvider provides Tracers that are used by instrumentation code to +// trace computational workflows. +// +// A TracerProvider is the collection destination of all Spans from Tracers it +// provides, it represents a unique telemetry collection pipeline. How that +// pipeline is defined, meaning how those Spans are collected, processed, and +// where they are exported, depends on its implementation. Instrumentation +// authors do not need to define this implementation, rather just use the +// provided Tracers to instrument code. +// +// Commonly, instrumentation code will accept a TracerProvider implementation +// at runtime from its users or it can simply use the globally registered one +// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider). +// +// Warning: methods may be added to this interface in minor releases. type TracerProvider interface { - // Tracer creates an implementation of the Tracer interface. - // The instrumentationName must be the name of the library providing - // instrumentation. This name may be the same as the instrumented code - // only if that code provides built-in instrumentation. If the - // instrumentationName is empty, then a implementation defined default - // name will be used instead. + // Tracer returns a unique Tracer scoped to be used by instrumentation code + // to trace computational workflows. The scope and identity of that + // instrumentation code is uniquely defined by the name and options passed. + // + // The passed name needs to uniquely identify instrumentation code. + // Therefore, it is recommended that name is the Go package name of the + // library providing instrumentation (note: not the code being + // instrumented). Instrumentation libraries can have multiple versions, + // therefore, the WithInstrumentationVersion option should be used to + // distinguish these different codebases. Additionally, instrumentation + // libraries may sometimes use traces to communicate different domains of + // workflow data (i.e. using spans to communicate workflow events only). If + // this is the case, the WithScopeAttributes option should be used to + // uniquely identify Tracers that handle the different domains of workflow + // data. + // + // If the same name and options are passed multiple times, the same Tracer + // will be returned (it is up to the implementation if this will be the + // same underlying instance of that Tracer or not). It is not necessary to + // call this multiple times with the same name and options to get an + // up-to-date Tracer. All implementations will ensure any TracerProvider + // configuration changes are propagated to all provided Tracers. + // + // If name is empty, then an implementation defined default name will be + // used instead. // - // This method must be concurrency safe. - Tracer(instrumentationName string, opts ...TracerOption) Tracer + // This method is safe to call concurrently. + Tracer(name string, options ...TracerOption) Tracer } diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go new file mode 100644 index 00000000000..ca68a82e5f7 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go @@ -0,0 +1,212 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "encoding/json" + "fmt" + "regexp" + "strings" +) + +const ( + maxListMembers = 32 + + listDelimiter = "," + + // based on the W3C Trace Context specification, see + // https://www.w3.org/TR/trace-context-1/#tracestate-header + noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}` + withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}` + valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]` + + errInvalidKey errorConst = "invalid tracestate key" + errInvalidValue errorConst = "invalid tracestate value" + errInvalidMember errorConst = "invalid tracestate list-member" + errMemberNumber errorConst = "too many list-members in tracestate" + errDuplicate errorConst = "duplicate list-member in tracestate" +) + +var ( + keyRe = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`) + valueRe = regexp.MustCompile(`^(` + valueFormat + `)$`) + memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`) +) + +type member struct { + Key string + Value string +} + +func newMember(key, value string) (member, error) { + if !keyRe.MatchString(key) { + return member{}, fmt.Errorf("%w: %s", errInvalidKey, key) + } + if !valueRe.MatchString(value) { + return member{}, fmt.Errorf("%w: %s", errInvalidValue, value) + } + return member{Key: key, Value: value}, nil +} + +func parseMember(m string) (member, error) { + matches := memberRe.FindStringSubmatch(m) + if len(matches) != 5 { + return member{}, fmt.Errorf("%w: %s", errInvalidMember, m) + } + + return member{ + Key: matches[1], + Value: matches[4], + }, nil +} + +// String encodes member into a string compliant with the W3C Trace Context +// specification. +func (m member) String() string { + return fmt.Sprintf("%s=%s", m.Key, m.Value) +} + +// TraceState provides additional vendor-specific trace identification +// information across different distributed tracing systems. It represents an +// immutable list consisting of key/value pairs, each pair is referred to as a +// list-member. +// +// TraceState conforms to the W3C Trace Context specification +// (https://www.w3.org/TR/trace-context-1). All operations that create or copy +// a TraceState do so by validating all input and will only produce TraceState +// that conform to the specification. Specifically, this means that all +// list-member's key/value pairs are valid, no duplicate list-members exist, +// and the maximum number of list-members (32) is not exceeded. +type TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState` + // list is the members in order. + list []member +} + +var _ json.Marshaler = TraceState{} + +// ParseTraceState attempts to decode a TraceState from the passed +// string. It returns an error if the input is invalid according to the W3C +// Trace Context specification. +func ParseTraceState(tracestate string) (TraceState, error) { + if tracestate == "" { + return TraceState{}, nil + } + + wrapErr := func(err error) error { + return fmt.Errorf("failed to parse tracestate: %w", err) + } + + var members []member + found := make(map[string]struct{}) + for _, memberStr := range strings.Split(tracestate, listDelimiter) { + if len(memberStr) == 0 { + continue + } + + m, err := parseMember(memberStr) + if err != nil { + return TraceState{}, wrapErr(err) + } + + if _, ok := found[m.Key]; ok { + return TraceState{}, wrapErr(errDuplicate) + } + found[m.Key] = struct{}{} + + members = append(members, m) + if n := len(members); n > maxListMembers { + return TraceState{}, wrapErr(errMemberNumber) + } + } + + return TraceState{list: members}, nil +} + +// MarshalJSON marshals the TraceState into JSON. +func (ts TraceState) MarshalJSON() ([]byte, error) { + return json.Marshal(ts.String()) +} + +// String encodes the TraceState into a string compliant with the W3C +// Trace Context specification. The returned string will be invalid if the +// TraceState contains any invalid members. +func (ts TraceState) String() string { + members := make([]string, len(ts.list)) + for i, m := range ts.list { + members[i] = m.String() + } + return strings.Join(members, listDelimiter) +} + +// Get returns the value paired with key from the corresponding TraceState +// list-member if it exists, otherwise an empty string is returned. +func (ts TraceState) Get(key string) string { + for _, member := range ts.list { + if member.Key == key { + return member.Value + } + } + + return "" +} + +// Insert adds a new list-member defined by the key/value pair to the +// TraceState. If a list-member already exists for the given key, that +// list-member's value is updated. The new or updated list-member is always +// moved to the beginning of the TraceState as specified by the W3C Trace +// Context specification. +// +// If key or value are invalid according to the W3C Trace Context +// specification an error is returned with the original TraceState. +// +// If adding a new list-member means the TraceState would have more members +// then is allowed, the new list-member will be inserted and the right-most +// list-member will be dropped in the returned TraceState. +func (ts TraceState) Insert(key, value string) (TraceState, error) { + m, err := newMember(key, value) + if err != nil { + return ts, err + } + + cTS := ts.Delete(key) + if cTS.Len()+1 <= maxListMembers { + cTS.list = append(cTS.list, member{}) + } + // When the number of members exceeds capacity, drop the "right-most". + copy(cTS.list[1:], cTS.list) + cTS.list[0] = m + + return cTS, nil +} + +// Delete returns a copy of the TraceState with the list-member identified by +// key removed. +func (ts TraceState) Delete(key string) TraceState { + members := make([]member, ts.Len()) + copy(members, ts.list) + for i, member := range ts.list { + if member.Key == key { + members = append(members[:i], members[i+1:]...) + // TraceState should contain no duplicate members. + break + } + } + return TraceState{list: members} +} + +// Len returns the number of list-members in the TraceState. +func (ts TraceState) Len() int { + return len(ts.list) +} diff --git a/vendor/go.opentelemetry.io/otel/unit/doc.go b/vendor/go.opentelemetry.io/otel/unit/doc.go deleted file mode 100644 index 0d77a750cc3..00000000000 --- a/vendor/go.opentelemetry.io/otel/unit/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package unit provides units. -// -// This package is currently in a pre-GA phase. Backwards incompatible changes -// may be introduced in subsequent minor version releases as we work to track -// the evolving OpenTelemetry specification and user feedback. -package unit // import "go.opentelemetry.io/otel/unit" diff --git a/vendor/go.opentelemetry.io/otel/unit/unit.go b/vendor/go.opentelemetry.io/otel/unit/unit.go deleted file mode 100644 index 523bfe1d0a1..00000000000 --- a/vendor/go.opentelemetry.io/otel/unit/unit.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package unit // import "go.opentelemetry.io/otel/unit" - -type Unit string - -const ( - Dimensionless Unit = "1" - Bytes Unit = "By" - Milliseconds Unit = "ms" -) diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index 81be6f36817..ad64e199672 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "0.20.0" + return "1.19.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml new file mode 100644 index 00000000000..7d212769240 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -0,0 +1,55 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module-sets: + stable-v1: + version: v1.19.0 + modules: + - go.opentelemetry.io/otel + - go.opentelemetry.io/otel/bridge/opentracing + - go.opentelemetry.io/otel/bridge/opentracing/test + - go.opentelemetry.io/otel/example/dice + - go.opentelemetry.io/otel/example/fib + - go.opentelemetry.io/otel/example/namedtracer + - go.opentelemetry.io/otel/example/otel-collector + - go.opentelemetry.io/otel/example/passthrough + - go.opentelemetry.io/otel/example/zipkin + - go.opentelemetry.io/otel/exporters/otlp/otlptrace + - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc + - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp + - go.opentelemetry.io/otel/exporters/stdout/stdouttrace + - go.opentelemetry.io/otel/exporters/zipkin + - go.opentelemetry.io/otel/metric + - go.opentelemetry.io/otel/sdk + - go.opentelemetry.io/otel/sdk/metric + - go.opentelemetry.io/otel/trace + experimental-metrics: + version: v0.42.0 + modules: + - go.opentelemetry.io/otel/bridge/opencensus + - go.opentelemetry.io/otel/bridge/opencensus/test + - go.opentelemetry.io/otel/example/opencensus + - go.opentelemetry.io/otel/example/prometheus + - go.opentelemetry.io/otel/example/view + - go.opentelemetry.io/otel/exporters/otlp/otlpmetric + - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc + - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp + - go.opentelemetry.io/otel/exporters/prometheus + - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric + experimental-schema: + version: v0.0.7 + modules: + - go.opentelemetry.io/otel/schema +excluded-modules: + - go.opentelemetry.io/otel/internal/tools diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.go b/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.go deleted file mode 100644 index d496a141b0a..00000000000 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.go +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 -// source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto - -package v1 - -import ( - proto "github.com/golang/protobuf/proto" - v1 "go.opentelemetry.io/proto/otlp/metrics/v1" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type ExportMetricsServiceRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // An array of ResourceMetrics. - // For data coming from a single resource this array will typically contain one - // element. Intermediary nodes (such as OpenTelemetry Collector) that receive - // data from multiple origins typically batch the data before forwarding further and - // in that case this array will contain multiple elements. - ResourceMetrics []*v1.ResourceMetrics `protobuf:"bytes,1,rep,name=resource_metrics,json=resourceMetrics,proto3" json:"resource_metrics,omitempty"` -} - -func (x *ExportMetricsServiceRequest) Reset() { - *x = ExportMetricsServiceRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportMetricsServiceRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportMetricsServiceRequest) ProtoMessage() {} - -func (x *ExportMetricsServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportMetricsServiceRequest.ProtoReflect.Descriptor instead. -func (*ExportMetricsServiceRequest) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescGZIP(), []int{0} -} - -func (x *ExportMetricsServiceRequest) GetResourceMetrics() []*v1.ResourceMetrics { - if x != nil { - return x.ResourceMetrics - } - return nil -} - -type ExportMetricsServiceResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ExportMetricsServiceResponse) Reset() { - *x = ExportMetricsServiceResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportMetricsServiceResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportMetricsServiceResponse) ProtoMessage() {} - -func (x *ExportMetricsServiceResponse) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportMetricsServiceResponse.ProtoReflect.Descriptor instead. -func (*ExportMetricsServiceResponse) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescGZIP(), []int{1} -} - -var File_opentelemetry_proto_collector_metrics_v1_metrics_service_proto protoreflect.FileDescriptor - -var file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDesc = []byte{ - 0x0a, 0x3e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x28, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x2c, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x79, 0x0a, 0x1b, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x32, 0xac, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x12, 0x45, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x46, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x79, 0x0a, 0x2b, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x42, 0x13, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescOnce sync.Once - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescData = file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDesc -) - -func file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescGZIP() []byte { - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescOnce.Do(func() { - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescData) - }) - return file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDescData -} - -var file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_goTypes = []interface{}{ - (*ExportMetricsServiceRequest)(nil), // 0: opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest - (*ExportMetricsServiceResponse)(nil), // 1: opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse - (*v1.ResourceMetrics)(nil), // 2: opentelemetry.proto.metrics.v1.ResourceMetrics -} -var file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_depIdxs = []int32{ - 2, // 0: opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest.resource_metrics:type_name -> opentelemetry.proto.metrics.v1.ResourceMetrics - 0, // 1: opentelemetry.proto.collector.metrics.v1.MetricsService.Export:input_type -> opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest - 1, // 2: opentelemetry.proto.collector.metrics.v1.MetricsService.Export:output_type -> opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_init() } -func file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_init() { - if File_opentelemetry_proto_collector_metrics_v1_metrics_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportMetricsServiceRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportMetricsServiceResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_goTypes, - DependencyIndexes: file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_depIdxs, - MessageInfos: file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_msgTypes, - }.Build() - File_opentelemetry_proto_collector_metrics_v1_metrics_service_proto = out.File - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_rawDesc = nil - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_goTypes = nil - file_opentelemetry_proto_collector_metrics_v1_metrics_service_proto_depIdxs = nil -} diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.gw.go b/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.gw.go deleted file mode 100644 index f0dc06e5f5e..00000000000 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.gw.go +++ /dev/null @@ -1,169 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto - -/* -Package v1 is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package v1 - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage -var _ = metadata.Join - -func request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client MetricsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ExportMetricsServiceRequest - var metadata runtime.ServerMetadata - - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) - } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Export(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Marshaler, server MetricsServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ExportMetricsServiceRequest - var metadata runtime.ServerMetadata - - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) - } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.Export(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterMetricsServiceHandlerServer registers the http handlers for service MetricsService to "mux". -// UnaryRPC :call MetricsServiceServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMetricsServiceHandlerFromEndpoint instead. -func RegisterMetricsServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MetricsServiceServer) error { - - mux.Handle("POST", pattern_MetricsService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_MetricsService_Export_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_MetricsService_Export_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterMetricsServiceHandlerFromEndpoint is same as RegisterMetricsServiceHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterMetricsServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterMetricsServiceHandler(ctx, mux, conn) -} - -// RegisterMetricsServiceHandler registers the http handlers for service MetricsService to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterMetricsServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterMetricsServiceHandlerClient(ctx, mux, NewMetricsServiceClient(conn)) -} - -// RegisterMetricsServiceHandlerClient registers the http handlers for service MetricsService -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MetricsServiceClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MetricsServiceClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "MetricsServiceClient" to call the correct interceptors. -func RegisterMetricsServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MetricsServiceClient) error { - - mux.Handle("POST", pattern_MetricsService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_MetricsService_Export_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_MetricsService_Export_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_MetricsService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "metrics"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_MetricsService_Export_0 = runtime.ForwardResponseMessage -) diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service_grpc.pb.go b/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service_grpc.pb.go deleted file mode 100644 index eca49e5c4f3..00000000000 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service_grpc.pb.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion7 - -// MetricsServiceClient is the client API for MetricsService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type MetricsServiceClient interface { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(ctx context.Context, in *ExportMetricsServiceRequest, opts ...grpc.CallOption) (*ExportMetricsServiceResponse, error) -} - -type metricsServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewMetricsServiceClient(cc grpc.ClientConnInterface) MetricsServiceClient { - return &metricsServiceClient{cc} -} - -func (c *metricsServiceClient) Export(ctx context.Context, in *ExportMetricsServiceRequest, opts ...grpc.CallOption) (*ExportMetricsServiceResponse, error) { - out := new(ExportMetricsServiceResponse) - err := c.cc.Invoke(ctx, "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// MetricsServiceServer is the server API for MetricsService service. -// All implementations must embed UnimplementedMetricsServiceServer -// for forward compatibility -type MetricsServiceServer interface { - // For performance reasons, it is recommended to keep this RPC - // alive for the entire life of the application. - Export(context.Context, *ExportMetricsServiceRequest) (*ExportMetricsServiceResponse, error) - mustEmbedUnimplementedMetricsServiceServer() -} - -// UnimplementedMetricsServiceServer must be embedded to have forward compatible implementations. -type UnimplementedMetricsServiceServer struct { -} - -func (UnimplementedMetricsServiceServer) Export(context.Context, *ExportMetricsServiceRequest) (*ExportMetricsServiceResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Export not implemented") -} -func (UnimplementedMetricsServiceServer) mustEmbedUnimplementedMetricsServiceServer() {} - -// UnsafeMetricsServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to MetricsServiceServer will -// result in compilation errors. -type UnsafeMetricsServiceServer interface { - mustEmbedUnimplementedMetricsServiceServer() -} - -func RegisterMetricsServiceServer(s grpc.ServiceRegistrar, srv MetricsServiceServer) { - s.RegisterService(&_MetricsService_serviceDesc, srv) -} - -func _MetricsService_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ExportMetricsServiceRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MetricsServiceServer).Export(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MetricsServiceServer).Export(ctx, req.(*ExportMetricsServiceRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _MetricsService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "opentelemetry.proto.collector.metrics.v1.MetricsService", - HandlerType: (*MetricsServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Export", - Handler: _MetricsService_Export_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "opentelemetry/proto/collector/metrics/v1/metrics_service.proto", -} diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_config.pb.go b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_config.pb.go deleted file mode 100644 index 07f7e9b1fa3..00000000000 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_config.pb.go +++ /dev/null @@ -1,573 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 -// source: opentelemetry/proto/trace/v1/trace_config.proto - -package v1 - -import ( - proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -// How spans should be sampled: -// - Always off -// - Always on -// - Always follow the parent Span's decision (off if no parent). -type ConstantSampler_ConstantDecision int32 - -const ( - ConstantSampler_ALWAYS_OFF ConstantSampler_ConstantDecision = 0 - ConstantSampler_ALWAYS_ON ConstantSampler_ConstantDecision = 1 - ConstantSampler_ALWAYS_PARENT ConstantSampler_ConstantDecision = 2 -) - -// Enum value maps for ConstantSampler_ConstantDecision. -var ( - ConstantSampler_ConstantDecision_name = map[int32]string{ - 0: "ALWAYS_OFF", - 1: "ALWAYS_ON", - 2: "ALWAYS_PARENT", - } - ConstantSampler_ConstantDecision_value = map[string]int32{ - "ALWAYS_OFF": 0, - "ALWAYS_ON": 1, - "ALWAYS_PARENT": 2, - } -) - -func (x ConstantSampler_ConstantDecision) Enum() *ConstantSampler_ConstantDecision { - p := new(ConstantSampler_ConstantDecision) - *p = x - return p -} - -func (x ConstantSampler_ConstantDecision) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ConstantSampler_ConstantDecision) Descriptor() protoreflect.EnumDescriptor { - return file_opentelemetry_proto_trace_v1_trace_config_proto_enumTypes[0].Descriptor() -} - -func (ConstantSampler_ConstantDecision) Type() protoreflect.EnumType { - return &file_opentelemetry_proto_trace_v1_trace_config_proto_enumTypes[0] -} - -func (x ConstantSampler_ConstantDecision) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ConstantSampler_ConstantDecision.Descriptor instead. -func (ConstantSampler_ConstantDecision) EnumDescriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP(), []int{1, 0} -} - -// Global configuration of the trace service. All fields must be specified, or -// the default (zero) values will be used for each type. -type TraceConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The global default sampler used to make decisions on span sampling. - // - // Types that are assignable to Sampler: - // *TraceConfig_ConstantSampler - // *TraceConfig_TraceIdRatioBased - // *TraceConfig_RateLimitingSampler - Sampler isTraceConfig_Sampler `protobuf_oneof:"sampler"` - // The global default max number of attributes per span. - MaxNumberOfAttributes int64 `protobuf:"varint,4,opt,name=max_number_of_attributes,json=maxNumberOfAttributes,proto3" json:"max_number_of_attributes,omitempty"` - // The global default max number of annotation events per span. - MaxNumberOfTimedEvents int64 `protobuf:"varint,5,opt,name=max_number_of_timed_events,json=maxNumberOfTimedEvents,proto3" json:"max_number_of_timed_events,omitempty"` - // The global default max number of attributes per timed event. - MaxNumberOfAttributesPerTimedEvent int64 `protobuf:"varint,6,opt,name=max_number_of_attributes_per_timed_event,json=maxNumberOfAttributesPerTimedEvent,proto3" json:"max_number_of_attributes_per_timed_event,omitempty"` - // The global default max number of link entries per span. - MaxNumberOfLinks int64 `protobuf:"varint,7,opt,name=max_number_of_links,json=maxNumberOfLinks,proto3" json:"max_number_of_links,omitempty"` - // The global default max number of attributes per span. - MaxNumberOfAttributesPerLink int64 `protobuf:"varint,8,opt,name=max_number_of_attributes_per_link,json=maxNumberOfAttributesPerLink,proto3" json:"max_number_of_attributes_per_link,omitempty"` -} - -func (x *TraceConfig) Reset() { - *x = TraceConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TraceConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TraceConfig) ProtoMessage() {} - -func (x *TraceConfig) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TraceConfig.ProtoReflect.Descriptor instead. -func (*TraceConfig) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP(), []int{0} -} - -func (m *TraceConfig) GetSampler() isTraceConfig_Sampler { - if m != nil { - return m.Sampler - } - return nil -} - -func (x *TraceConfig) GetConstantSampler() *ConstantSampler { - if x, ok := x.GetSampler().(*TraceConfig_ConstantSampler); ok { - return x.ConstantSampler - } - return nil -} - -func (x *TraceConfig) GetTraceIdRatioBased() *TraceIdRatioBased { - if x, ok := x.GetSampler().(*TraceConfig_TraceIdRatioBased); ok { - return x.TraceIdRatioBased - } - return nil -} - -func (x *TraceConfig) GetRateLimitingSampler() *RateLimitingSampler { - if x, ok := x.GetSampler().(*TraceConfig_RateLimitingSampler); ok { - return x.RateLimitingSampler - } - return nil -} - -func (x *TraceConfig) GetMaxNumberOfAttributes() int64 { - if x != nil { - return x.MaxNumberOfAttributes - } - return 0 -} - -func (x *TraceConfig) GetMaxNumberOfTimedEvents() int64 { - if x != nil { - return x.MaxNumberOfTimedEvents - } - return 0 -} - -func (x *TraceConfig) GetMaxNumberOfAttributesPerTimedEvent() int64 { - if x != nil { - return x.MaxNumberOfAttributesPerTimedEvent - } - return 0 -} - -func (x *TraceConfig) GetMaxNumberOfLinks() int64 { - if x != nil { - return x.MaxNumberOfLinks - } - return 0 -} - -func (x *TraceConfig) GetMaxNumberOfAttributesPerLink() int64 { - if x != nil { - return x.MaxNumberOfAttributesPerLink - } - return 0 -} - -type isTraceConfig_Sampler interface { - isTraceConfig_Sampler() -} - -type TraceConfig_ConstantSampler struct { - ConstantSampler *ConstantSampler `protobuf:"bytes,1,opt,name=constant_sampler,json=constantSampler,proto3,oneof"` -} - -type TraceConfig_TraceIdRatioBased struct { - TraceIdRatioBased *TraceIdRatioBased `protobuf:"bytes,2,opt,name=trace_id_ratio_based,json=traceIdRatioBased,proto3,oneof"` -} - -type TraceConfig_RateLimitingSampler struct { - RateLimitingSampler *RateLimitingSampler `protobuf:"bytes,3,opt,name=rate_limiting_sampler,json=rateLimitingSampler,proto3,oneof"` -} - -func (*TraceConfig_ConstantSampler) isTraceConfig_Sampler() {} - -func (*TraceConfig_TraceIdRatioBased) isTraceConfig_Sampler() {} - -func (*TraceConfig_RateLimitingSampler) isTraceConfig_Sampler() {} - -// Sampler that always makes a constant decision on span sampling. -type ConstantSampler struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Decision ConstantSampler_ConstantDecision `protobuf:"varint,1,opt,name=decision,proto3,enum=opentelemetry.proto.trace.v1.ConstantSampler_ConstantDecision" json:"decision,omitempty"` -} - -func (x *ConstantSampler) Reset() { - *x = ConstantSampler{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ConstantSampler) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConstantSampler) ProtoMessage() {} - -func (x *ConstantSampler) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConstantSampler.ProtoReflect.Descriptor instead. -func (*ConstantSampler) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP(), []int{1} -} - -func (x *ConstantSampler) GetDecision() ConstantSampler_ConstantDecision { - if x != nil { - return x.Decision - } - return ConstantSampler_ALWAYS_OFF -} - -// Sampler that tries to uniformly sample traces with a given ratio. -// The ratio of sampling a trace is equal to that of the specified ratio. -type TraceIdRatioBased struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The desired ratio of sampling. Must be within [0.0, 1.0]. - SamplingRatio float64 `protobuf:"fixed64,1,opt,name=samplingRatio,proto3" json:"samplingRatio,omitempty"` -} - -func (x *TraceIdRatioBased) Reset() { - *x = TraceIdRatioBased{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TraceIdRatioBased) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TraceIdRatioBased) ProtoMessage() {} - -func (x *TraceIdRatioBased) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TraceIdRatioBased.ProtoReflect.Descriptor instead. -func (*TraceIdRatioBased) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP(), []int{2} -} - -func (x *TraceIdRatioBased) GetSamplingRatio() float64 { - if x != nil { - return x.SamplingRatio - } - return 0 -} - -// Sampler that tries to sample with a rate per time window. -type RateLimitingSampler struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Rate per second. - Qps int64 `protobuf:"varint,1,opt,name=qps,proto3" json:"qps,omitempty"` -} - -func (x *RateLimitingSampler) Reset() { - *x = RateLimitingSampler{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RateLimitingSampler) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RateLimitingSampler) ProtoMessage() {} - -func (x *RateLimitingSampler) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RateLimitingSampler.ProtoReflect.Descriptor instead. -func (*RateLimitingSampler) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP(), []int{3} -} - -func (x *RateLimitingSampler) GetQps() int64 { - if x != nil { - return x.Qps - } - return 0 -} - -var File_opentelemetry_proto_trace_v1_trace_config_proto protoreflect.FileDescriptor - -var file_opentelemetry_proto_trace_v1_trace_config_proto_rawDesc = []byte{ - 0x0a, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x1c, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x22, - 0x84, 0x05, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x5a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x12, 0x62, 0x0a, 0x14, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f, 0x62, 0x61, - 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, - 0x52, 0x61, 0x74, 0x69, 0x6f, 0x42, 0x61, 0x73, 0x65, 0x64, 0x48, 0x00, 0x52, 0x11, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x49, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x42, 0x61, 0x73, 0x65, 0x64, 0x12, - 0x67, 0x0a, 0x15, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x6e, 0x67, - 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x72, 0x48, 0x00, 0x52, 0x13, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x12, 0x3a, 0x0a, 0x1a, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, - 0x6f, 0x66, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x6d, 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x4f, 0x66, 0x54, 0x69, 0x6d, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x54, 0x0a, - 0x28, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x22, 0x6d, 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x64, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x10, 0x6d, 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4c, 0x69, 0x6e, - 0x6b, 0x73, 0x12, 0x47, 0x0a, 0x21, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x6f, 0x66, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x70, - 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x6d, - 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x42, 0x09, 0x0a, 0x07, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x22, 0xb3, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x08, 0x64, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x44, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x4c, - 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4f, 0x46, 0x46, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x4c, - 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x4c, 0x57, - 0x41, 0x59, 0x53, 0x5f, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x22, 0x39, 0x0a, 0x11, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x42, 0x61, 0x73, 0x65, - 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, - 0x69, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, - 0x6e, 0x67, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x22, 0x27, 0x0a, 0x13, 0x52, 0x61, 0x74, 0x65, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x12, 0x10, - 0x0a, 0x03, 0x71, 0x70, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x71, 0x70, 0x73, - 0x42, 0x68, 0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescOnce sync.Once - file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescData = file_opentelemetry_proto_trace_v1_trace_config_proto_rawDesc -) - -func file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescGZIP() []byte { - file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescOnce.Do(func() { - file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescData) - }) - return file_opentelemetry_proto_trace_v1_trace_config_proto_rawDescData -} - -var file_opentelemetry_proto_trace_v1_trace_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_opentelemetry_proto_trace_v1_trace_config_proto_goTypes = []interface{}{ - (ConstantSampler_ConstantDecision)(0), // 0: opentelemetry.proto.trace.v1.ConstantSampler.ConstantDecision - (*TraceConfig)(nil), // 1: opentelemetry.proto.trace.v1.TraceConfig - (*ConstantSampler)(nil), // 2: opentelemetry.proto.trace.v1.ConstantSampler - (*TraceIdRatioBased)(nil), // 3: opentelemetry.proto.trace.v1.TraceIdRatioBased - (*RateLimitingSampler)(nil), // 4: opentelemetry.proto.trace.v1.RateLimitingSampler -} -var file_opentelemetry_proto_trace_v1_trace_config_proto_depIdxs = []int32{ - 2, // 0: opentelemetry.proto.trace.v1.TraceConfig.constant_sampler:type_name -> opentelemetry.proto.trace.v1.ConstantSampler - 3, // 1: opentelemetry.proto.trace.v1.TraceConfig.trace_id_ratio_based:type_name -> opentelemetry.proto.trace.v1.TraceIdRatioBased - 4, // 2: opentelemetry.proto.trace.v1.TraceConfig.rate_limiting_sampler:type_name -> opentelemetry.proto.trace.v1.RateLimitingSampler - 0, // 3: opentelemetry.proto.trace.v1.ConstantSampler.decision:type_name -> opentelemetry.proto.trace.v1.ConstantSampler.ConstantDecision - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_opentelemetry_proto_trace_v1_trace_config_proto_init() } -func file_opentelemetry_proto_trace_v1_trace_config_proto_init() { - if File_opentelemetry_proto_trace_v1_trace_config_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TraceConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConstantSampler); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TraceIdRatioBased); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RateLimitingSampler); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*TraceConfig_ConstantSampler)(nil), - (*TraceConfig_TraceIdRatioBased)(nil), - (*TraceConfig_RateLimitingSampler)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_opentelemetry_proto_trace_v1_trace_config_proto_rawDesc, - NumEnums: 1, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_opentelemetry_proto_trace_v1_trace_config_proto_goTypes, - DependencyIndexes: file_opentelemetry_proto_trace_v1_trace_config_proto_depIdxs, - EnumInfos: file_opentelemetry_proto_trace_v1_trace_config_proto_enumTypes, - MessageInfos: file_opentelemetry_proto_trace_v1_trace_config_proto_msgTypes, - }.Build() - File_opentelemetry_proto_trace_v1_trace_config_proto = out.File - file_opentelemetry_proto_trace_v1_trace_config_proto_rawDesc = nil - file_opentelemetry_proto_trace_v1_trace_config_proto_goTypes = nil - file_opentelemetry_proto_trace_v1_trace_config_proto_depIdxs = nil -} diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go index 402614f1d3c..c1af04e84e5 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 +// protoc-gen-go v1.26.0 +// protoc v3.21.6 // source: opentelemetry/proto/collector/trace/v1/trace_service.proto package v1 import ( - proto "github.com/golang/protobuf/proto" v1 "go.opentelemetry.io/proto/otlp/trace/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -36,10 +35,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type ExportTraceServiceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -96,6 +91,23 @@ type ExportTraceServiceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // The details of a partially successful export request. + // + // If the request is only partially accepted + // (i.e. when the server accepts only parts of the data and rejects the rest) + // the server MUST initialize the `partial_success` field and MUST + // set the `rejected_` with the number of items it rejected. + // + // Servers MAY also make use of the `partial_success` field to convey + // warnings/suggestions to senders even when the request was fully accepted. + // In such cases, the `rejected_` MUST have a value of `0` and + // the `error_message` MUST be non-empty. + // + // A `partial_success` message with an empty value (rejected_ = 0 and + // `error_message` = "") is equivalent to it not being set/present. Senders + // SHOULD interpret it the same way as in the full success case. + PartialSuccess *ExportTracePartialSuccess `protobuf:"bytes,1,opt,name=partial_success,json=partialSuccess,proto3" json:"partial_success,omitempty"` } func (x *ExportTraceServiceResponse) Reset() { @@ -130,6 +142,79 @@ func (*ExportTraceServiceResponse) Descriptor() ([]byte, []int) { return file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP(), []int{1} } +func (x *ExportTraceServiceResponse) GetPartialSuccess() *ExportTracePartialSuccess { + if x != nil { + return x.PartialSuccess + } + return nil +} + +type ExportTracePartialSuccess struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The number of rejected spans. + // + // A `rejected_` field holding a `0` value indicates that the + // request was fully accepted. + RejectedSpans int64 `protobuf:"varint,1,opt,name=rejected_spans,json=rejectedSpans,proto3" json:"rejected_spans,omitempty"` + // A developer-facing human-readable message in English. It should be used + // either to explain why the server rejected parts of the data during a partial + // success or to convey warnings/suggestions during a full success. The message + // should offer guidance on how users can address such issues. + // + // error_message is an optional field. An error_message with an empty value + // is equivalent to it not being set. + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` +} + +func (x *ExportTracePartialSuccess) Reset() { + *x = ExportTracePartialSuccess{} + if protoimpl.UnsafeEnabled { + mi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExportTracePartialSuccess) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExportTracePartialSuccess) ProtoMessage() {} + +func (x *ExportTracePartialSuccess) ProtoReflect() protoreflect.Message { + mi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExportTracePartialSuccess.ProtoReflect.Descriptor instead. +func (*ExportTracePartialSuccess) Descriptor() ([]byte, []int) { + return file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ExportTracePartialSuccess) GetRejectedSpans() int64 { + if x != nil { + return x.RejectedSpans + } + return 0 +} + +func (x *ExportTracePartialSuccess) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + var File_opentelemetry_proto_collector_trace_v1_trace_service_proto protoreflect.FileDescriptor var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc = []byte{ @@ -149,26 +234,42 @@ var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc = [] 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x22, - 0x1c, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa2, 0x01, - 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x91, - 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x41, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x73, 0x0a, 0x29, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, - 0x11, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x88, 0x01, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, + 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x67, 0x0a, 0x19, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x41, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, + 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9c, 0x01, 0x0a, 0x29, 0x69, 0x6f, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x6f, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xaa, 0x02, + 0x26, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x54, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -183,21 +284,23 @@ func file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP return file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescData } -var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_goTypes = []interface{}{ (*ExportTraceServiceRequest)(nil), // 0: opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest (*ExportTraceServiceResponse)(nil), // 1: opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse - (*v1.ResourceSpans)(nil), // 2: opentelemetry.proto.trace.v1.ResourceSpans + (*ExportTracePartialSuccess)(nil), // 2: opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess + (*v1.ResourceSpans)(nil), // 3: opentelemetry.proto.trace.v1.ResourceSpans } var file_opentelemetry_proto_collector_trace_v1_trace_service_proto_depIdxs = []int32{ - 2, // 0: opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest.resource_spans:type_name -> opentelemetry.proto.trace.v1.ResourceSpans - 0, // 1: opentelemetry.proto.collector.trace.v1.TraceService.Export:input_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest - 1, // 2: opentelemetry.proto.collector.trace.v1.TraceService.Export:output_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 3, // 0: opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest.resource_spans:type_name -> opentelemetry.proto.trace.v1.ResourceSpans + 2, // 1: opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse.partial_success:type_name -> opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess + 0, // 2: opentelemetry.proto.collector.trace.v1.TraceService.Export:input_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest + 1, // 3: opentelemetry.proto.collector.trace.v1.TraceService.Export:output_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_opentelemetry_proto_collector_trace_v1_trace_service_proto_init() } @@ -230,6 +333,18 @@ func file_opentelemetry_proto_collector_trace_v1_trace_service_proto_init() { return nil } } + file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExportTracePartialSuccess); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -237,7 +352,7 @@ func file_opentelemetry_proto_collector_trace_v1_trace_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 1, }, diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go index 18dff3d03e7..bb1bd261ed8 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go +++ b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go @@ -13,15 +13,14 @@ import ( "io" "net/http" - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) // Suppress "imported and not used" errors @@ -30,7 +29,6 @@ var _ io.Reader var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage var _ = metadata.Join func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client TraceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -79,20 +77,22 @@ func RegisterTraceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/opentelemetry.proto.collector.trace.v1.TraceService/Export", runtime.WithHTTPPathPattern("/v1/traces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_TraceService_Export_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_TraceService_Export_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_TraceService_Export_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_TraceService_Export_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -141,19 +141,21 @@ func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/opentelemetry.proto.collector.trace.v1.TraceService/Export", runtime.WithHTTPPathPattern("/v1/traces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_TraceService_Export_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_TraceService_Export_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_TraceService_Export_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_TraceService_Export_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -161,7 +163,7 @@ func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu } var ( - pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "trace"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "traces"}, "")) ) var ( diff --git a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go index 4e4c24c0c87..dd1b73f1e99 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.1.0 +// - protoc v3.21.6 +// source: opentelemetry/proto/collector/trace/v1/trace_service.proto package v1 @@ -11,6 +15,7 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 // TraceServiceClient is the client API for TraceService service. @@ -66,7 +71,7 @@ type UnsafeTraceServiceServer interface { } func RegisterTraceServiceServer(s grpc.ServiceRegistrar, srv TraceServiceServer) { - s.RegisterService(&_TraceService_serviceDesc, srv) + s.RegisterService(&TraceService_ServiceDesc, srv) } func _TraceService_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -87,7 +92,10 @@ func _TraceService_Export_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } -var _TraceService_serviceDesc = grpc.ServiceDesc{ +// TraceService_ServiceDesc is the grpc.ServiceDesc for TraceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var TraceService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "opentelemetry.proto.collector.trace.v1.TraceService", HandlerType: (*TraceServiceServer)(nil), Methods: []grpc.MethodDesc{ diff --git a/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go b/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go index 567e55849ad..852209b097b 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 +// protoc-gen-go v1.26.0 +// protoc v3.21.6 // source: opentelemetry/proto/common/v1/common.proto package v1 import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -35,10 +34,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // AnyValue is used to represent any type of attribute value. AnyValue may contain a // primitive value such as a string or integer or it may contain an arbitrary nested // object containing arrays, key-value lists and primitives. @@ -48,7 +43,7 @@ type AnyValue struct { unknownFields protoimpl.UnknownFields // The value is one of the listed fields. It is valid for all values to be unspecified - // in which case this AnyValue is considered to be "null". + // in which case this AnyValue is considered to be "empty". // // Types that are assignable to Value: // *AnyValue_StringValue @@ -57,6 +52,7 @@ type AnyValue struct { // *AnyValue_DoubleValue // *AnyValue_ArrayValue // *AnyValue_KvlistValue + // *AnyValue_BytesValue Value isAnyValue_Value `protobuf_oneof:"value"` } @@ -141,6 +137,13 @@ func (x *AnyValue) GetKvlistValue() *KeyValueList { return nil } +func (x *AnyValue) GetBytesValue() []byte { + if x, ok := x.GetValue().(*AnyValue_BytesValue); ok { + return x.BytesValue + } + return nil +} + type isAnyValue_Value interface { isAnyValue_Value() } @@ -169,6 +172,10 @@ type AnyValue_KvlistValue struct { KvlistValue *KeyValueList `protobuf:"bytes,6,opt,name=kvlist_value,json=kvlistValue,proto3,oneof"` } +type AnyValue_BytesValue struct { + BytesValue []byte `protobuf:"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof"` +} + func (*AnyValue_StringValue) isAnyValue_Value() {} func (*AnyValue_BoolValue) isAnyValue_Value() {} @@ -181,6 +188,8 @@ func (*AnyValue_ArrayValue) isAnyValue_Value() {} func (*AnyValue_KvlistValue) isAnyValue_Value() {} +func (*AnyValue_BytesValue) isAnyValue_Value() {} + // ArrayValue is a list of AnyValue messages. We need ArrayValue as a message // since oneof in AnyValue does not allow repeated fields. type ArrayValue struct { @@ -243,6 +252,8 @@ type KeyValueList struct { // A collection of key/value pairs of key-value pairs. The list may be empty (may // contain 0 elements). + // The keys MUST be unique (it is not allowed to have more than one + // value with the same key). Values []*KeyValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` } @@ -342,19 +353,25 @@ func (x *KeyValue) GetValue() *AnyValue { return nil } -// StringKeyValue is a pair of key/value strings. This is the simpler (and faster) version -// of KeyValue that only supports string values. -type StringKeyValue struct { +// InstrumentationScope is a message representing the instrumentation scope information +// such as the fully qualified name and version. +type InstrumentationScope struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // An empty instrumentation scope name means the name is unknown. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // Additional attributes that describe the scope. [Optional]. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + Attributes []*KeyValue `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty"` + DroppedAttributesCount uint32 `protobuf:"varint,4,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3" json:"dropped_attributes_count,omitempty"` } -func (x *StringKeyValue) Reset() { - *x = StringKeyValue{} +func (x *InstrumentationScope) Reset() { + *x = InstrumentationScope{} if protoimpl.UnsafeEnabled { mi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -362,13 +379,13 @@ func (x *StringKeyValue) Reset() { } } -func (x *StringKeyValue) String() string { +func (x *InstrumentationScope) String() string { return protoimpl.X.MessageStringOf(x) } -func (*StringKeyValue) ProtoMessage() {} +func (*InstrumentationScope) ProtoMessage() {} -func (x *StringKeyValue) ProtoReflect() protoreflect.Message { +func (x *InstrumentationScope) ProtoReflect() protoreflect.Message { mi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -380,81 +397,37 @@ func (x *StringKeyValue) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use StringKeyValue.ProtoReflect.Descriptor instead. -func (*StringKeyValue) Descriptor() ([]byte, []int) { +// Deprecated: Use InstrumentationScope.ProtoReflect.Descriptor instead. +func (*InstrumentationScope) Descriptor() ([]byte, []int) { return file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{4} } -func (x *StringKeyValue) GetKey() string { +func (x *InstrumentationScope) GetName() string { if x != nil { - return x.Key + return x.Name } return "" } -func (x *StringKeyValue) GetValue() string { +func (x *InstrumentationScope) GetVersion() string { if x != nil { - return x.Value + return x.Version } return "" } -// InstrumentationLibrary is a message representing the instrumentation library information -// such as the fully qualified name and version. -type InstrumentationLibrary struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // An empty instrumentation library name means the name is unknown. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` -} - -func (x *InstrumentationLibrary) Reset() { - *x = InstrumentationLibrary{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InstrumentationLibrary) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InstrumentationLibrary) ProtoMessage() {} - -func (x *InstrumentationLibrary) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InstrumentationLibrary.ProtoReflect.Descriptor instead. -func (*InstrumentationLibrary) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{5} -} - -func (x *InstrumentationLibrary) GetName() string { +func (x *InstrumentationScope) GetAttributes() []*KeyValue { if x != nil { - return x.Name + return x.Attributes } - return "" + return nil } -func (x *InstrumentationLibrary) GetVersion() string { +func (x *InstrumentationScope) GetDroppedAttributesCount() uint32 { if x != nil { - return x.Version + return x.DroppedAttributesCount } - return "" + return 0 } var File_opentelemetry_proto_common_v1_common_proto protoreflect.FileDescriptor @@ -464,7 +437,7 @@ var file_opentelemetry_proto_common_v1_common_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0xbd, 0x02, 0x0a, 0x08, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0xe0, 0x02, 0x0a, 0x08, 0x41, 0x6e, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, @@ -484,37 +457,46 @@ var file_opentelemetry_proto_common_v1_common_proto_rawDesc = []byte{ 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6b, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4d, 0x0a, 0x0a, 0x41, - 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4d, + 0x0a, 0x0a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x06, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x4f, 0x0a, + 0x0c, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, + 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x5b, + 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc7, 0x01, 0x0a, 0x14, + 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x7b, 0x0a, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0c, 0x4b, 0x65, - 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x08, 0x4b, - 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x38, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x46, 0x0a, 0x16, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x5b, 0x0a, 0x20, 0x69, 0x6f, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0b, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, - 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, - 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, + 0x76, 0x31, 0xaa, 0x02, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -529,14 +511,13 @@ func file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP() []byte { return file_opentelemetry_proto_common_v1_common_proto_rawDescData } -var file_opentelemetry_proto_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_opentelemetry_proto_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_opentelemetry_proto_common_v1_common_proto_goTypes = []interface{}{ - (*AnyValue)(nil), // 0: opentelemetry.proto.common.v1.AnyValue - (*ArrayValue)(nil), // 1: opentelemetry.proto.common.v1.ArrayValue - (*KeyValueList)(nil), // 2: opentelemetry.proto.common.v1.KeyValueList - (*KeyValue)(nil), // 3: opentelemetry.proto.common.v1.KeyValue - (*StringKeyValue)(nil), // 4: opentelemetry.proto.common.v1.StringKeyValue - (*InstrumentationLibrary)(nil), // 5: opentelemetry.proto.common.v1.InstrumentationLibrary + (*AnyValue)(nil), // 0: opentelemetry.proto.common.v1.AnyValue + (*ArrayValue)(nil), // 1: opentelemetry.proto.common.v1.ArrayValue + (*KeyValueList)(nil), // 2: opentelemetry.proto.common.v1.KeyValueList + (*KeyValue)(nil), // 3: opentelemetry.proto.common.v1.KeyValue + (*InstrumentationScope)(nil), // 4: opentelemetry.proto.common.v1.InstrumentationScope } var file_opentelemetry_proto_common_v1_common_proto_depIdxs = []int32{ 1, // 0: opentelemetry.proto.common.v1.AnyValue.array_value:type_name -> opentelemetry.proto.common.v1.ArrayValue @@ -544,11 +525,12 @@ var file_opentelemetry_proto_common_v1_common_proto_depIdxs = []int32{ 0, // 2: opentelemetry.proto.common.v1.ArrayValue.values:type_name -> opentelemetry.proto.common.v1.AnyValue 3, // 3: opentelemetry.proto.common.v1.KeyValueList.values:type_name -> opentelemetry.proto.common.v1.KeyValue 0, // 4: opentelemetry.proto.common.v1.KeyValue.value:type_name -> opentelemetry.proto.common.v1.AnyValue - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 3, // 5: opentelemetry.proto.common.v1.InstrumentationScope.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_opentelemetry_proto_common_v1_common_proto_init() } @@ -606,19 +588,7 @@ func file_opentelemetry_proto_common_v1_common_proto_init() { } } file_opentelemetry_proto_common_v1_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringKeyValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_common_v1_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstrumentationLibrary); i { + switch v := v.(*InstrumentationScope); i { case 0: return &v.state case 1: @@ -637,6 +607,7 @@ func file_opentelemetry_proto_common_v1_common_proto_init() { (*AnyValue_DoubleValue)(nil), (*AnyValue_ArrayValue)(nil), (*AnyValue_KvlistValue)(nil), + (*AnyValue_BytesValue)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -644,7 +615,7 @@ func file_opentelemetry_proto_common_v1_common_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_opentelemetry_proto_common_v1_common_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go b/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go deleted file mode 100644 index 64364a184da..00000000000 --- a/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go +++ /dev/null @@ -1,2469 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 -// source: opentelemetry/proto/metrics/v1/metrics.proto - -package v1 - -import ( - proto "github.com/golang/protobuf/proto" - v11 "go.opentelemetry.io/proto/otlp/common/v1" - v1 "go.opentelemetry.io/proto/otlp/resource/v1" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -// AggregationTemporality defines how a metric aggregator reports aggregated -// values. It describes how those values relate to the time interval over -// which they are aggregated. -type AggregationTemporality int32 - -const ( - // UNSPECIFIED is the default AggregationTemporality, it MUST not be used. - AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED AggregationTemporality = 0 - // DELTA is an AggregationTemporality for a metric aggregator which reports - // changes since last report time. Successive metrics contain aggregation of - // values from continuous and non-overlapping intervals. - // - // The values for a DELTA metric are based only on the time interval - // associated with one measurement cycle. There is no dependency on - // previous measurements like is the case for CUMULATIVE metrics. - // - // For example, consider a system measuring the number of requests that - // it receives and reports the sum of these requests every second as a - // DELTA metric: - // - // 1. The system starts receiving at time=t_0. - // 2. A request is received, the system measures 1 request. - // 3. A request is received, the system measures 1 request. - // 4. A request is received, the system measures 1 request. - // 5. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+1 with a value of 3. - // 6. A request is received, the system measures 1 request. - // 7. A request is received, the system measures 1 request. - // 8. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0+1 to - // t_0+2 with a value of 2. - AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA AggregationTemporality = 1 - // CUMULATIVE is an AggregationTemporality for a metric aggregator which - // reports changes since a fixed start time. This means that current values - // of a CUMULATIVE metric depend on all previous measurements since the - // start time. Because of this, the sender is required to retain this state - // in some form. If this state is lost or invalidated, the CUMULATIVE metric - // values MUST be reset and a new fixed start time following the last - // reported measurement time sent MUST be used. - // - // For example, consider a system measuring the number of requests that - // it receives and reports the sum of these requests every second as a - // CUMULATIVE metric: - // - // 1. The system starts receiving at time=t_0. - // 2. A request is received, the system measures 1 request. - // 3. A request is received, the system measures 1 request. - // 4. A request is received, the system measures 1 request. - // 5. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+1 with a value of 3. - // 6. A request is received, the system measures 1 request. - // 7. A request is received, the system measures 1 request. - // 8. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_0 to - // t_0+2 with a value of 5. - // 9. The system experiences a fault and loses state. - // 10. The system recovers and resumes receiving at time=t_1. - // 11. A request is received, the system measures 1 request. - // 12. The 1 second collection cycle ends. A metric is exported for the - // number of requests received over the interval of time t_1 to - // t_0+1 with a value of 1. - // - // Note: Even though, when reporting changes since last report time, using - // CUMULATIVE is valid, it is not recommended. This may cause problems for - // systems that do not use start_time to determine when the aggregation - // value was reset (e.g. Prometheus). - AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE AggregationTemporality = 2 -) - -// Enum value maps for AggregationTemporality. -var ( - AggregationTemporality_name = map[int32]string{ - 0: "AGGREGATION_TEMPORALITY_UNSPECIFIED", - 1: "AGGREGATION_TEMPORALITY_DELTA", - 2: "AGGREGATION_TEMPORALITY_CUMULATIVE", - } - AggregationTemporality_value = map[string]int32{ - "AGGREGATION_TEMPORALITY_UNSPECIFIED": 0, - "AGGREGATION_TEMPORALITY_DELTA": 1, - "AGGREGATION_TEMPORALITY_CUMULATIVE": 2, - } -) - -func (x AggregationTemporality) Enum() *AggregationTemporality { - p := new(AggregationTemporality) - *p = x - return p -} - -func (x AggregationTemporality) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (AggregationTemporality) Descriptor() protoreflect.EnumDescriptor { - return file_opentelemetry_proto_metrics_v1_metrics_proto_enumTypes[0].Descriptor() -} - -func (AggregationTemporality) Type() protoreflect.EnumType { - return &file_opentelemetry_proto_metrics_v1_metrics_proto_enumTypes[0] -} - -func (x AggregationTemporality) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use AggregationTemporality.Descriptor instead. -func (AggregationTemporality) EnumDescriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{0} -} - -// A collection of InstrumentationLibraryMetrics from a Resource. -type ResourceMetrics struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The resource for the metrics in this message. - // If this field is not set then no resource info is known. - Resource *v1.Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` - // A list of metrics that originate from a resource. - InstrumentationLibraryMetrics []*InstrumentationLibraryMetrics `protobuf:"bytes,2,rep,name=instrumentation_library_metrics,json=instrumentationLibraryMetrics,proto3" json:"instrumentation_library_metrics,omitempty"` -} - -func (x *ResourceMetrics) Reset() { - *x = ResourceMetrics{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResourceMetrics) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResourceMetrics) ProtoMessage() {} - -func (x *ResourceMetrics) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResourceMetrics.ProtoReflect.Descriptor instead. -func (*ResourceMetrics) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{0} -} - -func (x *ResourceMetrics) GetResource() *v1.Resource { - if x != nil { - return x.Resource - } - return nil -} - -func (x *ResourceMetrics) GetInstrumentationLibraryMetrics() []*InstrumentationLibraryMetrics { - if x != nil { - return x.InstrumentationLibraryMetrics - } - return nil -} - -// A collection of Metrics produced by an InstrumentationLibrary. -type InstrumentationLibraryMetrics struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The instrumentation library information for the metrics in this message. - // Semantically when InstrumentationLibrary isn't set, it is equivalent with - // an empty instrumentation library name (unknown). - InstrumentationLibrary *v11.InstrumentationLibrary `protobuf:"bytes,1,opt,name=instrumentation_library,json=instrumentationLibrary,proto3" json:"instrumentation_library,omitempty"` - // A list of metrics that originate from an instrumentation library. - Metrics []*Metric `protobuf:"bytes,2,rep,name=metrics,proto3" json:"metrics,omitempty"` -} - -func (x *InstrumentationLibraryMetrics) Reset() { - *x = InstrumentationLibraryMetrics{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InstrumentationLibraryMetrics) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InstrumentationLibraryMetrics) ProtoMessage() {} - -func (x *InstrumentationLibraryMetrics) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InstrumentationLibraryMetrics.ProtoReflect.Descriptor instead. -func (*InstrumentationLibraryMetrics) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{1} -} - -func (x *InstrumentationLibraryMetrics) GetInstrumentationLibrary() *v11.InstrumentationLibrary { - if x != nil { - return x.InstrumentationLibrary - } - return nil -} - -func (x *InstrumentationLibraryMetrics) GetMetrics() []*Metric { - if x != nil { - return x.Metrics - } - return nil -} - -// Defines a Metric which has one or more timeseries. -// -// The data model and relation between entities is shown in the -// diagram below. Here, "DataPoint" is the term used to refer to any -// one of the specific data point value types, and "points" is the term used -// to refer to any one of the lists of points contained in the Metric. -// -// - Metric is composed of a metadata and data. -// - Metadata part contains a name, description, unit. -// - Data is one of the possible types (Gauge, Sum, Histogram, etc.). -// - DataPoint contains timestamps, labels, and one of the possible value type -// fields. -// -// Metric -// +------------+ -// |name | -// |description | -// |unit | +------------------------------------+ -// |data |---> |Gauge, Sum, Histogram, Summary, ... | -// +------------+ +------------------------------------+ -// -// Data [One of Gauge, Sum, Histogram, Summary, ...] -// +-----------+ -// |... | // Metadata about the Data. -// |points |--+ -// +-----------+ | -// | +---------------------------+ -// | |DataPoint 1 | -// v |+------+------+ +------+ | -// +-----+ ||label |label |...|label | | -// | 1 |-->||value1|value2|...|valueN| | -// +-----+ |+------+------+ +------+ | -// | . | |+-----+ | -// | . | ||value| | -// | . | |+-----+ | -// | . | +---------------------------+ -// | . | . -// | . | . -// | . | . -// | . | +---------------------------+ -// | . | |DataPoint M | -// +-----+ |+------+------+ +------+ | -// | M |-->||label |label |...|label | | -// +-----+ ||value1|value2|...|valueN| | -// |+------+------+ +------+ | -// |+-----+ | -// ||value| | -// |+-----+ | -// +---------------------------+ -// -// All DataPoint types have three common fields: -// - Labels zero or more key-value pairs associated with the data point. -// - StartTimeUnixNano MUST be set to the start of the interval when the data's -// type includes an AggregationTemporality. This field is not set otherwise. -// - TimeUnixNano MUST be set to: -// - the moment when an aggregation is reported (independent of the -// aggregation temporality). -// - the instantaneous time of the event. -type Metric struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name of the metric, including its DNS name prefix. It must be unique. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // description of the metric, which can be used in documentation. - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // unit in which the metric value is reported. Follows the format - // described by http://unitsofmeasure.org/ucum.html. - Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"` - // Data determines the aggregation type (if any) of the metric, what is the - // reported value type for the data points, as well as the relatationship to - // the time interval over which they are reported. - // - // TODO: Update table after the decision on: - // https://github.com/open-telemetry/opentelemetry-specification/issues/731. - // By default, metrics recording using the OpenTelemetry API are exported as - // (the table does not include MeasurementValueType to avoid extra rows): - // - // Instrument Type - // ---------------------------------------------- - // Counter Sum(aggregation_temporality=delta;is_monotonic=true) - // UpDownCounter Sum(aggregation_temporality=delta;is_monotonic=false) - // ValueRecorder TBD - // SumObserver Sum(aggregation_temporality=cumulative;is_monotonic=true) - // UpDownSumObserver Sum(aggregation_temporality=cumulative;is_monotonic=false) - // ValueObserver Gauge() - // - // Types that are assignable to Data: - // *Metric_IntGauge - // *Metric_DoubleGauge - // *Metric_IntSum - // *Metric_DoubleSum - // *Metric_IntHistogram - // *Metric_DoubleHistogram - // *Metric_DoubleSummary - Data isMetric_Data `protobuf_oneof:"data"` -} - -func (x *Metric) Reset() { - *x = Metric{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Metric) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Metric) ProtoMessage() {} - -func (x *Metric) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Metric.ProtoReflect.Descriptor instead. -func (*Metric) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{2} -} - -func (x *Metric) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Metric) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Metric) GetUnit() string { - if x != nil { - return x.Unit - } - return "" -} - -func (m *Metric) GetData() isMetric_Data { - if m != nil { - return m.Data - } - return nil -} - -func (x *Metric) GetIntGauge() *IntGauge { - if x, ok := x.GetData().(*Metric_IntGauge); ok { - return x.IntGauge - } - return nil -} - -func (x *Metric) GetDoubleGauge() *DoubleGauge { - if x, ok := x.GetData().(*Metric_DoubleGauge); ok { - return x.DoubleGauge - } - return nil -} - -func (x *Metric) GetIntSum() *IntSum { - if x, ok := x.GetData().(*Metric_IntSum); ok { - return x.IntSum - } - return nil -} - -func (x *Metric) GetDoubleSum() *DoubleSum { - if x, ok := x.GetData().(*Metric_DoubleSum); ok { - return x.DoubleSum - } - return nil -} - -func (x *Metric) GetIntHistogram() *IntHistogram { - if x, ok := x.GetData().(*Metric_IntHistogram); ok { - return x.IntHistogram - } - return nil -} - -func (x *Metric) GetDoubleHistogram() *DoubleHistogram { - if x, ok := x.GetData().(*Metric_DoubleHistogram); ok { - return x.DoubleHistogram - } - return nil -} - -func (x *Metric) GetDoubleSummary() *DoubleSummary { - if x, ok := x.GetData().(*Metric_DoubleSummary); ok { - return x.DoubleSummary - } - return nil -} - -type isMetric_Data interface { - isMetric_Data() -} - -type Metric_IntGauge struct { - IntGauge *IntGauge `protobuf:"bytes,4,opt,name=int_gauge,json=intGauge,proto3,oneof"` -} - -type Metric_DoubleGauge struct { - DoubleGauge *DoubleGauge `protobuf:"bytes,5,opt,name=double_gauge,json=doubleGauge,proto3,oneof"` -} - -type Metric_IntSum struct { - IntSum *IntSum `protobuf:"bytes,6,opt,name=int_sum,json=intSum,proto3,oneof"` -} - -type Metric_DoubleSum struct { - DoubleSum *DoubleSum `protobuf:"bytes,7,opt,name=double_sum,json=doubleSum,proto3,oneof"` -} - -type Metric_IntHistogram struct { - IntHistogram *IntHistogram `protobuf:"bytes,8,opt,name=int_histogram,json=intHistogram,proto3,oneof"` -} - -type Metric_DoubleHistogram struct { - DoubleHistogram *DoubleHistogram `protobuf:"bytes,9,opt,name=double_histogram,json=doubleHistogram,proto3,oneof"` -} - -type Metric_DoubleSummary struct { - DoubleSummary *DoubleSummary `protobuf:"bytes,11,opt,name=double_summary,json=doubleSummary,proto3,oneof"` -} - -func (*Metric_IntGauge) isMetric_Data() {} - -func (*Metric_DoubleGauge) isMetric_Data() {} - -func (*Metric_IntSum) isMetric_Data() {} - -func (*Metric_DoubleSum) isMetric_Data() {} - -func (*Metric_IntHistogram) isMetric_Data() {} - -func (*Metric_DoubleHistogram) isMetric_Data() {} - -func (*Metric_DoubleSummary) isMetric_Data() {} - -// Gauge represents the type of a int scalar metric that always exports the -// "current value" for every data point. It should be used for an "unknown" -// aggregation. -// -// A Gauge does not support different aggregation temporalities. Given the -// aggregation is unknown, points cannot be combined using the same -// aggregation, regardless of aggregation temporalities. Therefore, -// AggregationTemporality is not included. Consequently, this also means -// "StartTimeUnixNano" is ignored for all data points. -type IntGauge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*IntDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` -} - -func (x *IntGauge) Reset() { - *x = IntGauge{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntGauge) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntGauge) ProtoMessage() {} - -func (x *IntGauge) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntGauge.ProtoReflect.Descriptor instead. -func (*IntGauge) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{3} -} - -func (x *IntGauge) GetDataPoints() []*IntDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -// Gauge represents the type of a double scalar metric that always exports the -// "current value" for every data point. It should be used for an "unknown" -// aggregation. -// -// A Gauge does not support different aggregation temporalities. Given the -// aggregation is unknown, points cannot be combined using the same -// aggregation, regardless of aggregation temporalities. Therefore, -// AggregationTemporality is not included. Consequently, this also means -// "StartTimeUnixNano" is ignored for all data points. -type DoubleGauge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*DoubleDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` -} - -func (x *DoubleGauge) Reset() { - *x = DoubleGauge{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleGauge) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleGauge) ProtoMessage() {} - -func (x *DoubleGauge) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleGauge.ProtoReflect.Descriptor instead. -func (*DoubleGauge) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{4} -} - -func (x *DoubleGauge) GetDataPoints() []*DoubleDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -// Sum represents the type of a numeric int scalar metric that is calculated as -// a sum of all reported measurements over a time interval. -type IntSum struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*IntDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` - // aggregation_temporality describes if the aggregator reports delta changes - // since last report time, or cumulative changes since a fixed start time. - AggregationTemporality AggregationTemporality `protobuf:"varint,2,opt,name=aggregation_temporality,json=aggregationTemporality,proto3,enum=opentelemetry.proto.metrics.v1.AggregationTemporality" json:"aggregation_temporality,omitempty"` - // If "true" means that the sum is monotonic. - IsMonotonic bool `protobuf:"varint,3,opt,name=is_monotonic,json=isMonotonic,proto3" json:"is_monotonic,omitempty"` -} - -func (x *IntSum) Reset() { - *x = IntSum{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntSum) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntSum) ProtoMessage() {} - -func (x *IntSum) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntSum.ProtoReflect.Descriptor instead. -func (*IntSum) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{5} -} - -func (x *IntSum) GetDataPoints() []*IntDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -func (x *IntSum) GetAggregationTemporality() AggregationTemporality { - if x != nil { - return x.AggregationTemporality - } - return AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED -} - -func (x *IntSum) GetIsMonotonic() bool { - if x != nil { - return x.IsMonotonic - } - return false -} - -// Sum represents the type of a numeric double scalar metric that is calculated -// as a sum of all reported measurements over a time interval. -type DoubleSum struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*DoubleDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` - // aggregation_temporality describes if the aggregator reports delta changes - // since last report time, or cumulative changes since a fixed start time. - AggregationTemporality AggregationTemporality `protobuf:"varint,2,opt,name=aggregation_temporality,json=aggregationTemporality,proto3,enum=opentelemetry.proto.metrics.v1.AggregationTemporality" json:"aggregation_temporality,omitempty"` - // If "true" means that the sum is monotonic. - IsMonotonic bool `protobuf:"varint,3,opt,name=is_monotonic,json=isMonotonic,proto3" json:"is_monotonic,omitempty"` -} - -func (x *DoubleSum) Reset() { - *x = DoubleSum{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleSum) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleSum) ProtoMessage() {} - -func (x *DoubleSum) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleSum.ProtoReflect.Descriptor instead. -func (*DoubleSum) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{6} -} - -func (x *DoubleSum) GetDataPoints() []*DoubleDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -func (x *DoubleSum) GetAggregationTemporality() AggregationTemporality { - if x != nil { - return x.AggregationTemporality - } - return AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED -} - -func (x *DoubleSum) GetIsMonotonic() bool { - if x != nil { - return x.IsMonotonic - } - return false -} - -// Represents the type of a metric that is calculated by aggregating as a -// Histogram of all reported int measurements over a time interval. -type IntHistogram struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*IntHistogramDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` - // aggregation_temporality describes if the aggregator reports delta changes - // since last report time, or cumulative changes since a fixed start time. - AggregationTemporality AggregationTemporality `protobuf:"varint,2,opt,name=aggregation_temporality,json=aggregationTemporality,proto3,enum=opentelemetry.proto.metrics.v1.AggregationTemporality" json:"aggregation_temporality,omitempty"` -} - -func (x *IntHistogram) Reset() { - *x = IntHistogram{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntHistogram) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntHistogram) ProtoMessage() {} - -func (x *IntHistogram) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntHistogram.ProtoReflect.Descriptor instead. -func (*IntHistogram) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{7} -} - -func (x *IntHistogram) GetDataPoints() []*IntHistogramDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -func (x *IntHistogram) GetAggregationTemporality() AggregationTemporality { - if x != nil { - return x.AggregationTemporality - } - return AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED -} - -// Represents the type of a metric that is calculated by aggregating as a -// Histogram of all reported double measurements over a time interval. -type DoubleHistogram struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*DoubleHistogramDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` - // aggregation_temporality describes if the aggregator reports delta changes - // since last report time, or cumulative changes since a fixed start time. - AggregationTemporality AggregationTemporality `protobuf:"varint,2,opt,name=aggregation_temporality,json=aggregationTemporality,proto3,enum=opentelemetry.proto.metrics.v1.AggregationTemporality" json:"aggregation_temporality,omitempty"` -} - -func (x *DoubleHistogram) Reset() { - *x = DoubleHistogram{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleHistogram) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleHistogram) ProtoMessage() {} - -func (x *DoubleHistogram) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleHistogram.ProtoReflect.Descriptor instead. -func (*DoubleHistogram) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{8} -} - -func (x *DoubleHistogram) GetDataPoints() []*DoubleHistogramDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -func (x *DoubleHistogram) GetAggregationTemporality() AggregationTemporality { - if x != nil { - return x.AggregationTemporality - } - return AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED -} - -// DoubleSummary metric data are used to convey quantile summaries, -// a Prometheus (see: https://prometheus.io/docs/concepts/metric_types/#summary) -// and OpenMetrics (see: https://github.com/OpenObservability/OpenMetrics/blob/4dbf6075567ab43296eed941037c12951faafb92/protos/prometheus.proto#L45) -// data type. These data points cannot always be merged in a meaningful way. -// While they can be useful in some applications, histogram data points are -// recommended for new applications. -type DoubleSummary struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataPoints []*DoubleSummaryDataPoint `protobuf:"bytes,1,rep,name=data_points,json=dataPoints,proto3" json:"data_points,omitempty"` -} - -func (x *DoubleSummary) Reset() { - *x = DoubleSummary{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleSummary) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleSummary) ProtoMessage() {} - -func (x *DoubleSummary) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleSummary.ProtoReflect.Descriptor instead. -func (*DoubleSummary) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{9} -} - -func (x *DoubleSummary) GetDataPoints() []*DoubleSummaryDataPoint { - if x != nil { - return x.DataPoints - } - return nil -} - -// IntDataPoint is a single data point in a timeseries that describes the -// time-varying values of a int64 metric. -type IntDataPoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that uniquely identify this timeseries. - Labels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - // start_time_unix_nano is the last time when the aggregation value was reset - // to "zero". For some metric types this is ignored, see data types for more - // details. - // - // The aggregation value is over the time interval (start_time_unix_nano, - // time_unix_nano]. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the - // timestamp may be decided by the backend. - StartTimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3" json:"start_time_unix_nano,omitempty"` - // time_unix_nano is the moment when this aggregation value was reported. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,3,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // value itself. - Value int64 `protobuf:"fixed64,4,opt,name=value,proto3" json:"value,omitempty"` - // (Optional) List of exemplars collected from - // measurements that were used to form the data point - Exemplars []*IntExemplar `protobuf:"bytes,5,rep,name=exemplars,proto3" json:"exemplars,omitempty"` -} - -func (x *IntDataPoint) Reset() { - *x = IntDataPoint{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntDataPoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntDataPoint) ProtoMessage() {} - -func (x *IntDataPoint) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntDataPoint.ProtoReflect.Descriptor instead. -func (*IntDataPoint) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{10} -} - -func (x *IntDataPoint) GetLabels() []*v11.StringKeyValue { - if x != nil { - return x.Labels - } - return nil -} - -func (x *IntDataPoint) GetStartTimeUnixNano() uint64 { - if x != nil { - return x.StartTimeUnixNano - } - return 0 -} - -func (x *IntDataPoint) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *IntDataPoint) GetValue() int64 { - if x != nil { - return x.Value - } - return 0 -} - -func (x *IntDataPoint) GetExemplars() []*IntExemplar { - if x != nil { - return x.Exemplars - } - return nil -} - -// DoubleDataPoint is a single data point in a timeseries that describes the -// time-varying value of a double metric. -type DoubleDataPoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that uniquely identify this timeseries. - Labels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - // start_time_unix_nano is the last time when the aggregation value was reset - // to "zero". For some metric types this is ignored, see data types for more - // details. - // - // The aggregation value is over the time interval (start_time_unix_nano, - // time_unix_nano]. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the - // timestamp may be decided by the backend. - StartTimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3" json:"start_time_unix_nano,omitempty"` - // time_unix_nano is the moment when this aggregation value was reported. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,3,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // value itself. - Value float64 `protobuf:"fixed64,4,opt,name=value,proto3" json:"value,omitempty"` - // (Optional) List of exemplars collected from - // measurements that were used to form the data point - Exemplars []*DoubleExemplar `protobuf:"bytes,5,rep,name=exemplars,proto3" json:"exemplars,omitempty"` -} - -func (x *DoubleDataPoint) Reset() { - *x = DoubleDataPoint{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleDataPoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleDataPoint) ProtoMessage() {} - -func (x *DoubleDataPoint) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleDataPoint.ProtoReflect.Descriptor instead. -func (*DoubleDataPoint) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{11} -} - -func (x *DoubleDataPoint) GetLabels() []*v11.StringKeyValue { - if x != nil { - return x.Labels - } - return nil -} - -func (x *DoubleDataPoint) GetStartTimeUnixNano() uint64 { - if x != nil { - return x.StartTimeUnixNano - } - return 0 -} - -func (x *DoubleDataPoint) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *DoubleDataPoint) GetValue() float64 { - if x != nil { - return x.Value - } - return 0 -} - -func (x *DoubleDataPoint) GetExemplars() []*DoubleExemplar { - if x != nil { - return x.Exemplars - } - return nil -} - -// IntHistogramDataPoint is a single data point in a timeseries that describes -// the time-varying values of a Histogram of int values. A Histogram contains -// summary statistics for a population of values, it may optionally contain -// the distribution of those values across a set of buckets. -type IntHistogramDataPoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that uniquely identify this timeseries. - Labels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - // start_time_unix_nano is the last time when the aggregation value was reset - // to "zero". For some metric types this is ignored, see data types for more - // details. - // - // The aggregation value is over the time interval (start_time_unix_nano, - // time_unix_nano]. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the - // timestamp may be decided by the backend. - StartTimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3" json:"start_time_unix_nano,omitempty"` - // time_unix_nano is the moment when this aggregation value was reported. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,3,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // count is the number of values in the population. Must be non-negative. This - // value must be equal to the sum of the "count" fields in buckets if a - // histogram is provided. - Count uint64 `protobuf:"fixed64,4,opt,name=count,proto3" json:"count,omitempty"` - // sum of the values in the population. If count is zero then this field - // must be zero. This value must be equal to the sum of the "sum" fields in - // buckets if a histogram is provided. - Sum int64 `protobuf:"fixed64,5,opt,name=sum,proto3" json:"sum,omitempty"` - // bucket_counts is an optional field contains the count values of histogram - // for each bucket. - // - // The sum of the bucket_counts must equal the value in the count field. - // - // The number of elements in bucket_counts array must be by one greater than - // the number of elements in explicit_bounds array. - BucketCounts []uint64 `protobuf:"fixed64,6,rep,packed,name=bucket_counts,json=bucketCounts,proto3" json:"bucket_counts,omitempty"` - // explicit_bounds specifies buckets with explicitly defined bounds for values. - // The bucket boundaries are described by "bounds" field. - // - // This defines size(bounds) + 1 (= N) buckets. The boundaries for bucket - // at index i are: - // - // (-infinity, bounds[i]) for i == 0 - // [bounds[i-1], bounds[i]) for 0 < i < N-1 - // [bounds[i], +infinity) for i == N-1 - // The values in bounds array must be strictly increasing. - // - // Note: only [a, b) intervals are currently supported for each bucket except the first one. - // If we decide to also support (a, b] intervals we should add support for these by defining - // a boolean value which decides what type of intervals to use. - ExplicitBounds []float64 `protobuf:"fixed64,7,rep,packed,name=explicit_bounds,json=explicitBounds,proto3" json:"explicit_bounds,omitempty"` - // (Optional) List of exemplars collected from - // measurements that were used to form the data point - Exemplars []*IntExemplar `protobuf:"bytes,8,rep,name=exemplars,proto3" json:"exemplars,omitempty"` -} - -func (x *IntHistogramDataPoint) Reset() { - *x = IntHistogramDataPoint{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntHistogramDataPoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntHistogramDataPoint) ProtoMessage() {} - -func (x *IntHistogramDataPoint) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntHistogramDataPoint.ProtoReflect.Descriptor instead. -func (*IntHistogramDataPoint) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{12} -} - -func (x *IntHistogramDataPoint) GetLabels() []*v11.StringKeyValue { - if x != nil { - return x.Labels - } - return nil -} - -func (x *IntHistogramDataPoint) GetStartTimeUnixNano() uint64 { - if x != nil { - return x.StartTimeUnixNano - } - return 0 -} - -func (x *IntHistogramDataPoint) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *IntHistogramDataPoint) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -func (x *IntHistogramDataPoint) GetSum() int64 { - if x != nil { - return x.Sum - } - return 0 -} - -func (x *IntHistogramDataPoint) GetBucketCounts() []uint64 { - if x != nil { - return x.BucketCounts - } - return nil -} - -func (x *IntHistogramDataPoint) GetExplicitBounds() []float64 { - if x != nil { - return x.ExplicitBounds - } - return nil -} - -func (x *IntHistogramDataPoint) GetExemplars() []*IntExemplar { - if x != nil { - return x.Exemplars - } - return nil -} - -// HistogramDataPoint is a single data point in a timeseries that describes the -// time-varying values of a Histogram of double values. A Histogram contains -// summary statistics for a population of values, it may optionally contain the -// distribution of those values across a set of buckets. -type DoubleHistogramDataPoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that uniquely identify this timeseries. - Labels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - // start_time_unix_nano is the last time when the aggregation value was reset - // to "zero". For some metric types this is ignored, see data types for more - // details. - // - // The aggregation value is over the time interval (start_time_unix_nano, - // time_unix_nano]. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the - // timestamp may be decided by the backend. - StartTimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3" json:"start_time_unix_nano,omitempty"` - // time_unix_nano is the moment when this aggregation value was reported. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,3,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // count is the number of values in the population. Must be non-negative. This - // value must be equal to the sum of the "count" fields in buckets if a - // histogram is provided. - Count uint64 `protobuf:"fixed64,4,opt,name=count,proto3" json:"count,omitempty"` - // sum of the values in the population. If count is zero then this field - // must be zero. This value must be equal to the sum of the "sum" fields in - // buckets if a histogram is provided. - Sum float64 `protobuf:"fixed64,5,opt,name=sum,proto3" json:"sum,omitempty"` - // bucket_counts is an optional field contains the count values of histogram - // for each bucket. - // - // The sum of the bucket_counts must equal the value in the count field. - // - // The number of elements in bucket_counts array must be by one greater than - // the number of elements in explicit_bounds array. - BucketCounts []uint64 `protobuf:"fixed64,6,rep,packed,name=bucket_counts,json=bucketCounts,proto3" json:"bucket_counts,omitempty"` - // explicit_bounds specifies buckets with explicitly defined bounds for values. - // The bucket boundaries are described by "bounds" field. - // - // This defines size(bounds) + 1 (= N) buckets. The boundaries for bucket - // at index i are: - // - // (-infinity, bounds[i]) for i == 0 - // [bounds[i-1], bounds[i]) for 0 < i < N-1 - // [bounds[i], +infinity) for i == N-1 - // The values in bounds array must be strictly increasing. - // - // Note: only [a, b) intervals are currently supported for each bucket except the first one. - // If we decide to also support (a, b] intervals we should add support for these by defining - // a boolean value which decides what type of intervals to use. - ExplicitBounds []float64 `protobuf:"fixed64,7,rep,packed,name=explicit_bounds,json=explicitBounds,proto3" json:"explicit_bounds,omitempty"` - // (Optional) List of exemplars collected from - // measurements that were used to form the data point - Exemplars []*DoubleExemplar `protobuf:"bytes,8,rep,name=exemplars,proto3" json:"exemplars,omitempty"` -} - -func (x *DoubleHistogramDataPoint) Reset() { - *x = DoubleHistogramDataPoint{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleHistogramDataPoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleHistogramDataPoint) ProtoMessage() {} - -func (x *DoubleHistogramDataPoint) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleHistogramDataPoint.ProtoReflect.Descriptor instead. -func (*DoubleHistogramDataPoint) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{13} -} - -func (x *DoubleHistogramDataPoint) GetLabels() []*v11.StringKeyValue { - if x != nil { - return x.Labels - } - return nil -} - -func (x *DoubleHistogramDataPoint) GetStartTimeUnixNano() uint64 { - if x != nil { - return x.StartTimeUnixNano - } - return 0 -} - -func (x *DoubleHistogramDataPoint) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *DoubleHistogramDataPoint) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -func (x *DoubleHistogramDataPoint) GetSum() float64 { - if x != nil { - return x.Sum - } - return 0 -} - -func (x *DoubleHistogramDataPoint) GetBucketCounts() []uint64 { - if x != nil { - return x.BucketCounts - } - return nil -} - -func (x *DoubleHistogramDataPoint) GetExplicitBounds() []float64 { - if x != nil { - return x.ExplicitBounds - } - return nil -} - -func (x *DoubleHistogramDataPoint) GetExemplars() []*DoubleExemplar { - if x != nil { - return x.Exemplars - } - return nil -} - -// DoubleSummaryDataPoint is a single data point in a timeseries that describes the -// time-varying values of a Summary metric. -type DoubleSummaryDataPoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that uniquely identify this timeseries. - Labels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - // start_time_unix_nano is the last time when the aggregation value was reset - // to "zero". For some metric types this is ignored, see data types for more - // details. - // - // The aggregation value is over the time interval (start_time_unix_nano, - // time_unix_nano]. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - // - // Value of 0 indicates that the timestamp is unspecified. In that case the - // timestamp may be decided by the backend. - StartTimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3" json:"start_time_unix_nano,omitempty"` - // time_unix_nano is the moment when this aggregation value was reported. - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,3,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // count is the number of values in the population. Must be non-negative. - Count uint64 `protobuf:"fixed64,4,opt,name=count,proto3" json:"count,omitempty"` - // sum of the values in the population. If count is zero then this field - // must be zero. - Sum float64 `protobuf:"fixed64,5,opt,name=sum,proto3" json:"sum,omitempty"` - // (Optional) list of values at different quantiles of the distribution calculated - // from the current snapshot. The quantiles must be strictly increasing. - QuantileValues []*DoubleSummaryDataPoint_ValueAtQuantile `protobuf:"bytes,6,rep,name=quantile_values,json=quantileValues,proto3" json:"quantile_values,omitempty"` -} - -func (x *DoubleSummaryDataPoint) Reset() { - *x = DoubleSummaryDataPoint{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleSummaryDataPoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleSummaryDataPoint) ProtoMessage() {} - -func (x *DoubleSummaryDataPoint) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleSummaryDataPoint.ProtoReflect.Descriptor instead. -func (*DoubleSummaryDataPoint) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{14} -} - -func (x *DoubleSummaryDataPoint) GetLabels() []*v11.StringKeyValue { - if x != nil { - return x.Labels - } - return nil -} - -func (x *DoubleSummaryDataPoint) GetStartTimeUnixNano() uint64 { - if x != nil { - return x.StartTimeUnixNano - } - return 0 -} - -func (x *DoubleSummaryDataPoint) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *DoubleSummaryDataPoint) GetCount() uint64 { - if x != nil { - return x.Count - } - return 0 -} - -func (x *DoubleSummaryDataPoint) GetSum() float64 { - if x != nil { - return x.Sum - } - return 0 -} - -func (x *DoubleSummaryDataPoint) GetQuantileValues() []*DoubleSummaryDataPoint_ValueAtQuantile { - if x != nil { - return x.QuantileValues - } - return nil -} - -// A representation of an exemplar, which is a sample input int measurement. -// Exemplars also hold information about the environment when the measurement -// was recorded, for example the span and trace ID of the active span when the -// exemplar was recorded. -type IntExemplar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that were filtered out by the aggregator, but recorded - // alongside the original measurement. Only labels that were filtered out - // by the aggregator should be included - FilteredLabels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=filtered_labels,json=filteredLabels,proto3" json:"filtered_labels,omitempty"` - // time_unix_nano is the exact time when this exemplar was recorded - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // Numerical int value of the measurement that was recorded. - Value int64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"` - // (Optional) Span ID of the exemplar trace. - // span_id may be missing if the measurement is not recorded inside a trace - // or if the trace is not sampled. - SpanId []byte `protobuf:"bytes,4,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` - // (Optional) Trace ID of the exemplar trace. - // trace_id may be missing if the measurement is not recorded inside a trace - // or if the trace is not sampled. - TraceId []byte `protobuf:"bytes,5,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` -} - -func (x *IntExemplar) Reset() { - *x = IntExemplar{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntExemplar) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntExemplar) ProtoMessage() {} - -func (x *IntExemplar) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntExemplar.ProtoReflect.Descriptor instead. -func (*IntExemplar) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{15} -} - -func (x *IntExemplar) GetFilteredLabels() []*v11.StringKeyValue { - if x != nil { - return x.FilteredLabels - } - return nil -} - -func (x *IntExemplar) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *IntExemplar) GetValue() int64 { - if x != nil { - return x.Value - } - return 0 -} - -func (x *IntExemplar) GetSpanId() []byte { - if x != nil { - return x.SpanId - } - return nil -} - -func (x *IntExemplar) GetTraceId() []byte { - if x != nil { - return x.TraceId - } - return nil -} - -// A representation of an exemplar, which is a sample input double measurement. -// Exemplars also hold information about the environment when the measurement -// was recorded, for example the span and trace ID of the active span when the -// exemplar was recorded. -type DoubleExemplar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The set of labels that were filtered out by the aggregator, but recorded - // alongside the original measurement. Only labels that were filtered out - // by the aggregator should be included - FilteredLabels []*v11.StringKeyValue `protobuf:"bytes,1,rep,name=filtered_labels,json=filteredLabels,proto3" json:"filtered_labels,omitempty"` - // time_unix_nano is the exact time when this exemplar was recorded - // - // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - // 1970. - TimeUnixNano uint64 `protobuf:"fixed64,2,opt,name=time_unix_nano,json=timeUnixNano,proto3" json:"time_unix_nano,omitempty"` - // Numerical double value of the measurement that was recorded. - Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"` - // (Optional) Span ID of the exemplar trace. - // span_id may be missing if the measurement is not recorded inside a trace - // or if the trace is not sampled. - SpanId []byte `protobuf:"bytes,4,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` - // (Optional) Trace ID of the exemplar trace. - // trace_id may be missing if the measurement is not recorded inside a trace - // or if the trace is not sampled. - TraceId []byte `protobuf:"bytes,5,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` -} - -func (x *DoubleExemplar) Reset() { - *x = DoubleExemplar{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleExemplar) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleExemplar) ProtoMessage() {} - -func (x *DoubleExemplar) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleExemplar.ProtoReflect.Descriptor instead. -func (*DoubleExemplar) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{16} -} - -func (x *DoubleExemplar) GetFilteredLabels() []*v11.StringKeyValue { - if x != nil { - return x.FilteredLabels - } - return nil -} - -func (x *DoubleExemplar) GetTimeUnixNano() uint64 { - if x != nil { - return x.TimeUnixNano - } - return 0 -} - -func (x *DoubleExemplar) GetValue() float64 { - if x != nil { - return x.Value - } - return 0 -} - -func (x *DoubleExemplar) GetSpanId() []byte { - if x != nil { - return x.SpanId - } - return nil -} - -func (x *DoubleExemplar) GetTraceId() []byte { - if x != nil { - return x.TraceId - } - return nil -} - -// Represents the value at a given quantile of a distribution. -// -// To record Min and Max values following conventions are used: -// - The 1.0 quantile is equivalent to the maximum value observed. -// - The 0.0 quantile is equivalent to the minimum value observed. -// -// See the following issue for more context: -// https://github.com/open-telemetry/opentelemetry-proto/issues/125 -type DoubleSummaryDataPoint_ValueAtQuantile struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The quantile of a distribution. Must be in the interval - // [0.0, 1.0]. - Quantile float64 `protobuf:"fixed64,1,opt,name=quantile,proto3" json:"quantile,omitempty"` - // The value at the given quantile of a distribution. - Value float64 `protobuf:"fixed64,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *DoubleSummaryDataPoint_ValueAtQuantile) Reset() { - *x = DoubleSummaryDataPoint_ValueAtQuantile{} - if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DoubleSummaryDataPoint_ValueAtQuantile) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DoubleSummaryDataPoint_ValueAtQuantile) ProtoMessage() {} - -func (x *DoubleSummaryDataPoint_ValueAtQuantile) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DoubleSummaryDataPoint_ValueAtQuantile.ProtoReflect.Descriptor instead. -func (*DoubleSummaryDataPoint_ValueAtQuantile) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP(), []int{14, 0} -} - -func (x *DoubleSummaryDataPoint_ValueAtQuantile) GetQuantile() float64 { - if x != nil { - return x.Quantile - } - return 0 -} - -func (x *DoubleSummaryDataPoint_ValueAtQuantile) GetValue() float64 { - if x != nil { - return x.Value - } - return 0 -} - -var File_opentelemetry_proto_metrics_v1_metrics_proto protoreflect.FileDescriptor - -var file_opentelemetry_proto_metrics_v1_metrics_proto_rawDesc = []byte{ - 0x0a, 0x2c, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, - 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x2a, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x01, 0x0a, 0x0f, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x45, - 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x1f, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, - 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x1d, - 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0xd1, 0x01, - 0x0a, 0x1d, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, - 0x6e, 0x0a, 0x17, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x35, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, - 0x40, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x26, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x22, 0x8f, 0x05, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x47, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x61, - 0x75, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x47, 0x61, - 0x75, 0x67, 0x65, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, - 0x50, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x67, 0x61, 0x75, 0x67, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x47, 0x61, 0x75, - 0x67, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x47, 0x61, 0x75, 0x67, - 0x65, 0x12, 0x41, 0x0a, 0x07, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, - 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x53, 0x75, 0x6d, 0x48, 0x00, 0x52, 0x06, 0x69, 0x6e, - 0x74, 0x53, 0x75, 0x6d, 0x12, 0x4a, 0x0a, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x73, - 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x53, 0x75, 0x6d, 0x48, 0x00, 0x52, 0x09, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, - 0x12, 0x53, 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x5c, 0x0a, 0x10, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, - 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, - 0x48, 0x00, 0x52, 0x0f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, - 0x72, 0x61, 0x6d, 0x12, 0x56, 0x0a, 0x0e, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x6f, - 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x22, 0x59, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, - 0x4d, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x5f, - 0x0a, 0x0b, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, 0x50, 0x0a, - 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, - 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, - 0xeb, 0x01, 0x0a, 0x06, 0x49, 0x6e, 0x74, 0x53, 0x75, 0x6d, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x61, - 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x64, - 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x6f, 0x0a, 0x17, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x52, 0x16, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, - 0x5f, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x22, 0xf1, 0x01, - 0x0a, 0x09, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x50, 0x0a, 0x0b, 0x64, - 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, - 0x74, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x6f, 0x0a, - 0x17, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x6f, - 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x16, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x21, - 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, - 0x63, 0x22, 0xd7, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, - 0x61, 0x6d, 0x12, 0x56, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, - 0x64, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x6f, 0x0a, 0x17, 0x61, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x52, 0x16, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xdd, 0x01, 0x0a, 0x0f, - 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, - 0x59, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, - 0x64, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x6f, 0x0a, 0x17, 0x61, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x52, 0x16, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x68, 0x0a, 0x0d, 0x44, - 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x57, 0x0a, 0x0b, - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x36, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x50, - 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x8d, 0x02, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x44, 0x61, 0x74, - 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2f, 0x0a, - 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, - 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x24, - 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, - 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x10, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x09, 0x65, 0x78, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, - 0x6e, 0x74, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x09, 0x65, 0x78, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x72, 0x73, 0x22, 0x93, 0x02, 0x0a, 0x0f, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, - 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, - 0x6f, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, - 0x61, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, - 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4c, 0x0a, - 0x09, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, - 0x52, 0x09, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x22, 0xf6, 0x02, 0x0a, 0x15, - 0x49, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, - 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, - 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x14, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x24, 0x0a, - 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, - 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x06, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x6d, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x10, 0x52, 0x03, 0x73, 0x75, 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x62, - 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x06, 0x52, 0x0c, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x49, 0x0a, 0x09, 0x65, 0x78, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x74, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x09, 0x65, 0x78, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x72, 0x73, 0x22, 0xfc, 0x02, 0x0a, 0x18, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, - 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x06, 0x52, 0x05, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x03, 0x73, 0x75, 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x63, 0x6b, 0x65, - 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x06, 0x52, 0x0c, - 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0f, - 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, - 0x07, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x42, - 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x09, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x72, 0x73, 0x22, 0x94, 0x03, 0x0a, 0x16, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x45, - 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, - 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, - 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, - 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x06, 0x52, 0x05, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x03, 0x73, 0x75, 0x6d, 0x12, 0x6f, 0x0a, 0x0f, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, - 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x41, 0x74, 0x51, 0x75, 0x61, - 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x52, 0x0e, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x43, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x41, 0x74, - 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, - 0x74, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, - 0x74, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x0b, 0x49, - 0x6e, 0x74, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12, 0x56, 0x0a, 0x0f, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, - 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x10, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x49, 0x64, 0x22, 0xd8, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12, 0x56, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, - 0x64, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x24, 0x0a, - 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, - 0x61, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, - 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x2a, 0x8c, 0x01, - 0x0a, 0x16, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x23, 0x41, 0x47, 0x47, 0x52, - 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, 0x4c, - 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x45, 0x4c, - 0x54, 0x41, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x5f, - 0x43, 0x55, 0x4d, 0x55, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x42, 0x5e, 0x0a, 0x21, - 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x42, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x29, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, - 0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescOnce sync.Once - file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescData = file_opentelemetry_proto_metrics_v1_metrics_proto_rawDesc -) - -func file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescGZIP() []byte { - file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescOnce.Do(func() { - file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescData) - }) - return file_opentelemetry_proto_metrics_v1_metrics_proto_rawDescData -} - -var file_opentelemetry_proto_metrics_v1_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 18) -var file_opentelemetry_proto_metrics_v1_metrics_proto_goTypes = []interface{}{ - (AggregationTemporality)(0), // 0: opentelemetry.proto.metrics.v1.AggregationTemporality - (*ResourceMetrics)(nil), // 1: opentelemetry.proto.metrics.v1.ResourceMetrics - (*InstrumentationLibraryMetrics)(nil), // 2: opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics - (*Metric)(nil), // 3: opentelemetry.proto.metrics.v1.Metric - (*IntGauge)(nil), // 4: opentelemetry.proto.metrics.v1.IntGauge - (*DoubleGauge)(nil), // 5: opentelemetry.proto.metrics.v1.DoubleGauge - (*IntSum)(nil), // 6: opentelemetry.proto.metrics.v1.IntSum - (*DoubleSum)(nil), // 7: opentelemetry.proto.metrics.v1.DoubleSum - (*IntHistogram)(nil), // 8: opentelemetry.proto.metrics.v1.IntHistogram - (*DoubleHistogram)(nil), // 9: opentelemetry.proto.metrics.v1.DoubleHistogram - (*DoubleSummary)(nil), // 10: opentelemetry.proto.metrics.v1.DoubleSummary - (*IntDataPoint)(nil), // 11: opentelemetry.proto.metrics.v1.IntDataPoint - (*DoubleDataPoint)(nil), // 12: opentelemetry.proto.metrics.v1.DoubleDataPoint - (*IntHistogramDataPoint)(nil), // 13: opentelemetry.proto.metrics.v1.IntHistogramDataPoint - (*DoubleHistogramDataPoint)(nil), // 14: opentelemetry.proto.metrics.v1.DoubleHistogramDataPoint - (*DoubleSummaryDataPoint)(nil), // 15: opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint - (*IntExemplar)(nil), // 16: opentelemetry.proto.metrics.v1.IntExemplar - (*DoubleExemplar)(nil), // 17: opentelemetry.proto.metrics.v1.DoubleExemplar - (*DoubleSummaryDataPoint_ValueAtQuantile)(nil), // 18: opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint.ValueAtQuantile - (*v1.Resource)(nil), // 19: opentelemetry.proto.resource.v1.Resource - (*v11.InstrumentationLibrary)(nil), // 20: opentelemetry.proto.common.v1.InstrumentationLibrary - (*v11.StringKeyValue)(nil), // 21: opentelemetry.proto.common.v1.StringKeyValue -} -var file_opentelemetry_proto_metrics_v1_metrics_proto_depIdxs = []int32{ - 19, // 0: opentelemetry.proto.metrics.v1.ResourceMetrics.resource:type_name -> opentelemetry.proto.resource.v1.Resource - 2, // 1: opentelemetry.proto.metrics.v1.ResourceMetrics.instrumentation_library_metrics:type_name -> opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics - 20, // 2: opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics.instrumentation_library:type_name -> opentelemetry.proto.common.v1.InstrumentationLibrary - 3, // 3: opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics.metrics:type_name -> opentelemetry.proto.metrics.v1.Metric - 4, // 4: opentelemetry.proto.metrics.v1.Metric.int_gauge:type_name -> opentelemetry.proto.metrics.v1.IntGauge - 5, // 5: opentelemetry.proto.metrics.v1.Metric.double_gauge:type_name -> opentelemetry.proto.metrics.v1.DoubleGauge - 6, // 6: opentelemetry.proto.metrics.v1.Metric.int_sum:type_name -> opentelemetry.proto.metrics.v1.IntSum - 7, // 7: opentelemetry.proto.metrics.v1.Metric.double_sum:type_name -> opentelemetry.proto.metrics.v1.DoubleSum - 8, // 8: opentelemetry.proto.metrics.v1.Metric.int_histogram:type_name -> opentelemetry.proto.metrics.v1.IntHistogram - 9, // 9: opentelemetry.proto.metrics.v1.Metric.double_histogram:type_name -> opentelemetry.proto.metrics.v1.DoubleHistogram - 10, // 10: opentelemetry.proto.metrics.v1.Metric.double_summary:type_name -> opentelemetry.proto.metrics.v1.DoubleSummary - 11, // 11: opentelemetry.proto.metrics.v1.IntGauge.data_points:type_name -> opentelemetry.proto.metrics.v1.IntDataPoint - 12, // 12: opentelemetry.proto.metrics.v1.DoubleGauge.data_points:type_name -> opentelemetry.proto.metrics.v1.DoubleDataPoint - 11, // 13: opentelemetry.proto.metrics.v1.IntSum.data_points:type_name -> opentelemetry.proto.metrics.v1.IntDataPoint - 0, // 14: opentelemetry.proto.metrics.v1.IntSum.aggregation_temporality:type_name -> opentelemetry.proto.metrics.v1.AggregationTemporality - 12, // 15: opentelemetry.proto.metrics.v1.DoubleSum.data_points:type_name -> opentelemetry.proto.metrics.v1.DoubleDataPoint - 0, // 16: opentelemetry.proto.metrics.v1.DoubleSum.aggregation_temporality:type_name -> opentelemetry.proto.metrics.v1.AggregationTemporality - 13, // 17: opentelemetry.proto.metrics.v1.IntHistogram.data_points:type_name -> opentelemetry.proto.metrics.v1.IntHistogramDataPoint - 0, // 18: opentelemetry.proto.metrics.v1.IntHistogram.aggregation_temporality:type_name -> opentelemetry.proto.metrics.v1.AggregationTemporality - 14, // 19: opentelemetry.proto.metrics.v1.DoubleHistogram.data_points:type_name -> opentelemetry.proto.metrics.v1.DoubleHistogramDataPoint - 0, // 20: opentelemetry.proto.metrics.v1.DoubleHistogram.aggregation_temporality:type_name -> opentelemetry.proto.metrics.v1.AggregationTemporality - 15, // 21: opentelemetry.proto.metrics.v1.DoubleSummary.data_points:type_name -> opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint - 21, // 22: opentelemetry.proto.metrics.v1.IntDataPoint.labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 16, // 23: opentelemetry.proto.metrics.v1.IntDataPoint.exemplars:type_name -> opentelemetry.proto.metrics.v1.IntExemplar - 21, // 24: opentelemetry.proto.metrics.v1.DoubleDataPoint.labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 17, // 25: opentelemetry.proto.metrics.v1.DoubleDataPoint.exemplars:type_name -> opentelemetry.proto.metrics.v1.DoubleExemplar - 21, // 26: opentelemetry.proto.metrics.v1.IntHistogramDataPoint.labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 16, // 27: opentelemetry.proto.metrics.v1.IntHistogramDataPoint.exemplars:type_name -> opentelemetry.proto.metrics.v1.IntExemplar - 21, // 28: opentelemetry.proto.metrics.v1.DoubleHistogramDataPoint.labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 17, // 29: opentelemetry.proto.metrics.v1.DoubleHistogramDataPoint.exemplars:type_name -> opentelemetry.proto.metrics.v1.DoubleExemplar - 21, // 30: opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint.labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 18, // 31: opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint.quantile_values:type_name -> opentelemetry.proto.metrics.v1.DoubleSummaryDataPoint.ValueAtQuantile - 21, // 32: opentelemetry.proto.metrics.v1.IntExemplar.filtered_labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 21, // 33: opentelemetry.proto.metrics.v1.DoubleExemplar.filtered_labels:type_name -> opentelemetry.proto.common.v1.StringKeyValue - 34, // [34:34] is the sub-list for method output_type - 34, // [34:34] is the sub-list for method input_type - 34, // [34:34] is the sub-list for extension type_name - 34, // [34:34] is the sub-list for extension extendee - 0, // [0:34] is the sub-list for field type_name -} - -func init() { file_opentelemetry_proto_metrics_v1_metrics_proto_init() } -func file_opentelemetry_proto_metrics_v1_metrics_proto_init() { - if File_opentelemetry_proto_metrics_v1_metrics_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceMetrics); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstrumentationLibraryMetrics); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metric); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntGauge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleGauge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntSum); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleSum); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntHistogram); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleHistogram); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleSummary); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntDataPoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleDataPoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntHistogramDataPoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleHistogramDataPoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleSummaryDataPoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntExemplar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleExemplar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleSummaryDataPoint_ValueAtQuantile); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*Metric_IntGauge)(nil), - (*Metric_DoubleGauge)(nil), - (*Metric_IntSum)(nil), - (*Metric_DoubleSum)(nil), - (*Metric_IntHistogram)(nil), - (*Metric_DoubleHistogram)(nil), - (*Metric_DoubleSummary)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_opentelemetry_proto_metrics_v1_metrics_proto_rawDesc, - NumEnums: 1, - NumMessages: 18, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_opentelemetry_proto_metrics_v1_metrics_proto_goTypes, - DependencyIndexes: file_opentelemetry_proto_metrics_v1_metrics_proto_depIdxs, - EnumInfos: file_opentelemetry_proto_metrics_v1_metrics_proto_enumTypes, - MessageInfos: file_opentelemetry_proto_metrics_v1_metrics_proto_msgTypes, - }.Build() - File_opentelemetry_proto_metrics_v1_metrics_proto = out.File - file_opentelemetry_proto_metrics_v1_metrics_proto_rawDesc = nil - file_opentelemetry_proto_metrics_v1_metrics_proto_goTypes = nil - file_opentelemetry_proto_metrics_v1_metrics_proto_depIdxs = nil -} diff --git a/vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go b/vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go index ac347acb233..b7545b03b9f 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 +// protoc-gen-go v1.26.0 +// protoc v3.21.6 // source: opentelemetry/proto/resource/v1/resource.proto package v1 import ( - proto "github.com/golang/protobuf/proto" v1 "go.opentelemetry.io/proto/otlp/common/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -36,17 +35,15 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Resource information. type Resource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Set of labels that describe the resource. + // Set of attributes that describe the resource. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). Attributes []*v1.KeyValue `protobuf:"bytes,1,rep,name=attributes,proto3" json:"attributes,omitempty"` // dropped_attributes_count is the number of dropped attributes. If the value is 0, then // no attributes were dropped. @@ -118,14 +115,16 @@ var file_opentelemetry_proto_resource_v1_resource_proto_rawDesc = []byte{ 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x61, 0x0a, - 0x22, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, - 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x83, 0x01, + 0x0a, 0x22, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, + 0x31, 0xaa, 0x02, 0x1f, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, + 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go b/vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go index f37084af884..51a499816a6 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go @@ -14,14 +14,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.13.0 +// protoc-gen-go v1.26.0 +// protoc v3.21.6 // source: opentelemetry/proto/trace/v1/trace.proto package v1 import ( - proto "github.com/golang/protobuf/proto" v11 "go.opentelemetry.io/proto/otlp/common/v1" v1 "go.opentelemetry.io/proto/otlp/resource/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -37,10 +36,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // SpanKind is the type of span. Can be used to specify additional relationships between spans // in addition to a parent/child relationship. type Span_SpanKind int32 @@ -50,7 +45,7 @@ const ( // Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. Span_SPAN_KIND_UNSPECIFIED Span_SpanKind = 0 // Indicates that the span represents an internal operation within an application, - // as opposed to an operations happening at the boundaries. Default value. + // as opposed to an operation happening at the boundaries. Default value. Span_SPAN_KIND_INTERNAL Span_SpanKind = 1 // Indicates that the span covers server-side handling of an RPC or other // remote network request. @@ -112,109 +107,18 @@ func (x Span_SpanKind) Number() protoreflect.EnumNumber { // Deprecated: Use Span_SpanKind.Descriptor instead. func (Span_SpanKind) EnumDescriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2, 0} -} - -type Status_DeprecatedStatusCode int32 - -const ( - Status_DEPRECATED_STATUS_CODE_OK Status_DeprecatedStatusCode = 0 - Status_DEPRECATED_STATUS_CODE_CANCELLED Status_DeprecatedStatusCode = 1 - Status_DEPRECATED_STATUS_CODE_UNKNOWN_ERROR Status_DeprecatedStatusCode = 2 - Status_DEPRECATED_STATUS_CODE_INVALID_ARGUMENT Status_DeprecatedStatusCode = 3 - Status_DEPRECATED_STATUS_CODE_DEADLINE_EXCEEDED Status_DeprecatedStatusCode = 4 - Status_DEPRECATED_STATUS_CODE_NOT_FOUND Status_DeprecatedStatusCode = 5 - Status_DEPRECATED_STATUS_CODE_ALREADY_EXISTS Status_DeprecatedStatusCode = 6 - Status_DEPRECATED_STATUS_CODE_PERMISSION_DENIED Status_DeprecatedStatusCode = 7 - Status_DEPRECATED_STATUS_CODE_RESOURCE_EXHAUSTED Status_DeprecatedStatusCode = 8 - Status_DEPRECATED_STATUS_CODE_FAILED_PRECONDITION Status_DeprecatedStatusCode = 9 - Status_DEPRECATED_STATUS_CODE_ABORTED Status_DeprecatedStatusCode = 10 - Status_DEPRECATED_STATUS_CODE_OUT_OF_RANGE Status_DeprecatedStatusCode = 11 - Status_DEPRECATED_STATUS_CODE_UNIMPLEMENTED Status_DeprecatedStatusCode = 12 - Status_DEPRECATED_STATUS_CODE_INTERNAL_ERROR Status_DeprecatedStatusCode = 13 - Status_DEPRECATED_STATUS_CODE_UNAVAILABLE Status_DeprecatedStatusCode = 14 - Status_DEPRECATED_STATUS_CODE_DATA_LOSS Status_DeprecatedStatusCode = 15 - Status_DEPRECATED_STATUS_CODE_UNAUTHENTICATED Status_DeprecatedStatusCode = 16 -) - -// Enum value maps for Status_DeprecatedStatusCode. -var ( - Status_DeprecatedStatusCode_name = map[int32]string{ - 0: "DEPRECATED_STATUS_CODE_OK", - 1: "DEPRECATED_STATUS_CODE_CANCELLED", - 2: "DEPRECATED_STATUS_CODE_UNKNOWN_ERROR", - 3: "DEPRECATED_STATUS_CODE_INVALID_ARGUMENT", - 4: "DEPRECATED_STATUS_CODE_DEADLINE_EXCEEDED", - 5: "DEPRECATED_STATUS_CODE_NOT_FOUND", - 6: "DEPRECATED_STATUS_CODE_ALREADY_EXISTS", - 7: "DEPRECATED_STATUS_CODE_PERMISSION_DENIED", - 8: "DEPRECATED_STATUS_CODE_RESOURCE_EXHAUSTED", - 9: "DEPRECATED_STATUS_CODE_FAILED_PRECONDITION", - 10: "DEPRECATED_STATUS_CODE_ABORTED", - 11: "DEPRECATED_STATUS_CODE_OUT_OF_RANGE", - 12: "DEPRECATED_STATUS_CODE_UNIMPLEMENTED", - 13: "DEPRECATED_STATUS_CODE_INTERNAL_ERROR", - 14: "DEPRECATED_STATUS_CODE_UNAVAILABLE", - 15: "DEPRECATED_STATUS_CODE_DATA_LOSS", - 16: "DEPRECATED_STATUS_CODE_UNAUTHENTICATED", - } - Status_DeprecatedStatusCode_value = map[string]int32{ - "DEPRECATED_STATUS_CODE_OK": 0, - "DEPRECATED_STATUS_CODE_CANCELLED": 1, - "DEPRECATED_STATUS_CODE_UNKNOWN_ERROR": 2, - "DEPRECATED_STATUS_CODE_INVALID_ARGUMENT": 3, - "DEPRECATED_STATUS_CODE_DEADLINE_EXCEEDED": 4, - "DEPRECATED_STATUS_CODE_NOT_FOUND": 5, - "DEPRECATED_STATUS_CODE_ALREADY_EXISTS": 6, - "DEPRECATED_STATUS_CODE_PERMISSION_DENIED": 7, - "DEPRECATED_STATUS_CODE_RESOURCE_EXHAUSTED": 8, - "DEPRECATED_STATUS_CODE_FAILED_PRECONDITION": 9, - "DEPRECATED_STATUS_CODE_ABORTED": 10, - "DEPRECATED_STATUS_CODE_OUT_OF_RANGE": 11, - "DEPRECATED_STATUS_CODE_UNIMPLEMENTED": 12, - "DEPRECATED_STATUS_CODE_INTERNAL_ERROR": 13, - "DEPRECATED_STATUS_CODE_UNAVAILABLE": 14, - "DEPRECATED_STATUS_CODE_DATA_LOSS": 15, - "DEPRECATED_STATUS_CODE_UNAUTHENTICATED": 16, - } -) - -func (x Status_DeprecatedStatusCode) Enum() *Status_DeprecatedStatusCode { - p := new(Status_DeprecatedStatusCode) - *p = x - return p -} - -func (x Status_DeprecatedStatusCode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Status_DeprecatedStatusCode) Descriptor() protoreflect.EnumDescriptor { - return file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1].Descriptor() -} - -func (Status_DeprecatedStatusCode) Type() protoreflect.EnumType { - return &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1] -} - -func (x Status_DeprecatedStatusCode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Status_DeprecatedStatusCode.Descriptor instead. -func (Status_DeprecatedStatusCode) EnumDescriptor() ([]byte, []int) { return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 0} } // For the semantics of status codes see -// https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#set-status +// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status type Status_StatusCode int32 const ( // The default status. Status_STATUS_CODE_UNSET Status_StatusCode = 0 - // The Span has been validated by an Application developers or Operator to have - // completed successfully. + // The Span has been validated by an Application developer or Operator to + // have completed successfully. Status_STATUS_CODE_OK Status_StatusCode = 1 // The Span contains an error. Status_STATUS_CODE_ERROR Status_StatusCode = 2 @@ -245,11 +149,11 @@ func (x Status_StatusCode) String() string { } func (Status_StatusCode) Descriptor() protoreflect.EnumDescriptor { - return file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[2].Descriptor() + return file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1].Descriptor() } func (Status_StatusCode) Type() protoreflect.EnumType { - return &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[2] + return &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1] } func (x Status_StatusCode) Number() protoreflect.EnumNumber { @@ -258,10 +162,72 @@ func (x Status_StatusCode) Number() protoreflect.EnumNumber { // Deprecated: Use Status_StatusCode.Descriptor instead. func (Status_StatusCode) EnumDescriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 1} + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{4, 0} } -// A collection of InstrumentationLibrarySpans from a Resource. +// TracesData represents the traces data that can be stored in a persistent storage, +// OR can be embedded by other protocols that transfer OTLP traces data but do +// not implement the OTLP protocol. +// +// The main difference between this message and collector protocol is that +// in this message there will not be any "control" or "metadata" specific to +// OTLP protocol. +// +// When new fields are added into this message, the OTLP request MUST be updated +// as well. +type TracesData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // An array of ResourceSpans. + // For data coming from a single resource this array will typically contain + // one element. Intermediary nodes that receive data from multiple origins + // typically batch the data before forwarding further and in that case this + // array will contain multiple elements. + ResourceSpans []*ResourceSpans `protobuf:"bytes,1,rep,name=resource_spans,json=resourceSpans,proto3" json:"resource_spans,omitempty"` +} + +func (x *TracesData) Reset() { + *x = TracesData{} + if protoimpl.UnsafeEnabled { + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TracesData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TracesData) ProtoMessage() {} + +func (x *TracesData) ProtoReflect() protoreflect.Message { + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TracesData.ProtoReflect.Descriptor instead. +func (*TracesData) Descriptor() ([]byte, []int) { + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{0} +} + +func (x *TracesData) GetResourceSpans() []*ResourceSpans { + if x != nil { + return x.ResourceSpans + } + return nil +} + +// A collection of ScopeSpans from a Resource. type ResourceSpans struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -270,14 +236,17 @@ type ResourceSpans struct { // The resource for the spans in this message. // If this field is not set then no resource info is known. Resource *v1.Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` - // A list of InstrumentationLibrarySpans that originate from a resource. - InstrumentationLibrarySpans []*InstrumentationLibrarySpans `protobuf:"bytes,2,rep,name=instrumentation_library_spans,json=instrumentationLibrarySpans,proto3" json:"instrumentation_library_spans,omitempty"` + // A list of ScopeSpans that originate from a resource. + ScopeSpans []*ScopeSpans `protobuf:"bytes,2,rep,name=scope_spans,json=scopeSpans,proto3" json:"scope_spans,omitempty"` + // This schema_url applies to the data in the "resource" field. It does not apply + // to the data in the "scope_spans" field which have their own schema_url field. + SchemaUrl string `protobuf:"bytes,3,opt,name=schema_url,json=schemaUrl,proto3" json:"schema_url,omitempty"` } func (x *ResourceSpans) Reset() { *x = ResourceSpans{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -290,7 +259,7 @@ func (x *ResourceSpans) String() string { func (*ResourceSpans) ProtoMessage() {} func (x *ResourceSpans) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -303,7 +272,7 @@ func (x *ResourceSpans) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceSpans.ProtoReflect.Descriptor instead. func (*ResourceSpans) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{0} + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{1} } func (x *ResourceSpans) GetResource() *v1.Resource { @@ -313,44 +282,53 @@ func (x *ResourceSpans) GetResource() *v1.Resource { return nil } -func (x *ResourceSpans) GetInstrumentationLibrarySpans() []*InstrumentationLibrarySpans { +func (x *ResourceSpans) GetScopeSpans() []*ScopeSpans { if x != nil { - return x.InstrumentationLibrarySpans + return x.ScopeSpans } return nil } -// A collection of Spans produced by an InstrumentationLibrary. -type InstrumentationLibrarySpans struct { +func (x *ResourceSpans) GetSchemaUrl() string { + if x != nil { + return x.SchemaUrl + } + return "" +} + +// A collection of Spans produced by an InstrumentationScope. +type ScopeSpans struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The instrumentation library information for the spans in this message. - // Semantically when InstrumentationLibrary isn't set, it is equivalent with - // an empty instrumentation library name (unknown). - InstrumentationLibrary *v11.InstrumentationLibrary `protobuf:"bytes,1,opt,name=instrumentation_library,json=instrumentationLibrary,proto3" json:"instrumentation_library,omitempty"` - // A list of Spans that originate from an instrumentation library. + // The instrumentation scope information for the spans in this message. + // Semantically when InstrumentationScope isn't set, it is equivalent with + // an empty instrumentation scope name (unknown). + Scope *v11.InstrumentationScope `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"` + // A list of Spans that originate from an instrumentation scope. Spans []*Span `protobuf:"bytes,2,rep,name=spans,proto3" json:"spans,omitempty"` + // This schema_url applies to all spans and span events in the "spans" field. + SchemaUrl string `protobuf:"bytes,3,opt,name=schema_url,json=schemaUrl,proto3" json:"schema_url,omitempty"` } -func (x *InstrumentationLibrarySpans) Reset() { - *x = InstrumentationLibrarySpans{} +func (x *ScopeSpans) Reset() { + *x = ScopeSpans{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *InstrumentationLibrarySpans) String() string { +func (x *ScopeSpans) String() string { return protoimpl.X.MessageStringOf(x) } -func (*InstrumentationLibrarySpans) ProtoMessage() {} +func (*ScopeSpans) ProtoMessage() {} -func (x *InstrumentationLibrarySpans) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1] +func (x *ScopeSpans) ProtoReflect() protoreflect.Message { + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -361,32 +339,33 @@ func (x *InstrumentationLibrarySpans) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use InstrumentationLibrarySpans.ProtoReflect.Descriptor instead. -func (*InstrumentationLibrarySpans) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{1} +// Deprecated: Use ScopeSpans.ProtoReflect.Descriptor instead. +func (*ScopeSpans) Descriptor() ([]byte, []int) { + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2} } -func (x *InstrumentationLibrarySpans) GetInstrumentationLibrary() *v11.InstrumentationLibrary { +func (x *ScopeSpans) GetScope() *v11.InstrumentationScope { if x != nil { - return x.InstrumentationLibrary + return x.Scope } return nil } -func (x *InstrumentationLibrarySpans) GetSpans() []*Span { +func (x *ScopeSpans) GetSpans() []*Span { if x != nil { return x.Spans } return nil } -// Span represents a single operation within a trace. Spans can be -// nested to form a trace tree. Spans may also be linked to other spans -// from the same or different trace and form graphs. Often, a trace -// contains a root span that describes the end-to-end latency, and one -// or more subspans for its sub-operations. A trace can also contain -// multiple root spans, or none at all. Spans do not need to be -// contiguous - there may be gaps or overlaps between spans in a trace. +func (x *ScopeSpans) GetSchemaUrl() string { + if x != nil { + return x.SchemaUrl + } + return "" +} + +// A Span represents a single operation performed by a single component of the system. // // The next available field id is 17. type Span struct { @@ -395,20 +374,16 @@ type Span struct { unknownFields protoimpl.UnknownFields // A unique identifier for a trace. All spans from the same trace share - // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes - // is considered invalid. - // - // This field is semantically required. Receiver should generate new - // random trace_id if empty or invalid trace_id was received. + // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + // of length other than 16 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). // // This field is required. TraceId []byte `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` // A unique identifier for a span within a trace, assigned when the span - // is created. The ID is an 8-byte array. An ID with all zeroes is considered - // invalid. - // - // This field is semantically required. Receiver should generate new - // random span_id if empty or invalid span_id was received. + // is created. The ID is an 8-byte array. An ID with all zeroes OR of length + // other than 8 bytes is considered invalid (empty string in OTLP/JSON + // is zero-length and thus is also invalid). // // This field is required. SpanId []byte `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` @@ -427,9 +402,7 @@ type Span struct { // This makes it easier to correlate spans in different traces. // // This field is semantically required to be set to non-empty string. - // When null or empty string received - receiver may use string "name" - // as a replacement. There might be smarted algorithms implemented by - // receiver to fix the empty span name. + // Empty value is equivalent to an unknown span name. // // This field is required. Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` @@ -451,14 +424,18 @@ type Span struct { // // This field is semantically required and it is expected that end_time >= start_time. EndTimeUnixNano uint64 `protobuf:"fixed64,8,opt,name=end_time_unix_nano,json=endTimeUnixNano,proto3" json:"end_time_unix_nano,omitempty"` - // attributes is a collection of key/value pairs. The value can be a string, - // an integer, a double or the Boolean values `true` or `false`. Note, global attributes + // attributes is a collection of key/value pairs. Note, global attributes // like server name can be set using the resource API. Examples of attributes: // // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" // "/http/server_latency": 300 - // "abc.com/myattribute": true - // "abc.com/score": 10.239 + // "example.com/myattribute": true + // "example.com/score": 10.239 + // + // The OpenTelemetry API specification further restricts the allowed value types: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). Attributes []*v11.KeyValue `protobuf:"bytes,9,rep,name=attributes,proto3" json:"attributes,omitempty"` // dropped_attributes_count is the number of attributes that were discarded. Attributes // can be discarded because their keys are too long or because there are too many @@ -483,7 +460,7 @@ type Span struct { func (x *Span) Reset() { *x = Span{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -496,7 +473,7 @@ func (x *Span) String() string { func (*Span) ProtoMessage() {} func (x *Span) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -509,7 +486,7 @@ func (x *Span) ProtoReflect() protoreflect.Message { // Deprecated: Use Span.ProtoReflect.Descriptor instead. func (*Span) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2} + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3} } func (x *Span) GetTraceId() []byte { @@ -624,15 +601,6 @@ type Status struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The deprecated status code. This is an optional field. - // - // This field is deprecated and is replaced by the `code` field below. See backward - // compatibility notes below. According to our stability guarantees this field - // will be removed in 12 months, on Oct 22, 2021. All usage of old senders and - // receivers that do not understand the `code` field MUST be phased out by then. - // - // Deprecated: Do not use. - DeprecatedCode Status_DeprecatedStatusCode `protobuf:"varint,1,opt,name=deprecated_code,json=deprecatedCode,proto3,enum=opentelemetry.proto.trace.v1.Status_DeprecatedStatusCode" json:"deprecated_code,omitempty"` // A developer-facing human readable error message. Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // The status code. @@ -642,7 +610,7 @@ type Status struct { func (x *Status) Reset() { *x = Status{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -655,7 +623,7 @@ func (x *Status) String() string { func (*Status) ProtoMessage() {} func (x *Status) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -668,15 +636,7 @@ func (x *Status) ProtoReflect() protoreflect.Message { // Deprecated: Use Status.ProtoReflect.Descriptor instead. func (*Status) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3} -} - -// Deprecated: Do not use. -func (x *Status) GetDeprecatedCode() Status_DeprecatedStatusCode { - if x != nil { - return x.DeprecatedCode - } - return Status_DEPRECATED_STATUS_CODE_OK + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{4} } func (x *Status) GetMessage() string { @@ -706,6 +666,8 @@ type Span_Event struct { // This field is semantically required to be set to non-empty string. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // attributes is a collection of attribute key/value pairs on the event. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). Attributes []*v11.KeyValue `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty"` // dropped_attributes_count is the number of dropped attributes. If the value is 0, // then no attributes were dropped. @@ -715,7 +677,7 @@ type Span_Event struct { func (x *Span_Event) Reset() { *x = Span_Event{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -728,7 +690,7 @@ func (x *Span_Event) String() string { func (*Span_Event) ProtoMessage() {} func (x *Span_Event) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -741,7 +703,7 @@ func (x *Span_Event) ProtoReflect() protoreflect.Message { // Deprecated: Use Span_Event.ProtoReflect.Descriptor instead. func (*Span_Event) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2, 0} + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 0} } func (x *Span_Event) GetTimeUnixNano() uint64 { @@ -789,6 +751,8 @@ type Span_Link struct { // The trace_state associated with the link. TraceState string `protobuf:"bytes,3,opt,name=trace_state,json=traceState,proto3" json:"trace_state,omitempty"` // attributes is a collection of attribute key/value pairs on the link. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). Attributes []*v11.KeyValue `protobuf:"bytes,4,rep,name=attributes,proto3" json:"attributes,omitempty"` // dropped_attributes_count is the number of dropped attributes. If the value is 0, // then no attributes were dropped. @@ -798,7 +762,7 @@ type Span_Link struct { func (x *Span_Link) Reset() { *x = Span_Link{} if protoimpl.UnsafeEnabled { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -811,7 +775,7 @@ func (x *Span_Link) String() string { func (*Span_Link) ProtoMessage() {} func (x *Span_Link) ProtoReflect() protoreflect.Message { - mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5] + mi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -824,7 +788,7 @@ func (x *Span_Link) ProtoReflect() protoreflect.Message { // Deprecated: Use Span_Link.ProtoReflect.Descriptor instead. func (*Span_Link) Descriptor() ([]byte, []int) { - return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2, 1} + return file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 1} } func (x *Span_Link) GetTraceId() []byte { @@ -875,185 +839,139 @@ var file_opentelemetry_proto_trace_v1_trace_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd5, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x7d, 0x0a, - 0x1d, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x52, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, + 0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x49, 0x0a, 0x0b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, - 0x1b, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x22, 0xc7, 0x01, 0x0a, - 0x1b, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x6e, 0x0a, 0x17, - 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x79, 0x52, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x05, - 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, - 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x22, 0x9c, 0x0a, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x0a, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, 0x4a, 0x06, 0x08, 0xe8, 0x07, 0x10, 0xe9, + 0x07, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, + 0x12, 0x49, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x33, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x73, + 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x05, + 0x73, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x55, 0x72, 0x6c, 0x22, 0x9c, 0x0a, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x19, 0x0a, + 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, + 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x61, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, + 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x2f, 0x0a, + 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, + 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x2b, + 0x0a, 0x12, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, + 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0f, 0x65, 0x6e, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x47, 0x0a, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, + 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, + 0x61, 0x6e, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x30, 0x0a, 0x14, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, + 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0xc4, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xde, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, - 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, - 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, - 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, - 0x2f, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, - 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x06, 0x52, 0x11, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, - 0x12, 0x2b, 0x0a, 0x12, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, - 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0f, 0x65, 0x6e, - 0x64, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x47, 0x0a, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, - 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x40, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x12, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x0d, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, - 0x6e, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6c, - 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x1a, 0xc4, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, - 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xde, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, - 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, - 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, - 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x08, 0x53, 0x70, - 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, - 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x49, - 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x50, 0x41, - 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, - 0x14, 0x0a, 0x10, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4c, 0x49, - 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x45, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, - 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, - 0x4d, 0x45, 0x52, 0x10, 0x05, 0x22, 0xfc, 0x07, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x66, 0x0a, 0x0f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, - 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x43, 0x6f, 0x64, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, - 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xda, 0x05, 0x0a, 0x14, 0x44, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, - 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x4b, 0x10, 0x00, 0x12, - 0x24, 0x0a, 0x20, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, - 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, - 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, - 0x2b, 0x0a, 0x27, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, - 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x5f, - 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x45, - 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x05, - 0x12, 0x29, 0x0a, 0x25, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x4c, 0x52, 0x45, 0x41, - 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x06, 0x12, 0x2c, 0x0a, 0x28, 0x44, - 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, - 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x07, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x45, 0x50, - 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, - 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x58, 0x48, - 0x41, 0x55, 0x53, 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x2e, 0x0a, 0x2a, 0x44, 0x45, 0x50, 0x52, - 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4e, - 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x45, 0x50, 0x52, - 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x27, 0x0a, 0x23, - 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, - 0x4e, 0x47, 0x45, 0x10, 0x0b, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, - 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, - 0x55, 0x4e, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x0c, 0x12, - 0x29, 0x0a, 0x25, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, - 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x45, - 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, - 0x10, 0x0e, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x0f, 0x12, 0x2a, 0x0a, 0x26, 0x44, 0x45, 0x50, 0x52, - 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, - 0x45, 0x44, 0x10, 0x10, 0x22, 0x4e, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, - 0x64, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x15, 0x0a, - 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x02, 0x42, 0x58, 0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, + 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x08, 0x53, 0x70, 0x61, 0x6e, + 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x54, + 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x50, 0x41, 0x4e, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x14, 0x0a, + 0x10, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x45, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x53, + 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, + 0x52, 0x10, 0x05, 0x22, 0xbd, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x4e, 0x0a, + 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, + 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, + 0x45, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x4a, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x42, 0x77, 0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xaa, 0x02, 0x1c, + 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1068,34 +986,34 @@ func file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP() []byte { return file_opentelemetry_proto_trace_v1_trace_proto_rawDescData } -var file_opentelemetry_proto_trace_v1_trace_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_opentelemetry_proto_trace_v1_trace_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_opentelemetry_proto_trace_v1_trace_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_opentelemetry_proto_trace_v1_trace_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_opentelemetry_proto_trace_v1_trace_proto_goTypes = []interface{}{ - (Span_SpanKind)(0), // 0: opentelemetry.proto.trace.v1.Span.SpanKind - (Status_DeprecatedStatusCode)(0), // 1: opentelemetry.proto.trace.v1.Status.DeprecatedStatusCode - (Status_StatusCode)(0), // 2: opentelemetry.proto.trace.v1.Status.StatusCode - (*ResourceSpans)(nil), // 3: opentelemetry.proto.trace.v1.ResourceSpans - (*InstrumentationLibrarySpans)(nil), // 4: opentelemetry.proto.trace.v1.InstrumentationLibrarySpans - (*Span)(nil), // 5: opentelemetry.proto.trace.v1.Span - (*Status)(nil), // 6: opentelemetry.proto.trace.v1.Status - (*Span_Event)(nil), // 7: opentelemetry.proto.trace.v1.Span.Event - (*Span_Link)(nil), // 8: opentelemetry.proto.trace.v1.Span.Link - (*v1.Resource)(nil), // 9: opentelemetry.proto.resource.v1.Resource - (*v11.InstrumentationLibrary)(nil), // 10: opentelemetry.proto.common.v1.InstrumentationLibrary - (*v11.KeyValue)(nil), // 11: opentelemetry.proto.common.v1.KeyValue + (Span_SpanKind)(0), // 0: opentelemetry.proto.trace.v1.Span.SpanKind + (Status_StatusCode)(0), // 1: opentelemetry.proto.trace.v1.Status.StatusCode + (*TracesData)(nil), // 2: opentelemetry.proto.trace.v1.TracesData + (*ResourceSpans)(nil), // 3: opentelemetry.proto.trace.v1.ResourceSpans + (*ScopeSpans)(nil), // 4: opentelemetry.proto.trace.v1.ScopeSpans + (*Span)(nil), // 5: opentelemetry.proto.trace.v1.Span + (*Status)(nil), // 6: opentelemetry.proto.trace.v1.Status + (*Span_Event)(nil), // 7: opentelemetry.proto.trace.v1.Span.Event + (*Span_Link)(nil), // 8: opentelemetry.proto.trace.v1.Span.Link + (*v1.Resource)(nil), // 9: opentelemetry.proto.resource.v1.Resource + (*v11.InstrumentationScope)(nil), // 10: opentelemetry.proto.common.v1.InstrumentationScope + (*v11.KeyValue)(nil), // 11: opentelemetry.proto.common.v1.KeyValue } var file_opentelemetry_proto_trace_v1_trace_proto_depIdxs = []int32{ - 9, // 0: opentelemetry.proto.trace.v1.ResourceSpans.resource:type_name -> opentelemetry.proto.resource.v1.Resource - 4, // 1: opentelemetry.proto.trace.v1.ResourceSpans.instrumentation_library_spans:type_name -> opentelemetry.proto.trace.v1.InstrumentationLibrarySpans - 10, // 2: opentelemetry.proto.trace.v1.InstrumentationLibrarySpans.instrumentation_library:type_name -> opentelemetry.proto.common.v1.InstrumentationLibrary - 5, // 3: opentelemetry.proto.trace.v1.InstrumentationLibrarySpans.spans:type_name -> opentelemetry.proto.trace.v1.Span - 0, // 4: opentelemetry.proto.trace.v1.Span.kind:type_name -> opentelemetry.proto.trace.v1.Span.SpanKind - 11, // 5: opentelemetry.proto.trace.v1.Span.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue - 7, // 6: opentelemetry.proto.trace.v1.Span.events:type_name -> opentelemetry.proto.trace.v1.Span.Event - 8, // 7: opentelemetry.proto.trace.v1.Span.links:type_name -> opentelemetry.proto.trace.v1.Span.Link - 6, // 8: opentelemetry.proto.trace.v1.Span.status:type_name -> opentelemetry.proto.trace.v1.Status - 1, // 9: opentelemetry.proto.trace.v1.Status.deprecated_code:type_name -> opentelemetry.proto.trace.v1.Status.DeprecatedStatusCode - 2, // 10: opentelemetry.proto.trace.v1.Status.code:type_name -> opentelemetry.proto.trace.v1.Status.StatusCode + 3, // 0: opentelemetry.proto.trace.v1.TracesData.resource_spans:type_name -> opentelemetry.proto.trace.v1.ResourceSpans + 9, // 1: opentelemetry.proto.trace.v1.ResourceSpans.resource:type_name -> opentelemetry.proto.resource.v1.Resource + 4, // 2: opentelemetry.proto.trace.v1.ResourceSpans.scope_spans:type_name -> opentelemetry.proto.trace.v1.ScopeSpans + 10, // 3: opentelemetry.proto.trace.v1.ScopeSpans.scope:type_name -> opentelemetry.proto.common.v1.InstrumentationScope + 5, // 4: opentelemetry.proto.trace.v1.ScopeSpans.spans:type_name -> opentelemetry.proto.trace.v1.Span + 0, // 5: opentelemetry.proto.trace.v1.Span.kind:type_name -> opentelemetry.proto.trace.v1.Span.SpanKind + 11, // 6: opentelemetry.proto.trace.v1.Span.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue + 7, // 7: opentelemetry.proto.trace.v1.Span.events:type_name -> opentelemetry.proto.trace.v1.Span.Event + 8, // 8: opentelemetry.proto.trace.v1.Span.links:type_name -> opentelemetry.proto.trace.v1.Span.Link + 6, // 9: opentelemetry.proto.trace.v1.Span.status:type_name -> opentelemetry.proto.trace.v1.Status + 1, // 10: opentelemetry.proto.trace.v1.Status.code:type_name -> opentelemetry.proto.trace.v1.Status.StatusCode 11, // 11: opentelemetry.proto.trace.v1.Span.Event.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue 11, // 12: opentelemetry.proto.trace.v1.Span.Link.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue 13, // [13:13] is the sub-list for method output_type @@ -1112,7 +1030,7 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } if !protoimpl.UnsafeEnabled { file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceSpans); i { + switch v := v.(*TracesData); i { case 0: return &v.state case 1: @@ -1124,7 +1042,7 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } } file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstrumentationLibrarySpans); i { + switch v := v.(*ResourceSpans); i { case 0: return &v.state case 1: @@ -1136,7 +1054,7 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } } file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Span); i { + switch v := v.(*ScopeSpans); i { case 0: return &v.state case 1: @@ -1148,7 +1066,7 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } } file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Status); i { + switch v := v.(*Span); i { case 0: return &v.state case 1: @@ -1160,7 +1078,7 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } } file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Span_Event); i { + switch v := v.(*Status); i { case 0: return &v.state case 1: @@ -1172,6 +1090,18 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { } } file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span_Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Span_Link); i { case 0: return &v.state @@ -1189,8 +1119,8 @@ func file_opentelemetry_proto_trace_v1_trace_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_opentelemetry_proto_trace_v1_trace_proto_rawDesc, - NumEnums: 3, - NumMessages: 6, + NumEnums: 2, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/go.uber.org/atomic/CHANGELOG.md b/vendor/go.uber.org/atomic/CHANGELOG.md index 38f564e2b36..6f87f33fa95 100644 --- a/vendor/go.uber.org/atomic/CHANGELOG.md +++ b/vendor/go.uber.org/atomic/CHANGELOG.md @@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.11.0] - 2023-05-02 +### Fixed +- Fix initialization of `Value` wrappers. + +### Added +- Add `String` method to `atomic.Pointer[T]` type allowing users to safely print +underlying values of pointers. + +[1.11.0]: https://github.com/uber-go/atomic/compare/v1.10.0...v1.11.0 + +## [1.10.0] - 2022-08-11 +### Added +- Add `atomic.Float32` type for atomic operations on `float32`. +- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`, + and `atomic.Value`. +- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any + type. This is present only for Go 1.18 or higher, and is a drop-in for + replacement for the standard library's `sync/atomic.Pointer` type. + +### Changed +- Deprecate `CAS` methods on all types in favor of corresponding + `CompareAndSwap` methods. + +Thanks to @eNV25 and @icpd for their contributions to this release. + +[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0 + ## [1.9.0] - 2021-07-15 ### Added - Add `Float64.Swap` to match int atomic operations. diff --git a/vendor/go.uber.org/atomic/bool.go b/vendor/go.uber.org/atomic/bool.go index 209df7bbcd2..f0a2ddd148c 100644 --- a/vendor/go.uber.org/atomic/bool.go +++ b/vendor/go.uber.org/atomic/bool.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -55,8 +55,15 @@ func (x *Bool) Store(val bool) { } // CAS is an atomic compare-and-swap for bool values. +// +// Deprecated: Use CompareAndSwap. func (x *Bool) CAS(old, new bool) (swapped bool) { - return x.v.CAS(boolToInt(old), boolToInt(new)) + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for bool values. +func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { + return x.v.CompareAndSwap(boolToInt(old), boolToInt(new)) } // Swap atomically stores the given bool and returns the old diff --git a/vendor/go.uber.org/atomic/duration.go b/vendor/go.uber.org/atomic/duration.go index 207594f5e80..7c23868fc87 100644 --- a/vendor/go.uber.org/atomic/duration.go +++ b/vendor/go.uber.org/atomic/duration.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -56,8 +56,15 @@ func (x *Duration) Store(val time.Duration) { } // CAS is an atomic compare-and-swap for time.Duration values. +// +// Deprecated: Use CompareAndSwap. func (x *Duration) CAS(old, new time.Duration) (swapped bool) { - return x.v.CAS(int64(old), int64(new)) + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for time.Duration values. +func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) { + return x.v.CompareAndSwap(int64(old), int64(new)) } // Swap atomically stores the given time.Duration and returns the old diff --git a/vendor/go.uber.org/atomic/error.go b/vendor/go.uber.org/atomic/error.go index 3be19c35ee7..b7e3f1291a3 100644 --- a/vendor/go.uber.org/atomic/error.go +++ b/vendor/go.uber.org/atomic/error.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,3 +49,24 @@ func (x *Error) Load() error { func (x *Error) Store(val error) { x.v.Store(packError(val)) } + +// CompareAndSwap is an atomic compare-and-swap for error values. +func (x *Error) CompareAndSwap(old, new error) (swapped bool) { + if x.v.CompareAndSwap(packError(old), packError(new)) { + return true + } + + if old == _zeroError { + // If the old value is the empty value, then it's possible the + // underlying Value hasn't been set and is nil, so retry with nil. + return x.v.CompareAndSwap(nil, packError(new)) + } + + return false +} + +// Swap atomically stores the given error and returns the old +// value. +func (x *Error) Swap(val error) (old error) { + return unpackError(x.v.Swap(packError(val))) +} diff --git a/vendor/go.uber.org/atomic/error_ext.go b/vendor/go.uber.org/atomic/error_ext.go index ffe0be21cb0..d31fb633bb6 100644 --- a/vendor/go.uber.org/atomic/error_ext.go +++ b/vendor/go.uber.org/atomic/error_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ package atomic // atomic.Value panics on nil inputs, or if the underlying type changes. // Stabilize by always storing a custom struct that we control. -//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -file=error.go +//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -compareandswap -swap -file=error.go type packedError struct{ Value error } diff --git a/vendor/go.uber.org/atomic/float32.go b/vendor/go.uber.org/atomic/float32.go new file mode 100644 index 00000000000..62c36334fd5 --- /dev/null +++ b/vendor/go.uber.org/atomic/float32.go @@ -0,0 +1,77 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" +) + +// Float32 is an atomic type-safe wrapper for float32 values. +type Float32 struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroFloat32 float32 + +// NewFloat32 creates a new Float32. +func NewFloat32(val float32) *Float32 { + x := &Float32{} + if val != _zeroFloat32 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped float32. +func (x *Float32) Load() float32 { + return math.Float32frombits(x.v.Load()) +} + +// Store atomically stores the passed float32. +func (x *Float32) Store(val float32) { + x.v.Store(math.Float32bits(val)) +} + +// Swap atomically stores the given float32 and returns the old +// value. +func (x *Float32) Swap(val float32) (old float32) { + return math.Float32frombits(x.v.Swap(math.Float32bits(val))) +} + +// MarshalJSON encodes the wrapped float32 into JSON. +func (x *Float32) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a float32 from JSON. +func (x *Float32) UnmarshalJSON(b []byte) error { + var v float32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/vendor/go.uber.org/atomic/float32_ext.go b/vendor/go.uber.org/atomic/float32_ext.go new file mode 100644 index 00000000000..b0cd8d9c820 --- /dev/null +++ b/vendor/go.uber.org/atomic/float32_ext.go @@ -0,0 +1,76 @@ +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "math" + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Float32 -type=float32 -wrapped=Uint32 -pack=math.Float32bits -unpack=math.Float32frombits -swap -json -imports math -file=float32.go + +// Add atomically adds to the wrapped float32 and returns the new value. +func (f *Float32) Add(delta float32) float32 { + for { + old := f.Load() + new := old + delta + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float32 and returns the new value. +func (f *Float32) Sub(delta float32) float32 { + return f.Add(-delta) +} + +// CAS is an atomic compare-and-swap for float32 values. +// +// Deprecated: Use CompareAndSwap +func (f *Float32) CAS(old, new float32) (swapped bool) { + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float32 values. +// +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., +// +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float32) CompareAndSwap(old, new float32) (swapped bool) { + return f.v.CompareAndSwap(math.Float32bits(old), math.Float32bits(new)) +} + +// String encodes the wrapped value as a string. +func (f *Float32) String() string { + // 'g' is the behavior for floats with %v. + return strconv.FormatFloat(float64(f.Load()), 'g', -1, 32) +} diff --git a/vendor/go.uber.org/atomic/float64.go b/vendor/go.uber.org/atomic/float64.go index 8a136718472..5bc11caabe2 100644 --- a/vendor/go.uber.org/atomic/float64.go +++ b/vendor/go.uber.org/atomic/float64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/go.uber.org/atomic/float64_ext.go b/vendor/go.uber.org/atomic/float64_ext.go index df36b0107f0..48c52b0abf6 100644 --- a/vendor/go.uber.org/atomic/float64_ext.go +++ b/vendor/go.uber.org/atomic/float64_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -45,21 +45,28 @@ func (f *Float64) Sub(delta float64) float64 { // CAS is an atomic compare-and-swap for float64 values. // -// Note: CAS handles NaN incorrectly. NaN != NaN using Go's inbuilt operators -// but CAS allows a stored NaN to compare equal to a passed in NaN. -// This avoids typical CAS loops from blocking forever, e.g., +// Deprecated: Use CompareAndSwap +func (f *Float64) CAS(old, new float64) (swapped bool) { + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float64 values. // -// for { -// old := atom.Load() -// new = f(old) -// if atom.CAS(old, new) { -// break -// } -// } +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., // -// If CAS did not match NaN to match, then the above would loop forever. -func (f *Float64) CAS(old, new float64) (swapped bool) { - return f.v.CAS(math.Float64bits(old), math.Float64bits(new)) +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float64) CompareAndSwap(old, new float64) (swapped bool) { + return f.v.CompareAndSwap(math.Float64bits(old), math.Float64bits(new)) } // String encodes the wrapped value as a string. diff --git a/vendor/go.uber.org/atomic/int32.go b/vendor/go.uber.org/atomic/int32.go index 640ea36a175..5320eac10f1 100644 --- a/vendor/go.uber.org/atomic/int32.go +++ b/vendor/go.uber.org/atomic/int32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Int32) Dec() int32 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Int32) CAS(old, new int32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) { return atomic.CompareAndSwapInt32(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/int64.go b/vendor/go.uber.org/atomic/int64.go index 9ab66b98091..460821d009d 100644 --- a/vendor/go.uber.org/atomic/int64.go +++ b/vendor/go.uber.org/atomic/int64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Int64) Dec() int64 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Int64) CAS(old, new int64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) { return atomic.CompareAndSwapInt64(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/nocmp.go b/vendor/go.uber.org/atomic/nocmp.go index a8201cb4a18..54b74174abd 100644 --- a/vendor/go.uber.org/atomic/nocmp.go +++ b/vendor/go.uber.org/atomic/nocmp.go @@ -23,13 +23,13 @@ package atomic // nocmp is an uncomparable struct. Embed this inside another struct to make // it uncomparable. // -// type Foo struct { -// nocmp -// // ... -// } +// type Foo struct { +// nocmp +// // ... +// } // // This DOES NOT: // -// - Disallow shallow copies of structs -// - Disallow comparison of pointers to uncomparable structs +// - Disallow shallow copies of structs +// - Disallow comparison of pointers to uncomparable structs type nocmp [0]func() diff --git a/vendor/go.uber.org/atomic/pointer_go118.go b/vendor/go.uber.org/atomic/pointer_go118.go new file mode 100644 index 00000000000..1fb6c03b261 --- /dev/null +++ b/vendor/go.uber.org/atomic/pointer_go118.go @@ -0,0 +1,31 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 +// +build go1.18 + +package atomic + +import "fmt" + +// String returns a human readable representation of a Pointer's underlying value. +func (p *Pointer[T]) String() string { + return fmt.Sprint(p.Load()) +} diff --git a/vendor/go.uber.org/atomic/pointer_go118_pre119.go b/vendor/go.uber.org/atomic/pointer_go118_pre119.go new file mode 100644 index 00000000000..e0f47dba468 --- /dev/null +++ b/vendor/go.uber.org/atomic/pointer_go118_pre119.go @@ -0,0 +1,60 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 && !go1.19 +// +build go1.18,!go1.19 + +package atomic + +import "unsafe" + +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p UnsafePointer +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(unsafe.Pointer(v)) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return (*T)(p.p.Load()) +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(unsafe.Pointer(val)) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return (*T)(p.p.Swap(unsafe.Pointer(val))) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new)) +} diff --git a/vendor/go.uber.org/atomic/pointer_go119.go b/vendor/go.uber.org/atomic/pointer_go119.go new file mode 100644 index 00000000000..6726f17ad64 --- /dev/null +++ b/vendor/go.uber.org/atomic/pointer_go119.go @@ -0,0 +1,61 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.19 +// +build go1.19 + +package atomic + +import "sync/atomic" + +// Pointer is an atomic pointer of type *T. +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p atomic.Pointer[T] +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(v) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return p.p.Load() +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(val) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return p.p.Swap(val) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(old, new) +} diff --git a/vendor/go.uber.org/atomic/string.go b/vendor/go.uber.org/atomic/string.go index 80df93d0949..061466c5bde 100644 --- a/vendor/go.uber.org/atomic/string.go +++ b/vendor/go.uber.org/atomic/string.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -42,13 +42,31 @@ func NewString(val string) *String { // Load atomically loads the wrapped string. func (x *String) Load() string { - if v := x.v.Load(); v != nil { - return v.(string) - } - return _zeroString + return unpackString(x.v.Load()) } // Store atomically stores the passed string. func (x *String) Store(val string) { - x.v.Store(val) + x.v.Store(packString(val)) +} + +// CompareAndSwap is an atomic compare-and-swap for string values. +func (x *String) CompareAndSwap(old, new string) (swapped bool) { + if x.v.CompareAndSwap(packString(old), packString(new)) { + return true + } + + if old == _zeroString { + // If the old value is the empty value, then it's possible the + // underlying Value hasn't been set and is nil, so retry with nil. + return x.v.CompareAndSwap(nil, packString(new)) + } + + return false +} + +// Swap atomically stores the given string and returns the old +// value. +func (x *String) Swap(val string) (old string) { + return unpackString(x.v.Swap(packString(val))) } diff --git a/vendor/go.uber.org/atomic/string_ext.go b/vendor/go.uber.org/atomic/string_ext.go index 83d92edafc7..019109c86ba 100644 --- a/vendor/go.uber.org/atomic/string_ext.go +++ b/vendor/go.uber.org/atomic/string_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,18 @@ package atomic -//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped=Value -file=string.go -// Note: No Swap as String wraps Value, which wraps the stdlib sync/atomic.Value which -// only supports Swap as of go1.17: https://github.com/golang/go/issues/39351 +//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped Value -pack packString -unpack unpackString -compareandswap -swap -file=string.go + +func packString(s string) interface{} { + return s +} + +func unpackString(v interface{}) string { + if s, ok := v.(string); ok { + return s + } + return "" +} // String returns the wrapped value. func (s *String) String() string { diff --git a/vendor/go.uber.org/atomic/time.go b/vendor/go.uber.org/atomic/time.go index 33460fc37ea..cc2a230c001 100644 --- a/vendor/go.uber.org/atomic/time.go +++ b/vendor/go.uber.org/atomic/time.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/go.uber.org/atomic/uint32.go b/vendor/go.uber.org/atomic/uint32.go index 7859a9cc3b5..4adc294ac2a 100644 --- a/vendor/go.uber.org/atomic/uint32.go +++ b/vendor/go.uber.org/atomic/uint32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uint32) Dec() uint32 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uint32) CAS(old, new uint32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { return atomic.CompareAndSwapUint32(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/uint64.go b/vendor/go.uber.org/atomic/uint64.go index 2f2a7db6380..0e2eddb3038 100644 --- a/vendor/go.uber.org/atomic/uint64.go +++ b/vendor/go.uber.org/atomic/uint64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uint64) Dec() uint64 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uint64) CAS(old, new uint64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { return atomic.CompareAndSwapUint64(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/uintptr.go b/vendor/go.uber.org/atomic/uintptr.go index ecf7a77273a..7d5b000d610 100644 --- a/vendor/go.uber.org/atomic/uintptr.go +++ b/vendor/go.uber.org/atomic/uintptr.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uintptr) Dec() uintptr { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uintptr) CAS(old, new uintptr) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { return atomic.CompareAndSwapUintptr(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/unsafe_pointer.go b/vendor/go.uber.org/atomic/unsafe_pointer.go index 169f793dcf3..34868baf6a8 100644 --- a/vendor/go.uber.org/atomic/unsafe_pointer.go +++ b/vendor/go.uber.org/atomic/unsafe_pointer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2021-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -53,6 +53,13 @@ func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer) { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool) { + return p.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool) { return atomic.CompareAndSwapPointer(&p.v, old, new) } diff --git a/vendor/go.uber.org/atomic/value.go b/vendor/go.uber.org/atomic/value.go index 671f3a38247..52caedb9a58 100644 --- a/vendor/go.uber.org/atomic/value.go +++ b/vendor/go.uber.org/atomic/value.go @@ -25,7 +25,7 @@ import "sync/atomic" // Value shadows the type of the same name from sync/atomic // https://godoc.org/sync/atomic#Value type Value struct { - atomic.Value - _ nocmp // disallow non-atomic comparison + + atomic.Value } diff --git a/vendor/go.uber.org/automaxprocs/CHANGELOG.md b/vendor/go.uber.org/automaxprocs/CHANGELOG.md index a831bc71e5c..274797b0267 100644 --- a/vendor/go.uber.org/automaxprocs/CHANGELOG.md +++ b/vendor/go.uber.org/automaxprocs/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## v1.5.3 (2023-07-19) + +- Fix mountinfo parsing when super options have fields with spaces. +- Fix division by zero while parsing cgroups. + +## v1.5.2 (2023-03-16) + +- Support child control cgroups +- Fix file descriptor leak +- Update dependencies + ## v1.5.1 (2022-04-06) - Fix cgroups v2 mountpoint detection. diff --git a/vendor/go.uber.org/automaxprocs/Makefile b/vendor/go.uber.org/automaxprocs/Makefile index c54677208c6..1642b714801 100644 --- a/vendor/go.uber.org/automaxprocs/Makefile +++ b/vendor/go.uber.org/automaxprocs/Makefile @@ -28,7 +28,7 @@ $(GOLINT): tools/go.mod cd tools && go install golang.org/x/lint/golint $(STATICCHECK): tools/go.mod - cd tools && go install honnef.co/go/tools/cmd/staticcheck + cd tools && go install honnef.co/go/tools/cmd/staticcheck@2023.1.2 .PHONY: lint lint: $(GOLINT) $(STATICCHECK) diff --git a/vendor/go.uber.org/automaxprocs/README.md b/vendor/go.uber.org/automaxprocs/README.md index ab4b33becf8..bfed32adae8 100644 --- a/vendor/go.uber.org/automaxprocs/README.md +++ b/vendor/go.uber.org/automaxprocs/README.md @@ -16,6 +16,31 @@ func main() { } ``` +# Performance +Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores): + +| GOMAXPROCS | RPS | P50 (ms) | P99.9 (ms) | +| ------------------ | --------- | -------- | ---------- | +| 1 | 28,893.18 | 1.46 | 19.70 | +| 2 (equal to quota) | 44,715.07 | 0.84 | 26.38 | +| 3 | 44,212.93 | 0.66 | 30.07 | +| 4 | 41,071.15 | 0.57 | 42.94 | +| 8 | 33,111.69 | 0.43 | 64.32 | +| Default (24) | 22,191.40 | 0.45 | 76.19 | + +When `GOMAXPROCS` is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases. + +When `GOMAXPROCS` is higher than the CPU quota allocated, we also saw significant throttling: + +``` +$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat +nr_periods 42227334 +nr_throttled 131923 +throttled_time 88613212216618 +``` + +Once `GOMAXPROCS` was reduced to match the CPU quota, we saw no CPU throttling. + ## Development Status: Stable All APIs are finalized, and no breaking changes will be made in the 1.x series diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go index e6c17319790..e89f5436028 100644 --- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go +++ b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go @@ -110,8 +110,8 @@ func (cg CGroups) CPUQuota() (float64, bool, error) { } cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam) - if err != nil { - return -1, false, err + if defined := cfsPeriodUs > 0; err != nil || !defined { + return -1, defined, err } return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go index 66930d0ac75..78556062fe2 100644 --- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go +++ b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go @@ -59,6 +59,7 @@ var ErrNotV2 = errors.New("not using cgroups2") // CGroups2 provides access to cgroups data for systems using cgroups2. type CGroups2 struct { mountPoint string + groupPath string cpuMaxFile string } @@ -66,10 +67,10 @@ type CGroups2 struct { // // This returns ErrNotV2 if the system is not using cgroups2. func NewCGroups2ForCurrentProcess() (*CGroups2, error) { - return newCGroups2FromMountInfo(_procPathMountInfo) + return newCGroups2From(_procPathMountInfo, _procPathCGroup) } -func newCGroups2FromMountInfo(mountInfoPath string) (*CGroups2, error) { +func newCGroups2From(mountInfoPath, procPathCGroup string) (*CGroups2, error) { isV2, err := isCGroupV2(mountInfoPath) if err != nil { return nil, err @@ -79,8 +80,27 @@ func newCGroups2FromMountInfo(mountInfoPath string) (*CGroups2, error) { return nil, ErrNotV2 } + subsystems, err := parseCGroupSubsystems(procPathCGroup) + if err != nil { + return nil, err + } + + // Find v2 subsystem by looking for the `0` id + var v2subsys *CGroupSubsys + for _, subsys := range subsystems { + if subsys.ID == 0 { + v2subsys = subsys + break + } + } + + if v2subsys == nil { + return nil, ErrNotV2 + } + return &CGroups2{ mountPoint: _cgroupv2MountPoint, + groupPath: v2subsys.Name, cpuMaxFile: _cgroupv2CPUMax, }, nil } @@ -106,13 +126,14 @@ func isCGroupV2(procPathMountInfo string) (bool, error) { // It will return `cpu.max / cpu.period`. If cpu.max is set to max, it returns // (-1, false, nil) func (cg *CGroups2) CPUQuota() (float64, bool, error) { - cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.cpuMaxFile)) + cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.groupPath, cg.cpuMaxFile)) if err != nil { if os.IsNotExist(err) { return -1, false, nil } return -1, false, err } + defer cpuMaxParams.Close() scanner := bufio.NewScanner(cpuMaxParams) if scanner.Scan() { @@ -138,6 +159,10 @@ func (cg *CGroups2) CPUQuota() (float64, bool, error) { if err != nil { return -1, false, err } + + if period == 0 { + return -1, false, errors.New("zero value for period is not allowed") + } } return float64(max) / float64(period), true, nil diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go index 2efde4c4ba9..f3877f78aa6 100644 --- a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go +++ b/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go @@ -95,8 +95,12 @@ func NewMountPointFromLine(line string) (*MountPoint, error) { for i, field := range fields[_miFieldIDOptionalFields:] { if field == _mountInfoOptionalFieldsSep { + // End of optional fields. fsTypeStart := _miFieldIDOptionalFields + i + 1 + // Now we know where the optional fields end, split the line again with a + // limit to avoid issues with spaces in super options as present on WSL. + fields = strings.SplitN(line, _mountInfoSep, fsTypeStart+_miFieldCountSecondHalf) if len(fields) != fsTypeStart+_miFieldCountSecondHalf { return nil, mountPointFormatInvalidError{line} } diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go b/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go index 3a751564915..df6eacf0530 100644 --- a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go +++ b/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go @@ -28,6 +28,6 @@ const ( CPUQuotaUndefined CPUQuotaStatus = iota // CPUQuotaUsed is returned when a valid CPU quota can be used CPUQuotaUsed - // CPUQuotaMinUsed is return when CPU quota is smaller than the min value + // CPUQuotaMinUsed is returned when CPU quota is smaller than the min value CPUQuotaMinUsed ) diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/version.go b/vendor/go.uber.org/automaxprocs/maxprocs/version.go index 15b156c99e5..108a95535e5 100644 --- a/vendor/go.uber.org/automaxprocs/maxprocs/version.go +++ b/vendor/go.uber.org/automaxprocs/maxprocs/version.go @@ -21,4 +21,4 @@ package maxprocs // Version is the current package version. -const Version = "1.5.1" +const Version = "1.5.2" diff --git a/vendor/go.uber.org/multierr/.travis.yml b/vendor/go.uber.org/multierr/.travis.yml new file mode 100644 index 00000000000..8636ab42ad1 --- /dev/null +++ b/vendor/go.uber.org/multierr/.travis.yml @@ -0,0 +1,23 @@ +sudo: false +language: go +go_import_path: go.uber.org/multierr + +env: + global: + - GO111MODULE=on + +go: + - oldstable + - stable + +before_install: +- go version + +script: +- | + set -e + make lint + make cover + +after_success: +- bash <(curl -s https://codecov.io/bash) diff --git a/vendor/go.uber.org/multierr/CHANGELOG.md b/vendor/go.uber.org/multierr/CHANGELOG.md index 3ba05276f1a..6f1db9ef4a0 100644 --- a/vendor/go.uber.org/multierr/CHANGELOG.md +++ b/vendor/go.uber.org/multierr/CHANGELOG.md @@ -1,18 +1,6 @@ Releases ======== -v1.8.0 (2022-02-28) -=================== - -- `Combine`: perform zero allocations when there are no errors. - - -v1.7.0 (2021-05-06) -=================== - -- Add `AppendInvoke` to append into errors from `defer` blocks. - - v1.6.0 (2020-09-14) =================== diff --git a/vendor/go.uber.org/multierr/LICENSE.txt b/vendor/go.uber.org/multierr/LICENSE.txt index 413e30f7ce2..858e02475f1 100644 --- a/vendor/go.uber.org/multierr/LICENSE.txt +++ b/vendor/go.uber.org/multierr/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2017-2021 Uber Technologies, Inc. +Copyright (c) 2017 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/go.uber.org/multierr/Makefile b/vendor/go.uber.org/multierr/Makefile index dcb6fe723c0..316004400b8 100644 --- a/vendor/go.uber.org/multierr/Makefile +++ b/vendor/go.uber.org/multierr/Makefile @@ -34,5 +34,9 @@ lint: gofmt golint staticcheck .PHONY: cover cover: - go test -race -coverprofile=cover.out -coverpkg=./... -v ./... + go test -coverprofile=cover.out -coverpkg=./... -v ./... go tool cover -html=cover.out -o cover.html + +update-license: + @cd tools && go install go.uber.org/tools/update-license + @$(GOBIN)/update-license $(GO_FILES) diff --git a/vendor/go.uber.org/multierr/README.md b/vendor/go.uber.org/multierr/README.md index 70aacecd715..751bd65e581 100644 --- a/vendor/go.uber.org/multierr/README.md +++ b/vendor/go.uber.org/multierr/README.md @@ -15,9 +15,9 @@ Stable: No breaking changes will be made before 2.0. Released under the [MIT License]. [MIT License]: LICENSE.txt -[doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr -[doc]: https://pkg.go.dev/go.uber.org/multierr -[ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg +[doc-img]: https://godoc.org/go.uber.org/multierr?status.svg +[doc]: https://godoc.org/go.uber.org/multierr +[ci-img]: https://travis-ci.com/uber-go/multierr.svg?branch=master [cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg -[ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml +[ci]: https://travis-ci.com/uber-go/multierr [cov]: https://codecov.io/gh/uber-go/multierr diff --git a/vendor/go.uber.org/multierr/error.go b/vendor/go.uber.org/multierr/error.go index f45af149c10..5c9b67d5379 100644 --- a/vendor/go.uber.org/multierr/error.go +++ b/vendor/go.uber.org/multierr/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021 Uber Technologies, Inc. +// Copyright (c) 2019 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -35,53 +35,8 @@ // // err = multierr.Append(reader.Close(), writer.Close()) // -// The underlying list of errors for a returned error object may be retrieved -// with the Errors function. -// -// errors := multierr.Errors(err) -// if len(errors) > 0 { -// fmt.Println("The following errors occurred:", errors) -// } -// -// Appending from a loop -// -// You sometimes need to append into an error from a loop. -// -// var err error -// for _, item := range items { -// err = multierr.Append(err, process(item)) -// } -// -// Cases like this may require knowledge of whether an individual instance -// failed. This usually requires introduction of a new variable. -// -// var err error -// for _, item := range items { -// if perr := process(item); perr != nil { -// log.Warn("skipping item", item) -// err = multierr.Append(err, perr) -// } -// } -// -// multierr includes AppendInto to simplify cases like this. -// -// var err error -// for _, item := range items { -// if multierr.AppendInto(&err, process(item)) { -// log.Warn("skipping item", item) -// } -// } -// -// This will append the error into the err variable, and return true if that -// individual error was non-nil. -// -// See AppendInto for more information. -// -// Deferred Functions -// -// Go makes it possible to modify the return value of a function in a defer -// block if the function was using named returns. This makes it possible to -// record resource cleanup failures from deferred blocks. +// This makes it possible to record resource cleanup failures from deferred +// blocks with the help of named return values. // // func sendRequest(req Request) (err error) { // conn, err := openConnection() @@ -94,21 +49,14 @@ // // ... // } // -// multierr provides the Invoker type and AppendInvoke function to make cases -// like the above simpler and obviate the need for a closure. The following is -// roughly equivalent to the example above. +// The underlying list of errors for a returned error object may be retrieved +// with the Errors function. // -// func sendRequest(req Request) (err error) { -// conn, err := openConnection() -// if err != nil { -// return err -// } -// defer multierr.AppendInvoke(&err, multierr.Close(conn)) -// // ... +// errors := multierr.Errors(err) +// if len(errors) > 0 { +// fmt.Println("The following errors occurred:", errors) // } // -// See AppendInvoke and Invoker for more information. -// // Advanced Usage // // Errors returned by Combine and Append MAY implement the following @@ -139,7 +87,6 @@ package multierr // import "go.uber.org/multierr" import ( "bytes" - "errors" "fmt" "io" "strings" @@ -239,33 +186,6 @@ func (merr *multiError) Errors() []error { return merr.errors } -// As attempts to find the first error in the error list that matches the type -// of the value that target points to. -// -// This function allows errors.As to traverse the values stored on the -// multierr error. -func (merr *multiError) As(target interface{}) bool { - for _, err := range merr.Errors() { - if errors.As(err, target) { - return true - } - } - return false -} - -// Is attempts to match the provided error against errors in the error list. -// -// This function allows errors.Is to traverse the values stored on the -// multierr error. -func (merr *multiError) Is(target error) bool { - for _, err := range merr.Errors() { - if errors.Is(err, target) { - return true - } - } - return false -} - func (merr *multiError) Error() string { if merr == nil { return "" @@ -372,14 +292,6 @@ func inspect(errors []error) (res inspectResult) { // fromSlice converts the given list of errors into a single error. func fromSlice(errors []error) error { - // Don't pay to inspect small slices. - switch len(errors) { - case 0: - return nil - case 1: - return errors[0] - } - res := inspect(errors) switch res.Count { case 0: @@ -389,13 +301,8 @@ func fromSlice(errors []error) error { return errors[res.FirstErrorIdx] case len(errors): if !res.ContainsMultiError { - // Error list is flat. Make a copy of it - // Otherwise "errors" escapes to the heap - // unconditionally for all other cases. - // This lets us optimize for the "no errors" case. - out := make([]error, len(errors)) - copy(out, errors) - return &multiError{errors: out} + // already flat + return &multiError{errors: errors} } } @@ -514,7 +421,7 @@ func Append(left error, right error) error { // items = append(items, item) // } // -// Compare this with a version that relies solely on Append: +// Compare this with a verison that relies solely on Append: // // var err error // for line := range lines { @@ -540,113 +447,3 @@ func AppendInto(into *error, err error) (errored bool) { *into = Append(*into, err) return true } - -// Invoker is an operation that may fail with an error. Use it with -// AppendInvoke to append the result of calling the function into an error. -// This allows you to conveniently defer capture of failing operations. -// -// See also, Close and Invoke. -type Invoker interface { - Invoke() error -} - -// Invoke wraps a function which may fail with an error to match the Invoker -// interface. Use it to supply functions matching this signature to -// AppendInvoke. -// -// For example, -// -// func processReader(r io.Reader) (err error) { -// scanner := bufio.NewScanner(r) -// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) -// for scanner.Scan() { -// // ... -// } -// // ... -// } -// -// In this example, the following line will construct the Invoker right away, -// but defer the invocation of scanner.Err() until the function returns. -// -// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) -type Invoke func() error - -// Invoke calls the supplied function and returns its result. -func (i Invoke) Invoke() error { return i() } - -// Close builds an Invoker that closes the provided io.Closer. Use it with -// AppendInvoke to close io.Closers and append their results into an error. -// -// For example, -// -// func processFile(path string) (err error) { -// f, err := os.Open(path) -// if err != nil { -// return err -// } -// defer multierr.AppendInvoke(&err, multierr.Close(f)) -// return processReader(f) -// } -// -// In this example, multierr.Close will construct the Invoker right away, but -// defer the invocation of f.Close until the function returns. -// -// defer multierr.AppendInvoke(&err, multierr.Close(f)) -func Close(closer io.Closer) Invoker { - return Invoke(closer.Close) -} - -// AppendInvoke appends the result of calling the given Invoker into the -// provided error pointer. Use it with named returns to safely defer -// invocation of fallible operations until a function returns, and capture the -// resulting errors. -// -// func doSomething(...) (err error) { -// // ... -// f, err := openFile(..) -// if err != nil { -// return err -// } -// -// // multierr will call f.Close() when this function returns and -// // if the operation fails, its append its error into the -// // returned error. -// defer multierr.AppendInvoke(&err, multierr.Close(f)) -// -// scanner := bufio.NewScanner(f) -// // Similarly, this scheduled scanner.Err to be called and -// // inspected when the function returns and append its error -// // into the returned error. -// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err)) -// -// // ... -// } -// -// Without defer, AppendInvoke behaves exactly like AppendInto. -// -// err := // ... -// multierr.AppendInvoke(&err, mutltierr.Invoke(foo)) -// -// // ...is roughly equivalent to... -// -// err := // ... -// multierr.AppendInto(&err, foo()) -// -// The advantage of the indirection introduced by Invoker is to make it easy -// to defer the invocation of a function. Without this indirection, the -// invoked function will be evaluated at the time of the defer block rather -// than when the function returns. -// -// // BAD: This is likely not what the caller intended. This will evaluate -// // foo() right away and append its result into the error when the -// // function returns. -// defer multierr.AppendInto(&err, foo()) -// -// // GOOD: This will defer invocation of foo unutil the function returns. -// defer multierr.AppendInvoke(&err, multierr.Invoke(foo)) -// -// multierr provides a few Invoker implementations out of the box for -// convenience. See Invoker for more information. -func AppendInvoke(into *error, invoker Invoker) { - AppendInto(into, invoker.Invoke()) -} diff --git a/vendor/go.uber.org/multierr/go113.go b/vendor/go.uber.org/multierr/go113.go new file mode 100644 index 00000000000..264b0eac0dd --- /dev/null +++ b/vendor/go.uber.org/multierr/go113.go @@ -0,0 +1,52 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// +build go1.13 + +package multierr + +import "errors" + +// As attempts to find the first error in the error list that matches the type +// of the value that target points to. +// +// This function allows errors.As to traverse the values stored on the +// multierr error. +func (merr *multiError) As(target interface{}) bool { + for _, err := range merr.Errors() { + if errors.As(err, target) { + return true + } + } + return false +} + +// Is attempts to match the provided error against errors in the error list. +// +// This function allows errors.Is to traverse the values stored on the +// multierr error. +func (merr *multiError) Is(target error) bool { + for _, err := range merr.Errors() { + if errors.Is(err, target) { + return true + } + } + return false +} diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md index 1793b08c89a..0db1f9f15fe 100644 --- a/vendor/go.uber.org/zap/CHANGELOG.md +++ b/vendor/go.uber.org/zap/CHANGELOG.md @@ -3,6 +3,59 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 1.24.0 (30 Nov 2022) + +Enhancements: +* [#1148][]: Add `Level` to both `Logger` and `SugaredLogger` that reports the + current minimum enabled log level. +* [#1185][]: `SugaredLogger` turns errors to zap.Error automatically. + +Thanks to @Abirdcfly, @craigpastro, @nnnkkk7, and @sashamelentyev for their +contributions to this release. + +[#1148]: https://github.coml/uber-go/zap/pull/1148 +[#1185]: https://github.coml/uber-go/zap/pull/1185 + +## 1.23.0 (24 Aug 2022) + +Enhancements: +* [#1147][]: Add a `zapcore.LevelOf` function to determine the level of a + `LevelEnabler` or `Core`. +* [#1155][]: Add `zap.Stringers` field constructor to log arrays of objects + that implement `String() string`. + +[#1147]: https://github.com/uber-go/zap/pull/1147 +[#1155]: https://github.com/uber-go/zap/pull/1155 + + +## 1.22.0 (8 Aug 2022) + +Enhancements: +* [#1071][]: Add `zap.Objects` and `zap.ObjectValues` field constructors to log + arrays of objects. With these two constructors, you don't need to implement + `zapcore.ArrayMarshaler` for use with `zap.Array` if those objects implement + `zapcore.ObjectMarshaler`. +* [#1079][]: Add `SugaredLogger.WithOptions` to build a copy of an existing + `SugaredLogger` with the provided options applied. +* [#1080][]: Add `*ln` variants to `SugaredLogger` for each log level. + These functions provide a string joining behavior similar to `fmt.Println`. +* [#1088][]: Add `zap.WithFatalHook` option to control the behavior of the + logger for `Fatal`-level log entries. This defaults to exiting the program. +* [#1108][]: Add a `zap.Must` function that you can use with `NewProduction` or + `NewDevelopment` to panic if the system was unable to build the logger. +* [#1118][]: Add a `Logger.Log` method that allows specifying the log level for + a statement dynamically. + +Thanks to @cardil, @craigpastro, @sashamelentyev, @shota3506, and @zhupeijun +for their contributions to this release. + +[#1071]: https://github.com/uber-go/zap/pull/1071 +[#1079]: https://github.com/uber-go/zap/pull/1079 +[#1080]: https://github.com/uber-go/zap/pull/1080 +[#1088]: https://github.com/uber-go/zap/pull/1088 +[#1108]: https://github.com/uber-go/zap/pull/1108 +[#1118]: https://github.com/uber-go/zap/pull/1118 + ## 1.21.0 (7 Feb 2022) Enhancements: diff --git a/vendor/go.uber.org/zap/CONTRIBUTING.md b/vendor/go.uber.org/zap/CONTRIBUTING.md index 5cd96568713..ea02f3cae2d 100644 --- a/vendor/go.uber.org/zap/CONTRIBUTING.md +++ b/vendor/go.uber.org/zap/CONTRIBUTING.md @@ -16,7 +16,7 @@ you to accept the CLA when you open your pull request. [Fork][fork], then clone the repository: -``` +```bash mkdir -p $GOPATH/src/go.uber.org cd $GOPATH/src/go.uber.org git clone git@github.com:your_github_username/zap.git @@ -27,21 +27,16 @@ git fetch upstream Make sure that the tests and the linters pass: -``` +```bash make test make lint ``` -If you're not using the minor version of Go specified in the Makefile's -`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is -fine, but it means that you'll only discover lint failures after you open your -pull request. - ## Making Changes Start by creating a new branch for your changes: -``` +```bash cd $GOPATH/src/go.uber.org/zap git checkout master git fetch upstream @@ -52,22 +47,22 @@ git checkout -b cool_new_feature Make your changes, then ensure that `make lint` and `make test` still pass. If you're satisfied with your changes, push them to your fork. -``` +```bash git push origin cool_new_feature ``` Then use the GitHub UI to open a pull request. -At this point, you're waiting on us to review your changes. We *try* to respond +At this point, you're waiting on us to review your changes. We _try_ to respond to issues and pull requests within a few business days, and we may suggest some improvements or alternatives. Once your changes are approved, one of the project maintainers will merge them. We're much more likely to approve your changes if you: -* Add tests for new functionality. -* Write a [good commit message][commit-message]. -* Maintain backward compatibility. +- Add tests for new functionality. +- Write a [good commit message][commit-message]. +- Maintain backward compatibility. [fork]: https://github.com/uber-go/zap/fork [open-issue]: https://github.com/uber-go/zap/issues/new diff --git a/vendor/go.uber.org/zap/README.md b/vendor/go.uber.org/zap/README.md index 9c9dfe1ed7b..a553a428c8f 100644 --- a/vendor/go.uber.org/zap/README.md +++ b/vendor/go.uber.org/zap/README.md @@ -54,7 +54,7 @@ and make many small allocations. Put differently, using `encoding/json` and Zap takes a different approach. It includes a reflection-free, zero-allocation JSON encoder, and the base `Logger` strives to avoid serialization overhead and allocations wherever possible. By building the high-level `SugaredLogger` -on that foundation, zap lets users *choose* when they need to count every +on that foundation, zap lets users _choose_ when they need to count every allocation and when they'd prefer a more familiar, loosely typed API. As measured by its own [benchmarking suite][], not only is zap more performant @@ -64,40 +64,40 @@ id="anchor-versions">[1](#footnote-versions) Log a message and 10 fields: -| Package | Time | Time % to zap | Objects Allocated | -| :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 2900 ns/op | +0% | 5 allocs/op -| :zap: zap (sugared) | 3475 ns/op | +20% | 10 allocs/op -| zerolog | 10639 ns/op | +267% | 32 allocs/op -| go-kit | 14434 ns/op | +398% | 59 allocs/op -| logrus | 17104 ns/op | +490% | 81 allocs/op -| apex/log | 32424 ns/op | +1018% | 66 allocs/op -| log15 | 33579 ns/op | +1058% | 76 allocs/op +| Package | Time | Time % to zap | Objects Allocated | +| :------------------ | :---------: | :-----------: | :---------------: | +| :zap: zap | 2900 ns/op | +0% | 5 allocs/op | +| :zap: zap (sugared) | 3475 ns/op | +20% | 10 allocs/op | +| zerolog | 10639 ns/op | +267% | 32 allocs/op | +| go-kit | 14434 ns/op | +398% | 59 allocs/op | +| logrus | 17104 ns/op | +490% | 81 allocs/op | +| apex/log | 32424 ns/op | +1018% | 66 allocs/op | +| log15 | 33579 ns/op | +1058% | 76 allocs/op | Log a message with a logger that already has 10 fields of context: -| Package | Time | Time % to zap | Objects Allocated | -| :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 373 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 452 ns/op | +21% | 1 allocs/op -| zerolog | 288 ns/op | -23% | 0 allocs/op -| go-kit | 11785 ns/op | +3060% | 58 allocs/op -| logrus | 19629 ns/op | +5162% | 70 allocs/op -| log15 | 21866 ns/op | +5762% | 72 allocs/op -| apex/log | 30890 ns/op | +8182% | 55 allocs/op +| Package | Time | Time % to zap | Objects Allocated | +| :------------------ | :---------: | :-----------: | :---------------: | +| :zap: zap | 373 ns/op | +0% | 0 allocs/op | +| :zap: zap (sugared) | 452 ns/op | +21% | 1 allocs/op | +| zerolog | 288 ns/op | -23% | 0 allocs/op | +| go-kit | 11785 ns/op | +3060% | 58 allocs/op | +| logrus | 19629 ns/op | +5162% | 70 allocs/op | +| log15 | 21866 ns/op | +5762% | 72 allocs/op | +| apex/log | 30890 ns/op | +8182% | 55 allocs/op | Log a static string, without any context or `printf`-style templating: -| Package | Time | Time % to zap | Objects Allocated | -| :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 381 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 410 ns/op | +8% | 1 allocs/op -| zerolog | 369 ns/op | -3% | 0 allocs/op -| standard library | 385 ns/op | +1% | 2 allocs/op -| go-kit | 606 ns/op | +59% | 11 allocs/op -| logrus | 1730 ns/op | +354% | 25 allocs/op -| apex/log | 1998 ns/op | +424% | 7 allocs/op -| log15 | 4546 ns/op | +1093% | 22 allocs/op +| Package | Time | Time % to zap | Objects Allocated | +| :------------------ | :--------: | :-----------: | :---------------: | +| :zap: zap | 381 ns/op | +0% | 0 allocs/op | +| :zap: zap (sugared) | 410 ns/op | +8% | 1 allocs/op | +| zerolog | 369 ns/op | -3% | 0 allocs/op | +| standard library | 385 ns/op | +1% | 2 allocs/op | +| go-kit | 606 ns/op | +59% | 11 allocs/op | +| logrus | 1730 ns/op | +354% | 25 allocs/op | +| apex/log | 1998 ns/op | +424% | 7 allocs/op | +| log15 | 4546 ns/op | +1093% | 22 allocs/op | ## Development Status: Stable @@ -131,4 +131,3 @@ pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions) [cov]: https://codecov.io/gh/uber-go/zap [benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks [benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod - diff --git a/vendor/go.uber.org/zap/array_go118.go b/vendor/go.uber.org/zap/array_go118.go new file mode 100644 index 00000000000..d0d2c49d698 --- /dev/null +++ b/vendor/go.uber.org/zap/array_go118.go @@ -0,0 +1,156 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 +// +build go1.18 + +package zap + +import ( + "fmt" + + "go.uber.org/zap/zapcore" +) + +// Objects constructs a field with the given key, holding a list of the +// provided objects that can be marshaled by Zap. +// +// Note that these objects must implement zapcore.ObjectMarshaler directly. +// That is, if you're trying to marshal a []Request, the MarshalLogObject +// method must be declared on the Request type, not its pointer (*Request). +// If it's on the pointer, use ObjectValues. +// +// Given an object that implements MarshalLogObject on the value receiver, you +// can log a slice of those objects with Objects like so: +// +// type Author struct{ ... } +// func (a Author) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var authors []Author = ... +// logger.Info("loading article", zap.Objects("authors", authors)) +// +// Similarly, given a type that implements MarshalLogObject on its pointer +// receiver, you can log a slice of pointers to that object with Objects like +// so: +// +// type Request struct{ ... } +// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var requests []*Request = ... +// logger.Info("sending requests", zap.Objects("requests", requests)) +// +// If instead, you have a slice of values of such an object, use the +// ObjectValues constructor. +// +// var requests []Request = ... +// logger.Info("sending requests", zap.ObjectValues("requests", requests)) +func Objects[T zapcore.ObjectMarshaler](key string, values []T) Field { + return Array(key, objects[T](values)) +} + +type objects[T zapcore.ObjectMarshaler] []T + +func (os objects[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for _, o := range os { + if err := arr.AppendObject(o); err != nil { + return err + } + } + return nil +} + +// ObjectMarshalerPtr is a constraint that specifies that the given type +// implements zapcore.ObjectMarshaler on a pointer receiver. +type ObjectMarshalerPtr[T any] interface { + *T + zapcore.ObjectMarshaler +} + +// ObjectValues constructs a field with the given key, holding a list of the +// provided objects, where pointers to these objects can be marshaled by Zap. +// +// Note that pointers to these objects must implement zapcore.ObjectMarshaler. +// That is, if you're trying to marshal a []Request, the MarshalLogObject +// method must be declared on the *Request type, not the value (Request). +// If it's on the value, use Objects. +// +// Given an object that implements MarshalLogObject on the pointer receiver, +// you can log a slice of those objects with ObjectValues like so: +// +// type Request struct{ ... } +// func (r *Request) MarshalLogObject(enc zapcore.ObjectEncoder) error +// +// var requests []Request = ... +// logger.Info("sending requests", zap.ObjectValues("requests", requests)) +// +// If instead, you have a slice of pointers of such an object, use the Objects +// field constructor. +// +// var requests []*Request = ... +// logger.Info("sending requests", zap.Objects("requests", requests)) +func ObjectValues[T any, P ObjectMarshalerPtr[T]](key string, values []T) Field { + return Array(key, objectValues[T, P](values)) +} + +type objectValues[T any, P ObjectMarshalerPtr[T]] []T + +func (os objectValues[T, P]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for i := range os { + // It is necessary for us to explicitly reference the "P" type. + // We cannot simply pass "&os[i]" to AppendObject because its type + // is "*T", which the type system does not consider as + // implementing ObjectMarshaler. + // Only the type "P" satisfies ObjectMarshaler, which we have + // to convert "*T" to explicitly. + var p P = &os[i] + if err := arr.AppendObject(p); err != nil { + return err + } + } + return nil +} + +// Stringers constructs a field with the given key, holding a list of the +// output provided by the value's String method +// +// Given an object that implements String on the value receiver, you +// can log a slice of those objects with Objects like so: +// +// type Request struct{ ... } +// func (a Request) String() string +// +// var requests []Request = ... +// logger.Info("sending requests", zap.Stringers("requests", requests)) +// +// Note that these objects must implement fmt.Stringer directly. +// That is, if you're trying to marshal a []Request, the String method +// must be declared on the Request type, not its pointer (*Request). +func Stringers[T fmt.Stringer](key string, values []T) Field { + return Array(key, stringers[T](values)) +} + +type stringers[T fmt.Stringer] []T + +func (os stringers[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for _, o := range os { + arr.AppendString(o.String()) + } + return nil +} diff --git a/vendor/go.uber.org/zap/config.go b/vendor/go.uber.org/zap/config.go index 55637fb0b4b..ee6096766a8 100644 --- a/vendor/go.uber.org/zap/config.go +++ b/vendor/go.uber.org/zap/config.go @@ -21,7 +21,7 @@ package zap import ( - "fmt" + "errors" "sort" "time" @@ -182,7 +182,7 @@ func (cfg Config) Build(opts ...Option) (*Logger, error) { } if cfg.Level == (AtomicLevel{}) { - return nil, fmt.Errorf("missing Level") + return nil, errors.New("missing Level") } log := New( diff --git a/vendor/go.uber.org/zap/doc.go b/vendor/go.uber.org/zap/doc.go index 8638dd1b965..3c50d7b4d3f 100644 --- a/vendor/go.uber.org/zap/doc.go +++ b/vendor/go.uber.org/zap/doc.go @@ -32,7 +32,7 @@ // they need to count every allocation and when they'd prefer a more familiar, // loosely typed API. // -// Choosing a Logger +// # Choosing a Logger // // In contexts where performance is nice, but not critical, use the // SugaredLogger. It's 4-10x faster than other structured logging packages and @@ -41,14 +41,15 @@ // variadic number of key-value pairs. (For more advanced use cases, they also // accept strongly typed fields - see the SugaredLogger.With documentation for // details.) -// sugar := zap.NewExample().Sugar() -// defer sugar.Sync() -// sugar.Infow("failed to fetch URL", -// "url", "http://example.com", -// "attempt", 3, -// "backoff", time.Second, -// ) -// sugar.Infof("failed to fetch URL: %s", "http://example.com") +// +// sugar := zap.NewExample().Sugar() +// defer sugar.Sync() +// sugar.Infow("failed to fetch URL", +// "url", "http://example.com", +// "attempt", 3, +// "backoff", time.Second, +// ) +// sugar.Infof("failed to fetch URL: %s", "http://example.com") // // By default, loggers are unbuffered. However, since zap's low-level APIs // allow buffering, calling Sync before letting your process exit is a good @@ -57,32 +58,35 @@ // In the rare contexts where every microsecond and every allocation matter, // use the Logger. It's even faster than the SugaredLogger and allocates far // less, but it only supports strongly-typed, structured logging. -// logger := zap.NewExample() -// defer logger.Sync() -// logger.Info("failed to fetch URL", -// zap.String("url", "http://example.com"), -// zap.Int("attempt", 3), -// zap.Duration("backoff", time.Second), -// ) +// +// logger := zap.NewExample() +// defer logger.Sync() +// logger.Info("failed to fetch URL", +// zap.String("url", "http://example.com"), +// zap.Int("attempt", 3), +// zap.Duration("backoff", time.Second), +// ) // // Choosing between the Logger and SugaredLogger doesn't need to be an // application-wide decision: converting between the two is simple and // inexpensive. -// logger := zap.NewExample() -// defer logger.Sync() -// sugar := logger.Sugar() -// plain := sugar.Desugar() // -// Configuring Zap +// logger := zap.NewExample() +// defer logger.Sync() +// sugar := logger.Sugar() +// plain := sugar.Desugar() +// +// # Configuring Zap // // The simplest way to build a Logger is to use zap's opinionated presets: // NewExample, NewProduction, and NewDevelopment. These presets build a logger // with a single function call: -// logger, err := zap.NewProduction() -// if err != nil { -// log.Fatalf("can't initialize zap logger: %v", err) -// } -// defer logger.Sync() +// +// logger, err := zap.NewProduction() +// if err != nil { +// log.Fatalf("can't initialize zap logger: %v", err) +// } +// defer logger.Sync() // // Presets are fine for small projects, but larger projects and organizations // naturally require a bit more customization. For most users, zap's Config @@ -94,7 +98,7 @@ // go.uber.org/zap/zapcore. See the package-level AdvancedConfiguration // example for sample code. // -// Extending Zap +// # Extending Zap // // The zap package itself is a relatively thin wrapper around the interfaces // in go.uber.org/zap/zapcore. Extending zap to support a new encoding (e.g., @@ -106,7 +110,7 @@ // Similarly, package authors can use the high-performance Encoder and Core // implementations in the zapcore package to build their own loggers. // -// Frequently Asked Questions +// # Frequently Asked Questions // // An FAQ covering everything from installation errors to design decisions is // available at https://github.com/uber-go/zap/blob/master/FAQ.md. diff --git a/vendor/go.uber.org/zap/encoder.go b/vendor/go.uber.org/zap/encoder.go index 08ed8335436..caa04ceefd8 100644 --- a/vendor/go.uber.org/zap/encoder.go +++ b/vendor/go.uber.org/zap/encoder.go @@ -63,7 +63,7 @@ func RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapco func newEncoder(name string, encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) { if encoderConfig.TimeKey != "" && encoderConfig.EncodeTime == nil { - return nil, fmt.Errorf("missing EncodeTime in EncoderConfig") + return nil, errors.New("missing EncodeTime in EncoderConfig") } _encoderMutex.RLock() diff --git a/vendor/go.uber.org/zap/http_handler.go b/vendor/go.uber.org/zap/http_handler.go index 1297c33b328..632b6831a85 100644 --- a/vendor/go.uber.org/zap/http_handler.go +++ b/vendor/go.uber.org/zap/http_handler.go @@ -22,6 +22,7 @@ package zap import ( "encoding/json" + "errors" "fmt" "io" "net/http" @@ -32,22 +33,23 @@ import ( // ServeHTTP is a simple JSON endpoint that can report on or change the current // logging level. // -// GET +// # GET // // The GET request returns a JSON description of the current logging level like: -// {"level":"info"} // -// PUT +// {"level":"info"} +// +// # PUT // // The PUT request changes the logging level. It is perfectly safe to change the // logging level while a program is running. Two content types are supported: // -// Content-Type: application/x-www-form-urlencoded +// Content-Type: application/x-www-form-urlencoded // // With this content type, the level can be provided through the request body or // a query parameter. The log level is URL encoded like: // -// level=debug +// level=debug // // The request body takes precedence over the query parameter, if both are // specified. @@ -55,18 +57,17 @@ import ( // This content type is the default for a curl PUT request. Following are two // example curl requests that both set the logging level to debug. // -// curl -X PUT localhost:8080/log/level?level=debug -// curl -X PUT localhost:8080/log/level -d level=debug +// curl -X PUT localhost:8080/log/level?level=debug +// curl -X PUT localhost:8080/log/level -d level=debug // // For any other content type, the payload is expected to be JSON encoded and // look like: // -// {"level":"info"} +// {"level":"info"} // // An example curl request could look like this: // -// curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}' -// +// curl -X PUT localhost:8080/log/level -H "Content-Type: application/json" -d '{"level":"debug"}' func (lvl AtomicLevel) ServeHTTP(w http.ResponseWriter, r *http.Request) { type errorResponse struct { Error string `json:"error"` @@ -108,7 +109,7 @@ func decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error func decodePutURL(r *http.Request) (zapcore.Level, error) { lvl := r.FormValue("level") if lvl == "" { - return 0, fmt.Errorf("must specify logging level") + return 0, errors.New("must specify logging level") } var l zapcore.Level if err := l.UnmarshalText([]byte(lvl)); err != nil { @@ -125,7 +126,7 @@ func decodePutJSON(body io.Reader) (zapcore.Level, error) { return 0, fmt.Errorf("malformed request body: %v", err) } if pld.Level == nil { - return 0, fmt.Errorf("must specify logging level") + return 0, errors.New("must specify logging level") } return *pld.Level, nil diff --git a/vendor/go.uber.org/zap/internal/exit/exit.go b/vendor/go.uber.org/zap/internal/exit/exit.go index dfc5b05feb7..f673f9947b8 100644 --- a/vendor/go.uber.org/zap/internal/exit/exit.go +++ b/vendor/go.uber.org/zap/internal/exit/exit.go @@ -24,24 +24,25 @@ package exit import "os" -var real = func() { os.Exit(1) } +var _exit = os.Exit -// Exit normally terminates the process by calling os.Exit(1). If the package -// is stubbed, it instead records a call in the testing spy. -func Exit() { - real() +// With terminates the process by calling os.Exit(code). If the package is +// stubbed, it instead records a call in the testing spy. +func With(code int) { + _exit(code) } // A StubbedExit is a testing fake for os.Exit. type StubbedExit struct { Exited bool - prev func() + Code int + prev func(code int) } // Stub substitutes a fake for the call to os.Exit(1). func Stub() *StubbedExit { - s := &StubbedExit{prev: real} - real = s.exit + s := &StubbedExit{prev: _exit} + _exit = s.exit return s } @@ -56,9 +57,10 @@ func WithStub(f func()) *StubbedExit { // Unstub restores the previous exit function. func (se *StubbedExit) Unstub() { - real = se.prev + _exit = se.prev } -func (se *StubbedExit) exit() { +func (se *StubbedExit) exit(code int) { se.Exited = true + se.Code = code } diff --git a/vendor/go.uber.org/zap/internal/level_enabler.go b/vendor/go.uber.org/zap/internal/level_enabler.go new file mode 100644 index 00000000000..5f3e3f1b924 --- /dev/null +++ b/vendor/go.uber.org/zap/internal/level_enabler.go @@ -0,0 +1,35 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package internal + +import "go.uber.org/zap/zapcore" + +// LeveledEnabler is an interface satisfied by LevelEnablers that are able to +// report their own level. +// +// This interface is defined to use more conveniently in tests and non-zapcore +// packages. +// This cannot be imported from zapcore because of the cyclic dependency. +type LeveledEnabler interface { + zapcore.LevelEnabler + + Level() zapcore.Level +} diff --git a/vendor/go.uber.org/zap/level.go b/vendor/go.uber.org/zap/level.go index 8f86c430f0f..db951e19a50 100644 --- a/vendor/go.uber.org/zap/level.go +++ b/vendor/go.uber.org/zap/level.go @@ -22,6 +22,7 @@ package zap import ( "go.uber.org/atomic" + "go.uber.org/zap/internal" "go.uber.org/zap/zapcore" ) @@ -70,6 +71,8 @@ type AtomicLevel struct { l *atomic.Int32 } +var _ internal.LeveledEnabler = AtomicLevel{} + // NewAtomicLevel creates an AtomicLevel with InfoLevel and above logging // enabled. func NewAtomicLevel() AtomicLevel { diff --git a/vendor/go.uber.org/zap/logger.go b/vendor/go.uber.org/zap/logger.go index 087c7422281..cd44030d13f 100644 --- a/vendor/go.uber.org/zap/logger.go +++ b/vendor/go.uber.org/zap/logger.go @@ -22,7 +22,7 @@ package zap import ( "fmt" - "io/ioutil" + "io" "os" "strings" @@ -42,7 +42,7 @@ type Logger struct { development bool addCaller bool - onFatal zapcore.CheckWriteAction // default is WriteThenFatal + onFatal zapcore.CheckWriteHook // default is WriteThenFatal name string errorOutput zapcore.WriteSyncer @@ -85,7 +85,7 @@ func New(core zapcore.Core, options ...Option) *Logger { func NewNop() *Logger { return &Logger{ core: zapcore.NewNopCore(), - errorOutput: zapcore.AddSync(ioutil.Discard), + errorOutput: zapcore.AddSync(io.Discard), addStack: zapcore.FatalLevel + 1, clock: zapcore.DefaultClock, } @@ -107,6 +107,19 @@ func NewDevelopment(options ...Option) (*Logger, error) { return NewDevelopmentConfig().Build(options...) } +// Must is a helper that wraps a call to a function returning (*Logger, error) +// and panics if the error is non-nil. It is intended for use in variable +// initialization such as: +// +// var logger = zap.Must(zap.NewProduction()) +func Must(logger *Logger, err error) *Logger { + if err != nil { + panic(err) + } + + return logger +} + // NewExample builds a Logger that's designed for use in zap's testable // examples. It writes DebugLevel and above logs to standard out as JSON, but // omits the timestamp and calling function to keep example output @@ -170,6 +183,13 @@ func (log *Logger) With(fields ...Field) *Logger { return l } +// Level reports the minimum enabled level for this logger. +// +// For NopLoggers, this is [zapcore.InvalidLevel]. +func (log *Logger) Level() zapcore.Level { + return zapcore.LevelOf(log.core) +} + // Check returns a CheckedEntry if logging a message at the specified level // is enabled. It's a completely optional optimization; in high-performance // applications, Check can help avoid allocating a slice to hold fields. @@ -177,6 +197,14 @@ func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { return log.check(lvl, msg) } +// Log logs a message at the specified level. The message includes any fields +// passed at the log site, as well as any fields accumulated on the logger. +func (log *Logger) Log(lvl zapcore.Level, msg string, fields ...Field) { + if ce := log.check(lvl, msg); ce != nil { + ce.Write(fields...) + } +} + // Debug logs a message at DebugLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. func (log *Logger) Debug(msg string, fields ...Field) { @@ -285,18 +313,27 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Set up any required terminal behavior. switch ent.Level { case zapcore.PanicLevel: - ce = ce.Should(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, zapcore.WriteThenPanic) case zapcore.FatalLevel: onFatal := log.onFatal - // Noop is the default value for CheckWriteAction, and it leads to - // continued execution after a Fatal which is unexpected. - if onFatal == zapcore.WriteThenNoop { + // nil or WriteThenNoop will lead to continued execution after + // a Fatal log entry, which is unexpected. For example, + // + // f, err := os.Open(..) + // if err != nil { + // log.Fatal("cannot open", zap.Error(err)) + // } + // fmt.Println(f.Name()) + // + // The f.Name() will panic if we continue execution after the + // log.Fatal. + if onFatal == nil || onFatal == zapcore.WriteThenNoop { onFatal = zapcore.WriteThenFatal } - ce = ce.Should(ent, onFatal) + ce = ce.After(ent, onFatal) case zapcore.DPanicLevel: if log.development { - ce = ce.Should(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, zapcore.WriteThenPanic) } } diff --git a/vendor/go.uber.org/zap/options.go b/vendor/go.uber.org/zap/options.go index e9e66161f51..c4f3bca3d20 100644 --- a/vendor/go.uber.org/zap/options.go +++ b/vendor/go.uber.org/zap/options.go @@ -133,9 +133,28 @@ func IncreaseLevel(lvl zapcore.LevelEnabler) Option { } // OnFatal sets the action to take on fatal logs. +// +// Deprecated: Use [WithFatalHook] instead. func OnFatal(action zapcore.CheckWriteAction) Option { + return WithFatalHook(action) +} + +// WithFatalHook sets a CheckWriteHook to run on fatal logs. +// Zap will call this hook after writing a log statement with a Fatal level. +// +// For example, the following builds a logger that will exit the current +// goroutine after writing a fatal log message, but it will not exit the +// program. +// +// zap.New(core, zap.WithFatalHook(zapcore.WriteThenGoexit)) +// +// It is important that the provided CheckWriteHook stops the control flow at +// the current statement to meet expectations of callers of the logger. +// We recommend calling os.Exit or runtime.Goexit inside custom hooks at +// minimum. +func WithFatalHook(hook zapcore.CheckWriteHook) Option { return optionFunc(func(log *Logger) { - log.onFatal = action + log.onFatal = hook }) } diff --git a/vendor/go.uber.org/zap/sink.go b/vendor/go.uber.org/zap/sink.go index df46fa87a70..478c9a10ffc 100644 --- a/vendor/go.uber.org/zap/sink.go +++ b/vendor/go.uber.org/zap/sink.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,7 @@ import ( "io" "net/url" "os" + "path/filepath" "strings" "sync" @@ -34,23 +35,7 @@ import ( const schemeFile = "file" -var ( - _sinkMutex sync.RWMutex - _sinkFactories map[string]func(*url.URL) (Sink, error) // keyed by scheme -) - -func init() { - resetSinkRegistry() -} - -func resetSinkRegistry() { - _sinkMutex.Lock() - defer _sinkMutex.Unlock() - - _sinkFactories = map[string]func(*url.URL) (Sink, error){ - schemeFile: newFileSink, - } -} +var _sinkRegistry = newSinkRegistry() // Sink defines the interface to write to and close logger destinations. type Sink interface { @@ -58,10 +43,6 @@ type Sink interface { io.Closer } -type nopCloserSink struct{ zapcore.WriteSyncer } - -func (nopCloserSink) Close() error { return nil } - type errSinkNotFound struct { scheme string } @@ -70,16 +51,29 @@ func (e *errSinkNotFound) Error() string { return fmt.Sprintf("no sink found for scheme %q", e.scheme) } -// RegisterSink registers a user-supplied factory for all sinks with a -// particular scheme. -// -// All schemes must be ASCII, valid under section 3.1 of RFC 3986 -// (https://tools.ietf.org/html/rfc3986#section-3.1), and must not already -// have a factory registered. Zap automatically registers a factory for the -// "file" scheme. -func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error { - _sinkMutex.Lock() - defer _sinkMutex.Unlock() +type nopCloserSink struct{ zapcore.WriteSyncer } + +func (nopCloserSink) Close() error { return nil } + +type sinkRegistry struct { + mu sync.Mutex + factories map[string]func(*url.URL) (Sink, error) // keyed by scheme + openFile func(string, int, os.FileMode) (*os.File, error) // type matches os.OpenFile +} + +func newSinkRegistry() *sinkRegistry { + sr := &sinkRegistry{ + factories: make(map[string]func(*url.URL) (Sink, error)), + openFile: os.OpenFile, + } + sr.RegisterSink(schemeFile, sr.newFileSinkFromURL) + return sr +} + +// RegisterScheme registers the given factory for the specific scheme. +func (sr *sinkRegistry) RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error { + sr.mu.Lock() + defer sr.mu.Unlock() if scheme == "" { return errors.New("can't register a sink factory for empty string") @@ -88,14 +82,22 @@ func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error { if err != nil { return fmt.Errorf("%q is not a valid scheme: %v", scheme, err) } - if _, ok := _sinkFactories[normalized]; ok { + if _, ok := sr.factories[normalized]; ok { return fmt.Errorf("sink factory already registered for scheme %q", normalized) } - _sinkFactories[normalized] = factory + sr.factories[normalized] = factory return nil } -func newSink(rawURL string) (Sink, error) { +func (sr *sinkRegistry) newSink(rawURL string) (Sink, error) { + // URL parsing doesn't work well for Windows paths such as `c:\log.txt`, as scheme is set to + // the drive, and path is unset unless `c:/log.txt` is used. + // To avoid Windows-specific URL handling, we instead check IsAbs to open as a file. + // filepath.IsAbs is OS-specific, so IsAbs('c:/log.txt') is false outside of Windows. + if filepath.IsAbs(rawURL) { + return sr.newFileSinkFromPath(rawURL) + } + u, err := url.Parse(rawURL) if err != nil { return nil, fmt.Errorf("can't parse %q as a URL: %v", rawURL, err) @@ -104,16 +106,27 @@ func newSink(rawURL string) (Sink, error) { u.Scheme = schemeFile } - _sinkMutex.RLock() - factory, ok := _sinkFactories[u.Scheme] - _sinkMutex.RUnlock() + sr.mu.Lock() + factory, ok := sr.factories[u.Scheme] + sr.mu.Unlock() if !ok { return nil, &errSinkNotFound{u.Scheme} } return factory(u) } -func newFileSink(u *url.URL) (Sink, error) { +// RegisterSink registers a user-supplied factory for all sinks with a +// particular scheme. +// +// All schemes must be ASCII, valid under section 0.1 of RFC 3986 +// (https://tools.ietf.org/html/rfc3983#section-3.1), and must not already +// have a factory registered. Zap automatically registers a factory for the +// "file" scheme. +func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error { + return _sinkRegistry.RegisterSink(scheme, factory) +} + +func (sr *sinkRegistry) newFileSinkFromURL(u *url.URL) (Sink, error) { if u.User != nil { return nil, fmt.Errorf("user and password not allowed with file URLs: got %v", u) } @@ -130,13 +143,18 @@ func newFileSink(u *url.URL) (Sink, error) { if hn := u.Hostname(); hn != "" && hn != "localhost" { return nil, fmt.Errorf("file URLs must leave host empty or use localhost: got %v", u) } - switch u.Path { + + return sr.newFileSinkFromPath(u.Path) +} + +func (sr *sinkRegistry) newFileSinkFromPath(path string) (Sink, error) { + switch path { case "stdout": return nopCloserSink{os.Stdout}, nil case "stderr": return nopCloserSink{os.Stderr}, nil } - return os.OpenFile(u.Path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) + return sr.openFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) } func normalizeScheme(s string) (string, error) { diff --git a/vendor/go.uber.org/zap/stacktrace.go b/vendor/go.uber.org/zap/stacktrace.go index 3d187fa5666..817a3bde8b1 100644 --- a/vendor/go.uber.org/zap/stacktrace.go +++ b/vendor/go.uber.org/zap/stacktrace.go @@ -154,7 +154,7 @@ func newStackFormatter(b *buffer.Buffer) stackFormatter { // the final runtime.main/runtime.goexit frame. func (sf *stackFormatter) FormatStack(stack *stacktrace) { // Note: On the last iteration, frames.Next() returns false, with a valid - // frame, but we ignore this frame. The last frame is a a runtime frame which + // frame, but we ignore this frame. The last frame is a runtime frame which // adds noise, since it's only either runtime.main or runtime.goexit. for frame, more := stack.Next(); more; frame, more = stack.Next() { sf.FormatFrame(frame) diff --git a/vendor/go.uber.org/zap/sugar.go b/vendor/go.uber.org/zap/sugar.go index 0b9651981a9..ac387b3e47d 100644 --- a/vendor/go.uber.org/zap/sugar.go +++ b/vendor/go.uber.org/zap/sugar.go @@ -31,6 +31,7 @@ import ( const ( _oddNumberErrMsg = "Ignored key without a value." _nonStringKeyErrMsg = "Ignored key-value pairs with non-string keys." + _multipleErrMsg = "Multiple errors without a key." ) // A SugaredLogger wraps the base Logger functionality in a slower, but less @@ -38,10 +39,19 @@ const ( // method. // // Unlike the Logger, the SugaredLogger doesn't insist on structured logging. -// For each log level, it exposes three methods: one for loosely-typed -// structured logging, one for println-style formatting, and one for -// printf-style formatting. For example, SugaredLoggers can produce InfoLevel -// output with Infow ("info with" structured context), Info, or Infof. +// For each log level, it exposes four methods: +// +// - methods named after the log level for log.Print-style logging +// - methods ending in "w" for loosely-typed structured logging +// - methods ending in "f" for log.Printf-style logging +// - methods ending in "ln" for log.Println-style logging +// +// For example, the methods for InfoLevel are: +// +// Info(...any) Print-style logging +// Infow(...any) Structured logging (read as "info with") +// Infof(string, ...any) Printf-style logging +// Infoln(...any) Println-style logging type SugaredLogger struct { base *Logger } @@ -61,27 +71,40 @@ func (s *SugaredLogger) Named(name string) *SugaredLogger { return &SugaredLogger{base: s.base.Named(name)} } +// WithOptions clones the current SugaredLogger, applies the supplied Options, +// and returns the result. It's safe to use concurrently. +func (s *SugaredLogger) WithOptions(opts ...Option) *SugaredLogger { + base := s.base.clone() + for _, opt := range opts { + opt.apply(base) + } + return &SugaredLogger{base: base} +} + // With adds a variadic number of fields to the logging context. It accepts a // mix of strongly-typed Field objects and loosely-typed key-value pairs. When // processing pairs, the first element of the pair is used as the field key // and the second as the field value. // // For example, -// sugaredLogger.With( -// "hello", "world", -// "failure", errors.New("oh no"), -// Stack(), -// "count", 42, -// "user", User{Name: "alice"}, -// ) +// +// sugaredLogger.With( +// "hello", "world", +// "failure", errors.New("oh no"), +// Stack(), +// "count", 42, +// "user", User{Name: "alice"}, +// ) +// // is the equivalent of -// unsugared.With( -// String("hello", "world"), -// String("failure", "oh no"), -// Stack(), -// Int("count", 42), -// Object("user", User{Name: "alice"}), -// ) +// +// unsugared.With( +// String("hello", "world"), +// String("failure", "oh no"), +// Stack(), +// Int("count", 42), +// Object("user", User{Name: "alice"}), +// ) // // Note that the keys in key-value pairs should be strings. In development, // passing a non-string key panics. In production, the logger is more @@ -92,6 +115,13 @@ func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger { return &SugaredLogger{base: s.base.With(s.sweetenFields(args)...)} } +// Level reports the minimum enabled level for this logger. +// +// For NopLoggers, this is [zapcore.InvalidLevel]. +func (s *SugaredLogger) Level() zapcore.Level { + return zapcore.LevelOf(s.base.core) +} + // Debug uses fmt.Sprint to construct and log a message. func (s *SugaredLogger) Debug(args ...interface{}) { s.log(DebugLevel, "", args, nil) @@ -168,7 +198,8 @@ func (s *SugaredLogger) Fatalf(template string, args ...interface{}) { // pairs are treated as they are in With. // // When debug-level logging is disabled, this is much faster than -// s.With(keysAndValues).Debug(msg) +// +// s.With(keysAndValues).Debug(msg) func (s *SugaredLogger) Debugw(msg string, keysAndValues ...interface{}) { s.log(DebugLevel, msg, nil, keysAndValues) } @@ -210,11 +241,48 @@ func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } +// Debugln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Debugln(args ...interface{}) { + s.logln(DebugLevel, args, nil) +} + +// Infoln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Infoln(args ...interface{}) { + s.logln(InfoLevel, args, nil) +} + +// Warnln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Warnln(args ...interface{}) { + s.logln(WarnLevel, args, nil) +} + +// Errorln uses fmt.Sprintln to construct and log a message. +func (s *SugaredLogger) Errorln(args ...interface{}) { + s.logln(ErrorLevel, args, nil) +} + +// DPanicln uses fmt.Sprintln to construct and log a message. In development, the +// logger then panics. (See DPanicLevel for details.) +func (s *SugaredLogger) DPanicln(args ...interface{}) { + s.logln(DPanicLevel, args, nil) +} + +// Panicln uses fmt.Sprintln to construct and log a message, then panics. +func (s *SugaredLogger) Panicln(args ...interface{}) { + s.logln(PanicLevel, args, nil) +} + +// Fatalln uses fmt.Sprintln to construct and log a message, then calls os.Exit. +func (s *SugaredLogger) Fatalln(args ...interface{}) { + s.logln(FatalLevel, args, nil) +} + // Sync flushes any buffered log entries. func (s *SugaredLogger) Sync() error { return s.base.Sync() } +// log message with Sprint, Sprintf, or neither. func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) { // If logging at this level is completely disabled, skip the overhead of // string formatting. @@ -228,6 +296,18 @@ func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interf } } +// logln message with Sprintln +func (s *SugaredLogger) logln(lvl zapcore.Level, fmtArgs []interface{}, context []interface{}) { + if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) { + return + } + + msg := getMessageln(fmtArgs) + if ce := s.base.Check(lvl, msg); ce != nil { + ce.Write(s.sweetenFields(context)...) + } +} + // getMessage format with Sprint, Sprintf, or neither. func getMessage(template string, fmtArgs []interface{}) string { if len(fmtArgs) == 0 { @@ -246,15 +326,24 @@ func getMessage(template string, fmtArgs []interface{}) string { return fmt.Sprint(fmtArgs...) } +// getMessageln format with Sprintln. +func getMessageln(fmtArgs []interface{}) string { + msg := fmt.Sprintln(fmtArgs...) + return msg[:len(msg)-1] +} + func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { if len(args) == 0 { return nil } - // Allocate enough space for the worst case; if users pass only structured - // fields, we shouldn't penalize them with extra allocations. - fields := make([]Field, 0, len(args)) - var invalid invalidPairs + var ( + // Allocate enough space for the worst case; if users pass only structured + // fields, we shouldn't penalize them with extra allocations. + fields = make([]Field, 0, len(args)) + invalid invalidPairs + seenError bool + ) for i := 0; i < len(args); { // This is a strongly-typed field. Consume it and move on. @@ -264,6 +353,18 @@ func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { continue } + // If it is an error, consume it and move on. + if err, ok := args[i].(error); ok { + if !seenError { + seenError = true + fields = append(fields, Error(err)) + } else { + s.base.Error(_multipleErrMsg, Error(err)) + } + i++ + continue + } + // Make sure this element isn't a dangling key. if i == len(args)-1 { s.base.Error(_oddNumberErrMsg, Any("ignored", args[i])) diff --git a/vendor/go.uber.org/zap/writer.go b/vendor/go.uber.org/zap/writer.go index 86a709ab0be..f08728e1ec0 100644 --- a/vendor/go.uber.org/zap/writer.go +++ b/vendor/go.uber.org/zap/writer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,6 @@ package zap import ( "fmt" "io" - "io/ioutil" "go.uber.org/zap/zapcore" @@ -69,9 +68,9 @@ func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { var openErr error for _, path := range paths { - sink, err := newSink(path) + sink, err := _sinkRegistry.newSink(path) if err != nil { - openErr = multierr.Append(openErr, fmt.Errorf("couldn't open sink %q: %v", path, err)) + openErr = multierr.Append(openErr, fmt.Errorf("open sink %q: %w", path, err)) continue } writers = append(writers, sink) @@ -79,7 +78,7 @@ func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { } if openErr != nil { close() - return writers, nil, openErr + return nil, nil, openErr } return writers, close, nil @@ -93,7 +92,7 @@ func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { // using zapcore.NewMultiWriteSyncer and zapcore.Lock individually. func CombineWriteSyncers(writers ...zapcore.WriteSyncer) zapcore.WriteSyncer { if len(writers) == 0 { - return zapcore.AddSync(ioutil.Discard) + return zapcore.AddSync(io.Discard) } return zapcore.Lock(zapcore.NewMultiWriteSyncer(writers...)) } diff --git a/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go b/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go index ef2f7d9637b..a40e93b3ec8 100644 --- a/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go +++ b/vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go @@ -43,6 +43,37 @@ const ( // // BufferedWriteSyncer is safe for concurrent use. You don't need to use // zapcore.Lock for WriteSyncers with BufferedWriteSyncer. +// +// To set up a BufferedWriteSyncer, construct a WriteSyncer for your log +// destination (*os.File is a valid WriteSyncer), wrap it with +// BufferedWriteSyncer, and defer a Stop() call for when you no longer need the +// object. +// +// func main() { +// ws := ... // your log destination +// bws := &zapcore.BufferedWriteSyncer{WS: ws} +// defer bws.Stop() +// +// // ... +// core := zapcore.NewCore(enc, bws, lvl) +// logger := zap.New(core) +// +// // ... +// } +// +// By default, a BufferedWriteSyncer will buffer up to 256 kilobytes of logs, +// waiting at most 30 seconds between flushes. +// You can customize these parameters by setting the Size or FlushInterval +// fields. +// For example, the following buffers up to 512 kB of logs before flushing them +// to Stderr, with a maximum of one minute between each flush. +// +// ws := &BufferedWriteSyncer{ +// WS: os.Stderr, +// Size: 512 * 1024, // 512 kB +// FlushInterval: time.Minute, +// } +// defer ws.Stop() type BufferedWriteSyncer struct { // WS is the WriteSyncer around which BufferedWriteSyncer will buffer // writes. diff --git a/vendor/go.uber.org/zap/zapcore/core.go b/vendor/go.uber.org/zap/zapcore/core.go index a1ef8b034bb..9dfd64051f0 100644 --- a/vendor/go.uber.org/zap/zapcore/core.go +++ b/vendor/go.uber.org/zap/zapcore/core.go @@ -69,6 +69,15 @@ type ioCore struct { out WriteSyncer } +var ( + _ Core = (*ioCore)(nil) + _ leveledEnabler = (*ioCore)(nil) +) + +func (c *ioCore) Level() Level { + return LevelOf(c.LevelEnabler) +} + func (c *ioCore) With(fields []Field) Core { clone := c.clone() addFields(clone.enc, fields) diff --git a/vendor/go.uber.org/zap/zapcore/encoder.go b/vendor/go.uber.org/zap/zapcore/encoder.go index 6e5fd565113..5769ff3e4e5 100644 --- a/vendor/go.uber.org/zap/zapcore/encoder.go +++ b/vendor/go.uber.org/zap/zapcore/encoder.go @@ -188,10 +188,13 @@ func (e *TimeEncoder) UnmarshalText(text []byte) error { // UnmarshalYAML unmarshals YAML to a TimeEncoder. // If value is an object with a "layout" field, it will be unmarshaled to TimeEncoder with given layout. -// timeEncoder: -// layout: 06/01/02 03:04pm +// +// timeEncoder: +// layout: 06/01/02 03:04pm +// // If value is string, it uses UnmarshalText. -// timeEncoder: iso8601 +// +// timeEncoder: iso8601 func (e *TimeEncoder) UnmarshalYAML(unmarshal func(interface{}) error) error { var o struct { Layout string `json:"layout" yaml:"layout"` diff --git a/vendor/go.uber.org/zap/zapcore/entry.go b/vendor/go.uber.org/zap/zapcore/entry.go index 0885505b75b..9d326e95ea2 100644 --- a/vendor/go.uber.org/zap/zapcore/entry.go +++ b/vendor/go.uber.org/zap/zapcore/entry.go @@ -27,10 +27,9 @@ import ( "sync" "time" + "go.uber.org/multierr" "go.uber.org/zap/internal/bufferpool" "go.uber.org/zap/internal/exit" - - "go.uber.org/multierr" ) var ( @@ -152,6 +151,27 @@ type Entry struct { Stack string } +// CheckWriteHook is a custom action that may be executed after an entry is +// written. +// +// Register one on a CheckedEntry with the After method. +// +// if ce := logger.Check(...); ce != nil { +// ce = ce.After(hook) +// ce.Write(...) +// } +// +// You can configure the hook for Fatal log statements at the logger level with +// the zap.WithFatalHook option. +type CheckWriteHook interface { + // OnWrite is invoked with the CheckedEntry that was written and a list + // of fields added with that entry. + // + // The list of fields DOES NOT include fields that were already added + // to the logger with the With method. + OnWrite(*CheckedEntry, []Field) +} + // CheckWriteAction indicates what action to take after a log entry is // processed. Actions are ordered in increasing severity. type CheckWriteAction uint8 @@ -164,21 +184,36 @@ const ( WriteThenGoexit // WriteThenPanic causes a panic after Write. WriteThenPanic - // WriteThenFatal causes a fatal os.Exit after Write. + // WriteThenFatal causes an os.Exit(1) after Write. WriteThenFatal ) +// OnWrite implements the OnWrite method to keep CheckWriteAction compatible +// with the new CheckWriteHook interface which deprecates CheckWriteAction. +func (a CheckWriteAction) OnWrite(ce *CheckedEntry, _ []Field) { + switch a { + case WriteThenGoexit: + runtime.Goexit() + case WriteThenPanic: + panic(ce.Message) + case WriteThenFatal: + exit.With(1) + } +} + +var _ CheckWriteHook = CheckWriteAction(0) + // CheckedEntry is an Entry together with a collection of Cores that have // already agreed to log it. // -// CheckedEntry references should be created by calling AddCore or Should on a +// CheckedEntry references should be created by calling AddCore or After on a // nil *CheckedEntry. References are returned to a pool after Write, and MUST // NOT be retained after calling their Write method. type CheckedEntry struct { Entry ErrorOutput WriteSyncer dirty bool // best-effort detection of pool misuse - should CheckWriteAction + after CheckWriteHook cores []Core } @@ -186,7 +221,7 @@ func (ce *CheckedEntry) reset() { ce.Entry = Entry{} ce.ErrorOutput = nil ce.dirty = false - ce.should = WriteThenNoop + ce.after = nil for i := range ce.cores { // don't keep references to cores ce.cores[i] = nil @@ -224,17 +259,11 @@ func (ce *CheckedEntry) Write(fields ...Field) { ce.ErrorOutput.Sync() } - should, msg := ce.should, ce.Message - putCheckedEntry(ce) - - switch should { - case WriteThenPanic: - panic(msg) - case WriteThenFatal: - exit.Exit() - case WriteThenGoexit: - runtime.Goexit() + hook := ce.after + if hook != nil { + hook.OnWrite(ce, fields) } + putCheckedEntry(ce) } // AddCore adds a Core that has agreed to log this CheckedEntry. It's intended to be @@ -252,11 +281,20 @@ func (ce *CheckedEntry) AddCore(ent Entry, core Core) *CheckedEntry { // Should sets this CheckedEntry's CheckWriteAction, which controls whether a // Core will panic or fatal after writing this log entry. Like AddCore, it's // safe to call on nil CheckedEntry references. +// +// Deprecated: Use [CheckedEntry.After] instead. func (ce *CheckedEntry) Should(ent Entry, should CheckWriteAction) *CheckedEntry { + return ce.After(ent, should) +} + +// After sets this CheckEntry's CheckWriteHook, which will be called after this +// log entry has been written. It's safe to call this on nil CheckedEntry +// references. +func (ce *CheckedEntry) After(ent Entry, hook CheckWriteHook) *CheckedEntry { if ce == nil { ce = getCheckedEntry() ce.Entry = ent } - ce.should = should + ce.after = hook return ce } diff --git a/vendor/go.uber.org/zap/zapcore/error.go b/vendor/go.uber.org/zap/zapcore/error.go index 74919b0ccb1..06359907af4 100644 --- a/vendor/go.uber.org/zap/zapcore/error.go +++ b/vendor/go.uber.org/zap/zapcore/error.go @@ -36,13 +36,13 @@ import ( // causer (from github.com/pkg/errors), a ${key}Causes field is added with an // array of objects containing the errors this error was comprised of. // -// { -// "error": err.Error(), -// "errorVerbose": fmt.Sprintf("%+v", err), -// "errorCauses": [ -// ... -// ], -// } +// { +// "error": err.Error(), +// "errorVerbose": fmt.Sprintf("%+v", err), +// "errorCauses": [ +// ... +// ], +// } func encodeError(key string, err error, enc ObjectEncoder) (retErr error) { // Try to capture panics (from nil references or otherwise) when calling // the Error() method diff --git a/vendor/go.uber.org/zap/zapcore/hook.go b/vendor/go.uber.org/zap/zapcore/hook.go index 5db4afb302b..198def9917c 100644 --- a/vendor/go.uber.org/zap/zapcore/hook.go +++ b/vendor/go.uber.org/zap/zapcore/hook.go @@ -27,6 +27,11 @@ type hooked struct { funcs []func(Entry) error } +var ( + _ Core = (*hooked)(nil) + _ leveledEnabler = (*hooked)(nil) +) + // RegisterHooks wraps a Core and runs a collection of user-defined callback // hooks each time a message is logged. Execution of the callbacks is blocking. // @@ -40,6 +45,10 @@ func RegisterHooks(core Core, hooks ...func(Entry) error) Core { } } +func (h *hooked) Level() Level { + return LevelOf(h.Core) +} + func (h *hooked) Check(ent Entry, ce *CheckedEntry) *CheckedEntry { // Let the wrapped Core decide whether to log this message or not. This // also gives the downstream a chance to register itself directly with the diff --git a/vendor/go.uber.org/zap/zapcore/increase_level.go b/vendor/go.uber.org/zap/zapcore/increase_level.go index 5a1749261ab..7a11237ae97 100644 --- a/vendor/go.uber.org/zap/zapcore/increase_level.go +++ b/vendor/go.uber.org/zap/zapcore/increase_level.go @@ -27,6 +27,11 @@ type levelFilterCore struct { level LevelEnabler } +var ( + _ Core = (*levelFilterCore)(nil) + _ leveledEnabler = (*levelFilterCore)(nil) +) + // NewIncreaseLevelCore creates a core that can be used to increase the level of // an existing Core. It cannot be used to decrease the logging level, as it acts // as a filter before calling the underlying core. If level decreases the log level, @@ -45,6 +50,10 @@ func (c *levelFilterCore) Enabled(lvl Level) bool { return c.level.Enabled(lvl) } +func (c *levelFilterCore) Level() Level { + return LevelOf(c.level) +} + func (c *levelFilterCore) With(fields []Field) Core { return &levelFilterCore{c.core.With(fields), c.level} } diff --git a/vendor/go.uber.org/zap/zapcore/json_encoder.go b/vendor/go.uber.org/zap/zapcore/json_encoder.go index c5d751b8215..3921c5cd333 100644 --- a/vendor/go.uber.org/zap/zapcore/json_encoder.go +++ b/vendor/go.uber.org/zap/zapcore/json_encoder.go @@ -71,7 +71,9 @@ type jsonEncoder struct { // // Note that the encoder doesn't deduplicate keys, so it's possible to produce // a message like -// {"foo":"bar","foo":"baz"} +// +// {"foo":"bar","foo":"baz"} +// // This is permitted by the JSON specification, but not encouraged. Many // libraries will ignore duplicate key-value pairs (typically keeping the last // pair) when unmarshaling, but users should attempt to avoid adding duplicate diff --git a/vendor/go.uber.org/zap/zapcore/level.go b/vendor/go.uber.org/zap/zapcore/level.go index 56e88dc0c84..e01a2413166 100644 --- a/vendor/go.uber.org/zap/zapcore/level.go +++ b/vendor/go.uber.org/zap/zapcore/level.go @@ -53,6 +53,11 @@ const ( _minLevel = DebugLevel _maxLevel = FatalLevel + + // InvalidLevel is an invalid value for Level. + // + // Core implementations may panic if they see messages of this level. + InvalidLevel = _maxLevel + 1 ) // ParseLevel parses a level based on the lower-case or all-caps ASCII @@ -67,6 +72,43 @@ func ParseLevel(text string) (Level, error) { return level, err } +type leveledEnabler interface { + LevelEnabler + + Level() Level +} + +// LevelOf reports the minimum enabled log level for the given LevelEnabler +// from Zap's supported log levels, or [InvalidLevel] if none of them are +// enabled. +// +// A LevelEnabler may implement a 'Level() Level' method to override the +// behavior of this function. +// +// func (c *core) Level() Level { +// return c.currentLevel +// } +// +// It is recommended that [Core] implementations that wrap other cores use +// LevelOf to retrieve the level of the wrapped core. For example, +// +// func (c *coreWrapper) Level() Level { +// return zapcore.LevelOf(c.wrappedCore) +// } +func LevelOf(enab LevelEnabler) Level { + if lvler, ok := enab.(leveledEnabler); ok { + return lvler.Level() + } + + for lvl := _minLevel; lvl <= _maxLevel; lvl++ { + if enab.Enabled(lvl) { + return lvl + } + } + + return InvalidLevel +} + // String returns a lower-case ASCII representation of the log level. func (l Level) String() string { switch l { diff --git a/vendor/go.uber.org/zap/zapcore/sampler.go b/vendor/go.uber.org/zap/zapcore/sampler.go index 8c116049d35..dc518055a41 100644 --- a/vendor/go.uber.org/zap/zapcore/sampler.go +++ b/vendor/go.uber.org/zap/zapcore/sampler.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -113,12 +113,12 @@ func nopSamplingHook(Entry, SamplingDecision) {} // This hook may be used to get visibility into the performance of the sampler. // For example, use it to track metrics of dropped versus sampled logs. // -// var dropped atomic.Int64 -// zapcore.SamplerHook(func(ent zapcore.Entry, dec zapcore.SamplingDecision) { -// if dec&zapcore.LogDropped > 0 { -// dropped.Inc() -// } -// }) +// var dropped atomic.Int64 +// zapcore.SamplerHook(func(ent zapcore.Entry, dec zapcore.SamplingDecision) { +// if dec&zapcore.LogDropped > 0 { +// dropped.Inc() +// } +// }) func SamplerHook(hook func(entry Entry, dec SamplingDecision)) SamplerOption { return optionFunc(func(s *sampler) { s.hook = hook @@ -135,7 +135,7 @@ func SamplerHook(hook func(entry Entry, dec SamplingDecision)) SamplerOption { // // For example, // -// core = NewSamplerWithOptions(core, time.Second, 10, 5) +// core = NewSamplerWithOptions(core, time.Second, 10, 5) // // This will log the first 10 log entries with the same level and message // in a one second interval as-is. Following that, it will allow through @@ -175,6 +175,11 @@ type sampler struct { hook func(Entry, SamplingDecision) } +var ( + _ Core = (*sampler)(nil) + _ leveledEnabler = (*sampler)(nil) +) + // NewSampler creates a Core that samples incoming entries, which // caps the CPU and I/O load of logging while attempting to preserve a // representative subset of your logs. @@ -192,6 +197,10 @@ func NewSampler(core Core, tick time.Duration, first, thereafter int) Core { return NewSamplerWithOptions(core, tick, first, thereafter) } +func (s *sampler) Level() Level { + return LevelOf(s.Core) +} + func (s *sampler) With(fields []Field) Core { return &sampler{ Core: s.Core.With(fields), diff --git a/vendor/go.uber.org/zap/zapcore/tee.go b/vendor/go.uber.org/zap/zapcore/tee.go index 07a32eef9a4..9bb32f05576 100644 --- a/vendor/go.uber.org/zap/zapcore/tee.go +++ b/vendor/go.uber.org/zap/zapcore/tee.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,11 @@ import "go.uber.org/multierr" type multiCore []Core +var ( + _ leveledEnabler = multiCore(nil) + _ Core = multiCore(nil) +) + // NewTee creates a Core that duplicates log entries into two or more // underlying Cores. // @@ -48,6 +53,16 @@ func (mc multiCore) With(fields []Field) Core { return clone } +func (mc multiCore) Level() Level { + minLvl := _maxLevel // mc is never empty + for i := range mc { + if lvl := LevelOf(mc[i]); lvl < minLvl { + minLvl = lvl + } + } + return minLvl +} + func (mc multiCore) Enabled(lvl Level) bool { for i := range mc { if mc[i].Enabled(lvl) { diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/LICENSE b/vendor/golang.org/x/crypto/LICENSE similarity index 100% rename from vendor/k8s.io/client-go/third_party/forked/golang/LICENSE rename to vendor/golang.org/x/crypto/LICENSE diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/PATENTS b/vendor/golang.org/x/crypto/PATENTS similarity index 100% rename from vendor/k8s.io/client-go/third_party/forked/golang/PATENTS rename to vendor/golang.org/x/crypto/PATENTS diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go new file mode 100644 index 00000000000..5dfacbb9839 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package chacha20 + +const bufSize = 256 + +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s new file mode 100644 index 00000000000..f1f66230d1c --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s @@ -0,0 +1,308 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" + +#define NUM_ROUNDS 10 + +// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) +TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 + MOVD dst+0(FP), R1 + MOVD src+24(FP), R2 + MOVD src_len+32(FP), R3 + MOVD key+48(FP), R4 + MOVD nonce+56(FP), R6 + MOVD counter+64(FP), R7 + + MOVD $·constants(SB), R10 + MOVD $·incRotMatrix(SB), R11 + + MOVW (R7), R20 + + AND $~255, R3, R13 + ADD R2, R13, R12 // R12 for block end + AND $255, R3, R13 +loop: + MOVD $NUM_ROUNDS, R21 + VLD1 (R11), [V30.S4, V31.S4] + + // load contants + // VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4] + WORD $0x4D60E940 + + // load keys + // VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4] + WORD $0x4DFFE884 + // VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4] + WORD $0x4DFFE888 + SUB $32, R4 + + // load counter + nonce + // VLD1R (R7), [V12.S4] + WORD $0x4D40C8EC + + // VLD3R (R6), [V13.S4, V14.S4, V15.S4] + WORD $0x4D40E8CD + + // update counter + VADD V30.S4, V12.S4, V12.S4 + +chacha: + // V0..V3 += V4..V7 + // V12..V15 <<<= ((V12..V15 XOR V0..V3), 16) + VADD V0.S4, V4.S4, V0.S4 + VADD V1.S4, V5.S4, V1.S4 + VADD V2.S4, V6.S4, V2.S4 + VADD V3.S4, V7.S4, V3.S4 + VEOR V12.B16, V0.B16, V12.B16 + VEOR V13.B16, V1.B16, V13.B16 + VEOR V14.B16, V2.B16, V14.B16 + VEOR V15.B16, V3.B16, V15.B16 + VREV32 V12.H8, V12.H8 + VREV32 V13.H8, V13.H8 + VREV32 V14.H8, V14.H8 + VREV32 V15.H8, V15.H8 + // V8..V11 += V12..V15 + // V4..V7 <<<= ((V4..V7 XOR V8..V11), 12) + VADD V8.S4, V12.S4, V8.S4 + VADD V9.S4, V13.S4, V9.S4 + VADD V10.S4, V14.S4, V10.S4 + VADD V11.S4, V15.S4, V11.S4 + VEOR V8.B16, V4.B16, V16.B16 + VEOR V9.B16, V5.B16, V17.B16 + VEOR V10.B16, V6.B16, V18.B16 + VEOR V11.B16, V7.B16, V19.B16 + VSHL $12, V16.S4, V4.S4 + VSHL $12, V17.S4, V5.S4 + VSHL $12, V18.S4, V6.S4 + VSHL $12, V19.S4, V7.S4 + VSRI $20, V16.S4, V4.S4 + VSRI $20, V17.S4, V5.S4 + VSRI $20, V18.S4, V6.S4 + VSRI $20, V19.S4, V7.S4 + + // V0..V3 += V4..V7 + // V12..V15 <<<= ((V12..V15 XOR V0..V3), 8) + VADD V0.S4, V4.S4, V0.S4 + VADD V1.S4, V5.S4, V1.S4 + VADD V2.S4, V6.S4, V2.S4 + VADD V3.S4, V7.S4, V3.S4 + VEOR V12.B16, V0.B16, V12.B16 + VEOR V13.B16, V1.B16, V13.B16 + VEOR V14.B16, V2.B16, V14.B16 + VEOR V15.B16, V3.B16, V15.B16 + VTBL V31.B16, [V12.B16], V12.B16 + VTBL V31.B16, [V13.B16], V13.B16 + VTBL V31.B16, [V14.B16], V14.B16 + VTBL V31.B16, [V15.B16], V15.B16 + + // V8..V11 += V12..V15 + // V4..V7 <<<= ((V4..V7 XOR V8..V11), 7) + VADD V12.S4, V8.S4, V8.S4 + VADD V13.S4, V9.S4, V9.S4 + VADD V14.S4, V10.S4, V10.S4 + VADD V15.S4, V11.S4, V11.S4 + VEOR V8.B16, V4.B16, V16.B16 + VEOR V9.B16, V5.B16, V17.B16 + VEOR V10.B16, V6.B16, V18.B16 + VEOR V11.B16, V7.B16, V19.B16 + VSHL $7, V16.S4, V4.S4 + VSHL $7, V17.S4, V5.S4 + VSHL $7, V18.S4, V6.S4 + VSHL $7, V19.S4, V7.S4 + VSRI $25, V16.S4, V4.S4 + VSRI $25, V17.S4, V5.S4 + VSRI $25, V18.S4, V6.S4 + VSRI $25, V19.S4, V7.S4 + + // V0..V3 += V5..V7, V4 + // V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16) + VADD V0.S4, V5.S4, V0.S4 + VADD V1.S4, V6.S4, V1.S4 + VADD V2.S4, V7.S4, V2.S4 + VADD V3.S4, V4.S4, V3.S4 + VEOR V15.B16, V0.B16, V15.B16 + VEOR V12.B16, V1.B16, V12.B16 + VEOR V13.B16, V2.B16, V13.B16 + VEOR V14.B16, V3.B16, V14.B16 + VREV32 V12.H8, V12.H8 + VREV32 V13.H8, V13.H8 + VREV32 V14.H8, V14.H8 + VREV32 V15.H8, V15.H8 + + // V10 += V15; V5 <<<= ((V10 XOR V5), 12) + // ... + VADD V15.S4, V10.S4, V10.S4 + VADD V12.S4, V11.S4, V11.S4 + VADD V13.S4, V8.S4, V8.S4 + VADD V14.S4, V9.S4, V9.S4 + VEOR V10.B16, V5.B16, V16.B16 + VEOR V11.B16, V6.B16, V17.B16 + VEOR V8.B16, V7.B16, V18.B16 + VEOR V9.B16, V4.B16, V19.B16 + VSHL $12, V16.S4, V5.S4 + VSHL $12, V17.S4, V6.S4 + VSHL $12, V18.S4, V7.S4 + VSHL $12, V19.S4, V4.S4 + VSRI $20, V16.S4, V5.S4 + VSRI $20, V17.S4, V6.S4 + VSRI $20, V18.S4, V7.S4 + VSRI $20, V19.S4, V4.S4 + + // V0 += V5; V15 <<<= ((V0 XOR V15), 8) + // ... + VADD V5.S4, V0.S4, V0.S4 + VADD V6.S4, V1.S4, V1.S4 + VADD V7.S4, V2.S4, V2.S4 + VADD V4.S4, V3.S4, V3.S4 + VEOR V0.B16, V15.B16, V15.B16 + VEOR V1.B16, V12.B16, V12.B16 + VEOR V2.B16, V13.B16, V13.B16 + VEOR V3.B16, V14.B16, V14.B16 + VTBL V31.B16, [V12.B16], V12.B16 + VTBL V31.B16, [V13.B16], V13.B16 + VTBL V31.B16, [V14.B16], V14.B16 + VTBL V31.B16, [V15.B16], V15.B16 + + // V10 += V15; V5 <<<= ((V10 XOR V5), 7) + // ... + VADD V15.S4, V10.S4, V10.S4 + VADD V12.S4, V11.S4, V11.S4 + VADD V13.S4, V8.S4, V8.S4 + VADD V14.S4, V9.S4, V9.S4 + VEOR V10.B16, V5.B16, V16.B16 + VEOR V11.B16, V6.B16, V17.B16 + VEOR V8.B16, V7.B16, V18.B16 + VEOR V9.B16, V4.B16, V19.B16 + VSHL $7, V16.S4, V5.S4 + VSHL $7, V17.S4, V6.S4 + VSHL $7, V18.S4, V7.S4 + VSHL $7, V19.S4, V4.S4 + VSRI $25, V16.S4, V5.S4 + VSRI $25, V17.S4, V6.S4 + VSRI $25, V18.S4, V7.S4 + VSRI $25, V19.S4, V4.S4 + + SUB $1, R21 + CBNZ R21, chacha + + // VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4] + WORD $0x4D60E950 + + // VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4] + WORD $0x4DFFE894 + VADD V30.S4, V12.S4, V12.S4 + VADD V16.S4, V0.S4, V0.S4 + VADD V17.S4, V1.S4, V1.S4 + VADD V18.S4, V2.S4, V2.S4 + VADD V19.S4, V3.S4, V3.S4 + // VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4] + WORD $0x4DFFE898 + // restore R4 + SUB $32, R4 + + // load counter + nonce + // VLD1R (R7), [V28.S4] + WORD $0x4D40C8FC + // VLD3R (R6), [V29.S4, V30.S4, V31.S4] + WORD $0x4D40E8DD + + VADD V20.S4, V4.S4, V4.S4 + VADD V21.S4, V5.S4, V5.S4 + VADD V22.S4, V6.S4, V6.S4 + VADD V23.S4, V7.S4, V7.S4 + VADD V24.S4, V8.S4, V8.S4 + VADD V25.S4, V9.S4, V9.S4 + VADD V26.S4, V10.S4, V10.S4 + VADD V27.S4, V11.S4, V11.S4 + VADD V28.S4, V12.S4, V12.S4 + VADD V29.S4, V13.S4, V13.S4 + VADD V30.S4, V14.S4, V14.S4 + VADD V31.S4, V15.S4, V15.S4 + + VZIP1 V1.S4, V0.S4, V16.S4 + VZIP2 V1.S4, V0.S4, V17.S4 + VZIP1 V3.S4, V2.S4, V18.S4 + VZIP2 V3.S4, V2.S4, V19.S4 + VZIP1 V5.S4, V4.S4, V20.S4 + VZIP2 V5.S4, V4.S4, V21.S4 + VZIP1 V7.S4, V6.S4, V22.S4 + VZIP2 V7.S4, V6.S4, V23.S4 + VZIP1 V9.S4, V8.S4, V24.S4 + VZIP2 V9.S4, V8.S4, V25.S4 + VZIP1 V11.S4, V10.S4, V26.S4 + VZIP2 V11.S4, V10.S4, V27.S4 + VZIP1 V13.S4, V12.S4, V28.S4 + VZIP2 V13.S4, V12.S4, V29.S4 + VZIP1 V15.S4, V14.S4, V30.S4 + VZIP2 V15.S4, V14.S4, V31.S4 + VZIP1 V18.D2, V16.D2, V0.D2 + VZIP2 V18.D2, V16.D2, V4.D2 + VZIP1 V19.D2, V17.D2, V8.D2 + VZIP2 V19.D2, V17.D2, V12.D2 + VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16] + + VZIP1 V22.D2, V20.D2, V1.D2 + VZIP2 V22.D2, V20.D2, V5.D2 + VZIP1 V23.D2, V21.D2, V9.D2 + VZIP2 V23.D2, V21.D2, V13.D2 + VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16] + VZIP1 V26.D2, V24.D2, V2.D2 + VZIP2 V26.D2, V24.D2, V6.D2 + VZIP1 V27.D2, V25.D2, V10.D2 + VZIP2 V27.D2, V25.D2, V14.D2 + VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16] + VZIP1 V30.D2, V28.D2, V3.D2 + VZIP2 V30.D2, V28.D2, V7.D2 + VZIP1 V31.D2, V29.D2, V11.D2 + VZIP2 V31.D2, V29.D2, V15.D2 + VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16] + VEOR V0.B16, V16.B16, V16.B16 + VEOR V1.B16, V17.B16, V17.B16 + VEOR V2.B16, V18.B16, V18.B16 + VEOR V3.B16, V19.B16, V19.B16 + VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1) + VEOR V4.B16, V20.B16, V20.B16 + VEOR V5.B16, V21.B16, V21.B16 + VEOR V6.B16, V22.B16, V22.B16 + VEOR V7.B16, V23.B16, V23.B16 + VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1) + VEOR V8.B16, V24.B16, V24.B16 + VEOR V9.B16, V25.B16, V25.B16 + VEOR V10.B16, V26.B16, V26.B16 + VEOR V11.B16, V27.B16, V27.B16 + VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1) + VEOR V12.B16, V28.B16, V28.B16 + VEOR V13.B16, V29.B16, V29.B16 + VEOR V14.B16, V30.B16, V30.B16 + VEOR V15.B16, V31.B16, V31.B16 + VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1) + + ADD $4, R20 + MOVW R20, (R7) // update counter + + CMP R2, R12 + BGT loop + + RET + + +DATA ·constants+0x00(SB)/4, $0x61707865 +DATA ·constants+0x04(SB)/4, $0x3320646e +DATA ·constants+0x08(SB)/4, $0x79622d32 +DATA ·constants+0x0c(SB)/4, $0x6b206574 +GLOBL ·constants(SB), NOPTR|RODATA, $32 + +DATA ·incRotMatrix+0x00(SB)/4, $0x00000000 +DATA ·incRotMatrix+0x04(SB)/4, $0x00000001 +DATA ·incRotMatrix+0x08(SB)/4, $0x00000002 +DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003 +DATA ·incRotMatrix+0x10(SB)/4, $0x02010003 +DATA ·incRotMatrix+0x14(SB)/4, $0x06050407 +DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B +DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F +GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32 diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go new file mode 100644 index 00000000000..93eb5ae6de6 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_generic.go @@ -0,0 +1,398 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms +// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01. +package chacha20 + +import ( + "crypto/cipher" + "encoding/binary" + "errors" + "math/bits" + + "golang.org/x/crypto/internal/alias" +) + +const ( + // KeySize is the size of the key used by this cipher, in bytes. + KeySize = 32 + + // NonceSize is the size of the nonce used with the standard variant of this + // cipher, in bytes. + // + // Note that this is too short to be safely generated at random if the same + // key is reused more than 2³² times. + NonceSize = 12 + + // NonceSizeX is the size of the nonce used with the XChaCha20 variant of + // this cipher, in bytes. + NonceSizeX = 24 +) + +// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key +// and nonce. A *Cipher implements the cipher.Stream interface. +type Cipher struct { + // The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter + // (incremented after each block), and 3 of nonce. + key [8]uint32 + counter uint32 + nonce [3]uint32 + + // The last len bytes of buf are leftover key stream bytes from the previous + // XORKeyStream invocation. The size of buf depends on how many blocks are + // computed at a time by xorKeyStreamBlocks. + buf [bufSize]byte + len int + + // overflow is set when the counter overflowed, no more blocks can be + // generated, and the next XORKeyStream call should panic. + overflow bool + + // The counter-independent results of the first round are cached after they + // are computed the first time. + precompDone bool + p1, p5, p9, p13 uint32 + p2, p6, p10, p14 uint32 + p3, p7, p11, p15 uint32 +} + +var _ cipher.Stream = (*Cipher)(nil) + +// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given +// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided, +// the XChaCha20 construction will be used. It returns an error if key or nonce +// have any other length. +// +// Note that ChaCha20, like all stream ciphers, is not authenticated and allows +// attackers to silently tamper with the plaintext. For this reason, it is more +// appropriate as a building block than as a standalone encryption mechanism. +// Instead, consider using package golang.org/x/crypto/chacha20poly1305. +func NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) { + // This function is split into a wrapper so that the Cipher allocation will + // be inlined, and depending on how the caller uses the return value, won't + // escape to the heap. + c := &Cipher{} + return newUnauthenticatedCipher(c, key, nonce) +} + +func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20: wrong key size") + } + if len(nonce) == NonceSizeX { + // XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a + // derived key, allowing it to operate on a nonce of 24 bytes. See + // draft-irtf-cfrg-xchacha-01, Section 2.3. + key, _ = HChaCha20(key, nonce[0:16]) + cNonce := make([]byte, NonceSize) + copy(cNonce[4:12], nonce[16:24]) + nonce = cNonce + } else if len(nonce) != NonceSize { + return nil, errors.New("chacha20: wrong nonce size") + } + + key, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint + c.key = [8]uint32{ + binary.LittleEndian.Uint32(key[0:4]), + binary.LittleEndian.Uint32(key[4:8]), + binary.LittleEndian.Uint32(key[8:12]), + binary.LittleEndian.Uint32(key[12:16]), + binary.LittleEndian.Uint32(key[16:20]), + binary.LittleEndian.Uint32(key[20:24]), + binary.LittleEndian.Uint32(key[24:28]), + binary.LittleEndian.Uint32(key[28:32]), + } + c.nonce = [3]uint32{ + binary.LittleEndian.Uint32(nonce[0:4]), + binary.LittleEndian.Uint32(nonce[4:8]), + binary.LittleEndian.Uint32(nonce[8:12]), + } + return c, nil +} + +// The constant first 4 words of the ChaCha20 state. +const ( + j0 uint32 = 0x61707865 // expa + j1 uint32 = 0x3320646e // nd 3 + j2 uint32 = 0x79622d32 // 2-by + j3 uint32 = 0x6b206574 // te k +) + +const blockSize = 64 + +// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words. +// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16 +// words each round, in columnar or diagonal groups of 4 at a time. +func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) { + a += b + d ^= a + d = bits.RotateLeft32(d, 16) + c += d + b ^= c + b = bits.RotateLeft32(b, 12) + a += b + d ^= a + d = bits.RotateLeft32(d, 8) + c += d + b ^= c + b = bits.RotateLeft32(b, 7) + return a, b, c, d +} + +// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will +// behave as if (64 * counter) bytes had been encrypted so far. +// +// To prevent accidental counter reuse, SetCounter panics if counter is less +// than the current value. +// +// Note that the execution time of XORKeyStream is not independent of the +// counter value. +func (s *Cipher) SetCounter(counter uint32) { + // Internally, s may buffer multiple blocks, which complicates this + // implementation slightly. When checking whether the counter has rolled + // back, we must use both s.counter and s.len to determine how many blocks + // we have already output. + outputCounter := s.counter - uint32(s.len)/blockSize + if s.overflow || counter < outputCounter { + panic("chacha20: SetCounter attempted to rollback counter") + } + + // In the general case, we set the new counter value and reset s.len to 0, + // causing the next call to XORKeyStream to refill the buffer. However, if + // we're advancing within the existing buffer, we can save work by simply + // setting s.len. + if counter < s.counter { + s.len = int(s.counter-counter) * blockSize + } else { + s.counter = counter + s.len = 0 + } +} + +// XORKeyStream XORs each byte in the given slice with a byte from the +// cipher's key stream. Dst and src must overlap entirely or not at all. +// +// If len(dst) < len(src), XORKeyStream will panic. It is acceptable +// to pass a dst bigger than src, and in that case, XORKeyStream will +// only update dst[:len(src)] and will not touch the rest of dst. +// +// Multiple calls to XORKeyStream behave as if the concatenation of +// the src buffers was passed in a single run. That is, Cipher +// maintains state and does not reset at each XORKeyStream call. +func (s *Cipher) XORKeyStream(dst, src []byte) { + if len(src) == 0 { + return + } + if len(dst) < len(src) { + panic("chacha20: output smaller than input") + } + dst = dst[:len(src)] + if alias.InexactOverlap(dst, src) { + panic("chacha20: invalid buffer overlap") + } + + // First, drain any remaining key stream from a previous XORKeyStream. + if s.len != 0 { + keyStream := s.buf[bufSize-s.len:] + if len(src) < len(keyStream) { + keyStream = keyStream[:len(src)] + } + _ = src[len(keyStream)-1] // bounds check elimination hint + for i, b := range keyStream { + dst[i] = src[i] ^ b + } + s.len -= len(keyStream) + dst, src = dst[len(keyStream):], src[len(keyStream):] + } + if len(src) == 0 { + return + } + + // If we'd need to let the counter overflow and keep generating output, + // panic immediately. If instead we'd only reach the last block, remember + // not to generate any more output after the buffer is drained. + numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize + if s.overflow || uint64(s.counter)+numBlocks > 1<<32 { + panic("chacha20: counter overflow") + } else if uint64(s.counter)+numBlocks == 1<<32 { + s.overflow = true + } + + // xorKeyStreamBlocks implementations expect input lengths that are a + // multiple of bufSize. Platform-specific ones process multiple blocks at a + // time, so have bufSizes that are a multiple of blockSize. + + full := len(src) - len(src)%bufSize + if full > 0 { + s.xorKeyStreamBlocks(dst[:full], src[:full]) + } + dst, src = dst[full:], src[full:] + + // If using a multi-block xorKeyStreamBlocks would overflow, use the generic + // one that does one block at a time. + const blocksPerBuf = bufSize / blockSize + if uint64(s.counter)+blocksPerBuf > 1<<32 { + s.buf = [bufSize]byte{} + numBlocks := (len(src) + blockSize - 1) / blockSize + buf := s.buf[bufSize-numBlocks*blockSize:] + copy(buf, src) + s.xorKeyStreamBlocksGeneric(buf, buf) + s.len = len(buf) - copy(dst, buf) + return + } + + // If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and + // keep the leftover keystream for the next XORKeyStream invocation. + if len(src) > 0 { + s.buf = [bufSize]byte{} + copy(s.buf[:], src) + s.xorKeyStreamBlocks(s.buf[:], s.buf[:]) + s.len = bufSize - copy(dst, s.buf[:]) + } +} + +func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) { + if len(dst) != len(src) || len(dst)%blockSize != 0 { + panic("chacha20: internal error: wrong dst and/or src length") + } + + // To generate each block of key stream, the initial cipher state + // (represented below) is passed through 20 rounds of shuffling, + // alternatively applying quarterRounds by columns (like 1, 5, 9, 13) + // or by diagonals (like 1, 6, 11, 12). + // + // 0:cccccccc 1:cccccccc 2:cccccccc 3:cccccccc + // 4:kkkkkkkk 5:kkkkkkkk 6:kkkkkkkk 7:kkkkkkkk + // 8:kkkkkkkk 9:kkkkkkkk 10:kkkkkkkk 11:kkkkkkkk + // 12:bbbbbbbb 13:nnnnnnnn 14:nnnnnnnn 15:nnnnnnnn + // + // c=constant k=key b=blockcount n=nonce + var ( + c0, c1, c2, c3 = j0, j1, j2, j3 + c4, c5, c6, c7 = s.key[0], s.key[1], s.key[2], s.key[3] + c8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7] + _, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2] + ) + + // Three quarters of the first round don't depend on the counter, so we can + // calculate them here, and reuse them for multiple blocks in the loop, and + // for future XORKeyStream invocations. + if !s.precompDone { + s.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13) + s.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14) + s.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15) + s.precompDone = true + } + + // A condition of len(src) > 0 would be sufficient, but this also + // acts as a bounds check elimination hint. + for len(src) >= 64 && len(dst) >= 64 { + // The remainder of the first column round. + fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter) + + // The second diagonal round. + x0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15) + x1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12) + x2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13) + x3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14) + + // The remaining 18 rounds. + for i := 0; i < 9; i++ { + // Column round. + x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) + x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) + x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) + x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) + + // Diagonal round. + x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) + x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) + x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) + x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) + } + + // Add back the initial state to generate the key stream, then + // XOR the key stream with the source and write out the result. + addXor(dst[0:4], src[0:4], x0, c0) + addXor(dst[4:8], src[4:8], x1, c1) + addXor(dst[8:12], src[8:12], x2, c2) + addXor(dst[12:16], src[12:16], x3, c3) + addXor(dst[16:20], src[16:20], x4, c4) + addXor(dst[20:24], src[20:24], x5, c5) + addXor(dst[24:28], src[24:28], x6, c6) + addXor(dst[28:32], src[28:32], x7, c7) + addXor(dst[32:36], src[32:36], x8, c8) + addXor(dst[36:40], src[36:40], x9, c9) + addXor(dst[40:44], src[40:44], x10, c10) + addXor(dst[44:48], src[44:48], x11, c11) + addXor(dst[48:52], src[48:52], x12, s.counter) + addXor(dst[52:56], src[52:56], x13, c13) + addXor(dst[56:60], src[56:60], x14, c14) + addXor(dst[60:64], src[60:64], x15, c15) + + s.counter += 1 + + src, dst = src[blockSize:], dst[blockSize:] + } +} + +// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes +// key and a 16 bytes nonce. It returns an error if key or nonce have any other +// length. It is used as part of the XChaCha20 construction. +func HChaCha20(key, nonce []byte) ([]byte, error) { + // This function is split into a wrapper so that the slice allocation will + // be inlined, and depending on how the caller uses the return value, won't + // escape to the heap. + out := make([]byte, 32) + return hChaCha20(out, key, nonce) +} + +func hChaCha20(out, key, nonce []byte) ([]byte, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20: wrong HChaCha20 key size") + } + if len(nonce) != 16 { + return nil, errors.New("chacha20: wrong HChaCha20 nonce size") + } + + x0, x1, x2, x3 := j0, j1, j2, j3 + x4 := binary.LittleEndian.Uint32(key[0:4]) + x5 := binary.LittleEndian.Uint32(key[4:8]) + x6 := binary.LittleEndian.Uint32(key[8:12]) + x7 := binary.LittleEndian.Uint32(key[12:16]) + x8 := binary.LittleEndian.Uint32(key[16:20]) + x9 := binary.LittleEndian.Uint32(key[20:24]) + x10 := binary.LittleEndian.Uint32(key[24:28]) + x11 := binary.LittleEndian.Uint32(key[28:32]) + x12 := binary.LittleEndian.Uint32(nonce[0:4]) + x13 := binary.LittleEndian.Uint32(nonce[4:8]) + x14 := binary.LittleEndian.Uint32(nonce[8:12]) + x15 := binary.LittleEndian.Uint32(nonce[12:16]) + + for i := 0; i < 10; i++ { + // Diagonal round. + x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) + x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) + x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) + x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) + + // Column round. + x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) + x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) + x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) + x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) + } + + _ = out[31] // bounds check elimination hint + binary.LittleEndian.PutUint32(out[0:4], x0) + binary.LittleEndian.PutUint32(out[4:8], x1) + binary.LittleEndian.PutUint32(out[8:12], x2) + binary.LittleEndian.PutUint32(out[12:16], x3) + binary.LittleEndian.PutUint32(out[16:20], x12) + binary.LittleEndian.PutUint32(out[20:24], x13) + binary.LittleEndian.PutUint32(out[24:28], x14) + binary.LittleEndian.PutUint32(out[28:32], x15) + return out, nil +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go new file mode 100644 index 00000000000..02ff3d05e9a --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego +// +build !arm64,!s390x,!ppc64le !gc purego + +package chacha20 + +const bufSize = blockSize + +func (s *Cipher) xorKeyStreamBlocks(dst, src []byte) { + s.xorKeyStreamBlocksGeneric(dst, src) +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go new file mode 100644 index 00000000000..da420b2e97b --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go @@ -0,0 +1,17 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package chacha20 + +const bufSize = 256 + +//go:noescape +func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter) +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s new file mode 100644 index 00000000000..5c0fed26f85 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s @@ -0,0 +1,450 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Based on CRYPTOGAMS code with the following comment: +// # ==================================================================== +// # Written by Andy Polyakov for the OpenSSL +// # project. The module is, however, dual licensed under OpenSSL and +// # CRYPTOGAMS licenses depending on where you obtain it. For further +// # details see http://www.openssl.org/~appro/cryptogams/. +// # ==================================================================== + +// Code for the perl script that generates the ppc64 assembler +// can be found in the cryptogams repository at the link below. It is based on +// the original from openssl. + +// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91 + +// The differences in this and the original implementation are +// due to the calling conventions and initialization of constants. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" + +#define OUT R3 +#define INP R4 +#define LEN R5 +#define KEY R6 +#define CNT R7 +#define TMP R15 + +#define CONSTBASE R16 +#define BLOCKS R17 + +DATA consts<>+0x00(SB)/8, $0x3320646e61707865 +DATA consts<>+0x08(SB)/8, $0x6b20657479622d32 +DATA consts<>+0x10(SB)/8, $0x0000000000000001 +DATA consts<>+0x18(SB)/8, $0x0000000000000000 +DATA consts<>+0x20(SB)/8, $0x0000000000000004 +DATA consts<>+0x28(SB)/8, $0x0000000000000000 +DATA consts<>+0x30(SB)/8, $0x0a0b08090e0f0c0d +DATA consts<>+0x38(SB)/8, $0x0203000106070405 +DATA consts<>+0x40(SB)/8, $0x090a0b080d0e0f0c +DATA consts<>+0x48(SB)/8, $0x0102030005060704 +DATA consts<>+0x50(SB)/8, $0x6170786561707865 +DATA consts<>+0x58(SB)/8, $0x6170786561707865 +DATA consts<>+0x60(SB)/8, $0x3320646e3320646e +DATA consts<>+0x68(SB)/8, $0x3320646e3320646e +DATA consts<>+0x70(SB)/8, $0x79622d3279622d32 +DATA consts<>+0x78(SB)/8, $0x79622d3279622d32 +DATA consts<>+0x80(SB)/8, $0x6b2065746b206574 +DATA consts<>+0x88(SB)/8, $0x6b2065746b206574 +DATA consts<>+0x90(SB)/8, $0x0000000100000000 +DATA consts<>+0x98(SB)/8, $0x0000000300000002 +GLOBL consts<>(SB), RODATA, $0xa0 + +//func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32) +TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40 + MOVD out+0(FP), OUT + MOVD inp+8(FP), INP + MOVD len+16(FP), LEN + MOVD key+24(FP), KEY + MOVD counter+32(FP), CNT + + // Addressing for constants + MOVD $consts<>+0x00(SB), CONSTBASE + MOVD $16, R8 + MOVD $32, R9 + MOVD $48, R10 + MOVD $64, R11 + SRD $6, LEN, BLOCKS + // V16 + LXVW4X (CONSTBASE)(R0), VS48 + ADD $80,CONSTBASE + + // Load key into V17,V18 + LXVW4X (KEY)(R0), VS49 + LXVW4X (KEY)(R8), VS50 + + // Load CNT, NONCE into V19 + LXVW4X (CNT)(R0), VS51 + + // Clear V27 + VXOR V27, V27, V27 + + // V28 + LXVW4X (CONSTBASE)(R11), VS60 + + // splat slot from V19 -> V26 + VSPLTW $0, V19, V26 + + VSLDOI $4, V19, V27, V19 + VSLDOI $12, V27, V19, V19 + + VADDUWM V26, V28, V26 + + MOVD $10, R14 + MOVD R14, CTR + +loop_outer_vsx: + // V0, V1, V2, V3 + LXVW4X (R0)(CONSTBASE), VS32 + LXVW4X (R8)(CONSTBASE), VS33 + LXVW4X (R9)(CONSTBASE), VS34 + LXVW4X (R10)(CONSTBASE), VS35 + + // splat values from V17, V18 into V4-V11 + VSPLTW $0, V17, V4 + VSPLTW $1, V17, V5 + VSPLTW $2, V17, V6 + VSPLTW $3, V17, V7 + VSPLTW $0, V18, V8 + VSPLTW $1, V18, V9 + VSPLTW $2, V18, V10 + VSPLTW $3, V18, V11 + + // VOR + VOR V26, V26, V12 + + // splat values from V19 -> V13, V14, V15 + VSPLTW $1, V19, V13 + VSPLTW $2, V19, V14 + VSPLTW $3, V19, V15 + + // splat const values + VSPLTISW $-16, V27 + VSPLTISW $12, V28 + VSPLTISW $8, V29 + VSPLTISW $7, V30 + +loop_vsx: + VADDUWM V0, V4, V0 + VADDUWM V1, V5, V1 + VADDUWM V2, V6, V2 + VADDUWM V3, V7, V3 + + VXOR V12, V0, V12 + VXOR V13, V1, V13 + VXOR V14, V2, V14 + VXOR V15, V3, V15 + + VRLW V12, V27, V12 + VRLW V13, V27, V13 + VRLW V14, V27, V14 + VRLW V15, V27, V15 + + VADDUWM V8, V12, V8 + VADDUWM V9, V13, V9 + VADDUWM V10, V14, V10 + VADDUWM V11, V15, V11 + + VXOR V4, V8, V4 + VXOR V5, V9, V5 + VXOR V6, V10, V6 + VXOR V7, V11, V7 + + VRLW V4, V28, V4 + VRLW V5, V28, V5 + VRLW V6, V28, V6 + VRLW V7, V28, V7 + + VADDUWM V0, V4, V0 + VADDUWM V1, V5, V1 + VADDUWM V2, V6, V2 + VADDUWM V3, V7, V3 + + VXOR V12, V0, V12 + VXOR V13, V1, V13 + VXOR V14, V2, V14 + VXOR V15, V3, V15 + + VRLW V12, V29, V12 + VRLW V13, V29, V13 + VRLW V14, V29, V14 + VRLW V15, V29, V15 + + VADDUWM V8, V12, V8 + VADDUWM V9, V13, V9 + VADDUWM V10, V14, V10 + VADDUWM V11, V15, V11 + + VXOR V4, V8, V4 + VXOR V5, V9, V5 + VXOR V6, V10, V6 + VXOR V7, V11, V7 + + VRLW V4, V30, V4 + VRLW V5, V30, V5 + VRLW V6, V30, V6 + VRLW V7, V30, V7 + + VADDUWM V0, V5, V0 + VADDUWM V1, V6, V1 + VADDUWM V2, V7, V2 + VADDUWM V3, V4, V3 + + VXOR V15, V0, V15 + VXOR V12, V1, V12 + VXOR V13, V2, V13 + VXOR V14, V3, V14 + + VRLW V15, V27, V15 + VRLW V12, V27, V12 + VRLW V13, V27, V13 + VRLW V14, V27, V14 + + VADDUWM V10, V15, V10 + VADDUWM V11, V12, V11 + VADDUWM V8, V13, V8 + VADDUWM V9, V14, V9 + + VXOR V5, V10, V5 + VXOR V6, V11, V6 + VXOR V7, V8, V7 + VXOR V4, V9, V4 + + VRLW V5, V28, V5 + VRLW V6, V28, V6 + VRLW V7, V28, V7 + VRLW V4, V28, V4 + + VADDUWM V0, V5, V0 + VADDUWM V1, V6, V1 + VADDUWM V2, V7, V2 + VADDUWM V3, V4, V3 + + VXOR V15, V0, V15 + VXOR V12, V1, V12 + VXOR V13, V2, V13 + VXOR V14, V3, V14 + + VRLW V15, V29, V15 + VRLW V12, V29, V12 + VRLW V13, V29, V13 + VRLW V14, V29, V14 + + VADDUWM V10, V15, V10 + VADDUWM V11, V12, V11 + VADDUWM V8, V13, V8 + VADDUWM V9, V14, V9 + + VXOR V5, V10, V5 + VXOR V6, V11, V6 + VXOR V7, V8, V7 + VXOR V4, V9, V4 + + VRLW V5, V30, V5 + VRLW V6, V30, V6 + VRLW V7, V30, V7 + VRLW V4, V30, V4 + BC 16, LT, loop_vsx + + VADDUWM V12, V26, V12 + + WORD $0x13600F8C // VMRGEW V0, V1, V27 + WORD $0x13821F8C // VMRGEW V2, V3, V28 + + WORD $0x10000E8C // VMRGOW V0, V1, V0 + WORD $0x10421E8C // VMRGOW V2, V3, V2 + + WORD $0x13A42F8C // VMRGEW V4, V5, V29 + WORD $0x13C63F8C // VMRGEW V6, V7, V30 + + XXPERMDI VS32, VS34, $0, VS33 + XXPERMDI VS32, VS34, $3, VS35 + XXPERMDI VS59, VS60, $0, VS32 + XXPERMDI VS59, VS60, $3, VS34 + + WORD $0x10842E8C // VMRGOW V4, V5, V4 + WORD $0x10C63E8C // VMRGOW V6, V7, V6 + + WORD $0x13684F8C // VMRGEW V8, V9, V27 + WORD $0x138A5F8C // VMRGEW V10, V11, V28 + + XXPERMDI VS36, VS38, $0, VS37 + XXPERMDI VS36, VS38, $3, VS39 + XXPERMDI VS61, VS62, $0, VS36 + XXPERMDI VS61, VS62, $3, VS38 + + WORD $0x11084E8C // VMRGOW V8, V9, V8 + WORD $0x114A5E8C // VMRGOW V10, V11, V10 + + WORD $0x13AC6F8C // VMRGEW V12, V13, V29 + WORD $0x13CE7F8C // VMRGEW V14, V15, V30 + + XXPERMDI VS40, VS42, $0, VS41 + XXPERMDI VS40, VS42, $3, VS43 + XXPERMDI VS59, VS60, $0, VS40 + XXPERMDI VS59, VS60, $3, VS42 + + WORD $0x118C6E8C // VMRGOW V12, V13, V12 + WORD $0x11CE7E8C // VMRGOW V14, V15, V14 + + VSPLTISW $4, V27 + VADDUWM V26, V27, V26 + + XXPERMDI VS44, VS46, $0, VS45 + XXPERMDI VS44, VS46, $3, VS47 + XXPERMDI VS61, VS62, $0, VS44 + XXPERMDI VS61, VS62, $3, VS46 + + VADDUWM V0, V16, V0 + VADDUWM V4, V17, V4 + VADDUWM V8, V18, V8 + VADDUWM V12, V19, V12 + + CMPU LEN, $64 + BLT tail_vsx + + // Bottom of loop + LXVW4X (INP)(R0), VS59 + LXVW4X (INP)(R8), VS60 + LXVW4X (INP)(R9), VS61 + LXVW4X (INP)(R10), VS62 + + VXOR V27, V0, V27 + VXOR V28, V4, V28 + VXOR V29, V8, V29 + VXOR V30, V12, V30 + + STXVW4X VS59, (OUT)(R0) + STXVW4X VS60, (OUT)(R8) + ADD $64, INP + STXVW4X VS61, (OUT)(R9) + ADD $-64, LEN + STXVW4X VS62, (OUT)(R10) + ADD $64, OUT + BEQ done_vsx + + VADDUWM V1, V16, V0 + VADDUWM V5, V17, V4 + VADDUWM V9, V18, V8 + VADDUWM V13, V19, V12 + + CMPU LEN, $64 + BLT tail_vsx + + LXVW4X (INP)(R0), VS59 + LXVW4X (INP)(R8), VS60 + LXVW4X (INP)(R9), VS61 + LXVW4X (INP)(R10), VS62 + VXOR V27, V0, V27 + + VXOR V28, V4, V28 + VXOR V29, V8, V29 + VXOR V30, V12, V30 + + STXVW4X VS59, (OUT)(R0) + STXVW4X VS60, (OUT)(R8) + ADD $64, INP + STXVW4X VS61, (OUT)(R9) + ADD $-64, LEN + STXVW4X VS62, (OUT)(V10) + ADD $64, OUT + BEQ done_vsx + + VADDUWM V2, V16, V0 + VADDUWM V6, V17, V4 + VADDUWM V10, V18, V8 + VADDUWM V14, V19, V12 + + CMPU LEN, $64 + BLT tail_vsx + + LXVW4X (INP)(R0), VS59 + LXVW4X (INP)(R8), VS60 + LXVW4X (INP)(R9), VS61 + LXVW4X (INP)(R10), VS62 + + VXOR V27, V0, V27 + VXOR V28, V4, V28 + VXOR V29, V8, V29 + VXOR V30, V12, V30 + + STXVW4X VS59, (OUT)(R0) + STXVW4X VS60, (OUT)(R8) + ADD $64, INP + STXVW4X VS61, (OUT)(R9) + ADD $-64, LEN + STXVW4X VS62, (OUT)(R10) + ADD $64, OUT + BEQ done_vsx + + VADDUWM V3, V16, V0 + VADDUWM V7, V17, V4 + VADDUWM V11, V18, V8 + VADDUWM V15, V19, V12 + + CMPU LEN, $64 + BLT tail_vsx + + LXVW4X (INP)(R0), VS59 + LXVW4X (INP)(R8), VS60 + LXVW4X (INP)(R9), VS61 + LXVW4X (INP)(R10), VS62 + + VXOR V27, V0, V27 + VXOR V28, V4, V28 + VXOR V29, V8, V29 + VXOR V30, V12, V30 + + STXVW4X VS59, (OUT)(R0) + STXVW4X VS60, (OUT)(R8) + ADD $64, INP + STXVW4X VS61, (OUT)(R9) + ADD $-64, LEN + STXVW4X VS62, (OUT)(R10) + ADD $64, OUT + + MOVD $10, R14 + MOVD R14, CTR + BNE loop_outer_vsx + +done_vsx: + // Increment counter by number of 64 byte blocks + MOVD (CNT), R14 + ADD BLOCKS, R14 + MOVD R14, (CNT) + RET + +tail_vsx: + ADD $32, R1, R11 + MOVD LEN, CTR + + // Save values on stack to copy from + STXVW4X VS32, (R11)(R0) + STXVW4X VS36, (R11)(R8) + STXVW4X VS40, (R11)(R9) + STXVW4X VS44, (R11)(R10) + ADD $-1, R11, R12 + ADD $-1, INP + ADD $-1, OUT + +looptail_vsx: + // Copying the result to OUT + // in bytes. + MOVBZU 1(R12), KEY + MOVBZU 1(INP), TMP + XOR KEY, TMP, KEY + MOVBU KEY, 1(OUT) + BC 16, LT, looptail_vsx + + // Clear the stack values + STXVW4X VS48, (R11)(R0) + STXVW4X VS48, (R11)(R8) + STXVW4X VS48, (R11)(R9) + STXVW4X VS48, (R11)(R10) + BR done_vsx diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go new file mode 100644 index 00000000000..4652247b8a6 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go @@ -0,0 +1,28 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package chacha20 + +import "golang.org/x/sys/cpu" + +var haveAsm = cpu.S390X.HasVX + +const bufSize = 256 + +// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only +// be called when the vector facility is available. Implementation in asm_s390x.s. +// +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + if cpu.S390X.HasVX { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) + } else { + c.xorKeyStreamBlocksGeneric(dst, src) + } +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s new file mode 100644 index 00000000000..f3ef5a019d9 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s @@ -0,0 +1,225 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +#include "go_asm.h" +#include "textflag.h" + +// This is an implementation of the ChaCha20 encryption algorithm as +// specified in RFC 7539. It uses vector instructions to compute +// 4 keystream blocks in parallel (256 bytes) which are then XORed +// with the bytes in the input slice. + +GLOBL ·constants<>(SB), RODATA|NOPTR, $32 +// BSWAP: swap bytes in each 4-byte element +DATA ·constants<>+0x00(SB)/4, $0x03020100 +DATA ·constants<>+0x04(SB)/4, $0x07060504 +DATA ·constants<>+0x08(SB)/4, $0x0b0a0908 +DATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c +// J0: [j0, j1, j2, j3] +DATA ·constants<>+0x10(SB)/4, $0x61707865 +DATA ·constants<>+0x14(SB)/4, $0x3320646e +DATA ·constants<>+0x18(SB)/4, $0x79622d32 +DATA ·constants<>+0x1c(SB)/4, $0x6b206574 + +#define BSWAP V5 +#define J0 V6 +#define KEY0 V7 +#define KEY1 V8 +#define NONCE V9 +#define CTR V10 +#define M0 V11 +#define M1 V12 +#define M2 V13 +#define M3 V14 +#define INC V15 +#define X0 V16 +#define X1 V17 +#define X2 V18 +#define X3 V19 +#define X4 V20 +#define X5 V21 +#define X6 V22 +#define X7 V23 +#define X8 V24 +#define X9 V25 +#define X10 V26 +#define X11 V27 +#define X12 V28 +#define X13 V29 +#define X14 V30 +#define X15 V31 + +#define NUM_ROUNDS 20 + +#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \ + VAF a1, a0, a0 \ + VAF b1, b0, b0 \ + VAF c1, c0, c0 \ + VAF d1, d0, d0 \ + VX a0, a2, a2 \ + VX b0, b2, b2 \ + VX c0, c2, c2 \ + VX d0, d2, d2 \ + VERLLF $16, a2, a2 \ + VERLLF $16, b2, b2 \ + VERLLF $16, c2, c2 \ + VERLLF $16, d2, d2 \ + VAF a2, a3, a3 \ + VAF b2, b3, b3 \ + VAF c2, c3, c3 \ + VAF d2, d3, d3 \ + VX a3, a1, a1 \ + VX b3, b1, b1 \ + VX c3, c1, c1 \ + VX d3, d1, d1 \ + VERLLF $12, a1, a1 \ + VERLLF $12, b1, b1 \ + VERLLF $12, c1, c1 \ + VERLLF $12, d1, d1 \ + VAF a1, a0, a0 \ + VAF b1, b0, b0 \ + VAF c1, c0, c0 \ + VAF d1, d0, d0 \ + VX a0, a2, a2 \ + VX b0, b2, b2 \ + VX c0, c2, c2 \ + VX d0, d2, d2 \ + VERLLF $8, a2, a2 \ + VERLLF $8, b2, b2 \ + VERLLF $8, c2, c2 \ + VERLLF $8, d2, d2 \ + VAF a2, a3, a3 \ + VAF b2, b3, b3 \ + VAF c2, c3, c3 \ + VAF d2, d3, d3 \ + VX a3, a1, a1 \ + VX b3, b1, b1 \ + VX c3, c1, c1 \ + VX d3, d1, d1 \ + VERLLF $7, a1, a1 \ + VERLLF $7, b1, b1 \ + VERLLF $7, c1, c1 \ + VERLLF $7, d1, d1 + +#define PERMUTE(mask, v0, v1, v2, v3) \ + VPERM v0, v0, mask, v0 \ + VPERM v1, v1, mask, v1 \ + VPERM v2, v2, mask, v2 \ + VPERM v3, v3, mask, v3 + +#define ADDV(x, v0, v1, v2, v3) \ + VAF x, v0, v0 \ + VAF x, v1, v1 \ + VAF x, v2, v2 \ + VAF x, v3, v3 + +#define XORV(off, dst, src, v0, v1, v2, v3) \ + VLM off(src), M0, M3 \ + PERMUTE(BSWAP, v0, v1, v2, v3) \ + VX v0, M0, M0 \ + VX v1, M1, M1 \ + VX v2, M2, M2 \ + VX v3, M3, M3 \ + VSTM M0, M3, off(dst) + +#define SHUFFLE(a, b, c, d, t, u, v, w) \ + VMRHF a, c, t \ // t = {a[0], c[0], a[1], c[1]} + VMRHF b, d, u \ // u = {b[0], d[0], b[1], d[1]} + VMRLF a, c, v \ // v = {a[2], c[2], a[3], c[3]} + VMRLF b, d, w \ // w = {b[2], d[2], b[3], d[3]} + VMRHF t, u, a \ // a = {a[0], b[0], c[0], d[0]} + VMRLF t, u, b \ // b = {a[1], b[1], c[1], d[1]} + VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]} + VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]} + +// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) +TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 + MOVD $·constants<>(SB), R1 + MOVD dst+0(FP), R2 // R2=&dst[0] + LMG src+24(FP), R3, R4 // R3=&src[0] R4=len(src) + MOVD key+48(FP), R5 // R5=key + MOVD nonce+56(FP), R6 // R6=nonce + MOVD counter+64(FP), R7 // R7=counter + + // load BSWAP and J0 + VLM (R1), BSWAP, J0 + + // setup + MOVD $95, R0 + VLM (R5), KEY0, KEY1 + VLL R0, (R6), NONCE + VZERO M0 + VLEIB $7, $32, M0 + VSRLB M0, NONCE, NONCE + + // initialize counter values + VLREPF (R7), CTR + VZERO INC + VLEIF $1, $1, INC + VLEIF $2, $2, INC + VLEIF $3, $3, INC + VAF INC, CTR, CTR + VREPIF $4, INC + +chacha: + VREPF $0, J0, X0 + VREPF $1, J0, X1 + VREPF $2, J0, X2 + VREPF $3, J0, X3 + VREPF $0, KEY0, X4 + VREPF $1, KEY0, X5 + VREPF $2, KEY0, X6 + VREPF $3, KEY0, X7 + VREPF $0, KEY1, X8 + VREPF $1, KEY1, X9 + VREPF $2, KEY1, X10 + VREPF $3, KEY1, X11 + VLR CTR, X12 + VREPF $1, NONCE, X13 + VREPF $2, NONCE, X14 + VREPF $3, NONCE, X15 + + MOVD $(NUM_ROUNDS/2), R1 + +loop: + ROUND4(X0, X4, X12, X8, X1, X5, X13, X9, X2, X6, X14, X10, X3, X7, X15, X11) + ROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8, X3, X4, X14, X9) + + ADD $-1, R1 + BNE loop + + // decrement length + ADD $-256, R4 + + // rearrange vectors + SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3) + ADDV(J0, X0, X1, X2, X3) + SHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3) + ADDV(KEY0, X4, X5, X6, X7) + SHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3) + ADDV(KEY1, X8, X9, X10, X11) + VAF CTR, X12, X12 + SHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3) + ADDV(NONCE, X12, X13, X14, X15) + + // increment counters + VAF INC, CTR, CTR + + // xor keystream with plaintext + XORV(0*64, R2, R3, X0, X4, X8, X12) + XORV(1*64, R2, R3, X1, X5, X9, X13) + XORV(2*64, R2, R3, X2, X6, X10, X14) + XORV(3*64, R2, R3, X3, X7, X11, X15) + + // increment pointers + MOVD $256(R2), R2 + MOVD $256(R3), R3 + + CMPBNE R4, $0, chacha + + VSTEF $0, CTR, (R7) + RET diff --git a/vendor/golang.org/x/crypto/chacha20/xor.go b/vendor/golang.org/x/crypto/chacha20/xor.go new file mode 100644 index 00000000000..c2d04851e0d --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20/xor.go @@ -0,0 +1,42 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found src the LICENSE file. + +package chacha20 + +import "runtime" + +// Platforms that have fast unaligned 32-bit little endian accesses. +const unaligned = runtime.GOARCH == "386" || + runtime.GOARCH == "amd64" || + runtime.GOARCH == "arm64" || + runtime.GOARCH == "ppc64le" || + runtime.GOARCH == "s390x" + +// addXor reads a little endian uint32 from src, XORs it with (a + b) and +// places the result in little endian byte order in dst. +func addXor(dst, src []byte, a, b uint32) { + _, _ = src[3], dst[3] // bounds check elimination hint + if unaligned { + // The compiler should optimize this code into + // 32-bit unaligned little endian loads and stores. + // TODO: delete once the compiler does a reliably + // good job with the generic code below. + // See issue #25111 for more details. + v := uint32(src[0]) + v |= uint32(src[1]) << 8 + v |= uint32(src[2]) << 16 + v |= uint32(src[3]) << 24 + v ^= a + b + dst[0] = byte(v) + dst[1] = byte(v >> 8) + dst[2] = byte(v >> 16) + dst[3] = byte(v >> 24) + } else { + a += b + dst[0] = src[0] ^ byte(a) + dst[1] = src[1] ^ byte(a>>8) + dst[2] = src[2] ^ byte(a>>16) + dst[3] = src[3] ^ byte(a>>24) + } +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go new file mode 100644 index 00000000000..93da7322bc4 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go @@ -0,0 +1,98 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its +// extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and +// draft-irtf-cfrg-xchacha-01. +package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305" + +import ( + "crypto/cipher" + "errors" +) + +const ( + // KeySize is the size of the key used by this AEAD, in bytes. + KeySize = 32 + + // NonceSize is the size of the nonce used with the standard variant of this + // AEAD, in bytes. + // + // Note that this is too short to be safely generated at random if the same + // key is reused more than 2³² times. + NonceSize = 12 + + // NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305 + // variant of this AEAD, in bytes. + NonceSizeX = 24 + + // Overhead is the size of the Poly1305 authentication tag, and the + // difference between a ciphertext length and its plaintext. + Overhead = 16 +) + +type chacha20poly1305 struct { + key [KeySize]byte +} + +// New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key. +func New(key []byte) (cipher.AEAD, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20poly1305: bad key length") + } + ret := new(chacha20poly1305) + copy(ret.key[:], key) + return ret, nil +} + +func (c *chacha20poly1305) NonceSize() int { + return NonceSize +} + +func (c *chacha20poly1305) Overhead() int { + return Overhead +} + +func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + if len(nonce) != NonceSize { + panic("chacha20poly1305: bad nonce length passed to Seal") + } + + if uint64(len(plaintext)) > (1<<38)-64 { + panic("chacha20poly1305: plaintext too large") + } + + return c.seal(dst, nonce, plaintext, additionalData) +} + +var errOpen = errors.New("chacha20poly1305: message authentication failed") + +func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if len(nonce) != NonceSize { + panic("chacha20poly1305: bad nonce length passed to Open") + } + if len(ciphertext) < 16 { + return nil, errOpen + } + if uint64(len(ciphertext)) > (1<<38)-48 { + panic("chacha20poly1305: ciphertext too large") + } + + return c.open(dst, nonce, ciphertext, additionalData) +} + +// sliceForAppend takes a slice and a requested number of bytes. It returns a +// slice with the contents of the given slice followed by that many bytes and a +// second slice that aliases into it and contains only the extra bytes. If the +// original slice has sufficient capacity then no allocation is performed. +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go new file mode 100644 index 00000000000..0c408c57094 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go @@ -0,0 +1,87 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package chacha20poly1305 + +import ( + "encoding/binary" + + "golang.org/x/crypto/internal/alias" + "golang.org/x/sys/cpu" +) + +//go:noescape +func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool + +//go:noescape +func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte) + +var ( + useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2 +) + +// setupState writes a ChaCha20 input matrix to state. See +// https://tools.ietf.org/html/rfc7539#section-2.3. +func setupState(state *[16]uint32, key *[32]byte, nonce []byte) { + state[0] = 0x61707865 + state[1] = 0x3320646e + state[2] = 0x79622d32 + state[3] = 0x6b206574 + + state[4] = binary.LittleEndian.Uint32(key[0:4]) + state[5] = binary.LittleEndian.Uint32(key[4:8]) + state[6] = binary.LittleEndian.Uint32(key[8:12]) + state[7] = binary.LittleEndian.Uint32(key[12:16]) + state[8] = binary.LittleEndian.Uint32(key[16:20]) + state[9] = binary.LittleEndian.Uint32(key[20:24]) + state[10] = binary.LittleEndian.Uint32(key[24:28]) + state[11] = binary.LittleEndian.Uint32(key[28:32]) + + state[12] = 0 + state[13] = binary.LittleEndian.Uint32(nonce[0:4]) + state[14] = binary.LittleEndian.Uint32(nonce[4:8]) + state[15] = binary.LittleEndian.Uint32(nonce[8:12]) +} + +func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte { + if !cpu.X86.HasSSSE3 { + return c.sealGeneric(dst, nonce, plaintext, additionalData) + } + + var state [16]uint32 + setupState(&state, &c.key, nonce) + + ret, out := sliceForAppend(dst, len(plaintext)+16) + if alias.InexactOverlap(out, plaintext) { + panic("chacha20poly1305: invalid buffer overlap") + } + chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData) + return ret +} + +func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if !cpu.X86.HasSSSE3 { + return c.openGeneric(dst, nonce, ciphertext, additionalData) + } + + var state [16]uint32 + setupState(&state, &c.key, nonce) + + ciphertext = ciphertext[:len(ciphertext)-16] + ret, out := sliceForAppend(dst, len(ciphertext)) + if alias.InexactOverlap(out, ciphertext) { + panic("chacha20poly1305: invalid buffer overlap") + } + if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) { + for i := range out { + out[i] = 0 + } + return nil, errOpen + } + + return ret, nil +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s new file mode 100644 index 00000000000..867c181a14c --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s @@ -0,0 +1,2696 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" +// General register allocation +#define oup DI +#define inp SI +#define inl BX +#define adp CX // free to reuse, after we hash the additional data +#define keyp R8 // free to reuse, when we copy the key to stack +#define itr2 R9 // general iterator +#define itr1 CX // general iterator +#define acc0 R10 +#define acc1 R11 +#define acc2 R12 +#define t0 R13 +#define t1 R14 +#define t2 R15 +#define t3 R8 +// Register and stack allocation for the SSE code +#define rStore (0*16)(BP) +#define sStore (1*16)(BP) +#define state1Store (2*16)(BP) +#define state2Store (3*16)(BP) +#define tmpStore (4*16)(BP) +#define ctr0Store (5*16)(BP) +#define ctr1Store (6*16)(BP) +#define ctr2Store (7*16)(BP) +#define ctr3Store (8*16)(BP) +#define A0 X0 +#define A1 X1 +#define A2 X2 +#define B0 X3 +#define B1 X4 +#define B2 X5 +#define C0 X6 +#define C1 X7 +#define C2 X8 +#define D0 X9 +#define D1 X10 +#define D2 X11 +#define T0 X12 +#define T1 X13 +#define T2 X14 +#define T3 X15 +#define A3 T0 +#define B3 T1 +#define C3 T2 +#define D3 T3 +// Register and stack allocation for the AVX2 code +#define rsStoreAVX2 (0*32)(BP) +#define state1StoreAVX2 (1*32)(BP) +#define state2StoreAVX2 (2*32)(BP) +#define ctr0StoreAVX2 (3*32)(BP) +#define ctr1StoreAVX2 (4*32)(BP) +#define ctr2StoreAVX2 (5*32)(BP) +#define ctr3StoreAVX2 (6*32)(BP) +#define tmpStoreAVX2 (7*32)(BP) // 256 bytes on stack +#define AA0 Y0 +#define AA1 Y5 +#define AA2 Y6 +#define AA3 Y7 +#define BB0 Y14 +#define BB1 Y9 +#define BB2 Y10 +#define BB3 Y11 +#define CC0 Y12 +#define CC1 Y13 +#define CC2 Y8 +#define CC3 Y15 +#define DD0 Y4 +#define DD1 Y1 +#define DD2 Y2 +#define DD3 Y3 +#define TT0 DD3 +#define TT1 AA3 +#define TT2 BB3 +#define TT3 CC3 +// ChaCha20 constants +DATA ·chacha20Constants<>+0x00(SB)/4, $0x61707865 +DATA ·chacha20Constants<>+0x04(SB)/4, $0x3320646e +DATA ·chacha20Constants<>+0x08(SB)/4, $0x79622d32 +DATA ·chacha20Constants<>+0x0c(SB)/4, $0x6b206574 +DATA ·chacha20Constants<>+0x10(SB)/4, $0x61707865 +DATA ·chacha20Constants<>+0x14(SB)/4, $0x3320646e +DATA ·chacha20Constants<>+0x18(SB)/4, $0x79622d32 +DATA ·chacha20Constants<>+0x1c(SB)/4, $0x6b206574 +// <<< 16 with PSHUFB +DATA ·rol16<>+0x00(SB)/8, $0x0504070601000302 +DATA ·rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A +DATA ·rol16<>+0x10(SB)/8, $0x0504070601000302 +DATA ·rol16<>+0x18(SB)/8, $0x0D0C0F0E09080B0A +// <<< 8 with PSHUFB +DATA ·rol8<>+0x00(SB)/8, $0x0605040702010003 +DATA ·rol8<>+0x08(SB)/8, $0x0E0D0C0F0A09080B +DATA ·rol8<>+0x10(SB)/8, $0x0605040702010003 +DATA ·rol8<>+0x18(SB)/8, $0x0E0D0C0F0A09080B + +DATA ·avx2InitMask<>+0x00(SB)/8, $0x0 +DATA ·avx2InitMask<>+0x08(SB)/8, $0x0 +DATA ·avx2InitMask<>+0x10(SB)/8, $0x1 +DATA ·avx2InitMask<>+0x18(SB)/8, $0x0 + +DATA ·avx2IncMask<>+0x00(SB)/8, $0x2 +DATA ·avx2IncMask<>+0x08(SB)/8, $0x0 +DATA ·avx2IncMask<>+0x10(SB)/8, $0x2 +DATA ·avx2IncMask<>+0x18(SB)/8, $0x0 +// Poly1305 key clamp +DATA ·polyClampMask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF +DATA ·polyClampMask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC +DATA ·polyClampMask<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF +DATA ·polyClampMask<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF + +DATA ·sseIncMask<>+0x00(SB)/8, $0x1 +DATA ·sseIncMask<>+0x08(SB)/8, $0x0 +// To load/store the last < 16 bytes in a buffer +DATA ·andMask<>+0x00(SB)/8, $0x00000000000000ff +DATA ·andMask<>+0x08(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x10(SB)/8, $0x000000000000ffff +DATA ·andMask<>+0x18(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x20(SB)/8, $0x0000000000ffffff +DATA ·andMask<>+0x28(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x30(SB)/8, $0x00000000ffffffff +DATA ·andMask<>+0x38(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x40(SB)/8, $0x000000ffffffffff +DATA ·andMask<>+0x48(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x50(SB)/8, $0x0000ffffffffffff +DATA ·andMask<>+0x58(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x60(SB)/8, $0x00ffffffffffffff +DATA ·andMask<>+0x68(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x70(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x78(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x80(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x88(SB)/8, $0x00000000000000ff +DATA ·andMask<>+0x90(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x98(SB)/8, $0x000000000000ffff +DATA ·andMask<>+0xa0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xa8(SB)/8, $0x0000000000ffffff +DATA ·andMask<>+0xb0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xb8(SB)/8, $0x00000000ffffffff +DATA ·andMask<>+0xc0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xc8(SB)/8, $0x000000ffffffffff +DATA ·andMask<>+0xd0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xd8(SB)/8, $0x0000ffffffffffff +DATA ·andMask<>+0xe0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xe8(SB)/8, $0x00ffffffffffffff + +GLOBL ·chacha20Constants<>(SB), (NOPTR+RODATA), $32 +GLOBL ·rol16<>(SB), (NOPTR+RODATA), $32 +GLOBL ·rol8<>(SB), (NOPTR+RODATA), $32 +GLOBL ·sseIncMask<>(SB), (NOPTR+RODATA), $16 +GLOBL ·avx2IncMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·avx2InitMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·polyClampMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240 +// No PALIGNR in Go ASM yet (but VPALIGNR is present). +#define shiftB0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X3, X3 +#define shiftB1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x04 // PALIGNR $4, X4, X4 +#define shiftB2Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X5, X5 +#define shiftB3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X13, X13 +#define shiftC0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X6, X6 +#define shiftC1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x08 // PALIGNR $8, X7, X7 +#define shiftC2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc0; BYTE $0x08 // PALIGNR $8, X8, X8 +#define shiftC3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X14, X14 +#define shiftD0Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x0c // PALIGNR $12, X9, X9 +#define shiftD1Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x0c // PALIGNR $12, X10, X10 +#define shiftD2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X11, X11 +#define shiftD3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x0c // PALIGNR $12, X15, X15 +#define shiftB0Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X3, X3 +#define shiftB1Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x0c // PALIGNR $12, X4, X4 +#define shiftB2Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X5, X5 +#define shiftB3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X13, X13 +#define shiftC0Right shiftC0Left +#define shiftC1Right shiftC1Left +#define shiftC2Right shiftC2Left +#define shiftC3Right shiftC3Left +#define shiftD0Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x04 // PALIGNR $4, X9, X9 +#define shiftD1Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x04 // PALIGNR $4, X10, X10 +#define shiftD2Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X11, X11 +#define shiftD3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x04 // PALIGNR $4, X15, X15 +// Some macros +#define chachaQR(A, B, C, D, T) \ + PADDD B, A; PXOR A, D; PSHUFB ·rol16<>(SB), D \ + PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $12, T; PSRLL $20, B; PXOR T, B \ + PADDD B, A; PXOR A, D; PSHUFB ·rol8<>(SB), D \ + PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $7, T; PSRLL $25, B; PXOR T, B + +#define chachaQR_AVX2(A, B, C, D, T) \ + VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol16<>(SB), D, D \ + VPADDD D, C, C; VPXOR C, B, B; VPSLLD $12, B, T; VPSRLD $20, B, B; VPXOR T, B, B \ + VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol8<>(SB), D, D \ + VPADDD D, C, C; VPXOR C, B, B; VPSLLD $7, B, T; VPSRLD $25, B, B; VPXOR T, B, B + +#define polyAdd(S) ADDQ S, acc0; ADCQ 8+S, acc1; ADCQ $1, acc2 +#define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2 +#define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX +#define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3 +#define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t3, t2; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2 + +#define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2 +#define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3 +#define polyMulStage3_AVX2 IMULQ acc2, DX; ADDQ AX, t2; ADCQ DX, t3 + +#define polyMul polyMulStage1; polyMulStage2; polyMulStage3; polyMulReduceStage +#define polyMulAVX2 polyMulStage1_AVX2; polyMulStage2_AVX2; polyMulStage3_AVX2; polyMulReduceStage +// ---------------------------------------------------------------------------- +TEXT polyHashADInternal<>(SB), NOSPLIT, $0 + // adp points to beginning of additional data + // itr2 holds ad length + XORQ acc0, acc0 + XORQ acc1, acc1 + XORQ acc2, acc2 + CMPQ itr2, $13 + JNE hashADLoop + +openFastTLSAD: + // Special treatment for the TLS case of 13 bytes + MOVQ (adp), acc0 + MOVQ 5(adp), acc1 + SHRQ $24, acc1 + MOVQ $1, acc2 + polyMul + RET + +hashADLoop: + // Hash in 16 byte chunks + CMPQ itr2, $16 + JB hashADTail + polyAdd(0(adp)) + LEAQ (1*16)(adp), adp + SUBQ $16, itr2 + polyMul + JMP hashADLoop + +hashADTail: + CMPQ itr2, $0 + JE hashADDone + + // Hash last < 16 byte tail + XORQ t0, t0 + XORQ t1, t1 + XORQ t2, t2 + ADDQ itr2, adp + +hashADTailLoop: + SHLQ $8, t0, t1 + SHLQ $8, t0 + MOVB -1(adp), t2 + XORQ t2, t0 + DECQ adp + DECQ itr2 + JNE hashADTailLoop + +hashADTailFinish: + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + // Finished AD +hashADDone: + RET + +// ---------------------------------------------------------------------------- +// func chacha20Poly1305Open(dst, key, src, ad []byte) bool +TEXT ·chacha20Poly1305Open(SB), 0, $288-97 + // For aligned stack access + MOVQ SP, BP + ADDQ $32, BP + ANDQ $-32, BP + MOVQ dst+0(FP), oup + MOVQ key+24(FP), keyp + MOVQ src+48(FP), inp + MOVQ src_len+56(FP), inl + MOVQ ad+72(FP), adp + + // Check for AVX2 support + CMPB ·useAVX2(SB), $1 + JE chacha20Poly1305Open_AVX2 + + // Special optimization, for very short buffers + CMPQ inl, $128 + JBE openSSE128 // About 16% faster + + // For long buffers, prepare the poly key first + MOVOU ·chacha20Constants<>(SB), A0 + MOVOU (1*16)(keyp), B0 + MOVOU (2*16)(keyp), C0 + MOVOU (3*16)(keyp), D0 + MOVO D0, T1 + + // Store state on stack for future use + MOVO B0, state1Store + MOVO C0, state2Store + MOVO D0, ctr3Store + MOVQ $10, itr2 + +openSSEPreparePolyKey: + chachaQR(A0, B0, C0, D0, T0) + shiftB0Left; shiftC0Left; shiftD0Left + chachaQR(A0, B0, C0, D0, T0) + shiftB0Right; shiftC0Right; shiftD0Right + DECQ itr2 + JNE openSSEPreparePolyKey + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVO A0, rStore; MOVO B0, sStore + + // Hash AAD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openSSEMainLoop: + CMPQ inl, $256 + JB openSSEMainLoopDone + + // Load state, increment counter blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + + // There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we hash 2 blocks, and for the remaining 4 only 1 block - for a total of 16 + MOVQ $4, itr1 + MOVQ inp, itr2 + +openSSEInternalLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyAdd(0(itr2)) + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + LEAQ (2*8)(itr2), itr2 + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + polyMulStage3 + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr1 + JGE openSSEInternalLoop + + polyAdd(0(itr2)) + polyMul + LEAQ (2*8)(itr2), itr2 + + CMPQ itr1, $-6 + JG openSSEInternalLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + + // Load - xor - store + MOVO D3, tmpStore + MOVOU (0*16)(inp), D3; PXOR D3, A0; MOVOU A0, (0*16)(oup) + MOVOU (1*16)(inp), D3; PXOR D3, B0; MOVOU B0, (1*16)(oup) + MOVOU (2*16)(inp), D3; PXOR D3, C0; MOVOU C0, (2*16)(oup) + MOVOU (3*16)(inp), D3; PXOR D3, D0; MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), D0; PXOR D0, A1; MOVOU A1, (4*16)(oup) + MOVOU (5*16)(inp), D0; PXOR D0, B1; MOVOU B1, (5*16)(oup) + MOVOU (6*16)(inp), D0; PXOR D0, C1; MOVOU C1, (6*16)(oup) + MOVOU (7*16)(inp), D0; PXOR D0, D1; MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), D0; PXOR D0, A2; MOVOU A2, (8*16)(oup) + MOVOU (9*16)(inp), D0; PXOR D0, B2; MOVOU B2, (9*16)(oup) + MOVOU (10*16)(inp), D0; PXOR D0, C2; MOVOU C2, (10*16)(oup) + MOVOU (11*16)(inp), D0; PXOR D0, D2; MOVOU D2, (11*16)(oup) + MOVOU (12*16)(inp), D0; PXOR D0, A3; MOVOU A3, (12*16)(oup) + MOVOU (13*16)(inp), D0; PXOR D0, B3; MOVOU B3, (13*16)(oup) + MOVOU (14*16)(inp), D0; PXOR D0, C3; MOVOU C3, (14*16)(oup) + MOVOU (15*16)(inp), D0; PXOR tmpStore, D0; MOVOU D0, (15*16)(oup) + LEAQ 256(inp), inp + LEAQ 256(oup), oup + SUBQ $256, inl + JMP openSSEMainLoop + +openSSEMainLoopDone: + // Handle the various tail sizes efficiently + TESTQ inl, inl + JE openSSEFinalize + CMPQ inl, $64 + JBE openSSETail64 + CMPQ inl, $128 + JBE openSSETail128 + CMPQ inl, $192 + JBE openSSETail192 + JMP openSSETail256 + +openSSEFinalize: + // Hash in the PT, AAD lengths + ADDQ ad_len+80(FP), acc0; ADCQ src_len+56(FP), acc1; ADCQ $1, acc2 + polyMul + + // Final reduce + MOVQ acc0, t0 + MOVQ acc1, t1 + MOVQ acc2, t2 + SUBQ $-5, acc0 + SBBQ $-1, acc1 + SBBQ $3, acc2 + CMOVQCS t0, acc0 + CMOVQCS t1, acc1 + CMOVQCS t2, acc2 + + // Add in the "s" part of the key + ADDQ 0+sStore, acc0 + ADCQ 8+sStore, acc1 + + // Finally, constant time compare to the tag at the end of the message + XORQ AX, AX + MOVQ $1, DX + XORQ (0*8)(inp), acc0 + XORQ (1*8)(inp), acc1 + ORQ acc1, acc0 + CMOVQEQ DX, AX + + // Return true iff tags are equal + MOVB AX, ret+96(FP) + RET + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 129 bytes +openSSE128: + // For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks + MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO B0, T1; MOVO C0, T2; MOVO D1, T3 + MOVQ $10, itr2 + +openSSE128InnerCipherLoop: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftB1Left; shiftB2Left + shiftC0Left; shiftC1Left; shiftC2Left + shiftD0Left; shiftD1Left; shiftD2Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftB1Right; shiftB2Right + shiftC0Right; shiftC1Right; shiftC2Right + shiftD0Right; shiftD1Right; shiftD2Right + DECQ itr2 + JNE openSSE128InnerCipherLoop + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL T1, B0; PADDL T1, B1; PADDL T1, B2 + PADDL T2, C1; PADDL T2, C2 + PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVOU A0, rStore; MOVOU B0, sStore + + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openSSE128Open: + CMPQ inl, $16 + JB openSSETail16 + SUBQ $16, inl + + // Load for hashing + polyAdd(0(inp)) + + // Load for decryption + MOVOU (inp), T0; PXOR T0, A1; MOVOU A1, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + polyMul + + // Shift the stream "left" + MOVO B1, A1 + MOVO C1, B1 + MOVO D1, C1 + MOVO A2, D1 + MOVO B2, A2 + MOVO C2, B2 + MOVO D2, C2 + JMP openSSE128Open + +openSSETail16: + TESTQ inl, inl + JE openSSEFinalize + + // We can safely load the CT from the end, because it is padded with the MAC + MOVQ inl, itr2 + SHLQ $4, itr2 + LEAQ ·andMask<>(SB), t0 + MOVOU (inp), T0 + ADDQ inl, inp + PAND -16(t0)(itr2*1), T0 + MOVO T0, 0+tmpStore + MOVQ T0, t0 + MOVQ 8+tmpStore, t1 + PXOR A1, T0 + + // We can only store one byte at a time, since plaintext can be shorter than 16 bytes +openSSETail16Store: + MOVQ T0, t3 + MOVB t3, (oup) + PSRLDQ $1, T0 + INCQ oup + DECQ inl + JNE openSSETail16Store + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + JMP openSSEFinalize + +// ---------------------------------------------------------------------------- +// Special optimization for the last 64 bytes of ciphertext +openSSETail64: + // Need to decrypt up to 64 bytes - prepare single block + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + XORQ itr2, itr2 + MOVQ inl, itr1 + CMPQ itr1, $16 + JB openSSETail64LoopB + +openSSETail64LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + SUBQ $16, itr1 + +openSSETail64LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0) + shiftB0Left; shiftC0Left; shiftD0Left + chachaQR(A0, B0, C0, D0, T0) + shiftB0Right; shiftC0Right; shiftD0Right + + CMPQ itr1, $16 + JAE openSSETail64LoopA + + CMPQ itr2, $160 + JNE openSSETail64LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0; PADDL state2Store, C0; PADDL ctr0Store, D0 + +openSSETail64DecLoop: + CMPQ inl, $16 + JB openSSETail64DecLoopDone + SUBQ $16, inl + MOVOU (inp), T0 + PXOR T0, A0 + MOVOU A0, (oup) + LEAQ 16(inp), inp + LEAQ 16(oup), oup + MOVO B0, A0 + MOVO C0, B0 + MOVO D0, C0 + JMP openSSETail64DecLoop + +openSSETail64DecLoopDone: + MOVO A0, A1 + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +openSSETail128: + // Need to decrypt up to 128 bytes - prepare two blocks + MOVO ·chacha20Constants<>(SB), A1; MOVO state1Store, B1; MOVO state2Store, C1; MOVO ctr3Store, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr0Store + MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr1Store + XORQ itr2, itr2 + MOVQ inl, itr1 + ANDQ $-16, itr1 + +openSSETail128LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + +openSSETail128LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + + CMPQ itr2, itr1 + JB openSSETail128LoopA + + CMPQ itr2, $160 + JNE openSSETail128LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B0; PADDL state1Store, B1 + PADDL state2Store, C0; PADDL state2Store, C1 + PADDL ctr1Store, D0; PADDL ctr0Store, D1 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup) + + SUBQ $64, inl + LEAQ 64(inp), inp + LEAQ 64(oup), oup + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 192 bytes of ciphertext +openSSETail192: + // Need to decrypt up to 192 bytes - prepare three blocks + MOVO ·chacha20Constants<>(SB), A2; MOVO state1Store, B2; MOVO state2Store, C2; MOVO ctr3Store, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr0Store + MOVO A2, A1; MOVO B2, B1; MOVO C2, C1; MOVO D2, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr2Store + + MOVQ inl, itr1 + MOVQ $160, itr2 + CMPQ itr1, $160 + CMOVQGT itr2, itr1 + ANDQ $-16, itr1 + XORQ itr2, itr2 + +openSSLTail192LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + +openSSLTail192LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + shiftB2Left; shiftC2Left; shiftD2Left + + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + shiftB2Right; shiftC2Right; shiftD2Right + + CMPQ itr2, itr1 + JB openSSLTail192LoopA + + CMPQ itr2, $160 + JNE openSSLTail192LoopB + + CMPQ inl, $176 + JB openSSLTail192Store + + polyAdd(160(inp)) + polyMul + + CMPQ inl, $192 + JB openSSLTail192Store + + polyAdd(176(inp)) + polyMul + +openSSLTail192Store: + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2 + PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2 + PADDL ctr2Store, D0; PADDL ctr1Store, D1; PADDL ctr0Store, D2 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A2; PXOR T1, B2; PXOR T2, C2; PXOR T3, D2 + MOVOU A2, (0*16)(oup); MOVOU B2, (1*16)(oup); MOVOU C2, (2*16)(oup); MOVOU D2, (3*16)(oup) + + MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + + SUBQ $128, inl + LEAQ 128(inp), inp + LEAQ 128(oup), oup + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +openSSETail256: + // Need to decrypt up to 256 bytes - prepare four blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + XORQ itr2, itr2 + +openSSETail256Loop: + // This loop inteleaves 8 ChaCha quarter rounds with 1 poly multiplication + polyAdd(0(inp)(itr2*1)) + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulStage3 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + ADDQ $2*8, itr2 + CMPQ itr2, $160 + JB openSSETail256Loop + MOVQ inl, itr1 + ANDQ $-16, itr1 + +openSSETail256HashLoop: + polyAdd(0(inp)(itr2*1)) + polyMul + ADDQ $2*8, itr2 + CMPQ itr2, itr1 + JB openSSETail256HashLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + MOVO D3, tmpStore + + // Load - xor - store + MOVOU (0*16)(inp), D3; PXOR D3, A0 + MOVOU (1*16)(inp), D3; PXOR D3, B0 + MOVOU (2*16)(inp), D3; PXOR D3, C0 + MOVOU (3*16)(inp), D3; PXOR D3, D0 + MOVOU A0, (0*16)(oup) + MOVOU B0, (1*16)(oup) + MOVOU C0, (2*16)(oup) + MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup) + LEAQ 192(inp), inp + LEAQ 192(oup), oup + SUBQ $192, inl + MOVO A3, A0 + MOVO B3, B0 + MOVO C3, C0 + MOVO tmpStore, D0 + + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// ------------------------- AVX2 Code ---------------------------------------- +chacha20Poly1305Open_AVX2: + VZEROUPPER + VMOVDQU ·chacha20Constants<>(SB), AA0 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12 + BYTE $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4 + VPADDD ·avx2InitMask<>(SB), DD0, DD0 + + // Special optimization, for very short buffers + CMPQ inl, $192 + JBE openAVX2192 + CMPQ inl, $320 + JBE openAVX2320 + + // For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream + VMOVDQA BB0, state1StoreAVX2 + VMOVDQA CC0, state2StoreAVX2 + VMOVDQA DD0, ctr3StoreAVX2 + MOVQ $10, itr2 + +openAVX2PreparePolyKey: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + DECQ itr2 + JNE openAVX2PreparePolyKey + + VPADDD ·chacha20Constants<>(SB), AA0, AA0 + VPADDD state1StoreAVX2, BB0, BB0 + VPADDD state2StoreAVX2, CC0, CC0 + VPADDD ctr3StoreAVX2, DD0, DD0 + + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for the first 64 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + + // Hash AD + first 64 bytes + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +openAVX2InitialHash64: + polyAdd(0(inp)(itr1*1)) + polyMulAVX2 + ADDQ $16, itr1 + CMPQ itr1, $64 + JNE openAVX2InitialHash64 + + // Decrypt the first 64 bytes + VPXOR (0*32)(inp), AA0, AA0 + VPXOR (1*32)(inp), BB0, BB0 + VMOVDQU AA0, (0*32)(oup) + VMOVDQU BB0, (1*32)(oup) + LEAQ (2*32)(inp), inp + LEAQ (2*32)(oup), oup + SUBQ $64, inl + +openAVX2MainLoop: + CMPQ inl, $512 + JB openAVX2MainLoopDone + + // Load state, increment counter blocks, store the incremented counters + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + XORQ itr1, itr1 + +openAVX2InternalLoop: + // Lets just say this spaghetti loop interleaves 2 quarter rounds with 3 poly multiplications + // Effectively per 512 bytes of stream we hash 480 bytes of ciphertext + polyAdd(0*8(inp)(itr1*1)) + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage1_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulStage2_AVX2 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyMulStage3_AVX2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + polyAdd(2*8(inp)(itr1*1)) + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage1_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage2_AVX2 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage3_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulReduceStage + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(4*8(inp)(itr1*1)) + LEAQ (6*8)(itr1), itr1 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage1_AVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + polyMulStage2_AVX2 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage3_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + CMPQ itr1, $480 + JNE openAVX2InternalLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + + // We only hashed 480 of the 512 bytes available - hash the remaining 32 here + polyAdd(480(inp)) + polyMulAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + // and here + polyAdd(496(inp)) + polyMulAVX2 + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + VPXOR (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0 + VMOVDQU AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup) + LEAQ (32*16)(inp), inp + LEAQ (32*16)(oup), oup + SUBQ $(32*16), inl + JMP openAVX2MainLoop + +openAVX2MainLoopDone: + // Handle the various tail sizes efficiently + TESTQ inl, inl + JE openSSEFinalize + CMPQ inl, $128 + JBE openAVX2Tail128 + CMPQ inl, $256 + JBE openAVX2Tail256 + CMPQ inl, $384 + JBE openAVX2Tail384 + JMP openAVX2Tail512 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 193 bytes +openAVX2192: + // For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks + VMOVDQA AA0, AA1 + VMOVDQA BB0, BB1 + VMOVDQA CC0, CC1 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2 + VMOVDQA BB0, BB2 + VMOVDQA CC0, CC2 + VMOVDQA DD0, DD2 + VMOVDQA DD1, TT3 + MOVQ $10, itr2 + +openAVX2192InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr2 + JNE openAVX2192InnerCipherLoop + VPADDD AA2, AA0, AA0; VPADDD AA2, AA1, AA1 + VPADDD BB2, BB0, BB0; VPADDD BB2, BB1, BB1 + VPADDD CC2, CC0, CC0; VPADDD CC2, CC1, CC1 + VPADDD DD2, DD0, DD0; VPADDD TT3, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 192 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + +openAVX2ShortOpen: + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openAVX2ShortOpenLoop: + CMPQ inl, $32 + JB openAVX2ShortTail32 + SUBQ $32, inl + + // Load for hashing + polyAdd(0*8(inp)) + polyMulAVX2 + polyAdd(2*8(inp)) + polyMulAVX2 + + // Load for decryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + LEAQ (1*32)(oup), oup + + // Shift stream left + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + VMOVDQA AA1, DD0 + VMOVDQA BB1, AA1 + VMOVDQA CC1, BB1 + VMOVDQA DD1, CC1 + VMOVDQA AA2, DD1 + VMOVDQA BB2, AA2 + JMP openAVX2ShortOpenLoop + +openAVX2ShortTail32: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB openAVX2ShortDone + + SUBQ $16, inl + + // Load for hashing + polyAdd(0*8(inp)) + polyMulAVX2 + + // Load for decryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +openAVX2ShortDone: + VZEROUPPER + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 321 bytes +openAVX2320: + // For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks + VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3 + MOVQ $10, itr2 + +openAVX2320InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr2 + JNE openAVX2320InnerCipherLoop + + VMOVDQA ·chacha20Constants<>(SB), TT0 + VPADDD TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2 + VPADDD TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2 + VPADDD TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2 + VMOVDQA ·avx2IncMask<>(SB), TT0 + VPADDD TT3, DD0, DD0; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD1, DD1; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD2, DD2 + + // Clamp and store poly key + VPERM2I128 $0x02, AA0, BB0, TT0 + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 320 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + VPERM2I128 $0x02, AA2, BB2, CC1 + VPERM2I128 $0x02, CC2, DD2, DD1 + VPERM2I128 $0x13, AA2, BB2, AA2 + VPERM2I128 $0x13, CC2, DD2, BB2 + JMP openAVX2ShortOpen + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +openAVX2Tail128: + // Need to decrypt up to 128 bytes - prepare two blocks + VMOVDQA ·chacha20Constants<>(SB), AA1 + VMOVDQA state1StoreAVX2, BB1 + VMOVDQA state2StoreAVX2, CC1 + VMOVDQA ctr3StoreAVX2, DD1 + VPADDD ·avx2IncMask<>(SB), DD1, DD1 + VMOVDQA DD1, DD0 + + XORQ itr2, itr2 + MOVQ inl, itr1 + ANDQ $-16, itr1 + TESTQ itr1, itr1 + JE openAVX2Tail128LoopB + +openAVX2Tail128LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMulAVX2 + +openAVX2Tail128LoopB: + ADDQ $16, itr2 + chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD1, DD1, DD1 + CMPQ itr2, itr1 + JB openAVX2Tail128LoopA + CMPQ itr2, $160 + JNE openAVX2Tail128LoopB + + VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC1, CC1 + VPADDD DD0, DD1, DD1 + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + +openAVX2TailLoop: + CMPQ inl, $32 + JB openAVX2Tail + SUBQ $32, inl + + // Load for decryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + LEAQ (1*32)(oup), oup + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + JMP openAVX2TailLoop + +openAVX2Tail: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB openAVX2TailDone + SUBQ $16, inl + + // Load for decryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +openAVX2TailDone: + VZEROUPPER + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +openAVX2Tail256: + // Need to decrypt up to 256 bytes - prepare four blocks + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA DD0, TT1 + VMOVDQA DD1, TT2 + + // Compute the number of iterations that will hash data + MOVQ inl, tmpStoreAVX2 + MOVQ inl, itr1 + SUBQ $128, itr1 + SHRQ $4, itr1 + MOVQ $10, itr2 + CMPQ itr1, $10 + CMOVQGT itr2, itr1 + MOVQ inp, inl + XORQ itr2, itr2 + +openAVX2Tail256LoopA: + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + + // Perform ChaCha rounds, while hashing the remaining input +openAVX2Tail256LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + INCQ itr2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + CMPQ itr2, itr1 + JB openAVX2Tail256LoopA + + CMPQ itr2, $10 + JNE openAVX2Tail256LoopB + + MOVQ inl, itr2 + SUBQ inp, inl + MOVQ inl, itr1 + MOVQ tmpStoreAVX2, inl + + // Hash the remainder of data (if any) +openAVX2Tail256Hash: + ADDQ $16, itr1 + CMPQ itr1, inl + JGT openAVX2Tail256HashEnd + polyAdd (0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + JMP openAVX2Tail256Hash + +// Store 128 bytes safely, then go to store loop +openAVX2Tail256HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, AA2; VPERM2I128 $0x02, CC0, DD0, BB2; VPERM2I128 $0x13, AA0, BB0, CC2; VPERM2I128 $0x13, CC0, DD0, DD2 + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + + VPXOR (0*32)(inp), AA2, AA2; VPXOR (1*32)(inp), BB2, BB2; VPXOR (2*32)(inp), CC2, CC2; VPXOR (3*32)(inp), DD2, DD2 + VMOVDQU AA2, (0*32)(oup); VMOVDQU BB2, (1*32)(oup); VMOVDQU CC2, (2*32)(oup); VMOVDQU DD2, (3*32)(oup) + LEAQ (4*32)(inp), inp + LEAQ (4*32)(oup), oup + SUBQ $4*32, inl + + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 384 bytes of ciphertext +openAVX2Tail384: + // Need to decrypt up to 384 bytes - prepare six blocks + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA DD0, ctr0StoreAVX2 + VMOVDQA DD1, ctr1StoreAVX2 + VMOVDQA DD2, ctr2StoreAVX2 + + // Compute the number of iterations that will hash two blocks of data + MOVQ inl, tmpStoreAVX2 + MOVQ inl, itr1 + SUBQ $256, itr1 + SHRQ $4, itr1 + ADDQ $6, itr1 + MOVQ $10, itr2 + CMPQ itr1, $10 + CMOVQGT itr2, itr1 + MOVQ inp, inl + XORQ itr2, itr2 + + // Perform ChaCha rounds, while hashing the remaining input +openAVX2Tail384LoopB: + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + +openAVX2Tail384LoopA: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + INCQ itr2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + + CMPQ itr2, itr1 + JB openAVX2Tail384LoopB + + CMPQ itr2, $10 + JNE openAVX2Tail384LoopA + + MOVQ inl, itr2 + SUBQ inp, inl + MOVQ inl, itr1 + MOVQ tmpStoreAVX2, inl + +openAVX2Tail384Hash: + ADDQ $16, itr1 + CMPQ itr1, inl + JGT openAVX2Tail384HashEnd + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + JMP openAVX2Tail384Hash + +// Store 256 bytes safely, then go to store loop +openAVX2Tail384HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2 + VPERM2I128 $0x02, AA0, BB0, TT0; VPERM2I128 $0x02, CC0, DD0, TT1; VPERM2I128 $0x13, AA0, BB0, TT2; VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, TT0; VPERM2I128 $0x02, CC1, DD1, TT1; VPERM2I128 $0x13, AA1, BB1, TT2; VPERM2I128 $0x13, CC1, DD1, TT3 + VPXOR (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3 + VMOVDQU TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + LEAQ (8*32)(inp), inp + LEAQ (8*32)(oup), oup + SUBQ $8*32, inl + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 512 bytes of ciphertext +openAVX2Tail512: + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + XORQ itr1, itr1 + MOVQ inp, itr2 + +openAVX2Tail512LoopB: + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ (2*8)(itr2), itr2 + +openAVX2Tail512LoopA: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyAdd(0*8(itr2)) + polyMulAVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(2*8(itr2)) + polyMulAVX2 + LEAQ (4*8)(itr2), itr2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + INCQ itr1 + CMPQ itr1, $4 + JLT openAVX2Tail512LoopB + + CMPQ itr1, $10 + JNE openAVX2Tail512LoopA + + MOVQ inl, itr1 + SUBQ $384, itr1 + ANDQ $-16, itr1 + +openAVX2Tail512HashLoop: + TESTQ itr1, itr1 + JE openAVX2Tail512HashEnd + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + SUBQ $16, itr1 + JMP openAVX2Tail512HashLoop + +openAVX2Tail512HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + + LEAQ (12*32)(inp), inp + LEAQ (12*32)(oup), oup + SUBQ $12*32, inl + + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// func chacha20Poly1305Seal(dst, key, src, ad []byte) +TEXT ·chacha20Poly1305Seal(SB), 0, $288-96 + // For aligned stack access + MOVQ SP, BP + ADDQ $32, BP + ANDQ $-32, BP + MOVQ dst+0(FP), oup + MOVQ key+24(FP), keyp + MOVQ src+48(FP), inp + MOVQ src_len+56(FP), inl + MOVQ ad+72(FP), adp + + CMPB ·useAVX2(SB), $1 + JE chacha20Poly1305Seal_AVX2 + + // Special optimization, for very short buffers + CMPQ inl, $128 + JBE sealSSE128 // About 15% faster + + // In the seal case - prepare the poly key + 3 blocks of stream in the first iteration + MOVOU ·chacha20Constants<>(SB), A0 + MOVOU (1*16)(keyp), B0 + MOVOU (2*16)(keyp), C0 + MOVOU (3*16)(keyp), D0 + + // Store state on stack for future use + MOVO B0, state1Store + MOVO C0, state2Store + + // Load state, increment counter blocks + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + MOVQ $10, itr2 + +sealSSEIntroLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr2 + JNE sealSSEIntroLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVO A0, rStore + MOVO B0, sStore + + // Hash AAD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup) + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (4*16)(oup); MOVOU B2, (5*16)(oup); MOVOU C2, (6*16)(oup); MOVOU D2, (7*16)(oup) + + MOVQ $128, itr1 + SUBQ $128, inl + LEAQ 128(inp), inp + + MOVO A3, A1; MOVO B3, B1; MOVO C3, C1; MOVO D3, D1 + + CMPQ inl, $64 + JBE sealSSE128SealHash + + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3 + MOVOU A3, (8*16)(oup); MOVOU B3, (9*16)(oup); MOVOU C3, (10*16)(oup); MOVOU D3, (11*16)(oup) + + ADDQ $64, itr1 + SUBQ $64, inl + LEAQ 64(inp), inp + + MOVQ $2, itr1 + MOVQ $8, itr2 + + CMPQ inl, $64 + JBE sealSSETail64 + CMPQ inl, $128 + JBE sealSSETail128 + CMPQ inl, $192 + JBE sealSSETail192 + +sealSSEMainLoop: + // Load state, increment counter blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + +sealSSEInnerLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyAdd(0(oup)) + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + LEAQ (2*8)(oup), oup + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + polyMulStage3 + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr2 + JGE sealSSEInnerLoop + polyAdd(0(oup)) + polyMul + LEAQ (2*8)(oup), oup + DECQ itr1 + JG sealSSEInnerLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + MOVO D3, tmpStore + + // Load - xor - store + MOVOU (0*16)(inp), D3; PXOR D3, A0 + MOVOU (1*16)(inp), D3; PXOR D3, B0 + MOVOU (2*16)(inp), D3; PXOR D3, C0 + MOVOU (3*16)(inp), D3; PXOR D3, D0 + MOVOU A0, (0*16)(oup) + MOVOU B0, (1*16)(oup) + MOVOU C0, (2*16)(oup) + MOVOU D0, (3*16)(oup) + MOVO tmpStore, D3 + + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup) + ADDQ $192, inp + MOVQ $192, itr1 + SUBQ $192, inl + MOVO A3, A1 + MOVO B3, B1 + MOVO C3, C1 + MOVO D3, D1 + CMPQ inl, $64 + JBE sealSSE128SealHash + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3 + MOVOU A3, (12*16)(oup); MOVOU B3, (13*16)(oup); MOVOU C3, (14*16)(oup); MOVOU D3, (15*16)(oup) + LEAQ 64(inp), inp + SUBQ $64, inl + MOVQ $6, itr1 + MOVQ $4, itr2 + CMPQ inl, $192 + JG sealSSEMainLoop + + MOVQ inl, itr1 + TESTQ inl, inl + JE sealSSE128SealHash + MOVQ $6, itr1 + CMPQ inl, $64 + JBE sealSSETail64 + CMPQ inl, $128 + JBE sealSSETail128 + JMP sealSSETail192 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 64 bytes of plaintext +sealSSETail64: + // Need to encrypt up to 64 bytes - prepare single block, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A1 + MOVO state1Store, B1 + MOVO state2Store, C1 + MOVO ctr3Store, D1 + PADDL ·sseIncMask<>(SB), D1 + MOVO D1, ctr0Store + +sealSSETail64LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail64LoopB: + chachaQR(A1, B1, C1, D1, T1) + shiftB1Left; shiftC1Left; shiftD1Left + chachaQR(A1, B1, C1, D1, T1) + shiftB1Right; shiftC1Right; shiftD1Right + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + + DECQ itr1 + JG sealSSETail64LoopA + + DECQ itr2 + JGE sealSSETail64LoopB + PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B1 + PADDL state2Store, C1 + PADDL ctr0Store, D1 + + JMP sealSSE128Seal + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of plaintext +sealSSETail128: + // Need to encrypt up to 128 bytes - prepare two blocks, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + +sealSSETail128LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail128LoopB: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + + DECQ itr1 + JG sealSSETail128LoopA + + DECQ itr2 + JGE sealSSETail128LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B0; PADDL state1Store, B1 + PADDL state2Store, C0; PADDL state2Store, C1 + PADDL ctr0Store, D0; PADDL ctr1Store, D1 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0 + MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup) + + MOVQ $64, itr1 + LEAQ 64(inp), inp + SUBQ $64, inl + + JMP sealSSE128SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 192 bytes of plaintext +sealSSETail192: + // Need to encrypt up to 192 bytes - prepare three blocks, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr2Store + +sealSSETail192LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail192LoopB: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + shiftB2Left; shiftC2Left; shiftD2Left + + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + shiftB2Right; shiftC2Right; shiftD2Right + + DECQ itr1 + JG sealSSETail192LoopA + + DECQ itr2 + JGE sealSSETail192LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2 + PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2 + PADDL ctr0Store, D0; PADDL ctr1Store, D1; PADDL ctr2Store, D2 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0 + MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + + MOVO A2, A1 + MOVO B2, B1 + MOVO C2, C1 + MOVO D2, D1 + MOVQ $128, itr1 + LEAQ 128(inp), inp + SUBQ $128, inl + + JMP sealSSE128SealHash + +// ---------------------------------------------------------------------------- +// Special seal optimization for buffers smaller than 129 bytes +sealSSE128: + // For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks + MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO B0, T1; MOVO C0, T2; MOVO D1, T3 + MOVQ $10, itr2 + +sealSSE128InnerCipherLoop: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftB1Left; shiftB2Left + shiftC0Left; shiftC1Left; shiftC2Left + shiftD0Left; shiftD1Left; shiftD2Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftB1Right; shiftB2Right + shiftC0Right; shiftC1Right; shiftC2Right + shiftD0Right; shiftD1Right; shiftD2Right + DECQ itr2 + JNE sealSSE128InnerCipherLoop + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL T1, B0; PADDL T1, B1; PADDL T1, B2 + PADDL T2, C1; PADDL T2, C2 + PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2 + PAND ·polyClampMask<>(SB), A0 + MOVOU A0, rStore + MOVOU B0, sStore + + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +sealSSE128SealHash: + // itr1 holds the number of bytes encrypted but not yet hashed + CMPQ itr1, $16 + JB sealSSE128Seal + polyAdd(0(oup)) + polyMul + + SUBQ $16, itr1 + ADDQ $16, oup + + JMP sealSSE128SealHash + +sealSSE128Seal: + CMPQ inl, $16 + JB sealSSETail + SUBQ $16, inl + + // Load for decryption + MOVOU (inp), T0 + PXOR T0, A1 + MOVOU A1, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + + // Extract for hashing + MOVQ A1, t0 + PSRLDQ $8, A1 + MOVQ A1, t1 + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + // Shift the stream "left" + MOVO B1, A1 + MOVO C1, B1 + MOVO D1, C1 + MOVO A2, D1 + MOVO B2, A2 + MOVO C2, B2 + MOVO D2, C2 + JMP sealSSE128Seal + +sealSSETail: + TESTQ inl, inl + JE sealSSEFinalize + + // We can only load the PT one byte at a time to avoid read after end of buffer + MOVQ inl, itr2 + SHLQ $4, itr2 + LEAQ ·andMask<>(SB), t0 + MOVQ inl, itr1 + LEAQ -1(inp)(inl*1), inp + XORQ t2, t2 + XORQ t3, t3 + XORQ AX, AX + +sealSSETailLoadLoop: + SHLQ $8, t2, t3 + SHLQ $8, t2 + MOVB (inp), AX + XORQ AX, t2 + LEAQ -1(inp), inp + DECQ itr1 + JNE sealSSETailLoadLoop + MOVQ t2, 0+tmpStore + MOVQ t3, 8+tmpStore + PXOR 0+tmpStore, A1 + MOVOU A1, (oup) + MOVOU -16(t0)(itr2*1), T0 + PAND T0, A1 + MOVQ A1, t0 + PSRLDQ $8, A1 + MOVQ A1, t1 + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + ADDQ inl, oup + +sealSSEFinalize: + // Hash in the buffer lengths + ADDQ ad_len+80(FP), acc0 + ADCQ src_len+56(FP), acc1 + ADCQ $1, acc2 + polyMul + + // Final reduce + MOVQ acc0, t0 + MOVQ acc1, t1 + MOVQ acc2, t2 + SUBQ $-5, acc0 + SBBQ $-1, acc1 + SBBQ $3, acc2 + CMOVQCS t0, acc0 + CMOVQCS t1, acc1 + CMOVQCS t2, acc2 + + // Add in the "s" part of the key + ADDQ 0+sStore, acc0 + ADCQ 8+sStore, acc1 + + // Finally store the tag at the end of the message + MOVQ acc0, (0*8)(oup) + MOVQ acc1, (1*8)(oup) + RET + +// ---------------------------------------------------------------------------- +// ------------------------- AVX2 Code ---------------------------------------- +chacha20Poly1305Seal_AVX2: + VZEROUPPER + VMOVDQU ·chacha20Constants<>(SB), AA0 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12 + BYTE $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4 + VPADDD ·avx2InitMask<>(SB), DD0, DD0 + + // Special optimizations, for very short buffers + CMPQ inl, $192 + JBE seal192AVX2 // 33% faster + CMPQ inl, $320 + JBE seal320AVX2 // 17% faster + + // For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream + VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3; VMOVDQA BB0, state1StoreAVX2 + VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3; VMOVDQA CC0, state2StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD0, DD1; VMOVDQA DD0, ctr0StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD1, DD2; VMOVDQA DD1, ctr1StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD2, DD3; VMOVDQA DD2, ctr2StoreAVX2 + VMOVDQA DD3, ctr3StoreAVX2 + MOVQ $10, itr2 + +sealAVX2IntroLoop: + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1 + VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2 + VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1 + VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2 + VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3 + DECQ itr2 + JNE sealAVX2IntroLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + + VPERM2I128 $0x13, CC0, DD0, CC0 // Stream bytes 96 - 127 + VPERM2I128 $0x02, AA0, BB0, DD0 // The Poly1305 key + VPERM2I128 $0x13, AA0, BB0, AA0 // Stream bytes 64 - 95 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), DD0, DD0 + VMOVDQA DD0, rsStoreAVX2 + + // Hash AD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + + // Can store at least 320 bytes + VPXOR (0*32)(inp), AA0, AA0 + VPXOR (1*32)(inp), CC0, CC0 + VMOVDQU AA0, (0*32)(oup) + VMOVDQU CC0, (1*32)(oup) + + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (2*32)(inp), AA0, AA0; VPXOR (3*32)(inp), BB0, BB0; VPXOR (4*32)(inp), CC0, CC0; VPXOR (5*32)(inp), DD0, DD0 + VMOVDQU AA0, (2*32)(oup); VMOVDQU BB0, (3*32)(oup); VMOVDQU CC0, (4*32)(oup); VMOVDQU DD0, (5*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (6*32)(inp), AA0, AA0; VPXOR (7*32)(inp), BB0, BB0; VPXOR (8*32)(inp), CC0, CC0; VPXOR (9*32)(inp), DD0, DD0 + VMOVDQU AA0, (6*32)(oup); VMOVDQU BB0, (7*32)(oup); VMOVDQU CC0, (8*32)(oup); VMOVDQU DD0, (9*32)(oup) + + MOVQ $320, itr1 + SUBQ $320, inl + LEAQ 320(inp), inp + + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, CC3, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, CC3, DD3, DD0 + CMPQ inl, $128 + JBE sealAVX2SealHash + + VPXOR (0*32)(inp), AA0, AA0; VPXOR (1*32)(inp), BB0, BB0; VPXOR (2*32)(inp), CC0, CC0; VPXOR (3*32)(inp), DD0, DD0 + VMOVDQU AA0, (10*32)(oup); VMOVDQU BB0, (11*32)(oup); VMOVDQU CC0, (12*32)(oup); VMOVDQU DD0, (13*32)(oup) + SUBQ $128, inl + LEAQ 128(inp), inp + + MOVQ $8, itr1 + MOVQ $2, itr2 + + CMPQ inl, $128 + JBE sealAVX2Tail128 + CMPQ inl, $256 + JBE sealAVX2Tail256 + CMPQ inl, $384 + JBE sealAVX2Tail384 + CMPQ inl, $512 + JBE sealAVX2Tail512 + + // We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1 + VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2 + VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1 + VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2 + VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + + SUBQ $16, oup // Adjust the pointer + MOVQ $9, itr1 + JMP sealAVX2InternalLoopStart + +sealAVX2MainLoop: + // Load state, increment counter blocks, store the incremented counters + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + MOVQ $10, itr1 + +sealAVX2InternalLoop: + polyAdd(0*8(oup)) + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage1_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulStage2_AVX2 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyMulStage3_AVX2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + +sealAVX2InternalLoopStart: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + polyAdd(2*8(oup)) + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage1_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage2_AVX2 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage3_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulReduceStage + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(4*8(oup)) + LEAQ (6*8)(oup), oup + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage1_AVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + polyMulStage2_AVX2 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage3_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + DECQ itr1 + JNE sealAVX2InternalLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + + // We only hashed 480 of the 512 bytes available - hash the remaining 32 here + polyAdd(0*8(oup)) + polyMulAVX2 + LEAQ (4*8)(oup), oup + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + // and here + polyAdd(-2*8(oup)) + polyMulAVX2 + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + VPXOR (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0 + VMOVDQU AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup) + LEAQ (32*16)(inp), inp + SUBQ $(32*16), inl + CMPQ inl, $512 + JG sealAVX2MainLoop + + // Tail can only hash 480 bytes + polyAdd(0*8(oup)) + polyMulAVX2 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ 32(oup), oup + + MOVQ $10, itr1 + MOVQ $0, itr2 + CMPQ inl, $128 + JBE sealAVX2Tail128 + CMPQ inl, $256 + JBE sealAVX2Tail256 + CMPQ inl, $384 + JBE sealAVX2Tail384 + JMP sealAVX2Tail512 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 193 bytes +seal192AVX2: + // For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks + VMOVDQA AA0, AA1 + VMOVDQA BB0, BB1 + VMOVDQA CC0, CC1 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2 + VMOVDQA BB0, BB2 + VMOVDQA CC0, CC2 + VMOVDQA DD0, DD2 + VMOVDQA DD1, TT3 + MOVQ $10, itr2 + +sealAVX2192InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr2 + JNE sealAVX2192InnerCipherLoop + VPADDD AA2, AA0, AA0; VPADDD AA2, AA1, AA1 + VPADDD BB2, BB0, BB0; VPADDD BB2, BB1, BB1 + VPADDD CC2, CC0, CC0; VPADDD CC2, CC1, CC1 + VPADDD DD2, DD0, DD0; VPADDD TT3, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 192 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + +sealAVX2ShortSeal: + // Hash aad + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +sealAVX2SealHash: + // itr1 holds the number of bytes encrypted but not yet hashed + CMPQ itr1, $16 + JB sealAVX2ShortSealLoop + polyAdd(0(oup)) + polyMul + SUBQ $16, itr1 + ADDQ $16, oup + JMP sealAVX2SealHash + +sealAVX2ShortSealLoop: + CMPQ inl, $32 + JB sealAVX2ShortTail32 + SUBQ $32, inl + + // Load for encryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + + // Now can hash + polyAdd(0*8(oup)) + polyMulAVX2 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ (1*32)(oup), oup + + // Shift stream left + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + VMOVDQA AA1, DD0 + VMOVDQA BB1, AA1 + VMOVDQA CC1, BB1 + VMOVDQA DD1, CC1 + VMOVDQA AA2, DD1 + VMOVDQA BB2, AA2 + JMP sealAVX2ShortSealLoop + +sealAVX2ShortTail32: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB sealAVX2ShortDone + + SUBQ $16, inl + + // Load for encryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + + // Hash + polyAdd(0*8(oup)) + polyMulAVX2 + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +sealAVX2ShortDone: + VZEROUPPER + JMP sealSSETail + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 321 bytes +seal320AVX2: + // For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks + VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3 + MOVQ $10, itr2 + +sealAVX2320InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr2 + JNE sealAVX2320InnerCipherLoop + + VMOVDQA ·chacha20Constants<>(SB), TT0 + VPADDD TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2 + VPADDD TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2 + VPADDD TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2 + VMOVDQA ·avx2IncMask<>(SB), TT0 + VPADDD TT3, DD0, DD0; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD1, DD1; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD2, DD2 + + // Clamp and store poly key + VPERM2I128 $0x02, AA0, BB0, TT0 + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 320 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + VPERM2I128 $0x02, AA2, BB2, CC1 + VPERM2I128 $0x02, CC2, DD2, DD1 + VPERM2I128 $0x13, AA2, BB2, AA2 + VPERM2I128 $0x13, CC2, DD2, BB2 + JMP sealAVX2ShortSeal + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +sealAVX2Tail128: + // Need to decrypt up to 128 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0 + VMOVDQA state1StoreAVX2, BB0 + VMOVDQA state2StoreAVX2, CC0 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VMOVDQA DD0, DD1 + +sealAVX2Tail128LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail128LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0 + VPALIGNR $8, CC0, CC0, CC0 + VPALIGNR $12, DD0, DD0, DD0 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0 + VPALIGNR $8, CC0, CC0, CC0 + VPALIGNR $4, DD0, DD0, DD0 + DECQ itr1 + JG sealAVX2Tail128LoopA + DECQ itr2 + JGE sealAVX2Tail128LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA1 + VPADDD state1StoreAVX2, BB0, BB1 + VPADDD state2StoreAVX2, CC0, CC1 + VPADDD DD1, DD0, DD1 + + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + JMP sealAVX2ShortSealLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +sealAVX2Tail256: + // Need to decrypt up to 256 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA ·chacha20Constants<>(SB), AA1 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA state1StoreAVX2, BB1 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA state2StoreAVX2, CC1 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA DD0, TT1 + VMOVDQA DD1, TT2 + +sealAVX2Tail256LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail256LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr1 + JG sealAVX2Tail256LoopA + DECQ itr2 + JGE sealAVX2Tail256LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + VPERM2I128 $0x02, CC0, DD0, TT1 + VPERM2I128 $0x13, AA0, BB0, TT2 + VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + MOVQ $128, itr1 + LEAQ 128(inp), inp + SUBQ $128, inl + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + + JMP sealAVX2SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 384 bytes of ciphertext +sealAVX2Tail384: + // Need to decrypt up to 384 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA DD0, TT1; VMOVDQA DD1, TT2; VMOVDQA DD2, TT3 + +sealAVX2Tail384LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail384LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr1 + JG sealAVX2Tail384LoopA + DECQ itr2 + JGE sealAVX2Tail384LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1; VPADDD TT3, DD2, DD2 + VPERM2I128 $0x02, AA0, BB0, TT0 + VPERM2I128 $0x02, CC0, DD0, TT1 + VPERM2I128 $0x13, AA0, BB0, TT2 + VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, TT0 + VPERM2I128 $0x02, CC1, DD1, TT1 + VPERM2I128 $0x13, AA1, BB1, TT2 + VPERM2I128 $0x13, CC1, DD1, TT3 + VPXOR (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3 + VMOVDQU TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup) + MOVQ $256, itr1 + LEAQ 256(inp), inp + SUBQ $256, inl + VPERM2I128 $0x02, AA2, BB2, AA0 + VPERM2I128 $0x02, CC2, DD2, BB0 + VPERM2I128 $0x13, AA2, BB2, CC0 + VPERM2I128 $0x13, CC2, DD2, DD0 + + JMP sealAVX2SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 512 bytes of ciphertext +sealAVX2Tail512: + // Need to decrypt up to 512 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + +sealAVX2Tail512LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail512LoopB: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyAdd(0*8(oup)) + polyMulAVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ (4*8)(oup), oup + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + + DECQ itr1 + JG sealAVX2Tail512LoopA + DECQ itr2 + JGE sealAVX2Tail512LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3 + VPXOR (0*32)(inp), CC3, CC3 + VMOVDQU CC3, (0*32)(oup) + VPERM2I128 $0x02, CC0, DD0, CC3 + VPXOR (1*32)(inp), CC3, CC3 + VMOVDQU CC3, (1*32)(oup) + VPERM2I128 $0x13, AA0, BB0, CC3 + VPXOR (2*32)(inp), CC3, CC3 + VMOVDQU CC3, (2*32)(oup) + VPERM2I128 $0x13, CC0, DD0, CC3 + VPXOR (3*32)(inp), CC3, CC3 + VMOVDQU CC3, (3*32)(oup) + + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + VPERM2I128 $0x02, AA2, BB2, AA0 + VPERM2I128 $0x02, CC2, DD2, BB0 + VPERM2I128 $0x13, AA2, BB2, CC0 + VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + + MOVQ $384, itr1 + LEAQ 384(inp), inp + SUBQ $384, inl + VPERM2I128 $0x02, AA3, BB3, AA0 + VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0 + VPERM2I128 $0x13, AA3, BB3, CC0 + VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + + JMP sealAVX2SealHash diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go new file mode 100644 index 00000000000..6313898f0a7 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go @@ -0,0 +1,81 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package chacha20poly1305 + +import ( + "encoding/binary" + + "golang.org/x/crypto/chacha20" + "golang.org/x/crypto/internal/alias" + "golang.org/x/crypto/internal/poly1305" +) + +func writeWithPadding(p *poly1305.MAC, b []byte) { + p.Write(b) + if rem := len(b) % 16; rem != 0 { + var buf [16]byte + padLen := 16 - rem + p.Write(buf[:padLen]) + } +} + +func writeUint64(p *poly1305.MAC, n int) { + var buf [8]byte + binary.LittleEndian.PutUint64(buf[:], uint64(n)) + p.Write(buf[:]) +} + +func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte { + ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) + ciphertext, tag := out[:len(plaintext)], out[len(plaintext):] + if alias.InexactOverlap(out, plaintext) { + panic("chacha20poly1305: invalid buffer overlap") + } + + var polyKey [32]byte + s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) + s.XORKeyStream(polyKey[:], polyKey[:]) + s.SetCounter(1) // set the counter to 1, skipping 32 bytes + s.XORKeyStream(ciphertext, plaintext) + + p := poly1305.New(&polyKey) + writeWithPadding(p, additionalData) + writeWithPadding(p, ciphertext) + writeUint64(p, len(additionalData)) + writeUint64(p, len(plaintext)) + p.Sum(tag[:0]) + + return ret +} + +func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + tag := ciphertext[len(ciphertext)-16:] + ciphertext = ciphertext[:len(ciphertext)-16] + + var polyKey [32]byte + s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) + s.XORKeyStream(polyKey[:], polyKey[:]) + s.SetCounter(1) // set the counter to 1, skipping 32 bytes + + p := poly1305.New(&polyKey) + writeWithPadding(p, additionalData) + writeWithPadding(p, ciphertext) + writeUint64(p, len(additionalData)) + writeUint64(p, len(ciphertext)) + + ret, out := sliceForAppend(dst, len(ciphertext)) + if alias.InexactOverlap(out, ciphertext) { + panic("chacha20poly1305: invalid buffer overlap") + } + if !p.Verify(tag) { + for i := range out { + out[i] = 0 + } + return nil, errOpen + } + + s.XORKeyStream(out, ciphertext) + return ret, nil +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go new file mode 100644 index 00000000000..f832b33d45f --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go @@ -0,0 +1,16 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !amd64 || !gc || purego +// +build !amd64 !gc purego + +package chacha20poly1305 + +func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte { + return c.sealGeneric(dst, nonce, plaintext, additionalData) +} + +func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + return c.openGeneric(dst, nonce, ciphertext, additionalData) +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go b/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go new file mode 100644 index 00000000000..1cebfe946f4 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go @@ -0,0 +1,86 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package chacha20poly1305 + +import ( + "crypto/cipher" + "errors" + + "golang.org/x/crypto/chacha20" +) + +type xchacha20poly1305 struct { + key [KeySize]byte +} + +// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key. +// +// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce, +// suitable to be generated randomly without risk of collisions. It should be +// preferred when nonce uniqueness cannot be trivially ensured, or whenever +// nonces are randomly generated. +func NewX(key []byte) (cipher.AEAD, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20poly1305: bad key length") + } + ret := new(xchacha20poly1305) + copy(ret.key[:], key) + return ret, nil +} + +func (*xchacha20poly1305) NonceSize() int { + return NonceSizeX +} + +func (*xchacha20poly1305) Overhead() int { + return Overhead +} + +func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + if len(nonce) != NonceSizeX { + panic("chacha20poly1305: bad nonce length passed to Seal") + } + + // XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no + // size limit. However, since we reuse the ChaCha20-Poly1305 implementation, + // the second half of the counter is not available. This is unlikely to be + // an issue because the cipher.AEAD API requires the entire message to be in + // memory, and the counter overflows at 256 GB. + if uint64(len(plaintext)) > (1<<38)-64 { + panic("chacha20poly1305: plaintext too large") + } + + c := new(chacha20poly1305) + hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16]) + copy(c.key[:], hKey) + + // The first 4 bytes of the final nonce are unused counter space. + cNonce := make([]byte, NonceSize) + copy(cNonce[4:12], nonce[16:24]) + + return c.seal(dst, cNonce[:], plaintext, additionalData) +} + +func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if len(nonce) != NonceSizeX { + panic("chacha20poly1305: bad nonce length passed to Open") + } + if len(ciphertext) < 16 { + return nil, errOpen + } + if uint64(len(ciphertext)) > (1<<38)-48 { + panic("chacha20poly1305: ciphertext too large") + } + + c := new(chacha20poly1305) + hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16]) + copy(c.key[:], hKey) + + // The first 4 bytes of the final nonce are unused counter space. + cNonce := make([]byte, NonceSize) + copy(cNonce[4:12], nonce[16:24]) + + return c.open(dst, cNonce[:], ciphertext, additionalData) +} diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1.go new file mode 100644 index 00000000000..6fc2838a3fb --- /dev/null +++ b/vendor/golang.org/x/crypto/cryptobyte/asn1.go @@ -0,0 +1,824 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cryptobyte + +import ( + encoding_asn1 "encoding/asn1" + "fmt" + "math/big" + "reflect" + "time" + + "golang.org/x/crypto/cryptobyte/asn1" +) + +// This file contains ASN.1-related methods for String and Builder. + +// Builder + +// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER. +func (b *Builder) AddASN1Int64(v int64) { + b.addASN1Signed(asn1.INTEGER, v) +} + +// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the +// given tag. +func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) { + b.addASN1Signed(tag, v) +} + +// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION. +func (b *Builder) AddASN1Enum(v int64) { + b.addASN1Signed(asn1.ENUM, v) +} + +func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) { + b.AddASN1(tag, func(c *Builder) { + length := 1 + for i := v; i >= 0x80 || i < -0x80; i >>= 8 { + length++ + } + + for ; length > 0; length-- { + i := v >> uint((length-1)*8) & 0xff + c.AddUint8(uint8(i)) + } + }) +} + +// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER. +func (b *Builder) AddASN1Uint64(v uint64) { + b.AddASN1(asn1.INTEGER, func(c *Builder) { + length := 1 + for i := v; i >= 0x80; i >>= 8 { + length++ + } + + for ; length > 0; length-- { + i := v >> uint((length-1)*8) & 0xff + c.AddUint8(uint8(i)) + } + }) +} + +// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER. +func (b *Builder) AddASN1BigInt(n *big.Int) { + if b.err != nil { + return + } + + b.AddASN1(asn1.INTEGER, func(c *Builder) { + if n.Sign() < 0 { + // A negative number has to be converted to two's-complement form. So we + // invert and subtract 1. If the most-significant-bit isn't set then + // we'll need to pad the beginning with 0xff in order to keep the number + // negative. + nMinus1 := new(big.Int).Neg(n) + nMinus1.Sub(nMinus1, bigOne) + bytes := nMinus1.Bytes() + for i := range bytes { + bytes[i] ^= 0xff + } + if len(bytes) == 0 || bytes[0]&0x80 == 0 { + c.add(0xff) + } + c.add(bytes...) + } else if n.Sign() == 0 { + c.add(0) + } else { + bytes := n.Bytes() + if bytes[0]&0x80 != 0 { + c.add(0) + } + c.add(bytes...) + } + }) +} + +// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING. +func (b *Builder) AddASN1OctetString(bytes []byte) { + b.AddASN1(asn1.OCTET_STRING, func(c *Builder) { + c.AddBytes(bytes) + }) +} + +const generalizedTimeFormatStr = "20060102150405Z0700" + +// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME. +func (b *Builder) AddASN1GeneralizedTime(t time.Time) { + if t.Year() < 0 || t.Year() > 9999 { + b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t) + return + } + b.AddASN1(asn1.GeneralizedTime, func(c *Builder) { + c.AddBytes([]byte(t.Format(generalizedTimeFormatStr))) + }) +} + +// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime. +func (b *Builder) AddASN1UTCTime(t time.Time) { + b.AddASN1(asn1.UTCTime, func(c *Builder) { + // As utilized by the X.509 profile, UTCTime can only + // represent the years 1950 through 2049. + if t.Year() < 1950 || t.Year() >= 2050 { + b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t) + return + } + c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr))) + }) +} + +// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not +// support BIT STRINGs that are not a whole number of bytes. +func (b *Builder) AddASN1BitString(data []byte) { + b.AddASN1(asn1.BIT_STRING, func(b *Builder) { + b.AddUint8(0) + b.AddBytes(data) + }) +} + +func (b *Builder) addBase128Int(n int64) { + var length int + if n == 0 { + length = 1 + } else { + for i := n; i > 0; i >>= 7 { + length++ + } + } + + for i := length - 1; i >= 0; i-- { + o := byte(n >> uint(i*7)) + o &= 0x7f + if i != 0 { + o |= 0x80 + } + + b.add(o) + } +} + +func isValidOID(oid encoding_asn1.ObjectIdentifier) bool { + if len(oid) < 2 { + return false + } + + if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) { + return false + } + + for _, v := range oid { + if v < 0 { + return false + } + } + + return true +} + +func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) { + b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) { + if !isValidOID(oid) { + b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid) + return + } + + b.addBase128Int(int64(oid[0])*40 + int64(oid[1])) + for _, v := range oid[2:] { + b.addBase128Int(int64(v)) + } + }) +} + +func (b *Builder) AddASN1Boolean(v bool) { + b.AddASN1(asn1.BOOLEAN, func(b *Builder) { + if v { + b.AddUint8(0xff) + } else { + b.AddUint8(0) + } + }) +} + +func (b *Builder) AddASN1NULL() { + b.add(uint8(asn1.NULL), 0) +} + +// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if +// successful or records an error if one occurred. +func (b *Builder) MarshalASN1(v interface{}) { + // NOTE(martinkr): This is somewhat of a hack to allow propagation of + // encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a + // value embedded into a struct, its tag information is lost. + if b.err != nil { + return + } + bytes, err := encoding_asn1.Marshal(v) + if err != nil { + b.err = err + return + } + b.AddBytes(bytes) +} + +// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag. +// Tags greater than 30 are not supported and result in an error (i.e. +// low-tag-number form only). The child builder passed to the +// BuilderContinuation can be used to build the content of the ASN.1 object. +func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) { + if b.err != nil { + return + } + // Identifiers with the low five bits set indicate high-tag-number format + // (two or more octets), which we don't support. + if tag&0x1f == 0x1f { + b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag) + return + } + b.AddUint8(uint8(tag)) + b.addLengthPrefixed(1, true, f) +} + +// String + +// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean +// representation into out and advances. It reports whether the read +// was successful. +func (s *String) ReadASN1Boolean(out *bool) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 { + return false + } + + switch bytes[0] { + case 0: + *out = false + case 0xff: + *out = true + default: + return false + } + + return true +} + +// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does +// not point to an integer, to a big.Int, or to a []byte it panics. Only +// positive and zero values can be decoded into []byte, and they are returned as +// big-endian binary values that share memory with s. Positive values will have +// no leading zeroes, and zero will be returned as a single zero byte. +// ReadASN1Integer reports whether the read was successful. +func (s *String) ReadASN1Integer(out interface{}) bool { + switch out := out.(type) { + case *int, *int8, *int16, *int32, *int64: + var i int64 + if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) { + return false + } + reflect.ValueOf(out).Elem().SetInt(i) + return true + case *uint, *uint8, *uint16, *uint32, *uint64: + var u uint64 + if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) { + return false + } + reflect.ValueOf(out).Elem().SetUint(u) + return true + case *big.Int: + return s.readASN1BigInt(out) + case *[]byte: + return s.readASN1Bytes(out) + default: + panic("out does not point to an integer type") + } +} + +func checkASN1Integer(bytes []byte) bool { + if len(bytes) == 0 { + // An INTEGER is encoded with at least one octet. + return false + } + if len(bytes) == 1 { + return true + } + if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 { + // Value is not minimally encoded. + return false + } + return true +} + +var bigOne = big.NewInt(1) + +func (s *String) readASN1BigInt(out *big.Int) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { + return false + } + if bytes[0]&0x80 == 0x80 { + // Negative number. + neg := make([]byte, len(bytes)) + for i, b := range bytes { + neg[i] = ^b + } + out.SetBytes(neg) + out.Add(out, bigOne) + out.Neg(out) + } else { + out.SetBytes(bytes) + } + return true +} + +func (s *String) readASN1Bytes(out *[]byte) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { + return false + } + if bytes[0]&0x80 == 0x80 { + return false + } + for len(bytes) > 1 && bytes[0] == 0 { + bytes = bytes[1:] + } + *out = bytes + return true +} + +func (s *String) readASN1Int64(out *int64) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) { + return false + } + return true +} + +func asn1Signed(out *int64, n []byte) bool { + length := len(n) + if length > 8 { + return false + } + for i := 0; i < length; i++ { + *out <<= 8 + *out |= int64(n[i]) + } + // Shift up and down in order to sign extend the result. + *out <<= 64 - uint8(length)*8 + *out >>= 64 - uint8(length)*8 + return true +} + +func (s *String) readASN1Uint64(out *uint64) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) { + return false + } + return true +} + +func asn1Unsigned(out *uint64, n []byte) bool { + length := len(n) + if length > 9 || length == 9 && n[0] != 0 { + // Too large for uint64. + return false + } + if n[0]&0x80 != 0 { + // Negative number. + return false + } + for i := 0; i < length; i++ { + *out <<= 8 + *out |= uint64(n[i]) + } + return true +} + +// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out +// and advances. It reports whether the read was successful and resulted in a +// value that can be represented in an int64. +func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool { + var bytes String + return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes) +} + +// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports +// whether the read was successful. +func (s *String) ReadASN1Enum(out *int) bool { + var bytes String + var i int64 + if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) { + return false + } + if int64(int(i)) != i { + return false + } + *out = int(i) + return true +} + +func (s *String) readBase128Int(out *int) bool { + ret := 0 + for i := 0; len(*s) > 0; i++ { + if i == 5 { + return false + } + // Avoid overflowing int on a 32-bit platform. + // We don't want different behavior based on the architecture. + if ret >= 1<<(31-7) { + return false + } + ret <<= 7 + b := s.read(1)[0] + + // ITU-T X.690, section 8.19.2: + // The subidentifier shall be encoded in the fewest possible octets, + // that is, the leading octet of the subidentifier shall not have the value 0x80. + if i == 0 && b == 0x80 { + return false + } + + ret |= int(b & 0x7f) + if b&0x80 == 0 { + *out = ret + return true + } + } + return false // truncated +} + +// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and +// advances. It reports whether the read was successful. +func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 { + return false + } + + // In the worst case, we get two elements from the first byte (which is + // encoded differently) and then every varint is a single byte long. + components := make([]int, len(bytes)+1) + + // The first varint is 40*value1 + value2: + // According to this packing, value1 can take the values 0, 1 and 2 only. + // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2, + // then there are no restrictions on value2. + var v int + if !bytes.readBase128Int(&v) { + return false + } + if v < 80 { + components[0] = v / 40 + components[1] = v % 40 + } else { + components[0] = 2 + components[1] = v - 80 + } + + i := 2 + for ; len(bytes) > 0; i++ { + if !bytes.readBase128Int(&v) { + return false + } + components[i] = v + } + *out = components[:i] + return true +} + +// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and +// advances. It reports whether the read was successful. +func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.GeneralizedTime) { + return false + } + t := string(bytes) + res, err := time.Parse(generalizedTimeFormatStr, t) + if err != nil { + return false + } + if serialized := res.Format(generalizedTimeFormatStr); serialized != t { + return false + } + *out = res + return true +} + +const defaultUTCTimeFormatStr = "060102150405Z0700" + +// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances. +// It reports whether the read was successful. +func (s *String) ReadASN1UTCTime(out *time.Time) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.UTCTime) { + return false + } + t := string(bytes) + + formatStr := defaultUTCTimeFormatStr + var err error + res, err := time.Parse(formatStr, t) + if err != nil { + // Fallback to minute precision if we can't parse second + // precision. If we are following X.509 or X.690 we shouldn't + // support this, but we do. + formatStr = "0601021504Z0700" + res, err = time.Parse(formatStr, t) + } + if err != nil { + return false + } + + if serialized := res.Format(formatStr); serialized != t { + return false + } + + if res.Year() >= 2050 { + // UTCTime interprets the low order digits 50-99 as 1950-99. + // This only applies to its use in the X.509 profile. + // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 + res = res.AddDate(-100, 0, 0) + } + *out = res + return true +} + +// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. +// It reports whether the read was successful. +func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool { + var bytes String + if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 || + len(bytes)*8/8 != len(bytes) { + return false + } + + paddingBits := bytes[0] + bytes = bytes[1:] + if paddingBits > 7 || + len(bytes) == 0 && paddingBits != 0 || + len(bytes) > 0 && bytes[len(bytes)-1]&(1< 4 || len(*s) < int(2+lenLen) { + return false + } + + lenBytes := String((*s)[2 : 2+lenLen]) + if !lenBytes.readUnsigned(&len32, int(lenLen)) { + return false + } + + // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length + // with the minimum number of octets. + if len32 < 128 { + // Length should have used short-form encoding. + return false + } + if len32>>((lenLen-1)*8) == 0 { + // Leading octet is 0. Length should have been at least one byte shorter. + return false + } + + headerLen = 2 + uint32(lenLen) + if headerLen+len32 < len32 { + // Overflow. + return false + } + length = headerLen + len32 + } + + if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) { + return false + } + if skipHeader && !out.Skip(int(headerLen)) { + panic("cryptobyte: internal error") + } + + return true +} diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go new file mode 100644 index 00000000000..cda8e3edfd5 --- /dev/null +++ b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go @@ -0,0 +1,46 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package asn1 contains supporting types for parsing and building ASN.1 +// messages with the cryptobyte package. +package asn1 // import "golang.org/x/crypto/cryptobyte/asn1" + +// Tag represents an ASN.1 identifier octet, consisting of a tag number +// (indicating a type) and class (such as context-specific or constructed). +// +// Methods in the cryptobyte package only support the low-tag-number form, i.e. +// a single identifier octet with bits 7-8 encoding the class and bits 1-6 +// encoding the tag number. +type Tag uint8 + +const ( + classConstructed = 0x20 + classContextSpecific = 0x80 +) + +// Constructed returns t with the constructed class bit set. +func (t Tag) Constructed() Tag { return t | classConstructed } + +// ContextSpecific returns t with the context-specific class bit set. +func (t Tag) ContextSpecific() Tag { return t | classContextSpecific } + +// The following is a list of standard tag and class combinations. +const ( + BOOLEAN = Tag(1) + INTEGER = Tag(2) + BIT_STRING = Tag(3) + OCTET_STRING = Tag(4) + NULL = Tag(5) + OBJECT_IDENTIFIER = Tag(6) + ENUM = Tag(10) + UTF8String = Tag(12) + SEQUENCE = Tag(16 | classConstructed) + SET = Tag(17 | classConstructed) + PrintableString = Tag(19) + T61String = Tag(20) + IA5String = Tag(22) + UTCTime = Tag(23) + GeneralizedTime = Tag(24) + GeneralString = Tag(27) +) diff --git a/vendor/golang.org/x/crypto/cryptobyte/builder.go b/vendor/golang.org/x/crypto/cryptobyte/builder.go new file mode 100644 index 00000000000..cf254f5f1e8 --- /dev/null +++ b/vendor/golang.org/x/crypto/cryptobyte/builder.go @@ -0,0 +1,350 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cryptobyte + +import ( + "errors" + "fmt" +) + +// A Builder builds byte strings from fixed-length and length-prefixed values. +// Builders either allocate space as needed, or are ‘fixed’, which means that +// they write into a given buffer and produce an error if it's exhausted. +// +// The zero value is a usable Builder that allocates space as needed. +// +// Simple values are marshaled and appended to a Builder using methods on the +// Builder. Length-prefixed values are marshaled by providing a +// BuilderContinuation, which is a function that writes the inner contents of +// the value to a given Builder. See the documentation for BuilderContinuation +// for details. +type Builder struct { + err error + result []byte + fixedSize bool + child *Builder + offset int + pendingLenLen int + pendingIsASN1 bool + inContinuation *bool +} + +// NewBuilder creates a Builder that appends its output to the given buffer. +// Like append(), the slice will be reallocated if its capacity is exceeded. +// Use Bytes to get the final buffer. +func NewBuilder(buffer []byte) *Builder { + return &Builder{ + result: buffer, + } +} + +// NewFixedBuilder creates a Builder that appends its output into the given +// buffer. This builder does not reallocate the output buffer. Writes that +// would exceed the buffer's capacity are treated as an error. +func NewFixedBuilder(buffer []byte) *Builder { + return &Builder{ + result: buffer, + fixedSize: true, + } +} + +// SetError sets the value to be returned as the error from Bytes. Writes +// performed after calling SetError are ignored. +func (b *Builder) SetError(err error) { + b.err = err +} + +// Bytes returns the bytes written by the builder or an error if one has +// occurred during building. +func (b *Builder) Bytes() ([]byte, error) { + if b.err != nil { + return nil, b.err + } + return b.result[b.offset:], nil +} + +// BytesOrPanic returns the bytes written by the builder or panics if an error +// has occurred during building. +func (b *Builder) BytesOrPanic() []byte { + if b.err != nil { + panic(b.err) + } + return b.result[b.offset:] +} + +// AddUint8 appends an 8-bit value to the byte string. +func (b *Builder) AddUint8(v uint8) { + b.add(byte(v)) +} + +// AddUint16 appends a big-endian, 16-bit value to the byte string. +func (b *Builder) AddUint16(v uint16) { + b.add(byte(v>>8), byte(v)) +} + +// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest +// byte of the 32-bit input value is silently truncated. +func (b *Builder) AddUint24(v uint32) { + b.add(byte(v>>16), byte(v>>8), byte(v)) +} + +// AddUint32 appends a big-endian, 32-bit value to the byte string. +func (b *Builder) AddUint32(v uint32) { + b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +// AddUint48 appends a big-endian, 48-bit value to the byte string. +func (b *Builder) AddUint48(v uint64) { + b.add(byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +// AddUint64 appends a big-endian, 64-bit value to the byte string. +func (b *Builder) AddUint64(v uint64) { + b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +// AddBytes appends a sequence of bytes to the byte string. +func (b *Builder) AddBytes(v []byte) { + b.add(v...) +} + +// BuilderContinuation is a continuation-passing interface for building +// length-prefixed byte sequences. Builder methods for length-prefixed +// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation +// supplied to them. The child builder passed to the continuation can be used +// to build the content of the length-prefixed sequence. For example: +// +// parent := cryptobyte.NewBuilder() +// parent.AddUint8LengthPrefixed(func (child *Builder) { +// child.AddUint8(42) +// child.AddUint8LengthPrefixed(func (grandchild *Builder) { +// grandchild.AddUint8(5) +// }) +// }) +// +// It is an error to write more bytes to the child than allowed by the reserved +// length prefix. After the continuation returns, the child must be considered +// invalid, i.e. users must not store any copies or references of the child +// that outlive the continuation. +// +// If the continuation panics with a value of type BuildError then the inner +// error will be returned as the error from Bytes. If the child panics +// otherwise then Bytes will repanic with the same value. +type BuilderContinuation func(child *Builder) + +// BuildError wraps an error. If a BuilderContinuation panics with this value, +// the panic will be recovered and the inner error will be returned from +// Builder.Bytes. +type BuildError struct { + Err error +} + +// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence. +func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) { + b.addLengthPrefixed(1, false, f) +} + +// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence. +func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) { + b.addLengthPrefixed(2, false, f) +} + +// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence. +func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) { + b.addLengthPrefixed(3, false, f) +} + +// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence. +func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) { + b.addLengthPrefixed(4, false, f) +} + +func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) { + if !*b.inContinuation { + *b.inContinuation = true + + defer func() { + *b.inContinuation = false + + r := recover() + if r == nil { + return + } + + if buildError, ok := r.(BuildError); ok { + b.err = buildError.Err + } else { + panic(r) + } + }() + } + + f(arg) +} + +func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) { + // Subsequent writes can be ignored if the builder has encountered an error. + if b.err != nil { + return + } + + offset := len(b.result) + b.add(make([]byte, lenLen)...) + + if b.inContinuation == nil { + b.inContinuation = new(bool) + } + + b.child = &Builder{ + result: b.result, + fixedSize: b.fixedSize, + offset: offset, + pendingLenLen: lenLen, + pendingIsASN1: isASN1, + inContinuation: b.inContinuation, + } + + b.callContinuation(f, b.child) + b.flushChild() + if b.child != nil { + panic("cryptobyte: internal error") + } +} + +func (b *Builder) flushChild() { + if b.child == nil { + return + } + b.child.flushChild() + child := b.child + b.child = nil + + if child.err != nil { + b.err = child.err + return + } + + length := len(child.result) - child.pendingLenLen - child.offset + + if length < 0 { + panic("cryptobyte: internal error") // result unexpectedly shrunk + } + + if child.pendingIsASN1 { + // For ASN.1, we reserved a single byte for the length. If that turned out + // to be incorrect, we have to move the contents along in order to make + // space. + if child.pendingLenLen != 1 { + panic("cryptobyte: internal error") + } + var lenLen, lenByte uint8 + if int64(length) > 0xfffffffe { + b.err = errors.New("pending ASN.1 child too long") + return + } else if length > 0xffffff { + lenLen = 5 + lenByte = 0x80 | 4 + } else if length > 0xffff { + lenLen = 4 + lenByte = 0x80 | 3 + } else if length > 0xff { + lenLen = 3 + lenByte = 0x80 | 2 + } else if length > 0x7f { + lenLen = 2 + lenByte = 0x80 | 1 + } else { + lenLen = 1 + lenByte = uint8(length) + length = 0 + } + + // Insert the initial length byte, make space for successive length bytes, + // and adjust the offset. + child.result[child.offset] = lenByte + extraBytes := int(lenLen - 1) + if extraBytes != 0 { + child.add(make([]byte, extraBytes)...) + childStart := child.offset + child.pendingLenLen + copy(child.result[childStart+extraBytes:], child.result[childStart:]) + } + child.offset++ + child.pendingLenLen = extraBytes + } + + l := length + for i := child.pendingLenLen - 1; i >= 0; i-- { + child.result[child.offset+i] = uint8(l) + l >>= 8 + } + if l != 0 { + b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen) + return + } + + if b.fixedSize && &b.result[0] != &child.result[0] { + panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer") + } + + b.result = child.result +} + +func (b *Builder) add(bytes ...byte) { + if b.err != nil { + return + } + if b.child != nil { + panic("cryptobyte: attempted write while child is pending") + } + if len(b.result)+len(bytes) < len(bytes) { + b.err = errors.New("cryptobyte: length overflow") + } + if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) { + b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer") + return + } + b.result = append(b.result, bytes...) +} + +// Unwrite rolls back non-negative n bytes written directly to the Builder. +// An attempt by a child builder passed to a continuation to unwrite bytes +// from its parent will panic. +func (b *Builder) Unwrite(n int) { + if b.err != nil { + return + } + if b.child != nil { + panic("cryptobyte: attempted unwrite while child is pending") + } + length := len(b.result) - b.pendingLenLen - b.offset + if length < 0 { + panic("cryptobyte: internal error") + } + if n < 0 { + panic("cryptobyte: attempted to unwrite negative number of bytes") + } + if n > length { + panic("cryptobyte: attempted to unwrite more than was written") + } + b.result = b.result[:len(b.result)-n] +} + +// A MarshalingValue marshals itself into a Builder. +type MarshalingValue interface { + // Marshal is called by Builder.AddValue. It receives a pointer to a builder + // to marshal itself into. It may return an error that occurred during + // marshaling, such as unset or invalid values. + Marshal(b *Builder) error +} + +// AddValue calls Marshal on v, passing a pointer to the builder to append to. +// If Marshal returns an error, it is set on the Builder so that subsequent +// appends don't have an effect. +func (b *Builder) AddValue(v MarshalingValue) { + err := v.Marshal(b) + if err != nil { + b.err = err + } +} diff --git a/vendor/golang.org/x/crypto/cryptobyte/string.go b/vendor/golang.org/x/crypto/cryptobyte/string.go new file mode 100644 index 00000000000..10692a8a315 --- /dev/null +++ b/vendor/golang.org/x/crypto/cryptobyte/string.go @@ -0,0 +1,183 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cryptobyte contains types that help with parsing and constructing +// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage +// contains useful ASN.1 constants.) +// +// The String type is for parsing. It wraps a []byte slice and provides helper +// functions for consuming structures, value by value. +// +// The Builder type is for constructing messages. It providers helper functions +// for appending values and also for appending length-prefixed submessages – +// without having to worry about calculating the length prefix ahead of time. +// +// See the documentation and examples for the Builder and String types to get +// started. +package cryptobyte // import "golang.org/x/crypto/cryptobyte" + +// String represents a string of bytes. It provides methods for parsing +// fixed-length and length-prefixed values from it. +type String []byte + +// read advances a String by n bytes and returns them. If less than n bytes +// remain, it returns nil. +func (s *String) read(n int) []byte { + if len(*s) < n || n < 0 { + return nil + } + v := (*s)[:n] + *s = (*s)[n:] + return v +} + +// Skip advances the String by n byte and reports whether it was successful. +func (s *String) Skip(n int) bool { + return s.read(n) != nil +} + +// ReadUint8 decodes an 8-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint8(out *uint8) bool { + v := s.read(1) + if v == nil { + return false + } + *out = uint8(v[0]) + return true +} + +// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint16(out *uint16) bool { + v := s.read(2) + if v == nil { + return false + } + *out = uint16(v[0])<<8 | uint16(v[1]) + return true +} + +// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint24(out *uint32) bool { + v := s.read(3) + if v == nil { + return false + } + *out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2]) + return true +} + +// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint32(out *uint32) bool { + v := s.read(4) + if v == nil { + return false + } + *out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3]) + return true +} + +// ReadUint48 decodes a big-endian, 48-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint48(out *uint64) bool { + v := s.read(6) + if v == nil { + return false + } + *out = uint64(v[0])<<40 | uint64(v[1])<<32 | uint64(v[2])<<24 | uint64(v[3])<<16 | uint64(v[4])<<8 | uint64(v[5]) + return true +} + +// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint64(out *uint64) bool { + v := s.read(8) + if v == nil { + return false + } + *out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7]) + return true +} + +func (s *String) readUnsigned(out *uint32, length int) bool { + v := s.read(length) + if v == nil { + return false + } + var result uint32 + for i := 0; i < length; i++ { + result <<= 8 + result |= uint32(v[i]) + } + *out = result + return true +} + +func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool { + lenBytes := s.read(lenLen) + if lenBytes == nil { + return false + } + var length uint32 + for _, b := range lenBytes { + length = length << 8 + length = length | uint32(b) + } + v := s.read(int(length)) + if v == nil { + return false + } + *outChild = v + return true +} + +// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value +// into out and advances over it. It reports whether the read was successful. +func (s *String) ReadUint8LengthPrefixed(out *String) bool { + return s.readLengthPrefixed(1, out) +} + +// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit +// length-prefixed value into out and advances over it. It reports whether the +// read was successful. +func (s *String) ReadUint16LengthPrefixed(out *String) bool { + return s.readLengthPrefixed(2, out) +} + +// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit +// length-prefixed value into out and advances over it. It reports whether +// the read was successful. +func (s *String) ReadUint24LengthPrefixed(out *String) bool { + return s.readLengthPrefixed(3, out) +} + +// ReadBytes reads n bytes into out and advances over them. It reports +// whether the read was successful. +func (s *String) ReadBytes(out *[]byte, n int) bool { + v := s.read(n) + if v == nil { + return false + } + *out = v + return true +} + +// CopyBytes copies len(out) bytes into out and advances over them. It reports +// whether the copy operation was successful +func (s *String) CopyBytes(out []byte) bool { + n := len(out) + v := s.read(n) + if v == nil { + return false + } + return copy(out, v) == n +} + +// Empty reports whether the string does not contain any bytes. +func (s String) Empty() bool { + return len(s) == 0 +} diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go new file mode 100644 index 00000000000..dda3f143bec --- /dev/null +++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go @@ -0,0 +1,93 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation +// Function (HKDF) as defined in RFC 5869. +// +// HKDF is a cryptographic key derivation function (KDF) with the goal of +// expanding limited input keying material into one or more cryptographically +// strong secret keys. +package hkdf // import "golang.org/x/crypto/hkdf" + +import ( + "crypto/hmac" + "errors" + "hash" + "io" +) + +// Extract generates a pseudorandom key for use with Expand from an input secret +// and an optional independent salt. +// +// Only use this function if you need to reuse the extracted key with multiple +// Expand invocations and different context values. Most common scenarios, +// including the generation of multiple keys, should use New instead. +func Extract(hash func() hash.Hash, secret, salt []byte) []byte { + if salt == nil { + salt = make([]byte, hash().Size()) + } + extractor := hmac.New(hash, salt) + extractor.Write(secret) + return extractor.Sum(nil) +} + +type hkdf struct { + expander hash.Hash + size int + + info []byte + counter byte + + prev []byte + buf []byte +} + +func (f *hkdf) Read(p []byte) (int, error) { + // Check whether enough data can be generated + need := len(p) + remains := len(f.buf) + int(255-f.counter+1)*f.size + if remains < need { + return 0, errors.New("hkdf: entropy limit reached") + } + // Read any leftover from the buffer + n := copy(p, f.buf) + p = p[n:] + + // Fill the rest of the buffer + for len(p) > 0 { + f.expander.Reset() + f.expander.Write(f.prev) + f.expander.Write(f.info) + f.expander.Write([]byte{f.counter}) + f.prev = f.expander.Sum(f.prev[:0]) + f.counter++ + + // Copy the new batch into p + f.buf = f.prev + n = copy(p, f.buf) + p = p[n:] + } + // Save leftovers for next run + f.buf = f.buf[n:] + + return need, nil +} + +// Expand returns a Reader, from which keys can be read, using the given +// pseudorandom key and optional context info, skipping the extraction step. +// +// The pseudorandomKey should have been generated by Extract, or be a uniformly +// random or pseudorandom cryptographically strong key. See RFC 5869, Section +// 3.3. Most common scenarios will want to use New instead. +func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader { + expander := hmac.New(hash, pseudorandomKey) + return &hkdf{expander, expander.Size(), info, 1, nil, nil} +} + +// New returns a Reader, from which keys can be read, using the given hash, +// secret, salt and context info. Salt and info can be nil. +func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader { + prk := Extract(hash, secret, salt) + return Expand(hash, prk, info) +} diff --git a/vendor/golang.org/x/crypto/internal/alias/alias.go b/vendor/golang.org/x/crypto/internal/alias/alias.go new file mode 100644 index 00000000000..69c17f822b9 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/alias/alias.go @@ -0,0 +1,32 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !purego +// +build !purego + +// Package alias implements memory aliasing tests. +package alias + +import "unsafe" + +// AnyOverlap reports whether x and y share memory at any (not necessarily +// corresponding) index. The memory beyond the slice length is ignored. +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && + uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) +} + +// InexactOverlap reports whether x and y share memory at any non-corresponding +// index. The memory beyond the slice length is ignored. Note that x and y can +// have different lengths and still not have any inexact overlap. +// +// InexactOverlap can be used to implement the requirements of the crypto/cipher +// AEAD, Block, BlockMode and Stream interfaces. +func InexactOverlap(x, y []byte) bool { + if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { + return false + } + return AnyOverlap(x, y) +} diff --git a/vendor/golang.org/x/crypto/internal/alias/alias_purego.go b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go new file mode 100644 index 00000000000..4775b0a4384 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/alias/alias_purego.go @@ -0,0 +1,35 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build purego +// +build purego + +// Package alias implements memory aliasing tests. +package alias + +// This is the Google App Engine standard variant based on reflect +// because the unsafe package and cgo are disallowed. + +import "reflect" + +// AnyOverlap reports whether x and y share memory at any (not necessarily +// corresponding) index. The memory beyond the slice length is ignored. +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() && + reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer() +} + +// InexactOverlap reports whether x and y share memory at any non-corresponding +// index. The memory beyond the slice length is ignored. Note that x and y can +// have different lengths and still not have any inexact overlap. +// +// InexactOverlap can be used to implement the requirements of the crypto/cipher +// AEAD, Block, BlockMode and Stream interfaces. +func InexactOverlap(x, y []byte) bool { + if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { + return false + } + return AnyOverlap(x, y) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go new file mode 100644 index 00000000000..45b5c966b2b --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go @@ -0,0 +1,40 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.13 +// +build !go1.13 + +package poly1305 + +// Generic fallbacks for the math/bits intrinsics, copied from +// src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had +// variable time fallbacks until Go 1.13. + +func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { + sum = x + y + carry + carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 + return +} + +func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 + return +} + +func bitsMul64(x, y uint64) (hi, lo uint64) { + const mask32 = 1<<32 - 1 + x0 := x & mask32 + x1 := x >> 32 + y0 := y & mask32 + y1 := y >> 32 + w0 := x0 * y0 + t := x1*y0 + w0>>32 + w1 := t & mask32 + w2 := t >> 32 + w1 += x0 * y1 + hi = x1*y1 + w2 + w1>>32 + lo = x * y + return +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go new file mode 100644 index 00000000000..ed52b3418ab --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.13 +// +build go1.13 + +package poly1305 + +import "math/bits" + +func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { + return bits.Add64(x, y, carry) +} + +func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { + return bits.Sub64(x, y, borrow) +} + +func bitsMul64(x, y uint64) (hi, lo uint64) { + return bits.Mul64(x, y) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go new file mode 100644 index 00000000000..f184b67d98d --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go @@ -0,0 +1,10 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego +// +build !amd64,!ppc64le,!s390x !gc purego + +package poly1305 + +type mac struct{ macGeneric } diff --git a/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go new file mode 100644 index 00000000000..4aaea810a26 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go @@ -0,0 +1,99 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package poly1305 implements Poly1305 one-time message authentication code as +// specified in https://cr.yp.to/mac/poly1305-20050329.pdf. +// +// Poly1305 is a fast, one-time authentication function. It is infeasible for an +// attacker to generate an authenticator for a message without the key. However, a +// key must only be used for a single message. Authenticating two different +// messages with the same key allows an attacker to forge authenticators for other +// messages with the same key. +// +// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was +// used with a fixed key in order to generate one-time keys from an nonce. +// However, in this package AES isn't used and the one-time key is specified +// directly. +package poly1305 + +import "crypto/subtle" + +// TagSize is the size, in bytes, of a poly1305 authenticator. +const TagSize = 16 + +// Sum generates an authenticator for msg using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + h := New(key) + h.Write(m) + h.Sum(out[:0]) +} + +// Verify returns true if mac is a valid authenticator for m with the given key. +func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { + var tmp [16]byte + Sum(&tmp, m, key) + return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 +} + +// New returns a new MAC computing an authentication +// tag of all data written to it with the given key. +// This allows writing the message progressively instead +// of passing it as a single slice. Common users should use +// the Sum function instead. +// +// The key must be unique for each message, as authenticating +// two different messages with the same key allows an attacker +// to forge messages at will. +func New(key *[32]byte) *MAC { + m := &MAC{} + initialize(key, &m.macState) + return m +} + +// MAC is an io.Writer computing an authentication tag +// of the data written to it. +// +// MAC cannot be used like common hash.Hash implementations, +// because using a poly1305 key twice breaks its security. +// Therefore writing data to a running MAC after calling +// Sum or Verify causes it to panic. +type MAC struct { + mac // platform-dependent implementation + + finalized bool +} + +// Size returns the number of bytes Sum will return. +func (h *MAC) Size() int { return TagSize } + +// Write adds more data to the running message authentication code. +// It never returns an error. +// +// It must not be called after the first call of Sum or Verify. +func (h *MAC) Write(p []byte) (n int, err error) { + if h.finalized { + panic("poly1305: write to MAC after Sum or Verify") + } + return h.mac.Write(p) +} + +// Sum computes the authenticator of all data written to the +// message authentication code. +func (h *MAC) Sum(b []byte) []byte { + var mac [TagSize]byte + h.mac.Sum(&mac) + h.finalized = true + return append(b, mac[:]...) +} + +// Verify returns whether the authenticator of all data written to +// the message authentication code matches the expected value. +func (h *MAC) Verify(expected []byte) bool { + var mac [TagSize]byte + h.mac.Sum(&mac) + h.finalized = true + return subtle.ConstantTimeCompare(expected, mac[:]) == 1 +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go new file mode 100644 index 00000000000..6d522333f29 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go @@ -0,0 +1,48 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package poly1305 + +//go:noescape +func update(state *macState, msg []byte) + +// mac is a wrapper for macGeneric that redirects calls that would have gone to +// updateGeneric to update. +// +// Its Write and Sum methods are otherwise identical to the macGeneric ones, but +// using function pointers would carry a major performance cost. +type mac struct{ macGeneric } + +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) + if h.offset > 0 { + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil + } + p = p[n:] + h.offset = 0 + update(&h.macState, h.buffer[:]) + } + if n := len(p) - (len(p) % TagSize); n > 0 { + update(&h.macState, p[:n]) + p = p[n:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return nn, nil +} + +func (h *mac) Sum(out *[16]byte) { + state := h.macState + if h.offset > 0 { + update(&state, h.buffer[:h.offset]) + } + finalize(out, &state.h, &state.s) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s new file mode 100644 index 00000000000..1d74f0f8818 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s @@ -0,0 +1,109 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" + +#define POLY1305_ADD(msg, h0, h1, h2) \ + ADDQ 0(msg), h0; \ + ADCQ 8(msg), h1; \ + ADCQ $1, h2; \ + LEAQ 16(msg), msg + +#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \ + MOVQ r0, AX; \ + MULQ h0; \ + MOVQ AX, t0; \ + MOVQ DX, t1; \ + MOVQ r0, AX; \ + MULQ h1; \ + ADDQ AX, t1; \ + ADCQ $0, DX; \ + MOVQ r0, t2; \ + IMULQ h2, t2; \ + ADDQ DX, t2; \ + \ + MOVQ r1, AX; \ + MULQ h0; \ + ADDQ AX, t1; \ + ADCQ $0, DX; \ + MOVQ DX, h0; \ + MOVQ r1, t3; \ + IMULQ h2, t3; \ + MOVQ r1, AX; \ + MULQ h1; \ + ADDQ AX, t2; \ + ADCQ DX, t3; \ + ADDQ h0, t2; \ + ADCQ $0, t3; \ + \ + MOVQ t0, h0; \ + MOVQ t1, h1; \ + MOVQ t2, h2; \ + ANDQ $3, h2; \ + MOVQ t2, t0; \ + ANDQ $0xFFFFFFFFFFFFFFFC, t0; \ + ADDQ t0, h0; \ + ADCQ t3, h1; \ + ADCQ $0, h2; \ + SHRQ $2, t3, t2; \ + SHRQ $2, t3; \ + ADDQ t2, h0; \ + ADCQ t3, h1; \ + ADCQ $0, h2 + +// func update(state *[7]uint64, msg []byte) +TEXT ·update(SB), $0-32 + MOVQ state+0(FP), DI + MOVQ msg_base+8(FP), SI + MOVQ msg_len+16(FP), R15 + + MOVQ 0(DI), R8 // h0 + MOVQ 8(DI), R9 // h1 + MOVQ 16(DI), R10 // h2 + MOVQ 24(DI), R11 // r0 + MOVQ 32(DI), R12 // r1 + + CMPQ R15, $16 + JB bytes_between_0_and_15 + +loop: + POLY1305_ADD(SI, R8, R9, R10) + +multiply: + POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14) + SUBQ $16, R15 + CMPQ R15, $16 + JAE loop + +bytes_between_0_and_15: + TESTQ R15, R15 + JZ done + MOVQ $1, BX + XORQ CX, CX + XORQ R13, R13 + ADDQ R15, SI + +flush_buffer: + SHLQ $8, BX, CX + SHLQ $8, BX + MOVB -1(SI), R13 + XORQ R13, BX + DECQ SI + DECQ R15 + JNZ flush_buffer + + ADDQ BX, R8 + ADCQ CX, R9 + ADCQ $0, R10 + MOVQ $16, R15 + JMP multiply + +done: + MOVQ R8, 0(DI) + MOVQ R9, 8(DI) + MOVQ R10, 16(DI) + RET diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go new file mode 100644 index 00000000000..e041da5ea3e --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go @@ -0,0 +1,309 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file provides the generic implementation of Sum and MAC. Other files +// might provide optimized assembly implementations of some of this code. + +package poly1305 + +import "encoding/binary" + +// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag +// for a 64 bytes message is approximately +// +// s + m[0:16] * r⁴ + m[16:32] * r³ + m[32:48] * r² + m[48:64] * r mod 2¹³⁰ - 5 +// +// for some secret r and s. It can be computed sequentially like +// +// for len(msg) > 0: +// h += read(msg, 16) +// h *= r +// h %= 2¹³⁰ - 5 +// return h + s +// +// All the complexity is about doing performant constant-time math on numbers +// larger than any available numeric type. + +func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) { + h := newMACGeneric(key) + h.Write(msg) + h.Sum(out) +} + +func newMACGeneric(key *[32]byte) macGeneric { + m := macGeneric{} + initialize(key, &m.macState) + return m +} + +// macState holds numbers in saturated 64-bit little-endian limbs. That is, +// the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸. +type macState struct { + // h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but + // can grow larger during and after rounds. It must, however, remain below + // 2 * (2¹³⁰ - 5). + h [3]uint64 + // r and s are the private key components. + r [2]uint64 + s [2]uint64 +} + +type macGeneric struct { + macState + + buffer [TagSize]byte + offset int +} + +// Write splits the incoming message into TagSize chunks, and passes them to +// update. It buffers incomplete chunks. +func (h *macGeneric) Write(p []byte) (int, error) { + nn := len(p) + if h.offset > 0 { + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil + } + p = p[n:] + h.offset = 0 + updateGeneric(&h.macState, h.buffer[:]) + } + if n := len(p) - (len(p) % TagSize); n > 0 { + updateGeneric(&h.macState, p[:n]) + p = p[n:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return nn, nil +} + +// Sum flushes the last incomplete chunk from the buffer, if any, and generates +// the MAC output. It does not modify its state, in order to allow for multiple +// calls to Sum, even if no Write is allowed after Sum. +func (h *macGeneric) Sum(out *[TagSize]byte) { + state := h.macState + if h.offset > 0 { + updateGeneric(&state, h.buffer[:h.offset]) + } + finalize(out, &state.h, &state.s) +} + +// [rMask0, rMask1] is the specified Poly1305 clamping mask in little-endian. It +// clears some bits of the secret coefficient to make it possible to implement +// multiplication more efficiently. +const ( + rMask0 = 0x0FFFFFFC0FFFFFFF + rMask1 = 0x0FFFFFFC0FFFFFFC +) + +// initialize loads the 256-bit key into the two 128-bit secret values r and s. +func initialize(key *[32]byte, m *macState) { + m.r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0 + m.r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1 + m.s[0] = binary.LittleEndian.Uint64(key[16:24]) + m.s[1] = binary.LittleEndian.Uint64(key[24:32]) +} + +// uint128 holds a 128-bit number as two 64-bit limbs, for use with the +// bits.Mul64 and bits.Add64 intrinsics. +type uint128 struct { + lo, hi uint64 +} + +func mul64(a, b uint64) uint128 { + hi, lo := bitsMul64(a, b) + return uint128{lo, hi} +} + +func add128(a, b uint128) uint128 { + lo, c := bitsAdd64(a.lo, b.lo, 0) + hi, c := bitsAdd64(a.hi, b.hi, c) + if c != 0 { + panic("poly1305: unexpected overflow") + } + return uint128{lo, hi} +} + +func shiftRightBy2(a uint128) uint128 { + a.lo = a.lo>>2 | (a.hi&3)<<62 + a.hi = a.hi >> 2 + return a +} + +// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of +// 128 bits of message, it computes +// +// h₊ = (h + m) * r mod 2¹³⁰ - 5 +// +// If the msg length is not a multiple of TagSize, it assumes the last +// incomplete chunk is the final one. +func updateGeneric(state *macState, msg []byte) { + h0, h1, h2 := state.h[0], state.h[1], state.h[2] + r0, r1 := state.r[0], state.r[1] + + for len(msg) > 0 { + var c uint64 + + // For the first step, h + m, we use a chain of bits.Add64 intrinsics. + // The resulting value of h might exceed 2¹³⁰ - 5, but will be partially + // reduced at the end of the multiplication below. + // + // The spec requires us to set a bit just above the message size, not to + // hide leading zeroes. For full chunks, that's 1 << 128, so we can just + // add 1 to the most significant (2¹²⁸) limb, h2. + if len(msg) >= TagSize { + h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0) + h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(msg[8:16]), c) + h2 += c + 1 + + msg = msg[TagSize:] + } else { + var buf [TagSize]byte + copy(buf[:], msg) + buf[len(msg)] = 1 + + h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0) + h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(buf[8:16]), c) + h2 += c + + msg = nil + } + + // Multiplication of big number limbs is similar to elementary school + // columnar multiplication. Instead of digits, there are 64-bit limbs. + // + // We are multiplying a 3 limbs number, h, by a 2 limbs number, r. + // + // h2 h1 h0 x + // r1 r0 = + // ---------------- + // h2r0 h1r0 h0r0 <-- individual 128-bit products + // + h2r1 h1r1 h0r1 + // ------------------------ + // m3 m2 m1 m0 <-- result in 128-bit overlapping limbs + // ------------------------ + // m3.hi m2.hi m1.hi m0.hi <-- carry propagation + // + m3.lo m2.lo m1.lo m0.lo + // ------------------------------- + // t4 t3 t2 t1 t0 <-- final result in 64-bit limbs + // + // The main difference from pen-and-paper multiplication is that we do + // carry propagation in a separate step, as if we wrote two digit sums + // at first (the 128-bit limbs), and then carried the tens all at once. + + h0r0 := mul64(h0, r0) + h1r0 := mul64(h1, r0) + h2r0 := mul64(h2, r0) + h0r1 := mul64(h0, r1) + h1r1 := mul64(h1, r1) + h2r1 := mul64(h2, r1) + + // Since h2 is known to be at most 7 (5 + 1 + 1), and r0 and r1 have their + // top 4 bits cleared by rMask{0,1}, we know that their product is not going + // to overflow 64 bits, so we can ignore the high part of the products. + // + // This also means that the product doesn't have a fifth limb (t4). + if h2r0.hi != 0 { + panic("poly1305: unexpected overflow") + } + if h2r1.hi != 0 { + panic("poly1305: unexpected overflow") + } + + m0 := h0r0 + m1 := add128(h1r0, h0r1) // These two additions don't overflow thanks again + m2 := add128(h2r0, h1r1) // to the 4 masked bits at the top of r0 and r1. + m3 := h2r1 + + t0 := m0.lo + t1, c := bitsAdd64(m1.lo, m0.hi, 0) + t2, c := bitsAdd64(m2.lo, m1.hi, c) + t3, _ := bitsAdd64(m3.lo, m2.hi, c) + + // Now we have the result as 4 64-bit limbs, and we need to reduce it + // modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do + // a cheap partial reduction according to the reduction identity + // + // c * 2¹³⁰ + n = c * 5 + n mod 2¹³⁰ - 5 + // + // because 2¹³⁰ = 5 mod 2¹³⁰ - 5. Partial reduction since the result is + // likely to be larger than 2¹³⁰ - 5, but still small enough to fit the + // assumptions we make about h in the rest of the code. + // + // See also https://speakerdeck.com/gtank/engineering-prime-numbers?slide=23 + + // We split the final result at the 2¹³⁰ mark into h and cc, the carry. + // Note that the carry bits are effectively shifted left by 2, in other + // words, cc = c * 4 for the c in the reduction identity. + h0, h1, h2 = t0, t1, t2&maskLow2Bits + cc := uint128{t2 & maskNotLow2Bits, t3} + + // To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c. + + h0, c = bitsAdd64(h0, cc.lo, 0) + h1, c = bitsAdd64(h1, cc.hi, c) + h2 += c + + cc = shiftRightBy2(cc) + + h0, c = bitsAdd64(h0, cc.lo, 0) + h1, c = bitsAdd64(h1, cc.hi, c) + h2 += c + + // h2 is at most 3 + 1 + 1 = 5, making the whole of h at most + // + // 5 * 2¹²⁸ + (2¹²⁸ - 1) = 6 * 2¹²⁸ - 1 + } + + state.h[0], state.h[1], state.h[2] = h0, h1, h2 +} + +const ( + maskLow2Bits uint64 = 0x0000000000000003 + maskNotLow2Bits uint64 = ^maskLow2Bits +) + +// select64 returns x if v == 1 and y if v == 0, in constant time. +func select64(v, x, y uint64) uint64 { return ^(v-1)&x | (v-1)&y } + +// [p0, p1, p2] is 2¹³⁰ - 5 in little endian order. +const ( + p0 = 0xFFFFFFFFFFFFFFFB + p1 = 0xFFFFFFFFFFFFFFFF + p2 = 0x0000000000000003 +) + +// finalize completes the modular reduction of h and computes +// +// out = h + s mod 2¹²⁸ +func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) { + h0, h1, h2 := h[0], h[1], h[2] + + // After the partial reduction in updateGeneric, h might be more than + // 2¹³⁰ - 5, but will be less than 2 * (2¹³⁰ - 5). To complete the reduction + // in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the + // result if the subtraction underflows, and t otherwise. + + hMinusP0, b := bitsSub64(h0, p0, 0) + hMinusP1, b := bitsSub64(h1, p1, b) + _, b = bitsSub64(h2, p2, b) + + // h = h if h < p else h - p + h0 = select64(b, h0, hMinusP0) + h1 = select64(b, h1, hMinusP1) + + // Finally, we compute the last Poly1305 step + // + // tag = h + s mod 2¹²⁸ + // + // by just doing a wide addition with the 128 low bits of h and discarding + // the overflow. + h0, c := bitsAdd64(h0, s[0], 0) + h1, _ = bitsAdd64(h1, s[1], c) + + binary.LittleEndian.PutUint64(out[0:8], h0) + binary.LittleEndian.PutUint64(out[8:16], h1) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go new file mode 100644 index 00000000000..4a069941a6e --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.go @@ -0,0 +1,48 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package poly1305 + +//go:noescape +func update(state *macState, msg []byte) + +// mac is a wrapper for macGeneric that redirects calls that would have gone to +// updateGeneric to update. +// +// Its Write and Sum methods are otherwise identical to the macGeneric ones, but +// using function pointers would carry a major performance cost. +type mac struct{ macGeneric } + +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) + if h.offset > 0 { + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil + } + p = p[n:] + h.offset = 0 + update(&h.macState, h.buffer[:]) + } + if n := len(p) - (len(p) % TagSize); n > 0 { + update(&h.macState, p[:n]) + p = p[n:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return nn, nil +} + +func (h *mac) Sum(out *[16]byte) { + state := h.macState + if h.offset > 0 { + update(&state, h.buffer[:h.offset]) + } + finalize(out, &state.h, &state.s) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s new file mode 100644 index 00000000000..58422aad230 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s @@ -0,0 +1,182 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" + +// This was ported from the amd64 implementation. + +#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \ + MOVD (msg), t0; \ + MOVD 8(msg), t1; \ + MOVD $1, t2; \ + ADDC t0, h0, h0; \ + ADDE t1, h1, h1; \ + ADDE t2, h2; \ + ADD $16, msg + +#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ + MULLD r0, h0, t0; \ + MULLD r0, h1, t4; \ + MULHDU r0, h0, t1; \ + MULHDU r0, h1, t5; \ + ADDC t4, t1, t1; \ + MULLD r0, h2, t2; \ + ADDZE t5; \ + MULHDU r1, h0, t4; \ + MULLD r1, h0, h0; \ + ADD t5, t2, t2; \ + ADDC h0, t1, t1; \ + MULLD h2, r1, t3; \ + ADDZE t4, h0; \ + MULHDU r1, h1, t5; \ + MULLD r1, h1, t4; \ + ADDC t4, t2, t2; \ + ADDE t5, t3, t3; \ + ADDC h0, t2, t2; \ + MOVD $-4, t4; \ + MOVD t0, h0; \ + MOVD t1, h1; \ + ADDZE t3; \ + ANDCC $3, t2, h2; \ + AND t2, t4, t0; \ + ADDC t0, h0, h0; \ + ADDE t3, h1, h1; \ + SLD $62, t3, t4; \ + SRD $2, t2; \ + ADDZE h2; \ + OR t4, t2, t2; \ + SRD $2, t3; \ + ADDC t2, h0, h0; \ + ADDE t3, h1, h1; \ + ADDZE h2 + +DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF +DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC +GLOBL ·poly1305Mask<>(SB), RODATA, $16 + +// func update(state *[7]uint64, msg []byte) +TEXT ·update(SB), $0-32 + MOVD state+0(FP), R3 + MOVD msg_base+8(FP), R4 + MOVD msg_len+16(FP), R5 + + MOVD 0(R3), R8 // h0 + MOVD 8(R3), R9 // h1 + MOVD 16(R3), R10 // h2 + MOVD 24(R3), R11 // r0 + MOVD 32(R3), R12 // r1 + + CMP R5, $16 + BLT bytes_between_0_and_15 + +loop: + POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) + +multiply: + POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) + ADD $-16, R5 + CMP R5, $16 + BGE loop + +bytes_between_0_and_15: + CMP R5, $0 + BEQ done + MOVD $0, R16 // h0 + MOVD $0, R17 // h1 + +flush_buffer: + CMP R5, $8 + BLE just1 + + MOVD $8, R21 + SUB R21, R5, R21 + + // Greater than 8 -- load the rightmost remaining bytes in msg + // and put into R17 (h1) + MOVD (R4)(R21), R17 + MOVD $16, R22 + + // Find the offset to those bytes + SUB R5, R22, R22 + SLD $3, R22 + + // Shift to get only the bytes in msg + SRD R22, R17, R17 + + // Put 1 at high end + MOVD $1, R23 + SLD $3, R21 + SLD R21, R23, R23 + OR R23, R17, R17 + + // Remainder is 8 + MOVD $8, R5 + +just1: + CMP R5, $8 + BLT less8 + + // Exactly 8 + MOVD (R4), R16 + + CMP R17, $0 + + // Check if we've already set R17; if not + // set 1 to indicate end of msg. + BNE carry + MOVD $1, R17 + BR carry + +less8: + MOVD $0, R16 // h0 + MOVD $0, R22 // shift count + CMP R5, $4 + BLT less4 + MOVWZ (R4), R16 + ADD $4, R4 + ADD $-4, R5 + MOVD $32, R22 + +less4: + CMP R5, $2 + BLT less2 + MOVHZ (R4), R21 + SLD R22, R21, R21 + OR R16, R21, R16 + ADD $16, R22 + ADD $-2, R5 + ADD $2, R4 + +less2: + CMP R5, $0 + BEQ insert1 + MOVBZ (R4), R21 + SLD R22, R21, R21 + OR R16, R21, R16 + ADD $8, R22 + +insert1: + // Insert 1 at end of msg + MOVD $1, R21 + SLD R22, R21, R21 + OR R16, R21, R16 + +carry: + // Add new values to h0, h1, h2 + ADDC R16, R8 + ADDE R17, R9 + ADDZE R10, R10 + MOVD $16, R5 + ADD R5, R4 + BR multiply + +done: + // Save h0, h1, h2 in state + MOVD R8, 0(R3) + MOVD R9, 8(R3) + MOVD R10, 16(R3) + RET diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go new file mode 100644 index 00000000000..ec959668896 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go @@ -0,0 +1,77 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +package poly1305 + +import ( + "golang.org/x/sys/cpu" +) + +// updateVX is an assembly implementation of Poly1305 that uses vector +// instructions. It must only be called if the vector facility (vx) is +// available. +// +//go:noescape +func updateVX(state *macState, msg []byte) + +// mac is a replacement for macGeneric that uses a larger buffer and redirects +// calls that would have gone to updateGeneric to updateVX if the vector +// facility is installed. +// +// A larger buffer is required for good performance because the vector +// implementation has a higher fixed cost per call than the generic +// implementation. +type mac struct { + macState + + buffer [16 * TagSize]byte // size must be a multiple of block size (16) + offset int +} + +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) + if h.offset > 0 { + n := copy(h.buffer[h.offset:], p) + if h.offset+n < len(h.buffer) { + h.offset += n + return nn, nil + } + p = p[n:] + h.offset = 0 + if cpu.S390X.HasVX { + updateVX(&h.macState, h.buffer[:]) + } else { + updateGeneric(&h.macState, h.buffer[:]) + } + } + + tail := len(p) % len(h.buffer) // number of bytes to copy into buffer + body := len(p) - tail // number of bytes to process now + if body > 0 { + if cpu.S390X.HasVX { + updateVX(&h.macState, p[:body]) + } else { + updateGeneric(&h.macState, p[:body]) + } + } + h.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0 + return nn, nil +} + +func (h *mac) Sum(out *[TagSize]byte) { + state := h.macState + remainder := h.buffer[:h.offset] + + // Use the generic implementation if we have 2 or fewer blocks left + // to sum. The vector implementation has a higher startup time. + if cpu.S390X.HasVX && len(remainder) > 2*TagSize { + updateVX(&state, remainder) + } else if len(remainder) > 0 { + updateGeneric(&state, remainder) + } + finalize(out, &state.h, &state.s) +} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s new file mode 100644 index 00000000000..aa9e0494c90 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s @@ -0,0 +1,504 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego +// +build gc,!purego + +#include "textflag.h" + +// This implementation of Poly1305 uses the vector facility (vx) +// to process up to 2 blocks (32 bytes) per iteration using an +// algorithm based on the one described in: +// +// NEON crypto, Daniel J. Bernstein & Peter Schwabe +// https://cryptojedi.org/papers/neoncrypto-20120320.pdf +// +// This algorithm uses 5 26-bit limbs to represent a 130-bit +// value. These limbs are, for the most part, zero extended and +// placed into 64-bit vector register elements. Each vector +// register is 128-bits wide and so holds 2 of these elements. +// Using 26-bit limbs allows us plenty of headroom to accommodate +// accumulations before and after multiplication without +// overflowing either 32-bits (before multiplication) or 64-bits +// (after multiplication). +// +// In order to parallelise the operations required to calculate +// the sum we use two separate accumulators and then sum those +// in an extra final step. For compatibility with the generic +// implementation we perform this summation at the end of every +// updateVX call. +// +// To use two accumulators we must multiply the message blocks +// by r² rather than r. Only the final message block should be +// multiplied by r. +// +// Example: +// +// We want to calculate the sum (h) for a 64 byte message (m): +// +// h = m[0:16]r⁴ + m[16:32]r³ + m[32:48]r² + m[48:64]r +// +// To do this we split the calculation into the even indices +// and odd indices of the message. These form our SIMD 'lanes': +// +// h = m[ 0:16]r⁴ + m[32:48]r² + <- lane 0 +// m[16:32]r³ + m[48:64]r <- lane 1 +// +// To calculate this iteratively we refactor so that both lanes +// are written in terms of r² and r: +// +// h = (m[ 0:16]r² + m[32:48])r² + <- lane 0 +// (m[16:32]r² + m[48:64])r <- lane 1 +// ^ ^ +// | coefficients for second iteration +// coefficients for first iteration +// +// So in this case we would have two iterations. In the first +// both lanes are multiplied by r². In the second only the +// first lane is multiplied by r² and the second lane is +// instead multiplied by r. This gives use the odd and even +// powers of r that we need from the original equation. +// +// Notation: +// +// h - accumulator +// r - key +// m - message +// +// [a, b] - SIMD register holding two 64-bit values +// [a, b, c, d] - SIMD register holding four 32-bit values +// xᵢ[n] - limb n of variable x with bit width i +// +// Limbs are expressed in little endian order, so for 26-bit +// limbs x₂₆[4] will be the most significant limb and x₂₆[0] +// will be the least significant limb. + +// masking constants +#define MOD24 V0 // [0x0000000000ffffff, 0x0000000000ffffff] - mask low 24-bits +#define MOD26 V1 // [0x0000000003ffffff, 0x0000000003ffffff] - mask low 26-bits + +// expansion constants (see EXPAND macro) +#define EX0 V2 +#define EX1 V3 +#define EX2 V4 + +// key (r², r or 1 depending on context) +#define R_0 V5 +#define R_1 V6 +#define R_2 V7 +#define R_3 V8 +#define R_4 V9 + +// precalculated coefficients (5r², 5r or 0 depending on context) +#define R5_1 V10 +#define R5_2 V11 +#define R5_3 V12 +#define R5_4 V13 + +// message block (m) +#define M_0 V14 +#define M_1 V15 +#define M_2 V16 +#define M_3 V17 +#define M_4 V18 + +// accumulator (h) +#define H_0 V19 +#define H_1 V20 +#define H_2 V21 +#define H_3 V22 +#define H_4 V23 + +// temporary registers (for short-lived values) +#define T_0 V24 +#define T_1 V25 +#define T_2 V26 +#define T_3 V27 +#define T_4 V28 + +GLOBL ·constants<>(SB), RODATA, $0x30 +// EX0 +DATA ·constants<>+0x00(SB)/8, $0x0006050403020100 +DATA ·constants<>+0x08(SB)/8, $0x1016151413121110 +// EX1 +DATA ·constants<>+0x10(SB)/8, $0x060c0b0a09080706 +DATA ·constants<>+0x18(SB)/8, $0x161c1b1a19181716 +// EX2 +DATA ·constants<>+0x20(SB)/8, $0x0d0d0d0d0d0f0e0d +DATA ·constants<>+0x28(SB)/8, $0x1d1d1d1d1d1f1e1d + +// MULTIPLY multiplies each lane of f and g, partially reduced +// modulo 2¹³⁰ - 5. The result, h, consists of partial products +// in each lane that need to be reduced further to produce the +// final result. +// +// h₁₃₀ = (f₁₃₀g₁₃₀) % 2¹³⁰ + (5f₁₃₀g₁₃₀) / 2¹³⁰ +// +// Note that the multiplication by 5 of the high bits is +// achieved by precalculating the multiplication of four of the +// g coefficients by 5. These are g51-g54. +#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \ + VMLOF f0, g0, h0 \ + VMLOF f0, g3, h3 \ + VMLOF f0, g1, h1 \ + VMLOF f0, g4, h4 \ + VMLOF f0, g2, h2 \ + VMLOF f1, g54, T_0 \ + VMLOF f1, g2, T_3 \ + VMLOF f1, g0, T_1 \ + VMLOF f1, g3, T_4 \ + VMLOF f1, g1, T_2 \ + VMALOF f2, g53, h0, h0 \ + VMALOF f2, g1, h3, h3 \ + VMALOF f2, g54, h1, h1 \ + VMALOF f2, g2, h4, h4 \ + VMALOF f2, g0, h2, h2 \ + VMALOF f3, g52, T_0, T_0 \ + VMALOF f3, g0, T_3, T_3 \ + VMALOF f3, g53, T_1, T_1 \ + VMALOF f3, g1, T_4, T_4 \ + VMALOF f3, g54, T_2, T_2 \ + VMALOF f4, g51, h0, h0 \ + VMALOF f4, g54, h3, h3 \ + VMALOF f4, g52, h1, h1 \ + VMALOF f4, g0, h4, h4 \ + VMALOF f4, g53, h2, h2 \ + VAG T_0, h0, h0 \ + VAG T_3, h3, h3 \ + VAG T_1, h1, h1 \ + VAG T_4, h4, h4 \ + VAG T_2, h2, h2 + +// REDUCE performs the following carry operations in four +// stages, as specified in Bernstein & Schwabe: +// +// 1: h₂₆[0]->h₂₆[1] h₂₆[3]->h₂₆[4] +// 2: h₂₆[1]->h₂₆[2] h₂₆[4]->h₂₆[0] +// 3: h₂₆[0]->h₂₆[1] h₂₆[2]->h₂₆[3] +// 4: h₂₆[3]->h₂₆[4] +// +// The result is that all of the limbs are limited to 26-bits +// except for h₂₆[1] and h₂₆[4] which are limited to 27-bits. +// +// Note that although each limb is aligned at 26-bit intervals +// they may contain values that exceed 2²⁶ - 1, hence the need +// to carry the excess bits in each limb. +#define REDUCE(h0, h1, h2, h3, h4) \ + VESRLG $26, h0, T_0 \ + VESRLG $26, h3, T_1 \ + VN MOD26, h0, h0 \ + VN MOD26, h3, h3 \ + VAG T_0, h1, h1 \ + VAG T_1, h4, h4 \ + VESRLG $26, h1, T_2 \ + VESRLG $26, h4, T_3 \ + VN MOD26, h1, h1 \ + VN MOD26, h4, h4 \ + VESLG $2, T_3, T_4 \ + VAG T_3, T_4, T_4 \ + VAG T_2, h2, h2 \ + VAG T_4, h0, h0 \ + VESRLG $26, h2, T_0 \ + VESRLG $26, h0, T_1 \ + VN MOD26, h2, h2 \ + VN MOD26, h0, h0 \ + VAG T_0, h3, h3 \ + VAG T_1, h1, h1 \ + VESRLG $26, h3, T_2 \ + VN MOD26, h3, h3 \ + VAG T_2, h4, h4 + +// EXPAND splits the 128-bit little-endian values in0 and in1 +// into 26-bit big-endian limbs and places the results into +// the first and second lane of d₂₆[0:4] respectively. +// +// The EX0, EX1 and EX2 constants are arrays of byte indices +// for permutation. The permutation both reverses the bytes +// in the input and ensures the bytes are copied into the +// destination limb ready to be shifted into their final +// position. +#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \ + VPERM in0, in1, EX0, d0 \ + VPERM in0, in1, EX1, d2 \ + VPERM in0, in1, EX2, d4 \ + VESRLG $26, d0, d1 \ + VESRLG $30, d2, d3 \ + VESRLG $4, d2, d2 \ + VN MOD26, d0, d0 \ // [in0₂₆[0], in1₂₆[0]] + VN MOD26, d3, d3 \ // [in0₂₆[3], in1₂₆[3]] + VN MOD26, d1, d1 \ // [in0₂₆[1], in1₂₆[1]] + VN MOD24, d4, d4 \ // [in0₂₆[4], in1₂₆[4]] + VN MOD26, d2, d2 // [in0₂₆[2], in1₂₆[2]] + +// func updateVX(state *macState, msg []byte) +TEXT ·updateVX(SB), NOSPLIT, $0 + MOVD state+0(FP), R1 + LMG msg+8(FP), R2, R3 // R2=msg_base, R3=msg_len + + // load EX0, EX1 and EX2 + MOVD $·constants<>(SB), R5 + VLM (R5), EX0, EX2 + + // generate masks + VGMG $(64-24), $63, MOD24 // [0x00ffffff, 0x00ffffff] + VGMG $(64-26), $63, MOD26 // [0x03ffffff, 0x03ffffff] + + // load h (accumulator) and r (key) from state + VZERO T_1 // [0, 0] + VL 0(R1), T_0 // [h₆₄[0], h₆₄[1]] + VLEG $0, 16(R1), T_1 // [h₆₄[2], 0] + VL 24(R1), T_2 // [r₆₄[0], r₆₄[1]] + VPDI $0, T_0, T_2, T_3 // [h₆₄[0], r₆₄[0]] + VPDI $5, T_0, T_2, T_4 // [h₆₄[1], r₆₄[1]] + + // unpack h and r into 26-bit limbs + // note: h₆₄[2] may have the low 3 bits set, so h₂₆[4] is a 27-bit value + VN MOD26, T_3, H_0 // [h₂₆[0], r₂₆[0]] + VZERO H_1 // [0, 0] + VZERO H_3 // [0, 0] + VGMG $(64-12-14), $(63-12), T_0 // [0x03fff000, 0x03fff000] - 26-bit mask with low 12 bits masked out + VESLG $24, T_1, T_1 // [h₆₄[2]<<24, 0] + VERIMG $-26&63, T_3, MOD26, H_1 // [h₂₆[1], r₂₆[1]] + VESRLG $+52&63, T_3, H_2 // [h₂₆[2], r₂₆[2]] - low 12 bits only + VERIMG $-14&63, T_4, MOD26, H_3 // [h₂₆[1], r₂₆[1]] + VESRLG $40, T_4, H_4 // [h₂₆[4], r₂₆[4]] - low 24 bits only + VERIMG $+12&63, T_4, T_0, H_2 // [h₂₆[2], r₂₆[2]] - complete + VO T_1, H_4, H_4 // [h₂₆[4], r₂₆[4]] - complete + + // replicate r across all 4 vector elements + VREPF $3, H_0, R_0 // [r₂₆[0], r₂₆[0], r₂₆[0], r₂₆[0]] + VREPF $3, H_1, R_1 // [r₂₆[1], r₂₆[1], r₂₆[1], r₂₆[1]] + VREPF $3, H_2, R_2 // [r₂₆[2], r₂₆[2], r₂₆[2], r₂₆[2]] + VREPF $3, H_3, R_3 // [r₂₆[3], r₂₆[3], r₂₆[3], r₂₆[3]] + VREPF $3, H_4, R_4 // [r₂₆[4], r₂₆[4], r₂₆[4], r₂₆[4]] + + // zero out lane 1 of h + VLEIG $1, $0, H_0 // [h₂₆[0], 0] + VLEIG $1, $0, H_1 // [h₂₆[1], 0] + VLEIG $1, $0, H_2 // [h₂₆[2], 0] + VLEIG $1, $0, H_3 // [h₂₆[3], 0] + VLEIG $1, $0, H_4 // [h₂₆[4], 0] + + // calculate 5r (ignore least significant limb) + VREPIF $5, T_0 + VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r₂₆[1], 5r₂₆[1], 5r₂₆[1]] + VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r₂₆[2], 5r₂₆[2], 5r₂₆[2]] + VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r₂₆[3], 5r₂₆[3], 5r₂₆[3]] + VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r₂₆[4], 5r₂₆[4], 5r₂₆[4]] + + // skip r² calculation if we are only calculating one block + CMPBLE R3, $16, skip + + // calculate r² + MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, M_0, M_1, M_2, M_3, M_4) + REDUCE(M_0, M_1, M_2, M_3, M_4) + VGBM $0x0f0f, T_0 + VERIMG $0, M_0, T_0, R_0 // [r₂₆[0], r²₂₆[0], r₂₆[0], r²₂₆[0]] + VERIMG $0, M_1, T_0, R_1 // [r₂₆[1], r²₂₆[1], r₂₆[1], r²₂₆[1]] + VERIMG $0, M_2, T_0, R_2 // [r₂₆[2], r²₂₆[2], r₂₆[2], r²₂₆[2]] + VERIMG $0, M_3, T_0, R_3 // [r₂₆[3], r²₂₆[3], r₂₆[3], r²₂₆[3]] + VERIMG $0, M_4, T_0, R_4 // [r₂₆[4], r²₂₆[4], r₂₆[4], r²₂₆[4]] + + // calculate 5r² (ignore least significant limb) + VREPIF $5, T_0 + VMLF T_0, R_1, R5_1 // [5r₂₆[1], 5r²₂₆[1], 5r₂₆[1], 5r²₂₆[1]] + VMLF T_0, R_2, R5_2 // [5r₂₆[2], 5r²₂₆[2], 5r₂₆[2], 5r²₂₆[2]] + VMLF T_0, R_3, R5_3 // [5r₂₆[3], 5r²₂₆[3], 5r₂₆[3], 5r²₂₆[3]] + VMLF T_0, R_4, R5_4 // [5r₂₆[4], 5r²₂₆[4], 5r₂₆[4], 5r²₂₆[4]] + +loop: + CMPBLE R3, $32, b2 // 2 or fewer blocks remaining, need to change key coefficients + + // load next 2 blocks from message + VLM (R2), T_0, T_1 + + // update message slice + SUB $32, R3 + MOVD $32(R2), R2 + + // unpack message blocks into 26-bit big-endian limbs + EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4) + + // add 2¹²⁸ to each message block value + VLEIB $4, $1, M_4 + VLEIB $12, $1, M_4 + +multiply: + // accumulate the incoming message + VAG H_0, M_0, M_0 + VAG H_3, M_3, M_3 + VAG H_1, M_1, M_1 + VAG H_4, M_4, M_4 + VAG H_2, M_2, M_2 + + // multiply the accumulator by the key coefficient + MULTIPLY(M_0, M_1, M_2, M_3, M_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4) + + // carry and partially reduce the partial products + REDUCE(H_0, H_1, H_2, H_3, H_4) + + CMPBNE R3, $0, loop + +finish: + // sum lane 0 and lane 1 and put the result in lane 1 + VZERO T_0 + VSUMQG H_0, T_0, H_0 + VSUMQG H_3, T_0, H_3 + VSUMQG H_1, T_0, H_1 + VSUMQG H_4, T_0, H_4 + VSUMQG H_2, T_0, H_2 + + // reduce again after summation + // TODO(mundaym): there might be a more efficient way to do this + // now that we only have 1 active lane. For example, we could + // simultaneously pack the values as we reduce them. + REDUCE(H_0, H_1, H_2, H_3, H_4) + + // carry h[1] through to h[4] so that only h[4] can exceed 2²⁶ - 1 + // TODO(mundaym): in testing this final carry was unnecessary. + // Needs a proof before it can be removed though. + VESRLG $26, H_1, T_1 + VN MOD26, H_1, H_1 + VAQ T_1, H_2, H_2 + VESRLG $26, H_2, T_2 + VN MOD26, H_2, H_2 + VAQ T_2, H_3, H_3 + VESRLG $26, H_3, T_3 + VN MOD26, H_3, H_3 + VAQ T_3, H_4, H_4 + + // h is now < 2(2¹³⁰ - 5) + // Pack each lane in h₂₆[0:4] into h₁₂₈[0:1]. + VESLG $26, H_1, H_1 + VESLG $26, H_3, H_3 + VO H_0, H_1, H_0 + VO H_2, H_3, H_2 + VESLG $4, H_2, H_2 + VLEIB $7, $48, H_1 + VSLB H_1, H_2, H_2 + VO H_0, H_2, H_0 + VLEIB $7, $104, H_1 + VSLB H_1, H_4, H_3 + VO H_3, H_0, H_0 + VLEIB $7, $24, H_1 + VSRLB H_1, H_4, H_1 + + // update state + VSTEG $1, H_0, 0(R1) + VSTEG $0, H_0, 8(R1) + VSTEG $1, H_1, 16(R1) + RET + +b2: // 2 or fewer blocks remaining + CMPBLE R3, $16, b1 + + // Load the 2 remaining blocks (17-32 bytes remaining). + MOVD $-17(R3), R0 // index of final byte to load modulo 16 + VL (R2), T_0 // load full 16 byte block + VLL R0, 16(R2), T_1 // load final (possibly partial) block and pad with zeros to 16 bytes + + // The Poly1305 algorithm requires that a 1 bit be appended to + // each message block. If the final block is less than 16 bytes + // long then it is easiest to insert the 1 before the message + // block is split into 26-bit limbs. If, on the other hand, the + // final message block is 16 bytes long then we append the 1 bit + // after expansion as normal. + MOVBZ $1, R0 + MOVD $-16(R3), R3 // index of byte in last block to insert 1 at (could be 16) + CMPBEQ R3, $16, 2(PC) // skip the insertion if the final block is 16 bytes long + VLVGB R3, R0, T_1 // insert 1 into the byte at index R3 + + // Split both blocks into 26-bit limbs in the appropriate lanes. + EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4) + + // Append a 1 byte to the end of the second to last block. + VLEIB $4, $1, M_4 + + // Append a 1 byte to the end of the last block only if it is a + // full 16 byte block. + CMPBNE R3, $16, 2(PC) + VLEIB $12, $1, M_4 + + // Finally, set up the coefficients for the final multiplication. + // We have previously saved r and 5r in the 32-bit even indexes + // of the R_[0-4] and R5_[1-4] coefficient registers. + // + // We want lane 0 to be multiplied by r² so that can be kept the + // same. We want lane 1 to be multiplied by r so we need to move + // the saved r value into the 32-bit odd index in lane 1 by + // rotating the 64-bit lane by 32. + VGBM $0x00ff, T_0 // [0, 0xffffffffffffffff] - mask lane 1 only + VERIMG $32, R_0, T_0, R_0 // [_, r²₂₆[0], _, r₂₆[0]] + VERIMG $32, R_1, T_0, R_1 // [_, r²₂₆[1], _, r₂₆[1]] + VERIMG $32, R_2, T_0, R_2 // [_, r²₂₆[2], _, r₂₆[2]] + VERIMG $32, R_3, T_0, R_3 // [_, r²₂₆[3], _, r₂₆[3]] + VERIMG $32, R_4, T_0, R_4 // [_, r²₂₆[4], _, r₂₆[4]] + VERIMG $32, R5_1, T_0, R5_1 // [_, 5r²₂₆[1], _, 5r₂₆[1]] + VERIMG $32, R5_2, T_0, R5_2 // [_, 5r²₂₆[2], _, 5r₂₆[2]] + VERIMG $32, R5_3, T_0, R5_3 // [_, 5r²₂₆[3], _, 5r₂₆[3]] + VERIMG $32, R5_4, T_0, R5_4 // [_, 5r²₂₆[4], _, 5r₂₆[4]] + + MOVD $0, R3 + BR multiply + +skip: + CMPBEQ R3, $0, finish + +b1: // 1 block remaining + + // Load the final block (1-16 bytes). This will be placed into + // lane 0. + MOVD $-1(R3), R0 + VLL R0, (R2), T_0 // pad to 16 bytes with zeros + + // The Poly1305 algorithm requires that a 1 bit be appended to + // each message block. If the final block is less than 16 bytes + // long then it is easiest to insert the 1 before the message + // block is split into 26-bit limbs. If, on the other hand, the + // final message block is 16 bytes long then we append the 1 bit + // after expansion as normal. + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, T_0 + + // Set the message block in lane 1 to the value 0 so that it + // can be accumulated without affecting the final result. + VZERO T_1 + + // Split the final message block into 26-bit limbs in lane 0. + // Lane 1 will be contain 0. + EXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4) + + // Append a 1 byte to the end of the last block only if it is a + // full 16 byte block. + CMPBNE R3, $16, 2(PC) + VLEIB $4, $1, M_4 + + // We have previously saved r and 5r in the 32-bit even indexes + // of the R_[0-4] and R5_[1-4] coefficient registers. + // + // We want lane 0 to be multiplied by r so we need to move the + // saved r value into the 32-bit odd index in lane 0. We want + // lane 1 to be set to the value 1. This makes multiplication + // a no-op. We do this by setting lane 1 in every register to 0 + // and then just setting the 32-bit index 3 in R_0 to 1. + VZERO T_0 + MOVD $0, R0 + MOVD $0x10111213, R12 + VLVGP R12, R0, T_1 // [_, 0x10111213, _, 0x00000000] + VPERM T_0, R_0, T_1, R_0 // [_, r₂₆[0], _, 0] + VPERM T_0, R_1, T_1, R_1 // [_, r₂₆[1], _, 0] + VPERM T_0, R_2, T_1, R_2 // [_, r₂₆[2], _, 0] + VPERM T_0, R_3, T_1, R_3 // [_, r₂₆[3], _, 0] + VPERM T_0, R_4, T_1, R_4 // [_, r₂₆[4], _, 0] + VPERM T_0, R5_1, T_1, R5_1 // [_, 5r₂₆[1], _, 0] + VPERM T_0, R5_2, T_1, R5_2 // [_, 5r₂₆[2], _, 0] + VPERM T_0, R5_3, T_1, R5_3 // [_, 5r₂₆[3], _, 0] + VPERM T_0, R5_4, T_1, R5_4 // [_, 5r₂₆[4], _, 0] + + // Set the value of lane 1 to be 1. + VLEIF $3, $1, R_0 // [_, r₂₆[0], _, 1] + + MOVD $0, R3 + BR multiply diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go deleted file mode 100644 index 37dc0cfdb5b..00000000000 --- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ctxhttp provides helper functions for performing context-aware HTTP requests. -package ctxhttp // import "golang.org/x/net/context/ctxhttp" - -import ( - "context" - "io" - "net/http" - "net/url" - "strings" -) - -// Do sends an HTTP request with the provided http.Client and returns -// an HTTP response. -// -// If the client is nil, http.DefaultClient is used. -// -// The provided ctx must be non-nil. If it is canceled or times out, -// ctx.Err() will be returned. -func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - resp, err := client.Do(req.WithContext(ctx)) - // If we got an error, and the context has been canceled, - // the context's error is probably more useful. - if err != nil { - select { - case <-ctx.Done(): - err = ctx.Err() - default: - } - } - return resp, err -} - -// Get issues a GET request via the Do function. -func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Head issues a HEAD request via the Do function. -func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("HEAD", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Post issues a POST request via the Do function. -func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { - req, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", bodyType) - return Do(ctx, client, req) -} - -// PostForm issues a POST request via the Do function. -func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { - return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 822ed42a04c..2466ae3d9a5 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -92,6 +92,27 @@ example, to process each anchor node in depth-first order: The relevant specifications include: https://html.spec.whatwg.org/multipage/syntax.html and https://html.spec.whatwg.org/multipage/syntax.html#tokenization + +# Security Considerations + +Care should be taken when parsing and interpreting HTML, whether full documents +or fragments, within the framework of the HTML specification, especially with +regard to untrusted inputs. + +This package provides both a tokenizer and a parser, which implement the +tokenization, and tokenization and tree construction stages of the WHATWG HTML +parsing specification respectively. While the tokenizer parses and normalizes +individual HTML tokens, only the parser constructs the DOM tree from the +tokenized HTML, as described in the tree construction stage of the +specification, dynamically modifying or extending the docuemnt's DOM tree. + +If your use case requires semantically well-formed HTML documents, as defined by +the WHATWG specification, the parser should be used rather than the tokenizer. + +In security contexts, if trust decisions are being made using the tokenized or +parsed content, the input must be re-serialized (for instance by using Render or +Token.String) in order for those trust decisions to hold, as the process of +tokenization or parsing may alter the content. */ package html // import "golang.org/x/net/html" diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index d8561396200..04c6bec2107 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -193,6 +193,87 @@ func lower(b []byte) []byte { return b } +// escapeComment is like func escape but escapes its input bytes less often. +// Per https://github.com/golang/go/issues/58246 some HTML comments are (1) +// meaningful and (2) contain angle brackets that we'd like to avoid escaping +// unless we have to. +// +// "We have to" includes the '&' byte, since that introduces other escapes. +// +// It also includes those bytes (not including EOF) that would otherwise end +// the comment. Per the summary table at the bottom of comment_test.go, this is +// the '>' byte that, per above, we'd like to avoid escaping unless we have to. +// +// Studying the summary table (and T actions in its '>' column) closely, we +// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the +// start of the comment data. State 52 is after a '!'. The other three states +// are after a '-'. +// +// Our algorithm is thus to escape every '&' and to escape '>' if and only if: +// - The '>' is after a '!' or '-' (in the unescaped data) or +// - The '>' is at the start of the comment data (after the opening ""); err != nil { @@ -194,9 +194,8 @@ func render1(w writer, n *Node) error { } } - // Render any child nodes. - switch n.Data { - case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": + // Render any child nodes + if childTextNodesAreLiteral(n) { for c := n.FirstChild; c != nil; c = c.NextSibling { if c.Type == TextNode { if _, err := w.WriteString(c.Data); err != nil { @@ -213,7 +212,7 @@ func render1(w writer, n *Node) error { // last element in the file, with no closing tag. return plaintextAbort } - default: + } else { for c := n.FirstChild; c != nil; c = c.NextSibling { if err := render1(w, c); err != nil { return err @@ -231,6 +230,27 @@ func render1(w writer, n *Node) error { return w.WriteByte('>') } +func childTextNodesAreLiteral(n *Node) bool { + // Per WHATWG HTML 13.3, if the parent of the current node is a style, + // script, xmp, iframe, noembed, noframes, or plaintext element, and the + // current node is a text node, append the value of the node's data + // literally. The specification is not explicit about it, but we only + // enforce this if we are in the HTML namespace (i.e. when the namespace is + // ""). + // NOTE: we also always include noscript elements, although the + // specification states that they should only be rendered as such if + // scripting is enabled for the node (which is not something we track). + if n.Namespace != "" { + return false + } + switch n.Data { + case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": + return true + default: + return false + } +} + // writeQuoted writes s to w surrounded by quotes. Normally it will use double // quotes, but if s contains a double quote, it will use single quotes. // It is used for writing the identifiers in a doctype declaration. diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index ae24a6fdf4a..de67f938a14 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,7 +110,7 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "" + return "" case DoctypeToken: return "" } @@ -598,6 +598,11 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with "") return + } else if c == '-' { + dashCount = 1 + beginning = false + continue } } } @@ -645,6 +649,35 @@ func (z *Tokenizer) readComment() { } } +func (z *Tokenizer) calculateAbruptCommentDataEnd() int { + raw := z.Raw() + const prefixLen = len(" balancer) calls are guaranteed to execute in a + // mutually exclusive manner as they are scheduled in the serializer. Fields + // accessed *only* in these serializer callbacks, can therefore be accessed + // without a mutex. balancer *gracefulswitch.Balancer curBalancerName string - updateCh *buffer.Unbounded // Updates written on this channel are processed by watcher(). - resultCh *buffer.Unbounded // Results of calls to UpdateClientConnState() are pushed here. - closed *grpcsync.Event // Indicates if close has been called. - done *grpcsync.Event // Indicates if close has completed its work. + // mu guards access to the below fields. Access to the serializer and its + // cancel function needs to be mutex protected because they are overwritten + // when the wrapper exits idle mode. + mu sync.Mutex + serializer *grpcsync.CallbackSerializer // To serialize all outoing calls. + serializerCancel context.CancelFunc // To close the seralizer at close/enterIdle time. + mode ccbMode // Tracks the current mode of the wrapper. } // newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer // is not created until the switchTo() method is invoked. func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper { + ctx, cancel := context.WithCancel(context.Background()) ccb := &ccBalancerWrapper{ - cc: cc, - updateCh: buffer.NewUnbounded(), - resultCh: buffer.NewUnbounded(), - closed: grpcsync.NewEvent(), - done: grpcsync.NewEvent(), + cc: cc, + opts: bopts, + serializer: grpcsync.NewCallbackSerializer(ctx), + serializerCancel: cancel, } - go ccb.watcher() ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts) return ccb } -// The following xxxUpdate structs wrap the arguments received as part of the -// corresponding update. The watcher goroutine uses the 'type' of the update to -// invoke the appropriate handler routine to handle the update. - -type ccStateUpdate struct { - ccs *balancer.ClientConnState -} - -type scStateUpdate struct { - sc balancer.SubConn - state connectivity.State - err error -} - -type exitIdleUpdate struct{} - -type resolverErrorUpdate struct { - err error -} - -type switchToUpdate struct { - name string -} - -type subConnUpdate struct { - acbw *acBalancerWrapper -} - -// watcher is a long-running goroutine which reads updates from a channel and -// invokes corresponding methods on the underlying balancer. It ensures that -// these methods are invoked in a synchronous fashion. It also ensures that -// these methods are invoked in the order in which the updates were received. -func (ccb *ccBalancerWrapper) watcher() { - for { - select { - case u := <-ccb.updateCh.Get(): - ccb.updateCh.Load() - if ccb.closed.HasFired() { - break - } - switch update := u.(type) { - case *ccStateUpdate: - ccb.handleClientConnStateChange(update.ccs) - case *scStateUpdate: - ccb.handleSubConnStateChange(update) - case *exitIdleUpdate: - ccb.handleExitIdle() - case *resolverErrorUpdate: - ccb.handleResolverError(update.err) - case *switchToUpdate: - ccb.handleSwitchTo(update.name) - case *subConnUpdate: - ccb.handleRemoveSubConn(update.acbw) - default: - logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", update, update) - } - case <-ccb.closed.Done(): - } - - if ccb.closed.HasFired() { - ccb.handleClose() - return - } - } -} - // updateClientConnState is invoked by grpc to push a ClientConnState update to // the underlying balancer. -// -// Unlike other methods invoked by grpc to push updates to the underlying -// balancer, this method cannot simply push the update onto the update channel -// and return. It needs to return the error returned by the underlying balancer -// back to grpc which propagates that to the resolver. func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { - ccb.updateCh.Put(&ccStateUpdate{ccs: ccs}) - - var res interface{} - select { - case res = <-ccb.resultCh.Get(): - ccb.resultCh.Load() - case <-ccb.closed.Done(): - // Return early if the balancer wrapper is closed while we are waiting for - // the underlying balancer to process a ClientConnState update. - return nil - } - // If the returned error is nil, attempting to type assert to error leads to - // panic. So, this needs to handled separately. - if res == nil { - return nil + ccb.mu.Lock() + errCh := make(chan error, 1) + // Here and everywhere else where Schedule() is called, it is done with the + // lock held. But the lock guards only the scheduling part. The actual + // callback is called asynchronously without the lock being held. + ok := ccb.serializer.Schedule(func(_ context.Context) { + errCh <- ccb.balancer.UpdateClientConnState(*ccs) + }) + if !ok { + // If we are unable to schedule a function with the serializer, it + // indicates that it has been closed. A serializer is only closed when + // the wrapper is closed or is in idle. + ccb.mu.Unlock() + return fmt.Errorf("grpc: cannot send state update to a closed or idle balancer") } - return res.(error) -} - -// handleClientConnStateChange handles a ClientConnState update from the update -// channel and invokes the appropriate method on the underlying balancer. -// -// If the addresses specified in the update contain addresses of type "grpclb" -// and the selected LB policy is not "grpclb", these addresses will be filtered -// out and ccs will be modified with the updated address list. -func (ccb *ccBalancerWrapper) handleClientConnStateChange(ccs *balancer.ClientConnState) { - if ccb.curBalancerName != grpclbName { - // Filter any grpclb addresses since we don't have the grpclb balancer. - var addrs []resolver.Address - for _, addr := range ccs.ResolverState.Addresses { - if addr.Type == resolver.GRPCLB { - continue - } - addrs = append(addrs, addr) - } - ccs.ResolverState.Addresses = addrs + ccb.mu.Unlock() + + // We get here only if the above call to Schedule succeeds, in which case it + // is guaranteed that the scheduled function will run. Therefore it is safe + // to block on this channel. + err := <-errCh + if logger.V(2) && err != nil { + logger.Infof("error from balancer.UpdateClientConnState: %v", err) } - ccb.resultCh.Put(ccb.balancer.UpdateClientConnState(*ccs)) + return err } // updateSubConnState is invoked by grpc to push a subConn state update to the // underlying balancer. func (ccb *ccBalancerWrapper) updateSubConnState(sc balancer.SubConn, s connectivity.State, err error) { - // When updating addresses for a SubConn, if the address in use is not in - // the new addresses, the old ac will be tearDown() and a new ac will be - // created. tearDown() generates a state change with Shutdown state, we - // don't want the balancer to receive this state change. So before - // tearDown() on the old ac, ac.acbw (acWrapper) will be set to nil, and - // this function will be called with (nil, Shutdown). We don't need to call - // balancer method in this case. - if sc == nil { - return - } - ccb.updateCh.Put(&scStateUpdate{ - sc: sc, - state: s, - err: err, + ccb.mu.Lock() + ccb.serializer.Schedule(func(_ context.Context) { + // Even though it is optional for balancers, gracefulswitch ensures + // opts.StateListener is set, so this cannot ever be nil. + sc.(*acBalancerWrapper).stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err}) }) -} - -// handleSubConnStateChange handles a SubConnState update from the update -// channel and invokes the appropriate method on the underlying balancer. -func (ccb *ccBalancerWrapper) handleSubConnStateChange(update *scStateUpdate) { - ccb.balancer.UpdateSubConnState(update.sc, balancer.SubConnState{ConnectivityState: update.state, ConnectionError: update.err}) -} - -func (ccb *ccBalancerWrapper) exitIdle() { - ccb.updateCh.Put(&exitIdleUpdate{}) -} - -func (ccb *ccBalancerWrapper) handleExitIdle() { - if ccb.cc.GetState() != connectivity.Idle { - return - } - ccb.balancer.ExitIdle() + ccb.mu.Unlock() } func (ccb *ccBalancerWrapper) resolverError(err error) { - ccb.updateCh.Put(&resolverErrorUpdate{err: err}) -} - -func (ccb *ccBalancerWrapper) handleResolverError(err error) { - ccb.balancer.ResolverError(err) + ccb.mu.Lock() + ccb.serializer.Schedule(func(_ context.Context) { + ccb.balancer.ResolverError(err) + }) + ccb.mu.Unlock() } // switchTo is invoked by grpc to instruct the balancer wrapper to switch to the @@ -248,24 +151,27 @@ func (ccb *ccBalancerWrapper) handleResolverError(err error) { // the ccBalancerWrapper keeps track of the current LB policy name, and skips // the graceful balancer switching process if the name does not change. func (ccb *ccBalancerWrapper) switchTo(name string) { - ccb.updateCh.Put(&switchToUpdate{name: name}) + ccb.mu.Lock() + ccb.serializer.Schedule(func(_ context.Context) { + // TODO: Other languages use case-sensitive balancer registries. We should + // switch as well. See: https://github.com/grpc/grpc-go/issues/5288. + if strings.EqualFold(ccb.curBalancerName, name) { + return + } + ccb.buildLoadBalancingPolicy(name) + }) + ccb.mu.Unlock() } -// handleSwitchTo handles a balancer switch update from the update channel. It -// calls the SwitchTo() method on the gracefulswitch.Balancer with a -// balancer.Builder corresponding to name. If no balancer.Builder is registered -// for the given name, it uses the default LB policy which is "pick_first". -func (ccb *ccBalancerWrapper) handleSwitchTo(name string) { - // TODO: Other languages use case-insensitive balancer registries. We should - // switch as well. See: https://github.com/grpc/grpc-go/issues/5288. - if strings.EqualFold(ccb.curBalancerName, name) { - return - } - - // TODO: Ensure that name is a registered LB policy when we get here. - // We currently only validate the `loadBalancingConfig` field. We need to do - // the same for the `loadBalancingPolicy` field and reject the service config - // if the specified policy is not registered. +// buildLoadBalancingPolicy performs the following: +// - retrieve a balancer builder for the given name. Use the default LB +// policy, pick_first, if no LB policy with name is found in the registry. +// - instruct the gracefulswitch balancer to switch to the above builder. This +// will actually build the new balancer. +// - update the `curBalancerName` field +// +// Must be called from a serializer callback. +func (ccb *ccBalancerWrapper) buildLoadBalancingPolicy(name string) { builder := balancer.Get(name) if builder == nil { channelz.Warningf(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q, since the specified LB policy %q was not registered", PickFirstBalancerName, name) @@ -281,26 +187,112 @@ func (ccb *ccBalancerWrapper) handleSwitchTo(name string) { ccb.curBalancerName = builder.Name() } -// handleRemoveSucConn handles a request from the underlying balancer to remove -// a subConn. -// -// See comments in RemoveSubConn() for more details. -func (ccb *ccBalancerWrapper) handleRemoveSubConn(acbw *acBalancerWrapper) { - ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain) +func (ccb *ccBalancerWrapper) close() { + channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing") + ccb.closeBalancer(ccbModeClosed) } -func (ccb *ccBalancerWrapper) close() { - ccb.closed.Fire() - <-ccb.done.Done() +// enterIdleMode is invoked by grpc when the channel enters idle mode upon +// expiry of idle_timeout. This call blocks until the balancer is closed. +func (ccb *ccBalancerWrapper) enterIdleMode() { + channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: entering idle mode") + ccb.closeBalancer(ccbModeIdle) +} + +// closeBalancer is invoked when the channel is being closed or when it enters +// idle mode upon expiry of idle_timeout. +func (ccb *ccBalancerWrapper) closeBalancer(m ccbMode) { + ccb.mu.Lock() + if ccb.mode == ccbModeClosed || ccb.mode == ccbModeIdle { + ccb.mu.Unlock() + return + } + + ccb.mode = m + done := ccb.serializer.Done() + b := ccb.balancer + ok := ccb.serializer.Schedule(func(_ context.Context) { + // Close the serializer to ensure that no more calls from gRPC are sent + // to the balancer. + ccb.serializerCancel() + // Empty the current balancer name because we don't have a balancer + // anymore and also so that we act on the next call to switchTo by + // creating a new balancer specified by the new resolver. + ccb.curBalancerName = "" + }) + if !ok { + ccb.mu.Unlock() + return + } + ccb.mu.Unlock() + + // Give enqueued callbacks a chance to finish before closing the balancer. + <-done + b.Close() } -func (ccb *ccBalancerWrapper) handleClose() { - ccb.balancer.Close() - ccb.done.Fire() +// exitIdleMode is invoked by grpc when the channel exits idle mode either +// because of an RPC or because of an invocation of the Connect() API. This +// recreates the balancer that was closed previously when entering idle mode. +// +// If the channel is not in idle mode, we know for a fact that we are here as a +// result of the user calling the Connect() method on the ClientConn. In this +// case, we can simply forward the call to the underlying balancer, instructing +// it to reconnect to the backends. +func (ccb *ccBalancerWrapper) exitIdleMode() { + ccb.mu.Lock() + if ccb.mode == ccbModeClosed { + // Request to exit idle is a no-op when wrapper is already closed. + ccb.mu.Unlock() + return + } + + if ccb.mode == ccbModeIdle { + // Recreate the serializer which was closed when we entered idle. + ctx, cancel := context.WithCancel(context.Background()) + ccb.serializer = grpcsync.NewCallbackSerializer(ctx) + ccb.serializerCancel = cancel + } + + // The ClientConn guarantees that mutual exclusion between close() and + // exitIdleMode(), and since we just created a new serializer, we can be + // sure that the below function will be scheduled. + done := make(chan struct{}) + ccb.serializer.Schedule(func(_ context.Context) { + defer close(done) + + ccb.mu.Lock() + defer ccb.mu.Unlock() + + if ccb.mode != ccbModeIdle { + ccb.balancer.ExitIdle() + return + } + + // Gracefulswitch balancer does not support a switchTo operation after + // being closed. Hence we need to create a new one here. + ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts) + ccb.mode = ccbModeActive + channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: exiting idle mode") + + }) + ccb.mu.Unlock() + + <-done +} + +func (ccb *ccBalancerWrapper) isIdleOrClosed() bool { + ccb.mu.Lock() + defer ccb.mu.Unlock() + return ccb.mode == ccbModeIdle || ccb.mode == ccbModeClosed } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { - if len(addrs) <= 0 { + if ccb.isIdleOrClosed() { + return nil, fmt.Errorf("grpc: cannot create SubConn when balancer is closed or idle") + } + + if len(addrs) == 0 { return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list") } ac, err := ccb.cc.newAddrConn(addrs, opts) @@ -308,32 +300,26 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) return nil, err } - acbw := &acBalancerWrapper{ac: ac, producers: make(map[balancer.ProducerBuilder]*refCountedProducer)} - acbw.ac.mu.Lock() + acbw := &acBalancerWrapper{ + ccb: ccb, + ac: ac, + producers: make(map[balancer.ProducerBuilder]*refCountedProducer), + stateListener: opts.StateListener, + } ac.acbw = acbw - acbw.ac.mu.Unlock() return acbw, nil } func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { - // Before we switched the ccBalancerWrapper to use gracefulswitch.Balancer, it - // was required to handle the RemoveSubConn() method asynchronously by pushing - // the update onto the update channel. This was done to avoid a deadlock as - // switchBalancer() was holding cc.mu when calling Close() on the old - // balancer, which would in turn call RemoveSubConn(). - // - // With the use of gracefulswitch.Balancer in ccBalancerWrapper, handling this - // asynchronously is probably not required anymore since the switchTo() method - // handles the balancer switch by pushing the update onto the channel. - // TODO(easwars): Handle this inline. - acbw, ok := sc.(*acBalancerWrapper) - if !ok { - return - } - ccb.updateCh.Put(&subConnUpdate{acbw: acbw}) + // The graceful switch balancer will never call this. + logger.Errorf("ccb RemoveSubConn(%v) called unexpectedly, sc") } func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { + if ccb.isIdleOrClosed() { + return + } + acbw, ok := sc.(*acBalancerWrapper) if !ok { return @@ -342,6 +328,10 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol } func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { + if ccb.isIdleOrClosed() { + return + } + // Update picker before updating state. Even though the ordering here does // not matter, it can lead to multiple calls of Pick in the common start-up // case where we wait for ready and then perform an RPC. If the picker is @@ -352,6 +342,10 @@ func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { } func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) { + if ccb.isIdleOrClosed() { + return + } + ccb.cc.resolveNow(o) } @@ -362,78 +356,57 @@ func (ccb *ccBalancerWrapper) Target() string { // acBalancerWrapper is a wrapper on top of ac for balancers. // It implements balancer.SubConn interface. type acBalancerWrapper struct { + ac *addrConn // read-only + ccb *ccBalancerWrapper // read-only + stateListener func(balancer.SubConnState) + mu sync.Mutex - ac *addrConn producers map[balancer.ProducerBuilder]*refCountedProducer } -func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { - acbw.mu.Lock() - defer acbw.mu.Unlock() - if len(addrs) <= 0 { - acbw.ac.cc.removeAddrConn(acbw.ac, errConnDrain) - return - } - if !acbw.ac.tryUpdateAddrs(addrs) { - cc := acbw.ac.cc - opts := acbw.ac.scopts - acbw.ac.mu.Lock() - // Set old ac.acbw to nil so the Shutdown state update will be ignored - // by balancer. - // - // TODO(bar) the state transition could be wrong when tearDown() old ac - // and creating new ac, fix the transition. - acbw.ac.acbw = nil - acbw.ac.mu.Unlock() - acState := acbw.ac.getState() - acbw.ac.cc.removeAddrConn(acbw.ac, errConnDrain) - - if acState == connectivity.Shutdown { - return - } +func (acbw *acBalancerWrapper) String() string { + return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int()) +} - newAC, err := cc.newAddrConn(addrs, opts) - if err != nil { - channelz.Warningf(logger, acbw.ac.channelzID, "acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err) - return - } - acbw.ac = newAC - newAC.mu.Lock() - newAC.acbw = acbw - newAC.mu.Unlock() - if acState != connectivity.Idle { - go newAC.connect() - } - } +func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { + acbw.ac.updateAddrs(addrs) } func (acbw *acBalancerWrapper) Connect() { - acbw.mu.Lock() - defer acbw.mu.Unlock() go acbw.ac.connect() } -func (acbw *acBalancerWrapper) getAddrConn() *addrConn { - acbw.mu.Lock() - defer acbw.mu.Unlock() - return acbw.ac -} +func (acbw *acBalancerWrapper) Shutdown() { + ccb := acbw.ccb + if ccb.isIdleOrClosed() { + // It it safe to ignore this call when the balancer is closed or in idle + // because the ClientConn takes care of closing the connections. + // + // Not returning early from here when the balancer is closed or in idle + // leads to a deadlock though, because of the following sequence of + // calls when holding cc.mu: + // cc.exitIdleMode --> ccb.enterIdleMode --> gsw.Close --> + // ccb.RemoveAddrConn --> cc.removeAddrConn + return + } -var errSubConnNotReady = status.Error(codes.Unavailable, "SubConn not currently connected") + ccb.cc.removeAddrConn(acbw.ac, errConnDrain) +} // NewStream begins a streaming RPC on the addrConn. If the addrConn is not -// ready, returns errSubConnNotReady. +// ready, blocks until it is or ctx expires. Returns an error when the context +// expires or the addrConn is shut down. func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { - transport := acbw.ac.getReadyTransport() - if transport == nil { - return nil, errSubConnNotReady + transport, err := acbw.ac.getTransport(ctx) + if err != nil { + return nil, err } return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...) } // Invoke performs a unary RPC. If the addrConn is not ready, returns // errSubConnNotReady. -func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error { +func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error { cs, err := acbw.NewStream(ctx, unaryStreamDesc, method, opts...) if err != nil { return err diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 64a232f2811..5954801122a 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -18,14 +18,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.31.0 +// protoc v4.22.0 // source: grpc/binlog/v1/binarylog.proto package grpc_binarylog_v1 import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" @@ -41,10 +40,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Enumerates the type of event // Note the terminology is different from the RPC semantics // definition, but the same meaning is expressed here. diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index 9e20e4d385f..788c89c16f9 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -26,7 +26,7 @@ import ( // received. This is typically called by generated code. // // All errors returned by Invoke are compatible with the status package. -func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...CallOption) error { +func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply any, opts ...CallOption) error { // allow interceptor to see all applicable call options, which means those // configured as defaults from dial option as well as per-call options opts = combine(cc.dopts.callOptions, opts) @@ -56,13 +56,13 @@ func combine(o1 []CallOption, o2 []CallOption) []CallOption { // received. This is typically called by generated code. // // DEPRECATED: Use ClientConn.Invoke instead. -func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) error { +func Invoke(ctx context.Context, method string, args, reply any, cc *ClientConn, opts ...CallOption) error { return cc.Invoke(ctx, method, args, reply, opts...) } var unaryStreamDesc = &StreamDesc{ServerStreams: false, ClientStreams: false} -func invoke(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error { +func invoke(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error { cs, err := newClientStream(ctx, unaryStreamDesc, cc, method, opts...) if err != nil { return err diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 422639c79db..ff7fea10228 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -24,7 +24,6 @@ import ( "fmt" "math" "net/url" - "reflect" "strings" "sync" "sync/atomic" @@ -35,9 +34,12 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/idle" + "google.golang.org/grpc/internal/pretty" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -54,8 +56,6 @@ import ( const ( // minimum time to give a connection to complete minConnectTimeout = 20 * time.Second - // must match grpclbName in grpclb/grpclb.go - grpclbName = "grpclb" ) var ( @@ -69,6 +69,9 @@ var ( errConnDrain = errors.New("grpc: the connection is drained") // errConnClosing indicates that the connection is closing. errConnClosing = errors.New("grpc: the connection is closing") + // errConnIdling indicates the the connection is being closed as the channel + // is moving to an idle mode due to inactivity. + errConnIdling = errors.New("grpc: the connection is closing due to channel idleness") // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default // service config. invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" @@ -134,20 +137,41 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires // e.g. to use dns resolver, a "dns:///" prefix should be applied to the target. func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ - target: target, - csMgr: &connectivityStateManager{}, - conns: make(map[*addrConn]struct{}), - dopts: defaultDialOptions(), - blockingpicker: newPickerWrapper(), - czData: new(channelzData), - firstResolveEvent: grpcsync.NewEvent(), + target: target, + conns: make(map[*addrConn]struct{}), + dopts: defaultDialOptions(), + czData: new(channelzData), } + + // We start the channel off in idle mode, but kick it out of idle at the end + // of this method, instead of waiting for the first RPC. Other gRPC + // implementations do wait for the first RPC to kick the channel out of + // idle. But doing so would be a major behavior change for our users who are + // used to seeing the channel active after Dial. + // + // Taking this approach of kicking it out of idle at the end of this method + // allows us to share the code between channel creation and exiting idle + // mode. This will also make it easy for us to switch to starting the + // channel off in idle, if at all we ever get to do that. + cc.idlenessState = ccIdlenessStateIdle + cc.retryThrottler.Store((*retryThrottler)(nil)) cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil}) cc.ctx, cc.cancel = context.WithCancel(context.Background()) + cc.exitIdleCond = sync.NewCond(&cc.mu) - for _, opt := range extraDialOptions { - opt.apply(&cc.dopts) + disableGlobalOpts := false + for _, opt := range opts { + if _, ok := opt.(*disableGlobalDialOptions); ok { + disableGlobalOpts = true + break + } + } + + if !disableGlobalOpts { + for _, opt := range globalDialOptions { + opt.apply(&cc.dopts) + } } for _, opt := range opts { @@ -163,40 +187,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } }() - pid := cc.dopts.channelzParentID - cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, pid, target) - ted := &channelz.TraceEventDesc{ - Desc: "Channel created", - Severity: channelz.CtInfo, - } - if cc.dopts.channelzParentID != nil { - ted.Parent = &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Nested Channel(id:%d) created", cc.channelzID.Int()), - Severity: channelz.CtInfo, - } - } - channelz.AddTraceEvent(logger, cc.channelzID, 1, ted) - cc.csMgr.channelzID = cc.channelzID + // Register ClientConn with channelz. + cc.channelzRegistration(target) - if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil { - return nil, errNoTransportSecurity - } - if cc.dopts.copts.TransportCredentials != nil && cc.dopts.copts.CredsBundle != nil { - return nil, errTransportCredsAndBundle - } - if cc.dopts.copts.CredsBundle != nil && cc.dopts.copts.CredsBundle.TransportCredentials() == nil { - return nil, errNoTransportCredsInBundle - } - transportCreds := cc.dopts.copts.TransportCredentials - if transportCreds == nil { - transportCreds = cc.dopts.copts.CredsBundle.TransportCredentials() - } - if transportCreds.Info().SecurityProtocol == "insecure" { - for _, cd := range cc.dopts.copts.PerRPCCredentials { - if cd.RequireTransportSecurity() { - return nil, errTransportCredentialsMissing - } - } + cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelzID) + + if err := cc.validateTransportCredentials(); err != nil { + return nil, err } if cc.dopts.defaultServiceConfigRawJSON != nil { @@ -234,35 +231,19 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } }() - scSet := false - if cc.dopts.scChan != nil { - // Try to get an initial service config. - select { - case sc, ok := <-cc.dopts.scChan: - if ok { - cc.sc = &sc - cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc}) - scSet = true - } - default: - } - } if cc.dopts.bs == nil { cc.dopts.bs = backoff.DefaultExponential } // Determine the resolver to use. - resolverBuilder, err := cc.parseTargetAndFindResolver() - if err != nil { + if err := cc.parseTargetAndFindResolver(); err != nil { return nil, err } - cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint, cc.target, cc.dopts) - if err != nil { + if err = cc.determineAuthority(); err != nil { return nil, err } - channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority) - if cc.dopts.scChan != nil && !scSet { + if cc.dopts.scChan != nil { // Blocking wait for the initial service config. select { case sc, ok := <-cc.dopts.scChan: @@ -278,57 +259,234 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * go cc.scWatcher() } + // This creates the name resolver, load balancer, blocking picker etc. + if err := cc.exitIdleMode(); err != nil { + return nil, err + } + + // Configure idleness support with configured idle timeout or default idle + // timeout duration. Idleness can be explicitly disabled by the user, by + // setting the dial option to 0. + cc.idlenessMgr = idle.NewManager(idle.ManagerOptions{Enforcer: (*idler)(cc), Timeout: cc.dopts.idleTimeout, Logger: logger}) + + // Return early for non-blocking dials. + if !cc.dopts.block { + return cc, nil + } + + // A blocking dial blocks until the clientConn is ready. + for { + s := cc.GetState() + if s == connectivity.Idle { + cc.Connect() + } + if s == connectivity.Ready { + return cc, nil + } else if cc.dopts.copts.FailOnNonTempDialError && s == connectivity.TransientFailure { + if err = cc.connectionError(); err != nil { + terr, ok := err.(interface { + Temporary() bool + }) + if ok && !terr.Temporary() { + return nil, err + } + } + } + if !cc.WaitForStateChange(ctx, s) { + // ctx got timeout or canceled. + if err = cc.connectionError(); err != nil && cc.dopts.returnLastError { + return nil, err + } + return nil, ctx.Err() + } + } +} + +// addTraceEvent is a helper method to add a trace event on the channel. If the +// channel is a nested one, the same event is also added on the parent channel. +func (cc *ClientConn) addTraceEvent(msg string) { + ted := &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Channel %s", msg), + Severity: channelz.CtInfo, + } + if cc.dopts.channelzParentID != nil { + ted.Parent = &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Nested channel(id:%d) %s", cc.channelzID.Int(), msg), + Severity: channelz.CtInfo, + } + } + channelz.AddTraceEvent(logger, cc.channelzID, 0, ted) +} + +type idler ClientConn + +func (i *idler) EnterIdleMode() error { + return (*ClientConn)(i).enterIdleMode() +} + +func (i *idler) ExitIdleMode() error { + return (*ClientConn)(i).exitIdleMode() +} + +// exitIdleMode moves the channel out of idle mode by recreating the name +// resolver and load balancer. +func (cc *ClientConn) exitIdleMode() error { + cc.mu.Lock() + if cc.conns == nil { + cc.mu.Unlock() + return errConnClosing + } + if cc.idlenessState != ccIdlenessStateIdle { + cc.mu.Unlock() + channelz.Infof(logger, cc.channelzID, "ClientConn asked to exit idle mode, current mode is %v", cc.idlenessState) + return nil + } + + defer func() { + // When Close() and exitIdleMode() race against each other, one of the + // following two can happen: + // - Close() wins the race and runs first. exitIdleMode() runs after, and + // sees that the ClientConn is already closed and hence returns early. + // - exitIdleMode() wins the race and runs first and recreates the balancer + // and releases the lock before recreating the resolver. If Close() runs + // in this window, it will wait for exitIdleMode to complete. + // + // We achieve this synchronization using the below condition variable. + cc.mu.Lock() + cc.idlenessState = ccIdlenessStateActive + cc.exitIdleCond.Signal() + cc.mu.Unlock() + }() + + cc.idlenessState = ccIdlenessStateExitingIdle + exitedIdle := false + if cc.blockingpicker == nil { + cc.blockingpicker = newPickerWrapper(cc.dopts.copts.StatsHandlers) + } else { + cc.blockingpicker.exitIdleMode() + exitedIdle = true + } + var credsClone credentials.TransportCredentials if creds := cc.dopts.copts.TransportCredentials; creds != nil { credsClone = creds.Clone() } - cc.balancerWrapper = newCCBalancerWrapper(cc, balancer.BuildOptions{ - DialCreds: credsClone, - CredsBundle: cc.dopts.copts.CredsBundle, - Dialer: cc.dopts.copts.Dialer, - Authority: cc.authority, - CustomUserAgent: cc.dopts.copts.UserAgent, - ChannelzParentID: cc.channelzID, - Target: cc.parsedTarget, - }) + if cc.balancerWrapper == nil { + cc.balancerWrapper = newCCBalancerWrapper(cc, balancer.BuildOptions{ + DialCreds: credsClone, + CredsBundle: cc.dopts.copts.CredsBundle, + Dialer: cc.dopts.copts.Dialer, + Authority: cc.authority, + CustomUserAgent: cc.dopts.copts.UserAgent, + ChannelzParentID: cc.channelzID, + Target: cc.parsedTarget, + }) + } else { + cc.balancerWrapper.exitIdleMode() + } + cc.firstResolveEvent = grpcsync.NewEvent() + cc.mu.Unlock() - // Build the resolver. - rWrapper, err := newCCResolverWrapper(cc, resolverBuilder) - if err != nil { - return nil, fmt.Errorf("failed to build resolver: %v", err) + // This needs to be called without cc.mu because this builds a new resolver + // which might update state or report error inline which needs to be handled + // by cc.updateResolverState() which also grabs cc.mu. + if err := cc.initResolverWrapper(credsClone); err != nil { + return err } + + if exitedIdle { + cc.addTraceEvent("exiting idle mode") + } + return nil +} + +// enterIdleMode puts the channel in idle mode, and as part of it shuts down the +// name resolver, load balancer and any subchannels. +func (cc *ClientConn) enterIdleMode() error { cc.mu.Lock() - cc.resolverWrapper = rWrapper + if cc.conns == nil { + cc.mu.Unlock() + return ErrClientConnClosing + } + if cc.idlenessState != ccIdlenessStateActive { + channelz.Errorf(logger, cc.channelzID, "ClientConn asked to enter idle mode, current mode is %v", cc.idlenessState) + cc.mu.Unlock() + return nil + } + + // cc.conns == nil is a proxy for the ClientConn being closed. So, instead + // of setting it to nil here, we recreate the map. This also means that we + // don't have to do this when exiting idle mode. + conns := cc.conns + cc.conns = make(map[*addrConn]struct{}) + + // TODO: Currently, we close the resolver wrapper upon entering idle mode + // and create a new one upon exiting idle mode. This means that the + // `cc.resolverWrapper` field would be overwritten everytime we exit idle + // mode. While this means that we need to hold `cc.mu` when accessing + // `cc.resolverWrapper`, it makes the code simpler in the wrapper. We should + // try to do the same for the balancer and picker wrappers too. + cc.resolverWrapper.close() + cc.blockingpicker.enterIdleMode() + cc.balancerWrapper.enterIdleMode() + cc.csMgr.updateState(connectivity.Idle) + cc.idlenessState = ccIdlenessStateIdle cc.mu.Unlock() - // A blocking dial blocks until the clientConn is ready. - if cc.dopts.block { - for { - cc.Connect() - s := cc.GetState() - if s == connectivity.Ready { - break - } else if cc.dopts.copts.FailOnNonTempDialError && s == connectivity.TransientFailure { - if err = cc.connectionError(); err != nil { - terr, ok := err.(interface { - Temporary() bool - }) - if ok && !terr.Temporary() { - return nil, err - } - } - } - if !cc.WaitForStateChange(ctx, s) { - // ctx got timeout or canceled. - if err = cc.connectionError(); err != nil && cc.dopts.returnLastError { - return nil, err - } - return nil, ctx.Err() + go func() { + cc.addTraceEvent("entering idle mode") + for ac := range conns { + ac.tearDown(errConnIdling) + } + }() + return nil +} + +// validateTransportCredentials performs a series of checks on the configured +// transport credentials. It returns a non-nil error if any of these conditions +// are met: +// - no transport creds and no creds bundle is configured +// - both transport creds and creds bundle are configured +// - creds bundle is configured, but it lacks a transport credentials +// - insecure transport creds configured alongside call creds that require +// transport level security +// +// If none of the above conditions are met, the configured credentials are +// deemed valid and a nil error is returned. +func (cc *ClientConn) validateTransportCredentials() error { + if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil { + return errNoTransportSecurity + } + if cc.dopts.copts.TransportCredentials != nil && cc.dopts.copts.CredsBundle != nil { + return errTransportCredsAndBundle + } + if cc.dopts.copts.CredsBundle != nil && cc.dopts.copts.CredsBundle.TransportCredentials() == nil { + return errNoTransportCredsInBundle + } + transportCreds := cc.dopts.copts.TransportCredentials + if transportCreds == nil { + transportCreds = cc.dopts.copts.CredsBundle.TransportCredentials() + } + if transportCreds.Info().SecurityProtocol == "insecure" { + for _, cd := range cc.dopts.copts.PerRPCCredentials { + if cd.RequireTransportSecurity() { + return errTransportCredentialsMissing } } } + return nil +} - return cc, nil +// channelzRegistration registers the newly created ClientConn with channelz and +// stores the returned identifier in `cc.channelzID` and `cc.csMgr.channelzID`. +// A channelz trace event is emitted for ClientConn creation. If the newly +// created ClientConn is a nested one, i.e a valid parent ClientConn ID is +// specified via a dial option, the trace event is also added to the parent. +// +// Doesn't grab cc.mu as this method is expected to be called only at Dial time. +func (cc *ClientConn) channelzRegistration(target string) { + cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target) + cc.addTraceEvent("created") } // chainUnaryClientInterceptors chains all unary client interceptors into one. @@ -345,7 +503,7 @@ func chainUnaryClientInterceptors(cc *ClientConn) { } else if len(interceptors) == 1 { chainedInt = interceptors[0] } else { - chainedInt = func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error { + chainedInt = func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error { return interceptors[0](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, 0, invoker), opts...) } } @@ -357,7 +515,7 @@ func getChainUnaryInvoker(interceptors []UnaryClientInterceptor, curr int, final if curr == len(interceptors)-1 { return finalInvoker } - return func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error { + return func(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error { return interceptors[curr+1](ctx, method, req, reply, cc, getChainUnaryInvoker(interceptors, curr+1, finalInvoker), opts...) } } @@ -393,13 +551,27 @@ func getChainStreamer(interceptors []StreamClientInterceptor, curr int, finalStr } } +// newConnectivityStateManager creates an connectivityStateManager with +// the specified id. +func newConnectivityStateManager(ctx context.Context, id *channelz.Identifier) *connectivityStateManager { + return &connectivityStateManager{ + channelzID: id, + pubSub: grpcsync.NewPubSub(ctx), + } +} + // connectivityStateManager keeps the connectivity.State of ClientConn. // This struct will eventually be exported so the balancers can access it. +// +// TODO: If possible, get rid of the `connectivityStateManager` type, and +// provide this functionality using the `PubSub`, to avoid keeping track of +// the connectivity state at two places. type connectivityStateManager struct { mu sync.Mutex state connectivity.State notifyChan chan struct{} channelzID *channelz.Identifier + pubSub *grpcsync.PubSub } // updateState updates the connectivity.State of ClientConn. @@ -415,6 +587,8 @@ func (csm *connectivityStateManager) updateState(state connectivity.State) { return } csm.state = state + csm.pubSub.Publish(state) + channelz.Infof(logger, csm.channelzID, "Channel Connectivity change to %v", state) if csm.notifyChan != nil { // There are other goroutines waiting on this channel. @@ -444,7 +618,7 @@ func (csm *connectivityStateManager) getNotifyChan() <-chan struct{} { type ClientConnInterface interface { // Invoke performs a unary RPC and returns after the response is received // into reply. - Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...CallOption) error + Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error // NewStream begins a streaming RPC. NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) } @@ -474,7 +648,9 @@ type ClientConn struct { authority string // See determineAuthority(). dopts dialOptions // Default and user specified dial options. channelzID *channelz.Identifier // Channelz identifier for the channel. + resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). balancerWrapper *ccBalancerWrapper // Uses gracefulswitch.balancer underneath. + idlenessMgr idle.Manager // The following provide their own synchronization, and therefore don't // require cc.mu to be held to access them. @@ -495,11 +671,44 @@ type ClientConn struct { sc *ServiceConfig // Latest service config received from the resolver. conns map[*addrConn]struct{} // Set to nil on close. mkp keepalive.ClientParameters // May be updated upon receipt of a GoAway. + idlenessState ccIdlenessState // Tracks idleness state of the channel. + exitIdleCond *sync.Cond // Signalled when channel exits idle. lceMu sync.Mutex // protects lastConnectionError lastConnectionError error } +// ccIdlenessState tracks the idleness state of the channel. +// +// Channels start off in `active` and move to `idle` after a period of +// inactivity. When moving back to `active` upon an incoming RPC, they +// transition through `exiting_idle`. This state is useful for synchronization +// with Close(). +// +// This state tracking is mostly for self-protection. The idlenessManager is +// expected to keep track of the state as well, and is expected not to call into +// the ClientConn unnecessarily. +type ccIdlenessState int8 + +const ( + ccIdlenessStateActive ccIdlenessState = iota + ccIdlenessStateIdle + ccIdlenessStateExitingIdle +) + +func (s ccIdlenessState) String() string { + switch s { + case ccIdlenessStateActive: + return "active" + case ccIdlenessStateIdle: + return "idle" + case ccIdlenessStateExitingIdle: + return "exitingIdle" + default: + return "unknown" + } +} + // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or // ctx expires. A true value is returned in former case and false in latter. // @@ -539,7 +748,10 @@ func (cc *ClientConn) GetState() connectivity.State { // Notice: This API is EXPERIMENTAL and may be changed or removed in a later // release. func (cc *ClientConn) Connect() { - cc.balancerWrapper.exitIdle() + cc.exitIdleMode() + // If the ClientConn was not in idle mode, we need to call ExitIdle on the + // LB policy so that connections can be created. + cc.balancerWrapper.exitIdleMode() } func (cc *ClientConn) scWatcher() { @@ -588,6 +800,10 @@ func init() { panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err)) } emptyServiceConfig = cfg.Config.(*ServiceConfig) + + internal.SubscribeToConnectivityStateChanges = func(cc *ClientConn, s grpcsync.Subscriber) func() { + return cc.csMgr.pubSub.Subscribe(s) + } } func (cc *ClientConn) maybeApplyDefaultServiceConfig(addrs []resolver.Address) { @@ -696,6 +912,20 @@ func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivi cc.balancerWrapper.updateSubConnState(sc, s, err) } +// Makes a copy of the input addresses slice and clears out the balancer +// attributes field. Addresses are passed during subconn creation and address +// update operations. In both cases, we will clear the balancer attributes by +// calling this function, and therefore we will be able to use the Equal method +// provided by the resolver.Address type for comparison. +func copyAddressesWithoutBalancerAttributes(in []resolver.Address) []resolver.Address { + out := make([]resolver.Address, len(in)) + for i := range in { + out[i] = in[i] + out[i].BalancerAttributes = nil + } + return out +} + // newAddrConn creates an addrConn for addrs and adds it to cc.conns. // // Caller needs to make sure len(addrs) > 0. @@ -703,11 +933,12 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSub ac := &addrConn{ state: connectivity.Idle, cc: cc, - addrs: addrs, + addrs: copyAddressesWithoutBalancerAttributes(addrs), scopts: opts, dopts: cc.dopts, czData: new(channelzData), resetBackoff: make(chan struct{}), + stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) // Track ac in cc. This needs to be done before any getTransport(...) is called. @@ -788,16 +1019,19 @@ func (cc *ClientConn) incrCallsFailed() { func (ac *addrConn) connect() error { ac.mu.Lock() if ac.state == connectivity.Shutdown { + if logger.V(2) { + logger.Infof("connect called on shutdown addrConn; ignoring.") + } ac.mu.Unlock() return errConnClosing } if ac.state != connectivity.Idle { + if logger.V(2) { + logger.Infof("connect called on addrConn in non-idle state (%v); ignoring.", ac.state) + } ac.mu.Unlock() return nil } - // Update connectivity state within the lock to prevent subsequent or - // concurrent calls from resetting the transport more than once. - ac.updateConnectivityState(connectivity.Connecting, nil) ac.mu.Unlock() ac.resetTransport() @@ -816,58 +1050,63 @@ func equalAddresses(a, b []resolver.Address) bool { return true } -// tryUpdateAddrs tries to update ac.addrs with the new addresses list. -// -// If ac is TransientFailure, it updates ac.addrs and returns true. The updated -// addresses will be picked up by retry in the next iteration after backoff. -// -// If ac is Shutdown or Idle, it updates ac.addrs and returns true. -// -// If the addresses is the same as the old list, it does nothing and returns -// true. -// -// If ac is Connecting, it returns false. The caller should tear down the ac and -// create a new one. Note that the backoff will be reset when this happens. -// -// If ac is Ready, it checks whether current connected address of ac is in the -// new addrs list. -// - If true, it updates ac.addrs and returns true. The ac will keep using -// the existing connection. -// - If false, it does nothing and returns false. -func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { +// updateAddrs updates ac.addrs with the new addresses list and handles active +// connections or connection attempts. +func (ac *addrConn) updateAddrs(addrs []resolver.Address) { ac.mu.Lock() - defer ac.mu.Unlock() - channelz.Infof(logger, ac.channelzID, "addrConn: tryUpdateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs) + channelz.Infof(logger, ac.channelzID, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) + + addrs = copyAddressesWithoutBalancerAttributes(addrs) + if equalAddresses(ac.addrs, addrs) { + ac.mu.Unlock() + return + } + + ac.addrs = addrs + if ac.state == connectivity.Shutdown || ac.state == connectivity.TransientFailure || ac.state == connectivity.Idle { - ac.addrs = addrs - return true + // We were not connecting, so do nothing but update the addresses. + ac.mu.Unlock() + return } - if equalAddresses(ac.addrs, addrs) { - return true + if ac.state == connectivity.Ready { + // Try to find the connected address. + for _, a := range addrs { + a.ServerName = ac.cc.getServerName(a) + if a.Equal(ac.curAddr) { + // We are connected to a valid address, so do nothing but + // update the addresses. + ac.mu.Unlock() + return + } + } } - if ac.state == connectivity.Connecting { - return false - } + // We are either connected to the wrong address or currently connecting. + // Stop the current iteration and restart. - // ac.state is Ready, try to find the connected address. - var curAddrFound bool - for _, a := range addrs { - a.ServerName = ac.cc.getServerName(a) - if reflect.DeepEqual(ac.curAddr, a) { - curAddrFound = true - break - } + ac.cancel() + ac.ctx, ac.cancel = context.WithCancel(ac.cc.ctx) + + // We have to defer here because GracefulClose => onClose, which requires + // locking ac.mu. + if ac.transport != nil { + defer ac.transport.GracefulClose() + ac.transport = nil } - channelz.Infof(logger, ac.channelzID, "addrConn: tryUpdateAddrs curAddrFound: %v", curAddrFound) - if curAddrFound { - ac.addrs = addrs + + if len(addrs) == 0 { + ac.updateConnectivityState(connectivity.Idle, nil) } - return curAddrFound + ac.mu.Unlock() + + // Since we were connecting/connected, we should start a new connection + // attempt. + go ac.resetTransport() } // getServerName determines the serverName to be used in the connection @@ -928,7 +1167,7 @@ func (cc *ClientConn) healthCheckConfig() *healthCheckConfig { return cc.sc.healthCheckConfig } -func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, func(balancer.DoneInfo), error) { +func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, balancer.PickResult, error) { return cc.blockingpicker.pick(ctx, failfast, balancer.PickInfo{ Ctx: ctx, FullMethodName: method, @@ -958,23 +1197,13 @@ func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSel } var newBalancerName string - if cc.sc != nil && cc.sc.lbConfig != nil { + if cc.sc == nil || (cc.sc.lbConfig == nil && cc.sc.LB == nil) { + // No service config or no LB policy specified in config. + newBalancerName = PickFirstBalancerName + } else if cc.sc.lbConfig != nil { newBalancerName = cc.sc.lbConfig.name - } else { - var isGRPCLB bool - for _, a := range addrs { - if a.Type == resolver.GRPCLB { - isGRPCLB = true - break - } - } - if isGRPCLB { - newBalancerName = grpclbName - } else if cc.sc != nil && cc.sc.LB != nil { - newBalancerName = *cc.sc.LB - } else { - newBalancerName = PickFirstBalancerName - } + } else { // cc.sc.LB != nil + newBalancerName = *cc.sc.LB } cc.balancerWrapper.switchTo(newBalancerName) } @@ -1013,46 +1242,50 @@ func (cc *ClientConn) ResetConnectBackoff() { // Close tears down the ClientConn and all underlying connections. func (cc *ClientConn) Close() error { - defer cc.cancel() + defer func() { + cc.cancel() + <-cc.csMgr.pubSub.Done() + }() cc.mu.Lock() if cc.conns == nil { cc.mu.Unlock() return ErrClientConnClosing } + + for cc.idlenessState == ccIdlenessStateExitingIdle { + cc.exitIdleCond.Wait() + } + conns := cc.conns cc.conns = nil cc.csMgr.updateState(connectivity.Shutdown) + pWrapper := cc.blockingpicker rWrapper := cc.resolverWrapper - cc.resolverWrapper = nil bWrapper := cc.balancerWrapper + idlenessMgr := cc.idlenessMgr cc.mu.Unlock() // The order of closing matters here since the balancer wrapper assumes the // picker is closed before it is closed. - cc.blockingpicker.close() + if pWrapper != nil { + pWrapper.close() + } if bWrapper != nil { bWrapper.close() } if rWrapper != nil { rWrapper.close() } + if idlenessMgr != nil { + idlenessMgr.Close() + } for ac := range conns { ac.tearDown(ErrClientConnClosing) } - ted := &channelz.TraceEventDesc{ - Desc: "Channel deleted", - Severity: channelz.CtInfo, - } - if cc.dopts.channelzParentID != nil { - ted.Parent = &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Nested channel(id:%d) deleted", cc.channelzID.Int()), - Severity: channelz.CtInfo, - } - } - channelz.AddTraceEvent(logger, cc.channelzID, 0, ted) + cc.addTraceEvent("deleted") // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from being // deleted right away. @@ -1082,7 +1315,8 @@ type addrConn struct { addrs []resolver.Address // All addresses that the resolver resolved to. // Use updateConnectivityState for updating addrConn's connectivity state. - state connectivity.State + state connectivity.State + stateChan chan struct{} // closed and recreated on every state change. backoffIdx int // Needs to be stateful for resetConnectBackoff. resetBackoff chan struct{} @@ -1096,8 +1330,15 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error) if ac.state == s { return } + // When changing states, reset the state change channel. + close(ac.stateChan) + ac.stateChan = make(chan struct{}) ac.state = s - channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s) + if lastErr == nil { + channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s) + } else { + channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) + } ac.cc.handleSubConnStateChange(ac.acbw, s, lastErr) } @@ -1117,7 +1358,8 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { func (ac *addrConn) resetTransport() { ac.mu.Lock() - if ac.state == connectivity.Shutdown { + acCtx := ac.ctx + if acCtx.Err() != nil { ac.mu.Unlock() return } @@ -1145,15 +1387,16 @@ func (ac *addrConn) resetTransport() { ac.updateConnectivityState(connectivity.Connecting, nil) ac.mu.Unlock() - if err := ac.tryAllAddrs(addrs, connectDeadline); err != nil { + if err := ac.tryAllAddrs(acCtx, addrs, connectDeadline); err != nil { ac.cc.resolveNow(resolver.ResolveNowOptions{}) - // After exhausting all addresses, the addrConn enters - // TRANSIENT_FAILURE. ac.mu.Lock() - if ac.state == connectivity.Shutdown { + if acCtx.Err() != nil { + // addrConn was torn down. ac.mu.Unlock() return } + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. ac.updateConnectivityState(connectivity.TransientFailure, err) // Backoff. @@ -1168,13 +1411,13 @@ func (ac *addrConn) resetTransport() { ac.mu.Unlock() case <-b: timer.Stop() - case <-ac.ctx.Done(): + case <-acCtx.Done(): timer.Stop() return } ac.mu.Lock() - if ac.state != connectivity.Shutdown { + if acCtx.Err() == nil { ac.updateConnectivityState(connectivity.Idle, err) } ac.mu.Unlock() @@ -1189,14 +1432,13 @@ func (ac *addrConn) resetTransport() { // tryAllAddrs tries to creates a connection to the addresses, and stop when at // the first successful one. It returns an error if no address was successfully // connected, or updates ac appropriately with the new transport. -func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) error { +func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, connectDeadline time.Time) error { var firstConnErr error for _, addr := range addrs { - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() + if ctx.Err() != nil { return errConnClosing } + ac.mu.Lock() ac.cc.mu.RLock() ac.dopts.copts.KeepaliveParams = ac.cc.mkp @@ -1210,7 +1452,7 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T channelz.Infof(logger, ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr) - err := ac.createTransport(addr, copts, connectDeadline) + err := ac.createTransport(ctx, addr, copts, connectDeadline) if err == nil { return nil } @@ -1227,17 +1469,20 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T // createTransport creates a connection to addr. It returns an error if the // address was not successfully connected, or updates ac appropriately with the // new transport. -func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { +func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { addr.ServerName = ac.cc.getServerName(addr) - hctx, hcancel := context.WithCancel(ac.ctx) + hctx, hcancel := context.WithCancel(ctx) - onClose := grpcsync.OnceFunc(func() { + onClose := func(r transport.GoAwayReason) { ac.mu.Lock() defer ac.mu.Unlock() - if ac.state == connectivity.Shutdown { - // Already shut down. tearDown() already cleared the transport and - // canceled hctx via ac.ctx, and we expected this connection to be - // closed, so do nothing here. + // adjust params based on GoAwayReason + ac.adjustParams(r) + if ctx.Err() != nil { + // Already shut down or connection attempt canceled. tearDown() or + // updateAddrs() already cleared the transport and canceled hctx + // via ac.ctx, and we expected this connection to be closed, so do + // nothing here. return } hcancel() @@ -1254,20 +1499,17 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne // Always go idle and wait for the LB policy to initiate a new // connection attempt. ac.updateConnectivityState(connectivity.Idle, nil) - }) - onGoAway := func(r transport.GoAwayReason) { - ac.mu.Lock() - ac.adjustParams(r) - ac.mu.Unlock() - onClose() } - connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) + connectCtx, cancel := context.WithDeadline(ctx, connectDeadline) defer cancel() copts.ChannelzParentID = ac.channelzID - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onGoAway, onClose) + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onClose) if err != nil { + if logger.V(2) { + logger.Infof("Creating new client transport to %q: %v", addr, err) + } // newTr is either nil, or closed. hcancel() channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) @@ -1276,7 +1518,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne ac.mu.Lock() defer ac.mu.Unlock() - if ac.state == connectivity.Shutdown { + if ctx.Err() != nil { // This can happen if the subConn was removed while in `Connecting` // state. tearDown() would have set the state to `Shutdown`, but // would not have closed the transport since ac.transport would not @@ -1288,6 +1530,9 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne // The error we pass to Close() is immaterial since there are no open // streams at this point, so no trailers with error details will be sent // out. We just need to pass a non-nil error. + // + // This can also happen when updateAddrs is called during a connection + // attempt. go newTr.Close(transport.ErrConnClosing) return nil } @@ -1347,7 +1592,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { // Set up the health check helper functions. currentTr := ac.transport - newStream := func(method string) (interface{}, error) { + newStream := func(method string) (any, error) { ac.mu.Lock() if ac.transport != currentTr { ac.mu.Unlock() @@ -1371,7 +1616,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { if status.Code(err) == codes.Unimplemented { channelz.Error(logger, ac.channelzID, "Subchannel health check is unimplemented at server side, thus health check is disabled") } else { - channelz.Errorf(logger, ac.channelzID, "HealthCheckFunc exits with unexpected error %v", err) + channelz.Errorf(logger, ac.channelzID, "Health checking failed: %v", err) } } }() @@ -1395,6 +1640,29 @@ func (ac *addrConn) getReadyTransport() transport.ClientTransport { return nil } +// getTransport waits until the addrconn is ready and returns the transport. +// If the context expires first, returns an appropriate status. If the +// addrConn is stopped first, returns an Unavailable status error. +func (ac *addrConn) getTransport(ctx context.Context) (transport.ClientTransport, error) { + for ctx.Err() == nil { + ac.mu.Lock() + t, state, sc := ac.transport, ac.state, ac.stateChan + ac.mu.Unlock() + if state == connectivity.Ready { + return t, nil + } + if state == connectivity.Shutdown { + return nil, status.Errorf(codes.Unavailable, "SubConn shutting down") + } + + select { + case <-ctx.Done(): + case <-sc: + } + } + return nil, status.FromContextError(ctx.Err()).Err() +} + // tearDown starts to tear down the addrConn. // // Note that tearDown doesn't remove ac from ac.cc.conns, so the addrConn struct @@ -1412,16 +1680,7 @@ func (ac *addrConn) tearDown(err error) { ac.updateConnectivityState(connectivity.Shutdown, nil) ac.cancel() ac.curAddr = resolver.Address{} - if err == errConnDrain && curTr != nil { - // GracefulClose(...) may be executed multiple times when - // i) receiving multiple GoAway frames from the server; or - // ii) there are concurrent name resolver/Balancer triggered - // address removal and GoAway. - // We have to unlock and re-lock here because GracefulClose => Close => onClose, which requires locking ac.mu. - ac.mu.Unlock() - curTr.GracefulClose() - ac.mu.Lock() - } + channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{ Desc: "Subchannel deleted", Severity: channelz.CtInfo, @@ -1435,6 +1694,29 @@ func (ac *addrConn) tearDown(err error) { // being deleted right away. channelz.RemoveEntry(ac.channelzID) ac.mu.Unlock() + + // We have to release the lock before the call to GracefulClose/Close here + // because both of them call onClose(), which requires locking ac.mu. + if curTr != nil { + if err == errConnDrain { + // Close the transport gracefully when the subConn is being shutdown. + // + // GracefulClose() may be executed multiple times if: + // - multiple GoAway frames are received from the server + // - there are concurrent name resolver or balancer triggered + // address removal and GoAway + curTr.GracefulClose() + } else { + // Hard close the transport when the channel is entering idle or is + // being shutdown. In the case where the channel is being shutdown, + // closing of transports is also taken care of by cancelation of cc.ctx. + // But in the case where the channel is entering idle, we need to + // explicitly close the transports here. Instead of distinguishing + // between these two cases, it is simpler to close the transport + // unconditionally here. + curTr.Close(err) + } + } } func (ac *addrConn) getState() connectivity.State { @@ -1522,6 +1804,9 @@ func (c *channelzChannel) ChannelzMetric() *channelz.ChannelInternalMetric { // referenced by users. var ErrClientConnTimeout = errors.New("grpc: timed out when dialing") +// getResolver finds the scheme in the cc's resolvers or the global registry. +// scheme should always be lowercase (typically by virtue of url.Parse() +// performing proper RFC3986 behavior). func (cc *ClientConn) getResolver(scheme string) resolver.Builder { for _, rb := range cc.dopts.resolvers { if scheme == rb.Scheme() { @@ -1543,7 +1828,14 @@ func (cc *ClientConn) connectionError() error { return cc.lastConnectionError } -func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { +// parseTargetAndFindResolver parses the user's dial target and stores the +// parsed target in `cc.parsedTarget`. +// +// The resolver to use is determined based on the scheme in the parsed target +// and the same is stored in `cc.resolverBuilder`. +// +// Doesn't grab cc.mu as this method is expected to be called only at Dial time. +func (cc *ClientConn) parseTargetAndFindResolver() error { channelz.Infof(logger, cc.channelzID, "original dial target is: %q", cc.target) var rb resolver.Builder @@ -1555,7 +1847,8 @@ func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { rb = cc.getResolver(parsedTarget.URL.Scheme) if rb != nil { cc.parsedTarget = parsedTarget - return rb, nil + cc.resolverBuilder = rb + return nil } } @@ -1570,51 +1863,98 @@ func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { parsedTarget, err = parseTarget(canonicalTarget) if err != nil { channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", canonicalTarget, err) - return nil, err + return err } channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb == nil { - return nil, fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) + return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) } cc.parsedTarget = parsedTarget - return rb, nil + cc.resolverBuilder = rb + return nil } // parseTarget uses RFC 3986 semantics to parse the given target into a -// resolver.Target struct containing scheme, authority and endpoint. Query -// params are stripped from the endpoint. +// resolver.Target struct containing url. Query params are stripped from the +// endpoint. func parseTarget(target string) (resolver.Target, error) { u, err := url.Parse(target) if err != nil { return resolver.Target{}, err } - // For targets of the form "[scheme]://[authority]/endpoint, the endpoint - // value returned from url.Parse() contains a leading "/". Although this is - // in accordance with RFC 3986, we do not want to break existing resolver - // implementations which expect the endpoint without the leading "/". So, we - // end up stripping the leading "/" here. But this will result in an - // incorrect parsing for something like "unix:///path/to/socket". Since we - // own the "unix" resolver, we can workaround in the unix resolver by using - // the `URL` field instead of the `Endpoint` field. - endpoint := u.Path - if endpoint == "" { - endpoint = u.Opaque - } - endpoint = strings.TrimPrefix(endpoint, "/") - return resolver.Target{ - Scheme: u.Scheme, - Authority: u.Host, - Endpoint: endpoint, - URL: *u, - }, nil + + return resolver.Target{URL: *u}, nil +} + +func encodeAuthority(authority string) string { + const upperhex = "0123456789ABCDEF" + + // Return for characters that must be escaped as per + // Valid chars are mentioned here: + // https://datatracker.ietf.org/doc/html/rfc3986#section-3.2 + shouldEscape := func(c byte) bool { + // Alphanum are always allowed. + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { + return false + } + switch c { + case '-', '_', '.', '~': // Unreserved characters + return false + case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // Subdelim characters + return false + case ':', '[', ']', '@': // Authority related delimeters + return false + } + // Everything else must be escaped. + return true + } + + hexCount := 0 + for i := 0; i < len(authority); i++ { + c := authority[i] + if shouldEscape(c) { + hexCount++ + } + } + + if hexCount == 0 { + return authority + } + + required := len(authority) + 2*hexCount + t := make([]byte, required) + + j := 0 + // This logic is a barebones version of escape in the go net/url library. + for i := 0; i < len(authority); i++ { + switch c := authority[i]; { + case shouldEscape(c): + t[j] = '%' + t[j+1] = upperhex[c>>4] + t[j+2] = upperhex[c&15] + j += 3 + default: + t[j] = authority[i] + j++ + } + } + return string(t) } // Determine channel authority. The order of precedence is as follows: // - user specified authority override using `WithAuthority` dial option // - creds' notion of server name for the authentication handshake // - endpoint from dial target of the form "scheme://[authority]/endpoint" -func determineAuthority(endpoint, target string, dopts dialOptions) (string, error) { +// +// Stores the determined authority in `cc.authority`. +// +// Returns a non-nil error if the authority returned by the transport +// credentials do not match the authority configured through the dial option. +// +// Doesn't grab cc.mu as this method is expected to be called only at Dial time. +func (cc *ClientConn) determineAuthority() error { + dopts := cc.dopts // Historically, we had two options for users to specify the serverName or // authority for a channel. One was through the transport credentials // (either in its constructor, or through the OverrideServerName() method). @@ -1631,25 +1971,62 @@ func determineAuthority(endpoint, target string, dopts dialOptions) (string, err } authorityFromDialOption := dopts.authority if (authorityFromCreds != "" && authorityFromDialOption != "") && authorityFromCreds != authorityFromDialOption { - return "", fmt.Errorf("ClientConn's authority from transport creds %q and dial option %q don't match", authorityFromCreds, authorityFromDialOption) + return fmt.Errorf("ClientConn's authority from transport creds %q and dial option %q don't match", authorityFromCreds, authorityFromDialOption) } + endpoint := cc.parsedTarget.Endpoint() + target := cc.target switch { case authorityFromDialOption != "": - return authorityFromDialOption, nil + cc.authority = authorityFromDialOption case authorityFromCreds != "": - return authorityFromCreds, nil + cc.authority = authorityFromCreds case strings.HasPrefix(target, "unix:") || strings.HasPrefix(target, "unix-abstract:"): // TODO: remove when the unix resolver implements optional interface to // return channel authority. - return "localhost", nil + cc.authority = "localhost" case strings.HasPrefix(endpoint, ":"): - return "localhost" + endpoint, nil + cc.authority = "localhost" + endpoint default: // TODO: Define an optional interface on the resolver builder to return // the channel authority given the user's dial target. For resolvers // which don't implement this interface, we will use the endpoint from // "scheme://authority/endpoint" as the default authority. - return endpoint, nil + // Escape the endpoint to handle use cases where the endpoint + // might not be a valid authority by default. + // For example an endpoint which has multiple paths like + // 'a/b/c', which is not a valid authority by default. + cc.authority = encodeAuthority(endpoint) } + channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority) + return nil +} + +// initResolverWrapper creates a ccResolverWrapper, which builds the name +// resolver. This method grabs the lock to assign the newly built resolver +// wrapper to the cc.resolverWrapper field. +func (cc *ClientConn) initResolverWrapper(creds credentials.TransportCredentials) error { + rw, err := newCCResolverWrapper(cc, ccResolverWrapperOpts{ + target: cc.parsedTarget, + builder: cc.resolverBuilder, + bOpts: resolver.BuildOptions{ + DisableServiceConfig: cc.dopts.disableServiceConfig, + DialCreds: creds, + CredsBundle: cc.dopts.copts.CredsBundle, + Dialer: cc.dopts.copts.Dialer, + }, + channelzID: cc.channelzID, + }) + if err != nil { + return fmt.Errorf("failed to build resolver: %v", err) + } + // Resolver implementations may report state update or error inline when + // built (or right after), and this is handled in cc.updateResolverState. + // Also, an error from the resolver might lead to a re-resolution request + // from the balancer, which is handled in resolveNow() where + // `cc.resolverWrapper` is accessed. Hence, we need to hold the lock here. + cc.mu.Lock() + cc.resolverWrapper = rw + cc.mu.Unlock() + return nil } diff --git a/vendor/google.golang.org/grpc/codec.go b/vendor/google.golang.org/grpc/codec.go index 12977654781..411e3dfd47c 100644 --- a/vendor/google.golang.org/grpc/codec.go +++ b/vendor/google.golang.org/grpc/codec.go @@ -27,8 +27,8 @@ import ( // omits the name/string, which vary between the two and are not needed for // anything besides the registry in the encoding package. type baseCodec interface { - Marshal(v interface{}) ([]byte, error) - Unmarshal(data []byte, v interface{}) error + Marshal(v any) ([]byte, error) + Unmarshal(data []byte, v any) error } var _ baseCodec = Codec(nil) @@ -41,9 +41,9 @@ var _ baseCodec = encoding.Codec(nil) // Deprecated: use encoding.Codec instead. type Codec interface { // Marshal returns the wire format of v. - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) // Unmarshal parses the wire format into v. - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error // String returns the name of the Codec implementation. This is unused by // gRPC. String() string diff --git a/vendor/google.golang.org/grpc/codes/code_string.go b/vendor/google.golang.org/grpc/codes/code_string.go index 0b206a57822..934fac2b090 100644 --- a/vendor/google.golang.org/grpc/codes/code_string.go +++ b/vendor/google.golang.org/grpc/codes/code_string.go @@ -18,7 +18,15 @@ package codes -import "strconv" +import ( + "strconv" + + "google.golang.org/grpc/internal" +) + +func init() { + internal.CanonicalString = canonicalString +} func (c Code) String() string { switch c { @@ -60,3 +68,44 @@ func (c Code) String() string { return "Code(" + strconv.FormatInt(int64(c), 10) + ")" } } + +func canonicalString(c Code) string { + switch c { + case OK: + return "OK" + case Canceled: + return "CANCELLED" + case Unknown: + return "UNKNOWN" + case InvalidArgument: + return "INVALID_ARGUMENT" + case DeadlineExceeded: + return "DEADLINE_EXCEEDED" + case NotFound: + return "NOT_FOUND" + case AlreadyExists: + return "ALREADY_EXISTS" + case PermissionDenied: + return "PERMISSION_DENIED" + case ResourceExhausted: + return "RESOURCE_EXHAUSTED" + case FailedPrecondition: + return "FAILED_PRECONDITION" + case Aborted: + return "ABORTED" + case OutOfRange: + return "OUT_OF_RANGE" + case Unimplemented: + return "UNIMPLEMENTED" + case Internal: + return "INTERNAL" + case Unavailable: + return "UNAVAILABLE" + case DataLoss: + return "DATA_LOSS" + case Unauthenticated: + return "UNAUTHENTICATED" + default: + return "CODE(" + strconv.FormatInt(int64(c), 10) + ")" + } +} diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go b/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go index 7b953a520e5..0854e7af651 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/handshaker.go @@ -25,8 +25,8 @@ import ( "fmt" "io" "net" - "sync" + "golang.org/x/sync/semaphore" grpc "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -35,15 +35,13 @@ import ( "google.golang.org/grpc/credentials/alts/internal/conn" altsgrpc "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp" altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp" + "google.golang.org/grpc/internal/envconfig" ) const ( // The maximum byte size of receive frames. frameLimit = 64 * 1024 // 64 KB rekeyRecordProtocolName = "ALTSRP_GCM_AES128_REKEY" - // maxPendingHandshakes represents the maximum number of concurrent - // handshakes. - maxPendingHandshakes = 100 ) var ( @@ -59,9 +57,9 @@ var ( return conn.NewAES128GCMRekey(s, keyData) }, } - // control number of concurrent created (but not closed) handshakers. - mu sync.Mutex - concurrentHandshakes = int64(0) + // control number of concurrent created (but not closed) handshakes. + clientHandshakes = semaphore.NewWeighted(int64(envconfig.ALTSMaxConcurrentHandshakes)) + serverHandshakes = semaphore.NewWeighted(int64(envconfig.ALTSMaxConcurrentHandshakes)) // errDropped occurs when maxPendingHandshakes is reached. errDropped = errors.New("maximum number of concurrent ALTS handshakes is reached") // errOutOfBound occurs when the handshake service returns a consumed @@ -77,30 +75,6 @@ func init() { } } -func acquire() bool { - mu.Lock() - // If we need n to be configurable, we can pass it as an argument. - n := int64(1) - success := maxPendingHandshakes-concurrentHandshakes >= n - if success { - concurrentHandshakes += n - } - mu.Unlock() - return success -} - -func release() { - mu.Lock() - // If we need n to be configurable, we can pass it as an argument. - n := int64(1) - concurrentHandshakes -= n - if concurrentHandshakes < 0 { - mu.Unlock() - panic("bad release") - } - mu.Unlock() -} - // ClientHandshakerOptions contains the client handshaker options that can // provided by the caller. type ClientHandshakerOptions struct { @@ -134,11 +108,7 @@ func DefaultServerHandshakerOptions() *ServerHandshakerOptions { return &ServerHandshakerOptions{} } -// TODO: add support for future local and remote endpoint in both client options -// and server options (server options struct does not exist now. When -// caller can provide endpoints, it should be created. - -// altsHandshaker is used to complete a ALTS handshaking between client and +// altsHandshaker is used to complete an ALTS handshake between client and // server. This handshaker talks to the ALTS handshaker service in the metadata // server. type altsHandshaker struct { @@ -146,6 +116,8 @@ type altsHandshaker struct { stream altsgrpc.HandshakerService_DoHandshakeClient // the connection to the peer. conn net.Conn + // a virtual connection to the ALTS handshaker service. + clientConn *grpc.ClientConn // client handshake options. clientOpts *ClientHandshakerOptions // server handshake options. @@ -154,50 +126,54 @@ type altsHandshaker struct { side core.Side } -// NewClientHandshaker creates a ALTS handshaker for GCP which contains an RPC -// stub created using the passed conn and used to talk to the ALTS Handshaker +// NewClientHandshaker creates a core.Handshaker that performs a client-side +// ALTS handshake by acting as a proxy between the peer and the ALTS handshaker // service in the metadata server. func NewClientHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, opts *ClientHandshakerOptions) (core.Handshaker, error) { - stream, err := altsgrpc.NewHandshakerServiceClient(conn).DoHandshake(ctx) - if err != nil { - return nil, err - } return &altsHandshaker{ - stream: stream, + stream: nil, conn: c, + clientConn: conn, clientOpts: opts, side: core.ClientSide, }, nil } -// NewServerHandshaker creates a ALTS handshaker for GCP which contains an RPC -// stub created using the passed conn and used to talk to the ALTS Handshaker +// NewServerHandshaker creates a core.Handshaker that performs a server-side +// ALTS handshake by acting as a proxy between the peer and the ALTS handshaker // service in the metadata server. func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, opts *ServerHandshakerOptions) (core.Handshaker, error) { - stream, err := altsgrpc.NewHandshakerServiceClient(conn).DoHandshake(ctx) - if err != nil { - return nil, err - } return &altsHandshaker{ - stream: stream, + stream: nil, conn: c, + clientConn: conn, serverOpts: opts, side: core.ServerSide, }, nil } -// ClientHandshake starts and completes a client ALTS handshaking for GCP. Once +// ClientHandshake starts and completes a client ALTS handshake for GCP. Once // done, ClientHandshake returns a secure connection. func (h *altsHandshaker) ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) { - if !acquire() { + if !clientHandshakes.TryAcquire(1) { return nil, nil, errDropped } - defer release() + defer clientHandshakes.Release(1) if h.side != core.ClientSide { return nil, nil, errors.New("only handshakers created using NewClientHandshaker can perform a client handshaker") } + // TODO(matthewstevenson88): Change unit tests to use public APIs so + // that h.stream can unconditionally be set based on h.clientConn. + if h.stream == nil { + stream, err := altsgrpc.NewHandshakerServiceClient(h.clientConn).DoHandshake(ctx) + if err != nil { + return nil, nil, fmt.Errorf("failed to establish stream to ALTS handshaker service: %v", err) + } + h.stream = stream + } + // Create target identities from service account list. targetIdentities := make([]*altspb.Identity, 0, len(h.clientOpts.TargetServiceAccounts)) for _, account := range h.clientOpts.TargetServiceAccounts { @@ -229,18 +205,28 @@ func (h *altsHandshaker) ClientHandshake(ctx context.Context) (net.Conn, credent return conn, authInfo, nil } -// ServerHandshake starts and completes a server ALTS handshaking for GCP. Once +// ServerHandshake starts and completes a server ALTS handshake for GCP. Once // done, ServerHandshake returns a secure connection. func (h *altsHandshaker) ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error) { - if !acquire() { + if !serverHandshakes.TryAcquire(1) { return nil, nil, errDropped } - defer release() + defer serverHandshakes.Release(1) if h.side != core.ServerSide { return nil, nil, errors.New("only handshakers created using NewServerHandshaker can perform a server handshaker") } + // TODO(matthewstevenson88): Change unit tests to use public APIs so + // that h.stream can unconditionally be set based on h.clientConn. + if h.stream == nil { + stream, err := altsgrpc.NewHandshakerServiceClient(h.clientConn).DoHandshake(ctx) + if err != nil { + return nil, nil, fmt.Errorf("failed to establish stream to ALTS handshaker service: %v", err) + } + h.stream = stream + } + p := make([]byte, frameLimit) n, err := h.conn.Read(p) if err != nil { @@ -248,8 +234,6 @@ func (h *altsHandshaker) ServerHandshake(ctx context.Context) (net.Conn, credent } // Prepare server parameters. - // TODO: currently only ALTS parameters are provided. Might need to use - // more options in the future. params := make(map[int32]*altspb.ServerHandshakeParameters) params[int32(altspb.HandshakeProtocol_ALTS)] = &altspb.ServerHandshakeParameters{ RecordProtocols: recordProtocols, @@ -371,5 +355,14 @@ func (h *altsHandshaker) processUntilDone(resp *altspb.HandshakerResp, extra []b // Close terminates the Handshaker. It should be called when the caller obtains // the secure connection. func (h *altsHandshaker) Close() { - h.stream.CloseSend() + if h.stream != nil { + h.stream.CloseSend() + } +} + +// ResetConcurrentHandshakeSemaphoreForTesting resets the handshake semaphores +// to allow numberOfAllowedHandshakes concurrent handshakes each. +func ResetConcurrentHandshakeSemaphoreForTesting(numberOfAllowedHandshakes int64) { + clientHandshakes = semaphore.NewWeighted(numberOfAllowedHandshakes) + serverHandshakes = semaphore.NewWeighted(numberOfAllowedHandshakes) } diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go b/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go index 2de2c4affda..e1cdafb980c 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/handshaker/service/service.go @@ -58,3 +58,21 @@ func Dial(hsAddress string) (*grpc.ClientConn, error) { } return hsConn, nil } + +// CloseForTesting closes all open connections to the handshaker service. +// +// For testing purposes only. +func CloseForTesting() error { + for _, hsConn := range hsConnMap { + if hsConn == nil { + continue + } + if err := hsConn.Close(); err != nil { + return err + } + } + + // Reset the connection map. + hsConnMap = make(map[string]*grpc.ClientConn) + return nil +} diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go index 703b48da753..c7cf1810a19 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go @@ -17,14 +17,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.31.0 +// protoc v4.22.0 // source: grpc/gcp/altscontext.proto package grpc_gcp import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -38,10 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type AltsContext struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go index 383c5fb97a7..81d0f114084 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go @@ -17,14 +17,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.31.0 +// protoc v4.22.0 // source: grpc/gcp/handshaker.proto package grpc_gcp import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -38,10 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type HandshakeProtocol int32 const ( diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go index d3562c6d5e6..39ecccf878e 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go @@ -17,8 +17,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.14.0 +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.22.0 // source: grpc/gcp/handshaker.proto package grpc_gcp @@ -35,6 +35,10 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + HandshakerService_DoHandshake_FullMethodName = "/grpc.gcp.HandshakerService/DoHandshake" +) + // HandshakerServiceClient is the client API for HandshakerService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -57,7 +61,7 @@ func NewHandshakerServiceClient(cc grpc.ClientConnInterface) HandshakerServiceCl } func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) { - stream, err := c.cc.NewStream(ctx, &HandshakerService_ServiceDesc.Streams[0], "/grpc.gcp.HandshakerService/DoHandshake", opts...) + stream, err := c.cc.NewStream(ctx, &HandshakerService_ServiceDesc.Streams[0], HandshakerService_DoHandshake_FullMethodName, opts...) if err != nil { return nil, err } diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go index 4fc3c79d6a3..69f0947582d 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go @@ -17,14 +17,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.31.0 +// protoc v4.22.0 // source: grpc/gcp/transport_security_common.proto package grpc_gcp import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -38,10 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // The security level of the created channel. The list is sorted in increasing // level of security. This order must always be maintained. type SecurityLevel int32 diff --git a/vendor/google.golang.org/grpc/credentials/oauth/oauth.go b/vendor/google.golang.org/grpc/credentials/oauth/oauth.go index c748fd21ce2..d475cbc0894 100644 --- a/vendor/google.golang.org/grpc/credentials/oauth/oauth.go +++ b/vendor/google.golang.org/grpc/credentials/oauth/oauth.go @@ -22,8 +22,8 @@ package oauth import ( "context" "fmt" - "io/ioutil" "net/url" + "os" "sync" "golang.org/x/oauth2" @@ -73,7 +73,7 @@ type jwtAccess struct { // NewJWTAccessFromFile creates PerRPCCredentials from the given keyFile. func NewJWTAccessFromFile(keyFile string) (credentials.PerRPCCredentials, error) { - jsonKey, err := ioutil.ReadFile(keyFile) + jsonKey, err := os.ReadFile(keyFile) if err != nil { return nil, fmt.Errorf("credentials: failed to read the service account key file: %v", err) } @@ -121,6 +121,8 @@ type oauthAccess struct { } // NewOauthAccess constructs the PerRPCCredentials using a given token. +// +// Deprecated: use oauth.TokenSource instead. func NewOauthAccess(token *oauth2.Token) credentials.PerRPCCredentials { return oauthAccess{token: *token} } @@ -190,7 +192,7 @@ func NewServiceAccountFromKey(jsonKey []byte, scope ...string) (credentials.PerR // NewServiceAccountFromFile constructs the PerRPCCredentials using the JSON key file // of a Google Developers service account. func NewServiceAccountFromFile(keyFile string, scope ...string) (credentials.PerRPCCredentials, error) { - jsonKey, err := ioutil.ReadFile(keyFile) + jsonKey, err := os.ReadFile(keyFile) if err != nil { return nil, fmt.Errorf("credentials: failed to read the service account key file: %v", err) } diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index ce2bbc10a14..877b7cd21af 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -23,9 +23,9 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" "net" "net/url" + "os" credinternal "google.golang.org/grpc/internal/credentials" ) @@ -166,7 +166,7 @@ func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) Transpor // it will override the virtual host name of authority (e.g. :authority header // field) in requests. func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) { - b, err := ioutil.ReadFile(certFile) + b, err := os.ReadFile(certFile) if err != nil { return nil, err } diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 9372dc322e8..1fd0d5c127f 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -38,12 +38,14 @@ import ( func init() { internal.AddGlobalDialOptions = func(opt ...DialOption) { - extraDialOptions = append(extraDialOptions, opt...) + globalDialOptions = append(globalDialOptions, opt...) } internal.ClearGlobalDialOptions = func() { - extraDialOptions = nil + globalDialOptions = nil } internal.WithBinaryLogger = withBinaryLogger + internal.JoinDialOptions = newJoinDialOption + internal.DisableGlobalDialOptions = newDisableGlobalDialOptions } // dialOptions configure a Dial call. dialOptions are set by the DialOption @@ -75,6 +77,8 @@ type dialOptions struct { defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON. defaultServiceConfigRawJSON *string resolvers []resolver.Builder + idleTimeout time.Duration + recvBufferPool SharedBufferPool } // DialOption configures how we set up the connection. @@ -82,7 +86,7 @@ type DialOption interface { apply(*dialOptions) } -var extraDialOptions []DialOption +var globalDialOptions []DialOption // EmptyDialOption does not alter the dial configuration. It can be embedded in // another structure to build custom dial options. @@ -95,6 +99,16 @@ type EmptyDialOption struct{} func (EmptyDialOption) apply(*dialOptions) {} +type disableGlobalDialOptions struct{} + +func (disableGlobalDialOptions) apply(*dialOptions) {} + +// newDisableGlobalDialOptions returns a DialOption that prevents the ClientConn +// from applying the global DialOptions (set via AddGlobalDialOptions). +func newDisableGlobalDialOptions() DialOption { + return &disableGlobalDialOptions{} +} + // funcDialOption wraps a function that modifies dialOptions into an // implementation of the DialOption interface. type funcDialOption struct { @@ -111,13 +125,42 @@ func newFuncDialOption(f func(*dialOptions)) *funcDialOption { } } +type joinDialOption struct { + opts []DialOption +} + +func (jdo *joinDialOption) apply(do *dialOptions) { + for _, opt := range jdo.opts { + opt.apply(do) + } +} + +func newJoinDialOption(opts ...DialOption) DialOption { + return &joinDialOption{opts: opts} +} + +// WithSharedWriteBuffer allows reusing per-connection transport write buffer. +// If this option is set to true every connection will release the buffer after +// flushing the data on the wire. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WithSharedWriteBuffer(val bool) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.copts.SharedWriteBuffer = val + }) +} + // WithWriteBufferSize determines how much data can be batched before doing a // write on the wire. The corresponding memory allocation for this buffer will // be twice the size to keep syscalls low. The default value for this buffer is // 32KB. // -// Zero will disable the write buffer such that each write will be on underlying -// connection. Note: A Send call may not directly translate to a write. +// Zero or negative values will disable the write buffer such that each write +// will be on underlying connection. Note: A Send call may not directly +// translate to a write. func WithWriteBufferSize(s int) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.WriteBufferSize = s @@ -127,8 +170,9 @@ func WithWriteBufferSize(s int) DialOption { // WithReadBufferSize lets you set the size of read buffer, this determines how // much data can be read at most for each read syscall. // -// The default value for this buffer is 32KB. Zero will disable read buffer for -// a connection so data framer can access the underlying conn directly. +// The default value for this buffer is 32KB. Zero or negative values will +// disable read buffer for a connection so data framer can access the +// underlying conn directly. func WithReadBufferSize(s int) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.ReadBufferSize = s @@ -267,6 +311,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption { // WithBlock returns a DialOption which makes callers of Dial block until the // underlying connection is up. Without this, Dial returns immediately and // connecting the server happens in background. +// +// Use of this feature is not recommended. For more information, please see: +// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md func WithBlock() DialOption { return newFuncDialOption(func(o *dialOptions) { o.block = true @@ -278,6 +325,9 @@ func WithBlock() DialOption { // the context.DeadlineExceeded error. // Implies WithBlock() // +// Use of this feature is not recommended. For more information, please see: +// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md +// // # Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a @@ -420,6 +470,9 @@ func withBinaryLogger(bl binarylog.Logger) DialOption { // FailOnNonTempDialError only affects the initial dial, and does not do // anything useful unless you are also using WithBlock(). // +// Use of this feature is not recommended. For more information, please see: +// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md +// // # Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a @@ -590,6 +643,7 @@ func defaultDialOptions() dialOptions { ReadBufferSize: defaultReadBufSize, UseProxy: true, }, + recvBufferPool: nopBufferPool{}, } } @@ -618,3 +672,44 @@ func WithResolvers(rs ...resolver.Builder) DialOption { o.resolvers = append(o.resolvers, rs...) }) } + +// WithIdleTimeout returns a DialOption that configures an idle timeout for the +// channel. If the channel is idle for the configured timeout, i.e there are no +// ongoing RPCs and no new RPCs are initiated, the channel will enter idle mode +// and as a result the name resolver and load balancer will be shut down. The +// channel will exit idle mode when the Connect() method is called or when an +// RPC is initiated. +// +// By default this feature is disabled, which can also be explicitly configured +// by passing zero to this function. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WithIdleTimeout(d time.Duration) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.idleTimeout = d + }) +} + +// WithRecvBufferPool returns a DialOption that configures the ClientConn +// to use the provided shared buffer pool for parsing incoming messages. Depending +// on the application's workload, this could result in reduced memory allocation. +// +// If you are unsure about how to implement a memory pool but want to utilize one, +// begin with grpc.NewSharedBufferPool. +// +// Note: The shared buffer pool feature will not be active if any of the following +// options are used: WithStatsHandler, EnableTracing, or binary logging. In such +// cases, the shared buffer pool will be ignored. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.recvBufferPool = bufferPool + }) +} diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index 711763d54fb..69d5580b6ad 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -75,7 +75,9 @@ var registeredCompressor = make(map[string]Compressor) // registered with the same name, the one registered last will take effect. func RegisterCompressor(c Compressor) { registeredCompressor[c.Name()] = c - grpcutil.RegisteredCompressorNames = append(grpcutil.RegisteredCompressorNames, c.Name()) + if !grpcutil.IsCompressorNameRegistered(c.Name()) { + grpcutil.RegisteredCompressorNames = append(grpcutil.RegisteredCompressorNames, c.Name()) + } } // GetCompressor returns Compressor for the given compressor name. @@ -88,9 +90,9 @@ func GetCompressor(name string) Compressor { // methods can be called from concurrent goroutines. type Codec interface { // Marshal returns the wire format of v. - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) // Unmarshal parses the wire format into v. - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error // Name returns the name of the Codec implementation. The returned string // will be used as part of content type in transmission. The result must be // static; the result cannot change between calls. diff --git a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go index ca820bd47d4..6306e8bb0f0 100644 --- a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go +++ b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go @@ -30,7 +30,6 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" "sync" "google.golang.org/grpc/encoding" @@ -41,8 +40,8 @@ const Name = "gzip" func init() { c := &compressor{} - c.poolCompressor.New = func() interface{} { - return &writer{Writer: gzip.NewWriter(ioutil.Discard), pool: &c.poolCompressor} + c.poolCompressor.New = func() any { + return &writer{Writer: gzip.NewWriter(io.Discard), pool: &c.poolCompressor} } encoding.RegisterCompressor(c) } @@ -62,8 +61,8 @@ func SetLevel(level int) error { return fmt.Errorf("grpc: invalid gzip compression level: %d", level) } c := encoding.GetCompressor(Name).(*compressor) - c.poolCompressor.New = func() interface{} { - w, err := gzip.NewWriterLevel(ioutil.Discard, level) + c.poolCompressor.New = func() any { + w, err := gzip.NewWriterLevel(io.Discard, level) if err != nil { panic(err) } diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go index 3009b35afe7..0ee3d3bae97 100644 --- a/vendor/google.golang.org/grpc/encoding/proto/proto.go +++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go @@ -37,7 +37,7 @@ func init() { // codec is a Codec implementation with protobuf. It is the default codec for gRPC. type codec struct{} -func (codec) Marshal(v interface{}) ([]byte, error) { +func (codec) Marshal(v any) ([]byte, error) { vv, ok := v.(proto.Message) if !ok { return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) @@ -45,7 +45,7 @@ func (codec) Marshal(v interface{}) ([]byte, error) { return proto.Marshal(vv) } -func (codec) Unmarshal(data []byte, v interface{}) error { +func (codec) Unmarshal(data []byte, v any) error { vv, ok := v.(proto.Message) if !ok { return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v) diff --git a/vendor/google.golang.org/grpc/grpclog/component.go b/vendor/google.golang.org/grpc/grpclog/component.go index 8358dd6e2ab..ac73c9ced25 100644 --- a/vendor/google.golang.org/grpc/grpclog/component.go +++ b/vendor/google.golang.org/grpc/grpclog/component.go @@ -31,71 +31,71 @@ type componentData struct { var cache = map[string]*componentData{} -func (c *componentData) InfoDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) InfoDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.InfoDepth(depth+1, args...) } -func (c *componentData) WarningDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) WarningDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.WarningDepth(depth+1, args...) } -func (c *componentData) ErrorDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) ErrorDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.ErrorDepth(depth+1, args...) } -func (c *componentData) FatalDepth(depth int, args ...interface{}) { - args = append([]interface{}{"[" + string(c.name) + "]"}, args...) +func (c *componentData) FatalDepth(depth int, args ...any) { + args = append([]any{"[" + string(c.name) + "]"}, args...) grpclog.FatalDepth(depth+1, args...) } -func (c *componentData) Info(args ...interface{}) { +func (c *componentData) Info(args ...any) { c.InfoDepth(1, args...) } -func (c *componentData) Warning(args ...interface{}) { +func (c *componentData) Warning(args ...any) { c.WarningDepth(1, args...) } -func (c *componentData) Error(args ...interface{}) { +func (c *componentData) Error(args ...any) { c.ErrorDepth(1, args...) } -func (c *componentData) Fatal(args ...interface{}) { +func (c *componentData) Fatal(args ...any) { c.FatalDepth(1, args...) } -func (c *componentData) Infof(format string, args ...interface{}) { +func (c *componentData) Infof(format string, args ...any) { c.InfoDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Warningf(format string, args ...interface{}) { +func (c *componentData) Warningf(format string, args ...any) { c.WarningDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Errorf(format string, args ...interface{}) { +func (c *componentData) Errorf(format string, args ...any) { c.ErrorDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Fatalf(format string, args ...interface{}) { +func (c *componentData) Fatalf(format string, args ...any) { c.FatalDepth(1, fmt.Sprintf(format, args...)) } -func (c *componentData) Infoln(args ...interface{}) { +func (c *componentData) Infoln(args ...any) { c.InfoDepth(1, args...) } -func (c *componentData) Warningln(args ...interface{}) { +func (c *componentData) Warningln(args ...any) { c.WarningDepth(1, args...) } -func (c *componentData) Errorln(args ...interface{}) { +func (c *componentData) Errorln(args ...any) { c.ErrorDepth(1, args...) } -func (c *componentData) Fatalln(args ...interface{}) { +func (c *componentData) Fatalln(args ...any) { c.FatalDepth(1, args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go index c8bb2be34bf..16928c9cb99 100644 --- a/vendor/google.golang.org/grpc/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go @@ -42,53 +42,53 @@ func V(l int) bool { } // Info logs to the INFO log. -func Info(args ...interface{}) { +func Info(args ...any) { grpclog.Logger.Info(args...) } // Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf. -func Infof(format string, args ...interface{}) { +func Infof(format string, args ...any) { grpclog.Logger.Infof(format, args...) } // Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println. -func Infoln(args ...interface{}) { +func Infoln(args ...any) { grpclog.Logger.Infoln(args...) } // Warning logs to the WARNING log. -func Warning(args ...interface{}) { +func Warning(args ...any) { grpclog.Logger.Warning(args...) } // Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf. -func Warningf(format string, args ...interface{}) { +func Warningf(format string, args ...any) { grpclog.Logger.Warningf(format, args...) } // Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println. -func Warningln(args ...interface{}) { +func Warningln(args ...any) { grpclog.Logger.Warningln(args...) } // Error logs to the ERROR log. -func Error(args ...interface{}) { +func Error(args ...any) { grpclog.Logger.Error(args...) } // Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf. -func Errorf(format string, args ...interface{}) { +func Errorf(format string, args ...any) { grpclog.Logger.Errorf(format, args...) } // Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println. -func Errorln(args ...interface{}) { +func Errorln(args ...any) { grpclog.Logger.Errorln(args...) } // Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print. // It calls os.Exit() with exit code 1. -func Fatal(args ...interface{}) { +func Fatal(args ...any) { grpclog.Logger.Fatal(args...) // Make sure fatal logs will exit. os.Exit(1) @@ -96,7 +96,7 @@ func Fatal(args ...interface{}) { // Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf. // It calls os.Exit() with exit code 1. -func Fatalf(format string, args ...interface{}) { +func Fatalf(format string, args ...any) { grpclog.Logger.Fatalf(format, args...) // Make sure fatal logs will exit. os.Exit(1) @@ -104,7 +104,7 @@ func Fatalf(format string, args ...interface{}) { // Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println. // It calle os.Exit()) with exit code 1. -func Fatalln(args ...interface{}) { +func Fatalln(args ...any) { grpclog.Logger.Fatalln(args...) // Make sure fatal logs will exit. os.Exit(1) @@ -113,20 +113,20 @@ func Fatalln(args ...interface{}) { // Print prints to the logger. Arguments are handled in the manner of fmt.Print. // // Deprecated: use Info. -func Print(args ...interface{}) { +func Print(args ...any) { grpclog.Logger.Info(args...) } // Printf prints to the logger. Arguments are handled in the manner of fmt.Printf. // // Deprecated: use Infof. -func Printf(format string, args ...interface{}) { +func Printf(format string, args ...any) { grpclog.Logger.Infof(format, args...) } // Println prints to the logger. Arguments are handled in the manner of fmt.Println. // // Deprecated: use Infoln. -func Println(args ...interface{}) { +func Println(args ...any) { grpclog.Logger.Infoln(args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/logger.go b/vendor/google.golang.org/grpc/grpclog/logger.go index ef06a4822b7..b1674d8267c 100644 --- a/vendor/google.golang.org/grpc/grpclog/logger.go +++ b/vendor/google.golang.org/grpc/grpclog/logger.go @@ -24,12 +24,12 @@ import "google.golang.org/grpc/internal/grpclog" // // Deprecated: use LoggerV2. type Logger interface { - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Fatalln(args ...interface{}) - Print(args ...interface{}) - Printf(format string, args ...interface{}) - Println(args ...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) } // SetLogger sets the logger that is used in grpc. Call only from @@ -45,39 +45,39 @@ type loggerWrapper struct { Logger } -func (g *loggerWrapper) Info(args ...interface{}) { +func (g *loggerWrapper) Info(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Infoln(args ...interface{}) { +func (g *loggerWrapper) Infoln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Infof(format string, args ...interface{}) { +func (g *loggerWrapper) Infof(format string, args ...any) { g.Logger.Printf(format, args...) } -func (g *loggerWrapper) Warning(args ...interface{}) { +func (g *loggerWrapper) Warning(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Warningln(args ...interface{}) { +func (g *loggerWrapper) Warningln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Warningf(format string, args ...interface{}) { +func (g *loggerWrapper) Warningf(format string, args ...any) { g.Logger.Printf(format, args...) } -func (g *loggerWrapper) Error(args ...interface{}) { +func (g *loggerWrapper) Error(args ...any) { g.Logger.Print(args...) } -func (g *loggerWrapper) Errorln(args ...interface{}) { +func (g *loggerWrapper) Errorln(args ...any) { g.Logger.Println(args...) } -func (g *loggerWrapper) Errorf(format string, args ...interface{}) { +func (g *loggerWrapper) Errorf(format string, args ...any) { g.Logger.Printf(format, args...) } diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go index b5560b47ec4..ecfd36d7130 100644 --- a/vendor/google.golang.org/grpc/grpclog/loggerv2.go +++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go @@ -22,7 +22,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "log" "os" "strconv" @@ -34,35 +33,35 @@ import ( // LoggerV2 does underlying logging work for grpclog. type LoggerV2 interface { // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. - Info(args ...interface{}) + Info(args ...any) // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. - Infoln(args ...interface{}) + Infoln(args ...any) // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. - Infof(format string, args ...interface{}) + Infof(format string, args ...any) // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. - Warning(args ...interface{}) + Warning(args ...any) // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. - Warningln(args ...interface{}) + Warningln(args ...any) // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. - Warningf(format string, args ...interface{}) + Warningf(format string, args ...any) // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. - Error(args ...interface{}) + Error(args ...any) // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - Errorln(args ...interface{}) + Errorln(args ...any) // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - Errorf(format string, args ...interface{}) + Errorf(format string, args ...any) // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatal(args ...interface{}) + Fatal(args ...any) // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalln(args ...interface{}) + Fatalln(args ...any) // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalf(format string, args ...interface{}) + Fatalf(format string, args ...any) // V reports whether verbosity level l is at least the requested verbose level. V(l int) bool } @@ -140,9 +139,9 @@ func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config) // newLoggerV2 creates a loggerV2 to be used as default logger. // All logs are written to stderr. func newLoggerV2() LoggerV2 { - errorW := ioutil.Discard - warningW := ioutil.Discard - infoW := ioutil.Discard + errorW := io.Discard + warningW := io.Discard + infoW := io.Discard logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL") switch logLevel { @@ -183,53 +182,53 @@ func (g *loggerT) output(severity int, s string) { g.m[severity].Output(2, string(b)) } -func (g *loggerT) Info(args ...interface{}) { +func (g *loggerT) Info(args ...any) { g.output(infoLog, fmt.Sprint(args...)) } -func (g *loggerT) Infoln(args ...interface{}) { +func (g *loggerT) Infoln(args ...any) { g.output(infoLog, fmt.Sprintln(args...)) } -func (g *loggerT) Infof(format string, args ...interface{}) { +func (g *loggerT) Infof(format string, args ...any) { g.output(infoLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Warning(args ...interface{}) { +func (g *loggerT) Warning(args ...any) { g.output(warningLog, fmt.Sprint(args...)) } -func (g *loggerT) Warningln(args ...interface{}) { +func (g *loggerT) Warningln(args ...any) { g.output(warningLog, fmt.Sprintln(args...)) } -func (g *loggerT) Warningf(format string, args ...interface{}) { +func (g *loggerT) Warningf(format string, args ...any) { g.output(warningLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Error(args ...interface{}) { +func (g *loggerT) Error(args ...any) { g.output(errorLog, fmt.Sprint(args...)) } -func (g *loggerT) Errorln(args ...interface{}) { +func (g *loggerT) Errorln(args ...any) { g.output(errorLog, fmt.Sprintln(args...)) } -func (g *loggerT) Errorf(format string, args ...interface{}) { +func (g *loggerT) Errorf(format string, args ...any) { g.output(errorLog, fmt.Sprintf(format, args...)) } -func (g *loggerT) Fatal(args ...interface{}) { +func (g *loggerT) Fatal(args ...any) { g.output(fatalLog, fmt.Sprint(args...)) os.Exit(1) } -func (g *loggerT) Fatalln(args ...interface{}) { +func (g *loggerT) Fatalln(args ...any) { g.output(fatalLog, fmt.Sprintln(args...)) os.Exit(1) } -func (g *loggerT) Fatalf(format string, args ...interface{}) { +func (g *loggerT) Fatalf(format string, args ...any) { g.output(fatalLog, fmt.Sprintf(format, args...)) os.Exit(1) } @@ -249,11 +248,11 @@ func (g *loggerT) V(l int) bool { type DepthLoggerV2 interface { LoggerV2 // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. - InfoDepth(depth int, args ...interface{}) + InfoDepth(depth int, args ...any) // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. - WarningDepth(depth int, args ...interface{}) + WarningDepth(depth int, args ...any) // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. - ErrorDepth(depth int, args ...interface{}) + ErrorDepth(depth int, args ...any) // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. - FatalDepth(depth int, args ...interface{}) + FatalDepth(depth int, args ...any) } diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go new file mode 100644 index 00000000000..24299efd63f --- /dev/null +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -0,0 +1,308 @@ +// Copyright 2015 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.22.0 +// source: grpc/health/v1/health.proto + +package grpc_health_v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HealthCheckResponse_ServingStatus int32 + +const ( + HealthCheckResponse_UNKNOWN HealthCheckResponse_ServingStatus = 0 + HealthCheckResponse_SERVING HealthCheckResponse_ServingStatus = 1 + HealthCheckResponse_NOT_SERVING HealthCheckResponse_ServingStatus = 2 + HealthCheckResponse_SERVICE_UNKNOWN HealthCheckResponse_ServingStatus = 3 // Used only by the Watch method. +) + +// Enum value maps for HealthCheckResponse_ServingStatus. +var ( + HealthCheckResponse_ServingStatus_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SERVING", + 2: "NOT_SERVING", + 3: "SERVICE_UNKNOWN", + } + HealthCheckResponse_ServingStatus_value = map[string]int32{ + "UNKNOWN": 0, + "SERVING": 1, + "NOT_SERVING": 2, + "SERVICE_UNKNOWN": 3, + } +) + +func (x HealthCheckResponse_ServingStatus) Enum() *HealthCheckResponse_ServingStatus { + p := new(HealthCheckResponse_ServingStatus) + *p = x + return p +} + +func (x HealthCheckResponse_ServingStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HealthCheckResponse_ServingStatus) Descriptor() protoreflect.EnumDescriptor { + return file_grpc_health_v1_health_proto_enumTypes[0].Descriptor() +} + +func (HealthCheckResponse_ServingStatus) Type() protoreflect.EnumType { + return &file_grpc_health_v1_health_proto_enumTypes[0] +} + +func (x HealthCheckResponse_ServingStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use HealthCheckResponse_ServingStatus.Descriptor instead. +func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { + return file_grpc_health_v1_health_proto_rawDescGZIP(), []int{1, 0} +} + +type HealthCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` +} + +func (x *HealthCheckRequest) Reset() { + *x = HealthCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_health_v1_health_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckRequest) ProtoMessage() {} + +func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_health_v1_health_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckRequest.ProtoReflect.Descriptor instead. +func (*HealthCheckRequest) Descriptor() ([]byte, []int) { + return file_grpc_health_v1_health_proto_rawDescGZIP(), []int{0} +} + +func (x *HealthCheckRequest) GetService() string { + if x != nil { + return x.Service + } + return "" +} + +type HealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"` +} + +func (x *HealthCheckResponse) Reset() { + *x = HealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_grpc_health_v1_health_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckResponse) ProtoMessage() {} + +func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_health_v1_health_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthCheckResponse.ProtoReflect.Descriptor instead. +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { + return file_grpc_health_v1_health_proto_rawDescGZIP(), []int{1} +} + +func (x *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus { + if x != nil { + return x.Status + } + return HealthCheckResponse_UNKNOWN +} + +var File_grpc_health_v1_health_proto protoreflect.FileDescriptor + +var file_grpc_health_v1_health_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x76, 0x31, + 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x22, 0x2e, 0x0a, + 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xb1, 0x01, + 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x4f, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, + 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, + 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x03, 0x32, 0xae, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x50, 0x0a, 0x05, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, + 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x30, 0x01, 0x42, 0x61, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, + 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x5f, 0x76, 0x31, 0xaa, 0x02, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_grpc_health_v1_health_proto_rawDescOnce sync.Once + file_grpc_health_v1_health_proto_rawDescData = file_grpc_health_v1_health_proto_rawDesc +) + +func file_grpc_health_v1_health_proto_rawDescGZIP() []byte { + file_grpc_health_v1_health_proto_rawDescOnce.Do(func() { + file_grpc_health_v1_health_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_health_v1_health_proto_rawDescData) + }) + return file_grpc_health_v1_health_proto_rawDescData +} + +var file_grpc_health_v1_health_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_grpc_health_v1_health_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_grpc_health_v1_health_proto_goTypes = []interface{}{ + (HealthCheckResponse_ServingStatus)(0), // 0: grpc.health.v1.HealthCheckResponse.ServingStatus + (*HealthCheckRequest)(nil), // 1: grpc.health.v1.HealthCheckRequest + (*HealthCheckResponse)(nil), // 2: grpc.health.v1.HealthCheckResponse +} +var file_grpc_health_v1_health_proto_depIdxs = []int32{ + 0, // 0: grpc.health.v1.HealthCheckResponse.status:type_name -> grpc.health.v1.HealthCheckResponse.ServingStatus + 1, // 1: grpc.health.v1.Health.Check:input_type -> grpc.health.v1.HealthCheckRequest + 1, // 2: grpc.health.v1.Health.Watch:input_type -> grpc.health.v1.HealthCheckRequest + 2, // 3: grpc.health.v1.Health.Check:output_type -> grpc.health.v1.HealthCheckResponse + 2, // 4: grpc.health.v1.Health.Watch:output_type -> grpc.health.v1.HealthCheckResponse + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_grpc_health_v1_health_proto_init() } +func file_grpc_health_v1_health_proto_init() { + if File_grpc_health_v1_health_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_grpc_health_v1_health_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_grpc_health_v1_health_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_grpc_health_v1_health_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_grpc_health_v1_health_proto_goTypes, + DependencyIndexes: file_grpc_health_v1_health_proto_depIdxs, + EnumInfos: file_grpc_health_v1_health_proto_enumTypes, + MessageInfos: file_grpc_health_v1_health_proto_msgTypes, + }.Build() + File_grpc_health_v1_health_proto = out.File + file_grpc_health_v1_health_proto_rawDesc = nil + file_grpc_health_v1_health_proto_goTypes = nil + file_grpc_health_v1_health_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go new file mode 100644 index 00000000000..a01a1b4d54b --- /dev/null +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -0,0 +1,223 @@ +// Copyright 2015 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.22.0 +// source: grpc/health/v1/health.proto + +package grpc_health_v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Health_Check_FullMethodName = "/grpc.health.v1.Health/Check" + Health_Watch_FullMethodName = "/grpc.health.v1.Health/Watch" +) + +// HealthClient is the client API for Health service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HealthClient interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) +} + +type healthClient struct { + cc grpc.ClientConnInterface +} + +func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { + return &healthClient{cc} +} + +func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + out := new(HealthCheckResponse) + err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { + stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &healthWatchClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Health_WatchClient interface { + Recv() (*HealthCheckResponse, error) + grpc.ClientStream +} + +type healthWatchClient struct { + grpc.ClientStream +} + +func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { + m := new(HealthCheckResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// HealthServer is the server API for Health service. +// All implementations should embed UnimplementedHealthServer +// for forward compatibility +type HealthServer interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + Watch(*HealthCheckRequest, Health_WatchServer) error +} + +// UnimplementedHealthServer should be embedded to have forward compatible implementations. +type UnimplementedHealthServer struct { +} + +func (UnimplementedHealthServer) Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} +func (UnimplementedHealthServer) Watch(*HealthCheckRequest, Health_WatchServer) error { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") +} + +// UnsafeHealthServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HealthServer will +// result in compilation errors. +type UnsafeHealthServer interface { + mustEmbedUnimplementedHealthServer() +} + +func RegisterHealthServer(s grpc.ServiceRegistrar, srv HealthServer) { + s.RegisterService(&Health_ServiceDesc, srv) +} + +func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HealthServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Health_Check_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(HealthCheckRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(HealthServer).Watch(m, &healthWatchServer{stream}) +} + +type Health_WatchServer interface { + Send(*HealthCheckResponse) error + grpc.ServerStream +} + +type healthWatchServer struct { + grpc.ServerStream +} + +func (x *healthWatchServer) Send(m *HealthCheckResponse) error { + return x.ServerStream.SendMsg(m) +} + +// Health_ServiceDesc is the grpc.ServiceDesc for Health service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Health_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.health.v1.Health", + HandlerType: (*HealthServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Check", + Handler: _Health_Check_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Watch", + Handler: _Health_Watch_Handler, + ServerStreams: true, + }, + }, + Metadata: "grpc/health/v1/health.proto", +} diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go index bb96ef57be8..877d78fc3d0 100644 --- a/vendor/google.golang.org/grpc/interceptor.go +++ b/vendor/google.golang.org/grpc/interceptor.go @@ -23,7 +23,7 @@ import ( ) // UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. -type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error +type UnaryInvoker func(ctx context.Context, method string, req, reply any, cc *ClientConn, opts ...CallOption) error // UnaryClientInterceptor intercepts the execution of a unary RPC on the client. // Unary interceptors can be specified as a DialOption, using @@ -40,7 +40,7 @@ type UnaryInvoker func(ctx context.Context, method string, req, reply interface{ // defaults from the ClientConn as well as per-call options. // // The returned error must be compatible with the status package. -type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error +type UnaryClientInterceptor func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error // Streamer is called by StreamClientInterceptor to create a ClientStream. type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) @@ -66,7 +66,7 @@ type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *Cli // server side. All per-rpc information may be mutated by the interceptor. type UnaryServerInfo struct { // Server is the service implementation the user provides. This is read-only. - Server interface{} + Server any // FullMethod is the full RPC method string, i.e., /package.service/method. FullMethod string } @@ -78,13 +78,13 @@ type UnaryServerInfo struct { // status package, or be one of the context errors. Otherwise, gRPC will use // codes.Unknown as the status code and err.Error() as the status message of the // RPC. -type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error) +type UnaryHandler func(ctx context.Context, req any) (any, error) // UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info // contains all the information of this RPC the interceptor can operate on. And handler is the wrapper // of the service method implementation. It is the responsibility of the interceptor to invoke handler // to complete the RPC. -type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error) +type UnaryServerInterceptor func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (resp any, err error) // StreamServerInfo consists of various information about a streaming RPC on // server side. All per-rpc information may be mutated by the interceptor. @@ -101,4 +101,4 @@ type StreamServerInfo struct { // info contains all the information of this RPC the interceptor can operate on. And handler is the // service method implementation. It is the responsibility of the interceptor to invoke handler to // complete the RPC. -type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error +type StreamServerInterceptor func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index 08666f62a7c..3c594e6e4e5 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -200,8 +200,8 @@ func (gsb *Balancer) ExitIdle() { } } -// UpdateSubConnState forwards the update to the appropriate child. -func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { +// updateSubConnState forwards the update to the appropriate child. +func (gsb *Balancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState, cb func(balancer.SubConnState)) { gsb.currentMu.Lock() defer gsb.currentMu.Unlock() gsb.mu.Lock() @@ -214,13 +214,26 @@ func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubC } else if gsb.balancerPending != nil && gsb.balancerPending.subconns[sc] { balToUpdate = gsb.balancerPending } - gsb.mu.Unlock() if balToUpdate == nil { // SubConn belonged to a stale lb policy that has not yet fully closed, // or the balancer was already closed. + gsb.mu.Unlock() return } - balToUpdate.UpdateSubConnState(sc, state) + if state.ConnectivityState == connectivity.Shutdown { + delete(balToUpdate.subconns, sc) + } + gsb.mu.Unlock() + if cb != nil { + cb(state) + } else { + balToUpdate.UpdateSubConnState(sc, state) + } +} + +// UpdateSubConnState forwards the update to the appropriate child. +func (gsb *Balancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { + gsb.updateSubConnState(sc, state, nil) } // Close closes any active child balancers. @@ -242,7 +255,7 @@ func (gsb *Balancer) Close() { // // It implements the balancer.ClientConn interface and is passed down in that // capacity to the wrapped balancer. It maintains a set of subConns created by -// the wrapped balancer and calls from the latter to create/update/remove +// the wrapped balancer and calls from the latter to create/update/shutdown // SubConns update this set before being forwarded to the parent ClientConn. // State updates from the wrapped balancer can result in invocation of the // graceful switch logic. @@ -254,21 +267,10 @@ type balancerWrapper struct { subconns map[balancer.SubConn]bool // subconns created by this balancer } -func (bw *balancerWrapper) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { - if state.ConnectivityState == connectivity.Shutdown { - bw.gsb.mu.Lock() - delete(bw.subconns, sc) - bw.gsb.mu.Unlock() - } - // There is no need to protect this read with a mutex, as the write to the - // Balancer field happens in SwitchTo, which completes before this can be - // called. - bw.Balancer.UpdateSubConnState(sc, state) -} - -// Close closes the underlying LB policy and removes the subconns it created. bw -// must not be referenced via balancerCurrent or balancerPending in gsb when -// called. gsb.mu must not be held. Does not panic with a nil receiver. +// Close closes the underlying LB policy and shuts down the subconns it +// created. bw must not be referenced via balancerCurrent or balancerPending in +// gsb when called. gsb.mu must not be held. Does not panic with a nil +// receiver. func (bw *balancerWrapper) Close() { // before Close is called. if bw == nil { @@ -281,7 +283,7 @@ func (bw *balancerWrapper) Close() { bw.Balancer.Close() bw.gsb.mu.Lock() for sc := range bw.subconns { - bw.gsb.cc.RemoveSubConn(sc) + sc.Shutdown() } bw.gsb.mu.Unlock() } @@ -335,13 +337,16 @@ func (bw *balancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.Ne } bw.gsb.mu.Unlock() + var sc balancer.SubConn + oldListener := opts.StateListener + opts.StateListener = func(state balancer.SubConnState) { bw.gsb.updateSubConnState(sc, state, oldListener) } sc, err := bw.gsb.cc.NewSubConn(addrs, opts) if err != nil { return nil, err } bw.gsb.mu.Lock() if !bw.gsb.balancerCurrentOrPending(bw) { // balancer was closed during this call - bw.gsb.cc.RemoveSubConn(sc) + sc.Shutdown() bw.gsb.mu.Unlock() return nil, fmt.Errorf("%T at address %p that called NewSubConn is deleted", bw, bw) } @@ -360,13 +365,9 @@ func (bw *balancerWrapper) ResolveNow(opts resolver.ResolveNowOptions) { } func (bw *balancerWrapper) RemoveSubConn(sc balancer.SubConn) { - bw.gsb.mu.Lock() - if !bw.gsb.balancerCurrentOrPending(bw) { - bw.gsb.mu.Unlock() - return - } - bw.gsb.mu.Unlock() - bw.gsb.cc.RemoveSubConn(sc) + // Note: existing third party balancers may call this, so it must remain + // until RemoveSubConn is fully removed. + sc.Shutdown() } func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { diff --git a/vendor/google.golang.org/grpc/internal/balancerload/load.go b/vendor/google.golang.org/grpc/internal/balancerload/load.go index 3a905d96657..94a08d6875a 100644 --- a/vendor/google.golang.org/grpc/internal/balancerload/load.go +++ b/vendor/google.golang.org/grpc/internal/balancerload/load.go @@ -25,7 +25,7 @@ import ( // Parser converts loads from metadata into a concrete type. type Parser interface { // Parse parses loads from metadata. - Parse(md metadata.MD) interface{} + Parse(md metadata.MD) any } var parser Parser @@ -38,7 +38,7 @@ func SetParser(lr Parser) { } // Parse calls parser.Read(). -func Parse(md metadata.MD) interface{} { +func Parse(md metadata.MD) any { if parser == nil { return nil } diff --git a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go index 809d73ccafb..755fdebc1b1 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go @@ -28,8 +28,13 @@ import ( "google.golang.org/grpc/internal/grpcutil" ) -// Logger is the global binary logger. It can be used to get binary logger for -// each method. +var grpclogLogger = grpclog.Component("binarylog") + +// Logger specifies MethodLoggers for method names with a Log call that +// takes a context. +// +// This is used in the 1.0 release of gcp/observability, and thus must not be +// deleted or changed. type Logger interface { GetMethodLogger(methodName string) MethodLogger } @@ -40,8 +45,6 @@ type Logger interface { // It is used to get a MethodLogger for each individual method. var binLogger Logger -var grpclogLogger = grpclog.Component("binarylog") - // SetLogger sets the binary logger. // // Only call this at init time. diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index 179f4a26d13..0f31274a3cc 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -19,6 +19,7 @@ package binarylog import ( + "context" "net" "strings" "sync/atomic" @@ -26,7 +27,7 @@ import ( "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" - pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -48,8 +49,11 @@ func (g *callIDGenerator) reset() { var idGen callIDGenerator // MethodLogger is the sub-logger for each method. +// +// This is used in the 1.0 release of gcp/observability, and thus must not be +// deleted or changed. type MethodLogger interface { - Log(LogEntryConfig) + Log(context.Context, LogEntryConfig) } // TruncatingMethodLogger is a method logger that truncates headers and messages @@ -64,6 +68,9 @@ type TruncatingMethodLogger struct { } // NewTruncatingMethodLogger returns a new truncating method logger. +// +// This is used in the 1.0 release of gcp/observability, and thus must not be +// deleted or changed. func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { return &TruncatingMethodLogger{ headerMaxLen: h, @@ -79,7 +86,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { // Build is an internal only method for building the proto message out of the // input event. It's made public to enable other library to reuse as much logic // in TruncatingMethodLogger as possible. -func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry { +func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry { m := c.toProto() timestamp, _ := ptypes.TimestampProto(time.Now()) m.Timestamp = timestamp @@ -87,22 +94,22 @@ func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry { m.SequenceIdWithinCall = ml.idWithinCallGen.next() switch pay := m.Payload.(type) { - case *pb.GrpcLogEntry_ClientHeader: + case *binlogpb.GrpcLogEntry_ClientHeader: m.PayloadTruncated = ml.truncateMetadata(pay.ClientHeader.GetMetadata()) - case *pb.GrpcLogEntry_ServerHeader: + case *binlogpb.GrpcLogEntry_ServerHeader: m.PayloadTruncated = ml.truncateMetadata(pay.ServerHeader.GetMetadata()) - case *pb.GrpcLogEntry_Message: + case *binlogpb.GrpcLogEntry_Message: m.PayloadTruncated = ml.truncateMessage(pay.Message) } return m } // Log creates a proto binary log entry, and logs it to the sink. -func (ml *TruncatingMethodLogger) Log(c LogEntryConfig) { +func (ml *TruncatingMethodLogger) Log(ctx context.Context, c LogEntryConfig) { ml.sink.Write(ml.Build(c)) } -func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) { +func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *binlogpb.Metadata) (truncated bool) { if ml.headerMaxLen == maxUInt { return false } @@ -121,7 +128,7 @@ func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated // but not counted towards the size limit. continue } - currentEntryLen := uint64(len(entry.Value)) + currentEntryLen := uint64(len(entry.GetKey())) + uint64(len(entry.GetValue())) if currentEntryLen > bytesLimit { break } @@ -132,7 +139,7 @@ func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated return truncated } -func (ml *TruncatingMethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) { +func (ml *TruncatingMethodLogger) truncateMessage(msgPb *binlogpb.Message) (truncated bool) { if ml.messageMaxLen == maxUInt { return false } @@ -144,8 +151,11 @@ func (ml *TruncatingMethodLogger) truncateMessage(msgPb *pb.Message) (truncated } // LogEntryConfig represents the configuration for binary log entry. +// +// This is used in the 1.0 release of gcp/observability, and thus must not be +// deleted or changed. type LogEntryConfig interface { - toProto() *pb.GrpcLogEntry + toProto() *binlogpb.GrpcLogEntry } // ClientHeader configs the binary log entry to be a ClientHeader entry. @@ -159,10 +169,10 @@ type ClientHeader struct { PeerAddr net.Addr } -func (c *ClientHeader) toProto() *pb.GrpcLogEntry { +func (c *ClientHeader) toProto() *binlogpb.GrpcLogEntry { // This function doesn't need to set all the fields (e.g. seq ID). The Log // function will set the fields when necessary. - clientHeader := &pb.ClientHeader{ + clientHeader := &binlogpb.ClientHeader{ Metadata: mdToMetadataProto(c.Header), MethodName: c.MethodName, Authority: c.Authority, @@ -170,16 +180,16 @@ func (c *ClientHeader) toProto() *pb.GrpcLogEntry { if c.Timeout > 0 { clientHeader.Timeout = ptypes.DurationProto(c.Timeout) } - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER, - Payload: &pb.GrpcLogEntry_ClientHeader{ + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER, + Payload: &binlogpb.GrpcLogEntry_ClientHeader{ ClientHeader: clientHeader, }, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } if c.PeerAddr != nil { ret.Peer = addrToProto(c.PeerAddr) @@ -195,19 +205,19 @@ type ServerHeader struct { PeerAddr net.Addr } -func (c *ServerHeader) toProto() *pb.GrpcLogEntry { - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_HEADER, - Payload: &pb.GrpcLogEntry_ServerHeader{ - ServerHeader: &pb.ServerHeader{ +func (c *ServerHeader) toProto() *binlogpb.GrpcLogEntry { + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_HEADER, + Payload: &binlogpb.GrpcLogEntry_ServerHeader{ + ServerHeader: &binlogpb.ServerHeader{ Metadata: mdToMetadataProto(c.Header), }, }, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } if c.PeerAddr != nil { ret.Peer = addrToProto(c.PeerAddr) @@ -220,10 +230,10 @@ type ClientMessage struct { OnClientSide bool // Message can be a proto.Message or []byte. Other messages formats are not // supported. - Message interface{} + Message any } -func (c *ClientMessage) toProto() *pb.GrpcLogEntry { +func (c *ClientMessage) toProto() *binlogpb.GrpcLogEntry { var ( data []byte err error @@ -238,19 +248,19 @@ func (c *ClientMessage) toProto() *pb.GrpcLogEntry { } else { grpclogLogger.Infof("binarylogging: message to log is neither proto.message nor []byte") } - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE, - Payload: &pb.GrpcLogEntry_Message{ - Message: &pb.Message{ + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE, + Payload: &binlogpb.GrpcLogEntry_Message{ + Message: &binlogpb.Message{ Length: uint32(len(data)), Data: data, }, }, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } return ret } @@ -260,10 +270,10 @@ type ServerMessage struct { OnClientSide bool // Message can be a proto.Message or []byte. Other messages formats are not // supported. - Message interface{} + Message any } -func (c *ServerMessage) toProto() *pb.GrpcLogEntry { +func (c *ServerMessage) toProto() *binlogpb.GrpcLogEntry { var ( data []byte err error @@ -278,19 +288,19 @@ func (c *ServerMessage) toProto() *pb.GrpcLogEntry { } else { grpclogLogger.Infof("binarylogging: message to log is neither proto.message nor []byte") } - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE, - Payload: &pb.GrpcLogEntry_Message{ - Message: &pb.Message{ + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE, + Payload: &binlogpb.GrpcLogEntry_Message{ + Message: &binlogpb.Message{ Length: uint32(len(data)), Data: data, }, }, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } return ret } @@ -300,15 +310,15 @@ type ClientHalfClose struct { OnClientSide bool } -func (c *ClientHalfClose) toProto() *pb.GrpcLogEntry { - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE, +func (c *ClientHalfClose) toProto() *binlogpb.GrpcLogEntry { + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE, Payload: nil, // No payload here. } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } return ret } @@ -324,7 +334,7 @@ type ServerTrailer struct { PeerAddr net.Addr } -func (c *ServerTrailer) toProto() *pb.GrpcLogEntry { +func (c *ServerTrailer) toProto() *binlogpb.GrpcLogEntry { st, ok := status.FromError(c.Err) if !ok { grpclogLogger.Info("binarylogging: error in trailer is not a status error") @@ -340,10 +350,10 @@ func (c *ServerTrailer) toProto() *pb.GrpcLogEntry { grpclogLogger.Infof("binarylogging: failed to marshal status proto: %v", err) } } - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER, - Payload: &pb.GrpcLogEntry_Trailer{ - Trailer: &pb.Trailer{ + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER, + Payload: &binlogpb.GrpcLogEntry_Trailer{ + Trailer: &binlogpb.Trailer{ Metadata: mdToMetadataProto(c.Trailer), StatusCode: uint32(st.Code()), StatusMessage: st.Message(), @@ -352,9 +362,9 @@ func (c *ServerTrailer) toProto() *pb.GrpcLogEntry { }, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } if c.PeerAddr != nil { ret.Peer = addrToProto(c.PeerAddr) @@ -367,15 +377,15 @@ type Cancel struct { OnClientSide bool } -func (c *Cancel) toProto() *pb.GrpcLogEntry { - ret := &pb.GrpcLogEntry{ - Type: pb.GrpcLogEntry_EVENT_TYPE_CANCEL, +func (c *Cancel) toProto() *binlogpb.GrpcLogEntry { + ret := &binlogpb.GrpcLogEntry{ + Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CANCEL, Payload: nil, } if c.OnClientSide { - ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT } else { - ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER + ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER } return ret } @@ -392,15 +402,15 @@ func metadataKeyOmit(key string) bool { return strings.HasPrefix(key, "grpc-") } -func mdToMetadataProto(md metadata.MD) *pb.Metadata { - ret := &pb.Metadata{} +func mdToMetadataProto(md metadata.MD) *binlogpb.Metadata { + ret := &binlogpb.Metadata{} for k, vv := range md { if metadataKeyOmit(k) { continue } for _, v := range vv { ret.Entry = append(ret.Entry, - &pb.MetadataEntry{ + &binlogpb.MetadataEntry{ Key: k, Value: []byte(v), }, @@ -410,26 +420,26 @@ func mdToMetadataProto(md metadata.MD) *pb.Metadata { return ret } -func addrToProto(addr net.Addr) *pb.Address { - ret := &pb.Address{} +func addrToProto(addr net.Addr) *binlogpb.Address { + ret := &binlogpb.Address{} switch a := addr.(type) { case *net.TCPAddr: if a.IP.To4() != nil { - ret.Type = pb.Address_TYPE_IPV4 + ret.Type = binlogpb.Address_TYPE_IPV4 } else if a.IP.To16() != nil { - ret.Type = pb.Address_TYPE_IPV6 + ret.Type = binlogpb.Address_TYPE_IPV6 } else { - ret.Type = pb.Address_TYPE_UNKNOWN + ret.Type = binlogpb.Address_TYPE_UNKNOWN // Do not set address and port fields. break } ret.Address = a.IP.String() ret.IpPort = uint32(a.Port) case *net.UnixAddr: - ret.Type = pb.Address_TYPE_UNIX + ret.Type = binlogpb.Address_TYPE_UNIX ret.Address = a.String() default: - ret.Type = pb.Address_TYPE_UNKNOWN + ret.Type = binlogpb.Address_TYPE_UNKNOWN } return ret } diff --git a/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/vendor/google.golang.org/grpc/internal/binarylog/sink.go index c2fdd58b319..264de387c2a 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/sink.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/sink.go @@ -26,7 +26,7 @@ import ( "time" "github.com/golang/protobuf/proto" - pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" ) var ( @@ -42,15 +42,15 @@ type Sink interface { // Write will be called to write the log entry into the sink. // // It should be thread-safe so it can be called in parallel. - Write(*pb.GrpcLogEntry) error + Write(*binlogpb.GrpcLogEntry) error // Close will be called when the Sink is replaced by a new Sink. Close() error } type noopSink struct{} -func (ns *noopSink) Write(*pb.GrpcLogEntry) error { return nil } -func (ns *noopSink) Close() error { return nil } +func (ns *noopSink) Write(*binlogpb.GrpcLogEntry) error { return nil } +func (ns *noopSink) Close() error { return nil } // newWriterSink creates a binary log sink with the given writer. // @@ -66,7 +66,7 @@ type writerSink struct { out io.Writer } -func (ws *writerSink) Write(e *pb.GrpcLogEntry) error { +func (ws *writerSink) Write(e *binlogpb.GrpcLogEntry) error { b, err := proto.Marshal(e) if err != nil { grpclogLogger.Errorf("binary logging: failed to marshal proto message: %v", err) @@ -96,7 +96,7 @@ type bufferedSink struct { done chan struct{} } -func (fs *bufferedSink) Write(e *pb.GrpcLogEntry) error { +func (fs *bufferedSink) Write(e *binlogpb.GrpcLogEntry) error { fs.mu.Lock() defer fs.mu.Unlock() if !fs.flusherStarted { diff --git a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go index 9f6a0c1200d..4399c3df495 100644 --- a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go +++ b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go @@ -28,35 +28,38 @@ import "sync" // the underlying mutex used for synchronization. // // Unbounded supports values of any type to be stored in it by using a channel -// of `interface{}`. This means that a call to Put() incurs an extra memory -// allocation, and also that users need a type assertion while reading. For -// performance critical code paths, using Unbounded is strongly discouraged and -// defining a new type specific implementation of this buffer is preferred. See +// of `any`. This means that a call to Put() incurs an extra memory allocation, +// and also that users need a type assertion while reading. For performance +// critical code paths, using Unbounded is strongly discouraged and defining a +// new type specific implementation of this buffer is preferred. See // internal/transport/transport.go for an example of this. type Unbounded struct { - c chan interface{} + c chan any + closed bool mu sync.Mutex - backlog []interface{} + backlog []any } // NewUnbounded returns a new instance of Unbounded. func NewUnbounded() *Unbounded { - return &Unbounded{c: make(chan interface{}, 1)} + return &Unbounded{c: make(chan any, 1)} } // Put adds t to the unbounded buffer. -func (b *Unbounded) Put(t interface{}) { +func (b *Unbounded) Put(t any) { b.mu.Lock() + defer b.mu.Unlock() + if b.closed { + return + } if len(b.backlog) == 0 { select { case b.c <- t: - b.mu.Unlock() return default: } } b.backlog = append(b.backlog, t) - b.mu.Unlock() } // Load sends the earliest buffered data, if any, onto the read channel @@ -64,6 +67,10 @@ func (b *Unbounded) Put(t interface{}) { // value from the read channel. func (b *Unbounded) Load() { b.mu.Lock() + defer b.mu.Unlock() + if b.closed { + return + } if len(b.backlog) > 0 { select { case b.c <- b.backlog[0]: @@ -72,7 +79,6 @@ func (b *Unbounded) Load() { default: } } - b.mu.Unlock() } // Get returns a read channel on which values added to the buffer, via Put(), @@ -80,6 +86,20 @@ func (b *Unbounded) Load() { // // Upon reading a value from this channel, users are expected to call Load() to // send the next buffered value onto the channel if there is any. -func (b *Unbounded) Get() <-chan interface{} { +// +// If the unbounded buffer is closed, the read channel returned by this method +// is closed. +func (b *Unbounded) Get() <-chan any { return b.c } + +// Close closes the unbounded buffer. +func (b *Unbounded) Close() { + b.mu.Lock() + defer b.mu.Unlock() + if b.closed { + return + } + b.closed = true + close(b.c) +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index 777cbcd7921..5395e77529c 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -24,9 +24,7 @@ package channelz import ( - "context" "errors" - "fmt" "sort" "sync" "sync/atomic" @@ -40,8 +38,11 @@ const ( ) var ( - db dbWrapper - idGen idGenerator + // IDGen is the global channelz entity ID generator. It should not be used + // outside this package except by tests. + IDGen IDGenerator + + db dbWrapper // EntryPerPage defines the number of channelz entries to be shown on a web page. EntryPerPage = int64(50) curState int32 @@ -52,14 +53,14 @@ var ( func TurnOn() { if !IsOn() { db.set(newChannelMap()) - idGen.reset() + IDGen.Reset() atomic.StoreInt32(&curState, 1) } } // IsOn returns whether channelz data collection is on. func IsOn() bool { - return atomic.CompareAndSwapInt32(&curState, 1, 1) + return atomic.LoadInt32(&curState) == 1 } // SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel). @@ -97,43 +98,6 @@ func (d *dbWrapper) get() *channelMap { return d.DB } -// NewChannelzStorageForTesting initializes channelz data storage and id -// generator for testing purposes. -// -// Returns a cleanup function to be invoked by the test, which waits for up to -// 10s for all channelz state to be reset by the grpc goroutines when those -// entities get closed. This cleanup function helps with ensuring that tests -// don't mess up each other. -func NewChannelzStorageForTesting() (cleanup func() error) { - db.set(newChannelMap()) - idGen.reset() - - return func() error { - cm := db.get() - if cm == nil { - return nil - } - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - ticker := time.NewTicker(10 * time.Millisecond) - defer ticker.Stop() - for { - cm.mu.RLock() - topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets := len(cm.topLevelChannels), len(cm.servers), len(cm.channels), len(cm.subChannels), len(cm.listenSockets), len(cm.normalSockets) - cm.mu.RUnlock() - - if err := ctx.Err(); err != nil { - return fmt.Errorf("after 10s the channelz map has not been cleaned up yet, topchannels: %d, servers: %d, channels: %d, subchannels: %d, listen sockets: %d, normal sockets: %d", topLevelChannels, servers, channels, subChannels, listenSockets, normalSockets) - } - if topLevelChannels == 0 && servers == 0 && channels == 0 && subChannels == 0 && listenSockets == 0 && normalSockets == 0 { - return nil - } - <-ticker.C - } - } -} - // GetTopChannels returns a slice of top channel's ChannelMetric, along with a // boolean indicating whether there's more top channels to be queried for. // @@ -193,7 +157,7 @@ func GetServer(id int64) *ServerMetric { // // If channelz is not turned ON, the channelz database is not mutated. func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier { - id := idGen.genID() + id := IDGen.genID() var parent int64 isTopChannel := true if pid != nil { @@ -229,7 +193,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er if pid == nil { return nil, errors.New("a SubChannel's parent id cannot be nil") } - id := idGen.genID() + id := IDGen.genID() if !IsOn() { return newIdentifer(RefSubChannel, id, pid), nil } @@ -251,7 +215,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er // // If channelz is not turned ON, the channelz database is not mutated. func RegisterServer(s Server, ref string) *Identifier { - id := idGen.genID() + id := IDGen.genID() if !IsOn() { return newIdentifer(RefServer, id, nil) } @@ -277,7 +241,7 @@ func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, e if pid == nil { return nil, errors.New("a ListenSocket's parent id cannot be 0") } - id := idGen.genID() + id := IDGen.genID() if !IsOn() { return newIdentifer(RefListenSocket, id, pid), nil } @@ -297,7 +261,7 @@ func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, e if pid == nil { return nil, errors.New("a NormalSocket's parent id cannot be 0") } - id := idGen.genID() + id := IDGen.genID() if !IsOn() { return newIdentifer(RefNormalSocket, id, pid), nil } @@ -776,14 +740,17 @@ func (c *channelMap) GetServer(id int64) *ServerMetric { return sm } -type idGenerator struct { +// IDGenerator is an incrementing atomic that tracks IDs for channelz entities. +type IDGenerator struct { id int64 } -func (i *idGenerator) reset() { +// Reset resets the generated ID back to zero. Should only be used at +// initialization or by tests sensitive to the ID number. +func (i *IDGenerator) Reset() { atomic.StoreInt64(&i.id, 0) } -func (i *idGenerator) genID() int64 { +func (i *IDGenerator) genID() int64 { return atomic.AddInt64(&i.id, 1) } diff --git a/vendor/google.golang.org/grpc/internal/channelz/logging.go b/vendor/google.golang.org/grpc/internal/channelz/logging.go index 8e13a3d2ce7..f89e6f77bbd 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/logging.go +++ b/vendor/google.golang.org/grpc/internal/channelz/logging.go @@ -31,7 +31,7 @@ func withParens(id *Identifier) string { } // Info logs and adds a trace event if channelz is on. -func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { +func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprint(args...), Severity: CtInfo, @@ -39,7 +39,7 @@ func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { } // Infof logs and adds a trace event if channelz is on. -func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { +func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprintf(format, args...), Severity: CtInfo, @@ -47,7 +47,7 @@ func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...inter } // Warning logs and adds a trace event if channelz is on. -func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { +func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprint(args...), Severity: CtWarning, @@ -55,7 +55,7 @@ func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { } // Warningf logs and adds a trace event if channelz is on. -func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { +func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprintf(format, args...), Severity: CtWarning, @@ -63,7 +63,7 @@ func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...in } // Error logs and adds a trace event if channelz is on. -func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { +func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprint(args...), Severity: CtError, @@ -71,7 +71,7 @@ func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...interface{}) { } // Errorf logs and adds a trace event if channelz is on. -func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...interface{}) { +func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { AddTraceEvent(l, id, 1, &TraceEventDesc{ Desc: fmt.Sprintf(format, args...), Severity: CtError, diff --git a/vendor/google.golang.org/grpc/internal/channelz/types.go b/vendor/google.golang.org/grpc/internal/channelz/types.go index 7b2f350e2e6..1d4020f5379 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types.go @@ -628,6 +628,7 @@ type tracedChannel interface { type channelTrace struct { cm *channelMap + clearCalled bool createdTime time.Time eventCount int64 mu sync.Mutex @@ -656,6 +657,10 @@ func (c *channelTrace) append(e *TraceEvent) { } func (c *channelTrace) clear() { + if c.clearCalled { + return + } + c.clearCalled = true c.mu.Lock() for _, e := range c.events { if e.RefID != 0 { diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go index 8d194e44e1d..98288c3f866 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go @@ -23,7 +23,7 @@ import ( ) // GetSocketOption gets the socket option info of the conn. -func GetSocketOption(socket interface{}) *SocketOptionData { +func GetSocketOption(socket any) *SocketOptionData { c, ok := socket.(syscall.Conn) if !ok { return nil diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go index 837ddc40240..b5568b22e20 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go @@ -22,6 +22,6 @@ package channelz // GetSocketOption gets the socket option info of the conn. -func GetSocketOption(c interface{}) *SocketOptionData { +func GetSocketOption(c any) *SocketOptionData { return nil } diff --git a/vendor/google.golang.org/grpc/internal/credentials/credentials.go b/vendor/google.golang.org/grpc/internal/credentials/credentials.go index 32c9b59033c..9deee7f6513 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/internal/credentials/credentials.go @@ -25,12 +25,12 @@ import ( type requestInfoKey struct{} // NewRequestInfoContext creates a context with ri. -func NewRequestInfoContext(ctx context.Context, ri interface{}) context.Context { +func NewRequestInfoContext(ctx context.Context, ri any) context.Context { return context.WithValue(ctx, requestInfoKey{}, ri) } // RequestInfoFromContext extracts the RequestInfo from ctx. -func RequestInfoFromContext(ctx context.Context) interface{} { +func RequestInfoFromContext(ctx context.Context) any { return ctx.Value(requestInfoKey{}) } @@ -39,11 +39,11 @@ func RequestInfoFromContext(ctx context.Context) interface{} { type clientHandshakeInfoKey struct{} // ClientHandshakeInfoFromContext extracts the ClientHandshakeInfo from ctx. -func ClientHandshakeInfoFromContext(ctx context.Context) interface{} { +func ClientHandshakeInfoFromContext(ctx context.Context) any { return ctx.Value(clientHandshakeInfoKey{}) } // NewClientHandshakeInfoContext creates a context with chi. -func NewClientHandshakeInfoContext(ctx context.Context, chi interface{}) context.Context { +func NewClientHandshakeInfoContext(ctx context.Context, chi any) context.Context { return context.WithValue(ctx, clientHandshakeInfoKey{}, chi) } diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 7edd196bd3d..3cf10ddfbd4 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -21,19 +21,52 @@ package envconfig import ( "os" + "strconv" "strings" ) -const ( - prefix = "GRPC_GO_" - txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS" - advertiseCompressorsStr = prefix + "ADVERTISE_COMPRESSORS" -) - var ( // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). - TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false") + TXTErrIgnore = boolFromEnv("GRPC_GO_IGNORE_TXT_ERRORS", true) // AdvertiseCompressors is set if registered compressor should be advertised // ("GRPC_GO_ADVERTISE_COMPRESSORS" is not "false"). - AdvertiseCompressors = !strings.EqualFold(os.Getenv(advertiseCompressorsStr), "false") + AdvertiseCompressors = boolFromEnv("GRPC_GO_ADVERTISE_COMPRESSORS", true) + // RingHashCap indicates the maximum ring size which defaults to 4096 + // entries but may be overridden by setting the environment variable + // "GRPC_RING_HASH_CAP". This does not override the default bounds + // checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M). + RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024) + // PickFirstLBConfig is set if we should support configuration of the + // pick_first LB policy. + PickFirstLBConfig = boolFromEnv("GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG", true) + // LeastRequestLB is set if we should support the least_request_experimental + // LB policy, which can be enabled by setting the environment variable + // "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true". + LeastRequestLB = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST", false) + // ALTSMaxConcurrentHandshakes is the maximum number of concurrent ALTS + // handshakes that can be performed. + ALTSMaxConcurrentHandshakes = uint64FromEnv("GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES", 100, 1, 100) ) + +func boolFromEnv(envVar string, def bool) bool { + if def { + // The default is true; return true unless the variable is "false". + return !strings.EqualFold(os.Getenv(envVar), "false") + } + // The default is false; return false unless the variable is "true". + return strings.EqualFold(os.Getenv(envVar), "true") +} + +func uint64FromEnv(envVar string, def, min, max uint64) uint64 { + v, err := strconv.ParseUint(os.Getenv(envVar), 10, 64) + if err != nil { + return def + } + if v < min { + return min + } + if v > max { + return max + } + return v +} diff --git a/vendor/google.golang.org/grpc/internal/envconfig/observability.go b/vendor/google.golang.org/grpc/internal/envconfig/observability.go index 821dd0a7c19..dd314cfb18f 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/observability.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/observability.go @@ -28,9 +28,15 @@ const ( var ( // ObservabilityConfig is the json configuration for the gcp/observability // package specified directly in the envObservabilityConfig env var. + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. ObservabilityConfig = os.Getenv(envObservabilityConfig) // ObservabilityConfigFile is the json configuration for the // gcp/observability specified in a file with the location specified in // envObservabilityConfigFile env var. + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. ObservabilityConfigFile = os.Getenv(envObservabilityConfigFile) ) diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go index af09711a3e8..02b4b6a1c10 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -20,7 +20,6 @@ package envconfig import ( "os" - "strings" ) const ( @@ -36,16 +35,6 @@ const ( // // When both bootstrap FileName and FileContent are set, FileName is used. XDSBootstrapFileContentEnv = "GRPC_XDS_BOOTSTRAP_CONFIG" - - ringHashSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" - clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - aggregateAndDNSSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" - rbacSupportEnv = "GRPC_XDS_EXPERIMENTAL_RBAC" - outlierDetectionSupportEnv = "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION" - federationEnv = "GRPC_EXPERIMENTAL_XDS_FEDERATION" - rlsInXDSEnv = "GRPC_EXPERIMENTAL_XDS_RLS_LB" - - c2pResolverTestOnlyTrafficDirectorURIEnv = "GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI" ) var ( @@ -64,38 +53,43 @@ var ( // XDSRingHash indicates whether ring hash support is enabled, which can be // disabled by setting the environment variable // "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false". - XDSRingHash = !strings.EqualFold(os.Getenv(ringHashSupportEnv), "false") + XDSRingHash = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH", true) // XDSClientSideSecurity is used to control processing of security // configuration on the client-side. // // Note that there is no env var protection for the server-side because we // have a brand new API on the server-side and users explicitly need to use // the new API to get security integration on the server. - XDSClientSideSecurity = !strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "false") - // XDSAggregateAndDNS indicates whether processing of aggregated cluster - // and DNS cluster is enabled, which can be enabled by setting the - // environment variable - // "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" to - // "true". - XDSAggregateAndDNS = !strings.EqualFold(os.Getenv(aggregateAndDNSSupportEnv), "false") + XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true) + // XDSAggregateAndDNS indicates whether processing of aggregated cluster and + // DNS cluster is enabled, which can be disabled by setting the environment + // variable "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" + // to "false". + XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true) // XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled, // which can be disabled by setting the environment variable // "GRPC_XDS_EXPERIMENTAL_RBAC" to "false". - XDSRBAC = !strings.EqualFold(os.Getenv(rbacSupportEnv), "false") + XDSRBAC = boolFromEnv("GRPC_XDS_EXPERIMENTAL_RBAC", true) // XDSOutlierDetection indicates whether outlier detection support is // enabled, which can be disabled by setting the environment variable // "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION" to "false". - XDSOutlierDetection = !strings.EqualFold(os.Getenv(outlierDetectionSupportEnv), "false") - // XDSFederation indicates whether federation support is enabled. - XDSFederation = strings.EqualFold(os.Getenv(federationEnv), "true") + XDSOutlierDetection = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", true) + // XDSFederation indicates whether federation support is enabled, which can + // be enabled by setting the environment variable + // "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true". + XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true) // XDSRLS indicates whether processing of Cluster Specifier plugins and - // support for the RLS CLuster Specifier is enabled, which can be enabled by + // support for the RLS CLuster Specifier is enabled, which can be disabled by // setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to - // "true". - XDSRLS = strings.EqualFold(os.Getenv(rlsInXDSEnv), "true") + // "false". + XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", true) // C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing. - C2PResolverTestOnlyTrafficDirectorURI = os.Getenv(c2pResolverTestOnlyTrafficDirectorURIEnv) + C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI") + // XDSCustomLBPolicy indicates whether Custom LB Policies are enabled, which + // can be disabled by setting the environment variable + // "GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG" to "false". + XDSCustomLBPolicy = boolFromEnv("GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG", true) ) diff --git a/vendor/google.golang.org/grpc/internal/googlecloud/manufacturer_linux.go b/vendor/google.golang.org/grpc/internal/googlecloud/manufacturer_linux.go index e53b8ffc837..6e455fb0a82 100644 --- a/vendor/google.golang.org/grpc/internal/googlecloud/manufacturer_linux.go +++ b/vendor/google.golang.org/grpc/internal/googlecloud/manufacturer_linux.go @@ -18,10 +18,10 @@ package googlecloud -import "io/ioutil" +import "os" const linuxProductNameFile = "/sys/class/dmi/id/product_name" func manufacturer() ([]byte, error) { - return ioutil.ReadFile(linuxProductNameFile) + return os.ReadFile(linuxProductNameFile) } diff --git a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go index b68e26a3649..bfc45102ab2 100644 --- a/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go @@ -30,7 +30,7 @@ var Logger LoggerV2 var DepthLogger DepthLoggerV2 // InfoDepth logs to the INFO log at the specified depth. -func InfoDepth(depth int, args ...interface{}) { +func InfoDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.InfoDepth(depth, args...) } else { @@ -39,7 +39,7 @@ func InfoDepth(depth int, args ...interface{}) { } // WarningDepth logs to the WARNING log at the specified depth. -func WarningDepth(depth int, args ...interface{}) { +func WarningDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.WarningDepth(depth, args...) } else { @@ -48,7 +48,7 @@ func WarningDepth(depth int, args ...interface{}) { } // ErrorDepth logs to the ERROR log at the specified depth. -func ErrorDepth(depth int, args ...interface{}) { +func ErrorDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.ErrorDepth(depth, args...) } else { @@ -57,7 +57,7 @@ func ErrorDepth(depth int, args ...interface{}) { } // FatalDepth logs to the FATAL log at the specified depth. -func FatalDepth(depth int, args ...interface{}) { +func FatalDepth(depth int, args ...any) { if DepthLogger != nil { DepthLogger.FatalDepth(depth, args...) } else { @@ -71,35 +71,35 @@ func FatalDepth(depth int, args ...interface{}) { // is defined here to avoid a circular dependency. type LoggerV2 interface { // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. - Info(args ...interface{}) + Info(args ...any) // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. - Infoln(args ...interface{}) + Infoln(args ...any) // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. - Infof(format string, args ...interface{}) + Infof(format string, args ...any) // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. - Warning(args ...interface{}) + Warning(args ...any) // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. - Warningln(args ...interface{}) + Warningln(args ...any) // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. - Warningf(format string, args ...interface{}) + Warningf(format string, args ...any) // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. - Error(args ...interface{}) + Error(args ...any) // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - Errorln(args ...interface{}) + Errorln(args ...any) // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - Errorf(format string, args ...interface{}) + Errorf(format string, args ...any) // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatal(args ...interface{}) + Fatal(args ...any) // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalln(args ...interface{}) + Fatalln(args ...any) // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. // gRPC ensures that all Fatal logs will exit with os.Exit(1). // Implementations may also call os.Exit() with a non-zero exit code. - Fatalf(format string, args ...interface{}) + Fatalf(format string, args ...any) // V reports whether verbosity level l is at least the requested verbose level. V(l int) bool } @@ -116,11 +116,11 @@ type LoggerV2 interface { // later release. type DepthLoggerV2 interface { // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. - InfoDepth(depth int, args ...interface{}) + InfoDepth(depth int, args ...any) // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. - WarningDepth(depth int, args ...interface{}) + WarningDepth(depth int, args ...any) // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. - ErrorDepth(depth int, args ...interface{}) + ErrorDepth(depth int, args ...any) // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. - FatalDepth(depth int, args ...interface{}) + FatalDepth(depth int, args ...any) } diff --git a/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go b/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go index 82af70e96f1..faa998de763 100644 --- a/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go +++ b/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go @@ -31,7 +31,7 @@ type PrefixLogger struct { } // Infof does info logging. -func (pl *PrefixLogger) Infof(format string, args ...interface{}) { +func (pl *PrefixLogger) Infof(format string, args ...any) { if pl != nil { // Handle nil, so the tests can pass in a nil logger. format = pl.prefix + format @@ -42,7 +42,7 @@ func (pl *PrefixLogger) Infof(format string, args ...interface{}) { } // Warningf does warning logging. -func (pl *PrefixLogger) Warningf(format string, args ...interface{}) { +func (pl *PrefixLogger) Warningf(format string, args ...any) { if pl != nil { format = pl.prefix + format pl.logger.WarningDepth(1, fmt.Sprintf(format, args...)) @@ -52,7 +52,7 @@ func (pl *PrefixLogger) Warningf(format string, args ...interface{}) { } // Errorf does error logging. -func (pl *PrefixLogger) Errorf(format string, args ...interface{}) { +func (pl *PrefixLogger) Errorf(format string, args ...any) { if pl != nil { format = pl.prefix + format pl.logger.ErrorDepth(1, fmt.Sprintf(format, args...)) @@ -62,7 +62,10 @@ func (pl *PrefixLogger) Errorf(format string, args ...interface{}) { } // Debugf does info logging at verbose level 2. -func (pl *PrefixLogger) Debugf(format string, args ...interface{}) { +func (pl *PrefixLogger) Debugf(format string, args ...any) { + // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe + // rewrite PrefixLogger a little to ensure that we don't use the global + // `Logger` here, and instead use the `logger` field. if !Logger.V(2) { return } @@ -73,6 +76,15 @@ func (pl *PrefixLogger) Debugf(format string, args ...interface{}) { return } InfoDepth(1, fmt.Sprintf(format, args...)) + +} + +// V reports whether verbosity level l is at least the requested verbose level. +func (pl *PrefixLogger) V(l int) bool { + // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe + // rewrite PrefixLogger a little to ensure that we don't use the global + // `Logger` here, and instead use the `logger` field. + return Logger.V(l) } // NewPrefixLogger creates a prefix logger with the given prefix. diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go index 517ea70642a..aa97273e7d1 100644 --- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go @@ -72,3 +72,24 @@ func Uint64() uint64 { defer mu.Unlock() return r.Uint64() } + +// Uint32 implements rand.Uint32 on the grpcrand global source. +func Uint32() uint32 { + mu.Lock() + defer mu.Unlock() + return r.Uint32() +} + +// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. +func ExpFloat64() float64 { + mu.Lock() + defer mu.Unlock() + return r.ExpFloat64() +} + +// Shuffle implements rand.Shuffle on the grpcrand global source. +var Shuffle = func(n int, f func(int, int)) { + mu.Lock() + defer mu.Unlock() + r.Shuffle(n, f) +} diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go new file mode 100644 index 00000000000..900917dbe6c --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go @@ -0,0 +1,125 @@ +/* + * + * Copyright 2022 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpcsync + +import ( + "context" + "sync" + + "google.golang.org/grpc/internal/buffer" +) + +// CallbackSerializer provides a mechanism to schedule callbacks in a +// synchronized manner. It provides a FIFO guarantee on the order of execution +// of scheduled callbacks. New callbacks can be scheduled by invoking the +// Schedule() method. +// +// This type is safe for concurrent access. +type CallbackSerializer struct { + // done is closed once the serializer is shut down completely, i.e all + // scheduled callbacks are executed and the serializer has deallocated all + // its resources. + done chan struct{} + + callbacks *buffer.Unbounded + closedMu sync.Mutex + closed bool +} + +// NewCallbackSerializer returns a new CallbackSerializer instance. The provided +// context will be passed to the scheduled callbacks. Users should cancel the +// provided context to shutdown the CallbackSerializer. It is guaranteed that no +// callbacks will be added once this context is canceled, and any pending un-run +// callbacks will be executed before the serializer is shut down. +func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { + cs := &CallbackSerializer{ + done: make(chan struct{}), + callbacks: buffer.NewUnbounded(), + } + go cs.run(ctx) + return cs +} + +// Schedule adds a callback to be scheduled after existing callbacks are run. +// +// Callbacks are expected to honor the context when performing any blocking +// operations, and should return early when the context is canceled. +// +// Return value indicates if the callback was successfully added to the list of +// callbacks to be executed by the serializer. It is not possible to add +// callbacks once the context passed to NewCallbackSerializer is cancelled. +func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool { + cs.closedMu.Lock() + defer cs.closedMu.Unlock() + + if cs.closed { + return false + } + cs.callbacks.Put(f) + return true +} + +func (cs *CallbackSerializer) run(ctx context.Context) { + var backlog []func(context.Context) + + defer close(cs.done) + for ctx.Err() == nil { + select { + case <-ctx.Done(): + // Do nothing here. Next iteration of the for loop will not happen, + // since ctx.Err() would be non-nil. + case callback, ok := <-cs.callbacks.Get(): + if !ok { + return + } + cs.callbacks.Load() + callback.(func(ctx context.Context))(ctx) + } + } + + // Fetch pending callbacks if any, and execute them before returning from + // this method and closing cs.done. + cs.closedMu.Lock() + cs.closed = true + backlog = cs.fetchPendingCallbacks() + cs.callbacks.Close() + cs.closedMu.Unlock() + for _, b := range backlog { + b(ctx) + } +} + +func (cs *CallbackSerializer) fetchPendingCallbacks() []func(context.Context) { + var backlog []func(context.Context) + for { + select { + case b := <-cs.callbacks.Get(): + backlog = append(backlog, b.(func(context.Context))) + cs.callbacks.Load() + default: + return backlog + } + } +} + +// Done returns a channel that is closed after the context passed to +// NewCallbackSerializer is canceled and all callbacks have been executed. +func (cs *CallbackSerializer) Done() <-chan struct{} { + return cs.done +} diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go b/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go new file mode 100644 index 00000000000..aef8cec1ab0 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go @@ -0,0 +1,121 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpcsync + +import ( + "context" + "sync" +) + +// Subscriber represents an entity that is subscribed to messages published on +// a PubSub. It wraps the callback to be invoked by the PubSub when a new +// message is published. +type Subscriber interface { + // OnMessage is invoked when a new message is published. Implementations + // must not block in this method. + OnMessage(msg any) +} + +// PubSub is a simple one-to-many publish-subscribe system that supports +// messages of arbitrary type. It guarantees that messages are delivered in +// the same order in which they were published. +// +// Publisher invokes the Publish() method to publish new messages, while +// subscribers interested in receiving these messages register a callback +// via the Subscribe() method. +// +// Once a PubSub is stopped, no more messages can be published, but any pending +// published messages will be delivered to the subscribers. Done may be used +// to determine when all published messages have been delivered. +type PubSub struct { + cs *CallbackSerializer + + // Access to the below fields are guarded by this mutex. + mu sync.Mutex + msg any + subscribers map[Subscriber]bool +} + +// NewPubSub returns a new PubSub instance. Users should cancel the +// provided context to shutdown the PubSub. +func NewPubSub(ctx context.Context) *PubSub { + return &PubSub{ + cs: NewCallbackSerializer(ctx), + subscribers: map[Subscriber]bool{}, + } +} + +// Subscribe registers the provided Subscriber to the PubSub. +// +// If the PubSub contains a previously published message, the Subscriber's +// OnMessage() callback will be invoked asynchronously with the existing +// message to begin with, and subsequently for every newly published message. +// +// The caller is responsible for invoking the returned cancel function to +// unsubscribe itself from the PubSub. +func (ps *PubSub) Subscribe(sub Subscriber) (cancel func()) { + ps.mu.Lock() + defer ps.mu.Unlock() + + ps.subscribers[sub] = true + + if ps.msg != nil { + msg := ps.msg + ps.cs.Schedule(func(context.Context) { + ps.mu.Lock() + defer ps.mu.Unlock() + if !ps.subscribers[sub] { + return + } + sub.OnMessage(msg) + }) + } + + return func() { + ps.mu.Lock() + defer ps.mu.Unlock() + delete(ps.subscribers, sub) + } +} + +// Publish publishes the provided message to the PubSub, and invokes +// callbacks registered by subscribers asynchronously. +func (ps *PubSub) Publish(msg any) { + ps.mu.Lock() + defer ps.mu.Unlock() + + ps.msg = msg + for sub := range ps.subscribers { + s := sub + ps.cs.Schedule(func(context.Context) { + ps.mu.Lock() + defer ps.mu.Unlock() + if !ps.subscribers[s] { + return + } + s.OnMessage(msg) + }) + } +} + +// Done returns a channel that is closed after the context passed to NewPubSub +// is canceled and all updates have been sent to subscribers. +func (ps *PubSub) Done() <-chan struct{} { + return ps.cs.Done() +} diff --git a/vendor/google.golang.org/grpc/internal/idle/idle.go b/vendor/google.golang.org/grpc/internal/idle/idle.go new file mode 100644 index 00000000000..6c272476e5e --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/idle/idle.go @@ -0,0 +1,301 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package idle contains a component for managing idleness (entering and exiting) +// based on RPC activity. +package idle + +import ( + "fmt" + "math" + "sync" + "sync/atomic" + "time" + + "google.golang.org/grpc/grpclog" +) + +// For overriding in unit tests. +var timeAfterFunc = func(d time.Duration, f func()) *time.Timer { + return time.AfterFunc(d, f) +} + +// Enforcer is the functionality provided by grpc.ClientConn to enter +// and exit from idle mode. +type Enforcer interface { + ExitIdleMode() error + EnterIdleMode() error +} + +// Manager defines the functionality required to track RPC activity on a +// channel. +type Manager interface { + OnCallBegin() error + OnCallEnd() + Close() +} + +type noopManager struct{} + +func (noopManager) OnCallBegin() error { return nil } +func (noopManager) OnCallEnd() {} +func (noopManager) Close() {} + +// manager implements the Manager interface. It uses atomic operations to +// synchronize access to shared state and a mutex to guarantee mutual exclusion +// in a critical section. +type manager struct { + // State accessed atomically. + lastCallEndTime int64 // Unix timestamp in nanos; time when the most recent RPC completed. + activeCallsCount int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there. + activeSinceLastTimerCheck int32 // Boolean; True if there was an RPC since the last timer callback. + closed int32 // Boolean; True when the manager is closed. + + // Can be accessed without atomics or mutex since these are set at creation + // time and read-only after that. + enforcer Enforcer // Functionality provided by grpc.ClientConn. + timeout int64 // Idle timeout duration nanos stored as an int64. + logger grpclog.LoggerV2 + + // idleMu is used to guarantee mutual exclusion in two scenarios: + // - Opposing intentions: + // - a: Idle timeout has fired and handleIdleTimeout() is trying to put + // the channel in idle mode because the channel has been inactive. + // - b: At the same time an RPC is made on the channel, and OnCallBegin() + // is trying to prevent the channel from going idle. + // - Competing intentions: + // - The channel is in idle mode and there are multiple RPCs starting at + // the same time, all trying to move the channel out of idle. Only one + // of them should succeed in doing so, while the other RPCs should + // piggyback on the first one and be successfully handled. + idleMu sync.RWMutex + actuallyIdle bool + timer *time.Timer +} + +// ManagerOptions is a collection of options used by +// NewManager. +type ManagerOptions struct { + Enforcer Enforcer + Timeout time.Duration + Logger grpclog.LoggerV2 +} + +// NewManager creates a new idleness manager implementation for the +// given idle timeout. +func NewManager(opts ManagerOptions) Manager { + if opts.Timeout == 0 { + return noopManager{} + } + + m := &manager{ + enforcer: opts.Enforcer, + timeout: int64(opts.Timeout), + logger: opts.Logger, + } + m.timer = timeAfterFunc(opts.Timeout, m.handleIdleTimeout) + return m +} + +// resetIdleTimer resets the idle timer to the given duration. This method +// should only be called from the timer callback. +func (m *manager) resetIdleTimer(d time.Duration) { + m.idleMu.Lock() + defer m.idleMu.Unlock() + + if m.timer == nil { + // Only close sets timer to nil. We are done. + return + } + + // It is safe to ignore the return value from Reset() because this method is + // only ever called from the timer callback, which means the timer has + // already fired. + m.timer.Reset(d) +} + +// handleIdleTimeout is the timer callback that is invoked upon expiry of the +// configured idle timeout. The channel is considered inactive if there are no +// ongoing calls and no RPC activity since the last time the timer fired. +func (m *manager) handleIdleTimeout() { + if m.isClosed() { + return + } + + if atomic.LoadInt32(&m.activeCallsCount) > 0 { + m.resetIdleTimer(time.Duration(m.timeout)) + return + } + + // There has been activity on the channel since we last got here. Reset the + // timer and return. + if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 { + // Set the timer to fire after a duration of idle timeout, calculated + // from the time the most recent RPC completed. + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 0) + m.resetIdleTimer(time.Duration(atomic.LoadInt64(&m.lastCallEndTime) + m.timeout - time.Now().UnixNano())) + return + } + + // This CAS operation is extremely likely to succeed given that there has + // been no activity since the last time we were here. Setting the + // activeCallsCount to -math.MaxInt32 indicates to OnCallBegin() that the + // channel is either in idle mode or is trying to get there. + if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) { + // This CAS operation can fail if an RPC started after we checked for + // activity at the top of this method, or one was ongoing from before + // the last time we were here. In both case, reset the timer and return. + m.resetIdleTimer(time.Duration(m.timeout)) + return + } + + // Now that we've set the active calls count to -math.MaxInt32, it's time to + // actually move to idle mode. + if m.tryEnterIdleMode() { + // Successfully entered idle mode. No timer needed until we exit idle. + return + } + + // Failed to enter idle mode due to a concurrent RPC that kept the channel + // active, or because of an error from the channel. Undo the attempt to + // enter idle, and reset the timer to try again later. + atomic.AddInt32(&m.activeCallsCount, math.MaxInt32) + m.resetIdleTimer(time.Duration(m.timeout)) +} + +// tryEnterIdleMode instructs the channel to enter idle mode. But before +// that, it performs a last minute check to ensure that no new RPC has come in, +// making the channel active. +// +// Return value indicates whether or not the channel moved to idle mode. +// +// Holds idleMu which ensures mutual exclusion with exitIdleMode. +func (m *manager) tryEnterIdleMode() bool { + m.idleMu.Lock() + defer m.idleMu.Unlock() + + if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 { + // We raced and lost to a new RPC. Very rare, but stop entering idle. + return false + } + if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 { + // An very short RPC could have come in (and also finished) after we + // checked for calls count and activity in handleIdleTimeout(), but + // before the CAS operation. So, we need to check for activity again. + return false + } + + // No new RPCs have come in since we last set the active calls count value + // -math.MaxInt32 in the timer callback. And since we have the lock, it is + // safe to enter idle mode now. + if err := m.enforcer.EnterIdleMode(); err != nil { + m.logger.Errorf("Failed to enter idle mode: %v", err) + return false + } + + // Successfully entered idle mode. + m.actuallyIdle = true + return true +} + +// OnCallBegin is invoked at the start of every RPC. +func (m *manager) OnCallBegin() error { + if m.isClosed() { + return nil + } + + if atomic.AddInt32(&m.activeCallsCount, 1) > 0 { + // Channel is not idle now. Set the activity bit and allow the call. + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1) + return nil + } + + // Channel is either in idle mode or is in the process of moving to idle + // mode. Attempt to exit idle mode to allow this RPC. + if err := m.exitIdleMode(); err != nil { + // Undo the increment to calls count, and return an error causing the + // RPC to fail. + atomic.AddInt32(&m.activeCallsCount, -1) + return err + } + + atomic.StoreInt32(&m.activeSinceLastTimerCheck, 1) + return nil +} + +// exitIdleMode instructs the channel to exit idle mode. +// +// Holds idleMu which ensures mutual exclusion with tryEnterIdleMode. +func (m *manager) exitIdleMode() error { + m.idleMu.Lock() + defer m.idleMu.Unlock() + + if !m.actuallyIdle { + // This can happen in two scenarios: + // - handleIdleTimeout() set the calls count to -math.MaxInt32 and called + // tryEnterIdleMode(). But before the latter could grab the lock, an RPC + // came in and OnCallBegin() noticed that the calls count is negative. + // - Channel is in idle mode, and multiple new RPCs come in at the same + // time, all of them notice a negative calls count in OnCallBegin and get + // here. The first one to get the lock would got the channel to exit idle. + // + // Either way, nothing to do here. + return nil + } + + if err := m.enforcer.ExitIdleMode(); err != nil { + return fmt.Errorf("channel failed to exit idle mode: %v", err) + } + + // Undo the idle entry process. This also respects any new RPC attempts. + atomic.AddInt32(&m.activeCallsCount, math.MaxInt32) + m.actuallyIdle = false + + // Start a new timer to fire after the configured idle timeout. + m.timer = timeAfterFunc(time.Duration(m.timeout), m.handleIdleTimeout) + return nil +} + +// OnCallEnd is invoked at the end of every RPC. +func (m *manager) OnCallEnd() { + if m.isClosed() { + return + } + + // Record the time at which the most recent call finished. + atomic.StoreInt64(&m.lastCallEndTime, time.Now().UnixNano()) + + // Decrement the active calls count. This count can temporarily go negative + // when the timer callback is in the process of moving the channel to idle + // mode, but one or more RPCs come in and complete before the timer callback + // can get done with the process of moving to idle mode. + atomic.AddInt32(&m.activeCallsCount, -1) +} + +func (m *manager) isClosed() bool { + return atomic.LoadInt32(&m.closed) == 1 +} + +func (m *manager) Close() { + atomic.StoreInt32(&m.closed, 1) + + m.idleMu.Lock() + m.timer.Stop() + m.timer = nil + m.idleMu.Unlock() +} diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index fd0ee3dcaf1..c8a8c76d628 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -30,7 +30,7 @@ import ( var ( // WithHealthCheckFunc is set by dialoptions.go - WithHealthCheckFunc interface{} // func (HealthChecker) DialOption + WithHealthCheckFunc any // func (HealthChecker) DialOption // HealthCheckFunc is used to provide client-side LB channel health checking HealthCheckFunc HealthChecker // BalancerUnregister is exported by package balancer to unregister a balancer. @@ -38,8 +38,12 @@ var ( // KeepaliveMinPingTime is the minimum ping interval. This must be 10s by // default, but tests may wish to set it lower for convenience. KeepaliveMinPingTime = 10 * time.Second + // KeepaliveMinServerPingTime is the minimum ping interval for servers. + // This must be 1s by default, but tests may wish to set it lower for + // convenience. + KeepaliveMinServerPingTime = time.Second // ParseServiceConfig parses a JSON representation of the service config. - ParseServiceConfig interface{} // func(string) *serviceconfig.ParseResult + ParseServiceConfig any // func(string) *serviceconfig.ParseResult // EqualServiceConfigForTesting is for testing service config generation and // parsing. Both a and b should be returned by ParseServiceConfig. // This function compares the config without rawJSON stripped, in case the @@ -49,44 +53,81 @@ var ( // given name. This is set by package certprovider for use from xDS // bootstrap code while parsing certificate provider configs in the // bootstrap file. - GetCertificateProviderBuilder interface{} // func(string) certprovider.Builder + GetCertificateProviderBuilder any // func(string) certprovider.Builder // GetXDSHandshakeInfoForTesting returns a pointer to the xds.HandshakeInfo // stored in the passed in attributes. This is set by // credentials/xds/xds.go. - GetXDSHandshakeInfoForTesting interface{} // func (*attributes.Attributes) *xds.HandshakeInfo + GetXDSHandshakeInfoForTesting any // func (*attributes.Attributes) *xds.HandshakeInfo // GetServerCredentials returns the transport credentials configured on a // gRPC server. An xDS-enabled server needs to know what type of credentials // is configured on the underlying gRPC server. This is set by server.go. - GetServerCredentials interface{} // func (*grpc.Server) credentials.TransportCredentials + GetServerCredentials any // func (*grpc.Server) credentials.TransportCredentials + // CanonicalString returns the canonical string of the code defined here: + // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md. + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + CanonicalString any // func (codes.Code) string // DrainServerTransports initiates a graceful close of existing connections // on a gRPC server accepted on the provided listener address. An // xDS-enabled server invokes this method on a grpc.Server when a particular // listener moves to "not-serving" mode. - DrainServerTransports interface{} // func(*grpc.Server, string) + DrainServerTransports any // func(*grpc.Server, string) // AddGlobalServerOptions adds an array of ServerOption that will be // effective globally for newly created servers. The priority will be: 1. // user-provided; 2. this method; 3. default values. - AddGlobalServerOptions interface{} // func(opt ...ServerOption) + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + AddGlobalServerOptions any // func(opt ...ServerOption) // ClearGlobalServerOptions clears the array of extra ServerOption. This // method is useful in testing and benchmarking. + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. ClearGlobalServerOptions func() // AddGlobalDialOptions adds an array of DialOption that will be effective // globally for newly created client channels. The priority will be: 1. // user-provided; 2. this method; 3. default values. - AddGlobalDialOptions interface{} // func(opt ...DialOption) + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + AddGlobalDialOptions any // func(opt ...DialOption) + // DisableGlobalDialOptions returns a DialOption that prevents the + // ClientConn from applying the global DialOptions (set via + // AddGlobalDialOptions). + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + DisableGlobalDialOptions any // func() grpc.DialOption // ClearGlobalDialOptions clears the array of extra DialOption. This // method is useful in testing and benchmarking. + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. ClearGlobalDialOptions func() + // JoinDialOptions combines the dial options passed as arguments into a + // single dial option. + JoinDialOptions any // func(...grpc.DialOption) grpc.DialOption // JoinServerOptions combines the server options passed as arguments into a // single server option. - JoinServerOptions interface{} // func(...grpc.ServerOption) grpc.ServerOption + JoinServerOptions any // func(...grpc.ServerOption) grpc.ServerOption // WithBinaryLogger returns a DialOption that specifies the binary logger // for a ClientConn. - WithBinaryLogger interface{} // func(binarylog.Logger) grpc.DialOption + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + WithBinaryLogger any // func(binarylog.Logger) grpc.DialOption // BinaryLogger returns a ServerOption that can set the binary logger for a // server. - BinaryLogger interface{} // func(binarylog.Logger) grpc.ServerOption + // + // This is used in the 1.0 release of gcp/observability, and thus must not be + // deleted or changed. + BinaryLogger any // func(binarylog.Logger) grpc.ServerOption + + // SubscribeToConnectivityStateChanges adds a grpcsync.Subscriber to a provided grpc.ClientConn + SubscribeToConnectivityStateChanges any // func(*grpc.ClientConn, grpcsync.Subscriber) // NewXDSResolverWithConfigForTesting creates a new xds resolver builder using // the provided xds bootstrap config instead of the global configuration from @@ -97,7 +138,7 @@ var ( // // This function should ONLY be used for testing and may not work with some // other features, including the CSDS service. - NewXDSResolverWithConfigForTesting interface{} // func([]byte) (resolver.Builder, error) + NewXDSResolverWithConfigForTesting any // func([]byte) (resolver.Builder, error) // RegisterRLSClusterSpecifierPluginForTesting registers the RLS Cluster // Specifier Plugin for testing purposes, regardless of the XDSRLS environment @@ -127,6 +168,13 @@ var ( // // TODO: Remove this function once the RBAC env var is removed. UnregisterRBACHTTPFilterForTesting func() + + // ORCAAllowAnyMinReportingInterval is for examples/orca use ONLY. + ORCAAllowAnyMinReportingInterval any // func(so *orca.ServiceOptions) + + // GRPCResolverSchemeExtraMetadata determines when gRPC will add extra + // metadata to RPCs. + GRPCResolverSchemeExtraMetadata string = "xds" ) // HealthChecker defines the signature of the client-side LB channel health checking function. @@ -137,7 +185,7 @@ var ( // // The health checking protocol is defined at: // https://github.com/grpc/grpc/blob/master/doc/health-checking.md -type HealthChecker func(ctx context.Context, newStream func(string) (interface{}, error), setConnectivityState func(connectivity.State, error), serviceName string) error +type HealthChecker func(ctx context.Context, newStream func(string) (any, error), setConnectivityState func(connectivity.State, error), serviceName string) error const ( // CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode. diff --git a/vendor/google.golang.org/grpc/internal/metadata/metadata.go b/vendor/google.golang.org/grpc/internal/metadata/metadata.go index b2980f8ac44..900bfb71608 100644 --- a/vendor/google.golang.org/grpc/internal/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/internal/metadata/metadata.go @@ -35,7 +35,7 @@ const mdKey = mdKeyType("grpc.internal.address.metadata") type mdValue metadata.MD -func (m mdValue) Equal(o interface{}) bool { +func (m mdValue) Equal(o any) bool { om, ok := o.(mdValue) if !ok { return false @@ -76,33 +76,11 @@ func Set(addr resolver.Address, md metadata.MD) resolver.Address { return addr } -// Validate returns an error if the input md contains invalid keys or values. -// -// If the header is not a pseudo-header, the following items are checked: -// - header names must contain one or more characters from this set [0-9 a-z _ - .]. -// - if the header-name ends with a "-bin" suffix, no validation of the header value is performed. -// - otherwise, the header value must contain one or more characters from the set [%x20-%x7E]. +// Validate validates every pair in md with ValidatePair. func Validate(md metadata.MD) error { for k, vals := range md { - // pseudo-header will be ignored - if k[0] == ':' { - continue - } - // check key, for i that saving a conversion if not using for range - for i := 0; i < len(k); i++ { - r := k[i] - if !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') && r != '.' && r != '-' && r != '_' { - return fmt.Errorf("header key %q contains illegal characters not in [0-9a-z-_.]", k) - } - } - if strings.HasSuffix(k, "-bin") { - continue - } - // check value - for _, val := range vals { - if hasNotPrintable(val) { - return fmt.Errorf("header key %q contains value with non-printable ASCII characters", k) - } + if err := ValidatePair(k, vals...); err != nil { + return err } } return nil @@ -118,3 +96,37 @@ func hasNotPrintable(msg string) bool { } return false } + +// ValidatePair validate a key-value pair with the following rules (the pseudo-header will be skipped) : +// +// - key must contain one or more characters. +// - the characters in the key must be contained in [0-9 a-z _ - .]. +// - if the key ends with a "-bin" suffix, no validation of the corresponding value is performed. +// - the characters in the every value must be printable (in [%x20-%x7E]). +func ValidatePair(key string, vals ...string) error { + // key should not be empty + if key == "" { + return fmt.Errorf("there is an empty key in the header") + } + // pseudo-header will be ignored + if key[0] == ':' { + return nil + } + // check key, for i that saving a conversion if not using for range + for i := 0; i < len(key); i++ { + r := key[i] + if !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') && r != '.' && r != '-' && r != '_' { + return fmt.Errorf("header key %q contains illegal characters not in [0-9a-z-_.]", key) + } + } + if strings.HasSuffix(key, "-bin") { + return nil + } + // check value + for _, val := range vals { + if hasNotPrintable(val) { + return fmt.Errorf("header key %q contains value with non-printable ASCII characters", key) + } + } + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/internal/pretty/pretty.go index 0177af4b511..7033191375d 100644 --- a/vendor/google.golang.org/grpc/internal/pretty/pretty.go +++ b/vendor/google.golang.org/grpc/internal/pretty/pretty.go @@ -35,7 +35,7 @@ const jsonIndent = " " // ToJSON marshals the input into a json string. // // If marshal fails, it falls back to fmt.Sprintf("%+v"). -func ToJSON(e interface{}) string { +func ToJSON(e any) string { switch ee := e.(type) { case protov1.Message: mm := jsonpb.Marshaler{Indent: jsonIndent} diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index c7a18a948ad..f0603871c93 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -92,7 +92,7 @@ type ClientStream interface { // calling RecvMsg on the same stream at the same time, but it is not safe // to call SendMsg on the same stream in different goroutines. It is also // not safe to call CloseSend concurrently with SendMsg. - SendMsg(m interface{}) error + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the stream completes successfully. On // any other error, the stream is aborted and the error contains the RPC @@ -101,7 +101,7 @@ type ClientStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // ClientInterceptor is an interceptor for gRPC client streams. diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index 75301c51491..99e1e5b36c8 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -62,7 +62,8 @@ const ( defaultPort = "443" defaultDNSSvrPort = "53" golang = "GO" - // txtPrefix is the prefix string to be prepended to the host name for txt record lookup. + // txtPrefix is the prefix string to be prepended to the host name for txt + // record lookup. txtPrefix = "_grpc_config." // In DNS, service config is encoded in a TXT record via the mechanism // described in RFC-1464 using the attribute name grpc_config. @@ -86,14 +87,14 @@ var ( minDNSResRate = 30 * time.Second ) -var customAuthorityDialler = func(authority string) func(ctx context.Context, network, address string) (net.Conn, error) { - return func(ctx context.Context, network, address string) (net.Conn, error) { +var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) { + return func(ctx context.Context, network, _ string) (net.Conn, error) { var dialer net.Dialer - return dialer.DialContext(ctx, network, authority) + return dialer.DialContext(ctx, network, address) } } -var customAuthorityResolver = func(authority string) (netResolver, error) { +var newNetResolver = func(authority string) (netResolver, error) { host, port, err := parseTarget(authority, defaultDNSSvrPort) if err != nil { return nil, err @@ -103,7 +104,7 @@ var customAuthorityResolver = func(authority string) (netResolver, error) { return &net.Resolver{ PreferGo: true, - Dial: customAuthorityDialler(authorityWithPort), + Dial: addressDialer(authorityWithPort), }, nil } @@ -114,9 +115,10 @@ func NewBuilder() resolver.Builder { type dnsBuilder struct{} -// Build creates and starts a DNS resolver that watches the name resolution of the target. +// Build creates and starts a DNS resolver that watches the name resolution of +// the target. func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { - host, port, err := parseTarget(target.Endpoint, defaultPort) + host, port, err := parseTarget(target.Endpoint(), defaultPort) if err != nil { return nil, err } @@ -140,10 +142,10 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts disableServiceConfig: opts.DisableServiceConfig, } - if target.Authority == "" { + if target.URL.Host == "" { d.resolver = defaultResolver } else { - d.resolver, err = customAuthorityResolver(target.Authority) + d.resolver, err = newNetResolver(target.URL.Host) if err != nil { return nil, err } @@ -180,19 +182,22 @@ type dnsResolver struct { ctx context.Context cancel context.CancelFunc cc resolver.ClientConn - // rn channel is used by ResolveNow() to force an immediate resolution of the target. + // rn channel is used by ResolveNow() to force an immediate resolution of the + // target. rn chan struct{} - // wg is used to enforce Close() to return after the watcher() goroutine has finished. - // Otherwise, data race will be possible. [Race Example] in dns_resolver_test we - // replace the real lookup functions with mocked ones to facilitate testing. - // If Close() doesn't wait for watcher() goroutine finishes, race detector sometimes - // will warns lookup (READ the lookup function pointers) inside watcher() goroutine - // has data race with replaceNetFunc (WRITE the lookup function pointers). + // wg is used to enforce Close() to return after the watcher() goroutine has + // finished. Otherwise, data race will be possible. [Race Example] in + // dns_resolver_test we replace the real lookup functions with mocked ones to + // facilitate testing. If Close() doesn't wait for watcher() goroutine + // finishes, race detector sometimes will warns lookup (READ the lookup + // function pointers) inside watcher() goroutine has data race with + // replaceNetFunc (WRITE the lookup function pointers). wg sync.WaitGroup disableServiceConfig bool } -// ResolveNow invoke an immediate resolution of the target that this dnsResolver watches. +// ResolveNow invoke an immediate resolution of the target that this +// dnsResolver watches. func (d *dnsResolver) ResolveNow(resolver.ResolveNowOptions) { select { case d.rn <- struct{}{}: @@ -220,8 +225,8 @@ func (d *dnsResolver) watcher() { var timer *time.Timer if err == nil { - // Success resolving, wait for the next ResolveNow. However, also wait 30 seconds at the very least - // to prevent constantly re-resolving. + // Success resolving, wait for the next ResolveNow. However, also wait 30 + // seconds at the very least to prevent constantly re-resolving. backoffIndex = 1 timer = newTimerDNSResRate(minDNSResRate) select { @@ -231,7 +236,8 @@ func (d *dnsResolver) watcher() { case <-d.rn: } } else { - // Poll on an error found in DNS Resolver or an error received from ClientConn. + // Poll on an error found in DNS Resolver or an error received from + // ClientConn. timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex)) backoffIndex++ } @@ -278,7 +284,8 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { } func handleDNSError(err error, lookupType string) error { - if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { + dnsErr, ok := err.(*net.DNSError) + if ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { // Timeouts and temporary errors should be communicated to gRPC to // attempt another DNS query (with backoff). Other errors should be // suppressed (they may represent the absence of a TXT record). @@ -307,10 +314,12 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { res += s } - // TXT record must have "grpc_config=" attribute in order to be used as service config. + // TXT record must have "grpc_config=" attribute in order to be used as + // service config. if !strings.HasPrefix(res, txtAttribute) { logger.Warningf("dns: TXT record %v missing %v attribute", res, txtAttribute) - // This is not an error; it is the equivalent of not having a service config. + // This is not an error; it is the equivalent of not having a service + // config. return nil } sc := canaryingSC(strings.TrimPrefix(res, txtAttribute)) @@ -352,9 +361,10 @@ func (d *dnsResolver) lookup() (*resolver.State, error) { return &state, nil } -// formatIP returns ok = false if addr is not a valid textual representation of an IP address. -// If addr is an IPv4 address, return the addr and ok = true. -// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true. +// formatIP returns ok = false if addr is not a valid textual representation of +// an IP address. If addr is an IPv4 address, return the addr and ok = true. +// If addr is an IPv6 address, return the addr enclosed in square brackets and +// ok = true. func formatIP(addr string) (addrIP string, ok bool) { ip := net.ParseIP(addr) if ip == nil { @@ -366,10 +376,10 @@ func formatIP(addr string) (addrIP string, ok bool) { return "[" + addr + "]", true } -// parseTarget takes the user input target string and default port, returns formatted host and port info. -// If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in square brackets, brackets -// are stripped when setting the host. +// parseTarget takes the user input target string and default port, returns +// formatted host and port info. If target doesn't specify a port, set the port +// to be the defaultPort. If target is in IPv6 format and host-name is enclosed +// in square brackets, brackets are stripped when setting the host. // examples: // target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443" // target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80" @@ -385,12 +395,14 @@ func parseTarget(target, defaultPort string) (host, port string, err error) { } if host, port, err = net.SplitHostPort(target); err == nil { if port == "" { - // If the port field is empty (target ends with colon), e.g. "[::1]:", this is an error. + // If the port field is empty (target ends with colon), e.g. "[::1]:", + // this is an error. return "", "", errEndsWithColon } // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port if host == "" { - // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed. + // Keep consistent with net.Dial(): If the host is empty, as in ":80", + // the local system is assumed. host = "localhost" } return host, port, nil diff --git a/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go b/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go index 520d9229e1e..afac56572ad 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go +++ b/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go @@ -20,13 +20,20 @@ // name without scheme back to gRPC as resolved address. package passthrough -import "google.golang.org/grpc/resolver" +import ( + "errors" + + "google.golang.org/grpc/resolver" +) const scheme = "passthrough" type passthroughBuilder struct{} func (*passthroughBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { + if target.Endpoint() == "" && opts.Dialer == nil { + return nil, errors.New("passthrough: received empty target in Build()") + } r := &passthroughResolver{ target: target, cc: cc, @@ -45,7 +52,7 @@ type passthroughResolver struct { } func (r *passthroughResolver) start() { - r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}}) + r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint()}}}) } func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOptions) {} diff --git a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go index 7f1a702cacb..16091168773 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go +++ b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go @@ -34,8 +34,8 @@ type builder struct { } func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) { - if target.Authority != "" { - return nil, fmt.Errorf("invalid (non-empty) authority: %v", target.Authority) + if target.URL.Host != "" { + return nil, fmt.Errorf("invalid (non-empty) authority: %v", target.URL.Host) } // gRPC was parsing the dial target manually before PR #4817, and we diff --git a/vendor/google.golang.org/grpc/internal/serviceconfig/duration.go b/vendor/google.golang.org/grpc/internal/serviceconfig/duration.go new file mode 100644 index 00000000000..11d82afcc7e --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/serviceconfig/duration.go @@ -0,0 +1,130 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package serviceconfig + +import ( + "encoding/json" + "fmt" + "math" + "strconv" + "strings" + "time" +) + +// Duration defines JSON marshal and unmarshal methods to conform to the +// protobuf JSON spec defined [here]. +// +// [here]: https://protobuf.dev/reference/protobuf/google.protobuf/#duration +type Duration time.Duration + +func (d Duration) String() string { + return fmt.Sprint(time.Duration(d)) +} + +// MarshalJSON converts from d to a JSON string output. +func (d Duration) MarshalJSON() ([]byte, error) { + ns := time.Duration(d).Nanoseconds() + sec := ns / int64(time.Second) + ns = ns % int64(time.Second) + + var sign string + if sec < 0 || ns < 0 { + sign, sec, ns = "-", -1*sec, -1*ns + } + + // Generated output always contains 0, 3, 6, or 9 fractional digits, + // depending on required precision. + str := fmt.Sprintf("%s%d.%09d", sign, sec, ns) + str = strings.TrimSuffix(str, "000") + str = strings.TrimSuffix(str, "000") + str = strings.TrimSuffix(str, ".000") + return []byte(fmt.Sprintf("\"%ss\"", str)), nil +} + +// UnmarshalJSON unmarshals b as a duration JSON string into d. +func (d *Duration) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + if !strings.HasSuffix(s, "s") { + return fmt.Errorf("malformed duration %q: missing seconds unit", s) + } + neg := false + if s[0] == '-' { + neg = true + s = s[1:] + } + ss := strings.SplitN(s[:len(s)-1], ".", 3) + if len(ss) > 2 { + return fmt.Errorf("malformed duration %q: too many decimals", s) + } + // hasDigits is set if either the whole or fractional part of the number is + // present, since both are optional but one is required. + hasDigits := false + var sec, ns int64 + if len(ss[0]) > 0 { + var err error + if sec, err = strconv.ParseInt(ss[0], 10, 64); err != nil { + return fmt.Errorf("malformed duration %q: %v", s, err) + } + // Maximum seconds value per the durationpb spec. + const maxProtoSeconds = 315_576_000_000 + if sec > maxProtoSeconds { + return fmt.Errorf("out of range: %q", s) + } + hasDigits = true + } + if len(ss) == 2 && len(ss[1]) > 0 { + if len(ss[1]) > 9 { + return fmt.Errorf("malformed duration %q: too many digits after decimal", s) + } + var err error + if ns, err = strconv.ParseInt(ss[1], 10, 64); err != nil { + return fmt.Errorf("malformed duration %q: %v", s, err) + } + for i := 9; i > len(ss[1]); i-- { + ns *= 10 + } + hasDigits = true + } + if !hasDigits { + return fmt.Errorf("malformed duration %q: contains no numbers", s) + } + + if neg { + sec *= -1 + ns *= -1 + } + + // Maximum/minimum seconds/nanoseconds representable by Go's time.Duration. + const maxSeconds = math.MaxInt64 / int64(time.Second) + const maxNanosAtMaxSeconds = math.MaxInt64 % int64(time.Second) + const minSeconds = math.MinInt64 / int64(time.Second) + const minNanosAtMinSeconds = math.MinInt64 % int64(time.Second) + + if sec > maxSeconds || (sec == maxSeconds && ns >= maxNanosAtMaxSeconds) { + *d = Duration(math.MaxInt64) + } else if sec < minSeconds || (sec == minSeconds && ns <= minNanosAtMinSeconds) { + *d = Duration(math.MinInt64) + } else { + *d = Duration(sec*int64(time.Second) + ns) + } + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go index b0ead4f54f8..4cf85cad9f8 100644 --- a/vendor/google.golang.org/grpc/internal/status/status.go +++ b/vendor/google.golang.org/grpc/internal/status/status.go @@ -49,7 +49,7 @@ func New(c codes.Code, msg string) *Status { } // Newf returns New(c, fmt.Sprintf(format, a...)). -func Newf(c codes.Code, format string, a ...interface{}) *Status { +func Newf(c codes.Code, format string, a ...any) *Status { return New(c, fmt.Sprintf(format, a...)) } @@ -64,7 +64,7 @@ func Err(c codes.Code, msg string) error { } // Errorf returns Error(c, fmt.Sprintf(format, a...)). -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return Err(c, fmt.Sprintf(format, a...)) } @@ -120,11 +120,11 @@ func (s *Status) WithDetails(details ...proto.Message) (*Status, error) { // Details returns a slice of details messages attached to the status. // If a detail cannot be decoded, the error is returned in place of the detail. -func (s *Status) Details() []interface{} { +func (s *Status) Details() []any { if s == nil || s.s == nil { return nil } - details := make([]interface{}, 0, len(s.s.Details)) + details := make([]any, 0, len(s.s.Details)) for _, any := range s.s.Details { detail := &ptypes.DynamicAny{} if err := ptypes.UnmarshalAny(any, detail); err != nil { diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 409769f48fd..b330ccedc8a 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -22,6 +22,7 @@ import ( "bytes" "errors" "fmt" + "net" "runtime" "strconv" "sync" @@ -29,6 +30,7 @@ import ( "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" + "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/status" ) @@ -38,7 +40,7 @@ var updateHeaderTblSize = func(e *hpack.Encoder, v uint32) { } type itemNode struct { - it interface{} + it any next *itemNode } @@ -47,7 +49,7 @@ type itemList struct { tail *itemNode } -func (il *itemList) enqueue(i interface{}) { +func (il *itemList) enqueue(i any) { n := &itemNode{it: i} if il.tail == nil { il.head, il.tail = n, n @@ -59,11 +61,11 @@ func (il *itemList) enqueue(i interface{}) { // peek returns the first item in the list without removing it from the // list. -func (il *itemList) peek() interface{} { +func (il *itemList) peek() any { return il.head.it } -func (il *itemList) dequeue() interface{} { +func (il *itemList) dequeue() any { if il.head == nil { return nil } @@ -191,7 +193,7 @@ type goAway struct { code http2.ErrCode debugData []byte headsUp bool - closeConn bool + closeConn error // if set, loopyWriter will exit, resulting in conn closure } func (*goAway) isTransportResponseFrame() bool { return false } @@ -209,6 +211,14 @@ type outFlowControlSizeRequest struct { func (*outFlowControlSizeRequest) isTransportResponseFrame() bool { return false } +// closeConnection is an instruction to tell the loopy writer to flush the +// framer and exit, which will cause the transport's connection to be closed +// (by the client or server). The transport itself will close after the reader +// encounters the EOF caused by the connection closure. +type closeConnection struct{} + +func (closeConnection) isTransportResponseFrame() bool { return false } + type outStreamState int const ( @@ -326,7 +336,7 @@ func (c *controlBuffer) put(it cbItem) error { return err } -func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (bool, error) { +func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, error) { var wakeUp bool c.mu.Lock() if c.err != nil { @@ -363,7 +373,7 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (b } // Note argument f should never be nil. -func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bool, error) { +func (c *controlBuffer) execute(f func(it any) bool, it any) (bool, error) { c.mu.Lock() if c.err != nil { c.mu.Unlock() @@ -377,7 +387,7 @@ func (c *controlBuffer) execute(f func(it interface{}) bool, it interface{}) (bo return true, nil } -func (c *controlBuffer) get(block bool) (interface{}, error) { +func (c *controlBuffer) get(block bool) (any, error) { for { c.mu.Lock() if c.err != nil { @@ -408,7 +418,7 @@ func (c *controlBuffer) get(block bool) (interface{}, error) { select { case <-c.ch: case <-c.done: - return nil, ErrConnClosing + return nil, errors.New("transport closed by client") } } } @@ -478,12 +488,14 @@ type loopyWriter struct { hEnc *hpack.Encoder // HPACK encoder. bdpEst *bdpEstimator draining bool + conn net.Conn + logger *grpclog.PrefixLogger // Side-specific handlers ssGoAwayHandler func(*goAway) (bool, error) } -func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator) *loopyWriter { +func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter { var buf bytes.Buffer l := &loopyWriter{ side: s, @@ -496,6 +508,8 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato hBuf: &buf, hEnc: hpack.NewEncoder(&buf), bdpEst: bdpEst, + conn: conn, + logger: logger, } return l } @@ -513,23 +527,26 @@ const minBatchSize = 1000 // 2. Stream level flow control quota available. // // In each iteration of run loop, other than processing the incoming control -// frame, loopy calls processData, which processes one node from the activeStreams linked-list. -// This results in writing of HTTP2 frames into an underlying write buffer. -// When there's no more control frames to read from controlBuf, loopy flushes the write buffer. -// As an optimization, to increase the batch size for each flush, loopy yields the processor, once -// if the batch size is too low to give stream goroutines a chance to fill it up. +// frame, loopy calls processData, which processes one node from the +// activeStreams linked-list. This results in writing of HTTP2 frames into an +// underlying write buffer. When there's no more control frames to read from +// controlBuf, loopy flushes the write buffer. As an optimization, to increase +// the batch size for each flush, loopy yields the processor, once if the batch +// size is too low to give stream goroutines a chance to fill it up. +// +// Upon exiting, if the error causing the exit is not an I/O error, run() +// flushes and closes the underlying connection. Otherwise, the connection is +// left open to allow the I/O error to be encountered by the reader instead. func (l *loopyWriter) run() (err error) { defer func() { - if err == ErrConnClosing { - // Don't log ErrConnClosing as error since it happens - // 1. When the connection is closed by some other known issue. - // 2. User closed the connection. - // 3. A graceful close of connection. - if logger.V(logLevel) { - logger.Infof("transport: loopyWriter.run returning. %v", err) - } - err = nil + if l.logger.V(logLevel) { + l.logger.Infof("loopyWriter exiting with error: %v", err) } + if !isIOError(err) { + l.framer.writer.Flush() + l.conn.Close() + } + l.cbuf.finish() }() for { it, err := l.cbuf.get(true) @@ -574,7 +591,6 @@ func (l *loopyWriter) run() (err error) { } l.framer.writer.Flush() break hasdata - } } } @@ -583,11 +599,11 @@ func (l *loopyWriter) outgoingWindowUpdateHandler(w *outgoingWindowUpdate) error return l.framer.fr.WriteWindowUpdate(w.streamID, w.increment) } -func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error { +func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) { // Otherwise update the quota. if w.streamID == 0 { l.sendQuota += w.increment - return nil + return } // Find the stream and update it. if str, ok := l.estdStreams[w.streamID]; ok { @@ -595,10 +611,9 @@ func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota > 0 && str.state == waitingOnStreamQuota { str.state = active l.activeStreams.enqueue(str) - return nil + return } } - return nil } func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error { @@ -606,13 +621,11 @@ func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error { } func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error { - if err := l.applySettings(s.ss); err != nil { - return err - } + l.applySettings(s.ss) return l.framer.fr.WriteSettingsAck() } -func (l *loopyWriter) registerStreamHandler(h *registerStream) error { +func (l *loopyWriter) registerStreamHandler(h *registerStream) { str := &outStream{ id: h.streamID, state: empty, @@ -620,15 +633,14 @@ func (l *loopyWriter) registerStreamHandler(h *registerStream) error { wq: h.wq, } l.estdStreams[h.streamID] = str - return nil } func (l *loopyWriter) headerHandler(h *headerFrame) error { if l.side == serverSide { str, ok := l.estdStreams[h.streamID] if !ok { - if logger.V(logLevel) { - logger.Warningf("transport: loopy doesn't recognize the stream: %d", h.streamID) + if l.logger.V(logLevel) { + l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID) } return nil } @@ -655,19 +667,20 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error { itl: &itemList{}, wq: h.wq, } - str.itl.enqueue(h) - return l.originateStream(str) + return l.originateStream(str, h) } -func (l *loopyWriter) originateStream(str *outStream) error { - hdr := str.itl.dequeue().(*headerFrame) - if err := hdr.initStream(str.id); err != nil { - if err == ErrConnClosing { - return err - } - // Other errors(errStreamDrain) need not close transport. +func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error { + // l.draining is set when handling GoAway. In which case, we want to avoid + // creating new streams. + if l.draining { + // TODO: provide a better error with the reason we are in draining. + hdr.onOrphaned(errStreamDrain) return nil } + if err := hdr.initStream(str.id); err != nil { + return err + } if err := l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil { return err } @@ -682,8 +695,8 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He l.hBuf.Reset() for _, f := range hf { if err := l.hEnc.WriteField(f); err != nil { - if logger.V(logLevel) { - logger.Warningf("transport: loopyWriter.writeHeader encountered error while encoding headers: %v", err) + if l.logger.V(logLevel) { + l.logger.Warningf("Encountered error while encoding headers: %v", err) } } } @@ -721,10 +734,10 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He return nil } -func (l *loopyWriter) preprocessData(df *dataFrame) error { +func (l *loopyWriter) preprocessData(df *dataFrame) { str, ok := l.estdStreams[df.streamID] if !ok { - return nil + return } // If we got data for a stream it means that // stream was originated and the headers were sent out. @@ -733,7 +746,6 @@ func (l *loopyWriter) preprocessData(df *dataFrame) error { str.state = active l.activeStreams.enqueue(str) } - return nil } func (l *loopyWriter) pingHandler(p *ping) error { @@ -744,9 +756,8 @@ func (l *loopyWriter) pingHandler(p *ping) error { } -func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) error { +func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) { o.resp <- l.sendQuota - return nil } func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error { @@ -763,8 +774,9 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error { return err } } - if l.side == clientSide && l.draining && len(l.estdStreams) == 0 { - return ErrConnClosing + if l.draining && len(l.estdStreams) == 0 { + // Flush and close the connection; we are done with it. + return errors.New("finished processing active streams while in draining mode") } return nil } @@ -799,7 +811,8 @@ func (l *loopyWriter) incomingGoAwayHandler(*incomingGoAway) error { if l.side == clientSide { l.draining = true if len(l.estdStreams) == 0 { - return ErrConnClosing + // Flush and close the connection; we are done with it. + return errors.New("received GOAWAY with no active streams") } } return nil @@ -817,10 +830,10 @@ func (l *loopyWriter) goAwayHandler(g *goAway) error { return nil } -func (l *loopyWriter) handle(i interface{}) error { +func (l *loopyWriter) handle(i any) error { switch i := i.(type) { case *incomingWindowUpdate: - return l.incomingWindowUpdateHandler(i) + l.incomingWindowUpdateHandler(i) case *outgoingWindowUpdate: return l.outgoingWindowUpdateHandler(i) case *incomingSettings: @@ -830,7 +843,7 @@ func (l *loopyWriter) handle(i interface{}) error { case *headerFrame: return l.headerHandler(i) case *registerStream: - return l.registerStreamHandler(i) + l.registerStreamHandler(i) case *cleanupStream: return l.cleanupStreamHandler(i) case *earlyAbortStream: @@ -838,19 +851,24 @@ func (l *loopyWriter) handle(i interface{}) error { case *incomingGoAway: return l.incomingGoAwayHandler(i) case *dataFrame: - return l.preprocessData(i) + l.preprocessData(i) case *ping: return l.pingHandler(i) case *goAway: return l.goAwayHandler(i) case *outFlowControlSizeRequest: - return l.outFlowControlSizeRequestHandler(i) + l.outFlowControlSizeRequestHandler(i) + case closeConnection: + // Just return a non-I/O error and run() will flush and close the + // connection. + return ErrConnClosing default: return fmt.Errorf("transport: unknown control message type %T", i) } + return nil } -func (l *loopyWriter) applySettings(ss []http2.Setting) error { +func (l *loopyWriter) applySettings(ss []http2.Setting) { for _, s := range ss { switch s.ID { case http2.SettingInitialWindowSize: @@ -869,7 +887,6 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error { updateHeaderTblSize(l.hEnc, s.Val) } } - return nil } // processData removes the first stream from active streams, writes out at most 16KB @@ -903,7 +920,7 @@ func (l *loopyWriter) processData() (bool, error) { return false, err } if err := l.cleanupStreamHandler(trailer.cleanup); err != nil { - return false, nil + return false, err } } else { l.activeStreams.enqueue(str) diff --git a/vendor/google.golang.org/grpc/internal/transport/defaults.go b/vendor/google.golang.org/grpc/internal/transport/defaults.go index 9fa306b2e07..bc8ee074749 100644 --- a/vendor/google.golang.org/grpc/internal/transport/defaults.go +++ b/vendor/google.golang.org/grpc/internal/transport/defaults.go @@ -47,3 +47,9 @@ const ( defaultClientMaxHeaderListSize = uint32(16 << 20) defaultServerMaxHeaderListSize = uint32(16 << 20) ) + +// MaxStreamID is the upper bound for the stream ID before the current +// transport gracefully closes and new transport is created for subsequent RPCs. +// This is set to 75% of 2^31-1. Streams are identified with an unsigned 31-bit +// integer. It's exported so that tests can override it. +var MaxStreamID = uint32(math.MaxInt32 * 3 / 4) diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index fb272235d81..98f80e3fa00 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -39,6 +39,7 @@ import ( "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -46,24 +47,32 @@ import ( "google.golang.org/grpc/status" ) -// NewServerHandlerTransport returns a ServerTransport handling gRPC -// from inside an http.Handler. It requires that the http Server -// supports HTTP/2. +// NewServerHandlerTransport returns a ServerTransport handling gRPC from +// inside an http.Handler, or writes an HTTP error to w and returns an error. +// It requires that the http Server supports HTTP/2. func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler) (ServerTransport, error) { if r.ProtoMajor != 2 { - return nil, errors.New("gRPC requires HTTP/2") + msg := "gRPC requires HTTP/2" + http.Error(w, msg, http.StatusBadRequest) + return nil, errors.New(msg) } if r.Method != "POST" { - return nil, errors.New("invalid gRPC request method") + msg := fmt.Sprintf("invalid gRPC request method %q", r.Method) + http.Error(w, msg, http.StatusBadRequest) + return nil, errors.New(msg) } contentType := r.Header.Get("Content-Type") // TODO: do we assume contentType is lowercase? we did before contentSubtype, validContentType := grpcutil.ContentSubtype(contentType) if !validContentType { - return nil, errors.New("invalid gRPC request content-type") + msg := fmt.Sprintf("invalid gRPC request content-type %q", contentType) + http.Error(w, msg, http.StatusUnsupportedMediaType) + return nil, errors.New(msg) } if _, ok := w.(http.Flusher); !ok { - return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher") + msg := "gRPC requires a ResponseWriter supporting http.Flusher" + http.Error(w, msg, http.StatusInternalServerError) + return nil, errors.New(msg) } st := &serverHandlerTransport{ @@ -75,11 +84,14 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s contentSubtype: contentSubtype, stats: stats, } + st.logger = prefixLoggerForServerHandlerTransport(st) if v := r.Header.Get("grpc-timeout"); v != "" { to, err := decodeTimeout(v) if err != nil { - return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err) + msg := fmt.Sprintf("malformed grpc-timeout: %v", err) + http.Error(w, msg, http.StatusBadRequest) + return nil, status.Error(codes.Internal, msg) } st.timeoutSet = true st.timeout = to @@ -97,7 +109,9 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s for _, v := range vv { v, err := decodeMetadataHeader(k, v) if err != nil { - return nil, status.Errorf(codes.Internal, "malformed binary metadata: %v", err) + msg := fmt.Sprintf("malformed binary metadata %q in header %q: %v", v, k, err) + http.Error(w, msg, http.StatusBadRequest) + return nil, status.Error(codes.Internal, msg) } metakv = append(metakv, k, v) } @@ -138,15 +152,19 @@ type serverHandlerTransport struct { // TODO make sure this is consistent across handler_server and http2_server contentSubtype string - stats []stats.Handler + stats []stats.Handler + logger *grpclog.PrefixLogger } -func (ht *serverHandlerTransport) Close() { - ht.closeOnce.Do(ht.closeCloseChanOnce) +func (ht *serverHandlerTransport) Close(err error) { + ht.closeOnce.Do(func() { + if ht.logger.V(logLevel) { + ht.logger.Infof("Closing: %v", err) + } + close(ht.closedCh) + }) } -func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) } - func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) } // strAddr is a net.Addr backed by either a TCP "ip:port" string, or @@ -236,7 +254,7 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro }) } } - ht.Close() + ht.Close(errors.New("finished writing status")) return err } @@ -346,7 +364,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace case <-ht.req.Context().Done(): } cancel() - ht.Close() + ht.Close(errors.New("request is done processing")) }() req := ht.req @@ -435,7 +453,7 @@ func (ht *serverHandlerTransport) IncrMsgSent() {} func (ht *serverHandlerTransport) IncrMsgRecv() {} -func (ht *serverHandlerTransport) Drain() { +func (ht *serverHandlerTransport) Drain(debugData string) { panic("Drain() is not implemented") } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index d518b07e16f..badab8acf3b 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -38,6 +38,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" icredentials "google.golang.org/grpc/internal/credentials" + "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/grpcutil" imetadata "google.golang.org/grpc/internal/metadata" @@ -59,11 +60,15 @@ var clientConnectionCounter uint64 // http2Client implements the ClientTransport interface with HTTP2. type http2Client struct { - lastRead int64 // Keep this field 64-bit aligned. Accessed atomically. - ctx context.Context - cancel context.CancelFunc - ctxDone <-chan struct{} // Cache the ctx.Done() chan. - userAgent string + lastRead int64 // Keep this field 64-bit aligned. Accessed atomically. + ctx context.Context + cancel context.CancelFunc + ctxDone <-chan struct{} // Cache the ctx.Done() chan. + userAgent string + // address contains the resolver returned address for this transport. + // If the `ServerName` field is set, it takes precedence over `CallHdr.Host` + // passed to `NewStream`, when determining the :authority header. + address resolver.Address md metadata.MD conn net.Conn // underlying communication channel loopy *loopyWriter @@ -136,12 +141,12 @@ type http2Client struct { channelzID *channelz.Identifier czData *channelzData - onGoAway func(GoAwayReason) - onClose func() + onClose func(GoAwayReason) bufferPool *bufferPool connectionID uint64 + logger *grpclog.PrefixLogger } func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) { @@ -193,7 +198,7 @@ func isTemporary(err error) bool { // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { +func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (_ *http2Client, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -213,7 +218,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts if opts.FailOnNonTempDialError { return nil, connectionErrorf(isTemporary(err), err, "transport: error while dialing: %v", err) } - return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err) + return nil, connectionErrorf(true, err, "transport: Error while dialing: %v", err) } // Any further errors will close the underlying connection @@ -238,8 +243,11 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts go func(conn net.Conn) { defer ctxMonitorDone.Fire() // Signal this goroutine has exited. <-newClientCtx.Done() // Block until connectCtx expires or the defer above executes. - if connectCtx.Err() != nil { + if err := connectCtx.Err(); err != nil { // connectCtx expired before exiting the function. Hard close the connection. + if logger.V(logLevel) { + logger.Infof("Aborting due to connect deadline expiring: %v", err) + } conn.Close() } }(conn) @@ -314,6 +322,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts cancel: cancel, userAgent: opts.UserAgent, registeredCompressors: grpcutil.RegisteredCompressors(), + address: addr, conn: conn, remoteAddr: conn.RemoteAddr(), localAddr: conn.LocalAddr(), @@ -321,7 +330,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts readerDone: make(chan struct{}), writerDone: make(chan struct{}), goAway: make(chan struct{}), - framer: newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize), + framer: newFramer(conn, writeBufSize, readBufSize, opts.SharedWriteBuffer, maxHeaderListSize), fc: &trInFlow{limit: uint32(icwz)}, scheme: scheme, activeStreams: make(map[uint32]*Stream), @@ -335,11 +344,11 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), czData: new(channelzData), - onGoAway: onGoAway, keepaliveEnabled: keepaliveEnabled, bufferPool: newBufferPool(), onClose: onClose, } + t.logger = prefixLoggerForClientTransport(t) // Add peer information to the http2client context. t.ctx = peer.NewContext(t.ctx, t.getPeer()) @@ -438,17 +447,8 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts return nil, err } go func() { - t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst) - err := t.loopy.run() - if err != nil { - if logger.V(logLevel) { - logger.Errorf("transport: loopyWriter.run returning. Err: %v", err) - } - } - // Do not close the transport. Let reader goroutine handle it since - // there might be data in the buffers. - t.conn.Close() - t.controlBuf.finish() + t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) + t.loopy.run() close(t.writerDone) }() return t, nil @@ -702,6 +702,18 @@ func (e NewStreamError) Error() string { // streams. All non-nil errors returned will be *NewStreamError. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error) { ctx = peer.NewContext(ctx, t.getPeer()) + + // ServerName field of the resolver returned address takes precedence over + // Host field of CallHdr to determine the :authority header. This is because, + // the ServerName field takes precedence for server authentication during + // TLS handshake, and the :authority header should match the value used + // for server authentication. + if t.address.ServerName != "" { + newCallHdr := *callHdr + newCallHdr.Host = t.address.ServerName + callHdr = &newCallHdr + } + headerFields, err := t.createHeaderFields(ctx, callHdr) if err != nil { return nil, &NewStreamError{Err: err, AllowTransparentRetry: false} @@ -726,15 +738,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, endStream: false, initStream: func(id uint32) error { t.mu.Lock() - if state := t.state; state != reachable { + // TODO: handle transport closure in loopy instead and remove this + // initStream is never called when transport is draining. + if t.state == closing { t.mu.Unlock() - // Do a quick cleanup. - err := error(errStreamDrain) - if state == closing { - err = ErrConnClosing - } - cleanup(err) - return err + cleanup(ErrConnClosing) + return ErrConnClosing } if channelz.IsOn() { atomic.AddInt64(&t.czData.streamsStarted, 1) @@ -752,7 +761,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, } firstTry := true var ch chan struct{} - checkForStreamQuota := func(it interface{}) bool { + transportDrainRequired := false + checkForStreamQuota := func(it any) bool { if t.streamQuota <= 0 { // Can go negative if server decreases it. if firstTry { t.waitingStreams++ @@ -767,10 +777,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, h := it.(*headerFrame) h.streamID = t.nextID t.nextID += 2 + + // Drain client transport if nextID > MaxStreamID which signals gRPC that + // the connection is closed and a new one must be created for subsequent RPCs. + transportDrainRequired = t.nextID > MaxStreamID + s.id = h.streamID s.fc = &inFlow{limit: uint32(t.initialWindowSize)} t.mu.Lock() - if t.activeStreams == nil { // Can be niled from Close(). + if t.state == draining || t.activeStreams == nil { // Can be niled from Close(). t.mu.Unlock() return false // Don't create a stream if the transport is already closed. } @@ -785,7 +800,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } var hdrListSizeErr error - checkForHeaderListSize := func(it interface{}) bool { + checkForHeaderListSize := func(it any) bool { if t.maxSendHeaderListSize == nil { return true } @@ -800,7 +815,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } for { - success, err := t.controlBuf.executeAndPut(func(it interface{}) bool { + success, err := t.controlBuf.executeAndPut(func(it any) bool { return checkForHeaderListSize(it) && checkForStreamQuota(it) }, hdr) if err != nil { @@ -846,6 +861,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, sh.HandleRPC(s.ctx, outHeader) } } + if transportDrainRequired { + if t.logger.V(logLevel) { + t.logger.Infof("Draining transport: t.nextID > MaxStreamID") + } + t.GracefulClose() + } return s, nil } @@ -906,7 +927,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. rst: rst, rstCode: rstCode, } - addBackStreamQuota := func(interface{}) bool { + addBackStreamQuota := func(any) bool { t.streamQuota++ if t.streamQuota > 0 && t.waitingStreams > 0 { select { @@ -934,9 +955,14 @@ func (t *http2Client) Close(err error) { t.mu.Unlock() return } + if t.logger.V(logLevel) { + t.logger.Infof("Closing: %v", err) + } // Call t.onClose ASAP to prevent the client from attempting to create new // streams. - t.onClose() + if t.state != draining { + t.onClose(GoAwayInvalid) + } t.state = closing streams := t.activeStreams t.activeStreams = nil @@ -986,11 +1012,15 @@ func (t *http2Client) GracefulClose() { t.mu.Unlock() return } + if t.logger.V(logLevel) { + t.logger.Infof("GracefulClose called") + } + t.onClose(GoAwayInvalid) t.state = draining active := len(t.activeStreams) t.mu.Unlock() if active == 0 { - t.Close(ErrConnClosing) + t.Close(connectionErrorf(true, nil, "no active streams left to process while draining")) return } t.controlBuf.put(&incomingGoAway{}) @@ -1050,7 +1080,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { // for the transport and the stream based on the current bdp // estimation. func (t *http2Client) updateFlowControl(n uint32) { - updateIWS := func(interface{}) bool { + updateIWS := func(any) bool { t.initialWindowSize = int32(n) t.mu.Lock() for _, s := range t.activeStreams { @@ -1147,8 +1177,8 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { } statusCode, ok := http2ErrConvTab[f.ErrCode] if !ok { - if logger.V(logLevel) { - logger.Warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error %v", f.ErrCode) + if t.logger.V(logLevel) { + t.logger.Infof("Received a RST_STREAM frame with code %q, but found no mapped gRPC status", f.ErrCode) } statusCode = codes.Unknown } @@ -1203,7 +1233,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { } updateFuncs = append(updateFuncs, updateStreamQuota) } - t.controlBuf.executeAndPut(func(interface{}) bool { + t.controlBuf.executeAndPut(func(any) bool { for _, f := range updateFuncs { f() } @@ -1230,10 +1260,12 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { t.mu.Unlock() return } - if f.ErrCode == http2.ErrCodeEnhanceYourCalm { - if logger.V(logLevel) { - logger.Infof("Client received GoAway with http2.ErrCodeEnhanceYourCalm.") - } + if f.ErrCode == http2.ErrCodeEnhanceYourCalm && string(f.DebugData()) == "too_many_pings" { + // When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug + // data equal to ASCII "too_many_pings", it should log the occurrence at a log level that is + // enabled by default and double the configure KEEPALIVE_TIME used for new connections + // on that channel. + logger.Errorf("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\".") } id := f.LastStreamID if id > 0 && id%2 == 0 { @@ -1266,8 +1298,10 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { // Notify the clientconn about the GOAWAY before we set the state to // draining, to allow the client to stop attempting to create streams // before disallowing new streams on this connection. - t.onGoAway(t.goAwayReason) - t.state = draining + if t.state != draining { + t.onClose(t.goAwayReason) + t.state = draining + } } // All streams with IDs greater than the GoAwayId // and smaller than the previous GoAway ID should be killed. @@ -1303,7 +1337,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { // setGoAwayReason sets the value of t.goAwayReason based // on the GoAway frame received. -// It expects a lock on transport's mutext to be held by +// It expects a lock on transport's mutex to be held by // the caller. func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) { t.goAwayReason = GoAwayNoReason @@ -1471,14 +1505,15 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { return } - isHeader := false - - // If headerChan hasn't been closed yet - if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { - s.headerValid = true - if !endStream { - // HEADERS frame block carries a Response-Headers. - isHeader = true + // For headers, set them in s.header and close headerChan. For trailers or + // trailers-only, closeStream will set the trailers and close headerChan as + // needed. + if !endStream { + // If headerChan hasn't been closed yet (expected, given we checked it + // above, but something else could have potentially closed the whole + // stream). + if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { + s.headerValid = true // These values can be set without any synchronization because // stream goroutine will read it only after seeing a closed // headerChan which we'll close after setting this. @@ -1486,15 +1521,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if len(mdata) > 0 { s.header = mdata } - } else { - // HEADERS frame block carries a Trailers-Only. - s.noHeaders = true + close(s.headerChan) } - close(s.headerChan) } for _, sh := range t.statsHandlers { - if isHeader { + if !endStream { inHeader := &stats.InHeader{ Client: true, WireLength: int(frame.Header().Length), @@ -1520,9 +1552,10 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { statusGen = status.New(rawStatusCode, grpcMessage) } - // if client received END_STREAM from server while stream was still active, send RST_STREAM - rst := s.getState() == streamActive - t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, statusGen, mdata, true) + // If client received END_STREAM from server while stream was still active, + // send RST_STREAM. + rstStream := s.getState() == streamActive + t.closeStream(s, io.EOF, rstStream, http2.ErrCodeNo, statusGen, mdata, true) } // readServerPreface reads and handles the initial settings frame from the @@ -1756,3 +1789,9 @@ func (t *http2Client) getOutFlowWindow() int64 { return -2 } } + +func (t *http2Client) stateForTesting() transportState { + t.mu.Lock() + defer t.mu.Unlock() + return t.state +} diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 3dd15647bc8..8d3a353c1d5 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -21,6 +21,7 @@ package transport import ( "bytes" "context" + "errors" "fmt" "io" "math" @@ -34,13 +35,16 @@ import ( "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" + "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" + "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/syscall" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcrand" + "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -101,13 +105,13 @@ type http2Server struct { mu sync.Mutex // guard the following - // drainChan is initialized when Drain() is called the first time. - // After which the server writes out the first GoAway(with ID 2^31-1) frame. - // Then an independent goroutine will be launched to later send the second GoAway. - // During this time we don't want to write another first GoAway(with ID 2^31 -1) frame. - // Thus call to Drain() will be a no-op if drainChan is already initialized since draining is - // already underway. - drainChan chan struct{} + // drainEvent is initialized when Drain() is called the first time. After + // which the server writes out the first GoAway(with ID 2^31-1) frame. Then + // an independent goroutine will be launched to later send the second + // GoAway. During this time we don't want to write another first GoAway(with + // ID 2^31 -1) frame. Thus call to Drain() will be a no-op if drainEvent is + // already initialized since draining is already underway. + drainEvent *grpcsync.Event state transportState activeStreams map[uint32]*Stream // idle is the time instant when the connection went idle. @@ -127,6 +131,8 @@ type http2Server struct { // This lock may not be taken if mu is already held. maxStreamMu sync.Mutex maxStreamID uint32 // max stream ID ever seen + + logger *grpclog.PrefixLogger } // NewServerTransport creates a http2 transport with conn and configuration @@ -159,7 +165,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, if config.MaxHeaderListSize != nil { maxHeaderListSize = *config.MaxHeaderListSize } - framer := newFramer(conn, writeBufSize, readBufSize, maxHeaderListSize) + framer := newFramer(conn, writeBufSize, readBufSize, config.SharedWriteBuffer, maxHeaderListSize) // Send initial settings as connection preface to client. isettings := []http2.Setting{{ ID: http2.SettingMaxFrameSize, @@ -232,7 +238,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, kp.Timeout = defaultServerKeepaliveTimeout } if kp.Time != infinity { - if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil { + if err = syscall.SetTCPUserTimeout(rawConn, kp.Timeout); err != nil { return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err) } } @@ -265,6 +271,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, czData: new(channelzData), bufferPool: newBufferPool(), } + t.logger = prefixLoggerForServerTransport(t) // Add peer information to the http2server context. t.ctx = peer.NewContext(t.ctx, t.getPeer()) @@ -293,7 +300,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, defer func() { if err != nil { - t.Close() + t.Close(err) } }() @@ -329,23 +336,18 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, t.handleSettings(sf) go func() { - t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst) + t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler - if err := t.loopy.run(); err != nil { - if logger.V(logLevel) { - logger.Errorf("transport: loopyWriter.run returning. Err: %v", err) - } - } - t.conn.Close() - t.controlBuf.finish() + t.loopy.run() close(t.writerDone) }() go t.keepalive() return t, nil } -// operateHeader takes action on the decoded headers. -func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { +// operateHeaders takes action on the decoded headers. Returns an error if fatal +// error encountered and transport needs to close, otherwise returns nil. +func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) error { // Acquire max stream ID lock for entire duration t.maxStreamMu.Lock() defer t.maxStreamMu.Unlock() @@ -361,15 +363,12 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rstCode: http2.ErrCodeFrameSize, onWrite: func() {}, }) - return false + return nil } if streamID%2 != 1 || streamID <= t.maxStreamID { // illegal gRPC stream id. - if logger.V(logLevel) { - logger.Errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", streamID) - } - return true + return fmt.Errorf("received an illegal stream id: %v. headers frame: %+v", streamID, frame) } t.maxStreamID = streamID @@ -381,13 +380,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( fc: &inFlow{limit: uint32(t.initialWindowSize)}, } var ( - // If a gRPC Response-Headers has already been received, then it means - // that the peer is speaking gRPC and we are in gRPC mode. - isGRPC = false - mdata = make(map[string][]string) - httpMethod string - // headerError is set if an error is encountered while parsing the headers - headerError bool + // if false, content-type was missing or invalid + isGRPC = false + contentType = "" + mdata = make(metadata.MD, len(frame.Fields)) + httpMethod string + // these are set if an error is encountered while parsing the headers + protocolError bool + headerError *status.Status timeoutSet bool timeout time.Duration @@ -398,11 +398,23 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( case "content-type": contentSubtype, validContentType := grpcutil.ContentSubtype(hf.Value) if !validContentType { + contentType = hf.Value break } mdata[hf.Name] = append(mdata[hf.Name], hf.Value) s.contentSubtype = contentSubtype isGRPC = true + + case "grpc-accept-encoding": + mdata[hf.Name] = append(mdata[hf.Name], hf.Value) + if hf.Value == "" { + continue + } + compressors := hf.Value + if s.clientAdvertisedCompressors != "" { + compressors = s.clientAdvertisedCompressors + "," + compressors + } + s.clientAdvertisedCompressors = compressors case "grpc-encoding": s.recvCompress = hf.Value case ":method": @@ -413,23 +425,23 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( timeoutSet = true var err error if timeout, err = decodeTimeout(hf.Value); err != nil { - headerError = true + headerError = status.Newf(codes.Internal, "malformed grpc-timeout: %v", err) } // "Transports must consider requests containing the Connection header // as malformed." - A41 case "connection": - if logger.V(logLevel) { - logger.Errorf("transport: http2Server.operateHeaders parsed a :connection header which makes a request malformed as per the HTTP/2 spec") + if t.logger.V(logLevel) { + t.logger.Infof("Received a HEADERS frame with a :connection header which makes the request malformed, as per the HTTP/2 spec") } - headerError = true + protocolError = true default: if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) { break } v, err := decodeMetadataHeader(hf.Name, hf.Value) if err != nil { - headerError = true - logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err) + headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err) + t.logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err) break } mdata[hf.Name] = append(mdata[hf.Name], v) @@ -443,27 +455,47 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( // error, this takes precedence over a client not speaking gRPC. if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 { errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"])) - if logger.V(logLevel) { - logger.Errorf("transport: %v", errMsg) + if t.logger.V(logLevel) { + t.logger.Infof("Aborting the stream early: %v", errMsg) } t.controlBuf.put(&earlyAbortStream{ - httpStatus: 400, + httpStatus: http.StatusBadRequest, streamID: streamID, contentSubtype: s.contentSubtype, status: status.New(codes.Internal, errMsg), rst: !frame.StreamEnded(), }) - return false + return nil } - if !isGRPC || headerError { + if protocolError { t.controlBuf.put(&cleanupStream{ streamID: streamID, rst: true, rstCode: http2.ErrCodeProtocol, onWrite: func() {}, }) - return false + return nil + } + if !isGRPC { + t.controlBuf.put(&earlyAbortStream{ + httpStatus: http.StatusUnsupportedMediaType, + streamID: streamID, + contentSubtype: s.contentSubtype, + status: status.Newf(codes.InvalidArgument, "invalid gRPC request content-type %q", contentType), + rst: !frame.StreamEnded(), + }) + return nil + } + if headerError != nil { + t.controlBuf.put(&earlyAbortStream{ + httpStatus: http.StatusBadRequest, + streamID: streamID, + contentSubtype: s.contentSubtype, + status: headerError, + rst: !frame.StreamEnded(), + }) + return nil } // "If :authority is missing, Host must be renamed to :authority." - A41 @@ -503,7 +535,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( if t.state != reachable { t.mu.Unlock() s.cancel() - return false + return nil } if uint32(len(t.activeStreams)) >= t.maxStreams { t.mu.Unlock() @@ -514,13 +546,13 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( onWrite: func() {}, }) s.cancel() - return false + return nil } if httpMethod != http.MethodPost { t.mu.Unlock() - errMsg := fmt.Sprintf("http2Server.operateHeaders parsed a :method field: %v which should be POST", httpMethod) - if logger.V(logLevel) { - logger.Infof("transport: %v", errMsg) + errMsg := fmt.Sprintf("Received a HEADERS frame with :method %q which should be POST", httpMethod) + if t.logger.V(logLevel) { + t.logger.Infof("Aborting the stream early: %v", errMsg) } t.controlBuf.put(&earlyAbortStream{ httpStatus: 405, @@ -530,14 +562,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( rst: !frame.StreamEnded(), }) s.cancel() - return false + return nil } if t.inTapHandle != nil { var err error if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil { t.mu.Unlock() - if logger.V(logLevel) { - logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err) + if t.logger.V(logLevel) { + t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err) } stat, ok := status.FromError(err) if !ok { @@ -550,7 +582,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( status: stat, rst: !frame.StreamEnded(), }) - return false + return nil } } t.activeStreams[streamID] = s @@ -574,7 +606,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( LocalAddr: t.localAddr, Compression: s.recvCompress, WireLength: int(frame.Header().Length), - Header: metadata.MD(mdata).Copy(), + Header: mdata.Copy(), } sh.HandleRPC(s.ctx, inHeader) } @@ -597,7 +629,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( wq: s.wq, }) handle(s) - return false + return nil } // HandleStreams receives incoming streams using the given handler. This is @@ -611,8 +643,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. atomic.StoreInt64(&t.lastRead, time.Now().UnixNano()) if err != nil { if se, ok := err.(http2.StreamError); ok { - if logger.V(logLevel) { - logger.Warningf("transport: http2Server.HandleStreams encountered http2.StreamError: %v", se) + if t.logger.V(logLevel) { + t.logger.Warningf("Encountered http2.StreamError: %v", se) } t.mu.Lock() s := t.activeStreams[se.StreamID] @@ -630,19 +662,16 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. continue } if err == io.EOF || err == io.ErrUnexpectedEOF { - t.Close() + t.Close(err) return } - if logger.V(logLevel) { - logger.Warningf("transport: http2Server.HandleStreams failed to read frame: %v", err) - } - t.Close() + t.Close(err) return } switch frame := frame.(type) { case *http2.MetaHeadersFrame: - if t.operateHeaders(frame, handle, traceCtx) { - t.Close() + if err := t.operateHeaders(frame, handle, traceCtx); err != nil { + t.Close(err) break } case *http2.DataFrame: @@ -658,8 +687,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. case *http2.GoAwayFrame: // TODO: Handle GoAway from the client appropriately. default: - if logger.V(logLevel) { - logger.Errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame) + if t.logger.V(logLevel) { + t.logger.Infof("Received unsupported frame type %T", frame) } } } @@ -826,7 +855,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } return nil }) - t.controlBuf.executeAndPut(func(interface{}) bool { + t.controlBuf.executeAndPut(func(any) bool { for _, f := range updateFuncs { f() } @@ -843,8 +872,8 @@ const ( func (t *http2Server) handlePing(f *http2.PingFrame) { if f.IsAck() { - if f.Data == goAwayPing.data && t.drainChan != nil { - close(t.drainChan) + if f.Data == goAwayPing.data && t.drainEvent != nil { + t.drainEvent.Fire() return } // Maybe it's a BDP ping. @@ -886,10 +915,7 @@ func (t *http2Server) handlePing(f *http2.PingFrame) { if t.pingStrikes > maxPingStrikes { // Send goaway and close the connection. - if logger.V(logLevel) { - logger.Errorf("transport: Got too many pings from the client, closing the connection.") - } - t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings"), closeConn: true}) + t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings"), closeConn: errors.New("got too many pings from the client")}) } } @@ -913,7 +939,7 @@ func appendHeaderFieldsFromMD(headerFields []hpack.HeaderField, md metadata.MD) return headerFields } -func (t *http2Server) checkForHeaderListSize(it interface{}) bool { +func (t *http2Server) checkForHeaderListSize(it any) bool { if t.maxSendHeaderListSize == nil { return true } @@ -921,8 +947,8 @@ func (t *http2Server) checkForHeaderListSize(it interface{}) bool { var sz int64 for _, f := range hdrFrame.hf { if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) { - if logger.V(logLevel) { - logger.Errorf("header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize) + if t.logger.V(logLevel) { + t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize) } return false } @@ -1035,7 +1061,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { stBytes, err := proto.Marshal(p) if err != nil { // TODO: return error instead, when callers are able to handle it. - logger.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err) + t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err) } else { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)}) } @@ -1140,20 +1166,20 @@ func (t *http2Server) keepalive() { if val <= 0 { // The connection has been idle for a duration of keepalive.MaxConnectionIdle or more. // Gracefully close the connection. - t.Drain() + t.Drain("max_idle") return } idleTimer.Reset(val) case <-ageTimer.C: - t.Drain() + t.Drain("max_age") ageTimer.Reset(t.kp.MaxConnectionAgeGrace) select { case <-ageTimer.C: // Close the connection after grace period. - if logger.V(logLevel) { - logger.Infof("transport: closing server transport due to maximum connection age.") + if t.logger.V(logLevel) { + t.logger.Infof("Closing server transport due to maximum connection age") } - t.Close() + t.controlBuf.put(closeConnection{}) case <-t.done: } return @@ -1169,10 +1195,7 @@ func (t *http2Server) keepalive() { continue } if outstandingPing && kpTimeoutLeft <= 0 { - if logger.V(logLevel) { - logger.Infof("transport: closing server transport due to idleness.") - } - t.Close() + t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Time)) return } if !outstandingPing { @@ -1199,20 +1222,23 @@ func (t *http2Server) keepalive() { // Close starts shutting down the http2Server transport. // TODO(zhaoq): Now the destruction is not blocked on any pending streams. This // could cause some resource issue. Revisit this later. -func (t *http2Server) Close() { +func (t *http2Server) Close(err error) { t.mu.Lock() if t.state == closing { t.mu.Unlock() return } + if t.logger.V(logLevel) { + t.logger.Infof("Closing: %v", err) + } t.state = closing streams := t.activeStreams t.activeStreams = nil t.mu.Unlock() t.controlBuf.finish() close(t.done) - if err := t.conn.Close(); err != nil && logger.V(logLevel) { - logger.Infof("transport: error closing conn during Close: %v", err) + if err := t.conn.Close(); err != nil && t.logger.V(logLevel) { + t.logger.Infof("Error closing underlying net.Conn during Close: %v", err) } channelz.RemoveEntry(t.channelzID) // Cancel all active streams. @@ -1292,14 +1318,14 @@ func (t *http2Server) RemoteAddr() net.Addr { return t.remoteAddr } -func (t *http2Server) Drain() { +func (t *http2Server) Drain(debugData string) { t.mu.Lock() defer t.mu.Unlock() - if t.drainChan != nil { + if t.drainEvent != nil { return } - t.drainChan = make(chan struct{}) - t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte{}, headsUp: true}) + t.drainEvent = grpcsync.NewEvent() + t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte(debugData), headsUp: true}) } var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}} @@ -1319,19 +1345,17 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { // Stop accepting more streams now. t.state = draining sid := t.maxStreamID + retErr := g.closeConn if len(t.activeStreams) == 0 { - g.closeConn = true + retErr = errors.New("second GOAWAY written and no active streams left to process") } t.mu.Unlock() t.maxStreamMu.Unlock() if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil { return false, err } - if g.closeConn { - // Abruptly close the connection following the GoAway (via - // loopywriter). But flush out what's inside the buffer first. - t.framer.writer.Flush() - return false, fmt.Errorf("transport: Connection closing") + if retErr != nil { + return false, retErr } return true, nil } @@ -1343,7 +1367,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { // originated before the GoAway reaches the client. // After getting the ack or timer expiration send out another GoAway this // time with an ID of the max stream server intends to process. - if err := t.framer.fr.WriteGoAway(math.MaxUint32, http2.ErrCodeNo, []byte{}); err != nil { + if err := t.framer.fr.WriteGoAway(math.MaxUint32, http2.ErrCodeNo, g.debugData); err != nil { return false, err } if err := t.framer.fr.WritePing(false, goAwayPing.data); err != nil { @@ -1353,7 +1377,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { timer := time.NewTimer(time.Minute) defer timer.Stop() select { - case <-t.drainChan: + case <-t.drainEvent.Done(): case <-timer.C: case <-t.done: return diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index 2c601a864d9..1958140082b 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -21,6 +21,7 @@ package transport import ( "bufio" "encoding/base64" + "errors" "fmt" "io" "math" @@ -29,6 +30,7 @@ import ( "net/url" "strconv" "strings" + "sync" "time" "unicode/utf8" @@ -37,7 +39,6 @@ import ( "golang.org/x/net/http2/hpack" spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" "google.golang.org/grpc/status" ) @@ -85,7 +86,6 @@ var ( // 504 Gateway timeout - UNAVAILABLE. http.StatusGatewayTimeout: codes.Unavailable, } - logger = grpclog.Component("transport") ) // isReservedHeader checks whether hdr belongs to HTTP2 headers @@ -310,6 +310,7 @@ func decodeGrpcMessageUnchecked(msg string) string { } type bufWriter struct { + pool *sync.Pool buf []byte offset int batchSize int @@ -317,12 +318,17 @@ type bufWriter struct { err error } -func newBufWriter(conn net.Conn, batchSize int) *bufWriter { - return &bufWriter{ - buf: make([]byte, batchSize*2), +func newBufWriter(conn net.Conn, batchSize int, pool *sync.Pool) *bufWriter { + w := &bufWriter{ batchSize: batchSize, conn: conn, + pool: pool, } + // this indicates that we should use non shared buf + if pool == nil { + w.buf = make([]byte, batchSize) + } + return w } func (w *bufWriter) Write(b []byte) (n int, err error) { @@ -330,7 +336,12 @@ func (w *bufWriter) Write(b []byte) (n int, err error) { return 0, w.err } if w.batchSize == 0 { // Buffer has been disabled. - return w.conn.Write(b) + n, err = w.conn.Write(b) + return n, toIOError(err) + } + if w.buf == nil { + b := w.pool.Get().(*[]byte) + w.buf = *b } for len(b) > 0 { nn := copy(w.buf[w.offset:], b) @@ -338,13 +349,24 @@ func (w *bufWriter) Write(b []byte) (n int, err error) { w.offset += nn n += nn if w.offset >= w.batchSize { - err = w.Flush() + err = w.flushKeepBuffer() } } return n, err } func (w *bufWriter) Flush() error { + err := w.flushKeepBuffer() + // Only release the buffer if we are in a "shared" mode + if w.buf != nil && w.pool != nil { + b := w.buf + w.pool.Put(&b) + w.buf = nil + } + return err +} + +func (w *bufWriter) flushKeepBuffer() error { if w.err != nil { return w.err } @@ -352,16 +374,39 @@ func (w *bufWriter) Flush() error { return nil } _, w.err = w.conn.Write(w.buf[:w.offset]) + w.err = toIOError(w.err) w.offset = 0 return w.err } +type ioError struct { + error +} + +func (i ioError) Unwrap() error { + return i.error +} + +func isIOError(err error) bool { + return errors.As(err, &ioError{}) +} + +func toIOError(err error) error { + if err == nil { + return nil + } + return ioError{error: err} +} + type framer struct { writer *bufWriter fr *http2.Framer } -func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderListSize uint32) *framer { +var writeBufferPoolMap map[int]*sync.Pool = make(map[int]*sync.Pool) +var writeBufferMutex sync.Mutex + +func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32) *framer { if writeBufferSize < 0 { writeBufferSize = 0 } @@ -369,7 +414,11 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList if readBufferSize > 0 { r = bufio.NewReaderSize(r, readBufferSize) } - w := newBufWriter(conn, writeBufferSize) + var pool *sync.Pool + if sharedWriteBuffer { + pool = getWriteBufferPool(writeBufferSize) + } + w := newBufWriter(conn, writeBufferSize, pool) f := &framer{ writer: w, fr: http2.NewFramer(w, r), @@ -383,6 +432,24 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, maxHeaderList return f } +func getWriteBufferPool(writeBufferSize int) *sync.Pool { + writeBufferMutex.Lock() + defer writeBufferMutex.Unlock() + size := writeBufferSize * 2 + pool, ok := writeBufferPoolMap[size] + if ok { + return pool + } + pool = &sync.Pool{ + New: func() any { + b := make([]byte, size) + return &b + }, + } + writeBufferPoolMap[size] = pool + return pool +} + // parseDialTarget returns the network and address to pass to dialer. func parseDialTarget(target string) (string, string) { net := "tcp" diff --git a/vendor/google.golang.org/grpc/internal/transport/logging.go b/vendor/google.golang.org/grpc/internal/transport/logging.go new file mode 100644 index 00000000000..42ed2b07af6 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/transport/logging.go @@ -0,0 +1,40 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package transport + +import ( + "fmt" + + "google.golang.org/grpc/grpclog" + internalgrpclog "google.golang.org/grpc/internal/grpclog" +) + +var logger = grpclog.Component("transport") + +func prefixLoggerForServerTransport(p *http2Server) *internalgrpclog.PrefixLogger { + return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-transport %p] ", p)) +} + +func prefixLoggerForServerHandlerTransport(p *serverHandlerTransport) *internalgrpclog.PrefixLogger { + return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-handler-transport %p] ", p)) +} + +func prefixLoggerForClientTransport(p *http2Client) *internalgrpclog.PrefixLogger { + return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[client-transport %p] ", p)) +} diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 2e615ee20cc..74a811fc059 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -43,10 +43,6 @@ import ( "google.golang.org/grpc/tap" ) -// ErrNoHeaders is used as a signal that a trailers only response was received, -// and is not a real error. -var ErrNoHeaders = errors.New("stream has no headers") - const logLevel = 2 type bufferPool struct { @@ -56,7 +52,7 @@ type bufferPool struct { func newBufferPool() *bufferPool { return &bufferPool{ pool: sync.Pool{ - New: func() interface{} { + New: func() any { return new(bytes.Buffer) }, }, @@ -257,6 +253,9 @@ type Stream struct { fc *inFlow wq *writeQuota + // Holds compressor names passed in grpc-accept-encoding metadata from the + // client. This is empty for the client side stream. + clientAdvertisedCompressors string // Callback to state application's intentions to read data. This // is used to adjust flow control, if needed. requestRead func(int) @@ -345,8 +344,24 @@ func (s *Stream) RecvCompress() string { } // SetSendCompress sets the compression algorithm to the stream. -func (s *Stream) SetSendCompress(str string) { - s.sendCompress = str +func (s *Stream) SetSendCompress(name string) error { + if s.isHeaderSent() || s.getState() == streamDone { + return errors.New("transport: set send compressor called after headers sent or stream done") + } + + s.sendCompress = name + return nil +} + +// SendCompress returns the send compressor name. +func (s *Stream) SendCompress() string { + return s.sendCompress +} + +// ClientAdvertisedCompressors returns the compressor names advertised by the +// client via grpc-accept-encoding header. +func (s *Stream) ClientAdvertisedCompressors() string { + return s.clientAdvertisedCompressors } // Done returns a channel which is closed when it receives the final status @@ -371,14 +386,10 @@ func (s *Stream) Header() (metadata.MD, error) { } s.waitOnHeader() - if !s.headerValid { + if !s.headerValid || s.noHeaders { return nil, s.status.Err() } - if s.noHeaders { - return nil, ErrNoHeaders - } - return s.header.Copy(), nil } @@ -540,6 +551,7 @@ type ServerConfig struct { InitialConnWindowSize int32 WriteBufferSize int ReadBufferSize int + SharedWriteBuffer bool ChannelzParentID *channelz.Identifier MaxHeaderListSize *uint32 HeaderTableSize *uint32 @@ -573,6 +585,8 @@ type ConnectOptions struct { WriteBufferSize int // ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall. ReadBufferSize int + // SharedWriteBuffer indicates whether connections should reuse write buffer + SharedWriteBuffer bool // ChannelzParentID sets the addrConn id which initiate the creation of this client transport. ChannelzParentID *channelz.Identifier // MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received. @@ -583,8 +597,8 @@ type ConnectOptions struct { // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { - return newHTTP2Client(connectCtx, ctx, addr, opts, onGoAway, onClose) +func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (ClientTransport, error) { + return newHTTP2Client(connectCtx, ctx, addr, opts, onClose) } // Options provides additional hints and information for message @@ -701,13 +715,13 @@ type ServerTransport interface { // Close tears down the transport. Once it is called, the transport // should not be accessed any more. All the pending streams and their // handlers will be terminated asynchronously. - Close() + Close(err error) // RemoteAddr returns the remote network address. RemoteAddr() net.Addr // Drain notifies the client this ServerTransport stops accepting new RPCs. - Drain() + Drain(debugData string) // IncrMsgSent increments the number of message sent through this transport. IncrMsgSent() @@ -717,7 +731,7 @@ type ServerTransport interface { } // connectionErrorf creates an ConnectionError with the specified error description. -func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { +func connectionErrorf(temp bool, e error, format string, a ...any) ConnectionError { return ConnectionError{ Desc: fmt.Sprintf(format, a...), temp: temp, diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index fb4a88f59bd..a2cdcaf12a8 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -91,7 +91,11 @@ func (md MD) Len() int { // Copy returns a copy of md. func (md MD) Copy() MD { - return Join(md) + out := make(MD, len(md)) + for k, v := range md { + out[k] = copyOf(v) + } + return out } // Get obtains the values for a given key. @@ -171,8 +175,11 @@ func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context md, _ := ctx.Value(mdOutgoingKey{}).(rawMD) added := make([][]string, len(md.added)+1) copy(added, md.added) - added[len(added)-1] = make([]string, len(kv)) - copy(added[len(added)-1], kv) + kvCopy := make([]string, 0, len(kv)) + for i := 0; i < len(kv); i += 2 { + kvCopy = append(kvCopy, strings.ToLower(kv[i]), kv[i+1]) + } + added[len(added)-1] = kvCopy return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added}) } diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index a5d5516ee06..236837f4157 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -28,26 +28,36 @@ import ( "google.golang.org/grpc/internal/channelz" istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/transport" + "google.golang.org/grpc/stats" "google.golang.org/grpc/status" ) // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick // actions and unblock when there's a picker update. type pickerWrapper struct { - mu sync.Mutex - done bool - blockingCh chan struct{} - picker balancer.Picker + mu sync.Mutex + done bool + idle bool + blockingCh chan struct{} + picker balancer.Picker + statsHandlers []stats.Handler // to record blocking picker calls } -func newPickerWrapper() *pickerWrapper { - return &pickerWrapper{blockingCh: make(chan struct{})} +func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper { + return &pickerWrapper{ + blockingCh: make(chan struct{}), + statsHandlers: statsHandlers, + } } // updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. func (pw *pickerWrapper) updatePicker(p balancer.Picker) { pw.mu.Lock() - if pw.done { + if pw.done || pw.idle { + // There is a small window where a picker update from the LB policy can + // race with the channel going to idle mode. If the picker is idle here, + // it is because the channel asked it to do so, and therefore it is sage + // to ignore the update from the LB policy. pw.mu.Unlock() return } @@ -58,12 +68,16 @@ func (pw *pickerWrapper) updatePicker(p balancer.Picker) { pw.mu.Unlock() } -func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) func(balancer.DoneInfo) { - acw.mu.Lock() - ac := acw.ac - acw.mu.Unlock() +// doneChannelzWrapper performs the following: +// - increments the calls started channelz counter +// - wraps the done function in the passed in result to increment the calls +// failed or calls succeeded channelz counter before invoking the actual +// done function. +func doneChannelzWrapper(acbw *acBalancerWrapper, result *balancer.PickResult) { + ac := acbw.ac ac.incrCallsStarted() - return func(b balancer.DoneInfo) { + done := result.Done + result.Done = func(b balancer.DoneInfo) { if b.Err != nil && b.Err != io.EOF { ac.incrCallsFailed() } else { @@ -82,15 +96,16 @@ func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) f // - the current picker returns other errors and failfast is false. // - the subConn returned by the current picker is not READY // When one of these situations happens, pick blocks until the picker gets updated. -func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.PickInfo) (transport.ClientTransport, func(balancer.DoneInfo), error) { +func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.PickInfo) (transport.ClientTransport, balancer.PickResult, error) { var ch chan struct{} var lastPickErr error + for { pw.mu.Lock() if pw.done { pw.mu.Unlock() - return nil, nil, ErrClientConnClosing + return nil, balancer.PickResult{}, ErrClientConnClosing } if pw.picker == nil { @@ -111,21 +126,34 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. } switch ctx.Err() { case context.DeadlineExceeded: - return nil, nil, status.Error(codes.DeadlineExceeded, errStr) + return nil, balancer.PickResult{}, status.Error(codes.DeadlineExceeded, errStr) case context.Canceled: - return nil, nil, status.Error(codes.Canceled, errStr) + return nil, balancer.PickResult{}, status.Error(codes.Canceled, errStr) } case <-ch: } continue } + // If the channel is set, it means that the pick call had to wait for a + // new picker at some point. Either it's the first iteration and this + // function received the first picker, or a picker errored with + // ErrNoSubConnAvailable or errored with failfast set to false, which + // will trigger a continue to the next iteration. In the first case this + // conditional will hit if this call had to block (the channel is set). + // In the second case, the only way it will get to this conditional is + // if there is a new picker. + if ch != nil { + for _, sh := range pw.statsHandlers { + sh.HandleRPC(ctx, &stats.PickerUpdated{}) + } + } + ch = pw.blockingCh p := pw.picker pw.mu.Unlock() pickResult, err := p.Pick(info) - if err != nil { if err == balancer.ErrNoSubConnAvailable { continue @@ -136,7 +164,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. if istatus.IsRestrictedControlPlaneCode(st) { err = status.Errorf(codes.Internal, "received picker error with illegal status: %v", err) } - return nil, nil, dropError{error: err} + return nil, balancer.PickResult{}, dropError{error: err} } // For all other errors, wait for ready RPCs should block and other // RPCs should fail with unavailable. @@ -144,19 +172,20 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. lastPickErr = err continue } - return nil, nil, status.Error(codes.Unavailable, err.Error()) + return nil, balancer.PickResult{}, status.Error(codes.Unavailable, err.Error()) } - acw, ok := pickResult.SubConn.(*acBalancerWrapper) + acbw, ok := pickResult.SubConn.(*acBalancerWrapper) if !ok { logger.Errorf("subconn returned from pick is type %T, not *acBalancerWrapper", pickResult.SubConn) continue } - if t := acw.getAddrConn().getReadyTransport(); t != nil { + if t := acbw.ac.getReadyTransport(); t != nil { if channelz.IsOn() { - return t, doneChannelzWrapper(acw, pickResult.Done), nil + doneChannelzWrapper(acbw, &pickResult) + return t, pickResult, nil } - return t, pickResult.Done, nil + return t, pickResult, nil } if pickResult.Done != nil { // Calling done with nil error, no bytes sent and no bytes received. @@ -181,6 +210,25 @@ func (pw *pickerWrapper) close() { close(pw.blockingCh) } +func (pw *pickerWrapper) enterIdleMode() { + pw.mu.Lock() + defer pw.mu.Unlock() + if pw.done { + return + } + pw.idle = true +} + +func (pw *pickerWrapper) exitIdleMode() { + pw.mu.Lock() + defer pw.mu.Unlock() + if pw.done { + return + } + pw.blockingCh = make(chan struct{}) + pw.idle = false +} + // dropError is a wrapper error that indicates the LB policy wishes to drop the // RPC and not retry it. type dropError struct { diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index fb7a99e0a27..2e9cf66b4af 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -19,15 +19,25 @@ package grpc import ( + "encoding/json" "errors" "fmt" "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/internal/envconfig" + internalgrpclog "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/internal/grpcrand" + "google.golang.org/grpc/internal/pretty" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/serviceconfig" ) -// PickFirstBalancerName is the name of the pick_first balancer. -const PickFirstBalancerName = "pick_first" +const ( + // PickFirstBalancerName is the name of the pick_first balancer. + PickFirstBalancerName = "pick_first" + logPrefix = "[pick-first-lb %p] " +) func newPickfirstBuilder() balancer.Builder { return &pickfirstBuilder{} @@ -36,22 +46,55 @@ func newPickfirstBuilder() balancer.Builder { type pickfirstBuilder struct{} func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { - return &pickfirstBalancer{cc: cc} + b := &pickfirstBalancer{cc: cc} + b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b)) + return b } func (*pickfirstBuilder) Name() string { return PickFirstBalancerName } +type pfConfig struct { + serviceconfig.LoadBalancingConfig `json:"-"` + + // If set to true, instructs the LB policy to shuffle the order of the list + // of addresses received from the name resolver before attempting to + // connect to them. + ShuffleAddressList bool `json:"shuffleAddressList"` +} + +func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { + if !envconfig.PickFirstLBConfig { + // Prior to supporting loadbalancing configuration, the pick_first LB + // policy did not implement the balancer.ConfigParser interface. This + // meant that if a non-empty configuration was passed to it, the service + // config unmarshaling code would throw a warning log, but would + // continue using the pick_first LB policy. The code below ensures the + // same behavior is retained if the env var is not set. + if string(js) != "{}" { + logger.Warningf("Ignoring non-empty balancer configuration %q for the pick_first LB policy", string(js)) + } + return nil, nil + } + + var cfg pfConfig + if err := json.Unmarshal(js, &cfg); err != nil { + return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err) + } + return cfg, nil +} + type pickfirstBalancer struct { + logger *internalgrpclog.PrefixLogger state connectivity.State cc balancer.ClientConn subConn balancer.SubConn } func (b *pickfirstBalancer) ResolverError(err error) { - if logger.V(2) { - logger.Infof("pickfirstBalancer: ResolverError called with error %v", err) + if b.logger.V(2) { + b.logger.Infof("Received error from the name resolver: %v", err) } if b.subConn == nil { b.state = connectivity.TransientFailure @@ -69,28 +112,49 @@ func (b *pickfirstBalancer) ResolverError(err error) { } func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { - if len(state.ResolverState.Addresses) == 0 { + addrs := state.ResolverState.Addresses + if len(addrs) == 0 { // The resolver reported an empty address list. Treat it like an error by // calling b.ResolverError. if b.subConn != nil { - // Remove the old subConn. All addresses were removed, so it is no longer - // valid. - b.cc.RemoveSubConn(b.subConn) + // Shut down the old subConn. All addresses were removed, so it is + // no longer valid. + b.subConn.Shutdown() b.subConn = nil } b.ResolverError(errors.New("produced zero addresses")) return balancer.ErrBadResolverState } + // We don't have to guard this block with the env var because ParseConfig + // already does so. + cfg, ok := state.BalancerConfig.(pfConfig) + if state.BalancerConfig != nil && !ok { + return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig) + } + if cfg.ShuffleAddressList { + addrs = append([]resolver.Address{}, addrs...) + grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) + } + + if b.logger.V(2) { + b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState)) + } + if b.subConn != nil { - b.cc.UpdateAddresses(b.subConn, state.ResolverState.Addresses) + b.cc.UpdateAddresses(b.subConn, addrs) return nil } - subConn, err := b.cc.NewSubConn(state.ResolverState.Addresses, balancer.NewSubConnOptions{}) + var subConn balancer.SubConn + subConn, err := b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{ + StateListener: func(state balancer.SubConnState) { + b.updateSubConnState(subConn, state) + }, + }) if err != nil { - if logger.V(2) { - logger.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err) + if b.logger.V(2) { + b.logger.Infof("Failed to create new SubConn: %v", err) } b.state = connectivity.TransientFailure b.cc.UpdateState(balancer.State{ @@ -102,24 +166,29 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState b.subConn = subConn b.state = connectivity.Idle b.cc.UpdateState(balancer.State{ - ConnectivityState: connectivity.Idle, - Picker: &picker{result: balancer.PickResult{SubConn: b.subConn}}, + ConnectivityState: connectivity.Connecting, + Picker: &picker{err: balancer.ErrNoSubConnAvailable}, }) b.subConn.Connect() return nil } +// UpdateSubConnState is unused as a StateListener is always registered when +// creating SubConns. func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) { - if logger.V(2) { - logger.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", subConn, state) + b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", subConn, state) +} + +func (b *pickfirstBalancer) updateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) { + if b.logger.V(2) { + b.logger.Infof("Received SubConn state update: %p, %+v", subConn, state) } if b.subConn != subConn { - if logger.V(2) { - logger.Infof("pickfirstBalancer: ignored state change because subConn is not recognized") + if b.logger.V(2) { + b.logger.Infof("Ignored state change because subConn is not recognized") } return } - b.state = state.ConnectivityState if state.ConnectivityState == connectivity.Shutdown { b.subConn = nil return @@ -132,11 +201,21 @@ func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state b Picker: &picker{result: balancer.PickResult{SubConn: subConn}}, }) case connectivity.Connecting: + if b.state == connectivity.TransientFailure { + // We stay in TransientFailure until we are Ready. See A62. + return + } b.cc.UpdateState(balancer.State{ ConnectivityState: state.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable}, }) case connectivity.Idle: + if b.state == connectivity.TransientFailure { + // We stay in TransientFailure until we are Ready. Also kick the + // subConn out of Idle into Connecting. See A62. + b.subConn.Connect() + return + } b.cc.UpdateState(balancer.State{ ConnectivityState: state.ConnectivityState, Picker: &idlePicker{subConn: subConn}, @@ -147,6 +226,7 @@ func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state b Picker: &picker{err: state.ConnectionError}, }) } + b.state = state.ConnectivityState } func (b *pickfirstBalancer) Close() { diff --git a/vendor/google.golang.org/grpc/preloader.go b/vendor/google.golang.org/grpc/preloader.go index cd45547854f..73bd6336433 100644 --- a/vendor/google.golang.org/grpc/preloader.go +++ b/vendor/google.golang.org/grpc/preloader.go @@ -37,7 +37,7 @@ type PreparedMsg struct { } // Encode marshalls and compresses the message using the codec and compressor for the stream. -func (p *PreparedMsg) Encode(s Stream, msg interface{}) error { +func (p *PreparedMsg) Encode(s Stream, msg any) error { ctx := s.Context() rpcInfo, ok := rpcInfoFromContext(ctx) if !ok { diff --git a/vendor/google.golang.org/grpc/regenerate.sh b/vendor/google.golang.org/grpc/regenerate.sh index 99db79fafcf..a6f26c8ab0f 100644 --- a/vendor/google.golang.org/grpc/regenerate.sh +++ b/vendor/google.golang.org/grpc/regenerate.sh @@ -57,7 +57,8 @@ LEGACY_SOURCES=( ${WORKDIR}/grpc-proto/grpc/health/v1/health.proto ${WORKDIR}/grpc-proto/grpc/lb/v1/load_balancer.proto profiling/proto/service.proto - reflection/grpc_reflection_v1alpha/reflection.proto + ${WORKDIR}/grpc-proto/grpc/reflection/v1alpha/reflection.proto + ${WORKDIR}/grpc-proto/grpc/reflection/v1/reflection.proto ) # Generates only the new gRPC Service symbols @@ -119,8 +120,4 @@ mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/ # see grpc_testing_not_regenerate/README.md for details. rm ${WORKDIR}/out/google.golang.org/grpc/reflection/grpc_testing_not_regenerate/*.pb.go -# grpc/testing does not have a go_package option. -mv ${WORKDIR}/out/grpc/testing/*.pb.go interop/grpc_testing/ -mv ${WORKDIR}/out/grpc/core/*.pb.go interop/grpc_testing/core/ - cp -R ${WORKDIR}/out/google.golang.org/grpc/* . diff --git a/vendor/google.golang.org/grpc/resolver/map.go b/vendor/google.golang.org/grpc/resolver/map.go index efcb7f3efd8..804be887de0 100644 --- a/vendor/google.golang.org/grpc/resolver/map.go +++ b/vendor/google.golang.org/grpc/resolver/map.go @@ -20,7 +20,7 @@ package resolver type addressMapEntry struct { addr Address - value interface{} + value any } // AddressMap is a map of addresses to arbitrary values taking into account @@ -69,7 +69,7 @@ func (l addressMapEntryList) find(addr Address) int { } // Get returns the value for the address in the map, if present. -func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { +func (a *AddressMap) Get(addr Address) (value any, ok bool) { addrKey := toMapKey(&addr) entryList := a.m[addrKey] if entry := entryList.find(addr); entry != -1 { @@ -79,7 +79,7 @@ func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { } // Set updates or adds the value to the address in the map. -func (a *AddressMap) Set(addr Address, value interface{}) { +func (a *AddressMap) Set(addr Address, value any) { addrKey := toMapKey(&addr) entryList := a.m[addrKey] if entry := entryList.find(addr); entry != -1 { @@ -127,8 +127,8 @@ func (a *AddressMap) Keys() []Address { } // Values returns a slice of all current map values. -func (a *AddressMap) Values() []interface{} { - ret := make([]interface{}, 0, a.Len()) +func (a *AddressMap) Values() []any { + ret := make([]any, 0, a.Len()) for _, entryList := range a.m { for _, entry := range entryList { ret = append(ret, entry.value) diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 967cbc7373a..11384e228e5 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -22,12 +22,13 @@ package resolver import ( "context" + "fmt" "net" "net/url" + "strings" "google.golang.org/grpc/attributes" "google.golang.org/grpc/credentials" - "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/serviceconfig" ) @@ -40,8 +41,9 @@ var ( // TODO(bar) install dns resolver in init(){}. -// Register registers the resolver builder to the resolver map. b.Scheme will be -// used as the scheme registered with this builder. +// Register registers the resolver builder to the resolver map. b.Scheme will +// be used as the scheme registered with this builder. The registry is case +// sensitive, and schemes should not contain any uppercase characters. // // NOTE: this function must only be called during initialization time (i.e. in // an init() function), and is not thread-safe. If multiple Resolvers are @@ -75,25 +77,6 @@ func GetDefaultScheme() string { return defaultScheme } -// AddressType indicates the address type returned by name resolution. -// -// Deprecated: use Attributes in Address instead. -type AddressType uint8 - -const ( - // Backend indicates the address is for a backend server. - // - // Deprecated: use Attributes in Address instead. - Backend AddressType = iota - // GRPCLB indicates the address is for a grpclb load balancer. - // - // Deprecated: to select the GRPCLB load balancing policy, use a service - // config with a corresponding loadBalancingConfig. To supply balancer - // addresses to the GRPCLB load balancing policy, set State.Attributes - // using balancer/grpclb/state.Set. - GRPCLB -) - // Address represents a server the client connects to. // // # Experimental @@ -109,9 +92,6 @@ type Address struct { // the address, instead of the hostname from the Dial target string. In most cases, // this should not be set. // - // If Type is GRPCLB, ServerName should be the name of the remote load - // balancer, not the name of the backend. - // // WARNING: ServerName must only be populated with trusted values. It // is insecure to populate it with data from untrusted inputs since untrusted // values could be used to bypass the authority checks performed by TLS. @@ -122,34 +102,46 @@ type Address struct { Attributes *attributes.Attributes // BalancerAttributes contains arbitrary data about this address intended - // for consumption by the LB policy. These attribes do not affect SubConn + // for consumption by the LB policy. These attributes do not affect SubConn // creation, connection establishment, handshaking, etc. - BalancerAttributes *attributes.Attributes - - // Type is the type of this address. // - // Deprecated: use Attributes instead. - Type AddressType + // Deprecated: when an Address is inside an Endpoint, this field should not + // be used, and it will eventually be removed entirely. + BalancerAttributes *attributes.Attributes // Metadata is the information associated with Addr, which may be used // to make load balancing decision. // // Deprecated: use Attributes instead. - Metadata interface{} + Metadata any } // Equal returns whether a and o are identical. Metadata is compared directly, // not with any recursive introspection. +// +// This method compares all fields of the address. When used to tell apart +// addresses during subchannel creation or connection establishment, it might be +// more appropriate for the caller to implement custom equality logic. func (a Address) Equal(o Address) bool { return a.Addr == o.Addr && a.ServerName == o.ServerName && a.Attributes.Equal(o.Attributes) && a.BalancerAttributes.Equal(o.BalancerAttributes) && - a.Type == o.Type && a.Metadata == o.Metadata + a.Metadata == o.Metadata } // String returns JSON formatted string representation of the address. func (a Address) String() string { - return pretty.ToJSON(a) + var sb strings.Builder + sb.WriteString(fmt.Sprintf("{Addr: %q, ", a.Addr)) + sb.WriteString(fmt.Sprintf("ServerName: %q, ", a.ServerName)) + if a.Attributes != nil { + sb.WriteString(fmt.Sprintf("Attributes: %v, ", a.Attributes.String())) + } + if a.BalancerAttributes != nil { + sb.WriteString(fmt.Sprintf("BalancerAttributes: %v", a.BalancerAttributes.String())) + } + sb.WriteString("}") + return sb.String() } // BuildOptions includes additional information for the builder to create @@ -178,11 +170,37 @@ type BuildOptions struct { Dialer func(context.Context, string) (net.Conn, error) } +// An Endpoint is one network endpoint, or server, which may have multiple +// addresses with which it can be accessed. +type Endpoint struct { + // Addresses contains a list of addresses used to access this endpoint. + Addresses []Address + + // Attributes contains arbitrary data about this endpoint intended for + // consumption by the LB policy. + Attributes *attributes.Attributes +} + // State contains the current Resolver state relevant to the ClientConn. type State struct { // Addresses is the latest set of resolved addresses for the target. + // + // If a resolver sets Addresses but does not set Endpoints, one Endpoint + // will be created for each Address before the State is passed to the LB + // policy. The BalancerAttributes of each entry in Addresses will be set + // in Endpoints.Attributes, and be cleared in the Endpoint's Address's + // BalancerAttributes. + // + // Soon, Addresses will be deprecated and replaced fully by Endpoints. Addresses []Address + // Endpoints is the latest set of resolved endpoints for the target. + // + // If a resolver produces a State containing Endpoints but not Addresses, + // it must take care to ensure the LB policies it selects will support + // Endpoints. + Endpoints []Endpoint + // ServiceConfig contains the result from parsing the latest service // config. If it is nil, it indicates no service config is present or the // resolver does not provide service configs. @@ -202,6 +220,15 @@ type State struct { // gRPC to add new methods to this interface. type ClientConn interface { // UpdateState updates the state of the ClientConn appropriately. + // + // If an error is returned, the resolver should try to resolve the + // target again. The resolver should use a backoff timer to prevent + // overloading the server with requests. If a resolver is certain that + // reresolving will not change the result, e.g. because it is + // a watch-based resolver, returned errors can be ignored. + // + // If the resolved State is the same as the last reported one, calling + // UpdateState can be omitted. UpdateState(State) error // ReportError notifies the ClientConn that the Resolver encountered an // error. The ClientConn will notify the load balancer and begin calling @@ -233,23 +260,7 @@ type ClientConn interface { // target does not contain a scheme or if the parsed scheme is not registered // (i.e. no corresponding resolver available to resolve the endpoint), we will // apply the default scheme, and will attempt to reparse it. -// -// Examples: -// -// - "dns://some_authority/foo.bar" -// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} -// - "foo.bar" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} -// - "unknown_scheme://authority/endpoint" -// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} type Target struct { - // Deprecated: use URL.Scheme instead. - Scheme string - // Deprecated: use URL.Host instead. - Authority string - // Deprecated: use URL.Path or URL.Opaque instead. The latter is set when - // the former is empty. - Endpoint string // URL contains the parsed dial target with an optional default scheme added // to it if the original dial target contained no scheme or contained an // unregistered scheme. Any query params specified in the original dial @@ -257,6 +268,24 @@ type Target struct { URL url.URL } +// Endpoint retrieves endpoint without leading "/" from either `URL.Path` +// or `URL.Opaque`. The latter is used when the former is empty. +func (t Target) Endpoint() string { + endpoint := t.URL.Path + if endpoint == "" { + endpoint = t.URL.Opaque + } + // For targets of the form "[scheme]://[authority]/endpoint, the endpoint + // value returned from url.Parse() contains a leading "/". Although this is + // in accordance with RFC 3986, we do not want to break existing resolver + // implementations which expect the endpoint without the leading "/". So, we + // end up stripping the leading "/" here. But this will result in an + // incorrect parsing for something like "unix:///path/to/socket". Since we + // own the "unix" resolver, we can workaround in the unix resolver by using + // the `URL` field. + return strings.TrimPrefix(endpoint, "/") +} + // Builder creates a resolver that will be used to watch name resolution updates. type Builder interface { // Build creates a new resolver for the given target. @@ -264,8 +293,10 @@ type Builder interface { // gRPC dial calls Build synchronously, and fails if the returned error is // not nil. Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error) - // Scheme returns the scheme supported by this resolver. - // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md. + // Scheme returns the scheme supported by this resolver. Scheme is defined + // at https://github.com/grpc/grpc/blob/master/doc/naming.md. The returned + // string should not contain uppercase characters, as they will not match + // the parsed target's scheme as defined in RFC 3986. Scheme() string } @@ -283,10 +314,3 @@ type Resolver interface { // Close closes the resolver. Close() } - -// UnregisterForTesting removes the resolver builder with the given scheme from the -// resolver map. -// This function is for testing only. -func UnregisterForTesting(scheme string) { - delete(m, scheme) -} diff --git a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go index 05a9d4e0bac..d6833056084 100644 --- a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go @@ -19,11 +19,11 @@ package grpc import ( + "context" "strings" "sync" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/pretty" @@ -31,129 +31,200 @@ import ( "google.golang.org/grpc/serviceconfig" ) +// resolverStateUpdater wraps the single method used by ccResolverWrapper to +// report a state update from the actual resolver implementation. +type resolverStateUpdater interface { + updateResolverState(s resolver.State, err error) error +} + // ccResolverWrapper is a wrapper on top of cc for resolvers. // It implements resolver.ClientConn interface. type ccResolverWrapper struct { - cc *ClientConn - resolverMu sync.Mutex - resolver resolver.Resolver - done *grpcsync.Event - curState resolver.State + // The following fields are initialized when the wrapper is created and are + // read-only afterwards, and therefore can be accessed without a mutex. + cc resolverStateUpdater + channelzID *channelz.Identifier + ignoreServiceConfig bool + opts ccResolverWrapperOpts + serializer *grpcsync.CallbackSerializer // To serialize all incoming calls. + serializerCancel context.CancelFunc // To close the serializer, accessed only from close(). + + // All incoming (resolver --> gRPC) calls are guaranteed to execute in a + // mutually exclusive manner as they are scheduled on the serializer. + // Fields accessed *only* in these serializer callbacks, can therefore be + // accessed without a mutex. + curState resolver.State + + // mu guards access to the below fields. + mu sync.Mutex + closed bool + resolver resolver.Resolver // Accessed only from outgoing calls. +} - incomingMu sync.Mutex // Synchronizes all the incoming calls. +// ccResolverWrapperOpts wraps the arguments to be passed when creating a new +// ccResolverWrapper. +type ccResolverWrapperOpts struct { + target resolver.Target // User specified dial target to resolve. + builder resolver.Builder // Resolver builder to use. + bOpts resolver.BuildOptions // Resolver build options to use. + channelzID *channelz.Identifier // Channelz identifier for the channel. } // newCCResolverWrapper uses the resolver.Builder to build a Resolver and // returns a ccResolverWrapper object which wraps the newly built resolver. -func newCCResolverWrapper(cc *ClientConn, rb resolver.Builder) (*ccResolverWrapper, error) { +func newCCResolverWrapper(cc resolverStateUpdater, opts ccResolverWrapperOpts) (*ccResolverWrapper, error) { + ctx, cancel := context.WithCancel(context.Background()) ccr := &ccResolverWrapper{ - cc: cc, - done: grpcsync.NewEvent(), - } - - var credsClone credentials.TransportCredentials - if creds := cc.dopts.copts.TransportCredentials; creds != nil { - credsClone = creds.Clone() - } - rbo := resolver.BuildOptions{ - DisableServiceConfig: cc.dopts.disableServiceConfig, - DialCreds: credsClone, - CredsBundle: cc.dopts.copts.CredsBundle, - Dialer: cc.dopts.copts.Dialer, - } - - var err error - // We need to hold the lock here while we assign to the ccr.resolver field - // to guard against a data race caused by the following code path, - // rb.Build-->ccr.ReportError-->ccr.poll-->ccr.resolveNow, would end up - // accessing ccr.resolver which is being assigned here. - ccr.resolverMu.Lock() - defer ccr.resolverMu.Unlock() - ccr.resolver, err = rb.Build(cc.parsedTarget, ccr, rbo) + cc: cc, + channelzID: opts.channelzID, + ignoreServiceConfig: opts.bOpts.DisableServiceConfig, + opts: opts, + serializer: grpcsync.NewCallbackSerializer(ctx), + serializerCancel: cancel, + } + + // Cannot hold the lock at build time because the resolver can send an + // update or error inline and these incoming calls grab the lock to schedule + // a callback in the serializer. + r, err := opts.builder.Build(opts.target, ccr, opts.bOpts) if err != nil { + cancel() return nil, err } + + // Any error reported by the resolver at build time that leads to a + // re-resolution request from the balancer is dropped by grpc until we + // return from this function. So, we don't have to handle pending resolveNow + // requests here. + ccr.mu.Lock() + ccr.resolver = r + ccr.mu.Unlock() + return ccr, nil } func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) { - ccr.resolverMu.Lock() - if !ccr.done.HasFired() { - ccr.resolver.ResolveNow(o) + ccr.mu.Lock() + defer ccr.mu.Unlock() + + // ccr.resolver field is set only after the call to Build() returns. But in + // the process of building, the resolver may send an error update which when + // propagated to the balancer may result in a re-resolution request. + if ccr.closed || ccr.resolver == nil { + return } - ccr.resolverMu.Unlock() + ccr.resolver.ResolveNow(o) } func (ccr *ccResolverWrapper) close() { - ccr.resolverMu.Lock() - ccr.resolver.Close() - ccr.done.Fire() - ccr.resolverMu.Unlock() + ccr.mu.Lock() + if ccr.closed { + ccr.mu.Unlock() + return + } + + channelz.Info(logger, ccr.channelzID, "Closing the name resolver") + + // Close the serializer to ensure that no more calls from the resolver are + // handled, before actually closing the resolver. + ccr.serializerCancel() + ccr.closed = true + r := ccr.resolver + ccr.mu.Unlock() + + // Give enqueued callbacks a chance to finish. + <-ccr.serializer.Done() + + // Spawn a goroutine to close the resolver (since it may block trying to + // cleanup all allocated resources) and return early. + go r.Close() +} + +// serializerScheduleLocked is a convenience method to schedule a function to be +// run on the serializer while holding ccr.mu. +func (ccr *ccResolverWrapper) serializerScheduleLocked(f func(context.Context)) { + ccr.mu.Lock() + ccr.serializer.Schedule(f) + ccr.mu.Unlock() } +// UpdateState is called by resolver implementations to report new state to gRPC +// which includes addresses and service config. func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error { - ccr.incomingMu.Lock() - defer ccr.incomingMu.Unlock() - if ccr.done.HasFired() { + errCh := make(chan error, 1) + if s.Endpoints == nil { + s.Endpoints = make([]resolver.Endpoint, 0, len(s.Addresses)) + for _, a := range s.Addresses { + ep := resolver.Endpoint{Addresses: []resolver.Address{a}, Attributes: a.BalancerAttributes} + ep.Addresses[0].BalancerAttributes = nil + s.Endpoints = append(s.Endpoints, ep) + } + } + ok := ccr.serializer.Schedule(func(context.Context) { + ccr.addChannelzTraceEvent(s) + ccr.curState = s + if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState { + errCh <- balancer.ErrBadResolverState + return + } + errCh <- nil + }) + if !ok { + // The only time when Schedule() fail to add the callback to the + // serializer is when the serializer is closed, and this happens only + // when the resolver wrapper is closed. return nil } - ccr.addChannelzTraceEvent(s) - ccr.curState = s - if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState { - return balancer.ErrBadResolverState - } - return nil + return <-errCh } +// ReportError is called by resolver implementations to report errors +// encountered during name resolution to gRPC. func (ccr *ccResolverWrapper) ReportError(err error) { - ccr.incomingMu.Lock() - defer ccr.incomingMu.Unlock() - if ccr.done.HasFired() { - return - } - channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: reporting error to cc: %v", err) - ccr.cc.updateResolverState(resolver.State{}, err) + ccr.serializerScheduleLocked(func(_ context.Context) { + channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: reporting error to cc: %v", err) + ccr.cc.updateResolverState(resolver.State{}, err) + }) } -// NewAddress is called by the resolver implementation to send addresses to gRPC. +// NewAddress is called by the resolver implementation to send addresses to +// gRPC. func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { - ccr.incomingMu.Lock() - defer ccr.incomingMu.Unlock() - if ccr.done.HasFired() { - return - } - ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}) - ccr.curState.Addresses = addrs - ccr.cc.updateResolverState(ccr.curState, nil) + ccr.serializerScheduleLocked(func(_ context.Context) { + ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}) + ccr.curState.Addresses = addrs + ccr.cc.updateResolverState(ccr.curState, nil) + }) } // NewServiceConfig is called by the resolver implementation to send service // configs to gRPC. func (ccr *ccResolverWrapper) NewServiceConfig(sc string) { - ccr.incomingMu.Lock() - defer ccr.incomingMu.Unlock() - if ccr.done.HasFired() { - return - } - channelz.Infof(logger, ccr.cc.channelzID, "ccResolverWrapper: got new service config: %s", sc) - if ccr.cc.dopts.disableServiceConfig { - channelz.Info(logger, ccr.cc.channelzID, "Service config lookups disabled; ignoring config") - return - } - scpr := parseServiceConfig(sc) - if scpr.Err != nil { - channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err) - return - } - ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr}) - ccr.curState.ServiceConfig = scpr - ccr.cc.updateResolverState(ccr.curState, nil) + ccr.serializerScheduleLocked(func(_ context.Context) { + channelz.Infof(logger, ccr.channelzID, "ccResolverWrapper: got new service config: %s", sc) + if ccr.ignoreServiceConfig { + channelz.Info(logger, ccr.channelzID, "Service config lookups disabled; ignoring config") + return + } + scpr := parseServiceConfig(sc) + if scpr.Err != nil { + channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err) + return + } + ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr}) + ccr.curState.ServiceConfig = scpr + ccr.cc.updateResolverState(ccr.curState, nil) + }) } +// ParseServiceConfig is called by resolver implementations to parse a JSON +// representation of the service config. func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult { return parseServiceConfig(scJSON) } +// addChannelzTraceEvent adds a channelz trace event containing the new +// state received from resolver implementations. func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { var updates []string var oldSC, newSC *ServiceConfig @@ -172,5 +243,5 @@ func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { updates = append(updates, "resolver returned new addresses") } - channelz.Infof(logger, ccr.cc.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) + channelz.Infof(logger, ccr.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) } diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 934fc1aa015..b7723aa09cb 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -25,7 +25,6 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" "math" "strings" "sync" @@ -76,8 +75,8 @@ func NewGZIPCompressorWithLevel(level int) (Compressor, error) { } return &gzipCompressor{ pool: sync.Pool{ - New: func() interface{} { - w, err := gzip.NewWriterLevel(ioutil.Discard, level) + New: func() any { + w, err := gzip.NewWriterLevel(io.Discard, level) if err != nil { panic(err) } @@ -143,7 +142,7 @@ func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) { z.Close() d.pool.Put(z) }() - return ioutil.ReadAll(z) + return io.ReadAll(z) } func (d *gzipDecompressor) Type() string { @@ -160,6 +159,7 @@ type callInfo struct { contentSubtype string codec baseCodec maxRetryRPCBufferSize int + onFinish []func(err error) } func defaultCallInfo() *callInfo { @@ -296,8 +296,44 @@ func (o FailFastCallOption) before(c *callInfo) error { } func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {} +// OnFinish returns a CallOption that configures a callback to be called when +// the call completes. The error passed to the callback is the status of the +// RPC, and may be nil. The onFinish callback provided will only be called once +// by gRPC. This is mainly used to be used by streaming interceptors, to be +// notified when the RPC completes along with information about the status of +// the RPC. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func OnFinish(onFinish func(err error)) CallOption { + return OnFinishCallOption{ + OnFinish: onFinish, + } +} + +// OnFinishCallOption is CallOption that indicates a callback to be called when +// the call completes. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type OnFinishCallOption struct { + OnFinish func(error) +} + +func (o OnFinishCallOption) before(c *callInfo) error { + c.onFinish = append(c.onFinish, o.OnFinish) + return nil +} + +func (o OnFinishCallOption) after(c *callInfo, attempt *csAttempt) {} + // MaxCallRecvMsgSize returns a CallOption which sets the maximum message size -// in bytes the client can receive. +// in bytes the client can receive. If this is not set, gRPC uses the default +// 4MB. func MaxCallRecvMsgSize(bytes int) CallOption { return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: bytes} } @@ -320,7 +356,8 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error { func (o MaxRecvMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {} // MaxCallSendMsgSize returns a CallOption which sets the maximum message size -// in bytes the client can send. +// in bytes the client can send. If this is not set, gRPC uses the default +// `math.MaxInt32`. func MaxCallSendMsgSize(bytes int) CallOption { return MaxSendMsgSizeCallOption{MaxSendMsgSize: bytes} } @@ -540,6 +577,9 @@ type parser struct { // The header of a gRPC message. Find more detail at // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md header [5]byte + + // recvBufferPool is the pool of shared receive buffers. + recvBufferPool SharedBufferPool } // recvMsg reads a complete gRPC message from the stream. @@ -573,9 +613,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt if int(length) > maxReceiveMessageSize { return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize) } - // TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead - // of making it for each message: - msg = make([]byte, int(length)) + msg = p.recvBufferPool.Get(int(length)) if _, err := p.r.Read(msg); err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF @@ -588,7 +626,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt // encode serializes msg and returns a buffer containing the message, or an // error if it is too large to be transmitted by grpc. If msg is nil, it // generates an empty message. -func encode(c baseCodec, msg interface{}) ([]byte, error) { +func encode(c baseCodec, msg any) ([]byte, error) { if msg == nil { // NOTE: typed nils will not be caught by this check return nil, nil } @@ -655,14 +693,15 @@ func msgHeader(data, compData []byte) (hdr []byte, payload []byte) { return hdr, data } -func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload { +func outPayload(client bool, msg any, data, payload []byte, t time.Time) *stats.OutPayload { return &stats.OutPayload{ - Client: client, - Payload: msg, - Data: data, - Length: len(data), - WireLength: len(payload) + headerLen, - SentTime: t, + Client: client, + Payload: msg, + Data: data, + Length: len(data), + WireLength: len(payload) + headerLen, + CompressedLength: len(payload), + SentTime: t, } } @@ -683,17 +722,17 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool } type payloadInfo struct { - wireLength int // The compressed length got from wire. + compressedLength int // The compressed length got from wire. uncompressedBytes []byte } func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) { - pf, d, err := p.recvMsg(maxReceiveMessageSize) + pf, buf, err := p.recvMsg(maxReceiveMessageSize) if err != nil { return nil, err } if payInfo != nil { - payInfo.wireLength = len(d) + payInfo.compressedLength = len(buf) } if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil { @@ -705,13 +744,13 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei // To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor, // use this decompressor as the default. if dc != nil { - d, err = dc.Do(bytes.NewReader(d)) - size = len(d) + buf, err = dc.Do(bytes.NewReader(buf)) + size = len(buf) } else { - d, size, err = decompress(compressor, d, maxReceiveMessageSize) + buf, size, err = decompress(compressor, buf, maxReceiveMessageSize) } if err != nil { - return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) + return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) } if size > maxReceiveMessageSize { // TODO: Revisit the error code. Currently keep it consistent with java @@ -719,7 +758,7 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) } } - return d, nil + return buf, nil } // Using compressor, decompress d, returning data and size. @@ -746,23 +785,25 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize } // Read from LimitReader with limit max+1. So if the underlying // reader is over limit, the result will be bigger than max. - d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) + d, err = io.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) return d, len(d), err } // For the two compressor parameters, both should not be set, but if they are, // dc takes precedence over compressor. // TODO(dfawley): wrap the old compressor/decompressor using the new API? -func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { - d, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) +func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { + buf, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) if err != nil { return err } - if err := c.Unmarshal(d, m); err != nil { - return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err) + if err := c.Unmarshal(buf, m); err != nil { + return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err) } if payInfo != nil { - payInfo.uncompressedBytes = d + payInfo.uncompressedBytes = buf + } else { + p.recvBufferPool.Put(&buf) } return nil } @@ -822,19 +863,22 @@ func ErrorDesc(err error) string { // Errorf returns nil if c is OK. // // Deprecated: use status.Errorf instead. -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return status.Errorf(c, format, a...) } +var errContextCanceled = status.Error(codes.Canceled, context.Canceled.Error()) +var errContextDeadline = status.Error(codes.DeadlineExceeded, context.DeadlineExceeded.Error()) + // toRPCErr converts an error into an error from the status package. func toRPCErr(err error) error { switch err { case nil, io.EOF: return err case context.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) + return errContextDeadline case context.Canceled: - return status.Error(codes.Canceled, err.Error()) + return errContextCanceled case io.ErrUnexpectedEOF: return status.Error(codes.Internal, err.Error()) } diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index f4dde72b41f..244123c6c5a 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -43,8 +43,8 @@ import ( "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" - "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" @@ -74,10 +74,10 @@ func init() { srv.drainServerTransports(addr) } internal.AddGlobalServerOptions = func(opt ...ServerOption) { - extraServerOptions = append(extraServerOptions, opt...) + globalServerOptions = append(globalServerOptions, opt...) } internal.ClearGlobalServerOptions = func() { - extraServerOptions = nil + globalServerOptions = nil } internal.BinaryLogger = binaryLogger internal.JoinServerOptions = newJoinServerOption @@ -86,7 +86,7 @@ func init() { var statusOK = status.New(codes.OK, "") var logger = grpclog.Component("core") -type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error) +type methodHandler func(srv any, ctx context.Context, dec func(any) error, interceptor UnaryServerInterceptor) (any, error) // MethodDesc represents an RPC service's method specification. type MethodDesc struct { @@ -99,20 +99,20 @@ type ServiceDesc struct { ServiceName string // The pointer to the service interface. Used to check whether the user // provided implementation satisfies the interface requirements. - HandlerType interface{} + HandlerType any Methods []MethodDesc Streams []StreamDesc - Metadata interface{} + Metadata any } // serviceInfo wraps information about a service. It is very similar to // ServiceDesc and is constructed from it for internal purposes. type serviceInfo struct { // Contains the implementation for the methods in this service. - serviceImpl interface{} + serviceImpl any methods map[string]*MethodDesc streams map[string]*StreamDesc - mdata interface{} + mdata any } type serverWorkerData struct { @@ -145,7 +145,7 @@ type Server struct { channelzID *channelz.Identifier czData *channelzData - serverWorkerChannels []chan *serverWorkerData + serverWorkerChannel chan *serverWorkerData } type serverOptions struct { @@ -170,10 +170,12 @@ type serverOptions struct { initialConnWindowSize int32 writeBufferSize int readBufferSize int + sharedWriteBuffer bool connectionTimeout time.Duration maxHeaderListSize *uint32 headerTableSize *uint32 numServerWorkers uint32 + recvBufferPool SharedBufferPool } var defaultServerOptions = serverOptions{ @@ -182,8 +184,9 @@ var defaultServerOptions = serverOptions{ connectionTimeout: 120 * time.Second, writeBufferSize: defaultWriteBufSize, readBufferSize: defaultReadBufSize, + recvBufferPool: nopBufferPool{}, } -var extraServerOptions []ServerOption +var globalServerOptions []ServerOption // A ServerOption sets options such as credentials, codec and keepalive parameters, etc. type ServerOption interface { @@ -233,10 +236,25 @@ func newJoinServerOption(opts ...ServerOption) ServerOption { return &joinServerOption{opts: opts} } -// WriteBufferSize determines how much data can be batched before doing a write on the wire. -// The corresponding memory allocation for this buffer will be twice the size to keep syscalls low. -// The default value for this buffer is 32KB. -// Zero will disable the write buffer such that each write will be on underlying connection. +// SharedWriteBuffer allows reusing per-connection transport write buffer. +// If this option is set to true every connection will release the buffer after +// flushing the data on the wire. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func SharedWriteBuffer(val bool) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.sharedWriteBuffer = val + }) +} + +// WriteBufferSize determines how much data can be batched before doing a write +// on the wire. The corresponding memory allocation for this buffer will be +// twice the size to keep syscalls low. The default value for this buffer is +// 32KB. Zero or negative values will disable the write buffer such that each +// write will be on underlying connection. // Note: A Send call may not directly translate to a write. func WriteBufferSize(s int) ServerOption { return newFuncServerOption(func(o *serverOptions) { @@ -244,11 +262,10 @@ func WriteBufferSize(s int) ServerOption { }) } -// ReadBufferSize lets you set the size of read buffer, this determines how much data can be read at most -// for one read syscall. -// The default value for this buffer is 32KB. -// Zero will disable read buffer for a connection so data framer can access the underlying -// conn directly. +// ReadBufferSize lets you set the size of read buffer, this determines how much +// data can be read at most for one read syscall. The default value for this +// buffer is 32KB. Zero or negative values will disable read buffer for a +// connection so data framer can access the underlying conn directly. func ReadBufferSize(s int) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.readBufferSize = s @@ -273,9 +290,9 @@ func InitialConnWindowSize(s int32) ServerOption { // KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server. func KeepaliveParams(kp keepalive.ServerParameters) ServerOption { - if kp.Time > 0 && kp.Time < time.Second { + if kp.Time > 0 && kp.Time < internal.KeepaliveMinServerPingTime { logger.Warning("Adjusting keepalive ping interval to minimum period of 1s") - kp.Time = time.Second + kp.Time = internal.KeepaliveMinServerPingTime } return newFuncServerOption(func(o *serverOptions) { @@ -552,6 +569,27 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption { }) } +// RecvBufferPool returns a ServerOption that configures the server +// to use the provided shared buffer pool for parsing incoming messages. Depending +// on the application's workload, this could result in reduced memory allocation. +// +// If you are unsure about how to implement a memory pool but want to utilize one, +// begin with grpc.NewSharedBufferPool. +// +// Note: The shared buffer pool feature will not be active if any of the following +// options are used: StatsHandler, EnableTracing, or binary logging. In such +// cases, the shared buffer pool will be ignored. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func RecvBufferPool(bufferPool SharedBufferPool) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.recvBufferPool = bufferPool + }) +} + // serverWorkerResetThreshold defines how often the stack must be reset. Every // N requests, by spawning a new goroutine in its place, a worker can reset its // stack so that large stacks don't live in memory forever. 2^16 should allow @@ -560,47 +598,45 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption { const serverWorkerResetThreshold = 1 << 16 // serverWorkers blocks on a *transport.Stream channel forever and waits for -// data to be fed by serveStreams. This allows different requests to be +// data to be fed by serveStreams. This allows multiple requests to be // processed by the same goroutine, removing the need for expensive stack // re-allocations (see the runtime.morestack problem [1]). // // [1] https://github.com/golang/go/issues/18138 -func (s *Server) serverWorker(ch chan *serverWorkerData) { - // To make sure all server workers don't reset at the same time, choose a - // random number of iterations before resetting. - threshold := serverWorkerResetThreshold + grpcrand.Intn(serverWorkerResetThreshold) - for completed := 0; completed < threshold; completed++ { - data, ok := <-ch +func (s *Server) serverWorker() { + for completed := 0; completed < serverWorkerResetThreshold; completed++ { + data, ok := <-s.serverWorkerChannel if !ok { return } - s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream)) - data.wg.Done() + s.handleSingleStream(data) } - go s.serverWorker(ch) + go s.serverWorker() +} + +func (s *Server) handleSingleStream(data *serverWorkerData) { + defer data.wg.Done() + s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream)) } -// initServerWorkers creates worker goroutines and channels to process incoming +// initServerWorkers creates worker goroutines and a channel to process incoming // connections to reduce the time spent overall on runtime.morestack. func (s *Server) initServerWorkers() { - s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers) + s.serverWorkerChannel = make(chan *serverWorkerData) for i := uint32(0); i < s.opts.numServerWorkers; i++ { - s.serverWorkerChannels[i] = make(chan *serverWorkerData) - go s.serverWorker(s.serverWorkerChannels[i]) + go s.serverWorker() } } func (s *Server) stopServerWorkers() { - for i := uint32(0); i < s.opts.numServerWorkers; i++ { - close(s.serverWorkerChannels[i]) - } + close(s.serverWorkerChannel) } // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { opts := defaultServerOptions - for _, o := range extraServerOptions { + for _, o := range globalServerOptions { o.apply(&opts) } for _, o := range opt { @@ -634,7 +670,7 @@ func NewServer(opt ...ServerOption) *Server { // printf records an event in s's event log, unless s has been stopped. // REQUIRES s.mu is held. -func (s *Server) printf(format string, a ...interface{}) { +func (s *Server) printf(format string, a ...any) { if s.events != nil { s.events.Printf(format, a...) } @@ -642,7 +678,7 @@ func (s *Server) printf(format string, a ...interface{}) { // errorf records an error in s's event log, unless s has been stopped. // REQUIRES s.mu is held. -func (s *Server) errorf(format string, a ...interface{}) { +func (s *Server) errorf(format string, a ...any) { if s.events != nil { s.events.Errorf(format, a...) } @@ -657,14 +693,14 @@ type ServiceRegistrar interface { // once the server has started serving. // desc describes the service and its methods and handlers. impl is the // service implementation which is passed to the method handlers. - RegisterService(desc *ServiceDesc, impl interface{}) + RegisterService(desc *ServiceDesc, impl any) } // RegisterService registers a service and its implementation to the gRPC // server. It is called from the IDL generated code. This must be called before // invoking Serve. If ss is non-nil (for legacy code), its type is checked to // ensure it implements sd.HandlerType. -func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { +func (s *Server) RegisterService(sd *ServiceDesc, ss any) { if ss != nil { ht := reflect.TypeOf(sd.HandlerType).Elem() st := reflect.TypeOf(ss) @@ -675,7 +711,7 @@ func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { s.register(sd, ss) } -func (s *Server) register(sd *ServiceDesc, ss interface{}) { +func (s *Server) register(sd *ServiceDesc, ss any) { s.mu.Lock() defer s.mu.Unlock() s.printf("RegisterService(%q)", sd.ServiceName) @@ -716,7 +752,7 @@ type MethodInfo struct { type ServiceInfo struct { Methods []MethodInfo // Metadata is the metadata specified in ServiceDesc when registering service. - Metadata interface{} + Metadata any } // GetServiceInfo returns a map from service names to ServiceInfo. @@ -897,7 +933,7 @@ func (s *Server) drainServerTransports(addr string) { s.mu.Lock() conns := s.conns[addr] for st := range conns { - st.Drain() + st.Drain("") } s.mu.Unlock() } @@ -917,6 +953,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { InitialConnWindowSize: s.opts.initialConnWindowSize, WriteBufferSize: s.opts.writeBufferSize, ReadBufferSize: s.opts.readBufferSize, + SharedWriteBuffer: s.opts.sharedWriteBuffer, ChannelzParentID: s.channelzID, MaxHeaderListSize: s.opts.maxHeaderListSize, HeaderTableSize: s.opts.headerTableSize, @@ -942,29 +979,24 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { } func (s *Server) serveStreams(st transport.ServerTransport) { - defer st.Close() + defer st.Close(errors.New("finished serving streams for the server transport")) var wg sync.WaitGroup - var roundRobinCounter uint32 st.HandleStreams(func(stream *transport.Stream) { wg.Add(1) if s.opts.numServerWorkers > 0 { data := &serverWorkerData{st: st, wg: &wg, stream: stream} select { - case s.serverWorkerChannels[atomic.AddUint32(&roundRobinCounter, 1)%s.opts.numServerWorkers] <- data: + case s.serverWorkerChannel <- data: + return default: // If all stream workers are busy, fallback to the default code path. - go func() { - s.handleStream(st, stream, s.traceInfo(st, stream)) - wg.Done() - }() } - } else { - go func() { - defer wg.Done() - s.handleStream(st, stream, s.traceInfo(st, stream)) - }() } + go func() { + defer wg.Done() + s.handleStream(st, stream, s.traceInfo(st, stream)) + }() }, func(ctx context.Context, method string) context.Context { if !EnableTracing { return ctx @@ -1008,7 +1040,8 @@ var _ http.Handler = (*Server)(nil) func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { st, err := transport.NewServerHandlerTransport(w, r, s.opts.statsHandlers) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + // Errors returned from transport.NewServerHandlerTransport have + // already been written to w. return } if !s.addConn(listenerAddressForServeHTTP, st) { @@ -1046,13 +1079,13 @@ func (s *Server) addConn(addr string, st transport.ServerTransport) bool { s.mu.Lock() defer s.mu.Unlock() if s.conns == nil { - st.Close() + st.Close(errors.New("Server.addConn called when server has already been stopped")) return false } if s.drain { // Transport added after we drained our existing conns: drain it // immediately. - st.Drain() + st.Drain("") } if s.conns[addr] == nil { @@ -1102,7 +1135,7 @@ func (s *Server) incrCallsFailed() { atomic.AddInt64(&s.czData.callsFailed, 1) } -func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { +func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg any, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { data, err := encode(s.getCodec(stream.ContentSubtype()), msg) if err != nil { channelz.Error(logger, s.channelzID, "grpc: server failed to encode response: ", err) @@ -1149,22 +1182,17 @@ func chainUnaryServerInterceptors(s *Server) { } func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) { - // the struct ensures the variables are allocated together, rather than separately, since we - // know they should be garbage collected together. This saves 1 allocation and decreases - // time/call by about 10% on the microbenchmark. - var state struct { - i int - next UnaryHandler - } - state.next = func(ctx context.Context, req interface{}) (interface{}, error) { - if state.i == len(interceptors)-1 { - return interceptors[state.i](ctx, req, info, handler) - } - state.i++ - return interceptors[state.i-1](ctx, req, info, state.next) - } - return state.next(ctx, req) + return func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (any, error) { + return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler)) + } +} + +func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info *UnaryServerInfo, finalHandler UnaryHandler) UnaryHandler { + if curr == len(interceptors)-1 { + return finalHandler + } + return func(ctx context.Context, req any) (any, error) { + return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler)) } } @@ -1200,7 +1228,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. defer func() { if trInfo != nil { if err != nil && err != io.EOF { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) trInfo.tr.SetError() } trInfo.tr.Finish() @@ -1256,7 +1284,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. logEntry.PeerAddr = peer.Addr } for _, binlog := range binlogs { - binlog.Log(logEntry) + binlog.Log(ctx, logEntry) } } @@ -1267,6 +1295,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. var comp, decomp encoding.Compressor var cp Compressor var dc Decompressor + var sendCompressorName string // If dc is set and matches the stream's compression, use it. Otherwise, try // to find a matching registered compressor for decomp. @@ -1287,12 +1316,18 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. // NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686. if s.opts.cp != nil { cp = s.opts.cp - stream.SetSendCompress(cp.Type()) + sendCompressorName = cp.Type() } else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity { // Legacy compressor not specified; attempt to respond with same encoding. comp = encoding.GetCompressor(rc) if comp != nil { - stream.SetSendCompress(rc) + sendCompressorName = comp.Name() + } + } + + if sendCompressorName != "" { + if err := stream.SetSendCompress(sendCompressorName); err != nil { + return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err) } } @@ -1300,27 +1335,28 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if len(shs) != 0 || len(binlogs) != 0 { payInfo = &payloadInfo{} } - d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) + d, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) if err != nil { if e := t.WriteStatus(stream, status.Convert(err)); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status %v", e) + channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) } return err } if channelz.IsOn() { t.IncrMsgRecv() } - df := func(v interface{}) error { + df := func(v any) error { if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) } for _, sh := range shs { sh.HandleRPC(stream.Context(), &stats.InPayload{ - RecvTime: time.Now(), - Payload: v, - WireLength: payInfo.wireLength + headerLen, - Data: d, - Length: len(d), + RecvTime: time.Now(), + Payload: v, + Length: len(d), + WireLength: payInfo.compressedLength + headerLen, + CompressedLength: payInfo.compressedLength, + Data: d, }) } if len(binlogs) != 0 { @@ -1328,7 +1364,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Message: d, } for _, binlog := range binlogs { - binlog.Log(cm) + binlog.Log(stream.Context(), cm) } } if trInfo != nil { @@ -1361,7 +1397,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Header: h, } for _, binlog := range binlogs { - binlog.Log(sh) + binlog.Log(stream.Context(), sh) } } st := &binarylog.ServerTrailer{ @@ -1369,7 +1405,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Err: appErr, } for _, binlog := range binlogs { - binlog.Log(st) + binlog.Log(stream.Context(), st) } } return appErr @@ -1379,6 +1415,11 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } opts := &transport.Options{Last: true} + // Server handler could have set new compressor by calling SetSendCompressor. + // In case it is set, we need to use it for compressing outbound message. + if stream.SendCompress() != sendCompressorName { + comp = encoding.GetCompressor(stream.SendCompress()) + } if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil { if err == io.EOF { // The entire stream is done (for unary RPC only). @@ -1406,8 +1447,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Err: appErr, } for _, binlog := range binlogs { - binlog.Log(sh) - binlog.Log(st) + binlog.Log(stream.Context(), sh) + binlog.Log(stream.Context(), st) } } return err @@ -1421,8 +1462,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Message: reply, } for _, binlog := range binlogs { - binlog.Log(sh) - binlog.Log(sm) + binlog.Log(stream.Context(), sh) + binlog.Log(stream.Context(), sm) } } if channelz.IsOn() { @@ -1434,17 +1475,16 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. // TODO: Should we be logging if writing status failed here, like above? // Should the logging be in WriteStatus? Should we ignore the WriteStatus // error or allow the stats handler to see it? - err = t.WriteStatus(stream, statusOK) if len(binlogs) != 0 { st := &binarylog.ServerTrailer{ Trailer: stream.Trailer(), Err: appErr, } for _, binlog := range binlogs { - binlog.Log(st) + binlog.Log(stream.Context(), st) } } - return err + return t.WriteStatus(stream, statusOK) } // chainStreamServerInterceptors chains all stream server interceptors into one. @@ -1469,22 +1509,17 @@ func chainStreamServerInterceptors(s *Server) { } func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor { - return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { - // the struct ensures the variables are allocated together, rather than separately, since we - // know they should be garbage collected together. This saves 1 allocation and decreases - // time/call by about 10% on the microbenchmark. - var state struct { - i int - next StreamHandler - } - state.next = func(srv interface{}, ss ServerStream) error { - if state.i == len(interceptors)-1 { - return interceptors[state.i](srv, ss, info, handler) - } - state.i++ - return interceptors[state.i-1](srv, ss, info, state.next) - } - return state.next(srv, ss) + return func(srv any, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { + return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler)) + } +} + +func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, info *StreamServerInfo, finalHandler StreamHandler) StreamHandler { + if curr == len(interceptors)-1 { + return finalHandler + } + return func(srv any, stream ServerStream) error { + return interceptors[curr+1](srv, stream, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler)) } } @@ -1510,7 +1545,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ctx: ctx, t: t, s: stream, - p: &parser{r: stream}, + p: &parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, codec: s.getCodec(stream.ContentSubtype()), maxReceiveMessageSize: s.opts.maxReceiveMessageSize, maxSendMessageSize: s.opts.maxSendMessageSize, @@ -1524,7 +1559,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp if trInfo != nil { ss.mu.Lock() if err != nil && err != io.EOF { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } ss.trInfo.tr.Finish() @@ -1583,7 +1618,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp logEntry.PeerAddr = peer.Addr } for _, binlog := range ss.binlogs { - binlog.Log(logEntry) + binlog.Log(stream.Context(), logEntry) } } @@ -1606,12 +1641,18 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp // NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686. if s.opts.cp != nil { ss.cp = s.opts.cp - stream.SetSendCompress(s.opts.cp.Type()) + ss.sendCompressorName = s.opts.cp.Type() } else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity { // Legacy compressor not specified; attempt to respond with same encoding. ss.comp = encoding.GetCompressor(rc) if ss.comp != nil { - stream.SetSendCompress(rc) + ss.sendCompressorName = rc + } + } + + if ss.sendCompressorName != "" { + if err := stream.SetSendCompress(ss.sendCompressorName); err != nil { + return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err) } } @@ -1621,7 +1662,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp trInfo.tr.LazyLog(&trInfo.firstLine, false) } var appErr error - var server interface{} + var server any if info != nil { server = info.serviceImpl } @@ -1649,16 +1690,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.trInfo.tr.SetError() ss.mu.Unlock() } - t.WriteStatus(ss.s, appStatus) if len(ss.binlogs) != 0 { st := &binarylog.ServerTrailer{ Trailer: ss.s.Trailer(), Err: appErr, } for _, binlog := range ss.binlogs { - binlog.Log(st) + binlog.Log(stream.Context(), st) } } + t.WriteStatus(ss.s, appStatus) // TODO: Should we log an error from WriteStatus here and below? return appErr } @@ -1667,17 +1708,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.trInfo.tr.LazyLog(stringer("OK"), false) ss.mu.Unlock() } - err = t.WriteStatus(ss.s, statusOK) if len(ss.binlogs) != 0 { st := &binarylog.ServerTrailer{ Trailer: ss.s.Trailer(), Err: appErr, } for _, binlog := range ss.binlogs { - binlog.Log(st) + binlog.Log(stream.Context(), st) } } - return err + return t.WriteStatus(ss.s, statusOK) } func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) { @@ -1688,13 +1728,13 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str pos := strings.LastIndex(sm, "/") if pos == -1 { if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true) + trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []any{sm}}, true) trInfo.tr.SetError() } errDesc := fmt.Sprintf("malformed method name: %q", stream.Method()) if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) trInfo.tr.SetError() } channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) @@ -1735,7 +1775,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str } if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) trInfo.tr.SetError() } channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) @@ -1819,7 +1859,7 @@ func (s *Server) Stop() { } for _, cs := range conns { for st := range cs { - st.Close() + st.Close(errors.New("Server.Stop called")) } } if s.opts.numServerWorkers > 0 { @@ -1855,7 +1895,7 @@ func (s *Server) GracefulStop() { if !s.drain { for _, conns := range s.conns { for st := range conns { - st.Drain() + st.Drain("graceful_stop") } } s.drain = true @@ -1944,6 +1984,60 @@ func SendHeader(ctx context.Context, md metadata.MD) error { return nil } +// SetSendCompressor sets a compressor for outbound messages from the server. +// It must not be called after any event that causes headers to be sent +// (see ServerStream.SetHeader for the complete list). Provided compressor is +// used when below conditions are met: +// +// - compressor is registered via encoding.RegisterCompressor +// - compressor name must exist in the client advertised compressor names +// sent in grpc-accept-encoding header. Use ClientSupportedCompressors to +// get client supported compressor names. +// +// The context provided must be the context passed to the server's handler. +// It must be noted that compressor name encoding.Identity disables the +// outbound compression. +// By default, server messages will be sent using the same compressor with +// which request messages were sent. +// +// It is not safe to call SetSendCompressor concurrently with SendHeader and +// SendMsg. +// +// # Experimental +// +// Notice: This function is EXPERIMENTAL and may be changed or removed in a +// later release. +func SetSendCompressor(ctx context.Context, name string) error { + stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream) + if !ok || stream == nil { + return fmt.Errorf("failed to fetch the stream from the given context") + } + + if err := validateSendCompressor(name, stream.ClientAdvertisedCompressors()); err != nil { + return fmt.Errorf("unable to set send compressor: %w", err) + } + + return stream.SetSendCompress(name) +} + +// ClientSupportedCompressors returns compressor names advertised by the client +// via grpc-accept-encoding header. +// +// The context provided must be the context passed to the server's handler. +// +// # Experimental +// +// Notice: This function is EXPERIMENTAL and may be changed or removed in a +// later release. +func ClientSupportedCompressors(ctx context.Context) ([]string, error) { + stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream) + if !ok || stream == nil { + return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx) + } + + return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil +} + // SetTrailer sets the trailer metadata that will be sent when an RPC returns. // When called more than once, all the provided metadata will be merged. // @@ -1978,3 +2072,22 @@ type channelzServer struct { func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric { return c.s.channelzMetric() } + +// validateSendCompressor returns an error when given compressor name cannot be +// handled by the server or the client based on the advertised compressors. +func validateSendCompressor(name, clientCompressors string) error { + if name == encoding.Identity { + return nil + } + + if !grpcutil.IsCompressorNameRegistered(name) { + return fmt.Errorf("compressor not registered %q", name) + } + + for _, c := range strings.Split(clientCompressors, ",") { + if c == name { + return nil // found match + } + } + return fmt.Errorf("client does not support compressor %q", name) +} diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 01bbb2025ae..0df11fc0988 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -23,8 +23,6 @@ import ( "errors" "fmt" "reflect" - "strconv" - "strings" "time" "google.golang.org/grpc/codes" @@ -106,8 +104,8 @@ type healthCheckConfig struct { type jsonRetryPolicy struct { MaxAttempts int - InitialBackoff string - MaxBackoff string + InitialBackoff internalserviceconfig.Duration + MaxBackoff internalserviceconfig.Duration BackoffMultiplier float64 RetryableStatusCodes []codes.Code } @@ -129,50 +127,6 @@ type retryThrottlingPolicy struct { TokenRatio float64 } -func parseDuration(s *string) (*time.Duration, error) { - if s == nil { - return nil, nil - } - if !strings.HasSuffix(*s, "s") { - return nil, fmt.Errorf("malformed duration %q", *s) - } - ss := strings.SplitN((*s)[:len(*s)-1], ".", 3) - if len(ss) > 2 { - return nil, fmt.Errorf("malformed duration %q", *s) - } - // hasDigits is set if either the whole or fractional part of the number is - // present, since both are optional but one is required. - hasDigits := false - var d time.Duration - if len(ss[0]) > 0 { - i, err := strconv.ParseInt(ss[0], 10, 32) - if err != nil { - return nil, fmt.Errorf("malformed duration %q: %v", *s, err) - } - d = time.Duration(i) * time.Second - hasDigits = true - } - if len(ss) == 2 && len(ss[1]) > 0 { - if len(ss[1]) > 9 { - return nil, fmt.Errorf("malformed duration %q", *s) - } - f, err := strconv.ParseInt(ss[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("malformed duration %q: %v", *s, err) - } - for i := 9; i > len(ss[1]); i-- { - f *= 10 - } - d += time.Duration(f) - hasDigits = true - } - if !hasDigits { - return nil, fmt.Errorf("malformed duration %q", *s) - } - - return &d, nil -} - type jsonName struct { Service string Method string @@ -201,7 +155,7 @@ func (j jsonName) generatePath() (string, error) { type jsonMC struct { Name *[]jsonName WaitForReady *bool - Timeout *string + Timeout *internalserviceconfig.Duration MaxRequestMessageBytes *int64 MaxResponseMessageBytes *int64 RetryPolicy *jsonRetryPolicy @@ -226,7 +180,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { var rsc jsonSC err := json.Unmarshal([]byte(js), &rsc) if err != nil { - logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) + logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } sc := ServiceConfig{ @@ -252,18 +206,13 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { if m.Name == nil { continue } - d, err := parseDuration(m.Timeout) - if err != nil { - logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return &serviceconfig.ParseResult{Err: err} - } mc := MethodConfig{ WaitForReady: m.WaitForReady, - Timeout: d, + Timeout: (*time.Duration)(m.Timeout), } if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { - logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) + logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } if m.MaxRequestMessageBytes != nil { @@ -283,13 +232,13 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { for i, n := range *m.Name { path, err := n.generatePath() if err != nil { - logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } if _, ok := paths[path]; ok { err = errDuplicatedName - logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } paths[path] = struct{}{} @@ -312,18 +261,10 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol if jrp == nil { return nil, nil } - ib, err := parseDuration(&jrp.InitialBackoff) - if err != nil { - return nil, err - } - mb, err := parseDuration(&jrp.MaxBackoff) - if err != nil { - return nil, err - } if jrp.MaxAttempts <= 1 || - *ib <= 0 || - *mb <= 0 || + jrp.InitialBackoff <= 0 || + jrp.MaxBackoff <= 0 || jrp.BackoffMultiplier <= 0 || len(jrp.RetryableStatusCodes) == 0 { logger.Warningf("grpc: ignoring retry policy %v due to illegal configuration", jrp) @@ -332,8 +273,8 @@ func convertRetryPolicy(jrp *jsonRetryPolicy) (p *internalserviceconfig.RetryPol rp := &internalserviceconfig.RetryPolicy{ MaxAttempts: jrp.MaxAttempts, - InitialBackoff: *ib, - MaxBackoff: *mb, + InitialBackoff: time.Duration(jrp.InitialBackoff), + MaxBackoff: time.Duration(jrp.MaxBackoff), BackoffMultiplier: jrp.BackoffMultiplier, RetryableStatusCodes: make(map[codes.Code]bool), } diff --git a/vendor/google.golang.org/grpc/shared_buffer_pool.go b/vendor/google.golang.org/grpc/shared_buffer_pool.go new file mode 100644 index 00000000000..48a64cfe8e2 --- /dev/null +++ b/vendor/google.golang.org/grpc/shared_buffer_pool.go @@ -0,0 +1,154 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpc + +import "sync" + +// SharedBufferPool is a pool of buffers that can be shared, resulting in +// decreased memory allocation. Currently, in gRPC-go, it is only utilized +// for parsing incoming messages. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +type SharedBufferPool interface { + // Get returns a buffer with specified length from the pool. + // + // The returned byte slice may be not zero initialized. + Get(length int) []byte + + // Put returns a buffer to the pool. + Put(*[]byte) +} + +// NewSharedBufferPool creates a simple SharedBufferPool with buckets +// of different sizes to optimize memory usage. This prevents the pool from +// wasting large amounts of memory, even when handling messages of varying sizes. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func NewSharedBufferPool() SharedBufferPool { + return &simpleSharedBufferPool{ + pools: [poolArraySize]simpleSharedBufferChildPool{ + newBytesPool(level0PoolMaxSize), + newBytesPool(level1PoolMaxSize), + newBytesPool(level2PoolMaxSize), + newBytesPool(level3PoolMaxSize), + newBytesPool(level4PoolMaxSize), + newBytesPool(0), + }, + } +} + +// simpleSharedBufferPool is a simple implementation of SharedBufferPool. +type simpleSharedBufferPool struct { + pools [poolArraySize]simpleSharedBufferChildPool +} + +func (p *simpleSharedBufferPool) Get(size int) []byte { + return p.pools[p.poolIdx(size)].Get(size) +} + +func (p *simpleSharedBufferPool) Put(bs *[]byte) { + p.pools[p.poolIdx(cap(*bs))].Put(bs) +} + +func (p *simpleSharedBufferPool) poolIdx(size int) int { + switch { + case size <= level0PoolMaxSize: + return level0PoolIdx + case size <= level1PoolMaxSize: + return level1PoolIdx + case size <= level2PoolMaxSize: + return level2PoolIdx + case size <= level3PoolMaxSize: + return level3PoolIdx + case size <= level4PoolMaxSize: + return level4PoolIdx + default: + return levelMaxPoolIdx + } +} + +const ( + level0PoolMaxSize = 16 // 16 B + level1PoolMaxSize = level0PoolMaxSize * 16 // 256 B + level2PoolMaxSize = level1PoolMaxSize * 16 // 4 KB + level3PoolMaxSize = level2PoolMaxSize * 16 // 64 KB + level4PoolMaxSize = level3PoolMaxSize * 16 // 1 MB +) + +const ( + level0PoolIdx = iota + level1PoolIdx + level2PoolIdx + level3PoolIdx + level4PoolIdx + levelMaxPoolIdx + poolArraySize +) + +type simpleSharedBufferChildPool interface { + Get(size int) []byte + Put(any) +} + +type bufferPool struct { + sync.Pool + + defaultSize int +} + +func (p *bufferPool) Get(size int) []byte { + bs := p.Pool.Get().(*[]byte) + + if cap(*bs) < size { + p.Pool.Put(bs) + + return make([]byte, size) + } + + return (*bs)[:size] +} + +func newBytesPool(size int) simpleSharedBufferChildPool { + return &bufferPool{ + Pool: sync.Pool{ + New: func() any { + bs := make([]byte, size) + return &bs + }, + }, + defaultSize: size, + } +} + +// nopBufferPool is a buffer pool just makes new buffer without pooling. +type nopBufferPool struct { +} + +func (nopBufferPool) Get(length int) []byte { + return make([]byte, length) +} + +func (nopBufferPool) Put(*[]byte) { +} diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 0285dcc6a26..4ab70e2d462 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -59,18 +59,36 @@ func (s *Begin) IsClient() bool { return s.Client } func (s *Begin) isRPCStats() {} +// PickerUpdated indicates that the LB policy provided a new picker while the +// RPC was waiting for one. +type PickerUpdated struct{} + +// IsClient indicates if the stats information is from client side. Only Client +// Side interfaces with a Picker, thus always returns true. +func (*PickerUpdated) IsClient() bool { return true } + +func (*PickerUpdated) isRPCStats() {} + // InPayload contains the information for an incoming payload. type InPayload struct { // Client is true if this InPayload is from client side. Client bool // Payload is the payload with original type. - Payload interface{} + Payload any // Data is the serialized message payload. Data []byte - // Length is the length of uncompressed data. + + // Length is the size of the uncompressed payload data. Does not include any + // framing (gRPC or HTTP/2). Length int - // WireLength is the length of data on wire (compressed, signed, encrypted). + // CompressedLength is the size of the compressed payload data. Does not + // include any framing (gRPC or HTTP/2). Same as Length if compression not + // enabled. + CompressedLength int + // WireLength is the size of the compressed payload data plus gRPC framing. + // Does not include HTTP/2 framing. WireLength int + // RecvTime is the time when the payload is received. RecvTime time.Time } @@ -126,12 +144,18 @@ type OutPayload struct { // Client is true if this OutPayload is from client side. Client bool // Payload is the payload with original type. - Payload interface{} + Payload any // Data is the serialized message payload. Data []byte - // Length is the length of uncompressed data. + // Length is the size of the uncompressed payload data. Does not include any + // framing (gRPC or HTTP/2). Length int - // WireLength is the length of data on wire (compressed, signed, encrypted). + // CompressedLength is the size of the compressed payload data. Does not + // include any framing (gRPC or HTTP/2). Same as Length if compression not + // enabled. + CompressedLength int + // WireLength is the size of the compressed payload data plus gRPC framing. + // Does not include HTTP/2 framing. WireLength int // SentTime is the time when the payload is sent. SentTime time.Time diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go index 623be39f26b..a93360efb84 100644 --- a/vendor/google.golang.org/grpc/status/status.go +++ b/vendor/google.golang.org/grpc/status/status.go @@ -50,7 +50,7 @@ func New(c codes.Code, msg string) *Status { } // Newf returns New(c, fmt.Sprintf(format, a...)). -func Newf(c codes.Code, format string, a ...interface{}) *Status { +func Newf(c codes.Code, format string, a ...any) *Status { return New(c, fmt.Sprintf(format, a...)) } @@ -60,7 +60,7 @@ func Error(c codes.Code, msg string) error { } // Errorf returns Error(c, fmt.Sprintf(format, a...)). -func Errorf(c codes.Code, format string, a ...interface{}) error { +func Errorf(c codes.Code, format string, a ...any) error { return Error(c, fmt.Sprintf(format, a...)) } @@ -77,9 +77,18 @@ func FromProto(s *spb.Status) *Status { // FromError returns a Status representation of err. // // - If err was produced by this package or implements the method `GRPCStatus() -// *Status`, the appropriate Status is returned. +// *Status` and `GRPCStatus()` does not return nil, or if err wraps a type +// satisfying this, the Status from `GRPCStatus()` is returned. For wrapped +// errors, the message returned contains the entire err.Error() text and not +// just the wrapped status. In that case, ok is true. // -// - If err is nil, a Status is returned with codes.OK and no message. +// - If err is nil, a Status is returned with codes.OK and no message, and ok +// is true. +// +// - If err implements the method `GRPCStatus() *Status` and `GRPCStatus()` +// returns nil (which maps to Codes.OK), or if err wraps a type +// satisfying this, a Status is returned with codes.Unknown and err's +// Error() message, and ok is false. // // - Otherwise, err is an error not compatible with this package. In this // case, a Status is returned with codes.Unknown and err's Error() message, @@ -88,10 +97,31 @@ func FromError(err error) (s *Status, ok bool) { if err == nil { return nil, true } - if se, ok := err.(interface { - GRPCStatus() *Status - }); ok { - return se.GRPCStatus(), true + type grpcstatus interface{ GRPCStatus() *Status } + if gs, ok := err.(grpcstatus); ok { + grpcStatus := gs.GRPCStatus() + if grpcStatus == nil { + // Error has status nil, which maps to codes.OK. There + // is no sensible behavior for this, so we turn it into + // an error with codes.Unknown and discard the existing + // status. + return New(codes.Unknown, err.Error()), false + } + return grpcStatus, true + } + var gs grpcstatus + if errors.As(err, &gs) { + grpcStatus := gs.GRPCStatus() + if grpcStatus == nil { + // Error wraps an error that has status nil, which maps + // to codes.OK. There is no sensible behavior for this, + // so we turn it into an error with codes.Unknown and + // discard the existing status. + return New(codes.Unknown, err.Error()), false + } + p := grpcStatus.Proto() + p.Message = err.Error() + return status.FromProto(p), true } return New(codes.Unknown, err.Error()), false } @@ -103,19 +133,16 @@ func Convert(err error) *Status { return s } -// Code returns the Code of the error if it is a Status error, codes.OK if err -// is nil, or codes.Unknown otherwise. +// Code returns the Code of the error if it is a Status error or if it wraps a +// Status error. If that is not the case, it returns codes.OK if err is nil, or +// codes.Unknown otherwise. func Code(err error) codes.Code { // Don't use FromError to avoid allocation of OK status. if err == nil { return codes.OK } - if se, ok := err.(interface { - GRPCStatus() *Status - }); ok { - return se.GRPCStatus().Code() - } - return codes.Unknown + + return Convert(err).Code() } // FromContextError converts a context error or wrapped context error into a diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 960c3e33dfd..b14b2fbea2e 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -31,6 +31,7 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/encoding" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/balancerload" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" @@ -54,7 +55,7 @@ import ( // status package, or be one of the context errors. Otherwise, gRPC will use // codes.Unknown as the status code and err.Error() as the status message of the // RPC. -type StreamHandler func(srv interface{}, stream ServerStream) error +type StreamHandler func(srv any, stream ServerStream) error // StreamDesc represents a streaming RPC service's method specification. Used // on the server when registering services and on the client when initiating @@ -79,9 +80,9 @@ type Stream interface { // Deprecated: See ClientStream and ServerStream documentation instead. Context() context.Context // Deprecated: See ClientStream and ServerStream documentation instead. - SendMsg(m interface{}) error + SendMsg(m any) error // Deprecated: See ClientStream and ServerStream documentation instead. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // ClientStream defines the client-side behavior of a streaming RPC. @@ -90,7 +91,9 @@ type Stream interface { // status package. type ClientStream interface { // Header returns the header metadata received from the server if there - // is any. It blocks if the metadata is not ready to read. + // is any. It blocks if the metadata is not ready to read. If the metadata + // is nil and the error is also nil, then the stream was terminated without + // headers, and the status can be discovered by calling RecvMsg. Header() (metadata.MD, error) // Trailer returns the trailer metadata from the server, if there is any. // It must only be called after stream.CloseAndRecv has returned, or @@ -123,7 +126,10 @@ type ClientStream interface { // calling RecvMsg on the same stream at the same time, but it is not safe // to call SendMsg on the same stream in different goroutines. It is also // not safe to call CloseSend concurrently with SendMsg. - SendMsg(m interface{}) error + // + // It is not safe to modify the message after calling SendMsg. Tracing + // libraries and stats handlers may use the message lazily. + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the stream completes successfully. On // any other error, the stream is aborted and the error contains the RPC @@ -132,7 +138,7 @@ type ClientStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // NewStream creates a new Stream for the client side. This is typically @@ -168,10 +174,29 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { - if md, _, ok := metadata.FromOutgoingContextRaw(ctx); ok { + // Start tracking the RPC for idleness purposes. This is where a stream is + // created for both streaming and unary RPCs, and hence is a good place to + // track active RPC count. + if err := cc.idlenessMgr.OnCallBegin(); err != nil { + return nil, err + } + // Add a calloption, to decrement the active call count, that gets executed + // when the RPC completes. + opts = append([]CallOption{OnFinish(func(error) { cc.idlenessMgr.OnCallEnd() })}, opts...) + + if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok { + // validate md if err := imetadata.Validate(md); err != nil { return nil, status.Error(codes.Internal, err.Error()) } + // validate added + for _, kvs := range added { + for i := 0; i < len(kvs); i += 2 { + if err := imetadata.ValidatePair(kvs[i], kvs[i+1]); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + } + } } if channelz.IsOn() { cc.incrCallsStarted() @@ -352,7 +377,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client } } for _, binlog := range cs.binlogs { - binlog.Log(logEntry) + binlog.Log(cs.ctx, logEntry) } } @@ -416,7 +441,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error) ctx = trace.NewContext(ctx, trInfo.tr) } - if cs.cc.parsedTarget.Scheme == "xds" { + if cs.cc.parsedTarget.URL.Scheme == internal.GRPCResolverSchemeExtraMetadata { // Add extra metadata (metadata that will be added by transport) to context // so the balancer can see them. ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs( @@ -438,7 +463,7 @@ func (a *csAttempt) getTransport() error { cs := a.cs var err error - a.t, a.done, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method) + a.t, a.pickResult, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method) if err != nil { if de, ok := err.(dropError); ok { err = de.error @@ -455,6 +480,25 @@ func (a *csAttempt) getTransport() error { func (a *csAttempt) newStream() error { cs := a.cs cs.callHdr.PreviousAttempts = cs.numRetries + + // Merge metadata stored in PickResult, if any, with existing call metadata. + // It is safe to overwrite the csAttempt's context here, since all state + // maintained in it are local to the attempt. When the attempt has to be + // retried, a new instance of csAttempt will be created. + if a.pickResult.Metadata != nil { + // We currently do not have a function it the metadata package which + // merges given metadata with existing metadata in a context. Existing + // function `AppendToOutgoingContext()` takes a variadic argument of key + // value pairs. + // + // TODO: Make it possible to retrieve key value pairs from metadata.MD + // in a form passable to AppendToOutgoingContext(), or create a version + // of AppendToOutgoingContext() that accepts a metadata.MD. + md, _ := metadata.FromOutgoingContext(a.ctx) + md = metadata.Join(md, a.pickResult.Metadata) + a.ctx = metadata.NewOutgoingContext(a.ctx, md) + } + s, err := a.t.NewStream(a.ctx, cs.callHdr) if err != nil { nse, ok := err.(*transport.NewStreamError) @@ -471,7 +515,7 @@ func (a *csAttempt) newStream() error { return toRPCErr(nse.Err) } a.s = s - a.p = &parser{r: s} + a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool} return nil } @@ -529,12 +573,12 @@ type clientStream struct { // csAttempt implements a single transport stream attempt within a // clientStream. type csAttempt struct { - ctx context.Context - cs *clientStream - t transport.ClientTransport - s *transport.Stream - p *parser - done func(balancer.DoneInfo) + ctx context.Context + cs *clientStream + t transport.ClientTransport + s *transport.Stream + p *parser + pickResult balancer.PickResult finished bool dc Decompressor @@ -752,23 +796,24 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func()) func (cs *clientStream) Header() (metadata.MD, error) { var m metadata.MD - noHeader := false err := cs.withRetry(func(a *csAttempt) error { var err error m, err = a.s.Header() - if err == transport.ErrNoHeaders { - noHeader = true - return nil - } return toRPCErr(err) }, cs.commitAttemptLocked) + if m == nil && err == nil { + // The stream ended with success. Finish the clientStream. + err = io.EOF + } + if err != nil { cs.finish(err) - return nil, err + // Do not return the error. The user should get it by calling Recv(). + return nil, nil } - if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && !noHeader { + if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged && m != nil { // Only log if binary log is on and header has not been logged, and // there is actually headers to log. logEntry := &binarylog.ServerHeader{ @@ -781,9 +826,10 @@ func (cs *clientStream) Header() (metadata.MD, error) { } cs.serverHeaderBinlogged = true for _, binlog := range cs.binlogs { - binlog.Log(logEntry) + binlog.Log(cs.ctx, logEntry) } } + return m, nil } @@ -824,7 +870,7 @@ func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error cs.buffer = append(cs.buffer, op) } -func (cs *clientStream) SendMsg(m interface{}) (err error) { +func (cs *clientStream) SendMsg(m any) (err error) { defer func() { if err != nil && err != io.EOF { // Call finish on the client stream for errors generated by this SendMsg @@ -862,13 +908,13 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { Message: data, } for _, binlog := range cs.binlogs { - binlog.Log(cm) + binlog.Log(cs.ctx, cm) } } return err } -func (cs *clientStream) RecvMsg(m interface{}) error { +func (cs *clientStream) RecvMsg(m any) error { if len(cs.binlogs) != 0 && !cs.serverHeaderBinlogged { // Call Header() to binary log header if it's not already logged. cs.Header() @@ -886,30 +932,12 @@ func (cs *clientStream) RecvMsg(m interface{}) error { Message: recvInfo.uncompressedBytes, } for _, binlog := range cs.binlogs { - binlog.Log(sm) + binlog.Log(cs.ctx, sm) } } if err != nil || !cs.desc.ServerStreams { // err != nil or non-server-streaming indicates end of stream. cs.finish(err) - - if len(cs.binlogs) != 0 { - // finish will not log Trailer. Log Trailer here. - logEntry := &binarylog.ServerTrailer{ - OnClientSide: true, - Trailer: cs.Trailer(), - Err: err, - } - if logEntry.Err == io.EOF { - logEntry.Err = nil - } - if peer, ok := peer.FromContext(cs.Context()); ok { - logEntry.PeerAddr = peer.Addr - } - for _, binlog := range cs.binlogs { - binlog.Log(logEntry) - } - } } return err } @@ -934,7 +962,7 @@ func (cs *clientStream) CloseSend() error { OnClientSide: true, } for _, binlog := range cs.binlogs { - binlog.Log(chc) + binlog.Log(cs.ctx, chc) } } // We never returned an error here for reasons. @@ -952,6 +980,9 @@ func (cs *clientStream) finish(err error) { return } cs.finished = true + for _, onFinish := range cs.callInfo.onFinish { + onFinish(err) + } cs.commitAttemptLocked() if cs.attempt != nil { cs.attempt.finish(err) @@ -962,18 +993,30 @@ func (cs *clientStream) finish(err error) { } } } + cs.mu.Unlock() - // For binary logging. only log cancel in finish (could be caused by RPC ctx - // canceled or ClientConn closed). Trailer will be logged in RecvMsg. - // - // Only one of cancel or trailer needs to be logged. In the cases where - // users don't call RecvMsg, users must have already canceled the RPC. - if len(cs.binlogs) != 0 && status.Code(err) == codes.Canceled { - c := &binarylog.Cancel{ - OnClientSide: true, - } - for _, binlog := range cs.binlogs { - binlog.Log(c) + // Only one of cancel or trailer needs to be logged. + if len(cs.binlogs) != 0 { + switch err { + case errContextCanceled, errContextDeadline, ErrClientConnClosing: + c := &binarylog.Cancel{ + OnClientSide: true, + } + for _, binlog := range cs.binlogs { + binlog.Log(cs.ctx, c) + } + default: + logEntry := &binarylog.ServerTrailer{ + OnClientSide: true, + Trailer: cs.Trailer(), + Err: err, + } + if peer, ok := peer.FromContext(cs.Context()); ok { + logEntry.PeerAddr = peer.Addr + } + for _, binlog := range cs.binlogs { + binlog.Log(cs.ctx, logEntry) + } } } if err == nil { @@ -989,7 +1032,7 @@ func (cs *clientStream) finish(err error) { cs.cancel() } -func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { +func (a *csAttempt) sendMsg(m any, hdr, payld, data []byte) error { cs := a.cs if a.trInfo != nil { a.mu.Lock() @@ -1016,7 +1059,7 @@ func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { return nil } -func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { +func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { cs := a.cs if len(a.statsHandlers) != 0 && payInfo == nil { payInfo = &payloadInfo{} @@ -1062,9 +1105,10 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { RecvTime: time.Now(), Payload: m, // TODO truncate large payload. - Data: payInfo.uncompressedBytes, - WireLength: payInfo.wireLength + headerLen, - Length: len(payInfo.uncompressedBytes), + Data: payInfo.uncompressedBytes, + WireLength: payInfo.compressedLength + headerLen, + CompressedLength: payInfo.compressedLength, + Length: len(payInfo.uncompressedBytes), }) } if channelz.IsOn() { @@ -1103,12 +1147,12 @@ func (a *csAttempt) finish(err error) { tr = a.s.Trailer() } - if a.done != nil { + if a.pickResult.Done != nil { br := false if a.s != nil { br = a.s.BytesReceived() } - a.done(balancer.DoneInfo{ + a.pickResult.Done(balancer.DoneInfo{ Err: err, Trailer: tr, BytesSent: a.s != nil, @@ -1230,17 +1274,22 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin return nil, err } as.s = s - as.p = &parser{r: s} + as.p = &parser{r: s, recvBufferPool: ac.dopts.recvBufferPool} ac.incrCallsStarted() if desc != unaryStreamDesc { - // Listen on cc and stream contexts to cleanup when the user closes the - // ClientConn or cancels the stream context. In all other cases, an error - // should already be injected into the recv buffer by the transport, which - // the client will eventually receive, and then we will cancel the stream's - // context in clientStream.finish. + // Listen on stream context to cleanup when the stream context is + // canceled. Also listen for the addrConn's context in case the + // addrConn is closed or reconnects to a different address. In all + // other cases, an error should already be injected into the recv + // buffer by the transport, which the client will eventually receive, + // and then we will cancel the stream's context in + // addrConnStream.finish. go func() { + ac.mu.Lock() + acCtx := ac.ctx + ac.mu.Unlock() select { - case <-ac.ctx.Done(): + case <-acCtx.Done(): as.finish(status.Error(codes.Canceled, "grpc: the SubConn is closing")) case <-ctx.Done(): as.finish(toRPCErr(ctx.Err())) @@ -1303,7 +1352,7 @@ func (as *addrConnStream) Context() context.Context { return as.s.Context() } -func (as *addrConnStream) SendMsg(m interface{}) (err error) { +func (as *addrConnStream) SendMsg(m any) (err error) { defer func() { if err != nil && err != io.EOF { // Call finish on the client stream for errors generated by this SendMsg @@ -1348,7 +1397,7 @@ func (as *addrConnStream) SendMsg(m interface{}) (err error) { return nil } -func (as *addrConnStream) RecvMsg(m interface{}) (err error) { +func (as *addrConnStream) RecvMsg(m any) (err error) { defer func() { if err != nil || !as.desc.ServerStreams { // err != nil or non-server-streaming indicates end of stream. @@ -1464,7 +1513,10 @@ type ServerStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not safe // to call SendMsg on the same stream in different goroutines. - SendMsg(m interface{}) error + // + // It is not safe to modify the message after calling SendMsg. Tracing + // libraries and stats handlers may use the message lazily. + SendMsg(m any) error // RecvMsg blocks until it receives a message into m or the stream is // done. It returns io.EOF when the client has performed a CloseSend. On // any non-EOF error, the stream is aborted and the error contains the @@ -1473,7 +1525,7 @@ type ServerStream interface { // It is safe to have a goroutine calling SendMsg and another goroutine // calling RecvMsg on the same stream at the same time, but it is not // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m interface{}) error + RecvMsg(m any) error } // serverStream implements a server side Stream. @@ -1489,6 +1541,8 @@ type serverStream struct { comp encoding.Compressor decomp encoding.Compressor + sendCompressorName string + maxReceiveMessageSize int maxSendMessageSize int trInfo *traceInfo @@ -1536,7 +1590,7 @@ func (ss *serverStream) SendHeader(md metadata.MD) error { } ss.serverHeaderBinlogged = true for _, binlog := range ss.binlogs { - binlog.Log(sh) + binlog.Log(ss.ctx, sh) } } return err @@ -1552,7 +1606,7 @@ func (ss *serverStream) SetTrailer(md metadata.MD) { ss.s.SetTrailer(md) } -func (ss *serverStream) SendMsg(m interface{}) (err error) { +func (ss *serverStream) SendMsg(m any) (err error) { defer func() { if ss.trInfo != nil { ss.mu.Lock() @@ -1560,7 +1614,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err == nil { ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) } else { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } } @@ -1581,6 +1635,13 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { } }() + // Server handler could have set new compressor by calling SetSendCompressor. + // In case it is set, we need to use it for compressing outbound message. + if sendCompressorsName := ss.s.SendCompress(); sendCompressorsName != ss.sendCompressorName { + ss.comp = encoding.GetCompressor(sendCompressorsName) + ss.sendCompressorName = sendCompressorsName + } + // load hdr, payload, data hdr, payload, data, err := prepareMsg(m, ss.codec, ss.cp, ss.comp) if err != nil { @@ -1602,14 +1663,14 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { } ss.serverHeaderBinlogged = true for _, binlog := range ss.binlogs { - binlog.Log(sh) + binlog.Log(ss.ctx, sh) } } sm := &binarylog.ServerMessage{ Message: data, } for _, binlog := range ss.binlogs { - binlog.Log(sm) + binlog.Log(ss.ctx, sm) } } if len(ss.statsHandler) != 0 { @@ -1620,7 +1681,7 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { return nil } -func (ss *serverStream) RecvMsg(m interface{}) (err error) { +func (ss *serverStream) RecvMsg(m any) (err error) { defer func() { if ss.trInfo != nil { ss.mu.Lock() @@ -1628,7 +1689,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { if err == nil { ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) } else if err != io.EOF { - ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ss.trInfo.tr.SetError() } } @@ -1657,7 +1718,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { if len(ss.binlogs) != 0 { chc := &binarylog.ClientHalfClose{} for _, binlog := range ss.binlogs { - binlog.Log(chc) + binlog.Log(ss.ctx, chc) } } return err @@ -1673,9 +1734,10 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { RecvTime: time.Now(), Payload: m, // TODO truncate large payload. - Data: payInfo.uncompressedBytes, - WireLength: payInfo.wireLength + headerLen, - Length: len(payInfo.uncompressedBytes), + Data: payInfo.uncompressedBytes, + Length: len(payInfo.uncompressedBytes), + WireLength: payInfo.compressedLength + headerLen, + CompressedLength: payInfo.compressedLength, }) } } @@ -1684,7 +1746,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { Message: payInfo.uncompressedBytes, } for _, binlog := range ss.binlogs { - binlog.Log(cm) + binlog.Log(ss.ctx, cm) } } return nil @@ -1699,7 +1761,7 @@ func MethodFromServerStream(stream ServerStream) (string, bool) { // prepareMsg returns the hdr, payload and data // using the compressors passed or using the // passed preparedmsg -func prepareMsg(m interface{}, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) { +func prepareMsg(m any, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) { if preparedMsg, ok := m.(*PreparedMsg); ok { return preparedMsg.hdr, preparedMsg.payload, preparedMsg.encodedData, nil } diff --git a/vendor/google.golang.org/grpc/test/bufconn/bufconn.go b/vendor/google.golang.org/grpc/test/bufconn/bufconn.go new file mode 100644 index 00000000000..3f77f4876eb --- /dev/null +++ b/vendor/google.golang.org/grpc/test/bufconn/bufconn.go @@ -0,0 +1,318 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package bufconn provides a net.Conn implemented by a buffer and related +// dialing and listening functionality. +package bufconn + +import ( + "context" + "fmt" + "io" + "net" + "sync" + "time" +) + +// Listener implements a net.Listener that creates local, buffered net.Conns +// via its Accept and Dial method. +type Listener struct { + mu sync.Mutex + sz int + ch chan net.Conn + done chan struct{} +} + +// Implementation of net.Error providing timeout +type netErrorTimeout struct { + error +} + +func (e netErrorTimeout) Timeout() bool { return true } +func (e netErrorTimeout) Temporary() bool { return false } + +var errClosed = fmt.Errorf("closed") +var errTimeout net.Error = netErrorTimeout{error: fmt.Errorf("i/o timeout")} + +// Listen returns a Listener that can only be contacted by its own Dialers and +// creates buffered connections between the two. +func Listen(sz int) *Listener { + return &Listener{sz: sz, ch: make(chan net.Conn), done: make(chan struct{})} +} + +// Accept blocks until Dial is called, then returns a net.Conn for the server +// half of the connection. +func (l *Listener) Accept() (net.Conn, error) { + select { + case <-l.done: + return nil, errClosed + case c := <-l.ch: + return c, nil + } +} + +// Close stops the listener. +func (l *Listener) Close() error { + l.mu.Lock() + defer l.mu.Unlock() + select { + case <-l.done: + // Already closed. + break + default: + close(l.done) + } + return nil +} + +// Addr reports the address of the listener. +func (l *Listener) Addr() net.Addr { return addr{} } + +// Dial creates an in-memory full-duplex network connection, unblocks Accept by +// providing it the server half of the connection, and returns the client half +// of the connection. +func (l *Listener) Dial() (net.Conn, error) { + return l.DialContext(context.Background()) +} + +// DialContext creates an in-memory full-duplex network connection, unblocks Accept by +// providing it the server half of the connection, and returns the client half +// of the connection. If ctx is Done, returns ctx.Err() +func (l *Listener) DialContext(ctx context.Context) (net.Conn, error) { + p1, p2 := newPipe(l.sz), newPipe(l.sz) + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-l.done: + return nil, errClosed + case l.ch <- &conn{p1, p2}: + return &conn{p2, p1}, nil + } +} + +type pipe struct { + mu sync.Mutex + + // buf contains the data in the pipe. It is a ring buffer of fixed capacity, + // with r and w pointing to the offset to read and write, respsectively. + // + // Data is read between [r, w) and written to [w, r), wrapping around the end + // of the slice if necessary. + // + // The buffer is empty if r == len(buf), otherwise if r == w, it is full. + // + // w and r are always in the range [0, cap(buf)) and [0, len(buf)]. + buf []byte + w, r int + + wwait sync.Cond + rwait sync.Cond + + // Indicate that a write/read timeout has occurred + wtimedout bool + rtimedout bool + + wtimer *time.Timer + rtimer *time.Timer + + closed bool + writeClosed bool +} + +func newPipe(sz int) *pipe { + p := &pipe{buf: make([]byte, 0, sz)} + p.wwait.L = &p.mu + p.rwait.L = &p.mu + + p.wtimer = time.AfterFunc(0, func() {}) + p.rtimer = time.AfterFunc(0, func() {}) + return p +} + +func (p *pipe) empty() bool { + return p.r == len(p.buf) +} + +func (p *pipe) full() bool { + return p.r < len(p.buf) && p.r == p.w +} + +func (p *pipe) Read(b []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + // Block until p has data. + for { + if p.closed { + return 0, io.ErrClosedPipe + } + if !p.empty() { + break + } + if p.writeClosed { + return 0, io.EOF + } + if p.rtimedout { + return 0, errTimeout + } + + p.rwait.Wait() + } + wasFull := p.full() + + n = copy(b, p.buf[p.r:len(p.buf)]) + p.r += n + if p.r == cap(p.buf) { + p.r = 0 + p.buf = p.buf[:p.w] + } + + // Signal a blocked writer, if any + if wasFull { + p.wwait.Signal() + } + + return n, nil +} + +func (p *pipe) Write(b []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + if p.closed { + return 0, io.ErrClosedPipe + } + for len(b) > 0 { + // Block until p is not full. + for { + if p.closed || p.writeClosed { + return 0, io.ErrClosedPipe + } + if !p.full() { + break + } + if p.wtimedout { + return 0, errTimeout + } + + p.wwait.Wait() + } + wasEmpty := p.empty() + + end := cap(p.buf) + if p.w < p.r { + end = p.r + } + x := copy(p.buf[p.w:end], b) + b = b[x:] + n += x + p.w += x + if p.w > len(p.buf) { + p.buf = p.buf[:p.w] + } + if p.w == cap(p.buf) { + p.w = 0 + } + + // Signal a blocked reader, if any. + if wasEmpty { + p.rwait.Signal() + } + } + return n, nil +} + +func (p *pipe) Close() error { + p.mu.Lock() + defer p.mu.Unlock() + p.closed = true + // Signal all blocked readers and writers to return an error. + p.rwait.Broadcast() + p.wwait.Broadcast() + return nil +} + +func (p *pipe) closeWrite() error { + p.mu.Lock() + defer p.mu.Unlock() + p.writeClosed = true + // Signal all blocked readers and writers to return an error. + p.rwait.Broadcast() + p.wwait.Broadcast() + return nil +} + +type conn struct { + io.Reader + io.Writer +} + +func (c *conn) Close() error { + err1 := c.Reader.(*pipe).Close() + err2 := c.Writer.(*pipe).closeWrite() + if err1 != nil { + return err1 + } + return err2 +} + +func (c *conn) SetDeadline(t time.Time) error { + c.SetReadDeadline(t) + c.SetWriteDeadline(t) + return nil +} + +func (c *conn) SetReadDeadline(t time.Time) error { + p := c.Reader.(*pipe) + p.mu.Lock() + defer p.mu.Unlock() + p.rtimer.Stop() + p.rtimedout = false + if !t.IsZero() { + p.rtimer = time.AfterFunc(time.Until(t), func() { + p.mu.Lock() + defer p.mu.Unlock() + p.rtimedout = true + p.rwait.Broadcast() + }) + } + return nil +} + +func (c *conn) SetWriteDeadline(t time.Time) error { + p := c.Writer.(*pipe) + p.mu.Lock() + defer p.mu.Unlock() + p.wtimer.Stop() + p.wtimedout = false + if !t.IsZero() { + p.wtimer = time.AfterFunc(time.Until(t), func() { + p.mu.Lock() + defer p.mu.Unlock() + p.wtimedout = true + p.wwait.Broadcast() + }) + } + return nil +} + +func (*conn) LocalAddr() net.Addr { return addr{} } +func (*conn) RemoteAddr() net.Addr { return addr{} } + +type addr struct{} + +func (addr) Network() string { return "bufconn" } +func (addr) String() string { return "bufconn" } diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index 07a2d26b3e7..9ded79321ba 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -97,8 +97,8 @@ func truncate(x string, l int) string { // payload represents an RPC request or response payload. type payload struct { - sent bool // whether this is an outgoing payload - msg interface{} // e.g. a proto.Message + sent bool // whether this is an outgoing payload + msg any // e.g. a proto.Message // TODO(dsymonds): add stringifying info to codec, and limit how much we hold here? } @@ -111,7 +111,7 @@ func (p payload) String() string { type fmtStringer struct { format string - a []interface{} + a []any } func (f *fmtStringer) String() string { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 2198e7098d7..d3f5bcbfcef 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.51.0" +const Version = "1.58.2" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index bd8e0cdb33c..bbc9e2e3c8e 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -41,16 +41,8 @@ if [[ "$1" = "-install" ]]; then github.com/client9/misspell/cmd/misspell popd if [[ -z "${VET_SKIP_PROTO}" ]]; then - if [[ "${TRAVIS}" = "true" ]]; then - PROTOBUF_VERSION=3.14.0 - PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip - pushd /home/travis - wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} - unzip ${PROTOC_FILENAME} - bin/protoc --version - popd - elif [[ "${GITHUB_ACTIONS}" = "true" ]]; then - PROTOBUF_VERSION=3.14.0 + if [[ "${GITHUB_ACTIONS}" = "true" ]]; then + PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files. PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip pushd /home/runner/go wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} @@ -66,6 +58,16 @@ elif [[ "$#" -ne 0 ]]; then die "Unknown argument(s): $*" fi +# - Check that generated proto files are up to date. +if [[ -z "${VET_SKIP_PROTO}" ]]; then + make proto && git status --porcelain 2>&1 | fail_on_output || \ + (git status; git --no-pager diff; exit 1) +fi + +if [[ -n "${VET_ONLY_PROTO}" ]]; then + exit 0 +fi + # - Ensure all source files contain a copyright message. # (Done in two parts because Darwin "git grep" has broken support for compound # exclusion matches.) @@ -82,6 +84,9 @@ not git grep -l 'x/net/context' -- "*.go" # thread safety. git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test' +# - Do not use "interface{}"; use "any" instead. +git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc' + # - Do not call grpclog directly. Use grpclog.Component instead. git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' @@ -93,13 +98,6 @@ git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*. misspell -error . -# - Check that generated proto files are up to date. -if [[ -z "${VET_SKIP_PROTO}" ]]; then - PATH="/home/travis/bin:${PATH}" make proto && \ - git status --porcelain 2>&1 | fail_on_output || \ - (git status; git --no-pager diff; exit 1) -fi - # - gofmt, goimports, golint (with exceptions for generated code), go vet, # go mod tidy. # Perform these checks on each module inside gRPC. @@ -111,7 +109,7 @@ for MOD_FILE in $(find . -name 'go.mod'); do goimports -l . 2>&1 | not grep -vE "\.pb\.go" golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:" - go mod tidy + go mod tidy -compat=1.19 git status --porcelain 2>&1 | fail_on_output || \ (git status; git --no-pager diff; exit 1) popd @@ -121,8 +119,9 @@ done # # TODO(dfawley): don't use deprecated functions in examples or first-party # plugins. +# TODO(dfawley): enable ST1019 (duplicate imports) but allow for protobufs. SC_OUT="$(mktemp)" -staticcheck -go 1.9 -checks 'inherit,-ST1015' ./... > "${SC_OUT}" || true +staticcheck -go 1.19 -checks 'inherit,-ST1015,-ST1019,-SA1019' ./... > "${SC_OUT}" || true # Error if anything other than deprecation warnings are printed. not grep -v "is deprecated:.*SA1019" "${SC_OUT}" # Only ignore the following deprecated types/fields/functions. @@ -172,8 +171,6 @@ proto.RegisteredExtension is deprecated proto.RegisteredExtensions is deprecated proto.RegisterMapType is deprecated proto.Unmarshaler is deprecated -resolver.Backend -resolver.GRPCLB Target is deprecated: Use the Target field in the BuildOptions instead. xxx_messageInfo_ ' "${SC_OUT}" diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/doc.go b/vendor/google.golang.org/protobuf/encoding/protojson/doc.go index 00ea2fecfb7..21d5d2cb18e 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/doc.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/doc.go @@ -4,7 +4,7 @@ // Package protojson marshals and unmarshals protocol buffer messages as JSON // format. It follows the guide at -// https://developers.google.com/protocol-buffers/docs/proto3#json. +// https://protobuf.dev/programming-guides/proto3#json. // // This package produces a different output than the standard "encoding/json" // package, which does not operate correctly on protocol buffer messages. diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go index d09d22e139b..66b95870e97 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/encode.go @@ -106,13 +106,19 @@ func (o MarshalOptions) Format(m proto.Message) string { // MarshalOptions. Do not depend on the output being stable. It may change over // time across different versions of the program. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) { - return o.marshal(m) + return o.marshal(nil, m) +} + +// MarshalAppend appends the JSON format encoding of m to b, +// returning the result. +func (o MarshalOptions) MarshalAppend(b []byte, m proto.Message) ([]byte, error) { + return o.marshal(b, m) } // marshal is a centralized function that all marshal operations go through. // For profiling purposes, avoid changing the name of this function or // introducing other code paths for marshal that do not go through this. -func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { +func (o MarshalOptions) marshal(b []byte, m proto.Message) ([]byte, error) { if o.Multiline && o.Indent == "" { o.Indent = defaultIndent } @@ -120,7 +126,7 @@ func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { o.Resolver = protoregistry.GlobalTypes } - internalEnc, err := json.NewEncoder(o.Indent) + internalEnc, err := json.NewEncoder(b, o.Indent) if err != nil { return nil, err } @@ -128,7 +134,7 @@ func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { // Treat nil message interface as an empty message, // in which case the output in an empty JSON object. if m == nil { - return []byte("{}"), nil + return append(b, '{', '}'), nil } enc := encoder{internalEnc, o} diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go index c85f8469480..6c37d417449 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go @@ -814,16 +814,22 @@ func (d decoder) unmarshalTimestamp(m protoreflect.Message) error { return d.unexpectedTokenError(tok) } - t, err := time.Parse(time.RFC3339Nano, tok.ParsedString()) + s := tok.ParsedString() + t, err := time.Parse(time.RFC3339Nano, s) if err != nil { return d.newError(tok.Pos(), "invalid %v value %v", genid.Timestamp_message_fullname, tok.RawString()) } - // Validate seconds. No need to validate nanos because time.Parse would have - // covered that already. + // Validate seconds. secs := t.Unix() if secs < minTimestampSeconds || secs > maxTimestampSeconds { return d.newError(tok.Pos(), "%v value out of range: %v", genid.Timestamp_message_fullname, tok.RawString()) } + // Validate subseconds. + i := strings.LastIndexByte(s, '.') // start of subsecond field + j := strings.LastIndexAny(s, "Z-+") // start of timezone field + if i >= 0 && j >= i && j-i > len(".999999999") { + return d.newError(tok.Pos(), "invalid %v value %v", genid.Timestamp_message_fullname, tok.RawString()) + } fds := m.Descriptor().Fields() fdSeconds := fds.ByNumber(genid.Timestamp_Seconds_field_number) diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go index ebf6c65284d..722a7b41df3 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go @@ -101,13 +101,19 @@ func (o MarshalOptions) Format(m proto.Message) string { // MarshalOptions object. Do not depend on the output being stable. It may // change over time across different versions of the program. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) { - return o.marshal(m) + return o.marshal(nil, m) +} + +// MarshalAppend appends the textproto format encoding of m to b, +// returning the result. +func (o MarshalOptions) MarshalAppend(b []byte, m proto.Message) ([]byte, error) { + return o.marshal(b, m) } // marshal is a centralized function that all marshal operations go through. // For profiling purposes, avoid changing the name of this function or // introducing other code paths for marshal that do not go through this. -func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { +func (o MarshalOptions) marshal(b []byte, m proto.Message) ([]byte, error) { var delims = [2]byte{'{', '}'} if o.Multiline && o.Indent == "" { @@ -117,7 +123,7 @@ func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { o.Resolver = protoregistry.GlobalTypes } - internalEnc, err := text.NewEncoder(o.Indent, delims, o.EmitASCII) + internalEnc, err := text.NewEncoder(b, o.Indent, delims, o.EmitASCII) if err != nil { return nil, err } @@ -125,7 +131,7 @@ func (o MarshalOptions) marshal(m proto.Message) ([]byte, error) { // Treat nil message interface as an empty message, // in which case there is nothing to output. if m == nil { - return []byte{}, nil + return b, nil } enc := encoder{internalEnc, o} diff --git a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go index ce57f57ebd4..f4b4686cf9d 100644 --- a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go +++ b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package protowire parses and formats the raw wire encoding. -// See https://developers.google.com/protocol-buffers/docs/encoding. +// See https://protobuf.dev/programming-guides/encoding. // // For marshaling and unmarshaling entire protobuf messages, // use the "google.golang.org/protobuf/proto" package instead. @@ -29,12 +29,8 @@ const ( ) // IsValid reports whether the field number is semantically valid. -// -// Note that while numbers within the reserved range are semantically invalid, -// they are syntactically valid in the wire format. -// Implementations may treat records with reserved field numbers as unknown. func (n Number) IsValid() bool { - return MinValidNumber <= n && n < FirstReservedNumber || LastReservedNumber < n && n <= MaxValidNumber + return MinValidNumber <= n && n <= MaxValidNumber } // Type represents the wire type. diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go index b13fd29e81e..d043a6ebe0b 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go @@ -294,7 +294,7 @@ func (d *Decoder) isValueNext() bool { } // consumeToken constructs a Token for given Kind with raw value derived from -// current d.in and given size, and consumes the given size-lenght of it. +// current d.in and given size, and consumes the given size-length of it. func (d *Decoder) consumeToken(kind Kind, size int) Token { tok := Token{ kind: kind, diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go index fbdf3487342..934f2dcb39d 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/json/encode.go @@ -41,8 +41,10 @@ type Encoder struct { // // If indent is a non-empty string, it causes every entry for an Array or Object // to be preceded by the indent and trailed by a newline. -func NewEncoder(indent string) (*Encoder, error) { - e := &Encoder{} +func NewEncoder(buf []byte, indent string) (*Encoder, error) { + e := &Encoder{ + out: buf, + } if len(indent) > 0 { if strings.Trim(indent, " \t") != "" { return nil, errors.New("indent may only be composed of space or tab characters") @@ -176,13 +178,13 @@ func appendFloat(out []byte, n float64, bitSize int) []byte { // WriteInt writes out the given signed integer in JSON number value. func (e *Encoder) WriteInt(n int64) { e.prepareNext(scalar) - e.out = append(e.out, strconv.FormatInt(n, 10)...) + e.out = strconv.AppendInt(e.out, n, 10) } // WriteUint writes out the given unsigned integer in JSON number value. func (e *Encoder) WriteUint(n uint64) { e.prepareNext(scalar) - e.out = append(e.out, strconv.FormatUint(n, 10)...) + e.out = strconv.AppendUint(e.out, n, 10) } // StartObject writes out the '{' symbol. diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go index 427c62d037f..87853e786d0 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go @@ -412,12 +412,13 @@ func (d *Decoder) parseFieldName() (tok Token, err error) { // Field number. Identify if input is a valid number that is not negative // and is decimal integer within 32-bit range. if num := parseNumber(d.in); num.size > 0 { + str := num.string(d.in) if !num.neg && num.kind == numDec { - if _, err := strconv.ParseInt(string(d.in[:num.size]), 10, 32); err == nil { + if _, err := strconv.ParseInt(str, 10, 32); err == nil { return d.consumeToken(Name, num.size, uint8(FieldNumber)), nil } } - return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size]) + return Token{}, d.newSyntaxError("invalid field number: %s", str) } return Token{}, d.newSyntaxError("invalid field name: %s", errId(d.in)) diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go b/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go index 81a5d8c8613..45c81f0298e 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go @@ -15,17 +15,12 @@ func (d *Decoder) parseNumberValue() (Token, bool) { if num.neg { numAttrs |= isNegative } - strSize := num.size - last := num.size - 1 - if num.kind == numFloat && (d.in[last] == 'f' || d.in[last] == 'F') { - strSize = last - } tok := Token{ kind: Scalar, attrs: numberValue, pos: len(d.orig) - len(d.in), raw: d.in[:num.size], - str: string(d.in[:strSize]), + str: num.string(d.in), numAttrs: numAttrs, } d.consume(num.size) @@ -46,6 +41,27 @@ type number struct { kind uint8 neg bool size int + // if neg, this is the length of whitespace and comments between + // the minus sign and the rest fo the number literal + sep int +} + +func (num number) string(data []byte) string { + strSize := num.size + last := num.size - 1 + if num.kind == numFloat && (data[last] == 'f' || data[last] == 'F') { + strSize = last + } + if num.neg && num.sep > 0 { + // strip whitespace/comments between negative sign and the rest + strLen := strSize - num.sep + str := make([]byte, strLen) + str[0] = data[0] + copy(str[1:], data[num.sep+1:strSize]) + return string(str) + } + return string(data[:strSize]) + } // parseNumber constructs a number object from given input. It allows for the @@ -67,19 +83,22 @@ func parseNumber(input []byte) number { } // Optional - + var sep int if s[0] == '-' { neg = true s = s[1:] size++ + // Consume any whitespace or comments between the + // negative sign and the rest of the number + lenBefore := len(s) + s = consume(s, 0) + sep = lenBefore - len(s) + size += sep if len(s) == 0 { return number{} } } - // C++ allows for whitespace and comments in between the negative sign and - // the rest of the number. This logic currently does not but is consistent - // with v1. - switch { case s[0] == '0': if len(s) > 1 { @@ -116,7 +135,7 @@ func parseNumber(input []byte) number { if len(s) > 0 && !isDelim(s[0]) { return number{} } - return number{kind: kind, neg: neg, size: size} + return number{kind: kind, neg: neg, size: size, sep: sep} } } s = s[1:] @@ -188,5 +207,5 @@ func parseNumber(input []byte) number { return number{} } - return number{kind: kind, neg: neg, size: size} + return number{kind: kind, neg: neg, size: size, sep: sep} } diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go b/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go index da289ccce6e..cf7aed77bc3 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/encode.go @@ -53,8 +53,10 @@ type encoderState struct { // If outputASCII is true, strings will be serialized in such a way that // multi-byte UTF-8 sequences are escaped. This property ensures that the // overall output is ASCII (as opposed to UTF-8). -func NewEncoder(indent string, delims [2]byte, outputASCII bool) (*Encoder, error) { - e := &Encoder{} +func NewEncoder(buf []byte, indent string, delims [2]byte, outputASCII bool) (*Encoder, error) { + e := &Encoder{ + encoderState: encoderState{out: buf}, + } if len(indent) > 0 { if strings.Trim(indent, " \t") != "" { return nil, errors.New("indent may only be composed of space and tab characters") @@ -195,13 +197,13 @@ func appendFloat(out []byte, n float64, bitSize int) []byte { // WriteInt writes out the given signed integer value. func (e *Encoder) WriteInt(n int64) { e.prepareNext(scalar) - e.out = append(e.out, strconv.FormatInt(n, 10)...) + e.out = strconv.AppendInt(e.out, n, 10) } // WriteUint writes out the given unsigned integer value. func (e *Encoder) WriteUint(n uint64) { e.prepareNext(scalar) - e.out = append(e.out, strconv.FormatUint(n, 10)...) + e.out = strconv.AppendUint(e.out, n, 10) } // WriteLiteral writes out the given string as a literal value without quotes. diff --git a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go index e3cdf1c2059..136f1b21573 100644 --- a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go +++ b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go @@ -50,6 +50,7 @@ const ( FileDescriptorProto_Options_field_name protoreflect.Name = "options" FileDescriptorProto_SourceCodeInfo_field_name protoreflect.Name = "source_code_info" FileDescriptorProto_Syntax_field_name protoreflect.Name = "syntax" + FileDescriptorProto_Edition_field_name protoreflect.Name = "edition" FileDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.name" FileDescriptorProto_Package_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.package" @@ -63,6 +64,7 @@ const ( FileDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.options" FileDescriptorProto_SourceCodeInfo_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.source_code_info" FileDescriptorProto_Syntax_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.syntax" + FileDescriptorProto_Edition_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.edition" ) // Field numbers for google.protobuf.FileDescriptorProto. @@ -79,6 +81,7 @@ const ( FileDescriptorProto_Options_field_number protoreflect.FieldNumber = 8 FileDescriptorProto_SourceCodeInfo_field_number protoreflect.FieldNumber = 9 FileDescriptorProto_Syntax_field_number protoreflect.FieldNumber = 12 + FileDescriptorProto_Edition_field_number protoreflect.FieldNumber = 13 ) // Names for google.protobuf.DescriptorProto. @@ -180,13 +183,58 @@ const ( // Field names for google.protobuf.ExtensionRangeOptions. const ( ExtensionRangeOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + ExtensionRangeOptions_Declaration_field_name protoreflect.Name = "declaration" + ExtensionRangeOptions_Verification_field_name protoreflect.Name = "verification" ExtensionRangeOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.uninterpreted_option" + ExtensionRangeOptions_Declaration_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.declaration" + ExtensionRangeOptions_Verification_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.verification" ) // Field numbers for google.protobuf.ExtensionRangeOptions. const ( ExtensionRangeOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 + ExtensionRangeOptions_Declaration_field_number protoreflect.FieldNumber = 2 + ExtensionRangeOptions_Verification_field_number protoreflect.FieldNumber = 3 +) + +// Full and short names for google.protobuf.ExtensionRangeOptions.VerificationState. +const ( + ExtensionRangeOptions_VerificationState_enum_fullname = "google.protobuf.ExtensionRangeOptions.VerificationState" + ExtensionRangeOptions_VerificationState_enum_name = "VerificationState" +) + +// Names for google.protobuf.ExtensionRangeOptions.Declaration. +const ( + ExtensionRangeOptions_Declaration_message_name protoreflect.Name = "Declaration" + ExtensionRangeOptions_Declaration_message_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration" +) + +// Field names for google.protobuf.ExtensionRangeOptions.Declaration. +const ( + ExtensionRangeOptions_Declaration_Number_field_name protoreflect.Name = "number" + ExtensionRangeOptions_Declaration_FullName_field_name protoreflect.Name = "full_name" + ExtensionRangeOptions_Declaration_Type_field_name protoreflect.Name = "type" + ExtensionRangeOptions_Declaration_IsRepeated_field_name protoreflect.Name = "is_repeated" + ExtensionRangeOptions_Declaration_Reserved_field_name protoreflect.Name = "reserved" + ExtensionRangeOptions_Declaration_Repeated_field_name protoreflect.Name = "repeated" + + ExtensionRangeOptions_Declaration_Number_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.number" + ExtensionRangeOptions_Declaration_FullName_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.full_name" + ExtensionRangeOptions_Declaration_Type_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.type" + ExtensionRangeOptions_Declaration_IsRepeated_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.is_repeated" + ExtensionRangeOptions_Declaration_Reserved_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.reserved" + ExtensionRangeOptions_Declaration_Repeated_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.Declaration.repeated" +) + +// Field numbers for google.protobuf.ExtensionRangeOptions.Declaration. +const ( + ExtensionRangeOptions_Declaration_Number_field_number protoreflect.FieldNumber = 1 + ExtensionRangeOptions_Declaration_FullName_field_number protoreflect.FieldNumber = 2 + ExtensionRangeOptions_Declaration_Type_field_number protoreflect.FieldNumber = 3 + ExtensionRangeOptions_Declaration_IsRepeated_field_number protoreflect.FieldNumber = 4 + ExtensionRangeOptions_Declaration_Reserved_field_number protoreflect.FieldNumber = 5 + ExtensionRangeOptions_Declaration_Repeated_field_number protoreflect.FieldNumber = 6 ) // Names for google.protobuf.FieldDescriptorProto. @@ -494,26 +542,29 @@ const ( // Field names for google.protobuf.MessageOptions. const ( - MessageOptions_MessageSetWireFormat_field_name protoreflect.Name = "message_set_wire_format" - MessageOptions_NoStandardDescriptorAccessor_field_name protoreflect.Name = "no_standard_descriptor_accessor" - MessageOptions_Deprecated_field_name protoreflect.Name = "deprecated" - MessageOptions_MapEntry_field_name protoreflect.Name = "map_entry" - MessageOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + MessageOptions_MessageSetWireFormat_field_name protoreflect.Name = "message_set_wire_format" + MessageOptions_NoStandardDescriptorAccessor_field_name protoreflect.Name = "no_standard_descriptor_accessor" + MessageOptions_Deprecated_field_name protoreflect.Name = "deprecated" + MessageOptions_MapEntry_field_name protoreflect.Name = "map_entry" + MessageOptions_DeprecatedLegacyJsonFieldConflicts_field_name protoreflect.Name = "deprecated_legacy_json_field_conflicts" + MessageOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" - MessageOptions_MessageSetWireFormat_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.message_set_wire_format" - MessageOptions_NoStandardDescriptorAccessor_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.no_standard_descriptor_accessor" - MessageOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.deprecated" - MessageOptions_MapEntry_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.map_entry" - MessageOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.uninterpreted_option" + MessageOptions_MessageSetWireFormat_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.message_set_wire_format" + MessageOptions_NoStandardDescriptorAccessor_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.no_standard_descriptor_accessor" + MessageOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.deprecated" + MessageOptions_MapEntry_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.map_entry" + MessageOptions_DeprecatedLegacyJsonFieldConflicts_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts" + MessageOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.uninterpreted_option" ) // Field numbers for google.protobuf.MessageOptions. const ( - MessageOptions_MessageSetWireFormat_field_number protoreflect.FieldNumber = 1 - MessageOptions_NoStandardDescriptorAccessor_field_number protoreflect.FieldNumber = 2 - MessageOptions_Deprecated_field_number protoreflect.FieldNumber = 3 - MessageOptions_MapEntry_field_number protoreflect.FieldNumber = 7 - MessageOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 + MessageOptions_MessageSetWireFormat_field_number protoreflect.FieldNumber = 1 + MessageOptions_NoStandardDescriptorAccessor_field_number protoreflect.FieldNumber = 2 + MessageOptions_Deprecated_field_number protoreflect.FieldNumber = 3 + MessageOptions_MapEntry_field_number protoreflect.FieldNumber = 7 + MessageOptions_DeprecatedLegacyJsonFieldConflicts_field_number protoreflect.FieldNumber = 11 + MessageOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 ) // Names for google.protobuf.FieldOptions. @@ -528,16 +579,26 @@ const ( FieldOptions_Packed_field_name protoreflect.Name = "packed" FieldOptions_Jstype_field_name protoreflect.Name = "jstype" FieldOptions_Lazy_field_name protoreflect.Name = "lazy" + FieldOptions_UnverifiedLazy_field_name protoreflect.Name = "unverified_lazy" FieldOptions_Deprecated_field_name protoreflect.Name = "deprecated" FieldOptions_Weak_field_name protoreflect.Name = "weak" + FieldOptions_DebugRedact_field_name protoreflect.Name = "debug_redact" + FieldOptions_Retention_field_name protoreflect.Name = "retention" + FieldOptions_Target_field_name protoreflect.Name = "target" + FieldOptions_Targets_field_name protoreflect.Name = "targets" FieldOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" FieldOptions_Ctype_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.ctype" FieldOptions_Packed_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.packed" FieldOptions_Jstype_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.jstype" FieldOptions_Lazy_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.lazy" + FieldOptions_UnverifiedLazy_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.unverified_lazy" FieldOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.deprecated" FieldOptions_Weak_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.weak" + FieldOptions_DebugRedact_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.debug_redact" + FieldOptions_Retention_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.retention" + FieldOptions_Target_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.target" + FieldOptions_Targets_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.targets" FieldOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.uninterpreted_option" ) @@ -547,8 +608,13 @@ const ( FieldOptions_Packed_field_number protoreflect.FieldNumber = 2 FieldOptions_Jstype_field_number protoreflect.FieldNumber = 6 FieldOptions_Lazy_field_number protoreflect.FieldNumber = 5 + FieldOptions_UnverifiedLazy_field_number protoreflect.FieldNumber = 15 FieldOptions_Deprecated_field_number protoreflect.FieldNumber = 3 FieldOptions_Weak_field_number protoreflect.FieldNumber = 10 + FieldOptions_DebugRedact_field_number protoreflect.FieldNumber = 16 + FieldOptions_Retention_field_number protoreflect.FieldNumber = 17 + FieldOptions_Target_field_number protoreflect.FieldNumber = 18 + FieldOptions_Targets_field_number protoreflect.FieldNumber = 19 FieldOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 ) @@ -564,6 +630,18 @@ const ( FieldOptions_JSType_enum_name = "JSType" ) +// Full and short names for google.protobuf.FieldOptions.OptionRetention. +const ( + FieldOptions_OptionRetention_enum_fullname = "google.protobuf.FieldOptions.OptionRetention" + FieldOptions_OptionRetention_enum_name = "OptionRetention" +) + +// Full and short names for google.protobuf.FieldOptions.OptionTargetType. +const ( + FieldOptions_OptionTargetType_enum_fullname = "google.protobuf.FieldOptions.OptionTargetType" + FieldOptions_OptionTargetType_enum_name = "OptionTargetType" +) + // Names for google.protobuf.OneofOptions. const ( OneofOptions_message_name protoreflect.Name = "OneofOptions" @@ -590,20 +668,23 @@ const ( // Field names for google.protobuf.EnumOptions. const ( - EnumOptions_AllowAlias_field_name protoreflect.Name = "allow_alias" - EnumOptions_Deprecated_field_name protoreflect.Name = "deprecated" - EnumOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + EnumOptions_AllowAlias_field_name protoreflect.Name = "allow_alias" + EnumOptions_Deprecated_field_name protoreflect.Name = "deprecated" + EnumOptions_DeprecatedLegacyJsonFieldConflicts_field_name protoreflect.Name = "deprecated_legacy_json_field_conflicts" + EnumOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" - EnumOptions_AllowAlias_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.allow_alias" - EnumOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.deprecated" - EnumOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.uninterpreted_option" + EnumOptions_AllowAlias_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.allow_alias" + EnumOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.deprecated" + EnumOptions_DeprecatedLegacyJsonFieldConflicts_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts" + EnumOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.uninterpreted_option" ) // Field numbers for google.protobuf.EnumOptions. const ( - EnumOptions_AllowAlias_field_number protoreflect.FieldNumber = 2 - EnumOptions_Deprecated_field_number protoreflect.FieldNumber = 3 - EnumOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 + EnumOptions_AllowAlias_field_number protoreflect.FieldNumber = 2 + EnumOptions_Deprecated_field_number protoreflect.FieldNumber = 3 + EnumOptions_DeprecatedLegacyJsonFieldConflicts_field_number protoreflect.FieldNumber = 6 + EnumOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 ) // Names for google.protobuf.EnumValueOptions. @@ -813,11 +894,13 @@ const ( GeneratedCodeInfo_Annotation_SourceFile_field_name protoreflect.Name = "source_file" GeneratedCodeInfo_Annotation_Begin_field_name protoreflect.Name = "begin" GeneratedCodeInfo_Annotation_End_field_name protoreflect.Name = "end" + GeneratedCodeInfo_Annotation_Semantic_field_name protoreflect.Name = "semantic" GeneratedCodeInfo_Annotation_Path_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.path" GeneratedCodeInfo_Annotation_SourceFile_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.source_file" GeneratedCodeInfo_Annotation_Begin_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.begin" GeneratedCodeInfo_Annotation_End_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.end" + GeneratedCodeInfo_Annotation_Semantic_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.semantic" ) // Field numbers for google.protobuf.GeneratedCodeInfo.Annotation. @@ -826,4 +909,11 @@ const ( GeneratedCodeInfo_Annotation_SourceFile_field_number protoreflect.FieldNumber = 2 GeneratedCodeInfo_Annotation_Begin_field_number protoreflect.FieldNumber = 3 GeneratedCodeInfo_Annotation_End_field_number protoreflect.FieldNumber = 4 + GeneratedCodeInfo_Annotation_Semantic_field_number protoreflect.FieldNumber = 5 +) + +// Full and short names for google.protobuf.GeneratedCodeInfo.Annotation.Semantic. +const ( + GeneratedCodeInfo_Annotation_Semantic_enum_fullname = "google.protobuf.GeneratedCodeInfo.Annotation.Semantic" + GeneratedCodeInfo_Annotation_Semantic_enum_name = "Semantic" ) diff --git a/vendor/google.golang.org/protobuf/internal/genid/type_gen.go b/vendor/google.golang.org/protobuf/internal/genid/type_gen.go index 3bc710138ad..e0f75fea0a1 100644 --- a/vendor/google.golang.org/protobuf/internal/genid/type_gen.go +++ b/vendor/google.golang.org/protobuf/internal/genid/type_gen.go @@ -32,6 +32,7 @@ const ( Type_Options_field_name protoreflect.Name = "options" Type_SourceContext_field_name protoreflect.Name = "source_context" Type_Syntax_field_name protoreflect.Name = "syntax" + Type_Edition_field_name protoreflect.Name = "edition" Type_Name_field_fullname protoreflect.FullName = "google.protobuf.Type.name" Type_Fields_field_fullname protoreflect.FullName = "google.protobuf.Type.fields" @@ -39,6 +40,7 @@ const ( Type_Options_field_fullname protoreflect.FullName = "google.protobuf.Type.options" Type_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Type.source_context" Type_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Type.syntax" + Type_Edition_field_fullname protoreflect.FullName = "google.protobuf.Type.edition" ) // Field numbers for google.protobuf.Type. @@ -49,6 +51,7 @@ const ( Type_Options_field_number protoreflect.FieldNumber = 4 Type_SourceContext_field_number protoreflect.FieldNumber = 5 Type_Syntax_field_number protoreflect.FieldNumber = 6 + Type_Edition_field_number protoreflect.FieldNumber = 7 ) // Names for google.protobuf.Field. @@ -121,12 +124,14 @@ const ( Enum_Options_field_name protoreflect.Name = "options" Enum_SourceContext_field_name protoreflect.Name = "source_context" Enum_Syntax_field_name protoreflect.Name = "syntax" + Enum_Edition_field_name protoreflect.Name = "edition" Enum_Name_field_fullname protoreflect.FullName = "google.protobuf.Enum.name" Enum_Enumvalue_field_fullname protoreflect.FullName = "google.protobuf.Enum.enumvalue" Enum_Options_field_fullname protoreflect.FullName = "google.protobuf.Enum.options" Enum_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Enum.source_context" Enum_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Enum.syntax" + Enum_Edition_field_fullname protoreflect.FullName = "google.protobuf.Enum.edition" ) // Field numbers for google.protobuf.Enum. @@ -136,6 +141,7 @@ const ( Enum_Options_field_number protoreflect.FieldNumber = 3 Enum_SourceContext_field_number protoreflect.FieldNumber = 4 Enum_Syntax_field_number protoreflect.FieldNumber = 5 + Enum_Edition_field_number protoreflect.FieldNumber = 6 ) // Names for google.protobuf.EnumValue. diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert.go b/vendor/google.golang.org/protobuf/internal/impl/convert.go index 11a6128ba56..185ef2efa5b 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/convert.go +++ b/vendor/google.golang.org/protobuf/internal/impl/convert.go @@ -59,7 +59,6 @@ func NewConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { default: return newSingularConverter(t, fd) } - panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) } var ( diff --git a/vendor/google.golang.org/protobuf/internal/order/order.go b/vendor/google.golang.org/protobuf/internal/order/order.go index 33745ed0625..dea522e127d 100644 --- a/vendor/google.golang.org/protobuf/internal/order/order.go +++ b/vendor/google.golang.org/protobuf/internal/order/order.go @@ -33,7 +33,7 @@ var ( return !inOneof(ox) && inOneof(oy) } // Fields in disjoint oneof sets are sorted by declaration index. - if ox != nil && oy != nil && ox != oy { + if inOneof(ox) && inOneof(oy) && ox != oy { return ox.Index() < oy.Index() } // Fields sorted by field number. diff --git a/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go b/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go index fea589c457e..61a84d34185 100644 --- a/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go +++ b/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go @@ -87,7 +87,7 @@ func (sb *Builder) grow(n int) { // Unlike strings.Builder, we do not need to copy over the contents // of the old buffer since our builder provides no API for // retrieving previously created strings. - sb.buf = make([]byte, 2*(cap(sb.buf)+n)) + sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n)) } func (sb *Builder) last(n int) string { diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index b480c5010f1..0999f29d501 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -51,8 +51,8 @@ import ( // 10. Send out the CL for review and submit it. const ( Major = 1 - Minor = 28 - Patch = 1 + Minor = 31 + Patch = 0 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/proto/doc.go b/vendor/google.golang.org/protobuf/proto/doc.go index 08d2a46f535..ec71e717fe7 100644 --- a/vendor/google.golang.org/protobuf/proto/doc.go +++ b/vendor/google.golang.org/protobuf/proto/doc.go @@ -5,16 +5,13 @@ // Package proto provides functions operating on protocol buffer messages. // // For documentation on protocol buffers in general, see: -// -// https://developers.google.com/protocol-buffers +// https://protobuf.dev. // // For a tutorial on using protocol buffers with Go, see: -// -// https://developers.google.com/protocol-buffers/docs/gotutorial +// https://protobuf.dev/getting-started/gotutorial. // // For a guide to generated Go protocol buffer code, see: -// -// https://developers.google.com/protocol-buffers/docs/reference/go-generated +// https://protobuf.dev/reference/go/go-generated. // // # Binary serialization // diff --git a/vendor/google.golang.org/protobuf/proto/equal.go b/vendor/google.golang.org/protobuf/proto/equal.go index 67948dd1df8..1a0be1b03c7 100644 --- a/vendor/google.golang.org/protobuf/proto/equal.go +++ b/vendor/google.golang.org/protobuf/proto/equal.go @@ -5,30 +5,39 @@ package proto import ( - "bytes" - "math" "reflect" - "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/reflect/protoreflect" ) -// Equal reports whether two messages are equal. -// If two messages marshal to the same bytes under deterministic serialization, -// then Equal is guaranteed to report true. +// Equal reports whether two messages are equal, +// by recursively comparing the fields of the message. // -// Two messages are equal if they belong to the same message descriptor, -// have the same set of populated known and extension field values, -// and the same set of unknown fields values. If either of the top-level -// messages are invalid, then Equal reports true only if both are invalid. +// - Bytes fields are equal if they contain identical bytes. +// Empty bytes (regardless of nil-ness) are considered equal. // -// Scalar values are compared with the equivalent of the == operator in Go, -// except bytes values which are compared using bytes.Equal and -// floating point values which specially treat NaNs as equal. -// Message values are compared by recursively calling Equal. -// Lists are equal if each element value is also equal. -// Maps are equal if they have the same set of keys, where the pair of values -// for each key is also equal. +// - Floating-point fields are equal if they contain the same value. +// Unlike the == operator, a NaN is equal to another NaN. +// +// - Other scalar fields are equal if they contain the same value. +// +// - Message fields are equal if they have +// the same set of populated known and extension field values, and +// the same set of unknown fields values. +// +// - Lists are equal if they are the same length and +// each corresponding element is equal. +// +// - Maps are equal if they have the same set of keys and +// the corresponding value for each key is equal. +// +// An invalid message is not equal to a valid message. +// An invalid message is only equal to another invalid message of the +// same type. An invalid message often corresponds to a nil pointer +// of the concrete message type. For example, (*pb.M)(nil) is not equal +// to &pb.M{}. +// If two valid messages marshal to the same bytes under deterministic +// serialization, then Equal is guaranteed to report true. func Equal(x, y Message) bool { if x == nil || y == nil { return x == nil && y == nil @@ -42,130 +51,7 @@ func Equal(x, y Message) bool { if mx.IsValid() != my.IsValid() { return false } - return equalMessage(mx, my) -} - -// equalMessage compares two messages. -func equalMessage(mx, my protoreflect.Message) bool { - if mx.Descriptor() != my.Descriptor() { - return false - } - - nx := 0 - equal := true - mx.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool { - nx++ - vy := my.Get(fd) - equal = my.Has(fd) && equalField(fd, vx, vy) - return equal - }) - if !equal { - return false - } - ny := 0 - my.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool { - ny++ - return true - }) - if nx != ny { - return false - } - - return equalUnknown(mx.GetUnknown(), my.GetUnknown()) -} - -// equalField compares two fields. -func equalField(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool { - switch { - case fd.IsList(): - return equalList(fd, x.List(), y.List()) - case fd.IsMap(): - return equalMap(fd, x.Map(), y.Map()) - default: - return equalValue(fd, x, y) - } -} - -// equalMap compares two maps. -func equalMap(fd protoreflect.FieldDescriptor, x, y protoreflect.Map) bool { - if x.Len() != y.Len() { - return false - } - equal := true - x.Range(func(k protoreflect.MapKey, vx protoreflect.Value) bool { - vy := y.Get(k) - equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy) - return equal - }) - return equal -} - -// equalList compares two lists. -func equalList(fd protoreflect.FieldDescriptor, x, y protoreflect.List) bool { - if x.Len() != y.Len() { - return false - } - for i := x.Len() - 1; i >= 0; i-- { - if !equalValue(fd, x.Get(i), y.Get(i)) { - return false - } - } - return true -} - -// equalValue compares two singular values. -func equalValue(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool { - switch fd.Kind() { - case protoreflect.BoolKind: - return x.Bool() == y.Bool() - case protoreflect.EnumKind: - return x.Enum() == y.Enum() - case protoreflect.Int32Kind, protoreflect.Sint32Kind, - protoreflect.Int64Kind, protoreflect.Sint64Kind, - protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind: - return x.Int() == y.Int() - case protoreflect.Uint32Kind, protoreflect.Uint64Kind, - protoreflect.Fixed32Kind, protoreflect.Fixed64Kind: - return x.Uint() == y.Uint() - case protoreflect.FloatKind, protoreflect.DoubleKind: - fx := x.Float() - fy := y.Float() - if math.IsNaN(fx) || math.IsNaN(fy) { - return math.IsNaN(fx) && math.IsNaN(fy) - } - return fx == fy - case protoreflect.StringKind: - return x.String() == y.String() - case protoreflect.BytesKind: - return bytes.Equal(x.Bytes(), y.Bytes()) - case protoreflect.MessageKind, protoreflect.GroupKind: - return equalMessage(x.Message(), y.Message()) - default: - return x.Interface() == y.Interface() - } -} - -// equalUnknown compares unknown fields by direct comparison on the raw bytes -// of each individual field number. -func equalUnknown(x, y protoreflect.RawFields) bool { - if len(x) != len(y) { - return false - } - if bytes.Equal([]byte(x), []byte(y)) { - return true - } - - mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - my := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - for len(x) > 0 { - fnum, _, n := protowire.ConsumeField(x) - mx[fnum] = append(mx[fnum], x[:n]...) - x = x[n:] - } - for len(y) > 0 { - fnum, _, n := protowire.ConsumeField(y) - my[fnum] = append(my[fnum], y[:n]...) - y = y[n:] - } - return reflect.DeepEqual(mx, my) + vx := protoreflect.ValueOfMessage(mx) + vy := protoreflect.ValueOfMessage(my) + return vx.Equal(vy) } diff --git a/vendor/google.golang.org/protobuf/proto/size.go b/vendor/google.golang.org/protobuf/proto/size.go index 554b9c6c09a..f1692b49b6c 100644 --- a/vendor/google.golang.org/protobuf/proto/size.go +++ b/vendor/google.golang.org/protobuf/proto/size.go @@ -73,23 +73,27 @@ func (o MarshalOptions) sizeField(fd protoreflect.FieldDescriptor, value protore } func (o MarshalOptions) sizeList(num protowire.Number, fd protoreflect.FieldDescriptor, list protoreflect.List) (size int) { + sizeTag := protowire.SizeTag(num) + if fd.IsPacked() && list.Len() > 0 { content := 0 for i, llen := 0, list.Len(); i < llen; i++ { content += o.sizeSingular(num, fd.Kind(), list.Get(i)) } - return protowire.SizeTag(num) + protowire.SizeBytes(content) + return sizeTag + protowire.SizeBytes(content) } for i, llen := 0, list.Len(); i < llen; i++ { - size += protowire.SizeTag(num) + o.sizeSingular(num, fd.Kind(), list.Get(i)) + size += sizeTag + o.sizeSingular(num, fd.Kind(), list.Get(i)) } return size } func (o MarshalOptions) sizeMap(num protowire.Number, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) (size int) { + sizeTag := protowire.SizeTag(num) + mapv.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool { - size += protowire.SizeTag(num) + size += sizeTag size += protowire.SizeBytes(o.sizeField(fd.MapKey(), key.Value()) + o.sizeField(fd.MapValue(), value)) return true }) diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go index b03c1223c4a..717b106f3da 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go @@ -35,6 +35,8 @@ func (p *SourcePath) appendFileDescriptorProto(b []byte) []byte { b = p.appendSingularField(b, "source_code_info", (*SourcePath).appendSourceCodeInfo) case 12: b = p.appendSingularField(b, "syntax", nil) + case 13: + b = p.appendSingularField(b, "edition", nil) } return b } @@ -236,6 +238,8 @@ func (p *SourcePath) appendMessageOptions(b []byte) []byte { b = p.appendSingularField(b, "deprecated", nil) case 7: b = p.appendSingularField(b, "map_entry", nil) + case 11: + b = p.appendSingularField(b, "deprecated_legacy_json_field_conflicts", nil) case 999: b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption) } @@ -279,6 +283,8 @@ func (p *SourcePath) appendEnumOptions(b []byte) []byte { b = p.appendSingularField(b, "allow_alias", nil) case 3: b = p.appendSingularField(b, "deprecated", nil) + case 6: + b = p.appendSingularField(b, "deprecated_legacy_json_field_conflicts", nil) case 999: b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption) } @@ -345,10 +351,20 @@ func (p *SourcePath) appendFieldOptions(b []byte) []byte { b = p.appendSingularField(b, "jstype", nil) case 5: b = p.appendSingularField(b, "lazy", nil) + case 15: + b = p.appendSingularField(b, "unverified_lazy", nil) case 3: b = p.appendSingularField(b, "deprecated", nil) case 10: b = p.appendSingularField(b, "weak", nil) + case 16: + b = p.appendSingularField(b, "debug_redact", nil) + case 17: + b = p.appendSingularField(b, "retention", nil) + case 18: + b = p.appendSingularField(b, "target", nil) + case 19: + b = p.appendRepeatedField(b, "targets", nil) case 999: b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption) } @@ -404,6 +420,10 @@ func (p *SourcePath) appendExtensionRangeOptions(b []byte) []byte { switch (*p)[0] { case 999: b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption) + case 2: + b = p.appendRepeatedField(b, "declaration", (*SourcePath).appendExtensionRangeOptions_Declaration) + case 3: + b = p.appendSingularField(b, "verification", nil) } return b } @@ -459,3 +479,24 @@ func (p *SourcePath) appendUninterpretedOption_NamePart(b []byte) []byte { } return b } + +func (p *SourcePath) appendExtensionRangeOptions_Declaration(b []byte) []byte { + if len(*p) == 0 { + return b + } + switch (*p)[0] { + case 1: + b = p.appendSingularField(b, "number", nil) + case 2: + b = p.appendSingularField(b, "full_name", nil) + case 3: + b = p.appendSingularField(b, "type", nil) + case 4: + b = p.appendSingularField(b, "is_repeated", nil) + case 5: + b = p.appendSingularField(b, "reserved", nil) + case 6: + b = p.appendSingularField(b, "repeated", nil) + } + return b +} diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go index f3198107782..37601b78199 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go @@ -148,7 +148,7 @@ type Message interface { // be preserved in marshaling or other operations. IsValid() bool - // ProtoMethods returns optional fast-path implementions of various operations. + // ProtoMethods returns optional fast-path implementations of various operations. // This method may return nil. // // The returned methods type is identical to diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/value_equal.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_equal.go new file mode 100644 index 00000000000..591652541f2 --- /dev/null +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_equal.go @@ -0,0 +1,168 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protoreflect + +import ( + "bytes" + "fmt" + "math" + "reflect" + + "google.golang.org/protobuf/encoding/protowire" +) + +// Equal reports whether v1 and v2 are recursively equal. +// +// - Values of different types are always unequal. +// +// - Bytes values are equal if they contain identical bytes. +// Empty bytes (regardless of nil-ness) are considered equal. +// +// - Floating point values are equal if they contain the same value. +// Unlike the == operator, a NaN is equal to another NaN. +// +// - Enums are equal if they contain the same number. +// Since Value does not contain an enum descriptor, +// enum values do not consider the type of the enum. +// +// - Other scalar values are equal if they contain the same value. +// +// - Message values are equal if they belong to the same message descriptor, +// have the same set of populated known and extension field values, +// and the same set of unknown fields values. +// +// - Lists are equal if they are the same length and +// each corresponding element is equal. +// +// - Maps are equal if they have the same set of keys and +// the corresponding value for each key is equal. +func (v1 Value) Equal(v2 Value) bool { + return equalValue(v1, v2) +} + +func equalValue(x, y Value) bool { + eqType := x.typ == y.typ + switch x.typ { + case nilType: + return eqType + case boolType: + return eqType && x.Bool() == y.Bool() + case int32Type, int64Type: + return eqType && x.Int() == y.Int() + case uint32Type, uint64Type: + return eqType && x.Uint() == y.Uint() + case float32Type, float64Type: + return eqType && equalFloat(x.Float(), y.Float()) + case stringType: + return eqType && x.String() == y.String() + case bytesType: + return eqType && bytes.Equal(x.Bytes(), y.Bytes()) + case enumType: + return eqType && x.Enum() == y.Enum() + default: + switch x := x.Interface().(type) { + case Message: + y, ok := y.Interface().(Message) + return ok && equalMessage(x, y) + case List: + y, ok := y.Interface().(List) + return ok && equalList(x, y) + case Map: + y, ok := y.Interface().(Map) + return ok && equalMap(x, y) + default: + panic(fmt.Sprintf("unknown type: %T", x)) + } + } +} + +// equalFloat compares two floats, where NaNs are treated as equal. +func equalFloat(x, y float64) bool { + if math.IsNaN(x) || math.IsNaN(y) { + return math.IsNaN(x) && math.IsNaN(y) + } + return x == y +} + +// equalMessage compares two messages. +func equalMessage(mx, my Message) bool { + if mx.Descriptor() != my.Descriptor() { + return false + } + + nx := 0 + equal := true + mx.Range(func(fd FieldDescriptor, vx Value) bool { + nx++ + vy := my.Get(fd) + equal = my.Has(fd) && equalValue(vx, vy) + return equal + }) + if !equal { + return false + } + ny := 0 + my.Range(func(fd FieldDescriptor, vx Value) bool { + ny++ + return true + }) + if nx != ny { + return false + } + + return equalUnknown(mx.GetUnknown(), my.GetUnknown()) +} + +// equalList compares two lists. +func equalList(x, y List) bool { + if x.Len() != y.Len() { + return false + } + for i := x.Len() - 1; i >= 0; i-- { + if !equalValue(x.Get(i), y.Get(i)) { + return false + } + } + return true +} + +// equalMap compares two maps. +func equalMap(x, y Map) bool { + if x.Len() != y.Len() { + return false + } + equal := true + x.Range(func(k MapKey, vx Value) bool { + vy := y.Get(k) + equal = y.Has(k) && equalValue(vx, vy) + return equal + }) + return equal +} + +// equalUnknown compares unknown fields by direct comparison on the raw bytes +// of each individual field number. +func equalUnknown(x, y RawFields) bool { + if len(x) != len(y) { + return false + } + if bytes.Equal([]byte(x), []byte(y)) { + return true + } + + mx := make(map[FieldNumber]RawFields) + my := make(map[FieldNumber]RawFields) + for len(x) > 0 { + fnum, _, n := protowire.ConsumeField(x) + mx[fnum] = append(mx[fnum], x[:n]...) + x = x[n:] + } + for len(y) > 0 { + fnum, _, n := protowire.ConsumeField(y) + my[fnum] = append(my[fnum], y[:n]...) + y = y[n:] + } + return reflect.DeepEqual(mx, my) +} diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go index ca8e28c5bc8..08e5ef73fc0 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go @@ -54,11 +54,11 @@ import ( // // Append a 0 to a "repeated int32" field. // // Since the Value returned by Mutable is guaranteed to alias // // the source message, modifying the Value modifies the message. -// message.Mutable(fieldDesc).(List).Append(protoreflect.ValueOfInt32(0)) +// message.Mutable(fieldDesc).List().Append(protoreflect.ValueOfInt32(0)) // // // Assign [0] to a "repeated int32" field by creating a new Value, // // modifying it, and assigning it. -// list := message.NewField(fieldDesc).(List) +// list := message.NewField(fieldDesc).List() // list.Append(protoreflect.ValueOfInt32(0)) // message.Set(fieldDesc, list) // // ERROR: Since it is not defined whether Set aliases the source, diff --git a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go index 58352a6978b..aeb55977446 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go +++ b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go @@ -46,7 +46,7 @@ var conflictPolicy = "panic" // "panic" | "warn" | "ignore" // It is a variable so that the behavior is easily overridden in another file. var ignoreConflict = func(d protoreflect.Descriptor, err error) bool { const env = "GOLANG_PROTOBUF_REGISTRATION_CONFLICT" - const faq = "https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict" + const faq = "https://protobuf.dev/reference/go/faq#namespace-conflict" policy := conflictPolicy if v := os.Getenv(env); v != "" { policy = v diff --git a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go index abe4ab5115b..04c00f737c1 100644 --- a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go +++ b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go @@ -48,6 +48,64 @@ import ( sync "sync" ) +// The verification state of the extension range. +type ExtensionRangeOptions_VerificationState int32 + +const ( + // All the extensions of the range must be declared. + ExtensionRangeOptions_DECLARATION ExtensionRangeOptions_VerificationState = 0 + ExtensionRangeOptions_UNVERIFIED ExtensionRangeOptions_VerificationState = 1 +) + +// Enum value maps for ExtensionRangeOptions_VerificationState. +var ( + ExtensionRangeOptions_VerificationState_name = map[int32]string{ + 0: "DECLARATION", + 1: "UNVERIFIED", + } + ExtensionRangeOptions_VerificationState_value = map[string]int32{ + "DECLARATION": 0, + "UNVERIFIED": 1, + } +) + +func (x ExtensionRangeOptions_VerificationState) Enum() *ExtensionRangeOptions_VerificationState { + p := new(ExtensionRangeOptions_VerificationState) + *p = x + return p +} + +func (x ExtensionRangeOptions_VerificationState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExtensionRangeOptions_VerificationState) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[0].Descriptor() +} + +func (ExtensionRangeOptions_VerificationState) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[0] +} + +func (x ExtensionRangeOptions_VerificationState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ExtensionRangeOptions_VerificationState) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ExtensionRangeOptions_VerificationState(num) + return nil +} + +// Deprecated: Use ExtensionRangeOptions_VerificationState.Descriptor instead. +func (ExtensionRangeOptions_VerificationState) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3, 0} +} + type FieldDescriptorProto_Type int32 const ( @@ -137,11 +195,11 @@ func (x FieldDescriptorProto_Type) String() string { } func (FieldDescriptorProto_Type) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[0].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor() } func (FieldDescriptorProto_Type) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[0] + return &file_google_protobuf_descriptor_proto_enumTypes[1] } func (x FieldDescriptorProto_Type) Number() protoreflect.EnumNumber { @@ -197,11 +255,11 @@ func (x FieldDescriptorProto_Label) String() string { } func (FieldDescriptorProto_Label) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor() } func (FieldDescriptorProto_Label) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[1] + return &file_google_protobuf_descriptor_proto_enumTypes[2] } func (x FieldDescriptorProto_Label) Number() protoreflect.EnumNumber { @@ -258,11 +316,11 @@ func (x FileOptions_OptimizeMode) String() string { } func (FileOptions_OptimizeMode) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor() } func (FileOptions_OptimizeMode) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[2] + return &file_google_protobuf_descriptor_proto_enumTypes[3] } func (x FileOptions_OptimizeMode) Number() protoreflect.EnumNumber { @@ -288,7 +346,13 @@ type FieldOptions_CType int32 const ( // Default mode. - FieldOptions_STRING FieldOptions_CType = 0 + FieldOptions_STRING FieldOptions_CType = 0 + // The option [ctype=CORD] may be applied to a non-repeated field of type + // "bytes". It indicates that in C++, the data should be stored in a Cord + // instead of a string. For very large strings, this may reduce memory + // fragmentation. It may also allow better performance when parsing from a + // Cord, or when parsing with aliasing enabled, as the parsed Cord may then + // alias the original buffer. FieldOptions_CORD FieldOptions_CType = 1 FieldOptions_STRING_PIECE FieldOptions_CType = 2 ) @@ -318,11 +382,11 @@ func (x FieldOptions_CType) String() string { } func (FieldOptions_CType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor() } func (FieldOptions_CType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[3] + return &file_google_protobuf_descriptor_proto_enumTypes[4] } func (x FieldOptions_CType) Number() protoreflect.EnumNumber { @@ -380,11 +444,11 @@ func (x FieldOptions_JSType) String() string { } func (FieldOptions_JSType) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor() } func (FieldOptions_JSType) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[4] + return &file_google_protobuf_descriptor_proto_enumTypes[5] } func (x FieldOptions_JSType) Number() protoreflect.EnumNumber { @@ -406,6 +470,152 @@ func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12, 1} } +// If set to RETENTION_SOURCE, the option will be omitted from the binary. +// Note: as of January 2023, support for this is in progress and does not yet +// have an effect (b/264593489). +type FieldOptions_OptionRetention int32 + +const ( + FieldOptions_RETENTION_UNKNOWN FieldOptions_OptionRetention = 0 + FieldOptions_RETENTION_RUNTIME FieldOptions_OptionRetention = 1 + FieldOptions_RETENTION_SOURCE FieldOptions_OptionRetention = 2 +) + +// Enum value maps for FieldOptions_OptionRetention. +var ( + FieldOptions_OptionRetention_name = map[int32]string{ + 0: "RETENTION_UNKNOWN", + 1: "RETENTION_RUNTIME", + 2: "RETENTION_SOURCE", + } + FieldOptions_OptionRetention_value = map[string]int32{ + "RETENTION_UNKNOWN": 0, + "RETENTION_RUNTIME": 1, + "RETENTION_SOURCE": 2, + } +) + +func (x FieldOptions_OptionRetention) Enum() *FieldOptions_OptionRetention { + p := new(FieldOptions_OptionRetention) + *p = x + return p +} + +func (x FieldOptions_OptionRetention) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FieldOptions_OptionRetention) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[6].Descriptor() +} + +func (FieldOptions_OptionRetention) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[6] +} + +func (x FieldOptions_OptionRetention) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *FieldOptions_OptionRetention) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = FieldOptions_OptionRetention(num) + return nil +} + +// Deprecated: Use FieldOptions_OptionRetention.Descriptor instead. +func (FieldOptions_OptionRetention) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12, 2} +} + +// This indicates the types of entities that the field may apply to when used +// as an option. If it is unset, then the field may be freely used as an +// option on any kind of entity. Note: as of January 2023, support for this is +// in progress and does not yet have an effect (b/264593489). +type FieldOptions_OptionTargetType int32 + +const ( + FieldOptions_TARGET_TYPE_UNKNOWN FieldOptions_OptionTargetType = 0 + FieldOptions_TARGET_TYPE_FILE FieldOptions_OptionTargetType = 1 + FieldOptions_TARGET_TYPE_EXTENSION_RANGE FieldOptions_OptionTargetType = 2 + FieldOptions_TARGET_TYPE_MESSAGE FieldOptions_OptionTargetType = 3 + FieldOptions_TARGET_TYPE_FIELD FieldOptions_OptionTargetType = 4 + FieldOptions_TARGET_TYPE_ONEOF FieldOptions_OptionTargetType = 5 + FieldOptions_TARGET_TYPE_ENUM FieldOptions_OptionTargetType = 6 + FieldOptions_TARGET_TYPE_ENUM_ENTRY FieldOptions_OptionTargetType = 7 + FieldOptions_TARGET_TYPE_SERVICE FieldOptions_OptionTargetType = 8 + FieldOptions_TARGET_TYPE_METHOD FieldOptions_OptionTargetType = 9 +) + +// Enum value maps for FieldOptions_OptionTargetType. +var ( + FieldOptions_OptionTargetType_name = map[int32]string{ + 0: "TARGET_TYPE_UNKNOWN", + 1: "TARGET_TYPE_FILE", + 2: "TARGET_TYPE_EXTENSION_RANGE", + 3: "TARGET_TYPE_MESSAGE", + 4: "TARGET_TYPE_FIELD", + 5: "TARGET_TYPE_ONEOF", + 6: "TARGET_TYPE_ENUM", + 7: "TARGET_TYPE_ENUM_ENTRY", + 8: "TARGET_TYPE_SERVICE", + 9: "TARGET_TYPE_METHOD", + } + FieldOptions_OptionTargetType_value = map[string]int32{ + "TARGET_TYPE_UNKNOWN": 0, + "TARGET_TYPE_FILE": 1, + "TARGET_TYPE_EXTENSION_RANGE": 2, + "TARGET_TYPE_MESSAGE": 3, + "TARGET_TYPE_FIELD": 4, + "TARGET_TYPE_ONEOF": 5, + "TARGET_TYPE_ENUM": 6, + "TARGET_TYPE_ENUM_ENTRY": 7, + "TARGET_TYPE_SERVICE": 8, + "TARGET_TYPE_METHOD": 9, + } +) + +func (x FieldOptions_OptionTargetType) Enum() *FieldOptions_OptionTargetType { + p := new(FieldOptions_OptionTargetType) + *p = x + return p +} + +func (x FieldOptions_OptionTargetType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FieldOptions_OptionTargetType) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[7].Descriptor() +} + +func (FieldOptions_OptionTargetType) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[7] +} + +func (x FieldOptions_OptionTargetType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *FieldOptions_OptionTargetType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = FieldOptions_OptionTargetType(num) + return nil +} + +// Deprecated: Use FieldOptions_OptionTargetType.Descriptor instead. +func (FieldOptions_OptionTargetType) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12, 3} +} + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, // or neither? HTTP based RPC implementation may choose GET verb for safe // methods, and PUT verb for idempotent methods instead of the default POST. @@ -442,11 +652,11 @@ func (x MethodOptions_IdempotencyLevel) String() string { } func (MethodOptions_IdempotencyLevel) Descriptor() protoreflect.EnumDescriptor { - return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor() + return file_google_protobuf_descriptor_proto_enumTypes[8].Descriptor() } func (MethodOptions_IdempotencyLevel) Type() protoreflect.EnumType { - return &file_google_protobuf_descriptor_proto_enumTypes[5] + return &file_google_protobuf_descriptor_proto_enumTypes[8] } func (x MethodOptions_IdempotencyLevel) Number() protoreflect.EnumNumber { @@ -468,6 +678,70 @@ func (MethodOptions_IdempotencyLevel) EnumDescriptor() ([]byte, []int) { return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{17, 0} } +// Represents the identified object's effect on the element in the original +// .proto file. +type GeneratedCodeInfo_Annotation_Semantic int32 + +const ( + // There is no effect or the effect is indescribable. + GeneratedCodeInfo_Annotation_NONE GeneratedCodeInfo_Annotation_Semantic = 0 + // The element is set or otherwise mutated. + GeneratedCodeInfo_Annotation_SET GeneratedCodeInfo_Annotation_Semantic = 1 + // An alias to the element is returned. + GeneratedCodeInfo_Annotation_ALIAS GeneratedCodeInfo_Annotation_Semantic = 2 +) + +// Enum value maps for GeneratedCodeInfo_Annotation_Semantic. +var ( + GeneratedCodeInfo_Annotation_Semantic_name = map[int32]string{ + 0: "NONE", + 1: "SET", + 2: "ALIAS", + } + GeneratedCodeInfo_Annotation_Semantic_value = map[string]int32{ + "NONE": 0, + "SET": 1, + "ALIAS": 2, + } +) + +func (x GeneratedCodeInfo_Annotation_Semantic) Enum() *GeneratedCodeInfo_Annotation_Semantic { + p := new(GeneratedCodeInfo_Annotation_Semantic) + *p = x + return p +} + +func (x GeneratedCodeInfo_Annotation_Semantic) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GeneratedCodeInfo_Annotation_Semantic) Descriptor() protoreflect.EnumDescriptor { + return file_google_protobuf_descriptor_proto_enumTypes[9].Descriptor() +} + +func (GeneratedCodeInfo_Annotation_Semantic) Type() protoreflect.EnumType { + return &file_google_protobuf_descriptor_proto_enumTypes[9] +} + +func (x GeneratedCodeInfo_Annotation_Semantic) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *GeneratedCodeInfo_Annotation_Semantic) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = GeneratedCodeInfo_Annotation_Semantic(num) + return nil +} + +// Deprecated: Use GeneratedCodeInfo_Annotation_Semantic.Descriptor instead. +func (GeneratedCodeInfo_Annotation_Semantic) EnumDescriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{20, 0, 0} +} + // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. type FileDescriptorSet struct { @@ -544,8 +818,12 @@ type FileDescriptorProto struct { // development tools. SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info,json=sourceCodeInfo" json:"source_code_info,omitempty"` // The syntax of the proto file. - // The supported values are "proto2" and "proto3". + // The supported values are "proto2", "proto3", and "editions". + // + // If `edition` is present, this value must be "editions". Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + // The edition of the proto file, which is an opaque string. + Edition *string `protobuf:"bytes,13,opt,name=edition" json:"edition,omitempty"` } func (x *FileDescriptorProto) Reset() { @@ -664,6 +942,13 @@ func (x *FileDescriptorProto) GetSyntax() string { return "" } +func (x *FileDescriptorProto) GetEdition() string { + if x != nil && x.Edition != nil { + return *x.Edition + } + return "" +} + // Describes a message type. type DescriptorProto struct { state protoimpl.MessageState @@ -794,7 +1079,21 @@ type ExtensionRangeOptions struct { // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` -} + // go/protobuf-stripping-extension-declarations + // Like Metadata, but we use a repeated field to hold all extension + // declarations. This should avoid the size increases of transforming a large + // extension range into small ranges in generated binaries. + Declaration []*ExtensionRangeOptions_Declaration `protobuf:"bytes,2,rep,name=declaration" json:"declaration,omitempty"` + // The verification state of the range. + // TODO(b/278783756): flip the default to DECLARATION once all empty ranges + // are marked as UNVERIFIED. + Verification *ExtensionRangeOptions_VerificationState `protobuf:"varint,3,opt,name=verification,enum=google.protobuf.ExtensionRangeOptions_VerificationState,def=1" json:"verification,omitempty"` +} + +// Default values for ExtensionRangeOptions fields. +const ( + Default_ExtensionRangeOptions_Verification = ExtensionRangeOptions_UNVERIFIED +) func (x *ExtensionRangeOptions) Reset() { *x = ExtensionRangeOptions{} @@ -835,6 +1134,20 @@ func (x *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption return nil } +func (x *ExtensionRangeOptions) GetDeclaration() []*ExtensionRangeOptions_Declaration { + if x != nil { + return x.Declaration + } + return nil +} + +func (x *ExtensionRangeOptions) GetVerification() ExtensionRangeOptions_VerificationState { + if x != nil && x.Verification != nil { + return *x.Verification + } + return Default_ExtensionRangeOptions_Verification +} + // Describes a field within a message. type FieldDescriptorProto struct { state protoimpl.MessageState @@ -860,7 +1173,6 @@ type FieldDescriptorProto struct { // For booleans, "true" or "false". // For strings, contains the default text contents (not escaped in any way). // For bytes, contains the C escaped value. All bytes >= 128 are escaped. - // TODO(kenton): Base-64 encode? DefaultValue *string `protobuf:"bytes,7,opt,name=default_value,json=defaultValue" json:"default_value,omitempty"` // If set, gives the index of a oneof in the containing type's oneof_decl // list. This field is a member of that oneof. @@ -1382,22 +1694,22 @@ type FileOptions struct { // inappropriate because proto packages do not normally start with backwards // domain names. JavaPackage *string `protobuf:"bytes,1,opt,name=java_package,json=javaPackage" json:"java_package,omitempty"` - // If set, all the classes from the .proto file are wrapped in a single - // outer class with the given name. This applies to both Proto1 - // (equivalent to the old "--one_java_file" option) and Proto2 (where - // a .proto always translates to a single class, but you may want to - // explicitly choose the class name). + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname,json=javaOuterClassname" json:"java_outer_classname,omitempty"` - // If set true, then the Java code generator will generate a separate .java + // If enabled, then the Java code generator will generate a separate .java // file for each top-level message, enum, and service defined in the .proto - // file. Thus, these types will *not* be nested inside the outer class - // named by java_outer_classname. However, the outer class will still be + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be // generated to contain the file's getDescriptor() method as well as any // top-level extensions defined in the file. JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"` // This option does nothing. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash" json:"java_generate_equals_and_hash,omitempty"` // If set true, then the Java2 code generator will generate code that // throws an exception whenever an attempt is made to assign a non-UTF-8 @@ -1531,7 +1843,7 @@ func (x *FileOptions) GetJavaMultipleFiles() bool { return Default_FileOptions_JavaMultipleFiles } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. func (x *FileOptions) GetJavaGenerateEqualsAndHash() bool { if x != nil && x.JavaGenerateEqualsAndHash != nil { return *x.JavaGenerateEqualsAndHash @@ -1670,10 +1982,12 @@ type MessageOptions struct { // efficient, has fewer features, and is more complicated. // // The message must be defined exactly as follows: - // message Foo { - // option message_set_wire_format = true; - // extensions 4 to max; - // } + // + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // // Note that the message cannot have any defined fields; MessageSets only // have extensions. // @@ -1692,28 +2006,44 @@ type MessageOptions struct { // for the message, or it will be completely ignored; in the very least, // this is a formalization for deprecating messages. Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + // // Whether the message is an automatically generated map entry type for the // maps field. // // For maps fields: - // map map_field = 1; + // + // map map_field = 1; + // // The parsed descriptor looks like: - // message MapFieldEntry { - // option map_entry = true; - // optional KeyType key = 1; - // optional ValueType value = 2; - // } - // repeated MapFieldEntry map_field = 1; + // + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; // // Implementations may choose not to generate the map_entry=true message, but // use a native map in the target language to hold the keys and values. // The reflection APIs in such implementations still need to work as // if the field is a repeated message field. - // - // NOTE: Do not set the option in .proto files. Always use the maps syntax - // instead. The option should only be implicitly set by the proto compiler - // parser. MapEntry *bool `protobuf:"varint,7,opt,name=map_entry,json=mapEntry" json:"map_entry,omitempty"` + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // + // This should only be used as a temporary measure against broken builds due + // to the change in behavior for JSON field name conflicts. + // + // TODO(b/261750190) This is legacy behavior we plan to remove once downstream + // teams have had time to migrate. + // + // Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. + DeprecatedLegacyJsonFieldConflicts *bool `protobuf:"varint,11,opt,name=deprecated_legacy_json_field_conflicts,json=deprecatedLegacyJsonFieldConflicts" json:"deprecated_legacy_json_field_conflicts,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` } @@ -1785,6 +2115,14 @@ func (x *MessageOptions) GetMapEntry() bool { return false } +// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. +func (x *MessageOptions) GetDeprecatedLegacyJsonFieldConflicts() bool { + if x != nil && x.DeprecatedLegacyJsonFieldConflicts != nil { + return *x.DeprecatedLegacyJsonFieldConflicts + } + return false +} + func (x *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { if x != nil { return x.UninterpretedOption @@ -1800,8 +2138,10 @@ type FieldOptions struct { // The ctype option instructs the C++ code generator to use a different // representation of the field than it normally would. See the specific - // options below. This option is not yet implemented in the open source - // release -- sorry, we'll try to include it in a future version! + // options below. This option is only implemented to support use of + // [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of + // type "bytes" in the open source release -- sorry, we'll try to include + // other types in a future version! Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` // The packed option can be enabled for repeated primitive fields to enable // a more efficient representation on the wire. Rather than repeatedly @@ -1838,7 +2178,6 @@ type FieldOptions struct { // call from multiple threads concurrently, while non-const methods continue // to require exclusive access. // - // // Note that implementations may choose not to check required fields within // a lazy sub-message. That is, calling IsInitialized() on the outer message // may return true even if the inner message has missing required fields. @@ -1849,7 +2188,14 @@ type FieldOptions struct { // implementation must either *always* check its required fields, or *never* // check its required fields, regardless of whether or not the message has // been parsed. + // + // As of May 2022, lazy verifies the contents of the byte stream during + // parsing. An invalid byte stream will cause the overall parsing to fail. Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"` + // unverified_lazy does no correctness checks on the byte stream. This should + // only be used where lazy with verification is prohibitive for performance + // reasons. + UnverifiedLazy *bool `protobuf:"varint,15,opt,name=unverified_lazy,json=unverifiedLazy,def=0" json:"unverified_lazy,omitempty"` // Is this field deprecated? // Depending on the target platform, this can emit Deprecated annotations // for accessors, or it will be completely ignored; in the very least, this @@ -1857,17 +2203,26 @@ type FieldOptions struct { Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // For Google-internal migration only. Do not use. Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` + // Indicate that the field value should not be printed out when using debug + // formats, e.g. when the field contains sensitive credentials. + DebugRedact *bool `protobuf:"varint,16,opt,name=debug_redact,json=debugRedact,def=0" json:"debug_redact,omitempty"` + Retention *FieldOptions_OptionRetention `protobuf:"varint,17,opt,name=retention,enum=google.protobuf.FieldOptions_OptionRetention" json:"retention,omitempty"` + // Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. + Target *FieldOptions_OptionTargetType `protobuf:"varint,18,opt,name=target,enum=google.protobuf.FieldOptions_OptionTargetType" json:"target,omitempty"` + Targets []FieldOptions_OptionTargetType `protobuf:"varint,19,rep,name=targets,enum=google.protobuf.FieldOptions_OptionTargetType" json:"targets,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` } // Default values for FieldOptions fields. const ( - Default_FieldOptions_Ctype = FieldOptions_STRING - Default_FieldOptions_Jstype = FieldOptions_JS_NORMAL - Default_FieldOptions_Lazy = bool(false) - Default_FieldOptions_Deprecated = bool(false) - Default_FieldOptions_Weak = bool(false) + Default_FieldOptions_Ctype = FieldOptions_STRING + Default_FieldOptions_Jstype = FieldOptions_JS_NORMAL + Default_FieldOptions_Lazy = bool(false) + Default_FieldOptions_UnverifiedLazy = bool(false) + Default_FieldOptions_Deprecated = bool(false) + Default_FieldOptions_Weak = bool(false) + Default_FieldOptions_DebugRedact = bool(false) ) func (x *FieldOptions) Reset() { @@ -1930,6 +2285,13 @@ func (x *FieldOptions) GetLazy() bool { return Default_FieldOptions_Lazy } +func (x *FieldOptions) GetUnverifiedLazy() bool { + if x != nil && x.UnverifiedLazy != nil { + return *x.UnverifiedLazy + } + return Default_FieldOptions_UnverifiedLazy +} + func (x *FieldOptions) GetDeprecated() bool { if x != nil && x.Deprecated != nil { return *x.Deprecated @@ -1944,6 +2306,35 @@ func (x *FieldOptions) GetWeak() bool { return Default_FieldOptions_Weak } +func (x *FieldOptions) GetDebugRedact() bool { + if x != nil && x.DebugRedact != nil { + return *x.DebugRedact + } + return Default_FieldOptions_DebugRedact +} + +func (x *FieldOptions) GetRetention() FieldOptions_OptionRetention { + if x != nil && x.Retention != nil { + return *x.Retention + } + return FieldOptions_RETENTION_UNKNOWN +} + +// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. +func (x *FieldOptions) GetTarget() FieldOptions_OptionTargetType { + if x != nil && x.Target != nil { + return *x.Target + } + return FieldOptions_TARGET_TYPE_UNKNOWN +} + +func (x *FieldOptions) GetTargets() []FieldOptions_OptionTargetType { + if x != nil { + return x.Targets + } + return nil +} + func (x *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { if x != nil { return x.UninterpretedOption @@ -2014,6 +2405,15 @@ type EnumOptions struct { // for the enum, or it will be completely ignored; in the very least, this // is a formalization for deprecating enums. Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enable the legacy handling of JSON field name conflicts. This lowercases + // and strips underscored from the fields before comparison in proto3 only. + // The new behavior takes `json_name` into account and applies to proto2 as + // well. + // TODO(b/261750190) Remove this legacy behavior once downstream teams have + // had time to migrate. + // + // Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. + DeprecatedLegacyJsonFieldConflicts *bool `protobuf:"varint,6,opt,name=deprecated_legacy_json_field_conflicts,json=deprecatedLegacyJsonFieldConflicts" json:"deprecated_legacy_json_field_conflicts,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` } @@ -2069,6 +2469,14 @@ func (x *EnumOptions) GetDeprecated() bool { return Default_EnumOptions_Deprecated } +// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. +func (x *EnumOptions) GetDeprecatedLegacyJsonFieldConflicts() bool { + if x != nil && x.DeprecatedLegacyJsonFieldConflicts != nil { + return *x.DeprecatedLegacyJsonFieldConflicts + } + return false +} + func (x *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { if x != nil { return x.UninterpretedOption @@ -2399,43 +2807,48 @@ type SourceCodeInfo struct { // tools. // // For example, say we have a file like: - // message Foo { - // optional string foo = 1; - // } + // + // message Foo { + // optional string foo = 1; + // } + // // Let's look at just the field definition: - // optional string foo = 1; - // ^ ^^ ^^ ^ ^^^ - // a bc de f ghi + // + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // // We have the following locations: - // span path represents - // [a,i) [ 4, 0, 2, 0 ] The whole field definition. - // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). - // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). - // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). - // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). // // Notes: - // - A location may refer to a repeated field itself (i.e. not to any - // particular index within it). This is used whenever a set of elements are - // logically enclosed in a single code segment. For example, an entire - // extend block (possibly containing multiple extension definitions) will - // have an outer location whose path refers to the "extensions" repeated - // field without an index. - // - Multiple locations may have the same path. This happens when a single - // logical declaration is spread out across multiple places. The most - // obvious example is the "extend" block again -- there may be multiple - // extend blocks in the same scope, each of which will have the same path. - // - A location's span is not always a subset of its parent's span. For - // example, the "extendee" of an extension declaration appears at the - // beginning of the "extend" block and is shared by all extensions within - // the block. - // - Just because a location's span is a subset of some other location's span - // does not mean that it is a descendant. For example, a "group" defines - // both a type and a field in a single declaration. Thus, the locations - // corresponding to the type and field and their components will overlap. - // - Code which tries to interpret locations should probably be designed to - // ignore those that it doesn't understand, as more types of locations could - // be recorded in the future. + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` } @@ -2651,6 +3064,108 @@ func (x *DescriptorProto_ReservedRange) GetEnd() int32 { return 0 } +type ExtensionRangeOptions_Declaration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The extension number declared within the extension range. + Number *int32 `protobuf:"varint,1,opt,name=number" json:"number,omitempty"` + // The fully-qualified name of the extension field. There must be a leading + // dot in front of the full name. + FullName *string `protobuf:"bytes,2,opt,name=full_name,json=fullName" json:"full_name,omitempty"` + // The fully-qualified type name of the extension field. Unlike + // Metadata.type, Declaration.type must have a leading dot for messages + // and enums. + Type *string `protobuf:"bytes,3,opt,name=type" json:"type,omitempty"` + // Deprecated. Please use "repeated". + // + // Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. + IsRepeated *bool `protobuf:"varint,4,opt,name=is_repeated,json=isRepeated" json:"is_repeated,omitempty"` + // If true, indicates that the number is reserved in the extension range, + // and any extension field with the number will fail to compile. Set this + // when a declared extension field is deleted. + Reserved *bool `protobuf:"varint,5,opt,name=reserved" json:"reserved,omitempty"` + // If true, indicates that the extension must be defined as repeated. + // Otherwise the extension must be defined as optional. + Repeated *bool `protobuf:"varint,6,opt,name=repeated" json:"repeated,omitempty"` +} + +func (x *ExtensionRangeOptions_Declaration) Reset() { + *x = ExtensionRangeOptions_Declaration{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_descriptor_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionRangeOptions_Declaration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionRangeOptions_Declaration) ProtoMessage() {} + +func (x *ExtensionRangeOptions_Declaration) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_descriptor_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionRangeOptions_Declaration.ProtoReflect.Descriptor instead. +func (*ExtensionRangeOptions_Declaration) Descriptor() ([]byte, []int) { + return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *ExtensionRangeOptions_Declaration) GetNumber() int32 { + if x != nil && x.Number != nil { + return *x.Number + } + return 0 +} + +func (x *ExtensionRangeOptions_Declaration) GetFullName() string { + if x != nil && x.FullName != nil { + return *x.FullName + } + return "" +} + +func (x *ExtensionRangeOptions_Declaration) GetType() string { + if x != nil && x.Type != nil { + return *x.Type + } + return "" +} + +// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto. +func (x *ExtensionRangeOptions_Declaration) GetIsRepeated() bool { + if x != nil && x.IsRepeated != nil { + return *x.IsRepeated + } + return false +} + +func (x *ExtensionRangeOptions_Declaration) GetReserved() bool { + if x != nil && x.Reserved != nil { + return *x.Reserved + } + return false +} + +func (x *ExtensionRangeOptions_Declaration) GetRepeated() bool { + if x != nil && x.Repeated != nil { + return *x.Repeated + } + return false +} + // Range of reserved numeric values. Reserved values may not be used by // entries in the same enum. Reserved ranges may not overlap. // @@ -2669,7 +3184,7 @@ type EnumDescriptorProto_EnumReservedRange struct { func (x *EnumDescriptorProto_EnumReservedRange) Reset() { *x = EnumDescriptorProto_EnumReservedRange{} if protoimpl.UnsafeEnabled { - mi := &file_google_protobuf_descriptor_proto_msgTypes[23] + mi := &file_google_protobuf_descriptor_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2682,7 +3197,7 @@ func (x *EnumDescriptorProto_EnumReservedRange) String() string { func (*EnumDescriptorProto_EnumReservedRange) ProtoMessage() {} func (x *EnumDescriptorProto_EnumReservedRange) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[23] + mi := &file_google_protobuf_descriptor_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2715,8 +3230,8 @@ func (x *EnumDescriptorProto_EnumReservedRange) GetEnd() int32 { // The name of the uninterpreted option. Each string represents a segment in // a dot-separated name. is_extension is true iff a segment represents an // extension (denoted with parentheses in options specs in .proto files). -// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents -// "foo.(bar.baz).qux". +// E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents +// "foo.(bar.baz).moo". type UninterpretedOption_NamePart struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2729,7 +3244,7 @@ type UninterpretedOption_NamePart struct { func (x *UninterpretedOption_NamePart) Reset() { *x = UninterpretedOption_NamePart{} if protoimpl.UnsafeEnabled { - mi := &file_google_protobuf_descriptor_proto_msgTypes[24] + mi := &file_google_protobuf_descriptor_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2742,7 +3257,7 @@ func (x *UninterpretedOption_NamePart) String() string { func (*UninterpretedOption_NamePart) ProtoMessage() {} func (x *UninterpretedOption_NamePart) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[24] + mi := &file_google_protobuf_descriptor_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2781,23 +3296,34 @@ type SourceCodeInfo_Location struct { // location. // // Each element is a field number or an index. They form a path from - // the root FileDescriptorProto to the place where the definition. For - // example, this path: - // [ 4, 3, 2, 7, 1 ] + // the root FileDescriptorProto to the place where the definition occurs. + // For example, this path: + // + // [ 4, 3, 2, 7, 1 ] + // // refers to: - // file.message_type(3) // 4, 3 - // .field(7) // 2, 7 - // .name() // 1 + // + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // // This is because FileDescriptorProto.message_type has field number 4: - // repeated DescriptorProto message_type = 4; + // + // repeated DescriptorProto message_type = 4; + // // and DescriptorProto.field has field number 2: - // repeated FieldDescriptorProto field = 2; + // + // repeated FieldDescriptorProto field = 2; + // // and FieldDescriptorProto.name has field number 1: - // optional string name = 1; + // + // optional string name = 1; // // Thus, the above path gives the location of a field name. If we removed // the last element: - // [ 4, 3, 2, 7 ] + // + // [ 4, 3, 2, 7 ] + // // this path refers to the whole field declaration (from the beginning // of the label to the terminating semicolon). Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` @@ -2826,34 +3352,34 @@ type SourceCodeInfo_Location struct { // // Examples: // - // optional int32 foo = 1; // Comment attached to foo. - // // Comment attached to bar. - // optional int32 bar = 2; + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; // - // optional string baz = 3; - // // Comment attached to baz. - // // Another line attached to baz. + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. // - // // Comment attached to qux. - // // - // // Another line attached to qux. - // optional double qux = 4; + // // Comment attached to moo. + // // + // // Another line attached to moo. + // optional double moo = 4; // - // // Detached comment for corge. This is not leading or trailing comments - // // to qux or corge because there are blank lines separating it from - // // both. + // // Detached comment for corge. This is not leading or trailing comments + // // to moo or corge because there are blank lines separating it from + // // both. // - // // Detached comment for corge paragraph 2. + // // Detached comment for corge paragraph 2. // - // optional string corge = 5; - // /* Block comment attached - // * to corge. Leading asterisks - // * will be removed. */ - // /* Block comment attached to - // * grault. */ - // optional int32 grault = 6; + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; // - // // ignored detached comments. + // // ignored detached comments. LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` @@ -2862,7 +3388,7 @@ type SourceCodeInfo_Location struct { func (x *SourceCodeInfo_Location) Reset() { *x = SourceCodeInfo_Location{} if protoimpl.UnsafeEnabled { - mi := &file_google_protobuf_descriptor_proto_msgTypes[25] + mi := &file_google_protobuf_descriptor_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2875,7 +3401,7 @@ func (x *SourceCodeInfo_Location) String() string { func (*SourceCodeInfo_Location) ProtoMessage() {} func (x *SourceCodeInfo_Location) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[25] + mi := &file_google_protobuf_descriptor_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2940,15 +3466,16 @@ type GeneratedCodeInfo_Annotation struct { // that relates to the identified object. Begin *int32 `protobuf:"varint,3,opt,name=begin" json:"begin,omitempty"` // Identifies the ending offset in bytes in the generated code that - // relates to the identified offset. The end offset should be one past + // relates to the identified object. The end offset should be one past // the last relevant byte (so the length of the text = end - begin). - End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + Semantic *GeneratedCodeInfo_Annotation_Semantic `protobuf:"varint,5,opt,name=semantic,enum=google.protobuf.GeneratedCodeInfo_Annotation_Semantic" json:"semantic,omitempty"` } func (x *GeneratedCodeInfo_Annotation) Reset() { *x = GeneratedCodeInfo_Annotation{} if protoimpl.UnsafeEnabled { - mi := &file_google_protobuf_descriptor_proto_msgTypes[26] + mi := &file_google_protobuf_descriptor_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2961,7 +3488,7 @@ func (x *GeneratedCodeInfo_Annotation) String() string { func (*GeneratedCodeInfo_Annotation) ProtoMessage() {} func (x *GeneratedCodeInfo_Annotation) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_descriptor_proto_msgTypes[26] + mi := &file_google_protobuf_descriptor_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3005,6 +3532,13 @@ func (x *GeneratedCodeInfo_Annotation) GetEnd() int32 { return 0 } +func (x *GeneratedCodeInfo_Annotation) GetSemantic() GeneratedCodeInfo_Annotation_Semantic { + if x != nil && x.Semantic != nil { + return *x.Semantic + } + return GeneratedCodeInfo_Annotation_NONE +} + var File_google_protobuf_descriptor_proto protoreflect.FileDescriptor var file_google_protobuf_descriptor_proto_rawDesc = []byte{ @@ -3016,7 +3550,7 @@ var file_google_protobuf_descriptor_proto_rawDesc = []byte{ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x04, 0x66, 0x69, - 0x6c, 0x65, 0x22, 0xe4, 0x04, 0x0a, 0x13, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x6c, 0x65, 0x22, 0xfe, 0x04, 0x0a, 0x13, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -3054,330 +3588,423 @@ var file_google_protobuf_descriptor_proto_rawDesc = []byte{ 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x22, 0xb9, 0x06, 0x0a, 0x0f, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x43, - 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, - 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x09, 0x52, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x06, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x43, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, + 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x64, 0x65, 0x63, - 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, - 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x63, 0x6c, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, + 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, - 0x1a, 0x7a, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x37, 0x0a, 0x0d, - 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x7c, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, - 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, - 0x80, 0x80, 0x02, 0x22, 0xc1, 0x06, 0x0a, 0x14, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3e, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x64, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x64, 0x65, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x6e, 0x65, - 0x6f, 0x66, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, - 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, - 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, - 0x73, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0xb6, 0x02, 0x0a, 0x04, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, - 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, - 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x36, - 0x34, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, - 0x36, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, - 0x33, 0x32, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, - 0x45, 0x44, 0x36, 0x34, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, - 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, 0x12, 0x11, 0x0a, - 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x10, - 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, - 0x11, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x36, 0x34, - 0x10, 0x12, 0x22, 0x43, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x0e, 0x4c, - 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, - 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x50, - 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x22, 0x63, 0x0a, 0x14, 0x4f, 0x6e, 0x65, 0x6f, 0x66, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, + 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x44, + 0x65, 0x63, 0x6c, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, + 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x7a, 0x0a, 0x0e, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x03, 0x65, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x37, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, + 0xad, 0x04, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, + 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, + 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, 0x0b, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0x88, 0x01, + 0x02, 0x52, 0x0b, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x68, + 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x0a, + 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xb3, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x23, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x34, + 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x45, 0x43, 0x4c, 0x41, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x01, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, + 0xc1, 0x06, 0x0a, 0x14, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe3, 0x02, 0x0a, - 0x13, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, - 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x5d, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, - 0x65, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x11, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, - 0x6e, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0xb6, 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, + 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, + 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x02, 0x12, + 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x03, 0x12, + 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, + 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x05, + 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, + 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, + 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, + 0x4c, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, + 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, + 0x53, 0x41, 0x47, 0x45, 0x10, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, + 0x59, 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x10, 0x12, 0x0f, 0x0a, 0x0b, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x11, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x12, 0x22, 0x43, + 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, + 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4c, + 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, + 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x45, + 0x44, 0x10, 0x03, 0x22, 0x63, 0x0a, 0x14, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x13, 0x45, 0x6e, 0x75, + 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5d, 0x0a, + 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x1a, 0x3b, 0x0a, 0x11, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x83, + 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x16, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, - 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x89, 0x02, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x38, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x10, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x10, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x91, - 0x09, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, - 0x0a, 0x0c, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x61, 0x76, 0x61, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, - 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x12, 0x6a, 0x61, 0x76, 0x61, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x6a, 0x61, 0x76, 0x61, 0x4d, 0x75, 0x6c, - 0x74, 0x69, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x1d, 0x6a, 0x61, - 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x71, 0x75, 0x61, - 0x6c, 0x73, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x19, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x41, 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x3a, 0x0a, 0x16, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x74, 0x66, 0x38, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x74, 0x66, 0x38, 0x12, 0x53, 0x0a, 0x0c, - 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x05, 0x53, - 0x50, 0x45, 0x45, 0x44, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, - 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, - 0x12, 0x35, 0x0a, 0x13, 0x63, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x63, 0x63, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x15, 0x6a, 0x61, 0x76, 0x61, 0x5f, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, - 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x35, 0x0a, 0x13, 0x70, 0x79, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x70, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, - 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x14, 0x70, 0x68, 0x70, - 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x12, - 0x70, 0x68, 0x70, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x63, 0x5f, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x18, 0x1f, 0x20, - 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x63, 0x45, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x41, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x62, 0x6a, - 0x63, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x24, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x62, 0x6a, 0x63, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x73, 0x68, 0x61, 0x72, 0x70, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x63, 0x73, 0x68, 0x61, 0x72, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x18, 0x27, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x68, 0x70, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, - 0x68, 0x70, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, - 0x0d, 0x70, 0x68, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x29, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x68, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x68, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x2c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x14, 0x70, 0x68, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x62, 0x79, - 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x72, 0x75, 0x62, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x58, 0x0a, 0x14, 0x75, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, - 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x02, 0x12, - 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, - 0x03, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x26, - 0x10, 0x27, 0x22, 0xd1, 0x02, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x14, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x4c, 0x0a, 0x1f, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, - 0x72, 0x64, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x52, 0x1c, 0x6e, 0x6f, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, - 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x61, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, - 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, - 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0xe2, 0x03, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x06, 0x53, 0x54, 0x52, - 0x49, 0x4e, 0x47, 0x52, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, - 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x63, 0x6b, - 0x65, 0x64, 0x12, 0x47, 0x0a, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x06, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, + 0x02, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x91, 0x09, 0x0a, 0x0b, 0x46, + 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x61, + 0x76, 0x61, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x6a, 0x61, 0x76, 0x61, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, + 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6a, 0x61, 0x76, + 0x61, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x35, 0x0a, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, + 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x52, 0x11, 0x6a, 0x61, 0x76, 0x61, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x1d, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x5f, 0x61, + 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x19, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, + 0x71, 0x75, 0x61, 0x6c, 0x73, 0x41, 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3a, 0x0a, 0x16, + 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x75, 0x74, 0x66, 0x38, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x55, 0x74, 0x66, 0x38, 0x12, 0x53, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x69, + 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, + 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, + 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x1d, 0x0a, + 0x0a, 0x67, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x67, 0x6f, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x13, + 0x63, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x52, 0x11, 0x63, 0x63, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x15, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, + 0x0a, 0x13, 0x70, 0x79, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x52, 0x11, 0x70, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x14, 0x70, 0x68, 0x70, 0x5f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x2a, 0x20, + 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x12, 0x70, 0x68, 0x70, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, + 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x63, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x3a, + 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, + 0x72, 0x65, 0x6e, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x63, 0x5f, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x6f, 0x62, 0x6a, 0x63, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x73, 0x68, 0x61, 0x72, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x73, 0x68, + 0x61, 0x72, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x27, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, + 0x28, 0x0a, 0x10, 0x70, 0x68, 0x70, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x68, 0x70, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x68, 0x70, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x70, 0x68, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, + 0x0a, 0x16, 0x70, 0x68, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, + 0x70, 0x68, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x62, 0x79, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, + 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4c, + 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x03, 0x2a, 0x09, 0x08, + 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x22, 0xbb, + 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x3c, 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x14, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, + 0x4c, 0x0a, 0x1f, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, + 0x1c, 0x6e, 0x6f, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x25, 0x0a, + 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, + 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, + 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x85, 0x09, 0x0a, + 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, + 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x54, 0x79, 0x70, + 0x65, 0x3a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x52, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x06, 0x6a, 0x73, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x09, + 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x52, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x19, 0x0a, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, + 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x12, 0x2e, 0x0a, 0x0f, + 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x7a, 0x79, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0e, 0x75, 0x6e, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4c, 0x61, 0x7a, 0x79, 0x12, 0x25, 0x0a, 0x0a, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x28, + 0x0a, 0x0c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x62, + 0x75, 0x67, 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, + 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, + 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x48, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x13, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, - 0x4d, 0x41, 0x4c, 0x52, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x04, 0x6c, - 0x61, 0x7a, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x52, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, - 0x04, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x52, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, - 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, 0x52, 0x44, 0x10, - 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x49, 0x45, 0x43, - 0x45, 0x10, 0x02, 0x22, 0x35, 0x0a, 0x06, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, - 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, - 0x4a, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4a, - 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x02, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, - 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x73, 0x0a, 0x0c, 0x4f, - 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, + 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, - 0x22, 0xc0, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, - 0x05, 0x10, 0x06, 0x22, 0x9e, 0x01, 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, + 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, + 0x52, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, + 0x49, 0x45, 0x43, 0x45, 0x10, 0x02, 0x22, 0x35, 0x0a, 0x06, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, + 0x0d, 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x02, 0x22, 0x55, 0x0a, + 0x0f, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x14, + 0x0a, 0x10, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x10, 0x02, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, + 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x41, 0x52, 0x47, + 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, + 0x4e, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, + 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, + 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, + 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x4e, 0x45, 0x4f, 0x46, 0x10, 0x05, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, + 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x54, + 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, + 0x44, 0x10, 0x09, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x22, 0x73, 0x0a, 0x0c, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, + 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, + 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x98, 0x02, 0x0a, 0x0b, 0x45, 0x6e, + 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, + 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, + 0x08, 0x05, 0x10, 0x06, 0x22, 0x9e, 0x01, 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, + 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, + 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, + 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, @@ -3385,97 +4012,95 @@ var file_google_protobuf_descriptor_proto_rawDesc = []byte{ 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, - 0x80, 0x80, 0x80, 0x02, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, - 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x80, 0x80, 0x80, 0x02, 0x22, 0xe0, 0x02, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, + 0x11, 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, + 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x10, + 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, + 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x10, 0x49, 0x64, + 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x17, + 0x0a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4e, 0x4f, 0x5f, 0x53, 0x49, + 0x44, 0x45, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, + 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x2a, 0x09, 0x08, 0xe8, + 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9a, 0x03, 0x0a, 0x13, 0x55, 0x6e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, - 0x80, 0x80, 0x02, 0x22, 0xe0, 0x02, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x11, - 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, - 0x6c, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, - 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, - 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x10, 0x69, - 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, - 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, - 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, - 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x10, 0x49, 0x64, 0x65, - 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x17, 0x0a, - 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4e, 0x4f, 0x5f, 0x53, 0x49, 0x44, - 0x45, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, - 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x2a, 0x09, 0x08, 0xe8, 0x07, - 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9a, 0x03, 0x0a, 0x13, 0x55, 0x6e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, - 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, - 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, - 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, - 0x0a, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x4a, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x50, - 0x61, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, - 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x02, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, - 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xce, 0x01, 0x0a, - 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x16, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x42, - 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x65, 0x61, - 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, - 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x74, - 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x74, - 0x61, 0x63, 0x68, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd1, 0x01, - 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x4d, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0x6d, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, - 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x67, - 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x12, - 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, - 0x64, 0x42, 0x7e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, + 0x12, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6e, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x4a, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, + 0x50, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x02, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, + 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xce, 0x01, + 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x12, 0x16, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, + 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x65, + 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, + 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, + 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd0, + 0x02, 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4d, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0xeb, 0x01, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, + 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, + 0x65, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x65, 0x6e, 0x64, 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x52, 0x08, 0x73, + 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x22, 0x28, 0x0a, 0x08, 0x53, 0x65, 0x6d, 0x61, 0x6e, + 0x74, 0x69, 0x63, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, + 0x03, 0x53, 0x45, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x49, 0x41, 0x53, 0x10, + 0x02, 0x42, 0x7e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x48, 0x01, 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, @@ -3498,92 +4123,103 @@ func file_google_protobuf_descriptor_proto_rawDescGZIP() []byte { return file_google_protobuf_descriptor_proto_rawDescData } -var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 27) +var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 10) +var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 28) var file_google_protobuf_descriptor_proto_goTypes = []interface{}{ - (FieldDescriptorProto_Type)(0), // 0: google.protobuf.FieldDescriptorProto.Type - (FieldDescriptorProto_Label)(0), // 1: google.protobuf.FieldDescriptorProto.Label - (FileOptions_OptimizeMode)(0), // 2: google.protobuf.FileOptions.OptimizeMode - (FieldOptions_CType)(0), // 3: google.protobuf.FieldOptions.CType - (FieldOptions_JSType)(0), // 4: google.protobuf.FieldOptions.JSType - (MethodOptions_IdempotencyLevel)(0), // 5: google.protobuf.MethodOptions.IdempotencyLevel - (*FileDescriptorSet)(nil), // 6: google.protobuf.FileDescriptorSet - (*FileDescriptorProto)(nil), // 7: google.protobuf.FileDescriptorProto - (*DescriptorProto)(nil), // 8: google.protobuf.DescriptorProto - (*ExtensionRangeOptions)(nil), // 9: google.protobuf.ExtensionRangeOptions - (*FieldDescriptorProto)(nil), // 10: google.protobuf.FieldDescriptorProto - (*OneofDescriptorProto)(nil), // 11: google.protobuf.OneofDescriptorProto - (*EnumDescriptorProto)(nil), // 12: google.protobuf.EnumDescriptorProto - (*EnumValueDescriptorProto)(nil), // 13: google.protobuf.EnumValueDescriptorProto - (*ServiceDescriptorProto)(nil), // 14: google.protobuf.ServiceDescriptorProto - (*MethodDescriptorProto)(nil), // 15: google.protobuf.MethodDescriptorProto - (*FileOptions)(nil), // 16: google.protobuf.FileOptions - (*MessageOptions)(nil), // 17: google.protobuf.MessageOptions - (*FieldOptions)(nil), // 18: google.protobuf.FieldOptions - (*OneofOptions)(nil), // 19: google.protobuf.OneofOptions - (*EnumOptions)(nil), // 20: google.protobuf.EnumOptions - (*EnumValueOptions)(nil), // 21: google.protobuf.EnumValueOptions - (*ServiceOptions)(nil), // 22: google.protobuf.ServiceOptions - (*MethodOptions)(nil), // 23: google.protobuf.MethodOptions - (*UninterpretedOption)(nil), // 24: google.protobuf.UninterpretedOption - (*SourceCodeInfo)(nil), // 25: google.protobuf.SourceCodeInfo - (*GeneratedCodeInfo)(nil), // 26: google.protobuf.GeneratedCodeInfo - (*DescriptorProto_ExtensionRange)(nil), // 27: google.protobuf.DescriptorProto.ExtensionRange - (*DescriptorProto_ReservedRange)(nil), // 28: google.protobuf.DescriptorProto.ReservedRange - (*EnumDescriptorProto_EnumReservedRange)(nil), // 29: google.protobuf.EnumDescriptorProto.EnumReservedRange - (*UninterpretedOption_NamePart)(nil), // 30: google.protobuf.UninterpretedOption.NamePart - (*SourceCodeInfo_Location)(nil), // 31: google.protobuf.SourceCodeInfo.Location - (*GeneratedCodeInfo_Annotation)(nil), // 32: google.protobuf.GeneratedCodeInfo.Annotation + (ExtensionRangeOptions_VerificationState)(0), // 0: google.protobuf.ExtensionRangeOptions.VerificationState + (FieldDescriptorProto_Type)(0), // 1: google.protobuf.FieldDescriptorProto.Type + (FieldDescriptorProto_Label)(0), // 2: google.protobuf.FieldDescriptorProto.Label + (FileOptions_OptimizeMode)(0), // 3: google.protobuf.FileOptions.OptimizeMode + (FieldOptions_CType)(0), // 4: google.protobuf.FieldOptions.CType + (FieldOptions_JSType)(0), // 5: google.protobuf.FieldOptions.JSType + (FieldOptions_OptionRetention)(0), // 6: google.protobuf.FieldOptions.OptionRetention + (FieldOptions_OptionTargetType)(0), // 7: google.protobuf.FieldOptions.OptionTargetType + (MethodOptions_IdempotencyLevel)(0), // 8: google.protobuf.MethodOptions.IdempotencyLevel + (GeneratedCodeInfo_Annotation_Semantic)(0), // 9: google.protobuf.GeneratedCodeInfo.Annotation.Semantic + (*FileDescriptorSet)(nil), // 10: google.protobuf.FileDescriptorSet + (*FileDescriptorProto)(nil), // 11: google.protobuf.FileDescriptorProto + (*DescriptorProto)(nil), // 12: google.protobuf.DescriptorProto + (*ExtensionRangeOptions)(nil), // 13: google.protobuf.ExtensionRangeOptions + (*FieldDescriptorProto)(nil), // 14: google.protobuf.FieldDescriptorProto + (*OneofDescriptorProto)(nil), // 15: google.protobuf.OneofDescriptorProto + (*EnumDescriptorProto)(nil), // 16: google.protobuf.EnumDescriptorProto + (*EnumValueDescriptorProto)(nil), // 17: google.protobuf.EnumValueDescriptorProto + (*ServiceDescriptorProto)(nil), // 18: google.protobuf.ServiceDescriptorProto + (*MethodDescriptorProto)(nil), // 19: google.protobuf.MethodDescriptorProto + (*FileOptions)(nil), // 20: google.protobuf.FileOptions + (*MessageOptions)(nil), // 21: google.protobuf.MessageOptions + (*FieldOptions)(nil), // 22: google.protobuf.FieldOptions + (*OneofOptions)(nil), // 23: google.protobuf.OneofOptions + (*EnumOptions)(nil), // 24: google.protobuf.EnumOptions + (*EnumValueOptions)(nil), // 25: google.protobuf.EnumValueOptions + (*ServiceOptions)(nil), // 26: google.protobuf.ServiceOptions + (*MethodOptions)(nil), // 27: google.protobuf.MethodOptions + (*UninterpretedOption)(nil), // 28: google.protobuf.UninterpretedOption + (*SourceCodeInfo)(nil), // 29: google.protobuf.SourceCodeInfo + (*GeneratedCodeInfo)(nil), // 30: google.protobuf.GeneratedCodeInfo + (*DescriptorProto_ExtensionRange)(nil), // 31: google.protobuf.DescriptorProto.ExtensionRange + (*DescriptorProto_ReservedRange)(nil), // 32: google.protobuf.DescriptorProto.ReservedRange + (*ExtensionRangeOptions_Declaration)(nil), // 33: google.protobuf.ExtensionRangeOptions.Declaration + (*EnumDescriptorProto_EnumReservedRange)(nil), // 34: google.protobuf.EnumDescriptorProto.EnumReservedRange + (*UninterpretedOption_NamePart)(nil), // 35: google.protobuf.UninterpretedOption.NamePart + (*SourceCodeInfo_Location)(nil), // 36: google.protobuf.SourceCodeInfo.Location + (*GeneratedCodeInfo_Annotation)(nil), // 37: google.protobuf.GeneratedCodeInfo.Annotation } var file_google_protobuf_descriptor_proto_depIdxs = []int32{ - 7, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto - 8, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto - 12, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto - 14, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto - 10, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto - 16, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions - 25, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo - 10, // 7: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto - 10, // 8: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto - 8, // 9: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto - 12, // 10: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto - 27, // 11: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange - 11, // 12: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto - 17, // 13: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions - 28, // 14: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange - 24, // 15: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 1, // 16: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label - 0, // 17: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type - 18, // 18: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions - 19, // 19: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions - 13, // 20: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto - 20, // 21: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions - 29, // 22: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange - 21, // 23: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions - 15, // 24: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto - 22, // 25: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions - 23, // 26: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions - 2, // 27: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode - 24, // 28: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 24, // 29: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 3, // 30: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType - 4, // 31: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType - 24, // 32: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 24, // 33: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 24, // 34: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 24, // 35: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 24, // 36: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 5, // 37: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel - 24, // 38: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption - 30, // 39: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart - 31, // 40: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location - 32, // 41: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation - 9, // 42: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions - 43, // [43:43] is the sub-list for method output_type - 43, // [43:43] is the sub-list for method input_type - 43, // [43:43] is the sub-list for extension type_name - 43, // [43:43] is the sub-list for extension extendee - 0, // [0:43] is the sub-list for field type_name + 11, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto + 12, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto + 16, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto + 18, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto + 14, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto + 20, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions + 29, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo + 14, // 7: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto + 14, // 8: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto + 12, // 9: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto + 16, // 10: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto + 31, // 11: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange + 15, // 12: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto + 21, // 13: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions + 32, // 14: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange + 28, // 15: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 33, // 16: google.protobuf.ExtensionRangeOptions.declaration:type_name -> google.protobuf.ExtensionRangeOptions.Declaration + 0, // 17: google.protobuf.ExtensionRangeOptions.verification:type_name -> google.protobuf.ExtensionRangeOptions.VerificationState + 2, // 18: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label + 1, // 19: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type + 22, // 20: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions + 23, // 21: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions + 17, // 22: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto + 24, // 23: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions + 34, // 24: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange + 25, // 25: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions + 19, // 26: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto + 26, // 27: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions + 27, // 28: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions + 3, // 29: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode + 28, // 30: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 28, // 31: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 4, // 32: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType + 5, // 33: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType + 6, // 34: google.protobuf.FieldOptions.retention:type_name -> google.protobuf.FieldOptions.OptionRetention + 7, // 35: google.protobuf.FieldOptions.target:type_name -> google.protobuf.FieldOptions.OptionTargetType + 7, // 36: google.protobuf.FieldOptions.targets:type_name -> google.protobuf.FieldOptions.OptionTargetType + 28, // 37: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 28, // 38: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 28, // 39: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 28, // 40: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 28, // 41: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 8, // 42: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel + 28, // 43: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption + 35, // 44: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart + 36, // 45: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location + 37, // 46: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation + 13, // 47: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions + 9, // 48: google.protobuf.GeneratedCodeInfo.Annotation.semantic:type_name -> google.protobuf.GeneratedCodeInfo.Annotation.Semantic + 49, // [49:49] is the sub-list for method output_type + 49, // [49:49] is the sub-list for method input_type + 49, // [49:49] is the sub-list for extension type_name + 49, // [49:49] is the sub-list for extension extendee + 0, // [0:49] is the sub-list for field type_name } func init() { file_google_protobuf_descriptor_proto_init() } @@ -3887,7 +4523,7 @@ func file_google_protobuf_descriptor_proto_init() { } } file_google_protobuf_descriptor_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnumDescriptorProto_EnumReservedRange); i { + switch v := v.(*ExtensionRangeOptions_Declaration); i { case 0: return &v.state case 1: @@ -3899,7 +4535,7 @@ func file_google_protobuf_descriptor_proto_init() { } } file_google_protobuf_descriptor_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UninterpretedOption_NamePart); i { + switch v := v.(*EnumDescriptorProto_EnumReservedRange); i { case 0: return &v.state case 1: @@ -3911,7 +4547,7 @@ func file_google_protobuf_descriptor_proto_init() { } } file_google_protobuf_descriptor_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceCodeInfo_Location); i { + switch v := v.(*UninterpretedOption_NamePart); i { case 0: return &v.state case 1: @@ -3923,6 +4559,18 @@ func file_google_protobuf_descriptor_proto_init() { } } file_google_protobuf_descriptor_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SourceCodeInfo_Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_descriptor_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GeneratedCodeInfo_Annotation); i { case 0: return &v.state @@ -3940,8 +4588,8 @@ func file_google_protobuf_descriptor_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_protobuf_descriptor_proto_rawDesc, - NumEnums: 6, - NumMessages: 27, + NumEnums: 10, + NumMessages: 28, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/google.golang.org/protobuf/types/dynamicpb/types.go b/vendor/google.golang.org/protobuf/types/dynamicpb/types.go new file mode 100644 index 00000000000..5a8010f18fa --- /dev/null +++ b/vendor/google.golang.org/protobuf/types/dynamicpb/types.go @@ -0,0 +1,177 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dynamicpb + +import ( + "fmt" + "strings" + "sync" + "sync/atomic" + + "google.golang.org/protobuf/internal/errors" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +type extField struct { + name protoreflect.FullName + number protoreflect.FieldNumber +} + +// A Types is a collection of dynamically constructed descriptors. +// Its methods are safe for concurrent use. +// +// Types implements protoregistry.MessageTypeResolver and protoregistry.ExtensionTypeResolver. +// A Types may be used as a proto.UnmarshalOptions.Resolver. +type Types struct { + files *protoregistry.Files + + extMu sync.Mutex + atomicExtFiles uint64 + extensionsByMessage map[extField]protoreflect.ExtensionDescriptor +} + +// NewTypes creates a new Types registry with the provided files. +// The Files registry is retained, and changes to Files will be reflected in Types. +// It is not safe to concurrently change the Files while calling Types methods. +func NewTypes(f *protoregistry.Files) *Types { + return &Types{ + files: f, + } +} + +// FindEnumByName looks up an enum by its full name; +// e.g., "google.protobuf.Field.Kind". +// +// This returns (nil, protoregistry.NotFound) if not found. +func (t *Types) FindEnumByName(name protoreflect.FullName) (protoreflect.EnumType, error) { + d, err := t.files.FindDescriptorByName(name) + if err != nil { + return nil, err + } + ed, ok := d.(protoreflect.EnumDescriptor) + if !ok { + return nil, errors.New("found wrong type: got %v, want enum", descName(d)) + } + return NewEnumType(ed), nil +} + +// FindExtensionByName looks up an extension field by the field's full name. +// Note that this is the full name of the field as determined by +// where the extension is declared and is unrelated to the full name of the +// message being extended. +// +// This returns (nil, protoregistry.NotFound) if not found. +func (t *Types) FindExtensionByName(name protoreflect.FullName) (protoreflect.ExtensionType, error) { + d, err := t.files.FindDescriptorByName(name) + if err != nil { + return nil, err + } + xd, ok := d.(protoreflect.ExtensionDescriptor) + if !ok { + return nil, errors.New("found wrong type: got %v, want extension", descName(d)) + } + return NewExtensionType(xd), nil +} + +// FindExtensionByNumber looks up an extension field by the field number +// within some parent message, identified by full name. +// +// This returns (nil, protoregistry.NotFound) if not found. +func (t *Types) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + // Construct the extension number map lazily, since not every user will need it. + // Update the map if new files are added to the registry. + if atomic.LoadUint64(&t.atomicExtFiles) != uint64(t.files.NumFiles()) { + t.updateExtensions() + } + xd := t.extensionsByMessage[extField{message, field}] + if xd == nil { + return nil, protoregistry.NotFound + } + return NewExtensionType(xd), nil +} + +// FindMessageByName looks up a message by its full name; +// e.g. "google.protobuf.Any". +// +// This returns (nil, protoregistry.NotFound) if not found. +func (t *Types) FindMessageByName(name protoreflect.FullName) (protoreflect.MessageType, error) { + d, err := t.files.FindDescriptorByName(name) + if err != nil { + return nil, err + } + md, ok := d.(protoreflect.MessageDescriptor) + if !ok { + return nil, errors.New("found wrong type: got %v, want message", descName(d)) + } + return NewMessageType(md), nil +} + +// FindMessageByURL looks up a message by a URL identifier. +// See documentation on google.protobuf.Any.type_url for the URL format. +// +// This returns (nil, protoregistry.NotFound) if not found. +func (t *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) { + // This function is similar to FindMessageByName but + // truncates anything before and including '/' in the URL. + message := protoreflect.FullName(url) + if i := strings.LastIndexByte(url, '/'); i >= 0 { + message = message[i+len("/"):] + } + return t.FindMessageByName(message) +} + +func (t *Types) updateExtensions() { + t.extMu.Lock() + defer t.extMu.Unlock() + if atomic.LoadUint64(&t.atomicExtFiles) == uint64(t.files.NumFiles()) { + return + } + defer atomic.StoreUint64(&t.atomicExtFiles, uint64(t.files.NumFiles())) + t.files.RangeFiles(func(fd protoreflect.FileDescriptor) bool { + t.registerExtensions(fd.Extensions()) + t.registerExtensionsInMessages(fd.Messages()) + return true + }) +} + +func (t *Types) registerExtensionsInMessages(mds protoreflect.MessageDescriptors) { + count := mds.Len() + for i := 0; i < count; i++ { + md := mds.Get(i) + t.registerExtensions(md.Extensions()) + t.registerExtensionsInMessages(md.Messages()) + } +} + +func (t *Types) registerExtensions(xds protoreflect.ExtensionDescriptors) { + count := xds.Len() + for i := 0; i < count; i++ { + xd := xds.Get(i) + field := xd.Number() + message := xd.ContainingMessage().FullName() + if t.extensionsByMessage == nil { + t.extensionsByMessage = make(map[extField]protoreflect.ExtensionDescriptor) + } + t.extensionsByMessage[extField{message, field}] = xd + } +} + +func descName(d protoreflect.Descriptor) string { + switch d.(type) { + case protoreflect.EnumDescriptor: + return "enum" + case protoreflect.EnumValueDescriptor: + return "enum value" + case protoreflect.MessageDescriptor: + return "message" + case protoreflect.ExtensionDescriptor: + return "extension" + case protoreflect.ServiceDescriptor: + return "service" + default: + return fmt.Sprintf("%T", d) + } +} diff --git a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go index 8c10797b905..580b232f477 100644 --- a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go @@ -37,8 +37,7 @@ // It is functionally a tuple of the full name of the remote message type and // the serialized bytes of the remote message value. // -// -// Constructing an Any +// # Constructing an Any // // An Any message containing another message value is constructed using New: // @@ -48,8 +47,7 @@ // } // ... // make use of any // -// -// Unmarshaling an Any +// # Unmarshaling an Any // // With a populated Any message, the underlying message can be serialized into // a remote concrete message value in a few ways. @@ -95,8 +93,7 @@ // listed in the case clauses are linked into the Go binary and therefore also // registered in the global registry. // -// -// Type checking an Any +// # Type checking an Any // // In order to type check whether an Any message represents some other message, // then use the MessageIs method: @@ -115,7 +112,6 @@ // } // ... // make use of m // } -// package anypb import ( @@ -136,45 +132,49 @@ import ( // // Example 1: Pack and unpack a message in C++. // -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } // // Example 2: Pack and unpack a message in Java. // -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := anypb.New(foo) -// if err != nil { -// ... -// } -// ... -// foo := &pb.Foo{} -// if err := any.UnmarshalTo(foo); err != nil { -// ... -// } +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// // or ... +// if (any.isSameTypeAs(Foo.getDefaultInstance())) { +// foo = any.unpack(Foo.getDefaultInstance()); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } // // The pack methods provided by protobuf library will by default use // 'type.googleapis.com/full.type.name' as the type URL and the unpack @@ -182,35 +182,33 @@ import ( // in the type URL, for example "foo.bar.com/x/y.z" will yield type // name "y.z". // -// // JSON // ==== // The JSON representation of an `Any` value uses the regular // representation of the deserialized, embedded message, with an // additional field `@type` which contains the type URL. Example: // -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } // -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } // // If the embedded message type is well-known and has a custom JSON // representation, that representation will be embedded adding a field // `value` which holds the custom JSON in addition to the `@type` // field. Example (for message [google.protobuf.Duration][]): // -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } type Any struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -228,14 +226,14 @@ type Any struct { // scheme `http`, `https`, or no scheme, one can optionally set up a type // server that maps type URLs to message definitions as follows: // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) + // - If no scheme is provided, `https` is assumed. + // - An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // - Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) // // Note: this functionality is not currently available in the official // protobuf release, and it is not used for type URLs beginning with @@ -243,7 +241,6 @@ type Any struct { // // Schemes other than `http`, `https` (or the empty scheme) might be // used with implementation specific semantics. - // TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` // Must be a valid serialized protocol buffer of the above specified type. Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` diff --git a/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go b/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go index a583ca2f6c7..df709a8dd4c 100644 --- a/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go @@ -35,8 +35,7 @@ // // The Duration message represents a signed span of time. // -// -// Conversion to a Go Duration +// # Conversion to a Go Duration // // The AsDuration method can be used to convert a Duration message to a // standard Go time.Duration value: @@ -65,15 +64,13 @@ // the resulting value to the closest representable value (e.g., math.MaxInt64 // for positive overflow and math.MinInt64 for negative overflow). // -// -// Conversion from a Go Duration +// # Conversion from a Go Duration // // The durationpb.New function can be used to construct a Duration message // from a standard Go time.Duration value: // // dur := durationpb.New(d) // ... // make use of d as a *durationpb.Duration -// package durationpb import ( @@ -96,43 +93,43 @@ import ( // // Example 1: Compute Duration from two Timestamps in pseudo code. // -// Timestamp start = ...; -// Timestamp end = ...; -// Duration duration = ...; +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; // -// duration.seconds = end.seconds - start.seconds; -// duration.nanos = end.nanos - start.nanos; +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; // -// if (duration.seconds < 0 && duration.nanos > 0) { -// duration.seconds += 1; -// duration.nanos -= 1000000000; -// } else if (duration.seconds > 0 && duration.nanos < 0) { -// duration.seconds -= 1; -// duration.nanos += 1000000000; -// } +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } // // Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. // -// Timestamp start = ...; -// Duration duration = ...; -// Timestamp end = ...; +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; // -// end.seconds = start.seconds + duration.seconds; -// end.nanos = start.nanos + duration.nanos; +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; // -// if (end.nanos < 0) { -// end.seconds -= 1; -// end.nanos += 1000000000; -// } else if (end.nanos >= 1000000000) { -// end.seconds += 1; -// end.nanos -= 1000000000; -// } +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } // // Example 3: Compute Duration from datetime.timedelta in Python. // -// td = datetime.timedelta(days=3, minutes=10) -// duration = Duration() -// duration.FromTimedelta(td) +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) // // # JSON Mapping // @@ -143,8 +140,6 @@ import ( // encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should // be expressed in JSON format as "3.000000001s", and 3 seconds and 1 // microsecond should be expressed in JSON format as "3.000001s". -// -// type Duration struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go b/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go index e7fcea31f62..9a7277ba394 100644 --- a/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go @@ -44,11 +44,9 @@ import ( // empty messages in your APIs. A typical example is to use it as the request // or the response type of an API method. For instance: // -// service Foo { -// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); -// } -// -// The JSON representation for `Empty` is empty JSON object `{}`. +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } type Empty struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go index 1b2085d4690..e8789cb331e 100644 --- a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go @@ -37,8 +37,7 @@ // The paths are specific to some target message type, // which is not stored within the FieldMask message itself. // -// -// Constructing a FieldMask +// # Constructing a FieldMask // // The New function is used construct a FieldMask: // @@ -61,8 +60,7 @@ // ... // handle error // } // -// -// Type checking a FieldMask +// # Type checking a FieldMask // // In order to verify that a FieldMask represents a set of fields that are // reachable from some target message type, use the IsValid method: @@ -89,8 +87,8 @@ import ( // `FieldMask` represents a set of symbolic field paths, for example: // -// paths: "f.a" -// paths: "f.b.d" +// paths: "f.a" +// paths: "f.b.d" // // Here `f` represents a field in some root message, `a` and `b` // fields in the message found in `f`, and `d` a field found in the @@ -107,27 +105,26 @@ import ( // specified in the mask. For example, if the mask in the previous // example is applied to a response message as follows: // -// f { -// a : 22 -// b { -// d : 1 -// x : 2 -// } -// y : 13 -// } -// z: 8 +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 // // The result will not contain specific values for fields x,y and z // (their value will be set to the default, and omitted in proto text // output): // -// -// f { -// a : 22 -// b { -// d : 1 -// } -// } +// f { +// a : 22 +// b { +// d : 1 +// } +// } // // A repeated field is not allowed except at the last position of a // paths string. @@ -165,36 +162,36 @@ import ( // // For example, given the target message: // -// f { -// b { -// d: 1 -// x: 2 -// } -// c: [1] -// } +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } // // And an update message: // -// f { -// b { -// d: 10 -// } -// c: [2] -// } +// f { +// b { +// d: 10 +// } +// c: [2] +// } // // then if the field mask is: // -// paths: ["f.b", "f.c"] +// paths: ["f.b", "f.c"] // // then the result will be: // -// f { -// b { -// d: 10 -// x: 2 -// } -// c: [1, 2] -// } +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } // // An implementation may provide options to override this default behavior for // repeated and message fields. @@ -232,51 +229,51 @@ import ( // // As an example, consider the following message declarations: // -// message Profile { -// User user = 1; -// Photo photo = 2; -// } -// message User { -// string display_name = 1; -// string address = 2; -// } +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } // // In proto a field mask for `Profile` may look as such: // -// mask { -// paths: "user.display_name" -// paths: "photo" -// } +// mask { +// paths: "user.display_name" +// paths: "photo" +// } // // In JSON, the same mask is represented as below: // -// { -// mask: "user.displayName,photo" -// } +// { +// mask: "user.displayName,photo" +// } // // # Field Masks and Oneof Fields // // Field masks treat fields in oneofs just as regular fields. Consider the // following message: // -// message SampleMessage { -// oneof test_oneof { -// string name = 4; -// SubMessage sub_message = 9; -// } -// } +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } // // The field mask can be: // -// mask { -// paths: "name" -// } +// mask { +// paths: "name" +// } // // Or: // -// mask { -// paths: "sub_message" -// } +// mask { +// paths: "sub_message" +// } // // Note that oneof type names ("test_oneof" in this case) cannot be used in // paths. diff --git a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go index 586690522a4..d2bac8b88ea 100644 --- a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go @@ -44,8 +44,7 @@ // "google.golang.org/protobuf/encoding/protojson" package // ensures that they will be serialized as their JSON equivalent. // -// -// Conversion to and from a Go interface +// # Conversion to and from a Go interface // // The standard Go "encoding/json" package has functionality to serialize // arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and @@ -58,8 +57,7 @@ // forms back as Value, Struct, and ListValue messages, use the NewStruct, // NewList, and NewValue constructor functions. // -// -// Example usage +// # Example usage // // Consider the following example JSON object: // @@ -118,7 +116,6 @@ // ... // handle error // } // ... // make use of m as a *structpb.Value -// package structpb import ( @@ -135,7 +132,7 @@ import ( // `NullValue` is a singleton enumeration to represent the null value for the // `Value` type union. // -// The JSON representation for `NullValue` is JSON `null`. +// The JSON representation for `NullValue` is JSON `null`. type NullValue int32 const ( @@ -218,8 +215,9 @@ func NewStruct(v map[string]interface{}) (*Struct, error) { // AsMap converts x to a general-purpose Go map. // The map values are converted by calling Value.AsInterface. func (x *Struct) AsMap() map[string]interface{} { - vs := make(map[string]interface{}) - for k, v := range x.GetFields() { + f := x.GetFields() + vs := make(map[string]interface{}, len(f)) + for k, v := range f { vs[k] = v.AsInterface() } return vs @@ -274,8 +272,8 @@ func (x *Struct) GetFields() map[string]*Value { // `Value` represents a dynamically typed value which can be either // null, a number, a string, a boolean, a recursive struct value, or a -// list of values. A producer of value is expected to set one of that -// variants, absence of any variant indicates an error. +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. // // The JSON representation for `Value` is JSON value. type Value struct { @@ -286,6 +284,7 @@ type Value struct { // The kind of value. // // Types that are assignable to Kind: + // // *Value_NullValue // *Value_NumberValue // *Value_StringValue @@ -596,8 +595,9 @@ func NewList(v []interface{}) (*ListValue, error) { // AsSlice converts x to a general-purpose Go slice. // The slice elements are converted by calling Value.AsInterface. func (x *ListValue) AsSlice() []interface{} { - vs := make([]interface{}, len(x.GetValues())) - for i, v := range x.GetValues() { + vals := x.GetValues() + vs := make([]interface{}, len(vals)) + for i, v := range vals { vs[i] = v.AsInterface() } return vs diff --git a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go index c9ae92132aa..81511a3363e 100644 --- a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go @@ -36,8 +36,7 @@ // The Timestamp message represents a timestamp, // an instant in time since the Unix epoch (January 1st, 1970). // -// -// Conversion to a Go Time +// # Conversion to a Go Time // // The AsTime method can be used to convert a Timestamp message to a // standard Go time.Time value in UTC: @@ -59,8 +58,7 @@ // ... // handle error // } // -// -// Conversion from a Go Time +// # Conversion from a Go Time // // The timestamppb.New function can be used to construct a Timestamp message // from a standard Go time.Time value: @@ -72,7 +70,6 @@ // // ts := timestamppb.Now() // ... // make use of ts as a *timestamppb.Timestamp -// package timestamppb import ( @@ -101,52 +98,50 @@ import ( // // Example 1: Compute Timestamp from POSIX `time()`. // -// Timestamp timestamp; -// timestamp.set_seconds(time(NULL)); -// timestamp.set_nanos(0); +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); // // Example 2: Compute Timestamp from POSIX `gettimeofday()`. // -// struct timeval tv; -// gettimeofday(&tv, NULL); +// struct timeval tv; +// gettimeofday(&tv, NULL); // -// Timestamp timestamp; -// timestamp.set_seconds(tv.tv_sec); -// timestamp.set_nanos(tv.tv_usec * 1000); +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); // // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. // -// FILETIME ft; -// GetSystemTimeAsFileTime(&ft); -// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; // -// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z -// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. -// Timestamp timestamp; -// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); -// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); // // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. // -// long millis = System.currentTimeMillis(); -// -// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) -// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// long millis = System.currentTimeMillis(); // +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); // // Example 5: Compute Timestamp from Java `Instant.now()`. // -// Instant now = Instant.now(); -// -// Timestamp timestamp = -// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) -// .setNanos(now.getNano()).build(); +// Instant now = Instant.now(); // +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); // // Example 6: Compute Timestamp from current time in Python. // -// timestamp = Timestamp() -// timestamp.GetCurrentTime() +// timestamp = Timestamp() +// timestamp.GetCurrentTime() // // # JSON Mapping // @@ -172,10 +167,8 @@ import ( // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use // the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() // ) to obtain a formatter capable of generating timestamps in this format. -// -// type Timestamp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go index 895a8049e22..762a87130f8 100644 --- a/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go @@ -27,7 +27,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +// // Wrappers for primitive (non-message) types. These types are useful // for embedding primitives in the `google.protobuf.Any` type and for places // where we need to distinguish between the absence of a primitive diff --git a/vendor/gopkg.in/tomb.v1/LICENSE b/vendor/gopkg.in/tomb.v1/LICENSE deleted file mode 100644 index a4249bb31dd..00000000000 --- a/vendor/gopkg.in/tomb.v1/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -tomb - support for clean goroutine termination in Go. - -Copyright (c) 2010-2011 - Gustavo Niemeyer - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gopkg.in/tomb.v1/README.md b/vendor/gopkg.in/tomb.v1/README.md deleted file mode 100644 index 3ae8788e813..00000000000 --- a/vendor/gopkg.in/tomb.v1/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Installation and usage ----------------------- - -See [gopkg.in/tomb.v1](https://gopkg.in/tomb.v1) for documentation and usage details. diff --git a/vendor/gopkg.in/tomb.v1/tomb.go b/vendor/gopkg.in/tomb.v1/tomb.go deleted file mode 100644 index 9aec56d821d..00000000000 --- a/vendor/gopkg.in/tomb.v1/tomb.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) 2011 - Gustavo Niemeyer -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The tomb package offers a conventional API for clean goroutine termination. -// -// A Tomb tracks the lifecycle of a goroutine as alive, dying or dead, -// and the reason for its death. -// -// The zero value of a Tomb assumes that a goroutine is about to be -// created or already alive. Once Kill or Killf is called with an -// argument that informs the reason for death, the goroutine is in -// a dying state and is expected to terminate soon. Right before the -// goroutine function or method returns, Done must be called to inform -// that the goroutine is indeed dead and about to stop running. -// -// A Tomb exposes Dying and Dead channels. These channels are closed -// when the Tomb state changes in the respective way. They enable -// explicit blocking until the state changes, and also to selectively -// unblock select statements accordingly. -// -// When the tomb state changes to dying and there's still logic going -// on within the goroutine, nested functions and methods may choose to -// return ErrDying as their error value, as this error won't alter the -// tomb state if provided to the Kill method. This is a convenient way to -// follow standard Go practices in the context of a dying tomb. -// -// For background and a detailed example, see the following blog post: -// -// http://blog.labix.org/2011/10/09/death-of-goroutines-under-control -// -// For a more complex code snippet demonstrating the use of multiple -// goroutines with a single Tomb, see: -// -// http://play.golang.org/p/Xh7qWsDPZP -// -package tomb - -import ( - "errors" - "fmt" - "sync" -) - -// A Tomb tracks the lifecycle of a goroutine as alive, dying or dead, -// and the reason for its death. -// -// See the package documentation for details. -type Tomb struct { - m sync.Mutex - dying chan struct{} - dead chan struct{} - reason error -} - -var ( - ErrStillAlive = errors.New("tomb: still alive") - ErrDying = errors.New("tomb: dying") -) - -func (t *Tomb) init() { - t.m.Lock() - if t.dead == nil { - t.dead = make(chan struct{}) - t.dying = make(chan struct{}) - t.reason = ErrStillAlive - } - t.m.Unlock() -} - -// Dead returns the channel that can be used to wait -// until t.Done has been called. -func (t *Tomb) Dead() <-chan struct{} { - t.init() - return t.dead -} - -// Dying returns the channel that can be used to wait -// until t.Kill or t.Done has been called. -func (t *Tomb) Dying() <-chan struct{} { - t.init() - return t.dying -} - -// Wait blocks until the goroutine is in a dead state and returns the -// reason for its death. -func (t *Tomb) Wait() error { - t.init() - <-t.dead - t.m.Lock() - reason := t.reason - t.m.Unlock() - return reason -} - -// Done flags the goroutine as dead, and should be called a single time -// right before the goroutine function or method returns. -// If the goroutine was not already in a dying state before Done is -// called, it will be flagged as dying and dead at once with no -// error. -func (t *Tomb) Done() { - t.Kill(nil) - close(t.dead) -} - -// Kill flags the goroutine as dying for the given reason. -// Kill may be called multiple times, but only the first -// non-nil error is recorded as the reason for termination. -// -// If reason is ErrDying, the previous reason isn't replaced -// even if it is nil. It's a runtime error to call Kill with -// ErrDying if t is not in a dying state. -func (t *Tomb) Kill(reason error) { - t.init() - t.m.Lock() - defer t.m.Unlock() - if reason == ErrDying { - if t.reason == ErrStillAlive { - panic("tomb: Kill with ErrDying while still alive") - } - return - } - if t.reason == nil || t.reason == ErrStillAlive { - t.reason = reason - } - // If the receive on t.dying succeeds, then - // it can only be because we have already closed it. - // If it blocks, then we know that it needs to be closed. - select { - case <-t.dying: - default: - close(t.dying) - } -} - -// Killf works like Kill, but builds the reason providing the received -// arguments to fmt.Errorf. The generated error is also returned. -func (t *Tomb) Killf(f string, a ...interface{}) error { - err := fmt.Errorf(f, a...) - t.Kill(err) - return err -} - -// Err returns the reason for the goroutine death provided via Kill -// or Killf, or ErrStillAlive when the goroutine is still alive. -func (t *Tomb) Err() (reason error) { - t.init() - t.m.Lock() - reason = t.reason - t.m.Unlock() - return -} diff --git a/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go index f81594c9123..1395a7e107b 100644 --- a/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AdmissionRequest = map[string]string{ diff --git a/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go index 13067ad80d5..82598ed5730 100644 --- a/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AdmissionRequest = map[string]string{ diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go index 6ac9e80ffca..9a2d0bccdda 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go @@ -44,10 +44,38 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_aaac5994f79683e8, []int{0} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} } func (*MutatingWebhook) ProtoMessage() {} func (*MutatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{0} + return fileDescriptor_aaac5994f79683e8, []int{1} } func (m *MutatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +103,7 @@ var xxx_messageInfo_MutatingWebhook proto.InternalMessageInfo func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} } func (*MutatingWebhookConfiguration) ProtoMessage() {} func (*MutatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{1} + return fileDescriptor_aaac5994f79683e8, []int{2} } func (m *MutatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +131,7 @@ var xxx_messageInfo_MutatingWebhookConfiguration proto.InternalMessageInfo func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} } func (*MutatingWebhookConfigurationList) ProtoMessage() {} func (*MutatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{2} + return fileDescriptor_aaac5994f79683e8, []int{3} } func (m *MutatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +159,7 @@ var xxx_messageInfo_MutatingWebhookConfigurationList proto.InternalMessageInfo func (m *Rule) Reset() { *m = Rule{} } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{3} + return fileDescriptor_aaac5994f79683e8, []int{4} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +187,7 @@ var xxx_messageInfo_Rule proto.InternalMessageInfo func (m *RuleWithOperations) Reset() { *m = RuleWithOperations{} } func (*RuleWithOperations) ProtoMessage() {} func (*RuleWithOperations) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{4} + return fileDescriptor_aaac5994f79683e8, []int{5} } func (m *RuleWithOperations) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -187,7 +215,7 @@ var xxx_messageInfo_RuleWithOperations proto.InternalMessageInfo func (m *ServiceReference) Reset() { *m = ServiceReference{} } func (*ServiceReference) ProtoMessage() {} func (*ServiceReference) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{5} + return fileDescriptor_aaac5994f79683e8, []int{6} } func (m *ServiceReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -215,7 +243,7 @@ var xxx_messageInfo_ServiceReference proto.InternalMessageInfo func (m *ValidatingWebhook) Reset() { *m = ValidatingWebhook{} } func (*ValidatingWebhook) ProtoMessage() {} func (*ValidatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{6} + return fileDescriptor_aaac5994f79683e8, []int{7} } func (m *ValidatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -243,7 +271,7 @@ var xxx_messageInfo_ValidatingWebhook proto.InternalMessageInfo func (m *ValidatingWebhookConfiguration) Reset() { *m = ValidatingWebhookConfiguration{} } func (*ValidatingWebhookConfiguration) ProtoMessage() {} func (*ValidatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{7} + return fileDescriptor_aaac5994f79683e8, []int{8} } func (m *ValidatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -271,7 +299,7 @@ var xxx_messageInfo_ValidatingWebhookConfiguration proto.InternalMessageInfo func (m *ValidatingWebhookConfigurationList) Reset() { *m = ValidatingWebhookConfigurationList{} } func (*ValidatingWebhookConfigurationList) ProtoMessage() {} func (*ValidatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{8} + return fileDescriptor_aaac5994f79683e8, []int{9} } func (m *ValidatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -299,7 +327,7 @@ var xxx_messageInfo_ValidatingWebhookConfigurationList proto.InternalMessageInfo func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } func (*WebhookClientConfig) ProtoMessage() {} func (*WebhookClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{9} + return fileDescriptor_aaac5994f79683e8, []int{10} } func (m *WebhookClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -325,6 +353,7 @@ func (m *WebhookClientConfig) XXX_DiscardUnknown() { var xxx_messageInfo_WebhookClientConfig proto.InternalMessageInfo func init() { + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1.MatchCondition") proto.RegisterType((*MutatingWebhook)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhook") proto.RegisterType((*MutatingWebhookConfiguration)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhookConfiguration") proto.RegisterType((*MutatingWebhookConfigurationList)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhookConfigurationList") @@ -342,79 +371,116 @@ func init() { } var fileDescriptor_aaac5994f79683e8 = []byte{ - // 1105 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0xc6, 0x76, 0x63, 0x8f, 0xf3, 0xa7, 0x19, 0xa0, 0x35, 0xa1, 0xf2, 0x5a, 0xae, 0x84, - 0x8c, 0x80, 0xdd, 0x26, 0x94, 0x52, 0x71, 0x41, 0xd9, 0xf0, 0x47, 0x11, 0x49, 0x1b, 0x4d, 0xda, - 0x14, 0xa1, 0x1c, 0x3a, 0x5e, 0x8f, 0xed, 0x21, 0xf6, 0xce, 0x6a, 0x66, 0xd6, 0x90, 0x1b, 0x1f, - 0x81, 0xaf, 0x00, 0x9f, 0x82, 0x1b, 0xe2, 0x96, 0x63, 0x8f, 0x39, 0xa0, 0x85, 0x2c, 0x17, 0x0e, - 0x7c, 0x82, 0x9c, 0xd0, 0xcc, 0xae, 0x77, 0xfd, 0x27, 0x09, 0x56, 0x0e, 0x3d, 0xe5, 0xe6, 0xf9, - 0xbd, 0x79, 0xbf, 0x37, 0xef, 0xed, 0x7b, 0xef, 0x27, 0x83, 0x9d, 0xa3, 0xc7, 0xc2, 0xa2, 0xcc, - 0x3e, 0x0a, 0x9a, 0x84, 0x7b, 0x44, 0x12, 0x61, 0x0f, 0x88, 0xd7, 0x62, 0xdc, 0x4e, 0x0c, 0xd8, - 0xa7, 0x36, 0x6e, 0xf5, 0xa9, 0x10, 0x94, 0x79, 0x9c, 0x74, 0xa8, 0x90, 0x1c, 0x4b, 0xca, 0x3c, - 0x7b, 0xb0, 0x6e, 0x77, 0x88, 0x47, 0x38, 0x96, 0xa4, 0x65, 0xf9, 0x9c, 0x49, 0x06, 0xef, 0xc7, - 0x4e, 0x16, 0xf6, 0xa9, 0x75, 0xa1, 0x93, 0x35, 0x58, 0x5f, 0xfb, 0xb0, 0x43, 0x65, 0x37, 0x68, - 0x5a, 0x2e, 0xeb, 0xdb, 0x1d, 0xd6, 0x61, 0xb6, 0xf6, 0x6d, 0x06, 0x6d, 0x7d, 0xd2, 0x07, 0xfd, - 0x2b, 0xe6, 0x5c, 0x7b, 0x98, 0x3d, 0xa4, 0x8f, 0xdd, 0x2e, 0xf5, 0x08, 0x3f, 0xb6, 0xfd, 0xa3, - 0x8e, 0x02, 0x84, 0xdd, 0x27, 0x12, 0x5f, 0xf0, 0x92, 0x35, 0xfb, 0x32, 0x2f, 0x1e, 0x78, 0x92, - 0xf6, 0xc9, 0x94, 0xc3, 0xa3, 0xff, 0x73, 0x10, 0x6e, 0x97, 0xf4, 0xf1, 0xa4, 0x5f, 0xfd, 0xb7, - 0x05, 0xb0, 0xb2, 0x1b, 0x48, 0x2c, 0xa9, 0xd7, 0x79, 0x41, 0x9a, 0x5d, 0xc6, 0x8e, 0x60, 0x0d, - 0xe4, 0x3d, 0xdc, 0x27, 0x15, 0xa3, 0x66, 0x34, 0x4a, 0xce, 0xe2, 0x49, 0x68, 0xce, 0x45, 0xa1, - 0x99, 0x7f, 0x82, 0xfb, 0x04, 0x69, 0x0b, 0xe4, 0x60, 0xd1, 0xed, 0x51, 0xe2, 0xc9, 0x2d, 0xe6, - 0xb5, 0x69, 0xa7, 0x32, 0x5f, 0x33, 0x1a, 0xe5, 0x8d, 0xc7, 0xd6, 0x0c, 0xf5, 0xb3, 0x92, 0x28, - 0x5b, 0x23, 0xfe, 0xce, 0x9b, 0x49, 0x8c, 0xc5, 0x51, 0x14, 0x8d, 0xc5, 0x80, 0x87, 0xa0, 0xc0, - 0x83, 0x1e, 0x11, 0x95, 0x5c, 0x2d, 0xd7, 0x28, 0x6f, 0x7c, 0x32, 0x53, 0x30, 0x14, 0xf4, 0xc8, - 0x0b, 0x2a, 0xbb, 0x4f, 0x7d, 0x12, 0x83, 0xc2, 0x59, 0x4a, 0x62, 0x15, 0x94, 0x4d, 0xa0, 0x98, - 0x14, 0xee, 0x80, 0xa5, 0x36, 0xa6, 0xbd, 0x80, 0x93, 0x3d, 0xd6, 0xa3, 0xee, 0x71, 0x25, 0xaf, - 0x93, 0x7f, 0x37, 0x0a, 0xcd, 0xa5, 0x2f, 0x47, 0x0d, 0xe7, 0xa1, 0xb9, 0x3a, 0x06, 0x3c, 0x3b, - 0xf6, 0x09, 0x1a, 0x77, 0x86, 0x9f, 0x83, 0x72, 0x1f, 0x4b, 0xb7, 0x9b, 0x70, 0x95, 0x34, 0x57, - 0x3d, 0x0a, 0xcd, 0xf2, 0x6e, 0x06, 0x9f, 0x87, 0xe6, 0xca, 0xc8, 0x51, 0xf3, 0x8c, 0xba, 0xc1, - 0x1f, 0xc0, 0xaa, 0xaa, 0xb6, 0xf0, 0xb1, 0x4b, 0xf6, 0x49, 0x8f, 0xb8, 0x92, 0xf1, 0x4a, 0x41, - 0x97, 0xfa, 0xa3, 0x91, 0xec, 0xd3, 0xef, 0x6d, 0xf9, 0x47, 0x1d, 0x05, 0x08, 0x4b, 0xb5, 0x95, - 0x4a, 0x7f, 0x07, 0x37, 0x49, 0x6f, 0xe8, 0xea, 0xbc, 0x15, 0x85, 0xe6, 0xea, 0x93, 0x49, 0x46, - 0x34, 0x1d, 0x04, 0x32, 0xb0, 0xcc, 0x9a, 0xdf, 0x11, 0x57, 0xa6, 0x61, 0xcb, 0xd7, 0x0f, 0x0b, - 0xa3, 0xd0, 0x5c, 0x7e, 0x3a, 0x46, 0x87, 0x26, 0xe8, 0x55, 0xc1, 0x04, 0x6d, 0x91, 0x2f, 0xda, - 0x6d, 0xe2, 0x4a, 0x51, 0xb9, 0x95, 0x15, 0x6c, 0x3f, 0x83, 0x55, 0xc1, 0xb2, 0xe3, 0x56, 0x0f, - 0x0b, 0x81, 0x46, 0xdd, 0xe0, 0xa7, 0x60, 0x59, 0xf5, 0x3a, 0x0b, 0xe4, 0x3e, 0x71, 0x99, 0xd7, - 0x12, 0x95, 0x85, 0x9a, 0xd1, 0x28, 0xc4, 0x2f, 0x78, 0x36, 0x66, 0x41, 0x13, 0x37, 0xe1, 0x73, - 0x70, 0x37, 0xed, 0x22, 0x44, 0x06, 0x94, 0x7c, 0x7f, 0x40, 0xb8, 0x3a, 0x88, 0x4a, 0xb1, 0x96, - 0x6b, 0x94, 0x9c, 0x77, 0xa2, 0xd0, 0xbc, 0xbb, 0x79, 0xf1, 0x15, 0x74, 0x99, 0x2f, 0x7c, 0x09, - 0x20, 0x27, 0xd4, 0x1b, 0x30, 0x57, 0xb7, 0x5f, 0xd2, 0x10, 0x40, 0xe7, 0xf7, 0x20, 0x0a, 0x4d, - 0x88, 0xa6, 0xac, 0xe7, 0xa1, 0x79, 0x67, 0x1a, 0xd5, 0xed, 0x71, 0x01, 0x57, 0xfd, 0xd4, 0x00, - 0xf7, 0x26, 0x26, 0x38, 0x9e, 0x98, 0x20, 0xee, 0x78, 0xf8, 0x12, 0x14, 0xd5, 0x87, 0x69, 0x61, - 0x89, 0xf5, 0x48, 0x97, 0x37, 0x1e, 0xcc, 0xf6, 0x19, 0xe3, 0x6f, 0xb6, 0x4b, 0x24, 0x76, 0x60, - 0x32, 0x34, 0x20, 0xc3, 0x50, 0xca, 0x0a, 0x0f, 0x40, 0x31, 0x89, 0x2c, 0x2a, 0xf3, 0x7a, 0x3a, - 0x1f, 0xce, 0x34, 0x9d, 0x13, 0xcf, 0x76, 0xf2, 0x2a, 0x0a, 0x4a, 0xb9, 0xea, 0xff, 0x18, 0xa0, - 0x76, 0x55, 0x6a, 0x3b, 0x54, 0x48, 0x78, 0x38, 0x95, 0x9e, 0x35, 0x63, 0x97, 0x52, 0x11, 0x27, - 0x77, 0x3b, 0x49, 0xae, 0x38, 0x44, 0x46, 0x52, 0x6b, 0x83, 0x02, 0x95, 0xa4, 0x3f, 0xcc, 0x6b, - 0xf3, 0x3a, 0x79, 0x8d, 0xbd, 0x39, 0xdb, 0x3f, 0xdb, 0x8a, 0x17, 0xc5, 0xf4, 0xf5, 0xdf, 0x0d, - 0x90, 0x57, 0x0b, 0x09, 0xbe, 0x0f, 0x4a, 0xd8, 0xa7, 0x5f, 0x71, 0x16, 0xf8, 0xa2, 0x62, 0xe8, - 0xce, 0x5b, 0x8a, 0x42, 0xb3, 0xb4, 0xb9, 0xb7, 0x1d, 0x83, 0x28, 0xb3, 0xc3, 0x75, 0x50, 0xc6, - 0x3e, 0x4d, 0x1b, 0x75, 0x5e, 0x5f, 0x5f, 0x51, 0x63, 0xb3, 0xb9, 0xb7, 0x9d, 0x36, 0xe7, 0xe8, - 0x1d, 0xc5, 0xcf, 0x89, 0x60, 0x01, 0x77, 0x93, 0x55, 0x9a, 0xf0, 0xa3, 0x21, 0x88, 0x32, 0x3b, - 0xfc, 0x00, 0x14, 0x84, 0xcb, 0x7c, 0x92, 0x6c, 0xc3, 0x3b, 0xea, 0xd9, 0xfb, 0x0a, 0x38, 0x0f, - 0xcd, 0x92, 0xfe, 0xa1, 0xdb, 0x32, 0xbe, 0x54, 0xff, 0xc5, 0x00, 0x70, 0x7a, 0xe1, 0xc2, 0xcf, - 0x00, 0x60, 0xe9, 0x29, 0x49, 0xc9, 0xd4, 0xbd, 0x94, 0xa2, 0xe7, 0xa1, 0xb9, 0x94, 0x9e, 0x34, - 0xe5, 0x88, 0x0b, 0xfc, 0x1a, 0xe4, 0xd5, 0x92, 0x4e, 0x54, 0xe6, 0xbd, 0x99, 0x17, 0x7f, 0x26, - 0x5d, 0xea, 0x84, 0x34, 0x49, 0xfd, 0x67, 0x03, 0xdc, 0xde, 0x27, 0x7c, 0x40, 0x5d, 0x82, 0x48, - 0x9b, 0x70, 0xe2, 0xb9, 0x04, 0xda, 0xa0, 0x94, 0x2e, 0xc1, 0x44, 0xf6, 0x56, 0x13, 0xdf, 0x52, - 0xba, 0x30, 0x51, 0x76, 0x27, 0x95, 0xc8, 0xf9, 0x4b, 0x25, 0xf2, 0x1e, 0xc8, 0xfb, 0x58, 0x76, - 0x2b, 0x39, 0x7d, 0xa3, 0xa8, 0xac, 0x7b, 0x58, 0x76, 0x91, 0x46, 0xb5, 0x95, 0x71, 0xa9, 0xeb, - 0x5a, 0x48, 0xac, 0x8c, 0x4b, 0xa4, 0xd1, 0xfa, 0x9f, 0xb7, 0xc0, 0xea, 0x01, 0xee, 0xd1, 0xd6, - 0x8d, 0x2c, 0xdf, 0xc8, 0xf2, 0x95, 0xb2, 0x0c, 0x6e, 0x64, 0xf9, 0x3a, 0xb2, 0x5c, 0xff, 0xc3, - 0x00, 0xd5, 0xa9, 0x09, 0x7b, 0xdd, 0xb2, 0xf9, 0xcd, 0x94, 0x6c, 0x3e, 0x9a, 0x69, 0x7a, 0xa6, - 0x1e, 0x3e, 0x25, 0x9c, 0xff, 0x1a, 0xa0, 0x7e, 0x75, 0x7a, 0xaf, 0x41, 0x3a, 0xbb, 0xe3, 0xd2, - 0xb9, 0x75, 0xbd, 0xdc, 0x66, 0x11, 0xcf, 0x5f, 0x0d, 0xf0, 0xc6, 0x05, 0xfb, 0x0b, 0xbe, 0x0d, - 0x72, 0x01, 0xef, 0x25, 0x2b, 0x78, 0x21, 0x0a, 0xcd, 0xdc, 0x73, 0xb4, 0x83, 0x14, 0x06, 0x0f, - 0xc1, 0x82, 0x88, 0x55, 0x20, 0xc9, 0xfc, 0xe3, 0x99, 0x9e, 0x37, 0xa9, 0x1c, 0x4e, 0x39, 0x0a, - 0xcd, 0x85, 0x21, 0x3a, 0xa4, 0x84, 0x0d, 0x50, 0x74, 0xb1, 0x13, 0x78, 0xad, 0x44, 0xb5, 0x16, - 0x9d, 0x45, 0x55, 0xa4, 0xad, 0xcd, 0x18, 0x43, 0xa9, 0xd5, 0xd9, 0x3e, 0x39, 0xab, 0xce, 0xbd, - 0x3a, 0xab, 0xce, 0x9d, 0x9e, 0x55, 0xe7, 0x7e, 0x8c, 0xaa, 0xc6, 0x49, 0x54, 0x35, 0x5e, 0x45, - 0x55, 0xe3, 0x34, 0xaa, 0x1a, 0x7f, 0x45, 0x55, 0xe3, 0xa7, 0xbf, 0xab, 0x73, 0xdf, 0xde, 0x9f, - 0xe1, 0xdf, 0xec, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x43, 0x44, 0x86, 0xf5, 0x0c, 0x0f, 0x00, + // 1169 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0x1b, 0x45, + 0x18, 0xce, 0xc6, 0x36, 0xb1, 0xc7, 0x4e, 0xd2, 0x0c, 0xd0, 0x2e, 0xa5, 0xf2, 0x5a, 0xae, 0x84, + 0x82, 0x00, 0x6f, 0x9b, 0x96, 0x52, 0x71, 0x41, 0xb1, 0x29, 0x28, 0x22, 0x69, 0xa3, 0x49, 0x3f, + 0x10, 0xea, 0xa1, 0xe3, 0xf5, 0xd8, 0x1e, 0x62, 0xef, 0xac, 0x66, 0x66, 0x4d, 0x7b, 0xe3, 0x27, + 0xf0, 0x17, 0xe0, 0x4f, 0xc0, 0x95, 0x5b, 0x8f, 0xbd, 0x91, 0x03, 0x5a, 0x91, 0xe5, 0xc2, 0x81, + 0x5f, 0x90, 0x13, 0x9a, 0xd9, 0xf5, 0xae, 0xbf, 0x12, 0x56, 0x39, 0xe4, 0x94, 0x5b, 0xe6, 0x79, + 0xdf, 0xf7, 0x79, 0xe7, 0x19, 0xbf, 0x1f, 0xab, 0x80, 0xdd, 0xc3, 0xfb, 0xa2, 0x41, 0x99, 0x7d, + 0xe8, 0xb7, 0x09, 0x77, 0x89, 0x24, 0xc2, 0x1e, 0x11, 0xb7, 0xc3, 0xb8, 0x1d, 0x1b, 0xb0, 0x47, + 0x6d, 0xdc, 0x19, 0x52, 0x21, 0x28, 0x73, 0x39, 0xe9, 0x51, 0x21, 0x39, 0x96, 0x94, 0xb9, 0xf6, + 0xe8, 0xb6, 0xdd, 0x23, 0x2e, 0xe1, 0x58, 0x92, 0x4e, 0xc3, 0xe3, 0x4c, 0x32, 0x78, 0x33, 0x0a, + 0x6a, 0x60, 0x8f, 0x36, 0x16, 0x06, 0x35, 0x46, 0xb7, 0xaf, 0x7f, 0xd2, 0xa3, 0xb2, 0xef, 0xb7, + 0x1b, 0x0e, 0x1b, 0xda, 0x3d, 0xd6, 0x63, 0xb6, 0x8e, 0x6d, 0xfb, 0x5d, 0x7d, 0xd2, 0x07, 0xfd, + 0x57, 0xc4, 0x79, 0xfd, 0x6e, 0x7a, 0x91, 0x21, 0x76, 0xfa, 0xd4, 0x25, 0xfc, 0x95, 0xed, 0x1d, + 0xf6, 0x14, 0x20, 0xec, 0x21, 0x91, 0x78, 0xc1, 0x4d, 0xae, 0xdb, 0xa7, 0x45, 0x71, 0xdf, 0x95, + 0x74, 0x48, 0xe6, 0x02, 0xee, 0xfd, 0x5f, 0x80, 0x70, 0xfa, 0x64, 0x88, 0x67, 0xe3, 0xea, 0x5d, + 0xb0, 0xb6, 0x87, 0xa5, 0xd3, 0x6f, 0x31, 0xb7, 0x43, 0x95, 0x44, 0x58, 0x03, 0x79, 0x17, 0x0f, + 0x89, 0x69, 0xd4, 0x8c, 0xcd, 0x52, 0xb3, 0xf2, 0x3a, 0xb0, 0x96, 0xc2, 0xc0, 0xca, 0x3f, 0xc4, + 0x43, 0x82, 0xb4, 0x05, 0x6e, 0x01, 0x40, 0x5e, 0x7a, 0x9c, 0xe8, 0xe7, 0x31, 0x97, 0xb5, 0x1f, + 0x8c, 0xfd, 0xc0, 0x83, 0xc4, 0x82, 0x26, 0xbc, 0xea, 0xbf, 0x16, 0xc1, 0xfa, 0x9e, 0x2f, 0xb1, + 0xa4, 0x6e, 0xef, 0x19, 0x69, 0xf7, 0x19, 0x3b, 0xcc, 0x90, 0x89, 0x83, 0x8a, 0x33, 0xa0, 0xc4, + 0x95, 0x2d, 0xe6, 0x76, 0x69, 0x4f, 0xe7, 0x2a, 0x6f, 0xdd, 0x6f, 0x64, 0xf8, 0x9d, 0x1a, 0x71, + 0x96, 0xd6, 0x44, 0x7c, 0xf3, 0x9d, 0x38, 0x47, 0x65, 0x12, 0x45, 0x53, 0x39, 0xe0, 0x73, 0x50, + 0xe0, 0xfe, 0x80, 0x08, 0x33, 0x57, 0xcb, 0x6d, 0x96, 0xb7, 0x3e, 0xcb, 0x94, 0x0c, 0xf9, 0x03, + 0xf2, 0x8c, 0xca, 0xfe, 0x23, 0x8f, 0x44, 0xa0, 0x68, 0xae, 0xc6, 0xb9, 0x0a, 0xca, 0x26, 0x50, + 0x44, 0x0a, 0x77, 0xc1, 0x6a, 0x17, 0xd3, 0x81, 0xcf, 0xc9, 0x3e, 0x1b, 0x50, 0xe7, 0x95, 0x99, + 0xd7, 0xe2, 0x3f, 0x08, 0x03, 0x6b, 0xf5, 0xab, 0x49, 0xc3, 0x49, 0x60, 0x6d, 0x4c, 0x01, 0x8f, + 0x5f, 0x79, 0x04, 0x4d, 0x07, 0xc3, 0x2f, 0x41, 0x79, 0xa8, 0x7e, 0xbd, 0x98, 0xab, 0xa4, 0xb9, + 0xea, 0x61, 0x60, 0x95, 0xf7, 0x52, 0xf8, 0x24, 0xb0, 0xd6, 0x27, 0x8e, 0x9a, 0x67, 0x32, 0x0c, + 0xbe, 0x04, 0x1b, 0xea, 0xb5, 0x85, 0x87, 0x1d, 0x72, 0x40, 0x06, 0xc4, 0x91, 0x8c, 0x9b, 0x05, + 0xfd, 0xd4, 0x77, 0x26, 0xd4, 0x27, 0x75, 0xd5, 0xf0, 0x0e, 0x7b, 0x0a, 0x10, 0x0d, 0x55, 0xbe, + 0x4a, 0xfe, 0x2e, 0x6e, 0x93, 0xc1, 0x38, 0xb4, 0xf9, 0x6e, 0x18, 0x58, 0x1b, 0x0f, 0x67, 0x19, + 0xd1, 0x7c, 0x12, 0xc8, 0xc0, 0x1a, 0x6b, 0x7f, 0x4f, 0x1c, 0x99, 0xa4, 0x2d, 0x9f, 0x3f, 0x2d, + 0x0c, 0x03, 0x6b, 0xed, 0xd1, 0x14, 0x1d, 0x9a, 0xa1, 0x57, 0x0f, 0x26, 0x68, 0x87, 0x3c, 0xe8, + 0x76, 0x89, 0x23, 0x85, 0xf9, 0x56, 0xfa, 0x60, 0x07, 0x29, 0xac, 0x1e, 0x2c, 0x3d, 0xb6, 0x06, + 0x58, 0x08, 0x34, 0x19, 0x06, 0x3f, 0x07, 0x6b, 0xaa, 0xa7, 0x98, 0x2f, 0x0f, 0x88, 0xc3, 0xdc, + 0x8e, 0x30, 0x57, 0x6a, 0xc6, 0x66, 0x21, 0xba, 0xc1, 0xe3, 0x29, 0x0b, 0x9a, 0xf1, 0x84, 0x4f, + 0xc0, 0xb5, 0xa4, 0x8a, 0x10, 0x19, 0x51, 0xf2, 0xc3, 0x53, 0xc2, 0xd5, 0x41, 0x98, 0xc5, 0x5a, + 0x6e, 0xb3, 0xd4, 0x7c, 0x3f, 0x0c, 0xac, 0x6b, 0xdb, 0x8b, 0x5d, 0xd0, 0x69, 0xb1, 0xf0, 0x05, + 0x80, 0x9c, 0x50, 0x77, 0xc4, 0x1c, 0x5d, 0x7e, 0x71, 0x41, 0x00, 0xad, 0xef, 0x56, 0x18, 0x58, + 0x10, 0xcd, 0x59, 0x4f, 0x02, 0xeb, 0xea, 0x3c, 0xaa, 0xcb, 0x63, 0x01, 0x17, 0x1c, 0x81, 0xf5, + 0xe1, 0xd4, 0xa4, 0x10, 0x66, 0x45, 0x77, 0xc8, 0x9d, 0x4c, 0x1d, 0x32, 0x3d, 0x65, 0x9a, 0xd7, + 0xe2, 0xee, 0x58, 0x9f, 0xc6, 0x05, 0x9a, 0x4d, 0x52, 0x3f, 0x32, 0xc0, 0x8d, 0x99, 0xc9, 0x11, + 0x75, 0xaa, 0x1f, 0x91, 0xc3, 0x17, 0xa0, 0xa8, 0x0a, 0xa2, 0x83, 0x25, 0xd6, 0xa3, 0xa4, 0xbc, + 0x75, 0x2b, 0x5b, 0xf9, 0x44, 0xb5, 0xb2, 0x47, 0x24, 0x4e, 0xc7, 0x57, 0x8a, 0xa1, 0x84, 0x15, + 0x3e, 0x05, 0xc5, 0x38, 0xb3, 0x30, 0x97, 0xb5, 0xe6, 0xbb, 0xd9, 0x34, 0x4f, 0x5f, 0xbb, 0x99, + 0x57, 0x59, 0x50, 0xc2, 0x55, 0xff, 0xc7, 0x00, 0xb5, 0xb3, 0xa4, 0xed, 0x52, 0x21, 0xe1, 0xf3, + 0x39, 0x79, 0x8d, 0x8c, 0xdd, 0x41, 0x45, 0x24, 0xee, 0x4a, 0x2c, 0xae, 0x38, 0x46, 0x26, 0xa4, + 0x75, 0x41, 0x81, 0x4a, 0x32, 0x1c, 0xeb, 0xda, 0x3e, 0x8f, 0xae, 0xa9, 0x3b, 0xa7, 0x73, 0x6f, + 0x47, 0xf1, 0xa2, 0x88, 0xbe, 0xfe, 0xbb, 0x01, 0xf2, 0x6a, 0x10, 0xc2, 0x8f, 0x40, 0x09, 0x7b, + 0xf4, 0x6b, 0xce, 0x7c, 0x4f, 0x98, 0x86, 0xae, 0xf8, 0xd5, 0x30, 0xb0, 0x4a, 0xdb, 0xfb, 0x3b, + 0x11, 0x88, 0x52, 0x3b, 0xbc, 0x0d, 0xca, 0xd8, 0xa3, 0x49, 0x83, 0x2c, 0x6b, 0xf7, 0x75, 0xd5, + 0xae, 0xdb, 0xfb, 0x3b, 0x49, 0x53, 0x4c, 0xfa, 0x28, 0x7e, 0x4e, 0x04, 0xf3, 0xb9, 0x13, 0x8f, + 0xf0, 0x98, 0x1f, 0x8d, 0x41, 0x94, 0xda, 0xe1, 0xc7, 0xa0, 0x20, 0x1c, 0xe6, 0x91, 0x78, 0x0a, + 0x5f, 0x55, 0xd7, 0x3e, 0x50, 0xc0, 0x49, 0x60, 0x95, 0xf4, 0x1f, 0xba, 0x1d, 0x22, 0xa7, 0xfa, + 0x2f, 0x06, 0x80, 0xf3, 0x83, 0x1e, 0x7e, 0x01, 0x00, 0x4b, 0x4e, 0xb1, 0x24, 0x4b, 0xd7, 0x52, + 0x82, 0x9e, 0x04, 0xd6, 0x6a, 0x72, 0xd2, 0x94, 0x13, 0x21, 0xf0, 0x1b, 0x90, 0x57, 0xcb, 0x21, + 0xde, 0x6e, 0x1f, 0x66, 0x5e, 0x38, 0xe9, 0xca, 0x54, 0x27, 0xa4, 0x49, 0xea, 0x3f, 0x1b, 0xe0, + 0xca, 0x01, 0xe1, 0x23, 0xea, 0x10, 0x44, 0xba, 0x84, 0x13, 0xd7, 0x21, 0xd0, 0x06, 0xa5, 0x64, + 0xf8, 0xc6, 0xeb, 0x76, 0x23, 0x8e, 0x2d, 0x25, 0x83, 0x1a, 0xa5, 0x3e, 0xc9, 0x6a, 0x5e, 0x3e, + 0x75, 0x35, 0xdf, 0x00, 0x79, 0x0f, 0xcb, 0xbe, 0x99, 0xd3, 0x1e, 0x45, 0x65, 0xdd, 0xc7, 0xb2, + 0x8f, 0x34, 0xaa, 0xad, 0x8c, 0x4b, 0xfd, 0xae, 0x85, 0xd8, 0xca, 0xb8, 0x44, 0x1a, 0xad, 0xff, + 0xb1, 0x02, 0x36, 0x9e, 0xe2, 0x01, 0xed, 0x5c, 0x7e, 0x0e, 0x5c, 0x7e, 0x0e, 0x9c, 0xf9, 0x39, + 0x00, 0x2e, 0x3f, 0x07, 0xce, 0xf5, 0x39, 0xb0, 0x60, 0x59, 0x97, 0x2f, 0x62, 0x59, 0xff, 0x69, + 0x80, 0xea, 0x5c, 0x67, 0x5f, 0xf4, 0xba, 0xfe, 0x76, 0x6e, 0x5d, 0xdf, 0xcb, 0xa4, 0x7a, 0xee, + 0xe2, 0x73, 0x0b, 0xfb, 0x5f, 0x03, 0xd4, 0xcf, 0x96, 0x77, 0x01, 0x2b, 0xbb, 0x3f, 0xbd, 0xb2, + 0x5b, 0xe7, 0xd3, 0x96, 0x65, 0x69, 0xff, 0x66, 0x80, 0xb7, 0x17, 0xcc, 0x4d, 0xf8, 0x1e, 0xc8, + 0xf9, 0x7c, 0x10, 0x8f, 0xfe, 0x95, 0x30, 0xb0, 0x72, 0x4f, 0xd0, 0x2e, 0x52, 0x18, 0x7c, 0x0e, + 0x56, 0x44, 0xb4, 0x7d, 0x62, 0xe5, 0x9f, 0x66, 0xba, 0xde, 0xec, 0xc6, 0x6a, 0x96, 0xc3, 0xc0, + 0x5a, 0x19, 0xa3, 0x63, 0x4a, 0xb8, 0x09, 0x8a, 0x0e, 0x6e, 0xfa, 0x6e, 0x27, 0xde, 0x96, 0x95, + 0x66, 0x45, 0x3d, 0x52, 0x6b, 0x3b, 0xc2, 0x50, 0x62, 0x6d, 0xee, 0xbc, 0x3e, 0xae, 0x2e, 0xbd, + 0x39, 0xae, 0x2e, 0x1d, 0x1d, 0x57, 0x97, 0x7e, 0x0c, 0xab, 0xc6, 0xeb, 0xb0, 0x6a, 0xbc, 0x09, + 0xab, 0xc6, 0x51, 0x58, 0x35, 0xfe, 0x0a, 0xab, 0xc6, 0x4f, 0x7f, 0x57, 0x97, 0xbe, 0xbb, 0x99, + 0xe1, 0xbf, 0x04, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7f, 0xe1, 0x3a, 0x73, 0x64, 0x10, 0x00, 0x00, } +func (m *MatchCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -435,6 +501,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -791,6 +871,20 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -1036,6 +1130,19 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *MutatingWebhook) Size() (n int) { if m == nil { return 0 @@ -1085,6 +1192,12 @@ func (m *MutatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1235,6 +1348,12 @@ func (m *ValidatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1299,6 +1418,17 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *MutatingWebhook) String() string { if this == nil { return "nil" @@ -1308,6 +1438,11 @@ func (this *MutatingWebhook) String() string { repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&MutatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1320,6 +1455,7 @@ func (this *MutatingWebhook) String() string { `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1402,6 +1538,11 @@ func (this *ValidatingWebhook) String() string { repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&ValidatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1413,6 +1554,7 @@ func (this *ValidatingWebhook) String() string { `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1469,6 +1611,120 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } +func (m *MatchCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1853,6 +2109,40 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2920,6 +3210,40 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1/generated.proto index a53605b588c..cdf1f47655f 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.proto @@ -28,6 +28,35 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1"; +// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { // The name of the admission webhook. @@ -173,6 +202,28 @@ message MutatingWebhook { // Defaults to "Never". // +optional optional string reinvocationPolicy = 10; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 12; } // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. @@ -205,11 +256,13 @@ message Rule { // APIGroups is the API groups the resources belong to. '*' is all groups. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic repeated string apiGroups = 1; // APIVersions is the API versions the resources belong to. '*' is all versions. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic repeated string apiVersions = 2; // Resources is a list of resources this rule applies to. @@ -227,6 +280,7 @@ message Rule { // // Depending on the enclosing object, subresources might not be allowed. // Required. + // +listType=atomic repeated string resources = 3; // scope specifies the scope of this rule. @@ -249,6 +303,7 @@ message RuleWithOperations { // for all of those operations and any future admission operations that are added. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic repeated string operations = 1; // Rule is embedded, it describes other criteria of the rule, like @@ -405,6 +460,28 @@ message ValidatingWebhook { // include any versions known to the API Server, calls to the webhook will fail // and be subject to the failure policy. repeated string admissionReviewVersions = 8; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 11; } // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. diff --git a/vendor/k8s.io/api/admissionregistration/v1/types.go b/vendor/k8s.io/api/admissionregistration/v1/types.go index 29873b796bb..74f17d54a2b 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types.go @@ -26,11 +26,13 @@ type Rule struct { // APIGroups is the API groups the resources belong to. '*' is all groups. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"` // APIVersions is the API versions the resources belong to. '*' is all versions. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,2,rep,name=apiVersions"` // Resources is a list of resources this rule applies to. @@ -48,6 +50,7 @@ type Rule struct { // // Depending on the enclosing object, subresources might not be allowed. // Required. + // +listType=atomic Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` // scope specifies the scope of this rule. @@ -304,6 +307,28 @@ type ValidatingWebhook struct { // include any versions known to the API Server, calls to the webhook will fail // and be subject to the failure policy. AdmissionReviewVersions []string `json:"admissionReviewVersions" protobuf:"bytes,8,rep,name=admissionReviewVersions"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,opt,name=matchConditions"` } // MutatingWebhook describes an admission webhook and the resources and operations it applies to. @@ -451,6 +476,28 @@ type MutatingWebhook struct { // Defaults to "Never". // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,opt,name=matchConditions"` } // ReinvocationPolicyType specifies what type of policy the admission hook uses. @@ -474,6 +521,7 @@ type RuleWithOperations struct { // for all of those operations and any future admission operations that are added. // If '*' is present, the length of the slice must be one. // Required. + // +listType=atomic Operations []OperationType `json:"operations,omitempty" protobuf:"bytes,1,rep,name=operations,casttype=OperationType"` // Rule is embedded, it describes other criteria of the rule, like // APIGroups, APIVersions, Resources, etc. @@ -559,3 +607,32 @@ type ServiceReference struct { // +optional Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"` } + +// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. +type MatchCondition struct { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + Expression string `json:"expression" protobuf:"bytes,2,opt,name=expression"` +} diff --git a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go index ba92729c3c5..ce306b307a8 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go @@ -24,9 +24,19 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_MatchCondition = map[string]string{ + "": "MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.", + "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", +} + +func (MatchCondition) SwaggerDoc() map[string]string { + return map_MatchCondition +} + var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", @@ -40,6 +50,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -111,6 +122,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go index cff7377a557..b9560991384 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go @@ -26,6 +26,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = *in @@ -77,6 +93,11 @@ func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = new(ReinvocationPolicyType) **out = **in } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } @@ -286,6 +307,11 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go new file mode 100644 index 00000000000..385c60e0d3f --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +groupName=admissionregistration.k8s.io + +// Package v1alpha1 is the v1alpha1 version of the API. +package v1alpha1 // import "k8s.io/api/admissionregistration/v1alpha1" diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go new file mode 100644 index 00000000000..7465350263b --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go @@ -0,0 +1,4269 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto + +package v1alpha1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *AuditAnnotation) Reset() { *m = AuditAnnotation{} } +func (*AuditAnnotation) ProtoMessage() {} +func (*AuditAnnotation) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{0} +} +func (m *AuditAnnotation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AuditAnnotation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *AuditAnnotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_AuditAnnotation.Merge(m, src) +} +func (m *AuditAnnotation) XXX_Size() int { + return m.Size() +} +func (m *AuditAnnotation) XXX_DiscardUnknown() { + xxx_messageInfo_AuditAnnotation.DiscardUnknown(m) +} + +var xxx_messageInfo_AuditAnnotation proto.InternalMessageInfo + +func (m *ExpressionWarning) Reset() { *m = ExpressionWarning{} } +func (*ExpressionWarning) ProtoMessage() {} +func (*ExpressionWarning) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{1} +} +func (m *ExpressionWarning) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ExpressionWarning) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ExpressionWarning) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExpressionWarning.Merge(m, src) +} +func (m *ExpressionWarning) XXX_Size() int { + return m.Size() +} +func (m *ExpressionWarning) XXX_DiscardUnknown() { + xxx_messageInfo_ExpressionWarning.DiscardUnknown(m) +} + +var xxx_messageInfo_ExpressionWarning proto.InternalMessageInfo + +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{2} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + +func (m *MatchResources) Reset() { *m = MatchResources{} } +func (*MatchResources) ProtoMessage() {} +func (*MatchResources) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{3} +} +func (m *MatchResources) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchResources) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MatchResources) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchResources.Merge(m, src) +} +func (m *MatchResources) XXX_Size() int { + return m.Size() +} +func (m *MatchResources) XXX_DiscardUnknown() { + xxx_messageInfo_MatchResources.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchResources proto.InternalMessageInfo + +func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} } +func (*NamedRuleWithOperations) ProtoMessage() {} +func (*NamedRuleWithOperations) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{4} +} +func (m *NamedRuleWithOperations) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NamedRuleWithOperations) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NamedRuleWithOperations) XXX_Merge(src proto.Message) { + xxx_messageInfo_NamedRuleWithOperations.Merge(m, src) +} +func (m *NamedRuleWithOperations) XXX_Size() int { + return m.Size() +} +func (m *NamedRuleWithOperations) XXX_DiscardUnknown() { + xxx_messageInfo_NamedRuleWithOperations.DiscardUnknown(m) +} + +var xxx_messageInfo_NamedRuleWithOperations proto.InternalMessageInfo + +func (m *ParamKind) Reset() { *m = ParamKind{} } +func (*ParamKind) ProtoMessage() {} +func (*ParamKind) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{5} +} +func (m *ParamKind) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ParamKind) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ParamKind) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParamKind.Merge(m, src) +} +func (m *ParamKind) XXX_Size() int { + return m.Size() +} +func (m *ParamKind) XXX_DiscardUnknown() { + xxx_messageInfo_ParamKind.DiscardUnknown(m) +} + +var xxx_messageInfo_ParamKind proto.InternalMessageInfo + +func (m *ParamRef) Reset() { *m = ParamRef{} } +func (*ParamRef) ProtoMessage() {} +func (*ParamRef) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{6} +} +func (m *ParamRef) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ParamRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ParamRef) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParamRef.Merge(m, src) +} +func (m *ParamRef) XXX_Size() int { + return m.Size() +} +func (m *ParamRef) XXX_DiscardUnknown() { + xxx_messageInfo_ParamRef.DiscardUnknown(m) +} + +var xxx_messageInfo_ParamRef proto.InternalMessageInfo + +func (m *TypeChecking) Reset() { *m = TypeChecking{} } +func (*TypeChecking) ProtoMessage() {} +func (*TypeChecking) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{7} +} +func (m *TypeChecking) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TypeChecking) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *TypeChecking) XXX_Merge(src proto.Message) { + xxx_messageInfo_TypeChecking.Merge(m, src) +} +func (m *TypeChecking) XXX_Size() int { + return m.Size() +} +func (m *TypeChecking) XXX_DiscardUnknown() { + xxx_messageInfo_TypeChecking.DiscardUnknown(m) +} + +var xxx_messageInfo_TypeChecking proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicy) Reset() { *m = ValidatingAdmissionPolicy{} } +func (*ValidatingAdmissionPolicy) ProtoMessage() {} +func (*ValidatingAdmissionPolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{8} +} +func (m *ValidatingAdmissionPolicy) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicy.Merge(m, src) +} +func (m *ValidatingAdmissionPolicy) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicy) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicy proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicyBinding) Reset() { *m = ValidatingAdmissionPolicyBinding{} } +func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {} +func (*ValidatingAdmissionPolicyBinding) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{9} +} +func (m *ValidatingAdmissionPolicyBinding) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyBinding) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicyBinding) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyBinding.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyBinding) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyBinding) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyBinding.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyBinding proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicyBindingList) Reset() { *m = ValidatingAdmissionPolicyBindingList{} } +func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {} +func (*ValidatingAdmissionPolicyBindingList) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{10} +} +func (m *ValidatingAdmissionPolicyBindingList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyBindingList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicyBindingList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyBindingList.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyBindingList) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyBindingList) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyBindingList.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyBindingList proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicyBindingSpec) Reset() { *m = ValidatingAdmissionPolicyBindingSpec{} } +func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {} +func (*ValidatingAdmissionPolicyBindingSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{11} +} +func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyBindingSpec.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyBindingSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyBindingSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyBindingSpec proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicyList) Reset() { *m = ValidatingAdmissionPolicyList{} } +func (*ValidatingAdmissionPolicyList) ProtoMessage() {} +func (*ValidatingAdmissionPolicyList) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{12} +} +func (m *ValidatingAdmissionPolicyList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicyList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyList.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyList) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyList) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyList.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyList proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicySpec) Reset() { *m = ValidatingAdmissionPolicySpec{} } +func (*ValidatingAdmissionPolicySpec) ProtoMessage() {} +func (*ValidatingAdmissionPolicySpec) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{13} +} +func (m *ValidatingAdmissionPolicySpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicySpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicySpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicySpec.Merge(m, src) +} +func (m *ValidatingAdmissionPolicySpec) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicySpec) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicySpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicySpec proto.InternalMessageInfo + +func (m *ValidatingAdmissionPolicyStatus) Reset() { *m = ValidatingAdmissionPolicyStatus{} } +func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {} +func (*ValidatingAdmissionPolicyStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{14} +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyStatus.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyStatus) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyStatus proto.InternalMessageInfo + +func (m *Validation) Reset() { *m = Validation{} } +func (*Validation) ProtoMessage() {} +func (*Validation) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{15} +} +func (m *Validation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Validation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Validation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Validation.Merge(m, src) +} +func (m *Validation) XXX_Size() int { + return m.Size() +} +func (m *Validation) XXX_DiscardUnknown() { + xxx_messageInfo_Validation.DiscardUnknown(m) +} + +var xxx_messageInfo_Validation proto.InternalMessageInfo + +func init() { + proto.RegisterType((*AuditAnnotation)(nil), "k8s.io.api.admissionregistration.v1alpha1.AuditAnnotation") + proto.RegisterType((*ExpressionWarning)(nil), "k8s.io.api.admissionregistration.v1alpha1.ExpressionWarning") + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchCondition") + proto.RegisterType((*MatchResources)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchResources") + proto.RegisterType((*NamedRuleWithOperations)(nil), "k8s.io.api.admissionregistration.v1alpha1.NamedRuleWithOperations") + proto.RegisterType((*ParamKind)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamKind") + proto.RegisterType((*ParamRef)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamRef") + proto.RegisterType((*TypeChecking)(nil), "k8s.io.api.admissionregistration.v1alpha1.TypeChecking") + proto.RegisterType((*ValidatingAdmissionPolicy)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy") + proto.RegisterType((*ValidatingAdmissionPolicyBinding)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding") + proto.RegisterType((*ValidatingAdmissionPolicyBindingList)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingList") + proto.RegisterType((*ValidatingAdmissionPolicyBindingSpec)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingSpec") + proto.RegisterType((*ValidatingAdmissionPolicyList)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyList") + proto.RegisterType((*ValidatingAdmissionPolicySpec)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec") + proto.RegisterType((*ValidatingAdmissionPolicyStatus)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus") + proto.RegisterType((*Validation)(nil), "k8s.io.api.admissionregistration.v1alpha1.Validation") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto", fileDescriptor_c3be8d256e3ae3cf) +} + +var fileDescriptor_c3be8d256e3ae3cf = []byte{ + // 1407 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6f, 0x1b, 0x45, + 0x18, 0xcf, 0xc6, 0x4e, 0x9a, 0x8c, 0xf3, 0xb0, 0x87, 0x56, 0x75, 0x23, 0x6a, 0x47, 0xab, 0x0a, + 0x35, 0x12, 0xec, 0x92, 0xb4, 0x50, 0x40, 0x48, 0x28, 0xdb, 0x17, 0x7d, 0xa4, 0x89, 0xa6, 0x28, + 0x91, 0x10, 0x95, 0x98, 0xec, 0x4e, 0xec, 0xa9, 0xbd, 0x0f, 0x76, 0xd6, 0xa1, 0x11, 0x48, 0x54, + 0xe2, 0x02, 0x37, 0x0e, 0x5c, 0xf8, 0x5f, 0xb8, 0x70, 0xeb, 0xb1, 0xc7, 0x72, 0xc0, 0x22, 0xe6, + 0xc2, 0x5f, 0x00, 0x52, 0x2e, 0xa0, 0x99, 0x9d, 0x7d, 0x3b, 0xc4, 0x2e, 0x81, 0x9b, 0xf7, 0x7b, + 0xfc, 0x7e, 0xf3, 0x7d, 0xf3, 0x7d, 0x33, 0xdf, 0x18, 0xa0, 0xce, 0x3b, 0x4c, 0xa3, 0xae, 0xde, + 0xe9, 0xed, 0x12, 0xdf, 0x21, 0x01, 0x61, 0xfa, 0x3e, 0x71, 0x2c, 0xd7, 0xd7, 0xa5, 0x02, 0x7b, + 0x54, 0xc7, 0x96, 0x4d, 0x19, 0xa3, 0xae, 0xe3, 0x93, 0x16, 0x65, 0x81, 0x8f, 0x03, 0xea, 0x3a, + 0xfa, 0xfe, 0x2a, 0xee, 0x7a, 0x6d, 0xbc, 0xaa, 0xb7, 0x88, 0x43, 0x7c, 0x1c, 0x10, 0x4b, 0xf3, + 0x7c, 0x37, 0x70, 0xe1, 0x4a, 0xe8, 0xaa, 0x61, 0x8f, 0x6a, 0x43, 0x5d, 0xb5, 0xc8, 0x75, 0xe9, + 0x8d, 0x16, 0x0d, 0xda, 0xbd, 0x5d, 0xcd, 0x74, 0x6d, 0xbd, 0xe5, 0xb6, 0x5c, 0x5d, 0x20, 0xec, + 0xf6, 0xf6, 0xc4, 0x97, 0xf8, 0x10, 0xbf, 0x42, 0xe4, 0xa5, 0x2b, 0x23, 0x2c, 0x2a, 0xbf, 0x9c, + 0xa5, 0xab, 0x89, 0x93, 0x8d, 0xcd, 0x36, 0x75, 0x88, 0x7f, 0xa0, 0x7b, 0x9d, 0x16, 0x17, 0x30, + 0xdd, 0x26, 0x01, 0x1e, 0xe6, 0xa5, 0x1f, 0xe7, 0xe5, 0xf7, 0x9c, 0x80, 0xda, 0xa4, 0xe0, 0xf0, + 0xf6, 0x49, 0x0e, 0xcc, 0x6c, 0x13, 0x1b, 0xe7, 0xfd, 0x54, 0x06, 0x16, 0xd7, 0x7b, 0x16, 0x0d, + 0xd6, 0x1d, 0xc7, 0x0d, 0x44, 0x10, 0xf0, 0x22, 0x28, 0x75, 0xc8, 0x41, 0x5d, 0x59, 0x56, 0x2e, + 0xcf, 0x1a, 0x95, 0x67, 0xfd, 0xe6, 0xc4, 0xa0, 0xdf, 0x2c, 0xdd, 0x23, 0x07, 0x88, 0xcb, 0xe1, + 0x3a, 0x58, 0xdc, 0xc7, 0xdd, 0x1e, 0xb9, 0xf9, 0xc4, 0xf3, 0x89, 0x48, 0x41, 0x7d, 0x52, 0x98, + 0x9e, 0x97, 0xa6, 0x8b, 0xdb, 0x59, 0x35, 0xca, 0xdb, 0xab, 0x5d, 0x50, 0x4b, 0xbe, 0x76, 0xb0, + 0xef, 0x50, 0xa7, 0x05, 0x5f, 0x07, 0x33, 0x7b, 0x94, 0x74, 0x2d, 0x44, 0xf6, 0x24, 0x60, 0x55, + 0x02, 0xce, 0xdc, 0x92, 0x72, 0x14, 0x5b, 0xc0, 0x15, 0x70, 0xe6, 0xf3, 0xd0, 0xb1, 0x5e, 0x12, + 0xc6, 0x8b, 0xd2, 0xf8, 0x8c, 0xc4, 0x43, 0x91, 0x5e, 0xdd, 0x03, 0x0b, 0x1b, 0x38, 0x30, 0xdb, + 0xd7, 0x5d, 0xc7, 0xa2, 0x22, 0xc2, 0x65, 0x50, 0x76, 0xb0, 0x4d, 0x64, 0x88, 0x73, 0xd2, 0xb3, + 0xfc, 0x00, 0xdb, 0x04, 0x09, 0x0d, 0x5c, 0x03, 0x80, 0xe4, 0xe3, 0x83, 0xd2, 0x0e, 0xa4, 0x42, + 0x4b, 0x59, 0xa9, 0x3f, 0x97, 0x25, 0x11, 0x22, 0xcc, 0xed, 0xf9, 0x26, 0x61, 0xf0, 0x09, 0xa8, + 0x71, 0x38, 0xe6, 0x61, 0x93, 0x3c, 0x24, 0x5d, 0x62, 0x06, 0xae, 0x2f, 0x58, 0x2b, 0x6b, 0x57, + 0xb4, 0xa4, 0x4e, 0xe3, 0x1d, 0xd3, 0xbc, 0x4e, 0x8b, 0x0b, 0x98, 0xc6, 0x0b, 0x43, 0xdb, 0x5f, + 0xd5, 0xee, 0xe3, 0x5d, 0xd2, 0x8d, 0x5c, 0x8d, 0x73, 0x83, 0x7e, 0xb3, 0xf6, 0x20, 0x8f, 0x88, + 0x8a, 0x24, 0xd0, 0x05, 0x0b, 0xee, 0xee, 0x63, 0x62, 0x06, 0x31, 0xed, 0xe4, 0xcb, 0xd3, 0xc2, + 0x41, 0xbf, 0xb9, 0xb0, 0x99, 0x81, 0x43, 0x39, 0x78, 0xf8, 0x15, 0x98, 0xf7, 0x65, 0xdc, 0xa8, + 0xd7, 0x25, 0xac, 0x5e, 0x5a, 0x2e, 0x5d, 0xae, 0xac, 0x19, 0xda, 0xc8, 0xed, 0xa8, 0xf1, 0xc0, + 0x2c, 0xee, 0xbc, 0x43, 0x83, 0xf6, 0xa6, 0x47, 0x42, 0x3d, 0x33, 0xce, 0xc9, 0xc4, 0xcf, 0xa3, + 0x34, 0x01, 0xca, 0xf2, 0xc1, 0xef, 0x15, 0x70, 0x96, 0x3c, 0x31, 0xbb, 0x3d, 0x8b, 0x64, 0xec, + 0xea, 0xe5, 0x53, 0x5b, 0xc8, 0xab, 0x72, 0x21, 0x67, 0x6f, 0x0e, 0xe1, 0x41, 0x43, 0xd9, 0xe1, + 0x0d, 0x50, 0xb1, 0x79, 0x51, 0x6c, 0xb9, 0x5d, 0x6a, 0x1e, 0xd4, 0xcf, 0x88, 0x52, 0x52, 0x07, + 0xfd, 0x66, 0x65, 0x23, 0x11, 0x1f, 0xf5, 0x9b, 0x8b, 0xa9, 0xcf, 0x8f, 0x0e, 0x3c, 0x82, 0xd2, + 0x6e, 0xea, 0x0b, 0x05, 0x9c, 0x3f, 0x66, 0x55, 0xf0, 0x5a, 0x92, 0x79, 0x51, 0x1a, 0x75, 0x65, + 0xb9, 0x74, 0x79, 0xd6, 0xa8, 0xa5, 0x33, 0x26, 0x14, 0x28, 0x6b, 0x07, 0xbf, 0x56, 0x00, 0xf4, + 0x0b, 0x78, 0xb2, 0x50, 0xae, 0x8d, 0x92, 0x2f, 0x6d, 0x48, 0x92, 0x96, 0x64, 0x92, 0x60, 0x51, + 0x87, 0x86, 0xd0, 0xa9, 0x18, 0xcc, 0x6e, 0x61, 0x1f, 0xdb, 0xf7, 0xa8, 0x63, 0xf1, 0xbe, 0xc3, + 0x1e, 0xdd, 0x26, 0xbe, 0xe8, 0x3b, 0x25, 0xdb, 0x77, 0xeb, 0x5b, 0x77, 0xa4, 0x06, 0xa5, 0xac, + 0x78, 0x37, 0x77, 0xa8, 0x63, 0xc9, 0x2e, 0x8d, 0xbb, 0x99, 0xe3, 0x21, 0xa1, 0x51, 0x1f, 0x81, + 0x19, 0x41, 0xc1, 0x0f, 0x8e, 0x93, 0x7b, 0x5f, 0x07, 0xb3, 0x71, 0x3f, 0x49, 0xd0, 0x9a, 0x34, + 0x9b, 0x8d, 0x7b, 0x0f, 0x25, 0x36, 0xea, 0x0f, 0x0a, 0x98, 0xe3, 0x5b, 0x76, 0xbd, 0x4d, 0xcc, + 0x0e, 0x3f, 0xca, 0xbe, 0x51, 0x00, 0x24, 0xf9, 0x03, 0x2e, 0xdc, 0x97, 0xca, 0xda, 0xfb, 0x63, + 0x14, 0x62, 0xe1, 0x94, 0x4c, 0xb2, 0x5b, 0x50, 0x31, 0x34, 0x84, 0x53, 0xfd, 0x65, 0x12, 0x5c, + 0xd8, 0xc6, 0x5d, 0x6a, 0xe1, 0x80, 0x3a, 0xad, 0xf5, 0x88, 0x2e, 0x2c, 0x2b, 0xf8, 0x29, 0x98, + 0xe1, 0x1d, 0x6f, 0xe1, 0x00, 0xcb, 0x63, 0xe9, 0xcd, 0xd1, 0xce, 0x87, 0xf0, 0x30, 0xd8, 0x20, + 0x01, 0x4e, 0xb6, 0x27, 0x91, 0xa1, 0x18, 0x15, 0x3e, 0x06, 0x65, 0xe6, 0x11, 0x53, 0x16, 0xd5, + 0x87, 0x63, 0xc4, 0x7e, 0xec, 0xaa, 0x1f, 0x7a, 0xc4, 0x4c, 0x36, 0x8e, 0x7f, 0x21, 0xc1, 0x01, + 0x7d, 0x30, 0xcd, 0x02, 0x1c, 0xf4, 0x98, 0xb8, 0x12, 0x2a, 0x6b, 0x77, 0x4f, 0x85, 0x4d, 0x20, + 0x1a, 0x0b, 0x92, 0x6f, 0x3a, 0xfc, 0x46, 0x92, 0x49, 0xfd, 0x53, 0x01, 0xcb, 0xc7, 0xfa, 0x1a, + 0xd4, 0xb1, 0x78, 0x3d, 0xfc, 0xf7, 0x69, 0xfe, 0x2c, 0x93, 0xe6, 0xcd, 0xd3, 0x08, 0x5c, 0x2e, + 0xfe, 0xb8, 0x6c, 0xab, 0x7f, 0x28, 0xe0, 0xd2, 0x49, 0xce, 0xf7, 0x29, 0x0b, 0xe0, 0x27, 0x85, + 0xe8, 0xb5, 0x11, 0x2f, 0x21, 0xca, 0xc2, 0xd8, 0xe3, 0x41, 0x20, 0x92, 0xa4, 0x22, 0xf7, 0xc0, + 0x14, 0x0d, 0x88, 0xcd, 0x8f, 0x2d, 0xde, 0x5d, 0xf7, 0x4e, 0x31, 0x74, 0x63, 0x5e, 0xf2, 0x4e, + 0xdd, 0xe1, 0x0c, 0x28, 0x24, 0x52, 0xbf, 0x2d, 0x9d, 0x1c, 0x38, 0xcf, 0x13, 0x3f, 0xcc, 0x3c, + 0x21, 0x7c, 0x90, 0x1c, 0x38, 0xf1, 0x36, 0x6e, 0xc5, 0x1a, 0x94, 0xb2, 0x82, 0x8f, 0xc0, 0x8c, + 0x27, 0x8f, 0xaa, 0x21, 0x37, 0xf6, 0x49, 0x11, 0x45, 0xa7, 0x9c, 0x31, 0xc7, 0xb3, 0x15, 0x7d, + 0xa1, 0x18, 0x12, 0xf6, 0xc0, 0x82, 0x9d, 0x19, 0x51, 0x64, 0xab, 0xbc, 0x3b, 0x06, 0x49, 0x76, + 0xc6, 0x09, 0x87, 0x83, 0xac, 0x0c, 0xe5, 0x48, 0xe0, 0x0e, 0xa8, 0xed, 0xcb, 0x8c, 0xb9, 0xce, + 0xba, 0x19, 0xde, 0x33, 0x65, 0x71, 0x4d, 0xad, 0xf0, 0x91, 0x66, 0x3b, 0xaf, 0x3c, 0xea, 0x37, + 0xab, 0x79, 0x21, 0x2a, 0x62, 0xa8, 0xbf, 0x2b, 0xe0, 0xe2, 0xb1, 0x7b, 0xf1, 0x3f, 0x54, 0x1f, + 0xcd, 0x56, 0xdf, 0x8d, 0x53, 0xa9, 0xbe, 0xe1, 0x65, 0xf7, 0xe3, 0xd4, 0x3f, 0x84, 0x2a, 0xea, + 0x0d, 0x83, 0x59, 0x2f, 0xba, 0x49, 0x65, 0xac, 0x57, 0xc7, 0x2d, 0x1e, 0xee, 0x6b, 0xcc, 0xf3, + 0xab, 0x2e, 0xfe, 0x44, 0x09, 0x2a, 0xfc, 0x02, 0x54, 0x6d, 0x39, 0x4b, 0x73, 0x00, 0xea, 0x04, + 0xd1, 0xbc, 0xf0, 0x2f, 0x2a, 0xe8, 0xec, 0xa0, 0xdf, 0xac, 0x6e, 0xe4, 0x60, 0x51, 0x81, 0x08, + 0x76, 0x41, 0x25, 0xa9, 0x80, 0x68, 0xc0, 0x7c, 0xeb, 0x25, 0x52, 0xee, 0x3a, 0xc6, 0x2b, 0x32, + 0xc7, 0x95, 0x44, 0xc6, 0x50, 0x1a, 0x1e, 0xde, 0x07, 0xf3, 0x7b, 0x98, 0x76, 0x7b, 0x3e, 0x91, + 0xa3, 0x5b, 0x59, 0x34, 0xf0, 0x6b, 0x7c, 0xac, 0xba, 0x95, 0x56, 0x1c, 0xf5, 0x9b, 0xb5, 0x8c, + 0x40, 0x8c, 0x6f, 0x59, 0x67, 0xf8, 0x54, 0x01, 0x55, 0x9c, 0x7d, 0x68, 0xb1, 0xfa, 0x94, 0x88, + 0xe0, 0xbd, 0x31, 0x22, 0xc8, 0xbd, 0xd5, 0x8c, 0xba, 0x0c, 0xa3, 0x9a, 0x53, 0x30, 0x54, 0x60, + 0x83, 0x5f, 0x82, 0x45, 0x3b, 0xf3, 0x0e, 0x62, 0xf5, 0x69, 0xb1, 0x80, 0xb1, 0xb7, 0x2e, 0x46, + 0x48, 0xde, 0x7c, 0x59, 0x39, 0x43, 0x79, 0x2a, 0xf5, 0xa7, 0x49, 0xd0, 0x3c, 0xe1, 0x92, 0x85, + 0x77, 0x01, 0x74, 0x77, 0x19, 0xf1, 0xf7, 0x89, 0x75, 0x3b, 0x7c, 0xa7, 0x46, 0x53, 0x60, 0x29, + 0x19, 0x7c, 0x36, 0x0b, 0x16, 0x68, 0x88, 0x17, 0xb4, 0xc1, 0x5c, 0x90, 0x9a, 0xc9, 0xc6, 0x99, + 0x6a, 0x65, 0xa8, 0xe9, 0x91, 0xce, 0xa8, 0x0e, 0xfa, 0xcd, 0xcc, 0x90, 0x87, 0x32, 0xf0, 0xd0, + 0x04, 0xc0, 0x4c, 0xf2, 0x1a, 0x96, 0xa6, 0x3e, 0xda, 0x41, 0x93, 0x64, 0x33, 0xbe, 0x1c, 0x52, + 0x89, 0x4c, 0xc1, 0xaa, 0x7f, 0x29, 0x00, 0x24, 0xf5, 0x0a, 0x2f, 0x81, 0xd4, 0x53, 0x54, 0xde, + 0x2f, 0x65, 0x0e, 0x81, 0x52, 0x72, 0xfe, 0x52, 0xb6, 0x09, 0x63, 0xb8, 0x15, 0x0d, 0xb3, 0xf1, + 0x4b, 0x79, 0x23, 0x14, 0xa3, 0x48, 0x0f, 0x77, 0xc0, 0xb4, 0x4f, 0x30, 0x73, 0x1d, 0xf9, 0xa6, + 0xfe, 0x80, 0x0f, 0x3c, 0x48, 0x48, 0x8e, 0xfa, 0xcd, 0xd5, 0x51, 0xfe, 0xc9, 0xd0, 0xe4, 0x7c, + 0x24, 0x9c, 0x90, 0x84, 0x83, 0xb7, 0x41, 0x4d, 0x72, 0xa4, 0x16, 0x1c, 0xf6, 0xd3, 0x05, 0xb9, + 0x9a, 0xda, 0x46, 0xde, 0x00, 0x15, 0x7d, 0x8c, 0xcd, 0x67, 0x87, 0x8d, 0x89, 0xe7, 0x87, 0x8d, + 0x89, 0x17, 0x87, 0x8d, 0x89, 0xa7, 0x83, 0x86, 0xf2, 0x6c, 0xd0, 0x50, 0x9e, 0x0f, 0x1a, 0xca, + 0x8b, 0x41, 0x43, 0xf9, 0x75, 0xd0, 0x50, 0xbe, 0xfb, 0xad, 0x31, 0xf1, 0xf1, 0xca, 0xc8, 0xff, + 0x1e, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x08, 0xaf, 0xaa, 0x52, 0x82, 0x12, 0x00, 0x00, +} + +func (m *AuditAnnotation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuditAnnotation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AuditAnnotation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.ValueExpression) + copy(dAtA[i:], m.ValueExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValueExpression))) + i-- + dAtA[i] = 0x12 + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ExpressionWarning) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExpressionWarning) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ExpressionWarning) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Warning) + copy(dAtA[i:], m.Warning) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Warning))) + i-- + dAtA[i] = 0x1a + i -= len(m.FieldRef) + copy(dAtA[i:], m.FieldRef) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.FieldRef))) + i-- + dAtA[i] = 0x12 + return len(dAtA) - i, nil +} + +func (m *MatchCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MatchResources) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MatchResources) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchResources) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MatchPolicy != nil { + i -= len(*m.MatchPolicy) + copy(dAtA[i:], *m.MatchPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy))) + i-- + dAtA[i] = 0x3a + } + if len(m.ExcludeResourceRules) > 0 { + for iNdEx := len(m.ExcludeResourceRules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExcludeResourceRules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.ResourceRules) > 0 { + for iNdEx := len(m.ResourceRules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceRules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.ObjectSelector != nil { + { + size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.NamespaceSelector != nil { + { + size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NamedRuleWithOperations) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NamedRuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.RuleWithOperations.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.ResourceNames) > 0 { + for iNdEx := len(m.ResourceNames) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ResourceNames[iNdEx]) + copy(dAtA[i:], m.ResourceNames[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceNames[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ParamKind) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ParamKind) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ParamKind) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIVersion) + copy(dAtA[i:], m.APIVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ParamRef) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ParamRef) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *TypeChecking) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TypeChecking) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ExpressionWarnings) > 0 { + for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExpressionWarnings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidationActions) > 0 { + for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValidationActions[iNdEx]) + copy(dAtA[i:], m.ValidationActions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if m.MatchResources != nil { + { + size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.ParamRef != nil { + { + size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.PolicyName) + copy(dAtA[i:], m.PolicyName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.AuditAnnotations) > 0 { + for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.FailurePolicy != nil { + i -= len(*m.FailurePolicy) + copy(dAtA[i:], *m.FailurePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) + i-- + dAtA[i] = 0x22 + } + if len(m.Validations) > 0 { + for iNdEx := len(m.Validations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Validations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.MatchConstraints != nil { + { + size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.ParamKind != nil { + { + size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.TypeChecking != nil { + { + size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func (m *Validation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Validation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x22 + if m.Reason != nil { + i -= len(*m.Reason) + copy(dAtA[i:], *m.Reason) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Reason))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x12 + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AuditAnnotation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.ValueExpression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ExpressionWarning) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FieldRef) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Warning) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MatchResources) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NamespaceSelector != nil { + l = m.NamespaceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ObjectSelector != nil { + l = m.ObjectSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ResourceRules) > 0 { + for _, e := range m.ResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.ExcludeResourceRules) > 0 { + for _, e := range m.ExcludeResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.MatchPolicy != nil { + l = len(*m.MatchPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *NamedRuleWithOperations) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ResourceNames) > 0 { + for _, s := range m.ResourceNames { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = m.RuleWithOperations.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ParamKind) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIVersion) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ParamRef) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *TypeChecking) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ExpressionWarnings) > 0 { + for _, e := range m.ExpressionWarnings { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ValidatingAdmissionPolicyBinding) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PolicyName) + n += 1 + l + sovGenerated(uint64(l)) + if m.ParamRef != nil { + l = m.ParamRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.MatchResources != nil { + l = m.MatchResources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ValidationActions) > 0 { + for _, s := range m.ValidationActions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicyList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicySpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ParamKind != nil { + l = m.ParamKind.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.MatchConstraints != nil { + l = m.MatchConstraints.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.Validations) > 0 { + for _, e := range m.Validations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.FailurePolicy != nil { + l = len(*m.FailurePolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.AuditAnnotations) > 0 { + for _, e := range m.AuditAnnotations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicyStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.ObservedGeneration)) + if m.TypeChecking != nil { + l = m.TypeChecking.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *Validation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) + if m.Reason != nil { + l = len(*m.Reason) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *AuditAnnotation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AuditAnnotation{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`, + `}`, + }, "") + return s +} +func (this *ExpressionWarning) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ExpressionWarning{`, + `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`, + `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`, + `}`, + }, "") + return s +} +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} +func (this *MatchResources) String() string { + if this == nil { + return "nil" + } + repeatedStringForResourceRules := "[]NamedRuleWithOperations{" + for _, f := range this.ResourceRules { + repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceRules += "}" + repeatedStringForExcludeResourceRules := "[]NamedRuleWithOperations{" + for _, f := range this.ExcludeResourceRules { + repeatedStringForExcludeResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForExcludeResourceRules += "}" + s := strings.Join([]string{`&MatchResources{`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ResourceRules:` + repeatedStringForResourceRules + `,`, + `ExcludeResourceRules:` + repeatedStringForExcludeResourceRules + `,`, + `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, + `}`, + }, "") + return s +} +func (this *NamedRuleWithOperations) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedRuleWithOperations{`, + `ResourceNames:` + fmt.Sprintf("%v", this.ResourceNames) + `,`, + `RuleWithOperations:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.RuleWithOperations), "RuleWithOperations", "v11.RuleWithOperations", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ParamKind) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParamKind{`, + `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `}`, + }, "") + return s +} +func (this *ParamRef) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParamRef{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `}`, + }, "") + return s +} +func (this *TypeChecking) String() string { + if this == nil { + return "nil" + } + repeatedStringForExpressionWarnings := "[]ExpressionWarning{" + for _, f := range this.ExpressionWarnings { + repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + "," + } + repeatedStringForExpressionWarnings += "}" + s := strings.Join([]string{`&TypeChecking{`, + `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicy{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBinding) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicyBinding{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicyBindingSpec", "ValidatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBindingList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ValidatingAdmissionPolicyBinding{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicyBinding", "ValidatingAdmissionPolicyBinding", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBindingSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingSpec{`, + `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`, + `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`, + `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`, + `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ValidatingAdmissionPolicy{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicy", "ValidatingAdmissionPolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicySpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForValidations := "[]Validation{" + for _, f := range this.Validations { + repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + "," + } + repeatedStringForValidations += "}" + repeatedStringForAuditAnnotations := "[]AuditAnnotation{" + for _, f := range this.AuditAnnotations { + repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + "," + } + repeatedStringForAuditAnnotations += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`, + `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`, + `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`, + `Validations:` + repeatedStringForValidations + `,`, + `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`, + `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, + `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} +func (this *Validation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Validation{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `Reason:` + valueToStringGenerated(this.Reason) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuditAnnotation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValueExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExpressionWarning: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FieldRef = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Warning", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Warning = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MatchCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MatchResources) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchResources: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchResources: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamespaceSelector == nil { + m.NamespaceSelector = &v1.LabelSelector{} + } + if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ObjectSelector == nil { + m.ObjectSelector = &v1.LabelSelector{} + } + if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceRules = append(m.ResourceRules, NamedRuleWithOperations{}) + if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExcludeResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExcludeResourceRules = append(m.ExcludeResourceRules, NamedRuleWithOperations{}) + if err := m.ExcludeResourceRules[len(m.ExcludeResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := MatchPolicyType(dAtA[iNdEx:postIndex]) + m.MatchPolicy = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NamedRuleWithOperations) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NamedRuleWithOperations: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NamedRuleWithOperations: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceNames", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceNames = append(m.ResourceNames, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RuleWithOperations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.RuleWithOperations.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ParamKind) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ParamKind: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ParamKind: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ParamRef) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ParamRef: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ParamRef: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TypeChecking) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TypeChecking: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TypeChecking: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpressionWarnings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExpressionWarnings = append(m.ExpressionWarnings, ExpressionWarning{}) + if err := m.ExpressionWarnings[len(m.ExpressionWarnings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicyBinding) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBinding: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBinding: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicyBindingList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBindingList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBindingList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ValidatingAdmissionPolicyBinding{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicyBindingSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBindingSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyBindingSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PolicyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParamRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParamRef == nil { + m.ParamRef = &ParamRef{} + } + if err := m.ParamRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MatchResources == nil { + m.MatchResources = &MatchResources{} + } + if err := m.MatchResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidationActions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidationActions = append(m.ValidationActions, ValidationAction(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicyList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ValidatingAdmissionPolicy{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicySpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicySpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParamKind", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParamKind == nil { + m.ParamKind = &ParamKind{} + } + if err := m.ParamKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConstraints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MatchConstraints == nil { + m.MatchConstraints = &MatchResources{} + } + if err := m.MatchConstraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validations = append(m.Validations, Validation{}) + if err := m.Validations[len(m.Validations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FailurePolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := FailurePolicyType(dAtA[iNdEx:postIndex]) + m.FailurePolicy = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuditAnnotations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AuditAnnotations = append(m.AuditAnnotations, AuditAnnotation{}) + if err := m.AuditAnnotations[len(m.AuditAnnotations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatingAdmissionPolicyStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TypeChecking", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TypeChecking == nil { + m.TypeChecking = &TypeChecking{} + } + if err := m.TypeChecking.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Validation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Validation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Validation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := k8s_io_apimachinery_pkg_apis_meta_v1.StatusReason(dAtA[iNdEx:postIndex]) + m.Reason = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MessageExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto new file mode 100644 index 00000000000..c718c5464df --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto @@ -0,0 +1,527 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.admissionregistration.v1alpha1; + +import "k8s.io/api/admissionregistration/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/admissionregistration/v1alpha1"; + +// AuditAnnotation describes how to produce an audit annotation for an API request. +message AuditAnnotation { + // key specifies the audit annotation key. The audit annotation keys of + // a ValidatingAdmissionPolicy must be unique. The key must be a qualified + // name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length. + // + // The key is combined with the resource name of the + // ValidatingAdmissionPolicy to construct an audit annotation key: + // "{ValidatingAdmissionPolicy name}/{key}". + // + // If an admission webhook uses the same resource name as this ValidatingAdmissionPolicy + // and the same audit annotation key, the annotation key will be identical. + // In this case, the first annotation written with the key will be included + // in the audit event and all subsequent annotations with the same key + // will be discarded. + // + // Required. + optional string key = 1; + + // valueExpression represents the expression which is evaluated by CEL to + // produce an audit annotation value. The expression must evaluate to either + // a string or null value. If the expression evaluates to a string, the + // audit annotation is included with the string value. If the expression + // evaluates to null or empty string the audit annotation will be omitted. + // The valueExpression may be no longer than 5kb in length. + // If the result of the valueExpression is more than 10kb in length, it + // will be truncated to 10kb. + // + // If multiple ValidatingAdmissionPolicyBinding resources match an + // API request, then the valueExpression will be evaluated for + // each binding. All unique values produced by the valueExpressions + // will be joined together in a comma-separated list. + // + // Required. + optional string valueExpression = 2; +} + +// ExpressionWarning is a warning information that targets a specific expression. +message ExpressionWarning { + // The path to the field that refers the expression. + // For example, the reference to the expression of the first item of + // validations is "spec.validations[0].expression" + optional string fieldRef = 2; + + // The content of type checking information in a human-readable form. + // Each line of the warning contains the type that the expression is checked + // against, followed by the type check error from the compiler. + optional string warning = 3; +} + +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + +// MatchResources decides whether to run the admission control policy on an object based +// on whether it meets the match criteria. +// The exclude rules take precedence over include rules (if a resource matches both, it is excluded) +// +structType=atomic +message MatchResources { + // NamespaceSelector decides whether to run the admission control policy on an object based + // on whether the namespace for that object matches the selector. If the + // object itself is a namespace, the matching is performed on + // object.metadata.labels. If the object is another cluster scoped resource, + // it never skips the policy. + // + // For example, to run the webhook on any objects whose namespace is not + // associated with "runlevel" of "0" or "1"; you will set the selector as + // follows: + // "namespaceSelector": { + // "matchExpressions": [ + // { + // "key": "runlevel", + // "operator": "NotIn", + // "values": [ + // "0", + // "1" + // ] + // } + // ] + // } + // + // If instead you want to only run the policy on any objects whose + // namespace is associated with the "environment" of "prod" or "staging"; + // you will set the selector as follows: + // "namespaceSelector": { + // "matchExpressions": [ + // { + // "key": "environment", + // "operator": "In", + // "values": [ + // "prod", + // "staging" + // ] + // } + // ] + // } + // + // See + // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + // for more examples of label selectors. + // + // Default to the empty LabelSelector, which matches everything. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1; + + // ObjectSelector decides whether to run the validation based on if the + // object has matching labels. objectSelector is evaluated against both + // the oldObject and newObject that would be sent to the cel validation, and + // is considered to match if either object matches the selector. A null + // object (oldObject in the case of create, or newObject in the case of + // delete) or an object that cannot have labels (like a + // DeploymentRollback or a PodProxyOptions object) is not considered to + // match. + // Use the object selector only if the webhook is opt-in, because end + // users may skip the admission webhook by setting the labels. + // Default to the empty LabelSelector, which matches everything. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2; + + // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // The policy cares about an operation if it matches _any_ Rule. + // +listType=atomic + // +optional + repeated NamedRuleWithOperations resourceRules = 3; + + // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) + // +listType=atomic + // +optional + repeated NamedRuleWithOperations excludeResourceRules = 4; + + // matchPolicy defines how the "MatchResources" list is used to match incoming requests. + // Allowed values are "Exact" or "Equivalent". + // + // - Exact: match a request only if it exactly matches a specified rule. + // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, + // but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, + // a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy. + // + // - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. + // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, + // and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, + // a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy. + // + // Defaults to "Equivalent" + // +optional + optional string matchPolicy = 7; +} + +// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. +// +structType=atomic +message NamedRuleWithOperations { + // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // +listType=atomic + // +optional + repeated string resourceNames = 1; + + // RuleWithOperations is a tuple of Operations and Resources. + optional k8s.io.api.admissionregistration.v1.RuleWithOperations ruleWithOperations = 2; +} + +// ParamKind is a tuple of Group Kind and Version. +// +structType=atomic +message ParamKind { + // APIVersion is the API group version the resources belong to. + // In format of "group/version". + // Required. + optional string apiVersion = 1; + + // Kind is the API kind the resources belong to. + // Required. + optional string kind = 2; +} + +// ParamRef references a parameter resource +// +structType=atomic +message ParamRef { + // Name of the resource being referenced. + optional string name = 1; + + // Namespace of the referenced resource. + // Should be empty for the cluster-scoped resources + // +optional + optional string namespace = 2; +} + +// TypeChecking contains results of type checking the expressions in the +// ValidatingAdmissionPolicy +message TypeChecking { + // The type checking warnings for each expression. + // +optional + // +listType=atomic + repeated ExpressionWarning expressionWarnings = 1; +} + +// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. +message ValidatingAdmissionPolicy { + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Specification of the desired behavior of the ValidatingAdmissionPolicy. + optional ValidatingAdmissionPolicySpec spec = 2; + + // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // behaves in the expected way. + // Populated by the system. + // Read-only. + // +optional + optional ValidatingAdmissionPolicyStatus status = 3; +} + +// ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. +// ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters. +message ValidatingAdmissionPolicyBinding { + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + optional ValidatingAdmissionPolicyBindingSpec spec = 2; +} + +// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. +message ValidatingAdmissionPolicyBindingList { + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // List of PolicyBinding. + repeated ValidatingAdmissionPolicyBinding items = 2; +} + +// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. +message ValidatingAdmissionPolicyBindingSpec { + // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // If the referenced resource does not exist, this binding is considered invalid and will be ignored + // Required. + optional string policyName = 1; + + // ParamRef specifies the parameter resource used to configure the admission control policy. + // It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. + // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. + // +optional + optional ParamRef paramRef = 2; + + // MatchResources declares what resources match this binding and will be validated by it. + // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. + // If this is unset, all resources matched by the policy are validated by this binding + // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. + // Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required. + // +optional + optional MatchResources matchResources = 3; + + // validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. + // If a validation evaluates to false it is always enforced according to these actions. + // + // Failures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according + // to these actions only if the FailurePolicy is set to Fail, otherwise the failures are + // ignored. This includes compilation errors, runtime errors and misconfigurations of the policy. + // + // validationActions is declared as a set of action values. Order does + // not matter. validationActions may not contain duplicates of the same action. + // + // The supported actions values are: + // + // "Deny" specifies that a validation failure results in a denied request. + // + // "Warn" specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + // + // "Audit" specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failures, formatted as + // a JSON list of objects, each with the following fields: + // - message: The validation failure message string + // - policy: The resource name of the ValidatingAdmissionPolicy + // - binding: The resource name of the ValidatingAdmissionPolicyBinding + // - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy + // - validationActions: The enforcement actions enacted for the validation failure + // Example audit annotation: + // `"validation.policy.admission.k8s.io/validation_failure": "[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]"` + // + // Clients should expect to handle additional values by ignoring + // any values not recognized. + // + // "Deny" and "Warn" may not be used together since this combination + // needlessly duplicates the validation failure both in the + // API response body and the HTTP warning headers. + // + // Required. + // +listType=set + repeated string validationActions = 4; +} + +// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. +message ValidatingAdmissionPolicyList { + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // List of ValidatingAdmissionPolicy. + repeated ValidatingAdmissionPolicy items = 2; +} + +// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. +message ValidatingAdmissionPolicySpec { + // ParamKind specifies the kind of resources used to parameterize this policy. + // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. + // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. + // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. + // +optional + optional ParamKind paramKind = 1; + + // MatchConstraints specifies what resources this policy is designed to validate. + // The AdmissionPolicy cares about a request if it matches _all_ Constraints. + // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API + // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. + // Required. + optional MatchResources matchConstraints = 2; + + // Validations contain CEL expressions which is used to apply the validation. + // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is + // required. + // +listType=atomic + // +optional + repeated Validation validations = 3; + + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // + // A policy is invalid if spec.paramKind refers to a non-existent Kind. + // A binding is invalid if spec.paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // When failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions + // define how failures are enforced. + // + // Allowed values are Ignore or Fail. Defaults to Fail. + // +optional + optional string failurePolicy = 4; + + // auditAnnotations contains CEL expressions which are used to produce audit + // annotations for the audit event of the API request. + // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is + // required. + // +listType=atomic + // +optional + repeated AuditAnnotation auditAnnotations = 5; + + // MatchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + repeated MatchCondition matchConditions = 6; +} + +// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. +message ValidatingAdmissionPolicyStatus { + // The generation observed by the controller. + // +optional + optional int64 observedGeneration = 1; + + // The results of type checking for each expression. + // Presence of this field indicates the completion of the type checking. + // +optional + optional TypeChecking typeChecking = 2; + + // The conditions represent the latest available observations of a policy's current state. + // +optional + // +listType=map + // +listMapKey=type + repeated k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 3; +} + +// Validation specifies the CEL expression which is used to apply the validation. +message Validation { + // Expression represents the expression which will be evaluated by CEL. + // ref: https://github.com/google/cel-spec + // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the + // object. No other metadata properties are accessible. + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Accessible property names are escaped according to the following rules when accessed in the expression: + // - '__' escapes to '__underscores__' + // - '.' escapes to '__dot__' + // - '-' escapes to '__dash__' + // - '/' escapes to '__slash__' + // - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are: + // "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if", + // "import", "let", "loop", "package", "namespace", "return". + // Examples: + // - Expression accessing a property named "namespace": {"Expression": "object.__namespace__ > 0"} + // - Expression accessing a property named "x-prop": {"Expression": "object.x__dash__prop > 0"} + // - Expression accessing a property named "redact__d": {"Expression": "object.redact__underscores__d > 0"} + // + // Equality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. + // Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type: + // - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and + // non-intersecting elements in `Y` are appended, retaining their partial order. + // - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values + // are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with + // non-intersecting keys are appended, retaining their partial order. + // Required. + optional string Expression = 1; + + // Message represents the message displayed when validation fails. The message is required if the Expression contains + // line breaks. The message must not contain line breaks. + // If unset, the message is "failed rule: {Rule}". + // e.g. "must be a URL with the host matching spec.host" + // If the Expression contains line breaks. Message is required. + // The message must not contain line breaks. + // If unset, the message is "failed Expression: {Expression}". + // +optional + optional string message = 2; + + // Reason represents a machine-readable description of why this validation failed. + // If this is the first validation in the list to fail, this reason, as well as the + // corresponding HTTP response code, are used in the + // HTTP response to the client. + // The currently supported reasons are: "Unauthorized", "Forbidden", "Invalid", "RequestEntityTooLarge". + // If not set, StatusReasonInvalid is used in the response to the client. + // +optional + optional string reason = 3; + + // messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. + // If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. + // Example: + // "object.x must be less than max ("+string(params.max)+")" + // +optional + optional string messageExpression = 4; +} + diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/register.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/register.go new file mode 100644 index 00000000000..d4c2fbe807f --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/register.go @@ -0,0 +1,56 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name for this API. +const GroupName = "admissionregistration.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. +// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. +var ( + // SchemeBuilder points to a list of functions added to Scheme. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme. + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ValidatingAdmissionPolicy{}, + &ValidatingAdmissionPolicyList{}, + &ValidatingAdmissionPolicyBinding{}, + &ValidatingAdmissionPolicyBindingList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go new file mode 100644 index 00000000000..2bbb55a47da --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go @@ -0,0 +1,570 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + v1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended +// to make sure that all the tuple expansions are valid. +type Rule = v1.Rule + +// ScopeType specifies a scope for a Rule. +// +enum +type ScopeType = v1.ScopeType + +const ( + // ClusterScope means that scope is limited to cluster-scoped objects. + // Namespace objects are cluster-scoped. + ClusterScope ScopeType = v1.ClusterScope + // NamespacedScope means that scope is limited to namespaced objects. + NamespacedScope ScopeType = v1.NamespacedScope + // AllScopes means that all scopes are included. + AllScopes ScopeType = v1.AllScopes +) + +// FailurePolicyType specifies a failure policy that defines how unrecognized errors from the admission endpoint are handled. +// +enum +type FailurePolicyType string + +const ( + // Ignore means that an error calling the webhook is ignored. + Ignore FailurePolicyType = "Ignore" + // Fail means that an error calling the webhook causes the admission to fail. + Fail FailurePolicyType = "Fail" +) + +// MatchPolicyType specifies the type of match policy. +// +enum +type MatchPolicyType string + +const ( + // Exact means requests should only be sent to the webhook if they exactly match a given rule. + Exact MatchPolicyType = "Exact" + // Equivalent means requests should be sent to the webhook if they modify a resource listed in rules via another API group or version. + Equivalent MatchPolicyType = "Equivalent" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. +type ValidatingAdmissionPolicy struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Specification of the desired behavior of the ValidatingAdmissionPolicy. + Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // behaves in the expected way. + // Populated by the system. + // Read-only. + // +optional + Status ValidatingAdmissionPolicyStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. +type ValidatingAdmissionPolicyStatus struct { + // The generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` + // The results of type checking for each expression. + // Presence of this field indicates the completion of the type checking. + // +optional + TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"` + // The conditions represent the latest available observations of a policy's current state. + // +optional + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" protobuf:"bytes,3,rep,name=conditions"` +} + +// TypeChecking contains results of type checking the expressions in the +// ValidatingAdmissionPolicy +type TypeChecking struct { + // The type checking warnings for each expression. + // +optional + // +listType=atomic + ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"` +} + +// ExpressionWarning is a warning information that targets a specific expression. +type ExpressionWarning struct { + // The path to the field that refers the expression. + // For example, the reference to the expression of the first item of + // validations is "spec.validations[0].expression" + FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"` + // The content of type checking information in a human-readable form. + // Each line of the warning contains the type that the expression is checked + // against, followed by the type check error from the compiler. + Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. +type ValidatingAdmissionPolicyList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // List of ValidatingAdmissionPolicy. + Items []ValidatingAdmissionPolicy `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"` +} + +// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. +type ValidatingAdmissionPolicySpec struct { + // ParamKind specifies the kind of resources used to parameterize this policy. + // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. + // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. + // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. + // +optional + ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"` + + // MatchConstraints specifies what resources this policy is designed to validate. + // The AdmissionPolicy cares about a request if it matches _all_ Constraints. + // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API + // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. + // Required. + MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` + + // Validations contain CEL expressions which is used to apply the validation. + // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is + // required. + // +listType=atomic + // +optional + Validations []Validation `json:"validations,omitempty" protobuf:"bytes,3,rep,name=validations"` + + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // + // A policy is invalid if spec.paramKind refers to a non-existent Kind. + // A binding is invalid if spec.paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // When failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions + // define how failures are enforced. + // + // Allowed values are Ignore or Fail. Defaults to Fail. + // +optional + FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` + + // auditAnnotations contains CEL expressions which are used to produce audit + // annotations for the audit event of the API request. + // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is + // required. + // +listType=atomic + // +optional + AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"` + + // MatchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` +} + +type MatchCondition v1.MatchCondition + +// ParamKind is a tuple of Group Kind and Version. +// +structType=atomic +type ParamKind struct { + // APIVersion is the API group version the resources belong to. + // In format of "group/version". + // Required. + APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"` + + // Kind is the API kind the resources belong to. + // Required. + Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"` +} + +// Validation specifies the CEL expression which is used to apply the validation. +type Validation struct { + // Expression represents the expression which will be evaluated by CEL. + // ref: https://github.com/google/cel-spec + // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the + // object. No other metadata properties are accessible. + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Accessible property names are escaped according to the following rules when accessed in the expression: + // - '__' escapes to '__underscores__' + // - '.' escapes to '__dot__' + // - '-' escapes to '__dash__' + // - '/' escapes to '__slash__' + // - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are: + // "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if", + // "import", "let", "loop", "package", "namespace", "return". + // Examples: + // - Expression accessing a property named "namespace": {"Expression": "object.__namespace__ > 0"} + // - Expression accessing a property named "x-prop": {"Expression": "object.x__dash__prop > 0"} + // - Expression accessing a property named "redact__d": {"Expression": "object.redact__underscores__d > 0"} + // + // Equality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. + // Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type: + // - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and + // non-intersecting elements in `Y` are appended, retaining their partial order. + // - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values + // are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with + // non-intersecting keys are appended, retaining their partial order. + // Required. + Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"` + // Message represents the message displayed when validation fails. The message is required if the Expression contains + // line breaks. The message must not contain line breaks. + // If unset, the message is "failed rule: {Rule}". + // e.g. "must be a URL with the host matching spec.host" + // If the Expression contains line breaks. Message is required. + // The message must not contain line breaks. + // If unset, the message is "failed Expression: {Expression}". + // +optional + Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` + // Reason represents a machine-readable description of why this validation failed. + // If this is the first validation in the list to fail, this reason, as well as the + // corresponding HTTP response code, are used in the + // HTTP response to the client. + // The currently supported reasons are: "Unauthorized", "Forbidden", "Invalid", "RequestEntityTooLarge". + // If not set, StatusReasonInvalid is used in the response to the client. + // +optional + Reason *metav1.StatusReason `json:"reason,omitempty" protobuf:"bytes,3,opt,name=reason"` + // messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. + // If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. + // Example: + // "object.x must be less than max ("+string(params.max)+")" + // +optional + MessageExpression string `json:"messageExpression,omitempty" protobuf:"bytes,4,opt,name=messageExpression"` +} + +// AuditAnnotation describes how to produce an audit annotation for an API request. +type AuditAnnotation struct { + // key specifies the audit annotation key. The audit annotation keys of + // a ValidatingAdmissionPolicy must be unique. The key must be a qualified + // name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length. + // + // The key is combined with the resource name of the + // ValidatingAdmissionPolicy to construct an audit annotation key: + // "{ValidatingAdmissionPolicy name}/{key}". + // + // If an admission webhook uses the same resource name as this ValidatingAdmissionPolicy + // and the same audit annotation key, the annotation key will be identical. + // In this case, the first annotation written with the key will be included + // in the audit event and all subsequent annotations with the same key + // will be discarded. + // + // Required. + Key string `json:"key" protobuf:"bytes,1,opt,name=key"` + + // valueExpression represents the expression which is evaluated by CEL to + // produce an audit annotation value. The expression must evaluate to either + // a string or null value. If the expression evaluates to a string, the + // audit annotation is included with the string value. If the expression + // evaluates to null or empty string the audit annotation will be omitted. + // The valueExpression may be no longer than 5kb in length. + // If the result of the valueExpression is more than 10kb in length, it + // will be truncated to 10kb. + // + // If multiple ValidatingAdmissionPolicyBinding resources match an + // API request, then the valueExpression will be evaluated for + // each binding. All unique values produced by the valueExpressions + // will be joined together in a comma-separated list. + // + // Required. + ValueExpression string `json:"valueExpression" protobuf:"bytes,2,opt,name=valueExpression"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. +// ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters. +type ValidatingAdmissionPolicyBinding struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. +type ValidatingAdmissionPolicyBindingList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // List of PolicyBinding. + Items []ValidatingAdmissionPolicyBinding `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"` +} + +// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. +type ValidatingAdmissionPolicyBindingSpec struct { + // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // If the referenced resource does not exist, this binding is considered invalid and will be ignored + // Required. + PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"` + + // ParamRef specifies the parameter resource used to configure the admission control policy. + // It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. + // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. + // +optional + ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"` + + // MatchResources declares what resources match this binding and will be validated by it. + // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. + // If this is unset, all resources matched by the policy are validated by this binding + // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. + // Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required. + // +optional + MatchResources *MatchResources `json:"matchResources,omitempty" protobuf:"bytes,3,rep,name=matchResources"` + + // validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. + // If a validation evaluates to false it is always enforced according to these actions. + // + // Failures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according + // to these actions only if the FailurePolicy is set to Fail, otherwise the failures are + // ignored. This includes compilation errors, runtime errors and misconfigurations of the policy. + // + // validationActions is declared as a set of action values. Order does + // not matter. validationActions may not contain duplicates of the same action. + // + // The supported actions values are: + // + // "Deny" specifies that a validation failure results in a denied request. + // + // "Warn" specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + // + // "Audit" specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failures, formatted as + // a JSON list of objects, each with the following fields: + // - message: The validation failure message string + // - policy: The resource name of the ValidatingAdmissionPolicy + // - binding: The resource name of the ValidatingAdmissionPolicyBinding + // - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy + // - validationActions: The enforcement actions enacted for the validation failure + // Example audit annotation: + // `"validation.policy.admission.k8s.io/validation_failure": "[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]"` + // + // Clients should expect to handle additional values by ignoring + // any values not recognized. + // + // "Deny" and "Warn" may not be used together since this combination + // needlessly duplicates the validation failure both in the + // API response body and the HTTP warning headers. + // + // Required. + // +listType=set + ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"` +} + +// ParamRef references a parameter resource +// +structType=atomic +type ParamRef struct { + // Name of the resource being referenced. + Name string `json:"name,omitempty" protobuf:"bytes,1,rep,name=name"` + // Namespace of the referenced resource. + // Should be empty for the cluster-scoped resources + // +optional + Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,rep,name=namespace"` +} + +// MatchResources decides whether to run the admission control policy on an object based +// on whether it meets the match criteria. +// The exclude rules take precedence over include rules (if a resource matches both, it is excluded) +// +structType=atomic +type MatchResources struct { + // NamespaceSelector decides whether to run the admission control policy on an object based + // on whether the namespace for that object matches the selector. If the + // object itself is a namespace, the matching is performed on + // object.metadata.labels. If the object is another cluster scoped resource, + // it never skips the policy. + // + // For example, to run the webhook on any objects whose namespace is not + // associated with "runlevel" of "0" or "1"; you will set the selector as + // follows: + // "namespaceSelector": { + // "matchExpressions": [ + // { + // "key": "runlevel", + // "operator": "NotIn", + // "values": [ + // "0", + // "1" + // ] + // } + // ] + // } + // + // If instead you want to only run the policy on any objects whose + // namespace is associated with the "environment" of "prod" or "staging"; + // you will set the selector as follows: + // "namespaceSelector": { + // "matchExpressions": [ + // { + // "key": "environment", + // "operator": "In", + // "values": [ + // "prod", + // "staging" + // ] + // } + // ] + // } + // + // See + // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + // for more examples of label selectors. + // + // Default to the empty LabelSelector, which matches everything. + // +optional + NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"` + // ObjectSelector decides whether to run the validation based on if the + // object has matching labels. objectSelector is evaluated against both + // the oldObject and newObject that would be sent to the cel validation, and + // is considered to match if either object matches the selector. A null + // object (oldObject in the case of create, or newObject in the case of + // delete) or an object that cannot have labels (like a + // DeploymentRollback or a PodProxyOptions object) is not considered to + // match. + // Use the object selector only if the webhook is opt-in, because end + // users may skip the admission webhook by setting the labels. + // Default to the empty LabelSelector, which matches everything. + // +optional + ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"` + // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // The policy cares about an operation if it matches _any_ Rule. + // +listType=atomic + // +optional + ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"` + // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) + // +listType=atomic + // +optional + ExcludeResourceRules []NamedRuleWithOperations `json:"excludeResourceRules,omitempty" protobuf:"bytes,4,rep,name=excludeResourceRules"` + // matchPolicy defines how the "MatchResources" list is used to match incoming requests. + // Allowed values are "Exact" or "Equivalent". + // + // - Exact: match a request only if it exactly matches a specified rule. + // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, + // but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, + // a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy. + // + // - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. + // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, + // and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, + // a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy. + // + // Defaults to "Equivalent" + // +optional + MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,7,opt,name=matchPolicy,casttype=MatchPolicyType"` +} + +// ValidationAction specifies a policy enforcement action. +// +enum +type ValidationAction string + +const ( + // Deny specifies that a validation failure results in a denied request. + Deny ValidationAction = "Deny" + // Warn specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + Warn ValidationAction = "Warn" + // Audit specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failure. + Audit ValidationAction = "Audit" +) + +// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. +// +structType=atomic +type NamedRuleWithOperations struct { + // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // +listType=atomic + // +optional + ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"` + // RuleWithOperations is a tuple of Operations and Resources. + RuleWithOperations `json:",inline" protobuf:"bytes,2,opt,name=ruleWithOperations"` +} + +// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make +// sure that all the tuple expansions are valid. +type RuleWithOperations = v1.RuleWithOperations + +// OperationType specifies an operation for a request. +// +enum +type OperationType = v1.OperationType + +// The constants should be kept in sync with those defined in k8s.io/kubernetes/pkg/admission/interface.go. +const ( + OperationAll OperationType = v1.OperationAll + Create OperationType = v1.Create + Update OperationType = v1.Update + Delete OperationType = v1.Delete + Connect OperationType = v1.Connect +) diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 00000000000..b3cac1821ba --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,191 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_AuditAnnotation = map[string]string{ + "": "AuditAnnotation describes how to produce an audit annotation for an API request.", + "key": "key specifies the audit annotation key. The audit annotation keys of a ValidatingAdmissionPolicy must be unique. The key must be a qualified name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length.\n\nThe key is combined with the resource name of the ValidatingAdmissionPolicy to construct an audit annotation key: \"{ValidatingAdmissionPolicy name}/{key}\".\n\nIf an admission webhook uses the same resource name as this ValidatingAdmissionPolicy and the same audit annotation key, the annotation key will be identical. In this case, the first annotation written with the key will be included in the audit event and all subsequent annotations with the same key will be discarded.\n\nRequired.", + "valueExpression": "valueExpression represents the expression which is evaluated by CEL to produce an audit annotation value. The expression must evaluate to either a string or null value. If the expression evaluates to a string, the audit annotation is included with the string value. If the expression evaluates to null or empty string the audit annotation will be omitted. The valueExpression may be no longer than 5kb in length. If the result of the valueExpression is more than 10kb in length, it will be truncated to 10kb.\n\nIf multiple ValidatingAdmissionPolicyBinding resources match an API request, then the valueExpression will be evaluated for each binding. All unique values produced by the valueExpressions will be joined together in a comma-separated list.\n\nRequired.", +} + +func (AuditAnnotation) SwaggerDoc() map[string]string { + return map_AuditAnnotation +} + +var map_ExpressionWarning = map[string]string{ + "": "ExpressionWarning is a warning information that targets a specific expression.", + "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", + "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", +} + +func (ExpressionWarning) SwaggerDoc() map[string]string { + return map_ExpressionWarning +} + +var map_MatchResources = map[string]string{ + "": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", + "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"", +} + +func (MatchResources) SwaggerDoc() map[string]string { + return map_MatchResources +} + +var map_NamedRuleWithOperations = map[string]string{ + "": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.", + "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", +} + +func (NamedRuleWithOperations) SwaggerDoc() map[string]string { + return map_NamedRuleWithOperations +} + +var map_ParamKind = map[string]string{ + "": "ParamKind is a tuple of Group Kind and Version.", + "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.", + "kind": "Kind is the API kind the resources belong to. Required.", +} + +func (ParamKind) SwaggerDoc() map[string]string { + return map_ParamKind +} + +var map_ParamRef = map[string]string{ + "": "ParamRef references a parameter resource", + "name": "Name of the resource being referenced.", + "namespace": "Namespace of the referenced resource. Should be empty for the cluster-scoped resources", +} + +func (ParamRef) SwaggerDoc() map[string]string { + return map_ParamRef +} + +var map_TypeChecking = map[string]string{ + "": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy", + "expressionWarnings": "The type checking warnings for each expression.", +} + +func (TypeChecking) SwaggerDoc() map[string]string { + return map_TypeChecking +} + +var map_ValidatingAdmissionPolicy = map[string]string{ + "": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.", + "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.", + "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", +} + +func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicy +} + +var map_ValidatingAdmissionPolicyBinding = map[string]string{ + "": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.", + "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.", +} + +func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyBinding +} + +var map_ValidatingAdmissionPolicyBindingList = map[string]string{ + "": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.", + "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "items": "List of PolicyBinding.", +} + +func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyBindingList +} + +var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{ + "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", + "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "paramRef": "ParamRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied.", + "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.", +} + +func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyBindingSpec +} + +var map_ValidatingAdmissionPolicyList = map[string]string{ + "": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.", + "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "items": "List of ValidatingAdmissionPolicy.", +} + +func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyList +} + +var map_ValidatingAdmissionPolicySpec = map[string]string{ + "": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.", + "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", + "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", + "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", + "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", + "auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", +} + +func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicySpec +} + +var map_ValidatingAdmissionPolicyStatus = map[string]string{ + "": "ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.", + "observedGeneration": "The generation observed by the controller.", + "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.", + "conditions": "The conditions represent the latest available observations of a policy's current state.", +} + +func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyStatus +} + +var map_Validation = map[string]string{ + "": "Validation specifies the CEL expression which is used to apply the validation.", + "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", + "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", + "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"", +} + +func (Validation) SwaggerDoc() map[string]string { + return map_Validation +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..8e4abfd0877 --- /dev/null +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,444 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuditAnnotation) DeepCopyInto(out *AuditAnnotation) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuditAnnotation. +func (in *AuditAnnotation) DeepCopy() *AuditAnnotation { + if in == nil { + return nil + } + out := new(AuditAnnotation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpressionWarning) DeepCopyInto(out *ExpressionWarning) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpressionWarning. +func (in *ExpressionWarning) DeepCopy() *ExpressionWarning { + if in == nil { + return nil + } + out := new(ExpressionWarning) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchResources) DeepCopyInto(out *MatchResources) { + *out = *in + if in.NamespaceSelector != nil { + in, out := &in.NamespaceSelector, &out.NamespaceSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.ObjectSelector != nil { + in, out := &in.ObjectSelector, &out.ObjectSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.ResourceRules != nil { + in, out := &in.ResourceRules, &out.ResourceRules + *out = make([]NamedRuleWithOperations, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExcludeResourceRules != nil { + in, out := &in.ExcludeResourceRules, &out.ExcludeResourceRules + *out = make([]NamedRuleWithOperations, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MatchPolicy != nil { + in, out := &in.MatchPolicy, &out.MatchPolicy + *out = new(MatchPolicyType) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchResources. +func (in *MatchResources) DeepCopy() *MatchResources { + if in == nil { + return nil + } + out := new(MatchResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedRuleWithOperations) DeepCopyInto(out *NamedRuleWithOperations) { + *out = *in + if in.ResourceNames != nil { + in, out := &in.ResourceNames, &out.ResourceNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.RuleWithOperations.DeepCopyInto(&out.RuleWithOperations) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedRuleWithOperations. +func (in *NamedRuleWithOperations) DeepCopy() *NamedRuleWithOperations { + if in == nil { + return nil + } + out := new(NamedRuleWithOperations) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParamKind) DeepCopyInto(out *ParamKind) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParamKind. +func (in *ParamKind) DeepCopy() *ParamKind { + if in == nil { + return nil + } + out := new(ParamKind) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParamRef) DeepCopyInto(out *ParamRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParamRef. +func (in *ParamRef) DeepCopy() *ParamRef { + if in == nil { + return nil + } + out := new(ParamRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TypeChecking) DeepCopyInto(out *TypeChecking) { + *out = *in + if in.ExpressionWarnings != nil { + in, out := &in.ExpressionWarnings, &out.ExpressionWarnings + *out = make([]ExpressionWarning, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TypeChecking. +func (in *TypeChecking) DeepCopy() *TypeChecking { + if in == nil { + return nil + } + out := new(TypeChecking) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicy) DeepCopyInto(out *ValidatingAdmissionPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicy. +func (in *ValidatingAdmissionPolicy) DeepCopy() *ValidatingAdmissionPolicy { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyBinding) DeepCopyInto(out *ValidatingAdmissionPolicyBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyBinding. +func (in *ValidatingAdmissionPolicyBinding) DeepCopy() *ValidatingAdmissionPolicyBinding { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicyBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyBindingList) DeepCopyInto(out *ValidatingAdmissionPolicyBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ValidatingAdmissionPolicyBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyBindingList. +func (in *ValidatingAdmissionPolicyBindingList) DeepCopy() *ValidatingAdmissionPolicyBindingList { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicyBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyBindingSpec) DeepCopyInto(out *ValidatingAdmissionPolicyBindingSpec) { + *out = *in + if in.ParamRef != nil { + in, out := &in.ParamRef, &out.ParamRef + *out = new(ParamRef) + **out = **in + } + if in.MatchResources != nil { + in, out := &in.MatchResources, &out.MatchResources + *out = new(MatchResources) + (*in).DeepCopyInto(*out) + } + if in.ValidationActions != nil { + in, out := &in.ValidationActions, &out.ValidationActions + *out = make([]ValidationAction, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyBindingSpec. +func (in *ValidatingAdmissionPolicyBindingSpec) DeepCopy() *ValidatingAdmissionPolicyBindingSpec { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyBindingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyList) DeepCopyInto(out *ValidatingAdmissionPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ValidatingAdmissionPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyList. +func (in *ValidatingAdmissionPolicyList) DeepCopy() *ValidatingAdmissionPolicyList { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicySpec) DeepCopyInto(out *ValidatingAdmissionPolicySpec) { + *out = *in + if in.ParamKind != nil { + in, out := &in.ParamKind, &out.ParamKind + *out = new(ParamKind) + **out = **in + } + if in.MatchConstraints != nil { + in, out := &in.MatchConstraints, &out.MatchConstraints + *out = new(MatchResources) + (*in).DeepCopyInto(*out) + } + if in.Validations != nil { + in, out := &in.Validations, &out.Validations + *out = make([]Validation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.FailurePolicy != nil { + in, out := &in.FailurePolicy, &out.FailurePolicy + *out = new(FailurePolicyType) + **out = **in + } + if in.AuditAnnotations != nil { + in, out := &in.AuditAnnotations, &out.AuditAnnotations + *out = make([]AuditAnnotation, len(*in)) + copy(*out, *in) + } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicySpec. +func (in *ValidatingAdmissionPolicySpec) DeepCopy() *ValidatingAdmissionPolicySpec { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyStatus) DeepCopyInto(out *ValidatingAdmissionPolicyStatus) { + *out = *in + if in.TypeChecking != nil { + in, out := &in.TypeChecking, &out.TypeChecking + *out = new(TypeChecking) + (*in).DeepCopyInto(*out) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyStatus. +func (in *ValidatingAdmissionPolicyStatus) DeepCopy() *ValidatingAdmissionPolicyStatus { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Validation) DeepCopyInto(out *Validation) { + *out = *in + if in.Reason != nil { + in, out := &in.Reason, &out.Reason + *out = new(v1.StatusReason) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Validation. +func (in *Validation) DeepCopy() *Validation { + if in == nil { + return nil + } + out := new(Validation) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go index e2899ea171b..8fb354c319a 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go @@ -25,7 +25,8 @@ import ( io "io" proto "github.com/gogo/protobuf/proto" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/admissionregistration/v1" + v11 "k8s.io/apimachinery/pkg/apis/meta/v1" math "math" math_bits "math/bits" @@ -44,10 +45,38 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_abeea74cbc46f55a, []int{0} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} } func (*MutatingWebhook) ProtoMessage() {} func (*MutatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{0} + return fileDescriptor_abeea74cbc46f55a, []int{1} } func (m *MutatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +104,7 @@ var xxx_messageInfo_MutatingWebhook proto.InternalMessageInfo func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} } func (*MutatingWebhookConfiguration) ProtoMessage() {} func (*MutatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{1} + return fileDescriptor_abeea74cbc46f55a, []int{2} } func (m *MutatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +132,7 @@ var xxx_messageInfo_MutatingWebhookConfiguration proto.InternalMessageInfo func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} } func (*MutatingWebhookConfigurationList) ProtoMessage() {} func (*MutatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{2} + return fileDescriptor_abeea74cbc46f55a, []int{3} } func (m *MutatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -128,66 +157,10 @@ func (m *MutatingWebhookConfigurationList) XXX_DiscardUnknown() { var xxx_messageInfo_MutatingWebhookConfigurationList proto.InternalMessageInfo -func (m *Rule) Reset() { *m = Rule{} } -func (*Rule) ProtoMessage() {} -func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{3} -} -func (m *Rule) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *Rule) XXX_Merge(src proto.Message) { - xxx_messageInfo_Rule.Merge(m, src) -} -func (m *Rule) XXX_Size() int { - return m.Size() -} -func (m *Rule) XXX_DiscardUnknown() { - xxx_messageInfo_Rule.DiscardUnknown(m) -} - -var xxx_messageInfo_Rule proto.InternalMessageInfo - -func (m *RuleWithOperations) Reset() { *m = RuleWithOperations{} } -func (*RuleWithOperations) ProtoMessage() {} -func (*RuleWithOperations) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{4} -} -func (m *RuleWithOperations) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RuleWithOperations) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *RuleWithOperations) XXX_Merge(src proto.Message) { - xxx_messageInfo_RuleWithOperations.Merge(m, src) -} -func (m *RuleWithOperations) XXX_Size() int { - return m.Size() -} -func (m *RuleWithOperations) XXX_DiscardUnknown() { - xxx_messageInfo_RuleWithOperations.DiscardUnknown(m) -} - -var xxx_messageInfo_RuleWithOperations proto.InternalMessageInfo - func (m *ServiceReference) Reset() { *m = ServiceReference{} } func (*ServiceReference) ProtoMessage() {} func (*ServiceReference) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{5} + return fileDescriptor_abeea74cbc46f55a, []int{4} } func (m *ServiceReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -215,7 +188,7 @@ var xxx_messageInfo_ServiceReference proto.InternalMessageInfo func (m *ValidatingWebhook) Reset() { *m = ValidatingWebhook{} } func (*ValidatingWebhook) ProtoMessage() {} func (*ValidatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{6} + return fileDescriptor_abeea74cbc46f55a, []int{5} } func (m *ValidatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -243,7 +216,7 @@ var xxx_messageInfo_ValidatingWebhook proto.InternalMessageInfo func (m *ValidatingWebhookConfiguration) Reset() { *m = ValidatingWebhookConfiguration{} } func (*ValidatingWebhookConfiguration) ProtoMessage() {} func (*ValidatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{7} + return fileDescriptor_abeea74cbc46f55a, []int{6} } func (m *ValidatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -271,7 +244,7 @@ var xxx_messageInfo_ValidatingWebhookConfiguration proto.InternalMessageInfo func (m *ValidatingWebhookConfigurationList) Reset() { *m = ValidatingWebhookConfigurationList{} } func (*ValidatingWebhookConfigurationList) ProtoMessage() {} func (*ValidatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{8} + return fileDescriptor_abeea74cbc46f55a, []int{7} } func (m *ValidatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -299,7 +272,7 @@ var xxx_messageInfo_ValidatingWebhookConfigurationList proto.InternalMessageInfo func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } func (*WebhookClientConfig) ProtoMessage() {} func (*WebhookClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{9} + return fileDescriptor_abeea74cbc46f55a, []int{8} } func (m *WebhookClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -325,11 +298,10 @@ func (m *WebhookClientConfig) XXX_DiscardUnknown() { var xxx_messageInfo_WebhookClientConfig proto.InternalMessageInfo func init() { + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1beta1.MatchCondition") proto.RegisterType((*MutatingWebhook)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhook") proto.RegisterType((*MutatingWebhookConfiguration)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhookConfiguration") proto.RegisterType((*MutatingWebhookConfigurationList)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhookConfigurationList") - proto.RegisterType((*Rule)(nil), "k8s.io.api.admissionregistration.v1beta1.Rule") - proto.RegisterType((*RuleWithOperations)(nil), "k8s.io.api.admissionregistration.v1beta1.RuleWithOperations") proto.RegisterType((*ServiceReference)(nil), "k8s.io.api.admissionregistration.v1beta1.ServiceReference") proto.RegisterType((*ValidatingWebhook)(nil), "k8s.io.api.admissionregistration.v1beta1.ValidatingWebhook") proto.RegisterType((*ValidatingWebhookConfiguration)(nil), "k8s.io.api.admissionregistration.v1beta1.ValidatingWebhookConfiguration") @@ -342,77 +314,106 @@ func init() { } var fileDescriptor_abeea74cbc46f55a = []byte{ - // 1112 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4b, 0x6f, 0x23, 0x45, - 0x10, 0xce, 0xc4, 0xf6, 0xc6, 0x6e, 0xe7, 0xb1, 0x69, 0x60, 0xd7, 0x84, 0x95, 0xc7, 0xf2, 0x01, - 0x59, 0x02, 0x66, 0x36, 0x01, 0x21, 0x58, 0x40, 0x28, 0x0e, 0x2c, 0x44, 0x4a, 0xb2, 0xa1, 0xb3, - 0x0f, 0x89, 0x87, 0xb4, 0xed, 0x71, 0xd9, 0x6e, 0x6c, 0x4f, 0x8f, 0xa6, 0x7b, 0xbc, 0xe4, 0xc6, - 0x4f, 0xe0, 0x2f, 0x70, 0xe2, 0x57, 0x70, 0xe0, 0x16, 0x6e, 0x7b, 0xdc, 0x0b, 0x23, 0x32, 0x9c, - 0x38, 0x70, 0xe0, 0x9a, 0x13, 0xea, 0x9e, 0xf1, 0xf8, 0x95, 0x2c, 0x26, 0x48, 0x7b, 0xca, 0xcd, - 0xfd, 0x55, 0xd7, 0x57, 0x5d, 0x35, 0x55, 0xf5, 0xc9, 0xe8, 0x8b, 0xee, 0x7b, 0xc2, 0x62, 0xdc, - 0xee, 0x06, 0x0d, 0xf0, 0x5d, 0x90, 0x20, 0xec, 0x01, 0xb8, 0x4d, 0xee, 0xdb, 0x89, 0x81, 0x7a, - 0xcc, 0xa6, 0xcd, 0x3e, 0x13, 0x82, 0x71, 0xd7, 0x87, 0x36, 0x13, 0xd2, 0xa7, 0x92, 0x71, 0xd7, - 0x1e, 0x6c, 0x36, 0x40, 0xd2, 0x4d, 0xbb, 0x0d, 0x2e, 0xf8, 0x54, 0x42, 0xd3, 0xf2, 0x7c, 0x2e, - 0x39, 0xae, 0xc5, 0x9e, 0x16, 0xf5, 0x98, 0x75, 0xae, 0xa7, 0x95, 0x78, 0x6e, 0xbc, 0xd5, 0x66, - 0xb2, 0x13, 0x34, 0x2c, 0x87, 0xf7, 0xed, 0x36, 0x6f, 0x73, 0x5b, 0x13, 0x34, 0x82, 0x96, 0x3e, - 0xe9, 0x83, 0xfe, 0x15, 0x13, 0x6f, 0xbc, 0x33, 0x7a, 0x52, 0x9f, 0x3a, 0x1d, 0xe6, 0x82, 0x7f, - 0x6c, 0x7b, 0xdd, 0xb6, 0x02, 0x84, 0xdd, 0x07, 0x49, 0xed, 0xc1, 0xcc, 0x73, 0x36, 0xec, 0x8b, - 0xbc, 0xfc, 0xc0, 0x95, 0xac, 0x0f, 0x33, 0x0e, 0xef, 0xfe, 0x9b, 0x83, 0x70, 0x3a, 0xd0, 0xa7, - 0xd3, 0x7e, 0xd5, 0x5f, 0x97, 0xd0, 0xda, 0x7e, 0x20, 0xa9, 0x64, 0x6e, 0xfb, 0x11, 0x34, 0x3a, - 0x9c, 0x77, 0x71, 0x05, 0x65, 0x5d, 0xda, 0x87, 0x92, 0x51, 0x31, 0x6a, 0x85, 0xfa, 0xf2, 0x49, - 0x68, 0x2e, 0x44, 0xa1, 0x99, 0x3d, 0xa0, 0x7d, 0x20, 0xda, 0x82, 0x9f, 0xa0, 0x65, 0xa7, 0xc7, - 0xc0, 0x95, 0x3b, 0xdc, 0x6d, 0xb1, 0x76, 0x69, 0xb1, 0x62, 0xd4, 0x8a, 0x5b, 0x1f, 0x59, 0xf3, - 0x16, 0xd1, 0x4a, 0x42, 0xed, 0x8c, 0x91, 0xd4, 0x5f, 0x4e, 0x02, 0x2d, 0x8f, 0xa3, 0x64, 0x22, - 0x10, 0xa6, 0x28, 0xe7, 0x07, 0x3d, 0x10, 0xa5, 0x4c, 0x25, 0x53, 0x2b, 0x6e, 0x7d, 0x38, 0x7f, - 0x44, 0x12, 0xf4, 0xe0, 0x11, 0x93, 0x9d, 0x7b, 0x1e, 0xc4, 0x16, 0x51, 0x5f, 0x49, 0x02, 0xe6, - 0x94, 0x4d, 0x90, 0x98, 0x19, 0xef, 0xa1, 0x95, 0x16, 0x65, 0xbd, 0xc0, 0x87, 0x43, 0xde, 0x63, - 0xce, 0x71, 0x29, 0xab, 0xcb, 0xf0, 0x7a, 0x14, 0x9a, 0x2b, 0x77, 0xc7, 0x0d, 0x67, 0xa1, 0xb9, - 0x3e, 0x01, 0xdc, 0x3f, 0xf6, 0x80, 0x4c, 0x3a, 0xe3, 0x4f, 0x50, 0xb1, 0x4f, 0xa5, 0xd3, 0x49, - 0xb8, 0x0a, 0x9a, 0xab, 0x1a, 0x85, 0x66, 0x71, 0x7f, 0x04, 0x9f, 0x85, 0xe6, 0xda, 0xd8, 0x51, - 0xf3, 0x8c, 0xbb, 0xe1, 0xef, 0xd0, 0xba, 0xaa, 0xbb, 0xf0, 0xa8, 0x03, 0x47, 0xd0, 0x03, 0x47, - 0x72, 0xbf, 0x94, 0xd3, 0x45, 0x7f, 0x7b, 0xac, 0x04, 0xe9, 0x97, 0xb7, 0xbc, 0x6e, 0x5b, 0x01, - 0xc2, 0x52, 0x0d, 0x66, 0x0d, 0x36, 0xad, 0x3d, 0xda, 0x80, 0xde, 0xd0, 0xb5, 0xfe, 0x4a, 0x14, - 0x9a, 0xeb, 0x07, 0xd3, 0x8c, 0x64, 0x36, 0x08, 0xe6, 0x68, 0x95, 0x37, 0xbe, 0x05, 0x47, 0xa6, - 0x61, 0x8b, 0x97, 0x0f, 0x8b, 0xa3, 0xd0, 0x5c, 0xbd, 0x37, 0x41, 0x47, 0xa6, 0xe8, 0x55, 0xc1, - 0x04, 0x6b, 0xc2, 0xa7, 0xad, 0x16, 0x38, 0x52, 0x94, 0xae, 0x8d, 0x0a, 0x76, 0x34, 0x82, 0x55, - 0xc1, 0x46, 0xc7, 0x9d, 0x1e, 0x15, 0x82, 0x8c, 0xbb, 0xe1, 0x3b, 0x68, 0x55, 0x75, 0x3d, 0x0f, - 0xe4, 0x11, 0x38, 0xdc, 0x6d, 0x8a, 0xd2, 0x52, 0xc5, 0xa8, 0xe5, 0xe2, 0x17, 0xdc, 0x9f, 0xb0, - 0x90, 0xa9, 0x9b, 0xf8, 0x01, 0xba, 0x99, 0xb6, 0x12, 0x81, 0x01, 0x83, 0x27, 0x0f, 0xc1, 0x57, - 0x07, 0x51, 0xca, 0x57, 0x32, 0xb5, 0x42, 0xfd, 0xb5, 0x28, 0x34, 0x6f, 0x6e, 0x9f, 0x7f, 0x85, - 0x5c, 0xe4, 0x8b, 0x1f, 0x23, 0xec, 0x03, 0x73, 0x07, 0xdc, 0xd1, 0xed, 0x97, 0x34, 0x04, 0xd2, - 0xf9, 0xdd, 0x8e, 0x42, 0x13, 0x93, 0x19, 0xeb, 0x59, 0x68, 0xde, 0x98, 0x45, 0x75, 0x7b, 0x9c, - 0xc3, 0x55, 0xfd, 0xcd, 0x40, 0xb7, 0xa6, 0x66, 0x39, 0x1e, 0x9b, 0x20, 0xee, 0x78, 0xfc, 0x18, - 0xe5, 0xd5, 0x87, 0x69, 0x52, 0x49, 0xf5, 0x70, 0x17, 0xb7, 0x6e, 0xcf, 0xf7, 0x19, 0xe3, 0x6f, - 0xb6, 0x0f, 0x92, 0xd6, 0x71, 0x32, 0x34, 0x68, 0x84, 0x91, 0x94, 0x15, 0x7f, 0x85, 0xf2, 0x49, - 0x64, 0x51, 0x5a, 0xd4, 0x23, 0xfa, 0xfe, 0xfc, 0x23, 0x3a, 0xf5, 0xf6, 0x7a, 0x56, 0x85, 0x22, - 0x29, 0x61, 0xf5, 0x2f, 0x03, 0x55, 0x9e, 0x97, 0xdf, 0x1e, 0x13, 0x12, 0x7f, 0x3d, 0x93, 0xa3, - 0x35, 0x67, 0xab, 0x32, 0x11, 0x67, 0x78, 0x3d, 0xc9, 0x30, 0x3f, 0x44, 0xc6, 0xf2, 0xeb, 0xa2, - 0x1c, 0x93, 0xd0, 0x1f, 0x26, 0x77, 0xf7, 0xd2, 0xc9, 0x4d, 0x3c, 0x7c, 0xb4, 0x89, 0x76, 0x15, - 0x39, 0x89, 0x63, 0x54, 0x7f, 0x31, 0x50, 0x56, 0xad, 0x26, 0xfc, 0x06, 0x2a, 0x50, 0x8f, 0x7d, - 0xe6, 0xf3, 0xc0, 0x13, 0x25, 0x43, 0xf7, 0xe0, 0x4a, 0x14, 0x9a, 0x85, 0xed, 0xc3, 0xdd, 0x18, - 0x24, 0x23, 0x3b, 0xde, 0x44, 0x45, 0xea, 0xb1, 0xb4, 0x65, 0x17, 0xf5, 0xf5, 0x35, 0x35, 0x40, - 0xdb, 0x87, 0xbb, 0x69, 0x9b, 0x8e, 0xdf, 0x51, 0xfc, 0x3e, 0x08, 0x1e, 0xf8, 0x4e, 0xb2, 0x59, - 0x13, 0x7e, 0x32, 0x04, 0xc9, 0xc8, 0x8e, 0xdf, 0x44, 0x39, 0xe1, 0x70, 0x0f, 0x92, 0xbd, 0x78, - 0x43, 0x3d, 0xfb, 0x48, 0x01, 0x67, 0xa1, 0x59, 0xd0, 0x3f, 0x74, 0x83, 0xc6, 0x97, 0xaa, 0x3f, - 0x19, 0x08, 0xcf, 0xae, 0x5e, 0xfc, 0x31, 0x42, 0x3c, 0x3d, 0x25, 0x29, 0x99, 0xba, 0xab, 0x52, - 0xf4, 0x2c, 0x34, 0x57, 0xd2, 0x93, 0xa6, 0x1c, 0x73, 0xc1, 0x87, 0x28, 0xab, 0xd6, 0x75, 0xa2, - 0x3c, 0xd6, 0x7f, 0xd3, 0x81, 0x91, 0xa6, 0xa9, 0x13, 0xd1, 0x4c, 0xd5, 0x1f, 0x0d, 0x74, 0xfd, - 0x08, 0xfc, 0x01, 0x73, 0x80, 0x40, 0x0b, 0x7c, 0x70, 0x1d, 0xc0, 0x36, 0x2a, 0xa4, 0x3b, 0x31, - 0xd1, 0xc3, 0xf5, 0xc4, 0xb7, 0x90, 0xee, 0x4f, 0x32, 0xba, 0x93, 0x6a, 0xe7, 0xe2, 0x85, 0xda, - 0x79, 0x0b, 0x65, 0x3d, 0x2a, 0x3b, 0xa5, 0x8c, 0xbe, 0x91, 0x57, 0xd6, 0x43, 0x2a, 0x3b, 0x44, - 0xa3, 0xda, 0xca, 0x7d, 0xa9, 0x8b, 0x9b, 0x4b, 0xac, 0xdc, 0x97, 0x44, 0xa3, 0xd5, 0x3f, 0xaf, - 0xa1, 0xf5, 0x87, 0xb4, 0xc7, 0x9a, 0x57, 0x7a, 0x7d, 0xa5, 0xd7, 0x73, 0xea, 0x35, 0xba, 0xd2, - 0xeb, 0xcb, 0xe8, 0x75, 0xf5, 0xd4, 0x40, 0xe5, 0x99, 0x59, 0x7b, 0xd1, 0x7a, 0xfa, 0xcd, 0x8c, - 0x9e, 0x7e, 0x30, 0xff, 0x08, 0xcd, 0xbc, 0x7e, 0x46, 0x51, 0xff, 0x36, 0x50, 0xf5, 0xf9, 0x39, - 0xbe, 0x00, 0x4d, 0xed, 0x4f, 0x6a, 0xea, 0xe7, 0xff, 0x23, 0xc1, 0x79, 0x54, 0xf5, 0x67, 0x03, - 0xbd, 0x74, 0xce, 0x3a, 0xc3, 0xaf, 0xa2, 0x4c, 0xe0, 0xf7, 0x92, 0xb5, 0xbc, 0x14, 0x85, 0x66, - 0xe6, 0x01, 0xd9, 0x23, 0x0a, 0xc3, 0x14, 0x2d, 0x89, 0x58, 0x19, 0x92, 0xf4, 0xef, 0xcc, 0xff, - 0xc6, 0x69, 0x49, 0xa9, 0x17, 0xa3, 0xd0, 0x5c, 0x1a, 0xa2, 0x43, 0x5e, 0x5c, 0x43, 0x79, 0x87, - 0xd6, 0x03, 0xb7, 0x99, 0x68, 0xda, 0x72, 0x7d, 0x59, 0x95, 0x6b, 0x67, 0x3b, 0xc6, 0x48, 0x6a, - 0xad, 0x1f, 0x9c, 0x9c, 0x96, 0x17, 0x9e, 0x9e, 0x96, 0x17, 0x9e, 0x9d, 0x96, 0x17, 0xbe, 0x8f, - 0xca, 0xc6, 0x49, 0x54, 0x36, 0x9e, 0x46, 0x65, 0xe3, 0x59, 0x54, 0x36, 0x7e, 0x8f, 0xca, 0xc6, - 0x0f, 0x7f, 0x94, 0x17, 0xbe, 0xac, 0xcd, 0xfb, 0x4f, 0xf8, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x29, 0xe6, 0x3d, 0x13, 0x4d, 0x0f, 0x00, 0x00, + // 1041 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4f, 0x73, 0xdb, 0xc4, + 0x1b, 0x8e, 0xe2, 0xf8, 0x17, 0x67, 0xed, 0x24, 0xcd, 0xfe, 0x80, 0x88, 0xd0, 0xb1, 0x3c, 0x3e, + 0x30, 0xbe, 0x20, 0xb5, 0x29, 0x03, 0xa5, 0x0c, 0x87, 0x2a, 0xb4, 0x03, 0x33, 0x49, 0x5a, 0x36, + 0xfd, 0x33, 0x03, 0x65, 0xa6, 0x6b, 0xf9, 0xb5, 0xbd, 0x58, 0xd2, 0x7a, 0xb4, 0xab, 0xb4, 0x19, + 0x2e, 0x7c, 0x04, 0xbe, 0x02, 0x1f, 0x84, 0x03, 0xb7, 0x1c, 0x7b, 0xec, 0x05, 0x0d, 0x11, 0x67, + 0x0e, 0x5c, 0x73, 0x62, 0xb4, 0x52, 0x6c, 0xcb, 0x76, 0x5a, 0x11, 0x66, 0x72, 0xca, 0xcd, 0xfb, + 0xbc, 0xfb, 0xbe, 0xcf, 0x3e, 0xab, 0x77, 0xdf, 0x67, 0x8c, 0xbe, 0x19, 0xdc, 0x16, 0x26, 0xe3, + 0xd6, 0x20, 0x6c, 0x43, 0xe0, 0x83, 0x04, 0x61, 0x1d, 0x82, 0xdf, 0xe1, 0x81, 0x95, 0x05, 0xe8, + 0x90, 0x59, 0xb4, 0xe3, 0x31, 0x21, 0x18, 0xf7, 0x03, 0xe8, 0x31, 0x21, 0x03, 0x2a, 0x19, 0xf7, + 0xad, 0xc3, 0x9b, 0x6d, 0x90, 0xf4, 0xa6, 0xd5, 0x03, 0x1f, 0x02, 0x2a, 0xa1, 0x63, 0x0e, 0x03, + 0x2e, 0x39, 0x6e, 0xa5, 0x99, 0x26, 0x1d, 0x32, 0x73, 0x6e, 0xa6, 0x99, 0x65, 0x6e, 0x7d, 0xd4, + 0x63, 0xb2, 0x1f, 0xb6, 0x4d, 0x87, 0x7b, 0x56, 0x8f, 0xf7, 0xb8, 0xa5, 0x0a, 0xb4, 0xc3, 0xae, + 0x5a, 0xa9, 0x85, 0xfa, 0x95, 0x16, 0xde, 0xba, 0x55, 0xe0, 0x48, 0xd3, 0xa7, 0xd9, 0xfa, 0x78, + 0x9c, 0xe4, 0x51, 0xa7, 0xcf, 0x7c, 0x08, 0x8e, 0xac, 0xe1, 0xa0, 0x97, 0x00, 0xc2, 0xf2, 0x40, + 0xd2, 0x79, 0x59, 0xd6, 0x79, 0x59, 0x41, 0xe8, 0x4b, 0xe6, 0xc1, 0x4c, 0xc2, 0x27, 0x6f, 0x4b, + 0x10, 0x4e, 0x1f, 0x3c, 0x3a, 0x9d, 0xd7, 0xec, 0xa2, 0xb5, 0x3d, 0x2a, 0x9d, 0xfe, 0x0e, 0xf7, + 0x3b, 0x2c, 0xd1, 0x80, 0x1b, 0x68, 0xc9, 0xa7, 0x1e, 0xe8, 0x5a, 0x43, 0x6b, 0xad, 0xd8, 0xb5, + 0xe3, 0xc8, 0x58, 0x88, 0x23, 0x63, 0x69, 0x9f, 0x7a, 0x40, 0x54, 0x04, 0x6f, 0x23, 0x04, 0x2f, + 0x87, 0x01, 0x28, 0xfd, 0xfa, 0xa2, 0xda, 0x87, 0xb3, 0x7d, 0xe8, 0xde, 0x28, 0x42, 0x26, 0x76, + 0x35, 0x7f, 0xab, 0xa0, 0xf5, 0xbd, 0x50, 0x52, 0xc9, 0xfc, 0xde, 0x53, 0x68, 0xf7, 0x39, 0x1f, + 0x14, 0x60, 0x7a, 0x81, 0x6a, 0x8e, 0xcb, 0xc0, 0x97, 0x3b, 0xdc, 0xef, 0xb2, 0x9e, 0xe2, 0xaa, + 0x6e, 0x7f, 0x61, 0x16, 0xfd, 0xc2, 0x66, 0x46, 0xb5, 0x33, 0x51, 0xc4, 0x7e, 0x27, 0x23, 0xaa, + 0x4d, 0xa2, 0x24, 0x47, 0x84, 0x9f, 0xa1, 0x72, 0x10, 0xba, 0x20, 0xf4, 0x52, 0xa3, 0xd4, 0xaa, + 0x6e, 0x7f, 0x5a, 0x84, 0xd1, 0x24, 0xa1, 0x0b, 0x4f, 0x99, 0xec, 0x3f, 0x18, 0x42, 0x0a, 0x0a, + 0x7b, 0x35, 0xe3, 0x2a, 0x27, 0x31, 0x41, 0xd2, 0xa2, 0x78, 0x17, 0xad, 0x76, 0x29, 0x73, 0xc3, + 0x00, 0x1e, 0x72, 0x97, 0x39, 0x47, 0xfa, 0x92, 0xba, 0x81, 0x0f, 0xe3, 0xc8, 0x58, 0xbd, 0x3f, + 0x19, 0x38, 0x8d, 0x8c, 0x8d, 0x1c, 0xf0, 0xe8, 0x68, 0x08, 0x24, 0x9f, 0x8c, 0xbf, 0x44, 0x55, + 0x2f, 0xf9, 0x84, 0x59, 0xad, 0x15, 0x55, 0xab, 0x19, 0x47, 0x46, 0x75, 0x6f, 0x0c, 0x9f, 0x46, + 0xc6, 0xfa, 0xc4, 0x52, 0xd5, 0x99, 0x4c, 0xc3, 0x2f, 0xd1, 0x46, 0x72, 0xe5, 0x62, 0x48, 0x1d, + 0x38, 0x00, 0x17, 0x1c, 0xc9, 0x03, 0xbd, 0xac, 0xee, 0xfb, 0xd6, 0x84, 0xfa, 0x51, 0x73, 0x99, + 0xc3, 0x41, 0x2f, 0x01, 0x84, 0x99, 0xf4, 0x70, 0x22, 0x7f, 0x97, 0xb6, 0xc1, 0x3d, 0x4b, 0xb5, + 0xdf, 0x8d, 0x23, 0x63, 0x63, 0x7f, 0xba, 0x22, 0x99, 0x25, 0xc1, 0x1c, 0xad, 0xf1, 0xf6, 0x0f, + 0xe0, 0xc8, 0x11, 0x6d, 0xf5, 0xe2, 0xb4, 0x38, 0x8e, 0x8c, 0xb5, 0x07, 0xb9, 0x72, 0x64, 0xaa, + 0x7c, 0x72, 0x61, 0x82, 0x75, 0xe0, 0x5e, 0xb7, 0x0b, 0x8e, 0x14, 0xfa, 0xff, 0xc6, 0x17, 0x76, + 0x30, 0x86, 0x93, 0x0b, 0x1b, 0x2f, 0x77, 0x5c, 0x2a, 0x04, 0x99, 0x4c, 0xc3, 0x77, 0xd0, 0x5a, + 0xf2, 0xb0, 0x78, 0x28, 0x0f, 0xc0, 0xe1, 0x7e, 0x47, 0xe8, 0xcb, 0x0d, 0xad, 0x55, 0x4e, 0x4f, + 0xf0, 0x28, 0x17, 0x21, 0x53, 0x3b, 0xf1, 0x63, 0xb4, 0x39, 0xea, 0x22, 0x02, 0x87, 0x0c, 0x5e, + 0x3c, 0x81, 0x20, 0x59, 0x08, 0xbd, 0xd2, 0x28, 0xb5, 0x56, 0xec, 0x0f, 0xe2, 0xc8, 0xd8, 0xbc, + 0x3b, 0x7f, 0x0b, 0x39, 0x2f, 0x17, 0x3f, 0x47, 0x38, 0x00, 0xe6, 0x1f, 0x72, 0x47, 0xb5, 0x5f, + 0xd6, 0x10, 0x48, 0xe9, 0xbb, 0x11, 0x47, 0x06, 0x26, 0x33, 0xd1, 0xd3, 0xc8, 0x78, 0x6f, 0x16, + 0x55, 0xed, 0x31, 0xa7, 0x16, 0xfe, 0x11, 0xad, 0x7b, 0xb9, 0x71, 0x21, 0xf4, 0x9a, 0x7a, 0x21, + 0xb7, 0x8b, 0xbf, 0xc9, 0xfc, 0xbc, 0xb1, 0x37, 0xb3, 0x27, 0xb2, 0x9e, 0xc7, 0x05, 0x99, 0x66, + 0x6a, 0xfe, 0xae, 0xa1, 0xeb, 0x53, 0x33, 0x24, 0x7d, 0xae, 0x61, 0xca, 0x80, 0x9f, 0xa3, 0x4a, + 0xd2, 0x15, 0x1d, 0x2a, 0xa9, 0x1a, 0x2a, 0xd5, 0xed, 0x1b, 0xc5, 0x7a, 0x28, 0x6d, 0x98, 0x3d, + 0x90, 0x74, 0x3c, 0xc8, 0xc6, 0x18, 0x19, 0x55, 0xc5, 0xdf, 0xa1, 0x4a, 0xc6, 0x2c, 0xf4, 0x45, + 0x25, 0xfc, 0xb3, 0x7f, 0x21, 0x3c, 0x7f, 0x76, 0x7b, 0x29, 0xa1, 0x22, 0xa3, 0x82, 0xcd, 0xbf, + 0x34, 0xd4, 0x78, 0x93, 0xbe, 0x5d, 0x26, 0x24, 0x7e, 0x36, 0xa3, 0xd1, 0x2c, 0xf8, 0x4e, 0x98, + 0x48, 0x15, 0x5e, 0xcb, 0x14, 0x56, 0xce, 0x90, 0x09, 0x7d, 0x03, 0x54, 0x66, 0x12, 0xbc, 0x33, + 0x71, 0xf7, 0x2f, 0x2c, 0x2e, 0x77, 0xf0, 0xf1, 0x18, 0xfc, 0x3a, 0x29, 0x4e, 0x52, 0x8e, 0xe6, + 0x2f, 0x1a, 0xba, 0x76, 0x00, 0xc1, 0x21, 0x73, 0x80, 0x40, 0x17, 0x02, 0xf0, 0x1d, 0xc0, 0x16, + 0x5a, 0x19, 0x8d, 0x88, 0xcc, 0x19, 0x36, 0xb2, 0xec, 0x95, 0xd1, 0x38, 0x21, 0xe3, 0x3d, 0x23, + 0x17, 0x59, 0x3c, 0xd7, 0x45, 0xae, 0xa3, 0xa5, 0x21, 0x95, 0x7d, 0xbd, 0xa4, 0x76, 0x54, 0x92, + 0xe8, 0x43, 0x2a, 0xfb, 0x44, 0xa1, 0x2a, 0xca, 0x03, 0xa9, 0x66, 0x70, 0x39, 0x8b, 0xf2, 0x40, + 0x12, 0x85, 0x36, 0x4f, 0x96, 0xd1, 0xc6, 0x13, 0xea, 0xb2, 0xce, 0x95, 0x73, 0x5d, 0x39, 0xd7, + 0xdb, 0x9d, 0x0b, 0x5d, 0x39, 0xd7, 0x85, 0x9c, 0x6b, 0x8e, 0xaf, 0x54, 0x2f, 0xcd, 0x57, 0x4e, + 0x34, 0x54, 0x9f, 0x79, 0xe3, 0x97, 0xed, 0x2c, 0xdf, 0xcf, 0x38, 0xcb, 0xe7, 0xc5, 0xa5, 0xcf, + 0x9c, 0x7e, 0xc6, 0x5b, 0xfe, 0xd6, 0x50, 0xf3, 0xcd, 0x1a, 0x2f, 0xc1, 0x5d, 0xbc, 0xbc, 0xbb, + 0x7c, 0xf5, 0x1f, 0x04, 0x16, 0xf1, 0x97, 0x5f, 0x35, 0xf4, 0xff, 0x39, 0x63, 0x14, 0xbf, 0x8f, + 0x4a, 0x61, 0xe0, 0x66, 0x76, 0xb0, 0x1c, 0x47, 0x46, 0xe9, 0x31, 0xd9, 0x25, 0x09, 0x86, 0x29, + 0x5a, 0x16, 0xa9, 0x23, 0x65, 0xf2, 0xef, 0x14, 0x3f, 0xe3, 0xb4, 0x95, 0xd9, 0xd5, 0x38, 0x32, + 0x96, 0xcf, 0xd0, 0xb3, 0xba, 0xb8, 0x85, 0x2a, 0x0e, 0xb5, 0x43, 0xbf, 0xe3, 0xa6, 0x9e, 0x55, + 0xb3, 0x6b, 0xc9, 0x75, 0xed, 0xdc, 0x4d, 0x31, 0x32, 0x8a, 0xda, 0xfb, 0xc7, 0x27, 0xf5, 0x85, + 0x57, 0x27, 0xf5, 0x85, 0xd7, 0x27, 0xf5, 0x85, 0x9f, 0xe2, 0xba, 0x76, 0x1c, 0xd7, 0xb5, 0x57, + 0x71, 0x5d, 0x7b, 0x1d, 0xd7, 0xb5, 0x3f, 0xe2, 0xba, 0xf6, 0xf3, 0x9f, 0xf5, 0x85, 0x6f, 0x5b, + 0x45, 0xff, 0x28, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0x1f, 0xf5, 0x97, 0x1c, 0x6c, 0x0f, 0x00, + 0x00, +} + +func (m *MatchCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) { @@ -435,6 +436,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -627,105 +642,6 @@ func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } -func (m *Rule) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Rule) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Rule) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Scope != nil { - i -= len(*m.Scope) - copy(dAtA[i:], *m.Scope) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Scope))) - i-- - dAtA[i] = 0x22 - } - if len(m.Resources) > 0 { - for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Resources[iNdEx]) - copy(dAtA[i:], m.Resources[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.APIVersions) > 0 { - for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.APIVersions[iNdEx]) - copy(dAtA[i:], m.APIVersions[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx]))) - i-- - dAtA[i] = 0x12 - } - } - if len(m.APIGroups) > 0 { - for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.APIGroups[iNdEx]) - copy(dAtA[i:], m.APIGroups[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RuleWithOperations) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Rule.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.Operations) > 0 { - for iNdEx := len(m.Operations) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Operations[iNdEx]) - copy(dAtA[i:], m.Operations[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operations[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *ServiceReference) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -791,6 +707,20 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -1036,6 +966,19 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *MutatingWebhook) Size() (n int) { if m == nil { return 0 @@ -1085,6 +1028,12 @@ func (m *MutatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1122,54 +1071,6 @@ func (m *MutatingWebhookConfigurationList) Size() (n int) { return n } -func (m *Rule) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.APIGroups) > 0 { - for _, s := range m.APIGroups { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.APIVersions) > 0 { - for _, s := range m.APIVersions { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Resources) > 0 { - for _, s := range m.Resources { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.Scope != nil { - l = len(*m.Scope) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *RuleWithOperations) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Operations) > 0 { - for _, s := range m.Operations { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = m.Rule.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - func (m *ServiceReference) Size() (n int) { if m == nil { return 0 @@ -1235,6 +1136,12 @@ func (m *ValidatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1299,27 +1206,44 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *MutatingWebhook) String() string { if this == nil { return "nil" } repeatedStringForRules := "[]RuleWithOperations{" for _, f := range this.Rules { - repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," + repeatedStringForRules += fmt.Sprintf("%v", f) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&MutatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, `Rules:` + repeatedStringForRules + `,`, `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, - `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, - `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1334,7 +1258,7 @@ func (this *MutatingWebhookConfiguration) String() string { } repeatedStringForWebhooks += "}" s := strings.Join([]string{`&MutatingWebhookConfiguration{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, `Webhooks:` + repeatedStringForWebhooks + `,`, `}`, }, "") @@ -1350,36 +1274,12 @@ func (this *MutatingWebhookConfigurationList) String() string { } repeatedStringForItems += "}" s := strings.Join([]string{`&MutatingWebhookConfigurationList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, `Items:` + repeatedStringForItems + `,`, `}`, }, "") return s } -func (this *Rule) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Rule{`, - `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`, - `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, - `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`, - `Scope:` + valueToStringGenerated(this.Scope) + `,`, - `}`, - }, "") - return s -} -func (this *RuleWithOperations) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RuleWithOperations{`, - `Operations:` + fmt.Sprintf("%v", this.Operations) + `,`, - `Rule:` + strings.Replace(strings.Replace(this.Rule.String(), "Rule", "Rule", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} func (this *ServiceReference) String() string { if this == nil { return "nil" @@ -1399,20 +1299,26 @@ func (this *ValidatingWebhook) String() string { } repeatedStringForRules := "[]RuleWithOperations{" for _, f := range this.Rules { - repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," + repeatedStringForRules += fmt.Sprintf("%v", f) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&ValidatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, `Rules:` + repeatedStringForRules + `,`, `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, - `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, - `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1427,7 +1333,7 @@ func (this *ValidatingWebhookConfiguration) String() string { } repeatedStringForWebhooks += "}" s := strings.Join([]string{`&ValidatingWebhookConfiguration{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, `Webhooks:` + repeatedStringForWebhooks + `,`, `}`, }, "") @@ -1443,7 +1349,7 @@ func (this *ValidatingWebhookConfigurationList) String() string { } repeatedStringForItems += "}" s := strings.Join([]string{`&ValidatingWebhookConfigurationList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, `Items:` + repeatedStringForItems + `,`, `}`, }, "") @@ -1469,7 +1375,121 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } -func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { +func (m *MatchCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1592,7 +1612,7 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Rules = append(m.Rules, RuleWithOperations{}) + m.Rules = append(m.Rules, v1.RuleWithOperations{}) if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1660,7 +1680,7 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.NamespaceSelector == nil { - m.NamespaceSelector = &v1.LabelSelector{} + m.NamespaceSelector = &v11.LabelSelector{} } if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1847,98 +1867,15 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.ObjectSelector == nil { - m.ObjectSelector = &v1.LabelSelector{} + m.ObjectSelector = &v11.LabelSelector{} } if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MutatingWebhookConfiguration) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MutatingWebhookConfiguration: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MutatingWebhookConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: + case 12: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Webhooks", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1965,8 +1902,8 @@ func (m *MutatingWebhookConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Webhooks = append(m.Webhooks, MutatingWebhook{}) - if err := m.Webhooks[len(m.Webhooks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1991,7 +1928,7 @@ func (m *MutatingWebhookConfiguration) Unmarshal(dAtA []byte) error { } return nil } -func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { +func (m *MutatingWebhookConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2014,15 +1951,15 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MutatingWebhookConfigurationList: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingWebhookConfiguration: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MutatingWebhookConfigurationList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingWebhookConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2049,13 +1986,13 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Webhooks", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2082,8 +2019,8 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, MutatingWebhookConfiguration{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Webhooks = append(m.Webhooks, MutatingWebhook{}) + if err := m.Webhooks[len(m.Webhooks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -2108,7 +2045,7 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { } return nil } -func (m *Rule) Unmarshal(dAtA []byte) error { +func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2131,113 +2068,17 @@ func (m *Rule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Rule: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingWebhookConfigurationList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Rule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingWebhookConfigurationList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIGroups", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.APIGroups = append(m.APIGroups, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIVersions", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.APIVersions = append(m.APIVersions, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resources = append(m.Resources, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2247,110 +2088,28 @@ func (m *Rule) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := ScopeType(dAtA[iNdEx:postIndex]) - m.Scope = &s - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RuleWithOperations) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RuleWithOperations: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RuleWithOperations: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Operations", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Operations = append(m.Operations, OperationType(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2377,7 +2136,8 @@ func (m *RuleWithOperations) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Rule.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, MutatingWebhookConfiguration{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -2692,7 +2452,7 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Rules = append(m.Rules, RuleWithOperations{}) + m.Rules = append(m.Rules, v1.RuleWithOperations{}) if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -2760,7 +2520,7 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.NamespaceSelector == nil { - m.NamespaceSelector = &v1.LabelSelector{} + m.NamespaceSelector = &v11.LabelSelector{} } if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2914,12 +2674,46 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.ObjectSelector == nil { - m.ObjectSelector = &v1.LabelSelector{} + m.ObjectSelector = &v11.LabelSelector{} } if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto index 78440764f3b..cfd75928541 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto @@ -21,6 +21,7 @@ syntax = "proto2"; package k8s.io.api.admissionregistration.v1beta1; +import "k8s.io/api/admissionregistration/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -28,6 +29,35 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1beta1"; +// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { // The name of the admission webhook. @@ -47,7 +77,7 @@ message MutatingWebhook { // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. - repeated RuleWithOperations rules = 3; + repeated k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3; // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. @@ -176,6 +206,28 @@ message MutatingWebhook { // Defaults to "Never". // +optional optional string reinvocationPolicy = 10; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 12; } // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. @@ -203,63 +255,6 @@ message MutatingWebhookConfigurationList { repeated MutatingWebhookConfiguration items = 2; } -// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended -// to make sure that all the tuple expansions are valid. -message Rule { - // APIGroups is the API groups the resources belong to. '*' is all groups. - // If '*' is present, the length of the slice must be one. - // Required. - repeated string apiGroups = 1; - - // APIVersions is the API versions the resources belong to. '*' is all versions. - // If '*' is present, the length of the slice must be one. - // Required. - repeated string apiVersions = 2; - - // Resources is a list of resources this rule applies to. - // - // For example: - // 'pods' means pods. - // 'pods/log' means the log subresource of pods. - // '*' means all resources, but not subresources. - // 'pods/*' means all subresources of pods. - // '*/scale' means all scale subresources. - // '*/*' means all resources and their subresources. - // - // If wildcard is present, the validation rule will ensure resources do not - // overlap with each other. - // - // Depending on the enclosing object, subresources might not be allowed. - // Required. - repeated string resources = 3; - - // scope specifies the scope of this rule. - // Valid values are "Cluster", "Namespaced", and "*" - // "Cluster" means that only cluster-scoped resources will match this rule. - // Namespace API objects are cluster-scoped. - // "Namespaced" means that only namespaced resources will match this rule. - // "*" means that there are no scope restrictions. - // Subresources match the scope of their parent resource. - // Default is "*". - // - // +optional - optional string scope = 4; -} - -// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make -// sure that all the tuple expansions are valid. -message RuleWithOperations { - // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * - // for all of those operations and any future admission operations that are added. - // If '*' is present, the length of the slice must be one. - // Required. - repeated string operations = 1; - - // Rule is embedded, it describes other criteria of the rule, like - // APIGroups, APIVersions, Resources, etc. - optional Rule rule = 2; -} - // ServiceReference holds a reference to Service.legacy.k8s.io message ServiceReference { // `namespace` is the namespace of the service. @@ -301,7 +296,7 @@ message ValidatingWebhook { // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. - repeated RuleWithOperations rules = 3; + repeated k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3; // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. @@ -412,6 +407,28 @@ message ValidatingWebhook { // Default to `['v1beta1']`. // +optional repeated string admissionReviewVersions = 8; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 11; } // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go index 630ea1f57b4..82ee7df9bad 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go @@ -17,63 +17,25 @@ limitations under the License. package v1beta1 import ( + v1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended // to make sure that all the tuple expansions are valid. -type Rule struct { - // APIGroups is the API groups the resources belong to. '*' is all groups. - // If '*' is present, the length of the slice must be one. - // Required. - APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"` - - // APIVersions is the API versions the resources belong to. '*' is all versions. - // If '*' is present, the length of the slice must be one. - // Required. - APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,2,rep,name=apiVersions"` - - // Resources is a list of resources this rule applies to. - // - // For example: - // 'pods' means pods. - // 'pods/log' means the log subresource of pods. - // '*' means all resources, but not subresources. - // 'pods/*' means all subresources of pods. - // '*/scale' means all scale subresources. - // '*/*' means all resources and their subresources. - // - // If wildcard is present, the validation rule will ensure resources do not - // overlap with each other. - // - // Depending on the enclosing object, subresources might not be allowed. - // Required. - Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` - - // scope specifies the scope of this rule. - // Valid values are "Cluster", "Namespaced", and "*" - // "Cluster" means that only cluster-scoped resources will match this rule. - // Namespace API objects are cluster-scoped. - // "Namespaced" means that only namespaced resources will match this rule. - // "*" means that there are no scope restrictions. - // Subresources match the scope of their parent resource. - // Default is "*". - // - // +optional - Scope *ScopeType `json:"scope,omitempty" protobuf:"bytes,4,rep,name=scope"` -} +type Rule = v1.Rule // ScopeType specifies a scope for a Rule. -type ScopeType string +type ScopeType = v1.ScopeType const ( // ClusterScope means that scope is limited to cluster-scoped objects. // Namespace objects are cluster-scoped. - ClusterScope ScopeType = "Cluster" + ClusterScope ScopeType = v1.ClusterScope // NamespacedScope means that scope is limited to namespaced objects. - NamespacedScope ScopeType = "Namespaced" + NamespacedScope ScopeType = v1.NamespacedScope // AllScopes means that all scopes are included. - AllScopes ScopeType = "*" + AllScopes ScopeType = v1.AllScopes ) // FailurePolicyType specifies a failure policy that defines how unrecognized errors from the admission endpoint are handled. @@ -321,6 +283,28 @@ type ValidatingWebhook struct { // Default to `['v1beta1']`. // +optional AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,rep,name=matchConditions"` } // MutatingWebhook describes an admission webhook and the resources and operations it applies to. @@ -471,6 +455,28 @@ type MutatingWebhook struct { // Defaults to "Never". // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,rep,name=matchConditions"` } // ReinvocationPolicyType specifies what type of policy the admission hook uses. @@ -488,27 +494,19 @@ const ( // RuleWithOperations is a tuple of Operations and Resources. It is recommended to make // sure that all the tuple expansions are valid. -type RuleWithOperations struct { - // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * - // for all of those operations and any future admission operations that are added. - // If '*' is present, the length of the slice must be one. - // Required. - Operations []OperationType `json:"operations,omitempty" protobuf:"bytes,1,rep,name=operations,casttype=OperationType"` - // Rule is embedded, it describes other criteria of the rule, like - // APIGroups, APIVersions, Resources, etc. - Rule `json:",inline" protobuf:"bytes,2,opt,name=rule"` -} +type RuleWithOperations = v1.RuleWithOperations // OperationType specifies an operation for a request. -type OperationType string +// +enum +type OperationType = v1.OperationType // The constants should be kept in sync with those defined in k8s.io/kubernetes/pkg/admission/interface.go. const ( - OperationAll OperationType = "*" - Create OperationType = "CREATE" - Update OperationType = "UPDATE" - Delete OperationType = "DELETE" - Connect OperationType = "CONNECT" + OperationAll OperationType = v1.OperationAll + Create OperationType = v1.Create + Update OperationType = v1.Update + Delete OperationType = v1.Delete + Connect OperationType = v1.Connect ) // WebhookClientConfig contains the information to make a TLS @@ -577,3 +575,32 @@ type ServiceReference struct { // +optional Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"` } + +// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. +type MatchCondition struct { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + Expression string `json:"expression" protobuf:"bytes,2,opt,name=expression"` +} diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go index 314c3afae06..2c0a9f01179 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go @@ -24,9 +24,19 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_MatchCondition = map[string]string{ + "": "MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.", + "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", +} + +func (MatchCondition) SwaggerDoc() map[string]string { + return map_MatchCondition +} + var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", @@ -40,6 +50,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -66,27 +77,6 @@ func (MutatingWebhookConfigurationList) SwaggerDoc() map[string]string { return map_MutatingWebhookConfigurationList } -var map_Rule = map[string]string{ - "": "Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended to make sure that all the tuple expansions are valid.", - "apiGroups": "APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.", - "apiVersions": "APIVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.", - "resources": "Resources is a list of resources this rule applies to.\n\nFor example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.\n\nIf wildcard is present, the validation rule will ensure resources do not overlap with each other.\n\nDepending on the enclosing object, subresources might not be allowed. Required.", - "scope": "scope specifies the scope of this rule. Valid values are \"Cluster\", \"Namespaced\", and \"*\" \"Cluster\" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. \"Namespaced\" means that only namespaced resources will match this rule. \"*\" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is \"*\".", -} - -func (Rule) SwaggerDoc() map[string]string { - return map_Rule -} - -var map_RuleWithOperations = map[string]string{ - "": "RuleWithOperations is a tuple of Operations and Resources. It is recommended to make sure that all the tuple expansions are valid.", - "operations": "Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.", -} - -func (RuleWithOperations) SwaggerDoc() map[string]string { - return map_RuleWithOperations -} - var map_ServiceReference = map[string]string{ "": "ServiceReference holds a reference to Service.legacy.k8s.io", "namespace": "`namespace` is the namespace of the service. Required", @@ -111,6 +101,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go index 23ddb1fa2c1..9c5299bdfa2 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go @@ -22,17 +22,34 @@ limitations under the License. package v1beta1 import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = *in in.ClientConfig.DeepCopyInto(&out.ClientConfig) if in.Rules != nil { in, out := &in.Rules, &out.Rules - *out = make([]RuleWithOperations, len(*in)) + *out = make([]v1.RuleWithOperations, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -49,12 +66,12 @@ func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { } if in.NamespaceSelector != nil { in, out := &in.NamespaceSelector, &out.NamespaceSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.ObjectSelector != nil { in, out := &in.ObjectSelector, &out.ObjectSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.SideEffects != nil { @@ -77,6 +94,11 @@ func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = new(ReinvocationPolicyType) **out = **in } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } @@ -156,64 +178,6 @@ func (in *MutatingWebhookConfigurationList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Rule) DeepCopyInto(out *Rule) { - *out = *in - if in.APIGroups != nil { - in, out := &in.APIGroups, &out.APIGroups - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.APIVersions != nil { - in, out := &in.APIVersions, &out.APIVersions - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Scope != nil { - in, out := &in.Scope, &out.Scope - *out = new(ScopeType) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. -func (in *Rule) DeepCopy() *Rule { - if in == nil { - return nil - } - out := new(Rule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RuleWithOperations) DeepCopyInto(out *RuleWithOperations) { - *out = *in - if in.Operations != nil { - in, out := &in.Operations, &out.Operations - *out = make([]OperationType, len(*in)) - copy(*out, *in) - } - in.Rule.DeepCopyInto(&out.Rule) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleWithOperations. -func (in *RuleWithOperations) DeepCopy() *RuleWithOperations { - if in == nil { - return nil - } - out := new(RuleWithOperations) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceReference) DeepCopyInto(out *ServiceReference) { *out = *in @@ -246,7 +210,7 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { in.ClientConfig.DeepCopyInto(&out.ClientConfig) if in.Rules != nil { in, out := &in.Rules, &out.Rules - *out = make([]RuleWithOperations, len(*in)) + *out = make([]v1.RuleWithOperations, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -263,12 +227,12 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { } if in.NamespaceSelector != nil { in, out := &in.NamespaceSelector, &out.NamespaceSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.ObjectSelector != nil { in, out := &in.ObjectSelector, &out.ObjectSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.SideEffects != nil { @@ -286,6 +250,11 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go b/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go new file mode 100644 index 00000000000..e85da226e02 --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true + +// +groupName=apidiscovery.k8s.io + +package v2beta1 // import "k8s.io/api/apidiscovery/v2beta1" diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.pb.go b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.pb.go new file mode 100644 index 00000000000..ba6eee1b327 --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.pb.go @@ -0,0 +1,1744 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto + +package v2beta1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *APIGroupDiscovery) Reset() { *m = APIGroupDiscovery{} } +func (*APIGroupDiscovery) ProtoMessage() {} +func (*APIGroupDiscovery) Descriptor() ([]byte, []int) { + return fileDescriptor_0442b7af4d680cb7, []int{0} +} +func (m *APIGroupDiscovery) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *APIGroupDiscovery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *APIGroupDiscovery) XXX_Merge(src proto.Message) { + xxx_messageInfo_APIGroupDiscovery.Merge(m, src) +} +func (m *APIGroupDiscovery) XXX_Size() int { + return m.Size() +} +func (m *APIGroupDiscovery) XXX_DiscardUnknown() { + xxx_messageInfo_APIGroupDiscovery.DiscardUnknown(m) +} + +var xxx_messageInfo_APIGroupDiscovery proto.InternalMessageInfo + +func (m *APIGroupDiscoveryList) Reset() { *m = APIGroupDiscoveryList{} } +func (*APIGroupDiscoveryList) ProtoMessage() {} +func (*APIGroupDiscoveryList) Descriptor() ([]byte, []int) { + return fileDescriptor_0442b7af4d680cb7, []int{1} +} +func (m *APIGroupDiscoveryList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *APIGroupDiscoveryList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *APIGroupDiscoveryList) XXX_Merge(src proto.Message) { + xxx_messageInfo_APIGroupDiscoveryList.Merge(m, src) +} +func (m *APIGroupDiscoveryList) XXX_Size() int { + return m.Size() +} +func (m *APIGroupDiscoveryList) XXX_DiscardUnknown() { + xxx_messageInfo_APIGroupDiscoveryList.DiscardUnknown(m) +} + +var xxx_messageInfo_APIGroupDiscoveryList proto.InternalMessageInfo + +func (m *APIResourceDiscovery) Reset() { *m = APIResourceDiscovery{} } +func (*APIResourceDiscovery) ProtoMessage() {} +func (*APIResourceDiscovery) Descriptor() ([]byte, []int) { + return fileDescriptor_0442b7af4d680cb7, []int{2} +} +func (m *APIResourceDiscovery) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *APIResourceDiscovery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *APIResourceDiscovery) XXX_Merge(src proto.Message) { + xxx_messageInfo_APIResourceDiscovery.Merge(m, src) +} +func (m *APIResourceDiscovery) XXX_Size() int { + return m.Size() +} +func (m *APIResourceDiscovery) XXX_DiscardUnknown() { + xxx_messageInfo_APIResourceDiscovery.DiscardUnknown(m) +} + +var xxx_messageInfo_APIResourceDiscovery proto.InternalMessageInfo + +func (m *APISubresourceDiscovery) Reset() { *m = APISubresourceDiscovery{} } +func (*APISubresourceDiscovery) ProtoMessage() {} +func (*APISubresourceDiscovery) Descriptor() ([]byte, []int) { + return fileDescriptor_0442b7af4d680cb7, []int{3} +} +func (m *APISubresourceDiscovery) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *APISubresourceDiscovery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *APISubresourceDiscovery) XXX_Merge(src proto.Message) { + xxx_messageInfo_APISubresourceDiscovery.Merge(m, src) +} +func (m *APISubresourceDiscovery) XXX_Size() int { + return m.Size() +} +func (m *APISubresourceDiscovery) XXX_DiscardUnknown() { + xxx_messageInfo_APISubresourceDiscovery.DiscardUnknown(m) +} + +var xxx_messageInfo_APISubresourceDiscovery proto.InternalMessageInfo + +func (m *APIVersionDiscovery) Reset() { *m = APIVersionDiscovery{} } +func (*APIVersionDiscovery) ProtoMessage() {} +func (*APIVersionDiscovery) Descriptor() ([]byte, []int) { + return fileDescriptor_0442b7af4d680cb7, []int{4} +} +func (m *APIVersionDiscovery) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *APIVersionDiscovery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *APIVersionDiscovery) XXX_Merge(src proto.Message) { + xxx_messageInfo_APIVersionDiscovery.Merge(m, src) +} +func (m *APIVersionDiscovery) XXX_Size() int { + return m.Size() +} +func (m *APIVersionDiscovery) XXX_DiscardUnknown() { + xxx_messageInfo_APIVersionDiscovery.DiscardUnknown(m) +} + +var xxx_messageInfo_APIVersionDiscovery proto.InternalMessageInfo + +func init() { + proto.RegisterType((*APIGroupDiscovery)(nil), "k8s.io.api.apidiscovery.v2beta1.APIGroupDiscovery") + proto.RegisterType((*APIGroupDiscoveryList)(nil), "k8s.io.api.apidiscovery.v2beta1.APIGroupDiscoveryList") + proto.RegisterType((*APIResourceDiscovery)(nil), "k8s.io.api.apidiscovery.v2beta1.APIResourceDiscovery") + proto.RegisterType((*APISubresourceDiscovery)(nil), "k8s.io.api.apidiscovery.v2beta1.APISubresourceDiscovery") + proto.RegisterType((*APIVersionDiscovery)(nil), "k8s.io.api.apidiscovery.v2beta1.APIVersionDiscovery") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto", fileDescriptor_0442b7af4d680cb7) +} + +var fileDescriptor_0442b7af4d680cb7 = []byte{ + // 754 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcd, 0x4e, 0xdb, 0x4c, + 0x14, 0x8d, 0x09, 0xf9, 0x48, 0x26, 0xc9, 0xf7, 0x85, 0x01, 0xf4, 0x59, 0x2c, 0x6c, 0x94, 0x4d, + 0xa9, 0xd4, 0xda, 0x25, 0x02, 0xc4, 0x36, 0x29, 0xb4, 0x8d, 0xfa, 0x87, 0x26, 0x15, 0x95, 0xaa, + 0x2e, 0x6a, 0x3b, 0x17, 0xc7, 0x0d, 0xb1, 0xad, 0x99, 0x71, 0x24, 0x76, 0x7d, 0x84, 0xbe, 0x43, + 0x5f, 0x86, 0x55, 0xc5, 0xa2, 0x0b, 0xba, 0x89, 0x4a, 0xfa, 0x00, 0xdd, 0xb3, 0xaa, 0xec, 0x8c, + 0x7f, 0x42, 0x40, 0x44, 0x5d, 0x74, 0x81, 0x84, 0xcf, 0x3d, 0xe7, 0xdc, 0x7b, 0x2e, 0xd7, 0x06, + 0x3d, 0xeb, 0xef, 0x31, 0xcd, 0xf1, 0xf4, 0x7e, 0x60, 0x02, 0x75, 0x81, 0x03, 0xd3, 0x87, 0xe0, + 0x76, 0x3d, 0xaa, 0x8b, 0x82, 0xe1, 0x3b, 0xe1, 0x4f, 0xd7, 0x61, 0x96, 0x37, 0x04, 0x7a, 0xaa, + 0x0f, 0x1b, 0x26, 0x70, 0x63, 0x4b, 0xb7, 0xc1, 0x05, 0x6a, 0x70, 0xe8, 0x6a, 0x3e, 0xf5, 0xb8, + 0x87, 0xd5, 0x89, 0x40, 0x33, 0x7c, 0x47, 0xcb, 0x0a, 0x34, 0x21, 0x58, 0x7f, 0x68, 0x3b, 0xbc, + 0x17, 0x98, 0x9a, 0xe5, 0x0d, 0x74, 0xdb, 0xb3, 0x3d, 0x3d, 0xd2, 0x99, 0xc1, 0x71, 0xf4, 0x14, + 0x3d, 0x44, 0xbf, 0x4d, 0xfc, 0xd6, 0xb7, 0xd3, 0x01, 0x06, 0x86, 0xd5, 0x73, 0xdc, 0xb0, 0xb9, + 0xdf, 0xb7, 0x43, 0x80, 0xe9, 0x03, 0xe0, 0x86, 0x3e, 0x9c, 0x99, 0x62, 0x5d, 0xbf, 0x4d, 0x45, + 0x03, 0x97, 0x3b, 0x03, 0x98, 0x11, 0xec, 0xde, 0x25, 0x60, 0x56, 0x0f, 0x06, 0xc6, 0x75, 0x5d, + 0xfd, 0xbb, 0x84, 0x96, 0x9b, 0x87, 0xed, 0xa7, 0xd4, 0x0b, 0xfc, 0xfd, 0x38, 0x2b, 0xfe, 0x80, + 0x8a, 0xe1, 0x64, 0x5d, 0x83, 0x1b, 0xb2, 0xb4, 0x21, 0x6d, 0x96, 0x1b, 0x8f, 0xb4, 0x74, 0x2f, + 0x49, 0x03, 0xcd, 0xef, 0xdb, 0x21, 0xc0, 0xb4, 0x90, 0xad, 0x0d, 0xb7, 0xb4, 0xd7, 0xe6, 0x47, + 0xb0, 0xf8, 0x4b, 0xe0, 0x46, 0x0b, 0x9f, 0x8d, 0xd4, 0xdc, 0x78, 0xa4, 0xa2, 0x14, 0x23, 0x89, + 0x2b, 0x36, 0x51, 0x71, 0x08, 0x94, 0x39, 0x9e, 0xcb, 0xe4, 0x85, 0x8d, 0xfc, 0x66, 0xb9, 0xb1, + 0xad, 0xdd, 0xb1, 0x79, 0xad, 0x79, 0xd8, 0x3e, 0x9a, 0x68, 0x92, 0x49, 0x5b, 0x35, 0xd1, 0xa5, + 0x28, 0x2a, 0x8c, 0x24, 0xbe, 0xf5, 0xaf, 0x12, 0x5a, 0x9b, 0xc9, 0xf6, 0xc2, 0x61, 0x1c, 0xbf, + 0x9f, 0xc9, 0xa7, 0xcd, 0x97, 0x2f, 0x54, 0x47, 0xe9, 0x92, 0xbe, 0x31, 0x92, 0xc9, 0xf6, 0x16, + 0x15, 0x1c, 0x0e, 0x83, 0x38, 0x58, 0x63, 0x9e, 0x60, 0xd3, 0x43, 0xb6, 0xaa, 0xc2, 0xbe, 0xd0, + 0x0e, 0x8d, 0xc8, 0xc4, 0xaf, 0xfe, 0x65, 0x11, 0xad, 0x36, 0x0f, 0xdb, 0x04, 0x98, 0x17, 0x50, + 0x0b, 0xd2, 0xbf, 0xd7, 0x03, 0x54, 0xa4, 0x02, 0x8c, 0xf2, 0x94, 0xd2, 0xf9, 0x62, 0x32, 0x49, + 0x18, 0xf8, 0x04, 0x55, 0x28, 0x30, 0xdf, 0x73, 0x19, 0x3c, 0x77, 0xdc, 0xae, 0xbc, 0x10, 0x6d, + 0x60, 0x77, 0xbe, 0x0d, 0x44, 0x83, 0x8a, 0x65, 0x87, 0xea, 0x56, 0x6d, 0x3c, 0x52, 0x2b, 0x24, + 0xe3, 0x47, 0xa6, 0xdc, 0xf1, 0x36, 0x2a, 0x30, 0xcb, 0xf3, 0x41, 0xce, 0x47, 0x83, 0x29, 0x71, + 0xb2, 0x4e, 0x08, 0x5e, 0x8d, 0xd4, 0x6a, 0x3c, 0x61, 0x04, 0x90, 0x09, 0x19, 0xef, 0xa3, 0x1a, + 0x73, 0x5c, 0x3b, 0x38, 0x31, 0x68, 0x5c, 0x97, 0x17, 0x23, 0x03, 0x59, 0x18, 0xd4, 0x3a, 0xd7, + 0xea, 0x64, 0x46, 0x81, 0x55, 0x54, 0x18, 0x02, 0x35, 0x99, 0x5c, 0xd8, 0xc8, 0x6f, 0x96, 0x5a, + 0xa5, 0xb0, 0xef, 0x51, 0x08, 0x90, 0x09, 0x8e, 0x35, 0x84, 0x58, 0xcf, 0xa3, 0xfc, 0x95, 0x31, + 0x00, 0x26, 0xff, 0x13, 0xb1, 0xfe, 0x0d, 0x8f, 0xb6, 0x93, 0xa0, 0x24, 0xc3, 0x08, 0xf9, 0x96, + 0xc1, 0xc1, 0xf6, 0xa8, 0x03, 0x4c, 0x5e, 0x4a, 0xf9, 0x8f, 0x13, 0x94, 0x64, 0x18, 0x98, 0xa2, + 0x0a, 0x0b, 0xcc, 0x78, 0xf3, 0x4c, 0x2e, 0x46, 0x17, 0xb1, 0x37, 0xcf, 0x45, 0x74, 0x52, 0x5d, + 0x7a, 0x17, 0xab, 0x22, 0x7c, 0x25, 0x53, 0x65, 0x64, 0xaa, 0x47, 0xfd, 0xdb, 0x02, 0xfa, 0xff, + 0x16, 0x3d, 0xde, 0x41, 0xe5, 0x0c, 0x57, 0xdc, 0xca, 0x8a, 0x30, 0x2d, 0x67, 0x24, 0x24, 0xcb, + 0xfb, 0xcb, 0x17, 0xc3, 0x50, 0xd5, 0xb0, 0x2c, 0xf0, 0x39, 0x74, 0xdf, 0x9c, 0xfa, 0xc0, 0xe4, + 0x7c, 0xb4, 0xb5, 0x3f, 0x6d, 0xb7, 0x26, 0xe2, 0x55, 0x9b, 0x59, 0x53, 0x32, 0xdd, 0x23, 0x3d, + 0x95, 0xc5, 0x9b, 0x4f, 0xa5, 0xfe, 0x4b, 0x42, 0x2b, 0x37, 0x7c, 0x81, 0xf0, 0x7d, 0xb4, 0x24, + 0xbe, 0x38, 0x62, 0x9d, 0xff, 0x89, 0x7e, 0x4b, 0x82, 0x4a, 0xe2, 0x3a, 0x3e, 0x46, 0xa5, 0xf4, + 0x14, 0x26, 0x1f, 0x87, 0x9d, 0x79, 0x4e, 0x61, 0xe6, 0x85, 0x6f, 0x2d, 0x8b, 0x1e, 0x25, 0x92, + 0x1c, 0x41, 0x6a, 0x8d, 0x0f, 0x50, 0xe9, 0x98, 0x02, 0xeb, 0xb9, 0xc0, 0x98, 0x78, 0xed, 0xee, + 0xc5, 0x82, 0x27, 0x71, 0xe1, 0x6a, 0xa4, 0xe2, 0xc4, 0x30, 0x41, 0x49, 0xaa, 0x6c, 0x1d, 0x9c, + 0x5d, 0x2a, 0xb9, 0xf3, 0x4b, 0x25, 0x77, 0x71, 0xa9, 0xe4, 0x3e, 0x8d, 0x15, 0xe9, 0x6c, 0xac, + 0x48, 0xe7, 0x63, 0x45, 0xba, 0x18, 0x2b, 0xd2, 0x8f, 0xb1, 0x22, 0x7d, 0xfe, 0xa9, 0xe4, 0xde, + 0xa9, 0x77, 0xfc, 0x87, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x66, 0x3b, 0x84, 0x9c, 0x07, + 0x00, 0x00, +} + +func (m *APIGroupDiscovery) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *APIGroupDiscovery) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *APIGroupDiscovery) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Versions) > 0 { + for iNdEx := len(m.Versions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Versions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *APIGroupDiscoveryList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *APIGroupDiscoveryList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *APIGroupDiscoveryList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *APIResourceDiscovery) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *APIResourceDiscovery) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *APIResourceDiscovery) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Subresources) > 0 { + for iNdEx := len(m.Subresources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Subresources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Categories) > 0 { + for iNdEx := len(m.Categories) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Categories[iNdEx]) + copy(dAtA[i:], m.Categories[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Categories[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(m.ShortNames) > 0 { + for iNdEx := len(m.ShortNames) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ShortNames[iNdEx]) + copy(dAtA[i:], m.ShortNames[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ShortNames[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } + if len(m.Verbs) > 0 { + for iNdEx := len(m.Verbs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Verbs[iNdEx]) + copy(dAtA[i:], m.Verbs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Verbs[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + i -= len(m.SingularResource) + copy(dAtA[i:], m.SingularResource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SingularResource))) + i-- + dAtA[i] = 0x22 + i -= len(m.Scope) + copy(dAtA[i:], m.Scope) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Scope))) + i-- + dAtA[i] = 0x1a + if m.ResponseKind != nil { + { + size, err := m.ResponseKind.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Resource) + copy(dAtA[i:], m.Resource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *APISubresourceDiscovery) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *APISubresourceDiscovery) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *APISubresourceDiscovery) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Verbs) > 0 { + for iNdEx := len(m.Verbs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Verbs[iNdEx]) + copy(dAtA[i:], m.Verbs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Verbs[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.AcceptedTypes) > 0 { + for iNdEx := len(m.AcceptedTypes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AcceptedTypes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.ResponseKind != nil { + { + size, err := m.ResponseKind.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Subresource) + copy(dAtA[i:], m.Subresource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Subresource))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *APIVersionDiscovery) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *APIVersionDiscovery) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *APIVersionDiscovery) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Freshness) + copy(dAtA[i:], m.Freshness) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Freshness))) + i-- + dAtA[i] = 0x1a + if len(m.Resources) > 0 { + for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Resources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *APIGroupDiscovery) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Versions) > 0 { + for _, e := range m.Versions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *APIGroupDiscoveryList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *APIResourceDiscovery) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Resource) + n += 1 + l + sovGenerated(uint64(l)) + if m.ResponseKind != nil { + l = m.ResponseKind.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.Scope) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.SingularResource) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Verbs) > 0 { + for _, s := range m.Verbs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.ShortNames) > 0 { + for _, s := range m.ShortNames { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Categories) > 0 { + for _, s := range m.Categories { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Subresources) > 0 { + for _, e := range m.Subresources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *APISubresourceDiscovery) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Subresource) + n += 1 + l + sovGenerated(uint64(l)) + if m.ResponseKind != nil { + l = m.ResponseKind.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.AcceptedTypes) > 0 { + for _, e := range m.AcceptedTypes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Verbs) > 0 { + for _, s := range m.Verbs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *APIVersionDiscovery) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Resources) > 0 { + for _, e := range m.Resources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = len(m.Freshness) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *APIGroupDiscovery) String() string { + if this == nil { + return "nil" + } + repeatedStringForVersions := "[]APIVersionDiscovery{" + for _, f := range this.Versions { + repeatedStringForVersions += strings.Replace(strings.Replace(f.String(), "APIVersionDiscovery", "APIVersionDiscovery", 1), `&`, ``, 1) + "," + } + repeatedStringForVersions += "}" + s := strings.Join([]string{`&APIGroupDiscovery{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Versions:` + repeatedStringForVersions + `,`, + `}`, + }, "") + return s +} +func (this *APIGroupDiscoveryList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]APIGroupDiscovery{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "APIGroupDiscovery", "APIGroupDiscovery", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&APIGroupDiscoveryList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *APIResourceDiscovery) String() string { + if this == nil { + return "nil" + } + repeatedStringForSubresources := "[]APISubresourceDiscovery{" + for _, f := range this.Subresources { + repeatedStringForSubresources += strings.Replace(strings.Replace(f.String(), "APISubresourceDiscovery", "APISubresourceDiscovery", 1), `&`, ``, 1) + "," + } + repeatedStringForSubresources += "}" + s := strings.Join([]string{`&APIResourceDiscovery{`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `ResponseKind:` + strings.Replace(fmt.Sprintf("%v", this.ResponseKind), "GroupVersionKind", "v1.GroupVersionKind", 1) + `,`, + `Scope:` + fmt.Sprintf("%v", this.Scope) + `,`, + `SingularResource:` + fmt.Sprintf("%v", this.SingularResource) + `,`, + `Verbs:` + fmt.Sprintf("%v", this.Verbs) + `,`, + `ShortNames:` + fmt.Sprintf("%v", this.ShortNames) + `,`, + `Categories:` + fmt.Sprintf("%v", this.Categories) + `,`, + `Subresources:` + repeatedStringForSubresources + `,`, + `}`, + }, "") + return s +} +func (this *APISubresourceDiscovery) String() string { + if this == nil { + return "nil" + } + repeatedStringForAcceptedTypes := "[]GroupVersionKind{" + for _, f := range this.AcceptedTypes { + repeatedStringForAcceptedTypes += fmt.Sprintf("%v", f) + "," + } + repeatedStringForAcceptedTypes += "}" + s := strings.Join([]string{`&APISubresourceDiscovery{`, + `Subresource:` + fmt.Sprintf("%v", this.Subresource) + `,`, + `ResponseKind:` + strings.Replace(fmt.Sprintf("%v", this.ResponseKind), "GroupVersionKind", "v1.GroupVersionKind", 1) + `,`, + `AcceptedTypes:` + repeatedStringForAcceptedTypes + `,`, + `Verbs:` + fmt.Sprintf("%v", this.Verbs) + `,`, + `}`, + }, "") + return s +} +func (this *APIVersionDiscovery) String() string { + if this == nil { + return "nil" + } + repeatedStringForResources := "[]APIResourceDiscovery{" + for _, f := range this.Resources { + repeatedStringForResources += strings.Replace(strings.Replace(f.String(), "APIResourceDiscovery", "APIResourceDiscovery", 1), `&`, ``, 1) + "," + } + repeatedStringForResources += "}" + s := strings.Join([]string{`&APIVersionDiscovery{`, + `Version:` + fmt.Sprintf("%v", this.Version) + `,`, + `Resources:` + repeatedStringForResources + `,`, + `Freshness:` + fmt.Sprintf("%v", this.Freshness) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *APIGroupDiscovery) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: APIGroupDiscovery: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: APIGroupDiscovery: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Versions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Versions = append(m.Versions, APIVersionDiscovery{}) + if err := m.Versions[len(m.Versions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *APIGroupDiscoveryList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: APIGroupDiscoveryList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: APIGroupDiscoveryList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, APIGroupDiscovery{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *APIResourceDiscovery) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: APIResourceDiscovery: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: APIResourceDiscovery: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResponseKind", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ResponseKind == nil { + m.ResponseKind = &v1.GroupVersionKind{} + } + if err := m.ResponseKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Scope = ResourceScope(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SingularResource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SingularResource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShortNames", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShortNames = append(m.ShortNames, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Categories = append(m.Categories, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subresources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subresources = append(m.Subresources, APISubresourceDiscovery{}) + if err := m.Subresources[len(m.Subresources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *APISubresourceDiscovery) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: APISubresourceDiscovery: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: APISubresourceDiscovery: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subresource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subresource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResponseKind", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ResponseKind == nil { + m.ResponseKind = &v1.GroupVersionKind{} + } + if err := m.ResponseKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptedTypes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptedTypes = append(m.AcceptedTypes, v1.GroupVersionKind{}) + if err := m.AcceptedTypes[len(m.AcceptedTypes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *APIVersionDiscovery) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: APIVersionDiscovery: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: APIVersionDiscovery: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, APIResourceDiscovery{}) + if err := m.Resources[len(m.Resources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Freshness", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Freshness = DiscoveryFreshness(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto new file mode 100644 index 00000000000..aa08b4978c2 --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto @@ -0,0 +1,156 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.apidiscovery.v2beta1; + +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/apidiscovery/v2beta1"; + +// APIGroupDiscovery holds information about which resources are being served for all version of the API Group. +// It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version. +// Versions are in descending order of preference, with the first version being the preferred entry. +message APIGroupDiscovery { + // Standard object's metadata. + // The only field completed will be name. For instance, resourceVersion will be empty. + // name is the name of the API group whose discovery information is presented here. + // name is allowed to be "" to represent the legacy, ungroupified resources. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // versions are the versions supported in this group. They are sorted in descending order of preference, + // with the preferred version being the first entry. + // +listType=map + // +listMapKey=version + repeated APIVersionDiscovery versions = 2; +} + +// APIGroupDiscoveryList is a resource containing a list of APIGroupDiscovery. +// This is one of the types able to be returned from the /api and /apis endpoint and contains an aggregated +// list of API resources (built-ins, Custom Resource Definitions, resources from aggregated servers) +// that a cluster supports. +message APIGroupDiscoveryList { + // ResourceVersion will not be set, because this does not have a replayable ordering among multiple apiservers. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is the list of groups for discovery. The groups are listed in priority order. + repeated APIGroupDiscovery items = 2; +} + +// APIResourceDiscovery provides information about an API resource for discovery. +message APIResourceDiscovery { + // resource is the plural name of the resource. This is used in the URL path and is the unique identifier + // for this resource across all versions in the API group. + // Resources with non-empty groups are located at /apis/// + // Resources with empty groups are located at /api/v1/ + optional string resource = 1; + + // responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns. + // APIs may return other objects types at their discretion, such as error conditions, requests for alternate representations, or other operation specific behavior. + // This value will be null if an APIService reports subresources but supports no operations on the parent resource + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind responseKind = 2; + + // scope indicates the scope of a resource, either Cluster or Namespaced + optional string scope = 3; + + // singularResource is the singular name of the resource. This allows clients to handle plural and singular opaquely. + // For many clients the singular form of the resource will be more understandable to users reading messages and should be used when integrating the name of the resource into a sentence. + // The command line tool kubectl, for example, allows use of the singular resource name in place of plurals. + // The singular form of a resource should always be an optional element - when in doubt use the canonical resource name. + optional string singularResource = 4; + + // verbs is a list of supported API operation types (this includes + // but is not limited to get, list, watch, create, update, patch, + // delete, deletecollection, and proxy). + // +listType=set + repeated string verbs = 5; + + // shortNames is a list of suggested short names of the resource. + // +listType=set + repeated string shortNames = 6; + + // categories is a list of the grouped resources this resource belongs to (e.g. 'all'). + // Clients may use this to simplify acting on multiple resource types at once. + // +listType=set + repeated string categories = 7; + + // subresources is a list of subresources provided by this resource. Subresources are located at /apis////name-of-instance/ + // +listType=map + // +listMapKey=subresource + repeated APISubresourceDiscovery subresources = 8; +} + +// APISubresourceDiscovery provides information about an API subresource for discovery. +message APISubresourceDiscovery { + // subresource is the name of the subresource. This is used in the URL path and is the unique identifier + // for this resource across all versions. + optional string subresource = 1; + + // responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns. + // Some subresources do not return normal resources, these will have null return types. + optional k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind responseKind = 2; + + // acceptedTypes describes the kinds that this endpoint accepts. + // Subresources may accept the standard content types or define + // custom negotiation schemes. The list may not be exhaustive for + // all operations. + // +listType=map + // +listMapKey=group + // +listMapKey=version + // +listMapKey=kind + repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind acceptedTypes = 3; + + // verbs is a list of supported API operation types (this includes + // but is not limited to get, list, watch, create, update, patch, + // delete, deletecollection, and proxy). Subresources may define + // custom verbs outside the standard Kubernetes verb set. Clients + // should expect the behavior of standard verbs to align with + // Kubernetes interaction conventions. + // +listType=set + repeated string verbs = 4; +} + +// APIVersionDiscovery holds a list of APIResourceDiscovery types that are served for a particular version within an API Group. +message APIVersionDiscovery { + // version is the name of the version within a group version. + optional string version = 1; + + // resources is a list of APIResourceDiscovery objects for the corresponding group version. + // +listType=map + // +listMapKey=resource + repeated APIResourceDiscovery resources = 2; + + // freshness marks whether a group version's discovery document is up to date. + // "Current" indicates the discovery document was recently + // refreshed. "Stale" indicates the discovery document could not + // be retrieved and the returned discovery document may be + // significantly out of date. Clients that require the latest + // version of the discovery information be retrieved before + // performing an operation should not use the aggregated document + optional string freshness = 3; +} + diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/register.go b/vendor/k8s.io/api/apidiscovery/v2beta1/register.go new file mode 100644 index 00000000000..f7cef108121 --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/register.go @@ -0,0 +1,56 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name for this API. +const GroupName = "apidiscovery.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2beta1"} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder installs the api group to a scheme + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme adds api to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &APIGroupDiscoveryList{}, + &APIGroupDiscovery{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/types.go b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go new file mode 100644 index 00000000000..1aff3e3702f --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go @@ -0,0 +1,163 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2beta1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 +// +k8s:prerelease-lifecycle-gen:deprecated=1.32 +// +k8s:prerelease-lifecycle-gen:removed=1.35 +// The deprecate and remove versions stated above are rough estimates and may be subject to change. We are estimating v2 types will be available in 1.28 and will support 4 versions where both v2beta1 and v2 are supported before deprecation. + +// APIGroupDiscoveryList is a resource containing a list of APIGroupDiscovery. +// This is one of the types able to be returned from the /api and /apis endpoint and contains an aggregated +// list of API resources (built-ins, Custom Resource Definitions, resources from aggregated servers) +// that a cluster supports. +type APIGroupDiscoveryList struct { + v1.TypeMeta `json:",inline"` + // ResourceVersion will not be set, because this does not have a replayable ordering among multiple apiservers. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + v1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // items is the list of groups for discovery. The groups are listed in priority order. + Items []APIGroupDiscovery `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 +// +k8s:prerelease-lifecycle-gen:deprecated=1.32 +// +k8s:prerelease-lifecycle-gen:removed=1.35 +// The deprecate and remove versions stated above are rough estimates and may be subject to change. We are estimating v2 types will be available in 1.28 and will support 4 versions where both v2beta1 and v2 are supported before deprecation. + +// APIGroupDiscovery holds information about which resources are being served for all version of the API Group. +// It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version. +// Versions are in descending order of preference, with the first version being the preferred entry. +type APIGroupDiscovery struct { + v1.TypeMeta `json:",inline"` + // Standard object's metadata. + // The only field completed will be name. For instance, resourceVersion will be empty. + // name is the name of the API group whose discovery information is presented here. + // name is allowed to be "" to represent the legacy, ungroupified resources. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // versions are the versions supported in this group. They are sorted in descending order of preference, + // with the preferred version being the first entry. + // +listType=map + // +listMapKey=version + Versions []APIVersionDiscovery `json:"versions,omitempty" protobuf:"bytes,2,rep,name=versions"` +} + +// APIVersionDiscovery holds a list of APIResourceDiscovery types that are served for a particular version within an API Group. +type APIVersionDiscovery struct { + // version is the name of the version within a group version. + Version string `json:"version" protobuf:"bytes,1,opt,name=version"` + // resources is a list of APIResourceDiscovery objects for the corresponding group version. + // +listType=map + // +listMapKey=resource + Resources []APIResourceDiscovery `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"` + // freshness marks whether a group version's discovery document is up to date. + // "Current" indicates the discovery document was recently + // refreshed. "Stale" indicates the discovery document could not + // be retrieved and the returned discovery document may be + // significantly out of date. Clients that require the latest + // version of the discovery information be retrieved before + // performing an operation should not use the aggregated document + Freshness DiscoveryFreshness `json:"freshness,omitempty" protobuf:"bytes,3,opt,name=freshness"` +} + +// APIResourceDiscovery provides information about an API resource for discovery. +type APIResourceDiscovery struct { + // resource is the plural name of the resource. This is used in the URL path and is the unique identifier + // for this resource across all versions in the API group. + // Resources with non-empty groups are located at /apis/// + // Resources with empty groups are located at /api/v1/ + Resource string `json:"resource" protobuf:"bytes,1,opt,name=resource"` + // responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns. + // APIs may return other objects types at their discretion, such as error conditions, requests for alternate representations, or other operation specific behavior. + // This value will be null if an APIService reports subresources but supports no operations on the parent resource + ResponseKind *v1.GroupVersionKind `json:"responseKind,omitempty" protobuf:"bytes,2,opt,name=responseKind"` + // scope indicates the scope of a resource, either Cluster or Namespaced + Scope ResourceScope `json:"scope" protobuf:"bytes,3,opt,name=scope"` + // singularResource is the singular name of the resource. This allows clients to handle plural and singular opaquely. + // For many clients the singular form of the resource will be more understandable to users reading messages and should be used when integrating the name of the resource into a sentence. + // The command line tool kubectl, for example, allows use of the singular resource name in place of plurals. + // The singular form of a resource should always be an optional element - when in doubt use the canonical resource name. + SingularResource string `json:"singularResource" protobuf:"bytes,4,opt,name=singularResource"` + // verbs is a list of supported API operation types (this includes + // but is not limited to get, list, watch, create, update, patch, + // delete, deletecollection, and proxy). + // +listType=set + Verbs []string `json:"verbs" protobuf:"bytes,5,opt,name=verbs"` + // shortNames is a list of suggested short names of the resource. + // +listType=set + ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,6,rep,name=shortNames"` + // categories is a list of the grouped resources this resource belongs to (e.g. 'all'). + // Clients may use this to simplify acting on multiple resource types at once. + // +listType=set + Categories []string `json:"categories,omitempty" protobuf:"bytes,7,rep,name=categories"` + // subresources is a list of subresources provided by this resource. Subresources are located at /apis////name-of-instance/ + // +listType=map + // +listMapKey=subresource + Subresources []APISubresourceDiscovery `json:"subresources,omitempty" protobuf:"bytes,8,rep,name=subresources"` +} + +// ResourceScope is an enum defining the different scopes available to a resource. +type ResourceScope string + +const ( + ScopeCluster ResourceScope = "Cluster" + ScopeNamespace ResourceScope = "Namespaced" +) + +// DiscoveryFreshness is an enum defining whether the Discovery document published by an apiservice is up to date (fresh). +type DiscoveryFreshness string + +const ( + DiscoveryFreshnessCurrent DiscoveryFreshness = "Current" + DiscoveryFreshnessStale DiscoveryFreshness = "Stale" +) + +// APISubresourceDiscovery provides information about an API subresource for discovery. +type APISubresourceDiscovery struct { + // subresource is the name of the subresource. This is used in the URL path and is the unique identifier + // for this resource across all versions. + Subresource string `json:"subresource" protobuf:"bytes,1,opt,name=subresource"` + // responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns. + // Some subresources do not return normal resources, these will have null return types. + ResponseKind *v1.GroupVersionKind `json:"responseKind,omitempty" protobuf:"bytes,2,opt,name=responseKind"` + // acceptedTypes describes the kinds that this endpoint accepts. + // Subresources may accept the standard content types or define + // custom negotiation schemes. The list may not be exhaustive for + // all operations. + // +listType=map + // +listMapKey=group + // +listMapKey=version + // +listMapKey=kind + AcceptedTypes []v1.GroupVersionKind `json:"acceptedTypes,omitempty" protobuf:"bytes,3,rep,name=acceptedTypes"` + // verbs is a list of supported API operation types (this includes + // but is not limited to get, list, watch, create, update, patch, + // delete, deletecollection, and proxy). Subresources may define + // custom verbs outside the standard Kubernetes verb set. Clients + // should expect the behavior of standard verbs to align with + // Kubernetes interaction conventions. + // +listType=set + Verbs []string `json:"verbs" protobuf:"bytes,4,opt,name=verbs"` +} diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..cf8f98c6fba --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.deepcopy.go @@ -0,0 +1,190 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v2beta1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIGroupDiscovery) DeepCopyInto(out *APIGroupDiscovery) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Versions != nil { + in, out := &in.Versions, &out.Versions + *out = make([]APIVersionDiscovery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGroupDiscovery. +func (in *APIGroupDiscovery) DeepCopy() *APIGroupDiscovery { + if in == nil { + return nil + } + out := new(APIGroupDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *APIGroupDiscovery) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIGroupDiscoveryList) DeepCopyInto(out *APIGroupDiscoveryList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]APIGroupDiscovery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGroupDiscoveryList. +func (in *APIGroupDiscoveryList) DeepCopy() *APIGroupDiscoveryList { + if in == nil { + return nil + } + out := new(APIGroupDiscoveryList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *APIGroupDiscoveryList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIResourceDiscovery) DeepCopyInto(out *APIResourceDiscovery) { + *out = *in + if in.ResponseKind != nil { + in, out := &in.ResponseKind, &out.ResponseKind + *out = new(v1.GroupVersionKind) + **out = **in + } + if in.Verbs != nil { + in, out := &in.Verbs, &out.Verbs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ShortNames != nil { + in, out := &in.ShortNames, &out.ShortNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Categories != nil { + in, out := &in.Categories, &out.Categories + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Subresources != nil { + in, out := &in.Subresources, &out.Subresources + *out = make([]APISubresourceDiscovery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIResourceDiscovery. +func (in *APIResourceDiscovery) DeepCopy() *APIResourceDiscovery { + if in == nil { + return nil + } + out := new(APIResourceDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APISubresourceDiscovery) DeepCopyInto(out *APISubresourceDiscovery) { + *out = *in + if in.ResponseKind != nil { + in, out := &in.ResponseKind, &out.ResponseKind + *out = new(v1.GroupVersionKind) + **out = **in + } + if in.AcceptedTypes != nil { + in, out := &in.AcceptedTypes, &out.AcceptedTypes + *out = make([]v1.GroupVersionKind, len(*in)) + copy(*out, *in) + } + if in.Verbs != nil { + in, out := &in.Verbs, &out.Verbs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APISubresourceDiscovery. +func (in *APISubresourceDiscovery) DeepCopy() *APISubresourceDiscovery { + if in == nil { + return nil + } + out := new(APISubresourceDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIVersionDiscovery) DeepCopyInto(out *APIVersionDiscovery) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]APIResourceDiscovery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIVersionDiscovery. +func (in *APIVersionDiscovery) DeepCopy() *APIVersionDiscovery { + if in == nil { + return nil + } + out := new(APIVersionDiscovery) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.prerelease-lifecycle.go new file mode 100644 index 00000000000..aa8f15fb4c3 --- /dev/null +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v2beta1 + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *APIGroupDiscovery) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *APIGroupDiscovery) APILifecycleDeprecated() (major, minor int) { + return 1, 32 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *APIGroupDiscovery) APILifecycleRemoved() (major, minor int) { + return 1, 35 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *APIGroupDiscoveryList) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *APIGroupDiscoveryList) APILifecycleDeprecated() (major, minor int) { + return 1, 32 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *APIGroupDiscoveryList) APILifecycleRemoved() (major, minor int) { + return 1, 35 +} diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto index 37ac0d32670..63c45d54d71 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto @@ -44,7 +44,7 @@ message ServerStorageVersion { repeated string decodableVersions = 3; } -// Storage version of a specific resource. +// Storage version of a specific resource. message StorageVersion { // The name is .. optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go index bfa249e135c..a0437b5074c 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go @@ -24,7 +24,7 @@ import ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Storage version of a specific resource. +// Storage version of a specific resource. type StorageVersion struct { metav1.TypeMeta `json:",inline"` // The name is .. diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go index 297ed08a715..3b75fa65bc3 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ServerStorageVersion = map[string]string{ @@ -39,7 +39,7 @@ func (ServerStorageVersion) SwaggerDoc() map[string]string { } var map_StorageVersion = map[string]string{ - "": "\n Storage version of a specific resource.", + "": "Storage version of a specific resource.", "metadata": "The name is ..", "spec": "Spec is an empty spec. It is here to comply with Kubernetes API style.", "status": "API server instances report the version they can decode and the version they encode objects to when persisting objects in the backend.", diff --git a/vendor/k8s.io/api/apps/v1/generated.pb.go b/vendor/k8s.io/api/apps/v1/generated.pb.go index ee10998d52c..84a7af5994f 100644 --- a/vendor/k8s.io/api/apps/v1/generated.pb.go +++ b/vendor/k8s.io/api/apps/v1/generated.pb.go @@ -748,12 +748,40 @@ func (m *StatefulSetList) XXX_DiscardUnknown() { var xxx_messageInfo_StatefulSetList proto.InternalMessageInfo +func (m *StatefulSetOrdinals) Reset() { *m = StatefulSetOrdinals{} } +func (*StatefulSetOrdinals) ProtoMessage() {} +func (*StatefulSetOrdinals) Descriptor() ([]byte, []int) { + return fileDescriptor_e1014cab6f31e43b, []int{25} +} +func (m *StatefulSetOrdinals) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StatefulSetOrdinals) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *StatefulSetOrdinals) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatefulSetOrdinals.Merge(m, src) +} +func (m *StatefulSetOrdinals) XXX_Size() int { + return m.Size() +} +func (m *StatefulSetOrdinals) XXX_DiscardUnknown() { + xxx_messageInfo_StatefulSetOrdinals.DiscardUnknown(m) +} + +var xxx_messageInfo_StatefulSetOrdinals proto.InternalMessageInfo + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Reset() { *m = StatefulSetPersistentVolumeClaimRetentionPolicy{} } func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} func (*StatefulSetPersistentVolumeClaimRetentionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_e1014cab6f31e43b, []int{25} + return fileDescriptor_e1014cab6f31e43b, []int{26} } func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -781,7 +809,7 @@ var xxx_messageInfo_StatefulSetPersistentVolumeClaimRetentionPolicy proto.Intern func (m *StatefulSetSpec) Reset() { *m = StatefulSetSpec{} } func (*StatefulSetSpec) ProtoMessage() {} func (*StatefulSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e1014cab6f31e43b, []int{26} + return fileDescriptor_e1014cab6f31e43b, []int{27} } func (m *StatefulSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -809,7 +837,7 @@ var xxx_messageInfo_StatefulSetSpec proto.InternalMessageInfo func (m *StatefulSetStatus) Reset() { *m = StatefulSetStatus{} } func (*StatefulSetStatus) ProtoMessage() {} func (*StatefulSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e1014cab6f31e43b, []int{27} + return fileDescriptor_e1014cab6f31e43b, []int{28} } func (m *StatefulSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -837,7 +865,7 @@ var xxx_messageInfo_StatefulSetStatus proto.InternalMessageInfo func (m *StatefulSetUpdateStrategy) Reset() { *m = StatefulSetUpdateStrategy{} } func (*StatefulSetUpdateStrategy) ProtoMessage() {} func (*StatefulSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_e1014cab6f31e43b, []int{28} + return fileDescriptor_e1014cab6f31e43b, []int{29} } func (m *StatefulSetUpdateStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -888,6 +916,7 @@ func init() { proto.RegisterType((*StatefulSet)(nil), "k8s.io.api.apps.v1.StatefulSet") proto.RegisterType((*StatefulSetCondition)(nil), "k8s.io.api.apps.v1.StatefulSetCondition") proto.RegisterType((*StatefulSetList)(nil), "k8s.io.api.apps.v1.StatefulSetList") + proto.RegisterType((*StatefulSetOrdinals)(nil), "k8s.io.api.apps.v1.StatefulSetOrdinals") proto.RegisterType((*StatefulSetPersistentVolumeClaimRetentionPolicy)(nil), "k8s.io.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy") proto.RegisterType((*StatefulSetSpec)(nil), "k8s.io.api.apps.v1.StatefulSetSpec") proto.RegisterType((*StatefulSetStatus)(nil), "k8s.io.api.apps.v1.StatefulSetStatus") @@ -899,142 +928,146 @@ func init() { } var fileDescriptor_e1014cab6f31e43b = []byte{ - // 2160 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x6f, 0x1c, 0xb7, - 0x15, 0xd7, 0xec, 0x87, 0xb4, 0xa2, 0x2c, 0xc9, 0xa6, 0x54, 0x69, 0x63, 0x37, 0xbb, 0xee, 0xd6, - 0x75, 0x94, 0x38, 0xde, 0xad, 0x1d, 0x27, 0x08, 0xe2, 0x22, 0x81, 0x66, 0x95, 0xa6, 0x69, 0x24, - 0x59, 0xa5, 0x2c, 0x07, 0x70, 0xd3, 0xa2, 0xd4, 0x2c, 0xbd, 0x9a, 0x68, 0xbe, 0x30, 0xc3, 0x51, - 0x2c, 0xf4, 0x52, 0x14, 0xe8, 0xad, 0x87, 0xfe, 0x27, 0x45, 0x51, 0x34, 0xb7, 0x20, 0x08, 0x7a, - 0xf1, 0xa5, 0x68, 0xd0, 0x4b, 0x73, 0x5a, 0xd4, 0x9b, 0x53, 0x51, 0xf4, 0xd6, 0x5e, 0x7c, 0x69, - 0x41, 0x0e, 0xe7, 0x9b, 0xa3, 0x5d, 0xc9, 0xb1, 0xf2, 0x01, 0xdf, 0xb4, 0xe4, 0xef, 0xfd, 0xf8, - 0x48, 0xbe, 0xc7, 0xf7, 0x23, 0x47, 0xe0, 0xe6, 0xfe, 0xab, 0x5e, 0x5b, 0xb7, 0x3b, 0xfb, 0xfe, - 0x2e, 0x71, 0x2d, 0x42, 0x89, 0xd7, 0x39, 0x20, 0x56, 0xcf, 0x76, 0x3b, 0xa2, 0x03, 0x3b, 0x7a, - 0x07, 0x3b, 0x8e, 0xd7, 0x39, 0xb8, 0xd6, 0xe9, 0x13, 0x8b, 0xb8, 0x98, 0x92, 0x5e, 0xdb, 0x71, - 0x6d, 0x6a, 0x43, 0x18, 0x60, 0xda, 0xd8, 0xd1, 0xdb, 0x0c, 0xd3, 0x3e, 0xb8, 0x76, 0xfe, 0x6a, - 0x5f, 0xa7, 0x7b, 0xfe, 0x6e, 0x5b, 0xb3, 0xcd, 0x4e, 0xdf, 0xee, 0xdb, 0x1d, 0x0e, 0xdd, 0xf5, - 0xef, 0xf1, 0x5f, 0xfc, 0x07, 0xff, 0x2b, 0xa0, 0x38, 0xdf, 0x4a, 0x0c, 0xa3, 0xd9, 0x2e, 0x91, - 0x0c, 0x73, 0xfe, 0x46, 0x8c, 0x31, 0xb1, 0xb6, 0xa7, 0x5b, 0xc4, 0x3d, 0xec, 0x38, 0xfb, 0x7d, - 0xd6, 0xe0, 0x75, 0x4c, 0x42, 0xb1, 0xcc, 0xaa, 0x53, 0x64, 0xe5, 0xfa, 0x16, 0xd5, 0x4d, 0x92, - 0x33, 0x78, 0x65, 0x94, 0x81, 0xa7, 0xed, 0x11, 0x13, 0xe7, 0xec, 0x5e, 0x2a, 0xb2, 0xf3, 0xa9, - 0x6e, 0x74, 0x74, 0x8b, 0x7a, 0xd4, 0xcd, 0x1a, 0xb5, 0xfe, 0xab, 0x00, 0xd8, 0xb5, 0x2d, 0xea, - 0xda, 0x86, 0x41, 0x5c, 0x44, 0x0e, 0x74, 0x4f, 0xb7, 0x2d, 0xf8, 0x0b, 0x50, 0x63, 0xf3, 0xe9, - 0x61, 0x8a, 0xeb, 0xca, 0x45, 0x65, 0x65, 0xe6, 0xfa, 0xf7, 0xdb, 0xf1, 0x22, 0x47, 0xf4, 0x6d, - 0x67, 0xbf, 0xcf, 0x1a, 0xbc, 0x36, 0x43, 0xb7, 0x0f, 0xae, 0xb5, 0x6f, 0xed, 0xbe, 0x4f, 0x34, - 0xba, 0x41, 0x28, 0x56, 0xe1, 0x83, 0x41, 0x73, 0x62, 0x38, 0x68, 0x82, 0xb8, 0x0d, 0x45, 0xac, - 0xf0, 0x16, 0xa8, 0x70, 0xf6, 0x12, 0x67, 0xbf, 0x5a, 0xc8, 0x2e, 0x26, 0xdd, 0x46, 0xf8, 0x83, - 0x37, 0xef, 0x53, 0x62, 0x31, 0xf7, 0xd4, 0x33, 0x82, 0xba, 0xb2, 0x86, 0x29, 0x46, 0x9c, 0x08, - 0xbe, 0x08, 0x6a, 0xae, 0x70, 0xbf, 0x5e, 0xbe, 0xa8, 0xac, 0x94, 0xd5, 0xb3, 0x02, 0x55, 0x0b, - 0xa7, 0x85, 0x22, 0x44, 0xeb, 0xcf, 0x0a, 0x58, 0xca, 0xcf, 0x7b, 0x5d, 0xf7, 0x28, 0x7c, 0x2f, - 0x37, 0xf7, 0xf6, 0x78, 0x73, 0x67, 0xd6, 0x7c, 0xe6, 0xd1, 0xc0, 0x61, 0x4b, 0x62, 0xde, 0xef, - 0x80, 0xaa, 0x4e, 0x89, 0xe9, 0xd5, 0x4b, 0x17, 0xcb, 0x2b, 0x33, 0xd7, 0x2f, 0xb7, 0xf3, 0xb1, - 0xdb, 0xce, 0x3b, 0xa6, 0xce, 0x0a, 0xca, 0xea, 0xdb, 0xcc, 0x18, 0x05, 0x1c, 0xad, 0xff, 0x29, - 0x60, 0x7a, 0x0d, 0x13, 0xd3, 0xb6, 0xb6, 0x09, 0x3d, 0x85, 0x4d, 0xeb, 0x82, 0x8a, 0xe7, 0x10, - 0x4d, 0x6c, 0xda, 0x77, 0x64, 0xbe, 0x47, 0xee, 0x6c, 0x3b, 0x44, 0x8b, 0x37, 0x8a, 0xfd, 0x42, - 0xdc, 0x18, 0xbe, 0x03, 0x26, 0x3d, 0x8a, 0xa9, 0xef, 0xf1, 0x6d, 0x9a, 0xb9, 0xfe, 0xdd, 0xa3, - 0x69, 0x38, 0x54, 0x9d, 0x13, 0x44, 0x93, 0xc1, 0x6f, 0x24, 0x28, 0x5a, 0xff, 0x2c, 0x01, 0x18, - 0x61, 0xbb, 0xb6, 0xd5, 0xd3, 0x29, 0x8b, 0xdf, 0xd7, 0x40, 0x85, 0x1e, 0x3a, 0x84, 0x2f, 0xc3, - 0xb4, 0x7a, 0x39, 0xf4, 0xe2, 0xf6, 0xa1, 0x43, 0x1e, 0x0d, 0x9a, 0x4b, 0x79, 0x0b, 0xd6, 0x83, - 0xb8, 0x0d, 0x5c, 0x8f, 0xfc, 0x2b, 0x71, 0xeb, 0x1b, 0xe9, 0xa1, 0x1f, 0x0d, 0x9a, 0x92, 0xc3, - 0xa2, 0x1d, 0x31, 0xa5, 0x1d, 0x84, 0x07, 0x00, 0x1a, 0xd8, 0xa3, 0xb7, 0x5d, 0x6c, 0x79, 0xc1, - 0x48, 0xba, 0x49, 0xc4, 0xcc, 0x5f, 0x18, 0x6f, 0x7b, 0x98, 0x85, 0x7a, 0x5e, 0x78, 0x01, 0xd7, - 0x73, 0x6c, 0x48, 0x32, 0x02, 0xbc, 0x0c, 0x26, 0x5d, 0x82, 0x3d, 0xdb, 0xaa, 0x57, 0xf8, 0x2c, - 0xa2, 0x05, 0x44, 0xbc, 0x15, 0x89, 0x5e, 0xf8, 0x3c, 0x98, 0x32, 0x89, 0xe7, 0xe1, 0x3e, 0xa9, - 0x57, 0x39, 0x70, 0x5e, 0x00, 0xa7, 0x36, 0x82, 0x66, 0x14, 0xf6, 0xb7, 0xfe, 0xa0, 0x80, 0xd9, - 0x68, 0xe5, 0x4e, 0x21, 0x55, 0xd4, 0x74, 0xaa, 0x3c, 0x7b, 0x64, 0x9c, 0x14, 0x64, 0xc8, 0xc7, - 0xe5, 0x84, 0xcf, 0x2c, 0x08, 0xe1, 0xcf, 0x40, 0xcd, 0x23, 0x06, 0xd1, 0xa8, 0xed, 0x0a, 0x9f, - 0x5f, 0x1a, 0xd3, 0x67, 0xbc, 0x4b, 0x8c, 0x6d, 0x61, 0xaa, 0x9e, 0x61, 0x4e, 0x87, 0xbf, 0x50, - 0x44, 0x09, 0x7f, 0x02, 0x6a, 0x94, 0x98, 0x8e, 0x81, 0x29, 0x11, 0x69, 0x92, 0x8a, 0x6f, 0x16, - 0x2e, 0x8c, 0x6c, 0xcb, 0xee, 0xdd, 0x16, 0x30, 0x9e, 0x28, 0xd1, 0x3a, 0x84, 0xad, 0x28, 0xa2, - 0x81, 0xfb, 0x60, 0xce, 0x77, 0x7a, 0x0c, 0x49, 0xd9, 0xd1, 0xdd, 0x3f, 0x14, 0xe1, 0x73, 0xe5, - 0xc8, 0x05, 0xd9, 0x49, 0x99, 0xa8, 0x4b, 0x62, 0x80, 0xb9, 0x74, 0x3b, 0xca, 0x50, 0xc3, 0x55, - 0x30, 0x6f, 0xea, 0x16, 0x22, 0xb8, 0x77, 0xb8, 0x4d, 0x34, 0xdb, 0xea, 0x79, 0x3c, 0x80, 0xaa, - 0xea, 0xb2, 0x20, 0x98, 0xdf, 0x48, 0x77, 0xa3, 0x2c, 0x1e, 0xae, 0x83, 0xc5, 0xf0, 0x9c, 0xfd, - 0x91, 0xee, 0x51, 0xdb, 0x3d, 0x5c, 0xd7, 0x4d, 0x9d, 0xd6, 0x27, 0x39, 0x4f, 0x7d, 0x38, 0x68, - 0x2e, 0x22, 0x49, 0x3f, 0x92, 0x5a, 0xb5, 0x7e, 0x3b, 0x09, 0xe6, 0x33, 0xa7, 0x01, 0xbc, 0x03, - 0x96, 0x34, 0xdf, 0x75, 0x89, 0x45, 0x37, 0x7d, 0x73, 0x97, 0xb8, 0xdb, 0xda, 0x1e, 0xe9, 0xf9, - 0x06, 0xe9, 0xf1, 0x1d, 0xad, 0xaa, 0x0d, 0xe1, 0xeb, 0x52, 0x57, 0x8a, 0x42, 0x05, 0xd6, 0xf0, - 0xc7, 0x00, 0x5a, 0xbc, 0x69, 0x43, 0xf7, 0xbc, 0x88, 0xb3, 0xc4, 0x39, 0xa3, 0x04, 0xdc, 0xcc, - 0x21, 0x90, 0xc4, 0x8a, 0xf9, 0xd8, 0x23, 0x9e, 0xee, 0x92, 0x5e, 0xd6, 0xc7, 0x72, 0xda, 0xc7, - 0x35, 0x29, 0x0a, 0x15, 0x58, 0xc3, 0x97, 0xc1, 0x4c, 0x30, 0x1a, 0x5f, 0x73, 0xb1, 0x39, 0x0b, - 0x82, 0x6c, 0x66, 0x33, 0xee, 0x42, 0x49, 0x1c, 0x9b, 0x9a, 0xbd, 0xeb, 0x11, 0xf7, 0x80, 0xf4, - 0xde, 0x0a, 0x34, 0x00, 0x2b, 0x94, 0x55, 0x5e, 0x28, 0xa3, 0xa9, 0xdd, 0xca, 0x21, 0x90, 0xc4, - 0x8a, 0x4d, 0x2d, 0x88, 0x9a, 0xdc, 0xd4, 0x26, 0xd3, 0x53, 0xdb, 0x91, 0xa2, 0x50, 0x81, 0x35, - 0x8b, 0xbd, 0xc0, 0xe5, 0xd5, 0x03, 0xac, 0x1b, 0x78, 0xd7, 0x20, 0xf5, 0xa9, 0x74, 0xec, 0x6d, - 0xa6, 0xbb, 0x51, 0x16, 0x0f, 0xdf, 0x02, 0xe7, 0x82, 0xa6, 0x1d, 0x0b, 0x47, 0x24, 0x35, 0x4e, - 0xf2, 0x8c, 0x20, 0x39, 0xb7, 0x99, 0x05, 0xa0, 0xbc, 0x0d, 0x7c, 0x0d, 0xcc, 0x69, 0xb6, 0x61, - 0xf0, 0x78, 0xec, 0xda, 0xbe, 0x45, 0xeb, 0xd3, 0x9c, 0x05, 0xb2, 0x1c, 0xea, 0xa6, 0x7a, 0x50, - 0x06, 0x09, 0xef, 0x02, 0xa0, 0x85, 0xe5, 0xc0, 0xab, 0x83, 0xe2, 0x42, 0x9f, 0xaf, 0x43, 0x71, - 0x01, 0x8e, 0x9a, 0x3c, 0x94, 0x60, 0x6b, 0x7d, 0xac, 0x80, 0xe5, 0x82, 0x1c, 0x87, 0x6f, 0xa4, - 0xaa, 0xde, 0x95, 0x4c, 0xd5, 0xbb, 0x50, 0x60, 0x96, 0x28, 0x7d, 0x1a, 0x98, 0x65, 0xba, 0x43, - 0xb7, 0xfa, 0x01, 0x44, 0x9c, 0x60, 0x2f, 0xc8, 0x7c, 0x47, 0x49, 0x60, 0x7c, 0x0c, 0x9f, 0x1b, - 0x0e, 0x9a, 0xb3, 0xa9, 0x3e, 0x94, 0xe6, 0x6c, 0xfd, 0xba, 0x04, 0xc0, 0x1a, 0x71, 0x0c, 0xfb, - 0xd0, 0x24, 0xd6, 0x69, 0xa8, 0x96, 0xb5, 0x94, 0x6a, 0x69, 0x49, 0x37, 0x22, 0xf2, 0xa7, 0x50, - 0xb6, 0xac, 0x67, 0x64, 0xcb, 0xa5, 0x11, 0x3c, 0x47, 0xeb, 0x96, 0xbf, 0x97, 0xc1, 0x42, 0x0c, - 0x8e, 0x85, 0xcb, 0xcd, 0xd4, 0x16, 0x3e, 0x97, 0xd9, 0xc2, 0x65, 0x89, 0xc9, 0x13, 0x53, 0x2e, - 0xef, 0x83, 0x39, 0xa6, 0x2b, 0x82, 0x5d, 0xe3, 0xaa, 0x65, 0xf2, 0xd8, 0xaa, 0x25, 0xaa, 0x3a, - 0xeb, 0x29, 0x26, 0x94, 0x61, 0x2e, 0x50, 0x49, 0x53, 0x5f, 0x47, 0x95, 0xf4, 0x47, 0x05, 0xcc, - 0xc5, 0xdb, 0x74, 0x0a, 0x32, 0xa9, 0x9b, 0x96, 0x49, 0x8d, 0xa3, 0xe3, 0xb2, 0x40, 0x27, 0xfd, - 0xad, 0x92, 0xf4, 0x9a, 0x0b, 0xa5, 0x15, 0x76, 0xa1, 0x72, 0x0c, 0x5d, 0xc3, 0x9e, 0x28, 0xab, - 0x67, 0x82, 0xcb, 0x54, 0xd0, 0x86, 0xa2, 0xde, 0x94, 0xa4, 0x2a, 0x3d, 0x59, 0x49, 0x55, 0xfe, - 0x62, 0x24, 0xd5, 0x6d, 0x50, 0xf3, 0x42, 0x31, 0x55, 0xe1, 0x94, 0x97, 0x47, 0xa5, 0xb3, 0xd0, - 0x51, 0x11, 0x6b, 0xa4, 0xa0, 0x22, 0x26, 0x99, 0x76, 0xaa, 0x7e, 0x99, 0xda, 0x89, 0x85, 0xb7, - 0x83, 0x7d, 0x8f, 0xf4, 0x78, 0x2a, 0xd5, 0xe2, 0xf0, 0xde, 0xe2, 0xad, 0x48, 0xf4, 0xc2, 0x1d, - 0xb0, 0xec, 0xb8, 0x76, 0xdf, 0x25, 0x9e, 0xb7, 0x46, 0x70, 0xcf, 0xd0, 0x2d, 0x12, 0x4e, 0x20, - 0xa8, 0x7a, 0x17, 0x86, 0x83, 0xe6, 0xf2, 0x96, 0x1c, 0x82, 0x8a, 0x6c, 0x5b, 0x1f, 0x55, 0xc0, - 0xd9, 0xec, 0x89, 0x58, 0x20, 0x44, 0x94, 0x13, 0x09, 0x91, 0x17, 0x13, 0x21, 0x1a, 0xa8, 0xb4, - 0xc4, 0x9d, 0x3f, 0x17, 0xa6, 0xab, 0x60, 0x5e, 0x08, 0x8f, 0xb0, 0x53, 0x48, 0xb1, 0x68, 0x7b, - 0x76, 0xd2, 0xdd, 0x28, 0x8b, 0x87, 0x37, 0xc1, 0xac, 0xcb, 0xb5, 0x55, 0x48, 0x10, 0xe8, 0x93, - 0x6f, 0x09, 0x82, 0x59, 0x94, 0xec, 0x44, 0x69, 0x2c, 0xd3, 0x26, 0xb1, 0xe4, 0x08, 0x09, 0x2a, - 0x69, 0x6d, 0xb2, 0x9a, 0x05, 0xa0, 0xbc, 0x0d, 0xdc, 0x00, 0x0b, 0xbe, 0x95, 0xa7, 0x0a, 0x62, - 0xed, 0x82, 0xa0, 0x5a, 0xd8, 0xc9, 0x43, 0x90, 0xcc, 0x0e, 0xfe, 0x34, 0x25, 0x57, 0x26, 0xf9, - 0x29, 0xf2, 0xdc, 0xd1, 0xe9, 0x30, 0xb6, 0x5e, 0x91, 0xe8, 0xa8, 0xda, 0xb8, 0x3a, 0xaa, 0xf5, - 0xa1, 0x02, 0x60, 0x3e, 0x05, 0x47, 0x5e, 0xee, 0x73, 0x16, 0x89, 0x12, 0xd9, 0x93, 0x2b, 0x9c, - 0x2b, 0xa3, 0x15, 0x4e, 0x7c, 0x82, 0x8e, 0x27, 0x71, 0xc4, 0xf2, 0x9e, 0xce, 0xc3, 0xcc, 0x18, - 0x12, 0x27, 0xf6, 0xe7, 0xf1, 0x24, 0x4e, 0x82, 0xe7, 0x68, 0x89, 0xf3, 0xaf, 0x12, 0x58, 0x88, - 0xc1, 0x63, 0x4b, 0x1c, 0x89, 0xc9, 0xd3, 0xc7, 0x99, 0xf1, 0x64, 0x47, 0xbc, 0x74, 0x5f, 0x11, - 0xd9, 0x11, 0x3b, 0x54, 0x20, 0x3b, 0x7e, 0x5f, 0x4a, 0x7a, 0x7d, 0x4c, 0xd9, 0xf1, 0x05, 0x3c, - 0x55, 0x7c, 0xed, 0x94, 0x4b, 0xeb, 0x93, 0x32, 0x38, 0x9b, 0x4d, 0xc1, 0x54, 0x1d, 0x54, 0x46, - 0xd6, 0xc1, 0x2d, 0xb0, 0x78, 0xcf, 0x37, 0x8c, 0x43, 0x3e, 0x87, 0x44, 0x31, 0x0c, 0x2a, 0xe8, - 0xb7, 0x85, 0xe5, 0xe2, 0x0f, 0x25, 0x18, 0x24, 0xb5, 0xcc, 0x97, 0xc5, 0xca, 0xe3, 0x96, 0xc5, - 0xea, 0x09, 0xca, 0xa2, 0x5c, 0x59, 0x94, 0x4f, 0xa4, 0x2c, 0xc6, 0xae, 0x89, 0x92, 0xe3, 0x6a, - 0xe4, 0x1d, 0x7e, 0xa8, 0x80, 0x25, 0xf9, 0xf5, 0x19, 0x1a, 0x60, 0xce, 0xc4, 0xf7, 0x93, 0x8f, - 0x17, 0xa3, 0x0a, 0x86, 0x4f, 0x75, 0xa3, 0x1d, 0x7c, 0xdd, 0x69, 0xbf, 0x6d, 0xd1, 0x5b, 0xee, - 0x36, 0x75, 0x75, 0xab, 0x1f, 0x14, 0xd8, 0x8d, 0x14, 0x17, 0xca, 0x70, 0xc3, 0xbb, 0xa0, 0x66, - 0xe2, 0xfb, 0xdb, 0xbe, 0xdb, 0x0f, 0x0b, 0xe1, 0xf1, 0xc7, 0xe1, 0xb1, 0xbf, 0x21, 0x58, 0x50, - 0xc4, 0xd7, 0xfa, 0x5c, 0x01, 0xcb, 0x05, 0x15, 0xf4, 0x1b, 0x34, 0xcb, 0x8f, 0x14, 0x70, 0x31, - 0x35, 0x4b, 0x96, 0x91, 0xe4, 0x9e, 0x6f, 0xf0, 0xe4, 0x14, 0x82, 0xe5, 0x0a, 0x98, 0x76, 0xb0, - 0x4b, 0xf5, 0x48, 0xe9, 0x56, 0xd5, 0xd9, 0xe1, 0xa0, 0x39, 0xbd, 0x15, 0x36, 0xa2, 0xb8, 0x5f, - 0xb2, 0x36, 0xa5, 0x27, 0xb7, 0x36, 0xad, 0xdf, 0x94, 0xc0, 0x4c, 0xc2, 0xe5, 0x53, 0x90, 0x2a, - 0x6f, 0xa6, 0xa4, 0x8a, 0xf4, 0xe3, 0x4f, 0x72, 0x0d, 0x8b, 0xb4, 0xca, 0x46, 0x46, 0xab, 0x7c, - 0x6f, 0x14, 0xd1, 0xd1, 0x62, 0xe5, 0xdf, 0x25, 0xb0, 0x98, 0x40, 0xc7, 0x6a, 0xe5, 0x07, 0x29, - 0xb5, 0xb2, 0x92, 0x51, 0x2b, 0x75, 0x99, 0xcd, 0x53, 0xb9, 0x32, 0x5a, 0xae, 0xfc, 0x49, 0x01, - 0xf3, 0x89, 0xb5, 0x3b, 0x05, 0xbd, 0xb2, 0x96, 0xd6, 0x2b, 0xcd, 0x11, 0xf1, 0x52, 0x20, 0x58, - 0xfe, 0xa3, 0x80, 0x4e, 0x02, 0xb5, 0x45, 0x5c, 0x4f, 0xf7, 0x28, 0xb1, 0xe8, 0x1d, 0xdb, 0xf0, - 0x4d, 0xd2, 0x35, 0xb0, 0x6e, 0x22, 0xc2, 0x1a, 0x74, 0xdb, 0xda, 0xb2, 0x0d, 0x5d, 0x3b, 0x84, - 0x18, 0xcc, 0x7c, 0xb0, 0x47, 0xac, 0x35, 0x62, 0x10, 0x2a, 0x3e, 0x51, 0x4c, 0xab, 0x6f, 0x84, - 0x2f, 0xf6, 0xef, 0xc6, 0x5d, 0x8f, 0x06, 0xcd, 0x95, 0x71, 0x18, 0x79, 0x80, 0x25, 0x39, 0xe1, - 0xcf, 0x01, 0x60, 0x3f, 0xb7, 0x35, 0x1c, 0x7e, 0xb0, 0x98, 0x56, 0x5f, 0x0f, 0xd3, 0xf0, 0xdd, - 0xa8, 0xe7, 0x58, 0x03, 0x24, 0x18, 0x5b, 0x7f, 0x9d, 0x4a, 0x6d, 0xd7, 0x37, 0xfe, 0x7d, 0xe8, - 0x97, 0x60, 0xf1, 0x20, 0x5e, 0x9d, 0x10, 0xc0, 0x74, 0x0d, 0x8b, 0x9d, 0xe7, 0xa5, 0xf4, 0xb2, - 0x75, 0x8d, 0xd5, 0xd4, 0x1d, 0x09, 0x1d, 0x92, 0x0e, 0x02, 0x5f, 0x06, 0x33, 0x4c, 0x8f, 0xe8, - 0x1a, 0xd9, 0xc4, 0x66, 0x98, 0x4a, 0xd1, 0x17, 0x9e, 0xed, 0xb8, 0x0b, 0x25, 0x71, 0x70, 0x0f, - 0x2c, 0x38, 0x76, 0x6f, 0x03, 0x5b, 0xb8, 0x4f, 0x58, 0x95, 0x0d, 0xb6, 0x92, 0xbf, 0x1c, 0x4d, - 0xab, 0xaf, 0x84, 0xaf, 0x02, 0x5b, 0x79, 0x08, 0xbb, 0x75, 0x49, 0x9a, 0x79, 0x10, 0xc8, 0x28, - 0xa1, 0x99, 0xfb, 0x20, 0x39, 0x95, 0xfb, 0x2f, 0x0e, 0x59, 0x4e, 0x9d, 0xf0, 0x93, 0x64, 0xd1, - 0x9b, 0x58, 0xed, 0x44, 0x6f, 0x62, 0x92, 0x5b, 0xc3, 0xf4, 0x31, 0x6f, 0x0d, 0x9f, 0x28, 0xe0, - 0x92, 0x33, 0x46, 0x1a, 0xd5, 0x01, 0x5f, 0x96, 0xee, 0x88, 0x65, 0x19, 0x27, 0x23, 0xd5, 0x95, - 0xe1, 0xa0, 0x79, 0x69, 0x1c, 0x24, 0x1a, 0xcb, 0xb5, 0xd6, 0x87, 0x55, 0x70, 0x2e, 0x57, 0x1e, - 0xbf, 0xc4, 0xc7, 0xb9, 0xdc, 0x15, 0xa2, 0x7c, 0x8c, 0x2b, 0xc4, 0x2a, 0x98, 0x17, 0x5f, 0x74, - 0x33, 0x37, 0x90, 0x68, 0x4f, 0xbb, 0xe9, 0x6e, 0x94, 0xc5, 0xcb, 0x1e, 0x07, 0xab, 0xc7, 0x7c, - 0x1c, 0x4c, 0x7a, 0x21, 0xfe, 0x11, 0x29, 0x48, 0xbe, 0xbc, 0x17, 0xe2, 0xff, 0x91, 0xb2, 0x78, - 0xf8, 0x7a, 0x98, 0x59, 0x11, 0xc3, 0x14, 0x67, 0xc8, 0xa4, 0x4a, 0x44, 0x90, 0x41, 0x3f, 0xd6, - 0x57, 0xcb, 0xf7, 0x24, 0x5f, 0x2d, 0x57, 0x46, 0x84, 0xee, 0xf8, 0xef, 0x80, 0xd2, 0x5b, 0xde, - 0xcc, 0xf1, 0x6f, 0x79, 0xad, 0xbf, 0x28, 0xe0, 0x99, 0xc2, 0x33, 0x05, 0xae, 0xa6, 0xe4, 0xda, - 0xd5, 0x8c, 0x5c, 0x7b, 0xb6, 0xd0, 0x30, 0xa1, 0xd9, 0x4c, 0xf9, 0x13, 0xe1, 0x8d, 0x91, 0x4f, - 0x84, 0x12, 0xe9, 0x3f, 0xfa, 0xad, 0x50, 0x7d, 0xf5, 0xc1, 0xc3, 0xc6, 0xc4, 0xa7, 0x0f, 0x1b, - 0x13, 0x9f, 0x3d, 0x6c, 0x4c, 0xfc, 0x6a, 0xd8, 0x50, 0x1e, 0x0c, 0x1b, 0xca, 0xa7, 0xc3, 0x86, - 0xf2, 0xd9, 0xb0, 0xa1, 0xfc, 0x63, 0xd8, 0x50, 0x7e, 0xf7, 0x79, 0x63, 0xe2, 0x2e, 0xcc, 0xff, - 0x1b, 0xe4, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x92, 0xcf, 0x5d, 0xcc, 0x34, 0x29, 0x00, 0x00, + // 2211 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0xf2, 0x43, 0xa2, 0x86, 0x96, 0x64, 0x8f, 0x54, 0x89, 0xb1, 0x1b, 0xd2, 0xdd, 0xb8, + 0xb6, 0x12, 0xc7, 0x64, 0xed, 0x38, 0x41, 0x60, 0x17, 0x09, 0x44, 0x2a, 0x4d, 0xd3, 0xe8, 0xab, + 0x43, 0xcb, 0x01, 0xdc, 0xb4, 0xe8, 0x88, 0x1c, 0x53, 0x1b, 0xed, 0x17, 0x76, 0x87, 0x8a, 0x89, + 0x5e, 0x8a, 0x02, 0xbd, 0xf5, 0xd0, 0xbf, 0xa1, 0xff, 0x40, 0x51, 0x14, 0xcd, 0x2d, 0x08, 0x82, + 0x5e, 0x7c, 0x29, 0x10, 0xf4, 0xd2, 0x9c, 0x88, 0x9a, 0x39, 0x15, 0x45, 0x6f, 0xed, 0xc5, 0x97, + 0x16, 0x33, 0x3b, 0xfb, 0x3d, 0x2b, 0x52, 0x72, 0xac, 0x34, 0x81, 0x6f, 0xdc, 0x99, 0xdf, 0xfb, + 0xed, 0x9b, 0x99, 0xf7, 0xe6, 0xfd, 0x66, 0x96, 0xe0, 0xf6, 0xc1, 0xeb, 0x6e, 0x5d, 0xb3, 0x1a, + 0x07, 0xfd, 0x3d, 0xe2, 0x98, 0x84, 0x12, 0xb7, 0x71, 0x48, 0xcc, 0xae, 0xe5, 0x34, 0x44, 0x07, + 0xb6, 0xb5, 0x06, 0xb6, 0x6d, 0xb7, 0x71, 0x78, 0xbd, 0xd1, 0x23, 0x26, 0x71, 0x30, 0x25, 0xdd, + 0xba, 0xed, 0x58, 0xd4, 0x82, 0xd0, 0xc3, 0xd4, 0xb1, 0xad, 0xd5, 0x19, 0xa6, 0x7e, 0x78, 0xfd, + 0xfc, 0xb5, 0x9e, 0x46, 0xf7, 0xfb, 0x7b, 0xf5, 0x8e, 0x65, 0x34, 0x7a, 0x56, 0xcf, 0x6a, 0x70, + 0xe8, 0x5e, 0xff, 0x3e, 0x7f, 0xe2, 0x0f, 0xfc, 0x97, 0x47, 0x71, 0x5e, 0x8d, 0xbc, 0xa6, 0x63, + 0x39, 0x44, 0xf2, 0x9a, 0xf3, 0x37, 0x43, 0x8c, 0x81, 0x3b, 0xfb, 0x9a, 0x49, 0x9c, 0x41, 0xc3, + 0x3e, 0xe8, 0xb1, 0x06, 0xb7, 0x61, 0x10, 0x8a, 0x65, 0x56, 0x8d, 0x2c, 0x2b, 0xa7, 0x6f, 0x52, + 0xcd, 0x20, 0x29, 0x83, 0xd7, 0xc6, 0x19, 0xb8, 0x9d, 0x7d, 0x62, 0xe0, 0x94, 0xdd, 0x2b, 0x59, + 0x76, 0x7d, 0xaa, 0xe9, 0x0d, 0xcd, 0xa4, 0x2e, 0x75, 0x92, 0x46, 0xea, 0x7f, 0x14, 0x00, 0x5b, + 0x96, 0x49, 0x1d, 0x4b, 0xd7, 0x89, 0x83, 0xc8, 0xa1, 0xe6, 0x6a, 0x96, 0x09, 0x7f, 0x0e, 0x4a, + 0x6c, 0x3c, 0x5d, 0x4c, 0x71, 0x45, 0xb9, 0xa8, 0xac, 0x96, 0x6f, 0x7c, 0xaf, 0x1e, 0x4e, 0x72, + 0x40, 0x5f, 0xb7, 0x0f, 0x7a, 0xac, 0xc1, 0xad, 0x33, 0x74, 0xfd, 0xf0, 0x7a, 0x7d, 0x7b, 0xef, + 0x03, 0xd2, 0xa1, 0x9b, 0x84, 0xe2, 0x26, 0x7c, 0x38, 0xac, 0x4d, 0x8d, 0x86, 0x35, 0x10, 0xb6, + 0xa1, 0x80, 0x15, 0x6e, 0x83, 0x02, 0x67, 0xcf, 0x71, 0xf6, 0x6b, 0x99, 0xec, 0x62, 0xd0, 0x75, + 0x84, 0x3f, 0x7c, 0xeb, 0x01, 0x25, 0x26, 0x73, 0xaf, 0x79, 0x46, 0x50, 0x17, 0xd6, 0x31, 0xc5, + 0x88, 0x13, 0xc1, 0x97, 0x41, 0xc9, 0x11, 0xee, 0x57, 0xf2, 0x17, 0x95, 0xd5, 0x7c, 0xf3, 0xac, + 0x40, 0x95, 0xfc, 0x61, 0xa1, 0x00, 0xa1, 0xfe, 0x59, 0x01, 0xcb, 0xe9, 0x71, 0x6f, 0x68, 0x2e, + 0x85, 0xef, 0xa7, 0xc6, 0x5e, 0x9f, 0x6c, 0xec, 0xcc, 0x9a, 0x8f, 0x3c, 0x78, 0xb1, 0xdf, 0x12, + 0x19, 0xf7, 0xbb, 0xa0, 0xa8, 0x51, 0x62, 0xb8, 0x95, 0xdc, 0xc5, 0xfc, 0x6a, 0xf9, 0xc6, 0xe5, + 0x7a, 0x3a, 0x76, 0xeb, 0x69, 0xc7, 0x9a, 0x73, 0x82, 0xb2, 0xf8, 0x0e, 0x33, 0x46, 0x1e, 0x87, + 0xfa, 0x5f, 0x05, 0xcc, 0xae, 0x63, 0x62, 0x58, 0x66, 0x9b, 0xd0, 0x53, 0x58, 0xb4, 0x16, 0x28, + 0xb8, 0x36, 0xe9, 0x88, 0x45, 0xfb, 0x8e, 0xcc, 0xf7, 0xc0, 0x9d, 0xb6, 0x4d, 0x3a, 0xe1, 0x42, + 0xb1, 0x27, 0xc4, 0x8d, 0xe1, 0xbb, 0x60, 0xda, 0xa5, 0x98, 0xf6, 0x5d, 0xbe, 0x4c, 0xe5, 0x1b, + 0x2f, 0x1c, 0x4d, 0xc3, 0xa1, 0xcd, 0x79, 0x41, 0x34, 0xed, 0x3d, 0x23, 0x41, 0xa1, 0xfe, 0x23, + 0x07, 0x60, 0x80, 0x6d, 0x59, 0x66, 0x57, 0xa3, 0x2c, 0x7e, 0x6f, 0x81, 0x02, 0x1d, 0xd8, 0x84, + 0x4f, 0xc3, 0x6c, 0xf3, 0xb2, 0xef, 0xc5, 0x9d, 0x81, 0x4d, 0x1e, 0x0f, 0x6b, 0xcb, 0x69, 0x0b, + 0xd6, 0x83, 0xb8, 0x0d, 0xdc, 0x08, 0xfc, 0xcb, 0x71, 0xeb, 0x9b, 0xf1, 0x57, 0x3f, 0x1e, 0xd6, + 0x24, 0x9b, 0x45, 0x3d, 0x60, 0x8a, 0x3b, 0x08, 0x0f, 0x01, 0xd4, 0xb1, 0x4b, 0xef, 0x38, 0xd8, + 0x74, 0xbd, 0x37, 0x69, 0x06, 0x11, 0x23, 0x7f, 0x69, 0xb2, 0xe5, 0x61, 0x16, 0xcd, 0xf3, 0xc2, + 0x0b, 0xb8, 0x91, 0x62, 0x43, 0x92, 0x37, 0xc0, 0xcb, 0x60, 0xda, 0x21, 0xd8, 0xb5, 0xcc, 0x4a, + 0x81, 0x8f, 0x22, 0x98, 0x40, 0xc4, 0x5b, 0x91, 0xe8, 0x85, 0x2f, 0x82, 0x19, 0x83, 0xb8, 0x2e, + 0xee, 0x91, 0x4a, 0x91, 0x03, 0x17, 0x04, 0x70, 0x66, 0xd3, 0x6b, 0x46, 0x7e, 0xbf, 0xfa, 0x07, + 0x05, 0xcc, 0x05, 0x33, 0x77, 0x0a, 0xa9, 0xd2, 0x8c, 0xa7, 0xca, 0xf3, 0x47, 0xc6, 0x49, 0x46, + 0x86, 0x7c, 0x92, 0x8f, 0xf8, 0xcc, 0x82, 0x10, 0xfe, 0x14, 0x94, 0x5c, 0xa2, 0x93, 0x0e, 0xb5, + 0x1c, 0xe1, 0xf3, 0x2b, 0x13, 0xfa, 0x8c, 0xf7, 0x88, 0xde, 0x16, 0xa6, 0xcd, 0x33, 0xcc, 0x69, + 0xff, 0x09, 0x05, 0x94, 0xf0, 0xc7, 0xa0, 0x44, 0x89, 0x61, 0xeb, 0x98, 0x12, 0x91, 0x26, 0xb1, + 0xf8, 0x66, 0xe1, 0xc2, 0xc8, 0x76, 0xac, 0xee, 0x1d, 0x01, 0xe3, 0x89, 0x12, 0xcc, 0x83, 0xdf, + 0x8a, 0x02, 0x1a, 0x78, 0x00, 0xe6, 0xfb, 0x76, 0x97, 0x21, 0x29, 0xdb, 0xba, 0x7b, 0x03, 0x11, + 0x3e, 0x57, 0x8f, 0x9c, 0x90, 0xdd, 0x98, 0x49, 0x73, 0x59, 0xbc, 0x60, 0x3e, 0xde, 0x8e, 0x12, + 0xd4, 0x70, 0x0d, 0x2c, 0x18, 0x9a, 0x89, 0x08, 0xee, 0x0e, 0xda, 0xa4, 0x63, 0x99, 0x5d, 0x97, + 0x07, 0x50, 0xb1, 0xb9, 0x22, 0x08, 0x16, 0x36, 0xe3, 0xdd, 0x28, 0x89, 0x87, 0x1b, 0x60, 0xc9, + 0xdf, 0x67, 0x7f, 0xa8, 0xb9, 0xd4, 0x72, 0x06, 0x1b, 0x9a, 0xa1, 0xd1, 0xca, 0x34, 0xe7, 0xa9, + 0x8c, 0x86, 0xb5, 0x25, 0x24, 0xe9, 0x47, 0x52, 0x2b, 0xf5, 0x37, 0xd3, 0x60, 0x21, 0xb1, 0x1b, + 0xc0, 0xbb, 0x60, 0xb9, 0xd3, 0x77, 0x1c, 0x62, 0xd2, 0xad, 0xbe, 0xb1, 0x47, 0x9c, 0x76, 0x67, + 0x9f, 0x74, 0xfb, 0x3a, 0xe9, 0xf2, 0x15, 0x2d, 0x36, 0xab, 0xc2, 0xd7, 0xe5, 0x96, 0x14, 0x85, + 0x32, 0xac, 0xe1, 0x8f, 0x00, 0x34, 0x79, 0xd3, 0xa6, 0xe6, 0xba, 0x01, 0x67, 0x8e, 0x73, 0x06, + 0x09, 0xb8, 0x95, 0x42, 0x20, 0x89, 0x15, 0xf3, 0xb1, 0x4b, 0x5c, 0xcd, 0x21, 0xdd, 0xa4, 0x8f, + 0xf9, 0xb8, 0x8f, 0xeb, 0x52, 0x14, 0xca, 0xb0, 0x86, 0xaf, 0x82, 0xb2, 0xf7, 0x36, 0x3e, 0xe7, + 0x62, 0x71, 0x16, 0x05, 0x59, 0x79, 0x2b, 0xec, 0x42, 0x51, 0x1c, 0x1b, 0x9a, 0xb5, 0xe7, 0x12, + 0xe7, 0x90, 0x74, 0xdf, 0xf6, 0x34, 0x00, 0x2b, 0x94, 0x45, 0x5e, 0x28, 0x83, 0xa1, 0x6d, 0xa7, + 0x10, 0x48, 0x62, 0xc5, 0x86, 0xe6, 0x45, 0x4d, 0x6a, 0x68, 0xd3, 0xf1, 0xa1, 0xed, 0x4a, 0x51, + 0x28, 0xc3, 0x9a, 0xc5, 0x9e, 0xe7, 0xf2, 0xda, 0x21, 0xd6, 0x74, 0xbc, 0xa7, 0x93, 0xca, 0x4c, + 0x3c, 0xf6, 0xb6, 0xe2, 0xdd, 0x28, 0x89, 0x87, 0x6f, 0x83, 0x73, 0x5e, 0xd3, 0xae, 0x89, 0x03, + 0x92, 0x12, 0x27, 0x79, 0x4e, 0x90, 0x9c, 0xdb, 0x4a, 0x02, 0x50, 0xda, 0x06, 0xde, 0x02, 0xf3, + 0x1d, 0x4b, 0xd7, 0x79, 0x3c, 0xb6, 0xac, 0xbe, 0x49, 0x2b, 0xb3, 0x9c, 0x05, 0xb2, 0x1c, 0x6a, + 0xc5, 0x7a, 0x50, 0x02, 0x09, 0xef, 0x01, 0xd0, 0xf1, 0xcb, 0x81, 0x5b, 0x01, 0xd9, 0x85, 0x3e, + 0x5d, 0x87, 0xc2, 0x02, 0x1c, 0x34, 0xb9, 0x28, 0xc2, 0xa6, 0x7e, 0xa2, 0x80, 0x95, 0x8c, 0x1c, + 0x87, 0x6f, 0xc6, 0xaa, 0xde, 0xd5, 0x44, 0xd5, 0xbb, 0x90, 0x61, 0x16, 0x29, 0x7d, 0x1d, 0x30, + 0xc7, 0x74, 0x87, 0x66, 0xf6, 0x3c, 0x88, 0xd8, 0xc1, 0x5e, 0x92, 0xf9, 0x8e, 0xa2, 0xc0, 0x70, + 0x1b, 0x3e, 0x37, 0x1a, 0xd6, 0xe6, 0x62, 0x7d, 0x28, 0xce, 0xa9, 0xfe, 0x2a, 0x07, 0xc0, 0x3a, + 0xb1, 0x75, 0x6b, 0x60, 0x10, 0xf3, 0x34, 0x54, 0xcb, 0x7a, 0x4c, 0xb5, 0xa8, 0xd2, 0x85, 0x08, + 0xfc, 0xc9, 0x94, 0x2d, 0x1b, 0x09, 0xd9, 0x72, 0x69, 0x0c, 0xcf, 0xd1, 0xba, 0xe5, 0x6f, 0x79, + 0xb0, 0x18, 0x82, 0x43, 0xe1, 0x72, 0x3b, 0xb6, 0x84, 0x57, 0x12, 0x4b, 0xb8, 0x22, 0x31, 0x79, + 0x6a, 0xca, 0xe5, 0x03, 0x30, 0xcf, 0x74, 0x85, 0xb7, 0x6a, 0x5c, 0xb5, 0x4c, 0x1f, 0x5b, 0xb5, + 0x04, 0x55, 0x67, 0x23, 0xc6, 0x84, 0x12, 0xcc, 0x19, 0x2a, 0x69, 0xe6, 0xeb, 0xa8, 0x92, 0xfe, + 0xa8, 0x80, 0xf9, 0x70, 0x99, 0x4e, 0x41, 0x26, 0xb5, 0xe2, 0x32, 0xa9, 0x7a, 0x74, 0x5c, 0x66, + 0xe8, 0xa4, 0xbf, 0x16, 0xa2, 0x5e, 0x73, 0xa1, 0xb4, 0xca, 0x0e, 0x54, 0xb6, 0xae, 0x75, 0xb0, + 0x2b, 0xca, 0xea, 0x19, 0xef, 0x30, 0xe5, 0xb5, 0xa1, 0xa0, 0x37, 0x26, 0xa9, 0x72, 0x4f, 0x57, + 0x52, 0xe5, 0xbf, 0x1c, 0x49, 0x75, 0x07, 0x94, 0x5c, 0x5f, 0x4c, 0x15, 0x38, 0xe5, 0xe5, 0x71, + 0xe9, 0x2c, 0x74, 0x54, 0xc0, 0x1a, 0x28, 0xa8, 0x80, 0x49, 0xa6, 0x9d, 0x8a, 0x5f, 0xa5, 0x76, + 0x62, 0xe1, 0x6d, 0xe3, 0xbe, 0x4b, 0xba, 0x3c, 0x95, 0x4a, 0x61, 0x78, 0xef, 0xf0, 0x56, 0x24, + 0x7a, 0xe1, 0x2e, 0x58, 0xb1, 0x1d, 0xab, 0xe7, 0x10, 0xd7, 0x5d, 0x27, 0xb8, 0xab, 0x6b, 0x26, + 0xf1, 0x07, 0xe0, 0x55, 0xbd, 0x0b, 0xa3, 0x61, 0x6d, 0x65, 0x47, 0x0e, 0x41, 0x59, 0xb6, 0xea, + 0xc7, 0x05, 0x70, 0x36, 0xb9, 0x23, 0x66, 0x08, 0x11, 0xe5, 0x44, 0x42, 0xe4, 0xe5, 0x48, 0x88, + 0x7a, 0x2a, 0x2d, 0x72, 0xe6, 0x4f, 0x85, 0xe9, 0x1a, 0x58, 0x10, 0xc2, 0xc3, 0xef, 0x14, 0x52, + 0x2c, 0x58, 0x9e, 0xdd, 0x78, 0x37, 0x4a, 0xe2, 0xe1, 0x6d, 0x30, 0xe7, 0x70, 0x6d, 0xe5, 0x13, + 0x78, 0xfa, 0xe4, 0x5b, 0x82, 0x60, 0x0e, 0x45, 0x3b, 0x51, 0x1c, 0xcb, 0xb4, 0x49, 0x28, 0x39, + 0x7c, 0x82, 0x42, 0x5c, 0x9b, 0xac, 0x25, 0x01, 0x28, 0x6d, 0x03, 0x37, 0xc1, 0x62, 0xdf, 0x4c, + 0x53, 0x79, 0xb1, 0x76, 0x41, 0x50, 0x2d, 0xee, 0xa6, 0x21, 0x48, 0x66, 0x07, 0x7f, 0x12, 0x93, + 0x2b, 0xd3, 0x7c, 0x17, 0xb9, 0x72, 0x74, 0x3a, 0x4c, 0xac, 0x57, 0x24, 0x3a, 0xaa, 0x34, 0xa9, + 0x8e, 0x52, 0x3f, 0x52, 0x00, 0x4c, 0xa7, 0xe0, 0xd8, 0xc3, 0x7d, 0xca, 0x22, 0x52, 0x22, 0xbb, + 0x72, 0x85, 0x73, 0x75, 0xbc, 0xc2, 0x09, 0x77, 0xd0, 0xc9, 0x24, 0x8e, 0x98, 0xde, 0xd3, 0xb9, + 0x98, 0x99, 0x40, 0xe2, 0x84, 0xfe, 0x3c, 0x99, 0xc4, 0x89, 0xf0, 0x1c, 0x2d, 0x71, 0xfe, 0x99, + 0x03, 0x8b, 0x21, 0x78, 0x62, 0x89, 0x23, 0x31, 0x79, 0x76, 0x39, 0x33, 0x99, 0xec, 0x08, 0xa7, + 0xee, 0xff, 0x44, 0x76, 0x84, 0x0e, 0x65, 0xc8, 0x8e, 0xdf, 0xe7, 0xa2, 0x5e, 0x1f, 0x53, 0x76, + 0x7c, 0x09, 0x57, 0x15, 0x5f, 0x3b, 0xe5, 0xa2, 0x7e, 0x9a, 0x07, 0x67, 0x93, 0x29, 0x18, 0xab, + 0x83, 0xca, 0xd8, 0x3a, 0xb8, 0x03, 0x96, 0xee, 0xf7, 0x75, 0x7d, 0xc0, 0xc7, 0x10, 0x29, 0x86, + 0x5e, 0x05, 0xfd, 0xb6, 0xb0, 0x5c, 0xfa, 0x81, 0x04, 0x83, 0xa4, 0x96, 0xe9, 0xb2, 0x58, 0x78, + 0xd2, 0xb2, 0x58, 0x3c, 0x41, 0x59, 0x94, 0x2b, 0x8b, 0xfc, 0x89, 0x94, 0xc5, 0xc4, 0x35, 0x51, + 0xb2, 0x5d, 0x8d, 0x3d, 0xc3, 0x8f, 0x14, 0xb0, 0x2c, 0x3f, 0x3e, 0x43, 0x1d, 0xcc, 0x1b, 0xf8, + 0x41, 0xf4, 0xf2, 0x62, 0x5c, 0xc1, 0xe8, 0x53, 0x4d, 0xaf, 0x7b, 0x5f, 0x77, 0xea, 0xef, 0x98, + 0x74, 0xdb, 0x69, 0x53, 0x47, 0x33, 0x7b, 0x5e, 0x81, 0xdd, 0x8c, 0x71, 0xa1, 0x04, 0x37, 0xbc, + 0x07, 0x4a, 0x06, 0x7e, 0xd0, 0xee, 0x3b, 0x3d, 0xbf, 0x10, 0x1e, 0xff, 0x3d, 0x3c, 0xf6, 0x37, + 0x05, 0x0b, 0x0a, 0xf8, 0xd4, 0x2f, 0x14, 0xb0, 0x92, 0x51, 0x41, 0xbf, 0x41, 0xa3, 0xfc, 0x58, + 0x01, 0x17, 0x63, 0xa3, 0x64, 0x19, 0x49, 0xee, 0xf7, 0x75, 0x9e, 0x9c, 0x42, 0xb0, 0x5c, 0x05, + 0xb3, 0x36, 0x76, 0xa8, 0x16, 0x28, 0xdd, 0x62, 0x73, 0x6e, 0x34, 0xac, 0xcd, 0xee, 0xf8, 0x8d, + 0x28, 0xec, 0x97, 0xcc, 0x4d, 0xee, 0xe9, 0xcd, 0x8d, 0xfa, 0xeb, 0x1c, 0x28, 0x47, 0x5c, 0x3e, + 0x05, 0xa9, 0xf2, 0x56, 0x4c, 0xaa, 0x48, 0x3f, 0xfe, 0x44, 0xe7, 0x30, 0x4b, 0xab, 0x6c, 0x26, + 0xb4, 0xca, 0x77, 0xc7, 0x11, 0x1d, 0x2d, 0x56, 0xfe, 0x95, 0x03, 0x4b, 0x11, 0x74, 0xa8, 0x56, + 0xbe, 0x1f, 0x53, 0x2b, 0xab, 0x09, 0xb5, 0x52, 0x91, 0xd9, 0x3c, 0x93, 0x2b, 0xe3, 0xe5, 0xca, + 0x9f, 0x14, 0xb0, 0x10, 0x99, 0xbb, 0x53, 0xd0, 0x2b, 0xeb, 0x71, 0xbd, 0x52, 0x1b, 0x13, 0x2f, + 0x19, 0x82, 0xe5, 0x16, 0x58, 0x8c, 0x80, 0xb6, 0x9d, 0xae, 0x66, 0x62, 0xdd, 0x85, 0x2f, 0x80, + 0xa2, 0x4b, 0xb1, 0x43, 0xfd, 0xec, 0xf6, 0x6d, 0xdb, 0xac, 0x11, 0x79, 0x7d, 0xea, 0xbf, 0x15, + 0xd0, 0x88, 0x18, 0xef, 0x10, 0xc7, 0xd5, 0x5c, 0x4a, 0x4c, 0x7a, 0xd7, 0xd2, 0xfb, 0x06, 0x69, + 0xe9, 0x58, 0x33, 0x10, 0x61, 0x0d, 0x9a, 0x65, 0xee, 0x58, 0xba, 0xd6, 0x19, 0x40, 0x0c, 0xca, + 0x1f, 0xee, 0x13, 0x73, 0x9d, 0xe8, 0x84, 0x8a, 0xcf, 0x1b, 0xb3, 0xcd, 0x37, 0xfd, 0xdb, 0xfe, + 0xf7, 0xc2, 0xae, 0xc7, 0xc3, 0xda, 0xea, 0x24, 0x8c, 0x3c, 0x38, 0xa3, 0x9c, 0xf0, 0x67, 0x00, + 0xb0, 0xc7, 0x76, 0x07, 0xfb, 0x1f, 0x3b, 0x66, 0x9b, 0x6f, 0xf8, 0x29, 0xfc, 0x5e, 0xd0, 0x73, + 0xac, 0x17, 0x44, 0x18, 0xd5, 0xdf, 0x95, 0x62, 0x4b, 0xfd, 0x8d, 0xbf, 0x5b, 0xfa, 0x05, 0x58, + 0x3a, 0x0c, 0x67, 0xc7, 0x07, 0x30, 0x4d, 0xc4, 0xe2, 0xee, 0x45, 0x29, 0xbd, 0x6c, 0x5e, 0x43, + 0x25, 0x76, 0x57, 0x42, 0x87, 0xa4, 0x2f, 0x81, 0xaf, 0x82, 0x32, 0xd3, 0x32, 0x5a, 0x87, 0x6c, + 0x61, 0xc3, 0x4f, 0xc3, 0xe0, 0xeb, 0x50, 0x3b, 0xec, 0x42, 0x51, 0x1c, 0xdc, 0x07, 0x8b, 0xb6, + 0xd5, 0xdd, 0xc4, 0x26, 0xee, 0x11, 0x56, 0xa1, 0xbd, 0xa5, 0xe4, 0xb7, 0x4e, 0xb3, 0xcd, 0xd7, + 0xfc, 0x1b, 0x85, 0x9d, 0x34, 0x84, 0x9d, 0xd8, 0x24, 0xcd, 0x3c, 0x08, 0x64, 0x94, 0xd0, 0x48, + 0x7d, 0xcc, 0x9c, 0x49, 0xfd, 0x03, 0x44, 0x96, 0x8f, 0x27, 0xfc, 0x9c, 0x99, 0x75, 0x9f, 0x56, + 0x3a, 0xd1, 0x7d, 0x9a, 0xe4, 0xc4, 0x31, 0x7b, 0xcc, 0x13, 0xc7, 0xa7, 0x0a, 0xb8, 0x64, 0x4f, + 0x90, 0x46, 0x15, 0xc0, 0xa7, 0xa5, 0x35, 0x66, 0x5a, 0x26, 0xc9, 0xc8, 0xe6, 0xea, 0x68, 0x58, + 0xbb, 0x34, 0x09, 0x12, 0x4d, 0xe4, 0x1a, 0x4b, 0x1a, 0x4b, 0xec, 0x7c, 0x95, 0x32, 0x77, 0xf3, + 0xca, 0x18, 0x37, 0xfd, 0x8d, 0xd2, 0xcb, 0x43, 0xff, 0x09, 0x05, 0x34, 0xea, 0x47, 0x45, 0x70, + 0x2e, 0x55, 0xad, 0xbf, 0xc2, 0xbb, 0xc2, 0xd4, 0x89, 0x26, 0x7f, 0x8c, 0x13, 0xcd, 0x1a, 0x58, + 0x10, 0x1f, 0x98, 0x13, 0x07, 0xa2, 0x20, 0x4c, 0x5a, 0xf1, 0x6e, 0x94, 0xc4, 0xcb, 0xee, 0x2a, + 0x8b, 0xc7, 0xbc, 0xab, 0x8c, 0x7a, 0x21, 0xfe, 0x17, 0xe5, 0xe5, 0x73, 0xda, 0x0b, 0xf1, 0xf7, + 0xa8, 0x24, 0x1e, 0xbe, 0xe1, 0x27, 0x6b, 0xc0, 0x30, 0xc3, 0x19, 0x12, 0xd9, 0x17, 0x10, 0x24, + 0xd0, 0x4f, 0xf4, 0x11, 0xf5, 0x7d, 0xc9, 0x47, 0xd4, 0xd5, 0x31, 0x61, 0x36, 0xf9, 0xb5, 0xa4, + 0xf4, 0xd0, 0x59, 0x3e, 0xfe, 0xa1, 0x53, 0xfd, 0x8b, 0x02, 0x9e, 0xcb, 0xdc, 0xa6, 0xe0, 0x5a, + 0x4c, 0x3d, 0x5e, 0x4b, 0xa8, 0xc7, 0xe7, 0x33, 0x0d, 0x23, 0x12, 0xd2, 0x90, 0xdf, 0x58, 0xde, + 0x1c, 0x7b, 0x63, 0x29, 0x39, 0x89, 0x8c, 0xbf, 0xba, 0x6c, 0xbe, 0xfe, 0xf0, 0x51, 0x75, 0xea, + 0xb3, 0x47, 0xd5, 0xa9, 0xcf, 0x1f, 0x55, 0xa7, 0x7e, 0x39, 0xaa, 0x2a, 0x0f, 0x47, 0x55, 0xe5, + 0xb3, 0x51, 0x55, 0xf9, 0x7c, 0x54, 0x55, 0xfe, 0x3e, 0xaa, 0x2a, 0xbf, 0xfd, 0xa2, 0x3a, 0x75, + 0x0f, 0xa6, 0xff, 0x95, 0xf9, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xae, 0x39, 0x4c, 0x13, 0xc3, + 0x29, 0x00, 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -2341,6 +2374,32 @@ func (m *StatefulSetList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *StatefulSetOrdinals) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StatefulSetOrdinals) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StatefulSetOrdinals) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.Start)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2394,6 +2453,18 @@ func (m *StatefulSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Ordinals != nil { + { + size, err := m.Ordinals.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } if m.PersistentVolumeClaimRetentionPolicy != nil { { size, err := m.PersistentVolumeClaimRetentionPolicy.MarshalToSizedBuffer(dAtA[:i]) @@ -3054,6 +3125,16 @@ func (m *StatefulSetList) Size() (n int) { return n } +func (m *StatefulSetOrdinals) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Start)) + return n +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Size() (n int) { if m == nil { return 0 @@ -3102,6 +3183,10 @@ func (m *StatefulSetSpec) Size() (n int) { l = m.PersistentVolumeClaimRetentionPolicy.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Ordinals != nil { + l = m.Ordinals.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -3516,6 +3601,16 @@ func (this *StatefulSetList) String() string { }, "") return s } +func (this *StatefulSetOrdinals) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StatefulSetOrdinals{`, + `Start:` + fmt.Sprintf("%v", this.Start) + `,`, + `}`, + }, "") + return s +} func (this *StatefulSetPersistentVolumeClaimRetentionPolicy) String() string { if this == nil { return "nil" @@ -3547,6 +3642,7 @@ func (this *StatefulSetSpec) String() string { `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, `MinReadySeconds:` + fmt.Sprintf("%v", this.MinReadySeconds) + `,`, `PersistentVolumeClaimRetentionPolicy:` + strings.Replace(this.PersistentVolumeClaimRetentionPolicy.String(), "StatefulSetPersistentVolumeClaimRetentionPolicy", "StatefulSetPersistentVolumeClaimRetentionPolicy", 1) + `,`, + `Ordinals:` + strings.Replace(this.Ordinals.String(), "StatefulSetOrdinals", "StatefulSetOrdinals", 1) + `,`, `}`, }, "") return s @@ -7626,6 +7722,75 @@ func (m *StatefulSetList) Unmarshal(dAtA []byte) error { } return nil } +func (m *StatefulSetOrdinals) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StatefulSetOrdinals: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StatefulSetOrdinals: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + m.Start = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Start |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8064,6 +8229,42 @@ func (m *StatefulSetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ordinals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ordinals == nil { + m.Ordinals = &StatefulSetOrdinals{} + } + if err := m.Ordinals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/apps/v1/generated.proto b/vendor/k8s.io/api/apps/v1/generated.proto index 1bdc400b9d2..a7a7e7c5471 100644 --- a/vendor/k8s.io/api/apps/v1/generated.proto +++ b/vendor/k8s.io/api/apps/v1/generated.proto @@ -127,6 +127,7 @@ message DaemonSetSpec { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template optional k8s.io.api.core.v1.PodTemplateSpec template = 2; @@ -277,6 +278,7 @@ message DeploymentSpec { optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -449,7 +451,7 @@ message ReplicaSetSpec { // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller optional int32 replicas = 1; @@ -513,7 +515,6 @@ message RollingUpdateDaemonSet { // daemonset on any given node can double if the readiness check fails, and // so resource intensive daemonsets should take into account that they may // cause evictions during disruption. - // This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxSurge = 2; } @@ -570,8 +571,9 @@ message RollingUpdateStatefulSetStrategy { // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. message StatefulSet { @@ -622,6 +624,21 @@ message StatefulSetList { repeated StatefulSet items = 2; } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +message StatefulSetOrdinals { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + optional int32 start = 1; +} + // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. message StatefulSetPersistentVolumeClaimRetentionPolicy { @@ -657,7 +674,10 @@ message StatefulSetSpec { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -702,7 +722,6 @@ message StatefulSetSpec { // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional optional int32 minReadySeconds = 9; @@ -714,6 +733,14 @@ message StatefulSetSpec { // down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, // which is alpha. +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + optional StatefulSetOrdinals ordinals = 11; } // StatefulSetStatus represents the current state of a StatefulSet. @@ -758,7 +785,6 @@ message StatefulSetStatus { repeated StatefulSetCondition conditions = 10; // Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. // +optional optional int32 availableReplicas = 11; } diff --git a/vendor/k8s.io/api/apps/v1/types.go b/vendor/k8s.io/api/apps/v1/types.go index 28474be7f4f..15dc3150a63 100644 --- a/vendor/k8s.io/api/apps/v1/types.go +++ b/vendor/k8s.io/api/apps/v1/types.go @@ -39,8 +39,9 @@ const ( // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. type StatefulSet struct { @@ -162,6 +163,21 @@ type StatefulSetPersistentVolumeClaimRetentionPolicy struct { WhenScaled PersistentVolumeClaimRetentionPolicyType `json:"whenScaled,omitempty" protobuf:"bytes,2,opt,name=whenScaled,casttype=PersistentVolumeClaimRetentionPolicyType"` } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +type StatefulSetOrdinals struct { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + Start int32 `json:"start" protobuf:"varint,1,opt,name=start"` +} + // A StatefulSetSpec is the specification of a StatefulSet. type StatefulSetSpec struct { // replicas is the desired number of replicas of the given Template. @@ -180,7 +196,10 @@ type StatefulSetSpec struct { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -225,7 +244,6 @@ type StatefulSetSpec struct { // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,9,opt,name=minReadySeconds"` @@ -237,6 +255,14 @@ type StatefulSetSpec struct { // down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, // which is alpha. +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } // StatefulSetStatus represents the current state of a StatefulSet. @@ -281,7 +307,6 @@ type StatefulSetStatus struct { Conditions []StatefulSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"` // Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. // +optional AvailableReplicas int32 `json:"availableReplicas" protobuf:"varint,11,opt,name=availableReplicas"` } @@ -355,6 +380,7 @@ type DeploymentSpec struct { Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -598,7 +624,6 @@ type RollingUpdateDaemonSet struct { // daemonset on any given node can double if the readiness check fails, and // so resource intensive daemonsets should take into account that they may // cause evictions during disruption. - // This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate. // +optional MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,2,opt,name=maxSurge"` } @@ -615,6 +640,7 @@ type DaemonSetSpec struct { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,2,opt,name=template"` @@ -833,7 +859,7 @@ type ReplicaSetSpec struct { // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` diff --git a/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go index f00d10aeabc..6676da06403 100644 --- a/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ @@ -85,7 +85,7 @@ func (DaemonSetList) SwaggerDoc() map[string]string { var map_DaemonSetSpec = map[string]string{ "": "DaemonSetSpec is the specification of a daemon set.", "selector": "A label query over pods that are managed by the daemon set. Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", "updateStrategy": "An update strategy to replace existing DaemonSet pods with new pods.", "minReadySeconds": "The minimum number of seconds for which a newly created DaemonSet pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).", "revisionHistoryLimit": "The number of old history to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -162,7 +162,7 @@ var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.", - "template": "Template describes the pods that will be created.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -248,7 +248,7 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", "readyReplicas": "readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition.", "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", @@ -263,7 +263,7 @@ func (ReplicaSetStatus) SwaggerDoc() map[string]string { var map_RollingUpdateDaemonSet = map[string]string{ "": "Spec to control the desired behavior of daemon set rolling update.", "maxUnavailable": "The maximum number of DaemonSet pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of total number of DaemonSet pods at the start of the update (ex: 10%). Absolute number is calculated from percentage by rounding up. This cannot be 0 if MaxSurge is 0 Default value is 1. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their pods stopped for an update at any given time. The update starts by stopping at most 30% of those DaemonSet pods and then brings up new DaemonSet pods in their place. Once the new pods are available, it then proceeds onto other DaemonSet pods, thus ensuring that at least 70% of original number of DaemonSet pods are available at all times during the update.", - "maxSurge": "The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption. This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.", + "maxSurge": "The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption.", } func (RollingUpdateDaemonSet) SwaggerDoc() map[string]string { @@ -291,7 +291,7 @@ func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { } var map_StatefulSet = map[string]string{ - "": "StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", + "": "StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\n\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "spec": "Spec defines the desired identities of pods in this set.", "status": "Status is the current status of Pods in this StatefulSet. This data may be out of date by some window of time.", @@ -324,6 +324,15 @@ func (StatefulSetList) SwaggerDoc() map[string]string { return map_StatefulSetList } +var map_StatefulSetOrdinals = map[string]string{ + "": "StatefulSetOrdinals describes the policy used for replica ordinal assignment in this StatefulSet.", + "start": "start is the number representing the first replica's index. It may be used to number replicas from an alternate index (eg: 1-indexed) over the default 0-indexed names, or to orchestrate progressive movement of replicas from one StatefulSet to another. If set, replica indices will be in the range:\n [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas).\nIf unset, defaults to 0. Replica indices will be in the range:\n [0, .spec.replicas).", +} + +func (StatefulSetOrdinals) SwaggerDoc() map[string]string { + return map_StatefulSetOrdinals +} + var map_StatefulSetPersistentVolumeClaimRetentionPolicy = map[string]string{ "": "StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", "whenDeleted": "WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", @@ -338,14 +347,15 @@ var map_StatefulSetSpec = map[string]string{ "": "A StatefulSetSpec is the specification of a StatefulSet.", "replicas": "replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.", "selector": "selector is a label query over pods that should match the replica count. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.", + "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\". The only allowed template.spec.restartPolicy value is \"Always\".", "volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.", "serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.", "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", - "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.", + "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "persistentVolumeClaimRetentionPolicy": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. +optional", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { @@ -363,7 +373,7 @@ var map_StatefulSetStatus = map[string]string{ "updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)", "collisionCount": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision.", "conditions": "Represents the latest available observations of a statefulset's current state.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset. This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate.", + "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset.", } func (StatefulSetStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go index 72d76670e78..6912986ac37 100644 --- a/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go @@ -693,6 +693,22 @@ func (in *StatefulSetList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatefulSetOrdinals) DeepCopyInto(out *StatefulSetOrdinals) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetOrdinals. +func (in *StatefulSetOrdinals) DeepCopy() *StatefulSetOrdinals { + if in == nil { + return nil + } + out := new(StatefulSetOrdinals) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StatefulSetPersistentVolumeClaimRetentionPolicy) DeepCopyInto(out *StatefulSetPersistentVolumeClaimRetentionPolicy) { *out = *in @@ -741,6 +757,11 @@ func (in *StatefulSetSpec) DeepCopyInto(out *StatefulSetSpec) { *out = new(StatefulSetPersistentVolumeClaimRetentionPolicy) **out = **in } + if in.Ordinals != nil { + in, out := &in.Ordinals, &out.Ordinals + *out = new(StatefulSetOrdinals) + **out = **in + } return } diff --git a/vendor/k8s.io/api/apps/v1beta1/generated.pb.go b/vendor/k8s.io/api/apps/v1beta1/generated.pb.go index 48ac988f452..2f1e7c00a18 100644 --- a/vendor/k8s.io/api/apps/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/apps/v1beta1/generated.pb.go @@ -553,12 +553,40 @@ func (m *StatefulSetList) XXX_DiscardUnknown() { var xxx_messageInfo_StatefulSetList proto.InternalMessageInfo +func (m *StatefulSetOrdinals) Reset() { *m = StatefulSetOrdinals{} } +func (*StatefulSetOrdinals) ProtoMessage() {} +func (*StatefulSetOrdinals) Descriptor() ([]byte, []int) { + return fileDescriptor_2a07313e8f66e805, []int{18} +} +func (m *StatefulSetOrdinals) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StatefulSetOrdinals) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *StatefulSetOrdinals) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatefulSetOrdinals.Merge(m, src) +} +func (m *StatefulSetOrdinals) XXX_Size() int { + return m.Size() +} +func (m *StatefulSetOrdinals) XXX_DiscardUnknown() { + xxx_messageInfo_StatefulSetOrdinals.DiscardUnknown(m) +} + +var xxx_messageInfo_StatefulSetOrdinals proto.InternalMessageInfo + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Reset() { *m = StatefulSetPersistentVolumeClaimRetentionPolicy{} } func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} func (*StatefulSetPersistentVolumeClaimRetentionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_2a07313e8f66e805, []int{18} + return fileDescriptor_2a07313e8f66e805, []int{19} } func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -586,7 +614,7 @@ var xxx_messageInfo_StatefulSetPersistentVolumeClaimRetentionPolicy proto.Intern func (m *StatefulSetSpec) Reset() { *m = StatefulSetSpec{} } func (*StatefulSetSpec) ProtoMessage() {} func (*StatefulSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_2a07313e8f66e805, []int{19} + return fileDescriptor_2a07313e8f66e805, []int{20} } func (m *StatefulSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -614,7 +642,7 @@ var xxx_messageInfo_StatefulSetSpec proto.InternalMessageInfo func (m *StatefulSetStatus) Reset() { *m = StatefulSetStatus{} } func (*StatefulSetStatus) ProtoMessage() {} func (*StatefulSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_2a07313e8f66e805, []int{20} + return fileDescriptor_2a07313e8f66e805, []int{21} } func (m *StatefulSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -642,7 +670,7 @@ var xxx_messageInfo_StatefulSetStatus proto.InternalMessageInfo func (m *StatefulSetUpdateStrategy) Reset() { *m = StatefulSetUpdateStrategy{} } func (*StatefulSetUpdateStrategy) ProtoMessage() {} func (*StatefulSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_2a07313e8f66e805, []int{21} + return fileDescriptor_2a07313e8f66e805, []int{22} } func (m *StatefulSetUpdateStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -688,6 +716,7 @@ func init() { proto.RegisterType((*StatefulSet)(nil), "k8s.io.api.apps.v1beta1.StatefulSet") proto.RegisterType((*StatefulSetCondition)(nil), "k8s.io.api.apps.v1beta1.StatefulSetCondition") proto.RegisterType((*StatefulSetList)(nil), "k8s.io.api.apps.v1beta1.StatefulSetList") + proto.RegisterType((*StatefulSetOrdinals)(nil), "k8s.io.api.apps.v1beta1.StatefulSetOrdinals") proto.RegisterType((*StatefulSetPersistentVolumeClaimRetentionPolicy)(nil), "k8s.io.api.apps.v1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy") proto.RegisterType((*StatefulSetSpec)(nil), "k8s.io.api.apps.v1beta1.StatefulSetSpec") proto.RegisterType((*StatefulSetStatus)(nil), "k8s.io.api.apps.v1beta1.StatefulSetStatus") @@ -699,131 +728,135 @@ func init() { } var fileDescriptor_2a07313e8f66e805 = []byte{ - // 1982 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcf, 0x6f, 0x1b, 0xc7, - 0xf5, 0xd7, 0x52, 0xa2, 0x44, 0x3d, 0x45, 0x94, 0x3d, 0xd2, 0xd7, 0x62, 0x94, 0x6f, 0x49, 0x81, - 0x35, 0x12, 0xe5, 0x87, 0x97, 0xb1, 0x92, 0x06, 0x89, 0xdd, 0xba, 0x15, 0x25, 0x37, 0x76, 0x20, - 0xc5, 0xca, 0x48, 0x8a, 0xd1, 0xf4, 0x07, 0x32, 0x24, 0xc7, 0xd4, 0x46, 0xfb, 0x0b, 0xbb, 0x43, - 0xc6, 0x44, 0x2f, 0xfd, 0x03, 0x0a, 0xa4, 0xe7, 0xfe, 0x15, 0xbd, 0xb5, 0x68, 0xd1, 0x4b, 0x0f, - 0x85, 0x8f, 0x41, 0x2f, 0x4d, 0x2f, 0x44, 0xcd, 0x5c, 0xdb, 0x5b, 0x7b, 0x31, 0x50, 0xa0, 0x98, - 0xd9, 0xd9, 0xdf, 0xbb, 0xd2, 0xb2, 0x80, 0x05, 0xb4, 0x37, 0xed, 0xbc, 0xf7, 0x3e, 0x6f, 0xe6, - 0xcd, 0x7b, 0x6f, 0xde, 0x87, 0x82, 0xef, 0x9d, 0xbd, 0xeb, 0xaa, 0x9a, 0xd5, 0x3a, 0x1b, 0x74, - 0xa8, 0x63, 0x52, 0x46, 0xdd, 0xd6, 0x90, 0x9a, 0x3d, 0xcb, 0x69, 0x49, 0x01, 0xb1, 0xb5, 0x16, - 0xb1, 0x6d, 0xb7, 0x35, 0xbc, 0xd9, 0xa1, 0x8c, 0xdc, 0x6c, 0xf5, 0xa9, 0x49, 0x1d, 0xc2, 0x68, - 0x4f, 0xb5, 0x1d, 0x8b, 0x59, 0x68, 0xdd, 0x53, 0x54, 0x89, 0xad, 0xa9, 0x5c, 0x51, 0x95, 0x8a, - 0x1b, 0x37, 0xfa, 0x1a, 0x3b, 0x1d, 0x74, 0xd4, 0xae, 0x65, 0xb4, 0xfa, 0x56, 0xdf, 0x6a, 0x09, - 0xfd, 0xce, 0xe0, 0x91, 0xf8, 0x12, 0x1f, 0xe2, 0x2f, 0x0f, 0x67, 0xa3, 0x19, 0x71, 0xd8, 0xb5, - 0x1c, 0xda, 0x1a, 0xa6, 0x7c, 0x6d, 0xbc, 0x1d, 0xea, 0x18, 0xa4, 0x7b, 0xaa, 0x99, 0xd4, 0x19, - 0xb5, 0xec, 0xb3, 0x3e, 0x5f, 0x70, 0x5b, 0x06, 0x65, 0x24, 0xcb, 0xaa, 0x95, 0x67, 0xe5, 0x0c, - 0x4c, 0xa6, 0x19, 0x34, 0x65, 0xf0, 0xce, 0x45, 0x06, 0x6e, 0xf7, 0x94, 0x1a, 0x24, 0x65, 0xf7, - 0x56, 0x9e, 0xdd, 0x80, 0x69, 0x7a, 0x4b, 0x33, 0x99, 0xcb, 0x9c, 0xa4, 0x51, 0xf3, 0x9f, 0x0a, - 0xa0, 0x5d, 0xcb, 0x64, 0x8e, 0xa5, 0xeb, 0xd4, 0xc1, 0x74, 0xa8, 0xb9, 0x9a, 0x65, 0xa2, 0x4f, - 0xa1, 0xc2, 0xcf, 0xd3, 0x23, 0x8c, 0xd4, 0x94, 0x4d, 0x65, 0x6b, 0x69, 0xfb, 0x4d, 0x35, 0x8c, - 0x74, 0x00, 0xaf, 0xda, 0x67, 0x7d, 0xbe, 0xe0, 0xaa, 0x5c, 0x5b, 0x1d, 0xde, 0x54, 0x1f, 0x74, - 0x3e, 0xa3, 0x5d, 0x76, 0x40, 0x19, 0x69, 0xa3, 0x27, 0xe3, 0xc6, 0xcc, 0x64, 0xdc, 0x80, 0x70, - 0x0d, 0x07, 0xa8, 0xe8, 0x01, 0xcc, 0x09, 0xf4, 0x92, 0x40, 0xbf, 0x91, 0x8b, 0x2e, 0x0f, 0xad, - 0x62, 0xf2, 0xf9, 0xdd, 0xc7, 0x8c, 0x9a, 0x7c, 0x7b, 0xed, 0x17, 0x24, 0xf4, 0xdc, 0x1e, 0x61, - 0x04, 0x0b, 0x20, 0xf4, 0x06, 0x54, 0x1c, 0xb9, 0xfd, 0xda, 0xec, 0xa6, 0xb2, 0x35, 0xdb, 0xbe, - 0x22, 0xb5, 0x2a, 0xfe, 0xb1, 0x70, 0xa0, 0xd1, 0x7c, 0xa2, 0xc0, 0xb5, 0xf4, 0xb9, 0xf7, 0x35, - 0x97, 0xa1, 0x1f, 0xa5, 0xce, 0xae, 0x16, 0x3b, 0x3b, 0xb7, 0x16, 0x27, 0x0f, 0x1c, 0xfb, 0x2b, - 0x91, 0x73, 0x1f, 0x42, 0x59, 0x63, 0xd4, 0x70, 0x6b, 0xa5, 0xcd, 0xd9, 0xad, 0xa5, 0xed, 0xd7, - 0xd5, 0x9c, 0x04, 0x56, 0xd3, 0xbb, 0x6b, 0x2f, 0x4b, 0xdc, 0xf2, 0x7d, 0x8e, 0x80, 0x3d, 0xa0, - 0xe6, 0xcf, 0x4b, 0x00, 0x7b, 0xd4, 0xd6, 0xad, 0x91, 0x41, 0x4d, 0x76, 0x09, 0x57, 0x77, 0x1f, - 0xe6, 0x5c, 0x9b, 0x76, 0xe5, 0xd5, 0xbd, 0x92, 0x7b, 0x82, 0x70, 0x53, 0x47, 0x36, 0xed, 0x86, - 0x97, 0xc6, 0xbf, 0xb0, 0x80, 0x40, 0x1f, 0xc1, 0xbc, 0xcb, 0x08, 0x1b, 0xb8, 0xe2, 0xca, 0x96, - 0xb6, 0x5f, 0x2d, 0x02, 0x26, 0x0c, 0xda, 0x55, 0x09, 0x37, 0xef, 0x7d, 0x63, 0x09, 0xd4, 0xfc, - 0xf3, 0x2c, 0xac, 0x86, 0xca, 0xbb, 0x96, 0xd9, 0xd3, 0x18, 0x4f, 0xe9, 0xdb, 0x30, 0xc7, 0x46, - 0x36, 0x15, 0x31, 0x59, 0x6c, 0xbf, 0xe2, 0x6f, 0xe6, 0x78, 0x64, 0xd3, 0x67, 0xe3, 0xc6, 0x7a, - 0x86, 0x09, 0x17, 0x61, 0x61, 0x84, 0xf6, 0x83, 0x7d, 0x96, 0x84, 0xf9, 0xdb, 0x71, 0xe7, 0xcf, - 0xc6, 0x8d, 0x8c, 0x06, 0xa2, 0x06, 0x48, 0xf1, 0x2d, 0xa2, 0xcf, 0xa0, 0xaa, 0x13, 0x97, 0x9d, - 0xd8, 0x3d, 0xc2, 0xe8, 0xb1, 0x66, 0xd0, 0xda, 0xbc, 0x38, 0xfd, 0x6b, 0xc5, 0x2e, 0x8a, 0x5b, - 0xb4, 0xaf, 0xc9, 0x1d, 0x54, 0xf7, 0x63, 0x48, 0x38, 0x81, 0x8c, 0x86, 0x80, 0xf8, 0xca, 0xb1, - 0x43, 0x4c, 0xd7, 0x3b, 0x15, 0xf7, 0xb7, 0x30, 0xb5, 0xbf, 0x0d, 0xe9, 0x0f, 0xed, 0xa7, 0xd0, - 0x70, 0x86, 0x07, 0xf4, 0x32, 0xcc, 0x3b, 0x94, 0xb8, 0x96, 0x59, 0x9b, 0x13, 0x11, 0x0b, 0xae, - 0x0b, 0x8b, 0x55, 0x2c, 0xa5, 0xe8, 0x55, 0x58, 0x30, 0xa8, 0xeb, 0x92, 0x3e, 0xad, 0x95, 0x85, - 0xe2, 0x8a, 0x54, 0x5c, 0x38, 0xf0, 0x96, 0xb1, 0x2f, 0x6f, 0xfe, 0x46, 0x81, 0x6a, 0x78, 0x4d, - 0x97, 0x50, 0xab, 0xf7, 0xe2, 0xb5, 0xfa, 0xcd, 0x02, 0xc9, 0x99, 0x53, 0xa3, 0x7f, 0x2b, 0x01, - 0x0a, 0x95, 0xb0, 0xa5, 0xeb, 0x1d, 0xd2, 0x3d, 0x43, 0x9b, 0x30, 0x67, 0x12, 0xc3, 0xcf, 0xc9, - 0xa0, 0x40, 0x3e, 0x24, 0x06, 0xc5, 0x42, 0x82, 0xbe, 0x50, 0x00, 0x0d, 0xc4, 0x6d, 0xf6, 0x76, - 0x4c, 0xd3, 0x62, 0x84, 0x07, 0xd8, 0xdf, 0xd0, 0x6e, 0x81, 0x0d, 0xf9, 0xbe, 0xd4, 0x93, 0x14, - 0xca, 0x5d, 0x93, 0x39, 0xa3, 0xf0, 0x62, 0xd3, 0x0a, 0x38, 0xc3, 0x35, 0xfa, 0x21, 0x80, 0x23, - 0x31, 0x8f, 0x2d, 0x59, 0xb6, 0xf9, 0x3d, 0xc0, 0x77, 0xbf, 0x6b, 0x99, 0x8f, 0xb4, 0x7e, 0xd8, - 0x58, 0x70, 0x00, 0x81, 0x23, 0x70, 0x1b, 0x77, 0x61, 0x3d, 0x67, 0x9f, 0xe8, 0x0a, 0xcc, 0x9e, - 0xd1, 0x91, 0x17, 0x2a, 0xcc, 0xff, 0x44, 0x6b, 0x50, 0x1e, 0x12, 0x7d, 0x40, 0xbd, 0x9a, 0xc4, - 0xde, 0xc7, 0xad, 0xd2, 0xbb, 0x4a, 0xf3, 0x57, 0xe5, 0x68, 0xa6, 0xf0, 0x7e, 0x83, 0xb6, 0xf8, - 0xf3, 0x60, 0xeb, 0x5a, 0x97, 0xb8, 0x02, 0xa3, 0xdc, 0x7e, 0xc1, 0x7b, 0x1a, 0xbc, 0x35, 0x1c, - 0x48, 0xd1, 0x8f, 0xa1, 0xe2, 0x52, 0x9d, 0x76, 0x99, 0xe5, 0xc8, 0x16, 0xf7, 0x56, 0xc1, 0x9c, - 0x22, 0x1d, 0xaa, 0x1f, 0x49, 0x53, 0x0f, 0xde, 0xff, 0xc2, 0x01, 0x24, 0xfa, 0x08, 0x2a, 0x8c, - 0x1a, 0xb6, 0x4e, 0x18, 0x95, 0xd1, 0x8b, 0xe5, 0x15, 0xef, 0x1d, 0x1c, 0xec, 0xd0, 0xea, 0x1d, - 0x4b, 0x35, 0xd1, 0x3d, 0x83, 0x3c, 0xf5, 0x57, 0x71, 0x00, 0x83, 0x7e, 0x00, 0x15, 0x97, 0xf1, - 0x57, 0xbd, 0x3f, 0x12, 0xd5, 0x76, 0xde, 0xb3, 0x12, 0xed, 0xa3, 0x9e, 0x49, 0x08, 0xed, 0xaf, - 0xe0, 0x00, 0x0e, 0xed, 0xc0, 0x8a, 0xa1, 0x99, 0x98, 0x92, 0xde, 0xe8, 0x88, 0x76, 0x2d, 0xb3, - 0xe7, 0x8a, 0x32, 0x2d, 0xb7, 0xd7, 0xa5, 0xd1, 0xca, 0x41, 0x5c, 0x8c, 0x93, 0xfa, 0x68, 0x1f, - 0xd6, 0xfc, 0x67, 0xf7, 0x9e, 0xe6, 0x32, 0xcb, 0x19, 0xed, 0x6b, 0x86, 0xc6, 0x44, 0xcf, 0x2b, - 0xb7, 0x6b, 0x93, 0x71, 0x63, 0x0d, 0x67, 0xc8, 0x71, 0xa6, 0x15, 0xef, 0x2b, 0x36, 0x19, 0xb8, - 0xb4, 0x27, 0x7a, 0x58, 0x25, 0xec, 0x2b, 0x87, 0x62, 0x15, 0x4b, 0x29, 0x7a, 0x18, 0x4b, 0xd3, - 0xca, 0x74, 0x69, 0x5a, 0xcd, 0x4f, 0x51, 0x74, 0x02, 0xeb, 0xb6, 0x63, 0xf5, 0x1d, 0xea, 0xba, - 0x7b, 0x94, 0xf4, 0x74, 0xcd, 0xa4, 0x7e, 0x64, 0x16, 0xc5, 0x89, 0x5e, 0x9a, 0x8c, 0x1b, 0xeb, - 0x87, 0xd9, 0x2a, 0x38, 0xcf, 0xb6, 0xf9, 0x87, 0x39, 0xb8, 0x92, 0x7c, 0xe3, 0xd0, 0x07, 0x80, - 0xac, 0x8e, 0x4b, 0x9d, 0x21, 0xed, 0xbd, 0xef, 0x0d, 0x6e, 0x7c, 0xba, 0x51, 0xc4, 0x74, 0x13, - 0xd4, 0xed, 0x83, 0x94, 0x06, 0xce, 0xb0, 0xf2, 0xe6, 0x23, 0x59, 0x00, 0x25, 0xb1, 0xd1, 0xc8, - 0x7c, 0x94, 0x2a, 0x82, 0x1d, 0x58, 0x91, 0xb5, 0xef, 0x0b, 0x45, 0xb2, 0x46, 0xee, 0xfd, 0x24, - 0x2e, 0xc6, 0x49, 0x7d, 0x74, 0x1b, 0x96, 0x1d, 0x9e, 0x07, 0x01, 0xc0, 0x82, 0x00, 0xf8, 0x3f, - 0x09, 0xb0, 0x8c, 0xa3, 0x42, 0x1c, 0xd7, 0x45, 0xef, 0xc3, 0x55, 0x32, 0x24, 0x9a, 0x4e, 0x3a, - 0x3a, 0x0d, 0x00, 0xe6, 0x04, 0xc0, 0x8b, 0x12, 0xe0, 0xea, 0x4e, 0x52, 0x01, 0xa7, 0x6d, 0xd0, - 0x01, 0xac, 0x0e, 0xcc, 0x34, 0x94, 0x97, 0xc4, 0x2f, 0x49, 0xa8, 0xd5, 0x93, 0xb4, 0x0a, 0xce, - 0xb2, 0x43, 0x9f, 0x02, 0x74, 0xfd, 0x57, 0xdd, 0xad, 0xcd, 0x8b, 0x36, 0xfc, 0x46, 0x81, 0x62, - 0x0b, 0x46, 0x81, 0xb0, 0x05, 0x06, 0x4b, 0x2e, 0x8e, 0x60, 0xa2, 0x5b, 0x50, 0xed, 0x5a, 0xba, - 0x2e, 0x32, 0x7f, 0xd7, 0x1a, 0x98, 0x4c, 0x24, 0x6f, 0xb9, 0x8d, 0xf8, 0x63, 0xbf, 0x1b, 0x93, - 0xe0, 0x84, 0x66, 0xf3, 0x77, 0x4a, 0xf4, 0x99, 0xf1, 0xcb, 0x19, 0xdd, 0x8a, 0x8d, 0x3e, 0x2f, - 0x27, 0x46, 0x9f, 0x6b, 0x69, 0x8b, 0xc8, 0xe4, 0xa3, 0xc1, 0x32, 0x4f, 0x7e, 0xcd, 0xec, 0x7b, - 0x17, 0x2e, 0x5b, 0xe2, 0x9b, 0xe7, 0x96, 0x52, 0xa0, 0x1d, 0x79, 0x18, 0xaf, 0x8a, 0x3b, 0x8f, - 0x0a, 0x71, 0x1c, 0xb9, 0x79, 0x07, 0xaa, 0xf1, 0x3a, 0x8c, 0xcd, 0xf4, 0xca, 0x85, 0x33, 0xfd, - 0xd7, 0x0a, 0xac, 0xe7, 0x78, 0x47, 0x3a, 0x54, 0x0d, 0xf2, 0x38, 0x72, 0xcd, 0x17, 0xce, 0xc6, - 0x9c, 0x35, 0xa9, 0x1e, 0x6b, 0x52, 0xef, 0x9b, 0xec, 0x81, 0x73, 0xc4, 0x1c, 0xcd, 0xec, 0x7b, - 0xf7, 0x70, 0x10, 0xc3, 0xc2, 0x09, 0x6c, 0xf4, 0x09, 0x54, 0x0c, 0xf2, 0xf8, 0x68, 0xe0, 0xf4, - 0xb3, 0xe2, 0x55, 0xcc, 0x8f, 0x78, 0x3f, 0x0e, 0x24, 0x0a, 0x0e, 0xf0, 0x9a, 0xbf, 0x57, 0x60, - 0x33, 0x76, 0x4a, 0xde, 0x2b, 0xe8, 0xa3, 0x81, 0x7e, 0x44, 0xc3, 0x1b, 0x7f, 0x1d, 0x16, 0x6d, - 0xe2, 0x30, 0x2d, 0xe8, 0x17, 0xe5, 0xf6, 0xf2, 0x64, 0xdc, 0x58, 0x3c, 0xf4, 0x17, 0x71, 0x28, - 0xcf, 0x88, 0x4d, 0xe9, 0xf9, 0xc5, 0xa6, 0xf9, 0x2f, 0x05, 0xca, 0x47, 0x5d, 0xa2, 0xd3, 0x4b, - 0x60, 0x2a, 0x7b, 0x31, 0xa6, 0xd2, 0xcc, 0xcd, 0x59, 0xb1, 0x9f, 0x5c, 0x92, 0xb2, 0x9f, 0x20, - 0x29, 0xd7, 0x2f, 0xc0, 0x39, 0x9f, 0x9f, 0xbc, 0x07, 0x8b, 0x81, 0xbb, 0x58, 0x53, 0x56, 0x2e, - 0x6a, 0xca, 0xcd, 0x5f, 0x96, 0x60, 0x29, 0xe2, 0x62, 0x3a, 0x6b, 0x1e, 0xee, 0xc8, 0x5c, 0xc3, - 0x1b, 0xd7, 0x76, 0x91, 0x83, 0xa8, 0xfe, 0x0c, 0xe3, 0x8d, 0x8b, 0xe1, 0xb0, 0x90, 0x1e, 0x6d, - 0xee, 0x40, 0x95, 0x11, 0xa7, 0x4f, 0x99, 0x2f, 0x13, 0x01, 0x5b, 0x0c, 0xb9, 0xca, 0x71, 0x4c, - 0x8a, 0x13, 0xda, 0x1b, 0xb7, 0x61, 0x39, 0xe6, 0x6c, 0xaa, 0x99, 0xef, 0x0b, 0x1e, 0x9c, 0xb0, - 0x14, 0x2e, 0x21, 0xbb, 0x3e, 0x88, 0x65, 0xd7, 0x56, 0x7e, 0x30, 0x23, 0x05, 0x9a, 0x97, 0x63, - 0x38, 0x91, 0x63, 0xaf, 0x15, 0x42, 0x3b, 0x3f, 0xd3, 0xfe, 0x5e, 0x82, 0xb5, 0x88, 0x76, 0x48, - 0x85, 0xbf, 0x1d, 0x7b, 0x0f, 0xb6, 0x12, 0xef, 0x41, 0x2d, 0xcb, 0xe6, 0xb9, 0x71, 0xe1, 0x6c, - 0x7e, 0x3a, 0xfb, 0xdf, 0xc8, 0x4f, 0x7f, 0xab, 0xc0, 0x4a, 0x24, 0x76, 0x97, 0x40, 0x50, 0xef, - 0xc7, 0x09, 0xea, 0xf5, 0x22, 0x49, 0x93, 0xc3, 0x50, 0xff, 0xa1, 0x40, 0x2b, 0xa2, 0x75, 0x48, - 0x1d, 0x57, 0x73, 0x19, 0x35, 0xd9, 0xc7, 0x96, 0x3e, 0x30, 0xe8, 0xae, 0x4e, 0x34, 0x03, 0x53, - 0xbe, 0xa0, 0x59, 0xe6, 0xa1, 0xa5, 0x6b, 0xdd, 0x11, 0x22, 0xb0, 0xf4, 0xf9, 0x29, 0x35, 0xf7, - 0xa8, 0x4e, 0x19, 0xed, 0xc9, 0x74, 0xfa, 0xae, 0x84, 0x5f, 0x7a, 0x18, 0x8a, 0x9e, 0x8d, 0x1b, - 0x5b, 0x45, 0x10, 0x45, 0x96, 0x45, 0x31, 0xd1, 0x4f, 0x00, 0xf8, 0xa7, 0xe8, 0x47, 0x3d, 0x99, - 0x70, 0x77, 0xfc, 0xaa, 0x7c, 0x18, 0x48, 0xa6, 0x72, 0x10, 0x41, 0x6c, 0xfe, 0x65, 0x21, 0x76, - 0x67, 0xff, 0xf3, 0x54, 0xf1, 0xa7, 0xb0, 0x36, 0x0c, 0xa3, 0xe3, 0x2b, 0xf0, 0xd1, 0x7a, 0x36, - 0xf9, 0xf3, 0x5b, 0x00, 0x9f, 0x15, 0xd7, 0xf6, 0xff, 0x4b, 0x27, 0x6b, 0x1f, 0x67, 0xc0, 0xe1, - 0x4c, 0x27, 0xe8, 0x5b, 0xb0, 0xc4, 0x69, 0x89, 0xd6, 0xa5, 0x1f, 0x12, 0xc3, 0xaf, 0xa7, 0x55, - 0x3f, 0x5f, 0x8e, 0x42, 0x11, 0x8e, 0xea, 0xa1, 0x53, 0x58, 0xb5, 0xad, 0xde, 0x01, 0x31, 0x49, - 0x9f, 0xf2, 0x61, 0xce, 0xbb, 0x4a, 0xc1, 0x1f, 0x17, 0xdb, 0xef, 0xf8, 0x23, 0xfc, 0x61, 0x5a, - 0xe5, 0x19, 0x27, 0x62, 0xe9, 0x65, 0x91, 0x04, 0x59, 0x90, 0xc8, 0x81, 0xea, 0x40, 0xce, 0x54, - 0x92, 0x4e, 0x7b, 0x3f, 0x94, 0x6d, 0x17, 0x29, 0xac, 0x93, 0x98, 0x65, 0xf8, 0xe8, 0xc5, 0xd7, - 0x71, 0xc2, 0x43, 0x2e, 0x3d, 0xae, 0xfc, 0x47, 0xf4, 0x38, 0x83, 0xaf, 0x2f, 0x4e, 0xc9, 0xd7, - 0xff, 0xa8, 0xc0, 0x75, 0xbb, 0x40, 0x2d, 0xd5, 0x40, 0xc4, 0xe6, 0x5e, 0x91, 0xd8, 0x14, 0xa9, - 0xcd, 0xf6, 0xd6, 0x64, 0xdc, 0xb8, 0x5e, 0x44, 0x13, 0x17, 0xda, 0x5f, 0xf3, 0xd7, 0x65, 0xb8, - 0x9a, 0x7a, 0x2d, 0xd1, 0xf7, 0xcf, 0xe1, 0xd4, 0xd7, 0x9e, 0x1b, 0x9f, 0x4e, 0x91, 0xe1, 0xd9, - 0x29, 0xc8, 0xf0, 0x0e, 0xac, 0x74, 0x07, 0x8e, 0x43, 0x4d, 0x96, 0xa0, 0xc2, 0xc1, 0xa5, 0xee, - 0xc6, 0xc5, 0x38, 0xa9, 0x9f, 0xc5, 0xe7, 0xcb, 0x53, 0xf2, 0xf9, 0xe8, 0x2e, 0x24, 0x27, 0xf3, - 0x4a, 0x30, 0xbd, 0x0b, 0x49, 0xcd, 0x92, 0xfa, 0x7c, 0x40, 0xf4, 0x50, 0x03, 0x84, 0x85, 0xf8, - 0x80, 0x78, 0x12, 0x93, 0xe2, 0x84, 0x76, 0x06, 0x37, 0x5e, 0x2c, 0xca, 0x8d, 0x11, 0x89, 0x31, - 0x77, 0x10, 0xfd, 0xee, 0x46, 0x91, 0xdc, 0x2d, 0x4e, 0xdd, 0x33, 0x7f, 0xb4, 0x58, 0x9a, 0xfe, - 0x47, 0x8b, 0xe6, 0x9f, 0x14, 0x78, 0x31, 0xb7, 0xb3, 0xa0, 0x9d, 0xd8, 0xf8, 0x76, 0x23, 0x31, - 0xbe, 0x7d, 0x23, 0xd7, 0x30, 0x32, 0xc3, 0x39, 0xd9, 0xac, 0xfe, 0xbd, 0x62, 0xac, 0x3e, 0x83, - 0x71, 0x5e, 0x4c, 0xef, 0xdb, 0xdf, 0x79, 0xf2, 0xb4, 0x3e, 0xf3, 0xe5, 0xd3, 0xfa, 0xcc, 0x57, - 0x4f, 0xeb, 0x33, 0x3f, 0x9b, 0xd4, 0x95, 0x27, 0x93, 0xba, 0xf2, 0xe5, 0xa4, 0xae, 0x7c, 0x35, - 0xa9, 0x2b, 0x7f, 0x9d, 0xd4, 0x95, 0x5f, 0x7c, 0x5d, 0x9f, 0xf9, 0x64, 0x3d, 0xe7, 0x3f, 0xbf, - 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x15, 0x68, 0x85, 0x2c, 0x1e, 0x00, 0x00, + // 2034 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0x52, 0xa2, 0x44, 0x3d, 0x45, 0x54, 0x3c, 0x52, 0x2d, 0x46, 0x69, 0x25, 0x61, 0x63, + 0x24, 0x4a, 0x62, 0x2f, 0x63, 0x25, 0x0d, 0x12, 0xbb, 0x75, 0x2b, 0x4a, 0x6e, 0xec, 0x40, 0x8a, + 0x94, 0x91, 0x64, 0xa3, 0xe9, 0x07, 0x32, 0x22, 0xc7, 0xd4, 0x46, 0xfb, 0x85, 0xdd, 0x21, 0x63, + 0xa2, 0x97, 0xfe, 0x01, 0x05, 0xd2, 0x73, 0xff, 0x8a, 0xf6, 0xd4, 0xa2, 0x45, 0x2f, 0x3d, 0x14, + 0x3e, 0x06, 0xbd, 0x34, 0x27, 0xa2, 0x66, 0xae, 0xed, 0xad, 0xbd, 0x18, 0x28, 0x50, 0xcc, 0xec, + 0xec, 0xf7, 0xae, 0xb4, 0x2c, 0x60, 0x01, 0xed, 0x8d, 0x3b, 0xef, 0xbd, 0xdf, 0x7b, 0xf3, 0xe6, + 0xbd, 0x37, 0xef, 0x0d, 0xe1, 0xfb, 0x67, 0xef, 0x79, 0x9a, 0x6e, 0x37, 0xcf, 0x7a, 0x27, 0xd4, + 0xb5, 0x28, 0xa3, 0x5e, 0xb3, 0x4f, 0xad, 0x8e, 0xed, 0x36, 0x25, 0x81, 0x38, 0x7a, 0x93, 0x38, + 0x8e, 0xd7, 0xec, 0xdf, 0x3c, 0xa1, 0x8c, 0xdc, 0x6c, 0x76, 0xa9, 0x45, 0x5d, 0xc2, 0x68, 0x47, + 0x73, 0x5c, 0x9b, 0xd9, 0x68, 0xd9, 0x67, 0xd4, 0x88, 0xa3, 0x6b, 0x9c, 0x51, 0x93, 0x8c, 0x2b, + 0x37, 0xba, 0x3a, 0x3b, 0xed, 0x9d, 0x68, 0x6d, 0xdb, 0x6c, 0x76, 0xed, 0xae, 0xdd, 0x14, 0xfc, + 0x27, 0xbd, 0x47, 0xe2, 0x4b, 0x7c, 0x88, 0x5f, 0x3e, 0xce, 0x8a, 0x1a, 0x53, 0xd8, 0xb6, 0x5d, + 0xda, 0xec, 0x67, 0x74, 0xad, 0xbc, 0x13, 0xf1, 0x98, 0xa4, 0x7d, 0xaa, 0x5b, 0xd4, 0x1d, 0x34, + 0x9d, 0xb3, 0x2e, 0x5f, 0xf0, 0x9a, 0x26, 0x65, 0x24, 0x4f, 0xaa, 0x59, 0x24, 0xe5, 0xf6, 0x2c, + 0xa6, 0x9b, 0x34, 0x23, 0xf0, 0xee, 0x45, 0x02, 0x5e, 0xfb, 0x94, 0x9a, 0x24, 0x23, 0xf7, 0x76, + 0x91, 0x5c, 0x8f, 0xe9, 0x46, 0x53, 0xb7, 0x98, 0xc7, 0xdc, 0xb4, 0x90, 0xfa, 0x2f, 0x05, 0xd0, + 0xb6, 0x6d, 0x31, 0xd7, 0x36, 0x0c, 0xea, 0x62, 0xda, 0xd7, 0x3d, 0xdd, 0xb6, 0xd0, 0xa7, 0x50, + 0xe3, 0xfb, 0xe9, 0x10, 0x46, 0x1a, 0xca, 0xba, 0xb2, 0x31, 0xb7, 0xf9, 0x96, 0x16, 0x79, 0x3a, + 0x84, 0xd7, 0x9c, 0xb3, 0x2e, 0x5f, 0xf0, 0x34, 0xce, 0xad, 0xf5, 0x6f, 0x6a, 0xfb, 0x27, 0x9f, + 0xd1, 0x36, 0xdb, 0xa3, 0x8c, 0xb4, 0xd0, 0x93, 0xe1, 0xda, 0xc4, 0x68, 0xb8, 0x06, 0xd1, 0x1a, + 0x0e, 0x51, 0xd1, 0x3e, 0x4c, 0x09, 0xf4, 0x8a, 0x40, 0xbf, 0x51, 0x88, 0x2e, 0x37, 0xad, 0x61, + 0xf2, 0xf9, 0xdd, 0xc7, 0x8c, 0x5a, 0xdc, 0xbc, 0xd6, 0x0b, 0x12, 0x7a, 0x6a, 0x87, 0x30, 0x82, + 0x05, 0x10, 0xba, 0x0e, 0x35, 0x57, 0x9a, 0xdf, 0x98, 0x5c, 0x57, 0x36, 0x26, 0x5b, 0x2f, 0x4a, + 0xae, 0x5a, 0xb0, 0x2d, 0x1c, 0x72, 0xa8, 0x4f, 0x14, 0xb8, 0x9a, 0xdd, 0xf7, 0xae, 0xee, 0x31, + 0xf4, 0xe3, 0xcc, 0xde, 0xb5, 0x72, 0x7b, 0xe7, 0xd2, 0x62, 0xe7, 0xa1, 0xe2, 0x60, 0x25, 0xb6, + 0xef, 0x03, 0xa8, 0xea, 0x8c, 0x9a, 0x5e, 0xa3, 0xb2, 0x3e, 0xb9, 0x31, 0xb7, 0xf9, 0xa6, 0x56, + 0x10, 0xc0, 0x5a, 0xd6, 0xba, 0xd6, 0xbc, 0xc4, 0xad, 0xde, 0xe7, 0x08, 0xd8, 0x07, 0x52, 0x7f, + 0x51, 0x01, 0xd8, 0xa1, 0x8e, 0x61, 0x0f, 0x4c, 0x6a, 0xb1, 0x4b, 0x38, 0xba, 0xfb, 0x30, 0xe5, + 0x39, 0xb4, 0x2d, 0x8f, 0xee, 0xb5, 0xc2, 0x1d, 0x44, 0x46, 0x1d, 0x3a, 0xb4, 0x1d, 0x1d, 0x1a, + 0xff, 0xc2, 0x02, 0x02, 0x7d, 0x0c, 0xd3, 0x1e, 0x23, 0xac, 0xe7, 0x89, 0x23, 0x9b, 0xdb, 0x7c, + 0xbd, 0x0c, 0x98, 0x10, 0x68, 0xd5, 0x25, 0xdc, 0xb4, 0xff, 0x8d, 0x25, 0x90, 0xfa, 0xd7, 0x49, + 0x58, 0x8c, 0x98, 0xb7, 0x6d, 0xab, 0xa3, 0x33, 0x1e, 0xd2, 0xb7, 0x61, 0x8a, 0x0d, 0x1c, 0x2a, + 0x7c, 0x32, 0xdb, 0x7a, 0x2d, 0x30, 0xe6, 0x68, 0xe0, 0xd0, 0x67, 0xc3, 0xb5, 0xe5, 0x1c, 0x11, + 0x4e, 0xc2, 0x42, 0x08, 0xed, 0x86, 0x76, 0x56, 0x84, 0xf8, 0x3b, 0x49, 0xe5, 0xcf, 0x86, 0x6b, + 0x39, 0x05, 0x44, 0x0b, 0x91, 0x92, 0x26, 0xa2, 0xcf, 0xa0, 0x6e, 0x10, 0x8f, 0x1d, 0x3b, 0x1d, + 0xc2, 0xe8, 0x91, 0x6e, 0xd2, 0xc6, 0xb4, 0xd8, 0xfd, 0x1b, 0xe5, 0x0e, 0x8a, 0x4b, 0xb4, 0xae, + 0x4a, 0x0b, 0xea, 0xbb, 0x09, 0x24, 0x9c, 0x42, 0x46, 0x7d, 0x40, 0x7c, 0xe5, 0xc8, 0x25, 0x96, + 0xe7, 0xef, 0x8a, 0xeb, 0x9b, 0x19, 0x5b, 0xdf, 0x8a, 0xd4, 0x87, 0x76, 0x33, 0x68, 0x38, 0x47, + 0x03, 0x7a, 0x15, 0xa6, 0x5d, 0x4a, 0x3c, 0xdb, 0x6a, 0x4c, 0x09, 0x8f, 0x85, 0xc7, 0x85, 0xc5, + 0x2a, 0x96, 0x54, 0xf4, 0x3a, 0xcc, 0x98, 0xd4, 0xf3, 0x48, 0x97, 0x36, 0xaa, 0x82, 0x71, 0x41, + 0x32, 0xce, 0xec, 0xf9, 0xcb, 0x38, 0xa0, 0xab, 0xbf, 0x53, 0xa0, 0x1e, 0x1d, 0xd3, 0x25, 0xe4, + 0xea, 0xbd, 0x64, 0xae, 0xbe, 0x52, 0x22, 0x38, 0x0b, 0x72, 0xf4, 0xef, 0x15, 0x40, 0x11, 0x13, + 0xb6, 0x0d, 0xe3, 0x84, 0xb4, 0xcf, 0xd0, 0x3a, 0x4c, 0x59, 0xc4, 0x0c, 0x62, 0x32, 0x4c, 0x90, + 0x8f, 0x88, 0x49, 0xb1, 0xa0, 0xa0, 0x2f, 0x14, 0x40, 0x3d, 0x71, 0x9a, 0x9d, 0x2d, 0xcb, 0xb2, + 0x19, 0xe1, 0x0e, 0x0e, 0x0c, 0xda, 0x2e, 0x61, 0x50, 0xa0, 0x4b, 0x3b, 0xce, 0xa0, 0xdc, 0xb5, + 0x98, 0x3b, 0x88, 0x0e, 0x36, 0xcb, 0x80, 0x73, 0x54, 0xa3, 0x1f, 0x01, 0xb8, 0x12, 0xf3, 0xc8, + 0x96, 0x69, 0x5b, 0x5c, 0x03, 0x02, 0xf5, 0xdb, 0xb6, 0xf5, 0x48, 0xef, 0x46, 0x85, 0x05, 0x87, + 0x10, 0x38, 0x06, 0xb7, 0x72, 0x17, 0x96, 0x0b, 0xec, 0x44, 0x2f, 0xc2, 0xe4, 0x19, 0x1d, 0xf8, + 0xae, 0xc2, 0xfc, 0x27, 0x5a, 0x82, 0x6a, 0x9f, 0x18, 0x3d, 0xea, 0xe7, 0x24, 0xf6, 0x3f, 0x6e, + 0x55, 0xde, 0x53, 0xd4, 0x5f, 0x57, 0xe3, 0x91, 0xc2, 0xeb, 0x0d, 0xda, 0xe0, 0xd7, 0x83, 0x63, + 0xe8, 0x6d, 0xe2, 0x09, 0x8c, 0x6a, 0xeb, 0x05, 0xff, 0x6a, 0xf0, 0xd7, 0x70, 0x48, 0x45, 0x3f, + 0x81, 0x9a, 0x47, 0x0d, 0xda, 0x66, 0xb6, 0x2b, 0x4b, 0xdc, 0xdb, 0x25, 0x63, 0x8a, 0x9c, 0x50, + 0xe3, 0x50, 0x8a, 0xfa, 0xf0, 0xc1, 0x17, 0x0e, 0x21, 0xd1, 0xc7, 0x50, 0x63, 0xd4, 0x74, 0x0c, + 0xc2, 0xa8, 0xf4, 0x5e, 0x22, 0xae, 0x78, 0xed, 0xe0, 0x60, 0x07, 0x76, 0xe7, 0x48, 0xb2, 0x89, + 0xea, 0x19, 0xc6, 0x69, 0xb0, 0x8a, 0x43, 0x18, 0xf4, 0x43, 0xa8, 0x79, 0x8c, 0xdf, 0xea, 0xdd, + 0x81, 0xc8, 0xb6, 0xf3, 0xae, 0x95, 0x78, 0x1d, 0xf5, 0x45, 0x22, 0xe8, 0x60, 0x05, 0x87, 0x70, + 0x68, 0x0b, 0x16, 0x4c, 0xdd, 0xc2, 0x94, 0x74, 0x06, 0x87, 0xb4, 0x6d, 0x5b, 0x1d, 0x4f, 0xa4, + 0x69, 0xb5, 0xb5, 0x2c, 0x85, 0x16, 0xf6, 0x92, 0x64, 0x9c, 0xe6, 0x47, 0xbb, 0xb0, 0x14, 0x5c, + 0xbb, 0xf7, 0x74, 0x8f, 0xd9, 0xee, 0x60, 0x57, 0x37, 0x75, 0x26, 0x6a, 0x5e, 0xb5, 0xd5, 0x18, + 0x0d, 0xd7, 0x96, 0x70, 0x0e, 0x1d, 0xe7, 0x4a, 0xf1, 0xba, 0xe2, 0x90, 0x9e, 0x47, 0x3b, 0xa2, + 0x86, 0xd5, 0xa2, 0xba, 0x72, 0x20, 0x56, 0xb1, 0xa4, 0xa2, 0x87, 0x89, 0x30, 0xad, 0x8d, 0x17, + 0xa6, 0xf5, 0xe2, 0x10, 0x45, 0xc7, 0xb0, 0xec, 0xb8, 0x76, 0xd7, 0xa5, 0x9e, 0xb7, 0x43, 0x49, + 0xc7, 0xd0, 0x2d, 0x1a, 0x78, 0x66, 0x56, 0xec, 0xe8, 0xe5, 0xd1, 0x70, 0x6d, 0xf9, 0x20, 0x9f, + 0x05, 0x17, 0xc9, 0xaa, 0x7f, 0x9a, 0x82, 0x17, 0xd3, 0x77, 0x1c, 0xfa, 0x10, 0x90, 0x7d, 0xe2, + 0x51, 0xb7, 0x4f, 0x3b, 0x1f, 0xf8, 0x8d, 0x1b, 0xef, 0x6e, 0x14, 0xd1, 0xdd, 0x84, 0x79, 0xbb, + 0x9f, 0xe1, 0xc0, 0x39, 0x52, 0x7e, 0x7f, 0x24, 0x13, 0xa0, 0x22, 0x0c, 0x8d, 0xf5, 0x47, 0x99, + 0x24, 0xd8, 0x82, 0x05, 0x99, 0xfb, 0x01, 0x51, 0x04, 0x6b, 0xec, 0xdc, 0x8f, 0x93, 0x64, 0x9c, + 0xe6, 0x47, 0xb7, 0x61, 0xde, 0xe5, 0x71, 0x10, 0x02, 0xcc, 0x08, 0x80, 0x6f, 0x48, 0x80, 0x79, + 0x1c, 0x27, 0xe2, 0x24, 0x2f, 0xfa, 0x00, 0xae, 0x90, 0x3e, 0xd1, 0x0d, 0x72, 0x62, 0xd0, 0x10, + 0x60, 0x4a, 0x00, 0xbc, 0x24, 0x01, 0xae, 0x6c, 0xa5, 0x19, 0x70, 0x56, 0x06, 0xed, 0xc1, 0x62, + 0xcf, 0xca, 0x42, 0xf9, 0x41, 0xfc, 0xb2, 0x84, 0x5a, 0x3c, 0xce, 0xb2, 0xe0, 0x3c, 0x39, 0xf4, + 0x29, 0x40, 0x3b, 0xb8, 0xd5, 0xbd, 0xc6, 0xb4, 0x28, 0xc3, 0xd7, 0x4b, 0x24, 0x5b, 0xd8, 0x0a, + 0x44, 0x25, 0x30, 0x5c, 0xf2, 0x70, 0x0c, 0x13, 0xdd, 0x82, 0x7a, 0xdb, 0x36, 0x0c, 0x11, 0xf9, + 0xdb, 0x76, 0xcf, 0x62, 0x22, 0x78, 0xab, 0x2d, 0xc4, 0x2f, 0xfb, 0xed, 0x04, 0x05, 0xa7, 0x38, + 0xd5, 0x3f, 0x28, 0xf1, 0x6b, 0x26, 0x48, 0x67, 0x74, 0x2b, 0xd1, 0xfa, 0xbc, 0x9a, 0x6a, 0x7d, + 0xae, 0x66, 0x25, 0x62, 0x9d, 0x8f, 0x0e, 0xf3, 0x3c, 0xf8, 0x75, 0xab, 0xeb, 0x1f, 0xb8, 0x2c, + 0x89, 0x6f, 0x9d, 0x9b, 0x4a, 0x21, 0x77, 0xec, 0x62, 0xbc, 0x22, 0xce, 0x3c, 0x4e, 0xc4, 0x49, + 0x64, 0xf5, 0x0e, 0xd4, 0x93, 0x79, 0x98, 0xe8, 0xe9, 0x95, 0x0b, 0x7b, 0xfa, 0xaf, 0x15, 0x58, + 0x2e, 0xd0, 0x8e, 0x0c, 0xa8, 0x9b, 0xe4, 0x71, 0xec, 0x98, 0x2f, 0xec, 0x8d, 0xf9, 0xd4, 0xa4, + 0xf9, 0x53, 0x93, 0x76, 0xdf, 0x62, 0xfb, 0xee, 0x21, 0x73, 0x75, 0xab, 0xeb, 0x9f, 0xc3, 0x5e, + 0x02, 0x0b, 0xa7, 0xb0, 0xd1, 0x27, 0x50, 0x33, 0xc9, 0xe3, 0xc3, 0x9e, 0xdb, 0xcd, 0xf3, 0x57, + 0x39, 0x3d, 0xe2, 0xfe, 0xd8, 0x93, 0x28, 0x38, 0xc4, 0x53, 0xff, 0xa8, 0xc0, 0x7a, 0x62, 0x97, + 0xbc, 0x56, 0xd0, 0x47, 0x3d, 0xe3, 0x90, 0x46, 0x27, 0xfe, 0x26, 0xcc, 0x3a, 0xc4, 0x65, 0x7a, + 0x58, 0x2f, 0xaa, 0xad, 0xf9, 0xd1, 0x70, 0x6d, 0xf6, 0x20, 0x58, 0xc4, 0x11, 0x3d, 0xc7, 0x37, + 0x95, 0xe7, 0xe7, 0x1b, 0xf5, 0xdf, 0x0a, 0x54, 0x0f, 0xdb, 0xc4, 0xa0, 0x97, 0x30, 0xa9, 0xec, + 0x24, 0x26, 0x15, 0xb5, 0x30, 0x66, 0x85, 0x3d, 0x85, 0x43, 0xca, 0x6e, 0x6a, 0x48, 0xb9, 0x76, + 0x01, 0xce, 0xf9, 0xf3, 0xc9, 0xfb, 0x30, 0x1b, 0xaa, 0x4b, 0x14, 0x65, 0xe5, 0xa2, 0xa2, 0xac, + 0xfe, 0xaa, 0x02, 0x73, 0x31, 0x15, 0xe3, 0x49, 0x73, 0x77, 0xc7, 0xfa, 0x1a, 0x5e, 0xb8, 0x36, + 0xcb, 0x6c, 0x44, 0x0b, 0x7a, 0x18, 0xbf, 0x5d, 0x8c, 0x9a, 0x85, 0x6c, 0x6b, 0x73, 0x07, 0xea, + 0x8c, 0xb8, 0x5d, 0xca, 0x02, 0x9a, 0x70, 0xd8, 0x6c, 0x34, 0xab, 0x1c, 0x25, 0xa8, 0x38, 0xc5, + 0xbd, 0x72, 0x1b, 0xe6, 0x13, 0xca, 0xc6, 0xea, 0xf9, 0xbe, 0xe0, 0xce, 0x89, 0x52, 0xe1, 0x12, + 0xa2, 0xeb, 0xc3, 0x44, 0x74, 0x6d, 0x14, 0x3b, 0x33, 0x96, 0xa0, 0x45, 0x31, 0x86, 0x53, 0x31, + 0xf6, 0x46, 0x29, 0xb4, 0xf3, 0x23, 0xed, 0x1f, 0x15, 0x58, 0x8a, 0x71, 0x47, 0xa3, 0xf0, 0x77, + 0x12, 0xf7, 0xc1, 0x46, 0xea, 0x3e, 0x68, 0xe4, 0xc9, 0x3c, 0xb7, 0x59, 0x38, 0x7f, 0x3e, 0x9d, + 0xfc, 0x5f, 0x9c, 0x4f, 0x7f, 0xaf, 0xc0, 0x42, 0xcc, 0x77, 0x97, 0x30, 0xa0, 0xde, 0x4f, 0x0e, + 0xa8, 0xd7, 0xca, 0x04, 0x4d, 0xc1, 0x84, 0x7a, 0x0b, 0x16, 0x63, 0x4c, 0xfb, 0x6e, 0x47, 0xb7, + 0x88, 0xe1, 0xa1, 0x57, 0xa0, 0xea, 0x31, 0xe2, 0xb2, 0xe0, 0x12, 0x09, 0x64, 0x0f, 0xf9, 0x22, + 0xf6, 0x69, 0xea, 0x3f, 0x15, 0x68, 0xc6, 0x84, 0x0f, 0xa8, 0xeb, 0xe9, 0x1e, 0xa3, 0x16, 0x7b, + 0x60, 0x1b, 0x3d, 0x93, 0x6e, 0x1b, 0x44, 0x37, 0x31, 0xe5, 0x0b, 0xba, 0x6d, 0x1d, 0xd8, 0x86, + 0xde, 0x1e, 0x20, 0x02, 0x73, 0x9f, 0x9f, 0x52, 0x6b, 0x87, 0x1a, 0x94, 0xd1, 0x8e, 0x0c, 0xc5, + 0xef, 0x49, 0xf8, 0xb9, 0x87, 0x11, 0xe9, 0xd9, 0x70, 0x6d, 0xa3, 0x0c, 0xa2, 0x88, 0xd0, 0x38, + 0x26, 0xfa, 0x29, 0x00, 0xff, 0x14, 0xb5, 0xac, 0x23, 0x83, 0xf5, 0x4e, 0x90, 0xd1, 0x0f, 0x43, + 0xca, 0x58, 0x0a, 0x62, 0x88, 0xea, 0x6f, 0x6a, 0x89, 0xf3, 0xfe, 0xbf, 0x1f, 0x33, 0x7f, 0x06, + 0x4b, 0xfd, 0xc8, 0x3b, 0x01, 0x03, 0x6f, 0xcb, 0x27, 0xd3, 0x4f, 0x77, 0x21, 0x7c, 0x9e, 0x5f, + 0x5b, 0xdf, 0x94, 0x4a, 0x96, 0x1e, 0xe4, 0xc0, 0xe1, 0x5c, 0x25, 0xe8, 0xdb, 0x30, 0xc7, 0x47, + 0x1a, 0xbd, 0x4d, 0x3f, 0x22, 0x66, 0x90, 0x8b, 0x8b, 0x41, 0xbc, 0x1c, 0x46, 0x24, 0x1c, 0xe7, + 0x43, 0xa7, 0xb0, 0xe8, 0xd8, 0x9d, 0x3d, 0x62, 0x91, 0x2e, 0xe5, 0x8d, 0xa0, 0x7f, 0x94, 0x62, + 0xf6, 0x9c, 0x6d, 0xbd, 0x1b, 0xb4, 0xff, 0x07, 0x59, 0x96, 0x67, 0x7c, 0x88, 0xcb, 0x2e, 0x8b, + 0x20, 0xc8, 0x83, 0x44, 0x2e, 0xd4, 0x7b, 0xb2, 0x1f, 0x93, 0xa3, 0xb8, 0xff, 0xc8, 0xb6, 0x59, + 0x26, 0x29, 0x8f, 0x13, 0x92, 0xd1, 0x85, 0x99, 0x5c, 0xc7, 0x29, 0x0d, 0x85, 0xa3, 0x75, 0xed, + 0xbf, 0x1a, 0xad, 0x73, 0x66, 0xfd, 0xd9, 0x31, 0x67, 0xfd, 0x3f, 0x2b, 0x70, 0xcd, 0x29, 0x91, + 0x4b, 0x0d, 0x10, 0xbe, 0xb9, 0x57, 0xc6, 0x37, 0x65, 0x72, 0xb3, 0xb5, 0x31, 0x1a, 0xae, 0x5d, + 0x2b, 0xc3, 0x89, 0x4b, 0xd9, 0x87, 0x1e, 0x40, 0xcd, 0x96, 0x35, 0xb0, 0x31, 0x27, 0x6c, 0xbd, + 0x5e, 0xc6, 0xd6, 0xa0, 0x6e, 0xfa, 0x69, 0x19, 0x7c, 0xe1, 0x10, 0x4b, 0xfd, 0x6d, 0x15, 0xae, + 0x64, 0x6e, 0x70, 0xf4, 0x83, 0x73, 0xe6, 0xfc, 0xab, 0xcf, 0x6d, 0xc6, 0xcf, 0x0c, 0xe8, 0x93, + 0x63, 0x0c, 0xe8, 0x5b, 0xb0, 0xd0, 0xee, 0xb9, 0x2e, 0xb5, 0x58, 0x6a, 0x3c, 0x0f, 0x83, 0x65, + 0x3b, 0x49, 0xc6, 0x69, 0xfe, 0xbc, 0x37, 0x86, 0xea, 0x98, 0x6f, 0x0c, 0x71, 0x2b, 0xe4, 0x9c, + 0xe8, 0xa7, 0x76, 0xd6, 0x0a, 0x39, 0x2e, 0xa6, 0xf9, 0x79, 0xd3, 0xea, 0xa3, 0x86, 0x08, 0x33, + 0xc9, 0xa6, 0xf5, 0x38, 0x41, 0xc5, 0x29, 0xee, 0x9c, 0x79, 0x7d, 0xb6, 0xec, 0xbc, 0x8e, 0x48, + 0xe2, 0x35, 0x01, 0x44, 0x1d, 0xbd, 0x51, 0x26, 0xce, 0xca, 0x3f, 0x27, 0xe4, 0x3e, 0xa4, 0xcc, + 0x8d, 0xff, 0x90, 0xa2, 0xfe, 0x45, 0x81, 0x97, 0x0a, 0x2b, 0x16, 0xda, 0x4a, 0xb4, 0x94, 0x37, + 0x52, 0x2d, 0xe5, 0xb7, 0x0a, 0x05, 0x63, 0x7d, 0xa5, 0x9b, 0xff, 0xd2, 0xf0, 0x7e, 0xb9, 0x97, + 0x86, 0x9c, 0x29, 0xf8, 0xe2, 0x27, 0x87, 0xd6, 0x77, 0x9f, 0x3c, 0x5d, 0x9d, 0xf8, 0xf2, 0xe9, + 0xea, 0xc4, 0x57, 0x4f, 0x57, 0x27, 0x7e, 0x3e, 0x5a, 0x55, 0x9e, 0x8c, 0x56, 0x95, 0x2f, 0x47, + 0xab, 0xca, 0x57, 0xa3, 0x55, 0xe5, 0x6f, 0xa3, 0x55, 0xe5, 0x97, 0x5f, 0xaf, 0x4e, 0x7c, 0xb2, + 0x5c, 0xf0, 0x6f, 0xf4, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xaf, 0x0a, 0xd6, 0x32, 0xc0, 0x1e, + 0x00, 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -1737,6 +1770,32 @@ func (m *StatefulSetList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *StatefulSetOrdinals) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StatefulSetOrdinals) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StatefulSetOrdinals) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.Start)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1790,6 +1849,18 @@ func (m *StatefulSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Ordinals != nil { + { + size, err := m.Ordinals.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } if m.PersistentVolumeClaimRetentionPolicy != nil { { size, err := m.PersistentVolumeClaimRetentionPolicy.MarshalToSizedBuffer(dAtA[:i]) @@ -2312,6 +2383,16 @@ func (m *StatefulSetList) Size() (n int) { return n } +func (m *StatefulSetOrdinals) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Start)) + return n +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Size() (n int) { if m == nil { return 0 @@ -2360,6 +2441,10 @@ func (m *StatefulSetSpec) Size() (n int) { l = m.PersistentVolumeClaimRetentionPolicy.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Ordinals != nil { + l = m.Ordinals.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -2676,6 +2761,16 @@ func (this *StatefulSetList) String() string { }, "") return s } +func (this *StatefulSetOrdinals) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StatefulSetOrdinals{`, + `Start:` + fmt.Sprintf("%v", this.Start) + `,`, + `}`, + }, "") + return s +} func (this *StatefulSetPersistentVolumeClaimRetentionPolicy) String() string { if this == nil { return "nil" @@ -2707,6 +2802,7 @@ func (this *StatefulSetSpec) String() string { `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, `MinReadySeconds:` + fmt.Sprintf("%v", this.MinReadySeconds) + `,`, `PersistentVolumeClaimRetentionPolicy:` + strings.Replace(this.PersistentVolumeClaimRetentionPolicy.String(), "StatefulSetPersistentVolumeClaimRetentionPolicy", "StatefulSetPersistentVolumeClaimRetentionPolicy", 1) + `,`, + `Ordinals:` + strings.Replace(this.Ordinals.String(), "StatefulSetOrdinals", "StatefulSetOrdinals", 1) + `,`, `}`, }, "") return s @@ -5601,6 +5697,75 @@ func (m *StatefulSetList) Unmarshal(dAtA []byte) error { } return nil } +func (m *StatefulSetOrdinals) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StatefulSetOrdinals: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StatefulSetOrdinals: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + m.Start = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Start |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -6039,6 +6204,42 @@ func (m *StatefulSetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ordinals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ordinals == nil { + m.Ordinals = &StatefulSetOrdinals{} + } + if err := m.Ordinals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/apps/v1beta1/generated.proto b/vendor/k8s.io/api/apps/v1beta1/generated.proto index 53df96ee4de..245ec30f421 100644 --- a/vendor/k8s.io/api/apps/v1beta1/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta1/generated.proto @@ -47,10 +47,10 @@ message ControllerRevision { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Data is the serialized representation of the state. + // data is the serialized representation of the state. optional k8s.io.apimachinery.pkg.runtime.RawExtension data = 2; - // Revision indicates the revision of the state represented by Data. + // revision indicates the revision of the state represented by Data. optional int64 revision = 3; } @@ -128,17 +128,18 @@ message DeploymentRollback { // DeploymentSpec is the specification of the desired behavior of the Deployment. message DeploymentSpec { - // Number of desired pods. This is a pointer to distinguish between explicit + // replicas is the number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional optional int32 replicas = 1; - // Label selector for pods. Existing ReplicaSets whose pods are + // selector is the label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this deployment. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -146,28 +147,28 @@ message DeploymentSpec { // +patchStrategy=retainKeys optional DeploymentStrategy strategy = 4; - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional optional int32 minReadySeconds = 5; - // The number of old ReplicaSets to retain to allow rollback. + // revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. // Defaults to 2. // +optional optional int32 revisionHistoryLimit = 6; - // Indicates that the deployment is paused. + // paused indicates that the deployment is paused. // +optional optional bool paused = 7; // DEPRECATED. - // The config this deployment is rolling back to. Will be cleared after rollback is done. + // rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done. // +optional optional RollbackConfig rollbackTo = 8; - // The maximum time in seconds for a deployment to make progress before it + // progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it // is considered to be failed. The deployment controller will continue to // process failed deployments and a condition with a ProgressDeadlineExceeded // reason will be surfaced in the deployment status. Note that progress will @@ -178,15 +179,15 @@ message DeploymentSpec { // DeploymentStatus is the most recently observed status of the Deployment. message DeploymentStatus { - // The generation observed by the deployment controller. + // observedGeneration is the generation observed by the deployment controller. // +optional optional int64 observedGeneration = 1; - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector). // +optional optional int32 replicas = 2; - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; @@ -198,18 +199,18 @@ message DeploymentStatus { // +optional optional int32 availableReplicas = 4; - // Total number of unavailable pods targeted by this deployment. This is the total number of + // unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of // pods that are still required for the deployment to have 100% available capacity. They may // either be pods that are running but not yet available or pods that still have not been created. // +optional optional int32 unavailableReplicas = 5; - // Represents the latest available observations of a deployment's current state. + // Conditions represent the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge repeated DeploymentCondition conditions = 6; - // Count of hash collisions for the Deployment. The Deployment controller uses this + // collisionCount is the count of hash collisions for the Deployment. The Deployment controller uses this // field as a collision avoidance mechanism when it needs to create the name for the // newest ReplicaSet. // +optional @@ -276,7 +277,7 @@ message RollingUpdateStatefulSetStrategy { // This is helpful in being able to do a canary based deployment. The default value is 0. optional int32 partition = 1; - // The maximum number of pods that can be unavailable during the update. + // maxUnavailable is the maximum number of pods that can be unavailable during the update. // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // Absolute number is calculated from percentage by rounding up. This can not be 0. // Defaults to 1. This field is alpha-level and is only honored by servers that enable the @@ -293,32 +294,32 @@ message Scale { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional ScaleSpec spec = 2; - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional optional ScaleStatus status = 3; } // ScaleSpec describes the attributes of a scale subresource message ScaleSpec { - // desired number of instances for the scaled object. + // replicas is the number of observed instances of the scaled object. // +optional optional int32 replicas = 1; } // ScaleStatus represents the current status of a scale subresource. message ScaleStatus { - // actual number of observed instances of the scaled object. + // replias is the actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional map selector = 2; - // label selector for pods that should match the replicas count. This is a serializated + // targetSelector is the label selector for pods that should match the replicas count. This is a serializated // version of both map-based and more expressive set-based selectors. This is done to // avoid introspection in the clients. The string will be in the same format as the // query-param syntax. If the target type only supports map-based selectors, both this @@ -332,8 +333,9 @@ message ScaleStatus { // more information. // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. message StatefulSet { @@ -379,16 +381,31 @@ message StatefulSetList { repeated StatefulSet items = 2; } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +message StatefulSetOrdinals { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + optional int32 start = 1; +} + // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. message StatefulSetPersistentVolumeClaimRetentionPolicy { - // WhenDeleted specifies what happens to PVCs created from StatefulSet + // whenDeleted specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is deleted. The default policy // of `Retain` causes PVCs to not be affected by StatefulSet deletion. The // `Delete` policy causes those PVCs to be deleted. optional string whenDeleted = 1; - // WhenScaled specifies what happens to PVCs created from StatefulSet + // whenScaled specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is scaled down. The default // policy of `Retain` causes PVCs to not be affected by a scaledown. The // `Delete` policy causes the associated PVCs for any excess pods above @@ -415,7 +432,9 @@ message StatefulSetSpec { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -457,10 +476,9 @@ message StatefulSetSpec { // StatefulSetSpec version. The default value is 10. optional int32 revisionHistoryLimit = 8; - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional optional int32 minReadySeconds = 9; @@ -469,6 +487,14 @@ message StatefulSetSpec { // StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. // +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + optional StatefulSetOrdinals ordinals = 11; } // StatefulSetStatus represents the current state of a StatefulSet. @@ -506,14 +532,13 @@ message StatefulSetStatus { // +optional optional int32 collisionCount = 9; - // Represents the latest available observations of a statefulset's current state. + // conditions represent the latest available observations of a statefulset's current state. // +optional // +patchMergeKey=type // +patchStrategy=merge repeated StatefulSetCondition conditions = 10; - // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. + // availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. // +optional optional int32 availableReplicas = 11; } diff --git a/vendor/k8s.io/api/apps/v1beta1/types.go b/vendor/k8s.io/api/apps/v1beta1/types.go index cdc81c956a3..59ed9c2ac3b 100644 --- a/vendor/k8s.io/api/apps/v1beta1/types.go +++ b/vendor/k8s.io/api/apps/v1beta1/types.go @@ -31,21 +31,21 @@ const ( // ScaleSpec describes the attributes of a scale subresource type ScaleSpec struct { - // desired number of instances for the scaled object. + // replicas is the number of observed instances of the scaled object. // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } // ScaleStatus represents the current status of a scale subresource. type ScaleStatus struct { - // actual number of observed instances of the scaled object. + // replias is the actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` - // label selector for pods that should match the replicas count. This is a serializated + // targetSelector is the label selector for pods that should match the replicas count. This is a serializated // version of both map-based and more expressive set-based selectors. This is done to // avoid introspection in the clients. The string will be in the same format as the // query-param syntax. If the target type only supports map-based selectors, both this @@ -68,11 +68,11 @@ type Scale struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec ScaleSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional Status ScaleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -88,8 +88,9 @@ type Scale struct { // more information. // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. type StatefulSet struct { @@ -158,7 +159,7 @@ type RollingUpdateStatefulSetStrategy struct { // Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. // This is helpful in being able to do a canary based deployment. The default value is 0. Partition *int32 `json:"partition,omitempty" protobuf:"varint,1,opt,name=partition"` - // The maximum number of pods that can be unavailable during the update. + // maxUnavailable is the maximum number of pods that can be unavailable during the update. // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // Absolute number is calculated from percentage by rounding up. This can not be 0. // Defaults to 1. This field is alpha-level and is only honored by servers that enable the @@ -190,12 +191,12 @@ const ( // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. type StatefulSetPersistentVolumeClaimRetentionPolicy struct { - // WhenDeleted specifies what happens to PVCs created from StatefulSet + // whenDeleted specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is deleted. The default policy // of `Retain` causes PVCs to not be affected by StatefulSet deletion. The // `Delete` policy causes those PVCs to be deleted. WhenDeleted PersistentVolumeClaimRetentionPolicyType `json:"whenDeleted,omitempty" protobuf:"bytes,1,opt,name=whenDeleted,casttype=PersistentVolumeClaimRetentionPolicyType"` - // WhenScaled specifies what happens to PVCs created from StatefulSet + // whenScaled specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is scaled down. The default // policy of `Retain` causes PVCs to not be affected by a scaledown. The // `Delete` policy causes the associated PVCs for any excess pods above @@ -203,6 +204,21 @@ type StatefulSetPersistentVolumeClaimRetentionPolicy struct { WhenScaled PersistentVolumeClaimRetentionPolicyType `json:"whenScaled,omitempty" protobuf:"bytes,2,opt,name=whenScaled,casttype=PersistentVolumeClaimRetentionPolicyType"` } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +type StatefulSetOrdinals struct { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + Start int32 `json:"start" protobuf:"varint,1,opt,name=start"` +} + // A StatefulSetSpec is the specification of a StatefulSet. type StatefulSetSpec struct { // replicas is the desired number of replicas of the given Template. @@ -222,7 +238,9 @@ type StatefulSetSpec struct { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -264,10 +282,9 @@ type StatefulSetSpec struct { // StatefulSetSpec version. The default value is 10. RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,8,opt,name=revisionHistoryLimit"` - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,9,opt,name=minReadySeconds"` @@ -276,6 +293,14 @@ type StatefulSetSpec struct { // StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } // StatefulSetStatus represents the current state of a StatefulSet. @@ -313,14 +338,13 @@ type StatefulSetStatus struct { // +optional CollisionCount *int32 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"` - // Represents the latest available observations of a statefulset's current state. + // conditions represent the latest available observations of a statefulset's current state. // +optional // +patchMergeKey=type // +patchStrategy=merge Conditions []StatefulSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. + // availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. // +optional AvailableReplicas int32 `json:"availableReplicas" protobuf:"varint,11,opt,name=availableReplicas"` } @@ -385,17 +409,18 @@ type Deployment struct { // DeploymentSpec is the specification of the desired behavior of the Deployment. type DeploymentSpec struct { - // Number of desired pods. This is a pointer to distinguish between explicit + // replicas is the number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` - // Label selector for pods. Existing ReplicaSets whose pods are + // selector is the label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this deployment. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -403,28 +428,28 @@ type DeploymentSpec struct { // +patchStrategy=retainKeys Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"` - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,5,opt,name=minReadySeconds"` - // The number of old ReplicaSets to retain to allow rollback. + // revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. // Defaults to 2. // +optional RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,6,opt,name=revisionHistoryLimit"` - // Indicates that the deployment is paused. + // paused indicates that the deployment is paused. // +optional Paused bool `json:"paused,omitempty" protobuf:"varint,7,opt,name=paused"` // DEPRECATED. - // The config this deployment is rolling back to. Will be cleared after rollback is done. + // rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done. // +optional RollbackTo *RollbackConfig `json:"rollbackTo,omitempty" protobuf:"bytes,8,opt,name=rollbackTo"` - // The maximum time in seconds for a deployment to make progress before it + // progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it // is considered to be failed. The deployment controller will continue to // process failed deployments and a condition with a ProgressDeadlineExceeded // reason will be surfaced in the deployment status. Note that progress will @@ -523,15 +548,15 @@ type RollingUpdateDeployment struct { // DeploymentStatus is the most recently observed status of the Deployment. type DeploymentStatus struct { - // The generation observed by the deployment controller. + // observedGeneration is the generation observed by the deployment controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector). // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"` - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` @@ -543,18 +568,18 @@ type DeploymentStatus struct { // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` - // Total number of unavailable pods targeted by this deployment. This is the total number of + // unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of // pods that are still required for the deployment to have 100% available capacity. They may // either be pods that are running but not yet available or pods that still have not been created. // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` - // Represents the latest available observations of a deployment's current state. + // Conditions represent the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge Conditions []DeploymentCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"` - // Count of hash collisions for the Deployment. The Deployment controller uses this + // collisionCount is the count of hash collisions for the Deployment. The Deployment controller uses this // field as a collision avoidance mechanism when it needs to create the name for the // newest ReplicaSet. // +optional @@ -636,10 +661,10 @@ type ControllerRevision struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Data is the serialized representation of the state. + // data is the serialized representation of the state. Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` - // Revision indicates the revision of the state represented by Data. + // revision indicates the revision of the state represented by Data. Revision int64 `json:"revision" protobuf:"varint,3,opt,name=revision"` } diff --git a/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go index f57b7b2efcf..a62e9869d68 100644 --- a/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ "": "DEPRECATED - This group version of ControllerRevision is deprecated by apps/v1beta2/ControllerRevision. See the release notes for more information. ControllerRevision implements an immutable snapshot of state data. Clients are responsible for serializing and deserializing the objects that contain their internal state. Once a ControllerRevision has been successfully created, it can not be updated. The API Server will fail validation of all requests that attempt to mutate the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However, it may be subject to name and representation changes in future releases, and clients should not depend on its stability. It is primarily for internal use by controllers.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "data": "Data is the serialized representation of the state.", - "revision": "Revision indicates the revision of the state represented by Data.", + "data": "data is the serialized representation of the state.", + "revision": "revision indicates the revision of the state represented by Data.", } func (ControllerRevision) SwaggerDoc() map[string]string { @@ -96,15 +96,15 @@ func (DeploymentRollback) SwaggerDoc() map[string]string { var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", - "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", - "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment.", - "template": "Template describes the pods that will be created.", + "replicas": "replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", + "selector": "selector is the label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", - "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", - "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 2.", - "paused": "Indicates that the deployment is paused.", - "rollbackTo": "DEPRECATED. The config this deployment is rolling back to. Will be cleared after rollback is done.", - "progressDeadlineSeconds": "The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.", + "minReadySeconds": "minReadySeconds is the minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", + "revisionHistoryLimit": "revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 2.", + "paused": "paused indicates that the deployment is paused.", + "rollbackTo": "DEPRECATED. rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done.", + "progressDeadlineSeconds": "progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.", } func (DeploymentSpec) SwaggerDoc() map[string]string { @@ -113,14 +113,14 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", - "observedGeneration": "The generation observed by the deployment controller.", - "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", - "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", + "observedGeneration": "observedGeneration is the generation observed by the deployment controller.", + "replicas": "replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec.", "readyReplicas": "readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition.", "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", - "unavailableReplicas": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", - "conditions": "Represents the latest available observations of a deployment's current state.", - "collisionCount": "Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", + "unavailableReplicas": "unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "conditions": "Conditions represent the latest available observations of a deployment's current state.", + "collisionCount": "collisionCount is the count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", } func (DeploymentStatus) SwaggerDoc() map[string]string { @@ -159,7 +159,7 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { var map_RollingUpdateStatefulSetStrategy = map[string]string{ "": "RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.", "partition": "Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0.", - "maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0. Defaults to 1. This field is alpha-level and is only honored by servers that enable the MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it will be counted towards MaxUnavailable.", + "maxUnavailable": "maxUnavailable is the maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0. Defaults to 1. This field is alpha-level and is only honored by servers that enable the MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it will be counted towards MaxUnavailable.", } func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { @@ -169,8 +169,8 @@ func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { var map_Scale = map[string]string{ "": "Scale represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", + "spec": "spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -179,7 +179,7 @@ func (Scale) SwaggerDoc() map[string]string { var map_ScaleSpec = map[string]string{ "": "ScaleSpec describes the attributes of a scale subresource", - "replicas": "desired number of instances for the scaled object.", + "replicas": "replicas is the number of observed instances of the scaled object.", } func (ScaleSpec) SwaggerDoc() map[string]string { @@ -188,9 +188,9 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", - "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", - "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", + "replicas": "replias is the actual number of observed instances of the scaled object.", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", + "targetSelector": "targetSelector is the label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } func (ScaleStatus) SwaggerDoc() map[string]string { @@ -198,7 +198,7 @@ func (ScaleStatus) SwaggerDoc() map[string]string { } var map_StatefulSet = map[string]string{ - "": "DEPRECATED - This group version of StatefulSet is deprecated by apps/v1beta2/StatefulSet. See the release notes for more information. StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", + "": "DEPRECATED - This group version of StatefulSet is deprecated by apps/v1beta2/StatefulSet. See the release notes for more information. StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\n\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", "spec": "Spec defines the desired identities of pods in this set.", "status": "Status is the current status of Pods in this StatefulSet. This data may be out of date by some window of time.", } @@ -228,10 +228,19 @@ func (StatefulSetList) SwaggerDoc() map[string]string { return map_StatefulSetList } +var map_StatefulSetOrdinals = map[string]string{ + "": "StatefulSetOrdinals describes the policy used for replica ordinal assignment in this StatefulSet.", + "start": "start is the number representing the first replica's index. It may be used to number replicas from an alternate index (eg: 1-indexed) over the default 0-indexed names, or to orchestrate progressive movement of replicas from one StatefulSet to another. If set, replica indices will be in the range:\n [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas).\nIf unset, defaults to 0. Replica indices will be in the range:\n [0, .spec.replicas).", +} + +func (StatefulSetOrdinals) SwaggerDoc() map[string]string { + return map_StatefulSetOrdinals +} + var map_StatefulSetPersistentVolumeClaimRetentionPolicy = map[string]string{ "": "StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", - "whenDeleted": "WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", - "whenScaled": "WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of `Retain` causes PVCs to not be affected by a scaledown. The `Delete` policy causes the associated PVCs for any excess pods above the replica count to be deleted.", + "whenDeleted": "whenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", + "whenScaled": "whenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of `Retain` causes PVCs to not be affected by a scaledown. The `Delete` policy causes the associated PVCs for any excess pods above the replica count to be deleted.", } func (StatefulSetPersistentVolumeClaimRetentionPolicy) SwaggerDoc() map[string]string { @@ -242,14 +251,15 @@ var map_StatefulSetSpec = map[string]string{ "": "A StatefulSetSpec is the specification of a StatefulSet.", "replicas": "replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.", "selector": "selector is a label query over pods that should match the replica count. If empty, defaulted to labels on the pod template. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.", + "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\".", "volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.", "serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.", "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", - "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.", + "minReadySeconds": "minReadySeconds is the minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha.", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { @@ -266,8 +276,8 @@ var map_StatefulSetStatus = map[string]string{ "currentRevision": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).", "updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)", "collisionCount": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision.", - "conditions": "Represents the latest available observations of a statefulset's current state.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate.", + "conditions": "conditions represent the latest available observations of a statefulset's current state.", + "availableReplicas": "availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet.", } func (StatefulSetStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go index 185f868cd68..dd73f1a5a9c 100644 --- a/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go @@ -505,6 +505,22 @@ func (in *StatefulSetList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatefulSetOrdinals) DeepCopyInto(out *StatefulSetOrdinals) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetOrdinals. +func (in *StatefulSetOrdinals) DeepCopy() *StatefulSetOrdinals { + if in == nil { + return nil + } + out := new(StatefulSetOrdinals) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StatefulSetPersistentVolumeClaimRetentionPolicy) DeepCopyInto(out *StatefulSetPersistentVolumeClaimRetentionPolicy) { *out = *in @@ -553,6 +569,11 @@ func (in *StatefulSetSpec) DeepCopyInto(out *StatefulSetSpec) { *out = new(StatefulSetPersistentVolumeClaimRetentionPolicy) **out = **in } + if in.Ordinals != nil { + in, out := &in.Ordinals, &out.Ordinals + *out = new(StatefulSetOrdinals) + **out = **in + } return } diff --git a/vendor/k8s.io/api/apps/v1beta2/generated.pb.go b/vendor/k8s.io/api/apps/v1beta2/generated.pb.go index df26908fcfc..6dfb4d5d2a8 100644 --- a/vendor/k8s.io/api/apps/v1beta2/generated.pb.go +++ b/vendor/k8s.io/api/apps/v1beta2/generated.pb.go @@ -833,12 +833,40 @@ func (m *StatefulSetList) XXX_DiscardUnknown() { var xxx_messageInfo_StatefulSetList proto.InternalMessageInfo +func (m *StatefulSetOrdinals) Reset() { *m = StatefulSetOrdinals{} } +func (*StatefulSetOrdinals) ProtoMessage() {} +func (*StatefulSetOrdinals) Descriptor() ([]byte, []int) { + return fileDescriptor_42fe616264472f7e, []int{28} +} +func (m *StatefulSetOrdinals) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StatefulSetOrdinals) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *StatefulSetOrdinals) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatefulSetOrdinals.Merge(m, src) +} +func (m *StatefulSetOrdinals) XXX_Size() int { + return m.Size() +} +func (m *StatefulSetOrdinals) XXX_DiscardUnknown() { + xxx_messageInfo_StatefulSetOrdinals.DiscardUnknown(m) +} + +var xxx_messageInfo_StatefulSetOrdinals proto.InternalMessageInfo + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Reset() { *m = StatefulSetPersistentVolumeClaimRetentionPolicy{} } func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} func (*StatefulSetPersistentVolumeClaimRetentionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_42fe616264472f7e, []int{28} + return fileDescriptor_42fe616264472f7e, []int{29} } func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -866,7 +894,7 @@ var xxx_messageInfo_StatefulSetPersistentVolumeClaimRetentionPolicy proto.Intern func (m *StatefulSetSpec) Reset() { *m = StatefulSetSpec{} } func (*StatefulSetSpec) ProtoMessage() {} func (*StatefulSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_42fe616264472f7e, []int{29} + return fileDescriptor_42fe616264472f7e, []int{30} } func (m *StatefulSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -894,7 +922,7 @@ var xxx_messageInfo_StatefulSetSpec proto.InternalMessageInfo func (m *StatefulSetStatus) Reset() { *m = StatefulSetStatus{} } func (*StatefulSetStatus) ProtoMessage() {} func (*StatefulSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_42fe616264472f7e, []int{30} + return fileDescriptor_42fe616264472f7e, []int{31} } func (m *StatefulSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -922,7 +950,7 @@ var xxx_messageInfo_StatefulSetStatus proto.InternalMessageInfo func (m *StatefulSetUpdateStrategy) Reset() { *m = StatefulSetUpdateStrategy{} } func (*StatefulSetUpdateStrategy) ProtoMessage() {} func (*StatefulSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_42fe616264472f7e, []int{31} + return fileDescriptor_42fe616264472f7e, []int{32} } func (m *StatefulSetUpdateStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -977,6 +1005,7 @@ func init() { proto.RegisterType((*StatefulSet)(nil), "k8s.io.api.apps.v1beta2.StatefulSet") proto.RegisterType((*StatefulSetCondition)(nil), "k8s.io.api.apps.v1beta2.StatefulSetCondition") proto.RegisterType((*StatefulSetList)(nil), "k8s.io.api.apps.v1beta2.StatefulSetList") + proto.RegisterType((*StatefulSetOrdinals)(nil), "k8s.io.api.apps.v1beta2.StatefulSetOrdinals") proto.RegisterType((*StatefulSetPersistentVolumeClaimRetentionPolicy)(nil), "k8s.io.api.apps.v1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy") proto.RegisterType((*StatefulSetSpec)(nil), "k8s.io.api.apps.v1beta2.StatefulSetSpec") proto.RegisterType((*StatefulSetStatus)(nil), "k8s.io.api.apps.v1beta2.StatefulSetStatus") @@ -988,151 +1017,154 @@ func init() { } var fileDescriptor_42fe616264472f7e = []byte{ - // 2295 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcf, 0x6f, 0x1b, 0xc7, - 0xf5, 0xd7, 0xf2, 0x87, 0x44, 0x8e, 0x2c, 0xc9, 0x1e, 0xe9, 0x2b, 0x31, 0xf2, 0xb7, 0xa4, 0xb1, - 0x31, 0x1c, 0x25, 0xb6, 0x49, 0x5b, 0xf9, 0x81, 0xc4, 0x6e, 0x93, 0x8a, 0x52, 0x6a, 0x3b, 0x90, - 0x64, 0x66, 0x64, 0x39, 0x68, 0xd0, 0x1f, 0x1e, 0x91, 0x63, 0x6a, 0xa3, 0xe5, 0xee, 0x62, 0x77, - 0x96, 0x31, 0xd1, 0x4b, 0xaf, 0x05, 0x0a, 0xb4, 0xbd, 0xf6, 0x9f, 0xe8, 0xad, 0x28, 0x1a, 0xf4, - 0x52, 0x04, 0x81, 0x8f, 0x41, 0x2f, 0x49, 0x2f, 0x44, 0xcd, 0x9c, 0x8a, 0xa2, 0xb7, 0xf6, 0x62, - 0xa0, 0x40, 0x31, 0xb3, 0xb3, 0xbf, 0x77, 0xcd, 0xa5, 0x62, 0x2b, 0x4d, 0x90, 0x1b, 0x77, 0xde, - 0x7b, 0x9f, 0x79, 0x33, 0xf3, 0xde, 0xbc, 0xcf, 0xcc, 0x10, 0x7c, 0xff, 0xe8, 0x75, 0xab, 0xae, - 0xe8, 0x8d, 0x23, 0xfb, 0x80, 0x98, 0x1a, 0xa1, 0xc4, 0x6a, 0xf4, 0x89, 0xd6, 0xd1, 0xcd, 0x86, - 0x10, 0x60, 0x43, 0x69, 0x60, 0xc3, 0xb0, 0x1a, 0xfd, 0xab, 0x07, 0x84, 0xe2, 0xf5, 0x46, 0x97, - 0x68, 0xc4, 0xc4, 0x94, 0x74, 0xea, 0x86, 0xa9, 0x53, 0x1d, 0xae, 0x38, 0x8a, 0x75, 0x6c, 0x28, - 0x75, 0xa6, 0x58, 0x17, 0x8a, 0xab, 0x97, 0xbb, 0x0a, 0x3d, 0xb4, 0x0f, 0xea, 0x6d, 0xbd, 0xd7, - 0xe8, 0xea, 0x5d, 0xbd, 0xc1, 0xf5, 0x0f, 0xec, 0xfb, 0xfc, 0x8b, 0x7f, 0xf0, 0x5f, 0x0e, 0xce, - 0xaa, 0x1c, 0xe8, 0xb0, 0xad, 0x9b, 0xa4, 0xd1, 0xbf, 0x1a, 0xed, 0x6b, 0xf5, 0x15, 0x5f, 0xa7, - 0x87, 0xdb, 0x87, 0x8a, 0x46, 0xcc, 0x41, 0xc3, 0x38, 0xea, 0xb2, 0x06, 0xab, 0xd1, 0x23, 0x14, - 0x27, 0x59, 0x35, 0xd2, 0xac, 0x4c, 0x5b, 0xa3, 0x4a, 0x8f, 0xc4, 0x0c, 0x5e, 0x1b, 0x67, 0x60, - 0xb5, 0x0f, 0x49, 0x0f, 0xc7, 0xec, 0x5e, 0x4e, 0xb3, 0xb3, 0xa9, 0xa2, 0x36, 0x14, 0x8d, 0x5a, - 0xd4, 0x8c, 0x1a, 0xc9, 0xff, 0x96, 0x00, 0xdc, 0xd4, 0x35, 0x6a, 0xea, 0xaa, 0x4a, 0x4c, 0x44, - 0xfa, 0x8a, 0xa5, 0xe8, 0x1a, 0xbc, 0x07, 0x4a, 0x6c, 0x3c, 0x1d, 0x4c, 0x71, 0x45, 0x3a, 0x27, - 0xad, 0xcd, 0xae, 0x5f, 0xa9, 0xfb, 0x33, 0xed, 0xc1, 0xd7, 0x8d, 0xa3, 0x2e, 0x6b, 0xb0, 0xea, - 0x4c, 0xbb, 0xde, 0xbf, 0x5a, 0xbf, 0x7d, 0xf0, 0x01, 0x69, 0xd3, 0x1d, 0x42, 0x71, 0x13, 0x3e, - 0x1c, 0xd6, 0xa6, 0x46, 0xc3, 0x1a, 0xf0, 0xdb, 0x90, 0x87, 0x0a, 0x6f, 0x83, 0x02, 0x47, 0xcf, - 0x71, 0xf4, 0xcb, 0xa9, 0xe8, 0x62, 0xd0, 0x75, 0x84, 0x3f, 0x7c, 0xfb, 0x01, 0x25, 0x1a, 0x73, - 0xaf, 0x79, 0x4a, 0x40, 0x17, 0xb6, 0x30, 0xc5, 0x88, 0x03, 0xc1, 0x4b, 0xa0, 0x64, 0x0a, 0xf7, - 0x2b, 0xf9, 0x73, 0xd2, 0x5a, 0xbe, 0x79, 0x5a, 0x68, 0x95, 0xdc, 0x61, 0x21, 0x4f, 0x43, 0x7e, - 0x28, 0x81, 0xe5, 0xf8, 0xb8, 0xb7, 0x15, 0x8b, 0xc2, 0x1f, 0xc5, 0xc6, 0x5e, 0xcf, 0x36, 0x76, - 0x66, 0xcd, 0x47, 0xee, 0x75, 0xec, 0xb6, 0x04, 0xc6, 0xdd, 0x02, 0x45, 0x85, 0x92, 0x9e, 0x55, - 0xc9, 0x9d, 0xcb, 0xaf, 0xcd, 0xae, 0x5f, 0xac, 0xa7, 0x04, 0x70, 0x3d, 0xee, 0x5d, 0x73, 0x4e, - 0xe0, 0x16, 0x6f, 0x31, 0x04, 0xe4, 0x00, 0xc9, 0xbf, 0xc8, 0x81, 0xf2, 0x16, 0x26, 0x3d, 0x5d, - 0xdb, 0x23, 0xf4, 0x04, 0x56, 0xee, 0x26, 0x28, 0x58, 0x06, 0x69, 0x8b, 0x95, 0xbb, 0x90, 0x3a, - 0x00, 0xcf, 0xa7, 0x3d, 0x83, 0xb4, 0xfd, 0x25, 0x63, 0x5f, 0x88, 0x23, 0xc0, 0x16, 0x98, 0xb6, - 0x28, 0xa6, 0xb6, 0xc5, 0x17, 0x6c, 0x76, 0x7d, 0x2d, 0x03, 0x16, 0xd7, 0x6f, 0xce, 0x0b, 0xb4, - 0x69, 0xe7, 0x1b, 0x09, 0x1c, 0xf9, 0xef, 0x39, 0x00, 0x3d, 0xdd, 0x4d, 0x5d, 0xeb, 0x28, 0x94, - 0x85, 0xf3, 0x35, 0x50, 0xa0, 0x03, 0x83, 0xf0, 0x09, 0x29, 0x37, 0x2f, 0xb8, 0xae, 0xdc, 0x19, - 0x18, 0xe4, 0xf1, 0xb0, 0xb6, 0x1c, 0xb7, 0x60, 0x12, 0xc4, 0x6d, 0xe0, 0xb6, 0xe7, 0x64, 0x8e, - 0x5b, 0xbf, 0x12, 0xee, 0xfa, 0xf1, 0xb0, 0x96, 0xb0, 0x77, 0xd4, 0x3d, 0xa4, 0xb0, 0x83, 0xb0, - 0x0f, 0xa0, 0x8a, 0x2d, 0x7a, 0xc7, 0xc4, 0x9a, 0xe5, 0xf4, 0xa4, 0xf4, 0x88, 0x18, 0xfe, 0x4b, - 0xd9, 0x16, 0x8a, 0x59, 0x34, 0x57, 0x85, 0x17, 0x70, 0x3b, 0x86, 0x86, 0x12, 0x7a, 0x80, 0x17, - 0xc0, 0xb4, 0x49, 0xb0, 0xa5, 0x6b, 0x95, 0x02, 0x1f, 0x85, 0x37, 0x81, 0x88, 0xb7, 0x22, 0x21, - 0x85, 0x2f, 0x82, 0x99, 0x1e, 0xb1, 0x2c, 0xdc, 0x25, 0x95, 0x22, 0x57, 0x5c, 0x10, 0x8a, 0x33, - 0x3b, 0x4e, 0x33, 0x72, 0xe5, 0xf2, 0xef, 0x25, 0x30, 0xe7, 0xcd, 0xdc, 0x09, 0x64, 0xce, 0x8d, - 0x70, 0xe6, 0xc8, 0xe3, 0x83, 0x25, 0x25, 0x61, 0x3e, 0xce, 0x07, 0x1c, 0x67, 0xe1, 0x08, 0x7f, - 0x0c, 0x4a, 0x16, 0x51, 0x49, 0x9b, 0xea, 0xa6, 0x70, 0xfc, 0xe5, 0x8c, 0x8e, 0xe3, 0x03, 0xa2, - 0xee, 0x09, 0xd3, 0xe6, 0x29, 0xe6, 0xb9, 0xfb, 0x85, 0x3c, 0x48, 0xf8, 0x2e, 0x28, 0x51, 0xd2, - 0x33, 0x54, 0x4c, 0x89, 0xc8, 0x9a, 0xe7, 0x83, 0xce, 0xb3, 0x98, 0x61, 0x60, 0x2d, 0xbd, 0x73, - 0x47, 0xa8, 0xf1, 0x94, 0xf1, 0x26, 0xc3, 0x6d, 0x45, 0x1e, 0x0c, 0x34, 0xc0, 0xbc, 0x6d, 0x74, - 0x98, 0x26, 0x65, 0xdb, 0x79, 0x77, 0x20, 0x62, 0xe8, 0xca, 0xf8, 0x59, 0xd9, 0x0f, 0xd9, 0x35, - 0x97, 0x45, 0x2f, 0xf3, 0xe1, 0x76, 0x14, 0xc1, 0x87, 0x1b, 0x60, 0xa1, 0xa7, 0x68, 0x88, 0xe0, - 0xce, 0x60, 0x8f, 0xb4, 0x75, 0xad, 0x63, 0xf1, 0x50, 0x2a, 0x36, 0x57, 0x04, 0xc0, 0xc2, 0x4e, - 0x58, 0x8c, 0xa2, 0xfa, 0x70, 0x1b, 0x2c, 0xb9, 0x1b, 0xf0, 0x4d, 0xc5, 0xa2, 0xba, 0x39, 0xd8, - 0x56, 0x7a, 0x0a, 0xad, 0x4c, 0x73, 0x9c, 0xca, 0x68, 0x58, 0x5b, 0x42, 0x09, 0x72, 0x94, 0x68, - 0x25, 0xff, 0x66, 0x1a, 0x2c, 0x44, 0xf6, 0x05, 0x78, 0x17, 0x2c, 0xb7, 0x6d, 0xd3, 0x24, 0x1a, - 0xdd, 0xb5, 0x7b, 0x07, 0xc4, 0xdc, 0x6b, 0x1f, 0x92, 0x8e, 0xad, 0x92, 0x0e, 0x5f, 0xd6, 0x62, - 0xb3, 0x2a, 0x7c, 0x5d, 0xde, 0x4c, 0xd4, 0x42, 0x29, 0xd6, 0xf0, 0x1d, 0x00, 0x35, 0xde, 0xb4, - 0xa3, 0x58, 0x96, 0x87, 0x99, 0xe3, 0x98, 0x5e, 0x2a, 0xee, 0xc6, 0x34, 0x50, 0x82, 0x15, 0xf3, - 0xb1, 0x43, 0x2c, 0xc5, 0x24, 0x9d, 0xa8, 0x8f, 0xf9, 0xb0, 0x8f, 0x5b, 0x89, 0x5a, 0x28, 0xc5, - 0x1a, 0xbe, 0x0a, 0x66, 0x9d, 0xde, 0xf8, 0x9c, 0x8b, 0xc5, 0x59, 0x14, 0x60, 0xb3, 0xbb, 0xbe, - 0x08, 0x05, 0xf5, 0xd8, 0xd0, 0xf4, 0x03, 0x8b, 0x98, 0x7d, 0xd2, 0xb9, 0xe1, 0x90, 0x03, 0x56, - 0x41, 0x8b, 0xbc, 0x82, 0x7a, 0x43, 0xbb, 0x1d, 0xd3, 0x40, 0x09, 0x56, 0x6c, 0x68, 0x4e, 0xd4, - 0xc4, 0x86, 0x36, 0x1d, 0x1e, 0xda, 0x7e, 0xa2, 0x16, 0x4a, 0xb1, 0x66, 0xb1, 0xe7, 0xb8, 0xbc, - 0xd1, 0xc7, 0x8a, 0x8a, 0x0f, 0x54, 0x52, 0x99, 0x09, 0xc7, 0xde, 0x6e, 0x58, 0x8c, 0xa2, 0xfa, - 0xf0, 0x06, 0x38, 0xe3, 0x34, 0xed, 0x6b, 0xd8, 0x03, 0x29, 0x71, 0x90, 0xe7, 0x04, 0xc8, 0x99, - 0xdd, 0xa8, 0x02, 0x8a, 0xdb, 0xc0, 0x6b, 0x60, 0xbe, 0xad, 0xab, 0x2a, 0x8f, 0xc7, 0x4d, 0xdd, - 0xd6, 0x68, 0xa5, 0xcc, 0x51, 0x20, 0xcb, 0xa1, 0xcd, 0x90, 0x04, 0x45, 0x34, 0xe1, 0x4f, 0x01, - 0x68, 0xbb, 0x85, 0xc1, 0xaa, 0x80, 0x31, 0x0c, 0x20, 0x5e, 0x96, 0xfc, 0xca, 0xec, 0x35, 0x59, - 0x28, 0x00, 0x29, 0x7f, 0x2c, 0x81, 0x95, 0x94, 0x44, 0x87, 0x6f, 0x85, 0x8a, 0xe0, 0xc5, 0x48, - 0x11, 0x3c, 0x9b, 0x62, 0x16, 0xa8, 0x84, 0x87, 0x60, 0x8e, 0x11, 0x12, 0x45, 0xeb, 0x3a, 0x2a, - 0x62, 0x2f, 0x6b, 0xa4, 0x0e, 0x00, 0x05, 0xb5, 0xfd, 0x5d, 0xf9, 0xcc, 0x68, 0x58, 0x9b, 0x0b, - 0xc9, 0x50, 0x18, 0x58, 0xfe, 0x65, 0x0e, 0x80, 0x2d, 0x62, 0xa8, 0xfa, 0xa0, 0x47, 0xb4, 0x93, - 0xe0, 0x34, 0xb7, 0x42, 0x9c, 0xe6, 0x85, 0xf4, 0x25, 0xf1, 0x9c, 0x4a, 0x25, 0x35, 0xef, 0x46, - 0x48, 0xcd, 0x8b, 0x59, 0xc0, 0x9e, 0xcc, 0x6a, 0x3e, 0xcb, 0x83, 0x45, 0x5f, 0xd9, 0xa7, 0x35, - 0xd7, 0x43, 0x2b, 0xfa, 0x42, 0x64, 0x45, 0x57, 0x12, 0x4c, 0x9e, 0x19, 0xaf, 0xf9, 0x00, 0xcc, - 0x33, 0xd6, 0xe1, 0xac, 0x1f, 0xe7, 0x34, 0xd3, 0x13, 0x73, 0x1a, 0xaf, 0x12, 0x6d, 0x87, 0x90, - 0x50, 0x04, 0x39, 0x85, 0x43, 0xcd, 0x7c, 0x1d, 0x39, 0xd4, 0x1f, 0x24, 0x30, 0xef, 0x2f, 0xd3, - 0x09, 0x90, 0xa8, 0x9b, 0x61, 0x12, 0xf5, 0x7c, 0x86, 0xe0, 0x4c, 0x61, 0x51, 0x9f, 0x15, 0x82, - 0xae, 0x73, 0x1a, 0xb5, 0xc6, 0x8e, 0x60, 0x86, 0xaa, 0xb4, 0xb1, 0x25, 0xea, 0xed, 0x29, 0xe7, - 0xf8, 0xe5, 0xb4, 0x21, 0x4f, 0x1a, 0x22, 0x5c, 0xb9, 0x67, 0x4b, 0xb8, 0xf2, 0x4f, 0x87, 0x70, - 0xfd, 0x10, 0x94, 0x2c, 0x97, 0x6a, 0x15, 0x38, 0xe4, 0xc5, 0x4c, 0x89, 0x2d, 0x58, 0x96, 0x07, - 0xed, 0xf1, 0x2b, 0x0f, 0x2e, 0x89, 0x59, 0x15, 0xbf, 0x4a, 0x66, 0xc5, 0x02, 0xdd, 0xc0, 0xb6, - 0x45, 0x3a, 0x3c, 0xa9, 0x4a, 0x7e, 0xa0, 0xb7, 0x78, 0x2b, 0x12, 0x52, 0xb8, 0x0f, 0x56, 0x0c, - 0x53, 0xef, 0x9a, 0xc4, 0xb2, 0xb6, 0x08, 0xee, 0xa8, 0x8a, 0x46, 0xdc, 0x01, 0x38, 0x35, 0xf1, - 0xec, 0x68, 0x58, 0x5b, 0x69, 0x25, 0xab, 0xa0, 0x34, 0x5b, 0xf9, 0xcf, 0x05, 0x70, 0x3a, 0xba, - 0x37, 0xa6, 0xd0, 0x14, 0xe9, 0x58, 0x34, 0xe5, 0x52, 0x20, 0x4e, 0x1d, 0x0e, 0x17, 0xb8, 0x2a, - 0x88, 0xc5, 0xea, 0x06, 0x58, 0x10, 0xb4, 0xc4, 0x15, 0x0a, 0xa2, 0xe6, 0x2d, 0xcf, 0x7e, 0x58, - 0x8c, 0xa2, 0xfa, 0xf0, 0x3a, 0x98, 0x33, 0x39, 0xf3, 0x72, 0x01, 0x1c, 0xf6, 0xf2, 0x7f, 0x02, - 0x60, 0x0e, 0x05, 0x85, 0x28, 0xac, 0xcb, 0x98, 0x8b, 0x4f, 0x48, 0x5c, 0x80, 0x42, 0x98, 0xb9, - 0x6c, 0x44, 0x15, 0x50, 0xdc, 0x06, 0xee, 0x80, 0x45, 0x5b, 0x8b, 0x43, 0x39, 0xb1, 0x76, 0x56, - 0x40, 0x2d, 0xee, 0xc7, 0x55, 0x50, 0x92, 0x1d, 0xbc, 0x17, 0x22, 0x33, 0xd3, 0x7c, 0x3f, 0xb9, - 0x94, 0x21, 0x27, 0x32, 0xb3, 0x99, 0x04, 0xaa, 0x55, 0xca, 0x4a, 0xb5, 0xe4, 0x8f, 0x24, 0x00, - 0xe3, 0x79, 0x38, 0xf6, 0x26, 0x20, 0x66, 0x11, 0xa8, 0x98, 0x4a, 0x32, 0xff, 0xb9, 0x92, 0x91, - 0xff, 0xf8, 0x1b, 0x6a, 0x36, 0x02, 0x24, 0x26, 0xfa, 0x64, 0x2e, 0x75, 0xb2, 0x12, 0x20, 0xdf, - 0xa9, 0xa7, 0x40, 0x80, 0x02, 0x60, 0x4f, 0x26, 0x40, 0xff, 0xc8, 0x81, 0x45, 0x5f, 0x39, 0x33, - 0x01, 0x4a, 0x30, 0xf9, 0xf6, 0x62, 0x27, 0x1b, 0x29, 0xf1, 0xa7, 0xee, 0x7f, 0x89, 0x94, 0xf8, - 0x5e, 0xa5, 0x90, 0x92, 0xdf, 0xe5, 0x82, 0xae, 0x4f, 0x48, 0x4a, 0x9e, 0xc2, 0x0d, 0xc7, 0xd7, - 0x8e, 0xd7, 0xc8, 0x9f, 0xe4, 0xc1, 0xe9, 0x68, 0x1e, 0x86, 0x0a, 0xa4, 0x34, 0xb6, 0x40, 0xb6, - 0xc0, 0xd2, 0x7d, 0x5b, 0x55, 0x07, 0x7c, 0x0c, 0x81, 0x2a, 0xe9, 0x94, 0xd6, 0xff, 0x17, 0x96, - 0x4b, 0x3f, 0x48, 0xd0, 0x41, 0x89, 0x96, 0xf1, 0x7a, 0x59, 0xf8, 0xb2, 0xf5, 0xb2, 0x78, 0x8c, - 0x7a, 0x99, 0x4c, 0x39, 0xf2, 0xc7, 0xa2, 0x1c, 0x93, 0x15, 0xcb, 0x84, 0x8d, 0x6b, 0xec, 0xd1, - 0x7f, 0x24, 0x81, 0xe5, 0xe4, 0x03, 0x37, 0x54, 0xc1, 0x7c, 0x0f, 0x3f, 0x08, 0x5e, 0x7c, 0x8c, - 0x2b, 0x22, 0x36, 0x55, 0xd4, 0xba, 0xf3, 0x64, 0x54, 0xbf, 0xa5, 0xd1, 0xdb, 0xe6, 0x1e, 0x35, - 0x15, 0xad, 0xeb, 0x54, 0xde, 0x9d, 0x10, 0x16, 0x8a, 0x60, 0xc3, 0xf7, 0x41, 0xa9, 0x87, 0x1f, - 0xec, 0xd9, 0x66, 0x37, 0xa9, 0x42, 0x66, 0xeb, 0x87, 0x27, 0xc0, 0x8e, 0x40, 0x41, 0x1e, 0x9e, - 0xfc, 0x85, 0x04, 0x56, 0x52, 0xaa, 0xea, 0x37, 0x68, 0x94, 0x7f, 0x92, 0xc0, 0xb9, 0xd0, 0x28, - 0x59, 0x5a, 0x92, 0xfb, 0xb6, 0xca, 0x33, 0x54, 0x30, 0x99, 0x8b, 0xa0, 0x6c, 0x60, 0x93, 0x2a, - 0x1e, 0x0f, 0x2e, 0x36, 0xe7, 0x46, 0xc3, 0x5a, 0xb9, 0xe5, 0x36, 0x22, 0x5f, 0x9e, 0x30, 0x37, - 0xb9, 0x67, 0x37, 0x37, 0xf2, 0x7f, 0x24, 0x50, 0xdc, 0x6b, 0x63, 0x95, 0x9c, 0x00, 0x71, 0xd9, - 0x0a, 0x11, 0x97, 0xf4, 0x47, 0x01, 0xee, 0x4f, 0x2a, 0x67, 0xd9, 0x8e, 0x70, 0x96, 0xf3, 0x63, - 0x70, 0x9e, 0x4c, 0x57, 0xde, 0x00, 0x65, 0xaf, 0xbb, 0xc9, 0xf6, 0x52, 0xf9, 0xb7, 0x39, 0x30, - 0x1b, 0xe8, 0x62, 0xc2, 0x9d, 0xf8, 0x5e, 0xa8, 0xfc, 0xb0, 0x3d, 0x66, 0x3d, 0xcb, 0x40, 0xea, - 0x6e, 0xa9, 0x79, 0x5b, 0xa3, 0x66, 0xf0, 0xac, 0x1a, 0xaf, 0x40, 0x6f, 0x82, 0x79, 0x8a, 0xcd, - 0x2e, 0xa1, 0xae, 0x8c, 0x4f, 0x58, 0xd9, 0xbf, 0xbb, 0xb9, 0x13, 0x92, 0xa2, 0x88, 0xf6, 0xea, - 0x75, 0x30, 0x17, 0xea, 0x0c, 0x9e, 0x06, 0xf9, 0x23, 0x32, 0x70, 0x18, 0x1c, 0x62, 0x3f, 0xe1, - 0x12, 0x28, 0xf6, 0xb1, 0x6a, 0x3b, 0x21, 0x5a, 0x46, 0xce, 0xc7, 0xb5, 0xdc, 0xeb, 0x92, 0xfc, - 0x2b, 0x36, 0x39, 0x7e, 0x2a, 0x9c, 0x40, 0x74, 0xbd, 0x13, 0x8a, 0xae, 0xf4, 0xf7, 0xc9, 0x60, - 0x82, 0xa6, 0xc5, 0x18, 0x8a, 0xc4, 0xd8, 0x4b, 0x99, 0xd0, 0x9e, 0x1c, 0x69, 0xff, 0xcc, 0x81, - 0xa5, 0x80, 0xb6, 0xcf, 0x8c, 0xbf, 0x1b, 0x62, 0xc6, 0x6b, 0x11, 0x66, 0x5c, 0x49, 0xb2, 0xf9, - 0x96, 0x1a, 0x8f, 0xa7, 0xc6, 0x7f, 0x94, 0xc0, 0x42, 0x60, 0xee, 0x4e, 0x80, 0x1b, 0xdf, 0x0a, - 0x73, 0xe3, 0xf3, 0x59, 0x82, 0x26, 0x85, 0x1c, 0xff, 0x4b, 0x02, 0x8d, 0x80, 0x56, 0x8b, 0x98, - 0x96, 0x62, 0x51, 0xa2, 0xd1, 0xbb, 0xba, 0x6a, 0xf7, 0xc8, 0xa6, 0x8a, 0x95, 0x1e, 0x22, 0xac, - 0x41, 0xd1, 0xb5, 0x96, 0xae, 0x2a, 0xed, 0x01, 0xc4, 0x60, 0xf6, 0xc3, 0x43, 0xa2, 0x6d, 0x11, - 0x95, 0x50, 0xf1, 0x8a, 0x56, 0x6e, 0xbe, 0xe5, 0x3e, 0x2a, 0xbd, 0xe7, 0x8b, 0x1e, 0x0f, 0x6b, - 0x6b, 0x59, 0x10, 0x79, 0x94, 0x05, 0x31, 0xe1, 0x4f, 0x00, 0x60, 0x9f, 0x7c, 0x3f, 0xea, 0x88, - 0x80, 0x7b, 0xd3, 0xcd, 0xca, 0xf7, 0x3c, 0xc9, 0x44, 0x1d, 0x04, 0x10, 0xe5, 0xbf, 0xce, 0x84, - 0xd6, 0xec, 0x1b, 0x7f, 0x53, 0xf9, 0x33, 0xb0, 0xd4, 0xf7, 0x67, 0xc7, 0x55, 0x60, 0x1c, 0x3a, - 0x1f, 0x3d, 0x8d, 0x7b, 0xf0, 0x49, 0xf3, 0xea, 0x33, 0xf7, 0xbb, 0x09, 0x70, 0x28, 0xb1, 0x13, - 0xf8, 0x2a, 0x98, 0x65, 0xdc, 0x57, 0x69, 0x93, 0x5d, 0xdc, 0x73, 0xf3, 0xc9, 0x7b, 0x84, 0xdc, - 0xf3, 0x45, 0x28, 0xa8, 0x07, 0x0f, 0xc1, 0xa2, 0xa1, 0x77, 0x76, 0xb0, 0x86, 0xbb, 0x84, 0x91, - 0x39, 0x67, 0x29, 0xf9, 0xf5, 0x65, 0xb9, 0xf9, 0x9a, 0x7b, 0x35, 0xd5, 0x8a, 0xab, 0xb0, 0x63, - 0x7e, 0x42, 0x33, 0x0f, 0x82, 0x24, 0x48, 0x68, 0xc6, 0x1e, 0xce, 0x9d, 0x87, 0x83, 0xf5, 0x2c, - 0x89, 0x75, 0xcc, 0xa7, 0xf3, 0xb4, 0xdb, 0xd9, 0xd2, 0xb1, 0x6e, 0x67, 0x13, 0x8e, 0xa9, 0xe5, - 0x09, 0x8f, 0xa9, 0x9f, 0x48, 0xe0, 0xbc, 0x91, 0x21, 0x97, 0x2a, 0x80, 0xcf, 0xcd, 0xcd, 0x2c, - 0x73, 0x93, 0x25, 0x37, 0x9b, 0x6b, 0xa3, 0x61, 0xed, 0x7c, 0x16, 0x4d, 0x94, 0xc9, 0x3f, 0xf9, - 0xa3, 0x22, 0x38, 0x13, 0xab, 0x96, 0x5f, 0xe1, 0x5d, 0x71, 0xec, 0xe0, 0x9a, 0x9f, 0xe0, 0xe0, - 0xba, 0x01, 0x16, 0xc4, 0xdf, 0x0f, 0x22, 0xe7, 0x5e, 0x6f, 0x61, 0x37, 0xc3, 0x62, 0x14, 0xd5, - 0x4f, 0xba, 0xab, 0x2e, 0x4e, 0x78, 0x57, 0x1d, 0xf4, 0x42, 0xfc, 0x9d, 0xce, 0x49, 0xc3, 0xb8, - 0x17, 0xe2, 0x5f, 0x75, 0x51, 0x7d, 0x46, 0x12, 0x1d, 0x54, 0x0f, 0x61, 0x26, 0x4c, 0x12, 0xf7, - 0x43, 0x52, 0x14, 0xd1, 0xfe, 0x52, 0x4f, 0xec, 0x38, 0xe1, 0x89, 0xfd, 0x72, 0x96, 0xf8, 0xcd, - 0x7e, 0x2d, 0x9d, 0x78, 0xc1, 0x30, 0x3b, 0xf9, 0x05, 0x83, 0xfc, 0x17, 0x09, 0x3c, 0x97, 0xba, - 0xbb, 0xc0, 0x8d, 0x10, 0x85, 0xbb, 0x1c, 0xa1, 0x70, 0xdf, 0x49, 0x35, 0x0c, 0xf0, 0x38, 0x33, - 0xf9, 0xc6, 0xfa, 0x8d, 0x6c, 0x37, 0xd6, 0x09, 0xa7, 0xce, 0xf1, 0x57, 0xd7, 0xcd, 0xef, 0x3d, - 0x7c, 0x54, 0x9d, 0xfa, 0xf4, 0x51, 0x75, 0xea, 0xf3, 0x47, 0xd5, 0xa9, 0x9f, 0x8f, 0xaa, 0xd2, - 0xc3, 0x51, 0x55, 0xfa, 0x74, 0x54, 0x95, 0x3e, 0x1f, 0x55, 0xa5, 0xbf, 0x8d, 0xaa, 0xd2, 0xaf, - 0xbf, 0xa8, 0x4e, 0xbd, 0xbf, 0x92, 0xf2, 0x07, 0xdf, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5c, - 0xbc, 0x64, 0x9c, 0x13, 0x2c, 0x00, 0x00, + // 2345 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xf7, 0xf2, 0x43, 0x26, 0x87, 0x96, 0x64, 0x8f, 0x54, 0x89, 0x91, 0x5b, 0xd2, 0x58, 0x1b, + 0x8e, 0x12, 0xdb, 0xa4, 0xad, 0x7c, 0x20, 0xb1, 0xdb, 0xa4, 0xa2, 0x94, 0xda, 0x0e, 0xf4, 0xc1, + 0x0c, 0x2d, 0x07, 0x0d, 0xfa, 0xe1, 0x11, 0x39, 0xa6, 0x36, 0x5a, 0xee, 0x2e, 0x76, 0x87, 0x8c, + 0x89, 0x5e, 0x7a, 0x2d, 0x50, 0xa0, 0xed, 0xb5, 0xff, 0x44, 0xd1, 0x4b, 0x51, 0x34, 0xe8, 0xa5, + 0x08, 0x02, 0x1f, 0x83, 0x5e, 0x92, 0x13, 0x51, 0x33, 0xa7, 0xa2, 0xe8, 0xad, 0xbd, 0x18, 0x28, + 0x50, 0xcc, 0xec, 0xec, 0xf7, 0xae, 0xb9, 0x54, 0x6c, 0xe5, 0x03, 0xb9, 0x71, 0xe7, 0xbd, 0xf7, + 0x9b, 0x37, 0x33, 0xef, 0xcd, 0xfb, 0xcd, 0x0c, 0xc1, 0x0f, 0x0f, 0x5f, 0xb3, 0x6a, 0x8a, 0x5e, + 0x3f, 0xec, 0xef, 0x13, 0x53, 0x23, 0x94, 0x58, 0xf5, 0x01, 0xd1, 0x3a, 0xba, 0x59, 0x17, 0x02, + 0x6c, 0x28, 0x75, 0x6c, 0x18, 0x56, 0x7d, 0x70, 0x6d, 0x9f, 0x50, 0xbc, 0x56, 0xef, 0x12, 0x8d, + 0x98, 0x98, 0x92, 0x4e, 0xcd, 0x30, 0x75, 0xaa, 0xc3, 0x65, 0x5b, 0xb1, 0x86, 0x0d, 0xa5, 0xc6, + 0x14, 0x6b, 0x42, 0x71, 0xe5, 0x4a, 0x57, 0xa1, 0x07, 0xfd, 0xfd, 0x5a, 0x5b, 0xef, 0xd5, 0xbb, + 0x7a, 0x57, 0xaf, 0x73, 0xfd, 0xfd, 0xfe, 0x7d, 0xfe, 0xc5, 0x3f, 0xf8, 0x2f, 0x1b, 0x67, 0x45, + 0xf6, 0x75, 0xd8, 0xd6, 0x4d, 0x52, 0x1f, 0x5c, 0x0b, 0xf7, 0xb5, 0xf2, 0xb2, 0xa7, 0xd3, 0xc3, + 0xed, 0x03, 0x45, 0x23, 0xe6, 0xb0, 0x6e, 0x1c, 0x76, 0x59, 0x83, 0x55, 0xef, 0x11, 0x8a, 0xe3, + 0xac, 0xea, 0x49, 0x56, 0x66, 0x5f, 0xa3, 0x4a, 0x8f, 0x44, 0x0c, 0x5e, 0x9d, 0x64, 0x60, 0xb5, + 0x0f, 0x48, 0x0f, 0x47, 0xec, 0x5e, 0x4a, 0xb2, 0xeb, 0x53, 0x45, 0xad, 0x2b, 0x1a, 0xb5, 0xa8, + 0x19, 0x36, 0x92, 0xff, 0x2b, 0x01, 0xb8, 0xa1, 0x6b, 0xd4, 0xd4, 0x55, 0x95, 0x98, 0x88, 0x0c, + 0x14, 0x4b, 0xd1, 0x35, 0x78, 0x0f, 0x14, 0xd8, 0x78, 0x3a, 0x98, 0xe2, 0xb2, 0x74, 0x4e, 0x5a, + 0x2d, 0xad, 0x5d, 0xad, 0x79, 0x33, 0xed, 0xc2, 0xd7, 0x8c, 0xc3, 0x2e, 0x6b, 0xb0, 0x6a, 0x4c, + 0xbb, 0x36, 0xb8, 0x56, 0xdb, 0xdd, 0x7f, 0x9f, 0xb4, 0xe9, 0x36, 0xa1, 0xb8, 0x01, 0x1f, 0x8e, + 0xaa, 0x27, 0xc6, 0xa3, 0x2a, 0xf0, 0xda, 0x90, 0x8b, 0x0a, 0x77, 0x41, 0x8e, 0xa3, 0x67, 0x38, + 0xfa, 0x95, 0x44, 0x74, 0x31, 0xe8, 0x1a, 0xc2, 0x1f, 0xbc, 0xf5, 0x80, 0x12, 0x8d, 0xb9, 0xd7, + 0x38, 0x25, 0xa0, 0x73, 0x9b, 0x98, 0x62, 0xc4, 0x81, 0xe0, 0x65, 0x50, 0x30, 0x85, 0xfb, 0xe5, + 0xec, 0x39, 0x69, 0x35, 0xdb, 0x38, 0x2d, 0xb4, 0x0a, 0xce, 0xb0, 0x90, 0xab, 0x21, 0x3f, 0x94, + 0xc0, 0x52, 0x74, 0xdc, 0x5b, 0x8a, 0x45, 0xe1, 0x4f, 0x22, 0x63, 0xaf, 0xa5, 0x1b, 0x3b, 0xb3, + 0xe6, 0x23, 0x77, 0x3b, 0x76, 0x5a, 0x7c, 0xe3, 0x6e, 0x82, 0xbc, 0x42, 0x49, 0xcf, 0x2a, 0x67, + 0xce, 0x65, 0x57, 0x4b, 0x6b, 0x97, 0x6a, 0x09, 0x01, 0x5c, 0x8b, 0x7a, 0xd7, 0x98, 0x15, 0xb8, + 0xf9, 0xdb, 0x0c, 0x01, 0xd9, 0x40, 0xf2, 0xaf, 0x32, 0xa0, 0xb8, 0x89, 0x49, 0x4f, 0xd7, 0x5a, + 0x84, 0x1e, 0xc3, 0xca, 0xdd, 0x02, 0x39, 0xcb, 0x20, 0x6d, 0xb1, 0x72, 0x17, 0x13, 0x07, 0xe0, + 0xfa, 0xd4, 0x32, 0x48, 0xdb, 0x5b, 0x32, 0xf6, 0x85, 0x38, 0x02, 0x6c, 0x82, 0x19, 0x8b, 0x62, + 0xda, 0xb7, 0xf8, 0x82, 0x95, 0xd6, 0x56, 0x53, 0x60, 0x71, 0xfd, 0xc6, 0x9c, 0x40, 0x9b, 0xb1, + 0xbf, 0x91, 0xc0, 0x91, 0xff, 0x99, 0x01, 0xd0, 0xd5, 0xdd, 0xd0, 0xb5, 0x8e, 0x42, 0x59, 0x38, + 0x5f, 0x07, 0x39, 0x3a, 0x34, 0x08, 0x9f, 0x90, 0x62, 0xe3, 0xa2, 0xe3, 0xca, 0x9d, 0xa1, 0x41, + 0x1e, 0x8f, 0xaa, 0x4b, 0x51, 0x0b, 0x26, 0x41, 0xdc, 0x06, 0x6e, 0xb9, 0x4e, 0x66, 0xb8, 0xf5, + 0xcb, 0xc1, 0xae, 0x1f, 0x8f, 0xaa, 0x31, 0x7b, 0x47, 0xcd, 0x45, 0x0a, 0x3a, 0x08, 0x07, 0x00, + 0xaa, 0xd8, 0xa2, 0x77, 0x4c, 0xac, 0x59, 0x76, 0x4f, 0x4a, 0x8f, 0x88, 0xe1, 0xbf, 0x98, 0x6e, + 0xa1, 0x98, 0x45, 0x63, 0x45, 0x78, 0x01, 0xb7, 0x22, 0x68, 0x28, 0xa6, 0x07, 0x78, 0x11, 0xcc, + 0x98, 0x04, 0x5b, 0xba, 0x56, 0xce, 0xf1, 0x51, 0xb8, 0x13, 0x88, 0x78, 0x2b, 0x12, 0x52, 0xf8, + 0x02, 0x38, 0xd9, 0x23, 0x96, 0x85, 0xbb, 0xa4, 0x9c, 0xe7, 0x8a, 0xf3, 0x42, 0xf1, 0xe4, 0xb6, + 0xdd, 0x8c, 0x1c, 0xb9, 0xfc, 0x27, 0x09, 0xcc, 0xba, 0x33, 0x77, 0x0c, 0x99, 0x73, 0x33, 0x98, + 0x39, 0xf2, 0xe4, 0x60, 0x49, 0x48, 0x98, 0x8f, 0xb2, 0x3e, 0xc7, 0x59, 0x38, 0xc2, 0x9f, 0x82, + 0x82, 0x45, 0x54, 0xd2, 0xa6, 0xba, 0x29, 0x1c, 0x7f, 0x29, 0xa5, 0xe3, 0x78, 0x9f, 0xa8, 0x2d, + 0x61, 0xda, 0x38, 0xc5, 0x3c, 0x77, 0xbe, 0x90, 0x0b, 0x09, 0xdf, 0x01, 0x05, 0x4a, 0x7a, 0x86, + 0x8a, 0x29, 0x11, 0x59, 0x73, 0xde, 0xef, 0x3c, 0x8b, 0x19, 0x06, 0xd6, 0xd4, 0x3b, 0x77, 0x84, + 0x1a, 0x4f, 0x19, 0x77, 0x32, 0x9c, 0x56, 0xe4, 0xc2, 0x40, 0x03, 0xcc, 0xf5, 0x8d, 0x0e, 0xd3, + 0xa4, 0x6c, 0x3b, 0xef, 0x0e, 0x45, 0x0c, 0x5d, 0x9d, 0x3c, 0x2b, 0x7b, 0x01, 0xbb, 0xc6, 0x92, + 0xe8, 0x65, 0x2e, 0xd8, 0x8e, 0x42, 0xf8, 0x70, 0x1d, 0xcc, 0xf7, 0x14, 0x0d, 0x11, 0xdc, 0x19, + 0xb6, 0x48, 0x5b, 0xd7, 0x3a, 0x16, 0x0f, 0xa5, 0x7c, 0x63, 0x59, 0x00, 0xcc, 0x6f, 0x07, 0xc5, + 0x28, 0xac, 0x0f, 0xb7, 0xc0, 0xa2, 0xb3, 0x01, 0xdf, 0x52, 0x2c, 0xaa, 0x9b, 0xc3, 0x2d, 0xa5, + 0xa7, 0xd0, 0xf2, 0x0c, 0xc7, 0x29, 0x8f, 0x47, 0xd5, 0x45, 0x14, 0x23, 0x47, 0xb1, 0x56, 0xf2, + 0xef, 0x66, 0xc0, 0x7c, 0x68, 0x5f, 0x80, 0x77, 0xc1, 0x52, 0xbb, 0x6f, 0x9a, 0x44, 0xa3, 0x3b, + 0xfd, 0xde, 0x3e, 0x31, 0x5b, 0xed, 0x03, 0xd2, 0xe9, 0xab, 0xa4, 0xc3, 0x97, 0x35, 0xdf, 0xa8, + 0x08, 0x5f, 0x97, 0x36, 0x62, 0xb5, 0x50, 0x82, 0x35, 0x7c, 0x1b, 0x40, 0x8d, 0x37, 0x6d, 0x2b, + 0x96, 0xe5, 0x62, 0x66, 0x38, 0xa6, 0x9b, 0x8a, 0x3b, 0x11, 0x0d, 0x14, 0x63, 0xc5, 0x7c, 0xec, + 0x10, 0x4b, 0x31, 0x49, 0x27, 0xec, 0x63, 0x36, 0xe8, 0xe3, 0x66, 0xac, 0x16, 0x4a, 0xb0, 0x86, + 0xaf, 0x80, 0x92, 0xdd, 0x1b, 0x9f, 0x73, 0xb1, 0x38, 0x0b, 0x02, 0xac, 0xb4, 0xe3, 0x89, 0x90, + 0x5f, 0x8f, 0x0d, 0x4d, 0xdf, 0xb7, 0x88, 0x39, 0x20, 0x9d, 0x9b, 0x36, 0x39, 0x60, 0x15, 0x34, + 0xcf, 0x2b, 0xa8, 0x3b, 0xb4, 0xdd, 0x88, 0x06, 0x8a, 0xb1, 0x62, 0x43, 0xb3, 0xa3, 0x26, 0x32, + 0xb4, 0x99, 0xe0, 0xd0, 0xf6, 0x62, 0xb5, 0x50, 0x82, 0x35, 0x8b, 0x3d, 0xdb, 0xe5, 0xf5, 0x01, + 0x56, 0x54, 0xbc, 0xaf, 0x92, 0xf2, 0xc9, 0x60, 0xec, 0xed, 0x04, 0xc5, 0x28, 0xac, 0x0f, 0x6f, + 0x82, 0x33, 0x76, 0xd3, 0x9e, 0x86, 0x5d, 0x90, 0x02, 0x07, 0x79, 0x4e, 0x80, 0x9c, 0xd9, 0x09, + 0x2b, 0xa0, 0xa8, 0x0d, 0xbc, 0x0e, 0xe6, 0xda, 0xba, 0xaa, 0xf2, 0x78, 0xdc, 0xd0, 0xfb, 0x1a, + 0x2d, 0x17, 0x39, 0x0a, 0x64, 0x39, 0xb4, 0x11, 0x90, 0xa0, 0x90, 0x26, 0xfc, 0x39, 0x00, 0x6d, + 0xa7, 0x30, 0x58, 0x65, 0x30, 0x81, 0x01, 0x44, 0xcb, 0x92, 0x57, 0x99, 0xdd, 0x26, 0x0b, 0xf9, + 0x20, 0xe5, 0x8f, 0x24, 0xb0, 0x9c, 0x90, 0xe8, 0xf0, 0xcd, 0x40, 0x11, 0xbc, 0x14, 0x2a, 0x82, + 0x67, 0x13, 0xcc, 0x7c, 0x95, 0xf0, 0x00, 0xcc, 0x32, 0x42, 0xa2, 0x68, 0x5d, 0x5b, 0x45, 0xec, + 0x65, 0xf5, 0xc4, 0x01, 0x20, 0xbf, 0xb6, 0xb7, 0x2b, 0x9f, 0x19, 0x8f, 0xaa, 0xb3, 0x01, 0x19, + 0x0a, 0x02, 0xcb, 0xbf, 0xce, 0x00, 0xb0, 0x49, 0x0c, 0x55, 0x1f, 0xf6, 0x88, 0x76, 0x1c, 0x9c, + 0xe6, 0x76, 0x80, 0xd3, 0x3c, 0x9f, 0xbc, 0x24, 0xae, 0x53, 0x89, 0xa4, 0xe6, 0x9d, 0x10, 0xa9, + 0x79, 0x21, 0x0d, 0xd8, 0x93, 0x59, 0xcd, 0xa7, 0x59, 0xb0, 0xe0, 0x29, 0x7b, 0xb4, 0xe6, 0x46, + 0x60, 0x45, 0x9f, 0x0f, 0xad, 0xe8, 0x72, 0x8c, 0xc9, 0x33, 0xe3, 0x35, 0xef, 0x83, 0x39, 0xc6, + 0x3a, 0xec, 0xf5, 0xe3, 0x9c, 0x66, 0x66, 0x6a, 0x4e, 0xe3, 0x56, 0xa2, 0xad, 0x00, 0x12, 0x0a, + 0x21, 0x27, 0x70, 0xa8, 0x93, 0x5f, 0x47, 0x0e, 0xf5, 0x67, 0x09, 0xcc, 0x79, 0xcb, 0x74, 0x0c, + 0x24, 0xea, 0x56, 0x90, 0x44, 0x9d, 0x4f, 0x11, 0x9c, 0x09, 0x2c, 0xea, 0xd3, 0x9c, 0xdf, 0x75, + 0x4e, 0xa3, 0x56, 0xd9, 0x11, 0xcc, 0x50, 0x95, 0x36, 0xb6, 0x44, 0xbd, 0x3d, 0x65, 0x1f, 0xbf, + 0xec, 0x36, 0xe4, 0x4a, 0x03, 0x84, 0x2b, 0xf3, 0x6c, 0x09, 0x57, 0xf6, 0xe9, 0x10, 0xae, 0x1f, + 0x83, 0x82, 0xe5, 0x50, 0xad, 0x1c, 0x87, 0xbc, 0x94, 0x2a, 0xb1, 0x05, 0xcb, 0x72, 0xa1, 0x5d, + 0x7e, 0xe5, 0xc2, 0xc5, 0x31, 0xab, 0xfc, 0x97, 0xc9, 0xac, 0x58, 0xa0, 0x1b, 0xb8, 0x6f, 0x91, + 0x0e, 0x4f, 0xaa, 0x82, 0x17, 0xe8, 0x4d, 0xde, 0x8a, 0x84, 0x14, 0xee, 0x81, 0x65, 0xc3, 0xd4, + 0xbb, 0x26, 0xb1, 0xac, 0x4d, 0x82, 0x3b, 0xaa, 0xa2, 0x11, 0x67, 0x00, 0x76, 0x4d, 0x3c, 0x3b, + 0x1e, 0x55, 0x97, 0x9b, 0xf1, 0x2a, 0x28, 0xc9, 0x56, 0xfe, 0x5b, 0x0e, 0x9c, 0x0e, 0xef, 0x8d, + 0x09, 0x34, 0x45, 0x3a, 0x12, 0x4d, 0xb9, 0xec, 0x8b, 0x53, 0x9b, 0xc3, 0xf9, 0xae, 0x0a, 0x22, + 0xb1, 0xba, 0x0e, 0xe6, 0x05, 0x2d, 0x71, 0x84, 0x82, 0xa8, 0xb9, 0xcb, 0xb3, 0x17, 0x14, 0xa3, + 0xb0, 0x3e, 0xbc, 0x01, 0x66, 0x4d, 0xce, 0xbc, 0x1c, 0x00, 0x9b, 0xbd, 0x7c, 0x47, 0x00, 0xcc, + 0x22, 0xbf, 0x10, 0x05, 0x75, 0x19, 0x73, 0xf1, 0x08, 0x89, 0x03, 0x90, 0x0b, 0x32, 0x97, 0xf5, + 0xb0, 0x02, 0x8a, 0xda, 0xc0, 0x6d, 0xb0, 0xd0, 0xd7, 0xa2, 0x50, 0x76, 0xac, 0x9d, 0x15, 0x50, + 0x0b, 0x7b, 0x51, 0x15, 0x14, 0x67, 0x07, 0xef, 0x05, 0xc8, 0xcc, 0x0c, 0xdf, 0x4f, 0x2e, 0xa7, + 0xc8, 0x89, 0xd4, 0x6c, 0x26, 0x86, 0x6a, 0x15, 0xd2, 0x52, 0x2d, 0xf9, 0x43, 0x09, 0xc0, 0x68, + 0x1e, 0x4e, 0xbc, 0x09, 0x88, 0x58, 0xf8, 0x2a, 0xa6, 0x12, 0xcf, 0x7f, 0xae, 0xa6, 0xe4, 0x3f, + 0xde, 0x86, 0x9a, 0x8e, 0x00, 0x89, 0x89, 0x3e, 0x9e, 0x4b, 0x9d, 0xb4, 0x04, 0xc8, 0x73, 0xea, + 0x29, 0x10, 0x20, 0x1f, 0xd8, 0x93, 0x09, 0xd0, 0xbf, 0x32, 0x60, 0xc1, 0x53, 0x4e, 0x4d, 0x80, + 0x62, 0x4c, 0xbe, 0xbd, 0xd8, 0x49, 0x47, 0x4a, 0xbc, 0xa9, 0xfb, 0x2a, 0x91, 0x12, 0xcf, 0xab, + 0x04, 0x52, 0xf2, 0x87, 0x8c, 0xdf, 0xf5, 0x29, 0x49, 0xc9, 0x53, 0xb8, 0xe1, 0xf8, 0xda, 0xf1, + 0x1a, 0xf9, 0xe3, 0x2c, 0x38, 0x1d, 0xce, 0xc3, 0x40, 0x81, 0x94, 0x26, 0x16, 0xc8, 0x26, 0x58, + 0xbc, 0xdf, 0x57, 0xd5, 0x21, 0x1f, 0x83, 0xaf, 0x4a, 0xda, 0xa5, 0xf5, 0xbb, 0xc2, 0x72, 0xf1, + 0x47, 0x31, 0x3a, 0x28, 0xd6, 0x32, 0x5a, 0x2f, 0x73, 0x5f, 0xb4, 0x5e, 0xe6, 0x8f, 0x50, 0x2f, + 0xe3, 0x29, 0x47, 0xf6, 0x48, 0x94, 0x63, 0xba, 0x62, 0x19, 0xb3, 0x71, 0x4d, 0x3c, 0xfa, 0x8f, + 0x25, 0xb0, 0x14, 0x7f, 0xe0, 0x86, 0x2a, 0x98, 0xeb, 0xe1, 0x07, 0xfe, 0x8b, 0x8f, 0x49, 0x45, + 0xa4, 0x4f, 0x15, 0xb5, 0x66, 0x3f, 0x19, 0xd5, 0x6e, 0x6b, 0x74, 0xd7, 0x6c, 0x51, 0x53, 0xd1, + 0xba, 0x76, 0xe5, 0xdd, 0x0e, 0x60, 0xa1, 0x10, 0x36, 0x7c, 0x0f, 0x14, 0x7a, 0xf8, 0x41, 0xab, + 0x6f, 0x76, 0xe3, 0x2a, 0x64, 0xba, 0x7e, 0x78, 0x02, 0x6c, 0x0b, 0x14, 0xe4, 0xe2, 0xc9, 0x9f, + 0x4b, 0x60, 0x39, 0xa1, 0xaa, 0x7e, 0x83, 0x46, 0xf9, 0x57, 0x09, 0x9c, 0x0b, 0x8c, 0x92, 0xa5, + 0x25, 0xb9, 0xdf, 0x57, 0x79, 0x86, 0x0a, 0x26, 0x73, 0x09, 0x14, 0x0d, 0x6c, 0x52, 0xc5, 0xe5, + 0xc1, 0xf9, 0xc6, 0xec, 0x78, 0x54, 0x2d, 0x36, 0x9d, 0x46, 0xe4, 0xc9, 0x63, 0xe6, 0x26, 0xf3, + 0xec, 0xe6, 0x46, 0xfe, 0x9f, 0x04, 0xf2, 0xad, 0x36, 0x56, 0xc9, 0x31, 0x10, 0x97, 0xcd, 0x00, + 0x71, 0x49, 0x7e, 0x14, 0xe0, 0xfe, 0x24, 0x72, 0x96, 0xad, 0x10, 0x67, 0xb9, 0x30, 0x01, 0xe7, + 0xc9, 0x74, 0xe5, 0x75, 0x50, 0x74, 0xbb, 0x9b, 0x6e, 0x2f, 0x95, 0x7f, 0x9f, 0x01, 0x25, 0x5f, + 0x17, 0x53, 0xee, 0xc4, 0xf7, 0x02, 0xe5, 0x87, 0xed, 0x31, 0x6b, 0x69, 0x06, 0x52, 0x73, 0x4a, + 0xcd, 0x5b, 0x1a, 0x35, 0xfd, 0x67, 0xd5, 0x68, 0x05, 0x7a, 0x03, 0xcc, 0x51, 0x6c, 0x76, 0x09, + 0x75, 0x64, 0x7c, 0xc2, 0x8a, 0xde, 0xdd, 0xcd, 0x9d, 0x80, 0x14, 0x85, 0xb4, 0x57, 0x6e, 0x80, + 0xd9, 0x40, 0x67, 0xf0, 0x34, 0xc8, 0x1e, 0x92, 0xa1, 0xcd, 0xe0, 0x10, 0xfb, 0x09, 0x17, 0x41, + 0x7e, 0x80, 0xd5, 0xbe, 0x1d, 0xa2, 0x45, 0x64, 0x7f, 0x5c, 0xcf, 0xbc, 0x26, 0xc9, 0xbf, 0x61, + 0x93, 0xe3, 0xa5, 0xc2, 0x31, 0x44, 0xd7, 0xdb, 0x81, 0xe8, 0x4a, 0x7e, 0x9f, 0xf4, 0x27, 0x68, + 0x52, 0x8c, 0xa1, 0x50, 0x8c, 0xbd, 0x98, 0x0a, 0xed, 0xc9, 0x91, 0xf6, 0xef, 0x0c, 0x58, 0xf4, + 0x69, 0x7b, 0xcc, 0xf8, 0xfb, 0x01, 0x66, 0xbc, 0x1a, 0x62, 0xc6, 0xe5, 0x38, 0x9b, 0x6f, 0xa9, + 0xf1, 0x64, 0x6a, 0xfc, 0x17, 0x09, 0xcc, 0xfb, 0xe6, 0xee, 0x18, 0xb8, 0xf1, 0xed, 0x20, 0x37, + 0xbe, 0x90, 0x26, 0x68, 0x12, 0xc8, 0xf1, 0x75, 0xb0, 0xe0, 0x53, 0xda, 0x35, 0x3b, 0x8a, 0x86, + 0x55, 0x0b, 0x9e, 0x07, 0x79, 0x8b, 0x62, 0x93, 0x3a, 0x45, 0xc4, 0xb1, 0x6d, 0xb1, 0x46, 0x64, + 0xcb, 0xe4, 0xff, 0x48, 0xa0, 0xee, 0x33, 0x6e, 0x12, 0xd3, 0x52, 0x2c, 0x4a, 0x34, 0x7a, 0x57, + 0x57, 0xfb, 0x3d, 0xb2, 0xa1, 0x62, 0xa5, 0x87, 0x08, 0x6b, 0x50, 0x74, 0xad, 0xa9, 0xab, 0x4a, + 0x7b, 0x08, 0x31, 0x28, 0x7d, 0x70, 0x40, 0xb4, 0x4d, 0xa2, 0x12, 0x2a, 0x5e, 0xe0, 0x8a, 0x8d, + 0x37, 0x9d, 0x07, 0xa9, 0x77, 0x3d, 0xd1, 0xe3, 0x51, 0x75, 0x35, 0x0d, 0x22, 0x8f, 0x50, 0x3f, + 0x26, 0xfc, 0x19, 0x00, 0xec, 0x93, 0xef, 0x65, 0x1d, 0x11, 0xac, 0x6f, 0x38, 0x19, 0xfd, 0xae, + 0x2b, 0x99, 0xaa, 0x03, 0x1f, 0xa2, 0xfc, 0xc7, 0x42, 0x60, 0xbd, 0xbf, 0xf1, 0xb7, 0x9c, 0xbf, + 0x00, 0x8b, 0x03, 0x6f, 0x76, 0x1c, 0x05, 0xc6, 0xbf, 0xb3, 0xe1, 0x93, 0xbc, 0x0b, 0x1f, 0x37, + 0xaf, 0x1e, 0xeb, 0xbf, 0x1b, 0x03, 0x87, 0x62, 0x3b, 0x81, 0xaf, 0x80, 0x12, 0xe3, 0xcd, 0x4a, + 0x9b, 0xec, 0xe0, 0x9e, 0x93, 0x8b, 0xee, 0x03, 0x66, 0xcb, 0x13, 0x21, 0xbf, 0x1e, 0x3c, 0x00, + 0x0b, 0x86, 0xde, 0xd9, 0xc6, 0x1a, 0xee, 0x12, 0x46, 0x04, 0xed, 0xa5, 0xe4, 0x57, 0x9f, 0xc5, + 0xc6, 0xab, 0xce, 0xb5, 0x56, 0x33, 0xaa, 0xf2, 0x78, 0x54, 0x5d, 0x8e, 0x69, 0xe6, 0x41, 0x10, + 0x07, 0x09, 0xcd, 0xc8, 0xa3, 0xbb, 0xfd, 0xe8, 0xb0, 0x96, 0x26, 0x29, 0x8f, 0xf8, 0xec, 0x9e, + 0x74, 0xb3, 0x5b, 0x38, 0xd2, 0xcd, 0x6e, 0xcc, 0x11, 0xb7, 0x38, 0xe5, 0x11, 0xf7, 0x63, 0x09, + 0x5c, 0x30, 0x52, 0xe4, 0x52, 0x19, 0xf0, 0xb9, 0xb9, 0x95, 0x66, 0x6e, 0xd2, 0xe4, 0x66, 0x63, + 0x75, 0x3c, 0xaa, 0x5e, 0x48, 0xa3, 0x89, 0x52, 0xf9, 0x07, 0xef, 0x82, 0x82, 0x2e, 0xf6, 0xc0, + 0x72, 0x89, 0xfb, 0x7a, 0x39, 0x8d, 0xaf, 0xce, 0xbe, 0x69, 0xa7, 0xa5, 0xf3, 0x85, 0x5c, 0x2c, + 0xf9, 0xc3, 0x3c, 0x38, 0x13, 0xa9, 0xe0, 0x5f, 0xe2, 0xfd, 0x75, 0xe4, 0x30, 0x9d, 0x9d, 0xe2, + 0x30, 0xbd, 0x0e, 0xe6, 0xc5, 0x5f, 0x22, 0x42, 0x67, 0x71, 0x37, 0x60, 0x36, 0x82, 0x62, 0x14, + 0xd6, 0x8f, 0xbb, 0x3f, 0xcf, 0x4f, 0x79, 0x7f, 0xee, 0xf7, 0x42, 0xfc, 0xc5, 0xcf, 0x4e, 0xef, + 0xa8, 0x17, 0xe2, 0x9f, 0x7e, 0x61, 0x7d, 0x46, 0x5c, 0x6d, 0x54, 0x17, 0xe1, 0x64, 0x90, 0xb8, + 0xee, 0x05, 0xa4, 0x28, 0xa4, 0xfd, 0x85, 0x9e, 0xfd, 0x71, 0xcc, 0xb3, 0xff, 0x95, 0x34, 0xb1, + 0x96, 0xfe, 0xaa, 0x3c, 0xf6, 0xd2, 0xa3, 0x34, 0xfd, 0xa5, 0x87, 0xfc, 0x77, 0x09, 0x3c, 0x97, + 0xb8, 0x6b, 0xc1, 0xf5, 0x00, 0xad, 0xbc, 0x12, 0xa2, 0x95, 0xdf, 0x4b, 0x34, 0xf4, 0x71, 0x4b, + 0x33, 0xfe, 0x16, 0xfd, 0xf5, 0x74, 0xb7, 0xe8, 0x31, 0x27, 0xe1, 0xc9, 0xd7, 0xe9, 0x8d, 0x1f, + 0x3c, 0x7c, 0x54, 0x39, 0xf1, 0xc9, 0xa3, 0xca, 0x89, 0xcf, 0x1e, 0x55, 0x4e, 0xfc, 0x72, 0x5c, + 0x91, 0x1e, 0x8e, 0x2b, 0xd2, 0x27, 0xe3, 0x8a, 0xf4, 0xd9, 0xb8, 0x22, 0xfd, 0x63, 0x5c, 0x91, + 0x7e, 0xfb, 0x79, 0xe5, 0xc4, 0x7b, 0xcb, 0x09, 0x7f, 0x3a, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd1, 0xcb, 0x7d, 0xc7, 0xa7, 0x2c, 0x00, 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -2573,6 +2605,32 @@ func (m *StatefulSetList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *StatefulSetOrdinals) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StatefulSetOrdinals) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StatefulSetOrdinals) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.Start)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2626,6 +2684,18 @@ func (m *StatefulSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Ordinals != nil { + { + size, err := m.Ordinals.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } if m.PersistentVolumeClaimRetentionPolicy != nil { { size, err := m.PersistentVolumeClaimRetentionPolicy.MarshalToSizedBuffer(dAtA[:i]) @@ -3331,6 +3401,16 @@ func (m *StatefulSetList) Size() (n int) { return n } +func (m *StatefulSetOrdinals) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Start)) + return n +} + func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Size() (n int) { if m == nil { return 0 @@ -3379,6 +3459,10 @@ func (m *StatefulSetSpec) Size() (n int) { l = m.PersistentVolumeClaimRetentionPolicy.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Ordinals != nil { + l = m.Ordinals.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -3837,6 +3921,16 @@ func (this *StatefulSetList) String() string { }, "") return s } +func (this *StatefulSetOrdinals) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StatefulSetOrdinals{`, + `Start:` + fmt.Sprintf("%v", this.Start) + `,`, + `}`, + }, "") + return s +} func (this *StatefulSetPersistentVolumeClaimRetentionPolicy) String() string { if this == nil { return "nil" @@ -3868,6 +3962,7 @@ func (this *StatefulSetSpec) String() string { `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, `MinReadySeconds:` + fmt.Sprintf("%v", this.MinReadySeconds) + `,`, `PersistentVolumeClaimRetentionPolicy:` + strings.Replace(this.PersistentVolumeClaimRetentionPolicy.String(), "StatefulSetPersistentVolumeClaimRetentionPolicy", "StatefulSetPersistentVolumeClaimRetentionPolicy", 1) + `,`, + `Ordinals:` + strings.Replace(this.Ordinals.String(), "StatefulSetOrdinals", "StatefulSetOrdinals", 1) + `,`, `}`, }, "") return s @@ -8393,6 +8488,75 @@ func (m *StatefulSetList) Unmarshal(dAtA []byte) error { } return nil } +func (m *StatefulSetOrdinals) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StatefulSetOrdinals: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StatefulSetOrdinals: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + m.Start = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Start |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *StatefulSetPersistentVolumeClaimRetentionPolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8831,6 +8995,42 @@ func (m *StatefulSetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ordinals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ordinals == nil { + m.Ordinals = &StatefulSetOrdinals{} + } + if err := m.Ordinals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/apps/v1beta2/generated.proto b/vendor/k8s.io/api/apps/v1beta2/generated.proto index b5bc8c0cab5..ddbe3544114 100644 --- a/vendor/k8s.io/api/apps/v1beta2/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta2/generated.proto @@ -131,6 +131,7 @@ message DaemonSetSpec { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template optional k8s.io.api.core.v1.PodTemplateSpec template = 2; @@ -282,6 +283,7 @@ message DeploymentSpec { optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -455,7 +457,7 @@ message ReplicaSetSpec { // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller optional int32 replicas = 1; @@ -519,7 +521,6 @@ message RollingUpdateDaemonSet { // daemonset on any given node can double if the readiness check fails, and // so resource intensive daemonsets should take into account that they may // cause evictions during disruption. - // This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxSurge = 2; } @@ -601,7 +602,7 @@ message ScaleStatus { // actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic map selector = 2; @@ -620,8 +621,9 @@ message ScaleStatus { // more information. // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. message StatefulSet { @@ -667,6 +669,21 @@ message StatefulSetList { repeated StatefulSet items = 2; } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +message StatefulSetOrdinals { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + optional int32 start = 1; +} + // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. message StatefulSetPersistentVolumeClaimRetentionPolicy { @@ -702,7 +719,10 @@ message StatefulSetSpec { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -747,7 +767,6 @@ message StatefulSetSpec { // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional optional int32 minReadySeconds = 9; @@ -756,6 +775,14 @@ message StatefulSetSpec { // StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. // +optional optional StatefulSetPersistentVolumeClaimRetentionPolicy persistentVolumeClaimRetentionPolicy = 10; + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + optional StatefulSetOrdinals ordinals = 11; } // StatefulSetStatus represents the current state of a StatefulSet. @@ -800,7 +827,6 @@ message StatefulSetStatus { repeated StatefulSetCondition conditions = 10; // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. // +optional optional int32 availableReplicas = 11; } diff --git a/vendor/k8s.io/api/apps/v1beta2/types.go b/vendor/k8s.io/api/apps/v1beta2/types.go index 6c2448869e7..a97ac6fcf0b 100644 --- a/vendor/k8s.io/api/apps/v1beta2/types.go +++ b/vendor/k8s.io/api/apps/v1beta2/types.go @@ -43,7 +43,7 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` @@ -94,8 +94,9 @@ type Scale struct { // more information. // StatefulSet represents a set of pods with consistent identities. // Identities are defined as: -// - Network: A single stable DNS and hostname. -// - Storage: As many VolumeClaims as requested. +// - Network: A single stable DNS and hostname. +// - Storage: As many VolumeClaims as requested. +// // The StatefulSet guarantees that a given network identity will always // map to the same storage identity. type StatefulSet struct { @@ -213,6 +214,21 @@ type StatefulSetPersistentVolumeClaimRetentionPolicy struct { WhenScaled PersistentVolumeClaimRetentionPolicyType `json:"whenScaled,omitempty" protobuf:"bytes,2,opt,name=whenScaled,casttype=PersistentVolumeClaimRetentionPolicyType"` } +// StatefulSetOrdinals describes the policy used for replica ordinal assignment +// in this StatefulSet. +type StatefulSetOrdinals struct { + // start is the number representing the first replica's index. It may be used + // to number replicas from an alternate index (eg: 1-indexed) over the default + // 0-indexed names, or to orchestrate progressive movement of replicas from + // one StatefulSet to another. + // If set, replica indices will be in the range: + // [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). + // If unset, defaults to 0. Replica indices will be in the range: + // [0, .spec.replicas). + // +optional + Start int32 `json:"start" protobuf:"varint,1,opt,name=start"` +} + // A StatefulSetSpec is the specification of a StatefulSet. type StatefulSetSpec struct { // replicas is the desired number of replicas of the given Template. @@ -231,7 +247,10 @@ type StatefulSetSpec struct { // template is the object that describes the pod that will be created if // insufficient replicas are detected. Each pod stamped out by the StatefulSet // will fulfill this Template, but have a unique identity from the rest - // of the StatefulSet. + // of the StatefulSet. Each pod will be named with the format + // -. For example, a pod in a StatefulSet named + // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -276,7 +295,6 @@ type StatefulSetSpec struct { // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) - // This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate. // +optional MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,9,opt,name=minReadySeconds"` @@ -285,6 +303,14 @@ type StatefulSetSpec struct { // StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaimRetentionPolicy"` + + // ordinals controls the numbering of replica indices in a StatefulSet. The + // default ordinals behavior assigns a "0" index to the first replica and + // increments the index by one for each additional replica requested. Using + // the ordinals field requires the StatefulSetStartOrdinal feature gate to be + // enabled, which is beta. + // +optional + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } // StatefulSetStatus represents the current state of a StatefulSet. @@ -329,7 +355,6 @@ type StatefulSetStatus struct { Conditions []StatefulSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"` // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. - // This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate. // +optional AvailableReplicas int32 `json:"availableReplicas" protobuf:"varint,11,opt,name=availableReplicas"` } @@ -405,6 +430,7 @@ type DeploymentSpec struct { Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -650,7 +676,6 @@ type RollingUpdateDaemonSet struct { // daemonset on any given node can double if the readiness check fails, and // so resource intensive daemonsets should take into account that they may // cause evictions during disruption. - // This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate. // +optional MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,2,opt,name=maxSurge"` } @@ -667,6 +692,7 @@ type DaemonSetSpec struct { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,2,opt,name=template"` @@ -901,7 +927,7 @@ type ReplicaSetSpec struct { // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` diff --git a/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go index ef1de63b2f2..d7e92099155 100644 --- a/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ @@ -85,7 +85,7 @@ func (DaemonSetList) SwaggerDoc() map[string]string { var map_DaemonSetSpec = map[string]string{ "": "DaemonSetSpec is the specification of a daemon set.", "selector": "A label query over pods that are managed by the daemon set. Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", "updateStrategy": "An update strategy to replace existing DaemonSet pods with new pods.", "minReadySeconds": "The minimum number of seconds for which a newly created DaemonSet pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready).", "revisionHistoryLimit": "The number of old history to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -162,7 +162,7 @@ var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.", - "template": "Template describes the pods that will be created.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -248,7 +248,7 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", "readyReplicas": "readyReplicas is the number of pods targeted by this ReplicaSet controller with a Ready Condition.", "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", @@ -263,7 +263,7 @@ func (ReplicaSetStatus) SwaggerDoc() map[string]string { var map_RollingUpdateDaemonSet = map[string]string{ "": "Spec to control the desired behavior of daemon set rolling update.", "maxUnavailable": "The maximum number of DaemonSet pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of total number of DaemonSet pods at the start of the update (ex: 10%). Absolute number is calculated from percentage by rounding up. This cannot be 0 if MaxSurge is 0 Default value is 1. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their pods stopped for an update at any given time. The update starts by stopping at most 30% of those DaemonSet pods and then brings up new DaemonSet pods in their place. Once the new pods are available, it then proceeds onto other DaemonSet pods, thus ensuring that at least 70% of original number of DaemonSet pods are available at all times during the update.", - "maxSurge": "The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption. This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.", + "maxSurge": "The maximum number of nodes with an existing available DaemonSet pod that can have an updated DaemonSet pod during during an update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up to a minimum of 1. Default value is 0. Example: when this is set to 30%, at most 30% of the total number of nodes that should be running the daemon pod (i.e. status.desiredNumberScheduled) can have their a new pod created before the old pod is marked as deleted. The update starts by launching new pods on 30% of nodes. Once an updated pod is available (Ready for at least minReadySeconds) the old DaemonSet pod on that node is marked deleted. If the old pod becomes unavailable for any reason (Ready transitions to false, is evicted, or is drained) an updated pod is immediatedly created on that node without considering surge limits. Allowing surge implies the possibility that the resources consumed by the daemonset on any given node can double if the readiness check fails, and so resource intensive daemonsets should take into account that they may cause evictions during disruption.", } func (RollingUpdateDaemonSet) SwaggerDoc() map[string]string { @@ -313,7 +313,7 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } @@ -322,7 +322,7 @@ func (ScaleStatus) SwaggerDoc() map[string]string { } var map_StatefulSet = map[string]string{ - "": "DEPRECATED - This group version of StatefulSet is deprecated by apps/v1/StatefulSet. See the release notes for more information. StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", + "": "DEPRECATED - This group version of StatefulSet is deprecated by apps/v1/StatefulSet. See the release notes for more information. StatefulSet represents a set of pods with consistent identities. Identities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\n\nThe StatefulSet guarantees that a given network identity will always map to the same storage identity.", "spec": "Spec defines the desired identities of pods in this set.", "status": "Status is the current status of Pods in this StatefulSet. This data may be out of date by some window of time.", } @@ -352,6 +352,15 @@ func (StatefulSetList) SwaggerDoc() map[string]string { return map_StatefulSetList } +var map_StatefulSetOrdinals = map[string]string{ + "": "StatefulSetOrdinals describes the policy used for replica ordinal assignment in this StatefulSet.", + "start": "start is the number representing the first replica's index. It may be used to number replicas from an alternate index (eg: 1-indexed) over the default 0-indexed names, or to orchestrate progressive movement of replicas from one StatefulSet to another. If set, replica indices will be in the range:\n [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas).\nIf unset, defaults to 0. Replica indices will be in the range:\n [0, .spec.replicas).", +} + +func (StatefulSetOrdinals) SwaggerDoc() map[string]string { + return map_StatefulSetOrdinals +} + var map_StatefulSetPersistentVolumeClaimRetentionPolicy = map[string]string{ "": "StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", "whenDeleted": "WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", @@ -366,14 +375,15 @@ var map_StatefulSetSpec = map[string]string{ "": "A StatefulSetSpec is the specification of a StatefulSet.", "replicas": "replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.", "selector": "selector is a label query over pods that should match the replica count. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet.", + "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\". The only allowed template.spec.restartPolicy value is \"Always\".", "volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.", "serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where \"pod-specific-string\" is managed by the StatefulSet controller.", "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", - "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) This is an alpha field and requires enabling StatefulSetMinReadySeconds feature gate.", + "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha.", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { @@ -391,7 +401,7 @@ var map_StatefulSetStatus = map[string]string{ "updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)", "collisionCount": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision.", "conditions": "Represents the latest available observations of a statefulset's current state.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. This is a beta field and enabled/disabled by StatefulSetMinReadySeconds feature gate.", + "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet.", } func (StatefulSetStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go b/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go index 118fd38093d..cd92792db56 100644 --- a/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go @@ -760,6 +760,22 @@ func (in *StatefulSetList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatefulSetOrdinals) DeepCopyInto(out *StatefulSetOrdinals) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetOrdinals. +func (in *StatefulSetOrdinals) DeepCopy() *StatefulSetOrdinals { + if in == nil { + return nil + } + out := new(StatefulSetOrdinals) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StatefulSetPersistentVolumeClaimRetentionPolicy) DeepCopyInto(out *StatefulSetPersistentVolumeClaimRetentionPolicy) { *out = *in @@ -808,6 +824,11 @@ func (in *StatefulSetSpec) DeepCopyInto(out *StatefulSetSpec) { *out = new(StatefulSetPersistentVolumeClaimRetentionPolicy) **out = **in } + if in.Ordinals != nil { + in, out := &in.Ordinals, &out.Ordinals + *out = new(StatefulSetOrdinals) + **out = **in + } return } diff --git a/vendor/k8s.io/api/authentication/v1/generated.proto b/vendor/k8s.io/api/authentication/v1/generated.proto index d2158420942..f4806a3c636 100644 --- a/vendor/k8s.io/api/authentication/v1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1/generated.proto @@ -74,7 +74,7 @@ message TokenRequest { // TokenRequestSpec contains client provided parameters of a token request. message TokenRequestSpec { // Audiences are the intendend audiences of the token. A recipient of a - // token must identitfy themself with an identifier in the list of + // token must identify themself with an identifier in the list of // audiences of the token, and otherwise should reject the token. A // token issued for multiple audiences may be used to authenticate // against any of the audiences listed but implies a high degree of diff --git a/vendor/k8s.io/api/authentication/v1/types.go b/vendor/k8s.io/api/authentication/v1/types.go index 7ba247d633c..4e221e58c7d 100644 --- a/vendor/k8s.io/api/authentication/v1/types.go +++ b/vendor/k8s.io/api/authentication/v1/types.go @@ -151,7 +151,7 @@ type TokenRequest struct { // TokenRequestSpec contains client provided parameters of a token request. type TokenRequestSpec struct { // Audiences are the intendend audiences of the token. A recipient of a - // token must identitfy themself with an identifier in the list of + // token must identify themself with an identifier in the list of // audiences of the token, and otherwise should reject the token. A // token issued for multiple audiences may be used to authenticate // against any of the audiences listed but implies a high degree of diff --git a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go index f9a88a3df25..b1a730b816e 100644 --- a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_BoundObjectReference = map[string]string{ @@ -52,7 +52,7 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_TokenRequestSpec = map[string]string{ "": "TokenRequestSpec contains client provided parameters of a token request.", - "audiences": "Audiences are the intendend audiences of the token. A recipient of a token must identitfy themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.", + "audiences": "Audiences are the intendend audiences of the token. A recipient of a token must identify themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.", "expirationSeconds": "ExpirationSeconds is the requested duration of validity of the request. The token issuer may return a token with a different validity duration so a client needs to check the 'expiration' field in a response.", "boundObjectRef": "BoundObjectRef is a reference to an object that the token will be bound to. The token will only be valid for as long as the bound object exists. NOTE: The API server's TokenReview endpoint will validate the BoundObjectRef, but other audiences may not. Keep ExpirationSeconds small if you want prompt revocation.", } diff --git a/vendor/k8s.io/api/authentication/v1alpha1/doc.go b/vendor/k8s.io/api/authentication/v1alpha1/doc.go new file mode 100644 index 00000000000..eb32def904d --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +groupName=authentication.k8s.io +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true + +package v1alpha1 // import "k8s.io/api/authentication/v1alpha1" diff --git a/vendor/k8s.io/api/authentication/v1alpha1/generated.pb.go b/vendor/k8s.io/api/authentication/v1alpha1/generated.pb.go new file mode 100644 index 00000000000..ea274ac07b8 --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/generated.pb.go @@ -0,0 +1,567 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/authentication/v1alpha1/generated.proto + +package v1alpha1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *SelfSubjectReview) Reset() { *m = SelfSubjectReview{} } +func (*SelfSubjectReview) ProtoMessage() {} +func (*SelfSubjectReview) Descriptor() ([]byte, []int) { + return fileDescriptor_05a77aeb710b43c2, []int{0} +} +func (m *SelfSubjectReview) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReview) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SelfSubjectReview) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReview.Merge(m, src) +} +func (m *SelfSubjectReview) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReview) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReview.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReview proto.InternalMessageInfo + +func (m *SelfSubjectReviewStatus) Reset() { *m = SelfSubjectReviewStatus{} } +func (*SelfSubjectReviewStatus) ProtoMessage() {} +func (*SelfSubjectReviewStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_05a77aeb710b43c2, []int{1} +} +func (m *SelfSubjectReviewStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReviewStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SelfSubjectReviewStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReviewStatus.Merge(m, src) +} +func (m *SelfSubjectReviewStatus) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReviewStatus) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReviewStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReviewStatus proto.InternalMessageInfo + +func init() { + proto.RegisterType((*SelfSubjectReview)(nil), "k8s.io.api.authentication.v1alpha1.SelfSubjectReview") + proto.RegisterType((*SelfSubjectReviewStatus)(nil), "k8s.io.api.authentication.v1alpha1.SelfSubjectReviewStatus") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/authentication/v1alpha1/generated.proto", fileDescriptor_05a77aeb710b43c2) +} + +var fileDescriptor_05a77aeb710b43c2 = []byte{ + // 384 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xbd, 0x6e, 0xdb, 0x30, + 0x14, 0x85, 0xc5, 0x0e, 0x86, 0xa1, 0x02, 0x45, 0xab, 0xa5, 0x86, 0x07, 0xba, 0xd0, 0x50, 0x74, + 0x68, 0xc9, 0xba, 0x28, 0x8a, 0x02, 0xdd, 0x34, 0x35, 0x08, 0x82, 0x00, 0x72, 0xb2, 0x64, 0x0a, + 0x25, 0x5f, 0x4b, 0x8c, 0x2c, 0x52, 0x10, 0x49, 0x05, 0xd9, 0xf2, 0x08, 0x79, 0x2c, 0x8f, 0x1e, + 0x8d, 0x0c, 0x46, 0xac, 0xbc, 0x48, 0x20, 0x59, 0xb6, 0x11, 0x3b, 0xb6, 0x37, 0xde, 0xc3, 0xfb, + 0x9d, 0x7b, 0xf8, 0x63, 0x9f, 0x26, 0x7f, 0x15, 0xe1, 0x92, 0x26, 0x26, 0x80, 0x5c, 0x80, 0x06, + 0x45, 0x0b, 0x10, 0x43, 0x99, 0xd3, 0x66, 0x83, 0x65, 0x9c, 0x32, 0xa3, 0x63, 0x10, 0x9a, 0x87, + 0x4c, 0x73, 0x29, 0x68, 0xd1, 0x67, 0xe3, 0x2c, 0x66, 0x7d, 0x1a, 0x81, 0x80, 0x9c, 0x69, 0x18, + 0x92, 0x2c, 0x97, 0x5a, 0x3a, 0xee, 0x92, 0x21, 0x2c, 0xe3, 0xe4, 0x35, 0x43, 0x56, 0x4c, 0xf7, + 0x47, 0xc4, 0x75, 0x6c, 0x02, 0x12, 0xca, 0x94, 0x46, 0x32, 0x92, 0xb4, 0x46, 0x03, 0x33, 0xaa, + 0xab, 0xba, 0xa8, 0x57, 0x4b, 0xcb, 0xee, 0xf7, 0x43, 0x31, 0xb6, 0x03, 0x74, 0x7f, 0x6f, 0xba, + 0x53, 0x16, 0xc6, 0x5c, 0x40, 0x7e, 0x47, 0xb3, 0x24, 0xaa, 0x04, 0x45, 0x53, 0xd0, 0xec, 0x2d, + 0x8a, 0xee, 0xa3, 0x72, 0x23, 0x34, 0x4f, 0x61, 0x07, 0xf8, 0x73, 0x0c, 0x50, 0x61, 0x0c, 0x29, + 0xdb, 0xe6, 0xdc, 0x47, 0x64, 0x7f, 0x1a, 0xc0, 0x78, 0x34, 0x30, 0xc1, 0x0d, 0x84, 0xda, 0x87, + 0x82, 0xc3, 0xad, 0x73, 0x6d, 0xb7, 0xab, 0x64, 0x43, 0xa6, 0x59, 0x07, 0x7d, 0x41, 0xdf, 0xde, + 0xff, 0xfa, 0x49, 0x36, 0x17, 0xb9, 0x1e, 0x40, 0xb2, 0x24, 0xaa, 0x04, 0x45, 0xaa, 0x6e, 0x52, + 0xf4, 0xc9, 0x79, 0xed, 0x72, 0x06, 0x9a, 0x79, 0xce, 0x64, 0xde, 0xb3, 0xca, 0x79, 0xcf, 0xde, + 0x68, 0xfe, 0xda, 0xd5, 0x09, 0xed, 0x96, 0xd2, 0x4c, 0x1b, 0xd5, 0x79, 0x57, 0xfb, 0xff, 0x23, + 0xc7, 0x1f, 0x8a, 0xec, 0x04, 0x1d, 0xd4, 0x16, 0xde, 0x87, 0x66, 0x54, 0x6b, 0x59, 0xfb, 0x8d, + 0xb5, 0x2b, 0xed, 0xcf, 0x7b, 0x10, 0xe7, 0xc2, 0x6e, 0x1b, 0x05, 0xf9, 0x89, 0x18, 0xc9, 0xe6, + 0x84, 0x5f, 0x0f, 0x26, 0x20, 0x97, 0x4d, 0xb7, 0xf7, 0xb1, 0x19, 0xd6, 0x5e, 0x29, 0xfe, 0xda, + 0xc9, 0xfb, 0x3f, 0x59, 0x60, 0x6b, 0xba, 0xc0, 0xd6, 0x6c, 0x81, 0xad, 0xfb, 0x12, 0xa3, 0x49, + 0x89, 0xd1, 0xb4, 0xc4, 0x68, 0x56, 0x62, 0xf4, 0x54, 0x62, 0xf4, 0xf0, 0x8c, 0xad, 0x2b, 0xf7, + 0xf8, 0x3f, 0x7e, 0x09, 0x00, 0x00, 0xff, 0xff, 0xec, 0xf9, 0xa3, 0xcd, 0x05, 0x03, 0x00, 0x00, +} + +func (m *SelfSubjectReview) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SelfSubjectReview) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *SelfSubjectReviewStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SelfSubjectReviewStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReviewStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.UserInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SelfSubjectReview) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *SelfSubjectReviewStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.UserInfo.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *SelfSubjectReview) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReview{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "SelfSubjectReviewStatus", "SelfSubjectReviewStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *SelfSubjectReviewStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReviewStatus{`, + `UserInfo:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.UserInfo), "UserInfo", "v11.UserInfo", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *SelfSubjectReview) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SelfSubjectReview: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReview: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SelfSubjectReviewStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SelfSubjectReviewStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReviewStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/authentication/v1alpha1/generated.proto b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto new file mode 100644 index 00000000000..51d9252440c --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto @@ -0,0 +1,51 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.authentication.v1alpha1; + +import "k8s.io/api/authentication/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/authentication/v1alpha1"; + +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +message SelfSubjectReview { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Status is filled in by the server with the user attributes. + optional SelfSubjectReviewStatus status = 2; +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +message SelfSubjectReviewStatus { + // User attributes of the user making this request. + // +optional + optional k8s.io.api.authentication.v1.UserInfo userInfo = 1; +} + diff --git a/vendor/k8s.io/api/authentication/v1alpha1/register.go b/vendor/k8s.io/api/authentication/v1alpha1/register.go new file mode 100644 index 00000000000..4f93928d9be --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/register.go @@ -0,0 +1,51 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "authentication.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &SelfSubjectReview{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types.go b/vendor/k8s.io/api/authentication/v1alpha1/types.go new file mode 100644 index 00000000000..1ee3612fbc4 --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/types.go @@ -0,0 +1,48 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + v1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +genclient:onlyVerbs=create +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +type SelfSubjectReview struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Status is filled in by the server with the user attributes. + Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +type SelfSubjectReviewStatus struct { + // User attributes of the user making this request. + // +optional + UserInfo v1.UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` +} diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 00000000000..1ffcc99e7d3 --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,49 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_SelfSubjectReview = map[string]string{ + "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "Status is filled in by the server with the user attributes.", +} + +func (SelfSubjectReview) SwaggerDoc() map[string]string { + return map_SelfSubjectReview +} + +var map_SelfSubjectReviewStatus = map[string]string{ + "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", + "userInfo": "User attributes of the user making this request.", +} + +func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { + return map_SelfSubjectReviewStatus +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..9b146a84748 --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,70 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SelfSubjectReview) DeepCopyInto(out *SelfSubjectReview) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReview. +func (in *SelfSubjectReview) DeepCopy() *SelfSubjectReview { + if in == nil { + return nil + } + out := new(SelfSubjectReview) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SelfSubjectReview) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SelfSubjectReviewStatus) DeepCopyInto(out *SelfSubjectReviewStatus) { + *out = *in + in.UserInfo.DeepCopyInto(&out.UserInfo) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReviewStatus. +func (in *SelfSubjectReviewStatus) DeepCopy() *SelfSubjectReviewStatus { + if in == nil { + return nil + } + out := new(SelfSubjectReviewStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go new file mode 100644 index 00000000000..62a70a781d1 --- /dev/null +++ b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,40 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v1alpha1 + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *SelfSubjectReview) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *SelfSubjectReview) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *SelfSubjectReview) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go b/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go index 1978dcf6ab3..7f1d5ca6ce1 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go @@ -72,10 +72,66 @@ func (m *ExtraValue) XXX_DiscardUnknown() { var xxx_messageInfo_ExtraValue proto.InternalMessageInfo +func (m *SelfSubjectReview) Reset() { *m = SelfSubjectReview{} } +func (*SelfSubjectReview) ProtoMessage() {} +func (*SelfSubjectReview) Descriptor() ([]byte, []int) { + return fileDescriptor_77c9b20d3ad27844, []int{1} +} +func (m *SelfSubjectReview) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReview) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SelfSubjectReview) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReview.Merge(m, src) +} +func (m *SelfSubjectReview) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReview) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReview.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReview proto.InternalMessageInfo + +func (m *SelfSubjectReviewStatus) Reset() { *m = SelfSubjectReviewStatus{} } +func (*SelfSubjectReviewStatus) ProtoMessage() {} +func (*SelfSubjectReviewStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_77c9b20d3ad27844, []int{2} +} +func (m *SelfSubjectReviewStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReviewStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SelfSubjectReviewStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReviewStatus.Merge(m, src) +} +func (m *SelfSubjectReviewStatus) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReviewStatus) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReviewStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReviewStatus proto.InternalMessageInfo + func (m *TokenReview) Reset() { *m = TokenReview{} } func (*TokenReview) ProtoMessage() {} func (*TokenReview) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{1} + return fileDescriptor_77c9b20d3ad27844, []int{3} } func (m *TokenReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +159,7 @@ var xxx_messageInfo_TokenReview proto.InternalMessageInfo func (m *TokenReviewSpec) Reset() { *m = TokenReviewSpec{} } func (*TokenReviewSpec) ProtoMessage() {} func (*TokenReviewSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{2} + return fileDescriptor_77c9b20d3ad27844, []int{4} } func (m *TokenReviewSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +187,7 @@ var xxx_messageInfo_TokenReviewSpec proto.InternalMessageInfo func (m *TokenReviewStatus) Reset() { *m = TokenReviewStatus{} } func (*TokenReviewStatus) ProtoMessage() {} func (*TokenReviewStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{3} + return fileDescriptor_77c9b20d3ad27844, []int{5} } func (m *TokenReviewStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +215,7 @@ var xxx_messageInfo_TokenReviewStatus proto.InternalMessageInfo func (m *UserInfo) Reset() { *m = UserInfo{} } func (*UserInfo) ProtoMessage() {} func (*UserInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{4} + return fileDescriptor_77c9b20d3ad27844, []int{6} } func (m *UserInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -186,6 +242,8 @@ var xxx_messageInfo_UserInfo proto.InternalMessageInfo func init() { proto.RegisterType((*ExtraValue)(nil), "k8s.io.api.authentication.v1beta1.ExtraValue") + proto.RegisterType((*SelfSubjectReview)(nil), "k8s.io.api.authentication.v1beta1.SelfSubjectReview") + proto.RegisterType((*SelfSubjectReviewStatus)(nil), "k8s.io.api.authentication.v1beta1.SelfSubjectReviewStatus") proto.RegisterType((*TokenReview)(nil), "k8s.io.api.authentication.v1beta1.TokenReview") proto.RegisterType((*TokenReviewSpec)(nil), "k8s.io.api.authentication.v1beta1.TokenReviewSpec") proto.RegisterType((*TokenReviewStatus)(nil), "k8s.io.api.authentication.v1beta1.TokenReviewStatus") @@ -198,49 +256,53 @@ func init() { } var fileDescriptor_77c9b20d3ad27844 = []byte{ - // 666 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcf, 0x4e, 0x13, 0x5f, - 0x14, 0x9e, 0xe9, 0x1f, 0xd2, 0xde, 0xfe, 0xfa, 0x13, 0x6f, 0x62, 0xd2, 0x34, 0x71, 0x0a, 0x75, - 0x43, 0x82, 0xdc, 0x11, 0x42, 0x90, 0xe0, 0x8a, 0x51, 0x42, 0x30, 0x21, 0x26, 0x57, 0x70, 0xa1, - 0x2e, 0xbc, 0x9d, 0x1e, 0xa6, 0x63, 0x9d, 0x3f, 0xb9, 0x73, 0xa7, 0xca, 0x8e, 0x47, 0x70, 0xe9, - 0xd2, 0xc4, 0x27, 0x71, 0xc7, 0x92, 0x25, 0x0b, 0xd3, 0xc8, 0xf8, 0x04, 0xbe, 0x81, 0xb9, 0x77, - 0x2e, 0x4c, 0x81, 0x68, 0x61, 0x37, 0xf7, 0x3b, 0xe7, 0xfb, 0xce, 0x39, 0xdf, 0xe9, 0x29, 0x7a, - 0x3e, 0x5c, 0x4f, 0x88, 0x1f, 0xd9, 0xc3, 0xb4, 0x07, 0x3c, 0x04, 0x01, 0x89, 0x3d, 0x82, 0xb0, - 0x1f, 0x71, 0x5b, 0x07, 0x58, 0xec, 0xdb, 0x2c, 0x15, 0x03, 0x08, 0x85, 0xef, 0x32, 0xe1, 0x47, - 0xa1, 0x3d, 0x5a, 0xee, 0x81, 0x60, 0xcb, 0xb6, 0x07, 0x21, 0x70, 0x26, 0xa0, 0x4f, 0x62, 0x1e, - 0x89, 0x08, 0xcf, 0xe7, 0x14, 0xc2, 0x62, 0x9f, 0x5c, 0xa6, 0x10, 0x4d, 0x69, 0x2f, 0x79, 0xbe, - 0x18, 0xa4, 0x3d, 0xe2, 0x46, 0x81, 0xed, 0x45, 0x5e, 0x64, 0x2b, 0x66, 0x2f, 0x3d, 0x50, 0x2f, - 0xf5, 0x50, 0x5f, 0xb9, 0x62, 0x7b, 0xb5, 0x68, 0x22, 0x60, 0xee, 0xc0, 0x0f, 0x81, 0x1f, 0xda, - 0xf1, 0xd0, 0x93, 0x40, 0x62, 0x07, 0x20, 0x98, 0x3d, 0xba, 0xd6, 0x47, 0xdb, 0xfe, 0x1b, 0x8b, - 0xa7, 0xa1, 0xf0, 0x03, 0xb8, 0x46, 0x58, 0x9b, 0x46, 0x48, 0xdc, 0x01, 0x04, 0xec, 0x2a, 0xaf, - 0xfb, 0x18, 0xa1, 0xad, 0x4f, 0x82, 0xb3, 0x57, 0xec, 0x43, 0x0a, 0xb8, 0x83, 0xaa, 0xbe, 0x80, - 0x20, 0x69, 0x99, 0x73, 0xe5, 0x85, 0xba, 0x53, 0xcf, 0xc6, 0x9d, 0xea, 0x8e, 0x04, 0x68, 0x8e, - 0x6f, 0xd4, 0xbe, 0x7c, 0xed, 0x18, 0x47, 0x3f, 0xe6, 0x8c, 0xee, 0xb7, 0x12, 0x6a, 0xec, 0x45, - 0x43, 0x08, 0x29, 0x8c, 0x7c, 0xf8, 0x88, 0xdf, 0xa1, 0x9a, 0x1c, 0xa6, 0xcf, 0x04, 0x6b, 0x99, - 0x73, 0xe6, 0x42, 0x63, 0xe5, 0x11, 0x29, 0xcc, 0xbc, 0xe8, 0x89, 0xc4, 0x43, 0x4f, 0x02, 0x09, - 0x91, 0xd9, 0x64, 0xb4, 0x4c, 0x5e, 0xf4, 0xde, 0x83, 0x2b, 0x76, 0x41, 0x30, 0x07, 0x1f, 0x8f, - 0x3b, 0x46, 0x36, 0xee, 0xa0, 0x02, 0xa3, 0x17, 0xaa, 0x78, 0x0f, 0x55, 0x92, 0x18, 0xdc, 0x56, - 0x49, 0xa9, 0xaf, 0x90, 0xa9, 0xab, 0x22, 0x13, 0xfd, 0xbd, 0x8c, 0xc1, 0x75, 0xfe, 0xd3, 0xfa, - 0x15, 0xf9, 0xa2, 0x4a, 0x0d, 0xbf, 0x45, 0x33, 0x89, 0x60, 0x22, 0x4d, 0x5a, 0x65, 0xa5, 0xbb, - 0x7a, 0x4b, 0x5d, 0xc5, 0x75, 0xfe, 0xd7, 0xca, 0x33, 0xf9, 0x9b, 0x6a, 0xcd, 0xae, 0x8b, 0xee, - 0x5c, 0x69, 0x02, 0x3f, 0x40, 0x55, 0x21, 0x21, 0xe5, 0x52, 0xdd, 0x69, 0x6a, 0x66, 0x35, 0xcf, - 0xcb, 0x63, 0x78, 0x11, 0xd5, 0x59, 0xda, 0xf7, 0x21, 0x74, 0x21, 0x69, 0x95, 0xd4, 0x32, 0x9a, - 0xd9, 0xb8, 0x53, 0xdf, 0x3c, 0x07, 0x69, 0x11, 0xef, 0xfe, 0x36, 0xd1, 0xdd, 0x6b, 0x2d, 0xe1, - 0x27, 0xa8, 0x39, 0xd1, 0x3e, 0xf4, 0x55, 0xbd, 0x9a, 0x73, 0x4f, 0xd7, 0x6b, 0x6e, 0x4e, 0x06, - 0xe9, 0xe5, 0x5c, 0xbc, 0x8b, 0x2a, 0x69, 0x02, 0x5c, 0x7b, 0xbd, 0x78, 0x03, 0x4f, 0xf6, 0x13, - 0xe0, 0x3b, 0xe1, 0x41, 0x54, 0x98, 0x2c, 0x11, 0xaa, 0x64, 0x2e, 0x8f, 0x53, 0xf9, 0xf7, 0x38, - 0xd2, 0x20, 0xe0, 0x3c, 0xe2, 0x6a, 0x21, 0x13, 0x06, 0x6d, 0x49, 0x90, 0xe6, 0xb1, 0xee, 0xf7, - 0x12, 0xaa, 0x9d, 0x97, 0xc4, 0x0f, 0x51, 0x4d, 0x96, 0x09, 0x59, 0x00, 0xda, 0xd5, 0x59, 0x4d, - 0x52, 0x39, 0x12, 0xa7, 0x17, 0x19, 0xf8, 0x3e, 0x2a, 0xa7, 0x7e, 0x5f, 0x8d, 0x56, 0x77, 0x1a, - 0x3a, 0xb1, 0xbc, 0xbf, 0xf3, 0x8c, 0x4a, 0x1c, 0x77, 0xd1, 0x8c, 0xc7, 0xa3, 0x34, 0x96, 0x3f, - 0x08, 0xd9, 0x28, 0x92, 0x6b, 0xdd, 0x56, 0x08, 0xd5, 0x11, 0xfc, 0x06, 0x55, 0x41, 0x5e, 0x8d, - 0x9a, 0xa5, 0xb1, 0xb2, 0x76, 0x0b, 0x7f, 0x88, 0x3a, 0xb7, 0xad, 0x50, 0xf0, 0xc3, 0x89, 0xd1, - 0x24, 0x46, 0x73, 0xcd, 0xb6, 0xa7, 0x4f, 0x52, 0xe5, 0xe0, 0x59, 0x54, 0x1e, 0xc2, 0x61, 0x3e, - 0x16, 0x95, 0x9f, 0xf8, 0x29, 0xaa, 0x8e, 0xe4, 0xb5, 0xea, 0xe5, 0x2c, 0xdd, 0xa0, 0x78, 0x71, - 0xe2, 0x34, 0xe7, 0x6e, 0x94, 0xd6, 0x4d, 0x67, 0xfb, 0xf8, 0xcc, 0x32, 0x4e, 0xce, 0x2c, 0xe3, - 0xf4, 0xcc, 0x32, 0x8e, 0x32, 0xcb, 0x3c, 0xce, 0x2c, 0xf3, 0x24, 0xb3, 0xcc, 0xd3, 0xcc, 0x32, - 0x7f, 0x66, 0x96, 0xf9, 0xf9, 0x97, 0x65, 0xbc, 0x9e, 0x9f, 0xfa, 0x2f, 0xfa, 0x27, 0x00, 0x00, - 0xff, 0xff, 0xb8, 0x72, 0x2c, 0x2c, 0x82, 0x05, 0x00, 0x00, + // 725 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x4f, 0x13, 0x41, + 0x14, 0xef, 0xf6, 0x0f, 0x69, 0xa7, 0x56, 0x61, 0x12, 0x23, 0x69, 0xe2, 0x16, 0x6a, 0x62, 0x48, + 0x80, 0x59, 0x21, 0x04, 0x09, 0x9e, 0x58, 0x25, 0x04, 0x13, 0x62, 0x32, 0x05, 0x0f, 0xea, 0xc1, + 0xe9, 0xf6, 0xb1, 0x5d, 0x4b, 0x77, 0x37, 0xbb, 0xb3, 0x55, 0x6e, 0x7c, 0x04, 0x8f, 0x1e, 0x4d, + 0xfc, 0x24, 0xde, 0x38, 0x72, 0xc4, 0xc4, 0x34, 0xb2, 0x7e, 0x02, 0xbf, 0x81, 0x99, 0xd9, 0x61, + 0xdb, 0x82, 0x14, 0xb8, 0x78, 0xdb, 0xf9, 0xcd, 0xfb, 0xfd, 0xde, 0x7b, 0xbf, 0xf7, 0x32, 0x8b, + 0x5e, 0x76, 0xd6, 0x42, 0xe2, 0x78, 0x46, 0x27, 0x6a, 0x42, 0xe0, 0x02, 0x87, 0xd0, 0xe8, 0x81, + 0xdb, 0xf2, 0x02, 0x43, 0x5d, 0x30, 0xdf, 0x31, 0x58, 0xc4, 0xdb, 0xe0, 0x72, 0xc7, 0x62, 0xdc, + 0xf1, 0x5c, 0xa3, 0xb7, 0xd4, 0x04, 0xce, 0x96, 0x0c, 0x1b, 0x5c, 0x08, 0x18, 0x87, 0x16, 0xf1, + 0x03, 0x8f, 0x7b, 0x78, 0x36, 0xa1, 0x10, 0xe6, 0x3b, 0x64, 0x94, 0x42, 0x14, 0xa5, 0xba, 0x68, + 0x3b, 0xbc, 0x1d, 0x35, 0x89, 0xe5, 0x75, 0x0d, 0xdb, 0xb3, 0x3d, 0x43, 0x32, 0x9b, 0xd1, 0xbe, + 0x3c, 0xc9, 0x83, 0xfc, 0x4a, 0x14, 0xab, 0x0b, 0xe3, 0x8a, 0xb8, 0x98, 0xbf, 0xba, 0x32, 0x88, + 0xee, 0x32, 0xab, 0xed, 0xb8, 0x10, 0x1c, 0x1a, 0x7e, 0xc7, 0x16, 0x40, 0x68, 0x74, 0x81, 0xb3, + 0x7f, 0xb1, 0x8c, 0xab, 0x58, 0x41, 0xe4, 0x72, 0xa7, 0x0b, 0x97, 0x08, 0xab, 0xd7, 0x11, 0x42, + 0xab, 0x0d, 0x5d, 0x76, 0x91, 0x57, 0x7f, 0x8a, 0xd0, 0xe6, 0x27, 0x1e, 0xb0, 0xd7, 0xec, 0x20, + 0x02, 0x5c, 0x43, 0x05, 0x87, 0x43, 0x37, 0x9c, 0xd6, 0x66, 0x72, 0x73, 0x25, 0xb3, 0x14, 0xf7, + 0x6b, 0x85, 0x6d, 0x01, 0xd0, 0x04, 0x5f, 0x2f, 0x7e, 0xf9, 0x5a, 0xcb, 0x1c, 0xfd, 0x9c, 0xc9, + 0xd4, 0x7f, 0x68, 0x68, 0xaa, 0x01, 0x07, 0xfb, 0x8d, 0xa8, 0xf9, 0x01, 0x2c, 0x4e, 0xa1, 0xe7, + 0xc0, 0x47, 0xfc, 0x1e, 0x15, 0x45, 0x4b, 0x2d, 0xc6, 0xd9, 0xb4, 0x36, 0xa3, 0xcd, 0x95, 0x97, + 0x9f, 0x90, 0xc1, 0x00, 0xd2, 0xca, 0x88, 0xdf, 0xb1, 0x05, 0x10, 0x12, 0x11, 0x4d, 0x7a, 0x4b, + 0xe4, 0x95, 0x54, 0xd9, 0x01, 0xce, 0x4c, 0x7c, 0xdc, 0xaf, 0x65, 0xe2, 0x7e, 0x0d, 0x0d, 0x30, + 0x9a, 0xaa, 0xe2, 0x26, 0x9a, 0x08, 0x39, 0xe3, 0x51, 0x38, 0x9d, 0x95, 0xfa, 0xeb, 0xe4, 0xda, + 0x01, 0x93, 0x4b, 0x75, 0x36, 0xa4, 0x82, 0x79, 0x57, 0x65, 0x9a, 0x48, 0xce, 0x54, 0x29, 0xd7, + 0x3d, 0xf4, 0xe0, 0x0a, 0x0a, 0xde, 0x45, 0xc5, 0x28, 0x84, 0x60, 0xdb, 0xdd, 0xf7, 0x54, 0x83, + 0x8f, 0xc7, 0x16, 0x40, 0xf6, 0x54, 0xb4, 0x39, 0xa9, 0x92, 0x15, 0xcf, 0x11, 0x9a, 0x2a, 0xd5, + 0xbf, 0x65, 0x51, 0x79, 0xd7, 0xeb, 0x80, 0xfb, 0xdf, 0x6c, 0xdc, 0x45, 0xf9, 0xd0, 0x07, 0x4b, + 0x99, 0xb8, 0x7c, 0x03, 0x13, 0x87, 0xea, 0x6b, 0xf8, 0x60, 0x99, 0x77, 0x94, 0x7e, 0x5e, 0x9c, + 0xa8, 0x54, 0xc3, 0xef, 0xd2, 0xe1, 0xe4, 0xa4, 0xee, 0xca, 0x2d, 0x75, 0xc7, 0x8f, 0xc5, 0x42, + 0xf7, 0x2e, 0x14, 0x81, 0x1f, 0xa1, 0x02, 0x17, 0x90, 0x74, 0xa9, 0x64, 0x56, 0x14, 0xb3, 0x90, + 0xc4, 0x25, 0x77, 0x78, 0x1e, 0x95, 0x58, 0xd4, 0x72, 0xc0, 0xb5, 0x40, 0x6c, 0x8d, 0xd8, 0xec, + 0x4a, 0xdc, 0xaf, 0x95, 0x36, 0xce, 0x41, 0x3a, 0xb8, 0xaf, 0xff, 0xd1, 0xd0, 0xd4, 0xa5, 0x92, + 0xf0, 0x33, 0x54, 0x19, 0x2a, 0x1f, 0x5a, 0x32, 0x5f, 0xd1, 0xbc, 0xaf, 0xf2, 0x55, 0x36, 0x86, + 0x2f, 0xe9, 0x68, 0x2c, 0xde, 0x41, 0x79, 0x31, 0x69, 0xe5, 0xf5, 0xfc, 0x0d, 0x3c, 0x49, 0x97, + 0x26, 0x35, 0x59, 0x20, 0x54, 0xca, 0x8c, 0xb6, 0x93, 0x1f, 0xdf, 0x8e, 0x30, 0x08, 0x82, 0xc0, + 0x0b, 0xe4, 0x40, 0x86, 0x0c, 0xda, 0x14, 0x20, 0x4d, 0xee, 0xea, 0xdf, 0xb3, 0x28, 0xdd, 0x4a, + 0xbc, 0x90, 0x6c, 0xb8, 0xcb, 0xba, 0xa0, 0x5c, 0x1d, 0xd9, 0x5c, 0x81, 0xd3, 0x34, 0x02, 0x3f, + 0x44, 0xb9, 0xc8, 0x69, 0xc9, 0xd6, 0x4a, 0x66, 0x59, 0x05, 0xe6, 0xf6, 0xb6, 0x5f, 0x50, 0x81, + 0xe3, 0x3a, 0x9a, 0xb0, 0x03, 0x2f, 0xf2, 0xc5, 0x42, 0x88, 0x42, 0x91, 0x18, 0xeb, 0x96, 0x44, + 0xa8, 0xba, 0xc1, 0x6f, 0x51, 0x01, 0xc4, 0x13, 0x24, 0x7b, 0x29, 0x2f, 0xaf, 0xde, 0xc2, 0x1f, + 0x22, 0xdf, 0xae, 0x4d, 0x97, 0x07, 0x87, 0x43, 0xad, 0x09, 0x8c, 0x26, 0x9a, 0x55, 0x5b, 0xbd, + 0x6f, 0x32, 0x06, 0x4f, 0xa2, 0x5c, 0x07, 0x0e, 0x93, 0xb6, 0xa8, 0xf8, 0xc4, 0xcf, 0x51, 0xa1, + 0x27, 0x9e, 0x3e, 0x35, 0x9c, 0xc5, 0x1b, 0x24, 0x1f, 0xbc, 0x97, 0x34, 0xe1, 0xae, 0x67, 0xd7, + 0x34, 0x73, 0xeb, 0xf8, 0x4c, 0xcf, 0x9c, 0x9c, 0xe9, 0x99, 0xd3, 0x33, 0x3d, 0x73, 0x14, 0xeb, + 0xda, 0x71, 0xac, 0x6b, 0x27, 0xb1, 0xae, 0x9d, 0xc6, 0xba, 0xf6, 0x2b, 0xd6, 0xb5, 0xcf, 0xbf, + 0xf5, 0xcc, 0x9b, 0xd9, 0x6b, 0x7f, 0x60, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x19, 0x49, + 0x3f, 0xfd, 0x06, 0x00, 0x00, } func (m ExtraValue) Marshal() (dAtA []byte, err error) { @@ -275,6 +337,82 @@ func (m ExtraValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SelfSubjectReview) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SelfSubjectReview) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *SelfSubjectReviewStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SelfSubjectReviewStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReviewStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.UserInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *TokenReview) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -517,6 +655,30 @@ func (m ExtraValue) Size() (n int) { return n } +func (m *SelfSubjectReview) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *SelfSubjectReviewStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.UserInfo.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *TokenReview) Size() (n int) { if m == nil { return 0 @@ -603,6 +765,27 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *SelfSubjectReview) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReview{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "SelfSubjectReviewStatus", "SelfSubjectReviewStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *SelfSubjectReviewStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReviewStatus{`, + `UserInfo:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.UserInfo), "UserInfo", "v11.UserInfo", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func (this *TokenReview) String() string { if this == nil { return "nil" @@ -752,6 +935,205 @@ func (m *ExtraValue) Unmarshal(dAtA []byte) error { } return nil } +func (m *SelfSubjectReview) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SelfSubjectReview: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReview: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SelfSubjectReviewStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SelfSubjectReviewStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReviewStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *TokenReview) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.proto b/vendor/k8s.io/api/authentication/v1beta1/generated.proto index d1847a02e5d..53b4635d7e9 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1beta1/generated.proto @@ -21,6 +21,7 @@ syntax = "proto2"; package k8s.io.api.authentication.v1beta1; +import "k8s.io/api/authentication/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -37,6 +38,26 @@ message ExtraValue { repeated string items = 1; } +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +message SelfSubjectReview { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Status is filled in by the server with the user attributes. + optional SelfSubjectReviewStatus status = 2; +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +message SelfSubjectReviewStatus { + // User attributes of the user making this request. + // +optional + optional k8s.io.api.authentication.v1.UserInfo userInfo = 1; +} + // TokenReview attempts to authenticate a token to a known user. // Note: TokenReview requests may be cached by the webhook token authenticator // plugin in the kube-apiserver. diff --git a/vendor/k8s.io/api/authentication/v1beta1/register.go b/vendor/k8s.io/api/authentication/v1beta1/register.go index ed23e50f7e9..075ee1263dc 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/register.go +++ b/vendor/k8s.io/api/authentication/v1beta1/register.go @@ -44,6 +44,7 @@ var ( // Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, + &SelfSubjectReview{}, &TokenReview{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/vendor/k8s.io/api/authentication/v1beta1/types.go b/vendor/k8s.io/api/authentication/v1beta1/types.go index 08e1e09b640..5bce82e7cfd 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types.go @@ -19,6 +19,7 @@ package v1beta1 import ( "fmt" + v1 "k8s.io/api/authentication/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -113,3 +114,29 @@ type ExtraValue []string func (t ExtraValue) String() string { return fmt.Sprintf("%v", []string(t)) } + +// +genclient +// +genclient:nonNamespaced +// +genclient:onlyVerbs=create +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.27 + +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +type SelfSubjectReview struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Status is filled in by the server with the user attributes. + Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +type SelfSubjectReviewStatus struct { + // User attributes of the user making this request. + // +optional + UserInfo v1.UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` +} diff --git a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go index 1086955c3a8..d6644f2cf9d 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go @@ -24,9 +24,28 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_SelfSubjectReview = map[string]string{ + "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "Status is filled in by the server with the user attributes.", +} + +func (SelfSubjectReview) SwaggerDoc() map[string]string { + return map_SelfSubjectReview +} + +var map_SelfSubjectReviewStatus = map[string]string{ + "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", + "userInfo": "User attributes of the user making this request.", +} + +func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { + return map_SelfSubjectReviewStatus +} + var map_TokenReview = map[string]string{ "": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go index 059ec1a8647..99ffadf7baf 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go @@ -45,6 +45,50 @@ func (in ExtraValue) DeepCopy() ExtraValue { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SelfSubjectReview) DeepCopyInto(out *SelfSubjectReview) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReview. +func (in *SelfSubjectReview) DeepCopy() *SelfSubjectReview { + if in == nil { + return nil + } + out := new(SelfSubjectReview) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SelfSubjectReview) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SelfSubjectReviewStatus) DeepCopyInto(out *SelfSubjectReviewStatus) { + *out = *in + in.UserInfo.DeepCopyInto(&out.UserInfo) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReviewStatus. +func (in *SelfSubjectReviewStatus) DeepCopy() *SelfSubjectReviewStatus { + if in == nil { + return nil + } + out := new(SelfSubjectReviewStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TokenReview) DeepCopyInto(out *TokenReview) { *out = *in diff --git a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go index e448106e419..904796925c1 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go @@ -25,6 +25,24 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" ) +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *SelfSubjectReview) APILifecycleIntroduced() (major, minor int) { + return 1, 27 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *SelfSubjectReview) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *SelfSubjectReview) APILifecycleRemoved() (major, minor int) { + return 1, 33 +} + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *TokenReview) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go index 2e5fbea7ad6..93229485cc0 100644 --- a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_LocalSubjectAccessReview = map[string]string{ diff --git a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go index 2d291189eb2..e0846be7a4d 100644 --- a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_LocalSubjectAccessReview = map[string]string{ diff --git a/vendor/k8s.io/api/autoscaling/v1/generated.proto b/vendor/k8s.io/api/autoscaling/v1/generated.proto index 9820705e762..1dbafd1a531 100644 --- a/vendor/k8s.io/api/autoscaling/v1/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v1/generated.proto @@ -87,13 +87,13 @@ message ContainerResourceMetricStatus { // CrossVersionObjectReference contains enough information to let you identify the referred resource. // +structType=atomic message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -147,11 +147,11 @@ message HorizontalPodAutoscaler { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional HorizontalPodAutoscalerSpec spec = 2; - // current information about the autoscaler. + // status is the current information about the autoscaler. // +optional optional HorizontalPodAutoscalerStatus status = 3; } @@ -186,7 +186,7 @@ message HorizontalPodAutoscalerList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // list of horizontal pod autoscaler objects. + // items is the list of horizontal pod autoscaler objects. repeated HorizontalPodAutoscaler items = 2; } @@ -204,10 +204,10 @@ message HorizontalPodAutoscalerSpec { // +optional optional int32 minReplicas = 2; - // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. optional int32 maxReplicas = 3; - // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; // if not specified the default autoscaling policy will be used. // +optional optional int32 targetCPUUtilizationPercentage = 4; @@ -215,22 +215,22 @@ message HorizontalPodAutoscalerSpec { // current status of a horizontal pod autoscaler message HorizontalPodAutoscalerStatus { - // most recent generation observed by this autoscaler. + // observedGeneration is the most recent generation observed by this autoscaler. // +optional optional int64 observedGeneration = 1; - // last time the HorizontalPodAutoscaler scaled the number of pods; + // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; // used by the autoscaler to control how often the number of pods is changed. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastScaleTime = 2; - // current number of replicas of pods managed by this autoscaler. + // currentReplicas is the current number of replicas of pods managed by this autoscaler. optional int32 currentReplicas = 3; - // desired number of replicas of pods managed by this autoscaler. + // desiredReplicas is the desired number of replicas of pods managed by this autoscaler. optional int32 desiredReplicas = 4; - // current average CPU utilization over all pods, represented as a percentage of requested CPU, + // currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, // e.g. 70 means that an average pod is using now 70% of its requested CPU. // +optional optional int32 currentCPUUtilizationPercentage = 5; @@ -264,7 +264,7 @@ message MetricSpec { // +optional optional ResourceMetricSource resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod of the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -309,7 +309,7 @@ message MetricStatus { // +optional optional ResourceMetricStatus resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -464,31 +464,31 @@ message Scale { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional ScaleSpec spec = 2; - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional optional ScaleStatus status = 3; } // ScaleSpec describes the attributes of a scale subresource. message ScaleSpec { - // desired number of instances for the scaled object. + // replicas is the desired number of instances for the scaled object. // +optional optional int32 replicas = 1; } // ScaleStatus represents the current status of a scale subresource. message ScaleStatus { - // actual number of observed instances of the scaled object. + // replicas is the actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. This is same + // selector is the label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional optional string selector = 2; } diff --git a/vendor/k8s.io/api/autoscaling/v1/types.go b/vendor/k8s.io/api/autoscaling/v1/types.go index 8e0a46525e1..45082901764 100644 --- a/vendor/k8s.io/api/autoscaling/v1/types.go +++ b/vendor/k8s.io/api/autoscaling/v1/types.go @@ -25,11 +25,13 @@ import ( // CrossVersionObjectReference contains enough information to let you identify the referred resource. // +structType=atomic type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -46,9 +48,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` - // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + + // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` - // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + + // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; // if not specified the default autoscaling policy will be used. // +optional TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage,omitempty" protobuf:"varint,4,opt,name=targetCPUUtilizationPercentage"` @@ -56,22 +60,22 @@ type HorizontalPodAutoscalerSpec struct { // current status of a horizontal pod autoscaler type HorizontalPodAutoscalerStatus struct { - // most recent generation observed by this autoscaler. + // observedGeneration is the most recent generation observed by this autoscaler. // +optional ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // last time the HorizontalPodAutoscaler scaled the number of pods; + // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; // used by the autoscaler to control how often the number of pods is changed. // +optional LastScaleTime *metav1.Time `json:"lastScaleTime,omitempty" protobuf:"bytes,2,opt,name=lastScaleTime"` - // current number of replicas of pods managed by this autoscaler. + // currentReplicas is the current number of replicas of pods managed by this autoscaler. CurrentReplicas int32 `json:"currentReplicas" protobuf:"varint,3,opt,name=currentReplicas"` - // desired number of replicas of pods managed by this autoscaler. + // desiredReplicas is the desired number of replicas of pods managed by this autoscaler. DesiredReplicas int32 `json:"desiredReplicas" protobuf:"varint,4,opt,name=desiredReplicas"` - // current average CPU utilization over all pods, represented as a percentage of requested CPU, + // currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, // e.g. 70 means that an average pod is using now 70% of its requested CPU. // +optional CurrentCPUUtilizationPercentage *int32 `json:"currentCPUUtilizationPercentage,omitempty" protobuf:"varint,5,opt,name=currentCPUUtilizationPercentage"` @@ -87,11 +91,11 @@ type HorizontalPodAutoscaler struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current information about the autoscaler. + // status is the current information about the autoscaler. // +optional Status HorizontalPodAutoscalerStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -105,7 +109,7 @@ type HorizontalPodAutoscalerList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // list of horizontal pod autoscaler objects. + // items is the list of horizontal pod autoscaler objects. Items []HorizontalPodAutoscaler `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -118,31 +122,31 @@ type Scale struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec ScaleSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional Status ScaleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // ScaleSpec describes the attributes of a scale subresource. type ScaleSpec struct { - // desired number of instances for the scaled object. + // replicas is the desired number of instances for the scaled object. // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } // ScaleStatus represents the current status of a scale subresource. type ScaleStatus struct { - // actual number of observed instances of the scaled object. + // replicas is the actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. This is same + // selector is the label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional Selector string `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` } @@ -194,11 +198,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -206,7 +212,8 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod of the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -214,6 +221,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -231,6 +239,7 @@ type ObjectMetricSource struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` + // targetValue is the target value of the metric (as a quantity). TargetValue resource.Quantity `json:"targetValue" protobuf:"bytes,3,name=targetValue"` @@ -239,6 +248,7 @@ type ObjectMetricSource struct { // When unset, just the metricName will be used to gather metrics. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional @@ -252,6 +262,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metricName is the name of the metric in question MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // targetAverageValue is the target value of the average of the // metric across all relevant pods (as a quantity) TargetAverageValue resource.Quantity `json:"targetAverageValue" protobuf:"bytes,2,name=targetAverageValue"` @@ -273,11 +284,13 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // targetAverageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` + // targetAverageValue is the target value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. @@ -295,16 +308,19 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // targetAverageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` + // targetAverageValue is the target value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. // +optional TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"` + // container is the name of the container in the pods of the scaling target. Container string `json:"container" protobuf:"bytes,5,opt,name=container"` } @@ -315,14 +331,17 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // metricSelector is used to identify a specific time series // within a given metric. // +optional MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` + // targetValue is the target value of the metric (as a quantity). // Mutually exclusive with TargetAverageValue. // +optional TargetValue *resource.Quantity `json:"targetValue,omitempty" protobuf:"bytes,3,opt,name=targetValue"` + // targetAverageValue is the target per-pod value of global metric (as a quantity). // Mutually exclusive with TargetValue. // +optional @@ -341,11 +360,13 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -353,13 +374,15 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -390,15 +413,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -413,6 +440,7 @@ type ObjectMetricStatus struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` + // currentValue is the current value of the metric (as a quantity). CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` @@ -421,6 +449,7 @@ type ObjectMetricStatus struct { // When unset, just the metricName will be used to gather metrics. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional @@ -432,6 +461,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metricName is the name of the metric in question MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // currentAverageValue is the current value of the average of the // metric across all relevant pods (as a quantity) CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,2,name=currentAverageValue"` @@ -451,6 +481,7 @@ type PodsMetricStatus struct { type ResourceMetricStatus struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. It will only be @@ -458,6 +489,7 @@ type ResourceMetricStatus struct { // specification. // +optional CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` + // currentAverageValue is the current value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. @@ -473,6 +505,7 @@ type ResourceMetricStatus struct { type ContainerResourceMetricStatus struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. It will only be @@ -480,11 +513,13 @@ type ContainerResourceMetricStatus struct { // specification. // +optional CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` + // currentAverageValue is the current value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. // It will always be set, regardless of the corresponding metric specification. CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"` + // container is the name of the container in the pods of the scaling taget Container string `json:"container" protobuf:"bytes,4,opt,name=container"` } @@ -495,12 +530,14 @@ type ExternalMetricStatus struct { // metricName is the name of a metric used for autoscaling in // metric system. MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // metricSelector is used to identify a specific time series // within a given metric. // +optional MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` // currentValue is the current value of the metric (as a quantity) CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` + // currentAverageValue is the current value of metric averaged over autoscaled pods. // +optional CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty" protobuf:"bytes,4,opt,name=currentAverageValue"` diff --git a/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go index 192dc5f3985..37c2b36a51f 100644 --- a/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -53,9 +53,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -89,8 +89,8 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscaler = map[string]string{ "": "configuration of a horizontal pod autoscaler.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current information about the autoscaler.", + "spec": "spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status is the current information about the autoscaler.", } func (HorizontalPodAutoscaler) SwaggerDoc() map[string]string { @@ -113,7 +113,7 @@ func (HorizontalPodAutoscalerCondition) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscalerList = map[string]string{ "": "list of horizontal pod autoscaler objects.", "metadata": "Standard list metadata.", - "items": "list of horizontal pod autoscaler objects.", + "items": "items is the list of horizontal pod autoscaler objects.", } func (HorizontalPodAutoscalerList) SwaggerDoc() map[string]string { @@ -124,8 +124,8 @@ var map_HorizontalPodAutoscalerSpec = map[string]string{ "": "specification of a horizontal pod autoscaler.", "scaleTargetRef": "reference to scaled resource; horizontal pod autoscaler will learn the current resource consumption and will set the desired number of pods by using its Scale subresource.", "minReplicas": "minReplicas is the lower limit for the number of replicas to which the autoscaler can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the alpha feature gate HPAScaleToZero is enabled and at least one Object or External metric is configured. Scaling is active as long as at least one metric value is available.", - "maxReplicas": "upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.", - "targetCPUUtilizationPercentage": "target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.", + "maxReplicas": "maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.", + "targetCPUUtilizationPercentage": "targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.", } func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { @@ -134,11 +134,11 @@ func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscalerStatus = map[string]string{ "": "current status of a horizontal pod autoscaler", - "observedGeneration": "most recent generation observed by this autoscaler.", - "lastScaleTime": "last time the HorizontalPodAutoscaler scaled the number of pods; used by the autoscaler to control how often the number of pods is changed.", - "currentReplicas": "current number of replicas of pods managed by this autoscaler.", - "desiredReplicas": "desired number of replicas of pods managed by this autoscaler.", - "currentCPUUtilizationPercentage": "current average CPU utilization over all pods, represented as a percentage of requested CPU, e.g. 70 means that an average pod is using now 70% of its requested CPU.", + "observedGeneration": "observedGeneration is the most recent generation observed by this autoscaler.", + "lastScaleTime": "lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; used by the autoscaler to control how often the number of pods is changed.", + "currentReplicas": "currentReplicas is the current number of replicas of pods managed by this autoscaler.", + "desiredReplicas": "desiredReplicas is the desired number of replicas of pods managed by this autoscaler.", + "currentCPUUtilizationPercentage": "currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, e.g. 70 means that an average pod is using now 70% of its requested CPU.", } func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { @@ -151,7 +151,7 @@ var map_MetricSpec = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -165,7 +165,7 @@ var map_MetricStatus = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -246,8 +246,8 @@ func (ResourceMetricStatus) SwaggerDoc() map[string]string { var map_Scale = map[string]string{ "": "Scale represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", + "spec": "spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -256,7 +256,7 @@ func (Scale) SwaggerDoc() map[string]string { var map_ScaleSpec = map[string]string{ "": "ScaleSpec describes the attributes of a scale subresource.", - "replicas": "desired number of instances for the scaled object.", + "replicas": "replicas is the desired number of instances for the scaled object.", } func (ScaleSpec) SwaggerDoc() map[string]string { @@ -265,8 +265,8 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", - "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "replicas": "replicas is the actual number of observed instances of the scaled object.", + "selector": "selector is the label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", } func (ScaleStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/autoscaling/v2/generated.proto b/vendor/k8s.io/api/autoscaling/v2/generated.proto index 0595f1eb8fc..a9e36975fca 100644 --- a/vendor/k8s.io/api/autoscaling/v2/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2/generated.proto @@ -54,25 +54,25 @@ message ContainerResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ContainerResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric optional MetricValueStatus current = 2; - // Container is the name of the container in the pods of the scaling target + // container is the name of the container in the pods of the scaling target optional string container = 3; } // CrossVersionObjectReference contains enough information to let you identify the referred resource. message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -100,14 +100,14 @@ message ExternalMetricStatus { // HPAScalingPolicy is a single policy which must hold true for a specified past interval. message HPAScalingPolicy { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. optional string type = 1; - // Value contains the amount of change which is permitted by the policy. + // value contains the amount of change which is permitted by the policy. // It must be greater than zero optional int32 value = 2; - // PeriodSeconds specifies the window of time for which the policy should hold true. + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). optional int32 periodSeconds = 3; } @@ -119,7 +119,7 @@ message HPAScalingPolicy { // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. message HPAScalingRules { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). // If not set, use the default values: @@ -495,7 +495,7 @@ message ResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric diff --git a/vendor/k8s.io/api/autoscaling/v2/types.go b/vendor/k8s.io/api/autoscaling/v2/types.go index 9931f6146b8..c12a83df1bf 100644 --- a/vendor/k8s.io/api/autoscaling/v2/types.go +++ b/vendor/k8s.io/api/autoscaling/v2/types.go @@ -59,9 +59,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` + // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` + // metrics contains the specifications for which to use to calculate the // desired replica count (the maximum replica count across all metrics will // be used). The desired replica count is calculated multiplying the @@ -83,11 +85,13 @@ type HorizontalPodAutoscalerSpec struct { // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -105,11 +109,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -117,6 +123,7 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in // each pod of the current scale target (e.g. CPU or memory). Such metrics are @@ -125,6 +132,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -144,6 +152,7 @@ type HorizontalPodAutoscalerBehavior struct { // No stabilization is used. // +optional ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" protobuf:"bytes,1,opt,name=scaleUp"` + // scaleDown is scaling policy for scaling Down. // If not set, the default value is to allow to scale down to minReplicas pods, with a // 300 second stabilization window (i.e., the highest recommendation for @@ -171,7 +180,7 @@ const ( // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. type HPAScalingRules struct { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). // If not set, use the default values: @@ -179,10 +188,12 @@ type HPAScalingRules struct { // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). // +optional StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty" protobuf:"varint,3,opt,name=stabilizationWindowSeconds"` + // selectPolicy is used to specify which policy should be used. // If not set, the default value Max is used. // +optional SelectPolicy *ScalingPolicySelect `json:"selectPolicy,omitempty" protobuf:"bytes,1,opt,name=selectPolicy"` + // policies is a list of potential scaling polices which can be used during scaling. // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid // +listType=atomic @@ -203,12 +214,14 @@ const ( // HPAScalingPolicy is a single policy which must hold true for a specified past interval. type HPAScalingPolicy struct { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. Type HPAScalingPolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=HPAScalingPolicyType"` - // Value contains the amount of change which is permitted by the policy. + + // value contains the amount of change which is permitted by the policy. // It must be greater than zero Value int32 `json:"value" protobuf:"varint,2,opt,name=value"` - // PeriodSeconds specifies the window of time for which the policy should hold true. + + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). PeriodSeconds int32 `json:"periodSeconds" protobuf:"varint,3,opt,name=periodSeconds"` } @@ -249,8 +262,10 @@ const ( type ObjectMetricSource struct { // describedObject specifies the descriptions of a object,such as kind,name apiVersion DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,1,name=describedObject"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,3,name=metric"` } @@ -262,6 +277,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -276,6 +292,7 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -290,8 +307,10 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -302,6 +321,7 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -310,6 +330,7 @@ type ExternalMetricSource struct { type MetricIdentifier struct { // name is the name of the given metric Name string `json:"name" protobuf:"bytes,1,name=name"` + // selector is the string-encoded form of a standard kubernetes label selector for the given metric // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. // When unset, just the metricName will be used to gather metrics. @@ -321,13 +342,16 @@ type MetricIdentifier struct { type MetricTarget struct { // type represents whether the metric type is Utilization, Value, or AverageValue Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` + // value is the target value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` + // averageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. @@ -405,15 +429,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -432,11 +460,13 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -444,6 +474,7 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // container resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -451,6 +482,7 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -465,8 +497,10 @@ type MetricStatus struct { type ObjectMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` + // DescribedObject specifies the descriptions of a object,such as kind,name apiVersion DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,3,name=describedObject"` } @@ -476,6 +510,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -486,8 +521,9 @@ type PodsMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -498,11 +534,13 @@ type ResourceMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ContainerResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - // Container is the name of the container in the pods of the scaling target + + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -511,6 +549,7 @@ type ContainerResourceMetricStatus struct { type ExternalMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -520,10 +559,12 @@ type MetricValueStatus struct { // value is the current value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. diff --git a/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go index 05355a5523a..1941b1ef57a 100644 --- a/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -40,9 +40,9 @@ func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { var map_ContainerResourceMetricStatus = map[string]string{ "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", - "container": "Container is the name of the container in the pods of the scaling target", + "container": "container is the name of the container in the pods of the scaling target", } func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { @@ -51,9 +51,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HPAScalingPolicy = map[string]string{ "": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", - "type": "Type is used to specify the scaling policy.", - "value": "Value contains the amount of change which is permitted by the policy. It must be greater than zero", - "periodSeconds": "PeriodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", + "type": "type is used to specify the scaling policy.", + "value": "value contains the amount of change which is permitted by the policy. It must be greater than zero", + "periodSeconds": "periodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", } func (HPAScalingPolicy) SwaggerDoc() map[string]string { @@ -93,7 +93,7 @@ func (HPAScalingPolicy) SwaggerDoc() map[string]string { var map_HPAScalingRules = map[string]string{ "": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", - "stabilizationWindowSeconds": "StabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", + "stabilizationWindowSeconds": "stabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", "selectPolicy": "selectPolicy is used to specify which policy should be used. If not set, the default value Max is used.", "policies": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", } @@ -288,7 +288,7 @@ func (ResourceMetricSource) SwaggerDoc() map[string]string { var map_ResourceMetricStatus = map[string]string{ "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", } diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto index ebd3b31faee..6b3d4152126 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto @@ -86,10 +86,10 @@ message ContainerResourceMetricStatus { // CrossVersionObjectReference contains enough information to let you identify the referred resource. message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; // API version of the referent diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types.go b/vendor/k8s.io/api/autoscaling/v2beta1/types.go index 22bb7699e9d..842284072d9 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types.go +++ b/vendor/k8s.io/api/autoscaling/v2beta1/types.go @@ -24,9 +24,9 @@ import ( // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` // API version of the referent // +optional diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go index 08a54621f8f..d656ee416da 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -53,8 +53,8 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", "apiVersion": "API version of the referent", } diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto index 920031b1a19..5b2fe9442aa 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto @@ -54,25 +54,25 @@ message ContainerResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ContainerResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric optional MetricValueStatus current = 2; - // Container is the name of the container in the pods of the scaling target + // container is the name of the container in the pods of the scaling target optional string container = 3; } // CrossVersionObjectReference contains enough information to let you identify the referred resource. message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -100,14 +100,14 @@ message ExternalMetricStatus { // HPAScalingPolicy is a single policy which must hold true for a specified past interval. message HPAScalingPolicy { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. optional string type = 1; - // Value contains the amount of change which is permitted by the policy. + // value contains the amount of change which is permitted by the policy. // It must be greater than zero optional int32 value = 2; - // PeriodSeconds specifies the window of time for which the policy should hold true. + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). optional int32 periodSeconds = 3; } @@ -119,7 +119,7 @@ message HPAScalingPolicy { // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. message HPAScalingRules { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). // If not set, use the default values: @@ -361,7 +361,7 @@ message MetricStatus { // +optional optional ResourceMetricStatus resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -411,7 +411,7 @@ message MetricValueStatus { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 2; - // currentAverageUtilization is the current value of the average of the + // averageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional @@ -485,7 +485,7 @@ message ResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types.go b/vendor/k8s.io/api/autoscaling/v2beta2/types.go index 10bdec5b940..b0b7681c0eb 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types.go +++ b/vendor/k8s.io/api/autoscaling/v2beta2/types.go @@ -62,9 +62,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` + // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` + // metrics contains the specifications for which to use to calculate the // desired replica count (the maximum replica count across all metrics will // be used). The desired replica count is calculated multiplying the @@ -85,11 +87,13 @@ type HorizontalPodAutoscalerSpec struct { // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -107,11 +111,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -119,6 +125,7 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // container resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in // each pod of the current scale target (e.g. CPU or memory). Such metrics are @@ -127,6 +134,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -146,6 +154,7 @@ type HorizontalPodAutoscalerBehavior struct { // No stabilization is used. // +optional ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" protobuf:"bytes,1,opt,name=scaleUp"` + // scaleDown is scaling policy for scaling Down. // If not set, the default value is to allow to scale down to minReplicas pods, with a // 300 second stabilization window (i.e., the highest recommendation for @@ -173,7 +182,7 @@ const ( // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. type HPAScalingRules struct { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). // If not set, use the default values: @@ -181,10 +190,12 @@ type HPAScalingRules struct { // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). // +optional StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty" protobuf:"varint,3,opt,name=stabilizationWindowSeconds"` + // selectPolicy is used to specify which policy should be used. // If not set, the default value MaxPolicySelect is used. // +optional SelectPolicy *ScalingPolicySelect `json:"selectPolicy,omitempty" protobuf:"bytes,1,opt,name=selectPolicy"` + // policies is a list of potential scaling polices which can be used during scaling. // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid // +optional @@ -204,12 +215,14 @@ const ( // HPAScalingPolicy is a single policy which must hold true for a specified past interval. type HPAScalingPolicy struct { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. Type HPAScalingPolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=HPAScalingPolicyType"` - // Value contains the amount of change which is permitted by the policy. + + // value contains the amount of change which is permitted by the policy. // It must be greater than zero Value int32 `json:"value" protobuf:"varint,2,opt,name=value"` - // PeriodSeconds specifies the window of time for which the policy should hold true. + + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). PeriodSeconds int32 `json:"periodSeconds" protobuf:"varint,3,opt,name=periodSeconds"` } @@ -251,6 +264,7 @@ type ObjectMetricSource struct { DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,1,name=describedObject"` // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,3,name=metric"` } @@ -262,6 +276,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -276,6 +291,7 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -290,8 +306,10 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -302,6 +320,7 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -310,6 +329,7 @@ type ExternalMetricSource struct { type MetricIdentifier struct { // name is the name of the given metric Name string `json:"name" protobuf:"bytes,1,name=name"` + // selector is the string-encoded form of a standard kubernetes label selector for the given metric // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. // When unset, just the metricName will be used to gather metrics. @@ -321,13 +341,16 @@ type MetricIdentifier struct { type MetricTarget struct { // type represents whether the metric type is Utilization, Value, or AverageValue Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` + // value is the target value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` + // averageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. @@ -399,15 +422,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -426,6 +453,7 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. @@ -438,13 +466,15 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -459,6 +489,7 @@ type MetricStatus struct { type ObjectMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` @@ -470,6 +501,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -480,8 +512,9 @@ type PodsMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -492,11 +525,13 @@ type ResourceMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ContainerResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - // Container is the name of the container in the pods of the scaling target + + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -505,6 +540,7 @@ type ContainerResourceMetricStatus struct { type ExternalMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -514,11 +550,13 @@ type MetricValueStatus struct { // value is the current value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"` - // currentAverageUtilization is the current value of the average of the + + // averageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go index e3ea3002bdd..4af7d0ec0d2 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -40,9 +40,9 @@ func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { var map_ContainerResourceMetricStatus = map[string]string{ "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", - "container": "Container is the name of the container in the pods of the scaling target", + "container": "container is the name of the container in the pods of the scaling target", } func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { @@ -51,9 +51,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HPAScalingPolicy = map[string]string{ "": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", - "type": "Type is used to specify the scaling policy.", - "value": "Value contains the amount of change which is permitted by the policy. It must be greater than zero", - "periodSeconds": "PeriodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", + "type": "type is used to specify the scaling policy.", + "value": "value contains the amount of change which is permitted by the policy. It must be greater than zero", + "periodSeconds": "periodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", } func (HPAScalingPolicy) SwaggerDoc() map[string]string { @@ -93,7 +93,7 @@ func (HPAScalingPolicy) SwaggerDoc() map[string]string { var map_HPAScalingRules = map[string]string{ "": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", - "stabilizationWindowSeconds": "StabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", + "stabilizationWindowSeconds": "stabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", "selectPolicy": "selectPolicy is used to specify which policy should be used. If not set, the default value MaxPolicySelect is used.", "policies": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", } @@ -203,7 +203,7 @@ var map_MetricStatus = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -227,7 +227,7 @@ var map_MetricValueStatus = map[string]string{ "": "MetricValueStatus holds the current value for a metric", "value": "value is the current value of the metric (as a quantity).", "averageValue": "averageValue is the current value of the average of the metric across all relevant pods (as a quantity)", - "averageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", + "averageUtilization": "averageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", } func (MetricValueStatus) SwaggerDoc() map[string]string { @@ -286,7 +286,7 @@ func (ResourceMetricSource) SwaggerDoc() map[string]string { var map_ResourceMetricStatus = map[string]string{ "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", } diff --git a/vendor/k8s.io/api/batch/v1/generated.pb.go b/vendor/k8s.io/api/batch/v1/generated.pb.go index 483406d84c5..feafc23c2bb 100644 --- a/vendor/k8s.io/api/batch/v1/generated.pb.go +++ b/vendor/k8s.io/api/batch/v1/generated.pb.go @@ -328,10 +328,126 @@ func (m *JobTemplateSpec) XXX_DiscardUnknown() { var xxx_messageInfo_JobTemplateSpec proto.InternalMessageInfo +func (m *PodFailurePolicy) Reset() { *m = PodFailurePolicy{} } +func (*PodFailurePolicy) ProtoMessage() {} +func (*PodFailurePolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_3b52da57c93de713, []int{10} +} +func (m *PodFailurePolicy) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodFailurePolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodFailurePolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodFailurePolicy.Merge(m, src) +} +func (m *PodFailurePolicy) XXX_Size() int { + return m.Size() +} +func (m *PodFailurePolicy) XXX_DiscardUnknown() { + xxx_messageInfo_PodFailurePolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_PodFailurePolicy proto.InternalMessageInfo + +func (m *PodFailurePolicyOnExitCodesRequirement) Reset() { + *m = PodFailurePolicyOnExitCodesRequirement{} +} +func (*PodFailurePolicyOnExitCodesRequirement) ProtoMessage() {} +func (*PodFailurePolicyOnExitCodesRequirement) Descriptor() ([]byte, []int) { + return fileDescriptor_3b52da57c93de713, []int{11} +} +func (m *PodFailurePolicyOnExitCodesRequirement) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodFailurePolicyOnExitCodesRequirement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodFailurePolicyOnExitCodesRequirement) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodFailurePolicyOnExitCodesRequirement.Merge(m, src) +} +func (m *PodFailurePolicyOnExitCodesRequirement) XXX_Size() int { + return m.Size() +} +func (m *PodFailurePolicyOnExitCodesRequirement) XXX_DiscardUnknown() { + xxx_messageInfo_PodFailurePolicyOnExitCodesRequirement.DiscardUnknown(m) +} + +var xxx_messageInfo_PodFailurePolicyOnExitCodesRequirement proto.InternalMessageInfo + +func (m *PodFailurePolicyOnPodConditionsPattern) Reset() { + *m = PodFailurePolicyOnPodConditionsPattern{} +} +func (*PodFailurePolicyOnPodConditionsPattern) ProtoMessage() {} +func (*PodFailurePolicyOnPodConditionsPattern) Descriptor() ([]byte, []int) { + return fileDescriptor_3b52da57c93de713, []int{12} +} +func (m *PodFailurePolicyOnPodConditionsPattern) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodFailurePolicyOnPodConditionsPattern) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodFailurePolicyOnPodConditionsPattern) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodFailurePolicyOnPodConditionsPattern.Merge(m, src) +} +func (m *PodFailurePolicyOnPodConditionsPattern) XXX_Size() int { + return m.Size() +} +func (m *PodFailurePolicyOnPodConditionsPattern) XXX_DiscardUnknown() { + xxx_messageInfo_PodFailurePolicyOnPodConditionsPattern.DiscardUnknown(m) +} + +var xxx_messageInfo_PodFailurePolicyOnPodConditionsPattern proto.InternalMessageInfo + +func (m *PodFailurePolicyRule) Reset() { *m = PodFailurePolicyRule{} } +func (*PodFailurePolicyRule) ProtoMessage() {} +func (*PodFailurePolicyRule) Descriptor() ([]byte, []int) { + return fileDescriptor_3b52da57c93de713, []int{13} +} +func (m *PodFailurePolicyRule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodFailurePolicyRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodFailurePolicyRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodFailurePolicyRule.Merge(m, src) +} +func (m *PodFailurePolicyRule) XXX_Size() int { + return m.Size() +} +func (m *PodFailurePolicyRule) XXX_DiscardUnknown() { + xxx_messageInfo_PodFailurePolicyRule.DiscardUnknown(m) +} + +var xxx_messageInfo_PodFailurePolicyRule proto.InternalMessageInfo + func (m *UncountedTerminatedPods) Reset() { *m = UncountedTerminatedPods{} } func (*UncountedTerminatedPods) ProtoMessage() {} func (*UncountedTerminatedPods) Descriptor() ([]byte, []int) { - return fileDescriptor_3b52da57c93de713, []int{10} + return fileDescriptor_3b52da57c93de713, []int{14} } func (m *UncountedTerminatedPods) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -367,6 +483,10 @@ func init() { proto.RegisterType((*JobSpec)(nil), "k8s.io.api.batch.v1.JobSpec") proto.RegisterType((*JobStatus)(nil), "k8s.io.api.batch.v1.JobStatus") proto.RegisterType((*JobTemplateSpec)(nil), "k8s.io.api.batch.v1.JobTemplateSpec") + proto.RegisterType((*PodFailurePolicy)(nil), "k8s.io.api.batch.v1.PodFailurePolicy") + proto.RegisterType((*PodFailurePolicyOnExitCodesRequirement)(nil), "k8s.io.api.batch.v1.PodFailurePolicyOnExitCodesRequirement") + proto.RegisterType((*PodFailurePolicyOnPodConditionsPattern)(nil), "k8s.io.api.batch.v1.PodFailurePolicyOnPodConditionsPattern") + proto.RegisterType((*PodFailurePolicyRule)(nil), "k8s.io.api.batch.v1.PodFailurePolicyRule") proto.RegisterType((*UncountedTerminatedPods)(nil), "k8s.io.api.batch.v1.UncountedTerminatedPods") } @@ -375,97 +495,113 @@ func init() { } var fileDescriptor_3b52da57c93de713 = []byte{ - // 1431 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x41, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0xc6, 0x71, 0x6c, 0x8f, 0x93, 0xd4, 0x9d, 0xfe, 0xdb, 0xfa, 0x6f, 0x2a, 0x6f, 0x6a, - 0x0a, 0x0a, 0xa8, 0xac, 0x49, 0x88, 0x10, 0x20, 0x40, 0xca, 0xa6, 0x2a, 0x34, 0x38, 0x6a, 0x18, - 0x3b, 0x42, 0x2a, 0x05, 0xb1, 0xde, 0x1d, 0x3b, 0xdb, 0xac, 0x77, 0xac, 0x9d, 0x71, 0x84, 0x6f, - 0x48, 0x7c, 0x01, 0xf8, 0x12, 0x1c, 0x11, 0x12, 0x9c, 0x39, 0xa2, 0x1e, 0x2b, 0x4e, 0x3d, 0xad, - 0xe8, 0xf2, 0x01, 0xb8, 0x87, 0x0b, 0x9a, 0xd9, 0xf1, 0xee, 0xda, 0xde, 0x0d, 0x49, 0x0f, 0x15, - 0xb7, 0xcc, 0x9b, 0xdf, 0xfb, 0xcd, 0xdb, 0x79, 0xbf, 0x79, 0xef, 0x39, 0xe0, 0xfd, 0xe3, 0x77, - 0xa8, 0x66, 0x93, 0xe6, 0xf1, 0xa8, 0x8b, 0x3d, 0x17, 0x33, 0x4c, 0x9b, 0x27, 0xd8, 0xb5, 0x88, - 0xd7, 0x94, 0x1b, 0xc6, 0xd0, 0x6e, 0x76, 0x0d, 0x66, 0x1e, 0x35, 0x4f, 0x36, 0x9b, 0x7d, 0xec, - 0x62, 0xcf, 0x60, 0xd8, 0xd2, 0x86, 0x1e, 0x61, 0x04, 0x5e, 0x09, 0x41, 0x9a, 0x31, 0xb4, 0x35, - 0x01, 0xd2, 0x4e, 0x36, 0x6b, 0x6f, 0xf4, 0x6d, 0x76, 0x34, 0xea, 0x6a, 0x26, 0x19, 0x34, 0xfb, - 0xa4, 0x4f, 0x9a, 0x02, 0xdb, 0x1d, 0xf5, 0xc4, 0x4a, 0x2c, 0xc4, 0x5f, 0x21, 0x47, 0xad, 0x91, - 0x38, 0xc8, 0x24, 0x1e, 0x4e, 0x39, 0xa7, 0xb6, 0x1d, 0x63, 0x06, 0x86, 0x79, 0x64, 0xbb, 0xd8, - 0x1b, 0x37, 0x87, 0xc7, 0x7d, 0x6e, 0xa0, 0xcd, 0x01, 0x66, 0x46, 0x9a, 0x57, 0x33, 0xcb, 0xcb, - 0x1b, 0xb9, 0xcc, 0x1e, 0xe0, 0x39, 0x87, 0xb7, 0xff, 0xcd, 0x81, 0x9a, 0x47, 0x78, 0x60, 0xcc, - 0xfa, 0x35, 0xfe, 0x56, 0x40, 0x61, 0xd7, 0x23, 0xee, 0x1e, 0xe9, 0xc2, 0xaf, 0x40, 0x91, 0xc7, - 0x63, 0x19, 0xcc, 0xa8, 0x2a, 0xeb, 0xca, 0x46, 0x79, 0xeb, 0x4d, 0x2d, 0xbe, 0xa5, 0x88, 0x56, - 0x1b, 0x1e, 0xf7, 0xb9, 0x81, 0x6a, 0x1c, 0xad, 0x9d, 0x6c, 0x6a, 0xf7, 0xbb, 0x8f, 0xb0, 0xc9, - 0xf6, 0x31, 0x33, 0x74, 0xf8, 0xd8, 0x57, 0x17, 0x02, 0x5f, 0x05, 0xb1, 0x0d, 0x45, 0xac, 0x50, - 0x07, 0x4b, 0x74, 0x88, 0xcd, 0xea, 0xa2, 0x60, 0x5f, 0xd7, 0x52, 0x72, 0xa0, 0xc9, 0x68, 0xda, - 0x43, 0x6c, 0xea, 0x2b, 0x92, 0x6d, 0x89, 0xaf, 0x90, 0xf0, 0x85, 0x7b, 0x60, 0x99, 0x32, 0x83, - 0x8d, 0x68, 0x35, 0x27, 0x58, 0x1a, 0x67, 0xb2, 0x08, 0xa4, 0xbe, 0x26, 0x79, 0x96, 0xc3, 0x35, - 0x92, 0x0c, 0x8d, 0x1f, 0x15, 0x50, 0x96, 0xc8, 0x96, 0x4d, 0x19, 0x7c, 0x38, 0x77, 0x03, 0xda, - 0xf9, 0x6e, 0x80, 0x7b, 0x8b, 0xef, 0xaf, 0xc8, 0x93, 0x8a, 0x13, 0x4b, 0xe2, 0xeb, 0x77, 0x40, - 0xde, 0x66, 0x78, 0x40, 0xab, 0x8b, 0xeb, 0xb9, 0x8d, 0xf2, 0xd6, 0x8d, 0xb3, 0x02, 0xd7, 0x57, - 0x25, 0x51, 0xfe, 0x1e, 0x77, 0x41, 0xa1, 0x67, 0xe3, 0xf7, 0xa5, 0x28, 0x60, 0x7e, 0x25, 0xf0, - 0x36, 0x28, 0xf2, 0xc4, 0x5a, 0x23, 0x07, 0x8b, 0x80, 0x4b, 0x71, 0x00, 0x6d, 0x69, 0x47, 0x11, - 0x02, 0x6e, 0x80, 0x22, 0xd7, 0xc2, 0x03, 0xe2, 0xe2, 0x6a, 0x51, 0xa0, 0x57, 0x38, 0xb2, 0x23, - 0x6d, 0x28, 0xda, 0x85, 0x87, 0xe0, 0x3a, 0x65, 0x86, 0xc7, 0x6c, 0xb7, 0x7f, 0x07, 0x1b, 0x96, - 0x63, 0xbb, 0xb8, 0x8d, 0x4d, 0xe2, 0x5a, 0x54, 0xe4, 0x2e, 0xa7, 0xbf, 0x14, 0xf8, 0xea, 0xf5, - 0x76, 0x3a, 0x04, 0x65, 0xf9, 0xc2, 0x87, 0xe0, 0xb2, 0x49, 0x5c, 0x73, 0xe4, 0x79, 0xd8, 0x35, - 0xc7, 0x07, 0xc4, 0xb1, 0xcd, 0xb1, 0x48, 0x63, 0x49, 0xd7, 0x64, 0xdc, 0x97, 0x77, 0x67, 0x01, - 0xa7, 0x69, 0x46, 0x34, 0x4f, 0x04, 0x5f, 0x01, 0x05, 0x3a, 0xa2, 0x43, 0xec, 0x5a, 0xd5, 0xa5, - 0x75, 0x65, 0xa3, 0xa8, 0x97, 0x03, 0x5f, 0x2d, 0xb4, 0x43, 0x13, 0x9a, 0xec, 0xc1, 0xcf, 0x41, - 0xf9, 0x11, 0xe9, 0x76, 0xf0, 0x60, 0xe8, 0x18, 0x0c, 0x57, 0xf3, 0x22, 0xcf, 0xb7, 0x52, 0x93, - 0xb1, 0x17, 0xe3, 0x84, 0x1e, 0xaf, 0xc8, 0x20, 0xcb, 0x89, 0x0d, 0x94, 0x64, 0x83, 0x5f, 0x82, - 0x1a, 0x1d, 0x99, 0x26, 0xa6, 0xb4, 0x37, 0x72, 0xf6, 0x48, 0x97, 0x7e, 0x6c, 0x53, 0x46, 0xbc, - 0x71, 0xcb, 0x1e, 0xd8, 0xac, 0xba, 0xbc, 0xae, 0x6c, 0xe4, 0xf5, 0x7a, 0xe0, 0xab, 0xb5, 0x76, - 0x26, 0x0a, 0x9d, 0xc1, 0x00, 0x11, 0xb8, 0xd6, 0x33, 0x6c, 0x07, 0x5b, 0x73, 0xdc, 0x05, 0xc1, - 0x5d, 0x0b, 0x7c, 0xf5, 0xda, 0xdd, 0x54, 0x04, 0xca, 0xf0, 0x6c, 0xfc, 0xba, 0x08, 0x56, 0xa7, - 0xde, 0x0b, 0xfc, 0x04, 0x2c, 0x1b, 0x26, 0xb3, 0x4f, 0xb8, 0xa8, 0xb8, 0x54, 0x5f, 0x4e, 0xde, - 0x0e, 0xaf, 0x74, 0xf1, 0xab, 0x47, 0xb8, 0x87, 0x79, 0x12, 0x70, 0xfc, 0xc8, 0x76, 0x84, 0x2b, - 0x92, 0x14, 0xd0, 0x01, 0x15, 0xc7, 0xa0, 0x6c, 0xa2, 0x47, 0xae, 0x36, 0x91, 0x9f, 0xf2, 0xd6, - 0xeb, 0xe7, 0x7b, 0x5c, 0xdc, 0x43, 0xff, 0x5f, 0xe0, 0xab, 0x95, 0xd6, 0x0c, 0x0f, 0x9a, 0x63, - 0x86, 0x1e, 0x80, 0xc2, 0x16, 0x5d, 0xa1, 0x38, 0x2f, 0x7f, 0xe1, 0xf3, 0xae, 0x05, 0xbe, 0x0a, - 0x5b, 0x73, 0x4c, 0x28, 0x85, 0xbd, 0xf1, 0x97, 0x02, 0x72, 0x2f, 0xa6, 0x80, 0x7e, 0x38, 0x55, - 0x40, 0x6f, 0x64, 0x89, 0x36, 0xb3, 0x78, 0xde, 0x9d, 0x29, 0x9e, 0xf5, 0x4c, 0x86, 0xb3, 0x0b, - 0xe7, 0x6f, 0x39, 0xb0, 0xb2, 0x47, 0xba, 0xbb, 0xc4, 0xb5, 0x6c, 0x66, 0x13, 0x17, 0x6e, 0x83, - 0x25, 0x36, 0x1e, 0x4e, 0x8a, 0xd0, 0xfa, 0xe4, 0xe8, 0xce, 0x78, 0x88, 0x4f, 0x7d, 0xb5, 0x92, - 0xc4, 0x72, 0x1b, 0x12, 0x68, 0xd8, 0x8a, 0xc2, 0x59, 0x14, 0x7e, 0xdb, 0xd3, 0xc7, 0x9d, 0xfa, - 0x6a, 0x4a, 0x8b, 0xd5, 0x22, 0xa6, 0xe9, 0xa0, 0x60, 0x1f, 0xac, 0xf2, 0xe4, 0x1c, 0x78, 0xa4, - 0x1b, 0xaa, 0x2c, 0x77, 0xe1, 0xac, 0x5f, 0x95, 0x01, 0xac, 0xb6, 0x92, 0x44, 0x68, 0x9a, 0x17, - 0x9e, 0x84, 0x1a, 0xeb, 0x78, 0x86, 0x4b, 0xc3, 0x4f, 0x7a, 0x3e, 0x4d, 0xd7, 0xe4, 0x69, 0x42, - 0x67, 0xd3, 0x6c, 0x28, 0xe5, 0x04, 0xf8, 0x2a, 0x58, 0xf6, 0xb0, 0x41, 0x89, 0x2b, 0xf4, 0x5c, - 0x8a, 0xb3, 0x83, 0x84, 0x15, 0xc9, 0x5d, 0xf8, 0x1a, 0x28, 0x0c, 0x30, 0xa5, 0x46, 0x1f, 0x8b, - 0x8a, 0x53, 0xd2, 0x2f, 0x49, 0x60, 0x61, 0x3f, 0x34, 0xa3, 0xc9, 0x7e, 0xe3, 0x07, 0x05, 0x14, - 0x5e, 0x4c, 0xf7, 0xfb, 0x60, 0xba, 0xfb, 0x55, 0xb3, 0x94, 0x97, 0xd1, 0xf9, 0x7e, 0xca, 0x8b, - 0x40, 0x45, 0xd7, 0xdb, 0x04, 0xe5, 0xa1, 0xe1, 0x19, 0x8e, 0x83, 0x1d, 0x9b, 0x0e, 0x44, 0xac, - 0x79, 0xfd, 0x12, 0xaf, 0xcb, 0x07, 0xb1, 0x19, 0x25, 0x31, 0xdc, 0xc5, 0x24, 0x83, 0xa1, 0x83, - 0xf9, 0x65, 0x86, 0x72, 0x93, 0x2e, 0xbb, 0xb1, 0x19, 0x25, 0x31, 0xf0, 0x3e, 0xb8, 0x1a, 0x56, - 0xb0, 0xd9, 0x0e, 0x98, 0x13, 0x1d, 0xf0, 0xff, 0x81, 0xaf, 0x5e, 0xdd, 0x49, 0x03, 0xa0, 0x74, - 0x3f, 0xb8, 0x0d, 0x56, 0xba, 0x86, 0x79, 0x4c, 0x7a, 0xbd, 0x64, 0xc5, 0xae, 0x04, 0xbe, 0xba, - 0xa2, 0x27, 0xec, 0x68, 0x0a, 0x05, 0xbf, 0x00, 0x45, 0x8a, 0x1d, 0x6c, 0x32, 0xe2, 0x49, 0x89, - 0xbd, 0x75, 0xce, 0xac, 0x18, 0x5d, 0xec, 0xb4, 0xa5, 0x6b, 0xd8, 0xe9, 0x27, 0x2b, 0x14, 0x51, - 0xc2, 0xf7, 0xc0, 0xda, 0xc0, 0x70, 0x47, 0x46, 0x84, 0x14, 0xda, 0x2a, 0xea, 0x30, 0xf0, 0xd5, - 0xb5, 0xfd, 0xa9, 0x1d, 0x34, 0x83, 0x84, 0x9f, 0x82, 0x22, 0x9b, 0xb4, 0xd1, 0x65, 0x11, 0x5a, - 0x6a, 0xa3, 0x38, 0x20, 0xd6, 0x54, 0x17, 0x8d, 0x54, 0x12, 0xb5, 0xd0, 0x88, 0x86, 0x0f, 0x1e, - 0x8c, 0x39, 0xf2, 0xc6, 0x76, 0x7a, 0x0c, 0x7b, 0x77, 0x6d, 0xd7, 0xa6, 0x47, 0xd8, 0x12, 0x13, - 0x4b, 0x3e, 0x1c, 0x3c, 0x3a, 0x9d, 0x56, 0x1a, 0x04, 0x65, 0xf9, 0xc2, 0x16, 0x58, 0x8b, 0x53, - 0xbb, 0x4f, 0x2c, 0x5c, 0x2d, 0x89, 0x87, 0x71, 0x8b, 0x7f, 0xe5, 0xee, 0xd4, 0xce, 0xe9, 0x9c, - 0x05, 0xcd, 0xf8, 0x26, 0x07, 0x0d, 0x90, 0x3d, 0x68, 0x34, 0xbe, 0xcf, 0x83, 0x52, 0xdc, 0x53, - 0x0f, 0x01, 0x30, 0x27, 0x85, 0x8b, 0xca, 0xbe, 0x7a, 0x33, 0xeb, 0x11, 0x44, 0x25, 0x2e, 0xee, - 0x07, 0x91, 0x89, 0xa2, 0x04, 0x11, 0xfc, 0x0c, 0x94, 0xc4, 0xb4, 0x25, 0x4a, 0xd0, 0xe2, 0x85, - 0x4b, 0xd0, 0x6a, 0xe0, 0xab, 0xa5, 0xf6, 0x84, 0x00, 0xc5, 0x5c, 0xb0, 0x97, 0xbc, 0xb2, 0xe7, - 0x2c, 0xa7, 0x70, 0xfa, 0x7a, 0xc5, 0x11, 0x33, 0xac, 0xbc, 0xa8, 0xc9, 0x59, 0x63, 0x49, 0x24, - 0x38, 0x6b, 0x8c, 0x68, 0x82, 0x92, 0x98, 0x8b, 0xb0, 0x85, 0x2d, 0xa1, 0xd1, 0xbc, 0x7e, 0x59, - 0x42, 0x4b, 0xed, 0xc9, 0x06, 0x8a, 0x31, 0x9c, 0x38, 0x1c, 0x78, 0xe4, 0xd8, 0x15, 0x11, 0x87, - 0xe3, 0x11, 0x92, 0xbb, 0xf0, 0x0e, 0xa8, 0xc8, 0x90, 0xb0, 0x75, 0xcf, 0xb5, 0xf0, 0xd7, 0x98, - 0x8a, 0xa7, 0x59, 0xd2, 0xab, 0xd2, 0xa3, 0xb2, 0x3b, 0xb3, 0x8f, 0xe6, 0x3c, 0xe0, 0xb7, 0x0a, - 0xb8, 0x3e, 0x72, 0x4d, 0x32, 0x72, 0x19, 0xb6, 0x3a, 0xd8, 0x1b, 0xd8, 0x2e, 0xff, 0x99, 0x75, - 0x40, 0x2c, 0x2a, 0x94, 0x5b, 0xde, 0xba, 0x9d, 0x9a, 0xec, 0xc3, 0x74, 0x9f, 0x50, 0xe7, 0x19, - 0x9b, 0x28, 0xeb, 0x24, 0xa8, 0x82, 0xbc, 0x87, 0x0d, 0x6b, 0x2c, 0xe4, 0x9d, 0xd7, 0x4b, 0xbc, - 0x8c, 0x22, 0x6e, 0x40, 0xa1, 0xbd, 0xf1, 0xb3, 0x02, 0x2e, 0xcd, 0x4c, 0xb5, 0xff, 0xfd, 0xb1, - 0xa5, 0xf1, 0x8b, 0x02, 0xb2, 0xee, 0x02, 0x1e, 0x24, 0x75, 0xc1, 0x9f, 0x55, 0x49, 0xdf, 0x9a, - 0xd2, 0xc4, 0xa9, 0xaf, 0xde, 0xcc, 0xfa, 0x75, 0xcc, 0xa7, 0x10, 0xaa, 0x1d, 0xde, 0xbb, 0x93, - 0x14, 0xce, 0x47, 0x91, 0x70, 0x16, 0x05, 0x5d, 0x33, 0x16, 0xcd, 0xf9, 0xb8, 0xa4, 0xbb, 0xfe, - 0xee, 0xe3, 0x67, 0xf5, 0x85, 0x27, 0xcf, 0xea, 0x0b, 0x4f, 0x9f, 0xd5, 0x17, 0xbe, 0x09, 0xea, - 0xca, 0xe3, 0xa0, 0xae, 0x3c, 0x09, 0xea, 0xca, 0xd3, 0xa0, 0xae, 0xfc, 0x11, 0xd4, 0x95, 0xef, - 0xfe, 0xac, 0x2f, 0x3c, 0xb8, 0x92, 0xf2, 0xef, 0x8a, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xae, - 0xfd, 0x54, 0xb2, 0xdd, 0x10, 0x00, 0x00, + // 1696 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x73, 0xe3, 0x48, + 0x15, 0x8f, 0xe2, 0xd8, 0xb1, 0xdb, 0xc9, 0xc4, 0xd3, 0xb3, 0x33, 0x63, 0xc2, 0x96, 0x95, 0xd5, + 0xec, 0x6e, 0x65, 0xa9, 0x45, 0x66, 0xb2, 0x53, 0x2c, 0xff, 0x8b, 0x91, 0x87, 0x59, 0x26, 0x78, + 0x36, 0xa6, 0x9d, 0x40, 0xd5, 0xb2, 0x50, 0xc8, 0x52, 0xdb, 0xd1, 0x46, 0x56, 0x1b, 0x75, 0x2b, + 0xb5, 0xb9, 0x50, 0x54, 0xf1, 0x05, 0xe0, 0xc8, 0x17, 0xe0, 0xc8, 0x05, 0xce, 0x70, 0xa3, 0x72, + 0xdc, 0xe2, 0xb4, 0xc5, 0x41, 0xc5, 0x88, 0x0f, 0xc0, 0x3d, 0x5c, 0xa8, 0x6e, 0xb5, 0xf5, 0xcf, + 0x52, 0xc8, 0x6c, 0x15, 0x5b, 0xdc, 0xa2, 0xf7, 0x7e, 0xef, 0xd7, 0x4f, 0xfd, 0x9e, 0x7e, 0xef, + 0xc5, 0xe0, 0x5b, 0x67, 0x5f, 0xa3, 0xba, 0x43, 0xfa, 0x67, 0xc1, 0x04, 0xfb, 0x1e, 0x66, 0x98, + 0xf6, 0xcf, 0xb1, 0x67, 0x13, 0xbf, 0x2f, 0x1d, 0xe6, 0xc2, 0xe9, 0x4f, 0x4c, 0x66, 0x9d, 0xf6, + 0xcf, 0x1f, 0xf6, 0x67, 0xd8, 0xc3, 0xbe, 0xc9, 0xb0, 0xad, 0x2f, 0x7c, 0xc2, 0x08, 0xbc, 0x13, + 0x83, 0x74, 0x73, 0xe1, 0xe8, 0x02, 0xa4, 0x9f, 0x3f, 0xdc, 0xfd, 0xf2, 0xcc, 0x61, 0xa7, 0xc1, + 0x44, 0xb7, 0xc8, 0xbc, 0x3f, 0x23, 0x33, 0xd2, 0x17, 0xd8, 0x49, 0x30, 0x15, 0x4f, 0xe2, 0x41, + 0xfc, 0x15, 0x73, 0xec, 0x6a, 0x99, 0x83, 0x2c, 0xe2, 0xe3, 0x92, 0x73, 0x76, 0x1f, 0xa5, 0x98, + 0xb9, 0x69, 0x9d, 0x3a, 0x1e, 0xf6, 0x2f, 0xfa, 0x8b, 0xb3, 0x19, 0x37, 0xd0, 0xfe, 0x1c, 0x33, + 0xb3, 0x2c, 0xaa, 0x5f, 0x15, 0xe5, 0x07, 0x1e, 0x73, 0xe6, 0x78, 0x25, 0xe0, 0xab, 0xff, 0x2d, + 0x80, 0x5a, 0xa7, 0x78, 0x6e, 0x16, 0xe3, 0xb4, 0x7f, 0x2b, 0x60, 0x73, 0xe0, 0x13, 0xef, 0x90, + 0x4c, 0xe0, 0xcf, 0x41, 0x93, 0xe7, 0x63, 0x9b, 0xcc, 0xec, 0x2a, 0x7b, 0xca, 0x7e, 0xfb, 0xe0, + 0x2b, 0x7a, 0x7a, 0x4b, 0x09, 0xad, 0xbe, 0x38, 0x9b, 0x71, 0x03, 0xd5, 0x39, 0x5a, 0x3f, 0x7f, + 0xa8, 0x1f, 0x4d, 0x3e, 0xc2, 0x16, 0x7b, 0x8e, 0x99, 0x69, 0xc0, 0xcb, 0x50, 0x5d, 0x8b, 0x42, + 0x15, 0xa4, 0x36, 0x94, 0xb0, 0x42, 0x03, 0x6c, 0xd0, 0x05, 0xb6, 0xba, 0xeb, 0x82, 0x7d, 0x4f, + 0x2f, 0xa9, 0x81, 0x2e, 0xb3, 0x19, 0x2f, 0xb0, 0x65, 0x6c, 0x49, 0xb6, 0x0d, 0xfe, 0x84, 0x44, + 0x2c, 0x3c, 0x04, 0x0d, 0xca, 0x4c, 0x16, 0xd0, 0x6e, 0x4d, 0xb0, 0x68, 0xd7, 0xb2, 0x08, 0xa4, + 0x71, 0x4b, 0xf2, 0x34, 0xe2, 0x67, 0x24, 0x19, 0xb4, 0x3f, 0x28, 0xa0, 0x2d, 0x91, 0x43, 0x87, + 0x32, 0xf8, 0xe1, 0xca, 0x0d, 0xe8, 0x37, 0xbb, 0x01, 0x1e, 0x2d, 0xde, 0xbf, 0x23, 0x4f, 0x6a, + 0x2e, 0x2d, 0x99, 0xb7, 0x7f, 0x0c, 0xea, 0x0e, 0xc3, 0x73, 0xda, 0x5d, 0xdf, 0xab, 0xed, 0xb7, + 0x0f, 0x5e, 0xbd, 0x2e, 0x71, 0x63, 0x5b, 0x12, 0xd5, 0x9f, 0xf1, 0x10, 0x14, 0x47, 0x6a, 0x7f, + 0xdb, 0x48, 0x12, 0xe6, 0x57, 0x02, 0xdf, 0x06, 0x4d, 0x5e, 0x58, 0x3b, 0x70, 0xb1, 0x48, 0xb8, + 0x95, 0x26, 0x30, 0x96, 0x76, 0x94, 0x20, 0xe0, 0x3e, 0x68, 0xf2, 0x5e, 0xf8, 0x80, 0x78, 0xb8, + 0xdb, 0x14, 0xe8, 0x2d, 0x8e, 0x3c, 0x96, 0x36, 0x94, 0x78, 0xe1, 0x09, 0xb8, 0x4f, 0x99, 0xe9, + 0x33, 0xc7, 0x9b, 0x3d, 0xc1, 0xa6, 0xed, 0x3a, 0x1e, 0x1e, 0x63, 0x8b, 0x78, 0x36, 0x15, 0xb5, + 0xab, 0x19, 0x5f, 0x8c, 0x42, 0xf5, 0xfe, 0xb8, 0x1c, 0x82, 0xaa, 0x62, 0xe1, 0x87, 0xe0, 0xb6, + 0x45, 0x3c, 0x2b, 0xf0, 0x7d, 0xec, 0x59, 0x17, 0x23, 0xe2, 0x3a, 0xd6, 0x85, 0x28, 0x63, 0xcb, + 0xd0, 0x65, 0xde, 0xb7, 0x07, 0x45, 0xc0, 0x55, 0x99, 0x11, 0xad, 0x12, 0xc1, 0x37, 0xc0, 0x26, + 0x0d, 0xe8, 0x02, 0x7b, 0x76, 0x77, 0x63, 0x4f, 0xd9, 0x6f, 0x1a, 0xed, 0x28, 0x54, 0x37, 0xc7, + 0xb1, 0x09, 0x2d, 0x7d, 0xf0, 0x27, 0xa0, 0xfd, 0x11, 0x99, 0x1c, 0xe3, 0xf9, 0xc2, 0x35, 0x19, + 0xee, 0xd6, 0x45, 0x9d, 0x5f, 0x2f, 0x2d, 0xc6, 0x61, 0x8a, 0x13, 0xfd, 0x78, 0x47, 0x26, 0xd9, + 0xce, 0x38, 0x50, 0x96, 0x0d, 0xfe, 0x0c, 0xec, 0xd2, 0xc0, 0xb2, 0x30, 0xa5, 0xd3, 0xc0, 0x3d, + 0x24, 0x13, 0xfa, 0x7d, 0x87, 0x32, 0xe2, 0x5f, 0x0c, 0x9d, 0xb9, 0xc3, 0xba, 0x8d, 0x3d, 0x65, + 0xbf, 0x6e, 0xf4, 0xa2, 0x50, 0xdd, 0x1d, 0x57, 0xa2, 0xd0, 0x35, 0x0c, 0x10, 0x81, 0x7b, 0x53, + 0xd3, 0x71, 0xb1, 0xbd, 0xc2, 0xbd, 0x29, 0xb8, 0x77, 0xa3, 0x50, 0xbd, 0xf7, 0xb4, 0x14, 0x81, + 0x2a, 0x22, 0xb5, 0x3f, 0xaf, 0x83, 0xed, 0xdc, 0xf7, 0x02, 0x7f, 0x00, 0x1a, 0xa6, 0xc5, 0x9c, + 0x73, 0xde, 0x54, 0xbc, 0x55, 0x1f, 0x64, 0x6f, 0x87, 0x2b, 0x5d, 0xfa, 0xd5, 0x23, 0x3c, 0xc5, + 0xbc, 0x08, 0x38, 0xfd, 0xc8, 0x1e, 0x8b, 0x50, 0x24, 0x29, 0xa0, 0x0b, 0x3a, 0xae, 0x49, 0xd9, + 0xb2, 0x1f, 0x79, 0xb7, 0x89, 0xfa, 0xb4, 0x0f, 0xbe, 0x74, 0xb3, 0x8f, 0x8b, 0x47, 0x18, 0xaf, + 0x44, 0xa1, 0xda, 0x19, 0x16, 0x78, 0xd0, 0x0a, 0x33, 0xf4, 0x01, 0x14, 0xb6, 0xe4, 0x0a, 0xc5, + 0x79, 0xf5, 0x97, 0x3e, 0xef, 0x5e, 0x14, 0xaa, 0x70, 0xb8, 0xc2, 0x84, 0x4a, 0xd8, 0xb5, 0x7f, + 0x29, 0xa0, 0xf6, 0xf9, 0x08, 0xe8, 0x77, 0x72, 0x02, 0xfa, 0x6a, 0x55, 0xd3, 0x56, 0x8a, 0xe7, + 0xd3, 0x82, 0x78, 0xf6, 0x2a, 0x19, 0xae, 0x17, 0xce, 0xbf, 0xd6, 0xc0, 0xd6, 0x21, 0x99, 0x0c, + 0x88, 0x67, 0x3b, 0xcc, 0x21, 0x1e, 0x7c, 0x04, 0x36, 0xd8, 0xc5, 0x62, 0x29, 0x42, 0x7b, 0xcb, + 0xa3, 0x8f, 0x2f, 0x16, 0xf8, 0x2a, 0x54, 0x3b, 0x59, 0x2c, 0xb7, 0x21, 0x81, 0x86, 0xc3, 0x24, + 0x9d, 0x75, 0x11, 0xf7, 0x28, 0x7f, 0xdc, 0x55, 0xa8, 0x96, 0x8c, 0x58, 0x3d, 0x61, 0xca, 0x27, + 0x05, 0x67, 0x60, 0x9b, 0x17, 0x67, 0xe4, 0x93, 0x49, 0xdc, 0x65, 0xb5, 0x97, 0xae, 0xfa, 0x5d, + 0x99, 0xc0, 0xf6, 0x30, 0x4b, 0x84, 0xf2, 0xbc, 0xf0, 0x3c, 0xee, 0xb1, 0x63, 0xdf, 0xf4, 0x68, + 0xfc, 0x4a, 0x9f, 0xad, 0xa7, 0x77, 0xe5, 0x69, 0xa2, 0xcf, 0xf2, 0x6c, 0xa8, 0xe4, 0x04, 0xf8, + 0x26, 0x68, 0xf8, 0xd8, 0xa4, 0xc4, 0x13, 0xfd, 0xdc, 0x4a, 0xab, 0x83, 0x84, 0x15, 0x49, 0x2f, + 0x7c, 0x0b, 0x6c, 0xce, 0x31, 0xa5, 0xe6, 0x0c, 0x0b, 0xc5, 0x69, 0x19, 0x3b, 0x12, 0xb8, 0xf9, + 0x3c, 0x36, 0xa3, 0xa5, 0x5f, 0xfb, 0xbd, 0x02, 0x36, 0x3f, 0x9f, 0xe9, 0xf7, 0xed, 0xfc, 0xf4, + 0xeb, 0x56, 0x75, 0x5e, 0xc5, 0xe4, 0xfb, 0x5d, 0x43, 0x24, 0x2a, 0xa6, 0xde, 0x43, 0xd0, 0x5e, + 0x98, 0xbe, 0xe9, 0xba, 0xd8, 0x75, 0xe8, 0x5c, 0xe4, 0x5a, 0x37, 0x76, 0xb8, 0x2e, 0x8f, 0x52, + 0x33, 0xca, 0x62, 0x78, 0x88, 0x45, 0xe6, 0x0b, 0x17, 0xf3, 0xcb, 0x8c, 0xdb, 0x4d, 0x86, 0x0c, + 0x52, 0x33, 0xca, 0x62, 0xe0, 0x11, 0xb8, 0x1b, 0x2b, 0x58, 0x71, 0x02, 0xd6, 0xc4, 0x04, 0xfc, + 0x42, 0x14, 0xaa, 0x77, 0x1f, 0x97, 0x01, 0x50, 0x79, 0x1c, 0x9c, 0x81, 0xce, 0x82, 0xd8, 0x5c, + 0x9c, 0x03, 0x1f, 0xcb, 0xe1, 0xd7, 0x16, 0xf7, 0xfc, 0x46, 0xe9, 0x65, 0x8c, 0x0a, 0xe0, 0x58, + 0x03, 0x8b, 0x56, 0xb4, 0x42, 0x0a, 0x1f, 0x81, 0xad, 0x89, 0x69, 0x9d, 0x91, 0xe9, 0x34, 0x3b, + 0x1a, 0x3a, 0x51, 0xa8, 0x6e, 0x19, 0x19, 0x3b, 0xca, 0xa1, 0xe0, 0x4f, 0x41, 0x93, 0x62, 0x17, + 0x5b, 0x8c, 0xf8, 0xb2, 0x97, 0xdf, 0xb9, 0x61, 0xf9, 0xcd, 0x09, 0x76, 0xc7, 0x32, 0x34, 0x5e, + 0x29, 0x96, 0x4f, 0x28, 0xa1, 0x84, 0xdf, 0x00, 0xb7, 0xe6, 0xa6, 0x17, 0x98, 0x09, 0x52, 0x34, + 0x71, 0xd3, 0x80, 0x51, 0xa8, 0xde, 0x7a, 0x9e, 0xf3, 0xa0, 0x02, 0x12, 0xfe, 0x10, 0x34, 0xd9, + 0x72, 0x5e, 0x37, 0x44, 0x6a, 0xa5, 0x13, 0x69, 0x44, 0xec, 0xdc, 0xb8, 0x4e, 0xda, 0x31, 0x99, + 0xd5, 0x09, 0x0d, 0xdf, 0x70, 0x18, 0x73, 0x65, 0x69, 0x1e, 0x4f, 0x19, 0xf6, 0x9f, 0x3a, 0x9e, + 0x43, 0x4f, 0xb1, 0x2d, 0x56, 0xa3, 0x7a, 0xbc, 0xe1, 0x1c, 0x1f, 0x0f, 0xcb, 0x20, 0xa8, 0x2a, + 0x16, 0x0e, 0xc1, 0xad, 0xb4, 0x87, 0x9e, 0x13, 0x1b, 0x77, 0x5b, 0xe2, 0x0b, 0x7c, 0x9d, 0xbf, + 0xe5, 0x20, 0xe7, 0xb9, 0x5a, 0xb1, 0xa0, 0x42, 0x6c, 0x76, 0xa3, 0x01, 0xd5, 0x1b, 0x8d, 0xf6, + 0xdb, 0x3a, 0x68, 0xa5, 0xc3, 0xfb, 0x04, 0x00, 0x6b, 0xa9, 0x90, 0x54, 0x0e, 0xf0, 0xd7, 0xaa, + 0xbe, 0xb6, 0x44, 0x4b, 0xd3, 0xc1, 0x93, 0x98, 0x28, 0xca, 0x10, 0xc1, 0x1f, 0x83, 0x96, 0x58, + 0xeb, 0x84, 0xd6, 0xad, 0xbf, 0xb4, 0xd6, 0x6d, 0x47, 0xa1, 0xda, 0x1a, 0x2f, 0x09, 0x50, 0xca, + 0x05, 0xa7, 0xd9, 0x2b, 0xfb, 0x8c, 0xba, 0x0d, 0xf3, 0xd7, 0x2b, 0x8e, 0x28, 0xb0, 0x72, 0xf5, + 0x94, 0x4b, 0xcd, 0x86, 0x28, 0x70, 0xd5, 0xbe, 0xd2, 0x07, 0x2d, 0xb1, 0x80, 0x61, 0x1b, 0xdb, + 0xa2, 0x47, 0xeb, 0xc6, 0x6d, 0x09, 0x6d, 0x8d, 0x97, 0x0e, 0x94, 0x62, 0x38, 0x71, 0xbc, 0x59, + 0xc9, 0xfd, 0x2e, 0x21, 0x8e, 0xf7, 0x30, 0x24, 0xbd, 0xf0, 0x09, 0xe8, 0xc8, 0x94, 0xb0, 0xfd, + 0xcc, 0xb3, 0xf1, 0xc7, 0x98, 0x8a, 0x4f, 0xb3, 0x65, 0x74, 0x65, 0x44, 0x67, 0x50, 0xf0, 0xa3, + 0x95, 0x08, 0xf8, 0x6b, 0x05, 0xdc, 0x0f, 0x3c, 0x8b, 0x04, 0x1e, 0xc3, 0xf6, 0x31, 0xf6, 0xe7, + 0x8e, 0xc7, 0xff, 0x9f, 0x1b, 0x11, 0x9b, 0x8a, 0xce, 0x6d, 0x1f, 0xbc, 0x5d, 0x5a, 0xec, 0x93, + 0xf2, 0x98, 0xb8, 0xcf, 0x2b, 0x9c, 0xa8, 0xea, 0x24, 0xa8, 0x82, 0xba, 0x8f, 0x4d, 0xfb, 0x42, + 0xb4, 0x77, 0xdd, 0x68, 0x71, 0xbd, 0x46, 0xdc, 0x80, 0x62, 0xbb, 0xf6, 0x47, 0x05, 0xec, 0x14, + 0xd6, 0xe7, 0xff, 0xff, 0xfd, 0x48, 0x9b, 0x80, 0x15, 0x7d, 0x85, 0xef, 0x83, 0xba, 0x1f, 0xb8, + 0x78, 0xf9, 0x29, 0xbd, 0x75, 0x23, 0xad, 0x46, 0x81, 0x8b, 0xd3, 0x49, 0xc6, 0x9f, 0x28, 0x8a, + 0x69, 0xb4, 0xbf, 0x2b, 0xe0, 0xcd, 0x22, 0xfc, 0xc8, 0xfb, 0xde, 0xc7, 0x0e, 0x1b, 0x10, 0x1b, + 0x53, 0x84, 0x7f, 0x11, 0x38, 0x3e, 0x9e, 0x63, 0x8f, 0xc1, 0x77, 0xc1, 0xb6, 0x45, 0x3c, 0x66, + 0xf2, 0x6b, 0x79, 0xdf, 0x9c, 0x2f, 0xd7, 0xab, 0xdb, 0x7c, 0x43, 0x19, 0x64, 0x1d, 0x28, 0x8f, + 0x83, 0x63, 0xd0, 0x24, 0x0b, 0xfe, 0x8f, 0x3e, 0xf1, 0xe5, 0x6a, 0xf5, 0xee, 0x52, 0x0b, 0x8f, + 0xa4, 0xfd, 0x2a, 0x54, 0x1f, 0x5c, 0x93, 0xc6, 0x12, 0x86, 0x12, 0x22, 0xa8, 0x81, 0xc6, 0xb9, + 0xe9, 0x06, 0x98, 0x4f, 0xc0, 0xda, 0x7e, 0xdd, 0x00, 0xbc, 0xc7, 0x7f, 0x24, 0x2c, 0x48, 0x7a, + 0xb4, 0xbf, 0x94, 0xbe, 0xdc, 0x88, 0xd8, 0xa9, 0xaa, 0x8c, 0x4c, 0xc6, 0xb0, 0xef, 0xc1, 0xf7, + 0x72, 0x2b, 0xe3, 0x3b, 0x85, 0x95, 0xf1, 0x41, 0xc9, 0xe2, 0x97, 0xa5, 0xf9, 0x5f, 0x6d, 0x91, + 0xda, 0xe5, 0x3a, 0x78, 0xa5, 0xac, 0x9a, 0xf0, 0xbb, 0xb1, 0x7e, 0x10, 0x4f, 0x66, 0xbc, 0x9f, + 0xd5, 0x0f, 0xe2, 0x5d, 0x85, 0xea, 0xbd, 0x62, 0x5c, 0xec, 0x41, 0x32, 0x0e, 0x7a, 0xa0, 0x4d, + 0xd2, 0x1b, 0x96, 0x4d, 0xfa, 0xcd, 0x1b, 0xf5, 0x53, 0x79, 0x83, 0xc4, 0x1b, 0x4c, 0xd6, 0x97, + 0x3d, 0x00, 0xfe, 0x12, 0xec, 0x90, 0xfc, 0xdd, 0x8b, 0xca, 0xdd, 0xfc, 0xcc, 0xb2, 0xba, 0x19, + 0xf7, 0xe5, 0x7b, 0xef, 0x14, 0xfc, 0xa8, 0x78, 0x98, 0xf6, 0x27, 0x05, 0x54, 0x29, 0x0b, 0x1c, + 0x65, 0x55, 0x96, 0x7f, 0x59, 0x2d, 0xe3, 0x20, 0xa7, 0xb0, 0x57, 0xa1, 0xfa, 0x5a, 0xd5, 0x8f, + 0x5a, 0xbc, 0xec, 0x54, 0x3f, 0x79, 0xf6, 0x24, 0x2b, 0xc3, 0xef, 0x25, 0x32, 0xbc, 0x2e, 0xe8, + 0xfa, 0xa9, 0x04, 0xdf, 0x8c, 0x4b, 0x86, 0x1b, 0x5f, 0xbf, 0x7c, 0xd1, 0x5b, 0xfb, 0xe4, 0x45, + 0x6f, 0xed, 0xd3, 0x17, 0xbd, 0xb5, 0x5f, 0x45, 0x3d, 0xe5, 0x32, 0xea, 0x29, 0x9f, 0x44, 0x3d, + 0xe5, 0xd3, 0xa8, 0xa7, 0xfc, 0x23, 0xea, 0x29, 0xbf, 0xf9, 0x67, 0x6f, 0xed, 0x83, 0x3b, 0x25, + 0xbf, 0x32, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x8e, 0x19, 0x59, 0x94, 0x14, 0x00, 0x00, } func (m *CronJob) Marshal() (dAtA []byte, err error) { @@ -887,6 +1023,18 @@ func (m *JobSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PodFailurePolicy != nil { + { + size, err := m.PodFailurePolicy.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } if m.Suspend != nil { i-- if *m.Suspend { @@ -1099,6 +1247,172 @@ func (m *JobTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PodFailurePolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodFailurePolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodFailurePolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PodFailurePolicyOnExitCodesRequirement) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodFailurePolicyOnExitCodesRequirement) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodFailurePolicyOnExitCodesRequirement) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Values) > 0 { + for iNdEx := len(m.Values) - 1; iNdEx >= 0; iNdEx-- { + i = encodeVarintGenerated(dAtA, i, uint64(m.Values[iNdEx])) + i-- + dAtA[i] = 0x18 + } + } + i -= len(m.Operator) + copy(dAtA[i:], m.Operator) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operator))) + i-- + dAtA[i] = 0x12 + if m.ContainerName != nil { + i -= len(*m.ContainerName) + copy(dAtA[i:], *m.ContainerName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ContainerName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PodFailurePolicyOnPodConditionsPattern) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodFailurePolicyOnPodConditionsPattern) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodFailurePolicyOnPodConditionsPattern) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Status) + copy(dAtA[i:], m.Status) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) + i-- + dAtA[i] = 0x12 + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodFailurePolicyRule) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodFailurePolicyRule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodFailurePolicyRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.OnPodConditions) > 0 { + for iNdEx := len(m.OnPodConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.OnPodConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.OnExitCodes != nil { + { + size, err := m.OnExitCodes.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Action) + copy(dAtA[i:], m.Action) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Action))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *UncountedTerminatedPods) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1327,6 +1641,10 @@ func (m *JobSpec) Size() (n int) { if m.Suspend != nil { n += 2 } + if m.PodFailurePolicy != nil { + l = m.PodFailurePolicy.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -1378,47 +1696,116 @@ func (m *JobTemplateSpec) Size() (n int) { return n } -func (m *UncountedTerminatedPods) Size() (n int) { +func (m *PodFailurePolicy) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Succeeded) > 0 { - for _, s := range m.Succeeded { - l = len(s) + if len(m.Rules) > 0 { + for _, e := range m.Rules { + l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } - if len(m.Failed) > 0 { - for _, s := range m.Failed { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PodFailurePolicyOnExitCodesRequirement) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ContainerName != nil { + l = len(*m.ContainerName) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.Operator) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Values) > 0 { + for _, e := range m.Values { + n += 1 + sovGenerated(uint64(e)) } } return n } -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *CronJob) String() string { - if this == nil { - return "nil" +func (m *PodFailurePolicyOnPodConditionsPattern) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&CronJob{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "CronJobSpec", "CronJobSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "CronJobStatus", "CronJobStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Status) + n += 1 + l + sovGenerated(uint64(l)) + return n } -func (this *CronJobList) String() string { - if this == nil { + +func (m *PodFailurePolicyRule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Action) + n += 1 + l + sovGenerated(uint64(l)) + if m.OnExitCodes != nil { + l = m.OnExitCodes.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.OnPodConditions) > 0 { + for _, e := range m.OnPodConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *UncountedTerminatedPods) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Succeeded) > 0 { + for _, s := range m.Succeeded { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Failed) > 0 { + for _, s := range m.Failed { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *CronJob) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CronJob{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "CronJobSpec", "CronJobSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "CronJobStatus", "CronJobStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *CronJobList) String() string { + if this == nil { return "nil" } repeatedStringForItems := "[]CronJob{" @@ -1525,6 +1912,7 @@ func (this *JobSpec) String() string { `TTLSecondsAfterFinished:` + valueToStringGenerated(this.TTLSecondsAfterFinished) + `,`, `CompletionMode:` + valueToStringGenerated(this.CompletionMode) + `,`, `Suspend:` + valueToStringGenerated(this.Suspend) + `,`, + `PodFailurePolicy:` + strings.Replace(this.PodFailurePolicy.String(), "PodFailurePolicy", "PodFailurePolicy", 1) + `,`, `}`, }, "") return s @@ -1563,6 +1951,61 @@ func (this *JobTemplateSpec) String() string { }, "") return s } +func (this *PodFailurePolicy) String() string { + if this == nil { + return "nil" + } + repeatedStringForRules := "[]PodFailurePolicyRule{" + for _, f := range this.Rules { + repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "PodFailurePolicyRule", "PodFailurePolicyRule", 1), `&`, ``, 1) + "," + } + repeatedStringForRules += "}" + s := strings.Join([]string{`&PodFailurePolicy{`, + `Rules:` + repeatedStringForRules + `,`, + `}`, + }, "") + return s +} +func (this *PodFailurePolicyOnExitCodesRequirement) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodFailurePolicyOnExitCodesRequirement{`, + `ContainerName:` + valueToStringGenerated(this.ContainerName) + `,`, + `Operator:` + fmt.Sprintf("%v", this.Operator) + `,`, + `Values:` + fmt.Sprintf("%v", this.Values) + `,`, + `}`, + }, "") + return s +} +func (this *PodFailurePolicyOnPodConditionsPattern) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodFailurePolicyOnPodConditionsPattern{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Status:` + fmt.Sprintf("%v", this.Status) + `,`, + `}`, + }, "") + return s +} +func (this *PodFailurePolicyRule) String() string { + if this == nil { + return "nil" + } + repeatedStringForOnPodConditions := "[]PodFailurePolicyOnPodConditionsPattern{" + for _, f := range this.OnPodConditions { + repeatedStringForOnPodConditions += strings.Replace(strings.Replace(f.String(), "PodFailurePolicyOnPodConditionsPattern", "PodFailurePolicyOnPodConditionsPattern", 1), `&`, ``, 1) + "," + } + repeatedStringForOnPodConditions += "}" + s := strings.Join([]string{`&PodFailurePolicyRule{`, + `Action:` + fmt.Sprintf("%v", this.Action) + `,`, + `OnExitCodes:` + strings.Replace(this.OnExitCodes.String(), "PodFailurePolicyOnExitCodesRequirement", "PodFailurePolicyOnExitCodesRequirement", 1) + `,`, + `OnPodConditions:` + repeatedStringForOnPodConditions + `,`, + `}`, + }, "") + return s +} func (this *UncountedTerminatedPods) String() string { if this == nil { return "nil" @@ -3048,6 +3491,42 @@ func (m *JobSpec) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.Suspend = &b + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodFailurePolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PodFailurePolicy == nil { + m.PodFailurePolicy = &PodFailurePolicy{} + } + if err := m.PodFailurePolicy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -3486,6 +3965,547 @@ func (m *JobTemplateSpec) Unmarshal(dAtA []byte) error { } return nil } +func (m *PodFailurePolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodFailurePolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodFailurePolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rules = append(m.Rules, PodFailurePolicyRule{}) + if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodFailurePolicyOnExitCodesRequirement) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodFailurePolicyOnExitCodesRequirement: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodFailurePolicyOnExitCodesRequirement: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ContainerName = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operator = PodFailurePolicyOnExitCodesOperator(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType == 0 { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Values = append(m.Values, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.Values) == 0 { + m.Values = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Values = append(m.Values, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodFailurePolicyOnPodConditionsPattern) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodFailurePolicyOnPodConditionsPattern: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodFailurePolicyOnPodConditionsPattern: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = k8s_io_api_core_v1.PodConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodFailurePolicyRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodFailurePolicyRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodFailurePolicyRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Action = PodFailurePolicyAction(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnExitCodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OnExitCodes == nil { + m.OnExitCodes = &PodFailurePolicyOnExitCodesRequirement{} + } + if err := m.OnExitCodes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnPodConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OnPodConditions = append(m.OnPodConditions, PodFailurePolicyOnPodConditionsPattern{}) + if err := m.OnPodConditions[len(m.OnPodConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *UncountedTerminatedPods) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/batch/v1/generated.proto b/vendor/k8s.io/api/batch/v1/generated.proto index a57fef0b2f6..df4381c737f 100644 --- a/vendor/k8s.io/api/batch/v1/generated.proto +++ b/vendor/k8s.io/api/batch/v1/generated.proto @@ -63,9 +63,15 @@ message CronJobSpec { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. optional string schedule = 1; - // The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. - // If not specified, this will rely on the time zone of the kube-controller-manager process. - // ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate. + // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. + // If not specified, this will default to the time zone of the kube-controller-manager process. + // The set of valid time zone names and the time zone offset is loaded from the system-wide time zone + // database by the API server during CronJob validation and the controller manager during execution. + // If no system-wide time zone database can be found a bundled version of the database is used instead. + // If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host + // configuration, the controller will stop creating new new Jobs and will create a system event with the + // reason UnknownTimeZone. + // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones // +optional optional string timeZone = 8; @@ -76,6 +82,7 @@ message CronJobSpec { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one @@ -182,7 +189,7 @@ message JobSpec { optional int32 parallelism = 1; // Specifies the desired number of successfully finished pods the - // job should be run with. Setting to nil means that the success of any + // job should be run with. Setting to null means that the success of any // pod signals the success of all pods, and allows parallelism to have any positive // value. Setting to 1 means that parallelism is limited to 1 and the success of that // pod signals the success of the job. @@ -198,6 +205,19 @@ message JobSpec { // +optional optional int64 activeDeadlineSeconds = 3; + // Specifies the policy of handling failed pods. In particular, it allows to + // specify the set of actions and conditions which need to be + // satisfied to take the associated action. + // If empty, the default behaviour applies - the counter of failed pods, + // represented by the jobs's .status.failed field, is incremented and it is + // checked against the backoffLimit. This field cannot be used in combination + // with restartPolicy=OnFailure. + // + // This field is beta-level. It can be used when the `JobPodFailurePolicy` + // feature gate is enabled (enabled by default). + // +optional + optional PodFailurePolicy podFailurePolicy = 11; + // Specifies the number of retries before marking this job failed. // Defaults to 6 // +optional @@ -223,6 +243,7 @@ message JobSpec { optional bool manualSelector = 5; // Describes the pod that will be created when executing a job. + // The only allowed template.spec.restartPolicy values are "Never" or "OnFailure". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/ optional k8s.io.api.core.v1.PodTemplateSpec template = 6; @@ -236,7 +257,7 @@ message JobSpec { // +optional optional int32 ttlSecondsAfterFinished = 8; - // CompletionMode specifies how Pod completions are tracked. It can be + // completionMode specifies how Pod completions are tracked. It can be // `NonIndexed` (default) or `Indexed`. // // `NonIndexed` means that the Job is considered complete when there have @@ -261,7 +282,7 @@ message JobSpec { // +optional optional string completionMode = 9; - // Suspend specifies whether the Job controller should create Pods or not. If + // suspend specifies whether the Job controller should create Pods or not. If // a Job is created with suspend set to true, no Pods are created by the Job // controller. If a Job is suspended after creation (i.e. the flag goes from // false to true), the Job controller will delete all active Pods associated @@ -314,7 +335,7 @@ message JobStatus { // +optional optional int32 failed = 6; - // CompletedIndexes holds the completed indexes when .spec.completionMode = + // completedIndexes holds the completed indexes when .spec.completionMode = // "Indexed" in a text format. The indexes are represented as decimal integers // separated by commas. The numbers are listed in increasing order. Three or // more consecutive numbers are compressed and represented by the first and @@ -324,20 +345,18 @@ message JobStatus { // +optional optional string completedIndexes = 7; - // UncountedTerminatedPods holds the UIDs of Pods that have terminated but + // uncountedTerminatedPods holds the UIDs of Pods that have terminated but // the job controller hasn't yet accounted for in the status counters. // // The job controller creates pods with a finalizer. When a pod terminates // (succeeded or failed), the controller does three steps to account for it // in the job status: - // (1) Add the pod UID to the arrays in this field. - // (2) Remove the pod finalizer. - // (3) Remove the pod UID from the arrays while increasing the corresponding + // + // 1. Add the pod UID to the arrays in this field. + // 2. Remove the pod finalizer. + // 3. Remove the pod UID from the arrays while increasing the corresponding // counter. // - // This field is beta-level. The job controller only makes use of this field - // when the feature gate JobTrackingWithFinalizers is enabled (enabled - // by default). // Old jobs might not be tracked using this field, in which case the field // remains null. // +optional @@ -364,15 +383,103 @@ message JobTemplateSpec { optional JobSpec spec = 2; } +// PodFailurePolicy describes how failed pods influence the backoffLimit. +message PodFailurePolicy { + // A list of pod failure policy rules. The rules are evaluated in order. + // Once a rule matches a Pod failure, the remaining of the rules are ignored. + // When no rule matches the Pod failure, the default handling applies - the + // counter of pod failures is incremented and it is checked against + // the backoffLimit. At most 20 elements are allowed. + // +listType=atomic + repeated PodFailurePolicyRule rules = 1; +} + +// PodFailurePolicyOnExitCodesRequirement describes the requirement for handling +// a failed pod based on its container exit codes. In particular, it lookups the +// .state.terminated.exitCode for each app container and init container status, +// represented by the .status.containerStatuses and .status.initContainerStatuses +// fields in the Pod status, respectively. Containers completed with success +// (exit code 0) are excluded from the requirement check. +message PodFailurePolicyOnExitCodesRequirement { + // Restricts the check for exit codes to the container with the + // specified name. When null, the rule applies to all containers. + // When specified, it should match one the container or initContainer + // names in the pod template. + // +optional + optional string containerName = 1; + + // Represents the relationship between the container exit code(s) and the + // specified values. Containers completed with success (exit code 0) are + // excluded from the requirement check. Possible values are: + // + // - In: the requirement is satisfied if at least one container exit code + // (might be multiple if there are multiple containers not restricted + // by the 'containerName' field) is in the set of specified values. + // - NotIn: the requirement is satisfied if at least one container exit code + // (might be multiple if there are multiple containers not restricted + // by the 'containerName' field) is not in the set of specified values. + // Additional values are considered to be added in the future. Clients should + // react to an unknown operator by assuming the requirement is not satisfied. + optional string operator = 2; + + // Specifies the set of values. Each returned container exit code (might be + // multiple in case of multiple containers) is checked against this set of + // values with respect to the operator. The list of values must be ordered + // and must not contain duplicates. Value '0' cannot be used for the In operator. + // At least one element is required. At most 255 elements are allowed. + // +listType=set + repeated int32 values = 3; +} + +// PodFailurePolicyOnPodConditionsPattern describes a pattern for matching +// an actual pod condition type. +message PodFailurePolicyOnPodConditionsPattern { + // Specifies the required Pod condition type. To match a pod condition + // it is required that specified type equals the pod condition type. + optional string type = 1; + + // Specifies the required Pod condition status. To match a pod condition + // it is required that the specified status equals the pod condition status. + // Defaults to True. + optional string status = 2; +} + +// PodFailurePolicyRule describes how a pod failure is handled when the requirements are met. +// One of onExitCodes and onPodConditions, but not both, can be used in each rule. +message PodFailurePolicyRule { + // Specifies the action taken on a pod failure when the requirements are satisfied. + // Possible values are: + // + // - FailJob: indicates that the pod's job is marked as Failed and all + // running pods are terminated. + // - Ignore: indicates that the counter towards the .backoffLimit is not + // incremented and a replacement pod is created. + // - Count: indicates that the pod is handled in the default way - the + // counter towards the .backoffLimit is incremented. + // Additional values are considered to be added in the future. Clients should + // react to an unknown action by skipping the rule. + optional string action = 1; + + // Represents the requirement on the container exit codes. + // +optional + optional PodFailurePolicyOnExitCodesRequirement onExitCodes = 2; + + // Represents the requirement on the pod conditions. The requirement is represented + // as a list of pod condition patterns. The requirement is satisfied if at + // least one pattern matches an actual pod condition. At most 20 elements are allowed. + // +listType=atomic + repeated PodFailurePolicyOnPodConditionsPattern onPodConditions = 3; +} + // UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't // been accounted in Job status counters. message UncountedTerminatedPods { - // Succeeded holds UIDs of succeeded Pods. + // succeeded holds UIDs of succeeded Pods. // +listType=set // +optional repeated string succeeded = 1; - // Failed holds UIDs of failed Pods. + // failed holds UIDs of failed Pods. // +listType=set // +optional repeated string failed = 2; diff --git a/vendor/k8s.io/api/batch/v1/types.go b/vendor/k8s.io/api/batch/v1/types.go index 110f974b788..22cf9ee9cb6 100644 --- a/vendor/k8s.io/api/batch/v1/types.go +++ b/vendor/k8s.io/api/batch/v1/types.go @@ -23,15 +23,28 @@ import ( ) const ( - JobCompletionIndexAnnotation = "batch.kubernetes.io/job-completion-index" + // All Kubernetes labels need to be prefixed with Kubernetes to distinguish them from end-user labels + // More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#label-selector-and-annotation-conventions + labelPrefix = "batch.kubernetes.io/" + JobCompletionIndexAnnotation = labelPrefix + "job-completion-index" // JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from // being deleted before being accounted in the Job status. - // The apiserver and job controller use this string as a Job annotation, to - // mark Jobs that are being tracked using pod finalizers. Two releases after - // the JobTrackingWithFinalizers graduates to GA, JobTrackingFinalizer will - // no longer be used as a Job annotation. - JobTrackingFinalizer = "batch.kubernetes.io/job-tracking" + // + // Additionally, the apiserver and job controller use this string as a Job + // annotation, to mark Jobs that are being tracked using pod finalizers. + // However, this behavior is deprecated in kubernetes 1.26. This means that, in + // 1.27+, one release after JobTrackingWithFinalizers graduates to GA, the + // apiserver and job controller will ignore this annotation and they will + // always track jobs using finalizers. + JobTrackingFinalizer = labelPrefix + "job-tracking" + // The Job labels will use batch.kubernetes.io as a prefix for all labels + // Historically the job controller uses unprefixed labels for job-name and controller-uid and + // Kubernetes continutes to recognize those unprefixed labels for consistency. + JobNameLabel = labelPrefix + "job-name" + // ControllerUid is used to programatically get pods corresponding to a Job. + // There is a corresponding label without the batch.kubernetes.io that we support for legacy reasons. + ControllerUidLabel = labelPrefix + "controller-uid" ) // +genclient @@ -87,6 +100,122 @@ const ( IndexedCompletion CompletionMode = "Indexed" ) +// PodFailurePolicyAction specifies how a Pod failure is handled. +// +enum +type PodFailurePolicyAction string + +const ( + // This is an action which might be taken on a pod failure - mark the + // pod's job as Failed and terminate all running pods. + PodFailurePolicyActionFailJob PodFailurePolicyAction = "FailJob" + + // This is an action which might be taken on a pod failure - the counter towards + // .backoffLimit, represented by the job's .status.failed field, is not + // incremented and a replacement pod is created. + PodFailurePolicyActionIgnore PodFailurePolicyAction = "Ignore" + + // This is an action which might be taken on a pod failure - the pod failure + // is handled in the default way - the counter towards .backoffLimit, + // represented by the job's .status.failed field, is incremented. + PodFailurePolicyActionCount PodFailurePolicyAction = "Count" +) + +// +enum +type PodFailurePolicyOnExitCodesOperator string + +const ( + PodFailurePolicyOnExitCodesOpIn PodFailurePolicyOnExitCodesOperator = "In" + PodFailurePolicyOnExitCodesOpNotIn PodFailurePolicyOnExitCodesOperator = "NotIn" +) + +// PodFailurePolicyOnExitCodesRequirement describes the requirement for handling +// a failed pod based on its container exit codes. In particular, it lookups the +// .state.terminated.exitCode for each app container and init container status, +// represented by the .status.containerStatuses and .status.initContainerStatuses +// fields in the Pod status, respectively. Containers completed with success +// (exit code 0) are excluded from the requirement check. +type PodFailurePolicyOnExitCodesRequirement struct { + // Restricts the check for exit codes to the container with the + // specified name. When null, the rule applies to all containers. + // When specified, it should match one the container or initContainer + // names in the pod template. + // +optional + ContainerName *string `json:"containerName" protobuf:"bytes,1,opt,name=containerName"` + + // Represents the relationship between the container exit code(s) and the + // specified values. Containers completed with success (exit code 0) are + // excluded from the requirement check. Possible values are: + // + // - In: the requirement is satisfied if at least one container exit code + // (might be multiple if there are multiple containers not restricted + // by the 'containerName' field) is in the set of specified values. + // - NotIn: the requirement is satisfied if at least one container exit code + // (might be multiple if there are multiple containers not restricted + // by the 'containerName' field) is not in the set of specified values. + // Additional values are considered to be added in the future. Clients should + // react to an unknown operator by assuming the requirement is not satisfied. + Operator PodFailurePolicyOnExitCodesOperator `json:"operator" protobuf:"bytes,2,req,name=operator"` + + // Specifies the set of values. Each returned container exit code (might be + // multiple in case of multiple containers) is checked against this set of + // values with respect to the operator. The list of values must be ordered + // and must not contain duplicates. Value '0' cannot be used for the In operator. + // At least one element is required. At most 255 elements are allowed. + // +listType=set + Values []int32 `json:"values" protobuf:"varint,3,rep,name=values"` +} + +// PodFailurePolicyOnPodConditionsPattern describes a pattern for matching +// an actual pod condition type. +type PodFailurePolicyOnPodConditionsPattern struct { + // Specifies the required Pod condition type. To match a pod condition + // it is required that specified type equals the pod condition type. + Type corev1.PodConditionType `json:"type" protobuf:"bytes,1,req,name=type"` + + // Specifies the required Pod condition status. To match a pod condition + // it is required that the specified status equals the pod condition status. + // Defaults to True. + Status corev1.ConditionStatus `json:"status" protobuf:"bytes,2,req,name=status"` +} + +// PodFailurePolicyRule describes how a pod failure is handled when the requirements are met. +// One of onExitCodes and onPodConditions, but not both, can be used in each rule. +type PodFailurePolicyRule struct { + // Specifies the action taken on a pod failure when the requirements are satisfied. + // Possible values are: + // + // - FailJob: indicates that the pod's job is marked as Failed and all + // running pods are terminated. + // - Ignore: indicates that the counter towards the .backoffLimit is not + // incremented and a replacement pod is created. + // - Count: indicates that the pod is handled in the default way - the + // counter towards the .backoffLimit is incremented. + // Additional values are considered to be added in the future. Clients should + // react to an unknown action by skipping the rule. + Action PodFailurePolicyAction `json:"action" protobuf:"bytes,1,req,name=action"` + + // Represents the requirement on the container exit codes. + // +optional + OnExitCodes *PodFailurePolicyOnExitCodesRequirement `json:"onExitCodes" protobuf:"bytes,2,opt,name=onExitCodes"` + + // Represents the requirement on the pod conditions. The requirement is represented + // as a list of pod condition patterns. The requirement is satisfied if at + // least one pattern matches an actual pod condition. At most 20 elements are allowed. + // +listType=atomic + OnPodConditions []PodFailurePolicyOnPodConditionsPattern `json:"onPodConditions" protobuf:"bytes,3,opt,name=onPodConditions"` +} + +// PodFailurePolicy describes how failed pods influence the backoffLimit. +type PodFailurePolicy struct { + // A list of pod failure policy rules. The rules are evaluated in order. + // Once a rule matches a Pod failure, the remaining of the rules are ignored. + // When no rule matches the Pod failure, the default handling applies - the + // counter of pod failures is incremented and it is checked against + // the backoffLimit. At most 20 elements are allowed. + // +listType=atomic + Rules []PodFailurePolicyRule `json:"rules" protobuf:"bytes,1,opt,name=rules"` +} + // JobSpec describes how the job execution will look like. type JobSpec struct { @@ -99,7 +228,7 @@ type JobSpec struct { Parallelism *int32 `json:"parallelism,omitempty" protobuf:"varint,1,opt,name=parallelism"` // Specifies the desired number of successfully finished pods the - // job should be run with. Setting to nil means that the success of any + // job should be run with. Setting to null means that the success of any // pod signals the success of all pods, and allows parallelism to have any positive // value. Setting to 1 means that parallelism is limited to 1 and the success of that // pod signals the success of the job. @@ -115,6 +244,19 @@ type JobSpec struct { // +optional ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" protobuf:"varint,3,opt,name=activeDeadlineSeconds"` + // Specifies the policy of handling failed pods. In particular, it allows to + // specify the set of actions and conditions which need to be + // satisfied to take the associated action. + // If empty, the default behaviour applies - the counter of failed pods, + // represented by the jobs's .status.failed field, is incremented and it is + // checked against the backoffLimit. This field cannot be used in combination + // with restartPolicy=OnFailure. + // + // This field is beta-level. It can be used when the `JobPodFailurePolicy` + // feature gate is enabled (enabled by default). + // +optional + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" protobuf:"bytes,11,opt,name=podFailurePolicy"` + // Specifies the number of retries before marking this job failed. // Defaults to 6 // +optional @@ -145,6 +287,7 @@ type JobSpec struct { ManualSelector *bool `json:"manualSelector,omitempty" protobuf:"varint,5,opt,name=manualSelector"` // Describes the pod that will be created when executing a job. + // The only allowed template.spec.restartPolicy values are "Never" or "OnFailure". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/ Template corev1.PodTemplateSpec `json:"template" protobuf:"bytes,6,opt,name=template"` @@ -158,7 +301,7 @@ type JobSpec struct { // +optional TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty" protobuf:"varint,8,opt,name=ttlSecondsAfterFinished"` - // CompletionMode specifies how Pod completions are tracked. It can be + // completionMode specifies how Pod completions are tracked. It can be // `NonIndexed` (default) or `Indexed`. // // `NonIndexed` means that the Job is considered complete when there have @@ -183,7 +326,7 @@ type JobSpec struct { // +optional CompletionMode *CompletionMode `json:"completionMode,omitempty" protobuf:"bytes,9,opt,name=completionMode,casttype=CompletionMode"` - // Suspend specifies whether the Job controller should create Pods or not. If + // suspend specifies whether the Job controller should create Pods or not. If // a Job is created with suspend set to true, no Pods are created by the Job // controller. If a Job is suspended after creation (i.e. the flag goes from // false to true), the Job controller will delete all active Pods associated @@ -236,7 +379,7 @@ type JobStatus struct { // +optional Failed int32 `json:"failed,omitempty" protobuf:"varint,6,opt,name=failed"` - // CompletedIndexes holds the completed indexes when .spec.completionMode = + // completedIndexes holds the completed indexes when .spec.completionMode = // "Indexed" in a text format. The indexes are represented as decimal integers // separated by commas. The numbers are listed in increasing order. Three or // more consecutive numbers are compressed and represented by the first and @@ -246,20 +389,18 @@ type JobStatus struct { // +optional CompletedIndexes string `json:"completedIndexes,omitempty" protobuf:"bytes,7,opt,name=completedIndexes"` - // UncountedTerminatedPods holds the UIDs of Pods that have terminated but + // uncountedTerminatedPods holds the UIDs of Pods that have terminated but // the job controller hasn't yet accounted for in the status counters. // // The job controller creates pods with a finalizer. When a pod terminates // (succeeded or failed), the controller does three steps to account for it // in the job status: - // (1) Add the pod UID to the arrays in this field. - // (2) Remove the pod finalizer. - // (3) Remove the pod UID from the arrays while increasing the corresponding + // + // 1. Add the pod UID to the arrays in this field. + // 2. Remove the pod finalizer. + // 3. Remove the pod UID from the arrays while increasing the corresponding // counter. // - // This field is beta-level. The job controller only makes use of this field - // when the feature gate JobTrackingWithFinalizers is enabled (enabled - // by default). // Old jobs might not be tracked using this field, in which case the field // remains null. // +optional @@ -276,12 +417,12 @@ type JobStatus struct { // UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't // been accounted in Job status counters. type UncountedTerminatedPods struct { - // Succeeded holds UIDs of succeeded Pods. + // succeeded holds UIDs of succeeded Pods. // +listType=set // +optional Succeeded []types.UID `json:"succeeded,omitempty" protobuf:"bytes,1,rep,name=succeeded,casttype=k8s.io/apimachinery/pkg/types.UID"` - // Failed holds UIDs of failed Pods. + // failed holds UIDs of failed Pods. // +listType=set // +optional Failed []types.UID `json:"failed,omitempty" protobuf:"bytes,2,rep,name=failed,casttype=k8s.io/apimachinery/pkg/types.UID"` @@ -297,6 +438,8 @@ const ( JobComplete JobConditionType = "Complete" // JobFailed means the job has failed its execution. JobFailed JobConditionType = "Failed" + // FailureTarget means the job is about to fail its execution. + JobFailureTarget JobConditionType = "FailureTarget" ) // JobCondition describes current state of a job. @@ -375,9 +518,15 @@ type CronJobSpec struct { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` - // The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. - // If not specified, this will rely on the time zone of the kube-controller-manager process. - // ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate. + // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. + // If not specified, this will default to the time zone of the kube-controller-manager process. + // The set of valid time zone names and the time zone offset is loaded from the system-wide time zone + // database by the API server during CronJob validation and the controller manager during execution. + // If no system-wide time zone database can be found a bundled version of the database is used instead. + // If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host + // configuration, the controller will stop creating new new Jobs and will create a system event with the + // reason UnknownTimeZone. + // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones // +optional TimeZone *string `json:"timeZone,omitempty" protobuf:"bytes,8,opt,name=timeZone"` @@ -388,6 +537,7 @@ type CronJobSpec struct { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one diff --git a/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go index df24723a82f..f6f3141f189 100644 --- a/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CronJob = map[string]string{ @@ -51,9 +51,9 @@ func (CronJobList) SwaggerDoc() map[string]string { var map_CronJobSpec = map[string]string{ "": "CronJobSpec describes how the job execution will look like and when it will actually run.", "schedule": "The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.", - "timeZone": "The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will rely on the time zone of the kube-controller-manager process. ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate.", + "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones", "startingDeadlineSeconds": "Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.", - "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are: - \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", + "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are:\n\n- \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", "suspend": "This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false.", "jobTemplate": "Specifies the job that will be created when executing a CronJob.", "successfulJobsHistoryLimit": "The number of successful finished jobs to retain. Value must be non-negative integer. Defaults to 3.", @@ -113,15 +113,16 @@ func (JobList) SwaggerDoc() map[string]string { var map_JobSpec = map[string]string{ "": "JobSpec describes how the job execution will look like.", "parallelism": "Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", - "completions": "Specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", + "completions": "Specifies the desired number of successfully finished pods the job should be run with. Setting to null means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", "activeDeadlineSeconds": "Specifies the duration in seconds relative to the startTime that the job may be continuously active before the system tries to terminate it; value must be positive integer. If a Job is suspended (at creation or through an update), this timer will effectively be stopped and reset when the Job is resumed again.", + "podFailurePolicy": "Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.\n\nThis field is beta-level. It can be used when the `JobPodFailurePolicy` feature gate is enabled (enabled by default).", "backoffLimit": "Specifies the number of retries before marking this job failed. Defaults to 6", "selector": "A label query over pods that should match the pod count. Normally, the system sets this field for you. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", "manualSelector": "manualSelector controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector", - "template": "Describes the pod that will be created when executing a job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", + "template": "Describes the pod that will be created when executing a job. The only allowed template.spec.restartPolicy values are \"Never\" or \"OnFailure\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", "ttlSecondsAfterFinished": "ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.", - "completionMode": "CompletionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`.\n\n`NonIndexed` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other.\n\n`Indexed` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is `Indexed`, .spec.completions must be specified and `.spec.parallelism` must be less than or equal to 10^5. In addition, The Pod name takes the form `$(job-name)-$(index)-$(random-string)`, the Pod hostname takes the form `$(job-name)-$(index)`.\n\nMore completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, which is possible during upgrades due to version skew, the controller skips updates for the Job.", - "suspend": "Suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.", + "completionMode": "completionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`.\n\n`NonIndexed` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other.\n\n`Indexed` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is `Indexed`, .spec.completions must be specified and `.spec.parallelism` must be less than or equal to 10^5. In addition, The Pod name takes the form `$(job-name)-$(index)-$(random-string)`, the Pod hostname takes the form `$(job-name)-$(index)`.\n\nMore completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, which is possible during upgrades due to version skew, the controller skips updates for the Job.", + "suspend": "suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.", } func (JobSpec) SwaggerDoc() map[string]string { @@ -136,8 +137,8 @@ var map_JobStatus = map[string]string{ "active": "The number of pending and running pods.", "succeeded": "The number of pods which reached phase Succeeded.", "failed": "The number of pods which reached phase Failed.", - "completedIndexes": "CompletedIndexes holds the completed indexes when .spec.completionMode = \"Indexed\" in a text format. The indexes are represented as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the completed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\".", - "uncountedTerminatedPods": "UncountedTerminatedPods holds the UIDs of Pods that have terminated but the job controller hasn't yet accounted for in the status counters.\n\nThe job controller creates pods with a finalizer. When a pod terminates (succeeded or failed), the controller does three steps to account for it in the job status: (1) Add the pod UID to the arrays in this field. (2) Remove the pod finalizer. (3) Remove the pod UID from the arrays while increasing the corresponding\n counter.\n\nThis field is beta-level. The job controller only makes use of this field when the feature gate JobTrackingWithFinalizers is enabled (enabled by default). Old jobs might not be tracked using this field, in which case the field remains null.", + "completedIndexes": "completedIndexes holds the completed indexes when .spec.completionMode = \"Indexed\" in a text format. The indexes are represented as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the completed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\".", + "uncountedTerminatedPods": "uncountedTerminatedPods holds the UIDs of Pods that have terminated but the job controller hasn't yet accounted for in the status counters.\n\nThe job controller creates pods with a finalizer. When a pod terminates (succeeded or failed), the controller does three steps to account for it in the job status:\n\n1. Add the pod UID to the arrays in this field. 2. Remove the pod finalizer. 3. Remove the pod UID from the arrays while increasing the corresponding\n counter.\n\nOld jobs might not be tracked using this field, in which case the field remains null.", "ready": "The number of pods which have a Ready condition.\n\nThis field is beta-level. The job controller populates the field when the feature gate JobReadyPods is enabled (enabled by default).", } @@ -155,10 +156,51 @@ func (JobTemplateSpec) SwaggerDoc() map[string]string { return map_JobTemplateSpec } +var map_PodFailurePolicy = map[string]string{ + "": "PodFailurePolicy describes how failed pods influence the backoffLimit.", + "rules": "A list of pod failure policy rules. The rules are evaluated in order. Once a rule matches a Pod failure, the remaining of the rules are ignored. When no rule matches the Pod failure, the default handling applies - the counter of pod failures is incremented and it is checked against the backoffLimit. At most 20 elements are allowed.", +} + +func (PodFailurePolicy) SwaggerDoc() map[string]string { + return map_PodFailurePolicy +} + +var map_PodFailurePolicyOnExitCodesRequirement = map[string]string{ + "": "PodFailurePolicyOnExitCodesRequirement describes the requirement for handling a failed pod based on its container exit codes. In particular, it lookups the .state.terminated.exitCode for each app container and init container status, represented by the .status.containerStatuses and .status.initContainerStatuses fields in the Pod status, respectively. Containers completed with success (exit code 0) are excluded from the requirement check.", + "containerName": "Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.", + "operator": "Represents the relationship between the container exit code(s) and the specified values. Containers completed with success (exit code 0) are excluded from the requirement check. Possible values are:\n\n- In: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is in the set of specified values.\n- NotIn: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is not in the set of specified values.\nAdditional values are considered to be added in the future. Clients should react to an unknown operator by assuming the requirement is not satisfied.", + "values": "Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator. The list of values must be ordered and must not contain duplicates. Value '0' cannot be used for the In operator. At least one element is required. At most 255 elements are allowed.", +} + +func (PodFailurePolicyOnExitCodesRequirement) SwaggerDoc() map[string]string { + return map_PodFailurePolicyOnExitCodesRequirement +} + +var map_PodFailurePolicyOnPodConditionsPattern = map[string]string{ + "": "PodFailurePolicyOnPodConditionsPattern describes a pattern for matching an actual pod condition type.", + "type": "Specifies the required Pod condition type. To match a pod condition it is required that specified type equals the pod condition type.", + "status": "Specifies the required Pod condition status. To match a pod condition it is required that the specified status equals the pod condition status. Defaults to True.", +} + +func (PodFailurePolicyOnPodConditionsPattern) SwaggerDoc() map[string]string { + return map_PodFailurePolicyOnPodConditionsPattern +} + +var map_PodFailurePolicyRule = map[string]string{ + "": "PodFailurePolicyRule describes how a pod failure is handled when the requirements are met. One of onExitCodes and onPodConditions, but not both, can be used in each rule.", + "action": "Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are:\n\n- FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\n- Ignore: indicates that the counter towards the .backoffLimit is not\n incremented and a replacement pod is created.\n- Count: indicates that the pod is handled in the default way - the\n counter towards the .backoffLimit is incremented.\nAdditional values are considered to be added in the future. Clients should react to an unknown action by skipping the rule.", + "onExitCodes": "Represents the requirement on the container exit codes.", + "onPodConditions": "Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition. At most 20 elements are allowed.", +} + +func (PodFailurePolicyRule) SwaggerDoc() map[string]string { + return map_PodFailurePolicyRule +} + var map_UncountedTerminatedPods = map[string]string{ "": "UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't been accounted in Job status counters.", - "succeeded": "Succeeded holds UIDs of succeeded Pods.", - "failed": "Failed holds UIDs of failed Pods.", + "succeeded": "succeeded holds UIDs of succeeded Pods.", + "failed": "failed holds UIDs of failed Pods.", } func (UncountedTerminatedPods) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/batch/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/batch/v1/zz_generated.deepcopy.go index 4bc195a9f52..2a901e9d0f9 100644 --- a/vendor/k8s.io/api/batch/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/batch/v1/zz_generated.deepcopy.go @@ -257,6 +257,11 @@ func (in *JobSpec) DeepCopyInto(out *JobSpec) { *out = new(int64) **out = **in } + if in.PodFailurePolicy != nil { + in, out := &in.PodFailurePolicy, &out.PodFailurePolicy + *out = new(PodFailurePolicy) + (*in).DeepCopyInto(*out) + } if in.BackoffLimit != nil { in, out := &in.BackoffLimit, &out.BackoffLimit *out = new(int32) @@ -360,6 +365,97 @@ func (in *JobTemplateSpec) DeepCopy() *JobTemplateSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodFailurePolicy) DeepCopyInto(out *PodFailurePolicy) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]PodFailurePolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicy. +func (in *PodFailurePolicy) DeepCopy() *PodFailurePolicy { + if in == nil { + return nil + } + out := new(PodFailurePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodFailurePolicyOnExitCodesRequirement) DeepCopyInto(out *PodFailurePolicyOnExitCodesRequirement) { + *out = *in + if in.ContainerName != nil { + in, out := &in.ContainerName, &out.ContainerName + *out = new(string) + **out = **in + } + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = make([]int32, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyOnExitCodesRequirement. +func (in *PodFailurePolicyOnExitCodesRequirement) DeepCopy() *PodFailurePolicyOnExitCodesRequirement { + if in == nil { + return nil + } + out := new(PodFailurePolicyOnExitCodesRequirement) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodFailurePolicyOnPodConditionsPattern) DeepCopyInto(out *PodFailurePolicyOnPodConditionsPattern) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyOnPodConditionsPattern. +func (in *PodFailurePolicyOnPodConditionsPattern) DeepCopy() *PodFailurePolicyOnPodConditionsPattern { + if in == nil { + return nil + } + out := new(PodFailurePolicyOnPodConditionsPattern) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodFailurePolicyRule) DeepCopyInto(out *PodFailurePolicyRule) { + *out = *in + if in.OnExitCodes != nil { + in, out := &in.OnExitCodes, &out.OnExitCodes + *out = new(PodFailurePolicyOnExitCodesRequirement) + (*in).DeepCopyInto(*out) + } + if in.OnPodConditions != nil { + in, out := &in.OnPodConditions, &out.OnPodConditions + *out = make([]PodFailurePolicyOnPodConditionsPattern, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodFailurePolicyRule. +func (in *PodFailurePolicyRule) DeepCopy() *PodFailurePolicyRule { + if in == nil { + return nil + } + out := new(PodFailurePolicyRule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UncountedTerminatedPods) DeepCopyInto(out *UncountedTerminatedPods) { *out = *in diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.pb.go b/vendor/k8s.io/api/batch/v1beta1/generated.pb.go index d042fc69512..03feb2ceafa 100644 --- a/vendor/k8s.io/api/batch/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/batch/v1beta1/generated.pb.go @@ -157,38 +157,10 @@ func (m *CronJobStatus) XXX_DiscardUnknown() { var xxx_messageInfo_CronJobStatus proto.InternalMessageInfo -func (m *JobTemplate) Reset() { *m = JobTemplate{} } -func (*JobTemplate) ProtoMessage() {} -func (*JobTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e57b277b05179ae7, []int{4} -} -func (m *JobTemplate) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *JobTemplate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *JobTemplate) XXX_Merge(src proto.Message) { - xxx_messageInfo_JobTemplate.Merge(m, src) -} -func (m *JobTemplate) XXX_Size() int { - return m.Size() -} -func (m *JobTemplate) XXX_DiscardUnknown() { - xxx_messageInfo_JobTemplate.DiscardUnknown(m) -} - -var xxx_messageInfo_JobTemplate proto.InternalMessageInfo - func (m *JobTemplateSpec) Reset() { *m = JobTemplateSpec{} } func (*JobTemplateSpec) ProtoMessage() {} func (*JobTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e57b277b05179ae7, []int{5} + return fileDescriptor_e57b277b05179ae7, []int{4} } func (m *JobTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -218,7 +190,6 @@ func init() { proto.RegisterType((*CronJobList)(nil), "k8s.io.api.batch.v1beta1.CronJobList") proto.RegisterType((*CronJobSpec)(nil), "k8s.io.api.batch.v1beta1.CronJobSpec") proto.RegisterType((*CronJobStatus)(nil), "k8s.io.api.batch.v1beta1.CronJobStatus") - proto.RegisterType((*JobTemplate)(nil), "k8s.io.api.batch.v1beta1.JobTemplate") proto.RegisterType((*JobTemplateSpec)(nil), "k8s.io.api.batch.v1beta1.JobTemplateSpec") } @@ -227,58 +198,57 @@ func init() { } var fileDescriptor_e57b277b05179ae7 = []byte{ - // 814 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x41, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0xbd, 0x4e, 0x9c, 0xb8, 0xe3, 0x16, 0xd2, 0x01, 0xa5, 0x2b, 0x83, 0xd6, 0xc1, 0x55, - 0x85, 0x41, 0x30, 0x4b, 0x22, 0x84, 0x38, 0x55, 0xea, 0x16, 0x15, 0x08, 0x41, 0x45, 0xe3, 0x22, - 0xa4, 0xaa, 0x42, 0x9d, 0x1d, 0xbf, 0x38, 0xd3, 0x78, 0x77, 0x56, 0x3b, 0xb3, 0x91, 0x72, 0xe3, - 0xc2, 0x9d, 0xef, 0xc2, 0x9d, 0x73, 0x8e, 0xbd, 0xd1, 0xd3, 0x8a, 0x2c, 0xdf, 0x82, 0x13, 0x9a, - 0xf1, 0x7a, 0xed, 0xda, 0xeb, 0xa6, 0xbd, 0xf4, 0xe6, 0x79, 0xf3, 0xff, 0xff, 0xe6, 0xed, 0x7b, - 0x6f, 0x67, 0x8d, 0xee, 0x9d, 0x7e, 0xad, 0x88, 0x90, 0xfe, 0x69, 0x16, 0x42, 0x1a, 0x83, 0x06, - 0xe5, 0x9f, 0x41, 0x3c, 0x92, 0xa9, 0x5f, 0x6e, 0xb0, 0x44, 0xf8, 0x21, 0xd3, 0xfc, 0xc4, 0x3f, - 0xdb, 0x0f, 0x41, 0xb3, 0x7d, 0x7f, 0x0c, 0x31, 0xa4, 0x4c, 0xc3, 0x88, 0x24, 0xa9, 0xd4, 0x12, - 0xbb, 0x53, 0x25, 0x61, 0x89, 0x20, 0x56, 0x49, 0x4a, 0x65, 0xf7, 0xf3, 0xb1, 0xd0, 0x27, 0x59, - 0x48, 0xb8, 0x8c, 0xfc, 0xb1, 0x1c, 0x4b, 0xdf, 0x1a, 0xc2, 0xec, 0xd8, 0xae, 0xec, 0xc2, 0xfe, - 0x9a, 0x82, 0xba, 0xb7, 0x6b, 0x8e, 0x5c, 0x3e, 0xad, 0xdb, 0x5f, 0x10, 0x71, 0x99, 0x42, 0x9d, - 0xe6, 0xcb, 0xb9, 0x26, 0x62, 0xfc, 0x44, 0xc4, 0x90, 0x9e, 0xfb, 0xc9, 0xe9, 0xd8, 0x04, 0x94, - 0x1f, 0x81, 0x66, 0x75, 0x2e, 0x7f, 0x9d, 0x2b, 0xcd, 0x62, 0x2d, 0x22, 0x58, 0x31, 0x7c, 0x75, - 0x95, 0x41, 0xf1, 0x13, 0x88, 0xd8, 0xb2, 0xaf, 0xff, 0x7b, 0x13, 0x6d, 0xdf, 0x4f, 0x65, 0x7c, - 0x28, 0x43, 0xfc, 0x14, 0xb5, 0x4d, 0x3e, 0x23, 0xa6, 0x99, 0xeb, 0xec, 0x39, 0x83, 0xce, 0xc1, - 0x17, 0x64, 0x5e, 0xcf, 0x0a, 0x4b, 0x92, 0xd3, 0xb1, 0x09, 0x28, 0x62, 0xd4, 0xe4, 0x6c, 0x9f, - 0x3c, 0x0c, 0x9f, 0x01, 0xd7, 0x3f, 0x82, 0x66, 0x01, 0xbe, 0xc8, 0x7b, 0x8d, 0x22, 0xef, 0xa1, - 0x79, 0x8c, 0x56, 0x54, 0xfc, 0x2d, 0xda, 0x54, 0x09, 0x70, 0xb7, 0x69, 0xe9, 0x77, 0xc8, 0xba, - 0x6e, 0x91, 0x32, 0xa5, 0x61, 0x02, 0x3c, 0xb8, 0x5e, 0x22, 0x37, 0xcd, 0x8a, 0x5a, 0x00, 0x7e, - 0x88, 0xb6, 0x94, 0x66, 0x3a, 0x53, 0xee, 0x86, 0x45, 0x7d, 0x7c, 0x35, 0xca, 0xca, 0x83, 0x77, - 0x4a, 0xd8, 0xd6, 0x74, 0x4d, 0x4b, 0x4c, 0xff, 0x4f, 0x07, 0x75, 0x4a, 0xe5, 0x91, 0x50, 0x1a, - 0x3f, 0x59, 0xa9, 0x05, 0x79, 0xbd, 0x5a, 0x18, 0xb7, 0xad, 0xc4, 0x4e, 0x79, 0x52, 0x7b, 0x16, - 0x59, 0xa8, 0xc3, 0x03, 0xd4, 0x12, 0x1a, 0x22, 0xe5, 0x36, 0xf7, 0x36, 0x06, 0x9d, 0x83, 0x8f, - 0xae, 0xcc, 0x3e, 0xb8, 0x51, 0xd2, 0x5a, 0xdf, 0x1b, 0x1f, 0x9d, 0xda, 0xfb, 0x7f, 0x6f, 0x56, - 0x59, 0x9b, 0xe2, 0xe0, 0xcf, 0x50, 0xdb, 0xf4, 0x79, 0x94, 0x4d, 0xc0, 0x66, 0x7d, 0x6d, 0x9e, - 0xc5, 0xb0, 0x8c, 0xd3, 0x4a, 0x81, 0x07, 0xa8, 0x6d, 0x46, 0xe3, 0xb1, 0x8c, 0xc1, 0x6d, 0x5b, - 0xf5, 0x75, 0xa3, 0x7c, 0x54, 0xc6, 0x68, 0xb5, 0x8b, 0x7f, 0x46, 0xb7, 0x94, 0x66, 0xa9, 0x16, - 0xf1, 0xf8, 0x1b, 0x60, 0xa3, 0x89, 0x88, 0x61, 0x08, 0x5c, 0xc6, 0x23, 0x65, 0x5b, 0xb9, 0x11, - 0x7c, 0x50, 0xe4, 0xbd, 0x5b, 0xc3, 0x7a, 0x09, 0x5d, 0xe7, 0xc5, 0x4f, 0xd0, 0x4d, 0x2e, 0x63, - 0x9e, 0xa5, 0x29, 0xc4, 0xfc, 0xfc, 0x27, 0x39, 0x11, 0xfc, 0xdc, 0x36, 0xf4, 0x5a, 0x40, 0xca, - 0xbc, 0x6f, 0xde, 0x5f, 0x16, 0xfc, 0x57, 0x17, 0xa4, 0xab, 0x20, 0x7c, 0x07, 0x6d, 0xab, 0x4c, - 0x25, 0x10, 0x8f, 0xdc, 0xcd, 0x3d, 0x67, 0xd0, 0x0e, 0x3a, 0x45, 0xde, 0xdb, 0x1e, 0x4e, 0x43, - 0x74, 0xb6, 0x87, 0x9f, 0xa2, 0xce, 0x33, 0x19, 0x3e, 0x82, 0x28, 0x99, 0x30, 0x0d, 0x6e, 0xcb, - 0x36, 0xfb, 0x93, 0xf5, 0x1d, 0x39, 0x9c, 0x8b, 0xed, 0x78, 0xbe, 0x57, 0x66, 0xda, 0x59, 0xd8, - 0xa0, 0x8b, 0x48, 0xfc, 0x2b, 0xea, 0xaa, 0x8c, 0x73, 0x50, 0xea, 0x38, 0x9b, 0x1c, 0xca, 0x50, - 0x7d, 0x27, 0x94, 0x96, 0xe9, 0xf9, 0x91, 0x88, 0x84, 0x76, 0xb7, 0xf6, 0x9c, 0x41, 0x2b, 0xf0, - 0x8a, 0xbc, 0xd7, 0x1d, 0xae, 0x55, 0xd1, 0x57, 0x10, 0x30, 0x45, 0xbb, 0xc7, 0x4c, 0x4c, 0x60, - 0xb4, 0xc2, 0xde, 0xb6, 0xec, 0x6e, 0x91, 0xf7, 0x76, 0x1f, 0xd4, 0x2a, 0xe8, 0x1a, 0x67, 0xff, - 0xaf, 0x26, 0xba, 0xf1, 0xd2, 0x9b, 0x83, 0x7f, 0x40, 0x5b, 0x8c, 0x6b, 0x71, 0x66, 0x26, 0xcb, - 0x0c, 0xed, 0xed, 0xc5, 0x12, 0x99, 0xdb, 0x6f, 0x7e, 0x13, 0x50, 0x38, 0x06, 0xd3, 0x09, 0x98, - 0xbf, 0x6e, 0xf7, 0xac, 0x95, 0x96, 0x08, 0x3c, 0x41, 0x3b, 0x13, 0xa6, 0xf4, 0x6c, 0x28, 0xcd, - 0xc8, 0xd9, 0x26, 0x75, 0x0e, 0x3e, 0x7d, 0xbd, 0xd7, 0xcc, 0x38, 0x82, 0xf7, 0x8b, 0xbc, 0xb7, - 0x73, 0xb4, 0xc4, 0xa1, 0x2b, 0x64, 0x9c, 0x22, 0x6c, 0x63, 0x55, 0x09, 0xed, 0x79, 0xad, 0x37, - 0x3e, 0x6f, 0xb7, 0xc8, 0x7b, 0xf8, 0x68, 0x85, 0x44, 0x6b, 0xe8, 0xfd, 0x0b, 0x07, 0x2d, 0x4e, - 0xc4, 0x5b, 0xb8, 0x5c, 0x7f, 0x41, 0x6d, 0x3d, 0x9b, 0xe2, 0xe6, 0x9b, 0x4e, 0x71, 0x75, 0x4f, - 0x54, 0x23, 0x5c, 0xc1, 0xcc, 0xdd, 0xf8, 0xee, 0x92, 0xfe, 0x2d, 0x3c, 0xce, 0xdd, 0x97, 0xbe, - 0x15, 0x1f, 0xd6, 0x3d, 0x0a, 0x79, 0xc5, 0x27, 0x22, 0xb8, 0x7b, 0x71, 0xe9, 0x35, 0x9e, 0x5f, - 0x7a, 0x8d, 0x17, 0x97, 0x5e, 0xe3, 0xb7, 0xc2, 0x73, 0x2e, 0x0a, 0xcf, 0x79, 0x5e, 0x78, 0xce, - 0x8b, 0xc2, 0x73, 0xfe, 0x29, 0x3c, 0xe7, 0x8f, 0x7f, 0xbd, 0xc6, 0x63, 0x77, 0xdd, 0x5f, 0x8b, - 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xf2, 0x8b, 0xe9, 0x8e, 0x08, 0x00, 0x00, + // 787 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0x41, 0x6f, 0x1b, 0x45, + 0x14, 0xc7, 0xbd, 0x49, 0x9c, 0xb8, 0xe3, 0x16, 0xd2, 0x01, 0xa5, 0x2b, 0x83, 0xd6, 0xc1, 0x55, + 0x85, 0x41, 0x30, 0x4b, 0x22, 0x84, 0x38, 0x55, 0xea, 0x16, 0x15, 0x08, 0x41, 0x45, 0xe3, 0x72, + 0xa9, 0x2a, 0xd4, 0xd9, 0xd9, 0x17, 0x67, 0x9a, 0xdd, 0x9d, 0xd5, 0xce, 0x6c, 0xa4, 0xdc, 0xb8, + 0x70, 0xe7, 0xbb, 0x70, 0xe7, 0x9c, 0x63, 0x6f, 0xf4, 0xb4, 0x22, 0xcb, 0xb7, 0xe0, 0x84, 0x66, + 0xbc, 0xb1, 0x5d, 0x7b, 0xdd, 0x84, 0x4b, 0x6f, 0x9e, 0x37, 0xff, 0xff, 0x6f, 0x9e, 0xde, 0x7b, + 0xfb, 0x8c, 0x1e, 0x9c, 0x7c, 0xad, 0x88, 0x90, 0xfe, 0x49, 0x11, 0x42, 0x9e, 0x82, 0x06, 0xe5, + 0x9f, 0x42, 0x1a, 0xc9, 0xdc, 0xaf, 0x2f, 0x58, 0x26, 0xfc, 0x90, 0x69, 0x7e, 0xec, 0x9f, 0xee, + 0x85, 0xa0, 0xd9, 0x9e, 0x3f, 0x86, 0x14, 0x72, 0xa6, 0x21, 0x22, 0x59, 0x2e, 0xb5, 0xc4, 0xee, + 0x44, 0x49, 0x58, 0x26, 0x88, 0x55, 0x92, 0x5a, 0xd9, 0xfb, 0x7c, 0x2c, 0xf4, 0x71, 0x11, 0x12, + 0x2e, 0x13, 0x7f, 0x2c, 0xc7, 0xd2, 0xb7, 0x86, 0xb0, 0x38, 0xb2, 0x27, 0x7b, 0xb0, 0xbf, 0x26, + 0xa0, 0xde, 0xdd, 0x86, 0x27, 0x17, 0x5f, 0xeb, 0x0d, 0xe6, 0x44, 0x5c, 0xe6, 0xd0, 0xa4, 0xf9, + 0x72, 0xa6, 0x49, 0x18, 0x3f, 0x16, 0x29, 0xe4, 0x67, 0x7e, 0x76, 0x32, 0x36, 0x01, 0xe5, 0x27, + 0xa0, 0x59, 0x93, 0xcb, 0x5f, 0xe5, 0xca, 0x8b, 0x54, 0x8b, 0x04, 0x96, 0x0c, 0x5f, 0x5d, 0x65, + 0x50, 0xfc, 0x18, 0x12, 0xb6, 0xe8, 0x1b, 0xfc, 0xb6, 0x86, 0xb6, 0x1e, 0xe6, 0x32, 0x3d, 0x90, + 0x21, 0x7e, 0x8e, 0x3a, 0x26, 0x9f, 0x88, 0x69, 0xe6, 0x3a, 0xbb, 0xce, 0xb0, 0xbb, 0xff, 0x05, + 0x99, 0xd5, 0x73, 0x8a, 0x25, 0xd9, 0xc9, 0xd8, 0x04, 0x14, 0x31, 0x6a, 0x72, 0xba, 0x47, 0x1e, + 0x87, 0x2f, 0x80, 0xeb, 0x1f, 0x41, 0xb3, 0x00, 0x9f, 0x97, 0xfd, 0x56, 0x55, 0xf6, 0xd1, 0x2c, + 0x46, 0xa7, 0x54, 0xfc, 0x2d, 0xda, 0x50, 0x19, 0x70, 0x77, 0xcd, 0xd2, 0xef, 0x91, 0x55, 0xdd, + 0x22, 0x75, 0x4a, 0xa3, 0x0c, 0x78, 0x70, 0xb3, 0x46, 0x6e, 0x98, 0x13, 0xb5, 0x00, 0xfc, 0x18, + 0x6d, 0x2a, 0xcd, 0x74, 0xa1, 0xdc, 0x75, 0x8b, 0xfa, 0xf8, 0x6a, 0x94, 0x95, 0x07, 0xef, 0xd4, + 0xb0, 0xcd, 0xc9, 0x99, 0xd6, 0x98, 0xc1, 0x1f, 0x0e, 0xea, 0xd6, 0xca, 0x43, 0xa1, 0x34, 0x7e, + 0xb6, 0x54, 0x0b, 0x72, 0xbd, 0x5a, 0x18, 0xb7, 0xad, 0xc4, 0x76, 0xfd, 0x52, 0xe7, 0x32, 0x32, + 0x57, 0x87, 0x47, 0xa8, 0x2d, 0x34, 0x24, 0xca, 0x5d, 0xdb, 0x5d, 0x1f, 0x76, 0xf7, 0x3f, 0xba, + 0x32, 0xfb, 0xe0, 0x56, 0x4d, 0x6b, 0x7f, 0x6f, 0x7c, 0x74, 0x62, 0x1f, 0xfc, 0xb5, 0x31, 0xcd, + 0xda, 0x14, 0x07, 0x7f, 0x86, 0x3a, 0xa6, 0xcf, 0x51, 0x11, 0x83, 0xcd, 0xfa, 0xc6, 0x2c, 0x8b, + 0x51, 0x1d, 0xa7, 0x53, 0x05, 0x1e, 0xa2, 0x8e, 0x19, 0x8d, 0xa7, 0x32, 0x05, 0xb7, 0x63, 0xd5, + 0x37, 0x8d, 0xf2, 0x49, 0x1d, 0xa3, 0xd3, 0x5b, 0xfc, 0x33, 0xba, 0xa3, 0x34, 0xcb, 0xb5, 0x48, + 0xc7, 0xdf, 0x00, 0x8b, 0x62, 0x91, 0xc2, 0x08, 0xb8, 0x4c, 0x23, 0x65, 0x5b, 0xb9, 0x1e, 0x7c, + 0x50, 0x95, 0xfd, 0x3b, 0xa3, 0x66, 0x09, 0x5d, 0xe5, 0xc5, 0xcf, 0xd0, 0x6d, 0x2e, 0x53, 0x5e, + 0xe4, 0x39, 0xa4, 0xfc, 0xec, 0x27, 0x19, 0x0b, 0x7e, 0x66, 0x1b, 0x7a, 0x23, 0x20, 0x75, 0xde, + 0xb7, 0x1f, 0x2e, 0x0a, 0xfe, 0x6d, 0x0a, 0xd2, 0x65, 0x10, 0xbe, 0x87, 0xb6, 0x54, 0xa1, 0x32, + 0x48, 0x23, 0x77, 0x63, 0xd7, 0x19, 0x76, 0x82, 0x6e, 0x55, 0xf6, 0xb7, 0x46, 0x93, 0x10, 0xbd, + 0xbc, 0xc3, 0xcf, 0x51, 0xf7, 0x85, 0x0c, 0x9f, 0x40, 0x92, 0xc5, 0x4c, 0x83, 0xdb, 0xb6, 0xcd, + 0xfe, 0x64, 0x75, 0x47, 0x0e, 0x66, 0x62, 0x3b, 0x9e, 0xef, 0xd5, 0x99, 0x76, 0xe7, 0x2e, 0xe8, + 0x3c, 0x12, 0xff, 0x82, 0x7a, 0xaa, 0xe0, 0x1c, 0x94, 0x3a, 0x2a, 0xe2, 0x03, 0x19, 0xaa, 0xef, + 0x84, 0xd2, 0x32, 0x3f, 0x3b, 0x14, 0x89, 0xd0, 0xee, 0xe6, 0xae, 0x33, 0x6c, 0x07, 0x5e, 0x55, + 0xf6, 0x7b, 0xa3, 0x95, 0x2a, 0xfa, 0x06, 0x02, 0xa6, 0x68, 0xe7, 0x88, 0x89, 0x18, 0xa2, 0x25, + 0xf6, 0x96, 0x65, 0xf7, 0xaa, 0xb2, 0xbf, 0xf3, 0xa8, 0x51, 0x41, 0x57, 0x38, 0x07, 0x7f, 0xae, + 0xa1, 0x5b, 0xaf, 0x7d, 0x39, 0xf8, 0x07, 0xb4, 0xc9, 0xb8, 0x16, 0xa7, 0x66, 0xb2, 0xcc, 0xd0, + 0xde, 0x9d, 0x2f, 0x91, 0xd9, 0x7e, 0xb3, 0x4d, 0x40, 0xe1, 0x08, 0x4c, 0x27, 0x60, 0xf6, 0xb9, + 0x3d, 0xb0, 0x56, 0x5a, 0x23, 0x70, 0x8c, 0xb6, 0x63, 0xa6, 0xf4, 0xe5, 0x50, 0x9a, 0x91, 0xb3, + 0x4d, 0xea, 0xee, 0x7f, 0x7a, 0xbd, 0xcf, 0xcc, 0x38, 0x82, 0xf7, 0xab, 0xb2, 0xbf, 0x7d, 0xb8, + 0xc0, 0xa1, 0x4b, 0x64, 0x9c, 0x23, 0x6c, 0x63, 0xd3, 0x12, 0xda, 0xf7, 0xda, 0xff, 0xfb, 0xbd, + 0x9d, 0xaa, 0xec, 0xe3, 0xc3, 0x25, 0x12, 0x6d, 0xa0, 0x9b, 0x85, 0xf2, 0xee, 0xc2, 0xa8, 0xbc, + 0x85, 0x05, 0x7b, 0xff, 0xb5, 0x05, 0xfb, 0x61, 0xd3, 0x14, 0x93, 0x37, 0xec, 0xd5, 0xe0, 0xfe, + 0xf9, 0x85, 0xd7, 0x7a, 0x79, 0xe1, 0xb5, 0x5e, 0x5d, 0x78, 0xad, 0x5f, 0x2b, 0xcf, 0x39, 0xaf, + 0x3c, 0xe7, 0x65, 0xe5, 0x39, 0xaf, 0x2a, 0xcf, 0xf9, 0xbb, 0xf2, 0x9c, 0xdf, 0xff, 0xf1, 0x5a, + 0x4f, 0xdd, 0x55, 0xff, 0xc7, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x61, 0x72, 0xc3, 0xe0, 0xc3, + 0x07, 0x00, 0x00, } func (m *CronJob) Marshal() (dAtA []byte, err error) { @@ -517,49 +487,6 @@ func (m *CronJobStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *JobTemplate) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *JobTemplate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *JobTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Template.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *JobTemplateSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -700,19 +627,6 @@ func (m *CronJobStatus) Size() (n int) { return n } -func (m *JobTemplate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Template.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - func (m *JobTemplateSpec) Size() (n int) { if m == nil { return 0 @@ -794,17 +708,6 @@ func (this *CronJobStatus) String() string { }, "") return s } -func (this *JobTemplate) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&JobTemplate{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Template:` + strings.Replace(strings.Replace(this.Template.String(), "JobTemplateSpec", "JobTemplateSpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} func (this *JobTemplateSpec) String() string { if this == nil { return "nil" @@ -1507,122 +1410,6 @@ func (m *CronJobStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobTemplate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobTemplate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobTemplate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *JobTemplateSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.proto b/vendor/k8s.io/api/batch/v1beta1/generated.proto index c73b7a65403..ac774f19ade 100644 --- a/vendor/k8s.io/api/batch/v1beta1/generated.proto +++ b/vendor/k8s.io/api/batch/v1beta1/generated.proto @@ -64,9 +64,15 @@ message CronJobSpec { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. optional string schedule = 1; - // The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. - // If not specified, this will rely on the time zone of the kube-controller-manager process. - // ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate. + // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. + // If not specified, this will default to the time zone of the kube-controller-manager process. + // The set of valid time zone names and the time zone offset is loaded from the system-wide time zone + // database by the API server during CronJob validation and the controller manager during execution. + // If no system-wide time zone database can be found a bundled version of the database is used instead. + // If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host + // configuration, the controller will stop creating new new Jobs and will create a system event with the + // reason UnknownTimeZone. + // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones // +optional optional string timeZone = 8; @@ -77,6 +83,7 @@ message CronJobSpec { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one @@ -120,19 +127,6 @@ message CronJobStatus { optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastSuccessfulTime = 5; } -// JobTemplate describes a template for creating copies of a predefined pod. -message JobTemplate { - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // Defines jobs that will be created from this template. - // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - optional JobTemplateSpec template = 2; -} - // JobTemplateSpec describes the data a Job should have when created from a template message JobTemplateSpec { // Standard object's metadata of the jobs created from this template. diff --git a/vendor/k8s.io/api/batch/v1beta1/register.go b/vendor/k8s.io/api/batch/v1beta1/register.go index 226de49f4d2..9382ca23f2e 100644 --- a/vendor/k8s.io/api/batch/v1beta1/register.go +++ b/vendor/k8s.io/api/batch/v1beta1/register.go @@ -44,7 +44,6 @@ var ( // Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &JobTemplate{}, &CronJob{}, &CronJobList{}, ) diff --git a/vendor/k8s.io/api/batch/v1beta1/types.go b/vendor/k8s.io/api/batch/v1beta1/types.go index 54a2d14318f..976752a926f 100644 --- a/vendor/k8s.io/api/batch/v1beta1/types.go +++ b/vendor/k8s.io/api/batch/v1beta1/types.go @@ -22,24 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.8 -// +k8s:prerelease-lifecycle-gen:deprecated=1.22 - -// JobTemplate describes a template for creating copies of a predefined pod. -type JobTemplate struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // Defines jobs that will be created from this template. - // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - Template JobTemplateSpec `json:"template,omitempty" protobuf:"bytes,2,opt,name=template"` -} - // JobTemplateSpec describes the data a Job should have when created from a template type JobTemplateSpec struct { // Standard object's metadata of the jobs created from this template. @@ -104,9 +86,15 @@ type CronJobSpec struct { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` - // The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. - // If not specified, this will rely on the time zone of the kube-controller-manager process. - // ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate. + // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. + // If not specified, this will default to the time zone of the kube-controller-manager process. + // The set of valid time zone names and the time zone offset is loaded from the system-wide time zone + // database by the API server during CronJob validation and the controller manager during execution. + // If no system-wide time zone database can be found a bundled version of the database is used instead. + // If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host + // configuration, the controller will stop creating new new Jobs and will create a system event with the + // reason UnknownTimeZone. + // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones // +optional TimeZone *string `json:"timeZone,omitempty" protobuf:"bytes,8,opt,name=timeZone"` @@ -117,6 +105,7 @@ type CronJobSpec struct { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one diff --git a/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go index 87194807631..3b3eafe8ccb 100644 --- a/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CronJob = map[string]string{ @@ -51,9 +51,9 @@ func (CronJobList) SwaggerDoc() map[string]string { var map_CronJobSpec = map[string]string{ "": "CronJobSpec describes how the job execution will look like and when it will actually run.", "schedule": "The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.", - "timeZone": "The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will rely on the time zone of the kube-controller-manager process. ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate.", + "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones", "startingDeadlineSeconds": "Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.", - "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are: - \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", + "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are:\n\n- \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", "suspend": "This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false.", "jobTemplate": "Specifies the job that will be created when executing a CronJob.", "successfulJobsHistoryLimit": "The number of successful finished jobs to retain. This is a pointer to distinguish between explicit zero and not specified. Defaults to 3.", @@ -75,16 +75,6 @@ func (CronJobStatus) SwaggerDoc() map[string]string { return map_CronJobStatus } -var map_JobTemplate = map[string]string{ - "": "JobTemplate describes a template for creating copies of a predefined pod.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "template": "Defines jobs that will be created from this template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", -} - -func (JobTemplate) SwaggerDoc() map[string]string { - return map_JobTemplate -} - var map_JobTemplateSpec = map[string]string{ "": "JobTemplateSpec describes the data a Job should have when created from a template", "metadata": "Standard object's metadata of the jobs created from this template. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go index c3a3494c4a0..2c8570332a2 100644 --- a/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go @@ -158,33 +158,6 @@ func (in *CronJobStatus) DeepCopy() *CronJobStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JobTemplate) DeepCopyInto(out *JobTemplate) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Template.DeepCopyInto(&out.Template) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobTemplate. -func (in *JobTemplate) DeepCopy() *JobTemplate { - if in == nil { - return nil - } - out := new(JobTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *JobTemplate) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JobTemplateSpec) DeepCopyInto(out *JobTemplateSpec) { *out = *in diff --git a/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go index 2836b3b014f..b57e9f1b86b 100644 --- a/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go @@ -72,21 +72,3 @@ func (in *CronJobList) APILifecycleReplacement() schema.GroupVersionKind { func (in *CronJobList) APILifecycleRemoved() (major, minor int) { return 1, 25 } - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *JobTemplate) APILifecycleIntroduced() (major, minor int) { - return 1, 8 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *JobTemplate) APILifecycleDeprecated() (major, minor int) { - return 1, 22 -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *JobTemplate) APILifecycleRemoved() (major, minor int) { - return 1, 25 -} diff --git a/vendor/k8s.io/api/certificates/v1/types.go b/vendor/k8s.io/api/certificates/v1/types.go index 752c6697347..92b2018e761 100644 --- a/vendor/k8s.io/api/certificates/v1/types.go +++ b/vendor/k8s.io/api/certificates/v1/types.go @@ -274,8 +274,11 @@ type CertificateSigningRequestList struct { } // KeyUsage specifies valid usage contexts for keys. -// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 -// https://tools.ietf.org/html/rfc5280#section-4.2.1.12 +// See: +// +// https://tools.ietf.org/html/rfc5280#section-4.2.1.3 +// https://tools.ietf.org/html/rfc5280#section-4.2.1.12 +// // +enum type KeyUsage string diff --git a/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go index 0dc8a4c69b3..4bdf39ebb3e 100644 --- a/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CertificateSigningRequest = map[string]string{ diff --git a/vendor/k8s.io/api/certificates/v1alpha1/doc.go b/vendor/k8s.io/api/certificates/v1alpha1/doc.go new file mode 100644 index 00000000000..d83d0e82076 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true + +// +groupName=certificates.k8s.io + +package v1alpha1 // import "k8s.io/api/certificates/v1alpha1" diff --git a/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go b/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go new file mode 100644 index 00000000000..546ecbefbf7 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go @@ -0,0 +1,831 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/certificates/v1alpha1/generated.proto + +package v1alpha1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *ClusterTrustBundle) Reset() { *m = ClusterTrustBundle{} } +func (*ClusterTrustBundle) ProtoMessage() {} +func (*ClusterTrustBundle) Descriptor() ([]byte, []int) { + return fileDescriptor_8915b0d419f9eda6, []int{0} +} +func (m *ClusterTrustBundle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundle) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundle.Merge(m, src) +} +func (m *ClusterTrustBundle) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundle) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundle.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundle proto.InternalMessageInfo + +func (m *ClusterTrustBundleList) Reset() { *m = ClusterTrustBundleList{} } +func (*ClusterTrustBundleList) ProtoMessage() {} +func (*ClusterTrustBundleList) Descriptor() ([]byte, []int) { + return fileDescriptor_8915b0d419f9eda6, []int{1} +} +func (m *ClusterTrustBundleList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundleList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundleList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundleList.Merge(m, src) +} +func (m *ClusterTrustBundleList) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundleList) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundleList.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundleList proto.InternalMessageInfo + +func (m *ClusterTrustBundleSpec) Reset() { *m = ClusterTrustBundleSpec{} } +func (*ClusterTrustBundleSpec) ProtoMessage() {} +func (*ClusterTrustBundleSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_8915b0d419f9eda6, []int{2} +} +func (m *ClusterTrustBundleSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundleSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundleSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundleSpec.Merge(m, src) +} +func (m *ClusterTrustBundleSpec) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundleSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundleSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundleSpec proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ClusterTrustBundle)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundle") + proto.RegisterType((*ClusterTrustBundleList)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundleList") + proto.RegisterType((*ClusterTrustBundleSpec)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundleSpec") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/certificates/v1alpha1/generated.proto", fileDescriptor_8915b0d419f9eda6) +} + +var fileDescriptor_8915b0d419f9eda6 = []byte{ + // 448 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xc7, 0x77, 0x6a, 0x0b, 0xed, 0x44, 0x41, 0x56, 0x90, 0x90, 0xc3, 0x34, 0xe4, 0xd4, 0x8b, + 0x33, 0x26, 0x54, 0xe9, 0x79, 0x05, 0xa1, 0xe0, 0x0f, 0xd8, 0x7a, 0xb1, 0x78, 0x70, 0x32, 0x79, + 0xdd, 0x8c, 0xc9, 0xee, 0x0e, 0x33, 0xb3, 0x01, 0x6f, 0x82, 0xff, 0x80, 0x7f, 0x56, 0x8e, 0xd5, + 0x53, 0x4f, 0xc5, 0xac, 0xff, 0x88, 0xcc, 0x64, 0x93, 0x5d, 0x5c, 0x25, 0xd2, 0xdb, 0xbe, 0x1f, + 0x9f, 0xef, 0x7b, 0xdf, 0xb7, 0x0c, 0x3e, 0x9f, 0x9d, 0x19, 0x2a, 0x73, 0x36, 0x2b, 0xc6, 0xa0, + 0x33, 0xb0, 0x60, 0xd8, 0x02, 0xb2, 0x49, 0xae, 0x59, 0x55, 0xe0, 0x4a, 0x32, 0x01, 0xda, 0xca, + 0x2b, 0x29, 0xb8, 0x2f, 0x0f, 0xf9, 0x5c, 0x4d, 0xf9, 0x90, 0x25, 0x90, 0x81, 0xe6, 0x16, 0x26, + 0x54, 0xe9, 0xdc, 0xe6, 0x61, 0x7f, 0x4d, 0x50, 0xae, 0x24, 0x6d, 0x12, 0x74, 0x43, 0xf4, 0x9e, + 0x24, 0xd2, 0x4e, 0x8b, 0x31, 0x15, 0x79, 0xca, 0x92, 0x3c, 0xc9, 0x99, 0x07, 0xc7, 0xc5, 0x95, + 0x8f, 0x7c, 0xe0, 0xbf, 0xd6, 0x82, 0xbd, 0xd3, 0x7a, 0x85, 0x94, 0x8b, 0xa9, 0xcc, 0x40, 0x7f, + 0x66, 0x6a, 0x96, 0xb8, 0x84, 0x61, 0x29, 0x58, 0xce, 0x16, 0xad, 0x35, 0x7a, 0xec, 0x5f, 0x94, + 0x2e, 0x32, 0x2b, 0x53, 0x68, 0x01, 0xcf, 0x77, 0x01, 0x46, 0x4c, 0x21, 0xe5, 0x7f, 0x72, 0x83, + 0x1f, 0x08, 0x87, 0x2f, 0xe6, 0x85, 0xb1, 0xa0, 0xdf, 0xe9, 0xc2, 0xd8, 0xa8, 0xc8, 0x26, 0x73, + 0x08, 0x3f, 0xe2, 0x43, 0xb7, 0xda, 0x84, 0x5b, 0xde, 0x45, 0x7d, 0x74, 0xd2, 0x19, 0x3d, 0xa5, + 0xf5, 0x65, 0xb6, 0x13, 0xa8, 0x9a, 0x25, 0x2e, 0x61, 0xa8, 0xeb, 0xa6, 0x8b, 0x21, 0x7d, 0x3b, + 0xfe, 0x04, 0xc2, 0xbe, 0x06, 0xcb, 0xa3, 0x70, 0x79, 0x7b, 0x1c, 0x94, 0xb7, 0xc7, 0xb8, 0xce, + 0xc5, 0x5b, 0xd5, 0xf0, 0x12, 0xef, 0x1b, 0x05, 0xa2, 0xbb, 0xe7, 0xd5, 0xcf, 0xe8, 0xae, 0xbb, + 0xd3, 0xf6, 0x96, 0x17, 0x0a, 0x44, 0x74, 0xbf, 0x9a, 0xb2, 0xef, 0xa2, 0xd8, 0x6b, 0x0e, 0xbe, + 0x23, 0xfc, 0xb8, 0xdd, 0xfe, 0x4a, 0x1a, 0x1b, 0x7e, 0x68, 0x19, 0xa3, 0xff, 0x67, 0xcc, 0xd1, + 0xde, 0xd6, 0xc3, 0x6a, 0xe0, 0xe1, 0x26, 0xd3, 0x30, 0xf5, 0x1e, 0x1f, 0x48, 0x0b, 0xa9, 0xe9, + 0xee, 0xf5, 0xef, 0x9d, 0x74, 0x46, 0xa7, 0x77, 0x71, 0x15, 0x3d, 0xa8, 0x06, 0x1c, 0x9c, 0x3b, + 0xa9, 0x78, 0xad, 0x38, 0xf8, 0xfa, 0x57, 0x4f, 0xce, 0x74, 0x38, 0xc2, 0xd8, 0xc8, 0x24, 0x03, + 0xfd, 0x86, 0xa7, 0xe0, 0x5d, 0x1d, 0xd5, 0xc7, 0xbf, 0xd8, 0x56, 0xe2, 0x46, 0x57, 0xf8, 0x0c, + 0x77, 0x6c, 0x2d, 0xe3, 0xff, 0xc2, 0x51, 0xf4, 0xa8, 0x82, 0x3a, 0x8d, 0x09, 0x71, 0xb3, 0x2f, + 0x7a, 0xb9, 0x5c, 0x91, 0xe0, 0x7a, 0x45, 0x82, 0x9b, 0x15, 0x09, 0xbe, 0x94, 0x04, 0x2d, 0x4b, + 0x82, 0xae, 0x4b, 0x82, 0x6e, 0x4a, 0x82, 0x7e, 0x96, 0x04, 0x7d, 0xfb, 0x45, 0x82, 0xcb, 0xfe, + 0xae, 0x67, 0xf7, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x05, 0xe9, 0xaa, 0x07, 0xb2, 0x03, 0x00, 0x00, +} + +func (m *ClusterTrustBundle) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterTrustBundleList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundleList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundleList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterTrustBundleSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundleSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.TrustBundle) + copy(dAtA[i:], m.TrustBundle) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TrustBundle))) + i-- + dAtA[i] = 0x12 + i -= len(m.SignerName) + copy(dAtA[i:], m.SignerName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SignerName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ClusterTrustBundle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ClusterTrustBundleList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ClusterTrustBundleSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SignerName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.TrustBundle) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *ClusterTrustBundle) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterTrustBundle{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ClusterTrustBundleSpec", "ClusterTrustBundleSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ClusterTrustBundleList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ClusterTrustBundle{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ClusterTrustBundle", "ClusterTrustBundle", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ClusterTrustBundleList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ClusterTrustBundleSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterTrustBundleSpec{`, + `SignerName:` + fmt.Sprintf("%v", this.SignerName) + `,`, + `TrustBundle:` + fmt.Sprintf("%v", this.TrustBundle) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *ClusterTrustBundle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterTrustBundleList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundleList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundleList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ClusterTrustBundle{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterTrustBundleSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundleSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundleSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SignerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SignerName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrustBundle", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TrustBundle = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/certificates/v1alpha1/generated.proto b/vendor/k8s.io/api/certificates/v1alpha1/generated.proto new file mode 100644 index 00000000000..b0ebc4bd458 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/generated.proto @@ -0,0 +1,103 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.certificates.v1alpha1; + +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/certificates/v1alpha1"; + +// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors +// (root certificates). +// +// ClusterTrustBundle objects are considered to be readable by any authenticated +// user in the cluster, because they can be mounted by pods using the +// `clusterTrustBundle` projection. All service accounts have read access to +// ClusterTrustBundles by default. Users who only have namespace-level access +// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount +// that they have access to. +// +// It can be optionally associated with a particular assigner, in which case it +// contains one valid set of trust anchors for that signer. Signers may have +// multiple associated ClusterTrustBundles; each is an independent set of trust +// anchors for that signer. Admission control is used to enforce that only users +// with permissions on the signer can create or modify the corresponding bundle. +message ClusterTrustBundle { + // metadata contains the object metadata. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec contains the signer (if any) and trust anchors. + optional ClusterTrustBundleSpec spec = 2; +} + +// ClusterTrustBundleList is a collection of ClusterTrustBundle objects +message ClusterTrustBundleList { + // metadata contains the list metadata. + // + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is a collection of ClusterTrustBundle objects + repeated ClusterTrustBundle items = 2; +} + +// ClusterTrustBundleSpec contains the signer and trust anchors. +message ClusterTrustBundleSpec { + // signerName indicates the associated signer, if any. + // + // In order to create or update a ClusterTrustBundle that sets signerName, + // you must have the following cluster-scoped permission: + // group=certificates.k8s.io resource=signers resourceName= + // verb=attest. + // + // If signerName is not empty, then the ClusterTrustBundle object must be + // named with the signer name as a prefix (translating slashes to colons). + // For example, for the signer name `example.com/foo`, valid + // ClusterTrustBundle object names include `example.com:foo:abc` and + // `example.com:foo:v1`. + // + // If signerName is empty, then the ClusterTrustBundle object's name must + // not have such a prefix. + // + // List/watch requests for ClusterTrustBundles can filter on this field + // using a `spec.signerName=NAME` field selector. + // + // +optional + optional string signerName = 1; + + // trustBundle contains the individual X.509 trust anchors for this + // bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates. + // + // The data must consist only of PEM certificate blocks that parse as valid + // X.509 certificates. Each certificate must include a basic constraints + // extension with the CA bit set. The API server will reject objects that + // contain duplicate certificates, or that use PEM block headers. + // + // Users of ClusterTrustBundles, including Kubelet, are free to reorder and + // deduplicate certificate blocks in this file according to their own logic, + // as well as to drop PEM block headers and inter-block data. + optional string trustBundle = 2; +} + diff --git a/vendor/k8s.io/api/certificates/v1alpha1/register.go b/vendor/k8s.io/api/certificates/v1alpha1/register.go new file mode 100644 index 00000000000..7288ed9a3e8 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/register.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "certificates.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + localSchemeBuilder = &SchemeBuilder + + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ClusterTrustBundle{}, + &ClusterTrustBundleList{}, + ) + + // Add the watch version that applies + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/certificates/v1alpha1/types.go b/vendor/k8s.io/api/certificates/v1alpha1/types.go new file mode 100644 index 00000000000..1a9fda01123 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/types.go @@ -0,0 +1,106 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:prerelease-lifecycle-gen:introduced=1.26 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors +// (root certificates). +// +// ClusterTrustBundle objects are considered to be readable by any authenticated +// user in the cluster, because they can be mounted by pods using the +// `clusterTrustBundle` projection. All service accounts have read access to +// ClusterTrustBundles by default. Users who only have namespace-level access +// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount +// that they have access to. +// +// It can be optionally associated with a particular assigner, in which case it +// contains one valid set of trust anchors for that signer. Signers may have +// multiple associated ClusterTrustBundles; each is an independent set of trust +// anchors for that signer. Admission control is used to enforce that only users +// with permissions on the signer can create or modify the corresponding bundle. +type ClusterTrustBundle struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the object metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // spec contains the signer (if any) and trust anchors. + Spec ClusterTrustBundleSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` +} + +// ClusterTrustBundleSpec contains the signer and trust anchors. +type ClusterTrustBundleSpec struct { + // signerName indicates the associated signer, if any. + // + // In order to create or update a ClusterTrustBundle that sets signerName, + // you must have the following cluster-scoped permission: + // group=certificates.k8s.io resource=signers resourceName= + // verb=attest. + // + // If signerName is not empty, then the ClusterTrustBundle object must be + // named with the signer name as a prefix (translating slashes to colons). + // For example, for the signer name `example.com/foo`, valid + // ClusterTrustBundle object names include `example.com:foo:abc` and + // `example.com:foo:v1`. + // + // If signerName is empty, then the ClusterTrustBundle object's name must + // not have such a prefix. + // + // List/watch requests for ClusterTrustBundles can filter on this field + // using a `spec.signerName=NAME` field selector. + // + // +optional + SignerName string `json:"signerName,omitempty" protobuf:"bytes,1,opt,name=signerName"` + + // trustBundle contains the individual X.509 trust anchors for this + // bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates. + // + // The data must consist only of PEM certificate blocks that parse as valid + // X.509 certificates. Each certificate must include a basic constraints + // extension with the CA bit set. The API server will reject objects that + // contain duplicate certificates, or that use PEM block headers. + // + // Users of ClusterTrustBundles, including Kubelet, are free to reorder and + // deduplicate certificate blocks in this file according to their own logic, + // as well as to drop PEM block headers and inter-block data. + TrustBundle string `json:"trustBundle" protobuf:"bytes,2,opt,name=trustBundle"` +} + +// +k8s:prerelease-lifecycle-gen:introduced=1.26 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTrustBundleList is a collection of ClusterTrustBundle objects +type ClusterTrustBundleList struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the list metadata. + // + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // items is a collection of ClusterTrustBundle objects + Items []ClusterTrustBundle `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 00000000000..bff649e3cbd --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,60 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_ClusterTrustBundle = map[string]string{ + "": "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.", + "metadata": "metadata contains the object metadata.", + "spec": "spec contains the signer (if any) and trust anchors.", +} + +func (ClusterTrustBundle) SwaggerDoc() map[string]string { + return map_ClusterTrustBundle +} + +var map_ClusterTrustBundleList = map[string]string{ + "": "ClusterTrustBundleList is a collection of ClusterTrustBundle objects", + "metadata": "metadata contains the list metadata.", + "items": "items is a collection of ClusterTrustBundle objects", +} + +func (ClusterTrustBundleList) SwaggerDoc() map[string]string { + return map_ClusterTrustBundleList +} + +var map_ClusterTrustBundleSpec = map[string]string{ + "": "ClusterTrustBundleSpec contains the signer and trust anchors.", + "signerName": "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName= verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.", + "trustBundle": "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.", +} + +func (ClusterTrustBundleSpec) SwaggerDoc() map[string]string { + return map_ClusterTrustBundleSpec +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..30a4dc1e80d --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,102 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundle) DeepCopyInto(out *ClusterTrustBundle) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundle. +func (in *ClusterTrustBundle) DeepCopy() *ClusterTrustBundle { + if in == nil { + return nil + } + out := new(ClusterTrustBundle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTrustBundle) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundleList) DeepCopyInto(out *ClusterTrustBundleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterTrustBundle, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleList. +func (in *ClusterTrustBundleList) DeepCopy() *ClusterTrustBundleList { + if in == nil { + return nil + } + out := new(ClusterTrustBundleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTrustBundleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundleSpec) DeepCopyInto(out *ClusterTrustBundleSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleSpec. +func (in *ClusterTrustBundleSpec) DeepCopy() *ClusterTrustBundleSpec { + if in == nil { + return nil + } + out := new(ClusterTrustBundleSpec) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go new file mode 100644 index 00000000000..dfafa656ccc --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v1alpha1 + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterTrustBundle) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterTrustBundle) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterTrustBundle) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterTrustBundleList) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterTrustBundleList) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterTrustBundleList) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} diff --git a/vendor/k8s.io/api/certificates/v1beta1/generated.proto b/vendor/k8s.io/api/certificates/v1beta1/generated.proto index e246fba021c..f70f01ef7ab 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/generated.proto +++ b/vendor/k8s.io/api/certificates/v1beta1/generated.proto @@ -124,8 +124,10 @@ message CertificateSigningRequestSpec { // allowedUsages specifies a set of usage contexts the key will be // valid for. - // See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 - // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // See: + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // // Valid values are: // "signing", // "digital signature", diff --git a/vendor/k8s.io/api/certificates/v1beta1/types.go b/vendor/k8s.io/api/certificates/v1beta1/types.go index 877312d97e3..7e5a5c198a6 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types.go @@ -89,8 +89,10 @@ type CertificateSigningRequestSpec struct { // allowedUsages specifies a set of usage contexts the key will be // valid for. - // See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 - // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // See: + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // // Valid values are: // "signing", // "digital signature", @@ -229,8 +231,10 @@ type CertificateSigningRequestList struct { } // KeyUsages specifies valid usage contexts for keys. -// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 -// https://tools.ietf.org/html/rfc5280#section-4.2.1.12 +// See: +// +// https://tools.ietf.org/html/rfc5280#section-4.2.1.3 +// https://tools.ietf.org/html/rfc5280#section-4.2.1.12 type KeyUsage string const ( diff --git a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go index d3f318150cb..f9ab1f13de9 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CertificateSigningRequest = map[string]string{ @@ -55,7 +55,7 @@ var map_CertificateSigningRequestSpec = map[string]string{ "request": "Base64-encoded PKCS#10 CSR data", "signerName": "Requested signer for the request. It is a qualified name in the form: `scope-hostname.io/name`. If empty, it will be defaulted:\n 1. If it's a kubelet client certificate, it is assigned\n \"kubernetes.io/kube-apiserver-client-kubelet\".\n 2. If it's a kubelet serving certificate, it is assigned\n \"kubernetes.io/kubelet-serving\".\n 3. Otherwise, it is assigned \"kubernetes.io/legacy-unknown\".\nDistribution of trust for signers happens out of band. You can select on this field using `spec.signerName`.", "expirationSeconds": "expirationSeconds is the requested duration of validity of the issued certificate. The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration.\n\nThe v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager.\n\nCertificate signers may not honor this field for various reasons:\n\n 1. Old signer that is unaware of the field (such as the in-tree\n implementations prior to v1.22)\n 2. Signer whose configured maximum is shorter than the requested duration\n 3. Signer whose configured minimum is longer than the requested duration\n\nThe minimum valid value for expirationSeconds is 600, i.e. 10 minutes.", - "usages": "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12\nValid values are:\n \"signing\",\n \"digital signature\",\n \"content commitment\",\n \"key encipherment\",\n \"key agreement\",\n \"data encipherment\",\n \"cert sign\",\n \"crl sign\",\n \"encipher only\",\n \"decipher only\",\n \"any\",\n \"server auth\",\n \"client auth\",\n \"code signing\",\n \"email protection\",\n \"s/mime\",\n \"ipsec end system\",\n \"ipsec tunnel\",\n \"ipsec user\",\n \"timestamping\",\n \"ocsp signing\",\n \"microsoft sgc\",\n \"netscape sgc\"", + "usages": "allowedUsages specifies a set of usage contexts the key will be valid for. See:\n\thttps://tools.ietf.org/html/rfc5280#section-4.2.1.3\n\thttps://tools.ietf.org/html/rfc5280#section-4.2.1.12\n\nValid values are:\n \"signing\",\n \"digital signature\",\n \"content commitment\",\n \"key encipherment\",\n \"key agreement\",\n \"data encipherment\",\n \"cert sign\",\n \"crl sign\",\n \"encipher only\",\n \"decipher only\",\n \"any\",\n \"server auth\",\n \"client auth\",\n \"code signing\",\n \"email protection\",\n \"s/mime\",\n \"ipsec end system\",\n \"ipsec tunnel\",\n \"ipsec user\",\n \"timestamping\",\n \"ocsp signing\",\n \"microsoft sgc\",\n \"netscape sgc\"", "username": "Information about the requesting user. See user.Info interface for details.", "uid": "UID information about the requesting user. See user.Info interface for details.", "groups": "Group information about the requesting user. See user.Info interface for details.", diff --git a/vendor/k8s.io/api/coordination/v1/generated.proto b/vendor/k8s.io/api/coordination/v1/generated.proto index b1efb737f0c..36fce60f2de 100644 --- a/vendor/k8s.io/api/coordination/v1/generated.proto +++ b/vendor/k8s.io/api/coordination/v1/generated.proto @@ -34,7 +34,7 @@ message Lease { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the Lease. + // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional LeaseSpec spec = 2; @@ -47,7 +47,7 @@ message LeaseList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated Lease items = 2; } @@ -59,7 +59,7 @@ message LeaseSpec { // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional optional int32 leaseDurationSeconds = 2; diff --git a/vendor/k8s.io/api/coordination/v1/types.go b/vendor/k8s.io/api/coordination/v1/types.go index 7a5605ace17..b0e1d068296 100644 --- a/vendor/k8s.io/api/coordination/v1/types.go +++ b/vendor/k8s.io/api/coordination/v1/types.go @@ -30,7 +30,7 @@ type Lease struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the Lease. + // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec LeaseSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -43,7 +43,7 @@ type LeaseSpec struct { HolderIdentity *string `json:"holderIdentity,omitempty" protobuf:"bytes,1,opt,name=holderIdentity"` // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty" protobuf:"varint,2,opt,name=leaseDurationSeconds"` // acquireTime is a time when the current lease was acquired. @@ -69,6 +69,6 @@ type LeaseList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go index 0f14404308c..f3720eca027 100644 --- a/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Lease = map[string]string{ "": "Lease defines a lease concept.", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec contains the specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Lease) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (Lease) SwaggerDoc() map[string]string { var map_LeaseList = map[string]string{ "": "LeaseList is a list of Lease objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (LeaseList) SwaggerDoc() map[string]string { @@ -50,7 +50,7 @@ func (LeaseList) SwaggerDoc() map[string]string { var map_LeaseSpec = map[string]string{ "": "LeaseSpec is a specification of a Lease.", "holderIdentity": "holderIdentity contains the identity of the holder of a current lease.", - "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed RenewTime.", + "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed renewTime.", "acquireTime": "acquireTime is a time when the current lease was acquired.", "renewTime": "renewTime is a time when the current holder of a lease has last updated the lease.", "leaseTransitions": "leaseTransitions is the number of transitions of a lease between holders.", diff --git a/vendor/k8s.io/api/coordination/v1beta1/generated.proto b/vendor/k8s.io/api/coordination/v1beta1/generated.proto index 85faa3b09b4..92c8918b801 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/generated.proto +++ b/vendor/k8s.io/api/coordination/v1beta1/generated.proto @@ -34,7 +34,7 @@ message Lease { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the Lease. + // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional LeaseSpec spec = 2; @@ -47,7 +47,7 @@ message LeaseList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated Lease items = 2; } @@ -59,7 +59,7 @@ message LeaseSpec { // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional optional int32 leaseDurationSeconds = 2; diff --git a/vendor/k8s.io/api/coordination/v1beta1/types.go b/vendor/k8s.io/api/coordination/v1beta1/types.go index 8f300fca854..3a3d5f32e21 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/types.go +++ b/vendor/k8s.io/api/coordination/v1beta1/types.go @@ -33,7 +33,7 @@ type Lease struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the Lease. + // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec LeaseSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -46,7 +46,7 @@ type LeaseSpec struct { HolderIdentity *string `json:"holderIdentity,omitempty" protobuf:"bytes,1,opt,name=holderIdentity"` // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty" protobuf:"varint,2,opt,name=leaseDurationSeconds"` // acquireTime is a time when the current lease was acquired. @@ -75,6 +75,6 @@ type LeaseList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go index f557d265d4c..78ca4e393fc 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Lease = map[string]string{ "": "Lease defines a lease concept.", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec contains the specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Lease) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (Lease) SwaggerDoc() map[string]string { var map_LeaseList = map[string]string{ "": "LeaseList is a list of Lease objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (LeaseList) SwaggerDoc() map[string]string { @@ -50,7 +50,7 @@ func (LeaseList) SwaggerDoc() map[string]string { var map_LeaseSpec = map[string]string{ "": "LeaseSpec is a specification of a Lease.", "holderIdentity": "holderIdentity contains the identity of the holder of a current lease.", - "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed RenewTime.", + "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed renewTime.", "acquireTime": "acquireTime is a time when the current lease was acquired.", "renewTime": "renewTime is a time when the current holder of a lease has last updated the lease.", "leaseTransitions": "leaseTransitions is the number of transitions of a lease between holders.", diff --git a/vendor/k8s.io/api/core/v1/annotation_key_constants.go b/vendor/k8s.io/api/core/v1/annotation_key_constants.go index eb9517e1dd9..61f86f850a3 100644 --- a/vendor/k8s.io/api/core/v1/annotation_key_constants.go +++ b/vendor/k8s.io/api/core/v1/annotation_key_constants.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file should be consistent with pkg/api/annotation_key_constants.go. +// This file should be consistent with pkg/apis/core/annotation_key_constants.go. package v1 @@ -144,8 +144,19 @@ const ( // This annotation is beta-level and is only honored when PodDeletionCost feature is enabled. PodDeletionCost = "controller.kubernetes.io/pod-deletion-cost" - // AnnotationTopologyAwareHints can be used to enable or disable Topology - // Aware Hints for a Service. This may be set to "Auto" or "Disabled". Any - // other value is treated as "Disabled". - AnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + // DeprecatedAnnotationTopologyAwareHints can be used to enable or disable + // Topology Aware Hints for a Service. This may be set to "Auto" or + // "Disabled". Any other value is treated as "Disabled". This annotation has + // been deprecated in favor of the "service.kubernetes.io/topology-mode" + // annotation. + DeprecatedAnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + + // AnnotationTopologyMode can be used to enable or disable Topology Aware + // Routing for a Service. Well known values are "Auto" and "Disabled". + // Implementations may choose to develop new topology approaches, exposing + // them with domain-prefixed values. For example, "example.com/lowest-rtt" + // could be a valid implementation-specific value for this annotation. These + // heuristics will often populate topology hints on EndpointSlices, but that + // is not a requirement. + AnnotationTopologyMode = "service.kubernetes.io/topology-mode" ) diff --git a/vendor/k8s.io/api/core/v1/generated.pb.go b/vendor/k8s.io/api/core/v1/generated.pb.go index 3f8aaf1006b..c7664629600 100644 --- a/vendor/k8s.io/api/core/v1/generated.pb.go +++ b/vendor/k8s.io/api/core/v1/generated.pb.go @@ -469,10 +469,38 @@ func (m *CinderVolumeSource) XXX_DiscardUnknown() { var xxx_messageInfo_CinderVolumeSource proto.InternalMessageInfo +func (m *ClaimSource) Reset() { *m = ClaimSource{} } +func (*ClaimSource) ProtoMessage() {} +func (*ClaimSource) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{15} +} +func (m *ClaimSource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClaimSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClaimSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClaimSource.Merge(m, src) +} +func (m *ClaimSource) XXX_Size() int { + return m.Size() +} +func (m *ClaimSource) XXX_DiscardUnknown() { + xxx_messageInfo_ClaimSource.DiscardUnknown(m) +} + +var xxx_messageInfo_ClaimSource proto.InternalMessageInfo + func (m *ClientIPConfig) Reset() { *m = ClientIPConfig{} } func (*ClientIPConfig) ProtoMessage() {} func (*ClientIPConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{15} + return fileDescriptor_83c10c24ec417dc9, []int{16} } func (m *ClientIPConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -500,7 +528,7 @@ var xxx_messageInfo_ClientIPConfig proto.InternalMessageInfo func (m *ComponentCondition) Reset() { *m = ComponentCondition{} } func (*ComponentCondition) ProtoMessage() {} func (*ComponentCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{16} + return fileDescriptor_83c10c24ec417dc9, []int{17} } func (m *ComponentCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -528,7 +556,7 @@ var xxx_messageInfo_ComponentCondition proto.InternalMessageInfo func (m *ComponentStatus) Reset() { *m = ComponentStatus{} } func (*ComponentStatus) ProtoMessage() {} func (*ComponentStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{17} + return fileDescriptor_83c10c24ec417dc9, []int{18} } func (m *ComponentStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +584,7 @@ var xxx_messageInfo_ComponentStatus proto.InternalMessageInfo func (m *ComponentStatusList) Reset() { *m = ComponentStatusList{} } func (*ComponentStatusList) ProtoMessage() {} func (*ComponentStatusList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{18} + return fileDescriptor_83c10c24ec417dc9, []int{19} } func (m *ComponentStatusList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -584,7 +612,7 @@ var xxx_messageInfo_ComponentStatusList proto.InternalMessageInfo func (m *ConfigMap) Reset() { *m = ConfigMap{} } func (*ConfigMap) ProtoMessage() {} func (*ConfigMap) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{19} + return fileDescriptor_83c10c24ec417dc9, []int{20} } func (m *ConfigMap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -612,7 +640,7 @@ var xxx_messageInfo_ConfigMap proto.InternalMessageInfo func (m *ConfigMapEnvSource) Reset() { *m = ConfigMapEnvSource{} } func (*ConfigMapEnvSource) ProtoMessage() {} func (*ConfigMapEnvSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{20} + return fileDescriptor_83c10c24ec417dc9, []int{21} } func (m *ConfigMapEnvSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -640,7 +668,7 @@ var xxx_messageInfo_ConfigMapEnvSource proto.InternalMessageInfo func (m *ConfigMapKeySelector) Reset() { *m = ConfigMapKeySelector{} } func (*ConfigMapKeySelector) ProtoMessage() {} func (*ConfigMapKeySelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{21} + return fileDescriptor_83c10c24ec417dc9, []int{22} } func (m *ConfigMapKeySelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -668,7 +696,7 @@ var xxx_messageInfo_ConfigMapKeySelector proto.InternalMessageInfo func (m *ConfigMapList) Reset() { *m = ConfigMapList{} } func (*ConfigMapList) ProtoMessage() {} func (*ConfigMapList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{22} + return fileDescriptor_83c10c24ec417dc9, []int{23} } func (m *ConfigMapList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +724,7 @@ var xxx_messageInfo_ConfigMapList proto.InternalMessageInfo func (m *ConfigMapNodeConfigSource) Reset() { *m = ConfigMapNodeConfigSource{} } func (*ConfigMapNodeConfigSource) ProtoMessage() {} func (*ConfigMapNodeConfigSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{23} + return fileDescriptor_83c10c24ec417dc9, []int{24} } func (m *ConfigMapNodeConfigSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -724,7 +752,7 @@ var xxx_messageInfo_ConfigMapNodeConfigSource proto.InternalMessageInfo func (m *ConfigMapProjection) Reset() { *m = ConfigMapProjection{} } func (*ConfigMapProjection) ProtoMessage() {} func (*ConfigMapProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{24} + return fileDescriptor_83c10c24ec417dc9, []int{25} } func (m *ConfigMapProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +780,7 @@ var xxx_messageInfo_ConfigMapProjection proto.InternalMessageInfo func (m *ConfigMapVolumeSource) Reset() { *m = ConfigMapVolumeSource{} } func (*ConfigMapVolumeSource) ProtoMessage() {} func (*ConfigMapVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{25} + return fileDescriptor_83c10c24ec417dc9, []int{26} } func (m *ConfigMapVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -780,7 +808,7 @@ var xxx_messageInfo_ConfigMapVolumeSource proto.InternalMessageInfo func (m *Container) Reset() { *m = Container{} } func (*Container) ProtoMessage() {} func (*Container) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{26} + return fileDescriptor_83c10c24ec417dc9, []int{27} } func (m *Container) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -808,7 +836,7 @@ var xxx_messageInfo_Container proto.InternalMessageInfo func (m *ContainerImage) Reset() { *m = ContainerImage{} } func (*ContainerImage) ProtoMessage() {} func (*ContainerImage) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{27} + return fileDescriptor_83c10c24ec417dc9, []int{28} } func (m *ContainerImage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -836,7 +864,7 @@ var xxx_messageInfo_ContainerImage proto.InternalMessageInfo func (m *ContainerPort) Reset() { *m = ContainerPort{} } func (*ContainerPort) ProtoMessage() {} func (*ContainerPort) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{28} + return fileDescriptor_83c10c24ec417dc9, []int{29} } func (m *ContainerPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -861,10 +889,38 @@ func (m *ContainerPort) XXX_DiscardUnknown() { var xxx_messageInfo_ContainerPort proto.InternalMessageInfo +func (m *ContainerResizePolicy) Reset() { *m = ContainerResizePolicy{} } +func (*ContainerResizePolicy) ProtoMessage() {} +func (*ContainerResizePolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{30} +} +func (m *ContainerResizePolicy) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContainerResizePolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ContainerResizePolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContainerResizePolicy.Merge(m, src) +} +func (m *ContainerResizePolicy) XXX_Size() int { + return m.Size() +} +func (m *ContainerResizePolicy) XXX_DiscardUnknown() { + xxx_messageInfo_ContainerResizePolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_ContainerResizePolicy proto.InternalMessageInfo + func (m *ContainerState) Reset() { *m = ContainerState{} } func (*ContainerState) ProtoMessage() {} func (*ContainerState) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{29} + return fileDescriptor_83c10c24ec417dc9, []int{31} } func (m *ContainerState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,7 +948,7 @@ var xxx_messageInfo_ContainerState proto.InternalMessageInfo func (m *ContainerStateRunning) Reset() { *m = ContainerStateRunning{} } func (*ContainerStateRunning) ProtoMessage() {} func (*ContainerStateRunning) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{30} + return fileDescriptor_83c10c24ec417dc9, []int{32} } func (m *ContainerStateRunning) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +976,7 @@ var xxx_messageInfo_ContainerStateRunning proto.InternalMessageInfo func (m *ContainerStateTerminated) Reset() { *m = ContainerStateTerminated{} } func (*ContainerStateTerminated) ProtoMessage() {} func (*ContainerStateTerminated) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{31} + return fileDescriptor_83c10c24ec417dc9, []int{33} } func (m *ContainerStateTerminated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -948,7 +1004,7 @@ var xxx_messageInfo_ContainerStateTerminated proto.InternalMessageInfo func (m *ContainerStateWaiting) Reset() { *m = ContainerStateWaiting{} } func (*ContainerStateWaiting) ProtoMessage() {} func (*ContainerStateWaiting) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{32} + return fileDescriptor_83c10c24ec417dc9, []int{34} } func (m *ContainerStateWaiting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -976,7 +1032,7 @@ var xxx_messageInfo_ContainerStateWaiting proto.InternalMessageInfo func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (*ContainerStatus) ProtoMessage() {} func (*ContainerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{33} + return fileDescriptor_83c10c24ec417dc9, []int{35} } func (m *ContainerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1004,7 +1060,7 @@ var xxx_messageInfo_ContainerStatus proto.InternalMessageInfo func (m *DaemonEndpoint) Reset() { *m = DaemonEndpoint{} } func (*DaemonEndpoint) ProtoMessage() {} func (*DaemonEndpoint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{34} + return fileDescriptor_83c10c24ec417dc9, []int{36} } func (m *DaemonEndpoint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1032,7 +1088,7 @@ var xxx_messageInfo_DaemonEndpoint proto.InternalMessageInfo func (m *DownwardAPIProjection) Reset() { *m = DownwardAPIProjection{} } func (*DownwardAPIProjection) ProtoMessage() {} func (*DownwardAPIProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{35} + return fileDescriptor_83c10c24ec417dc9, []int{37} } func (m *DownwardAPIProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1060,7 +1116,7 @@ var xxx_messageInfo_DownwardAPIProjection proto.InternalMessageInfo func (m *DownwardAPIVolumeFile) Reset() { *m = DownwardAPIVolumeFile{} } func (*DownwardAPIVolumeFile) ProtoMessage() {} func (*DownwardAPIVolumeFile) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{36} + return fileDescriptor_83c10c24ec417dc9, []int{38} } func (m *DownwardAPIVolumeFile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1088,7 +1144,7 @@ var xxx_messageInfo_DownwardAPIVolumeFile proto.InternalMessageInfo func (m *DownwardAPIVolumeSource) Reset() { *m = DownwardAPIVolumeSource{} } func (*DownwardAPIVolumeSource) ProtoMessage() {} func (*DownwardAPIVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{37} + return fileDescriptor_83c10c24ec417dc9, []int{39} } func (m *DownwardAPIVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1116,7 +1172,7 @@ var xxx_messageInfo_DownwardAPIVolumeSource proto.InternalMessageInfo func (m *EmptyDirVolumeSource) Reset() { *m = EmptyDirVolumeSource{} } func (*EmptyDirVolumeSource) ProtoMessage() {} func (*EmptyDirVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{38} + return fileDescriptor_83c10c24ec417dc9, []int{40} } func (m *EmptyDirVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1144,7 +1200,7 @@ var xxx_messageInfo_EmptyDirVolumeSource proto.InternalMessageInfo func (m *EndpointAddress) Reset() { *m = EndpointAddress{} } func (*EndpointAddress) ProtoMessage() {} func (*EndpointAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{39} + return fileDescriptor_83c10c24ec417dc9, []int{41} } func (m *EndpointAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1172,7 +1228,7 @@ var xxx_messageInfo_EndpointAddress proto.InternalMessageInfo func (m *EndpointPort) Reset() { *m = EndpointPort{} } func (*EndpointPort) ProtoMessage() {} func (*EndpointPort) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{40} + return fileDescriptor_83c10c24ec417dc9, []int{42} } func (m *EndpointPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1200,7 +1256,7 @@ var xxx_messageInfo_EndpointPort proto.InternalMessageInfo func (m *EndpointSubset) Reset() { *m = EndpointSubset{} } func (*EndpointSubset) ProtoMessage() {} func (*EndpointSubset) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{41} + return fileDescriptor_83c10c24ec417dc9, []int{43} } func (m *EndpointSubset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1228,7 +1284,7 @@ var xxx_messageInfo_EndpointSubset proto.InternalMessageInfo func (m *Endpoints) Reset() { *m = Endpoints{} } func (*Endpoints) ProtoMessage() {} func (*Endpoints) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{42} + return fileDescriptor_83c10c24ec417dc9, []int{44} } func (m *Endpoints) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1256,7 +1312,7 @@ var xxx_messageInfo_Endpoints proto.InternalMessageInfo func (m *EndpointsList) Reset() { *m = EndpointsList{} } func (*EndpointsList) ProtoMessage() {} func (*EndpointsList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{43} + return fileDescriptor_83c10c24ec417dc9, []int{45} } func (m *EndpointsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1284,7 +1340,7 @@ var xxx_messageInfo_EndpointsList proto.InternalMessageInfo func (m *EnvFromSource) Reset() { *m = EnvFromSource{} } func (*EnvFromSource) ProtoMessage() {} func (*EnvFromSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{44} + return fileDescriptor_83c10c24ec417dc9, []int{46} } func (m *EnvFromSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1312,7 +1368,7 @@ var xxx_messageInfo_EnvFromSource proto.InternalMessageInfo func (m *EnvVar) Reset() { *m = EnvVar{} } func (*EnvVar) ProtoMessage() {} func (*EnvVar) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{45} + return fileDescriptor_83c10c24ec417dc9, []int{47} } func (m *EnvVar) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1340,7 +1396,7 @@ var xxx_messageInfo_EnvVar proto.InternalMessageInfo func (m *EnvVarSource) Reset() { *m = EnvVarSource{} } func (*EnvVarSource) ProtoMessage() {} func (*EnvVarSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{46} + return fileDescriptor_83c10c24ec417dc9, []int{48} } func (m *EnvVarSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1368,7 +1424,7 @@ var xxx_messageInfo_EnvVarSource proto.InternalMessageInfo func (m *EphemeralContainer) Reset() { *m = EphemeralContainer{} } func (*EphemeralContainer) ProtoMessage() {} func (*EphemeralContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{47} + return fileDescriptor_83c10c24ec417dc9, []int{49} } func (m *EphemeralContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1396,7 +1452,7 @@ var xxx_messageInfo_EphemeralContainer proto.InternalMessageInfo func (m *EphemeralContainerCommon) Reset() { *m = EphemeralContainerCommon{} } func (*EphemeralContainerCommon) ProtoMessage() {} func (*EphemeralContainerCommon) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{48} + return fileDescriptor_83c10c24ec417dc9, []int{50} } func (m *EphemeralContainerCommon) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1424,7 +1480,7 @@ var xxx_messageInfo_EphemeralContainerCommon proto.InternalMessageInfo func (m *EphemeralVolumeSource) Reset() { *m = EphemeralVolumeSource{} } func (*EphemeralVolumeSource) ProtoMessage() {} func (*EphemeralVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{49} + return fileDescriptor_83c10c24ec417dc9, []int{51} } func (m *EphemeralVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1452,7 +1508,7 @@ var xxx_messageInfo_EphemeralVolumeSource proto.InternalMessageInfo func (m *Event) Reset() { *m = Event{} } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{50} + return fileDescriptor_83c10c24ec417dc9, []int{52} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1480,7 +1536,7 @@ var xxx_messageInfo_Event proto.InternalMessageInfo func (m *EventList) Reset() { *m = EventList{} } func (*EventList) ProtoMessage() {} func (*EventList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{51} + return fileDescriptor_83c10c24ec417dc9, []int{53} } func (m *EventList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1508,7 +1564,7 @@ var xxx_messageInfo_EventList proto.InternalMessageInfo func (m *EventSeries) Reset() { *m = EventSeries{} } func (*EventSeries) ProtoMessage() {} func (*EventSeries) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{52} + return fileDescriptor_83c10c24ec417dc9, []int{54} } func (m *EventSeries) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1536,7 +1592,7 @@ var xxx_messageInfo_EventSeries proto.InternalMessageInfo func (m *EventSource) Reset() { *m = EventSource{} } func (*EventSource) ProtoMessage() {} func (*EventSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{53} + return fileDescriptor_83c10c24ec417dc9, []int{55} } func (m *EventSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1564,7 +1620,7 @@ var xxx_messageInfo_EventSource proto.InternalMessageInfo func (m *ExecAction) Reset() { *m = ExecAction{} } func (*ExecAction) ProtoMessage() {} func (*ExecAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{54} + return fileDescriptor_83c10c24ec417dc9, []int{56} } func (m *ExecAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1592,7 +1648,7 @@ var xxx_messageInfo_ExecAction proto.InternalMessageInfo func (m *FCVolumeSource) Reset() { *m = FCVolumeSource{} } func (*FCVolumeSource) ProtoMessage() {} func (*FCVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{55} + return fileDescriptor_83c10c24ec417dc9, []int{57} } func (m *FCVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1620,7 +1676,7 @@ var xxx_messageInfo_FCVolumeSource proto.InternalMessageInfo func (m *FlexPersistentVolumeSource) Reset() { *m = FlexPersistentVolumeSource{} } func (*FlexPersistentVolumeSource) ProtoMessage() {} func (*FlexPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{56} + return fileDescriptor_83c10c24ec417dc9, []int{58} } func (m *FlexPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1648,7 +1704,7 @@ var xxx_messageInfo_FlexPersistentVolumeSource proto.InternalMessageInfo func (m *FlexVolumeSource) Reset() { *m = FlexVolumeSource{} } func (*FlexVolumeSource) ProtoMessage() {} func (*FlexVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{57} + return fileDescriptor_83c10c24ec417dc9, []int{59} } func (m *FlexVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1676,7 +1732,7 @@ var xxx_messageInfo_FlexVolumeSource proto.InternalMessageInfo func (m *FlockerVolumeSource) Reset() { *m = FlockerVolumeSource{} } func (*FlockerVolumeSource) ProtoMessage() {} func (*FlockerVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{58} + return fileDescriptor_83c10c24ec417dc9, []int{60} } func (m *FlockerVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1704,7 +1760,7 @@ var xxx_messageInfo_FlockerVolumeSource proto.InternalMessageInfo func (m *GCEPersistentDiskVolumeSource) Reset() { *m = GCEPersistentDiskVolumeSource{} } func (*GCEPersistentDiskVolumeSource) ProtoMessage() {} func (*GCEPersistentDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{59} + return fileDescriptor_83c10c24ec417dc9, []int{61} } func (m *GCEPersistentDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1732,7 +1788,7 @@ var xxx_messageInfo_GCEPersistentDiskVolumeSource proto.InternalMessageInfo func (m *GRPCAction) Reset() { *m = GRPCAction{} } func (*GRPCAction) ProtoMessage() {} func (*GRPCAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{60} + return fileDescriptor_83c10c24ec417dc9, []int{62} } func (m *GRPCAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1760,7 +1816,7 @@ var xxx_messageInfo_GRPCAction proto.InternalMessageInfo func (m *GitRepoVolumeSource) Reset() { *m = GitRepoVolumeSource{} } func (*GitRepoVolumeSource) ProtoMessage() {} func (*GitRepoVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{61} + return fileDescriptor_83c10c24ec417dc9, []int{63} } func (m *GitRepoVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1788,7 +1844,7 @@ var xxx_messageInfo_GitRepoVolumeSource proto.InternalMessageInfo func (m *GlusterfsPersistentVolumeSource) Reset() { *m = GlusterfsPersistentVolumeSource{} } func (*GlusterfsPersistentVolumeSource) ProtoMessage() {} func (*GlusterfsPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{62} + return fileDescriptor_83c10c24ec417dc9, []int{64} } func (m *GlusterfsPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1816,7 +1872,7 @@ var xxx_messageInfo_GlusterfsPersistentVolumeSource proto.InternalMessageInfo func (m *GlusterfsVolumeSource) Reset() { *m = GlusterfsVolumeSource{} } func (*GlusterfsVolumeSource) ProtoMessage() {} func (*GlusterfsVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{63} + return fileDescriptor_83c10c24ec417dc9, []int{65} } func (m *GlusterfsVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1844,7 +1900,7 @@ var xxx_messageInfo_GlusterfsVolumeSource proto.InternalMessageInfo func (m *HTTPGetAction) Reset() { *m = HTTPGetAction{} } func (*HTTPGetAction) ProtoMessage() {} func (*HTTPGetAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{64} + return fileDescriptor_83c10c24ec417dc9, []int{66} } func (m *HTTPGetAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1872,7 +1928,7 @@ var xxx_messageInfo_HTTPGetAction proto.InternalMessageInfo func (m *HTTPHeader) Reset() { *m = HTTPHeader{} } func (*HTTPHeader) ProtoMessage() {} func (*HTTPHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{65} + return fileDescriptor_83c10c24ec417dc9, []int{67} } func (m *HTTPHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1900,7 +1956,7 @@ var xxx_messageInfo_HTTPHeader proto.InternalMessageInfo func (m *HostAlias) Reset() { *m = HostAlias{} } func (*HostAlias) ProtoMessage() {} func (*HostAlias) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{66} + return fileDescriptor_83c10c24ec417dc9, []int{68} } func (m *HostAlias) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1928,7 +1984,7 @@ var xxx_messageInfo_HostAlias proto.InternalMessageInfo func (m *HostPathVolumeSource) Reset() { *m = HostPathVolumeSource{} } func (*HostPathVolumeSource) ProtoMessage() {} func (*HostPathVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{67} + return fileDescriptor_83c10c24ec417dc9, []int{69} } func (m *HostPathVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1956,7 +2012,7 @@ var xxx_messageInfo_HostPathVolumeSource proto.InternalMessageInfo func (m *ISCSIPersistentVolumeSource) Reset() { *m = ISCSIPersistentVolumeSource{} } func (*ISCSIPersistentVolumeSource) ProtoMessage() {} func (*ISCSIPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{68} + return fileDescriptor_83c10c24ec417dc9, []int{70} } func (m *ISCSIPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1984,7 +2040,7 @@ var xxx_messageInfo_ISCSIPersistentVolumeSource proto.InternalMessageInfo func (m *ISCSIVolumeSource) Reset() { *m = ISCSIVolumeSource{} } func (*ISCSIVolumeSource) ProtoMessage() {} func (*ISCSIVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{69} + return fileDescriptor_83c10c24ec417dc9, []int{71} } func (m *ISCSIVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2012,7 +2068,7 @@ var xxx_messageInfo_ISCSIVolumeSource proto.InternalMessageInfo func (m *KeyToPath) Reset() { *m = KeyToPath{} } func (*KeyToPath) ProtoMessage() {} func (*KeyToPath) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{70} + return fileDescriptor_83c10c24ec417dc9, []int{72} } func (m *KeyToPath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2040,7 +2096,7 @@ var xxx_messageInfo_KeyToPath proto.InternalMessageInfo func (m *Lifecycle) Reset() { *m = Lifecycle{} } func (*Lifecycle) ProtoMessage() {} func (*Lifecycle) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{71} + return fileDescriptor_83c10c24ec417dc9, []int{73} } func (m *Lifecycle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2068,7 +2124,7 @@ var xxx_messageInfo_Lifecycle proto.InternalMessageInfo func (m *LifecycleHandler) Reset() { *m = LifecycleHandler{} } func (*LifecycleHandler) ProtoMessage() {} func (*LifecycleHandler) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{72} + return fileDescriptor_83c10c24ec417dc9, []int{74} } func (m *LifecycleHandler) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2096,7 +2152,7 @@ var xxx_messageInfo_LifecycleHandler proto.InternalMessageInfo func (m *LimitRange) Reset() { *m = LimitRange{} } func (*LimitRange) ProtoMessage() {} func (*LimitRange) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{73} + return fileDescriptor_83c10c24ec417dc9, []int{75} } func (m *LimitRange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2124,7 +2180,7 @@ var xxx_messageInfo_LimitRange proto.InternalMessageInfo func (m *LimitRangeItem) Reset() { *m = LimitRangeItem{} } func (*LimitRangeItem) ProtoMessage() {} func (*LimitRangeItem) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{74} + return fileDescriptor_83c10c24ec417dc9, []int{76} } func (m *LimitRangeItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2152,7 +2208,7 @@ var xxx_messageInfo_LimitRangeItem proto.InternalMessageInfo func (m *LimitRangeList) Reset() { *m = LimitRangeList{} } func (*LimitRangeList) ProtoMessage() {} func (*LimitRangeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{75} + return fileDescriptor_83c10c24ec417dc9, []int{77} } func (m *LimitRangeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2180,7 +2236,7 @@ var xxx_messageInfo_LimitRangeList proto.InternalMessageInfo func (m *LimitRangeSpec) Reset() { *m = LimitRangeSpec{} } func (*LimitRangeSpec) ProtoMessage() {} func (*LimitRangeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{76} + return fileDescriptor_83c10c24ec417dc9, []int{78} } func (m *LimitRangeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2208,7 +2264,7 @@ var xxx_messageInfo_LimitRangeSpec proto.InternalMessageInfo func (m *List) Reset() { *m = List{} } func (*List) ProtoMessage() {} func (*List) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{77} + return fileDescriptor_83c10c24ec417dc9, []int{79} } func (m *List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2236,7 +2292,7 @@ var xxx_messageInfo_List proto.InternalMessageInfo func (m *LoadBalancerIngress) Reset() { *m = LoadBalancerIngress{} } func (*LoadBalancerIngress) ProtoMessage() {} func (*LoadBalancerIngress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{78} + return fileDescriptor_83c10c24ec417dc9, []int{80} } func (m *LoadBalancerIngress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2264,7 +2320,7 @@ var xxx_messageInfo_LoadBalancerIngress proto.InternalMessageInfo func (m *LoadBalancerStatus) Reset() { *m = LoadBalancerStatus{} } func (*LoadBalancerStatus) ProtoMessage() {} func (*LoadBalancerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{79} + return fileDescriptor_83c10c24ec417dc9, []int{81} } func (m *LoadBalancerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2292,7 +2348,7 @@ var xxx_messageInfo_LoadBalancerStatus proto.InternalMessageInfo func (m *LocalObjectReference) Reset() { *m = LocalObjectReference{} } func (*LocalObjectReference) ProtoMessage() {} func (*LocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{80} + return fileDescriptor_83c10c24ec417dc9, []int{82} } func (m *LocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2320,7 +2376,7 @@ var xxx_messageInfo_LocalObjectReference proto.InternalMessageInfo func (m *LocalVolumeSource) Reset() { *m = LocalVolumeSource{} } func (*LocalVolumeSource) ProtoMessage() {} func (*LocalVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{81} + return fileDescriptor_83c10c24ec417dc9, []int{83} } func (m *LocalVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2348,7 +2404,7 @@ var xxx_messageInfo_LocalVolumeSource proto.InternalMessageInfo func (m *NFSVolumeSource) Reset() { *m = NFSVolumeSource{} } func (*NFSVolumeSource) ProtoMessage() {} func (*NFSVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{82} + return fileDescriptor_83c10c24ec417dc9, []int{84} } func (m *NFSVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2376,7 +2432,7 @@ var xxx_messageInfo_NFSVolumeSource proto.InternalMessageInfo func (m *Namespace) Reset() { *m = Namespace{} } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{83} + return fileDescriptor_83c10c24ec417dc9, []int{85} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2404,7 +2460,7 @@ var xxx_messageInfo_Namespace proto.InternalMessageInfo func (m *NamespaceCondition) Reset() { *m = NamespaceCondition{} } func (*NamespaceCondition) ProtoMessage() {} func (*NamespaceCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{84} + return fileDescriptor_83c10c24ec417dc9, []int{86} } func (m *NamespaceCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2432,7 +2488,7 @@ var xxx_messageInfo_NamespaceCondition proto.InternalMessageInfo func (m *NamespaceList) Reset() { *m = NamespaceList{} } func (*NamespaceList) ProtoMessage() {} func (*NamespaceList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{85} + return fileDescriptor_83c10c24ec417dc9, []int{87} } func (m *NamespaceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2460,7 +2516,7 @@ var xxx_messageInfo_NamespaceList proto.InternalMessageInfo func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{86} + return fileDescriptor_83c10c24ec417dc9, []int{88} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2488,7 +2544,7 @@ var xxx_messageInfo_NamespaceSpec proto.InternalMessageInfo func (m *NamespaceStatus) Reset() { *m = NamespaceStatus{} } func (*NamespaceStatus) ProtoMessage() {} func (*NamespaceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{87} + return fileDescriptor_83c10c24ec417dc9, []int{89} } func (m *NamespaceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2516,7 +2572,7 @@ var xxx_messageInfo_NamespaceStatus proto.InternalMessageInfo func (m *Node) Reset() { *m = Node{} } func (*Node) ProtoMessage() {} func (*Node) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{88} + return fileDescriptor_83c10c24ec417dc9, []int{90} } func (m *Node) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2544,7 +2600,7 @@ var xxx_messageInfo_Node proto.InternalMessageInfo func (m *NodeAddress) Reset() { *m = NodeAddress{} } func (*NodeAddress) ProtoMessage() {} func (*NodeAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{89} + return fileDescriptor_83c10c24ec417dc9, []int{91} } func (m *NodeAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2572,7 +2628,7 @@ var xxx_messageInfo_NodeAddress proto.InternalMessageInfo func (m *NodeAffinity) Reset() { *m = NodeAffinity{} } func (*NodeAffinity) ProtoMessage() {} func (*NodeAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{90} + return fileDescriptor_83c10c24ec417dc9, []int{92} } func (m *NodeAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2600,7 +2656,7 @@ var xxx_messageInfo_NodeAffinity proto.InternalMessageInfo func (m *NodeCondition) Reset() { *m = NodeCondition{} } func (*NodeCondition) ProtoMessage() {} func (*NodeCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{91} + return fileDescriptor_83c10c24ec417dc9, []int{93} } func (m *NodeCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2628,7 +2684,7 @@ var xxx_messageInfo_NodeCondition proto.InternalMessageInfo func (m *NodeConfigSource) Reset() { *m = NodeConfigSource{} } func (*NodeConfigSource) ProtoMessage() {} func (*NodeConfigSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{92} + return fileDescriptor_83c10c24ec417dc9, []int{94} } func (m *NodeConfigSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2656,7 +2712,7 @@ var xxx_messageInfo_NodeConfigSource proto.InternalMessageInfo func (m *NodeConfigStatus) Reset() { *m = NodeConfigStatus{} } func (*NodeConfigStatus) ProtoMessage() {} func (*NodeConfigStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{93} + return fileDescriptor_83c10c24ec417dc9, []int{95} } func (m *NodeConfigStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2684,7 +2740,7 @@ var xxx_messageInfo_NodeConfigStatus proto.InternalMessageInfo func (m *NodeDaemonEndpoints) Reset() { *m = NodeDaemonEndpoints{} } func (*NodeDaemonEndpoints) ProtoMessage() {} func (*NodeDaemonEndpoints) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{94} + return fileDescriptor_83c10c24ec417dc9, []int{96} } func (m *NodeDaemonEndpoints) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2712,7 +2768,7 @@ var xxx_messageInfo_NodeDaemonEndpoints proto.InternalMessageInfo func (m *NodeList) Reset() { *m = NodeList{} } func (*NodeList) ProtoMessage() {} func (*NodeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{95} + return fileDescriptor_83c10c24ec417dc9, []int{97} } func (m *NodeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2740,7 +2796,7 @@ var xxx_messageInfo_NodeList proto.InternalMessageInfo func (m *NodeProxyOptions) Reset() { *m = NodeProxyOptions{} } func (*NodeProxyOptions) ProtoMessage() {} func (*NodeProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{96} + return fileDescriptor_83c10c24ec417dc9, []int{98} } func (m *NodeProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2768,7 +2824,7 @@ var xxx_messageInfo_NodeProxyOptions proto.InternalMessageInfo func (m *NodeResources) Reset() { *m = NodeResources{} } func (*NodeResources) ProtoMessage() {} func (*NodeResources) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{97} + return fileDescriptor_83c10c24ec417dc9, []int{99} } func (m *NodeResources) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2796,7 +2852,7 @@ var xxx_messageInfo_NodeResources proto.InternalMessageInfo func (m *NodeSelector) Reset() { *m = NodeSelector{} } func (*NodeSelector) ProtoMessage() {} func (*NodeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{98} + return fileDescriptor_83c10c24ec417dc9, []int{100} } func (m *NodeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2824,7 +2880,7 @@ var xxx_messageInfo_NodeSelector proto.InternalMessageInfo func (m *NodeSelectorRequirement) Reset() { *m = NodeSelectorRequirement{} } func (*NodeSelectorRequirement) ProtoMessage() {} func (*NodeSelectorRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{99} + return fileDescriptor_83c10c24ec417dc9, []int{101} } func (m *NodeSelectorRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2852,7 +2908,7 @@ var xxx_messageInfo_NodeSelectorRequirement proto.InternalMessageInfo func (m *NodeSelectorTerm) Reset() { *m = NodeSelectorTerm{} } func (*NodeSelectorTerm) ProtoMessage() {} func (*NodeSelectorTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{100} + return fileDescriptor_83c10c24ec417dc9, []int{102} } func (m *NodeSelectorTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2880,7 +2936,7 @@ var xxx_messageInfo_NodeSelectorTerm proto.InternalMessageInfo func (m *NodeSpec) Reset() { *m = NodeSpec{} } func (*NodeSpec) ProtoMessage() {} func (*NodeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{101} + return fileDescriptor_83c10c24ec417dc9, []int{103} } func (m *NodeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2908,7 +2964,7 @@ var xxx_messageInfo_NodeSpec proto.InternalMessageInfo func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{102} + return fileDescriptor_83c10c24ec417dc9, []int{104} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2936,7 +2992,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *NodeSystemInfo) Reset() { *m = NodeSystemInfo{} } func (*NodeSystemInfo) ProtoMessage() {} func (*NodeSystemInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{103} + return fileDescriptor_83c10c24ec417dc9, []int{105} } func (m *NodeSystemInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2964,7 +3020,7 @@ var xxx_messageInfo_NodeSystemInfo proto.InternalMessageInfo func (m *ObjectFieldSelector) Reset() { *m = ObjectFieldSelector{} } func (*ObjectFieldSelector) ProtoMessage() {} func (*ObjectFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{104} + return fileDescriptor_83c10c24ec417dc9, []int{106} } func (m *ObjectFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2992,7 +3048,7 @@ var xxx_messageInfo_ObjectFieldSelector proto.InternalMessageInfo func (m *ObjectReference) Reset() { *m = ObjectReference{} } func (*ObjectReference) ProtoMessage() {} func (*ObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{105} + return fileDescriptor_83c10c24ec417dc9, []int{107} } func (m *ObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3020,7 +3076,7 @@ var xxx_messageInfo_ObjectReference proto.InternalMessageInfo func (m *PersistentVolume) Reset() { *m = PersistentVolume{} } func (*PersistentVolume) ProtoMessage() {} func (*PersistentVolume) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{106} + return fileDescriptor_83c10c24ec417dc9, []int{108} } func (m *PersistentVolume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3048,7 +3104,7 @@ var xxx_messageInfo_PersistentVolume proto.InternalMessageInfo func (m *PersistentVolumeClaim) Reset() { *m = PersistentVolumeClaim{} } func (*PersistentVolumeClaim) ProtoMessage() {} func (*PersistentVolumeClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{107} + return fileDescriptor_83c10c24ec417dc9, []int{109} } func (m *PersistentVolumeClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3076,7 +3132,7 @@ var xxx_messageInfo_PersistentVolumeClaim proto.InternalMessageInfo func (m *PersistentVolumeClaimCondition) Reset() { *m = PersistentVolumeClaimCondition{} } func (*PersistentVolumeClaimCondition) ProtoMessage() {} func (*PersistentVolumeClaimCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{108} + return fileDescriptor_83c10c24ec417dc9, []int{110} } func (m *PersistentVolumeClaimCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3104,7 +3160,7 @@ var xxx_messageInfo_PersistentVolumeClaimCondition proto.InternalMessageInfo func (m *PersistentVolumeClaimList) Reset() { *m = PersistentVolumeClaimList{} } func (*PersistentVolumeClaimList) ProtoMessage() {} func (*PersistentVolumeClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{109} + return fileDescriptor_83c10c24ec417dc9, []int{111} } func (m *PersistentVolumeClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3132,7 +3188,7 @@ var xxx_messageInfo_PersistentVolumeClaimList proto.InternalMessageInfo func (m *PersistentVolumeClaimSpec) Reset() { *m = PersistentVolumeClaimSpec{} } func (*PersistentVolumeClaimSpec) ProtoMessage() {} func (*PersistentVolumeClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{110} + return fileDescriptor_83c10c24ec417dc9, []int{112} } func (m *PersistentVolumeClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3160,7 +3216,7 @@ var xxx_messageInfo_PersistentVolumeClaimSpec proto.InternalMessageInfo func (m *PersistentVolumeClaimStatus) Reset() { *m = PersistentVolumeClaimStatus{} } func (*PersistentVolumeClaimStatus) ProtoMessage() {} func (*PersistentVolumeClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{111} + return fileDescriptor_83c10c24ec417dc9, []int{113} } func (m *PersistentVolumeClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3188,7 +3244,7 @@ var xxx_messageInfo_PersistentVolumeClaimStatus proto.InternalMessageInfo func (m *PersistentVolumeClaimTemplate) Reset() { *m = PersistentVolumeClaimTemplate{} } func (*PersistentVolumeClaimTemplate) ProtoMessage() {} func (*PersistentVolumeClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{112} + return fileDescriptor_83c10c24ec417dc9, []int{114} } func (m *PersistentVolumeClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3216,7 +3272,7 @@ var xxx_messageInfo_PersistentVolumeClaimTemplate proto.InternalMessageInfo func (m *PersistentVolumeClaimVolumeSource) Reset() { *m = PersistentVolumeClaimVolumeSource{} } func (*PersistentVolumeClaimVolumeSource) ProtoMessage() {} func (*PersistentVolumeClaimVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{113} + return fileDescriptor_83c10c24ec417dc9, []int{115} } func (m *PersistentVolumeClaimVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3244,7 +3300,7 @@ var xxx_messageInfo_PersistentVolumeClaimVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeList) Reset() { *m = PersistentVolumeList{} } func (*PersistentVolumeList) ProtoMessage() {} func (*PersistentVolumeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{114} + return fileDescriptor_83c10c24ec417dc9, []int{116} } func (m *PersistentVolumeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3272,7 +3328,7 @@ var xxx_messageInfo_PersistentVolumeList proto.InternalMessageInfo func (m *PersistentVolumeSource) Reset() { *m = PersistentVolumeSource{} } func (*PersistentVolumeSource) ProtoMessage() {} func (*PersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{115} + return fileDescriptor_83c10c24ec417dc9, []int{117} } func (m *PersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3300,7 +3356,7 @@ var xxx_messageInfo_PersistentVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeSpec) Reset() { *m = PersistentVolumeSpec{} } func (*PersistentVolumeSpec) ProtoMessage() {} func (*PersistentVolumeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{116} + return fileDescriptor_83c10c24ec417dc9, []int{118} } func (m *PersistentVolumeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3328,7 +3384,7 @@ var xxx_messageInfo_PersistentVolumeSpec proto.InternalMessageInfo func (m *PersistentVolumeStatus) Reset() { *m = PersistentVolumeStatus{} } func (*PersistentVolumeStatus) ProtoMessage() {} func (*PersistentVolumeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{117} + return fileDescriptor_83c10c24ec417dc9, []int{119} } func (m *PersistentVolumeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3356,7 +3412,7 @@ var xxx_messageInfo_PersistentVolumeStatus proto.InternalMessageInfo func (m *PhotonPersistentDiskVolumeSource) Reset() { *m = PhotonPersistentDiskVolumeSource{} } func (*PhotonPersistentDiskVolumeSource) ProtoMessage() {} func (*PhotonPersistentDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{118} + return fileDescriptor_83c10c24ec417dc9, []int{120} } func (m *PhotonPersistentDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3384,7 +3440,7 @@ var xxx_messageInfo_PhotonPersistentDiskVolumeSource proto.InternalMessageInfo func (m *Pod) Reset() { *m = Pod{} } func (*Pod) ProtoMessage() {} func (*Pod) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{119} + return fileDescriptor_83c10c24ec417dc9, []int{121} } func (m *Pod) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3412,7 +3468,7 @@ var xxx_messageInfo_Pod proto.InternalMessageInfo func (m *PodAffinity) Reset() { *m = PodAffinity{} } func (*PodAffinity) ProtoMessage() {} func (*PodAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{120} + return fileDescriptor_83c10c24ec417dc9, []int{122} } func (m *PodAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3440,7 +3496,7 @@ var xxx_messageInfo_PodAffinity proto.InternalMessageInfo func (m *PodAffinityTerm) Reset() { *m = PodAffinityTerm{} } func (*PodAffinityTerm) ProtoMessage() {} func (*PodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{121} + return fileDescriptor_83c10c24ec417dc9, []int{123} } func (m *PodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3468,7 +3524,7 @@ var xxx_messageInfo_PodAffinityTerm proto.InternalMessageInfo func (m *PodAntiAffinity) Reset() { *m = PodAntiAffinity{} } func (*PodAntiAffinity) ProtoMessage() {} func (*PodAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{122} + return fileDescriptor_83c10c24ec417dc9, []int{124} } func (m *PodAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3496,7 +3552,7 @@ var xxx_messageInfo_PodAntiAffinity proto.InternalMessageInfo func (m *PodAttachOptions) Reset() { *m = PodAttachOptions{} } func (*PodAttachOptions) ProtoMessage() {} func (*PodAttachOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{123} + return fileDescriptor_83c10c24ec417dc9, []int{125} } func (m *PodAttachOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3524,7 +3580,7 @@ var xxx_messageInfo_PodAttachOptions proto.InternalMessageInfo func (m *PodCondition) Reset() { *m = PodCondition{} } func (*PodCondition) ProtoMessage() {} func (*PodCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{124} + return fileDescriptor_83c10c24ec417dc9, []int{126} } func (m *PodCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3552,7 +3608,7 @@ var xxx_messageInfo_PodCondition proto.InternalMessageInfo func (m *PodDNSConfig) Reset() { *m = PodDNSConfig{} } func (*PodDNSConfig) ProtoMessage() {} func (*PodDNSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{125} + return fileDescriptor_83c10c24ec417dc9, []int{127} } func (m *PodDNSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3580,7 +3636,7 @@ var xxx_messageInfo_PodDNSConfig proto.InternalMessageInfo func (m *PodDNSConfigOption) Reset() { *m = PodDNSConfigOption{} } func (*PodDNSConfigOption) ProtoMessage() {} func (*PodDNSConfigOption) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{126} + return fileDescriptor_83c10c24ec417dc9, []int{128} } func (m *PodDNSConfigOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3608,7 +3664,7 @@ var xxx_messageInfo_PodDNSConfigOption proto.InternalMessageInfo func (m *PodExecOptions) Reset() { *m = PodExecOptions{} } func (*PodExecOptions) ProtoMessage() {} func (*PodExecOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{127} + return fileDescriptor_83c10c24ec417dc9, []int{129} } func (m *PodExecOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3636,7 +3692,7 @@ var xxx_messageInfo_PodExecOptions proto.InternalMessageInfo func (m *PodIP) Reset() { *m = PodIP{} } func (*PodIP) ProtoMessage() {} func (*PodIP) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{128} + return fileDescriptor_83c10c24ec417dc9, []int{130} } func (m *PodIP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3664,7 +3720,7 @@ var xxx_messageInfo_PodIP proto.InternalMessageInfo func (m *PodList) Reset() { *m = PodList{} } func (*PodList) ProtoMessage() {} func (*PodList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{129} + return fileDescriptor_83c10c24ec417dc9, []int{131} } func (m *PodList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3692,7 +3748,7 @@ var xxx_messageInfo_PodList proto.InternalMessageInfo func (m *PodLogOptions) Reset() { *m = PodLogOptions{} } func (*PodLogOptions) ProtoMessage() {} func (*PodLogOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{130} + return fileDescriptor_83c10c24ec417dc9, []int{132} } func (m *PodLogOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3720,7 +3776,7 @@ var xxx_messageInfo_PodLogOptions proto.InternalMessageInfo func (m *PodOS) Reset() { *m = PodOS{} } func (*PodOS) ProtoMessage() {} func (*PodOS) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{131} + return fileDescriptor_83c10c24ec417dc9, []int{133} } func (m *PodOS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3748,7 +3804,7 @@ var xxx_messageInfo_PodOS proto.InternalMessageInfo func (m *PodPortForwardOptions) Reset() { *m = PodPortForwardOptions{} } func (*PodPortForwardOptions) ProtoMessage() {} func (*PodPortForwardOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{132} + return fileDescriptor_83c10c24ec417dc9, []int{134} } func (m *PodPortForwardOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3776,7 +3832,7 @@ var xxx_messageInfo_PodPortForwardOptions proto.InternalMessageInfo func (m *PodProxyOptions) Reset() { *m = PodProxyOptions{} } func (*PodProxyOptions) ProtoMessage() {} func (*PodProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{133} + return fileDescriptor_83c10c24ec417dc9, []int{135} } func (m *PodProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3804,7 +3860,7 @@ var xxx_messageInfo_PodProxyOptions proto.InternalMessageInfo func (m *PodReadinessGate) Reset() { *m = PodReadinessGate{} } func (*PodReadinessGate) ProtoMessage() {} func (*PodReadinessGate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{134} + return fileDescriptor_83c10c24ec417dc9, []int{136} } func (m *PodReadinessGate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3829,10 +3885,66 @@ func (m *PodReadinessGate) XXX_DiscardUnknown() { var xxx_messageInfo_PodReadinessGate proto.InternalMessageInfo +func (m *PodResourceClaim) Reset() { *m = PodResourceClaim{} } +func (*PodResourceClaim) ProtoMessage() {} +func (*PodResourceClaim) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{137} +} +func (m *PodResourceClaim) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodResourceClaim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodResourceClaim) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodResourceClaim.Merge(m, src) +} +func (m *PodResourceClaim) XXX_Size() int { + return m.Size() +} +func (m *PodResourceClaim) XXX_DiscardUnknown() { + xxx_messageInfo_PodResourceClaim.DiscardUnknown(m) +} + +var xxx_messageInfo_PodResourceClaim proto.InternalMessageInfo + +func (m *PodSchedulingGate) Reset() { *m = PodSchedulingGate{} } +func (*PodSchedulingGate) ProtoMessage() {} +func (*PodSchedulingGate) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{138} +} +func (m *PodSchedulingGate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodSchedulingGate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodSchedulingGate) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingGate.Merge(m, src) +} +func (m *PodSchedulingGate) XXX_Size() int { + return m.Size() +} +func (m *PodSchedulingGate) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingGate.DiscardUnknown(m) +} + +var xxx_messageInfo_PodSchedulingGate proto.InternalMessageInfo + func (m *PodSecurityContext) Reset() { *m = PodSecurityContext{} } func (*PodSecurityContext) ProtoMessage() {} func (*PodSecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{135} + return fileDescriptor_83c10c24ec417dc9, []int{139} } func (m *PodSecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3860,7 +3972,7 @@ var xxx_messageInfo_PodSecurityContext proto.InternalMessageInfo func (m *PodSignature) Reset() { *m = PodSignature{} } func (*PodSignature) ProtoMessage() {} func (*PodSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{136} + return fileDescriptor_83c10c24ec417dc9, []int{140} } func (m *PodSignature) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3888,7 +4000,7 @@ var xxx_messageInfo_PodSignature proto.InternalMessageInfo func (m *PodSpec) Reset() { *m = PodSpec{} } func (*PodSpec) ProtoMessage() {} func (*PodSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{137} + return fileDescriptor_83c10c24ec417dc9, []int{141} } func (m *PodSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3916,7 +4028,7 @@ var xxx_messageInfo_PodSpec proto.InternalMessageInfo func (m *PodStatus) Reset() { *m = PodStatus{} } func (*PodStatus) ProtoMessage() {} func (*PodStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{138} + return fileDescriptor_83c10c24ec417dc9, []int{142} } func (m *PodStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3944,7 +4056,7 @@ var xxx_messageInfo_PodStatus proto.InternalMessageInfo func (m *PodStatusResult) Reset() { *m = PodStatusResult{} } func (*PodStatusResult) ProtoMessage() {} func (*PodStatusResult) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{139} + return fileDescriptor_83c10c24ec417dc9, []int{143} } func (m *PodStatusResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3972,7 +4084,7 @@ var xxx_messageInfo_PodStatusResult proto.InternalMessageInfo func (m *PodTemplate) Reset() { *m = PodTemplate{} } func (*PodTemplate) ProtoMessage() {} func (*PodTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{140} + return fileDescriptor_83c10c24ec417dc9, []int{144} } func (m *PodTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4000,7 +4112,7 @@ var xxx_messageInfo_PodTemplate proto.InternalMessageInfo func (m *PodTemplateList) Reset() { *m = PodTemplateList{} } func (*PodTemplateList) ProtoMessage() {} func (*PodTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{141} + return fileDescriptor_83c10c24ec417dc9, []int{145} } func (m *PodTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4028,7 +4140,7 @@ var xxx_messageInfo_PodTemplateList proto.InternalMessageInfo func (m *PodTemplateSpec) Reset() { *m = PodTemplateSpec{} } func (*PodTemplateSpec) ProtoMessage() {} func (*PodTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{142} + return fileDescriptor_83c10c24ec417dc9, []int{146} } func (m *PodTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4056,7 +4168,7 @@ var xxx_messageInfo_PodTemplateSpec proto.InternalMessageInfo func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} func (*PortStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{143} + return fileDescriptor_83c10c24ec417dc9, []int{147} } func (m *PortStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4084,7 +4196,7 @@ var xxx_messageInfo_PortStatus proto.InternalMessageInfo func (m *PortworxVolumeSource) Reset() { *m = PortworxVolumeSource{} } func (*PortworxVolumeSource) ProtoMessage() {} func (*PortworxVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{144} + return fileDescriptor_83c10c24ec417dc9, []int{148} } func (m *PortworxVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4112,7 +4224,7 @@ var xxx_messageInfo_PortworxVolumeSource proto.InternalMessageInfo func (m *Preconditions) Reset() { *m = Preconditions{} } func (*Preconditions) ProtoMessage() {} func (*Preconditions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{145} + return fileDescriptor_83c10c24ec417dc9, []int{149} } func (m *Preconditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4140,7 +4252,7 @@ var xxx_messageInfo_Preconditions proto.InternalMessageInfo func (m *PreferAvoidPodsEntry) Reset() { *m = PreferAvoidPodsEntry{} } func (*PreferAvoidPodsEntry) ProtoMessage() {} func (*PreferAvoidPodsEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{146} + return fileDescriptor_83c10c24ec417dc9, []int{150} } func (m *PreferAvoidPodsEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4168,7 +4280,7 @@ var xxx_messageInfo_PreferAvoidPodsEntry proto.InternalMessageInfo func (m *PreferredSchedulingTerm) Reset() { *m = PreferredSchedulingTerm{} } func (*PreferredSchedulingTerm) ProtoMessage() {} func (*PreferredSchedulingTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{147} + return fileDescriptor_83c10c24ec417dc9, []int{151} } func (m *PreferredSchedulingTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4196,7 +4308,7 @@ var xxx_messageInfo_PreferredSchedulingTerm proto.InternalMessageInfo func (m *Probe) Reset() { *m = Probe{} } func (*Probe) ProtoMessage() {} func (*Probe) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{148} + return fileDescriptor_83c10c24ec417dc9, []int{152} } func (m *Probe) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4224,7 +4336,7 @@ var xxx_messageInfo_Probe proto.InternalMessageInfo func (m *ProbeHandler) Reset() { *m = ProbeHandler{} } func (*ProbeHandler) ProtoMessage() {} func (*ProbeHandler) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{149} + return fileDescriptor_83c10c24ec417dc9, []int{153} } func (m *ProbeHandler) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4252,7 +4364,7 @@ var xxx_messageInfo_ProbeHandler proto.InternalMessageInfo func (m *ProjectedVolumeSource) Reset() { *m = ProjectedVolumeSource{} } func (*ProjectedVolumeSource) ProtoMessage() {} func (*ProjectedVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{150} + return fileDescriptor_83c10c24ec417dc9, []int{154} } func (m *ProjectedVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4280,7 +4392,7 @@ var xxx_messageInfo_ProjectedVolumeSource proto.InternalMessageInfo func (m *QuobyteVolumeSource) Reset() { *m = QuobyteVolumeSource{} } func (*QuobyteVolumeSource) ProtoMessage() {} func (*QuobyteVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{151} + return fileDescriptor_83c10c24ec417dc9, []int{155} } func (m *QuobyteVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4308,7 +4420,7 @@ var xxx_messageInfo_QuobyteVolumeSource proto.InternalMessageInfo func (m *RBDPersistentVolumeSource) Reset() { *m = RBDPersistentVolumeSource{} } func (*RBDPersistentVolumeSource) ProtoMessage() {} func (*RBDPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{152} + return fileDescriptor_83c10c24ec417dc9, []int{156} } func (m *RBDPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4336,7 +4448,7 @@ var xxx_messageInfo_RBDPersistentVolumeSource proto.InternalMessageInfo func (m *RBDVolumeSource) Reset() { *m = RBDVolumeSource{} } func (*RBDVolumeSource) ProtoMessage() {} func (*RBDVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{153} + return fileDescriptor_83c10c24ec417dc9, []int{157} } func (m *RBDVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4364,7 +4476,7 @@ var xxx_messageInfo_RBDVolumeSource proto.InternalMessageInfo func (m *RangeAllocation) Reset() { *m = RangeAllocation{} } func (*RangeAllocation) ProtoMessage() {} func (*RangeAllocation) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{154} + return fileDescriptor_83c10c24ec417dc9, []int{158} } func (m *RangeAllocation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4392,7 +4504,7 @@ var xxx_messageInfo_RangeAllocation proto.InternalMessageInfo func (m *ReplicationController) Reset() { *m = ReplicationController{} } func (*ReplicationController) ProtoMessage() {} func (*ReplicationController) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{155} + return fileDescriptor_83c10c24ec417dc9, []int{159} } func (m *ReplicationController) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4420,7 +4532,7 @@ var xxx_messageInfo_ReplicationController proto.InternalMessageInfo func (m *ReplicationControllerCondition) Reset() { *m = ReplicationControllerCondition{} } func (*ReplicationControllerCondition) ProtoMessage() {} func (*ReplicationControllerCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{156} + return fileDescriptor_83c10c24ec417dc9, []int{160} } func (m *ReplicationControllerCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4448,7 +4560,7 @@ var xxx_messageInfo_ReplicationControllerCondition proto.InternalMessageInfo func (m *ReplicationControllerList) Reset() { *m = ReplicationControllerList{} } func (*ReplicationControllerList) ProtoMessage() {} func (*ReplicationControllerList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{157} + return fileDescriptor_83c10c24ec417dc9, []int{161} } func (m *ReplicationControllerList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4476,7 +4588,7 @@ var xxx_messageInfo_ReplicationControllerList proto.InternalMessageInfo func (m *ReplicationControllerSpec) Reset() { *m = ReplicationControllerSpec{} } func (*ReplicationControllerSpec) ProtoMessage() {} func (*ReplicationControllerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{158} + return fileDescriptor_83c10c24ec417dc9, []int{162} } func (m *ReplicationControllerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4504,7 +4616,7 @@ var xxx_messageInfo_ReplicationControllerSpec proto.InternalMessageInfo func (m *ReplicationControllerStatus) Reset() { *m = ReplicationControllerStatus{} } func (*ReplicationControllerStatus) ProtoMessage() {} func (*ReplicationControllerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{159} + return fileDescriptor_83c10c24ec417dc9, []int{163} } func (m *ReplicationControllerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4529,10 +4641,38 @@ func (m *ReplicationControllerStatus) XXX_DiscardUnknown() { var xxx_messageInfo_ReplicationControllerStatus proto.InternalMessageInfo +func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } +func (*ResourceClaim) ProtoMessage() {} +func (*ResourceClaim) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{164} +} +func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaim) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaim.Merge(m, src) +} +func (m *ResourceClaim) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaim) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaim.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo + func (m *ResourceFieldSelector) Reset() { *m = ResourceFieldSelector{} } func (*ResourceFieldSelector) ProtoMessage() {} func (*ResourceFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{160} + return fileDescriptor_83c10c24ec417dc9, []int{165} } func (m *ResourceFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4560,7 +4700,7 @@ var xxx_messageInfo_ResourceFieldSelector proto.InternalMessageInfo func (m *ResourceQuota) Reset() { *m = ResourceQuota{} } func (*ResourceQuota) ProtoMessage() {} func (*ResourceQuota) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{161} + return fileDescriptor_83c10c24ec417dc9, []int{166} } func (m *ResourceQuota) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4588,7 +4728,7 @@ var xxx_messageInfo_ResourceQuota proto.InternalMessageInfo func (m *ResourceQuotaList) Reset() { *m = ResourceQuotaList{} } func (*ResourceQuotaList) ProtoMessage() {} func (*ResourceQuotaList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{162} + return fileDescriptor_83c10c24ec417dc9, []int{167} } func (m *ResourceQuotaList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4616,7 +4756,7 @@ var xxx_messageInfo_ResourceQuotaList proto.InternalMessageInfo func (m *ResourceQuotaSpec) Reset() { *m = ResourceQuotaSpec{} } func (*ResourceQuotaSpec) ProtoMessage() {} func (*ResourceQuotaSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{163} + return fileDescriptor_83c10c24ec417dc9, []int{168} } func (m *ResourceQuotaSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4644,7 +4784,7 @@ var xxx_messageInfo_ResourceQuotaSpec proto.InternalMessageInfo func (m *ResourceQuotaStatus) Reset() { *m = ResourceQuotaStatus{} } func (*ResourceQuotaStatus) ProtoMessage() {} func (*ResourceQuotaStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{164} + return fileDescriptor_83c10c24ec417dc9, []int{169} } func (m *ResourceQuotaStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4672,7 +4812,7 @@ var xxx_messageInfo_ResourceQuotaStatus proto.InternalMessageInfo func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{165} + return fileDescriptor_83c10c24ec417dc9, []int{170} } func (m *ResourceRequirements) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4700,7 +4840,7 @@ var xxx_messageInfo_ResourceRequirements proto.InternalMessageInfo func (m *SELinuxOptions) Reset() { *m = SELinuxOptions{} } func (*SELinuxOptions) ProtoMessage() {} func (*SELinuxOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{166} + return fileDescriptor_83c10c24ec417dc9, []int{171} } func (m *SELinuxOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4728,7 +4868,7 @@ var xxx_messageInfo_SELinuxOptions proto.InternalMessageInfo func (m *ScaleIOPersistentVolumeSource) Reset() { *m = ScaleIOPersistentVolumeSource{} } func (*ScaleIOPersistentVolumeSource) ProtoMessage() {} func (*ScaleIOPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{167} + return fileDescriptor_83c10c24ec417dc9, []int{172} } func (m *ScaleIOPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4756,7 +4896,7 @@ var xxx_messageInfo_ScaleIOPersistentVolumeSource proto.InternalMessageInfo func (m *ScaleIOVolumeSource) Reset() { *m = ScaleIOVolumeSource{} } func (*ScaleIOVolumeSource) ProtoMessage() {} func (*ScaleIOVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{168} + return fileDescriptor_83c10c24ec417dc9, []int{173} } func (m *ScaleIOVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4784,7 +4924,7 @@ var xxx_messageInfo_ScaleIOVolumeSource proto.InternalMessageInfo func (m *ScopeSelector) Reset() { *m = ScopeSelector{} } func (*ScopeSelector) ProtoMessage() {} func (*ScopeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{169} + return fileDescriptor_83c10c24ec417dc9, []int{174} } func (m *ScopeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4812,7 +4952,7 @@ var xxx_messageInfo_ScopeSelector proto.InternalMessageInfo func (m *ScopedResourceSelectorRequirement) Reset() { *m = ScopedResourceSelectorRequirement{} } func (*ScopedResourceSelectorRequirement) ProtoMessage() {} func (*ScopedResourceSelectorRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{170} + return fileDescriptor_83c10c24ec417dc9, []int{175} } func (m *ScopedResourceSelectorRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4840,7 +4980,7 @@ var xxx_messageInfo_ScopedResourceSelectorRequirement proto.InternalMessageInfo func (m *SeccompProfile) Reset() { *m = SeccompProfile{} } func (*SeccompProfile) ProtoMessage() {} func (*SeccompProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{171} + return fileDescriptor_83c10c24ec417dc9, []int{176} } func (m *SeccompProfile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4868,7 +5008,7 @@ var xxx_messageInfo_SeccompProfile proto.InternalMessageInfo func (m *Secret) Reset() { *m = Secret{} } func (*Secret) ProtoMessage() {} func (*Secret) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{172} + return fileDescriptor_83c10c24ec417dc9, []int{177} } func (m *Secret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4896,7 +5036,7 @@ var xxx_messageInfo_Secret proto.InternalMessageInfo func (m *SecretEnvSource) Reset() { *m = SecretEnvSource{} } func (*SecretEnvSource) ProtoMessage() {} func (*SecretEnvSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{173} + return fileDescriptor_83c10c24ec417dc9, []int{178} } func (m *SecretEnvSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4924,7 +5064,7 @@ var xxx_messageInfo_SecretEnvSource proto.InternalMessageInfo func (m *SecretKeySelector) Reset() { *m = SecretKeySelector{} } func (*SecretKeySelector) ProtoMessage() {} func (*SecretKeySelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{174} + return fileDescriptor_83c10c24ec417dc9, []int{179} } func (m *SecretKeySelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4952,7 +5092,7 @@ var xxx_messageInfo_SecretKeySelector proto.InternalMessageInfo func (m *SecretList) Reset() { *m = SecretList{} } func (*SecretList) ProtoMessage() {} func (*SecretList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{175} + return fileDescriptor_83c10c24ec417dc9, []int{180} } func (m *SecretList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4980,7 +5120,7 @@ var xxx_messageInfo_SecretList proto.InternalMessageInfo func (m *SecretProjection) Reset() { *m = SecretProjection{} } func (*SecretProjection) ProtoMessage() {} func (*SecretProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{176} + return fileDescriptor_83c10c24ec417dc9, []int{181} } func (m *SecretProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5008,7 +5148,7 @@ var xxx_messageInfo_SecretProjection proto.InternalMessageInfo func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} func (*SecretReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{177} + return fileDescriptor_83c10c24ec417dc9, []int{182} } func (m *SecretReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5036,7 +5176,7 @@ var xxx_messageInfo_SecretReference proto.InternalMessageInfo func (m *SecretVolumeSource) Reset() { *m = SecretVolumeSource{} } func (*SecretVolumeSource) ProtoMessage() {} func (*SecretVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{178} + return fileDescriptor_83c10c24ec417dc9, []int{183} } func (m *SecretVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5064,7 +5204,7 @@ var xxx_messageInfo_SecretVolumeSource proto.InternalMessageInfo func (m *SecurityContext) Reset() { *m = SecurityContext{} } func (*SecurityContext) ProtoMessage() {} func (*SecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{179} + return fileDescriptor_83c10c24ec417dc9, []int{184} } func (m *SecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5092,7 +5232,7 @@ var xxx_messageInfo_SecurityContext proto.InternalMessageInfo func (m *SerializedReference) Reset() { *m = SerializedReference{} } func (*SerializedReference) ProtoMessage() {} func (*SerializedReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{180} + return fileDescriptor_83c10c24ec417dc9, []int{185} } func (m *SerializedReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5120,7 +5260,7 @@ var xxx_messageInfo_SerializedReference proto.InternalMessageInfo func (m *Service) Reset() { *m = Service{} } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{181} + return fileDescriptor_83c10c24ec417dc9, []int{186} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5148,7 +5288,7 @@ var xxx_messageInfo_Service proto.InternalMessageInfo func (m *ServiceAccount) Reset() { *m = ServiceAccount{} } func (*ServiceAccount) ProtoMessage() {} func (*ServiceAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{182} + return fileDescriptor_83c10c24ec417dc9, []int{187} } func (m *ServiceAccount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5176,7 +5316,7 @@ var xxx_messageInfo_ServiceAccount proto.InternalMessageInfo func (m *ServiceAccountList) Reset() { *m = ServiceAccountList{} } func (*ServiceAccountList) ProtoMessage() {} func (*ServiceAccountList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{183} + return fileDescriptor_83c10c24ec417dc9, []int{188} } func (m *ServiceAccountList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5204,7 +5344,7 @@ var xxx_messageInfo_ServiceAccountList proto.InternalMessageInfo func (m *ServiceAccountTokenProjection) Reset() { *m = ServiceAccountTokenProjection{} } func (*ServiceAccountTokenProjection) ProtoMessage() {} func (*ServiceAccountTokenProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{184} + return fileDescriptor_83c10c24ec417dc9, []int{189} } func (m *ServiceAccountTokenProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5232,7 +5372,7 @@ var xxx_messageInfo_ServiceAccountTokenProjection proto.InternalMessageInfo func (m *ServiceList) Reset() { *m = ServiceList{} } func (*ServiceList) ProtoMessage() {} func (*ServiceList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{185} + return fileDescriptor_83c10c24ec417dc9, []int{190} } func (m *ServiceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5260,7 +5400,7 @@ var xxx_messageInfo_ServiceList proto.InternalMessageInfo func (m *ServicePort) Reset() { *m = ServicePort{} } func (*ServicePort) ProtoMessage() {} func (*ServicePort) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{186} + return fileDescriptor_83c10c24ec417dc9, []int{191} } func (m *ServicePort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5288,7 +5428,7 @@ var xxx_messageInfo_ServicePort proto.InternalMessageInfo func (m *ServiceProxyOptions) Reset() { *m = ServiceProxyOptions{} } func (*ServiceProxyOptions) ProtoMessage() {} func (*ServiceProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{187} + return fileDescriptor_83c10c24ec417dc9, []int{192} } func (m *ServiceProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5316,7 +5456,7 @@ var xxx_messageInfo_ServiceProxyOptions proto.InternalMessageInfo func (m *ServiceSpec) Reset() { *m = ServiceSpec{} } func (*ServiceSpec) ProtoMessage() {} func (*ServiceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{188} + return fileDescriptor_83c10c24ec417dc9, []int{193} } func (m *ServiceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5344,7 +5484,7 @@ var xxx_messageInfo_ServiceSpec proto.InternalMessageInfo func (m *ServiceStatus) Reset() { *m = ServiceStatus{} } func (*ServiceStatus) ProtoMessage() {} func (*ServiceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{189} + return fileDescriptor_83c10c24ec417dc9, []int{194} } func (m *ServiceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5372,7 +5512,7 @@ var xxx_messageInfo_ServiceStatus proto.InternalMessageInfo func (m *SessionAffinityConfig) Reset() { *m = SessionAffinityConfig{} } func (*SessionAffinityConfig) ProtoMessage() {} func (*SessionAffinityConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{190} + return fileDescriptor_83c10c24ec417dc9, []int{195} } func (m *SessionAffinityConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5400,7 +5540,7 @@ var xxx_messageInfo_SessionAffinityConfig proto.InternalMessageInfo func (m *StorageOSPersistentVolumeSource) Reset() { *m = StorageOSPersistentVolumeSource{} } func (*StorageOSPersistentVolumeSource) ProtoMessage() {} func (*StorageOSPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{191} + return fileDescriptor_83c10c24ec417dc9, []int{196} } func (m *StorageOSPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5428,7 +5568,7 @@ var xxx_messageInfo_StorageOSPersistentVolumeSource proto.InternalMessageInfo func (m *StorageOSVolumeSource) Reset() { *m = StorageOSVolumeSource{} } func (*StorageOSVolumeSource) ProtoMessage() {} func (*StorageOSVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{192} + return fileDescriptor_83c10c24ec417dc9, []int{197} } func (m *StorageOSVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5456,7 +5596,7 @@ var xxx_messageInfo_StorageOSVolumeSource proto.InternalMessageInfo func (m *Sysctl) Reset() { *m = Sysctl{} } func (*Sysctl) ProtoMessage() {} func (*Sysctl) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{193} + return fileDescriptor_83c10c24ec417dc9, []int{198} } func (m *Sysctl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5484,7 +5624,7 @@ var xxx_messageInfo_Sysctl proto.InternalMessageInfo func (m *TCPSocketAction) Reset() { *m = TCPSocketAction{} } func (*TCPSocketAction) ProtoMessage() {} func (*TCPSocketAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{194} + return fileDescriptor_83c10c24ec417dc9, []int{199} } func (m *TCPSocketAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5512,7 +5652,7 @@ var xxx_messageInfo_TCPSocketAction proto.InternalMessageInfo func (m *Taint) Reset() { *m = Taint{} } func (*Taint) ProtoMessage() {} func (*Taint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{195} + return fileDescriptor_83c10c24ec417dc9, []int{200} } func (m *Taint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5540,7 +5680,7 @@ var xxx_messageInfo_Taint proto.InternalMessageInfo func (m *Toleration) Reset() { *m = Toleration{} } func (*Toleration) ProtoMessage() {} func (*Toleration) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{196} + return fileDescriptor_83c10c24ec417dc9, []int{201} } func (m *Toleration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5568,7 +5708,7 @@ var xxx_messageInfo_Toleration proto.InternalMessageInfo func (m *TopologySelectorLabelRequirement) Reset() { *m = TopologySelectorLabelRequirement{} } func (*TopologySelectorLabelRequirement) ProtoMessage() {} func (*TopologySelectorLabelRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{197} + return fileDescriptor_83c10c24ec417dc9, []int{202} } func (m *TopologySelectorLabelRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5596,7 +5736,7 @@ var xxx_messageInfo_TopologySelectorLabelRequirement proto.InternalMessageInfo func (m *TopologySelectorTerm) Reset() { *m = TopologySelectorTerm{} } func (*TopologySelectorTerm) ProtoMessage() {} func (*TopologySelectorTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{198} + return fileDescriptor_83c10c24ec417dc9, []int{203} } func (m *TopologySelectorTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5624,7 +5764,7 @@ var xxx_messageInfo_TopologySelectorTerm proto.InternalMessageInfo func (m *TopologySpreadConstraint) Reset() { *m = TopologySpreadConstraint{} } func (*TopologySpreadConstraint) ProtoMessage() {} func (*TopologySpreadConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{199} + return fileDescriptor_83c10c24ec417dc9, []int{204} } func (m *TopologySpreadConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5652,7 +5792,7 @@ var xxx_messageInfo_TopologySpreadConstraint proto.InternalMessageInfo func (m *TypedLocalObjectReference) Reset() { *m = TypedLocalObjectReference{} } func (*TypedLocalObjectReference) ProtoMessage() {} func (*TypedLocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{200} + return fileDescriptor_83c10c24ec417dc9, []int{205} } func (m *TypedLocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5677,10 +5817,38 @@ func (m *TypedLocalObjectReference) XXX_DiscardUnknown() { var xxx_messageInfo_TypedLocalObjectReference proto.InternalMessageInfo +func (m *TypedObjectReference) Reset() { *m = TypedObjectReference{} } +func (*TypedObjectReference) ProtoMessage() {} +func (*TypedObjectReference) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{206} +} +func (m *TypedObjectReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TypedObjectReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *TypedObjectReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_TypedObjectReference.Merge(m, src) +} +func (m *TypedObjectReference) XXX_Size() int { + return m.Size() +} +func (m *TypedObjectReference) XXX_DiscardUnknown() { + xxx_messageInfo_TypedObjectReference.DiscardUnknown(m) +} + +var xxx_messageInfo_TypedObjectReference proto.InternalMessageInfo + func (m *Volume) Reset() { *m = Volume{} } func (*Volume) ProtoMessage() {} func (*Volume) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{201} + return fileDescriptor_83c10c24ec417dc9, []int{207} } func (m *Volume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5708,7 +5876,7 @@ var xxx_messageInfo_Volume proto.InternalMessageInfo func (m *VolumeDevice) Reset() { *m = VolumeDevice{} } func (*VolumeDevice) ProtoMessage() {} func (*VolumeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{202} + return fileDescriptor_83c10c24ec417dc9, []int{208} } func (m *VolumeDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5736,7 +5904,7 @@ var xxx_messageInfo_VolumeDevice proto.InternalMessageInfo func (m *VolumeMount) Reset() { *m = VolumeMount{} } func (*VolumeMount) ProtoMessage() {} func (*VolumeMount) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{203} + return fileDescriptor_83c10c24ec417dc9, []int{209} } func (m *VolumeMount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5764,7 +5932,7 @@ var xxx_messageInfo_VolumeMount proto.InternalMessageInfo func (m *VolumeNodeAffinity) Reset() { *m = VolumeNodeAffinity{} } func (*VolumeNodeAffinity) ProtoMessage() {} func (*VolumeNodeAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{204} + return fileDescriptor_83c10c24ec417dc9, []int{210} } func (m *VolumeNodeAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5792,7 +5960,7 @@ var xxx_messageInfo_VolumeNodeAffinity proto.InternalMessageInfo func (m *VolumeProjection) Reset() { *m = VolumeProjection{} } func (*VolumeProjection) ProtoMessage() {} func (*VolumeProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{205} + return fileDescriptor_83c10c24ec417dc9, []int{211} } func (m *VolumeProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5820,7 +5988,7 @@ var xxx_messageInfo_VolumeProjection proto.InternalMessageInfo func (m *VolumeSource) Reset() { *m = VolumeSource{} } func (*VolumeSource) ProtoMessage() {} func (*VolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{206} + return fileDescriptor_83c10c24ec417dc9, []int{212} } func (m *VolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5848,7 +6016,7 @@ var xxx_messageInfo_VolumeSource proto.InternalMessageInfo func (m *VsphereVirtualDiskVolumeSource) Reset() { *m = VsphereVirtualDiskVolumeSource{} } func (*VsphereVirtualDiskVolumeSource) ProtoMessage() {} func (*VsphereVirtualDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{207} + return fileDescriptor_83c10c24ec417dc9, []int{213} } func (m *VsphereVirtualDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5876,7 +6044,7 @@ var xxx_messageInfo_VsphereVirtualDiskVolumeSource proto.InternalMessageInfo func (m *WeightedPodAffinityTerm) Reset() { *m = WeightedPodAffinityTerm{} } func (*WeightedPodAffinityTerm) ProtoMessage() {} func (*WeightedPodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{208} + return fileDescriptor_83c10c24ec417dc9, []int{214} } func (m *WeightedPodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5904,7 +6072,7 @@ var xxx_messageInfo_WeightedPodAffinityTerm proto.InternalMessageInfo func (m *WindowsSecurityContextOptions) Reset() { *m = WindowsSecurityContextOptions{} } func (*WindowsSecurityContextOptions) ProtoMessage() {} func (*WindowsSecurityContextOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{209} + return fileDescriptor_83c10c24ec417dc9, []int{215} } func (m *WindowsSecurityContextOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5947,6 +6115,7 @@ func init() { proto.RegisterType((*CephFSVolumeSource)(nil), "k8s.io.api.core.v1.CephFSVolumeSource") proto.RegisterType((*CinderPersistentVolumeSource)(nil), "k8s.io.api.core.v1.CinderPersistentVolumeSource") proto.RegisterType((*CinderVolumeSource)(nil), "k8s.io.api.core.v1.CinderVolumeSource") + proto.RegisterType((*ClaimSource)(nil), "k8s.io.api.core.v1.ClaimSource") proto.RegisterType((*ClientIPConfig)(nil), "k8s.io.api.core.v1.ClientIPConfig") proto.RegisterType((*ComponentCondition)(nil), "k8s.io.api.core.v1.ComponentCondition") proto.RegisterType((*ComponentStatus)(nil), "k8s.io.api.core.v1.ComponentStatus") @@ -5963,11 +6132,13 @@ func init() { proto.RegisterType((*Container)(nil), "k8s.io.api.core.v1.Container") proto.RegisterType((*ContainerImage)(nil), "k8s.io.api.core.v1.ContainerImage") proto.RegisterType((*ContainerPort)(nil), "k8s.io.api.core.v1.ContainerPort") + proto.RegisterType((*ContainerResizePolicy)(nil), "k8s.io.api.core.v1.ContainerResizePolicy") proto.RegisterType((*ContainerState)(nil), "k8s.io.api.core.v1.ContainerState") proto.RegisterType((*ContainerStateRunning)(nil), "k8s.io.api.core.v1.ContainerStateRunning") proto.RegisterType((*ContainerStateTerminated)(nil), "k8s.io.api.core.v1.ContainerStateTerminated") proto.RegisterType((*ContainerStateWaiting)(nil), "k8s.io.api.core.v1.ContainerStateWaiting") proto.RegisterType((*ContainerStatus)(nil), "k8s.io.api.core.v1.ContainerStatus") + proto.RegisterMapType((ResourceList)(nil), "k8s.io.api.core.v1.ContainerStatus.AllocatedResourcesEntry") proto.RegisterType((*DaemonEndpoint)(nil), "k8s.io.api.core.v1.DaemonEndpoint") proto.RegisterType((*DownwardAPIProjection)(nil), "k8s.io.api.core.v1.DownwardAPIProjection") proto.RegisterType((*DownwardAPIVolumeFile)(nil), "k8s.io.api.core.v1.DownwardAPIVolumeFile") @@ -6082,6 +6253,8 @@ func init() { proto.RegisterType((*PodPortForwardOptions)(nil), "k8s.io.api.core.v1.PodPortForwardOptions") proto.RegisterType((*PodProxyOptions)(nil), "k8s.io.api.core.v1.PodProxyOptions") proto.RegisterType((*PodReadinessGate)(nil), "k8s.io.api.core.v1.PodReadinessGate") + proto.RegisterType((*PodResourceClaim)(nil), "k8s.io.api.core.v1.PodResourceClaim") + proto.RegisterType((*PodSchedulingGate)(nil), "k8s.io.api.core.v1.PodSchedulingGate") proto.RegisterType((*PodSecurityContext)(nil), "k8s.io.api.core.v1.PodSecurityContext") proto.RegisterType((*PodSignature)(nil), "k8s.io.api.core.v1.PodSignature") proto.RegisterType((*PodSpec)(nil), "k8s.io.api.core.v1.PodSpec") @@ -6110,6 +6283,7 @@ func init() { proto.RegisterType((*ReplicationControllerSpec)(nil), "k8s.io.api.core.v1.ReplicationControllerSpec") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.core.v1.ReplicationControllerSpec.SelectorEntry") proto.RegisterType((*ReplicationControllerStatus)(nil), "k8s.io.api.core.v1.ReplicationControllerStatus") + proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.core.v1.ResourceClaim") proto.RegisterType((*ResourceFieldSelector)(nil), "k8s.io.api.core.v1.ResourceFieldSelector") proto.RegisterType((*ResourceQuota)(nil), "k8s.io.api.core.v1.ResourceQuota") proto.RegisterType((*ResourceQuotaList)(nil), "k8s.io.api.core.v1.ResourceQuotaList") @@ -6159,6 +6333,7 @@ func init() { proto.RegisterType((*TopologySelectorTerm)(nil), "k8s.io.api.core.v1.TopologySelectorTerm") proto.RegisterType((*TopologySpreadConstraint)(nil), "k8s.io.api.core.v1.TopologySpreadConstraint") proto.RegisterType((*TypedLocalObjectReference)(nil), "k8s.io.api.core.v1.TypedLocalObjectReference") + proto.RegisterType((*TypedObjectReference)(nil), "k8s.io.api.core.v1.TypedObjectReference") proto.RegisterType((*Volume)(nil), "k8s.io.api.core.v1.Volume") proto.RegisterType((*VolumeDevice)(nil), "k8s.io.api.core.v1.VolumeDevice") proto.RegisterType((*VolumeMount)(nil), "k8s.io.api.core.v1.VolumeMount") @@ -6175,899 +6350,925 @@ func init() { } var fileDescriptor_83c10c24ec417dc9 = []byte{ - // 14260 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x69, 0x70, 0x24, 0xd7, - 0x79, 0x98, 0x7a, 0x06, 0xd7, 0x7c, 0xb8, 0xdf, 0x1e, 0xc4, 0x82, 0xdc, 0xc5, 0xb2, 0x29, 0x2d, - 0x97, 0x22, 0x89, 0xd5, 0xf2, 0x90, 0x68, 0x52, 0xa2, 0x05, 0x60, 0x80, 0x5d, 0x70, 0x17, 0xd8, - 0xe1, 0x1b, 0xec, 0xae, 0x24, 0x53, 0x2a, 0x35, 0x66, 0x1e, 0x80, 0x16, 0x66, 0xba, 0x87, 0xdd, - 0x3d, 0xd8, 0x05, 0x23, 0x57, 0x1c, 0xf9, 0x94, 0x8f, 0x94, 0x2a, 0xe5, 0x1c, 0x25, 0xbb, 0x5c, - 0x29, 0xc7, 0x89, 0xad, 0x28, 0x97, 0x23, 0xc7, 0x76, 0x2c, 0x27, 0x76, 0x6e, 0x27, 0x3f, 0x6c, - 0xc7, 0x55, 0xb1, 0x5c, 0xe5, 0x0a, 0x62, 0xaf, 0x53, 0xe5, 0x52, 0x55, 0x62, 0x3b, 0x71, 0xf2, - 0x23, 0x1b, 0x57, 0x9c, 0x7a, 0x67, 0xbf, 0xd7, 0xd7, 0x0c, 0x96, 0x58, 0x88, 0x52, 0xf1, 0xdf, - 0xcc, 0xfb, 0xbe, 0xf7, 0xbd, 0xd7, 0xef, 0xfc, 0xde, 0x77, 0xc2, 0x2b, 0xbb, 0x2f, 0x85, 0xf3, - 0xae, 0x7f, 0x69, 0xb7, 0xbb, 0x49, 0x02, 0x8f, 0x44, 0x24, 0xbc, 0xb4, 0x47, 0xbc, 0xa6, 0x1f, - 0x5c, 0x12, 0x00, 0xa7, 0xe3, 0x5e, 0x6a, 0xf8, 0x01, 0xb9, 0xb4, 0x77, 0xf9, 0xd2, 0x36, 0xf1, - 0x48, 0xe0, 0x44, 0xa4, 0x39, 0xdf, 0x09, 0xfc, 0xc8, 0x47, 0x88, 0xe3, 0xcc, 0x3b, 0x1d, 0x77, - 0x9e, 0xe2, 0xcc, 0xef, 0x5d, 0x9e, 0x7d, 0x76, 0xdb, 0x8d, 0x76, 0xba, 0x9b, 0xf3, 0x0d, 0xbf, - 0x7d, 0x69, 0xdb, 0xdf, 0xf6, 0x2f, 0x31, 0xd4, 0xcd, 0xee, 0x16, 0xfb, 0xc7, 0xfe, 0xb0, 0x5f, - 0x9c, 0xc4, 0xec, 0x0b, 0x71, 0x33, 0x6d, 0xa7, 0xb1, 0xe3, 0x7a, 0x24, 0xd8, 0xbf, 0xd4, 0xd9, - 0xdd, 0x66, 0xed, 0x06, 0x24, 0xf4, 0xbb, 0x41, 0x83, 0x24, 0x1b, 0x2e, 0xac, 0x15, 0x5e, 0x6a, - 0x93, 0xc8, 0xc9, 0xe8, 0xee, 0xec, 0xa5, 0xbc, 0x5a, 0x41, 0xd7, 0x8b, 0xdc, 0x76, 0xba, 0x99, - 0x0f, 0xf6, 0xaa, 0x10, 0x36, 0x76, 0x48, 0xdb, 0x49, 0xd5, 0x7b, 0x3e, 0xaf, 0x5e, 0x37, 0x72, - 0x5b, 0x97, 0x5c, 0x2f, 0x0a, 0xa3, 0x20, 0x59, 0xc9, 0xfe, 0x9a, 0x05, 0xe7, 0x17, 0x6e, 0xd7, - 0x97, 0x5b, 0x4e, 0x18, 0xb9, 0x8d, 0xc5, 0x96, 0xdf, 0xd8, 0xad, 0x47, 0x7e, 0x40, 0x6e, 0xf9, - 0xad, 0x6e, 0x9b, 0xd4, 0xd9, 0x40, 0xa0, 0x67, 0x60, 0x64, 0x8f, 0xfd, 0x5f, 0xad, 0xce, 0x58, - 0xe7, 0xad, 0x8b, 0x95, 0xc5, 0xa9, 0x5f, 0x3b, 0x98, 0x7b, 0xcf, 0xbd, 0x83, 0xb9, 0x91, 0x5b, - 0xa2, 0x1c, 0x2b, 0x0c, 0x74, 0x01, 0x86, 0xb6, 0xc2, 0x8d, 0xfd, 0x0e, 0x99, 0x29, 0x31, 0xdc, - 0x09, 0x81, 0x3b, 0xb4, 0x52, 0xa7, 0xa5, 0x58, 0x40, 0xd1, 0x25, 0xa8, 0x74, 0x9c, 0x20, 0x72, - 0x23, 0xd7, 0xf7, 0x66, 0xca, 0xe7, 0xad, 0x8b, 0x83, 0x8b, 0xd3, 0x02, 0xb5, 0x52, 0x93, 0x00, - 0x1c, 0xe3, 0xd0, 0x6e, 0x04, 0xc4, 0x69, 0xde, 0xf0, 0x5a, 0xfb, 0x33, 0x03, 0xe7, 0xad, 0x8b, - 0x23, 0x71, 0x37, 0xb0, 0x28, 0xc7, 0x0a, 0xc3, 0xfe, 0x62, 0x09, 0x46, 0x16, 0xb6, 0xb6, 0x5c, - 0xcf, 0x8d, 0xf6, 0xd1, 0x2d, 0x18, 0xf3, 0xfc, 0x26, 0x91, 0xff, 0xd9, 0x57, 0x8c, 0x3e, 0x77, - 0x7e, 0x3e, 0xbd, 0x94, 0xe6, 0xd7, 0x35, 0xbc, 0xc5, 0xa9, 0x7b, 0x07, 0x73, 0x63, 0x7a, 0x09, - 0x36, 0xe8, 0x20, 0x0c, 0xa3, 0x1d, 0xbf, 0xa9, 0xc8, 0x96, 0x18, 0xd9, 0xb9, 0x2c, 0xb2, 0xb5, - 0x18, 0x6d, 0x71, 0xf2, 0xde, 0xc1, 0xdc, 0xa8, 0x56, 0x80, 0x75, 0x22, 0x68, 0x13, 0x26, 0xe9, - 0x5f, 0x2f, 0x72, 0x15, 0xdd, 0x32, 0xa3, 0xfb, 0x44, 0x1e, 0x5d, 0x0d, 0x75, 0xf1, 0xc4, 0xbd, - 0x83, 0xb9, 0xc9, 0x44, 0x21, 0x4e, 0x12, 0xb4, 0xdf, 0x82, 0x89, 0x85, 0x28, 0x72, 0x1a, 0x3b, - 0xa4, 0xc9, 0x67, 0x10, 0xbd, 0x00, 0x03, 0x9e, 0xd3, 0x26, 0x62, 0x7e, 0xcf, 0x8b, 0x81, 0x1d, - 0x58, 0x77, 0xda, 0xe4, 0xfe, 0xc1, 0xdc, 0xd4, 0x4d, 0xcf, 0x7d, 0xb3, 0x2b, 0x56, 0x05, 0x2d, - 0xc3, 0x0c, 0x1b, 0x3d, 0x07, 0xd0, 0x24, 0x7b, 0x6e, 0x83, 0xd4, 0x9c, 0x68, 0x47, 0xcc, 0x37, - 0x12, 0x75, 0xa1, 0xaa, 0x20, 0x58, 0xc3, 0xb2, 0xef, 0x42, 0x65, 0x61, 0xcf, 0x77, 0x9b, 0x35, - 0xbf, 0x19, 0xa2, 0x5d, 0x98, 0xec, 0x04, 0x64, 0x8b, 0x04, 0xaa, 0x68, 0xc6, 0x3a, 0x5f, 0xbe, - 0x38, 0xfa, 0xdc, 0xc5, 0xcc, 0x8f, 0x35, 0x51, 0x97, 0xbd, 0x28, 0xd8, 0x5f, 0x7c, 0x44, 0xb4, - 0x37, 0x99, 0x80, 0xe2, 0x24, 0x65, 0xfb, 0x5f, 0x97, 0xe0, 0xd4, 0xc2, 0x5b, 0xdd, 0x80, 0x54, - 0xdd, 0x70, 0x37, 0xb9, 0xc2, 0x9b, 0x6e, 0xb8, 0xbb, 0x1e, 0x8f, 0x80, 0x5a, 0x5a, 0x55, 0x51, - 0x8e, 0x15, 0x06, 0x7a, 0x16, 0x86, 0xe9, 0xef, 0x9b, 0x78, 0x55, 0x7c, 0xf2, 0x09, 0x81, 0x3c, - 0x5a, 0x75, 0x22, 0xa7, 0xca, 0x41, 0x58, 0xe2, 0xa0, 0x35, 0x18, 0x6d, 0xb0, 0x0d, 0xb9, 0xbd, - 0xe6, 0x37, 0x09, 0x9b, 0xcc, 0xca, 0xe2, 0xd3, 0x14, 0x7d, 0x29, 0x2e, 0xbe, 0x7f, 0x30, 0x37, - 0xc3, 0xfb, 0x26, 0x48, 0x68, 0x30, 0xac, 0xd7, 0x47, 0xb6, 0xda, 0x5f, 0x03, 0x8c, 0x12, 0x64, - 0xec, 0xad, 0x8b, 0xda, 0x56, 0x19, 0x64, 0x5b, 0x65, 0x2c, 0x7b, 0x9b, 0xa0, 0xcb, 0x30, 0xb0, - 0xeb, 0x7a, 0xcd, 0x99, 0x21, 0x46, 0xeb, 0x2c, 0x9d, 0xf3, 0x6b, 0xae, 0xd7, 0xbc, 0x7f, 0x30, - 0x37, 0x6d, 0x74, 0x87, 0x16, 0x62, 0x86, 0x6a, 0xff, 0xa9, 0x05, 0x73, 0x0c, 0xb6, 0xe2, 0xb6, - 0x48, 0x8d, 0x04, 0xa1, 0x1b, 0x46, 0xc4, 0x8b, 0x8c, 0x01, 0x7d, 0x0e, 0x20, 0x24, 0x8d, 0x80, - 0x44, 0xda, 0x90, 0xaa, 0x85, 0x51, 0x57, 0x10, 0xac, 0x61, 0xd1, 0x03, 0x21, 0xdc, 0x71, 0x02, - 0xb6, 0xbe, 0xc4, 0xc0, 0xaa, 0x03, 0xa1, 0x2e, 0x01, 0x38, 0xc6, 0x31, 0x0e, 0x84, 0x72, 0xaf, - 0x03, 0x01, 0x7d, 0x04, 0x26, 0xe3, 0xc6, 0xc2, 0x8e, 0xd3, 0x90, 0x03, 0xc8, 0xb6, 0x4c, 0xdd, - 0x04, 0xe1, 0x24, 0xae, 0xfd, 0x77, 0x2d, 0xb1, 0x78, 0xe8, 0x57, 0xbf, 0xc3, 0xbf, 0xd5, 0xfe, - 0x45, 0x0b, 0x86, 0x17, 0x5d, 0xaf, 0xe9, 0x7a, 0xdb, 0xe8, 0xd3, 0x30, 0x42, 0xef, 0xa6, 0xa6, - 0x13, 0x39, 0xe2, 0xdc, 0xfb, 0x80, 0xb6, 0xb7, 0xd4, 0x55, 0x31, 0xdf, 0xd9, 0xdd, 0xa6, 0x05, - 0xe1, 0x3c, 0xc5, 0xa6, 0xbb, 0xed, 0xc6, 0xe6, 0x67, 0x48, 0x23, 0x5a, 0x23, 0x91, 0x13, 0x7f, - 0x4e, 0x5c, 0x86, 0x15, 0x55, 0x74, 0x0d, 0x86, 0x22, 0x27, 0xd8, 0x26, 0x91, 0x38, 0x00, 0x33, - 0x0f, 0x2a, 0x5e, 0x13, 0xd3, 0x1d, 0x49, 0xbc, 0x06, 0x89, 0xaf, 0x85, 0x0d, 0x56, 0x15, 0x0b, - 0x12, 0xf6, 0x8f, 0x0c, 0xc3, 0x99, 0xa5, 0xfa, 0x6a, 0xce, 0xba, 0xba, 0x00, 0x43, 0xcd, 0xc0, - 0xdd, 0x23, 0x81, 0x18, 0x67, 0x45, 0xa5, 0xca, 0x4a, 0xb1, 0x80, 0xa2, 0x97, 0x60, 0x8c, 0x5f, - 0x48, 0x57, 0x1d, 0xaf, 0xd9, 0x92, 0x43, 0x7c, 0x52, 0x60, 0x8f, 0xdd, 0xd2, 0x60, 0xd8, 0xc0, - 0x3c, 0xe4, 0xa2, 0xba, 0x90, 0xd8, 0x8c, 0x79, 0x97, 0xdd, 0xe7, 0x2d, 0x98, 0xe2, 0xcd, 0x2c, - 0x44, 0x51, 0xe0, 0x6e, 0x76, 0x23, 0x12, 0xce, 0x0c, 0xb2, 0x93, 0x6e, 0x29, 0x6b, 0xb4, 0x72, - 0x47, 0x60, 0xfe, 0x56, 0x82, 0x0a, 0x3f, 0x04, 0x67, 0x44, 0xbb, 0x53, 0x49, 0x30, 0x4e, 0x35, - 0x8b, 0xbe, 0xdb, 0x82, 0xd9, 0x86, 0xef, 0x45, 0x81, 0xdf, 0x6a, 0x91, 0xa0, 0xd6, 0xdd, 0x6c, - 0xb9, 0xe1, 0x0e, 0x5f, 0xa7, 0x98, 0x6c, 0xb1, 0x93, 0x20, 0x67, 0x0e, 0x15, 0x92, 0x98, 0xc3, - 0x73, 0xf7, 0x0e, 0xe6, 0x66, 0x97, 0x72, 0x49, 0xe1, 0x82, 0x66, 0xd0, 0x2e, 0x20, 0x7a, 0x95, - 0xd6, 0x23, 0x67, 0x9b, 0xc4, 0x8d, 0x0f, 0xf7, 0xdf, 0xf8, 0xe9, 0x7b, 0x07, 0x73, 0x68, 0x3d, - 0x45, 0x02, 0x67, 0x90, 0x45, 0x6f, 0xc2, 0x49, 0x5a, 0x9a, 0xfa, 0xd6, 0x91, 0xfe, 0x9b, 0x9b, - 0xb9, 0x77, 0x30, 0x77, 0x72, 0x3d, 0x83, 0x08, 0xce, 0x24, 0x8d, 0xbe, 0xcb, 0x82, 0x33, 0xf1, - 0xe7, 0x2f, 0xdf, 0xed, 0x38, 0x5e, 0x33, 0x6e, 0xb8, 0xd2, 0x7f, 0xc3, 0xf4, 0x4c, 0x3e, 0xb3, - 0x94, 0x47, 0x09, 0xe7, 0x37, 0x32, 0xbb, 0x04, 0xa7, 0x32, 0x57, 0x0b, 0x9a, 0x82, 0xf2, 0x2e, - 0xe1, 0x5c, 0x50, 0x05, 0xd3, 0x9f, 0xe8, 0x24, 0x0c, 0xee, 0x39, 0xad, 0xae, 0xd8, 0x28, 0x98, - 0xff, 0x79, 0xb9, 0xf4, 0x92, 0x65, 0xff, 0x9b, 0x32, 0x4c, 0x2e, 0xd5, 0x57, 0x1f, 0x68, 0x17, - 0xea, 0xd7, 0x50, 0xa9, 0xf0, 0x1a, 0x8a, 0x2f, 0xb5, 0x72, 0xee, 0xa5, 0xf6, 0x17, 0x33, 0xb6, - 0xd0, 0x00, 0xdb, 0x42, 0xdf, 0x96, 0xb3, 0x85, 0x8e, 0x78, 0xe3, 0xec, 0xe5, 0xac, 0xa2, 0x41, - 0x36, 0x99, 0x99, 0x1c, 0xcb, 0x75, 0xbf, 0xe1, 0xb4, 0x92, 0x47, 0xdf, 0x21, 0x97, 0xd2, 0xd1, - 0xcc, 0x63, 0x03, 0xc6, 0x96, 0x9c, 0x8e, 0xb3, 0xe9, 0xb6, 0xdc, 0xc8, 0x25, 0x21, 0x7a, 0x12, - 0xca, 0x4e, 0xb3, 0xc9, 0xb8, 0xad, 0xca, 0xe2, 0xa9, 0x7b, 0x07, 0x73, 0xe5, 0x85, 0x26, 0xbd, - 0xf6, 0x41, 0x61, 0xed, 0x63, 0x8a, 0x81, 0xde, 0x0f, 0x03, 0xcd, 0xc0, 0xef, 0xcc, 0x94, 0x18, - 0x26, 0xdd, 0x75, 0x03, 0xd5, 0xc0, 0xef, 0x24, 0x50, 0x19, 0x8e, 0xfd, 0xab, 0x25, 0x78, 0x6c, - 0x89, 0x74, 0x76, 0x56, 0xea, 0x39, 0xe7, 0xf7, 0x45, 0x18, 0x69, 0xfb, 0x9e, 0x1b, 0xf9, 0x41, - 0x28, 0x9a, 0x66, 0x2b, 0x62, 0x4d, 0x94, 0x61, 0x05, 0x45, 0xe7, 0x61, 0xa0, 0x13, 0x33, 0x95, - 0x63, 0x92, 0x21, 0x65, 0xec, 0x24, 0x83, 0x50, 0x8c, 0x6e, 0x48, 0x02, 0xb1, 0x62, 0x14, 0xc6, - 0xcd, 0x90, 0x04, 0x98, 0x41, 0xe2, 0x9b, 0x99, 0xde, 0xd9, 0xe2, 0x84, 0x4e, 0xdc, 0xcc, 0x14, - 0x82, 0x35, 0x2c, 0x54, 0x83, 0x4a, 0x98, 0x98, 0xd9, 0xbe, 0xb6, 0xe9, 0x38, 0xbb, 0xba, 0xd5, - 0x4c, 0xc6, 0x44, 0x8c, 0x1b, 0x65, 0xa8, 0xe7, 0xd5, 0xfd, 0xd5, 0x12, 0x20, 0x3e, 0x84, 0xdf, - 0x64, 0x03, 0x77, 0x33, 0x3d, 0x70, 0xfd, 0x6f, 0x89, 0xa3, 0x1a, 0xbd, 0xff, 0x65, 0xc1, 0x63, - 0x4b, 0xae, 0xd7, 0x24, 0x41, 0xce, 0x02, 0x7c, 0x38, 0x6f, 0xd9, 0xc3, 0x31, 0x0d, 0xc6, 0x12, - 0x1b, 0x38, 0x82, 0x25, 0x66, 0xff, 0xb1, 0x05, 0x88, 0x7f, 0xf6, 0x3b, 0xee, 0x63, 0x6f, 0xa6, - 0x3f, 0xf6, 0x08, 0x96, 0x85, 0x7d, 0x1d, 0x26, 0x96, 0x5a, 0x2e, 0xf1, 0xa2, 0xd5, 0xda, 0x92, - 0xef, 0x6d, 0xb9, 0xdb, 0xe8, 0x65, 0x98, 0x88, 0xdc, 0x36, 0xf1, 0xbb, 0x51, 0x9d, 0x34, 0x7c, - 0x8f, 0xbd, 0x24, 0xad, 0x8b, 0x83, 0x8b, 0xe8, 0xde, 0xc1, 0xdc, 0xc4, 0x86, 0x01, 0xc1, 0x09, - 0x4c, 0xfb, 0x77, 0xe9, 0xf8, 0xf9, 0xed, 0x8e, 0xef, 0x11, 0x2f, 0x5a, 0xf2, 0xbd, 0x26, 0x97, - 0x38, 0xbc, 0x0c, 0x03, 0x11, 0x1d, 0x0f, 0x3e, 0x76, 0x17, 0xe4, 0x46, 0xa1, 0xa3, 0x70, 0xff, - 0x60, 0xee, 0x74, 0xba, 0x06, 0x1b, 0x27, 0x56, 0x07, 0x7d, 0x1b, 0x0c, 0x85, 0x91, 0x13, 0x75, - 0x43, 0x31, 0x9a, 0x8f, 0xcb, 0xd1, 0xac, 0xb3, 0xd2, 0xfb, 0x07, 0x73, 0x93, 0xaa, 0x1a, 0x2f, - 0xc2, 0xa2, 0x02, 0x7a, 0x0a, 0x86, 0xdb, 0x24, 0x0c, 0x9d, 0x6d, 0x79, 0x1b, 0x4e, 0x8a, 0xba, - 0xc3, 0x6b, 0xbc, 0x18, 0x4b, 0x38, 0x7a, 0x02, 0x06, 0x49, 0x10, 0xf8, 0x81, 0xd8, 0xa3, 0xe3, - 0x02, 0x71, 0x70, 0x99, 0x16, 0x62, 0x0e, 0xb3, 0x7f, 0xc3, 0x82, 0x49, 0xd5, 0x57, 0xde, 0xd6, - 0x31, 0xbc, 0x0a, 0x3e, 0x01, 0xd0, 0x90, 0x1f, 0x18, 0xb2, 0xdb, 0x63, 0xf4, 0xb9, 0x0b, 0x99, - 0x17, 0x75, 0x6a, 0x18, 0x63, 0xca, 0xaa, 0x28, 0xc4, 0x1a, 0x35, 0xfb, 0x9f, 0x59, 0x70, 0x22, - 0xf1, 0x45, 0xd7, 0xdd, 0x30, 0x42, 0x6f, 0xa4, 0xbe, 0x6a, 0xbe, 0xbf, 0xaf, 0xa2, 0xb5, 0xd9, - 0x37, 0xa9, 0xa5, 0x2c, 0x4b, 0xb4, 0x2f, 0xba, 0x0a, 0x83, 0x6e, 0x44, 0xda, 0xf2, 0x63, 0x9e, - 0x28, 0xfc, 0x18, 0xde, 0xab, 0x78, 0x46, 0x56, 0x69, 0x4d, 0xcc, 0x09, 0xd8, 0xbf, 0x5a, 0x86, - 0x0a, 0x5f, 0xb6, 0x6b, 0x4e, 0xe7, 0x18, 0xe6, 0xe2, 0x69, 0xa8, 0xb8, 0xed, 0x76, 0x37, 0x72, - 0x36, 0xc5, 0x71, 0x3e, 0xc2, 0xb7, 0xd6, 0xaa, 0x2c, 0xc4, 0x31, 0x1c, 0xad, 0xc2, 0x00, 0xeb, - 0x0a, 0xff, 0xca, 0x27, 0xb3, 0xbf, 0x52, 0xf4, 0x7d, 0xbe, 0xea, 0x44, 0x0e, 0xe7, 0xa4, 0xd4, - 0x3d, 0x42, 0x8b, 0x30, 0x23, 0x81, 0x1c, 0x80, 0x4d, 0xd7, 0x73, 0x82, 0x7d, 0x5a, 0x36, 0x53, - 0x66, 0x04, 0x9f, 0x2d, 0x26, 0xb8, 0xa8, 0xf0, 0x39, 0x59, 0xf5, 0x61, 0x31, 0x00, 0x6b, 0x44, - 0x67, 0x3f, 0x04, 0x15, 0x85, 0x7c, 0x18, 0x86, 0x68, 0xf6, 0x23, 0x30, 0x99, 0x68, 0xab, 0x57, - 0xf5, 0x31, 0x9d, 0x9f, 0xfa, 0x25, 0x76, 0x64, 0x88, 0x5e, 0x2f, 0x7b, 0x7b, 0xe2, 0xc8, 0x7d, - 0x0b, 0x4e, 0xb6, 0x32, 0x4e, 0x32, 0x31, 0xaf, 0xfd, 0x9f, 0x7c, 0x8f, 0x89, 0xcf, 0x3e, 0x99, - 0x05, 0xc5, 0x99, 0x6d, 0x50, 0x1e, 0xc1, 0xef, 0xd0, 0x0d, 0xe2, 0xb4, 0x74, 0x76, 0xfb, 0x86, - 0x28, 0xc3, 0x0a, 0x4a, 0xcf, 0xbb, 0x93, 0xaa, 0xf3, 0xd7, 0xc8, 0x7e, 0x9d, 0xb4, 0x48, 0x23, - 0xf2, 0x83, 0x6f, 0x68, 0xf7, 0xcf, 0xf2, 0xd1, 0xe7, 0xc7, 0xe5, 0xa8, 0x20, 0x50, 0xbe, 0x46, - 0xf6, 0xf9, 0x54, 0xe8, 0x5f, 0x57, 0x2e, 0xfc, 0xba, 0x9f, 0xb5, 0x60, 0x5c, 0x7d, 0xdd, 0x31, - 0x9c, 0x0b, 0x8b, 0xe6, 0xb9, 0x70, 0xb6, 0x70, 0x81, 0xe7, 0x9c, 0x08, 0x5f, 0x2d, 0xc1, 0x19, - 0x85, 0x43, 0xdf, 0x06, 0xfc, 0x8f, 0x58, 0x55, 0x97, 0xa0, 0xe2, 0x29, 0xa9, 0x95, 0x65, 0x8a, - 0x8b, 0x62, 0x99, 0x55, 0x8c, 0x43, 0x59, 0x3c, 0x2f, 0x16, 0x2d, 0x8d, 0xe9, 0xe2, 0x5c, 0x21, - 0xba, 0x5d, 0x84, 0x72, 0xd7, 0x6d, 0x8a, 0x0b, 0xe6, 0x03, 0x72, 0xb4, 0x6f, 0xae, 0x56, 0xef, - 0x1f, 0xcc, 0x3d, 0x9e, 0xa7, 0x4a, 0xa0, 0x37, 0x5b, 0x38, 0x7f, 0x73, 0xb5, 0x8a, 0x69, 0x65, - 0xb4, 0x00, 0x93, 0x52, 0x5b, 0x72, 0x8b, 0xb2, 0x5b, 0xbe, 0x27, 0xee, 0x21, 0x25, 0x93, 0xc5, - 0x26, 0x18, 0x27, 0xf1, 0x51, 0x15, 0xa6, 0x76, 0xbb, 0x9b, 0xa4, 0x45, 0x22, 0xfe, 0xc1, 0xd7, - 0x08, 0x97, 0x58, 0x56, 0xe2, 0x97, 0xd9, 0xb5, 0x04, 0x1c, 0xa7, 0x6a, 0xd8, 0x7f, 0xce, 0xee, - 0x03, 0x31, 0x7a, 0xb5, 0xc0, 0xa7, 0x0b, 0x8b, 0x52, 0xff, 0x46, 0x2e, 0xe7, 0x7e, 0x56, 0xc5, - 0x35, 0xb2, 0xbf, 0xe1, 0x53, 0xce, 0x3c, 0x7b, 0x55, 0x18, 0x6b, 0x7e, 0xa0, 0x70, 0xcd, 0xff, - 0x5c, 0x09, 0x4e, 0xa9, 0x11, 0x30, 0x98, 0xc0, 0x6f, 0xf6, 0x31, 0xb8, 0x0c, 0xa3, 0x4d, 0xb2, - 0xe5, 0x74, 0x5b, 0x91, 0x12, 0x9f, 0x0f, 0x72, 0x15, 0x4a, 0x35, 0x2e, 0xc6, 0x3a, 0xce, 0x21, - 0x86, 0xed, 0x7f, 0x8f, 0xb2, 0x8b, 0x38, 0x72, 0xe8, 0x1a, 0x57, 0xbb, 0xc6, 0xca, 0xdd, 0x35, - 0x4f, 0xc0, 0xa0, 0xdb, 0xa6, 0x8c, 0x59, 0xc9, 0xe4, 0xb7, 0x56, 0x69, 0x21, 0xe6, 0x30, 0xf4, - 0x3e, 0x18, 0x6e, 0xf8, 0xed, 0xb6, 0xe3, 0x35, 0xd9, 0x95, 0x57, 0x59, 0x1c, 0xa5, 0xbc, 0xdb, - 0x12, 0x2f, 0xc2, 0x12, 0x86, 0x1e, 0x83, 0x01, 0x27, 0xd8, 0xe6, 0x32, 0x8c, 0xca, 0xe2, 0x08, - 0x6d, 0x69, 0x21, 0xd8, 0x0e, 0x31, 0x2b, 0xa5, 0x4f, 0xb0, 0x3b, 0x7e, 0xb0, 0xeb, 0x7a, 0xdb, - 0x55, 0x37, 0x10, 0x5b, 0x42, 0xdd, 0x85, 0xb7, 0x15, 0x04, 0x6b, 0x58, 0x68, 0x05, 0x06, 0x3b, - 0x7e, 0x10, 0x85, 0x33, 0x43, 0x6c, 0xb8, 0x1f, 0xcf, 0x39, 0x88, 0xf8, 0xd7, 0xd6, 0xfc, 0x20, - 0x8a, 0x3f, 0x80, 0xfe, 0x0b, 0x31, 0xaf, 0x8e, 0xae, 0xc3, 0x30, 0xf1, 0xf6, 0x56, 0x02, 0xbf, - 0x3d, 0x73, 0x22, 0x9f, 0xd2, 0x32, 0x47, 0xe1, 0xcb, 0x2c, 0xe6, 0x51, 0x45, 0x31, 0x96, 0x24, - 0xd0, 0xb7, 0x41, 0x99, 0x78, 0x7b, 0x33, 0xc3, 0x8c, 0xd2, 0x6c, 0x0e, 0xa5, 0x5b, 0x4e, 0x10, - 0x9f, 0xf9, 0xcb, 0xde, 0x1e, 0xa6, 0x75, 0xd0, 0xc7, 0xa1, 0x22, 0x0f, 0x8c, 0x50, 0x08, 0xeb, - 0x32, 0x17, 0xac, 0x3c, 0x66, 0x30, 0x79, 0xb3, 0xeb, 0x06, 0xa4, 0x4d, 0xbc, 0x28, 0x8c, 0x4f, - 0x48, 0x09, 0x0d, 0x71, 0x4c, 0x0d, 0x7d, 0x5c, 0x4a, 0x88, 0xd7, 0xfc, 0xae, 0x17, 0x85, 0x33, - 0x15, 0xd6, 0xbd, 0x4c, 0xdd, 0xdd, 0xad, 0x18, 0x2f, 0x29, 0x42, 0xe6, 0x95, 0xb1, 0x41, 0x0a, - 0x7d, 0x12, 0xc6, 0xf9, 0x7f, 0xae, 0x01, 0x0b, 0x67, 0x4e, 0x31, 0xda, 0xe7, 0xf3, 0x69, 0x73, - 0xc4, 0xc5, 0x53, 0x82, 0xf8, 0xb8, 0x5e, 0x1a, 0x62, 0x93, 0x1a, 0xc2, 0x30, 0xde, 0x72, 0xf7, - 0x88, 0x47, 0xc2, 0xb0, 0x16, 0xf8, 0x9b, 0x64, 0x06, 0xd8, 0xc0, 0x9c, 0xc9, 0xd6, 0x98, 0xf9, - 0x9b, 0x64, 0x71, 0x9a, 0xd2, 0xbc, 0xae, 0xd7, 0xc1, 0x26, 0x09, 0x74, 0x13, 0x26, 0xe8, 0x8b, - 0xcd, 0x8d, 0x89, 0x8e, 0xf6, 0x22, 0xca, 0xde, 0x55, 0xd8, 0xa8, 0x84, 0x13, 0x44, 0xd0, 0x0d, - 0x18, 0x0b, 0x23, 0x27, 0x88, 0xba, 0x1d, 0x4e, 0xf4, 0x74, 0x2f, 0xa2, 0x4c, 0xe1, 0x5a, 0xd7, - 0xaa, 0x60, 0x83, 0x00, 0x7a, 0x0d, 0x2a, 0x2d, 0x77, 0x8b, 0x34, 0xf6, 0x1b, 0x2d, 0x32, 0x33, - 0xc6, 0xa8, 0x65, 0x1e, 0x2a, 0xd7, 0x25, 0x12, 0xe7, 0x73, 0xd5, 0x5f, 0x1c, 0x57, 0x47, 0xb7, - 0xe0, 0x74, 0x44, 0x82, 0xb6, 0xeb, 0x39, 0xf4, 0x30, 0x10, 0x4f, 0x2b, 0xa6, 0xc8, 0x1c, 0x67, - 0xbb, 0xed, 0x9c, 0x98, 0x8d, 0xd3, 0x1b, 0x99, 0x58, 0x38, 0xa7, 0x36, 0xba, 0x0b, 0x33, 0x19, - 0x10, 0xbf, 0xe5, 0x36, 0xf6, 0x67, 0x4e, 0x32, 0xca, 0x1f, 0x16, 0x94, 0x67, 0x36, 0x72, 0xf0, - 0xee, 0x17, 0xc0, 0x70, 0x2e, 0x75, 0x74, 0x03, 0x26, 0xd9, 0x09, 0x54, 0xeb, 0xb6, 0x5a, 0xa2, - 0xc1, 0x09, 0xd6, 0xe0, 0xfb, 0xe4, 0x7d, 0xbc, 0x6a, 0x82, 0xef, 0x1f, 0xcc, 0x41, 0xfc, 0x0f, - 0x27, 0x6b, 0xa3, 0x4d, 0xa6, 0x33, 0xeb, 0x06, 0x6e, 0xb4, 0x4f, 0xcf, 0x0d, 0x72, 0x37, 0x9a, - 0x99, 0x2c, 0x94, 0x57, 0xe8, 0xa8, 0x4a, 0xb1, 0xa6, 0x17, 0xe2, 0x24, 0x41, 0x7a, 0xa4, 0x86, - 0x51, 0xd3, 0xf5, 0x66, 0xa6, 0xf8, 0xbb, 0x44, 0x9e, 0x48, 0x75, 0x5a, 0x88, 0x39, 0x8c, 0xe9, - 0xcb, 0xe8, 0x8f, 0x1b, 0xf4, 0xe6, 0x9a, 0x66, 0x88, 0xb1, 0xbe, 0x4c, 0x02, 0x70, 0x8c, 0x43, - 0x99, 0xc9, 0x28, 0xda, 0x9f, 0x41, 0x0c, 0x55, 0x1d, 0x2c, 0x1b, 0x1b, 0x1f, 0xc7, 0xb4, 0xdc, - 0xde, 0x84, 0x09, 0x75, 0x10, 0xb2, 0x31, 0x41, 0x73, 0x30, 0xc8, 0xd8, 0x27, 0x21, 0x5d, 0xab, - 0xd0, 0x2e, 0x30, 0xd6, 0x0a, 0xf3, 0x72, 0xd6, 0x05, 0xf7, 0x2d, 0xb2, 0xb8, 0x1f, 0x11, 0xfe, - 0xa6, 0x2f, 0x6b, 0x5d, 0x90, 0x00, 0x1c, 0xe3, 0xd8, 0xff, 0x8f, 0xb3, 0xa1, 0xf1, 0x69, 0xdb, - 0xc7, 0xfd, 0xf2, 0x0c, 0x8c, 0xec, 0xf8, 0x61, 0x44, 0xb1, 0x59, 0x1b, 0x83, 0x31, 0xe3, 0x79, - 0x55, 0x94, 0x63, 0x85, 0x81, 0x5e, 0x81, 0xf1, 0x86, 0xde, 0x80, 0xb8, 0x1c, 0xd5, 0x31, 0x62, - 0xb4, 0x8e, 0x4d, 0x5c, 0xf4, 0x12, 0x8c, 0x30, 0x1b, 0x90, 0x86, 0xdf, 0x12, 0x5c, 0x9b, 0xbc, - 0xe1, 0x47, 0x6a, 0xa2, 0xfc, 0xbe, 0xf6, 0x1b, 0x2b, 0x6c, 0x74, 0x01, 0x86, 0x68, 0x17, 0x56, - 0x6b, 0xe2, 0x5a, 0x52, 0x82, 0xa2, 0xab, 0xac, 0x14, 0x0b, 0xa8, 0xfd, 0x57, 0x4a, 0xda, 0x28, - 0xd3, 0xf7, 0x30, 0x41, 0x35, 0x18, 0xbe, 0xe3, 0xb8, 0x91, 0xeb, 0x6d, 0x0b, 0xfe, 0xe3, 0xa9, - 0xc2, 0x3b, 0x8a, 0x55, 0xba, 0xcd, 0x2b, 0xf0, 0x5b, 0x54, 0xfc, 0xc1, 0x92, 0x0c, 0xa5, 0x18, - 0x74, 0x3d, 0x8f, 0x52, 0x2c, 0xf5, 0x4b, 0x11, 0xf3, 0x0a, 0x9c, 0xa2, 0xf8, 0x83, 0x25, 0x19, - 0xf4, 0x06, 0x80, 0xdc, 0x61, 0xa4, 0x29, 0x6c, 0x2f, 0x9e, 0xe9, 0x4d, 0x74, 0x43, 0xd5, 0x59, - 0x9c, 0xa0, 0x77, 0x74, 0xfc, 0x1f, 0x6b, 0xf4, 0xec, 0x88, 0xf1, 0x69, 0xe9, 0xce, 0xa0, 0xef, - 0xa0, 0x4b, 0xdc, 0x09, 0x22, 0xd2, 0x5c, 0x88, 0xc4, 0xe0, 0xbc, 0xbf, 0xbf, 0x47, 0xca, 0x86, - 0xdb, 0x26, 0xfa, 0x76, 0x10, 0x44, 0x70, 0x4c, 0xcf, 0xfe, 0x85, 0x32, 0xcc, 0xe4, 0x75, 0x97, - 0x2e, 0x3a, 0x72, 0xd7, 0x8d, 0x96, 0x28, 0x7b, 0x65, 0x99, 0x8b, 0x6e, 0x59, 0x94, 0x63, 0x85, - 0x41, 0x67, 0x3f, 0x74, 0xb7, 0xe5, 0x1b, 0x73, 0x30, 0x9e, 0xfd, 0x3a, 0x2b, 0xc5, 0x02, 0x4a, - 0xf1, 0x02, 0xe2, 0x84, 0xc2, 0xb8, 0x47, 0x5b, 0x25, 0x98, 0x95, 0x62, 0x01, 0xd5, 0xa5, 0x5d, - 0x03, 0x3d, 0xa4, 0x5d, 0xc6, 0x10, 0x0d, 0x1e, 0xed, 0x10, 0xa1, 0x4f, 0x01, 0x6c, 0xb9, 0x9e, - 0x1b, 0xee, 0x30, 0xea, 0x43, 0x87, 0xa6, 0xae, 0x98, 0xb3, 0x15, 0x45, 0x05, 0x6b, 0x14, 0xd1, - 0x8b, 0x30, 0xaa, 0x36, 0xe0, 0x6a, 0x95, 0x69, 0x3a, 0x35, 0xcb, 0x91, 0xf8, 0x34, 0xaa, 0x62, - 0x1d, 0xcf, 0xfe, 0x4c, 0x72, 0xbd, 0x88, 0x1d, 0xa0, 0x8d, 0xaf, 0xd5, 0xef, 0xf8, 0x96, 0x8a, - 0xc7, 0xd7, 0xfe, 0x7a, 0x19, 0x26, 0x8d, 0xc6, 0xba, 0x61, 0x1f, 0x67, 0xd6, 0x15, 0x7a, 0x80, - 0x3b, 0x11, 0x11, 0xfb, 0xcf, 0xee, 0xbd, 0x55, 0xf4, 0x43, 0x9e, 0xee, 0x00, 0x5e, 0x1f, 0x7d, - 0x0a, 0x2a, 0x2d, 0x27, 0x64, 0x92, 0x33, 0x22, 0xf6, 0x5d, 0x3f, 0xc4, 0xe2, 0x87, 0x89, 0x13, - 0x46, 0xda, 0xad, 0xc9, 0x69, 0xc7, 0x24, 0xe9, 0x4d, 0x43, 0xf9, 0x13, 0x69, 0x3d, 0xa6, 0x3a, - 0x41, 0x99, 0x98, 0x7d, 0xcc, 0x61, 0xe8, 0x25, 0x18, 0x0b, 0x08, 0x5b, 0x15, 0x4b, 0x94, 0x9b, - 0x63, 0xcb, 0x6c, 0x30, 0x66, 0xfb, 0xb0, 0x06, 0xc3, 0x06, 0x66, 0xfc, 0x36, 0x18, 0x2a, 0x78, - 0x1b, 0x3c, 0x05, 0xc3, 0xec, 0x87, 0x5a, 0x01, 0x6a, 0x36, 0x56, 0x79, 0x31, 0x96, 0xf0, 0xe4, - 0x82, 0x19, 0xe9, 0x6f, 0xc1, 0xd0, 0xd7, 0x87, 0x58, 0xd4, 0x4c, 0xcb, 0x3c, 0xc2, 0x4f, 0x39, - 0xb1, 0xe4, 0xb1, 0x84, 0xd9, 0xef, 0x87, 0x89, 0xaa, 0x43, 0xda, 0xbe, 0xb7, 0xec, 0x35, 0x3b, - 0xbe, 0xeb, 0x45, 0x68, 0x06, 0x06, 0xd8, 0x25, 0xc2, 0x8f, 0x80, 0x01, 0xda, 0x10, 0x66, 0x25, - 0xf6, 0x36, 0x9c, 0xaa, 0xfa, 0x77, 0xbc, 0x3b, 0x4e, 0xd0, 0x5c, 0xa8, 0xad, 0x6a, 0xef, 0xeb, - 0x75, 0xf9, 0xbe, 0xe3, 0x46, 0x5b, 0x99, 0x47, 0xaf, 0x56, 0x93, 0xb3, 0xb5, 0x2b, 0x6e, 0x8b, - 0xe4, 0x48, 0x41, 0xfe, 0x7a, 0xc9, 0x68, 0x29, 0xc6, 0x57, 0x5a, 0x2d, 0x2b, 0x57, 0xab, 0xf5, - 0x3a, 0x8c, 0x6c, 0xb9, 0xa4, 0xd5, 0xc4, 0x64, 0x4b, 0xac, 0xc4, 0x27, 0xf3, 0xed, 0x50, 0x56, - 0x28, 0xa6, 0x94, 0x7a, 0xf1, 0xd7, 0xe1, 0x8a, 0xa8, 0x8c, 0x15, 0x19, 0xb4, 0x0b, 0x53, 0xf2, - 0xc1, 0x20, 0xa1, 0x62, 0x5d, 0x3e, 0x55, 0xf4, 0x0a, 0x31, 0x89, 0x9f, 0xbc, 0x77, 0x30, 0x37, - 0x85, 0x13, 0x64, 0x70, 0x8a, 0x30, 0x7d, 0x0e, 0xb6, 0xe9, 0x09, 0x3c, 0xc0, 0x86, 0x9f, 0x3d, - 0x07, 0xd9, 0xcb, 0x96, 0x95, 0xda, 0x3f, 0x6e, 0xc1, 0x23, 0xa9, 0x91, 0x11, 0x2f, 0xfc, 0x23, - 0x9e, 0x85, 0xe4, 0x8b, 0xbb, 0xd4, 0xfb, 0xc5, 0x6d, 0xff, 0x3d, 0x0b, 0x4e, 0x2e, 0xb7, 0x3b, - 0xd1, 0x7e, 0xd5, 0x35, 0x55, 0x50, 0x1f, 0x82, 0xa1, 0x36, 0x69, 0xba, 0xdd, 0xb6, 0x98, 0xb9, - 0x39, 0x79, 0x4a, 0xad, 0xb1, 0xd2, 0xfb, 0x07, 0x73, 0xe3, 0xf5, 0xc8, 0x0f, 0x9c, 0x6d, 0xc2, - 0x0b, 0xb0, 0x40, 0x67, 0x67, 0xbd, 0xfb, 0x16, 0xb9, 0xee, 0xb6, 0x5d, 0x69, 0x57, 0x54, 0x28, - 0xb3, 0x9b, 0x97, 0x03, 0x3a, 0xff, 0x7a, 0xd7, 0xf1, 0x22, 0x37, 0xda, 0x17, 0xda, 0x23, 0x49, - 0x04, 0xc7, 0xf4, 0xec, 0xaf, 0x59, 0x30, 0x29, 0xd7, 0xfd, 0x42, 0xb3, 0x19, 0x90, 0x30, 0x44, - 0xb3, 0x50, 0x72, 0x3b, 0xa2, 0x97, 0x20, 0x7a, 0x59, 0x5a, 0xad, 0xe1, 0x92, 0xdb, 0x91, 0x6c, - 0x19, 0x3b, 0x08, 0xcb, 0xa6, 0x22, 0xed, 0xaa, 0x28, 0xc7, 0x0a, 0x03, 0x5d, 0x84, 0x11, 0xcf, - 0x6f, 0x72, 0xdb, 0x2e, 0x7e, 0xa5, 0xb1, 0x05, 0xb6, 0x2e, 0xca, 0xb0, 0x82, 0xa2, 0x1a, 0x54, - 0xb8, 0xd9, 0x53, 0xbc, 0x68, 0xfb, 0x32, 0x9e, 0x62, 0x5f, 0xb6, 0x21, 0x6b, 0xe2, 0x98, 0x88, - 0xfd, 0x2b, 0x16, 0x8c, 0xc9, 0x2f, 0xeb, 0x93, 0xe7, 0xa4, 0x5b, 0x2b, 0xe6, 0x37, 0xe3, 0xad, - 0x45, 0x79, 0x46, 0x06, 0x31, 0x58, 0xc5, 0xf2, 0xa1, 0x58, 0xc5, 0xcb, 0x30, 0xea, 0x74, 0x3a, - 0x35, 0x93, 0xcf, 0x64, 0x4b, 0x69, 0x21, 0x2e, 0xc6, 0x3a, 0x8e, 0xfd, 0x63, 0x25, 0x98, 0x90, - 0x5f, 0x50, 0xef, 0x6e, 0x86, 0x24, 0x42, 0x1b, 0x50, 0x71, 0xf8, 0x2c, 0x11, 0xb9, 0xc8, 0x9f, - 0xc8, 0x96, 0x23, 0x18, 0x53, 0x1a, 0x5f, 0xf8, 0x0b, 0xb2, 0x36, 0x8e, 0x09, 0xa1, 0x16, 0x4c, - 0x7b, 0x7e, 0xc4, 0x0e, 0x7f, 0x05, 0x2f, 0x52, 0xed, 0x24, 0xa9, 0x9f, 0x11, 0xd4, 0xa7, 0xd7, - 0x93, 0x54, 0x70, 0x9a, 0x30, 0x5a, 0x96, 0xb2, 0x99, 0x72, 0xbe, 0x30, 0x40, 0x9f, 0xb8, 0x6c, - 0xd1, 0x8c, 0xfd, 0xcb, 0x16, 0x54, 0x24, 0xda, 0x71, 0x68, 0xf1, 0xd6, 0x60, 0x38, 0x64, 0x93, - 0x20, 0x87, 0xc6, 0x2e, 0xea, 0x38, 0x9f, 0xaf, 0xf8, 0x4e, 0xe3, 0xff, 0x43, 0x2c, 0x69, 0x30, - 0xd1, 0xbc, 0xea, 0xfe, 0x3b, 0x44, 0x34, 0xaf, 0xfa, 0x93, 0x73, 0x29, 0xfd, 0x21, 0xeb, 0xb3, - 0x26, 0xeb, 0xa2, 0xac, 0x57, 0x27, 0x20, 0x5b, 0xee, 0xdd, 0x24, 0xeb, 0x55, 0x63, 0xa5, 0x58, - 0x40, 0xd1, 0x1b, 0x30, 0xd6, 0x90, 0x32, 0xd9, 0x78, 0x87, 0x5f, 0x28, 0xd4, 0x0f, 0x28, 0x55, - 0x12, 0x97, 0x85, 0x2c, 0x69, 0xf5, 0xb1, 0x41, 0xcd, 0x34, 0x23, 0x28, 0xf7, 0x32, 0x23, 0x88, - 0xe9, 0xe6, 0x2b, 0xd5, 0x7f, 0xc2, 0x82, 0x21, 0x2e, 0x8b, 0xeb, 0x4f, 0x14, 0xaa, 0x69, 0xd6, - 0xe2, 0xb1, 0xbb, 0x45, 0x0b, 0x85, 0xa6, 0x0c, 0xad, 0x41, 0x85, 0xfd, 0x60, 0xb2, 0xc4, 0x72, - 0xbe, 0xd5, 0x3d, 0x6f, 0x55, 0xef, 0xe0, 0x2d, 0x59, 0x0d, 0xc7, 0x14, 0xec, 0x1f, 0x2d, 0xd3, - 0xd3, 0x2d, 0x46, 0x35, 0x2e, 0x7d, 0xeb, 0xe1, 0x5d, 0xfa, 0xa5, 0x87, 0x75, 0xe9, 0x6f, 0xc3, - 0x64, 0x43, 0xd3, 0xc3, 0xc5, 0x33, 0x79, 0xb1, 0x70, 0x91, 0x68, 0x2a, 0x3b, 0x2e, 0x65, 0x59, - 0x32, 0x89, 0xe0, 0x24, 0x55, 0xf4, 0x1d, 0x30, 0xc6, 0xe7, 0x59, 0xb4, 0xc2, 0x2d, 0x31, 0xde, - 0x97, 0xbf, 0x5e, 0xf4, 0x26, 0xb8, 0x54, 0x4e, 0xab, 0x8e, 0x0d, 0x62, 0xf6, 0x9f, 0x58, 0x80, - 0x96, 0x3b, 0x3b, 0xa4, 0x4d, 0x02, 0xa7, 0x15, 0x8b, 0xd3, 0x7f, 0xd0, 0x82, 0x19, 0x92, 0x2a, - 0x5e, 0xf2, 0xdb, 0x6d, 0xf1, 0x68, 0xc9, 0x79, 0x57, 0x2f, 0xe7, 0xd4, 0x51, 0x6e, 0x09, 0x33, - 0x79, 0x18, 0x38, 0xb7, 0x3d, 0xb4, 0x06, 0x27, 0xf8, 0x2d, 0xa9, 0x00, 0x9a, 0xed, 0xf5, 0xa3, - 0x82, 0xf0, 0x89, 0x8d, 0x34, 0x0a, 0xce, 0xaa, 0x67, 0x7f, 0xcf, 0x18, 0xe4, 0xf6, 0xe2, 0x5d, - 0x3d, 0xc2, 0xbb, 0x7a, 0x84, 0x77, 0xf5, 0x08, 0xef, 0xea, 0x11, 0xde, 0xd5, 0x23, 0x7c, 0xcb, - 0xeb, 0x11, 0xfe, 0xaa, 0x05, 0xa7, 0xd4, 0x35, 0x60, 0x3c, 0x7c, 0x3f, 0x0b, 0x27, 0xf8, 0x76, - 0x5b, 0x6a, 0x39, 0x6e, 0x7b, 0x83, 0xb4, 0x3b, 0x2d, 0x27, 0x92, 0x5a, 0xf7, 0xcb, 0x99, 0x2b, - 0x37, 0x61, 0xb1, 0x6a, 0x54, 0x5c, 0x7c, 0x84, 0x5e, 0x4f, 0x19, 0x00, 0x9c, 0xd5, 0x8c, 0xfd, - 0x0b, 0x23, 0x30, 0xb8, 0xbc, 0x47, 0xbc, 0xe8, 0x18, 0x9e, 0x08, 0x0d, 0x98, 0x70, 0xbd, 0x3d, - 0xbf, 0xb5, 0x47, 0x9a, 0x1c, 0x7e, 0x98, 0x97, 0xec, 0x69, 0x41, 0x7a, 0x62, 0xd5, 0x20, 0x81, - 0x13, 0x24, 0x1f, 0x86, 0x34, 0xf9, 0x0a, 0x0c, 0xf1, 0x43, 0x5c, 0x88, 0x92, 0x33, 0xcf, 0x6c, - 0x36, 0x88, 0xe2, 0x6a, 0x8a, 0x25, 0xdd, 0xfc, 0x92, 0x10, 0xd5, 0xd1, 0x67, 0x60, 0x62, 0xcb, - 0x0d, 0xc2, 0x68, 0xc3, 0x6d, 0x93, 0x30, 0x72, 0xda, 0x9d, 0x07, 0x90, 0x1e, 0xab, 0x71, 0x58, - 0x31, 0x28, 0xe1, 0x04, 0x65, 0xb4, 0x0d, 0xe3, 0x2d, 0x47, 0x6f, 0x6a, 0xf8, 0xd0, 0x4d, 0xa9, - 0xdb, 0xe1, 0xba, 0x4e, 0x08, 0x9b, 0x74, 0xe9, 0x76, 0x6a, 0x30, 0x01, 0xe8, 0x08, 0x13, 0x0b, - 0xa8, 0xed, 0xc4, 0x25, 0x9f, 0x1c, 0x46, 0x19, 0x1d, 0x66, 0x20, 0x5b, 0x31, 0x19, 0x1d, 0xcd, - 0x0c, 0xf6, 0xd3, 0x50, 0x21, 0x74, 0x08, 0x29, 0x61, 0x71, 0xc1, 0x5c, 0xea, 0xaf, 0xaf, 0x6b, - 0x6e, 0x23, 0xf0, 0x4d, 0xb9, 0xfd, 0xb2, 0xa4, 0x84, 0x63, 0xa2, 0x68, 0x09, 0x86, 0x42, 0x12, - 0xb8, 0x24, 0x14, 0x57, 0x4d, 0xc1, 0x34, 0x32, 0x34, 0xee, 0x5b, 0xc2, 0x7f, 0x63, 0x51, 0x95, - 0x2e, 0x2f, 0x87, 0x89, 0x34, 0xd9, 0x65, 0xa0, 0x2d, 0xaf, 0x05, 0x56, 0x8a, 0x05, 0x14, 0xbd, - 0x06, 0xc3, 0x01, 0x69, 0x31, 0xc5, 0xd0, 0x78, 0xff, 0x8b, 0x9c, 0xeb, 0x99, 0x78, 0x3d, 0x2c, - 0x09, 0xa0, 0x6b, 0x80, 0x02, 0x42, 0x19, 0x25, 0xd7, 0xdb, 0x56, 0x66, 0xa3, 0xe2, 0xa0, 0x55, - 0x0c, 0x29, 0x8e, 0x31, 0xa4, 0x9b, 0x0f, 0xce, 0xa8, 0x86, 0xae, 0xc0, 0xb4, 0x2a, 0x5d, 0xf5, - 0xc2, 0xc8, 0xa1, 0x07, 0xdc, 0x24, 0xa3, 0xa5, 0xe4, 0x14, 0x38, 0x89, 0x80, 0xd3, 0x75, 0xec, - 0x2f, 0x59, 0xc0, 0xc7, 0xf9, 0x18, 0x5e, 0xe7, 0xaf, 0x9a, 0xaf, 0xf3, 0x33, 0xb9, 0x33, 0x97, - 0xf3, 0x32, 0xff, 0x92, 0x05, 0xa3, 0xda, 0xcc, 0xc6, 0x6b, 0xd6, 0x2a, 0x58, 0xb3, 0x5d, 0x98, - 0xa2, 0x2b, 0xfd, 0xc6, 0x66, 0x48, 0x82, 0x3d, 0xd2, 0x64, 0x0b, 0xb3, 0xf4, 0x60, 0x0b, 0x53, - 0x99, 0xa8, 0x5d, 0x4f, 0x10, 0xc4, 0xa9, 0x26, 0xec, 0x4f, 0xcb, 0xae, 0x2a, 0x8b, 0xbe, 0x86, - 0x9a, 0xf3, 0x84, 0x45, 0x9f, 0x9a, 0x55, 0x1c, 0xe3, 0xd0, 0xad, 0xb6, 0xe3, 0x87, 0x51, 0xd2, - 0xa2, 0xef, 0xaa, 0x1f, 0x46, 0x98, 0x41, 0xec, 0xe7, 0x01, 0x96, 0xef, 0x92, 0x06, 0x5f, 0xb1, - 0xfa, 0xe3, 0xc1, 0xca, 0x7f, 0x3c, 0xd8, 0xbf, 0x65, 0xc1, 0xc4, 0xca, 0x92, 0x71, 0x73, 0xcd, - 0x03, 0xf0, 0x17, 0xcf, 0xed, 0xdb, 0xeb, 0x52, 0x1d, 0xce, 0x35, 0x9a, 0xaa, 0x14, 0x6b, 0x18, - 0xe8, 0x0c, 0x94, 0x5b, 0x5d, 0x4f, 0x88, 0x0f, 0x87, 0xe9, 0xf5, 0x78, 0xbd, 0xeb, 0x61, 0x5a, - 0xa6, 0xb9, 0x14, 0x94, 0xfb, 0x76, 0x29, 0xe8, 0xe9, 0xda, 0x8f, 0xe6, 0x60, 0xf0, 0xce, 0x1d, - 0xb7, 0xc9, 0x1d, 0x28, 0x85, 0xaa, 0xfe, 0xf6, 0xed, 0xd5, 0x6a, 0x88, 0x79, 0xb9, 0xfd, 0x85, - 0x32, 0xcc, 0xae, 0xb4, 0xc8, 0xdd, 0xb7, 0xe9, 0x44, 0xda, 0xaf, 0x43, 0xc4, 0xe1, 0x04, 0x31, - 0x87, 0x75, 0x7a, 0xe9, 0x3d, 0x1e, 0x5b, 0x30, 0xcc, 0x0d, 0xda, 0xa4, 0x4b, 0xe9, 0x2b, 0x59, - 0xad, 0xe7, 0x0f, 0xc8, 0x3c, 0x37, 0x8c, 0x13, 0x1e, 0x71, 0xea, 0xc2, 0x14, 0xa5, 0x58, 0x12, - 0x9f, 0x7d, 0x19, 0xc6, 0x74, 0xcc, 0x43, 0xb9, 0x9f, 0xfd, 0xa5, 0x32, 0x4c, 0xd1, 0x1e, 0x3c, - 0xd4, 0x89, 0xb8, 0x99, 0x9e, 0x88, 0xa3, 0x76, 0x41, 0xea, 0x3d, 0x1b, 0x6f, 0x24, 0x67, 0xe3, - 0x72, 0xde, 0x6c, 0x1c, 0xf7, 0x1c, 0x7c, 0xb7, 0x05, 0x27, 0x56, 0x5a, 0x7e, 0x63, 0x37, 0xe1, - 0x26, 0xf4, 0x22, 0x8c, 0xd2, 0xe3, 0x38, 0x34, 0x3c, 0xd8, 0x8d, 0x98, 0x06, 0x02, 0x84, 0x75, - 0x3c, 0xad, 0xda, 0xcd, 0x9b, 0xab, 0xd5, 0xac, 0x50, 0x08, 0x02, 0x84, 0x75, 0x3c, 0xfb, 0xd7, - 0x2d, 0x38, 0x7b, 0x65, 0x69, 0x39, 0x5e, 0x8a, 0xa9, 0x68, 0x0c, 0x17, 0x60, 0xa8, 0xd3, 0xd4, - 0xba, 0x12, 0x8b, 0x57, 0xab, 0xac, 0x17, 0x02, 0xfa, 0x4e, 0x89, 0x34, 0x72, 0x13, 0xe0, 0x0a, - 0xae, 0x2d, 0x89, 0x73, 0x57, 0x6a, 0x53, 0xac, 0x5c, 0x6d, 0xca, 0xfb, 0x60, 0x98, 0xde, 0x0b, - 0x6e, 0x43, 0xf6, 0x9b, 0x2b, 0x68, 0x79, 0x11, 0x96, 0x30, 0xfb, 0x67, 0x2c, 0x38, 0x71, 0xc5, - 0x8d, 0xe8, 0xa5, 0x9d, 0x0c, 0x37, 0x40, 0x6f, 0xed, 0xd0, 0x8d, 0xfc, 0x60, 0x3f, 0x19, 0x6e, - 0x00, 0x2b, 0x08, 0xd6, 0xb0, 0xf8, 0x07, 0xed, 0xb9, 0xcc, 0x42, 0xbb, 0x64, 0xea, 0xaf, 0xb0, - 0x28, 0xc7, 0x0a, 0x83, 0x8e, 0x57, 0xd3, 0x0d, 0x98, 0xe8, 0x6f, 0x5f, 0x1c, 0xdc, 0x6a, 0xbc, - 0xaa, 0x12, 0x80, 0x63, 0x1c, 0xfb, 0x8f, 0x2c, 0x98, 0xbb, 0xd2, 0xea, 0x86, 0x11, 0x09, 0xb6, - 0xc2, 0x9c, 0x43, 0xf7, 0x79, 0xa8, 0x10, 0x29, 0x68, 0x17, 0xbd, 0x56, 0x8c, 0xa8, 0x92, 0xc0, - 0xf3, 0xa8, 0x07, 0x0a, 0xaf, 0x0f, 0x5f, 0xc6, 0xc3, 0x39, 0xa3, 0xad, 0x00, 0x22, 0x7a, 0x5b, - 0x7a, 0x18, 0x08, 0xe6, 0x4f, 0xbe, 0x9c, 0x82, 0xe2, 0x8c, 0x1a, 0xf6, 0x8f, 0x5b, 0x70, 0x4a, - 0x7d, 0xf0, 0x3b, 0xee, 0x33, 0xed, 0xaf, 0x94, 0x60, 0xfc, 0xea, 0xc6, 0x46, 0xed, 0x0a, 0x89, - 0xb4, 0x55, 0x59, 0xac, 0x3e, 0xc7, 0x9a, 0x16, 0xb0, 0xe8, 0x8d, 0xd8, 0x8d, 0xdc, 0xd6, 0x3c, - 0x8f, 0x26, 0x34, 0xbf, 0xea, 0x45, 0x37, 0x82, 0x7a, 0x14, 0xb8, 0xde, 0x76, 0xe6, 0x4a, 0x97, - 0x3c, 0x4b, 0x39, 0x8f, 0x67, 0x41, 0xcf, 0xc3, 0x10, 0x0b, 0x67, 0x24, 0x27, 0xe1, 0x51, 0xf5, - 0xc4, 0x62, 0xa5, 0xf7, 0x0f, 0xe6, 0x2a, 0x37, 0xf1, 0x2a, 0xff, 0x83, 0x05, 0x2a, 0xba, 0x09, - 0xa3, 0x3b, 0x51, 0xd4, 0xb9, 0x4a, 0x9c, 0x26, 0x09, 0xe4, 0x29, 0x7b, 0x2e, 0xeb, 0x94, 0xa5, - 0x83, 0xc0, 0xd1, 0xe2, 0x83, 0x29, 0x2e, 0x0b, 0xb1, 0x4e, 0xc7, 0xae, 0x03, 0xc4, 0xb0, 0x23, - 0x52, 0x80, 0xd8, 0x1b, 0x50, 0xa1, 0x9f, 0xbb, 0xd0, 0x72, 0x9d, 0x62, 0x15, 0xf3, 0xd3, 0x50, - 0x91, 0x0a, 0xe4, 0x50, 0xf8, 0x5a, 0xb3, 0x1b, 0x49, 0xea, 0x97, 0x43, 0x1c, 0xc3, 0xed, 0x2d, - 0x38, 0xc9, 0xcc, 0x01, 0x9d, 0x68, 0xc7, 0x58, 0x7d, 0xbd, 0xa7, 0xf9, 0x19, 0xf1, 0x62, 0xe3, - 0x7d, 0x9e, 0xd1, 0xdc, 0x19, 0xc7, 0x24, 0xc5, 0xf8, 0xf5, 0x66, 0x7f, 0x7d, 0x00, 0x1e, 0x5d, - 0xad, 0xe7, 0x87, 0xe3, 0x78, 0x09, 0xc6, 0x38, 0x23, 0x48, 0x27, 0xdd, 0x69, 0x89, 0x76, 0x95, - 0x6c, 0x73, 0x43, 0x83, 0x61, 0x03, 0x13, 0x9d, 0x85, 0xb2, 0xfb, 0xa6, 0x97, 0x74, 0xf6, 0x59, - 0x7d, 0x7d, 0x1d, 0xd3, 0x72, 0x0a, 0xa6, 0x3c, 0x25, 0x3f, 0xac, 0x15, 0x58, 0xf1, 0x95, 0xaf, - 0xc2, 0x84, 0x1b, 0x36, 0x42, 0x77, 0xd5, 0xa3, 0x3b, 0x50, 0xdb, 0xc3, 0x4a, 0x9a, 0x40, 0x3b, - 0xad, 0xa0, 0x38, 0x81, 0xad, 0xdd, 0x1c, 0x83, 0x7d, 0xf3, 0xa5, 0x3d, 0x9d, 0x8f, 0xe9, 0xc1, - 0xde, 0x61, 0x5f, 0x17, 0x32, 0x21, 0xb5, 0x38, 0xd8, 0xf9, 0x07, 0x87, 0x58, 0xc2, 0xe8, 0x53, - 0xad, 0xb1, 0xe3, 0x74, 0x16, 0xba, 0xd1, 0x4e, 0xd5, 0x0d, 0x1b, 0xfe, 0x1e, 0x09, 0xf6, 0xd9, - 0x2b, 0x7b, 0x24, 0x7e, 0xaa, 0x29, 0xc0, 0xd2, 0xd5, 0x85, 0x1a, 0xc5, 0xc4, 0xe9, 0x3a, 0x68, - 0x01, 0x26, 0x65, 0x61, 0x9d, 0x84, 0xec, 0x70, 0x1f, 0x65, 0x64, 0x94, 0xfb, 0x8d, 0x28, 0x56, - 0x44, 0x92, 0xf8, 0x26, 0xeb, 0x0a, 0x47, 0xc1, 0xba, 0x7e, 0x08, 0xc6, 0x5d, 0xcf, 0x8d, 0x5c, - 0x27, 0xf2, 0xb9, 0x86, 0x85, 0x3f, 0xa8, 0x99, 0xe8, 0x78, 0x55, 0x07, 0x60, 0x13, 0xcf, 0xfe, - 0xaf, 0x03, 0x30, 0xcd, 0xa6, 0xed, 0xdd, 0x15, 0xf6, 0xad, 0xb4, 0xc2, 0x6e, 0xa6, 0x57, 0xd8, - 0x51, 0xf0, 0xe4, 0x0f, 0xbc, 0xcc, 0x3e, 0x03, 0x15, 0xe5, 0x71, 0x24, 0x5d, 0x0e, 0xad, 0x1c, - 0x97, 0xc3, 0xde, 0xf7, 0xb2, 0x34, 0xda, 0x2a, 0x67, 0x1a, 0x6d, 0x7d, 0xd9, 0x82, 0x58, 0x65, - 0x80, 0x5e, 0x87, 0x4a, 0xc7, 0x67, 0xb6, 0x88, 0x81, 0x34, 0xf0, 0x7d, 0x6f, 0xa1, 0xce, 0x81, - 0x47, 0x24, 0x0a, 0xf8, 0x28, 0xd4, 0x64, 0x55, 0x1c, 0x53, 0x41, 0xd7, 0x60, 0xb8, 0x13, 0x90, - 0x7a, 0xc4, 0xc2, 0x73, 0xf4, 0x4f, 0x90, 0xaf, 0x1a, 0x5e, 0x11, 0x4b, 0x0a, 0xf6, 0x7f, 0xb3, - 0x60, 0x2a, 0x89, 0x8a, 0x3e, 0x0c, 0x03, 0xe4, 0x2e, 0x69, 0x88, 0xfe, 0x66, 0x5e, 0xb2, 0xb1, - 0xd0, 0x81, 0x0f, 0x00, 0xfd, 0x8f, 0x59, 0x2d, 0x74, 0x15, 0x86, 0xe9, 0x0d, 0x7b, 0x45, 0x85, - 0x86, 0x7a, 0x3c, 0xef, 0x96, 0x56, 0xac, 0x0a, 0xef, 0x9c, 0x28, 0xc2, 0xb2, 0x3a, 0xb3, 0x94, - 0x6a, 0x74, 0xea, 0xf4, 0xf1, 0x12, 0x15, 0xbd, 0xb1, 0x37, 0x96, 0x6a, 0x1c, 0x49, 0x50, 0xe3, - 0x96, 0x52, 0xb2, 0x10, 0xc7, 0x44, 0xec, 0x9f, 0xb3, 0x00, 0xb8, 0x61, 0x98, 0xe3, 0x6d, 0x93, - 0x63, 0x90, 0x93, 0x57, 0x61, 0x20, 0xec, 0x90, 0x46, 0x91, 0x99, 0x6c, 0xdc, 0x9f, 0x7a, 0x87, - 0x34, 0xe2, 0x15, 0x47, 0xff, 0x61, 0x56, 0xdb, 0xfe, 0x5e, 0x80, 0x89, 0x18, 0x6d, 0x35, 0x22, - 0x6d, 0xf4, 0xac, 0x11, 0xa6, 0xe0, 0x4c, 0x22, 0x4c, 0x41, 0x85, 0x61, 0x6b, 0x22, 0xd9, 0xcf, - 0x40, 0xb9, 0xed, 0xdc, 0x15, 0x32, 0xb7, 0xa7, 0x8b, 0xbb, 0x41, 0xe9, 0xcf, 0xaf, 0x39, 0x77, - 0xf9, 0xb3, 0xf4, 0x69, 0xb9, 0x43, 0xd6, 0x9c, 0xbb, 0xf7, 0xb9, 0x31, 0x2c, 0x3b, 0xa5, 0xaf, - 0xbb, 0x61, 0xf4, 0xb9, 0xff, 0x12, 0xff, 0x67, 0xfb, 0x8e, 0x36, 0xc2, 0xda, 0x72, 0x3d, 0x61, - 0xf3, 0xd4, 0x57, 0x5b, 0xae, 0x97, 0x6c, 0xcb, 0xf5, 0xfa, 0x68, 0xcb, 0xf5, 0xd0, 0x5b, 0x30, - 0x2c, 0x4c, 0x12, 0x45, 0x58, 0xa0, 0x4b, 0x7d, 0xb4, 0x27, 0x2c, 0x1a, 0x79, 0x9b, 0x97, 0xe4, - 0xb3, 0x5b, 0x94, 0xf6, 0x6c, 0x57, 0x36, 0x88, 0xfe, 0x9a, 0x05, 0x13, 0xe2, 0x37, 0x26, 0x6f, - 0x76, 0x49, 0x18, 0x09, 0xb6, 0xf4, 0x83, 0xfd, 0xf7, 0x41, 0x54, 0xe4, 0x5d, 0xf9, 0xa0, 0xbc, - 0x67, 0x4c, 0x60, 0xcf, 0x1e, 0x25, 0x7a, 0x81, 0xfe, 0x81, 0x05, 0x27, 0xdb, 0xce, 0x5d, 0xde, - 0x22, 0x2f, 0xc3, 0x4e, 0xe4, 0xfa, 0x42, 0xb5, 0xff, 0xe1, 0xfe, 0xa6, 0x3f, 0x55, 0x9d, 0x77, - 0x52, 0xea, 0x1f, 0x4f, 0x66, 0xa1, 0xf4, 0xec, 0x6a, 0x66, 0xbf, 0x66, 0xb7, 0x60, 0x44, 0xae, - 0xb7, 0x0c, 0xe1, 0x46, 0x55, 0xe7, 0xb9, 0x0f, 0x6d, 0x11, 0xaa, 0xbb, 0xff, 0xd3, 0x76, 0xc4, - 0x5a, 0x7b, 0xa8, 0xed, 0x7c, 0x06, 0xc6, 0xf4, 0x35, 0xf6, 0x50, 0xdb, 0x7a, 0x13, 0x4e, 0x64, - 0xac, 0xa5, 0x87, 0xda, 0xe4, 0x1d, 0x38, 0x93, 0xbb, 0x3e, 0x1e, 0x66, 0xc3, 0xf6, 0x57, 0x2c, - 0xfd, 0x1c, 0x3c, 0x06, 0x65, 0xc5, 0x92, 0xa9, 0xac, 0x38, 0x57, 0xbc, 0x73, 0x72, 0x34, 0x16, - 0x6f, 0xe8, 0x9d, 0xa6, 0xa7, 0x3a, 0x7a, 0x0d, 0x86, 0x5a, 0xb4, 0x44, 0x1a, 0xb6, 0xda, 0xbd, - 0x77, 0x64, 0xcc, 0x4c, 0xb2, 0xf2, 0x10, 0x0b, 0x0a, 0xf6, 0x2f, 0x5a, 0x30, 0x70, 0x0c, 0x23, - 0x81, 0xcd, 0x91, 0x78, 0x36, 0x97, 0xb4, 0x88, 0x58, 0x3c, 0x8f, 0x9d, 0x3b, 0xcb, 0x77, 0x23, - 0xe2, 0x85, 0xec, 0x46, 0xce, 0x1c, 0x98, 0x9f, 0xb2, 0xe0, 0xc4, 0x75, 0xdf, 0x69, 0x2e, 0x3a, - 0x2d, 0xc7, 0x6b, 0x90, 0x60, 0xd5, 0xdb, 0x3e, 0x94, 0x55, 0x76, 0xa9, 0xa7, 0x55, 0xf6, 0x92, - 0x34, 0x6a, 0x1a, 0xc8, 0x9f, 0x3f, 0xca, 0x49, 0x27, 0x03, 0xb7, 0x18, 0xe6, 0xb7, 0x3b, 0x80, - 0xf4, 0x5e, 0x0a, 0x1f, 0x19, 0x0c, 0xc3, 0x2e, 0xef, 0xaf, 0x98, 0xc4, 0x27, 0xb3, 0x39, 0xdc, - 0xd4, 0xe7, 0x69, 0xde, 0x1f, 0xbc, 0x00, 0x4b, 0x42, 0xf6, 0x4b, 0x90, 0xe9, 0x68, 0xdf, 0x5b, - 0x2e, 0x61, 0x7f, 0x1c, 0xa6, 0x59, 0xcd, 0x43, 0x4a, 0x06, 0xec, 0x84, 0x34, 0x35, 0x23, 0x04, - 0x9f, 0xfd, 0x79, 0x0b, 0x26, 0xd7, 0x13, 0x91, 0xc9, 0x2e, 0x30, 0xfd, 0x6b, 0x86, 0x10, 0xbf, - 0xce, 0x4a, 0xb1, 0x80, 0x1e, 0xb9, 0x90, 0xeb, 0xcf, 0x2d, 0x88, 0x63, 0x5f, 0x1c, 0x03, 0xfb, - 0xb6, 0x64, 0xb0, 0x6f, 0x99, 0x8c, 0xac, 0xea, 0x4e, 0x1e, 0xf7, 0x86, 0xae, 0xa9, 0xa8, 0x50, - 0x05, 0x3c, 0x6c, 0x4c, 0x86, 0x2f, 0xc5, 0x09, 0x33, 0x74, 0x94, 0x8c, 0x13, 0x65, 0xff, 0x76, - 0x09, 0x90, 0xc2, 0xed, 0x3b, 0x6a, 0x55, 0xba, 0xc6, 0xd1, 0x44, 0xad, 0xda, 0x03, 0xc4, 0x2c, - 0x08, 0x02, 0xc7, 0x0b, 0x39, 0x59, 0x57, 0x88, 0xf5, 0x0e, 0x67, 0x9e, 0x30, 0x2b, 0x9a, 0x44, - 0xd7, 0x53, 0xd4, 0x70, 0x46, 0x0b, 0x9a, 0x65, 0xc8, 0x60, 0xbf, 0x96, 0x21, 0x43, 0x3d, 0xfc, - 0xe0, 0x7e, 0xd6, 0x82, 0x71, 0x35, 0x4c, 0xef, 0x10, 0x2b, 0x75, 0xd5, 0x9f, 0x9c, 0x03, 0xb4, - 0xa6, 0x75, 0x99, 0x5d, 0x2c, 0xdf, 0xce, 0xfc, 0x19, 0x9d, 0x96, 0xfb, 0x16, 0x51, 0x31, 0x03, - 0xe7, 0x84, 0x7f, 0xa2, 0x28, 0xbd, 0x7f, 0x30, 0x37, 0xae, 0xfe, 0xf1, 0x18, 0xc5, 0x71, 0x15, - 0x7a, 0x24, 0x4f, 0x26, 0x96, 0x22, 0x7a, 0x11, 0x06, 0x3b, 0x3b, 0x4e, 0x48, 0x12, 0xde, 0x3c, - 0x83, 0x35, 0x5a, 0x78, 0xff, 0x60, 0x6e, 0x42, 0x55, 0x60, 0x25, 0x98, 0x63, 0xf7, 0x1f, 0x0b, - 0x2c, 0xbd, 0x38, 0x7b, 0xc6, 0x02, 0xfb, 0x13, 0x0b, 0x06, 0xd6, 0xfd, 0xe6, 0x71, 0x1c, 0x01, - 0xaf, 0x1a, 0x47, 0xc0, 0x63, 0x79, 0xe1, 0xe3, 0x73, 0x77, 0xff, 0x4a, 0x62, 0xf7, 0x9f, 0xcb, - 0xa5, 0x50, 0xbc, 0xf1, 0xdb, 0x30, 0xca, 0x82, 0xd2, 0x0b, 0xcf, 0xa5, 0xe7, 0x8d, 0x0d, 0x3f, - 0x97, 0xd8, 0xf0, 0x93, 0x1a, 0xaa, 0xb6, 0xd3, 0x9f, 0x82, 0x61, 0xe1, 0x0a, 0x93, 0x74, 0x0b, - 0x15, 0xb8, 0x58, 0xc2, 0xed, 0x9f, 0x28, 0x83, 0x11, 0x04, 0x1f, 0xfd, 0xb2, 0x05, 0xf3, 0x01, - 0x37, 0x91, 0x6d, 0x56, 0xbb, 0x81, 0xeb, 0x6d, 0xd7, 0x1b, 0x3b, 0xa4, 0xd9, 0x6d, 0xb9, 0xde, - 0xf6, 0xea, 0xb6, 0xe7, 0xab, 0xe2, 0xe5, 0xbb, 0xa4, 0xd1, 0x65, 0x6a, 0xb7, 0x1e, 0x11, 0xf7, - 0x95, 0xa9, 0xf9, 0x73, 0xf7, 0x0e, 0xe6, 0xe6, 0xf1, 0xa1, 0x68, 0xe3, 0x43, 0xf6, 0x05, 0xfd, - 0xba, 0x05, 0x97, 0x78, 0x6c, 0xf8, 0xfe, 0xfb, 0x5f, 0xf0, 0x5a, 0xae, 0x49, 0x52, 0x31, 0x91, - 0x0d, 0x12, 0xb4, 0x17, 0x3f, 0x24, 0x06, 0xf4, 0x52, 0xed, 0x70, 0x6d, 0xe1, 0xc3, 0x76, 0xce, - 0xfe, 0x17, 0x65, 0x18, 0x17, 0x31, 0xa3, 0xc4, 0x1d, 0xf0, 0xa2, 0xb1, 0x24, 0x1e, 0x4f, 0x2c, - 0x89, 0x69, 0x03, 0xf9, 0x68, 0x8e, 0xff, 0x10, 0xa6, 0xe9, 0xe1, 0x7c, 0x95, 0x38, 0x41, 0xb4, - 0x49, 0x1c, 0x6e, 0xf0, 0x55, 0x3e, 0xf4, 0xe9, 0xaf, 0xe4, 0x93, 0xd7, 0x93, 0xc4, 0x70, 0x9a, - 0xfe, 0xb7, 0xd2, 0x9d, 0xe3, 0xc1, 0x54, 0x2a, 0xec, 0xd7, 0x27, 0xa0, 0xa2, 0xfc, 0x38, 0xc4, - 0xa1, 0x53, 0x1c, 0x3d, 0x2f, 0x49, 0x81, 0x8b, 0xbf, 0x62, 0x1f, 0xa2, 0x98, 0x9c, 0xfd, 0x8f, - 0x4a, 0x46, 0x83, 0x7c, 0x12, 0xd7, 0x61, 0xc4, 0x09, 0x43, 0x77, 0xdb, 0x23, 0xcd, 0x22, 0x09, - 0x65, 0xaa, 0x19, 0xe6, 0x4b, 0xb3, 0x20, 0x6a, 0x62, 0x45, 0x03, 0x5d, 0xe5, 0x66, 0x75, 0x7b, - 0xa4, 0x48, 0x3c, 0x99, 0xa2, 0x06, 0xd2, 0xf0, 0x6e, 0x8f, 0x60, 0x51, 0x1f, 0x7d, 0x92, 0xdb, - 0x3d, 0x5e, 0xf3, 0xfc, 0x3b, 0xde, 0x15, 0xdf, 0x97, 0x71, 0x19, 0xfa, 0x23, 0x38, 0x2d, 0xad, - 0x1d, 0x55, 0x75, 0x6c, 0x52, 0xeb, 0x2f, 0x8e, 0xe6, 0x67, 0xe1, 0x04, 0x25, 0x6d, 0xba, 0x4d, - 0x87, 0x88, 0xc0, 0xa4, 0x08, 0x48, 0x26, 0xcb, 0xc4, 0xd8, 0x65, 0x3e, 0xe5, 0xcc, 0xda, 0xb1, - 0x20, 0xfd, 0x9a, 0x49, 0x02, 0x27, 0x69, 0xda, 0x3f, 0x6d, 0x01, 0x73, 0x21, 0x3d, 0x06, 0x7e, - 0xe4, 0x23, 0x26, 0x3f, 0x32, 0x93, 0x37, 0xc8, 0x39, 0xac, 0xc8, 0x0b, 0x7c, 0x65, 0xd5, 0x02, - 0xff, 0xee, 0xbe, 0x30, 0x56, 0xe9, 0xfd, 0xfe, 0xb0, 0xff, 0xaf, 0xc5, 0x0f, 0x31, 0xe5, 0x65, - 0x81, 0xbe, 0x13, 0x46, 0x1a, 0x4e, 0xc7, 0x69, 0xf0, 0x8c, 0x2d, 0xb9, 0x12, 0x3d, 0xa3, 0xd2, - 0xfc, 0x92, 0xa8, 0xc1, 0x25, 0x54, 0x32, 0xb0, 0xdd, 0x88, 0x2c, 0xee, 0x29, 0x95, 0x52, 0x4d, - 0xce, 0xee, 0xc2, 0xb8, 0x41, 0xec, 0xa1, 0x8a, 0x33, 0xbe, 0x93, 0x5f, 0xb1, 0x2a, 0x10, 0x63, - 0x1b, 0xa6, 0x3d, 0xed, 0x3f, 0xbd, 0x50, 0xe4, 0xe3, 0xf2, 0xbd, 0xbd, 0x2e, 0x51, 0x76, 0xfb, - 0x68, 0xde, 0xa9, 0x09, 0x32, 0x38, 0x4d, 0xd9, 0xfe, 0x49, 0x0b, 0x1e, 0xd1, 0x11, 0x35, 0x07, - 0x98, 0x5e, 0x4a, 0x92, 0x2a, 0x8c, 0xf8, 0x1d, 0x12, 0x38, 0x91, 0x1f, 0x88, 0x5b, 0xe3, 0xa2, - 0x1c, 0xf4, 0x1b, 0xa2, 0xfc, 0xbe, 0x88, 0x77, 0x2e, 0xa9, 0xcb, 0x72, 0xac, 0x6a, 0xd2, 0xd7, - 0x27, 0x1b, 0x8c, 0x50, 0xb8, 0x3a, 0xb1, 0x33, 0x80, 0x69, 0xd2, 0x43, 0x2c, 0x20, 0xf6, 0xd7, - 0x2d, 0xbe, 0xb0, 0xf4, 0xae, 0xa3, 0x37, 0x61, 0xaa, 0xed, 0x44, 0x8d, 0x9d, 0xe5, 0xbb, 0x9d, - 0x80, 0xab, 0x9c, 0xe4, 0x38, 0x3d, 0xdd, 0x6b, 0x9c, 0xb4, 0x8f, 0x8c, 0x4d, 0x39, 0xd7, 0x12, - 0xc4, 0x70, 0x8a, 0x3c, 0xda, 0x84, 0x51, 0x56, 0xc6, 0xbc, 0xf8, 0xc2, 0x22, 0xd6, 0x20, 0xaf, - 0x35, 0x65, 0x8c, 0xb0, 0x16, 0xd3, 0xc1, 0x3a, 0x51, 0xfb, 0xcb, 0x65, 0xbe, 0xdb, 0x19, 0x2b, - 0xff, 0x14, 0x0c, 0x77, 0xfc, 0xe6, 0xd2, 0x6a, 0x15, 0x8b, 0x59, 0x50, 0xd7, 0x48, 0x8d, 0x17, - 0x63, 0x09, 0x47, 0x17, 0x61, 0x44, 0xfc, 0x94, 0x2a, 0x42, 0x76, 0x36, 0x0b, 0xbc, 0x10, 0x2b, - 0x28, 0x7a, 0x0e, 0xa0, 0x13, 0xf8, 0x7b, 0x6e, 0x93, 0x45, 0x97, 0x28, 0x9b, 0x76, 0x44, 0x35, - 0x05, 0xc1, 0x1a, 0x16, 0x7a, 0x05, 0xc6, 0xbb, 0x5e, 0xc8, 0xd9, 0x11, 0x2d, 0x96, 0xac, 0xb2, - 0x70, 0xb9, 0xa9, 0x03, 0xb1, 0x89, 0x8b, 0x16, 0x60, 0x28, 0x72, 0x98, 0x5d, 0xcc, 0x60, 0xbe, - 0xb9, 0xef, 0x06, 0xc5, 0xd0, 0x93, 0x83, 0xd0, 0x0a, 0x58, 0x54, 0x44, 0x9f, 0x90, 0x0e, 0xb5, - 0xfc, 0x60, 0x17, 0x76, 0xf6, 0xfd, 0x5d, 0x02, 0x9a, 0x3b, 0xad, 0xb0, 0xdf, 0x37, 0x68, 0xa1, - 0x97, 0x01, 0xc8, 0xdd, 0x88, 0x04, 0x9e, 0xd3, 0x52, 0xd6, 0x6c, 0x8a, 0x2f, 0xa8, 0xfa, 0xeb, - 0x7e, 0x74, 0x33, 0x24, 0xcb, 0x0a, 0x03, 0x6b, 0xd8, 0xf6, 0xaf, 0x57, 0x00, 0x62, 0xbe, 0x1d, - 0xbd, 0x95, 0x3a, 0xb8, 0x9e, 0x29, 0xe6, 0xf4, 0x8f, 0xee, 0xd4, 0x42, 0xdf, 0x67, 0xc1, 0xa8, - 0xd3, 0x6a, 0xf9, 0x0d, 0x87, 0x47, 0xfb, 0x2d, 0x15, 0x1f, 0x9c, 0xa2, 0xfd, 0x85, 0xb8, 0x06, - 0xef, 0xc2, 0xf3, 0x72, 0x85, 0x6a, 0x90, 0x9e, 0xbd, 0xd0, 0x1b, 0x46, 0x1f, 0x90, 0x4f, 0xc5, - 0xb2, 0x31, 0x94, 0xea, 0xa9, 0x58, 0x61, 0x77, 0x84, 0xfe, 0x4a, 0xbc, 0x69, 0xbc, 0x12, 0x07, - 0xf2, 0x3d, 0x06, 0x0d, 0xf6, 0xb5, 0xd7, 0x03, 0x11, 0xd5, 0xf4, 0xe8, 0x01, 0x83, 0xf9, 0xee, - 0x79, 0xda, 0x3b, 0xa9, 0x47, 0xe4, 0x80, 0xcf, 0xc0, 0x64, 0xd3, 0x64, 0x02, 0xc4, 0x4a, 0x7c, - 0x32, 0x8f, 0x6e, 0x82, 0x67, 0x88, 0xaf, 0xfd, 0x04, 0x00, 0x27, 0x09, 0xa3, 0x1a, 0x0f, 0x26, - 0xb1, 0xea, 0x6d, 0xf9, 0xc2, 0xd7, 0xc3, 0xce, 0x9d, 0xcb, 0xfd, 0x30, 0x22, 0x6d, 0x8a, 0x19, - 0xdf, 0xee, 0xeb, 0xa2, 0x2e, 0x56, 0x54, 0xd0, 0x6b, 0x30, 0xc4, 0xfc, 0xb3, 0xc2, 0x99, 0x91, - 0x7c, 0x89, 0xb3, 0x19, 0x1d, 0x2d, 0xde, 0x90, 0xec, 0x6f, 0x88, 0x05, 0x05, 0x74, 0x55, 0x7a, - 0x3f, 0x86, 0xab, 0xde, 0xcd, 0x90, 0x30, 0xef, 0xc7, 0xca, 0xe2, 0x7b, 0x63, 0xc7, 0x46, 0x5e, - 0x9e, 0x99, 0x42, 0xcc, 0xa8, 0x49, 0xb9, 0x28, 0xf1, 0x5f, 0x66, 0x26, 0x9b, 0x81, 0xfc, 0xee, - 0x99, 0xd9, 0xcb, 0xe2, 0xe1, 0xbc, 0x65, 0x92, 0xc0, 0x49, 0x9a, 0x94, 0x23, 0xe5, 0xbb, 0x5e, - 0x78, 0x8b, 0xf4, 0x3a, 0x3b, 0xf8, 0x43, 0x9c, 0xdd, 0x46, 0xbc, 0x04, 0x8b, 0xfa, 0xc7, 0xca, - 0x1e, 0xcc, 0x7a, 0x30, 0x95, 0xdc, 0xa2, 0x0f, 0x95, 0x1d, 0xf9, 0x83, 0x01, 0x98, 0x30, 0x97, - 0x14, 0xba, 0x04, 0x15, 0x41, 0x44, 0x65, 0x13, 0x50, 0xbb, 0x64, 0x4d, 0x02, 0x70, 0x8c, 0xc3, - 0x92, 0x48, 0xb0, 0xea, 0x9a, 0x79, 0x70, 0x9c, 0x44, 0x42, 0x41, 0xb0, 0x86, 0x45, 0x1f, 0x56, - 0x9b, 0xbe, 0x1f, 0xa9, 0x0b, 0x49, 0xad, 0xbb, 0x45, 0x56, 0x8a, 0x05, 0x94, 0x5e, 0x44, 0xbb, - 0x24, 0xf0, 0x48, 0xcb, 0x8c, 0x3b, 0xac, 0x2e, 0xa2, 0x6b, 0x3a, 0x10, 0x9b, 0xb8, 0xf4, 0x3a, - 0xf5, 0x43, 0xb6, 0x90, 0xc5, 0xf3, 0x2d, 0x36, 0xb7, 0xae, 0x73, 0x07, 0x6c, 0x09, 0x47, 0x1f, - 0x87, 0x47, 0x54, 0x6c, 0x25, 0xcc, 0xb5, 0x19, 0xb2, 0xc5, 0x21, 0x43, 0xda, 0xf2, 0xc8, 0x52, - 0x36, 0x1a, 0xce, 0xab, 0x8f, 0x5e, 0x85, 0x09, 0xc1, 0xe2, 0x4b, 0x8a, 0xc3, 0xa6, 0x85, 0xd1, - 0x35, 0x03, 0x8a, 0x13, 0xd8, 0x32, 0x72, 0x32, 0xe3, 0xb2, 0x25, 0x85, 0x91, 0x74, 0xe4, 0x64, - 0x1d, 0x8e, 0x53, 0x35, 0xd0, 0x02, 0x4c, 0x72, 0x1e, 0xcc, 0xf5, 0xb6, 0xf9, 0x9c, 0x08, 0x67, - 0x2e, 0xb5, 0xa5, 0x6e, 0x98, 0x60, 0x9c, 0xc4, 0x47, 0x2f, 0xc1, 0x98, 0x13, 0x34, 0x76, 0xdc, - 0x88, 0x34, 0xa2, 0x6e, 0xc0, 0xbd, 0xbc, 0x34, 0x13, 0xad, 0x05, 0x0d, 0x86, 0x0d, 0x4c, 0xfb, - 0x2d, 0x38, 0x91, 0x11, 0x99, 0x81, 0x2e, 0x1c, 0xa7, 0xe3, 0xca, 0x6f, 0x4a, 0x58, 0x38, 0x2f, - 0xd4, 0x56, 0xe5, 0xd7, 0x68, 0x58, 0x74, 0x75, 0xb2, 0x08, 0x0e, 0x5a, 0x22, 0x42, 0xb5, 0x3a, - 0x57, 0x24, 0x00, 0xc7, 0x38, 0xf6, 0xff, 0x2c, 0xc1, 0x64, 0x86, 0x6e, 0x85, 0x25, 0xc3, 0x4b, - 0x3c, 0x52, 0xe2, 0xdc, 0x77, 0x66, 0x20, 0xee, 0xd2, 0x21, 0x02, 0x71, 0x97, 0x7b, 0x05, 0xe2, - 0x1e, 0x78, 0x3b, 0x81, 0xb8, 0xcd, 0x11, 0x1b, 0xec, 0x6b, 0xc4, 0x32, 0x82, 0x77, 0x0f, 0x1d, - 0x32, 0x78, 0xb7, 0x31, 0xe8, 0xc3, 0x7d, 0x0c, 0xfa, 0x8f, 0x96, 0x60, 0x2a, 0x69, 0x4a, 0x7a, - 0x0c, 0x72, 0xdb, 0xd7, 0x0c, 0xb9, 0xed, 0xc5, 0x7e, 0x9c, 0x6f, 0x73, 0x65, 0xb8, 0x38, 0x21, - 0xc3, 0x7d, 0x7f, 0x5f, 0xd4, 0x8a, 0xe5, 0xb9, 0x7f, 0xab, 0x04, 0xa7, 0x32, 0xbd, 0x7f, 0x8f, - 0x61, 0x6c, 0x6e, 0x18, 0x63, 0xf3, 0x6c, 0xdf, 0x8e, 0xc9, 0xb9, 0x03, 0x74, 0x3b, 0x31, 0x40, - 0x97, 0xfa, 0x27, 0x59, 0x3c, 0x4a, 0x5f, 0x2b, 0xc3, 0xb9, 0xcc, 0x7a, 0xb1, 0xd8, 0x73, 0xc5, - 0x10, 0x7b, 0x3e, 0x97, 0x10, 0x7b, 0xda, 0xc5, 0xb5, 0x8f, 0x46, 0x0e, 0x2a, 0x1c, 0x74, 0x59, - 0x98, 0x81, 0x07, 0x94, 0x81, 0x1a, 0x0e, 0xba, 0x8a, 0x10, 0x36, 0xe9, 0x7e, 0x2b, 0xc9, 0x3e, - 0xff, 0xbd, 0x05, 0x67, 0x32, 0xe7, 0xe6, 0x18, 0x64, 0x5d, 0xeb, 0xa6, 0xac, 0xeb, 0xa9, 0xbe, - 0x57, 0x6b, 0x8e, 0xf0, 0xeb, 0xcb, 0x83, 0x39, 0xdf, 0xc2, 0x5e, 0xf2, 0x37, 0x60, 0xd4, 0x69, - 0x34, 0x48, 0x18, 0xae, 0xf9, 0x4d, 0x15, 0x6b, 0xf8, 0x59, 0xf6, 0xce, 0x8a, 0x8b, 0xef, 0x1f, - 0xcc, 0xcd, 0x26, 0x49, 0xc4, 0x60, 0xac, 0x53, 0x40, 0x9f, 0x84, 0x91, 0x50, 0xdc, 0x9b, 0x62, - 0xee, 0x9f, 0xef, 0x73, 0x70, 0x9c, 0x4d, 0xd2, 0x32, 0x83, 0x21, 0x29, 0x49, 0x85, 0x22, 0x69, - 0x06, 0x4e, 0x29, 0x1d, 0x69, 0xe0, 0x94, 0xe7, 0x00, 0xf6, 0xd4, 0x63, 0x20, 0x29, 0x7f, 0xd0, - 0x9e, 0x09, 0x1a, 0x16, 0xfa, 0x28, 0x4c, 0x85, 0x3c, 0x5a, 0xe0, 0x52, 0xcb, 0x09, 0x99, 0x1f, - 0x8d, 0x58, 0x85, 0x2c, 0xe0, 0x52, 0x3d, 0x01, 0xc3, 0x29, 0x6c, 0xb4, 0x22, 0x5b, 0x65, 0xa1, - 0x0d, 0xf9, 0xc2, 0xbc, 0x10, 0xb7, 0x28, 0x52, 0xf1, 0x9e, 0x4c, 0x0e, 0x3f, 0x1b, 0x78, 0xad, - 0x26, 0xfa, 0x24, 0x00, 0x5d, 0x3e, 0x42, 0x0e, 0x31, 0x9c, 0x7f, 0x78, 0xd2, 0x53, 0xa5, 0x99, - 0x69, 0xdc, 0xcc, 0x7c, 0x6a, 0xab, 0x8a, 0x08, 0xd6, 0x08, 0xa2, 0x2d, 0x18, 0x8f, 0xff, 0xc5, - 0x99, 0x2a, 0x0f, 0xd9, 0x02, 0x93, 0x7b, 0x57, 0x75, 0x3a, 0xd8, 0x24, 0x6b, 0xff, 0xf8, 0x30, - 0x3c, 0x5a, 0x70, 0x16, 0xa3, 0x05, 0x53, 0xdf, 0xfb, 0x74, 0xf2, 0x11, 0x3f, 0x9b, 0x59, 0xd9, - 0x78, 0xd5, 0x27, 0x96, 0x7c, 0xe9, 0x6d, 0x2f, 0xf9, 0x1f, 0xb2, 0x34, 0xf1, 0x0a, 0xb7, 0x2c, - 0xfd, 0xc8, 0x21, 0xef, 0x98, 0x23, 0x94, 0xb7, 0x6c, 0x65, 0x08, 0x2d, 0x9e, 0xeb, 0xbb, 0x3b, - 0xfd, 0x4b, 0x31, 0xbe, 0x62, 0x01, 0x12, 0xe2, 0x15, 0xd2, 0x54, 0x1b, 0x4a, 0xc8, 0x33, 0xae, - 0x1c, 0xf6, 0xfb, 0x17, 0x52, 0x94, 0xf8, 0x48, 0xbc, 0x2c, 0x2f, 0x83, 0x34, 0x42, 0xcf, 0x31, - 0xc9, 0xe8, 0x1e, 0xfa, 0x38, 0x8b, 0xa6, 0xeb, 0xbe, 0x25, 0x38, 0x20, 0xb1, 0xe1, 0x5e, 0x14, - 0x91, 0x74, 0x55, 0x39, 0x65, 0x75, 0x33, 0xbb, 0xab, 0x23, 0x61, 0x83, 0xd4, 0xf1, 0xbe, 0xbf, - 0xbb, 0xf0, 0x48, 0xce, 0x90, 0x3d, 0xd4, 0x67, 0xf8, 0x6f, 0x59, 0x70, 0xb6, 0x30, 0x2c, 0xcc, - 0x37, 0x21, 0x83, 0x68, 0x7f, 0xce, 0x82, 0xec, 0xc9, 0x36, 0xcc, 0xca, 0x2e, 0x41, 0xa5, 0x41, - 0x0b, 0x35, 0x3f, 0xe0, 0x38, 0x40, 0x82, 0x04, 0xe0, 0x18, 0xc7, 0xb0, 0x1e, 0x2b, 0xf5, 0xb4, - 0x1e, 0xfb, 0x15, 0x0b, 0x52, 0x87, 0xfc, 0x31, 0x70, 0x1b, 0xab, 0x26, 0xb7, 0xf1, 0xde, 0x7e, - 0x46, 0x33, 0x87, 0xd1, 0xf8, 0xe3, 0x49, 0x38, 0x9d, 0xe3, 0x96, 0xb7, 0x07, 0xd3, 0xdb, 0x0d, - 0x62, 0x7a, 0x58, 0x17, 0x45, 0x1e, 0x2a, 0x74, 0xc7, 0x66, 0xc9, 0x61, 0xa7, 0x53, 0x28, 0x38, - 0xdd, 0x04, 0xfa, 0x9c, 0x05, 0x27, 0x9d, 0x3b, 0xe1, 0x32, 0xe5, 0x1a, 0xdd, 0xc6, 0x62, 0xcb, - 0x6f, 0xec, 0xd2, 0x2b, 0x59, 0x6e, 0x84, 0x17, 0x32, 0x25, 0x79, 0xb7, 0xeb, 0x29, 0x7c, 0xa3, - 0x79, 0x96, 0x2d, 0x37, 0x0b, 0x0b, 0x67, 0xb6, 0x85, 0xb0, 0x48, 0xa1, 0x40, 0xdf, 0xa4, 0x05, - 0x31, 0x00, 0xb2, 0xfc, 0x27, 0x39, 0x1b, 0x24, 0x21, 0x58, 0xd1, 0x41, 0x9f, 0x86, 0xca, 0xb6, - 0x74, 0xf7, 0xcd, 0x60, 0xb3, 0xe2, 0x81, 0x2c, 0x76, 0x82, 0xe6, 0xea, 0x78, 0x85, 0x84, 0x63, - 0xa2, 0xe8, 0x55, 0x28, 0x7b, 0x5b, 0x61, 0x51, 0xc2, 0xd9, 0x84, 0xdd, 0x25, 0x8f, 0xb4, 0xb1, - 0xbe, 0x52, 0xc7, 0xb4, 0x22, 0xba, 0x0a, 0xe5, 0x60, 0xb3, 0x29, 0xc4, 0xd0, 0x99, 0x9b, 0x14, - 0x2f, 0x56, 0x73, 0x7a, 0xc5, 0x28, 0xe1, 0xc5, 0x2a, 0xa6, 0x24, 0x50, 0x0d, 0x06, 0x99, 0x2f, - 0x9b, 0x60, 0x6a, 0x32, 0x9f, 0x6f, 0x05, 0x3e, 0xa1, 0x3c, 0x1c, 0x07, 0x43, 0xc0, 0x9c, 0x10, - 0xda, 0x80, 0xa1, 0x06, 0x4b, 0x4e, 0x2a, 0xb8, 0x98, 0x0f, 0x64, 0x0a, 0x9c, 0x0b, 0xb2, 0xb6, - 0x0a, 0xf9, 0x2b, 0xc3, 0xc0, 0x82, 0x16, 0xa3, 0x4a, 0x3a, 0x3b, 0x5b, 0xa1, 0x48, 0xa6, 0x9d, - 0x4d, 0xb5, 0x20, 0x19, 0xb1, 0xa0, 0xca, 0x30, 0xb0, 0xa0, 0x85, 0x5e, 0x86, 0xd2, 0x56, 0x43, - 0xf8, 0xa9, 0x65, 0x4a, 0x9e, 0xcd, 0x60, 0x29, 0x8b, 0x43, 0xf7, 0x0e, 0xe6, 0x4a, 0x2b, 0x4b, - 0xb8, 0xb4, 0xd5, 0x40, 0xeb, 0x30, 0xbc, 0xc5, 0xc3, 0x2b, 0x08, 0xe1, 0xf2, 0x93, 0xd9, 0x91, - 0x1f, 0x52, 0x11, 0x18, 0xb8, 0xcf, 0x93, 0x00, 0x60, 0x49, 0x84, 0x65, 0x24, 0x50, 0x61, 0x22, - 0x44, 0x94, 0xba, 0xf9, 0xc3, 0x85, 0xf6, 0xe0, 0x4c, 0x66, 0x1c, 0x6c, 0x02, 0x6b, 0x14, 0xe9, - 0xaa, 0x76, 0xde, 0xea, 0x06, 0x2c, 0x14, 0xb8, 0x08, 0x67, 0x94, 0xb9, 0xaa, 0x17, 0x24, 0x52, - 0xd1, 0xaa, 0x56, 0x48, 0x38, 0x26, 0x8a, 0x76, 0x61, 0x7c, 0x2f, 0xec, 0xec, 0x10, 0xb9, 0xa5, - 0x59, 0x74, 0xa3, 0x1c, 0xfe, 0xe8, 0x96, 0x40, 0x74, 0x83, 0xa8, 0xeb, 0xb4, 0x52, 0xa7, 0x10, - 0xe3, 0x65, 0x6f, 0xe9, 0xc4, 0xb0, 0x49, 0x9b, 0x0e, 0xff, 0x9b, 0x5d, 0x7f, 0x73, 0x3f, 0x22, - 0x22, 0xb8, 0x5c, 0xe6, 0xf0, 0xbf, 0xce, 0x51, 0xd2, 0xc3, 0x2f, 0x00, 0x58, 0x12, 0x41, 0xb7, - 0xc4, 0xf0, 0xb0, 0xd3, 0x73, 0x2a, 0x3f, 0x02, 0xec, 0x82, 0x44, 0xca, 0x19, 0x14, 0x76, 0x5a, - 0xc6, 0xa4, 0xd8, 0x29, 0xd9, 0xd9, 0xf1, 0x23, 0xdf, 0x4b, 0x9c, 0xd0, 0xd3, 0xf9, 0xa7, 0x64, - 0x2d, 0x03, 0x3f, 0x7d, 0x4a, 0x66, 0x61, 0xe1, 0xcc, 0xb6, 0x50, 0x13, 0x26, 0x3a, 0x7e, 0x10, - 0xdd, 0xf1, 0x03, 0xb9, 0xbe, 0x50, 0x81, 0x70, 0xcc, 0xc0, 0x14, 0x2d, 0xb2, 0xb8, 0x8d, 0x26, - 0x04, 0x27, 0x68, 0xa2, 0x8f, 0xc1, 0x70, 0xd8, 0x70, 0x5a, 0x64, 0xf5, 0xc6, 0xcc, 0x89, 0xfc, - 0xeb, 0xa7, 0xce, 0x51, 0x72, 0x56, 0x17, 0x8f, 0x8e, 0xc1, 0x51, 0xb0, 0x24, 0x87, 0x56, 0x60, - 0x90, 0x65, 0x9c, 0x63, 0x91, 0x10, 0x73, 0x02, 0xd9, 0xa6, 0xac, 0xe0, 0xf9, 0xd9, 0xc4, 0x8a, - 0x31, 0xaf, 0x4e, 0xf7, 0x80, 0x78, 0x23, 0xfa, 0xe1, 0xcc, 0xa9, 0xfc, 0x3d, 0x20, 0x9e, 0x96, - 0x37, 0xea, 0x45, 0x7b, 0x40, 0x21, 0xe1, 0x98, 0x28, 0x3d, 0x99, 0xe9, 0x69, 0x7a, 0xba, 0xc0, - 0x7c, 0x2b, 0xf7, 0x2c, 0x65, 0x27, 0x33, 0x3d, 0x49, 0x29, 0x09, 0xfb, 0xf7, 0x86, 0xd3, 0x3c, - 0x0b, 0x93, 0x2a, 0x7c, 0x8f, 0x95, 0x52, 0x38, 0x7f, 0xb0, 0x5f, 0x21, 0xe7, 0x11, 0x3e, 0x85, - 0x3e, 0x67, 0xc1, 0xe9, 0x4e, 0xe6, 0x87, 0x08, 0x06, 0xa0, 0x3f, 0x59, 0x29, 0xff, 0x74, 0x15, - 0x35, 0x33, 0x1b, 0x8e, 0x73, 0x5a, 0x4a, 0x3e, 0x37, 0xcb, 0x6f, 0xfb, 0xb9, 0xb9, 0x06, 0x23, - 0x0d, 0xfe, 0x14, 0x29, 0x4c, 0xd6, 0x9d, 0x7c, 0x7b, 0x33, 0x56, 0x42, 0xbc, 0x61, 0xb6, 0xb0, - 0x22, 0x81, 0x7e, 0xd8, 0x82, 0xb3, 0xc9, 0xae, 0x63, 0xc2, 0xc0, 0x22, 0xd4, 0x26, 0x17, 0x68, - 0xac, 0x88, 0xef, 0x4f, 0xf1, 0xff, 0x06, 0xf2, 0xfd, 0x5e, 0x08, 0xb8, 0xb8, 0x31, 0x54, 0xcd, - 0x90, 0xa8, 0x0c, 0x99, 0x5a, 0xa4, 0x3e, 0xa4, 0x2a, 0x2f, 0xc0, 0x58, 0xdb, 0xef, 0x7a, 0x91, - 0xb0, 0xf6, 0x12, 0x96, 0x27, 0xcc, 0xe2, 0x62, 0x4d, 0x2b, 0xc7, 0x06, 0x56, 0x42, 0x16, 0x33, - 0xf2, 0xc0, 0xb2, 0x98, 0x37, 0x60, 0xcc, 0xd3, 0xcc, 0x93, 0x05, 0x3f, 0x70, 0x21, 0x3f, 0x4c, - 0xae, 0x6e, 0xcc, 0xcc, 0x7b, 0xa9, 0x97, 0x60, 0x83, 0xda, 0xf1, 0x9a, 0x81, 0x7d, 0xc9, 0xca, - 0x60, 0xea, 0xb9, 0x28, 0xe6, 0xc3, 0xa6, 0x28, 0xe6, 0x42, 0x52, 0x14, 0x93, 0xd2, 0x20, 0x18, - 0x52, 0x98, 0xfe, 0xb3, 0x00, 0xf5, 0x1b, 0x6a, 0xd3, 0x6e, 0xc1, 0xf9, 0x5e, 0xd7, 0x12, 0x33, - 0xfb, 0x6b, 0x2a, 0x7d, 0x71, 0x6c, 0xf6, 0xd7, 0x5c, 0xad, 0x62, 0x06, 0xe9, 0x37, 0x88, 0x93, - 0xfd, 0xdf, 0x2d, 0x28, 0xd7, 0xfc, 0xe6, 0x31, 0x3c, 0x78, 0x3f, 0x62, 0x3c, 0x78, 0x1f, 0xcd, - 0xbe, 0x10, 0x9b, 0xb9, 0xfa, 0x8f, 0xe5, 0x84, 0xfe, 0xe3, 0x6c, 0x1e, 0x81, 0x62, 0x6d, 0xc7, - 0x4f, 0x95, 0x61, 0xb4, 0xe6, 0x37, 0x95, 0xcd, 0xfd, 0xbf, 0x7a, 0x10, 0x9b, 0xfb, 0xdc, 0x5c, - 0x16, 0x1a, 0x65, 0x66, 0x2d, 0x28, 0xdd, 0x8d, 0xbf, 0xc9, 0x4c, 0xef, 0x6f, 0x13, 0x77, 0x7b, - 0x27, 0x22, 0xcd, 0xe4, 0xe7, 0x1c, 0x9f, 0xe9, 0xfd, 0xef, 0x95, 0x60, 0x32, 0xd1, 0x3a, 0x6a, - 0xc1, 0x78, 0x4b, 0x97, 0xae, 0x8b, 0x75, 0xfa, 0x40, 0x82, 0x79, 0x61, 0xba, 0xac, 0x15, 0x61, - 0x93, 0x38, 0x9a, 0x07, 0x50, 0xea, 0x66, 0x29, 0x5e, 0x65, 0x5c, 0xbf, 0xd2, 0x47, 0x87, 0x58, - 0xc3, 0x40, 0x2f, 0xc2, 0x68, 0xe4, 0x77, 0xfc, 0x96, 0xbf, 0xbd, 0x7f, 0x8d, 0xc8, 0xf8, 0x5e, - 0xca, 0x20, 0x71, 0x23, 0x06, 0x61, 0x1d, 0x0f, 0xdd, 0x85, 0x69, 0x45, 0xa4, 0x7e, 0x04, 0x1a, - 0x07, 0x26, 0x55, 0x58, 0x4f, 0x52, 0xc4, 0xe9, 0x46, 0xec, 0x9f, 0x29, 0xf3, 0x21, 0xf6, 0x22, - 0xf7, 0xdd, 0xdd, 0xf0, 0xce, 0xde, 0x0d, 0x5f, 0xb3, 0x60, 0x8a, 0xb6, 0xce, 0xac, 0xad, 0xe4, - 0x35, 0xaf, 0x02, 0x73, 0x5b, 0x05, 0x81, 0xb9, 0x2f, 0xd0, 0x53, 0xb3, 0xe9, 0x77, 0x23, 0x21, - 0xbb, 0xd3, 0x8e, 0x45, 0x5a, 0x8a, 0x05, 0x54, 0xe0, 0x91, 0x20, 0x10, 0x1e, 0xa2, 0x3a, 0x1e, - 0x09, 0x02, 0x2c, 0xa0, 0x32, 0x6e, 0xf7, 0x40, 0x76, 0xdc, 0x6e, 0x1e, 0x7e, 0x55, 0xd8, 0xe5, - 0x08, 0x86, 0x4b, 0x0b, 0xbf, 0x2a, 0x0d, 0x76, 0x62, 0x1c, 0xfb, 0x2b, 0x65, 0x18, 0xab, 0xf9, - 0xcd, 0x58, 0xd5, 0xfc, 0x82, 0xa1, 0x6a, 0x3e, 0x9f, 0x50, 0x35, 0x4f, 0xe9, 0xb8, 0xef, 0x2a, - 0x96, 0xbf, 0x51, 0x8a, 0xe5, 0x7f, 0x6e, 0xb1, 0x59, 0xab, 0xae, 0xd7, 0xb9, 0xf1, 0x1e, 0xba, - 0x0c, 0xa3, 0xec, 0x80, 0x61, 0x2e, 0xc9, 0x52, 0xff, 0xca, 0xf2, 0x51, 0xad, 0xc7, 0xc5, 0x58, - 0xc7, 0x41, 0x17, 0x61, 0x24, 0x24, 0x4e, 0xd0, 0xd8, 0x51, 0xa7, 0xab, 0x50, 0x96, 0xf2, 0x32, - 0xac, 0xa0, 0xe8, 0xf5, 0x38, 0xf2, 0x67, 0x39, 0xdf, 0xc5, 0x51, 0xef, 0x0f, 0xdf, 0x22, 0xf9, - 0xe1, 0x3e, 0xed, 0xdb, 0x80, 0xd2, 0xf8, 0x7d, 0xc4, 0xa6, 0x9b, 0x33, 0x63, 0xd3, 0x55, 0x52, - 0x71, 0xe9, 0xfe, 0xcc, 0x82, 0x89, 0x9a, 0xdf, 0xa4, 0x5b, 0xf7, 0x5b, 0x69, 0x9f, 0xea, 0x61, - 0x8f, 0x87, 0x0a, 0xc2, 0x1e, 0x3f, 0x01, 0x83, 0x35, 0xbf, 0xb9, 0x5a, 0x2b, 0x8a, 0x2f, 0x60, - 0xff, 0x6d, 0x0b, 0x86, 0x6b, 0x7e, 0xf3, 0x18, 0xd4, 0x02, 0x1f, 0x36, 0xd5, 0x02, 0x8f, 0xe4, - 0xac, 0x9b, 0x1c, 0x4d, 0xc0, 0xdf, 0x1c, 0x80, 0x71, 0xda, 0x4f, 0x7f, 0x5b, 0x4e, 0xa5, 0x31, - 0x6c, 0x56, 0x1f, 0xc3, 0x46, 0xb9, 0x70, 0xbf, 0xd5, 0xf2, 0xef, 0x24, 0xa7, 0x75, 0x85, 0x95, - 0x62, 0x01, 0x45, 0xcf, 0xc0, 0x48, 0x27, 0x20, 0x7b, 0xae, 0x2f, 0xd8, 0x5b, 0x4d, 0xc9, 0x52, - 0x13, 0xe5, 0x58, 0x61, 0xd0, 0x67, 0x61, 0xe8, 0x7a, 0xf4, 0x2a, 0x6f, 0xf8, 0x5e, 0x93, 0x4b, - 0xce, 0xcb, 0x22, 0x37, 0x87, 0x56, 0x8e, 0x0d, 0x2c, 0x74, 0x1b, 0x2a, 0xec, 0x3f, 0x3b, 0x76, - 0x0e, 0x9f, 0xe5, 0x55, 0x64, 0xfd, 0x13, 0x04, 0x70, 0x4c, 0x0b, 0x3d, 0x07, 0x10, 0xc9, 0xf8, - 0xf6, 0xa1, 0x88, 0xb6, 0xa6, 0x9e, 0x02, 0x2a, 0xf2, 0x7d, 0x88, 0x35, 0x2c, 0xf4, 0x34, 0x54, - 0x22, 0xc7, 0x6d, 0x5d, 0x77, 0x3d, 0x12, 0x32, 0x89, 0x78, 0x59, 0x26, 0xdf, 0x13, 0x85, 0x38, - 0x86, 0x53, 0x56, 0x8c, 0x45, 0xe2, 0xe0, 0x39, 0xa2, 0x47, 0x18, 0x36, 0x63, 0xc5, 0xae, 0xab, - 0x52, 0xac, 0x61, 0xa0, 0x1d, 0x78, 0xcc, 0xf5, 0x58, 0x1e, 0x0b, 0x52, 0xdf, 0x75, 0x3b, 0x1b, - 0xd7, 0xeb, 0xb7, 0x48, 0xe0, 0x6e, 0xed, 0x2f, 0x3a, 0x8d, 0x5d, 0xe2, 0xc9, 0xfc, 0x9d, 0xef, - 0x15, 0x5d, 0x7c, 0x6c, 0xb5, 0x00, 0x17, 0x17, 0x52, 0xb2, 0x9f, 0x67, 0xeb, 0xfd, 0x46, 0x1d, - 0xbd, 0xdf, 0x38, 0x3a, 0x4e, 0xeb, 0x47, 0xc7, 0xfd, 0x83, 0xb9, 0xa1, 0x1b, 0x75, 0x2d, 0x90, - 0xc4, 0x4b, 0x70, 0xaa, 0xe6, 0x37, 0x6b, 0x7e, 0x10, 0xad, 0xf8, 0xc1, 0x1d, 0x27, 0x68, 0xca, - 0xe5, 0x35, 0x27, 0x43, 0x69, 0xd0, 0xf3, 0x73, 0x90, 0x9f, 0x2e, 0x46, 0x98, 0x8c, 0xe7, 0x19, - 0xc7, 0x76, 0x48, 0x07, 0xb0, 0x06, 0xe3, 0x1d, 0x54, 0x26, 0x98, 0x2b, 0x4e, 0x44, 0xd0, 0x0d, - 0x96, 0xe1, 0x3a, 0xbe, 0x46, 0x45, 0xf5, 0xa7, 0xb4, 0x0c, 0xd7, 0x31, 0x30, 0xf3, 0xde, 0x35, - 0xeb, 0xdb, 0xff, 0x63, 0x90, 0x9d, 0xa8, 0x89, 0x6c, 0x22, 0xe8, 0x53, 0x30, 0x11, 0x92, 0xeb, - 0xae, 0xd7, 0xbd, 0x2b, 0x45, 0x18, 0x05, 0x2e, 0x7c, 0xf5, 0x65, 0x1d, 0x93, 0x0b, 0x42, 0xcd, - 0x32, 0x9c, 0xa0, 0x86, 0xda, 0x30, 0x71, 0xc7, 0xf5, 0x9a, 0xfe, 0x9d, 0x50, 0xd2, 0x1f, 0xc9, - 0x97, 0x87, 0xde, 0xe6, 0x98, 0x89, 0x3e, 0x1a, 0xcd, 0xdd, 0x36, 0x88, 0xe1, 0x04, 0x71, 0xba, - 0x6a, 0x83, 0xae, 0xb7, 0x10, 0xde, 0x0c, 0x49, 0x20, 0x72, 0x95, 0xb3, 0x55, 0x8b, 0x65, 0x21, - 0x8e, 0xe1, 0x74, 0xd5, 0xb2, 0x3f, 0x57, 0x02, 0xbf, 0xcb, 0x53, 0x57, 0x88, 0x55, 0x8b, 0x55, - 0x29, 0xd6, 0x30, 0xe8, 0xae, 0x66, 0xff, 0xd6, 0x7d, 0x0f, 0xfb, 0x7e, 0x24, 0xcf, 0x01, 0xa6, - 0xd3, 0xd7, 0xca, 0xb1, 0x81, 0x85, 0x56, 0x00, 0x85, 0xdd, 0x4e, 0xa7, 0xc5, 0x6c, 0x83, 0x9c, - 0x16, 0x23, 0xc5, 0xed, 0x25, 0xca, 0x3c, 0xf4, 0x6e, 0x3d, 0x05, 0xc5, 0x19, 0x35, 0xe8, 0x01, - 0xbf, 0x25, 0xba, 0x3a, 0xc8, 0xba, 0xca, 0x75, 0x27, 0x75, 0xde, 0x4f, 0x09, 0x43, 0xcb, 0x30, - 0x1c, 0xee, 0x87, 0x8d, 0x48, 0x44, 0x4a, 0xcc, 0x49, 0x18, 0x55, 0x67, 0x28, 0x5a, 0xbe, 0x42, - 0x5e, 0x05, 0xcb, 0xba, 0xa8, 0x01, 0x27, 0x04, 0xc5, 0xa5, 0x1d, 0xc7, 0x53, 0xe9, 0x77, 0xb8, - 0x89, 0xf4, 0xe5, 0x7b, 0x07, 0x73, 0x27, 0x44, 0xcb, 0x3a, 0xf8, 0xfe, 0xc1, 0xdc, 0xe9, 0x9a, - 0xdf, 0xcc, 0x80, 0xe0, 0x2c, 0x6a, 0x7c, 0xf1, 0x35, 0x1a, 0x7e, 0xbb, 0x53, 0x0b, 0xfc, 0x2d, - 0xb7, 0x45, 0x8a, 0xf4, 0x4f, 0x75, 0x03, 0x53, 0x2c, 0x3e, 0xa3, 0x0c, 0x27, 0xa8, 0xd9, 0xdf, - 0xc9, 0x98, 0x20, 0x96, 0x9e, 0x3b, 0xea, 0x06, 0x04, 0xb5, 0x61, 0xbc, 0xc3, 0xb6, 0x89, 0x48, - 0x28, 0x21, 0xd6, 0xfa, 0x0b, 0x7d, 0xca, 0x51, 0xee, 0xd0, 0xbb, 0xc3, 0xb4, 0x31, 0xaa, 0xe9, - 0xe4, 0xb0, 0x49, 0xdd, 0xfe, 0x8d, 0x47, 0xd8, 0x35, 0x5a, 0xe7, 0xc2, 0x91, 0x61, 0xe1, 0x91, - 0x21, 0xde, 0x63, 0xb3, 0xf9, 0x52, 0xba, 0x78, 0x5a, 0x84, 0x57, 0x07, 0x96, 0x75, 0xd1, 0x27, - 0x61, 0x82, 0x3e, 0x6f, 0xd4, 0x55, 0x16, 0xce, 0x9c, 0xcc, 0x8f, 0x9c, 0xa1, 0xb0, 0xf4, 0x64, - 0x33, 0x7a, 0x65, 0x9c, 0x20, 0x86, 0x5e, 0x67, 0x36, 0x3d, 0x92, 0x74, 0xa9, 0x1f, 0xd2, 0xba, - 0xf9, 0x8e, 0x24, 0xab, 0x11, 0x41, 0x5d, 0x38, 0x91, 0x4e, 0x4d, 0x17, 0xce, 0xd8, 0xf9, 0x7c, - 0x62, 0x3a, 0xbb, 0x5c, 0x9c, 0x15, 0x24, 0x0d, 0x0b, 0x71, 0x16, 0x7d, 0x74, 0x1d, 0xc6, 0x45, - 0x8e, 0x6a, 0xb1, 0x72, 0xcb, 0x86, 0xf0, 0x70, 0x1c, 0xeb, 0xc0, 0xfb, 0xc9, 0x02, 0x6c, 0x56, - 0x46, 0xdb, 0x70, 0x56, 0xcb, 0x19, 0x75, 0x25, 0x70, 0x98, 0x05, 0x80, 0xcb, 0x8e, 0x53, 0xed, - 0x82, 0x7f, 0xfc, 0xde, 0xc1, 0xdc, 0xd9, 0x8d, 0x22, 0x44, 0x5c, 0x4c, 0x07, 0xdd, 0x80, 0x53, - 0xdc, 0xef, 0xbb, 0x4a, 0x9c, 0x66, 0xcb, 0xf5, 0x14, 0x07, 0xc1, 0xb7, 0xfc, 0x99, 0x7b, 0x07, - 0x73, 0xa7, 0x16, 0xb2, 0x10, 0x70, 0x76, 0x3d, 0xf4, 0x61, 0xa8, 0x34, 0xbd, 0x50, 0x8c, 0xc1, - 0x90, 0x91, 0x96, 0xab, 0x52, 0x5d, 0xaf, 0xab, 0xef, 0x8f, 0xff, 0xe0, 0xb8, 0x02, 0xda, 0xe6, - 0x02, 0x66, 0x25, 0xf6, 0x18, 0x4e, 0xc5, 0xbd, 0x4a, 0x4a, 0x06, 0x0d, 0xcf, 0x4f, 0xae, 0x59, - 0x51, 0x0e, 0x11, 0x86, 0x53, 0xa8, 0x41, 0x18, 0xbd, 0x06, 0x48, 0x84, 0x7f, 0x5f, 0x68, 0xb0, - 0x6c, 0x25, 0x4c, 0x1e, 0x3f, 0x62, 0xfa, 0x22, 0xd6, 0x53, 0x18, 0x38, 0xa3, 0x16, 0xba, 0x4a, - 0x4f, 0x15, 0xbd, 0x54, 0x9c, 0x5a, 0x2a, 0x89, 0x62, 0x95, 0x74, 0x02, 0xc2, 0x2c, 0x9a, 0x4c, - 0x8a, 0x38, 0x51, 0x0f, 0x35, 0xe1, 0x31, 0xa7, 0x1b, 0xf9, 0x4c, 0x76, 0x6f, 0xa2, 0x6e, 0xf8, - 0xbb, 0xc4, 0x63, 0x6a, 0xb3, 0x91, 0xc5, 0xf3, 0x94, 0x45, 0x59, 0x28, 0xc0, 0xc3, 0x85, 0x54, - 0x28, 0x6b, 0xa9, 0xb2, 0x26, 0x83, 0x19, 0xcd, 0x2b, 0x23, 0x73, 0xf2, 0x8b, 0x30, 0xba, 0xe3, - 0x87, 0xd1, 0x3a, 0x89, 0xee, 0xf8, 0xc1, 0xae, 0x88, 0x4a, 0x1b, 0xc7, 0xf8, 0x8e, 0x41, 0x58, - 0xc7, 0xa3, 0x6f, 0x47, 0x66, 0xd4, 0xb1, 0x5a, 0x65, 0xfa, 0xf4, 0x91, 0xf8, 0x8c, 0xb9, 0xca, - 0x8b, 0xb1, 0x84, 0x4b, 0xd4, 0xd5, 0xda, 0x12, 0xd3, 0x8d, 0x27, 0x50, 0x57, 0x6b, 0x4b, 0x58, - 0xc2, 0xe9, 0x72, 0x0d, 0x77, 0x9c, 0x80, 0xd4, 0x02, 0xbf, 0x41, 0x42, 0x2d, 0xb2, 0xfc, 0xa3, - 0x3c, 0xe6, 0x2e, 0x5d, 0xae, 0xf5, 0x2c, 0x04, 0x9c, 0x5d, 0x0f, 0x91, 0x74, 0xbe, 0xb4, 0x89, - 0x7c, 0xa5, 0x46, 0x9a, 0x9f, 0xe9, 0x33, 0x65, 0x9a, 0x07, 0x53, 0x2a, 0x53, 0x1b, 0x8f, 0xb2, - 0x1b, 0xce, 0x4c, 0xb2, 0xb5, 0xdd, 0x7f, 0x88, 0x5e, 0xa5, 0x26, 0x5a, 0x4d, 0x50, 0xc2, 0x29, - 0xda, 0x46, 0xc0, 0xb6, 0xa9, 0x9e, 0x01, 0xdb, 0x2e, 0x41, 0x25, 0xec, 0x6e, 0x36, 0xfd, 0xb6, - 0xe3, 0x7a, 0x4c, 0x37, 0xae, 0x3d, 0x62, 0xea, 0x12, 0x80, 0x63, 0x1c, 0xb4, 0x02, 0x23, 0x8e, - 0xd4, 0x01, 0xa1, 0xfc, 0x10, 0x3d, 0x4a, 0xf3, 0xc3, 0xa3, 0x56, 0x48, 0xad, 0x8f, 0xaa, 0x8b, - 0x5e, 0x81, 0x71, 0xe1, 0xb7, 0x2c, 0x92, 0x84, 0x9e, 0x30, 0x9d, 0xcb, 0xea, 0x3a, 0x10, 0x9b, - 0xb8, 0xe8, 0x26, 0x8c, 0x46, 0x7e, 0x8b, 0x79, 0x48, 0x51, 0x36, 0xef, 0x74, 0x7e, 0xb0, 0xb9, - 0x0d, 0x85, 0xa6, 0x8b, 0x5f, 0x55, 0x55, 0xac, 0xd3, 0x41, 0x1b, 0x7c, 0xbd, 0xb3, 0x38, 0xf2, - 0x24, 0x9c, 0x79, 0x24, 0xff, 0x4e, 0x52, 0xe1, 0xe6, 0xcd, 0xed, 0x20, 0x6a, 0x62, 0x9d, 0x0c, - 0xba, 0x02, 0xd3, 0x9d, 0xc0, 0xf5, 0xd9, 0x9a, 0x50, 0xea, 0xbf, 0x19, 0x33, 0x6b, 0x54, 0x2d, - 0x89, 0x80, 0xd3, 0x75, 0x98, 0xdb, 0xb9, 0x28, 0x9c, 0x39, 0xc3, 0x33, 0x5f, 0xf0, 0x37, 0x21, - 0x2f, 0xc3, 0x0a, 0x8a, 0xd6, 0xd8, 0x49, 0xcc, 0xc5, 0x19, 0x33, 0xb3, 0xf9, 0x51, 0x81, 0x74, - 0xb1, 0x07, 0x67, 0x5e, 0xd5, 0x5f, 0x1c, 0x53, 0x40, 0x4d, 0x2d, 0xe1, 0x24, 0x7d, 0x31, 0x84, - 0x33, 0x8f, 0x15, 0x58, 0xd6, 0x25, 0x9e, 0x17, 0x31, 0x43, 0x60, 0x14, 0x87, 0x38, 0x41, 0x13, - 0x7d, 0x14, 0xa6, 0x44, 0x2c, 0xc3, 0x78, 0x98, 0xce, 0xc6, 0x76, 0xe7, 0x38, 0x01, 0xc3, 0x29, - 0x6c, 0x9e, 0x79, 0xc2, 0xd9, 0x6c, 0x11, 0x71, 0xf4, 0x5d, 0x77, 0xbd, 0xdd, 0x70, 0xe6, 0x1c, - 0x3b, 0x1f, 0x44, 0xe6, 0x89, 0x24, 0x14, 0x67, 0xd4, 0x40, 0x1b, 0x30, 0xd5, 0x09, 0x08, 0x69, - 0x33, 0x46, 0x5f, 0xdc, 0x67, 0x73, 0x3c, 0xea, 0x02, 0xed, 0x49, 0x2d, 0x01, 0xbb, 0x9f, 0x51, - 0x86, 0x53, 0x14, 0xd0, 0x1d, 0x18, 0xf1, 0xf7, 0x48, 0xb0, 0x43, 0x9c, 0xe6, 0xcc, 0xf9, 0x02, - 0x3f, 0x08, 0x71, 0xb9, 0xdd, 0x10, 0xb8, 0x09, 0x93, 0x01, 0x59, 0xdc, 0xdb, 0x64, 0x40, 0x36, - 0x86, 0x7e, 0xc4, 0x82, 0x33, 0x52, 0xcb, 0x50, 0xef, 0xd0, 0x51, 0x5f, 0xf2, 0xbd, 0x30, 0x0a, - 0x78, 0x9c, 0x80, 0xc7, 0xf3, 0x7d, 0xe7, 0x37, 0x72, 0x2a, 0x29, 0x89, 0xea, 0x99, 0x3c, 0x8c, - 0x10, 0xe7, 0xb7, 0x88, 0x96, 0x60, 0x3a, 0x24, 0x91, 0x3c, 0x8c, 0x16, 0xc2, 0x95, 0xd7, 0xab, - 0xeb, 0x33, 0x4f, 0xf0, 0x20, 0x07, 0x74, 0x33, 0xd4, 0x93, 0x40, 0x9c, 0xc6, 0x47, 0x97, 0xa1, - 0xe4, 0x87, 0x33, 0xef, 0x2d, 0xc8, 0x51, 0x4a, 0x9f, 0xe2, 0xdc, 0x74, 0xec, 0x46, 0x1d, 0x97, - 0xfc, 0x70, 0xf6, 0xdb, 0x61, 0x3a, 0xc5, 0x31, 0x1c, 0x26, 0xb7, 0xcf, 0xec, 0x2e, 0x8c, 0x1b, - 0xb3, 0xf2, 0x50, 0xb5, 0xd4, 0xff, 0x76, 0x18, 0x2a, 0x4a, 0x83, 0x89, 0x2e, 0x99, 0x8a, 0xe9, - 0x33, 0x49, 0xc5, 0xf4, 0x48, 0xcd, 0x6f, 0x1a, 0xba, 0xe8, 0x8d, 0x8c, 0x68, 0x70, 0x79, 0x67, - 0x40, 0xff, 0x06, 0xf2, 0x9a, 0x58, 0xb8, 0xdc, 0xb7, 0x86, 0x7b, 0xa0, 0x50, 0xd2, 0x7c, 0x05, - 0xa6, 0x3d, 0x9f, 0xb1, 0xa9, 0xa4, 0x29, 0x79, 0x10, 0xc6, 0x6a, 0x54, 0xf4, 0xf0, 0x2a, 0x09, - 0x04, 0x9c, 0xae, 0x43, 0x1b, 0xe4, 0xbc, 0x42, 0x52, 0xb4, 0xcd, 0x59, 0x09, 0x2c, 0xa0, 0xe8, - 0x09, 0x18, 0xec, 0xf8, 0xcd, 0xd5, 0x9a, 0x60, 0x51, 0xb5, 0x18, 0xa4, 0xcd, 0xd5, 0x1a, 0xe6, - 0x30, 0xb4, 0x00, 0x43, 0xec, 0x47, 0x38, 0x33, 0x96, 0x1f, 0x47, 0x83, 0xd5, 0xd0, 0x32, 0x27, - 0xb1, 0x0a, 0x58, 0x54, 0x64, 0x22, 0x36, 0xca, 0xd7, 0x33, 0x11, 0xdb, 0xf0, 0x03, 0x8a, 0xd8, - 0x24, 0x01, 0x1c, 0xd3, 0x42, 0x77, 0xe1, 0x94, 0xf1, 0x96, 0xe2, 0x4b, 0x84, 0x84, 0xc2, 0x97, - 0xff, 0x89, 0xc2, 0x47, 0x94, 0xd0, 0x88, 0x9f, 0x15, 0x9d, 0x3e, 0xb5, 0x9a, 0x45, 0x09, 0x67, - 0x37, 0x80, 0x5a, 0x30, 0xdd, 0x48, 0xb5, 0x3a, 0xd2, 0x7f, 0xab, 0x6a, 0x42, 0xd3, 0x2d, 0xa6, - 0x09, 0xa3, 0x57, 0x60, 0xe4, 0x4d, 0x3f, 0x64, 0xc7, 0xbb, 0x60, 0xab, 0xa5, 0x23, 0xf8, 0xc8, - 0xeb, 0x37, 0xea, 0xac, 0xfc, 0xfe, 0xc1, 0xdc, 0x68, 0xcd, 0x6f, 0xca, 0xbf, 0x58, 0x55, 0x40, - 0xdf, 0x6f, 0xc1, 0x6c, 0xfa, 0xb1, 0xa6, 0x3a, 0x3d, 0xde, 0x7f, 0xa7, 0x6d, 0xd1, 0xe8, 0xec, - 0x72, 0x2e, 0x39, 0x5c, 0xd0, 0x94, 0xfd, 0x4b, 0x16, 0x13, 0xd4, 0x09, 0x4d, 0x13, 0x09, 0xbb, - 0xad, 0xe3, 0x48, 0x18, 0xbb, 0x6c, 0x28, 0xc1, 0x1e, 0xd8, 0x42, 0xe2, 0x5f, 0x5a, 0xcc, 0x42, - 0xe2, 0x18, 0x5d, 0x21, 0x5e, 0x87, 0x91, 0x48, 0x26, 0xf2, 0x2d, 0xc8, 0x71, 0xab, 0x75, 0x8a, - 0x59, 0x89, 0x28, 0x26, 0x57, 0xe5, 0xec, 0x55, 0x64, 0xec, 0x7f, 0xc2, 0x67, 0x40, 0x42, 0x8e, - 0x41, 0xd7, 0x50, 0x35, 0x75, 0x0d, 0x73, 0x3d, 0xbe, 0x20, 0x47, 0xe7, 0xf0, 0x8f, 0xcd, 0x7e, - 0x33, 0xe1, 0xce, 0x3b, 0xdd, 0x34, 0xc7, 0xfe, 0xbc, 0x05, 0x10, 0x87, 0x78, 0xee, 0x23, 0x55, - 0xdb, 0x4b, 0x94, 0xad, 0xf5, 0x23, 0xbf, 0xe1, 0xb7, 0x84, 0x26, 0xed, 0xb1, 0x58, 0xdd, 0xc1, - 0xcb, 0xef, 0x6b, 0xbf, 0xb1, 0xc2, 0x46, 0x73, 0x32, 0xa0, 0x5c, 0x39, 0x56, 0xc0, 0x19, 0xc1, - 0xe4, 0xbe, 0x68, 0xc1, 0xc9, 0x2c, 0xbb, 0x5a, 0xfa, 0x48, 0xe2, 0x62, 0x2e, 0x65, 0x36, 0xa5, - 0x66, 0xf3, 0x96, 0x28, 0xc7, 0x0a, 0xa3, 0xef, 0x1c, 0x78, 0x87, 0x8b, 0xad, 0x7c, 0x03, 0xc6, - 0x6b, 0x01, 0xd1, 0x2e, 0xd7, 0x57, 0x79, 0x90, 0x02, 0xde, 0x9f, 0x67, 0x0e, 0x1d, 0xa0, 0xc0, - 0xfe, 0x72, 0x09, 0x4e, 0x72, 0xeb, 0x83, 0x85, 0x3d, 0xdf, 0x6d, 0xd6, 0xfc, 0xa6, 0xf0, 0x9e, - 0xfa, 0x04, 0x8c, 0x75, 0x34, 0xd9, 0x64, 0x51, 0x9c, 0x50, 0x5d, 0x86, 0x19, 0x4b, 0x53, 0xf4, - 0x52, 0x6c, 0xd0, 0x42, 0x4d, 0x18, 0x23, 0x7b, 0x6e, 0x43, 0xa9, 0xb0, 0x4b, 0x87, 0xbe, 0xe8, - 0x54, 0x2b, 0xcb, 0x1a, 0x1d, 0x6c, 0x50, 0x7d, 0x08, 0x99, 0xa9, 0xed, 0x1f, 0xb3, 0xe0, 0x91, - 0x9c, 0xa8, 0xa2, 0xb4, 0xb9, 0x3b, 0xcc, 0xce, 0x43, 0x2c, 0x5b, 0xd5, 0x1c, 0xb7, 0xfe, 0xc0, - 0x02, 0x8a, 0x3e, 0x06, 0xc0, 0xad, 0x37, 0xe8, 0x2b, 0xbd, 0x57, 0xf8, 0x45, 0x23, 0x72, 0x9c, - 0x16, 0x04, 0x4c, 0xd6, 0xc7, 0x1a, 0x2d, 0xfb, 0x8b, 0x03, 0x30, 0xc8, 0xb3, 0xe8, 0xd7, 0x60, - 0x78, 0x87, 0xe7, 0x89, 0x29, 0x9c, 0x37, 0x8a, 0x2b, 0x53, 0xcf, 0xc4, 0xf3, 0xa6, 0x95, 0x62, - 0x49, 0x06, 0xad, 0xc1, 0x09, 0x9e, 0xae, 0xa7, 0x55, 0x25, 0x2d, 0x67, 0x5f, 0x8a, 0xfd, 0x78, - 0x6e, 0x59, 0x25, 0xfe, 0x5c, 0x4d, 0xa3, 0xe0, 0xac, 0x7a, 0xe8, 0x55, 0x98, 0xa0, 0xcf, 0x30, - 0xbf, 0x1b, 0x49, 0x4a, 0x3c, 0x51, 0x8f, 0x7a, 0xf7, 0x6d, 0x18, 0x50, 0x9c, 0xc0, 0x46, 0xaf, - 0xc0, 0x78, 0x27, 0x25, 0xe0, 0x1c, 0x8c, 0x25, 0x01, 0xa6, 0x50, 0xd3, 0xc4, 0x65, 0xa6, 0xb5, - 0x5d, 0x66, 0x48, 0xbc, 0xb1, 0x13, 0x90, 0x70, 0xc7, 0x6f, 0x35, 0x19, 0xfb, 0x37, 0xa8, 0x99, - 0xd6, 0x26, 0xe0, 0x38, 0x55, 0x83, 0x52, 0xd9, 0x72, 0xdc, 0x56, 0x37, 0x20, 0x31, 0x95, 0x21, - 0x93, 0xca, 0x4a, 0x02, 0x8e, 0x53, 0x35, 0x7a, 0x4b, 0x6e, 0x87, 0x8f, 0x46, 0x72, 0x6b, 0xff, - 0x9d, 0x12, 0x18, 0x53, 0xfb, 0xad, 0x9b, 0x40, 0x88, 0x7e, 0xd9, 0x76, 0xd0, 0x69, 0x08, 0xcb, - 0x98, 0xcc, 0x2f, 0x8b, 0xf3, 0x82, 0xf2, 0x2f, 0xa3, 0xff, 0x31, 0xab, 0x45, 0xf7, 0xf8, 0xa9, - 0x5a, 0xe0, 0xd3, 0x4b, 0x4e, 0x86, 0xb1, 0x52, 0x16, 0xec, 0xc3, 0xd2, 0xbb, 0xb7, 0x20, 0xe0, - 0xa3, 0xb0, 0xf1, 0xe5, 0x14, 0x0c, 0x23, 0x92, 0xba, 0xf0, 0xb5, 0x97, 0x54, 0xd0, 0x65, 0x18, - 0x15, 0x59, 0x61, 0x98, 0xa1, 0x35, 0xdf, 0x4c, 0xcc, 0xe8, 0xa5, 0x1a, 0x17, 0x63, 0x1d, 0xc7, - 0xfe, 0x81, 0x12, 0x9c, 0xc8, 0xf0, 0x94, 0xe1, 0xd7, 0xc8, 0xb6, 0x1b, 0x46, 0x2a, 0xf5, 0xa8, - 0x76, 0x8d, 0xf0, 0x72, 0xac, 0x30, 0xe8, 0x59, 0xc5, 0x2f, 0xaa, 0xe4, 0xe5, 0x24, 0x2c, 0xd1, - 0x05, 0xf4, 0x90, 0x49, 0x3c, 0xcf, 0xc3, 0x40, 0x37, 0x24, 0x32, 0x54, 0xab, 0xba, 0xb6, 0x99, - 0x5a, 0x93, 0x41, 0xe8, 0x33, 0x6a, 0x5b, 0x69, 0x08, 0xb5, 0x67, 0x14, 0xd7, 0x11, 0x72, 0x18, - 0xed, 0x5c, 0x44, 0x3c, 0xc7, 0x8b, 0xc4, 0x63, 0x2b, 0x8e, 0x39, 0xc8, 0x4a, 0xb1, 0x80, 0xda, - 0x5f, 0x28, 0xc3, 0x99, 0x5c, 0xdf, 0x39, 0xda, 0xf5, 0xb6, 0xef, 0xb9, 0x91, 0xaf, 0xac, 0x89, - 0x78, 0x9c, 0x41, 0xd2, 0xd9, 0x59, 0x13, 0xe5, 0x58, 0x61, 0xa0, 0x0b, 0x30, 0xc8, 0x84, 0xa2, - 0xa9, 0x24, 0xac, 0x8b, 0x55, 0x1e, 0x78, 0x8a, 0x83, 0xfb, 0xce, 0x9b, 0xfd, 0x04, 0xe5, 0x60, - 0xfc, 0x56, 0xf2, 0x42, 0xa1, 0xdd, 0xf5, 0xfd, 0x16, 0x66, 0x40, 0xf4, 0x3e, 0x31, 0x5e, 0x09, - 0xf3, 0x19, 0xec, 0x34, 0xfd, 0x50, 0x1b, 0xb4, 0xa7, 0x60, 0x78, 0x97, 0xec, 0x07, 0xae, 0xb7, - 0x9d, 0x34, 0xab, 0xba, 0xc6, 0x8b, 0xb1, 0x84, 0x9b, 0x59, 0x03, 0x87, 0x8f, 0x3a, 0xe1, 0xf5, - 0x48, 0x4f, 0xf6, 0xe4, 0x87, 0xca, 0x30, 0x89, 0x17, 0xab, 0xef, 0x4e, 0xc4, 0xcd, 0xf4, 0x44, - 0x1c, 0x75, 0xc2, 0xeb, 0xde, 0xb3, 0xf1, 0xf3, 0x16, 0x4c, 0xb2, 0xdc, 0x34, 0xc2, 0x43, 0xde, - 0xf5, 0xbd, 0x63, 0x78, 0x0a, 0x3c, 0x01, 0x83, 0x01, 0x6d, 0x34, 0x99, 0x7d, 0x95, 0xf5, 0x04, - 0x73, 0x18, 0x7a, 0x0c, 0x06, 0x58, 0x17, 0xe8, 0xe4, 0x8d, 0xf1, 0x23, 0xb8, 0xea, 0x44, 0x0e, - 0x66, 0xa5, 0x2c, 0xec, 0x12, 0x26, 0x9d, 0x96, 0xcb, 0x3b, 0x1d, 0xab, 0xac, 0xdf, 0x19, 0x5e, - 0xf5, 0x99, 0x5d, 0x7b, 0x7b, 0x61, 0x97, 0xb2, 0x49, 0x16, 0x3f, 0xb3, 0xff, 0xa8, 0x04, 0xe7, - 0x32, 0xeb, 0xf5, 0x1d, 0x76, 0xa9, 0xb8, 0xf6, 0xc3, 0xcc, 0x3e, 0x52, 0x3e, 0x46, 0xa3, 0xd5, - 0x81, 0x7e, 0xb9, 0xff, 0xc1, 0x3e, 0xa2, 0x21, 0x65, 0x0e, 0xd9, 0x3b, 0x24, 0x1a, 0x52, 0x66, - 0xdf, 0x72, 0xc4, 0x04, 0x7f, 0x5e, 0xca, 0xf9, 0x16, 0x26, 0x30, 0xb8, 0x48, 0xcf, 0x19, 0x06, - 0x0c, 0xe5, 0x23, 0x9c, 0x9f, 0x31, 0xbc, 0x0c, 0x2b, 0x28, 0x5a, 0x80, 0xc9, 0xb6, 0xeb, 0xd1, - 0xc3, 0x67, 0xdf, 0x64, 0xc5, 0x55, 0xb0, 0xba, 0x35, 0x13, 0x8c, 0x93, 0xf8, 0xc8, 0xd5, 0x22, - 0x25, 0xf1, 0xaf, 0x7b, 0xe5, 0x50, 0xbb, 0x6e, 0xde, 0x54, 0xe7, 0xab, 0x51, 0xcc, 0x88, 0x9a, - 0xb4, 0xa6, 0xc9, 0x89, 0xca, 0xfd, 0xcb, 0x89, 0xc6, 0xb2, 0x65, 0x44, 0xb3, 0xaf, 0xc0, 0xf8, - 0x03, 0x2b, 0x06, 0xec, 0xaf, 0x95, 0xe1, 0xd1, 0x82, 0x6d, 0xcf, 0xcf, 0x7a, 0x63, 0x0e, 0xb4, - 0xb3, 0x3e, 0x35, 0x0f, 0x35, 0x38, 0xb9, 0xd5, 0x6d, 0xb5, 0xf6, 0x99, 0x2f, 0x07, 0x69, 0x4a, - 0x0c, 0xc1, 0x53, 0x4a, 0xe1, 0xc8, 0xc9, 0x95, 0x0c, 0x1c, 0x9c, 0x59, 0x93, 0x3e, 0xb1, 0xe8, - 0x4d, 0xb2, 0xaf, 0x48, 0x25, 0x9e, 0x58, 0x58, 0x07, 0x62, 0x13, 0x17, 0x5d, 0x81, 0x69, 0x67, - 0xcf, 0x71, 0x79, 0xb8, 0x69, 0x49, 0x80, 0xbf, 0xb1, 0x94, 0x3c, 0x77, 0x21, 0x89, 0x80, 0xd3, - 0x75, 0xd0, 0x6b, 0x80, 0xfc, 0x4d, 0x66, 0xf1, 0xdd, 0xbc, 0x42, 0x3c, 0xa1, 0x75, 0x65, 0x73, - 0x57, 0x8e, 0x8f, 0x84, 0x1b, 0x29, 0x0c, 0x9c, 0x51, 0x2b, 0x11, 0x11, 0x68, 0x28, 0x3f, 0x22, - 0x50, 0xf1, 0xb9, 0xd8, 0x33, 0xf1, 0xcd, 0x7f, 0xb6, 0xe8, 0xf5, 0xc5, 0x99, 0x7c, 0x33, 0x80, - 0xe6, 0x2b, 0xcc, 0x6a, 0x92, 0xcb, 0x7a, 0xb5, 0xf8, 0x29, 0xa7, 0x34, 0xab, 0xc9, 0x18, 0x88, - 0x4d, 0x5c, 0xbe, 0x20, 0xc2, 0xd8, 0x6d, 0xd7, 0x60, 0xf1, 0x45, 0x94, 0x2f, 0x85, 0x81, 0x3e, - 0x0e, 0xc3, 0x4d, 0x77, 0xcf, 0x0d, 0x85, 0xa4, 0xeb, 0xd0, 0x6a, 0xa5, 0xf8, 0x1c, 0xac, 0x72, - 0x32, 0x58, 0xd2, 0xb3, 0x7f, 0xa8, 0x04, 0xe3, 0xb2, 0xc5, 0xd7, 0xbb, 0x7e, 0xe4, 0x1c, 0xc3, - 0xb5, 0x7c, 0xc5, 0xb8, 0x96, 0xdf, 0x57, 0x14, 0xea, 0x8c, 0x75, 0x29, 0xf7, 0x3a, 0xbe, 0x91, - 0xb8, 0x8e, 0x9f, 0xec, 0x4d, 0xaa, 0xf8, 0x1a, 0xfe, 0xa7, 0x16, 0x4c, 0x1b, 0xf8, 0xc7, 0x70, - 0x1b, 0xac, 0x98, 0xb7, 0xc1, 0xe3, 0x3d, 0xbf, 0x21, 0xe7, 0x16, 0xf8, 0xde, 0x72, 0xa2, 0xef, - 0xec, 0xf4, 0x7f, 0x13, 0x06, 0x76, 0x9c, 0xa0, 0x59, 0x94, 0xda, 0x21, 0x55, 0x69, 0xfe, 0xaa, - 0x13, 0x08, 0xb5, 0xf3, 0x33, 0x72, 0xd4, 0x69, 0x51, 0x4f, 0x95, 0x33, 0x6b, 0x0a, 0xbd, 0x04, - 0x43, 0x61, 0xc3, 0xef, 0x28, 0x4f, 0x8e, 0xf3, 0x6c, 0xa0, 0x59, 0xc9, 0xfd, 0x83, 0x39, 0x64, - 0x36, 0x47, 0x8b, 0xb1, 0xc0, 0x47, 0x9f, 0x80, 0x71, 0xf6, 0x4b, 0xd9, 0x80, 0x95, 0xf3, 0xc5, - 0x11, 0x75, 0x1d, 0x91, 0x1b, 0x48, 0x1a, 0x45, 0xd8, 0x24, 0x35, 0xbb, 0x0d, 0x15, 0xf5, 0x59, - 0x0f, 0x55, 0x6f, 0xfb, 0x1f, 0xcb, 0x70, 0x22, 0x63, 0xcd, 0xa1, 0xd0, 0x98, 0x89, 0xcb, 0x7d, - 0x2e, 0xd5, 0xb7, 0x39, 0x17, 0x21, 0x7b, 0x0d, 0x35, 0xc5, 0xda, 0xea, 0xbb, 0xd1, 0x9b, 0x21, - 0x49, 0x36, 0x4a, 0x8b, 0x7a, 0x37, 0x4a, 0x1b, 0x3b, 0xb6, 0xa1, 0xa6, 0x0d, 0xa9, 0x9e, 0x3e, - 0xd4, 0x39, 0xfd, 0xd3, 0x32, 0x9c, 0xcc, 0x8a, 0xbe, 0x88, 0x3e, 0x9b, 0x48, 0x2c, 0xfa, 0x42, - 0xbf, 0x71, 0x1b, 0x79, 0xb6, 0x51, 0x11, 0x10, 0x6e, 0xde, 0x4c, 0x35, 0xda, 0x73, 0x98, 0x45, - 0x9b, 0x2c, 0x24, 0x45, 0xc0, 0x13, 0xc2, 0xca, 0xe3, 0xe3, 0x83, 0x7d, 0x77, 0x40, 0x64, 0x92, - 0x0d, 0x13, 0xf6, 0x25, 0xb2, 0xb8, 0xb7, 0x7d, 0x89, 0x6c, 0x79, 0xd6, 0x85, 0x51, 0xed, 0x6b, - 0x1e, 0xea, 0x8c, 0xef, 0xd2, 0xdb, 0x4a, 0xeb, 0xf7, 0x43, 0x9d, 0xf5, 0x1f, 0xb3, 0x20, 0xe1, - 0x72, 0xa0, 0xc4, 0x62, 0x56, 0xae, 0x58, 0xec, 0x3c, 0x0c, 0x04, 0x7e, 0x8b, 0x24, 0x33, 0x70, - 0x62, 0xbf, 0x45, 0x30, 0x83, 0x50, 0x8c, 0x28, 0x16, 0x76, 0x8c, 0xe9, 0x0f, 0x39, 0xf1, 0x44, - 0x7b, 0x02, 0x06, 0x5b, 0x64, 0x8f, 0xb4, 0x92, 0x89, 0x92, 0xae, 0xd3, 0x42, 0xcc, 0x61, 0xf6, - 0xcf, 0x0f, 0xc0, 0xd9, 0xc2, 0xa0, 0x2e, 0xf4, 0x39, 0xb4, 0xed, 0x44, 0xe4, 0x8e, 0xb3, 0x9f, - 0xcc, 0x68, 0x72, 0x85, 0x17, 0x63, 0x09, 0x67, 0x9e, 0x64, 0x3c, 0x30, 0x79, 0x42, 0x88, 0x28, - 0xe2, 0x91, 0x0b, 0xa8, 0x29, 0x94, 0x2a, 0x1f, 0x85, 0x50, 0xea, 0x39, 0x80, 0x30, 0x6c, 0x71, - 0xc3, 0xac, 0xa6, 0x70, 0x51, 0x8b, 0x03, 0xd8, 0xd7, 0xaf, 0x0b, 0x08, 0xd6, 0xb0, 0x50, 0x15, - 0xa6, 0x3a, 0x81, 0x1f, 0x71, 0x99, 0x6c, 0x95, 0xdb, 0x2e, 0x0e, 0x9a, 0xf1, 0x34, 0x6a, 0x09, - 0x38, 0x4e, 0xd5, 0x40, 0x2f, 0xc2, 0xa8, 0x88, 0xb1, 0x51, 0xf3, 0xfd, 0x96, 0x10, 0x03, 0x29, - 0x73, 0xbe, 0x7a, 0x0c, 0xc2, 0x3a, 0x9e, 0x56, 0x8d, 0x09, 0x7a, 0x87, 0x33, 0xab, 0x71, 0x61, - 0xaf, 0x86, 0x97, 0x88, 0xc4, 0x3a, 0xd2, 0x57, 0x24, 0xd6, 0x58, 0x30, 0x56, 0xe9, 0x5b, 0xef, - 0x08, 0x3d, 0x45, 0x49, 0x3f, 0x3b, 0x00, 0x27, 0xc4, 0xc2, 0x79, 0xd8, 0xcb, 0xe5, 0x66, 0x7a, - 0xb9, 0x1c, 0x85, 0xe8, 0xec, 0xdd, 0x35, 0x73, 0xdc, 0x6b, 0xe6, 0x87, 0x2d, 0x30, 0xd9, 0x2b, - 0xf4, 0x17, 0x72, 0x53, 0x42, 0xbd, 0x98, 0xcb, 0xae, 0xa9, 0xa8, 0x9e, 0x6f, 0x33, 0x39, 0x94, - 0xfd, 0x9f, 0x2c, 0x78, 0xbc, 0x27, 0x45, 0xb4, 0x0c, 0x15, 0xc6, 0x03, 0x6a, 0xaf, 0xb3, 0x27, - 0x95, 0x6d, 0xb3, 0x04, 0xe4, 0xb0, 0xa4, 0x71, 0x4d, 0xb4, 0x9c, 0xca, 0xbd, 0xf5, 0x54, 0x46, - 0xee, 0xad, 0x53, 0xc6, 0xf0, 0x3c, 0x60, 0xf2, 0xad, 0x1f, 0xa4, 0x37, 0x8e, 0xe1, 0x57, 0x84, - 0x3e, 0x68, 0x88, 0xfd, 0xec, 0x84, 0xd8, 0x0f, 0x99, 0xd8, 0xda, 0x1d, 0xf2, 0x51, 0x98, 0x62, - 0xc1, 0xb7, 0x98, 0xa5, 0xbd, 0xf0, 0x78, 0x2a, 0xc5, 0xd6, 0xb4, 0xd7, 0x13, 0x30, 0x9c, 0xc2, - 0xb6, 0xff, 0xb0, 0x0c, 0x43, 0x7c, 0xfb, 0x1d, 0xc3, 0x9b, 0xf0, 0x69, 0xa8, 0xb8, 0xed, 0x76, - 0x97, 0xa7, 0x53, 0x1a, 0xe4, 0xbe, 0xd1, 0x74, 0x9e, 0x56, 0x65, 0x21, 0x8e, 0xe1, 0x68, 0x45, - 0x48, 0x9c, 0x0b, 0xe2, 0x7b, 0xf2, 0x8e, 0xcf, 0x57, 0x9d, 0xc8, 0xe1, 0x0c, 0x8e, 0xba, 0x67, - 0x63, 0xd9, 0x34, 0xfa, 0x14, 0x40, 0x18, 0x05, 0xae, 0xb7, 0x4d, 0xcb, 0x44, 0x58, 0xe1, 0xf7, - 0x17, 0x50, 0xab, 0x2b, 0x64, 0x4e, 0x33, 0x3e, 0x73, 0x14, 0x00, 0x6b, 0x14, 0xd1, 0xbc, 0x71, - 0xd3, 0xcf, 0x26, 0xe6, 0x0e, 0x38, 0xd5, 0x78, 0xce, 0x66, 0x3f, 0x04, 0x15, 0x45, 0xbc, 0x97, - 0xfc, 0x69, 0x4c, 0x67, 0x8b, 0x3e, 0x02, 0x93, 0x89, 0xbe, 0x1d, 0x4a, 0x7c, 0xf5, 0x0b, 0x16, - 0x4c, 0xf2, 0xce, 0x2c, 0x7b, 0x7b, 0xe2, 0x36, 0x78, 0x0b, 0x4e, 0xb6, 0x32, 0x4e, 0x65, 0x31, - 0xfd, 0xfd, 0x9f, 0xe2, 0x4a, 0x5c, 0x95, 0x05, 0xc5, 0x99, 0x6d, 0xa0, 0x8b, 0x74, 0xc7, 0xd1, - 0x53, 0xd7, 0x69, 0x09, 0x57, 0xe9, 0x31, 0xbe, 0xdb, 0x78, 0x19, 0x56, 0x50, 0xfb, 0x77, 0x2c, - 0x98, 0xe6, 0x3d, 0xbf, 0x46, 0xf6, 0xd5, 0xd9, 0xf4, 0x8d, 0xec, 0xbb, 0x48, 0xe4, 0x57, 0xca, - 0x49, 0xe4, 0xa7, 0x7f, 0x5a, 0xb9, 0xf0, 0xd3, 0xbe, 0x6c, 0x81, 0x58, 0x21, 0xc7, 0x20, 0x84, - 0xf8, 0x76, 0x53, 0x08, 0x31, 0x9b, 0xbf, 0x09, 0x72, 0xa4, 0x0f, 0x7f, 0x66, 0xc1, 0x14, 0x47, - 0x88, 0xb5, 0xe5, 0xdf, 0xd0, 0x79, 0xe8, 0x27, 0xdd, 0xf7, 0x35, 0xb2, 0xbf, 0xe1, 0xd7, 0x9c, - 0x68, 0x27, 0xfb, 0xa3, 0x8c, 0xc9, 0x1a, 0x28, 0x9c, 0xac, 0xa6, 0xdc, 0x40, 0x46, 0x9e, 0x9b, - 0x1e, 0xf1, 0x23, 0x0e, 0x9b, 0xe7, 0xc6, 0xfe, 0xba, 0x05, 0x88, 0x37, 0x63, 0x30, 0x6e, 0x94, - 0x1d, 0x62, 0xa5, 0xda, 0x45, 0x17, 0x1f, 0x4d, 0x0a, 0x82, 0x35, 0xac, 0x23, 0x19, 0x9e, 0x84, - 0xc9, 0x43, 0xb9, 0xb7, 0xc9, 0xc3, 0x21, 0x46, 0xf4, 0xdf, 0x0d, 0x41, 0xd2, 0xb7, 0x0a, 0xdd, - 0x82, 0xb1, 0x86, 0xd3, 0x71, 0x36, 0xdd, 0x96, 0x1b, 0xb9, 0x24, 0x2c, 0xb2, 0x87, 0x5a, 0xd2, - 0xf0, 0x84, 0x92, 0x5a, 0x2b, 0xc1, 0x06, 0x1d, 0x34, 0x0f, 0xd0, 0x09, 0xdc, 0x3d, 0xb7, 0x45, - 0xb6, 0x99, 0xac, 0x84, 0x05, 0x67, 0xe0, 0xc6, 0x59, 0xb2, 0x14, 0x6b, 0x18, 0x19, 0x8e, 0xec, - 0xe5, 0x87, 0xec, 0xc8, 0x0e, 0xc7, 0xe6, 0xc8, 0x3e, 0x70, 0x28, 0x47, 0xf6, 0x91, 0x43, 0x3b, - 0xb2, 0x0f, 0xf6, 0xe5, 0xc8, 0x8e, 0xe1, 0xb4, 0xe4, 0x3d, 0xe9, 0xff, 0x15, 0xb7, 0x45, 0xc4, - 0x83, 0x83, 0x47, 0x94, 0x98, 0xbd, 0x77, 0x30, 0x77, 0x1a, 0x67, 0x62, 0xe0, 0x9c, 0x9a, 0xe8, - 0x63, 0x30, 0xe3, 0xb4, 0x5a, 0xfe, 0x1d, 0x35, 0xa9, 0xcb, 0x61, 0xc3, 0x69, 0x71, 0x25, 0xc4, - 0x30, 0xa3, 0xfa, 0xd8, 0xbd, 0x83, 0xb9, 0x99, 0x85, 0x1c, 0x1c, 0x9c, 0x5b, 0x1b, 0x7d, 0x18, - 0x2a, 0x9d, 0xc0, 0x6f, 0xac, 0x69, 0x0e, 0xa0, 0xe7, 0xe8, 0x00, 0xd6, 0x64, 0xe1, 0xfd, 0x83, - 0xb9, 0x71, 0xf5, 0x87, 0x5d, 0xf8, 0x71, 0x85, 0x0c, 0xcf, 0xf4, 0xd1, 0x23, 0xf5, 0x4c, 0xdf, - 0x85, 0x13, 0x75, 0x12, 0xb8, 0x4e, 0xcb, 0x7d, 0x8b, 0xf2, 0xcb, 0xf2, 0x7c, 0xda, 0x80, 0x4a, - 0x90, 0x38, 0x91, 0xfb, 0x8a, 0xb9, 0xa9, 0x25, 0x1c, 0x91, 0x27, 0x70, 0x4c, 0xc8, 0xfe, 0x3f, - 0x16, 0x0c, 0x0b, 0x5f, 0xaa, 0x63, 0xe0, 0x1a, 0x17, 0x0c, 0x4d, 0xc2, 0x5c, 0xf6, 0x80, 0xb1, - 0xce, 0xe4, 0xea, 0x10, 0x56, 0x13, 0x3a, 0x84, 0xc7, 0x8b, 0x88, 0x14, 0x6b, 0x0f, 0xfe, 0x46, - 0x99, 0x72, 0xef, 0x86, 0x57, 0xef, 0xc3, 0x1f, 0x82, 0x75, 0x18, 0x0e, 0x85, 0x57, 0x69, 0x29, - 0xdf, 0xa7, 0x21, 0x39, 0x89, 0xb1, 0x1d, 0x9b, 0xf0, 0x23, 0x95, 0x44, 0x32, 0xdd, 0x55, 0xcb, - 0x0f, 0xd1, 0x5d, 0xb5, 0x97, 0xdf, 0xf3, 0xc0, 0x51, 0xf8, 0x3d, 0xdb, 0x5f, 0x65, 0x37, 0xa7, - 0x5e, 0x7e, 0x0c, 0x4c, 0xd5, 0x15, 0xf3, 0x8e, 0xb5, 0x0b, 0x56, 0x96, 0xe8, 0x54, 0x0e, 0x73, - 0xf5, 0x73, 0x16, 0x9c, 0xcd, 0xf8, 0x2a, 0x8d, 0xd3, 0x7a, 0x06, 0x46, 0x9c, 0x6e, 0xd3, 0x55, - 0x7b, 0x59, 0xd3, 0x27, 0x2e, 0x88, 0x72, 0xac, 0x30, 0xd0, 0x12, 0x4c, 0x93, 0xbb, 0x1d, 0x97, - 0xab, 0x52, 0x75, 0xf3, 0xdf, 0x32, 0x77, 0xc0, 0x5b, 0x4e, 0x02, 0x71, 0x1a, 0x5f, 0xc5, 0x9a, - 0x29, 0xe7, 0xc6, 0x9a, 0xf9, 0xfb, 0x16, 0x8c, 0x2a, 0xbf, 0xca, 0x87, 0x3e, 0xda, 0x1f, 0x35, - 0x47, 0xfb, 0xd1, 0x82, 0xd1, 0xce, 0x19, 0xe6, 0xdf, 0x2a, 0xa9, 0xfe, 0xd6, 0xfc, 0x20, 0xea, - 0x83, 0x83, 0x7b, 0x70, 0xd7, 0x85, 0xcb, 0x30, 0xea, 0x74, 0x3a, 0x12, 0x20, 0x6d, 0xd0, 0x58, - 0x04, 0xe5, 0xb8, 0x18, 0xeb, 0x38, 0xca, 0x93, 0xa2, 0x9c, 0xeb, 0x49, 0xd1, 0x04, 0x88, 0x9c, - 0x60, 0x9b, 0x44, 0xb4, 0x4c, 0x98, 0xcc, 0xe6, 0x9f, 0x37, 0xdd, 0xc8, 0x6d, 0xcd, 0xbb, 0x5e, - 0x14, 0x46, 0xc1, 0xfc, 0xaa, 0x17, 0xdd, 0x08, 0xf8, 0x13, 0x52, 0x8b, 0xd6, 0xa4, 0x68, 0x61, - 0x8d, 0xae, 0x8c, 0x21, 0xc0, 0xda, 0x18, 0x34, 0x8d, 0x19, 0xd6, 0x45, 0x39, 0x56, 0x18, 0xf6, - 0x87, 0xd8, 0xed, 0xc3, 0xc6, 0xf4, 0x70, 0x91, 0x8a, 0xfe, 0xe1, 0x98, 0x9a, 0x0d, 0xa6, 0xc9, - 0xac, 0xea, 0xf1, 0x90, 0x8a, 0x0f, 0x7b, 0xda, 0xb0, 0xee, 0xd7, 0x17, 0x07, 0x4d, 0x42, 0xdf, - 0x91, 0x32, 0x50, 0x79, 0xb6, 0xc7, 0xad, 0x71, 0x08, 0x93, 0x14, 0x96, 0x4e, 0x85, 0x25, 0x9b, - 0x58, 0xad, 0x89, 0x7d, 0xa1, 0xa5, 0x53, 0x11, 0x00, 0x1c, 0xe3, 0x50, 0x66, 0x4a, 0xfd, 0x09, - 0x67, 0x50, 0x1c, 0x56, 0x54, 0x61, 0x87, 0x58, 0xc3, 0x40, 0x97, 0x84, 0x40, 0x81, 0xeb, 0x05, - 0x1e, 0x4d, 0x08, 0x14, 0xe4, 0x70, 0x69, 0x52, 0xa0, 0xcb, 0x30, 0xaa, 0x32, 0x68, 0xd7, 0x78, - 0x22, 0x23, 0xb1, 0xcc, 0x96, 0xe3, 0x62, 0xac, 0xe3, 0xa0, 0x0d, 0x98, 0x0c, 0xb9, 0x9c, 0x4d, - 0xc5, 0x7a, 0xe6, 0xf2, 0xca, 0xf7, 0x4b, 0x2b, 0xa0, 0xba, 0x09, 0xbe, 0xcf, 0x8a, 0xf8, 0xe9, - 0x24, 0xfd, 0xfc, 0x93, 0x24, 0xd0, 0xab, 0x30, 0xd1, 0xf2, 0x9d, 0xe6, 0xa2, 0xd3, 0x72, 0xbc, - 0x06, 0x1b, 0x9f, 0x11, 0x33, 0x11, 0xeb, 0x75, 0x03, 0x8a, 0x13, 0xd8, 0x94, 0x79, 0xd3, 0x4b, - 0x44, 0x7c, 0x72, 0xc7, 0xdb, 0x26, 0xa1, 0xc8, 0x87, 0xcc, 0x98, 0xb7, 0xeb, 0x39, 0x38, 0x38, - 0xb7, 0x36, 0x7a, 0x09, 0xc6, 0xe4, 0xe7, 0x6b, 0x61, 0x31, 0x62, 0xa7, 0x14, 0x0d, 0x86, 0x0d, - 0x4c, 0x74, 0x07, 0x4e, 0xc9, 0xff, 0x1b, 0x81, 0xb3, 0xb5, 0xe5, 0x36, 0x84, 0xaf, 0x38, 0xf7, - 0x5e, 0x5d, 0x90, 0x2e, 0x96, 0xcb, 0x59, 0x48, 0xf7, 0x0f, 0xe6, 0xce, 0x8b, 0x51, 0xcb, 0x84, - 0xb3, 0x49, 0xcc, 0xa6, 0x8f, 0xd6, 0xe0, 0xc4, 0x0e, 0x71, 0x5a, 0xd1, 0xce, 0xd2, 0x0e, 0x69, - 0xec, 0xca, 0x4d, 0xc7, 0x82, 0x6d, 0x68, 0x0e, 0x1c, 0x57, 0xd3, 0x28, 0x38, 0xab, 0x1e, 0x7a, - 0x03, 0x66, 0x3a, 0xdd, 0xcd, 0x96, 0x1b, 0xee, 0xac, 0xfb, 0x11, 0x33, 0x05, 0x52, 0x09, 0xb9, - 0x45, 0x54, 0x0e, 0x15, 0xce, 0xa4, 0x96, 0x83, 0x87, 0x73, 0x29, 0xa0, 0xb7, 0xe0, 0x54, 0x62, - 0x31, 0x88, 0xb8, 0x04, 0x13, 0xf9, 0xd9, 0x1e, 0xea, 0x59, 0x15, 0x44, 0x88, 0x8f, 0x2c, 0x10, - 0xce, 0x6e, 0x02, 0xbd, 0x0c, 0xe0, 0x76, 0x56, 0x9c, 0xb6, 0xdb, 0xa2, 0xcf, 0xc5, 0x13, 0x6c, - 0x9d, 0xd0, 0xa7, 0x03, 0xac, 0xd6, 0x64, 0x29, 0x3d, 0x9f, 0xc5, 0xbf, 0x7d, 0xac, 0x61, 0xa3, - 0x1a, 0x4c, 0x88, 0x7f, 0xfb, 0x62, 0x5a, 0xa7, 0x55, 0x08, 0x80, 0x09, 0x59, 0x43, 0xcd, 0x25, - 0x32, 0x4b, 0xd8, 0xec, 0x25, 0xea, 0xa3, 0x6d, 0x38, 0x2b, 0xb3, 0x77, 0xe9, 0xeb, 0x54, 0xce, - 0x43, 0xc8, 0xd2, 0x2c, 0x8c, 0x70, 0xff, 0x90, 0x85, 0x22, 0x44, 0x5c, 0x4c, 0x87, 0xde, 0xef, - 0xfa, 0x72, 0xe7, 0x1e, 0xb4, 0xa7, 0xb8, 0x79, 0x12, 0xbd, 0xdf, 0xaf, 0x27, 0x81, 0x38, 0x8d, - 0x8f, 0x42, 0x38, 0xe5, 0x7a, 0x59, 0xab, 0xfb, 0x34, 0x23, 0xf4, 0x11, 0xee, 0x3c, 0x5c, 0xbc, - 0xb2, 0x33, 0xe1, 0x7c, 0x65, 0x67, 0xd2, 0x7e, 0x7b, 0x56, 0x78, 0xbf, 0x6d, 0xd1, 0xda, 0x1a, - 0xa7, 0x8e, 0x3e, 0x0d, 0x63, 0xfa, 0x87, 0x09, 0xae, 0xe3, 0x42, 0x36, 0x23, 0xab, 0x9d, 0x0f, - 0x9c, 0xcf, 0x57, 0x67, 0x80, 0x0e, 0xc3, 0x06, 0x45, 0xd4, 0xc8, 0x70, 0xb3, 0xbf, 0xd4, 0x1f, - 0x57, 0xd3, 0xbf, 0x11, 0x1a, 0x81, 0xec, 0x65, 0x8f, 0xae, 0xc3, 0x48, 0xa3, 0xe5, 0x12, 0x2f, - 0x5a, 0xad, 0x15, 0xc5, 0xd2, 0x5b, 0x12, 0x38, 0x62, 0x1f, 0x89, 0xac, 0x09, 0xbc, 0x0c, 0x2b, - 0x0a, 0xf6, 0xaf, 0x96, 0x60, 0xae, 0x47, 0x0a, 0x8e, 0x84, 0x4a, 0xca, 0xea, 0x4b, 0x25, 0xb5, - 0x20, 0xb3, 0xce, 0xaf, 0x27, 0xa4, 0x5d, 0x89, 0x8c, 0xf2, 0xb1, 0xcc, 0x2b, 0x89, 0xdf, 0xb7, - 0x8b, 0x80, 0xae, 0xd5, 0x1a, 0xe8, 0xe9, 0xe4, 0x62, 0x68, 0xb3, 0x07, 0xfb, 0x7f, 0x02, 0xe7, - 0x6a, 0x26, 0xed, 0xaf, 0x96, 0xe0, 0x94, 0x1a, 0xc2, 0x6f, 0xdd, 0x81, 0xbb, 0x99, 0x1e, 0xb8, - 0x23, 0xd0, 0xeb, 0xda, 0x37, 0x60, 0x88, 0x07, 0x07, 0xec, 0x83, 0xf5, 0x7e, 0xc2, 0x0c, 0xbe, - 0xab, 0xb8, 0x3d, 0x23, 0x00, 0xef, 0xf7, 0x5b, 0x30, 0x99, 0xf0, 0x35, 0x43, 0x58, 0x73, 0x48, - 0x7e, 0x10, 0xf6, 0x38, 0x8b, 0xf1, 0x3e, 0x0f, 0x03, 0x3b, 0x7e, 0x18, 0x25, 0x8d, 0x3e, 0xae, - 0xfa, 0x61, 0x84, 0x19, 0xc4, 0xfe, 0x5d, 0x0b, 0x06, 0x37, 0x1c, 0xd7, 0x8b, 0xa4, 0x82, 0xc0, - 0xca, 0x51, 0x10, 0xf4, 0xf3, 0x5d, 0xe8, 0x45, 0x18, 0x22, 0x5b, 0x5b, 0xa4, 0x11, 0x89, 0x59, - 0x95, 0xd1, 0x1c, 0x86, 0x96, 0x59, 0x29, 0xe5, 0x05, 0x59, 0x63, 0xfc, 0x2f, 0x16, 0xc8, 0xe8, - 0x36, 0x54, 0x22, 0xb7, 0x4d, 0x16, 0x9a, 0x4d, 0xa1, 0x36, 0x7f, 0x80, 0x88, 0x14, 0x1b, 0x92, - 0x00, 0x8e, 0x69, 0xd9, 0x5f, 0x28, 0x01, 0xc4, 0x51, 0x95, 0x7a, 0x7d, 0xe2, 0x62, 0x4a, 0xa1, - 0x7a, 0x21, 0x43, 0xa1, 0x8a, 0x62, 0x82, 0x19, 0xda, 0x54, 0x35, 0x4c, 0xe5, 0xbe, 0x86, 0x69, - 0xe0, 0x30, 0xc3, 0xb4, 0x04, 0xd3, 0x71, 0x54, 0x28, 0x33, 0x28, 0x1e, 0xbb, 0x3e, 0x37, 0x92, - 0x40, 0x9c, 0xc6, 0xb7, 0x09, 0x9c, 0x57, 0xc1, 0x71, 0xc4, 0x8d, 0xc6, 0xac, 0xb2, 0x75, 0x05, - 0x75, 0x8f, 0x71, 0x8a, 0x35, 0xc6, 0xa5, 0x5c, 0x8d, 0xf1, 0x4f, 0x5a, 0x70, 0x32, 0xd9, 0x0e, - 0x73, 0x61, 0xfe, 0xbc, 0x05, 0xa7, 0x98, 0xde, 0x9c, 0xb5, 0x9a, 0xd6, 0xd2, 0xbf, 0x50, 0x18, - 0xf0, 0x27, 0xa7, 0xc7, 0x71, 0xd8, 0x90, 0xb5, 0x2c, 0xd2, 0x38, 0xbb, 0x45, 0xfb, 0x7b, 0xca, - 0x30, 0x93, 0x17, 0x29, 0x88, 0x39, 0x6d, 0x38, 0x77, 0xeb, 0xbb, 0xe4, 0x8e, 0x30, 0x8d, 0x8f, - 0x9d, 0x36, 0x78, 0x31, 0x96, 0xf0, 0x64, 0x56, 0x85, 0x52, 0x9f, 0x59, 0x15, 0x76, 0x60, 0xfa, - 0xce, 0x0e, 0xf1, 0x6e, 0x7a, 0xa1, 0x13, 0xb9, 0xe1, 0x96, 0xcb, 0x74, 0xcc, 0x7c, 0xdd, 0xc8, - 0x54, 0xac, 0xd3, 0xb7, 0x93, 0x08, 0xf7, 0x0f, 0xe6, 0xce, 0x1a, 0x05, 0x71, 0x97, 0xf9, 0x41, - 0x82, 0xd3, 0x44, 0xd3, 0x49, 0x29, 0x06, 0x1e, 0x72, 0x52, 0x8a, 0xb6, 0x2b, 0x2c, 0x53, 0xa4, - 0x45, 0x3e, 0x7b, 0x3d, 0xae, 0xa9, 0x52, 0xac, 0x61, 0xd8, 0x9f, 0xb7, 0xe0, 0x4c, 0x6e, 0x1e, - 0x63, 0x74, 0x11, 0x46, 0x9c, 0x8e, 0xcb, 0xc5, 0xfa, 0xe2, 0xd8, 0x65, 0xe2, 0xa3, 0xda, 0x2a, - 0x17, 0xea, 0x2b, 0x28, 0x3d, 0xed, 0x76, 0x5d, 0xaf, 0x99, 0x3c, 0xed, 0xae, 0xb9, 0x5e, 0x13, - 0x33, 0x88, 0x3a, 0xbe, 0xcb, 0x79, 0xc7, 0xb7, 0xfd, 0x7d, 0x16, 0x08, 0x07, 0xd5, 0x3e, 0xce, - 0xfa, 0x4f, 0xc0, 0xd8, 0x5e, 0x3a, 0xd1, 0xd5, 0xf9, 0x7c, 0x8f, 0x5d, 0x91, 0xde, 0x4a, 0x31, - 0x70, 0x46, 0x52, 0x2b, 0x83, 0x96, 0xdd, 0x04, 0x01, 0xad, 0x12, 0x26, 0xb4, 0xee, 0xdd, 0x9b, - 0xe7, 0x00, 0x9a, 0x0c, 0x97, 0x65, 0xbf, 0x2c, 0x99, 0x37, 0x79, 0x55, 0x41, 0xb0, 0x86, 0x65, - 0xff, 0x87, 0x12, 0x8c, 0xca, 0xc4, 0x4a, 0x5d, 0xaf, 0x1f, 0xd1, 0xd2, 0xa1, 0x32, 0xad, 0xa2, - 0x4b, 0x50, 0x61, 0xb2, 0xcf, 0x5a, 0x2c, 0x91, 0x53, 0x92, 0x87, 0x35, 0x09, 0xc0, 0x31, 0x0e, - 0xdd, 0x75, 0x61, 0x77, 0x93, 0xa1, 0x27, 0xdc, 0x29, 0xeb, 0xbc, 0x18, 0x4b, 0x38, 0xfa, 0x18, - 0x4c, 0xf1, 0x7a, 0x81, 0xdf, 0x71, 0xb6, 0xb9, 0xbe, 0x64, 0x50, 0xc5, 0xa8, 0x98, 0x5a, 0x4b, - 0xc0, 0xee, 0x1f, 0xcc, 0x9d, 0x4c, 0x96, 0x31, 0x45, 0x60, 0x8a, 0x0a, 0x33, 0x8b, 0xe2, 0x8d, - 0xd0, 0xd3, 0x22, 0x65, 0x4d, 0x15, 0x83, 0xb0, 0x8e, 0x67, 0x7f, 0x1a, 0x50, 0x3a, 0xc5, 0x14, - 0x7a, 0x8d, 0xdb, 0xc2, 0xba, 0x01, 0x69, 0x16, 0x29, 0x06, 0xf5, 0x48, 0x0c, 0xd2, 0x13, 0x8a, - 0xd7, 0xc2, 0xaa, 0xbe, 0xfd, 0x97, 0xcb, 0x30, 0x95, 0xf4, 0xfd, 0x46, 0x57, 0x61, 0x88, 0xb3, - 0x2a, 0x82, 0x7c, 0x81, 0xdd, 0x89, 0xe6, 0x31, 0xce, 0x0e, 0x6d, 0xc1, 0xed, 0x88, 0xfa, 0xe8, - 0x0d, 0x18, 0x6d, 0xfa, 0x77, 0xbc, 0x3b, 0x4e, 0xd0, 0x5c, 0xa8, 0xad, 0x8a, 0xe5, 0x9c, 0xf9, - 0x10, 0xae, 0xc6, 0x68, 0xba, 0x17, 0x3a, 0xd3, 0xb1, 0xc6, 0x20, 0xac, 0x93, 0x43, 0x1b, 0x2c, - 0x2e, 0xfd, 0x96, 0xbb, 0xbd, 0xe6, 0x74, 0x8a, 0x1c, 0x23, 0x96, 0x24, 0x92, 0x46, 0x79, 0x5c, - 0x04, 0xaf, 0xe7, 0x00, 0x1c, 0x13, 0x42, 0x9f, 0x85, 0x13, 0x61, 0x8e, 0x78, 0x3e, 0x2f, 0xe3, - 0x60, 0x91, 0xc4, 0x7a, 0xf1, 0x91, 0x7b, 0x07, 0x73, 0x27, 0xb2, 0x04, 0xf9, 0x59, 0xcd, 0xd8, - 0x5f, 0x3c, 0x09, 0xc6, 0x26, 0x36, 0x12, 0xd0, 0x5a, 0x47, 0x94, 0x80, 0x16, 0xc3, 0x08, 0x69, - 0x77, 0xa2, 0xfd, 0xaa, 0x1b, 0x14, 0xa5, 0xe1, 0x5f, 0x16, 0x38, 0x69, 0x9a, 0x12, 0x82, 0x15, - 0x9d, 0xec, 0x2c, 0xc1, 0xe5, 0x6f, 0x60, 0x96, 0xe0, 0x81, 0x63, 0xcc, 0x12, 0xbc, 0x0e, 0xc3, - 0xdb, 0x6e, 0x84, 0x49, 0xc7, 0x17, 0x8f, 0x84, 0xcc, 0x75, 0x78, 0x85, 0xa3, 0xa4, 0xf3, 0x51, - 0x0a, 0x00, 0x96, 0x44, 0xd0, 0x6b, 0x6a, 0x07, 0x0e, 0xe5, 0x3f, 0xe4, 0xd3, 0x06, 0x12, 0x99, - 0x7b, 0x50, 0xe4, 0x02, 0x1e, 0x7e, 0xd0, 0x5c, 0xc0, 0x2b, 0x32, 0x83, 0xef, 0x48, 0xbe, 0x17, - 0x13, 0x4b, 0xd0, 0xdb, 0x23, 0x6f, 0xef, 0x2d, 0x3d, 0xeb, 0x71, 0x25, 0xff, 0x24, 0x50, 0x09, - 0x8d, 0xfb, 0xcc, 0x75, 0xfc, 0x7d, 0x16, 0x9c, 0xea, 0x64, 0x25, 0x00, 0x17, 0xb6, 0x04, 0x2f, - 0xf6, 0x9d, 0x63, 0xdc, 0x68, 0x90, 0xc9, 0xe0, 0xb2, 0xb3, 0xc8, 0x67, 0x37, 0x47, 0x07, 0x3a, - 0xd8, 0x6c, 0x0a, 0x9d, 0xf6, 0x13, 0x39, 0x49, 0x93, 0x0b, 0x52, 0x25, 0x6f, 0x64, 0x24, 0xe8, - 0x7d, 0x6f, 0x5e, 0x82, 0xde, 0xbe, 0xd3, 0xf2, 0xbe, 0xa6, 0xd2, 0x25, 0x8f, 0xe7, 0x2f, 0x25, - 0x9e, 0x0c, 0xb9, 0x67, 0x92, 0xe4, 0xd7, 0x54, 0x92, 0xe4, 0x82, 0xf8, 0xc1, 0x3c, 0x05, 0x72, - 0xcf, 0xd4, 0xc8, 0x5a, 0x7a, 0xe3, 0xc9, 0xa3, 0x49, 0x6f, 0x6c, 0x5c, 0x35, 0x3c, 0xc3, 0xee, - 0xd3, 0x3d, 0xae, 0x1a, 0x83, 0x6e, 0xf1, 0x65, 0xc3, 0x53, 0x39, 0x4f, 0x3f, 0x50, 0x2a, 0xe7, - 0x5b, 0x7a, 0x6a, 0x64, 0xd4, 0x23, 0xf7, 0x2f, 0x45, 0xea, 0x33, 0x21, 0xf2, 0x2d, 0xfd, 0x02, - 0x3c, 0x91, 0x4f, 0x57, 0xdd, 0x73, 0x69, 0xba, 0x99, 0x57, 0x60, 0x2a, 0xd1, 0xf2, 0xc9, 0xe3, - 0x49, 0xb4, 0x7c, 0xea, 0xc8, 0x13, 0x2d, 0x9f, 0x3e, 0x86, 0x44, 0xcb, 0x8f, 0x1c, 0x63, 0xa2, - 0xe5, 0x5b, 0xcc, 0x00, 0x87, 0x87, 0xf9, 0x11, 0xf1, 0x8e, 0x9f, 0xca, 0x89, 0x92, 0x95, 0x8e, - 0x05, 0xc4, 0x3f, 0x4e, 0x81, 0x70, 0x4c, 0x2a, 0x23, 0x81, 0xf3, 0xcc, 0x43, 0x48, 0xe0, 0xbc, - 0x1e, 0x27, 0x70, 0x3e, 0x93, 0x3f, 0xd5, 0x19, 0x2e, 0x1b, 0x39, 0x69, 0x9b, 0x6f, 0xe9, 0xe9, - 0x96, 0x1f, 0x2d, 0xd0, 0xb2, 0x64, 0x09, 0x2a, 0x0b, 0x92, 0x2c, 0xbf, 0xca, 0x93, 0x2c, 0x3f, - 0x96, 0x7f, 0x92, 0x27, 0xaf, 0x3b, 0x23, 0xb5, 0x32, 0xed, 0x97, 0x0a, 0x93, 0xc9, 0x22, 0x3b, - 0xe7, 0xf4, 0x4b, 0xc5, 0xd9, 0x4c, 0xf7, 0x4b, 0x81, 0x70, 0x4c, 0xca, 0xfe, 0x81, 0x12, 0x9c, - 0x2b, 0xde, 0x6f, 0xb1, 0xf4, 0xb5, 0x16, 0x2b, 0x9d, 0x13, 0xd2, 0x57, 0xfe, 0x66, 0x8b, 0xb1, - 0xfa, 0x8e, 0xfa, 0x77, 0x05, 0xa6, 0x95, 0xaf, 0x47, 0xcb, 0x6d, 0xec, 0xaf, 0xc7, 0x2f, 0x5f, - 0xe5, 0x1f, 0x5f, 0x4f, 0x22, 0xe0, 0x74, 0x1d, 0xb4, 0x00, 0x93, 0x46, 0xe1, 0x6a, 0x55, 0xbc, - 0xcd, 0x94, 0xb8, 0xb7, 0x6e, 0x82, 0x71, 0x12, 0xdf, 0xfe, 0x92, 0x05, 0x8f, 0xe4, 0x64, 0x28, - 0xec, 0x3b, 0xa8, 0xdd, 0x16, 0x4c, 0x76, 0xcc, 0xaa, 0x3d, 0xe2, 0x70, 0x1a, 0x79, 0x10, 0x55, - 0x5f, 0x13, 0x00, 0x9c, 0x24, 0x6a, 0xff, 0x74, 0x09, 0xce, 0x16, 0x1a, 0x2f, 0x22, 0x0c, 0xa7, - 0xb7, 0xdb, 0xa1, 0xb3, 0x14, 0x90, 0x26, 0xf1, 0x22, 0xd7, 0x69, 0xd5, 0x3b, 0xa4, 0xa1, 0xc9, - 0xcf, 0x99, 0x15, 0xe0, 0x95, 0xb5, 0xfa, 0x42, 0x1a, 0x03, 0xe7, 0xd4, 0x44, 0x2b, 0x80, 0xd2, - 0x10, 0x31, 0xc3, 0x2c, 0x46, 0x78, 0x9a, 0x1e, 0xce, 0xa8, 0x81, 0x3e, 0x04, 0xe3, 0xca, 0x28, - 0x52, 0x9b, 0x71, 0x76, 0xb0, 0x63, 0x1d, 0x80, 0x4d, 0x3c, 0x74, 0x99, 0x07, 0x99, 0x17, 0xe9, - 0x08, 0x84, 0xb0, 0x7d, 0x52, 0x46, 0x90, 0x17, 0xc5, 0x58, 0xc7, 0x59, 0x7c, 0xe9, 0xd7, 0x7e, - 0xff, 0xdc, 0x7b, 0x7e, 0xf3, 0xf7, 0xcf, 0xbd, 0xe7, 0x77, 0x7e, 0xff, 0xdc, 0x7b, 0xbe, 0xeb, - 0xde, 0x39, 0xeb, 0xd7, 0xee, 0x9d, 0xb3, 0x7e, 0xf3, 0xde, 0x39, 0xeb, 0x77, 0xee, 0x9d, 0xb3, - 0x7e, 0xef, 0xde, 0x39, 0xeb, 0x0b, 0x7f, 0x70, 0xee, 0x3d, 0x9f, 0x40, 0x71, 0x98, 0xc8, 0x4b, - 0x74, 0x76, 0x2e, 0xed, 0x5d, 0xfe, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x9e, 0xe7, 0x8d, - 0x05, 0x08, 0x01, 0x00, + // 14685 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x69, 0x90, 0x5c, 0xd7, + 0x75, 0x18, 0xac, 0xd7, 0x3d, 0x5b, 0x9f, 0xd9, 0xef, 0x00, 0xe0, 0x60, 0x48, 0xa0, 0xc1, 0x47, + 0x12, 0x04, 0x45, 0x72, 0x20, 0x70, 0x91, 0x28, 0x52, 0xa2, 0x35, 0x2b, 0x30, 0x04, 0x66, 0xd0, + 0xbc, 0x3d, 0x00, 0x24, 0x8a, 0x52, 0xe9, 0x4d, 0xf7, 0x9d, 0x99, 0xa7, 0xe9, 0x7e, 0xaf, 0xf9, + 0xde, 0xeb, 0x01, 0x06, 0x9f, 0x54, 0x9f, 0x2d, 0xc7, 0x8b, 0x6c, 0x27, 0xa5, 0x4a, 0x39, 0x4b, + 0xc9, 0x2e, 0x57, 0xca, 0x76, 0x6c, 0x2b, 0xca, 0xa6, 0xc8, 0xb1, 0x1d, 0xcb, 0x5b, 0xb6, 0x8a, + 0x93, 0x4a, 0x39, 0x8e, 0xab, 0x62, 0xb9, 0xe2, 0xca, 0xc4, 0x82, 0x53, 0xe5, 0x52, 0x55, 0x62, + 0x3b, 0xcb, 0x8f, 0x64, 0xe2, 0xc4, 0xa9, 0xbb, 0xbe, 0x7b, 0xdf, 0xd2, 0xdd, 0x03, 0x0e, 0x46, + 0x94, 0x8a, 0xff, 0xba, 0xcf, 0x39, 0xf7, 0xdc, 0xfb, 0xee, 0x7a, 0xee, 0x39, 0xe7, 0x9e, 0x03, + 0xaf, 0xec, 0xbc, 0x14, 0xce, 0xba, 0xfe, 0xc5, 0x9d, 0xf6, 0x06, 0x09, 0x3c, 0x12, 0x91, 0xf0, + 0xe2, 0x2e, 0xf1, 0xea, 0x7e, 0x70, 0x51, 0x20, 0x9c, 0x96, 0x7b, 0xb1, 0xe6, 0x07, 0xe4, 0xe2, + 0xee, 0xa5, 0x8b, 0x5b, 0xc4, 0x23, 0x81, 0x13, 0x91, 0xfa, 0x6c, 0x2b, 0xf0, 0x23, 0x1f, 0x21, + 0x4e, 0x33, 0xeb, 0xb4, 0xdc, 0x59, 0x4a, 0x33, 0xbb, 0x7b, 0x69, 0xe6, 0xd9, 0x2d, 0x37, 0xda, + 0x6e, 0x6f, 0xcc, 0xd6, 0xfc, 0xe6, 0xc5, 0x2d, 0x7f, 0xcb, 0xbf, 0xc8, 0x48, 0x37, 0xda, 0x9b, + 0xec, 0x1f, 0xfb, 0xc3, 0x7e, 0x71, 0x16, 0x33, 0x2f, 0xc4, 0xd5, 0x34, 0x9d, 0xda, 0xb6, 0xeb, + 0x91, 0x60, 0xef, 0x62, 0x6b, 0x67, 0x8b, 0xd5, 0x1b, 0x90, 0xd0, 0x6f, 0x07, 0x35, 0x92, 0xac, + 0xb8, 0x63, 0xa9, 0xf0, 0x62, 0x93, 0x44, 0x4e, 0x46, 0x73, 0x67, 0x2e, 0xe6, 0x95, 0x0a, 0xda, + 0x5e, 0xe4, 0x36, 0xd3, 0xd5, 0xbc, 0xbf, 0x5b, 0x81, 0xb0, 0xb6, 0x4d, 0x9a, 0x4e, 0xaa, 0xdc, + 0xf3, 0x79, 0xe5, 0xda, 0x91, 0xdb, 0xb8, 0xe8, 0x7a, 0x51, 0x18, 0x05, 0xc9, 0x42, 0xf6, 0xd7, + 0x2d, 0x38, 0x37, 0x77, 0xab, 0xba, 0xd4, 0x70, 0xc2, 0xc8, 0xad, 0xcd, 0x37, 0xfc, 0xda, 0x4e, + 0x35, 0xf2, 0x03, 0x72, 0xd3, 0x6f, 0xb4, 0x9b, 0xa4, 0xca, 0x3a, 0x02, 0x3d, 0x03, 0x43, 0xbb, + 0xec, 0xff, 0xca, 0xe2, 0xb4, 0x75, 0xce, 0xba, 0x50, 0x9a, 0x9f, 0xf8, 0xcd, 0xfd, 0xf2, 0x7b, + 0xee, 0xed, 0x97, 0x87, 0x6e, 0x0a, 0x38, 0x56, 0x14, 0xe8, 0x3c, 0x0c, 0x6c, 0x86, 0xeb, 0x7b, + 0x2d, 0x32, 0x5d, 0x60, 0xb4, 0x63, 0x82, 0x76, 0x60, 0xb9, 0x4a, 0xa1, 0x58, 0x60, 0xd1, 0x45, + 0x28, 0xb5, 0x9c, 0x20, 0x72, 0x23, 0xd7, 0xf7, 0xa6, 0x8b, 0xe7, 0xac, 0x0b, 0xfd, 0xf3, 0x93, + 0x82, 0xb4, 0x54, 0x91, 0x08, 0x1c, 0xd3, 0xd0, 0x66, 0x04, 0xc4, 0xa9, 0x5f, 0xf7, 0x1a, 0x7b, + 0xd3, 0x7d, 0xe7, 0xac, 0x0b, 0x43, 0x71, 0x33, 0xb0, 0x80, 0x63, 0x45, 0x61, 0x7f, 0xb1, 0x00, + 0x43, 0x73, 0x9b, 0x9b, 0xae, 0xe7, 0x46, 0x7b, 0xe8, 0x26, 0x8c, 0x78, 0x7e, 0x9d, 0xc8, 0xff, + 0xec, 0x2b, 0x86, 0x9f, 0x3b, 0x37, 0x9b, 0x9e, 0x4a, 0xb3, 0x6b, 0x1a, 0xdd, 0xfc, 0xc4, 0xbd, + 0xfd, 0xf2, 0x88, 0x0e, 0xc1, 0x06, 0x1f, 0x84, 0x61, 0xb8, 0xe5, 0xd7, 0x15, 0xdb, 0x02, 0x63, + 0x5b, 0xce, 0x62, 0x5b, 0x89, 0xc9, 0xe6, 0xc7, 0xef, 0xed, 0x97, 0x87, 0x35, 0x00, 0xd6, 0x99, + 0xa0, 0x0d, 0x18, 0xa7, 0x7f, 0xbd, 0xc8, 0x55, 0x7c, 0x8b, 0x8c, 0xef, 0x63, 0x79, 0x7c, 0x35, + 0xd2, 0xf9, 0xa9, 0x7b, 0xfb, 0xe5, 0xf1, 0x04, 0x10, 0x27, 0x19, 0xda, 0x77, 0x61, 0x6c, 0x2e, + 0x8a, 0x9c, 0xda, 0x36, 0xa9, 0xf3, 0x11, 0x44, 0x2f, 0x40, 0x9f, 0xe7, 0x34, 0x89, 0x18, 0xdf, + 0x73, 0xa2, 0x63, 0xfb, 0xd6, 0x9c, 0x26, 0x39, 0xd8, 0x2f, 0x4f, 0xdc, 0xf0, 0xdc, 0xb7, 0xda, + 0x62, 0x56, 0x50, 0x18, 0x66, 0xd4, 0xe8, 0x39, 0x80, 0x3a, 0xd9, 0x75, 0x6b, 0xa4, 0xe2, 0x44, + 0xdb, 0x62, 0xbc, 0x91, 0x28, 0x0b, 0x8b, 0x0a, 0x83, 0x35, 0x2a, 0xfb, 0x0e, 0x94, 0xe6, 0x76, + 0x7d, 0xb7, 0x5e, 0xf1, 0xeb, 0x21, 0xda, 0x81, 0xf1, 0x56, 0x40, 0x36, 0x49, 0xa0, 0x40, 0xd3, + 0xd6, 0xb9, 0xe2, 0x85, 0xe1, 0xe7, 0x2e, 0x64, 0x7e, 0xac, 0x49, 0xba, 0xe4, 0x45, 0xc1, 0xde, + 0xfc, 0x43, 0xa2, 0xbe, 0xf1, 0x04, 0x16, 0x27, 0x39, 0xdb, 0xff, 0xac, 0x00, 0x27, 0xe7, 0xee, + 0xb6, 0x03, 0xb2, 0xe8, 0x86, 0x3b, 0xc9, 0x19, 0x5e, 0x77, 0xc3, 0x9d, 0xb5, 0xb8, 0x07, 0xd4, + 0xd4, 0x5a, 0x14, 0x70, 0xac, 0x28, 0xd0, 0xb3, 0x30, 0x48, 0x7f, 0xdf, 0xc0, 0x2b, 0xe2, 0x93, + 0xa7, 0x04, 0xf1, 0xf0, 0xa2, 0x13, 0x39, 0x8b, 0x1c, 0x85, 0x25, 0x0d, 0x5a, 0x85, 0xe1, 0x1a, + 0x5b, 0x90, 0x5b, 0xab, 0x7e, 0x9d, 0xb0, 0xc1, 0x2c, 0xcd, 0x3f, 0x4d, 0xc9, 0x17, 0x62, 0xf0, + 0xc1, 0x7e, 0x79, 0x9a, 0xb7, 0x4d, 0xb0, 0xd0, 0x70, 0x58, 0x2f, 0x8f, 0x6c, 0xb5, 0xbe, 0xfa, + 0x18, 0x27, 0xc8, 0x58, 0x5b, 0x17, 0xb4, 0xa5, 0xd2, 0xcf, 0x96, 0xca, 0x48, 0xf6, 0x32, 0x41, + 0x97, 0xa0, 0x6f, 0xc7, 0xf5, 0xea, 0xd3, 0x03, 0x8c, 0xd7, 0x19, 0x3a, 0xe6, 0x57, 0x5d, 0xaf, + 0x7e, 0xb0, 0x5f, 0x9e, 0x34, 0x9a, 0x43, 0x81, 0x98, 0x91, 0xda, 0xff, 0xdd, 0x82, 0x32, 0xc3, + 0x2d, 0xbb, 0x0d, 0x52, 0x21, 0x41, 0xe8, 0x86, 0x11, 0xf1, 0x22, 0xa3, 0x43, 0x9f, 0x03, 0x08, + 0x49, 0x2d, 0x20, 0x91, 0xd6, 0xa5, 0x6a, 0x62, 0x54, 0x15, 0x06, 0x6b, 0x54, 0x74, 0x43, 0x08, + 0xb7, 0x9d, 0x80, 0xcd, 0x2f, 0xd1, 0xb1, 0x6a, 0x43, 0xa8, 0x4a, 0x04, 0x8e, 0x69, 0x8c, 0x0d, + 0xa1, 0xd8, 0x6d, 0x43, 0x40, 0x1f, 0x86, 0xf1, 0xb8, 0xb2, 0xb0, 0xe5, 0xd4, 0x64, 0x07, 0xb2, + 0x25, 0x53, 0x35, 0x51, 0x38, 0x49, 0x6b, 0xff, 0x2d, 0x4b, 0x4c, 0x1e, 0xfa, 0xd5, 0xef, 0xf0, + 0x6f, 0xb5, 0x7f, 0xc9, 0x82, 0xc1, 0x79, 0xd7, 0xab, 0xbb, 0xde, 0x16, 0xfa, 0x14, 0x0c, 0xd1, + 0xb3, 0xa9, 0xee, 0x44, 0x8e, 0xd8, 0xf7, 0xde, 0xa7, 0xad, 0x2d, 0x75, 0x54, 0xcc, 0xb6, 0x76, + 0xb6, 0x28, 0x20, 0x9c, 0xa5, 0xd4, 0x74, 0xb5, 0x5d, 0xdf, 0xf8, 0x34, 0xa9, 0x45, 0xab, 0x24, + 0x72, 0xe2, 0xcf, 0x89, 0x61, 0x58, 0x71, 0x45, 0x57, 0x61, 0x20, 0x72, 0x82, 0x2d, 0x12, 0x89, + 0x0d, 0x30, 0x73, 0xa3, 0xe2, 0x25, 0x31, 0x5d, 0x91, 0xc4, 0xab, 0x91, 0xf8, 0x58, 0x58, 0x67, + 0x45, 0xb1, 0x60, 0x61, 0xff, 0x9f, 0x41, 0x38, 0xbd, 0x50, 0x5d, 0xc9, 0x99, 0x57, 0xe7, 0x61, + 0xa0, 0x1e, 0xb8, 0xbb, 0x24, 0x10, 0xfd, 0xac, 0xb8, 0x2c, 0x32, 0x28, 0x16, 0x58, 0xf4, 0x12, + 0x8c, 0xf0, 0x03, 0xe9, 0x8a, 0xe3, 0xd5, 0x1b, 0xb2, 0x8b, 0x4f, 0x08, 0xea, 0x91, 0x9b, 0x1a, + 0x0e, 0x1b, 0x94, 0x87, 0x9c, 0x54, 0xe7, 0x13, 0x8b, 0x31, 0xef, 0xb0, 0xfb, 0xbc, 0x05, 0x13, + 0xbc, 0x9a, 0xb9, 0x28, 0x0a, 0xdc, 0x8d, 0x76, 0x44, 0xc2, 0xe9, 0x7e, 0xb6, 0xd3, 0x2d, 0x64, + 0xf5, 0x56, 0x6e, 0x0f, 0xcc, 0xde, 0x4c, 0x70, 0xe1, 0x9b, 0xe0, 0xb4, 0xa8, 0x77, 0x22, 0x89, + 0xc6, 0xa9, 0x6a, 0xd1, 0xf7, 0x5a, 0x30, 0x53, 0xf3, 0xbd, 0x28, 0xf0, 0x1b, 0x0d, 0x12, 0x54, + 0xda, 0x1b, 0x0d, 0x37, 0xdc, 0xe6, 0xf3, 0x14, 0x93, 0x4d, 0xb6, 0x13, 0xe4, 0x8c, 0xa1, 0x22, + 0x12, 0x63, 0x78, 0xf6, 0xde, 0x7e, 0x79, 0x66, 0x21, 0x97, 0x15, 0xee, 0x50, 0x0d, 0xda, 0x01, + 0x44, 0x8f, 0xd2, 0x6a, 0xe4, 0x6c, 0x91, 0xb8, 0xf2, 0xc1, 0xde, 0x2b, 0x3f, 0x75, 0x6f, 0xbf, + 0x8c, 0xd6, 0x52, 0x2c, 0x70, 0x06, 0x5b, 0xf4, 0x16, 0x9c, 0xa0, 0xd0, 0xd4, 0xb7, 0x0e, 0xf5, + 0x5e, 0xdd, 0xf4, 0xbd, 0xfd, 0xf2, 0x89, 0xb5, 0x0c, 0x26, 0x38, 0x93, 0x35, 0xfa, 0x6e, 0x0b, + 0x4e, 0xc7, 0x9f, 0xbf, 0x74, 0xa7, 0xe5, 0x78, 0xf5, 0xb8, 0xe2, 0x52, 0xef, 0x15, 0xd3, 0x3d, + 0xf9, 0xf4, 0x42, 0x1e, 0x27, 0x9c, 0x5f, 0x09, 0xf2, 0x60, 0x8a, 0x36, 0x2d, 0x59, 0x37, 0xf4, + 0x5e, 0xf7, 0x43, 0xf7, 0xf6, 0xcb, 0x53, 0x6b, 0x69, 0x1e, 0x38, 0x8b, 0xf1, 0xcc, 0x02, 0x9c, + 0xcc, 0x9c, 0x9d, 0x68, 0x02, 0x8a, 0x3b, 0x84, 0x4b, 0x5d, 0x25, 0x4c, 0x7f, 0xa2, 0x13, 0xd0, + 0xbf, 0xeb, 0x34, 0xda, 0x62, 0x61, 0x62, 0xfe, 0xe7, 0xe5, 0xc2, 0x4b, 0x96, 0xfd, 0xcf, 0x8b, + 0x30, 0xbe, 0x50, 0x5d, 0xb9, 0xaf, 0x55, 0xaf, 0x1f, 0x7b, 0x85, 0x8e, 0xc7, 0x5e, 0x7c, 0x88, + 0x16, 0x73, 0x0f, 0xd1, 0xff, 0x3f, 0x63, 0xc9, 0xf6, 0xb1, 0x25, 0xfb, 0xc1, 0x9c, 0x25, 0x7b, + 0xc4, 0x0b, 0x75, 0x37, 0x67, 0xd6, 0xf6, 0xb3, 0x01, 0xcc, 0x94, 0x90, 0xae, 0xf9, 0x35, 0xa7, + 0x91, 0xdc, 0x6a, 0x0f, 0x39, 0x75, 0x8f, 0x66, 0x1c, 0x6b, 0x30, 0xb2, 0xe0, 0xb4, 0x9c, 0x0d, + 0xb7, 0xe1, 0x46, 0x2e, 0x09, 0xd1, 0x93, 0x50, 0x74, 0xea, 0x75, 0x26, 0xdd, 0x95, 0xe6, 0x4f, + 0xde, 0xdb, 0x2f, 0x17, 0xe7, 0xea, 0x54, 0xcc, 0x00, 0x45, 0xb5, 0x87, 0x29, 0x05, 0x7a, 0x2f, + 0xf4, 0xd5, 0x03, 0xbf, 0x35, 0x5d, 0x60, 0x94, 0x74, 0x95, 0xf7, 0x2d, 0x06, 0x7e, 0x2b, 0x41, + 0xca, 0x68, 0xec, 0xdf, 0x28, 0xc0, 0x23, 0x0b, 0xa4, 0xb5, 0xbd, 0x5c, 0xcd, 0x39, 0x2f, 0x2e, + 0xc0, 0x50, 0xd3, 0xf7, 0xdc, 0xc8, 0x0f, 0x42, 0x51, 0x35, 0x9b, 0x11, 0xab, 0x02, 0x86, 0x15, + 0x16, 0x9d, 0x83, 0xbe, 0x56, 0x2c, 0xc4, 0x8e, 0x48, 0x01, 0x98, 0x89, 0xaf, 0x0c, 0x43, 0x29, + 0xda, 0x21, 0x09, 0xc4, 0x8c, 0x51, 0x14, 0x37, 0x42, 0x12, 0x60, 0x86, 0x89, 0x25, 0x01, 0x2a, + 0x23, 0x88, 0x13, 0x21, 0x21, 0x09, 0x50, 0x0c, 0xd6, 0xa8, 0x50, 0x05, 0x4a, 0x61, 0x62, 0x64, + 0x7b, 0x5a, 0x9a, 0xa3, 0x4c, 0x54, 0x50, 0x23, 0x19, 0x33, 0x31, 0x4e, 0xb0, 0x81, 0xae, 0xa2, + 0xc2, 0xd7, 0x0a, 0x80, 0x78, 0x17, 0x7e, 0x9b, 0x75, 0xdc, 0x8d, 0x74, 0xc7, 0xf5, 0xbe, 0x24, + 0x8e, 0xaa, 0xf7, 0xfe, 0x87, 0x05, 0x8f, 0x2c, 0xb8, 0x5e, 0x9d, 0x04, 0x39, 0x13, 0xf0, 0xc1, + 0xdc, 0x9d, 0x0f, 0x27, 0xa4, 0x18, 0x53, 0xac, 0xef, 0x08, 0xa6, 0x98, 0xfd, 0x27, 0x16, 0x20, + 0xfe, 0xd9, 0xef, 0xb8, 0x8f, 0xbd, 0x91, 0xfe, 0xd8, 0x23, 0x98, 0x16, 0xf6, 0xdf, 0xb3, 0x60, + 0x78, 0xa1, 0xe1, 0xb8, 0x4d, 0xf1, 0xa9, 0x0b, 0x30, 0x29, 0x15, 0x45, 0x0c, 0xac, 0xc9, 0xfe, + 0x74, 0x73, 0x9b, 0xc4, 0x49, 0x24, 0x4e, 0xd3, 0xa3, 0x8f, 0xc3, 0x69, 0x03, 0xb8, 0x4e, 0x9a, + 0xad, 0x86, 0x13, 0xe9, 0xb7, 0x02, 0x76, 0xfa, 0xe3, 0x3c, 0x22, 0x9c, 0x5f, 0xde, 0xbe, 0x06, + 0x63, 0x0b, 0x0d, 0x97, 0x78, 0xd1, 0x4a, 0x65, 0xc1, 0xf7, 0x36, 0xdd, 0x2d, 0xf4, 0x32, 0x8c, + 0x45, 0x6e, 0x93, 0xf8, 0xed, 0xa8, 0x4a, 0x6a, 0xbe, 0xc7, 0xee, 0xda, 0xd6, 0x85, 0xfe, 0x79, + 0x74, 0x6f, 0xbf, 0x3c, 0xb6, 0x6e, 0x60, 0x70, 0x82, 0xd2, 0xfe, 0x7d, 0x3a, 0xe2, 0x7e, 0xb3, + 0xe5, 0x7b, 0xc4, 0x8b, 0x16, 0x7c, 0xaf, 0xce, 0x75, 0x32, 0x2f, 0x43, 0x5f, 0x44, 0x47, 0x90, + 0x7f, 0xf9, 0x79, 0xb9, 0xb4, 0xe9, 0xb8, 0x1d, 0xec, 0x97, 0x4f, 0xa5, 0x4b, 0xb0, 0x91, 0x65, + 0x65, 0xd0, 0x07, 0x61, 0x20, 0x8c, 0x9c, 0xa8, 0x1d, 0x8a, 0x4f, 0x7d, 0x54, 0x8e, 0x7f, 0x95, + 0x41, 0x0f, 0xf6, 0xcb, 0xe3, 0xaa, 0x18, 0x07, 0x61, 0x51, 0x00, 0x3d, 0x05, 0x83, 0x4d, 0x12, + 0x86, 0xce, 0x96, 0x3c, 0xbf, 0xc7, 0x45, 0xd9, 0xc1, 0x55, 0x0e, 0xc6, 0x12, 0x8f, 0x1e, 0x83, + 0x7e, 0x12, 0x04, 0x7e, 0x20, 0x76, 0x95, 0x51, 0x41, 0xd8, 0xbf, 0x44, 0x81, 0x98, 0xe3, 0xec, + 0x7f, 0x63, 0xc1, 0xb8, 0x6a, 0x2b, 0xaf, 0xeb, 0x18, 0xee, 0x4d, 0x6f, 0x00, 0xd4, 0xe4, 0x07, + 0x86, 0xec, 0xbc, 0x1b, 0x7e, 0xee, 0x7c, 0xa6, 0x68, 0x91, 0xea, 0xc6, 0x98, 0xb3, 0x02, 0x85, + 0x58, 0xe3, 0x66, 0xff, 0xaa, 0x05, 0x53, 0x89, 0x2f, 0xba, 0xe6, 0x86, 0x11, 0x7a, 0x33, 0xf5, + 0x55, 0xb3, 0xbd, 0x7d, 0x15, 0x2d, 0xcd, 0xbe, 0x49, 0x2d, 0x3e, 0x09, 0xd1, 0xbe, 0xe8, 0x0a, + 0xf4, 0xbb, 0x11, 0x69, 0xca, 0x8f, 0x79, 0xac, 0xe3, 0xc7, 0xf0, 0x56, 0xc5, 0x23, 0xb2, 0x42, + 0x4b, 0x62, 0xce, 0xc0, 0xfe, 0x8d, 0x22, 0x94, 0xf8, 0xb4, 0x5d, 0x75, 0x5a, 0xc7, 0x30, 0x16, + 0x4f, 0x43, 0xc9, 0x6d, 0x36, 0xdb, 0x91, 0xb3, 0x21, 0x0e, 0xa0, 0x21, 0xbe, 0x19, 0xac, 0x48, + 0x20, 0x8e, 0xf1, 0x68, 0x05, 0xfa, 0x58, 0x53, 0xf8, 0x57, 0x3e, 0x99, 0xfd, 0x95, 0xa2, 0xed, + 0xb3, 0x8b, 0x4e, 0xe4, 0x70, 0xd9, 0x4f, 0x9d, 0x7c, 0x14, 0x84, 0x19, 0x0b, 0xe4, 0x00, 0x6c, + 0xb8, 0x9e, 0x13, 0xec, 0x51, 0xd8, 0x74, 0x91, 0x31, 0x7c, 0xb6, 0x33, 0xc3, 0x79, 0x45, 0xcf, + 0xd9, 0xaa, 0x0f, 0x8b, 0x11, 0x58, 0x63, 0x3a, 0xf3, 0x01, 0x28, 0x29, 0xe2, 0xc3, 0x88, 0x70, + 0x33, 0x1f, 0x86, 0xf1, 0x44, 0x5d, 0xdd, 0x8a, 0x8f, 0xe8, 0x12, 0xe0, 0x2f, 0xb3, 0x2d, 0x43, + 0xb4, 0x7a, 0xc9, 0xdb, 0x15, 0x3b, 0xe7, 0x5d, 0x38, 0xd1, 0xc8, 0xd8, 0x7b, 0xc5, 0xb8, 0xf6, + 0xbe, 0x57, 0x3f, 0x22, 0x3e, 0xfb, 0x44, 0x16, 0x16, 0x67, 0xd6, 0x41, 0xa5, 0x1a, 0xbf, 0x45, + 0x17, 0x88, 0xd3, 0xd0, 0x2f, 0x08, 0xd7, 0x05, 0x0c, 0x2b, 0x2c, 0xdd, 0xef, 0x4e, 0xa8, 0xc6, + 0x5f, 0x25, 0x7b, 0x55, 0xd2, 0x20, 0xb5, 0xc8, 0x0f, 0xbe, 0xa5, 0xcd, 0x3f, 0xc3, 0x7b, 0x9f, + 0x6f, 0x97, 0xc3, 0x82, 0x41, 0xf1, 0x2a, 0xd9, 0xe3, 0x43, 0xa1, 0x7f, 0x5d, 0xb1, 0xe3, 0xd7, + 0x7d, 0xc5, 0x82, 0x51, 0xf5, 0x75, 0xc7, 0xb0, 0x2f, 0xcc, 0x9b, 0xfb, 0xc2, 0x99, 0x8e, 0x13, + 0x3c, 0x67, 0x47, 0xf8, 0x5a, 0x01, 0x4e, 0x2b, 0x1a, 0x7a, 0x9b, 0xe1, 0x7f, 0xc4, 0xac, 0xba, + 0x08, 0x25, 0x4f, 0xe9, 0xf5, 0x2c, 0x53, 0xa1, 0x16, 0x6b, 0xf5, 0x62, 0x1a, 0x2a, 0x94, 0x7a, + 0xf1, 0x31, 0x3b, 0xa2, 0x2b, 0xbc, 0x85, 0x72, 0x7b, 0x1e, 0x8a, 0x6d, 0xb7, 0x2e, 0x0e, 0x98, + 0xf7, 0xc9, 0xde, 0xbe, 0xb1, 0xb2, 0x78, 0xb0, 0x5f, 0x7e, 0x34, 0xcf, 0xd8, 0x42, 0x4f, 0xb6, + 0x70, 0xf6, 0xc6, 0xca, 0x22, 0xa6, 0x85, 0xd1, 0x1c, 0x8c, 0xcb, 0x13, 0xfa, 0x26, 0x15, 0x10, + 0x7d, 0x4f, 0x9c, 0x43, 0x4a, 0x6b, 0x8d, 0x4d, 0x34, 0x4e, 0xd2, 0xa3, 0x45, 0x98, 0xd8, 0x69, + 0x6f, 0x90, 0x06, 0x89, 0xf8, 0x07, 0x5f, 0x25, 0x5c, 0xa7, 0x5b, 0x8a, 0xef, 0x92, 0x57, 0x13, + 0x78, 0x9c, 0x2a, 0x61, 0xff, 0x39, 0x3b, 0x0f, 0x44, 0xef, 0x55, 0x02, 0x9f, 0x4e, 0x2c, 0xca, + 0xfd, 0x5b, 0x39, 0x9d, 0x7b, 0x99, 0x15, 0x57, 0xc9, 0xde, 0xba, 0x4f, 0xef, 0x12, 0xd9, 0xb3, + 0xc2, 0x98, 0xf3, 0x7d, 0x1d, 0xe7, 0xfc, 0xcf, 0x17, 0xe0, 0xa4, 0xea, 0x01, 0x43, 0x6c, 0xfd, + 0x76, 0xef, 0x83, 0x4b, 0x30, 0x5c, 0x27, 0x9b, 0x4e, 0xbb, 0x11, 0x29, 0x03, 0x43, 0x3f, 0x37, + 0x32, 0x2d, 0xc6, 0x60, 0xac, 0xd3, 0x1c, 0xa2, 0xdb, 0xfe, 0xfd, 0x08, 0x3b, 0x88, 0x23, 0x87, + 0xce, 0x71, 0xb5, 0x6a, 0xac, 0xdc, 0x55, 0xf3, 0x18, 0xf4, 0xbb, 0x4d, 0x2a, 0x98, 0x15, 0x4c, + 0x79, 0x6b, 0x85, 0x02, 0x31, 0xc7, 0xa1, 0x27, 0x60, 0xb0, 0xe6, 0x37, 0x9b, 0x8e, 0x57, 0x67, + 0x47, 0x5e, 0x69, 0x7e, 0x98, 0xca, 0x6e, 0x0b, 0x1c, 0x84, 0x25, 0x0e, 0x3d, 0x02, 0x7d, 0x4e, + 0xb0, 0xc5, 0xb5, 0x2e, 0xa5, 0xf9, 0x21, 0x5a, 0xd3, 0x5c, 0xb0, 0x15, 0x62, 0x06, 0xa5, 0x97, + 0xc6, 0xdb, 0x7e, 0xb0, 0xe3, 0x7a, 0x5b, 0x8b, 0x6e, 0x20, 0x96, 0x84, 0x3a, 0x0b, 0x6f, 0x29, + 0x0c, 0xd6, 0xa8, 0xd0, 0x32, 0xf4, 0xb7, 0xfc, 0x20, 0x0a, 0xa7, 0x07, 0x58, 0x77, 0x3f, 0x9a, + 0xb3, 0x11, 0xf1, 0xaf, 0xad, 0xf8, 0x41, 0x14, 0x7f, 0x00, 0xfd, 0x17, 0x62, 0x5e, 0x1c, 0x5d, + 0x83, 0x41, 0xe2, 0xed, 0x2e, 0x07, 0x7e, 0x73, 0x7a, 0x2a, 0x9f, 0xd3, 0x12, 0x27, 0xe1, 0xd3, + 0x2c, 0x96, 0x51, 0x05, 0x18, 0x4b, 0x16, 0xe8, 0x83, 0x50, 0x24, 0xde, 0xee, 0xf4, 0x20, 0xe3, + 0x34, 0x93, 0xc3, 0xe9, 0xa6, 0x13, 0xc4, 0x7b, 0xfe, 0x92, 0xb7, 0x8b, 0x69, 0x19, 0xf4, 0x31, + 0x28, 0xc9, 0x0d, 0x23, 0x14, 0xea, 0xcc, 0xcc, 0x09, 0x2b, 0xb7, 0x19, 0x4c, 0xde, 0x6a, 0xbb, + 0x01, 0x69, 0x12, 0x2f, 0x0a, 0xe3, 0x1d, 0x52, 0x62, 0x43, 0x1c, 0x73, 0x43, 0x35, 0x18, 0x09, + 0x48, 0xe8, 0xde, 0x25, 0x15, 0xbf, 0xe1, 0xd6, 0xf6, 0xa6, 0x1f, 0x62, 0xcd, 0x7b, 0xaa, 0x63, + 0x97, 0x61, 0xad, 0x40, 0xac, 0x6e, 0xd7, 0xa1, 0xd8, 0x60, 0x8a, 0x3e, 0x26, 0x15, 0xf5, 0xab, + 0x7e, 0xdb, 0x8b, 0xc2, 0xe9, 0x12, 0xab, 0x24, 0xd3, 0x84, 0x7a, 0x33, 0xa6, 0x4b, 0x6a, 0xf2, + 0x79, 0x61, 0x6c, 0xb0, 0x42, 0x9f, 0x80, 0x51, 0xfe, 0x9f, 0x1b, 0x22, 0xc3, 0xe9, 0x93, 0x8c, + 0xf7, 0xb9, 0x7c, 0xde, 0x9c, 0x70, 0xfe, 0xa4, 0x60, 0x3e, 0xaa, 0x43, 0x43, 0x6c, 0x72, 0x43, + 0x18, 0x46, 0x1b, 0xee, 0x2e, 0xf1, 0x48, 0x18, 0x56, 0x02, 0x7f, 0x83, 0x08, 0xbd, 0xea, 0xe9, + 0x6c, 0xc3, 0xa5, 0xbf, 0x41, 0xe6, 0x27, 0x29, 0xcf, 0x6b, 0x7a, 0x19, 0x6c, 0xb2, 0x40, 0x37, + 0x60, 0x8c, 0x5e, 0x64, 0xdd, 0x98, 0xe9, 0x70, 0x37, 0xa6, 0xec, 0xf2, 0x86, 0x8d, 0x42, 0x38, + 0xc1, 0x04, 0x5d, 0x87, 0x91, 0x30, 0x72, 0x82, 0xa8, 0xdd, 0xe2, 0x4c, 0x4f, 0x75, 0x63, 0xca, + 0xec, 0xde, 0x55, 0xad, 0x08, 0x36, 0x18, 0xa0, 0xd7, 0xa0, 0xd4, 0x70, 0x37, 0x49, 0x6d, 0xaf, + 0xd6, 0x20, 0xd3, 0x23, 0x8c, 0x5b, 0xe6, 0xce, 0x75, 0x4d, 0x12, 0x71, 0x61, 0x5a, 0xfd, 0xc5, + 0x71, 0x71, 0x74, 0x13, 0x4e, 0x45, 0x24, 0x68, 0xba, 0x9e, 0x43, 0x77, 0x1c, 0x71, 0x7f, 0x63, + 0xf6, 0xe4, 0x51, 0xb6, 0xa4, 0xcf, 0x8a, 0xd1, 0x38, 0xb5, 0x9e, 0x49, 0x85, 0x73, 0x4a, 0xa3, + 0x3b, 0x30, 0x9d, 0x81, 0xe1, 0x53, 0xf9, 0x04, 0xe3, 0xfc, 0x21, 0xc1, 0x79, 0x7a, 0x3d, 0x87, + 0xee, 0xa0, 0x03, 0x0e, 0xe7, 0x72, 0x47, 0xd7, 0x61, 0x9c, 0x6d, 0x73, 0x95, 0x76, 0xa3, 0x21, + 0x2a, 0x1c, 0x63, 0x15, 0x3e, 0x21, 0x0f, 0xfd, 0x15, 0x13, 0x7d, 0xb0, 0x5f, 0x86, 0xf8, 0x1f, + 0x4e, 0x96, 0x46, 0x1b, 0xcc, 0x74, 0xd9, 0x0e, 0xdc, 0x68, 0x8f, 0xae, 0x34, 0x72, 0x27, 0x9a, + 0x1e, 0xef, 0xa8, 0xc6, 0xd1, 0x49, 0x95, 0x7d, 0x53, 0x07, 0xe2, 0x24, 0x43, 0xba, 0x6f, 0x87, + 0x51, 0xdd, 0xf5, 0xa6, 0x27, 0xf8, 0xe5, 0x47, 0x6e, 0x7b, 0x55, 0x0a, 0xc4, 0x1c, 0xc7, 0xcc, + 0x96, 0xf4, 0xc7, 0x75, 0x7a, 0x3c, 0x4e, 0x32, 0xc2, 0xd8, 0x6c, 0x29, 0x11, 0x38, 0xa6, 0xa1, + 0x12, 0x6b, 0x14, 0xed, 0x4d, 0x23, 0x46, 0xaa, 0x76, 0xaf, 0xf5, 0xf5, 0x8f, 0x61, 0x0a, 0xb7, + 0x37, 0x60, 0x4c, 0x6d, 0x1d, 0xac, 0x4f, 0x50, 0x19, 0xfa, 0x99, 0x8c, 0x26, 0x94, 0x8e, 0x25, + 0xda, 0x04, 0x26, 0xbf, 0x61, 0x0e, 0x67, 0x4d, 0x70, 0xef, 0x92, 0xf9, 0xbd, 0x88, 0x70, 0xc5, + 0x41, 0x51, 0x6b, 0x82, 0x44, 0xe0, 0x98, 0xc6, 0xfe, 0xbf, 0x5c, 0xd6, 0x8d, 0xb7, 0xf4, 0x1e, + 0x0e, 0xb1, 0x67, 0x60, 0x68, 0xdb, 0x0f, 0x23, 0x4a, 0xcd, 0xea, 0xe8, 0x8f, 0xa5, 0xdb, 0x2b, + 0x02, 0x8e, 0x15, 0x05, 0x7a, 0x05, 0x46, 0x6b, 0x7a, 0x05, 0xe2, 0x04, 0x56, 0xdb, 0x88, 0x51, + 0x3b, 0x36, 0x69, 0xd1, 0x4b, 0x30, 0xc4, 0x5c, 0x71, 0x6a, 0x7e, 0x43, 0x88, 0x86, 0x52, 0x8c, + 0x18, 0xaa, 0x08, 0xf8, 0x81, 0xf6, 0x1b, 0x2b, 0x6a, 0x74, 0x1e, 0x06, 0x68, 0x13, 0x56, 0x2a, + 0xe2, 0xec, 0x53, 0xfa, 0xb3, 0x2b, 0x0c, 0x8a, 0x05, 0xd6, 0xfe, 0x55, 0x8b, 0x09, 0x3e, 0xe9, + 0x0d, 0x1a, 0x5d, 0x61, 0x3b, 0x3c, 0xdb, 0xee, 0x35, 0xfd, 0xd5, 0xe3, 0xda, 0xb6, 0xad, 0x70, + 0x07, 0x89, 0xff, 0xd8, 0x28, 0x89, 0xde, 0x80, 0xd1, 0x80, 0xb0, 0x2d, 0x42, 0x4c, 0x78, 0x7e, + 0xfa, 0xbf, 0x20, 0xbb, 0x00, 0xeb, 0xc8, 0x83, 0xfd, 0xf2, 0xc3, 0xf1, 0x79, 0x44, 0xdb, 0x63, + 0xa0, 0xb1, 0xc9, 0xca, 0xfe, 0xcb, 0x05, 0x6d, 0x96, 0x54, 0x23, 0x27, 0x22, 0xa8, 0x02, 0x83, + 0xb7, 0x1d, 0x37, 0x72, 0xbd, 0x2d, 0x21, 0xa4, 0x75, 0x3e, 0x95, 0x58, 0xa1, 0x5b, 0xbc, 0x00, + 0x17, 0x35, 0xc4, 0x1f, 0x2c, 0xd9, 0x50, 0x8e, 0x41, 0xdb, 0xf3, 0x28, 0xc7, 0x42, 0xaf, 0x1c, + 0x31, 0x2f, 0xc0, 0x39, 0x8a, 0x3f, 0x58, 0xb2, 0x41, 0x6f, 0x02, 0xc8, 0x1d, 0x82, 0xd4, 0x85, + 0x0b, 0xcf, 0x33, 0xdd, 0x99, 0xae, 0xab, 0x32, 0xf3, 0x63, 0x54, 0x90, 0x89, 0xff, 0x63, 0x8d, + 0x9f, 0x1d, 0x69, 0x63, 0xaa, 0x37, 0x06, 0x7d, 0x9c, 0x2e, 0x51, 0x27, 0x88, 0x48, 0x7d, 0x2e, + 0x12, 0x9d, 0xf3, 0xde, 0xde, 0x6e, 0x72, 0xeb, 0x6e, 0x93, 0xe8, 0xcb, 0x59, 0x30, 0xc1, 0x31, + 0x3f, 0xfb, 0x17, 0x8b, 0x30, 0x9d, 0xd7, 0x5c, 0xba, 0x68, 0xc8, 0x1d, 0x37, 0x5a, 0xa0, 0x32, + 0xa8, 0x65, 0x2e, 0x9a, 0x25, 0x01, 0xc7, 0x8a, 0x82, 0xce, 0xde, 0xd0, 0xdd, 0x92, 0x17, 0xf1, + 0xfe, 0x78, 0xf6, 0x56, 0x19, 0x14, 0x0b, 0x2c, 0xa5, 0x0b, 0x88, 0x13, 0x0a, 0x1f, 0x31, 0x6d, + 0x96, 0x63, 0x06, 0xc5, 0x02, 0xab, 0xab, 0x04, 0xfb, 0xba, 0xa8, 0x04, 0x8d, 0x2e, 0xea, 0x3f, + 0xda, 0x2e, 0x42, 0x9f, 0x04, 0xd8, 0x74, 0x3d, 0x37, 0xdc, 0x66, 0xdc, 0x07, 0x0e, 0xcd, 0x5d, + 0x49, 0xb0, 0xcb, 0x8a, 0x0b, 0xd6, 0x38, 0xa2, 0x17, 0x61, 0x58, 0x6d, 0x20, 0x2b, 0x8b, 0xcc, + 0x60, 0xae, 0x39, 0x20, 0xc5, 0xbb, 0xe9, 0x22, 0xd6, 0xe9, 0xec, 0x4f, 0x27, 0xe7, 0x8b, 0x58, + 0x01, 0x5a, 0xff, 0x5a, 0xbd, 0xf6, 0x6f, 0xa1, 0x73, 0xff, 0xda, 0xdf, 0x18, 0x80, 0x71, 0xa3, + 0xb2, 0x76, 0xd8, 0xc3, 0x9e, 0x7b, 0x99, 0x1e, 0x40, 0x4e, 0x44, 0xc4, 0xfa, 0xb3, 0xbb, 0x2f, + 0x15, 0xfd, 0x90, 0xa2, 0x2b, 0x80, 0x97, 0x47, 0x9f, 0x84, 0x52, 0xc3, 0x09, 0x99, 0x7a, 0x91, + 0x88, 0x75, 0xd7, 0x0b, 0xb3, 0xf8, 0xf6, 0xe6, 0x84, 0x91, 0x76, 0xea, 0x73, 0xde, 0x31, 0x4b, + 0x7a, 0x52, 0x52, 0xf9, 0x4a, 0x3a, 0x21, 0xaa, 0x46, 0x50, 0x21, 0x6c, 0x0f, 0x73, 0x1c, 0x7a, + 0x89, 0x6d, 0xad, 0x74, 0x56, 0x2c, 0x50, 0x69, 0x94, 0x4d, 0xb3, 0x7e, 0x43, 0x22, 0x56, 0x38, + 0x6c, 0x50, 0xc6, 0x17, 0xa8, 0x81, 0x0e, 0x17, 0xa8, 0xa7, 0x60, 0x90, 0xfd, 0x50, 0x33, 0x40, + 0x8d, 0xc6, 0x0a, 0x07, 0x63, 0x89, 0x4f, 0x4e, 0x98, 0xa1, 0xde, 0x26, 0x0c, 0xbd, 0xa2, 0x89, + 0x49, 0xcd, 0x9c, 0x15, 0x86, 0xf8, 0x2e, 0x27, 0xa6, 0x3c, 0x96, 0x38, 0xf4, 0xb3, 0x16, 0x20, + 0xa7, 0x41, 0xaf, 0xb6, 0x14, 0xac, 0x6e, 0x22, 0xc0, 0x44, 0xed, 0x57, 0xba, 0x76, 0x7b, 0x3b, + 0x9c, 0x9d, 0x4b, 0x95, 0xe6, 0x6a, 0xcd, 0x97, 0x45, 0x13, 0x51, 0x9a, 0x40, 0x3f, 0x8c, 0xae, + 0xb9, 0x61, 0xf4, 0xb9, 0xff, 0x98, 0x38, 0x9c, 0x32, 0x9a, 0x84, 0x6e, 0xe8, 0x37, 0xa5, 0xe1, + 0x43, 0xde, 0x94, 0x46, 0xf3, 0x6e, 0x49, 0x33, 0x6d, 0x78, 0x28, 0xe7, 0x0b, 0x32, 0x94, 0xa5, + 0x8b, 0xba, 0xb2, 0xb4, 0x8b, 0x8a, 0x6d, 0x56, 0xd6, 0x31, 0xfb, 0x7a, 0xdb, 0xf1, 0x22, 0x37, + 0xda, 0xd3, 0x95, 0xab, 0xef, 0x85, 0xb1, 0x45, 0x87, 0x34, 0x7d, 0x6f, 0xc9, 0xab, 0xb7, 0x7c, + 0xd7, 0x8b, 0xd0, 0x34, 0xf4, 0x31, 0xe1, 0x83, 0x6f, 0xbd, 0x7d, 0xb4, 0xf7, 0x30, 0x83, 0xd8, + 0x5b, 0x70, 0x72, 0xd1, 0xbf, 0xed, 0xdd, 0x76, 0x82, 0xfa, 0x5c, 0x65, 0x45, 0x53, 0xfe, 0xac, + 0x49, 0xe5, 0x83, 0x95, 0x7f, 0xb5, 0xd3, 0x4a, 0xf2, 0xeb, 0xd0, 0xb2, 0xdb, 0x20, 0x39, 0x2a, + 0xba, 0xbf, 0x56, 0x30, 0x6a, 0x8a, 0xe9, 0x95, 0x91, 0xd8, 0xca, 0x35, 0x12, 0xbf, 0x0e, 0x43, + 0x9b, 0x2e, 0x69, 0xd4, 0x31, 0xd9, 0x14, 0xbd, 0xf3, 0x64, 0xbe, 0x1b, 0xd9, 0x32, 0xa5, 0x94, + 0x2a, 0x59, 0xae, 0xba, 0x58, 0x16, 0x85, 0xb1, 0x62, 0x83, 0x76, 0x60, 0x42, 0xf6, 0xa1, 0xc4, + 0x8a, 0xfd, 0xe0, 0xa9, 0x4e, 0x03, 0x6f, 0x32, 0x3f, 0x71, 0x6f, 0xbf, 0x3c, 0x81, 0x13, 0x6c, + 0x70, 0x8a, 0x31, 0x7a, 0x04, 0xfa, 0x9a, 0xf4, 0xe4, 0xeb, 0x63, 0xdd, 0xcf, 0x74, 0x15, 0x4c, + 0xed, 0xc2, 0xa0, 0xf6, 0x8f, 0x5b, 0xf0, 0x50, 0xaa, 0x67, 0x84, 0xfa, 0xe9, 0x88, 0x47, 0x21, + 0xa9, 0x0e, 0x2a, 0x74, 0x57, 0x07, 0xd9, 0x7f, 0xdb, 0x82, 0x13, 0x4b, 0xcd, 0x56, 0xb4, 0xb7, + 0xe8, 0x9a, 0x16, 0xdd, 0x0f, 0xc0, 0x40, 0x93, 0xd4, 0xdd, 0x76, 0x53, 0x8c, 0x5c, 0x59, 0x9e, + 0x0e, 0xab, 0x0c, 0x7a, 0xb0, 0x5f, 0x1e, 0xad, 0x46, 0x7e, 0xe0, 0x6c, 0x11, 0x0e, 0xc0, 0x82, + 0x9c, 0x9d, 0xb1, 0xee, 0x5d, 0x72, 0xcd, 0x6d, 0xba, 0xd1, 0xfd, 0xcd, 0x76, 0x61, 0x8c, 0x95, + 0x4c, 0x70, 0xcc, 0xcf, 0xfe, 0xba, 0x05, 0xe3, 0x72, 0xde, 0xcf, 0xd5, 0xeb, 0x01, 0x09, 0x43, + 0x34, 0x03, 0x05, 0xb7, 0x25, 0x5a, 0x09, 0xa2, 0x95, 0x85, 0x95, 0x0a, 0x2e, 0xb8, 0x2d, 0x29, + 0xce, 0xb3, 0x03, 0xa8, 0x68, 0xda, 0xa5, 0xaf, 0x08, 0x38, 0x56, 0x14, 0xe8, 0x02, 0x0c, 0x79, + 0x7e, 0x9d, 0x4b, 0xc4, 0x5c, 0x94, 0x60, 0x13, 0x6c, 0x4d, 0xc0, 0xb0, 0xc2, 0xa2, 0x0a, 0x94, + 0xb8, 0xd7, 0x62, 0x3c, 0x69, 0x7b, 0xf2, 0x7d, 0x64, 0x5f, 0xb6, 0x2e, 0x4b, 0xe2, 0x98, 0x89, + 0xfd, 0xeb, 0x16, 0x8c, 0xc8, 0x2f, 0xeb, 0xf1, 0xae, 0x42, 0x97, 0x56, 0x7c, 0x4f, 0x89, 0x97, + 0x16, 0xbd, 0x6b, 0x30, 0x8c, 0x71, 0xc5, 0x28, 0x1e, 0xea, 0x8a, 0x71, 0x09, 0x86, 0x9d, 0x56, + 0xab, 0x62, 0xde, 0x4f, 0xd8, 0x54, 0x9a, 0x8b, 0xc1, 0x58, 0xa7, 0xb1, 0x7f, 0xac, 0x00, 0x63, + 0xf2, 0x0b, 0xaa, 0xed, 0x8d, 0x90, 0x44, 0x68, 0x1d, 0x4a, 0x0e, 0x1f, 0x25, 0x22, 0x27, 0xf9, + 0x63, 0xd9, 0x4a, 0x2e, 0x63, 0x48, 0x63, 0x41, 0x6b, 0x4e, 0x96, 0xc6, 0x31, 0x23, 0xd4, 0x80, + 0x49, 0xcf, 0x8f, 0xd8, 0xa1, 0xab, 0xf0, 0x9d, 0xec, 0x8e, 0x49, 0xee, 0xa7, 0x05, 0xf7, 0xc9, + 0xb5, 0x24, 0x17, 0x9c, 0x66, 0x8c, 0x96, 0xa4, 0xe2, 0xb0, 0x98, 0xaf, 0x44, 0xd2, 0x07, 0x2e, + 0x5b, 0x6f, 0x68, 0xff, 0x8a, 0x05, 0x25, 0x49, 0x76, 0x1c, 0x26, 0xe6, 0x55, 0x18, 0x0c, 0xd9, + 0x20, 0xc8, 0xae, 0xb1, 0x3b, 0x35, 0x9c, 0x8f, 0x57, 0x2c, 0x4b, 0xf0, 0xff, 0x21, 0x96, 0x3c, + 0x98, 0xdd, 0x48, 0x35, 0xff, 0x1d, 0x62, 0x37, 0x52, 0xed, 0xc9, 0x39, 0x94, 0xfe, 0x88, 0xb5, + 0x59, 0x53, 0xc4, 0x52, 0x91, 0xb7, 0x15, 0x90, 0x4d, 0xf7, 0x4e, 0x52, 0xe4, 0xad, 0x30, 0x28, + 0x16, 0x58, 0xf4, 0x26, 0x8c, 0xd4, 0xa4, 0xc1, 0x20, 0x5e, 0xe1, 0xe7, 0x3b, 0x1a, 0xaf, 0x94, + 0x9d, 0x93, 0xeb, 0xd0, 0x16, 0xb4, 0xf2, 0xd8, 0xe0, 0x66, 0x7a, 0xe5, 0x14, 0xbb, 0x79, 0xe5, + 0xc4, 0x7c, 0xf3, 0x7d, 0x54, 0x7e, 0xc2, 0x82, 0x01, 0xae, 0x28, 0xee, 0x4d, 0x4f, 0xaf, 0x99, + 0x7d, 0xe3, 0xbe, 0xbb, 0x49, 0x81, 0x42, 0xd2, 0x40, 0xab, 0x50, 0x62, 0x3f, 0x98, 0xa2, 0xbb, + 0x98, 0xff, 0x68, 0x86, 0xd7, 0xaa, 0x37, 0xf0, 0xa6, 0x2c, 0x86, 0x63, 0x0e, 0xf6, 0x8f, 0x16, + 0xe9, 0xee, 0x16, 0x93, 0x1a, 0x87, 0xbe, 0xf5, 0xe0, 0x0e, 0xfd, 0xc2, 0x83, 0x3a, 0xf4, 0xb7, + 0x60, 0xbc, 0xa6, 0x19, 0x89, 0xe3, 0x91, 0xbc, 0xd0, 0x71, 0x92, 0x68, 0xf6, 0x64, 0xae, 0x9d, + 0x5b, 0x30, 0x99, 0xe0, 0x24, 0x57, 0xf4, 0x71, 0x18, 0xe1, 0xe3, 0x2c, 0x6a, 0xe1, 0x8e, 0x4d, + 0x4f, 0xe4, 0xcf, 0x17, 0xbd, 0x0a, 0xae, 0xcd, 0xd5, 0x8a, 0x63, 0x83, 0x99, 0xfd, 0xa7, 0x16, + 0xa0, 0xa5, 0xd6, 0x36, 0x69, 0x92, 0xc0, 0x69, 0xc4, 0xb6, 0x9e, 0x1f, 0xb2, 0x60, 0x9a, 0xa4, + 0xc0, 0x0b, 0x7e, 0xb3, 0x29, 0x2e, 0x8b, 0x39, 0xfa, 0x8c, 0xa5, 0x9c, 0x32, 0xea, 0x55, 0xd1, + 0x74, 0x1e, 0x05, 0xce, 0xad, 0x0f, 0xad, 0xc2, 0x14, 0x3f, 0x25, 0x15, 0x42, 0x73, 0x92, 0x7a, + 0x58, 0x30, 0x9e, 0x5a, 0x4f, 0x93, 0xe0, 0xac, 0x72, 0xf6, 0x37, 0x47, 0x20, 0xb7, 0x15, 0xef, + 0x1a, 0xb9, 0xde, 0x35, 0x72, 0xbd, 0x6b, 0xe4, 0x7a, 0xd7, 0xc8, 0xf5, 0xae, 0x91, 0xeb, 0x5d, + 0x23, 0xd7, 0x51, 0x18, 0xb9, 0xfe, 0x8a, 0x05, 0x27, 0xd5, 0x59, 0x63, 0xdc, 0xae, 0x3f, 0x03, + 0x53, 0x7c, 0xb9, 0x19, 0xde, 0xbb, 0xe2, 0x6c, 0xbd, 0x94, 0x39, 0x73, 0x13, 0x5e, 0xe6, 0x46, + 0x41, 0xfe, 0x5c, 0x27, 0x03, 0x81, 0xb3, 0xaa, 0xb1, 0x7f, 0x71, 0x08, 0xfa, 0x97, 0x76, 0x89, + 0x17, 0x1d, 0xc3, 0x3d, 0xa4, 0x06, 0x63, 0xae, 0xb7, 0xeb, 0x37, 0x76, 0x49, 0x9d, 0xe3, 0x0f, + 0x73, 0x5d, 0x3e, 0x25, 0x58, 0x8f, 0xad, 0x18, 0x2c, 0x70, 0x82, 0xe5, 0x83, 0x30, 0x15, 0x5c, + 0x86, 0x01, 0x7e, 0x52, 0x08, 0x3b, 0x41, 0xe6, 0x9e, 0xcd, 0x3a, 0x51, 0x9c, 0x7f, 0xb1, 0x19, + 0x83, 0x9f, 0x44, 0xa2, 0x38, 0xfa, 0x34, 0x8c, 0x6d, 0xba, 0x41, 0x18, 0xad, 0xbb, 0x4d, 0x12, + 0x46, 0x4e, 0xb3, 0x75, 0x1f, 0xa6, 0x01, 0xd5, 0x0f, 0xcb, 0x06, 0x27, 0x9c, 0xe0, 0x8c, 0xb6, + 0x60, 0xb4, 0xe1, 0xe8, 0x55, 0x0d, 0x1e, 0xba, 0x2a, 0x75, 0x3a, 0x5c, 0xd3, 0x19, 0x61, 0x93, + 0x2f, 0x5d, 0x4e, 0x35, 0xa6, 0xdd, 0x1e, 0x62, 0xba, 0x07, 0xb5, 0x9c, 0xb8, 0x5a, 0x9b, 0xe3, + 0xa8, 0x34, 0xc5, 0x5c, 0xc4, 0x4b, 0xa6, 0x34, 0xa5, 0x39, 0x82, 0x7f, 0x0a, 0x4a, 0x84, 0x76, + 0x21, 0x65, 0x2c, 0x0e, 0x98, 0x8b, 0xbd, 0xb5, 0x75, 0xd5, 0xad, 0x05, 0xbe, 0x69, 0x94, 0x59, + 0x92, 0x9c, 0x70, 0xcc, 0x14, 0x2d, 0xc0, 0x40, 0x48, 0x02, 0x57, 0x29, 0x7e, 0x3b, 0x0c, 0x23, + 0x23, 0xe3, 0xef, 0xc1, 0xf8, 0x6f, 0x2c, 0x8a, 0xd2, 0xe9, 0xe5, 0x30, 0xbd, 0x29, 0x3b, 0x0c, + 0xb4, 0xe9, 0x35, 0xc7, 0xa0, 0x58, 0x60, 0xd1, 0x6b, 0x30, 0x18, 0x90, 0x06, 0xb3, 0xfa, 0x8d, + 0xf6, 0x3e, 0xc9, 0xb9, 0x11, 0x91, 0x97, 0xc3, 0x92, 0x01, 0xba, 0x0a, 0x28, 0x20, 0x54, 0x1a, + 0x73, 0xbd, 0x2d, 0xe5, 0x38, 0x2d, 0x36, 0x5a, 0x25, 0xf5, 0xe2, 0x98, 0x42, 0x3e, 0x05, 0xc4, + 0x19, 0xc5, 0xd0, 0x65, 0x98, 0x54, 0xd0, 0x15, 0x2f, 0x8c, 0x1c, 0xba, 0xc1, 0x8d, 0x33, 0x5e, + 0x4a, 0x19, 0x82, 0x93, 0x04, 0x38, 0x5d, 0xc6, 0xfe, 0x92, 0x05, 0xbc, 0x9f, 0x8f, 0x41, 0x05, + 0xf0, 0xaa, 0xa9, 0x02, 0x38, 0x9d, 0x3b, 0x72, 0x39, 0xd7, 0xff, 0x2f, 0x59, 0x30, 0xac, 0x8d, + 0x6c, 0x3c, 0x67, 0xad, 0x0e, 0x73, 0xb6, 0x0d, 0x13, 0x74, 0xa6, 0x5f, 0xdf, 0x08, 0x49, 0xb0, + 0x4b, 0xea, 0x6c, 0x62, 0x16, 0xee, 0x6f, 0x62, 0x2a, 0x27, 0xcd, 0x6b, 0x09, 0x86, 0x38, 0x55, + 0x85, 0xfd, 0x29, 0xd9, 0x54, 0xe5, 0xd3, 0x5a, 0x53, 0x63, 0x9e, 0xf0, 0x69, 0x55, 0xa3, 0x8a, + 0x63, 0x1a, 0xba, 0xd4, 0xb6, 0xfd, 0x30, 0x4a, 0xfa, 0xb4, 0x5e, 0xf1, 0xc3, 0x08, 0x33, 0x8c, + 0xfd, 0x3c, 0xc0, 0xd2, 0x1d, 0x52, 0xe3, 0x33, 0x56, 0xbf, 0xa1, 0x58, 0xf9, 0x37, 0x14, 0xfb, + 0x77, 0x2c, 0x18, 0x5b, 0x5e, 0x30, 0x4e, 0xae, 0x59, 0x00, 0x7e, 0xad, 0xba, 0x75, 0x6b, 0x4d, + 0xfa, 0x6a, 0x70, 0x73, 0xb5, 0x82, 0x62, 0x8d, 0x02, 0x9d, 0x86, 0x62, 0xa3, 0xed, 0x09, 0x1d, + 0xe5, 0x20, 0x3d, 0x1e, 0xaf, 0xb5, 0x3d, 0x4c, 0x61, 0xda, 0x33, 0xa0, 0x62, 0xcf, 0xcf, 0x80, + 0xba, 0x86, 0xff, 0x40, 0x65, 0xe8, 0xbf, 0x7d, 0xdb, 0xad, 0xf3, 0x47, 0xd6, 0xc2, 0x8f, 0xe4, + 0xd6, 0xad, 0x95, 0xc5, 0x10, 0x73, 0xb8, 0xfd, 0x85, 0x22, 0xcc, 0x2c, 0x37, 0xc8, 0x9d, 0xb7, + 0xf9, 0xd0, 0xbc, 0xd7, 0x47, 0x4c, 0x87, 0xd3, 0xf6, 0x1c, 0xf6, 0xa1, 0x5a, 0xf7, 0xfe, 0xd8, + 0x84, 0x41, 0xee, 0xd2, 0x29, 0x9f, 0x9d, 0x67, 0xda, 0xe6, 0xf2, 0x3b, 0x64, 0x96, 0xbb, 0x86, + 0x0a, 0xdb, 0x9c, 0x3a, 0x30, 0x05, 0x14, 0x4b, 0xe6, 0x33, 0x2f, 0xc3, 0x88, 0x4e, 0x79, 0xa8, + 0x27, 0xa3, 0xdf, 0x53, 0x84, 0x09, 0xda, 0x82, 0x07, 0x3a, 0x10, 0x37, 0xd2, 0x03, 0x71, 0xd4, + 0xcf, 0x06, 0xbb, 0x8f, 0xc6, 0x9b, 0xc9, 0xd1, 0xb8, 0x94, 0x37, 0x1a, 0xc7, 0x3d, 0x06, 0xdf, + 0x6b, 0xc1, 0xd4, 0x72, 0xc3, 0xaf, 0xed, 0x24, 0x9e, 0xf6, 0xbd, 0x08, 0xc3, 0x74, 0x3b, 0x0e, + 0x8d, 0x28, 0x17, 0x46, 0xdc, 0x13, 0x81, 0xc2, 0x3a, 0x9d, 0x56, 0xec, 0xc6, 0x8d, 0x95, 0xc5, + 0xac, 0x70, 0x29, 0x02, 0x85, 0x75, 0x3a, 0xfb, 0xb7, 0x2c, 0x38, 0x73, 0x79, 0x61, 0x29, 0x9e, + 0x8a, 0xa9, 0x88, 0x2d, 0xe7, 0x61, 0xa0, 0x55, 0xd7, 0x9a, 0x12, 0xeb, 0x70, 0x17, 0x59, 0x2b, + 0x04, 0xf6, 0x9d, 0x12, 0x8d, 0xe8, 0x06, 0xc0, 0x65, 0x5c, 0x59, 0x10, 0xfb, 0xae, 0x34, 0xd9, + 0x58, 0xb9, 0x26, 0x9b, 0x27, 0x60, 0x90, 0x9e, 0x0b, 0x6e, 0x4d, 0xb6, 0x9b, 0x5b, 0xdf, 0x39, + 0x08, 0x4b, 0x9c, 0xfd, 0x73, 0x16, 0x4c, 0x5d, 0x76, 0x23, 0x7a, 0x68, 0x27, 0x43, 0x92, 0xd0, + 0x53, 0x3b, 0x74, 0x23, 0x3f, 0xd8, 0x4b, 0x86, 0x24, 0xc1, 0x0a, 0x83, 0x35, 0x2a, 0xfe, 0x41, + 0xbb, 0x2e, 0x7b, 0xa3, 0x50, 0x30, 0x8d, 0x64, 0x58, 0xc0, 0xb1, 0xa2, 0xa0, 0xfd, 0x55, 0x77, + 0x03, 0xa6, 0x5f, 0xdc, 0x13, 0x1b, 0xb7, 0xea, 0xaf, 0x45, 0x89, 0xc0, 0x31, 0x8d, 0xfd, 0xc7, + 0x16, 0x94, 0x2f, 0x37, 0xda, 0x61, 0x44, 0x82, 0xcd, 0x30, 0x67, 0xd3, 0x7d, 0x1e, 0x4a, 0x44, + 0x6a, 0xf3, 0xe5, 0x63, 0x4a, 0x29, 0x88, 0x2a, 0x35, 0x3f, 0x8f, 0x8c, 0xa2, 0xe8, 0x7a, 0x78, + 0x7f, 0x7c, 0xb8, 0x07, 0xa4, 0xcb, 0x80, 0x88, 0x5e, 0x97, 0x1e, 0x2a, 0x86, 0xc5, 0x9c, 0x58, + 0x4a, 0x61, 0x71, 0x46, 0x09, 0xfb, 0xc7, 0x2d, 0x38, 0xa9, 0x3e, 0xf8, 0x1d, 0xf7, 0x99, 0xf6, + 0x57, 0x0b, 0x30, 0x7a, 0x65, 0x7d, 0xbd, 0x72, 0x99, 0x44, 0xda, 0xac, 0xec, 0x6c, 0xa3, 0xc7, + 0x9a, 0xa9, 0xb1, 0xd3, 0x1d, 0xb1, 0x1d, 0xb9, 0x8d, 0x59, 0x1e, 0x71, 0x6c, 0x76, 0xc5, 0x8b, + 0xae, 0x07, 0xd5, 0x28, 0x70, 0xbd, 0xad, 0xcc, 0x99, 0x2e, 0x65, 0x96, 0x62, 0x9e, 0xcc, 0x82, + 0x9e, 0x87, 0x01, 0x16, 0xf2, 0x4c, 0x0e, 0xc2, 0xc3, 0xea, 0x8a, 0xc5, 0xa0, 0x07, 0xfb, 0xe5, + 0xd2, 0x0d, 0xbc, 0xc2, 0xff, 0x60, 0x41, 0x8a, 0x6e, 0xc0, 0xf0, 0x76, 0x14, 0xb5, 0xae, 0x10, + 0xa7, 0x4e, 0x02, 0xb9, 0xcb, 0x9e, 0xcd, 0xda, 0x65, 0x69, 0x27, 0x70, 0xb2, 0x78, 0x63, 0x8a, + 0x61, 0x21, 0xd6, 0xf9, 0xd8, 0x55, 0x80, 0x18, 0x77, 0x44, 0x56, 0x16, 0x7b, 0x1d, 0x4a, 0xf4, + 0x73, 0xe7, 0x1a, 0xae, 0xd3, 0xd9, 0x8e, 0xfd, 0x34, 0x94, 0xa4, 0x95, 0x3a, 0x14, 0xf1, 0x11, + 0xd8, 0x89, 0x24, 0x8d, 0xd8, 0x21, 0x8e, 0xf1, 0xf6, 0x26, 0x9c, 0x60, 0xbe, 0xaa, 0x4e, 0xb4, + 0x6d, 0xcc, 0xbe, 0xee, 0xc3, 0xfc, 0x8c, 0xb8, 0xb1, 0xf1, 0x36, 0x4f, 0x6b, 0x0f, 0x7a, 0x47, + 0x24, 0xc7, 0xf8, 0xf6, 0x66, 0x7f, 0xb3, 0x0f, 0x1e, 0x5e, 0xa9, 0xe6, 0x87, 0xec, 0x79, 0x09, + 0x46, 0xb8, 0x20, 0x48, 0x07, 0xdd, 0x69, 0x88, 0x7a, 0x95, 0x6e, 0x73, 0x5d, 0xc3, 0x61, 0x83, + 0x12, 0x9d, 0x81, 0xa2, 0xfb, 0x96, 0x97, 0x7c, 0xee, 0xb6, 0xf2, 0xfa, 0x1a, 0xa6, 0x70, 0x8a, + 0xa6, 0x32, 0x25, 0xdf, 0xac, 0x15, 0x5a, 0xc9, 0x95, 0xaf, 0xc2, 0x98, 0x1b, 0xd6, 0x42, 0x77, + 0xc5, 0xa3, 0x2b, 0x50, 0x5b, 0xc3, 0x4a, 0x9b, 0x40, 0x1b, 0xad, 0xb0, 0x38, 0x41, 0xad, 0x9d, + 0x1c, 0xfd, 0x3d, 0xcb, 0xa5, 0x5d, 0x03, 0x06, 0xd0, 0x8d, 0xbd, 0xc5, 0xbe, 0x2e, 0x64, 0x9a, + 0x70, 0xb1, 0xb1, 0xf3, 0x0f, 0x0e, 0xb1, 0xc4, 0xd1, 0xab, 0x5a, 0x6d, 0xdb, 0x69, 0xcd, 0xb5, + 0xa3, 0xed, 0x45, 0x37, 0xac, 0xf9, 0xbb, 0x24, 0xd8, 0x63, 0xb7, 0xec, 0xa1, 0xf8, 0xaa, 0xa6, + 0x10, 0x0b, 0x57, 0xe6, 0x2a, 0x94, 0x12, 0xa7, 0xcb, 0xa0, 0x39, 0x18, 0x97, 0xc0, 0x2a, 0x09, + 0xd9, 0xe6, 0x3e, 0xcc, 0xd8, 0xa8, 0x07, 0x68, 0x02, 0xac, 0x98, 0x24, 0xe9, 0x4d, 0xd1, 0x15, + 0x8e, 0x42, 0x74, 0xfd, 0x00, 0x8c, 0xba, 0x9e, 0x1b, 0xb9, 0x4e, 0xe4, 0x73, 0x33, 0x0e, 0xbf, + 0x50, 0x33, 0xd5, 0xf1, 0x8a, 0x8e, 0xc0, 0x26, 0x9d, 0xfd, 0x9f, 0xfa, 0x60, 0x92, 0x0d, 0xdb, + 0xbb, 0x33, 0xec, 0x3b, 0x69, 0x86, 0xdd, 0x48, 0xcf, 0xb0, 0xa3, 0x90, 0xc9, 0xef, 0x7b, 0x9a, + 0x7d, 0x1a, 0x4a, 0xea, 0xcd, 0x9d, 0x7c, 0x74, 0x6b, 0xe5, 0x3c, 0xba, 0xed, 0x7e, 0x2e, 0x4b, + 0xcf, 0xb0, 0x62, 0xa6, 0x67, 0xd8, 0x97, 0x2d, 0x88, 0x4d, 0x06, 0xe8, 0x75, 0x28, 0xb5, 0x7c, + 0xe6, 0x68, 0x1a, 0x48, 0xef, 0xed, 0xc7, 0x3b, 0xda, 0x1c, 0x78, 0xd4, 0xb2, 0x80, 0xf7, 0x42, + 0x45, 0x16, 0xc5, 0x31, 0x17, 0x74, 0x15, 0x06, 0x5b, 0x01, 0xa9, 0x46, 0x2c, 0xa4, 0x4e, 0xef, + 0x0c, 0xf9, 0xac, 0xe1, 0x05, 0xb1, 0xe4, 0x60, 0xff, 0x67, 0x0b, 0x26, 0x92, 0xa4, 0xe8, 0x43, + 0xd0, 0x47, 0xee, 0x90, 0x9a, 0x68, 0x6f, 0xe6, 0x21, 0x1b, 0x2b, 0x1d, 0x78, 0x07, 0xd0, 0xff, + 0x98, 0x95, 0x42, 0x57, 0x60, 0x90, 0x9e, 0xb0, 0x97, 0x55, 0xf8, 0xb8, 0x47, 0xf3, 0x4e, 0x69, + 0x25, 0xaa, 0xf0, 0xc6, 0x09, 0x10, 0x96, 0xc5, 0x99, 0x3b, 0x56, 0xad, 0x55, 0xa5, 0x97, 0x97, + 0xa8, 0xd3, 0x1d, 0x7b, 0x7d, 0xa1, 0xc2, 0x89, 0x04, 0x37, 0xee, 0x8e, 0x25, 0x81, 0x38, 0x66, + 0x62, 0xff, 0xbc, 0x05, 0xc0, 0xbd, 0xcf, 0x1c, 0x6f, 0x8b, 0x1c, 0x83, 0x9e, 0x7c, 0x11, 0xfa, + 0xc2, 0x16, 0xa9, 0x75, 0xf2, 0x81, 0x8e, 0xdb, 0x53, 0x6d, 0x91, 0x5a, 0x3c, 0xe3, 0xe8, 0x3f, + 0xcc, 0x4a, 0xdb, 0xdf, 0x07, 0x30, 0x16, 0x93, 0xad, 0x44, 0xa4, 0x89, 0x9e, 0x35, 0x02, 0x75, + 0x9c, 0x4e, 0x04, 0xea, 0x28, 0x31, 0x6a, 0x4d, 0x25, 0xfb, 0x69, 0x28, 0x36, 0x9d, 0x3b, 0x42, + 0xe7, 0xf6, 0x74, 0xe7, 0x66, 0x50, 0xfe, 0xb3, 0xab, 0xce, 0x1d, 0x7e, 0x2d, 0x7d, 0x5a, 0xae, + 0x90, 0x55, 0xe7, 0x4e, 0x57, 0x3f, 0x5d, 0x5a, 0x09, 0xab, 0xcb, 0xf5, 0x84, 0x63, 0x55, 0x4f, + 0x75, 0xb9, 0x5e, 0xb2, 0x2e, 0xd7, 0xeb, 0xa1, 0x2e, 0xd7, 0x43, 0x77, 0x61, 0x50, 0xf8, 0x3d, + 0x8a, 0x50, 0x5e, 0x17, 0x7b, 0xa8, 0x4f, 0xb8, 0x4d, 0xf2, 0x3a, 0x2f, 0xca, 0x6b, 0xb7, 0x80, + 0x76, 0xad, 0x57, 0x56, 0x88, 0xfe, 0xaa, 0x05, 0x63, 0xe2, 0x37, 0x26, 0x6f, 0xb5, 0x49, 0x18, + 0x09, 0xb1, 0xf4, 0xfd, 0xbd, 0xb7, 0x41, 0x14, 0xe4, 0x4d, 0x79, 0xbf, 0x3c, 0x67, 0x4c, 0x64, + 0xd7, 0x16, 0x25, 0x5a, 0x81, 0xfe, 0xae, 0x05, 0x27, 0x9a, 0xce, 0x1d, 0x5e, 0x23, 0x87, 0x61, + 0x27, 0x72, 0x7d, 0xe1, 0x3f, 0xf0, 0xa1, 0xde, 0x86, 0x3f, 0x55, 0x9c, 0x37, 0x52, 0xda, 0x1f, + 0x4f, 0x64, 0x91, 0x74, 0x6d, 0x6a, 0x66, 0xbb, 0x66, 0x36, 0x61, 0x48, 0xce, 0xb7, 0x07, 0xe9, + 0x64, 0xcd, 0xea, 0x11, 0x73, 0xed, 0x81, 0xd6, 0xf3, 0x69, 0x18, 0xd1, 0xe7, 0xd8, 0x03, 0xad, + 0xeb, 0x2d, 0x98, 0xca, 0x98, 0x4b, 0x0f, 0xb4, 0xca, 0xdb, 0x70, 0x3a, 0x77, 0x7e, 0x3c, 0x50, + 0x27, 0xf9, 0xaf, 0x5a, 0xfa, 0x3e, 0x78, 0x0c, 0xc6, 0x8a, 0x05, 0xd3, 0x58, 0x71, 0xb6, 0xf3, + 0xca, 0xc9, 0xb1, 0x58, 0xbc, 0xa9, 0x37, 0x9a, 0xee, 0xea, 0xe8, 0x35, 0x18, 0x68, 0x50, 0x88, + 0xf4, 0x9e, 0xb5, 0xbb, 0xaf, 0xc8, 0x58, 0x98, 0x64, 0xf0, 0x10, 0x0b, 0x0e, 0xf6, 0x2f, 0x59, + 0xd0, 0x77, 0x0c, 0x3d, 0x81, 0xcd, 0x9e, 0x78, 0x36, 0x97, 0xb5, 0x88, 0x6a, 0x3e, 0x8b, 0x9d, + 0xdb, 0x4b, 0x77, 0x22, 0xe2, 0x85, 0xec, 0x44, 0xce, 0xec, 0x98, 0x9f, 0xb6, 0x60, 0xea, 0x9a, + 0xef, 0xd4, 0xe7, 0x9d, 0x86, 0xe3, 0xd5, 0x48, 0xb0, 0xe2, 0x6d, 0x1d, 0xca, 0xf5, 0xbb, 0xd0, + 0xd5, 0xf5, 0x7b, 0x41, 0x7a, 0x4e, 0xf5, 0xe5, 0x8f, 0x1f, 0x95, 0xa4, 0x93, 0xa1, 0x8b, 0x0c, + 0x1f, 0xdf, 0x6d, 0x40, 0x7a, 0x2b, 0xc5, 0x03, 0x28, 0x0c, 0x83, 0x2e, 0x6f, 0xaf, 0x18, 0xc4, + 0x27, 0xb3, 0x25, 0xdc, 0xd4, 0xe7, 0x69, 0x4f, 0x7b, 0x38, 0x00, 0x4b, 0x46, 0xf6, 0x4b, 0x90, + 0x19, 0x6a, 0xa2, 0xbb, 0x5e, 0xc2, 0xfe, 0x18, 0x4c, 0xb2, 0x92, 0x87, 0xd4, 0x0c, 0xd8, 0x09, + 0x6d, 0x6a, 0x46, 0xd8, 0x4c, 0xfb, 0xf3, 0x16, 0x8c, 0xaf, 0x25, 0xa2, 0x09, 0x9e, 0x67, 0xf6, + 0xd7, 0x0c, 0x25, 0x7e, 0x95, 0x41, 0xb1, 0xc0, 0x1e, 0xb9, 0x92, 0xeb, 0xcf, 0x2d, 0x88, 0xa3, + 0xbf, 0x1c, 0x83, 0xf8, 0xb6, 0x60, 0x88, 0x6f, 0x99, 0x82, 0xac, 0x6a, 0x4e, 0x9e, 0xf4, 0x86, + 0xae, 0xaa, 0xb8, 0x68, 0x1d, 0x64, 0xd8, 0x98, 0x0d, 0x9f, 0x8a, 0x63, 0x66, 0xf0, 0x34, 0x19, + 0x29, 0xcd, 0xfe, 0xdd, 0x02, 0x20, 0x45, 0xdb, 0x73, 0xdc, 0xb6, 0x74, 0x89, 0xa3, 0x89, 0xdb, + 0xb6, 0x0b, 0x88, 0x79, 0x10, 0x04, 0x8e, 0x17, 0x72, 0xb6, 0xae, 0x50, 0xeb, 0x1d, 0xce, 0x3d, + 0x61, 0x46, 0xbe, 0x0d, 0xbb, 0x96, 0xe2, 0x86, 0x33, 0x6a, 0xd0, 0x3c, 0x43, 0xfa, 0x7b, 0xf5, + 0x0c, 0x19, 0xe8, 0xf2, 0xc8, 0xf1, 0x2b, 0x16, 0x8c, 0xaa, 0x6e, 0x7a, 0x87, 0xb8, 0xc2, 0xab, + 0xf6, 0xe4, 0x6c, 0xa0, 0x15, 0xad, 0xc9, 0xec, 0x60, 0xf9, 0x2e, 0xf6, 0x58, 0xd5, 0x69, 0xb8, + 0x77, 0x89, 0x8a, 0xf3, 0x59, 0x16, 0x8f, 0x4f, 0x05, 0xf4, 0x60, 0xbf, 0x3c, 0xaa, 0xfe, 0xf1, + 0x38, 0xe6, 0x71, 0x11, 0xba, 0x25, 0x8f, 0x27, 0xa6, 0x22, 0x7a, 0x11, 0xfa, 0x5b, 0xdb, 0x4e, + 0x48, 0x12, 0x4f, 0x86, 0xfa, 0x2b, 0x14, 0x78, 0xb0, 0x5f, 0x1e, 0x53, 0x05, 0x18, 0x04, 0x73, + 0xea, 0xde, 0xa3, 0xe1, 0xa5, 0x27, 0x67, 0xd7, 0x68, 0x78, 0x7f, 0x6a, 0x41, 0xdf, 0x9a, 0x5f, + 0x3f, 0x8e, 0x2d, 0xe0, 0x55, 0x63, 0x0b, 0x78, 0x24, 0x2f, 0xc5, 0x44, 0xee, 0xea, 0x5f, 0x4e, + 0xac, 0xfe, 0xb3, 0xb9, 0x1c, 0x3a, 0x2f, 0xfc, 0x26, 0x0c, 0xb3, 0xc4, 0x15, 0xe2, 0x79, 0xd4, + 0xf3, 0xc6, 0x82, 0x2f, 0x27, 0x16, 0xfc, 0xb8, 0x46, 0xaa, 0xad, 0xf4, 0xa7, 0x60, 0x50, 0xbc, + 0xb7, 0x49, 0xbe, 0xf9, 0x15, 0xb4, 0x58, 0xe2, 0xed, 0x9f, 0x28, 0x82, 0x91, 0x28, 0x03, 0xfd, + 0x8a, 0x05, 0xb3, 0x01, 0xf7, 0xc3, 0xad, 0x2f, 0xb6, 0x03, 0xd7, 0xdb, 0xaa, 0xd6, 0xb6, 0x49, + 0xbd, 0xdd, 0x70, 0xbd, 0xad, 0x95, 0x2d, 0xcf, 0x57, 0xe0, 0xa5, 0x3b, 0xa4, 0xd6, 0x66, 0x66, + 0xb7, 0x2e, 0x59, 0x39, 0x94, 0x3f, 0xfb, 0x73, 0xf7, 0xf6, 0xcb, 0xb3, 0xf8, 0x50, 0xbc, 0xf1, + 0x21, 0xdb, 0x82, 0x7e, 0xcb, 0x82, 0x8b, 0x3c, 0x7f, 0x44, 0xef, 0xed, 0xef, 0x70, 0x5b, 0xae, + 0x48, 0x56, 0x31, 0x93, 0x75, 0x12, 0x34, 0xe7, 0x3f, 0x20, 0x3a, 0xf4, 0x62, 0xe5, 0x70, 0x75, + 0xe1, 0xc3, 0x36, 0xce, 0xfe, 0xc7, 0x45, 0x18, 0x15, 0x51, 0xd3, 0xc4, 0x19, 0xf0, 0xa2, 0x31, + 0x25, 0x1e, 0x4d, 0x4c, 0x89, 0x49, 0x83, 0xf8, 0x68, 0xb6, 0xff, 0x10, 0x26, 0xe9, 0xe6, 0x7c, + 0x85, 0x38, 0x41, 0xb4, 0x41, 0x1c, 0xee, 0xf0, 0x55, 0x3c, 0xf4, 0xee, 0xaf, 0xf4, 0x93, 0xd7, + 0x92, 0xcc, 0x70, 0x9a, 0xff, 0x77, 0xd2, 0x99, 0xe3, 0xc1, 0x44, 0x2a, 0xf0, 0xdd, 0x1b, 0x50, + 0x52, 0x8f, 0x45, 0xc4, 0xa6, 0xd3, 0x39, 0x7e, 0x64, 0x92, 0x03, 0x57, 0x7f, 0xc5, 0x0f, 0x95, + 0x62, 0x76, 0xf6, 0xdf, 0x2f, 0x18, 0x15, 0xf2, 0x41, 0x5c, 0x83, 0x21, 0x27, 0x0c, 0xdd, 0x2d, + 0x8f, 0xd4, 0x3b, 0x69, 0x28, 0x53, 0xd5, 0xb0, 0x07, 0x3b, 0x73, 0xa2, 0x24, 0x56, 0x3c, 0xd0, + 0x15, 0xee, 0x56, 0xb7, 0x4b, 0x3a, 0xa9, 0x27, 0x53, 0xdc, 0x40, 0x3a, 0xde, 0xed, 0x12, 0x2c, + 0xca, 0xa3, 0x4f, 0x70, 0xbf, 0xc7, 0xab, 0x9e, 0x7f, 0xdb, 0xbb, 0xec, 0xfb, 0x32, 0xe8, 0x46, + 0x6f, 0x0c, 0x27, 0xa5, 0xb7, 0xa3, 0x2a, 0x8e, 0x4d, 0x6e, 0xbd, 0x45, 0x92, 0xfd, 0x0c, 0xb0, + 0x78, 0xf9, 0xe6, 0xdb, 0xec, 0x10, 0x11, 0x18, 0x17, 0x21, 0xf9, 0x24, 0x4c, 0xf4, 0x5d, 0xe6, + 0x55, 0xce, 0x2c, 0x1d, 0x2b, 0xd2, 0xaf, 0x9a, 0x2c, 0x70, 0x92, 0xa7, 0xfd, 0xb3, 0x16, 0xb0, + 0x77, 0xaa, 0xc7, 0x20, 0x8f, 0x7c, 0xd8, 0x94, 0x47, 0xa6, 0xf3, 0x3a, 0x39, 0x47, 0x14, 0x79, + 0x81, 0xcf, 0xac, 0x4a, 0xe0, 0xdf, 0xd9, 0x13, 0xce, 0x2a, 0xdd, 0xef, 0x1f, 0xf6, 0xff, 0xb6, + 0xf8, 0x26, 0x16, 0xbf, 0xea, 0xff, 0x2c, 0x0c, 0xd5, 0x9c, 0x96, 0x53, 0xe3, 0x59, 0x9d, 0x72, + 0x35, 0x7a, 0x46, 0xa1, 0xd9, 0x05, 0x51, 0x82, 0x6b, 0xa8, 0x64, 0x68, 0xc7, 0x21, 0x09, 0xee, + 0xaa, 0x95, 0x52, 0x55, 0xce, 0xec, 0xc0, 0xa8, 0xc1, 0xec, 0x81, 0xaa, 0x33, 0x3e, 0xcb, 0x8f, + 0x58, 0x15, 0x8a, 0xb4, 0x09, 0x93, 0x9e, 0xf6, 0x9f, 0x1e, 0x28, 0xf2, 0x72, 0xf9, 0x78, 0xb7, + 0x43, 0x94, 0x9d, 0x3e, 0xda, 0x13, 0xd8, 0x04, 0x1b, 0x9c, 0xe6, 0x6c, 0xff, 0xa4, 0x05, 0x0f, + 0xe9, 0x84, 0xda, 0x2b, 0x9b, 0x6e, 0x46, 0x92, 0x45, 0x18, 0xf2, 0x5b, 0x24, 0x70, 0x22, 0x3f, + 0x10, 0xa7, 0xc6, 0x05, 0xd9, 0xe9, 0xd7, 0x05, 0xfc, 0x40, 0xe4, 0x28, 0x90, 0xdc, 0x25, 0x1c, + 0xab, 0x92, 0xf4, 0xf6, 0xc9, 0x3a, 0x23, 0x14, 0xef, 0xa9, 0xd8, 0x1e, 0xc0, 0x2c, 0xe9, 0x21, + 0x16, 0x18, 0xfb, 0x9b, 0x16, 0x9f, 0x58, 0x7a, 0xd3, 0xd1, 0x5b, 0x30, 0xd1, 0x74, 0xa2, 0xda, + 0xf6, 0xd2, 0x9d, 0x56, 0xc0, 0x4d, 0x4e, 0xb2, 0x9f, 0x9e, 0xee, 0xd6, 0x4f, 0xda, 0x47, 0xc6, + 0xae, 0x9c, 0xab, 0x09, 0x66, 0x38, 0xc5, 0x1e, 0x6d, 0xc0, 0x30, 0x83, 0xb1, 0xa7, 0x82, 0x61, + 0x27, 0xd1, 0x20, 0xaf, 0x36, 0xe5, 0x8c, 0xb0, 0x1a, 0xf3, 0xc1, 0x3a, 0x53, 0xfb, 0xcb, 0x45, + 0xbe, 0xda, 0x99, 0x28, 0xff, 0x14, 0x0c, 0xb6, 0xfc, 0xfa, 0xc2, 0xca, 0x22, 0x16, 0xa3, 0xa0, + 0x8e, 0x91, 0x0a, 0x07, 0x63, 0x89, 0x47, 0x17, 0x60, 0x48, 0xfc, 0x94, 0x26, 0x42, 0xb6, 0x37, + 0x0b, 0xba, 0x10, 0x2b, 0x2c, 0x7a, 0x0e, 0xa0, 0x15, 0xf8, 0xbb, 0x6e, 0x9d, 0x85, 0x0e, 0x29, + 0x9a, 0x7e, 0x44, 0x15, 0x85, 0xc1, 0x1a, 0x15, 0x7a, 0x05, 0x46, 0xdb, 0x5e, 0xc8, 0xc5, 0x11, + 0x2d, 0x9a, 0xb2, 0xf2, 0x70, 0xb9, 0xa1, 0x23, 0xb1, 0x49, 0x8b, 0xe6, 0x60, 0x20, 0x72, 0x98, + 0x5f, 0x4c, 0x7f, 0xbe, 0xbb, 0xef, 0x3a, 0xa5, 0xd0, 0x13, 0x08, 0xd1, 0x02, 0x58, 0x14, 0x44, + 0x6f, 0xc8, 0x57, 0xbb, 0x7c, 0x63, 0x17, 0x7e, 0xf6, 0xbd, 0x1d, 0x02, 0xda, 0x9b, 0x5d, 0xe1, + 0xbf, 0x6f, 0xf0, 0x42, 0x2f, 0x03, 0x90, 0x3b, 0x11, 0x09, 0x3c, 0xa7, 0xa1, 0xbc, 0xd9, 0x94, + 0x5c, 0xb0, 0xe8, 0xaf, 0xf9, 0xd1, 0x8d, 0x90, 0x2c, 0x29, 0x0a, 0xac, 0x51, 0xdb, 0xbf, 0x55, + 0x02, 0x88, 0xe5, 0x76, 0x74, 0x37, 0xb5, 0x71, 0x3d, 0xd3, 0x59, 0xd2, 0x3f, 0xba, 0x5d, 0x0b, + 0x7d, 0xbf, 0x05, 0xc3, 0x22, 0x42, 0x0a, 0x1b, 0xa1, 0x42, 0xe7, 0x8d, 0xd3, 0x0c, 0xd4, 0x42, + 0x4b, 0xf0, 0x26, 0x3c, 0x2f, 0x67, 0xa8, 0x86, 0xe9, 0xda, 0x0a, 0xbd, 0x62, 0xf4, 0x3e, 0x79, + 0x55, 0x2c, 0x1a, 0x5d, 0xa9, 0xae, 0x8a, 0x25, 0x76, 0x46, 0xe8, 0xb7, 0xc4, 0x1b, 0xc6, 0x2d, + 0xb1, 0x2f, 0xff, 0x59, 0xa2, 0x21, 0xbe, 0x76, 0xbb, 0x20, 0xa2, 0x8a, 0x1e, 0xa2, 0xa0, 0x3f, + 0xff, 0x79, 0x9e, 0x76, 0x4f, 0xea, 0x12, 0x9e, 0xe0, 0xd3, 0x30, 0x5e, 0x37, 0x85, 0x00, 0x31, + 0x13, 0x9f, 0xcc, 0xe3, 0x9b, 0x90, 0x19, 0xe2, 0x63, 0x3f, 0x81, 0xc0, 0x49, 0xc6, 0xa8, 0xc2, + 0x23, 0x56, 0xac, 0x78, 0x9b, 0xbe, 0x78, 0xeb, 0x61, 0xe7, 0x8e, 0xe5, 0x5e, 0x18, 0x91, 0x26, + 0xa5, 0x8c, 0x4f, 0xf7, 0x35, 0x51, 0x16, 0x2b, 0x2e, 0xe8, 0x35, 0x18, 0x60, 0xef, 0xb3, 0xc2, + 0xe9, 0xa1, 0x7c, 0x8d, 0xb3, 0x19, 0xba, 0x2f, 0x5e, 0x90, 0xec, 0x6f, 0x88, 0x05, 0x07, 0x74, + 0x45, 0xbe, 0x7e, 0x0c, 0x57, 0xbc, 0x1b, 0x21, 0x61, 0xaf, 0x1f, 0x4b, 0xf3, 0x8f, 0xc7, 0x0f, + 0x1b, 0x39, 0x3c, 0x33, 0xcd, 0xa0, 0x51, 0x92, 0x4a, 0x51, 0xe2, 0xbf, 0xcc, 0x5e, 0x28, 0x02, + 0x0d, 0x65, 0x36, 0xcf, 0xcc, 0x70, 0x18, 0x77, 0xe7, 0x4d, 0x93, 0x05, 0x4e, 0xf2, 0xa4, 0x12, + 0x29, 0x5f, 0xf5, 0xe2, 0xb5, 0x48, 0xb7, 0xbd, 0x83, 0x5f, 0xc4, 0xd9, 0x69, 0xc4, 0x21, 0x58, + 0x94, 0x3f, 0x56, 0xf1, 0x60, 0xc6, 0x83, 0x89, 0xe4, 0x12, 0x7d, 0xa0, 0xe2, 0xc8, 0x1f, 0xf6, + 0xc1, 0x98, 0x39, 0xa5, 0xd0, 0x45, 0x28, 0x09, 0x26, 0x2a, 0x03, 0x88, 0x5a, 0x25, 0xab, 0x12, + 0x81, 0x63, 0x1a, 0x96, 0xf8, 0x85, 0x15, 0xd7, 0xdc, 0x83, 0xe3, 0xc4, 0x2f, 0x0a, 0x83, 0x35, + 0x2a, 0x7a, 0xb1, 0xda, 0xf0, 0xfd, 0x48, 0x1d, 0x48, 0x6a, 0xde, 0xcd, 0x33, 0x28, 0x16, 0x58, + 0x7a, 0x10, 0xed, 0x90, 0xc0, 0x23, 0x0d, 0x33, 0xf2, 0xb6, 0x3a, 0x88, 0xae, 0xea, 0x48, 0x6c, + 0xd2, 0xd2, 0xe3, 0xd4, 0x0f, 0xd9, 0x44, 0x16, 0xd7, 0xb7, 0xd8, 0xdd, 0xba, 0xca, 0x5f, 0x79, + 0x4b, 0x3c, 0xfa, 0x18, 0x3c, 0xa4, 0x02, 0x67, 0x61, 0x6e, 0xcd, 0x90, 0x35, 0x0e, 0x18, 0xda, + 0x96, 0x87, 0x16, 0xb2, 0xc9, 0x70, 0x5e, 0x79, 0xf4, 0x2a, 0x8c, 0x09, 0x11, 0x5f, 0x72, 0x1c, + 0x34, 0x3d, 0x8c, 0xae, 0x1a, 0x58, 0x9c, 0xa0, 0x96, 0xb1, 0xc3, 0x99, 0x94, 0x2d, 0x39, 0x0c, + 0xa5, 0x63, 0x87, 0xeb, 0x78, 0x9c, 0x2a, 0x81, 0xe6, 0x60, 0x9c, 0xcb, 0x60, 0xae, 0xb7, 0xc5, + 0xc7, 0x44, 0x3c, 0xe6, 0x52, 0x4b, 0xea, 0xba, 0x89, 0xc6, 0x49, 0x7a, 0xf4, 0x12, 0x8c, 0x38, + 0x41, 0x6d, 0xdb, 0x8d, 0x48, 0x2d, 0x6a, 0x07, 0xfc, 0x95, 0x97, 0xe6, 0xa2, 0x35, 0xa7, 0xe1, + 0xb0, 0x41, 0x69, 0xdf, 0x85, 0xa9, 0x8c, 0xf0, 0x0f, 0x74, 0xe2, 0x38, 0x2d, 0x57, 0x7e, 0x53, + 0xc2, 0xc3, 0x79, 0xae, 0xb2, 0x22, 0xbf, 0x46, 0xa3, 0xa2, 0xb3, 0x93, 0x85, 0x89, 0xd0, 0x92, + 0x95, 0xaa, 0xd9, 0xb9, 0x2c, 0x11, 0x38, 0xa6, 0xb1, 0xff, 0x5b, 0x01, 0xc6, 0x33, 0x6c, 0x2b, + 0x2c, 0x61, 0x66, 0xe2, 0x92, 0x12, 0xe7, 0xc7, 0x34, 0x43, 0xd1, 0x17, 0x0e, 0x11, 0x8a, 0xbe, + 0xd8, 0x2d, 0x14, 0x7d, 0xdf, 0xdb, 0x09, 0x45, 0x6f, 0xf6, 0x58, 0x7f, 0x4f, 0x3d, 0x96, 0x11, + 0xbe, 0x7e, 0xe0, 0x90, 0xe1, 0xeb, 0x8d, 0x4e, 0x1f, 0xec, 0xa1, 0xd3, 0x7f, 0xb4, 0x00, 0x13, + 0x49, 0x57, 0xd2, 0x63, 0xd0, 0xdb, 0xbe, 0x66, 0xe8, 0x6d, 0x2f, 0xf4, 0xf2, 0xf8, 0x36, 0x57, + 0x87, 0x8b, 0x13, 0x3a, 0xdc, 0xf7, 0xf6, 0xc4, 0xad, 0xb3, 0x3e, 0xf7, 0xa7, 0x0a, 0x70, 0x32, + 0xf3, 0xf5, 0xef, 0x31, 0xf4, 0xcd, 0x75, 0xa3, 0x6f, 0x9e, 0xed, 0xf9, 0x61, 0x72, 0x6e, 0x07, + 0xdd, 0x4a, 0x74, 0xd0, 0xc5, 0xde, 0x59, 0x76, 0xee, 0xa5, 0xaf, 0x17, 0xe1, 0x6c, 0x66, 0xb9, + 0x58, 0xed, 0xb9, 0x6c, 0xa8, 0x3d, 0x9f, 0x4b, 0xa8, 0x3d, 0xed, 0xce, 0xa5, 0x8f, 0x46, 0x0f, + 0x2a, 0x1e, 0xe8, 0xb2, 0x30, 0x03, 0xf7, 0xa9, 0x03, 0x35, 0x1e, 0xe8, 0x2a, 0x46, 0xd8, 0xe4, + 0xfb, 0x9d, 0xa4, 0xfb, 0xfc, 0x97, 0x16, 0x9c, 0xce, 0x1c, 0x9b, 0x63, 0xd0, 0x75, 0xad, 0x99, + 0xba, 0xae, 0xa7, 0x7a, 0x9e, 0xad, 0x39, 0xca, 0xaf, 0x9f, 0xe9, 0xcf, 0xf9, 0x16, 0x76, 0x93, + 0xbf, 0x0e, 0xc3, 0x4e, 0xad, 0x46, 0xc2, 0x70, 0xd5, 0xaf, 0xab, 0x40, 0xd8, 0xcf, 0xb2, 0x7b, + 0x56, 0x0c, 0x3e, 0xd8, 0x2f, 0xcf, 0x24, 0x59, 0xc4, 0x68, 0xac, 0x73, 0x40, 0x9f, 0x80, 0xa1, + 0x50, 0x9c, 0x9b, 0x62, 0xec, 0x9f, 0xef, 0xb1, 0x73, 0x9c, 0x0d, 0xd2, 0x30, 0x23, 0x2e, 0x29, + 0x4d, 0x85, 0x62, 0x69, 0x46, 0x67, 0x29, 0x1c, 0x69, 0x74, 0x96, 0xe7, 0x00, 0x76, 0xd5, 0x65, + 0x20, 0xa9, 0x7f, 0xd0, 0xae, 0x09, 0x1a, 0x15, 0xfa, 0x08, 0x4c, 0x84, 0x3c, 0x24, 0xe1, 0x42, + 0xc3, 0x09, 0xd9, 0x3b, 0x1a, 0x31, 0x0b, 0x59, 0x54, 0xa7, 0x6a, 0x02, 0x87, 0x53, 0xd4, 0x68, + 0x59, 0xd6, 0xca, 0xe2, 0x27, 0xf2, 0x89, 0x79, 0x3e, 0xae, 0x51, 0xa4, 0xeb, 0x3e, 0x91, 0xec, + 0x7e, 0xd6, 0xf1, 0x5a, 0x49, 0xf4, 0x09, 0x00, 0x3a, 0x7d, 0x84, 0x1e, 0x62, 0x30, 0x7f, 0xf3, + 0xa4, 0xbb, 0x4a, 0x3d, 0xd3, 0xb9, 0x99, 0xbd, 0xa9, 0x5d, 0x54, 0x4c, 0xb0, 0xc6, 0x10, 0x39, + 0x30, 0x1a, 0xff, 0x8b, 0xb3, 0xd9, 0x5e, 0xc8, 0xad, 0x21, 0xc9, 0x9c, 0xa9, 0xbc, 0x17, 0x75, + 0x16, 0xd8, 0xe4, 0x68, 0xff, 0xf8, 0x20, 0x3c, 0xdc, 0x61, 0x1b, 0x46, 0x73, 0xa6, 0xa9, 0xf7, + 0xe9, 0xe4, 0xfd, 0x7d, 0x26, 0xb3, 0xb0, 0x71, 0xa1, 0x4f, 0xcc, 0xf6, 0xc2, 0xdb, 0x9e, 0xed, + 0x3f, 0x6c, 0x69, 0x9a, 0x15, 0xee, 0x54, 0xfa, 0xe1, 0x43, 0x1e, 0x2f, 0x47, 0xa8, 0x6a, 0xd9, + 0xcc, 0xd0, 0x57, 0x3c, 0xd7, 0x73, 0x73, 0x7a, 0x57, 0x60, 0x7c, 0x35, 0x3b, 0x0e, 0x2f, 0x57, + 0x65, 0x5c, 0x3e, 0xec, 0xf7, 0x1f, 0x57, 0x4c, 0xde, 0x8f, 0xc9, 0xe8, 0x4b, 0xbc, 0x5e, 0xb1, + 0xd6, 0x5e, 0x8c, 0xc3, 0x29, 0xa9, 0xb3, 0xf4, 0xd1, 0xcc, 0xe6, 0xea, 0x44, 0xd8, 0x60, 0x75, + 0xbc, 0x57, 0xef, 0x6f, 0x51, 0x10, 0xe0, 0xdf, 0xb1, 0xe0, 0x4c, 0xc7, 0x88, 0x30, 0xdf, 0x86, + 0xb2, 0xa1, 0xfd, 0x39, 0x0b, 0xb2, 0x07, 0xdb, 0xf0, 0x28, 0xbb, 0x08, 0xa5, 0x5a, 0x22, 0xef, + 0x66, 0x1c, 0x1b, 0x41, 0xe5, 0xdc, 0x8c, 0x69, 0x0c, 0xc7, 0xb1, 0x42, 0x57, 0xc7, 0xb1, 0x5f, + 0xb7, 0x20, 0xb5, 0xbf, 0x1f, 0x83, 0xa0, 0xb1, 0x62, 0x0a, 0x1a, 0x8f, 0xf7, 0xd2, 0x9b, 0x39, + 0x32, 0xc6, 0x9f, 0x8c, 0xc3, 0xa9, 0x9c, 0x17, 0x79, 0xbb, 0x30, 0xb9, 0x55, 0x23, 0xe6, 0xe3, + 0xea, 0x4e, 0x41, 0x87, 0x3a, 0xbe, 0xc4, 0xe6, 0xe9, 0x4e, 0x53, 0x24, 0x38, 0x5d, 0x05, 0xfa, + 0x9c, 0x05, 0x27, 0x9c, 0xdb, 0xe1, 0x12, 0x15, 0x18, 0xdd, 0xda, 0x7c, 0xc3, 0xaf, 0xed, 0xd0, + 0xd3, 0x58, 0x2e, 0x84, 0x17, 0x32, 0x95, 0x78, 0xb7, 0xaa, 0x29, 0x7a, 0xa3, 0x7a, 0x96, 0xdc, + 0x3a, 0x8b, 0x0a, 0x67, 0xd6, 0x85, 0xb0, 0x48, 0xed, 0x41, 0xaf, 0xa3, 0x1d, 0x9e, 0xff, 0x67, + 0x3d, 0x9d, 0xe4, 0x12, 0x90, 0xc4, 0x60, 0xc5, 0x07, 0x7d, 0x0a, 0x4a, 0x5b, 0xf2, 0xa5, 0x6f, + 0x86, 0x84, 0x15, 0x77, 0x64, 0xe7, 0xf7, 0xcf, 0xdc, 0x12, 0xaf, 0x88, 0x70, 0xcc, 0x14, 0xbd, + 0x0a, 0x45, 0x6f, 0x33, 0xec, 0x94, 0x1f, 0x3a, 0xe1, 0x72, 0xc9, 0x83, 0x6c, 0xac, 0x2d, 0x57, + 0x31, 0x2d, 0x88, 0xae, 0x40, 0x31, 0xd8, 0xa8, 0x0b, 0x0d, 0x74, 0xe6, 0x22, 0xc5, 0xf3, 0x8b, + 0x39, 0xad, 0x62, 0x9c, 0xf0, 0xfc, 0x22, 0xa6, 0x2c, 0x50, 0x05, 0xfa, 0xd9, 0x33, 0x36, 0x21, + 0xcf, 0x64, 0xde, 0xdc, 0x3a, 0x3c, 0x07, 0xe5, 0x91, 0x38, 0x18, 0x01, 0xe6, 0x8c, 0xd0, 0x3a, + 0x0c, 0xd4, 0x58, 0x2e, 0x61, 0x21, 0xc0, 0xbc, 0x2f, 0x53, 0xd7, 0xdc, 0x21, 0xc9, 0xb2, 0x50, + 0xbd, 0x32, 0x0a, 0x2c, 0x78, 0x31, 0xae, 0xa4, 0xb5, 0xbd, 0x19, 0x8a, 0x5c, 0xfb, 0xd9, 0x5c, + 0x3b, 0xe4, 0x0e, 0x17, 0x5c, 0x19, 0x05, 0x16, 0xbc, 0xd0, 0xcb, 0x50, 0xd8, 0xac, 0x89, 0x27, + 0x6a, 0x99, 0x4a, 0x67, 0x33, 0x4e, 0xca, 0xfc, 0xc0, 0xbd, 0xfd, 0x72, 0x61, 0x79, 0x01, 0x17, + 0x36, 0x6b, 0x68, 0x0d, 0x06, 0x37, 0x79, 0x64, 0x05, 0xa1, 0x57, 0x7e, 0x32, 0x3b, 0xe8, 0x43, + 0x2a, 0xf8, 0x02, 0x7f, 0xee, 0x24, 0x10, 0x58, 0x32, 0x61, 0x99, 0x26, 0x54, 0x84, 0x08, 0x11, + 0xa0, 0x6e, 0xf6, 0x70, 0x51, 0x3d, 0xb8, 0x7c, 0x19, 0xc7, 0x99, 0xc0, 0x1a, 0x47, 0x3a, 0xab, + 0x9d, 0xbb, 0xed, 0x80, 0x85, 0x1a, 0x17, 0x91, 0x8c, 0x32, 0x67, 0xf5, 0x9c, 0x24, 0xea, 0x34, + 0xab, 0x15, 0x11, 0x8e, 0x99, 0xa2, 0x1d, 0x18, 0xdd, 0x0d, 0x5b, 0xdb, 0x44, 0x2e, 0x69, 0x16, + 0xd8, 0x28, 0x47, 0x3e, 0xba, 0x29, 0x08, 0xdd, 0x20, 0x6a, 0x3b, 0x8d, 0xd4, 0x2e, 0xc4, 0x64, + 0xd9, 0x9b, 0x3a, 0x33, 0x6c, 0xf2, 0xa6, 0xdd, 0xff, 0x56, 0xdb, 0xdf, 0xd8, 0x8b, 0x88, 0x88, + 0x2b, 0x97, 0xd9, 0xfd, 0xaf, 0x73, 0x92, 0x74, 0xf7, 0x0b, 0x04, 0x96, 0x4c, 0xd0, 0x4d, 0xd1, + 0x3d, 0x6c, 0xf7, 0x9c, 0xc8, 0x8f, 0x30, 0x3b, 0x27, 0x89, 0x72, 0x3a, 0x85, 0xed, 0x96, 0x31, + 0x2b, 0xb6, 0x4b, 0xb6, 0xb6, 0xfd, 0xc8, 0xf7, 0x12, 0x3b, 0xf4, 0x64, 0xfe, 0x2e, 0x59, 0xc9, + 0xa0, 0x4f, 0xef, 0x92, 0x59, 0x54, 0x38, 0xb3, 0x2e, 0x54, 0x87, 0xb1, 0x96, 0x1f, 0x44, 0xb7, + 0xfd, 0x40, 0xce, 0x2f, 0xd4, 0x41, 0x2f, 0x66, 0x50, 0x8a, 0x1a, 0x59, 0xc8, 0x46, 0x13, 0x83, + 0x13, 0x3c, 0xd1, 0x47, 0x61, 0x30, 0xac, 0x39, 0x0d, 0xb2, 0x72, 0x7d, 0x7a, 0x2a, 0xff, 0xf8, + 0xa9, 0x72, 0x92, 0x9c, 0xd9, 0xc5, 0x03, 0x63, 0x70, 0x12, 0x2c, 0xd9, 0xa1, 0x65, 0xe8, 0x67, + 0xe9, 0x16, 0x59, 0x10, 0xc4, 0x9c, 0x40, 0xb9, 0x29, 0x07, 0x78, 0xbe, 0x37, 0x31, 0x30, 0xe6, + 0xc5, 0xe9, 0x1a, 0x10, 0xd7, 0x43, 0x3f, 0x9c, 0x3e, 0x99, 0xbf, 0x06, 0xc4, 0xad, 0xf2, 0x7a, + 0xb5, 0xd3, 0x1a, 0x50, 0x44, 0x38, 0x66, 0x4a, 0x77, 0x66, 0xba, 0x9b, 0x9e, 0xea, 0xe0, 0xb9, + 0x95, 0xbb, 0x97, 0xb2, 0x9d, 0x99, 0xee, 0xa4, 0x94, 0x85, 0xfd, 0x07, 0x83, 0x69, 0x99, 0x85, + 0x29, 0x14, 0xfe, 0x82, 0x95, 0xb2, 0x35, 0xbf, 0xbf, 0x57, 0xfd, 0xe6, 0x11, 0x5e, 0x85, 0x3e, + 0x67, 0xc1, 0xa9, 0x56, 0xe6, 0x87, 0x08, 0x01, 0xa0, 0x37, 0x35, 0x29, 0xff, 0x74, 0x15, 0x30, + 0x33, 0x1b, 0x8f, 0x73, 0x6a, 0x4a, 0x5e, 0x37, 0x8b, 0x6f, 0xfb, 0xba, 0xb9, 0x0a, 0x43, 0x35, + 0x7e, 0x15, 0xe9, 0x98, 0x5b, 0x3f, 0x79, 0xf7, 0x66, 0xa2, 0x84, 0xb8, 0xc3, 0x6c, 0x62, 0xc5, + 0x02, 0xfd, 0x88, 0x05, 0x67, 0x92, 0x4d, 0xc7, 0x84, 0xa1, 0x45, 0x94, 0x4d, 0xae, 0xcb, 0x58, + 0x16, 0xdf, 0x9f, 0x92, 0xff, 0x0d, 0xe2, 0x83, 0x6e, 0x04, 0xb8, 0x73, 0x65, 0x68, 0x31, 0x43, + 0x99, 0x32, 0x60, 0x1a, 0x90, 0x7a, 0x50, 0xa8, 0xbc, 0x00, 0x23, 0x4d, 0xbf, 0xed, 0x45, 0xc2, + 0xd1, 0x4b, 0x38, 0x9d, 0x30, 0x67, 0x8b, 0x55, 0x0d, 0x8e, 0x0d, 0xaa, 0x84, 0x1a, 0x66, 0xe8, + 0xbe, 0xd5, 0x30, 0x6f, 0xc2, 0x88, 0xa7, 0x79, 0x26, 0x0b, 0x79, 0xe0, 0x7c, 0x7e, 0x84, 0x5c, + 0xdd, 0x8f, 0x99, 0xb7, 0x52, 0x87, 0x60, 0x83, 0xdb, 0xf1, 0x7a, 0x80, 0x7d, 0xc9, 0xca, 0x10, + 0xea, 0xb9, 0x2a, 0xe6, 0x43, 0xa6, 0x2a, 0xe6, 0x7c, 0x52, 0x15, 0x93, 0x32, 0x1e, 0x18, 0x5a, + 0x98, 0xde, 0xb3, 0x3b, 0xf5, 0x1a, 0x65, 0xd3, 0x6e, 0xc0, 0xb9, 0x6e, 0xc7, 0x12, 0xf3, 0xf8, + 0xab, 0x2b, 0x53, 0x71, 0xec, 0xf1, 0x57, 0x5f, 0x59, 0xc4, 0x0c, 0xd3, 0x6b, 0xfc, 0x26, 0xfb, + 0xbf, 0x58, 0x50, 0xac, 0xf8, 0xf5, 0x63, 0xb8, 0xf0, 0x7e, 0xd8, 0xb8, 0xf0, 0x3e, 0x9c, 0x7d, + 0x20, 0xd6, 0x73, 0x4d, 0x1f, 0x4b, 0x09, 0xd3, 0xc7, 0x99, 0x3c, 0x06, 0x9d, 0x0d, 0x1d, 0x3f, + 0x5d, 0x84, 0xe1, 0x8a, 0x5f, 0x57, 0xee, 0xf6, 0xff, 0xf4, 0x7e, 0xdc, 0xed, 0x73, 0x73, 0x65, + 0x68, 0x9c, 0x99, 0xa3, 0xa0, 0x7c, 0x69, 0xfc, 0x6d, 0xe6, 0x75, 0x7f, 0x8b, 0xb8, 0x5b, 0xdb, + 0x11, 0xa9, 0x27, 0x3f, 0xe7, 0xf8, 0xbc, 0xee, 0xff, 0xa0, 0x00, 0xe3, 0x89, 0xda, 0x51, 0x03, + 0x46, 0x1b, 0xba, 0x62, 0x5d, 0xcc, 0xd3, 0xfb, 0xd2, 0xc9, 0x0b, 0xaf, 0x65, 0x0d, 0x84, 0x4d, + 0xe6, 0x68, 0x16, 0x40, 0x59, 0x9a, 0xa5, 0x7a, 0x95, 0x49, 0xfd, 0xca, 0x14, 0x1d, 0x62, 0x8d, + 0x02, 0xbd, 0x08, 0xc3, 0x91, 0xdf, 0xf2, 0x1b, 0xfe, 0xd6, 0xde, 0x55, 0x22, 0x43, 0x7b, 0x29, + 0x5f, 0xc4, 0xf5, 0x18, 0x85, 0x75, 0x3a, 0x74, 0x07, 0x26, 0x15, 0x93, 0xea, 0x11, 0x18, 0x1b, + 0x98, 0x56, 0x61, 0x2d, 0xc9, 0x11, 0xa7, 0x2b, 0xb1, 0x7f, 0xae, 0xc8, 0xbb, 0xd8, 0x8b, 0xdc, + 0x77, 0x57, 0xc3, 0x3b, 0x7b, 0x35, 0x7c, 0xdd, 0x82, 0x09, 0x5a, 0x3b, 0x73, 0xb4, 0x92, 0xc7, + 0xbc, 0x8a, 0xc9, 0x6d, 0x75, 0x88, 0xc9, 0x7d, 0x9e, 0xee, 0x9a, 0x75, 0xbf, 0x1d, 0x09, 0xdd, + 0x9d, 0xb6, 0x2d, 0x52, 0x28, 0x16, 0x58, 0x41, 0x47, 0x82, 0x40, 0x3c, 0x0e, 0xd5, 0xe9, 0x48, + 0x10, 0x60, 0x81, 0x95, 0x21, 0xbb, 0xfb, 0xb2, 0x43, 0x76, 0xf3, 0xc8, 0xab, 0xc2, 0x25, 0x47, + 0x08, 0x5c, 0x5a, 0xe4, 0x55, 0xe9, 0xab, 0x13, 0xd3, 0xd8, 0x5f, 0x2d, 0xc2, 0x48, 0xc5, 0xaf, + 0xc7, 0x56, 0xe6, 0x17, 0x0c, 0x2b, 0xf3, 0xb9, 0x84, 0x95, 0x79, 0x42, 0xa7, 0x7d, 0xd7, 0xa6, + 0xfc, 0xad, 0xb2, 0x29, 0xff, 0x9a, 0xc5, 0x46, 0x6d, 0x71, 0xad, 0xca, 0xfd, 0xf6, 0xd0, 0x25, + 0x18, 0x66, 0x1b, 0x0c, 0x7b, 0x8d, 0x2c, 0x4d, 0xaf, 0x2c, 0xdf, 0xd5, 0x5a, 0x0c, 0xc6, 0x3a, + 0x0d, 0xba, 0x00, 0x43, 0x21, 0x71, 0x82, 0xda, 0xb6, 0xda, 0x5d, 0x85, 0x9d, 0x94, 0xc3, 0xb0, + 0xc2, 0xa2, 0xd7, 0xe3, 0xa0, 0x9f, 0xc5, 0xfc, 0xd7, 0x8d, 0x7a, 0x7b, 0xf8, 0x12, 0xc9, 0x8f, + 0xf4, 0x69, 0xdf, 0x02, 0x94, 0xa6, 0xef, 0x21, 0x2c, 0x5d, 0xd9, 0x0c, 0x4b, 0x57, 0x4a, 0x85, + 0xa4, 0xfb, 0x33, 0x0b, 0xc6, 0x2a, 0x7e, 0x9d, 0x2e, 0xdd, 0xef, 0xa4, 0x75, 0xaa, 0x47, 0x3c, + 0x1e, 0xe8, 0x10, 0xf1, 0xf8, 0x31, 0xe8, 0xaf, 0xf8, 0xf5, 0x95, 0x4a, 0xa7, 0xd0, 0x02, 0xf6, + 0xdf, 0xb4, 0x60, 0xb0, 0xe2, 0xd7, 0x8f, 0xc1, 0x2c, 0xf0, 0x21, 0xd3, 0x2c, 0xf0, 0x50, 0xce, + 0xbc, 0xc9, 0xb1, 0x04, 0xfc, 0x8d, 0x3e, 0x18, 0xa5, 0xed, 0xf4, 0xb7, 0xe4, 0x50, 0x1a, 0xdd, + 0x66, 0xf5, 0xd0, 0x6d, 0x54, 0x0a, 0xf7, 0x1b, 0x0d, 0xff, 0x76, 0x72, 0x58, 0x97, 0x19, 0x14, + 0x0b, 0x2c, 0x7a, 0x06, 0x86, 0x5a, 0x01, 0xd9, 0x75, 0x7d, 0x21, 0xde, 0x6a, 0x46, 0x96, 0x8a, + 0x80, 0x63, 0x45, 0x41, 0xaf, 0x85, 0xa1, 0xeb, 0xd1, 0xa3, 0xbc, 0xe6, 0x7b, 0x75, 0xae, 0x39, + 0x2f, 0x8a, 0xb4, 0x1c, 0x1a, 0x1c, 0x1b, 0x54, 0xe8, 0x16, 0x94, 0xd8, 0x7f, 0xb6, 0xed, 0x1c, + 0x3e, 0x7b, 0xaf, 0xc8, 0x2a, 0x28, 0x18, 0xe0, 0x98, 0x17, 0x7a, 0x0e, 0x20, 0x92, 0xa1, 0xed, + 0x43, 0x11, 0x68, 0x4d, 0x5d, 0x05, 0x54, 0xd0, 0xfb, 0x10, 0x6b, 0x54, 0xe8, 0x69, 0x28, 0x45, + 0x8e, 0xdb, 0xb8, 0xe6, 0x7a, 0x24, 0x64, 0x1a, 0xf1, 0xa2, 0x4c, 0xee, 0x27, 0x80, 0x38, 0xc6, + 0x53, 0x51, 0x8c, 0x05, 0xe1, 0xe0, 0xb9, 0xcb, 0x87, 0x18, 0x35, 0x13, 0xc5, 0xae, 0x29, 0x28, + 0xd6, 0x28, 0xd0, 0x36, 0x3c, 0xe2, 0x7a, 0x2c, 0x85, 0x05, 0xa9, 0xee, 0xb8, 0xad, 0xf5, 0x6b, + 0xd5, 0x9b, 0x24, 0x70, 0x37, 0xf7, 0xe6, 0x9d, 0xda, 0x0e, 0xf1, 0x64, 0x5e, 0x56, 0x99, 0xae, + 0xfb, 0x91, 0x95, 0x0e, 0xb4, 0xb8, 0x23, 0x27, 0xfb, 0x79, 0x36, 0xdf, 0xaf, 0x57, 0xd1, 0x7b, + 0x8d, 0xad, 0xe3, 0x94, 0xbe, 0x75, 0x1c, 0xec, 0x97, 0x07, 0xae, 0x57, 0xb5, 0x18, 0x12, 0x2f, + 0xc1, 0xc9, 0x8a, 0x5f, 0xaf, 0xf8, 0x41, 0xb4, 0xec, 0x07, 0xb7, 0x9d, 0xa0, 0x2e, 0xa7, 0x57, + 0x59, 0x46, 0xd1, 0xa0, 0xfb, 0x67, 0x3f, 0xdf, 0x5d, 0x8c, 0x08, 0x19, 0xcf, 0x33, 0x89, 0xed, + 0x90, 0x6f, 0xbf, 0x6a, 0x4c, 0x76, 0x50, 0x49, 0x60, 0x2e, 0x3b, 0x11, 0x41, 0xd7, 0x59, 0xe6, + 0xf5, 0xf8, 0x18, 0x15, 0xc5, 0x9f, 0xd2, 0x32, 0xaf, 0xc7, 0xc8, 0xcc, 0x73, 0xd7, 0x2c, 0x6f, + 0x7f, 0x56, 0x54, 0xc2, 0xef, 0xe0, 0xdc, 0xbf, 0xae, 0x97, 0xd4, 0xc5, 0x32, 0x4b, 0x44, 0x21, + 0x3f, 0xbd, 0x00, 0xb7, 0x7a, 0x76, 0xcc, 0x12, 0x61, 0xbf, 0x08, 0x93, 0xf4, 0xea, 0xa7, 0xe4, + 0x28, 0xf6, 0x91, 0xdd, 0xa3, 0x79, 0xfc, 0xd7, 0x7e, 0x76, 0x0e, 0x24, 0xd2, 0x9f, 0xa0, 0x4f, + 0xc2, 0x58, 0x48, 0xae, 0xb9, 0x5e, 0xfb, 0x8e, 0x54, 0xbc, 0x74, 0x78, 0x73, 0x58, 0x5d, 0xd2, + 0x29, 0xb9, 0xfa, 0xd6, 0x84, 0xe1, 0x04, 0x37, 0xd4, 0x84, 0xb1, 0xdb, 0xae, 0x57, 0xf7, 0x6f, + 0x87, 0x92, 0xff, 0x50, 0xbe, 0x16, 0xf7, 0x16, 0xa7, 0x4c, 0xb4, 0xd1, 0xa8, 0xee, 0x96, 0xc1, + 0x0c, 0x27, 0x98, 0xd3, 0xb5, 0x16, 0xb4, 0xbd, 0xb9, 0xf0, 0x46, 0x48, 0x02, 0x91, 0xf9, 0x9f, + 0xa7, 0xe5, 0x95, 0x40, 0x1c, 0xe3, 0xe9, 0x5a, 0x63, 0x7f, 0x2e, 0x07, 0x7e, 0x9b, 0xe7, 0xda, + 0x10, 0x6b, 0x0d, 0x2b, 0x28, 0xd6, 0x28, 0xe8, 0x5e, 0xc4, 0xfe, 0xad, 0xf9, 0x1e, 0xf6, 0xfd, + 0x48, 0xee, 0x5e, 0xcc, 0x13, 0x41, 0x83, 0x63, 0x83, 0x0a, 0x2d, 0x03, 0x0a, 0xdb, 0xad, 0x56, + 0x83, 0x39, 0x33, 0x39, 0x0d, 0xc6, 0x8a, 0x7b, 0x79, 0x14, 0x79, 0xac, 0xe0, 0x6a, 0x0a, 0x8b, + 0x33, 0x4a, 0xd0, 0x63, 0x69, 0x53, 0x34, 0xb5, 0x9f, 0x35, 0x95, 0x5b, 0x7c, 0xaa, 0xbc, 0x9d, + 0x12, 0x87, 0x96, 0x60, 0x30, 0xdc, 0x0b, 0x6b, 0x91, 0x08, 0xed, 0x98, 0x93, 0x46, 0xab, 0xca, + 0x48, 0xb4, 0x2c, 0x8e, 0xbc, 0x08, 0x96, 0x65, 0x51, 0x0d, 0xa6, 0x04, 0xc7, 0x85, 0x6d, 0xc7, + 0x53, 0xf9, 0x82, 0xb8, 0x4f, 0xf7, 0xa5, 0x7b, 0xfb, 0xe5, 0x29, 0x51, 0xb3, 0x8e, 0x3e, 0xd8, + 0x2f, 0x9f, 0xaa, 0xf8, 0xf5, 0x0c, 0x0c, 0xce, 0xe2, 0xc6, 0x27, 0x5f, 0xad, 0xe6, 0x37, 0x5b, + 0x95, 0xc0, 0xdf, 0x74, 0x1b, 0xa4, 0x93, 0xd5, 0xac, 0x6a, 0x50, 0x8a, 0xc9, 0x67, 0xc0, 0x70, + 0x82, 0x9b, 0xfd, 0x59, 0x26, 0xba, 0xb1, 0x64, 0xf1, 0x51, 0x3b, 0x20, 0xa8, 0x09, 0xa3, 0x2d, + 0xb6, 0xb8, 0x45, 0x06, 0x0c, 0x31, 0xd7, 0x5f, 0xe8, 0x51, 0xfb, 0x73, 0x9b, 0xe5, 0xf5, 0x32, + 0x3c, 0xa3, 0x2a, 0x3a, 0x3b, 0x6c, 0x72, 0xb7, 0xff, 0xf5, 0x69, 0x76, 0xf8, 0x57, 0xb9, 0x4a, + 0x67, 0x50, 0x3c, 0x21, 0x11, 0xb7, 0xc8, 0x99, 0x7c, 0xdd, 0x62, 0x3c, 0x2c, 0xe2, 0x19, 0x0a, + 0x96, 0x65, 0xd1, 0x27, 0x60, 0x8c, 0x5e, 0xca, 0xd4, 0x01, 0x1c, 0x4e, 0x9f, 0xc8, 0x0f, 0xf5, + 0xa1, 0xa8, 0xf4, 0xec, 0x38, 0x7a, 0x61, 0x9c, 0x60, 0x86, 0x5e, 0x67, 0x9e, 0x48, 0x92, 0x75, + 0xa1, 0x17, 0xd6, 0xba, 0xd3, 0x91, 0x64, 0xab, 0x31, 0x41, 0x6d, 0x98, 0x4a, 0x27, 0xec, 0x0b, + 0xa7, 0xed, 0x7c, 0xe9, 0x36, 0x9d, 0x73, 0x2f, 0x4e, 0x63, 0x92, 0xc6, 0x85, 0x38, 0x8b, 0x3f, + 0xba, 0x06, 0xa3, 0x22, 0x63, 0xba, 0x98, 0xb9, 0x45, 0x43, 0xe5, 0x39, 0x8a, 0x75, 0xe4, 0x41, + 0x12, 0x80, 0xcd, 0xc2, 0x68, 0x0b, 0xce, 0x68, 0x49, 0xae, 0x2e, 0x07, 0x0e, 0xf3, 0x5b, 0x70, + 0xd9, 0x76, 0xaa, 0x89, 0x25, 0x8f, 0xde, 0xdb, 0x2f, 0x9f, 0x59, 0xef, 0x44, 0x88, 0x3b, 0xf3, + 0x41, 0xd7, 0xe1, 0x24, 0x7f, 0xa8, 0xbe, 0x48, 0x9c, 0x7a, 0xc3, 0xf5, 0x94, 0xdc, 0xc3, 0x97, + 0xfc, 0xe9, 0x7b, 0xfb, 0xe5, 0x93, 0x73, 0x59, 0x04, 0x38, 0xbb, 0x1c, 0xfa, 0x10, 0x94, 0xea, + 0x5e, 0x28, 0xfa, 0x60, 0xc0, 0xc8, 0x23, 0x56, 0x5a, 0x5c, 0xab, 0xaa, 0xef, 0x8f, 0xff, 0xe0, + 0xb8, 0x00, 0xda, 0xe2, 0x6a, 0x71, 0xa5, 0xac, 0x19, 0x4c, 0x05, 0xea, 0x4a, 0xea, 0x33, 0x8d, + 0xa7, 0xaa, 0xdc, 0x1e, 0xa4, 0x5e, 0x70, 0x18, 0xaf, 0x58, 0x0d, 0xc6, 0xe8, 0x35, 0x40, 0x22, + 0x5e, 0xfd, 0x5c, 0x8d, 0xa5, 0x57, 0x61, 0x56, 0x84, 0x21, 0xf3, 0xf1, 0x64, 0x35, 0x45, 0x81, + 0x33, 0x4a, 0xa1, 0x2b, 0x74, 0x57, 0xd1, 0xa1, 0x62, 0xd7, 0x52, 0xa9, 0x25, 0x17, 0x49, 0x2b, + 0x20, 0xcc, 0x0f, 0xcb, 0xe4, 0x88, 0x13, 0xe5, 0x50, 0x1d, 0x1e, 0x71, 0xda, 0x91, 0xcf, 0x2c, + 0x0e, 0x26, 0xe9, 0xba, 0xbf, 0x43, 0x3c, 0x66, 0xec, 0x1b, 0x9a, 0x3f, 0x47, 0x05, 0xab, 0xb9, + 0x0e, 0x74, 0xb8, 0x23, 0x17, 0x2a, 0x10, 0xab, 0x5c, 0xd2, 0x60, 0x86, 0x1f, 0xcb, 0xc8, 0x27, + 0xfd, 0x22, 0x0c, 0x6f, 0xfb, 0x61, 0xb4, 0x46, 0xa2, 0xdb, 0x7e, 0xb0, 0x23, 0xc2, 0xe8, 0xc6, + 0x41, 0xc9, 0x63, 0x14, 0xd6, 0xe9, 0xe8, 0x8d, 0x97, 0xb9, 0xa2, 0xac, 0x2c, 0x32, 0x2f, 0x80, + 0xa1, 0x78, 0x8f, 0xb9, 0xc2, 0xc1, 0x58, 0xe2, 0x25, 0xe9, 0x4a, 0x65, 0x81, 0x59, 0xf4, 0x13, + 0xa4, 0x2b, 0x95, 0x05, 0x2c, 0xf1, 0x74, 0xba, 0x86, 0xdb, 0x4e, 0x40, 0x2a, 0x81, 0x5f, 0x23, + 0xa1, 0x16, 0x0a, 0xff, 0x61, 0x1e, 0x24, 0x98, 0x4e, 0xd7, 0x6a, 0x16, 0x01, 0xce, 0x2e, 0x87, + 0x48, 0x3a, 0xc1, 0xdb, 0x58, 0xbe, 0x29, 0x26, 0x2d, 0xcf, 0xf4, 0x98, 0xe3, 0xcd, 0x83, 0x09, + 0x95, 0x5a, 0x8e, 0x87, 0x05, 0x0e, 0xa7, 0xc7, 0xd9, 0xdc, 0xee, 0x3d, 0xa6, 0xb0, 0x32, 0x6e, + 0xad, 0x24, 0x38, 0xe1, 0x14, 0x6f, 0x23, 0xc2, 0xdc, 0x44, 0xd7, 0x08, 0x73, 0x17, 0xa1, 0x14, + 0xb6, 0x37, 0xea, 0x7e, 0xd3, 0x71, 0x3d, 0x66, 0xd1, 0xd7, 0xae, 0x5e, 0x55, 0x89, 0xc0, 0x31, + 0x0d, 0x5a, 0x86, 0x21, 0x47, 0x5a, 0xae, 0x50, 0x7e, 0x4c, 0x21, 0x65, 0xaf, 0xe2, 0x61, 0x36, + 0xa4, 0xad, 0x4a, 0x95, 0x45, 0xaf, 0xc0, 0xa8, 0x78, 0x68, 0x2d, 0x52, 0xa7, 0x4e, 0x99, 0xaf, + 0xe1, 0xaa, 0x3a, 0x12, 0x9b, 0xb4, 0xe8, 0x06, 0x0c, 0x47, 0x7e, 0x83, 0x3d, 0xe9, 0xa2, 0x62, + 0xde, 0xa9, 0xfc, 0xe8, 0x78, 0xeb, 0x8a, 0x4c, 0x57, 0x1a, 0xab, 0xa2, 0x58, 0xe7, 0x83, 0xd6, + 0xf9, 0x7c, 0x67, 0x81, 0xef, 0x49, 0x28, 0x72, 0x6f, 0x9e, 0xc9, 0x73, 0xc7, 0x62, 0x64, 0xe6, + 0x72, 0x10, 0x25, 0xb1, 0xce, 0x06, 0x5d, 0x86, 0xc9, 0x56, 0xe0, 0xfa, 0x6c, 0x4e, 0x28, 0xa3, + 0xe5, 0xb4, 0x99, 0xe6, 0xaa, 0x92, 0x24, 0xc0, 0xe9, 0x32, 0xec, 0x9d, 0xbc, 0x00, 0x4e, 0x9f, + 0xe6, 0xa9, 0x3a, 0xf8, 0x4d, 0x96, 0xc3, 0xb0, 0xc2, 0xa2, 0x55, 0xb6, 0x13, 0x73, 0x25, 0xcc, + 0xf4, 0x4c, 0x7e, 0x18, 0x23, 0x5d, 0x59, 0xc3, 0x85, 0x57, 0xf5, 0x17, 0xc7, 0x1c, 0x50, 0x5d, + 0xcb, 0x90, 0x49, 0xaf, 0x00, 0xe1, 0xf4, 0x23, 0x1d, 0xfc, 0x01, 0x13, 0x97, 0xa2, 0x58, 0x20, + 0x30, 0xc0, 0x21, 0x4e, 0xf0, 0x44, 0x1f, 0x81, 0x09, 0x11, 0x7c, 0x31, 0xee, 0xa6, 0x33, 0xb1, + 0xa3, 0x3c, 0x4e, 0xe0, 0x70, 0x8a, 0x9a, 0xa7, 0xca, 0x70, 0x36, 0x1a, 0x44, 0x6c, 0x7d, 0xd7, + 0x5c, 0x6f, 0x27, 0x9c, 0x3e, 0xcb, 0xf6, 0x07, 0x91, 0x2a, 0x23, 0x89, 0xc5, 0x19, 0x25, 0xd0, + 0x3a, 0x4c, 0xb4, 0x02, 0x42, 0x9a, 0x4c, 0xd0, 0x17, 0xe7, 0x59, 0x99, 0x87, 0x89, 0xa0, 0x2d, + 0xa9, 0x24, 0x70, 0x07, 0x19, 0x30, 0x9c, 0xe2, 0x80, 0x6e, 0xc3, 0x90, 0xbf, 0x4b, 0x82, 0x6d, + 0xe2, 0xd4, 0xa7, 0xcf, 0x75, 0x78, 0xb8, 0x21, 0x0e, 0xb7, 0xeb, 0x82, 0x36, 0xe1, 0xe8, 0x20, + 0xc1, 0xdd, 0x1d, 0x1d, 0x64, 0x65, 0xe8, 0x2f, 0x5a, 0x70, 0x5a, 0xda, 0x46, 0xaa, 0x2d, 0xda, + 0xeb, 0x0b, 0xbe, 0x17, 0x46, 0x01, 0x0f, 0x6c, 0xf0, 0x68, 0xfe, 0x63, 0xff, 0xf5, 0x9c, 0x42, + 0x4a, 0x0f, 0x7c, 0x3a, 0x8f, 0x22, 0xc4, 0xf9, 0x35, 0xa2, 0x05, 0x98, 0x0c, 0x49, 0x24, 0x37, + 0xa3, 0xb9, 0x70, 0xf9, 0xf5, 0xc5, 0xb5, 0xe9, 0xc7, 0x78, 0x54, 0x06, 0xba, 0x18, 0xaa, 0x49, + 0x24, 0x4e, 0xd3, 0xa3, 0x4b, 0x50, 0xf0, 0xc3, 0xe9, 0xc7, 0x3b, 0x24, 0x55, 0xf5, 0xeb, 0xd7, + 0xab, 0xdc, 0xe1, 0xed, 0x7a, 0x15, 0x17, 0xfc, 0x50, 0xa6, 0xab, 0xa0, 0xf7, 0xb1, 0x70, 0xfa, + 0x09, 0xae, 0x35, 0x94, 0xe9, 0x2a, 0x18, 0x10, 0xc7, 0x78, 0xb4, 0x0d, 0xe3, 0xa1, 0x71, 0xef, + 0x0d, 0xa7, 0xcf, 0xb3, 0x9e, 0x7a, 0x22, 0x6f, 0xd0, 0x0c, 0x6a, 0x2d, 0xda, 0xbc, 0xc9, 0x05, + 0x27, 0xd9, 0xf2, 0xd5, 0xa5, 0x5d, 0xf0, 0xc3, 0xe9, 0x27, 0xbb, 0xac, 0x2e, 0x8d, 0x58, 0x5f, + 0x5d, 0x3a, 0x0f, 0x9c, 0xe0, 0x39, 0xf3, 0x5d, 0x30, 0x99, 0x12, 0x97, 0x0e, 0x93, 0x89, 0x69, + 0x66, 0x07, 0x46, 0x8d, 0x29, 0xf9, 0x40, 0x1d, 0x0b, 0xbe, 0x67, 0x08, 0x4a, 0xca, 0xe8, 0x8c, + 0x2e, 0x9a, 0xbe, 0x04, 0xa7, 0x93, 0xbe, 0x04, 0x43, 0x15, 0xbf, 0x6e, 0xb8, 0x0f, 0xac, 0x67, + 0xc4, 0xee, 0xcb, 0xdb, 0x00, 0x7b, 0x7f, 0xd3, 0xa0, 0x69, 0xf2, 0x8b, 0x3d, 0x3b, 0x25, 0xf4, + 0x75, 0x34, 0x0e, 0x5c, 0x86, 0x49, 0xcf, 0x67, 0x32, 0x3a, 0xa9, 0x4b, 0x01, 0x8c, 0xc9, 0x59, + 0x25, 0x3d, 0x18, 0x4e, 0x82, 0x00, 0xa7, 0xcb, 0xd0, 0x0a, 0xb9, 0xa0, 0x94, 0xb4, 0x46, 0x70, + 0x39, 0x0a, 0x0b, 0x2c, 0x7a, 0x0c, 0xfa, 0x5b, 0x7e, 0x7d, 0xa5, 0x22, 0xe4, 0x73, 0x2d, 0x62, + 0x6c, 0x7d, 0xa5, 0x82, 0x39, 0x0e, 0xcd, 0xc1, 0x00, 0xfb, 0x11, 0x4e, 0x8f, 0xe4, 0x47, 0x3d, + 0x61, 0x25, 0xb4, 0x3c, 0x57, 0xac, 0x00, 0x16, 0x05, 0x99, 0x56, 0x94, 0x5e, 0x6a, 0x98, 0x56, + 0x74, 0xf0, 0x3e, 0xb5, 0xa2, 0x92, 0x01, 0x8e, 0x79, 0xa1, 0x3b, 0x70, 0xd2, 0xb8, 0x48, 0xf2, + 0x29, 0x42, 0x42, 0x11, 0x79, 0xe1, 0xb1, 0x8e, 0x37, 0x48, 0xe1, 0xc4, 0x70, 0x46, 0x34, 0xfa, + 0xe4, 0x4a, 0x16, 0x27, 0x9c, 0x5d, 0x01, 0x6a, 0xc0, 0x64, 0x2d, 0x55, 0xeb, 0x50, 0xef, 0xb5, + 0xaa, 0x01, 0x4d, 0xd7, 0x98, 0x66, 0x8c, 0x5e, 0x81, 0xa1, 0xb7, 0xfc, 0x90, 0x9d, 0x6d, 0xe2, + 0x4e, 0x21, 0x9f, 0xed, 0x0f, 0xbd, 0x7e, 0xbd, 0xca, 0xe0, 0x07, 0xfb, 0xe5, 0xe1, 0x8a, 0x5f, + 0x97, 0x7f, 0xb1, 0x2a, 0x80, 0x7e, 0xc0, 0x82, 0x99, 0xf4, 0x4d, 0x55, 0x35, 0x7a, 0xb4, 0xf7, + 0x46, 0xdb, 0xa2, 0xd2, 0x99, 0xa5, 0x5c, 0x76, 0xb8, 0x43, 0x55, 0xe8, 0x83, 0x74, 0x21, 0x84, + 0xee, 0x5d, 0x22, 0x92, 0x84, 0x3e, 0x1a, 0x2f, 0x04, 0x0a, 0x3d, 0xd8, 0x2f, 0x8f, 0xf3, 0x2d, + 0x2d, 0x7e, 0x37, 0x23, 0x0a, 0xd8, 0xbf, 0x6c, 0x31, 0xb5, 0xac, 0x80, 0x92, 0xb0, 0xdd, 0x38, + 0x8e, 0xcc, 0xc0, 0x4b, 0x86, 0xc9, 0xf3, 0xbe, 0xfd, 0x61, 0xfe, 0x89, 0xc5, 0xfc, 0x61, 0x8e, + 0xf1, 0xe1, 0xcb, 0xeb, 0x30, 0x14, 0xc9, 0x8c, 0xcd, 0x1d, 0x92, 0x19, 0x6b, 0x8d, 0x62, 0x3e, + 0x41, 0xea, 0x72, 0xa0, 0x92, 0x33, 0x2b, 0x36, 0xf6, 0x3f, 0xe4, 0x23, 0x20, 0x31, 0xc7, 0x60, + 0x59, 0x5a, 0x34, 0x2d, 0x4b, 0xe5, 0x2e, 0x5f, 0x90, 0x63, 0x61, 0xfa, 0x07, 0x66, 0xbb, 0x99, + 0x52, 0xec, 0x9d, 0xee, 0x88, 0x65, 0x7f, 0xde, 0x02, 0x88, 0x63, 0x79, 0xf7, 0x90, 0x93, 0xef, + 0x25, 0x7a, 0x1d, 0xf0, 0x23, 0xbf, 0xe6, 0x37, 0x84, 0xdd, 0xf4, 0x91, 0xd8, 0xb8, 0xc5, 0xe1, + 0x07, 0xda, 0x6f, 0xac, 0xa8, 0x51, 0x59, 0x46, 0x0e, 0x2c, 0xc6, 0xe6, 0x56, 0x23, 0x6a, 0xe0, + 0x17, 0x2d, 0x38, 0x91, 0xe5, 0x45, 0x4d, 0x2f, 0x97, 0x5c, 0x3d, 0xa8, 0x9c, 0xe4, 0xd4, 0x68, + 0xde, 0x14, 0x70, 0xac, 0x28, 0x7a, 0x4e, 0x76, 0x78, 0xb8, 0x20, 0xda, 0xd7, 0x61, 0xb4, 0x12, + 0x10, 0xed, 0x5c, 0x7e, 0x95, 0x47, 0xa3, 0xe0, 0xed, 0x79, 0xe6, 0xd0, 0x91, 0x28, 0xec, 0x2f, + 0x17, 0xe0, 0x04, 0xf7, 0x35, 0x99, 0xdb, 0xf5, 0xdd, 0x7a, 0xc5, 0xaf, 0x8b, 0xb7, 0x72, 0x6f, + 0xc0, 0x48, 0x4b, 0xd3, 0xe9, 0x76, 0x0a, 0x08, 0xab, 0xeb, 0x7e, 0x63, 0x2d, 0x94, 0x0e, 0xc5, + 0x06, 0x2f, 0x54, 0x87, 0x11, 0xb2, 0xeb, 0xd6, 0x94, 0xc3, 0x42, 0xe1, 0xd0, 0x67, 0xa4, 0xaa, + 0x65, 0x49, 0xe3, 0x83, 0x0d, 0xae, 0x0f, 0x20, 0x05, 0xb9, 0xfd, 0x63, 0x16, 0x3c, 0x94, 0x13, + 0x3e, 0x96, 0x56, 0x77, 0x9b, 0x79, 0xf5, 0x88, 0x69, 0xab, 0xaa, 0xe3, 0xbe, 0x3e, 0x58, 0x60, + 0xd1, 0x47, 0x01, 0xb8, 0xaf, 0x0e, 0xf1, 0x6a, 0x5d, 0xe3, 0x6c, 0x1a, 0x21, 0x02, 0xb5, 0x68, + 0x6f, 0xb2, 0x3c, 0xd6, 0x78, 0xd9, 0x5f, 0xec, 0x83, 0x7e, 0xe6, 0x1b, 0x82, 0x2a, 0x30, 0xb8, + 0xcd, 0x13, 0x02, 0x75, 0x1c, 0x37, 0x4a, 0x2b, 0x73, 0x0c, 0xc5, 0xe3, 0xa6, 0x41, 0xb1, 0x64, + 0x83, 0x56, 0x61, 0x8a, 0xe7, 0x65, 0x6a, 0x2c, 0x92, 0x86, 0xb3, 0x27, 0xd5, 0xa5, 0x3c, 0x89, + 0xb0, 0x52, 0x1b, 0xaf, 0xa4, 0x49, 0x70, 0x56, 0x39, 0xf4, 0x2a, 0x8c, 0xd1, 0xeb, 0xab, 0xdf, + 0x8e, 0x24, 0x27, 0x9e, 0x91, 0x49, 0x49, 0xf4, 0xeb, 0x06, 0x16, 0x27, 0xa8, 0xd1, 0x2b, 0x30, + 0xda, 0x4a, 0x29, 0x86, 0xfb, 0x63, 0x0d, 0x8a, 0xa9, 0x0c, 0x36, 0x69, 0x99, 0x23, 0x75, 0x9b, + 0xb9, 0x8d, 0xaf, 0x6f, 0x07, 0x24, 0xdc, 0xf6, 0x1b, 0x75, 0x26, 0x39, 0xf6, 0x6b, 0x8e, 0xd4, + 0x09, 0x3c, 0x4e, 0x95, 0xa0, 0x5c, 0x36, 0x1d, 0xb7, 0xd1, 0x0e, 0x48, 0xcc, 0x65, 0xc0, 0xe4, + 0xb2, 0x9c, 0xc0, 0xe3, 0x54, 0x89, 0xee, 0x1a, 0xef, 0xc1, 0xa3, 0xd1, 0x78, 0xdb, 0x3f, 0x53, + 0x00, 0x63, 0x68, 0xbf, 0x73, 0x33, 0x45, 0xd1, 0x2f, 0xdb, 0x0a, 0x5a, 0x35, 0xe1, 0x07, 0x95, + 0xf9, 0x65, 0x71, 0x02, 0x58, 0xfe, 0x65, 0xf4, 0x3f, 0x66, 0xa5, 0xe8, 0x1a, 0x3f, 0x59, 0x09, + 0x7c, 0x7a, 0xc8, 0xc9, 0x78, 0x65, 0xea, 0xbd, 0xc2, 0xa0, 0x7c, 0xcb, 0xdd, 0x21, 0xb2, 0xa7, + 0xf0, 0xe8, 0xe6, 0x1c, 0x0c, 0x97, 0xa1, 0xaa, 0x08, 0xaa, 0x20, 0xb9, 0xa0, 0x4b, 0x30, 0x2c, + 0xd2, 0xff, 0x30, 0xb7, 0x7a, 0xbe, 0x98, 0x98, 0x8b, 0xd3, 0x62, 0x0c, 0xc6, 0x3a, 0x8d, 0xfd, + 0x83, 0x05, 0x98, 0xca, 0x78, 0x17, 0xc5, 0x8f, 0x91, 0x2d, 0x37, 0x8c, 0x54, 0x8e, 0x59, 0xed, + 0x18, 0xe1, 0x70, 0xac, 0x28, 0xe8, 0x5e, 0xc5, 0x0f, 0xaa, 0xe4, 0xe1, 0x24, 0xde, 0x1d, 0x08, + 0xec, 0x21, 0xb3, 0xb5, 0x9e, 0x83, 0xbe, 0x76, 0x48, 0x64, 0x4c, 0x5e, 0x75, 0x6c, 0x33, 0x73, + 0x30, 0xc3, 0xd0, 0x1b, 0xd8, 0x96, 0xb2, 0xac, 0x6a, 0x37, 0x30, 0x6e, 0x5b, 0xe5, 0x38, 0xda, + 0xb8, 0x88, 0x78, 0x8e, 0x17, 0x89, 0x7b, 0x5a, 0x1c, 0x5c, 0x92, 0x41, 0xb1, 0xc0, 0xda, 0x5f, + 0x28, 0xc2, 0xe9, 0xdc, 0x97, 0x92, 0xb4, 0xe9, 0x4d, 0xdf, 0x73, 0x23, 0x5f, 0xf9, 0x8e, 0xf1, + 0x80, 0x92, 0xa4, 0xb5, 0xbd, 0x2a, 0xe0, 0x58, 0x51, 0xa0, 0xf3, 0xd0, 0xcf, 0x94, 0xc9, 0xa9, + 0x6c, 0xbb, 0xf3, 0x8b, 0x3c, 0xc2, 0x18, 0x47, 0xf7, 0x9c, 0x20, 0xfd, 0x31, 0x2a, 0xc1, 0xf8, + 0x8d, 0xe4, 0x81, 0x42, 0x9b, 0xeb, 0xfb, 0x0d, 0xcc, 0x90, 0xe8, 0x09, 0xd1, 0x5f, 0x09, 0x67, + 0x29, 0xec, 0xd4, 0xfd, 0x50, 0xeb, 0xb4, 0xa7, 0x60, 0x70, 0x87, 0xec, 0x05, 0xae, 0xb7, 0x95, + 0x74, 0xa2, 0xbb, 0xca, 0xc1, 0x58, 0xe2, 0xcd, 0xf4, 0x90, 0x83, 0x47, 0x9d, 0xd9, 0x7c, 0xa8, + 0xab, 0x78, 0xf2, 0xc3, 0x45, 0x18, 0xc7, 0xf3, 0x8b, 0xef, 0x0e, 0xc4, 0x8d, 0xf4, 0x40, 0x1c, + 0x75, 0x66, 0xf3, 0xee, 0xa3, 0xf1, 0x0b, 0x16, 0x8c, 0xb3, 0x24, 0x44, 0x22, 0x1e, 0x82, 0xeb, + 0x7b, 0xc7, 0x70, 0x15, 0x78, 0x0c, 0xfa, 0x03, 0x5a, 0x69, 0x32, 0xcd, 0x2e, 0x6b, 0x09, 0xe6, + 0x38, 0xf4, 0x08, 0xf4, 0xb1, 0x26, 0xd0, 0xc1, 0x1b, 0xe1, 0x5b, 0xf0, 0xa2, 0x13, 0x39, 0x98, + 0x41, 0x59, 0x7c, 0x2d, 0x4c, 0x5a, 0x0d, 0x97, 0x37, 0x3a, 0x36, 0xf5, 0xbf, 0x33, 0x62, 0x28, + 0x64, 0x36, 0xed, 0xed, 0xc5, 0xd7, 0xca, 0x66, 0xd9, 0xf9, 0x9a, 0xfd, 0xc7, 0x05, 0x38, 0x9b, + 0x59, 0xae, 0xe7, 0xf8, 0x5a, 0x9d, 0x4b, 0x3f, 0xc8, 0x34, 0x33, 0xc5, 0x63, 0x74, 0x51, 0xee, + 0xeb, 0x55, 0xfa, 0xef, 0xef, 0x21, 0xec, 0x55, 0x66, 0x97, 0xbd, 0x43, 0xc2, 0x5e, 0x65, 0xb6, + 0x2d, 0x47, 0x4d, 0xf0, 0xe7, 0x85, 0x9c, 0x6f, 0x61, 0x0a, 0x83, 0x0b, 0x74, 0x9f, 0x61, 0xc8, + 0x50, 0x5e, 0xc2, 0xf9, 0x1e, 0xc3, 0x61, 0x58, 0x61, 0xd1, 0x1c, 0x8c, 0x37, 0x5d, 0x8f, 0x6e, + 0x3e, 0x7b, 0xa6, 0x28, 0xae, 0x6c, 0x00, 0xab, 0x26, 0x1a, 0x27, 0xe9, 0x91, 0xab, 0x85, 0xc4, + 0xe2, 0x5f, 0xf7, 0xca, 0xa1, 0x56, 0xdd, 0xac, 0xe9, 0x06, 0xa1, 0x7a, 0x31, 0x23, 0x3c, 0xd6, + 0xaa, 0xa6, 0x27, 0x2a, 0xf6, 0xae, 0x27, 0x1a, 0xc9, 0xd6, 0x11, 0xcd, 0xbc, 0x02, 0xa3, 0xf7, + 0x6d, 0x53, 0xb0, 0xbf, 0x5e, 0x84, 0x87, 0x3b, 0x2c, 0x7b, 0xbe, 0xd7, 0x1b, 0x63, 0xa0, 0xed, + 0xf5, 0xa9, 0x71, 0xa8, 0xc0, 0x89, 0xcd, 0x76, 0xa3, 0xb1, 0xc7, 0x5e, 0xee, 0x90, 0xba, 0xa4, + 0x10, 0x32, 0xa5, 0x54, 0x8e, 0x9c, 0x58, 0xce, 0xa0, 0xc1, 0x99, 0x25, 0xe9, 0x15, 0x8b, 0x9e, + 0x24, 0x7b, 0x8a, 0x55, 0xe2, 0x8a, 0x85, 0x75, 0x24, 0x36, 0x69, 0xd1, 0x65, 0x98, 0x74, 0x76, + 0x1d, 0x97, 0xc7, 0x15, 0x97, 0x0c, 0xf8, 0x1d, 0x4b, 0xa9, 0x82, 0xe7, 0x92, 0x04, 0x38, 0x5d, + 0x06, 0xbd, 0x06, 0xc8, 0xdf, 0x60, 0xfe, 0xfd, 0xf5, 0xcb, 0xc4, 0x13, 0xd6, 0x6a, 0x36, 0x76, + 0xc5, 0x78, 0x4b, 0xb8, 0x9e, 0xa2, 0xc0, 0x19, 0xa5, 0x12, 0xf1, 0x9f, 0x06, 0xf2, 0xe3, 0x3f, + 0x75, 0xde, 0x17, 0xbb, 0x66, 0x38, 0xba, 0x04, 0xa3, 0x87, 0xf4, 0x5a, 0xb5, 0xff, 0x83, 0x45, + 0x4f, 0x3c, 0x5e, 0xc6, 0x0c, 0xae, 0xfa, 0x0a, 0x73, 0xab, 0xe5, 0x9a, 0x65, 0x2d, 0xc0, 0xce, + 0x49, 0xcd, 0xad, 0x36, 0x46, 0x62, 0x93, 0x96, 0xcf, 0x21, 0xcd, 0x1d, 0xd6, 0xb8, 0x15, 0x88, + 0x08, 0x70, 0x8a, 0x02, 0x7d, 0x0c, 0x06, 0xeb, 0xee, 0xae, 0x1b, 0x0a, 0xe5, 0xd8, 0xa1, 0x8d, + 0x58, 0xf1, 0xd6, 0xb9, 0xc8, 0xd9, 0x60, 0xc9, 0xcf, 0xfe, 0xe1, 0x42, 0xdc, 0x27, 0xaf, 0xb7, + 0xfd, 0xc8, 0x39, 0x86, 0x93, 0xfc, 0xb2, 0x71, 0x92, 0x3f, 0xd1, 0x29, 0x0c, 0x1e, 0x6b, 0x52, + 0xee, 0x09, 0x7e, 0x3d, 0x71, 0x82, 0x3f, 0xd9, 0x9d, 0x55, 0xe7, 0x93, 0xfb, 0x1f, 0x59, 0x30, + 0x69, 0xd0, 0x1f, 0xc3, 0x01, 0xb2, 0x6c, 0x1e, 0x20, 0x8f, 0x76, 0xfd, 0x86, 0x9c, 0x83, 0xe3, + 0xfb, 0x8a, 0x89, 0xb6, 0xb3, 0x03, 0xe3, 0x2d, 0xe8, 0xdb, 0x76, 0x82, 0x7a, 0xa7, 0xb4, 0x1f, + 0xa9, 0x42, 0xb3, 0x57, 0x9c, 0x40, 0x58, 0xf8, 0x9f, 0x91, 0xbd, 0x4e, 0x41, 0x5d, 0xad, 0xfb, + 0xac, 0x2a, 0xf4, 0x12, 0x0c, 0x84, 0x35, 0xbf, 0xa5, 0x9e, 0xfa, 0x9c, 0x63, 0x1d, 0xcd, 0x20, + 0x07, 0xfb, 0x65, 0x64, 0x56, 0x47, 0xc1, 0x58, 0xd0, 0xa3, 0x37, 0x60, 0x94, 0xfd, 0x52, 0xee, + 0x76, 0xc5, 0x7c, 0x0d, 0x46, 0x55, 0x27, 0xe4, 0xbe, 0xa8, 0x06, 0x08, 0x9b, 0xac, 0x66, 0xb6, + 0xa0, 0xa4, 0x3e, 0xeb, 0x81, 0x5a, 0x89, 0xff, 0x6d, 0x11, 0xa6, 0x32, 0xe6, 0x1c, 0x0a, 0x8d, + 0x91, 0xb8, 0xd4, 0xe3, 0x54, 0x7d, 0x9b, 0x63, 0x11, 0xb2, 0x0b, 0x54, 0x5d, 0xcc, 0xad, 0x9e, + 0x2b, 0xbd, 0x11, 0x92, 0x64, 0xa5, 0x14, 0xd4, 0xbd, 0x52, 0x5a, 0xd9, 0xb1, 0x75, 0x35, 0xad, + 0x48, 0xb5, 0xf4, 0x81, 0x8e, 0xe9, 0xaf, 0xf5, 0xc1, 0x89, 0xac, 0xc8, 0x9c, 0xe8, 0x33, 0x89, + 0xa4, 0xb3, 0x2f, 0xf4, 0x1a, 0xd3, 0x93, 0x67, 0xa2, 0x15, 0x11, 0x03, 0x67, 0xcd, 0x34, 0xb4, + 0x5d, 0xbb, 0x59, 0xd4, 0xc9, 0x62, 0x96, 0x04, 0x3c, 0x59, 0xb0, 0xdc, 0x3e, 0xde, 0xdf, 0x73, + 0x03, 0x44, 0x96, 0xe1, 0x30, 0xe1, 0xca, 0x23, 0xc1, 0xdd, 0x5d, 0x79, 0x64, 0xcd, 0x68, 0x05, + 0x06, 0x6a, 0xdc, 0x47, 0xa4, 0xd8, 0x7d, 0x0b, 0xe3, 0x0e, 0x22, 0x6a, 0x03, 0x16, 0x8e, 0x21, + 0x82, 0xc1, 0x8c, 0x0b, 0xc3, 0x5a, 0xc7, 0x3c, 0xd0, 0xc9, 0xb3, 0x43, 0x0f, 0x3e, 0xad, 0x0b, + 0x1e, 0xe8, 0x04, 0xfa, 0x31, 0x0b, 0x12, 0x0f, 0x45, 0x94, 0x52, 0xce, 0xca, 0x55, 0xca, 0x9d, + 0x83, 0xbe, 0xc0, 0x6f, 0x90, 0x64, 0xa2, 0x57, 0xec, 0x37, 0x08, 0x66, 0x18, 0x4a, 0x11, 0xc5, + 0xaa, 0x96, 0x11, 0xfd, 0x1a, 0x29, 0x2e, 0x88, 0x8f, 0x41, 0x7f, 0x83, 0xec, 0x92, 0x46, 0x32, + 0x1f, 0xd7, 0x35, 0x0a, 0xc4, 0x1c, 0x67, 0xff, 0x42, 0x1f, 0x9c, 0xe9, 0x18, 0x40, 0x88, 0x5e, + 0xc6, 0xb6, 0x9c, 0x88, 0xdc, 0x76, 0xf6, 0x92, 0x89, 0x73, 0x2e, 0x73, 0x30, 0x96, 0x78, 0xf6, + 0x6a, 0x91, 0xc7, 0xbf, 0x4f, 0xa8, 0x30, 0x45, 0xd8, 0x7b, 0x81, 0x35, 0x55, 0x62, 0xc5, 0xa3, + 0x50, 0x89, 0x3d, 0x07, 0x10, 0x86, 0x0d, 0xee, 0x4e, 0x57, 0x17, 0xcf, 0x21, 0xe3, 0x3c, 0x09, + 0xd5, 0x6b, 0x02, 0x83, 0x35, 0x2a, 0xb4, 0x08, 0x13, 0xad, 0xc0, 0x8f, 0xb8, 0x46, 0x78, 0x91, + 0x7b, 0x9c, 0xf6, 0x9b, 0xb1, 0x5b, 0x2a, 0x09, 0x3c, 0x4e, 0x95, 0x40, 0x2f, 0xc2, 0xb0, 0x88, + 0xe7, 0x52, 0xf1, 0xfd, 0x86, 0x50, 0x42, 0x29, 0x27, 0xcc, 0x6a, 0x8c, 0xc2, 0x3a, 0x9d, 0x56, + 0x8c, 0xa9, 0x99, 0x07, 0x33, 0x8b, 0x71, 0x55, 0xb3, 0x46, 0x97, 0x08, 0xf8, 0x3b, 0xd4, 0x53, + 0xc0, 0xdf, 0x58, 0x2d, 0x57, 0xea, 0xd9, 0xea, 0x09, 0x5d, 0x15, 0x59, 0x5f, 0xe9, 0x83, 0x29, + 0x31, 0x71, 0x1e, 0xf4, 0x74, 0xb9, 0x91, 0x9e, 0x2e, 0x47, 0xa1, 0xb8, 0x7b, 0x77, 0xce, 0x1c, + 0xf7, 0x9c, 0xf9, 0x11, 0x0b, 0x4c, 0x49, 0x0d, 0xfd, 0x7f, 0xb9, 0x99, 0xc7, 0x5e, 0xcc, 0x95, + 0xfc, 0x94, 0xc3, 0xe1, 0xdb, 0xcc, 0x41, 0x66, 0xff, 0x3b, 0x0b, 0x1e, 0xed, 0xca, 0x11, 0x2d, + 0x41, 0x89, 0x89, 0x93, 0xda, 0x45, 0xef, 0x49, 0xe5, 0x91, 0x2e, 0x11, 0x39, 0xd2, 0x6d, 0x5c, + 0x12, 0x2d, 0xa5, 0x52, 0xbc, 0x3d, 0x95, 0x91, 0xe2, 0xed, 0xa4, 0xd1, 0x3d, 0xf7, 0x99, 0xe3, + 0xed, 0x87, 0xe8, 0x89, 0x63, 0xbc, 0x06, 0x43, 0xef, 0x37, 0x94, 0x8e, 0x76, 0x42, 0xe9, 0x88, + 0x4c, 0x6a, 0xed, 0x0c, 0xf9, 0x08, 0x4c, 0xb0, 0x40, 0x6f, 0xec, 0x7d, 0x84, 0x78, 0xa7, 0x56, + 0x88, 0x7d, 0xa0, 0xaf, 0x25, 0x70, 0x38, 0x45, 0x6d, 0xff, 0x51, 0x11, 0x06, 0xf8, 0xf2, 0x3b, + 0x86, 0xeb, 0xe5, 0xd3, 0x50, 0x72, 0x9b, 0xcd, 0x36, 0xcf, 0xda, 0xd5, 0x1f, 0x7b, 0xd4, 0xae, + 0x48, 0x20, 0x8e, 0xf1, 0x68, 0x59, 0xe8, 0xbb, 0x3b, 0xc4, 0x92, 0xe5, 0x0d, 0x9f, 0x5d, 0x74, + 0x22, 0x87, 0xcb, 0x4a, 0xea, 0x9c, 0x8d, 0x35, 0xe3, 0xe8, 0x93, 0x00, 0x61, 0x14, 0xb8, 0xde, + 0x16, 0x85, 0x89, 0x10, 0xd6, 0xef, 0xed, 0xc0, 0xad, 0xaa, 0x88, 0x39, 0xcf, 0x78, 0xcf, 0x51, + 0x08, 0xac, 0x71, 0x44, 0xb3, 0xc6, 0x49, 0x3f, 0x93, 0x18, 0x3b, 0xe0, 0x5c, 0xe3, 0x31, 0x9b, + 0xf9, 0x00, 0x94, 0x14, 0xf3, 0x6e, 0xda, 0xaf, 0x11, 0x5d, 0x2c, 0xfa, 0x30, 0x8c, 0x27, 0xda, + 0x76, 0x28, 0xe5, 0xd9, 0x2f, 0x5a, 0x30, 0xce, 0x1b, 0xb3, 0xe4, 0xed, 0x8a, 0xd3, 0xe0, 0x2e, + 0x9c, 0x68, 0x64, 0xec, 0xca, 0x62, 0xf8, 0x7b, 0xdf, 0xc5, 0x95, 0xb2, 0x2c, 0x0b, 0x8b, 0x33, + 0xeb, 0x40, 0x17, 0xe8, 0x8a, 0xa3, 0xbb, 0xae, 0xd3, 0x10, 0xcf, 0xf2, 0x47, 0xf8, 0x6a, 0xe3, + 0x30, 0xac, 0xb0, 0xf6, 0xef, 0x59, 0x30, 0xc9, 0x5b, 0x7e, 0x95, 0xec, 0xa9, 0xbd, 0xe9, 0x5b, + 0xd9, 0x76, 0x91, 0x2f, 0xb2, 0x90, 0x93, 0x2f, 0x52, 0xff, 0xb4, 0x62, 0xc7, 0x4f, 0xfb, 0xb2, + 0x05, 0x62, 0x86, 0x1c, 0x83, 0x3e, 0xe3, 0xbb, 0x4c, 0x7d, 0xc6, 0x4c, 0xfe, 0x22, 0xc8, 0x51, + 0x64, 0xfc, 0x99, 0x05, 0x13, 0x9c, 0x20, 0xb6, 0xd5, 0x7f, 0x4b, 0xc7, 0xa1, 0x97, 0xac, 0xf2, + 0x57, 0xc9, 0xde, 0xba, 0x5f, 0x71, 0xa2, 0xed, 0xec, 0x8f, 0x32, 0x06, 0xab, 0xaf, 0xe3, 0x60, + 0xd5, 0xe5, 0x02, 0x32, 0xd2, 0x29, 0x75, 0x79, 0x5c, 0x7f, 0xd8, 0x74, 0x4a, 0xf6, 0x37, 0x2d, + 0x40, 0xbc, 0x1a, 0x43, 0x70, 0xa3, 0xe2, 0x10, 0x83, 0x6a, 0x07, 0x5d, 0xbc, 0x35, 0x29, 0x0c, + 0xd6, 0xa8, 0x8e, 0xa4, 0x7b, 0x12, 0x0e, 0x17, 0xc5, 0xee, 0x0e, 0x17, 0x87, 0xe8, 0xd1, 0x7f, + 0x31, 0x00, 0xc9, 0x17, 0x71, 0xe8, 0x26, 0x8c, 0xd4, 0x9c, 0x96, 0xb3, 0xe1, 0x36, 0xdc, 0xc8, + 0x25, 0x61, 0x27, 0x6f, 0xac, 0x05, 0x8d, 0x4e, 0x98, 0xc8, 0x35, 0x08, 0x36, 0xf8, 0xa0, 0x59, + 0x80, 0x56, 0xe0, 0xee, 0xba, 0x0d, 0xb2, 0xc5, 0xd4, 0x2e, 0x2c, 0x10, 0x08, 0x77, 0x0d, 0x93, + 0x50, 0xac, 0x51, 0x64, 0x84, 0x1f, 0x28, 0x3e, 0xe0, 0xf0, 0x03, 0x70, 0x6c, 0xe1, 0x07, 0xfa, + 0x0e, 0x15, 0x7e, 0x60, 0xe8, 0xd0, 0xe1, 0x07, 0xfa, 0x7b, 0x0a, 0x3f, 0x80, 0xe1, 0x94, 0x94, + 0x3d, 0xe9, 0xff, 0x65, 0xb7, 0x41, 0xc4, 0x85, 0x83, 0x47, 0x2f, 0x99, 0xb9, 0xb7, 0x5f, 0x3e, + 0x85, 0x33, 0x29, 0x70, 0x4e, 0x49, 0xf4, 0x51, 0x98, 0x76, 0x1a, 0x0d, 0xff, 0xb6, 0x1a, 0xd4, + 0xa5, 0xb0, 0xe6, 0x34, 0xb8, 0x09, 0x64, 0x90, 0x71, 0x7d, 0xe4, 0xde, 0x7e, 0x79, 0x7a, 0x2e, + 0x87, 0x06, 0xe7, 0x96, 0x46, 0x1f, 0x82, 0x52, 0x2b, 0xf0, 0x6b, 0xab, 0xda, 0xb3, 0xdd, 0xb3, + 0xb4, 0x03, 0x2b, 0x12, 0x78, 0xb0, 0x5f, 0x1e, 0x55, 0x7f, 0xd8, 0x81, 0x1f, 0x17, 0xc8, 0x88, + 0x27, 0x30, 0x7c, 0xa4, 0xf1, 0x04, 0x76, 0x60, 0xaa, 0x4a, 0x02, 0xd7, 0x69, 0xb8, 0x77, 0xa9, + 0xbc, 0x2c, 0xf7, 0xa7, 0x75, 0x28, 0x05, 0x89, 0x1d, 0xb9, 0xa7, 0xf8, 0xae, 0x5a, 0x5e, 0x1b, + 0xb9, 0x03, 0xc7, 0x8c, 0xec, 0xff, 0x65, 0xc1, 0xa0, 0x78, 0x01, 0x77, 0x0c, 0x52, 0xe3, 0x9c, + 0x61, 0x94, 0x28, 0x67, 0x77, 0x18, 0x6b, 0x4c, 0xae, 0x39, 0x62, 0x25, 0x61, 0x8e, 0x78, 0xb4, + 0x13, 0x93, 0xce, 0x86, 0x88, 0xbf, 0x5e, 0xa4, 0xd2, 0xbb, 0xf1, 0x16, 0xfb, 0xc1, 0x77, 0xc1, + 0x1a, 0x0c, 0x86, 0xe2, 0x2d, 0x70, 0x21, 0xff, 0x31, 0x46, 0x72, 0x10, 0x63, 0x2f, 0x3a, 0xf1, + 0xfa, 0x57, 0x32, 0xc9, 0x7c, 0x64, 0x5c, 0x7c, 0x80, 0x8f, 0x8c, 0xbb, 0xbd, 0x56, 0xef, 0x3b, + 0x8a, 0xd7, 0xea, 0xf6, 0xd7, 0xd8, 0xc9, 0xa9, 0xc3, 0x8f, 0x41, 0xa8, 0xba, 0x6c, 0x9e, 0xb1, + 0x76, 0x87, 0x99, 0x25, 0x1a, 0x95, 0x23, 0x5c, 0xfd, 0xbc, 0x05, 0x67, 0x32, 0xbe, 0x4a, 0x93, + 0xb4, 0x9e, 0x81, 0x21, 0xa7, 0x5d, 0x77, 0xd5, 0x5a, 0xd6, 0x4c, 0x93, 0x73, 0x02, 0x8e, 0x15, + 0x05, 0x5a, 0x80, 0x49, 0x72, 0xa7, 0xe5, 0x72, 0x43, 0xae, 0xee, 0x7c, 0x5c, 0xe4, 0xcf, 0x26, + 0x97, 0x92, 0x48, 0x9c, 0xa6, 0x57, 0x71, 0x8d, 0x8a, 0xb9, 0x71, 0x8d, 0xfe, 0x8e, 0x05, 0xc3, + 0xea, 0x35, 0xec, 0x03, 0xef, 0xed, 0x8f, 0x98, 0xbd, 0xfd, 0x70, 0x87, 0xde, 0xce, 0xe9, 0xe6, + 0xdf, 0x29, 0xa8, 0xf6, 0x56, 0xfc, 0x20, 0xea, 0x41, 0x82, 0xbb, 0xff, 0x87, 0x13, 0x97, 0x60, + 0xd8, 0x69, 0xb5, 0x24, 0x42, 0x7a, 0xc0, 0xb1, 0x68, 0xdd, 0x31, 0x18, 0xeb, 0x34, 0xea, 0x1d, + 0x47, 0x31, 0xf7, 0x1d, 0x47, 0x1d, 0x20, 0x72, 0x82, 0x2d, 0x12, 0x51, 0x98, 0x70, 0xd8, 0xcd, + 0xdf, 0x6f, 0xda, 0x91, 0xdb, 0x98, 0x75, 0xbd, 0x28, 0x8c, 0x82, 0xd9, 0x15, 0x2f, 0xba, 0x1e, + 0xf0, 0x2b, 0xa4, 0x16, 0x19, 0x4c, 0xf1, 0xc2, 0x1a, 0x5f, 0x19, 0xf9, 0x81, 0xd5, 0xd1, 0x6f, + 0xba, 0x52, 0xac, 0x09, 0x38, 0x56, 0x14, 0xf6, 0x07, 0xd8, 0xe9, 0xc3, 0xfa, 0xf4, 0x70, 0x51, + 0xb1, 0x7e, 0x6a, 0x44, 0x8d, 0x06, 0x33, 0x8a, 0x2e, 0xea, 0xb1, 0xb7, 0x3a, 0x6f, 0xf6, 0xb4, + 0x62, 0xfd, 0x41, 0x62, 0x1c, 0xa0, 0x0b, 0x7d, 0x3c, 0xe5, 0x1e, 0xf3, 0x6c, 0x97, 0x53, 0xe3, + 0x10, 0x0e, 0x31, 0x2c, 0x75, 0x0f, 0x4b, 0x6c, 0xb2, 0x52, 0x11, 0xeb, 0x42, 0x4b, 0xdd, 0x23, + 0x10, 0x38, 0xa6, 0xa1, 0xc2, 0x94, 0xfa, 0x13, 0x4e, 0xa3, 0x38, 0x84, 0xad, 0xa2, 0x0e, 0xb1, + 0x46, 0x81, 0x2e, 0x0a, 0x85, 0x02, 0xb7, 0x0b, 0x3c, 0x9c, 0x50, 0x28, 0xc8, 0xee, 0xd2, 0xb4, + 0x40, 0x97, 0x60, 0x58, 0x25, 0x6a, 0xaf, 0xf0, 0xa4, 0x59, 0x62, 0x9a, 0x2d, 0xc5, 0x60, 0xac, + 0xd3, 0xa0, 0x75, 0x18, 0x0f, 0xb9, 0x9e, 0x4d, 0xc5, 0x15, 0xe7, 0xfa, 0xca, 0xf7, 0xaa, 0x77, + 0xc8, 0x26, 0xfa, 0x80, 0x81, 0xf8, 0xee, 0x24, 0xa3, 0x33, 0x24, 0x59, 0xa0, 0x57, 0x61, 0xac, + 0xe1, 0x3b, 0xf5, 0x79, 0xa7, 0xe1, 0x78, 0x35, 0xd6, 0x3f, 0x43, 0x66, 0xbe, 0xdf, 0x6b, 0x06, + 0x16, 0x27, 0xa8, 0xa9, 0xf0, 0xa6, 0x43, 0x44, 0x74, 0x31, 0xc7, 0xdb, 0x22, 0xa1, 0x48, 0xbb, + 0xcd, 0x84, 0xb7, 0x6b, 0x39, 0x34, 0x38, 0xb7, 0x34, 0x7a, 0x09, 0x46, 0xe4, 0xe7, 0x6b, 0xc1, + 0x4c, 0xe2, 0x27, 0x31, 0x1a, 0x0e, 0x1b, 0x94, 0x28, 0x84, 0x93, 0xf2, 0xff, 0x7a, 0xe0, 0x6c, + 0x6e, 0xba, 0x35, 0xf1, 0xc2, 0x9f, 0x3f, 0xbb, 0xfd, 0xb0, 0x7c, 0x1b, 0xba, 0x94, 0x45, 0x74, + 0xb0, 0x5f, 0x7e, 0x44, 0xf4, 0x5a, 0x26, 0x1e, 0x67, 0xf3, 0x46, 0xab, 0x30, 0xb5, 0x4d, 0x9c, + 0x46, 0xb4, 0xbd, 0xb0, 0x4d, 0x6a, 0x3b, 0x72, 0xc1, 0xb1, 0xf0, 0x28, 0xda, 0xd3, 0x91, 0x2b, + 0x69, 0x12, 0x9c, 0x55, 0x0e, 0xbd, 0x09, 0xd3, 0xad, 0xf6, 0x46, 0xc3, 0x0d, 0xb7, 0xd7, 0xfc, + 0x88, 0x39, 0x21, 0xa9, 0x9c, 0xef, 0x22, 0x8e, 0x8a, 0x0a, 0x40, 0x53, 0xc9, 0xa1, 0xc3, 0xb9, + 0x1c, 0xd0, 0x5d, 0x38, 0x99, 0x98, 0x08, 0x22, 0x92, 0xc4, 0x58, 0x7e, 0x56, 0x91, 0x6a, 0x56, + 0x01, 0x11, 0x94, 0x25, 0x0b, 0x85, 0xb3, 0xab, 0x40, 0x2f, 0x03, 0xb8, 0xad, 0x65, 0xa7, 0xe9, + 0x36, 0xe8, 0x55, 0x71, 0x8a, 0xcd, 0x11, 0x7a, 0x6d, 0x80, 0x95, 0x8a, 0x84, 0xd2, 0xbd, 0x59, + 0xfc, 0xdb, 0xc3, 0x1a, 0x35, 0xba, 0x06, 0x63, 0xe2, 0xdf, 0x9e, 0x18, 0x52, 0x1e, 0xd0, 0xe4, + 0x71, 0x16, 0x8d, 0xaa, 0xa2, 0x63, 0x0e, 0x52, 0x10, 0x9c, 0x28, 0x8b, 0xb6, 0xe0, 0x8c, 0xcc, + 0x10, 0xa7, 0xcf, 0x4f, 0x39, 0x06, 0x21, 0x4b, 0xe5, 0x31, 0xc4, 0x5f, 0xa5, 0xcc, 0x75, 0x22, + 0xc4, 0x9d, 0xf9, 0xd0, 0x73, 0x5d, 0x9f, 0xe6, 0xfc, 0xc9, 0xef, 0x49, 0xee, 0xe1, 0x44, 0xcf, + 0xf5, 0x6b, 0x49, 0x24, 0x4e, 0xd3, 0x23, 0x1f, 0x4e, 0xba, 0x5e, 0xd6, 0xac, 0x3e, 0xc5, 0x18, + 0x7d, 0x90, 0xbf, 0x76, 0xee, 0x3c, 0xa3, 0x33, 0xf1, 0x38, 0x9b, 0xef, 0xdb, 0xf3, 0xfb, 0xfb, + 0x5d, 0x8b, 0x96, 0xd6, 0xa4, 0x73, 0xf4, 0x29, 0x18, 0xd1, 0x3f, 0x4a, 0x48, 0x1a, 0xe7, 0xb3, + 0x85, 0x57, 0x6d, 0x4f, 0xe0, 0xb2, 0xbd, 0x5a, 0xf7, 0x3a, 0x0e, 0x1b, 0x1c, 0x51, 0x2d, 0x23, + 0x26, 0xc0, 0xc5, 0xde, 0x24, 0x99, 0xde, 0xdd, 0xde, 0x08, 0x64, 0x4f, 0x77, 0x74, 0x0d, 0x86, + 0x6a, 0x0d, 0x97, 0x78, 0xd1, 0x4a, 0xa5, 0x53, 0xd4, 0xc3, 0x05, 0x41, 0x23, 0xd6, 0x8f, 0xc8, + 0xca, 0xc1, 0x61, 0x58, 0x71, 0xb0, 0x7f, 0xa3, 0x00, 0xe5, 0x2e, 0x29, 0x5e, 0x12, 0x66, 0x28, + 0xab, 0x27, 0x33, 0xd4, 0x1c, 0x8c, 0xc7, 0xff, 0x74, 0x0d, 0x97, 0xf2, 0x64, 0xbd, 0x69, 0xa2, + 0x71, 0x92, 0xbe, 0xe7, 0x47, 0x09, 0xba, 0x25, 0xab, 0xaf, 0xeb, 0xb3, 0x1a, 0xc3, 0x82, 0xdd, + 0xdf, 0xfb, 0xb5, 0x37, 0xd7, 0x1a, 0x69, 0x7f, 0xad, 0x00, 0x27, 0x55, 0x17, 0x7e, 0xe7, 0x76, + 0xdc, 0x8d, 0x74, 0xc7, 0x1d, 0x81, 0x2d, 0xd7, 0xbe, 0x0e, 0x03, 0x3c, 0x8c, 0x63, 0x0f, 0xe2, + 0xf6, 0x63, 0x66, 0x70, 0x67, 0x25, 0xe1, 0x19, 0x01, 0x9e, 0x7f, 0xc0, 0x82, 0xf1, 0xc4, 0xeb, + 0x36, 0x84, 0xb5, 0x27, 0xd0, 0xf7, 0x23, 0x12, 0x67, 0x09, 0xdb, 0xe7, 0xa0, 0x6f, 0xdb, 0x0f, + 0xa3, 0xa4, 0xa3, 0xc7, 0x15, 0x3f, 0x8c, 0x30, 0xc3, 0xd8, 0xbf, 0x6f, 0x41, 0xff, 0xba, 0xe3, + 0x7a, 0x91, 0x34, 0x0a, 0x58, 0x39, 0x46, 0x81, 0x5e, 0xbe, 0x0b, 0xbd, 0x08, 0x03, 0x64, 0x73, + 0x93, 0xd4, 0x22, 0x31, 0xaa, 0x32, 0xf4, 0xc4, 0xc0, 0x12, 0x83, 0x52, 0xf9, 0x8f, 0x55, 0xc6, + 0xff, 0x62, 0x41, 0x8c, 0x6e, 0x41, 0x29, 0x72, 0x9b, 0x64, 0xae, 0x5e, 0x17, 0xa6, 0xf2, 0xfb, + 0x08, 0x9f, 0xb1, 0x2e, 0x19, 0xe0, 0x98, 0x97, 0xfd, 0x85, 0x02, 0x40, 0x1c, 0xff, 0xaa, 0xdb, + 0x27, 0xce, 0xa7, 0x8c, 0xa8, 0xe7, 0x33, 0x8c, 0xa8, 0x28, 0x66, 0x98, 0x61, 0x41, 0x55, 0xdd, + 0x54, 0xec, 0xa9, 0x9b, 0xfa, 0x0e, 0xd3, 0x4d, 0x0b, 0x30, 0x19, 0xc7, 0xef, 0x32, 0xc3, 0x17, + 0xb2, 0xa3, 0x73, 0x3d, 0x89, 0xc4, 0x69, 0x7a, 0x9b, 0xc0, 0x39, 0x15, 0xc6, 0x48, 0x9c, 0x68, + 0xcc, 0x0f, 0x5c, 0x37, 0x4a, 0x77, 0xe9, 0xa7, 0xd8, 0x4a, 0x5c, 0xc8, 0xb5, 0x12, 0xff, 0xa4, + 0x05, 0x27, 0x92, 0xf5, 0xb0, 0x47, 0xd3, 0x9f, 0xb7, 0xe0, 0x24, 0xb3, 0x95, 0xb3, 0x5a, 0xd3, + 0x96, 0xf9, 0x17, 0x3a, 0x86, 0x66, 0xca, 0x69, 0x71, 0x1c, 0xe3, 0x64, 0x35, 0x8b, 0x35, 0xce, + 0xae, 0xd1, 0xfe, 0x9f, 0x7d, 0x30, 0x9d, 0x17, 0xd3, 0x89, 0x3d, 0x13, 0x71, 0xee, 0x54, 0x77, + 0xc8, 0x6d, 0xe1, 0x8c, 0x1f, 0x3f, 0x13, 0xe1, 0x60, 0x2c, 0xf1, 0xc9, 0xac, 0x1d, 0x85, 0x1e, + 0xb3, 0x76, 0x6c, 0xc3, 0xe4, 0xed, 0x6d, 0xe2, 0xdd, 0xf0, 0x42, 0x27, 0x72, 0xc3, 0x4d, 0x97, + 0xd9, 0x95, 0xf9, 0xbc, 0x91, 0xa9, 0x7e, 0x27, 0x6f, 0x25, 0x09, 0x0e, 0xf6, 0xcb, 0x67, 0x0c, + 0x40, 0xdc, 0x64, 0xbe, 0x91, 0xe0, 0x34, 0xd3, 0x74, 0xd2, 0x93, 0xbe, 0x07, 0x9c, 0xf4, 0xa4, + 0xe9, 0x0a, 0x6f, 0x14, 0xf9, 0x06, 0x80, 0xdd, 0x18, 0x57, 0x15, 0x14, 0x6b, 0x14, 0xe8, 0x13, + 0x80, 0xf4, 0xa4, 0x4e, 0x46, 0x48, 0xcd, 0x67, 0xef, 0xed, 0x97, 0xd1, 0x5a, 0x0a, 0x7b, 0xb0, + 0x5f, 0x9e, 0xa2, 0xd0, 0x15, 0x8f, 0xde, 0x3c, 0xe3, 0x38, 0x64, 0x19, 0x8c, 0xd0, 0x2d, 0x98, + 0xa0, 0x50, 0xb6, 0xa2, 0x64, 0xbc, 0x4e, 0x7e, 0x5b, 0x7c, 0xfa, 0xde, 0x7e, 0x79, 0x62, 0x2d, + 0x81, 0xcb, 0x63, 0x9d, 0x62, 0x82, 0x5e, 0x86, 0xb1, 0x78, 0x5e, 0x5d, 0x25, 0x7b, 0x3c, 0x3e, + 0x4e, 0x89, 0x2b, 0xbc, 0x57, 0x0d, 0x0c, 0x4e, 0x50, 0xda, 0x9f, 0xb7, 0xe0, 0x74, 0x6e, 0xe2, + 0x71, 0x74, 0x01, 0x86, 0x9c, 0x96, 0xcb, 0xcd, 0x17, 0xe2, 0xa8, 0x61, 0x6a, 0xb2, 0xca, 0x0a, + 0x37, 0x5e, 0x28, 0x2c, 0xdd, 0xe1, 0x77, 0x5c, 0xaf, 0x9e, 0xdc, 0xe1, 0xaf, 0xba, 0x5e, 0x1d, + 0x33, 0x8c, 0x3a, 0xb2, 0x8a, 0xb9, 0x4f, 0x11, 0xbe, 0x42, 0xd7, 0x6a, 0x46, 0x8a, 0xf2, 0xe3, + 0x6d, 0x06, 0x7a, 0x5a, 0x37, 0x35, 0x0a, 0xaf, 0xc2, 0x5c, 0x33, 0xe3, 0xf7, 0x5b, 0x20, 0x9e, + 0x2e, 0xf7, 0x70, 0x26, 0xbf, 0x01, 0x23, 0xbb, 0xe9, 0x84, 0x77, 0xe7, 0xf2, 0xdf, 0x72, 0x8b, + 0x40, 0xe1, 0x4a, 0xd0, 0x36, 0x92, 0xdb, 0x19, 0xbc, 0xec, 0x3a, 0x08, 0xec, 0x22, 0x61, 0x06, + 0x85, 0xee, 0xad, 0x79, 0x0e, 0xa0, 0xce, 0x68, 0x59, 0x16, 0xdc, 0x82, 0x29, 0x71, 0x2d, 0x2a, + 0x0c, 0xd6, 0xa8, 0xec, 0x7f, 0x55, 0x80, 0x61, 0x99, 0x60, 0xad, 0xed, 0xf5, 0xa2, 0xf6, 0x3b, + 0x54, 0xc6, 0x65, 0x74, 0x11, 0x4a, 0x4c, 0x2f, 0x5d, 0x89, 0xb5, 0xa5, 0x4a, 0x2b, 0xb4, 0x2a, + 0x11, 0x38, 0xa6, 0xa1, 0xbb, 0x63, 0xd8, 0xde, 0x60, 0xe4, 0x89, 0x87, 0xb6, 0x55, 0x0e, 0xc6, + 0x12, 0x8f, 0x3e, 0x0a, 0x13, 0xbc, 0x5c, 0xe0, 0xb7, 0x9c, 0x2d, 0x6e, 0xcb, 0xea, 0x57, 0xd1, + 0x4b, 0x26, 0x56, 0x13, 0xb8, 0x83, 0xfd, 0xf2, 0x89, 0x24, 0x8c, 0x19, 0x69, 0x53, 0x5c, 0x98, + 0xcb, 0x1a, 0xaf, 0x84, 0xee, 0xea, 0x29, 0x4f, 0xb7, 0x18, 0x85, 0x75, 0x3a, 0xfb, 0x53, 0x80, + 0xd2, 0xa9, 0xe6, 0xd0, 0x6b, 0xdc, 0xe5, 0xd9, 0x0d, 0x48, 0xbd, 0x93, 0xd1, 0x56, 0x8f, 0xd1, + 0x21, 0xdf, 0xc8, 0xf1, 0x52, 0x58, 0x95, 0xb7, 0xff, 0x52, 0x11, 0x26, 0x92, 0x51, 0x01, 0xd0, + 0x15, 0x18, 0xe0, 0x22, 0xa5, 0x60, 0xdf, 0xc1, 0x27, 0x48, 0x8b, 0x25, 0xc0, 0x0e, 0x57, 0x21, + 0x95, 0x8a, 0xf2, 0xe8, 0x4d, 0x18, 0xae, 0xfb, 0xb7, 0xbd, 0xdb, 0x4e, 0x50, 0x9f, 0xab, 0xac, + 0x88, 0xe9, 0x9c, 0xa9, 0xa8, 0x58, 0x8c, 0xc9, 0xf4, 0xf8, 0x04, 0xcc, 0xfe, 0x1d, 0xa3, 0xb0, + 0xce, 0x0e, 0xad, 0xb3, 0xfc, 0x14, 0x9b, 0xee, 0xd6, 0xaa, 0xd3, 0xea, 0xf4, 0xfe, 0x65, 0x41, + 0x12, 0x69, 0x9c, 0x47, 0x45, 0x12, 0x0b, 0x8e, 0xc0, 0x31, 0x23, 0xf4, 0x19, 0x98, 0x0a, 0x73, + 0x4c, 0x27, 0x79, 0x99, 0x47, 0x3b, 0x59, 0x13, 0xe6, 0x1f, 0xba, 0xb7, 0x5f, 0x9e, 0xca, 0x32, + 0xb2, 0x64, 0x55, 0x63, 0x7f, 0xf1, 0x04, 0x18, 0x8b, 0xd8, 0x48, 0x44, 0x6d, 0x1d, 0x51, 0x22, + 0x6a, 0x0c, 0x43, 0xa4, 0xd9, 0x8a, 0xf6, 0x16, 0xdd, 0x40, 0x8c, 0x49, 0x26, 0xcf, 0x25, 0x41, + 0x93, 0xe6, 0x29, 0x31, 0x58, 0xf1, 0xc9, 0xce, 0x16, 0x5e, 0xfc, 0x16, 0x66, 0x0b, 0xef, 0x3b, + 0xc6, 0x6c, 0xe1, 0x6b, 0x30, 0xb8, 0xe5, 0x46, 0x98, 0xb4, 0x7c, 0x71, 0x99, 0xcb, 0x9c, 0x87, + 0x97, 0x39, 0x49, 0x3a, 0x2f, 0xad, 0x40, 0x60, 0xc9, 0x04, 0xbd, 0xa6, 0x56, 0xe0, 0x40, 0xbe, + 0xc2, 0x25, 0xed, 0xbc, 0x92, 0xb9, 0x06, 0x45, 0x4e, 0xf0, 0xc1, 0xfb, 0xcd, 0x09, 0xbe, 0x2c, + 0x33, 0x79, 0x0f, 0xe5, 0x3f, 0x56, 0x63, 0x89, 0xba, 0xbb, 0xe4, 0xef, 0xbe, 0xa9, 0x67, 0x3f, + 0x2f, 0xe5, 0xef, 0x04, 0x2a, 0xb1, 0x79, 0x8f, 0x39, 0xcf, 0xbf, 0xdf, 0x82, 0x93, 0xc9, 0xec, + 0xa4, 0xec, 0x4d, 0x85, 0xf0, 0xf3, 0x78, 0xb1, 0x97, 0x74, 0xb1, 0xac, 0x80, 0x51, 0x21, 0xd3, + 0x91, 0x66, 0x92, 0xe1, 0xec, 0xea, 0x68, 0x47, 0x07, 0x1b, 0x75, 0xe1, 0x6f, 0xf0, 0x58, 0x4e, + 0xf2, 0xf4, 0x0e, 0x29, 0xd3, 0xd7, 0x33, 0x12, 0x75, 0x3f, 0x9e, 0x97, 0xa8, 0xbb, 0xe7, 0xf4, + 0xdc, 0xaf, 0xa9, 0xb4, 0xe9, 0xa3, 0xf9, 0x53, 0x89, 0x27, 0x45, 0xef, 0x9a, 0x2c, 0xfd, 0x35, + 0x95, 0x2c, 0xbd, 0x43, 0x44, 0x6e, 0x9e, 0x0a, 0xbd, 0x6b, 0x8a, 0x74, 0x2d, 0xcd, 0xf9, 0xf8, + 0xd1, 0xa4, 0x39, 0x37, 0x8e, 0x1a, 0x9e, 0x69, 0xfb, 0xe9, 0x2e, 0x47, 0x8d, 0xc1, 0xb7, 0xf3, + 0x61, 0xc3, 0x53, 0xba, 0x4f, 0xde, 0x57, 0x4a, 0xf7, 0x9b, 0x7a, 0x8a, 0x74, 0xd4, 0x25, 0x07, + 0x38, 0x25, 0xea, 0x31, 0x31, 0xfa, 0x4d, 0xfd, 0x00, 0x9c, 0xca, 0xe7, 0xab, 0xce, 0xb9, 0x34, + 0xdf, 0xcc, 0x23, 0x30, 0x95, 0x70, 0xfd, 0xc4, 0xf1, 0x24, 0x5c, 0x3f, 0x79, 0xe4, 0x09, 0xd7, + 0x4f, 0x1d, 0x43, 0xc2, 0xf5, 0x87, 0x8e, 0x31, 0xe1, 0xfa, 0x4d, 0xe6, 0x1c, 0xc5, 0x03, 0x40, + 0x89, 0x08, 0xe2, 0x4f, 0xe5, 0xc4, 0x4f, 0x4b, 0x47, 0x89, 0xe2, 0x1f, 0xa7, 0x50, 0x38, 0x66, + 0x95, 0x91, 0xc8, 0x7d, 0xfa, 0x01, 0x24, 0x72, 0x5f, 0x8b, 0x13, 0xb9, 0x9f, 0xce, 0x1f, 0xea, + 0x8c, 0xe7, 0x34, 0x39, 0xe9, 0xdb, 0x6f, 0xea, 0x69, 0xd7, 0x1f, 0xee, 0x60, 0x05, 0xcb, 0x52, + 0x28, 0x77, 0x48, 0xb6, 0xfe, 0x2a, 0x4f, 0xb6, 0xfe, 0x48, 0xfe, 0x4e, 0x9e, 0x3c, 0xee, 0x8c, + 0x14, 0xeb, 0xb4, 0x5d, 0x2a, 0xf6, 0x2a, 0x8b, 0x95, 0x9e, 0xd3, 0x2e, 0x15, 0xbc, 0x35, 0xdd, + 0x2e, 0x85, 0xc2, 0x31, 0x2b, 0xfb, 0x07, 0x0b, 0x70, 0xb6, 0xf3, 0x7a, 0x8b, 0xb5, 0xe4, 0x95, + 0xd8, 0x21, 0x20, 0xa1, 0x25, 0xe7, 0x77, 0xb6, 0x98, 0xaa, 0xe7, 0x78, 0x90, 0x97, 0x61, 0x52, + 0xbd, 0xc3, 0x69, 0xb8, 0xb5, 0xbd, 0xb5, 0xf8, 0x9a, 0xac, 0x22, 0x27, 0x54, 0x93, 0x04, 0x38, + 0x5d, 0x06, 0xcd, 0xc1, 0xb8, 0x01, 0x5c, 0x59, 0x14, 0x77, 0xb3, 0x38, 0x3a, 0xb7, 0x89, 0xc6, + 0x49, 0x7a, 0xfb, 0x4b, 0x16, 0x3c, 0x94, 0x93, 0xa9, 0xb4, 0xe7, 0x70, 0x87, 0x9b, 0x30, 0xde, + 0x32, 0x8b, 0x76, 0x89, 0xd0, 0x6a, 0xe4, 0x43, 0x55, 0x6d, 0x4d, 0x20, 0x70, 0x92, 0xa9, 0xfd, + 0xb3, 0x05, 0x38, 0xd3, 0xd1, 0xb1, 0x14, 0x61, 0x38, 0xb5, 0xd5, 0x0c, 0x9d, 0x85, 0x80, 0xd4, + 0x89, 0x17, 0xb9, 0x4e, 0xa3, 0xda, 0x22, 0x35, 0xcd, 0xce, 0xc1, 0x3c, 0x34, 0x2f, 0xaf, 0x56, + 0xe7, 0xd2, 0x14, 0x38, 0xa7, 0x24, 0x5a, 0x06, 0x94, 0xc6, 0x88, 0x11, 0x66, 0x51, 0xf7, 0xd3, + 0xfc, 0x70, 0x46, 0x09, 0xf4, 0x01, 0x18, 0x55, 0x0e, 0xab, 0xda, 0x88, 0xb3, 0x8d, 0x1d, 0xeb, + 0x08, 0x6c, 0xd2, 0xa1, 0x4b, 0x3c, 0x6d, 0x83, 0x48, 0xf0, 0x21, 0x8c, 0x22, 0xe3, 0x32, 0x27, + 0x83, 0x00, 0x63, 0x9d, 0x66, 0xfe, 0xa5, 0xdf, 0xfc, 0xc6, 0xd9, 0xf7, 0xfc, 0xf6, 0x37, 0xce, + 0xbe, 0xe7, 0xf7, 0xbe, 0x71, 0xf6, 0x3d, 0xdf, 0x7d, 0xef, 0xac, 0xf5, 0x9b, 0xf7, 0xce, 0x5a, + 0xbf, 0x7d, 0xef, 0xac, 0xf5, 0x7b, 0xf7, 0xce, 0x5a, 0x7f, 0x70, 0xef, 0xac, 0xf5, 0x85, 0x3f, + 0x3c, 0xfb, 0x9e, 0x37, 0x50, 0x1c, 0x40, 0xf4, 0x22, 0x1d, 0x9d, 0x8b, 0xbb, 0x97, 0xfe, 0x5f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x6c, 0x51, 0x7f, 0x2c, 0x10, 0x01, 0x00, } func (m *AWSElasticBlockStoreVolumeSource) Marshal() (dAtA []byte, err error) { @@ -7459,6 +7660,18 @@ func (m *CSIPersistentVolumeSource) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if m.NodeExpandSecretRef != nil { + { + size, err := m.NodeExpandSecretRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } if m.ControllerExpandSecretRef != nil { { size, err := m.ControllerExpandSecretRef.MarshalToSizedBuffer(dAtA[:i]) @@ -7919,6 +8132,43 @@ func (m *CinderVolumeSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ClaimSource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClaimSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClaimSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ResourceClaimTemplateName != nil { + i -= len(*m.ResourceClaimTemplateName) + copy(dAtA[i:], *m.ResourceClaimTemplateName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ResourceClaimTemplateName))) + i-- + dAtA[i] = 0x12 + } + if m.ResourceClaimName != nil { + i -= len(*m.ResourceClaimName) + copy(dAtA[i:], *m.ResourceClaimName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ResourceClaimName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ClientIPConfig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -8502,6 +8752,22 @@ func (m *Container) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ResizePolicy) > 0 { + for iNdEx := len(m.ResizePolicy) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResizePolicy[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + } if m.StartupProbe != nil { { size, err := m.StartupProbe.MarshalToSizedBuffer(dAtA[:i]) @@ -8810,6 +9076,39 @@ func (m *ContainerPort) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContainerResizePolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContainerResizePolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContainerResizePolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.RestartPolicy) + copy(dAtA[i:], m.RestartPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.RestartPolicy))) + i-- + dAtA[i] = 0x12 + i -= len(m.ResourceName) + copy(dAtA[i:], m.ResourceName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ContainerState) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9019,6 +9318,47 @@ func (m *ContainerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Resources != nil { + { + size, err := m.Resources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + if len(m.AllocatedResources) > 0 { + keysForAllocatedResources := make([]string, 0, len(m.AllocatedResources)) + for k := range m.AllocatedResources { + keysForAllocatedResources = append(keysForAllocatedResources, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAllocatedResources) + for iNdEx := len(keysForAllocatedResources) - 1; iNdEx >= 0; iNdEx-- { + v := m.AllocatedResources[ResourceName(keysForAllocatedResources[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForAllocatedResources[iNdEx]) + copy(dAtA[i:], keysForAllocatedResources[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForAllocatedResources[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x52 + } + } if m.Started != nil { i-- if *m.Started { @@ -9765,6 +10105,22 @@ func (m *EphemeralContainerCommon) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.ResizePolicy) > 0 { + for iNdEx := len(m.ResizePolicy) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResizePolicy[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + } if m.StartupProbe != nil { { size, err := m.StartupProbe.MarshalToSizedBuffer(dAtA[:i]) @@ -14873,6 +15229,72 @@ func (m *PodReadinessGate) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PodResourceClaim) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodResourceClaim) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodSchedulingGate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingGate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingGate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *PodSecurityContext) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -15040,6 +15462,50 @@ func (m *PodSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ResourceClaims) > 0 { + for iNdEx := len(m.ResourceClaims) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceClaims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xba + } + } + if len(m.SchedulingGates) > 0 { + for iNdEx := len(m.SchedulingGates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SchedulingGates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xb2 + } + } + if m.HostUsers != nil { + i-- + if *m.HostUsers { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xa8 + } if m.OS != nil { { size, err := m.OS.MarshalToSizedBuffer(dAtA[:i]) @@ -15470,6 +15936,11 @@ func (m *PodStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.Resize) + copy(dAtA[i:], m.Resize) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resize))) + i-- + dAtA[i] = 0x72 if len(m.EphemeralContainerStatuses) > 0 { for iNdEx := len(m.EphemeralContainerStatuses) - 1; iNdEx >= 0; iNdEx-- { { @@ -16657,6 +17128,34 @@ func (m *ReplicationControllerStatus) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *ResourceClaim) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaim) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ResourceFieldSelector) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -16974,6 +17473,20 @@ func (m *ResourceRequirements) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Claims) > 0 { + for iNdEx := len(m.Claims) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Claims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } if len(m.Requests) > 0 { keysForRequests := make([]string, 0, len(m.Requests)) for k := range m.Requests { @@ -18902,6 +19415,29 @@ func (m *TopologySpreadConstraint) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.MatchLabelKeys) > 0 { + for iNdEx := len(m.MatchLabelKeys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.MatchLabelKeys[iNdEx]) + copy(dAtA[i:], m.MatchLabelKeys[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MatchLabelKeys[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if m.NodeTaintsPolicy != nil { + i -= len(*m.NodeTaintsPolicy) + copy(dAtA[i:], *m.NodeTaintsPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.NodeTaintsPolicy))) + i-- + dAtA[i] = 0x3a + } + if m.NodeAffinityPolicy != nil { + i -= len(*m.NodeAffinityPolicy) + copy(dAtA[i:], *m.NodeAffinityPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.NodeAffinityPolicy))) + i-- + dAtA[i] = 0x32 + } if m.MinDomains != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.MinDomains)) i-- @@ -18975,6 +19511,53 @@ func (m *TypedLocalObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *TypedObjectReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TypedObjectReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TypedObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Namespace != nil { + i -= len(*m.Namespace) + copy(dAtA[i:], *m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Namespace))) + i-- + dAtA[i] = 0x22 + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + if m.APIGroup != nil { + i -= len(*m.APIGroup) + copy(dAtA[i:], *m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.APIGroup))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Volume) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -19927,6 +20510,10 @@ func (m *CSIPersistentVolumeSource) Size() (n int) { l = m.ControllerExpandSecretRef.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.NodeExpandSecretRef != nil { + l = m.NodeExpandSecretRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -20069,6 +20656,23 @@ func (m *CinderVolumeSource) Size() (n int) { return n } +func (m *ClaimSource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ResourceClaimName != nil { + l = len(*m.ResourceClaimName) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ResourceClaimTemplateName != nil { + l = len(*m.ResourceClaimTemplateName) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *ClientIPConfig) Size() (n int) { if m == nil { return 0 @@ -20360,6 +20964,12 @@ func (m *Container) Size() (n int) { l = m.StartupProbe.Size() n += 2 + l + sovGenerated(uint64(l)) } + if len(m.ResizePolicy) > 0 { + for _, e := range m.ResizePolicy { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -20396,6 +21006,19 @@ func (m *ContainerPort) Size() (n int) { return n } +func (m *ContainerResizePolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ResourceName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.RestartPolicy) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ContainerState) Size() (n int) { if m == nil { return 0 @@ -20485,6 +21108,19 @@ func (m *ContainerStatus) Size() (n int) { if m.Started != nil { n += 2 } + if len(m.AllocatedResources) > 0 { + for k, v := range m.AllocatedResources { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + if m.Resources != nil { + l = m.Resources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -20827,6 +21463,12 @@ func (m *EphemeralContainerCommon) Size() (n int) { l = m.StartupProbe.Size() n += 2 + l + sovGenerated(uint64(l)) } + if len(m.ResizePolicy) > 0 { + for _, e := range m.ResizePolicy { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -22608,6 +23250,30 @@ func (m *PodReadinessGate) Size() (n int) { return n } +func (m *PodResourceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Source.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PodSchedulingGate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *PodSecurityContext) Size() (n int) { if m == nil { return 0 @@ -22812,6 +23478,21 @@ func (m *PodSpec) Size() (n int) { l = m.OS.Size() n += 2 + l + sovGenerated(uint64(l)) } + if m.HostUsers != nil { + n += 3 + } + if len(m.SchedulingGates) > 0 { + for _, e := range m.SchedulingGates { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } + if len(m.ResourceClaims) > 0 { + for _, e := range m.ResourceClaims { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -22869,6 +23550,8 @@ func (m *PodStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + l = len(m.Resize) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -23255,6 +23938,17 @@ func (m *ReplicationControllerStatus) Size() (n int) { return n } +func (m *ResourceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ResourceFieldSelector) Size() (n int) { if m == nil { return 0 @@ -23381,6 +24075,12 @@ func (m *ResourceRequirements) Size() (n int) { n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } + if len(m.Claims) > 0 { + for _, e := range m.Claims { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -24093,6 +24793,20 @@ func (m *TopologySpreadConstraint) Size() (n int) { if m.MinDomains != nil { n += 1 + sovGenerated(uint64(*m.MinDomains)) } + if m.NodeAffinityPolicy != nil { + l = len(*m.NodeAffinityPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.NodeTaintsPolicy != nil { + l = len(*m.NodeTaintsPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.MatchLabelKeys) > 0 { + for _, s := range m.MatchLabelKeys { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -24113,6 +24827,27 @@ func (m *TypedLocalObjectReference) Size() (n int) { return n } +func (m *TypedObjectReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.APIGroup != nil { + l = len(*m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.Namespace != nil { + l = len(*m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *Volume) Size() (n int) { if m == nil { return 0 @@ -24509,6 +25244,7 @@ func (this *CSIPersistentVolumeSource) String() string { `NodeStageSecretRef:` + strings.Replace(this.NodeStageSecretRef.String(), "SecretReference", "SecretReference", 1) + `,`, `NodePublishSecretRef:` + strings.Replace(this.NodePublishSecretRef.String(), "SecretReference", "SecretReference", 1) + `,`, `ControllerExpandSecretRef:` + strings.Replace(this.ControllerExpandSecretRef.String(), "SecretReference", "SecretReference", 1) + `,`, + `NodeExpandSecretRef:` + strings.Replace(this.NodeExpandSecretRef.String(), "SecretReference", "SecretReference", 1) + `,`, `}`, }, "") return s @@ -24604,6 +25340,17 @@ func (this *CinderVolumeSource) String() string { }, "") return s } +func (this *ClaimSource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClaimSource{`, + `ResourceClaimName:` + valueToStringGenerated(this.ResourceClaimName) + `,`, + `ResourceClaimTemplateName:` + valueToStringGenerated(this.ResourceClaimTemplateName) + `,`, + `}`, + }, "") + return s +} func (this *ClientIPConfig) String() string { if this == nil { return "nil" @@ -24809,6 +25556,11 @@ func (this *Container) String() string { repeatedStringForVolumeDevices += strings.Replace(strings.Replace(f.String(), "VolumeDevice", "VolumeDevice", 1), `&`, ``, 1) + "," } repeatedStringForVolumeDevices += "}" + repeatedStringForResizePolicy := "[]ContainerResizePolicy{" + for _, f := range this.ResizePolicy { + repeatedStringForResizePolicy += strings.Replace(strings.Replace(f.String(), "ContainerResizePolicy", "ContainerResizePolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForResizePolicy += "}" s := strings.Join([]string{`&Container{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Image:` + fmt.Sprintf("%v", this.Image) + `,`, @@ -24832,6 +25584,7 @@ func (this *Container) String() string { `TerminationMessagePolicy:` + fmt.Sprintf("%v", this.TerminationMessagePolicy) + `,`, `VolumeDevices:` + repeatedStringForVolumeDevices + `,`, `StartupProbe:` + strings.Replace(this.StartupProbe.String(), "Probe", "Probe", 1) + `,`, + `ResizePolicy:` + repeatedStringForResizePolicy + `,`, `}`, }, "") return s @@ -24861,6 +25614,17 @@ func (this *ContainerPort) String() string { }, "") return s } +func (this *ContainerResizePolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ContainerResizePolicy{`, + `ResourceName:` + fmt.Sprintf("%v", this.ResourceName) + `,`, + `RestartPolicy:` + fmt.Sprintf("%v", this.RestartPolicy) + `,`, + `}`, + }, "") + return s +} func (this *ContainerState) String() string { if this == nil { return "nil" @@ -24914,6 +25678,16 @@ func (this *ContainerStatus) String() string { if this == nil { return "nil" } + keysForAllocatedResources := make([]string, 0, len(this.AllocatedResources)) + for k := range this.AllocatedResources { + keysForAllocatedResources = append(keysForAllocatedResources, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAllocatedResources) + mapStringForAllocatedResources := "ResourceList{" + for _, k := range keysForAllocatedResources { + mapStringForAllocatedResources += fmt.Sprintf("%v: %v,", k, this.AllocatedResources[ResourceName(k)]) + } + mapStringForAllocatedResources += "}" s := strings.Join([]string{`&ContainerStatus{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `State:` + strings.Replace(strings.Replace(this.State.String(), "ContainerState", "ContainerState", 1), `&`, ``, 1) + `,`, @@ -24924,6 +25698,8 @@ func (this *ContainerStatus) String() string { `ImageID:` + fmt.Sprintf("%v", this.ImageID) + `,`, `ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`, `Started:` + valueToStringGenerated(this.Started) + `,`, + `AllocatedResources:` + mapStringForAllocatedResources + `,`, + `Resources:` + strings.Replace(this.Resources.String(), "ResourceRequirements", "ResourceRequirements", 1) + `,`, `}`, }, "") return s @@ -25155,6 +25931,11 @@ func (this *EphemeralContainerCommon) String() string { repeatedStringForVolumeDevices += strings.Replace(strings.Replace(f.String(), "VolumeDevice", "VolumeDevice", 1), `&`, ``, 1) + "," } repeatedStringForVolumeDevices += "}" + repeatedStringForResizePolicy := "[]ContainerResizePolicy{" + for _, f := range this.ResizePolicy { + repeatedStringForResizePolicy += strings.Replace(strings.Replace(f.String(), "ContainerResizePolicy", "ContainerResizePolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForResizePolicy += "}" s := strings.Join([]string{`&EphemeralContainerCommon{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Image:` + fmt.Sprintf("%v", this.Image) + `,`, @@ -25178,6 +25959,7 @@ func (this *EphemeralContainerCommon) String() string { `TerminationMessagePolicy:` + fmt.Sprintf("%v", this.TerminationMessagePolicy) + `,`, `VolumeDevices:` + repeatedStringForVolumeDevices + `,`, `StartupProbe:` + strings.Replace(this.StartupProbe.String(), "Probe", "Probe", 1) + `,`, + `ResizePolicy:` + repeatedStringForResizePolicy + `,`, `}`, }, "") return s @@ -26156,7 +26938,7 @@ func (this *PersistentVolumeClaimSpec) String() string { `StorageClassName:` + valueToStringGenerated(this.StorageClassName) + `,`, `VolumeMode:` + valueToStringGenerated(this.VolumeMode) + `,`, `DataSource:` + strings.Replace(this.DataSource.String(), "TypedLocalObjectReference", "TypedLocalObjectReference", 1) + `,`, - `DataSourceRef:` + strings.Replace(this.DataSourceRef.String(), "TypedLocalObjectReference", "TypedLocalObjectReference", 1) + `,`, + `DataSourceRef:` + strings.Replace(this.DataSourceRef.String(), "TypedObjectReference", "TypedObjectReference", 1) + `,`, `}`, }, "") return s @@ -26544,6 +27326,27 @@ func (this *PodReadinessGate) String() string { }, "") return s } +func (this *PodResourceClaim) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodResourceClaim{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ClaimSource", "ClaimSource", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *PodSchedulingGate) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodSchedulingGate{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *PodSecurityContext) String() string { if this == nil { return "nil" @@ -26627,6 +27430,16 @@ func (this *PodSpec) String() string { repeatedStringForEphemeralContainers += strings.Replace(strings.Replace(f.String(), "EphemeralContainer", "EphemeralContainer", 1), `&`, ``, 1) + "," } repeatedStringForEphemeralContainers += "}" + repeatedStringForSchedulingGates := "[]PodSchedulingGate{" + for _, f := range this.SchedulingGates { + repeatedStringForSchedulingGates += strings.Replace(strings.Replace(f.String(), "PodSchedulingGate", "PodSchedulingGate", 1), `&`, ``, 1) + "," + } + repeatedStringForSchedulingGates += "}" + repeatedStringForResourceClaims := "[]PodResourceClaim{" + for _, f := range this.ResourceClaims { + repeatedStringForResourceClaims += strings.Replace(strings.Replace(f.String(), "PodResourceClaim", "PodResourceClaim", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceClaims += "}" keysForNodeSelector := make([]string, 0, len(this.NodeSelector)) for k := range this.NodeSelector { keysForNodeSelector = append(keysForNodeSelector, k) @@ -26684,6 +27497,9 @@ func (this *PodSpec) String() string { `EphemeralContainers:` + repeatedStringForEphemeralContainers + `,`, `SetHostnameAsFQDN:` + valueToStringGenerated(this.SetHostnameAsFQDN) + `,`, `OS:` + strings.Replace(this.OS.String(), "PodOS", "PodOS", 1) + `,`, + `HostUsers:` + valueToStringGenerated(this.HostUsers) + `,`, + `SchedulingGates:` + repeatedStringForSchedulingGates + `,`, + `ResourceClaims:` + repeatedStringForResourceClaims + `,`, `}`, }, "") return s @@ -26731,6 +27547,7 @@ func (this *PodStatus) String() string { `NominatedNodeName:` + fmt.Sprintf("%v", this.NominatedNodeName) + `,`, `PodIPs:` + repeatedStringForPodIPs + `,`, `EphemeralContainerStatuses:` + repeatedStringForEphemeralContainerStatuses + `,`, + `Resize:` + fmt.Sprintf("%v", this.Resize) + `,`, `}`, }, "") return s @@ -27033,6 +27850,16 @@ func (this *ReplicationControllerStatus) String() string { }, "") return s } +func (this *ResourceClaim) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaim{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *ResourceFieldSelector) String() string { if this == nil { return "nil" @@ -27130,6 +27957,11 @@ func (this *ResourceRequirements) String() string { if this == nil { return "nil" } + repeatedStringForClaims := "[]ResourceClaim{" + for _, f := range this.Claims { + repeatedStringForClaims += strings.Replace(strings.Replace(f.String(), "ResourceClaim", "ResourceClaim", 1), `&`, ``, 1) + "," + } + repeatedStringForClaims += "}" keysForLimits := make([]string, 0, len(this.Limits)) for k := range this.Limits { keysForLimits = append(keysForLimits, string(k)) @@ -27153,6 +27985,7 @@ func (this *ResourceRequirements) String() string { s := strings.Join([]string{`&ResourceRequirements{`, `Limits:` + mapStringForLimits + `,`, `Requests:` + mapStringForRequests + `,`, + `Claims:` + repeatedStringForClaims + `,`, `}`, }, "") return s @@ -27681,6 +28514,9 @@ func (this *TopologySpreadConstraint) String() string { `WhenUnsatisfiable:` + fmt.Sprintf("%v", this.WhenUnsatisfiable) + `,`, `LabelSelector:` + strings.Replace(fmt.Sprintf("%v", this.LabelSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, `MinDomains:` + valueToStringGenerated(this.MinDomains) + `,`, + `NodeAffinityPolicy:` + valueToStringGenerated(this.NodeAffinityPolicy) + `,`, + `NodeTaintsPolicy:` + valueToStringGenerated(this.NodeTaintsPolicy) + `,`, + `MatchLabelKeys:` + fmt.Sprintf("%v", this.MatchLabelKeys) + `,`, `}`, }, "") return s @@ -27697,6 +28533,19 @@ func (this *TypedLocalObjectReference) String() string { }, "") return s } +func (this *TypedObjectReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TypedObjectReference{`, + `APIGroup:` + valueToStringGenerated(this.APIGroup) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + valueToStringGenerated(this.Namespace) + `,`, + `}`, + }, "") + return s +} func (this *Volume) String() string { if this == nil { return "nil" @@ -29416,6 +30265,42 @@ func (m *CSIPersistentVolumeSource) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeExpandSecretRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeExpandSecretRef == nil { + m.NodeExpandSecretRef = &SecretReference{} + } + if err := m.NodeExpandSecretRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -30658,7 +31543,7 @@ func (m *CinderVolumeSource) Unmarshal(dAtA []byte) error { } return nil } -func (m *ClientIPConfig) Unmarshal(dAtA []byte) error { +func (m *ClaimSource) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -30681,17 +31566,17 @@ func (m *ClientIPConfig) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ClientIPConfig: wiretype end group for non-group") + return fmt.Errorf("proto: ClaimSource: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ClientIPConfig: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ClaimSource: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TimeoutSeconds", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) } - var v int32 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -30701,12 +31586,128 @@ func (m *ClientIPConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.TimeoutSeconds = &v + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimName = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimTemplateName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimTemplateName = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClientIPConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClientIPConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClientIPConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutSeconds", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TimeoutSeconds = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -33090,6 +34091,40 @@ func (m *Container) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResizePolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResizePolicy = append(m.ResizePolicy, ContainerResizePolicy{}) + if err := m.ResizePolicy[len(m.ResizePolicy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -33396,7 +34431,7 @@ func (m *ContainerPort) Unmarshal(dAtA []byte) error { } return nil } -func (m *ContainerState) Unmarshal(dAtA []byte) error { +func (m *ContainerResizePolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -33419,17 +34454,17 @@ func (m *ContainerState) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ContainerState: wiretype end group for non-group") + return fmt.Errorf("proto: ContainerResizePolicy: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerState: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContainerResizePolicy: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Waiting", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -33439,69 +34474,29 @@ func (m *ContainerState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Waiting == nil { - m.Waiting = &ContainerStateWaiting{} - } - if err := m.Waiting.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ResourceName = ResourceName(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Running", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Running == nil { - m.Running = &ContainerStateRunning{} - } - if err := m.Running.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Terminated", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RestartPolicy", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -33511,27 +34506,23 @@ func (m *ContainerState) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Terminated == nil { - m.Terminated = &ContainerStateTerminated{} - } - if err := m.Terminated.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.RestartPolicy = ResourceResizeRestartPolicy(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -33554,7 +34545,7 @@ func (m *ContainerState) Unmarshal(dAtA []byte) error { } return nil } -func (m *ContainerStateRunning) Unmarshal(dAtA []byte) error { +func (m *ContainerState) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -33577,15 +34568,15 @@ func (m *ContainerStateRunning) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ContainerStateRunning: wiretype end group for non-group") + return fmt.Errorf("proto: ContainerState: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerStateRunning: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ContainerState: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StartedAt", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Waiting", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -33612,7 +34603,165 @@ func (m *ContainerStateRunning) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.StartedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Waiting == nil { + m.Waiting = &ContainerStateWaiting{} + } + if err := m.Waiting.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Running", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Running == nil { + m.Running = &ContainerStateRunning{} + } + if err := m.Running.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Terminated", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Terminated == nil { + m.Terminated = &ContainerStateTerminated{} + } + if err := m.Terminated.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContainerStateRunning) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContainerStateRunning: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContainerStateRunning: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StartedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.StartedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -34284,6 +35433,171 @@ func (m *ContainerStatus) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.Started = &b + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocatedResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AllocatedResources == nil { + m.AllocatedResources = make(ResourceList) + } + var mapkey ResourceName + mapvalue := &resource.Quantity{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = ResourceName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &resource.Quantity{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.AllocatedResources[ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Resources == nil { + m.Resources = &ResourceRequirements{} + } + if err := m.Resources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -36930,6 +38244,40 @@ func (m *EphemeralContainerCommon) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResizePolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResizePolicy = append(m.ResizePolicy, ContainerResizePolicy{}) + if err := m.ResizePolicy[len(m.ResizePolicy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -47965,7 +49313,7 @@ func (m *PersistentVolumeClaimSpec) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.DataSourceRef == nil { - m.DataSourceRef = &TypedLocalObjectReference{} + m.DataSourceRef = &TypedObjectReference{} } if err := m.DataSourceRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -52471,7 +53819,204 @@ func (m *PodProxyOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodReadinessGate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodReadinessGate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodReadinessGate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConditionType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConditionType = PodConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodResourceClaim) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodResourceClaim: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodResourceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -52494,7 +54039,7 @@ func (m *PodProxyOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodReadinessGate) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingGate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52517,15 +54062,15 @@ func (m *PodReadinessGate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodReadinessGate: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingGate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodReadinessGate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingGate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConditionType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52553,7 +54098,7 @@ func (m *PodReadinessGate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConditionType = PodConditionType(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -54337,6 +55882,95 @@ func (m *PodSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 37: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HostUsers", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.HostUsers = &b + case 38: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingGates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SchedulingGates = append(m.SchedulingGates, PodSchedulingGate{}) + if err := m.SchedulingGates[len(m.SchedulingGates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 39: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaims = append(m.ResourceClaims, PodResourceClaim{}) + if err := m.ResourceClaims[len(m.ResourceClaims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -54817,6 +56451,38 @@ func (m *PodStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resize", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resize = PodResizeStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -58315,6 +59981,88 @@ func (m *ReplicationControllerStatus) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceClaim) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaim: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ResourceFieldSelector) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -59570,6 +61318,40 @@ func (m *ResourceRequirements) Unmarshal(dAtA []byte) error { } m.Requests[ResourceName(mapkey)] = *mapvalue iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Claims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Claims = append(m.Claims, ResourceClaim{}) + if err := m.Claims[len(m.Claims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -63838,7 +65620,7 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ExternalTrafficPolicy = ServiceExternalTrafficPolicyType(dAtA[iNdEx:postIndex]) + m.ExternalTrafficPolicy = ServiceExternalTrafficPolicy(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 12: if wireType != 0 { @@ -63945,7 +65727,7 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := IPFamilyPolicyType(dAtA[iNdEx:postIndex]) + s := IPFamilyPolicy(dAtA[iNdEx:postIndex]) m.IPFamilyPolicy = &s iNdEx = postIndex case 18: @@ -64096,7 +65878,7 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := ServiceInternalTrafficPolicyType(dAtA[iNdEx:postIndex]) + s := ServiceInternalTrafficPolicy(dAtA[iNdEx:postIndex]) m.InternalTrafficPolicy = &s iNdEx = postIndex default: @@ -65702,6 +67484,104 @@ func (m *TopologySpreadConstraint) Unmarshal(dAtA []byte) error { } } m.MinDomains = &v + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeAffinityPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := NodeInclusionPolicy(dAtA[iNdEx:postIndex]) + m.NodeAffinityPolicy = &s + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeTaintsPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := NodeInclusionPolicy(dAtA[iNdEx:postIndex]) + m.NodeTaintsPolicy = &s + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchLabelKeys", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchLabelKeys = append(m.MatchLabelKeys, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -65870,6 +67750,186 @@ func (m *TypedLocalObjectReference) Unmarshal(dAtA []byte) error { } return nil } +func (m *TypedObjectReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TypedObjectReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TypedObjectReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.APIGroup = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Namespace = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Volume) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/core/v1/generated.proto b/vendor/k8s.io/api/core/v1/generated.proto index 41423f45f72..8ef67ca40bd 100644 --- a/vendor/k8s.io/api/core/v1/generated.proto +++ b/vendor/k8s.io/api/core/v1/generated.proto @@ -220,11 +220,20 @@ message CSIPersistentVolumeSource { // controllerExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // ControllerExpandVolume call. - // This is an alpha field and requires enabling ExpandCSIVolumes feature gate. // This field is optional, and may be empty if no secret is required. If the // secret object contains more than one secret, all secrets are passed. // +optional optional SecretReference controllerExpandSecretRef = 9; + + // nodeExpandSecretRef is a reference to the secret object containing + // sensitive information to pass to the CSI driver to complete the CSI + // NodeExpandVolume call. + // This is a beta field which is enabled default by CSINodeExpandSecret feature gate. + // This field is optional, may be omitted if no secret is required. If the + // secret object contains more than one secret, all secrets are passed. + // +featureGate=CSINodeExpandSecret + // +optional + optional SecretReference nodeExpandSecretRef = 10; } // Represents a source location of a volume to mount, managed by an external CSI driver @@ -391,6 +400,36 @@ message CinderVolumeSource { optional LocalObjectReference secretRef = 4; } +// ClaimSource describes a reference to a ResourceClaim. +// +// Exactly one of these fields should be set. Consumers of this type must +// treat an empty object as if it has an unknown value. +message ClaimSource { + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this pod. + optional string resourceClaimName = 1; + + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this pod. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this pod. When this pod is deleted, the ResourceClaim + // will also be deleted. The name of the ResourceClaim will be -, where is the + // PodResourceClaim.Name. Pod validation will reject the pod if the + // concatenated name is not valid for a ResourceClaim (e.g. too long). + // + // An existing ResourceClaim with that name that is not owned by the + // pod will not be used for the pod to avoid using an unrelated + // resource by mistake. Scheduling and pod startup are then blocked + // until the unrelated ResourceClaim is removed. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + optional string resourceClaimTemplateName = 2; +} + // ClientIPConfig represents the configurations of Client IP based session affinity. message ClientIPConfig { // timeoutSeconds specifies the seconds of ClientIP type session sticky time. @@ -647,12 +686,12 @@ message Container { // +optional optional string workingDir = 5; - // List of ports to expose from the container. Exposing a port here gives - // the system additional information about the network connections a - // container uses, but is primarily informational. Not specifying a port here + // List of ports to expose from the container. Not specifying a port here // DOES NOT prevent that port from being exposed. Any port which is // listening on the default "0.0.0.0" address inside a container will be // accessible from the network. + // Modifying this array with strategic merge patch may corrupt the data. + // For more information See https://github.com/kubernetes/kubernetes/issues/108255. // Cannot be updated. // +optional // +patchMergeKey=containerPort @@ -684,6 +723,12 @@ message Container { // +optional optional ResourceRequirements resources = 8; + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + repeated ContainerResizePolicy resizePolicy = 23; + // Pod volumes to mount into the container's filesystem. // Cannot be updated. // +optional @@ -785,7 +830,7 @@ message Container { // Describe a container image message ContainerImage { // Names by which this image is known. - // e.g. ["k8s.gcr.io/hyperkube:v1.0.7", "dockerhub.io/google_containers/hyperkube:v1.0.7"] + // e.g. ["kubernetes.example/hyperkube:v1.0.7", "cloud-vendor.registry.example/cloud-vendor/hyperkube:v1.0.7"] // +optional repeated string names = 1; @@ -824,6 +869,17 @@ message ContainerPort { optional string hostIP = 5; } +// ContainerResizePolicy represents resource resize policy for the container. +message ContainerResizePolicy { + // Name of the resource to which this resource resize policy applies. + // Supported values: cpu, memory. + optional string resourceName = 1; + + // Restart policy to apply when specified resource is resized. + // If not specified, it defaults to NotRequired. + optional string restartPolicy = 2; +} + // ContainerState holds a possible state of container. // Only one of its members may be specified. // If none of them is specified, the default one is ContainerStateWaiting. @@ -891,41 +947,76 @@ message ContainerStateWaiting { // ContainerStatus contains details for the current status of this container. message ContainerStatus { - // This must be a DNS_LABEL. Each container in a pod must have a unique name. + // Name is a DNS_LABEL representing the unique name of the container. + // Each container in a pod must have a unique name across all container types. // Cannot be updated. optional string name = 1; - // Details about the container's current condition. + // State holds details about the container's current condition. // +optional optional ContainerState state = 2; - // Details about the container's last termination condition. + // LastTerminationState holds the last termination state of the container to + // help debug container crashes and restarts. This field is not + // populated if the container is still running and RestartCount is 0. // +optional optional ContainerState lastState = 3; - // Specifies whether the container has passed its readiness probe. + // Ready specifies whether the container is currently passing its readiness check. + // The value will change as readiness probes keep executing. If no readiness + // probes are specified, this field defaults to true once the container is + // fully started (see Started field). + // + // The value is typically used to determine whether a container is ready to + // accept traffic. optional bool ready = 4; - // The number of times the container has been restarted. + // RestartCount holds the number of times the container has been restarted. + // Kubelet makes an effort to always increment the value, but there + // are cases when the state may be lost due to node restarts and then the value + // may be reset to 0. The value is never negative. optional int32 restartCount = 5; - // The image the container is running. + // Image is the name of container image that the container is running. + // The container image may not match the image used in the PodSpec, + // as it may have been resolved by the runtime. // More info: https://kubernetes.io/docs/concepts/containers/images. optional string image = 6; - // ImageID of the container's image. + // ImageID is the image ID of the container's image. The image ID may not + // match the image ID of the image used in the PodSpec, as it may have been + // resolved by the runtime. optional string imageID = 7; - // Container's ID in the format '://'. + // ContainerID is the ID of the container in the format '://'. + // Where type is a container runtime identifier, returned from Version call of CRI API + // (for example "containerd"). // +optional optional string containerID = 8; - // Specifies whether the container has passed its startup probe. - // Initialized as false, becomes true after startupProbe is considered successful. - // Resets to false when the container is restarted, or if kubelet loses state temporarily. - // Is always true when no startupProbe is defined. + // Started indicates whether the container has finished its postStart lifecycle hook + // and passed its startup probe. + // Initialized as false, becomes true after startupProbe is considered + // successful. Resets to false when the container is restarted, or if kubelet + // loses state temporarily. In both cases, startup probes will run again. + // Is always true when no startupProbe is defined and container is running and + // has passed the postStart lifecycle hook. The null value must be treated the + // same as false. // +optional optional bool started = 9; + + // AllocatedResources represents the compute resources allocated for this container by the + // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission + // and after successfully admitting desired pod resize. + // +featureGate=InPlacePodVerticalScaling + // +optional + map allocatedResources = 10; + + // Resources represents the compute resource requests and limits that have been successfully + // enacted on the running container after it has been started or has been successfully resized. + // +featureGate=InPlacePodVerticalScaling + // +optional + optional ResourceRequirements resources = 11; } // DaemonEndpoint contains information about a single Daemon endpoint. @@ -1001,7 +1092,7 @@ message EmptyDirVolumeSource { // The maximum usage on memory medium EmptyDir would be the minimum value between // the SizeLimit specified here and the sum of memory limits of all containers in a pod. // The default is nil which means that the limit is undefined. - // More info: http://kubernetes.io/docs/user-guide/volumes#emptydir + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity sizeLimit = 2; } @@ -1010,11 +1101,8 @@ message EmptyDirVolumeSource { // +structType=atomic message EndpointAddress { // The IP of this endpoint. - // May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), - // or link-local multicast ((224.0.0.0/24). - // IPv6 is also accepted but not fully supported on all platforms. Also, certain - // kubernetes components, like kube-proxy, are not IPv6 ready. - // TODO: This should allow hostname or IP, See #4447. + // May not be loopback (127.0.0.0/8 or ::1), link-local (169.254.0.0/16 or fe80::/10), + // or link-local multicast (224.0.0.0/24 or ff02::/16). optional string ip = 1; // The Hostname of this endpoint @@ -1050,10 +1138,17 @@ message EndpointPort { optional string protocol = 3; // The application protocol for this port. + // This is used as a hint for implementations to offer richer behavior for protocols that they understand. // This field follows standard Kubernetes label syntax. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional optional string appProtocol = 4; @@ -1062,13 +1157,16 @@ message EndpointPort { // EndpointSubset is a group of addresses with a common set of ports. The // expanded set of endpoints is the Cartesian product of Addresses x Ports. // For example, given: -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// } +// +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// } +// // The resulting set of endpoints can be viewed as: -// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], -// b: [ 10.10.1.1:309, 10.10.2.2:309 ] +// +// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], +// b: [ 10.10.1.1:309, 10.10.2.2:309 ] message EndpointSubset { // IP addresses which offer the related ports that are marked as ready. These endpoints // should be considered safe for load balancers and clients to utilize. @@ -1087,17 +1185,18 @@ message EndpointSubset { } // Endpoints is a collection of endpoints that implement the actual service. Example: -// Name: "mysvc", -// Subsets: [ -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// }, -// { -// Addresses: [{"ip": "10.10.3.3"}], -// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] -// }, -// ] +// +// Name: "mysvc", +// Subsets: [ +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// }, +// { +// Addresses: [{"ip": "10.10.3.3"}], +// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] +// }, +// ] message Endpoints { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata @@ -1192,8 +1291,6 @@ message EnvVarSource { // // To add an ephemeral container, use the ephemeralcontainers subresource of an existing // Pod. Ephemeral containers may not be removed or restarted. -// -// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate. message EphemeralContainer { // Ephemeral containers have all of the fields of Container, plus additional fields // specific to ephemeral containers. Fields in common with Container are in the @@ -1283,6 +1380,12 @@ message EphemeralContainerCommon { // +optional optional ResourceRequirements resources = 8; + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + repeated ContainerResizePolicy resizePolicy = 23; + // Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. // Cannot be updated. // +optional @@ -1750,7 +1853,8 @@ message HTTPGetAction { // HTTPHeader describes a custom header to be used in HTTP probes message HTTPHeader { - // The header field name + // The header field name. + // This will be canonicalized upon output, so case-variant names will be understood as the same header. optional string name = 1; // The header field value @@ -2402,7 +2506,7 @@ message NodeSpec { // +optional repeated Taint taints = 5; - // Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed from Kubelets as of 1.24 and will be fully removed in 1.26. + // Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed. // +optional optional NodeConfigSource configSource = 6; @@ -2442,7 +2546,11 @@ message NodeStatus { // More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses // Note: This field is declared as mergeable, but the merge key is not sufficiently // unique, which can cause data corruption when it is merged. Callers should instead - // use a full-replacement patch. See http://pr.k8s.io/79391 for an example. + // use a full-replacement patch. See https://pr.k8s.io/79391 for an example. + // Consumers should assume that addresses can change during the + // lifetime of a Node. However, there are some exceptions where this may not + // be possible, such as Pods that inherit a Node's address in its own status or + // consumers of the downward API (status.hostIP). // +optional // +patchMergeKey=type // +patchStrategy=merge @@ -2535,6 +2643,7 @@ message ObjectFieldSelector { // and the version of the actual struct is irrelevant. // 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type // will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. +// // Instead of using this type, create a locally provided and used type that is well-focused on your reference. // For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -2623,7 +2732,7 @@ message PersistentVolumeClaim { optional PersistentVolumeClaimStatus status = 3; } -// PersistentVolumeClaimCondition contails details about state of pvc +// PersistentVolumeClaimCondition contains details about state of pvc message PersistentVolumeClaimCondition { optional string type = 1; @@ -2699,30 +2808,37 @@ message PersistentVolumeClaimSpec { // * An existing PVC (PersistentVolumeClaim) // If the provisioner or an external controller can support the specified data source, // it will create a new volume based on the contents of the specified data source. - // If the AnyVolumeDataSource feature gate is enabled, this field will always have - // the same contents as the DataSourceRef field. + // When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + // and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + // If the namespace is specified, then dataSourceRef will not be copied to dataSource. // +optional optional TypedLocalObjectReference dataSource = 7; // dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - // volume is desired. This may be any local object from a non-empty API group (non + // volume is desired. This may be any object from a non-empty API group (non // core object) or a PersistentVolumeClaim object. // When this field is specified, volume binding will only succeed if the type of // the specified object matches some installed volume populator or dynamic // provisioner. - // This field will replace the functionality of the DataSource field and as such + // This field will replace the functionality of the dataSource field and as such // if both fields are non-empty, they must have the same value. For backwards - // compatibility, both fields (DataSource and DataSourceRef) will be set to the same + // compatibility, when namespace isn't specified in dataSourceRef, + // both fields (dataSource and dataSourceRef) will be set to the same // value automatically if one of them is empty and the other is non-empty. - // There are two important differences between DataSource and DataSourceRef: - // * While DataSource only allows two specific types of objects, DataSourceRef + // When namespace is specified in dataSourceRef, + // dataSource isn't set to the same value and must be empty. + // There are three important differences between dataSource and dataSourceRef: + // * While dataSource only allows two specific types of objects, dataSourceRef // allows any non-core object, as well as PersistentVolumeClaim objects. - // * While DataSource ignores disallowed values (dropping them), DataSourceRef + // * While dataSource ignores disallowed values (dropping them), dataSourceRef // preserves all values, and generates an error if a disallowed value is // specified. + // * While dataSource only allows local objects, dataSourceRef allows objects + // in any namespaces. // (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + // (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. // +optional - optional TypedLocalObjectReference dataSourceRef = 8; + optional TypedObjectReference dataSourceRef = 8; } // PersistentVolumeClaimStatus is the current status of a persistent volume claim. @@ -2939,6 +3055,7 @@ message PersistentVolumeSpec { // claim.VolumeName is the authoritative bind between PV and PVC. // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#binding // +optional + // +structType=granular optional ObjectReference claimRef = 4; // persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim. @@ -3232,7 +3349,8 @@ message PodExecOptions { // IP address information for entries in the (plural) PodIPs field. // Each entry includes: -// IP: An IP address allocated to the pod. Routable at least within the cluster. +// +// IP: An IP address allocated to the pod. Routable at least within the cluster. message PodIP { // ip is an IP address (IPv4 or IPv6) assigned to the pod optional string ip = 1; @@ -3339,6 +3457,25 @@ message PodReadinessGate { optional string conditionType = 1; } +// PodResourceClaim references exactly one ResourceClaim through a ClaimSource. +// It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. +// Containers that need access to the ResourceClaim reference it with this name. +message PodResourceClaim { + // Name uniquely identifies this resource claim inside the pod. + // This must be a DNS_LABEL. + optional string name = 1; + + // Source describes where to find the ResourceClaim. + optional ClaimSource source = 2; +} + +// PodSchedulingGate is associated to a Pod to guard its scheduling. +message PodSchedulingGate { + // Name of the scheduling gate. + // Each scheduling gate must have a unique name field. + optional string name = 1; +} + // PodSecurityContext holds pod-level security attributes and common container settings. // Some fields are also present in container.securityContext. Field values of // container.securityContext take precedence over field values of PodSecurityContext. @@ -3387,8 +3524,11 @@ message PodSecurityContext { optional bool runAsNonRoot = 3; // A list of groups applied to the first process run in each container, in addition - // to the container's primary GID. If unspecified, no groups will be added to - // any container. + // to the container's primary GID, the fsGroup (if specified), and group memberships + // defined in the container image for the uid of the container process. If unspecified, + // no additional groups are added to any container. Note that group memberships + // defined in the container image for the uid of the container process are still effective, + // even if they are not included in this list. // Note that this field cannot be set when spec.os.name is windows. // +optional repeated int64 supplementalGroups = 4; @@ -3474,14 +3614,13 @@ message PodSpec { // pod to perform user-initiated actions such as debugging. This list cannot be specified when // creating a pod, and it cannot be modified by updating the pod spec. In order to add an // ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional // +patchMergeKey=name // +patchStrategy=merge repeated EphemeralContainer ephemeralContainers = 34; // Restart policy for all containers within the pod. - // One of Always, OnFailure, Never. + // One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. // Default to Always. // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy // +optional @@ -3700,6 +3839,7 @@ message PodSpec { // If the OS field is set to windows, following fields must be unset: // - spec.hostPID // - spec.hostIPC + // - spec.hostUsers // - spec.securityContext.seLinuxOptions // - spec.securityContext.seccompProfile // - spec.securityContext.fsGroup @@ -3719,8 +3859,54 @@ message PodSpec { // - spec.containers[*].securityContext.runAsUser // - spec.containers[*].securityContext.runAsGroup // +optional - // This is a beta field and requires the IdentifyPodOS feature optional PodOS os = 36; + + // Use the host's user namespace. + // Optional: Default to true. + // If set to true or not present, the pod will be run in the host user namespace, useful + // for when the pod needs a feature only available to the host user namespace, such as + // loading a kernel module with CAP_SYS_MODULE. + // When set to false, a new userns is created for the pod. Setting false is useful for + // mitigating container breakout vulnerabilities even allowing users to run their + // containers as root without actually having root privileges on the host. + // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + // +k8s:conversion-gen=false + // +optional + optional bool hostUsers = 37; + + // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + // scheduler will not attempt to schedule the pod. + // + // SchedulingGates can only be set at pod creation time, and be removed only afterwards. + // + // This is a beta feature enabled by the PodSchedulingReadiness feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=PodSchedulingReadiness + // +optional + repeated PodSchedulingGate schedulingGates = 38; + + // ResourceClaims defines which ResourceClaims must be allocated + // and reserved before the Pod is allowed to start. The resources + // will be made available to those containers which consume them + // by name. + // + // This is an alpha field and requires enabling the + // DynamicResourceAllocation feature gate. + // + // This field is immutable. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +featureGate=DynamicResourceAllocation + // +optional + repeated PodResourceClaim resourceClaims = 39; } // PodStatus represents information about the status of a pod. Status may trail the actual @@ -3809,14 +3995,20 @@ message PodStatus { // The Quality of Service (QOS) classification assigned to the pod based on resource requirements // See PodQOSClass type for available QOS classes - // More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes // +optional optional string qosClass = 9; // Status for any ephemeral containers that have run in this pod. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional repeated ContainerStatus ephemeralContainerStatuses = 13; + + // Status of resources resize desired for pod's containers. + // It is empty if no resources resize is pending. + // Any changes to container resources will automatically set this to "Proposed" + // +featureGate=InPlacePodVerticalScaling + // +optional + optional string resize = 14; } // PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded @@ -4009,8 +4201,6 @@ message ProbeHandler { optional TCPSocketAction tcpSocket = 3; // GRPC specifies an action involving a GRPC port. - // This is a beta field and requires enabling GRPCContainerProbe feature gate. - // +featureGate=GRPCContainerProbe // +optional optional GRPCAction grpc = 4; } @@ -4260,6 +4450,7 @@ message ReplicationControllerSpec { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. This takes precedence over a TemplateRef. + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template // +optional optional PodTemplateSpec template = 3; @@ -4268,7 +4459,7 @@ message ReplicationControllerSpec { // ReplicationControllerStatus represents the current status of a replication // controller. message ReplicationControllerStatus { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller optional int32 replicas = 1; @@ -4295,6 +4486,14 @@ message ReplicationControllerStatus { repeated ReplicationControllerCondition conditions = 6; } +// ResourceClaim references one entry in PodSpec.ResourceClaims. +message ResourceClaim { + // Name must match the name of one entry in pod.spec.resourceClaims of + // the Pod where this field is used. It makes that resource available + // inside a container. + optional string name = 1; +} + // ResourceFieldSelector represents container resources (cpu, memory) and their output format // +structType=atomic message ResourceFieldSelector { @@ -4380,10 +4579,24 @@ message ResourceRequirements { // Requests describes the minimum amount of compute resources required. // If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - // otherwise to an implementation-defined value. + // otherwise to an implementation-defined value. Requests cannot exceed Limits. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional map requests = 2; + + // Claims lists the names of resources, defined in spec.resourceClaims, + // that are used by this container. + // + // This is an alpha field and requires enabling the + // DynamicResourceAllocation feature gate. + // + // This field is immutable. It can only be set for containers. + // + // +listType=map + // +listMapKey=name + // +featureGate=DynamicResourceAllocation + // +optional + repeated ResourceClaim claims = 3; } // SELinuxOptions are the labels to be applied to the container @@ -5083,12 +5296,19 @@ message ServiceSpec { // +optional optional string externalName = 10; - // externalTrafficPolicy denotes if this Service desires to route external - // traffic to node-local or cluster-wide endpoints. "Local" preserves the - // client source IP and avoids a second hop for LoadBalancer and Nodeport - // type services, but risks potentially imbalanced traffic spreading. - // "Cluster" obscures the client source IP and may cause a second hop to - // another node, but should have good overall load-spreading. + // externalTrafficPolicy describes how nodes distribute service traffic they + // receive on one of the Service's "externally-facing" addresses (NodePorts, + // ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + // the service in a way that assumes that external load balancers will take care + // of balancing the service traffic between nodes, and so each node will deliver + // traffic only to the node-local endpoints of the service, without masquerading + // the client source IP. (Traffic mistakenly sent to a node with no endpoints will + // be dropped.) The default value, "Cluster", uses the standard behavior of + // routing to all endpoints evenly (possibly modified by topology and other + // features). Note that traffic sent to an External IP or LoadBalancer IP from + // within the cluster will always get "Cluster" semantics, but clients sending to + // a NodePort from within the cluster may need to take traffic policy into account + // when picking a node. // +optional optional string externalTrafficPolicy = 11; @@ -5101,6 +5321,7 @@ message ServiceSpec { // service or not. If this field is specified when creating a Service // which does not need it, creation will fail. This field will be wiped // when updating a Service to no longer need it (e.g. changing type). + // This field cannot be updated once set. // +optional optional int32 healthCheckNodePort = 12; @@ -5170,17 +5391,15 @@ message ServiceSpec { // implementation (e.g. cloud providers) should ignore Services that set this field. // This field can only be set when creating or updating a Service to type 'LoadBalancer'. // Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. - // +featureGate=LoadBalancerClass // +optional optional string loadBalancerClass = 21; - // InternalTrafficPolicy specifies if the cluster internal traffic - // should be routed to all endpoints or node-local endpoints only. - // "Cluster" routes internal traffic to a Service to all endpoints. - // "Local" routes traffic to node-local endpoints only, traffic is - // dropped if no node-local endpoints are ready. - // The default value is "Cluster". - // +featureGate=ServiceInternalTrafficPolicy + // InternalTrafficPolicy describes how nodes distribute service traffic they + // receive on the ClusterIP. If set to "Local", the proxy will assume that pods + // only want to talk to endpoints of the service on the same node as the pod, + // dropping the traffic if there are no local endpoints. The default value, + // "Cluster", uses the standard behavior of routing to all endpoints evenly + // (possibly modified by topology and other features). // +optional optional string internalTrafficPolicy = 22; } @@ -5399,7 +5618,8 @@ message TopologySpreadConstraint { // We consider each as a "bucket", and try to put balanced number // of pods into each bucket. // We define a domain as a particular instance of a topology. - // Also, we define an eligible domain as a domain whose nodes match the node selector. + // Also, we define an eligible domain as a domain whose nodes meet the requirements of + // nodeAffinityPolicy and nodeTaintsPolicy. // e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. // And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. // It's a required field. @@ -5457,9 +5677,44 @@ message TopologySpreadConstraint { // because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, // it will violate MaxSkew. // - // This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate. + // This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). // +optional optional int32 minDomains = 5; + + // NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + // when calculating pod topology spread skew. Options are: + // - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + // - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + // + // If this value is nil, the behavior is equivalent to the Honor policy. + // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + // +optional + optional string nodeAffinityPolicy = 6; + + // NodeTaintsPolicy indicates how we will treat node taints when calculating + // pod topology spread skew. Options are: + // - Honor: nodes without taints, along with tainted nodes for which the incoming pod + // has a toleration, are included. + // - Ignore: node taints are ignored. All nodes are included. + // + // If this value is nil, the behavior is equivalent to the Ignore policy. + // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + // +optional + optional string nodeTaintsPolicy = 7; + + // MatchLabelKeys is a set of pod label keys to select the pods over which + // spreading will be calculated. The keys are used to lookup values from the + // incoming pod labels, those key-value labels are ANDed with labelSelector + // to select the group of existing pods over which spreading will be calculated + // for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + // MatchLabelKeys cannot be set when LabelSelector isn't set. + // Keys that don't exist in the incoming pod labels will + // be ignored. A null or empty list means only match against labelSelector. + // + // This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + // +listType=atomic + // +optional + repeated string matchLabelKeys = 8; } // TypedLocalObjectReference contains enough information to let you locate the @@ -5479,6 +5734,27 @@ message TypedLocalObjectReference { optional string name = 3; } +message TypedObjectReference { + // APIGroup is the group for the resource being referenced. + // If APIGroup is not specified, the specified Kind must be in the core API group. + // For any other third-party types, APIGroup is required. + // +optional + optional string apiGroup = 1; + + // Kind is the type of resource being referenced + optional string kind = 2; + + // Name is the name of resource being referenced + optional string name = 3; + + // Namespace is the namespace of resource being referenced + // Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + // (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + // +featureGate=CrossNamespaceVolumeDataSource + // +optional + optional string namespace = 4; +} + // Volume represents a named volume in a pod that may be accessed by any container in the pod. message Volume { // name of the volume. diff --git a/vendor/k8s.io/api/core/v1/toleration.go b/vendor/k8s.io/api/core/v1/toleration.go index b203d335b6b..e803d518b5c 100644 --- a/vendor/k8s.io/api/core/v1/toleration.go +++ b/vendor/k8s.io/api/core/v1/toleration.go @@ -28,10 +28,11 @@ func (t *Toleration) MatchToleration(tolerationToMatch *Toleration) bool { // ToleratesTaint checks if the toleration tolerates the taint. // The matching follows the rules below: -// (1) Empty toleration.effect means to match all taint effects, +// +// 1. Empty toleration.effect means to match all taint effects, // otherwise taint effect must equal to toleration.effect. -// (2) If toleration.operator is 'Exists', it means to match all taint values. -// (3) Empty toleration.key means to match all taint keys. +// 2. If toleration.operator is 'Exists', it means to match all taint values. +// 3. Empty toleration.key means to match all taint keys. // If toleration.key is empty, toleration.operator must be 'Exists'; // this combination means to match all taint values and all taint keys. func (t *Toleration) ToleratesTaint(taint *Taint) bool { diff --git a/vendor/k8s.io/api/core/v1/types.go b/vendor/k8s.io/api/core/v1/types.go index c2a3c67b205..c831d5961cf 100644 --- a/vendor/k8s.io/api/core/v1/types.go +++ b/vendor/k8s.io/api/core/v1/types.go @@ -337,6 +337,7 @@ type PersistentVolumeSpec struct { // claim.VolumeName is the authoritative bind between PV and PVC. // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#binding // +optional + // +structType=granular ClaimRef *ObjectReference `json:"claimRef,omitempty" protobuf:"bytes,4,opt,name=claimRef"` // persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim. // Valid options are Retain (default for manually created PersistentVolumes), Delete (default @@ -496,29 +497,54 @@ type PersistentVolumeClaimSpec struct { // * An existing PVC (PersistentVolumeClaim) // If the provisioner or an external controller can support the specified data source, // it will create a new volume based on the contents of the specified data source. - // If the AnyVolumeDataSource feature gate is enabled, this field will always have - // the same contents as the DataSourceRef field. + // When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + // and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + // If the namespace is specified, then dataSourceRef will not be copied to dataSource. // +optional DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" protobuf:"bytes,7,opt,name=dataSource"` // dataSourceRef specifies the object from which to populate the volume with data, if a non-empty - // volume is desired. This may be any local object from a non-empty API group (non + // volume is desired. This may be any object from a non-empty API group (non // core object) or a PersistentVolumeClaim object. // When this field is specified, volume binding will only succeed if the type of // the specified object matches some installed volume populator or dynamic // provisioner. - // This field will replace the functionality of the DataSource field and as such + // This field will replace the functionality of the dataSource field and as such // if both fields are non-empty, they must have the same value. For backwards - // compatibility, both fields (DataSource and DataSourceRef) will be set to the same + // compatibility, when namespace isn't specified in dataSourceRef, + // both fields (dataSource and dataSourceRef) will be set to the same // value automatically if one of them is empty and the other is non-empty. - // There are two important differences between DataSource and DataSourceRef: - // * While DataSource only allows two specific types of objects, DataSourceRef + // When namespace is specified in dataSourceRef, + // dataSource isn't set to the same value and must be empty. + // There are three important differences between dataSource and dataSourceRef: + // * While dataSource only allows two specific types of objects, dataSourceRef // allows any non-core object, as well as PersistentVolumeClaim objects. - // * While DataSource ignores disallowed values (dropping them), DataSourceRef + // * While dataSource ignores disallowed values (dropping them), dataSourceRef // preserves all values, and generates an error if a disallowed value is // specified. + // * While dataSource only allows local objects, dataSourceRef allows objects + // in any namespaces. // (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + // (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. // +optional - DataSourceRef *TypedLocalObjectReference `json:"dataSourceRef,omitempty" protobuf:"bytes,8,opt,name=dataSourceRef"` + DataSourceRef *TypedObjectReference `json:"dataSourceRef,omitempty" protobuf:"bytes,8,opt,name=dataSourceRef"` +} + +type TypedObjectReference struct { + // APIGroup is the group for the resource being referenced. + // If APIGroup is not specified, the specified Kind must be in the core API group. + // For any other third-party types, APIGroup is required. + // +optional + APIGroup *string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` + // Kind is the type of resource being referenced + Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` + // Name is the name of resource being referenced + Name string `json:"name" protobuf:"bytes,3,opt,name=name"` + // Namespace is the namespace of resource being referenced + // Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + // (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + // +featureGate=CrossNamespaceVolumeDataSource + // +optional + Namespace *string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` } // PersistentVolumeClaimConditionType is a valid value of PersistentVolumeClaimCondition.Type @@ -551,7 +577,7 @@ const ( PersistentVolumeClaimNodeExpansionFailed PersistentVolumeClaimResizeStatus = "NodeExpansionFailed" ) -// PersistentVolumeClaimCondition contails details about state of pvc +// PersistentVolumeClaimCondition contains details about state of pvc type PersistentVolumeClaimCondition struct { Type PersistentVolumeClaimConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=PersistentVolumeClaimConditionType"` Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=ConditionStatus"` @@ -709,7 +735,7 @@ type EmptyDirVolumeSource struct { // The maximum usage on memory medium EmptyDir would be the minimum value between // the SizeLimit specified here and the sum of memory limits of all containers in a pod. // The default is nil which means that the limit is undefined. - // More info: http://kubernetes.io/docs/user-guide/volumes#emptydir + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir // +optional SizeLimit *resource.Quantity `json:"sizeLimit,omitempty" protobuf:"bytes,2,opt,name=sizeLimit"` } @@ -1662,7 +1688,7 @@ type ServiceAccountTokenProjection struct { // must identify itself with an identifier specified in the audience of the // token, and otherwise should reject the token. The audience defaults to the // identifier of the apiserver. - //+optional + // +optional Audience string `json:"audience,omitempty" protobuf:"bytes,1,rep,name=audience"` // expirationSeconds is the requested duration of validity of the service // account token. As the token approaches expiration, the kubelet volume @@ -1670,7 +1696,7 @@ type ServiceAccountTokenProjection struct { // start trying to rotate the token if the token is older than 80 percent of // its time to live or if the token is older than 24 hours.Defaults to 1 hour // and must be at least 10 minutes. - //+optional + // +optional ExpirationSeconds *int64 `json:"expirationSeconds,omitempty" protobuf:"varint,2,opt,name=expirationSeconds"` // path is the path relative to the mount point of the file to project the // token into. @@ -1800,11 +1826,20 @@ type CSIPersistentVolumeSource struct { // controllerExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // ControllerExpandVolume call. - // This is an alpha field and requires enabling ExpandCSIVolumes feature gate. // This field is optional, and may be empty if no secret is required. If the // secret object contains more than one secret, all secrets are passed. // +optional ControllerExpandSecretRef *SecretReference `json:"controllerExpandSecretRef,omitempty" protobuf:"bytes,9,opt,name=controllerExpandSecretRef"` + + // nodeExpandSecretRef is a reference to the secret object containing + // sensitive information to pass to the CSI driver to complete the CSI + // NodeExpandVolume call. + // This is a beta field which is enabled default by CSINodeExpandSecret feature gate. + // This field is optional, may be omitted if no secret is required. If the + // secret object contains more than one secret, all secrets are passed. + // +featureGate=CSINodeExpandSecret + // +optional + NodeExpandSecretRef *SecretReference `json:"nodeExpandSecretRef,omitempty" protobuf:"bytes,10,opt,name=nodeExpandSecretRef"` } // Represents a source location of a volume to mount, managed by an external CSI driver @@ -2102,7 +2137,8 @@ type SecretEnvSource struct { // HTTPHeader describes a custom header to be used in HTTP probes type HTTPHeader struct { - // The header field name + // The header field name. + // This will be canonicalized upon output, so case-variant names will be understood as the same header. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` // The header field value Value string `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -2229,6 +2265,33 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// ResourceResizeRestartPolicy specifies how to handle container resource resize. +type ResourceResizeRestartPolicy string + +// These are the valid resource resize restart policy values: +const ( + // 'NotRequired' means Kubernetes will try to resize the container + // without restarting it, if possible. Kubernetes may however choose to + // restart the container if it is unable to actuate resize without a + // restart. For e.g. the runtime doesn't support restart-free resizing. + NotRequired ResourceResizeRestartPolicy = "NotRequired" + // 'RestartContainer' means Kubernetes will resize the container in-place + // by stopping and starting the container when new resources are applied. + // This is needed for legacy applications. For e.g. java apps using the + // -xmxN flag which are unable to use resized memory without restarting. + RestartContainer ResourceResizeRestartPolicy = "RestartContainer" +) + +// ContainerResizePolicy represents resource resize policy for the container. +type ContainerResizePolicy struct { + // Name of the resource to which this resource resize policy applies. + // Supported values: cpu, memory. + ResourceName ResourceName `json:"resourceName" protobuf:"bytes,1,opt,name=resourceName,casttype=ResourceName"` + // Restart policy to apply when specified resource is resized. + // If not specified, it defaults to NotRequired. + RestartPolicy ResourceResizeRestartPolicy `json:"restartPolicy" protobuf:"bytes,2,opt,name=restartPolicy,casttype=ResourceResizeRestartPolicy"` +} + // PreemptionPolicy describes a policy for if/when to preempt a pod. // +enum type PreemptionPolicy string @@ -2275,10 +2338,31 @@ type ResourceRequirements struct { Limits ResourceList `json:"limits,omitempty" protobuf:"bytes,1,rep,name=limits,casttype=ResourceList,castkey=ResourceName"` // Requests describes the minimum amount of compute resources required. // If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - // otherwise to an implementation-defined value. + // otherwise to an implementation-defined value. Requests cannot exceed Limits. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional Requests ResourceList `json:"requests,omitempty" protobuf:"bytes,2,rep,name=requests,casttype=ResourceList,castkey=ResourceName"` + // Claims lists the names of resources, defined in spec.resourceClaims, + // that are used by this container. + // + // This is an alpha field and requires enabling the + // DynamicResourceAllocation feature gate. + // + // This field is immutable. It can only be set for containers. + // + // +listType=map + // +listMapKey=name + // +featureGate=DynamicResourceAllocation + // +optional + Claims []ResourceClaim `json:"claims,omitempty" protobuf:"bytes,3,opt,name=claims"` +} + +// ResourceClaim references one entry in PodSpec.ResourceClaims. +type ResourceClaim struct { + // Name must match the name of one entry in pod.spec.resourceClaims of + // the Pod where this field is used. It makes that resource available + // inside a container. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` } const ( @@ -2324,12 +2408,12 @@ type Container struct { // Cannot be updated. // +optional WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` - // List of ports to expose from the container. Exposing a port here gives - // the system additional information about the network connections a - // container uses, but is primarily informational. Not specifying a port here + // List of ports to expose from the container. Not specifying a port here // DOES NOT prevent that port from being exposed. Any port which is // listening on the default "0.0.0.0" address inside a container will be // accessible from the network. + // Modifying this array with strategic merge patch may corrupt the data. + // For more information See https://github.com/kubernetes/kubernetes/issues/108255. // Cannot be updated. // +optional // +patchMergeKey=containerPort @@ -2357,6 +2441,11 @@ type Container struct { // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional Resources ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" protobuf:"bytes,23,rep,name=resizePolicy"` // Pod volumes to mount into the container's filesystem. // Cannot be updated. // +optional @@ -2461,8 +2550,6 @@ type ProbeHandler struct { TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" protobuf:"bytes,3,opt,name=tcpSocket"` // GRPC specifies an action involving a GRPC port. - // This is a beta field and requires enabling GRPCContainerProbe feature gate. - // +featureGate=GRPCContainerProbe // +optional GRPC *GRPCAction `json:"grpc,omitempty" protobuf:"bytes,4,opt,name=grpc"` } @@ -2576,33 +2663,66 @@ type ContainerState struct { // ContainerStatus contains details for the current status of this container. type ContainerStatus struct { - // This must be a DNS_LABEL. Each container in a pod must have a unique name. + // Name is a DNS_LABEL representing the unique name of the container. + // Each container in a pod must have a unique name across all container types. // Cannot be updated. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Details about the container's current condition. + // State holds details about the container's current condition. // +optional State ContainerState `json:"state,omitempty" protobuf:"bytes,2,opt,name=state"` - // Details about the container's last termination condition. + // LastTerminationState holds the last termination state of the container to + // help debug container crashes and restarts. This field is not + // populated if the container is still running and RestartCount is 0. // +optional LastTerminationState ContainerState `json:"lastState,omitempty" protobuf:"bytes,3,opt,name=lastState"` - // Specifies whether the container has passed its readiness probe. + // Ready specifies whether the container is currently passing its readiness check. + // The value will change as readiness probes keep executing. If no readiness + // probes are specified, this field defaults to true once the container is + // fully started (see Started field). + // + // The value is typically used to determine whether a container is ready to + // accept traffic. Ready bool `json:"ready" protobuf:"varint,4,opt,name=ready"` - // The number of times the container has been restarted. + // RestartCount holds the number of times the container has been restarted. + // Kubelet makes an effort to always increment the value, but there + // are cases when the state may be lost due to node restarts and then the value + // may be reset to 0. The value is never negative. RestartCount int32 `json:"restartCount" protobuf:"varint,5,opt,name=restartCount"` - // The image the container is running. + // Image is the name of container image that the container is running. + // The container image may not match the image used in the PodSpec, + // as it may have been resolved by the runtime. // More info: https://kubernetes.io/docs/concepts/containers/images. Image string `json:"image" protobuf:"bytes,6,opt,name=image"` - // ImageID of the container's image. + // ImageID is the image ID of the container's image. The image ID may not + // match the image ID of the image used in the PodSpec, as it may have been + // resolved by the runtime. ImageID string `json:"imageID" protobuf:"bytes,7,opt,name=imageID"` - // Container's ID in the format '://'. + // ContainerID is the ID of the container in the format '://'. + // Where type is a container runtime identifier, returned from Version call of CRI API + // (for example "containerd"). // +optional ContainerID string `json:"containerID,omitempty" protobuf:"bytes,8,opt,name=containerID"` - // Specifies whether the container has passed its startup probe. - // Initialized as false, becomes true after startupProbe is considered successful. - // Resets to false when the container is restarted, or if kubelet loses state temporarily. - // Is always true when no startupProbe is defined. + // Started indicates whether the container has finished its postStart lifecycle hook + // and passed its startup probe. + // Initialized as false, becomes true after startupProbe is considered + // successful. Resets to false when the container is restarted, or if kubelet + // loses state temporarily. In both cases, startup probes will run again. + // Is always true when no startupProbe is defined and container is running and + // has passed the postStart lifecycle hook. The null value must be treated the + // same as false. // +optional Started *bool `json:"started,omitempty" protobuf:"varint,9,opt,name=started"` + // AllocatedResources represents the compute resources allocated for this container by the + // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission + // and after successfully admitting desired pod resize. + // +featureGate=InPlacePodVerticalScaling + // +optional + AllocatedResources ResourceList `json:"allocatedResources,omitempty" protobuf:"bytes,10,rep,name=allocatedResources,casttype=ResourceList,castkey=ResourceName"` + // Resources represents the compute resource requests and limits that have been successfully + // enacted on the running container after it has been started or has been successfully resized. + // +featureGate=InPlacePodVerticalScaling + // +optional + Resources *ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,11,opt,name=resources"` } // PodPhase is a label for the condition of a pod at the current time. @@ -2644,6 +2764,9 @@ const ( PodReady PodConditionType = "Ready" // PodScheduled represents status of the scheduling process for this pod. PodScheduled PodConditionType = "PodScheduled" + // DisruptionTarget indicates the pod is about to be terminated due to a + // disruption (such as preemption, eviction API or garbage-collection). + DisruptionTarget PodConditionType = "DisruptionTarget" ) // These are reasons for a pod's transition to a condition. @@ -2651,6 +2774,22 @@ const ( // PodReasonUnschedulable reason in PodScheduled PodCondition means that the scheduler // can't schedule the pod right now, for example due to insufficient resources in the cluster. PodReasonUnschedulable = "Unschedulable" + + // PodReasonSchedulingGated reason in PodScheduled PodCondition means that the scheduler + // skips scheduling the pod because one or more scheduling gates are still present. + PodReasonSchedulingGated = "SchedulingGated" + + // PodReasonSchedulerError reason in PodScheduled PodCondition means that some internal error happens + // during scheduling, for example due to nodeAffinity parsing errors. + PodReasonSchedulerError = "SchedulerError" + + // TerminationByKubelet reason in DisruptionTarget pod condition indicates that the termination + // is initiated by kubelet + PodReasonTerminationByKubelet = "TerminationByKubelet" + + // PodReasonPreemptionByScheduler reason in DisruptionTarget pod condition indicates that the + // disruption was initiated by scheduler's preemption. + PodReasonPreemptionByScheduler = "PreemptionByScheduler" ) // PodCondition contains details for the current condition of this pod. @@ -2676,6 +2815,20 @@ type PodCondition struct { Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"` } +// PodResizeStatus shows status of desired resize of a pod's containers. +type PodResizeStatus string + +const ( + // Pod resources resize has been requested and will be evaluated by node. + PodResizeStatusProposed PodResizeStatus = "Proposed" + // Pod resources resize has been accepted by node and is being actuated. + PodResizeStatusInProgress PodResizeStatus = "InProgress" + // Node cannot resize the pod at this time and will keep retrying. + PodResizeStatusDeferred PodResizeStatus = "Deferred" + // Requested pod resize is not feasible and will not be re-evaluated. + PodResizeStatusInfeasible PodResizeStatus = "Infeasible" +) + // RestartPolicy describes how the container should be restarted. // Only one of the following restart policies may be specified. // If none of the following policies is specified, the default one @@ -2725,7 +2878,7 @@ const ( // by the node selector terms. // +structType=atomic type NodeSelector struct { - //Required. A list of node selector terms. The terms are ORed. + // Required. A list of node selector terms. The terms are ORed. NodeSelectorTerms []NodeSelectorTerm `json:"nodeSelectorTerms" protobuf:"bytes,1,rep,name=nodeSelectorTerms"` } @@ -3081,13 +3234,12 @@ type PodSpec struct { // pod to perform user-initiated actions such as debugging. This list cannot be specified when // creating a pod, and it cannot be modified by updating the pod spec. In order to add an // ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional // +patchMergeKey=name // +patchStrategy=merge EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,34,rep,name=ephemeralContainers"` // Restart policy for all containers within the pod. - // One of Always, OnFailure, Never. + // One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. // Default to Always. // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy // +optional @@ -3277,6 +3429,7 @@ type PodSpec struct { // If the OS field is set to windows, following fields must be unset: // - spec.hostPID // - spec.hostIPC + // - spec.hostUsers // - spec.securityContext.seLinuxOptions // - spec.securityContext.seccompProfile // - spec.securityContext.fsGroup @@ -3296,8 +3449,95 @@ type PodSpec struct { // - spec.containers[*].securityContext.runAsUser // - spec.containers[*].securityContext.runAsGroup // +optional - // This is a beta field and requires the IdentifyPodOS feature OS *PodOS `json:"os,omitempty" protobuf:"bytes,36,opt,name=os"` + + // Use the host's user namespace. + // Optional: Default to true. + // If set to true or not present, the pod will be run in the host user namespace, useful + // for when the pod needs a feature only available to the host user namespace, such as + // loading a kernel module with CAP_SYS_MODULE. + // When set to false, a new userns is created for the pod. Setting false is useful for + // mitigating container breakout vulnerabilities even allowing users to run their + // containers as root without actually having root privileges on the host. + // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + // +k8s:conversion-gen=false + // +optional + HostUsers *bool `json:"hostUsers,omitempty" protobuf:"bytes,37,opt,name=hostUsers"` + + // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + // scheduler will not attempt to schedule the pod. + // + // SchedulingGates can only be set at pod creation time, and be removed only afterwards. + // + // This is a beta feature enabled by the PodSchedulingReadiness feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=PodSchedulingReadiness + // +optional + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,38,opt,name=schedulingGates"` + // ResourceClaims defines which ResourceClaims must be allocated + // and reserved before the Pod is allowed to start. The resources + // will be made available to those containers which consume them + // by name. + // + // This is an alpha field and requires enabling the + // DynamicResourceAllocation feature gate. + // + // This field is immutable. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +featureGate=DynamicResourceAllocation + // +optional + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,39,rep,name=resourceClaims"` +} + +// PodResourceClaim references exactly one ResourceClaim through a ClaimSource. +// It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. +// Containers that need access to the ResourceClaim reference it with this name. +type PodResourceClaim struct { + // Name uniquely identifies this resource claim inside the pod. + // This must be a DNS_LABEL. + Name string `json:"name" protobuf:"bytes,1,name=name"` + + // Source describes where to find the ResourceClaim. + Source ClaimSource `json:"source,omitempty" protobuf:"bytes,2,name=source"` +} + +// ClaimSource describes a reference to a ResourceClaim. +// +// Exactly one of these fields should be set. Consumers of this type must +// treat an empty object as if it has an unknown value. +type ClaimSource struct { + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this pod. + ResourceClaimName *string `json:"resourceClaimName,omitempty" protobuf:"bytes,1,opt,name=resourceClaimName"` + + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this pod. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this pod. When this pod is deleted, the ResourceClaim + // will also be deleted. The name of the ResourceClaim will be -, where is the + // PodResourceClaim.Name. Pod validation will reject the pod if the + // concatenated name is not valid for a ResourceClaim (e.g. too long). + // + // An existing ResourceClaim with that name that is not owned by the + // pod will not be used for the pod to avoid using an unrelated + // resource by mistake. Scheduling and pod startup are then blocked + // until the unrelated ResourceClaim is removed. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + ResourceClaimTemplateName *string `json:"resourceClaimTemplateName,omitempty" protobuf:"bytes,2,opt,name=resourceClaimTemplateName"` } // OSName is the set of OS'es that can be used in OS. @@ -3318,6 +3558,13 @@ type PodOS struct { Name OSName `json:"name" protobuf:"bytes,1,opt,name=name"` } +// PodSchedulingGate is associated to a Pod to guard its scheduling. +type PodSchedulingGate struct { + // Name of the scheduling gate. + // Each scheduling gate must have a unique name field. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` +} + // +enum type UnsatisfiableConstraintAction string @@ -3330,6 +3577,17 @@ const ( ScheduleAnyway UnsatisfiableConstraintAction = "ScheduleAnyway" ) +// NodeInclusionPolicy defines the type of node inclusion policy +// +enum +type NodeInclusionPolicy string + +const ( + // NodeInclusionPolicyIgnore means ignore this scheduling directive when calculating pod topology spread skew. + NodeInclusionPolicyIgnore NodeInclusionPolicy = "Ignore" + // NodeInclusionPolicyHonor means use this scheduling directive when calculating pod topology spread skew. + NodeInclusionPolicyHonor NodeInclusionPolicy = "Honor" +) + // TopologySpreadConstraint specifies how to spread matching pods among the given topology. type TopologySpreadConstraint struct { // MaxSkew describes the degree to which pods may be unevenly distributed. @@ -3358,7 +3616,8 @@ type TopologySpreadConstraint struct { // We consider each as a "bucket", and try to put balanced number // of pods into each bucket. // We define a domain as a particular instance of a topology. - // Also, we define an eligible domain as a domain whose nodes match the node selector. + // Also, we define an eligible domain as a domain whose nodes meet the requirements of + // nodeAffinityPolicy and nodeTaintsPolicy. // e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. // And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. // It's a required field. @@ -3413,9 +3672,41 @@ type TopologySpreadConstraint struct { // because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, // it will violate MaxSkew. // - // This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate. + // This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). // +optional MinDomains *int32 `json:"minDomains,omitempty" protobuf:"varint,5,opt,name=minDomains"` + // NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + // when calculating pod topology spread skew. Options are: + // - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + // - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + // + // If this value is nil, the behavior is equivalent to the Honor policy. + // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + // +optional + NodeAffinityPolicy *NodeInclusionPolicy `json:"nodeAffinityPolicy,omitempty" protobuf:"bytes,6,opt,name=nodeAffinityPolicy"` + // NodeTaintsPolicy indicates how we will treat node taints when calculating + // pod topology spread skew. Options are: + // - Honor: nodes without taints, along with tainted nodes for which the incoming pod + // has a toleration, are included. + // - Ignore: node taints are ignored. All nodes are included. + // + // If this value is nil, the behavior is equivalent to the Ignore policy. + // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + // +optional + NodeTaintsPolicy *NodeInclusionPolicy `json:"nodeTaintsPolicy,omitempty" protobuf:"bytes,7,opt,name=nodeTaintsPolicy"` + // MatchLabelKeys is a set of pod label keys to select the pods over which + // spreading will be calculated. The keys are used to lookup values from the + // incoming pod labels, those key-value labels are ANDed with labelSelector + // to select the group of existing pods over which spreading will be calculated + // for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + // MatchLabelKeys cannot be set when LabelSelector isn't set. + // Keys that don't exist in the incoming pod labels will + // be ignored. A null or empty list means only match against labelSelector. + // + // This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + // +listType=atomic + // +optional + MatchLabelKeys []string `json:"matchLabelKeys,omitempty" protobuf:"bytes,8,opt,name=matchLabelKeys"` } const ( @@ -3492,8 +3783,11 @@ type PodSecurityContext struct { // +optional RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" protobuf:"varint,3,opt,name=runAsNonRoot"` // A list of groups applied to the first process run in each container, in addition - // to the container's primary GID. If unspecified, no groups will be added to - // any container. + // to the container's primary GID, the fsGroup (if specified), and group memberships + // defined in the container image for the uid of the container process. If unspecified, + // no additional groups are added to any container. Note that group memberships + // defined in the container image for the uid of the container process are still effective, + // even if they are not included in this list. // Note that this field cannot be set when spec.os.name is windows. // +optional SupplementalGroups []int64 `json:"supplementalGroups,omitempty" protobuf:"varint,4,rep,name=supplementalGroups"` @@ -3607,7 +3901,8 @@ type PodDNSConfigOption struct { // IP address information for entries in the (plural) PodIPs field. // Each entry includes: -// IP: An IP address allocated to the pod. Routable at least within the cluster. +// +// IP: An IP address allocated to the pod. Routable at least within the cluster. type PodIP struct { // ip is an IP address (IPv4 or IPv6) assigned to the pod IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` @@ -3676,6 +3971,11 @@ type EphemeralContainerCommon struct { // already allocated to the pod. // +optional Resources ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" protobuf:"bytes,23,rep,name=resizePolicy"` // Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. // Cannot be updated. // +optional @@ -3764,8 +4064,6 @@ var _ = Container(EphemeralContainerCommon{}) // // To add an ephemeral container, use the ephemeralcontainers subresource of an existing // Pod. Ephemeral containers may not be removed or restarted. -// -// This is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate. type EphemeralContainer struct { // Ephemeral containers have all of the fields of Container, plus additional fields // specific to ephemeral containers. Fields in common with Container are in the @@ -3863,13 +4161,19 @@ type PodStatus struct { ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty" protobuf:"bytes,8,rep,name=containerStatuses"` // The Quality of Service (QOS) classification assigned to the pod based on resource requirements // See PodQOSClass type for available QOS classes - // More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes // +optional QOSClass PodQOSClass `json:"qosClass,omitempty" protobuf:"bytes,9,rep,name=qosClass"` // Status for any ephemeral containers that have run in this pod. - // This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate. // +optional EphemeralContainerStatuses []ContainerStatus `json:"ephemeralContainerStatuses,omitempty" protobuf:"bytes,13,rep,name=ephemeralContainerStatuses"` + + // Status of resources resize desired for pod's containers. + // It is empty if no resources resize is pending. + // Any changes to container resources will automatically set this to "Proposed" + // +featureGate=InPlacePodVerticalScaling + // +optional + Resize PodResizeStatus `json:"resize,omitempty" protobuf:"bytes,14,opt,name=resize,casttype=PodResizeStatus"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -4008,6 +4312,7 @@ type ReplicationControllerSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. This takes precedence over a TemplateRef. + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template // +optional Template *PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"` @@ -4016,7 +4321,7 @@ type ReplicationControllerSpec struct { // ReplicationControllerStatus represents the current status of a replication // controller. type ReplicationControllerStatus struct { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` @@ -4168,29 +4473,47 @@ const ( ServiceTypeExternalName ServiceType = "ExternalName" ) -// ServiceInternalTrafficPolicyType describes the type of traffic routing for -// internal traffic +// ServiceInternalTrafficPolicy describes how nodes distribute service traffic they +// receive on the ClusterIP. +// +enum +type ServiceInternalTrafficPolicy string + +const ( + // ServiceInternalTrafficPolicyCluster routes traffic to all endpoints. + ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicy = "Cluster" + + // ServiceInternalTrafficPolicyLocal routes traffic only to endpoints on the same + // node as the client pod (dropping the traffic if there are no local endpoints). + ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicy = "Local" +) + +// for backwards compat // +enum -type ServiceInternalTrafficPolicyType string +type ServiceInternalTrafficPolicyType = ServiceInternalTrafficPolicy + +// ServiceExternalTrafficPolicy describes how nodes distribute service traffic they +// receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs, +// and LoadBalancer IPs. +// +enum +type ServiceExternalTrafficPolicy string const ( - // ServiceInternalTrafficPolicyCluster routes traffic to all endpoints - ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicyType = "Cluster" + // ServiceExternalTrafficPolicyCluster routes traffic to all endpoints. + ServiceExternalTrafficPolicyCluster ServiceExternalTrafficPolicy = "Cluster" - // ServiceInternalTrafficPolicyLocal only routes to node-local - // endpoints, otherwise drops the traffic - ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicyType = "Local" + // ServiceExternalTrafficPolicyLocal preserves the source IP of the traffic by + // routing only to endpoints on the same node as the traffic was received on + // (dropping the traffic if there are no local endpoints). + ServiceExternalTrafficPolicyLocal ServiceExternalTrafficPolicy = "Local" ) -// Service External Traffic Policy Type string +// for backwards compat // +enum -type ServiceExternalTrafficPolicyType string +type ServiceExternalTrafficPolicyType = ServiceExternalTrafficPolicy const ( - // ServiceExternalTrafficPolicyTypeLocal specifies node-local endpoints behavior. - ServiceExternalTrafficPolicyTypeLocal ServiceExternalTrafficPolicyType = "Local" - // ServiceExternalTrafficPolicyTypeCluster specifies node-global (legacy) behavior. - ServiceExternalTrafficPolicyTypeCluster ServiceExternalTrafficPolicyType = "Cluster" + ServiceExternalTrafficPolicyTypeLocal = ServiceExternalTrafficPolicyLocal + ServiceExternalTrafficPolicyTypeCluster = ServiceExternalTrafficPolicyCluster ) // These are the valid conditions of a service. @@ -4198,6 +4521,9 @@ const ( // LoadBalancerPortsError represents the condition of the requested ports // on the cloud load balancer instance. LoadBalancerPortsError = "LoadBalancerPortsError" + // LoadBalancerPortsErrorReason reason in ServiceStatus condition LoadBalancerPortsError + // means the LoadBalancer was not able to be configured correctly. + LoadBalancerPortsErrorReason = "LoadBalancerMixedProtocolNotSupported" ) // ServiceStatus represents the current status of a service. @@ -4255,30 +4581,34 @@ const ( IPv6Protocol IPFamily = "IPv6" ) -// IPFamilyPolicyType represents the dual-stack-ness requested or required by a Service +// IPFamilyPolicy represents the dual-stack-ness requested or required by a Service // +enum -type IPFamilyPolicyType string +type IPFamilyPolicy string const ( // IPFamilyPolicySingleStack indicates that this service is required to have a single IPFamily. // The IPFamily assigned is based on the default IPFamily used by the cluster // or as identified by service.spec.ipFamilies field - IPFamilyPolicySingleStack IPFamilyPolicyType = "SingleStack" + IPFamilyPolicySingleStack IPFamilyPolicy = "SingleStack" // IPFamilyPolicyPreferDualStack indicates that this service prefers dual-stack when // the cluster is configured for dual-stack. If the cluster is not configured // for dual-stack the service will be assigned a single IPFamily. If the IPFamily is not // set in service.spec.ipFamilies then the service will be assigned the default IPFamily // configured on the cluster - IPFamilyPolicyPreferDualStack IPFamilyPolicyType = "PreferDualStack" + IPFamilyPolicyPreferDualStack IPFamilyPolicy = "PreferDualStack" // IPFamilyPolicyRequireDualStack indicates that this service requires dual-stack. Using // IPFamilyPolicyRequireDualStack on a single stack cluster will result in validation errors. The // IPFamilies (and their order) assigned to this service is based on service.spec.ipFamilies. If // service.spec.ipFamilies was not provided then it will be assigned according to how they are // configured on the cluster. If service.spec.ipFamilies has only one entry then the alternative // IPFamily will be added by apiserver - IPFamilyPolicyRequireDualStack IPFamilyPolicyType = "RequireDualStack" + IPFamilyPolicyRequireDualStack IPFamilyPolicy = "RequireDualStack" ) +// for backwards compat +// +enum +type IPFamilyPolicyType = IPFamilyPolicy + // ServiceSpec describes the attributes that a user creates on a service. type ServiceSpec struct { // The list of ports that are exposed by this service. @@ -4405,14 +4735,21 @@ type ServiceSpec struct { // +optional ExternalName string `json:"externalName,omitempty" protobuf:"bytes,10,opt,name=externalName"` - // externalTrafficPolicy denotes if this Service desires to route external - // traffic to node-local or cluster-wide endpoints. "Local" preserves the - // client source IP and avoids a second hop for LoadBalancer and Nodeport - // type services, but risks potentially imbalanced traffic spreading. - // "Cluster" obscures the client source IP and may cause a second hop to - // another node, but should have good overall load-spreading. - // +optional - ExternalTrafficPolicy ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty" protobuf:"bytes,11,opt,name=externalTrafficPolicy"` + // externalTrafficPolicy describes how nodes distribute service traffic they + // receive on one of the Service's "externally-facing" addresses (NodePorts, + // ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + // the service in a way that assumes that external load balancers will take care + // of balancing the service traffic between nodes, and so each node will deliver + // traffic only to the node-local endpoints of the service, without masquerading + // the client source IP. (Traffic mistakenly sent to a node with no endpoints will + // be dropped.) The default value, "Cluster", uses the standard behavior of + // routing to all endpoints evenly (possibly modified by topology and other + // features). Note that traffic sent to an External IP or LoadBalancer IP from + // within the cluster will always get "Cluster" semantics, but clients sending to + // a NodePort from within the cluster may need to take traffic policy into account + // when picking a node. + // +optional + ExternalTrafficPolicy ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty" protobuf:"bytes,11,opt,name=externalTrafficPolicy"` // healthCheckNodePort specifies the healthcheck nodePort for the service. // This only applies when type is set to LoadBalancer and @@ -4423,6 +4760,7 @@ type ServiceSpec struct { // service or not. If this field is specified when creating a Service // which does not need it, creation will fail. This field will be wiped // when updating a Service to no longer need it (e.g. changing type). + // This field cannot be updated once set. // +optional HealthCheckNodePort int32 `json:"healthCheckNodePort,omitempty" protobuf:"bytes,12,opt,name=healthCheckNodePort"` @@ -4442,7 +4780,7 @@ type ServiceSpec struct { SessionAffinityConfig *SessionAffinityConfig `json:"sessionAffinityConfig,omitempty" protobuf:"bytes,14,opt,name=sessionAffinityConfig"` // TopologyKeys is tombstoned to show why 16 is reserved protobuf tag. - //TopologyKeys []string `json:"topologyKeys,omitempty" protobuf:"bytes,16,opt,name=topologyKeys"` + // TopologyKeys []string `json:"topologyKeys,omitempty" protobuf:"bytes,16,opt,name=topologyKeys"` // IPFamily is tombstoned to show why 15 is a reserved protobuf tag. // IPFamily *IPFamily `json:"ipFamily,omitempty" protobuf:"bytes,15,opt,name=ipFamily,Configcasttype=IPFamily"` @@ -4476,7 +4814,7 @@ type ServiceSpec struct { // ipFamilies and clusterIPs fields depend on the value of this field. This // field will be wiped when updating a service to type ExternalName. // +optional - IPFamilyPolicy *IPFamilyPolicyType `json:"ipFamilyPolicy,omitempty" protobuf:"bytes,17,opt,name=ipFamilyPolicy,casttype=IPFamilyPolicyType"` + IPFamilyPolicy *IPFamilyPolicy `json:"ipFamilyPolicy,omitempty" protobuf:"bytes,17,opt,name=ipFamilyPolicy,casttype=IPFamilyPolicy"` // allocateLoadBalancerNodePorts defines if NodePorts will be automatically // allocated for services with type LoadBalancer. Default is "true". It @@ -4498,19 +4836,17 @@ type ServiceSpec struct { // implementation (e.g. cloud providers) should ignore Services that set this field. // This field can only be set when creating or updating a Service to type 'LoadBalancer'. // Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. - // +featureGate=LoadBalancerClass // +optional LoadBalancerClass *string `json:"loadBalancerClass,omitempty" protobuf:"bytes,21,opt,name=loadBalancerClass"` - // InternalTrafficPolicy specifies if the cluster internal traffic - // should be routed to all endpoints or node-local endpoints only. - // "Cluster" routes internal traffic to a Service to all endpoints. - // "Local" routes traffic to node-local endpoints only, traffic is - // dropped if no node-local endpoints are ready. - // The default value is "Cluster". - // +featureGate=ServiceInternalTrafficPolicy + // InternalTrafficPolicy describes how nodes distribute service traffic they + // receive on the ClusterIP. If set to "Local", the proxy will assume that pods + // only want to talk to endpoints of the service on the same node as the pod, + // dropping the traffic if there are no local endpoints. The default value, + // "Cluster", uses the standard behavior of routing to all endpoints evenly + // (possibly modified by topology and other features). // +optional - InternalTrafficPolicy *ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"` + InternalTrafficPolicy *ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"` } // ServicePort contains information on service's port. @@ -4669,17 +5005,18 @@ type ServiceAccountList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Endpoints is a collection of endpoints that implement the actual service. Example: -// Name: "mysvc", -// Subsets: [ -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// }, -// { -// Addresses: [{"ip": "10.10.3.3"}], -// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] -// }, -// ] +// +// Name: "mysvc", +// Subsets: [ +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// }, +// { +// Addresses: [{"ip": "10.10.3.3"}], +// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] +// }, +// ] type Endpoints struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. @@ -4701,13 +5038,16 @@ type Endpoints struct { // EndpointSubset is a group of addresses with a common set of ports. The // expanded set of endpoints is the Cartesian product of Addresses x Ports. // For example, given: -// { -// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], -// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] -// } +// +// { +// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], +// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] +// } +// // The resulting set of endpoints can be viewed as: -// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], -// b: [ 10.10.1.1:309, 10.10.2.2:309 ] +// +// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], +// b: [ 10.10.1.1:309, 10.10.2.2:309 ] type EndpointSubset struct { // IP addresses which offer the related ports that are marked as ready. These endpoints // should be considered safe for load balancers and clients to utilize. @@ -4727,11 +5067,8 @@ type EndpointSubset struct { // +structType=atomic type EndpointAddress struct { // The IP of this endpoint. - // May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), - // or link-local multicast ((224.0.0.0/24). - // IPv6 is also accepted but not fully supported on all platforms. Also, certain - // kubernetes components, like kube-proxy, are not IPv6 ready. - // TODO: This should allow hostname or IP, See #4447. + // May not be loopback (127.0.0.0/8 or ::1), link-local (169.254.0.0/16 or fe80::/10), + // or link-local multicast (224.0.0.0/24 or ff02::/16). IP string `json:"ip" protobuf:"bytes,1,opt,name=ip"` // The Hostname of this endpoint // +optional @@ -4764,10 +5101,17 @@ type EndpointPort struct { Protocol Protocol `json:"protocol,omitempty" protobuf:"bytes,3,opt,name=protocol,casttype=Protocol"` // The application protocol for this port. + // This is used as a hint for implementations to offer richer behavior for protocols that they understand. // This field follows standard Kubernetes label syntax. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional AppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,4,opt,name=appProtocol"` @@ -4811,7 +5155,7 @@ type NodeSpec struct { // +optional Taints []Taint `json:"taints,omitempty" protobuf:"bytes,5,opt,name=taints"` - // Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed from Kubelets as of 1.24 and will be fully removed in 1.26. + // Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed. // +optional ConfigSource *NodeConfigSource `json:"configSource,omitempty" protobuf:"bytes,6,opt,name=configSource"` @@ -4985,7 +5329,11 @@ type NodeStatus struct { // More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses // Note: This field is declared as mergeable, but the merge key is not sufficiently // unique, which can cause data corruption when it is merged. Callers should instead - // use a full-replacement patch. See http://pr.k8s.io/79391 for an example. + // use a full-replacement patch. See https://pr.k8s.io/79391 for an example. + // Consumers should assume that addresses can change during the + // lifetime of a Node. However, there are some exceptions where this may not + // be possible, such as Pods that inherit a Node's address in its own status or + // consumers of the downward API (status.hostIP). // +optional // +patchMergeKey=type // +patchStrategy=merge @@ -5058,7 +5406,7 @@ type PodSignature struct { // Describe a container image type ContainerImage struct { // Names by which this image is known. - // e.g. ["k8s.gcr.io/hyperkube:v1.0.7", "dockerhub.io/google_containers/hyperkube:v1.0.7"] + // e.g. ["kubernetes.example/hyperkube:v1.0.7", "cloud-vendor.registry.example/cloud-vendor/hyperkube:v1.0.7"] // +optional Names []string `json:"names" protobuf:"bytes,1,rep,name=names"` // The size of the image in bytes. @@ -5580,6 +5928,7 @@ type ServiceProxyOptions struct { // and the version of the actual struct is irrelevant. // 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type // will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. +// // Instead of using this type, create a locally provided and used type that is well-focused on your reference. // For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -6539,6 +6888,13 @@ const ( PortForwardRequestIDHeader = "requestID" ) +const ( + // MixedProtocolNotSupported error in PortStatus means that the cloud provider + // can't publish the port on the load balancer because mixed values of protocols + // on the same LoadBalancer type of Service are not supported by the cloud provider. + MixedProtocolNotSupported = "MixedProtocolNotSupported" +) + // PortStatus represents the error condition of a service port type PortStatus struct { diff --git a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go index 53a06b94528..a01ae371737 100644 --- a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AWSElasticBlockStoreVolumeSource = map[string]string{ @@ -126,7 +126,8 @@ var map_CSIPersistentVolumeSource = map[string]string{ "controllerPublishSecretRef": "controllerPublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerPublishVolume and ControllerUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", "nodeStageSecretRef": "nodeStageSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeStageVolume and NodeStageVolume and NodeUnstageVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", "nodePublishSecretRef": "nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", - "controllerExpandSecretRef": "controllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call. This is an alpha field and requires enabling ExpandCSIVolumes feature gate. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", + "controllerExpandSecretRef": "controllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", + "nodeExpandSecretRef": "nodeExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeExpandVolume call. This is a beta field which is enabled default by CSINodeExpandSecret feature gate. This field is optional, may be omitted if no secret is required. If the secret object contains more than one secret, all secrets are passed.", } func (CSIPersistentVolumeSource) SwaggerDoc() map[string]string { @@ -208,6 +209,16 @@ func (CinderVolumeSource) SwaggerDoc() map[string]string { return map_CinderVolumeSource } +var map_ClaimSource = map[string]string{ + "": "ClaimSource describes a reference to a ResourceClaim.\n\nExactly one of these fields should be set. Consumers of this type must treat an empty object as if it has an unknown value.", + "resourceClaimName": "ResourceClaimName is the name of a ResourceClaim object in the same namespace as this pod.", + "resourceClaimTemplateName": "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The name of the ResourceClaim will be -, where is the PodResourceClaim.Name. Pod validation will reject the pod if the concatenated name is not valid for a ResourceClaim (e.g. too long).\n\nAn existing ResourceClaim with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated resource by mistake. Scheduling and pod startup are then blocked until the unrelated ResourceClaim is removed.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.", +} + +func (ClaimSource) SwaggerDoc() map[string]string { + return map_ClaimSource +} + var map_ClientIPConfig = map[string]string{ "": "ClientIPConfig represents the configurations of Client IP based session affinity.", "timeoutSeconds": "timeoutSeconds specifies the seconds of ClientIP type session sticky time. The value must be >0 && <=86400(for 1 day) if ServiceAffinity == \"ClientIP\". Default value is 10800(for 3 hours).", @@ -331,10 +342,11 @@ var map_Container = map[string]string{ "command": "Entrypoint array. Not executed within a shell. The container image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "args": "Arguments to the entrypoint. The container image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "workingDir": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "ports": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "ports": "List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated.", "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "env": "List of environment variables to set in the container. Cannot be updated.", "resources": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "resizePolicy": "Resources resize policy for the container.", "volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.", "volumeDevices": "volumeDevices is the list of block devices to be used by the container.", "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", @@ -356,7 +368,7 @@ func (Container) SwaggerDoc() map[string]string { var map_ContainerImage = map[string]string{ "": "Describe a container image", - "names": "Names by which this image is known. e.g. [\"k8s.gcr.io/hyperkube:v1.0.7\", \"dockerhub.io/google_containers/hyperkube:v1.0.7\"]", + "names": "Names by which this image is known. e.g. [\"kubernetes.example/hyperkube:v1.0.7\", \"cloud-vendor.registry.example/cloud-vendor/hyperkube:v1.0.7\"]", "sizeBytes": "The size of the image in bytes.", } @@ -377,6 +389,16 @@ func (ContainerPort) SwaggerDoc() map[string]string { return map_ContainerPort } +var map_ContainerResizePolicy = map[string]string{ + "": "ContainerResizePolicy represents resource resize policy for the container.", + "resourceName": "Name of the resource to which this resource resize policy applies. Supported values: cpu, memory.", + "restartPolicy": "Restart policy to apply when specified resource is resized. If not specified, it defaults to NotRequired.", +} + +func (ContainerResizePolicy) SwaggerDoc() map[string]string { + return map_ContainerResizePolicy +} + var map_ContainerState = map[string]string{ "": "ContainerState holds a possible state of container. Only one of its members may be specified. If none of them is specified, the default one is ContainerStateWaiting.", "waiting": "Details about a waiting container", @@ -423,16 +445,18 @@ func (ContainerStateWaiting) SwaggerDoc() map[string]string { } var map_ContainerStatus = map[string]string{ - "": "ContainerStatus contains details for the current status of this container.", - "name": "This must be a DNS_LABEL. Each container in a pod must have a unique name. Cannot be updated.", - "state": "Details about the container's current condition.", - "lastState": "Details about the container's last termination condition.", - "ready": "Specifies whether the container has passed its readiness probe.", - "restartCount": "The number of times the container has been restarted.", - "image": "The image the container is running. More info: https://kubernetes.io/docs/concepts/containers/images.", - "imageID": "ImageID of the container's image.", - "containerID": "Container's ID in the format '://'.", - "started": "Specifies whether the container has passed its startup probe. Initialized as false, becomes true after startupProbe is considered successful. Resets to false when the container is restarted, or if kubelet loses state temporarily. Is always true when no startupProbe is defined.", + "": "ContainerStatus contains details for the current status of this container.", + "name": "Name is a DNS_LABEL representing the unique name of the container. Each container in a pod must have a unique name across all container types. Cannot be updated.", + "state": "State holds details about the container's current condition.", + "lastState": "LastTerminationState holds the last termination state of the container to help debug container crashes and restarts. This field is not populated if the container is still running and RestartCount is 0.", + "ready": "Ready specifies whether the container is currently passing its readiness check. The value will change as readiness probes keep executing. If no readiness probes are specified, this field defaults to true once the container is fully started (see Started field).\n\nThe value is typically used to determine whether a container is ready to accept traffic.", + "restartCount": "RestartCount holds the number of times the container has been restarted. Kubelet makes an effort to always increment the value, but there are cases when the state may be lost due to node restarts and then the value may be reset to 0. The value is never negative.", + "image": "Image is the name of container image that the container is running. The container image may not match the image used in the PodSpec, as it may have been resolved by the runtime. More info: https://kubernetes.io/docs/concepts/containers/images.", + "imageID": "ImageID is the image ID of the container's image. The image ID may not match the image ID of the image used in the PodSpec, as it may have been resolved by the runtime.", + "containerID": "ContainerID is the ID of the container in the format '://'. Where type is a container runtime identifier, returned from Version call of CRI API (for example \"containerd\").", + "started": "Started indicates whether the container has finished its postStart lifecycle hook and passed its startup probe. Initialized as false, becomes true after startupProbe is considered successful. Resets to false when the container is restarted, or if kubelet loses state temporarily. In both cases, startup probes will run again. Is always true when no startupProbe is defined and container is running and has passed the postStart lifecycle hook. The null value must be treated the same as false.", + "allocatedResources": "AllocatedResources represents the compute resources allocated for this container by the node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission and after successfully admitting desired pod resize.", + "resources": "Resources represents the compute resource requests and limits that have been successfully enacted on the running container after it has been started or has been successfully resized.", } func (ContainerStatus) SwaggerDoc() map[string]string { @@ -482,7 +506,7 @@ func (DownwardAPIVolumeSource) SwaggerDoc() map[string]string { var map_EmptyDirVolumeSource = map[string]string{ "": "Represents an empty directory for a pod. Empty directory volumes support ownership management and SELinux relabeling.", "medium": "medium represents what type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir", - "sizeLimit": "sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir", + "sizeLimit": "sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir", } func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { @@ -491,7 +515,7 @@ func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { var map_EndpointAddress = map[string]string{ "": "EndpointAddress is a tuple that describes single IP address.", - "ip": "The IP of this endpoint. May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready.", + "ip": "The IP of this endpoint. May not be loopback (127.0.0.0/8 or ::1), link-local (169.254.0.0/16 or fe80::/10), or link-local multicast (224.0.0.0/24 or ff02::/16).", "hostname": "The Hostname of this endpoint", "nodeName": "Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.", "targetRef": "Reference to object providing the endpoint.", @@ -506,7 +530,7 @@ var map_EndpointPort = map[string]string{ "name": "The name of this port. This must match the 'name' field in the corresponding ServicePort. Must be a DNS_LABEL. Optional only if one port is defined.", "port": "The port number of the endpoint.", "protocol": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "appProtocol": "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -514,7 +538,7 @@ func (EndpointPort) SwaggerDoc() map[string]string { } var map_EndpointSubset = map[string]string{ - "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n }\nThe resulting set of endpoints can be viewed as:\n a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n b: [ 10.10.1.1:309, 10.10.2.2:309 ]", + "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n\n\t{\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t}\n\nThe resulting set of endpoints can be viewed as:\n\n\ta: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n\tb: [ 10.10.1.1:309, 10.10.2.2:309 ]", "addresses": "IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize.", "notReadyAddresses": "IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check.", "ports": "Port numbers available on the related IP addresses.", @@ -525,7 +549,7 @@ func (EndpointSubset) SwaggerDoc() map[string]string { } var map_Endpoints = map[string]string{ - "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n Name: \"mysvc\",\n Subsets: [\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n },\n {\n Addresses: [{\"ip\": \"10.10.3.3\"}],\n Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n },\n ]", + "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n\n\t Name: \"mysvc\",\n\t Subsets: [\n\t {\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t },\n\t {\n\t Addresses: [{\"ip\": \"10.10.3.3\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n\t },\n\t]", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "subsets": "The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.", } @@ -579,7 +603,7 @@ func (EnvVarSource) SwaggerDoc() map[string]string { } var map_EphemeralContainer = map[string]string{ - "": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.\n\nThis is a beta feature available on clusters that haven't disabled the EphemeralContainers feature gate.", + "": "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation.\n\nTo add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted.", "targetContainerName": "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec.\n\nThe container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined.", } @@ -598,6 +622,7 @@ var map_EphemeralContainerCommon = map[string]string{ "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "env": "List of environment variables to set in the container. Cannot be updated.", "resources": "Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod.", + "resizePolicy": "Resources resize policy for the container.", "volumeMounts": "Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated.", "volumeDevices": "volumeDevices is the list of block devices to be used by the container.", "livenessProbe": "Probes are not allowed for ephemeral containers.", @@ -807,7 +832,7 @@ func (HTTPGetAction) SwaggerDoc() map[string]string { var map_HTTPHeader = map[string]string{ "": "HTTPHeader describes a custom header to be used in HTTP probes", - "name": "The header field name", + "name": "The header field name. This will be canonicalized upon output, so case-variant names will be understood as the same header.", "value": "The header field value", } @@ -1188,7 +1213,7 @@ var map_NodeSpec = map[string]string{ "providerID": "ID of the node assigned by the cloud provider in the format: ://", "unschedulable": "Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: https://kubernetes.io/docs/concepts/nodes/node/#manual-node-administration", "taints": "If specified, the node's taints.", - "configSource": "Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed from Kubelets as of 1.24 and will be fully removed in 1.26.", + "configSource": "Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed.", "externalID": "Deprecated. Not all kubelets will set this field. Remove field after 1.13. see: https://issues.k8s.io/61966", } @@ -1202,7 +1227,7 @@ var map_NodeStatus = map[string]string{ "allocatable": "Allocatable represents the resources of a node that are available for scheduling. Defaults to Capacity.", "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: https://kubernetes.io/docs/concepts/nodes/node/#phase The field is never populated, and now is deprecated.", "conditions": "Conditions is an array of current observed node conditions. More info: https://kubernetes.io/docs/concepts/nodes/node/#condition", - "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses Note: This field is declared as mergeable, but the merge key is not sufficiently unique, which can cause data corruption when it is merged. Callers should instead use a full-replacement patch. See http://pr.k8s.io/79391 for an example.", + "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses Note: This field is declared as mergeable, but the merge key is not sufficiently unique, which can cause data corruption when it is merged. Callers should instead use a full-replacement patch. See https://pr.k8s.io/79391 for an example. Consumers should assume that addresses can change during the lifetime of a Node. However, there are some exceptions where this may not be possible, such as Pods that inherit a Node's address in its own status or consumers of the downward API (status.hostIP).", "daemonEndpoints": "Endpoints of daemons running on the Node.", "nodeInfo": "Set of ids/uuids to uniquely identify the node. More info: https://kubernetes.io/docs/concepts/nodes/node/#info", "images": "List of container images on this node", @@ -1281,7 +1306,7 @@ func (PersistentVolumeClaim) SwaggerDoc() map[string]string { } var map_PersistentVolumeClaimCondition = map[string]string{ - "": "PersistentVolumeClaimCondition contails details about state of pvc", + "": "PersistentVolumeClaimCondition contains details about state of pvc", "lastProbeTime": "lastProbeTime is the time we probed the condition.", "lastTransitionTime": "lastTransitionTime is the time the condition transitioned from one status to another.", "reason": "reason is a unique, this should be a short, machine understandable string that gives the reason for condition's last transition. If it reports \"ResizeStarted\" that means the underlying persistent volume is being resized.", @@ -1310,8 +1335,8 @@ var map_PersistentVolumeClaimSpec = map[string]string{ "volumeName": "volumeName is the binding reference to the PersistentVolume backing this claim.", "storageClassName": "storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", "volumeMode": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.", - "dataSource": "dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field.", - "dataSourceRef": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef\n allows any non-core object, as well as PersistentVolumeClaim objects.\n* While DataSource ignores disallowed values (dropping them), DataSourceRef\n preserves all values, and generates an error if a disallowed value is\n specified.\n(Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.", + "dataSource": "dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.", + "dataSourceRef": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef\n allows any non-core object, as well as PersistentVolumeClaim objects.\n* While dataSource ignores disallowed values (dropping them), dataSourceRef\n preserves all values, and generates an error if a disallowed value is\n specified.\n* While dataSource only allows local objects, dataSourceRef allows objects\n in any namespaces.\n(Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", } func (PersistentVolumeClaimSpec) SwaggerDoc() map[string]string { @@ -1534,7 +1559,7 @@ func (PodExecOptions) SwaggerDoc() map[string]string { } var map_PodIP = map[string]string{ - "": "IP address information for entries in the (plural) PodIPs field. Each entry includes:\n IP: An IP address allocated to the pod. Routable at least within the cluster.", + "": "IP address information for entries in the (plural) PodIPs field. Each entry includes:\n\n\tIP: An IP address allocated to the pod. Routable at least within the cluster.", "ip": "ip is an IP address (IPv4 or IPv6) assigned to the pod", } @@ -1605,6 +1630,25 @@ func (PodReadinessGate) SwaggerDoc() map[string]string { return map_PodReadinessGate } +var map_PodResourceClaim = map[string]string{ + "": "PodResourceClaim references exactly one ResourceClaim through a ClaimSource. It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name.", + "name": "Name uniquely identifies this resource claim inside the pod. This must be a DNS_LABEL.", + "source": "Source describes where to find the ResourceClaim.", +} + +func (PodResourceClaim) SwaggerDoc() map[string]string { + return map_PodResourceClaim +} + +var map_PodSchedulingGate = map[string]string{ + "": "PodSchedulingGate is associated to a Pod to guard its scheduling.", + "name": "Name of the scheduling gate. Each scheduling gate must have a unique name field.", +} + +func (PodSchedulingGate) SwaggerDoc() map[string]string { + return map_PodSchedulingGate +} + var map_PodSecurityContext = map[string]string{ "": "PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext.", "seLinuxOptions": "The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.", @@ -1612,7 +1656,7 @@ var map_PodSecurityContext = map[string]string{ "runAsUser": "The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.", "runAsGroup": "The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.", "runAsNonRoot": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", - "supplementalGroups": "A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container. Note that this field cannot be set when spec.os.name is windows.", + "supplementalGroups": "A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows.", "fsGroup": "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod:\n\n1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw ", "sysctls": "Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows.", "fsGroupChangePolicy": "fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used. Note that this field cannot be set when spec.os.name is windows.", @@ -1637,8 +1681,8 @@ var map_PodSpec = map[string]string{ "volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes", "initContainers": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.", - "ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", - "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy", + "ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", + "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy", "terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.", "activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.", "dnsPolicy": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.", @@ -1669,7 +1713,10 @@ var map_PodSpec = map[string]string{ "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", "topologySpreadConstraints": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "setHostnameAsFQDN": "If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false.", - "os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature", + "os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup", + "hostUsers": "Use the host's user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.", + "schedulingGates": "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the scheduler will not attempt to schedule the pod.\n\nSchedulingGates can only be set at pod creation time, and be removed only afterwards.\n\nThis is a beta feature enabled by the PodSchedulingReadiness feature gate.", + "resourceClaims": "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.\n\nThis is an alpha field and requires enabling the DynamicResourceAllocation feature gate.\n\nThis field is immutable.", } func (PodSpec) SwaggerDoc() map[string]string { @@ -1689,8 +1736,9 @@ var map_PodStatus = map[string]string{ "startTime": "RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.", "initContainerStatuses": "The list has one entry per init container in the manifest. The most recent successful init container will have ready = true, the most recently started container will have startTime set. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", "containerStatuses": "The list has one entry per container in the manifest. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", - "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md", - "ephemeralContainerStatuses": "Status for any ephemeral containers that have run in this pod. This field is beta-level and available on clusters that haven't disabled the EphemeralContainers feature gate.", + "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes", + "ephemeralContainerStatuses": "Status for any ephemeral containers that have run in this pod.", + "resize": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\"", } func (PodStatus) SwaggerDoc() map[string]string { @@ -1808,7 +1856,7 @@ var map_ProbeHandler = map[string]string{ "exec": "Exec specifies the action to take.", "httpGet": "HTTPGet specifies the http request to perform.", "tcpSocket": "TCPSocket specifies an action involving a TCP port.", - "grpc": "GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate.", + "grpc": "GRPC specifies an action involving a GRPC port.", } func (ProbeHandler) SwaggerDoc() map[string]string { @@ -1921,7 +1969,7 @@ var map_ReplicationControllerSpec = map[string]string{ "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "selector": "Selector is a label query over pods that should match the Replicas count. If Selector is empty, it is defaulted to the labels present on the Pod template. Label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", } func (ReplicationControllerSpec) SwaggerDoc() map[string]string { @@ -1930,7 +1978,7 @@ func (ReplicationControllerSpec) SwaggerDoc() map[string]string { var map_ReplicationControllerStatus = map[string]string{ "": "ReplicationControllerStatus represents the current status of a replication controller.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller", + "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller", "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replication controller.", "readyReplicas": "The number of ready replicas for this replication controller.", "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replication controller.", @@ -1942,6 +1990,15 @@ func (ReplicationControllerStatus) SwaggerDoc() map[string]string { return map_ReplicationControllerStatus } +var map_ResourceClaim = map[string]string{ + "": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "name": "Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.", +} + +func (ResourceClaim) SwaggerDoc() map[string]string { + return map_ResourceClaim +} + var map_ResourceFieldSelector = map[string]string{ "": "ResourceFieldSelector represents container resources (cpu, memory) and their output format", "containerName": "Container name: required for volumes, optional for env vars", @@ -1998,7 +2055,8 @@ func (ResourceQuotaStatus) SwaggerDoc() map[string]string { var map_ResourceRequirements = map[string]string{ "": "ResourceRequirements describes the compute resource requirements.", "limits": "Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", - "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "claims": "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.\n\nThis is an alpha field and requires enabling the DynamicResourceAllocation feature gate.\n\nThis field is immutable. It can only be set for containers.", } func (ResourceRequirements) SwaggerDoc() map[string]string { @@ -2274,15 +2332,15 @@ var map_ServiceSpec = map[string]string{ "loadBalancerIP": "Only applies to Service Type: LoadBalancer. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature. Deprecated: This field was under-specified and its meaning varies across implementations, and it cannot support dual-stack. As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available. This field may be removed in a future API version.", "loadBalancerSourceRanges": "If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature.\" More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/", "externalName": "externalName is the external reference that discovery mechanisms will return as an alias for this service (e.g. a DNS CNAME record). No proxying will be involved. Must be a lowercase RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) and requires `type` to be \"ExternalName\".", - "externalTrafficPolicy": "externalTrafficPolicy denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints. \"Local\" preserves the client source IP and avoids a second hop for LoadBalancer and Nodeport type services, but risks potentially imbalanced traffic spreading. \"Cluster\" obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading.", - "healthCheckNodePort": "healthCheckNodePort specifies the healthcheck nodePort for the service. This only applies when type is set to LoadBalancer and externalTrafficPolicy is set to Local. If a value is specified, is in-range, and is not in use, it will be used. If not specified, a value will be automatically allocated. External systems (e.g. load-balancers) can use this port to determine if a given node holds endpoints for this service or not. If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type).", + "externalTrafficPolicy": "externalTrafficPolicy describes how nodes distribute service traffic they receive on one of the Service's \"externally-facing\" addresses (NodePorts, ExternalIPs, and LoadBalancer IPs). If set to \"Local\", the proxy will configure the service in a way that assumes that external load balancers will take care of balancing the service traffic between nodes, and so each node will deliver traffic only to the node-local endpoints of the service, without masquerading the client source IP. (Traffic mistakenly sent to a node with no endpoints will be dropped.) The default value, \"Cluster\", uses the standard behavior of routing to all endpoints evenly (possibly modified by topology and other features). Note that traffic sent to an External IP or LoadBalancer IP from within the cluster will always get \"Cluster\" semantics, but clients sending to a NodePort from within the cluster may need to take traffic policy into account when picking a node.", + "healthCheckNodePort": "healthCheckNodePort specifies the healthcheck nodePort for the service. This only applies when type is set to LoadBalancer and externalTrafficPolicy is set to Local. If a value is specified, is in-range, and is not in use, it will be used. If not specified, a value will be automatically allocated. External systems (e.g. load-balancers) can use this port to determine if a given node holds endpoints for this service or not. If this field is specified when creating a Service which does not need it, creation will fail. This field will be wiped when updating a Service to no longer need it (e.g. changing type). This field cannot be updated once set.", "publishNotReadyAddresses": "publishNotReadyAddresses indicates that any agent which deals with endpoints for this Service should disregard any indications of ready/not-ready. The primary use case for setting this field is for a StatefulSet's Headless Service to propagate SRV DNS records for its Pods for the purpose of peer discovery. The Kubernetes controllers that generate Endpoints and EndpointSlice resources for Services interpret this to mean that all endpoints are considered \"ready\" even if the Pods themselves are not. Agents which consume only Kubernetes generated endpoints through the Endpoints or EndpointSlice resources can safely assume this behavior.", "sessionAffinityConfig": "sessionAffinityConfig contains the configurations of session affinity.", "ipFamilies": "IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. If this field is specified manually, the requested family is available in the cluster, and ipFamilyPolicy allows it, it will be used; otherwise creation of the service will fail. This field is conditionally mutable: it allows for adding or removing a secondary IP family, but it does not allow changing the primary IP family of the Service. Valid values are \"IPv4\" and \"IPv6\". This field only applies to Services of types ClusterIP, NodePort, and LoadBalancer, and does apply to \"headless\" services. This field will be wiped when updating a Service to type ExternalName.\n\nThis field may hold a maximum of two entries (dual-stack families, in either order). These families must correspond to the values of the clusterIPs field, if specified. Both clusterIPs and ipFamilies are governed by the ipFamilyPolicy field.", "ipFamilyPolicy": "IPFamilyPolicy represents the dual-stack-ness requested or required by this Service. If there is no value provided, then this field will be set to SingleStack. Services can be \"SingleStack\" (a single IP family), \"PreferDualStack\" (two IP families on dual-stack configured clusters or a single IP family on single-stack clusters), or \"RequireDualStack\" (two IP families on dual-stack configured clusters, otherwise fail). The ipFamilies and clusterIPs fields depend on the value of this field. This field will be wiped when updating a service to type ExternalName.", "allocateLoadBalancerNodePorts": "allocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is \"true\". It may be set to \"false\" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type.", "loadBalancerClass": "loadBalancerClass is the class of the load balancer implementation this Service belongs to. If specified, the value of this field must be a label-style identifier, with an optional prefix, e.g. \"internal-vip\" or \"example.com/internal-vip\". Unprefixed names are reserved for end-users. This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load balancer implementation is used, today this is typically done through the cloud provider integration, but should apply for any default implementation. If set, it is assumed that a load balancer implementation is watching for Services with a matching class. Any default load balancer implementation (e.g. cloud providers) should ignore Services that set this field. This field can only be set when creating or updating a Service to type 'LoadBalancer'. Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type.", - "internalTrafficPolicy": "InternalTrafficPolicy specifies if the cluster internal traffic should be routed to all endpoints or node-local endpoints only. \"Cluster\" routes internal traffic to a Service to all endpoints. \"Local\" routes traffic to node-local endpoints only, traffic is dropped if no node-local endpoints are ready. The default value is \"Cluster\".", + "internalTrafficPolicy": "InternalTrafficPolicy describes how nodes distribute service traffic they receive on the ClusterIP. If set to \"Local\", the proxy will assume that pods only want to talk to endpoints of the service on the same node as the pod, dropping the traffic if there are no local endpoints. The default value, \"Cluster\", uses the standard behavior of routing to all endpoints evenly (possibly modified by topology and other features).", } func (ServiceSpec) SwaggerDoc() map[string]string { @@ -2399,12 +2457,15 @@ func (TopologySelectorTerm) SwaggerDoc() map[string]string { } var map_TopologySpreadConstraint = map[string]string{ - "": "TopologySpreadConstraint specifies how to spread matching pods among the given topology.", - "maxSkew": "MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. ", - "topologyKey": "TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a \"bucket\", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes match the node selector. e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology. And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology. It's a required field.", - "whenUnsatisfiable": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n but giving higher precedence to topologies that would help reduce the\n skew.\nA constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: ", - "labelSelector": "LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain.", - "minDomains": "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\nFor example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: ", + "": "TopologySpreadConstraint specifies how to spread matching pods among the given topology.", + "maxSkew": "MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. ", + "topologyKey": "TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a \"bucket\", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology. And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology. It's a required field.", + "whenUnsatisfiable": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n but giving higher precedence to topologies that would help reduce the\n skew.\nA constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: ", + "labelSelector": "LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain.", + "minDomains": "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\nFor example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: ", + "nodeAffinityPolicy": "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\nIf this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", + "nodeTaintsPolicy": "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included.\n\nIf this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", + "matchLabelKeys": "MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. MatchLabelKeys cannot be set when LabelSelector isn't set. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.\n\nThis is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).", } func (TopologySpreadConstraint) SwaggerDoc() map[string]string { @@ -2422,6 +2483,17 @@ func (TypedLocalObjectReference) SwaggerDoc() map[string]string { return map_TypedLocalObjectReference } +var map_TypedObjectReference = map[string]string{ + "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "kind": "Kind is the type of resource being referenced", + "name": "Name is the name of resource being referenced", + "namespace": "Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", +} + +func (TypedObjectReference) SwaggerDoc() map[string]string { + return map_TypedObjectReference +} + var map_Volume = map[string]string{ "": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", "name": "name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", diff --git a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go index a3fbd14c6c5..bfb7e0bff54 100644 --- a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go @@ -243,6 +243,11 @@ func (in *CSIPersistentVolumeSource) DeepCopyInto(out *CSIPersistentVolumeSource *out = new(SecretReference) **out = **in } + if in.NodeExpandSecretRef != nil { + in, out := &in.NodeExpandSecretRef, &out.NodeExpandSecretRef + *out = new(SecretReference) + **out = **in + } return } @@ -414,6 +419,32 @@ func (in *CinderVolumeSource) DeepCopy() *CinderVolumeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClaimSource) DeepCopyInto(out *ClaimSource) { + *out = *in + if in.ResourceClaimName != nil { + in, out := &in.ResourceClaimName, &out.ResourceClaimName + *out = new(string) + **out = **in + } + if in.ResourceClaimTemplateName != nil { + in, out := &in.ResourceClaimTemplateName, &out.ResourceClaimTemplateName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClaimSource. +func (in *ClaimSource) DeepCopy() *ClaimSource { + if in == nil { + return nil + } + out := new(ClaimSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClientIPConfig) DeepCopyInto(out *ClientIPConfig) { *out = *in @@ -757,6 +788,11 @@ func (in *Container) DeepCopyInto(out *Container) { } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -844,6 +880,22 @@ func (in *ContainerPort) DeepCopy() *ContainerPort { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResizePolicy) DeepCopyInto(out *ContainerResizePolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResizePolicy. +func (in *ContainerResizePolicy) DeepCopy() *ContainerResizePolicy { + if in == nil { + return nil + } + out := new(ContainerResizePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerState) DeepCopyInto(out *ContainerState) { *out = *in @@ -936,6 +988,18 @@ func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) { *out = new(bool) **out = **in } + if in.AllocatedResources != nil { + in, out := &in.AllocatedResources, &out.AllocatedResources + *out = make(ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(ResourceRequirements) + (*in).DeepCopyInto(*out) + } return } @@ -1351,6 +1415,11 @@ func (in *EphemeralContainerCommon) DeepCopyInto(out *EphemeralContainerCommon) } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -2958,7 +3027,7 @@ func (in *PersistentVolumeClaimSpec) DeepCopyInto(out *PersistentVolumeClaimSpec } if in.DataSourceRef != nil { in, out := &in.DataSourceRef, &out.DataSourceRef - *out = new(TypedLocalObjectReference) + *out = new(TypedObjectReference) (*in).DeepCopyInto(*out) } return @@ -3721,6 +3790,39 @@ func (in *PodReadinessGate) DeepCopy() *PodReadinessGate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodResourceClaim) DeepCopyInto(out *PodResourceClaim) { + *out = *in + in.Source.DeepCopyInto(&out.Source) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodResourceClaim. +func (in *PodResourceClaim) DeepCopy() *PodResourceClaim { + if in == nil { + return nil + } + out := new(PodResourceClaim) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingGate) DeepCopyInto(out *PodSchedulingGate) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingGate. +func (in *PodSchedulingGate) DeepCopy() *PodSchedulingGate { + if in == nil { + return nil + } + out := new(PodSchedulingGate) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) { *out = *in @@ -3949,6 +4051,23 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { *out = new(PodOS) **out = **in } + if in.HostUsers != nil { + in, out := &in.HostUsers, &out.HostUsers + *out = new(bool) + **out = **in + } + if in.SchedulingGates != nil { + in, out := &in.SchedulingGates, &out.SchedulingGates + *out = make([]PodSchedulingGate, len(*in)) + copy(*out, *in) + } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]PodResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -4532,6 +4651,22 @@ func (in *ReplicationControllerStatus) DeepCopy() *ReplicationControllerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaim) DeepCopyInto(out *ResourceClaim) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaim. +func (in *ResourceClaim) DeepCopy() *ResourceClaim { + if in == nil { + return nil + } + out := new(ResourceClaim) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceFieldSelector) DeepCopyInto(out *ResourceFieldSelector) { *out = *in @@ -4712,6 +4847,11 @@ func (in *ResourceRequirements) DeepCopyInto(out *ResourceRequirements) { (*out)[key] = val.DeepCopy() } } + if in.Claims != nil { + in, out := &in.Claims, &out.Claims + *out = make([]ResourceClaim, len(*in)) + copy(*out, *in) + } return } @@ -5400,7 +5540,7 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { } if in.IPFamilyPolicy != nil { in, out := &in.IPFamilyPolicy, &out.IPFamilyPolicy - *out = new(IPFamilyPolicyType) + *out = new(IPFamilyPolicy) **out = **in } if in.AllocateLoadBalancerNodePorts != nil { @@ -5415,7 +5555,7 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { } if in.InternalTrafficPolicy != nil { in, out := &in.InternalTrafficPolicy, &out.InternalTrafficPolicy - *out = new(ServiceInternalTrafficPolicyType) + *out = new(ServiceInternalTrafficPolicy) **out = **in } return @@ -5649,6 +5789,21 @@ func (in *TopologySpreadConstraint) DeepCopyInto(out *TopologySpreadConstraint) *out = new(int32) **out = **in } + if in.NodeAffinityPolicy != nil { + in, out := &in.NodeAffinityPolicy, &out.NodeAffinityPolicy + *out = new(NodeInclusionPolicy) + **out = **in + } + if in.NodeTaintsPolicy != nil { + in, out := &in.NodeTaintsPolicy, &out.NodeTaintsPolicy + *out = new(NodeInclusionPolicy) + **out = **in + } + if in.MatchLabelKeys != nil { + in, out := &in.MatchLabelKeys, &out.MatchLabelKeys + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -5683,6 +5838,32 @@ func (in *TypedLocalObjectReference) DeepCopy() *TypedLocalObjectReference { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TypedObjectReference) DeepCopyInto(out *TypedObjectReference) { + *out = *in + if in.APIGroup != nil { + in, out := &in.APIGroup, &out.APIGroup + *out = new(string) + **out = **in + } + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TypedObjectReference. +func (in *TypedObjectReference) DeepCopy() *TypedObjectReference { + if in == nil { + return nil + } + out := new(TypedObjectReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Volume) DeepCopyInto(out *Volume) { *out = *in diff --git a/vendor/k8s.io/api/discovery/v1/generated.proto b/vendor/k8s.io/api/discovery/v1/generated.proto index 44d9d19e26e..b7150ef2cb8 100644 --- a/vendor/k8s.io/api/discovery/v1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1/generated.proto @@ -66,8 +66,7 @@ message Endpoint { map deprecatedTopology = 5; // nodeName represents the name of the Node hosting this endpoint. This can - // be used to determine endpoints local to a Node. This field can be enabled - // with the EndpointSliceNodeName feature gate. + // be used to determine endpoints local to a Node. // +optional optional string nodeName = 6; @@ -87,22 +86,22 @@ message EndpointConditions { // according to whatever system is managing the endpoint. A nil value // indicates an unknown state. In most cases consumers should interpret this // unknown state as ready. For compatibility reasons, ready should never be - // "true" for terminating endpoints. + // "true" for terminating endpoints, except when the normal readiness + // behavior is being explicitly overridden, for example when the associated + // Service has set the publishNotReadyAddresses flag. // +optional optional bool ready = 1; // serving is identical to ready except that it is set regardless of the // terminating state of endpoints. This condition should be set to true for // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. This field can be enabled with the - // EndpointSliceTerminatingCondition feature gate. + // the ready condition. // +optional optional bool serving = 2; // terminating indicates that this endpoint is terminating. A nil value // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. This field can be enabled - // with the EndpointSliceTerminatingCondition feature gate. + // to mean that the endpoint is not terminating. // +optional optional bool terminating = 3; } @@ -118,9 +117,8 @@ message EndpointHints { // EndpointPort represents a Port used by an EndpointSlice // +structType=atomic message EndpointPort { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. // Name must either be an empty string or pass DNS_LABEL validation: // * must be no more than 63 characters long. // * must consist of lower case alphanumeric characters or '-'. @@ -128,21 +126,28 @@ message EndpointPort { // Default is empty string. optional string name = 1; - // The IP protocol for this port. + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. optional string protocol = 2; - // The port number of the endpoint. + // port represents the port number of the endpoint. // If this is not specified, ports are not restricted and must be // interpreted in the context of the specific consumer. optional int32 port = 3; // The application protocol for this port. + // This is used as a hint for implementations to offer richer behavior for protocols that they understand. // This field follows standard Kubernetes label syntax. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional optional string appProtocol = 4; @@ -186,7 +191,7 @@ message EndpointSliceList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // List of endpoint slices + // items is the list of endpoint slices repeated EndpointSlice items = 2; } diff --git a/vendor/k8s.io/api/discovery/v1/types.go b/vendor/k8s.io/api/discovery/v1/types.go index 13591436d14..9b4daafca90 100644 --- a/vendor/k8s.io/api/discovery/v1/types.go +++ b/vendor/k8s.io/api/discovery/v1/types.go @@ -29,9 +29,11 @@ import ( // labels, which must be joined to produce the full set of endpoints. type EndpointSlice struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // addressType specifies the type of address carried by this EndpointSlice. // All addresses in this slice must be the same type. This field is // immutable after creation. The following address types are currently @@ -40,10 +42,12 @@ type EndpointSlice struct { // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` + // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic Endpoints []Endpoint `json:"endpoints" protobuf:"bytes,2,rep,name=endpoints"` + // ports specifies the list of network ports exposed by each endpoint in // this slice. Each port must have a unique name. When ports is empty, it // indicates that there are no defined ports. When a port is defined with a @@ -61,8 +65,10 @@ type AddressType string const ( // AddressTypeIPv4 represents an IPv4 Address. AddressTypeIPv4 = AddressType(v1.IPv4Protocol) + // AddressTypeIPv6 represents an IPv6 Address. AddressTypeIPv6 = AddressType(v1.IPv6Protocol) + // AddressTypeFQDN represents a FQDN. AddressTypeFQDN = AddressType("FQDN") ) @@ -77,8 +83,10 @@ type Endpoint struct { // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` + // conditions contains information about the current status of the endpoint. Conditions EndpointConditions `json:"conditions,omitempty" protobuf:"bytes,2,opt,name=conditions"` + // hostname of this endpoint. This field may be used by consumers of // endpoints to distinguish endpoints from each other (e.g. in DNS names). // Multiple endpoints which use the same hostname should be considered @@ -86,6 +94,7 @@ type Endpoint struct { // Label (RFC 1123) validation. // +optional Hostname *string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"` + // targetRef is a reference to a Kubernetes object that represents this // endpoint. // +optional @@ -101,13 +110,14 @@ type Endpoint struct { DeprecatedTopology map[string]string `json:"deprecatedTopology,omitempty" protobuf:"bytes,5,opt,name=deprecatedTopology"` // nodeName represents the name of the Node hosting this endpoint. This can - // be used to determine endpoints local to a Node. This field can be enabled - // with the EndpointSliceNodeName feature gate. + // be used to determine endpoints local to a Node. // +optional NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,6,opt,name=nodeName"` + // zone is the name of the Zone this endpoint exists in. // +optional Zone *string `json:"zone,omitempty" protobuf:"bytes,7,opt,name=zone"` + // hints contains information associated with how an endpoint should be // consumed. // +optional @@ -120,22 +130,22 @@ type EndpointConditions struct { // according to whatever system is managing the endpoint. A nil value // indicates an unknown state. In most cases consumers should interpret this // unknown state as ready. For compatibility reasons, ready should never be - // "true" for terminating endpoints. + // "true" for terminating endpoints, except when the normal readiness + // behavior is being explicitly overridden, for example when the associated + // Service has set the publishNotReadyAddresses flag. // +optional Ready *bool `json:"ready,omitempty" protobuf:"bytes,1,name=ready"` // serving is identical to ready except that it is set regardless of the // terminating state of endpoints. This condition should be set to true for // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. This field can be enabled with the - // EndpointSliceTerminatingCondition feature gate. + // the ready condition. // +optional Serving *bool `json:"serving,omitempty" protobuf:"bytes,2,name=serving"` // terminating indicates that this endpoint is terminating. A nil value // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. This field can be enabled - // with the EndpointSliceTerminatingCondition feature gate. + // to mean that the endpoint is not terminating. // +optional Terminating *bool `json:"terminating,omitempty" protobuf:"bytes,3,name=terminating"` } @@ -157,28 +167,37 @@ type ForZone struct { // EndpointPort represents a Port used by an EndpointSlice // +structType=atomic type EndpointPort struct { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. // Name must either be an empty string or pass DNS_LABEL validation: // * must be no more than 63 characters long. // * must consist of lower case alphanumeric characters or '-'. // * must start and end with an alphanumeric character. // Default is empty string. Name *string `json:"name,omitempty" protobuf:"bytes,1,name=name"` - // The IP protocol for this port. + + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,name=protocol"` - // The port number of the endpoint. + + // port represents the port number of the endpoint. // If this is not specified, ports are not restricted and must be // interpreted in the context of the specific consumer. Port *int32 `json:"port,omitempty" protobuf:"bytes,3,opt,name=port"` + // The application protocol for this port. + // This is used as a hint for implementations to offer richer behavior for protocols that they understand. // This field follows standard Kubernetes label syntax. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional AppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,4,name=appProtocol"` @@ -189,9 +208,11 @@ type EndpointPort struct { // EndpointSliceList represents a list of endpoint slices type EndpointSliceList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // List of endpoint slices + + // items is the list of endpoint slices Items []EndpointSlice `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go index bb3c8769fd6..c780c9573d1 100644 --- a/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Endpoint = map[string]string{ @@ -34,7 +34,7 @@ var map_Endpoint = map[string]string{ "hostname": "hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.", "targetRef": "targetRef is a reference to a Kubernetes object that represents this endpoint.", "deprecatedTopology": "deprecatedTopology contains topology information part of the v1beta1 API. This field is deprecated, and will be removed when the v1beta1 API is removed (no sooner than kubernetes v1.24). While this field can hold values, it is not writable through the v1 API, and any attempts to write to it will be silently ignored. Topology information can be found in the zone and nodeName fields instead.", - "nodeName": "nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.", + "nodeName": "nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node.", "zone": "zone is the name of the Zone this endpoint exists in.", "hints": "hints contains information associated with how an endpoint should be consumed.", } @@ -45,9 +45,9 @@ func (Endpoint) SwaggerDoc() map[string]string { var map_EndpointConditions = map[string]string{ "": "EndpointConditions represents the current condition of an endpoint.", - "ready": "ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be \"true\" for terminating endpoints.", - "serving": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.", - "terminating": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.", + "ready": "ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be \"true\" for terminating endpoints, except when the normal readiness behavior is being explicitly overridden, for example when the associated Service has set the publishNotReadyAddresses flag.", + "serving": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition.", + "terminating": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating.", } func (EndpointConditions) SwaggerDoc() map[string]string { @@ -65,10 +65,10 @@ func (EndpointHints) SwaggerDoc() map[string]string { var map_EndpointPort = map[string]string{ "": "EndpointPort represents a Port used by an EndpointSlice", - "name": "The name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.", - "protocol": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "port": "The port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "name": "name represents the name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.", + "protocol": "protocol represents the IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", + "port": "port represents the port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", + "appProtocol": "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -90,7 +90,7 @@ func (EndpointSlice) SwaggerDoc() map[string]string { var map_EndpointSliceList = map[string]string{ "": "EndpointSliceList represents a list of endpoint slices", "metadata": "Standard list metadata.", - "items": "List of endpoint slices", + "items": "items is the list of endpoint slices", } func (EndpointSliceList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/discovery/v1beta1/generated.proto b/vendor/k8s.io/api/discovery/v1beta1/generated.proto index 84bdf075af2..8b6c360b0e6 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1beta1/generated.proto @@ -73,8 +73,7 @@ message Endpoint { map topology = 5; // nodeName represents the name of the Node hosting this endpoint. This can - // be used to determine endpoints local to a Node. This field can be enabled - // with the EndpointSliceNodeName feature gate. + // be used to determine endpoints local to a Node. // +optional optional string nodeName = 6; @@ -98,15 +97,13 @@ message EndpointConditions { // serving is identical to ready except that it is set regardless of the // terminating state of endpoints. This condition should be set to true for // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. This field can be enabled with the - // EndpointSliceTerminatingCondition feature gate. + // the ready condition. // +optional optional bool serving = 2; // terminating indicates that this endpoint is terminating. A nil value // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. This field can be enabled - // with the EndpointSliceTerminatingCondition feature gate. + // to mean that the endpoint is not terminating. // +optional optional bool terminating = 3; } @@ -121,9 +118,8 @@ message EndpointHints { // EndpointPort represents a Port used by an EndpointSlice message EndpointPort { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. // Name must either be an empty string or pass DNS_LABEL validation: // * must be no more than 63 characters long. // * must consist of lower case alphanumeric characters or '-'. @@ -131,17 +127,17 @@ message EndpointPort { // Default is empty string. optional string name = 1; - // The IP protocol for this port. + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. optional string protocol = 2; - // The port number of the endpoint. + // port represents the port number of the endpoint. // If this is not specified, ports are not restricted and must be // interpreted in the context of the specific consumer. optional int32 port = 3; - // The application protocol for this port. + // appProtocol represents the application protocol for this port. // This field follows standard Kubernetes label syntax. // Un-prefixed names are reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). @@ -189,7 +185,7 @@ message EndpointSliceList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // List of endpoint slices + // items is the list of endpoint slices repeated EndpointSlice items = 2; } diff --git a/vendor/k8s.io/api/discovery/v1beta1/types.go b/vendor/k8s.io/api/discovery/v1beta1/types.go index 8620004f44f..f09f7f320cd 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/types.go +++ b/vendor/k8s.io/api/discovery/v1beta1/types.go @@ -33,9 +33,11 @@ import ( // labels, which must be joined to produce the full set of endpoints. type EndpointSlice struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // addressType specifies the type of address carried by this EndpointSlice. // All addresses in this slice must be the same type. This field is // immutable after creation. The following address types are currently @@ -44,10 +46,12 @@ type EndpointSlice struct { // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` + // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic Endpoints []Endpoint `json:"endpoints" protobuf:"bytes,2,rep,name=endpoints"` + // ports specifies the list of network ports exposed by each endpoint in // this slice. Each port must have a unique name. When ports is empty, it // indicates that there are no defined ports. When a port is defined with a @@ -64,8 +68,10 @@ type AddressType string const ( // AddressTypeIPv4 represents an IPv4 Address. AddressTypeIPv4 = AddressType(v1.IPv4Protocol) + // AddressTypeIPv6 represents an IPv6 Address. AddressTypeIPv6 = AddressType(v1.IPv6Protocol) + // AddressTypeFQDN represents a FQDN. AddressTypeFQDN = AddressType("FQDN") ) @@ -80,8 +86,10 @@ type Endpoint struct { // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` + // conditions contains information about the current status of the endpoint. Conditions EndpointConditions `json:"conditions,omitempty" protobuf:"bytes,2,opt,name=conditions"` + // hostname of this endpoint. This field may be used by consumers of // endpoints to distinguish endpoints from each other (e.g. in DNS names). // Multiple endpoints which use the same hostname should be considered @@ -89,10 +97,12 @@ type Endpoint struct { // Label (RFC 1123) validation. // +optional Hostname *string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"` + // targetRef is a reference to a Kubernetes object that represents this // endpoint. // +optional TargetRef *v1.ObjectReference `json:"targetRef,omitempty" protobuf:"bytes,4,opt,name=targetRef"` + // topology contains arbitrary topology information associated with the // endpoint. These key/value pairs must conform with the label format. // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels @@ -108,11 +118,12 @@ type Endpoint struct { // This field is deprecated and will be removed in future api versions. // +optional Topology map[string]string `json:"topology,omitempty" protobuf:"bytes,5,opt,name=topology"` + // nodeName represents the name of the Node hosting this endpoint. This can - // be used to determine endpoints local to a Node. This field can be enabled - // with the EndpointSliceNodeName feature gate. + // be used to determine endpoints local to a Node. // +optional NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,6,opt,name=nodeName"` + // hints contains information associated with how an endpoint should be // consumed. // +featureGate=TopologyAwareHints @@ -133,15 +144,13 @@ type EndpointConditions struct { // serving is identical to ready except that it is set regardless of the // terminating state of endpoints. This condition should be set to true for // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. This field can be enabled with the - // EndpointSliceTerminatingCondition feature gate. + // the ready condition. // +optional Serving *bool `json:"serving,omitempty" protobuf:"bytes,2,name=serving"` // terminating indicates that this endpoint is terminating. A nil value // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. This field can be enabled - // with the EndpointSliceTerminatingCondition feature gate. + // to mean that the endpoint is not terminating. // +optional Terminating *bool `json:"terminating,omitempty" protobuf:"bytes,3,name=terminating"` } @@ -162,24 +171,26 @@ type ForZone struct { // EndpointPort represents a Port used by an EndpointSlice type EndpointPort struct { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. // Name must either be an empty string or pass DNS_LABEL validation: // * must be no more than 63 characters long. // * must consist of lower case alphanumeric characters or '-'. // * must start and end with an alphanumeric character. // Default is empty string. Name *string `json:"name,omitempty" protobuf:"bytes,1,name=name"` - // The IP protocol for this port. + + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,name=protocol"` - // The port number of the endpoint. + + // port represents the port number of the endpoint. // If this is not specified, ports are not restricted and must be // interpreted in the context of the specific consumer. Port *int32 `json:"port,omitempty" protobuf:"bytes,3,opt,name=port"` - // The application protocol for this port. + + // appProtocol represents the application protocol for this port. // This field follows standard Kubernetes label syntax. // Un-prefixed names are reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). @@ -198,9 +209,11 @@ type EndpointPort struct { // EndpointSliceList represents a list of endpoint slices type EndpointSliceList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // List of endpoint slices + + // items is the list of endpoint slices Items []EndpointSlice `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go index 96e6d13ef7f..b1d4c306ccd 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Endpoint = map[string]string{ @@ -34,7 +34,7 @@ var map_Endpoint = map[string]string{ "hostname": "hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.", "targetRef": "targetRef is a reference to a Kubernetes object that represents this endpoint.", "topology": "topology contains arbitrary topology information associated with the endpoint. These key/value pairs must conform with the label format. https://kubernetes.io/docs/concepts/overview/working-with-objects/labels Topology may include a maximum of 16 key/value pairs. This includes, but is not limited to the following well known keys: * kubernetes.io/hostname: the value indicates the hostname of the node\n where the endpoint is located. This should match the corresponding\n node label.\n* topology.kubernetes.io/zone: the value indicates the zone where the\n endpoint is located. This should match the corresponding node label.\n* topology.kubernetes.io/region: the value indicates the region where the\n endpoint is located. This should match the corresponding node label.\nThis field is deprecated and will be removed in future api versions.", - "nodeName": "nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node. This field can be enabled with the EndpointSliceNodeName feature gate.", + "nodeName": "nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node.", "hints": "hints contains information associated with how an endpoint should be consumed.", } @@ -45,8 +45,8 @@ func (Endpoint) SwaggerDoc() map[string]string { var map_EndpointConditions = map[string]string{ "": "EndpointConditions represents the current condition of an endpoint.", "ready": "ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be \"true\" for terminating endpoints.", - "serving": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.", - "terminating": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating. This field can be enabled with the EndpointSliceTerminatingCondition feature gate.", + "serving": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition.", + "terminating": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating.", } func (EndpointConditions) SwaggerDoc() map[string]string { @@ -64,10 +64,10 @@ func (EndpointHints) SwaggerDoc() map[string]string { var map_EndpointPort = map[string]string{ "": "EndpointPort represents a Port used by an EndpointSlice", - "name": "The name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.", - "protocol": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "port": "The port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "name": "name represents the name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.", + "protocol": "protocol represents the IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", + "port": "port represents the port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", + "appProtocol": "appProtocol represents the application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -89,7 +89,7 @@ func (EndpointSlice) SwaggerDoc() map[string]string { var map_EndpointSliceList = map[string]string{ "": "EndpointSliceList represents a list of endpoint slices", "metadata": "Standard list metadata.", - "items": "List of endpoint slices", + "items": "items is the list of endpoint slices", } func (EndpointSliceList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go index 797da63bb72..44ac0c3bb64 100644 --- a/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ diff --git a/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go index 0e6bd5a83c5..e6c28a4f8c0 100644 --- a/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go b/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go index db6b56bb26d..863ebbc4a72 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go @@ -49,94 +49,10 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -func (m *AllowedCSIDriver) Reset() { *m = AllowedCSIDriver{} } -func (*AllowedCSIDriver) ProtoMessage() {} -func (*AllowedCSIDriver) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{0} -} -func (m *AllowedCSIDriver) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedCSIDriver) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *AllowedCSIDriver) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedCSIDriver.Merge(m, src) -} -func (m *AllowedCSIDriver) XXX_Size() int { - return m.Size() -} -func (m *AllowedCSIDriver) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedCSIDriver.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedCSIDriver proto.InternalMessageInfo - -func (m *AllowedFlexVolume) Reset() { *m = AllowedFlexVolume{} } -func (*AllowedFlexVolume) ProtoMessage() {} -func (*AllowedFlexVolume) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{1} -} -func (m *AllowedFlexVolume) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedFlexVolume) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *AllowedFlexVolume) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedFlexVolume.Merge(m, src) -} -func (m *AllowedFlexVolume) XXX_Size() int { - return m.Size() -} -func (m *AllowedFlexVolume) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedFlexVolume.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedFlexVolume proto.InternalMessageInfo - -func (m *AllowedHostPath) Reset() { *m = AllowedHostPath{} } -func (*AllowedHostPath) ProtoMessage() {} -func (*AllowedHostPath) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{2} -} -func (m *AllowedHostPath) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedHostPath) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *AllowedHostPath) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedHostPath.Merge(m, src) -} -func (m *AllowedHostPath) XXX_Size() int { - return m.Size() -} -func (m *AllowedHostPath) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedHostPath.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedHostPath proto.InternalMessageInfo - func (m *DaemonSet) Reset() { *m = DaemonSet{} } func (*DaemonSet) ProtoMessage() {} func (*DaemonSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{3} + return fileDescriptor_cdc93917efc28165, []int{0} } func (m *DaemonSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -164,7 +80,7 @@ var xxx_messageInfo_DaemonSet proto.InternalMessageInfo func (m *DaemonSetCondition) Reset() { *m = DaemonSetCondition{} } func (*DaemonSetCondition) ProtoMessage() {} func (*DaemonSetCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{4} + return fileDescriptor_cdc93917efc28165, []int{1} } func (m *DaemonSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -192,7 +108,7 @@ var xxx_messageInfo_DaemonSetCondition proto.InternalMessageInfo func (m *DaemonSetList) Reset() { *m = DaemonSetList{} } func (*DaemonSetList) ProtoMessage() {} func (*DaemonSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{5} + return fileDescriptor_cdc93917efc28165, []int{2} } func (m *DaemonSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -220,7 +136,7 @@ var xxx_messageInfo_DaemonSetList proto.InternalMessageInfo func (m *DaemonSetSpec) Reset() { *m = DaemonSetSpec{} } func (*DaemonSetSpec) ProtoMessage() {} func (*DaemonSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{6} + return fileDescriptor_cdc93917efc28165, []int{3} } func (m *DaemonSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -248,7 +164,7 @@ var xxx_messageInfo_DaemonSetSpec proto.InternalMessageInfo func (m *DaemonSetStatus) Reset() { *m = DaemonSetStatus{} } func (*DaemonSetStatus) ProtoMessage() {} func (*DaemonSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{7} + return fileDescriptor_cdc93917efc28165, []int{4} } func (m *DaemonSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -276,7 +192,7 @@ var xxx_messageInfo_DaemonSetStatus proto.InternalMessageInfo func (m *DaemonSetUpdateStrategy) Reset() { *m = DaemonSetUpdateStrategy{} } func (*DaemonSetUpdateStrategy) ProtoMessage() {} func (*DaemonSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{8} + return fileDescriptor_cdc93917efc28165, []int{5} } func (m *DaemonSetUpdateStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -304,7 +220,7 @@ var xxx_messageInfo_DaemonSetUpdateStrategy proto.InternalMessageInfo func (m *Deployment) Reset() { *m = Deployment{} } func (*Deployment) ProtoMessage() {} func (*Deployment) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{9} + return fileDescriptor_cdc93917efc28165, []int{6} } func (m *Deployment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -332,7 +248,7 @@ var xxx_messageInfo_Deployment proto.InternalMessageInfo func (m *DeploymentCondition) Reset() { *m = DeploymentCondition{} } func (*DeploymentCondition) ProtoMessage() {} func (*DeploymentCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{10} + return fileDescriptor_cdc93917efc28165, []int{7} } func (m *DeploymentCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -360,7 +276,7 @@ var xxx_messageInfo_DeploymentCondition proto.InternalMessageInfo func (m *DeploymentList) Reset() { *m = DeploymentList{} } func (*DeploymentList) ProtoMessage() {} func (*DeploymentList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{11} + return fileDescriptor_cdc93917efc28165, []int{8} } func (m *DeploymentList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -388,7 +304,7 @@ var xxx_messageInfo_DeploymentList proto.InternalMessageInfo func (m *DeploymentRollback) Reset() { *m = DeploymentRollback{} } func (*DeploymentRollback) ProtoMessage() {} func (*DeploymentRollback) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{12} + return fileDescriptor_cdc93917efc28165, []int{9} } func (m *DeploymentRollback) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -416,7 +332,7 @@ var xxx_messageInfo_DeploymentRollback proto.InternalMessageInfo func (m *DeploymentSpec) Reset() { *m = DeploymentSpec{} } func (*DeploymentSpec) ProtoMessage() {} func (*DeploymentSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{13} + return fileDescriptor_cdc93917efc28165, []int{10} } func (m *DeploymentSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -444,7 +360,7 @@ var xxx_messageInfo_DeploymentSpec proto.InternalMessageInfo func (m *DeploymentStatus) Reset() { *m = DeploymentStatus{} } func (*DeploymentStatus) ProtoMessage() {} func (*DeploymentStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{14} + return fileDescriptor_cdc93917efc28165, []int{11} } func (m *DeploymentStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -472,7 +388,7 @@ var xxx_messageInfo_DeploymentStatus proto.InternalMessageInfo func (m *DeploymentStrategy) Reset() { *m = DeploymentStrategy{} } func (*DeploymentStrategy) ProtoMessage() {} func (*DeploymentStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{15} + return fileDescriptor_cdc93917efc28165, []int{12} } func (m *DeploymentStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,38 +413,10 @@ func (m *DeploymentStrategy) XXX_DiscardUnknown() { var xxx_messageInfo_DeploymentStrategy proto.InternalMessageInfo -func (m *FSGroupStrategyOptions) Reset() { *m = FSGroupStrategyOptions{} } -func (*FSGroupStrategyOptions) ProtoMessage() {} -func (*FSGroupStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{16} -} -func (m *FSGroupStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *FSGroupStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *FSGroupStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_FSGroupStrategyOptions.Merge(m, src) -} -func (m *FSGroupStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *FSGroupStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_FSGroupStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_FSGroupStrategyOptions proto.InternalMessageInfo - func (m *HTTPIngressPath) Reset() { *m = HTTPIngressPath{} } func (*HTTPIngressPath) ProtoMessage() {} func (*HTTPIngressPath) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{17} + return fileDescriptor_cdc93917efc28165, []int{13} } func (m *HTTPIngressPath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +444,7 @@ var xxx_messageInfo_HTTPIngressPath proto.InternalMessageInfo func (m *HTTPIngressRuleValue) Reset() { *m = HTTPIngressRuleValue{} } func (*HTTPIngressRuleValue) ProtoMessage() {} func (*HTTPIngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{18} + return fileDescriptor_cdc93917efc28165, []int{14} } func (m *HTTPIngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -581,66 +469,10 @@ func (m *HTTPIngressRuleValue) XXX_DiscardUnknown() { var xxx_messageInfo_HTTPIngressRuleValue proto.InternalMessageInfo -func (m *HostPortRange) Reset() { *m = HostPortRange{} } -func (*HostPortRange) ProtoMessage() {} -func (*HostPortRange) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{19} -} -func (m *HostPortRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HostPortRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *HostPortRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_HostPortRange.Merge(m, src) -} -func (m *HostPortRange) XXX_Size() int { - return m.Size() -} -func (m *HostPortRange) XXX_DiscardUnknown() { - xxx_messageInfo_HostPortRange.DiscardUnknown(m) -} - -var xxx_messageInfo_HostPortRange proto.InternalMessageInfo - -func (m *IDRange) Reset() { *m = IDRange{} } -func (*IDRange) ProtoMessage() {} -func (*IDRange) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{20} -} -func (m *IDRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *IDRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *IDRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_IDRange.Merge(m, src) -} -func (m *IDRange) XXX_Size() int { - return m.Size() -} -func (m *IDRange) XXX_DiscardUnknown() { - xxx_messageInfo_IDRange.DiscardUnknown(m) -} - -var xxx_messageInfo_IDRange proto.InternalMessageInfo - func (m *IPBlock) Reset() { *m = IPBlock{} } func (*IPBlock) ProtoMessage() {} func (*IPBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{21} + return fileDescriptor_cdc93917efc28165, []int{15} } func (m *IPBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -668,7 +500,7 @@ var xxx_messageInfo_IPBlock proto.InternalMessageInfo func (m *Ingress) Reset() { *m = Ingress{} } func (*Ingress) ProtoMessage() {} func (*Ingress) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{22} + return fileDescriptor_cdc93917efc28165, []int{16} } func (m *Ingress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +528,7 @@ var xxx_messageInfo_Ingress proto.InternalMessageInfo func (m *IngressBackend) Reset() { *m = IngressBackend{} } func (*IngressBackend) ProtoMessage() {} func (*IngressBackend) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{23} + return fileDescriptor_cdc93917efc28165, []int{17} } func (m *IngressBackend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -724,7 +556,7 @@ var xxx_messageInfo_IngressBackend proto.InternalMessageInfo func (m *IngressList) Reset() { *m = IngressList{} } func (*IngressList) ProtoMessage() {} func (*IngressList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{24} + return fileDescriptor_cdc93917efc28165, []int{18} } func (m *IngressList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -749,10 +581,94 @@ func (m *IngressList) XXX_DiscardUnknown() { var xxx_messageInfo_IngressList proto.InternalMessageInfo +func (m *IngressLoadBalancerIngress) Reset() { *m = IngressLoadBalancerIngress{} } +func (*IngressLoadBalancerIngress) ProtoMessage() {} +func (*IngressLoadBalancerIngress) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{19} +} +func (m *IngressLoadBalancerIngress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerIngress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerIngress) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerIngress.Merge(m, src) +} +func (m *IngressLoadBalancerIngress) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerIngress) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerIngress.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerIngress proto.InternalMessageInfo + +func (m *IngressLoadBalancerStatus) Reset() { *m = IngressLoadBalancerStatus{} } +func (*IngressLoadBalancerStatus) ProtoMessage() {} +func (*IngressLoadBalancerStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{20} +} +func (m *IngressLoadBalancerStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerStatus.Merge(m, src) +} +func (m *IngressLoadBalancerStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerStatus proto.InternalMessageInfo + +func (m *IngressPortStatus) Reset() { *m = IngressPortStatus{} } +func (*IngressPortStatus) ProtoMessage() {} +func (*IngressPortStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{21} +} +func (m *IngressPortStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressPortStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressPortStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressPortStatus.Merge(m, src) +} +func (m *IngressPortStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressPortStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressPortStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressPortStatus proto.InternalMessageInfo + func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} func (*IngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{25} + return fileDescriptor_cdc93917efc28165, []int{22} } func (m *IngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -780,7 +696,7 @@ var xxx_messageInfo_IngressRule proto.InternalMessageInfo func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} func (*IngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{26} + return fileDescriptor_cdc93917efc28165, []int{23} } func (m *IngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -808,7 +724,7 @@ var xxx_messageInfo_IngressRuleValue proto.InternalMessageInfo func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} func (*IngressSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{27} + return fileDescriptor_cdc93917efc28165, []int{24} } func (m *IngressSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -836,7 +752,7 @@ var xxx_messageInfo_IngressSpec proto.InternalMessageInfo func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} func (*IngressStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{28} + return fileDescriptor_cdc93917efc28165, []int{25} } func (m *IngressStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -864,7 +780,7 @@ var xxx_messageInfo_IngressStatus proto.InternalMessageInfo func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} func (*IngressTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{29} + return fileDescriptor_cdc93917efc28165, []int{26} } func (m *IngressTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,7 +808,7 @@ var xxx_messageInfo_IngressTLS proto.InternalMessageInfo func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} func (*NetworkPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{30} + return fileDescriptor_cdc93917efc28165, []int{27} } func (m *NetworkPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +836,7 @@ var xxx_messageInfo_NetworkPolicy proto.InternalMessageInfo func (m *NetworkPolicyEgressRule) Reset() { *m = NetworkPolicyEgressRule{} } func (*NetworkPolicyEgressRule) ProtoMessage() {} func (*NetworkPolicyEgressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{31} + return fileDescriptor_cdc93917efc28165, []int{28} } func (m *NetworkPolicyEgressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -948,7 +864,7 @@ var xxx_messageInfo_NetworkPolicyEgressRule proto.InternalMessageInfo func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } func (*NetworkPolicyIngressRule) ProtoMessage() {} func (*NetworkPolicyIngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{32} + return fileDescriptor_cdc93917efc28165, []int{29} } func (m *NetworkPolicyIngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -976,7 +892,7 @@ var xxx_messageInfo_NetworkPolicyIngressRule proto.InternalMessageInfo func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} func (*NetworkPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{33} + return fileDescriptor_cdc93917efc28165, []int{30} } func (m *NetworkPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1004,7 +920,7 @@ var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{34} + return fileDescriptor_cdc93917efc28165, []int{31} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1032,7 +948,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } func (*NetworkPolicyPort) ProtoMessage() {} func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{35} + return fileDescriptor_cdc93917efc28165, []int{32} } func (m *NetworkPolicyPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1060,7 +976,7 @@ var xxx_messageInfo_NetworkPolicyPort proto.InternalMessageInfo func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } func (*NetworkPolicySpec) ProtoMessage() {} func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{36} + return fileDescriptor_cdc93917efc28165, []int{33} } func (m *NetworkPolicySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1088,7 +1004,7 @@ var xxx_messageInfo_NetworkPolicySpec proto.InternalMessageInfo func (m *NetworkPolicyStatus) Reset() { *m = NetworkPolicyStatus{} } func (*NetworkPolicyStatus) ProtoMessage() {} func (*NetworkPolicyStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{37} + return fileDescriptor_cdc93917efc28165, []int{34} } func (m *NetworkPolicyStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1113,15 +1029,15 @@ func (m *NetworkPolicyStatus) XXX_DiscardUnknown() { var xxx_messageInfo_NetworkPolicyStatus proto.InternalMessageInfo -func (m *PodSecurityPolicy) Reset() { *m = PodSecurityPolicy{} } -func (*PodSecurityPolicy) ProtoMessage() {} -func (*PodSecurityPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{38} +func (m *ReplicaSet) Reset() { *m = ReplicaSet{} } +func (*ReplicaSet) ProtoMessage() {} +func (*ReplicaSet) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{35} } -func (m *PodSecurityPolicy) XXX_Unmarshal(b []byte) error { +func (m *ReplicaSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSecurityPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ReplicaSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -1129,27 +1045,27 @@ func (m *PodSecurityPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, e } return b[:n], nil } -func (m *PodSecurityPolicy) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicy.Merge(m, src) +func (m *ReplicaSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReplicaSet.Merge(m, src) } -func (m *PodSecurityPolicy) XXX_Size() int { +func (m *ReplicaSet) XXX_Size() int { return m.Size() } -func (m *PodSecurityPolicy) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicy.DiscardUnknown(m) +func (m *ReplicaSet) XXX_DiscardUnknown() { + xxx_messageInfo_ReplicaSet.DiscardUnknown(m) } -var xxx_messageInfo_PodSecurityPolicy proto.InternalMessageInfo +var xxx_messageInfo_ReplicaSet proto.InternalMessageInfo -func (m *PodSecurityPolicyList) Reset() { *m = PodSecurityPolicyList{} } -func (*PodSecurityPolicyList) ProtoMessage() {} -func (*PodSecurityPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{39} +func (m *ReplicaSetCondition) Reset() { *m = ReplicaSetCondition{} } +func (*ReplicaSetCondition) ProtoMessage() {} +func (*ReplicaSetCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{36} } -func (m *PodSecurityPolicyList) XXX_Unmarshal(b []byte) error { +func (m *ReplicaSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSecurityPolicyList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ReplicaSetCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -1157,27 +1073,27 @@ func (m *PodSecurityPolicyList) XXX_Marshal(b []byte, deterministic bool) ([]byt } return b[:n], nil } -func (m *PodSecurityPolicyList) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicyList.Merge(m, src) +func (m *ReplicaSetCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReplicaSetCondition.Merge(m, src) } -func (m *PodSecurityPolicyList) XXX_Size() int { +func (m *ReplicaSetCondition) XXX_Size() int { return m.Size() } -func (m *PodSecurityPolicyList) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicyList.DiscardUnknown(m) +func (m *ReplicaSetCondition) XXX_DiscardUnknown() { + xxx_messageInfo_ReplicaSetCondition.DiscardUnknown(m) } -var xxx_messageInfo_PodSecurityPolicyList proto.InternalMessageInfo +var xxx_messageInfo_ReplicaSetCondition proto.InternalMessageInfo -func (m *PodSecurityPolicySpec) Reset() { *m = PodSecurityPolicySpec{} } -func (*PodSecurityPolicySpec) ProtoMessage() {} -func (*PodSecurityPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{40} +func (m *ReplicaSetList) Reset() { *m = ReplicaSetList{} } +func (*ReplicaSetList) ProtoMessage() {} +func (*ReplicaSetList) Descriptor() ([]byte, []int) { + return fileDescriptor_cdc93917efc28165, []int{37} } -func (m *PodSecurityPolicySpec) XXX_Unmarshal(b []byte) error { +func (m *ReplicaSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSecurityPolicySpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ReplicaSetList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -1185,106 +1101,22 @@ func (m *PodSecurityPolicySpec) XXX_Marshal(b []byte, deterministic bool) ([]byt } return b[:n], nil } -func (m *PodSecurityPolicySpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicySpec.Merge(m, src) +func (m *ReplicaSetList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReplicaSetList.Merge(m, src) } -func (m *PodSecurityPolicySpec) XXX_Size() int { +func (m *ReplicaSetList) XXX_Size() int { return m.Size() } -func (m *PodSecurityPolicySpec) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicySpec.DiscardUnknown(m) +func (m *ReplicaSetList) XXX_DiscardUnknown() { + xxx_messageInfo_ReplicaSetList.DiscardUnknown(m) } -var xxx_messageInfo_PodSecurityPolicySpec proto.InternalMessageInfo - -func (m *ReplicaSet) Reset() { *m = ReplicaSet{} } -func (*ReplicaSet) ProtoMessage() {} -func (*ReplicaSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{41} -} -func (m *ReplicaSet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ReplicaSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *ReplicaSet) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReplicaSet.Merge(m, src) -} -func (m *ReplicaSet) XXX_Size() int { - return m.Size() -} -func (m *ReplicaSet) XXX_DiscardUnknown() { - xxx_messageInfo_ReplicaSet.DiscardUnknown(m) -} - -var xxx_messageInfo_ReplicaSet proto.InternalMessageInfo - -func (m *ReplicaSetCondition) Reset() { *m = ReplicaSetCondition{} } -func (*ReplicaSetCondition) ProtoMessage() {} -func (*ReplicaSetCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{42} -} -func (m *ReplicaSetCondition) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ReplicaSetCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *ReplicaSetCondition) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReplicaSetCondition.Merge(m, src) -} -func (m *ReplicaSetCondition) XXX_Size() int { - return m.Size() -} -func (m *ReplicaSetCondition) XXX_DiscardUnknown() { - xxx_messageInfo_ReplicaSetCondition.DiscardUnknown(m) -} - -var xxx_messageInfo_ReplicaSetCondition proto.InternalMessageInfo - -func (m *ReplicaSetList) Reset() { *m = ReplicaSetList{} } -func (*ReplicaSetList) ProtoMessage() {} -func (*ReplicaSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{43} -} -func (m *ReplicaSetList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ReplicaSetList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *ReplicaSetList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReplicaSetList.Merge(m, src) -} -func (m *ReplicaSetList) XXX_Size() int { - return m.Size() -} -func (m *ReplicaSetList) XXX_DiscardUnknown() { - xxx_messageInfo_ReplicaSetList.DiscardUnknown(m) -} - -var xxx_messageInfo_ReplicaSetList proto.InternalMessageInfo +var xxx_messageInfo_ReplicaSetList proto.InternalMessageInfo func (m *ReplicaSetSpec) Reset() { *m = ReplicaSetSpec{} } func (*ReplicaSetSpec) ProtoMessage() {} func (*ReplicaSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{44} + return fileDescriptor_cdc93917efc28165, []int{38} } func (m *ReplicaSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1312,7 +1144,7 @@ var xxx_messageInfo_ReplicaSetSpec proto.InternalMessageInfo func (m *ReplicaSetStatus) Reset() { *m = ReplicaSetStatus{} } func (*ReplicaSetStatus) ProtoMessage() {} func (*ReplicaSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{45} + return fileDescriptor_cdc93917efc28165, []int{39} } func (m *ReplicaSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1340,7 +1172,7 @@ var xxx_messageInfo_ReplicaSetStatus proto.InternalMessageInfo func (m *RollbackConfig) Reset() { *m = RollbackConfig{} } func (*RollbackConfig) ProtoMessage() {} func (*RollbackConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{46} + return fileDescriptor_cdc93917efc28165, []int{40} } func (m *RollbackConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1368,7 +1200,7 @@ var xxx_messageInfo_RollbackConfig proto.InternalMessageInfo func (m *RollingUpdateDaemonSet) Reset() { *m = RollingUpdateDaemonSet{} } func (*RollingUpdateDaemonSet) ProtoMessage() {} func (*RollingUpdateDaemonSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{47} + return fileDescriptor_cdc93917efc28165, []int{41} } func (m *RollingUpdateDaemonSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1396,7 +1228,7 @@ var xxx_messageInfo_RollingUpdateDaemonSet proto.InternalMessageInfo func (m *RollingUpdateDeployment) Reset() { *m = RollingUpdateDeployment{} } func (*RollingUpdateDeployment) ProtoMessage() {} func (*RollingUpdateDeployment) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{48} + return fileDescriptor_cdc93917efc28165, []int{42} } func (m *RollingUpdateDeployment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1421,122 +1253,10 @@ func (m *RollingUpdateDeployment) XXX_DiscardUnknown() { var xxx_messageInfo_RollingUpdateDeployment proto.InternalMessageInfo -func (m *RunAsGroupStrategyOptions) Reset() { *m = RunAsGroupStrategyOptions{} } -func (*RunAsGroupStrategyOptions) ProtoMessage() {} -func (*RunAsGroupStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{49} -} -func (m *RunAsGroupStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RunAsGroupStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *RunAsGroupStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunAsGroupStrategyOptions.Merge(m, src) -} -func (m *RunAsGroupStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RunAsGroupStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RunAsGroupStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RunAsGroupStrategyOptions proto.InternalMessageInfo - -func (m *RunAsUserStrategyOptions) Reset() { *m = RunAsUserStrategyOptions{} } -func (*RunAsUserStrategyOptions) ProtoMessage() {} -func (*RunAsUserStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{50} -} -func (m *RunAsUserStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RunAsUserStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *RunAsUserStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunAsUserStrategyOptions.Merge(m, src) -} -func (m *RunAsUserStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RunAsUserStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RunAsUserStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RunAsUserStrategyOptions proto.InternalMessageInfo - -func (m *RuntimeClassStrategyOptions) Reset() { *m = RuntimeClassStrategyOptions{} } -func (*RuntimeClassStrategyOptions) ProtoMessage() {} -func (*RuntimeClassStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{51} -} -func (m *RuntimeClassStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RuntimeClassStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *RuntimeClassStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RuntimeClassStrategyOptions.Merge(m, src) -} -func (m *RuntimeClassStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RuntimeClassStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RuntimeClassStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RuntimeClassStrategyOptions proto.InternalMessageInfo - -func (m *SELinuxStrategyOptions) Reset() { *m = SELinuxStrategyOptions{} } -func (*SELinuxStrategyOptions) ProtoMessage() {} -func (*SELinuxStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{52} -} -func (m *SELinuxStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SELinuxStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *SELinuxStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_SELinuxStrategyOptions.Merge(m, src) -} -func (m *SELinuxStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *SELinuxStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_SELinuxStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_SELinuxStrategyOptions proto.InternalMessageInfo - func (m *Scale) Reset() { *m = Scale{} } func (*Scale) ProtoMessage() {} func (*Scale) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{53} + return fileDescriptor_cdc93917efc28165, []int{43} } func (m *Scale) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1564,7 +1284,7 @@ var xxx_messageInfo_Scale proto.InternalMessageInfo func (m *ScaleSpec) Reset() { *m = ScaleSpec{} } func (*ScaleSpec) ProtoMessage() {} func (*ScaleSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{54} + return fileDescriptor_cdc93917efc28165, []int{44} } func (m *ScaleSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1592,7 +1312,7 @@ var xxx_messageInfo_ScaleSpec proto.InternalMessageInfo func (m *ScaleStatus) Reset() { *m = ScaleStatus{} } func (*ScaleStatus) ProtoMessage() {} func (*ScaleStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{55} + return fileDescriptor_cdc93917efc28165, []int{45} } func (m *ScaleStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1617,38 +1337,7 @@ func (m *ScaleStatus) XXX_DiscardUnknown() { var xxx_messageInfo_ScaleStatus proto.InternalMessageInfo -func (m *SupplementalGroupsStrategyOptions) Reset() { *m = SupplementalGroupsStrategyOptions{} } -func (*SupplementalGroupsStrategyOptions) ProtoMessage() {} -func (*SupplementalGroupsStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{56} -} -func (m *SupplementalGroupsStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SupplementalGroupsStrategyOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *SupplementalGroupsStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_SupplementalGroupsStrategyOptions.Merge(m, src) -} -func (m *SupplementalGroupsStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *SupplementalGroupsStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_SupplementalGroupsStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_SupplementalGroupsStrategyOptions proto.InternalMessageInfo - func init() { - proto.RegisterType((*AllowedCSIDriver)(nil), "k8s.io.api.extensions.v1beta1.AllowedCSIDriver") - proto.RegisterType((*AllowedFlexVolume)(nil), "k8s.io.api.extensions.v1beta1.AllowedFlexVolume") - proto.RegisterType((*AllowedHostPath)(nil), "k8s.io.api.extensions.v1beta1.AllowedHostPath") proto.RegisterType((*DaemonSet)(nil), "k8s.io.api.extensions.v1beta1.DaemonSet") proto.RegisterType((*DaemonSetCondition)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetCondition") proto.RegisterType((*DaemonSetList)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetList") @@ -1663,15 +1352,15 @@ func init() { proto.RegisterType((*DeploymentSpec)(nil), "k8s.io.api.extensions.v1beta1.DeploymentSpec") proto.RegisterType((*DeploymentStatus)(nil), "k8s.io.api.extensions.v1beta1.DeploymentStatus") proto.RegisterType((*DeploymentStrategy)(nil), "k8s.io.api.extensions.v1beta1.DeploymentStrategy") - proto.RegisterType((*FSGroupStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.FSGroupStrategyOptions") proto.RegisterType((*HTTPIngressPath)(nil), "k8s.io.api.extensions.v1beta1.HTTPIngressPath") proto.RegisterType((*HTTPIngressRuleValue)(nil), "k8s.io.api.extensions.v1beta1.HTTPIngressRuleValue") - proto.RegisterType((*HostPortRange)(nil), "k8s.io.api.extensions.v1beta1.HostPortRange") - proto.RegisterType((*IDRange)(nil), "k8s.io.api.extensions.v1beta1.IDRange") proto.RegisterType((*IPBlock)(nil), "k8s.io.api.extensions.v1beta1.IPBlock") proto.RegisterType((*Ingress)(nil), "k8s.io.api.extensions.v1beta1.Ingress") proto.RegisterType((*IngressBackend)(nil), "k8s.io.api.extensions.v1beta1.IngressBackend") proto.RegisterType((*IngressList)(nil), "k8s.io.api.extensions.v1beta1.IngressList") + proto.RegisterType((*IngressLoadBalancerIngress)(nil), "k8s.io.api.extensions.v1beta1.IngressLoadBalancerIngress") + proto.RegisterType((*IngressLoadBalancerStatus)(nil), "k8s.io.api.extensions.v1beta1.IngressLoadBalancerStatus") + proto.RegisterType((*IngressPortStatus)(nil), "k8s.io.api.extensions.v1beta1.IngressPortStatus") proto.RegisterType((*IngressRule)(nil), "k8s.io.api.extensions.v1beta1.IngressRule") proto.RegisterType((*IngressRuleValue)(nil), "k8s.io.api.extensions.v1beta1.IngressRuleValue") proto.RegisterType((*IngressSpec)(nil), "k8s.io.api.extensions.v1beta1.IngressSpec") @@ -1685,9 +1374,6 @@ func init() { proto.RegisterType((*NetworkPolicyPort)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicyPort") proto.RegisterType((*NetworkPolicySpec)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicySpec") proto.RegisterType((*NetworkPolicyStatus)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicyStatus") - proto.RegisterType((*PodSecurityPolicy)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicy") - proto.RegisterType((*PodSecurityPolicyList)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicyList") - proto.RegisterType((*PodSecurityPolicySpec)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicySpec") proto.RegisterType((*ReplicaSet)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSet") proto.RegisterType((*ReplicaSetCondition)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSetCondition") proto.RegisterType((*ReplicaSetList)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSetList") @@ -1696,15 +1382,10 @@ func init() { proto.RegisterType((*RollbackConfig)(nil), "k8s.io.api.extensions.v1beta1.RollbackConfig") proto.RegisterType((*RollingUpdateDaemonSet)(nil), "k8s.io.api.extensions.v1beta1.RollingUpdateDaemonSet") proto.RegisterType((*RollingUpdateDeployment)(nil), "k8s.io.api.extensions.v1beta1.RollingUpdateDeployment") - proto.RegisterType((*RunAsGroupStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RunAsGroupStrategyOptions") - proto.RegisterType((*RunAsUserStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RunAsUserStrategyOptions") - proto.RegisterType((*RuntimeClassStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RuntimeClassStrategyOptions") - proto.RegisterType((*SELinuxStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.SELinuxStrategyOptions") proto.RegisterType((*Scale)(nil), "k8s.io.api.extensions.v1beta1.Scale") proto.RegisterType((*ScaleSpec)(nil), "k8s.io.api.extensions.v1beta1.ScaleSpec") proto.RegisterType((*ScaleStatus)(nil), "k8s.io.api.extensions.v1beta1.ScaleStatus") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.extensions.v1beta1.ScaleStatus.SelectorEntry") - proto.RegisterType((*SupplementalGroupsStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.SupplementalGroupsStrategyOptions") } func init() { @@ -1712,337 +1393,188 @@ func init() { } var fileDescriptor_cdc93917efc28165 = []byte{ - // 3797 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4d, 0x6c, 0x1c, 0xc9, - 0x75, 0x56, 0xcf, 0x0c, 0x39, 0xc3, 0x47, 0xf1, 0xaf, 0x48, 0x91, 0x63, 0xc9, 0xe2, 0xc8, 0xbd, - 0x88, 0xa2, 0xdd, 0x68, 0x67, 0x56, 0x5c, 0xad, 0xbc, 0x59, 0x21, 0xf6, 0x72, 0x48, 0x51, 0xa2, - 0xc3, 0x9f, 0xd9, 0x1a, 0x52, 0x36, 0x16, 0x59, 0x67, 0x9b, 0x3d, 0xc5, 0x61, 0x2f, 0x7b, 0xba, - 0xdb, 0x5d, 0x3d, 0x34, 0x27, 0xc8, 0x21, 0x87, 0x5c, 0x0c, 0x04, 0x48, 0x2e, 0x4e, 0x72, 0xcc, - 0x22, 0x40, 0x6e, 0x41, 0x8e, 0xc9, 0xc1, 0x30, 0x12, 0xc4, 0x01, 0x84, 0xc0, 0x09, 0x0c, 0xe4, - 0x10, 0x9f, 0x88, 0x2c, 0x7d, 0x0a, 0x72, 0xca, 0x2d, 0xd0, 0x29, 0xa8, 0xea, 0xea, 0xff, 0x6e, - 0x4e, 0x0f, 0x2d, 0x11, 0xd9, 0xc0, 0x27, 0x69, 0xea, 0xbd, 0xf7, 0xbd, 0x57, 0x55, 0xaf, 0xde, - 0x7b, 0x55, 0xfd, 0x08, 0x1b, 0xc7, 0xef, 0xd3, 0xba, 0x66, 0x36, 0x8e, 0xfb, 0x07, 0xc4, 0x36, - 0x88, 0x43, 0x68, 0xe3, 0x84, 0x18, 0x1d, 0xd3, 0x6e, 0x08, 0x82, 0x62, 0x69, 0x0d, 0x72, 0xea, - 0x10, 0x83, 0x6a, 0xa6, 0x41, 0x1b, 0x27, 0x0f, 0x0e, 0x88, 0xa3, 0x3c, 0x68, 0x74, 0x89, 0x41, - 0x6c, 0xc5, 0x21, 0x9d, 0xba, 0x65, 0x9b, 0x8e, 0x89, 0x6e, 0xbb, 0xec, 0x75, 0xc5, 0xd2, 0xea, - 0x01, 0x7b, 0x5d, 0xb0, 0xdf, 0x7c, 0xbb, 0xab, 0x39, 0x47, 0xfd, 0x83, 0xba, 0x6a, 0xf6, 0x1a, - 0x5d, 0xb3, 0x6b, 0x36, 0xb8, 0xd4, 0x41, 0xff, 0x90, 0xff, 0xe2, 0x3f, 0xf8, 0xff, 0x5c, 0xb4, - 0x9b, 0x72, 0x48, 0xb9, 0x6a, 0xda, 0xa4, 0x71, 0x92, 0xd0, 0x78, 0xf3, 0x61, 0xc0, 0xd3, 0x53, - 0xd4, 0x23, 0xcd, 0x20, 0xf6, 0xa0, 0x61, 0x1d, 0x77, 0xd9, 0x00, 0x6d, 0xf4, 0x88, 0xa3, 0xa4, - 0x49, 0x35, 0xb2, 0xa4, 0xec, 0xbe, 0xe1, 0x68, 0x3d, 0x92, 0x10, 0x78, 0x34, 0x4c, 0x80, 0xaa, - 0x47, 0xa4, 0xa7, 0x24, 0xe4, 0xde, 0xcd, 0x92, 0xeb, 0x3b, 0x9a, 0xde, 0xd0, 0x0c, 0x87, 0x3a, - 0x76, 0x5c, 0x48, 0x7e, 0x08, 0xb3, 0xab, 0xba, 0x6e, 0x7e, 0x9f, 0x74, 0xd6, 0xda, 0x9b, 0xeb, - 0xb6, 0x76, 0x42, 0x6c, 0x74, 0x07, 0x4a, 0x86, 0xd2, 0x23, 0x55, 0xe9, 0x8e, 0x74, 0x6f, 0xa2, - 0x79, 0xfd, 0xc5, 0x59, 0xed, 0xda, 0xf9, 0x59, 0xad, 0xb4, 0xa3, 0xf4, 0x08, 0xe6, 0x14, 0xf9, - 0x31, 0xcc, 0x09, 0xa9, 0x0d, 0x9d, 0x9c, 0x3e, 0x37, 0xf5, 0x7e, 0x8f, 0xa0, 0xbb, 0x30, 0xde, - 0xe1, 0x00, 0x42, 0x70, 0x5a, 0x08, 0x8e, 0xbb, 0xb0, 0x58, 0x50, 0x65, 0x0a, 0x33, 0x42, 0xf8, - 0x99, 0x49, 0x9d, 0x96, 0xe2, 0x1c, 0xa1, 0x15, 0x00, 0x4b, 0x71, 0x8e, 0x5a, 0x36, 0x39, 0xd4, - 0x4e, 0x85, 0x38, 0x12, 0xe2, 0xd0, 0xf2, 0x29, 0x38, 0xc4, 0x85, 0xee, 0x43, 0xc5, 0x26, 0x4a, - 0x67, 0xd7, 0xd0, 0x07, 0xd5, 0xc2, 0x1d, 0xe9, 0x5e, 0xa5, 0x39, 0x2b, 0x24, 0x2a, 0x58, 0x8c, - 0x63, 0x9f, 0x43, 0xfe, 0x61, 0x01, 0x26, 0xd6, 0x15, 0xd2, 0x33, 0x8d, 0x36, 0x71, 0xd0, 0xa7, - 0x50, 0x61, 0xdb, 0xd5, 0x51, 0x1c, 0x85, 0x6b, 0x9b, 0x5c, 0x79, 0xa7, 0x1e, 0xb8, 0x93, 0xbf, - 0x7a, 0x75, 0xeb, 0xb8, 0xcb, 0x06, 0x68, 0x9d, 0x71, 0xd7, 0x4f, 0x1e, 0xd4, 0x77, 0x0f, 0x3e, - 0x23, 0xaa, 0xb3, 0x4d, 0x1c, 0x25, 0xb0, 0x2f, 0x18, 0xc3, 0x3e, 0x2a, 0xda, 0x81, 0x12, 0xb5, - 0x88, 0xca, 0x2d, 0x9b, 0x5c, 0xb9, 0x5f, 0xbf, 0xd0, 0x59, 0xeb, 0xbe, 0x65, 0x6d, 0x8b, 0xa8, - 0xc1, 0x8a, 0xb3, 0x5f, 0x98, 0xe3, 0xa0, 0xe7, 0x30, 0x4e, 0x1d, 0xc5, 0xe9, 0xd3, 0x6a, 0x91, - 0x23, 0xd6, 0x73, 0x23, 0x72, 0xa9, 0x60, 0x33, 0xdc, 0xdf, 0x58, 0xa0, 0xc9, 0xff, 0x59, 0x00, - 0xe4, 0xf3, 0xae, 0x99, 0x46, 0x47, 0x73, 0x34, 0xd3, 0x40, 0x1f, 0x40, 0xc9, 0x19, 0x58, 0x9e, - 0x0b, 0xdc, 0xf5, 0x0c, 0xda, 0x1b, 0x58, 0xe4, 0xe5, 0x59, 0x6d, 0x31, 0x29, 0xc1, 0x28, 0x98, - 0xcb, 0xa0, 0x2d, 0xdf, 0xd4, 0x02, 0x97, 0x7e, 0x18, 0x55, 0xfd, 0xf2, 0xac, 0x96, 0x72, 0xd8, - 0xea, 0x3e, 0x52, 0xd4, 0x40, 0x74, 0x02, 0x48, 0x57, 0xa8, 0xb3, 0x67, 0x2b, 0x06, 0x75, 0x35, - 0x69, 0x3d, 0x22, 0x16, 0xe1, 0xad, 0x7c, 0x9b, 0xc6, 0x24, 0x9a, 0x37, 0x85, 0x15, 0x68, 0x2b, - 0x81, 0x86, 0x53, 0x34, 0x30, 0x6f, 0xb6, 0x89, 0x42, 0x4d, 0xa3, 0x5a, 0x8a, 0x7a, 0x33, 0xe6, - 0xa3, 0x58, 0x50, 0xd1, 0x9b, 0x50, 0xee, 0x11, 0x4a, 0x95, 0x2e, 0xa9, 0x8e, 0x71, 0xc6, 0x19, - 0xc1, 0x58, 0xde, 0x76, 0x87, 0xb1, 0x47, 0x97, 0x7f, 0x24, 0xc1, 0x94, 0xbf, 0x72, 0x5b, 0x1a, - 0x75, 0xd0, 0xef, 0x24, 0xfc, 0xb0, 0x9e, 0x6f, 0x4a, 0x4c, 0x9a, 0x7b, 0xa1, 0xef, 0xf3, 0xde, - 0x48, 0xc8, 0x07, 0xb7, 0x61, 0x4c, 0x73, 0x48, 0x8f, 0xed, 0x43, 0xf1, 0xde, 0xe4, 0xca, 0xbd, - 0xbc, 0x2e, 0xd3, 0x9c, 0x12, 0xa0, 0x63, 0x9b, 0x4c, 0x1c, 0xbb, 0x28, 0xf2, 0x9f, 0x96, 0x42, - 0xe6, 0x33, 0xd7, 0x44, 0x9f, 0x40, 0x85, 0x12, 0x9d, 0xa8, 0x8e, 0x69, 0x0b, 0xf3, 0xdf, 0xcd, - 0x69, 0xbe, 0x72, 0x40, 0xf4, 0xb6, 0x10, 0x6d, 0x5e, 0x67, 0xf6, 0x7b, 0xbf, 0xb0, 0x0f, 0x89, - 0x3e, 0x82, 0x8a, 0x43, 0x7a, 0x96, 0xae, 0x38, 0x44, 0x9c, 0xa3, 0x37, 0xc2, 0x53, 0x60, 0x9e, - 0xc3, 0xc0, 0x5a, 0x66, 0x67, 0x4f, 0xb0, 0xf1, 0xe3, 0xe3, 0x2f, 0x89, 0x37, 0x8a, 0x7d, 0x18, - 0x74, 0x02, 0xd3, 0x7d, 0xab, 0xc3, 0x38, 0x1d, 0x16, 0x05, 0xbb, 0x03, 0xe1, 0x49, 0x8f, 0xf2, - 0xae, 0xcd, 0x7e, 0x44, 0xba, 0xb9, 0x28, 0x74, 0x4d, 0x47, 0xc7, 0x71, 0x4c, 0x0b, 0x5a, 0x85, - 0x99, 0x9e, 0x66, 0xb0, 0xb8, 0x34, 0x68, 0x13, 0xd5, 0x34, 0x3a, 0x94, 0xbb, 0xd5, 0x58, 0x73, - 0x49, 0x00, 0xcc, 0x6c, 0x47, 0xc9, 0x38, 0xce, 0x8f, 0xbe, 0x05, 0xc8, 0x9b, 0xc6, 0x53, 0x37, - 0x88, 0x6b, 0xa6, 0xc1, 0x7d, 0xae, 0x18, 0x38, 0xf7, 0x5e, 0x82, 0x03, 0xa7, 0x48, 0xa1, 0x2d, - 0x58, 0xb0, 0xc9, 0x89, 0xc6, 0xe6, 0xf8, 0x4c, 0xa3, 0x8e, 0x69, 0x0f, 0xb6, 0xb4, 0x9e, 0xe6, - 0x54, 0xc7, 0xb9, 0x4d, 0xd5, 0xf3, 0xb3, 0xda, 0x02, 0x4e, 0xa1, 0xe3, 0x54, 0x29, 0xf9, 0xcf, - 0xc6, 0x61, 0x26, 0x16, 0x6f, 0xd0, 0x73, 0x58, 0x54, 0xfb, 0xb6, 0x4d, 0x0c, 0x67, 0xa7, 0xdf, - 0x3b, 0x20, 0x76, 0x5b, 0x3d, 0x22, 0x9d, 0xbe, 0x4e, 0x3a, 0xdc, 0x51, 0xc6, 0x9a, 0xcb, 0xc2, - 0xe2, 0xc5, 0xb5, 0x54, 0x2e, 0x9c, 0x21, 0xcd, 0x56, 0xc1, 0xe0, 0x43, 0xdb, 0x1a, 0xa5, 0x3e, - 0x66, 0x81, 0x63, 0xfa, 0xab, 0xb0, 0x93, 0xe0, 0xc0, 0x29, 0x52, 0xcc, 0xc6, 0x0e, 0xa1, 0x9a, - 0x4d, 0x3a, 0x71, 0x1b, 0x8b, 0x51, 0x1b, 0xd7, 0x53, 0xb9, 0x70, 0x86, 0x34, 0x7a, 0x0f, 0x26, - 0x5d, 0x6d, 0x7c, 0xff, 0xc4, 0x46, 0xcf, 0x0b, 0xb0, 0xc9, 0x9d, 0x80, 0x84, 0xc3, 0x7c, 0x6c, - 0x6a, 0xe6, 0x01, 0x25, 0xf6, 0x09, 0xe9, 0x64, 0x6f, 0xf0, 0x6e, 0x82, 0x03, 0xa7, 0x48, 0xb1, - 0xa9, 0xb9, 0x1e, 0x98, 0x98, 0xda, 0x78, 0x74, 0x6a, 0xfb, 0xa9, 0x5c, 0x38, 0x43, 0x9a, 0xf9, - 0xb1, 0x6b, 0xf2, 0xea, 0x89, 0xa2, 0xe9, 0xca, 0x81, 0x4e, 0xaa, 0xe5, 0xa8, 0x1f, 0xef, 0x44, - 0xc9, 0x38, 0xce, 0x8f, 0x9e, 0xc2, 0x9c, 0x3b, 0xb4, 0x6f, 0x28, 0x3e, 0x48, 0x85, 0x83, 0x7c, - 0x45, 0x80, 0xcc, 0xed, 0xc4, 0x19, 0x70, 0x52, 0x06, 0x7d, 0x00, 0xd3, 0xaa, 0xa9, 0xeb, 0xdc, - 0x1f, 0xd7, 0xcc, 0xbe, 0xe1, 0x54, 0x27, 0x38, 0x0a, 0x62, 0xe7, 0x71, 0x2d, 0x42, 0xc1, 0x31, - 0x4e, 0x44, 0x00, 0x54, 0x2f, 0xe1, 0xd0, 0x2a, 0xf0, 0xf8, 0xf8, 0x20, 0x6f, 0x0c, 0xf0, 0x53, - 0x55, 0x50, 0x03, 0xf8, 0x43, 0x14, 0x87, 0x80, 0xe5, 0x7f, 0x96, 0x60, 0x29, 0x23, 0x74, 0xa0, - 0x6f, 0x46, 0x52, 0xec, 0x6f, 0xc4, 0x52, 0xec, 0xad, 0x0c, 0xb1, 0x50, 0x9e, 0x35, 0x60, 0xca, - 0x66, 0xb3, 0x32, 0xba, 0x2e, 0x8b, 0x88, 0x91, 0xef, 0x0d, 0x99, 0x06, 0x0e, 0xcb, 0x04, 0x31, - 0x7f, 0xee, 0xfc, 0xac, 0x36, 0x15, 0xa1, 0xe1, 0x28, 0xbc, 0xfc, 0xe7, 0x05, 0x80, 0x75, 0x62, - 0xe9, 0xe6, 0xa0, 0x47, 0x8c, 0xab, 0xa8, 0xa1, 0x76, 0x23, 0x35, 0xd4, 0xdb, 0xc3, 0xb6, 0xc7, - 0x37, 0x2d, 0xb3, 0x88, 0xfa, 0x76, 0xac, 0x88, 0x6a, 0xe4, 0x87, 0xbc, 0xb8, 0x8a, 0xfa, 0xf7, - 0x22, 0xcc, 0x07, 0xcc, 0x41, 0x19, 0xf5, 0x38, 0xb2, 0xc7, 0xbf, 0x1e, 0xdb, 0xe3, 0xa5, 0x14, - 0x91, 0xd7, 0x56, 0x47, 0x7d, 0x06, 0xd3, 0xac, 0xca, 0x71, 0xf7, 0x92, 0xd7, 0x50, 0xe3, 0x23, - 0xd7, 0x50, 0x7e, 0xb6, 0xdb, 0x8a, 0x20, 0xe1, 0x18, 0x72, 0x46, 0xcd, 0x56, 0xfe, 0x32, 0xd6, - 0x6c, 0x3f, 0x96, 0x60, 0x3a, 0xd8, 0xa6, 0x2b, 0x28, 0xda, 0x76, 0xa2, 0x45, 0xdb, 0x9b, 0xb9, - 0x5d, 0x34, 0xa3, 0x6a, 0xfb, 0x1f, 0x56, 0xe0, 0xfb, 0x4c, 0xec, 0x80, 0x1f, 0x28, 0xea, 0xf1, - 0xf0, 0x3b, 0x1e, 0xfa, 0xa1, 0x04, 0x48, 0x64, 0x81, 0x55, 0xc3, 0x30, 0x1d, 0xc5, 0x8d, 0x95, - 0xae, 0x59, 0x9b, 0xb9, 0xcd, 0xf2, 0x34, 0xd6, 0xf7, 0x13, 0x58, 0x4f, 0x0c, 0xc7, 0x1e, 0x04, - 0x9b, 0x9c, 0x64, 0xc0, 0x29, 0x06, 0x20, 0x05, 0xc0, 0x16, 0x98, 0x7b, 0xa6, 0x38, 0xc8, 0x6f, - 0xe7, 0x88, 0x79, 0x4c, 0x60, 0xcd, 0x34, 0x0e, 0xb5, 0x6e, 0x10, 0x76, 0xb0, 0x0f, 0x84, 0x43, - 0xa0, 0x37, 0x9f, 0xc0, 0x52, 0x86, 0xb5, 0x68, 0x16, 0x8a, 0xc7, 0x64, 0xe0, 0x2e, 0x1b, 0x66, - 0xff, 0x45, 0x0b, 0x30, 0x76, 0xa2, 0xe8, 0x7d, 0x37, 0xfc, 0x4e, 0x60, 0xf7, 0xc7, 0x07, 0x85, - 0xf7, 0x25, 0xf9, 0x47, 0x63, 0x61, 0xdf, 0xe1, 0x15, 0xf3, 0x3d, 0x76, 0x69, 0xb5, 0x74, 0x4d, - 0x55, 0xa8, 0x28, 0x84, 0xae, 0xbb, 0x17, 0x56, 0x77, 0x0c, 0xfb, 0xd4, 0x48, 0x6d, 0x5d, 0x78, - 0xbd, 0xb5, 0x75, 0xf1, 0xd5, 0xd4, 0xd6, 0xbf, 0x0b, 0x15, 0xea, 0x55, 0xd5, 0x25, 0x0e, 0xf9, - 0x60, 0x84, 0xf8, 0x2a, 0x0a, 0x6a, 0x5f, 0x81, 0x5f, 0x4a, 0xfb, 0xa0, 0x69, 0x45, 0xf4, 0xd8, - 0x88, 0x45, 0xf4, 0x2b, 0x2d, 0x7c, 0x59, 0xbc, 0xb1, 0x94, 0x3e, 0x25, 0x1d, 0x1e, 0xdb, 0x2a, - 0x41, 0xbc, 0x69, 0xf1, 0x51, 0x2c, 0xa8, 0xe8, 0x93, 0x88, 0xcb, 0x56, 0x2e, 0xe3, 0xb2, 0xd3, - 0xd9, 0xee, 0x8a, 0xf6, 0x61, 0xc9, 0xb2, 0xcd, 0xae, 0x4d, 0x28, 0x5d, 0x27, 0x4a, 0x47, 0xd7, - 0x0c, 0xe2, 0xad, 0x8f, 0x5b, 0x11, 0xdd, 0x3a, 0x3f, 0xab, 0x2d, 0xb5, 0xd2, 0x59, 0x70, 0x96, - 0xac, 0xfc, 0xa2, 0x04, 0xb3, 0xf1, 0x0c, 0x98, 0x51, 0xa4, 0x4a, 0x97, 0x2a, 0x52, 0xef, 0x87, - 0x0e, 0x83, 0x5b, 0xc1, 0x87, 0x5e, 0x70, 0x12, 0x07, 0x62, 0x15, 0x66, 0x44, 0x34, 0xf0, 0x88, - 0xa2, 0x4c, 0xf7, 0x77, 0x7f, 0x3f, 0x4a, 0xc6, 0x71, 0x7e, 0xf4, 0x18, 0xa6, 0x6c, 0x5e, 0x77, - 0x7b, 0x00, 0x6e, 0xed, 0x7a, 0x43, 0x00, 0x4c, 0xe1, 0x30, 0x11, 0x47, 0x79, 0x59, 0xdd, 0x1a, - 0x94, 0xa3, 0x1e, 0x40, 0x29, 0x5a, 0xb7, 0xae, 0xc6, 0x19, 0x70, 0x52, 0x06, 0x6d, 0xc3, 0x7c, - 0xdf, 0x48, 0x42, 0xb9, 0xae, 0x7c, 0x4b, 0x40, 0xcd, 0xef, 0x27, 0x59, 0x70, 0x9a, 0x1c, 0x3a, - 0x8c, 0x94, 0xb2, 0xe3, 0x3c, 0x3c, 0xaf, 0xe4, 0x3e, 0x78, 0xb9, 0x6b, 0xd9, 0x94, 0x72, 0xbb, - 0x92, 0xb7, 0xdc, 0x96, 0xff, 0x41, 0x0a, 0x27, 0x21, 0xbf, 0x04, 0x1e, 0xf6, 0xca, 0x94, 0x90, - 0x08, 0x55, 0x47, 0x66, 0x7a, 0xf5, 0xfb, 0x68, 0xa4, 0xea, 0x37, 0x48, 0x9e, 0xc3, 0xcb, 0xdf, - 0xcf, 0x25, 0x58, 0xdc, 0x68, 0x3f, 0xb5, 0xcd, 0xbe, 0xe5, 0x99, 0xb3, 0x6b, 0xb9, 0x4b, 0xf3, - 0x75, 0x28, 0xd9, 0x7d, 0xdd, 0x9b, 0xc7, 0x1b, 0xde, 0x3c, 0x70, 0x5f, 0x67, 0xf3, 0x98, 0x8f, - 0x49, 0xb9, 0x93, 0x60, 0x02, 0x68, 0x07, 0xc6, 0x6d, 0xc5, 0xe8, 0x12, 0x2f, 0xad, 0xde, 0x1d, - 0x62, 0xfd, 0xe6, 0x3a, 0x66, 0xec, 0xa1, 0xc2, 0x86, 0x4b, 0x63, 0x81, 0x22, 0xff, 0xa3, 0x04, - 0x33, 0xcf, 0xf6, 0xf6, 0x5a, 0x9b, 0x06, 0x3f, 0xd1, 0xfc, 0x6d, 0xf5, 0x0e, 0x94, 0x2c, 0xc5, - 0x39, 0x8a, 0x67, 0x7a, 0x46, 0xc3, 0x9c, 0x82, 0x1e, 0x42, 0x85, 0xfd, 0xcb, 0xec, 0xe2, 0x47, - 0x6a, 0x82, 0x07, 0xc2, 0x4a, 0x4b, 0x8c, 0xbd, 0x0c, 0xfd, 0x1f, 0xfb, 0x9c, 0xe8, 0x3b, 0x50, - 0x66, 0xf1, 0x87, 0x18, 0x9d, 0x9c, 0x05, 0xba, 0x30, 0xaa, 0xe9, 0x0a, 0x05, 0x35, 0x97, 0x18, - 0xc0, 0x1e, 0x9c, 0x7c, 0x0c, 0x0b, 0xa1, 0x49, 0xb0, 0x55, 0x7c, 0xce, 0x72, 0x2a, 0x6a, 0xc3, - 0x18, 0xd3, 0xce, 0x32, 0x67, 0x31, 0xc7, 0x13, 0x68, 0x6c, 0x21, 0x82, 0xfa, 0x88, 0xfd, 0xa2, - 0xd8, 0xc5, 0x92, 0xb7, 0x61, 0x8a, 0x3f, 0x43, 0x9b, 0xb6, 0xc3, 0x17, 0x13, 0xdd, 0x86, 0x62, - 0x4f, 0x33, 0x44, 0x76, 0x9e, 0x14, 0x32, 0x45, 0x96, 0x59, 0xd8, 0x38, 0x27, 0x2b, 0xa7, 0x22, - 0x5e, 0x05, 0x64, 0xe5, 0x14, 0xb3, 0x71, 0xf9, 0x29, 0x94, 0xc5, 0x26, 0x85, 0x81, 0x8a, 0x17, - 0x03, 0x15, 0x53, 0x80, 0x76, 0xa1, 0xbc, 0xd9, 0x6a, 0xea, 0xa6, 0x5b, 0xab, 0xa9, 0x5a, 0xc7, - 0x8e, 0xef, 0xe0, 0xda, 0xe6, 0x3a, 0xc6, 0x9c, 0x82, 0x64, 0x18, 0x27, 0xa7, 0x2a, 0xb1, 0x1c, - 0xee, 0x47, 0x13, 0x4d, 0x60, 0xbe, 0xf1, 0x84, 0x8f, 0x60, 0x41, 0x91, 0xff, 0xb8, 0x00, 0x65, - 0xb1, 0x1c, 0x57, 0x70, 0x77, 0xdb, 0x8a, 0xdc, 0xdd, 0xde, 0xca, 0xe7, 0x1a, 0x99, 0x17, 0xb7, - 0xbd, 0xd8, 0xc5, 0xed, 0x7e, 0x4e, 0xbc, 0x8b, 0x6f, 0x6d, 0x3f, 0x28, 0xc0, 0x74, 0xd4, 0x29, - 0xd1, 0x7b, 0x30, 0xc9, 0xd2, 0x94, 0xa6, 0x92, 0x9d, 0xa0, 0x3a, 0xf6, 0x9f, 0x6e, 0xda, 0x01, - 0x09, 0x87, 0xf9, 0x50, 0xd7, 0x17, 0x63, 0x7e, 0x24, 0x26, 0x9d, 0xbd, 0xa4, 0x7d, 0x47, 0xd3, - 0xeb, 0xee, 0x07, 0x99, 0xfa, 0xa6, 0xe1, 0xec, 0xda, 0x6d, 0xc7, 0xd6, 0x8c, 0x6e, 0x42, 0x11, - 0x77, 0xca, 0x30, 0x32, 0xfa, 0x36, 0x4b, 0x99, 0xd4, 0xec, 0xdb, 0x2a, 0x49, 0x2b, 0x7d, 0xbd, - 0xb2, 0x8d, 0x1d, 0xd0, 0xce, 0x96, 0xa9, 0x2a, 0xba, 0xbb, 0x39, 0x98, 0x1c, 0x12, 0x9b, 0x18, - 0x2a, 0xf1, 0xca, 0x4d, 0x17, 0x02, 0xfb, 0x60, 0xf2, 0xdf, 0x49, 0x30, 0x29, 0xd6, 0xe2, 0x0a, - 0x2e, 0x39, 0xbf, 0x1d, 0xbd, 0xe4, 0xdc, 0xcd, 0x19, 0x39, 0xd2, 0x6f, 0x38, 0x7f, 0x15, 0x98, - 0xce, 0x62, 0x05, 0x3b, 0x2e, 0x47, 0x26, 0x75, 0xe2, 0xc7, 0x85, 0x9d, 0x72, 0xcc, 0x29, 0xa8, - 0x0f, 0xb3, 0x5a, 0x2c, 0xb8, 0x88, 0x3d, 0x6b, 0xe4, 0xb3, 0xc4, 0x17, 0x6b, 0x56, 0x05, 0xfc, - 0x6c, 0x9c, 0x82, 0x13, 0x2a, 0x64, 0x02, 0x09, 0x2e, 0xf4, 0x11, 0x94, 0x8e, 0x1c, 0xc7, 0x4a, - 0x79, 0x3e, 0x1f, 0x12, 0xd2, 0x02, 0x13, 0x2a, 0x7c, 0x76, 0x7b, 0x7b, 0x2d, 0xcc, 0xa1, 0xe4, - 0xbf, 0x2f, 0xf8, 0xeb, 0xc1, 0xef, 0x1c, 0x1f, 0xfa, 0xb3, 0x5d, 0xd3, 0x15, 0x4a, 0xb9, 0x63, - 0xbb, 0xf7, 0xe3, 0x85, 0x90, 0xe1, 0x3e, 0x0d, 0x27, 0xb8, 0xd1, 0x5e, 0x10, 0xea, 0xa5, 0xcb, - 0x84, 0xfa, 0xc9, 0xb4, 0x30, 0x8f, 0x9e, 0x41, 0xd1, 0xd1, 0xf3, 0xde, 0x73, 0x05, 0xe2, 0xde, - 0x56, 0x3b, 0x88, 0x95, 0x7b, 0x5b, 0x6d, 0xcc, 0x20, 0xd0, 0x2e, 0x8c, 0xb1, 0x74, 0xca, 0xa2, - 0x43, 0x31, 0x7f, 0xb4, 0x61, 0x2b, 0x18, 0xb8, 0x14, 0xfb, 0x45, 0xb1, 0x8b, 0x23, 0x7f, 0x0f, - 0xa6, 0x22, 0x21, 0x04, 0x7d, 0x0a, 0xd7, 0x75, 0x53, 0xe9, 0x34, 0x15, 0x5d, 0x31, 0x54, 0xe2, - 0x7d, 0xed, 0xb8, 0x9b, 0x76, 0xf6, 0xb6, 0x42, 0x7c, 0x22, 0x00, 0x2d, 0x08, 0x25, 0xd7, 0xc3, - 0x34, 0x1c, 0x41, 0x94, 0x15, 0x80, 0x60, 0x8e, 0xa8, 0x06, 0x63, 0xcc, 0x53, 0xdd, 0x54, 0x37, - 0xd1, 0x9c, 0x60, 0x16, 0x32, 0x07, 0xa6, 0xd8, 0x1d, 0x47, 0x2b, 0x00, 0x94, 0xa8, 0x36, 0x71, - 0xf8, 0x76, 0x16, 0xa2, 0x5f, 0x4c, 0xdb, 0x3e, 0x05, 0x87, 0xb8, 0xe4, 0xcf, 0x0b, 0x30, 0xb5, - 0x43, 0x9c, 0xef, 0x9b, 0xf6, 0x71, 0xcb, 0xd4, 0x35, 0x75, 0x70, 0x05, 0x79, 0x00, 0x47, 0xf2, - 0xc0, 0x3b, 0x43, 0x76, 0x26, 0x62, 0x5d, 0x66, 0x36, 0xf8, 0x38, 0x96, 0x0d, 0x56, 0x46, 0x42, - 0xbd, 0x38, 0x27, 0xfc, 0x58, 0x82, 0xa5, 0x08, 0xff, 0x93, 0x20, 0xb0, 0xec, 0xc3, 0x98, 0x65, - 0xda, 0x8e, 0x57, 0x7f, 0x8c, 0x34, 0x19, 0x16, 0xbd, 0x43, 0x15, 0x08, 0x83, 0xc1, 0x2e, 0x1a, - 0xda, 0x82, 0x82, 0x63, 0x8a, 0x63, 0x30, 0x1a, 0x26, 0x21, 0x76, 0x13, 0x04, 0x66, 0x61, 0xcf, - 0xc4, 0x05, 0xc7, 0x94, 0xff, 0x49, 0x82, 0x6a, 0x84, 0x2b, 0x1c, 0x1a, 0x5f, 0xd3, 0x0c, 0x30, - 0x94, 0x0e, 0x6d, 0xb3, 0x77, 0xe9, 0x39, 0xf8, 0x9b, 0xbc, 0x61, 0x9b, 0x3d, 0xcc, 0xb1, 0xe4, - 0x9f, 0x48, 0x30, 0x17, 0xe1, 0xbc, 0x82, 0xb4, 0xf4, 0x51, 0x34, 0x2d, 0xdd, 0x1f, 0x65, 0x22, - 0x19, 0xc9, 0xe9, 0x27, 0x85, 0xd8, 0x34, 0xd8, 0x84, 0xd1, 0x21, 0x4c, 0x5a, 0x66, 0xa7, 0xfd, - 0x0a, 0xbe, 0x9d, 0xce, 0xb0, 0x72, 0xa1, 0x15, 0x60, 0xe1, 0x30, 0x30, 0x3a, 0x85, 0x39, 0x43, - 0xe9, 0x11, 0x6a, 0x29, 0x2a, 0x69, 0xbf, 0x82, 0xd7, 0xa4, 0x1b, 0xfc, 0xe3, 0x4c, 0x1c, 0x11, - 0x27, 0x95, 0xa0, 0x6d, 0x28, 0x6b, 0x16, 0x2f, 0x5f, 0xc5, 0x21, 0x1d, 0x9a, 0xe3, 0xdd, 0x62, - 0xd7, 0xcd, 0x15, 0xe2, 0x07, 0xf6, 0x30, 0xe4, 0x7f, 0x8b, 0x7b, 0x03, 0xaf, 0x86, 0x9e, 0x42, - 0x85, 0x77, 0xb1, 0xa8, 0xa6, 0xee, 0x7d, 0x46, 0xe1, 0x17, 0x17, 0x31, 0xf6, 0xf2, 0xac, 0x76, - 0x2b, 0xe5, 0x85, 0xdc, 0x23, 0x63, 0x5f, 0x18, 0xed, 0x40, 0xc9, 0xfa, 0x65, 0x0a, 0x37, 0x9e, - 0x82, 0x79, 0xb5, 0xc6, 0x71, 0xd0, 0xaf, 0x41, 0x99, 0x18, 0x1d, 0x5e, 0x0b, 0xba, 0x6f, 0x14, - 0x7c, 0x56, 0x4f, 0xdc, 0x21, 0xec, 0xd1, 0xe4, 0x3f, 0x2c, 0xc6, 0x66, 0xc5, 0xf3, 0xf5, 0x67, - 0xaf, 0xcc, 0x39, 0xfc, 0x7a, 0x32, 0xd3, 0x41, 0x0e, 0xa0, 0x2c, 0xb2, 0xbd, 0xf0, 0xf9, 0xaf, - 0x8f, 0xe2, 0xf3, 0xe1, 0x44, 0xea, 0x5f, 0xe7, 0xbc, 0x41, 0x0f, 0x18, 0x7d, 0x17, 0xc6, 0x89, - 0xab, 0xc2, 0x4d, 0xcf, 0x8f, 0x46, 0x51, 0x11, 0x84, 0xdf, 0x20, 0x64, 0x8b, 0x31, 0x81, 0x8a, - 0xbe, 0xc9, 0xd6, 0x8b, 0xf1, 0xb2, 0xaa, 0x97, 0x56, 0x4b, 0x3c, 0x63, 0xde, 0x76, 0xa7, 0xed, - 0x0f, 0xbf, 0x3c, 0xab, 0x41, 0xf0, 0x13, 0x87, 0x25, 0xe4, 0xdf, 0x83, 0xf9, 0x94, 0x14, 0x81, - 0xd4, 0xc8, 0xc3, 0x8a, 0x1b, 0x31, 0x1b, 0xf9, 0xb6, 0x21, 0xff, 0x17, 0xc2, 0x7f, 0x91, 0x60, - 0x8e, 0xef, 0x8e, 0xda, 0xb7, 0x35, 0x67, 0x70, 0x65, 0x79, 0xf9, 0x79, 0x24, 0x2f, 0x3f, 0x1c, - 0xb2, 0x25, 0x09, 0x0b, 0xb3, 0x72, 0xb3, 0xfc, 0x53, 0x09, 0x6e, 0x24, 0xb8, 0xaf, 0x20, 0x74, - 0xef, 0x47, 0x43, 0xf7, 0x3b, 0xa3, 0x4e, 0x28, 0x23, 0x7c, 0xff, 0xf7, 0x5c, 0xca, 0x74, 0xf8, - 0x29, 0x5d, 0x01, 0xb0, 0x6c, 0xed, 0x44, 0xd3, 0x49, 0x57, 0x34, 0x35, 0x54, 0x42, 0x2d, 0x6b, - 0x3e, 0x05, 0x87, 0xb8, 0x10, 0x85, 0xc5, 0x0e, 0x39, 0x54, 0xfa, 0xba, 0xb3, 0xda, 0xe9, 0xac, - 0x29, 0x96, 0x72, 0xa0, 0xe9, 0x9a, 0xa3, 0x89, 0xe7, 0x9f, 0x89, 0xe6, 0x63, 0xb7, 0xd9, 0x20, - 0x8d, 0xe3, 0xe5, 0x59, 0xed, 0x76, 0xda, 0xd7, 0x3e, 0x8f, 0x65, 0x80, 0x33, 0xa0, 0xd1, 0x00, - 0xaa, 0x36, 0xf9, 0x5e, 0x5f, 0xb3, 0x49, 0x67, 0xdd, 0x36, 0xad, 0x88, 0xda, 0x22, 0x57, 0xfb, - 0x5b, 0xe7, 0x67, 0xb5, 0x2a, 0xce, 0xe0, 0x19, 0xae, 0x38, 0x13, 0x1e, 0x7d, 0x06, 0xf3, 0x8a, - 0x68, 0x2e, 0x0c, 0x6b, 0x75, 0x4f, 0xe8, 0xfb, 0xe7, 0x67, 0xb5, 0xf9, 0xd5, 0x24, 0x79, 0xb8, - 0xc2, 0x34, 0x50, 0xd4, 0x80, 0xf2, 0x09, 0xef, 0x43, 0xa4, 0xd5, 0x31, 0x8e, 0xcf, 0x72, 0x55, - 0xd9, 0x6d, 0x4d, 0x64, 0x98, 0xe3, 0x1b, 0x6d, 0x7e, 0xf2, 0x3d, 0x2e, 0x76, 0xd5, 0x67, 0xa5, - 0xb4, 0x38, 0xf9, 0xfc, 0x0b, 0x40, 0x25, 0x88, 0x98, 0xcf, 0x02, 0x12, 0x0e, 0xf3, 0xa1, 0x4f, - 0x60, 0xe2, 0x48, 0xbc, 0x17, 0xd1, 0x6a, 0x39, 0x57, 0x9d, 0x10, 0x79, 0x5f, 0x6a, 0xce, 0x09, - 0x15, 0x13, 0xde, 0x30, 0xc5, 0x01, 0x22, 0x7a, 0x13, 0xca, 0xfc, 0xc7, 0xe6, 0x3a, 0x7f, 0x5e, - 0xad, 0x04, 0x71, 0xf5, 0x99, 0x3b, 0x8c, 0x3d, 0xba, 0xc7, 0xba, 0xd9, 0x5a, 0xe3, 0xcf, 0xfc, - 0x31, 0xd6, 0xcd, 0xd6, 0x1a, 0xf6, 0xe8, 0xe8, 0x53, 0x28, 0x53, 0xb2, 0xa5, 0x19, 0xfd, 0xd3, - 0x2a, 0xe4, 0x6a, 0x12, 0x68, 0x3f, 0xe1, 0xdc, 0xb1, 0x87, 0xce, 0x40, 0x83, 0xa0, 0x63, 0x0f, - 0x16, 0x1d, 0xc1, 0x84, 0xdd, 0x37, 0x56, 0xe9, 0x3e, 0x25, 0x76, 0x75, 0x92, 0xeb, 0x18, 0x96, - 0x4a, 0xb0, 0xc7, 0x1f, 0xd7, 0xe2, 0xaf, 0x90, 0xcf, 0x81, 0x03, 0x70, 0x74, 0x04, 0xc0, 0x7f, - 0xf0, 0x37, 0xd5, 0xea, 0x22, 0x57, 0xf5, 0x7e, 0x1e, 0x55, 0x69, 0x4f, 0xb7, 0xe2, 0xbb, 0x8a, - 0x4f, 0xc6, 0x21, 0x6c, 0xf4, 0x47, 0x12, 0x20, 0xda, 0xb7, 0x2c, 0x9d, 0xf4, 0x88, 0xe1, 0x28, - 0x3a, 0x1f, 0xa5, 0xd5, 0xeb, 0x5c, 0xe5, 0x87, 0xc3, 0x56, 0x30, 0x21, 0x18, 0x57, 0xed, 0x7f, - 0x2e, 0x49, 0xb2, 0xe2, 0x14, 0xbd, 0x6c, 0x13, 0x0f, 0xc5, 0xac, 0xa7, 0x72, 0x6d, 0x62, 0xfa, - 0x6b, 0x75, 0xb0, 0x89, 0x82, 0x8e, 0x3d, 0x58, 0xf4, 0x1c, 0x16, 0xbd, 0x86, 0x59, 0x6c, 0x9a, - 0xce, 0x86, 0xa6, 0x13, 0x3a, 0xa0, 0x0e, 0xe9, 0x55, 0xa7, 0xb9, 0x83, 0xf9, 0x5d, 0x43, 0x38, - 0x95, 0x0b, 0x67, 0x48, 0xa3, 0x1e, 0xd4, 0xbc, 0xe0, 0xc4, 0x4e, 0xae, 0x1f, 0x1d, 0x9f, 0x50, - 0x55, 0xd1, 0xdd, 0x2f, 0x48, 0x33, 0x5c, 0xc1, 0x1b, 0xe7, 0x67, 0xb5, 0xda, 0xfa, 0xc5, 0xac, - 0x78, 0x18, 0x16, 0xfa, 0x0e, 0x54, 0x95, 0x2c, 0x3d, 0xb3, 0x5c, 0xcf, 0x57, 0x59, 0xc4, 0xcb, - 0x54, 0x90, 0x29, 0x8d, 0x1c, 0x98, 0x55, 0xa2, 0xad, 0xcb, 0xb4, 0x3a, 0x97, 0xeb, 0x31, 0x3a, - 0xd6, 0xf1, 0x1c, 0xbc, 0x1b, 0xc5, 0x08, 0x14, 0x27, 0x34, 0xa0, 0xdf, 0x07, 0xa4, 0xc4, 0xbb, - 0xad, 0x69, 0x15, 0xe5, 0x4a, 0x74, 0x89, 0x36, 0xed, 0xc0, 0xed, 0x12, 0x24, 0x8a, 0x53, 0xf4, - 0xb0, 0x3b, 0x84, 0x12, 0xeb, 0x10, 0xa7, 0xd5, 0xa5, 0x44, 0x35, 0x74, 0x81, 0x72, 0x5f, 0x2e, - 0xf4, 0xa1, 0x2c, 0x8e, 0x88, 0x93, 0x4a, 0xd0, 0x16, 0x2c, 0x88, 0xc1, 0x7d, 0x83, 0x2a, 0x87, - 0xa4, 0x3d, 0xa0, 0xaa, 0xa3, 0xd3, 0xea, 0x3c, 0x8f, 0xef, 0xfc, 0x63, 0xed, 0x6a, 0x0a, 0x1d, - 0xa7, 0x4a, 0xa1, 0x0f, 0x61, 0xf6, 0xd0, 0xb4, 0x0f, 0xb4, 0x4e, 0x87, 0x18, 0x1e, 0xd2, 0x02, - 0x47, 0xe2, 0xcf, 0x60, 0x1b, 0x31, 0x1a, 0x4e, 0x70, 0x23, 0x0a, 0x37, 0x04, 0x72, 0xcb, 0x36, - 0xd5, 0x6d, 0xb3, 0x6f, 0x38, 0x6e, 0xc9, 0x79, 0xc3, 0x4f, 0xa3, 0x37, 0x56, 0xd3, 0x18, 0x5e, - 0x9e, 0xd5, 0xee, 0xa4, 0x5f, 0x44, 0x02, 0x26, 0x9c, 0x8e, 0x8d, 0x2c, 0xb8, 0x2e, 0xfa, 0xfe, - 0xf9, 0x7b, 0x5c, 0xb5, 0xca, 0x8f, 0xfe, 0x07, 0xc3, 0x03, 0x9e, 0x2f, 0x12, 0x3f, 0xff, 0xb3, - 0xe7, 0x67, 0xb5, 0xeb, 0x61, 0x06, 0x1c, 0xd1, 0xc0, 0xfb, 0xbc, 0xc4, 0xd7, 0xc5, 0xab, 0xe9, - 0x95, 0x1f, 0xad, 0xcf, 0x2b, 0x30, 0xed, 0x95, 0xf5, 0x79, 0x85, 0x20, 0x2f, 0x7e, 0x1d, 0xfa, - 0xaf, 0x02, 0xcc, 0x07, 0xcc, 0xb9, 0xfb, 0xbc, 0x52, 0x44, 0x7e, 0xd5, 0x2f, 0x9f, 0xaf, 0xf7, - 0x2a, 0x58, 0xba, 0xff, 0x7b, 0xbd, 0x57, 0x81, 0x6d, 0x19, 0xb7, 0x87, 0xbf, 0x29, 0x84, 0x27, - 0x30, 0x62, 0x03, 0xd0, 0x2b, 0x68, 0x19, 0xff, 0xd2, 0xf5, 0x10, 0xc9, 0x3f, 0x2d, 0xc2, 0x6c, - 0xfc, 0x34, 0x46, 0xfa, 0x44, 0xa4, 0xa1, 0x7d, 0x22, 0x2d, 0x58, 0x38, 0xec, 0xeb, 0xfa, 0x80, - 0xcf, 0x21, 0xd4, 0x2c, 0xe2, 0x7e, 0xb1, 0xfd, 0xaa, 0x90, 0x5c, 0xd8, 0x48, 0xe1, 0xc1, 0xa9, - 0x92, 0xc9, 0xb6, 0x91, 0xd2, 0x2f, 0xdb, 0x36, 0x32, 0x76, 0x89, 0xb6, 0x91, 0xf4, 0xce, 0x9b, - 0xe2, 0xa5, 0x3a, 0x6f, 0x2e, 0xd3, 0x33, 0x92, 0x12, 0xc4, 0x86, 0xbe, 0x6e, 0x7c, 0x03, 0xa6, - 0xa3, 0x7d, 0x4c, 0xee, 0x5e, 0xba, 0xad, 0x54, 0xe2, 0xcb, 0x78, 0x68, 0x2f, 0xdd, 0x71, 0xec, - 0x73, 0xc8, 0xe7, 0x12, 0x2c, 0xa6, 0xf7, 0x2b, 0x23, 0x1d, 0xa6, 0x7b, 0xca, 0x69, 0xb8, 0x87, - 0x5c, 0xba, 0xe4, 0xe3, 0x1d, 0x6f, 0x60, 0xd9, 0x8e, 0x60, 0xe1, 0x18, 0x36, 0xfa, 0x18, 0x2a, - 0x3d, 0xe5, 0xb4, 0xdd, 0xb7, 0xbb, 0xe4, 0xd2, 0x8f, 0x84, 0xfc, 0x18, 0x6d, 0x0b, 0x14, 0xec, - 0xe3, 0xc9, 0xbf, 0x90, 0x60, 0x29, 0xa3, 0x2d, 0xe5, 0xff, 0xd1, 0x2c, 0xff, 0x52, 0x82, 0xaf, - 0x64, 0x5e, 0xc3, 0xd0, 0xa3, 0x48, 0x07, 0x8d, 0x1c, 0xeb, 0xa0, 0x41, 0x49, 0xc1, 0xd7, 0xd4, - 0x40, 0xf3, 0xb9, 0x04, 0xd5, 0xac, 0x7b, 0x29, 0x7a, 0x2f, 0x62, 0xe4, 0xd7, 0x62, 0x46, 0xce, - 0x25, 0xe4, 0x5e, 0x93, 0x8d, 0xff, 0x2a, 0xc1, 0xad, 0x0b, 0xea, 0x3b, 0xff, 0xfa, 0x43, 0x3a, - 0x61, 0x2e, 0xfe, 0x6a, 0x2f, 0x3e, 0x27, 0x06, 0xd7, 0x9f, 0x14, 0x1e, 0x9c, 0x29, 0x8d, 0xf6, - 0x61, 0x49, 0xdc, 0xbd, 0xe2, 0x34, 0x51, 0xba, 0xf0, 0x46, 0xc3, 0xf5, 0x74, 0x16, 0x9c, 0x25, - 0x2b, 0xff, 0xb5, 0x04, 0x8b, 0xe9, 0x0f, 0x0e, 0xe8, 0xdd, 0xc8, 0x92, 0xd7, 0x62, 0x4b, 0x3e, - 0x13, 0x93, 0x12, 0x0b, 0xfe, 0x5d, 0x98, 0x16, 0xcf, 0x12, 0x02, 0x46, 0x38, 0xb3, 0x9c, 0x96, - 0x9d, 0x04, 0x84, 0x57, 0x1c, 0xf3, 0x63, 0x12, 0x1d, 0xc3, 0x31, 0x34, 0xf9, 0x07, 0x05, 0x18, - 0x6b, 0xab, 0x8a, 0x4e, 0xae, 0xa0, 0x36, 0xfe, 0x56, 0xa4, 0x36, 0x1e, 0xf6, 0x27, 0x7c, 0xdc, - 0xaa, 0xcc, 0xb2, 0x18, 0xc7, 0xca, 0xe2, 0xb7, 0x72, 0xa1, 0x5d, 0x5c, 0x11, 0xff, 0x26, 0x4c, - 0xf8, 0x4a, 0x47, 0x4b, 0xd4, 0xf2, 0x5f, 0x14, 0x60, 0x32, 0xa4, 0x62, 0xc4, 0x34, 0x7f, 0x18, - 0xa9, 0x6d, 0x8a, 0x39, 0x1e, 0x81, 0x42, 0xba, 0xea, 0x5e, 0x35, 0xe3, 0xb6, 0xa0, 0x07, 0x4d, - 0xc7, 0xc9, 0x22, 0xe7, 0x1b, 0x30, 0xed, 0x28, 0x76, 0x97, 0x38, 0xfe, 0x07, 0x19, 0xb7, 0x45, - 0xce, 0xff, 0x5b, 0x88, 0xbd, 0x08, 0x15, 0xc7, 0xb8, 0x6f, 0x3e, 0x86, 0xa9, 0x88, 0xb2, 0x91, - 0x3a, 0xc8, 0xff, 0x56, 0x82, 0xaf, 0x0d, 0x7d, 0x48, 0x42, 0xcd, 0xc8, 0x21, 0xa9, 0xc7, 0x0e, - 0xc9, 0x72, 0x36, 0xc0, 0xeb, 0xeb, 0x44, 0x6c, 0xae, 0xbd, 0xf8, 0x62, 0xf9, 0xda, 0xcf, 0xbe, - 0x58, 0xbe, 0xf6, 0xf3, 0x2f, 0x96, 0xaf, 0xfd, 0xc1, 0xf9, 0xb2, 0xf4, 0xe2, 0x7c, 0x59, 0xfa, - 0xd9, 0xf9, 0xb2, 0xf4, 0xf3, 0xf3, 0x65, 0xe9, 0x3f, 0xce, 0x97, 0xa5, 0x3f, 0xf9, 0xc5, 0xf2, - 0xb5, 0x8f, 0x6f, 0x5f, 0xf8, 0x27, 0xff, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x34, 0xc8, - 0x81, 0x2b, 0x40, 0x00, 0x00, -} - -func (m *AllowedCSIDriver) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AllowedCSIDriver) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedCSIDriver) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *AllowedFlexVolume) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AllowedFlexVolume) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedFlexVolume) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Driver) - copy(dAtA[i:], m.Driver) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *AllowedHostPath) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AllowedHostPath) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedHostPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i-- - if m.ReadOnly { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - i -= len(m.PathPrefix) - copy(dAtA[i:], m.PathPrefix) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.PathPrefix))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + // 2890 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcf, 0x6f, 0x24, 0x47, + 0xf5, 0xdf, 0x9e, 0xf1, 0xd8, 0xe3, 0xe7, 0xb5, 0xbd, 0x5b, 0xeb, 0xac, 0x1d, 0xef, 0x37, 0x76, + 0xd4, 0x5f, 0x11, 0x36, 0x61, 0x33, 0xc3, 0x6e, 0x92, 0x25, 0x3f, 0xa4, 0x84, 0x1d, 0xef, 0x26, + 0xeb, 0xc4, 0x1e, 0x4f, 0x6a, 0xc6, 0x09, 0x8a, 0x08, 0xd0, 0xee, 0x29, 0x8f, 0x3b, 0xee, 0xe9, + 0x1e, 0x75, 0xd7, 0x98, 0x35, 0x27, 0x10, 0x5c, 0x72, 0x82, 0x4b, 0x20, 0x47, 0x10, 0x12, 0x57, + 0xae, 0x1c, 0x42, 0x04, 0x22, 0x48, 0x2b, 0xc4, 0x21, 0x12, 0x07, 0x72, 0xb2, 0x88, 0x73, 0x42, + 0xfc, 0x03, 0x68, 0x4f, 0xa8, 0x7e, 0x74, 0xf5, 0x6f, 0xbb, 0xc7, 0x38, 0x16, 0x41, 0x9c, 0x3c, + 0x5d, 0xef, 0xbd, 0x4f, 0xbd, 0xaa, 0x7a, 0xf5, 0xde, 0xa7, 0xba, 0xda, 0xf0, 0xf2, 0xee, 0xb3, + 0x7e, 0xcd, 0x72, 0xeb, 0xbb, 0xc3, 0x2d, 0xe2, 0x39, 0x84, 0x12, 0xbf, 0xbe, 0x47, 0x9c, 0xae, + 0xeb, 0xd5, 0xa5, 0xc0, 0x18, 0x58, 0x75, 0x72, 0x8f, 0x12, 0xc7, 0xb7, 0x5c, 0xc7, 0xaf, 0xef, + 0x5d, 0xdf, 0x22, 0xd4, 0xb8, 0x5e, 0xef, 0x11, 0x87, 0x78, 0x06, 0x25, 0xdd, 0xda, 0xc0, 0x73, + 0xa9, 0x8b, 0x1e, 0x11, 0xea, 0x35, 0x63, 0x60, 0xd5, 0x42, 0xf5, 0x9a, 0x54, 0x5f, 0x7c, 0xb2, + 0x67, 0xd1, 0x9d, 0xe1, 0x56, 0xcd, 0x74, 0xfb, 0xf5, 0x9e, 0xdb, 0x73, 0xeb, 0xdc, 0x6a, 0x6b, + 0xb8, 0xcd, 0x9f, 0xf8, 0x03, 0xff, 0x25, 0xd0, 0x16, 0xf5, 0x48, 0xe7, 0xa6, 0xeb, 0x91, 0xfa, + 0x5e, 0xaa, 0xc7, 0xc5, 0xa7, 0x43, 0x9d, 0xbe, 0x61, 0xee, 0x58, 0x0e, 0xf1, 0xf6, 0xeb, 0x83, + 0xdd, 0x1e, 0x6b, 0xf0, 0xeb, 0x7d, 0x42, 0x8d, 0x2c, 0xab, 0x7a, 0x9e, 0x95, 0x37, 0x74, 0xa8, + 0xd5, 0x27, 0x29, 0x83, 0x9b, 0xc7, 0x19, 0xf8, 0xe6, 0x0e, 0xe9, 0x1b, 0x29, 0xbb, 0xa7, 0xf2, + 0xec, 0x86, 0xd4, 0xb2, 0xeb, 0x96, 0x43, 0x7d, 0xea, 0x25, 0x8d, 0xf4, 0xf7, 0x4a, 0x30, 0x79, + 0xdb, 0x20, 0x7d, 0xd7, 0x69, 0x13, 0x8a, 0xbe, 0x03, 0x55, 0x36, 0x8c, 0xae, 0x41, 0x8d, 0x05, + 0xed, 0x51, 0xed, 0xea, 0xd4, 0x8d, 0xaf, 0xd6, 0xc2, 0x69, 0x56, 0xa8, 0xb5, 0xc1, 0x6e, 0x8f, + 0x35, 0xf8, 0x35, 0xa6, 0x5d, 0xdb, 0xbb, 0x5e, 0xdb, 0xd8, 0x7a, 0x87, 0x98, 0x74, 0x9d, 0x50, + 0xa3, 0x81, 0xee, 0x1f, 0x2c, 0x9f, 0x3b, 0x3c, 0x58, 0x86, 0xb0, 0x0d, 0x2b, 0x54, 0xd4, 0x84, + 0x31, 0x7f, 0x40, 0xcc, 0x85, 0x12, 0x47, 0xbf, 0x56, 0x3b, 0x72, 0x11, 0x6b, 0xca, 0xb3, 0xf6, + 0x80, 0x98, 0x8d, 0xf3, 0x12, 0x79, 0x8c, 0x3d, 0x61, 0x8e, 0x83, 0xde, 0x80, 0x71, 0x9f, 0x1a, + 0x74, 0xe8, 0x2f, 0x94, 0x39, 0x62, 0xad, 0x30, 0x22, 0xb7, 0x6a, 0xcc, 0x48, 0xcc, 0x71, 0xf1, + 0x8c, 0x25, 0x9a, 0xfe, 0xf7, 0x12, 0x20, 0xa5, 0xbb, 0xe2, 0x3a, 0x5d, 0x8b, 0x5a, 0xae, 0x83, + 0x9e, 0x87, 0x31, 0xba, 0x3f, 0x20, 0x7c, 0x72, 0x26, 0x1b, 0x8f, 0x05, 0x0e, 0x75, 0xf6, 0x07, + 0xe4, 0xc1, 0xc1, 0xf2, 0xe5, 0xb4, 0x05, 0x93, 0x60, 0x6e, 0x83, 0xd6, 0x94, 0xab, 0x25, 0x6e, + 0xfd, 0x74, 0xbc, 0xeb, 0x07, 0x07, 0xcb, 0x19, 0x41, 0x58, 0x53, 0x48, 0x71, 0x07, 0xd1, 0x1e, + 0x20, 0xdb, 0xf0, 0x69, 0xc7, 0x33, 0x1c, 0x5f, 0xf4, 0x64, 0xf5, 0x89, 0x9c, 0x84, 0x27, 0x8a, + 0x2d, 0x1a, 0xb3, 0x68, 0x2c, 0x4a, 0x2f, 0xd0, 0x5a, 0x0a, 0x0d, 0x67, 0xf4, 0x80, 0x1e, 0x83, + 0x71, 0x8f, 0x18, 0xbe, 0xeb, 0x2c, 0x8c, 0xf1, 0x51, 0xa8, 0x09, 0xc4, 0xbc, 0x15, 0x4b, 0x29, + 0x7a, 0x1c, 0x26, 0xfa, 0xc4, 0xf7, 0x8d, 0x1e, 0x59, 0xa8, 0x70, 0xc5, 0x59, 0xa9, 0x38, 0xb1, + 0x2e, 0x9a, 0x71, 0x20, 0xd7, 0x3f, 0xd0, 0x60, 0x5a, 0xcd, 0xdc, 0x9a, 0xe5, 0x53, 0xf4, 0xcd, + 0x54, 0x1c, 0xd6, 0x8a, 0x0d, 0x89, 0x59, 0xf3, 0x28, 0xbc, 0x20, 0x7b, 0xab, 0x06, 0x2d, 0x91, + 0x18, 0x5c, 0x87, 0x8a, 0x45, 0x49, 0x9f, 0xad, 0x43, 0xf9, 0xea, 0xd4, 0x8d, 0xab, 0x45, 0x43, + 0xa6, 0x31, 0x2d, 0x41, 0x2b, 0xab, 0xcc, 0x1c, 0x0b, 0x14, 0xfd, 0xa7, 0x63, 0x11, 0xf7, 0x59, + 0x68, 0xa2, 0xb7, 0xa1, 0xea, 0x13, 0x9b, 0x98, 0xd4, 0xf5, 0xa4, 0xfb, 0x4f, 0x15, 0x74, 0xdf, + 0xd8, 0x22, 0x76, 0x5b, 0x9a, 0x36, 0xce, 0x33, 0xff, 0x83, 0x27, 0xac, 0x20, 0xd1, 0xeb, 0x50, + 0xa5, 0xa4, 0x3f, 0xb0, 0x0d, 0x4a, 0xe4, 0x3e, 0xfa, 0xff, 0xe8, 0x10, 0x58, 0xe4, 0x30, 0xb0, + 0x96, 0xdb, 0xed, 0x48, 0x35, 0xbe, 0x7d, 0xd4, 0x94, 0x04, 0xad, 0x58, 0xc1, 0xa0, 0x3d, 0x98, + 0x19, 0x0e, 0xba, 0x4c, 0x93, 0xb2, 0xec, 0xd0, 0xdb, 0x97, 0x91, 0x74, 0xb3, 0xe8, 0xdc, 0x6c, + 0xc6, 0xac, 0x1b, 0x97, 0x65, 0x5f, 0x33, 0xf1, 0x76, 0x9c, 0xe8, 0x05, 0xdd, 0x82, 0xd9, 0xbe, + 0xe5, 0x60, 0x62, 0x74, 0xf7, 0xdb, 0xc4, 0x74, 0x9d, 0xae, 0xcf, 0xc3, 0xaa, 0xd2, 0x98, 0x97, + 0x00, 0xb3, 0xeb, 0x71, 0x31, 0x4e, 0xea, 0xa3, 0x57, 0x01, 0x05, 0xc3, 0x78, 0x45, 0x24, 0x37, + 0xcb, 0x75, 0x78, 0xcc, 0x95, 0xc3, 0xe0, 0xee, 0xa4, 0x34, 0x70, 0x86, 0x15, 0x5a, 0x83, 0x39, + 0x8f, 0xec, 0x59, 0x6c, 0x8c, 0x77, 0x2d, 0x9f, 0xba, 0xde, 0xfe, 0x9a, 0xd5, 0xb7, 0xe8, 0xc2, + 0x38, 0xf7, 0x69, 0xe1, 0xf0, 0x60, 0x79, 0x0e, 0x67, 0xc8, 0x71, 0xa6, 0x95, 0xfe, 0xb3, 0x71, + 0x98, 0x4d, 0xe4, 0x1b, 0xf4, 0x06, 0x5c, 0x36, 0x87, 0x9e, 0x47, 0x1c, 0xda, 0x1c, 0xf6, 0xb7, + 0x88, 0xd7, 0x36, 0x77, 0x48, 0x77, 0x68, 0x93, 0x2e, 0x0f, 0x94, 0x4a, 0x63, 0x49, 0x7a, 0x7c, + 0x79, 0x25, 0x53, 0x0b, 0xe7, 0x58, 0xb3, 0x59, 0x70, 0x78, 0xd3, 0xba, 0xe5, 0xfb, 0x0a, 0xb3, + 0xc4, 0x31, 0xd5, 0x2c, 0x34, 0x53, 0x1a, 0x38, 0xc3, 0x8a, 0xf9, 0xd8, 0x25, 0xbe, 0xe5, 0x91, + 0x6e, 0xd2, 0xc7, 0x72, 0xdc, 0xc7, 0xdb, 0x99, 0x5a, 0x38, 0xc7, 0x1a, 0x3d, 0x03, 0x53, 0xa2, + 0x37, 0xbe, 0x7e, 0x72, 0xa1, 0x2f, 0x49, 0xb0, 0xa9, 0x66, 0x28, 0xc2, 0x51, 0x3d, 0x36, 0x34, + 0x77, 0xcb, 0x27, 0xde, 0x1e, 0xe9, 0xe6, 0x2f, 0xf0, 0x46, 0x4a, 0x03, 0x67, 0x58, 0xb1, 0xa1, + 0x89, 0x08, 0x4c, 0x0d, 0x6d, 0x3c, 0x3e, 0xb4, 0xcd, 0x4c, 0x2d, 0x9c, 0x63, 0xcd, 0xe2, 0x58, + 0xb8, 0x7c, 0x6b, 0xcf, 0xb0, 0x6c, 0x63, 0xcb, 0x26, 0x0b, 0x13, 0xf1, 0x38, 0x6e, 0xc6, 0xc5, + 0x38, 0xa9, 0x8f, 0x5e, 0x81, 0x8b, 0xa2, 0x69, 0xd3, 0x31, 0x14, 0x48, 0x95, 0x83, 0x3c, 0x2c, + 0x41, 0x2e, 0x36, 0x93, 0x0a, 0x38, 0x6d, 0x83, 0x9e, 0x87, 0x19, 0xd3, 0xb5, 0x6d, 0x1e, 0x8f, + 0x2b, 0xee, 0xd0, 0xa1, 0x0b, 0x93, 0x1c, 0x05, 0xb1, 0xfd, 0xb8, 0x12, 0x93, 0xe0, 0x84, 0x26, + 0x22, 0x00, 0x66, 0x50, 0x70, 0xfc, 0x05, 0xe0, 0xf9, 0xf1, 0x7a, 0xd1, 0x1c, 0xa0, 0x4a, 0x55, + 0xc8, 0x01, 0x54, 0x93, 0x8f, 0x23, 0xc0, 0xfa, 0x9f, 0x34, 0x98, 0xcf, 0x49, 0x1d, 0xe8, 0xa5, + 0x58, 0x89, 0xfd, 0x4a, 0xa2, 0xc4, 0x5e, 0xc9, 0x31, 0x8b, 0xd4, 0x59, 0x07, 0xa6, 0x3d, 0x36, + 0x2a, 0xa7, 0x27, 0x54, 0x64, 0x8e, 0x7c, 0xe6, 0x98, 0x61, 0xe0, 0xa8, 0x4d, 0x98, 0xf3, 0x2f, + 0x1e, 0x1e, 0x2c, 0x4f, 0xc7, 0x64, 0x38, 0x0e, 0xaf, 0xbf, 0x5f, 0x02, 0xb8, 0x4d, 0x06, 0xb6, + 0xbb, 0xdf, 0x27, 0xce, 0x59, 0x70, 0xa8, 0x8d, 0x18, 0x87, 0x7a, 0xf2, 0xb8, 0xe5, 0x51, 0xae, + 0xe5, 0x92, 0xa8, 0x37, 0x13, 0x24, 0xaa, 0x5e, 0x1c, 0xf2, 0x68, 0x16, 0xf5, 0xd7, 0x32, 0x5c, + 0x0a, 0x95, 0x43, 0x1a, 0xf5, 0x42, 0x6c, 0x8d, 0xbf, 0x9c, 0x58, 0xe3, 0xf9, 0x0c, 0x93, 0xcf, + 0x8d, 0x47, 0xbd, 0x03, 0x33, 0x8c, 0xe5, 0x88, 0xb5, 0xe4, 0x1c, 0x6a, 0x7c, 0x64, 0x0e, 0xa5, + 0xaa, 0xdd, 0x5a, 0x0c, 0x09, 0x27, 0x90, 0x73, 0x38, 0xdb, 0xc4, 0x17, 0x91, 0xb3, 0x7d, 0xa8, + 0xc1, 0x4c, 0xb8, 0x4c, 0x67, 0x40, 0xda, 0x9a, 0x71, 0xd2, 0xf6, 0x78, 0xe1, 0x10, 0xcd, 0x61, + 0x6d, 0xff, 0x64, 0x04, 0x5f, 0x29, 0xb1, 0x0d, 0xbe, 0x65, 0x98, 0xbb, 0xe8, 0x51, 0x18, 0x73, + 0x8c, 0x7e, 0x10, 0x99, 0x6a, 0xb3, 0x34, 0x8d, 0x3e, 0xc1, 0x5c, 0x82, 0xde, 0xd3, 0x00, 0xc9, + 0x2a, 0x70, 0xcb, 0x71, 0x5c, 0x6a, 0x88, 0x5c, 0x29, 0xdc, 0x5a, 0x2d, 0xec, 0x56, 0xd0, 0x63, + 0x6d, 0x33, 0x85, 0x75, 0xc7, 0xa1, 0xde, 0x7e, 0xb8, 0xc8, 0x69, 0x05, 0x9c, 0xe1, 0x00, 0x32, + 0x00, 0x3c, 0x89, 0xd9, 0x71, 0xe5, 0x46, 0x7e, 0xb2, 0x40, 0xce, 0x63, 0x06, 0x2b, 0xae, 0xb3, + 0x6d, 0xf5, 0xc2, 0xb4, 0x83, 0x15, 0x10, 0x8e, 0x80, 0x2e, 0xde, 0x81, 0xf9, 0x1c, 0x6f, 0xd1, + 0x05, 0x28, 0xef, 0x92, 0x7d, 0x31, 0x6d, 0x98, 0xfd, 0x44, 0x73, 0x50, 0xd9, 0x33, 0xec, 0xa1, + 0x48, 0xbf, 0x93, 0x58, 0x3c, 0x3c, 0x5f, 0x7a, 0x56, 0xd3, 0x3f, 0xa8, 0x44, 0x63, 0x87, 0x33, + 0xe6, 0xab, 0x50, 0xf5, 0xc8, 0xc0, 0xb6, 0x4c, 0xc3, 0x97, 0x44, 0x88, 0x93, 0x5f, 0x2c, 0xdb, + 0xb0, 0x92, 0xc6, 0xb8, 0x75, 0xe9, 0xf3, 0xe5, 0xd6, 0xe5, 0xd3, 0xe1, 0xd6, 0xdf, 0x86, 0xaa, + 0x1f, 0xb0, 0xea, 0x31, 0x0e, 0x79, 0x7d, 0x84, 0xfc, 0x2a, 0x09, 0xb5, 0xea, 0x40, 0x51, 0x69, + 0x05, 0x9a, 0x45, 0xa2, 0x2b, 0x23, 0x92, 0xe8, 0x53, 0x25, 0xbe, 0x2c, 0xdf, 0x0c, 0x8c, 0xa1, + 0x4f, 0xba, 0x3c, 0xb7, 0x55, 0xc3, 0x7c, 0xd3, 0xe2, 0xad, 0x58, 0x4a, 0xd1, 0xdb, 0xb1, 0x90, + 0xad, 0x9e, 0x24, 0x64, 0x67, 0xf2, 0xc3, 0x15, 0x6d, 0xc2, 0xfc, 0xc0, 0x73, 0x7b, 0x1e, 0xf1, + 0xfd, 0xdb, 0xc4, 0xe8, 0xda, 0x96, 0x43, 0x82, 0xf9, 0x11, 0x8c, 0xe8, 0xca, 0xe1, 0xc1, 0xf2, + 0x7c, 0x2b, 0x5b, 0x05, 0xe7, 0xd9, 0xea, 0xf7, 0xc7, 0xe0, 0x42, 0xb2, 0x02, 0xe6, 0x90, 0x54, + 0xed, 0x44, 0x24, 0xf5, 0x5a, 0x64, 0x33, 0x08, 0x06, 0xaf, 0x56, 0x3f, 0x63, 0x43, 0xdc, 0x82, + 0x59, 0x99, 0x0d, 0x02, 0xa1, 0xa4, 0xe9, 0x6a, 0xf5, 0x37, 0xe3, 0x62, 0x9c, 0xd4, 0x47, 0x2f, + 0xc0, 0xb4, 0xc7, 0x79, 0x77, 0x00, 0x20, 0xb8, 0xeb, 0x43, 0x12, 0x60, 0x1a, 0x47, 0x85, 0x38, + 0xae, 0xcb, 0x78, 0x6b, 0x48, 0x47, 0x03, 0x80, 0xb1, 0x38, 0x6f, 0xbd, 0x95, 0x54, 0xc0, 0x69, + 0x1b, 0xb4, 0x0e, 0x97, 0x86, 0x4e, 0x1a, 0x4a, 0x84, 0xf2, 0x15, 0x09, 0x75, 0x69, 0x33, 0xad, + 0x82, 0xb3, 0xec, 0xd0, 0x76, 0x8c, 0xca, 0x8e, 0xf3, 0xf4, 0x7c, 0xa3, 0xf0, 0xc6, 0x2b, 0xcc, + 0x65, 0x33, 0xe8, 0x76, 0xb5, 0x28, 0xdd, 0xd6, 0x7f, 0xaf, 0x45, 0x8b, 0x90, 0xa2, 0xc0, 0xc7, + 0xbd, 0x65, 0x4a, 0x59, 0x44, 0xd8, 0x91, 0x9b, 0xcd, 0x7e, 0x6f, 0x8e, 0xc4, 0x7e, 0xc3, 0xe2, + 0x79, 0x3c, 0xfd, 0xfd, 0x83, 0x06, 0xb3, 0x77, 0x3b, 0x9d, 0xd6, 0xaa, 0xc3, 0x77, 0x4b, 0xcb, + 0xa0, 0x3b, 0xac, 0x8a, 0x0e, 0x0c, 0xba, 0x93, 0xac, 0xa2, 0x4c, 0x86, 0xb9, 0x04, 0x3d, 0x0d, + 0x55, 0xf6, 0x97, 0x39, 0xce, 0xc3, 0x75, 0x92, 0x27, 0x99, 0x6a, 0x4b, 0xb6, 0x3d, 0x88, 0xfc, + 0xc6, 0x4a, 0x13, 0x7d, 0x03, 0x26, 0xd8, 0xde, 0x26, 0x4e, 0xb7, 0x20, 0xf9, 0x95, 0x4e, 0x35, + 0x84, 0x51, 0xc8, 0x67, 0x64, 0x03, 0x0e, 0xe0, 0xf4, 0x5d, 0x98, 0x8b, 0x0c, 0x02, 0x0f, 0x6d, + 0xf2, 0x06, 0xab, 0x57, 0xa8, 0x0d, 0x15, 0xd6, 0x3b, 0xab, 0x4a, 0xe5, 0x02, 0xaf, 0x17, 0x13, + 0x13, 0x11, 0x72, 0x0f, 0xf6, 0xe4, 0x63, 0x81, 0xa5, 0x6f, 0xc0, 0xc4, 0x6a, 0xab, 0x61, 0xbb, + 0x82, 0x6f, 0x98, 0x56, 0xd7, 0x4b, 0xce, 0xd4, 0xca, 0xea, 0x6d, 0x8c, 0xb9, 0x04, 0xe9, 0x30, + 0x4e, 0xee, 0x99, 0x64, 0x40, 0x39, 0xc5, 0x98, 0x6c, 0x00, 0x4b, 0xa4, 0x77, 0x78, 0x0b, 0x96, + 0x12, 0xfd, 0xc7, 0x25, 0x98, 0x90, 0xdd, 0x9e, 0xc1, 0xf9, 0x63, 0x2d, 0x76, 0xfe, 0x78, 0xa2, + 0xd8, 0x12, 0xe4, 0x1e, 0x3e, 0x3a, 0x89, 0xc3, 0xc7, 0xb5, 0x82, 0x78, 0x47, 0x9f, 0x3c, 0xde, + 0x2d, 0xc1, 0x4c, 0x7c, 0xf1, 0xd1, 0x33, 0x30, 0xc5, 0x52, 0xad, 0x65, 0x92, 0x66, 0xc8, 0xf0, + 0xd4, 0xeb, 0x87, 0x76, 0x28, 0xc2, 0x51, 0x3d, 0xd4, 0x53, 0x66, 0x2d, 0xd7, 0xa3, 0x72, 0xd0, + 0xf9, 0x53, 0x3a, 0xa4, 0x96, 0x5d, 0x13, 0x2f, 0xdb, 0x6b, 0xab, 0x0e, 0xdd, 0xf0, 0xda, 0xd4, + 0xb3, 0x9c, 0x5e, 0xaa, 0x23, 0x06, 0x86, 0xa3, 0xc8, 0xe8, 0x4d, 0x96, 0xf6, 0x7d, 0x77, 0xe8, + 0x99, 0x24, 0x8b, 0xbe, 0x05, 0xd4, 0x83, 0x6d, 0x84, 0xee, 0x9a, 0x6b, 0x1a, 0xb6, 0x58, 0x1c, + 0x4c, 0xb6, 0x89, 0x47, 0x1c, 0x93, 0x04, 0x94, 0x49, 0x40, 0x60, 0x05, 0xa6, 0xff, 0x46, 0x83, + 0x29, 0x39, 0x17, 0x67, 0x40, 0xd4, 0x5f, 0x8b, 0x13, 0xf5, 0xc7, 0x0a, 0xee, 0xd0, 0x6c, 0x96, + 0xfe, 0x5b, 0x0d, 0x16, 0x03, 0xd7, 0x5d, 0xa3, 0xdb, 0x30, 0x6c, 0xc3, 0x31, 0x89, 0x17, 0xc4, + 0xfa, 0x22, 0x94, 0xac, 0x81, 0x5c, 0x49, 0x90, 0x00, 0xa5, 0xd5, 0x16, 0x2e, 0x59, 0x03, 0x56, + 0x45, 0x77, 0x5c, 0x9f, 0x72, 0x36, 0x2f, 0x0e, 0x8a, 0xca, 0xeb, 0xbb, 0xb2, 0x1d, 0x2b, 0x0d, + 0xb4, 0x09, 0x95, 0x81, 0xeb, 0x51, 0x56, 0xb9, 0xca, 0x89, 0xf5, 0x3d, 0xc2, 0x6b, 0xb6, 0x6e, + 0x32, 0x10, 0xc3, 0x9d, 0xce, 0x60, 0xb0, 0x40, 0xd3, 0x7f, 0xa0, 0xc1, 0xc3, 0x19, 0xfe, 0x4b, + 0xd2, 0xd0, 0x85, 0x09, 0x4b, 0x08, 0x65, 0x7a, 0x79, 0xae, 0x58, 0xb7, 0x19, 0x53, 0x11, 0xa6, + 0xb6, 0x20, 0x85, 0x05, 0xd0, 0xfa, 0x2f, 0x35, 0xb8, 0x98, 0xf2, 0x97, 0xa7, 0x68, 0x16, 0xcf, + 0x92, 0x6d, 0xab, 0x14, 0xcd, 0xc2, 0x92, 0x4b, 0xd0, 0x6b, 0x50, 0xe5, 0x77, 0x44, 0xa6, 0x6b, + 0xcb, 0x09, 0xac, 0x07, 0x13, 0xd8, 0x92, 0xed, 0x0f, 0x0e, 0x96, 0xaf, 0x64, 0x9c, 0xb5, 0x03, + 0x31, 0x56, 0x00, 0x68, 0x19, 0x2a, 0xc4, 0xf3, 0x5c, 0x4f, 0x26, 0xfb, 0x49, 0x36, 0x53, 0x77, + 0x58, 0x03, 0x16, 0xed, 0xfa, 0xaf, 0xc2, 0x20, 0x65, 0xd9, 0x97, 0xf9, 0xc7, 0x16, 0x27, 0x99, + 0x18, 0xd9, 0xd2, 0x61, 0x2e, 0x41, 0x43, 0xb8, 0x60, 0x25, 0xd2, 0xb5, 0xdc, 0x9d, 0xf5, 0x62, + 0xd3, 0xa8, 0xcc, 0x1a, 0x0b, 0x12, 0xfe, 0x42, 0x52, 0x82, 0x53, 0x5d, 0xe8, 0x04, 0x52, 0x5a, + 0xe8, 0x75, 0x18, 0xdb, 0xa1, 0x74, 0x90, 0xf1, 0xb2, 0xff, 0x98, 0x22, 0x11, 0xba, 0x50, 0xe5, + 0xa3, 0xeb, 0x74, 0x5a, 0x98, 0x43, 0xe9, 0xbf, 0x2b, 0xa9, 0xf9, 0xe0, 0x27, 0xa4, 0xaf, 0xab, + 0xd1, 0xae, 0xd8, 0x86, 0xef, 0xf3, 0x14, 0x26, 0x4e, 0xf3, 0x73, 0x11, 0xc7, 0x95, 0x0c, 0xa7, + 0xb4, 0x51, 0x27, 0x2c, 0x9e, 0xda, 0x49, 0x8a, 0xe7, 0x54, 0x56, 0xe1, 0x44, 0x77, 0xa1, 0x4c, + 0xed, 0xa2, 0xa7, 0x72, 0x89, 0xd8, 0x59, 0x6b, 0x37, 0xa6, 0xe4, 0x94, 0x97, 0x3b, 0x6b, 0x6d, + 0xcc, 0x20, 0xd0, 0x06, 0x54, 0xbc, 0xa1, 0x4d, 0x58, 0x1d, 0x28, 0x17, 0xaf, 0x2b, 0x6c, 0x06, + 0xc3, 0xcd, 0xc7, 0x9e, 0x7c, 0x2c, 0x70, 0xf4, 0x1f, 0x6a, 0x30, 0x1d, 0xab, 0x16, 0xc8, 0x83, + 0xf3, 0x76, 0x64, 0xef, 0xc8, 0x79, 0x78, 0x76, 0xf4, 0x5d, 0x27, 0x37, 0xfd, 0x9c, 0xec, 0xf7, + 0x7c, 0x54, 0x86, 0x63, 0x7d, 0xe8, 0x06, 0x40, 0x38, 0x6c, 0xb6, 0x0f, 0x58, 0xf0, 0x8a, 0x0d, + 0x2f, 0xf7, 0x01, 0x8b, 0x69, 0x1f, 0x8b, 0x76, 0x74, 0x03, 0xc0, 0x27, 0xa6, 0x47, 0x68, 0x33, + 0x4c, 0x5c, 0xaa, 0x1c, 0xb7, 0x95, 0x04, 0x47, 0xb4, 0xf4, 0x5f, 0x94, 0x60, 0xba, 0x49, 0xe8, + 0x77, 0x5d, 0x6f, 0xb7, 0xe5, 0xda, 0x96, 0xb9, 0x7f, 0x06, 0x24, 0x00, 0xc7, 0x48, 0xc0, 0x71, + 0xf9, 0x32, 0xe6, 0x5d, 0x2e, 0x15, 0x78, 0x2b, 0x41, 0x05, 0x6e, 0x8c, 0x84, 0x7a, 0x34, 0x21, + 0xf8, 0x50, 0x83, 0xf9, 0x98, 0xfe, 0x9d, 0x30, 0xd7, 0xa8, 0xe4, 0xaf, 0x15, 0x4a, 0xfe, 0x31, + 0x18, 0x96, 0x30, 0xb3, 0x93, 0x3f, 0x5a, 0x83, 0x12, 0x75, 0xe5, 0xce, 0x18, 0x0d, 0x93, 0x10, + 0x2f, 0xac, 0x67, 0x1d, 0x17, 0x97, 0xa8, 0xab, 0xff, 0x51, 0x83, 0x85, 0x98, 0x56, 0x34, 0x5b, + 0x7e, 0x4e, 0x23, 0xc0, 0x30, 0xb6, 0xed, 0xb9, 0xfd, 0x13, 0x8f, 0x41, 0x2d, 0xf2, 0xcb, 0x9e, + 0xdb, 0xc7, 0x1c, 0x4b, 0xff, 0x48, 0x83, 0x8b, 0x31, 0xcd, 0x33, 0xe0, 0x24, 0xaf, 0xc7, 0x39, + 0xc9, 0xb5, 0x51, 0x06, 0x92, 0xc3, 0x4c, 0x3e, 0x2a, 0x25, 0x86, 0xc1, 0x06, 0x8c, 0xb6, 0x61, + 0x6a, 0xe0, 0x76, 0xdb, 0xa7, 0x70, 0xf9, 0x3b, 0xcb, 0xb8, 0x62, 0x2b, 0xc4, 0xc2, 0x51, 0x60, + 0x74, 0x0f, 0x2e, 0x32, 0xda, 0xe2, 0x0f, 0x0c, 0x93, 0xb4, 0x4f, 0xe1, 0x75, 0xd8, 0x43, 0xfc, + 0x76, 0x29, 0x89, 0x88, 0xd3, 0x9d, 0xa0, 0x75, 0x98, 0xb0, 0x06, 0xfc, 0xec, 0x22, 0x37, 0xe9, + 0xb1, 0x04, 0x4f, 0x9c, 0x74, 0x44, 0xf9, 0x90, 0x0f, 0x38, 0xc0, 0xd0, 0xff, 0x92, 0x8c, 0x06, + 0x4e, 0x85, 0x5f, 0x89, 0x50, 0x0f, 0x79, 0x0f, 0x74, 0x32, 0xda, 0xd1, 0x94, 0x2c, 0xe7, 0xa4, + 0xac, 0xbd, 0x9a, 0xe0, 0x44, 0x5f, 0x82, 0x09, 0xe2, 0x74, 0xf9, 0x41, 0x40, 0xbc, 0x64, 0xe1, + 0xa3, 0xba, 0x23, 0x9a, 0x70, 0x20, 0xd3, 0x7f, 0x54, 0x4e, 0x8c, 0x8a, 0x97, 0xf0, 0x77, 0x4e, + 0x2d, 0x38, 0xd4, 0x61, 0x22, 0x37, 0x40, 0xb6, 0x42, 0x6a, 0x29, 0x62, 0xfe, 0x6b, 0xa3, 0xc4, + 0x7c, 0xb4, 0xb6, 0xe6, 0x12, 0x4b, 0xf4, 0x2d, 0x18, 0x27, 0xa2, 0x0b, 0x51, 0xb1, 0x6f, 0x8e, + 0xd2, 0x45, 0x98, 0x7e, 0xc3, 0x94, 0x2d, 0xdb, 0x24, 0x2a, 0x7a, 0x89, 0xcd, 0x17, 0xd3, 0x65, + 0x47, 0x1e, 0xc1, 0xcc, 0x27, 0x1b, 0x8f, 0x88, 0x61, 0xab, 0xe6, 0x07, 0x07, 0xcb, 0x10, 0x3e, + 0xe2, 0xa8, 0x85, 0xfe, 0x3d, 0xb8, 0x94, 0x51, 0x22, 0x90, 0x19, 0x7b, 0x33, 0x24, 0x32, 0x66, + 0xbd, 0xd8, 0x32, 0x14, 0xbf, 0xe2, 0x7c, 0xbf, 0x04, 0x20, 0xdf, 0x45, 0x9d, 0xcd, 0x97, 0x55, + 0xa3, 0xdd, 0x0a, 0x86, 0xae, 0x9d, 0xda, 0xad, 0x60, 0x04, 0xf2, 0xe8, 0x52, 0xfc, 0x8f, 0x12, + 0x5c, 0x0a, 0x95, 0x0b, 0xdf, 0x0a, 0x66, 0x98, 0xfc, 0xef, 0xeb, 0xaa, 0x62, 0x37, 0x75, 0xe1, + 0xd4, 0xfd, 0xe7, 0xdd, 0xd4, 0x85, 0xbe, 0xe5, 0x54, 0xda, 0x5f, 0x97, 0xa2, 0x03, 0x18, 0xf1, + 0xba, 0xe8, 0x14, 0x3e, 0x30, 0xfa, 0xc2, 0xdd, 0x38, 0xe9, 0x7f, 0x2e, 0xc3, 0x85, 0xe4, 0x6e, + 0x8c, 0xdd, 0x2a, 0x68, 0xc7, 0xde, 0x2a, 0xb4, 0x60, 0x6e, 0x7b, 0x68, 0xdb, 0xfb, 0x7c, 0x0c, + 0x91, 0xab, 0x05, 0x71, 0x1f, 0xf1, 0x7f, 0xd2, 0x72, 0xee, 0xe5, 0x0c, 0x1d, 0x9c, 0x69, 0x99, + 0xbe, 0x64, 0x18, 0xfb, 0x77, 0x2f, 0x19, 0x2a, 0x27, 0xb8, 0x64, 0xc8, 0xbe, 0xa7, 0x29, 0x9f, + 0xe8, 0x9e, 0xe6, 0x24, 0x37, 0x0c, 0x19, 0x49, 0xec, 0xd8, 0x52, 0xf2, 0x22, 0xcc, 0xc4, 0x6f, + 0xbd, 0xc4, 0x5a, 0x8a, 0x8b, 0x37, 0x79, 0xc7, 0x14, 0x59, 0x4b, 0xd1, 0x8e, 0x95, 0x86, 0x7e, + 0xa8, 0xc1, 0xe5, 0xec, 0xaf, 0x5b, 0x90, 0x0d, 0x33, 0x7d, 0xe3, 0x5e, 0xf4, 0x8b, 0x23, 0xed, + 0x84, 0x4c, 0x89, 0x5f, 0x77, 0xac, 0xc7, 0xb0, 0x70, 0x02, 0x1b, 0xbd, 0x05, 0xd5, 0xbe, 0x71, + 0xaf, 0x3d, 0xf4, 0x7a, 0xe4, 0xc4, 0x8c, 0x8c, 0x6f, 0xa3, 0x75, 0x89, 0x82, 0x15, 0x9e, 0xfe, + 0x99, 0x06, 0xf3, 0x39, 0x97, 0x18, 0xff, 0x45, 0xa3, 0x7c, 0xb7, 0x04, 0x95, 0xb6, 0x69, 0xd8, + 0xe4, 0x0c, 0x08, 0xc5, 0xab, 0x31, 0x42, 0x71, 0xdc, 0x57, 0xb2, 0xdc, 0xab, 0x5c, 0x2e, 0x81, + 0x13, 0x5c, 0xe2, 0x89, 0x42, 0x68, 0x47, 0xd3, 0x88, 0xe7, 0x60, 0x52, 0x75, 0x3a, 0x5a, 0x76, + 0xd3, 0x7f, 0x5e, 0x82, 0xa9, 0x48, 0x17, 0x23, 0xe6, 0xc6, 0xed, 0x58, 0x41, 0x28, 0x17, 0x78, + 0x83, 0x14, 0xe9, 0xab, 0x16, 0x94, 0x00, 0xf1, 0x95, 0x47, 0x78, 0xaf, 0x9f, 0xae, 0x0c, 0x2f, + 0xc2, 0x0c, 0x35, 0xbc, 0x1e, 0xa1, 0xea, 0xc8, 0x20, 0x5e, 0x9e, 0xaa, 0xcf, 0x8d, 0x3a, 0x31, + 0x29, 0x4e, 0x68, 0x2f, 0xbe, 0x00, 0xd3, 0xb1, 0xce, 0x46, 0xf9, 0x48, 0xa3, 0xb1, 0x72, 0xff, + 0xd3, 0xa5, 0x73, 0x1f, 0x7f, 0xba, 0x74, 0xee, 0x93, 0x4f, 0x97, 0xce, 0x7d, 0xff, 0x70, 0x49, + 0xbb, 0x7f, 0xb8, 0xa4, 0x7d, 0x7c, 0xb8, 0xa4, 0x7d, 0x72, 0xb8, 0xa4, 0xfd, 0xed, 0x70, 0x49, + 0xfb, 0xc9, 0x67, 0x4b, 0xe7, 0xde, 0x7a, 0xe4, 0xc8, 0xff, 0xd9, 0xf8, 0x57, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x39, 0x36, 0x95, 0x55, 0xec, 0x31, 0x00, 0x00, } func (m *DaemonSet) Marshal() (dAtA []byte, err error) { @@ -2788,7 +2320,7 @@ func (m *DeploymentStrategy) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *FSGroupStrategyOptions) Marshal() (dAtA []byte, err error) { +func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2798,54 +2330,12 @@ func (m *FSGroupStrategyOptions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *FSGroupStrategyOptions) MarshalTo(dAtA []byte) (int, error) { +func (m *HTTPIngressPath) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *FSGroupStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HTTPIngressPath) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HTTPIngressPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *HTTPIngressPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2912,64 +2402,6 @@ func (m *HTTPIngressRuleValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *HostPortRange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HostPortRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HostPortRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Max)) - i-- - dAtA[i] = 0x10 - i = encodeVarintGenerated(dAtA, i, uint64(m.Min)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - -func (m *IDRange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *IDRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *IDRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Max)) - i-- - dAtA[i] = 0x10 - i = encodeVarintGenerated(dAtA, i, uint64(m.Min)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - func (m *IPBlock) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3157,6 +2589,128 @@ func (m *IngressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *IngressLoadBalancerIngress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerIngress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerIngress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ports) > 0 { + for iNdEx := len(m.Ports) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ports[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + i -= len(m.Hostname) + copy(dAtA[i:], m.Hostname) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Hostname))) + i-- + dAtA[i] = 0x12 + i -= len(m.IP) + copy(dAtA[i:], m.IP) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IP))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IngressLoadBalancerStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ingress) > 0 { + for iNdEx := len(m.Ingress) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ingress[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *IngressPortStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressPortStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressPortStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != nil { + i -= len(*m.Error) + copy(dAtA[i:], *m.Error) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Error))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0x12 + i = encodeVarintGenerated(dAtA, i, uint64(m.Port)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *IngressRule) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3785,7 +3339,7 @@ func (m *NetworkPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSecurityPolicy) Marshal() (dAtA []byte, err error) { +func (m *ReplicaSet) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3795,16 +3349,26 @@ func (m *PodSecurityPolicy) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSecurityPolicy) MarshalTo(dAtA []byte) (int, error) { +func (m *ReplicaSet) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSecurityPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ReplicaSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a { size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -3828,7 +3392,60 @@ func (m *PodSecurityPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSecurityPolicyList) Marshal() (dAtA []byte, err error) { +func (m *ReplicaSetCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReplicaSetCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReplicaSetCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x2a + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x22 + { + size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + i -= len(m.Status) + copy(dAtA[i:], m.Status) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) + i-- + dAtA[i] = 0x12 + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ReplicaSetList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3838,12 +3455,12 @@ func (m *PodSecurityPolicyList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSecurityPolicyList) MarshalTo(dAtA []byte) (int, error) { +func (m *ReplicaSetList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSecurityPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ReplicaSetList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -3875,7 +3492,7 @@ func (m *PodSecurityPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSecurityPolicySpec) Marshal() (dAtA []byte, err error) { +func (m *ReplicaSetSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3885,49 +3502,32 @@ func (m *PodSecurityPolicySpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSecurityPolicySpec) MarshalTo(dAtA []byte) (int, error) { +func (m *ReplicaSetSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSecurityPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ReplicaSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.RuntimeClass != nil { - { - size, err := m.RuntimeClass.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xc2 - } - if len(m.AllowedCSIDrivers) > 0 { - for iNdEx := len(m.AllowedCSIDrivers) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedCSIDrivers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xba + i = encodeVarintGenerated(dAtA, i, uint64(m.MinReadySeconds)) + i-- + dAtA[i] = 0x20 + { + size, err := m.Template.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if m.RunAsGroup != nil { + i-- + dAtA[i] = 0x1a + if m.Selector != nil { { - size, err := m.RunAsGroup.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -3935,165 +3535,40 @@ func (m *PodSecurityPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xb2 - } - if len(m.AllowedProcMountTypes) > 0 { - for iNdEx := len(m.AllowedProcMountTypes) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedProcMountTypes[iNdEx]) - copy(dAtA[i:], m.AllowedProcMountTypes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedProcMountTypes[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xaa - } - } - if len(m.ForbiddenSysctls) > 0 { - for iNdEx := len(m.ForbiddenSysctls) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ForbiddenSysctls[iNdEx]) - copy(dAtA[i:], m.ForbiddenSysctls[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ForbiddenSysctls[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xa2 - } - } - if len(m.AllowedUnsafeSysctls) > 0 { - for iNdEx := len(m.AllowedUnsafeSysctls) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedUnsafeSysctls[iNdEx]) - copy(dAtA[i:], m.AllowedUnsafeSysctls[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedUnsafeSysctls[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x9a - } - } - if len(m.AllowedFlexVolumes) > 0 { - for iNdEx := len(m.AllowedFlexVolumes) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedFlexVolumes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x92 - } - } - if len(m.AllowedHostPaths) > 0 { - for iNdEx := len(m.AllowedHostPaths) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedHostPaths[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x8a - } - } - if m.AllowPrivilegeEscalation != nil { - i-- - if *m.AllowPrivilegeEscalation { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x80 + dAtA[i] = 0x12 } - if m.DefaultAllowPrivilegeEscalation != nil { - i-- - if *m.DefaultAllowPrivilegeEscalation { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } + if m.Replicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Replicas)) i-- - dAtA[i] = 0x78 - } - i-- - if m.ReadOnlyRootFilesystem { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x70 - { - size, err := m.FSGroup.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x6a - { - size, err := m.SupplementalGroups.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x62 - { - size, err := m.RunAsUser.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x5a - { - size, err := m.SELinux.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - i-- - if m.HostIPC { - dAtA[i] = 1 - } else { - dAtA[i] = 0 + dAtA[i] = 0x8 } - i-- - dAtA[i] = 0x48 - i-- - if m.HostPID { - dAtA[i] = 1 - } else { - dAtA[i] = 0 + return len(dAtA) - i, nil +} + +func (m *ReplicaSetStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - i-- - dAtA[i] = 0x40 - if len(m.HostPorts) > 0 { - for iNdEx := len(m.HostPorts) - 1; iNdEx >= 0; iNdEx-- { + return dAtA[:n], nil +} + +func (m *ReplicaSetStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReplicaSetStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.HostPorts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -4101,65 +3576,28 @@ func (m *PodSecurityPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 } } + i = encodeVarintGenerated(dAtA, i, uint64(m.AvailableReplicas)) i-- - if m.HostNetwork { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } + dAtA[i] = 0x28 + i = encodeVarintGenerated(dAtA, i, uint64(m.ReadyReplicas)) i-- - dAtA[i] = 0x30 - if len(m.Volumes) > 0 { - for iNdEx := len(m.Volumes) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Volumes[iNdEx]) - copy(dAtA[i:], m.Volumes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Volumes[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(m.AllowedCapabilities) > 0 { - for iNdEx := len(m.AllowedCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedCapabilities[iNdEx]) - copy(dAtA[i:], m.AllowedCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.RequiredDropCapabilities) > 0 { - for iNdEx := len(m.RequiredDropCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.RequiredDropCapabilities[iNdEx]) - copy(dAtA[i:], m.RequiredDropCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.RequiredDropCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.DefaultAddCapabilities) > 0 { - for iNdEx := len(m.DefaultAddCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.DefaultAddCapabilities[iNdEx]) - copy(dAtA[i:], m.DefaultAddCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.DefaultAddCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x12 - } - } + dAtA[i] = 0x20 + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) i-- - if m.Privileged { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } + dAtA[i] = 0x18 + i = encodeVarintGenerated(dAtA, i, uint64(m.FullyLabeledReplicas)) + i-- + dAtA[i] = 0x10 + i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas)) i-- dAtA[i] = 0x8 return len(dAtA) - i, nil } -func (m *ReplicaSet) Marshal() (dAtA []byte, err error) { +func (m *RollbackConfig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4169,50 +3607,23 @@ func (m *ReplicaSet) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ReplicaSet) MarshalTo(dAtA []byte) (int, error) { +func (m *RollbackConfig) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ReplicaSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RollbackConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i = encodeVarintGenerated(dAtA, i, uint64(m.Revision)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 return len(dAtA) - i, nil } -func (m *ReplicaSetCondition) Marshal() (dAtA []byte, err error) { +func (m *RollingUpdateDaemonSet) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4222,132 +3633,31 @@ func (m *ReplicaSetCondition) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ReplicaSetCondition) MarshalTo(dAtA []byte) (int, error) { +func (m *RollingUpdateDaemonSet) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ReplicaSetCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RollingUpdateDaemonSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.Message) - copy(dAtA[i:], m.Message) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i-- - dAtA[i] = 0x2a - i -= len(m.Reason) - copy(dAtA[i:], m.Reason) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) - i-- - dAtA[i] = 0x22 - { - size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.MaxSurge != nil { + { + size, err := m.MaxSurge.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } - i-- - dAtA[i] = 0x1a - i -= len(m.Status) - copy(dAtA[i:], m.Status) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i-- - dAtA[i] = 0x12 - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ReplicaSetList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ReplicaSetList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ReplicaSetList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ReplicaSetSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ReplicaSetSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ReplicaSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.MinReadySeconds)) - i-- - dAtA[i] = 0x20 - { - size, err := m.Template.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if m.Selector != nil { + if m.MaxUnavailable != nil { { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.MaxUnavailable.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -4355,95 +3665,12 @@ func (m *ReplicaSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 - } - if m.Replicas != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.Replicas)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *ReplicaSetStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ReplicaSetStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ReplicaSetStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Conditions) > 0 { - for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - } - } - i = encodeVarintGenerated(dAtA, i, uint64(m.AvailableReplicas)) - i-- - dAtA[i] = 0x28 - i = encodeVarintGenerated(dAtA, i, uint64(m.ReadyReplicas)) - i-- - dAtA[i] = 0x20 - i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) - i-- - dAtA[i] = 0x18 - i = encodeVarintGenerated(dAtA, i, uint64(m.FullyLabeledReplicas)) - i-- - dAtA[i] = 0x10 - i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - -func (m *RollbackConfig) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err + dAtA[i] = 0xa } - return dAtA[:n], nil -} - -func (m *RollbackConfig) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RollbackConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Revision)) - i-- - dAtA[i] = 0x8 return len(dAtA) - i, nil } -func (m *RollingUpdateDaemonSet) Marshal() (dAtA []byte, err error) { +func (m *RollingUpdateDeployment) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4453,12 +3680,12 @@ func (m *RollingUpdateDaemonSet) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RollingUpdateDaemonSet) MarshalTo(dAtA []byte) (int, error) { +func (m *RollingUpdateDeployment) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RollingUpdateDaemonSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RollingUpdateDeployment) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4490,7 +3717,7 @@ func (m *RollingUpdateDaemonSet) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *RollingUpdateDeployment) Marshal() (dAtA []byte, err error) { +func (m *Scale) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4500,44 +3727,50 @@ func (m *RollingUpdateDeployment) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RollingUpdateDeployment) MarshalTo(dAtA []byte) (int, error) { +func (m *Scale) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RollingUpdateDeployment) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Scale) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.MaxSurge != nil { - { - size, err := m.MaxSurge.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } - i-- - dAtA[i] = 0x12 + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if m.MaxUnavailable != nil { - { - size, err := m.MaxUnavailable.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } - i-- - dAtA[i] = 0xa + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *RunAsGroupStrategyOptions) Marshal() (dAtA []byte, err error) { +func (m *ScaleSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4547,39 +3780,23 @@ func (m *RunAsGroupStrategyOptions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RunAsGroupStrategyOptions) MarshalTo(dAtA []byte) (int, error) { +func (m *ScaleSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RunAsGroupStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ScaleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) + i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 return len(dAtA) - i, nil } -func (m *RunAsUserStrategyOptions) Marshal() (dAtA []byte, err error) { +func (m *ScaleStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4589,207 +3806,7 @@ func (m *RunAsUserStrategyOptions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RunAsUserStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RunAsUserStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *RuntimeClassStrategyOptions) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RuntimeClassStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RuntimeClassStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.DefaultRuntimeClassName != nil { - i -= len(*m.DefaultRuntimeClassName) - copy(dAtA[i:], *m.DefaultRuntimeClassName) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.DefaultRuntimeClassName))) - i-- - dAtA[i] = 0x12 - } - if len(m.AllowedRuntimeClassNames) > 0 { - for iNdEx := len(m.AllowedRuntimeClassNames) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedRuntimeClassNames[iNdEx]) - copy(dAtA[i:], m.AllowedRuntimeClassNames[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedRuntimeClassNames[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *SELinuxStrategyOptions) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SELinuxStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SELinuxStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.SELinuxOptions != nil { - { - size, err := m.SELinuxOptions.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *Scale) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Scale) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Scale) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ScaleSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ScaleSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ScaleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - -func (m *ScaleStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ScaleStatus) MarshalTo(dAtA []byte) (int, error) { +func (m *ScaleStatus) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } @@ -4834,48 +3851,6 @@ func (m *ScaleStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *SupplementalGroupsStrategyOptions) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SupplementalGroupsStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SupplementalGroupsStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -4887,40 +3862,6 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *AllowedCSIDriver) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *AllowedFlexVolume) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *AllowedHostPath) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PathPrefix) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - return n -} - func (m *DaemonSet) Size() (n int) { if m == nil { return 0 @@ -5180,23 +4121,6 @@ func (m *DeploymentStrategy) Size() (n int) { return n } -func (m *FSGroupStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func (m *HTTPIngressPath) Size() (n int) { if m == nil { return 0 @@ -5229,29 +4153,7 @@ func (m *HTTPIngressRuleValue) Size() (n int) { return n } -func (m *HostPortRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.Min)) - n += 1 + sovGenerated(uint64(m.Max)) - return n -} - -func (m *IDRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.Min)) - n += 1 + sovGenerated(uint64(m.Max)) - return n -} - -func (m *IPBlock) Size() (n int) { +func (m *IPBlock) Size() (n int) { if m == nil { return 0 } @@ -5317,6 +4219,56 @@ func (m *IngressList) Size() (n int) { return n } +func (m *IngressLoadBalancerIngress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.IP) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Hostname) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Ports) > 0 { + for _, e := range m.Ports { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressLoadBalancerStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ingress) > 0 { + for _, e := range m.Ingress { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressPortStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Port)) + l = len(m.Protocol) + n += 1 + l + sovGenerated(uint64(l)) + if m.Error != nil { + l = len(*m.Error) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *IngressRule) Size() (n int) { if m == nil { return 0 @@ -5559,138 +4511,6 @@ func (m *NetworkPolicyStatus) Size() (n int) { return n } -func (m *PodSecurityPolicy) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *PodSecurityPolicyList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *PodSecurityPolicySpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 2 - if len(m.DefaultAddCapabilities) > 0 { - for _, s := range m.DefaultAddCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.RequiredDropCapabilities) > 0 { - for _, s := range m.RequiredDropCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedCapabilities) > 0 { - for _, s := range m.AllowedCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Volumes) > 0 { - for _, s := range m.Volumes { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - if len(m.HostPorts) > 0 { - for _, e := range m.HostPorts { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - n += 2 - l = m.SELinux.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.RunAsUser.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.SupplementalGroups.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.FSGroup.Size() - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - if m.DefaultAllowPrivilegeEscalation != nil { - n += 2 - } - if m.AllowPrivilegeEscalation != nil { - n += 3 - } - if len(m.AllowedHostPaths) > 0 { - for _, e := range m.AllowedHostPaths { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedFlexVolumes) > 0 { - for _, e := range m.AllowedFlexVolumes { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedUnsafeSysctls) > 0 { - for _, s := range m.AllowedUnsafeSysctls { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.ForbiddenSysctls) > 0 { - for _, s := range m.ForbiddenSysctls { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedProcMountTypes) > 0 { - for _, s := range m.AllowedProcMountTypes { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if m.RunAsGroup != nil { - l = m.RunAsGroup.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - if len(m.AllowedCSIDrivers) > 0 { - for _, e := range m.AllowedCSIDrivers { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if m.RuntimeClass != nil { - l = m.RuntimeClass.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *ReplicaSet) Size() (n int) { if m == nil { return 0 @@ -5825,74 +4645,6 @@ func (m *RollingUpdateDeployment) Size() (n int) { return n } -func (m *RunAsGroupStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *RunAsUserStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *RuntimeClassStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.AllowedRuntimeClassNames) > 0 { - for _, s := range m.AllowedRuntimeClassNames { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.DefaultRuntimeClassName != nil { - l = len(*m.DefaultRuntimeClassName) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *SELinuxStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if m.SELinuxOptions != nil { - l = m.SELinuxOptions.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *Scale) Size() (n int) { if m == nil { return 0 @@ -5938,60 +4690,12 @@ func (m *ScaleStatus) Size() (n int) { return n } -func (m *SupplementalGroupsStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func sovGenerated(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (this *AllowedCSIDriver) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedCSIDriver{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} -func (this *AllowedFlexVolume) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedFlexVolume{`, - `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, - `}`, - }, "") - return s -} -func (this *AllowedHostPath) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedHostPath{`, - `PathPrefix:` + fmt.Sprintf("%v", this.PathPrefix) + `,`, - `ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`, - `}`, - }, "") - return s -} func (this *DaemonSet) String() string { if this == nil { return "nil" @@ -6200,22 +4904,6 @@ func (this *DeploymentStrategy) String() string { }, "") return s } -func (this *FSGroupStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&FSGroupStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} func (this *HTTPIngressPath) String() string { if this == nil { return "nil" @@ -6243,28 +4931,6 @@ func (this *HTTPIngressRuleValue) String() string { }, "") return s } -func (this *HostPortRange) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HostPortRange{`, - `Min:` + fmt.Sprintf("%v", this.Min) + `,`, - `Max:` + fmt.Sprintf("%v", this.Max) + `,`, - `}`, - }, "") - return s -} -func (this *IDRange) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&IDRange{`, - `Min:` + fmt.Sprintf("%v", this.Min) + `,`, - `Max:` + fmt.Sprintf("%v", this.Max) + `,`, - `}`, - }, "") - return s -} func (this *IPBlock) String() string { if this == nil { return "nil" @@ -6316,22 +4982,66 @@ func (this *IngressList) String() string { }, "") return s } -func (this *IngressRule) String() string { +func (this *IngressLoadBalancerIngress) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&IngressRule{`, - `Host:` + fmt.Sprintf("%v", this.Host) + `,`, - `IngressRuleValue:` + strings.Replace(strings.Replace(this.IngressRuleValue.String(), "IngressRuleValue", "IngressRuleValue", 1), `&`, ``, 1) + `,`, + repeatedStringForPorts := "[]IngressPortStatus{" + for _, f := range this.Ports { + repeatedStringForPorts += strings.Replace(strings.Replace(f.String(), "IngressPortStatus", "IngressPortStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForPorts += "}" + s := strings.Join([]string{`&IngressLoadBalancerIngress{`, + `IP:` + fmt.Sprintf("%v", this.IP) + `,`, + `Hostname:` + fmt.Sprintf("%v", this.Hostname) + `,`, + `Ports:` + repeatedStringForPorts + `,`, `}`, }, "") return s } -func (this *IngressRuleValue) String() string { +func (this *IngressLoadBalancerStatus) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&IngressRuleValue{`, + repeatedStringForIngress := "[]IngressLoadBalancerIngress{" + for _, f := range this.Ingress { + repeatedStringForIngress += strings.Replace(strings.Replace(f.String(), "IngressLoadBalancerIngress", "IngressLoadBalancerIngress", 1), `&`, ``, 1) + "," + } + repeatedStringForIngress += "}" + s := strings.Join([]string{`&IngressLoadBalancerStatus{`, + `Ingress:` + repeatedStringForIngress + `,`, + `}`, + }, "") + return s +} +func (this *IngressPortStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IngressPortStatus{`, + `Port:` + fmt.Sprintf("%v", this.Port) + `,`, + `Protocol:` + fmt.Sprintf("%v", this.Protocol) + `,`, + `Error:` + valueToStringGenerated(this.Error) + `,`, + `}`, + }, "") + return s +} +func (this *IngressRule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IngressRule{`, + `Host:` + fmt.Sprintf("%v", this.Host) + `,`, + `IngressRuleValue:` + strings.Replace(strings.Replace(this.IngressRuleValue.String(), "IngressRuleValue", "IngressRuleValue", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *IngressRuleValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IngressRuleValue{`, `HTTP:` + strings.Replace(this.HTTP.String(), "HTTPIngressRuleValue", "HTTPIngressRuleValue", 1) + `,`, `}`, }, "") @@ -6365,7 +5075,7 @@ func (this *IngressStatus) String() string { return "nil" } s := strings.Join([]string{`&IngressStatus{`, - `LoadBalancer:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LoadBalancer), "LoadBalancerStatus", "v11.LoadBalancerStatus", 1), `&`, ``, 1) + `,`, + `LoadBalancer:` + strings.Replace(strings.Replace(this.LoadBalancer.String(), "IngressLoadBalancerStatus", "IngressLoadBalancerStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -6513,86 +5223,6 @@ func (this *NetworkPolicyStatus) String() string { }, "") return s } -func (this *PodSecurityPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodSecurityPolicy{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodSecurityPolicySpec", "PodSecurityPolicySpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodSecurityPolicyList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]PodSecurityPolicy{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodSecurityPolicy", "PodSecurityPolicy", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&PodSecurityPolicyList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *PodSecurityPolicySpec) String() string { - if this == nil { - return "nil" - } - repeatedStringForHostPorts := "[]HostPortRange{" - for _, f := range this.HostPorts { - repeatedStringForHostPorts += strings.Replace(strings.Replace(f.String(), "HostPortRange", "HostPortRange", 1), `&`, ``, 1) + "," - } - repeatedStringForHostPorts += "}" - repeatedStringForAllowedHostPaths := "[]AllowedHostPath{" - for _, f := range this.AllowedHostPaths { - repeatedStringForAllowedHostPaths += strings.Replace(strings.Replace(f.String(), "AllowedHostPath", "AllowedHostPath", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedHostPaths += "}" - repeatedStringForAllowedFlexVolumes := "[]AllowedFlexVolume{" - for _, f := range this.AllowedFlexVolumes { - repeatedStringForAllowedFlexVolumes += strings.Replace(strings.Replace(f.String(), "AllowedFlexVolume", "AllowedFlexVolume", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedFlexVolumes += "}" - repeatedStringForAllowedCSIDrivers := "[]AllowedCSIDriver{" - for _, f := range this.AllowedCSIDrivers { - repeatedStringForAllowedCSIDrivers += strings.Replace(strings.Replace(f.String(), "AllowedCSIDriver", "AllowedCSIDriver", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedCSIDrivers += "}" - s := strings.Join([]string{`&PodSecurityPolicySpec{`, - `Privileged:` + fmt.Sprintf("%v", this.Privileged) + `,`, - `DefaultAddCapabilities:` + fmt.Sprintf("%v", this.DefaultAddCapabilities) + `,`, - `RequiredDropCapabilities:` + fmt.Sprintf("%v", this.RequiredDropCapabilities) + `,`, - `AllowedCapabilities:` + fmt.Sprintf("%v", this.AllowedCapabilities) + `,`, - `Volumes:` + fmt.Sprintf("%v", this.Volumes) + `,`, - `HostNetwork:` + fmt.Sprintf("%v", this.HostNetwork) + `,`, - `HostPorts:` + repeatedStringForHostPorts + `,`, - `HostPID:` + fmt.Sprintf("%v", this.HostPID) + `,`, - `HostIPC:` + fmt.Sprintf("%v", this.HostIPC) + `,`, - `SELinux:` + strings.Replace(strings.Replace(this.SELinux.String(), "SELinuxStrategyOptions", "SELinuxStrategyOptions", 1), `&`, ``, 1) + `,`, - `RunAsUser:` + strings.Replace(strings.Replace(this.RunAsUser.String(), "RunAsUserStrategyOptions", "RunAsUserStrategyOptions", 1), `&`, ``, 1) + `,`, - `SupplementalGroups:` + strings.Replace(strings.Replace(this.SupplementalGroups.String(), "SupplementalGroupsStrategyOptions", "SupplementalGroupsStrategyOptions", 1), `&`, ``, 1) + `,`, - `FSGroup:` + strings.Replace(strings.Replace(this.FSGroup.String(), "FSGroupStrategyOptions", "FSGroupStrategyOptions", 1), `&`, ``, 1) + `,`, - `ReadOnlyRootFilesystem:` + fmt.Sprintf("%v", this.ReadOnlyRootFilesystem) + `,`, - `DefaultAllowPrivilegeEscalation:` + valueToStringGenerated(this.DefaultAllowPrivilegeEscalation) + `,`, - `AllowPrivilegeEscalation:` + valueToStringGenerated(this.AllowPrivilegeEscalation) + `,`, - `AllowedHostPaths:` + repeatedStringForAllowedHostPaths + `,`, - `AllowedFlexVolumes:` + repeatedStringForAllowedFlexVolumes + `,`, - `AllowedUnsafeSysctls:` + fmt.Sprintf("%v", this.AllowedUnsafeSysctls) + `,`, - `ForbiddenSysctls:` + fmt.Sprintf("%v", this.ForbiddenSysctls) + `,`, - `AllowedProcMountTypes:` + fmt.Sprintf("%v", this.AllowedProcMountTypes) + `,`, - `RunAsGroup:` + strings.Replace(this.RunAsGroup.String(), "RunAsGroupStrategyOptions", "RunAsGroupStrategyOptions", 1) + `,`, - `AllowedCSIDrivers:` + repeatedStringForAllowedCSIDrivers + `,`, - `RuntimeClass:` + strings.Replace(this.RuntimeClass.String(), "RuntimeClassStrategyOptions", "RuntimeClassStrategyOptions", 1) + `,`, - `}`, - }, "") - return s -} func (this *ReplicaSet) String() string { if this == nil { return "nil" @@ -6668,2240 +5298,91 @@ func (this *ReplicaSetStatus) String() string { }, "") return s } -func (this *RollbackConfig) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RollbackConfig{`, - `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, - `}`, - }, "") - return s -} -func (this *RollingUpdateDaemonSet) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RollingUpdateDaemonSet{`, - `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, - `MaxSurge:` + strings.Replace(fmt.Sprintf("%v", this.MaxSurge), "IntOrString", "intstr.IntOrString", 1) + `,`, - `}`, - }, "") - return s -} -func (this *RollingUpdateDeployment) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RollingUpdateDeployment{`, - `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, - `MaxSurge:` + strings.Replace(fmt.Sprintf("%v", this.MaxSurge), "IntOrString", "intstr.IntOrString", 1) + `,`, - `}`, - }, "") - return s -} -func (this *RunAsGroupStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&RunAsGroupStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} -func (this *RunAsUserStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&RunAsUserStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} -func (this *RuntimeClassStrategyOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RuntimeClassStrategyOptions{`, - `AllowedRuntimeClassNames:` + fmt.Sprintf("%v", this.AllowedRuntimeClassNames) + `,`, - `DefaultRuntimeClassName:` + valueToStringGenerated(this.DefaultRuntimeClassName) + `,`, - `}`, - }, "") - return s -} -func (this *SELinuxStrategyOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SELinuxStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `SELinuxOptions:` + strings.Replace(fmt.Sprintf("%v", this.SELinuxOptions), "SELinuxOptions", "v11.SELinuxOptions", 1) + `,`, - `}`, - }, "") - return s -} -func (this *Scale) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Scale{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ScaleSpec", "ScaleSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ScaleStatus", "ScaleStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ScaleSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ScaleSpec{`, - `Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`, - `}`, - }, "") - return s -} -func (this *ScaleStatus) String() string { - if this == nil { - return "nil" - } - keysForSelector := make([]string, 0, len(this.Selector)) - for k := range this.Selector { - keysForSelector = append(keysForSelector, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForSelector) - mapStringForSelector := "map[string]string{" - for _, k := range keysForSelector { - mapStringForSelector += fmt.Sprintf("%v: %v,", k, this.Selector[k]) - } - mapStringForSelector += "}" - s := strings.Join([]string{`&ScaleStatus{`, - `Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`, - `Selector:` + mapStringForSelector + `,`, - `TargetSelector:` + fmt.Sprintf("%v", this.TargetSelector) + `,`, - `}`, - }, "") - return s -} -func (this *SupplementalGroupsStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&SupplementalGroupsStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *AllowedCSIDriver) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AllowedCSIDriver: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedCSIDriver: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AllowedFlexVolume) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AllowedFlexVolume: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedFlexVolume: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Driver = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AllowedHostPath) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AllowedHostPath: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedHostPath: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PathPrefix", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PathPrefix = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadOnly", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ReadOnly = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSetCondition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSetCondition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSetCondition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = DaemonSetConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSetList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSetList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSetList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, DaemonSet{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSetSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSetSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSetSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdateStrategy", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.UpdateStrategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) - } - m.MinReadySeconds = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MinReadySeconds |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TemplateGeneration", wireType) - } - m.TemplateGeneration = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TemplateGeneration |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.RevisionHistoryLimit = &v - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSetStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSetStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSetStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentNumberScheduled", wireType) - } - m.CurrentNumberScheduled = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CurrentNumberScheduled |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumberMisscheduled", wireType) - } - m.NumberMisscheduled = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumberMisscheduled |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredNumberScheduled", wireType) - } - m.DesiredNumberScheduled = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DesiredNumberScheduled |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumberReady", wireType) - } - m.NumberReady = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumberReady |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) - } - m.ObservedGeneration = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ObservedGeneration |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdatedNumberScheduled", wireType) - } - m.UpdatedNumberScheduled = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.UpdatedNumberScheduled |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumberAvailable", wireType) - } - m.NumberAvailable = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumberAvailable |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumberUnavailable", wireType) - } - m.NumberUnavailable = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NumberUnavailable |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CollisionCount", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.CollisionCount = &v - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Conditions = append(m.Conditions, DaemonSetCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DaemonSetUpdateStrategy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DaemonSetUpdateStrategy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DaemonSetUpdateStrategy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = DaemonSetUpdateStrategyType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RollingUpdate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.RollingUpdate == nil { - m.RollingUpdate = &RollingUpdateDaemonSet{} - } - if err := m.RollingUpdate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Deployment) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Deployment: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Deployment: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeploymentCondition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeploymentCondition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentCondition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = DeploymentConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastUpdateTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastUpdateTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeploymentList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeploymentList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, Deployment{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeploymentRollback) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeploymentRollback: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentRollback: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdatedAnnotations", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.UpdatedAnnotations == nil { - m.UpdatedAnnotations = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.UpdatedAnnotations[mapkey] = mapvalue - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RollbackTo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.RollbackTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } +func (this *RollbackConfig) String() string { + if this == nil { + return "nil" } - - if iNdEx > l { - return io.ErrUnexpectedEOF + s := strings.Join([]string{`&RollbackConfig{`, + `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, + `}`, + }, "") + return s +} +func (this *RollingUpdateDaemonSet) String() string { + if this == nil { + return "nil" } - return nil + s := strings.Join([]string{`&RollingUpdateDaemonSet{`, + `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, + `MaxSurge:` + strings.Replace(fmt.Sprintf("%v", this.MaxSurge), "IntOrString", "intstr.IntOrString", 1) + `,`, + `}`, + }, "") + return s } -func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { +func (this *RollingUpdateDeployment) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RollingUpdateDeployment{`, + `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, + `MaxSurge:` + strings.Replace(fmt.Sprintf("%v", this.MaxSurge), "IntOrString", "intstr.IntOrString", 1) + `,`, + `}`, + }, "") + return s +} +func (this *Scale) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Scale{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ScaleSpec", "ScaleSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ScaleStatus", "ScaleStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ScaleSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ScaleSpec{`, + `Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`, + `}`, + }, "") + return s +} +func (this *ScaleStatus) String() string { + if this == nil { + return "nil" + } + keysForSelector := make([]string, 0, len(this.Selector)) + for k := range this.Selector { + keysForSelector = append(keysForSelector, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForSelector) + mapStringForSelector := "map[string]string{" + for _, k := range keysForSelector { + mapStringForSelector += fmt.Sprintf("%v: %v,", k, this.Selector[k]) + } + mapStringForSelector += "}" + s := strings.Join([]string{`&ScaleStatus{`, + `Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`, + `Selector:` + mapStringForSelector + `,`, + `TargetSelector:` + fmt.Sprintf("%v", this.TargetSelector) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *DaemonSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8924,71 +5405,15 @@ func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeploymentSpec: wiretype end group for non-group") + return fmt.Errorf("proto: DaemonSet: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DaemonSet: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Replicas = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9015,13 +5440,13 @@ func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9048,110 +5473,15 @@ func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Strategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) - } - m.MinReadySeconds = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MinReadySeconds |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.RevisionHistoryLimit = &v - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Paused", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Paused = bool(v != 0) - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RollbackTo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.RollbackTo == nil { - m.RollbackTo = &RollbackConfig{} - } - if err := m.RollbackTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ProgressDeadlineSeconds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var v int32 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9161,12 +5491,25 @@ func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.ProgressDeadlineSeconds = &v + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9188,7 +5531,7 @@ func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { +func (m *DaemonSetCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9211,17 +5554,17 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeploymentStatus: wiretype end group for non-group") + return fmt.Errorf("proto: DaemonSetCondition: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DaemonSetCondition: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - m.ObservedGeneration = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9231,54 +5574,29 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ObservedGeneration |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) - } - m.Replicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Replicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UpdatedReplicas", wireType) + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - m.UpdatedReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.UpdatedReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + if postIndex > l { + return io.ErrUnexpectedEOF } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AvailableReplicas", wireType) + m.Type = DaemonSetConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - m.AvailableReplicas = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9288,33 +5606,27 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.AvailableReplicas |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UnavailableReplicas", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - m.UnavailableReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.UnavailableReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - case 6: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9341,103 +5653,13 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Conditions = append(m.Conditions, DeploymentCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType) - } - m.ReadyReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ReadyReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CollisionCount", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.CollisionCount = &v - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeploymentStrategy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeploymentStrategy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9465,13 +5687,13 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = DeploymentStrategyType(dAtA[iNdEx:postIndex]) + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RollingUpdate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9481,27 +5703,23 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.RollingUpdate == nil { - m.RollingUpdate = &RollingUpdateDeployment{} - } - if err := m.RollingUpdate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -9524,7 +5742,7 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { } return nil } -func (m *FSGroupStrategyOptions) Unmarshal(dAtA []byte) error { +func (m *DaemonSetList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9547,17 +5765,17 @@ func (m *FSGroupStrategyOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: FSGroupStrategyOptions: wiretype end group for non-group") + return fmt.Errorf("proto: DaemonSetList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: FSGroupStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DaemonSetList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9567,27 +5785,28 @@ func (m *FSGroupStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Rule = FSGroupStrategyType(dAtA[iNdEx:postIndex]) + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9614,8 +5833,8 @@ func (m *FSGroupStrategyOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, DaemonSet{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9640,7 +5859,7 @@ func (m *FSGroupStrategyOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { +func (m *DaemonSetSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9663,17 +5882,17 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HTTPIngressPath: wiretype end group for non-group") + return fmt.Errorf("proto: DaemonSetSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HTTPIngressPath: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DaemonSetSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9683,27 +5902,31 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + if m.Selector == nil { + m.Selector = &v1.LabelSelector{} + } + if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Backend", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9730,15 +5953,15 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Backend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PathType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UpdateStrategy", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9748,25 +5971,83 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := PathType(dAtA[iNdEx:postIndex]) - m.PathType = &s + if err := m.UpdateStrategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) + } + m.MinReadySeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinReadySeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TemplateGeneration", wireType) + } + m.TemplateGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TemplateGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RevisionHistoryLimit = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9788,7 +6069,7 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { } return nil } -func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { +func (m *DaemonSetStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9798,28 +6079,200 @@ func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { if shift >= 64 { return ErrIntOverflowGenerated } - if iNdEx >= l { - return io.ErrUnexpectedEOF + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DaemonSetStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DaemonSetStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentNumberScheduled", wireType) + } + m.CurrentNumberScheduled = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentNumberScheduled |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberMisscheduled", wireType) + } + m.NumberMisscheduled = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberMisscheduled |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredNumberScheduled", wireType) + } + m.DesiredNumberScheduled = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DesiredNumberScheduled |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberReady", wireType) + } + m.NumberReady = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberReady |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedNumberScheduled", wireType) + } + m.UpdatedNumberScheduled = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpdatedNumberScheduled |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberAvailable", wireType) + } + m.NumberAvailable = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberAvailable |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberUnavailable", wireType) } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + m.NumberUnavailable = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberUnavailable |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HTTPIngressRuleValue: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HTTPIngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CollisionCount", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.CollisionCount = &v + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9846,8 +6299,8 @@ func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Paths = append(m.Paths, HTTPIngressPath{}) - if err := m.Paths[len(m.Paths)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Conditions = append(m.Conditions, DaemonSetCondition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9872,7 +6325,7 @@ func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *HostPortRange) Unmarshal(dAtA []byte) error { +func (m *DaemonSetUpdateStrategy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9895,17 +6348,17 @@ func (m *HostPortRange) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HostPortRange: wiretype end group for non-group") + return fmt.Errorf("proto: DaemonSetUpdateStrategy: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HostPortRange: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DaemonSetUpdateStrategy: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Min", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - m.Min = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9915,16 +6368,29 @@ func (m *HostPortRange) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Min |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = DaemonSetUpdateStrategyType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollingUpdate", wireType) } - m.Max = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -9934,11 +6400,28 @@ func (m *HostPortRange) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Max |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RollingUpdate == nil { + m.RollingUpdate = &RollingUpdateDaemonSet{} + } + if err := m.RollingUpdate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9960,7 +6443,7 @@ func (m *HostPortRange) Unmarshal(dAtA []byte) error { } return nil } -func (m *IDRange) Unmarshal(dAtA []byte) error { +func (m *Deployment) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9983,36 +6466,17 @@ func (m *IDRange) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IDRange: wiretype end group for non-group") + return fmt.Errorf("proto: Deployment: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IDRange: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Deployment: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Min", wireType) - } - m.Min = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Min |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } - m.Max = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10022,66 +6486,30 @@ func (m *IDRange) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Max |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *IPBlock) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - if iNdEx >= l { + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: IPBlock: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IPBlock: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CIDR", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10091,29 +6519,30 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.CIDR = string(dAtA[iNdEx:postIndex]) + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Except", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10123,23 +6552,24 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Except = append(m.Except, string(dAtA[iNdEx:postIndex])) + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -10162,7 +6592,7 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } return nil } -func (m *Ingress) Unmarshal(dAtA []byte) error { +func (m *DeploymentCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10185,17 +6615,17 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Ingress: wiretype end group for non-group") + return fmt.Errorf("proto: DeploymentCondition: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Ingress: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeploymentCondition: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10205,30 +6635,29 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Type = DeploymentConditionType(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10238,30 +6667,29 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10271,78 +6699,27 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *IngressBackend) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: IngressBackend: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IngressBackend: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServiceName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10370,11 +6747,11 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ServiceName = string(dAtA[iNdEx:postIndex]) + m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServicePort", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastUpdateTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10401,13 +6778,13 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ServicePort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LastUpdateTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10434,10 +6811,7 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Resource == nil { - m.Resource = &v11.TypedLocalObjectReference{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10462,7 +6836,7 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressList) Unmarshal(dAtA []byte) error { +func (m *DeploymentList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10485,10 +6859,10 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressList: wiretype end group for non-group") + return fmt.Errorf("proto: DeploymentList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeploymentList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10553,7 +6927,7 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, Ingress{}) + m.Items = append(m.Items, Deployment{}) if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -10579,7 +6953,7 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressRule) Unmarshal(dAtA []byte) error { +func (m *DeploymentRollback) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10602,15 +6976,15 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressRule: wiretype end group for non-group") + return fmt.Errorf("proto: DeploymentRollback: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeploymentRollback: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Host", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10638,11 +7012,11 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Host = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IngressRuleValue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedAnnotations", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10669,63 +7043,107 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.IngressRuleValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF + if m.UpdatedAnnotations == nil { + m.UpdatedAnnotations = make(map[string]string) } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: IngressRuleValue: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.UpdatedAnnotations[mapkey] = mapvalue + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HTTP", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RollbackTo", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10752,10 +7170,7 @@ func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.HTTP == nil { - m.HTTP = &HTTPIngressRuleValue{} - } - if err := m.HTTP.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.RollbackTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10780,7 +7195,7 @@ func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressSpec) Unmarshal(dAtA []byte) error { +func (m *DeploymentSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10803,15 +7218,35 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressSpec: wiretype end group for non-group") + return fmt.Errorf("proto: DeploymentSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeploymentSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Replicas = &v + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Backend", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10838,16 +7273,16 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Backend == nil { - m.Backend = &IngressBackend{} + if m.Selector == nil { + m.Selector = &v1.LabelSelector{} } - if err := m.Backend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLS", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10874,14 +7309,13 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TLS = append(m.TLS, IngressTLS{}) - if err := m.TLS[len(m.TLS)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10908,16 +7342,74 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Rules = append(m.Rules, IngressRule{}) - if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Strategy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) + } + m.MinReadySeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinReadySeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHistoryLimit", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RevisionHistoryLimit = &v + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Paused", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Paused = bool(v != 0) + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IngressClassName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RollbackTo", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -10927,25 +7419,48 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.IngressClassName = &s + if m.RollbackTo == nil { + m.RollbackTo = &RollbackConfig{} + } + if err := m.RollbackTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProgressDeadlineSeconds", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ProgressDeadlineSeconds = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -10967,7 +7482,7 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressStatus) Unmarshal(dAtA []byte) error { +func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10986,19 +7501,114 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { if b < 0x80 { break } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: IngressStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IngressStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeploymentStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeploymentStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + } + m.Replicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Replicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedReplicas", wireType) + } + m.UpdatedReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpdatedReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AvailableReplicas", wireType) + } + m.AvailableReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AvailableReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UnavailableReplicas", wireType) + } + m.UnavailableReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UnavailableReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LoadBalancer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11025,10 +7635,50 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LoadBalancer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Conditions = append(m.Conditions, DeploymentCondition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType) + } + m.ReadyReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ReadyReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CollisionCount", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.CollisionCount = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -11050,7 +7700,7 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressTLS) Unmarshal(dAtA []byte) error { +func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11073,15 +7723,15 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressTLS: wiretype end group for non-group") + return fmt.Errorf("proto: DeploymentStrategy: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressTLS: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeploymentStrategy: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11109,13 +7759,13 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hosts = append(m.Hosts, string(dAtA[iNdEx:postIndex])) + m.Type = DeploymentStrategyType(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RollingUpdate", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11125,23 +7775,27 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.SecretName = string(dAtA[iNdEx:postIndex]) + if m.RollingUpdate == nil { + m.RollingUpdate = &RollingUpdateDeployment{} + } + if err := m.RollingUpdate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -11164,7 +7818,7 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { +func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11187,17 +7841,17 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicy: wiretype end group for non-group") + return fmt.Errorf("proto: HTTPIngressPath: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HTTPIngressPath: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11207,28 +7861,27 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Backend", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11255,15 +7908,15 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Backend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PathType", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11273,24 +7926,24 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := PathType(dAtA[iNdEx:postIndex]) + m.PathType = &s iNdEx = postIndex default: iNdEx = preIndex @@ -11313,7 +7966,7 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { +func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11336,49 +7989,15 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyEgressRule: wiretype end group for non-group") + return fmt.Errorf("proto: HTTPIngressRuleValue: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyEgressRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HTTPIngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ports = append(m.Ports, NetworkPolicyPort{}) - if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11405,8 +8024,8 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.To = append(m.To, NetworkPolicyPeer{}) - if err := m.To[len(m.To)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Paths = append(m.Paths, HTTPIngressPath{}) + if err := m.Paths[len(m.Paths)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11431,7 +8050,7 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { +func (m *IPBlock) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11454,17 +8073,17 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyIngressRule: wiretype end group for non-group") + return fmt.Errorf("proto: IPBlock: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyIngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IPBlock: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CIDR", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11474,31 +8093,29 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ports = append(m.Ports, NetworkPolicyPort{}) - if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.CIDR = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Except", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11508,25 +8125,23 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.From = append(m.From, NetworkPolicyPeer{}) - if err := m.From[len(m.From)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Except = append(m.Except, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -11549,7 +8164,7 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { +func (m *Ingress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11572,15 +8187,15 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyList: wiretype end group for non-group") + return fmt.Errorf("proto: Ingress: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Ingress: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11607,13 +8222,46 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11640,8 +8288,7 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, NetworkPolicy{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11666,7 +8313,7 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { +func (m *IngressBackend) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11689,17 +8336,17 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyPeer: wiretype end group for non-group") + return fmt.Errorf("proto: IngressBackend: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyPeer: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressBackend: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServiceName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11709,31 +8356,27 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.PodSelector == nil { - m.PodSelector = &v1.LabelSelector{} - } - if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ServiceName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ServicePort", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11760,16 +8403,13 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NamespaceSelector == nil { - m.NamespaceSelector = &v1.LabelSelector{} - } - if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ServicePort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IPBlock", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11796,10 +8436,10 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.IPBlock == nil { - m.IPBlock = &IPBlock{} + if m.Resource == nil { + m.Resource = &v11.TypedLocalObjectReference{} } - if err := m.IPBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11824,7 +8464,7 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { +func (m *IngressList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11847,17 +8487,17 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyPort: wiretype end group for non-group") + return fmt.Errorf("proto: IngressList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyPort: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -11867,28 +8507,28 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) - m.Protocol = &s + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11915,33 +8555,11 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Port == nil { - m.Port = &intstr.IntOrString{} - } - if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, Ingress{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EndPort", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.EndPort = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -11963,7 +8581,7 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { +func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11986,17 +8604,17 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicySpec: wiretype end group for non-group") + return fmt.Errorf("proto: IngressLoadBalancerIngress: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressLoadBalancerIngress: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IP", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12006,30 +8624,29 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.IP = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12039,29 +8656,27 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ingress = append(m.Ingress, NetworkPolicyIngressRule{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Hostname = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Egress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12088,16 +8703,66 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Egress = append(m.Egress, NetworkPolicyEgressRule{}) - if err := m.Egress[len(m.Egress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Ports = append(m.Ports, IngressPortStatus{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PolicyTypes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12107,23 +8772,25 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.PolicyTypes = append(m.PolicyTypes, PolicyType(dAtA[iNdEx:postIndex])) + m.Ingress = append(m.Ingress, IngressLoadBalancerIngress{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -12146,7 +8813,7 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { +func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -12169,17 +8836,36 @@ func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyStatus: wiretype end group for non-group") + return fmt.Errorf("proto: IngressPortStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressPortStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + m.Port = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Port |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12189,25 +8875,56 @@ func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocol = k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Conditions = append(m.Conditions, v1.Condition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.Error = &s iNdEx = postIndex default: iNdEx = preIndex @@ -12230,7 +8947,7 @@ func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSecurityPolicy) Unmarshal(dAtA []byte) error { +func (m *IngressRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -12253,17 +8970,17 @@ func (m *PodSecurityPolicy) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSecurityPolicy: wiretype end group for non-group") + return fmt.Errorf("proto: IngressRule: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressRule: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Host", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12273,28 +8990,27 @@ func (m *PodSecurityPolicy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Host = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IngressRuleValue", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12321,7 +9037,7 @@ func (m *PodSecurityPolicy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.IngressRuleValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12346,7 +9062,7 @@ func (m *PodSecurityPolicy) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSecurityPolicyList) Unmarshal(dAtA []byte) error { +func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -12369,15 +9085,15 @@ func (m *PodSecurityPolicyList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSecurityPolicyList: wiretype end group for non-group") + return fmt.Errorf("proto: IngressRuleValue: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field HTTP", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12404,41 +9120,10 @@ func (m *PodSecurityPolicyList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF + if m.HTTP == nil { + m.HTTP = &HTTPIngressRuleValue{} } - m.Items = append(m.Items, PodSecurityPolicy{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.HTTP.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12463,7 +9148,7 @@ func (m *PodSecurityPolicyList) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { +func (m *IngressSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -12486,37 +9171,17 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSecurityPolicySpec: wiretype end group for non-group") + return fmt.Errorf("proto: IngressSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Privileged", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Privileged = bool(v != 0) - case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultAddCapabilities", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Backend", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12526,29 +9191,33 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.DefaultAddCapabilities = append(m.DefaultAddCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) + if m.Backend == nil { + m.Backend = &IngressBackend{} + } + if err := m.Backend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RequiredDropCapabilities", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TLS", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12558,29 +9227,31 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.RequiredDropCapabilities = append(m.RequiredDropCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) + m.TLS = append(m.TLS, IngressTLS{}) + if err := m.TLS[len(m.TLS)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedCapabilities", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12590,27 +9261,29 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedCapabilities = append(m.AllowedCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) + m.Rules = append(m.Rules, IngressRule{}) + if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Volumes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IngressClassName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12638,31 +9311,62 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Volumes = append(m.Volumes, FSType(dAtA[iNdEx:postIndex])) + s := string(dAtA[iNdEx:postIndex]) + m.IngressClassName = &s iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostNetwork", wireType) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated } - m.HostNetwork = bool(v != 0) - case 7: + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPorts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LoadBalancer", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12689,16 +9393,65 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.HostPorts = append(m.HostPorts, HostPortRange{}) - if err := m.HostPorts[len(m.HostPorts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LoadBalancer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPID", wireType) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressTLS) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressTLS: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressTLS: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12708,37 +9461,29 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.HostPID = bool(v != 0) - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostIPC", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - m.HostIPC = bool(v != 0) - case 10: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hosts = append(m.Hosts, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SELinux", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -12748,28 +9493,77 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SELinux.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.SecretName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { return err } - iNdEx = postIndex - case 11: + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RunAsUser", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12796,13 +9590,13 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.RunAsUser.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 12: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SupplementalGroups", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12829,13 +9623,13 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SupplementalGroups.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 13: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FSGroup", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12862,75 +9656,63 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.FSGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 14: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadOnlyRootFilesystem", wireType) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated } - m.ReadOnlyRootFilesystem = bool(v != 0) - case 15: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultAllowPrivilegeEscalation", wireType) + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated } - b := bool(v != 0) - m.DefaultAllowPrivilegeEscalation = &b - case 16: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowPrivilegeEscalation", wireType) + if iNdEx >= l { + return io.ErrUnexpectedEOF } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - b := bool(v != 0) - m.AllowPrivilegeEscalation = &b - case 17: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyEgressRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyEgressRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedHostPaths", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12957,14 +9739,14 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedHostPaths = append(m.AllowedHostPaths, AllowedHostPath{}) - if err := m.AllowedHostPaths[len(m.AllowedHostPaths)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Ports = append(m.Ports, NetworkPolicyPort{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 18: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedFlexVolumes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -12991,80 +9773,66 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedFlexVolumes = append(m.AllowedFlexVolumes, AllowedFlexVolume{}) - if err := m.AllowedFlexVolumes[len(m.AllowedFlexVolumes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.To = append(m.To, NetworkPolicyPeer{}) + if err := m.To[len(m.To)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 19: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedUnsafeSysctls", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AllowedUnsafeSysctls = append(m.AllowedUnsafeSysctls, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 20: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ForbiddenSysctls", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.ForbiddenSysctls = append(m.ForbiddenSysctls, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 21: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedProcMountTypes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13074,27 +9842,29 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedProcMountTypes = append(m.AllowedProcMountTypes, k8s_io_api_core_v1.ProcMountType(dAtA[iNdEx:postIndex])) + m.Ports = append(m.Ports, NetworkPolicyPort{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 22: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RunAsGroup", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13121,16 +9891,64 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RunAsGroup == nil { - m.RunAsGroup = &RunAsGroupStrategyOptions{} - } - if err := m.RunAsGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.From = append(m.From, NetworkPolicyPeer{}) + if err := m.From[len(m.From)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 23: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedCSIDrivers", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13157,14 +9975,13 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedCSIDrivers = append(m.AllowedCSIDrivers, AllowedCSIDriver{}) - if err := m.AllowedCSIDrivers[len(m.AllowedCSIDrivers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 24: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RuntimeClass", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13191,10 +10008,8 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RuntimeClass == nil { - m.RuntimeClass = &RuntimeClassStrategyOptions{} - } - if err := m.RuntimeClass.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, NetworkPolicy{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -13219,7 +10034,7 @@ func (m *PodSecurityPolicySpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *ReplicaSet) Unmarshal(dAtA []byte) error { +func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13242,15 +10057,15 @@ func (m *ReplicaSet) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ReplicaSet: wiretype end group for non-group") + return fmt.Errorf("proto: NetworkPolicyPeer: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ReplicaSet: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: NetworkPolicyPeer: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13277,13 +10092,16 @@ func (m *ReplicaSet) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.PodSelector == nil { + m.PodSelector = &v1.LabelSelector{} + } + if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13310,13 +10128,16 @@ func (m *ReplicaSet) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.NamespaceSelector == nil { + m.NamespaceSelector = &v1.LabelSelector{} + } + if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IPBlock", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13343,7 +10164,10 @@ func (m *ReplicaSet) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.IPBlock == nil { + m.IPBlock = &IPBlock{} + } + if err := m.IPBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -13368,7 +10192,7 @@ func (m *ReplicaSet) Unmarshal(dAtA []byte) error { } return nil } -func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { +func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13391,15 +10215,15 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ReplicaSetCondition: wiretype end group for non-group") + return fmt.Errorf("proto: NetworkPolicyPort: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ReplicaSetCondition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: NetworkPolicyPort: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -13427,13 +10251,120 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = ReplicaSetConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + s := k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + m.Protocol = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Port == nil { + m.Port = &intstr.IntOrString{} + } + if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndPort", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EndPort = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicySpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13443,27 +10374,28 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) + if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13490,15 +10422,16 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Ingress = append(m.Ingress, NetworkPolicyIngressRule{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Egress", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13508,27 +10441,29 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Reason = string(dAtA[iNdEx:postIndex]) + m.Egress = append(m.Egress, NetworkPolicyEgressRule{}) + if err := m.Egress[len(m.Egress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PolicyTypes", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -13556,7 +10491,7 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Message = string(dAtA[iNdEx:postIndex]) + m.PolicyTypes = append(m.PolicyTypes, PolicyType(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -13579,7 +10514,7 @@ func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { } return nil } -func (m *ReplicaSetList) Unmarshal(dAtA []byte) error { +func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13602,48 +10537,15 @@ func (m *ReplicaSetList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ReplicaSetList: wiretype end group for non-group") + return fmt.Errorf("proto: NetworkPolicyStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ReplicaSetList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: NetworkPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13670,8 +10572,8 @@ func (m *ReplicaSetList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, ReplicaSet{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -13696,7 +10598,7 @@ func (m *ReplicaSetList) Unmarshal(dAtA []byte) error { } return nil } -func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { +func (m *ReplicaSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13719,17 +10621,17 @@ func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ReplicaSetSpec: wiretype end group for non-group") + return fmt.Errorf("proto: ReplicaSet: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ReplicaSetSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ReplicaSet: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } - var v int32 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13739,15 +10641,28 @@ func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.Replicas = &v + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13774,16 +10689,13 @@ func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -13810,29 +10722,10 @@ func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) - } - m.MinReadySeconds = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MinReadySeconds |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -13854,7 +10747,7 @@ func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { +func (m *ReplicaSetCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -13877,17 +10770,17 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ReplicaSetStatus: wiretype end group for non-group") + return fmt.Errorf("proto: ReplicaSetCondition: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ReplicaSetStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ReplicaSetCondition: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - m.Replicas = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13897,35 +10790,29 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Replicas |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FullyLabeledReplicas", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - m.FullyLabeledReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.FullyLabeledReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + if postIndex > l { + return io.ErrUnexpectedEOF } - m.ObservedGeneration = 0 + m.Type = ReplicaSetConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13935,35 +10822,29 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ObservedGeneration |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - m.ReadyReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ReadyReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AvailableReplicas", wireType) + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) } - m.AvailableReplicas = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13973,16 +10854,30 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.AvailableReplicas |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 6: + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -13992,81 +10887,29 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Conditions = append(m.Conditions, ReplicaSetCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RollbackConfig) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RollbackConfig: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RollbackConfig: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } - m.Revision = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14076,11 +10919,24 @@ func (m *RollbackConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Revision |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -14102,7 +10958,7 @@ func (m *RollbackConfig) Unmarshal(dAtA []byte) error { } return nil } -func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { +func (m *ReplicaSetList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14125,15 +10981,15 @@ func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RollingUpdateDaemonSet: wiretype end group for non-group") + return fmt.Errorf("proto: ReplicaSetList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RollingUpdateDaemonSet: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ReplicaSetList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxUnavailable", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14160,16 +11016,13 @@ func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.MaxUnavailable == nil { - m.MaxUnavailable = &intstr.IntOrString{} - } - if err := m.MaxUnavailable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxSurge", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14196,10 +11049,8 @@ func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.MaxSurge == nil { - m.MaxSurge = &intstr.IntOrString{} - } - if err := m.MaxSurge.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, ReplicaSet{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14224,7 +11075,7 @@ func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { } return nil } -func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { +func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14247,15 +11098,35 @@ func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RollingUpdateDeployment: wiretype end group for non-group") + return fmt.Errorf("proto: ReplicaSetSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RollingUpdateDeployment: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ReplicaSetSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Replicas = &v + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxUnavailable", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14282,16 +11153,16 @@ func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.MaxUnavailable == nil { - m.MaxUnavailable = &intstr.IntOrString{} + if m.Selector == nil { + m.Selector = &v1.LabelSelector{} } - if err := m.MaxUnavailable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxSurge", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14318,13 +11189,29 @@ func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.MaxSurge == nil { - m.MaxSurge = &intstr.IntOrString{} - } - if err := m.MaxSurge.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Template.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinReadySeconds", wireType) + } + m.MinReadySeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinReadySeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -14346,7 +11233,7 @@ func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { } return nil } -func (m *RunAsGroupStrategyOptions) Unmarshal(dAtA []byte) error { +func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14369,17 +11256,74 @@ func (m *RunAsGroupStrategyOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RunAsGroupStrategyOptions: wiretype end group for non-group") + return fmt.Errorf("proto: ReplicaSetStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RunAsGroupStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ReplicaSetStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + } + m.Replicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Replicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FullyLabeledReplicas", wireType) + } + m.FullyLabeledReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FullyLabeledReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReadyReplicas", wireType) } - var stringLen uint64 + m.ReadyReplicas = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14389,27 +11333,33 @@ func (m *RunAsGroupStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ReadyReplicas |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AvailableReplicas", wireType) } - if postIndex > l { - return io.ErrUnexpectedEOF + m.AvailableReplicas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AvailableReplicas |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - m.Rule = RunAsGroupStrategy(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14436,8 +11386,8 @@ func (m *RunAsGroupStrategyOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Conditions = append(m.Conditions, ReplicaSetCondition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14462,7 +11412,7 @@ func (m *RunAsGroupStrategyOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *RunAsUserStrategyOptions) Unmarshal(dAtA []byte) error { +func (m *RollbackConfig) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14485,49 +11435,17 @@ func (m *RunAsUserStrategyOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RunAsUserStrategyOptions: wiretype end group for non-group") + return fmt.Errorf("proto: RollbackConfig: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RunAsUserStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RollbackConfig: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Rule = RunAsUserStrategy(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) } - var msglen int + m.Revision = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14537,26 +11455,11 @@ func (m *RunAsUserStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Revision |= int64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -14578,7 +11481,7 @@ func (m *RunAsUserStrategyOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *RuntimeClassStrategyOptions) Unmarshal(dAtA []byte) error { +func (m *RollingUpdateDaemonSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14601,17 +11504,17 @@ func (m *RuntimeClassStrategyOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RuntimeClassStrategyOptions: wiretype end group for non-group") + return fmt.Errorf("proto: RollingUpdateDaemonSet: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RuntimeClassStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RollingUpdateDaemonSet: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedRuntimeClassNames", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxUnavailable", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14621,29 +11524,33 @@ func (m *RuntimeClassStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.AllowedRuntimeClassNames = append(m.AllowedRuntimeClassNames, string(dAtA[iNdEx:postIndex])) + if m.MaxUnavailable == nil { + m.MaxUnavailable = &intstr.IntOrString{} + } + if err := m.MaxUnavailable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultRuntimeClassName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxSurge", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14653,24 +11560,27 @@ func (m *RuntimeClassStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.DefaultRuntimeClassName = &s + if m.MaxSurge == nil { + m.MaxSurge = &intstr.IntOrString{} + } + if err := m.MaxSurge.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -14693,7 +11603,7 @@ func (m *RuntimeClassStrategyOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *SELinuxStrategyOptions) Unmarshal(dAtA []byte) error { +func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -14716,17 +11626,17 @@ func (m *SELinuxStrategyOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SELinuxStrategyOptions: wiretype end group for non-group") + return fmt.Errorf("proto: RollingUpdateDeployment: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SELinuxStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RollingUpdateDeployment: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxUnavailable", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -14736,27 +11646,31 @@ func (m *SELinuxStrategyOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Rule = SELinuxStrategy(dAtA[iNdEx:postIndex]) + if m.MaxUnavailable == nil { + m.MaxUnavailable = &intstr.IntOrString{} + } + if err := m.MaxUnavailable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SELinuxOptions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxSurge", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -14783,10 +11697,10 @@ func (m *SELinuxStrategyOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.SELinuxOptions == nil { - m.SELinuxOptions = &v11.SELinuxOptions{} + if m.MaxSurge == nil { + m.MaxSurge = &intstr.IntOrString{} } - if err := m.SELinuxOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.MaxSurge.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -15257,122 +12171,6 @@ func (m *ScaleStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *SupplementalGroupsStrategyOptions) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SupplementalGroupsStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SupplementalGroupsStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Rule = SupplementalGroupsStrategyType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.proto b/vendor/k8s.io/api/extensions/v1beta1/generated.proto index eaa63b59fa4..3ab6a093b55 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.proto +++ b/vendor/k8s.io/api/extensions/v1beta1/generated.proto @@ -30,37 +30,6 @@ import "k8s.io/apimachinery/pkg/util/intstr/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/extensions/v1beta1"; -// AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used. -message AllowedCSIDriver { - // Name is the registered name of the CSI driver - optional string name = 1; -} - -// AllowedFlexVolume represents a single Flexvolume that is allowed to be used. -// Deprecated: use AllowedFlexVolume from policy API Group instead. -message AllowedFlexVolume { - // driver is the name of the Flexvolume driver. - optional string driver = 1; -} - -// AllowedHostPath defines the host volume conditions that will be enabled by a policy -// for pods to use. It requires the path prefix to be defined. -// Deprecated: use AllowedHostPath from policy API Group instead. -message AllowedHostPath { - // pathPrefix is the path prefix that the host volume must match. - // It does not support `*`. - // Trailing slashes are trimmed when validating the path prefix with a host path. - // - // Examples: - // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` - // `/foo` would not allow `/food` or `/etc/foo` - optional string pathPrefix = 1; - - // when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly. - // +optional - optional bool readOnly = 2; -} - // DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for // more information. // DaemonSet represents the configuration of a daemon set. @@ -398,19 +367,6 @@ message DeploymentStrategy { optional RollingUpdateDeployment rollingUpdate = 2; } -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use FSGroupStrategyOptions from policy API Group instead. -message FSGroupStrategyOptions { - // rule is the strategy that will dictate what FSGroup is used in the SecurityContext. - // +optional - optional string rule = 1; - - // ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { @@ -453,38 +409,17 @@ message HTTPIngressRuleValue { repeated HTTPIngressPath paths = 1; } -// HostPortRange defines a range of host ports that will be enabled by a policy -// for pods to use. It requires both the start and end to be defined. -// Deprecated: use HostPortRange from policy API Group instead. -message HostPortRange { - // min is the start of the range, inclusive. - optional int32 min = 1; - - // max is the end of the range, inclusive. - optional int32 max = 2; -} - -// IDRange provides a min/max of an allowed range of IDs. -// Deprecated: use IDRange from policy API Group instead. -message IDRange { - // min is the start of the range, inclusive. - optional int64 min = 1; - - // max is the end of the range, inclusive. - optional int64 max = 2; -} - // DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. -// IPBlock describes a particular CIDR (Ex. "192.168.1.1/24","2001:db9::/64") that is allowed +// IPBlock describes a particular CIDR (Ex. "192.168.1.0/24","2001:db8::/64") that is allowed // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. message IPBlock { // CIDR is a string representing the IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" optional string cidr = 1; // Except is a slice of CIDRs that should not be included within an IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" // Except values will be rejected if they are outside the CIDR range // +optional repeated string except = 2; @@ -540,6 +475,53 @@ message IngressList { repeated Ingress items = 2; } +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +message IngressLoadBalancerIngress { + // IP is set for load-balancer ingress points that are IP based. + // +optional + optional string ip = 1; + + // Hostname is set for load-balancer ingress points that are DNS based. + // +optional + optional string hostname = 2; + + // Ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic + // +optional + repeated IngressPortStatus ports = 4; +} + +// LoadBalancerStatus represents the status of a load-balancer. +message IngressLoadBalancerStatus { + // Ingress is a list containing ingress points for the load-balancer. + // +optional + repeated IngressLoadBalancerIngress ingress = 1; +} + +// IngressPortStatus represents the error condition of a service port +message IngressPortStatus { + // Port is the port number of the ingress port. + optional int32 port = 1; + + // Protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + optional string protocol = 2; + + // Error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + optional string error = 3; +} + // IngressRule represents the rules mapping the paths under a specified host to // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. @@ -632,7 +614,7 @@ message IngressSpec { message IngressStatus { // LoadBalancer contains the current status of the load-balancer. // +optional - optional k8s.io.api.core.v1.LoadBalancerStatus loadBalancer = 1; + optional IngressLoadBalancerStatus loadBalancer = 1; } // IngressTLS describes the transport layer security associated with an Ingress. @@ -769,8 +751,6 @@ message NetworkPolicyPort { // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional optional int32 endPort = 3; } @@ -830,164 +810,6 @@ message NetworkPolicyStatus { repeated k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1; } -// PodSecurityPolicy governs the ability to make requests that affect the Security Context -// that will be applied to a pod and container. -// Deprecated: use PodSecurityPolicy from policy API Group instead. -message PodSecurityPolicy { - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // spec defines the policy enforced. - // +optional - optional PodSecurityPolicySpec spec = 2; -} - -// PodSecurityPolicyList is a list of PodSecurityPolicy objects. -// Deprecated: use PodSecurityPolicyList from policy API Group instead. -message PodSecurityPolicyList { - // Standard list metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // items is a list of schema objects. - repeated PodSecurityPolicy items = 2; -} - -// PodSecurityPolicySpec defines the policy enforced. -// Deprecated: use PodSecurityPolicySpec from policy API Group instead. -message PodSecurityPolicySpec { - // privileged determines if a pod can request to be run as privileged. - // +optional - optional bool privileged = 1; - - // defaultAddCapabilities is the default set of capabilities that will be added to the container - // unless the pod spec specifically drops the capability. You may not list a capability in both - // defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly - // allowed, and need not be included in the allowedCapabilities list. - // +optional - repeated string defaultAddCapabilities = 2; - - // requiredDropCapabilities are the capabilities that will be dropped from the container. These - // are required to be dropped and cannot be added. - // +optional - repeated string requiredDropCapabilities = 3; - - // allowedCapabilities is a list of capabilities that can be requested to add to the container. - // Capabilities in this field may be added at the pod author's discretion. - // You must not list a capability in both allowedCapabilities and requiredDropCapabilities. - // +optional - repeated string allowedCapabilities = 4; - - // volumes is an allowlist of volume plugins. Empty indicates that - // no volumes may be used. To allow all volumes you may use '*'. - // +optional - repeated string volumes = 5; - - // hostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - // +optional - optional bool hostNetwork = 6; - - // hostPorts determines which host port ranges are allowed to be exposed. - // +optional - repeated HostPortRange hostPorts = 7; - - // hostPID determines if the policy allows the use of HostPID in the pod spec. - // +optional - optional bool hostPID = 8; - - // hostIPC determines if the policy allows the use of HostIPC in the pod spec. - // +optional - optional bool hostIPC = 9; - - // seLinux is the strategy that will dictate the allowable labels that may be set. - optional SELinuxStrategyOptions seLinux = 10; - - // runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. - optional RunAsUserStrategyOptions runAsUser = 11; - - // RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. - // If this field is omitted, the pod's RunAsGroup can take any value. This field requires the - // RunAsGroup feature gate to be enabled. - // +optional - optional RunAsGroupStrategyOptions runAsGroup = 22; - - // supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - optional SupplementalGroupsStrategyOptions supplementalGroups = 12; - - // fsGroup is the strategy that will dictate what fs group is used by the SecurityContext. - optional FSGroupStrategyOptions fsGroup = 13; - - // readOnlyRootFilesystem when set to true will force containers to run with a read only root file - // system. If the container specifically requests to run with a non-read only root file system - // the PSP should deny the pod. - // If set to false the container may run with a read only root file system if it wishes but it - // will not be forced to. - // +optional - optional bool readOnlyRootFilesystem = 14; - - // defaultAllowPrivilegeEscalation controls the default setting for whether a - // process can gain more privileges than its parent process. - // +optional - optional bool defaultAllowPrivilegeEscalation = 15; - - // allowPrivilegeEscalation determines if a pod can request to allow - // privilege escalation. If unspecified, defaults to true. - // +optional - optional bool allowPrivilegeEscalation = 16; - - // allowedHostPaths is an allowlist of host paths. Empty indicates - // that all host paths may be used. - // +optional - repeated AllowedHostPath allowedHostPaths = 17; - - // allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all - // Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes - // is allowed in the "volumes" field. - // +optional - repeated AllowedFlexVolume allowedFlexVolumes = 18; - - // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. - // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // +optional - repeated AllowedCSIDriver allowedCSIDrivers = 23; - - // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. - // Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection. - // - // Examples: - // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. - // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. - // +optional - repeated string allowedUnsafeSysctls = 19; - - // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // - // Examples: - // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. - // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. - // +optional - repeated string forbiddenSysctls = 20; - - // AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. - // Empty or nil indicates that only the DefaultProcMountType may be used. - // This requires the ProcMountType feature flag to be enabled. - // +optional - repeated string allowedProcMountTypes = 21; - - // runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. - // If this field is omitted, the pod's runtimeClassName field is unrestricted. - // Enforcement of this field depends on the RuntimeClass feature gate being enabled. - // +optional - optional RuntimeClassStrategyOptions runtimeClass = 24; -} - // DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1beta2/ReplicaSet. See the release notes for // more information. // ReplicaSet ensures that a specified number of pod replicas are running at any given time. @@ -1076,7 +898,7 @@ message ReplicaSetSpec { // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller optional int32 replicas = 1; @@ -1182,57 +1004,6 @@ message RollingUpdateDeployment { optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxSurge = 2; } -// RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsGroupStrategyOptions from policy API Group instead. -message RunAsGroupStrategyOptions { - // rule is the strategy that will dictate the allowable RunAsGroup values that may be set. - optional string rule = 1; - - // ranges are the allowed ranges of gids that may be used. If you would like to force a single gid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsUserStrategyOptions from policy API Group instead. -message RunAsUserStrategyOptions { - // rule is the strategy that will dictate the allowable RunAsUser values that may be set. - optional string rule = 1; - - // ranges are the allowed ranges of uids that may be used. If you would like to force a single uid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - -// RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses -// for a pod. -message RuntimeClassStrategyOptions { - // allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. - // A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the - // list. An empty list requires the RuntimeClassName field to be unset. - repeated string allowedRuntimeClassNames = 1; - - // defaultRuntimeClassName is the default RuntimeClassName to set on the pod. - // The default MUST be allowed by the allowedRuntimeClassNames list. - // A value of nil does not mutate the Pod. - // +optional - optional string defaultRuntimeClassName = 2; -} - -// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use SELinuxStrategyOptions from policy API Group instead. -message SELinuxStrategyOptions { - // rule is the strategy that will dictate the allowable labels that may be set. - optional string rule = 1; - - // seLinuxOptions required to run as; required for MustRunAs - // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - // +optional - optional k8s.io.api.core.v1.SELinuxOptions seLinuxOptions = 2; -} - // represents a scaling request for a resource. message Scale { // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. @@ -1260,7 +1031,7 @@ message ScaleStatus { // actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic map selector = 2; @@ -1275,16 +1046,3 @@ message ScaleStatus { optional string targetSelector = 3; } -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead. -message SupplementalGroupsStrategyOptions { - // rule is the strategy that will dictate what supplemental groups is used in the SecurityContext. - // +optional - optional string rule = 1; - - // ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - diff --git a/vendor/k8s.io/api/extensions/v1beta1/register.go b/vendor/k8s.io/api/extensions/v1beta1/register.go index c69eff0bc46..d58908edc04 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/register.go +++ b/vendor/k8s.io/api/extensions/v1beta1/register.go @@ -54,8 +54,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { &IngressList{}, &ReplicaSet{}, &ReplicaSetList{}, - &PodSecurityPolicy{}, - &PodSecurityPolicyList{}, &NetworkPolicy{}, &NetworkPolicyList{}, ) diff --git a/vendor/k8s.io/api/extensions/v1beta1/types.go b/vendor/k8s.io/api/extensions/v1beta1/types.go index c63cf0d6713..c0ac6fa25dd 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/types.go +++ b/vendor/k8s.io/api/extensions/v1beta1/types.go @@ -35,7 +35,7 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` @@ -683,7 +683,54 @@ type IngressTLS struct { type IngressStatus struct { // LoadBalancer contains the current status of the load-balancer. // +optional - LoadBalancer v1.LoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` + LoadBalancer IngressLoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` +} + +// LoadBalancerStatus represents the status of a load-balancer. +type IngressLoadBalancerStatus struct { + // Ingress is a list containing ingress points for the load-balancer. + // +optional + Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` +} + +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +type IngressLoadBalancerIngress struct { + // IP is set for load-balancer ingress points that are IP based. + // +optional + IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` + + // Hostname is set for load-balancer ingress points that are DNS based. + // +optional + Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` + + // Ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic + // +optional + Ports []IngressPortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"` +} + +// IngressPortStatus represents the error condition of a service port +type IngressPortStatus struct { + // Port is the port number of the ingress port. + Port int32 `json:"port" protobuf:"varint,1,opt,name=port"` + + // Protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + Protocol v1.Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` + + // Error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + Error *string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"` } // IngressRule represents the rules mapping the paths under a specified host to @@ -920,7 +967,7 @@ type ReplicaSetSpec struct { // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently oberved number of replicas. + // Replicas is the most recently observed number of replicas. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` @@ -974,389 +1021,6 @@ type ReplicaSetCondition struct { Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` } -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.2 -// +k8s:prerelease-lifecycle-gen:deprecated=1.11 -// +k8s:prerelease-lifecycle-gen:removed=1.16 -// +k8s:prerelease-lifecycle-gen:replacement=policy,v1beta1,PodSecurityPolicy - -// PodSecurityPolicy governs the ability to make requests that affect the Security Context -// that will be applied to a pod and container. -// Deprecated: use PodSecurityPolicy from policy API Group instead. -type PodSecurityPolicy struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // spec defines the policy enforced. - // +optional - Spec PodSecurityPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` -} - -// PodSecurityPolicySpec defines the policy enforced. -// Deprecated: use PodSecurityPolicySpec from policy API Group instead. -type PodSecurityPolicySpec struct { - // privileged determines if a pod can request to be run as privileged. - // +optional - Privileged bool `json:"privileged,omitempty" protobuf:"varint,1,opt,name=privileged"` - // defaultAddCapabilities is the default set of capabilities that will be added to the container - // unless the pod spec specifically drops the capability. You may not list a capability in both - // defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly - // allowed, and need not be included in the allowedCapabilities list. - // +optional - DefaultAddCapabilities []v1.Capability `json:"defaultAddCapabilities,omitempty" protobuf:"bytes,2,rep,name=defaultAddCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // requiredDropCapabilities are the capabilities that will be dropped from the container. These - // are required to be dropped and cannot be added. - // +optional - RequiredDropCapabilities []v1.Capability `json:"requiredDropCapabilities,omitempty" protobuf:"bytes,3,rep,name=requiredDropCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // allowedCapabilities is a list of capabilities that can be requested to add to the container. - // Capabilities in this field may be added at the pod author's discretion. - // You must not list a capability in both allowedCapabilities and requiredDropCapabilities. - // +optional - AllowedCapabilities []v1.Capability `json:"allowedCapabilities,omitempty" protobuf:"bytes,4,rep,name=allowedCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // volumes is an allowlist of volume plugins. Empty indicates that - // no volumes may be used. To allow all volumes you may use '*'. - // +optional - Volumes []FSType `json:"volumes,omitempty" protobuf:"bytes,5,rep,name=volumes,casttype=FSType"` - // hostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - // +optional - HostNetwork bool `json:"hostNetwork,omitempty" protobuf:"varint,6,opt,name=hostNetwork"` - // hostPorts determines which host port ranges are allowed to be exposed. - // +optional - HostPorts []HostPortRange `json:"hostPorts,omitempty" protobuf:"bytes,7,rep,name=hostPorts"` - // hostPID determines if the policy allows the use of HostPID in the pod spec. - // +optional - HostPID bool `json:"hostPID,omitempty" protobuf:"varint,8,opt,name=hostPID"` - // hostIPC determines if the policy allows the use of HostIPC in the pod spec. - // +optional - HostIPC bool `json:"hostIPC,omitempty" protobuf:"varint,9,opt,name=hostIPC"` - // seLinux is the strategy that will dictate the allowable labels that may be set. - SELinux SELinuxStrategyOptions `json:"seLinux" protobuf:"bytes,10,opt,name=seLinux"` - // runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. - RunAsUser RunAsUserStrategyOptions `json:"runAsUser" protobuf:"bytes,11,opt,name=runAsUser"` - // RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. - // If this field is omitted, the pod's RunAsGroup can take any value. This field requires the - // RunAsGroup feature gate to be enabled. - // +optional - RunAsGroup *RunAsGroupStrategyOptions `json:"runAsGroup,omitempty" protobuf:"bytes,22,opt,name=runAsGroup"` - // supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups" protobuf:"bytes,12,opt,name=supplementalGroups"` - // fsGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions `json:"fsGroup" protobuf:"bytes,13,opt,name=fsGroup"` - // readOnlyRootFilesystem when set to true will force containers to run with a read only root file - // system. If the container specifically requests to run with a non-read only root file system - // the PSP should deny the pod. - // If set to false the container may run with a read only root file system if it wishes but it - // will not be forced to. - // +optional - ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" protobuf:"varint,14,opt,name=readOnlyRootFilesystem"` - // defaultAllowPrivilegeEscalation controls the default setting for whether a - // process can gain more privileges than its parent process. - // +optional - DefaultAllowPrivilegeEscalation *bool `json:"defaultAllowPrivilegeEscalation,omitempty" protobuf:"varint,15,opt,name=defaultAllowPrivilegeEscalation"` - // allowPrivilegeEscalation determines if a pod can request to allow - // privilege escalation. If unspecified, defaults to true. - // +optional - AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty" protobuf:"varint,16,opt,name=allowPrivilegeEscalation"` - // allowedHostPaths is an allowlist of host paths. Empty indicates - // that all host paths may be used. - // +optional - AllowedHostPaths []AllowedHostPath `json:"allowedHostPaths,omitempty" protobuf:"bytes,17,rep,name=allowedHostPaths"` - // allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all - // Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes - // is allowed in the "volumes" field. - // +optional - AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"` - // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. - // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // +optional - AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"` - // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. - // Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection. - // - // Examples: - // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. - // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. - // +optional - AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty" protobuf:"bytes,19,rep,name=allowedUnsafeSysctls"` - // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // - // Examples: - // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. - // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. - // +optional - ForbiddenSysctls []string `json:"forbiddenSysctls,omitempty" protobuf:"bytes,20,rep,name=forbiddenSysctls"` - // AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. - // Empty or nil indicates that only the DefaultProcMountType may be used. - // This requires the ProcMountType feature flag to be enabled. - // +optional - AllowedProcMountTypes []v1.ProcMountType `json:"allowedProcMountTypes,omitempty" protobuf:"bytes,21,opt,name=allowedProcMountTypes"` - // runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. - // If this field is omitted, the pod's runtimeClassName field is unrestricted. - // Enforcement of this field depends on the RuntimeClass feature gate being enabled. - // +optional - RuntimeClass *RuntimeClassStrategyOptions `json:"runtimeClass,omitempty" protobuf:"bytes,24,opt,name=runtimeClass"` -} - -// AllowedHostPath defines the host volume conditions that will be enabled by a policy -// for pods to use. It requires the path prefix to be defined. -// Deprecated: use AllowedHostPath from policy API Group instead. -type AllowedHostPath struct { - // pathPrefix is the path prefix that the host volume must match. - // It does not support `*`. - // Trailing slashes are trimmed when validating the path prefix with a host path. - // - // Examples: - // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` - // `/foo` would not allow `/food` or `/etc/foo` - PathPrefix string `json:"pathPrefix,omitempty" protobuf:"bytes,1,rep,name=pathPrefix"` - - // when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly. - // +optional - ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"` -} - -// FSType gives strong typing to different file systems that are used by volumes. -// Deprecated: use FSType from policy API Group instead. -type FSType string - -const ( - AzureFile FSType = "azureFile" - Flocker FSType = "flocker" - FlexVolume FSType = "flexVolume" - HostPath FSType = "hostPath" - EmptyDir FSType = "emptyDir" - GCEPersistentDisk FSType = "gcePersistentDisk" - AWSElasticBlockStore FSType = "awsElasticBlockStore" - GitRepo FSType = "gitRepo" - Secret FSType = "secret" - NFS FSType = "nfs" - ISCSI FSType = "iscsi" - Glusterfs FSType = "glusterfs" - PersistentVolumeClaim FSType = "persistentVolumeClaim" - RBD FSType = "rbd" - Cinder FSType = "cinder" - CephFS FSType = "cephFS" - DownwardAPI FSType = "downwardAPI" - FC FSType = "fc" - ConfigMap FSType = "configMap" - Quobyte FSType = "quobyte" - AzureDisk FSType = "azureDisk" - CSI FSType = "csi" - All FSType = "*" -) - -// AllowedFlexVolume represents a single Flexvolume that is allowed to be used. -// Deprecated: use AllowedFlexVolume from policy API Group instead. -type AllowedFlexVolume struct { - // driver is the name of the Flexvolume driver. - Driver string `json:"driver" protobuf:"bytes,1,opt,name=driver"` -} - -// AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used. -type AllowedCSIDriver struct { - // Name is the registered name of the CSI driver - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` -} - -// HostPortRange defines a range of host ports that will be enabled by a policy -// for pods to use. It requires both the start and end to be defined. -// Deprecated: use HostPortRange from policy API Group instead. -type HostPortRange struct { - // min is the start of the range, inclusive. - Min int32 `json:"min" protobuf:"varint,1,opt,name=min"` - // max is the end of the range, inclusive. - Max int32 `json:"max" protobuf:"varint,2,opt,name=max"` -} - -// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use SELinuxStrategyOptions from policy API Group instead. -type SELinuxStrategyOptions struct { - // rule is the strategy that will dictate the allowable labels that may be set. - Rule SELinuxStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=SELinuxStrategy"` - // seLinuxOptions required to run as; required for MustRunAs - // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - // +optional - SELinuxOptions *v1.SELinuxOptions `json:"seLinuxOptions,omitempty" protobuf:"bytes,2,opt,name=seLinuxOptions"` -} - -// SELinuxStrategy denotes strategy types for generating SELinux options for a -// Security Context. -// Deprecated: use SELinuxStrategy from policy API Group instead. -type SELinuxStrategy string - -const ( - // SELinuxStrategyMustRunAs means that container must have SELinux labels of X applied. - // Deprecated: use SELinuxStrategyMustRunAs from policy API Group instead. - SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs" - // SELinuxStrategyRunAsAny means that container may make requests for any SELinux context labels. - // Deprecated: use SELinuxStrategyRunAsAny from policy API Group instead. - SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny" -) - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsUserStrategyOptions from policy API Group instead. -type RunAsUserStrategyOptions struct { - // rule is the strategy that will dictate the allowable RunAsUser values that may be set. - Rule RunAsUserStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=RunAsUserStrategy"` - // ranges are the allowed ranges of uids that may be used. If you would like to force a single uid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsGroupStrategyOptions from policy API Group instead. -type RunAsGroupStrategyOptions struct { - // rule is the strategy that will dictate the allowable RunAsGroup values that may be set. - Rule RunAsGroupStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=RunAsGroupStrategy"` - // ranges are the allowed ranges of gids that may be used. If you would like to force a single gid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// IDRange provides a min/max of an allowed range of IDs. -// Deprecated: use IDRange from policy API Group instead. -type IDRange struct { - // min is the start of the range, inclusive. - Min int64 `json:"min" protobuf:"varint,1,opt,name=min"` - // max is the end of the range, inclusive. - Max int64 `json:"max" protobuf:"varint,2,opt,name=max"` -} - -// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a -// Security Context. -// Deprecated: use RunAsUserStrategy from policy API Group instead. -type RunAsUserStrategy string - -const ( - // RunAsUserStrategyMustRunAs means that container must run as a particular uid. - // Deprecated: use RunAsUserStrategyMustRunAs from policy API Group instead. - RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs" - // RunAsUserStrategyMustRunAsNonRoot means that container must run as a non-root uid. - // Deprecated: use RunAsUserStrategyMustRunAsNonRoot from policy API Group instead. - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot" - // RunAsUserStrategyRunAsAny means that container may make requests for any uid. - // Deprecated: use RunAsUserStrategyRunAsAny from policy API Group instead. - RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny" -) - -// RunAsGroupStrategy denotes strategy types for generating RunAsGroup values for a -// Security Context. -// Deprecated: use RunAsGroupStrategy from policy API Group instead. -type RunAsGroupStrategy string - -const ( - // RunAsGroupStrategyMayRunAs means that container does not need to run with a particular gid. - // However, when RunAsGroup are specified, they have to fall in the defined range. - RunAsGroupStrategyMayRunAs RunAsGroupStrategy = "MayRunAs" - // RunAsGroupStrategyMustRunAs means that container must run as a particular gid. - // Deprecated: use RunAsGroupStrategyMustRunAs from policy API Group instead. - RunAsGroupStrategyMustRunAs RunAsGroupStrategy = "MustRunAs" - // RunAsGroupStrategyRunAsAny means that container may make requests for any gid. - // Deprecated: use RunAsGroupStrategyRunAsAny from policy API Group instead. - RunAsGroupStrategyRunAsAny RunAsGroupStrategy = "RunAsAny" -) - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use FSGroupStrategyOptions from policy API Group instead. -type FSGroupStrategyOptions struct { - // rule is the strategy that will dictate what FSGroup is used in the SecurityContext. - // +optional - Rule FSGroupStrategyType `json:"rule,omitempty" protobuf:"bytes,1,opt,name=rule,casttype=FSGroupStrategyType"` - // ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -// Deprecated: use FSGroupStrategyType from policy API Group instead. -type FSGroupStrategyType string - -const ( - // FSGroupStrategyMustRunAs meant that container must have FSGroup of X applied. - // Deprecated: use FSGroupStrategyMustRunAs from policy API Group instead. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // FSGroupStrategyRunAsAny means that container may make requests for any FSGroup labels. - // Deprecated: use FSGroupStrategyRunAsAny from policy API Group instead. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" -) - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead. -type SupplementalGroupsStrategyOptions struct { - // rule is the strategy that will dictate what supplemental groups is used in the SecurityContext. - // +optional - Rule SupplementalGroupsStrategyType `json:"rule,omitempty" protobuf:"bytes,1,opt,name=rule,casttype=SupplementalGroupsStrategyType"` - // ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -// Deprecated: use SupplementalGroupsStrategyType from policy API Group instead. -type SupplementalGroupsStrategyType string - -const ( - // SupplementalGroupsStrategyMustRunAs means that container must run as a particular gid. - // Deprecated: use SupplementalGroupsStrategyMustRunAs from policy API Group instead. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // SupplementalGroupsStrategyRunAsAny means that container may make requests for any gid. - // Deprecated: use SupplementalGroupsStrategyRunAsAny from policy API Group instead. - SupplementalGroupsStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses -// for a pod. -type RuntimeClassStrategyOptions struct { - // allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. - // A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the - // list. An empty list requires the RuntimeClassName field to be unset. - AllowedRuntimeClassNames []string `json:"allowedRuntimeClassNames" protobuf:"bytes,1,rep,name=allowedRuntimeClassNames"` - // defaultRuntimeClassName is the default RuntimeClassName to set on the pod. - // The default MUST be allowed by the allowedRuntimeClassNames list. - // A value of nil does not mutate the Pod. - // +optional - DefaultRuntimeClassName *string `json:"defaultRuntimeClassName,omitempty" protobuf:"bytes,2,opt,name=defaultRuntimeClassName"` -} - -// AllowAllRuntimeClassNames can be used as a value for the -// RuntimeClassStrategyOptions.AllowedRuntimeClassNames field and means that any RuntimeClassName is -// allowed. -const AllowAllRuntimeClassNames = "*" - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.2 -// +k8s:prerelease-lifecycle-gen:deprecated=1.11 -// +k8s:prerelease-lifecycle-gen:removed=1.16 -// +k8s:prerelease-lifecycle-gen:replacement=policy,v1beta1,PodSecurityPolicyList - -// PodSecurityPolicyList is a list of PodSecurityPolicy objects. -// Deprecated: use PodSecurityPolicyList from policy API Group instead. -type PodSecurityPolicyList struct { - metav1.TypeMeta `json:",inline"` - // Standard list metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // items is a list of schema objects. - Items []PodSecurityPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` -} - // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.3 @@ -1498,22 +1162,20 @@ type NetworkPolicyPort struct { // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"` } // DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. -// IPBlock describes a particular CIDR (Ex. "192.168.1.1/24","2001:db9::/64") that is allowed +// IPBlock describes a particular CIDR (Ex. "192.168.1.0/24","2001:db8::/64") that is allowed // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. type IPBlock struct { // CIDR is a string representing the IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"` // Except is a slice of CIDRs that should not be included within an IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" // Except values will be rejected if they are outside the CIDR range // +optional Except []string `json:"except,omitempty" protobuf:"bytes,2,rep,name=except"` diff --git a/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index cf924b5897c..39aaf485377 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -24,37 +24,9 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. -var map_AllowedCSIDriver = map[string]string{ - "": "AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used.", - "name": "Name is the registered name of the CSI driver", -} - -func (AllowedCSIDriver) SwaggerDoc() map[string]string { - return map_AllowedCSIDriver -} - -var map_AllowedFlexVolume = map[string]string{ - "": "AllowedFlexVolume represents a single Flexvolume that is allowed to be used. Deprecated: use AllowedFlexVolume from policy API Group instead.", - "driver": "driver is the name of the Flexvolume driver.", -} - -func (AllowedFlexVolume) SwaggerDoc() map[string]string { - return map_AllowedFlexVolume -} - -var map_AllowedHostPath = map[string]string{ - "": "AllowedHostPath defines the host volume conditions that will be enabled by a policy for pods to use. It requires the path prefix to be defined. Deprecated: use AllowedHostPath from policy API Group instead.", - "pathPrefix": "pathPrefix is the path prefix that the host volume must match. It does not support `*`. Trailing slashes are trimmed when validating the path prefix with a host path.\n\nExamples: `/foo` would allow `/foo`, `/foo/` and `/foo/bar` `/foo` would not allow `/food` or `/etc/foo`", - "readOnly": "when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly.", -} - -func (AllowedHostPath) SwaggerDoc() map[string]string { - return map_AllowedHostPath -} - var map_DaemonSet = map[string]string{ "": "DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more information. DaemonSet represents the configuration of a daemon set.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -220,16 +192,6 @@ func (DeploymentStrategy) SwaggerDoc() map[string]string { return map_DeploymentStrategy } -var map_FSGroupStrategyOptions = map[string]string{ - "": "FSGroupStrategyOptions defines the strategy type and options used to create the strategy. Deprecated: use FSGroupStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate what FSGroup is used in the SecurityContext.", - "ranges": "ranges are the allowed ranges of fs groups. If you would like to force a single fs group then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (FSGroupStrategyOptions) SwaggerDoc() map[string]string { - return map_FSGroupStrategyOptions -} - var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", @@ -250,30 +212,10 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { return map_HTTPIngressRuleValue } -var map_HostPortRange = map[string]string{ - "": "HostPortRange defines a range of host ports that will be enabled by a policy for pods to use. It requires both the start and end to be defined. Deprecated: use HostPortRange from policy API Group instead.", - "min": "min is the start of the range, inclusive.", - "max": "max is the end of the range, inclusive.", -} - -func (HostPortRange) SwaggerDoc() map[string]string { - return map_HostPortRange -} - -var map_IDRange = map[string]string{ - "": "IDRange provides a min/max of an allowed range of IDs. Deprecated: use IDRange from policy API Group instead.", - "min": "min is the start of the range, inclusive.", - "max": "max is the end of the range, inclusive.", -} - -func (IDRange) SwaggerDoc() map[string]string { - return map_IDRange -} - var map_IPBlock = map[string]string{ - "": "DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. IPBlock describes a particular CIDR (Ex. \"192.168.1.1/24\",\"2001:db9::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", - "cidr": "CIDR is a string representing the IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\"", - "except": "Except is a slice of CIDRs that should not be included within an IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\" Except values will be rejected if they are outside the CIDR range", + "": "DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. IPBlock describes a particular CIDR (Ex. \"192.168.1.0/24\",\"2001:db8::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", + "cidr": "CIDR is a string representing the IP Block Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", + "except": "Except is a slice of CIDRs that should not be included within an IP Block Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\" Except values will be rejected if they are outside the CIDR range", } func (IPBlock) SwaggerDoc() map[string]string { @@ -312,6 +254,37 @@ func (IngressList) SwaggerDoc() map[string]string { return map_IngressList } +var map_IngressLoadBalancerIngress = map[string]string{ + "": "IngressLoadBalancerIngress represents the status of a load-balancer ingress point.", + "ip": "IP is set for load-balancer ingress points that are IP based.", + "hostname": "Hostname is set for load-balancer ingress points that are DNS based.", + "ports": "Ports provides information about the ports exposed by this LoadBalancer.", +} + +func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerIngress +} + +var map_IngressLoadBalancerStatus = map[string]string{ + "": "LoadBalancerStatus represents the status of a load-balancer.", + "ingress": "Ingress is a list containing ingress points for the load-balancer.", +} + +func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerStatus +} + +var map_IngressPortStatus = map[string]string{ + "": "IngressPortStatus represents the error condition of a service port", + "port": "Port is the port number of the ingress port.", + "protocol": "Protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", + "error": "Error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", +} + +func (IngressPortStatus) SwaggerDoc() map[string]string { + return map_IngressPortStatus +} + var map_IngressRule = map[string]string{ "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nHost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", @@ -417,7 +390,7 @@ var map_NetworkPolicyPort = map[string]string{ "": "DEPRECATED 1.9 - This group version of NetworkPolicyPort is deprecated by networking/v1/NetworkPolicyPort.", "protocol": "Optional. The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", "port": "The port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", - "endPort": "If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. This feature is in Beta state and is enabled by default. It can be disabled using the Feature Gate \"NetworkPolicyEndPort\".", + "endPort": "If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port.", } func (NetworkPolicyPort) SwaggerDoc() map[string]string { @@ -445,58 +418,6 @@ func (NetworkPolicyStatus) SwaggerDoc() map[string]string { return map_NetworkPolicyStatus } -var map_PodSecurityPolicy = map[string]string{ - "": "PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Deprecated: use PodSecurityPolicy from policy API Group instead.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "spec defines the policy enforced.", -} - -func (PodSecurityPolicy) SwaggerDoc() map[string]string { - return map_PodSecurityPolicy -} - -var map_PodSecurityPolicyList = map[string]string{ - "": "PodSecurityPolicyList is a list of PodSecurityPolicy objects. Deprecated: use PodSecurityPolicyList from policy API Group instead.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "items is a list of schema objects.", -} - -func (PodSecurityPolicyList) SwaggerDoc() map[string]string { - return map_PodSecurityPolicyList -} - -var map_PodSecurityPolicySpec = map[string]string{ - "": "PodSecurityPolicySpec defines the policy enforced. Deprecated: use PodSecurityPolicySpec from policy API Group instead.", - "privileged": "privileged determines if a pod can request to be run as privileged.", - "defaultAddCapabilities": "defaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability. You may not list a capability in both defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly allowed, and need not be included in the allowedCapabilities list.", - "requiredDropCapabilities": "requiredDropCapabilities are the capabilities that will be dropped from the container. These are required to be dropped and cannot be added.", - "allowedCapabilities": "allowedCapabilities is a list of capabilities that can be requested to add to the container. Capabilities in this field may be added at the pod author's discretion. You must not list a capability in both allowedCapabilities and requiredDropCapabilities.", - "volumes": "volumes is an allowlist of volume plugins. Empty indicates that no volumes may be used. To allow all volumes you may use '*'.", - "hostNetwork": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.", - "hostPorts": "hostPorts determines which host port ranges are allowed to be exposed.", - "hostPID": "hostPID determines if the policy allows the use of HostPID in the pod spec.", - "hostIPC": "hostIPC determines if the policy allows the use of HostIPC in the pod spec.", - "seLinux": "seLinux is the strategy that will dictate the allowable labels that may be set.", - "runAsUser": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.", - "runAsGroup": "RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. If this field is omitted, the pod's RunAsGroup can take any value. This field requires the RunAsGroup feature gate to be enabled.", - "supplementalGroups": "supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.", - "fsGroup": "fsGroup is the strategy that will dictate what fs group is used by the SecurityContext.", - "readOnlyRootFilesystem": "readOnlyRootFilesystem when set to true will force containers to run with a read only root file system. If the container specifically requests to run with a non-read only root file system the PSP should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.", - "defaultAllowPrivilegeEscalation": "defaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process.", - "allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.", - "allowedHostPaths": "allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.", - "allowedFlexVolumes": "allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.", - "allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.", - "allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.", - "forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.", - "allowedProcMountTypes": "AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.", - "runtimeClass": "runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. If this field is omitted, the pod's runtimeClassName field is unrestricted. Enforcement of this field depends on the RuntimeClass feature gate being enabled.", -} - -func (PodSecurityPolicySpec) SwaggerDoc() map[string]string { - return map_PodSecurityPolicySpec -} - var map_ReplicaSet = map[string]string{ "": "DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1beta2/ReplicaSet. See the release notes for more information. ReplicaSet ensures that a specified number of pod replicas are running at any given time.", "metadata": "If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -545,7 +466,7 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", "readyReplicas": "The number of ready replicas for this replica set.", "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", @@ -586,46 +507,6 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { return map_RollingUpdateDeployment } -var map_RunAsGroupStrategyOptions = map[string]string{ - "": "RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use RunAsGroupStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable RunAsGroup values that may be set.", - "ranges": "ranges are the allowed ranges of gids that may be used. If you would like to force a single gid then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (RunAsGroupStrategyOptions) SwaggerDoc() map[string]string { - return map_RunAsGroupStrategyOptions -} - -var map_RunAsUserStrategyOptions = map[string]string{ - "": "RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use RunAsUserStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable RunAsUser values that may be set.", - "ranges": "ranges are the allowed ranges of uids that may be used. If you would like to force a single uid then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (RunAsUserStrategyOptions) SwaggerDoc() map[string]string { - return map_RunAsUserStrategyOptions -} - -var map_RuntimeClassStrategyOptions = map[string]string{ - "": "RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses for a pod.", - "allowedRuntimeClassNames": "allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. A value of \"*\" means that any RuntimeClass name is allowed, and must be the only item in the list. An empty list requires the RuntimeClassName field to be unset.", - "defaultRuntimeClassName": "defaultRuntimeClassName is the default RuntimeClassName to set on the pod. The default MUST be allowed by the allowedRuntimeClassNames list. A value of nil does not mutate the Pod.", -} - -func (RuntimeClassStrategyOptions) SwaggerDoc() map[string]string { - return map_RuntimeClassStrategyOptions -} - -var map_SELinuxStrategyOptions = map[string]string{ - "": "SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use SELinuxStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable labels that may be set.", - "seLinuxOptions": "seLinuxOptions required to run as; required for MustRunAs More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", -} - -func (SELinuxStrategyOptions) SwaggerDoc() map[string]string { - return map_SELinuxStrategyOptions -} - var map_Scale = map[string]string{ "": "represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", @@ -649,7 +530,7 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "represents the current status of a scale subresource.", "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } @@ -657,14 +538,4 @@ func (ScaleStatus) SwaggerDoc() map[string]string { return map_ScaleStatus } -var map_SupplementalGroupsStrategyOptions = map[string]string{ - "": "SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate what supplemental groups is used in the SecurityContext.", - "ranges": "ranges are the allowed ranges of supplemental groups. If you would like to force a single supplemental group then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (SupplementalGroupsStrategyOptions) SwaggerDoc() map[string]string { - return map_SupplementalGroupsStrategyOptions -} - // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go index 9c1c8421c31..b6e92729928 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go @@ -28,54 +28,6 @@ import ( intstr "k8s.io/apimachinery/pkg/util/intstr" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedCSIDriver) DeepCopyInto(out *AllowedCSIDriver) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedCSIDriver. -func (in *AllowedCSIDriver) DeepCopy() *AllowedCSIDriver { - if in == nil { - return nil - } - out := new(AllowedCSIDriver) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedFlexVolume) DeepCopyInto(out *AllowedFlexVolume) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedFlexVolume. -func (in *AllowedFlexVolume) DeepCopy() *AllowedFlexVolume { - if in == nil { - return nil - } - out := new(AllowedFlexVolume) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedHostPath) DeepCopyInto(out *AllowedHostPath) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedHostPath. -func (in *AllowedHostPath) DeepCopy() *AllowedHostPath { - if in == nil { - return nil - } - out := new(AllowedHostPath) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { *out = *in @@ -435,27 +387,6 @@ func (in *DeploymentStrategy) DeepCopy() *DeploymentStrategy { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FSGroupStrategyOptions) DeepCopyInto(out *FSGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FSGroupStrategyOptions. -func (in *FSGroupStrategyOptions) DeepCopy() *FSGroupStrategyOptions { - if in == nil { - return nil - } - out := new(FSGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in @@ -501,38 +432,6 @@ func (in *HTTPIngressRuleValue) DeepCopy() *HTTPIngressRuleValue { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HostPortRange) DeepCopyInto(out *HostPortRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPortRange. -func (in *HostPortRange) DeepCopy() *HostPortRange { - if in == nil { - return nil - } - out := new(HostPortRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IDRange) DeepCopyInto(out *IDRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IDRange. -func (in *IDRange) DeepCopy() *IDRange { - if in == nil { - return nil - } - out := new(IDRange) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IPBlock) DeepCopyInto(out *IPBlock) { *out = *in @@ -637,6 +536,73 @@ func (in *IngressList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerIngress) DeepCopyInto(out *IngressLoadBalancerIngress) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]IngressPortStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerIngress. +func (in *IngressLoadBalancerIngress) DeepCopy() *IngressLoadBalancerIngress { + if in == nil { + return nil + } + out := new(IngressLoadBalancerIngress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerStatus) DeepCopyInto(out *IngressLoadBalancerStatus) { + *out = *in + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = make([]IngressLoadBalancerIngress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerStatus. +func (in *IngressLoadBalancerStatus) DeepCopy() *IngressLoadBalancerStatus { + if in == nil { + return nil + } + out := new(IngressLoadBalancerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressPortStatus) DeepCopyInto(out *IngressPortStatus) { + *out = *in + if in.Error != nil { + in, out := &in.Error, &out.Error + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressPortStatus. +func (in *IngressPortStatus) DeepCopy() *IngressPortStatus { + if in == nil { + return nil + } + out := new(IngressPortStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = *in @@ -995,161 +961,6 @@ func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSecurityPolicy) DeepCopyInto(out *PodSecurityPolicy) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicy. -func (in *PodSecurityPolicy) DeepCopy() *PodSecurityPolicy { - if in == nil { - return nil - } - out := new(PodSecurityPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicy) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSecurityPolicyList) DeepCopyInto(out *PodSecurityPolicyList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PodSecurityPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicyList. -func (in *PodSecurityPolicyList) DeepCopy() *PodSecurityPolicyList { - if in == nil { - return nil - } - out := new(PodSecurityPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicyList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSecurityPolicySpec) DeepCopyInto(out *PodSecurityPolicySpec) { - *out = *in - if in.DefaultAddCapabilities != nil { - in, out := &in.DefaultAddCapabilities, &out.DefaultAddCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.RequiredDropCapabilities != nil { - in, out := &in.RequiredDropCapabilities, &out.RequiredDropCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.AllowedCapabilities != nil { - in, out := &in.AllowedCapabilities, &out.AllowedCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]FSType, len(*in)) - copy(*out, *in) - } - if in.HostPorts != nil { - in, out := &in.HostPorts, &out.HostPorts - *out = make([]HostPortRange, len(*in)) - copy(*out, *in) - } - in.SELinux.DeepCopyInto(&out.SELinux) - in.RunAsUser.DeepCopyInto(&out.RunAsUser) - if in.RunAsGroup != nil { - in, out := &in.RunAsGroup, &out.RunAsGroup - *out = new(RunAsGroupStrategyOptions) - (*in).DeepCopyInto(*out) - } - in.SupplementalGroups.DeepCopyInto(&out.SupplementalGroups) - in.FSGroup.DeepCopyInto(&out.FSGroup) - if in.DefaultAllowPrivilegeEscalation != nil { - in, out := &in.DefaultAllowPrivilegeEscalation, &out.DefaultAllowPrivilegeEscalation - *out = new(bool) - **out = **in - } - if in.AllowPrivilegeEscalation != nil { - in, out := &in.AllowPrivilegeEscalation, &out.AllowPrivilegeEscalation - *out = new(bool) - **out = **in - } - if in.AllowedHostPaths != nil { - in, out := &in.AllowedHostPaths, &out.AllowedHostPaths - *out = make([]AllowedHostPath, len(*in)) - copy(*out, *in) - } - if in.AllowedFlexVolumes != nil { - in, out := &in.AllowedFlexVolumes, &out.AllowedFlexVolumes - *out = make([]AllowedFlexVolume, len(*in)) - copy(*out, *in) - } - if in.AllowedCSIDrivers != nil { - in, out := &in.AllowedCSIDrivers, &out.AllowedCSIDrivers - *out = make([]AllowedCSIDriver, len(*in)) - copy(*out, *in) - } - if in.AllowedUnsafeSysctls != nil { - in, out := &in.AllowedUnsafeSysctls, &out.AllowedUnsafeSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ForbiddenSysctls != nil { - in, out := &in.ForbiddenSysctls, &out.ForbiddenSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.AllowedProcMountTypes != nil { - in, out := &in.AllowedProcMountTypes, &out.AllowedProcMountTypes - *out = make([]corev1.ProcMountType, len(*in)) - copy(*out, *in) - } - if in.RuntimeClass != nil { - in, out := &in.RuntimeClass, &out.RuntimeClass - *out = new(RuntimeClassStrategyOptions) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicySpec. -func (in *PodSecurityPolicySpec) DeepCopy() *PodSecurityPolicySpec { - if in == nil { - return nil - } - out := new(PodSecurityPolicySpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) { *out = *in @@ -1346,95 +1157,6 @@ func (in *RollingUpdateDeployment) DeepCopy() *RollingUpdateDeployment { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsGroupStrategyOptions) DeepCopyInto(out *RunAsGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsGroupStrategyOptions. -func (in *RunAsGroupStrategyOptions) DeepCopy() *RunAsGroupStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsUserStrategyOptions) DeepCopyInto(out *RunAsUserStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsUserStrategyOptions. -func (in *RunAsUserStrategyOptions) DeepCopy() *RunAsUserStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsUserStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RuntimeClassStrategyOptions) DeepCopyInto(out *RuntimeClassStrategyOptions) { - *out = *in - if in.AllowedRuntimeClassNames != nil { - in, out := &in.AllowedRuntimeClassNames, &out.AllowedRuntimeClassNames - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.DefaultRuntimeClassName != nil { - in, out := &in.DefaultRuntimeClassName, &out.DefaultRuntimeClassName - *out = new(string) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeClassStrategyOptions. -func (in *RuntimeClassStrategyOptions) DeepCopy() *RuntimeClassStrategyOptions { - if in == nil { - return nil - } - out := new(RuntimeClassStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SELinuxStrategyOptions) DeepCopyInto(out *SELinuxStrategyOptions) { - *out = *in - if in.SELinuxOptions != nil { - in, out := &in.SELinuxOptions, &out.SELinuxOptions - *out = new(corev1.SELinuxOptions) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SELinuxStrategyOptions. -func (in *SELinuxStrategyOptions) DeepCopy() *SELinuxStrategyOptions { - if in == nil { - return nil - } - out := new(SELinuxStrategyOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Scale) DeepCopyInto(out *Scale) { *out = *in @@ -1501,24 +1223,3 @@ func (in *ScaleStatus) DeepCopy() *ScaleStatus { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SupplementalGroupsStrategyOptions) DeepCopyInto(out *SupplementalGroupsStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupplementalGroupsStrategyOptions. -func (in *SupplementalGroupsStrategyOptions) DeepCopy() *SupplementalGroupsStrategyOptions { - if in == nil { - return nil - } - out := new(SupplementalGroupsStrategyOptions) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go index 963aaffba35..5c93542282e 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go @@ -235,54 +235,6 @@ func (in *NetworkPolicyList) APILifecycleRemoved() (major, minor int) { return 1, 16 } -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *PodSecurityPolicy) APILifecycleIntroduced() (major, minor int) { - return 1, 2 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *PodSecurityPolicy) APILifecycleDeprecated() (major, minor int) { - return 1, 11 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *PodSecurityPolicy) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicy"} -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *PodSecurityPolicy) APILifecycleRemoved() (major, minor int) { - return 1, 16 -} - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *PodSecurityPolicyList) APILifecycleIntroduced() (major, minor int) { - return 1, 2 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *PodSecurityPolicyList) APILifecycleDeprecated() (major, minor int) { - return 1, 11 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *PodSecurityPolicyList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicyList"} -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *PodSecurityPolicyList) APILifecycleRemoved() (major, minor int) { - return 1, 16 -} - // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *ReplicaSet) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.pb.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.pb.go index a45e23e236a..cf5fc5600ba 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.pb.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.pb.go @@ -689,102 +689,105 @@ func init() { } var fileDescriptor_45ba024d525b289b = []byte{ - // 1505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4b, 0x6f, 0xdb, 0xc6, - 0x16, 0x36, 0x65, 0xc9, 0xb6, 0xc6, 0xcf, 0x8c, 0x13, 0x58, 0x70, 0x00, 0xc9, 0xe1, 0x05, 0x6e, - 0x72, 0x6f, 0x12, 0x32, 0xce, 0x4d, 0x72, 0x53, 0x04, 0x45, 0x60, 0x3a, 0x69, 0x5e, 0xb6, 0x6b, - 0x8f, 0x92, 0x14, 0x0d, 0x52, 0x20, 0x34, 0x35, 0x96, 0x26, 0x96, 0x48, 0x76, 0x86, 0x54, 0xea, - 0x22, 0x8b, 0x02, 0xfd, 0x03, 0xfd, 0x01, 0x59, 0x76, 0xd1, 0x75, 0x7f, 0x41, 0x97, 0x46, 0xd1, - 0x45, 0x96, 0x59, 0x09, 0xb1, 0xba, 0x2d, 0xba, 0x6e, 0xb3, 0x2a, 0x66, 0x38, 0x24, 0x45, 0xbd, - 0xa8, 0xd4, 0x40, 0x56, 0xdd, 0x89, 0xe7, 0xf1, 0x9d, 0x39, 0x67, 0xce, 0x39, 0xf3, 0xd9, 0xe0, - 0xee, 0xfe, 0x75, 0xa6, 0x11, 0x47, 0xdf, 0xf7, 0x77, 0x31, 0xb5, 0xb1, 0x87, 0x99, 0xde, 0xc4, - 0x76, 0xc5, 0xa1, 0xba, 0x54, 0x98, 0x2e, 0xd1, 0xf7, 0xea, 0xce, 0x0b, 0xcb, 0xb1, 0x3d, 0xea, - 0xd4, 0xf5, 0xe6, 0xaa, 0x59, 0x77, 0x6b, 0xe6, 0xaa, 0x5e, 0xc5, 0x36, 0xa6, 0xa6, 0x87, 0x2b, - 0x9a, 0x4b, 0x1d, 0xcf, 0x81, 0xa5, 0xc0, 0x41, 0x33, 0x5d, 0xa2, 0x75, 0x38, 0x68, 0xa1, 0xc3, - 0xf2, 0xc5, 0x2a, 0xf1, 0x6a, 0xfe, 0xae, 0x66, 0x39, 0x0d, 0xbd, 0xea, 0x54, 0x1d, 0x5d, 0xf8, - 0xed, 0xfa, 0x7b, 0xe2, 0x4b, 0x7c, 0x88, 0x5f, 0x01, 0xde, 0xf2, 0x95, 0xf8, 0x00, 0x0d, 0xd3, - 0xaa, 0x11, 0x1b, 0xd3, 0x03, 0xdd, 0xdd, 0xaf, 0x72, 0x01, 0xd3, 0x1b, 0xd8, 0x33, 0xf5, 0x66, - 0xcf, 0x29, 0x96, 0xf5, 0x41, 0x5e, 0xd4, 0xb7, 0x3d, 0xd2, 0xc0, 0x3d, 0x0e, 0xd7, 0xd2, 0x1c, - 0x98, 0x55, 0xc3, 0x0d, 0xb3, 0xdb, 0x4f, 0x7d, 0x02, 0x96, 0x3e, 0xa9, 0x3b, 0x2f, 0x6e, 0x11, - 0xe6, 0x11, 0xbb, 0xea, 0x13, 0x56, 0xc3, 0x74, 0x13, 0x7b, 0x35, 0xa7, 0x02, 0x6f, 0x82, 0xac, - 0x77, 0xe0, 0xe2, 0x82, 0xb2, 0xa2, 0x9c, 0xcb, 0x1b, 0xe7, 0x0f, 0x5b, 0xa5, 0xb1, 0x76, 0xab, - 0x94, 0x7d, 0x78, 0xe0, 0xe2, 0x77, 0xad, 0xd2, 0xe9, 0x01, 0x6e, 0x5c, 0x8d, 0x84, 0xa3, 0xfa, - 0x2a, 0x03, 0x00, 0xb7, 0x2a, 0x8b, 0xd0, 0xf0, 0x19, 0x98, 0xe2, 0xe9, 0x56, 0x4c, 0xcf, 0x14, - 0x98, 0xd3, 0x97, 0x2f, 0x69, 0x71, 0xb1, 0xa3, 0x53, 0x6b, 0xee, 0x7e, 0x95, 0x0b, 0x98, 0xc6, - 0xad, 0xb5, 0xe6, 0xaa, 0xf6, 0xe9, 0xee, 0x73, 0x6c, 0x79, 0x9b, 0xd8, 0x33, 0x0d, 0x28, 0x4f, - 0x01, 0x62, 0x19, 0x8a, 0x50, 0xe1, 0x0e, 0xc8, 0x32, 0x17, 0x5b, 0x85, 0x8c, 0x40, 0xd7, 0xb5, - 0x94, 0xab, 0xd4, 0xe2, 0xc3, 0x95, 0x5d, 0x6c, 0x19, 0x33, 0x61, 0x8a, 0xfc, 0x0b, 0x09, 0x28, - 0xf8, 0x39, 0x98, 0x60, 0x9e, 0xe9, 0xf9, 0xac, 0x30, 0x2e, 0x40, 0x57, 0xdf, 0x07, 0x54, 0x38, - 0x1a, 0x73, 0x12, 0x76, 0x22, 0xf8, 0x46, 0x12, 0x50, 0x7d, 0x93, 0x01, 0x8b, 0xb1, 0xf1, 0xba, - 0x63, 0x57, 0x88, 0x47, 0x1c, 0x1b, 0xde, 0x48, 0xd4, 0xfd, 0x6c, 0x57, 0xdd, 0x97, 0xfa, 0xb8, - 0xc4, 0x35, 0x87, 0x1f, 0x45, 0xe7, 0xcd, 0x08, 0xf7, 0x33, 0xc9, 0xe0, 0xef, 0x5a, 0xa5, 0xf9, - 0xc8, 0x2d, 0x79, 0x1e, 0xd8, 0x04, 0xb0, 0x6e, 0x32, 0xef, 0x21, 0x35, 0x6d, 0x16, 0xc0, 0x92, - 0x06, 0x96, 0x69, 0xff, 0x77, 0xb4, 0x9b, 0xe2, 0x1e, 0xc6, 0xb2, 0x0c, 0x09, 0x37, 0x7a, 0xd0, - 0x50, 0x9f, 0x08, 0xf0, 0xdf, 0x60, 0x82, 0x62, 0x93, 0x39, 0x76, 0x21, 0x2b, 0x8e, 0x1c, 0xd5, - 0x0b, 0x09, 0x29, 0x92, 0x5a, 0xf8, 0x1f, 0x30, 0xd9, 0xc0, 0x8c, 0x99, 0x55, 0x5c, 0xc8, 0x09, - 0xc3, 0x79, 0x69, 0x38, 0xb9, 0x19, 0x88, 0x51, 0xa8, 0x57, 0x7f, 0x52, 0xc0, 0x5c, 0x5c, 0xa7, - 0x0d, 0xc2, 0x3c, 0xf8, 0xb4, 0xa7, 0xfb, 0xb4, 0xd1, 0x72, 0xe2, 0xde, 0xa2, 0xf7, 0x16, 0x64, - 0xb8, 0xa9, 0x50, 0xd2, 0xd1, 0x79, 0xdb, 0x20, 0x47, 0x3c, 0xdc, 0xe0, 0x55, 0x1f, 0x3f, 0x37, - 0x7d, 0xf9, 0xfc, 0x7b, 0x74, 0x89, 0x31, 0x2b, 0x71, 0x73, 0xf7, 0x38, 0x02, 0x0a, 0x80, 0xd4, - 0xdf, 0xc6, 0x3b, 0x53, 0xe0, 0x1d, 0x09, 0x7f, 0x50, 0xc0, 0xb2, 0x4b, 0x89, 0x43, 0x89, 0x77, - 0xb0, 0x81, 0x9b, 0xb8, 0xbe, 0xee, 0xd8, 0x7b, 0xa4, 0xea, 0x53, 0x93, 0xd7, 0x52, 0x66, 0x75, - 0x2b, 0x35, 0xf4, 0xf6, 0x40, 0x08, 0x84, 0xf7, 0x30, 0xc5, 0xb6, 0x85, 0x0d, 0x55, 0x9e, 0x69, - 0x79, 0x88, 0xf1, 0x90, 0xb3, 0xc0, 0xfb, 0x00, 0x36, 0x4c, 0x8f, 0xd7, 0xb4, 0xba, 0x4d, 0xb1, - 0x85, 0x2b, 0x1c, 0x55, 0xb4, 0x64, 0x2e, 0xee, 0x8f, 0xcd, 0x1e, 0x0b, 0xd4, 0xc7, 0x0b, 0x7e, - 0xab, 0x80, 0xc5, 0x4a, 0xef, 0xa2, 0x91, 0x9d, 0x79, 0x7d, 0xa4, 0x52, 0xf7, 0x59, 0x54, 0xc6, - 0x52, 0xbb, 0x55, 0x5a, 0xec, 0xa3, 0x40, 0xfd, 0xa2, 0xc1, 0x2f, 0x40, 0x8e, 0xfa, 0x75, 0xcc, - 0x0a, 0x59, 0x71, 0xc3, 0xe9, 0x61, 0xb7, 0x9d, 0x3a, 0xb1, 0x0e, 0x10, 0xf7, 0xf9, 0x8c, 0x78, - 0xb5, 0xb2, 0x2f, 0x36, 0x16, 0x8b, 0xaf, 0x5b, 0xa8, 0x50, 0x80, 0xaa, 0xbe, 0x04, 0x0b, 0xdd, - 0x8b, 0x03, 0xd6, 0x00, 0xb0, 0xc2, 0x59, 0x65, 0x05, 0x45, 0xc4, 0xbd, 0xf2, 0x1e, 0x9d, 0x15, - 0x0d, 0x7a, 0xbc, 0x36, 0x23, 0x11, 0x43, 0x1d, 0xd8, 0xea, 0x25, 0x30, 0x73, 0x87, 0x3a, 0xbe, - 0x2b, 0x0f, 0x09, 0x57, 0x40, 0xd6, 0x36, 0x1b, 0xe1, 0x0a, 0x8a, 0xf6, 0xe2, 0x96, 0xd9, 0xc0, - 0x48, 0x68, 0xd4, 0xef, 0x15, 0x30, 0xbb, 0x41, 0x1a, 0xc4, 0x43, 0x98, 0xb9, 0x8e, 0xcd, 0x30, - 0xbc, 0x9a, 0x58, 0x5b, 0x67, 0xba, 0xd6, 0xd6, 0x89, 0x84, 0x71, 0xc7, 0xc2, 0x7a, 0x0a, 0x26, - 0xbf, 0xf4, 0xb1, 0x4f, 0xec, 0xaa, 0x5c, 0xdb, 0x57, 0x53, 0x33, 0xdc, 0x09, 0xec, 0x13, 0x1d, - 0x67, 0x4c, 0xf3, 0x45, 0x20, 0x35, 0x28, 0x84, 0x54, 0x7f, 0x57, 0xc0, 0x19, 0x11, 0x19, 0x57, - 0x06, 0x77, 0x32, 0x7c, 0x0a, 0x0a, 0x26, 0x63, 0x3e, 0xc5, 0x95, 0x75, 0xc7, 0xb6, 0x7c, 0xca, - 0x67, 0xe0, 0xa0, 0x5c, 0x33, 0x29, 0x66, 0x22, 0x9d, 0x9c, 0xb1, 0x22, 0xd3, 0x29, 0xac, 0x0d, - 0xb0, 0x43, 0x03, 0x11, 0xe0, 0x3e, 0x98, 0xad, 0x77, 0x26, 0x2f, 0xf3, 0xd4, 0x52, 0xf3, 0x4c, - 0x94, 0xcc, 0x38, 0x25, 0x8f, 0x90, 0x2c, 0x3b, 0x4a, 0x62, 0xab, 0x2f, 0xc0, 0xa9, 0x2d, 0x3e, - 0xc8, 0xcc, 0xf1, 0xa9, 0x85, 0xe3, 0x1e, 0x84, 0x25, 0x90, 0x6b, 0x62, 0xba, 0x1b, 0xf4, 0x51, - 0xde, 0xc8, 0xf3, 0x0e, 0x7c, 0xcc, 0x05, 0x28, 0x90, 0xc3, 0x8f, 0xc1, 0xbc, 0x1d, 0x7b, 0x3e, - 0x42, 0x1b, 0xac, 0x30, 0x21, 0x4c, 0x17, 0xdb, 0xad, 0xd2, 0xfc, 0x56, 0x52, 0x85, 0xba, 0x6d, - 0xd5, 0xa3, 0x0c, 0x58, 0x1a, 0xd0, 0xf2, 0xf0, 0x31, 0x98, 0x62, 0xf2, 0xb7, 0x6c, 0xe3, 0x73, - 0xa9, 0xc9, 0x4b, 0xe7, 0x78, 0xeb, 0x86, 0x68, 0x28, 0xc2, 0x82, 0x2e, 0x98, 0xa5, 0xf2, 0x0c, - 0x22, 0xa8, 0xdc, 0xbe, 0xff, 0x4b, 0x05, 0xef, 0xad, 0x4f, 0x5c, 0x5e, 0xd4, 0x89, 0x88, 0x92, - 0x01, 0xe0, 0x4b, 0xb0, 0xd0, 0x91, 0x78, 0x10, 0x74, 0x5c, 0x04, 0xbd, 0x96, 0x1a, 0xb4, 0xef, - 0xbd, 0x18, 0x05, 0x19, 0x77, 0x61, 0xab, 0x0b, 0x17, 0xf5, 0x44, 0x52, 0x7f, 0xc9, 0x80, 0x21, - 0x0b, 0xf9, 0x03, 0x10, 0x2c, 0x33, 0x41, 0xb0, 0x6e, 0x1e, 0xe3, 0xa9, 0x19, 0x48, 0xb8, 0x48, - 0x17, 0xe1, 0x5a, 0x3b, 0x4e, 0x90, 0xe1, 0x04, 0xec, 0x8f, 0x0c, 0xf8, 0xd7, 0x60, 0xe7, 0x98, - 0x90, 0x3d, 0x48, 0x6c, 0xb6, 0xff, 0x77, 0x6d, 0xb6, 0xb3, 0x23, 0x40, 0xfc, 0x43, 0xd0, 0xba, - 0x08, 0xda, 0x5b, 0x05, 0x14, 0x07, 0xd7, 0xed, 0x03, 0x10, 0xb6, 0x67, 0x49, 0xc2, 0x76, 0xe3, - 0x18, 0x5d, 0x36, 0x80, 0xc0, 0xdd, 0x19, 0xd6, 0x5c, 0x11, 0xd3, 0x1a, 0xe1, 0xa9, 0x3d, 0x1c, - 0x5a, 0x2b, 0xc1, 0x0c, 0x53, 0xfe, 0x64, 0x48, 0x78, 0xdf, 0xb6, 0xcd, 0xdd, 0x3a, 0x6e, 0x60, - 0xdb, 0x93, 0x1d, 0x49, 0xc0, 0x64, 0x3d, 0x78, 0x22, 0xe5, 0x5c, 0x1b, 0xa3, 0xbd, 0x4c, 0xc3, - 0x9e, 0xd4, 0xe0, 0x39, 0x96, 0x66, 0x28, 0xc4, 0x57, 0x5f, 0x29, 0x60, 0x25, 0x6d, 0x5c, 0xe1, - 0x57, 0x7d, 0x68, 0xcf, 0x71, 0x58, 0xed, 0xe8, 0x34, 0xe8, 0x47, 0x05, 0x9c, 0xec, 0x47, 0x2e, - 0xf8, 0x04, 0x70, 0x46, 0x11, 0xd1, 0x81, 0x68, 0x02, 0x76, 0x84, 0x14, 0x49, 0x2d, 0xbc, 0x00, - 0xa6, 0x6a, 0xa6, 0x5d, 0x29, 0x93, 0xaf, 0x43, 0xb2, 0x1b, 0xf5, 0xe0, 0x5d, 0x29, 0x47, 0x91, - 0x05, 0xbc, 0x05, 0x16, 0x84, 0xdf, 0x06, 0xb6, 0xab, 0x5e, 0x4d, 0x14, 0x4b, 0x4c, 0x73, 0x2e, - 0x7e, 0x14, 0x76, 0xba, 0xf4, 0xa8, 0xc7, 0x43, 0xfd, 0x53, 0x01, 0xf0, 0xef, 0xbc, 0xf7, 0xe7, - 0x41, 0xde, 0x74, 0x89, 0xa0, 0x7d, 0xc1, 0x14, 0xe4, 0x8d, 0xd9, 0x76, 0xab, 0x94, 0x5f, 0xdb, - 0xbe, 0x17, 0x08, 0x51, 0xac, 0xe7, 0xc6, 0xe1, 0x43, 0x18, 0x3c, 0x78, 0xd2, 0x38, 0x0c, 0xcc, - 0x50, 0xac, 0x87, 0xd7, 0xc1, 0x8c, 0x55, 0xf7, 0x99, 0x87, 0x69, 0xd9, 0x72, 0x5c, 0x2c, 0xb6, - 0xc6, 0x94, 0x71, 0x52, 0xe6, 0x34, 0xb3, 0xde, 0xa1, 0x43, 0x09, 0x4b, 0xa8, 0x01, 0xc0, 0x5b, - 0x9e, 0xb9, 0x26, 0x8f, 0x93, 0x13, 0x71, 0xe6, 0xf8, 0x85, 0x6d, 0x45, 0x52, 0xd4, 0x61, 0xa1, - 0x3e, 0x07, 0xa7, 0xca, 0x98, 0x36, 0x89, 0x85, 0xd7, 0x2c, 0xcb, 0xf1, 0x6d, 0x2f, 0x24, 0xb0, - 0x3a, 0xc8, 0x47, 0x66, 0x72, 0x2a, 0x4e, 0xc8, 0xf8, 0xf9, 0x08, 0x0b, 0xc5, 0x36, 0xd1, 0x18, - 0x66, 0x06, 0x8e, 0xe1, 0xcf, 0x19, 0x30, 0x19, 0xc3, 0x67, 0xf7, 0x89, 0x5d, 0x91, 0xc8, 0xa7, - 0x43, 0xeb, 0x07, 0xc4, 0xae, 0xbc, 0x6b, 0x95, 0xa6, 0xa5, 0x19, 0xff, 0x44, 0xc2, 0x10, 0xde, - 0x07, 0x59, 0x9f, 0x61, 0x2a, 0x07, 0xec, 0x42, 0x6a, 0x37, 0x3f, 0x62, 0x98, 0x86, 0x0c, 0x68, - 0x8a, 0x43, 0x73, 0x01, 0x12, 0x18, 0x70, 0x0b, 0xe4, 0xaa, 0xfc, 0x56, 0xe4, 0xe6, 0xbf, 0x98, - 0x0a, 0xd6, 0x49, 0xed, 0x83, 0x46, 0x10, 0x12, 0x14, 0xc0, 0x40, 0x0a, 0xe6, 0x58, 0xa2, 0x88, - 0xe2, 0xc2, 0x46, 0x61, 0x34, 0x7d, 0x6b, 0x6f, 0xc0, 0x76, 0xab, 0x34, 0x97, 0x54, 0xa1, 0xae, - 0x08, 0xaa, 0x0e, 0xa6, 0x3b, 0x52, 0x4c, 0x5f, 0x82, 0xc6, 0xed, 0xc3, 0xa3, 0xe2, 0xd8, 0xeb, - 0xa3, 0xe2, 0xd8, 0x9b, 0xa3, 0xe2, 0xd8, 0x37, 0xed, 0xa2, 0x72, 0xd8, 0x2e, 0x2a, 0xaf, 0xdb, - 0x45, 0xe5, 0x4d, 0xbb, 0xa8, 0xbc, 0x6d, 0x17, 0x95, 0xef, 0x7e, 0x2d, 0x8e, 0x3d, 0x29, 0xa5, - 0xfc, 0xb7, 0xef, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x84, 0x5f, 0xef, 0x28, 0x14, 0x00, - 0x00, + // 1554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0x13, 0xc7, + 0x1b, 0xcf, 0x3a, 0x76, 0x12, 0x4f, 0x5e, 0x99, 0x10, 0xc5, 0xff, 0x20, 0xd9, 0x61, 0xff, 0x52, + 0xa1, 0x05, 0x76, 0x09, 0x05, 0x4a, 0x85, 0x2a, 0x94, 0x0d, 0x94, 0xb7, 0x24, 0x24, 0x13, 0xa0, + 0x2a, 0xa2, 0x12, 0x9b, 0xf5, 0xc4, 0x1e, 0x62, 0xef, 0x6e, 0x67, 0x76, 0x9d, 0xa6, 0xe2, 0x50, + 0xa9, 0x5f, 0xa0, 0x1f, 0x80, 0x63, 0x0f, 0x3d, 0xf7, 0x13, 0xf4, 0x18, 0x55, 0x3d, 0x70, 0xe4, + 0x64, 0x11, 0xf7, 0xda, 0x0f, 0xd0, 0x72, 0xa8, 0xaa, 0x99, 0x9d, 0xdd, 0xf5, 0xfa, 0x25, 0x6b, + 0x1a, 0x89, 0x53, 0x6f, 0xd9, 0xe7, 0xe5, 0xf7, 0xbc, 0xcc, 0xf3, 0xe6, 0x80, 0x3b, 0xbb, 0xd7, + 0x98, 0x46, 0x1c, 0x7d, 0xd7, 0xdf, 0xc6, 0xd4, 0xc6, 0x1e, 0x66, 0x7a, 0x03, 0xdb, 0x65, 0x87, + 0xea, 0x92, 0x61, 0xba, 0x44, 0xdf, 0xa9, 0x39, 0x7b, 0x96, 0x63, 0x7b, 0xd4, 0xa9, 0xe9, 0x8d, + 0x25, 0xb3, 0xe6, 0x56, 0xcd, 0x25, 0xbd, 0x82, 0x6d, 0x4c, 0x4d, 0x0f, 0x97, 0x35, 0x97, 0x3a, + 0x9e, 0x03, 0x4b, 0x81, 0x82, 0x66, 0xba, 0x44, 0x6b, 0x53, 0xd0, 0x42, 0x85, 0x85, 0x0b, 0x15, + 0xe2, 0x55, 0xfd, 0x6d, 0xcd, 0x72, 0xea, 0x7a, 0xc5, 0xa9, 0x38, 0xba, 0xd0, 0xdb, 0xf6, 0x77, + 0xc4, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x78, 0x0b, 0x97, 0x63, 0x07, 0xea, 0xa6, 0x55, 0x25, 0x36, + 0xa6, 0xfb, 0xba, 0xbb, 0x5b, 0xe1, 0x04, 0xa6, 0xd7, 0xb1, 0x67, 0xea, 0x8d, 0x2e, 0x2f, 0x16, + 0xf4, 0x7e, 0x5a, 0xd4, 0xb7, 0x3d, 0x52, 0xc7, 0x5d, 0x0a, 0x57, 0xd3, 0x14, 0x98, 0x55, 0xc5, + 0x75, 0xb3, 0x53, 0x4f, 0x7d, 0x02, 0xe6, 0x3f, 0xaf, 0x39, 0x7b, 0x37, 0x09, 0xf3, 0x88, 0x5d, + 0xf1, 0x09, 0xab, 0x62, 0xba, 0x86, 0xbd, 0xaa, 0x53, 0x86, 0x37, 0x40, 0xd6, 0xdb, 0x77, 0x71, + 0x41, 0x59, 0x54, 0xce, 0xe6, 0x8d, 0x73, 0x07, 0xcd, 0xd2, 0x50, 0xab, 0x59, 0xca, 0x3e, 0xdc, + 0x77, 0xf1, 0xdb, 0x66, 0xe9, 0x54, 0x1f, 0x35, 0xce, 0x46, 0x42, 0x51, 0x7d, 0x99, 0x01, 0x80, + 0x4b, 0x6d, 0x09, 0xd3, 0xf0, 0x19, 0x18, 0xe3, 0xe1, 0x96, 0x4d, 0xcf, 0x14, 0x98, 0xe3, 0x97, + 0x2e, 0x6a, 0x71, 0xb2, 0x23, 0xaf, 0x35, 0x77, 0xb7, 0xc2, 0x09, 0x4c, 0xe3, 0xd2, 0x5a, 0x63, + 0x49, 0x7b, 0xb0, 0xfd, 0x1c, 0x5b, 0xde, 0x1a, 0xf6, 0x4c, 0x03, 0x4a, 0x2f, 0x40, 0x4c, 0x43, + 0x11, 0x2a, 0xdc, 0x04, 0x59, 0xe6, 0x62, 0xab, 0x90, 0x11, 0xe8, 0xba, 0x96, 0xf2, 0x94, 0x5a, + 0xec, 0xdc, 0x96, 0x8b, 0x2d, 0x63, 0x22, 0x0c, 0x91, 0x7f, 0x21, 0x01, 0x05, 0xbf, 0x04, 0x23, + 0xcc, 0x33, 0x3d, 0x9f, 0x15, 0x86, 0x05, 0xe8, 0xd2, 0xbb, 0x80, 0x0a, 0x45, 0x63, 0x4a, 0xc2, + 0x8e, 0x04, 0xdf, 0x48, 0x02, 0xaa, 0xaf, 0x33, 0x60, 0x36, 0x16, 0x5e, 0x71, 0xec, 0x32, 0xf1, + 0x88, 0x63, 0xc3, 0xeb, 0x89, 0xbc, 0x9f, 0xe9, 0xc8, 0xfb, 0x7c, 0x0f, 0x95, 0x38, 0xe7, 0xf0, + 0xd3, 0xc8, 0xdf, 0x8c, 0x50, 0x3f, 0x9d, 0x34, 0xfe, 0xb6, 0x59, 0x9a, 0x8e, 0xd4, 0x92, 0xfe, + 0xc0, 0x06, 0x80, 0x35, 0x93, 0x79, 0x0f, 0xa9, 0x69, 0xb3, 0x00, 0x96, 0xd4, 0xb1, 0x0c, 0xfb, + 0xa3, 0xc1, 0x5e, 0x8a, 0x6b, 0x18, 0x0b, 0xd2, 0x24, 0x5c, 0xed, 0x42, 0x43, 0x3d, 0x2c, 0xc0, + 0x0f, 0xc0, 0x08, 0xc5, 0x26, 0x73, 0xec, 0x42, 0x56, 0xb8, 0x1c, 0xe5, 0x0b, 0x09, 0x2a, 0x92, + 0x5c, 0xf8, 0x21, 0x18, 0xad, 0x63, 0xc6, 0xcc, 0x0a, 0x2e, 0xe4, 0x84, 0xe0, 0xb4, 0x14, 0x1c, + 0x5d, 0x0b, 0xc8, 0x28, 0xe4, 0xab, 0xbf, 0x28, 0x60, 0x2a, 0xce, 0xd3, 0x2a, 0x61, 0x1e, 0x7c, + 0xda, 0x55, 0x7d, 0xda, 0x60, 0x31, 0x71, 0x6d, 0x51, 0x7b, 0x33, 0xd2, 0xdc, 0x58, 0x48, 0x69, + 0xab, 0xbc, 0x0d, 0x90, 0x23, 0x1e, 0xae, 0xf3, 0xac, 0x0f, 0x9f, 0x1d, 0xbf, 0x74, 0xee, 0x1d, + 0xaa, 0xc4, 0x98, 0x94, 0xb8, 0xb9, 0xbb, 0x1c, 0x01, 0x05, 0x40, 0xea, 0x1f, 0xc3, 0xed, 0x21, + 0xf0, 0x8a, 0x84, 0x3f, 0x29, 0x60, 0xc1, 0xa5, 0xc4, 0xa1, 0xc4, 0xdb, 0x5f, 0xc5, 0x0d, 0x5c, + 0x5b, 0x71, 0xec, 0x1d, 0x52, 0xf1, 0xa9, 0xc9, 0x73, 0x29, 0xa3, 0xba, 0x99, 0x6a, 0x7a, 0xa3, + 0x2f, 0x04, 0xc2, 0x3b, 0x98, 0x62, 0xdb, 0xc2, 0x86, 0x2a, 0x7d, 0x5a, 0x38, 0x42, 0xf8, 0x08, + 0x5f, 0xe0, 0x3d, 0x00, 0xeb, 0xa6, 0xc7, 0x73, 0x5a, 0xd9, 0xa0, 0xd8, 0xc2, 0x65, 0x8e, 0x2a, + 0x4a, 0x32, 0x17, 0xd7, 0xc7, 0x5a, 0x97, 0x04, 0xea, 0xa1, 0x05, 0xbf, 0x57, 0xc0, 0x6c, 0xb9, + 0x7b, 0xd0, 0xc8, 0xca, 0xbc, 0x36, 0x50, 0xaa, 0x7b, 0x0c, 0x2a, 0x63, 0xbe, 0xd5, 0x2c, 0xcd, + 0xf6, 0x60, 0xa0, 0x5e, 0xd6, 0xe0, 0x57, 0x20, 0x47, 0xfd, 0x1a, 0x66, 0x85, 0xac, 0x78, 0xe1, + 0x74, 0xb3, 0x1b, 0x4e, 0x8d, 0x58, 0xfb, 0x88, 0xeb, 0x7c, 0x41, 0xbc, 0xea, 0x96, 0x2f, 0x26, + 0x16, 0x8b, 0x9f, 0x5b, 0xb0, 0x50, 0x80, 0xaa, 0xbe, 0x00, 0x33, 0x9d, 0x83, 0x03, 0x56, 0x01, + 0xb0, 0xc2, 0x5e, 0x65, 0x05, 0x45, 0xd8, 0xbd, 0xfc, 0x0e, 0x95, 0x15, 0x35, 0x7a, 0x3c, 0x36, + 0x23, 0x12, 0x43, 0x6d, 0xd8, 0xea, 0x45, 0x30, 0x71, 0x9b, 0x3a, 0xbe, 0x2b, 0x9d, 0x84, 0x8b, + 0x20, 0x6b, 0x9b, 0xf5, 0x70, 0x04, 0x45, 0x73, 0x71, 0xdd, 0xac, 0x63, 0x24, 0x38, 0xea, 0x8f, + 0x0a, 0x98, 0x5c, 0x25, 0x75, 0xe2, 0x21, 0xcc, 0x5c, 0xc7, 0x66, 0x18, 0x5e, 0x49, 0x8c, 0xad, + 0xd3, 0x1d, 0x63, 0xeb, 0x44, 0x42, 0xb8, 0x6d, 0x60, 0x3d, 0x05, 0xa3, 0x5f, 0xfb, 0xd8, 0x27, + 0x76, 0x45, 0x8e, 0xed, 0x2b, 0xa9, 0x11, 0x6e, 0x06, 0xf2, 0x89, 0x8a, 0x33, 0xc6, 0xf9, 0x20, + 0x90, 0x1c, 0x14, 0x42, 0xaa, 0x7f, 0x67, 0xc0, 0x69, 0x61, 0x19, 0x97, 0xfb, 0x57, 0x32, 0x7c, + 0x0a, 0x0a, 0x26, 0x63, 0x3e, 0xc5, 0xe5, 0x15, 0xc7, 0xb6, 0x7c, 0xca, 0x7b, 0x60, 0x7f, 0xab, + 0x6a, 0x52, 0xcc, 0x44, 0x38, 0x39, 0x63, 0x51, 0x86, 0x53, 0x58, 0xee, 0x23, 0x87, 0xfa, 0x22, + 0xc0, 0x5d, 0x30, 0x59, 0x6b, 0x0f, 0x5e, 0xc6, 0xa9, 0xa5, 0xc6, 0x99, 0x48, 0x99, 0x31, 0x27, + 0x5d, 0x48, 0xa6, 0x1d, 0x25, 0xb1, 0xe1, 0x67, 0x60, 0xba, 0x86, 0xed, 0xb2, 0xb9, 0x5d, 0xc3, + 0x1b, 0x98, 0x5a, 0xd8, 0xf6, 0x44, 0x9f, 0xe4, 0x8c, 0xd9, 0x56, 0xb3, 0x34, 0xbd, 0x9a, 0x64, + 0xa1, 0x4e, 0x59, 0xf8, 0x00, 0xcc, 0x6d, 0x3b, 0x94, 0x3a, 0x7b, 0xc4, 0xae, 0x08, 0x3b, 0x21, + 0x48, 0x56, 0x80, 0xfc, 0xaf, 0xd5, 0x2c, 0xcd, 0x19, 0xbd, 0x04, 0x50, 0x6f, 0x3d, 0x75, 0x0f, + 0xcc, 0xad, 0xf3, 0xc1, 0xc2, 0x1c, 0x9f, 0x5a, 0x38, 0xee, 0x09, 0x58, 0x02, 0xb9, 0x06, 0xa6, + 0xdb, 0x41, 0x5d, 0xe7, 0x8d, 0x3c, 0xef, 0x88, 0xc7, 0x9c, 0x80, 0x02, 0x3a, 0x8f, 0xc4, 0x8e, + 0x35, 0x1f, 0xa1, 0x55, 0x56, 0x18, 0x11, 0xa2, 0x22, 0x92, 0xf5, 0x24, 0x0b, 0x75, 0xca, 0xaa, + 0x87, 0x19, 0x30, 0xdf, 0xa7, 0x05, 0xe1, 0x63, 0x30, 0xc6, 0xe4, 0xdf, 0xb2, 0xad, 0xce, 0xa6, + 0x3e, 0x86, 0x54, 0x8e, 0xb7, 0x40, 0x88, 0x86, 0x22, 0x2c, 0xe8, 0x82, 0x49, 0x2a, 0x7d, 0x10, + 0x46, 0xe5, 0x36, 0xf8, 0x38, 0x15, 0xbc, 0x3b, 0x3f, 0xf1, 0x73, 0xa3, 0x76, 0x44, 0x94, 0x34, + 0x00, 0x5f, 0x80, 0x99, 0xb6, 0xc0, 0x03, 0xa3, 0xc3, 0xc2, 0xe8, 0xd5, 0x54, 0xa3, 0x3d, 0xdf, + 0xc5, 0x28, 0x48, 0xbb, 0x33, 0xeb, 0x1d, 0xb8, 0xa8, 0xcb, 0x92, 0xfa, 0x5b, 0x06, 0x1c, 0xb1, + 0x20, 0xde, 0xc3, 0xc1, 0x67, 0x26, 0x0e, 0xbe, 0x1b, 0xc7, 0x58, 0x7d, 0x7d, 0x0f, 0x40, 0xd2, + 0x71, 0x00, 0x2e, 0x1f, 0xc7, 0xc8, 0xd1, 0x07, 0xe1, 0x9f, 0x19, 0xf0, 0xff, 0xfe, 0xca, 0xf1, + 0x81, 0x78, 0x3f, 0x31, 0x69, 0x3f, 0xe9, 0x98, 0xb4, 0x67, 0x06, 0x80, 0xf8, 0xef, 0x60, 0xec, + 0x38, 0x18, 0xdf, 0x28, 0xa0, 0xd8, 0x3f, 0x6f, 0xef, 0xe1, 0x80, 0x7c, 0x96, 0x3c, 0x20, 0xaf, + 0x1f, 0xa3, 0xca, 0xfa, 0x1c, 0x94, 0xb7, 0x8f, 0x2a, 0xae, 0xe8, 0xf2, 0x1b, 0x60, 0xf5, 0x1f, + 0x1c, 0x99, 0x2b, 0x71, 0xa9, 0xa6, 0xfc, 0x84, 0x49, 0x68, 0xdf, 0xb2, 0xf9, 0x02, 0xaa, 0xf3, + 0x1d, 0x12, 0x54, 0x24, 0x01, 0xa3, 0xb5, 0x60, 0x65, 0xcb, 0xbe, 0x36, 0x06, 0xdb, 0x94, 0x47, + 0xad, 0xf8, 0xe0, 0x3c, 0x90, 0x62, 0x28, 0xc4, 0x57, 0x5f, 0x2a, 0x60, 0x31, 0xad, 0x5d, 0xe1, + 0x37, 0x3d, 0xce, 0xb0, 0xe3, 0x5c, 0xd9, 0x83, 0x9f, 0x65, 0x3f, 0x2b, 0xe0, 0x64, 0xaf, 0x63, + 0x87, 0x77, 0x00, 0xbf, 0x70, 0xa2, 0xf3, 0x24, 0xea, 0x80, 0x4d, 0x41, 0x45, 0x92, 0x0b, 0xcf, + 0x83, 0xb1, 0xaa, 0x69, 0x97, 0xb7, 0xc8, 0xb7, 0xe1, 0xf1, 0x1d, 0xd5, 0xe0, 0x1d, 0x49, 0x47, + 0x91, 0x04, 0xbc, 0x09, 0x66, 0x84, 0xde, 0x2a, 0xb6, 0x2b, 0x5e, 0x55, 0x24, 0x4b, 0x1e, 0x0f, + 0xd1, 0x52, 0xd8, 0xec, 0xe0, 0xa3, 0x2e, 0x0d, 0xf5, 0x2f, 0x05, 0xc0, 0x7f, 0xb3, 0xef, 0xcf, + 0x81, 0xbc, 0xe9, 0x12, 0x71, 0x86, 0x06, 0x5d, 0x90, 0x37, 0x26, 0x5b, 0xcd, 0x52, 0x7e, 0x79, + 0xe3, 0x6e, 0x40, 0x44, 0x31, 0x9f, 0x0b, 0x87, 0x8b, 0x30, 0x58, 0x78, 0x52, 0x38, 0x34, 0xcc, + 0x50, 0xcc, 0x87, 0xd7, 0xc0, 0x84, 0x55, 0xf3, 0x99, 0x87, 0xe9, 0x96, 0xe5, 0xb8, 0x58, 0x4c, + 0x8d, 0x31, 0xe3, 0xa4, 0x8c, 0x69, 0x62, 0xa5, 0x8d, 0x87, 0x12, 0x92, 0x50, 0x03, 0x80, 0x97, + 0x3c, 0x73, 0x4d, 0x6e, 0x27, 0x27, 0xec, 0x4c, 0xf1, 0x07, 0x5b, 0x8f, 0xa8, 0xa8, 0x4d, 0x42, + 0x7d, 0x0e, 0xe6, 0xb6, 0x30, 0x6d, 0x10, 0x0b, 0x2f, 0x5b, 0x96, 0xe3, 0xdb, 0x5e, 0x78, 0x50, + 0xeb, 0x20, 0x1f, 0x89, 0xc9, 0xae, 0x38, 0x21, 0xed, 0xe7, 0x23, 0x2c, 0x14, 0xcb, 0x44, 0x6d, + 0x98, 0xe9, 0xdb, 0x86, 0xbf, 0x66, 0xc0, 0x68, 0x0c, 0x9f, 0xdd, 0x25, 0x76, 0x59, 0x22, 0x9f, + 0x0a, 0xa5, 0xef, 0x13, 0xbb, 0xfc, 0xb6, 0x59, 0x1a, 0x97, 0x62, 0xfc, 0x13, 0x09, 0x41, 0x78, + 0x0f, 0x64, 0x7d, 0x86, 0xa9, 0x6c, 0xb0, 0xf3, 0xa9, 0xd5, 0xfc, 0x88, 0x61, 0x1a, 0x5e, 0x40, + 0x63, 0x1c, 0x9a, 0x13, 0x90, 0xc0, 0x80, 0xeb, 0x20, 0x57, 0xe1, 0xaf, 0x22, 0x27, 0xff, 0x85, + 0x54, 0xb0, 0xf6, 0x9f, 0x1a, 0x41, 0x21, 0x08, 0x0a, 0x0a, 0x60, 0x20, 0x05, 0x53, 0x2c, 0x91, + 0x44, 0xf1, 0x60, 0x83, 0x5c, 0x34, 0x3d, 0x73, 0x6f, 0xc0, 0x56, 0xb3, 0x34, 0x95, 0x64, 0xa1, + 0x0e, 0x0b, 0xaa, 0x0e, 0xc6, 0xdb, 0x42, 0x4c, 0x1f, 0x82, 0xc6, 0xad, 0x83, 0xc3, 0xe2, 0xd0, + 0xab, 0xc3, 0xe2, 0xd0, 0xeb, 0xc3, 0xe2, 0xd0, 0x77, 0xad, 0xa2, 0x72, 0xd0, 0x2a, 0x2a, 0xaf, + 0x5a, 0x45, 0xe5, 0x75, 0xab, 0xa8, 0xbc, 0x69, 0x15, 0x95, 0x1f, 0x7e, 0x2f, 0x0e, 0x3d, 0x29, + 0xa5, 0xfc, 0xf7, 0xf1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x2e, 0x29, 0x16, 0xb8, 0x14, + 0x00, 0x00, } func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) { @@ -1155,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i _ = i var l int _ = l + if m.BorrowingLimitPercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent)) + i-- + dAtA[i] = 0x20 + } + if m.LendablePercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent)) + i-- + dAtA[i] = 0x18 + } { size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1904,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) { n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares)) l = m.LimitResponse.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.LendablePercent != nil { + n += 1 + sovGenerated(uint64(*m.LendablePercent)) + } + if m.BorrowingLimitPercent != nil { + n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent)) + } return n } @@ -2259,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string { s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`, `AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`, `LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`, + `LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`, + `BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`, `}`, }, "") return s @@ -3543,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LendablePercent = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BorrowingLimitPercent = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.proto b/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.proto index 347c9d3fa01..69ca79ad2fc 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/generated.proto @@ -153,8 +153,8 @@ message LimitResponse { // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? message LimitedPriorityLevelConfiguration { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration { // `limitResponse` indicates what to do with requests that can not be executed right now optional LimitResponse limitResponse = 2; + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + optional int32 lendablePercent = 3; + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + optional int32 borrowingLimitPercent = 4; } // NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/types.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/types.go index 5af677e2f53..ebf665bcc3b 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/types.go @@ -63,7 +63,7 @@ const ( // +k8s:prerelease-lifecycle-gen:introduced=1.18 // +k8s:prerelease-lifecycle-gen:deprecated=1.20 // +k8s:prerelease-lifecycle-gen:removed=1.21 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,FlowSchema +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchema // FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with // similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher". @@ -87,7 +87,7 @@ type FlowSchema struct { // +k8s:prerelease-lifecycle-gen:introduced=1.18 // +k8s:prerelease-lifecycle-gen:deprecated=1.20 // +k8s:prerelease-lifecycle-gen:removed=1.21 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,FlowSchemaList +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchemaList // FlowSchemaList is a list of FlowSchema objects. type FlowSchemaList struct { @@ -344,7 +344,7 @@ type FlowSchemaConditionType string // +k8s:prerelease-lifecycle-gen:introduced=1.18 // +k8s:prerelease-lifecycle-gen:deprecated=1.20 // +k8s:prerelease-lifecycle-gen:removed=1.21 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,PriorityLevelConfiguration +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfiguration // PriorityLevelConfiguration represents the configuration of a priority level. type PriorityLevelConfiguration struct { @@ -367,7 +367,7 @@ type PriorityLevelConfiguration struct { // +k8s:prerelease-lifecycle-gen:introduced=1.18 // +k8s:prerelease-lifecycle-gen:deprecated=1.20 // +k8s:prerelease-lifecycle-gen:removed=1.21 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,PriorityLevelConfigurationList +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfigurationList // PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects. type PriorityLevelConfigurationList struct { @@ -415,8 +415,8 @@ const ( // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? type LimitedPriorityLevelConfiguration struct { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -438,6 +438,35 @@ type LimitedPriorityLevelConfiguration struct { // `limitResponse` indicates what to do with requests that can not be executed right now LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"` + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"` + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"` } // LimitResponse defines how to handle requests that can not be executed right now. diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go index 1827be02d7e..c95999fa5e0 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ @@ -111,9 +111,11 @@ func (LimitResponse) SwaggerDoc() map[string]string { } var map_LimitedPriorityLevelConfiguration = map[string]string{ - "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n * How are requests for this priority level limited?\n * What should be done with requests that exceed the limit?", + "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?", "assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ", "limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now", + "lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )", + "borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.", } func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.deepcopy.go index 7f73f46061f..e0272804f45 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.deepcopy.go @@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse { func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) { *out = *in in.LimitResponse.DeepCopyInto(&out.LimitResponse) + if in.LendablePercent != nil { + in, out := &in.LendablePercent, &out.LendablePercent + *out = new(int32) + **out = **in + } + if in.BorrowingLimitPercent != nil { + in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent + *out = new(int32) + **out = **in + } return } diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.prerelease-lifecycle.go index 2260141609c..2b6a3d3fd96 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -40,7 +40,7 @@ func (in *FlowSchema) APILifecycleDeprecated() (major, minor int) { // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *FlowSchema) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchema"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchema"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -64,7 +64,7 @@ func (in *FlowSchemaList) APILifecycleDeprecated() (major, minor int) { // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *FlowSchemaList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchemaList"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchemaList"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -88,7 +88,7 @@ func (in *PriorityLevelConfiguration) APILifecycleDeprecated() (major, minor int // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *PriorityLevelConfiguration) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfiguration"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -112,7 +112,7 @@ func (in *PriorityLevelConfigurationList) APILifecycleDeprecated() (major, minor // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *PriorityLevelConfigurationList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfigurationList"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfigurationList"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.pb.go index e1d17b5b802..fbaea85dd6b 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.pb.go @@ -689,101 +689,105 @@ func init() { } var fileDescriptor_80171c2a4e3669de = []byte{ - // 1496 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcb, 0x73, 0xdb, 0x44, - 0x18, 0x8f, 0x1c, 0x3b, 0x89, 0xbf, 0x3c, 0xbb, 0x69, 0x27, 0x9e, 0x74, 0xc6, 0x4e, 0xc5, 0x0c, - 0x05, 0xda, 0xca, 0x6d, 0x69, 0x69, 0x81, 0xe1, 0x11, 0xa5, 0x50, 0x4a, 0x93, 0x34, 0xdd, 0xb4, - 0xc0, 0x94, 0xce, 0x50, 0x59, 0xde, 0xd8, 0x6a, 0x6c, 0x49, 0xd5, 0xae, 0x9c, 0x09, 0xbd, 0x30, - 0xfc, 0x05, 0x9c, 0xe1, 0xc8, 0x81, 0x3b, 0xff, 0x00, 0x47, 0x3a, 0x9c, 0x7a, 0xec, 0xc9, 0x50, - 0x73, 0xe2, 0xc0, 0x1d, 0x7a, 0x62, 0x76, 0xb5, 0x92, 0x2c, 0xbf, 0xe4, 0x69, 0x67, 0x7a, 0xe2, - 0x66, 0x7d, 0x8f, 0xdf, 0xf7, 0xd8, 0xdf, 0x7e, 0xfb, 0x25, 0x70, 0x75, 0xff, 0x32, 0xd5, 0x2c, - 0xa7, 0xbc, 0xef, 0x57, 0x88, 0x67, 0x13, 0x46, 0x68, 0xb9, 0x45, 0xec, 0xaa, 0xe3, 0x95, 0xa5, - 0xc2, 0x70, 0xad, 0xf2, 0x5e, 0xc3, 0x39, 0x30, 0x1d, 0x9b, 0x79, 0x4e, 0xa3, 0xdc, 0x3a, 0x57, - 0x21, 0xcc, 0x38, 0x57, 0xae, 0x11, 0x9b, 0x78, 0x06, 0x23, 0x55, 0xcd, 0xf5, 0x1c, 0xe6, 0xa0, - 0x62, 0x60, 0xaf, 0x19, 0xae, 0xa5, 0x75, 0xd9, 0x6b, 0xd2, 0x7e, 0xf5, 0x4c, 0xcd, 0x62, 0x75, - 0xbf, 0xa2, 0x99, 0x4e, 0xb3, 0x5c, 0x73, 0x6a, 0x4e, 0x59, 0xb8, 0x55, 0xfc, 0x3d, 0xf1, 0x25, - 0x3e, 0xc4, 0xaf, 0x00, 0x6e, 0xf5, 0x42, 0x1c, 0xbe, 0x69, 0x98, 0x75, 0xcb, 0x26, 0xde, 0x61, - 0xd9, 0xdd, 0xaf, 0x71, 0x01, 0x2d, 0x37, 0x09, 0x33, 0xca, 0xad, 0xbe, 0x24, 0x56, 0xcb, 0xc3, - 0xbc, 0x3c, 0xdf, 0x66, 0x56, 0x93, 0xf4, 0x39, 0xbc, 0x95, 0xe6, 0x40, 0xcd, 0x3a, 0x69, 0x1a, - 0xbd, 0x7e, 0xea, 0x1d, 0x58, 0xf9, 0xb8, 0xe1, 0x1c, 0x5c, 0xb1, 0x28, 0xb3, 0xec, 0x9a, 0x6f, - 0xd1, 0x3a, 0xf1, 0xb6, 0x08, 0xab, 0x3b, 0x55, 0xf4, 0x01, 0x64, 0xd9, 0xa1, 0x4b, 0x0a, 0xca, - 0x9a, 0xf2, 0x5a, 0x5e, 0x3f, 0xf5, 0xa8, 0x5d, 0x9a, 0xe8, 0xb4, 0x4b, 0xd9, 0x5b, 0x87, 0x2e, - 0x79, 0xd6, 0x2e, 0x1d, 0x1f, 0xe2, 0xc6, 0xd5, 0x58, 0x38, 0xaa, 0xdf, 0x67, 0x00, 0xb8, 0xd5, - 0xae, 0x08, 0x8d, 0xee, 0xc1, 0x0c, 0x2f, 0xb7, 0x6a, 0x30, 0x43, 0x60, 0xce, 0x9e, 0x3f, 0xab, - 0xc5, 0xbd, 0x8e, 0xb2, 0xd6, 0xdc, 0xfd, 0x1a, 0x17, 0x50, 0x8d, 0x5b, 0x6b, 0xad, 0x73, 0xda, - 0x8d, 0xca, 0x7d, 0x62, 0xb2, 0x2d, 0xc2, 0x0c, 0x1d, 0xc9, 0x2c, 0x20, 0x96, 0xe1, 0x08, 0x15, - 0xed, 0x40, 0x96, 0xba, 0xc4, 0x2c, 0x64, 0x04, 0xba, 0xa6, 0x8d, 0x3e, 0x49, 0x2d, 0xce, 0x6d, - 0xd7, 0x25, 0xa6, 0x3e, 0x17, 0x56, 0xc8, 0xbf, 0xb0, 0x40, 0x42, 0x5f, 0xc0, 0x14, 0x65, 0x06, - 0xf3, 0x69, 0x61, 0xb2, 0x2f, 0xe3, 0x34, 0x4c, 0xe1, 0xa7, 0x2f, 0x48, 0xd4, 0xa9, 0xe0, 0x1b, - 0x4b, 0x3c, 0xf5, 0x49, 0x06, 0x96, 0x63, 0xe3, 0x0d, 0xc7, 0xae, 0x5a, 0xcc, 0x72, 0x6c, 0xf4, - 0x6e, 0xa2, 0xeb, 0x27, 0x7b, 0xba, 0xbe, 0x32, 0xc0, 0x25, 0xee, 0x38, 0x7a, 0x3b, 0x4a, 0x37, - 0x23, 0xdc, 0x4f, 0x24, 0x83, 0x3f, 0x6b, 0x97, 0x16, 0x23, 0xb7, 0x64, 0x3e, 0xa8, 0x05, 0xa8, - 0x61, 0x50, 0x76, 0xcb, 0x33, 0x6c, 0x1a, 0xc0, 0x5a, 0x4d, 0x22, 0xab, 0x7e, 0x63, 0xbc, 0x73, - 0xe2, 0x1e, 0xfa, 0xaa, 0x0c, 0x89, 0x36, 0xfb, 0xd0, 0xf0, 0x80, 0x08, 0xe8, 0x55, 0x98, 0xf2, - 0x88, 0x41, 0x1d, 0xbb, 0x90, 0x15, 0x29, 0x47, 0xfd, 0xc2, 0x42, 0x8a, 0xa5, 0x16, 0xbd, 0x0e, - 0xd3, 0x4d, 0x42, 0xa9, 0x51, 0x23, 0x85, 0x9c, 0x30, 0x5c, 0x94, 0x86, 0xd3, 0x5b, 0x81, 0x18, - 0x87, 0x7a, 0xf5, 0x17, 0x05, 0x16, 0xe2, 0x3e, 0x6d, 0x5a, 0x94, 0xa1, 0xbb, 0x7d, 0xdc, 0xd3, - 0xc6, 0xab, 0x89, 0x7b, 0x0b, 0xe6, 0x2d, 0xc9, 0x70, 0x33, 0xa1, 0xa4, 0x8b, 0x77, 0x37, 0x20, - 0x67, 0x31, 0xd2, 0xe4, 0x5d, 0x9f, 0xec, 0x69, 0x57, 0x0a, 0x49, 0xf4, 0x79, 0x09, 0x9b, 0xbb, - 0xc6, 0x01, 0x70, 0x80, 0xa3, 0xfe, 0x35, 0xd9, 0x5d, 0x01, 0xe7, 0x23, 0xfa, 0x49, 0x81, 0x55, - 0xd7, 0xb3, 0x1c, 0xcf, 0x62, 0x87, 0x9b, 0xa4, 0x45, 0x1a, 0x1b, 0x8e, 0xbd, 0x67, 0xd5, 0x7c, - 0xcf, 0xe0, 0xad, 0x94, 0x45, 0x6d, 0xa4, 0x45, 0xde, 0x19, 0x8a, 0x80, 0xc9, 0x1e, 0xf1, 0x88, - 0x6d, 0x12, 0x5d, 0x95, 0x29, 0xad, 0x8e, 0x30, 0x1e, 0x91, 0x0a, 0xfa, 0x14, 0x50, 0xd3, 0x60, - 0xbc, 0xa3, 0xb5, 0x1d, 0x8f, 0x98, 0xa4, 0xca, 0x51, 0x05, 0x21, 0x73, 0x31, 0x3b, 0xb6, 0xfa, - 0x2c, 0xf0, 0x00, 0x2f, 0xf4, 0xad, 0x02, 0xcb, 0xd5, 0xfe, 0x21, 0x23, 0x79, 0x79, 0x69, 0x9c, - 0x46, 0x0f, 0x98, 0x51, 0xfa, 0x4a, 0xa7, 0x5d, 0x5a, 0x1e, 0xa0, 0xc0, 0x83, 0x82, 0xa1, 0xbb, - 0x90, 0xf3, 0xfc, 0x06, 0xa1, 0x85, 0xac, 0x38, 0xde, 0xd4, 0xa8, 0x3b, 0x4e, 0xc3, 0x32, 0x0f, - 0x31, 0x77, 0xf9, 0xdc, 0x62, 0xf5, 0x5d, 0x5f, 0xcc, 0x2a, 0x1a, 0x9f, 0xb5, 0x50, 0xe1, 0x00, - 0x54, 0x7d, 0x08, 0x4b, 0xbd, 0x43, 0x03, 0xd5, 0x00, 0xcc, 0xf0, 0x9e, 0xd2, 0x82, 0x22, 0xc2, - 0xbe, 0x39, 0x3e, 0xab, 0xa2, 0x3b, 0x1e, 0xcf, 0xcb, 0x48, 0x44, 0x71, 0x17, 0xb4, 0x7a, 0x16, - 0xe6, 0xae, 0x7a, 0x8e, 0xef, 0xca, 0x1c, 0xd1, 0x1a, 0x64, 0x6d, 0xa3, 0x19, 0x4e, 0x9f, 0x68, - 0x22, 0x6e, 0x1b, 0x4d, 0x82, 0x85, 0x46, 0xfd, 0x51, 0x81, 0xf9, 0x4d, 0xab, 0x69, 0x31, 0x4c, - 0xa8, 0xeb, 0xd8, 0x94, 0xa0, 0x8b, 0x89, 0x89, 0x75, 0xa2, 0x67, 0x62, 0x1d, 0x49, 0x18, 0x77, - 0xcd, 0xaa, 0x2f, 0x61, 0xfa, 0x81, 0x4f, 0x7c, 0xcb, 0xae, 0xc9, 0x79, 0x7d, 0x21, 0xad, 0xc0, - 0x9b, 0x81, 0x79, 0x82, 0x6d, 0xfa, 0x2c, 0x1f, 0x01, 0x52, 0x83, 0x43, 0x44, 0xf5, 0x6f, 0x05, - 0x4e, 0x88, 0xc0, 0xa4, 0x3a, 0x9c, 0xc5, 0xe8, 0x2e, 0x14, 0x0c, 0x4a, 0x7d, 0x8f, 0x54, 0x37, - 0x1c, 0xdb, 0xf4, 0x3d, 0xce, 0xff, 0xc3, 0xdd, 0xba, 0xe1, 0x11, 0x2a, 0xaa, 0xc9, 0xe9, 0x6b, - 0xb2, 0x9a, 0xc2, 0xfa, 0x10, 0x3b, 0x3c, 0x14, 0x01, 0xdd, 0x87, 0xf9, 0x46, 0x77, 0xed, 0xb2, - 0xcc, 0x33, 0x69, 0x65, 0x26, 0x1a, 0xa6, 0x1f, 0x93, 0x19, 0x24, 0x9b, 0x8e, 0x93, 0xd0, 0xea, - 0x01, 0x1c, 0xdb, 0xe6, 0x77, 0x98, 0x3a, 0xbe, 0x67, 0x92, 0x98, 0x80, 0xa8, 0x04, 0xb9, 0x16, - 0xf1, 0x2a, 0x01, 0x89, 0xf2, 0x7a, 0x9e, 0xd3, 0xef, 0x33, 0x2e, 0xc0, 0x81, 0x1c, 0xbd, 0x07, - 0x8b, 0x76, 0xec, 0x79, 0x1b, 0x6f, 0xd2, 0xc2, 0x94, 0x30, 0x5d, 0xee, 0xb4, 0x4b, 0x8b, 0xdb, - 0x49, 0x15, 0xee, 0xb5, 0x55, 0xdb, 0x19, 0x58, 0x19, 0xc2, 0x77, 0x74, 0x1b, 0x66, 0xa8, 0xfc, - 0x2d, 0x39, 0x7c, 0x32, 0xad, 0x76, 0xe9, 0x1b, 0x4f, 0xdb, 0x10, 0x0c, 0x47, 0x50, 0xc8, 0x81, - 0x79, 0x4f, 0xa6, 0x20, 0x62, 0xca, 0xa9, 0x7b, 0x3e, 0x0d, 0xbb, 0xbf, 0x3b, 0x71, 0x73, 0x71, - 0x37, 0x20, 0x4e, 0xe2, 0xa3, 0x87, 0xb0, 0xd4, 0x55, 0x76, 0x10, 0x73, 0x52, 0xc4, 0xbc, 0x98, - 0x16, 0x73, 0xe0, 0xa1, 0xe8, 0x05, 0x19, 0x76, 0x69, 0xbb, 0x07, 0x16, 0xf7, 0x05, 0x52, 0x7f, - 0xcb, 0xc0, 0x88, 0x41, 0xfc, 0x12, 0x96, 0xaa, 0x7b, 0x89, 0xa5, 0xea, 0xfd, 0xe7, 0x7f, 0x61, - 0x86, 0x2e, 0x59, 0xf5, 0x9e, 0x25, 0xeb, 0xc3, 0x17, 0x88, 0x31, 0x7a, 0xe9, 0xfa, 0x27, 0x03, - 0xaf, 0x0c, 0x77, 0x8e, 0x97, 0xb0, 0xeb, 0x89, 0x91, 0x76, 0xa9, 0x67, 0xa4, 0x9d, 0x1c, 0x03, - 0xe2, 0xff, 0xa5, 0xac, 0x67, 0x29, 0xfb, 0x5d, 0x81, 0xe2, 0xf0, 0xbe, 0xbd, 0x84, 0x25, 0xed, - 0xab, 0xe4, 0x92, 0xf6, 0xce, 0xf3, 0x93, 0x6c, 0xc8, 0xd2, 0x76, 0x75, 0x14, 0xb7, 0xa2, 0xf5, - 0x6a, 0x8c, 0x27, 0xf6, 0xd7, 0x91, 0xad, 0x12, 0xdb, 0x60, 0xca, 0x5f, 0x09, 0x09, 0xef, 0x8f, - 0x6c, 0xa3, 0xd2, 0x20, 0x4d, 0x62, 0x33, 0x49, 0xc8, 0x3a, 0x4c, 0x37, 0x82, 0xb7, 0x51, 0x5e, - 0xea, 0xf5, 0xb1, 0x9e, 0xa4, 0x51, 0x4f, 0x69, 0xf0, 0x0c, 0x4b, 0x33, 0x1c, 0xc2, 0xab, 0x3f, - 0x28, 0xb0, 0x96, 0x76, 0x59, 0xd1, 0xc1, 0x80, 0x65, 0xe7, 0x05, 0x16, 0xd9, 0xf1, 0x97, 0x9f, - 0x9f, 0x15, 0x38, 0x3a, 0x68, 0xa7, 0xe0, 0xf4, 0xe7, 0x8b, 0x44, 0xb4, 0x05, 0x44, 0xf4, 0xbf, - 0x29, 0xa4, 0x58, 0x6a, 0xd1, 0x69, 0x98, 0xa9, 0x1b, 0x76, 0x75, 0xd7, 0xfa, 0x3a, 0xdc, 0x6f, - 0x23, 0x02, 0x7e, 0x22, 0xe5, 0x38, 0xb2, 0x40, 0x57, 0x60, 0x49, 0xf8, 0x6d, 0x12, 0xbb, 0xc6, - 0xea, 0xa2, 0x57, 0xe2, 0x2a, 0xe7, 0xe2, 0xf7, 0xe0, 0x66, 0x8f, 0x1e, 0xf7, 0x79, 0xa8, 0xff, - 0x2a, 0x80, 0x9e, 0xe7, 0x9d, 0x3f, 0x05, 0x79, 0xc3, 0xb5, 0xc4, 0xb2, 0x17, 0x5c, 0x81, 0xbc, - 0x3e, 0xdf, 0x69, 0x97, 0xf2, 0xeb, 0x3b, 0xd7, 0x02, 0x21, 0x8e, 0xf5, 0xdc, 0x38, 0x7c, 0x02, - 0x83, 0xa7, 0x4e, 0x1a, 0x87, 0x81, 0x29, 0x8e, 0xf5, 0xe8, 0x32, 0xcc, 0x99, 0x0d, 0x9f, 0x32, - 0xe2, 0xed, 0x9a, 0x8e, 0x4b, 0xc4, 0xc8, 0x98, 0xd1, 0x8f, 0xca, 0x9a, 0xe6, 0x36, 0xba, 0x74, - 0x38, 0x61, 0x89, 0x34, 0x00, 0x4e, 0x78, 0xea, 0x1a, 0x3c, 0x4e, 0x4e, 0xc4, 0x59, 0xe0, 0x07, - 0xb6, 0x1d, 0x49, 0x71, 0x97, 0x85, 0x7a, 0x1f, 0x8e, 0xed, 0x12, 0xaf, 0x65, 0x99, 0x64, 0xdd, - 0x34, 0x1d, 0xdf, 0x66, 0xe1, 0xda, 0x5a, 0x86, 0x7c, 0x64, 0x26, 0xef, 0xc4, 0x11, 0x19, 0x3f, - 0x1f, 0x61, 0xe1, 0xd8, 0x26, 0xba, 0x84, 0x99, 0xe1, 0x97, 0x30, 0x03, 0xd3, 0x31, 0x7c, 0x76, - 0xdf, 0xb2, 0xab, 0x12, 0xf9, 0x78, 0x68, 0x7d, 0xdd, 0xb2, 0xab, 0xcf, 0xda, 0xa5, 0x59, 0x69, - 0xc6, 0x3f, 0xb1, 0x30, 0x44, 0xd7, 0x20, 0xeb, 0x53, 0xe2, 0xc9, 0xeb, 0x75, 0x2a, 0x8d, 0xcc, - 0xb7, 0x29, 0xf1, 0xc2, 0xcd, 0x67, 0x86, 0x23, 0x73, 0x01, 0x16, 0x10, 0x68, 0x0b, 0x72, 0x35, - 0x7e, 0x28, 0x72, 0xea, 0x9f, 0x4e, 0xc3, 0xea, 0x5e, 0xe7, 0x03, 0x1a, 0x08, 0x09, 0x0e, 0x50, - 0xd0, 0x03, 0x58, 0xa0, 0x89, 0x16, 0x8a, 0xe3, 0x1a, 0x63, 0x93, 0x19, 0xd8, 0x78, 0x1d, 0x75, - 0xda, 0xa5, 0x85, 0xa4, 0x0a, 0xf7, 0x04, 0x50, 0xcb, 0x30, 0xdb, 0x55, 0x60, 0xfa, 0xfc, 0xd3, - 0xaf, 0x3c, 0x7a, 0x5a, 0x9c, 0x78, 0xfc, 0xb4, 0x38, 0xf1, 0xe4, 0x69, 0x71, 0xe2, 0x9b, 0x4e, - 0x51, 0x79, 0xd4, 0x29, 0x2a, 0x8f, 0x3b, 0x45, 0xe5, 0x49, 0xa7, 0xa8, 0xfc, 0xd1, 0x29, 0x2a, - 0xdf, 0xfd, 0x59, 0x9c, 0xb8, 0x53, 0x1c, 0xfd, 0x7f, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, - 0x27, 0x1b, 0xb7, 0xd8, 0x11, 0x14, 0x00, 0x00, + // 1553 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4f, 0x6f, 0xdb, 0xc6, + 0x12, 0x37, 0x65, 0xc9, 0xb6, 0xc6, 0x7f, 0xb3, 0x8e, 0x61, 0x3d, 0x07, 0x90, 0x1c, 0x3e, 0xe0, + 0xe5, 0xbd, 0x97, 0x84, 0x4a, 0xd2, 0xa4, 0x49, 0x5b, 0xf4, 0x8f, 0xe9, 0xb4, 0x69, 0x1a, 0xdb, + 0x71, 0xd6, 0x49, 0x5b, 0xa4, 0x01, 0x1a, 0x8a, 0x5a, 0x4b, 0x8c, 0x25, 0x92, 0xd9, 0x25, 0x65, + 0xb8, 0xb9, 0x14, 0xfd, 0x04, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x17, 0xe8, 0xb1, 0x41, 0x4f, + 0x39, 0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xdf, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xf5, + 0x8f, 0x42, 0x02, 0xe4, 0xd4, 0x9b, 0x39, 0xf3, 0x9b, 0xdf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c, + 0xd7, 0x0e, 0xae, 0x30, 0xcd, 0x72, 0xca, 0x07, 0x7e, 0x85, 0x50, 0x9b, 0x78, 0x84, 0x95, 0x5b, + 0xc4, 0xae, 0x3a, 0xb4, 0x2c, 0x15, 0x86, 0x6b, 0x95, 0xf7, 0x1b, 0xce, 0xa1, 0xe9, 0xd8, 0x1e, + 0x75, 0x1a, 0xe5, 0xd6, 0xf9, 0x0a, 0xf1, 0x8c, 0xf3, 0xe5, 0x1a, 0xb1, 0x09, 0x35, 0x3c, 0x52, + 0xd5, 0x5c, 0xea, 0x78, 0x0e, 0x2a, 0x06, 0x78, 0xcd, 0x70, 0x2d, 0xad, 0x0b, 0xaf, 0x49, 0xfc, + 0xda, 0xd9, 0x9a, 0xe5, 0xd5, 0xfd, 0x8a, 0x66, 0x3a, 0xcd, 0x72, 0xcd, 0xa9, 0x39, 0x65, 0x61, + 0x56, 0xf1, 0xf7, 0xc5, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x74, 0x6b, 0x17, 0x63, 0xf7, 0x4d, 0xc3, + 0xac, 0x5b, 0x36, 0xa1, 0x47, 0x65, 0xf7, 0xa0, 0xc6, 0x05, 0xac, 0xdc, 0x24, 0x9e, 0x51, 0x6e, + 0xf5, 0x1d, 0x62, 0xad, 0x3c, 0xcc, 0x8a, 0xfa, 0xb6, 0x67, 0x35, 0x49, 0x9f, 0xc1, 0xeb, 0x69, + 0x06, 0xcc, 0xac, 0x93, 0xa6, 0xd1, 0x6b, 0xa7, 0xde, 0x85, 0xd5, 0x0f, 0x1a, 0xce, 0xe1, 0x55, + 0x8b, 0x79, 0x96, 0x5d, 0xf3, 0x2d, 0x56, 0x27, 0x74, 0x9b, 0x78, 0x75, 0xa7, 0x8a, 0xde, 0x85, + 0xac, 0x77, 0xe4, 0x92, 0x82, 0xb2, 0xae, 0xfc, 0x37, 0xaf, 0x9f, 0x7e, 0xdc, 0x2e, 0x4d, 0x74, + 0xda, 0xa5, 0xec, 0xed, 0x23, 0x97, 0x3c, 0x6f, 0x97, 0x4e, 0x0c, 0x31, 0xe3, 0x6a, 0x2c, 0x0c, + 0xd5, 0x6f, 0x32, 0x00, 0x1c, 0xb5, 0x27, 0x5c, 0xa3, 0xfb, 0x30, 0xc3, 0xc3, 0xad, 0x1a, 0x9e, + 0x21, 0x38, 0x67, 0x2f, 0x9c, 0xd3, 0xe2, 0x5c, 0x47, 0xa7, 0xd6, 0xdc, 0x83, 0x1a, 0x17, 0x30, + 0x8d, 0xa3, 0xb5, 0xd6, 0x79, 0xed, 0x66, 0xe5, 0x01, 0x31, 0xbd, 0x6d, 0xe2, 0x19, 0x3a, 0x92, + 0xa7, 0x80, 0x58, 0x86, 0x23, 0x56, 0xb4, 0x0b, 0x59, 0xe6, 0x12, 0xb3, 0x90, 0x11, 0xec, 0x9a, + 0x36, 0xfa, 0x26, 0xb5, 0xf8, 0x6c, 0x7b, 0x2e, 0x31, 0xf5, 0xb9, 0x30, 0x42, 0xfe, 0x85, 0x05, + 0x13, 0xfa, 0x14, 0xa6, 0x98, 0x67, 0x78, 0x3e, 0x2b, 0x4c, 0xf6, 0x9d, 0x38, 0x8d, 0x53, 0xd8, + 0xe9, 0x0b, 0x92, 0x75, 0x2a, 0xf8, 0xc6, 0x92, 0x4f, 0x7d, 0x9a, 0x81, 0xe5, 0x18, 0xbc, 0xe9, + 0xd8, 0x55, 0xcb, 0xb3, 0x1c, 0x1b, 0xbd, 0x95, 0xc8, 0xfa, 0xa9, 0x9e, 0xac, 0xaf, 0x0e, 0x30, + 0x89, 0x33, 0x8e, 0xde, 0x88, 0x8e, 0x9b, 0x11, 0xe6, 0x27, 0x93, 0xce, 0x9f, 0xb7, 0x4b, 0x8b, + 0x91, 0x59, 0xf2, 0x3c, 0xa8, 0x05, 0xa8, 0x61, 0x30, 0xef, 0x36, 0x35, 0x6c, 0x16, 0xd0, 0x5a, + 0x4d, 0x22, 0xa3, 0xfe, 0xff, 0x78, 0xf7, 0xc4, 0x2d, 0xf4, 0x35, 0xe9, 0x12, 0x6d, 0xf5, 0xb1, + 0xe1, 0x01, 0x1e, 0xd0, 0x7f, 0x60, 0x8a, 0x12, 0x83, 0x39, 0x76, 0x21, 0x2b, 0x8e, 0x1c, 0xe5, + 0x0b, 0x0b, 0x29, 0x96, 0x5a, 0xf4, 0x3f, 0x98, 0x6e, 0x12, 0xc6, 0x8c, 0x1a, 0x29, 0xe4, 0x04, + 0x70, 0x51, 0x02, 0xa7, 0xb7, 0x03, 0x31, 0x0e, 0xf5, 0xea, 0x8f, 0x0a, 0x2c, 0xc4, 0x79, 0xda, + 0xb2, 0x98, 0x87, 0xee, 0xf5, 0xd5, 0x9e, 0x36, 0x5e, 0x4c, 0xdc, 0x5a, 0x54, 0xde, 0x92, 0x74, + 0x37, 0x13, 0x4a, 0xba, 0xea, 0xee, 0x26, 0xe4, 0x2c, 0x8f, 0x34, 0x79, 0xd6, 0x27, 0x7b, 0xd2, + 0x95, 0x52, 0x24, 0xfa, 0xbc, 0xa4, 0xcd, 0x5d, 0xe7, 0x04, 0x38, 0xe0, 0x51, 0x7f, 0x9f, 0xec, + 0x8e, 0x80, 0xd7, 0x23, 0xfa, 0x5e, 0x81, 0x35, 0x97, 0x5a, 0x0e, 0xb5, 0xbc, 0xa3, 0x2d, 0xd2, + 0x22, 0x8d, 0x4d, 0xc7, 0xde, 0xb7, 0x6a, 0x3e, 0x35, 0x78, 0x2a, 0x65, 0x50, 0x9b, 0x69, 0x9e, + 0x77, 0x87, 0x32, 0x60, 0xb2, 0x4f, 0x28, 0xb1, 0x4d, 0xa2, 0xab, 0xf2, 0x48, 0x6b, 0x23, 0xc0, + 0x23, 0x8e, 0x82, 0x3e, 0x02, 0xd4, 0x34, 0x3c, 0x9e, 0xd1, 0xda, 0x2e, 0x25, 0x26, 0xa9, 0x72, + 0x56, 0x51, 0x90, 0xb9, 0xb8, 0x3a, 0xb6, 0xfb, 0x10, 0x78, 0x80, 0x15, 0xfa, 0x4a, 0x81, 0xe5, + 0x6a, 0xff, 0x90, 0x91, 0x75, 0x79, 0x79, 0x9c, 0x44, 0x0f, 0x98, 0x51, 0xfa, 0x6a, 0xa7, 0x5d, + 0x5a, 0x1e, 0xa0, 0xc0, 0x83, 0x9c, 0xa1, 0x7b, 0x90, 0xa3, 0x7e, 0x83, 0xb0, 0x42, 0x56, 0x5c, + 0x6f, 0xaa, 0xd7, 0x5d, 0xa7, 0x61, 0x99, 0x47, 0x98, 0x9b, 0x7c, 0x62, 0x79, 0xf5, 0x3d, 0x5f, + 0xcc, 0x2a, 0x16, 0xdf, 0xb5, 0x50, 0xe1, 0x80, 0x54, 0x7d, 0x04, 0x4b, 0xbd, 0x43, 0x03, 0xd5, + 0x00, 0xcc, 0xb0, 0x4f, 0x59, 0x41, 0x11, 0x6e, 0x5f, 0x1b, 0xbf, 0xaa, 0xa2, 0x1e, 0x8f, 0xe7, + 0x65, 0x24, 0x62, 0xb8, 0x8b, 0x5a, 0x3d, 0x07, 0x73, 0xd7, 0xa8, 0xe3, 0xbb, 0xf2, 0x8c, 0x68, + 0x1d, 0xb2, 0xb6, 0xd1, 0x0c, 0xa7, 0x4f, 0x34, 0x11, 0x77, 0x8c, 0x26, 0xc1, 0x42, 0xa3, 0x7e, + 0xa7, 0xc0, 0xfc, 0x96, 0xd5, 0xb4, 0x3c, 0x4c, 0x98, 0xeb, 0xd8, 0x8c, 0xa0, 0x4b, 0x89, 0x89, + 0x75, 0xb2, 0x67, 0x62, 0x1d, 0x4b, 0x80, 0xbb, 0x66, 0xd5, 0x67, 0x30, 0xfd, 0xd0, 0x27, 0xbe, + 0x65, 0xd7, 0xe4, 0xbc, 0xbe, 0x98, 0x16, 0xe0, 0xad, 0x00, 0x9e, 0xa8, 0x36, 0x7d, 0x96, 0x8f, + 0x00, 0xa9, 0xc1, 0x21, 0xa3, 0xfa, 0x57, 0x06, 0x4e, 0x0a, 0xc7, 0xa4, 0x3a, 0xbc, 0x8a, 0xd1, + 0x3d, 0x28, 0x18, 0x8c, 0xf9, 0x94, 0x54, 0x37, 0x1d, 0xdb, 0xf4, 0x29, 0xaf, 0xff, 0xa3, 0xbd, + 0xba, 0x41, 0x09, 0x13, 0xd1, 0xe4, 0xf4, 0x75, 0x19, 0x4d, 0x61, 0x63, 0x08, 0x0e, 0x0f, 0x65, + 0x40, 0x0f, 0x60, 0xbe, 0xd1, 0x1d, 0xbb, 0x0c, 0xf3, 0x6c, 0x5a, 0x98, 0x89, 0x84, 0xe9, 0x2b, + 0xf2, 0x04, 0xc9, 0xa4, 0xe3, 0x24, 0x35, 0x7a, 0x1b, 0x16, 0x1b, 0xc4, 0xae, 0x1a, 0x95, 0x06, + 0xd9, 0x25, 0xd4, 0x24, 0xb6, 0x27, 0x5a, 0x24, 0xa7, 0x2f, 0x77, 0xda, 0xa5, 0xc5, 0xad, 0xa4, + 0x0a, 0xf7, 0x62, 0xd1, 0x4d, 0x58, 0xa9, 0x38, 0x94, 0x3a, 0x87, 0x96, 0x5d, 0x13, 0x7e, 0x42, + 0x92, 0xac, 0x20, 0xf9, 0x57, 0xa7, 0x5d, 0x5a, 0xd1, 0x07, 0x01, 0xf0, 0x60, 0x3b, 0xf5, 0x10, + 0x56, 0x76, 0xf8, 0x4c, 0x61, 0x8e, 0x4f, 0x4d, 0x12, 0x37, 0x04, 0x2a, 0x41, 0xae, 0x45, 0x68, + 0x25, 0x28, 0xea, 0xbc, 0x9e, 0xe7, 0xed, 0xf0, 0x31, 0x17, 0xe0, 0x40, 0xce, 0x23, 0xb1, 0x63, + 0xcb, 0x3b, 0x78, 0x8b, 0x15, 0xa6, 0x04, 0x54, 0x44, 0xb2, 0x93, 0x54, 0xe1, 0x5e, 0xac, 0xda, + 0xce, 0xc0, 0xea, 0x90, 0xfe, 0x43, 0x77, 0x60, 0x86, 0xc9, 0xbf, 0x65, 0x4f, 0x9d, 0x4a, 0xbb, + 0x0b, 0x69, 0x1b, 0x4f, 0xff, 0x90, 0x0c, 0x47, 0x54, 0xc8, 0x81, 0x79, 0x2a, 0x8f, 0x20, 0x7c, + 0xca, 0x57, 0xe0, 0x42, 0x1a, 0x77, 0x7f, 0x76, 0xe2, 0xcb, 0xc6, 0xdd, 0x84, 0x38, 0xc9, 0x8f, + 0x1e, 0xc1, 0x52, 0x57, 0xd8, 0x81, 0xcf, 0x49, 0xe1, 0xf3, 0x52, 0x9a, 0xcf, 0x81, 0x97, 0xa2, + 0x17, 0xa4, 0xdb, 0xa5, 0x9d, 0x1e, 0x5a, 0xdc, 0xe7, 0x48, 0xfd, 0x39, 0x03, 0x23, 0x1e, 0x86, + 0x57, 0xb0, 0xe4, 0xdd, 0x4f, 0x2c, 0x79, 0xef, 0xbc, 0xf8, 0x8b, 0x37, 0x74, 0xe9, 0xab, 0xf7, + 0x2c, 0x7d, 0xef, 0xbd, 0x84, 0x8f, 0xd1, 0x4b, 0xe0, 0x1f, 0x19, 0xf8, 0xf7, 0x70, 0xe3, 0x78, + 0x29, 0xbc, 0x91, 0x18, 0xb1, 0x97, 0x7b, 0x46, 0xec, 0xa9, 0x31, 0x28, 0xfe, 0x59, 0x12, 0x7b, + 0x96, 0xc4, 0x5f, 0x14, 0x28, 0x0e, 0xcf, 0xdb, 0x2b, 0x58, 0x1a, 0x3f, 0x4f, 0x2e, 0x8d, 0x6f, + 0xbe, 0x78, 0x91, 0x0d, 0x59, 0x22, 0xaf, 0x8d, 0xaa, 0xad, 0x68, 0xdd, 0x1b, 0xe3, 0xc9, 0xff, + 0x69, 0x64, 0xaa, 0xc4, 0x76, 0x9a, 0xf2, 0xab, 0x25, 0x61, 0xfd, 0xbe, 0xcd, 0x9f, 0x9e, 0x26, + 0x7f, 0x3d, 0x82, 0x82, 0xac, 0xc3, 0x74, 0x23, 0x78, 0xab, 0x65, 0x53, 0x6f, 0x8c, 0xf5, 0x44, + 0x8e, 0x7a, 0xda, 0x83, 0xb5, 0x40, 0xc2, 0x70, 0x48, 0xaf, 0x7e, 0xab, 0xc0, 0x7a, 0x5a, 0xb3, + 0xa2, 0xc3, 0x01, 0xcb, 0xd7, 0x4b, 0x2c, 0xd6, 0xe3, 0x2f, 0x63, 0x3f, 0x28, 0x70, 0x7c, 0xd0, + 0x8e, 0xc3, 0xcb, 0x9f, 0x2f, 0x36, 0xd1, 0x56, 0x12, 0x95, 0xff, 0x2d, 0x21, 0xc5, 0x52, 0x8b, + 0xce, 0xc0, 0x4c, 0xdd, 0xb0, 0xab, 0x7b, 0xd6, 0x17, 0xe1, 0xbe, 0x1d, 0x15, 0xe0, 0x87, 0x52, + 0x8e, 0x23, 0x04, 0xba, 0x0a, 0x4b, 0xc2, 0x6e, 0x8b, 0xd8, 0x35, 0xaf, 0x2e, 0x72, 0x25, 0x97, + 0x86, 0xe8, 0x3d, 0xb8, 0xd5, 0xa3, 0xc7, 0x7d, 0x16, 0xea, 0x9f, 0x0a, 0xa0, 0x17, 0x79, 0xe7, + 0x4f, 0x43, 0xde, 0x70, 0x2d, 0xb1, 0x7c, 0x06, 0x2d, 0x90, 0xd7, 0xe7, 0x3b, 0xed, 0x52, 0x7e, + 0x63, 0xf7, 0x7a, 0x20, 0xc4, 0xb1, 0x9e, 0x83, 0xc3, 0x27, 0x30, 0x78, 0xea, 0x24, 0x38, 0x74, + 0xcc, 0x70, 0xac, 0x47, 0x57, 0x60, 0xce, 0x6c, 0xf8, 0xcc, 0x23, 0x74, 0xcf, 0x74, 0x5c, 0x22, + 0x46, 0xc6, 0x8c, 0x7e, 0x5c, 0xc6, 0x34, 0xb7, 0xd9, 0xa5, 0xc3, 0x09, 0x24, 0xd2, 0x00, 0x78, + 0xc1, 0x33, 0xd7, 0xe0, 0x7e, 0x72, 0xc2, 0xcf, 0x02, 0xbf, 0xb0, 0x9d, 0x48, 0x8a, 0xbb, 0x10, + 0xea, 0x03, 0x58, 0xd9, 0x23, 0xb4, 0x65, 0x99, 0x64, 0xc3, 0x34, 0x1d, 0xdf, 0xf6, 0xc2, 0x35, + 0xba, 0x0c, 0xf9, 0x08, 0x26, 0x7b, 0xe2, 0x98, 0xf4, 0x9f, 0x8f, 0xb8, 0x70, 0x8c, 0x89, 0x9a, + 0x30, 0x33, 0xbc, 0x09, 0x33, 0x30, 0x1d, 0xd3, 0x67, 0x0f, 0x2c, 0xbb, 0x2a, 0x99, 0x4f, 0x84, + 0xe8, 0x1b, 0x96, 0x5d, 0x7d, 0xde, 0x2e, 0xcd, 0x4a, 0x18, 0xff, 0xc4, 0x02, 0x88, 0xae, 0x43, + 0xd6, 0x67, 0x84, 0xca, 0xf6, 0x3a, 0x9d, 0x56, 0xcc, 0x77, 0x18, 0xa1, 0xe1, 0xe6, 0x33, 0xc3, + 0x99, 0xb9, 0x00, 0x0b, 0x0a, 0xb4, 0x0d, 0xb9, 0x1a, 0xbf, 0x14, 0x39, 0xf5, 0xcf, 0xa4, 0x71, + 0x75, 0xff, 0xbc, 0x08, 0xca, 0x40, 0x48, 0x70, 0xc0, 0x82, 0x1e, 0xc2, 0x02, 0x4b, 0xa4, 0x50, + 0x5c, 0xd7, 0x18, 0x9b, 0xcc, 0xc0, 0xc4, 0xeb, 0xa8, 0xd3, 0x2e, 0x2d, 0x24, 0x55, 0xb8, 0xc7, + 0x81, 0x5a, 0x86, 0xd9, 0xae, 0x00, 0xd3, 0xe7, 0x9f, 0x7e, 0xf5, 0xf1, 0xb3, 0xe2, 0xc4, 0x93, + 0x67, 0xc5, 0x89, 0xa7, 0xcf, 0x8a, 0x13, 0x5f, 0x76, 0x8a, 0xca, 0xe3, 0x4e, 0x51, 0x79, 0xd2, + 0x29, 0x2a, 0x4f, 0x3b, 0x45, 0xe5, 0xd7, 0x4e, 0x51, 0xf9, 0xfa, 0xb7, 0xe2, 0xc4, 0xdd, 0xe2, + 0xe8, 0xff, 0x33, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x6d, 0x6e, 0x75, 0xa1, 0x14, 0x00, + 0x00, } func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) { @@ -1154,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i _ = i var l int _ = l + if m.BorrowingLimitPercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent)) + i-- + dAtA[i] = 0x20 + } + if m.LendablePercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent)) + i-- + dAtA[i] = 0x18 + } { size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1903,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) { n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares)) l = m.LimitResponse.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.LendablePercent != nil { + n += 1 + sovGenerated(uint64(*m.LendablePercent)) + } + if m.BorrowingLimitPercent != nil { + n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent)) + } return n } @@ -2258,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string { s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`, `AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`, `LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`, + `LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`, + `BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`, `}`, }, "") return s @@ -3542,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LendablePercent = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BorrowingLimitPercent = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto index 474d520df74..98bfabe9c67 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto @@ -153,8 +153,8 @@ message LimitResponse { // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? message LimitedPriorityLevelConfiguration { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration { // `limitResponse` indicates what to do with requests that can not be executed right now optional LimitResponse limitResponse = 2; + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + optional int32 lendablePercent = 3; + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + optional int32 borrowingLimitPercent = 4; } // NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/types.go b/vendor/k8s.io/api/flowcontrol/v1beta1/types.go index b4573264298..c3b7f607a79 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/types.go @@ -105,7 +105,7 @@ const ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.20 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,FlowSchema +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchema // FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with // similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher". @@ -127,7 +127,7 @@ type FlowSchema struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.20 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,FlowSchemaList +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchemaList // FlowSchemaList is a list of FlowSchema objects. type FlowSchemaList struct { @@ -382,7 +382,7 @@ type FlowSchemaConditionType string // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.20 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,PriorityLevelConfiguration +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfiguration // PriorityLevelConfiguration represents the configuration of a priority level. type PriorityLevelConfiguration struct { @@ -403,7 +403,7 @@ type PriorityLevelConfiguration struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.20 -// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta2,PriorityLevelConfigurationList +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfigurationList // PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects. type PriorityLevelConfigurationList struct { @@ -451,8 +451,8 @@ const ( // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? type LimitedPriorityLevelConfiguration struct { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -474,6 +474,35 @@ type LimitedPriorityLevelConfiguration struct { // `limitResponse` indicates what to do with requests that can not be executed right now LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"` + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"` + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"` } // LimitResponse defines how to handle requests that can not be executed right now. diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go index b3752b6fb7d..fc08e128db3 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ @@ -111,9 +111,11 @@ func (LimitResponse) SwaggerDoc() map[string]string { } var map_LimitedPriorityLevelConfiguration = map[string]string{ - "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n * How are requests for this priority level limited?\n * What should be done with requests that exceed the limit?", + "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?", "assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ", "limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now", + "lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )", + "borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.", } func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.deepcopy.go index b7b84634ace..027c3057f81 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.deepcopy.go @@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse { func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) { *out = *in in.LimitResponse.DeepCopyInto(&out.LimitResponse) + if in.LendablePercent != nil { + in, out := &in.LendablePercent, &out.LendablePercent + *out = new(int32) + **out = **in + } + if in.BorrowingLimitPercent != nil { + in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent + *out = new(int32) + **out = **in + } return } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.prerelease-lifecycle.go index ed1e16c26a5..59b36b3bf9c 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/zz_generated.prerelease-lifecycle.go @@ -40,7 +40,7 @@ func (in *FlowSchema) APILifecycleDeprecated() (major, minor int) { // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *FlowSchema) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchema"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchema"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -64,7 +64,7 @@ func (in *FlowSchemaList) APILifecycleDeprecated() (major, minor int) { // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *FlowSchemaList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchemaList"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchemaList"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -88,7 +88,7 @@ func (in *PriorityLevelConfiguration) APILifecycleDeprecated() (major, minor int // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *PriorityLevelConfiguration) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfiguration"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. @@ -112,7 +112,7 @@ func (in *PriorityLevelConfigurationList) APILifecycleDeprecated() (major, minor // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. func (in *PriorityLevelConfigurationList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfigurationList"} + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfigurationList"} } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.pb.go index af42d24fb31..b4c8f958f1d 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.pb.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.pb.go @@ -689,101 +689,105 @@ func init() { } var fileDescriptor_ed300aa8e672704e = []byte{ - // 1497 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcb, 0x73, 0xdb, 0x44, - 0x18, 0x8f, 0x1c, 0x3b, 0x89, 0xbf, 0x3c, 0xbb, 0x69, 0x27, 0x9e, 0x74, 0xc6, 0x4e, 0xc5, 0x0c, - 0x05, 0xda, 0xca, 0x6d, 0x69, 0x69, 0x81, 0xe1, 0x11, 0xa5, 0x50, 0x4a, 0x93, 0x34, 0xdd, 0xb4, - 0xc0, 0x94, 0xce, 0x50, 0x59, 0xde, 0xd8, 0x6a, 0x6c, 0x49, 0xd5, 0xae, 0x9c, 0x09, 0xbd, 0x30, - 0xfc, 0x05, 0x9c, 0xe1, 0xc8, 0x81, 0x3b, 0xff, 0x00, 0x47, 0x3a, 0x9c, 0x7a, 0xec, 0xc9, 0x50, - 0x73, 0xe2, 0xc0, 0x1d, 0x7a, 0x62, 0x76, 0xb5, 0x92, 0x2c, 0xbf, 0xe4, 0x69, 0x67, 0x7a, 0xe2, - 0x66, 0x7d, 0x8f, 0xdf, 0xf7, 0xd8, 0xdf, 0x7e, 0xfb, 0x25, 0x70, 0x75, 0xff, 0x32, 0xd5, 0x2c, - 0xa7, 0xbc, 0xef, 0x57, 0x88, 0x67, 0x13, 0x46, 0x68, 0xb9, 0x45, 0xec, 0xaa, 0xe3, 0x95, 0xa5, - 0xc2, 0x70, 0xad, 0xf2, 0x5e, 0xc3, 0x39, 0x30, 0x1d, 0x9b, 0x79, 0x4e, 0xa3, 0xdc, 0x3a, 0x57, - 0x21, 0xcc, 0x38, 0x5f, 0xae, 0x11, 0x9b, 0x78, 0x06, 0x23, 0x55, 0xcd, 0xf5, 0x1c, 0xe6, 0xa0, - 0x62, 0x60, 0xaf, 0x19, 0xae, 0xa5, 0x75, 0xd9, 0x6b, 0xd2, 0x7e, 0xf5, 0x4c, 0xcd, 0x62, 0x75, - 0xbf, 0xa2, 0x99, 0x4e, 0xb3, 0x5c, 0x73, 0x6a, 0x4e, 0x59, 0xb8, 0x55, 0xfc, 0x3d, 0xf1, 0x25, - 0x3e, 0xc4, 0xaf, 0x00, 0x6e, 0xf5, 0x42, 0x1c, 0xbe, 0x69, 0x98, 0x75, 0xcb, 0x26, 0xde, 0x61, - 0xd9, 0xdd, 0xaf, 0x71, 0x01, 0x2d, 0x37, 0x09, 0x33, 0xca, 0xad, 0x73, 0xbd, 0x49, 0xac, 0x96, - 0x87, 0x79, 0x79, 0xbe, 0xcd, 0xac, 0x26, 0xe9, 0x73, 0x78, 0x2b, 0xcd, 0x81, 0x9a, 0x75, 0xd2, - 0x34, 0x7a, 0xfd, 0xd4, 0x3b, 0xb0, 0xf2, 0x71, 0xc3, 0x39, 0xb8, 0x62, 0x51, 0x66, 0xd9, 0x35, - 0xdf, 0xa2, 0x75, 0xe2, 0x6d, 0x11, 0x56, 0x77, 0xaa, 0xe8, 0x03, 0xc8, 0xb2, 0x43, 0x97, 0x14, - 0x94, 0x35, 0xe5, 0xb5, 0xbc, 0x7e, 0xea, 0x51, 0xbb, 0x34, 0xd1, 0x69, 0x97, 0xb2, 0xb7, 0x0e, - 0x5d, 0xf2, 0xac, 0x5d, 0x3a, 0x3e, 0xc4, 0x8d, 0xab, 0xb1, 0x70, 0x54, 0xbf, 0xcf, 0x00, 0x70, - 0xab, 0x5d, 0x11, 0x1a, 0xdd, 0x83, 0x19, 0x5e, 0x6e, 0xd5, 0x60, 0x86, 0xc0, 0x9c, 0x3d, 0x7f, - 0x56, 0x8b, 0x7b, 0x1d, 0x65, 0xad, 0xb9, 0xfb, 0x35, 0x2e, 0xa0, 0x1a, 0xb7, 0xd6, 0x5a, 0xe7, - 0xb4, 0x1b, 0x95, 0xfb, 0xc4, 0x64, 0x5b, 0x84, 0x19, 0x3a, 0x92, 0x59, 0x40, 0x2c, 0xc3, 0x11, - 0x2a, 0xda, 0x81, 0x2c, 0x75, 0x89, 0x59, 0xc8, 0x08, 0x74, 0x4d, 0x1b, 0x7d, 0x92, 0x5a, 0x9c, - 0xdb, 0xae, 0x4b, 0x4c, 0x7d, 0x2e, 0xac, 0x90, 0x7f, 0x61, 0x81, 0x84, 0xbe, 0x80, 0x29, 0xca, - 0x0c, 0xe6, 0xd3, 0xc2, 0x64, 0x5f, 0xc6, 0x69, 0x98, 0xc2, 0x4f, 0x5f, 0x90, 0xa8, 0x53, 0xc1, - 0x37, 0x96, 0x78, 0xea, 0x93, 0x0c, 0x2c, 0xc7, 0xc6, 0x1b, 0x8e, 0x5d, 0xb5, 0x98, 0xe5, 0xd8, - 0xe8, 0xdd, 0x44, 0xd7, 0x4f, 0xf6, 0x74, 0x7d, 0x65, 0x80, 0x4b, 0xdc, 0x71, 0xf4, 0x76, 0x94, - 0x6e, 0x46, 0xb8, 0x9f, 0x48, 0x06, 0x7f, 0xd6, 0x2e, 0x2d, 0x46, 0x6e, 0xc9, 0x7c, 0x50, 0x0b, - 0x50, 0xc3, 0xa0, 0xec, 0x96, 0x67, 0xd8, 0x34, 0x80, 0xb5, 0x9a, 0x44, 0x56, 0xfd, 0xc6, 0x78, - 0xe7, 0xc4, 0x3d, 0xf4, 0x55, 0x19, 0x12, 0x6d, 0xf6, 0xa1, 0xe1, 0x01, 0x11, 0xd0, 0xab, 0x30, - 0xe5, 0x11, 0x83, 0x3a, 0x76, 0x21, 0x2b, 0x52, 0x8e, 0xfa, 0x85, 0x85, 0x14, 0x4b, 0x2d, 0x7a, - 0x1d, 0xa6, 0x9b, 0x84, 0x52, 0xa3, 0x46, 0x0a, 0x39, 0x61, 0xb8, 0x28, 0x0d, 0xa7, 0xb7, 0x02, - 0x31, 0x0e, 0xf5, 0xea, 0x2f, 0x0a, 0x2c, 0xc4, 0x7d, 0xda, 0xb4, 0x28, 0x43, 0x77, 0xfb, 0xb8, - 0xa7, 0x8d, 0x57, 0x13, 0xf7, 0x16, 0xcc, 0x5b, 0x92, 0xe1, 0x66, 0x42, 0x49, 0x17, 0xef, 0x6e, - 0x40, 0xce, 0x62, 0xa4, 0xc9, 0xbb, 0x3e, 0xd9, 0xd3, 0xae, 0x14, 0x92, 0xe8, 0xf3, 0x12, 0x36, - 0x77, 0x8d, 0x03, 0xe0, 0x00, 0x47, 0xfd, 0x6b, 0xb2, 0xbb, 0x02, 0xce, 0x47, 0xf4, 0x93, 0x02, - 0xab, 0xae, 0x67, 0x39, 0x9e, 0xc5, 0x0e, 0x37, 0x49, 0x8b, 0x34, 0x36, 0x1c, 0x7b, 0xcf, 0xaa, - 0xf9, 0x9e, 0xc1, 0x5b, 0x29, 0x8b, 0xda, 0x48, 0x8b, 0xbc, 0x33, 0x14, 0x01, 0x93, 0x3d, 0xe2, - 0x11, 0xdb, 0x24, 0xba, 0x2a, 0x53, 0x5a, 0x1d, 0x61, 0x3c, 0x22, 0x15, 0xf4, 0x29, 0xa0, 0xa6, - 0xc1, 0x78, 0x47, 0x6b, 0x3b, 0x1e, 0x31, 0x49, 0x95, 0xa3, 0x0a, 0x42, 0xe6, 0x62, 0x76, 0x6c, - 0xf5, 0x59, 0xe0, 0x01, 0x5e, 0xe8, 0x5b, 0x05, 0x96, 0xab, 0xfd, 0x43, 0x46, 0xf2, 0xf2, 0xd2, - 0x38, 0x8d, 0x1e, 0x30, 0xa3, 0xf4, 0x95, 0x4e, 0xbb, 0xb4, 0x3c, 0x40, 0x81, 0x07, 0x05, 0x43, - 0x77, 0x21, 0xe7, 0xf9, 0x0d, 0x42, 0x0b, 0x59, 0x71, 0xbc, 0xa9, 0x51, 0x77, 0x9c, 0x86, 0x65, - 0x1e, 0x62, 0xee, 0xf2, 0xb9, 0xc5, 0xea, 0xbb, 0xbe, 0x98, 0x55, 0x34, 0x3e, 0x6b, 0xa1, 0xc2, - 0x01, 0xa8, 0xfa, 0x10, 0x96, 0x7a, 0x87, 0x06, 0xaa, 0x01, 0x98, 0xe1, 0x3d, 0xa5, 0x05, 0x45, - 0x84, 0x7d, 0x73, 0x7c, 0x56, 0x45, 0x77, 0x3c, 0x9e, 0x97, 0x91, 0x88, 0xe2, 0x2e, 0x68, 0xf5, - 0x2c, 0xcc, 0x5d, 0xf5, 0x1c, 0xdf, 0x95, 0x39, 0xa2, 0x35, 0xc8, 0xda, 0x46, 0x33, 0x9c, 0x3e, - 0xd1, 0x44, 0xdc, 0x36, 0x9a, 0x04, 0x0b, 0x8d, 0xfa, 0xa3, 0x02, 0xf3, 0x9b, 0x56, 0xd3, 0x62, - 0x98, 0x50, 0xd7, 0xb1, 0x29, 0x41, 0x17, 0x13, 0x13, 0xeb, 0x44, 0xcf, 0xc4, 0x3a, 0x92, 0x30, - 0xee, 0x9a, 0x55, 0x5f, 0xc2, 0xf4, 0x03, 0x9f, 0xf8, 0x96, 0x5d, 0x93, 0xf3, 0xfa, 0x42, 0x5a, - 0x81, 0x37, 0x03, 0xf3, 0x04, 0xdb, 0xf4, 0x59, 0x3e, 0x02, 0xa4, 0x06, 0x87, 0x88, 0xea, 0xdf, - 0x0a, 0x9c, 0x10, 0x81, 0x49, 0x75, 0x38, 0x8b, 0xd1, 0x5d, 0x28, 0x18, 0x94, 0xfa, 0x1e, 0xa9, - 0x6e, 0x38, 0xb6, 0xe9, 0x7b, 0x9c, 0xff, 0x87, 0xbb, 0x75, 0xc3, 0x23, 0x54, 0x54, 0x93, 0xd3, - 0xd7, 0x64, 0x35, 0x85, 0xf5, 0x21, 0x76, 0x78, 0x28, 0x02, 0xba, 0x0f, 0xf3, 0x8d, 0xee, 0xda, - 0x65, 0x99, 0x67, 0xd2, 0xca, 0x4c, 0x34, 0x4c, 0x3f, 0x26, 0x33, 0x48, 0x36, 0x1d, 0x27, 0xa1, - 0xd5, 0x03, 0x38, 0xb6, 0xcd, 0xef, 0x30, 0x75, 0x7c, 0xcf, 0x24, 0x31, 0x01, 0x51, 0x09, 0x72, - 0x2d, 0xe2, 0x55, 0x02, 0x12, 0xe5, 0xf5, 0x3c, 0xa7, 0xdf, 0x67, 0x5c, 0x80, 0x03, 0x39, 0x7a, - 0x0f, 0x16, 0xed, 0xd8, 0xf3, 0x36, 0xde, 0xa4, 0x85, 0x29, 0x61, 0xba, 0xdc, 0x69, 0x97, 0x16, - 0xb7, 0x93, 0x2a, 0xdc, 0x6b, 0xab, 0xb6, 0x33, 0xb0, 0x32, 0x84, 0xef, 0xe8, 0x36, 0xcc, 0x50, - 0xf9, 0x5b, 0x72, 0xf8, 0x64, 0x5a, 0xed, 0xd2, 0x37, 0x9e, 0xb6, 0x21, 0x18, 0x8e, 0xa0, 0x90, - 0x03, 0xf3, 0x9e, 0x4c, 0x41, 0xc4, 0x94, 0x53, 0xf7, 0x7c, 0x1a, 0x76, 0x7f, 0x77, 0xe2, 0xe6, - 0xe2, 0x6e, 0x40, 0x9c, 0xc4, 0x47, 0x0f, 0x61, 0xa9, 0xab, 0xec, 0x20, 0xe6, 0xa4, 0x88, 0x79, - 0x31, 0x2d, 0xe6, 0xc0, 0x43, 0xd1, 0x0b, 0x32, 0xec, 0xd2, 0x76, 0x0f, 0x2c, 0xee, 0x0b, 0xa4, - 0xfe, 0x96, 0x81, 0x11, 0x83, 0xf8, 0x25, 0x2c, 0x55, 0xf7, 0x12, 0x4b, 0xd5, 0xfb, 0xcf, 0xff, - 0xc2, 0x0c, 0x5d, 0xb2, 0xea, 0x3d, 0x4b, 0xd6, 0x87, 0x2f, 0x10, 0x63, 0xf4, 0xd2, 0xf5, 0x4f, - 0x06, 0x5e, 0x19, 0xee, 0x1c, 0x2f, 0x61, 0xd7, 0x13, 0x23, 0xed, 0x52, 0xcf, 0x48, 0x3b, 0x39, - 0x06, 0xc4, 0xff, 0x4b, 0x59, 0xcf, 0x52, 0xf6, 0xbb, 0x02, 0xc5, 0xe1, 0x7d, 0x7b, 0x09, 0x4b, - 0xda, 0x57, 0xc9, 0x25, 0xed, 0x9d, 0xe7, 0x27, 0xd9, 0x90, 0xa5, 0xed, 0xea, 0x28, 0x6e, 0x45, - 0xeb, 0xd5, 0x18, 0x4f, 0xec, 0xaf, 0x23, 0x5b, 0x25, 0xb6, 0xc1, 0x94, 0xbf, 0x12, 0x12, 0xde, - 0x1f, 0xd9, 0x46, 0xa5, 0x41, 0x9a, 0xc4, 0x66, 0x92, 0x90, 0x75, 0x98, 0x6e, 0x04, 0x6f, 0xa3, - 0xbc, 0xd4, 0xeb, 0x63, 0x3d, 0x49, 0xa3, 0x9e, 0xd2, 0xe0, 0x19, 0x96, 0x66, 0x38, 0x84, 0x57, - 0x7f, 0x50, 0x60, 0x2d, 0xed, 0xb2, 0xa2, 0x83, 0x01, 0xcb, 0xce, 0x0b, 0x2c, 0xb2, 0xe3, 0x2f, - 0x3f, 0x3f, 0x2b, 0x70, 0x74, 0xd0, 0x4e, 0xc1, 0xe9, 0xcf, 0x17, 0x89, 0x68, 0x0b, 0x88, 0xe8, - 0x7f, 0x53, 0x48, 0xb1, 0xd4, 0xa2, 0xd3, 0x30, 0x53, 0x37, 0xec, 0xea, 0xae, 0xf5, 0x75, 0xb8, - 0xdf, 0x46, 0x04, 0xfc, 0x44, 0xca, 0x71, 0x64, 0x81, 0xae, 0xc0, 0x92, 0xf0, 0xdb, 0x24, 0x76, - 0x8d, 0xd5, 0x45, 0xaf, 0xc4, 0x55, 0xce, 0xc5, 0xef, 0xc1, 0xcd, 0x1e, 0x3d, 0xee, 0xf3, 0x50, - 0xff, 0x55, 0x00, 0x3d, 0xcf, 0x3b, 0x7f, 0x0a, 0xf2, 0x86, 0x6b, 0x89, 0x65, 0x2f, 0xb8, 0x02, - 0x79, 0x7d, 0xbe, 0xd3, 0x2e, 0xe5, 0xd7, 0x77, 0xae, 0x05, 0x42, 0x1c, 0xeb, 0xb9, 0x71, 0xf8, - 0x04, 0x06, 0x4f, 0x9d, 0x34, 0x0e, 0x03, 0x53, 0x1c, 0xeb, 0xd1, 0x65, 0x98, 0x33, 0x1b, 0x3e, - 0x65, 0xc4, 0xdb, 0x35, 0x1d, 0x97, 0x88, 0x91, 0x31, 0xa3, 0x1f, 0x95, 0x35, 0xcd, 0x6d, 0x74, - 0xe9, 0x70, 0xc2, 0x12, 0x69, 0x00, 0x9c, 0xf0, 0xd4, 0x35, 0x78, 0x9c, 0x9c, 0x88, 0xb3, 0xc0, - 0x0f, 0x6c, 0x3b, 0x92, 0xe2, 0x2e, 0x0b, 0xf5, 0x3e, 0x1c, 0xdb, 0x25, 0x5e, 0xcb, 0x32, 0xc9, - 0xba, 0x69, 0x3a, 0xbe, 0xcd, 0xc2, 0xb5, 0xb5, 0x0c, 0xf9, 0xc8, 0x4c, 0xde, 0x89, 0x23, 0x32, - 0x7e, 0x3e, 0xc2, 0xc2, 0xb1, 0x4d, 0x74, 0x09, 0x33, 0xc3, 0x2f, 0x61, 0x06, 0xa6, 0x63, 0xf8, - 0xec, 0xbe, 0x65, 0x57, 0x25, 0xf2, 0xf1, 0xd0, 0xfa, 0xba, 0x65, 0x57, 0x9f, 0xb5, 0x4b, 0xb3, - 0xd2, 0x8c, 0x7f, 0x62, 0x61, 0x88, 0xae, 0x41, 0xd6, 0xa7, 0xc4, 0x93, 0xd7, 0xeb, 0x54, 0x1a, - 0x99, 0x6f, 0x53, 0xe2, 0x85, 0x9b, 0xcf, 0x0c, 0x47, 0xe6, 0x02, 0x2c, 0x20, 0xd0, 0x16, 0xe4, - 0x6a, 0xfc, 0x50, 0xe4, 0xd4, 0x3f, 0x9d, 0x86, 0xd5, 0xbd, 0xce, 0x07, 0x34, 0x10, 0x12, 0x1c, - 0xa0, 0xa0, 0x07, 0xb0, 0x40, 0x13, 0x2d, 0x14, 0xc7, 0x35, 0xc6, 0x26, 0x33, 0xb0, 0xf1, 0x3a, - 0xea, 0xb4, 0x4b, 0x0b, 0x49, 0x15, 0xee, 0x09, 0xa0, 0x96, 0x61, 0xb6, 0xab, 0xc0, 0xf4, 0xf9, - 0xa7, 0x5f, 0x79, 0xf4, 0xb4, 0x38, 0xf1, 0xf8, 0x69, 0x71, 0xe2, 0xc9, 0xd3, 0xe2, 0xc4, 0x37, - 0x9d, 0xa2, 0xf2, 0xa8, 0x53, 0x54, 0x1e, 0x77, 0x8a, 0xca, 0x93, 0x4e, 0x51, 0xf9, 0xa3, 0x53, - 0x54, 0xbe, 0xfb, 0xb3, 0x38, 0x71, 0xa7, 0x38, 0xfa, 0xff, 0x7a, 0xff, 0x05, 0x00, 0x00, 0xff, - 0xff, 0x1e, 0x66, 0x4a, 0x66, 0x11, 0x14, 0x00, 0x00, + // 1554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4f, 0x6f, 0xdb, 0xc6, + 0x12, 0x37, 0x65, 0xc9, 0xb6, 0xc6, 0x7f, 0xb3, 0x8e, 0x61, 0x3d, 0x07, 0x90, 0x1c, 0x3e, 0xe0, + 0xe5, 0xbd, 0x97, 0x84, 0x4a, 0xd2, 0xa4, 0x49, 0x5b, 0xf4, 0x8f, 0xe9, 0xb4, 0x69, 0x1a, 0xdb, + 0x71, 0xd6, 0x49, 0x5b, 0xa4, 0x01, 0x1a, 0x8a, 0x5a, 0x4b, 0x8c, 0x25, 0x92, 0xd9, 0x25, 0x65, + 0xb8, 0xb9, 0x14, 0xfd, 0x04, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x17, 0xe8, 0xb1, 0x41, 0x4f, + 0x39, 0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xdf, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xf5, + 0x8f, 0x42, 0x02, 0xe4, 0xd4, 0x9b, 0x39, 0xf3, 0x9b, 0xdf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c, + 0xd7, 0x0e, 0xae, 0x30, 0xcd, 0x72, 0xca, 0x07, 0x7e, 0x85, 0x50, 0x9b, 0x78, 0x84, 0x95, 0x5b, + 0xc4, 0xae, 0x3a, 0xb4, 0x2c, 0x15, 0x86, 0x6b, 0x95, 0xf7, 0x1b, 0xce, 0xa1, 0xe9, 0xd8, 0x1e, + 0x75, 0x1a, 0xe5, 0xd6, 0xf9, 0x0a, 0xf1, 0x8c, 0x0b, 0xe5, 0x1a, 0xb1, 0x09, 0x35, 0x3c, 0x52, + 0xd5, 0x5c, 0xea, 0x78, 0x0e, 0x2a, 0x06, 0x78, 0xcd, 0x70, 0x2d, 0xad, 0x0b, 0xaf, 0x49, 0xfc, + 0xda, 0xd9, 0x9a, 0xe5, 0xd5, 0xfd, 0x8a, 0x66, 0x3a, 0xcd, 0x72, 0xcd, 0xa9, 0x39, 0x65, 0x61, + 0x56, 0xf1, 0xf7, 0xc5, 0x97, 0xf8, 0x10, 0x7f, 0x05, 0x74, 0x6b, 0x17, 0x63, 0xf7, 0x4d, 0xc3, + 0xac, 0x5b, 0x36, 0xa1, 0x47, 0x65, 0xf7, 0xa0, 0xc6, 0x05, 0xac, 0xdc, 0x24, 0x9e, 0x51, 0x6e, + 0x9d, 0xef, 0x3d, 0xc4, 0x5a, 0x79, 0x98, 0x15, 0xf5, 0x6d, 0xcf, 0x6a, 0x92, 0x3e, 0x83, 0xd7, + 0xd3, 0x0c, 0x98, 0x59, 0x27, 0x4d, 0xa3, 0xd7, 0x4e, 0xbd, 0x0b, 0xab, 0x1f, 0x34, 0x9c, 0xc3, + 0xab, 0x16, 0xf3, 0x2c, 0xbb, 0xe6, 0x5b, 0xac, 0x4e, 0xe8, 0x36, 0xf1, 0xea, 0x4e, 0x15, 0xbd, + 0x0b, 0x59, 0xef, 0xc8, 0x25, 0x05, 0x65, 0x5d, 0xf9, 0x6f, 0x5e, 0x3f, 0xfd, 0xb8, 0x5d, 0x9a, + 0xe8, 0xb4, 0x4b, 0xd9, 0xdb, 0x47, 0x2e, 0x79, 0xde, 0x2e, 0x9d, 0x18, 0x62, 0xc6, 0xd5, 0x58, + 0x18, 0xaa, 0xdf, 0x64, 0x00, 0x38, 0x6a, 0x4f, 0xb8, 0x46, 0xf7, 0x61, 0x86, 0x87, 0x5b, 0x35, + 0x3c, 0x43, 0x70, 0xce, 0x5e, 0x38, 0xa7, 0xc5, 0xb9, 0x8e, 0x4e, 0xad, 0xb9, 0x07, 0x35, 0x2e, + 0x60, 0x1a, 0x47, 0x6b, 0xad, 0xf3, 0xda, 0xcd, 0xca, 0x03, 0x62, 0x7a, 0xdb, 0xc4, 0x33, 0x74, + 0x24, 0x4f, 0x01, 0xb1, 0x0c, 0x47, 0xac, 0x68, 0x17, 0xb2, 0xcc, 0x25, 0x66, 0x21, 0x23, 0xd8, + 0x35, 0x6d, 0xf4, 0x4d, 0x6a, 0xf1, 0xd9, 0xf6, 0x5c, 0x62, 0xea, 0x73, 0x61, 0x84, 0xfc, 0x0b, + 0x0b, 0x26, 0xf4, 0x29, 0x4c, 0x31, 0xcf, 0xf0, 0x7c, 0x56, 0x98, 0xec, 0x3b, 0x71, 0x1a, 0xa7, + 0xb0, 0xd3, 0x17, 0x24, 0xeb, 0x54, 0xf0, 0x8d, 0x25, 0x9f, 0xfa, 0x34, 0x03, 0xcb, 0x31, 0x78, + 0xd3, 0xb1, 0xab, 0x96, 0x67, 0x39, 0x36, 0x7a, 0x2b, 0x91, 0xf5, 0x53, 0x3d, 0x59, 0x5f, 0x1d, + 0x60, 0x12, 0x67, 0x1c, 0xbd, 0x11, 0x1d, 0x37, 0x23, 0xcc, 0x4f, 0x26, 0x9d, 0x3f, 0x6f, 0x97, + 0x16, 0x23, 0xb3, 0xe4, 0x79, 0x50, 0x0b, 0x50, 0xc3, 0x60, 0xde, 0x6d, 0x6a, 0xd8, 0x2c, 0xa0, + 0xb5, 0x9a, 0x44, 0x46, 0xfd, 0xff, 0xf1, 0xee, 0x89, 0x5b, 0xe8, 0x6b, 0xd2, 0x25, 0xda, 0xea, + 0x63, 0xc3, 0x03, 0x3c, 0xa0, 0xff, 0xc0, 0x14, 0x25, 0x06, 0x73, 0xec, 0x42, 0x56, 0x1c, 0x39, + 0xca, 0x17, 0x16, 0x52, 0x2c, 0xb5, 0xe8, 0x7f, 0x30, 0xdd, 0x24, 0x8c, 0x19, 0x35, 0x52, 0xc8, + 0x09, 0xe0, 0xa2, 0x04, 0x4e, 0x6f, 0x07, 0x62, 0x1c, 0xea, 0xd5, 0x1f, 0x15, 0x58, 0x88, 0xf3, + 0xb4, 0x65, 0x31, 0x0f, 0xdd, 0xeb, 0xab, 0x3d, 0x6d, 0xbc, 0x98, 0xb8, 0xb5, 0xa8, 0xbc, 0x25, + 0xe9, 0x6e, 0x26, 0x94, 0x74, 0xd5, 0xdd, 0x4d, 0xc8, 0x59, 0x1e, 0x69, 0xf2, 0xac, 0x4f, 0xf6, + 0xa4, 0x2b, 0xa5, 0x48, 0xf4, 0x79, 0x49, 0x9b, 0xbb, 0xce, 0x09, 0x70, 0xc0, 0xa3, 0xfe, 0x3e, + 0xd9, 0x1d, 0x01, 0xaf, 0x47, 0xf4, 0xbd, 0x02, 0x6b, 0x2e, 0xb5, 0x1c, 0x6a, 0x79, 0x47, 0x5b, + 0xa4, 0x45, 0x1a, 0x9b, 0x8e, 0xbd, 0x6f, 0xd5, 0x7c, 0x6a, 0xf0, 0x54, 0xca, 0xa0, 0x36, 0xd3, + 0x3c, 0xef, 0x0e, 0x65, 0xc0, 0x64, 0x9f, 0x50, 0x62, 0x9b, 0x44, 0x57, 0xe5, 0x91, 0xd6, 0x46, + 0x80, 0x47, 0x1c, 0x05, 0x7d, 0x04, 0xa8, 0x69, 0x78, 0x3c, 0xa3, 0xb5, 0x5d, 0x4a, 0x4c, 0x52, + 0xe5, 0xac, 0xa2, 0x20, 0x73, 0x71, 0x75, 0x6c, 0xf7, 0x21, 0xf0, 0x00, 0x2b, 0xf4, 0x95, 0x02, + 0xcb, 0xd5, 0xfe, 0x21, 0x23, 0xeb, 0xf2, 0xf2, 0x38, 0x89, 0x1e, 0x30, 0xa3, 0xf4, 0xd5, 0x4e, + 0xbb, 0xb4, 0x3c, 0x40, 0x81, 0x07, 0x39, 0x43, 0xf7, 0x20, 0x47, 0xfd, 0x06, 0x61, 0x85, 0xac, + 0xb8, 0xde, 0x54, 0xaf, 0xbb, 0x4e, 0xc3, 0x32, 0x8f, 0x30, 0x37, 0xf9, 0xc4, 0xf2, 0xea, 0x7b, + 0xbe, 0x98, 0x55, 0x2c, 0xbe, 0x6b, 0xa1, 0xc2, 0x01, 0xa9, 0xfa, 0x08, 0x96, 0x7a, 0x87, 0x06, + 0xaa, 0x01, 0x98, 0x61, 0x9f, 0xb2, 0x82, 0x22, 0xdc, 0xbe, 0x36, 0x7e, 0x55, 0x45, 0x3d, 0x1e, + 0xcf, 0xcb, 0x48, 0xc4, 0x70, 0x17, 0xb5, 0x7a, 0x0e, 0xe6, 0xae, 0x51, 0xc7, 0x77, 0xe5, 0x19, + 0xd1, 0x3a, 0x64, 0x6d, 0xa3, 0x19, 0x4e, 0x9f, 0x68, 0x22, 0xee, 0x18, 0x4d, 0x82, 0x85, 0x46, + 0xfd, 0x4e, 0x81, 0xf9, 0x2d, 0xab, 0x69, 0x79, 0x98, 0x30, 0xd7, 0xb1, 0x19, 0x41, 0x97, 0x12, + 0x13, 0xeb, 0x64, 0xcf, 0xc4, 0x3a, 0x96, 0x00, 0x77, 0xcd, 0xaa, 0xcf, 0x60, 0xfa, 0xa1, 0x4f, + 0x7c, 0xcb, 0xae, 0xc9, 0x79, 0x7d, 0x31, 0x2d, 0xc0, 0x5b, 0x01, 0x3c, 0x51, 0x6d, 0xfa, 0x2c, + 0x1f, 0x01, 0x52, 0x83, 0x43, 0x46, 0xf5, 0xaf, 0x0c, 0x9c, 0x14, 0x8e, 0x49, 0x75, 0x78, 0x15, + 0xa3, 0x7b, 0x50, 0x30, 0x18, 0xf3, 0x29, 0xa9, 0x6e, 0x3a, 0xb6, 0xe9, 0x53, 0x5e, 0xff, 0x47, + 0x7b, 0x75, 0x83, 0x12, 0x26, 0xa2, 0xc9, 0xe9, 0xeb, 0x32, 0x9a, 0xc2, 0xc6, 0x10, 0x1c, 0x1e, + 0xca, 0x80, 0x1e, 0xc0, 0x7c, 0xa3, 0x3b, 0x76, 0x19, 0xe6, 0xd9, 0xb4, 0x30, 0x13, 0x09, 0xd3, + 0x57, 0xe4, 0x09, 0x92, 0x49, 0xc7, 0x49, 0x6a, 0xf4, 0x36, 0x2c, 0x36, 0x88, 0x5d, 0x35, 0x2a, + 0x0d, 0xb2, 0x4b, 0xa8, 0x49, 0x6c, 0x4f, 0xb4, 0x48, 0x4e, 0x5f, 0xee, 0xb4, 0x4b, 0x8b, 0x5b, + 0x49, 0x15, 0xee, 0xc5, 0xa2, 0x9b, 0xb0, 0x52, 0x71, 0x28, 0x75, 0x0e, 0x2d, 0xbb, 0x26, 0xfc, + 0x84, 0x24, 0x59, 0x41, 0xf2, 0xaf, 0x4e, 0xbb, 0xb4, 0xa2, 0x0f, 0x02, 0xe0, 0xc1, 0x76, 0xea, + 0x21, 0xac, 0xec, 0xf0, 0x99, 0xc2, 0x1c, 0x9f, 0x9a, 0x24, 0x6e, 0x08, 0x54, 0x82, 0x5c, 0x8b, + 0xd0, 0x4a, 0x50, 0xd4, 0x79, 0x3d, 0xcf, 0xdb, 0xe1, 0x63, 0x2e, 0xc0, 0x81, 0x9c, 0x47, 0x62, + 0xc7, 0x96, 0x77, 0xf0, 0x16, 0x2b, 0x4c, 0x09, 0xa8, 0x88, 0x64, 0x27, 0xa9, 0xc2, 0xbd, 0x58, + 0xb5, 0x9d, 0x81, 0xd5, 0x21, 0xfd, 0x87, 0xee, 0xc0, 0x0c, 0x93, 0x7f, 0xcb, 0x9e, 0x3a, 0x95, + 0x76, 0x17, 0xd2, 0x36, 0x9e, 0xfe, 0x21, 0x19, 0x8e, 0xa8, 0x90, 0x03, 0xf3, 0x54, 0x1e, 0x41, + 0xf8, 0x94, 0xaf, 0xc0, 0x85, 0x34, 0xee, 0xfe, 0xec, 0xc4, 0x97, 0x8d, 0xbb, 0x09, 0x71, 0x92, + 0x1f, 0x3d, 0x82, 0xa5, 0xae, 0xb0, 0x03, 0x9f, 0x93, 0xc2, 0xe7, 0xa5, 0x34, 0x9f, 0x03, 0x2f, + 0x45, 0x2f, 0x48, 0xb7, 0x4b, 0x3b, 0x3d, 0xb4, 0xb8, 0xcf, 0x91, 0xfa, 0x73, 0x06, 0x46, 0x3c, + 0x0c, 0xaf, 0x60, 0xc9, 0xbb, 0x9f, 0x58, 0xf2, 0xde, 0x79, 0xf1, 0x17, 0x6f, 0xe8, 0xd2, 0x57, + 0xef, 0x59, 0xfa, 0xde, 0x7b, 0x09, 0x1f, 0xa3, 0x97, 0xc0, 0x3f, 0x32, 0xf0, 0xef, 0xe1, 0xc6, + 0xf1, 0x52, 0x78, 0x23, 0x31, 0x62, 0x2f, 0xf7, 0x8c, 0xd8, 0x53, 0x63, 0x50, 0xfc, 0xb3, 0x24, + 0xf6, 0x2c, 0x89, 0xbf, 0x28, 0x50, 0x1c, 0x9e, 0xb7, 0x57, 0xb0, 0x34, 0x7e, 0x9e, 0x5c, 0x1a, + 0xdf, 0x7c, 0xf1, 0x22, 0x1b, 0xb2, 0x44, 0x5e, 0x1b, 0x55, 0x5b, 0xd1, 0xba, 0x37, 0xc6, 0x93, + 0xff, 0xd3, 0xc8, 0x54, 0x89, 0xed, 0x34, 0xe5, 0x57, 0x4b, 0xc2, 0xfa, 0x7d, 0x9b, 0x3f, 0x3d, + 0x4d, 0xfe, 0x7a, 0x04, 0x05, 0x59, 0x87, 0xe9, 0x46, 0xf0, 0x56, 0xcb, 0xa6, 0xde, 0x18, 0xeb, + 0x89, 0x1c, 0xf5, 0xb4, 0x07, 0x6b, 0x81, 0x84, 0xe1, 0x90, 0x5e, 0xfd, 0x56, 0x81, 0xf5, 0xb4, + 0x66, 0x45, 0x87, 0x03, 0x96, 0xaf, 0x97, 0x58, 0xac, 0xc7, 0x5f, 0xc6, 0x7e, 0x50, 0xe0, 0xf8, + 0xa0, 0x1d, 0x87, 0x97, 0x3f, 0x5f, 0x6c, 0xa2, 0xad, 0x24, 0x2a, 0xff, 0x5b, 0x42, 0x8a, 0xa5, + 0x16, 0x9d, 0x81, 0x99, 0xba, 0x61, 0x57, 0xf7, 0xac, 0x2f, 0xc2, 0x7d, 0x3b, 0x2a, 0xc0, 0x0f, + 0xa5, 0x1c, 0x47, 0x08, 0x74, 0x15, 0x96, 0x84, 0xdd, 0x16, 0xb1, 0x6b, 0x5e, 0x5d, 0xe4, 0x4a, + 0x2e, 0x0d, 0xd1, 0x7b, 0x70, 0xab, 0x47, 0x8f, 0xfb, 0x2c, 0xd4, 0x3f, 0x15, 0x40, 0x2f, 0xf2, + 0xce, 0x9f, 0x86, 0xbc, 0xe1, 0x5a, 0x62, 0xf9, 0x0c, 0x5a, 0x20, 0xaf, 0xcf, 0x77, 0xda, 0xa5, + 0xfc, 0xc6, 0xee, 0xf5, 0x40, 0x88, 0x63, 0x3d, 0x07, 0x87, 0x4f, 0x60, 0xf0, 0xd4, 0x49, 0x70, + 0xe8, 0x98, 0xe1, 0x58, 0x8f, 0xae, 0xc0, 0x9c, 0xd9, 0xf0, 0x99, 0x47, 0xe8, 0x9e, 0xe9, 0xb8, + 0x44, 0x8c, 0x8c, 0x19, 0xfd, 0xb8, 0x8c, 0x69, 0x6e, 0xb3, 0x4b, 0x87, 0x13, 0x48, 0xa4, 0x01, + 0xf0, 0x82, 0x67, 0xae, 0xc1, 0xfd, 0xe4, 0x84, 0x9f, 0x05, 0x7e, 0x61, 0x3b, 0x91, 0x14, 0x77, + 0x21, 0xd4, 0x07, 0xb0, 0xb2, 0x47, 0x68, 0xcb, 0x32, 0xc9, 0x86, 0x69, 0x3a, 0xbe, 0xed, 0x85, + 0x6b, 0x74, 0x19, 0xf2, 0x11, 0x4c, 0xf6, 0xc4, 0x31, 0xe9, 0x3f, 0x1f, 0x71, 0xe1, 0x18, 0x13, + 0x35, 0x61, 0x66, 0x78, 0x13, 0x66, 0x60, 0x3a, 0xa6, 0xcf, 0x1e, 0x58, 0x76, 0x55, 0x32, 0x9f, + 0x08, 0xd1, 0x37, 0x2c, 0xbb, 0xfa, 0xbc, 0x5d, 0x9a, 0x95, 0x30, 0xfe, 0x89, 0x05, 0x10, 0x5d, + 0x87, 0xac, 0xcf, 0x08, 0x95, 0xed, 0x75, 0x3a, 0xad, 0x98, 0xef, 0x30, 0x42, 0xc3, 0xcd, 0x67, + 0x86, 0x33, 0x73, 0x01, 0x16, 0x14, 0x68, 0x1b, 0x72, 0x35, 0x7e, 0x29, 0x72, 0xea, 0x9f, 0x49, + 0xe3, 0xea, 0xfe, 0x79, 0x11, 0x94, 0x81, 0x90, 0xe0, 0x80, 0x05, 0x3d, 0x84, 0x05, 0x96, 0x48, + 0xa1, 0xb8, 0xae, 0x31, 0x36, 0x99, 0x81, 0x89, 0xd7, 0x51, 0xa7, 0x5d, 0x5a, 0x48, 0xaa, 0x70, + 0x8f, 0x03, 0xb5, 0x0c, 0xb3, 0x5d, 0x01, 0xa6, 0xcf, 0x3f, 0xfd, 0xea, 0xe3, 0x67, 0xc5, 0x89, + 0x27, 0xcf, 0x8a, 0x13, 0x4f, 0x9f, 0x15, 0x27, 0xbe, 0xec, 0x14, 0x95, 0xc7, 0x9d, 0xa2, 0xf2, + 0xa4, 0x53, 0x54, 0x9e, 0x76, 0x8a, 0xca, 0xaf, 0x9d, 0xa2, 0xf2, 0xf5, 0x6f, 0xc5, 0x89, 0xbb, + 0xc5, 0xd1, 0xff, 0x67, 0xfc, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x87, 0x72, 0xbf, 0xe2, 0xa1, 0x14, + 0x00, 0x00, } func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) { @@ -1154,6 +1158,16 @@ func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (i _ = i var l int _ = l + if m.BorrowingLimitPercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent)) + i-- + dAtA[i] = 0x20 + } + if m.LendablePercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent)) + i-- + dAtA[i] = 0x18 + } { size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1903,6 +1917,12 @@ func (m *LimitedPriorityLevelConfiguration) Size() (n int) { n += 1 + sovGenerated(uint64(m.AssuredConcurrencyShares)) l = m.LimitResponse.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.LendablePercent != nil { + n += 1 + sovGenerated(uint64(*m.LendablePercent)) + } + if m.BorrowingLimitPercent != nil { + n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent)) + } return n } @@ -2258,6 +2278,8 @@ func (this *LimitedPriorityLevelConfiguration) String() string { s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`, `AssuredConcurrencyShares:` + fmt.Sprintf("%v", this.AssuredConcurrencyShares) + `,`, `LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`, + `LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`, + `BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`, `}`, }, "") return s @@ -3542,6 +3564,46 @@ func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LendablePercent = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BorrowingLimitPercent = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto index 80bbaedea2f..4c98f21bcf5 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto @@ -153,8 +153,8 @@ message LimitResponse { // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? message LimitedPriorityLevelConfiguration { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -176,6 +176,35 @@ message LimitedPriorityLevelConfiguration { // `limitResponse` indicates what to do with requests that can not be executed right now optional LimitResponse limitResponse = 2; + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + optional int32 lendablePercent = 3; + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + optional int32 borrowingLimitPercent = 4; } // NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/types.go b/vendor/k8s.io/api/flowcontrol/v1beta2/types.go index 408681e998c..75409cee3e7 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/types.go @@ -105,6 +105,7 @@ const ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.23 +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchema // FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with // similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher". @@ -126,6 +127,7 @@ type FlowSchema struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.23 +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,FlowSchemaList // FlowSchemaList is a list of FlowSchema objects. type FlowSchemaList struct { @@ -380,6 +382,7 @@ type FlowSchemaConditionType string // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.23 +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfiguration // PriorityLevelConfiguration represents the configuration of a priority level. type PriorityLevelConfiguration struct { @@ -400,6 +403,7 @@ type PriorityLevelConfiguration struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.23 +// +k8s:prerelease-lifecycle-gen:replacement=flowcontrol.apiserver.k8s.io,v1beta3,PriorityLevelConfigurationList // PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects. type PriorityLevelConfigurationList struct { @@ -447,8 +451,8 @@ const ( // LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. // It addresses two issues: -// * How are requests for this priority level limited? -// * What should be done with requests that exceed the limit? +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? type LimitedPriorityLevelConfiguration struct { // `assuredConcurrencyShares` (ACS) configures the execution // limit, which is a limit on the number of requests of this @@ -470,6 +474,35 @@ type LimitedPriorityLevelConfiguration struct { // `limitResponse` indicates what to do with requests that can not be executed right now LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"` + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"` + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"` } // LimitResponse defines how to handle requests that can not be executed right now. diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go index 4775a8e993c..b2eff7f96e7 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ @@ -111,9 +111,11 @@ func (LimitResponse) SwaggerDoc() map[string]string { } var map_LimitedPriorityLevelConfiguration = map[string]string{ - "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n * How are requests for this priority level limited?\n * What should be done with requests that exceed the limit?", + "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?", "assuredConcurrencyShares": "`assuredConcurrencyShares` (ACS) configures the execution limit, which is a limit on the number of requests of this priority level that may be exeucting at a given time. ACS must be a positive number. The server's concurrency limit (SCL) is divided among the concurrency-controlled priority levels in proportion to their assured concurrency shares. This produces the assured concurrency value (ACV) ", "limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now", + "lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )", + "borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.", } func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.deepcopy.go b/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.deepcopy.go index e6288a687a9..aa692484c1c 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.deepcopy.go @@ -212,6 +212,16 @@ func (in *LimitResponse) DeepCopy() *LimitResponse { func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) { *out = *in in.LimitResponse.DeepCopyInto(&out.LimitResponse) + if in.LendablePercent != nil { + in, out := &in.LendablePercent, &out.LendablePercent + *out = new(int32) + **out = **in + } + if in.BorrowingLimitPercent != nil { + in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent + *out = new(int32) + **out = **in + } return } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.prerelease-lifecycle.go index 00cefde419f..2abad4e1942 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/zz_generated.prerelease-lifecycle.go @@ -21,6 +21,10 @@ limitations under the License. package v1beta2 +import ( + schema "k8s.io/apimachinery/pkg/runtime/schema" +) + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *FlowSchema) APILifecycleIntroduced() (major, minor int) { @@ -33,6 +37,12 @@ func (in *FlowSchema) APILifecycleDeprecated() (major, minor int) { return 1, 26 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *FlowSchema) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchema"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *FlowSchema) APILifecycleRemoved() (major, minor int) { @@ -51,6 +61,12 @@ func (in *FlowSchemaList) APILifecycleDeprecated() (major, minor int) { return 1, 26 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *FlowSchemaList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchemaList"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *FlowSchemaList) APILifecycleRemoved() (major, minor int) { @@ -69,6 +85,12 @@ func (in *PriorityLevelConfiguration) APILifecycleDeprecated() (major, minor int return 1, 26 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *PriorityLevelConfiguration) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfiguration"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *PriorityLevelConfiguration) APILifecycleRemoved() (major, minor int) { @@ -87,6 +109,12 @@ func (in *PriorityLevelConfigurationList) APILifecycleDeprecated() (major, minor return 1, 26 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *PriorityLevelConfigurationList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfigurationList"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *PriorityLevelConfigurationList) APILifecycleRemoved() (major, minor int) { diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go b/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go new file mode 100644 index 00000000000..cd60cfef7fe --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go @@ -0,0 +1,25 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true + +// +groupName=flowcontrol.apiserver.k8s.io + +// Package v1beta3 holds api types of version v1beta3 for group "flowcontrol.apiserver.k8s.io". +package v1beta3 // import "k8s.io/api/flowcontrol/v1beta3" diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.pb.go new file mode 100644 index 00000000000..166e8520b7c --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.pb.go @@ -0,0 +1,5428 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto + +package v1beta3 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *FlowDistinguisherMethod) Reset() { *m = FlowDistinguisherMethod{} } +func (*FlowDistinguisherMethod) ProtoMessage() {} +func (*FlowDistinguisherMethod) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{0} +} +func (m *FlowDistinguisherMethod) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowDistinguisherMethod) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowDistinguisherMethod) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowDistinguisherMethod.Merge(m, src) +} +func (m *FlowDistinguisherMethod) XXX_Size() int { + return m.Size() +} +func (m *FlowDistinguisherMethod) XXX_DiscardUnknown() { + xxx_messageInfo_FlowDistinguisherMethod.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowDistinguisherMethod proto.InternalMessageInfo + +func (m *FlowSchema) Reset() { *m = FlowSchema{} } +func (*FlowSchema) ProtoMessage() {} +func (*FlowSchema) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{1} +} +func (m *FlowSchema) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowSchema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowSchema) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowSchema.Merge(m, src) +} +func (m *FlowSchema) XXX_Size() int { + return m.Size() +} +func (m *FlowSchema) XXX_DiscardUnknown() { + xxx_messageInfo_FlowSchema.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowSchema proto.InternalMessageInfo + +func (m *FlowSchemaCondition) Reset() { *m = FlowSchemaCondition{} } +func (*FlowSchemaCondition) ProtoMessage() {} +func (*FlowSchemaCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{2} +} +func (m *FlowSchemaCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowSchemaCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowSchemaCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowSchemaCondition.Merge(m, src) +} +func (m *FlowSchemaCondition) XXX_Size() int { + return m.Size() +} +func (m *FlowSchemaCondition) XXX_DiscardUnknown() { + xxx_messageInfo_FlowSchemaCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowSchemaCondition proto.InternalMessageInfo + +func (m *FlowSchemaList) Reset() { *m = FlowSchemaList{} } +func (*FlowSchemaList) ProtoMessage() {} +func (*FlowSchemaList) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{3} +} +func (m *FlowSchemaList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowSchemaList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowSchemaList) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowSchemaList.Merge(m, src) +} +func (m *FlowSchemaList) XXX_Size() int { + return m.Size() +} +func (m *FlowSchemaList) XXX_DiscardUnknown() { + xxx_messageInfo_FlowSchemaList.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowSchemaList proto.InternalMessageInfo + +func (m *FlowSchemaSpec) Reset() { *m = FlowSchemaSpec{} } +func (*FlowSchemaSpec) ProtoMessage() {} +func (*FlowSchemaSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{4} +} +func (m *FlowSchemaSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowSchemaSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowSchemaSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowSchemaSpec.Merge(m, src) +} +func (m *FlowSchemaSpec) XXX_Size() int { + return m.Size() +} +func (m *FlowSchemaSpec) XXX_DiscardUnknown() { + xxx_messageInfo_FlowSchemaSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowSchemaSpec proto.InternalMessageInfo + +func (m *FlowSchemaStatus) Reset() { *m = FlowSchemaStatus{} } +func (*FlowSchemaStatus) ProtoMessage() {} +func (*FlowSchemaStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{5} +} +func (m *FlowSchemaStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FlowSchemaStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *FlowSchemaStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlowSchemaStatus.Merge(m, src) +} +func (m *FlowSchemaStatus) XXX_Size() int { + return m.Size() +} +func (m *FlowSchemaStatus) XXX_DiscardUnknown() { + xxx_messageInfo_FlowSchemaStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_FlowSchemaStatus proto.InternalMessageInfo + +func (m *GroupSubject) Reset() { *m = GroupSubject{} } +func (*GroupSubject) ProtoMessage() {} +func (*GroupSubject) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{6} +} +func (m *GroupSubject) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GroupSubject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *GroupSubject) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupSubject.Merge(m, src) +} +func (m *GroupSubject) XXX_Size() int { + return m.Size() +} +func (m *GroupSubject) XXX_DiscardUnknown() { + xxx_messageInfo_GroupSubject.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupSubject proto.InternalMessageInfo + +func (m *LimitResponse) Reset() { *m = LimitResponse{} } +func (*LimitResponse) ProtoMessage() {} +func (*LimitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{7} +} +func (m *LimitResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LimitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LimitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LimitResponse.Merge(m, src) +} +func (m *LimitResponse) XXX_Size() int { + return m.Size() +} +func (m *LimitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LimitResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LimitResponse proto.InternalMessageInfo + +func (m *LimitedPriorityLevelConfiguration) Reset() { *m = LimitedPriorityLevelConfiguration{} } +func (*LimitedPriorityLevelConfiguration) ProtoMessage() {} +func (*LimitedPriorityLevelConfiguration) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{8} +} +func (m *LimitedPriorityLevelConfiguration) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LimitedPriorityLevelConfiguration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LimitedPriorityLevelConfiguration) XXX_Merge(src proto.Message) { + xxx_messageInfo_LimitedPriorityLevelConfiguration.Merge(m, src) +} +func (m *LimitedPriorityLevelConfiguration) XXX_Size() int { + return m.Size() +} +func (m *LimitedPriorityLevelConfiguration) XXX_DiscardUnknown() { + xxx_messageInfo_LimitedPriorityLevelConfiguration.DiscardUnknown(m) +} + +var xxx_messageInfo_LimitedPriorityLevelConfiguration proto.InternalMessageInfo + +func (m *NonResourcePolicyRule) Reset() { *m = NonResourcePolicyRule{} } +func (*NonResourcePolicyRule) ProtoMessage() {} +func (*NonResourcePolicyRule) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{9} +} +func (m *NonResourcePolicyRule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NonResourcePolicyRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NonResourcePolicyRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_NonResourcePolicyRule.Merge(m, src) +} +func (m *NonResourcePolicyRule) XXX_Size() int { + return m.Size() +} +func (m *NonResourcePolicyRule) XXX_DiscardUnknown() { + xxx_messageInfo_NonResourcePolicyRule.DiscardUnknown(m) +} + +var xxx_messageInfo_NonResourcePolicyRule proto.InternalMessageInfo + +func (m *PolicyRulesWithSubjects) Reset() { *m = PolicyRulesWithSubjects{} } +func (*PolicyRulesWithSubjects) ProtoMessage() {} +func (*PolicyRulesWithSubjects) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{10} +} +func (m *PolicyRulesWithSubjects) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PolicyRulesWithSubjects) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PolicyRulesWithSubjects) XXX_Merge(src proto.Message) { + xxx_messageInfo_PolicyRulesWithSubjects.Merge(m, src) +} +func (m *PolicyRulesWithSubjects) XXX_Size() int { + return m.Size() +} +func (m *PolicyRulesWithSubjects) XXX_DiscardUnknown() { + xxx_messageInfo_PolicyRulesWithSubjects.DiscardUnknown(m) +} + +var xxx_messageInfo_PolicyRulesWithSubjects proto.InternalMessageInfo + +func (m *PriorityLevelConfiguration) Reset() { *m = PriorityLevelConfiguration{} } +func (*PriorityLevelConfiguration) ProtoMessage() {} +func (*PriorityLevelConfiguration) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{11} +} +func (m *PriorityLevelConfiguration) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfiguration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfiguration) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfiguration.Merge(m, src) +} +func (m *PriorityLevelConfiguration) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfiguration) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfiguration.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfiguration proto.InternalMessageInfo + +func (m *PriorityLevelConfigurationCondition) Reset() { *m = PriorityLevelConfigurationCondition{} } +func (*PriorityLevelConfigurationCondition) ProtoMessage() {} +func (*PriorityLevelConfigurationCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{12} +} +func (m *PriorityLevelConfigurationCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfigurationCondition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfigurationCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfigurationCondition.Merge(m, src) +} +func (m *PriorityLevelConfigurationCondition) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfigurationCondition) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfigurationCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfigurationCondition proto.InternalMessageInfo + +func (m *PriorityLevelConfigurationList) Reset() { *m = PriorityLevelConfigurationList{} } +func (*PriorityLevelConfigurationList) ProtoMessage() {} +func (*PriorityLevelConfigurationList) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{13} +} +func (m *PriorityLevelConfigurationList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfigurationList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfigurationList) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfigurationList.Merge(m, src) +} +func (m *PriorityLevelConfigurationList) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfigurationList) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfigurationList.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfigurationList proto.InternalMessageInfo + +func (m *PriorityLevelConfigurationReference) Reset() { *m = PriorityLevelConfigurationReference{} } +func (*PriorityLevelConfigurationReference) ProtoMessage() {} +func (*PriorityLevelConfigurationReference) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{14} +} +func (m *PriorityLevelConfigurationReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfigurationReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfigurationReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfigurationReference.Merge(m, src) +} +func (m *PriorityLevelConfigurationReference) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfigurationReference) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfigurationReference.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfigurationReference proto.InternalMessageInfo + +func (m *PriorityLevelConfigurationSpec) Reset() { *m = PriorityLevelConfigurationSpec{} } +func (*PriorityLevelConfigurationSpec) ProtoMessage() {} +func (*PriorityLevelConfigurationSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{15} +} +func (m *PriorityLevelConfigurationSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfigurationSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfigurationSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfigurationSpec.Merge(m, src) +} +func (m *PriorityLevelConfigurationSpec) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfigurationSpec) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfigurationSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfigurationSpec proto.InternalMessageInfo + +func (m *PriorityLevelConfigurationStatus) Reset() { *m = PriorityLevelConfigurationStatus{} } +func (*PriorityLevelConfigurationStatus) ProtoMessage() {} +func (*PriorityLevelConfigurationStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{16} +} +func (m *PriorityLevelConfigurationStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriorityLevelConfigurationStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PriorityLevelConfigurationStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriorityLevelConfigurationStatus.Merge(m, src) +} +func (m *PriorityLevelConfigurationStatus) XXX_Size() int { + return m.Size() +} +func (m *PriorityLevelConfigurationStatus) XXX_DiscardUnknown() { + xxx_messageInfo_PriorityLevelConfigurationStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_PriorityLevelConfigurationStatus proto.InternalMessageInfo + +func (m *QueuingConfiguration) Reset() { *m = QueuingConfiguration{} } +func (*QueuingConfiguration) ProtoMessage() {} +func (*QueuingConfiguration) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{17} +} +func (m *QueuingConfiguration) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuingConfiguration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *QueuingConfiguration) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuingConfiguration.Merge(m, src) +} +func (m *QueuingConfiguration) XXX_Size() int { + return m.Size() +} +func (m *QueuingConfiguration) XXX_DiscardUnknown() { + xxx_messageInfo_QueuingConfiguration.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuingConfiguration proto.InternalMessageInfo + +func (m *ResourcePolicyRule) Reset() { *m = ResourcePolicyRule{} } +func (*ResourcePolicyRule) ProtoMessage() {} +func (*ResourcePolicyRule) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{18} +} +func (m *ResourcePolicyRule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourcePolicyRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourcePolicyRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourcePolicyRule.Merge(m, src) +} +func (m *ResourcePolicyRule) XXX_Size() int { + return m.Size() +} +func (m *ResourcePolicyRule) XXX_DiscardUnknown() { + xxx_messageInfo_ResourcePolicyRule.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourcePolicyRule proto.InternalMessageInfo + +func (m *ServiceAccountSubject) Reset() { *m = ServiceAccountSubject{} } +func (*ServiceAccountSubject) ProtoMessage() {} +func (*ServiceAccountSubject) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{19} +} +func (m *ServiceAccountSubject) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServiceAccountSubject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ServiceAccountSubject) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceAccountSubject.Merge(m, src) +} +func (m *ServiceAccountSubject) XXX_Size() int { + return m.Size() +} +func (m *ServiceAccountSubject) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceAccountSubject.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceAccountSubject proto.InternalMessageInfo + +func (m *Subject) Reset() { *m = Subject{} } +func (*Subject) ProtoMessage() {} +func (*Subject) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{20} +} +func (m *Subject) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Subject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Subject) XXX_Merge(src proto.Message) { + xxx_messageInfo_Subject.Merge(m, src) +} +func (m *Subject) XXX_Size() int { + return m.Size() +} +func (m *Subject) XXX_DiscardUnknown() { + xxx_messageInfo_Subject.DiscardUnknown(m) +} + +var xxx_messageInfo_Subject proto.InternalMessageInfo + +func (m *UserSubject) Reset() { *m = UserSubject{} } +func (*UserSubject) ProtoMessage() {} +func (*UserSubject) Descriptor() ([]byte, []int) { + return fileDescriptor_803504887082f044, []int{21} +} +func (m *UserSubject) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UserSubject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *UserSubject) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserSubject.Merge(m, src) +} +func (m *UserSubject) XXX_Size() int { + return m.Size() +} +func (m *UserSubject) XXX_DiscardUnknown() { + xxx_messageInfo_UserSubject.DiscardUnknown(m) +} + +var xxx_messageInfo_UserSubject proto.InternalMessageInfo + +func init() { + proto.RegisterType((*FlowDistinguisherMethod)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowDistinguisherMethod") + proto.RegisterType((*FlowSchema)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowSchema") + proto.RegisterType((*FlowSchemaCondition)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowSchemaCondition") + proto.RegisterType((*FlowSchemaList)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowSchemaList") + proto.RegisterType((*FlowSchemaSpec)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowSchemaSpec") + proto.RegisterType((*FlowSchemaStatus)(nil), "k8s.io.api.flowcontrol.v1beta3.FlowSchemaStatus") + proto.RegisterType((*GroupSubject)(nil), "k8s.io.api.flowcontrol.v1beta3.GroupSubject") + proto.RegisterType((*LimitResponse)(nil), "k8s.io.api.flowcontrol.v1beta3.LimitResponse") + proto.RegisterType((*LimitedPriorityLevelConfiguration)(nil), "k8s.io.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration") + proto.RegisterType((*NonResourcePolicyRule)(nil), "k8s.io.api.flowcontrol.v1beta3.NonResourcePolicyRule") + proto.RegisterType((*PolicyRulesWithSubjects)(nil), "k8s.io.api.flowcontrol.v1beta3.PolicyRulesWithSubjects") + proto.RegisterType((*PriorityLevelConfiguration)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfiguration") + proto.RegisterType((*PriorityLevelConfigurationCondition)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfigurationCondition") + proto.RegisterType((*PriorityLevelConfigurationList)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfigurationList") + proto.RegisterType((*PriorityLevelConfigurationReference)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfigurationReference") + proto.RegisterType((*PriorityLevelConfigurationSpec)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfigurationSpec") + proto.RegisterType((*PriorityLevelConfigurationStatus)(nil), "k8s.io.api.flowcontrol.v1beta3.PriorityLevelConfigurationStatus") + proto.RegisterType((*QueuingConfiguration)(nil), "k8s.io.api.flowcontrol.v1beta3.QueuingConfiguration") + proto.RegisterType((*ResourcePolicyRule)(nil), "k8s.io.api.flowcontrol.v1beta3.ResourcePolicyRule") + proto.RegisterType((*ServiceAccountSubject)(nil), "k8s.io.api.flowcontrol.v1beta3.ServiceAccountSubject") + proto.RegisterType((*Subject)(nil), "k8s.io.api.flowcontrol.v1beta3.Subject") + proto.RegisterType((*UserSubject)(nil), "k8s.io.api.flowcontrol.v1beta3.UserSubject") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto", fileDescriptor_803504887082f044) +} + +var fileDescriptor_803504887082f044 = []byte{ + // 1552 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0xdb, 0x46, + 0x13, 0x36, 0x65, 0xc9, 0xb6, 0xd6, 0x9f, 0x59, 0xc7, 0xb0, 0x5e, 0x07, 0x90, 0x1c, 0xbe, 0xc0, + 0x9b, 0xb7, 0x4d, 0x42, 0xe5, 0xb3, 0x49, 0x5b, 0xf4, 0x23, 0x74, 0xda, 0x34, 0x8d, 0xed, 0x38, + 0xeb, 0xa4, 0x2d, 0xd2, 0x00, 0x0d, 0x45, 0xad, 0xa9, 0x8d, 0x25, 0x92, 0xd9, 0x25, 0x65, 0xb8, + 0xb9, 0x14, 0xfd, 0x05, 0x3d, 0xb7, 0xc7, 0x1e, 0x7a, 0xef, 0x1f, 0xe8, 0xb1, 0x41, 0x4f, 0x39, + 0xe6, 0xa4, 0x36, 0xea, 0xa9, 0xff, 0xa0, 0x0d, 0x50, 0xa0, 0xd8, 0xe5, 0x92, 0x14, 0xa9, 0x0f, + 0x0a, 0x09, 0x90, 0x53, 0x6f, 0xe6, 0xcc, 0x33, 0xcf, 0xec, 0xcc, 0xce, 0xcc, 0x8e, 0x0c, 0xae, + 0xed, 0x5f, 0x66, 0x1a, 0x71, 0xaa, 0xfb, 0x7e, 0x0d, 0x53, 0x1b, 0x7b, 0x98, 0x55, 0xdb, 0xd8, + 0xae, 0x3b, 0xb4, 0x2a, 0x15, 0x86, 0x4b, 0xaa, 0x7b, 0x4d, 0xe7, 0xc0, 0x74, 0x6c, 0x8f, 0x3a, + 0xcd, 0x6a, 0xfb, 0x6c, 0x0d, 0x7b, 0xc6, 0xf9, 0xaa, 0x85, 0x6d, 0x4c, 0x0d, 0x0f, 0xd7, 0x35, + 0x97, 0x3a, 0x9e, 0x03, 0xcb, 0x01, 0x5e, 0x33, 0x5c, 0xa2, 0xf5, 0xe0, 0x35, 0x89, 0x5f, 0x3b, + 0x6d, 0x11, 0xaf, 0xe1, 0xd7, 0x34, 0xd3, 0x69, 0x55, 0x2d, 0xc7, 0x72, 0xaa, 0xc2, 0xac, 0xe6, + 0xef, 0x89, 0x2f, 0xf1, 0x21, 0xfe, 0x0a, 0xe8, 0xd6, 0x2e, 0xc4, 0xee, 0x5b, 0x86, 0xd9, 0x20, + 0x36, 0xa6, 0x87, 0x55, 0x77, 0xdf, 0xe2, 0x02, 0x56, 0x6d, 0x61, 0xcf, 0xa8, 0xb6, 0xcf, 0xa6, + 0x0f, 0xb1, 0x56, 0x1d, 0x66, 0x45, 0x7d, 0xdb, 0x23, 0x2d, 0xdc, 0x67, 0xf0, 0x46, 0x96, 0x01, + 0x33, 0x1b, 0xb8, 0x65, 0xa4, 0xed, 0xd4, 0xbb, 0x60, 0xf5, 0xc3, 0xa6, 0x73, 0x70, 0x95, 0x30, + 0x8f, 0xd8, 0x96, 0x4f, 0x58, 0x03, 0xd3, 0x2d, 0xec, 0x35, 0x9c, 0x3a, 0x7c, 0x0f, 0xe4, 0xbd, + 0x43, 0x17, 0x97, 0x94, 0x75, 0xe5, 0xff, 0x45, 0xfd, 0xe4, 0xe3, 0x4e, 0x65, 0xa2, 0xdb, 0xa9, + 0xe4, 0x6f, 0x1f, 0xba, 0xf8, 0x79, 0xa7, 0x72, 0x6c, 0x88, 0x19, 0x57, 0x23, 0x61, 0xa8, 0x7e, + 0x9b, 0x03, 0x80, 0xa3, 0x76, 0x85, 0x6b, 0x78, 0x1f, 0xcc, 0xf0, 0x70, 0xeb, 0x86, 0x67, 0x08, + 0xce, 0xd9, 0x73, 0x67, 0xb4, 0x38, 0xd7, 0xd1, 0xa9, 0x35, 0x77, 0xdf, 0xe2, 0x02, 0xa6, 0x71, + 0xb4, 0xd6, 0x3e, 0xab, 0xdd, 0xac, 0x3d, 0xc0, 0xa6, 0xb7, 0x85, 0x3d, 0x43, 0x87, 0xf2, 0x14, + 0x20, 0x96, 0xa1, 0x88, 0x15, 0xee, 0x80, 0x3c, 0x73, 0xb1, 0x59, 0xca, 0x09, 0x76, 0x4d, 0x1b, + 0x7d, 0x93, 0x5a, 0x7c, 0xb6, 0x5d, 0x17, 0x9b, 0xfa, 0x5c, 0x18, 0x21, 0xff, 0x42, 0x82, 0x09, + 0x7e, 0x06, 0xa6, 0x98, 0x67, 0x78, 0x3e, 0x2b, 0x4d, 0xf6, 0x9d, 0x38, 0x8b, 0x53, 0xd8, 0xe9, + 0x0b, 0x92, 0x75, 0x2a, 0xf8, 0x46, 0x92, 0x4f, 0x7d, 0x9a, 0x03, 0xcb, 0x31, 0x78, 0xc3, 0xb1, + 0xeb, 0xc4, 0x23, 0x8e, 0x0d, 0xdf, 0x4e, 0x64, 0xfd, 0x44, 0x2a, 0xeb, 0xab, 0x03, 0x4c, 0xe2, + 0x8c, 0xc3, 0x37, 0xa3, 0xe3, 0xe6, 0x84, 0xf9, 0xf1, 0xa4, 0xf3, 0xe7, 0x9d, 0xca, 0x62, 0x64, + 0x96, 0x3c, 0x0f, 0x6c, 0x03, 0xd8, 0x34, 0x98, 0x77, 0x9b, 0x1a, 0x36, 0x0b, 0x68, 0x49, 0x0b, + 0xcb, 0xa8, 0x5f, 0x1f, 0xef, 0x9e, 0xb8, 0x85, 0xbe, 0x26, 0x5d, 0xc2, 0xcd, 0x3e, 0x36, 0x34, + 0xc0, 0x03, 0xfc, 0x1f, 0x98, 0xa2, 0xd8, 0x60, 0x8e, 0x5d, 0xca, 0x8b, 0x23, 0x47, 0xf9, 0x42, + 0x42, 0x8a, 0xa4, 0x16, 0xbe, 0x06, 0xa6, 0x5b, 0x98, 0x31, 0xc3, 0xc2, 0xa5, 0x82, 0x00, 0x2e, + 0x4a, 0xe0, 0xf4, 0x56, 0x20, 0x46, 0xa1, 0x5e, 0xfd, 0x49, 0x01, 0x0b, 0x71, 0x9e, 0x36, 0x09, + 0xf3, 0xe0, 0xbd, 0xbe, 0xda, 0xd3, 0xc6, 0x8b, 0x89, 0x5b, 0x8b, 0xca, 0x5b, 0x92, 0xee, 0x66, + 0x42, 0x49, 0x4f, 0xdd, 0xdd, 0x04, 0x05, 0xe2, 0xe1, 0x16, 0xcf, 0xfa, 0x64, 0x2a, 0x5d, 0x19, + 0x45, 0xa2, 0xcf, 0x4b, 0xda, 0xc2, 0x75, 0x4e, 0x80, 0x02, 0x1e, 0xf5, 0x8f, 0xc9, 0xde, 0x08, + 0x78, 0x3d, 0xc2, 0x1f, 0x14, 0xb0, 0xe6, 0x52, 0xe2, 0x50, 0xe2, 0x1d, 0x6e, 0xe2, 0x36, 0x6e, + 0x6e, 0x38, 0xf6, 0x1e, 0xb1, 0x7c, 0x6a, 0xf0, 0x54, 0xca, 0xa0, 0x36, 0xb2, 0x3c, 0xef, 0x0c, + 0x65, 0x40, 0x78, 0x0f, 0x53, 0x6c, 0x9b, 0x58, 0x57, 0xe5, 0x91, 0xd6, 0x46, 0x80, 0x47, 0x1c, + 0x05, 0x7e, 0x0c, 0x60, 0xcb, 0xf0, 0x78, 0x46, 0xad, 0x1d, 0x8a, 0x4d, 0x5c, 0xe7, 0xac, 0xa2, + 0x20, 0x0b, 0x71, 0x75, 0x6c, 0xf5, 0x21, 0xd0, 0x00, 0x2b, 0xf8, 0xb5, 0x02, 0x96, 0xeb, 0xfd, + 0x43, 0x46, 0xd6, 0xe5, 0xa5, 0x71, 0x12, 0x3d, 0x60, 0x46, 0xe9, 0xab, 0xdd, 0x4e, 0x65, 0x79, + 0x80, 0x02, 0x0d, 0x72, 0x06, 0xef, 0x81, 0x02, 0xf5, 0x9b, 0x98, 0x95, 0xf2, 0xe2, 0x7a, 0x33, + 0xbd, 0xee, 0x38, 0x4d, 0x62, 0x1e, 0x22, 0x6e, 0xf2, 0x29, 0xf1, 0x1a, 0xbb, 0xbe, 0x98, 0x55, + 0x2c, 0xbe, 0x6b, 0xa1, 0x42, 0x01, 0xa9, 0xfa, 0x08, 0x2c, 0xa5, 0x87, 0x06, 0xb4, 0x00, 0x30, + 0xc3, 0x3e, 0x65, 0x25, 0x45, 0xb8, 0x3d, 0x3f, 0x7e, 0x55, 0x45, 0x3d, 0x1e, 0xcf, 0xcb, 0x48, + 0xc4, 0x50, 0x0f, 0xb5, 0x7a, 0x06, 0xcc, 0x5d, 0xa3, 0x8e, 0xef, 0xca, 0x33, 0xc2, 0x75, 0x90, + 0xb7, 0x8d, 0x56, 0x38, 0x7d, 0xa2, 0x89, 0xb8, 0x6d, 0xb4, 0x30, 0x12, 0x1a, 0xf5, 0x7b, 0x05, + 0xcc, 0x6f, 0x92, 0x16, 0xf1, 0x10, 0x66, 0xae, 0x63, 0x33, 0x0c, 0x2f, 0x26, 0x26, 0xd6, 0xf1, + 0xd4, 0xc4, 0x3a, 0x92, 0x00, 0xf7, 0xcc, 0xaa, 0xcf, 0xc1, 0xf4, 0x43, 0x1f, 0xfb, 0xc4, 0xb6, + 0xe4, 0xbc, 0xbe, 0x90, 0x15, 0xe0, 0xad, 0x00, 0x9e, 0xa8, 0x36, 0x7d, 0x96, 0x8f, 0x00, 0xa9, + 0x41, 0x21, 0xa3, 0xfa, 0x77, 0x0e, 0x1c, 0x17, 0x8e, 0x71, 0x7d, 0x78, 0x15, 0xc3, 0x7b, 0xa0, + 0x64, 0x3b, 0x2d, 0x62, 0x1b, 0x5c, 0x6e, 0xfa, 0x94, 0xd7, 0xff, 0xe1, 0x6e, 0xc3, 0xa0, 0x98, + 0x89, 0x68, 0x0a, 0xfa, 0xba, 0x8c, 0xa6, 0xb4, 0x3d, 0x04, 0x87, 0x86, 0x32, 0xc0, 0x07, 0x60, + 0xbe, 0xd9, 0x1b, 0xbb, 0x0c, 0xf3, 0x74, 0x56, 0x98, 0x89, 0x84, 0xe9, 0x2b, 0xf2, 0x04, 0xc9, + 0xa4, 0xa3, 0x24, 0x35, 0x7c, 0x07, 0x2c, 0x36, 0xb1, 0x5d, 0x37, 0x6a, 0x4d, 0xbc, 0x83, 0xa9, + 0x89, 0x6d, 0x4f, 0xb4, 0x48, 0x41, 0x5f, 0xee, 0x76, 0x2a, 0x8b, 0x9b, 0x49, 0x15, 0x4a, 0x63, + 0xe1, 0x4d, 0xb0, 0x52, 0x73, 0x28, 0x75, 0x0e, 0x88, 0x6d, 0x09, 0x3f, 0x21, 0x49, 0x5e, 0x90, + 0xfc, 0xa7, 0xdb, 0xa9, 0xac, 0xe8, 0x83, 0x00, 0x68, 0xb0, 0x9d, 0x7a, 0x00, 0x56, 0xb6, 0xf9, + 0x4c, 0x61, 0x8e, 0x4f, 0x4d, 0x1c, 0x37, 0x04, 0xac, 0x80, 0x42, 0x1b, 0xd3, 0x5a, 0x50, 0xd4, + 0x45, 0xbd, 0xc8, 0xdb, 0xe1, 0x13, 0x2e, 0x40, 0x81, 0x9c, 0x47, 0x62, 0xc7, 0x96, 0x77, 0xd0, + 0x26, 0x2b, 0x4d, 0x09, 0xa8, 0x88, 0x64, 0x3b, 0xa9, 0x42, 0x69, 0xac, 0xda, 0xc9, 0x81, 0xd5, + 0x21, 0xfd, 0x07, 0xef, 0x80, 0x19, 0x26, 0xff, 0x96, 0x3d, 0x75, 0x22, 0xeb, 0x2e, 0xa4, 0x6d, + 0x3c, 0xfd, 0x43, 0x32, 0x14, 0x51, 0x41, 0x07, 0xcc, 0x53, 0x79, 0x04, 0xe1, 0x53, 0xbe, 0x02, + 0xe7, 0xb2, 0xb8, 0xfb, 0xb3, 0x13, 0x5f, 0x36, 0xea, 0x25, 0x44, 0x49, 0x7e, 0xf8, 0x08, 0x2c, + 0xf5, 0x84, 0x1d, 0xf8, 0x9c, 0x14, 0x3e, 0x2f, 0x66, 0xf9, 0x1c, 0x78, 0x29, 0x7a, 0x49, 0xba, + 0x5d, 0xda, 0x4e, 0xd1, 0xa2, 0x3e, 0x47, 0xea, 0x2f, 0x39, 0x30, 0xe2, 0x61, 0x78, 0x05, 0x4b, + 0xde, 0xfd, 0xc4, 0x92, 0xf7, 0xee, 0x8b, 0xbf, 0x78, 0x43, 0x97, 0xbe, 0x46, 0x6a, 0xe9, 0x7b, + 0xff, 0x25, 0x7c, 0x8c, 0x5e, 0x02, 0xff, 0xcc, 0x81, 0xff, 0x0e, 0x37, 0x8e, 0x97, 0xc2, 0x1b, + 0x89, 0x11, 0x7b, 0x29, 0x35, 0x62, 0x4f, 0x8c, 0x41, 0xf1, 0xef, 0x92, 0x98, 0x5a, 0x12, 0x7f, + 0x55, 0x40, 0x79, 0x78, 0xde, 0x5e, 0xc1, 0xd2, 0xf8, 0x45, 0x72, 0x69, 0x7c, 0xeb, 0xc5, 0x8b, + 0x6c, 0xc8, 0x12, 0x79, 0x6d, 0x54, 0x6d, 0x45, 0xeb, 0xde, 0x18, 0x4f, 0xfe, 0xcf, 0x23, 0x53, + 0x25, 0xb6, 0xd3, 0x8c, 0x5f, 0x2d, 0x09, 0xeb, 0x0f, 0x6c, 0xfe, 0xf4, 0xb4, 0xf8, 0xeb, 0x11, + 0x14, 0x64, 0x03, 0x4c, 0x37, 0x83, 0xb7, 0x5a, 0x36, 0xf5, 0x95, 0xb1, 0x9e, 0xc8, 0x51, 0x4f, + 0x7b, 0xb0, 0x16, 0x48, 0x18, 0x0a, 0xe9, 0xd5, 0xef, 0x14, 0xb0, 0x9e, 0xd5, 0xac, 0xf0, 0x60, + 0xc0, 0xf2, 0xf5, 0x12, 0x8b, 0xf5, 0xf8, 0xcb, 0xd8, 0x8f, 0x0a, 0x38, 0x3a, 0x68, 0xc7, 0xe1, + 0xe5, 0xcf, 0x17, 0x9b, 0x68, 0x2b, 0x89, 0xca, 0xff, 0x96, 0x90, 0x22, 0xa9, 0x85, 0xa7, 0xc0, + 0x4c, 0xc3, 0xb0, 0xeb, 0xbb, 0xe4, 0xcb, 0x70, 0xdf, 0x8e, 0x0a, 0xf0, 0x23, 0x29, 0x47, 0x11, + 0x02, 0x5e, 0x05, 0x4b, 0xc2, 0x6e, 0x13, 0xdb, 0x96, 0xd7, 0x10, 0xb9, 0x92, 0x4b, 0x43, 0xf4, + 0x1e, 0xdc, 0x4a, 0xe9, 0x51, 0x9f, 0x85, 0xfa, 0x97, 0x02, 0xe0, 0x8b, 0xbc, 0xf3, 0x27, 0x41, + 0xd1, 0x70, 0x89, 0x58, 0x3e, 0x83, 0x16, 0x28, 0xea, 0xf3, 0xdd, 0x4e, 0xa5, 0x78, 0x65, 0xe7, + 0x7a, 0x20, 0x44, 0xb1, 0x9e, 0x83, 0xc3, 0x27, 0x30, 0x78, 0xea, 0x24, 0x38, 0x74, 0xcc, 0x50, + 0xac, 0x87, 0x97, 0xc1, 0x9c, 0xd9, 0xf4, 0x99, 0x87, 0xe9, 0xae, 0xe9, 0xb8, 0x58, 0x8c, 0x8c, + 0x19, 0xfd, 0xa8, 0x8c, 0x69, 0x6e, 0xa3, 0x47, 0x87, 0x12, 0x48, 0xa8, 0x01, 0xc0, 0x0b, 0x9e, + 0xb9, 0x06, 0xf7, 0x53, 0x10, 0x7e, 0x16, 0xf8, 0x85, 0x6d, 0x47, 0x52, 0xd4, 0x83, 0x50, 0x1f, + 0x80, 0x95, 0x5d, 0x4c, 0xdb, 0xc4, 0xc4, 0x57, 0x4c, 0xd3, 0xf1, 0x6d, 0x2f, 0x5c, 0xa3, 0xab, + 0xa0, 0x18, 0xc1, 0x64, 0x4f, 0x1c, 0x91, 0xfe, 0x8b, 0x11, 0x17, 0x8a, 0x31, 0x51, 0x13, 0xe6, + 0x86, 0x37, 0x61, 0x0e, 0x4c, 0xc7, 0xf4, 0xf9, 0x7d, 0x62, 0xd7, 0x25, 0xf3, 0xb1, 0x10, 0x7d, + 0x83, 0xd8, 0xf5, 0xe7, 0x9d, 0xca, 0xac, 0x84, 0xf1, 0x4f, 0x24, 0x80, 0xf0, 0x3a, 0xc8, 0xfb, + 0x0c, 0x53, 0xd9, 0x5e, 0x27, 0xb3, 0x8a, 0xf9, 0x0e, 0xc3, 0x34, 0xdc, 0x7c, 0x66, 0x38, 0x33, + 0x17, 0x20, 0x41, 0x01, 0xb7, 0x40, 0xc1, 0xe2, 0x97, 0x22, 0xa7, 0xfe, 0xa9, 0x2c, 0xae, 0xde, + 0x9f, 0x17, 0x41, 0x19, 0x08, 0x09, 0x0a, 0x58, 0xe0, 0x43, 0xb0, 0xc0, 0x12, 0x29, 0x14, 0xd7, + 0x35, 0xc6, 0x26, 0x33, 0x30, 0xf1, 0x3a, 0xec, 0x76, 0x2a, 0x0b, 0x49, 0x15, 0x4a, 0x39, 0x50, + 0xab, 0x60, 0xb6, 0x27, 0xc0, 0xec, 0xf9, 0xa7, 0x5f, 0x7d, 0xfc, 0xac, 0x3c, 0xf1, 0xe4, 0x59, + 0x79, 0xe2, 0xe9, 0xb3, 0xf2, 0xc4, 0x57, 0xdd, 0xb2, 0xf2, 0xb8, 0x5b, 0x56, 0x9e, 0x74, 0xcb, + 0xca, 0xd3, 0x6e, 0x59, 0xf9, 0xad, 0x5b, 0x56, 0xbe, 0xf9, 0xbd, 0x3c, 0x71, 0xb7, 0x3c, 0xfa, + 0xff, 0x8c, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x98, 0x4a, 0x24, 0x86, 0xa1, 0x14, 0x00, 0x00, +} + +func (m *FlowDistinguisherMethod) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowDistinguisherMethod) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowDistinguisherMethod) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FlowSchema) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowSchema) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowSchema) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FlowSchemaCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowSchemaCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowSchemaCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x2a + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x22 + { + size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + i -= len(m.Status) + copy(dAtA[i:], m.Status) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) + i-- + dAtA[i] = 0x12 + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FlowSchemaList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowSchemaList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowSchemaList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FlowSchemaSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowSchemaSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowSchemaSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.DistinguisherMethod != nil { + { + size, err := m.DistinguisherMethod.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + i = encodeVarintGenerated(dAtA, i, uint64(m.MatchingPrecedence)) + i-- + dAtA[i] = 0x10 + { + size, err := m.PriorityLevelConfiguration.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *FlowSchemaStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FlowSchemaStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FlowSchemaStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *GroupSubject) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GroupSubject) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GroupSubject) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *LimitResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LimitResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LimitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Queuing != nil { + { + size, err := m.Queuing.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *LimitedPriorityLevelConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LimitedPriorityLevelConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LimitedPriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BorrowingLimitPercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.BorrowingLimitPercent)) + i-- + dAtA[i] = 0x20 + } + if m.LendablePercent != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.LendablePercent)) + i-- + dAtA[i] = 0x18 + } + { + size, err := m.LimitResponse.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i = encodeVarintGenerated(dAtA, i, uint64(m.NominalConcurrencyShares)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func (m *NonResourcePolicyRule) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NonResourcePolicyRule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NonResourcePolicyRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NonResourceURLs) > 0 { + for iNdEx := len(m.NonResourceURLs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.NonResourceURLs[iNdEx]) + copy(dAtA[i:], m.NonResourceURLs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NonResourceURLs[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } + if len(m.Verbs) > 0 { + for iNdEx := len(m.Verbs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Verbs[iNdEx]) + copy(dAtA[i:], m.Verbs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Verbs[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PolicyRulesWithSubjects) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PolicyRulesWithSubjects) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PolicyRulesWithSubjects) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NonResourceRules) > 0 { + for iNdEx := len(m.NonResourceRules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.NonResourceRules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.ResourceRules) > 0 { + for iNdEx := len(m.ResourceRules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceRules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Subjects) > 0 { + for iNdEx := len(m.Subjects) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Subjects[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfigurationCondition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfigurationCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfigurationCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x2a + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x22 + { + size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + i -= len(m.Status) + copy(dAtA[i:], m.Status) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) + i-- + dAtA[i] = 0x12 + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfigurationList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfigurationList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfigurationReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfigurationReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfigurationReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfigurationSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfigurationSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfigurationSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Limited != nil { + { + size, err := m.Limited.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PriorityLevelConfigurationStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PriorityLevelConfigurationStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriorityLevelConfigurationStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueuingConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueuingConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueuingConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.QueueLengthLimit)) + i-- + dAtA[i] = 0x18 + i = encodeVarintGenerated(dAtA, i, uint64(m.HandSize)) + i-- + dAtA[i] = 0x10 + i = encodeVarintGenerated(dAtA, i, uint64(m.Queues)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func (m *ResourcePolicyRule) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourcePolicyRule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourcePolicyRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Namespaces) > 0 { + for iNdEx := len(m.Namespaces) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Namespaces[iNdEx]) + copy(dAtA[i:], m.Namespaces[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespaces[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + i-- + if m.ClusterScope { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + if len(m.Resources) > 0 { + for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Resources[iNdEx]) + copy(dAtA[i:], m.Resources[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.APIGroups) > 0 { + for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.APIGroups[iNdEx]) + copy(dAtA[i:], m.APIGroups[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Verbs) > 0 { + for iNdEx := len(m.Verbs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Verbs[iNdEx]) + copy(dAtA[i:], m.Verbs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Verbs[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ServiceAccountSubject) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServiceAccountSubject) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServiceAccountSubject) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Subject) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Subject) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Subject) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ServiceAccount != nil { + { + size, err := m.ServiceAccount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Group != nil { + { + size, err := m.Group.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.User != nil { + { + size, err := m.User.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *UserSubject) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UserSubject) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UserSubject) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *FlowDistinguisherMethod) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *FlowSchema) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *FlowSchemaCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Status) + n += 1 + l + sovGenerated(uint64(l)) + l = m.LastTransitionTime.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Reason) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *FlowSchemaList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *FlowSchemaSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.PriorityLevelConfiguration.Size() + n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.MatchingPrecedence)) + if m.DistinguisherMethod != nil { + l = m.DistinguisherMethod.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.Rules) > 0 { + for _, e := range m.Rules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *FlowSchemaStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *GroupSubject) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *LimitResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + if m.Queuing != nil { + l = m.Queuing.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *LimitedPriorityLevelConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.NominalConcurrencyShares)) + l = m.LimitResponse.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.LendablePercent != nil { + n += 1 + sovGenerated(uint64(*m.LendablePercent)) + } + if m.BorrowingLimitPercent != nil { + n += 1 + sovGenerated(uint64(*m.BorrowingLimitPercent)) + } + return n +} + +func (m *NonResourcePolicyRule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Verbs) > 0 { + for _, s := range m.Verbs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.NonResourceURLs) > 0 { + for _, s := range m.NonResourceURLs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PolicyRulesWithSubjects) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subjects) > 0 { + for _, e := range m.Subjects { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.ResourceRules) > 0 { + for _, e := range m.ResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.NonResourceRules) > 0 { + for _, e := range m.NonResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PriorityLevelConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PriorityLevelConfigurationCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Status) + n += 1 + l + sovGenerated(uint64(l)) + l = m.LastTransitionTime.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Reason) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PriorityLevelConfigurationList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PriorityLevelConfigurationReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PriorityLevelConfigurationSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovGenerated(uint64(l)) + if m.Limited != nil { + l = m.Limited.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *PriorityLevelConfigurationStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *QueuingConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Queues)) + n += 1 + sovGenerated(uint64(m.HandSize)) + n += 1 + sovGenerated(uint64(m.QueueLengthLimit)) + return n +} + +func (m *ResourcePolicyRule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Verbs) > 0 { + for _, s := range m.Verbs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.APIGroups) > 0 { + for _, s := range m.APIGroups { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Resources) > 0 { + for _, s := range m.Resources { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + n += 2 + if len(m.Namespaces) > 0 { + for _, s := range m.Namespaces { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ServiceAccountSubject) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Subject) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + if m.User != nil { + l = m.User.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Group != nil { + l = m.Group.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ServiceAccount != nil { + l = m.ServiceAccount.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *UserSubject) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *FlowDistinguisherMethod) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&FlowDistinguisherMethod{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `}`, + }, "") + return s +} +func (this *FlowSchema) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&FlowSchema{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "FlowSchemaSpec", "FlowSchemaSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "FlowSchemaStatus", "FlowSchemaStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *FlowSchemaCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&FlowSchemaCondition{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Status:` + fmt.Sprintf("%v", this.Status) + `,`, + `LastTransitionTime:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, + `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `}`, + }, "") + return s +} +func (this *FlowSchemaList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]FlowSchema{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "FlowSchema", "FlowSchema", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&FlowSchemaList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *FlowSchemaSpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForRules := "[]PolicyRulesWithSubjects{" + for _, f := range this.Rules { + repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "PolicyRulesWithSubjects", "PolicyRulesWithSubjects", 1), `&`, ``, 1) + "," + } + repeatedStringForRules += "}" + s := strings.Join([]string{`&FlowSchemaSpec{`, + `PriorityLevelConfiguration:` + strings.Replace(strings.Replace(this.PriorityLevelConfiguration.String(), "PriorityLevelConfigurationReference", "PriorityLevelConfigurationReference", 1), `&`, ``, 1) + `,`, + `MatchingPrecedence:` + fmt.Sprintf("%v", this.MatchingPrecedence) + `,`, + `DistinguisherMethod:` + strings.Replace(this.DistinguisherMethod.String(), "FlowDistinguisherMethod", "FlowDistinguisherMethod", 1) + `,`, + `Rules:` + repeatedStringForRules + `,`, + `}`, + }, "") + return s +} +func (this *FlowSchemaStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]FlowSchemaCondition{" + for _, f := range this.Conditions { + repeatedStringForConditions += strings.Replace(strings.Replace(f.String(), "FlowSchemaCondition", "FlowSchemaCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&FlowSchemaStatus{`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} +func (this *GroupSubject) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GroupSubject{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *LimitResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LimitResponse{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Queuing:` + strings.Replace(this.Queuing.String(), "QueuingConfiguration", "QueuingConfiguration", 1) + `,`, + `}`, + }, "") + return s +} +func (this *LimitedPriorityLevelConfiguration) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LimitedPriorityLevelConfiguration{`, + `NominalConcurrencyShares:` + fmt.Sprintf("%v", this.NominalConcurrencyShares) + `,`, + `LimitResponse:` + strings.Replace(strings.Replace(this.LimitResponse.String(), "LimitResponse", "LimitResponse", 1), `&`, ``, 1) + `,`, + `LendablePercent:` + valueToStringGenerated(this.LendablePercent) + `,`, + `BorrowingLimitPercent:` + valueToStringGenerated(this.BorrowingLimitPercent) + `,`, + `}`, + }, "") + return s +} +func (this *NonResourcePolicyRule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NonResourcePolicyRule{`, + `Verbs:` + fmt.Sprintf("%v", this.Verbs) + `,`, + `NonResourceURLs:` + fmt.Sprintf("%v", this.NonResourceURLs) + `,`, + `}`, + }, "") + return s +} +func (this *PolicyRulesWithSubjects) String() string { + if this == nil { + return "nil" + } + repeatedStringForSubjects := "[]Subject{" + for _, f := range this.Subjects { + repeatedStringForSubjects += strings.Replace(strings.Replace(f.String(), "Subject", "Subject", 1), `&`, ``, 1) + "," + } + repeatedStringForSubjects += "}" + repeatedStringForResourceRules := "[]ResourcePolicyRule{" + for _, f := range this.ResourceRules { + repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "ResourcePolicyRule", "ResourcePolicyRule", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceRules += "}" + repeatedStringForNonResourceRules := "[]NonResourcePolicyRule{" + for _, f := range this.NonResourceRules { + repeatedStringForNonResourceRules += strings.Replace(strings.Replace(f.String(), "NonResourcePolicyRule", "NonResourcePolicyRule", 1), `&`, ``, 1) + "," + } + repeatedStringForNonResourceRules += "}" + s := strings.Join([]string{`&PolicyRulesWithSubjects{`, + `Subjects:` + repeatedStringForSubjects + `,`, + `ResourceRules:` + repeatedStringForResourceRules + `,`, + `NonResourceRules:` + repeatedStringForNonResourceRules + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfiguration) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PriorityLevelConfiguration{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PriorityLevelConfigurationSpec", "PriorityLevelConfigurationSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "PriorityLevelConfigurationStatus", "PriorityLevelConfigurationStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfigurationCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PriorityLevelConfigurationCondition{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Status:` + fmt.Sprintf("%v", this.Status) + `,`, + `LastTransitionTime:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, + `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfigurationList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]PriorityLevelConfiguration{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PriorityLevelConfiguration", "PriorityLevelConfiguration", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&PriorityLevelConfigurationList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfigurationReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PriorityLevelConfigurationReference{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfigurationSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PriorityLevelConfigurationSpec{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Limited:` + strings.Replace(this.Limited.String(), "LimitedPriorityLevelConfiguration", "LimitedPriorityLevelConfiguration", 1) + `,`, + `}`, + }, "") + return s +} +func (this *PriorityLevelConfigurationStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]PriorityLevelConfigurationCondition{" + for _, f := range this.Conditions { + repeatedStringForConditions += strings.Replace(strings.Replace(f.String(), "PriorityLevelConfigurationCondition", "PriorityLevelConfigurationCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&PriorityLevelConfigurationStatus{`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} +func (this *QueuingConfiguration) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QueuingConfiguration{`, + `Queues:` + fmt.Sprintf("%v", this.Queues) + `,`, + `HandSize:` + fmt.Sprintf("%v", this.HandSize) + `,`, + `QueueLengthLimit:` + fmt.Sprintf("%v", this.QueueLengthLimit) + `,`, + `}`, + }, "") + return s +} +func (this *ResourcePolicyRule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourcePolicyRule{`, + `Verbs:` + fmt.Sprintf("%v", this.Verbs) + `,`, + `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`, + `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`, + `ClusterScope:` + fmt.Sprintf("%v", this.ClusterScope) + `,`, + `Namespaces:` + fmt.Sprintf("%v", this.Namespaces) + `,`, + `}`, + }, "") + return s +} +func (this *ServiceAccountSubject) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ServiceAccountSubject{`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *Subject) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Subject{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `User:` + strings.Replace(this.User.String(), "UserSubject", "UserSubject", 1) + `,`, + `Group:` + strings.Replace(this.Group.String(), "GroupSubject", "GroupSubject", 1) + `,`, + `ServiceAccount:` + strings.Replace(this.ServiceAccount.String(), "ServiceAccountSubject", "ServiceAccountSubject", 1) + `,`, + `}`, + }, "") + return s +} +func (this *UserSubject) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&UserSubject{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *FlowDistinguisherMethod) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowDistinguisherMethod: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowDistinguisherMethod: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = FlowDistinguisherMethodType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FlowSchema) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowSchema: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowSchema: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FlowSchemaCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowSchemaCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowSchemaCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = FlowSchemaConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FlowSchemaList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowSchemaList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowSchemaList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, FlowSchema{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FlowSchemaSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowSchemaSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowSchemaSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriorityLevelConfiguration", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PriorityLevelConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchingPrecedence", wireType) + } + m.MatchingPrecedence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MatchingPrecedence |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistinguisherMethod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DistinguisherMethod == nil { + m.DistinguisherMethod = &FlowDistinguisherMethod{} + } + if err := m.DistinguisherMethod.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rules = append(m.Rules, PolicyRulesWithSubjects{}) + if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FlowSchemaStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FlowSchemaStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FlowSchemaStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, FlowSchemaCondition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GroupSubject) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GroupSubject: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GroupSubject: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LimitResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LimitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LimitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = LimitResponseType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Queuing", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Queuing == nil { + m.Queuing = &QueuingConfiguration{} + } + if err := m.Queuing.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LimitedPriorityLevelConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LimitedPriorityLevelConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LimitedPriorityLevelConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NominalConcurrencyShares", wireType) + } + m.NominalConcurrencyShares = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NominalConcurrencyShares |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LimitResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LimitResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LendablePercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LendablePercent = &v + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BorrowingLimitPercent", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BorrowingLimitPercent = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NonResourcePolicyRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NonResourcePolicyRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NonResourcePolicyRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NonResourceURLs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NonResourceURLs = append(m.NonResourceURLs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PolicyRulesWithSubjects) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PolicyRulesWithSubjects: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PolicyRulesWithSubjects: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subjects", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subjects = append(m.Subjects, Subject{}) + if err := m.Subjects[len(m.Subjects)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceRules = append(m.ResourceRules, ResourcePolicyRule{}) + if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NonResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NonResourceRules = append(m.NonResourceRules, NonResourcePolicyRule{}) + if err := m.NonResourceRules[len(m.NonResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfigurationCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfigurationCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfigurationCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = PriorityLevelConfigurationConditionType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = ConditionStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfigurationList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfigurationList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfigurationList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, PriorityLevelConfiguration{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfigurationReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfigurationReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfigurationReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfigurationSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfigurationSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfigurationSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = PriorityLevelEnablement(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limited", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Limited == nil { + m.Limited = &LimitedPriorityLevelConfiguration{} + } + if err := m.Limited.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityLevelConfigurationStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityLevelConfigurationStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityLevelConfigurationStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, PriorityLevelConfigurationCondition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueuingConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueuingConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueuingConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Queues", wireType) + } + m.Queues = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Queues |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HandSize", wireType) + } + m.HandSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HandSize |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field QueueLengthLimit", wireType) + } + m.QueueLengthLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.QueueLengthLimit |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourcePolicyRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourcePolicyRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourcePolicyRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroups", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIGroups = append(m.APIGroups, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterScope", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ClusterScope = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespaces", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespaces = append(m.Namespaces, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ServiceAccountSubject) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ServiceAccountSubject: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ServiceAccountSubject: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Subject) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subject: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subject: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = SubjectKind(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.User == nil { + m.User = &UserSubject{} + } + if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Group == nil { + m.Group = &GroupSubject{} + } + if err := m.Group.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServiceAccount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ServiceAccount == nil { + m.ServiceAccount = &ServiceAccountSubject{} + } + if err := m.ServiceAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UserSubject) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UserSubject: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UserSubject: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto new file mode 100644 index 00000000000..adf9e8682c4 --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto @@ -0,0 +1,473 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.flowcontrol.v1beta3; + +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/flowcontrol/v1beta3"; + +// FlowDistinguisherMethod specifies the method of a flow distinguisher. +message FlowDistinguisherMethod { + // `type` is the type of flow distinguisher method + // The supported types are "ByUser" and "ByNamespace". + // Required. + optional string type = 1; +} + +// FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with +// similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher". +message FlowSchema { + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // `spec` is the specification of the desired behavior of a FlowSchema. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional FlowSchemaSpec spec = 2; + + // `status` is the current status of a FlowSchema. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional FlowSchemaStatus status = 3; +} + +// FlowSchemaCondition describes conditions for a FlowSchema. +message FlowSchemaCondition { + // `type` is the type of the condition. + // Required. + optional string type = 1; + + // `status` is the status of the condition. + // Can be True, False, Unknown. + // Required. + optional string status = 2; + + // `lastTransitionTime` is the last time the condition transitioned from one status to another. + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; + + // `reason` is a unique, one-word, CamelCase reason for the condition's last transition. + optional string reason = 4; + + // `message` is a human-readable message indicating details about last transition. + optional string message = 5; +} + +// FlowSchemaList is a list of FlowSchema objects. +message FlowSchemaList { + // `metadata` is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // `items` is a list of FlowSchemas. + repeated FlowSchema items = 2; +} + +// FlowSchemaSpec describes how the FlowSchema's specification looks like. +message FlowSchemaSpec { + // `priorityLevelConfiguration` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot + // be resolved, the FlowSchema will be ignored and marked as invalid in its status. + // Required. + optional PriorityLevelConfigurationReference priorityLevelConfiguration = 1; + + // `matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen + // FlowSchema is among those with the numerically lowest (which we take to be logically highest) + // MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. + // Note that if the precedence is not specified, it will be set to 1000 as default. + // +optional + optional int32 matchingPrecedence = 2; + + // `distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. + // `nil` specifies that the distinguisher is disabled and thus will always be the empty string. + // +optional + optional FlowDistinguisherMethod distinguisherMethod = 3; + + // `rules` describes which requests will match this flow schema. This FlowSchema matches a request if and only if + // at least one member of rules matches the request. + // if it is an empty slice, there will be no requests matching the FlowSchema. + // +listType=atomic + // +optional + repeated PolicyRulesWithSubjects rules = 4; +} + +// FlowSchemaStatus represents the current state of a FlowSchema. +message FlowSchemaStatus { + // `conditions` is a list of the current states of FlowSchema. + // +listType=map + // +listMapKey=type + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + repeated FlowSchemaCondition conditions = 1; +} + +// GroupSubject holds detailed information for group-kind subject. +message GroupSubject { + // name is the user group that matches, or "*" to match all user groups. + // See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some + // well-known group names. + // Required. + optional string name = 1; +} + +// LimitResponse defines how to handle requests that can not be executed right now. +// +union +message LimitResponse { + // `type` is "Queue" or "Reject". + // "Queue" means that requests that can not be executed upon arrival + // are held in a queue until they can be executed or a queuing limit + // is reached. + // "Reject" means that requests that can not be executed upon arrival + // are rejected. + // Required. + // +unionDiscriminator + optional string type = 1; + + // `queuing` holds the configuration parameters for queuing. + // This field may be non-empty only if `type` is `"Queue"`. + // +optional + optional QueuingConfiguration queuing = 2; +} + +// LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. +// It addresses two issues: +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? +message LimitedPriorityLevelConfiguration { + // `nominalConcurrencyShares` (NCS) contributes to the computation of the + // NominalConcurrencyLimit (NominalCL) of this level. + // This is the number of execution seats available at this priority level. + // This is used both for requests dispatched from this priority level + // as well as requests dispatched from other priority levels + // borrowing seats from this level. + // The server's concurrency limit (ServerCL) is divided among the + // Limited priority levels in proportion to their NCS values: + // + // NominalCL(i) = ceil( ServerCL * NCS(i) / sum_ncs ) + // sum_ncs = sum[limited priority level k] NCS(k) + // + // Bigger numbers mean a larger nominal concurrency limit, + // at the expense of every other Limited priority level. + // This field has a default value of 30. + // +optional + optional int32 nominalConcurrencyShares = 1; + + // `limitResponse` indicates what to do with requests that can not be executed right now + optional LimitResponse limitResponse = 2; + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + optional int32 lendablePercent = 3; + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + optional int32 borrowingLimitPercent = 4; +} + +// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the +// target non-resource URL. A NonResourcePolicyRule matches a request if and only if both (a) at least one member +// of verbs matches the request and (b) at least one member of nonResourceURLs matches the request. +message NonResourcePolicyRule { + // `verbs` is a list of matching verbs and may not be empty. + // "*" matches all verbs. If it is present, it must be the only entry. + // +listType=set + // Required. + repeated string verbs = 1; + + // `nonResourceURLs` is a set of url prefixes that a user should have access to and may not be empty. + // For example: + // - "/healthz" is legal + // - "/hea*" is illegal + // - "/hea" is legal but matches nothing + // - "/hea/*" also matches nothing + // - "/healthz/*" matches all per-component health checks. + // "*" matches all non-resource urls. if it is present, it must be the only entry. + // +listType=set + // Required. + repeated string nonResourceURLs = 6; +} + +// PolicyRulesWithSubjects prescribes a test that applies to a request to an apiserver. The test considers the subject +// making the request, the verb being requested, and the resource to be acted upon. This PolicyRulesWithSubjects matches +// a request if and only if both (a) at least one member of subjects matches the request and (b) at least one member +// of resourceRules or nonResourceRules matches the request. +message PolicyRulesWithSubjects { + // subjects is the list of normal user, serviceaccount, or group that this rule cares about. + // There must be at least one member in this slice. + // A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. + // +listType=atomic + // Required. + repeated Subject subjects = 1; + + // `resourceRules` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the + // target resource. + // At least one of `resourceRules` and `nonResourceRules` has to be non-empty. + // +listType=atomic + // +optional + repeated ResourcePolicyRule resourceRules = 2; + + // `nonResourceRules` is a list of NonResourcePolicyRules that identify matching requests according to their verb + // and the target non-resource URL. + // +listType=atomic + // +optional + repeated NonResourcePolicyRule nonResourceRules = 3; +} + +// PriorityLevelConfiguration represents the configuration of a priority level. +message PriorityLevelConfiguration { + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // `spec` is the specification of the desired behavior of a "request-priority". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional PriorityLevelConfigurationSpec spec = 2; + + // `status` is the current status of a "request-priority". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional PriorityLevelConfigurationStatus status = 3; +} + +// PriorityLevelConfigurationCondition defines the condition of priority level. +message PriorityLevelConfigurationCondition { + // `type` is the type of the condition. + // Required. + optional string type = 1; + + // `status` is the status of the condition. + // Can be True, False, Unknown. + // Required. + optional string status = 2; + + // `lastTransitionTime` is the last time the condition transitioned from one status to another. + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; + + // `reason` is a unique, one-word, CamelCase reason for the condition's last transition. + optional string reason = 4; + + // `message` is a human-readable message indicating details about last transition. + optional string message = 5; +} + +// PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects. +message PriorityLevelConfigurationList { + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // `items` is a list of request-priorities. + repeated PriorityLevelConfiguration items = 2; +} + +// PriorityLevelConfigurationReference contains information that points to the "request-priority" being used. +message PriorityLevelConfigurationReference { + // `name` is the name of the priority level configuration being referenced + // Required. + optional string name = 1; +} + +// PriorityLevelConfigurationSpec specifies the configuration of a priority level. +// +union +message PriorityLevelConfigurationSpec { + // `type` indicates whether this priority level is subject to + // limitation on request execution. A value of `"Exempt"` means + // that requests of this priority level are not subject to a limit + // (and thus are never queued) and do not detract from the + // capacity made available to other priority levels. A value of + // `"Limited"` means that (a) requests of this priority level + // _are_ subject to limits and (b) some of the server's limited + // capacity is made available exclusively to this priority level. + // Required. + // +unionDiscriminator + optional string type = 1; + + // `limited` specifies how requests are handled for a Limited priority level. + // This field must be non-empty if and only if `type` is `"Limited"`. + // +optional + optional LimitedPriorityLevelConfiguration limited = 2; +} + +// PriorityLevelConfigurationStatus represents the current state of a "request-priority". +message PriorityLevelConfigurationStatus { + // `conditions` is the current state of "request-priority". + // +listType=map + // +listMapKey=type + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + repeated PriorityLevelConfigurationCondition conditions = 1; +} + +// QueuingConfiguration holds the configuration parameters for queuing +message QueuingConfiguration { + // `queues` is the number of queues for this priority level. The + // queues exist independently at each apiserver. The value must be + // positive. Setting it to 1 effectively precludes + // shufflesharding and thus makes the distinguisher method of + // associated flow schemas irrelevant. This field has a default + // value of 64. + // +optional + optional int32 queues = 1; + + // `handSize` is a small positive number that configures the + // shuffle sharding of requests into queues. When enqueuing a request + // at this priority level the request's flow identifier (a string + // pair) is hashed and the hash value is used to shuffle the list + // of queues and deal a hand of the size specified here. The + // request is put into one of the shortest queues in that hand. + // `handSize` must be no larger than `queues`, and should be + // significantly smaller (so that a few heavy flows do not + // saturate most of the queues). See the user-facing + // documentation for more extensive guidance on setting this + // field. This field has a default value of 8. + // +optional + optional int32 handSize = 2; + + // `queueLengthLimit` is the maximum number of requests allowed to + // be waiting in a given queue of this priority level at a time; + // excess requests are rejected. This value must be positive. If + // not specified, it will be defaulted to 50. + // +optional + optional int32 queueLengthLimit = 3; +} + +// ResourcePolicyRule is a predicate that matches some resource +// requests, testing the request's verb and the target resource. A +// ResourcePolicyRule matches a resource request if and only if: (a) +// at least one member of verbs matches the request, (b) at least one +// member of apiGroups matches the request, (c) at least one member of +// resources matches the request, and (d) either (d1) the request does +// not specify a namespace (i.e., `Namespace==""`) and clusterScope is +// true or (d2) the request specifies a namespace and least one member +// of namespaces matches the request's namespace. +message ResourcePolicyRule { + // `verbs` is a list of matching verbs and may not be empty. + // "*" matches all verbs and, if present, must be the only entry. + // +listType=set + // Required. + repeated string verbs = 1; + + // `apiGroups` is a list of matching API groups and may not be empty. + // "*" matches all API groups and, if present, must be the only entry. + // +listType=set + // Required. + repeated string apiGroups = 2; + + // `resources` is a list of matching resources (i.e., lowercase + // and plural) with, if desired, subresource. For example, [ + // "services", "nodes/status" ]. This list may not be empty. + // "*" matches all resources and, if present, must be the only entry. + // Required. + // +listType=set + repeated string resources = 3; + + // `clusterScope` indicates whether to match requests that do not + // specify a namespace (which happens either because the resource + // is not namespaced or the request targets all namespaces). + // If this field is omitted or false then the `namespaces` field + // must contain a non-empty list. + // +optional + optional bool clusterScope = 4; + + // `namespaces` is a list of target namespaces that restricts + // matches. A request that specifies a target namespace matches + // only if either (a) this list contains that target namespace or + // (b) this list contains "*". Note that "*" matches any + // specified namespace but does not match a request that _does + // not specify_ a namespace (see the `clusterScope` field for + // that). + // This list may be empty, but only if `clusterScope` is true. + // +optional + // +listType=set + repeated string namespaces = 5; +} + +// ServiceAccountSubject holds detailed information for service-account-kind subject. +message ServiceAccountSubject { + // `namespace` is the namespace of matching ServiceAccount objects. + // Required. + optional string namespace = 1; + + // `name` is the name of matching ServiceAccount objects, or "*" to match regardless of name. + // Required. + optional string name = 2; +} + +// Subject matches the originator of a request, as identified by the request authentication system. There are three +// ways of matching an originator; by user, group, or service account. +// +union +message Subject { + // `kind` indicates which one of the other fields is non-empty. + // Required + // +unionDiscriminator + optional string kind = 1; + + // `user` matches based on username. + // +optional + optional UserSubject user = 2; + + // `group` matches based on user group name. + // +optional + optional GroupSubject group = 3; + + // `serviceAccount` matches ServiceAccounts. + // +optional + optional ServiceAccountSubject serviceAccount = 4; +} + +// UserSubject holds detailed information for user-kind subject. +message UserSubject { + // `name` is the username that matches, or "*" to match all usernames. + // Required. + optional string name = 1; +} + diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/register.go b/vendor/k8s.io/api/flowcontrol/v1beta3/register.go new file mode 100644 index 00000000000..baf10b1829e --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/register.go @@ -0,0 +1,58 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the name of api group +const GroupName = "flowcontrol.apiserver.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta3"} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder installs the api group to a scheme + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme adds api to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &FlowSchema{}, + &FlowSchemaList{}, + &PriorityLevelConfiguration{}, + &PriorityLevelConfigurationList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/types.go b/vendor/k8s.io/api/flowcontrol/v1beta3/types.go new file mode 100644 index 00000000000..2baf2dc39eb --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/types.go @@ -0,0 +1,612 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// These are valid wildcards. +const ( + APIGroupAll = "*" + ResourceAll = "*" + VerbAll = "*" + NonResourceAll = "*" + NameAll = "*" + + NamespaceEvery = "*" // matches every particular namespace +) + +// System preset priority level names +const ( + PriorityLevelConfigurationNameExempt = "exempt" + PriorityLevelConfigurationNameCatchAll = "catch-all" + FlowSchemaNameExempt = "exempt" + FlowSchemaNameCatchAll = "catch-all" +) + +// Conditions +const ( + FlowSchemaConditionDangling = "Dangling" + + PriorityLevelConfigurationConditionConcurrencyShared = "ConcurrencyShared" +) + +// Constants used by api validation. +const ( + FlowSchemaMaxMatchingPrecedence int32 = 10000 +) + +// Constants for apiserver response headers. +const ( + ResponseHeaderMatchedPriorityLevelConfigurationUID = "X-Kubernetes-PF-PriorityLevel-UID" + ResponseHeaderMatchedFlowSchemaUID = "X-Kubernetes-PF-FlowSchema-UID" +) + +const ( + // AutoUpdateAnnotationKey is the name of an annotation that enables + // automatic update of the spec of the bootstrap configuration + // object(s), if set to 'true'. + // + // On a fresh install, all bootstrap configuration objects will have auto + // update enabled with the following annotation key: + // apf.kubernetes.io/autoupdate-spec: 'true' + // + // The kube-apiserver periodically checks the bootstrap configuration + // objects on the cluster and applies updates if necessary. + // + // kube-apiserver enforces an 'always auto-update' policy for the + // mandatory configuration object(s). This implies: + // - the auto-update annotation key is added with a value of 'true' + // if it is missing. + // - the auto-update annotation key is set to 'true' if its current value + // is a boolean false or has an invalid boolean representation + // (if the cluster operator sets it to 'false' it will be stomped) + // - any changes to the spec made by the cluster operator will be + // stomped. + // + // The kube-apiserver will apply updates on the suggested configuration if: + // - the cluster operator has enabled auto-update by setting the annotation + // (apf.kubernetes.io/autoupdate-spec: 'true') or + // - the annotation key is missing but the generation is 1 + // + // If the suggested configuration object is missing the annotation key, + // kube-apiserver will update the annotation appropriately: + // - it is set to 'true' if generation of the object is '1' which usually + // indicates that the spec of the object has not been changed. + // - it is set to 'false' if generation of the object is greater than 1. + // + // The goal is to enable the kube-apiserver to apply update on suggested + // configuration objects installed by previous releases but not overwrite + // changes made by the cluster operators. + // Note that this distinction is imperfectly detected: in the case where an + // operator deletes a suggested configuration object and later creates it + // but with a variant spec and then does no updates of the object + // (generation is 1), the technique outlined above will incorrectly + // determine that the object should be auto-updated. + AutoUpdateAnnotationKey = "apf.kubernetes.io/autoupdate-spec" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with +// similar attributes and is identified by a pair of strings: the name of the FlowSchema and a "flow distinguisher". +type FlowSchema struct { + metav1.TypeMeta `json:",inline"` + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // `spec` is the specification of the desired behavior of a FlowSchema. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec FlowSchemaSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // `status` is the current status of a FlowSchema. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Status FlowSchemaStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// FlowSchemaList is a list of FlowSchema objects. +type FlowSchemaList struct { + metav1.TypeMeta `json:",inline"` + // `metadata` is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // `items` is a list of FlowSchemas. + Items []FlowSchema `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// FlowSchemaSpec describes how the FlowSchema's specification looks like. +type FlowSchemaSpec struct { + // `priorityLevelConfiguration` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot + // be resolved, the FlowSchema will be ignored and marked as invalid in its status. + // Required. + PriorityLevelConfiguration PriorityLevelConfigurationReference `json:"priorityLevelConfiguration" protobuf:"bytes,1,opt,name=priorityLevelConfiguration"` + // `matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen + // FlowSchema is among those with the numerically lowest (which we take to be logically highest) + // MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. + // Note that if the precedence is not specified, it will be set to 1000 as default. + // +optional + MatchingPrecedence int32 `json:"matchingPrecedence" protobuf:"varint,2,opt,name=matchingPrecedence"` + // `distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. + // `nil` specifies that the distinguisher is disabled and thus will always be the empty string. + // +optional + DistinguisherMethod *FlowDistinguisherMethod `json:"distinguisherMethod,omitempty" protobuf:"bytes,3,opt,name=distinguisherMethod"` + // `rules` describes which requests will match this flow schema. This FlowSchema matches a request if and only if + // at least one member of rules matches the request. + // if it is an empty slice, there will be no requests matching the FlowSchema. + // +listType=atomic + // +optional + Rules []PolicyRulesWithSubjects `json:"rules,omitempty" protobuf:"bytes,4,rep,name=rules"` +} + +// FlowDistinguisherMethodType is the type of flow distinguisher method +type FlowDistinguisherMethodType string + +// These are valid flow-distinguisher methods. +const ( + // FlowDistinguisherMethodByUserType specifies that the flow distinguisher is the username in the request. + // This type is used to provide some insulation between users. + FlowDistinguisherMethodByUserType FlowDistinguisherMethodType = "ByUser" + + // FlowDistinguisherMethodByNamespaceType specifies that the flow distinguisher is the namespace of the + // object that the request acts upon. If the object is not namespaced, or if the request is a non-resource + // request, then the distinguisher will be the empty string. An example usage of this type is to provide + // some insulation between tenants in a situation where there are multiple tenants and each namespace + // is dedicated to a tenant. + FlowDistinguisherMethodByNamespaceType FlowDistinguisherMethodType = "ByNamespace" +) + +// FlowDistinguisherMethod specifies the method of a flow distinguisher. +type FlowDistinguisherMethod struct { + // `type` is the type of flow distinguisher method + // The supported types are "ByUser" and "ByNamespace". + // Required. + Type FlowDistinguisherMethodType `json:"type" protobuf:"bytes,1,opt,name=type"` +} + +// PriorityLevelConfigurationReference contains information that points to the "request-priority" being used. +type PriorityLevelConfigurationReference struct { + // `name` is the name of the priority level configuration being referenced + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` +} + +// PolicyRulesWithSubjects prescribes a test that applies to a request to an apiserver. The test considers the subject +// making the request, the verb being requested, and the resource to be acted upon. This PolicyRulesWithSubjects matches +// a request if and only if both (a) at least one member of subjects matches the request and (b) at least one member +// of resourceRules or nonResourceRules matches the request. +type PolicyRulesWithSubjects struct { + // subjects is the list of normal user, serviceaccount, or group that this rule cares about. + // There must be at least one member in this slice. + // A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. + // +listType=atomic + // Required. + Subjects []Subject `json:"subjects" protobuf:"bytes,1,rep,name=subjects"` + // `resourceRules` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the + // target resource. + // At least one of `resourceRules` and `nonResourceRules` has to be non-empty. + // +listType=atomic + // +optional + ResourceRules []ResourcePolicyRule `json:"resourceRules,omitempty" protobuf:"bytes,2,opt,name=resourceRules"` + // `nonResourceRules` is a list of NonResourcePolicyRules that identify matching requests according to their verb + // and the target non-resource URL. + // +listType=atomic + // +optional + NonResourceRules []NonResourcePolicyRule `json:"nonResourceRules,omitempty" protobuf:"bytes,3,opt,name=nonResourceRules"` +} + +// Subject matches the originator of a request, as identified by the request authentication system. There are three +// ways of matching an originator; by user, group, or service account. +// +union +type Subject struct { + // `kind` indicates which one of the other fields is non-empty. + // Required + // +unionDiscriminator + Kind SubjectKind `json:"kind" protobuf:"bytes,1,opt,name=kind"` + // `user` matches based on username. + // +optional + User *UserSubject `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"` + // `group` matches based on user group name. + // +optional + Group *GroupSubject `json:"group,omitempty" protobuf:"bytes,3,opt,name=group"` + // `serviceAccount` matches ServiceAccounts. + // +optional + ServiceAccount *ServiceAccountSubject `json:"serviceAccount,omitempty" protobuf:"bytes,4,opt,name=serviceAccount"` +} + +// SubjectKind is the kind of subject. +type SubjectKind string + +// Supported subject's kinds. +const ( + SubjectKindUser SubjectKind = "User" + SubjectKindGroup SubjectKind = "Group" + SubjectKindServiceAccount SubjectKind = "ServiceAccount" +) + +// UserSubject holds detailed information for user-kind subject. +type UserSubject struct { + // `name` is the username that matches, or "*" to match all usernames. + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` +} + +// GroupSubject holds detailed information for group-kind subject. +type GroupSubject struct { + // name is the user group that matches, or "*" to match all user groups. + // See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some + // well-known group names. + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` +} + +// ServiceAccountSubject holds detailed information for service-account-kind subject. +type ServiceAccountSubject struct { + // `namespace` is the namespace of matching ServiceAccount objects. + // Required. + Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"` + // `name` is the name of matching ServiceAccount objects, or "*" to match regardless of name. + // Required. + Name string `json:"name" protobuf:"bytes,2,opt,name=name"` +} + +// ResourcePolicyRule is a predicate that matches some resource +// requests, testing the request's verb and the target resource. A +// ResourcePolicyRule matches a resource request if and only if: (a) +// at least one member of verbs matches the request, (b) at least one +// member of apiGroups matches the request, (c) at least one member of +// resources matches the request, and (d) either (d1) the request does +// not specify a namespace (i.e., `Namespace==""`) and clusterScope is +// true or (d2) the request specifies a namespace and least one member +// of namespaces matches the request's namespace. +type ResourcePolicyRule struct { + // `verbs` is a list of matching verbs and may not be empty. + // "*" matches all verbs and, if present, must be the only entry. + // +listType=set + // Required. + Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` + + // `apiGroups` is a list of matching API groups and may not be empty. + // "*" matches all API groups and, if present, must be the only entry. + // +listType=set + // Required. + APIGroups []string `json:"apiGroups" protobuf:"bytes,2,rep,name=apiGroups"` + + // `resources` is a list of matching resources (i.e., lowercase + // and plural) with, if desired, subresource. For example, [ + // "services", "nodes/status" ]. This list may not be empty. + // "*" matches all resources and, if present, must be the only entry. + // Required. + // +listType=set + Resources []string `json:"resources" protobuf:"bytes,3,rep,name=resources"` + + // `clusterScope` indicates whether to match requests that do not + // specify a namespace (which happens either because the resource + // is not namespaced or the request targets all namespaces). + // If this field is omitted or false then the `namespaces` field + // must contain a non-empty list. + // +optional + ClusterScope bool `json:"clusterScope,omitempty" protobuf:"varint,4,opt,name=clusterScope"` + + // `namespaces` is a list of target namespaces that restricts + // matches. A request that specifies a target namespace matches + // only if either (a) this list contains that target namespace or + // (b) this list contains "*". Note that "*" matches any + // specified namespace but does not match a request that _does + // not specify_ a namespace (see the `clusterScope` field for + // that). + // This list may be empty, but only if `clusterScope` is true. + // +optional + // +listType=set + Namespaces []string `json:"namespaces" protobuf:"bytes,5,rep,name=namespaces"` +} + +// NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the +// target non-resource URL. A NonResourcePolicyRule matches a request if and only if both (a) at least one member +// of verbs matches the request and (b) at least one member of nonResourceURLs matches the request. +type NonResourcePolicyRule struct { + // `verbs` is a list of matching verbs and may not be empty. + // "*" matches all verbs. If it is present, it must be the only entry. + // +listType=set + // Required. + Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` + // `nonResourceURLs` is a set of url prefixes that a user should have access to and may not be empty. + // For example: + // - "/healthz" is legal + // - "/hea*" is illegal + // - "/hea" is legal but matches nothing + // - "/hea/*" also matches nothing + // - "/healthz/*" matches all per-component health checks. + // "*" matches all non-resource urls. if it is present, it must be the only entry. + // +listType=set + // Required. + NonResourceURLs []string `json:"nonResourceURLs" protobuf:"bytes,6,rep,name=nonResourceURLs"` +} + +// FlowSchemaStatus represents the current state of a FlowSchema. +type FlowSchemaStatus struct { + // `conditions` is a list of the current states of FlowSchema. + // +listType=map + // +listMapKey=type + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + Conditions []FlowSchemaCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// FlowSchemaCondition describes conditions for a FlowSchema. +type FlowSchemaCondition struct { + // `type` is the type of the condition. + // Required. + Type FlowSchemaConditionType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"` + // `status` is the status of the condition. + // Can be True, False, Unknown. + // Required. + Status ConditionStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` + // `lastTransitionTime` is the last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // `reason` is a unique, one-word, CamelCase reason for the condition's last transition. + Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // `message` is a human-readable message indicating details about last transition. + Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` +} + +// FlowSchemaConditionType is a valid value for FlowSchemaStatusCondition.Type +type FlowSchemaConditionType string + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// PriorityLevelConfiguration represents the configuration of a priority level. +type PriorityLevelConfiguration struct { + metav1.TypeMeta `json:",inline"` + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // `spec` is the specification of the desired behavior of a "request-priority". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec PriorityLevelConfigurationSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // `status` is the current status of a "request-priority". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Status PriorityLevelConfigurationStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects. +type PriorityLevelConfigurationList struct { + metav1.TypeMeta `json:",inline"` + // `metadata` is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // `items` is a list of request-priorities. + Items []PriorityLevelConfiguration `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// PriorityLevelConfigurationSpec specifies the configuration of a priority level. +// +union +type PriorityLevelConfigurationSpec struct { + // `type` indicates whether this priority level is subject to + // limitation on request execution. A value of `"Exempt"` means + // that requests of this priority level are not subject to a limit + // (and thus are never queued) and do not detract from the + // capacity made available to other priority levels. A value of + // `"Limited"` means that (a) requests of this priority level + // _are_ subject to limits and (b) some of the server's limited + // capacity is made available exclusively to this priority level. + // Required. + // +unionDiscriminator + Type PriorityLevelEnablement `json:"type" protobuf:"bytes,1,opt,name=type"` + + // `limited` specifies how requests are handled for a Limited priority level. + // This field must be non-empty if and only if `type` is `"Limited"`. + // +optional + Limited *LimitedPriorityLevelConfiguration `json:"limited,omitempty" protobuf:"bytes,2,opt,name=limited"` +} + +// PriorityLevelEnablement indicates whether limits on execution are enabled for the priority level +type PriorityLevelEnablement string + +// Supported priority level enablement values. +const ( + // PriorityLevelEnablementExempt means that requests are not subject to limits + PriorityLevelEnablementExempt PriorityLevelEnablement = "Exempt" + + // PriorityLevelEnablementLimited means that requests are subject to limits + PriorityLevelEnablementLimited PriorityLevelEnablement = "Limited" +) + +// LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. +// It addresses two issues: +// - How are requests for this priority level limited? +// - What should be done with requests that exceed the limit? +type LimitedPriorityLevelConfiguration struct { + // `nominalConcurrencyShares` (NCS) contributes to the computation of the + // NominalConcurrencyLimit (NominalCL) of this level. + // This is the number of execution seats available at this priority level. + // This is used both for requests dispatched from this priority level + // as well as requests dispatched from other priority levels + // borrowing seats from this level. + // The server's concurrency limit (ServerCL) is divided among the + // Limited priority levels in proportion to their NCS values: + // + // NominalCL(i) = ceil( ServerCL * NCS(i) / sum_ncs ) + // sum_ncs = sum[limited priority level k] NCS(k) + // + // Bigger numbers mean a larger nominal concurrency limit, + // at the expense of every other Limited priority level. + // This field has a default value of 30. + // +optional + NominalConcurrencyShares int32 `json:"nominalConcurrencyShares" protobuf:"varint,1,opt,name=nominalConcurrencyShares"` + + // `limitResponse` indicates what to do with requests that can not be executed right now + LimitResponse LimitResponse `json:"limitResponse,omitempty" protobuf:"bytes,2,opt,name=limitResponse"` + + // `lendablePercent` prescribes the fraction of the level's NominalCL that + // can be borrowed by other priority levels. The value of this + // field must be between 0 and 100, inclusive, and it defaults to 0. + // The number of seats that other levels can borrow from this level, known + // as this level's LendableConcurrencyLimit (LendableCL), is defined as follows. + // + // LendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 ) + // + // +optional + LendablePercent *int32 `json:"lendablePercent,omitempty" protobuf:"varint,3,opt,name=lendablePercent"` + + // `borrowingLimitPercent`, if present, configures a limit on how many + // seats this priority level can borrow from other priority levels. + // The limit is known as this level's BorrowingConcurrencyLimit + // (BorrowingCL) and is a limit on the total number of seats that this + // level may borrow at any one time. + // This field holds the ratio of that limit to the level's nominal + // concurrency limit. When this field is non-nil, it must hold a + // non-negative integer and the limit is calculated as follows. + // + // BorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 ) + // + // The value of this field can be more than 100, implying that this + // priority level can borrow a number of seats that is greater than + // its own nominal concurrency limit (NominalCL). + // When this field is left `nil`, the limit is effectively infinite. + // +optional + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty" protobuf:"varint,4,opt,name=borrowingLimitPercent"` +} + +// LimitResponse defines how to handle requests that can not be executed right now. +// +union +type LimitResponse struct { + // `type` is "Queue" or "Reject". + // "Queue" means that requests that can not be executed upon arrival + // are held in a queue until they can be executed or a queuing limit + // is reached. + // "Reject" means that requests that can not be executed upon arrival + // are rejected. + // Required. + // +unionDiscriminator + Type LimitResponseType `json:"type" protobuf:"bytes,1,opt,name=type"` + + // `queuing` holds the configuration parameters for queuing. + // This field may be non-empty only if `type` is `"Queue"`. + // +optional + Queuing *QueuingConfiguration `json:"queuing,omitempty" protobuf:"bytes,2,opt,name=queuing"` +} + +// LimitResponseType identifies how a Limited priority level handles a request that can not be executed right now +type LimitResponseType string + +// Supported limit responses. +const ( + // LimitResponseTypeQueue means that requests that can not be executed right now are queued until they can be executed or a queuing limit is hit + LimitResponseTypeQueue LimitResponseType = "Queue" + + // LimitResponseTypeReject means that requests that can not be executed right now are rejected + LimitResponseTypeReject LimitResponseType = "Reject" +) + +// QueuingConfiguration holds the configuration parameters for queuing +type QueuingConfiguration struct { + // `queues` is the number of queues for this priority level. The + // queues exist independently at each apiserver. The value must be + // positive. Setting it to 1 effectively precludes + // shufflesharding and thus makes the distinguisher method of + // associated flow schemas irrelevant. This field has a default + // value of 64. + // +optional + Queues int32 `json:"queues" protobuf:"varint,1,opt,name=queues"` + + // `handSize` is a small positive number that configures the + // shuffle sharding of requests into queues. When enqueuing a request + // at this priority level the request's flow identifier (a string + // pair) is hashed and the hash value is used to shuffle the list + // of queues and deal a hand of the size specified here. The + // request is put into one of the shortest queues in that hand. + // `handSize` must be no larger than `queues`, and should be + // significantly smaller (so that a few heavy flows do not + // saturate most of the queues). See the user-facing + // documentation for more extensive guidance on setting this + // field. This field has a default value of 8. + // +optional + HandSize int32 `json:"handSize" protobuf:"varint,2,opt,name=handSize"` + + // `queueLengthLimit` is the maximum number of requests allowed to + // be waiting in a given queue of this priority level at a time; + // excess requests are rejected. This value must be positive. If + // not specified, it will be defaulted to 50. + // +optional + QueueLengthLimit int32 `json:"queueLengthLimit" protobuf:"varint,3,opt,name=queueLengthLimit"` +} + +// PriorityLevelConfigurationConditionType is a valid value for PriorityLevelConfigurationStatusCondition.Type +type PriorityLevelConfigurationConditionType string + +// PriorityLevelConfigurationStatus represents the current state of a "request-priority". +type PriorityLevelConfigurationStatus struct { + // `conditions` is the current state of "request-priority". + // +listType=map + // +listMapKey=type + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + Conditions []PriorityLevelConfigurationCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// PriorityLevelConfigurationCondition defines the condition of priority level. +type PriorityLevelConfigurationCondition struct { + // `type` is the type of the condition. + // Required. + Type PriorityLevelConfigurationConditionType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"` + // `status` is the status of the condition. + // Can be True, False, Unknown. + // Required. + Status ConditionStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` + // `lastTransitionTime` is the last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // `reason` is a unique, one-word, CamelCase reason for the condition's last transition. + Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // `message` is a human-readable message indicating details about last transition. + Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` +} + +// ConditionStatus is the status of the condition. +type ConditionStatus string + +// These are valid condition statuses. "ConditionTrue" means a resource is in the condition. +// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes +// can't decide if a resource is in the condition or not. In the future, we could add other +// intermediate conditions, e.g. ConditionDegraded. +const ( + ConditionTrue ConditionStatus = "True" + ConditionFalse ConditionStatus = "False" + ConditionUnknown ConditionStatus = "Unknown" +) diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go new file mode 100644 index 00000000000..728252c0cf2 --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go @@ -0,0 +1,263 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta3 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_FlowDistinguisherMethod = map[string]string{ + "": "FlowDistinguisherMethod specifies the method of a flow distinguisher.", + "type": "`type` is the type of flow distinguisher method The supported types are \"ByUser\" and \"ByNamespace\". Required.", +} + +func (FlowDistinguisherMethod) SwaggerDoc() map[string]string { + return map_FlowDistinguisherMethod +} + +var map_FlowSchema = map[string]string{ + "": "FlowSchema defines the schema of a group of flows. Note that a flow is made up of a set of inbound API requests with similar attributes and is identified by a pair of strings: the name of the FlowSchema and a \"flow distinguisher\".", + "metadata": "`metadata` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "`spec` is the specification of the desired behavior of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "`status` is the current status of a FlowSchema. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (FlowSchema) SwaggerDoc() map[string]string { + return map_FlowSchema +} + +var map_FlowSchemaCondition = map[string]string{ + "": "FlowSchemaCondition describes conditions for a FlowSchema.", + "type": "`type` is the type of the condition. Required.", + "status": "`status` is the status of the condition. Can be True, False, Unknown. Required.", + "lastTransitionTime": "`lastTransitionTime` is the last time the condition transitioned from one status to another.", + "reason": "`reason` is a unique, one-word, CamelCase reason for the condition's last transition.", + "message": "`message` is a human-readable message indicating details about last transition.", +} + +func (FlowSchemaCondition) SwaggerDoc() map[string]string { + return map_FlowSchemaCondition +} + +var map_FlowSchemaList = map[string]string{ + "": "FlowSchemaList is a list of FlowSchema objects.", + "metadata": "`metadata` is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "`items` is a list of FlowSchemas.", +} + +func (FlowSchemaList) SwaggerDoc() map[string]string { + return map_FlowSchemaList +} + +var map_FlowSchemaSpec = map[string]string{ + "": "FlowSchemaSpec describes how the FlowSchema's specification looks like.", + "priorityLevelConfiguration": "`priorityLevelConfiguration` should reference a PriorityLevelConfiguration in the cluster. If the reference cannot be resolved, the FlowSchema will be ignored and marked as invalid in its status. Required.", + "matchingPrecedence": "`matchingPrecedence` is used to choose among the FlowSchemas that match a given request. The chosen FlowSchema is among those with the numerically lowest (which we take to be logically highest) MatchingPrecedence. Each MatchingPrecedence value must be ranged in [1,10000]. Note that if the precedence is not specified, it will be set to 1000 as default.", + "distinguisherMethod": "`distinguisherMethod` defines how to compute the flow distinguisher for requests that match this schema. `nil` specifies that the distinguisher is disabled and thus will always be the empty string.", + "rules": "`rules` describes which requests will match this flow schema. This FlowSchema matches a request if and only if at least one member of rules matches the request. if it is an empty slice, there will be no requests matching the FlowSchema.", +} + +func (FlowSchemaSpec) SwaggerDoc() map[string]string { + return map_FlowSchemaSpec +} + +var map_FlowSchemaStatus = map[string]string{ + "": "FlowSchemaStatus represents the current state of a FlowSchema.", + "conditions": "`conditions` is a list of the current states of FlowSchema.", +} + +func (FlowSchemaStatus) SwaggerDoc() map[string]string { + return map_FlowSchemaStatus +} + +var map_GroupSubject = map[string]string{ + "": "GroupSubject holds detailed information for group-kind subject.", + "name": "name is the user group that matches, or \"*\" to match all user groups. See https://github.com/kubernetes/apiserver/blob/master/pkg/authentication/user/user.go for some well-known group names. Required.", +} + +func (GroupSubject) SwaggerDoc() map[string]string { + return map_GroupSubject +} + +var map_LimitResponse = map[string]string{ + "": "LimitResponse defines how to handle requests that can not be executed right now.", + "type": "`type` is \"Queue\" or \"Reject\". \"Queue\" means that requests that can not be executed upon arrival are held in a queue until they can be executed or a queuing limit is reached. \"Reject\" means that requests that can not be executed upon arrival are rejected. Required.", + "queuing": "`queuing` holds the configuration parameters for queuing. This field may be non-empty only if `type` is `\"Queue\"`.", +} + +func (LimitResponse) SwaggerDoc() map[string]string { + return map_LimitResponse +} + +var map_LimitedPriorityLevelConfiguration = map[string]string{ + "": "LimitedPriorityLevelConfiguration specifies how to handle requests that are subject to limits. It addresses two issues:\n - How are requests for this priority level limited?\n - What should be done with requests that exceed the limit?", + "nominalConcurrencyShares": "`nominalConcurrencyShares` (NCS) contributes to the computation of the NominalConcurrencyLimit (NominalCL) of this level. This is the number of execution seats available at this priority level. This is used both for requests dispatched from this priority level as well as requests dispatched from other priority levels borrowing seats from this level. The server's concurrency limit (ServerCL) is divided among the Limited priority levels in proportion to their NCS values:\n\nNominalCL(i) = ceil( ServerCL * NCS(i) / sum_ncs ) sum_ncs = sum[limited priority level k] NCS(k)\n\nBigger numbers mean a larger nominal concurrency limit, at the expense of every other Limited priority level. This field has a default value of 30.", + "limitResponse": "`limitResponse` indicates what to do with requests that can not be executed right now", + "lendablePercent": "`lendablePercent` prescribes the fraction of the level's NominalCL that can be borrowed by other priority levels. The value of this field must be between 0 and 100, inclusive, and it defaults to 0. The number of seats that other levels can borrow from this level, known as this level's LendableConcurrencyLimit (LendableCL), is defined as follows.\n\nLendableCL(i) = round( NominalCL(i) * lendablePercent(i)/100.0 )", + "borrowingLimitPercent": "`borrowingLimitPercent`, if present, configures a limit on how many seats this priority level can borrow from other priority levels. The limit is known as this level's BorrowingConcurrencyLimit (BorrowingCL) and is a limit on the total number of seats that this level may borrow at any one time. This field holds the ratio of that limit to the level's nominal concurrency limit. When this field is non-nil, it must hold a non-negative integer and the limit is calculated as follows.\n\nBorrowingCL(i) = round( NominalCL(i) * borrowingLimitPercent(i)/100.0 )\n\nThe value of this field can be more than 100, implying that this priority level can borrow a number of seats that is greater than its own nominal concurrency limit (NominalCL). When this field is left `nil`, the limit is effectively infinite.", +} + +func (LimitedPriorityLevelConfiguration) SwaggerDoc() map[string]string { + return map_LimitedPriorityLevelConfiguration +} + +var map_NonResourcePolicyRule = map[string]string{ + "": "NonResourcePolicyRule is a predicate that matches non-resource requests according to their verb and the target non-resource URL. A NonResourcePolicyRule matches a request if and only if both (a) at least one member of verbs matches the request and (b) at least one member of nonResourceURLs matches the request.", + "verbs": "`verbs` is a list of matching verbs and may not be empty. \"*\" matches all verbs. If it is present, it must be the only entry. Required.", + "nonResourceURLs": "`nonResourceURLs` is a set of url prefixes that a user should have access to and may not be empty. For example:\n - \"/healthz\" is legal\n - \"/hea*\" is illegal\n - \"/hea\" is legal but matches nothing\n - \"/hea/*\" also matches nothing\n - \"/healthz/*\" matches all per-component health checks.\n\"*\" matches all non-resource urls. if it is present, it must be the only entry. Required.", +} + +func (NonResourcePolicyRule) SwaggerDoc() map[string]string { + return map_NonResourcePolicyRule +} + +var map_PolicyRulesWithSubjects = map[string]string{ + "": "PolicyRulesWithSubjects prescribes a test that applies to a request to an apiserver. The test considers the subject making the request, the verb being requested, and the resource to be acted upon. This PolicyRulesWithSubjects matches a request if and only if both (a) at least one member of subjects matches the request and (b) at least one member of resourceRules or nonResourceRules matches the request.", + "subjects": "subjects is the list of normal user, serviceaccount, or group that this rule cares about. There must be at least one member in this slice. A slice that includes both the system:authenticated and system:unauthenticated user groups matches every request. Required.", + "resourceRules": "`resourceRules` is a slice of ResourcePolicyRules that identify matching requests according to their verb and the target resource. At least one of `resourceRules` and `nonResourceRules` has to be non-empty.", + "nonResourceRules": "`nonResourceRules` is a list of NonResourcePolicyRules that identify matching requests according to their verb and the target non-resource URL.", +} + +func (PolicyRulesWithSubjects) SwaggerDoc() map[string]string { + return map_PolicyRulesWithSubjects +} + +var map_PriorityLevelConfiguration = map[string]string{ + "": "PriorityLevelConfiguration represents the configuration of a priority level.", + "metadata": "`metadata` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "`spec` is the specification of the desired behavior of a \"request-priority\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "`status` is the current status of a \"request-priority\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (PriorityLevelConfiguration) SwaggerDoc() map[string]string { + return map_PriorityLevelConfiguration +} + +var map_PriorityLevelConfigurationCondition = map[string]string{ + "": "PriorityLevelConfigurationCondition defines the condition of priority level.", + "type": "`type` is the type of the condition. Required.", + "status": "`status` is the status of the condition. Can be True, False, Unknown. Required.", + "lastTransitionTime": "`lastTransitionTime` is the last time the condition transitioned from one status to another.", + "reason": "`reason` is a unique, one-word, CamelCase reason for the condition's last transition.", + "message": "`message` is a human-readable message indicating details about last transition.", +} + +func (PriorityLevelConfigurationCondition) SwaggerDoc() map[string]string { + return map_PriorityLevelConfigurationCondition +} + +var map_PriorityLevelConfigurationList = map[string]string{ + "": "PriorityLevelConfigurationList is a list of PriorityLevelConfiguration objects.", + "metadata": "`metadata` is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "`items` is a list of request-priorities.", +} + +func (PriorityLevelConfigurationList) SwaggerDoc() map[string]string { + return map_PriorityLevelConfigurationList +} + +var map_PriorityLevelConfigurationReference = map[string]string{ + "": "PriorityLevelConfigurationReference contains information that points to the \"request-priority\" being used.", + "name": "`name` is the name of the priority level configuration being referenced Required.", +} + +func (PriorityLevelConfigurationReference) SwaggerDoc() map[string]string { + return map_PriorityLevelConfigurationReference +} + +var map_PriorityLevelConfigurationSpec = map[string]string{ + "": "PriorityLevelConfigurationSpec specifies the configuration of a priority level.", + "type": "`type` indicates whether this priority level is subject to limitation on request execution. A value of `\"Exempt\"` means that requests of this priority level are not subject to a limit (and thus are never queued) and do not detract from the capacity made available to other priority levels. A value of `\"Limited\"` means that (a) requests of this priority level _are_ subject to limits and (b) some of the server's limited capacity is made available exclusively to this priority level. Required.", + "limited": "`limited` specifies how requests are handled for a Limited priority level. This field must be non-empty if and only if `type` is `\"Limited\"`.", +} + +func (PriorityLevelConfigurationSpec) SwaggerDoc() map[string]string { + return map_PriorityLevelConfigurationSpec +} + +var map_PriorityLevelConfigurationStatus = map[string]string{ + "": "PriorityLevelConfigurationStatus represents the current state of a \"request-priority\".", + "conditions": "`conditions` is the current state of \"request-priority\".", +} + +func (PriorityLevelConfigurationStatus) SwaggerDoc() map[string]string { + return map_PriorityLevelConfigurationStatus +} + +var map_QueuingConfiguration = map[string]string{ + "": "QueuingConfiguration holds the configuration parameters for queuing", + "queues": "`queues` is the number of queues for this priority level. The queues exist independently at each apiserver. The value must be positive. Setting it to 1 effectively precludes shufflesharding and thus makes the distinguisher method of associated flow schemas irrelevant. This field has a default value of 64.", + "handSize": "`handSize` is a small positive number that configures the shuffle sharding of requests into queues. When enqueuing a request at this priority level the request's flow identifier (a string pair) is hashed and the hash value is used to shuffle the list of queues and deal a hand of the size specified here. The request is put into one of the shortest queues in that hand. `handSize` must be no larger than `queues`, and should be significantly smaller (so that a few heavy flows do not saturate most of the queues). See the user-facing documentation for more extensive guidance on setting this field. This field has a default value of 8.", + "queueLengthLimit": "`queueLengthLimit` is the maximum number of requests allowed to be waiting in a given queue of this priority level at a time; excess requests are rejected. This value must be positive. If not specified, it will be defaulted to 50.", +} + +func (QueuingConfiguration) SwaggerDoc() map[string]string { + return map_QueuingConfiguration +} + +var map_ResourcePolicyRule = map[string]string{ + "": "ResourcePolicyRule is a predicate that matches some resource requests, testing the request's verb and the target resource. A ResourcePolicyRule matches a resource request if and only if: (a) at least one member of verbs matches the request, (b) at least one member of apiGroups matches the request, (c) at least one member of resources matches the request, and (d) either (d1) the request does not specify a namespace (i.e., `Namespace==\"\"`) and clusterScope is true or (d2) the request specifies a namespace and least one member of namespaces matches the request's namespace.", + "verbs": "`verbs` is a list of matching verbs and may not be empty. \"*\" matches all verbs and, if present, must be the only entry. Required.", + "apiGroups": "`apiGroups` is a list of matching API groups and may not be empty. \"*\" matches all API groups and, if present, must be the only entry. Required.", + "resources": "`resources` is a list of matching resources (i.e., lowercase and plural) with, if desired, subresource. For example, [ \"services\", \"nodes/status\" ]. This list may not be empty. \"*\" matches all resources and, if present, must be the only entry. Required.", + "clusterScope": "`clusterScope` indicates whether to match requests that do not specify a namespace (which happens either because the resource is not namespaced or the request targets all namespaces). If this field is omitted or false then the `namespaces` field must contain a non-empty list.", + "namespaces": "`namespaces` is a list of target namespaces that restricts matches. A request that specifies a target namespace matches only if either (a) this list contains that target namespace or (b) this list contains \"*\". Note that \"*\" matches any specified namespace but does not match a request that _does not specify_ a namespace (see the `clusterScope` field for that). This list may be empty, but only if `clusterScope` is true.", +} + +func (ResourcePolicyRule) SwaggerDoc() map[string]string { + return map_ResourcePolicyRule +} + +var map_ServiceAccountSubject = map[string]string{ + "": "ServiceAccountSubject holds detailed information for service-account-kind subject.", + "namespace": "`namespace` is the namespace of matching ServiceAccount objects. Required.", + "name": "`name` is the name of matching ServiceAccount objects, or \"*\" to match regardless of name. Required.", +} + +func (ServiceAccountSubject) SwaggerDoc() map[string]string { + return map_ServiceAccountSubject +} + +var map_Subject = map[string]string{ + "": "Subject matches the originator of a request, as identified by the request authentication system. There are three ways of matching an originator; by user, group, or service account.", + "kind": "`kind` indicates which one of the other fields is non-empty. Required", + "user": "`user` matches based on username.", + "group": "`group` matches based on user group name.", + "serviceAccount": "`serviceAccount` matches ServiceAccounts.", +} + +func (Subject) SwaggerDoc() map[string]string { + return map_Subject +} + +var map_UserSubject = map[string]string{ + "": "UserSubject holds detailed information for user-kind subject.", + "name": "`name` is the username that matches, or \"*\" to match all usernames. Required.", +} + +func (UserSubject) SwaggerDoc() map[string]string { + return map_UserSubject +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.deepcopy.go b/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.deepcopy.go new file mode 100644 index 00000000000..ec02d2a9c4c --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.deepcopy.go @@ -0,0 +1,552 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowDistinguisherMethod) DeepCopyInto(out *FlowDistinguisherMethod) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowDistinguisherMethod. +func (in *FlowDistinguisherMethod) DeepCopy() *FlowDistinguisherMethod { + if in == nil { + return nil + } + out := new(FlowDistinguisherMethod) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowSchema) DeepCopyInto(out *FlowSchema) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowSchema. +func (in *FlowSchema) DeepCopy() *FlowSchema { + if in == nil { + return nil + } + out := new(FlowSchema) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FlowSchema) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowSchemaCondition) DeepCopyInto(out *FlowSchemaCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowSchemaCondition. +func (in *FlowSchemaCondition) DeepCopy() *FlowSchemaCondition { + if in == nil { + return nil + } + out := new(FlowSchemaCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowSchemaList) DeepCopyInto(out *FlowSchemaList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FlowSchema, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowSchemaList. +func (in *FlowSchemaList) DeepCopy() *FlowSchemaList { + if in == nil { + return nil + } + out := new(FlowSchemaList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FlowSchemaList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowSchemaSpec) DeepCopyInto(out *FlowSchemaSpec) { + *out = *in + out.PriorityLevelConfiguration = in.PriorityLevelConfiguration + if in.DistinguisherMethod != nil { + in, out := &in.DistinguisherMethod, &out.DistinguisherMethod + *out = new(FlowDistinguisherMethod) + **out = **in + } + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]PolicyRulesWithSubjects, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowSchemaSpec. +func (in *FlowSchemaSpec) DeepCopy() *FlowSchemaSpec { + if in == nil { + return nil + } + out := new(FlowSchemaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlowSchemaStatus) DeepCopyInto(out *FlowSchemaStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]FlowSchemaCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowSchemaStatus. +func (in *FlowSchemaStatus) DeepCopy() *FlowSchemaStatus { + if in == nil { + return nil + } + out := new(FlowSchemaStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupSubject) DeepCopyInto(out *GroupSubject) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupSubject. +func (in *GroupSubject) DeepCopy() *GroupSubject { + if in == nil { + return nil + } + out := new(GroupSubject) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LimitResponse) DeepCopyInto(out *LimitResponse) { + *out = *in + if in.Queuing != nil { + in, out := &in.Queuing, &out.Queuing + *out = new(QueuingConfiguration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LimitResponse. +func (in *LimitResponse) DeepCopy() *LimitResponse { + if in == nil { + return nil + } + out := new(LimitResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LimitedPriorityLevelConfiguration) DeepCopyInto(out *LimitedPriorityLevelConfiguration) { + *out = *in + in.LimitResponse.DeepCopyInto(&out.LimitResponse) + if in.LendablePercent != nil { + in, out := &in.LendablePercent, &out.LendablePercent + *out = new(int32) + **out = **in + } + if in.BorrowingLimitPercent != nil { + in, out := &in.BorrowingLimitPercent, &out.BorrowingLimitPercent + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LimitedPriorityLevelConfiguration. +func (in *LimitedPriorityLevelConfiguration) DeepCopy() *LimitedPriorityLevelConfiguration { + if in == nil { + return nil + } + out := new(LimitedPriorityLevelConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NonResourcePolicyRule) DeepCopyInto(out *NonResourcePolicyRule) { + *out = *in + if in.Verbs != nil { + in, out := &in.Verbs, &out.Verbs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.NonResourceURLs != nil { + in, out := &in.NonResourceURLs, &out.NonResourceURLs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NonResourcePolicyRule. +func (in *NonResourcePolicyRule) DeepCopy() *NonResourcePolicyRule { + if in == nil { + return nil + } + out := new(NonResourcePolicyRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyRulesWithSubjects) DeepCopyInto(out *PolicyRulesWithSubjects) { + *out = *in + if in.Subjects != nil { + in, out := &in.Subjects, &out.Subjects + *out = make([]Subject, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ResourceRules != nil { + in, out := &in.ResourceRules, &out.ResourceRules + *out = make([]ResourcePolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NonResourceRules != nil { + in, out := &in.NonResourceRules, &out.NonResourceRules + *out = make([]NonResourcePolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyRulesWithSubjects. +func (in *PolicyRulesWithSubjects) DeepCopy() *PolicyRulesWithSubjects { + if in == nil { + return nil + } + out := new(PolicyRulesWithSubjects) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfiguration) DeepCopyInto(out *PriorityLevelConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfiguration. +func (in *PriorityLevelConfiguration) DeepCopy() *PriorityLevelConfiguration { + if in == nil { + return nil + } + out := new(PriorityLevelConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PriorityLevelConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfigurationCondition) DeepCopyInto(out *PriorityLevelConfigurationCondition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfigurationCondition. +func (in *PriorityLevelConfigurationCondition) DeepCopy() *PriorityLevelConfigurationCondition { + if in == nil { + return nil + } + out := new(PriorityLevelConfigurationCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfigurationList) DeepCopyInto(out *PriorityLevelConfigurationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PriorityLevelConfiguration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfigurationList. +func (in *PriorityLevelConfigurationList) DeepCopy() *PriorityLevelConfigurationList { + if in == nil { + return nil + } + out := new(PriorityLevelConfigurationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PriorityLevelConfigurationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfigurationReference) DeepCopyInto(out *PriorityLevelConfigurationReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfigurationReference. +func (in *PriorityLevelConfigurationReference) DeepCopy() *PriorityLevelConfigurationReference { + if in == nil { + return nil + } + out := new(PriorityLevelConfigurationReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfigurationSpec) DeepCopyInto(out *PriorityLevelConfigurationSpec) { + *out = *in + if in.Limited != nil { + in, out := &in.Limited, &out.Limited + *out = new(LimitedPriorityLevelConfiguration) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfigurationSpec. +func (in *PriorityLevelConfigurationSpec) DeepCopy() *PriorityLevelConfigurationSpec { + if in == nil { + return nil + } + out := new(PriorityLevelConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PriorityLevelConfigurationStatus) DeepCopyInto(out *PriorityLevelConfigurationStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]PriorityLevelConfigurationCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityLevelConfigurationStatus. +func (in *PriorityLevelConfigurationStatus) DeepCopy() *PriorityLevelConfigurationStatus { + if in == nil { + return nil + } + out := new(PriorityLevelConfigurationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *QueuingConfiguration) DeepCopyInto(out *QueuingConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueuingConfiguration. +func (in *QueuingConfiguration) DeepCopy() *QueuingConfiguration { + if in == nil { + return nil + } + out := new(QueuingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePolicyRule) DeepCopyInto(out *ResourcePolicyRule) { + *out = *in + if in.Verbs != nil { + in, out := &in.Verbs, &out.Verbs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.APIGroups != nil { + in, out := &in.APIGroups, &out.APIGroups + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePolicyRule. +func (in *ResourcePolicyRule) DeepCopy() *ResourcePolicyRule { + if in == nil { + return nil + } + out := new(ResourcePolicyRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceAccountSubject) DeepCopyInto(out *ServiceAccountSubject) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountSubject. +func (in *ServiceAccountSubject) DeepCopy() *ServiceAccountSubject { + if in == nil { + return nil + } + out := new(ServiceAccountSubject) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subject) DeepCopyInto(out *Subject) { + *out = *in + if in.User != nil { + in, out := &in.User, &out.User + *out = new(UserSubject) + **out = **in + } + if in.Group != nil { + in, out := &in.Group, &out.Group + *out = new(GroupSubject) + **out = **in + } + if in.ServiceAccount != nil { + in, out := &in.ServiceAccount, &out.ServiceAccount + *out = new(ServiceAccountSubject) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subject. +func (in *Subject) DeepCopy() *Subject { + if in == nil { + return nil + } + out := new(Subject) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserSubject) DeepCopyInto(out *UserSubject) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserSubject. +func (in *UserSubject) DeepCopy() *UserSubject { + if in == nil { + return nil + } + out := new(UserSubject) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.prerelease-lifecycle.go new file mode 100644 index 00000000000..24b76138500 --- /dev/null +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,94 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v1beta3 + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *FlowSchema) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *FlowSchema) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *FlowSchema) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *FlowSchemaList) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *FlowSchemaList) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *FlowSchemaList) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *PriorityLevelConfiguration) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *PriorityLevelConfiguration) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *PriorityLevelConfiguration) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *PriorityLevelConfigurationList) APILifecycleIntroduced() (major, minor int) { + return 1, 26 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *PriorityLevelConfigurationList) APILifecycleDeprecated() (major, minor int) { + return 1, 29 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *PriorityLevelConfigurationList) APILifecycleRemoved() (major, minor int) { + return 1, 32 +} diff --git a/vendor/k8s.io/api/networking/v1/generated.pb.go b/vendor/k8s.io/api/networking/v1/generated.pb.go index 631acbf9357..e9566d57e27 100644 --- a/vendor/k8s.io/api/networking/v1/generated.pb.go +++ b/vendor/k8s.io/api/networking/v1/generated.pb.go @@ -328,10 +328,94 @@ func (m *IngressList) XXX_DiscardUnknown() { var xxx_messageInfo_IngressList proto.InternalMessageInfo +func (m *IngressLoadBalancerIngress) Reset() { *m = IngressLoadBalancerIngress{} } +func (*IngressLoadBalancerIngress) ProtoMessage() {} +func (*IngressLoadBalancerIngress) Descriptor() ([]byte, []int) { + return fileDescriptor_1c72867a70a7cc90, []int{10} +} +func (m *IngressLoadBalancerIngress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerIngress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerIngress) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerIngress.Merge(m, src) +} +func (m *IngressLoadBalancerIngress) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerIngress) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerIngress.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerIngress proto.InternalMessageInfo + +func (m *IngressLoadBalancerStatus) Reset() { *m = IngressLoadBalancerStatus{} } +func (*IngressLoadBalancerStatus) ProtoMessage() {} +func (*IngressLoadBalancerStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_1c72867a70a7cc90, []int{11} +} +func (m *IngressLoadBalancerStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerStatus.Merge(m, src) +} +func (m *IngressLoadBalancerStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerStatus proto.InternalMessageInfo + +func (m *IngressPortStatus) Reset() { *m = IngressPortStatus{} } +func (*IngressPortStatus) ProtoMessage() {} +func (*IngressPortStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_1c72867a70a7cc90, []int{12} +} +func (m *IngressPortStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressPortStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressPortStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressPortStatus.Merge(m, src) +} +func (m *IngressPortStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressPortStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressPortStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressPortStatus proto.InternalMessageInfo + func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} func (*IngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{10} + return fileDescriptor_1c72867a70a7cc90, []int{13} } func (m *IngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -359,7 +443,7 @@ var xxx_messageInfo_IngressRule proto.InternalMessageInfo func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} func (*IngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{11} + return fileDescriptor_1c72867a70a7cc90, []int{14} } func (m *IngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -387,7 +471,7 @@ var xxx_messageInfo_IngressRuleValue proto.InternalMessageInfo func (m *IngressServiceBackend) Reset() { *m = IngressServiceBackend{} } func (*IngressServiceBackend) ProtoMessage() {} func (*IngressServiceBackend) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{12} + return fileDescriptor_1c72867a70a7cc90, []int{15} } func (m *IngressServiceBackend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -415,7 +499,7 @@ var xxx_messageInfo_IngressServiceBackend proto.InternalMessageInfo func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} func (*IngressSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{13} + return fileDescriptor_1c72867a70a7cc90, []int{16} } func (m *IngressSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -443,7 +527,7 @@ var xxx_messageInfo_IngressSpec proto.InternalMessageInfo func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} func (*IngressStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{14} + return fileDescriptor_1c72867a70a7cc90, []int{17} } func (m *IngressStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -471,7 +555,7 @@ var xxx_messageInfo_IngressStatus proto.InternalMessageInfo func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} func (*IngressTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{15} + return fileDescriptor_1c72867a70a7cc90, []int{18} } func (m *IngressTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -499,7 +583,7 @@ var xxx_messageInfo_IngressTLS proto.InternalMessageInfo func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} func (*NetworkPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{16} + return fileDescriptor_1c72867a70a7cc90, []int{19} } func (m *NetworkPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -527,7 +611,7 @@ var xxx_messageInfo_NetworkPolicy proto.InternalMessageInfo func (m *NetworkPolicyEgressRule) Reset() { *m = NetworkPolicyEgressRule{} } func (*NetworkPolicyEgressRule) ProtoMessage() {} func (*NetworkPolicyEgressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{17} + return fileDescriptor_1c72867a70a7cc90, []int{20} } func (m *NetworkPolicyEgressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +639,7 @@ var xxx_messageInfo_NetworkPolicyEgressRule proto.InternalMessageInfo func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } func (*NetworkPolicyIngressRule) ProtoMessage() {} func (*NetworkPolicyIngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{18} + return fileDescriptor_1c72867a70a7cc90, []int{21} } func (m *NetworkPolicyIngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -583,7 +667,7 @@ var xxx_messageInfo_NetworkPolicyIngressRule proto.InternalMessageInfo func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} func (*NetworkPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{19} + return fileDescriptor_1c72867a70a7cc90, []int{22} } func (m *NetworkPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -611,7 +695,7 @@ var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{20} + return fileDescriptor_1c72867a70a7cc90, []int{23} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -639,7 +723,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } func (*NetworkPolicyPort) ProtoMessage() {} func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{21} + return fileDescriptor_1c72867a70a7cc90, []int{24} } func (m *NetworkPolicyPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -667,7 +751,7 @@ var xxx_messageInfo_NetworkPolicyPort proto.InternalMessageInfo func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } func (*NetworkPolicySpec) ProtoMessage() {} func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{22} + return fileDescriptor_1c72867a70a7cc90, []int{25} } func (m *NetworkPolicySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -695,7 +779,7 @@ var xxx_messageInfo_NetworkPolicySpec proto.InternalMessageInfo func (m *NetworkPolicyStatus) Reset() { *m = NetworkPolicyStatus{} } func (*NetworkPolicyStatus) ProtoMessage() {} func (*NetworkPolicyStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{23} + return fileDescriptor_1c72867a70a7cc90, []int{26} } func (m *NetworkPolicyStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -723,7 +807,7 @@ var xxx_messageInfo_NetworkPolicyStatus proto.InternalMessageInfo func (m *ServiceBackendPort) Reset() { *m = ServiceBackendPort{} } func (*ServiceBackendPort) ProtoMessage() {} func (*ServiceBackendPort) Descriptor() ([]byte, []int) { - return fileDescriptor_1c72867a70a7cc90, []int{24} + return fileDescriptor_1c72867a70a7cc90, []int{27} } func (m *ServiceBackendPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -759,6 +843,9 @@ func init() { proto.RegisterType((*IngressClassParametersReference)(nil), "k8s.io.api.networking.v1.IngressClassParametersReference") proto.RegisterType((*IngressClassSpec)(nil), "k8s.io.api.networking.v1.IngressClassSpec") proto.RegisterType((*IngressList)(nil), "k8s.io.api.networking.v1.IngressList") + proto.RegisterType((*IngressLoadBalancerIngress)(nil), "k8s.io.api.networking.v1.IngressLoadBalancerIngress") + proto.RegisterType((*IngressLoadBalancerStatus)(nil), "k8s.io.api.networking.v1.IngressLoadBalancerStatus") + proto.RegisterType((*IngressPortStatus)(nil), "k8s.io.api.networking.v1.IngressPortStatus") proto.RegisterType((*IngressRule)(nil), "k8s.io.api.networking.v1.IngressRule") proto.RegisterType((*IngressRuleValue)(nil), "k8s.io.api.networking.v1.IngressRuleValue") proto.RegisterType((*IngressServiceBackend)(nil), "k8s.io.api.networking.v1.IngressServiceBackend") @@ -781,107 +868,115 @@ func init() { } var fileDescriptor_1c72867a70a7cc90 = []byte{ - // 1589 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0x3a, 0x71, 0xec, 0x3c, 0x27, 0x69, 0x3a, 0x6d, 0xf5, 0xb5, 0xfa, 0x15, 0x76, 0x58, - 0xd1, 0x36, 0x50, 0x6a, 0xd3, 0xb4, 0x42, 0x70, 0x01, 0xba, 0x69, 0x9b, 0x86, 0xa6, 0x89, 0x35, - 0x36, 0x45, 0x20, 0x40, 0xdd, 0xac, 0x27, 0xce, 0xd6, 0xeb, 0x9d, 0x65, 0x76, 0x1c, 0x5a, 0x4e, - 0x5c, 0x38, 0x70, 0xe3, 0xc6, 0x99, 0x3f, 0x01, 0xc1, 0x0d, 0x41, 0xc5, 0x05, 0xf5, 0x58, 0x89, - 0x4b, 0x2f, 0x58, 0xd4, 0xfc, 0x17, 0x39, 0xa1, 0x99, 0x9d, 0xfd, 0xe1, 0x75, 0xdc, 0xac, 0xaa, - 0x2a, 0xa7, 0x64, 0xdf, 0x8f, 0xcf, 0xfb, 0x39, 0xef, 0xcd, 0x18, 0xae, 0x75, 0xdf, 0xf1, 0x6b, - 0x36, 0xad, 0x77, 0xfb, 0x3b, 0x84, 0xb9, 0x84, 0x13, 0xbf, 0xbe, 0x4f, 0xdc, 0x36, 0x65, 0x75, - 0xc5, 0x30, 0x3d, 0xbb, 0xee, 0x12, 0xfe, 0x15, 0x65, 0x5d, 0xdb, 0xed, 0xd4, 0xf7, 0x2f, 0xd7, - 0x3b, 0xc4, 0x25, 0xcc, 0xe4, 0xa4, 0x5d, 0xf3, 0x18, 0xe5, 0x14, 0x95, 0x03, 0xc9, 0x9a, 0xe9, - 0xd9, 0xb5, 0x58, 0xb2, 0xb6, 0x7f, 0xf9, 0xec, 0xa5, 0x8e, 0xcd, 0xf7, 0xfa, 0x3b, 0x35, 0x8b, - 0xf6, 0xea, 0x1d, 0xda, 0xa1, 0x75, 0xa9, 0xb0, 0xd3, 0xdf, 0x95, 0x5f, 0xf2, 0x43, 0xfe, 0x17, - 0x00, 0x9d, 0xd5, 0x13, 0x26, 0x2d, 0xca, 0xc8, 0x21, 0xc6, 0xce, 0x5e, 0x8d, 0x65, 0x7a, 0xa6, - 0xb5, 0x67, 0xbb, 0x84, 0x3d, 0xac, 0x7b, 0xdd, 0x8e, 0x20, 0xf8, 0xf5, 0x1e, 0xe1, 0xe6, 0x61, - 0x5a, 0xf5, 0x49, 0x5a, 0xac, 0xef, 0x72, 0xbb, 0x47, 0xc6, 0x14, 0xde, 0x3e, 0x4a, 0xc1, 0xb7, - 0xf6, 0x48, 0xcf, 0x1c, 0xd3, 0xbb, 0x32, 0x49, 0xaf, 0xcf, 0x6d, 0xa7, 0x6e, 0xbb, 0xdc, 0xe7, - 0x2c, 0xad, 0xa4, 0xff, 0xae, 0xc1, 0x89, 0x5b, 0xad, 0x56, 0x63, 0xc3, 0xed, 0x30, 0xe2, 0xfb, - 0x0d, 0x93, 0xef, 0xa1, 0x65, 0x98, 0xf1, 0x4c, 0xbe, 0x57, 0xd6, 0x96, 0xb5, 0x95, 0x39, 0x63, - 0xfe, 0xf1, 0xa0, 0x3a, 0x35, 0x1c, 0x54, 0x67, 0x04, 0x0f, 0x4b, 0x0e, 0xba, 0x0a, 0x45, 0xf1, - 0xb7, 0xf5, 0xd0, 0x23, 0xe5, 0x69, 0x29, 0x55, 0x1e, 0x0e, 0xaa, 0xc5, 0x86, 0xa2, 0x1d, 0x24, - 0xfe, 0xc7, 0x91, 0x24, 0x6a, 0x42, 0x61, 0xc7, 0xb4, 0xba, 0xc4, 0x6d, 0x97, 0x73, 0xcb, 0xda, - 0x4a, 0x69, 0x75, 0xa5, 0x36, 0xa9, 0x7c, 0x35, 0xe5, 0x8f, 0x11, 0xc8, 0x1b, 0x27, 0x94, 0x13, - 0x05, 0x45, 0xc0, 0x21, 0x92, 0xbe, 0x0b, 0xa7, 0x13, 0xfe, 0xe3, 0xbe, 0x43, 0xee, 0x9a, 0x4e, - 0x9f, 0xa0, 0x2d, 0xc8, 0x0b, 0xc3, 0x7e, 0x59, 0x5b, 0x9e, 0x5e, 0x29, 0xad, 0xbe, 0x3e, 0xd9, - 0x54, 0x2a, 0x7c, 0x63, 0x41, 0xd9, 0xca, 0x8b, 0x2f, 0x1f, 0x07, 0x30, 0xfa, 0x36, 0x14, 0x36, - 0x1a, 0x86, 0x43, 0xad, 0xae, 0xc8, 0x8f, 0x65, 0xb7, 0x59, 0x3a, 0x3f, 0x6b, 0x1b, 0xd7, 0x31, - 0x96, 0x1c, 0xa4, 0xc3, 0x2c, 0x79, 0x60, 0x11, 0x8f, 0x97, 0x73, 0xcb, 0xd3, 0x2b, 0x73, 0x06, - 0x0c, 0x07, 0xd5, 0xd9, 0x1b, 0x92, 0x82, 0x15, 0x47, 0xff, 0x36, 0x07, 0x05, 0x65, 0x16, 0xdd, - 0x83, 0xa2, 0x68, 0x9f, 0xb6, 0xc9, 0x4d, 0x89, 0x5a, 0x5a, 0x7d, 0x2b, 0xe1, 0x6f, 0x54, 0xcd, - 0x9a, 0xd7, 0xed, 0x08, 0x82, 0x5f, 0x13, 0xd2, 0xc2, 0xf7, 0xed, 0x9d, 0xfb, 0xc4, 0xe2, 0x77, - 0x08, 0x37, 0x0d, 0xa4, 0xfc, 0x80, 0x98, 0x86, 0x23, 0x54, 0xb4, 0x0e, 0x33, 0xbe, 0x47, 0x2c, - 0x95, 0xf8, 0x73, 0x47, 0x26, 0xbe, 0xe9, 0x11, 0x2b, 0x0e, 0x4d, 0x7c, 0x61, 0x09, 0x80, 0xb6, - 0x61, 0xd6, 0xe7, 0x26, 0xef, 0xfb, 0xb2, 0xf0, 0xa5, 0xd5, 0x0b, 0x47, 0x43, 0x49, 0x71, 0x63, - 0x51, 0x81, 0xcd, 0x06, 0xdf, 0x58, 0xc1, 0xe8, 0x7f, 0x68, 0xb0, 0x38, 0x5a, 0x6d, 0x74, 0x17, - 0x0a, 0x3e, 0x61, 0xfb, 0xb6, 0x45, 0xca, 0x33, 0xd2, 0x48, 0xfd, 0x68, 0x23, 0x81, 0x7c, 0xd8, - 0x2f, 0x25, 0xd1, 0x2b, 0x8a, 0x86, 0x43, 0x30, 0xf4, 0x31, 0x14, 0x19, 0xf1, 0x69, 0x9f, 0x59, - 0x44, 0x79, 0x7f, 0x29, 0x09, 0x2c, 0xce, 0xbd, 0x80, 0x14, 0xcd, 0xda, 0xde, 0xa4, 0x96, 0xe9, - 0x04, 0xa9, 0xc4, 0x64, 0x97, 0x30, 0xe2, 0x5a, 0xc4, 0x98, 0x17, 0x5d, 0x8e, 0x15, 0x04, 0x8e, - 0xc0, 0xc4, 0x29, 0x9a, 0x57, 0x8e, 0xac, 0x39, 0xe6, 0xb1, 0x14, 0x74, 0x73, 0xa4, 0xa0, 0x6f, - 0x1c, 0x99, 0x20, 0xe9, 0xd7, 0xa4, 0xaa, 0xea, 0xbf, 0x69, 0xb0, 0x94, 0x14, 0xdc, 0xb4, 0x7d, - 0x8e, 0x3e, 0x1b, 0x0b, 0xa2, 0x96, 0x2d, 0x08, 0xa1, 0x2d, 0x43, 0x58, 0x52, 0xa6, 0x8a, 0x21, - 0x25, 0x11, 0xc0, 0x6d, 0xc8, 0xdb, 0x9c, 0xf4, 0x7c, 0x79, 0x44, 0x4a, 0xab, 0xe7, 0xb3, 0x45, - 0x10, 0x9f, 0xce, 0x0d, 0xa1, 0x8c, 0x03, 0x0c, 0xfd, 0x6f, 0x0d, 0xaa, 0x49, 0xb1, 0x86, 0xc9, - 0xcc, 0x1e, 0xe1, 0x84, 0xf9, 0x51, 0xf1, 0xd0, 0x0a, 0x14, 0xcd, 0xc6, 0xc6, 0x3a, 0xa3, 0x7d, - 0x2f, 0x3c, 0xba, 0xc2, 0xb5, 0x6b, 0x8a, 0x86, 0x23, 0xae, 0x38, 0xe0, 0x5d, 0x5b, 0x4d, 0xa9, - 0xc4, 0x01, 0xbf, 0x6d, 0xbb, 0x6d, 0x2c, 0x39, 0x42, 0xc2, 0x35, 0x7b, 0xe1, 0xf0, 0x8b, 0x24, - 0xb6, 0xcc, 0x1e, 0xc1, 0x92, 0x83, 0xaa, 0x90, 0xf7, 0x2d, 0xea, 0x05, 0x1d, 0x3c, 0x67, 0xcc, - 0x09, 0x97, 0x9b, 0x82, 0x80, 0x03, 0x3a, 0xba, 0x08, 0x73, 0x42, 0xd0, 0xf7, 0x4c, 0x8b, 0x94, - 0xf3, 0x52, 0x68, 0x61, 0x38, 0xa8, 0xce, 0x6d, 0x85, 0x44, 0x1c, 0xf3, 0xf5, 0x9f, 0x52, 0xf5, - 0x11, 0xa5, 0x43, 0xab, 0x00, 0x16, 0x75, 0x39, 0xa3, 0x8e, 0x43, 0xc2, 0x69, 0x14, 0x35, 0xcd, - 0x5a, 0xc4, 0xc1, 0x09, 0x29, 0x64, 0x03, 0x78, 0x51, 0x6e, 0x54, 0xf3, 0xbc, 0x9b, 0x2d, 0xf5, - 0x87, 0xe4, 0xd4, 0x58, 0x14, 0xa6, 0x12, 0x8c, 0x04, 0xb8, 0xfe, 0xb3, 0x06, 0x25, 0xa5, 0x7f, - 0x0c, 0xed, 0x74, 0x73, 0xb4, 0x9d, 0x5e, 0x3d, 0x7a, 0xb5, 0x1c, 0xde, 0x49, 0x3f, 0xc6, 0x5e, - 0x8b, 0x65, 0x22, 0x2a, 0xbd, 0x47, 0x7d, 0x9e, 0x1e, 0xf6, 0xb7, 0xa8, 0xcf, 0xb1, 0xe4, 0x20, - 0x0f, 0x96, 0xec, 0xd4, 0xf6, 0xc9, 0x7c, 0x2a, 0x23, 0x0d, 0xa3, 0xac, 0x90, 0x97, 0xd2, 0x1c, - 0x3c, 0x86, 0xae, 0xdf, 0x83, 0x31, 0x29, 0x31, 0x0f, 0xf6, 0x38, 0xf7, 0x0e, 0xc9, 0xec, 0xe4, - 0x75, 0x17, 0x5b, 0x2f, 0xca, 0x98, 0x5a, 0xad, 0x06, 0x96, 0x28, 0xfa, 0x77, 0x1a, 0x9c, 0x39, - 0x74, 0xb2, 0x46, 0x9d, 0xaf, 0x4d, 0xec, 0xfc, 0x2d, 0x98, 0xf1, 0x28, 0xe3, 0x2a, 0x07, 0x6f, - 0x4e, 0xf6, 0x64, 0x14, 0xb9, 0x41, 0x19, 0x4f, 0x5c, 0x36, 0x28, 0xe3, 0x58, 0xe2, 0xe8, 0x7f, - 0xe6, 0xa2, 0x8a, 0xc8, 0xb6, 0xff, 0x20, 0xca, 0xb7, 0x6c, 0x4b, 0x61, 0x59, 0x1d, 0xb2, 0xd3, - 0x89, 0xfc, 0x45, 0x3c, 0x3c, 0x26, 0x8d, 0xda, 0xb0, 0xd8, 0x26, 0xbb, 0x66, 0xdf, 0xe1, 0xca, - 0xb6, 0xca, 0x5a, 0xf6, 0xfb, 0x08, 0x1a, 0x0e, 0xaa, 0x8b, 0xd7, 0x47, 0x30, 0x70, 0x0a, 0x13, - 0xad, 0xc1, 0x34, 0x77, 0xc2, 0x7e, 0x7c, 0xed, 0x48, 0xe8, 0xd6, 0x66, 0xd3, 0x28, 0xa9, 0xf0, - 0xa7, 0x5b, 0x9b, 0x4d, 0x2c, 0xb4, 0xd1, 0x87, 0x90, 0x67, 0x7d, 0x87, 0x88, 0x6d, 0x3b, 0x9d, - 0x69, 0x71, 0x8b, 0x9a, 0xc6, 0xad, 0x2d, 0xbe, 0x7c, 0x1c, 0x40, 0xe8, 0x5f, 0xc2, 0xc2, 0xc8, - 0x4a, 0x46, 0xf7, 0x60, 0xde, 0xa1, 0x66, 0xdb, 0x30, 0x1d, 0xd3, 0xb5, 0xd4, 0x08, 0x49, 0x4d, - 0xe2, 0x70, 0x27, 0x6e, 0x26, 0xe4, 0xd4, 0x42, 0x3f, 0xad, 0x8c, 0xcc, 0x27, 0x79, 0x78, 0x04, - 0x51, 0x37, 0x01, 0xe2, 0xf0, 0xc4, 0x4c, 0x14, 0x27, 0x26, 0xb8, 0x93, 0xa9, 0x99, 0x28, 0x0e, - 0x92, 0x8f, 0x03, 0xba, 0x98, 0x68, 0x3e, 0xb1, 0x18, 0xe1, 0xb2, 0xa8, 0xb9, 0xd1, 0x89, 0xd6, - 0x8c, 0x38, 0x38, 0x21, 0xa5, 0xff, 0x90, 0x83, 0x85, 0xad, 0x20, 0x13, 0x0d, 0xea, 0xd8, 0xd6, - 0xc3, 0x63, 0x58, 0xbe, 0x77, 0x46, 0x96, 0xef, 0xc5, 0xc9, 0x45, 0x19, 0x71, 0x6c, 0xe2, 0x9d, - 0xea, 0xa3, 0xd4, 0x9d, 0xea, 0x52, 0x56, 0xc0, 0xe7, 0xdf, 0xac, 0x7e, 0xd1, 0xe0, 0x7f, 0x23, - 0xf2, 0x37, 0xe2, 0xb1, 0xd6, 0x80, 0xbc, 0x38, 0x5c, 0xe1, 0xf5, 0x38, 0x6b, 0x08, 0xf2, 0x90, - 0xc6, 0x17, 0x64, 0x81, 0x80, 0x03, 0x20, 0xb4, 0x0e, 0x39, 0x4e, 0x55, 0xb7, 0x67, 0x86, 0x23, - 0x84, 0x19, 0xa0, 0xe0, 0x72, 0x2d, 0x8a, 0x73, 0x9c, 0xea, 0xbf, 0x6a, 0x50, 0x1e, 0x91, 0x4a, - 0x8e, 0xe3, 0x97, 0xef, 0xf7, 0x1d, 0x98, 0xd9, 0x65, 0xb4, 0xf7, 0x22, 0x9e, 0x47, 0xb5, 0xbc, - 0xc9, 0x68, 0x0f, 0x4b, 0x18, 0xfd, 0x91, 0x06, 0x27, 0x47, 0x24, 0x8f, 0x61, 0xf7, 0x6d, 0x8e, - 0xee, 0xbe, 0x0b, 0x19, 0x63, 0x98, 0xb0, 0x01, 0x1f, 0xe5, 0x52, 0x11, 0x88, 0x58, 0xd1, 0x2e, - 0x94, 0x3c, 0xda, 0x6e, 0x12, 0x87, 0x58, 0x9c, 0x86, 0xa3, 0xe2, 0x4a, 0xc6, 0x20, 0xcc, 0x1d, - 0xe2, 0x84, 0xaa, 0xc6, 0x89, 0xe1, 0xa0, 0x5a, 0x6a, 0xc4, 0x58, 0x38, 0x09, 0x8c, 0x1e, 0xc0, - 0xc9, 0xe8, 0xda, 0x13, 0x59, 0xcb, 0xbd, 0xb8, 0xb5, 0x33, 0xc3, 0x41, 0xf5, 0xe4, 0x56, 0x1a, - 0x11, 0x8f, 0x1b, 0x41, 0xb7, 0xa0, 0x60, 0x7b, 0xf2, 0x85, 0xa7, 0x8e, 0xe1, 0xf3, 0xee, 0x10, - 0xc1, 0x53, 0x30, 0x78, 0x67, 0xa8, 0x0f, 0x1c, 0xaa, 0xeb, 0x7f, 0xa5, 0x7b, 0x40, 0x34, 0x1c, - 0x5a, 0x87, 0xa2, 0x7c, 0x73, 0x5b, 0xd4, 0x51, 0xdb, 0xf3, 0xa2, 0x7c, 0x34, 0x2b, 0xda, 0xc1, - 0xa0, 0xfa, 0xff, 0xf1, 0x1f, 0x21, 0x6a, 0x21, 0x1b, 0x47, 0xca, 0xa9, 0x05, 0x3b, 0x79, 0xb6, - 0x89, 0x77, 0x7f, 0x2d, 0x78, 0xf7, 0xd7, 0x36, 0x5c, 0xbe, 0xcd, 0x9a, 0x9c, 0xd9, 0x6e, 0x27, - 0x58, 0xf6, 0xf1, 0x82, 0x45, 0xe7, 0xa0, 0xa0, 0xf6, 0xaf, 0x0c, 0x3c, 0x1f, 0x44, 0x75, 0x23, - 0x20, 0xe1, 0x90, 0xa7, 0x1f, 0xa4, 0xfb, 0x42, 0x6e, 0xe3, 0xfb, 0x2f, 0xad, 0x2f, 0x4e, 0xa9, - 0x6e, 0x9c, 0xdc, 0x1b, 0x9f, 0x43, 0x41, 0xed, 0x72, 0xd5, 0xe9, 0xab, 0x19, 0x3b, 0x3d, 0xb9, - 0x1b, 0xa3, 0x9f, 0x12, 0x42, 0x62, 0x88, 0x89, 0x3e, 0x81, 0x59, 0x12, 0xa0, 0x07, 0xcb, 0xf6, - 0x72, 0x46, 0xf4, 0x78, 0xac, 0xc6, 0xa3, 0x58, 0xd1, 0x14, 0x20, 0x7a, 0x5f, 0x64, 0x49, 0xc8, - 0x8a, 0xb7, 0xa5, 0x5f, 0x9e, 0x91, 0xfb, 0xef, 0x95, 0x20, 0xd8, 0x88, 0x7c, 0x20, 0xee, 0xd2, - 0xd1, 0x27, 0x4e, 0x6a, 0xe8, 0x5f, 0xc3, 0xa9, 0x43, 0x46, 0x3f, 0xb2, 0xe4, 0x13, 0xa0, 0x6d, - 0x73, 0x9b, 0xba, 0xe1, 0x4c, 0xac, 0x67, 0x4b, 0xfe, 0x5a, 0xa8, 0x37, 0xf2, 0x66, 0x50, 0x50, - 0x38, 0x01, 0xab, 0x7f, 0x01, 0x68, 0xfc, 0xaa, 0x96, 0xe1, 0x22, 0x78, 0x1e, 0x66, 0xdd, 0x7e, - 0x6f, 0x87, 0x04, 0xe7, 0x37, 0x1f, 0x27, 0x67, 0x4b, 0x52, 0xb1, 0xe2, 0x1a, 0xef, 0x3d, 0x7e, - 0x56, 0x99, 0x7a, 0xf2, 0xac, 0x32, 0xf5, 0xf4, 0x59, 0x65, 0xea, 0x9b, 0x61, 0x45, 0x7b, 0x3c, - 0xac, 0x68, 0x4f, 0x86, 0x15, 0xed, 0xe9, 0xb0, 0xa2, 0xfd, 0x33, 0xac, 0x68, 0xdf, 0xff, 0x5b, - 0x99, 0xfa, 0xb4, 0x3c, 0xe9, 0x47, 0xc1, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x43, 0xa0, - 0xa5, 0x48, 0x14, 0x00, 0x00, + // 1715 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4b, 0x6f, 0x1b, 0x47, + 0x12, 0xd6, 0x50, 0xa2, 0x48, 0x35, 0x25, 0x59, 0x6a, 0xdb, 0x58, 0xae, 0x16, 0x4b, 0x6a, 0x07, + 0x6b, 0x5b, 0xbb, 0xb6, 0xc9, 0xb5, 0x6c, 0x2c, 0x76, 0x2f, 0x49, 0x3c, 0xb2, 0x2c, 0x2b, 0x96, + 0x29, 0xa2, 0xc9, 0x38, 0x48, 0x90, 0x87, 0x47, 0xc3, 0x16, 0x35, 0xe6, 0x70, 0x7a, 0xd0, 0xd3, + 0x54, 0xac, 0x20, 0x08, 0x72, 0xc9, 0x21, 0xb7, 0xdc, 0x72, 0x0e, 0xf2, 0x0b, 0x82, 0xe4, 0x10, + 0x20, 0x48, 0x8c, 0x5c, 0x02, 0x1f, 0x0d, 0xe4, 0xe2, 0x4b, 0x88, 0x98, 0xf9, 0x17, 0x3a, 0x05, + 0xfd, 0x98, 0x17, 0x1f, 0x22, 0x63, 0x18, 0x3a, 0x49, 0x5d, 0x55, 0xfd, 0x75, 0xbd, 0xab, 0x86, + 0xe0, 0x66, 0xeb, 0x7f, 0x7e, 0xc9, 0x26, 0xe5, 0x56, 0x67, 0x0f, 0x53, 0x17, 0x33, 0xec, 0x97, + 0x0f, 0xb1, 0xdb, 0x20, 0xb4, 0xac, 0x18, 0xa6, 0x67, 0x97, 0x5d, 0xcc, 0x3e, 0x20, 0xb4, 0x65, + 0xbb, 0xcd, 0xf2, 0xe1, 0xb5, 0x72, 0x13, 0xbb, 0x98, 0x9a, 0x0c, 0x37, 0x4a, 0x1e, 0x25, 0x8c, + 0xc0, 0xbc, 0x94, 0x2c, 0x99, 0x9e, 0x5d, 0x8a, 0x24, 0x4b, 0x87, 0xd7, 0x56, 0xae, 0x36, 0x6d, + 0x76, 0xd0, 0xd9, 0x2b, 0x59, 0xa4, 0x5d, 0x6e, 0x92, 0x26, 0x29, 0x8b, 0x0b, 0x7b, 0x9d, 0x7d, + 0x71, 0x12, 0x07, 0xf1, 0x9f, 0x04, 0x5a, 0xd1, 0x63, 0x4f, 0x5a, 0x84, 0xe2, 0x21, 0x8f, 0xad, + 0xdc, 0x88, 0x64, 0xda, 0xa6, 0x75, 0x60, 0xbb, 0x98, 0x1e, 0x95, 0xbd, 0x56, 0x93, 0x13, 0xfc, + 0x72, 0x1b, 0x33, 0x73, 0xd8, 0xad, 0xf2, 0xa8, 0x5b, 0xb4, 0xe3, 0x32, 0xbb, 0x8d, 0x07, 0x2e, + 0xfc, 0x77, 0xdc, 0x05, 0xdf, 0x3a, 0xc0, 0x6d, 0x73, 0xe0, 0xde, 0xf5, 0x51, 0xf7, 0x3a, 0xcc, + 0x76, 0xca, 0xb6, 0xcb, 0x7c, 0x46, 0xfb, 0x2f, 0xe9, 0x3f, 0x6a, 0xe0, 0xcc, 0x9d, 0x7a, 0xbd, + 0xba, 0xed, 0x36, 0x29, 0xf6, 0xfd, 0xaa, 0xc9, 0x0e, 0xe0, 0x2a, 0x98, 0xf1, 0x4c, 0x76, 0x90, + 0xd7, 0x56, 0xb5, 0xb5, 0x39, 0x63, 0xfe, 0x49, 0xb7, 0x38, 0xd5, 0xeb, 0x16, 0x67, 0x38, 0x0f, + 0x09, 0x0e, 0xbc, 0x01, 0xb2, 0xfc, 0x6f, 0xfd, 0xc8, 0xc3, 0xf9, 0x69, 0x21, 0x95, 0xef, 0x75, + 0x8b, 0xd9, 0xaa, 0xa2, 0x1d, 0xc7, 0xfe, 0x47, 0xa1, 0x24, 0xac, 0x81, 0xcc, 0x9e, 0x69, 0xb5, + 0xb0, 0xdb, 0xc8, 0xa7, 0x56, 0xb5, 0xb5, 0xdc, 0xfa, 0x5a, 0x69, 0x54, 0xf8, 0x4a, 0x4a, 0x1f, + 0x43, 0xca, 0x1b, 0x67, 0x94, 0x12, 0x19, 0x45, 0x40, 0x01, 0x92, 0xbe, 0x0f, 0xce, 0xc5, 0xf4, + 0x47, 0x1d, 0x07, 0xdf, 0x37, 0x9d, 0x0e, 0x86, 0x15, 0x90, 0xe6, 0x0f, 0xfb, 0x79, 0x6d, 0x75, + 0x7a, 0x2d, 0xb7, 0xfe, 0xaf, 0xd1, 0x4f, 0xf5, 0x99, 0x6f, 0x2c, 0xa8, 0xb7, 0xd2, 0xfc, 0xe4, + 0x23, 0x09, 0xa3, 0xef, 0x82, 0xcc, 0x76, 0xd5, 0x70, 0x88, 0xd5, 0xe2, 0xfe, 0xb1, 0xec, 0x06, + 0xed, 0xf7, 0xcf, 0xc6, 0xf6, 0x2d, 0x84, 0x04, 0x07, 0xea, 0x60, 0x16, 0x3f, 0xb2, 0xb0, 0xc7, + 0xf2, 0xa9, 0xd5, 0xe9, 0xb5, 0x39, 0x03, 0xf4, 0xba, 0xc5, 0xd9, 0x4d, 0x41, 0x41, 0x8a, 0xa3, + 0x7f, 0x9a, 0x02, 0x19, 0xf5, 0x2c, 0x7c, 0x00, 0xb2, 0x3c, 0x7d, 0x1a, 0x26, 0x33, 0x05, 0x6a, + 0x6e, 0xfd, 0x3f, 0x31, 0x7d, 0xc3, 0x68, 0x96, 0xbc, 0x56, 0x93, 0x13, 0xfc, 0x12, 0x97, 0xe6, + 0xba, 0xef, 0xee, 0x3d, 0xc4, 0x16, 0xbb, 0x87, 0x99, 0x69, 0x40, 0xa5, 0x07, 0x88, 0x68, 0x28, + 0x44, 0x85, 0x5b, 0x60, 0xc6, 0xf7, 0xb0, 0xa5, 0x1c, 0x7f, 0x61, 0xac, 0xe3, 0x6b, 0x1e, 0xb6, + 0x22, 0xd3, 0xf8, 0x09, 0x09, 0x00, 0xb8, 0x0b, 0x66, 0x7d, 0x66, 0xb2, 0x8e, 0x2f, 0x02, 0x9f, + 0x5b, 0xbf, 0x34, 0x1e, 0x4a, 0x88, 0x1b, 0x8b, 0x0a, 0x6c, 0x56, 0x9e, 0x91, 0x82, 0xd1, 0x7f, + 0xd2, 0xc0, 0x62, 0x32, 0xda, 0xf0, 0x3e, 0xc8, 0xf8, 0x98, 0x1e, 0xda, 0x16, 0xce, 0xcf, 0x88, + 0x47, 0xca, 0xe3, 0x1f, 0x91, 0xf2, 0x41, 0xbe, 0xe4, 0x78, 0xae, 0x28, 0x1a, 0x0a, 0xc0, 0xe0, + 0x9b, 0x20, 0x4b, 0xb1, 0x4f, 0x3a, 0xd4, 0xc2, 0x4a, 0xfb, 0xab, 0x71, 0x60, 0x5e, 0xf7, 0x1c, + 0x92, 0x27, 0x6b, 0x63, 0x87, 0x58, 0xa6, 0x23, 0x5d, 0x89, 0xf0, 0x3e, 0xa6, 0xd8, 0xb5, 0xb0, + 0x31, 0xcf, 0xb3, 0x1c, 0x29, 0x08, 0x14, 0x82, 0xf1, 0x2a, 0x9a, 0x57, 0x8a, 0x6c, 0x38, 0xe6, + 0xa9, 0x04, 0x74, 0x27, 0x11, 0xd0, 0x7f, 0x8f, 0x75, 0x90, 0xd0, 0x6b, 0x54, 0x54, 0xf5, 0x1f, + 0x34, 0xb0, 0x14, 0x17, 0xdc, 0xb1, 0x7d, 0x06, 0xdf, 0x19, 0x30, 0xa2, 0x34, 0x99, 0x11, 0xfc, + 0xb6, 0x30, 0x61, 0x49, 0x3d, 0x95, 0x0d, 0x28, 0x31, 0x03, 0xee, 0x82, 0xb4, 0xcd, 0x70, 0xdb, + 0x17, 0x25, 0x92, 0x5b, 0xbf, 0x38, 0x99, 0x05, 0x51, 0x75, 0x6e, 0xf3, 0xcb, 0x48, 0x62, 0xe8, + 0xbf, 0x6a, 0xa0, 0x18, 0x17, 0xab, 0x9a, 0xd4, 0x6c, 0x63, 0x86, 0xa9, 0x1f, 0x06, 0x0f, 0xae, + 0x81, 0xac, 0x59, 0xdd, 0xde, 0xa2, 0xa4, 0xe3, 0x05, 0xa5, 0xcb, 0x55, 0xbb, 0xa9, 0x68, 0x28, + 0xe4, 0xf2, 0x02, 0x6f, 0xd9, 0xaa, 0x4b, 0xc5, 0x0a, 0xfc, 0xae, 0xed, 0x36, 0x90, 0xe0, 0x70, + 0x09, 0xd7, 0x6c, 0x07, 0xcd, 0x2f, 0x94, 0xa8, 0x98, 0x6d, 0x8c, 0x04, 0x07, 0x16, 0x41, 0xda, + 0xb7, 0x88, 0x27, 0x33, 0x78, 0xce, 0x98, 0xe3, 0x2a, 0xd7, 0x38, 0x01, 0x49, 0x3a, 0xbc, 0x0c, + 0xe6, 0xb8, 0xa0, 0xef, 0x99, 0x16, 0xce, 0xa7, 0x85, 0xd0, 0x42, 0xaf, 0x5b, 0x9c, 0xab, 0x04, + 0x44, 0x14, 0xf1, 0xf5, 0xaf, 0xfb, 0xe2, 0xc3, 0x43, 0x07, 0xd7, 0x01, 0xb0, 0x88, 0xcb, 0x28, + 0x71, 0x1c, 0x1c, 0x74, 0xa3, 0x30, 0x69, 0x36, 0x42, 0x0e, 0x8a, 0x49, 0x41, 0x1b, 0x00, 0x2f, + 0xf4, 0x8d, 0x4a, 0x9e, 0xff, 0x4f, 0xe6, 0xfa, 0x21, 0x3e, 0x35, 0x16, 0xf9, 0x53, 0x31, 0x46, + 0x0c, 0x5c, 0xff, 0x46, 0x03, 0x39, 0x75, 0xff, 0x14, 0xd2, 0xe9, 0x76, 0x32, 0x9d, 0xfe, 0x31, + 0x7e, 0xb4, 0x0c, 0xcf, 0xa4, 0xef, 0x34, 0xb0, 0x12, 0x68, 0x4d, 0xcc, 0x86, 0x61, 0x3a, 0xa6, + 0x6b, 0x61, 0x1a, 0x74, 0xea, 0x15, 0x90, 0xb2, 0x83, 0xf4, 0x01, 0x0a, 0x20, 0xb5, 0x5d, 0x45, + 0x29, 0xdb, 0x83, 0x57, 0x40, 0xf6, 0x80, 0xf8, 0x4c, 0x24, 0x86, 0x4c, 0x9d, 0x50, 0xe1, 0x3b, + 0x8a, 0x8e, 0x42, 0x09, 0x58, 0x05, 0x69, 0x8f, 0x50, 0xe6, 0xe7, 0x67, 0x84, 0xc2, 0x97, 0xc7, + 0x2a, 0x5c, 0x25, 0x94, 0xa9, 0x5e, 0x1a, 0x8d, 0x28, 0x8e, 0x80, 0x24, 0x90, 0xfe, 0x11, 0xf8, + 0xeb, 0x10, 0xcd, 0xe5, 0x15, 0xf8, 0x3e, 0xc8, 0xd8, 0x92, 0xa9, 0x26, 0xe2, 0x8d, 0xb1, 0x0f, + 0x0e, 0xb1, 0x3f, 0x1a, 0xc4, 0xc1, 0xc0, 0x0d, 0x50, 0xf5, 0xaf, 0x34, 0xb0, 0x3c, 0xa0, 0xa9, + 0xd8, 0x25, 0x08, 0x65, 0xc2, 0x63, 0xe9, 0xd8, 0x2e, 0x41, 0x28, 0x43, 0x82, 0x03, 0xef, 0x82, + 0xac, 0x58, 0x45, 0x2c, 0xe2, 0x28, 0xaf, 0x95, 0x03, 0xaf, 0x55, 0x15, 0xfd, 0xb8, 0x5b, 0xfc, + 0xdb, 0xe0, 0x7e, 0x56, 0x0a, 0xd8, 0x28, 0x04, 0xe0, 0x55, 0x87, 0x29, 0x25, 0x54, 0x15, 0xa6, + 0xa8, 0xba, 0x4d, 0x4e, 0x40, 0x92, 0xae, 0x7f, 0x19, 0x25, 0x25, 0xdf, 0x15, 0xb8, 0x7e, 0x3c, + 0x22, 0xfd, 0xb3, 0x9c, 0xc7, 0x0b, 0x09, 0x0e, 0xf4, 0xc0, 0x92, 0xdd, 0xb7, 0x5c, 0x4c, 0xdc, + 0x74, 0xc3, 0x1b, 0x46, 0x5e, 0x21, 0x2f, 0xf5, 0x73, 0xd0, 0x00, 0xba, 0xfe, 0x00, 0x0c, 0x48, + 0xf1, 0x76, 0x7f, 0xc0, 0x98, 0x37, 0xa4, 0x70, 0x46, 0x6f, 0x33, 0xd1, 0xeb, 0x59, 0x61, 0x53, + 0xbd, 0x5e, 0x45, 0x02, 0x45, 0xff, 0x4c, 0x03, 0xe7, 0x87, 0x0e, 0xce, 0xb0, 0xb1, 0x69, 0x23, + 0x1b, 0x5b, 0x45, 0x45, 0x54, 0xfa, 0xe0, 0xca, 0x68, 0x4d, 0x92, 0xc8, 0x3c, 0xe2, 0xc3, 0xe2, + 0xaf, 0xff, 0x9c, 0x0a, 0x23, 0x22, 0xba, 0xda, 0x6b, 0xa1, 0xbf, 0x45, 0xd7, 0xe1, 0x2f, 0xab, + 0x1e, 0x7a, 0x2e, 0xe6, 0xbf, 0x90, 0x87, 0x06, 0xa4, 0x61, 0x03, 0x2c, 0x36, 0xf0, 0xbe, 0xd9, + 0x71, 0x98, 0x7a, 0x5b, 0x79, 0x6d, 0xf2, 0x75, 0x13, 0xf6, 0xba, 0xc5, 0xc5, 0x5b, 0x09, 0x0c, + 0xd4, 0x87, 0x09, 0x37, 0xc0, 0x34, 0x73, 0x82, 0x76, 0xf3, 0xcf, 0xb1, 0xd0, 0xf5, 0x9d, 0x9a, + 0x91, 0x53, 0xe6, 0x4f, 0xd7, 0x77, 0x6a, 0x88, 0xdf, 0x86, 0xaf, 0x83, 0x34, 0xed, 0x38, 0x98, + 0x2f, 0x53, 0xd3, 0x13, 0xed, 0x65, 0x3c, 0xa6, 0x51, 0xf9, 0xf3, 0x93, 0x8f, 0x24, 0x84, 0xfe, + 0x31, 0x58, 0x48, 0x6c, 0x5c, 0xb0, 0x0d, 0xe6, 0x9d, 0x58, 0x09, 0x2b, 0x2f, 0x5c, 0xff, 0x53, + 0x75, 0xaf, 0x1a, 0xce, 0x39, 0xf5, 0xe2, 0x7c, 0x9c, 0x87, 0x12, 0xf0, 0xba, 0x09, 0x40, 0x64, + 0x2b, 0xaf, 0x44, 0x5e, 0x3e, 0xb2, 0xdb, 0xa8, 0x4a, 0xe4, 0x55, 0xe5, 0x23, 0x49, 0xe7, 0xd3, + 0xcb, 0xc7, 0x16, 0xc5, 0xac, 0x12, 0xf5, 0xcb, 0x70, 0x7a, 0xd5, 0x42, 0x0e, 0x8a, 0x49, 0xe9, + 0x5f, 0xa4, 0xc0, 0x42, 0x45, 0xaa, 0x5c, 0x25, 0x8e, 0x6d, 0x1d, 0x9d, 0xc2, 0xa2, 0x75, 0x2f, + 0xb1, 0x68, 0x9d, 0xd0, 0xa6, 0x13, 0x8a, 0x8d, 0xdc, 0x9f, 0xdf, 0xe8, 0xdb, 0x9f, 0xaf, 0x4e, + 0x0a, 0x78, 0xf2, 0x16, 0xfd, 0xad, 0x06, 0xfe, 0x92, 0x90, 0xdf, 0x8c, 0x7a, 0x5c, 0x38, 0x69, + 0xb4, 0x71, 0x93, 0x26, 0x81, 0x20, 0x2a, 0x76, 0xe8, 0xa4, 0x81, 0x5b, 0x20, 0xc5, 0x88, 0x4a, + 0xfd, 0x89, 0xe1, 0x30, 0xa6, 0xd1, 0xc8, 0xac, 0x13, 0x94, 0x62, 0x44, 0xff, 0x5e, 0x03, 0xf9, + 0x84, 0x54, 0xbc, 0x37, 0xbf, 0x7c, 0xbd, 0xef, 0x81, 0x99, 0x7d, 0x4a, 0xda, 0x2f, 0xa2, 0x79, + 0x18, 0xcb, 0xdb, 0x94, 0xb4, 0x91, 0x80, 0xd1, 0x1f, 0x6b, 0x60, 0x39, 0x21, 0x79, 0x0a, 0x7b, + 0xce, 0x4e, 0x72, 0xcf, 0xb9, 0x34, 0xa1, 0x0d, 0x23, 0xb6, 0x9d, 0xc7, 0xa9, 0x3e, 0x0b, 0xb8, + 0xad, 0x70, 0x1f, 0xe4, 0x3c, 0xd2, 0xa8, 0x61, 0x07, 0x5b, 0x8c, 0x0c, 0xeb, 0x1b, 0x27, 0x19, + 0x61, 0xee, 0x61, 0x27, 0xb8, 0x6a, 0x9c, 0xe9, 0x75, 0x8b, 0xb9, 0x6a, 0x84, 0x85, 0xe2, 0xc0, + 0xf0, 0x11, 0x58, 0x0e, 0x57, 0xdc, 0xf0, 0xb5, 0xd4, 0x8b, 0xbf, 0x76, 0xbe, 0xd7, 0x2d, 0x2e, + 0x57, 0xfa, 0x11, 0xd1, 0xe0, 0x23, 0xf0, 0x0e, 0xc8, 0xd8, 0x9e, 0xf8, 0x9a, 0x57, 0x65, 0x78, + 0xd2, 0xbe, 0x28, 0x3f, 0xfb, 0xe5, 0x37, 0xa5, 0x3a, 0xa0, 0xe0, 0xba, 0xfe, 0x4b, 0x7f, 0x0e, + 0xf0, 0x84, 0x83, 0x5b, 0xb1, 0xa5, 0x46, 0x8e, 0xd2, 0xcb, 0x2f, 0xb6, 0xd0, 0x24, 0xa7, 0xed, + 0xe8, 0xde, 0xd6, 0x61, 0xb6, 0x53, 0x92, 0xbf, 0xf1, 0x94, 0xb6, 0x5d, 0xb6, 0x4b, 0x6b, 0x8c, + 0xda, 0x6e, 0x53, 0x4e, 0xfe, 0xd8, 0xb6, 0x75, 0x01, 0x64, 0xd4, 0x30, 0x16, 0x86, 0xa7, 0xa5, + 0x55, 0x9b, 0x92, 0x84, 0x02, 0x9e, 0x7e, 0xdc, 0x9f, 0x17, 0x62, 0x34, 0x3f, 0x7c, 0x69, 0x79, + 0x71, 0x56, 0x65, 0xe3, 0xe8, 0xdc, 0x78, 0x37, 0xda, 0x57, 0x65, 0xa6, 0xaf, 0x4f, 0x98, 0xe9, + 0xf1, 0x41, 0x39, 0x72, 0x5b, 0x85, 0x6f, 0x81, 0x59, 0x2c, 0xd1, 0xe5, 0xe4, 0xbd, 0x36, 0x21, + 0x7a, 0xd4, 0x56, 0xa3, 0x56, 0xac, 0x68, 0x0a, 0x10, 0xbe, 0xca, 0xbd, 0xc4, 0x65, 0xeb, 0x47, + 0x1e, 0x96, 0xeb, 0xfd, 0x9c, 0xf1, 0x77, 0x69, 0x6c, 0x48, 0x3e, 0xe6, 0xdf, 0x4d, 0xe1, 0x11, + 0xc5, 0x6f, 0xe8, 0x1f, 0x82, 0xb3, 0x43, 0x5a, 0x3f, 0xb4, 0xc4, 0xe7, 0x5e, 0xc3, 0x66, 0x36, + 0x71, 0x83, 0x9e, 0x58, 0x9e, 0xcc, 0xf9, 0x1b, 0xc1, 0xbd, 0xc4, 0xf7, 0xa1, 0x82, 0x42, 0x31, + 0x58, 0xfd, 0x3d, 0x00, 0x07, 0xf7, 0xb6, 0x09, 0xb6, 0xc2, 0x8b, 0x60, 0xd6, 0xed, 0xb4, 0xf7, + 0xb0, 0xac, 0xdf, 0x74, 0xe4, 0x9c, 0x8a, 0xa0, 0x22, 0xc5, 0x35, 0x5e, 0x79, 0xf2, 0xbc, 0x30, + 0xf5, 0xf4, 0x79, 0x61, 0xea, 0xd9, 0xf3, 0xc2, 0xd4, 0x27, 0xbd, 0x82, 0xf6, 0xa4, 0x57, 0xd0, + 0x9e, 0xf6, 0x0a, 0xda, 0xb3, 0x5e, 0x41, 0xfb, 0xad, 0x57, 0xd0, 0x3e, 0xff, 0xbd, 0x30, 0xf5, + 0x76, 0x7e, 0xd4, 0x0f, 0xc0, 0x7f, 0x04, 0x00, 0x00, 0xff, 0xff, 0x61, 0x0f, 0x0a, 0xd7, 0x34, + 0x16, 0x00, 0x00, } func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { @@ -1334,6 +1429,128 @@ func (m *IngressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *IngressLoadBalancerIngress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerIngress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerIngress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ports) > 0 { + for iNdEx := len(m.Ports) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ports[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + i -= len(m.Hostname) + copy(dAtA[i:], m.Hostname) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Hostname))) + i-- + dAtA[i] = 0x12 + i -= len(m.IP) + copy(dAtA[i:], m.IP) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IP))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IngressLoadBalancerStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ingress) > 0 { + for iNdEx := len(m.Ingress) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ingress[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *IngressPortStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressPortStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressPortStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != nil { + i -= len(*m.Error) + copy(dAtA[i:], *m.Error) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Error))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0x12 + i = encodeVarintGenerated(dAtA, i, uint64(m.Port)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *IngressRule) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2210,6 +2427,56 @@ func (m *IngressList) Size() (n int) { return n } +func (m *IngressLoadBalancerIngress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.IP) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Hostname) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Ports) > 0 { + for _, e := range m.Ports { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressLoadBalancerStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ingress) > 0 { + for _, e := range m.Ingress { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressPortStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Port)) + l = len(m.Protocol) + n += 1 + l + sovGenerated(uint64(l)) + if m.Error != nil { + l = len(*m.Error) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *IngressRule) Size() (n int) { if m == nil { return 0 @@ -2612,6 +2879,50 @@ func (this *IngressList) String() string { }, "") return s } +func (this *IngressLoadBalancerIngress) String() string { + if this == nil { + return "nil" + } + repeatedStringForPorts := "[]IngressPortStatus{" + for _, f := range this.Ports { + repeatedStringForPorts += strings.Replace(strings.Replace(f.String(), "IngressPortStatus", "IngressPortStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForPorts += "}" + s := strings.Join([]string{`&IngressLoadBalancerIngress{`, + `IP:` + fmt.Sprintf("%v", this.IP) + `,`, + `Hostname:` + fmt.Sprintf("%v", this.Hostname) + `,`, + `Ports:` + repeatedStringForPorts + `,`, + `}`, + }, "") + return s +} +func (this *IngressLoadBalancerStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForIngress := "[]IngressLoadBalancerIngress{" + for _, f := range this.Ingress { + repeatedStringForIngress += strings.Replace(strings.Replace(f.String(), "IngressLoadBalancerIngress", "IngressLoadBalancerIngress", 1), `&`, ``, 1) + "," + } + repeatedStringForIngress += "}" + s := strings.Join([]string{`&IngressLoadBalancerStatus{`, + `Ingress:` + repeatedStringForIngress + `,`, + `}`, + }, "") + return s +} +func (this *IngressPortStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IngressPortStatus{`, + `Port:` + fmt.Sprintf("%v", this.Port) + `,`, + `Protocol:` + fmt.Sprintf("%v", this.Protocol) + `,`, + `Error:` + valueToStringGenerated(this.Error) + `,`, + `}`, + }, "") + return s +} func (this *IngressRule) String() string { if this == nil { return "nil" @@ -2672,7 +2983,7 @@ func (this *IngressStatus) String() string { return "nil" } s := strings.Join([]string{`&IngressStatus{`, - `LoadBalancer:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LoadBalancer), "LoadBalancerStatus", "v11.LoadBalancerStatus", 1), `&`, ``, 1) + `,`, + `LoadBalancer:` + strings.Replace(strings.Replace(this.LoadBalancer.String(), "IngressLoadBalancerStatus", "IngressLoadBalancerStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -4137,6 +4448,372 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { } return nil } +func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressLoadBalancerIngress: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressLoadBalancerIngress: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IP", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IP = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hostname = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, IngressPortStatus{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ingress = append(m.Ingress, IngressLoadBalancerIngress{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressPortStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressPortStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + m.Port = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Port |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocol = k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Error = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *IngressRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/networking/v1/generated.proto b/vendor/k8s.io/api/networking/v1/generated.proto index ec806639695..ed194a89d56 100644 --- a/vendor/k8s.io/api/networking/v1/generated.proto +++ b/vendor/k8s.io/api/networking/v1/generated.proto @@ -33,14 +33,14 @@ option go_package = "k8s.io/api/networking/v1"; // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional optional string path = 1; - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -56,7 +56,7 @@ message HTTPIngressPath { // Implementations are required to support all path types. optional string pathType = 3; - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; } @@ -67,22 +67,22 @@ message HTTPIngressPath { // to match against everything after the last '/' and before the first '?' // or '#'. message HTTPIngressRuleValue { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. // +listType=atomic repeated HTTPIngressPath paths = 1; } -// IPBlock describes a particular CIDR (Ex. "192.168.1.1/24","2001:db9::/64") that is allowed +// IPBlock describes a particular CIDR (Ex. "192.168.1.0/24","2001:db8::/64") that is allowed // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. message IPBlock { - // CIDR is a string representing the IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // cidr is a string representing the IPBlock + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" optional string cidr = 1; - // Except is a slice of CIDRs that should not be included within an IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" - // Except values will be rejected if they are outside the CIDR range + // except is a slice of CIDRs that should not be included within an IPBlock + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // Except values will be rejected if they are outside the cidr range // +optional repeated string except = 2; } @@ -97,12 +97,12 @@ message Ingress { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressSpec spec = 2; - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressStatus status = 3; @@ -110,12 +110,12 @@ message Ingress { // IngressBackend describes all endpoints for a given service and port. message IngressBackend { - // Service references a Service as a Backend. + // service references a service as a backend. // This is a mutually exclusive setting with "Resource". // +optional optional IngressServiceBackend service = 4; - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, a service.Name and // service.Port must not be specified. // This is a mutually exclusive setting with "Service". @@ -134,7 +134,7 @@ message IngressClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressClassSpec spec = 2; @@ -146,31 +146,31 @@ message IngressClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of IngressClasses. + // items is the list of IngressClasses. repeated IngressClass items = 2; } // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. message IngressClassParametersReference { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional optional string aPIGroup = 1; - // Kind is the type of resource being referenced. + // kind is the type of resource being referenced. optional string kind = 2; - // Name is the name of resource being referenced. + // name is the name of resource being referenced. optional string name = 3; - // Scope represents if this refers to a cluster or namespace scoped resource. + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". // +optional optional string scope = 4; - // Namespace is the namespace of the resource being referenced. This field is + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -179,15 +179,15 @@ message IngressClassParametersReference { // IngressClassSpec provides information about the class of an Ingress. message IngressClassSpec { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. optional string controller = 1; - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -201,15 +201,62 @@ message IngressList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of Ingress. + // items is the list of Ingress. repeated Ingress items = 2; } +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +message IngressLoadBalancerIngress { + // ip is set for load-balancer ingress points that are IP based. + // +optional + optional string ip = 1; + + // hostname is set for load-balancer ingress points that are DNS based. + // +optional + optional string hostname = 2; + + // ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic + // +optional + repeated IngressPortStatus ports = 4; +} + +// IngressLoadBalancerStatus represents the status of a load-balancer. +message IngressLoadBalancerStatus { + // ingress is a list containing ingress points for the load-balancer. + // +optional + repeated IngressLoadBalancerIngress ingress = 1; +} + +// IngressPortStatus represents the error condition of a service port +message IngressPortStatus { + // port is the port number of the ingress port. + optional int32 port = 1; + + // protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + optional string protocol = 2; + + // error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + optional string error = 3; +} + // IngressRule represents the rules mapping the paths under a specified host to // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. message IngressRule { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -222,14 +269,14 @@ message IngressRule { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and // matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). // Requests will be matched against the Host field in the following way: - // 1. If Host is precise, the request matches this rule if the http host header is equal to Host. - // 2. If Host is a wildcard, then the request matches this rule if the http host header + // 1. If host is precise, the request matches this rule if the http host header is equal to Host. + // 2. If host is a wildcard, then the request matches this rule if the http host header // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional optional string host = 1; @@ -254,48 +301,48 @@ message IngressRuleValue { // IngressServiceBackend references a Kubernetes Service as a Backend. message IngressServiceBackend { - // Name is the referenced service. The service must exist in + // name is the referenced service. The service must exist in // the same namespace as the Ingress object. optional string name = 1; - // Port of the referenced service. A port name or port number + // port of the referenced service. A port name or port number // is required for a IngressServiceBackend. optional ServiceBackendPort port = 2; } // IngressSpec describes the Ingress the user wishes to exist. message IngressSpec { - // IngressClassName is the name of the IngressClass cluster resource. The - // associated IngressClass defines which controller will implement the - // resource. This replaces the deprecated `kubernetes.io/ingress.class` - // annotation. For backwards compatibility, when that annotation is set, it - // must be given precedence over this field. The controller may emit a - // warning if the field and annotation have different values. - // Implementations of this API should ignore Ingresses without a class - // specified. An IngressClass resource may be marked as default, which can - // be used to set a default value for this field. For more information, - // refer to the IngressClass documentation. + // ingressClassName is the name of an IngressClass cluster resource. Ingress + // controller implementations use this field to know whether they should be + // serving this Ingress resource, by a transitive connection + // (controller -> IngressClass -> Ingress resource). Although the + // `kubernetes.io/ingress.class` annotation (simple constant name) was never + // formally defined, it was widely supported by Ingress controllers to create + // a direct binding between Ingress controller and Ingress resources. Newly + // created Ingress resources should prefer using the field. However, even + // though the annotation is officially deprecated, for backwards compatibility + // reasons, ingress controllers should still honor that annotation if present. // +optional optional string ingressClassName = 4; - // DefaultBackend is the backend that should handle requests that don't + // defaultBackend is the backend that should handle requests that don't // match any rule. If Rules are not specified, DefaultBackend must be specified. // If DefaultBackend is not set, the handling of requests that do not match any // of the rules will be up to the Ingress controller. // +optional optional IngressBackend defaultBackend = 1; - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +listType=atomic // +optional repeated IngressTLS tls = 2; - // A list of host rules used to configure the Ingress. If unspecified, or - // no rule matches, all traffic is sent to the default backend. + // rules is a list of host rules used to configure the Ingress. If unspecified, + // or no rule matches, all traffic is sent to the default backend. // +listType=atomic // +optional repeated IngressRule rules = 3; @@ -303,14 +350,14 @@ message IngressSpec { // IngressStatus describe the current state of the Ingress. message IngressStatus { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional - optional k8s.io.api.core.v1.LoadBalancerStatus loadBalancer = 1; + optional IngressLoadBalancerStatus loadBalancer = 1; } -// IngressTLS describes the transport layer security associated with an Ingress. +// IngressTLS describes the transport layer security associated with an ingress. message IngressTLS { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. @@ -318,11 +365,11 @@ message IngressTLS { // +optional repeated string hosts = 1; - // SecretName is the name of the secret used to terminate TLS traffic on + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination - // and value of the Host header is used for routing. + // and value of the "Host" header is used for routing. // +optional optional string secretName = 2; } @@ -334,11 +381,11 @@ message NetworkPolicy { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior for this NetworkPolicy. + // spec represents the specification of the desired behavior for this NetworkPolicy. // +optional optional NetworkPolicySpec spec = 2; - // Status is the current state of the NetworkPolicy. + // status represents the current state of the NetworkPolicy. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional NetworkPolicyStatus status = 3; @@ -348,7 +395,7 @@ message NetworkPolicy { // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. // This type is beta-level in 1.8 message NetworkPolicyEgressRule { - // List of destination ports for outgoing traffic. + // ports is a list of destination ports for outgoing traffic. // Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows @@ -356,7 +403,7 @@ message NetworkPolicyEgressRule { // +optional repeated NetworkPolicyPort ports = 1; - // List of destinations for outgoing traffic of pods selected for this rule. + // to is a list of destinations for outgoing traffic of pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all destinations (traffic not restricted by // destination). If this field is present and contains at least one item, this rule @@ -368,15 +415,15 @@ message NetworkPolicyEgressRule { // NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. message NetworkPolicyIngressRule { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is + // ports is a list of ports which should be made accessible on the pods selected for + // this rule. Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows // traffic only if the traffic matches at least one port in the list. // +optional repeated NetworkPolicyPort ports = 1; - // List of sources which should be able to access the pods selected for this rule. + // from is a list of sources which should be able to access the pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all sources (traffic not restricted by // source). If this field is present and contains at least one item, this rule @@ -392,32 +439,32 @@ message NetworkPolicyList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated NetworkPolicy items = 2; } // NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of // fields are allowed message NetworkPolicyPeer { - // This is a label selector which selects Pods. This field follows standard label + // podSelector is a label selector which selects pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. // - // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. + // If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the Namespaces selected by NamespaceSelector. + // Otherwise it selects the pods matching podSelector in the policy's own namespace. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector podSelector = 1; - // Selects Namespaces using cluster-scoped labels. This field follows standard label - // selector semantics; if present but empty, it selects all namespaces. + // namespaceSelector selects namespaces using cluster-scoped labels. This field follows + // standard label selector semantics; if present but empty, it selects all namespaces. // - // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. + // If podSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the namespaces selected by namespaceSelector. + // Otherwise it selects all pods in the namespaces selected by namespaceSelector. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 2; - // IPBlock defines policy on a particular IPBlock. If this field is set then + // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional optional IPBlock ipBlock = 3; @@ -425,40 +472,38 @@ message NetworkPolicyPeer { // NetworkPolicyPort describes a port to allow traffic on message NetworkPolicyPort { - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this - // field defaults to TCP. + // protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. + // If not specified, this field defaults to TCP. // +optional optional string protocol = 1; - // The port on the given protocol. This can either be a numerical or named + // port represents the port on the given protocol. This can either be a numerical or named // port on a pod. If this field is not provided, this matches all port names and // numbers. // If present, only traffic on the specified protocol AND port will be matched. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString port = 2; - // If set, indicates that the range of ports from port to endPort, inclusive, + // endPort indicates that the range of ports from port to endPort if set, inclusive, // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional optional int32 endPort = 3; } // NetworkPolicySpec provides the specification of a NetworkPolicy message NetworkPolicySpec { - // Selects the pods to which this NetworkPolicy object applies. The array of - // ingress rules is applied to any pods selected by this field. Multiple network - // policies can select the same set of pods. In this case, the ingress rules for - // each are combined additively. This field is NOT optional and follows standard - // label selector semantics. An empty podSelector matches all pods in this - // namespace. + // podSelector selects the pods to which this NetworkPolicy object applies. + // The array of ingress rules is applied to any pods selected by this field. + // Multiple network policies can select the same set of pods. In this case, + // the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector podSelector = 1; - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod + // ingress is a list of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod // (and cluster policy otherwise allows the traffic), OR if the traffic source is // the pod's local node, OR if the traffic matches at least one ingress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If @@ -467,8 +512,8 @@ message NetworkPolicySpec { // +optional repeated NetworkPolicyIngressRule ingress = 2; - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic + // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy // otherwise allows the traffic), OR if the traffic matches at least one egress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves @@ -477,23 +522,23 @@ message NetworkPolicySpec { // +optional repeated NetworkPolicyEgressRule egress = 3; - // List of rule types that the NetworkPolicy relates to. + // policyTypes is a list of rule types that the NetworkPolicy relates to. // Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If this field is not specified, it will default based on the existence of ingress or egress rules; + // policies that contain an egress section are assumed to affect egress, and all policies + // (whether or not they contain an ingress section) are assumed to affect ingress. // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. // Likewise, if you want to write a policy that specifies that no egress is allowed, // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). + // an egress section and would otherwise default to just [ "Ingress" ]). // This field is beta-level in 1.8 // +optional repeated string policyTypes = 4; } -// NetworkPolicyStatus describe the current state of the NetworkPolicy. +// NetworkPolicyStatus describes the current state of the NetworkPolicy. message NetworkPolicyStatus { - // Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. + // conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. // Current service state // +optional // +patchMergeKey=type @@ -505,12 +550,12 @@ message NetworkPolicyStatus { // ServiceBackendPort is the service port being referenced. message ServiceBackendPort { - // Name is the name of the port on the Service. + // name is the name of the port on the Service. // This is a mutually exclusive setting with "Number". // +optional optional string name = 1; - // Number is the numerical port number (e.g. 80) on the Service. + // number is the numerical port number (e.g. 80) on the Service. // This is a mutually exclusive setting with "Name". // +optional optional int32 number = 2; diff --git a/vendor/k8s.io/api/networking/v1/types.go b/vendor/k8s.io/api/networking/v1/types.go index bb6da40987d..fa7cf1bd700 100644 --- a/vendor/k8s.io/api/networking/v1/types.go +++ b/vendor/k8s.io/api/networking/v1/types.go @@ -28,16 +28,17 @@ import ( // NetworkPolicy describes what network traffic is allowed for a set of Pods type NetworkPolicy struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior for this NetworkPolicy. + // spec represents the specification of the desired behavior for this NetworkPolicy. // +optional Spec NetworkPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the NetworkPolicy. + // status represents the current state of the NetworkPolicy. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status NetworkPolicyStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -57,16 +58,16 @@ const ( // NetworkPolicySpec provides the specification of a NetworkPolicy type NetworkPolicySpec struct { - // Selects the pods to which this NetworkPolicy object applies. The array of - // ingress rules is applied to any pods selected by this field. Multiple network - // policies can select the same set of pods. In this case, the ingress rules for - // each are combined additively. This field is NOT optional and follows standard - // label selector semantics. An empty podSelector matches all pods in this - // namespace. + // podSelector selects the pods to which this NetworkPolicy object applies. + // The array of ingress rules is applied to any pods selected by this field. + // Multiple network policies can select the same set of pods. In this case, + // the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. PodSelector metav1.LabelSelector `json:"podSelector" protobuf:"bytes,1,opt,name=podSelector"` - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod + // ingress is a list of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod // (and cluster policy otherwise allows the traffic), OR if the traffic source is // the pod's local node, OR if the traffic matches at least one ingress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If @@ -75,8 +76,8 @@ type NetworkPolicySpec struct { // +optional Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic + // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy // otherwise allows the traffic), OR if the traffic matches at least one egress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves @@ -85,15 +86,15 @@ type NetworkPolicySpec struct { // +optional Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` - // List of rule types that the NetworkPolicy relates to. + // policyTypes is a list of rule types that the NetworkPolicy relates to. // Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If this field is not specified, it will default based on the existence of ingress or egress rules; + // policies that contain an egress section are assumed to affect egress, and all policies + // (whether or not they contain an ingress section) are assumed to affect ingress. // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. // Likewise, if you want to write a policy that specifies that no egress is allowed, // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). + // an egress section and would otherwise default to just [ "Ingress" ]). // This field is beta-level in 1.8 // +optional PolicyTypes []PolicyType `json:"policyTypes,omitempty" protobuf:"bytes,4,rep,name=policyTypes,casttype=PolicyType"` @@ -102,15 +103,15 @@ type NetworkPolicySpec struct { // NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. type NetworkPolicyIngressRule struct { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is + // ports is a list of ports which should be made accessible on the pods selected for + // this rule. Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows // traffic only if the traffic matches at least one port in the list. // +optional Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - // List of sources which should be able to access the pods selected for this rule. + // from is a list of sources which should be able to access the pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all sources (traffic not restricted by // source). If this field is present and contains at least one item, this rule @@ -123,7 +124,7 @@ type NetworkPolicyIngressRule struct { // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. // This type is beta-level in 1.8 type NetworkPolicyEgressRule struct { - // List of destination ports for outgoing traffic. + // ports is a list of destination ports for outgoing traffic. // Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows @@ -131,7 +132,7 @@ type NetworkPolicyEgressRule struct { // +optional Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - // List of destinations for outgoing traffic of pods selected for this rule. + // to is a list of destinations for outgoing traffic of pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all destinations (traffic not restricted by // destination). If this field is present and contains at least one item, this rule @@ -142,38 +143,37 @@ type NetworkPolicyEgressRule struct { // NetworkPolicyPort describes a port to allow traffic on type NetworkPolicyPort struct { - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this - // field defaults to TCP. + // protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. + // If not specified, this field defaults to TCP. // +optional Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,1,opt,name=protocol,casttype=k8s.io/api/core/v1.Protocol"` - // The port on the given protocol. This can either be a numerical or named + // port represents the port on the given protocol. This can either be a numerical or named // port on a pod. If this field is not provided, this matches all port names and // numbers. // If present, only traffic on the specified protocol AND port will be matched. // +optional Port *intstr.IntOrString `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` - // If set, indicates that the range of ports from port to endPort, inclusive, + // endPort indicates that the range of ports from port to endPort if set, inclusive, // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"` } -// IPBlock describes a particular CIDR (Ex. "192.168.1.1/24","2001:db9::/64") that is allowed +// IPBlock describes a particular CIDR (Ex. "192.168.1.0/24","2001:db8::/64") that is allowed // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. type IPBlock struct { - // CIDR is a string representing the IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" + // cidr is a string representing the IPBlock + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"` - // Except is a slice of CIDRs that should not be included within an IP Block - // Valid examples are "192.168.1.1/24" or "2001:db9::/64" - // Except values will be rejected if they are outside the CIDR range + + // except is a slice of CIDRs that should not be included within an IPBlock + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // Except values will be rejected if they are outside the cidr range // +optional Except []string `json:"except,omitempty" protobuf:"bytes,2,rep,name=except"` } @@ -181,25 +181,25 @@ type IPBlock struct { // NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of // fields are allowed type NetworkPolicyPeer struct { - // This is a label selector which selects Pods. This field follows standard label + // podSelector is a label selector which selects pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. // - // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. + // If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the Namespaces selected by NamespaceSelector. + // Otherwise it selects the pods matching podSelector in the policy's own namespace. // +optional PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"` - // Selects Namespaces using cluster-scoped labels. This field follows standard label - // selector semantics; if present but empty, it selects all namespaces. + // namespaceSelector selects namespaces using cluster-scoped labels. This field follows + // standard label selector semantics; if present but empty, it selects all namespaces. // - // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. + // If podSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the namespaces selected by namespaceSelector. + // Otherwise it selects all pods in the namespaces selected by namespaceSelector. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"` - // IPBlock defines policy on a particular IPBlock. If this field is set then + // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` @@ -235,9 +235,9 @@ const ( NetworkPolicyConditionReasonFeatureNotSupported NetworkPolicyConditionReason = "FeatureNotSupported" ) -// NetworkPolicyStatus describe the current state of the NetworkPolicy. +// NetworkPolicyStatus describes the current state of the NetworkPolicy. type NetworkPolicyStatus struct { - // Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. + // conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. // Current service state // +optional // +patchMergeKey=type @@ -252,12 +252,13 @@ type NetworkPolicyStatus struct { // NetworkPolicyList is a list of NetworkPolicy objects. type NetworkPolicyList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []NetworkPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -270,17 +271,18 @@ type NetworkPolicyList struct { // based virtual hosting etc. type Ingress struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status IngressStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -291,83 +293,132 @@ type Ingress struct { // IngressList is a collection of Ingress. type IngressList struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of Ingress. + // items is the list of Ingress. Items []Ingress `json:"items" protobuf:"bytes,2,rep,name=items"` } // IngressSpec describes the Ingress the user wishes to exist. type IngressSpec struct { - // IngressClassName is the name of the IngressClass cluster resource. The - // associated IngressClass defines which controller will implement the - // resource. This replaces the deprecated `kubernetes.io/ingress.class` - // annotation. For backwards compatibility, when that annotation is set, it - // must be given precedence over this field. The controller may emit a - // warning if the field and annotation have different values. - // Implementations of this API should ignore Ingresses without a class - // specified. An IngressClass resource may be marked as default, which can - // be used to set a default value for this field. For more information, - // refer to the IngressClass documentation. + // ingressClassName is the name of an IngressClass cluster resource. Ingress + // controller implementations use this field to know whether they should be + // serving this Ingress resource, by a transitive connection + // (controller -> IngressClass -> Ingress resource). Although the + // `kubernetes.io/ingress.class` annotation (simple constant name) was never + // formally defined, it was widely supported by Ingress controllers to create + // a direct binding between Ingress controller and Ingress resources. Newly + // created Ingress resources should prefer using the field. However, even + // though the annotation is officially deprecated, for backwards compatibility + // reasons, ingress controllers should still honor that annotation if present. // +optional IngressClassName *string `json:"ingressClassName,omitempty" protobuf:"bytes,4,opt,name=ingressClassName"` - // DefaultBackend is the backend that should handle requests that don't + // defaultBackend is the backend that should handle requests that don't // match any rule. If Rules are not specified, DefaultBackend must be specified. // If DefaultBackend is not set, the handling of requests that do not match any // of the rules will be up to the Ingress controller. // +optional DefaultBackend *IngressBackend `json:"defaultBackend,omitempty" protobuf:"bytes,1,opt,name=defaultBackend"` - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +listType=atomic // +optional TLS []IngressTLS `json:"tls,omitempty" protobuf:"bytes,2,rep,name=tls"` - // A list of host rules used to configure the Ingress. If unspecified, or - // no rule matches, all traffic is sent to the default backend. + // rules is a list of host rules used to configure the Ingress. If unspecified, + // or no rule matches, all traffic is sent to the default backend. // +listType=atomic // +optional Rules []IngressRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` } -// IngressTLS describes the transport layer security associated with an Ingress. +// IngressTLS describes the transport layer security associated with an ingress. type IngressTLS struct { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +listType=atomic // +optional Hosts []string `json:"hosts,omitempty" protobuf:"bytes,1,rep,name=hosts"` - // SecretName is the name of the secret used to terminate TLS traffic on + + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination - // and value of the Host header is used for routing. + // and value of the "Host" header is used for routing. // +optional SecretName string `json:"secretName,omitempty" protobuf:"bytes,2,opt,name=secretName"` } // IngressStatus describe the current state of the Ingress. type IngressStatus struct { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. + // +optional + LoadBalancer IngressLoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` +} + +// IngressLoadBalancerStatus represents the status of a load-balancer. +type IngressLoadBalancerStatus struct { + // ingress is a list containing ingress points for the load-balancer. + // +optional + Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` +} + +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +type IngressLoadBalancerIngress struct { + // ip is set for load-balancer ingress points that are IP based. + // +optional + IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` + + // hostname is set for load-balancer ingress points that are DNS based. + // +optional + Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` + + // ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic // +optional - LoadBalancer v1.LoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` + Ports []IngressPortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"` +} + +// IngressPortStatus represents the error condition of a service port +type IngressPortStatus struct { + // port is the port number of the ingress port. + Port int32 `json:"port" protobuf:"varint,1,opt,name=port"` + + // protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + Protocol v1.Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` + + // error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + Error *string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"` } // IngressRule represents the rules mapping the paths under a specified host to // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. type IngressRule struct { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -380,14 +431,14 @@ type IngressRule struct { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and // matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). // Requests will be matched against the Host field in the following way: - // 1. If Host is precise, the request matches this rule if the http host header is equal to Host. - // 2. If Host is a wildcard, then the request matches this rule if the http host header + // 1. If host is precise, the request matches this rule if the http host header is equal to Host. + // 2. If host is a wildcard, then the request matches this rule if the http host header // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional Host string `json:"host,omitempty" protobuf:"bytes,1,opt,name=host"` @@ -415,7 +466,7 @@ type IngressRuleValue struct { // to match against everything after the last '/' and before the first '?' // or '#'. type HTTPIngressRuleValue struct { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. // +listType=atomic Paths []HTTPIngressPath `json:"paths" protobuf:"bytes,1,rep,name=paths"` } @@ -454,14 +505,14 @@ const ( // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. type HTTPIngressPath struct { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -477,19 +528,19 @@ type HTTPIngressPath struct { // Implementations are required to support all path types. PathType *PathType `json:"pathType" protobuf:"bytes,3,opt,name=pathType"` - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` } // IngressBackend describes all endpoints for a given service and port. type IngressBackend struct { - // Service references a Service as a Backend. + // service references a service as a backend. // This is a mutually exclusive setting with "Resource". // +optional Service *IngressServiceBackend `json:"service,omitempty" protobuf:"bytes,4,opt,name=service"` - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, a service.Name and // service.Port must not be specified. // This is a mutually exclusive setting with "Service". @@ -499,23 +550,23 @@ type IngressBackend struct { // IngressServiceBackend references a Kubernetes Service as a Backend. type IngressServiceBackend struct { - // Name is the referenced service. The service must exist in + // name is the referenced service. The service must exist in // the same namespace as the Ingress object. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Port of the referenced service. A port name or port number + // port of the referenced service. A port name or port number // is required for a IngressServiceBackend. Port ServiceBackendPort `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` } // ServiceBackendPort is the service port being referenced. type ServiceBackendPort struct { - // Name is the name of the port on the Service. + // name is the name of the port on the Service. // This is a mutually exclusive setting with "Number". // +optional Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Number is the numerical port number (e.g. 80) on the Service. + // number is the numerical port number (e.g. 80) on the Service. // This is a mutually exclusive setting with "Name". // +optional Number int32 `json:"number,omitempty" protobuf:"bytes,2,opt,name=number"` @@ -532,12 +583,13 @@ type ServiceBackendPort struct { // resources without a class specified will be assigned this default class. type IngressClass struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressClassSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -545,15 +597,15 @@ type IngressClass struct { // IngressClassSpec provides information about the class of an Ingress. type IngressClassSpec struct { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. Controller string `json:"controller,omitempty" protobuf:"bytes,1,opt,name=controller"` - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -564,7 +616,7 @@ const ( // IngressClassParametersReferenceScopeNamespace indicates that the // referenced Parameters resource is namespace-scoped. IngressClassParametersReferenceScopeNamespace = "Namespace" - // IngressClassParametersReferenceScopeNamespace indicates that the + // IngressClassParametersReferenceScopeCluster indicates that the // referenced Parameters resource is cluster-scoped. IngressClassParametersReferenceScopeCluster = "Cluster" ) @@ -572,20 +624,24 @@ const ( // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. type IngressClassParametersReference struct { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` - // Kind is the type of resource being referenced. + + // kind is the type of resource being referenced. Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - // Name is the name of resource being referenced. + + // name is the name of resource being referenced. Name string `json:"name" protobuf:"bytes,3,opt,name=name"` - // Scope represents if this refers to a cluster or namespace scoped resource. + + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". // +optional Scope *string `json:"scope" protobuf:"bytes,4,opt,name=scope"` - // Namespace is the namespace of the resource being referenced. This field is + + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -597,10 +653,11 @@ type IngressClassParametersReference struct { // IngressClassList is a collection of IngressClasses. type IngressClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of IngressClasses. + // items is the list of IngressClasses. Items []IngressClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go index 8e7870daefd..91161d5ca4e 100644 --- a/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", - "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "path": "path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", + "pathType": "pathType determines the interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types.", + "backend": "backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (HTTPIngressPath) SwaggerDoc() map[string]string { var map_HTTPIngressRuleValue = map[string]string{ "": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", - "paths": "A collection of paths that map requests to backends.", + "paths": "paths is a collection of paths that map requests to backends.", } func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { @@ -48,9 +48,9 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { } var map_IPBlock = map[string]string{ - "": "IPBlock describes a particular CIDR (Ex. \"192.168.1.1/24\",\"2001:db9::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", - "cidr": "CIDR is a string representing the IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\"", - "except": "Except is a slice of CIDRs that should not be included within an IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\" Except values will be rejected if they are outside the CIDR range", + "": "IPBlock describes a particular CIDR (Ex. \"192.168.1.0/24\",\"2001:db8::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", + "cidr": "cidr is a string representing the IPBlock Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", + "except": "except is a slice of CIDRs that should not be included within an IPBlock Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\" Except values will be rejected if they are outside the cidr range", } func (IPBlock) SwaggerDoc() map[string]string { @@ -60,8 +60,8 @@ func (IPBlock) SwaggerDoc() map[string]string { var map_Ingress = map[string]string{ "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", - "status": "Status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Ingress) SwaggerDoc() map[string]string { @@ -70,8 +70,8 @@ func (Ingress) SwaggerDoc() map[string]string { var map_IngressBackend = map[string]string{ "": "IngressBackend describes all endpoints for a given service and port.", - "service": "Service references a Service as a Backend. This is a mutually exclusive setting with \"Resource\".", - "resource": "Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with \"Service\".", + "service": "service references a service as a backend. This is a mutually exclusive setting with \"Resource\".", + "resource": "resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with \"Service\".", } func (IngressBackend) SwaggerDoc() map[string]string { @@ -81,7 +81,7 @@ func (IngressBackend) SwaggerDoc() map[string]string { var map_IngressClass = map[string]string{ "": "IngressClass represents the class of the Ingress, referenced by the Ingress Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (IngressClass) SwaggerDoc() map[string]string { @@ -91,7 +91,7 @@ func (IngressClass) SwaggerDoc() map[string]string { var map_IngressClassList = map[string]string{ "": "IngressClassList is a collection of IngressClasses.", "metadata": "Standard list metadata.", - "items": "Items is the list of IngressClasses.", + "items": "items is the list of IngressClasses.", } func (IngressClassList) SwaggerDoc() map[string]string { @@ -100,11 +100,11 @@ func (IngressClassList) SwaggerDoc() map[string]string { var map_IngressClassParametersReference = map[string]string{ "": "IngressClassParametersReference identifies an API object. This can be used to specify a cluster or namespace-scoped resource.", - "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", - "kind": "Kind is the type of resource being referenced.", - "name": "Name is the name of resource being referenced.", - "scope": "Scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", - "namespace": "Namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", + "apiGroup": "apiGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "kind": "kind is the type of resource being referenced.", + "name": "name is the name of resource being referenced.", + "scope": "scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", + "namespace": "namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", } func (IngressClassParametersReference) SwaggerDoc() map[string]string { @@ -113,8 +113,8 @@ func (IngressClassParametersReference) SwaggerDoc() map[string]string { var map_IngressClassSpec = map[string]string{ "": "IngressClassSpec provides information about the class of an Ingress.", - "controller": "Controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", - "parameters": "Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", + "controller": "controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", + "parameters": "parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", } func (IngressClassSpec) SwaggerDoc() map[string]string { @@ -124,16 +124,47 @@ func (IngressClassSpec) SwaggerDoc() map[string]string { var map_IngressList = map[string]string{ "": "IngressList is a collection of Ingress.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of Ingress.", + "items": "items is the list of Ingress.", } func (IngressList) SwaggerDoc() map[string]string { return map_IngressList } +var map_IngressLoadBalancerIngress = map[string]string{ + "": "IngressLoadBalancerIngress represents the status of a load-balancer ingress point.", + "ip": "ip is set for load-balancer ingress points that are IP based.", + "hostname": "hostname is set for load-balancer ingress points that are DNS based.", + "ports": "ports provides information about the ports exposed by this LoadBalancer.", +} + +func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerIngress +} + +var map_IngressLoadBalancerStatus = map[string]string{ + "": "IngressLoadBalancerStatus represents the status of a load-balancer.", + "ingress": "ingress is a list containing ingress points for the load-balancer.", +} + +func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerStatus +} + +var map_IngressPortStatus = map[string]string{ + "": "IngressPortStatus represents the error condition of a service port", + "port": "port is the port number of the ingress port.", + "protocol": "protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", + "error": "error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", +} + +func (IngressPortStatus) SwaggerDoc() map[string]string { + return map_IngressPortStatus +} + var map_IngressRule = map[string]string{ "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", - "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nHost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", + "host": "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nhost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If host is precise, the request matches this rule if the http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", } func (IngressRule) SwaggerDoc() map[string]string { @@ -150,8 +181,8 @@ func (IngressRuleValue) SwaggerDoc() map[string]string { var map_IngressServiceBackend = map[string]string{ "": "IngressServiceBackend references a Kubernetes Service as a Backend.", - "name": "Name is the referenced service. The service must exist in the same namespace as the Ingress object.", - "port": "Port of the referenced service. A port name or port number is required for a IngressServiceBackend.", + "name": "name is the referenced service. The service must exist in the same namespace as the Ingress object.", + "port": "port of the referenced service. A port name or port number is required for a IngressServiceBackend.", } func (IngressServiceBackend) SwaggerDoc() map[string]string { @@ -160,10 +191,10 @@ func (IngressServiceBackend) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "": "IngressSpec describes the Ingress the user wishes to exist.", - "ingressClassName": "IngressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated `kubernetes.io/ingress.class` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.", - "defaultBackend": "DefaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.", - "tls": "TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", - "rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", + "ingressClassName": "ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` annotation (simple constant name) was never formally defined, it was widely supported by Ingress controllers to create a direct binding between Ingress controller and Ingress resources. Newly created Ingress resources should prefer using the field. However, even though the annotation is officially deprecated, for backwards compatibility reasons, ingress controllers should still honor that annotation if present.", + "defaultBackend": "defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.", + "tls": "tls represents the TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", + "rules": "rules is a list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", } func (IngressSpec) SwaggerDoc() map[string]string { @@ -172,7 +203,7 @@ func (IngressSpec) SwaggerDoc() map[string]string { var map_IngressStatus = map[string]string{ "": "IngressStatus describe the current state of the Ingress.", - "loadBalancer": "LoadBalancer contains the current status of the load-balancer.", + "loadBalancer": "loadBalancer contains the current status of the load-balancer.", } func (IngressStatus) SwaggerDoc() map[string]string { @@ -180,9 +211,9 @@ func (IngressStatus) SwaggerDoc() map[string]string { } var map_IngressTLS = map[string]string{ - "": "IngressTLS describes the transport layer security associated with an Ingress.", - "hosts": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", - "secretName": "SecretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", + "": "IngressTLS describes the transport layer security associated with an ingress.", + "hosts": "hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", + "secretName": "secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the \"Host\" header is used for routing.", } func (IngressTLS) SwaggerDoc() map[string]string { @@ -192,8 +223,8 @@ func (IngressTLS) SwaggerDoc() map[string]string { var map_NetworkPolicy = map[string]string{ "": "NetworkPolicy describes what network traffic is allowed for a set of Pods", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired behavior for this NetworkPolicy.", - "status": "Status is the current state of the NetworkPolicy. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec represents the specification of the desired behavior for this NetworkPolicy.", + "status": "status represents the current state of the NetworkPolicy. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (NetworkPolicy) SwaggerDoc() map[string]string { @@ -202,8 +233,8 @@ func (NetworkPolicy) SwaggerDoc() map[string]string { var map_NetworkPolicyEgressRule = map[string]string{ "": "NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8", - "ports": "List of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", - "to": "List of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.", + "ports": "ports is a list of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + "to": "to is a list of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.", } func (NetworkPolicyEgressRule) SwaggerDoc() map[string]string { @@ -212,8 +243,8 @@ func (NetworkPolicyEgressRule) SwaggerDoc() map[string]string { var map_NetworkPolicyIngressRule = map[string]string{ "": "NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from.", - "ports": "List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", - "from": "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.", + "ports": "ports is a list of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + "from": "from is a list of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.", } func (NetworkPolicyIngressRule) SwaggerDoc() map[string]string { @@ -223,7 +254,7 @@ func (NetworkPolicyIngressRule) SwaggerDoc() map[string]string { var map_NetworkPolicyList = map[string]string{ "": "NetworkPolicyList is a list of NetworkPolicy objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (NetworkPolicyList) SwaggerDoc() map[string]string { @@ -232,9 +263,9 @@ func (NetworkPolicyList) SwaggerDoc() map[string]string { var map_NetworkPolicyPeer = map[string]string{ "": "NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of fields are allowed", - "podSelector": "This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.", - "namespaceSelector": "Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.", - "ipBlock": "IPBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be.", + "podSelector": "podSelector is a label selector which selects pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the pods matching podSelector in the policy's own namespace.", + "namespaceSelector": "namespaceSelector selects namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf podSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the namespaces selected by namespaceSelector. Otherwise it selects all pods in the namespaces selected by namespaceSelector.", + "ipBlock": "ipBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be.", } func (NetworkPolicyPeer) SwaggerDoc() map[string]string { @@ -243,9 +274,9 @@ func (NetworkPolicyPeer) SwaggerDoc() map[string]string { var map_NetworkPolicyPort = map[string]string{ "": "NetworkPolicyPort describes a port to allow traffic on", - "protocol": "The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", - "port": "The port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", - "endPort": "If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. This feature is in Beta state and is enabled by default. It can be disabled using the Feature Gate \"NetworkPolicyEndPort\".", + "protocol": "protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", + "port": "port represents the port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", + "endPort": "endPort indicates that the range of ports from port to endPort if set, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port.", } func (NetworkPolicyPort) SwaggerDoc() map[string]string { @@ -254,10 +285,10 @@ func (NetworkPolicyPort) SwaggerDoc() map[string]string { var map_NetworkPolicySpec = map[string]string{ "": "NetworkPolicySpec provides the specification of a NetworkPolicy", - "podSelector": "Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.", - "ingress": "List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", - "egress": "List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", - "policyTypes": "List of rule types that the NetworkPolicy relates to. Valid options are [\"Ingress\"], [\"Egress\"], or [\"Ingress\", \"Egress\"]. If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an Egress section and would otherwise default to just [ \"Ingress\" ]). This field is beta-level in 1.8", + "podSelector": "podSelector selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.", + "ingress": "ingress is a list of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", + "egress": "egress is a list of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", + "policyTypes": "policyTypes is a list of rule types that the NetworkPolicy relates to. Valid options are [\"Ingress\"], [\"Egress\"], or [\"Ingress\", \"Egress\"]. If this field is not specified, it will default based on the existence of ingress or egress rules; policies that contain an egress section are assumed to affect egress, and all policies (whether or not they contain an ingress section) are assumed to affect ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an egress section and would otherwise default to just [ \"Ingress\" ]). This field is beta-level in 1.8", } func (NetworkPolicySpec) SwaggerDoc() map[string]string { @@ -265,8 +296,8 @@ func (NetworkPolicySpec) SwaggerDoc() map[string]string { } var map_NetworkPolicyStatus = map[string]string{ - "": "NetworkPolicyStatus describe the current state of the NetworkPolicy.", - "conditions": "Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. Current service state", + "": "NetworkPolicyStatus describes the current state of the NetworkPolicy.", + "conditions": "conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. Current service state", } func (NetworkPolicyStatus) SwaggerDoc() map[string]string { @@ -275,8 +306,8 @@ func (NetworkPolicyStatus) SwaggerDoc() map[string]string { var map_ServiceBackendPort = map[string]string{ "": "ServiceBackendPort is the service port being referenced.", - "name": "Name is the name of the port on the Service. This is a mutually exclusive setting with \"Number\".", - "number": "Number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with \"Name\".", + "name": "name is the name of the port on the Service. This is a mutually exclusive setting with \"Number\".", + "number": "number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with \"Name\".", } func (ServiceBackendPort) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go index 349c40ca7e6..c95653c918c 100644 --- a/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go @@ -293,6 +293,73 @@ func (in *IngressList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerIngress) DeepCopyInto(out *IngressLoadBalancerIngress) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]IngressPortStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerIngress. +func (in *IngressLoadBalancerIngress) DeepCopy() *IngressLoadBalancerIngress { + if in == nil { + return nil + } + out := new(IngressLoadBalancerIngress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerStatus) DeepCopyInto(out *IngressLoadBalancerStatus) { + *out = *in + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = make([]IngressLoadBalancerIngress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerStatus. +func (in *IngressLoadBalancerStatus) DeepCopy() *IngressLoadBalancerStatus { + if in == nil { + return nil + } + out := new(IngressLoadBalancerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressPortStatus) DeepCopyInto(out *IngressPortStatus) { + *out = *in + if in.Error != nil { + in, out := &in.Error, &out.Error + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressPortStatus. +func (in *IngressPortStatus) DeepCopy() *IngressPortStatus { + if in == nil { + return nil + } + out := new(IngressPortStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = *in diff --git a/vendor/k8s.io/api/networking/v1alpha1/doc.go b/vendor/k8s.io/api/networking/v1alpha1/doc.go new file mode 100644 index 00000000000..3827b0418f9 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true +// +groupName=networking.k8s.io + +package v1alpha1 // import "k8s.io/api/networking/v1alpha1" diff --git a/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go b/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go new file mode 100644 index 00000000000..f54d1f82421 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go @@ -0,0 +1,1858 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/networking/v1alpha1/generated.proto + +package v1alpha1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + v11 "k8s.io/api/core/v1" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" + + k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *ClusterCIDR) Reset() { *m = ClusterCIDR{} } +func (*ClusterCIDR) ProtoMessage() {} +func (*ClusterCIDR) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{0} +} +func (m *ClusterCIDR) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterCIDR) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterCIDR) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterCIDR.Merge(m, src) +} +func (m *ClusterCIDR) XXX_Size() int { + return m.Size() +} +func (m *ClusterCIDR) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterCIDR.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterCIDR proto.InternalMessageInfo + +func (m *ClusterCIDRList) Reset() { *m = ClusterCIDRList{} } +func (*ClusterCIDRList) ProtoMessage() {} +func (*ClusterCIDRList) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{1} +} +func (m *ClusterCIDRList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterCIDRList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterCIDRList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterCIDRList.Merge(m, src) +} +func (m *ClusterCIDRList) XXX_Size() int { + return m.Size() +} +func (m *ClusterCIDRList) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterCIDRList.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterCIDRList proto.InternalMessageInfo + +func (m *ClusterCIDRSpec) Reset() { *m = ClusterCIDRSpec{} } +func (*ClusterCIDRSpec) ProtoMessage() {} +func (*ClusterCIDRSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{2} +} +func (m *ClusterCIDRSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterCIDRSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterCIDRSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterCIDRSpec.Merge(m, src) +} +func (m *ClusterCIDRSpec) XXX_Size() int { + return m.Size() +} +func (m *ClusterCIDRSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterCIDRSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterCIDRSpec proto.InternalMessageInfo + +func (m *IPAddress) Reset() { *m = IPAddress{} } +func (*IPAddress) ProtoMessage() {} +func (*IPAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{3} +} +func (m *IPAddress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddress.Merge(m, src) +} +func (m *IPAddress) XXX_Size() int { + return m.Size() +} +func (m *IPAddress) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddress proto.InternalMessageInfo + +func (m *IPAddressList) Reset() { *m = IPAddressList{} } +func (*IPAddressList) ProtoMessage() {} +func (*IPAddressList) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{4} +} +func (m *IPAddressList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddressList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddressList) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddressList.Merge(m, src) +} +func (m *IPAddressList) XXX_Size() int { + return m.Size() +} +func (m *IPAddressList) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddressList.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddressList proto.InternalMessageInfo + +func (m *IPAddressSpec) Reset() { *m = IPAddressSpec{} } +func (*IPAddressSpec) ProtoMessage() {} +func (*IPAddressSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{5} +} +func (m *IPAddressSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddressSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddressSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddressSpec.Merge(m, src) +} +func (m *IPAddressSpec) XXX_Size() int { + return m.Size() +} +func (m *IPAddressSpec) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddressSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddressSpec proto.InternalMessageInfo + +func (m *ParentReference) Reset() { *m = ParentReference{} } +func (*ParentReference) ProtoMessage() {} +func (*ParentReference) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{6} +} +func (m *ParentReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ParentReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ParentReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParentReference.Merge(m, src) +} +func (m *ParentReference) XXX_Size() int { + return m.Size() +} +func (m *ParentReference) XXX_DiscardUnknown() { + xxx_messageInfo_ParentReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ParentReference proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ClusterCIDR)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDR") + proto.RegisterType((*ClusterCIDRList)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDRList") + proto.RegisterType((*ClusterCIDRSpec)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDRSpec") + proto.RegisterType((*IPAddress)(nil), "k8s.io.api.networking.v1alpha1.IPAddress") + proto.RegisterType((*IPAddressList)(nil), "k8s.io.api.networking.v1alpha1.IPAddressList") + proto.RegisterType((*IPAddressSpec)(nil), "k8s.io.api.networking.v1alpha1.IPAddressSpec") + proto.RegisterType((*ParentReference)(nil), "k8s.io.api.networking.v1alpha1.ParentReference") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/networking/v1alpha1/generated.proto", fileDescriptor_c1b7ac8d7d97acec) +} + +var fileDescriptor_c1b7ac8d7d97acec = []byte{ + // 698 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcf, 0x4e, 0xdb, 0x4a, + 0x14, 0xc6, 0x63, 0x92, 0x48, 0x78, 0x00, 0x85, 0xeb, 0xcd, 0x8d, 0x58, 0x38, 0xb9, 0xb9, 0x1b, + 0xae, 0x6e, 0x19, 0x03, 0x42, 0x51, 0xb7, 0x98, 0x48, 0x34, 0x52, 0x0b, 0xe9, 0x20, 0xba, 0xa8, + 0x58, 0xd4, 0xb1, 0x0f, 0x8e, 0x1b, 0xfc, 0x47, 0x33, 0xe3, 0x54, 0xec, 0xfa, 0x08, 0x7d, 0xa1, + 0x56, 0x6a, 0x57, 0x2c, 0x59, 0xb2, 0x8a, 0x8a, 0xfb, 0x02, 0x5d, 0xb7, 0x9b, 0x6a, 0x26, 0x4e, + 0xec, 0x24, 0x0d, 0xd0, 0x0d, 0xbb, 0xcc, 0x39, 0xbf, 0xf3, 0xcd, 0x39, 0x73, 0xbe, 0x24, 0xe8, + 0xb0, 0xff, 0x94, 0x61, 0x2f, 0x34, 0xfa, 0x71, 0x17, 0x68, 0x00, 0x1c, 0x98, 0x31, 0x80, 0xc0, + 0x09, 0xa9, 0x91, 0x26, 0xac, 0xc8, 0x33, 0x02, 0xe0, 0xef, 0x42, 0xda, 0xf7, 0x02, 0xd7, 0x18, + 0xec, 0x58, 0x17, 0x51, 0xcf, 0xda, 0x31, 0x5c, 0x08, 0x80, 0x5a, 0x1c, 0x1c, 0x1c, 0xd1, 0x90, + 0x87, 0x9a, 0x3e, 0xe2, 0xb1, 0x15, 0x79, 0x38, 0xe3, 0xf1, 0x98, 0xdf, 0xd8, 0x72, 0x3d, 0xde, + 0x8b, 0xbb, 0xd8, 0x0e, 0x7d, 0xc3, 0x0d, 0xdd, 0xd0, 0x90, 0x65, 0xdd, 0xf8, 0x5c, 0x9e, 0xe4, + 0x41, 0x7e, 0x1a, 0xc9, 0x6d, 0x34, 0x72, 0xd7, 0xdb, 0x21, 0x05, 0x63, 0x30, 0x77, 0xe5, 0xc6, + 0x5e, 0xc6, 0xf8, 0x96, 0xdd, 0xf3, 0x02, 0xa0, 0x97, 0x46, 0xd4, 0x77, 0x45, 0x80, 0x19, 0x3e, + 0x70, 0xeb, 0x77, 0x55, 0xc6, 0xa2, 0x2a, 0x1a, 0x07, 0xdc, 0xf3, 0x61, 0xae, 0xa0, 0x79, 0x5f, + 0x01, 0xb3, 0x7b, 0xe0, 0x5b, 0xb3, 0x75, 0x8d, 0x2f, 0x0a, 0x5a, 0x39, 0xb8, 0x88, 0x19, 0x07, + 0x7a, 0xd0, 0x6e, 0x11, 0xed, 0x0d, 0x5a, 0x16, 0x3d, 0x39, 0x16, 0xb7, 0xaa, 0x4a, 0x5d, 0xd9, + 0x5c, 0xd9, 0xdd, 0xc6, 0xd9, 0xa3, 0x4d, 0xa4, 0x71, 0xd4, 0x77, 0x45, 0x80, 0x61, 0x41, 0xe3, + 0xc1, 0x0e, 0x3e, 0xee, 0xbe, 0x05, 0x9b, 0xbf, 0x00, 0x6e, 0x99, 0xda, 0xd5, 0xb0, 0x56, 0x48, + 0x86, 0x35, 0x94, 0xc5, 0xc8, 0x44, 0x55, 0x7b, 0x89, 0x4a, 0x2c, 0x02, 0xbb, 0xba, 0x24, 0xd5, + 0x0d, 0x7c, 0xf7, 0x4a, 0x70, 0xae, 0xb9, 0x93, 0x08, 0x6c, 0x73, 0x35, 0x15, 0x2f, 0x89, 0x13, + 0x91, 0x52, 0x8d, 0xcf, 0x0a, 0xaa, 0xe4, 0xb8, 0xe7, 0x1e, 0xe3, 0xda, 0xd9, 0xdc, 0x20, 0xf8, + 0x61, 0x83, 0x88, 0x6a, 0x39, 0xc6, 0x7a, 0x7a, 0xd3, 0xf2, 0x38, 0x92, 0x1b, 0xa2, 0x83, 0xca, + 0x1e, 0x07, 0x9f, 0x55, 0x97, 0xea, 0xc5, 0xcd, 0x95, 0xdd, 0xff, 0xff, 0x60, 0x0a, 0x73, 0x2d, + 0xd5, 0x2d, 0xb7, 0x85, 0x02, 0x19, 0x09, 0x35, 0xbe, 0x4f, 0xcf, 0x20, 0xa6, 0xd3, 0x5e, 0xa1, + 0xd5, 0x20, 0x74, 0xe0, 0x04, 0x2e, 0xc0, 0xe6, 0x21, 0x4d, 0xe7, 0xa8, 0xe7, 0x2f, 0x13, 0xb6, + 0x13, 0x5d, 0x1f, 0xe5, 0x38, 0x73, 0x3d, 0x19, 0xd6, 0x56, 0xf3, 0x11, 0x32, 0xa5, 0xa3, 0xed, + 0xa3, 0x4a, 0x04, 0x54, 0x00, 0xcf, 0x42, 0xc6, 0x4d, 0x8f, 0x33, 0xb9, 0x8d, 0xb2, 0xf9, 0x77, + 0xda, 0x5a, 0xa5, 0x33, 0x9d, 0x26, 0xb3, 0xbc, 0x56, 0x47, 0x25, 0x2f, 0x1a, 0xec, 0x55, 0x8b, + 0x75, 0x65, 0x53, 0xcd, 0x96, 0xd2, 0xee, 0x0c, 0xf6, 0x88, 0xcc, 0xa4, 0x44, 0xb3, 0x5a, 0x9a, + 0x23, 0x9a, 0x92, 0x68, 0x36, 0x3e, 0x29, 0x48, 0x6d, 0x77, 0xf6, 0x1d, 0x87, 0x02, 0x63, 0x8f, + 0xe0, 0xbc, 0xe3, 0x29, 0xe7, 0x6d, 0xdd, 0xb7, 0xb3, 0x49, 0x6b, 0x0b, 0x7d, 0xf7, 0x51, 0x41, + 0x6b, 0x13, 0xea, 0x11, 0x5c, 0x77, 0x34, 0xed, 0xba, 0xff, 0x1e, 0x3c, 0xc1, 0x02, 0xcf, 0xf9, + 0xb9, 0xf6, 0xa5, 0xe1, 0xce, 0x90, 0x1a, 0x59, 0x14, 0x02, 0x4e, 0xe0, 0x3c, 0xed, 0xff, 0xde, + 0x2f, 0x68, 0x67, 0x5c, 0x00, 0x14, 0x02, 0x1b, 0xcc, 0xb5, 0x64, 0x58, 0x53, 0x27, 0x41, 0x92, + 0x09, 0x36, 0x7e, 0x2a, 0xa8, 0x32, 0x43, 0x6b, 0xff, 0xa2, 0xb2, 0x4b, 0xc3, 0x38, 0x92, 0xb7, + 0xa9, 0x59, 0x9f, 0x87, 0x22, 0x48, 0x46, 0x39, 0xed, 0x09, 0x5a, 0xa6, 0xc0, 0xc2, 0x98, 0xda, + 0x20, 0x97, 0xa7, 0x66, 0xaf, 0x44, 0xd2, 0x38, 0x99, 0x10, 0x9a, 0x81, 0xd4, 0xc0, 0xf2, 0x81, + 0x45, 0x96, 0x0d, 0xa9, 0x3f, 0xff, 0x4a, 0x71, 0xf5, 0x68, 0x9c, 0x20, 0x19, 0x23, 0x9c, 0x2a, + 0x0e, 0xb3, 0x4e, 0x15, 0x2c, 0x91, 0x19, 0xcd, 0x44, 0xc5, 0xd8, 0x73, 0xaa, 0x65, 0x09, 0x6c, + 0xa7, 0x40, 0xf1, 0xb4, 0xdd, 0xfa, 0x31, 0xac, 0xfd, 0xb3, 0xe8, 0x97, 0x97, 0x5f, 0x46, 0xc0, + 0xf0, 0x69, 0xbb, 0x45, 0x44, 0xb1, 0xd9, 0xba, 0xba, 0xd5, 0x0b, 0xd7, 0xb7, 0x7a, 0xe1, 0xe6, + 0x56, 0x2f, 0xbc, 0x4f, 0x74, 0xe5, 0x2a, 0xd1, 0x95, 0xeb, 0x44, 0x57, 0x6e, 0x12, 0x5d, 0xf9, + 0x9a, 0xe8, 0xca, 0x87, 0x6f, 0x7a, 0xe1, 0xb5, 0x7e, 0xf7, 0x3f, 0xda, 0xaf, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf9, 0x9d, 0x9e, 0xc6, 0x0b, 0x07, 0x00, 0x00, +} + +func (m *ClusterCIDR) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterCIDR) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterCIDR) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterCIDRList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterCIDRList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterCIDRList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterCIDRSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterCIDRSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterCIDRSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.IPv6) + copy(dAtA[i:], m.IPv6) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IPv6))) + i-- + dAtA[i] = 0x22 + i -= len(m.IPv4) + copy(dAtA[i:], m.IPv4) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IPv4))) + i-- + dAtA[i] = 0x1a + i = encodeVarintGenerated(dAtA, i, uint64(m.PerNodeHostBits)) + i-- + dAtA[i] = 0x10 + if m.NodeSelector != nil { + { + size, err := m.NodeSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *IPAddress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IPAddress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IPAddressList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IPAddressList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IPAddressSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IPAddressSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddressSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ParentRef != nil { + { + size, err := m.ParentRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ParentReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ParentReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ParentReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.UID) + copy(dAtA[i:], m.UID) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i-- + dAtA[i] = 0x2a + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x1a + i -= len(m.Resource) + copy(dAtA[i:], m.Resource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + i-- + dAtA[i] = 0x12 + i -= len(m.Group) + copy(dAtA[i:], m.Group) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ClusterCIDR) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ClusterCIDRList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ClusterCIDRSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NodeSelector != nil { + l = m.NodeSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 1 + sovGenerated(uint64(m.PerNodeHostBits)) + l = len(m.IPv4) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.IPv6) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *IPAddress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *IPAddressList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IPAddressSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ParentRef != nil { + l = m.ParentRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *ParentReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Group) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Resource) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *ClusterCIDR) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterCIDR{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ClusterCIDRSpec", "ClusterCIDRSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ClusterCIDRList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ClusterCIDR{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ClusterCIDR", "ClusterCIDR", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ClusterCIDRList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ClusterCIDRSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterCIDRSpec{`, + `NodeSelector:` + strings.Replace(fmt.Sprintf("%v", this.NodeSelector), "NodeSelector", "v11.NodeSelector", 1) + `,`, + `PerNodeHostBits:` + fmt.Sprintf("%v", this.PerNodeHostBits) + `,`, + `IPv4:` + fmt.Sprintf("%v", this.IPv4) + `,`, + `IPv6:` + fmt.Sprintf("%v", this.IPv6) + `,`, + `}`, + }, "") + return s +} +func (this *IPAddress) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IPAddress{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "IPAddressSpec", "IPAddressSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *IPAddressList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]IPAddress{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "IPAddress", "IPAddress", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&IPAddressList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *IPAddressSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IPAddressSpec{`, + `ParentRef:` + strings.Replace(this.ParentRef.String(), "ParentReference", "ParentReference", 1) + `,`, + `}`, + }, "") + return s +} +func (this *ParentReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParentReference{`, + `Group:` + fmt.Sprintf("%v", this.Group) + `,`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *ClusterCIDR) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterCIDR: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterCIDR: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterCIDRList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterCIDRList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterCIDRList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ClusterCIDR{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterCIDRSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterCIDRSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterCIDRSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeSelector == nil { + m.NodeSelector = &v11.NodeSelector{} + } + if err := m.NodeSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PerNodeHostBits", wireType) + } + m.PerNodeHostBits = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PerNodeHostBits |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IPv4", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IPv4 = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IPv6", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IPv6 = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IPAddress) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IPAddress: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IPAddress: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IPAddressList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IPAddressList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IPAddressList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, IPAddress{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IPAddressSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IPAddressSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IPAddressSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParentRef == nil { + m.ParentRef = &ParentReference{} + } + if err := m.ParentRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ParentReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ParentReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ParentReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Group = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/networking/v1alpha1/generated.proto b/vendor/k8s.io/api/networking/v1alpha1/generated.proto new file mode 100644 index 00000000000..0f1f30d7011 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/generated.proto @@ -0,0 +1,155 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.networking.v1alpha1; + +import "k8s.io/api/core/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/networking/v1alpha1"; + +// ClusterCIDR represents a single configuration for per-Node Pod CIDR +// allocations when the MultiCIDRRangeAllocator is enabled (see the config for +// kube-controller-manager). A cluster may have any number of ClusterCIDR +// resources, all of which will be considered when allocating a CIDR for a +// Node. A ClusterCIDR is eligible to be used for a given Node when the node +// selector matches the node in question and has free CIDRs to allocate. In +// case of multiple matching ClusterCIDR resources, the allocator will attempt +// to break ties using internal heuristics, but any ClusterCIDR whose node +// selector matches the Node may be used. +message ClusterCIDR { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec is the desired state of the ClusterCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional ClusterCIDRSpec spec = 2; +} + +// ClusterCIDRList contains a list of ClusterCIDR. +message ClusterCIDRList { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is the list of ClusterCIDRs. + repeated ClusterCIDR items = 2; +} + +// ClusterCIDRSpec defines the desired state of ClusterCIDR. +message ClusterCIDRSpec { + // nodeSelector defines which nodes the config is applicable to. + // An empty or nil nodeSelector selects all nodes. + // This field is immutable. + // +optional + optional k8s.io.api.core.v1.NodeSelector nodeSelector = 1; + + // perNodeHostBits defines the number of host bits to be configured per node. + // A subnet mask determines how much of the address is used for network bits + // and host bits. For example an IPv4 address of 192.168.0.0/24, splits the + // address into 24 bits for the network portion and 8 bits for the host portion. + // To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6). + // Minimum value is 4 (16 IPs). + // This field is immutable. + // +required + optional int32 perNodeHostBits = 2; + + // ipv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). + // At least one of ipv4 and ipv6 must be specified. + // This field is immutable. + // +optional + optional string ipv4 = 3; + + // ipv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). + // At least one of ipv4 and ipv6 must be specified. + // This field is immutable. + // +optional + optional string ipv6 = 4; +} + +// IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs +// that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. +// An IP address can be represented in different formats, to guarantee the uniqueness of the IP, +// the name of the object is the IP address in canonical format, four decimal digits separated +// by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. +// Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 +// Invalid: 10.01.2.3 or 2001:db8:0:0:0::1 +message IPAddress { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec is the desired state of the IPAddress. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional IPAddressSpec spec = 2; +} + +// IPAddressList contains a list of IPAddress. +message IPAddressList { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is the list of IPAddresses. + repeated IPAddress items = 2; +} + +// IPAddressSpec describe the attributes in an IP Address. +message IPAddressSpec { + // ParentRef references the resource that an IPAddress is attached to. + // An IPAddress must reference a parent object. + // +required + optional ParentReference parentRef = 1; +} + +// ParentReference describes a reference to a parent object. +message ParentReference { + // Group is the group of the object being referenced. + // +optional + optional string group = 1; + + // Resource is the resource of the object being referenced. + // +required + optional string resource = 2; + + // Namespace is the namespace of the object being referenced. + // +optional + optional string namespace = 3; + + // Name is the name of the object being referenced. + // +required + optional string name = 4; + + // UID is the uid of the object being referenced. + // +optional + optional string uid = 5; +} + diff --git a/vendor/k8s.io/api/networking/v1alpha1/register.go b/vendor/k8s.io/api/networking/v1alpha1/register.go new file mode 100644 index 00000000000..8dda6394d47 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/register.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name used in this package. +const GroupName = "networking.k8s.io" + +// SchemeGroupVersion is group version used to register objects in this package. +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind. +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder holds functions that add things to a scheme. + // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + localSchemeBuilder = &SchemeBuilder + + // AddToScheme adds the types of this group into the given scheme. + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ClusterCIDR{}, + &ClusterCIDRList{}, + &IPAddress{}, + &IPAddressList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/networking/v1alpha1/types.go b/vendor/k8s.io/api/networking/v1alpha1/types.go new file mode 100644 index 00000000000..52e4a11e8b1 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/types.go @@ -0,0 +1,163 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.25 + +// ClusterCIDR represents a single configuration for per-Node Pod CIDR +// allocations when the MultiCIDRRangeAllocator is enabled (see the config for +// kube-controller-manager). A cluster may have any number of ClusterCIDR +// resources, all of which will be considered when allocating a CIDR for a +// Node. A ClusterCIDR is eligible to be used for a given Node when the node +// selector matches the node in question and has free CIDRs to allocate. In +// case of multiple matching ClusterCIDR resources, the allocator will attempt +// to break ties using internal heuristics, but any ClusterCIDR whose node +// selector matches the Node may be used. +type ClusterCIDR struct { + metav1.TypeMeta `json:",inline"` + + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // spec is the desired state of the ClusterCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec ClusterCIDRSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// ClusterCIDRSpec defines the desired state of ClusterCIDR. +type ClusterCIDRSpec struct { + // nodeSelector defines which nodes the config is applicable to. + // An empty or nil nodeSelector selects all nodes. + // This field is immutable. + // +optional + NodeSelector *v1.NodeSelector `json:"nodeSelector,omitempty" protobuf:"bytes,1,opt,name=nodeSelector"` + + // perNodeHostBits defines the number of host bits to be configured per node. + // A subnet mask determines how much of the address is used for network bits + // and host bits. For example an IPv4 address of 192.168.0.0/24, splits the + // address into 24 bits for the network portion and 8 bits for the host portion. + // To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6). + // Minimum value is 4 (16 IPs). + // This field is immutable. + // +required + PerNodeHostBits int32 `json:"perNodeHostBits" protobuf:"varint,2,opt,name=perNodeHostBits"` + + // ipv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). + // At least one of ipv4 and ipv6 must be specified. + // This field is immutable. + // +optional + IPv4 string `json:"ipv4" protobuf:"bytes,3,opt,name=ipv4"` + + // ipv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). + // At least one of ipv4 and ipv6 must be specified. + // This field is immutable. + // +optional + IPv6 string `json:"ipv6" protobuf:"bytes,4,opt,name=ipv6"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.25 + +// ClusterCIDRList contains a list of ClusterCIDR. +type ClusterCIDRList struct { + metav1.TypeMeta `json:",inline"` + + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // items is the list of ClusterCIDRs. + Items []ClusterCIDR `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.27 + +// IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs +// that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. +// An IP address can be represented in different formats, to guarantee the uniqueness of the IP, +// the name of the object is the IP address in canonical format, four decimal digits separated +// by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. +// Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 +// Invalid: 10.01.2.3 or 2001:db8:0:0:0::1 +type IPAddress struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // spec is the desired state of the IPAddress. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec IPAddressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// IPAddressSpec describe the attributes in an IP Address. +type IPAddressSpec struct { + // ParentRef references the resource that an IPAddress is attached to. + // An IPAddress must reference a parent object. + // +required + ParentRef *ParentReference `json:"parentRef,omitempty" protobuf:"bytes,1,opt,name=parentRef"` +} + +// ParentReference describes a reference to a parent object. +type ParentReference struct { + // Group is the group of the object being referenced. + // +optional + Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` + // Resource is the resource of the object being referenced. + // +required + Resource string `json:"resource,omitempty" protobuf:"bytes,2,opt,name=resource"` + // Namespace is the namespace of the object being referenced. + // +optional + Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` + // Name is the name of the object being referenced. + // +required + Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` + // UID is the uid of the object being referenced. + // +optional + UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.27 + +// IPAddressList contains a list of IPAddress. +type IPAddressList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // items is the list of IPAddresses. + Items []IPAddress `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 00000000000..85304784f4e --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,104 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_ClusterCIDR = map[string]string{ + "": "ClusterCIDR represents a single configuration for per-Node Pod CIDR allocations when the MultiCIDRRangeAllocator is enabled (see the config for kube-controller-manager). A cluster may have any number of ClusterCIDR resources, all of which will be considered when allocating a CIDR for a Node. A ClusterCIDR is eligible to be used for a given Node when the node selector matches the node in question and has free CIDRs to allocate. In case of multiple matching ClusterCIDR resources, the allocator will attempt to break ties using internal heuristics, but any ClusterCIDR whose node selector matches the Node may be used.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec is the desired state of the ClusterCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (ClusterCIDR) SwaggerDoc() map[string]string { + return map_ClusterCIDR +} + +var map_ClusterCIDRList = map[string]string{ + "": "ClusterCIDRList contains a list of ClusterCIDR.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "items is the list of ClusterCIDRs.", +} + +func (ClusterCIDRList) SwaggerDoc() map[string]string { + return map_ClusterCIDRList +} + +var map_ClusterCIDRSpec = map[string]string{ + "": "ClusterCIDRSpec defines the desired state of ClusterCIDR.", + "nodeSelector": "nodeSelector defines which nodes the config is applicable to. An empty or nil nodeSelector selects all nodes. This field is immutable.", + "perNodeHostBits": "perNodeHostBits defines the number of host bits to be configured per node. A subnet mask determines how much of the address is used for network bits and host bits. For example an IPv4 address of 192.168.0.0/24, splits the address into 24 bits for the network portion and 8 bits for the host portion. To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6). Minimum value is 4 (16 IPs). This field is immutable.", + "ipv4": "ipv4 defines an IPv4 IP block in CIDR notation(e.g. \"10.0.0.0/8\"). At least one of ipv4 and ipv6 must be specified. This field is immutable.", + "ipv6": "ipv6 defines an IPv6 IP block in CIDR notation(e.g. \"2001:db8::/64\"). At least one of ipv4 and ipv6 must be specified. This field is immutable.", +} + +func (ClusterCIDRSpec) SwaggerDoc() map[string]string { + return map_ClusterCIDRSpec +} + +var map_IPAddress = map[string]string{ + "": "IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. An IP address can be represented in different formats, to guarantee the uniqueness of the IP, the name of the object is the IP address in canonical format, four decimal digits separated by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 Invalid: 10.01.2.3 or 2001:db8:0:0:0::1", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec is the desired state of the IPAddress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (IPAddress) SwaggerDoc() map[string]string { + return map_IPAddress +} + +var map_IPAddressList = map[string]string{ + "": "IPAddressList contains a list of IPAddress.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "items is the list of IPAddresses.", +} + +func (IPAddressList) SwaggerDoc() map[string]string { + return map_IPAddressList +} + +var map_IPAddressSpec = map[string]string{ + "": "IPAddressSpec describe the attributes in an IP Address.", + "parentRef": "ParentRef references the resource that an IPAddress is attached to. An IPAddress must reference a parent object.", +} + +func (IPAddressSpec) SwaggerDoc() map[string]string { + return map_IPAddressSpec +} + +var map_ParentReference = map[string]string{ + "": "ParentReference describes a reference to a parent object.", + "group": "Group is the group of the object being referenced.", + "resource": "Resource is the resource of the object being referenced.", + "namespace": "Namespace is the namespace of the object being referenced.", + "name": "Name is the name of the object being referenced.", + "uid": "UID is the uid of the object being referenced.", +} + +func (ParentReference) SwaggerDoc() map[string]string { + return map_ParentReference +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go b/vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go new file mode 100644 index 00000000000..5f9c23f708c --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +const ( + + // TODO: Use IPFamily as field with a field selector,And the value is set based on + // the name at create time and immutable. + // LabelIPAddressFamily is used to indicate the IP family of a Kubernetes IPAddress. + // This label simplify dual-stack client operations allowing to obtain the list of + // IP addresses filtered by family. + LabelIPAddressFamily = "ipaddress.kubernetes.io/ip-family" + // LabelManagedBy is used to indicate the controller or entity that manages + // an IPAddress. This label aims to enable different IPAddress + // objects to be managed by different controllers or entities within the + // same cluster. It is highly recommended to configure this label for all + // IPAddress objects. + LabelManagedBy = "ipaddress.kubernetes.io/managed-by" +) diff --git a/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..97db2eacc95 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,205 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCIDR) DeepCopyInto(out *ClusterCIDR) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDR. +func (in *ClusterCIDR) DeepCopy() *ClusterCIDR { + if in == nil { + return nil + } + out := new(ClusterCIDR) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCIDR) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCIDRList) DeepCopyInto(out *ClusterCIDRList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterCIDR, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDRList. +func (in *ClusterCIDRList) DeepCopy() *ClusterCIDRList { + if in == nil { + return nil + } + out := new(ClusterCIDRList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCIDRList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCIDRSpec) DeepCopyInto(out *ClusterCIDRSpec) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = new(v1.NodeSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCIDRSpec. +func (in *ClusterCIDRSpec) DeepCopy() *ClusterCIDRSpec { + if in == nil { + return nil + } + out := new(ClusterCIDRSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddress) DeepCopyInto(out *IPAddress) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddress. +func (in *IPAddress) DeepCopy() *IPAddress { + if in == nil { + return nil + } + out := new(IPAddress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IPAddress) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddressList) DeepCopyInto(out *IPAddressList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IPAddress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddressList. +func (in *IPAddressList) DeepCopy() *IPAddressList { + if in == nil { + return nil + } + out := new(IPAddressList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IPAddressList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddressSpec) DeepCopyInto(out *IPAddressSpec) { + *out = *in + if in.ParentRef != nil { + in, out := &in.ParentRef, &out.ParentRef + *out = new(ParentReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddressSpec. +func (in *IPAddressSpec) DeepCopy() *IPAddressSpec { + if in == nil { + return nil + } + out := new(IPAddressSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParentReference) DeepCopyInto(out *ParentReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference. +func (in *ParentReference) DeepCopy() *ParentReference { + if in == nil { + return nil + } + out := new(ParentReference) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go new file mode 100644 index 00000000000..60438ba59fc --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,94 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v1alpha1 + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterCIDR) APILifecycleIntroduced() (major, minor int) { + return 1, 25 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterCIDR) APILifecycleDeprecated() (major, minor int) { + return 1, 28 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterCIDR) APILifecycleRemoved() (major, minor int) { + return 1, 31 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterCIDRList) APILifecycleIntroduced() (major, minor int) { + return 1, 25 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterCIDRList) APILifecycleDeprecated() (major, minor int) { + return 1, 28 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterCIDRList) APILifecycleRemoved() (major, minor int) { + return 1, 31 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *IPAddress) APILifecycleIntroduced() (major, minor int) { + return 1, 27 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *IPAddress) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *IPAddress) APILifecycleRemoved() (major, minor int) { + return 1, 33 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *IPAddressList) APILifecycleIntroduced() (major, minor int) { + return 1, 27 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *IPAddressList) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *IPAddressList) APILifecycleRemoved() (major, minor int) { + return 1, 33 +} diff --git a/vendor/k8s.io/api/networking/v1beta1/generated.pb.go b/vendor/k8s.io/api/networking/v1beta1/generated.pb.go index 8eb092b4d01..6f298cd7811 100644 --- a/vendor/k8s.io/api/networking/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/networking/v1beta1/generated.pb.go @@ -25,6 +25,7 @@ import ( io "io" proto "github.com/gogo/protobuf/proto" + k8s_io_api_core_v1 "k8s.io/api/core/v1" v11 "k8s.io/api/core/v1" math "math" @@ -296,10 +297,94 @@ func (m *IngressList) XXX_DiscardUnknown() { var xxx_messageInfo_IngressList proto.InternalMessageInfo +func (m *IngressLoadBalancerIngress) Reset() { *m = IngressLoadBalancerIngress{} } +func (*IngressLoadBalancerIngress) ProtoMessage() {} +func (*IngressLoadBalancerIngress) Descriptor() ([]byte, []int) { + return fileDescriptor_5bea11de0ceb8f53, []int{9} +} +func (m *IngressLoadBalancerIngress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerIngress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerIngress) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerIngress.Merge(m, src) +} +func (m *IngressLoadBalancerIngress) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerIngress) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerIngress.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerIngress proto.InternalMessageInfo + +func (m *IngressLoadBalancerStatus) Reset() { *m = IngressLoadBalancerStatus{} } +func (*IngressLoadBalancerStatus) ProtoMessage() {} +func (*IngressLoadBalancerStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_5bea11de0ceb8f53, []int{10} +} +func (m *IngressLoadBalancerStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressLoadBalancerStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressLoadBalancerStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressLoadBalancerStatus.Merge(m, src) +} +func (m *IngressLoadBalancerStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressLoadBalancerStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressLoadBalancerStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressLoadBalancerStatus proto.InternalMessageInfo + +func (m *IngressPortStatus) Reset() { *m = IngressPortStatus{} } +func (*IngressPortStatus) ProtoMessage() {} +func (*IngressPortStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_5bea11de0ceb8f53, []int{11} +} +func (m *IngressPortStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IngressPortStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IngressPortStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_IngressPortStatus.Merge(m, src) +} +func (m *IngressPortStatus) XXX_Size() int { + return m.Size() +} +func (m *IngressPortStatus) XXX_DiscardUnknown() { + xxx_messageInfo_IngressPortStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_IngressPortStatus proto.InternalMessageInfo + func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} func (*IngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_5bea11de0ceb8f53, []int{9} + return fileDescriptor_5bea11de0ceb8f53, []int{12} } func (m *IngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -327,7 +412,7 @@ var xxx_messageInfo_IngressRule proto.InternalMessageInfo func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} func (*IngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_5bea11de0ceb8f53, []int{10} + return fileDescriptor_5bea11de0ceb8f53, []int{13} } func (m *IngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -355,7 +440,7 @@ var xxx_messageInfo_IngressRuleValue proto.InternalMessageInfo func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} func (*IngressSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_5bea11de0ceb8f53, []int{11} + return fileDescriptor_5bea11de0ceb8f53, []int{14} } func (m *IngressSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -383,7 +468,7 @@ var xxx_messageInfo_IngressSpec proto.InternalMessageInfo func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} func (*IngressStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_5bea11de0ceb8f53, []int{12} + return fileDescriptor_5bea11de0ceb8f53, []int{15} } func (m *IngressStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -411,7 +496,7 @@ var xxx_messageInfo_IngressStatus proto.InternalMessageInfo func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} func (*IngressTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_5bea11de0ceb8f53, []int{13} + return fileDescriptor_5bea11de0ceb8f53, []int{16} } func (m *IngressTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -446,6 +531,9 @@ func init() { proto.RegisterType((*IngressClassParametersReference)(nil), "k8s.io.api.networking.v1beta1.IngressClassParametersReference") proto.RegisterType((*IngressClassSpec)(nil), "k8s.io.api.networking.v1beta1.IngressClassSpec") proto.RegisterType((*IngressList)(nil), "k8s.io.api.networking.v1beta1.IngressList") + proto.RegisterType((*IngressLoadBalancerIngress)(nil), "k8s.io.api.networking.v1beta1.IngressLoadBalancerIngress") + proto.RegisterType((*IngressLoadBalancerStatus)(nil), "k8s.io.api.networking.v1beta1.IngressLoadBalancerStatus") + proto.RegisterType((*IngressPortStatus)(nil), "k8s.io.api.networking.v1beta1.IngressPortStatus") proto.RegisterType((*IngressRule)(nil), "k8s.io.api.networking.v1beta1.IngressRule") proto.RegisterType((*IngressRuleValue)(nil), "k8s.io.api.networking.v1beta1.IngressRuleValue") proto.RegisterType((*IngressSpec)(nil), "k8s.io.api.networking.v1beta1.IngressSpec") @@ -458,75 +546,85 @@ func init() { } var fileDescriptor_5bea11de0ceb8f53 = []byte{ - // 1087 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x41, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0xda, 0x71, 0xeb, 0x8c, 0x9d, 0x34, 0x1a, 0x72, 0xb0, 0x22, 0xd5, 0x8e, 0xf6, 0x80, - 0x02, 0xa5, 0xbb, 0xc4, 0x2d, 0x88, 0x13, 0x82, 0x8d, 0x04, 0x89, 0x6a, 0x1a, 0x33, 0xb6, 0x00, - 0x21, 0x0e, 0x1d, 0xaf, 0x5f, 0xd7, 0x8b, 0xd7, 0xbb, 0xcb, 0xcc, 0xac, 0x51, 0x6f, 0x5c, 0x39, - 0xc1, 0xaf, 0xe0, 0x27, 0x20, 0x8e, 0x08, 0x2e, 0x39, 0xf6, 0xd8, 0x0b, 0x11, 0x31, 0xff, 0x82, - 0x13, 0x9a, 0xd9, 0xf1, 0xee, 0xda, 0x4e, 0x5a, 0x87, 0x43, 0x4f, 0xf6, 0xbc, 0xf7, 0xbd, 0xf7, - 0xe6, 0xbd, 0xf7, 0xed, 0x7b, 0x83, 0x3e, 0x19, 0x7f, 0xc0, 0x2d, 0x3f, 0xb2, 0xc7, 0xc9, 0x00, - 0x58, 0x08, 0x02, 0xb8, 0x3d, 0x85, 0x70, 0x18, 0x31, 0x5b, 0x2b, 0x68, 0xec, 0xdb, 0x21, 0x88, - 0xef, 0x23, 0x36, 0xf6, 0x43, 0xcf, 0x9e, 0x1e, 0x0d, 0x40, 0xd0, 0x23, 0xdb, 0x83, 0x10, 0x18, - 0x15, 0x30, 0xb4, 0x62, 0x16, 0x89, 0x08, 0xdf, 0x4d, 0xe1, 0x16, 0x8d, 0x7d, 0x2b, 0x87, 0x5b, - 0x1a, 0xbe, 0x7f, 0xdf, 0xf3, 0xc5, 0x28, 0x19, 0x58, 0x6e, 0x34, 0xb1, 0xbd, 0xc8, 0x8b, 0x6c, - 0x65, 0x35, 0x48, 0x9e, 0xaa, 0x93, 0x3a, 0xa8, 0x7f, 0xa9, 0xb7, 0x7d, 0xb3, 0x10, 0xdc, 0x8d, - 0x18, 0xd8, 0xd3, 0x95, 0x88, 0xfb, 0x0f, 0x73, 0xcc, 0x84, 0xba, 0x23, 0x3f, 0x04, 0xf6, 0xcc, - 0x8e, 0xc7, 0x9e, 0x14, 0x70, 0x7b, 0x02, 0x82, 0x5e, 0x65, 0x65, 0x5f, 0x67, 0xc5, 0x92, 0x50, - 0xf8, 0x13, 0x58, 0x31, 0x78, 0xff, 0x55, 0x06, 0xdc, 0x1d, 0xc1, 0x84, 0xae, 0xd8, 0x3d, 0xb8, - 0xce, 0x2e, 0x11, 0x7e, 0x60, 0xfb, 0xa1, 0xe0, 0x82, 0x2d, 0x1b, 0x99, 0x7f, 0x1a, 0xe8, 0xce, - 0x49, 0xbf, 0xdf, 0x3d, 0x0d, 0x3d, 0x06, 0x9c, 0x77, 0xa9, 0x18, 0xe1, 0x03, 0xb4, 0x19, 0x53, - 0x31, 0x6a, 0x18, 0x07, 0xc6, 0xe1, 0x96, 0x53, 0x3f, 0xbf, 0x68, 0x6d, 0xcc, 0x2e, 0x5a, 0x9b, - 0x52, 0x47, 0x94, 0x06, 0x3f, 0x44, 0x55, 0xf9, 0xdb, 0x7f, 0x16, 0x43, 0xa3, 0xac, 0x50, 0x8d, - 0xd9, 0x45, 0xab, 0xda, 0xd5, 0xb2, 0x7f, 0x0b, 0xff, 0x49, 0x86, 0xc4, 0x5f, 0xa1, 0xdb, 0x03, - 0xea, 0x8e, 0x21, 0x1c, 0x36, 0x4a, 0x07, 0xc6, 0x61, 0xad, 0x7d, 0xdf, 0x7a, 0x69, 0x0f, 0x2d, - 0x7d, 0x29, 0x27, 0x35, 0x72, 0xee, 0xe8, 0x9b, 0xdc, 0xd6, 0x02, 0x32, 0x77, 0x67, 0x8e, 0xd1, - 0x5e, 0x21, 0x09, 0x92, 0x04, 0xf0, 0x05, 0x0d, 0x12, 0xc0, 0x3d, 0x54, 0x91, 0xd1, 0x79, 0xc3, - 0x38, 0x28, 0x1f, 0xd6, 0xda, 0xd6, 0x2b, 0xe2, 0x2d, 0x15, 0xc2, 0xd9, 0xd6, 0x01, 0x2b, 0xf2, - 0xc4, 0x49, 0xea, 0xcb, 0xfc, 0xa9, 0x84, 0x6e, 0x6b, 0x14, 0x7e, 0x82, 0xaa, 0xb2, 0xef, 0x43, - 0x2a, 0xa8, 0x2a, 0x57, 0xad, 0xfd, 0x6e, 0x21, 0x46, 0xd6, 0x06, 0x2b, 0x1e, 0x7b, 0x52, 0xc0, - 0x2d, 0x89, 0xb6, 0xa6, 0x47, 0xd6, 0xd9, 0xe0, 0x5b, 0x70, 0xc5, 0x67, 0x20, 0xa8, 0x83, 0x75, - 0x14, 0x94, 0xcb, 0x48, 0xe6, 0x15, 0x77, 0xd0, 0x26, 0x8f, 0xc1, 0xd5, 0x15, 0x7b, 0x7b, 0xbd, - 0x8a, 0xf5, 0x62, 0x70, 0xf3, 0xc6, 0xc9, 0x13, 0x51, 0x5e, 0x70, 0x1f, 0xdd, 0xe2, 0x82, 0x8a, - 0x84, 0xab, 0xb6, 0xd5, 0xda, 0xef, 0xac, 0xe9, 0x4f, 0xd9, 0x38, 0x3b, 0xda, 0xe3, 0xad, 0xf4, - 0x4c, 0xb4, 0x2f, 0xf3, 0xc7, 0x12, 0xda, 0x59, 0xec, 0x15, 0x7e, 0x0f, 0xd5, 0x38, 0xb0, 0xa9, - 0xef, 0xc2, 0x63, 0x3a, 0x01, 0x4d, 0xa5, 0x37, 0xb4, 0x7d, 0xad, 0x97, 0xab, 0x48, 0x11, 0x87, - 0xbd, 0xcc, 0xac, 0x1b, 0x31, 0xa1, 0x93, 0xbe, 0xbe, 0xa4, 0x92, 0xd9, 0x56, 0xca, 0x6c, 0xeb, - 0x34, 0x14, 0x67, 0xac, 0x27, 0x98, 0x1f, 0x7a, 0x2b, 0x81, 0xa4, 0x33, 0x52, 0xf4, 0x8c, 0xbf, - 0x44, 0x55, 0x06, 0x3c, 0x4a, 0x98, 0x0b, 0xba, 0x14, 0x0b, 0x64, 0x94, 0x23, 0x40, 0xb6, 0x49, - 0xf2, 0x76, 0xd8, 0x89, 0x5c, 0x1a, 0xa4, 0xcd, 0x21, 0xf0, 0x14, 0x18, 0x84, 0x2e, 0x38, 0x75, - 0x49, 0x78, 0xa2, 0x5d, 0x90, 0xcc, 0x99, 0xfc, 0xa0, 0xea, 0xba, 0x16, 0xc7, 0x01, 0x7d, 0x2d, - 0x14, 0xf9, 0x7c, 0x81, 0x22, 0xf6, 0x7a, 0x2d, 0x55, 0x97, 0xbb, 0x8e, 0x27, 0xe6, 0x1f, 0x06, - 0xda, 0x2d, 0x02, 0x3b, 0x3e, 0x17, 0xf8, 0x9b, 0x95, 0x4c, 0xac, 0xf5, 0x32, 0x91, 0xd6, 0x2a, - 0x8f, 0x5d, 0x1d, 0xaa, 0x3a, 0x97, 0x14, 0xb2, 0xe8, 0xa2, 0x8a, 0x2f, 0x60, 0xc2, 0x1b, 0x25, - 0xf5, 0xad, 0xde, 0xbb, 0x41, 0x1a, 0xf9, 0x87, 0x7a, 0x2a, 0x3d, 0x90, 0xd4, 0x91, 0xf9, 0x97, - 0x81, 0x5a, 0x45, 0x58, 0x97, 0x32, 0x3a, 0x01, 0x01, 0x8c, 0x67, 0x6d, 0xc4, 0x87, 0xa8, 0x4a, - 0xbb, 0xa7, 0x9f, 0xb2, 0x28, 0x89, 0xe7, 0xf3, 0x4e, 0xde, 0xef, 0x63, 0x2d, 0x23, 0x99, 0x56, - 0x4e, 0xc5, 0xb1, 0xaf, 0x47, 0x57, 0x61, 0x2a, 0x3e, 0xf2, 0xc3, 0x21, 0x51, 0x1a, 0x89, 0x08, - 0x25, 0xd9, 0xcb, 0x8b, 0x08, 0xc5, 0x72, 0xa5, 0xc1, 0x2d, 0x54, 0xe1, 0x6e, 0x14, 0x43, 0x63, - 0x53, 0x41, 0xb6, 0xe4, 0x95, 0x7b, 0x52, 0x40, 0x52, 0x39, 0xbe, 0x87, 0xb6, 0x24, 0x90, 0xc7, - 0xd4, 0x85, 0x46, 0x45, 0x81, 0xb6, 0x67, 0x17, 0xad, 0xad, 0xc7, 0x73, 0x21, 0xc9, 0xf5, 0xe6, - 0xaf, 0x4b, 0x4d, 0x92, 0xfd, 0xc3, 0x6d, 0x84, 0xdc, 0x28, 0x14, 0x2c, 0x0a, 0x02, 0x60, 0x3a, - 0xa5, 0x8c, 0x3e, 0xc7, 0x99, 0x86, 0x14, 0x50, 0x38, 0x44, 0x28, 0xce, 0x6a, 0xa3, 0x69, 0xf4, - 0xe1, 0x0d, 0xea, 0x7f, 0x45, 0x61, 0x9d, 0x1d, 0x19, 0xaf, 0xa0, 0x28, 0x44, 0x30, 0x7f, 0x33, - 0x50, 0x4d, 0xdb, 0xbf, 0x06, 0x62, 0x3d, 0x5a, 0x24, 0xd6, 0x9b, 0x6b, 0x2e, 0x9d, 0xab, 0x39, - 0xf5, 0x4b, 0x7e, 0x75, 0xb9, 0x66, 0x64, 0xcf, 0x47, 0x11, 0x17, 0xcb, 0xbb, 0xf2, 0x24, 0xe2, - 0x82, 0x28, 0x0d, 0x4e, 0xd0, 0xae, 0xbf, 0xb4, 0x97, 0x6e, 0xf6, 0xa5, 0x66, 0x66, 0x4e, 0x43, - 0xbb, 0xdf, 0x5d, 0xd6, 0x90, 0x95, 0x10, 0x26, 0xa0, 0x15, 0x94, 0x1c, 0x14, 0x23, 0x21, 0x62, - 0x5d, 0xe3, 0x07, 0xeb, 0x6f, 0xc3, 0xfc, 0x0a, 0x55, 0x95, 0x5d, 0xbf, 0xdf, 0x25, 0xca, 0x95, - 0xf9, 0x7b, 0x29, 0xab, 0x87, 0xa2, 0xdf, 0x47, 0x59, 0xb6, 0x8a, 0x19, 0x6a, 0xf8, 0xa7, 0x64, - 0xdf, 0x2b, 0x5c, 0x3c, 0xd3, 0x91, 0x15, 0x34, 0xee, 0xe7, 0xaf, 0x04, 0xe3, 0xff, 0xbc, 0x12, - 0x6a, 0x57, 0xbd, 0x10, 0xf0, 0x09, 0x2a, 0x8b, 0x60, 0x4e, 0x81, 0xb7, 0xd6, 0xf3, 0xd8, 0xef, - 0xf4, 0x9c, 0x9a, 0x2e, 0x79, 0xb9, 0xdf, 0xe9, 0x11, 0xe9, 0x02, 0x9f, 0xa1, 0x0a, 0x4b, 0x02, - 0x90, 0x1b, 0xb4, 0xbc, 0xfe, 0x46, 0x96, 0x15, 0xcc, 0x29, 0x25, 0x4f, 0x9c, 0xa4, 0x7e, 0xcc, - 0xef, 0xd0, 0xf6, 0xc2, 0x9a, 0xc5, 0x4f, 0x50, 0x3d, 0x88, 0xe8, 0xd0, 0xa1, 0x01, 0x0d, 0x5d, - 0xfd, 0x11, 0x2f, 0xf1, 0x76, 0xbe, 0x9f, 0x3a, 0x05, 0x9c, 0x5e, 0xd2, 0x7b, 0x3a, 0x48, 0xbd, - 0xa8, 0x23, 0x0b, 0x1e, 0x4d, 0x8a, 0x50, 0x9e, 0xa3, 0x9c, 0x4a, 0x92, 0xa9, 0xe9, 0x2b, 0x49, - 0x4f, 0x25, 0x49, 0x60, 0x4e, 0x52, 0xb9, 0x9c, 0x29, 0x1c, 0x5c, 0x06, 0x42, 0xb5, 0xb3, 0xb4, - 0x38, 0x53, 0x7a, 0x99, 0x86, 0x14, 0x50, 0xce, 0xf1, 0xf9, 0x65, 0x73, 0xe3, 0xf9, 0x65, 0x73, - 0xe3, 0xc5, 0x65, 0x73, 0xe3, 0x87, 0x59, 0xd3, 0x38, 0x9f, 0x35, 0x8d, 0xe7, 0xb3, 0xa6, 0xf1, - 0x62, 0xd6, 0x34, 0xfe, 0x9e, 0x35, 0x8d, 0x9f, 0xff, 0x69, 0x6e, 0x7c, 0x7d, 0xf7, 0xa5, 0x6f, - 0xfe, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xb0, 0xe2, 0xe8, 0x2c, 0x0c, 0x00, 0x00, + // 1247 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcb, 0x6f, 0x1b, 0x45, + 0x18, 0xcf, 0xda, 0x71, 0xe3, 0x8c, 0xd3, 0x36, 0x0c, 0x3d, 0x98, 0xa0, 0xda, 0xd1, 0x1e, 0x50, + 0xa0, 0xed, 0x6e, 0x93, 0x16, 0x54, 0x2e, 0x08, 0x36, 0x02, 0x12, 0x25, 0x24, 0x66, 0x6c, 0x1e, + 0x42, 0x1c, 0x18, 0xaf, 0xa7, 0xf6, 0xe2, 0xf5, 0xee, 0x6a, 0x66, 0x36, 0xa8, 0x37, 0x10, 0x27, + 0x4e, 0xf0, 0x3f, 0x20, 0xf1, 0x27, 0x20, 0x2e, 0x48, 0x08, 0x2e, 0x39, 0xf6, 0xd8, 0x0b, 0x11, + 0x31, 0xff, 0x45, 0x4f, 0xe8, 0x9b, 0x9d, 0x7d, 0xf8, 0x91, 0xd6, 0xe1, 0xd0, 0x53, 0xbc, 0xdf, + 0xe3, 0xf7, 0xbd, 0xbf, 0xf9, 0x82, 0x3e, 0x18, 0x3e, 0x10, 0x96, 0x17, 0xda, 0xc3, 0xb8, 0xcb, + 0x78, 0xc0, 0x24, 0x13, 0xf6, 0x09, 0x0b, 0x7a, 0x21, 0xb7, 0x35, 0x83, 0x46, 0x9e, 0x1d, 0x30, + 0xf9, 0x4d, 0xc8, 0x87, 0x5e, 0xd0, 0xb7, 0x4f, 0xb6, 0xbb, 0x4c, 0xd2, 0x6d, 0xbb, 0xcf, 0x02, + 0xc6, 0xa9, 0x64, 0x3d, 0x2b, 0xe2, 0xa1, 0x0c, 0xf1, 0xcd, 0x44, 0xdc, 0xa2, 0x91, 0x67, 0xe5, + 0xe2, 0x96, 0x16, 0xdf, 0xb8, 0xd3, 0xf7, 0xe4, 0x20, 0xee, 0x5a, 0x6e, 0x38, 0xb2, 0xfb, 0x61, + 0x3f, 0xb4, 0x95, 0x56, 0x37, 0x7e, 0xa8, 0xbe, 0xd4, 0x87, 0xfa, 0x95, 0xa0, 0x6d, 0x98, 0x05, + 0xe3, 0x6e, 0xc8, 0x99, 0x7d, 0x32, 0x63, 0x71, 0xe3, 0x7e, 0x2e, 0x33, 0xa2, 0xee, 0xc0, 0x0b, + 0x18, 0x7f, 0x64, 0x47, 0xc3, 0x3e, 0x10, 0x84, 0x3d, 0x62, 0x92, 0xce, 0xd3, 0xb2, 0x2f, 0xd2, + 0xe2, 0x71, 0x20, 0xbd, 0x11, 0x9b, 0x51, 0x78, 0xeb, 0x79, 0x0a, 0xc2, 0x1d, 0xb0, 0x11, 0x9d, + 0xd1, 0xbb, 0x77, 0x91, 0x5e, 0x2c, 0x3d, 0xdf, 0xf6, 0x02, 0x29, 0x24, 0x9f, 0x56, 0x32, 0xff, + 0x32, 0xd0, 0xf5, 0xbd, 0x4e, 0xa7, 0xb5, 0x1f, 0xf4, 0x39, 0x13, 0xa2, 0x45, 0xe5, 0x00, 0x6f, + 0xa2, 0xe5, 0x88, 0xca, 0x41, 0xdd, 0xd8, 0x34, 0xb6, 0x56, 0x9d, 0xb5, 0xd3, 0xb3, 0xe6, 0xd2, + 0xf8, 0xac, 0xb9, 0x0c, 0x3c, 0xa2, 0x38, 0xf8, 0x3e, 0xaa, 0xc2, 0xdf, 0xce, 0xa3, 0x88, 0xd5, + 0xcb, 0x4a, 0xaa, 0x3e, 0x3e, 0x6b, 0x56, 0x5b, 0x9a, 0xf6, 0xb4, 0xf0, 0x9b, 0x64, 0x92, 0xf8, + 0x73, 0xb4, 0xd2, 0xa5, 0xee, 0x90, 0x05, 0xbd, 0x7a, 0x69, 0xd3, 0xd8, 0xaa, 0xed, 0xdc, 0xb1, + 0x9e, 0x59, 0x43, 0x4b, 0x3b, 0xe5, 0x24, 0x4a, 0xce, 0x75, 0xed, 0xc9, 0x8a, 0x26, 0x90, 0x14, + 0xce, 0x1c, 0xa2, 0x1b, 0x85, 0x20, 0x48, 0xec, 0xb3, 0x4f, 0xa9, 0x1f, 0x33, 0xdc, 0x46, 0x15, + 0xb0, 0x2e, 0xea, 0xc6, 0x66, 0x79, 0xab, 0xb6, 0x63, 0x3d, 0xc7, 0xde, 0x54, 0x22, 0x9c, 0xab, + 0xda, 0x60, 0x05, 0xbe, 0x04, 0x49, 0xb0, 0xcc, 0x1f, 0x4b, 0x68, 0x45, 0x4b, 0xe1, 0xaf, 0x50, + 0x15, 0xea, 0xde, 0xa3, 0x92, 0xaa, 0x74, 0xd5, 0x76, 0xee, 0x16, 0x6c, 0x64, 0x65, 0xb0, 0xa2, + 0x61, 0x1f, 0x08, 0xc2, 0x02, 0x69, 0xeb, 0x64, 0xdb, 0x3a, 0xee, 0x7e, 0xcd, 0x5c, 0xf9, 0x11, + 0x93, 0xd4, 0xc1, 0xda, 0x0a, 0xca, 0x69, 0x24, 0x43, 0xc5, 0x87, 0x68, 0x59, 0x44, 0xcc, 0xd5, + 0x19, 0x7b, 0x63, 0xb1, 0x8c, 0xb5, 0x23, 0xe6, 0xe6, 0x85, 0x83, 0x2f, 0xa2, 0x50, 0x70, 0x07, + 0x5d, 0x11, 0x92, 0xca, 0x58, 0xa8, 0xb2, 0xd5, 0x76, 0x6e, 0x2f, 0x88, 0xa7, 0x74, 0x9c, 0x6b, + 0x1a, 0xf1, 0x4a, 0xf2, 0x4d, 0x34, 0x96, 0xf9, 0x43, 0x09, 0x5d, 0x9b, 0xac, 0x15, 0x7e, 0x13, + 0xd5, 0x04, 0xe3, 0x27, 0x9e, 0xcb, 0x8e, 0xe8, 0x88, 0xe9, 0x56, 0x7a, 0x59, 0xeb, 0xd7, 0xda, + 0x39, 0x8b, 0x14, 0xe5, 0x70, 0x3f, 0x53, 0x6b, 0x85, 0x5c, 0xea, 0xa0, 0x2f, 0x4e, 0x29, 0x74, + 0xb6, 0x95, 0x74, 0xb6, 0xb5, 0x1f, 0xc8, 0x63, 0xde, 0x96, 0xdc, 0x0b, 0xfa, 0x33, 0x86, 0x00, + 0x8c, 0x14, 0x91, 0xf1, 0x67, 0xa8, 0xca, 0x99, 0x08, 0x63, 0xee, 0x32, 0x9d, 0x8a, 0x89, 0x66, + 0x84, 0x15, 0x00, 0x65, 0x82, 0xbe, 0xed, 0x1d, 0x86, 0x2e, 0xf5, 0x93, 0xe2, 0x10, 0xf6, 0x90, + 0x71, 0x16, 0xb8, 0xcc, 0x59, 0x83, 0x86, 0x27, 0x1a, 0x82, 0x64, 0x60, 0x30, 0x50, 0x6b, 0x3a, + 0x17, 0xbb, 0x3e, 0x7d, 0x21, 0x2d, 0xf2, 0xf1, 0x44, 0x8b, 0xd8, 0x8b, 0x95, 0x54, 0x39, 0x77, + 0x51, 0x9f, 0x98, 0x7f, 0x1a, 0x68, 0xbd, 0x28, 0x78, 0xe8, 0x09, 0x89, 0xbf, 0x9c, 0x89, 0xc4, + 0x5a, 0x2c, 0x12, 0xd0, 0x56, 0x71, 0xac, 0x6b, 0x53, 0xd5, 0x94, 0x52, 0x88, 0xa2, 0x85, 0x2a, + 0x9e, 0x64, 0x23, 0x51, 0x2f, 0xa9, 0x59, 0xbd, 0x75, 0x89, 0x30, 0xf2, 0x41, 0xdd, 0x07, 0x04, + 0x92, 0x00, 0x99, 0x7f, 0x1b, 0xa8, 0x59, 0x14, 0x6b, 0x51, 0x4e, 0x47, 0x4c, 0x32, 0x2e, 0xb2, + 0x32, 0xe2, 0x2d, 0x54, 0xa5, 0xad, 0xfd, 0x0f, 0x79, 0x18, 0x47, 0xe9, 0xbe, 0x03, 0xff, 0xde, + 0xd3, 0x34, 0x92, 0x71, 0x61, 0x2b, 0x0e, 0x3d, 0xbd, 0xba, 0x0a, 0x5b, 0xf1, 0xc0, 0x0b, 0x7a, + 0x44, 0x71, 0x40, 0x22, 0x80, 0x66, 0x2f, 0x4f, 0x4a, 0xa8, 0x2e, 0x57, 0x1c, 0xdc, 0x44, 0x15, + 0xe1, 0x86, 0x11, 0xab, 0x2f, 0x2b, 0x91, 0x55, 0x70, 0xb9, 0x0d, 0x04, 0x92, 0xd0, 0xf1, 0x2d, + 0xb4, 0x0a, 0x82, 0x22, 0xa2, 0x2e, 0xab, 0x57, 0x94, 0xd0, 0xd5, 0xf1, 0x59, 0x73, 0xf5, 0x28, + 0x25, 0x92, 0x9c, 0x6f, 0xfe, 0x3a, 0x55, 0x24, 0xa8, 0x1f, 0xde, 0x41, 0xc8, 0x0d, 0x03, 0xc9, + 0x43, 0xdf, 0x67, 0x5c, 0x87, 0x94, 0xb5, 0xcf, 0x6e, 0xc6, 0x21, 0x05, 0x29, 0x1c, 0x20, 0x14, + 0x65, 0xb9, 0xd1, 0x6d, 0xf4, 0xce, 0x25, 0xf2, 0x3f, 0x27, 0xb1, 0xce, 0x35, 0xb0, 0x57, 0x60, + 0x14, 0x2c, 0x98, 0xbf, 0x19, 0xa8, 0xa6, 0xf5, 0x5f, 0x40, 0x63, 0x1d, 0x4c, 0x36, 0xd6, 0x6b, + 0x0b, 0x3e, 0x3a, 0xf3, 0x7b, 0xea, 0x77, 0x03, 0x6d, 0xa4, 0xae, 0x87, 0xb4, 0xe7, 0x50, 0x9f, + 0x06, 0x2e, 0xe3, 0xe9, 0x7b, 0xb0, 0x81, 0x4a, 0x5e, 0xda, 0x48, 0x48, 0x03, 0x94, 0xf6, 0x5b, + 0xa4, 0xe4, 0x45, 0xf8, 0x36, 0xaa, 0x0e, 0x42, 0x21, 0x55, 0x8b, 0x24, 0x4d, 0x94, 0x79, 0xbd, + 0xa7, 0xe9, 0x24, 0x93, 0xc0, 0x9f, 0xa0, 0x4a, 0x14, 0x72, 0x29, 0xea, 0xcb, 0xca, 0xeb, 0xbb, + 0x8b, 0x79, 0x0d, 0xbb, 0x4d, 0x2f, 0xeb, 0xfc, 0xf1, 0x02, 0x18, 0x92, 0xa0, 0x99, 0xdf, 0x19, + 0xe8, 0x95, 0x39, 0xfe, 0x27, 0x3a, 0xb8, 0x87, 0x56, 0xbc, 0x84, 0xa9, 0x5f, 0xcc, 0xb7, 0x17, + 0x33, 0x3b, 0x27, 0x15, 0xf9, 0x6b, 0x9d, 0xbe, 0xca, 0x29, 0xb4, 0xf9, 0xb3, 0x81, 0x5e, 0x9a, + 0xf1, 0x57, 0x5d, 0x1d, 0xb0, 0xf3, 0x21, 0x79, 0x95, 0xc2, 0xd5, 0x01, 0xab, 0x5b, 0x71, 0xf0, + 0x01, 0xaa, 0xaa, 0xa3, 0xc5, 0x0d, 0x7d, 0x9d, 0x40, 0x3b, 0x4d, 0x60, 0x4b, 0xd3, 0x9f, 0x9e, + 0x35, 0x5f, 0x9d, 0xbd, 0xe4, 0xac, 0x94, 0x4d, 0x32, 0x00, 0x18, 0x45, 0xc6, 0x79, 0xc8, 0xf5, + 0xb4, 0xaa, 0x51, 0x7c, 0x1f, 0x08, 0x24, 0xa1, 0x9b, 0xbf, 0xe4, 0x4d, 0x0a, 0x07, 0x05, 0xf8, + 0x07, 0xc5, 0x99, 0xbe, 0x8a, 0xa0, 0x74, 0x44, 0x71, 0x70, 0x8c, 0xd6, 0xbd, 0xa9, 0x0b, 0xe4, + 0x72, 0x3b, 0x39, 0x53, 0x73, 0xea, 0x1a, 0x7e, 0x7d, 0x9a, 0x43, 0x66, 0x4c, 0x98, 0x0c, 0xcd, + 0x48, 0xc1, 0x93, 0x30, 0x90, 0x32, 0xd2, 0xd3, 0x74, 0x6f, 0xf1, 0xbb, 0x27, 0x77, 0xa1, 0xaa, + 0xa2, 0xeb, 0x74, 0x5a, 0x44, 0x41, 0x99, 0x7f, 0x94, 0xb2, 0x7c, 0xa8, 0x45, 0xf3, 0x6e, 0x16, + 0xad, 0xda, 0x01, 0xea, 0x99, 0x4f, 0xd6, 0xda, 0x8d, 0x82, 0xe3, 0x19, 0x8f, 0xcc, 0x48, 0xe3, + 0x4e, 0x7e, 0x0f, 0x1a, 0xff, 0xe7, 0x1e, 0xac, 0xcd, 0xbb, 0x05, 0xf1, 0x1e, 0x2a, 0x4b, 0x3f, + 0x1d, 0xf6, 0xd7, 0x17, 0x43, 0xec, 0x1c, 0xb6, 0x9d, 0x9a, 0x4e, 0x79, 0xb9, 0x73, 0xd8, 0x26, + 0x00, 0x81, 0x8f, 0x51, 0x85, 0xc7, 0x3e, 0x83, 0x5b, 0xa9, 0xbc, 0xf8, 0xed, 0x05, 0x19, 0xcc, + 0x87, 0x0f, 0xbe, 0x04, 0x49, 0x70, 0xcc, 0xef, 0x0d, 0x74, 0x75, 0xe2, 0xa2, 0xc2, 0x1c, 0xad, + 0xf9, 0x85, 0xd9, 0xd1, 0x79, 0x78, 0x70, 0xf9, 0xa9, 0xd3, 0x43, 0x7f, 0x43, 0xdb, 0x5d, 0x2b, + 0xf2, 0xc8, 0x84, 0x0d, 0x93, 0x22, 0x94, 0x87, 0x0d, 0x73, 0x00, 0xcd, 0x9b, 0x0c, 0xbc, 0x9e, + 0x03, 0xe8, 0x69, 0x41, 0x12, 0x3a, 0x3c, 0x28, 0x82, 0xb9, 0x9c, 0xc9, 0xa3, 0x7c, 0x71, 0x65, + 0x0f, 0x4a, 0x3b, 0xe3, 0x90, 0x82, 0x94, 0xb3, 0x7b, 0x7a, 0xde, 0x58, 0x7a, 0x7c, 0xde, 0x58, + 0x7a, 0x72, 0xde, 0x58, 0xfa, 0x76, 0xdc, 0x30, 0x4e, 0xc7, 0x0d, 0xe3, 0xf1, 0xb8, 0x61, 0x3c, + 0x19, 0x37, 0x8c, 0x7f, 0xc6, 0x0d, 0xe3, 0xa7, 0x7f, 0x1b, 0x4b, 0x5f, 0xdc, 0x7c, 0xe6, 0x3f, + 0x7c, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x08, 0x04, 0x22, 0x31, 0x29, 0x0e, 0x00, 0x00, } func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { @@ -945,6 +1043,128 @@ func (m *IngressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *IngressLoadBalancerIngress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerIngress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerIngress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ports) > 0 { + for iNdEx := len(m.Ports) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ports[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + i -= len(m.Hostname) + copy(dAtA[i:], m.Hostname) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Hostname))) + i-- + dAtA[i] = 0x12 + i -= len(m.IP) + copy(dAtA[i:], m.IP) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IP))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IngressLoadBalancerStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressLoadBalancerStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressLoadBalancerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ingress) > 0 { + for iNdEx := len(m.Ingress) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ingress[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *IngressPortStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressPortStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressPortStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != nil { + i -= len(*m.Error) + copy(dAtA[i:], *m.Error) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Error))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0x12 + i = encodeVarintGenerated(dAtA, i, uint64(m.Port)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *IngressRule) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1320,6 +1540,56 @@ func (m *IngressList) Size() (n int) { return n } +func (m *IngressLoadBalancerIngress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.IP) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Hostname) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Ports) > 0 { + for _, e := range m.Ports { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressLoadBalancerStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ingress) > 0 { + for _, e := range m.Ingress { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IngressPortStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.Port)) + l = len(m.Protocol) + n += 1 + l + sovGenerated(uint64(l)) + if m.Error != nil { + l = len(*m.Error) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *IngressRule) Size() (n int) { if m == nil { return 0 @@ -1528,6 +1798,50 @@ func (this *IngressList) String() string { }, "") return s } +func (this *IngressLoadBalancerIngress) String() string { + if this == nil { + return "nil" + } + repeatedStringForPorts := "[]IngressPortStatus{" + for _, f := range this.Ports { + repeatedStringForPorts += strings.Replace(strings.Replace(f.String(), "IngressPortStatus", "IngressPortStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForPorts += "}" + s := strings.Join([]string{`&IngressLoadBalancerIngress{`, + `IP:` + fmt.Sprintf("%v", this.IP) + `,`, + `Hostname:` + fmt.Sprintf("%v", this.Hostname) + `,`, + `Ports:` + repeatedStringForPorts + `,`, + `}`, + }, "") + return s +} +func (this *IngressLoadBalancerStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForIngress := "[]IngressLoadBalancerIngress{" + for _, f := range this.Ingress { + repeatedStringForIngress += strings.Replace(strings.Replace(f.String(), "IngressLoadBalancerIngress", "IngressLoadBalancerIngress", 1), `&`, ``, 1) + "," + } + repeatedStringForIngress += "}" + s := strings.Join([]string{`&IngressLoadBalancerStatus{`, + `Ingress:` + repeatedStringForIngress + `,`, + `}`, + }, "") + return s +} +func (this *IngressPortStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IngressPortStatus{`, + `Port:` + fmt.Sprintf("%v", this.Port) + `,`, + `Protocol:` + fmt.Sprintf("%v", this.Protocol) + `,`, + `Error:` + valueToStringGenerated(this.Error) + `,`, + `}`, + }, "") + return s +} func (this *IngressRule) String() string { if this == nil { return "nil" @@ -1577,7 +1891,7 @@ func (this *IngressStatus) String() string { return "nil" } s := strings.Join([]string{`&IngressStatus{`, - `LoadBalancer:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LoadBalancer), "LoadBalancerStatus", "v11.LoadBalancerStatus", 1), `&`, ``, 1) + `,`, + `LoadBalancer:` + strings.Replace(strings.Replace(this.LoadBalancer.String(), "IngressLoadBalancerStatus", "IngressLoadBalancerStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -2814,6 +3128,372 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { } return nil } +func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressLoadBalancerIngress: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressLoadBalancerIngress: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IP", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IP = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hostname = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, IngressPortStatus{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressLoadBalancerStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ingress = append(m.Ingress, IngressLoadBalancerIngress{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressPortStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressPortStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + m.Port = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Port |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocol = k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Error = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *IngressRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/networking/v1beta1/generated.proto b/vendor/k8s.io/api/networking/v1beta1/generated.proto index 439c8905063..46bb7f66f22 100644 --- a/vendor/k8s.io/api/networking/v1beta1/generated.proto +++ b/vendor/k8s.io/api/networking/v1beta1/generated.proto @@ -33,14 +33,14 @@ option go_package = "k8s.io/api/networking/v1beta1"; // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional optional string path = 1; - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -57,7 +57,7 @@ message HTTPIngressPath { // Defaults to ImplementationSpecific. optional string pathType = 3; - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; } @@ -68,7 +68,7 @@ message HTTPIngressPath { // to match against everything after the last '/' and before the first '?' // or '#'. message HTTPIngressRuleValue { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. repeated HTTPIngressPath paths = 1; } @@ -82,12 +82,12 @@ message Ingress { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressSpec spec = 2; - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressStatus status = 3; @@ -95,15 +95,15 @@ message Ingress { // IngressBackend describes all endpoints for a given service and port. message IngressBackend { - // Specifies the name of the referenced service. + // serviceName specifies the name of the referenced service. // +optional optional string serviceName = 1; - // Specifies the port of the referenced service. + // servicePort Specifies the port of the referenced service. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString servicePort = 2; - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, serviceName and servicePort // must not be specified. // +optional @@ -121,7 +121,7 @@ message IngressClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressClassSpec spec = 2; @@ -133,30 +133,30 @@ message IngressClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of IngressClasses. + // items is the list of IngressClasses. repeated IngressClass items = 2; } // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. message IngressClassParametersReference { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional optional string aPIGroup = 1; - // Kind is the type of resource being referenced. + // kind is the type of resource being referenced. optional string kind = 2; - // Name is the name of resource being referenced. + // name is the name of resource being referenced. optional string name = 3; - // Scope represents if this refers to a cluster or namespace scoped resource. + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". optional string scope = 4; - // Namespace is the namespace of the resource being referenced. This field is + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -165,15 +165,15 @@ message IngressClassParametersReference { // IngressClassSpec provides information about the class of an Ingress. message IngressClassSpec { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. optional string controller = 1; - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -187,15 +187,62 @@ message IngressList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of Ingress. + // items is the list of Ingress. repeated Ingress items = 2; } +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +message IngressLoadBalancerIngress { + // ip is set for load-balancer ingress points that are IP based. + // +optional + optional string ip = 1; + + // hostname is set for load-balancer ingress points that are DNS based. + // +optional + optional string hostname = 2; + + // ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic + // +optional + repeated IngressPortStatus ports = 4; +} + +// LoadBalancerStatus represents the status of a load-balancer. +message IngressLoadBalancerStatus { + // ingress is a list containing ingress points for the load-balancer. + // +optional + repeated IngressLoadBalancerIngress ingress = 1; +} + +// IngressPortStatus represents the error condition of a service port +message IngressPortStatus { + // port is the port number of the ingress port. + optional int32 port = 1; + + // protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + optional string protocol = 2; + + // error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + optional string error = 3; +} + // IngressRule represents the rules mapping the paths under a specified host to // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. message IngressRule { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -208,7 +255,7 @@ message IngressRule { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and @@ -240,7 +287,7 @@ message IngressRuleValue { // IngressSpec describes the Ingress the user wishes to exist. message IngressSpec { - // IngressClassName is the name of the IngressClass cluster resource. The + // ingressClassName is the name of the IngressClass cluster resource. The // associated IngressClass defines which controller will implement the // resource. This replaces the deprecated `kubernetes.io/ingress.class` // annotation. For backwards compatibility, when that annotation is set, it @@ -253,44 +300,44 @@ message IngressSpec { // +optional optional string ingressClassName = 4; - // A default backend capable of servicing requests that don't match any + // backend is the default backend capable of servicing requests that don't match any // rule. At least one of 'backend' or 'rules' must be specified. This field // is optional to allow the loadbalancer controller or defaulting logic to // specify a global default. // +optional optional IngressBackend backend = 1; - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +optional repeated IngressTLS tls = 2; - // A list of host rules used to configure the Ingress. If unspecified, or + // rules is a list of host rules used to configure the Ingress. If unspecified, or // no rule matches, all traffic is sent to the default backend. // +optional repeated IngressRule rules = 3; } -// IngressStatus describe the current state of the Ingress. +// IngressStatus describes the current state of the Ingress. message IngressStatus { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional - optional k8s.io.api.core.v1.LoadBalancerStatus loadBalancer = 1; + optional IngressLoadBalancerStatus loadBalancer = 1; } // IngressTLS describes the transport layer security associated with an Ingress. message IngressTLS { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +optional repeated string hosts = 1; - // SecretName is the name of the secret used to terminate TLS traffic on + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination diff --git a/vendor/k8s.io/api/networking/v1beta1/types.go b/vendor/k8s.io/api/networking/v1beta1/types.go index 1bfdcd0915b..87cc91654b8 100644 --- a/vendor/k8s.io/api/networking/v1beta1/types.go +++ b/vendor/k8s.io/api/networking/v1beta1/types.go @@ -34,17 +34,18 @@ import ( // based virtual hosting etc. type Ingress struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status IngressStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -58,18 +59,19 @@ type Ingress struct { // IngressList is a collection of Ingress. type IngressList struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of Ingress. + // items is the list of Ingress. Items []Ingress `json:"items" protobuf:"bytes,2,rep,name=items"` } // IngressSpec describes the Ingress the user wishes to exist. type IngressSpec struct { - // IngressClassName is the name of the IngressClass cluster resource. The + // ingressClassName is the name of the IngressClass cluster resource. The // associated IngressClass defines which controller will implement the // resource. This replaces the deprecated `kubernetes.io/ingress.class` // annotation. For backwards compatibility, when that annotation is set, it @@ -82,22 +84,22 @@ type IngressSpec struct { // +optional IngressClassName *string `json:"ingressClassName,omitempty" protobuf:"bytes,4,opt,name=ingressClassName"` - // A default backend capable of servicing requests that don't match any + // backend is the default backend capable of servicing requests that don't match any // rule. At least one of 'backend' or 'rules' must be specified. This field // is optional to allow the loadbalancer controller or defaulting logic to // specify a global default. // +optional Backend *IngressBackend `json:"backend,omitempty" protobuf:"bytes,1,opt,name=backend"` - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +optional TLS []IngressTLS `json:"tls,omitempty" protobuf:"bytes,2,rep,name=tls"` - // A list of host rules used to configure the Ingress. If unspecified, or + // rules is a list of host rules used to configure the Ingress. If unspecified, or // no rule matches, all traffic is sent to the default backend. // +optional Rules []IngressRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` @@ -106,13 +108,14 @@ type IngressSpec struct { // IngressTLS describes the transport layer security associated with an Ingress. type IngressTLS struct { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +optional Hosts []string `json:"hosts,omitempty" protobuf:"bytes,1,rep,name=hosts"` - // SecretName is the name of the secret used to terminate TLS traffic on + + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination @@ -122,18 +125,65 @@ type IngressTLS struct { // TODO: Consider specifying different modes of termination, protocols etc. } -// IngressStatus describe the current state of the Ingress. +// IngressStatus describes the current state of the Ingress. type IngressStatus struct { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. + // +optional + LoadBalancer IngressLoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` +} + +// LoadBalancerStatus represents the status of a load-balancer. +type IngressLoadBalancerStatus struct { + // ingress is a list containing ingress points for the load-balancer. // +optional - LoadBalancer v1.LoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` + Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` +} + +// IngressLoadBalancerIngress represents the status of a load-balancer ingress point. +type IngressLoadBalancerIngress struct { + // ip is set for load-balancer ingress points that are IP based. + // +optional + IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` + + // hostname is set for load-balancer ingress points that are DNS based. + // +optional + Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` + + // ports provides information about the ports exposed by this LoadBalancer. + // +listType=atomic + // +optional + Ports []IngressPortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"` +} + +// IngressPortStatus represents the error condition of a service port +type IngressPortStatus struct { + // port is the port number of the ingress port. + Port int32 `json:"port" protobuf:"varint,1,opt,name=port"` + + // protocol is the protocol of the ingress port. + // The supported values are: "TCP", "UDP", "SCTP" + Protocol v1.Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` + + // error is to record the problem with the service port + // The format of the error shall comply with the following rules: + // - built-in error values shall be specified in this file and those shall use + // CamelCase names + // - cloud provider specific error values must have names that comply with the + // format foo.example.com/CamelCase. + // --- + // The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + // +optional + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + Error *string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"` } // IngressRule represents the rules mapping the paths under a specified host to // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. type IngressRule struct { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -146,7 +196,7 @@ type IngressRule struct { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and @@ -157,6 +207,7 @@ type IngressRule struct { // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional Host string `json:"host,omitempty" protobuf:"bytes,1,opt,name=host"` + // IngressRuleValue represents a rule to route requests for this IngressRule. // If unspecified, the rule defaults to a http catch-all. Whether that sends // just traffic matching the host to the default backend or all traffic to the @@ -187,7 +238,7 @@ type IngressRuleValue struct { // to match against everything after the last '/' and before the first '?' // or '#'. type HTTPIngressRuleValue struct { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. Paths []HTTPIngressPath `json:"paths" protobuf:"bytes,1,rep,name=paths"` // TODO: Consider adding fields for ingress-type specific global // options usable by a loadbalancer, like http keep-alive. @@ -226,14 +277,14 @@ const ( // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. type HTTPIngressPath struct { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -250,22 +301,22 @@ type HTTPIngressPath struct { // Defaults to ImplementationSpecific. PathType *PathType `json:"pathType,omitempty" protobuf:"bytes,3,opt,name=pathType"` - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` } // IngressBackend describes all endpoints for a given service and port. type IngressBackend struct { - // Specifies the name of the referenced service. + // serviceName specifies the name of the referenced service. // +optional ServiceName string `json:"serviceName,omitempty" protobuf:"bytes,1,opt,name=serviceName"` - // Specifies the port of the referenced service. + // servicePort Specifies the port of the referenced service. // +optional ServicePort intstr.IntOrString `json:"servicePort,omitempty" protobuf:"bytes,2,opt,name=servicePort"` - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, serviceName and servicePort // must not be specified. // +optional @@ -286,12 +337,13 @@ type IngressBackend struct { // resources without a class specified will be assigned this default class. type IngressClass struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressClassSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -299,15 +351,15 @@ type IngressClass struct { // IngressClassSpec provides information about the class of an Ingress. type IngressClassSpec struct { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. Controller string `json:"controller,omitempty" protobuf:"bytes,1,opt,name=controller"` - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -318,7 +370,7 @@ const ( // IngressClassParametersReferenceScopeNamespace indicates that the // referenced Parameters resource is namespace-scoped. IngressClassParametersReferenceScopeNamespace = "Namespace" - // IngressClassParametersReferenceScopeNamespace indicates that the + // IngressClassParametersReferenceScopeCluster indicates that the // referenced Parameters resource is cluster-scoped. IngressClassParametersReferenceScopeCluster = "Cluster" ) @@ -326,19 +378,23 @@ const ( // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. type IngressClassParametersReference struct { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` - // Kind is the type of resource being referenced. + + // kind is the type of resource being referenced. Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - // Name is the name of resource being referenced. + + // name is the name of resource being referenced. Name string `json:"name" protobuf:"bytes,3,opt,name=name"` - // Scope represents if this refers to a cluster or namespace scoped resource. + + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". Scope *string `json:"scope" protobuf:"bytes,4,opt,name=scope"` - // Namespace is the namespace of the resource being referenced. This field is + + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -357,6 +413,6 @@ type IngressClassList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of IngressClasses. + // items is the list of IngressClasses. Items []IngressClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go index 79c42a6ba4b..b2373669fec 100644 --- a/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", - "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "path": "path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", + "pathType": "pathType determines the interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", + "backend": "backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (HTTPIngressPath) SwaggerDoc() map[string]string { var map_HTTPIngressRuleValue = map[string]string{ "": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", - "paths": "A collection of paths that map requests to backends.", + "paths": "paths is a collection of paths that map requests to backends.", } func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { @@ -50,8 +50,8 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { var map_Ingress = map[string]string{ "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", - "status": "Status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Ingress) SwaggerDoc() map[string]string { @@ -60,9 +60,9 @@ func (Ingress) SwaggerDoc() map[string]string { var map_IngressBackend = map[string]string{ "": "IngressBackend describes all endpoints for a given service and port.", - "serviceName": "Specifies the name of the referenced service.", - "servicePort": "Specifies the port of the referenced service.", - "resource": "Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, serviceName and servicePort must not be specified.", + "serviceName": "serviceName specifies the name of the referenced service.", + "servicePort": "servicePort Specifies the port of the referenced service.", + "resource": "resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, serviceName and servicePort must not be specified.", } func (IngressBackend) SwaggerDoc() map[string]string { @@ -72,7 +72,7 @@ func (IngressBackend) SwaggerDoc() map[string]string { var map_IngressClass = map[string]string{ "": "IngressClass represents the class of the Ingress, referenced by the Ingress Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (IngressClass) SwaggerDoc() map[string]string { @@ -82,7 +82,7 @@ func (IngressClass) SwaggerDoc() map[string]string { var map_IngressClassList = map[string]string{ "": "IngressClassList is a collection of IngressClasses.", "metadata": "Standard list metadata.", - "items": "Items is the list of IngressClasses.", + "items": "items is the list of IngressClasses.", } func (IngressClassList) SwaggerDoc() map[string]string { @@ -91,11 +91,11 @@ func (IngressClassList) SwaggerDoc() map[string]string { var map_IngressClassParametersReference = map[string]string{ "": "IngressClassParametersReference identifies an API object. This can be used to specify a cluster or namespace-scoped resource.", - "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", - "kind": "Kind is the type of resource being referenced.", - "name": "Name is the name of resource being referenced.", - "scope": "Scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", - "namespace": "Namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", + "apiGroup": "apiGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "kind": "kind is the type of resource being referenced.", + "name": "name is the name of resource being referenced.", + "scope": "scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", + "namespace": "namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", } func (IngressClassParametersReference) SwaggerDoc() map[string]string { @@ -104,8 +104,8 @@ func (IngressClassParametersReference) SwaggerDoc() map[string]string { var map_IngressClassSpec = map[string]string{ "": "IngressClassSpec provides information about the class of an Ingress.", - "controller": "Controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", - "parameters": "Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", + "controller": "controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", + "parameters": "parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", } func (IngressClassSpec) SwaggerDoc() map[string]string { @@ -115,16 +115,47 @@ func (IngressClassSpec) SwaggerDoc() map[string]string { var map_IngressList = map[string]string{ "": "IngressList is a collection of Ingress.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of Ingress.", + "items": "items is the list of Ingress.", } func (IngressList) SwaggerDoc() map[string]string { return map_IngressList } +var map_IngressLoadBalancerIngress = map[string]string{ + "": "IngressLoadBalancerIngress represents the status of a load-balancer ingress point.", + "ip": "ip is set for load-balancer ingress points that are IP based.", + "hostname": "hostname is set for load-balancer ingress points that are DNS based.", + "ports": "ports provides information about the ports exposed by this LoadBalancer.", +} + +func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerIngress +} + +var map_IngressLoadBalancerStatus = map[string]string{ + "": "LoadBalancerStatus represents the status of a load-balancer.", + "ingress": "ingress is a list containing ingress points for the load-balancer.", +} + +func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { + return map_IngressLoadBalancerStatus +} + +var map_IngressPortStatus = map[string]string{ + "": "IngressPortStatus represents the error condition of a service port", + "port": "port is the port number of the ingress port.", + "protocol": "protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", + "error": "error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", +} + +func (IngressPortStatus) SwaggerDoc() map[string]string { + return map_IngressPortStatus +} + var map_IngressRule = map[string]string{ "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", - "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nHost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", + "host": "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nhost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", } func (IngressRule) SwaggerDoc() map[string]string { @@ -141,10 +172,10 @@ func (IngressRuleValue) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "": "IngressSpec describes the Ingress the user wishes to exist.", - "ingressClassName": "IngressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated `kubernetes.io/ingress.class` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.", - "backend": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", - "tls": "TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", - "rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", + "ingressClassName": "ingressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated `kubernetes.io/ingress.class` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.", + "backend": "backend is the default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", + "tls": "tls represents the TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", + "rules": "rules is a list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", } func (IngressSpec) SwaggerDoc() map[string]string { @@ -152,8 +183,8 @@ func (IngressSpec) SwaggerDoc() map[string]string { } var map_IngressStatus = map[string]string{ - "": "IngressStatus describe the current state of the Ingress.", - "loadBalancer": "LoadBalancer contains the current status of the load-balancer.", + "": "IngressStatus describes the current state of the Ingress.", + "loadBalancer": "loadBalancer contains the current status of the load-balancer.", } func (IngressStatus) SwaggerDoc() map[string]string { @@ -162,8 +193,8 @@ func (IngressStatus) SwaggerDoc() map[string]string { var map_IngressTLS = map[string]string{ "": "IngressTLS describes the transport layer security associated with an Ingress.", - "hosts": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", - "secretName": "SecretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", + "hosts": "hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", + "secretName": "secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", } func (IngressTLS) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go index 77259e368d6..005d64e7fd4 100644 --- a/vendor/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go @@ -266,6 +266,73 @@ func (in *IngressList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerIngress) DeepCopyInto(out *IngressLoadBalancerIngress) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]IngressPortStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerIngress. +func (in *IngressLoadBalancerIngress) DeepCopy() *IngressLoadBalancerIngress { + if in == nil { + return nil + } + out := new(IngressLoadBalancerIngress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressLoadBalancerStatus) DeepCopyInto(out *IngressLoadBalancerStatus) { + *out = *in + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = make([]IngressLoadBalancerIngress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressLoadBalancerStatus. +func (in *IngressLoadBalancerStatus) DeepCopy() *IngressLoadBalancerStatus { + if in == nil { + return nil + } + out := new(IngressLoadBalancerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressPortStatus) DeepCopyInto(out *IngressPortStatus) { + *out = *in + if in.Error != nil { + in, out := &in.Error, &out.Error + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressPortStatus. +func (in *IngressPortStatus) DeepCopy() *IngressPortStatus { + if in == nil { + return nil + } + out := new(IngressPortStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = *in diff --git a/vendor/k8s.io/api/node/v1/generated.proto b/vendor/k8s.io/api/node/v1/generated.proto index 294be85b624..0152d5e3aba 100644 --- a/vendor/k8s.io/api/node/v1/generated.proto +++ b/vendor/k8s.io/api/node/v1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -61,13 +61,13 @@ message RuntimeClass { // and is immutable. optional string handler = 2; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ // +optional optional Overhead overhead = 3; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -82,7 +82,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } diff --git a/vendor/k8s.io/api/node/v1/types.go b/vendor/k8s.io/api/node/v1/types.go index 984696d9837..b00f58772cd 100644 --- a/vendor/k8s.io/api/node/v1/types.go +++ b/vendor/k8s.io/api/node/v1/types.go @@ -34,11 +34,12 @@ import ( // https://kubernetes.io/docs/concepts/containers/runtime-class/ type RuntimeClass struct { metav1.TypeMeta `json:",inline"` + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -50,13 +51,13 @@ type RuntimeClass struct { // and is immutable. Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,3,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -66,7 +67,7 @@ type RuntimeClass struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -96,11 +97,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go index a9eddc60ea3..f5e6b327794 100644 --- a/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,9 +39,9 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://kubernetes.io/docs/concepts/containers/runtime-class/", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see\n https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "handler": "handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see\n https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -51,7 +51,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/node/v1alpha1/generated.proto b/vendor/k8s.io/api/node/v1alpha1/generated.proto index d46e0ec6aa1..4673e9261d8 100644 --- a/vendor/k8s.io/api/node/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/node/v1alpha1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1alpha1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the RuntimeClass + // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status optional RuntimeClassSpec spec = 2; } @@ -61,7 +61,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } @@ -70,7 +70,7 @@ message RuntimeClassList { // Interface (CRI) implementation, as well as any other components that need to // understand how the pod will be run. The RuntimeClassSpec is immutable. message RuntimeClassSpec { - // RuntimeHandler specifies the underlying runtime and configuration that the + // runtimeHandler specifies the underlying runtime and configuration that the // CRI implementation will use to handle pods of this class. The possible // values are specific to the node & CRI configuration. It is assumed that // all handlers are available on every node, and handlers of the same name are @@ -78,17 +78,17 @@ message RuntimeClassSpec { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) + // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. optional string runtimeHandler = 1; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional optional Overhead overhead = 2; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. diff --git a/vendor/k8s.io/api/node/v1alpha1/types.go b/vendor/k8s.io/api/node/v1alpha1/types.go index 588c8e4c0a7..bf9e284bf73 100644 --- a/vendor/k8s.io/api/node/v1alpha1/types.go +++ b/vendor/k8s.io/api/node/v1alpha1/types.go @@ -34,11 +34,12 @@ import ( // https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class type RuntimeClass struct { metav1.TypeMeta `json:",inline"` + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the RuntimeClass + // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status Spec RuntimeClassSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -48,7 +49,7 @@ type RuntimeClass struct { // Interface (CRI) implementation, as well as any other components that need to // understand how the pod will be run. The RuntimeClassSpec is immutable. type RuntimeClassSpec struct { - // RuntimeHandler specifies the underlying runtime and configuration that the + // runtimeHandler specifies the underlying runtime and configuration that the // CRI implementation will use to handle pods of this class. The possible // values are specific to the node & CRI configuration. It is assumed that // all handlers are available on every node, and handlers of the same name are @@ -56,17 +57,17 @@ type RuntimeClassSpec struct { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) + // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. RuntimeHandler string `json:"runtimeHandler" protobuf:"bytes,1,opt,name=runtimeHandler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,2,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -76,7 +77,7 @@ type RuntimeClassSpec struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -106,11 +107,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go index 96413754f05..ccc1b708539 100644 --- a/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,7 +39,7 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec represents specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -49,7 +49,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { @@ -58,9 +58,9 @@ func (RuntimeClassList) SwaggerDoc() map[string]string { var map_RuntimeClassSpec = map[string]string{ "": "RuntimeClassSpec is a specification of a RuntimeClass. It contains parameters that are required to describe the RuntimeClass to the Container Runtime Interface (CRI) implementation, as well as any other components that need to understand how the pod will be run. The RuntimeClassSpec is immutable.", - "runtimeHandler": "RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "runtimeHandler": "runtimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClassSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/node/v1beta1/generated.proto b/vendor/k8s.io/api/node/v1beta1/generated.proto index 8ffad697314..54dbc0995ac 100644 --- a/vendor/k8s.io/api/node/v1beta1/generated.proto +++ b/vendor/k8s.io/api/node/v1beta1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1beta1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -57,17 +57,17 @@ message RuntimeClass { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, + // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. optional string handler = 2; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional optional Overhead overhead = 3; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -82,7 +82,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } diff --git a/vendor/k8s.io/api/node/v1beta1/types.go b/vendor/k8s.io/api/node/v1beta1/types.go index b924cb421ad..74ecca26ad4 100644 --- a/vendor/k8s.io/api/node/v1beta1/types.go +++ b/vendor/k8s.io/api/node/v1beta1/types.go @@ -36,11 +36,12 @@ import ( // https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class type RuntimeClass struct { metav1.TypeMeta `json:",inline"` + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -48,17 +49,17 @@ type RuntimeClass struct { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, + // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,3,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -68,7 +69,7 @@ type RuntimeClass struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -100,11 +101,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go index fec4398b2e7..086105ecc5f 100644 --- a/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,9 +39,9 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "handler": "handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -51,7 +51,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/policy/v1/generated.pb.go b/vendor/k8s.io/api/policy/v1/generated.pb.go index cba6ca4bbd6..d7e467a9215 100644 --- a/vendor/k8s.io/api/policy/v1/generated.pb.go +++ b/vendor/k8s.io/api/policy/v1/generated.pb.go @@ -201,58 +201,61 @@ func init() { } var fileDescriptor_2d50488813b2d18e = []byte{ - // 808 bytes of a gzipped FileDescriptorProto + // 854 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0xcf, 0x8f, 0xdb, 0x44, - 0x14, 0xc7, 0xe3, 0xcd, 0x66, 0x59, 0xa6, 0x49, 0xb4, 0x0c, 0x0b, 0x2c, 0x39, 0x38, 0x28, 0xa7, - 0x82, 0xd4, 0x31, 0xdb, 0x22, 0xb4, 0xaa, 0x04, 0xa2, 0x6e, 0x56, 0x50, 0xd4, 0x25, 0xd5, 0x2c, - 0x08, 0x09, 0x81, 0xc4, 0xc4, 0x7e, 0xcd, 0x0e, 0xb1, 0x3d, 0xd6, 0xcc, 0x38, 0x34, 0x27, 0xf8, - 0x13, 0xf8, 0x17, 0xf8, 0x53, 0x38, 0xb1, 0x27, 0xd4, 0x63, 0xc5, 0x21, 0x62, 0xcd, 0x3f, 0x82, - 0x3c, 0x76, 0x7e, 0x38, 0xf1, 0xaa, 0x59, 0x0e, 0xbd, 0x79, 0xde, 0x7b, 0xdf, 0xcf, 0x9b, 0xf7, - 0xe6, 0xcd, 0xc8, 0xe8, 0x93, 0xf1, 0x89, 0x22, 0x5c, 0x38, 0xe3, 0x64, 0x08, 0x32, 0x02, 0x0d, - 0xca, 0x99, 0x40, 0xe4, 0x0b, 0xe9, 0x14, 0x0e, 0x16, 0x73, 0x27, 0x16, 0x01, 0xf7, 0xa6, 0xce, - 0xe4, 0xd8, 0x19, 0x41, 0x04, 0x92, 0x69, 0xf0, 0x49, 0x2c, 0x85, 0x16, 0xf8, 0x30, 0x8f, 0x22, - 0x2c, 0xe6, 0x24, 0x8f, 0x22, 0x93, 0xe3, 0xce, 0x9d, 0x11, 0xd7, 0x17, 0xc9, 0x90, 0x78, 0x22, - 0x74, 0x46, 0x62, 0x24, 0x1c, 0x13, 0x3c, 0x4c, 0x9e, 0x9a, 0x95, 0x59, 0x98, 0xaf, 0x1c, 0xd2, - 0xf9, 0x68, 0x99, 0x2a, 0x64, 0xde, 0x05, 0x8f, 0x40, 0x4e, 0x9d, 0x78, 0x3c, 0xca, 0x0c, 0xca, - 0x09, 0x41, 0xb3, 0x8a, 0xd4, 0x1d, 0xe7, 0x3a, 0x95, 0x4c, 0x22, 0xcd, 0x43, 0xd8, 0x10, 0x7c, - 0xfc, 0x32, 0x81, 0xf2, 0x2e, 0x20, 0x64, 0x1b, 0xba, 0x7b, 0xd7, 0xe9, 0x12, 0xcd, 0x03, 0x87, - 0x47, 0x5a, 0x69, 0xb9, 0x2e, 0xea, 0xfd, 0x6d, 0xa1, 0xfd, 0xd3, 0x09, 0xf7, 0x34, 0x17, 0x11, - 0xfe, 0x11, 0xed, 0x67, 0x55, 0xf8, 0x4c, 0xb3, 0x23, 0xeb, 0x3d, 0xeb, 0xf6, 0xad, 0xbb, 0x1f, - 0x92, 0x65, 0xe3, 0x16, 0x50, 0x12, 0x8f, 0x47, 0x99, 0x41, 0x91, 0x2c, 0x9a, 0x4c, 0x8e, 0xc9, - 0x60, 0xf8, 0x13, 0x78, 0xfa, 0x0c, 0x34, 0x73, 0xf1, 0xe5, 0xac, 0x5b, 0x4b, 0x67, 0x5d, 0xb4, - 0xb4, 0xd1, 0x05, 0x15, 0x07, 0xa8, 0xe5, 0x43, 0x00, 0x1a, 0x06, 0x71, 0x96, 0x51, 0x1d, 0xed, - 0x98, 0x34, 0xf7, 0xb6, 0x4b, 0xd3, 0x5f, 0x95, 0xba, 0x6f, 0xa4, 0xb3, 0x6e, 0xab, 0x64, 0xa2, - 0x65, 0x78, 0xef, 0xf7, 0x1d, 0xf4, 0xe6, 0x13, 0xe1, 0xf7, 0xb9, 0x92, 0x89, 0x31, 0xb9, 0x89, - 0x3f, 0x02, 0xfd, 0x0a, 0xea, 0x1c, 0xa0, 0x5d, 0x15, 0x83, 0x57, 0x94, 0x77, 0x87, 0x54, 0x8d, - 0x1f, 0xa9, 0xd8, 0xda, 0x79, 0x0c, 0x9e, 0xdb, 0x2c, 0xd0, 0xbb, 0xd9, 0x8a, 0x1a, 0x10, 0xfe, - 0x16, 0xed, 0x29, 0xcd, 0x74, 0xa2, 0x8e, 0xea, 0x06, 0xe9, 0x6c, 0x8f, 0x34, 0x32, 0xb7, 0x5d, - 0x40, 0xf7, 0xf2, 0x35, 0x2d, 0x70, 0xbd, 0x3f, 0x2d, 0xf4, 0x4e, 0x85, 0xea, 0x31, 0x57, 0x1a, - 0x7f, 0xbf, 0xd1, 0x27, 0xb2, 0x5d, 0x9f, 0x32, 0xb5, 0xe9, 0xd2, 0x41, 0x91, 0x75, 0x7f, 0x6e, - 0x59, 0xe9, 0xd1, 0x57, 0xa8, 0xc1, 0x35, 0x84, 0xd9, 0x0c, 0xd4, 0x6f, 0xdf, 0xba, 0xfb, 0xfe, - 0xd6, 0x15, 0xb9, 0xad, 0x82, 0xda, 0x78, 0x94, 0xe9, 0x69, 0x8e, 0xe9, 0xfd, 0xb5, 0x53, 0x59, - 0x49, 0xd6, 0x44, 0xfc, 0x14, 0x35, 0x43, 0x1e, 0x3d, 0x98, 0x30, 0x1e, 0xb0, 0x61, 0x00, 0x2f, - 0x3d, 0xf5, 0xec, 0xca, 0x90, 0xfc, 0xca, 0x90, 0x47, 0x91, 0x1e, 0xc8, 0x73, 0x2d, 0x79, 0x34, - 0x72, 0x0f, 0xd2, 0x59, 0xb7, 0x79, 0xb6, 0x42, 0xa2, 0x25, 0x2e, 0xfe, 0x01, 0xed, 0x2b, 0x08, - 0xc0, 0xd3, 0x42, 0xde, 0x6c, 0xb4, 0x1f, 0xb3, 0x21, 0x04, 0xe7, 0x85, 0xd4, 0x6d, 0x66, 0x2d, - 0x9b, 0xaf, 0xe8, 0x02, 0x89, 0x03, 0xd4, 0x0e, 0xd9, 0xb3, 0x6f, 0x22, 0xb6, 0x28, 0xa4, 0xfe, - 0x3f, 0x0b, 0xc1, 0xe9, 0xac, 0xdb, 0x3e, 0x2b, 0xb1, 0xe8, 0x1a, 0xbb, 0xf7, 0x47, 0x03, 0xbd, - 0x7b, 0xed, 0x40, 0xe1, 0x2f, 0x11, 0x16, 0x43, 0x05, 0x72, 0x02, 0xfe, 0xe7, 0xf9, 0xa3, 0xc2, - 0x45, 0x64, 0x1a, 0x5b, 0x77, 0x3b, 0xc5, 0x01, 0xe1, 0xc1, 0x46, 0x04, 0xad, 0x50, 0xe1, 0x5f, - 0x50, 0xcb, 0xcf, 0xb3, 0x80, 0xff, 0x44, 0xf8, 0xf3, 0x91, 0x70, 0x6f, 0x38, 0xe4, 0xa4, 0xbf, - 0x0a, 0x39, 0x8d, 0xb4, 0x9c, 0xba, 0x6f, 0x15, 0x5b, 0x69, 0x95, 0x7c, 0xb4, 0x9c, 0x2f, 0x2b, - 0xc6, 0x5f, 0x20, 0xd5, 0x83, 0x20, 0x10, 0x3f, 0x83, 0x6f, 0x9a, 0xdb, 0x58, 0x16, 0xd3, 0xdf, - 0x88, 0xa0, 0x15, 0x2a, 0xfc, 0x29, 0x6a, 0x7b, 0x89, 0x94, 0x10, 0xe9, 0x2f, 0x80, 0x05, 0xfa, - 0x62, 0x7a, 0xb4, 0x6b, 0x38, 0x6f, 0x17, 0x9c, 0xf6, 0xc3, 0x92, 0x97, 0xae, 0x45, 0x67, 0x7a, - 0x1f, 0x14, 0x97, 0xe0, 0xcf, 0xf5, 0x8d, 0xb2, 0xbe, 0x5f, 0xf2, 0xd2, 0xb5, 0x68, 0x7c, 0x82, - 0x9a, 0xf0, 0x2c, 0x06, 0x6f, 0xde, 0xcb, 0x3d, 0xa3, 0x3e, 0x2c, 0xd4, 0xcd, 0xd3, 0x15, 0x1f, - 0x2d, 0x45, 0x62, 0x0f, 0x21, 0x4f, 0x44, 0x3e, 0xcf, 0x9f, 0xe6, 0xd7, 0xcc, 0x19, 0x38, 0xdb, - 0xcd, 0xef, 0xc3, 0xb9, 0x6e, 0xf9, 0x30, 0x2e, 0x4c, 0x8a, 0xae, 0x60, 0x3b, 0x01, 0xc2, 0x9b, - 0xc7, 0x84, 0x0f, 0x50, 0x7d, 0x0c, 0x53, 0x33, 0x3e, 0xaf, 0xd3, 0xec, 0x13, 0x7f, 0x86, 0x1a, - 0x13, 0x16, 0x24, 0x50, 0xdc, 0xa3, 0x0f, 0xb6, 0xdb, 0xc7, 0xd7, 0x3c, 0x04, 0x9a, 0x0b, 0xef, - 0xef, 0x9c, 0x58, 0xee, 0xfd, 0xcb, 0x2b, 0xbb, 0xf6, 0xfc, 0xca, 0xae, 0xbd, 0xb8, 0xb2, 0x6b, - 0xbf, 0xa6, 0xb6, 0x75, 0x99, 0xda, 0xd6, 0xf3, 0xd4, 0xb6, 0x5e, 0xa4, 0xb6, 0xf5, 0x4f, 0x6a, - 0x5b, 0xbf, 0xfd, 0x6b, 0xd7, 0xbe, 0x3b, 0xac, 0xfa, 0x89, 0xf8, 0x2f, 0x00, 0x00, 0xff, 0xff, - 0x8d, 0x9b, 0x69, 0xee, 0x74, 0x08, 0x00, 0x00, + 0x14, 0xc7, 0xe3, 0xcd, 0x66, 0xd9, 0x4e, 0x93, 0x68, 0x19, 0x16, 0x58, 0x72, 0x70, 0xaa, 0x9c, + 0x16, 0xa4, 0x8e, 0xd9, 0x16, 0xa1, 0x55, 0x25, 0x50, 0xeb, 0x66, 0x05, 0x45, 0x5d, 0xb2, 0x9a, + 0x6d, 0x85, 0x84, 0x40, 0x62, 0x62, 0xbf, 0x26, 0x43, 0x6c, 0x8f, 0xe5, 0x19, 0x87, 0xe6, 0x44, + 0xff, 0x04, 0xfe, 0x05, 0xfe, 0x14, 0x4e, 0xec, 0xb1, 0xdc, 0x2a, 0x0e, 0x11, 0x6b, 0xfe, 0x0b, + 0x4e, 0xc8, 0x63, 0xe7, 0x87, 0x37, 0x0e, 0xcd, 0x72, 0xe8, 0xcd, 0xf3, 0xde, 0xfb, 0x7e, 0x9e, + 0xdf, 0x8f, 0x71, 0x82, 0x3e, 0x1b, 0x1d, 0x4b, 0xc2, 0x85, 0x35, 0x8a, 0xfb, 0x10, 0x05, 0xa0, + 0x40, 0x5a, 0x63, 0x08, 0x5c, 0x11, 0x59, 0xb9, 0x83, 0x85, 0xdc, 0x0a, 0x85, 0xc7, 0x9d, 0x89, + 0x35, 0x3e, 0xb2, 0x06, 0x10, 0x40, 0xc4, 0x14, 0xb8, 0x24, 0x8c, 0x84, 0x12, 0x78, 0x3f, 0x8b, + 0x22, 0x2c, 0xe4, 0x24, 0x8b, 0x22, 0xe3, 0xa3, 0xd6, 0xed, 0x01, 0x57, 0xc3, 0xb8, 0x4f, 0x1c, + 0xe1, 0x5b, 0x03, 0x31, 0x10, 0x96, 0x0e, 0xee, 0xc7, 0xcf, 0xf4, 0x49, 0x1f, 0xf4, 0x53, 0x06, + 0x69, 0x7d, 0xb2, 0x48, 0xe5, 0x33, 0x67, 0xc8, 0x03, 0x88, 0x26, 0x56, 0x38, 0x1a, 0xa4, 0x06, + 0x69, 0xf9, 0xa0, 0x58, 0x49, 0xea, 0x96, 0xb5, 0x4e, 0x15, 0xc5, 0x81, 0xe2, 0x3e, 0xac, 0x08, + 0x3e, 0x7d, 0x9d, 0x40, 0x3a, 0x43, 0xf0, 0xd9, 0x8a, 0xee, 0xee, 0x3a, 0x5d, 0xac, 0xb8, 0x67, + 0xf1, 0x40, 0x49, 0x15, 0x5d, 0x15, 0x75, 0xfe, 0x34, 0xd0, 0xee, 0xc9, 0x98, 0x3b, 0x8a, 0x8b, + 0x00, 0xff, 0x80, 0x76, 0xd3, 0x2a, 0x5c, 0xa6, 0xd8, 0x81, 0x71, 0xcb, 0x38, 0xbc, 0x79, 0xe7, + 0x63, 0xb2, 0x68, 0xdc, 0x1c, 0x4a, 0xc2, 0xd1, 0x20, 0x35, 0x48, 0x92, 0x46, 0x93, 0xf1, 0x11, + 0xe9, 0xf5, 0x7f, 0x04, 0x47, 0x9d, 0x82, 0x62, 0x36, 0xbe, 0x98, 0xb6, 0x2b, 0xc9, 0xb4, 0x8d, + 0x16, 0x36, 0x3a, 0xa7, 0x62, 0x0f, 0x35, 0x5c, 0xf0, 0x40, 0x41, 0x2f, 0x4c, 0x33, 0xca, 0x83, + 0x2d, 0x9d, 0xe6, 0xee, 0x66, 0x69, 0xba, 0xcb, 0x52, 0xfb, 0xed, 0x64, 0xda, 0x6e, 0x14, 0x4c, + 0xb4, 0x08, 0xef, 0xfc, 0xba, 0x85, 0xde, 0x39, 0x13, 0x6e, 0x97, 0xcb, 0x28, 0xd6, 0x26, 0x3b, + 0x76, 0x07, 0xa0, 0xde, 0x40, 0x9d, 0x3d, 0xb4, 0x2d, 0x43, 0x70, 0xf2, 0xf2, 0x6e, 0x93, 0xb2, + 0xf5, 0x23, 0x25, 0xaf, 0x76, 0x1e, 0x82, 0x63, 0xd7, 0x73, 0xf4, 0x76, 0x7a, 0xa2, 0x1a, 0x84, + 0xbf, 0x41, 0x3b, 0x52, 0x31, 0x15, 0xcb, 0x83, 0xaa, 0x46, 0x5a, 0x9b, 0x23, 0xb5, 0xcc, 0x6e, + 0xe6, 0xd0, 0x9d, 0xec, 0x4c, 0x73, 0x5c, 0xe7, 0x77, 0x03, 0xbd, 0x5f, 0xa2, 0x7a, 0xcc, 0xa5, + 0xc2, 0xdf, 0xad, 0xf4, 0x89, 0x6c, 0xd6, 0xa7, 0x54, 0xad, 0xbb, 0xb4, 0x97, 0x67, 0xdd, 0x9d, + 0x59, 0x96, 0x7a, 0xf4, 0x35, 0xaa, 0x71, 0x05, 0x7e, 0xba, 0x03, 0xd5, 0xc3, 0x9b, 0x77, 0x3e, + 0xdc, 0xb8, 0x22, 0xbb, 0x91, 0x53, 0x6b, 0x8f, 0x52, 0x3d, 0xcd, 0x30, 0x9d, 0x3f, 0xaa, 0xa5, + 0x95, 0xa4, 0x4d, 0xc4, 0xcf, 0x50, 0xdd, 0xe7, 0xc1, 0x83, 0x31, 0xe3, 0x1e, 0xeb, 0x7b, 0xf0, + 0xda, 0xa9, 0xa7, 0x57, 0x86, 0x64, 0x57, 0x86, 0x3c, 0x0a, 0x54, 0x2f, 0x3a, 0x57, 0x11, 0x0f, + 0x06, 0xf6, 0x5e, 0x32, 0x6d, 0xd7, 0x4f, 0x97, 0x48, 0xb4, 0xc0, 0xc5, 0xdf, 0xa3, 0x5d, 0x09, + 0x1e, 0x38, 0x4a, 0x44, 0xd7, 0x5b, 0xed, 0xc7, 0xac, 0x0f, 0xde, 0x79, 0x2e, 0xb5, 0xeb, 0x69, + 0xcb, 0x66, 0x27, 0x3a, 0x47, 0x62, 0x0f, 0x35, 0x7d, 0xf6, 0xfc, 0x69, 0xc0, 0xe6, 0x85, 0x54, + 0xff, 0x67, 0x21, 0x38, 0x99, 0xb6, 0x9b, 0xa7, 0x05, 0x16, 0xbd, 0xc2, 0xc6, 0x2f, 0x0c, 0xd4, + 0x8a, 0x83, 0x21, 0x30, 0x4f, 0x0d, 0x27, 0x67, 0xc2, 0x9d, 0x7d, 0x27, 0xce, 0xf4, 0x70, 0x0e, + 0xb6, 0x6f, 0x19, 0x87, 0x37, 0xec, 0xfb, 0xc9, 0xb4, 0xdd, 0x7a, 0xba, 0x36, 0xea, 0x9f, 0x69, + 0xdb, 0x5c, 0xef, 0x7d, 0x32, 0x09, 0x81, 0xfe, 0x47, 0x8e, 0xce, 0x6f, 0x35, 0xf4, 0xc1, 0xda, + 0x9d, 0xc6, 0x5f, 0x21, 0x2c, 0xfa, 0x12, 0xa2, 0x31, 0xb8, 0x5f, 0x64, 0xdf, 0x35, 0x2e, 0x02, + 0x3d, 0xdb, 0xaa, 0xdd, 0xca, 0x77, 0x04, 0xf7, 0x56, 0x22, 0x68, 0x89, 0x0a, 0xff, 0x8c, 0x1a, + 0x6e, 0x96, 0x05, 0xdc, 0x33, 0xe1, 0xce, 0xb6, 0xd2, 0xbe, 0xe6, 0x3d, 0x23, 0xdd, 0x65, 0xc8, + 0x49, 0xa0, 0xa2, 0x89, 0xfd, 0x6e, 0xfe, 0x2a, 0x8d, 0x82, 0x8f, 0x16, 0xf3, 0xa5, 0xc5, 0xb8, + 0x73, 0xa4, 0x7c, 0xe0, 0x79, 0xe2, 0x27, 0x70, 0xf5, 0x7c, 0x6b, 0x8b, 0x62, 0xba, 0x2b, 0x11, + 0xb4, 0x44, 0x85, 0x3f, 0x47, 0x4d, 0x27, 0x8e, 0x22, 0x08, 0xd4, 0x97, 0x59, 0x67, 0xf5, 0xb0, + 0x6a, 0xf6, 0x7b, 0x39, 0xa7, 0xf9, 0xb0, 0xe0, 0xa5, 0x57, 0xa2, 0x53, 0xbd, 0x0b, 0x92, 0x47, + 0xe0, 0xce, 0xf4, 0xb5, 0xa2, 0xbe, 0x5b, 0xf0, 0xd2, 0x2b, 0xd1, 0xf8, 0x18, 0xd5, 0xe1, 0x79, + 0x08, 0xce, 0xac, 0x97, 0x3b, 0x5a, 0xbd, 0x9f, 0xab, 0xeb, 0x27, 0x4b, 0x3e, 0x5a, 0x88, 0xc4, + 0x0e, 0x42, 0x8e, 0x08, 0x5c, 0x9e, 0xfd, 0x3a, 0xbc, 0xa5, 0x67, 0x60, 0x6d, 0x76, 0x85, 0x1e, + 0xce, 0x74, 0x8b, 0x6f, 0xf3, 0xdc, 0x24, 0xe9, 0x12, 0xb6, 0xe5, 0x21, 0xbc, 0x3a, 0x26, 0xbc, + 0x87, 0xaa, 0x23, 0x98, 0xe8, 0xf5, 0xb9, 0x41, 0xd3, 0x47, 0x7c, 0x1f, 0xd5, 0xc6, 0xcc, 0x8b, + 0x21, 0xbf, 0xca, 0x1f, 0x6d, 0xf6, 0x1e, 0x4f, 0xb8, 0x0f, 0x34, 0x13, 0xde, 0xdb, 0x3a, 0x36, + 0xec, 0x7b, 0x17, 0x97, 0x66, 0xe5, 0xe5, 0xa5, 0x59, 0x79, 0x75, 0x69, 0x56, 0x5e, 0x24, 0xa6, + 0x71, 0x91, 0x98, 0xc6, 0xcb, 0xc4, 0x34, 0x5e, 0x25, 0xa6, 0xf1, 0x57, 0x62, 0x1a, 0xbf, 0xfc, + 0x6d, 0x56, 0xbe, 0xdd, 0x2f, 0xfb, 0x1f, 0xf3, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x79, 0xd7, + 0x99, 0xdb, 0xf7, 0x08, 0x00, 0x00, } func (m *Eviction) Marshal() (dAtA []byte, err error) { @@ -420,6 +423,13 @@ func (m *PodDisruptionBudgetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if m.UnhealthyPodEvictionPolicy != nil { + i -= len(*m.UnhealthyPodEvictionPolicy) + copy(dAtA[i:], *m.UnhealthyPodEvictionPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.UnhealthyPodEvictionPolicy))) + i-- + dAtA[i] = 0x22 + } if m.MaxUnavailable != nil { { size, err := m.MaxUnavailable.MarshalToSizedBuffer(dAtA[:i]) @@ -616,6 +626,10 @@ func (m *PodDisruptionBudgetSpec) Size() (n int) { l = m.MaxUnavailable.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.UnhealthyPodEvictionPolicy != nil { + l = len(*m.UnhealthyPodEvictionPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -701,6 +715,7 @@ func (this *PodDisruptionBudgetSpec) String() string { `MinAvailable:` + strings.Replace(fmt.Sprintf("%v", this.MinAvailable), "IntOrString", "intstr.IntOrString", 1) + `,`, `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, + `UnhealthyPodEvictionPolicy:` + valueToStringGenerated(this.UnhealthyPodEvictionPolicy) + `,`, `}`, }, "") return s @@ -1266,6 +1281,39 @@ func (m *PodDisruptionBudgetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnhealthyPodEvictionPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := UnhealthyPodEvictionPolicyType(dAtA[iNdEx:postIndex]) + m.UnhealthyPodEvictionPolicy = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/policy/v1/generated.proto b/vendor/k8s.io/api/policy/v1/generated.proto index 33bc72b86f3..a79e7102841 100644 --- a/vendor/k8s.io/api/policy/v1/generated.proto +++ b/vendor/k8s.io/api/policy/v1/generated.proto @@ -92,6 +92,34 @@ message PodDisruptionBudgetSpec { // by specifying 0. This is a mutually exclusive setting with "minAvailable". // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUnavailable = 3; + + // UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + // should be considered for eviction. Current implementation considers healthy pods, + // as pods that have status.conditions item with type="Ready",status="True". + // + // Valid policies are IfHealthyBudget and AlwaysAllow. + // If no policy is specified, the default behavior will be used, + // which corresponds to the IfHealthyBudget policy. + // + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + // + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + // + // Additional policies may be added in the future. + // Clients making eviction decisions should disallow eviction of unhealthy pods + // if they encounter an unrecognized policy in this field. + // + // This field is beta-level. The eviction API uses this field when + // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + // +optional + optional string unhealthyPodEvictionPolicy = 4; } // PodDisruptionBudgetStatus represents information about the status of a diff --git a/vendor/k8s.io/api/policy/v1/types.go b/vendor/k8s.io/api/policy/v1/types.go index 4a03696f000..45b9550f4a7 100644 --- a/vendor/k8s.io/api/policy/v1/types.go +++ b/vendor/k8s.io/api/policy/v1/types.go @@ -47,8 +47,56 @@ type PodDisruptionBudgetSpec struct { // by specifying 0. This is a mutually exclusive setting with "minAvailable". // +optional MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"` + + // UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + // should be considered for eviction. Current implementation considers healthy pods, + // as pods that have status.conditions item with type="Ready",status="True". + // + // Valid policies are IfHealthyBudget and AlwaysAllow. + // If no policy is specified, the default behavior will be used, + // which corresponds to the IfHealthyBudget policy. + // + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + // + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + // + // Additional policies may be added in the future. + // Clients making eviction decisions should disallow eviction of unhealthy pods + // if they encounter an unrecognized policy in this field. + // + // This field is beta-level. The eviction API uses this field when + // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + // +optional + UnhealthyPodEvictionPolicy *UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty" protobuf:"bytes,4,opt,name=unhealthyPodEvictionPolicy"` } +// UnhealthyPodEvictionPolicyType defines the criteria for when unhealthy pods +// should be considered for eviction. +// +enum +type UnhealthyPodEvictionPolicyType string + +const ( + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + IfHealthyBudget UnhealthyPodEvictionPolicyType = "IfHealthyBudget" + + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + AlwaysAllow UnhealthyPodEvictionPolicyType = "AlwaysAllow" +) + // PodDisruptionBudgetStatus represents information about the status of a // PodDisruptionBudget. Status may trail the actual state of a system. type PodDisruptionBudgetStatus struct { diff --git a/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go index 3208392e880..799b0794a97 100644 --- a/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Eviction = map[string]string{ @@ -59,10 +59,11 @@ func (PodDisruptionBudgetList) SwaggerDoc() map[string]string { } var map_PodDisruptionBudgetSpec = map[string]string{ - "": "PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.", - "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", - "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector will match no pods, while an empty ({}) selector will select all pods within the namespace.", - "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", + "": "PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.", + "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", + "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector will match no pods, while an empty ({}) selector will select all pods within the namespace.", + "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", + "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/policy/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/policy/v1/zz_generated.deepcopy.go index 485e1c93800..74b4f3a3aff 100644 --- a/vendor/k8s.io/api/policy/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/policy/v1/zz_generated.deepcopy.go @@ -137,6 +137,11 @@ func (in *PodDisruptionBudgetSpec) DeepCopyInto(out *PodDisruptionBudgetSpec) { *out = new(intstr.IntOrString) **out = **in } + if in.UnhealthyPodEvictionPolicy != nil { + in, out := &in.UnhealthyPodEvictionPolicy, &out.UnhealthyPodEvictionPolicy + *out = new(UnhealthyPodEvictionPolicyType) + **out = **in + } return } diff --git a/vendor/k8s.io/api/policy/v1beta1/generated.pb.go b/vendor/k8s.io/api/policy/v1beta1/generated.pb.go index d19c93b109a..0b75d641541 100644 --- a/vendor/k8s.io/api/policy/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/policy/v1beta1/generated.pb.go @@ -609,127 +609,129 @@ func init() { } var fileDescriptor_014060e454a820dc = []byte{ - // 1907 bytes of a gzipped FileDescriptorProto + // 1946 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x5b, 0x73, 0xdb, 0xc6, - 0xf5, 0x17, 0x4c, 0x5d, 0xa8, 0xd5, 0xc5, 0xe2, 0xea, 0x62, 0x48, 0xf9, 0x87, 0x70, 0x90, 0x99, - 0xff, 0xb8, 0x69, 0x0a, 0xc6, 0xb2, 0xe3, 0x7a, 0x9a, 0x5e, 0x22, 0x88, 0x92, 0xad, 0x8c, 0x65, - 0xb1, 0x4b, 0x3b, 0xd3, 0x76, 0xdc, 0x4e, 0x97, 0xc0, 0x8a, 0x42, 0x04, 0x02, 0x28, 0x76, 0xc1, - 0x88, 0x6f, 0x7d, 0xe8, 0x43, 0x1f, 0xfb, 0x05, 0x32, 0xfd, 0x00, 0x9d, 0x3e, 0xf5, 0x43, 0xd4, - 0x99, 0xe9, 0x64, 0xf2, 0x98, 0xe9, 0x03, 0xa7, 0x66, 0xbf, 0x85, 0x9f, 0x3a, 0x58, 0x2e, 0x40, - 0x5c, 0x49, 0x3b, 0x33, 0xf6, 0x1b, 0xb1, 0xe7, 0xf7, 0xfb, 0x9d, 0xdd, 0xb3, 0x67, 0xcf, 0x5e, - 0x08, 0xf4, 0xcb, 0xfb, 0x54, 0xb3, 0xdc, 0xc6, 0x65, 0xd0, 0x21, 0xbe, 0x43, 0x18, 0xa1, 0x8d, - 0x3e, 0x71, 0x4c, 0xd7, 0x6f, 0x08, 0x03, 0xf6, 0xac, 0x86, 0xe7, 0xda, 0x96, 0x31, 0x68, 0xf4, - 0x6f, 0x77, 0x08, 0xc3, 0xb7, 0x1b, 0x5d, 0xe2, 0x10, 0x1f, 0x33, 0x62, 0x6a, 0x9e, 0xef, 0x32, - 0x17, 0xee, 0x8e, 0xa1, 0x1a, 0xf6, 0x2c, 0x6d, 0x0c, 0xd5, 0x04, 0x74, 0xef, 0x47, 0x5d, 0x8b, - 0x5d, 0x04, 0x1d, 0xcd, 0x70, 0x7b, 0x8d, 0xae, 0xdb, 0x75, 0x1b, 0x9c, 0xd1, 0x09, 0xce, 0xf9, - 0x17, 0xff, 0xe0, 0xbf, 0xc6, 0x4a, 0x7b, 0x6a, 0xc2, 0xa9, 0xe1, 0xfa, 0xa4, 0xd1, 0xcf, 0x79, - 0xdb, 0xbb, 0x3b, 0xc1, 0xf4, 0xb0, 0x71, 0x61, 0x39, 0xc4, 0x1f, 0x34, 0xbc, 0xcb, 0x6e, 0xd8, - 0x40, 0x1b, 0x3d, 0xc2, 0x70, 0x11, 0xab, 0x51, 0xc6, 0xf2, 0x03, 0x87, 0x59, 0x3d, 0x92, 0x23, - 0xdc, 0x9b, 0x45, 0xa0, 0xc6, 0x05, 0xe9, 0xe1, 0x1c, 0xef, 0x4e, 0x19, 0x2f, 0x60, 0x96, 0xdd, - 0xb0, 0x1c, 0x46, 0x99, 0x9f, 0x25, 0xa9, 0x77, 0xc1, 0xc6, 0x81, 0x6d, 0xbb, 0x5f, 0x12, 0xf3, - 0xb0, 0x7d, 0xd2, 0xf4, 0xad, 0x3e, 0xf1, 0xe1, 0x4d, 0x30, 0xef, 0xe0, 0x1e, 0x91, 0xa5, 0x9b, - 0xd2, 0xad, 0x65, 0x7d, 0xf5, 0xf9, 0x50, 0x99, 0x1b, 0x0d, 0x95, 0xf9, 0xc7, 0xb8, 0x47, 0x10, - 0xb7, 0xa8, 0x9f, 0x80, 0x9a, 0x60, 0x1d, 0xdb, 0xe4, 0xea, 0x73, 0xd7, 0x0e, 0x7a, 0x04, 0xfe, - 0x3f, 0x58, 0x34, 0xb9, 0x80, 0x20, 0xae, 0x0b, 0xe2, 0xe2, 0x58, 0x16, 0x09, 0xab, 0x4a, 0xc1, - 0x75, 0x41, 0x7e, 0xe8, 0x52, 0xd6, 0xc2, 0xec, 0x02, 0xee, 0x03, 0xe0, 0x61, 0x76, 0xd1, 0xf2, - 0xc9, 0xb9, 0x75, 0x25, 0xe8, 0x50, 0xd0, 0x41, 0x2b, 0xb6, 0xa0, 0x04, 0x0a, 0x7e, 0x08, 0xaa, - 0x3e, 0xc1, 0xe6, 0x99, 0x63, 0x0f, 0xe4, 0x6b, 0x37, 0xa5, 0x5b, 0x55, 0x7d, 0x43, 0x30, 0xaa, - 0x48, 0xb4, 0xa3, 0x18, 0xa1, 0xfe, 0x5b, 0x02, 0xd5, 0xa3, 0xbe, 0x65, 0x30, 0xcb, 0x75, 0xe0, - 0xef, 0x41, 0x35, 0x9c, 0x2d, 0x13, 0x33, 0xcc, 0x9d, 0xad, 0xec, 0x7f, 0xa4, 0x4d, 0x32, 0x29, - 0x0e, 0x9e, 0xe6, 0x5d, 0x76, 0xc3, 0x06, 0xaa, 0x85, 0x68, 0xad, 0x7f, 0x5b, 0x3b, 0xeb, 0x7c, - 0x41, 0x0c, 0x76, 0x4a, 0x18, 0x9e, 0x74, 0x6f, 0xd2, 0x86, 0x62, 0x55, 0x68, 0x83, 0x35, 0x93, - 0xd8, 0x84, 0x91, 0x33, 0x2f, 0xf4, 0x48, 0x79, 0x0f, 0x57, 0xf6, 0xef, 0xbc, 0x9a, 0x9b, 0x66, - 0x92, 0xaa, 0xd7, 0x46, 0x43, 0x65, 0x2d, 0xd5, 0x84, 0xd2, 0xe2, 0xea, 0x57, 0x12, 0xd8, 0x39, - 0x6e, 0x3f, 0xf0, 0xdd, 0xc0, 0x6b, 0xb3, 0x70, 0x76, 0xbb, 0x03, 0x61, 0x82, 0x3f, 0x06, 0xf3, - 0x7e, 0x60, 0x47, 0x73, 0xf9, 0x7e, 0x34, 0x97, 0x28, 0xb0, 0xc9, 0xcb, 0xa1, 0xb2, 0x99, 0x61, - 0x3d, 0x19, 0x78, 0x04, 0x71, 0x02, 0xfc, 0x0c, 0x2c, 0xfa, 0xd8, 0xe9, 0x92, 0xb0, 0xeb, 0x95, - 0x5b, 0x2b, 0xfb, 0xaa, 0x56, 0xba, 0xd6, 0xb4, 0x93, 0x26, 0x0a, 0xa1, 0x93, 0x19, 0xe7, 0x9f, - 0x14, 0x09, 0x05, 0xf5, 0x14, 0xac, 0xf1, 0xa9, 0x76, 0x7d, 0xc6, 0x2d, 0xf0, 0x5d, 0x50, 0xe9, - 0x59, 0x0e, 0xef, 0xd4, 0x82, 0xbe, 0x22, 0x58, 0x95, 0x53, 0xcb, 0x41, 0x61, 0x3b, 0x37, 0xe3, - 0x2b, 0x1e, 0xb3, 0xa4, 0x19, 0x5f, 0xa1, 0xb0, 0x5d, 0x7d, 0x00, 0x96, 0x84, 0xc7, 0xa4, 0x50, - 0x65, 0xba, 0x50, 0xa5, 0x40, 0xe8, 0x6f, 0xd7, 0xc0, 0x66, 0xcb, 0x35, 0x9b, 0x16, 0xf5, 0x03, - 0x1e, 0x2f, 0x3d, 0x30, 0xbb, 0x84, 0xbd, 0x85, 0xfc, 0x78, 0x02, 0xe6, 0xa9, 0x47, 0x0c, 0x91, - 0x16, 0xfb, 0x53, 0x62, 0x5b, 0xd0, 0xbf, 0xb6, 0x47, 0x8c, 0xc9, 0xb2, 0x0c, 0xbf, 0x10, 0x57, - 0x83, 0xcf, 0xc0, 0x22, 0x65, 0x98, 0x05, 0x54, 0xae, 0x70, 0xdd, 0xbb, 0xaf, 0xa9, 0xcb, 0xb9, - 0x93, 0x59, 0x1c, 0x7f, 0x23, 0xa1, 0xa9, 0xfe, 0x4b, 0x02, 0x37, 0x0a, 0x58, 0x8f, 0x2c, 0xca, - 0xe0, 0xb3, 0x5c, 0xc4, 0xb4, 0x57, 0x8b, 0x58, 0xc8, 0xe6, 0xf1, 0x8a, 0x17, 0x6f, 0xd4, 0x92, - 0x88, 0x56, 0x1b, 0x2c, 0x58, 0x8c, 0xf4, 0xa2, 0x54, 0xd4, 0x5e, 0x6f, 0x58, 0xfa, 0x9a, 0x90, - 0x5e, 0x38, 0x09, 0x45, 0xd0, 0x58, 0x4b, 0xfd, 0xe6, 0x5a, 0xe1, 0x70, 0xc2, 0x70, 0xc2, 0x73, - 0xb0, 0xda, 0xb3, 0x9c, 0x83, 0x3e, 0xb6, 0x6c, 0xdc, 0x11, 0xab, 0x67, 0x5a, 0x12, 0x84, 0x15, - 0x56, 0x1b, 0x57, 0x58, 0xed, 0xc4, 0x61, 0x67, 0x7e, 0x9b, 0xf9, 0x96, 0xd3, 0xd5, 0x37, 0x46, - 0x43, 0x65, 0xf5, 0x34, 0xa1, 0x84, 0x52, 0xba, 0xf0, 0xb7, 0xa0, 0x4a, 0x89, 0x4d, 0x0c, 0xe6, - 0xfa, 0xaf, 0x57, 0x21, 0x1e, 0xe1, 0x0e, 0xb1, 0xdb, 0x82, 0xaa, 0xaf, 0x86, 0x71, 0x8b, 0xbe, - 0x50, 0x2c, 0x09, 0x6d, 0xb0, 0xde, 0xc3, 0x57, 0x4f, 0x1d, 0x1c, 0x0f, 0xa4, 0xf2, 0x3d, 0x07, - 0x02, 0x47, 0x43, 0x65, 0xfd, 0x34, 0xa5, 0x85, 0x32, 0xda, 0xea, 0x3f, 0x17, 0xc0, 0x6e, 0x69, - 0x56, 0xc1, 0xcf, 0x00, 0x74, 0x3b, 0x94, 0xf8, 0x7d, 0x62, 0x3e, 0x18, 0xef, 0x41, 0x96, 0x1b, - 0x2d, 0xdc, 0x3d, 0x31, 0x41, 0xf0, 0x2c, 0x87, 0x40, 0x05, 0x2c, 0xf8, 0x27, 0x09, 0xac, 0x99, - 0x63, 0x37, 0xc4, 0x6c, 0xb9, 0x66, 0x94, 0x18, 0x0f, 0xbe, 0x4f, 0xbe, 0x6b, 0xcd, 0xa4, 0xd2, - 0x91, 0xc3, 0xfc, 0x81, 0xbe, 0x2d, 0x3a, 0xb4, 0x96, 0xb2, 0xa1, 0xb4, 0xd3, 0x70, 0x48, 0x66, - 0x2c, 0x49, 0xc5, 0x9e, 0xc6, 0x43, 0xbc, 0x30, 0x19, 0x52, 0x33, 0x87, 0x40, 0x05, 0x2c, 0xf8, - 0x73, 0xb0, 0x6e, 0x04, 0xbe, 0x4f, 0x1c, 0xf6, 0x90, 0x60, 0x9b, 0x5d, 0x0c, 0xe4, 0x79, 0xae, - 0xb3, 0x23, 0x74, 0xd6, 0x0f, 0x53, 0x56, 0x94, 0x41, 0x87, 0x7c, 0x93, 0x50, 0xcb, 0x27, 0x66, - 0xc4, 0x5f, 0x48, 0xf3, 0x9b, 0x29, 0x2b, 0xca, 0xa0, 0xe1, 0x7d, 0xb0, 0x4a, 0xae, 0x3c, 0x62, - 0x44, 0x01, 0x5d, 0xe4, 0xec, 0x2d, 0xc1, 0x5e, 0x3d, 0x4a, 0xd8, 0x50, 0x0a, 0x09, 0x0d, 0x00, - 0x0c, 0xd7, 0x31, 0xad, 0xf1, 0x3e, 0xb7, 0xc4, 0x27, 0xa2, 0xf1, 0x6a, 0x59, 0x7c, 0x18, 0xf1, - 0x26, 0xd5, 0x32, 0x6e, 0xa2, 0x28, 0x21, 0xbb, 0x67, 0x03, 0x98, 0x9f, 0x26, 0xb8, 0x01, 0x2a, - 0x97, 0x64, 0x30, 0xde, 0xdb, 0x50, 0xf8, 0x13, 0x7e, 0x0a, 0x16, 0xfa, 0xd8, 0x0e, 0x88, 0x58, - 0x4d, 0x1f, 0xbc, 0x5a, 0x3f, 0x9e, 0x58, 0x3d, 0x82, 0xc6, 0xc4, 0x9f, 0x5c, 0xbb, 0x2f, 0xa9, - 0x5f, 0x4b, 0xa0, 0xd6, 0x72, 0xcd, 0x36, 0x31, 0x02, 0xdf, 0x62, 0x83, 0x16, 0xcf, 0xa4, 0xb7, - 0xb0, 0x2b, 0xa0, 0xd4, 0xae, 0xf0, 0xd1, 0xf4, 0x6c, 0x4e, 0xf7, 0xae, 0x6c, 0x4f, 0x50, 0x9f, - 0x4b, 0x60, 0x3b, 0x87, 0x7e, 0x0b, 0x35, 0xfb, 0x97, 0xe9, 0x9a, 0xfd, 0xe1, 0xeb, 0x0c, 0xa6, - 0xa4, 0x62, 0x7f, 0x5d, 0x2b, 0x18, 0x0a, 0xaf, 0xd7, 0xe1, 0xf9, 0xd1, 0xb7, 0xfa, 0x96, 0x4d, - 0xba, 0xc4, 0xe4, 0x83, 0xa9, 0x26, 0xce, 0x8f, 0xb1, 0x05, 0x25, 0x50, 0x90, 0x82, 0x1d, 0x93, - 0x9c, 0xe3, 0xc0, 0x66, 0x07, 0xa6, 0x79, 0x88, 0x3d, 0xdc, 0xb1, 0x6c, 0x8b, 0x59, 0xe2, 0xc0, - 0xb3, 0xac, 0x7f, 0x32, 0x1a, 0x2a, 0x3b, 0xcd, 0x42, 0xc4, 0xcb, 0xa1, 0xf2, 0x6e, 0xfe, 0xbe, - 0xa0, 0xc5, 0x90, 0x01, 0x2a, 0x91, 0x86, 0x03, 0x20, 0xfb, 0xe4, 0x0f, 0x41, 0xb8, 0xf2, 0x9a, - 0xbe, 0xeb, 0xa5, 0xdc, 0x56, 0xb8, 0xdb, 0x9f, 0x8d, 0x86, 0x8a, 0x8c, 0x4a, 0x30, 0xb3, 0x1d, - 0x97, 0xca, 0xc3, 0x2f, 0xc0, 0x26, 0x16, 0x27, 0xfd, 0xa4, 0xd7, 0x79, 0xee, 0xf5, 0xfe, 0x68, - 0xa8, 0x6c, 0x1e, 0xe4, 0xcd, 0xb3, 0x1d, 0x16, 0x89, 0xc2, 0x06, 0x58, 0xea, 0xf3, 0x4b, 0x01, - 0x95, 0x17, 0xb8, 0xfe, 0xf6, 0x68, 0xa8, 0x2c, 0x8d, 0xef, 0x09, 0xa1, 0xe6, 0xe2, 0x71, 0x9b, - 0x1f, 0x35, 0x23, 0x14, 0xfc, 0x18, 0xac, 0x5c, 0xb8, 0x94, 0x3d, 0x26, 0xec, 0x4b, 0xd7, 0xbf, - 0xe4, 0xd5, 0xa7, 0xaa, 0x6f, 0x8a, 0x19, 0x5c, 0x79, 0x38, 0x31, 0xa1, 0x24, 0x0e, 0xfe, 0x1a, - 0x2c, 0x5f, 0x88, 0x83, 0x65, 0x54, 0x7a, 0x6e, 0x4d, 0x49, 0xb4, 0xd4, 0x21, 0x54, 0xaf, 0x09, - 0xf9, 0xe5, 0xa8, 0x99, 0xa2, 0x89, 0x1a, 0xfc, 0x01, 0x58, 0xe2, 0x1f, 0x27, 0x4d, 0xb9, 0xca, - 0x7b, 0x73, 0x5d, 0xc0, 0x97, 0x1e, 0x8e, 0x9b, 0x51, 0x64, 0x8f, 0xa0, 0x27, 0xad, 0x43, 0x79, - 0x39, 0x0f, 0x3d, 0x69, 0x1d, 0xa2, 0xc8, 0x0e, 0x9f, 0x81, 0x25, 0x4a, 0x1e, 0x59, 0x4e, 0x70, - 0x25, 0x03, 0xbe, 0xe4, 0x6e, 0x4f, 0xe9, 0x6e, 0xfb, 0x88, 0x23, 0x33, 0x47, 0xfa, 0x89, 0xba, - 0xb0, 0xa3, 0x48, 0x12, 0x9a, 0x60, 0xd9, 0x0f, 0x9c, 0x03, 0xfa, 0x94, 0x12, 0x5f, 0x5e, 0xc9, - 0x9d, 0x27, 0xb2, 0xfa, 0x28, 0xc2, 0x66, 0x3d, 0xc4, 0x91, 0x89, 0x11, 0x68, 0x22, 0x0c, 0x4d, - 0x00, 0xf8, 0x07, 0xbf, 0x39, 0xc8, 0x3b, 0x33, 0x4f, 0x9a, 0x28, 0x06, 0x67, 0xfd, 0xac, 0x87, - 0xcb, 0x73, 0x62, 0x46, 0x09, 0x5d, 0xf8, 0x67, 0x09, 0x40, 0x1a, 0x78, 0x9e, 0x4d, 0x7a, 0xc4, - 0x61, 0xd8, 0xe6, 0xad, 0x54, 0x5e, 0xe5, 0xee, 0x7e, 0x3a, 0x2d, 0x6a, 0x39, 0x52, 0xd6, 0x6d, - 0xbc, 0x37, 0xe7, 0xa1, 0xa8, 0xc0, 0x67, 0x38, 0x69, 0xe7, 0x62, 0xb4, 0x6b, 0x33, 0x27, 0xad, - 0xf8, 0x1e, 0x36, 0x99, 0x34, 0x61, 0x47, 0x91, 0x24, 0xfc, 0x1c, 0xec, 0x44, 0xb7, 0x54, 0xe4, - 0xba, 0xec, 0xd8, 0xb2, 0x09, 0x1d, 0x50, 0x46, 0x7a, 0xf2, 0x3a, 0x4f, 0xa6, 0xba, 0x60, 0xee, - 0xa0, 0x42, 0x14, 0x2a, 0x61, 0xc3, 0x1e, 0x50, 0xa2, 0x22, 0x14, 0xae, 0xd0, 0xb8, 0x0a, 0x1e, - 0x51, 0x03, 0xdb, 0xe3, 0xd3, 0xd7, 0x75, 0xee, 0xe0, 0xfd, 0xd1, 0x50, 0x51, 0x9a, 0xd3, 0xa1, - 0x68, 0x96, 0x16, 0xfc, 0x15, 0x90, 0x71, 0x99, 0x9f, 0x0d, 0xee, 0xe7, 0xff, 0xc2, 0xca, 0x56, - 0xea, 0xa0, 0x94, 0x0d, 0x3d, 0xb0, 0x81, 0xd3, 0xef, 0x05, 0x54, 0xae, 0xf1, 0xb5, 0xfe, 0xc1, - 0x94, 0x79, 0xc8, 0x3c, 0x31, 0xe8, 0xb2, 0x08, 0xe3, 0x46, 0xc6, 0x40, 0x51, 0x4e, 0x1d, 0x5e, - 0x01, 0x88, 0xb3, 0xcf, 0x1b, 0x54, 0x86, 0x33, 0x37, 0xb2, 0xdc, 0x9b, 0xc8, 0x24, 0xd5, 0x72, - 0x26, 0x8a, 0x0a, 0x7c, 0x40, 0x06, 0x6a, 0x38, 0xf3, 0x1c, 0x43, 0xe5, 0x1b, 0xdc, 0xf1, 0x0f, - 0x67, 0x3b, 0x8e, 0x39, 0xfa, 0xae, 0xf0, 0x5b, 0xcb, 0x5a, 0x28, 0xca, 0x3b, 0x80, 0x8f, 0xc0, - 0x96, 0x68, 0x7c, 0xea, 0x50, 0x7c, 0x4e, 0xda, 0x03, 0x6a, 0x30, 0x9b, 0xca, 0x9b, 0xbc, 0x76, - 0xcb, 0xa3, 0xa1, 0xb2, 0x75, 0x50, 0x60, 0x47, 0x85, 0x2c, 0xf8, 0x29, 0xd8, 0x38, 0x77, 0xfd, - 0x8e, 0x65, 0x9a, 0xc4, 0x89, 0x94, 0xb6, 0xb8, 0xd2, 0x56, 0x18, 0xff, 0xe3, 0x8c, 0x0d, 0xe5, - 0xd0, 0x90, 0x82, 0x6d, 0xa1, 0xdc, 0xf2, 0x5d, 0xe3, 0xd4, 0x0d, 0x1c, 0x16, 0x6e, 0x17, 0x54, - 0xde, 0x8e, 0xb7, 0xc8, 0xed, 0x83, 0x22, 0xc0, 0xcb, 0xa1, 0x72, 0xb3, 0x60, 0xbb, 0x4a, 0x81, - 0x50, 0xb1, 0x36, 0xb4, 0xc1, 0xaa, 0x78, 0x60, 0x3b, 0xb4, 0x31, 0xa5, 0xb2, 0xcc, 0x97, 0xfa, - 0xbd, 0xe9, 0x85, 0x2d, 0x86, 0x67, 0xd7, 0x3b, 0xbf, 0xf9, 0x25, 0x01, 0x28, 0xa5, 0xae, 0xfe, - 0x55, 0x02, 0xbb, 0xa5, 0x85, 0x11, 0xde, 0x4b, 0xbd, 0xda, 0xa8, 0x99, 0x57, 0x1b, 0x98, 0x27, - 0xbe, 0x81, 0x47, 0x9b, 0xaf, 0x24, 0x20, 0x97, 0xed, 0x10, 0xf0, 0xe3, 0x54, 0x07, 0xdf, 0xcb, - 0x74, 0xb0, 0x96, 0xe3, 0xbd, 0x81, 0xfe, 0x7d, 0x23, 0x81, 0x77, 0xa6, 0xcc, 0x40, 0x5c, 0x90, - 0x88, 0x99, 0x44, 0x3d, 0xc6, 0xe1, 0x52, 0x96, 0x78, 0x1e, 0x4d, 0x0a, 0x52, 0x01, 0x06, 0x95, - 0xb2, 0xe1, 0x53, 0x70, 0x43, 0x54, 0xc3, 0xac, 0x8d, 0x9f, 0xdc, 0x97, 0xf5, 0x77, 0x46, 0x43, - 0xe5, 0x46, 0xb3, 0x18, 0x82, 0xca, 0xb8, 0xea, 0xdf, 0x25, 0xb0, 0x53, 0xbc, 0xe5, 0xc3, 0x3b, - 0xa9, 0x70, 0x2b, 0x99, 0x70, 0x5f, 0xcf, 0xb0, 0x44, 0xb0, 0x7f, 0x07, 0xd6, 0xc5, 0xc1, 0x20, - 0xfd, 0x08, 0x99, 0x0a, 0x7a, 0xb8, 0x44, 0xc2, 0x33, 0xbd, 0x90, 0x88, 0xd2, 0x97, 0xdf, 0xf7, - 0xd3, 0x6d, 0x28, 0xa3, 0xa6, 0xfe, 0x43, 0x02, 0xef, 0xcd, 0xdc, 0x6c, 0xa1, 0x9e, 0xea, 0xba, - 0x96, 0xe9, 0x7a, 0xbd, 0x5c, 0xe0, 0xcd, 0xbc, 0x45, 0xea, 0xbf, 0x78, 0xfe, 0xa2, 0x3e, 0xf7, - 0xed, 0x8b, 0xfa, 0xdc, 0x77, 0x2f, 0xea, 0x73, 0x7f, 0x1c, 0xd5, 0xa5, 0xe7, 0xa3, 0xba, 0xf4, - 0xed, 0xa8, 0x2e, 0x7d, 0x37, 0xaa, 0x4b, 0xff, 0x19, 0xd5, 0xa5, 0xbf, 0xfc, 0xb7, 0x3e, 0xf7, - 0x9b, 0xdd, 0xd2, 0xff, 0x20, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xec, 0x71, 0xd7, 0x62, 0xb8, - 0x18, 0x00, 0x00, + 0x15, 0x16, 0x4c, 0x5d, 0xa8, 0xd5, 0xc5, 0xe2, 0xea, 0x62, 0x48, 0x69, 0x08, 0x07, 0x99, 0xe9, + 0xb8, 0x69, 0x0a, 0xc6, 0xb2, 0xe3, 0x7a, 0x9a, 0x5e, 0x2c, 0x88, 0x92, 0xad, 0x8c, 0x65, 0xb1, + 0x4b, 0x2b, 0xd3, 0x76, 0xdc, 0x4e, 0x97, 0xc0, 0x8a, 0x44, 0x04, 0x02, 0x28, 0x76, 0xc1, 0x88, + 0x6f, 0x79, 0xe8, 0x43, 0x1f, 0xfb, 0x07, 0x32, 0xfd, 0x01, 0x9d, 0x3e, 0xf5, 0x47, 0xd4, 0x99, + 0xe9, 0x74, 0xd2, 0xb7, 0x4c, 0x1f, 0x38, 0x35, 0xfb, 0x2f, 0xfc, 0xd4, 0xc1, 0x72, 0x01, 0x12, + 0x37, 0xd2, 0xce, 0x8c, 0xfd, 0x46, 0xec, 0xf9, 0xbe, 0xef, 0xec, 0x9e, 0xdd, 0x3d, 0x67, 0x77, + 0x09, 0xf4, 0xcb, 0xfb, 0x54, 0xb3, 0xdc, 0xda, 0x65, 0xd0, 0x22, 0xbe, 0x43, 0x18, 0xa1, 0xb5, + 0x1e, 0x71, 0x4c, 0xd7, 0xaf, 0x09, 0x03, 0xf6, 0xac, 0x9a, 0xe7, 0xda, 0x96, 0xd1, 0xaf, 0xf5, + 0x6e, 0xb7, 0x08, 0xc3, 0xb7, 0x6b, 0x6d, 0xe2, 0x10, 0x1f, 0x33, 0x62, 0x6a, 0x9e, 0xef, 0x32, + 0x17, 0xee, 0x8e, 0xa0, 0x1a, 0xf6, 0x2c, 0x6d, 0x04, 0xd5, 0x04, 0x74, 0xef, 0x47, 0x6d, 0x8b, + 0x75, 0x82, 0x96, 0x66, 0xb8, 0xdd, 0x5a, 0xdb, 0x6d, 0xbb, 0x35, 0xce, 0x68, 0x05, 0x17, 0xfc, + 0x8b, 0x7f, 0xf0, 0x5f, 0x23, 0xa5, 0x3d, 0x75, 0xc2, 0xa9, 0xe1, 0xfa, 0xa4, 0xd6, 0xcb, 0x78, + 0xdb, 0xbb, 0x3b, 0xc6, 0x74, 0xb1, 0xd1, 0xb1, 0x1c, 0xe2, 0xf7, 0x6b, 0xde, 0x65, 0x3b, 0x6c, + 0xa0, 0xb5, 0x2e, 0x61, 0x38, 0x8f, 0x55, 0x2b, 0x62, 0xf9, 0x81, 0xc3, 0xac, 0x2e, 0xc9, 0x10, + 0xee, 0xcd, 0x22, 0x50, 0xa3, 0x43, 0xba, 0x38, 0xc3, 0xbb, 0x53, 0xc4, 0x0b, 0x98, 0x65, 0xd7, + 0x2c, 0x87, 0x51, 0xe6, 0xa7, 0x49, 0xea, 0x5d, 0xb0, 0x71, 0x60, 0xdb, 0xee, 0x17, 0xc4, 0x3c, + 0x6c, 0x9e, 0xd4, 0x7d, 0xab, 0x47, 0x7c, 0x78, 0x13, 0xcc, 0x3b, 0xb8, 0x4b, 0x64, 0xe9, 0xa6, + 0x74, 0x6b, 0x59, 0x5f, 0x7d, 0x3e, 0x50, 0xe6, 0x86, 0x03, 0x65, 0xfe, 0x09, 0xee, 0x12, 0xc4, + 0x2d, 0xea, 0x27, 0xa0, 0x22, 0x58, 0xc7, 0x36, 0xb9, 0xfa, 0xcc, 0xb5, 0x83, 0x2e, 0x81, 0xdf, + 0x07, 0x8b, 0x26, 0x17, 0x10, 0xc4, 0x75, 0x41, 0x5c, 0x1c, 0xc9, 0x22, 0x61, 0x55, 0x29, 0xb8, + 0x2e, 0xc8, 0x8f, 0x5c, 0xca, 0x1a, 0x98, 0x75, 0xe0, 0x3e, 0x00, 0x1e, 0x66, 0x9d, 0x86, 0x4f, + 0x2e, 0xac, 0x2b, 0x41, 0x87, 0x82, 0x0e, 0x1a, 0xb1, 0x05, 0x4d, 0xa0, 0xe0, 0x87, 0xa0, 0xec, + 0x13, 0x6c, 0x9e, 0x39, 0x76, 0x5f, 0xbe, 0x76, 0x53, 0xba, 0x55, 0xd6, 0x37, 0x04, 0xa3, 0x8c, + 0x44, 0x3b, 0x8a, 0x11, 0xea, 0x7f, 0x24, 0x50, 0x3e, 0xea, 0x59, 0x06, 0xb3, 0x5c, 0x07, 0xfe, + 0x1e, 0x94, 0xc3, 0xd9, 0x32, 0x31, 0xc3, 0xdc, 0xd9, 0xca, 0xfe, 0x47, 0xda, 0x78, 0x25, 0xc5, + 0xc1, 0xd3, 0xbc, 0xcb, 0x76, 0xd8, 0x40, 0xb5, 0x10, 0xad, 0xf5, 0x6e, 0x6b, 0x67, 0xad, 0xcf, + 0x89, 0xc1, 0x4e, 0x09, 0xc3, 0xe3, 0xee, 0x8d, 0xdb, 0x50, 0xac, 0x0a, 0x6d, 0xb0, 0x66, 0x12, + 0x9b, 0x30, 0x72, 0xe6, 0x85, 0x1e, 0x29, 0xef, 0xe1, 0xca, 0xfe, 0x9d, 0x57, 0x73, 0x53, 0x9f, + 0xa4, 0xea, 0x95, 0xe1, 0x40, 0x59, 0x4b, 0x34, 0xa1, 0xa4, 0xb8, 0xfa, 0x95, 0x04, 0x76, 0x8e, + 0x9b, 0x0f, 0x7d, 0x37, 0xf0, 0x9a, 0x2c, 0x9c, 0xdd, 0x76, 0x5f, 0x98, 0xe0, 0x8f, 0xc1, 0xbc, + 0x1f, 0xd8, 0xd1, 0x5c, 0xbe, 0x1f, 0xcd, 0x25, 0x0a, 0x6c, 0xf2, 0x72, 0xa0, 0x6c, 0xa6, 0x58, + 0x4f, 0xfb, 0x1e, 0x41, 0x9c, 0x00, 0x3f, 0x05, 0x8b, 0x3e, 0x76, 0xda, 0x24, 0xec, 0x7a, 0xe9, + 0xd6, 0xca, 0xbe, 0xaa, 0x15, 0xee, 0x35, 0xed, 0xa4, 0x8e, 0x42, 0xe8, 0x78, 0xc6, 0xf9, 0x27, + 0x45, 0x42, 0x41, 0x3d, 0x05, 0x6b, 0x7c, 0xaa, 0x5d, 0x9f, 0x71, 0x0b, 0x7c, 0x17, 0x94, 0xba, + 0x96, 0xc3, 0x3b, 0xb5, 0xa0, 0xaf, 0x08, 0x56, 0xe9, 0xd4, 0x72, 0x50, 0xd8, 0xce, 0xcd, 0xf8, + 0x8a, 0xc7, 0x6c, 0xd2, 0x8c, 0xaf, 0x50, 0xd8, 0xae, 0x3e, 0x04, 0x4b, 0xc2, 0xe3, 0xa4, 0x50, + 0x69, 0xba, 0x50, 0x29, 0x47, 0xe8, 0xaf, 0xd7, 0xc0, 0x66, 0xc3, 0x35, 0xeb, 0x16, 0xf5, 0x03, + 0x1e, 0x2f, 0x3d, 0x30, 0xdb, 0x84, 0xbd, 0x85, 0xf5, 0xf1, 0x14, 0xcc, 0x53, 0x8f, 0x18, 0x62, + 0x59, 0xec, 0x4f, 0x89, 0x6d, 0x4e, 0xff, 0x9a, 0x1e, 0x31, 0xc6, 0xdb, 0x32, 0xfc, 0x42, 0x5c, + 0x0d, 0x3e, 0x03, 0x8b, 0x94, 0x61, 0x16, 0x50, 0xb9, 0xc4, 0x75, 0xef, 0xbe, 0xa6, 0x2e, 0xe7, + 0x8e, 0x67, 0x71, 0xf4, 0x8d, 0x84, 0xa6, 0xfa, 0x4f, 0x09, 0xdc, 0xc8, 0x61, 0x3d, 0xb6, 0x28, + 0x83, 0xcf, 0x32, 0x11, 0xd3, 0x5e, 0x2d, 0x62, 0x21, 0x9b, 0xc7, 0x2b, 0xde, 0xbc, 0x51, 0xcb, + 0x44, 0xb4, 0x9a, 0x60, 0xc1, 0x62, 0xa4, 0x1b, 0x2d, 0x45, 0xed, 0xf5, 0x86, 0xa5, 0xaf, 0x09, + 0xe9, 0x85, 0x93, 0x50, 0x04, 0x8d, 0xb4, 0xd4, 0x7f, 0x97, 0x72, 0x87, 0x13, 0x86, 0x13, 0x5e, + 0x80, 0xd5, 0xae, 0xe5, 0x1c, 0xf4, 0xb0, 0x65, 0xe3, 0x96, 0xd8, 0x3d, 0xd3, 0x16, 0x41, 0x98, + 0x61, 0xb5, 0x51, 0x86, 0xd5, 0x4e, 0x1c, 0x76, 0xe6, 0x37, 0x99, 0x6f, 0x39, 0x6d, 0x7d, 0x63, + 0x38, 0x50, 0x56, 0x4f, 0x27, 0x94, 0x50, 0x42, 0x17, 0xfe, 0x16, 0x94, 0x29, 0xb1, 0x89, 0xc1, + 0x5c, 0xff, 0xf5, 0x32, 0xc4, 0x63, 0xdc, 0x22, 0x76, 0x53, 0x50, 0xf5, 0xd5, 0x30, 0x6e, 0xd1, + 0x17, 0x8a, 0x25, 0xa1, 0x0d, 0xd6, 0xbb, 0xf8, 0xea, 0xdc, 0xc1, 0xf1, 0x40, 0x4a, 0xdf, 0x71, + 0x20, 0x70, 0x38, 0x50, 0xd6, 0x4f, 0x13, 0x5a, 0x28, 0xa5, 0x0d, 0xbf, 0x94, 0xc0, 0x5e, 0xe0, + 0x74, 0x08, 0xb6, 0x59, 0xa7, 0xdf, 0x70, 0xcd, 0x28, 0xdd, 0x36, 0xf8, 0x0c, 0xc9, 0xf3, 0x3c, + 0x03, 0x3d, 0x18, 0x0e, 0x94, 0xbd, 0xf3, 0x42, 0xd4, 0xcb, 0x81, 0x52, 0x2d, 0xb6, 0xf2, 0xf4, + 0x34, 0xc5, 0x87, 0xfa, 0x8f, 0x05, 0xb0, 0x5b, 0xb8, 0xb0, 0xe1, 0xa7, 0x00, 0xba, 0x2d, 0x4a, + 0xfc, 0x1e, 0x31, 0x1f, 0x8e, 0xca, 0xa0, 0xe5, 0x46, 0xb9, 0x63, 0x4f, 0xac, 0x11, 0x78, 0x96, + 0x41, 0xa0, 0x1c, 0x16, 0xfc, 0xa3, 0x04, 0xd6, 0xcc, 0x91, 0x1b, 0x62, 0x36, 0x5c, 0x33, 0x5a, + 0x9b, 0x0f, 0xbf, 0xcb, 0x96, 0xd3, 0xea, 0x93, 0x4a, 0x47, 0x0e, 0xf3, 0xfb, 0xfa, 0xb6, 0xe8, + 0xd0, 0x5a, 0xc2, 0x86, 0x92, 0x4e, 0xc3, 0x21, 0x99, 0xb1, 0x24, 0x15, 0x65, 0x95, 0xcf, 0xf2, + 0xc2, 0x78, 0x48, 0xf5, 0x0c, 0x02, 0xe5, 0xb0, 0xe0, 0xcf, 0xc1, 0xba, 0x11, 0xf8, 0x3e, 0x71, + 0xd8, 0xa3, 0x51, 0x7c, 0xf9, 0x94, 0x2d, 0xe8, 0x3b, 0x42, 0x67, 0xfd, 0x30, 0x61, 0x45, 0x29, + 0x74, 0xc8, 0x37, 0x09, 0xb5, 0x7c, 0x62, 0x46, 0xfc, 0x85, 0x24, 0xbf, 0x9e, 0xb0, 0xa2, 0x14, + 0x1a, 0xde, 0x07, 0xab, 0xe4, 0xca, 0x23, 0x46, 0x14, 0xd0, 0x45, 0xce, 0xde, 0x12, 0xec, 0xd5, + 0xa3, 0x09, 0x1b, 0x4a, 0x20, 0xa1, 0x01, 0x80, 0xe1, 0x3a, 0xa6, 0x35, 0x2a, 0xb5, 0x4b, 0x7c, + 0x22, 0x6a, 0xaf, 0xb6, 0x91, 0x0e, 0x23, 0xde, 0x38, 0x61, 0xc7, 0x4d, 0x14, 0x4d, 0xc8, 0xee, + 0xd9, 0x00, 0x66, 0xa7, 0x09, 0x6e, 0x80, 0xd2, 0x25, 0xe9, 0x8f, 0xca, 0x2b, 0x0a, 0x7f, 0xc2, + 0x07, 0x60, 0xa1, 0x87, 0xed, 0x80, 0x88, 0x0d, 0xfd, 0xc1, 0xab, 0xf5, 0xe3, 0xa9, 0xd5, 0x25, + 0x68, 0x44, 0xfc, 0xc9, 0xb5, 0xfb, 0x92, 0xfa, 0xb5, 0x04, 0x2a, 0x0d, 0xd7, 0x6c, 0x12, 0x23, + 0xf0, 0x2d, 0xd6, 0x1f, 0xad, 0xef, 0xb7, 0x50, 0x98, 0x50, 0xa2, 0x30, 0x7d, 0x34, 0x7d, 0x35, + 0x27, 0x7b, 0x57, 0x54, 0x96, 0xd4, 0xe7, 0x12, 0xd8, 0xce, 0xa0, 0xdf, 0x42, 0xd9, 0xf8, 0x65, + 0xb2, 0x6c, 0x7c, 0xf8, 0x3a, 0x83, 0x29, 0x28, 0x1a, 0x5f, 0x57, 0x72, 0x86, 0xc2, 0x4b, 0x46, + 0x78, 0x84, 0xf5, 0xad, 0x9e, 0x65, 0x93, 0x36, 0x31, 0xf9, 0x60, 0xca, 0x13, 0x47, 0xd8, 0xd8, + 0x82, 0x26, 0x50, 0x90, 0x82, 0x1d, 0x93, 0x5c, 0xe0, 0xc0, 0x66, 0x07, 0xa6, 0x79, 0x88, 0x3d, + 0xdc, 0xb2, 0x6c, 0x8b, 0x59, 0xe2, 0xcc, 0xb5, 0xac, 0x7f, 0x32, 0x1c, 0x28, 0x3b, 0xf5, 0x5c, + 0xc4, 0xcb, 0x81, 0xf2, 0x6e, 0xf6, 0xca, 0xa2, 0xc5, 0x90, 0x3e, 0x2a, 0x90, 0x86, 0x7d, 0x20, + 0xfb, 0xe4, 0x0f, 0x41, 0xb8, 0xf3, 0xea, 0xbe, 0xeb, 0x25, 0xdc, 0x96, 0xb8, 0xdb, 0x9f, 0x0d, + 0x07, 0x8a, 0x8c, 0x0a, 0x30, 0xb3, 0x1d, 0x17, 0xca, 0xc3, 0xcf, 0xc1, 0x26, 0x16, 0x97, 0x8d, + 0x49, 0xaf, 0xf3, 0xdc, 0xeb, 0xfd, 0xe1, 0x40, 0xd9, 0x3c, 0xc8, 0x9a, 0x67, 0x3b, 0xcc, 0x13, + 0x85, 0x35, 0xb0, 0xd4, 0xe3, 0xf7, 0x12, 0x2a, 0x2f, 0x70, 0xfd, 0xed, 0xe1, 0x40, 0x59, 0x1a, + 0x5d, 0x55, 0x42, 0xcd, 0xc5, 0xe3, 0x26, 0x2f, 0x27, 0x11, 0x0a, 0x7e, 0x0c, 0x56, 0x3a, 0x2e, + 0x65, 0x4f, 0x08, 0xfb, 0xc2, 0xf5, 0x2f, 0x79, 0xf6, 0x29, 0xeb, 0x9b, 0x62, 0x06, 0x57, 0x1e, + 0x8d, 0x4d, 0x68, 0x12, 0x07, 0x7f, 0x0d, 0x96, 0x3b, 0xe2, 0x6c, 0x1b, 0xa5, 0x9e, 0x5b, 0x53, + 0x16, 0x5a, 0xe2, 0x1c, 0xac, 0x57, 0x84, 0xfc, 0x72, 0xd4, 0x4c, 0xd1, 0x58, 0x0d, 0xfe, 0x00, + 0x2c, 0xf1, 0x8f, 0x93, 0xba, 0x5c, 0xe6, 0xbd, 0xb9, 0x2e, 0xe0, 0x4b, 0x8f, 0x46, 0xcd, 0x28, + 0xb2, 0x47, 0xd0, 0x93, 0xc6, 0xa1, 0xbc, 0x9c, 0x85, 0x9e, 0x34, 0x0e, 0x51, 0x64, 0x87, 0xcf, + 0xc0, 0x12, 0x25, 0x8f, 0x2d, 0x27, 0xb8, 0x92, 0x01, 0xdf, 0x72, 0xb7, 0xa7, 0x74, 0xb7, 0x79, + 0xc4, 0x91, 0xa9, 0x5b, 0xc5, 0x58, 0x5d, 0xd8, 0x51, 0x24, 0x09, 0x4d, 0xb0, 0xec, 0x07, 0xce, + 0x01, 0x3d, 0xa7, 0xc4, 0x97, 0x57, 0x32, 0x47, 0x9a, 0xb4, 0x3e, 0x8a, 0xb0, 0x69, 0x0f, 0x71, + 0x64, 0x62, 0x04, 0x1a, 0x0b, 0x43, 0x13, 0x00, 0xfe, 0xc1, 0x2f, 0x2f, 0xf2, 0xce, 0xcc, 0xc3, + 0x2e, 0x8a, 0xc1, 0x69, 0x3f, 0xeb, 0xe1, 0xf6, 0x1c, 0x9b, 0xd1, 0x84, 0x2e, 0xfc, 0x93, 0x04, + 0x20, 0x0d, 0x3c, 0xcf, 0x26, 0x5d, 0xe2, 0x30, 0x6c, 0xf3, 0x56, 0x2a, 0xaf, 0x72, 0x77, 0x3f, + 0x9d, 0x16, 0xb5, 0x0c, 0x29, 0xed, 0x36, 0xae, 0xcd, 0x59, 0x28, 0xca, 0xf1, 0x19, 0x4e, 0xda, + 0x85, 0x18, 0xed, 0xda, 0xcc, 0x49, 0xcb, 0xbf, 0x0a, 0x8e, 0x27, 0x4d, 0xd8, 0x51, 0x24, 0x09, + 0x3f, 0x03, 0x3b, 0xd1, 0x45, 0x19, 0xb9, 0x2e, 0x3b, 0xb6, 0x6c, 0x42, 0xfb, 0x94, 0x91, 0xae, + 0xbc, 0xce, 0x17, 0x53, 0x55, 0x30, 0x77, 0x50, 0x2e, 0x0a, 0x15, 0xb0, 0x61, 0x17, 0x28, 0x51, + 0x12, 0x0a, 0x77, 0x68, 0x9c, 0x05, 0x8f, 0xa8, 0x81, 0xed, 0xd1, 0xe9, 0xeb, 0x3a, 0x77, 0xf0, + 0xfe, 0x70, 0xa0, 0x28, 0xf5, 0xe9, 0x50, 0x34, 0x4b, 0x0b, 0xfe, 0x0a, 0xc8, 0xb8, 0xc8, 0xcf, + 0x06, 0xf7, 0xf3, 0xbd, 0x30, 0xb3, 0x15, 0x3a, 0x28, 0x64, 0x43, 0x0f, 0x6c, 0xe0, 0xe4, 0x93, + 0x05, 0x95, 0x2b, 0x7c, 0xaf, 0x7f, 0x30, 0x65, 0x1e, 0x52, 0xaf, 0x1c, 0xba, 0x2c, 0xc2, 0xb8, + 0x91, 0x32, 0x50, 0x94, 0x51, 0x87, 0x57, 0x00, 0xe2, 0xf4, 0x0b, 0x0b, 0x95, 0xe1, 0xcc, 0x42, + 0x96, 0x79, 0x96, 0x19, 0x2f, 0xb5, 0x8c, 0x89, 0xa2, 0x1c, 0x1f, 0x90, 0x81, 0x0a, 0x4e, 0xbd, + 0x08, 0x51, 0xf9, 0x06, 0x77, 0xfc, 0xc3, 0xd9, 0x8e, 0x63, 0x8e, 0xbe, 0x2b, 0xfc, 0x56, 0xd2, + 0x16, 0x8a, 0xb2, 0x0e, 0xe0, 0x63, 0xb0, 0x25, 0x1a, 0xcf, 0x1d, 0x8a, 0x2f, 0x48, 0xb3, 0x4f, + 0x0d, 0x66, 0x53, 0x79, 0x93, 0xe7, 0x6e, 0x79, 0x38, 0x50, 0xb6, 0x0e, 0x72, 0xec, 0x28, 0x97, + 0x05, 0x1f, 0x80, 0x8d, 0x0b, 0xd7, 0x6f, 0x59, 0xa6, 0x49, 0x9c, 0x48, 0x69, 0x8b, 0x2b, 0x6d, + 0x85, 0xf1, 0x3f, 0x4e, 0xd9, 0x50, 0x06, 0x0d, 0x29, 0xd8, 0x16, 0xca, 0x0d, 0xdf, 0x35, 0x4e, + 0xdd, 0xc0, 0x61, 0x61, 0xb9, 0xa0, 0xf2, 0x76, 0x5c, 0x22, 0xb7, 0x0f, 0xf2, 0x00, 0x2f, 0x07, + 0xca, 0xcd, 0x9c, 0x72, 0x95, 0x00, 0xa1, 0x7c, 0x6d, 0x68, 0x83, 0x55, 0xf1, 0xc6, 0x77, 0x68, + 0x63, 0x4a, 0x65, 0x99, 0x6f, 0xf5, 0x7b, 0xd3, 0x13, 0x5b, 0x0c, 0x4f, 0xef, 0x77, 0x7e, 0xf9, + 0x9c, 0x04, 0xa0, 0x84, 0xba, 0xfa, 0x17, 0x09, 0xec, 0x16, 0x26, 0x46, 0x78, 0x2f, 0xf1, 0x70, + 0xa4, 0xa6, 0x1e, 0x8e, 0x60, 0x96, 0xf8, 0x06, 0xde, 0x8d, 0xbe, 0x92, 0x80, 0x5c, 0x54, 0x21, + 0xe0, 0xc7, 0x89, 0x0e, 0xbe, 0x97, 0xea, 0x60, 0x25, 0xc3, 0x7b, 0x03, 0xfd, 0xfb, 0x97, 0x04, + 0xde, 0x99, 0x32, 0x03, 0x71, 0x42, 0x22, 0xe6, 0x24, 0xea, 0x09, 0x0e, 0xb7, 0xb2, 0xc4, 0xd7, + 0xd1, 0x38, 0x21, 0xe5, 0x60, 0x50, 0x21, 0x1b, 0x9e, 0x83, 0x1b, 0x22, 0x1b, 0xa6, 0x6d, 0xfc, + 0xe4, 0xbe, 0xac, 0xbf, 0x33, 0x1c, 0x28, 0x37, 0xea, 0xf9, 0x10, 0x54, 0xc4, 0x55, 0xff, 0x26, + 0x81, 0x9d, 0xfc, 0x92, 0x0f, 0xef, 0x24, 0xc2, 0xad, 0xa4, 0xc2, 0x7d, 0x3d, 0xc5, 0x12, 0xc1, + 0xfe, 0x1d, 0x58, 0x17, 0x07, 0x83, 0xe4, 0x3b, 0x68, 0x22, 0xe8, 0xe1, 0x16, 0x09, 0xcf, 0xf4, + 0x42, 0x22, 0x5a, 0xbe, 0xfc, 0xc9, 0x21, 0xd9, 0x86, 0x52, 0x6a, 0xea, 0xdf, 0x25, 0xf0, 0xde, + 0xcc, 0x62, 0x0b, 0xf5, 0x44, 0xd7, 0xb5, 0x54, 0xd7, 0xab, 0xc5, 0x02, 0x6f, 0xe6, 0x39, 0x54, + 0xff, 0xc5, 0xf3, 0x17, 0xd5, 0xb9, 0x6f, 0x5e, 0x54, 0xe7, 0xbe, 0x7d, 0x51, 0x9d, 0xfb, 0x72, + 0x58, 0x95, 0x9e, 0x0f, 0xab, 0xd2, 0x37, 0xc3, 0xaa, 0xf4, 0xed, 0xb0, 0x2a, 0xfd, 0x77, 0x58, + 0x95, 0xfe, 0xfc, 0xbf, 0xea, 0xdc, 0x6f, 0x76, 0x0b, 0xff, 0x06, 0xf9, 0x7f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xb4, 0x84, 0x53, 0xfb, 0x3b, 0x19, 0x00, 0x00, } func (m *AllowedCSIDriver) Marshal() (dAtA []byte, err error) { @@ -1089,6 +1091,13 @@ func (m *PodDisruptionBudgetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if m.UnhealthyPodEvictionPolicy != nil { + i -= len(*m.UnhealthyPodEvictionPolicy) + copy(dAtA[i:], *m.UnhealthyPodEvictionPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.UnhealthyPodEvictionPolicy))) + i-- + dAtA[i] = 0x22 + } if m.MaxUnavailable != nil { { size, err := m.MaxUnavailable.MarshalToSizedBuffer(dAtA[:i]) @@ -1937,6 +1946,10 @@ func (m *PodDisruptionBudgetSpec) Size() (n int) { l = m.MaxUnavailable.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.UnhealthyPodEvictionPolicy != nil { + l = len(*m.UnhealthyPodEvictionPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -2308,6 +2321,7 @@ func (this *PodDisruptionBudgetSpec) String() string { `MinAvailable:` + strings.Replace(fmt.Sprintf("%v", this.MinAvailable), "IntOrString", "intstr.IntOrString", 1) + `,`, `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, `MaxUnavailable:` + strings.Replace(fmt.Sprintf("%v", this.MaxUnavailable), "IntOrString", "intstr.IntOrString", 1) + `,`, + `UnhealthyPodEvictionPolicy:` + valueToStringGenerated(this.UnhealthyPodEvictionPolicy) + `,`, `}`, }, "") return s @@ -3581,6 +3595,39 @@ func (m *PodDisruptionBudgetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnhealthyPodEvictionPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := UnhealthyPodEvictionPolicyType(dAtA[iNdEx:postIndex]) + m.UnhealthyPodEvictionPolicy = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/policy/v1beta1/generated.proto b/vendor/k8s.io/api/policy/v1beta1/generated.proto index 09dbdde9817..16301c236af 100644 --- a/vendor/k8s.io/api/policy/v1beta1/generated.proto +++ b/vendor/k8s.io/api/policy/v1beta1/generated.proto @@ -153,6 +153,34 @@ message PodDisruptionBudgetSpec { // by specifying 0. This is a mutually exclusive setting with "minAvailable". // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUnavailable = 3; + + // UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + // should be considered for eviction. Current implementation considers healthy pods, + // as pods that have status.conditions item with type="Ready",status="True". + // + // Valid policies are IfHealthyBudget and AlwaysAllow. + // If no policy is specified, the default behavior will be used, + // which corresponds to the IfHealthyBudget policy. + // + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + // + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + // + // Additional policies may be added in the future. + // Clients making eviction decisions should disallow eviction of unhealthy pods + // if they encounter an unrecognized policy in this field. + // + // This field is beta-level. The eviction API uses this field when + // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + // +optional + optional string unhealthyPodEvictionPolicy = 4; } // PodDisruptionBudgetStatus represents information about the status of a @@ -329,7 +357,6 @@ message PodSecurityPolicySpec { // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate. // +optional repeated AllowedCSIDriver allowedCSIDrivers = 23; diff --git a/vendor/k8s.io/api/policy/v1beta1/types.go b/vendor/k8s.io/api/policy/v1beta1/types.go index 486f93461af..1e6b075e32d 100644 --- a/vendor/k8s.io/api/policy/v1beta1/types.go +++ b/vendor/k8s.io/api/policy/v1beta1/types.go @@ -45,8 +45,56 @@ type PodDisruptionBudgetSpec struct { // by specifying 0. This is a mutually exclusive setting with "minAvailable". // +optional MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"` + + // UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods + // should be considered for eviction. Current implementation considers healthy pods, + // as pods that have status.conditions item with type="Ready",status="True". + // + // Valid policies are IfHealthyBudget and AlwaysAllow. + // If no policy is specified, the default behavior will be used, + // which corresponds to the IfHealthyBudget policy. + // + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + // + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + // + // Additional policies may be added in the future. + // Clients making eviction decisions should disallow eviction of unhealthy pods + // if they encounter an unrecognized policy in this field. + // + // This field is beta-level. The eviction API uses this field when + // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). + // +optional + UnhealthyPodEvictionPolicy *UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty" protobuf:"bytes,4,opt,name=unhealthyPodEvictionPolicy"` } +// UnhealthyPodEvictionPolicyType defines the criteria for when unhealthy pods +// should be considered for eviction. +// +enum +type UnhealthyPodEvictionPolicyType string + +const ( + // IfHealthyBudget policy means that running pods (status.phase="Running"), + // but not yet healthy can be evicted only if the guarded application is not + // disrupted (status.currentHealthy is at least equal to status.desiredHealthy). + // Healthy pods will be subject to the PDB for eviction. + IfHealthyBudget UnhealthyPodEvictionPolicyType = "IfHealthyBudget" + + // AlwaysAllow policy means that all running pods (status.phase="Running"), + // but not yet healthy are considered disrupted and can be evicted regardless + // of whether the criteria in a PDB is met. This means perspective running + // pods of a disrupted application might not get a chance to become healthy. + // Healthy pods will be subject to the PDB for eviction. + AlwaysAllow UnhealthyPodEvictionPolicyType = "AlwaysAllow" +) + // PodDisruptionBudgetStatus represents information about the status of a // PodDisruptionBudget. Status may trail the actual state of a system. type PodDisruptionBudgetStatus struct { @@ -278,7 +326,6 @@ type PodSecurityPolicySpec struct { AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"` // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate. // +optional AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"` // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. diff --git a/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go index ef81d43af36..266a9a853a8 100644 --- a/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllowedCSIDriver = map[string]string{ @@ -117,10 +117,11 @@ func (PodDisruptionBudgetList) SwaggerDoc() map[string]string { } var map_PodDisruptionBudgetSpec = map[string]string{ - "": "PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.", - "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", - "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector selects no pods. An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. In policy/v1, an empty selector will select all pods in the namespace.", - "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", + "": "PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.", + "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", + "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector selects no pods. An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. In policy/v1, an empty selector will select all pods in the namespace.", + "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", + "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { @@ -183,7 +184,7 @@ var map_PodSecurityPolicySpec = map[string]string{ "allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.", "allowedHostPaths": "allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.", "allowedFlexVolumes": "allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.", - "allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes. This is a beta field, and is only honored if the API server enables the CSIInlineVolume feature gate.", + "allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.", "allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.", "forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.", "allowedProcMountTypes": "AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.", diff --git a/vendor/k8s.io/api/policy/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/policy/v1beta1/zz_generated.deepcopy.go index 0a6239b87e7..8602d1adcad 100644 --- a/vendor/k8s.io/api/policy/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/policy/v1beta1/zz_generated.deepcopy.go @@ -239,6 +239,11 @@ func (in *PodDisruptionBudgetSpec) DeepCopyInto(out *PodDisruptionBudgetSpec) { *out = new(intstr.IntOrString) **out = **in } + if in.UnhealthyPodEvictionPolicy != nil { + in, out := &in.UnhealthyPodEvictionPolicy, &out.UnhealthyPodEvictionPolicy + *out = new(UnhealthyPodEvictionPolicyType) + **out = **in + } return } diff --git a/vendor/k8s.io/api/rbac/v1/generated.proto b/vendor/k8s.io/api/rbac/v1/generated.proto index 1cb19d5dae9..222f2b9052b 100644 --- a/vendor/k8s.io/api/rbac/v1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1/generated.proto @@ -96,7 +96,7 @@ message PolicyRule { repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional repeated string apiGroups = 2; diff --git a/vendor/k8s.io/api/rbac/v1/types.go b/vendor/k8s.io/api/rbac/v1/types.go index 067b6f15efb..5a8e4a85c88 100644 --- a/vendor/k8s.io/api/rbac/v1/types.go +++ b/vendor/k8s.io/api/rbac/v1/types.go @@ -51,7 +51,7 @@ type PolicyRule struct { Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` // Resources is a list of resources this rule applies to. '*' represents all resources. diff --git a/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go index 228ee54c086..370398198bc 100644 --- a/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ @@ -81,7 +81,7 @@ func (ClusterRoleList) SwaggerDoc() map[string]string { var map_PolicyRule = map[string]string{ "": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.", "verbs": "Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.", - "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.", + "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"\" represents the core API group and \"*\" represents all API groups.", "resources": "Resources is a list of resources this rule applies to. '*' represents all resources.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.", diff --git a/vendor/k8s.io/api/rbac/v1alpha1/generated.proto b/vendor/k8s.io/api/rbac/v1alpha1/generated.proto index bc0da93cea9..d5ceaa0e824 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1alpha1/generated.proto @@ -100,7 +100,7 @@ message PolicyRule { repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional repeated string apiGroups = 3; diff --git a/vendor/k8s.io/api/rbac/v1alpha1/types.go b/vendor/k8s.io/api/rbac/v1alpha1/types.go index 13a0a1f0a3d..e0e75b1503b 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/types.go +++ b/vendor/k8s.io/api/rbac/v1alpha1/types.go @@ -51,7 +51,7 @@ type PolicyRule struct { Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,3,rep,name=apiGroups"` // Resources is a list of resources this rule applies to. '*' represents all resources. diff --git a/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go index 46b8b9ee6f3..6708f3e58e3 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ @@ -81,7 +81,7 @@ func (ClusterRoleList) SwaggerDoc() map[string]string { var map_PolicyRule = map[string]string{ "": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.", "verbs": "Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.", - "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.", + "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"\" represents the core API group and \"*\" represents all API groups.", "resources": "Resources is a list of resources this rule applies to. '*' represents all resources.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.", diff --git a/vendor/k8s.io/api/rbac/v1beta1/generated.proto b/vendor/k8s.io/api/rbac/v1beta1/generated.proto index c0988d1b61b..f6b2f0dde1a 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1beta1/generated.proto @@ -100,7 +100,7 @@ message PolicyRule { repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional repeated string apiGroups = 2; diff --git a/vendor/k8s.io/api/rbac/v1beta1/types.go b/vendor/k8s.io/api/rbac/v1beta1/types.go index 96e6b18f542..4941cd2abce 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/types.go +++ b/vendor/k8s.io/api/rbac/v1beta1/types.go @@ -51,7 +51,7 @@ type PolicyRule struct { Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of - // the enumerated resources in any API group will be allowed. + // the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` // Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. diff --git a/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go index 5d57cb348f0..fff1fe40fab 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ @@ -81,7 +81,7 @@ func (ClusterRoleList) SwaggerDoc() map[string]string { var map_PolicyRule = map[string]string{ "": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.", "verbs": "Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.", - "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.", + "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"\" represents the core API group and \"*\" represents all API groups.", "resources": "Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.", diff --git a/vendor/k8s.io/api/resource/v1alpha2/doc.go b/vendor/k8s.io/api/resource/v1alpha2/doc.go new file mode 100644 index 00000000000..d9c20e089d9 --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package + +// +groupName=resource.k8s.io + +// Package v1alpha2 is the v1alpha2 version of the resource API. +package v1alpha2 // import "k8s.io/api/resource/v1alpha2" diff --git a/vendor/k8s.io/api/resource/v1alpha2/generated.pb.go b/vendor/k8s.io/api/resource/v1alpha2/generated.pb.go new file mode 100644 index 00000000000..2e8f9c724a5 --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -0,0 +1,4817 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha2/generated.proto + +package v1alpha2 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + v1 "k8s.io/api/core/v1" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" + + k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *AllocationResult) Reset() { *m = AllocationResult{} } +func (*AllocationResult) ProtoMessage() {} +func (*AllocationResult) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{0} +} +func (m *AllocationResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AllocationResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *AllocationResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllocationResult.Merge(m, src) +} +func (m *AllocationResult) XXX_Size() int { + return m.Size() +} +func (m *AllocationResult) XXX_DiscardUnknown() { + xxx_messageInfo_AllocationResult.DiscardUnknown(m) +} + +var xxx_messageInfo_AllocationResult proto.InternalMessageInfo + +func (m *PodSchedulingContext) Reset() { *m = PodSchedulingContext{} } +func (*PodSchedulingContext) ProtoMessage() {} +func (*PodSchedulingContext) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{1} +} +func (m *PodSchedulingContext) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodSchedulingContext) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodSchedulingContext) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContext.Merge(m, src) +} +func (m *PodSchedulingContext) XXX_Size() int { + return m.Size() +} +func (m *PodSchedulingContext) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContext.DiscardUnknown(m) +} + +var xxx_messageInfo_PodSchedulingContext proto.InternalMessageInfo + +func (m *PodSchedulingContextList) Reset() { *m = PodSchedulingContextList{} } +func (*PodSchedulingContextList) ProtoMessage() {} +func (*PodSchedulingContextList) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{2} +} +func (m *PodSchedulingContextList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodSchedulingContextList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodSchedulingContextList) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextList.Merge(m, src) +} +func (m *PodSchedulingContextList) XXX_Size() int { + return m.Size() +} +func (m *PodSchedulingContextList) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextList.DiscardUnknown(m) +} + +var xxx_messageInfo_PodSchedulingContextList proto.InternalMessageInfo + +func (m *PodSchedulingContextSpec) Reset() { *m = PodSchedulingContextSpec{} } +func (*PodSchedulingContextSpec) ProtoMessage() {} +func (*PodSchedulingContextSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{3} +} +func (m *PodSchedulingContextSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodSchedulingContextSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodSchedulingContextSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextSpec.Merge(m, src) +} +func (m *PodSchedulingContextSpec) XXX_Size() int { + return m.Size() +} +func (m *PodSchedulingContextSpec) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_PodSchedulingContextSpec proto.InternalMessageInfo + +func (m *PodSchedulingContextStatus) Reset() { *m = PodSchedulingContextStatus{} } +func (*PodSchedulingContextStatus) ProtoMessage() {} +func (*PodSchedulingContextStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{4} +} +func (m *PodSchedulingContextStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PodSchedulingContextStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PodSchedulingContextStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextStatus.Merge(m, src) +} +func (m *PodSchedulingContextStatus) XXX_Size() int { + return m.Size() +} +func (m *PodSchedulingContextStatus) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_PodSchedulingContextStatus proto.InternalMessageInfo + +func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } +func (*ResourceClaim) ProtoMessage() {} +func (*ResourceClaim) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{5} +} +func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaim) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaim.Merge(m, src) +} +func (m *ResourceClaim) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaim) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaim.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo + +func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } +func (*ResourceClaimConsumerReference) ProtoMessage() {} +func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{6} +} +func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimConsumerReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimConsumerReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimConsumerReference.Merge(m, src) +} +func (m *ResourceClaimConsumerReference) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimConsumerReference) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimConsumerReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo + +func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } +func (*ResourceClaimList) ProtoMessage() {} +func (*ResourceClaimList) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{7} +} +func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimList.Merge(m, src) +} +func (m *ResourceClaimList) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo + +func (m *ResourceClaimParametersReference) Reset() { *m = ResourceClaimParametersReference{} } +func (*ResourceClaimParametersReference) ProtoMessage() {} +func (*ResourceClaimParametersReference) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{8} +} +func (m *ResourceClaimParametersReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimParametersReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimParametersReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimParametersReference.Merge(m, src) +} +func (m *ResourceClaimParametersReference) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimParametersReference) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimParametersReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimParametersReference proto.InternalMessageInfo + +func (m *ResourceClaimSchedulingStatus) Reset() { *m = ResourceClaimSchedulingStatus{} } +func (*ResourceClaimSchedulingStatus) ProtoMessage() {} +func (*ResourceClaimSchedulingStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{9} +} +func (m *ResourceClaimSchedulingStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimSchedulingStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimSchedulingStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimSchedulingStatus.Merge(m, src) +} +func (m *ResourceClaimSchedulingStatus) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimSchedulingStatus) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimSchedulingStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimSchedulingStatus proto.InternalMessageInfo + +func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } +func (*ResourceClaimSpec) ProtoMessage() {} +func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{10} +} +func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimSpec.Merge(m, src) +} +func (m *ResourceClaimSpec) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo + +func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } +func (*ResourceClaimStatus) ProtoMessage() {} +func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{11} +} +func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimStatus.Merge(m, src) +} +func (m *ResourceClaimStatus) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimStatus) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo + +func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } +func (*ResourceClaimTemplate) ProtoMessage() {} +func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{12} +} +func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimTemplate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimTemplate) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimTemplate.Merge(m, src) +} +func (m *ResourceClaimTemplate) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimTemplate) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimTemplate.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo + +func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } +func (*ResourceClaimTemplateList) ProtoMessage() {} +func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{13} +} +func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimTemplateList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimTemplateList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimTemplateList.Merge(m, src) +} +func (m *ResourceClaimTemplateList) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimTemplateList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimTemplateList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo + +func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } +func (*ResourceClaimTemplateSpec) ProtoMessage() {} +func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{14} +} +func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClaimTemplateSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClaimTemplateSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClaimTemplateSpec.Merge(m, src) +} +func (m *ResourceClaimTemplateSpec) XXX_Size() int { + return m.Size() +} +func (m *ResourceClaimTemplateSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClaimTemplateSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo + +func (m *ResourceClass) Reset() { *m = ResourceClass{} } +func (*ResourceClass) ProtoMessage() {} +func (*ResourceClass) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{15} +} +func (m *ResourceClass) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClass) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClass) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClass.Merge(m, src) +} +func (m *ResourceClass) XXX_Size() int { + return m.Size() +} +func (m *ResourceClass) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClass.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClass proto.InternalMessageInfo + +func (m *ResourceClassList) Reset() { *m = ResourceClassList{} } +func (*ResourceClassList) ProtoMessage() {} +func (*ResourceClassList) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{16} +} +func (m *ResourceClassList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClassList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClassList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClassList.Merge(m, src) +} +func (m *ResourceClassList) XXX_Size() int { + return m.Size() +} +func (m *ResourceClassList) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClassList.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClassList proto.InternalMessageInfo + +func (m *ResourceClassParametersReference) Reset() { *m = ResourceClassParametersReference{} } +func (*ResourceClassParametersReference) ProtoMessage() {} +func (*ResourceClassParametersReference) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{17} +} +func (m *ResourceClassParametersReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceClassParametersReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceClassParametersReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceClassParametersReference.Merge(m, src) +} +func (m *ResourceClassParametersReference) XXX_Size() int { + return m.Size() +} +func (m *ResourceClassParametersReference) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceClassParametersReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceClassParametersReference proto.InternalMessageInfo + +func (m *ResourceHandle) Reset() { *m = ResourceHandle{} } +func (*ResourceHandle) ProtoMessage() {} +func (*ResourceHandle) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{18} +} +func (m *ResourceHandle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceHandle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ResourceHandle) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceHandle.Merge(m, src) +} +func (m *ResourceHandle) XXX_Size() int { + return m.Size() +} +func (m *ResourceHandle) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceHandle.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceHandle proto.InternalMessageInfo + +func init() { + proto.RegisterType((*AllocationResult)(nil), "k8s.io.api.resource.v1alpha2.AllocationResult") + proto.RegisterType((*PodSchedulingContext)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContext") + proto.RegisterType((*PodSchedulingContextList)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextList") + proto.RegisterType((*PodSchedulingContextSpec)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextSpec") + proto.RegisterType((*PodSchedulingContextStatus)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextStatus") + proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaim") + proto.RegisterType((*ResourceClaimConsumerReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimConsumerReference") + proto.RegisterType((*ResourceClaimList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimList") + proto.RegisterType((*ResourceClaimParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimParametersReference") + proto.RegisterType((*ResourceClaimSchedulingStatus)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSchedulingStatus") + proto.RegisterType((*ResourceClaimSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSpec") + proto.RegisterType((*ResourceClaimStatus)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimStatus") + proto.RegisterType((*ResourceClaimTemplate)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplate") + proto.RegisterType((*ResourceClaimTemplateList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplateList") + proto.RegisterType((*ResourceClaimTemplateSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplateSpec") + proto.RegisterType((*ResourceClass)(nil), "k8s.io.api.resource.v1alpha2.ResourceClass") + proto.RegisterType((*ResourceClassList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassList") + proto.RegisterType((*ResourceClassParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassParametersReference") + proto.RegisterType((*ResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.ResourceHandle") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha2/generated.proto", fileDescriptor_3add37bbd52889e0) +} + +var fileDescriptor_3add37bbd52889e0 = []byte{ + // 1233 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xcf, 0xda, 0x6e, 0x95, 0x4c, 0x1a, 0x37, 0xd9, 0xb6, 0xe0, 0x46, 0xad, 0x63, 0xf6, 0x14, + 0x89, 0xb2, 0xdb, 0x06, 0x54, 0x2a, 0xfe, 0x49, 0xd9, 0x06, 0x4a, 0x04, 0x4d, 0xc3, 0x98, 0x8a, + 0x16, 0x21, 0xd4, 0xc9, 0xee, 0xab, 0xbd, 0x64, 0xff, 0xb1, 0x33, 0x6b, 0xa8, 0xb8, 0xf4, 0x23, + 0xf4, 0xc0, 0x01, 0x4e, 0x1c, 0xf9, 0x02, 0x7c, 0x03, 0x84, 0xd4, 0x63, 0x11, 0x1c, 0x7a, 0xb2, + 0xa8, 0xf9, 0x08, 0x9c, 0xe8, 0x09, 0xcd, 0x78, 0x77, 0xbd, 0xb3, 0xf6, 0x9a, 0x38, 0x07, 0x0b, + 0x4e, 0xc9, 0xcc, 0xfb, 0xbd, 0xdf, 0xfb, 0x37, 0xef, 0xcd, 0xac, 0xd1, 0xbb, 0x87, 0xd7, 0xa8, + 0xee, 0x04, 0xc6, 0x61, 0x7c, 0x00, 0x91, 0x0f, 0x0c, 0xa8, 0xd1, 0x03, 0xdf, 0x0e, 0x22, 0x23, + 0x11, 0x90, 0xd0, 0x31, 0x22, 0xa0, 0x41, 0x1c, 0x59, 0x60, 0xf4, 0xae, 0x10, 0x37, 0xec, 0x92, + 0x2d, 0xa3, 0x03, 0x3e, 0x44, 0x84, 0x81, 0xad, 0x87, 0x51, 0xc0, 0x02, 0xf5, 0xc2, 0x10, 0xad, + 0x93, 0xd0, 0xd1, 0x53, 0xb4, 0x9e, 0xa2, 0xd7, 0x5f, 0xe9, 0x38, 0xac, 0x1b, 0x1f, 0xe8, 0x56, + 0xe0, 0x19, 0x9d, 0xa0, 0x13, 0x18, 0x42, 0xe9, 0x20, 0xbe, 0x2f, 0x56, 0x62, 0x21, 0xfe, 0x1b, + 0x92, 0xad, 0x6b, 0x39, 0xd3, 0x56, 0x10, 0x71, 0xb3, 0x45, 0x83, 0xeb, 0xaf, 0x8d, 0x30, 0x1e, + 0xb1, 0xba, 0x8e, 0x0f, 0xd1, 0x03, 0x23, 0x3c, 0xec, 0xf0, 0x0d, 0x6a, 0x78, 0xc0, 0xc8, 0x24, + 0x2d, 0xa3, 0x4c, 0x2b, 0x8a, 0x7d, 0xe6, 0x78, 0x30, 0xa6, 0x70, 0xf5, 0xdf, 0x14, 0xa8, 0xd5, + 0x05, 0x8f, 0x14, 0xf5, 0xb4, 0xef, 0x2a, 0x68, 0x75, 0xdb, 0x75, 0x03, 0x8b, 0x30, 0x27, 0xf0, + 0x31, 0xd0, 0xd8, 0x65, 0x6a, 0x80, 0x4e, 0xa7, 0xb9, 0x79, 0x9f, 0xf8, 0xb6, 0x0b, 0xb4, 0xa1, + 0xb4, 0xaa, 0x9b, 0xcb, 0x5b, 0x97, 0xf4, 0x69, 0xe9, 0xd3, 0xb1, 0xa4, 0x64, 0xbe, 0xf8, 0xb8, + 0xbf, 0xb1, 0x30, 0xe8, 0x6f, 0x9c, 0x96, 0xf7, 0x29, 0x2e, 0xb2, 0xab, 0x07, 0x68, 0x95, 0xf4, + 0x88, 0xe3, 0x92, 0x03, 0x17, 0x6e, 0xf9, 0x7b, 0x81, 0x0d, 0xb4, 0x51, 0x69, 0x29, 0x9b, 0xcb, + 0x5b, 0xad, 0xbc, 0x45, 0x9e, 0x63, 0xbd, 0x77, 0x45, 0xe7, 0x80, 0x36, 0xb8, 0x60, 0xb1, 0x20, + 0x32, 0xcf, 0x0e, 0xfa, 0x1b, 0xab, 0xdb, 0x05, 0x6d, 0x3c, 0xc6, 0xa7, 0x1a, 0x68, 0x89, 0x76, + 0x49, 0x04, 0x7c, 0xaf, 0x51, 0x6d, 0x29, 0x9b, 0x8b, 0xe6, 0x5a, 0xe2, 0xe0, 0x52, 0x3b, 0x15, + 0xe0, 0x11, 0x46, 0xfb, 0xa9, 0x82, 0xce, 0xee, 0x07, 0x76, 0xdb, 0xea, 0x82, 0x1d, 0xbb, 0x8e, + 0xdf, 0xb9, 0x1e, 0xf8, 0x0c, 0xbe, 0x66, 0xea, 0x3d, 0xb4, 0xc8, 0xeb, 0x66, 0x13, 0x46, 0x1a, + 0x8a, 0xf0, 0xf2, 0x72, 0xce, 0xcb, 0x2c, 0xfd, 0x7a, 0x78, 0xd8, 0xe1, 0x1b, 0x54, 0xe7, 0x68, + 0xee, 0xf7, 0xad, 0x83, 0x2f, 0xc0, 0x62, 0x37, 0x81, 0x11, 0x53, 0x4d, 0x4c, 0xa3, 0xd1, 0x1e, + 0xce, 0x58, 0xd5, 0x3b, 0xa8, 0x46, 0x43, 0xb0, 0x92, 0x1c, 0x5c, 0x9d, 0x9e, 0xf5, 0x49, 0x3e, + 0xb6, 0x43, 0xb0, 0xcc, 0x53, 0x89, 0x8d, 0x1a, 0x5f, 0x61, 0xc1, 0xa8, 0xde, 0x43, 0x27, 0x29, + 0x23, 0x2c, 0xa6, 0x22, 0x05, 0xcb, 0x5b, 0xd7, 0x8e, 0xc1, 0x2d, 0xf4, 0xcd, 0x7a, 0xc2, 0x7e, + 0x72, 0xb8, 0xc6, 0x09, 0xaf, 0xf6, 0xab, 0x82, 0x1a, 0x93, 0xd4, 0x3e, 0x74, 0x28, 0x53, 0x3f, + 0x1b, 0x4b, 0x9d, 0x7e, 0xb4, 0xd4, 0x71, 0x6d, 0x91, 0xb8, 0xd5, 0xc4, 0xec, 0x62, 0xba, 0x93, + 0x4b, 0xdb, 0x27, 0xe8, 0x84, 0xc3, 0xc0, 0xe3, 0x67, 0x87, 0x9f, 0xd6, 0xad, 0xd9, 0x63, 0x33, + 0x57, 0x12, 0xfa, 0x13, 0xbb, 0x9c, 0x08, 0x0f, 0xf9, 0xb4, 0x47, 0x25, 0x31, 0xf1, 0xc4, 0xaa, + 0xd7, 0xd0, 0x29, 0x2a, 0x0e, 0x23, 0xd8, 0xfc, 0xa4, 0x89, 0xb8, 0x96, 0xcc, 0xb3, 0x09, 0xd1, + 0xa9, 0x76, 0x4e, 0x86, 0x25, 0xa4, 0xfa, 0x06, 0xaa, 0x87, 0x01, 0x03, 0x9f, 0x39, 0xc4, 0x4d, + 0x0f, 0x7d, 0x75, 0x73, 0xc9, 0x54, 0x07, 0xfd, 0x8d, 0xfa, 0xbe, 0x24, 0xc1, 0x05, 0xa4, 0xf6, + 0xbd, 0x82, 0xd6, 0xcb, 0xab, 0xa3, 0x7e, 0x83, 0xea, 0x69, 0xc4, 0xd7, 0x5d, 0xe2, 0x78, 0x69, + 0x07, 0xbf, 0x79, 0xb4, 0x0e, 0x16, 0x3a, 0x23, 0xee, 0xa4, 0xe4, 0x2f, 0x24, 0x31, 0xd5, 0x25, + 0x18, 0xc5, 0x05, 0x53, 0xda, 0x0f, 0x15, 0xb4, 0x22, 0x41, 0xe6, 0xd0, 0x32, 0x1f, 0x49, 0x2d, + 0x63, 0xcc, 0x12, 0x66, 0x59, 0xaf, 0xdc, 0x2d, 0xf4, 0xca, 0x95, 0x59, 0x48, 0xa7, 0x37, 0xc9, + 0x40, 0x41, 0x4d, 0x09, 0x7f, 0x3d, 0xf0, 0x69, 0xec, 0x41, 0x84, 0xe1, 0x3e, 0x44, 0xe0, 0x5b, + 0xa0, 0x5e, 0x42, 0x8b, 0x24, 0x74, 0x6e, 0x44, 0x41, 0x1c, 0x26, 0x47, 0x2a, 0x3b, 0xfa, 0xdb, + 0xfb, 0xbb, 0x62, 0x1f, 0x67, 0x08, 0x8e, 0x4e, 0x3d, 0x12, 0xde, 0xe6, 0xd0, 0xa9, 0x1d, 0x9c, + 0x21, 0xd4, 0x16, 0xaa, 0xf9, 0xc4, 0x83, 0x46, 0x4d, 0x20, 0xb3, 0xd8, 0xf7, 0x88, 0x07, 0x58, + 0x48, 0x54, 0x13, 0x55, 0x63, 0xc7, 0x6e, 0x9c, 0x10, 0x80, 0xcb, 0x09, 0xa0, 0x7a, 0x7b, 0x77, + 0xe7, 0x79, 0x7f, 0xe3, 0xa5, 0xb2, 0xbb, 0x86, 0x3d, 0x08, 0x81, 0xea, 0xb7, 0x77, 0x77, 0x30, + 0x57, 0xd6, 0x7e, 0x56, 0xd0, 0x9a, 0x14, 0xe4, 0x1c, 0x46, 0xc0, 0xbe, 0x3c, 0x02, 0x5e, 0x9e, + 0xa1, 0x64, 0x25, 0xbd, 0xff, 0xad, 0x82, 0x5a, 0x12, 0x6e, 0x9f, 0x44, 0xc4, 0x03, 0x06, 0x11, + 0x3d, 0x6e, 0xb1, 0x5a, 0xa8, 0x76, 0xe8, 0xf8, 0xb6, 0x38, 0xab, 0xb9, 0xf4, 0x7f, 0xe0, 0xf8, + 0x36, 0x16, 0x92, 0xac, 0x40, 0xd5, 0xb2, 0x02, 0x69, 0x0f, 0x15, 0x74, 0x71, 0x6a, 0xb7, 0x66, + 0x1c, 0x4a, 0x69, 0x91, 0xdf, 0x46, 0xa7, 0x63, 0x9f, 0xc6, 0x0e, 0xe3, 0xf7, 0x5d, 0x7e, 0x00, + 0x9d, 0xe1, 0xb7, 0xf6, 0x6d, 0x59, 0x84, 0x8b, 0x58, 0xed, 0xc7, 0x4a, 0xa1, 0xbe, 0x62, 0x1c, + 0xde, 0x40, 0x6b, 0xb9, 0x71, 0x40, 0xe9, 0xde, 0xc8, 0x87, 0xf3, 0x89, 0x0f, 0x79, 0xad, 0x21, + 0x00, 0x8f, 0xeb, 0xa8, 0x5f, 0xa1, 0x95, 0x30, 0x9f, 0xea, 0xa4, 0xb5, 0xdf, 0x99, 0xa1, 0xa4, + 0x13, 0x4a, 0x65, 0xae, 0x0d, 0xfa, 0x1b, 0x2b, 0x92, 0x00, 0xcb, 0x76, 0xd4, 0x7d, 0x54, 0x27, + 0xd9, 0x93, 0xe8, 0x26, 0x1f, 0xe9, 0xc3, 0x32, 0x6c, 0xa6, 0xe3, 0x6f, 0x5b, 0x92, 0x3e, 0x1f, + 0xdb, 0xc1, 0x05, 0x7d, 0xed, 0xaf, 0x0a, 0x3a, 0x33, 0x61, 0x3c, 0xa8, 0x5b, 0x08, 0xd9, 0x91, + 0xd3, 0x83, 0x28, 0x97, 0xa4, 0x6c, 0xcc, 0xed, 0x64, 0x12, 0x9c, 0x43, 0xa9, 0x9f, 0x23, 0x34, + 0x62, 0x4f, 0x72, 0xa2, 0x4f, 0xcf, 0x49, 0xf1, 0x81, 0x67, 0xd6, 0x39, 0x7f, 0x6e, 0x37, 0xc7, + 0xa8, 0x52, 0xb4, 0x1c, 0x01, 0x85, 0xa8, 0x07, 0xf6, 0x7b, 0x41, 0xd4, 0xa8, 0x8a, 0x3e, 0x7a, + 0x6b, 0x86, 0xa4, 0x8f, 0x8d, 0x32, 0xf3, 0x4c, 0x12, 0xd2, 0x32, 0x1e, 0x11, 0xe3, 0xbc, 0x15, + 0xb5, 0x8d, 0xce, 0xd9, 0x40, 0x72, 0x6e, 0x7e, 0x19, 0x03, 0x65, 0x60, 0x8b, 0x09, 0xb5, 0x68, + 0x5e, 0x4c, 0x08, 0xce, 0xed, 0x4c, 0x02, 0xe1, 0xc9, 0xba, 0xda, 0xef, 0x0a, 0x3a, 0x27, 0x79, + 0xf6, 0x31, 0x78, 0xa1, 0x4b, 0x18, 0xcc, 0xe1, 0x3a, 0xba, 0x2b, 0x5d, 0x47, 0xaf, 0xcf, 0x90, + 0xbe, 0xd4, 0xc9, 0xb2, 0x6b, 0x49, 0xfb, 0x4d, 0x41, 0xe7, 0x27, 0x6a, 0xcc, 0x61, 0xbc, 0xde, + 0x91, 0xc7, 0xeb, 0xab, 0xc7, 0x88, 0xab, 0x64, 0xcc, 0x3e, 0x29, 0x8b, 0xaa, 0x3d, 0x7c, 0xb6, + 0xfe, 0xff, 0xde, 0x0f, 0xda, 0xdf, 0xf2, 0x33, 0x88, 0xd2, 0x39, 0x84, 0x21, 0x4f, 0x94, 0xca, + 0x91, 0x26, 0xca, 0xd8, 0xa0, 0xad, 0xce, 0x38, 0x68, 0x29, 0x3d, 0xde, 0xa0, 0xbd, 0x8b, 0x56, + 0xe4, 0xdb, 0xa7, 0x76, 0xc4, 0x6f, 0x3e, 0x41, 0xdd, 0x96, 0x6e, 0x27, 0x99, 0xa9, 0xf8, 0xf6, + 0xa0, 0xf4, 0xbf, 0xfc, 0xf6, 0xa0, 0xb4, 0xa4, 0x29, 0x7e, 0x91, 0xdf, 0x1e, 0x13, 0xf3, 0x3c, + 0xff, 0xb7, 0x07, 0xff, 0x94, 0xe6, 0x7f, 0x69, 0x48, 0xac, 0xf4, 0x0d, 0x99, 0x7d, 0x4a, 0xef, + 0xa5, 0x02, 0x3c, 0xc2, 0x68, 0xf7, 0x51, 0x5d, 0xfe, 0x0d, 0xe0, 0x58, 0x37, 0x5f, 0x0b, 0xd5, + 0x44, 0xe5, 0x0a, 0xae, 0xef, 0x10, 0x46, 0xb0, 0x90, 0x98, 0xe6, 0xe3, 0x67, 0xcd, 0x85, 0x27, + 0xcf, 0x9a, 0x0b, 0x4f, 0x9f, 0x35, 0x17, 0x1e, 0x0e, 0x9a, 0xca, 0xe3, 0x41, 0x53, 0x79, 0x32, + 0x68, 0x2a, 0x4f, 0x07, 0x4d, 0xe5, 0x8f, 0x41, 0x53, 0x79, 0xf4, 0x67, 0x73, 0xe1, 0xd3, 0x0b, + 0xd3, 0x7e, 0x31, 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0x67, 0xe4, 0xf6, 0x18, 0x69, 0x12, 0x00, + 0x00, +} + +func (m *AllocationResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AllocationResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i-- + if m.Shareable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + if m.AvailableOnNodes != nil { + { + size, err := m.AvailableOnNodes.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ResourceHandles) > 0 { + for iNdEx := len(m.ResourceHandles) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceHandles[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PodSchedulingContext) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingContext) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingContext) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodSchedulingContextList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingContextList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingContextList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodSchedulingContextSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingContextSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingContextSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PotentialNodes) > 0 { + for iNdEx := len(m.PotentialNodes) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.PotentialNodes[iNdEx]) + copy(dAtA[i:], m.PotentialNodes[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PotentialNodes[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.SelectedNode) + copy(dAtA[i:], m.SelectedNode) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SelectedNode))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodSchedulingContextStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingContextStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingContextStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ResourceClaims) > 0 { + for iNdEx := len(m.ResourceClaims) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceClaims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ResourceClaim) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaim) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimConsumerReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimConsumerReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimConsumerReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.UID) + copy(dAtA[i:], m.UID) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) + i-- + dAtA[i] = 0x2a + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + i -= len(m.Resource) + copy(dAtA[i:], m.Resource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + i-- + dAtA[i] = 0x1a + i -= len(m.APIGroup) + copy(dAtA[i:], m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimParametersReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimParametersReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimParametersReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIGroup) + copy(dAtA[i:], m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimSchedulingStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimSchedulingStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimSchedulingStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.UnsuitableNodes) > 0 { + for iNdEx := len(m.UnsuitableNodes) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UnsuitableNodes[iNdEx]) + copy(dAtA[i:], m.UnsuitableNodes[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UnsuitableNodes[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.AllocationMode) + copy(dAtA[i:], m.AllocationMode) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllocationMode))) + i-- + dAtA[i] = 0x1a + if m.ParametersRef != nil { + { + size, err := m.ParametersRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.ResourceClassName) + copy(dAtA[i:], m.ResourceClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceClassName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i-- + if m.DeallocationRequested { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + if len(m.ReservedFor) > 0 { + for iNdEx := len(m.ReservedFor) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ReservedFor[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Allocation != nil { + { + size, err := m.Allocation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimTemplate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimTemplate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimTemplateList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimTemplateList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplateList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimTemplateSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimTemplateSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClass) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClass) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClass) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SuitableNodes != nil { + { + size, err := m.SuitableNodes.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.ParametersRef != nil { + { + size, err := m.ParametersRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClassList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClassList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClassList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClassParametersReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClassParametersReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClassParametersReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x22 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIGroup) + copy(dAtA[i:], m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceHandle) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceHandle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceHandle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AllocationResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ResourceHandles) > 0 { + for _, e := range m.ResourceHandles { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.AvailableOnNodes != nil { + l = m.AvailableOnNodes.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 2 + return n +} + +func (m *PodSchedulingContext) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PodSchedulingContextList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PodSchedulingContextSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SelectedNode) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.PotentialNodes) > 0 { + for _, s := range m.PotentialNodes { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PodSchedulingContextStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ResourceClaims) > 0 { + for _, e := range m.ResourceClaims { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimConsumerReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Resource) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimParametersReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimSchedulingStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.UnsuitableNodes) > 0 { + for _, s := range m.UnsuitableNodes { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ResourceClassName) + n += 1 + l + sovGenerated(uint64(l)) + if m.ParametersRef != nil { + l = m.ParametersRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.AllocationMode) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + if m.Allocation != nil { + l = m.Allocation.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ReservedFor) > 0 { + for _, e := range m.ReservedFor { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + n += 2 + return n +} + +func (m *ResourceClaimTemplate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimTemplateList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimTemplateSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClass) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + if m.ParametersRef != nil { + l = m.ParametersRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.SuitableNodes != nil { + l = m.SuitableNodes.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *ResourceClassList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClassParametersReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceHandle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Data) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *AllocationResult) String() string { + if this == nil { + return "nil" + } + repeatedStringForResourceHandles := "[]ResourceHandle{" + for _, f := range this.ResourceHandles { + repeatedStringForResourceHandles += strings.Replace(strings.Replace(f.String(), "ResourceHandle", "ResourceHandle", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceHandles += "}" + s := strings.Join([]string{`&AllocationResult{`, + `ResourceHandles:` + repeatedStringForResourceHandles + `,`, + `AvailableOnNodes:` + strings.Replace(fmt.Sprintf("%v", this.AvailableOnNodes), "NodeSelector", "v1.NodeSelector", 1) + `,`, + `Shareable:` + fmt.Sprintf("%v", this.Shareable) + `,`, + `}`, + }, "") + return s +} +func (this *PodSchedulingContext) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodSchedulingContext{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodSchedulingContextSpec", "PodSchedulingContextSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "PodSchedulingContextStatus", "PodSchedulingContextStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *PodSchedulingContextList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]PodSchedulingContext{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodSchedulingContext", "PodSchedulingContext", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&PodSchedulingContextList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *PodSchedulingContextSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodSchedulingContextSpec{`, + `SelectedNode:` + fmt.Sprintf("%v", this.SelectedNode) + `,`, + `PotentialNodes:` + fmt.Sprintf("%v", this.PotentialNodes) + `,`, + `}`, + }, "") + return s +} +func (this *PodSchedulingContextStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForResourceClaims := "[]ResourceClaimSchedulingStatus{" + for _, f := range this.ResourceClaims { + repeatedStringForResourceClaims += strings.Replace(strings.Replace(f.String(), "ResourceClaimSchedulingStatus", "ResourceClaimSchedulingStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceClaims += "}" + s := strings.Join([]string{`&PodSchedulingContextStatus{`, + `ResourceClaims:` + repeatedStringForResourceClaims + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaim) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaim{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ResourceClaimSpec", "ResourceClaimSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ResourceClaimStatus", "ResourceClaimStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimConsumerReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimConsumerReference{`, + `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceClaim{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceClaim", "ResourceClaim", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceClaimList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimParametersReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimParametersReference{`, + `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimSchedulingStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimSchedulingStatus{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `UnsuitableNodes:` + fmt.Sprintf("%v", this.UnsuitableNodes) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimSpec{`, + `ResourceClassName:` + fmt.Sprintf("%v", this.ResourceClassName) + `,`, + `ParametersRef:` + strings.Replace(this.ParametersRef.String(), "ResourceClaimParametersReference", "ResourceClaimParametersReference", 1) + `,`, + `AllocationMode:` + fmt.Sprintf("%v", this.AllocationMode) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForReservedFor := "[]ResourceClaimConsumerReference{" + for _, f := range this.ReservedFor { + repeatedStringForReservedFor += strings.Replace(strings.Replace(f.String(), "ResourceClaimConsumerReference", "ResourceClaimConsumerReference", 1), `&`, ``, 1) + "," + } + repeatedStringForReservedFor += "}" + s := strings.Join([]string{`&ResourceClaimStatus{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `Allocation:` + strings.Replace(this.Allocation.String(), "AllocationResult", "AllocationResult", 1) + `,`, + `ReservedFor:` + repeatedStringForReservedFor + `,`, + `DeallocationRequested:` + fmt.Sprintf("%v", this.DeallocationRequested) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimTemplate) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimTemplate{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ResourceClaimTemplateSpec", "ResourceClaimTemplateSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimTemplateList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceClaimTemplate{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceClaimTemplate", "ResourceClaimTemplate", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceClaimTemplateList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClaimTemplateSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClaimTemplateSpec{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ResourceClaimSpec", "ResourceClaimSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClass) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClass{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `ParametersRef:` + strings.Replace(this.ParametersRef.String(), "ResourceClassParametersReference", "ResourceClassParametersReference", 1) + `,`, + `SuitableNodes:` + strings.Replace(fmt.Sprintf("%v", this.SuitableNodes), "NodeSelector", "v1.NodeSelector", 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClassList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourceClass{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourceClass", "ResourceClass", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourceClassList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ResourceClassParametersReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceClassParametersReference{`, + `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceHandle) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceHandle{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *AllocationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllocationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceHandles", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceHandles = append(m.ResourceHandles, ResourceHandle{}) + if err := m.ResourceHandles[len(m.ResourceHandles)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AvailableOnNodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AvailableOnNodes == nil { + m.AvailableOnNodes = &v1.NodeSelector{} + } + if err := m.AvailableOnNodes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Shareable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Shareable = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodSchedulingContext) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodSchedulingContext: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodSchedulingContext: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodSchedulingContextList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodSchedulingContextList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodSchedulingContextList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, PodSchedulingContext{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodSchedulingContextSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodSchedulingContextSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodSchedulingContextSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SelectedNode", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SelectedNode = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PotentialNodes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PotentialNodes = append(m.PotentialNodes, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodSchedulingContextStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodSchedulingContextStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodSchedulingContextStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaims = append(m.ResourceClaims, ResourceClaimSchedulingStatus{}) + if err := m.ResourceClaims[len(m.ResourceClaims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaim) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaim: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimConsumerReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimConsumerReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimConsumerReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIGroup = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UID = k8s_io_apimachinery_pkg_types.UID(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceClaim{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimParametersReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimParametersReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimParametersReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIGroup = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimSchedulingStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimSchedulingStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimSchedulingStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnsuitableNodes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnsuitableNodes = append(m.UnsuitableNodes, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClassName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClassName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParametersRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParametersRef == nil { + m.ParametersRef = &ResourceClaimParametersReference{} + } + if err := m.ParametersRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMode", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllocationMode = AllocationMode(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allocation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Allocation == nil { + m.Allocation = &AllocationResult{} + } + if err := m.Allocation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReservedFor", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ReservedFor = append(m.ReservedFor, ResourceClaimConsumerReference{}) + if err := m.ReservedFor[len(m.ReservedFor)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeallocationRequested", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DeallocationRequested = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimTemplate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimTemplate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimTemplateList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimTemplateList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimTemplateList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceClaimTemplate{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClaimTemplateSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClaimTemplateSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClaimTemplateSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClass) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClass: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClass: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParametersRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParametersRef == nil { + m.ParametersRef = &ResourceClassParametersReference{} + } + if err := m.ParametersRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SuitableNodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SuitableNodes == nil { + m.SuitableNodes = &v1.NodeSelector{} + } + if err := m.SuitableNodes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClassList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClassList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClassList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ResourceClass{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceClassParametersReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceClassParametersReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceClassParametersReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIGroup = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceHandle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceHandle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceHandle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/resource/v1alpha2/generated.proto b/vendor/k8s.io/api/resource/v1alpha2/generated.proto new file mode 100644 index 00000000000..02412398c43 --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/generated.proto @@ -0,0 +1,400 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.resource.v1alpha2; + +import "k8s.io/api/core/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/resource/v1alpha2"; + +// AllocationResult contains attributes of an allocated resource. +message AllocationResult { + // ResourceHandles contain the state associated with an allocation that + // should be maintained throughout the lifetime of a claim. Each + // ResourceHandle contains data that should be passed to a specific kubelet + // plugin once it lands on a node. This data is returned by the driver + // after a successful allocation and is opaque to Kubernetes. Driver + // documentation may explain to users how to interpret this data if needed. + // + // Setting this field is optional. It has a maximum size of 32 entries. + // If null (or empty), it is assumed this allocation will be processed by a + // single kubelet plugin with no ResourceHandle data attached. The name of + // the kubelet plugin invoked will match the DriverName set in the + // ResourceClaimStatus this AllocationResult is embedded in. + // + // +listType=atomic + // +optional + repeated ResourceHandle resourceHandles = 1; + + // This field will get set by the resource driver after it has allocated + // the resource to inform the scheduler where it can schedule Pods using + // the ResourceClaim. + // + // Setting this field is optional. If null, the resource is available + // everywhere. + // +optional + optional k8s.io.api.core.v1.NodeSelector availableOnNodes = 2; + + // Shareable determines whether the resource supports more + // than one consumer at a time. + // +optional + optional bool shareable = 3; +} + +// PodSchedulingContext objects hold information that is needed to schedule +// a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation +// mode. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +message PodSchedulingContext { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec describes where resources for the Pod are needed. + optional PodSchedulingContextSpec spec = 2; + + // Status describes where resources for the Pod can be allocated. + // +optional + optional PodSchedulingContextStatus status = 3; +} + +// PodSchedulingContextList is a collection of Pod scheduling objects. +message PodSchedulingContextList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of PodSchedulingContext objects. + repeated PodSchedulingContext items = 2; +} + +// PodSchedulingContextSpec describes where resources for the Pod are needed. +message PodSchedulingContextSpec { + // SelectedNode is the node for which allocation of ResourceClaims that + // are referenced by the Pod and that use "WaitForFirstConsumer" + // allocation is to be attempted. + // +optional + optional string selectedNode = 1; + + // PotentialNodes lists nodes where the Pod might be able to run. + // + // The size of this field is limited to 128. This is large enough for + // many clusters. Larger clusters may need more attempts to find a node + // that suits all pending resources. This may get increased in the + // future, but not reduced. + // + // +listType=set + // +optional + repeated string potentialNodes = 2; +} + +// PodSchedulingContextStatus describes where resources for the Pod can be allocated. +message PodSchedulingContextStatus { + // ResourceClaims describes resource availability for each + // pod.spec.resourceClaim entry where the corresponding ResourceClaim + // uses "WaitForFirstConsumer" allocation mode. + // + // +listType=map + // +listMapKey=name + // +optional + repeated ResourceClaimSchedulingStatus resourceClaims = 1; +} + +// ResourceClaim describes which resources are needed by a resource consumer. +// Its status tracks whether the resource has been allocated and what the +// resulting attributes are. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +message ResourceClaim { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec describes the desired attributes of a resource that then needs + // to be allocated. It can only be set once when creating the + // ResourceClaim. + optional ResourceClaimSpec spec = 2; + + // Status describes whether the resource is available and with which + // attributes. + // +optional + optional ResourceClaimStatus status = 3; +} + +// ResourceClaimConsumerReference contains enough information to let you +// locate the consumer of a ResourceClaim. The user must be a resource in the same +// namespace as the ResourceClaim. +message ResourceClaimConsumerReference { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + optional string apiGroup = 1; + + // Resource is the type of resource being referenced, for example "pods". + optional string resource = 3; + + // Name is the name of resource being referenced. + optional string name = 4; + + // UID identifies exactly one incarnation of the resource. + optional string uid = 5; +} + +// ResourceClaimList is a collection of claims. +message ResourceClaimList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of resource claims. + repeated ResourceClaim items = 2; +} + +// ResourceClaimParametersReference contains enough information to let you +// locate the parameters for a ResourceClaim. The object must be in the same +// namespace as the ResourceClaim. +message ResourceClaimParametersReference { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + optional string apiGroup = 1; + + // Kind is the type of resource being referenced. This is the same + // value as in the parameter object's metadata, for example "ConfigMap". + optional string kind = 2; + + // Name is the name of resource being referenced. + optional string name = 3; +} + +// ResourceClaimSchedulingStatus contains information about one particular +// ResourceClaim with "WaitForFirstConsumer" allocation mode. +message ResourceClaimSchedulingStatus { + // Name matches the pod.spec.resourceClaims[*].Name field. + // +optional + optional string name = 1; + + // UnsuitableNodes lists nodes that the ResourceClaim cannot be + // allocated for. + // + // The size of this field is limited to 128, the same as for + // PodSchedulingSpec.PotentialNodes. This may get increased in the + // future, but not reduced. + // + // +listType=set + // +optional + repeated string unsuitableNodes = 2; +} + +// ResourceClaimSpec defines how a resource is to be allocated. +message ResourceClaimSpec { + // ResourceClassName references the driver and additional parameters + // via the name of a ResourceClass that was created as part of the + // driver deployment. + optional string resourceClassName = 1; + + // ParametersRef references a separate object with arbitrary parameters + // that will be used by the driver when allocating a resource for the + // claim. + // + // The object must be in the same namespace as the ResourceClaim. + // +optional + optional ResourceClaimParametersReference parametersRef = 2; + + // Allocation can start immediately or when a Pod wants to use the + // resource. "WaitForFirstConsumer" is the default. + // +optional + optional string allocationMode = 3; +} + +// ResourceClaimStatus tracks whether the resource has been allocated and what +// the resulting attributes are. +message ResourceClaimStatus { + // DriverName is a copy of the driver name from the ResourceClass at + // the time when allocation started. + // +optional + optional string driverName = 1; + + // Allocation is set by the resource driver once a resource or set of + // resources has been allocated successfully. If this is not specified, the + // resources have not been allocated yet. + // +optional + optional AllocationResult allocation = 2; + + // ReservedFor indicates which entities are currently allowed to use + // the claim. A Pod which references a ResourceClaim which is not + // reserved for that Pod will not be started. + // + // There can be at most 32 such reservations. This may get increased in + // the future, but not reduced. + // + // +listType=map + // +listMapKey=uid + // +optional + repeated ResourceClaimConsumerReference reservedFor = 3; + + // DeallocationRequested indicates that a ResourceClaim is to be + // deallocated. + // + // The driver then must deallocate this claim and reset the field + // together with clearing the Allocation field. + // + // While DeallocationRequested is set, no new consumers may be added to + // ReservedFor. + // +optional + optional bool deallocationRequested = 4; +} + +// ResourceClaimTemplate is used to produce ResourceClaim objects. +message ResourceClaimTemplate { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Describes the ResourceClaim that is to be generated. + // + // This field is immutable. A ResourceClaim will get created by the + // control plane for a Pod when needed and then not get updated + // anymore. + optional ResourceClaimTemplateSpec spec = 2; +} + +// ResourceClaimTemplateList is a collection of claim templates. +message ResourceClaimTemplateList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of resource claim templates. + repeated ResourceClaimTemplate items = 2; +} + +// ResourceClaimTemplateSpec contains the metadata and fields for a ResourceClaim. +message ResourceClaimTemplateSpec { + // ObjectMeta may contain labels and annotations that will be copied into the PVC + // when creating it. No other fields are allowed and will be rejected during + // validation. + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec for the ResourceClaim. The entire content is copied unchanged + // into the ResourceClaim that gets created from this template. The + // same fields as in a ResourceClaim are also valid here. + optional ResourceClaimSpec spec = 2; +} + +// ResourceClass is used by administrators to influence how resources +// are allocated. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +message ResourceClass { + // Standard object metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // DriverName defines the name of the dynamic resource driver that is + // used for allocation of a ResourceClaim that uses this class. + // + // Resource drivers have a unique name in forward domain order + // (acme.example.com). + optional string driverName = 2; + + // ParametersRef references an arbitrary separate object that may hold + // parameters that will be used by the driver when allocating a + // resource that uses this class. A dynamic resource driver can + // distinguish between parameters stored here and and those stored in + // ResourceClaimSpec. + // +optional + optional ResourceClassParametersReference parametersRef = 3; + + // Only nodes matching the selector will be considered by the scheduler + // when trying to find a Node that fits a Pod when that Pod uses + // a ResourceClaim that has not been allocated yet. + // + // Setting this field is optional. If null, all nodes are candidates. + // +optional + optional k8s.io.api.core.v1.NodeSelector suitableNodes = 4; +} + +// ResourceClassList is a collection of classes. +message ResourceClassList { + // Standard list metadata + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of resource classes. + repeated ResourceClass items = 2; +} + +// ResourceClassParametersReference contains enough information to let you +// locate the parameters for a ResourceClass. +message ResourceClassParametersReference { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + optional string apiGroup = 1; + + // Kind is the type of resource being referenced. This is the same + // value as in the parameter object's metadata. + optional string kind = 2; + + // Name is the name of resource being referenced. + optional string name = 3; + + // Namespace that contains the referenced resource. Must be empty + // for cluster-scoped resources and non-empty for namespaced + // resources. + // +optional + optional string namespace = 4; +} + +// ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. +message ResourceHandle { + // DriverName specifies the name of the resource driver whose kubelet + // plugin should be invoked to process this ResourceHandle's data once it + // lands on a node. This may differ from the DriverName set in + // ResourceClaimStatus this ResourceHandle is embedded in. + optional string driverName = 1; + + // Data contains the opaque data associated with this ResourceHandle. It is + // set by the controller component of the resource driver whose name + // matches the DriverName set in the ResourceClaimStatus this + // ResourceHandle is embedded in. It is set at allocation time and is + // intended for processing by the kubelet plugin whose name matches + // the DriverName set in this ResourceHandle. + // + // The maximum size of this field is 16KiB. This may get increased in the + // future, but not reduced. + // +optional + optional string data = 2; +} + diff --git a/vendor/k8s.io/api/resource/v1alpha2/register.go b/vendor/k8s.io/api/resource/v1alpha2/register.go new file mode 100644 index 00000000000..6e0d7ceb988 --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/register.go @@ -0,0 +1,63 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "resource.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ResourceClass{}, + &ResourceClassList{}, + &ResourceClaim{}, + &ResourceClaimList{}, + &ResourceClaimTemplate{}, + &ResourceClaimTemplateList{}, + &PodSchedulingContext{}, + &PodSchedulingContextList{}, + ) + + // Add common types + scheme.AddKnownTypes(SchemeGroupVersion, &metav1.Status{}) + + // Add the watch version that applies + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/resource/v1alpha2/types.go b/vendor/k8s.io/api/resource/v1alpha2/types.go new file mode 100644 index 00000000000..21936bfe3d1 --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/types.go @@ -0,0 +1,462 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClaim describes which resources are needed by a resource consumer. +// Its status tracks whether the resource has been allocated and what the +// resulting attributes are. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +type ResourceClaim struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec describes the desired attributes of a resource that then needs + // to be allocated. It can only be set once when creating the + // ResourceClaim. + Spec ResourceClaimSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // Status describes whether the resource is available and with which + // attributes. + // +optional + Status ResourceClaimStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// ResourceClaimSpec defines how a resource is to be allocated. +type ResourceClaimSpec struct { + // ResourceClassName references the driver and additional parameters + // via the name of a ResourceClass that was created as part of the + // driver deployment. + ResourceClassName string `json:"resourceClassName" protobuf:"bytes,1,name=resourceClassName"` + + // ParametersRef references a separate object with arbitrary parameters + // that will be used by the driver when allocating a resource for the + // claim. + // + // The object must be in the same namespace as the ResourceClaim. + // +optional + ParametersRef *ResourceClaimParametersReference `json:"parametersRef,omitempty" protobuf:"bytes,2,opt,name=parametersRef"` + + // Allocation can start immediately or when a Pod wants to use the + // resource. "WaitForFirstConsumer" is the default. + // +optional + AllocationMode AllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,3,opt,name=allocationMode"` +} + +// AllocationMode describes whether a ResourceClaim gets allocated immediately +// when it gets created (AllocationModeImmediate) or whether allocation is +// delayed until it is needed for a Pod +// (AllocationModeWaitForFirstConsumer). Other modes might get added in the +// future. +type AllocationMode string + +const ( + // When a ResourceClaim has AllocationModeWaitForFirstConsumer, allocation is + // delayed until a Pod gets scheduled that needs the ResourceClaim. The + // scheduler will consider all resource requirements of that Pod and + // trigger allocation for a node that fits the Pod. + AllocationModeWaitForFirstConsumer AllocationMode = "WaitForFirstConsumer" + + // When a ResourceClaim has AllocationModeImmediate, allocation starts + // as soon as the ResourceClaim gets created. This is done without + // considering the needs of Pods that will use the ResourceClaim + // because those Pods are not known yet. + AllocationModeImmediate AllocationMode = "Immediate" +) + +// ResourceClaimStatus tracks whether the resource has been allocated and what +// the resulting attributes are. +type ResourceClaimStatus struct { + // DriverName is a copy of the driver name from the ResourceClass at + // the time when allocation started. + // +optional + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + // Allocation is set by the resource driver once a resource or set of + // resources has been allocated successfully. If this is not specified, the + // resources have not been allocated yet. + // +optional + Allocation *AllocationResult `json:"allocation,omitempty" protobuf:"bytes,2,opt,name=allocation"` + + // ReservedFor indicates which entities are currently allowed to use + // the claim. A Pod which references a ResourceClaim which is not + // reserved for that Pod will not be started. + // + // There can be at most 32 such reservations. This may get increased in + // the future, but not reduced. + // + // +listType=map + // +listMapKey=uid + // +optional + ReservedFor []ResourceClaimConsumerReference `json:"reservedFor,omitempty" protobuf:"bytes,3,opt,name=reservedFor"` + + // DeallocationRequested indicates that a ResourceClaim is to be + // deallocated. + // + // The driver then must deallocate this claim and reset the field + // together with clearing the Allocation field. + // + // While DeallocationRequested is set, no new consumers may be added to + // ReservedFor. + // +optional + DeallocationRequested bool `json:"deallocationRequested,omitempty" protobuf:"varint,4,opt,name=deallocationRequested"` +} + +// ReservedForMaxSize is the maximum number of entries in +// claim.status.reservedFor. +const ResourceClaimReservedForMaxSize = 32 + +// AllocationResult contains attributes of an allocated resource. +type AllocationResult struct { + // ResourceHandles contain the state associated with an allocation that + // should be maintained throughout the lifetime of a claim. Each + // ResourceHandle contains data that should be passed to a specific kubelet + // plugin once it lands on a node. This data is returned by the driver + // after a successful allocation and is opaque to Kubernetes. Driver + // documentation may explain to users how to interpret this data if needed. + // + // Setting this field is optional. It has a maximum size of 32 entries. + // If null (or empty), it is assumed this allocation will be processed by a + // single kubelet plugin with no ResourceHandle data attached. The name of + // the kubelet plugin invoked will match the DriverName set in the + // ResourceClaimStatus this AllocationResult is embedded in. + // + // +listType=atomic + // +optional + ResourceHandles []ResourceHandle `json:"resourceHandles,omitempty" protobuf:"bytes,1,opt,name=resourceHandles"` + + // This field will get set by the resource driver after it has allocated + // the resource to inform the scheduler where it can schedule Pods using + // the ResourceClaim. + // + // Setting this field is optional. If null, the resource is available + // everywhere. + // +optional + AvailableOnNodes *v1.NodeSelector `json:"availableOnNodes,omitempty" protobuf:"bytes,2,opt,name=availableOnNodes"` + + // Shareable determines whether the resource supports more + // than one consumer at a time. + // +optional + Shareable bool `json:"shareable,omitempty" protobuf:"varint,3,opt,name=shareable"` +} + +// AllocationResultResourceHandlesMaxSize represents the maximum number of +// entries in allocation.resourceHandles. +const AllocationResultResourceHandlesMaxSize = 32 + +// ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. +type ResourceHandle struct { + // DriverName specifies the name of the resource driver whose kubelet + // plugin should be invoked to process this ResourceHandle's data once it + // lands on a node. This may differ from the DriverName set in + // ResourceClaimStatus this ResourceHandle is embedded in. + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + // Data contains the opaque data associated with this ResourceHandle. It is + // set by the controller component of the resource driver whose name + // matches the DriverName set in the ResourceClaimStatus this + // ResourceHandle is embedded in. It is set at allocation time and is + // intended for processing by the kubelet plugin whose name matches + // the DriverName set in this ResourceHandle. + // + // The maximum size of this field is 16KiB. This may get increased in the + // future, but not reduced. + // +optional + Data string `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` +} + +// ResourceHandleDataMaxSize represents the maximum size of resourceHandle.data. +const ResourceHandleDataMaxSize = 16 * 1024 + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClaimList is a collection of claims. +type ResourceClaimList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of resource claims. + Items []ResourceClaim `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// PodSchedulingContext objects hold information that is needed to schedule +// a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation +// mode. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +type PodSchedulingContext struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec describes where resources for the Pod are needed. + Spec PodSchedulingContextSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // Status describes where resources for the Pod can be allocated. + // +optional + Status PodSchedulingContextStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// PodSchedulingContextSpec describes where resources for the Pod are needed. +type PodSchedulingContextSpec struct { + // SelectedNode is the node for which allocation of ResourceClaims that + // are referenced by the Pod and that use "WaitForFirstConsumer" + // allocation is to be attempted. + // +optional + SelectedNode string `json:"selectedNode,omitempty" protobuf:"bytes,1,opt,name=selectedNode"` + + // PotentialNodes lists nodes where the Pod might be able to run. + // + // The size of this field is limited to 128. This is large enough for + // many clusters. Larger clusters may need more attempts to find a node + // that suits all pending resources. This may get increased in the + // future, but not reduced. + // + // +listType=set + // +optional + PotentialNodes []string `json:"potentialNodes,omitempty" protobuf:"bytes,2,opt,name=potentialNodes"` +} + +// PodSchedulingContextStatus describes where resources for the Pod can be allocated. +type PodSchedulingContextStatus struct { + // ResourceClaims describes resource availability for each + // pod.spec.resourceClaim entry where the corresponding ResourceClaim + // uses "WaitForFirstConsumer" allocation mode. + // + // +listType=map + // +listMapKey=name + // +optional + ResourceClaims []ResourceClaimSchedulingStatus `json:"resourceClaims,omitempty" protobuf:"bytes,1,opt,name=resourceClaims"` + + // If there ever is a need to support other kinds of resources + // than ResourceClaim, then new fields could get added here + // for those other resources. +} + +// ResourceClaimSchedulingStatus contains information about one particular +// ResourceClaim with "WaitForFirstConsumer" allocation mode. +type ResourceClaimSchedulingStatus struct { + // Name matches the pod.spec.resourceClaims[*].Name field. + // +optional + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + + // UnsuitableNodes lists nodes that the ResourceClaim cannot be + // allocated for. + // + // The size of this field is limited to 128, the same as for + // PodSchedulingSpec.PotentialNodes. This may get increased in the + // future, but not reduced. + // + // +listType=set + // +optional + UnsuitableNodes []string `json:"unsuitableNodes,omitempty" protobuf:"bytes,2,opt,name=unsuitableNodes"` +} + +// PodSchedulingNodeListMaxSize defines the maximum number of entries in the +// node lists that are stored in PodSchedulingContext objects. This limit is part +// of the API. +const PodSchedulingNodeListMaxSize = 128 + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// PodSchedulingContextList is a collection of Pod scheduling objects. +type PodSchedulingContextList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of PodSchedulingContext objects. + Items []PodSchedulingContext `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClass is used by administrators to influence how resources +// are allocated. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +type ResourceClass struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // DriverName defines the name of the dynamic resource driver that is + // used for allocation of a ResourceClaim that uses this class. + // + // Resource drivers have a unique name in forward domain order + // (acme.example.com). + DriverName string `json:"driverName" protobuf:"bytes,2,name=driverName"` + + // ParametersRef references an arbitrary separate object that may hold + // parameters that will be used by the driver when allocating a + // resource that uses this class. A dynamic resource driver can + // distinguish between parameters stored here and and those stored in + // ResourceClaimSpec. + // +optional + ParametersRef *ResourceClassParametersReference `json:"parametersRef,omitempty" protobuf:"bytes,3,opt,name=parametersRef"` + + // Only nodes matching the selector will be considered by the scheduler + // when trying to find a Node that fits a Pod when that Pod uses + // a ResourceClaim that has not been allocated yet. + // + // Setting this field is optional. If null, all nodes are candidates. + // +optional + SuitableNodes *v1.NodeSelector `json:"suitableNodes,omitempty" protobuf:"bytes,4,opt,name=suitableNodes"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClassList is a collection of classes. +type ResourceClassList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of resource classes. + Items []ResourceClass `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// ResourceClassParametersReference contains enough information to let you +// locate the parameters for a ResourceClass. +type ResourceClassParametersReference struct { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=apiGroup"` + // Kind is the type of resource being referenced. This is the same + // value as in the parameter object's metadata. + Kind string `json:"kind" protobuf:"bytes,2,name=kind"` + // Name is the name of resource being referenced. + Name string `json:"name" protobuf:"bytes,3,name=name"` + // Namespace that contains the referenced resource. Must be empty + // for cluster-scoped resources and non-empty for namespaced + // resources. + // +optional + Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` +} + +// ResourceClaimParametersReference contains enough information to let you +// locate the parameters for a ResourceClaim. The object must be in the same +// namespace as the ResourceClaim. +type ResourceClaimParametersReference struct { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=apiGroup"` + // Kind is the type of resource being referenced. This is the same + // value as in the parameter object's metadata, for example "ConfigMap". + Kind string `json:"kind" protobuf:"bytes,2,name=kind"` + // Name is the name of resource being referenced. + Name string `json:"name" protobuf:"bytes,3,name=name"` +} + +// ResourceClaimConsumerReference contains enough information to let you +// locate the consumer of a ResourceClaim. The user must be a resource in the same +// namespace as the ResourceClaim. +type ResourceClaimConsumerReference struct { + // APIGroup is the group for the resource being referenced. It is + // empty for the core API. This matches the group in the APIVersion + // that is used when creating the resources. + // +optional + APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=apiGroup"` + // Resource is the type of resource being referenced, for example "pods". + Resource string `json:"resource" protobuf:"bytes,3,name=resource"` + // Name is the name of resource being referenced. + Name string `json:"name" protobuf:"bytes,4,name=name"` + // UID identifies exactly one incarnation of the resource. + UID types.UID `json:"uid" protobuf:"bytes,5,name=uid"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClaimTemplate is used to produce ResourceClaim objects. +type ResourceClaimTemplate struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Describes the ResourceClaim that is to be generated. + // + // This field is immutable. A ResourceClaim will get created by the + // control plane for a Pod when needed and then not get updated + // anymore. + Spec ResourceClaimTemplateSpec `json:"spec" protobuf:"bytes,2,name=spec"` +} + +// ResourceClaimTemplateSpec contains the metadata and fields for a ResourceClaim. +type ResourceClaimTemplateSpec struct { + // ObjectMeta may contain labels and annotations that will be copied into the PVC + // when creating it. No other fields are allowed and will be rejected during + // validation. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec for the ResourceClaim. The entire content is copied unchanged + // into the ResourceClaim that gets created from this template. The + // same fields as in a ResourceClaim are also valid here. + Spec ResourceClaimSpec `json:"spec" protobuf:"bytes,2,name=spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.26 + +// ResourceClaimTemplateList is a collection of claim templates. +type ResourceClaimTemplateList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of resource claim templates. + Items []ResourceClaimTemplate `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go new file mode 100644 index 00000000000..474be8c85ce --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go @@ -0,0 +1,232 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_AllocationResult = map[string]string{ + "": "AllocationResult contains attributes of an allocated resource.", + "resourceHandles": "ResourceHandles contain the state associated with an allocation that should be maintained throughout the lifetime of a claim. Each ResourceHandle contains data that should be passed to a specific kubelet plugin once it lands on a node. This data is returned by the driver after a successful allocation and is opaque to Kubernetes. Driver documentation may explain to users how to interpret this data if needed.\n\nSetting this field is optional. It has a maximum size of 32 entries. If null (or empty), it is assumed this allocation will be processed by a single kubelet plugin with no ResourceHandle data attached. The name of the kubelet plugin invoked will match the DriverName set in the ResourceClaimStatus this AllocationResult is embedded in.", + "availableOnNodes": "This field will get set by the resource driver after it has allocated the resource to inform the scheduler where it can schedule Pods using the ResourceClaim.\n\nSetting this field is optional. If null, the resource is available everywhere.", + "shareable": "Shareable determines whether the resource supports more than one consumer at a time.", +} + +func (AllocationResult) SwaggerDoc() map[string]string { + return map_AllocationResult +} + +var map_PodSchedulingContext = map[string]string{ + "": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "metadata": "Standard object metadata", + "spec": "Spec describes where resources for the Pod are needed.", + "status": "Status describes where resources for the Pod can be allocated.", +} + +func (PodSchedulingContext) SwaggerDoc() map[string]string { + return map_PodSchedulingContext +} + +var map_PodSchedulingContextList = map[string]string{ + "": "PodSchedulingContextList is a collection of Pod scheduling objects.", + "metadata": "Standard list metadata", + "items": "Items is the list of PodSchedulingContext objects.", +} + +func (PodSchedulingContextList) SwaggerDoc() map[string]string { + return map_PodSchedulingContextList +} + +var map_PodSchedulingContextSpec = map[string]string{ + "": "PodSchedulingContextSpec describes where resources for the Pod are needed.", + "selectedNode": "SelectedNode is the node for which allocation of ResourceClaims that are referenced by the Pod and that use \"WaitForFirstConsumer\" allocation is to be attempted.", + "potentialNodes": "PotentialNodes lists nodes where the Pod might be able to run.\n\nThe size of this field is limited to 128. This is large enough for many clusters. Larger clusters may need more attempts to find a node that suits all pending resources. This may get increased in the future, but not reduced.", +} + +func (PodSchedulingContextSpec) SwaggerDoc() map[string]string { + return map_PodSchedulingContextSpec +} + +var map_PodSchedulingContextStatus = map[string]string{ + "": "PodSchedulingContextStatus describes where resources for the Pod can be allocated.", + "resourceClaims": "ResourceClaims describes resource availability for each pod.spec.resourceClaim entry where the corresponding ResourceClaim uses \"WaitForFirstConsumer\" allocation mode.", +} + +func (PodSchedulingContextStatus) SwaggerDoc() map[string]string { + return map_PodSchedulingContextStatus +} + +var map_ResourceClaim = map[string]string{ + "": "ResourceClaim describes which resources are needed by a resource consumer. Its status tracks whether the resource has been allocated and what the resulting attributes are.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "metadata": "Standard object metadata", + "spec": "Spec describes the desired attributes of a resource that then needs to be allocated. It can only be set once when creating the ResourceClaim.", + "status": "Status describes whether the resource is available and with which attributes.", +} + +func (ResourceClaim) SwaggerDoc() map[string]string { + return map_ResourceClaim +} + +var map_ResourceClaimConsumerReference = map[string]string{ + "": "ResourceClaimConsumerReference contains enough information to let you locate the consumer of a ResourceClaim. The user must be a resource in the same namespace as the ResourceClaim.", + "apiGroup": "APIGroup is the group for the resource being referenced. It is empty for the core API. This matches the group in the APIVersion that is used when creating the resources.", + "resource": "Resource is the type of resource being referenced, for example \"pods\".", + "name": "Name is the name of resource being referenced.", + "uid": "UID identifies exactly one incarnation of the resource.", +} + +func (ResourceClaimConsumerReference) SwaggerDoc() map[string]string { + return map_ResourceClaimConsumerReference +} + +var map_ResourceClaimList = map[string]string{ + "": "ResourceClaimList is a collection of claims.", + "metadata": "Standard list metadata", + "items": "Items is the list of resource claims.", +} + +func (ResourceClaimList) SwaggerDoc() map[string]string { + return map_ResourceClaimList +} + +var map_ResourceClaimParametersReference = map[string]string{ + "": "ResourceClaimParametersReference contains enough information to let you locate the parameters for a ResourceClaim. The object must be in the same namespace as the ResourceClaim.", + "apiGroup": "APIGroup is the group for the resource being referenced. It is empty for the core API. This matches the group in the APIVersion that is used when creating the resources.", + "kind": "Kind is the type of resource being referenced. This is the same value as in the parameter object's metadata, for example \"ConfigMap\".", + "name": "Name is the name of resource being referenced.", +} + +func (ResourceClaimParametersReference) SwaggerDoc() map[string]string { + return map_ResourceClaimParametersReference +} + +var map_ResourceClaimSchedulingStatus = map[string]string{ + "": "ResourceClaimSchedulingStatus contains information about one particular ResourceClaim with \"WaitForFirstConsumer\" allocation mode.", + "name": "Name matches the pod.spec.resourceClaims[*].Name field.", + "unsuitableNodes": "UnsuitableNodes lists nodes that the ResourceClaim cannot be allocated for.\n\nThe size of this field is limited to 128, the same as for PodSchedulingSpec.PotentialNodes. This may get increased in the future, but not reduced.", +} + +func (ResourceClaimSchedulingStatus) SwaggerDoc() map[string]string { + return map_ResourceClaimSchedulingStatus +} + +var map_ResourceClaimSpec = map[string]string{ + "": "ResourceClaimSpec defines how a resource is to be allocated.", + "resourceClassName": "ResourceClassName references the driver and additional parameters via the name of a ResourceClass that was created as part of the driver deployment.", + "parametersRef": "ParametersRef references a separate object with arbitrary parameters that will be used by the driver when allocating a resource for the claim.\n\nThe object must be in the same namespace as the ResourceClaim.", + "allocationMode": "Allocation can start immediately or when a Pod wants to use the resource. \"WaitForFirstConsumer\" is the default.", +} + +func (ResourceClaimSpec) SwaggerDoc() map[string]string { + return map_ResourceClaimSpec +} + +var map_ResourceClaimStatus = map[string]string{ + "": "ResourceClaimStatus tracks whether the resource has been allocated and what the resulting attributes are.", + "driverName": "DriverName is a copy of the driver name from the ResourceClass at the time when allocation started.", + "allocation": "Allocation is set by the resource driver once a resource or set of resources has been allocated successfully. If this is not specified, the resources have not been allocated yet.", + "reservedFor": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", + "deallocationRequested": "DeallocationRequested indicates that a ResourceClaim is to be deallocated.\n\nThe driver then must deallocate this claim and reset the field together with clearing the Allocation field.\n\nWhile DeallocationRequested is set, no new consumers may be added to ReservedFor.", +} + +func (ResourceClaimStatus) SwaggerDoc() map[string]string { + return map_ResourceClaimStatus +} + +var map_ResourceClaimTemplate = map[string]string{ + "": "ResourceClaimTemplate is used to produce ResourceClaim objects.", + "metadata": "Standard object metadata", + "spec": "Describes the ResourceClaim that is to be generated.\n\nThis field is immutable. A ResourceClaim will get created by the control plane for a Pod when needed and then not get updated anymore.", +} + +func (ResourceClaimTemplate) SwaggerDoc() map[string]string { + return map_ResourceClaimTemplate +} + +var map_ResourceClaimTemplateList = map[string]string{ + "": "ResourceClaimTemplateList is a collection of claim templates.", + "metadata": "Standard list metadata", + "items": "Items is the list of resource claim templates.", +} + +func (ResourceClaimTemplateList) SwaggerDoc() map[string]string { + return map_ResourceClaimTemplateList +} + +var map_ResourceClaimTemplateSpec = map[string]string{ + "": "ResourceClaimTemplateSpec contains the metadata and fields for a ResourceClaim.", + "metadata": "ObjectMeta may contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.", + "spec": "Spec for the ResourceClaim. The entire content is copied unchanged into the ResourceClaim that gets created from this template. The same fields as in a ResourceClaim are also valid here.", +} + +func (ResourceClaimTemplateSpec) SwaggerDoc() map[string]string { + return map_ResourceClaimTemplateSpec +} + +var map_ResourceClass = map[string]string{ + "": "ResourceClass is used by administrators to influence how resources are allocated.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "metadata": "Standard object metadata", + "driverName": "DriverName defines the name of the dynamic resource driver that is used for allocation of a ResourceClaim that uses this class.\n\nResource drivers have a unique name in forward domain order (acme.example.com).", + "parametersRef": "ParametersRef references an arbitrary separate object that may hold parameters that will be used by the driver when allocating a resource that uses this class. A dynamic resource driver can distinguish between parameters stored here and and those stored in ResourceClaimSpec.", + "suitableNodes": "Only nodes matching the selector will be considered by the scheduler when trying to find a Node that fits a Pod when that Pod uses a ResourceClaim that has not been allocated yet.\n\nSetting this field is optional. If null, all nodes are candidates.", +} + +func (ResourceClass) SwaggerDoc() map[string]string { + return map_ResourceClass +} + +var map_ResourceClassList = map[string]string{ + "": "ResourceClassList is a collection of classes.", + "metadata": "Standard list metadata", + "items": "Items is the list of resource classes.", +} + +func (ResourceClassList) SwaggerDoc() map[string]string { + return map_ResourceClassList +} + +var map_ResourceClassParametersReference = map[string]string{ + "": "ResourceClassParametersReference contains enough information to let you locate the parameters for a ResourceClass.", + "apiGroup": "APIGroup is the group for the resource being referenced. It is empty for the core API. This matches the group in the APIVersion that is used when creating the resources.", + "kind": "Kind is the type of resource being referenced. This is the same value as in the parameter object's metadata.", + "name": "Name is the name of resource being referenced.", + "namespace": "Namespace that contains the referenced resource. Must be empty for cluster-scoped resources and non-empty for namespaced resources.", +} + +func (ResourceClassParametersReference) SwaggerDoc() map[string]string { + return map_ResourceClassParametersReference +} + +var map_ResourceHandle = map[string]string{ + "": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", + "driverName": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", + "data": "Data contains the opaque data associated with this ResourceHandle. It is set by the controller component of the resource driver whose name matches the DriverName set in the ResourceClaimStatus this ResourceHandle is embedded in. It is set at allocation time and is intended for processing by the kubelet plugin whose name matches the DriverName set in this ResourceHandle.\n\nThe maximum size of this field is 16KiB. This may get increased in the future, but not reduced.", +} + +func (ResourceHandle) SwaggerDoc() map[string]string { + return map_ResourceHandle +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 00000000000..89d521bf05a --- /dev/null +++ b/vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,498 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AllocationResult) DeepCopyInto(out *AllocationResult) { + *out = *in + if in.ResourceHandles != nil { + in, out := &in.ResourceHandles, &out.ResourceHandles + *out = make([]ResourceHandle, len(*in)) + copy(*out, *in) + } + if in.AvailableOnNodes != nil { + in, out := &in.AvailableOnNodes, &out.AvailableOnNodes + *out = new(v1.NodeSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllocationResult. +func (in *AllocationResult) DeepCopy() *AllocationResult { + if in == nil { + return nil + } + out := new(AllocationResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContext. +func (in *PodSchedulingContext) DeepCopy() *PodSchedulingContext { + if in == nil { + return nil + } + out := new(PodSchedulingContext) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodSchedulingContext) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingContextList) DeepCopyInto(out *PodSchedulingContextList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodSchedulingContext, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextList. +func (in *PodSchedulingContextList) DeepCopy() *PodSchedulingContextList { + if in == nil { + return nil + } + out := new(PodSchedulingContextList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodSchedulingContextList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingContextSpec) DeepCopyInto(out *PodSchedulingContextSpec) { + *out = *in + if in.PotentialNodes != nil { + in, out := &in.PotentialNodes, &out.PotentialNodes + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextSpec. +func (in *PodSchedulingContextSpec) DeepCopy() *PodSchedulingContextSpec { + if in == nil { + return nil + } + out := new(PodSchedulingContextSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingContextStatus) DeepCopyInto(out *PodSchedulingContextStatus) { + *out = *in + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]ResourceClaimSchedulingStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextStatus. +func (in *PodSchedulingContextStatus) DeepCopy() *PodSchedulingContextStatus { + if in == nil { + return nil + } + out := new(PodSchedulingContextStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaim) DeepCopyInto(out *ResourceClaim) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaim. +func (in *ResourceClaim) DeepCopy() *ResourceClaim { + if in == nil { + return nil + } + out := new(ResourceClaim) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaim) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimConsumerReference) DeepCopyInto(out *ResourceClaimConsumerReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimConsumerReference. +func (in *ResourceClaimConsumerReference) DeepCopy() *ResourceClaimConsumerReference { + if in == nil { + return nil + } + out := new(ResourceClaimConsumerReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimList) DeepCopyInto(out *ResourceClaimList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimList. +func (in *ResourceClaimList) DeepCopy() *ResourceClaimList { + if in == nil { + return nil + } + out := new(ResourceClaimList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimParametersReference) DeepCopyInto(out *ResourceClaimParametersReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimParametersReference. +func (in *ResourceClaimParametersReference) DeepCopy() *ResourceClaimParametersReference { + if in == nil { + return nil + } + out := new(ResourceClaimParametersReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimSchedulingStatus) DeepCopyInto(out *ResourceClaimSchedulingStatus) { + *out = *in + if in.UnsuitableNodes != nil { + in, out := &in.UnsuitableNodes, &out.UnsuitableNodes + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimSchedulingStatus. +func (in *ResourceClaimSchedulingStatus) DeepCopy() *ResourceClaimSchedulingStatus { + if in == nil { + return nil + } + out := new(ResourceClaimSchedulingStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimSpec) DeepCopyInto(out *ResourceClaimSpec) { + *out = *in + if in.ParametersRef != nil { + in, out := &in.ParametersRef, &out.ParametersRef + *out = new(ResourceClaimParametersReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimSpec. +func (in *ResourceClaimSpec) DeepCopy() *ResourceClaimSpec { + if in == nil { + return nil + } + out := new(ResourceClaimSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimStatus) DeepCopyInto(out *ResourceClaimStatus) { + *out = *in + if in.Allocation != nil { + in, out := &in.Allocation, &out.Allocation + *out = new(AllocationResult) + (*in).DeepCopyInto(*out) + } + if in.ReservedFor != nil { + in, out := &in.ReservedFor, &out.ReservedFor + *out = make([]ResourceClaimConsumerReference, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimStatus. +func (in *ResourceClaimStatus) DeepCopy() *ResourceClaimStatus { + if in == nil { + return nil + } + out := new(ResourceClaimStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimTemplate) DeepCopyInto(out *ResourceClaimTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimTemplate. +func (in *ResourceClaimTemplate) DeepCopy() *ResourceClaimTemplate { + if in == nil { + return nil + } + out := new(ResourceClaimTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimTemplateList) DeepCopyInto(out *ResourceClaimTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClaimTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimTemplateList. +func (in *ResourceClaimTemplateList) DeepCopy() *ResourceClaimTemplateList { + if in == nil { + return nil + } + out := new(ResourceClaimTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClaimTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClaimTemplateSpec) DeepCopyInto(out *ResourceClaimTemplateSpec) { + *out = *in + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClaimTemplateSpec. +func (in *ResourceClaimTemplateSpec) DeepCopy() *ResourceClaimTemplateSpec { + if in == nil { + return nil + } + out := new(ResourceClaimTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClass) DeepCopyInto(out *ResourceClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.ParametersRef != nil { + in, out := &in.ParametersRef, &out.ParametersRef + *out = new(ResourceClassParametersReference) + **out = **in + } + if in.SuitableNodes != nil { + in, out := &in.SuitableNodes, &out.SuitableNodes + *out = new(v1.NodeSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClass. +func (in *ResourceClass) DeepCopy() *ResourceClass { + if in == nil { + return nil + } + out := new(ResourceClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClass) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassList) DeepCopyInto(out *ResourceClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourceClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassList. +func (in *ResourceClassList) DeepCopy() *ResourceClassList { + if in == nil { + return nil + } + out := new(ResourceClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourceClassList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceClassParametersReference) DeepCopyInto(out *ResourceClassParametersReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceClassParametersReference. +func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersReference { + if in == nil { + return nil + } + out := new(ResourceClassParametersReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceHandle) DeepCopyInto(out *ResourceHandle) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceHandle. +func (in *ResourceHandle) DeepCopy() *ResourceHandle { + if in == nil { + return nil + } + out := new(ResourceHandle) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/scheduling/v1/generated.proto b/vendor/k8s.io/api/scheduling/v1/generated.proto index afc090777de..c1a27e8baa8 100644 --- a/vendor/k8s.io/api/scheduling/v1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1/generated.proto @@ -37,7 +37,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -54,7 +54,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1/types.go b/vendor/k8s.io/api/scheduling/v1/types.go index 0f2989424ef..146bae40d3b 100644 --- a/vendor/k8s.io/api/scheduling/v1/types.go +++ b/vendor/k8s.io/api/scheduling/v1/types.go @@ -34,7 +34,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -51,7 +51,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go index ac34c531fb9..f167e19707b 100644 --- a/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto b/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto index 5c60b7ab4c7..f0878fb16e0 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto @@ -38,7 +38,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -55,7 +55,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types.go b/vendor/k8s.io/api/scheduling/v1alpha1/types.go index 7b0df486460..26ba8ff5dcc 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types.go +++ b/vendor/k8s.io/api/scheduling/v1alpha1/types.go @@ -35,7 +35,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -52,7 +52,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go index fa25f969c43..557005db64e 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto index 44b49ea2463..43878184d6e 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto @@ -38,7 +38,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -55,7 +55,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1beta1/types.go b/vendor/k8s.io/api/scheduling/v1beta1/types.go index e315e1b3594..6f88592cf20 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/types.go +++ b/vendor/k8s.io/api/scheduling/v1beta1/types.go @@ -39,7 +39,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -56,7 +56,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go index cbc140f446b..f42008eb91f 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1/generated.pb.go b/vendor/k8s.io/api/storage/v1/generated.pb.go index a648c426aab..d36497432de 100644 --- a/vendor/k8s.io/api/storage/v1/generated.pb.go +++ b/vendor/k8s.io/api/storage/v1/generated.pb.go @@ -609,111 +609,112 @@ func init() { } var fileDescriptor_3b530c1983504d8d = []byte{ - // 1651 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xbd, 0x6f, 0x1b, 0xcb, - 0x11, 0xd7, 0x89, 0xd4, 0xd7, 0x52, 0xb2, 0xa4, 0x95, 0xe4, 0x30, 0x2a, 0x48, 0xe1, 0x6c, 0x24, - 0xb2, 0x13, 0x1f, 0x6d, 0xd9, 0x31, 0x0c, 0x07, 0x0e, 0xa0, 0x93, 0xe8, 0x58, 0x88, 0x28, 0x29, - 0x4b, 0xc5, 0x30, 0x82, 0x24, 0xf0, 0xea, 0x6e, 0x45, 0xad, 0xc5, 0xfb, 0xf0, 0xed, 0x92, 0x31, - 0x53, 0x25, 0x4d, 0xba, 0x00, 0x49, 0x1b, 0xe4, 0x8f, 0x48, 0x80, 0xa4, 0x49, 0x99, 0x22, 0x70, - 0x3a, 0x23, 0x95, 0x2b, 0xe2, 0x99, 0xaf, 0x7e, 0xaf, 0x7c, 0x85, 0xaa, 0x87, 0xdd, 0x5b, 0xf2, - 0x3e, 0x78, 0x94, 0xa5, 0x86, 0x1d, 0x77, 0x67, 0xe6, 0x37, 0xb3, 0x3b, 0xbf, 0x99, 0x9d, 0x23, - 0xf8, 0xc9, 0xf9, 0x13, 0x66, 0x50, 0xaf, 0x72, 0xde, 0x3a, 0x21, 0x81, 0x4b, 0x38, 0x61, 0x95, - 0x36, 0x71, 0x6d, 0x2f, 0xa8, 0x28, 0x01, 0xf6, 0x69, 0x85, 0x71, 0x2f, 0xc0, 0x0d, 0x52, 0x69, - 0x3f, 0xa8, 0x34, 0x88, 0x4b, 0x02, 0xcc, 0x89, 0x6d, 0xf8, 0x81, 0xc7, 0x3d, 0xb8, 0x16, 0xaa, - 0x19, 0xd8, 0xa7, 0x86, 0x52, 0x33, 0xda, 0x0f, 0xd6, 0xef, 0x35, 0x28, 0x3f, 0x6b, 0x9d, 0x18, - 0x96, 0xe7, 0x54, 0x1a, 0x5e, 0xc3, 0xab, 0x48, 0xed, 0x93, 0xd6, 0xa9, 0x5c, 0xc9, 0x85, 0xfc, - 0x15, 0xa2, 0xac, 0xeb, 0x31, 0x67, 0x96, 0x17, 0x64, 0x79, 0x5a, 0x7f, 0x14, 0xe9, 0x38, 0xd8, - 0x3a, 0xa3, 0x2e, 0x09, 0x3a, 0x15, 0xff, 0xbc, 0x21, 0x8d, 0x02, 0xc2, 0xbc, 0x56, 0x60, 0x91, - 0x6b, 0x59, 0xb1, 0x8a, 0x43, 0x38, 0xce, 0xf2, 0x55, 0x19, 0x65, 0x15, 0xb4, 0x5c, 0x4e, 0x9d, - 0x61, 0x37, 0x8f, 0x3f, 0x67, 0xc0, 0xac, 0x33, 0xe2, 0xe0, 0xb4, 0x9d, 0xfe, 0x2f, 0x0d, 0xcc, - 0xed, 0xd4, 0xf7, 0x76, 0x03, 0xda, 0x26, 0x01, 0x7c, 0x0d, 0x66, 0x45, 0x44, 0x36, 0xe6, 0xb8, - 0xa8, 0x6d, 0x68, 0x9b, 0x85, 0xad, 0xfb, 0x46, 0x74, 0xbf, 0x03, 0x60, 0xc3, 0x3f, 0x6f, 0x88, - 0x0d, 0x66, 0x08, 0x6d, 0xa3, 0xfd, 0xc0, 0x38, 0x3c, 0x79, 0x43, 0x2c, 0x5e, 0x23, 0x1c, 0x9b, - 0xf0, 0x7d, 0xb7, 0x3c, 0xd1, 0xeb, 0x96, 0x41, 0xb4, 0x87, 0x06, 0xa8, 0xf0, 0x39, 0xc8, 0x33, - 0x9f, 0x58, 0xc5, 0x49, 0x89, 0x7e, 0xdb, 0xc8, 0xcc, 0x9e, 0x31, 0x88, 0xa8, 0xee, 0x13, 0xcb, - 0x9c, 0x57, 0x88, 0x79, 0xb1, 0x42, 0xd2, 0x5e, 0xff, 0xa7, 0x06, 0x16, 0x06, 0x5a, 0xfb, 0x94, - 0x71, 0xf8, 0xab, 0xa1, 0xd8, 0x8d, 0xab, 0xc5, 0x2e, 0xac, 0x65, 0xe4, 0x4b, 0xca, 0xcf, 0x6c, - 0x7f, 0x27, 0x16, 0x77, 0x15, 0x4c, 0x51, 0x4e, 0x1c, 0x56, 0x9c, 0xdc, 0xc8, 0x6d, 0x16, 0xb6, - 0x36, 0x3e, 0x17, 0xb8, 0xb9, 0xa0, 0xc0, 0xa6, 0xf6, 0x84, 0x19, 0x0a, 0xad, 0xf5, 0xbf, 0xe5, - 0x63, 0x61, 0x8b, 0xe3, 0xc0, 0xa7, 0xe0, 0x06, 0xe6, 0x1c, 0x5b, 0x67, 0x88, 0xbc, 0x6d, 0xd1, - 0x80, 0xd8, 0x32, 0xf8, 0x59, 0x13, 0xf6, 0xba, 0xe5, 0x1b, 0xdb, 0x09, 0x09, 0x4a, 0x69, 0x0a, - 0x5b, 0xdf, 0xb3, 0xf7, 0xdc, 0x53, 0xef, 0xd0, 0xad, 0x79, 0x2d, 0x97, 0xcb, 0x6b, 0x55, 0xb6, - 0x47, 0x09, 0x09, 0x4a, 0x69, 0x42, 0x0b, 0xac, 0xb6, 0xbd, 0x66, 0xcb, 0x21, 0xfb, 0xf4, 0x94, - 0x58, 0x1d, 0xab, 0x49, 0x6a, 0x9e, 0x4d, 0x58, 0x31, 0xb7, 0x91, 0xdb, 0x9c, 0x33, 0x2b, 0xbd, - 0x6e, 0x79, 0xf5, 0x65, 0x86, 0xfc, 0xa2, 0x5b, 0x5e, 0xc9, 0xd8, 0x47, 0x99, 0x60, 0xf0, 0x19, - 0x58, 0x54, 0x97, 0xb3, 0x83, 0x7d, 0x6c, 0x51, 0xde, 0x29, 0xe6, 0x65, 0x84, 0x2b, 0xbd, 0x6e, - 0x79, 0xb1, 0x9e, 0x14, 0xa1, 0xb4, 0x2e, 0x7c, 0x01, 0x16, 0x4e, 0xd9, 0x4f, 0x03, 0xaf, 0xe5, - 0x1f, 0x79, 0x4d, 0x6a, 0x75, 0x8a, 0x53, 0x1b, 0xda, 0xe6, 0x9c, 0xa9, 0xf7, 0xba, 0xe5, 0x85, - 0xe7, 0xf5, 0x98, 0xe0, 0x22, 0xbd, 0x81, 0x92, 0x86, 0xf0, 0x35, 0x58, 0xe0, 0xde, 0x39, 0x71, - 0xc5, 0xd5, 0x11, 0xc6, 0x59, 0x71, 0x5a, 0xa6, 0xf1, 0xd6, 0x88, 0x34, 0x1e, 0xc7, 0x74, 0xcd, - 0x35, 0x95, 0xc9, 0x85, 0xf8, 0x2e, 0x43, 0x49, 0x40, 0xb8, 0x03, 0x96, 0x83, 0x30, 0x2f, 0x0c, - 0x11, 0xbf, 0x75, 0xd2, 0xa4, 0xec, 0xac, 0x38, 0x23, 0x0f, 0xbb, 0xd6, 0xeb, 0x96, 0x97, 0x51, - 0x5a, 0x88, 0x86, 0xf5, 0xf5, 0x7f, 0x68, 0x60, 0x66, 0xa7, 0xbe, 0x77, 0xe0, 0xd9, 0x64, 0x0c, - 0xb5, 0xb8, 0x9b, 0xa8, 0x45, 0x7d, 0x34, 0xa5, 0x45, 0x3c, 0x23, 0x2b, 0xf1, 0xeb, 0xb0, 0x12, - 0x85, 0x8e, 0xea, 0x22, 0x1b, 0x20, 0xef, 0x62, 0x87, 0xc8, 0xa8, 0xe7, 0x22, 0x9b, 0x03, 0xec, - 0x10, 0x24, 0x25, 0xf0, 0x7b, 0x60, 0xda, 0xf5, 0x6c, 0xb2, 0xb7, 0x2b, 0x7d, 0xcf, 0x99, 0x37, - 0x94, 0xce, 0xf4, 0x81, 0xdc, 0x45, 0x4a, 0x0a, 0x1f, 0x81, 0x79, 0xee, 0xf9, 0x5e, 0xd3, 0x6b, - 0x74, 0x7e, 0x46, 0x3a, 0x7d, 0x72, 0x2e, 0xf5, 0xba, 0xe5, 0xf9, 0xe3, 0xd8, 0x3e, 0x4a, 0x68, - 0xc1, 0x5f, 0x83, 0x02, 0x6e, 0x36, 0x3d, 0x0b, 0x73, 0x7c, 0xd2, 0x24, 0x92, 0x71, 0x85, 0xad, - 0xbb, 0x23, 0x8e, 0x17, 0x92, 0x59, 0xf8, 0x45, 0xaa, 0x85, 0x33, 0x73, 0xb1, 0xd7, 0x2d, 0x17, - 0xb6, 0x23, 0x08, 0x14, 0xc7, 0xd3, 0xff, 0xae, 0x81, 0x82, 0x3a, 0xf0, 0x18, 0x1a, 0xcf, 0x4e, - 0xb2, 0xf1, 0x94, 0x2e, 0xcf, 0xd2, 0x88, 0xb6, 0xf3, 0x9b, 0x41, 0xc4, 0xb2, 0xe7, 0x1c, 0x82, - 0x19, 0x5b, 0xa6, 0x8a, 0x15, 0x35, 0x89, 0x7a, 0xfb, 0x72, 0x54, 0xd5, 0xd2, 0x16, 0x15, 0xf6, - 0x4c, 0xb8, 0x66, 0xa8, 0x8f, 0xa2, 0x7f, 0x93, 0x03, 0x70, 0xa7, 0xbe, 0x97, 0x2a, 0xe8, 0x31, - 0x50, 0x98, 0x82, 0x79, 0x41, 0x95, 0x3e, 0x19, 0x14, 0x95, 0x1f, 0x5e, 0xf1, 0xfe, 0xf1, 0x09, - 0x69, 0xd6, 0x49, 0x93, 0x58, 0xdc, 0x0b, 0x42, 0x56, 0x1d, 0xc4, 0xc0, 0x50, 0x02, 0x1a, 0xee, - 0x82, 0xa5, 0x7e, 0x7f, 0x6a, 0x62, 0xc6, 0x04, 0x9b, 0x8b, 0x39, 0xc9, 0xde, 0xa2, 0x0a, 0x71, - 0xa9, 0x9e, 0x92, 0xa3, 0x21, 0x0b, 0xf8, 0x0a, 0xcc, 0x5a, 0xf1, 0x56, 0xf8, 0x19, 0xb2, 0x18, - 0xfd, 0xb9, 0xc2, 0xf8, 0x79, 0x0b, 0xbb, 0x9c, 0xf2, 0x8e, 0x39, 0x2f, 0x88, 0x32, 0xe8, 0x99, - 0x03, 0x34, 0xc8, 0xc0, 0xb2, 0x83, 0xdf, 0x51, 0xa7, 0xe5, 0x84, 0x94, 0xae, 0xd3, 0xdf, 0x11, - 0xd9, 0x30, 0xaf, 0xef, 0x42, 0x36, 0xac, 0x5a, 0x1a, 0x0c, 0x0d, 0xe3, 0xeb, 0xff, 0xd5, 0xc0, - 0xcd, 0xe1, 0xc4, 0x8f, 0xa1, 0x2c, 0x0e, 0x92, 0x65, 0x71, 0x67, 0x34, 0x81, 0x53, 0xb1, 0x8d, - 0xa8, 0x90, 0x3f, 0x4d, 0x83, 0xf9, 0x78, 0xfa, 0xc6, 0xc0, 0xdd, 0x1f, 0x81, 0x82, 0x1f, 0x78, - 0x6d, 0xca, 0xa8, 0xe7, 0x92, 0x40, 0x75, 0xc2, 0x15, 0x65, 0x52, 0x38, 0x8a, 0x44, 0x28, 0xae, - 0x07, 0x1b, 0x00, 0xf8, 0x38, 0xc0, 0x0e, 0xe1, 0xa2, 0x7e, 0x73, 0xf2, 0xf8, 0x0f, 0x47, 0x1c, - 0x3f, 0x7e, 0x22, 0xe3, 0x68, 0x60, 0x55, 0x75, 0x79, 0xd0, 0x89, 0xa2, 0x8b, 0x04, 0x28, 0x06, - 0x0d, 0xcf, 0xc1, 0x42, 0x40, 0xac, 0x26, 0xa6, 0x8e, 0x7a, 0x7d, 0xf3, 0x32, 0xc2, 0xaa, 0x78, - 0x0a, 0x51, 0x5c, 0x70, 0xd1, 0x2d, 0xdf, 0x1f, 0x9e, 0x9f, 0x8d, 0x23, 0x12, 0x30, 0xca, 0x38, - 0x71, 0x79, 0x48, 0x98, 0x84, 0x0d, 0x4a, 0x62, 0x8b, 0x4e, 0xef, 0x88, 0xb9, 0xe4, 0xd0, 0xe7, - 0xd4, 0x73, 0x59, 0x71, 0x2a, 0xea, 0xf4, 0xb5, 0xd8, 0x3e, 0x4a, 0x68, 0xc1, 0x7d, 0xb0, 0x2a, - 0x3a, 0xf3, 0x6f, 0x43, 0x07, 0xd5, 0x77, 0x3e, 0x76, 0xc5, 0x2d, 0x15, 0xa7, 0xe5, 0xbb, 0x5b, - 0x14, 0x43, 0xcc, 0x76, 0x86, 0x1c, 0x65, 0x5a, 0xc1, 0x57, 0x60, 0x39, 0x9c, 0x62, 0x4c, 0xea, - 0xda, 0xd4, 0x6d, 0x88, 0x19, 0x46, 0x3e, 0xe1, 0x73, 0xe6, 0x5d, 0x51, 0x11, 0x2f, 0xd3, 0xc2, - 0x8b, 0xac, 0x4d, 0x34, 0x0c, 0x02, 0xdf, 0x82, 0x65, 0xe9, 0x91, 0xd8, 0xaa, 0x9d, 0x50, 0xc2, - 0x8a, 0xb3, 0x32, 0x75, 0x9b, 0xf1, 0xd4, 0x89, 0xab, 0x0b, 0xe7, 0x8f, 0xb0, 0xe9, 0xf4, 0x9b, - 0xd3, 0x31, 0x09, 0x1c, 0xf3, 0xbb, 0x2a, 0x5f, 0xcb, 0xdb, 0x69, 0x28, 0x34, 0x8c, 0xbe, 0xfe, - 0x0c, 0x2c, 0xa6, 0x12, 0x0e, 0x97, 0x40, 0xee, 0x9c, 0x74, 0xc2, 0x67, 0x19, 0x89, 0x9f, 0x70, - 0x15, 0x4c, 0xb5, 0x71, 0xb3, 0x45, 0x42, 0xf2, 0xa1, 0x70, 0xf1, 0x74, 0xf2, 0x89, 0xa6, 0xff, - 0x5b, 0x03, 0x89, 0x76, 0x36, 0x86, 0x92, 0x7e, 0x91, 0x2c, 0xe9, 0x5b, 0x57, 0xe0, 0xf4, 0x88, - 0x62, 0xfe, 0x83, 0x06, 0xe6, 0xe3, 0xc3, 0x1a, 0xfc, 0x21, 0x98, 0xc5, 0x2d, 0x9b, 0x12, 0xd7, - 0xea, 0x4f, 0x25, 0x83, 0x40, 0xb6, 0xd5, 0x3e, 0x1a, 0x68, 0x88, 0x51, 0x8e, 0xbc, 0xf3, 0x69, - 0x80, 0x05, 0xc9, 0xea, 0xc4, 0xf2, 0x5c, 0x9b, 0xc9, 0x1b, 0xca, 0x85, 0x9d, 0xb1, 0x9a, 0x16, - 0xa2, 0x61, 0x7d, 0xfd, 0xaf, 0x93, 0x60, 0x29, 0xe4, 0x46, 0x38, 0xc4, 0x3b, 0xc4, 0xe5, 0x63, - 0x68, 0x2a, 0xb5, 0xc4, 0x4c, 0xf7, 0x83, 0x4b, 0x87, 0x9e, 0x28, 0xb0, 0x51, 0xc3, 0x1d, 0xfc, - 0x05, 0x98, 0x66, 0x1c, 0xf3, 0x16, 0x93, 0x4f, 0x5d, 0x61, 0xeb, 0xde, 0x55, 0x01, 0xa5, 0x51, - 0x34, 0xd7, 0x85, 0x6b, 0xa4, 0xc0, 0xf4, 0xff, 0x68, 0x60, 0x35, 0x6d, 0x32, 0x06, 0x86, 0xed, - 0x27, 0x19, 0xf6, 0xfd, 0x2b, 0x1e, 0x66, 0x04, 0xcb, 0xfe, 0xaf, 0x81, 0x9b, 0x43, 0xe7, 0x96, - 0x2f, 0xa9, 0xe8, 0x4b, 0x7e, 0xaa, 0xfb, 0x1d, 0x44, 0x13, 0xb1, 0xec, 0x4b, 0x47, 0x19, 0x72, - 0x94, 0x69, 0x05, 0xdf, 0x80, 0x25, 0xea, 0x36, 0xa9, 0x4b, 0xd4, 0xc3, 0x1b, 0xe5, 0x37, 0xb3, - 0x79, 0xa4, 0x91, 0x65, 0x72, 0x57, 0xc5, 0x7c, 0xb2, 0x97, 0x42, 0x41, 0x43, 0xb8, 0xfa, 0xff, - 0x32, 0x32, 0x23, 0x67, 0x46, 0x51, 0x42, 0x72, 0x87, 0x04, 0x43, 0x25, 0xa4, 0xf6, 0xd1, 0x40, - 0x43, 0xf2, 0x46, 0x5e, 0x85, 0x0a, 0xf4, 0xca, 0xbc, 0x91, 0x46, 0x31, 0xde, 0xc8, 0x35, 0x52, - 0x60, 0x22, 0x08, 0x31, 0x93, 0xc5, 0x66, 0xaf, 0x41, 0x10, 0x07, 0x6a, 0x1f, 0x0d, 0x34, 0xf4, - 0xaf, 0x72, 0x19, 0x09, 0x92, 0x04, 0x8c, 0x9d, 0xa6, 0xff, 0xbd, 0x9d, 0x3e, 0x8d, 0x3d, 0x38, - 0x8d, 0x0d, 0xff, 0xa2, 0x01, 0x88, 0x07, 0x10, 0xb5, 0x3e, 0x41, 0x43, 0x16, 0x55, 0xaf, 0x55, - 0x12, 0xc6, 0xf6, 0x10, 0x4e, 0xf8, 0x1a, 0xaf, 0x2b, 0xff, 0x70, 0x58, 0x01, 0x65, 0x38, 0x87, - 0x36, 0x28, 0x84, 0xbb, 0xd5, 0x20, 0xf0, 0x02, 0x55, 0x9e, 0xfa, 0xa5, 0xb1, 0x48, 0x4d, 0xb3, - 0x24, 0x3f, 0x6e, 0x22, 0xd3, 0x8b, 0x6e, 0xb9, 0x10, 0x93, 0xa3, 0x38, 0xac, 0xf0, 0x62, 0x93, - 0xc8, 0x4b, 0xfe, 0x7a, 0x5e, 0x76, 0xc9, 0x68, 0x2f, 0x31, 0xd8, 0xf5, 0x2a, 0xf8, 0xce, 0x88, - 0x6b, 0xb9, 0xd6, 0x9b, 0xf5, 0x47, 0x0d, 0xc4, 0x7d, 0xc0, 0x7d, 0x90, 0xe7, 0x54, 0x55, 0x5d, - 0xf2, 0x03, 0xf0, 0x92, 0x46, 0x72, 0x4c, 0x1d, 0x12, 0xb5, 0x42, 0xb1, 0x42, 0x12, 0x05, 0xde, - 0x01, 0x33, 0x0e, 0x61, 0x0c, 0x37, 0x94, 0xe7, 0xe8, 0x73, 0xa8, 0x16, 0x6e, 0xa3, 0xbe, 0x5c, - 0x7f, 0x0c, 0x56, 0x32, 0x3e, 0x2b, 0x61, 0x19, 0x4c, 0x59, 0xf2, 0x5f, 0x1a, 0x11, 0xd0, 0x94, - 0x39, 0x27, 0x3a, 0xca, 0x8e, 0xfc, 0x73, 0x26, 0xdc, 0x37, 0x7f, 0xfc, 0xfe, 0x53, 0x69, 0xe2, - 0xc3, 0xa7, 0xd2, 0xc4, 0xc7, 0x4f, 0xa5, 0x89, 0xdf, 0xf7, 0x4a, 0xda, 0xfb, 0x5e, 0x49, 0xfb, - 0xd0, 0x2b, 0x69, 0x1f, 0x7b, 0x25, 0xed, 0x8b, 0x5e, 0x49, 0xfb, 0xf3, 0x97, 0xa5, 0x89, 0x5f, - 0xae, 0x65, 0xfe, 0x31, 0xfa, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0x72, 0x7b, 0x49, - 0x15, 0x00, 0x00, + // 1670 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x73, 0x1b, 0x4b, + 0x11, 0xf7, 0x5a, 0xf2, 0xd7, 0xc8, 0x8e, 0xed, 0xb1, 0xfd, 0x10, 0x3e, 0x48, 0xae, 0x7d, 0xaf, + 0xc0, 0xef, 0xc1, 0x5b, 0xbd, 0x38, 0x21, 0x95, 0x0a, 0x15, 0xaa, 0xbc, 0xb6, 0x42, 0x5c, 0x58, + 0xb6, 0x19, 0x99, 0x54, 0x8a, 0x02, 0x2a, 0xe3, 0xdd, 0xb1, 0x3c, 0xb1, 0xf6, 0x23, 0x3b, 0xb3, + 0xc2, 0xe2, 0x04, 0x17, 0x6e, 0x54, 0xc1, 0x95, 0xbf, 0x02, 0xaa, 0xe0, 0xc2, 0x91, 0x03, 0x15, + 0x6e, 0x29, 0x4e, 0x39, 0xa9, 0x88, 0x38, 0xc3, 0x91, 0x83, 0x4f, 0xaf, 0x66, 0x76, 0xa4, 0xfd, + 0xd0, 0xca, 0xb1, 0x2f, 0xba, 0x69, 0xa6, 0xbb, 0x7f, 0xdd, 0x33, 0xdd, 0xfd, 0x9b, 0x5e, 0x81, + 0x1f, 0x5c, 0x3e, 0x66, 0x06, 0xf5, 0x6a, 0x97, 0xe1, 0x19, 0x09, 0x5c, 0xc2, 0x09, 0xab, 0x75, + 0x88, 0x6b, 0x7b, 0x41, 0x4d, 0x09, 0xb0, 0x4f, 0x6b, 0x8c, 0x7b, 0x01, 0x6e, 0x91, 0x5a, 0xe7, + 0x7e, 0xad, 0x45, 0x5c, 0x12, 0x60, 0x4e, 0x6c, 0xc3, 0x0f, 0x3c, 0xee, 0xc1, 0x8d, 0x48, 0xcd, + 0xc0, 0x3e, 0x35, 0x94, 0x9a, 0xd1, 0xb9, 0xbf, 0xf9, 0x65, 0x8b, 0xf2, 0x8b, 0xf0, 0xcc, 0xb0, + 0x3c, 0xa7, 0xd6, 0xf2, 0x5a, 0x5e, 0x4d, 0x6a, 0x9f, 0x85, 0xe7, 0x72, 0x25, 0x17, 0xf2, 0x57, + 0x84, 0xb2, 0xa9, 0x27, 0x9c, 0x59, 0x5e, 0x90, 0xe7, 0x69, 0xf3, 0x61, 0xac, 0xe3, 0x60, 0xeb, + 0x82, 0xba, 0x24, 0xe8, 0xd6, 0xfc, 0xcb, 0x96, 0x34, 0x0a, 0x08, 0xf3, 0xc2, 0xc0, 0x22, 0x77, + 0xb2, 0x62, 0x35, 0x87, 0x70, 0x9c, 0xe7, 0xab, 0x36, 0xce, 0x2a, 0x08, 0x5d, 0x4e, 0x9d, 0x51, + 0x37, 0x8f, 0x3e, 0x66, 0xc0, 0xac, 0x0b, 0xe2, 0xe0, 0xac, 0x9d, 0xfe, 0x57, 0x0d, 0x2c, 0xec, + 0x35, 0x0f, 0xf6, 0x03, 0xda, 0x21, 0x01, 0x7c, 0x05, 0xe6, 0x45, 0x44, 0x36, 0xe6, 0xb8, 0xac, + 0x6d, 0x69, 0xdb, 0xa5, 0x9d, 0xaf, 0x8c, 0xf8, 0x7e, 0x87, 0xc0, 0x86, 0x7f, 0xd9, 0x12, 0x1b, + 0xcc, 0x10, 0xda, 0x46, 0xe7, 0xbe, 0x71, 0x7c, 0xf6, 0x9a, 0x58, 0xbc, 0x41, 0x38, 0x36, 0xe1, + 0xdb, 0x5e, 0x75, 0xaa, 0xdf, 0xab, 0x82, 0x78, 0x0f, 0x0d, 0x51, 0xe1, 0x33, 0x50, 0x64, 0x3e, + 0xb1, 0xca, 0xd3, 0x12, 0xfd, 0x33, 0x23, 0x37, 0x7b, 0xc6, 0x30, 0xa2, 0xa6, 0x4f, 0x2c, 0x73, + 0x51, 0x21, 0x16, 0xc5, 0x0a, 0x49, 0x7b, 0xfd, 0x2f, 0x1a, 0x58, 0x1a, 0x6a, 0x1d, 0x52, 0xc6, + 0xe1, 0xcf, 0x46, 0x62, 0x37, 0x6e, 0x17, 0xbb, 0xb0, 0x96, 0x91, 0xaf, 0x28, 0x3f, 0xf3, 0x83, + 0x9d, 0x44, 0xdc, 0x75, 0x30, 0x43, 0x39, 0x71, 0x58, 0x79, 0x7a, 0xab, 0xb0, 0x5d, 0xda, 0xd9, + 0xfa, 0x58, 0xe0, 0xe6, 0x92, 0x02, 0x9b, 0x39, 0x10, 0x66, 0x28, 0xb2, 0xd6, 0xff, 0x55, 0x4c, + 0x84, 0x2d, 0x8e, 0x03, 0x9f, 0x80, 0x7b, 0x98, 0x73, 0x6c, 0x5d, 0x20, 0xf2, 0x26, 0xa4, 0x01, + 0xb1, 0x65, 0xf0, 0xf3, 0x26, 0xec, 0xf7, 0xaa, 0xf7, 0x76, 0x53, 0x12, 0x94, 0xd1, 0x14, 0xb6, + 0xbe, 0x67, 0x1f, 0xb8, 0xe7, 0xde, 0xb1, 0xdb, 0xf0, 0x42, 0x97, 0xcb, 0x6b, 0x55, 0xb6, 0x27, + 0x29, 0x09, 0xca, 0x68, 0x42, 0x0b, 0xac, 0x77, 0xbc, 0x76, 0xe8, 0x90, 0x43, 0x7a, 0x4e, 0xac, + 0xae, 0xd5, 0x26, 0x0d, 0xcf, 0x26, 0xac, 0x5c, 0xd8, 0x2a, 0x6c, 0x2f, 0x98, 0xb5, 0x7e, 0xaf, + 0xba, 0xfe, 0x22, 0x47, 0x7e, 0xdd, 0xab, 0xae, 0xe5, 0xec, 0xa3, 0x5c, 0x30, 0xf8, 0x14, 0x2c, + 0xab, 0xcb, 0xd9, 0xc3, 0x3e, 0xb6, 0x28, 0xef, 0x96, 0x8b, 0x32, 0xc2, 0xb5, 0x7e, 0xaf, 0xba, + 0xdc, 0x4c, 0x8b, 0x50, 0x56, 0x17, 0x3e, 0x07, 0x4b, 0xe7, 0xec, 0x87, 0x81, 0x17, 0xfa, 0x27, + 0x5e, 0x9b, 0x5a, 0xdd, 0xf2, 0xcc, 0x96, 0xb6, 0xbd, 0x60, 0xea, 0xfd, 0x5e, 0x75, 0xe9, 0x59, + 0x33, 0x21, 0xb8, 0xce, 0x6e, 0xa0, 0xb4, 0x21, 0x7c, 0x05, 0x96, 0xb8, 0x77, 0x49, 0x5c, 0x71, + 0x75, 0x84, 0x71, 0x56, 0x9e, 0x95, 0x69, 0xfc, 0x74, 0x4c, 0x1a, 0x4f, 0x13, 0xba, 0xe6, 0x86, + 0xca, 0xe4, 0x52, 0x72, 0x97, 0xa1, 0x34, 0x20, 0xdc, 0x03, 0xab, 0x41, 0x94, 0x17, 0x86, 0x88, + 0x1f, 0x9e, 0xb5, 0x29, 0xbb, 0x28, 0xcf, 0xc9, 0xc3, 0x6e, 0xf4, 0x7b, 0xd5, 0x55, 0x94, 0x15, + 0xa2, 0x51, 0x7d, 0xf8, 0x10, 0x2c, 0x32, 0x72, 0x48, 0xdd, 0xf0, 0x2a, 0x4a, 0xe7, 0xbc, 0xb4, + 0x5f, 0xe9, 0xf7, 0xaa, 0x8b, 0xcd, 0x7a, 0xbc, 0x8f, 0x52, 0x5a, 0xfa, 0x9f, 0x35, 0x30, 0xb7, + 0xd7, 0x3c, 0x38, 0xf2, 0x6c, 0x32, 0x81, 0x0e, 0xde, 0x4f, 0x75, 0xb0, 0x3e, 0xbe, 0x11, 0x44, + 0x3c, 0x63, 0xfb, 0xf7, 0x7f, 0x51, 0xff, 0x0a, 0x1d, 0xc5, 0x3d, 0x5b, 0xa0, 0xe8, 0x62, 0x87, + 0xc8, 0xa8, 0x17, 0x62, 0x9b, 0x23, 0xec, 0x10, 0x24, 0x25, 0xf0, 0x5b, 0x60, 0xd6, 0xf5, 0x6c, + 0x72, 0xb0, 0x2f, 0x7d, 0x2f, 0x98, 0xf7, 0x94, 0xce, 0xec, 0x91, 0xdc, 0x45, 0x4a, 0x2a, 0x6e, + 0x91, 0x7b, 0xbe, 0xd7, 0xf6, 0x5a, 0xdd, 0x1f, 0x91, 0xee, 0xa0, 0xa4, 0xe5, 0x2d, 0x9e, 0x26, + 0xf6, 0x51, 0x4a, 0x0b, 0xfe, 0x1c, 0x94, 0x70, 0xbb, 0xed, 0x59, 0x98, 0xe3, 0xb3, 0x36, 0x91, + 0x75, 0x5a, 0xda, 0xf9, 0x62, 0xcc, 0xf1, 0xa2, 0x16, 0x10, 0x7e, 0x91, 0x22, 0x7e, 0x66, 0x2e, + 0xf7, 0x7b, 0xd5, 0xd2, 0x6e, 0x0c, 0x81, 0x92, 0x78, 0xfa, 0x9f, 0x34, 0x50, 0x52, 0x07, 0x9e, + 0x00, 0x5d, 0xed, 0xa5, 0xe9, 0xaa, 0x72, 0x73, 0x96, 0xc6, 0x90, 0xd5, 0x2f, 0x86, 0x11, 0x4b, + 0xa6, 0x3a, 0x06, 0x73, 0xb6, 0x4c, 0x15, 0x2b, 0x6b, 0x12, 0xf5, 0xb3, 0x9b, 0x51, 0x15, 0x11, + 0x2e, 0x2b, 0xec, 0xb9, 0x68, 0xcd, 0xd0, 0x00, 0x45, 0xff, 0x7f, 0x01, 0xc0, 0xbd, 0xe6, 0x41, + 0x86, 0x06, 0x26, 0x50, 0xc2, 0x14, 0x2c, 0x8a, 0x52, 0x19, 0x14, 0x83, 0x2a, 0xe5, 0x07, 0xb7, + 0xbc, 0x7f, 0x7c, 0x46, 0xda, 0x4d, 0xd2, 0x26, 0x16, 0xf7, 0x82, 0xa8, 0xaa, 0x8e, 0x12, 0x60, + 0x28, 0x05, 0x0d, 0xf7, 0xc1, 0xca, 0x80, 0xd5, 0xda, 0x98, 0x31, 0x51, 0xcd, 0xe5, 0x82, 0xac, + 0xde, 0xb2, 0x0a, 0x71, 0xa5, 0x99, 0x91, 0xa3, 0x11, 0x0b, 0xf8, 0x12, 0xcc, 0x5b, 0x49, 0x02, + 0xfd, 0x48, 0xb1, 0x18, 0x83, 0x69, 0xc4, 0xf8, 0x71, 0x88, 0x5d, 0x4e, 0x79, 0xd7, 0x5c, 0x14, + 0x85, 0x32, 0x64, 0xda, 0x21, 0x1a, 0x64, 0x60, 0xd5, 0xc1, 0x57, 0xd4, 0x09, 0x9d, 0xa8, 0xa4, + 0x9b, 0xf4, 0x57, 0x44, 0xd2, 0xec, 0xdd, 0x5d, 0x48, 0x9a, 0x6b, 0x64, 0xc1, 0xd0, 0x28, 0xbe, + 0xfe, 0x0f, 0x0d, 0x7c, 0x32, 0x9a, 0xf8, 0x09, 0xb4, 0xc5, 0x51, 0xba, 0x2d, 0x3e, 0x1f, 0x5f, + 0xc0, 0x99, 0xd8, 0xc6, 0x74, 0xc8, 0xef, 0x66, 0xc1, 0x62, 0x32, 0x7d, 0x13, 0xa8, 0xdd, 0xef, + 0x81, 0x92, 0x1f, 0x78, 0x1d, 0xca, 0xa8, 0xe7, 0x92, 0x40, 0x31, 0xe1, 0x9a, 0x32, 0x29, 0x9d, + 0xc4, 0x22, 0x94, 0xd4, 0x83, 0x2d, 0x00, 0x7c, 0x1c, 0x60, 0x87, 0x70, 0xd1, 0xbf, 0x05, 0x79, + 0xfc, 0x07, 0x63, 0x8e, 0x9f, 0x3c, 0x91, 0x71, 0x32, 0xb4, 0xaa, 0xbb, 0x3c, 0xe8, 0xc6, 0xd1, + 0xc5, 0x02, 0x94, 0x80, 0x86, 0x97, 0x60, 0x29, 0x20, 0x56, 0x1b, 0x53, 0x47, 0xbd, 0xd9, 0x45, + 0x19, 0x61, 0x5d, 0x3c, 0xa0, 0x28, 0x29, 0xb8, 0xee, 0x55, 0xbf, 0x1a, 0x9d, 0xba, 0x8d, 0x13, + 0x12, 0x30, 0xca, 0x38, 0x71, 0x79, 0x54, 0x30, 0x29, 0x1b, 0x94, 0xc6, 0x16, 0x4c, 0xef, 0x88, + 0x27, 0xf0, 0xd8, 0xe7, 0xd4, 0x73, 0x59, 0x79, 0x26, 0x66, 0xfa, 0x46, 0x62, 0x1f, 0xa5, 0xb4, + 0xe0, 0x21, 0x58, 0x17, 0xcc, 0xfc, 0xcb, 0xc8, 0x41, 0xfd, 0xca, 0xc7, 0xae, 0xb8, 0xa5, 0xf2, + 0xac, 0x7c, 0x6d, 0xcb, 0x62, 0xf4, 0xd9, 0xcd, 0x91, 0xa3, 0x5c, 0x2b, 0xf8, 0x12, 0xac, 0x46, + 0xb3, 0x8f, 0x49, 0x5d, 0x9b, 0xba, 0x2d, 0x31, 0xf9, 0xc8, 0x87, 0x7f, 0xc1, 0xfc, 0x42, 0x74, + 0xc4, 0x8b, 0xac, 0xf0, 0x3a, 0x6f, 0x13, 0x8d, 0x82, 0xc0, 0x37, 0x60, 0x55, 0x7a, 0x24, 0xb6, + 0xa2, 0x13, 0x4a, 0x58, 0x79, 0x5e, 0xa6, 0x6e, 0x3b, 0x99, 0x3a, 0x71, 0x75, 0xd1, 0xd4, 0x12, + 0x91, 0xce, 0x80, 0x9c, 0x4e, 0x49, 0xe0, 0x98, 0xdf, 0x54, 0xf9, 0x5a, 0xdd, 0xcd, 0x42, 0xa1, + 0x51, 0xf4, 0xcd, 0xa7, 0x60, 0x39, 0x93, 0x70, 0xb8, 0x02, 0x0a, 0x97, 0xa4, 0x1b, 0x3d, 0xcb, + 0x48, 0xfc, 0x84, 0xeb, 0x60, 0xa6, 0x83, 0xdb, 0x21, 0x89, 0x8a, 0x0f, 0x45, 0x8b, 0x27, 0xd3, + 0x8f, 0x35, 0xfd, 0x6f, 0x1a, 0x48, 0xd1, 0xd9, 0x04, 0x5a, 0xfa, 0x79, 0xba, 0xa5, 0x3f, 0xbd, + 0x45, 0x4d, 0x8f, 0x69, 0xe6, 0xdf, 0x68, 0x60, 0x31, 0x39, 0xe2, 0xc1, 0xef, 0x82, 0x79, 0x1c, + 0xda, 0x94, 0xb8, 0xd6, 0x60, 0x2a, 0x19, 0x06, 0xb2, 0xab, 0xf6, 0xd1, 0x50, 0x43, 0x0c, 0x80, + 0xe4, 0xca, 0xa7, 0x01, 0x16, 0x45, 0xd6, 0x24, 0x96, 0xe7, 0xda, 0x4c, 0xde, 0x50, 0x21, 0x62, + 0xc6, 0x7a, 0x56, 0x88, 0x46, 0xf5, 0xf5, 0x3f, 0x4e, 0x83, 0x95, 0xa8, 0x36, 0xa2, 0xd1, 0xdf, + 0x21, 0x2e, 0x9f, 0x00, 0xa9, 0x34, 0x52, 0x33, 0xdd, 0x77, 0x6e, 0x1c, 0x7a, 0xe2, 0xc0, 0xc6, + 0x0d, 0x77, 0xf0, 0x27, 0x60, 0x96, 0x71, 0xcc, 0x43, 0x26, 0x9f, 0xba, 0xd2, 0xce, 0x97, 0xb7, + 0x05, 0x94, 0x46, 0xf1, 0x5c, 0x17, 0xad, 0x91, 0x02, 0xd3, 0xff, 0xae, 0x81, 0xf5, 0xac, 0xc9, + 0x04, 0x2a, 0xec, 0x30, 0x5d, 0x61, 0xdf, 0xbe, 0xe5, 0x61, 0xc6, 0x7d, 0x01, 0x6a, 0xe0, 0x93, + 0x91, 0x73, 0xcb, 0x97, 0x54, 0xf0, 0x92, 0x9f, 0x61, 0xbf, 0xa3, 0x78, 0x22, 0x96, 0xbc, 0x74, + 0x92, 0x23, 0x47, 0xb9, 0x56, 0xf0, 0x35, 0x58, 0xa1, 0x6e, 0x9b, 0xba, 0x44, 0x3d, 0xbc, 0x71, + 0x7e, 0x73, 0xc9, 0x23, 0x8b, 0x2c, 0x93, 0xbb, 0x2e, 0xe6, 0x93, 0x83, 0x0c, 0x0a, 0x1a, 0xc1, + 0xd5, 0xff, 0x99, 0x93, 0x19, 0x39, 0x33, 0x8a, 0x16, 0x92, 0x3b, 0x24, 0x18, 0x69, 0x21, 0xb5, + 0x8f, 0x86, 0x1a, 0xb2, 0x6e, 0xe4, 0x55, 0xa8, 0x40, 0x6f, 0x5d, 0x37, 0xd2, 0x28, 0x51, 0x37, + 0x72, 0x8d, 0x14, 0x98, 0x08, 0x42, 0xcc, 0x64, 0x89, 0xd9, 0x6b, 0x18, 0xc4, 0x91, 0xda, 0x47, + 0x43, 0x0d, 0xfd, 0xbf, 0x85, 0x9c, 0x04, 0xc9, 0x02, 0x4c, 0x9c, 0x66, 0xf0, 0x95, 0x9e, 0x3d, + 0x8d, 0x3d, 0x3c, 0x8d, 0x0d, 0xff, 0xa0, 0x01, 0x88, 0x87, 0x10, 0x8d, 0x41, 0x81, 0x46, 0x55, + 0x54, 0xbf, 0x53, 0x4b, 0x18, 0xbb, 0x23, 0x38, 0xd1, 0x6b, 0xbc, 0xa9, 0xfc, 0xc3, 0x51, 0x05, + 0x94, 0xe3, 0x1c, 0xda, 0xa0, 0x14, 0xed, 0xd6, 0x83, 0xc0, 0x0b, 0x54, 0x7b, 0xea, 0x37, 0xc6, + 0x22, 0x35, 0xcd, 0x8a, 0xfc, 0xb8, 0x89, 0x4d, 0xaf, 0x7b, 0xd5, 0x52, 0x42, 0x8e, 0x92, 0xb0, + 0xc2, 0x8b, 0x4d, 0x62, 0x2f, 0xc5, 0xbb, 0x79, 0xd9, 0x27, 0xe3, 0xbd, 0x24, 0x60, 0x37, 0xeb, + 0xe0, 0x1b, 0x63, 0xae, 0xe5, 0x4e, 0x6f, 0xd6, 0x6f, 0x35, 0x90, 0xf4, 0x01, 0x0f, 0x41, 0x91, + 0x53, 0xd5, 0x75, 0xe9, 0x0f, 0xc0, 0x1b, 0x88, 0xe4, 0x94, 0x3a, 0x24, 0xa6, 0x42, 0xb1, 0x42, + 0x12, 0x05, 0x7e, 0x0e, 0xe6, 0x1c, 0xc2, 0x18, 0x6e, 0x29, 0xcf, 0xf1, 0xe7, 0x50, 0x23, 0xda, + 0x46, 0x03, 0xb9, 0xfe, 0x08, 0xac, 0xe5, 0x7c, 0x56, 0xc2, 0x2a, 0x98, 0xb1, 0xe4, 0x9f, 0x01, + 0x22, 0xa0, 0x19, 0x73, 0x41, 0x30, 0xca, 0x9e, 0xfc, 0x17, 0x20, 0xda, 0x37, 0xbf, 0xff, 0xf6, + 0x43, 0x65, 0xea, 0xdd, 0x87, 0xca, 0xd4, 0xfb, 0x0f, 0x95, 0xa9, 0x5f, 0xf7, 0x2b, 0xda, 0xdb, + 0x7e, 0x45, 0x7b, 0xd7, 0xaf, 0x68, 0xef, 0xfb, 0x15, 0xed, 0xdf, 0xfd, 0x8a, 0xf6, 0xfb, 0xff, + 0x54, 0xa6, 0x7e, 0xba, 0x91, 0xfb, 0x77, 0xea, 0xd7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0d, 0xf9, + 0xe3, 0xd5, 0x7f, 0x15, 0x00, 0x00, } func (m *CSIDriver) Marshal() (dAtA []byte, err error) { @@ -826,6 +827,16 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SELinuxMount != nil { + i-- + if *m.SELinuxMount { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } if m.RequiresRepublish != nil { i-- if *m.RequiresRepublish { @@ -1795,6 +1806,9 @@ func (m *CSIDriverSpec) Size() (n int) { if m.RequiresRepublish != nil { n += 2 } + if m.SELinuxMount != nil { + n += 2 + } return n } @@ -2148,6 +2162,7 @@ func (this *CSIDriverSpec) String() string { `FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`, `TokenRequests:` + repeatedStringForTokenRequests + `,`, `RequiresRepublish:` + valueToStringGenerated(this.RequiresRepublish) + `,`, + `SELinuxMount:` + valueToStringGenerated(this.SELinuxMount) + `,`, `}`, }, "") return s @@ -2844,6 +2859,27 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.RequiresRepublish = &b + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SELinuxMount", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.SELinuxMount = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/storage/v1/generated.proto b/vendor/k8s.io/api/storage/v1/generated.proto index 45417116a1f..5f8eccaefc5 100644 --- a/vendor/k8s.io/api/storage/v1/generated.proto +++ b/vendor/k8s.io/api/storage/v1/generated.proto @@ -46,7 +46,7 @@ message CSIDriver { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. optional CSIDriverSpec spec = 2; } @@ -79,16 +79,15 @@ message CSIDriverSpec { // +optional optional bool attachRequired = 1; - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -110,29 +109,27 @@ message CSIDriverSpec { optional bool podInfoOnMount = 2; // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html - // A driver can support one or more of these modes and - // more modes may be added in the future. - // This field is beta. + // A driver can support one or more of these modes and more modes may be added in the future. // + // This field is beta. // This field is immutable. // // +optional // +listType=set repeated string volumeLifecycleModes = 3; - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -149,7 +146,7 @@ message CSIDriverSpec { // +featureGate=CSIStorageCapacity optional bool storageCapacity = 4; - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -159,10 +156,11 @@ message CSIDriverSpec { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional optional string fsGroupPolicy = 5; - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -182,7 +180,7 @@ message CSIDriverSpec { // +listType=atomic repeated TokenRequest tokenRequests = 6; - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -192,6 +190,28 @@ message CSIDriverSpec { // // +optional optional bool requiresRepublish = 7; + + // seLinuxMount specifies if the CSI driver supports "-o context" + // mount option. + // + // When "true", the CSI driver must ensure that all volumes provided by this CSI + // driver can be mounted separately with different `-o context` options. This is + // typical for storage backends that provide volumes as filesystems on block + // devices or as independent shared volumes. + // Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount + // option when mounting a ReadWriteOncePod volume used in Pod that has + // explicitly set SELinux context. In the future, it may be expanded to other + // volume AccessModes. In any case, Kubernetes will ensure that the volume is + // mounted only with a single SELinux context. + // + // When "false", Kubernetes won't pass any special SELinux mount options to the driver. + // This is typical for volumes that represent subdirectories of a bigger shared filesystem. + // + // Default is "false". + // + // +featureGate=SELinuxMountReadWriteOncePod + // +optional + optional bool seLinuxMount = 8; } // CSINode holds information about all CSI drivers installed on a node. @@ -204,6 +224,7 @@ message CSIDriverSpec { // enough that it doesn't create this object. // CSINode has an OwnerReference that points to the corresponding node object. message CSINode { + // Standard object's metadata. // metadata.name must be the Kubernetes node name. optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; @@ -213,7 +234,7 @@ message CSINode { // CSINodeDriver holds information about the specification of one CSI driver installed on a node message CSINodeDriver { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. optional string name = 1; @@ -293,11 +314,11 @@ message CSINodeSpec { // the scheduler assumes that capacity is insufficient and tries some other // node. message CSIStorageCapacity { - // Standard object's metadata. The name has no particular meaning. It must be - // be a DNS subdomain (dots allowed, 253 characters). To ensure that - // there are no conflicts with other CSI drivers on the cluster, the recommendation - // is to use csisc-, a generated name, or a reverse-domain name which ends - // with the unique CSI driver name. + // Standard object's metadata. + // The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). + // To ensure that there are no conflicts with other CSI drivers on the cluster, + // the recommendation is to use csisc-, a generated name, or a reverse-domain name + // which ends with the unique CSI driver name. // // Objects are namespaced. // @@ -305,7 +326,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -314,7 +335,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -322,7 +343,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -334,7 +355,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -356,7 +377,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -373,36 +394,36 @@ message StorageClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. optional string provisioner = 2; - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional map parameters = 3; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional optional string reclaimPolicy = 4; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional repeated string mountOptions = 5; - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand. // +optional optional bool allowVolumeExpansion = 6; - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional optional string volumeBindingMode = 7; - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -418,17 +439,17 @@ message StorageClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of StorageClasses + // items is the list of StorageClasses repeated StorageClass items = 2; } // TokenRequest contains parameters of a service account token. message TokenRequest { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. optional string audience = 1; - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec". // // +optional @@ -445,11 +466,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -463,7 +484,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -472,7 +493,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -488,39 +509,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -529,11 +550,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -542,7 +563,7 @@ message VolumeError { // VolumeNodeResources is a set of resource limits for scheduling of volumes. message VolumeNodeResources { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is not specified, then the supported number of volumes on this node is unbounded. diff --git a/vendor/k8s.io/api/storage/v1/types.go b/vendor/k8s.io/api/storage/v1/types.go index 4812287abf6..c785f368efd 100644 --- a/vendor/k8s.io/api/storage/v1/types.go +++ b/vendor/k8s.io/api/storage/v1/types.go @@ -33,41 +33,42 @@ import ( // according to etcd is in ObjectMeta.Name. type StorageClass struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"` - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand. // +optional AllowVolumeExpansion *bool `json:"allowVolumeExpansion,omitempty" protobuf:"varint,6,opt,name=allowVolumeExpansion"` - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -81,12 +82,13 @@ type StorageClass struct { // StorageClassList is a collection of storage classes. type StorageClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of StorageClasses + // items is the list of StorageClasses Items []StorageClass `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -122,11 +124,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -138,25 +140,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -165,7 +168,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -181,26 +184,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -209,11 +212,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -242,7 +245,7 @@ type CSIDriver struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. Spec CSIDriverSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` } @@ -279,16 +282,15 @@ type CSIDriverSpec struct { // +optional AttachRequired *bool `json:"attachRequired,omitempty" protobuf:"varint,1,opt,name=attachRequired"` - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -310,29 +312,27 @@ type CSIDriverSpec struct { PodInfoOnMount *bool `json:"podInfoOnMount,omitempty" protobuf:"bytes,2,opt,name=podInfoOnMount"` // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html - // A driver can support one or more of these modes and - // more modes may be added in the future. - // This field is beta. + // A driver can support one or more of these modes and more modes may be added in the future. // + // This field is beta. // This field is immutable. // // +optional // +listType=set VolumeLifecycleModes []VolumeLifecycleMode `json:"volumeLifecycleModes,omitempty" protobuf:"bytes,3,opt,name=volumeLifecycleModes"` - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -349,7 +349,7 @@ type CSIDriverSpec struct { // +featureGate=CSIStorageCapacity StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -359,10 +359,11 @@ type CSIDriverSpec struct { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -382,7 +383,7 @@ type CSIDriverSpec struct { // +listType=atomic TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"` - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -392,6 +393,28 @@ type CSIDriverSpec struct { // // +optional RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"` + + // seLinuxMount specifies if the CSI driver supports "-o context" + // mount option. + // + // When "true", the CSI driver must ensure that all volumes provided by this CSI + // driver can be mounted separately with different `-o context` options. This is + // typical for storage backends that provide volumes as filesystems on block + // devices or as independent shared volumes. + // Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount + // option when mounting a ReadWriteOncePod volume used in Pod that has + // explicitly set SELinux context. In the future, it may be expanded to other + // volume AccessModes. In any case, Kubernetes will ensure that the volume is + // mounted only with a single SELinux context. + // + // When "false", Kubernetes won't pass any special SELinux mount options to the driver. + // This is typical for volumes that represent subdirectories of a bigger shared filesystem. + // + // Default is "false". + // + // +featureGate=SELinuxMountReadWriteOncePod + // +optional + SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"` } // FSGroupPolicy specifies if a CSI Driver supports modifying @@ -432,12 +455,11 @@ type VolumeLifecycleMode string // TokenRequest contains parameters of a service account token. type TokenRequest struct { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. - // Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"` - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec". // // +optional @@ -481,6 +503,7 @@ const ( type CSINode struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // metadata.name must be the Kubernetes node name. metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -499,7 +522,7 @@ type CSINodeSpec struct { // CSINodeDriver holds information about the specification of one CSI driver installed on a node type CSINodeDriver struct { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` @@ -536,7 +559,7 @@ type CSINodeDriver struct { // VolumeNodeResources is a set of resource limits for scheduling of volumes. type VolumeNodeResources struct { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is not specified, then the supported number of volumes on this node is unbounded. @@ -588,11 +611,12 @@ type CSINodeList struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. The name has no particular meaning. It must be - // be a DNS subdomain (dots allowed, 253 characters). To ensure that - // there are no conflicts with other CSI drivers on the cluster, the recommendation - // is to use csisc-, a generated name, or a reverse-domain name which ends - // with the unique CSI driver name. + + // Standard object's metadata. + // The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). + // To ensure that there are no conflicts with other CSI drivers on the cluster, + // the recommendation is to use csisc-, a generated name, or a reverse-domain name + // which ends with the unique CSI driver name. // // Objects are namespaced. // @@ -600,7 +624,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -609,7 +633,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -617,7 +641,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -629,7 +653,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -649,12 +673,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go index 7a407db46b2..c92a7f95a29 100644 --- a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIDriver = map[string]string{ "": "CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.", "metadata": "Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the CSI Driver.", + "spec": "spec represents the specification of the CSI Driver.", } func (CSIDriver) SwaggerDoc() map[string]string { @@ -50,12 +50,13 @@ func (CSIDriverList) SwaggerDoc() map[string]string { var map_CSIDriverSpec = map[string]string{ "": "CSIDriverSpec is the specification of a CSIDriver.", "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", - "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", - "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", - "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", - "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", - "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "podInfoOnMount": "podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations, if set to true. If set to false, pod information will not be passed on mount. Default is false.\n\nThe CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext.\n\nThe following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", + "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism.\n\nThe other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume.\n\nFor more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is beta. This field is immutable.", + "storageCapacity": "storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information, if set to true.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", + "fsGroupPolicy": "fsGroupPolicy defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", + "tokenRequests": "tokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", + "requiresRepublish": "requiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { @@ -64,7 +65,7 @@ func (CSIDriverSpec) SwaggerDoc() map[string]string { var map_CSINode = map[string]string{ "": "CSINode holds information about all CSI drivers installed on a node. CSI drivers do not need to create the CSINode object directly. As long as they use the node-driver-registrar sidecar container, the kubelet will automatically populate the CSINode object for the CSI driver as part of kubelet plugin registration. CSINode has the same name as a node. If the object is missing, it means either there are no CSI Drivers available on the node, or the Kubelet version is low enough that it doesn't create this object. CSINode has an OwnerReference that points to the corresponding node object.", - "metadata": "metadata.name must be the Kubernetes node name.", + "metadata": "Standard object's metadata. metadata.name must be the Kubernetes node name.", "spec": "spec is the specification of CSINode", } @@ -74,7 +75,7 @@ func (CSINode) SwaggerDoc() map[string]string { var map_CSINodeDriver = map[string]string{ "": "CSINodeDriver holds information about the specification of one CSI driver installed on a node", - "name": "This is the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", + "name": "name represents the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", "nodeID": "nodeID of the node from the driver point of view. This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as \"node1\", but the storage system may refer to the same node as \"nodeA\". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. \"nodeA\" instead of \"node1\". This field is required.", "topologyKeys": "topologyKeys is the list of keys supported by the driver. When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. \"company.com/zone\", \"company.com/region\"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.", "allocatable": "allocatable represents the volume resources of a node that are available for scheduling. This field is beta.", @@ -105,11 +106,11 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", - "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "metadata": "Standard object's metadata. The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -119,7 +120,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -129,13 +130,13 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_StorageClass = map[string]string{ "": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "provisioner": "Provisioner indicates the type of the provisioner.", - "parameters": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.", - "reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.", - "mountOptions": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", - "allowVolumeExpansion": "AllowVolumeExpansion shows whether the storage class allow volume expand", - "volumeBindingMode": "VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", - "allowedTopologies": "Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", + "provisioner": "provisioner indicates the type of the provisioner.", + "parameters": "parameters holds the parameters for the provisioner that should create volumes of this storage class.", + "reclaimPolicy": "reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.", + "mountOptions": "mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", + "allowVolumeExpansion": "allowVolumeExpansion shows whether the storage class allow volume expand.", + "volumeBindingMode": "volumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", + "allowedTopologies": "allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", } func (StorageClass) SwaggerDoc() map[string]string { @@ -145,7 +146,7 @@ func (StorageClass) SwaggerDoc() map[string]string { var map_StorageClassList = map[string]string{ "": "StorageClassList is a collection of storage classes.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of StorageClasses", + "items": "items is the list of StorageClasses", } func (StorageClassList) SwaggerDoc() map[string]string { @@ -154,8 +155,8 @@ func (StorageClassList) SwaggerDoc() map[string]string { var map_TokenRequest = map[string]string{ "": "TokenRequest contains parameters of a service account token.", - "audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", - "expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".", + "audience": "audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", + "expirationSeconds": "expirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".", } func (TokenRequest) SwaggerDoc() map[string]string { @@ -165,8 +166,8 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -176,7 +177,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -185,7 +186,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -194,9 +195,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -205,10 +206,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -217,8 +218,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { @@ -227,7 +228,7 @@ func (VolumeError) SwaggerDoc() map[string]string { var map_VolumeNodeResources = map[string]string{ "": "VolumeNodeResources is a set of resource limits for scheduling of volumes.", - "count": "Maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.", + "count": "count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.", } func (VolumeNodeResources) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go index b14b7fbcd87..74ae83bca82 100644 --- a/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go @@ -127,6 +127,11 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) { *out = new(bool) **out = **in } + if in.SELinuxMount != nil { + in, out := &in.SELinuxMount, &out.SELinuxMount + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/api/storage/v1alpha1/generated.proto b/vendor/k8s.io/api/storage/v1alpha1/generated.proto index a5345122607..88250a0f013 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/storage/v1alpha1/generated.proto @@ -67,7 +67,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -76,7 +76,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -84,7 +84,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -96,7 +96,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -118,7 +118,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -134,11 +134,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -152,7 +152,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -161,7 +161,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -177,39 +177,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -218,11 +218,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string maybe logged, so it should not contain sensitive // information. // +optional diff --git a/vendor/k8s.io/api/storage/v1alpha1/types.go b/vendor/k8s.io/api/storage/v1alpha1/types.go index fe8c9e3cd0a..59ef348a316 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/types.go +++ b/vendor/k8s.io/api/storage/v1alpha1/types.go @@ -41,11 +41,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -60,25 +60,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -87,7 +88,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -103,26 +104,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -131,11 +132,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string maybe logged, so it should not contain sensitive // information. // +optional @@ -174,6 +175,7 @@ type VolumeError struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that // there are no conflicts with other CSI drivers on the cluster, the recommendation @@ -186,7 +188,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -195,7 +197,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -203,7 +205,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -215,7 +217,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -238,12 +240,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go index a228a3fec7f..ba6afbd5916 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -43,7 +43,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -53,8 +53,8 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -64,7 +64,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -73,7 +73,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -93,10 +93,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -105,8 +105,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string maybe logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string maybe logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.pb.go b/vendor/k8s.io/api/storage/v1beta1/generated.pb.go index 379ce8f1836..42ef65ca0fa 100644 --- a/vendor/k8s.io/api/storage/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/storage/v1beta1/generated.pb.go @@ -609,111 +609,112 @@ func init() { } var fileDescriptor_7d2980599fd0de80 = []byte{ - // 1654 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0x1b, 0x37, - 0x16, 0xf7, 0x58, 0xf2, 0x17, 0x65, 0xc7, 0x36, 0xed, 0x64, 0xb5, 0x3a, 0x48, 0x86, 0x16, 0xbb, - 0x71, 0x82, 0xec, 0x28, 0xf1, 0x66, 0x83, 0x20, 0x40, 0x80, 0xf5, 0xd8, 0xde, 0x8d, 0x12, 0xcb, - 0x71, 0x28, 0x23, 0x08, 0x82, 0x3d, 0x2c, 0x35, 0x43, 0xcb, 0x8c, 0x35, 0x1f, 0x19, 0x52, 0xde, - 0xa8, 0xa7, 0xf6, 0xd2, 0x73, 0xd1, 0x43, 0xef, 0x05, 0xfa, 0x2f, 0xb4, 0x40, 0x7b, 0xe9, 0xb1, - 0x01, 0x0a, 0x14, 0x41, 0x4f, 0x39, 0x09, 0x8d, 0xfa, 0x27, 0x14, 0xe8, 0xc1, 0xe8, 0xa1, 0x20, - 0x87, 0xd2, 0x7c, 0x49, 0xb1, 0xdd, 0x83, 0x6e, 0xe2, 0xfb, 0xf8, 0xbd, 0x47, 0xf2, 0xf7, 0x1e, - 0xdf, 0x08, 0x6c, 0x1d, 0xdf, 0x65, 0x3a, 0x75, 0x2b, 0xc7, 0xed, 0x06, 0xf1, 0x1d, 0xc2, 0x09, - 0xab, 0x9c, 0x10, 0xc7, 0x72, 0xfd, 0x8a, 0x52, 0x60, 0x8f, 0x56, 0x18, 0x77, 0x7d, 0xdc, 0x24, - 0x95, 0x93, 0x5b, 0x0d, 0xc2, 0xf1, 0xad, 0x4a, 0x93, 0x38, 0xc4, 0xc7, 0x9c, 0x58, 0xba, 0xe7, - 0xbb, 0xdc, 0x85, 0x85, 0xc0, 0x56, 0xc7, 0x1e, 0xd5, 0x95, 0xad, 0xae, 0x6c, 0x0b, 0x7f, 0x6f, - 0x52, 0x7e, 0xd4, 0x6e, 0xe8, 0xa6, 0x6b, 0x57, 0x9a, 0x6e, 0xd3, 0xad, 0x48, 0x97, 0x46, 0xfb, - 0x50, 0xae, 0xe4, 0x42, 0xfe, 0x0a, 0xa0, 0x0a, 0xe5, 0x48, 0x58, 0xd3, 0xf5, 0x45, 0xcc, 0x64, - 0xb8, 0xc2, 0xed, 0xd0, 0xc6, 0xc6, 0xe6, 0x11, 0x75, 0x88, 0xdf, 0xa9, 0x78, 0xc7, 0x4d, 0xe9, - 0xe4, 0x13, 0xe6, 0xb6, 0x7d, 0x93, 0x5c, 0xc8, 0x8b, 0x55, 0x6c, 0xc2, 0xf1, 0xb0, 0x58, 0x95, - 0x51, 0x5e, 0x7e, 0xdb, 0xe1, 0xd4, 0x4e, 0x87, 0xb9, 0x73, 0x96, 0x03, 0x33, 0x8f, 0x88, 0x8d, - 0x93, 0x7e, 0xe5, 0x6f, 0x34, 0x30, 0xb7, 0x55, 0xaf, 0x6e, 0xfb, 0xf4, 0x84, 0xf8, 0xf0, 0x7f, - 0x60, 0x56, 0x64, 0x64, 0x61, 0x8e, 0xf3, 0xda, 0x9a, 0xb6, 0x9e, 0xdb, 0xb8, 0xa9, 0x87, 0x87, - 0x3c, 0x00, 0xd6, 0xbd, 0xe3, 0xa6, 0x10, 0x30, 0x5d, 0x58, 0xeb, 0x27, 0xb7, 0xf4, 0xc7, 0x8d, - 0x17, 0xc4, 0xe4, 0x35, 0xc2, 0xb1, 0x01, 0x5f, 0x77, 0x4b, 0x13, 0xbd, 0x6e, 0x09, 0x84, 0x32, - 0x34, 0x40, 0x85, 0x8f, 0x40, 0x96, 0x79, 0xc4, 0xcc, 0x4f, 0x4a, 0xf4, 0x6b, 0xfa, 0xe8, 0x2b, - 0xd4, 0x07, 0x69, 0xd5, 0x3d, 0x62, 0x1a, 0xf3, 0x0a, 0x36, 0x2b, 0x56, 0x48, 0x82, 0x94, 0xbf, - 0xd6, 0xc0, 0xc2, 0xc0, 0x6a, 0x97, 0x32, 0x0e, 0xff, 0x9b, 0xda, 0x80, 0x7e, 0xbe, 0x0d, 0x08, - 0x6f, 0x99, 0xfe, 0x92, 0x8a, 0x33, 0xdb, 0x97, 0x44, 0x92, 0x7f, 0x08, 0xa6, 0x28, 0x27, 0x36, - 0xcb, 0x4f, 0xae, 0x65, 0xd6, 0x73, 0x1b, 0x7f, 0x3d, 0x57, 0xf6, 0xc6, 0x82, 0x42, 0x9c, 0xaa, - 0x0a, 0x5f, 0x14, 0x40, 0x94, 0x3f, 0xcf, 0x46, 0x72, 0x17, 0x7b, 0x82, 0xf7, 0xc0, 0x25, 0xcc, - 0x39, 0x36, 0x8f, 0x10, 0x79, 0xd9, 0xa6, 0x3e, 0xb1, 0xe4, 0x0e, 0x66, 0x0d, 0xd8, 0xeb, 0x96, - 0x2e, 0x6d, 0xc6, 0x34, 0x28, 0x61, 0x29, 0x7c, 0x3d, 0xd7, 0xaa, 0x3a, 0x87, 0xee, 0x63, 0xa7, - 0xe6, 0xb6, 0x1d, 0x2e, 0x0f, 0x58, 0xf9, 0xee, 0xc7, 0x34, 0x28, 0x61, 0x09, 0x4d, 0xb0, 0x7a, - 0xe2, 0xb6, 0xda, 0x36, 0xd9, 0xa5, 0x87, 0xc4, 0xec, 0x98, 0x2d, 0x52, 0x73, 0x2d, 0xc2, 0xf2, - 0x99, 0xb5, 0xcc, 0xfa, 0x9c, 0x51, 0xe9, 0x75, 0x4b, 0xab, 0x4f, 0x87, 0xe8, 0x4f, 0xbb, 0xa5, - 0x95, 0x21, 0x72, 0x34, 0x14, 0x0c, 0xde, 0x07, 0x8b, 0xea, 0x84, 0xb6, 0xb0, 0x87, 0x4d, 0xca, - 0x3b, 0xf9, 0xac, 0xcc, 0x70, 0xa5, 0xd7, 0x2d, 0x2d, 0xd6, 0xe3, 0x2a, 0x94, 0xb4, 0x85, 0x0f, - 0xc0, 0xc2, 0x21, 0xfb, 0x8f, 0xef, 0xb6, 0xbd, 0x7d, 0xb7, 0x45, 0xcd, 0x4e, 0x7e, 0x6a, 0x4d, - 0x5b, 0x9f, 0x33, 0xca, 0xbd, 0x6e, 0x69, 0xe1, 0xdf, 0xf5, 0x88, 0xe2, 0x34, 0x29, 0x40, 0x71, - 0x47, 0x48, 0xc0, 0x02, 0x77, 0x8f, 0x89, 0x23, 0x8e, 0x8e, 0x30, 0xce, 0xf2, 0xd3, 0xf2, 0x2e, - 0xd7, 0xdf, 0x77, 0x97, 0x07, 0x11, 0x07, 0xe3, 0xb2, 0xba, 0xce, 0x85, 0xa8, 0x94, 0xa1, 0x38, - 0x2a, 0xdc, 0x02, 0xcb, 0x7e, 0x70, 0x39, 0x0c, 0x11, 0xaf, 0xdd, 0x68, 0x51, 0x76, 0x94, 0x9f, - 0x91, 0x3b, 0xbe, 0xdc, 0xeb, 0x96, 0x96, 0x51, 0x52, 0x89, 0xd2, 0xf6, 0xe5, 0xaf, 0x34, 0x30, - 0xb3, 0x55, 0xaf, 0xee, 0xb9, 0x16, 0x19, 0x43, 0x69, 0x56, 0x63, 0xa5, 0x79, 0xf5, 0x0c, 0x72, - 0x8b, 0xa4, 0x46, 0x16, 0xe6, 0x2f, 0x41, 0x61, 0x0a, 0x1b, 0xd5, 0x59, 0xd6, 0x40, 0xd6, 0xc1, - 0x36, 0x91, 0xa9, 0xcf, 0x85, 0x3e, 0x7b, 0xd8, 0x26, 0x48, 0x6a, 0xe0, 0xdf, 0xc0, 0xb4, 0xe3, - 0x5a, 0xa4, 0xba, 0x2d, 0x13, 0x98, 0x33, 0x2e, 0x29, 0x9b, 0xe9, 0x3d, 0x29, 0x45, 0x4a, 0x0b, - 0x6f, 0x83, 0x79, 0xee, 0x7a, 0x6e, 0xcb, 0x6d, 0x76, 0x1e, 0x91, 0x4e, 0x9f, 0xa6, 0x4b, 0xbd, - 0x6e, 0x69, 0xfe, 0x20, 0x22, 0x47, 0x31, 0x2b, 0xd8, 0x00, 0x39, 0xdc, 0x6a, 0xb9, 0x26, 0xe6, - 0xb8, 0xd1, 0x22, 0x92, 0x7b, 0xb9, 0x8d, 0xca, 0xfb, 0xf6, 0x18, 0x70, 0x5b, 0x04, 0x47, 0xaa, - 0xb7, 0x33, 0x63, 0xb1, 0xd7, 0x2d, 0xe5, 0x36, 0x43, 0x1c, 0x14, 0x05, 0x2d, 0x7f, 0xa9, 0x81, - 0x9c, 0xda, 0xf5, 0x18, 0x9a, 0xd1, 0x83, 0x78, 0x33, 0xfa, 0xcb, 0x39, 0xee, 0x6b, 0x44, 0x2b, - 0x32, 0x07, 0x69, 0xcb, 0x3e, 0x74, 0x00, 0x66, 0x2c, 0x79, 0x69, 0x2c, 0xaf, 0x49, 0xe8, 0x6b, - 0xe7, 0x80, 0x56, 0xbd, 0x6e, 0x51, 0x05, 0x98, 0x09, 0xd6, 0x0c, 0xf5, 0xa1, 0xca, 0xbf, 0x66, - 0x00, 0xdc, 0xaa, 0x57, 0x13, 0x95, 0x3e, 0x06, 0x5a, 0x53, 0x30, 0x2f, 0x98, 0xd3, 0xe7, 0x86, - 0xa2, 0xf7, 0x3f, 0xce, 0x79, 0x13, 0xb8, 0x41, 0x5a, 0x75, 0xd2, 0x22, 0x26, 0x77, 0xfd, 0x80, - 0x64, 0x7b, 0x11, 0x30, 0x14, 0x83, 0x86, 0xdb, 0x60, 0xa9, 0xdf, 0xb8, 0x5a, 0x98, 0x31, 0x41, - 0xee, 0x7c, 0x46, 0x92, 0x39, 0xaf, 0x52, 0x5c, 0xaa, 0x27, 0xf4, 0x28, 0xe5, 0x01, 0x9f, 0x81, - 0x59, 0x33, 0xda, 0x23, 0xcf, 0xa0, 0x8d, 0xde, 0x1f, 0x3d, 0xf4, 0x27, 0x6d, 0xec, 0x70, 0xca, - 0x3b, 0xc6, 0xbc, 0xa0, 0xcc, 0xa0, 0x99, 0x0e, 0xd0, 0x20, 0x03, 0xcb, 0x36, 0x7e, 0x45, 0xed, - 0xb6, 0x1d, 0x90, 0xbb, 0x4e, 0x3f, 0x20, 0xb2, 0x93, 0x5e, 0x3c, 0x84, 0x6c, 0x62, 0xb5, 0x24, - 0x18, 0x4a, 0xe3, 0x97, 0xbf, 0xd7, 0xc0, 0x95, 0xf4, 0xc5, 0x8f, 0xa1, 0x40, 0xea, 0xf1, 0x02, - 0xd1, 0xcf, 0x60, 0x71, 0x22, 0xc1, 0x11, 0xb5, 0xf2, 0xe9, 0x34, 0x98, 0x8f, 0xde, 0xe1, 0x18, - 0x08, 0xfc, 0x4f, 0x90, 0xf3, 0x7c, 0xf7, 0x84, 0x32, 0xea, 0x3a, 0xc4, 0x57, 0xdd, 0x71, 0x45, - 0xb9, 0xe4, 0xf6, 0x43, 0x15, 0x8a, 0xda, 0xc1, 0x16, 0x00, 0x1e, 0xf6, 0xb1, 0x4d, 0xb8, 0xa8, - 0xe4, 0x8c, 0x3c, 0x83, 0xbb, 0xef, 0x3b, 0x83, 0xe8, 0xb6, 0xf4, 0xfd, 0x81, 0xeb, 0x8e, 0xc3, - 0xfd, 0x4e, 0x98, 0x62, 0xa8, 0x40, 0x11, 0x7c, 0x78, 0x0c, 0x16, 0x7c, 0x62, 0xb6, 0x30, 0xb5, - 0xd5, 0x03, 0x9d, 0x95, 0x69, 0xee, 0x88, 0x87, 0x12, 0x45, 0x15, 0xa7, 0xdd, 0xd2, 0xcd, 0xf4, - 0xb0, 0xad, 0xef, 0x13, 0x9f, 0x51, 0xc6, 0x89, 0xc3, 0x03, 0xea, 0xc4, 0x7c, 0x50, 0x1c, 0x5b, - 0x3c, 0x01, 0xb6, 0x18, 0x5d, 0x1e, 0x7b, 0x9c, 0xba, 0x0e, 0xcb, 0x4f, 0x85, 0x4f, 0x40, 0x2d, - 0x22, 0x47, 0x31, 0x2b, 0xb8, 0x0b, 0x56, 0x45, 0xb7, 0xfe, 0x7f, 0x10, 0x60, 0xe7, 0x95, 0x87, - 0x1d, 0x71, 0x54, 0xf9, 0x69, 0xf9, 0x2a, 0xe7, 0xc5, 0x9c, 0xb3, 0x39, 0x44, 0x8f, 0x86, 0x7a, - 0xc1, 0x67, 0x60, 0x39, 0x18, 0x74, 0x0c, 0xea, 0x58, 0xd4, 0x69, 0x8a, 0x31, 0x47, 0x3e, 0xf0, - 0x73, 0xc6, 0x75, 0x51, 0x1b, 0x4f, 0x93, 0xca, 0xd3, 0x61, 0x42, 0x94, 0x06, 0x81, 0x2f, 0xc1, - 0xb2, 0x8c, 0x48, 0x2c, 0xd5, 0x58, 0x28, 0x61, 0xf9, 0xd9, 0xf4, 0x94, 0x22, 0x8e, 0x4e, 0x10, - 0xa9, 0xdf, 0x7e, 0xfa, 0x6d, 0xea, 0x80, 0xf8, 0xb6, 0xf1, 0x67, 0x75, 0x5f, 0xcb, 0x9b, 0x49, - 0x28, 0x94, 0x46, 0x2f, 0xdc, 0x07, 0x8b, 0x89, 0x0b, 0x87, 0x4b, 0x20, 0x73, 0x4c, 0x3a, 0xc1, - 0x7b, 0x8d, 0xc4, 0x4f, 0xb8, 0x0a, 0xa6, 0x4e, 0x70, 0xab, 0x4d, 0x02, 0x06, 0xa2, 0x60, 0x71, - 0x6f, 0xf2, 0xae, 0x56, 0xfe, 0x56, 0x03, 0xb1, 0xc6, 0x36, 0x86, 0xe2, 0xae, 0xc5, 0x8b, 0x7b, - 0xfd, 0xbc, 0xc4, 0x1e, 0x51, 0xd6, 0x1f, 0x69, 0x60, 0x3e, 0x3a, 0xcf, 0xc1, 0x1b, 0x60, 0x16, - 0xb7, 0x2d, 0x4a, 0x1c, 0xb3, 0x3f, 0xb3, 0x0c, 0xb2, 0xd9, 0x54, 0x72, 0x34, 0xb0, 0x10, 0xd3, - 0x1e, 0x79, 0xe5, 0x51, 0x1f, 0x0b, 0xa6, 0xd5, 0x89, 0xe9, 0x3a, 0x16, 0x93, 0xc7, 0x94, 0x09, - 0x1a, 0xe5, 0x4e, 0x52, 0x89, 0xd2, 0xf6, 0xe5, 0x2f, 0x26, 0xc1, 0x52, 0x40, 0x90, 0x60, 0xd8, - 0xb7, 0x89, 0xc3, 0xc7, 0xd0, 0x5e, 0x50, 0x6c, 0xec, 0xbb, 0x79, 0xf6, 0x48, 0x14, 0x66, 0x37, - 0x6a, 0xfe, 0x83, 0xcf, 0xc1, 0x34, 0xe3, 0x98, 0xb7, 0x99, 0x7c, 0xfe, 0x72, 0x1b, 0x1b, 0x17, - 0x42, 0x95, 0x9e, 0xe1, 0xfc, 0x17, 0xac, 0x91, 0x42, 0x2c, 0x7f, 0xa7, 0x81, 0xd5, 0xa4, 0xcb, - 0x18, 0x08, 0xf7, 0x24, 0x4e, 0xb8, 0x1b, 0x17, 0xd9, 0xd1, 0x08, 0xd2, 0xfd, 0xa8, 0x81, 0x2b, - 0xa9, 0xcd, 0xcb, 0x77, 0x56, 0xf4, 0x2a, 0x2f, 0xd1, 0x11, 0xf7, 0xc2, 0xf1, 0x59, 0xf6, 0xaa, - 0xfd, 0x21, 0x7a, 0x34, 0xd4, 0x0b, 0xbe, 0x00, 0x4b, 0xd4, 0x69, 0x51, 0x87, 0xa8, 0x67, 0x39, - 0xbc, 0xee, 0xa1, 0x0d, 0x25, 0x89, 0x2c, 0xaf, 0x79, 0x55, 0x4c, 0x2f, 0xd5, 0x04, 0x0a, 0x4a, - 0xe1, 0x96, 0x7f, 0x18, 0x72, 0x3d, 0x72, 0xac, 0x14, 0x15, 0x25, 0x25, 0xc4, 0x4f, 0x55, 0x94, - 0x92, 0xa3, 0x81, 0x85, 0x64, 0x90, 0x3c, 0x0a, 0x95, 0xe8, 0xc5, 0x18, 0x24, 0x3d, 0x23, 0x0c, - 0x92, 0x6b, 0xa4, 0x10, 0x45, 0x26, 0x62, 0x6c, 0x8b, 0x8c, 0x67, 0x83, 0x4c, 0xf6, 0x94, 0x1c, - 0x0d, 0x2c, 0xca, 0xbf, 0x65, 0x86, 0xdc, 0x92, 0xa4, 0x62, 0x64, 0x4b, 0xfd, 0x6f, 0xf5, 0xe4, - 0x96, 0xac, 0xc1, 0x96, 0x2c, 0xf8, 0x99, 0x06, 0x20, 0x1e, 0x40, 0xd4, 0xfa, 0x54, 0x0d, 0xf8, - 0xf4, 0xf0, 0xe2, 0x15, 0xa2, 0x6f, 0xa6, 0xc0, 0x82, 0xb7, 0xba, 0xa0, 0x92, 0x80, 0x69, 0x03, - 0x34, 0x24, 0x03, 0x48, 0x41, 0x2e, 0x90, 0xee, 0xf8, 0xbe, 0xeb, 0xab, 0x92, 0xbd, 0x7a, 0x76, - 0x42, 0xd2, 0xdc, 0x28, 0xca, 0x6f, 0xa2, 0xd0, 0xff, 0xb4, 0x5b, 0xca, 0x45, 0xf4, 0x28, 0x8a, - 0x2d, 0x42, 0x59, 0x24, 0x0c, 0x95, 0xfd, 0x03, 0xa1, 0xb6, 0xc9, 0xe8, 0x50, 0x11, 0xec, 0xc2, - 0x0e, 0xf8, 0xd3, 0x88, 0x03, 0xba, 0xd0, 0xdb, 0xf6, 0xb1, 0x06, 0xa2, 0x31, 0xe0, 0x2e, 0xc8, - 0x72, 0xaa, 0x2a, 0x31, 0xb7, 0x71, 0xfd, 0x7c, 0x1d, 0xe6, 0x80, 0xda, 0x24, 0x6c, 0x94, 0x62, - 0x85, 0x24, 0x0a, 0xbc, 0x06, 0x66, 0x6c, 0xc2, 0x18, 0x6e, 0xaa, 0xc8, 0xe1, 0x07, 0x54, 0x2d, - 0x10, 0xa3, 0xbe, 0xbe, 0x7c, 0x07, 0xac, 0x0c, 0xf9, 0x24, 0x85, 0x25, 0x30, 0x65, 0xca, 0x3f, - 0x7c, 0x44, 0x42, 0x53, 0xc6, 0x9c, 0xe8, 0x32, 0x5b, 0xf2, 0x7f, 0x9e, 0x40, 0x6e, 0xfc, 0xeb, - 0xf5, 0xbb, 0xe2, 0xc4, 0x9b, 0x77, 0xc5, 0x89, 0xb7, 0xef, 0x8a, 0x13, 0x1f, 0xf6, 0x8a, 0xda, - 0xeb, 0x5e, 0x51, 0x7b, 0xd3, 0x2b, 0x6a, 0x6f, 0x7b, 0x45, 0xed, 0xa7, 0x5e, 0x51, 0xfb, 0xe4, - 0xe7, 0xe2, 0xc4, 0xf3, 0xc2, 0xe8, 0xff, 0x5d, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x91, 0x4f, - 0x2f, 0xc0, 0xad, 0x15, 0x00, 0x00, + // 1672 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0x1b, 0x4d, + 0x19, 0xcf, 0xc6, 0xce, 0xd7, 0x38, 0x69, 0x92, 0x49, 0x5a, 0x8c, 0x0f, 0x76, 0x64, 0x04, 0x4d, + 0xab, 0xb2, 0x6e, 0x43, 0xa9, 0xaa, 0x4a, 0x95, 0xc8, 0x26, 0x81, 0xba, 0x8d, 0xd3, 0x74, 0x1c, + 0x55, 0x55, 0xc5, 0x81, 0xf1, 0xee, 0xc4, 0x99, 0xc6, 0xfb, 0xd1, 0x9d, 0xd9, 0x10, 0x73, 0x82, + 0x0b, 0x67, 0xc4, 0x81, 0xbf, 0x80, 0x7f, 0x01, 0x24, 0xb8, 0x70, 0xa4, 0x12, 0x12, 0xaa, 0xb8, + 0xd0, 0x93, 0x45, 0xcd, 0x9f, 0xf0, 0x4a, 0xef, 0x21, 0x7a, 0x0f, 0xaf, 0x66, 0x76, 0xec, 0xfd, + 0xb2, 0x9b, 0xe4, 0x3d, 0xf8, 0xe6, 0x79, 0x3e, 0x7e, 0xcf, 0x33, 0xf3, 0x7c, 0xae, 0xc1, 0xce, + 0xe9, 0x63, 0xa6, 0x53, 0xb7, 0x76, 0x1a, 0xb4, 0x88, 0xef, 0x10, 0x4e, 0x58, 0xed, 0x8c, 0x38, + 0x96, 0xeb, 0xd7, 0x14, 0x03, 0x7b, 0xb4, 0xc6, 0xb8, 0xeb, 0xe3, 0x36, 0xa9, 0x9d, 0x3d, 0x68, + 0x11, 0x8e, 0x1f, 0xd4, 0xda, 0xc4, 0x21, 0x3e, 0xe6, 0xc4, 0xd2, 0x3d, 0xdf, 0xe5, 0x2e, 0x2c, + 0x85, 0xb2, 0x3a, 0xf6, 0xa8, 0xae, 0x64, 0x75, 0x25, 0x5b, 0xfa, 0x71, 0x9b, 0xf2, 0x93, 0xa0, + 0xa5, 0x9b, 0xae, 0x5d, 0x6b, 0xbb, 0x6d, 0xb7, 0x26, 0x55, 0x5a, 0xc1, 0xb1, 0x3c, 0xc9, 0x83, + 0xfc, 0x15, 0x42, 0x95, 0xaa, 0x31, 0xb3, 0xa6, 0xeb, 0x0b, 0x9b, 0x69, 0x73, 0xa5, 0x87, 0x91, + 0x8c, 0x8d, 0xcd, 0x13, 0xea, 0x10, 0xbf, 0x5b, 0xf3, 0x4e, 0xdb, 0x52, 0xc9, 0x27, 0xcc, 0x0d, + 0x7c, 0x93, 0x5c, 0x4b, 0x8b, 0xd5, 0x6c, 0xc2, 0xf1, 0x28, 0x5b, 0xb5, 0x71, 0x5a, 0x7e, 0xe0, + 0x70, 0x6a, 0x67, 0xcd, 0x3c, 0xba, 0x4c, 0x81, 0x99, 0x27, 0xc4, 0xc6, 0x69, 0xbd, 0xea, 0xdf, + 0x35, 0xb0, 0xb0, 0xd3, 0xac, 0xef, 0xfa, 0xf4, 0x8c, 0xf8, 0xf0, 0x57, 0x60, 0x5e, 0x78, 0x64, + 0x61, 0x8e, 0x8b, 0xda, 0x86, 0xb6, 0x59, 0xd8, 0xba, 0xaf, 0x47, 0x8f, 0x3c, 0x04, 0xd6, 0xbd, + 0xd3, 0xb6, 0x20, 0x30, 0x5d, 0x48, 0xeb, 0x67, 0x0f, 0xf4, 0x97, 0xad, 0x77, 0xc4, 0xe4, 0x0d, + 0xc2, 0xb1, 0x01, 0x3f, 0xf4, 0x2a, 0x53, 0xfd, 0x5e, 0x05, 0x44, 0x34, 0x34, 0x44, 0x85, 0x2f, + 0x40, 0x9e, 0x79, 0xc4, 0x2c, 0x4e, 0x4b, 0xf4, 0x3b, 0xfa, 0xf8, 0x10, 0xea, 0x43, 0xb7, 0x9a, + 0x1e, 0x31, 0x8d, 0x45, 0x05, 0x9b, 0x17, 0x27, 0x24, 0x41, 0xaa, 0x7f, 0xd3, 0xc0, 0xd2, 0x50, + 0x6a, 0x9f, 0x32, 0x0e, 0x7f, 0x99, 0xb9, 0x80, 0x7e, 0xb5, 0x0b, 0x08, 0x6d, 0xe9, 0xfe, 0x8a, + 0xb2, 0x33, 0x3f, 0xa0, 0xc4, 0x9c, 0x7f, 0x0e, 0x66, 0x28, 0x27, 0x36, 0x2b, 0x4e, 0x6f, 0xe4, + 0x36, 0x0b, 0x5b, 0x3f, 0xbc, 0x92, 0xf7, 0xc6, 0x92, 0x42, 0x9c, 0xa9, 0x0b, 0x5d, 0x14, 0x42, + 0x54, 0xff, 0x9b, 0x8f, 0xf9, 0x2e, 0xee, 0x04, 0x9f, 0x80, 0x1b, 0x98, 0x73, 0x6c, 0x9e, 0x20, + 0xf2, 0x3e, 0xa0, 0x3e, 0xb1, 0xe4, 0x0d, 0xe6, 0x0d, 0xd8, 0xef, 0x55, 0x6e, 0x6c, 0x27, 0x38, + 0x28, 0x25, 0x29, 0x74, 0x3d, 0xd7, 0xaa, 0x3b, 0xc7, 0xee, 0x4b, 0xa7, 0xe1, 0x06, 0x0e, 0x97, + 0x0f, 0xac, 0x74, 0x0f, 0x13, 0x1c, 0x94, 0x92, 0x84, 0x26, 0x58, 0x3f, 0x73, 0x3b, 0x81, 0x4d, + 0xf6, 0xe9, 0x31, 0x31, 0xbb, 0x66, 0x87, 0x34, 0x5c, 0x8b, 0xb0, 0x62, 0x6e, 0x23, 0xb7, 0xb9, + 0x60, 0xd4, 0xfa, 0xbd, 0xca, 0xfa, 0xeb, 0x11, 0xfc, 0x8b, 0x5e, 0x65, 0x6d, 0x04, 0x1d, 0x8d, + 0x04, 0x83, 0x4f, 0xc1, 0xb2, 0x7a, 0xa1, 0x1d, 0xec, 0x61, 0x93, 0xf2, 0x6e, 0x31, 0x2f, 0x3d, + 0x5c, 0xeb, 0xf7, 0x2a, 0xcb, 0xcd, 0x24, 0x0b, 0xa5, 0x65, 0xe1, 0x33, 0xb0, 0x74, 0xcc, 0x7e, + 0xe1, 0xbb, 0x81, 0x77, 0xe8, 0x76, 0xa8, 0xd9, 0x2d, 0xce, 0x6c, 0x68, 0x9b, 0x0b, 0x46, 0xb5, + 0xdf, 0xab, 0x2c, 0xfd, 0xbc, 0x19, 0x63, 0x5c, 0xa4, 0x09, 0x28, 0xa9, 0x08, 0x09, 0x58, 0xe2, + 0xee, 0x29, 0x71, 0xc4, 0xd3, 0x11, 0xc6, 0x59, 0x71, 0x56, 0xc6, 0x72, 0xf3, 0x4b, 0xb1, 0x3c, + 0x8a, 0x29, 0x18, 0x37, 0x55, 0x38, 0x97, 0xe2, 0x54, 0x86, 0x92, 0xa8, 0x70, 0x07, 0xac, 0xfa, + 0x61, 0x70, 0x18, 0x22, 0x5e, 0xd0, 0xea, 0x50, 0x76, 0x52, 0x9c, 0x93, 0x37, 0xbe, 0xd9, 0xef, + 0x55, 0x56, 0x51, 0x9a, 0x89, 0xb2, 0xf2, 0xf0, 0x21, 0x58, 0x64, 0x64, 0x9f, 0x3a, 0xc1, 0x79, + 0x18, 0xd3, 0x79, 0xa9, 0xbf, 0xd2, 0xef, 0x55, 0x16, 0x9b, 0x7b, 0x11, 0x1d, 0x25, 0xa4, 0xaa, + 0x7f, 0xd5, 0xc0, 0xdc, 0x4e, 0xb3, 0x7e, 0xe0, 0x5a, 0x64, 0x02, 0x05, 0x5d, 0x4f, 0x14, 0xf4, + 0xed, 0x4b, 0x4a, 0x42, 0x38, 0x35, 0xb6, 0x9c, 0xbf, 0x0a, 0xcb, 0x59, 0xc8, 0xa8, 0x7e, 0xb4, + 0x01, 0xf2, 0x0e, 0xb6, 0x89, 0x74, 0x7d, 0x21, 0xd2, 0x39, 0xc0, 0x36, 0x41, 0x92, 0x03, 0x7f, + 0x04, 0x66, 0x1d, 0xd7, 0x22, 0xf5, 0x5d, 0xe9, 0xc0, 0x82, 0x71, 0x43, 0xc9, 0xcc, 0x1e, 0x48, + 0x2a, 0x52, 0x5c, 0xf1, 0x94, 0xdc, 0xf5, 0xdc, 0x8e, 0xdb, 0xee, 0xbe, 0x20, 0xdd, 0x41, 0x72, + 0xcb, 0xa7, 0x3c, 0x8a, 0xd1, 0x51, 0x42, 0x0a, 0xb6, 0x40, 0x01, 0x77, 0x3a, 0xae, 0x89, 0x39, + 0x6e, 0x75, 0x88, 0xcc, 0xd8, 0xc2, 0x56, 0xed, 0x4b, 0x77, 0x0c, 0x2b, 0x42, 0x18, 0x47, 0x6a, + 0x22, 0x30, 0x63, 0xb9, 0xdf, 0xab, 0x14, 0xb6, 0x23, 0x1c, 0x14, 0x07, 0xad, 0xfe, 0x45, 0x03, + 0x05, 0x75, 0xeb, 0x09, 0xb4, 0xb0, 0x67, 0xc9, 0x16, 0xf6, 0x83, 0x2b, 0xc4, 0x6b, 0x4c, 0x03, + 0x33, 0x87, 0x6e, 0xcb, 0xee, 0x75, 0x04, 0xe6, 0x2c, 0x19, 0x34, 0x56, 0xd4, 0x24, 0xf4, 0x9d, + 0x2b, 0x40, 0xab, 0x0e, 0xb9, 0xac, 0x0c, 0xcc, 0x85, 0x67, 0x86, 0x06, 0x50, 0xd5, 0xaf, 0x73, + 0x00, 0xee, 0x34, 0xeb, 0xa9, 0xfe, 0x30, 0x81, 0xb4, 0xa6, 0x60, 0x51, 0x64, 0xce, 0x20, 0x37, + 0x54, 0x7a, 0xff, 0xe4, 0x8a, 0x91, 0xc0, 0x2d, 0xd2, 0x69, 0x92, 0x0e, 0x31, 0xb9, 0xeb, 0x87, + 0x49, 0x76, 0x10, 0x03, 0x43, 0x09, 0x68, 0xb8, 0x0b, 0x56, 0x06, 0xed, 0xae, 0x83, 0x19, 0x13, + 0xc9, 0x5d, 0xcc, 0xc9, 0x64, 0x2e, 0x2a, 0x17, 0x57, 0x9a, 0x29, 0x3e, 0xca, 0x68, 0xc0, 0x37, + 0x60, 0xde, 0x8c, 0x77, 0xd6, 0x4b, 0xd2, 0x46, 0x1f, 0x2c, 0x2c, 0xfa, 0xab, 0x00, 0x3b, 0x9c, + 0xf2, 0xae, 0xb1, 0x28, 0x52, 0x66, 0xd8, 0x82, 0x87, 0x68, 0x90, 0x81, 0x55, 0x1b, 0x9f, 0x53, + 0x3b, 0xb0, 0xc3, 0xe4, 0x6e, 0xd2, 0xdf, 0x10, 0xd9, 0x7f, 0xaf, 0x6f, 0x42, 0xb6, 0xbe, 0x46, + 0x1a, 0x0c, 0x65, 0xf1, 0xab, 0xff, 0xd2, 0xc0, 0xad, 0x6c, 0xe0, 0x27, 0x50, 0x20, 0xcd, 0x64, + 0x81, 0xe8, 0x97, 0x64, 0x71, 0xca, 0xc1, 0x31, 0xb5, 0xf2, 0xc7, 0x59, 0xb0, 0x18, 0x8f, 0xe1, + 0x04, 0x12, 0xf8, 0xa7, 0xa0, 0xe0, 0xf9, 0xee, 0x19, 0x65, 0xd4, 0x75, 0x88, 0xaf, 0xba, 0xe3, + 0x9a, 0x52, 0x29, 0x1c, 0x46, 0x2c, 0x14, 0x97, 0x83, 0x1d, 0x00, 0x3c, 0xec, 0x63, 0x9b, 0x70, + 0x51, 0xc9, 0x39, 0xf9, 0x06, 0x8f, 0xbf, 0xf4, 0x06, 0xf1, 0x6b, 0xe9, 0x87, 0x43, 0xd5, 0x3d, + 0x87, 0xfb, 0xdd, 0xc8, 0xc5, 0x88, 0x81, 0x62, 0xf8, 0xf0, 0x14, 0x2c, 0xf9, 0xc4, 0xec, 0x60, + 0x6a, 0xab, 0xb1, 0x9e, 0x97, 0x6e, 0xee, 0x89, 0xf1, 0x8a, 0xe2, 0x8c, 0x8b, 0x5e, 0xe5, 0x7e, + 0x76, 0x45, 0xd7, 0x0f, 0x89, 0xcf, 0x28, 0xe3, 0xc4, 0xe1, 0x61, 0xea, 0x24, 0x74, 0x50, 0x12, + 0x5b, 0x8c, 0x00, 0x5b, 0x0c, 0xc8, 0x97, 0x1e, 0xa7, 0xae, 0xc3, 0x8a, 0x33, 0xd1, 0x08, 0x68, + 0xc4, 0xe8, 0x28, 0x21, 0x05, 0xf7, 0xc1, 0xba, 0xe8, 0xd6, 0xbf, 0x0e, 0x0d, 0xec, 0x9d, 0x7b, + 0xd8, 0x11, 0x4f, 0x55, 0x9c, 0x95, 0xb3, 0xb8, 0x28, 0xb6, 0xa3, 0xed, 0x11, 0x7c, 0x34, 0x52, + 0x0b, 0xbe, 0x01, 0xab, 0xe1, 0x7a, 0x64, 0x50, 0xc7, 0xa2, 0x4e, 0x5b, 0x2c, 0x47, 0x72, 0x2d, + 0x58, 0x30, 0xee, 0x8a, 0xda, 0x78, 0x9d, 0x66, 0x5e, 0x8c, 0x22, 0xa2, 0x2c, 0x08, 0x7c, 0x0f, + 0x56, 0xa5, 0x45, 0x62, 0xa9, 0xc6, 0x42, 0x09, 0x2b, 0xce, 0x67, 0x77, 0x1b, 0xf1, 0x74, 0x22, + 0x91, 0x06, 0xed, 0x67, 0xd0, 0xa6, 0x8e, 0x88, 0x6f, 0x1b, 0xdf, 0x57, 0xf1, 0x5a, 0xdd, 0x4e, + 0x43, 0xa1, 0x2c, 0x7a, 0xe9, 0x29, 0x58, 0x4e, 0x05, 0x1c, 0xae, 0x80, 0xdc, 0x29, 0xe9, 0x86, + 0xf3, 0x1a, 0x89, 0x9f, 0x70, 0x1d, 0xcc, 0x9c, 0xe1, 0x4e, 0x40, 0xc2, 0x0c, 0x44, 0xe1, 0xe1, + 0xc9, 0xf4, 0x63, 0xad, 0xfa, 0x0f, 0x0d, 0x24, 0x1a, 0xdb, 0x04, 0x8a, 0xbb, 0x91, 0x2c, 0xee, + 0xcd, 0xab, 0x26, 0xf6, 0x98, 0xb2, 0xfe, 0x9d, 0x06, 0x16, 0xe3, 0x5b, 0x20, 0xbc, 0x07, 0xe6, + 0x71, 0x60, 0x51, 0xe2, 0x98, 0x83, 0x9d, 0x65, 0xe8, 0xcd, 0xb6, 0xa2, 0xa3, 0xa1, 0x84, 0xd8, + 0x11, 0xc9, 0xb9, 0x47, 0x7d, 0x2c, 0x32, 0xad, 0x49, 0x4c, 0xd7, 0xb1, 0x98, 0x7c, 0xa6, 0x5c, + 0xd8, 0x28, 0xf7, 0xd2, 0x4c, 0x94, 0x95, 0xaf, 0xfe, 0x79, 0x1a, 0xac, 0x84, 0x09, 0x12, 0x7e, + 0x22, 0xd8, 0xc4, 0xe1, 0x13, 0x68, 0x2f, 0x28, 0xb1, 0xf6, 0xdd, 0xbf, 0x7c, 0x25, 0x8a, 0xbc, + 0x1b, 0xb7, 0xff, 0xc1, 0xb7, 0x60, 0x96, 0x71, 0xcc, 0x03, 0x26, 0xc7, 0x5f, 0x61, 0x6b, 0xeb, + 0x5a, 0xa8, 0x52, 0x33, 0xda, 0xff, 0xc2, 0x33, 0x52, 0x88, 0xd5, 0x7f, 0x6a, 0x60, 0x3d, 0xad, + 0x32, 0x81, 0x84, 0x7b, 0x95, 0x4c, 0xb8, 0x7b, 0xd7, 0xb9, 0xd1, 0x98, 0xa4, 0xfb, 0x8f, 0x06, + 0x6e, 0x65, 0x2e, 0x2f, 0xe7, 0xac, 0xe8, 0x55, 0x5e, 0xaa, 0x23, 0x1e, 0x44, 0xeb, 0xb3, 0xec, + 0x55, 0x87, 0x23, 0xf8, 0x68, 0xa4, 0x16, 0x7c, 0x07, 0x56, 0xa8, 0xd3, 0xa1, 0x0e, 0x51, 0x63, + 0x39, 0x0a, 0xf7, 0xc8, 0x86, 0x92, 0x46, 0x96, 0x61, 0x5e, 0x17, 0xdb, 0x4b, 0x3d, 0x85, 0x82, + 0x32, 0xb8, 0xd5, 0x7f, 0x8f, 0x08, 0x8f, 0x5c, 0x2b, 0x45, 0x45, 0x49, 0x0a, 0xf1, 0x33, 0x15, + 0xa5, 0xe8, 0x68, 0x28, 0x21, 0x33, 0x48, 0x3e, 0x85, 0x72, 0xf4, 0x7a, 0x19, 0x24, 0x35, 0x63, + 0x19, 0x24, 0xcf, 0x48, 0x21, 0x0a, 0x4f, 0xc4, 0xda, 0x16, 0x5b, 0xcf, 0x86, 0x9e, 0x1c, 0x28, + 0x3a, 0x1a, 0x4a, 0x54, 0xbf, 0xc9, 0x8d, 0x88, 0x92, 0x4c, 0xc5, 0xd8, 0x95, 0x06, 0x5f, 0xf8, + 0xe9, 0x2b, 0x59, 0xc3, 0x2b, 0x59, 0xf0, 0x4f, 0x1a, 0x80, 0x78, 0x08, 0xd1, 0x18, 0xa4, 0x6a, + 0x98, 0x4f, 0xcf, 0xaf, 0x5f, 0x21, 0xfa, 0x76, 0x06, 0x2c, 0x9c, 0xd5, 0x25, 0xe5, 0x04, 0xcc, + 0x0a, 0xa0, 0x11, 0x1e, 0x40, 0x0a, 0x0a, 0x21, 0x75, 0xcf, 0xf7, 0x5d, 0x5f, 0x95, 0xec, 0xed, + 0xcb, 0x1d, 0x92, 0xe2, 0x46, 0x59, 0x7e, 0x13, 0x45, 0xfa, 0x17, 0xbd, 0x4a, 0x21, 0xc6, 0x47, + 0x71, 0x6c, 0x61, 0xca, 0x22, 0x91, 0xa9, 0xfc, 0x77, 0x30, 0xb5, 0x4b, 0xc6, 0x9b, 0x8a, 0x61, + 0x97, 0xf6, 0xc0, 0xf7, 0xc6, 0x3c, 0xd0, 0xb5, 0x66, 0xdb, 0xef, 0x35, 0x10, 0xb7, 0x01, 0xf7, + 0x41, 0x9e, 0x53, 0x55, 0x89, 0x85, 0xad, 0xbb, 0x57, 0xeb, 0x30, 0x47, 0xd4, 0x26, 0x51, 0xa3, + 0x14, 0x27, 0x24, 0x51, 0xe0, 0x1d, 0x30, 0x67, 0x13, 0xc6, 0x70, 0x5b, 0x59, 0x8e, 0x3e, 0xa0, + 0x1a, 0x21, 0x19, 0x0d, 0xf8, 0xd5, 0x47, 0x60, 0x6d, 0xc4, 0x27, 0x29, 0xac, 0x80, 0x19, 0x53, + 0xfe, 0xa5, 0x20, 0x1c, 0x9a, 0x31, 0x16, 0x44, 0x97, 0xd9, 0x91, 0xff, 0x25, 0x84, 0x74, 0xe3, + 0x67, 0x1f, 0x3e, 0x97, 0xa7, 0x3e, 0x7e, 0x2e, 0x4f, 0x7d, 0xfa, 0x5c, 0x9e, 0xfa, 0x6d, 0xbf, + 0xac, 0x7d, 0xe8, 0x97, 0xb5, 0x8f, 0xfd, 0xb2, 0xf6, 0xa9, 0x5f, 0xd6, 0xfe, 0xd7, 0x2f, 0x6b, + 0x7f, 0xf8, 0x7f, 0x79, 0xea, 0x6d, 0x69, 0xfc, 0xbf, 0xb5, 0xdf, 0x06, 0x00, 0x00, 0xff, 0xff, + 0xee, 0x44, 0x0b, 0xed, 0xe3, 0x15, 0x00, 0x00, } func (m *CSIDriver) Marshal() (dAtA []byte, err error) { @@ -826,6 +827,16 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SELinuxMount != nil { + i-- + if *m.SELinuxMount { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } if m.RequiresRepublish != nil { i-- if *m.RequiresRepublish { @@ -1795,6 +1806,9 @@ func (m *CSIDriverSpec) Size() (n int) { if m.RequiresRepublish != nil { n += 2 } + if m.SELinuxMount != nil { + n += 2 + } return n } @@ -2148,6 +2162,7 @@ func (this *CSIDriverSpec) String() string { `FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`, `TokenRequests:` + repeatedStringForTokenRequests + `,`, `RequiresRepublish:` + valueToStringGenerated(this.RequiresRepublish) + `,`, + `SELinuxMount:` + valueToStringGenerated(this.SELinuxMount) + `,`, `}`, }, "") return s @@ -2844,6 +2859,27 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.RequiresRepublish = &b + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SELinuxMount", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.SELinuxMount = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.proto b/vendor/k8s.io/api/storage/v1beta1/generated.proto index 943900fa690..2b354dd4715 100644 --- a/vendor/k8s.io/api/storage/v1beta1/generated.proto +++ b/vendor/k8s.io/api/storage/v1beta1/generated.proto @@ -49,7 +49,7 @@ message CSIDriver { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. optional CSIDriverSpec spec = 2; } @@ -82,16 +82,15 @@ message CSIDriverSpec { // +optional optional bool attachRequired = 1; - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -112,14 +111,14 @@ message CSIDriverSpec { // +optional optional bool podInfoOnMount = 2; - // VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html // A driver can support one or more of these modes and @@ -130,10 +129,9 @@ message CSIDriverSpec { // +optional repeated string volumeLifecycleModes = 3; - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -149,7 +147,7 @@ message CSIDriverSpec { // +optional optional bool storageCapacity = 4; - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -159,10 +157,11 @@ message CSIDriverSpec { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional optional string fsGroupPolicy = 5; - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -182,7 +181,7 @@ message CSIDriverSpec { // +listType=atomic repeated TokenRequest tokenRequests = 6; - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -192,6 +191,28 @@ message CSIDriverSpec { // // +optional optional bool requiresRepublish = 7; + + // seLinuxMount specifies if the CSI driver supports "-o context" + // mount option. + // + // When "true", the CSI driver must ensure that all volumes provided by this CSI + // driver can be mounted separately with different `-o context` options. This is + // typical for storage backends that provide volumes as filesystems on block + // devices or as independent shared volumes. + // Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount + // option when mounting a ReadWriteOncePod volume used in Pod that has + // explicitly set SELinux context. In the future, it may be expanded to other + // volume AccessModes. In any case, Kubernetes will ensure that the volume is + // mounted only with a single SELinux context. + // + // When "false", Kubernetes won't pass any special SELinux mount options to the driver. + // This is typical for volumes that represent subdirectories of a bigger shared filesystem. + // + // Default is "false". + // + // +featureGate=SELinuxMountReadWriteOncePod + // +optional + optional bool seLinuxMount = 8; } // DEPRECATED - This group version of CSINode is deprecated by storage/v1/CSINode. @@ -215,7 +236,7 @@ message CSINode { // CSINodeDriver holds information about the specification of one CSI driver installed on a node message CSINodeDriver { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. optional string name = 1; @@ -306,7 +327,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -315,7 +336,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -323,7 +344,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -335,7 +356,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -357,7 +378,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -374,36 +395,36 @@ message StorageClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. optional string provisioner = 2; - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional map parameters = 3; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional optional string reclaimPolicy = 4; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional repeated string mountOptions = 5; - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand // +optional optional bool allowVolumeExpansion = 6; - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional optional string volumeBindingMode = 7; - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -419,17 +440,17 @@ message StorageClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of StorageClasses + // items is the list of StorageClasses repeated StorageClass items = 2; } // TokenRequest contains parameters of a service account token. message TokenRequest { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. optional string audience = 1; - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec" // // +optional @@ -446,11 +467,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -464,7 +485,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -473,7 +494,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -489,39 +510,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -530,11 +551,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -543,7 +564,7 @@ message VolumeError { // VolumeNodeResources is a set of resource limits for scheduling of volumes. message VolumeNodeResources { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is nil, then the supported number of volumes on this node is unbounded. diff --git a/vendor/k8s.io/api/storage/v1beta1/types.go b/vendor/k8s.io/api/storage/v1beta1/types.go index b39414b9605..4c39b49ccd8 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types.go +++ b/vendor/k8s.io/api/storage/v1beta1/types.go @@ -36,41 +36,42 @@ import ( // according to etcd is in ObjectMeta.Name. type StorageClass struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"` - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand // +optional AllowVolumeExpansion *bool `json:"allowVolumeExpansion,omitempty" protobuf:"varint,6,opt,name=allowVolumeExpansion"` - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -87,12 +88,13 @@ type StorageClass struct { // StorageClassList is a collection of storage classes. type StorageClassList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of StorageClasses + // items is the list of StorageClasses Items []StorageClass `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -130,11 +132,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -149,25 +151,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -176,7 +179,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -192,26 +195,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -220,11 +223,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -259,7 +262,7 @@ type CSIDriver struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. Spec CSIDriverSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` } @@ -299,16 +302,15 @@ type CSIDriverSpec struct { // +optional AttachRequired *bool `json:"attachRequired,omitempty" protobuf:"varint,1,opt,name=attachRequired"` - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -329,14 +331,14 @@ type CSIDriverSpec struct { // +optional PodInfoOnMount *bool `json:"podInfoOnMount,omitempty" protobuf:"bytes,2,opt,name=podInfoOnMount"` - // VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html // A driver can support one or more of these modes and @@ -347,11 +349,9 @@ type CSIDriverSpec struct { // +optional VolumeLifecycleModes []VolumeLifecycleMode `json:"volumeLifecycleModes,omitempty" protobuf:"bytes,3,opt,name=volumeLifecycleModes"` - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. - // + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -367,7 +367,7 @@ type CSIDriverSpec struct { // +optional StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -377,10 +377,11 @@ type CSIDriverSpec struct { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -400,7 +401,7 @@ type CSIDriverSpec struct { // +listType=atomic TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"` - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -410,6 +411,28 @@ type CSIDriverSpec struct { // // +optional RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"` + + // seLinuxMount specifies if the CSI driver supports "-o context" + // mount option. + // + // When "true", the CSI driver must ensure that all volumes provided by this CSI + // driver can be mounted separately with different `-o context` options. This is + // typical for storage backends that provide volumes as filesystems on block + // devices or as independent shared volumes. + // Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount + // option when mounting a ReadWriteOncePod volume used in Pod that has + // explicitly set SELinux context. In the future, it may be expanded to other + // volume AccessModes. In any case, Kubernetes will ensure that the volume is + // mounted only with a single SELinux context. + // + // When "false", Kubernetes won't pass any special SELinux mount options to the driver. + // This is typical for volumes that represent subdirectories of a bigger shared filesystem. + // + // Default is "false". + // + // +featureGate=SELinuxMountReadWriteOncePod + // +optional + SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"` } // FSGroupPolicy specifies if a CSI Driver supports modifying @@ -445,12 +468,11 @@ type VolumeLifecycleMode string // TokenRequest contains parameters of a service account token. type TokenRequest struct { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. - // Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"` - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec" // // +optional @@ -518,7 +540,7 @@ type CSINodeSpec struct { // CSINodeDriver holds information about the specification of one CSI driver installed on a node type CSINodeDriver struct { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` @@ -554,7 +576,7 @@ type CSINodeDriver struct { // VolumeNodeResources is a set of resource limits for scheduling of volumes. type VolumeNodeResources struct { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is nil, then the supported number of volumes on this node is unbounded. @@ -613,6 +635,7 @@ type CSINodeList struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that // there are no conflicts with other CSI drivers on the cluster, the recommendation @@ -625,7 +648,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -634,7 +657,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -642,7 +665,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -654,7 +677,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -677,12 +700,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go index d810b4e4c8b..0f2718b9c14 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIDriver = map[string]string{ "": "CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSI drivers do not need to create the CSIDriver object directly. Instead they may use the cluster-driver-registrar sidecar container. When deployed with a CSI driver it automatically creates a CSIDriver object representing the driver. Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.", "metadata": "Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the CSI Driver.", + "spec": "spec represents the specification of the CSI Driver.", } func (CSIDriver) SwaggerDoc() map[string]string { @@ -50,12 +50,13 @@ func (CSIDriverList) SwaggerDoc() map[string]string { var map_CSIDriverSpec = map[string]string{ "": "CSIDriverSpec is the specification of a CSIDriver.", "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", - "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", - "volumeLifecycleModes": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", - "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", - "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", - "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "podInfoOnMount": "podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations, if set to true. If set to false, pod information will not be passed on mount. Default is false.\n\nThe CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext.\n\nThe following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", + "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism.\n\nThe other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume.\n\nFor more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is immutable.", + "storageCapacity": "storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information, if set to true.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", + "fsGroupPolicy": "fsGroupPolicy defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", + "tokenRequests": "tokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", + "requiresRepublish": "requiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { @@ -74,7 +75,7 @@ func (CSINode) SwaggerDoc() map[string]string { var map_CSINodeDriver = map[string]string{ "": "CSINodeDriver holds information about the specification of one CSI driver installed on a node", - "name": "This is the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", + "name": "name represents the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", "nodeID": "nodeID of the node from the driver point of view. This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as \"node1\", but the storage system may refer to the same node as \"nodeA\". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. \"nodeA\" instead of \"node1\". This field is required.", "topologyKeys": "topologyKeys is the list of keys supported by the driver. When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. \"company.com/zone\", \"company.com/region\"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.", "allocatable": "allocatable represents the volume resources of a node that are available for scheduling.", @@ -106,10 +107,10 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -119,7 +120,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -129,13 +130,13 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_StorageClass = map[string]string{ "": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "provisioner": "Provisioner indicates the type of the provisioner.", - "parameters": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.", - "reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.", - "mountOptions": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", - "allowVolumeExpansion": "AllowVolumeExpansion shows whether the storage class allow volume expand", - "volumeBindingMode": "VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", - "allowedTopologies": "Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", + "provisioner": "provisioner indicates the type of the provisioner.", + "parameters": "parameters holds the parameters for the provisioner that should create volumes of this storage class.", + "reclaimPolicy": "reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.", + "mountOptions": "mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", + "allowVolumeExpansion": "allowVolumeExpansion shows whether the storage class allow volume expand", + "volumeBindingMode": "volumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", + "allowedTopologies": "allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", } func (StorageClass) SwaggerDoc() map[string]string { @@ -145,7 +146,7 @@ func (StorageClass) SwaggerDoc() map[string]string { var map_StorageClassList = map[string]string{ "": "StorageClassList is a collection of storage classes.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of StorageClasses", + "items": "items is the list of StorageClasses", } func (StorageClassList) SwaggerDoc() map[string]string { @@ -154,8 +155,8 @@ func (StorageClassList) SwaggerDoc() map[string]string { var map_TokenRequest = map[string]string{ "": "TokenRequest contains parameters of a service account token.", - "audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", - "expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"", + "audience": "audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", + "expirationSeconds": "expirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"", } func (TokenRequest) SwaggerDoc() map[string]string { @@ -165,8 +166,8 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -176,7 +177,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -185,7 +186,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -194,9 +195,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -205,10 +206,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -217,8 +218,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { @@ -227,7 +228,7 @@ func (VolumeError) SwaggerDoc() map[string]string { var map_VolumeNodeResources = map[string]string{ "": "VolumeNodeResources is a set of resource limits for scheduling of volumes.", - "count": "Maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is nil, then the supported number of volumes on this node is unbounded.", + "count": "count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is nil, then the supported number of volumes on this node is unbounded.", } func (VolumeNodeResources) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go index 5411ed8c00e..f0450182b27 100644 --- a/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go @@ -127,6 +127,11 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) { *out = new(bool) **out = **in } + if in.SELinuxMount != nil { + in, out := &in.SELinuxMount, &out.SELinuxMount + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go index f402c416d66..04ce206bb92 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go @@ -196,6 +196,18 @@ type ValidationRule struct { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" Message string + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + MessageExpression string } // JSON represents any valid JSON value. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go index 68eb08082d6..5dbb38c8bf9 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go @@ -814,198 +814,199 @@ func init() { } var fileDescriptor_f5a35c9667703937 = []byte{ - // 3047 bytes of a gzipped FileDescriptorProto + // 3072 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xdf, 0x6f, 0x24, 0x47, 0xf1, 0xbf, 0x59, 0xff, 0x5a, 0xb7, 0xed, 0xb3, 0xdd, 0x77, 0xf6, 0x77, 0xce, 0xb9, 0xf3, 0xfa, 0x36, 0xdf, 0x1c, 0x4e, 0x72, 0x59, 0x27, 0x26, 0x21, 0x47, 0x84, 0x40, 0x5e, 0xdb, 0x97, 0x38, - 0x67, 0x9f, 0xad, 0xde, 0xbb, 0x8b, 0x93, 0x00, 0xc9, 0x78, 0xa7, 0xbd, 0x9e, 0x78, 0x7e, 0x5d, - 0xf7, 0xcc, 0xda, 0x96, 0x40, 0x8a, 0x40, 0x11, 0x10, 0x09, 0xc2, 0x03, 0x0a, 0x4f, 0x08, 0x21, - 0x94, 0x07, 0x78, 0x80, 0x37, 0xf8, 0x17, 0xf2, 0x82, 0x94, 0x27, 0x14, 0x09, 0x69, 0x45, 0x96, - 0x7f, 0x00, 0x09, 0x10, 0xc2, 0x0f, 0x08, 0xf5, 0x8f, 0xe9, 0xe9, 0x9d, 0xdd, 0xbd, 0x3b, 0xd9, - 0xeb, 0xe4, 0xcd, 0xae, 0xaa, 0xae, 0x4f, 0x75, 0x75, 0x75, 0x55, 0x75, 0xcd, 0x02, 0x6b, 0xff, - 0x06, 0x2d, 0x39, 0xc1, 0xc2, 0x7e, 0xbc, 0x83, 0x89, 0x8f, 0x23, 0x4c, 0x17, 0xea, 0xd8, 0xb7, - 0x03, 0xb2, 0x20, 0x19, 0x56, 0xe8, 0xe0, 0xc3, 0x08, 0xfb, 0xd4, 0x09, 0x7c, 0xfa, 0x8c, 0x15, - 0x3a, 0x14, 0x93, 0x3a, 0x26, 0x0b, 0xe1, 0x7e, 0x8d, 0xf1, 0x68, 0xab, 0xc0, 0x42, 0xfd, 0xb9, - 0x85, 0x1a, 0xf6, 0x31, 0xb1, 0x22, 0x6c, 0x97, 0x42, 0x12, 0x44, 0x01, 0xbc, 0x21, 0x34, 0x95, - 0x5a, 0x04, 0xdf, 0x52, 0x9a, 0x4a, 0xe1, 0x7e, 0x8d, 0xf1, 0x68, 0xab, 0x40, 0xa9, 0xfe, 0xdc, - 0xcc, 0x33, 0x35, 0x27, 0xda, 0x8b, 0x77, 0x4a, 0xd5, 0xc0, 0x5b, 0xa8, 0x05, 0xb5, 0x60, 0x81, - 0x2b, 0xdc, 0x89, 0x77, 0xf9, 0x7f, 0xfc, 0x1f, 0xfe, 0x97, 0x00, 0x9a, 0x79, 0x3e, 0x35, 0xd9, + 0x67, 0x9f, 0xad, 0xde, 0xbb, 0x8b, 0x93, 0x20, 0x92, 0xf1, 0x4e, 0x7b, 0x3d, 0xf1, 0xfc, 0xba, + 0xee, 0x99, 0xb5, 0x2d, 0x81, 0x14, 0x81, 0x22, 0x20, 0x12, 0x84, 0x07, 0x14, 0x9e, 0x10, 0x42, + 0x28, 0x48, 0xf0, 0x00, 0x6f, 0xf0, 0x2f, 0xe4, 0x05, 0x29, 0x4f, 0x28, 0x12, 0xd2, 0x8a, 0x2c, + 0xff, 0x00, 0x12, 0x20, 0x84, 0x1f, 0x10, 0xea, 0x1f, 0xd3, 0xd3, 0x3b, 0xbb, 0x7b, 0x77, 0xb2, + 0xd7, 0xc9, 0xdb, 0x6e, 0x55, 0x75, 0x7d, 0xaa, 0xab, 0xab, 0xab, 0xab, 0xab, 0x07, 0x58, 0xfb, + 0x37, 0x68, 0xc9, 0x09, 0x16, 0xf6, 0xe3, 0x1d, 0x4c, 0x7c, 0x1c, 0x61, 0xba, 0x50, 0xc7, 0xbe, + 0x1d, 0x90, 0x05, 0xc9, 0xb0, 0x42, 0x07, 0x1f, 0x46, 0xd8, 0xa7, 0x4e, 0xe0, 0xd3, 0x67, 0xac, + 0xd0, 0xa1, 0x98, 0xd4, 0x31, 0x59, 0x08, 0xf7, 0x6b, 0x8c, 0x47, 0x5b, 0x05, 0x16, 0xea, 0xcf, + 0x2d, 0xd4, 0xb0, 0x8f, 0x89, 0x15, 0x61, 0xbb, 0x14, 0x92, 0x20, 0x0a, 0xe0, 0x0d, 0xa1, 0xa9, + 0xd4, 0x22, 0xf8, 0x96, 0xd2, 0x54, 0x0a, 0xf7, 0x6b, 0x8c, 0x47, 0x5b, 0x05, 0x4a, 0xf5, 0xe7, + 0x66, 0x9e, 0xa9, 0x39, 0xd1, 0x5e, 0xbc, 0x53, 0xaa, 0x06, 0xde, 0x42, 0x2d, 0xa8, 0x05, 0x0b, + 0x5c, 0xe1, 0x4e, 0xbc, 0xcb, 0xff, 0xf1, 0x3f, 0xfc, 0x97, 0x00, 0x9a, 0x79, 0x3e, 0x35, 0xd9, 0xb3, 0xaa, 0x7b, 0x8e, 0x8f, 0xc9, 0x51, 0x6a, 0xa7, 0x87, 0x23, 0xab, 0x83, 0x79, 0x33, 0x0b, - 0xdd, 0x56, 0x91, 0xd8, 0x8f, 0x1c, 0x0f, 0xb7, 0x2d, 0xf8, 0xca, 0xc3, 0x16, 0xd0, 0xea, 0x1e, - 0xf6, 0xac, 0xec, 0xba, 0xe2, 0xb1, 0x01, 0x26, 0x97, 0x03, 0xbf, 0x8e, 0x09, 0xdb, 0x20, 0xc2, + 0xdd, 0x46, 0x91, 0xd8, 0x8f, 0x1c, 0x0f, 0xb7, 0x0d, 0xf8, 0xca, 0xc3, 0x06, 0xd0, 0xea, 0x1e, + 0xf6, 0xac, 0xec, 0xb8, 0xe2, 0xb1, 0x01, 0x26, 0x97, 0x03, 0xbf, 0x8e, 0x09, 0x9b, 0x20, 0xc2, 0xf7, 0x63, 0x4c, 0x23, 0x58, 0x06, 0x7d, 0xb1, 0x63, 0x9b, 0xc6, 0x9c, 0x31, 0x3f, 0x5c, 0x7e, 0xf6, 0xe3, 0x46, 0xe1, 0x5c, 0xb3, 0x51, 0xe8, 0xbb, 0xbb, 0xb6, 0x72, 0xdc, 0x28, 0x5c, 0xed, - 0x86, 0x14, 0x1d, 0x85, 0x98, 0x96, 0xee, 0xae, 0xad, 0x20, 0xb6, 0x18, 0xbe, 0x0c, 0x26, 0x6d, + 0x86, 0x14, 0x1d, 0x85, 0x98, 0x96, 0xee, 0xae, 0xad, 0x20, 0x36, 0x18, 0xbe, 0x0c, 0x26, 0x6d, 0x4c, 0x1d, 0x82, 0xed, 0xa5, 0xad, 0xb5, 0x7b, 0x42, 0xbf, 0x99, 0xe3, 0x1a, 0x2f, 0x49, 0x8d, - 0x93, 0x2b, 0x59, 0x01, 0xd4, 0xbe, 0x06, 0x6e, 0x83, 0xa1, 0x60, 0xe7, 0x1d, 0x5c, 0x8d, 0xa8, - 0xd9, 0x37, 0xd7, 0x37, 0x3f, 0xb2, 0xf8, 0x4c, 0x29, 0x3d, 0x3c, 0x65, 0x02, 0x3f, 0x31, 0xb9, - 0xd9, 0x12, 0xb2, 0x0e, 0x56, 0x93, 0x43, 0x2b, 0x8f, 0x4b, 0xb4, 0xa1, 0x4d, 0xa1, 0x05, 0x25, - 0xea, 0x8a, 0xbf, 0xce, 0x01, 0xa8, 0x6f, 0x9e, 0x86, 0x81, 0x4f, 0x71, 0x4f, 0x76, 0x4f, 0xc1, + 0x93, 0x2b, 0x59, 0x01, 0xd4, 0x3e, 0x06, 0x6e, 0x83, 0xa1, 0x60, 0xe7, 0x1d, 0x5c, 0x8d, 0xa8, + 0xd9, 0x37, 0xd7, 0x37, 0x3f, 0xb2, 0xf8, 0x4c, 0x29, 0x5d, 0x3c, 0x65, 0x02, 0x5f, 0x31, 0x39, + 0xd9, 0x12, 0xb2, 0x0e, 0x56, 0x93, 0x45, 0x2b, 0x8f, 0x4b, 0xb4, 0xa1, 0x4d, 0xa1, 0x05, 0x25, + 0xea, 0x8a, 0xbf, 0xca, 0x01, 0xa8, 0x4f, 0x9e, 0x86, 0x81, 0x4f, 0x71, 0x4f, 0x66, 0x4f, 0xc1, 0x44, 0x95, 0x6b, 0x8e, 0xb0, 0x2d, 0x71, 0xcd, 0xdc, 0x49, 0xac, 0x37, 0x25, 0xfe, 0xc4, 0x72, 0x46, 0x1d, 0x6a, 0x03, 0x80, 0x77, 0xc0, 0x20, 0xc1, 0x34, 0x76, 0x23, 0xb3, 0x6f, 0xce, 0x98, 0x1f, 0x59, 0xbc, 0xde, 0x15, 0x8a, 0x87, 0x36, 0x0b, 0xbe, 0x52, 0xfd, 0xb9, 0x52, 0x25, 0xb2, 0xa2, 0x98, 0x96, 0xcf, 0x4b, 0xa4, 0x41, 0xc4, 0x75, 0x20, 0xa9, 0xab, 0xf8, 0x5f, 0x03, 0x4c, 0xe8, 0x5e, 0xaa, 0x3b, 0xf8, 0x00, 0x12, 0x30, 0x44, 0x44, 0xb0, 0x70, 0x3f, 0x8d, 0x2c, 0xde, - 0x2a, 0x9d, 0xf4, 0x46, 0x95, 0xda, 0xe2, 0xaf, 0x3c, 0xc2, 0x8e, 0x4b, 0xfe, 0x83, 0x12, 0x20, - 0x58, 0x07, 0x79, 0x22, 0xcf, 0x88, 0x07, 0xd2, 0xc8, 0xe2, 0x7a, 0x6f, 0x40, 0x85, 0xce, 0xf2, - 0x68, 0xb3, 0x51, 0xc8, 0x27, 0xff, 0x21, 0x85, 0x55, 0xfc, 0x65, 0x0e, 0xcc, 0x2e, 0xc7, 0x34, - 0x0a, 0x3c, 0x84, 0x69, 0x10, 0x93, 0x2a, 0x5e, 0x0e, 0xdc, 0xd8, 0xf3, 0x57, 0xf0, 0xae, 0xe3, - 0x3b, 0x11, 0x8b, 0xd1, 0x39, 0xd0, 0xef, 0x5b, 0x1e, 0x96, 0x31, 0x33, 0x2a, 0x3d, 0xd9, 0x7f, - 0xdb, 0xf2, 0x30, 0xe2, 0x1c, 0x26, 0xc1, 0x42, 0x44, 0xde, 0x00, 0x25, 0x71, 0xe7, 0x28, 0xc4, - 0x88, 0x73, 0xe0, 0x35, 0x30, 0xb8, 0x1b, 0x10, 0xcf, 0x12, 0xa7, 0x37, 0x9c, 0x9e, 0xc7, 0x4d, - 0x4e, 0x45, 0x92, 0x0b, 0x5f, 0x00, 0x23, 0x36, 0xa6, 0x55, 0xe2, 0x84, 0x0c, 0xda, 0xec, 0xe7, - 0xc2, 0x17, 0xa4, 0xf0, 0xc8, 0x4a, 0xca, 0x42, 0xba, 0x1c, 0xbc, 0x0e, 0xf2, 0x21, 0x71, 0x02, - 0xe2, 0x44, 0x47, 0xe6, 0xc0, 0x9c, 0x31, 0x3f, 0x50, 0x9e, 0x90, 0x6b, 0xf2, 0x5b, 0x92, 0x8e, - 0x94, 0x04, 0x93, 0x7e, 0x87, 0x06, 0xfe, 0x96, 0x15, 0xed, 0x99, 0x83, 0x1c, 0x41, 0x49, 0xbf, - 0x5a, 0xd9, 0xbc, 0xcd, 0xe8, 0x48, 0x49, 0x14, 0xff, 0x6c, 0x00, 0x33, 0xeb, 0xa1, 0xc4, 0xbd, - 0xf0, 0x26, 0xc8, 0xd3, 0x88, 0xe5, 0x9c, 0xda, 0x91, 0xf4, 0xcf, 0x53, 0x89, 0xaa, 0x8a, 0xa4, - 0x1f, 0x37, 0x0a, 0xd3, 0xe9, 0x8a, 0x84, 0xca, 0x7d, 0xa3, 0xd6, 0xb2, 0x90, 0x3b, 0xc0, 0x3b, - 0x7b, 0x41, 0xb0, 0x2f, 0x4f, 0xff, 0x14, 0x21, 0xf7, 0x9a, 0x50, 0x94, 0x62, 0x8a, 0x90, 0x93, - 0x64, 0x94, 0x00, 0x15, 0xff, 0x93, 0xcb, 0x6e, 0x4c, 0x3b, 0xf4, 0xb7, 0x41, 0x9e, 0x5d, 0x21, - 0xdb, 0x8a, 0x2c, 0x79, 0x09, 0x9e, 0x7d, 0xb4, 0x0b, 0x27, 0xee, 0xeb, 0x06, 0x8e, 0xac, 0x32, - 0x94, 0xae, 0x00, 0x29, 0x0d, 0x29, 0xad, 0xf0, 0x10, 0xf4, 0xd3, 0x10, 0x57, 0xe5, 0x7e, 0xef, - 0x9d, 0x22, 0xda, 0xbb, 0xec, 0xa1, 0x12, 0xe2, 0x6a, 0x1a, 0x8c, 0xec, 0x3f, 0xc4, 0x11, 0xe1, - 0xbb, 0x06, 0x18, 0xa4, 0x3c, 0x2f, 0xc8, 0x5c, 0xb2, 0x7d, 0x06, 0xe0, 0x99, 0xbc, 0x23, 0xfe, - 0x47, 0x12, 0xb7, 0xf8, 0xcf, 0x1c, 0xb8, 0xda, 0x6d, 0xe9, 0x72, 0xe0, 0xdb, 0xe2, 0x10, 0xd6, - 0xe4, 0xbd, 0x12, 0x91, 0xf5, 0x82, 0x7e, 0xaf, 0x8e, 0x1b, 0x85, 0x27, 0x1e, 0xaa, 0x40, 0xbb, - 0x80, 0x5f, 0x55, 0x5b, 0x16, 0x97, 0xf4, 0x6a, 0xab, 0x61, 0xc7, 0x8d, 0xc2, 0xb8, 0x5a, 0xd6, - 0x6a, 0x2b, 0xac, 0x03, 0xe8, 0x5a, 0x34, 0xba, 0x43, 0x2c, 0x9f, 0x0a, 0xb5, 0x8e, 0x87, 0xa5, - 0xe7, 0x9e, 0x7a, 0xb4, 0xa0, 0x60, 0x2b, 0xca, 0x33, 0x12, 0x12, 0xae, 0xb7, 0x69, 0x43, 0x1d, - 0x10, 0x58, 0xce, 0x20, 0xd8, 0xa2, 0x2a, 0x0d, 0x68, 0x39, 0x9c, 0x51, 0x91, 0xe4, 0xc2, 0x27, - 0xc1, 0x90, 0x87, 0x29, 0xb5, 0x6a, 0x98, 0xdf, 0xfd, 0xe1, 0xb4, 0x28, 0x6e, 0x08, 0x32, 0x4a, - 0xf8, 0xc5, 0x7f, 0x19, 0xe0, 0x72, 0x37, 0xaf, 0xad, 0x3b, 0x34, 0x82, 0xdf, 0x6c, 0x0b, 0xfb, - 0xd2, 0xa3, 0xed, 0x90, 0xad, 0xe6, 0x41, 0xaf, 0x52, 0x49, 0x42, 0xd1, 0x42, 0xfe, 0x00, 0x0c, - 0x38, 0x11, 0xf6, 0x92, 0x6a, 0x89, 0x7a, 0x1f, 0x76, 0xe5, 0x31, 0x09, 0x3f, 0xb0, 0xc6, 0x80, - 0x90, 0xc0, 0x2b, 0x7e, 0x94, 0x03, 0x57, 0xba, 0x2d, 0x61, 0x79, 0x9c, 0x32, 0x67, 0x87, 0x6e, - 0x4c, 0x2c, 0x57, 0x06, 0x9b, 0x72, 0xf6, 0x16, 0xa7, 0x22, 0xc9, 0x65, 0xb9, 0x93, 0x3a, 0x7e, - 0x2d, 0x76, 0x2d, 0x22, 0x23, 0x49, 0x6d, 0xb8, 0x22, 0xe9, 0x48, 0x49, 0xc0, 0x12, 0x00, 0x74, - 0x2f, 0x20, 0x11, 0xc7, 0xe0, 0x1d, 0xce, 0x70, 0xf9, 0x3c, 0xcb, 0x08, 0x15, 0x45, 0x45, 0x9a, - 0x04, 0x2b, 0x24, 0xfb, 0x8e, 0x6f, 0xcb, 0x03, 0x57, 0x77, 0xf7, 0x96, 0xe3, 0xdb, 0x88, 0x73, - 0x18, 0xbe, 0xeb, 0xd0, 0x88, 0x51, 0xe4, 0x69, 0xb7, 0x38, 0x9c, 0x4b, 0x2a, 0x09, 0x86, 0x5f, - 0x65, 0x09, 0x36, 0x20, 0x0e, 0xa6, 0xe6, 0x60, 0x8a, 0xbf, 0xac, 0xa8, 0x48, 0x93, 0x28, 0xfe, - 0xa5, 0xbf, 0x7b, 0x7c, 0xb0, 0x04, 0x02, 0x1f, 0x07, 0x03, 0x35, 0x12, 0xc4, 0xa1, 0xf4, 0x92, - 0xf2, 0xf6, 0xcb, 0x8c, 0x88, 0x04, 0x0f, 0x7e, 0x07, 0x0c, 0xf8, 0x72, 0xc3, 0x2c, 0x82, 0x5e, - 0xeb, 0xfd, 0x31, 0x73, 0x6f, 0xa5, 0xe8, 0xc2, 0x91, 0x02, 0x14, 0x3e, 0x0f, 0x06, 0x68, 0x35, - 0x08, 0xb1, 0x74, 0xe2, 0x6c, 0x22, 0x54, 0x61, 0xc4, 0xe3, 0x46, 0x61, 0x2c, 0x51, 0xc7, 0x09, - 0x48, 0x08, 0xc3, 0x1f, 0x18, 0x20, 0x2f, 0xcb, 0x05, 0x35, 0x87, 0x78, 0x78, 0xbe, 0xde, 0x7b, - 0xbb, 0x65, 0xdb, 0x9b, 0x9e, 0x99, 0x24, 0x50, 0xa4, 0xc0, 0xe1, 0xf7, 0x0c, 0x00, 0xaa, 0xaa, - 0x76, 0x99, 0xc3, 0xdc, 0x87, 0x3d, 0xbb, 0x2a, 0x5a, 0x55, 0x14, 0x81, 0x90, 0xb6, 0x4a, 0x1a, - 0x2a, 0xac, 0x80, 0xa9, 0x90, 0x60, 0xae, 0xfb, 0xae, 0xbf, 0xef, 0x07, 0x07, 0xfe, 0x4d, 0x07, - 0xbb, 0x36, 0x35, 0xc1, 0x9c, 0x31, 0x9f, 0x2f, 0x5f, 0x91, 0xf6, 0x4f, 0x6d, 0x75, 0x12, 0x42, - 0x9d, 0xd7, 0x16, 0xdf, 0xeb, 0xcb, 0xf6, 0x5a, 0xd9, 0x7a, 0x01, 0x3f, 0x10, 0x9b, 0x17, 0x79, - 0x98, 0x9a, 0x06, 0x3f, 0x88, 0x37, 0x7b, 0x7f, 0x10, 0x2a, 0xd7, 0xa7, 0x45, 0x5a, 0x91, 0x28, - 0xd2, 0x4c, 0x80, 0x3f, 0x33, 0xc0, 0x98, 0x55, 0xad, 0xe2, 0x30, 0xc2, 0xb6, 0xb8, 0xc6, 0xb9, - 0xb3, 0x8d, 0xea, 0x29, 0x69, 0xd0, 0xd8, 0x92, 0x8e, 0x8a, 0x5a, 0x8d, 0x80, 0x2f, 0x81, 0xf3, - 0x34, 0x0a, 0x08, 0xb6, 0x93, 0x08, 0x92, 0xd9, 0x05, 0x36, 0x1b, 0x85, 0xf3, 0x95, 0x16, 0x0e, - 0xca, 0x48, 0x16, 0x3f, 0x19, 0x00, 0x85, 0x87, 0x44, 0xe8, 0x23, 0x34, 0xbd, 0xd7, 0xc0, 0x20, - 0xdf, 0xa9, 0xcd, 0x1d, 0x92, 0xd7, 0x4a, 0x3d, 0xa7, 0x22, 0xc9, 0x65, 0xe5, 0x89, 0xe1, 0xb3, - 0xf2, 0xd4, 0xc7, 0x05, 0x55, 0x79, 0xaa, 0x08, 0x32, 0x4a, 0xf8, 0x70, 0x11, 0x00, 0x1b, 0x87, - 0x04, 0xb3, 0x8c, 0x64, 0x9b, 0x43, 0x5c, 0x5a, 0x9d, 0xcf, 0x8a, 0xe2, 0x20, 0x4d, 0x0a, 0xde, - 0x04, 0x30, 0xf9, 0xcf, 0x09, 0xfc, 0xd7, 0x2c, 0xe2, 0x3b, 0x7e, 0xcd, 0xcc, 0x73, 0xb3, 0xa7, - 0x59, 0xb5, 0x5d, 0x69, 0xe3, 0xa2, 0x0e, 0x2b, 0x60, 0x1d, 0x0c, 0x8a, 0x67, 0x34, 0xcf, 0x1b, - 0x3d, 0xbc, 0x71, 0xf7, 0x2c, 0xd7, 0xb1, 0x39, 0x54, 0x19, 0x70, 0xf7, 0x70, 0x14, 0x24, 0xd1, - 0xe0, 0xfb, 0x06, 0x18, 0xa5, 0xf1, 0x0e, 0x91, 0xd2, 0x94, 0x67, 0xf5, 0x91, 0xc5, 0x3b, 0xbd, - 0x82, 0xaf, 0x68, 0xba, 0xcb, 0x13, 0xcd, 0x46, 0x61, 0x54, 0xa7, 0xa0, 0x16, 0x6c, 0xf8, 0x07, - 0x03, 0x98, 0x96, 0x2d, 0x42, 0xdf, 0x72, 0xb7, 0x88, 0xe3, 0x47, 0x98, 0x88, 0x07, 0x91, 0x28, - 0x1f, 0x3d, 0xec, 0x15, 0xb3, 0xef, 0xac, 0xf2, 0x9c, 0x3c, 0x69, 0x73, 0xa9, 0x8b, 0x05, 0xa8, - 0xab, 0x6d, 0xc5, 0x7f, 0x1b, 0xd9, 0xd4, 0xa2, 0xed, 0xb2, 0x52, 0xb5, 0x5c, 0x0c, 0x57, 0xc0, - 0x04, 0xeb, 0x7e, 0x11, 0x0e, 0x5d, 0xa7, 0x6a, 0x51, 0xfe, 0xfa, 0x11, 0xd1, 0xad, 0x9e, 0xe1, - 0x95, 0x0c, 0x1f, 0xb5, 0xad, 0x80, 0xaf, 0x02, 0x28, 0xda, 0xc2, 0x16, 0x3d, 0xa2, 0x13, 0x50, - 0x0d, 0x5e, 0xa5, 0x4d, 0x02, 0x75, 0x58, 0x05, 0x97, 0xc1, 0xa4, 0x6b, 0xed, 0x60, 0xb7, 0x82, - 0x5d, 0x5c, 0x8d, 0x02, 0xc2, 0x55, 0x89, 0xf7, 0xe1, 0x54, 0xb3, 0x51, 0x98, 0x5c, 0xcf, 0x32, - 0x51, 0xbb, 0x7c, 0xf1, 0x6a, 0xf6, 0x2e, 0xeb, 0x1b, 0x17, 0xcd, 0xf6, 0x87, 0x39, 0x30, 0xd3, - 0x3d, 0x28, 0xe0, 0x77, 0x55, 0x6b, 0x2c, 0x3a, 0xbe, 0xd7, 0xcf, 0x20, 0xf4, 0xe4, 0x73, 0x00, - 0xb4, 0x3f, 0x05, 0xe0, 0x11, 0xab, 0xd7, 0x96, 0x9b, 0x3c, 0xfb, 0xb7, 0xcf, 0x02, 0x9d, 0xe9, - 0x2f, 0x0f, 0x8b, 0x2e, 0xc0, 0x72, 0x79, 0xd1, 0xb7, 0x5c, 0x5c, 0xfc, 0xa8, 0xed, 0x69, 0x9b, - 0x5e, 0x56, 0xf8, 0x43, 0x03, 0x8c, 0x07, 0x21, 0xf6, 0x97, 0xb6, 0xd6, 0xee, 0x7d, 0x59, 0x5c, - 0x5a, 0xe9, 0xa0, 0xb5, 0x93, 0x9b, 0xc8, 0xde, 0xd7, 0x42, 0xd7, 0x16, 0x09, 0x42, 0x5a, 0xbe, - 0xd0, 0x6c, 0x14, 0xc6, 0x37, 0x5b, 0x51, 0x50, 0x16, 0xb6, 0xe8, 0x81, 0xa9, 0xd5, 0xc3, 0x08, - 0x13, 0xdf, 0x72, 0x57, 0x82, 0x6a, 0xec, 0x61, 0x3f, 0x12, 0x36, 0x66, 0xc6, 0x05, 0xc6, 0x23, - 0x8e, 0x0b, 0xae, 0x80, 0xbe, 0x98, 0xb8, 0x32, 0x6a, 0x47, 0xd4, 0x10, 0x0c, 0xad, 0x23, 0x46, - 0x2f, 0x5e, 0x05, 0xfd, 0xcc, 0x4e, 0x78, 0x09, 0xf4, 0x11, 0xeb, 0x80, 0x6b, 0x1d, 0x2d, 0x0f, - 0x31, 0x11, 0x64, 0x1d, 0x20, 0x46, 0x2b, 0xfe, 0x7d, 0x0e, 0x8c, 0x67, 0xf6, 0x02, 0x67, 0x40, - 0x4e, 0x4d, 0xd6, 0x80, 0x54, 0x9a, 0x5b, 0x5b, 0x41, 0x39, 0xc7, 0x86, 0x2f, 0xaa, 0xec, 0x2a, - 0x40, 0x0b, 0xaa, 0x58, 0x70, 0x2a, 0x6b, 0xcb, 0x52, 0x75, 0xcc, 0x90, 0x24, 0x3d, 0x32, 0x1b, - 0xf0, 0xae, 0xbc, 0x15, 0xc2, 0x06, 0xbc, 0x8b, 0x18, 0xed, 0xa4, 0xb3, 0x92, 0x64, 0x58, 0x33, - 0xf0, 0x08, 0xc3, 0x9a, 0xc1, 0x07, 0x0e, 0x6b, 0x1e, 0x07, 0x03, 0x91, 0x13, 0xb9, 0x98, 0x57, - 0x2a, 0xad, 0x19, 0xbe, 0xc3, 0x88, 0x48, 0xf0, 0x20, 0x06, 0x43, 0x36, 0xde, 0xb5, 0x62, 0x37, - 0xe2, 0x45, 0x69, 0x64, 0xf1, 0xeb, 0xa7, 0x8b, 0x1e, 0x31, 0xcc, 0x58, 0x11, 0x2a, 0x51, 0xa2, - 0x1b, 0x3e, 0x01, 0x86, 0x3c, 0xeb, 0xd0, 0xf1, 0x62, 0x8f, 0x77, 0x8c, 0x86, 0x10, 0xdb, 0x10, - 0x24, 0x94, 0xf0, 0x58, 0x12, 0xc4, 0x87, 0x55, 0x37, 0xa6, 0x4e, 0x1d, 0x4b, 0xa6, 0x6c, 0xe9, - 0x54, 0x12, 0x5c, 0xcd, 0xf0, 0x51, 0xdb, 0x0a, 0x0e, 0xe6, 0xf8, 0x7c, 0xf1, 0x88, 0x06, 0x26, - 0x48, 0x28, 0xe1, 0xb5, 0x82, 0x49, 0xf9, 0xd1, 0x6e, 0x60, 0x72, 0x71, 0xdb, 0x0a, 0xf8, 0x34, - 0x18, 0xf6, 0xac, 0xc3, 0x75, 0xec, 0xd7, 0xa2, 0x3d, 0x73, 0x6c, 0xce, 0x98, 0xef, 0x2b, 0x8f, - 0x35, 0x1b, 0x85, 0xe1, 0x8d, 0x84, 0x88, 0x52, 0x3e, 0x17, 0x76, 0x7c, 0x29, 0x7c, 0x5e, 0x13, - 0x4e, 0x88, 0x28, 0xe5, 0xb3, 0xce, 0x24, 0xb4, 0x22, 0x76, 0xaf, 0xcc, 0xf1, 0xd6, 0x87, 0xf3, - 0x96, 0x20, 0xa3, 0x84, 0x0f, 0xe7, 0x41, 0xde, 0xb3, 0x0e, 0xf9, 0x9b, 0xd2, 0x9c, 0xe0, 0x6a, - 0xf9, 0x40, 0x71, 0x43, 0xd2, 0x90, 0xe2, 0x72, 0x49, 0xc7, 0x17, 0x92, 0x93, 0x9a, 0xa4, 0xa4, - 0x21, 0xc5, 0x65, 0xf1, 0x1b, 0xfb, 0xce, 0xfd, 0x18, 0x0b, 0x61, 0xc8, 0x3d, 0xa3, 0xe2, 0xf7, - 0x6e, 0xca, 0x42, 0xba, 0x1c, 0x7b, 0xd3, 0x79, 0xb1, 0x1b, 0x39, 0xa1, 0x8b, 0x37, 0x77, 0xcd, - 0x0b, 0xdc, 0xff, 0xbc, 0x95, 0xdf, 0x50, 0x54, 0xa4, 0x49, 0xc0, 0xb7, 0x41, 0x3f, 0xf6, 0x63, - 0xcf, 0xbc, 0xc8, 0xcb, 0xf7, 0x69, 0xa3, 0x4f, 0xdd, 0x97, 0x55, 0x3f, 0xf6, 0x10, 0xd7, 0x0c, - 0x5f, 0x04, 0x63, 0x9e, 0x75, 0xc8, 0x92, 0x00, 0x26, 0x11, 0x7b, 0x68, 0x4e, 0xf1, 0x7d, 0x4f, - 0xb2, 0x26, 0x76, 0x43, 0x67, 0xa0, 0x56, 0x39, 0xbe, 0xd0, 0xf1, 0xb5, 0x85, 0xd3, 0xda, 0x42, - 0x9d, 0x81, 0x5a, 0xe5, 0x98, 0x93, 0x09, 0xbe, 0x1f, 0x3b, 0x04, 0xdb, 0xe6, 0xff, 0xf1, 0xbe, - 0x57, 0xce, 0x77, 0x05, 0x0d, 0x29, 0x2e, 0xbc, 0x9f, 0x8c, 0x1c, 0x4c, 0x7e, 0xf9, 0xb6, 0x7a, - 0x96, 0xba, 0x37, 0xc9, 0x12, 0x21, 0xd6, 0x91, 0xa8, 0x2a, 0xfa, 0xb0, 0x01, 0xfa, 0x60, 0xc0, - 0x72, 0xdd, 0xcd, 0x5d, 0xf3, 0x12, 0xf7, 0x78, 0x0f, 0xab, 0x85, 0xca, 0x30, 0x4b, 0x4c, 0x3f, - 0x12, 0x30, 0x0c, 0x2f, 0xf0, 0x59, 0x2c, 0xcc, 0x9c, 0x19, 0xde, 0x26, 0xd3, 0x8f, 0x04, 0x0c, - 0xdf, 0x9f, 0x7f, 0xb4, 0xb9, 0x6b, 0x3e, 0x76, 0x76, 0xfb, 0x63, 0xfa, 0x91, 0x80, 0x81, 0x36, - 0xe8, 0xf3, 0x83, 0xc8, 0xbc, 0xdc, 0xeb, 0xda, 0xcb, 0xab, 0xc9, 0xed, 0x20, 0x42, 0x4c, 0x3d, - 0xfc, 0xb1, 0x01, 0x40, 0x98, 0x46, 0xe2, 0x95, 0xd3, 0x8e, 0x00, 0x32, 0x68, 0xa5, 0x34, 0x7a, - 0x57, 0xfd, 0x88, 0x1c, 0xa5, 0xef, 0x1a, 0x2d, 0xca, 0x35, 0x03, 0xe0, 0x2f, 0x0c, 0x70, 0x51, - 0x6f, 0x77, 0x95, 0x65, 0xb3, 0xdc, 0x0f, 0x9b, 0x3d, 0x0c, 0xe4, 0x72, 0x10, 0xb8, 0x65, 0xb3, - 0xd9, 0x28, 0x5c, 0x5c, 0xea, 0x00, 0x88, 0x3a, 0x9a, 0x01, 0x7f, 0x63, 0x80, 0x49, 0x99, 0x1d, - 0x35, 0xe3, 0x0a, 0xdc, 0x6d, 0x6f, 0xf7, 0xd0, 0x6d, 0x59, 0x08, 0xe1, 0x3d, 0xf5, 0x95, 0xb1, - 0x8d, 0x8f, 0xda, 0xad, 0x82, 0xbf, 0x37, 0xc0, 0xa8, 0x8d, 0x43, 0xec, 0xdb, 0xd8, 0xaf, 0x32, - 0x33, 0xe7, 0x4e, 0x3b, 0x57, 0xc8, 0x9a, 0xb9, 0xa2, 0x69, 0x17, 0x16, 0x96, 0xa4, 0x85, 0xa3, - 0x3a, 0xeb, 0xb8, 0x51, 0x98, 0x4e, 0x97, 0xea, 0x1c, 0xd4, 0x62, 0x20, 0xfc, 0x89, 0x01, 0xc6, - 0x53, 0xb7, 0x8b, 0x02, 0x71, 0xf5, 0x6c, 0x0e, 0x9e, 0xb7, 0xa0, 0x4b, 0xad, 0x58, 0x28, 0x0b, - 0x0e, 0x7f, 0x6b, 0xb0, 0x6e, 0x2b, 0x79, 0xab, 0x51, 0xb3, 0xc8, 0x3d, 0xf8, 0x46, 0x2f, 0x3d, - 0xa8, 0x94, 0x0b, 0x07, 0x5e, 0x4f, 0x3b, 0x39, 0xc5, 0x39, 0x6e, 0x14, 0xa6, 0x74, 0xff, 0x29, - 0x06, 0xd2, 0x8d, 0x83, 0xef, 0x19, 0x60, 0x14, 0xa7, 0x0d, 0x33, 0x35, 0x1f, 0x3f, 0xad, 0xeb, - 0x3a, 0xb6, 0xdf, 0xe2, 0x39, 0xad, 0xb1, 0x28, 0x6a, 0x81, 0x65, 0xbd, 0x1f, 0x3e, 0xb4, 0xbc, - 0xd0, 0xc5, 0xe6, 0xff, 0xf7, 0xae, 0xf7, 0x5b, 0x15, 0x2a, 0x51, 0xa2, 0x1b, 0x5e, 0x07, 0x79, - 0x3f, 0x76, 0x5d, 0x6b, 0xc7, 0xc5, 0xe6, 0x13, 0xbc, 0x8b, 0x50, 0xf3, 0xc5, 0xdb, 0x92, 0x8e, - 0x94, 0x04, 0xdc, 0x05, 0x73, 0x87, 0xb7, 0xd4, 0x8f, 0x2f, 0x3a, 0x0e, 0xf0, 0xcc, 0x6b, 0x5c, - 0xcb, 0x4c, 0xb3, 0x51, 0x98, 0xde, 0xee, 0x3c, 0xe2, 0x7b, 0xa8, 0x0e, 0xf8, 0x26, 0x78, 0x4c, - 0x93, 0x59, 0xf5, 0x76, 0xb0, 0x6d, 0x63, 0x3b, 0x79, 0x68, 0x99, 0x5f, 0xe2, 0x10, 0xea, 0x1e, - 0x6f, 0x67, 0x05, 0xd0, 0x83, 0x56, 0xc3, 0x75, 0x30, 0xad, 0xb1, 0xd7, 0xfc, 0x68, 0x93, 0x54, - 0x22, 0xe2, 0xf8, 0x35, 0x73, 0x9e, 0xeb, 0xbd, 0x98, 0xdc, 0xbe, 0x6d, 0x8d, 0x87, 0xba, 0xac, - 0x81, 0xaf, 0xb4, 0x68, 0xe3, 0x1f, 0x2e, 0xac, 0xf0, 0x16, 0x3e, 0xa2, 0xe6, 0x93, 0xbc, 0xb9, - 0xe0, 0xe7, 0xbc, 0xad, 0xd1, 0x51, 0x17, 0x79, 0xf8, 0x0d, 0x70, 0x21, 0xc3, 0x61, 0xef, 0x0a, - 0xf3, 0x29, 0xf1, 0x40, 0x60, 0x9d, 0xe8, 0x76, 0x42, 0x44, 0x9d, 0x24, 0xe1, 0xd7, 0x00, 0xd4, - 0xc8, 0x1b, 0x56, 0xc8, 0xd7, 0x3f, 0x2d, 0xde, 0x2a, 0xec, 0x44, 0xb7, 0x25, 0x0d, 0x75, 0x90, - 0x83, 0x1f, 0x1a, 0x2d, 0x3b, 0x49, 0x5f, 0xb3, 0xd4, 0xbc, 0xce, 0x2f, 0xec, 0x2b, 0x27, 0x0f, - 0xc0, 0x54, 0x19, 0x8a, 0x5d, 0xac, 0x79, 0x58, 0x43, 0x41, 0x5d, 0xd0, 0x67, 0xd8, 0x63, 0x3a, - 0x93, 0xc3, 0xe1, 0x04, 0xe8, 0xdb, 0xc7, 0xf2, 0xb3, 0x31, 0x62, 0x7f, 0xc2, 0xb7, 0xc0, 0x40, - 0xdd, 0x72, 0xe3, 0x64, 0x14, 0xd0, 0xbb, 0x5a, 0x8f, 0x84, 0xde, 0x97, 0x72, 0x37, 0x8c, 0x99, - 0x0f, 0x0c, 0x30, 0xdd, 0xb9, 0xaa, 0x7c, 0x51, 0x16, 0xfd, 0xdc, 0x00, 0x93, 0x6d, 0x05, 0xa4, - 0x83, 0x31, 0x6e, 0xab, 0x31, 0xf7, 0x7a, 0x58, 0x09, 0xc4, 0x45, 0xe0, 0x1d, 0xad, 0x6e, 0xd9, - 0x8f, 0x0c, 0x30, 0x91, 0x4d, 0xcc, 0x5f, 0x90, 0x97, 0x8a, 0xef, 0xe7, 0xc0, 0x74, 0xe7, 0x1e, - 0x1c, 0x7a, 0x6a, 0xba, 0xd0, 0xf3, 0x01, 0x4d, 0xa7, 0x91, 0xed, 0xbb, 0x06, 0x18, 0x79, 0x47, - 0xc9, 0x25, 0x5f, 0x33, 0x7b, 0x39, 0x15, 0x4a, 0x4a, 0x5f, 0xca, 0xa0, 0x48, 0x87, 0x2c, 0xfe, - 0xce, 0x00, 0x53, 0x1d, 0xcb, 0x39, 0xbc, 0x06, 0x06, 0x2d, 0xd7, 0x0d, 0x0e, 0xc4, 0x34, 0x4f, - 0x1b, 0xcb, 0x2f, 0x71, 0x2a, 0x92, 0x5c, 0xcd, 0x67, 0xb9, 0xcf, 0xc1, 0x67, 0xc5, 0x3f, 0x1a, - 0xe0, 0xf2, 0x83, 0xa2, 0xee, 0xf3, 0x3e, 0xc3, 0x79, 0x90, 0x97, 0xcd, 0xf6, 0x11, 0x3f, 0x3f, - 0x99, 0x5d, 0x65, 0x46, 0xe0, 0xbf, 0x96, 0x11, 0x7f, 0x15, 0x7f, 0x65, 0x80, 0x89, 0x0a, 0x26, - 0x75, 0xa7, 0x8a, 0x11, 0xde, 0xc5, 0x04, 0xfb, 0x55, 0x0c, 0x17, 0xc0, 0x30, 0xff, 0xda, 0x18, - 0x5a, 0xd5, 0xe4, 0x1b, 0xc9, 0xa4, 0x74, 0xf4, 0xf0, 0xed, 0x84, 0x81, 0x52, 0x19, 0xf5, 0x3d, - 0x25, 0xd7, 0xf5, 0x7b, 0xca, 0x65, 0xd0, 0x1f, 0xa6, 0x03, 0xe0, 0x3c, 0xe3, 0xf2, 0x99, 0x2f, - 0xa7, 0x72, 0x6e, 0x40, 0x22, 0x3e, 0xe5, 0x1a, 0x90, 0xdc, 0x80, 0x44, 0x88, 0x53, 0x8b, 0xdf, - 0x02, 0xe7, 0x5b, 0xd3, 0x33, 0xc3, 0x23, 0xb1, 0xdb, 0xf6, 0xfd, 0x86, 0xf1, 0x10, 0xe7, 0xe8, - 0x3f, 0x1b, 0xc8, 0x3d, 0xe4, 0x67, 0x03, 0x7f, 0x32, 0xc0, 0x85, 0xe4, 0x57, 0x35, 0xae, 0x83, - 0xfd, 0x68, 0x39, 0xf0, 0x77, 0x9d, 0x1a, 0xbc, 0x24, 0xe6, 0x88, 0xda, 0x70, 0x2e, 0x99, 0x21, - 0xc2, 0xfb, 0x60, 0x88, 0x0a, 0xa7, 0xc9, 0xf3, 0x7c, 0xf5, 0xe4, 0xe7, 0x99, 0xf5, 0xbe, 0x68, - 0x83, 0x12, 0x6a, 0x82, 0xc3, 0x8e, 0xb4, 0x6a, 0x95, 0x63, 0xdf, 0x96, 0xb3, 0xe4, 0x51, 0x71, - 0xa4, 0xcb, 0x4b, 0x82, 0x86, 0x14, 0xb7, 0xf8, 0x0f, 0x03, 0x4c, 0xb6, 0xfd, 0x4a, 0x08, 0x7e, - 0xdf, 0x00, 0xa3, 0x55, 0x6d, 0x7b, 0xf2, 0x62, 0x6c, 0x9c, 0xfe, 0x97, 0x48, 0x9a, 0x52, 0xd1, - 0x4b, 0xe8, 0x14, 0xd4, 0x02, 0x0a, 0xb7, 0x81, 0x59, 0xcd, 0xfc, 0x20, 0x2f, 0xf3, 0x89, 0xef, - 0x72, 0xb3, 0x51, 0x30, 0x97, 0xbb, 0xc8, 0xa0, 0xae, 0xab, 0xcb, 0xdf, 0xfe, 0xf8, 0xb3, 0xd9, - 0x73, 0x9f, 0x7c, 0x36, 0x7b, 0xee, 0xd3, 0xcf, 0x66, 0xcf, 0xbd, 0xdb, 0x9c, 0x35, 0x3e, 0x6e, - 0xce, 0x1a, 0x9f, 0x34, 0x67, 0x8d, 0x4f, 0x9b, 0xb3, 0xc6, 0x5f, 0x9b, 0xb3, 0xc6, 0x4f, 0xff, - 0x36, 0x7b, 0xee, 0x8d, 0x1b, 0x27, 0xfd, 0x19, 0xee, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc0, - 0x20, 0xb3, 0x2b, 0xda, 0x2b, 0x00, 0x00, + 0x2a, 0x9d, 0x74, 0x47, 0x95, 0xda, 0xe2, 0xaf, 0x3c, 0xc2, 0x96, 0x4b, 0xfe, 0x41, 0x09, 0x10, + 0xac, 0x83, 0x3c, 0x91, 0x6b, 0xc4, 0x03, 0x69, 0x64, 0x71, 0xbd, 0x37, 0xa0, 0x42, 0x67, 0x79, + 0xb4, 0xd9, 0x28, 0xe4, 0x93, 0x7f, 0x48, 0x61, 0x15, 0x7f, 0x91, 0x03, 0xb3, 0xcb, 0x31, 0x8d, + 0x02, 0x0f, 0x61, 0x1a, 0xc4, 0xa4, 0x8a, 0x97, 0x03, 0x37, 0xf6, 0xfc, 0x15, 0xbc, 0xeb, 0xf8, + 0x4e, 0xc4, 0x62, 0x74, 0x0e, 0xf4, 0xfb, 0x96, 0x87, 0x65, 0xcc, 0x8c, 0x4a, 0x4f, 0xf6, 0xdf, + 0xb6, 0x3c, 0x8c, 0x38, 0x87, 0x49, 0xb0, 0x10, 0x91, 0x3b, 0x40, 0x49, 0xdc, 0x39, 0x0a, 0x31, + 0xe2, 0x1c, 0x78, 0x0d, 0x0c, 0xee, 0x06, 0xc4, 0xb3, 0xc4, 0xea, 0x0d, 0xa7, 0xeb, 0x71, 0x93, + 0x53, 0x91, 0xe4, 0xc2, 0x17, 0xc0, 0x88, 0x8d, 0x69, 0x95, 0x38, 0x21, 0x83, 0x36, 0xfb, 0xb9, + 0xf0, 0x05, 0x29, 0x3c, 0xb2, 0x92, 0xb2, 0x90, 0x2e, 0x07, 0xaf, 0x83, 0x7c, 0x48, 0x9c, 0x80, + 0x38, 0xd1, 0x91, 0x39, 0x30, 0x67, 0xcc, 0x0f, 0x94, 0x27, 0xe4, 0x98, 0xfc, 0x96, 0xa4, 0x23, + 0x25, 0xc1, 0xa4, 0xdf, 0xa1, 0x81, 0xbf, 0x65, 0x45, 0x7b, 0xe6, 0x20, 0x47, 0x50, 0xd2, 0xaf, + 0x56, 0x36, 0x6f, 0x33, 0x3a, 0x52, 0x12, 0xc5, 0x3f, 0x1b, 0xc0, 0xcc, 0x7a, 0x28, 0x71, 0x2f, + 0xbc, 0x09, 0xf2, 0x34, 0x62, 0x39, 0xa7, 0x76, 0x24, 0xfd, 0xf3, 0x54, 0xa2, 0xaa, 0x22, 0xe9, + 0xc7, 0x8d, 0xc2, 0x74, 0x3a, 0x22, 0xa1, 0x72, 0xdf, 0xa8, 0xb1, 0x2c, 0xe4, 0x0e, 0xf0, 0xce, + 0x5e, 0x10, 0xec, 0xcb, 0xd5, 0x3f, 0x45, 0xc8, 0xbd, 0x26, 0x14, 0xa5, 0x98, 0x22, 0xe4, 0x24, + 0x19, 0x25, 0x40, 0xc5, 0xff, 0xe4, 0xb2, 0x13, 0xd3, 0x16, 0xfd, 0x6d, 0x90, 0x67, 0x5b, 0xc8, + 0xb6, 0x22, 0x4b, 0x6e, 0x82, 0x67, 0x1f, 0x6d, 0xc3, 0x89, 0xfd, 0xba, 0x81, 0x23, 0xab, 0x0c, + 0xa5, 0x2b, 0x40, 0x4a, 0x43, 0x4a, 0x2b, 0x3c, 0x04, 0xfd, 0x34, 0xc4, 0x55, 0x39, 0xdf, 0x7b, + 0xa7, 0x88, 0xf6, 0x2e, 0x73, 0xa8, 0x84, 0xb8, 0x9a, 0x06, 0x23, 0xfb, 0x87, 0x38, 0x22, 0x7c, + 0xd7, 0x00, 0x83, 0x94, 0xe7, 0x05, 0x99, 0x4b, 0xb6, 0xcf, 0x00, 0x3c, 0x93, 0x77, 0xc4, 0x7f, + 0x24, 0x71, 0x8b, 0xff, 0xcc, 0x81, 0xab, 0xdd, 0x86, 0x2e, 0x07, 0xbe, 0x2d, 0x16, 0x61, 0x4d, + 0xee, 0x2b, 0x11, 0x59, 0x2f, 0xe8, 0xfb, 0xea, 0xb8, 0x51, 0x78, 0xe2, 0xa1, 0x0a, 0xb4, 0x0d, + 0xf8, 0x55, 0x35, 0x65, 0xb1, 0x49, 0xaf, 0xb6, 0x1a, 0x76, 0xdc, 0x28, 0x8c, 0xab, 0x61, 0xad, + 0xb6, 0xc2, 0x3a, 0x80, 0xae, 0x45, 0xa3, 0x3b, 0xc4, 0xf2, 0xa9, 0x50, 0xeb, 0x78, 0x58, 0x7a, + 0xee, 0xa9, 0x47, 0x0b, 0x0a, 0x36, 0xa2, 0x3c, 0x23, 0x21, 0xe1, 0x7a, 0x9b, 0x36, 0xd4, 0x01, + 0x81, 0xe5, 0x0c, 0x82, 0x2d, 0xaa, 0xd2, 0x80, 0x96, 0xc3, 0x19, 0x15, 0x49, 0x2e, 0x7c, 0x12, + 0x0c, 0x79, 0x98, 0x52, 0xab, 0x86, 0xf9, 0xde, 0x1f, 0x4e, 0x0f, 0xc5, 0x0d, 0x41, 0x46, 0x09, + 0xbf, 0xf8, 0x2f, 0x03, 0x5c, 0xee, 0xe6, 0xb5, 0x75, 0x87, 0x46, 0xf0, 0x9b, 0x6d, 0x61, 0x5f, + 0x7a, 0xb4, 0x19, 0xb2, 0xd1, 0x3c, 0xe8, 0x55, 0x2a, 0x49, 0x28, 0x5a, 0xc8, 0x1f, 0x80, 0x01, + 0x27, 0xc2, 0x5e, 0x72, 0x5a, 0xa2, 0xde, 0x87, 0x5d, 0x79, 0x4c, 0xc2, 0x0f, 0xac, 0x31, 0x20, + 0x24, 0xf0, 0x8a, 0x1f, 0xe5, 0xc0, 0x95, 0x6e, 0x43, 0x58, 0x1e, 0xa7, 0xcc, 0xd9, 0xa1, 0x1b, + 0x13, 0xcb, 0x95, 0xc1, 0xa6, 0x9c, 0xbd, 0xc5, 0xa9, 0x48, 0x72, 0x59, 0xee, 0xa4, 0x8e, 0x5f, + 0x8b, 0x5d, 0x8b, 0xc8, 0x48, 0x52, 0x13, 0xae, 0x48, 0x3a, 0x52, 0x12, 0xb0, 0x04, 0x00, 0xdd, + 0x0b, 0x48, 0xc4, 0x31, 0x78, 0x85, 0x33, 0x5c, 0x3e, 0xcf, 0x32, 0x42, 0x45, 0x51, 0x91, 0x26, + 0xc1, 0x0e, 0x92, 0x7d, 0xc7, 0xb7, 0xe5, 0x82, 0xab, 0xbd, 0x7b, 0xcb, 0xf1, 0x6d, 0xc4, 0x39, + 0x0c, 0xdf, 0x75, 0x68, 0xc4, 0x28, 0x72, 0xb5, 0x5b, 0x1c, 0xce, 0x25, 0x95, 0x04, 0xc3, 0xaf, + 0xb2, 0x04, 0x1b, 0x10, 0x07, 0x53, 0x73, 0x30, 0xc5, 0x5f, 0x56, 0x54, 0xa4, 0x49, 0x14, 0xff, + 0xd2, 0xdf, 0x3d, 0x3e, 0x58, 0x02, 0x81, 0x8f, 0x83, 0x81, 0x1a, 0x09, 0xe2, 0x50, 0x7a, 0x49, + 0x79, 0xfb, 0x65, 0x46, 0x44, 0x82, 0x07, 0xbf, 0x0d, 0x06, 0x7c, 0x39, 0x61, 0x16, 0x41, 0xaf, + 0xf5, 0x7e, 0x99, 0xb9, 0xb7, 0x52, 0x74, 0xe1, 0x48, 0x01, 0x0a, 0x9f, 0x07, 0x03, 0xb4, 0x1a, + 0x84, 0x58, 0x3a, 0x71, 0x36, 0x11, 0xaa, 0x30, 0xe2, 0x71, 0xa3, 0x30, 0x96, 0xa8, 0xe3, 0x04, + 0x24, 0x84, 0xe1, 0xf7, 0x0d, 0x90, 0x97, 0xc7, 0x05, 0x35, 0x87, 0x78, 0x78, 0xbe, 0xde, 0x7b, + 0xbb, 0x65, 0xd9, 0x9b, 0xae, 0x99, 0x24, 0x50, 0xa4, 0xc0, 0xe1, 0x77, 0x0d, 0x00, 0xaa, 0xea, + 0xec, 0x32, 0x87, 0xb9, 0x0f, 0x7b, 0xb6, 0x55, 0xb4, 0x53, 0x51, 0x04, 0x42, 0x5a, 0x2a, 0x69, + 0xa8, 0xb0, 0x02, 0xa6, 0x42, 0x82, 0xb9, 0xee, 0xbb, 0xfe, 0xbe, 0x1f, 0x1c, 0xf8, 0x37, 0x1d, + 0xec, 0xda, 0xd4, 0x04, 0x73, 0xc6, 0x7c, 0xbe, 0x7c, 0x45, 0xda, 0x3f, 0xb5, 0xd5, 0x49, 0x08, + 0x75, 0x1e, 0x5b, 0x7c, 0xaf, 0x2f, 0x5b, 0x6b, 0x65, 0xcf, 0x0b, 0xf8, 0x81, 0x98, 0xbc, 0xc8, + 0xc3, 0xd4, 0x34, 0xf8, 0x42, 0xbc, 0xd9, 0xfb, 0x85, 0x50, 0xb9, 0x3e, 0x3d, 0xa4, 0x15, 0x89, + 0x22, 0xcd, 0x04, 0xf8, 0x53, 0x03, 0x8c, 0x59, 0xd5, 0x2a, 0x0e, 0x23, 0x6c, 0x8b, 0x6d, 0x9c, + 0x3b, 0xdb, 0xa8, 0x9e, 0x92, 0x06, 0x8d, 0x2d, 0xe9, 0xa8, 0xa8, 0xd5, 0x08, 0xf8, 0x12, 0x38, + 0x4f, 0xa3, 0x80, 0x60, 0x3b, 0x89, 0x20, 0x99, 0x5d, 0x60, 0xb3, 0x51, 0x38, 0x5f, 0x69, 0xe1, + 0xa0, 0x8c, 0x64, 0xf1, 0x93, 0x01, 0x50, 0x78, 0x48, 0x84, 0x3e, 0x42, 0xd1, 0x7b, 0x0d, 0x0c, + 0xf2, 0x99, 0xda, 0xdc, 0x21, 0x79, 0xed, 0xa8, 0xe7, 0x54, 0x24, 0xb9, 0xec, 0x78, 0x62, 0xf8, + 0xec, 0x78, 0xea, 0xe3, 0x82, 0xea, 0x78, 0xaa, 0x08, 0x32, 0x4a, 0xf8, 0x70, 0x11, 0x00, 0x1b, + 0x87, 0x04, 0xb3, 0x8c, 0x64, 0x9b, 0x43, 0x5c, 0x5a, 0xad, 0xcf, 0x8a, 0xe2, 0x20, 0x4d, 0x0a, + 0xde, 0x04, 0x30, 0xf9, 0xe7, 0x04, 0xfe, 0x6b, 0x16, 0xf1, 0x1d, 0xbf, 0x66, 0xe6, 0xb9, 0xd9, + 0xd3, 0xec, 0xb4, 0x5d, 0x69, 0xe3, 0xa2, 0x0e, 0x23, 0x60, 0x1d, 0x0c, 0x8a, 0x6b, 0x34, 0xcf, + 0x1b, 0x3d, 0xdc, 0x71, 0xf7, 0x2c, 0xd7, 0xb1, 0x39, 0x54, 0x19, 0x70, 0xf7, 0x70, 0x14, 0x24, + 0xd1, 0xe0, 0xfb, 0x06, 0x18, 0xa5, 0xf1, 0x0e, 0x91, 0xd2, 0x94, 0x67, 0xf5, 0x91, 0xc5, 0x3b, + 0xbd, 0x82, 0xaf, 0x68, 0xba, 0xcb, 0x13, 0xcd, 0x46, 0x61, 0x54, 0xa7, 0xa0, 0x16, 0x6c, 0xf8, + 0x07, 0x03, 0x98, 0x96, 0x2d, 0x42, 0xdf, 0x72, 0xb7, 0x88, 0xe3, 0x47, 0x98, 0x88, 0x0b, 0x91, + 0x38, 0x3e, 0x7a, 0x58, 0x2b, 0x66, 0xef, 0x59, 0xe5, 0x39, 0xb9, 0xd2, 0xe6, 0x52, 0x17, 0x0b, + 0x50, 0x57, 0xdb, 0x8a, 0xff, 0x36, 0xb2, 0xa9, 0x45, 0x9b, 0x65, 0xa5, 0x6a, 0xb9, 0x18, 0xae, + 0x80, 0x09, 0x56, 0xfd, 0x22, 0x1c, 0xba, 0x4e, 0xd5, 0xa2, 0xfc, 0xf6, 0x23, 0xa2, 0x5b, 0x5d, + 0xc3, 0x2b, 0x19, 0x3e, 0x6a, 0x1b, 0x01, 0x5f, 0x05, 0x50, 0x94, 0x85, 0x2d, 0x7a, 0x44, 0x25, + 0xa0, 0x0a, 0xbc, 0x4a, 0x9b, 0x04, 0xea, 0x30, 0x0a, 0x2e, 0x83, 0x49, 0xd7, 0xda, 0xc1, 0x6e, + 0x05, 0xbb, 0xb8, 0x1a, 0x05, 0x84, 0xab, 0x12, 0xf7, 0xc3, 0xa9, 0x66, 0xa3, 0x30, 0xb9, 0x9e, + 0x65, 0xa2, 0x76, 0xf9, 0xe2, 0xd5, 0xec, 0x5e, 0xd6, 0x27, 0x2e, 0x8a, 0xed, 0x0f, 0x73, 0x60, + 0xa6, 0x7b, 0x50, 0xc0, 0xef, 0xa8, 0xd2, 0x58, 0x54, 0x7c, 0xaf, 0x9f, 0x41, 0xe8, 0xc9, 0xeb, + 0x00, 0x68, 0xbf, 0x0a, 0xc0, 0x23, 0x76, 0x5e, 0x5b, 0x6e, 0x72, 0xed, 0xdf, 0x3e, 0x0b, 0x74, + 0xa6, 0xbf, 0x3c, 0x2c, 0xaa, 0x00, 0xcb, 0xe5, 0x87, 0xbe, 0xe5, 0xe2, 0xe2, 0x47, 0x6d, 0x57, + 0xdb, 0x74, 0xb3, 0xc2, 0x1f, 0x18, 0x60, 0x3c, 0x08, 0xb1, 0xbf, 0xb4, 0xb5, 0x76, 0xef, 0xcb, + 0x62, 0xd3, 0x4a, 0x07, 0xad, 0x9d, 0xdc, 0x44, 0x76, 0xbf, 0x16, 0xba, 0xb6, 0x48, 0x10, 0xd2, + 0xf2, 0x85, 0x66, 0xa3, 0x30, 0xbe, 0xd9, 0x8a, 0x82, 0xb2, 0xb0, 0x45, 0x0f, 0x4c, 0xad, 0x1e, + 0x46, 0x98, 0xf8, 0x96, 0xbb, 0x12, 0x54, 0x63, 0x0f, 0xfb, 0x91, 0xb0, 0x31, 0xd3, 0x2e, 0x30, + 0x1e, 0xb1, 0x5d, 0x70, 0x05, 0xf4, 0xc5, 0xc4, 0x95, 0x51, 0x3b, 0xa2, 0x9a, 0x60, 0x68, 0x1d, + 0x31, 0x7a, 0xf1, 0x2a, 0xe8, 0x67, 0x76, 0xc2, 0x4b, 0xa0, 0x8f, 0x58, 0x07, 0x5c, 0xeb, 0x68, + 0x79, 0x88, 0x89, 0x20, 0xeb, 0x00, 0x31, 0x5a, 0xf1, 0xef, 0x73, 0x60, 0x3c, 0x33, 0x17, 0x38, + 0x03, 0x72, 0xaa, 0xb3, 0x06, 0xa4, 0xd2, 0xdc, 0xda, 0x0a, 0xca, 0x39, 0x36, 0x7c, 0x51, 0x65, + 0x57, 0x01, 0x5a, 0x50, 0x87, 0x05, 0xa7, 0xb2, 0xb2, 0x2c, 0x55, 0xc7, 0x0c, 0x49, 0xd2, 0x23, + 0xb3, 0x01, 0xef, 0xca, 0x5d, 0x21, 0x6c, 0xc0, 0xbb, 0x88, 0xd1, 0x4e, 0xda, 0x2b, 0x49, 0x9a, + 0x35, 0x03, 0x8f, 0xd0, 0xac, 0x19, 0x7c, 0x60, 0xb3, 0xe6, 0x71, 0x30, 0x10, 0x39, 0x91, 0x8b, + 0xf9, 0x49, 0xa5, 0x15, 0xc3, 0x77, 0x18, 0x11, 0x09, 0x1e, 0xc4, 0x60, 0xc8, 0xc6, 0xbb, 0x56, + 0xec, 0x46, 0xfc, 0x50, 0x1a, 0x59, 0xfc, 0xfa, 0xe9, 0xa2, 0x47, 0x34, 0x33, 0x56, 0x84, 0x4a, + 0x94, 0xe8, 0x86, 0x4f, 0x80, 0x21, 0xcf, 0x3a, 0x74, 0xbc, 0xd8, 0xe3, 0x15, 0xa3, 0x21, 0xc4, + 0x36, 0x04, 0x09, 0x25, 0x3c, 0x96, 0x04, 0xf1, 0x61, 0xd5, 0x8d, 0xa9, 0x53, 0xc7, 0x92, 0x29, + 0x4b, 0x3a, 0x95, 0x04, 0x57, 0x33, 0x7c, 0xd4, 0x36, 0x82, 0x83, 0x39, 0x3e, 0x1f, 0x3c, 0xa2, + 0x81, 0x09, 0x12, 0x4a, 0x78, 0xad, 0x60, 0x52, 0x7e, 0xb4, 0x1b, 0x98, 0x1c, 0xdc, 0x36, 0x02, + 0x3e, 0x0d, 0x86, 0x3d, 0xeb, 0x70, 0x1d, 0xfb, 0xb5, 0x68, 0xcf, 0x1c, 0x9b, 0x33, 0xe6, 0xfb, + 0xca, 0x63, 0xcd, 0x46, 0x61, 0x78, 0x23, 0x21, 0xa2, 0x94, 0xcf, 0x85, 0x1d, 0x5f, 0x0a, 0x9f, + 0xd7, 0x84, 0x13, 0x22, 0x4a, 0xf9, 0xac, 0x32, 0x09, 0xad, 0x88, 0xed, 0x2b, 0x73, 0xbc, 0xf5, + 0xe2, 0xbc, 0x25, 0xc8, 0x28, 0xe1, 0xc3, 0x79, 0x90, 0xf7, 0xac, 0x43, 0x7e, 0xa7, 0x34, 0x27, + 0xb8, 0x5a, 0xde, 0x50, 0xdc, 0x90, 0x34, 0xa4, 0xb8, 0x5c, 0xd2, 0xf1, 0x85, 0xe4, 0xa4, 0x26, + 0x29, 0x69, 0x48, 0x71, 0x59, 0xfc, 0xc6, 0xbe, 0x73, 0x3f, 0xc6, 0x42, 0x18, 0x72, 0xcf, 0xa8, + 0xf8, 0xbd, 0x9b, 0xb2, 0x90, 0x2e, 0xc7, 0xee, 0x74, 0x5e, 0xec, 0x46, 0x4e, 0xe8, 0xe2, 0xcd, + 0x5d, 0xf3, 0x02, 0xf7, 0x3f, 0x2f, 0xe5, 0x37, 0x14, 0x15, 0x69, 0x12, 0xf0, 0x6d, 0xd0, 0x8f, + 0xfd, 0xd8, 0x33, 0x2f, 0xf2, 0xe3, 0xfb, 0xb4, 0xd1, 0xa7, 0xf6, 0xcb, 0xaa, 0x1f, 0x7b, 0x88, + 0x6b, 0x86, 0x2f, 0x82, 0x31, 0xcf, 0x3a, 0x64, 0x49, 0x00, 0x93, 0x88, 0x5d, 0x34, 0xa7, 0xf8, + 0xbc, 0x27, 0x59, 0x11, 0xbb, 0xa1, 0x33, 0x50, 0xab, 0x1c, 0x1f, 0xe8, 0xf8, 0xda, 0xc0, 0x69, + 0x6d, 0xa0, 0xce, 0x40, 0xad, 0x72, 0xcc, 0xc9, 0x04, 0xdf, 0x8f, 0x1d, 0x82, 0x6d, 0xf3, 0xff, + 0x78, 0xdd, 0x2b, 0xfb, 0xbb, 0x82, 0x86, 0x14, 0x17, 0xde, 0x4f, 0x5a, 0x0e, 0x26, 0xdf, 0x7c, + 0x5b, 0x3d, 0x4b, 0xdd, 0x9b, 0x64, 0x89, 0x10, 0xeb, 0x48, 0x9c, 0x2a, 0x7a, 0xb3, 0x01, 0xfa, + 0x60, 0xc0, 0x72, 0xdd, 0xcd, 0x5d, 0xf3, 0x12, 0xf7, 0x78, 0x0f, 0x4f, 0x0b, 0x95, 0x61, 0x96, + 0x98, 0x7e, 0x24, 0x60, 0x18, 0x5e, 0xe0, 0xb3, 0x58, 0x98, 0x39, 0x33, 0xbc, 0x4d, 0xa6, 0x1f, + 0x09, 0x18, 0x3e, 0x3f, 0xff, 0x68, 0x73, 0xd7, 0x7c, 0xec, 0xec, 0xe6, 0xc7, 0xf4, 0x23, 0x01, + 0x03, 0x6d, 0xd0, 0xe7, 0x07, 0x91, 0x79, 0xb9, 0xd7, 0x67, 0x2f, 0x3f, 0x4d, 0x6e, 0x07, 0x11, + 0x62, 0xea, 0xe1, 0x8f, 0x0c, 0x00, 0xc2, 0x34, 0x12, 0xaf, 0x9c, 0xb6, 0x05, 0x90, 0x41, 0x2b, + 0xa5, 0xd1, 0xbb, 0xea, 0x47, 0xe4, 0x28, 0xbd, 0xd7, 0x68, 0x51, 0xae, 0x19, 0x00, 0x7f, 0x6e, + 0x80, 0x8b, 0x7a, 0xb9, 0xab, 0x2c, 0x9b, 0xe5, 0x7e, 0xd8, 0xec, 0x61, 0x20, 0x97, 0x83, 0xc0, + 0x2d, 0x9b, 0xcd, 0x46, 0xe1, 0xe2, 0x52, 0x07, 0x40, 0xd4, 0xd1, 0x0c, 0xf8, 0x1b, 0x03, 0x4c, + 0xca, 0xec, 0xa8, 0x19, 0x57, 0xe0, 0x6e, 0x7b, 0xbb, 0x87, 0x6e, 0xcb, 0x42, 0x08, 0xef, 0xa9, + 0x57, 0xc6, 0x36, 0x3e, 0x6a, 0xb7, 0x0a, 0xfe, 0xde, 0x00, 0xa3, 0x36, 0x0e, 0xb1, 0x6f, 0x63, + 0xbf, 0xca, 0xcc, 0x9c, 0x3b, 0x6d, 0x5f, 0x21, 0x6b, 0xe6, 0x8a, 0xa6, 0x5d, 0x58, 0x58, 0x92, + 0x16, 0x8e, 0xea, 0xac, 0xe3, 0x46, 0x61, 0x3a, 0x1d, 0xaa, 0x73, 0x50, 0x8b, 0x81, 0xf0, 0xc7, + 0x06, 0x18, 0x4f, 0xdd, 0x2e, 0x0e, 0x88, 0xab, 0x67, 0xb3, 0xf0, 0xbc, 0x04, 0x5d, 0x6a, 0xc5, + 0x42, 0x59, 0x70, 0xf8, 0x5b, 0x83, 0x55, 0x5b, 0xc9, 0x5d, 0x8d, 0x9a, 0x45, 0xee, 0xc1, 0x37, + 0x7a, 0xe9, 0x41, 0xa5, 0x5c, 0x38, 0xf0, 0x7a, 0x5a, 0xc9, 0x29, 0xce, 0x71, 0xa3, 0x30, 0xa5, + 0xfb, 0x4f, 0x31, 0x90, 0x6e, 0x1c, 0x7c, 0xcf, 0x00, 0xa3, 0x38, 0x2d, 0x98, 0xa9, 0xf9, 0xf8, + 0x69, 0x5d, 0xd7, 0xb1, 0xfc, 0x16, 0xd7, 0x69, 0x8d, 0x45, 0x51, 0x0b, 0x2c, 0xab, 0xfd, 0xf0, + 0xa1, 0xe5, 0x85, 0x2e, 0x36, 0xff, 0xbf, 0x77, 0xb5, 0xdf, 0xaa, 0x50, 0x89, 0x12, 0xdd, 0xf0, + 0x3a, 0xc8, 0xfb, 0xb1, 0xeb, 0x5a, 0x3b, 0x2e, 0x36, 0x9f, 0xe0, 0x55, 0x84, 0xea, 0x2f, 0xde, + 0x96, 0x74, 0xa4, 0x24, 0xe0, 0x2e, 0x98, 0x3b, 0xbc, 0xa5, 0x3e, 0xbe, 0xe8, 0xd8, 0xc0, 0x33, + 0xaf, 0x71, 0x2d, 0x33, 0xcd, 0x46, 0x61, 0x7a, 0xbb, 0x73, 0x8b, 0xef, 0xa1, 0x3a, 0xe0, 0x9b, + 0xe0, 0x31, 0x4d, 0x66, 0xd5, 0xdb, 0xc1, 0xb6, 0x8d, 0xed, 0xe4, 0xa2, 0x65, 0x7e, 0x89, 0x43, + 0xa8, 0x7d, 0xbc, 0x9d, 0x15, 0x40, 0x0f, 0x1a, 0x0d, 0xd7, 0xc1, 0xb4, 0xc6, 0x5e, 0xf3, 0xa3, + 0x4d, 0x52, 0x89, 0x88, 0xe3, 0xd7, 0xcc, 0x79, 0xae, 0xf7, 0x62, 0xb2, 0xfb, 0xb6, 0x35, 0x1e, + 0xea, 0x32, 0x06, 0xbe, 0xd2, 0xa2, 0x8d, 0x3f, 0x5c, 0x58, 0xe1, 0x2d, 0x7c, 0x44, 0xcd, 0x27, + 0x79, 0x71, 0xc1, 0xd7, 0x79, 0x5b, 0xa3, 0xa3, 0x2e, 0xf2, 0xf0, 0x1b, 0xe0, 0x42, 0x86, 0xc3, + 0xee, 0x15, 0xe6, 0x53, 0xe2, 0x82, 0xc0, 0x2a, 0xd1, 0xed, 0x84, 0x88, 0x3a, 0x49, 0xc2, 0xaf, + 0x01, 0xa8, 0x91, 0x37, 0xac, 0x90, 0x8f, 0x7f, 0x5a, 0xdc, 0x55, 0xd8, 0x8a, 0x6e, 0x4b, 0x1a, + 0xea, 0x20, 0x07, 0x3f, 0x34, 0x5a, 0x66, 0x92, 0xde, 0x66, 0xa9, 0x79, 0x9d, 0x6f, 0xd8, 0x57, + 0x4e, 0x1e, 0x80, 0xa9, 0x32, 0x14, 0xbb, 0x58, 0xf3, 0xb0, 0x86, 0x82, 0xba, 0xa0, 0xcf, 0xb0, + 0xcb, 0x74, 0x26, 0x87, 0xc3, 0x09, 0xd0, 0xb7, 0x8f, 0xe5, 0xb3, 0x31, 0x62, 0x3f, 0xe1, 0x5b, + 0x60, 0xa0, 0x6e, 0xb9, 0x71, 0xd2, 0x0a, 0xe8, 0xdd, 0x59, 0x8f, 0x84, 0xde, 0x97, 0x72, 0x37, + 0x8c, 0x99, 0x0f, 0x0c, 0x30, 0xdd, 0xf9, 0x54, 0xf9, 0xa2, 0x2c, 0xfa, 0x99, 0x01, 0x26, 0xdb, + 0x0e, 0x90, 0x0e, 0xc6, 0xb8, 0xad, 0xc6, 0xdc, 0xeb, 0xe1, 0x49, 0x20, 0x36, 0x02, 0xaf, 0x68, + 0x75, 0xcb, 0x7e, 0x68, 0x80, 0x89, 0x6c, 0x62, 0xfe, 0x82, 0xbc, 0x54, 0x7c, 0x3f, 0x07, 0xa6, + 0x3b, 0xd7, 0xe0, 0xd0, 0x53, 0xdd, 0x85, 0x9e, 0x37, 0x68, 0x3a, 0xb5, 0x6c, 0xdf, 0x35, 0xc0, + 0xc8, 0x3b, 0x4a, 0x2e, 0x79, 0xcd, 0xec, 0x65, 0x57, 0x28, 0x39, 0xfa, 0x52, 0x06, 0x45, 0x3a, + 0x64, 0xf1, 0x77, 0x06, 0x98, 0xea, 0x78, 0x9c, 0xc3, 0x6b, 0x60, 0xd0, 0x72, 0xdd, 0xe0, 0x40, + 0x74, 0xf3, 0xb4, 0xb6, 0xfc, 0x12, 0xa7, 0x22, 0xc9, 0xd5, 0x7c, 0x96, 0xfb, 0x1c, 0x7c, 0x56, + 0xfc, 0xa3, 0x01, 0x2e, 0x3f, 0x28, 0xea, 0x3e, 0xef, 0x35, 0x9c, 0x07, 0x79, 0x59, 0x6c, 0x1f, + 0xf1, 0xf5, 0x93, 0xd9, 0x55, 0x66, 0x04, 0xfe, 0xb5, 0x8c, 0xf8, 0x55, 0xfc, 0xa5, 0x01, 0x26, + 0x2a, 0x98, 0xd4, 0x9d, 0x2a, 0x46, 0x78, 0x17, 0x13, 0xec, 0x57, 0x31, 0x5c, 0x00, 0xc3, 0xfc, + 0xb5, 0x31, 0xb4, 0xaa, 0xc9, 0x1b, 0xc9, 0xa4, 0x74, 0xf4, 0xf0, 0xed, 0x84, 0x81, 0x52, 0x19, + 0xf5, 0x9e, 0x92, 0xeb, 0xfa, 0x9e, 0x72, 0x19, 0xf4, 0x87, 0x69, 0x03, 0x38, 0xcf, 0xb8, 0xbc, + 0xe7, 0xcb, 0xa9, 0x9c, 0x1b, 0x90, 0x88, 0x77, 0xb9, 0x06, 0x24, 0x37, 0x20, 0x11, 0xe2, 0xd4, + 0xe2, 0xaf, 0x0d, 0x70, 0xbe, 0x35, 0x3f, 0x33, 0x40, 0x12, 0xbb, 0x6d, 0x0f, 0x38, 0x8c, 0x87, + 0x38, 0x47, 0xff, 0x6e, 0x20, 0xf7, 0xe0, 0xef, 0x06, 0xe0, 0xcb, 0x60, 0x52, 0xfe, 0x5c, 0x3d, + 0x0c, 0x09, 0xa6, 0xfc, 0x65, 0xb2, 0xaf, 0xf5, 0x7b, 0xbf, 0x8d, 0xac, 0x00, 0x6a, 0x1f, 0x53, + 0xfc, 0x93, 0x01, 0x2e, 0x24, 0xdf, 0xe7, 0xb8, 0x0e, 0xf6, 0xa3, 0xe5, 0xc0, 0xdf, 0x75, 0x6a, + 0xf0, 0x92, 0xe8, 0x48, 0x6a, 0x6d, 0xbe, 0xa4, 0x1b, 0x09, 0xef, 0x83, 0x21, 0x2a, 0xdc, 0x2f, + 0x23, 0xe3, 0xd5, 0x93, 0x47, 0x46, 0x76, 0x1d, 0x45, 0x41, 0x95, 0x50, 0x13, 0x1c, 0x16, 0x1c, + 0x55, 0xab, 0x1c, 0xfb, 0xb6, 0xec, 0x4a, 0x8f, 0x8a, 0xe0, 0x58, 0x5e, 0x12, 0x34, 0xa4, 0xb8, + 0xc5, 0x7f, 0x18, 0x60, 0xb2, 0xed, 0x7b, 0x23, 0xf8, 0x3d, 0x03, 0x8c, 0x56, 0xb5, 0xe9, 0xc9, + 0x2d, 0xb6, 0x71, 0xfa, 0x6f, 0x9a, 0x34, 0xa5, 0xa2, 0x2a, 0xd1, 0x29, 0xa8, 0x05, 0x14, 0x6e, + 0x03, 0xb3, 0x9a, 0xf9, 0xb4, 0x2f, 0xf3, 0x58, 0x78, 0xb9, 0xd9, 0x28, 0x98, 0xcb, 0x5d, 0x64, + 0x50, 0xd7, 0xd1, 0xe5, 0x6f, 0x7d, 0xfc, 0xd9, 0xec, 0xb9, 0x4f, 0x3e, 0x9b, 0x3d, 0xf7, 0xe9, + 0x67, 0xb3, 0xe7, 0xde, 0x6d, 0xce, 0x1a, 0x1f, 0x37, 0x67, 0x8d, 0x4f, 0x9a, 0xb3, 0xc6, 0xa7, + 0xcd, 0x59, 0xe3, 0xaf, 0xcd, 0x59, 0xe3, 0x27, 0x7f, 0x9b, 0x3d, 0xf7, 0xc6, 0x8d, 0x93, 0x7e, + 0xd0, 0xfb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x41, 0x66, 0xfd, 0x82, 0x24, 0x2c, 0x00, 0x00, } func (m *ConversionRequest) Marshal() (dAtA []byte, err error) { @@ -2629,6 +2630,11 @@ func (m *ValidationRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x1a i -= len(m.Message) copy(dAtA[i:], m.Message) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -3338,6 +3344,8 @@ func (m *ValidationRule) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -3813,6 +3821,7 @@ func (this *ValidationRule) String() string { s := strings.Join([]string{`&ValidationRule{`, `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, `}`, }, "") return s @@ -8879,6 +8888,38 @@ func (m *ValidationRule) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MessageExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto index 9c6b728fa53..4632a83e59d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto @@ -107,12 +107,12 @@ message CustomResourceColumnDefinition { // CustomResourceConversion describes how to convert different versions of a CR. message CustomResourceConversion { // strategy specifies how custom resources are converted between versions. Allowed values are: - // - `None`: The converter only change the apiVersion and would not touch any other field in the custom resource. - // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information + // - `"None"`: The converter only change the apiVersion and would not touch any other field in the custom resource. + // - `"Webhook"`: API Server will call to an external webhook to do the conversion. Additional information // is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set. optional string strategy = 1; - // webhook describes how to call the conversion webhook. Required when `strategy` is set to `Webhook`. + // webhook describes how to call the conversion webhook. Required when `strategy` is set to `"Webhook"`. // +optional optional WebhookConversion webhook = 2; } @@ -231,7 +231,7 @@ message CustomResourceDefinitionSpec { // in the OpenAPI schema should be preserved when persisting to storage. // apiVersion, kind, metadata and known fields inside metadata are always preserved. // This field is deprecated in favor of setting `x-preserve-unknown-fields` to true in `spec.versions[*].schema.openAPIV3Schema`. - // See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details. + // See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning for details. // +optional optional bool preserveUnknownFields = 10; } @@ -665,6 +665,19 @@ message ValidationRule { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" optional string message = 2; + + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + optional string messageExpression = 3; } // WebhookClientConfig contains the information to make a TLS connection with the webhook. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go index 223601bc450..59ec0e372b8 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go @@ -66,7 +66,7 @@ type CustomResourceDefinitionSpec struct { // in the OpenAPI schema should be preserved when persisting to storage. // apiVersion, kind, metadata and known fields inside metadata are always preserved. // This field is deprecated in favor of setting `x-preserve-unknown-fields` to true in `spec.versions[*].schema.openAPIV3Schema`. - // See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details. + // See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning for details. // +optional PreserveUnknownFields bool `json:"preserveUnknownFields,omitempty" protobuf:"varint,10,opt,name=preserveUnknownFields"` } @@ -74,12 +74,12 @@ type CustomResourceDefinitionSpec struct { // CustomResourceConversion describes how to convert different versions of a CR. type CustomResourceConversion struct { // strategy specifies how custom resources are converted between versions. Allowed values are: - // - `None`: The converter only change the apiVersion and would not touch any other field in the custom resource. - // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information + // - `"None"`: The converter only change the apiVersion and would not touch any other field in the custom resource. + // - `"Webhook"`: API Server will call to an external webhook to do the conversion. Additional information // is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set. Strategy ConversionStrategyType `json:"strategy" protobuf:"bytes,1,name=strategy"` - // webhook describes how to call the conversion webhook. Required when `strategy` is set to `Webhook`. + // webhook describes how to call the conversion webhook. Required when `strategy` is set to `"Webhook"`. // +optional Webhook *WebhookConversion `json:"webhook,omitempty" protobuf:"bytes,2,opt,name=webhook"` } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go index 277fd7a124a..b348d0d19b1 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go @@ -235,12 +235,24 @@ type ValidationRule struct { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + MessageExpression string `json:"messageExpression,omitempty" protobuf:"bytes,3,opt,name=messageExpression"` } // JSON represents any valid JSON value. // These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil. type JSON struct { - Raw []byte `protobuf:"bytes,1,opt,name=raw"` + Raw []byte `json:"-" protobuf:"bytes,1,opt,name=raw"` } // OpenAPISchemaType is used by the kube-openapi generator when constructing diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go index 95a58529b11..cde5275ceff 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go @@ -1258,6 +1258,7 @@ func Convert_apiextensions_ServiceReference_To_v1_ServiceReference(in *apiextens func autoConvert_v1_ValidationRule_To_apiextensions_ValidationRule(in *ValidationRule, out *apiextensions.ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } @@ -1269,6 +1270,7 @@ func Convert_v1_ValidationRule_To_apiextensions_ValidationRule(in *ValidationRul func autoConvert_apiextensions_ValidationRule_To_v1_ValidationRule(in *apiextensions.ValidationRule, out *ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go index 6ab50066766..011bd72dc7d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go @@ -785,200 +785,202 @@ func init() { } var fileDescriptor_98a4cc6918394e53 = []byte{ - // 3079 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcf, 0x73, 0x23, 0x47, - 0xf5, 0xdf, 0x91, 0x2d, 0x5b, 0x6e, 0xdb, 0x6b, 0xbb, 0x77, 0xed, 0xcc, 0x3a, 0x1b, 0xcb, 0x56, - 0xbe, 0xd9, 0xaf, 0x93, 0x6c, 0xe4, 0xc4, 0x24, 0x24, 0xa4, 0x48, 0x51, 0x96, 0xed, 0x0d, 0x4e, - 0xd6, 0x3f, 0x68, 0xed, 0x26, 0x86, 0xfc, 0x6c, 0x6b, 0xda, 0xf2, 0xc4, 0xa3, 0x99, 0xd9, 0xe9, - 0x19, 0xd9, 0xae, 0x00, 0xc5, 0x8f, 0x4a, 0x41, 0x51, 0x40, 0x28, 0x92, 0x0b, 0x05, 0x1c, 0x02, - 0xc5, 0x85, 0x03, 0x1c, 0xe0, 0x06, 0x7f, 0x40, 0x8e, 0x29, 0x8a, 0x43, 0x0e, 0x94, 0x20, 0xe2, - 0xca, 0x91, 0x2a, 0xaa, 0x7c, 0xa2, 0xfa, 0xc7, 0xf4, 0xb4, 0x46, 0xd2, 0xee, 0x56, 0x2c, 0x65, - 0xb9, 0x69, 0xde, 0xaf, 0xcf, 0x9b, 0xd7, 0xaf, 0x5f, 0xbf, 0x7e, 0x23, 0xb0, 0x7f, 0xf8, 0x0c, - 0x2d, 0xda, 0xde, 0xd2, 0x61, 0xb4, 0x47, 0x02, 0x97, 0x84, 0x84, 0x2e, 0xd5, 0x89, 0x6b, 0x79, - 0xc1, 0x92, 0x64, 0x60, 0xdf, 0x26, 0xc7, 0x21, 0x71, 0xa9, 0xed, 0xb9, 0xf4, 0x31, 0xec, 0xdb, - 0x94, 0x04, 0x75, 0x12, 0x2c, 0xf9, 0x87, 0x55, 0xc6, 0xa3, 0xad, 0x02, 0x4b, 0xf5, 0x27, 0xf6, - 0x48, 0x88, 0x9f, 0x58, 0xaa, 0x12, 0x97, 0x04, 0x38, 0x24, 0x56, 0xd1, 0x0f, 0xbc, 0xd0, 0x83, - 0xcf, 0x09, 0x73, 0xc5, 0x16, 0xe9, 0x37, 0x94, 0xb9, 0xa2, 0x7f, 0x58, 0x65, 0x3c, 0xda, 0x2a, - 0x50, 0x94, 0xe6, 0x66, 0x1f, 0xab, 0xda, 0xe1, 0x41, 0xb4, 0x57, 0xac, 0x78, 0xb5, 0xa5, 0xaa, - 0x57, 0xf5, 0x96, 0xb8, 0xd5, 0xbd, 0x68, 0x9f, 0x3f, 0xf1, 0x07, 0xfe, 0x4b, 0xa0, 0xcd, 0x3e, - 0x99, 0x38, 0x5f, 0xc3, 0x95, 0x03, 0xdb, 0x25, 0xc1, 0x49, 0xe2, 0x71, 0x8d, 0x84, 0x78, 0xa9, - 0xde, 0xe6, 0xe3, 0xec, 0x52, 0x37, 0xad, 0x20, 0x72, 0x43, 0xbb, 0x46, 0xda, 0x14, 0x3e, 0x7f, - 0x27, 0x05, 0x5a, 0x39, 0x20, 0x35, 0x9c, 0xd6, 0x2b, 0x9c, 0x1a, 0x60, 0x6a, 0xd5, 0x73, 0xeb, - 0x24, 0x60, 0x6f, 0x89, 0xc8, 0xad, 0x88, 0xd0, 0x10, 0x96, 0xc0, 0x40, 0x64, 0x5b, 0xa6, 0x31, - 0x6f, 0x2c, 0x8e, 0x94, 0x1e, 0xff, 0xb0, 0x91, 0x3f, 0xd7, 0x6c, 0xe4, 0x07, 0x6e, 0x6e, 0xac, - 0x9d, 0x36, 0xf2, 0x0b, 0xdd, 0x90, 0xc2, 0x13, 0x9f, 0xd0, 0xe2, 0xcd, 0x8d, 0x35, 0xc4, 0x94, - 0xe1, 0xf3, 0x60, 0xca, 0x22, 0xd4, 0x0e, 0x88, 0xb5, 0xb2, 0xb3, 0xf1, 0x92, 0xb0, 0x6f, 0x66, - 0xb8, 0xc5, 0x4b, 0xd2, 0xe2, 0xd4, 0x5a, 0x5a, 0x00, 0xb5, 0xeb, 0xc0, 0x5d, 0x30, 0xec, 0xed, - 0xbd, 0x45, 0x2a, 0x21, 0x35, 0x07, 0xe6, 0x07, 0x16, 0x47, 0x97, 0x1f, 0x2b, 0x26, 0x2b, 0xa8, - 0x5c, 0xe0, 0xcb, 0x26, 0x5f, 0xb6, 0x88, 0xf0, 0xd1, 0x7a, 0xbc, 0x72, 0xa5, 0x09, 0x89, 0x36, - 0xbc, 0x2d, 0xac, 0xa0, 0xd8, 0x5c, 0xe1, 0xd7, 0x19, 0x00, 0xf5, 0x97, 0xa7, 0xbe, 0xe7, 0x52, - 0xd2, 0x93, 0xb7, 0xa7, 0x60, 0xb2, 0xc2, 0x2d, 0x87, 0xc4, 0x92, 0xb8, 0x66, 0xe6, 0xd3, 0x78, - 0x6f, 0x4a, 0xfc, 0xc9, 0xd5, 0x94, 0x39, 0xd4, 0x06, 0x00, 0x6f, 0x80, 0xa1, 0x80, 0xd0, 0xc8, - 0x09, 0xcd, 0x81, 0x79, 0x63, 0x71, 0x74, 0xf9, 0x6a, 0x57, 0x28, 0x9e, 0xdf, 0x2c, 0xf9, 0x8a, - 0xf5, 0x27, 0x8a, 0xe5, 0x10, 0x87, 0x11, 0x2d, 0x9d, 0x97, 0x48, 0x43, 0x88, 0xdb, 0x40, 0xd2, - 0x56, 0xe1, 0xfb, 0x19, 0x30, 0xa9, 0x47, 0xa9, 0x6e, 0x93, 0x23, 0x78, 0x04, 0x86, 0x03, 0x91, - 0x2c, 0x3c, 0x4e, 0xa3, 0xcb, 0x3b, 0xc5, 0x33, 0x6d, 0xab, 0x62, 0x5b, 0x12, 0x96, 0x46, 0xd9, - 0x9a, 0xc9, 0x07, 0x14, 0xa3, 0xc1, 0xb7, 0x41, 0x2e, 0x90, 0x0b, 0xc5, 0xb3, 0x69, 0x74, 0xf9, - 0x2b, 0x3d, 0x44, 0x16, 0x86, 0x4b, 0x63, 0xcd, 0x46, 0x3e, 0x17, 0x3f, 0x21, 0x05, 0x58, 0x78, - 0x2f, 0x03, 0xe6, 0x56, 0x23, 0x1a, 0x7a, 0x35, 0x44, 0xa8, 0x17, 0x05, 0x15, 0xb2, 0xea, 0x39, - 0x51, 0xcd, 0x5d, 0x23, 0xfb, 0xb6, 0x6b, 0x87, 0x2c, 0x5b, 0xe7, 0xc1, 0xa0, 0x8b, 0x6b, 0x44, - 0x66, 0xcf, 0x98, 0x8c, 0xe9, 0xe0, 0x16, 0xae, 0x11, 0xc4, 0x39, 0x4c, 0x82, 0x25, 0x8b, 0xdc, - 0x0b, 0x4a, 0xe2, 0xc6, 0x89, 0x4f, 0x10, 0xe7, 0xc0, 0x2b, 0x60, 0x68, 0xdf, 0x0b, 0x6a, 0x58, - 0xac, 0xe3, 0x48, 0xb2, 0x32, 0xd7, 0x38, 0x15, 0x49, 0x2e, 0x7c, 0x0a, 0x8c, 0x5a, 0x84, 0x56, - 0x02, 0xdb, 0x67, 0xd0, 0xe6, 0x20, 0x17, 0xbe, 0x20, 0x85, 0x47, 0xd7, 0x12, 0x16, 0xd2, 0xe5, - 0xe0, 0x55, 0x90, 0xf3, 0x03, 0xdb, 0x0b, 0xec, 0xf0, 0xc4, 0xcc, 0xce, 0x1b, 0x8b, 0xd9, 0xd2, - 0xa4, 0xd4, 0xc9, 0xed, 0x48, 0x3a, 0x52, 0x12, 0x70, 0x1e, 0xe4, 0x5e, 0x28, 0x6f, 0x6f, 0xed, - 0xe0, 0xf0, 0xc0, 0x1c, 0xe2, 0x08, 0x83, 0x4c, 0x1a, 0x29, 0x6a, 0xe1, 0x6f, 0x19, 0x60, 0xa6, - 0xa3, 0x12, 0x87, 0x14, 0x5e, 0x03, 0x39, 0x1a, 0xb2, 0x8a, 0x53, 0x3d, 0x91, 0x31, 0x79, 0x24, - 0x06, 0x2b, 0x4b, 0xfa, 0x69, 0x23, 0x3f, 0x93, 0x68, 0xc4, 0x54, 0x1e, 0x0f, 0xa5, 0x0b, 0x7f, - 0x69, 0x80, 0x0b, 0x47, 0x64, 0xef, 0xc0, 0xf3, 0x0e, 0x57, 0x1d, 0x9b, 0xb8, 0xe1, 0xaa, 0xe7, - 0xee, 0xdb, 0x55, 0x99, 0x03, 0xe8, 0x8c, 0x39, 0xf0, 0x72, 0xbb, 0xe5, 0xd2, 0x7d, 0xcd, 0x46, - 0xfe, 0x42, 0x07, 0x06, 0xea, 0xe4, 0x07, 0xdc, 0x05, 0x66, 0x25, 0xb5, 0x49, 0x64, 0x01, 0x13, - 0x65, 0x6b, 0xa4, 0x74, 0xb9, 0xd9, 0xc8, 0x9b, 0xab, 0x5d, 0x64, 0x50, 0x57, 0xed, 0xc2, 0x77, - 0x07, 0xd2, 0xe1, 0xd5, 0xd2, 0xed, 0x4d, 0x90, 0x63, 0xdb, 0xd8, 0xc2, 0x21, 0x96, 0x1b, 0xf1, - 0xf1, 0xbb, 0xdb, 0xf4, 0xa2, 0x66, 0x6c, 0x92, 0x10, 0x97, 0xa0, 0x5c, 0x10, 0x90, 0xd0, 0x90, - 0xb2, 0x0a, 0xbf, 0x01, 0x06, 0xa9, 0x4f, 0x2a, 0x32, 0xd0, 0xaf, 0x9c, 0x75, 0xb3, 0x75, 0x79, - 0x91, 0xb2, 0x4f, 0x2a, 0xc9, 0x5e, 0x60, 0x4f, 0x88, 0xc3, 0xc2, 0x77, 0x0c, 0x30, 0x44, 0x79, - 0x81, 0x92, 0x45, 0xed, 0xb5, 0x7e, 0x79, 0x90, 0xaa, 0x82, 0xe2, 0x19, 0x49, 0xf0, 0xc2, 0xbf, - 0x33, 0x60, 0xa1, 0x9b, 0xea, 0xaa, 0xe7, 0x5a, 0x62, 0x39, 0x36, 0xe4, 0xde, 0x16, 0x99, 0xfe, - 0x94, 0xbe, 0xb7, 0x4f, 0x1b, 0xf9, 0x87, 0xee, 0x68, 0x40, 0x2b, 0x02, 0x5f, 0x50, 0xef, 0x2d, - 0x0a, 0xc5, 0x42, 0xab, 0x63, 0xa7, 0x8d, 0xfc, 0x84, 0x52, 0x6b, 0xf5, 0x15, 0xd6, 0x01, 0x74, - 0x30, 0x0d, 0x6f, 0x04, 0xd8, 0xa5, 0xc2, 0xac, 0x5d, 0x23, 0x32, 0x7c, 0x8f, 0xdc, 0x5d, 0x7a, - 0x30, 0x8d, 0xd2, 0xac, 0x84, 0x84, 0xd7, 0xdb, 0xac, 0xa1, 0x0e, 0x08, 0xac, 0x6e, 0x05, 0x04, - 0x53, 0x55, 0x8a, 0xb4, 0x13, 0x85, 0x51, 0x91, 0xe4, 0xc2, 0x87, 0xc1, 0x70, 0x8d, 0x50, 0x8a, - 0xab, 0x84, 0xd7, 0x9f, 0x91, 0xe4, 0x88, 0xde, 0x14, 0x64, 0x14, 0xf3, 0x59, 0x7f, 0x72, 0xb9, - 0x5b, 0xd4, 0xae, 0xdb, 0x34, 0x84, 0xaf, 0xb6, 0x6d, 0x80, 0xe2, 0xdd, 0xbd, 0x21, 0xd3, 0xe6, - 0xe9, 0xaf, 0x8a, 0x5f, 0x4c, 0xd1, 0x92, 0xff, 0xeb, 0x20, 0x6b, 0x87, 0xa4, 0x16, 0x9f, 0xdd, - 0x2f, 0xf7, 0x29, 0xf7, 0x4a, 0xe3, 0xd2, 0x87, 0xec, 0x06, 0x43, 0x43, 0x02, 0xb4, 0xf0, 0x9b, - 0x0c, 0x78, 0xa0, 0x9b, 0x0a, 0x3b, 0x50, 0x28, 0x8b, 0xb8, 0xef, 0x44, 0x01, 0x76, 0x64, 0xc6, - 0xa9, 0x88, 0xef, 0x70, 0x2a, 0x92, 0x5c, 0x56, 0xf2, 0xa9, 0xed, 0x56, 0x23, 0x07, 0x07, 0x32, - 0x9d, 0xd4, 0x5b, 0x97, 0x25, 0x1d, 0x29, 0x09, 0x58, 0x04, 0x80, 0x1e, 0x78, 0x41, 0xc8, 0x31, - 0x64, 0xf5, 0x3a, 0xcf, 0x0a, 0x44, 0x59, 0x51, 0x91, 0x26, 0xc1, 0x4e, 0xb4, 0x43, 0xdb, 0xb5, - 0xe4, 0xaa, 0xab, 0x5d, 0xfc, 0xa2, 0xed, 0x5a, 0x88, 0x73, 0x18, 0xbe, 0x63, 0xd3, 0x90, 0x51, - 0xe4, 0x92, 0xb7, 0x44, 0x9d, 0x4b, 0x2a, 0x09, 0x86, 0x5f, 0x61, 0x55, 0xdf, 0x0b, 0x6c, 0x42, - 0xcd, 0xa1, 0x04, 0x7f, 0x55, 0x51, 0x91, 0x26, 0x51, 0xf8, 0x57, 0xae, 0x7b, 0x92, 0xb0, 0x52, - 0x02, 0x1f, 0x04, 0xd9, 0x6a, 0xe0, 0x45, 0xbe, 0x8c, 0x92, 0x8a, 0xf6, 0xf3, 0x8c, 0x88, 0x04, - 0x8f, 0x65, 0x65, 0xbd, 0xa5, 0x4d, 0x55, 0x59, 0x19, 0x37, 0xa7, 0x31, 0x1f, 0x7e, 0xdb, 0x00, - 0x59, 0x57, 0x06, 0x87, 0xa5, 0xdc, 0xab, 0x7d, 0xca, 0x0b, 0x1e, 0xde, 0xc4, 0x5d, 0x11, 0x79, - 0x81, 0x0c, 0x9f, 0x04, 0x59, 0x5a, 0xf1, 0x7c, 0x22, 0xa3, 0x3e, 0x17, 0x0b, 0x95, 0x19, 0xf1, - 0xb4, 0x91, 0x1f, 0x8f, 0xcd, 0x71, 0x02, 0x12, 0xc2, 0xf0, 0x7b, 0x06, 0x00, 0x75, 0xec, 0xd8, - 0x16, 0xe6, 0x2d, 0x43, 0x96, 0xbb, 0xdf, 0xdb, 0xb4, 0x7e, 0x49, 0x99, 0x17, 0x8b, 0x96, 0x3c, - 0x23, 0x0d, 0x1a, 0xbe, 0x6b, 0x80, 0x31, 0x1a, 0xed, 0x05, 0x52, 0x8b, 0xf2, 0xe6, 0x62, 0x74, - 0xf9, 0xab, 0x3d, 0xf5, 0xa5, 0xac, 0x01, 0x94, 0x26, 0x9b, 0x8d, 0xfc, 0x98, 0x4e, 0x41, 0x2d, - 0x0e, 0xc0, 0x1f, 0x1a, 0x20, 0x57, 0x8f, 0xcf, 0xec, 0x61, 0xbe, 0xe1, 0x5f, 0xef, 0xd3, 0xc2, - 0xca, 0x8c, 0x4a, 0x76, 0x81, 0xea, 0x03, 0x94, 0x07, 0xf0, 0x4f, 0x06, 0x30, 0xb1, 0x25, 0x0a, - 0x3c, 0x76, 0x76, 0x02, 0xdb, 0x0d, 0x49, 0x20, 0xfa, 0x4d, 0x6a, 0xe6, 0xb8, 0x7b, 0xbd, 0x3d, - 0x0b, 0xd3, 0xbd, 0x6c, 0x69, 0x5e, 0x7a, 0x67, 0xae, 0x74, 0x71, 0x03, 0x75, 0x75, 0x90, 0x27, - 0x5a, 0xd2, 0xd2, 0x98, 0x23, 0x7d, 0x48, 0xb4, 0xa4, 0x97, 0x92, 0xd5, 0x21, 0xe9, 0xa0, 0x34, - 0x68, 0xb8, 0x0d, 0xa6, 0xfd, 0x80, 0x70, 0x80, 0x9b, 0xee, 0xa1, 0xeb, 0x1d, 0xb9, 0xd7, 0x6c, - 0xe2, 0x58, 0xd4, 0x04, 0xf3, 0xc6, 0x62, 0xae, 0x74, 0xa9, 0xd9, 0xc8, 0x4f, 0xef, 0x74, 0x12, - 0x40, 0x9d, 0xf5, 0x0a, 0xef, 0x0e, 0xa4, 0x6f, 0x01, 0xe9, 0x2e, 0x02, 0xbe, 0x2f, 0xde, 0x5e, - 0xc4, 0x86, 0x9a, 0x06, 0x5f, 0xad, 0x37, 0xfb, 0x94, 0x4c, 0xaa, 0x0d, 0x48, 0x3a, 0x39, 0x45, - 0xa2, 0x48, 0xf3, 0x03, 0xfe, 0xcc, 0x00, 0xe3, 0xb8, 0x52, 0x21, 0x7e, 0x48, 0x2c, 0x51, 0xdc, - 0x33, 0x9f, 0x41, 0xfd, 0x9a, 0x96, 0x5e, 0x8d, 0xaf, 0xe8, 0xd0, 0xa8, 0xd5, 0x13, 0xf8, 0x2c, - 0x38, 0x4f, 0x43, 0x2f, 0x20, 0x56, 0xaa, 0x6d, 0x86, 0xcd, 0x46, 0xfe, 0x7c, 0xb9, 0x85, 0x83, - 0x52, 0x92, 0x85, 0xbf, 0x67, 0x41, 0xfe, 0x0e, 0x5b, 0xed, 0x2e, 0x2e, 0x66, 0x57, 0xc0, 0x10, - 0x7f, 0x5d, 0x8b, 0x47, 0x25, 0xa7, 0xb5, 0x82, 0x9c, 0x8a, 0x24, 0x97, 0x1d, 0x14, 0x0c, 0x9f, - 0xb5, 0x2f, 0x03, 0x5c, 0x50, 0x1d, 0x14, 0x65, 0x41, 0x46, 0x31, 0x1f, 0x2e, 0x03, 0x60, 0x11, - 0x3f, 0x20, 0xec, 0xb0, 0xb2, 0xcc, 0x61, 0x2e, 0xad, 0x16, 0x69, 0x4d, 0x71, 0x90, 0x26, 0x05, - 0xaf, 0x01, 0x18, 0x3f, 0xd9, 0x9e, 0xfb, 0x32, 0x0e, 0x5c, 0xdb, 0xad, 0x9a, 0x39, 0xee, 0xf6, - 0x0c, 0xeb, 0xc6, 0xd6, 0xda, 0xb8, 0xa8, 0x83, 0x06, 0x7c, 0x1b, 0x0c, 0x89, 0xa1, 0x0f, 0x3f, - 0x21, 0xfa, 0x58, 0xe5, 0x01, 0x8f, 0x11, 0x87, 0x42, 0x12, 0xb2, 0xbd, 0xba, 0x67, 0xef, 0x75, - 0x75, 0xbf, 0x6d, 0x39, 0x1d, 0xfa, 0x1f, 0x2f, 0xa7, 0x85, 0xff, 0x18, 0xe9, 0x9a, 0xa3, 0xbd, - 0x6a, 0xb9, 0x82, 0x1d, 0x02, 0xd7, 0xc0, 0x24, 0xbb, 0x31, 0x21, 0xe2, 0x3b, 0x76, 0x05, 0x53, - 0x7e, 0x61, 0x17, 0xc9, 0xae, 0x66, 0x48, 0xe5, 0x14, 0x1f, 0xb5, 0x69, 0xc0, 0x17, 0x00, 0x14, - 0xb7, 0x88, 0x16, 0x3b, 0xa2, 0x21, 0x52, 0xf7, 0x81, 0x72, 0x9b, 0x04, 0xea, 0xa0, 0x05, 0x57, - 0xc1, 0x94, 0x83, 0xf7, 0x88, 0x53, 0x26, 0x0e, 0xa9, 0x84, 0x5e, 0xc0, 0x4d, 0x89, 0x91, 0xc6, - 0x74, 0xb3, 0x91, 0x9f, 0xba, 0x9e, 0x66, 0xa2, 0x76, 0xf9, 0xc2, 0x42, 0x7a, 0x6b, 0xeb, 0x2f, - 0x2e, 0xee, 0x66, 0x1f, 0x64, 0xc0, 0x6c, 0xf7, 0xcc, 0x80, 0xdf, 0x49, 0xae, 0x90, 0xe2, 0x86, - 0xf0, 0x7a, 0xbf, 0xb2, 0x50, 0xde, 0x21, 0x41, 0xfb, 0xfd, 0x11, 0x7e, 0x93, 0xb5, 0x6b, 0xd8, - 0x89, 0x87, 0x56, 0xaf, 0xf5, 0xcd, 0x05, 0x06, 0x52, 0x1a, 0x11, 0x9d, 0x20, 0x76, 0x78, 0xe3, - 0x87, 0x1d, 0x52, 0xf8, 0xad, 0x91, 0x9e, 0x22, 0x24, 0x3b, 0x18, 0xfe, 0xc8, 0x00, 0x13, 0x9e, - 0x4f, 0xdc, 0x95, 0x9d, 0x8d, 0x97, 0x3e, 0x27, 0x76, 0xb2, 0x0c, 0xd5, 0xd6, 0x19, 0xfd, 0x7c, - 0xa1, 0xbc, 0xbd, 0x25, 0x0c, 0xee, 0x04, 0x9e, 0x4f, 0x4b, 0x17, 0x9a, 0x8d, 0xfc, 0xc4, 0x76, - 0x2b, 0x14, 0x4a, 0x63, 0x17, 0x6a, 0x60, 0x7a, 0xfd, 0x38, 0x24, 0x81, 0x8b, 0x9d, 0x35, 0xaf, - 0x12, 0xd5, 0x88, 0x1b, 0x0a, 0x47, 0x53, 0x13, 0x2f, 0xe3, 0x2e, 0x27, 0x5e, 0x0f, 0x80, 0x81, - 0x28, 0x70, 0x64, 0x16, 0x8f, 0xaa, 0x89, 0x2e, 0xba, 0x8e, 0x18, 0xbd, 0xb0, 0x00, 0x06, 0x99, - 0x9f, 0xf0, 0x12, 0x18, 0x08, 0xf0, 0x11, 0xb7, 0x3a, 0x56, 0x1a, 0x66, 0x22, 0x08, 0x1f, 0x21, - 0x46, 0x2b, 0xfc, 0x75, 0x01, 0x4c, 0xa4, 0xde, 0x05, 0xce, 0x82, 0x8c, 0x1a, 0x13, 0x03, 0x69, - 0x34, 0xb3, 0xb1, 0x86, 0x32, 0xb6, 0x05, 0x9f, 0x56, 0xc5, 0x57, 0x80, 0xe6, 0xd5, 0x59, 0xc2, - 0xa9, 0xac, 0x3f, 0x4f, 0xcc, 0x31, 0x47, 0xe2, 0xc2, 0xc9, 0x7c, 0x20, 0xfb, 0x72, 0x97, 0x08, - 0x1f, 0xc8, 0x3e, 0x62, 0xb4, 0x4f, 0x3b, 0xee, 0x8b, 0xe7, 0x8d, 0xd9, 0xbb, 0x98, 0x37, 0x0e, - 0xdd, 0x76, 0xde, 0xf8, 0x20, 0xc8, 0x86, 0x76, 0xe8, 0x10, 0x7e, 0x90, 0x69, 0xd7, 0xa8, 0x1b, - 0x8c, 0x88, 0x04, 0x0f, 0xbe, 0x05, 0x86, 0x2d, 0xb2, 0x8f, 0x23, 0x27, 0xe4, 0x67, 0xd6, 0xe8, - 0xf2, 0x6a, 0x0f, 0x52, 0x48, 0x0c, 0x83, 0xd7, 0x84, 0x5d, 0x14, 0x03, 0xc0, 0x87, 0xc0, 0x70, - 0x0d, 0x1f, 0xdb, 0xb5, 0xa8, 0xc6, 0x1b, 0x4c, 0x43, 0x88, 0x6d, 0x0a, 0x12, 0x8a, 0x79, 0xac, - 0x32, 0x92, 0xe3, 0x8a, 0x13, 0x51, 0xbb, 0x4e, 0x24, 0x53, 0x36, 0x7f, 0xaa, 0x32, 0xae, 0xa7, - 0xf8, 0xa8, 0x4d, 0x83, 0x83, 0xd9, 0x2e, 0x57, 0x1e, 0xd5, 0xc0, 0x04, 0x09, 0xc5, 0xbc, 0x56, - 0x30, 0x29, 0x3f, 0xd6, 0x0d, 0x4c, 0x2a, 0xb7, 0x69, 0xc0, 0x47, 0xc1, 0x48, 0x0d, 0x1f, 0x5f, - 0x27, 0x6e, 0x35, 0x3c, 0x30, 0xc7, 0xe7, 0x8d, 0xc5, 0x81, 0xd2, 0x78, 0xb3, 0x91, 0x1f, 0xd9, - 0x8c, 0x89, 0x28, 0xe1, 0x73, 0x61, 0xdb, 0x95, 0xc2, 0xe7, 0x35, 0xe1, 0x98, 0x88, 0x12, 0x3e, - 0xeb, 0x5e, 0x7c, 0x1c, 0xb2, 0xcd, 0x65, 0x4e, 0xb4, 0x5e, 0x73, 0x77, 0x04, 0x19, 0xc5, 0x7c, - 0xb8, 0x08, 0x72, 0x35, 0x7c, 0xcc, 0x47, 0x12, 0xe6, 0x24, 0x37, 0xcb, 0x07, 0xe3, 0x9b, 0x92, - 0x86, 0x14, 0x97, 0x4b, 0xda, 0xae, 0x90, 0x9c, 0xd2, 0x24, 0x25, 0x0d, 0x29, 0x2e, 0x4b, 0xe2, - 0xc8, 0xb5, 0x6f, 0x45, 0x44, 0x08, 0x43, 0x1e, 0x19, 0x95, 0xc4, 0x37, 0x13, 0x16, 0xd2, 0xe5, - 0x60, 0x11, 0x80, 0x5a, 0xe4, 0x84, 0xb6, 0xef, 0x90, 0xed, 0x7d, 0xf3, 0x02, 0x8f, 0x3f, 0x6f, - 0xfa, 0x37, 0x15, 0x15, 0x69, 0x12, 0x90, 0x80, 0x41, 0xe2, 0x46, 0x35, 0xf3, 0x22, 0x3f, 0xd8, - 0x7b, 0x92, 0x82, 0x6a, 0xe7, 0xac, 0xbb, 0x51, 0x0d, 0x71, 0xf3, 0xf0, 0x69, 0x30, 0x5e, 0xc3, - 0xc7, 0xac, 0x1c, 0x90, 0x20, 0xb4, 0x09, 0x35, 0xa7, 0xf9, 0xcb, 0x4f, 0xb1, 0x6e, 0x77, 0x53, - 0x67, 0xa0, 0x56, 0x39, 0xae, 0x68, 0xbb, 0x9a, 0xe2, 0x8c, 0xa6, 0xa8, 0x33, 0x50, 0xab, 0x1c, - 0x8b, 0x74, 0x40, 0x6e, 0x45, 0x76, 0x40, 0x2c, 0xf3, 0x3e, 0xde, 0x20, 0xcb, 0x8f, 0x15, 0x82, - 0x86, 0x14, 0x17, 0xd6, 0xe3, 0xd9, 0x95, 0xc9, 0xb7, 0xe1, 0xcd, 0xde, 0x56, 0xf2, 0xed, 0x60, - 0x25, 0x08, 0xf0, 0x89, 0x38, 0x69, 0xf4, 0xa9, 0x15, 0xa4, 0x20, 0x8b, 0x1d, 0x67, 0x7b, 0xdf, - 0xbc, 0xc4, 0x63, 0xdf, 0xeb, 0x13, 0x44, 0x55, 0x9d, 0x15, 0x06, 0x82, 0x04, 0x16, 0x03, 0xf5, - 0x5c, 0x96, 0x1a, 0xb3, 0xfd, 0x05, 0xdd, 0x66, 0x20, 0x48, 0x60, 0xf1, 0x37, 0x75, 0x4f, 0xb6, - 0xf7, 0xcd, 0xfb, 0xfb, 0xfc, 0xa6, 0x0c, 0x04, 0x09, 0x2c, 0x68, 0x83, 0x01, 0xd7, 0x0b, 0xcd, - 0xcb, 0x7d, 0x39, 0x9e, 0xf9, 0x81, 0xb3, 0xe5, 0x85, 0x88, 0x61, 0xc0, 0x9f, 0x1a, 0x00, 0xf8, - 0x49, 0x8a, 0x3e, 0xd0, 0x93, 0x91, 0x48, 0x0a, 0xb2, 0x98, 0xe4, 0xf6, 0xba, 0x1b, 0x06, 0x27, - 0xc9, 0xf5, 0x48, 0xdb, 0x03, 0x9a, 0x17, 0xf0, 0x57, 0x06, 0xb8, 0xa8, 0xb7, 0xc9, 0xca, 0xbd, - 0x39, 0x1e, 0x91, 0x1b, 0xbd, 0x4e, 0xf3, 0x92, 0xe7, 0x39, 0x25, 0xb3, 0xd9, 0xc8, 0x5f, 0x5c, - 0xe9, 0x80, 0x8a, 0x3a, 0xfa, 0x02, 0x7f, 0x67, 0x80, 0x29, 0x59, 0x45, 0x35, 0x0f, 0xf3, 0x3c, - 0x80, 0xa4, 0xd7, 0x01, 0x4c, 0xe3, 0x88, 0x38, 0xaa, 0x8f, 0xec, 0x6d, 0x7c, 0xd4, 0xee, 0x1a, - 0xfc, 0xa3, 0x01, 0xc6, 0x2c, 0xe2, 0x13, 0xd7, 0x22, 0x6e, 0x85, 0xf9, 0x3a, 0xdf, 0x93, 0x91, - 0x45, 0xda, 0xd7, 0x35, 0x0d, 0x42, 0xb8, 0x59, 0x94, 0x6e, 0x8e, 0xe9, 0xac, 0xd3, 0x46, 0x7e, - 0x26, 0x51, 0xd5, 0x39, 0xa8, 0xc5, 0x4b, 0xf8, 0x9e, 0x01, 0x26, 0x92, 0x05, 0x10, 0x47, 0xca, - 0x42, 0x1f, 0xf3, 0x80, 0xb7, 0xaf, 0x2b, 0xad, 0x80, 0x28, 0xed, 0x01, 0xfc, 0xbd, 0xc1, 0x3a, - 0xb5, 0xf8, 0xde, 0x47, 0xcd, 0x02, 0x8f, 0xe5, 0x1b, 0x3d, 0x8f, 0xa5, 0x42, 0x10, 0xa1, 0xbc, - 0x9a, 0xb4, 0x82, 0x8a, 0x73, 0xda, 0xc8, 0x4f, 0xeb, 0x91, 0x54, 0x0c, 0xa4, 0x7b, 0x08, 0x7f, - 0x60, 0x80, 0x31, 0x92, 0x74, 0xdc, 0xd4, 0x7c, 0xb0, 0x27, 0x41, 0xec, 0xd8, 0xc4, 0x8b, 0x9b, - 0xba, 0xc6, 0xa2, 0xa8, 0x05, 0x9b, 0x75, 0x90, 0xe4, 0x18, 0xd7, 0x7c, 0x87, 0x98, 0xff, 0xd7, - 0xe3, 0x0e, 0x72, 0x5d, 0xd8, 0x45, 0x31, 0x00, 0xbc, 0x0a, 0x72, 0x6e, 0xe4, 0x38, 0x78, 0xcf, - 0x21, 0xe6, 0x43, 0xbc, 0x17, 0x51, 0x23, 0xd9, 0x2d, 0x49, 0x47, 0x4a, 0x02, 0xee, 0x83, 0xf9, - 0xe3, 0x17, 0xd5, 0xdf, 0x93, 0x3a, 0x0e, 0x0d, 0xcd, 0x2b, 0xdc, 0xca, 0x6c, 0xb3, 0x91, 0x9f, - 0xd9, 0xed, 0x3c, 0x56, 0xbc, 0xa3, 0x0d, 0xf8, 0x0a, 0xb8, 0x5f, 0x93, 0x59, 0xaf, 0xed, 0x11, - 0xcb, 0x22, 0x56, 0x7c, 0x71, 0x33, 0xff, 0x5f, 0x0c, 0x2e, 0xe3, 0x0d, 0xbe, 0x9b, 0x16, 0x40, - 0xb7, 0xd3, 0x86, 0xd7, 0xc1, 0x8c, 0xc6, 0xde, 0x70, 0xc3, 0xed, 0xa0, 0x1c, 0x06, 0xb6, 0x5b, - 0x35, 0x17, 0xb9, 0xdd, 0x8b, 0xf1, 0x8e, 0xdc, 0xd5, 0x78, 0xa8, 0x8b, 0x0e, 0xfc, 0x72, 0x8b, - 0x35, 0xfe, 0x09, 0x0d, 0xfb, 0x2f, 0x92, 0x13, 0x6a, 0x3e, 0xcc, 0xbb, 0x13, 0xbe, 0xd8, 0xbb, - 0x1a, 0x1d, 0x75, 0x91, 0x87, 0x5f, 0x02, 0x17, 0x52, 0x1c, 0x76, 0x45, 0x31, 0x1f, 0x11, 0x77, - 0x0d, 0xd6, 0xcf, 0xee, 0xc6, 0x44, 0xd4, 0x49, 0x12, 0x7e, 0x11, 0x40, 0x8d, 0xbc, 0x89, 0x7d, - 0xae, 0xff, 0xa8, 0xb8, 0xf6, 0xb0, 0x15, 0xdd, 0x95, 0x34, 0xd4, 0x41, 0x0e, 0xfe, 0xdc, 0x68, - 0x79, 0x93, 0xe4, 0x76, 0x4c, 0xcd, 0xab, 0x7c, 0xff, 0x6e, 0x9e, 0x31, 0x0b, 0xb5, 0xef, 0x20, - 0x91, 0x43, 0xb4, 0x30, 0x6b, 0x50, 0xa8, 0x8b, 0x0b, 0xb3, 0xec, 0x86, 0x9e, 0xaa, 0xf0, 0x70, - 0x12, 0x0c, 0x1c, 0x12, 0xf9, 0xaf, 0x0a, 0xc4, 0x7e, 0x42, 0x0b, 0x64, 0xeb, 0xd8, 0x89, 0xe2, - 0x21, 0x43, 0x8f, 0xbb, 0x03, 0x24, 0x8c, 0x3f, 0x9b, 0x79, 0xc6, 0x98, 0x7d, 0xdf, 0x00, 0x33, - 0x9d, 0x0f, 0x9e, 0x7b, 0xea, 0xd6, 0x2f, 0x0c, 0x30, 0xd5, 0x76, 0xc6, 0x74, 0xf0, 0xe8, 0x56, - 0xab, 0x47, 0xaf, 0xf4, 0xfa, 0xb0, 0x10, 0x9b, 0x83, 0x77, 0xc8, 0xba, 0x7b, 0x3f, 0x36, 0xc0, - 0x64, 0xba, 0x6c, 0xdf, 0xcb, 0x78, 0x15, 0xde, 0xcf, 0x80, 0x99, 0xce, 0x8d, 0x3d, 0x0c, 0xd4, - 0x04, 0xa3, 0x3f, 0x93, 0xa0, 0x4e, 0x53, 0xe3, 0x77, 0x0c, 0x30, 0xfa, 0x96, 0x92, 0x8b, 0xbf, - 0xba, 0xf7, 0x7c, 0x06, 0x15, 0x9f, 0x93, 0x09, 0x83, 0x22, 0x1d, 0xb7, 0xf0, 0x07, 0x03, 0x4c, - 0x77, 0x6c, 0x00, 0xe0, 0x15, 0x30, 0x84, 0x1d, 0xc7, 0x3b, 0x12, 0xa3, 0x44, 0xed, 0x1b, 0xc1, - 0x0a, 0xa7, 0x22, 0xc9, 0xd5, 0xa2, 0x97, 0xf9, 0xac, 0xa2, 0x57, 0xf8, 0xb3, 0x01, 0x2e, 0xdf, - 0x2e, 0x13, 0xef, 0xc9, 0x92, 0x2e, 0x82, 0x9c, 0x6c, 0xde, 0x4f, 0xf8, 0x72, 0xca, 0x52, 0x2c, - 0x8b, 0x06, 0xff, 0xa3, 0x99, 0xf8, 0x55, 0xf8, 0xc0, 0x00, 0x93, 0x65, 0x12, 0xd4, 0xed, 0x0a, - 0x41, 0x64, 0x9f, 0x04, 0xc4, 0xad, 0x10, 0xb8, 0x04, 0x46, 0xf8, 0xe7, 0x6e, 0x1f, 0x57, 0xe2, - 0x4f, 0x37, 0x53, 0x32, 0xe4, 0x23, 0x5b, 0x31, 0x03, 0x25, 0x32, 0xea, 0x33, 0x4f, 0xa6, 0xeb, - 0x67, 0x9e, 0xcb, 0x60, 0xd0, 0x4f, 0x06, 0xd1, 0x39, 0xc6, 0xe5, 0xb3, 0x67, 0x4e, 0xe5, 0x5c, - 0x2f, 0x08, 0xf9, 0x74, 0x2d, 0x2b, 0xb9, 0x5e, 0x10, 0x22, 0x4e, 0x2d, 0xbc, 0x06, 0xce, 0xb7, - 0x96, 0x71, 0x86, 0x17, 0x44, 0x4e, 0xdb, 0x67, 0x25, 0xc6, 0x43, 0x9c, 0xa3, 0xff, 0xdb, 0x25, - 0x73, 0x87, 0x7f, 0xbb, 0xfc, 0xc5, 0x00, 0x9d, 0xfe, 0x71, 0x06, 0x2f, 0x89, 0xf9, 0xa5, 0x36, - 0x14, 0x8c, 0x67, 0x97, 0xb0, 0x0e, 0x86, 0xa9, 0x08, 0x9a, 0x5c, 0xd4, 0xed, 0x33, 0x2e, 0x6a, - 0x7a, 0x09, 0x44, 0xe3, 0x14, 0x53, 0x63, 0x30, 0xb6, 0xae, 0x15, 0x5c, 0x8a, 0x5c, 0x4b, 0x8e, - 0xb4, 0xc7, 0xc4, 0xba, 0xae, 0xae, 0x08, 0x1a, 0x52, 0xdc, 0x52, 0xe5, 0xc3, 0x4f, 0xe6, 0xce, - 0x7d, 0xf4, 0xc9, 0xdc, 0xb9, 0x8f, 0x3f, 0x99, 0x3b, 0xf7, 0xad, 0xe6, 0x9c, 0xf1, 0x61, 0x73, - 0xce, 0xf8, 0xa8, 0x39, 0x67, 0x7c, 0xdc, 0x9c, 0x33, 0xfe, 0xd1, 0x9c, 0x33, 0x7e, 0xf2, 0xcf, - 0xb9, 0x73, 0x5f, 0x7b, 0xee, 0x4c, 0x7f, 0xf2, 0xfe, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, - 0x02, 0xc9, 0x93, 0x3d, 0x2e, 0x00, 0x00, + // 3105 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0x23, 0x47, + 0xd9, 0xdf, 0x91, 0x2c, 0x5b, 0x6e, 0x7b, 0x77, 0xed, 0xde, 0xb5, 0x33, 0xeb, 0x6c, 0x2c, 0x5b, + 0x79, 0xb3, 0xaf, 0x93, 0x6c, 0xe4, 0xc4, 0x6f, 0xf2, 0x26, 0xa4, 0x48, 0x51, 0x96, 0xed, 0x0d, + 0x4e, 0xd6, 0x1f, 0xb4, 0x76, 0x13, 0x43, 0x3e, 0xc7, 0x9a, 0xb6, 0x3c, 0xf1, 0x68, 0x66, 0xb6, + 0x7b, 0x46, 0xb6, 0x2b, 0x40, 0xf1, 0x51, 0x29, 0x28, 0x0a, 0x08, 0x45, 0x72, 0xa1, 0x80, 0x43, + 0xa0, 0xe0, 0xc0, 0x01, 0x0e, 0x70, 0x83, 0x3f, 0x20, 0xc7, 0x14, 0xc5, 0x21, 0x07, 0x4a, 0x10, + 0x71, 0xe5, 0x48, 0x15, 0x55, 0x3e, 0x51, 0xfd, 0x31, 0x3d, 0xad, 0x91, 0xb4, 0xbb, 0x15, 0x4b, + 0x59, 0x6e, 0xd2, 0xf3, 0xf5, 0x7b, 0xe6, 0xe9, 0xa7, 0x9f, 0x7e, 0xfa, 0x99, 0x01, 0x7b, 0x07, + 0xcf, 0xd0, 0x92, 0xe3, 0x2f, 0x1e, 0x44, 0xbb, 0x98, 0x78, 0x38, 0xc4, 0x74, 0xb1, 0x81, 0x3d, + 0xdb, 0x27, 0x8b, 0x92, 0x61, 0x05, 0x0e, 0x3e, 0x0a, 0xb1, 0x47, 0x1d, 0xdf, 0xa3, 0x8f, 0x59, + 0x81, 0x43, 0x31, 0x69, 0x60, 0xb2, 0x18, 0x1c, 0xd4, 0x18, 0x8f, 0xb6, 0x0b, 0x2c, 0x36, 0x9e, + 0xd8, 0xc5, 0xa1, 0xf5, 0xc4, 0x62, 0x0d, 0x7b, 0x98, 0x58, 0x21, 0xb6, 0x4b, 0x01, 0xf1, 0x43, + 0x1f, 0x3e, 0x27, 0xcc, 0x95, 0xda, 0xa4, 0xdf, 0x50, 0xe6, 0x4a, 0xc1, 0x41, 0x8d, 0xf1, 0x68, + 0xbb, 0x40, 0x49, 0x9a, 0x9b, 0x79, 0xac, 0xe6, 0x84, 0xfb, 0xd1, 0x6e, 0xa9, 0xea, 0xd7, 0x17, + 0x6b, 0x7e, 0xcd, 0x5f, 0xe4, 0x56, 0x77, 0xa3, 0x3d, 0xfe, 0x8f, 0xff, 0xe1, 0xbf, 0x04, 0xda, + 0xcc, 0x93, 0x89, 0xf3, 0x75, 0xab, 0xba, 0xef, 0x78, 0x98, 0x1c, 0x27, 0x1e, 0xd7, 0x71, 0x68, + 0x2d, 0x36, 0x3a, 0x7c, 0x9c, 0x59, 0xec, 0xa5, 0x45, 0x22, 0x2f, 0x74, 0xea, 0xb8, 0x43, 0xe1, + 0xff, 0xef, 0xa4, 0x40, 0xab, 0xfb, 0xb8, 0x6e, 0xa5, 0xf5, 0x8a, 0x27, 0x06, 0x98, 0x5c, 0xf1, + 0xbd, 0x06, 0x26, 0xec, 0x29, 0x11, 0xbe, 0x15, 0x61, 0x1a, 0xc2, 0x32, 0xc8, 0x46, 0x8e, 0x6d, + 0x1a, 0x73, 0xc6, 0xc2, 0x68, 0xf9, 0xf1, 0x0f, 0x9b, 0x85, 0x33, 0xad, 0x66, 0x21, 0x7b, 0x73, + 0x7d, 0xf5, 0xa4, 0x59, 0x98, 0xef, 0x85, 0x14, 0x1e, 0x07, 0x98, 0x96, 0x6e, 0xae, 0xaf, 0x22, + 0xa6, 0x0c, 0x9f, 0x07, 0x93, 0x36, 0xa6, 0x0e, 0xc1, 0xf6, 0xf2, 0xf6, 0xfa, 0x4b, 0xc2, 0xbe, + 0x99, 0xe1, 0x16, 0x2f, 0x49, 0x8b, 0x93, 0xab, 0x69, 0x01, 0xd4, 0xa9, 0x03, 0x77, 0xc0, 0x88, + 0xbf, 0xfb, 0x16, 0xae, 0x86, 0xd4, 0xcc, 0xce, 0x65, 0x17, 0xc6, 0x96, 0x1e, 0x2b, 0x25, 0x2b, + 0xa8, 0x5c, 0xe0, 0xcb, 0x26, 0x1f, 0xb6, 0x84, 0xac, 0xc3, 0xb5, 0x78, 0xe5, 0xca, 0xe7, 0x25, + 0xda, 0xc8, 0x96, 0xb0, 0x82, 0x62, 0x73, 0xc5, 0x5f, 0x66, 0x00, 0xd4, 0x1f, 0x9e, 0x06, 0xbe, + 0x47, 0x71, 0x5f, 0x9e, 0x9e, 0x82, 0x89, 0x2a, 0xb7, 0x1c, 0x62, 0x5b, 0xe2, 0x9a, 0x99, 0x4f, + 0xe3, 0xbd, 0x29, 0xf1, 0x27, 0x56, 0x52, 0xe6, 0x50, 0x07, 0x00, 0xbc, 0x01, 0x86, 0x09, 0xa6, + 0x91, 0x1b, 0x9a, 0xd9, 0x39, 0x63, 0x61, 0x6c, 0xe9, 0x6a, 0x4f, 0x28, 0x9e, 0xdf, 0x2c, 0xf9, + 0x4a, 0x8d, 0x27, 0x4a, 0x95, 0xd0, 0x0a, 0x23, 0x5a, 0x3e, 0x27, 0x91, 0x86, 0x11, 0xb7, 0x81, + 0xa4, 0xad, 0xe2, 0x77, 0x33, 0x60, 0x42, 0x8f, 0x52, 0xc3, 0xc1, 0x87, 0xf0, 0x10, 0x8c, 0x10, + 0x91, 0x2c, 0x3c, 0x4e, 0x63, 0x4b, 0xdb, 0xa5, 0x53, 0x6d, 0xab, 0x52, 0x47, 0x12, 0x96, 0xc7, + 0xd8, 0x9a, 0xc9, 0x3f, 0x28, 0x46, 0x83, 0x6f, 0x83, 0x3c, 0x91, 0x0b, 0xc5, 0xb3, 0x69, 0x6c, + 0xe9, 0x4b, 0x7d, 0x44, 0x16, 0x86, 0xcb, 0xe3, 0xad, 0x66, 0x21, 0x1f, 0xff, 0x43, 0x0a, 0xb0, + 0xf8, 0x5e, 0x06, 0xcc, 0xae, 0x44, 0x34, 0xf4, 0xeb, 0x08, 0x53, 0x3f, 0x22, 0x55, 0xbc, 0xe2, + 0xbb, 0x51, 0xdd, 0x5b, 0xc5, 0x7b, 0x8e, 0xe7, 0x84, 0x2c, 0x5b, 0xe7, 0xc0, 0x90, 0x67, 0xd5, + 0xb1, 0xcc, 0x9e, 0x71, 0x19, 0xd3, 0xa1, 0x4d, 0xab, 0x8e, 0x11, 0xe7, 0x30, 0x09, 0x96, 0x2c, + 0x72, 0x2f, 0x28, 0x89, 0x1b, 0xc7, 0x01, 0x46, 0x9c, 0x03, 0xaf, 0x80, 0xe1, 0x3d, 0x9f, 0xd4, + 0x2d, 0xb1, 0x8e, 0xa3, 0xc9, 0xca, 0x5c, 0xe3, 0x54, 0x24, 0xb9, 0xf0, 0x29, 0x30, 0x66, 0x63, + 0x5a, 0x25, 0x4e, 0xc0, 0xa0, 0xcd, 0x21, 0x2e, 0x7c, 0x41, 0x0a, 0x8f, 0xad, 0x26, 0x2c, 0xa4, + 0xcb, 0xc1, 0xab, 0x20, 0x1f, 0x10, 0xc7, 0x27, 0x4e, 0x78, 0x6c, 0xe6, 0xe6, 0x8c, 0x85, 0x5c, + 0x79, 0x42, 0xea, 0xe4, 0xb7, 0x25, 0x1d, 0x29, 0x09, 0x38, 0x07, 0xf2, 0x2f, 0x54, 0xb6, 0x36, + 0xb7, 0xad, 0x70, 0xdf, 0x1c, 0xe6, 0x08, 0x43, 0x4c, 0x1a, 0x29, 0x6a, 0xf1, 0xaf, 0x19, 0x60, + 0xa6, 0xa3, 0x12, 0x87, 0x14, 0x5e, 0x03, 0x79, 0x1a, 0xb2, 0x8a, 0x53, 0x3b, 0x96, 0x31, 0x79, + 0x24, 0x06, 0xab, 0x48, 0xfa, 0x49, 0xb3, 0x30, 0x9d, 0x68, 0xc4, 0x54, 0x1e, 0x0f, 0xa5, 0x0b, + 0x7f, 0x6e, 0x80, 0x0b, 0x87, 0x78, 0x77, 0xdf, 0xf7, 0x0f, 0x56, 0x5c, 0x07, 0x7b, 0xe1, 0x8a, + 0xef, 0xed, 0x39, 0x35, 0x99, 0x03, 0xe8, 0x94, 0x39, 0xf0, 0x72, 0xa7, 0xe5, 0xf2, 0x7d, 0xad, + 0x66, 0xe1, 0x42, 0x17, 0x06, 0xea, 0xe6, 0x07, 0xdc, 0x01, 0x66, 0x35, 0xb5, 0x49, 0x64, 0x01, + 0x13, 0x65, 0x6b, 0xb4, 0x7c, 0xb9, 0xd5, 0x2c, 0x98, 0x2b, 0x3d, 0x64, 0x50, 0x4f, 0xed, 0xe2, + 0xb7, 0xb3, 0xe9, 0xf0, 0x6a, 0xe9, 0xf6, 0x26, 0xc8, 0xb3, 0x6d, 0x6c, 0x5b, 0xa1, 0x25, 0x37, + 0xe2, 0xe3, 0x77, 0xb7, 0xe9, 0x45, 0xcd, 0xd8, 0xc0, 0xa1, 0x55, 0x86, 0x72, 0x41, 0x40, 0x42, + 0x43, 0xca, 0x2a, 0xfc, 0x1a, 0x18, 0xa2, 0x01, 0xae, 0xca, 0x40, 0xbf, 0x72, 0xda, 0xcd, 0xd6, + 0xe3, 0x41, 0x2a, 0x01, 0xae, 0x26, 0x7b, 0x81, 0xfd, 0x43, 0x1c, 0x16, 0xbe, 0x63, 0x80, 0x61, + 0xca, 0x0b, 0x94, 0x2c, 0x6a, 0xaf, 0x0d, 0xca, 0x83, 0x54, 0x15, 0x14, 0xff, 0x91, 0x04, 0x2f, + 0xfe, 0x2b, 0x03, 0xe6, 0x7b, 0xa9, 0xae, 0xf8, 0x9e, 0x2d, 0x96, 0x63, 0x5d, 0xee, 0x6d, 0x91, + 0xe9, 0x4f, 0xe9, 0x7b, 0xfb, 0xa4, 0x59, 0x78, 0xe8, 0x8e, 0x06, 0xb4, 0x22, 0xf0, 0x39, 0xf5, + 0xdc, 0xa2, 0x50, 0xcc, 0xb7, 0x3b, 0x76, 0xd2, 0x2c, 0x9c, 0x57, 0x6a, 0xed, 0xbe, 0xc2, 0x06, + 0x80, 0xae, 0x45, 0xc3, 0x1b, 0xc4, 0xf2, 0xa8, 0x30, 0xeb, 0xd4, 0xb1, 0x0c, 0xdf, 0x23, 0x77, + 0x97, 0x1e, 0x4c, 0xa3, 0x3c, 0x23, 0x21, 0xe1, 0xf5, 0x0e, 0x6b, 0xa8, 0x0b, 0x02, 0xab, 0x5b, + 0x04, 0x5b, 0x54, 0x95, 0x22, 0xed, 0x44, 0x61, 0x54, 0x24, 0xb9, 0xf0, 0x61, 0x30, 0x52, 0xc7, + 0x94, 0x5a, 0x35, 0xcc, 0xeb, 0xcf, 0x68, 0x72, 0x44, 0x6f, 0x08, 0x32, 0x8a, 0xf9, 0xac, 0x3f, + 0xb9, 0xdc, 0x2b, 0x6a, 0xd7, 0x1d, 0x1a, 0xc2, 0x57, 0x3b, 0x36, 0x40, 0xe9, 0xee, 0x9e, 0x90, + 0x69, 0xf3, 0xf4, 0x57, 0xc5, 0x2f, 0xa6, 0x68, 0xc9, 0xff, 0x55, 0x90, 0x73, 0x42, 0x5c, 0x8f, + 0xcf, 0xee, 0x97, 0x07, 0x94, 0x7b, 0xe5, 0xb3, 0xd2, 0x87, 0xdc, 0x3a, 0x43, 0x43, 0x02, 0xb4, + 0xf8, 0xab, 0x0c, 0x78, 0xa0, 0x97, 0x0a, 0x3b, 0x50, 0x28, 0x8b, 0x78, 0xe0, 0x46, 0xc4, 0x72, + 0x65, 0xc6, 0xa9, 0x88, 0x6f, 0x73, 0x2a, 0x92, 0x5c, 0x56, 0xf2, 0xa9, 0xe3, 0xd5, 0x22, 0xd7, + 0x22, 0x32, 0x9d, 0xd4, 0x53, 0x57, 0x24, 0x1d, 0x29, 0x09, 0x58, 0x02, 0x80, 0xee, 0xfb, 0x24, + 0xe4, 0x18, 0xb2, 0x7a, 0x9d, 0x63, 0x05, 0xa2, 0xa2, 0xa8, 0x48, 0x93, 0x60, 0x27, 0xda, 0x81, + 0xe3, 0xd9, 0x72, 0xd5, 0xd5, 0x2e, 0x7e, 0xd1, 0xf1, 0x6c, 0xc4, 0x39, 0x0c, 0xdf, 0x75, 0x68, + 0xc8, 0x28, 0x72, 0xc9, 0xdb, 0xa2, 0xce, 0x25, 0x95, 0x04, 0xc3, 0xaf, 0xb2, 0xaa, 0xef, 0x13, + 0x07, 0x53, 0x73, 0x38, 0xc1, 0x5f, 0x51, 0x54, 0xa4, 0x49, 0x14, 0xff, 0x99, 0xef, 0x9d, 0x24, + 0xac, 0x94, 0xc0, 0x07, 0x41, 0xae, 0x46, 0xfc, 0x28, 0x90, 0x51, 0x52, 0xd1, 0x7e, 0x9e, 0x11, + 0x91, 0xe0, 0xb1, 0xac, 0x6c, 0xb4, 0xb5, 0xa9, 0x2a, 0x2b, 0xe3, 0xe6, 0x34, 0xe6, 0xc3, 0x6f, + 0x1a, 0x20, 0xe7, 0xc9, 0xe0, 0xb0, 0x94, 0x7b, 0x75, 0x40, 0x79, 0xc1, 0xc3, 0x9b, 0xb8, 0x2b, + 0x22, 0x2f, 0x90, 0xe1, 0x93, 0x20, 0x47, 0xab, 0x7e, 0x80, 0x65, 0xd4, 0x67, 0x63, 0xa1, 0x0a, + 0x23, 0x9e, 0x34, 0x0b, 0x67, 0x63, 0x73, 0x9c, 0x80, 0x84, 0x30, 0xfc, 0x8e, 0x01, 0x40, 0xc3, + 0x72, 0x1d, 0xdb, 0xe2, 0x2d, 0x43, 0x8e, 0xbb, 0xdf, 0xdf, 0xb4, 0x7e, 0x49, 0x99, 0x17, 0x8b, + 0x96, 0xfc, 0x47, 0x1a, 0x34, 0x7c, 0xd7, 0x00, 0xe3, 0x34, 0xda, 0x25, 0x52, 0x8b, 0xf2, 0xe6, + 0x62, 0x6c, 0xe9, 0xcb, 0x7d, 0xf5, 0xa5, 0xa2, 0x01, 0x94, 0x27, 0x5a, 0xcd, 0xc2, 0xb8, 0x4e, + 0x41, 0x6d, 0x0e, 0xc0, 0xef, 0x1b, 0x20, 0xdf, 0x88, 0xcf, 0xec, 0x11, 0xbe, 0xe1, 0x5f, 0x1f, + 0xd0, 0xc2, 0xca, 0x8c, 0x4a, 0x76, 0x81, 0xea, 0x03, 0x94, 0x07, 0xf0, 0x8f, 0x06, 0x30, 0x2d, + 0x5b, 0x14, 0x78, 0xcb, 0xdd, 0x26, 0x8e, 0x17, 0x62, 0x22, 0xfa, 0x4d, 0x6a, 0xe6, 0xb9, 0x7b, + 0xfd, 0x3d, 0x0b, 0xd3, 0xbd, 0x6c, 0x79, 0x4e, 0x7a, 0x67, 0x2e, 0xf7, 0x70, 0x03, 0xf5, 0x74, + 0x90, 0x27, 0x5a, 0xd2, 0xd2, 0x98, 0xa3, 0x03, 0x48, 0xb4, 0xa4, 0x97, 0x92, 0xd5, 0x21, 0xe9, + 0xa0, 0x34, 0x68, 0xb8, 0x05, 0xa6, 0x02, 0x82, 0x39, 0xc0, 0x4d, 0xef, 0xc0, 0xf3, 0x0f, 0xbd, + 0x6b, 0x0e, 0x76, 0x6d, 0x6a, 0x82, 0x39, 0x63, 0x21, 0x5f, 0xbe, 0xd4, 0x6a, 0x16, 0xa6, 0xb6, + 0xbb, 0x09, 0xa0, 0xee, 0x7a, 0xc5, 0x77, 0xb3, 0xe9, 0x5b, 0x40, 0xba, 0x8b, 0x80, 0xef, 0x8b, + 0xa7, 0x17, 0xb1, 0xa1, 0xa6, 0xc1, 0x57, 0xeb, 0xcd, 0x01, 0x25, 0x93, 0x6a, 0x03, 0x92, 0x4e, + 0x4e, 0x91, 0x28, 0xd2, 0xfc, 0x80, 0x3f, 0x31, 0xc0, 0x59, 0xab, 0x5a, 0xc5, 0x41, 0x88, 0x6d, + 0x51, 0xdc, 0x33, 0x9f, 0x41, 0xfd, 0x9a, 0x92, 0x5e, 0x9d, 0x5d, 0xd6, 0xa1, 0x51, 0xbb, 0x27, + 0xf0, 0x59, 0x70, 0x8e, 0x86, 0x3e, 0xc1, 0x76, 0xaa, 0x6d, 0x86, 0xad, 0x66, 0xe1, 0x5c, 0xa5, + 0x8d, 0x83, 0x52, 0x92, 0xc5, 0xbf, 0xe5, 0x40, 0xe1, 0x0e, 0x5b, 0xed, 0x2e, 0x2e, 0x66, 0x57, + 0xc0, 0x30, 0x7f, 0x5c, 0x9b, 0x47, 0x25, 0xaf, 0xb5, 0x82, 0x9c, 0x8a, 0x24, 0x97, 0x1d, 0x14, + 0x0c, 0x9f, 0xb5, 0x2f, 0x59, 0x2e, 0xa8, 0x0e, 0x8a, 0x8a, 0x20, 0xa3, 0x98, 0x0f, 0x97, 0x00, + 0xb0, 0x71, 0x40, 0x30, 0x3b, 0xac, 0x6c, 0x73, 0x84, 0x4b, 0xab, 0x45, 0x5a, 0x55, 0x1c, 0xa4, + 0x49, 0xc1, 0x6b, 0x00, 0xc6, 0xff, 0x1c, 0xdf, 0x7b, 0xd9, 0x22, 0x9e, 0xe3, 0xd5, 0xcc, 0x3c, + 0x77, 0x7b, 0x9a, 0x75, 0x63, 0xab, 0x1d, 0x5c, 0xd4, 0x45, 0x03, 0xbe, 0x0d, 0x86, 0xc5, 0xd0, + 0x87, 0x9f, 0x10, 0x03, 0xac, 0xf2, 0x80, 0xc7, 0x88, 0x43, 0x21, 0x09, 0xd9, 0x59, 0xdd, 0x73, + 0xf7, 0xba, 0xba, 0xdf, 0xb6, 0x9c, 0x0e, 0xff, 0x97, 0x97, 0xd3, 0xe2, 0xbf, 0x8d, 0x74, 0xcd, + 0xd1, 0x1e, 0xb5, 0x52, 0xb5, 0x5c, 0x0c, 0x57, 0xc1, 0x04, 0xbb, 0x31, 0x21, 0x1c, 0xb8, 0x4e, + 0xd5, 0xa2, 0xfc, 0xc2, 0x2e, 0x92, 0x5d, 0xcd, 0x90, 0x2a, 0x29, 0x3e, 0xea, 0xd0, 0x80, 0x2f, + 0x00, 0x28, 0x6e, 0x11, 0x6d, 0x76, 0x44, 0x43, 0xa4, 0xee, 0x03, 0x95, 0x0e, 0x09, 0xd4, 0x45, + 0x0b, 0xae, 0x80, 0x49, 0xd7, 0xda, 0xc5, 0x6e, 0x05, 0xbb, 0xb8, 0x1a, 0xfa, 0x84, 0x9b, 0x12, + 0x23, 0x8d, 0xa9, 0x56, 0xb3, 0x30, 0x79, 0x3d, 0xcd, 0x44, 0x9d, 0xf2, 0xc5, 0xf9, 0xf4, 0xd6, + 0xd6, 0x1f, 0x5c, 0xdc, 0xcd, 0x3e, 0xc8, 0x80, 0x99, 0xde, 0x99, 0x01, 0xbf, 0x95, 0x5c, 0x21, + 0xc5, 0x0d, 0xe1, 0xf5, 0x41, 0x65, 0xa1, 0xbc, 0x43, 0x82, 0xce, 0xfb, 0x23, 0xfc, 0x3a, 0x6b, + 0xd7, 0x2c, 0x37, 0x1e, 0x5a, 0xbd, 0x36, 0x30, 0x17, 0x18, 0x48, 0x79, 0x54, 0x74, 0x82, 0x96, + 0xcb, 0x1b, 0x3f, 0xcb, 0xc5, 0xc5, 0xdf, 0x18, 0xe9, 0x29, 0x42, 0xb2, 0x83, 0xe1, 0x0f, 0x0c, + 0x70, 0xde, 0x0f, 0xb0, 0xb7, 0xbc, 0xbd, 0xfe, 0xd2, 0xff, 0x89, 0x9d, 0x2c, 0x43, 0xb5, 0x79, + 0x4a, 0x3f, 0x5f, 0xa8, 0x6c, 0x6d, 0x0a, 0x83, 0xdb, 0xc4, 0x0f, 0x68, 0xf9, 0x42, 0xab, 0x59, + 0x38, 0xbf, 0xd5, 0x0e, 0x85, 0xd2, 0xd8, 0xc5, 0x3a, 0x98, 0x5a, 0x3b, 0x0a, 0x31, 0xf1, 0x2c, + 0x77, 0xd5, 0xaf, 0x46, 0x75, 0xec, 0x85, 0xc2, 0xd1, 0xd4, 0xc4, 0xcb, 0xb8, 0xcb, 0x89, 0xd7, + 0x03, 0x20, 0x1b, 0x11, 0x57, 0x66, 0xf1, 0x98, 0x9a, 0xe8, 0xa2, 0xeb, 0x88, 0xd1, 0x8b, 0xf3, + 0x60, 0x88, 0xf9, 0x09, 0x2f, 0x81, 0x2c, 0xb1, 0x0e, 0xb9, 0xd5, 0xf1, 0xf2, 0x08, 0x13, 0x41, + 0xd6, 0x21, 0x62, 0xb4, 0xe2, 0x5f, 0xe6, 0xc1, 0xf9, 0xd4, 0xb3, 0xc0, 0x19, 0x90, 0x51, 0x63, + 0x62, 0x20, 0x8d, 0x66, 0xd6, 0x57, 0x51, 0xc6, 0xb1, 0xe1, 0xd3, 0xaa, 0xf8, 0x0a, 0xd0, 0x82, + 0x3a, 0x4b, 0x38, 0x95, 0xf5, 0xe7, 0x89, 0x39, 0xe6, 0x48, 0x5c, 0x38, 0x99, 0x0f, 0x78, 0x4f, + 0xee, 0x12, 0xe1, 0x03, 0xde, 0x43, 0x8c, 0xf6, 0x69, 0xc7, 0x7d, 0xf1, 0xbc, 0x31, 0x77, 0x17, + 0xf3, 0xc6, 0xe1, 0xdb, 0xce, 0x1b, 0x1f, 0x04, 0xb9, 0xd0, 0x09, 0x5d, 0xcc, 0x0f, 0x32, 0xed, + 0x1a, 0x75, 0x83, 0x11, 0x91, 0xe0, 0xc1, 0xb7, 0xc0, 0x88, 0x8d, 0xf7, 0xac, 0xc8, 0x0d, 0xf9, + 0x99, 0x35, 0xb6, 0xb4, 0xd2, 0x87, 0x14, 0x12, 0xc3, 0xe0, 0x55, 0x61, 0x17, 0xc5, 0x00, 0xf0, + 0x21, 0x30, 0x52, 0xb7, 0x8e, 0x9c, 0x7a, 0x54, 0xe7, 0x0d, 0xa6, 0x21, 0xc4, 0x36, 0x04, 0x09, + 0xc5, 0x3c, 0x56, 0x19, 0xf1, 0x51, 0xd5, 0x8d, 0xa8, 0xd3, 0xc0, 0x92, 0x29, 0x9b, 0x3f, 0x55, + 0x19, 0xd7, 0x52, 0x7c, 0xd4, 0xa1, 0xc1, 0xc1, 0x1c, 0x8f, 0x2b, 0x8f, 0x69, 0x60, 0x82, 0x84, + 0x62, 0x5e, 0x3b, 0x98, 0x94, 0x1f, 0xef, 0x05, 0x26, 0x95, 0x3b, 0x34, 0xe0, 0xa3, 0x60, 0xb4, + 0x6e, 0x1d, 0x5d, 0xc7, 0x5e, 0x2d, 0xdc, 0x37, 0xcf, 0xce, 0x19, 0x0b, 0xd9, 0xf2, 0xd9, 0x56, + 0xb3, 0x30, 0xba, 0x11, 0x13, 0x51, 0xc2, 0xe7, 0xc2, 0x8e, 0x27, 0x85, 0xcf, 0x69, 0xc2, 0x31, + 0x11, 0x25, 0x7c, 0xd6, 0xbd, 0x04, 0x56, 0xc8, 0x36, 0x97, 0x79, 0xbe, 0xfd, 0x9a, 0xbb, 0x2d, + 0xc8, 0x28, 0xe6, 0xc3, 0x05, 0x90, 0xaf, 0x5b, 0x47, 0x7c, 0x24, 0x61, 0x4e, 0x70, 0xb3, 0x7c, + 0x30, 0xbe, 0x21, 0x69, 0x48, 0x71, 0xb9, 0xa4, 0xe3, 0x09, 0xc9, 0x49, 0x4d, 0x52, 0xd2, 0x90, + 0xe2, 0xb2, 0x24, 0x8e, 0x3c, 0xe7, 0x56, 0x84, 0x85, 0x30, 0xe4, 0x91, 0x51, 0x49, 0x7c, 0x33, + 0x61, 0x21, 0x5d, 0x0e, 0x96, 0x00, 0xa8, 0x47, 0x6e, 0xe8, 0x04, 0x2e, 0xde, 0xda, 0x33, 0x2f, + 0xf0, 0xf8, 0xf3, 0xa6, 0x7f, 0x43, 0x51, 0x91, 0x26, 0x01, 0x31, 0x18, 0xc2, 0x5e, 0x54, 0x37, + 0x2f, 0xf2, 0x83, 0xbd, 0x2f, 0x29, 0xa8, 0x76, 0xce, 0x9a, 0x17, 0xd5, 0x11, 0x37, 0x0f, 0x9f, + 0x06, 0x67, 0xeb, 0xd6, 0x11, 0x2b, 0x07, 0x98, 0x84, 0x0e, 0xa6, 0xe6, 0x14, 0x7f, 0xf8, 0x49, + 0xd6, 0xed, 0x6e, 0xe8, 0x0c, 0xd4, 0x2e, 0xc7, 0x15, 0x1d, 0x4f, 0x53, 0x9c, 0xd6, 0x14, 0x75, + 0x06, 0x6a, 0x97, 0x63, 0x91, 0x26, 0xf8, 0x56, 0xe4, 0x10, 0x6c, 0x9b, 0xf7, 0xf1, 0x06, 0x59, + 0xbe, 0xac, 0x10, 0x34, 0xa4, 0xb8, 0xb0, 0x11, 0xcf, 0xae, 0x4c, 0xbe, 0x0d, 0x6f, 0xf6, 0xb7, + 0x92, 0x6f, 0x91, 0x65, 0x42, 0xac, 0x63, 0x71, 0xd2, 0xe8, 0x53, 0x2b, 0x48, 0x41, 0xce, 0x72, + 0xdd, 0xad, 0x3d, 0xf3, 0x12, 0x8f, 0x7d, 0xbf, 0x4f, 0x10, 0x55, 0x75, 0x96, 0x19, 0x08, 0x12, + 0x58, 0x0c, 0xd4, 0xf7, 0x58, 0x6a, 0xcc, 0x0c, 0x16, 0x74, 0x8b, 0x81, 0x20, 0x81, 0xc5, 0x9f, + 0xd4, 0x3b, 0xde, 0xda, 0x33, 0xef, 0x1f, 0xf0, 0x93, 0x32, 0x10, 0x24, 0xb0, 0xa0, 0x03, 0xb2, + 0x9e, 0x1f, 0x9a, 0x97, 0x07, 0x72, 0x3c, 0xf3, 0x03, 0x67, 0xd3, 0x0f, 0x11, 0xc3, 0x80, 0x3f, + 0x36, 0x00, 0x08, 0x92, 0x14, 0x7d, 0xa0, 0x2f, 0x23, 0x91, 0x14, 0x64, 0x29, 0xc9, 0xed, 0x35, + 0x2f, 0x24, 0xc7, 0xc9, 0xf5, 0x48, 0xdb, 0x03, 0x9a, 0x17, 0xf0, 0x17, 0x06, 0xb8, 0xa8, 0xb7, + 0xc9, 0xca, 0xbd, 0x59, 0x1e, 0x91, 0x1b, 0xfd, 0x4e, 0xf3, 0xb2, 0xef, 0xbb, 0x65, 0xb3, 0xd5, + 0x2c, 0x5c, 0x5c, 0xee, 0x82, 0x8a, 0xba, 0xfa, 0x02, 0x7f, 0x6b, 0x80, 0x49, 0x59, 0x45, 0x35, + 0x0f, 0x0b, 0x3c, 0x80, 0xb8, 0xdf, 0x01, 0x4c, 0xe3, 0x88, 0x38, 0xaa, 0x97, 0xec, 0x1d, 0x7c, + 0xd4, 0xe9, 0x1a, 0xfc, 0x83, 0x01, 0xc6, 0x6d, 0x1c, 0x60, 0xcf, 0xc6, 0x5e, 0x95, 0xf9, 0x3a, + 0xd7, 0x97, 0x91, 0x45, 0xda, 0xd7, 0x55, 0x0d, 0x42, 0xb8, 0x59, 0x92, 0x6e, 0x8e, 0xeb, 0xac, + 0x93, 0x66, 0x61, 0x3a, 0x51, 0xd5, 0x39, 0xa8, 0xcd, 0x4b, 0xf8, 0x9e, 0x01, 0xce, 0x27, 0x0b, + 0x20, 0x8e, 0x94, 0xf9, 0x01, 0xe6, 0x01, 0x6f, 0x5f, 0x97, 0xdb, 0x01, 0x51, 0xda, 0x03, 0xf8, + 0x3b, 0x83, 0x75, 0x6a, 0xf1, 0xbd, 0x8f, 0x9a, 0x45, 0x1e, 0xcb, 0x37, 0xfa, 0x1e, 0x4b, 0x85, + 0x20, 0x42, 0x79, 0x35, 0x69, 0x05, 0x15, 0xe7, 0xa4, 0x59, 0x98, 0xd2, 0x23, 0xa9, 0x18, 0x48, + 0xf7, 0x10, 0x7e, 0xcf, 0x00, 0xe3, 0x38, 0xe9, 0xb8, 0xa9, 0xf9, 0x60, 0x5f, 0x82, 0xd8, 0xb5, + 0x89, 0x17, 0x37, 0x75, 0x8d, 0x45, 0x51, 0x1b, 0x36, 0xeb, 0x20, 0xf1, 0x91, 0x55, 0x0f, 0x5c, + 0x6c, 0xfe, 0x4f, 0x9f, 0x3b, 0xc8, 0x35, 0x61, 0x17, 0xc5, 0x00, 0xf0, 0x2a, 0xc8, 0x7b, 0x91, + 0xeb, 0x5a, 0xbb, 0x2e, 0x36, 0x1f, 0xe2, 0xbd, 0x88, 0x1a, 0xc9, 0x6e, 0x4a, 0x3a, 0x52, 0x12, + 0x70, 0x0f, 0xcc, 0x1d, 0xbd, 0xa8, 0x3e, 0x4f, 0xea, 0x3a, 0x34, 0x34, 0xaf, 0x70, 0x2b, 0x33, + 0xad, 0x66, 0x61, 0x7a, 0xa7, 0xfb, 0x58, 0xf1, 0x8e, 0x36, 0xe0, 0x2b, 0xe0, 0x7e, 0x4d, 0x66, + 0xad, 0xbe, 0x8b, 0x6d, 0x1b, 0xdb, 0xf1, 0xc5, 0xcd, 0xfc, 0x5f, 0x31, 0xb8, 0x8c, 0x37, 0xf8, + 0x4e, 0x5a, 0x00, 0xdd, 0x4e, 0x1b, 0x5e, 0x07, 0xd3, 0x1a, 0x7b, 0xdd, 0x0b, 0xb7, 0x48, 0x25, + 0x24, 0x8e, 0x57, 0x33, 0x17, 0xb8, 0xdd, 0x8b, 0xf1, 0x8e, 0xdc, 0xd1, 0x78, 0xa8, 0x87, 0x0e, + 0xfc, 0x62, 0x9b, 0x35, 0xfe, 0x0a, 0xcd, 0x0a, 0x5e, 0xc4, 0xc7, 0xd4, 0x7c, 0x98, 0x77, 0x27, + 0x7c, 0xb1, 0x77, 0x34, 0x3a, 0xea, 0x21, 0x0f, 0xbf, 0x00, 0x2e, 0xa4, 0x38, 0xec, 0x8a, 0x62, + 0x3e, 0x22, 0xee, 0x1a, 0xac, 0x9f, 0xdd, 0x89, 0x89, 0xa8, 0x9b, 0x24, 0xfc, 0x3c, 0x80, 0x1a, + 0x79, 0xc3, 0x0a, 0xb8, 0xfe, 0xa3, 0xe2, 0xda, 0xc3, 0x56, 0x74, 0x47, 0xd2, 0x50, 0x17, 0x39, + 0xf8, 0x53, 0xa3, 0xed, 0x49, 0x92, 0xdb, 0x31, 0x35, 0xaf, 0xf2, 0xfd, 0xbb, 0x71, 0xca, 0x2c, + 0xd4, 0xde, 0x83, 0x44, 0x2e, 0xd6, 0xc2, 0xac, 0x41, 0xa1, 0x1e, 0x2e, 0xcc, 0xb0, 0x1b, 0x7a, + 0xaa, 0xc2, 0xc3, 0x09, 0x90, 0x3d, 0xc0, 0xf2, 0xab, 0x0a, 0xc4, 0x7e, 0x42, 0x1b, 0xe4, 0x1a, + 0x96, 0x1b, 0xc5, 0x43, 0x86, 0x3e, 0x77, 0x07, 0x48, 0x18, 0x7f, 0x36, 0xf3, 0x8c, 0x31, 0xf3, + 0xbe, 0x01, 0xa6, 0xbb, 0x1f, 0x3c, 0xf7, 0xd4, 0xad, 0x9f, 0x19, 0x60, 0xb2, 0xe3, 0x8c, 0xe9, + 0xe2, 0xd1, 0xad, 0x76, 0x8f, 0x5e, 0xe9, 0xf7, 0x61, 0x21, 0x36, 0x07, 0xef, 0x90, 0x75, 0xf7, + 0x7e, 0x68, 0x80, 0x89, 0x74, 0xd9, 0xbe, 0x97, 0xf1, 0x2a, 0xbe, 0x9f, 0x01, 0xd3, 0xdd, 0x1b, + 0x7b, 0x48, 0xd4, 0x04, 0x63, 0x30, 0x93, 0xa0, 0x6e, 0x53, 0xe3, 0x77, 0x0c, 0x30, 0xf6, 0x96, + 0x92, 0x8b, 0xdf, 0xba, 0xf7, 0x7d, 0x06, 0x15, 0x9f, 0x93, 0x09, 0x83, 0x22, 0x1d, 0xb7, 0xf8, + 0x7b, 0x03, 0x4c, 0x75, 0x6d, 0x00, 0xe0, 0x15, 0x30, 0x6c, 0xb9, 0xae, 0x7f, 0x28, 0x46, 0x89, + 0xda, 0x3b, 0x82, 0x65, 0x4e, 0x45, 0x92, 0xab, 0x45, 0x2f, 0xf3, 0x59, 0x45, 0xaf, 0xf8, 0x27, + 0x03, 0x5c, 0xbe, 0x5d, 0x26, 0xde, 0x93, 0x25, 0x5d, 0x00, 0x79, 0xd9, 0xbc, 0x1f, 0xf3, 0xe5, + 0x94, 0xa5, 0x58, 0x16, 0x0d, 0xfe, 0xa1, 0x99, 0xf8, 0x55, 0xfc, 0xc0, 0x00, 0x13, 0x15, 0x4c, + 0x1a, 0x4e, 0x15, 0x23, 0xbc, 0x87, 0x09, 0xf6, 0xaa, 0x18, 0x2e, 0x82, 0x51, 0xfe, 0xba, 0x3b, + 0xb0, 0xaa, 0xf1, 0xab, 0x9b, 0x49, 0x19, 0xf2, 0xd1, 0xcd, 0x98, 0x81, 0x12, 0x19, 0xf5, 0x9a, + 0x27, 0xd3, 0xf3, 0x35, 0xcf, 0x65, 0x30, 0x14, 0x24, 0x83, 0xe8, 0x3c, 0xe3, 0xf2, 0xd9, 0x33, + 0xa7, 0x72, 0xae, 0x4f, 0x42, 0x3e, 0x5d, 0xcb, 0x49, 0xae, 0x4f, 0x42, 0xc4, 0xa9, 0xc5, 0x5f, + 0x1b, 0xe0, 0x5c, 0x7b, 0x1d, 0x67, 0x80, 0x24, 0x72, 0x3b, 0xde, 0x2b, 0x31, 0x1e, 0xe2, 0x1c, + 0xfd, 0x73, 0x97, 0xcc, 0xed, 0x3f, 0x77, 0x81, 0xcf, 0x83, 0x49, 0xf9, 0x73, 0xed, 0x28, 0x20, + 0x98, 0xf2, 0x77, 0xa7, 0xd9, 0xf6, 0x8f, 0x66, 0x37, 0xd2, 0x02, 0xa8, 0x53, 0xa7, 0xf8, 0x67, + 0x03, 0x74, 0xfb, 0x76, 0x0d, 0x5e, 0x12, 0x93, 0x50, 0x6d, 0xbc, 0x18, 0x4f, 0x41, 0x61, 0x03, + 0x8c, 0x50, 0x11, 0x7e, 0x99, 0x1e, 0x5b, 0xa7, 0x4c, 0x8f, 0xf4, 0x62, 0x8a, 0x16, 0x2c, 0xa6, + 0xc6, 0x60, 0x2c, 0x43, 0xaa, 0x56, 0x39, 0xf2, 0x6c, 0x39, 0x1c, 0x1f, 0x17, 0x19, 0xb2, 0xb2, + 0x2c, 0x68, 0x48, 0x71, 0xcb, 0xd5, 0x0f, 0x3f, 0x99, 0x3d, 0xf3, 0xd1, 0x27, 0xb3, 0x67, 0x3e, + 0xfe, 0x64, 0xf6, 0xcc, 0x37, 0x5a, 0xb3, 0xc6, 0x87, 0xad, 0x59, 0xe3, 0xa3, 0xd6, 0xac, 0xf1, + 0x71, 0x6b, 0xd6, 0xf8, 0x7b, 0x6b, 0xd6, 0xf8, 0xd1, 0x3f, 0x66, 0xcf, 0x7c, 0xe5, 0xb9, 0x53, + 0x7d, 0x2e, 0xfe, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x11, 0x77, 0x12, 0x7e, 0x87, 0x2e, 0x00, + 0x00, } func (m *ConversionRequest) Marshal() (dAtA []byte, err error) { @@ -2656,6 +2658,11 @@ func (m *ValidationRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x1a i -= len(m.Message) copy(dAtA[i:], m.Message) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -3345,6 +3352,8 @@ func (m *ValidationRule) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -3811,6 +3820,7 @@ func (this *ValidationRule) String() string { s := strings.Join([]string{`&ValidationRule{`, `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, `}`, }, "") return s @@ -9037,6 +9047,38 @@ func (m *ValidationRule) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MessageExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto index 678e9b9104b..feb9fd9d1cd 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto @@ -277,7 +277,7 @@ message CustomResourceDefinitionSpec { // Defaults to true in v1beta for backwards compatibility. // Deprecated: will be required to be false in v1. Preservation of unknown fields can be specified // in the validation schema using the `x-kubernetes-preserve-unknown-fields: true` extension. - // See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details. + // See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning for details. // +optional optional bool preserveUnknownFields = 10; } @@ -717,6 +717,19 @@ message ValidationRule { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" optional string message = 2; + + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + optional string messageExpression = 3; } // WebhookClientConfig contains the information to make a TLS connection with the webhook. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go index 61ebdb63f21..db445b10d2b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go @@ -96,7 +96,7 @@ type CustomResourceDefinitionSpec struct { // Defaults to true in v1beta for backwards compatibility. // Deprecated: will be required to be false in v1. Preservation of unknown fields can be specified // in the validation schema using the `x-kubernetes-preserve-unknown-fields: true` extension. - // See https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#pruning-versus-preserving-unknown-fields for details. + // See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning for details. // +optional PreserveUnknownFields *bool `json:"preserveUnknownFields,omitempty" protobuf:"varint,10,opt,name=preserveUnknownFields"` } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go index c9d943c9a8a..ab0169f93e2 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types_jsonschema.go @@ -235,12 +235,24 @@ type ValidationRule struct { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + MessageExpression string `json:"messageExpression,omitempty" protobuf:"bytes,3,opt,name=messageExpression"` } // JSON represents any valid JSON value. // These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil. type JSON struct { - Raw []byte `protobuf:"bytes,1,opt,name=raw"` + Raw []byte `json:"-" protobuf:"bytes,1,opt,name=raw"` } // OpenAPISchemaType is used by the kube-openapi generator when constructing diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go index 54cae3cfdf1..ef5bc5e330a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go @@ -1306,6 +1306,7 @@ func Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in *apie func autoConvert_v1beta1_ValidationRule_To_apiextensions_ValidationRule(in *ValidationRule, out *apiextensions.ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } @@ -1317,6 +1318,7 @@ func Convert_v1beta1_ValidationRule_To_apiextensions_ValidationRule(in *Validati func autoConvert_apiextensions_ValidationRule_To_v1beta1_ValidationRule(in *apiextensions.ValidationRule, out *ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/cel_validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/cel_validation.go new file mode 100644 index 00000000000..a03615c28e3 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/cel_validation.go @@ -0,0 +1,336 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validation + +import ( + "fmt" + "math" + "sort" + + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" + structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/cel" +) + +// unbounded uses nil to represent an unbounded cardinality value. +var unbounded *uint64 = nil + +// CELSchemaContext keeps track of data used by x-kubernetes-validations rules for a specific schema node. +type CELSchemaContext struct { + // withinValidationRuleScope is true if the schema at the current level or above have x-kubernetes-validations rules. typeInfo + // should only be populated for schema nodes where this is true. + withinValidationRuleScope bool + + // typeInfo is lazily loaded for schema nodes withinValidationRuleScope and may be + // populated one of two possible ways: + // 1. Using a typeInfoAccessor to access it from the parent's type info. This is a cheap operation and should be + // used when a schema at a higher level already has type info. + // 2. Using a converter to construct type info from the jsonSchema. This is an expensive operation. + typeInfo *CELTypeInfo + // typeInfoErr is any cached error resulting from an attempt to lazily load typeInfo. + typeInfoErr error + + // parent is the context of the parent schema node, or nil if this is the context for the root schema node. + parent *CELSchemaContext + // typeInfoAccessor provides a way to access the type info of this schema node from the parent CELSchemaContext. + // nil if not extraction is possible, or the parent is nil. + typeInfoAccessor typeInfoAccessor + + // jsonSchema is the schema for this CELSchemaContext node. It must be non-nil. + jsonSchema *apiextensions.JSONSchemaProps + // converter converts a JSONSchemaProps to CELTypeInfo. + // Tests that check how many conversions are performed during CRD validation wrap DefaultConverter + // with a converter that counts how many conversion operations. + converter converter + + // MaxCardinality represents a limit to the number of data elements that can exist for the current + // schema based on MaxProperties or MaxItems limits present on parent schemas, If all parent + // map and array schemas have MaxProperties or MaxItems limits declared MaxCardinality is + // an int pointer representing the product of these limits. If least one parent map or list schema + // does not have a MaxProperties or MaxItems limits set, the MaxCardinality is nil, indicating + // that the parent schemas offer no bound to the number of times a data element for the current + // schema can exist. + MaxCardinality *uint64 + // TotalCost accumulates the x-kubernetes-validators estimated rule cost total for an entire custom resource + // definition. A single TotalCost is allocated for each CustomResourceDefinition and passed through the stack as the + // CustomResourceDefinition's OpenAPIv3 schema is recursively validated. + TotalCost *TotalCost +} + +// TypeInfo returns the CELTypeInfo for this CELSchemaContext node. Returns nil, nil if this CELSchemaContext is nil, +// or if current level or above does not have x-kubernetes-validations rules. The returned type info is shared and +// should not be modified by the caller. +func (c *CELSchemaContext) TypeInfo() (*CELTypeInfo, error) { + if c == nil || !c.withinValidationRuleScope { + return nil, nil + } + if c.typeInfo != nil || c.typeInfoErr != nil { + return c.typeInfo, c.typeInfoErr // return already computed result if available + } + + // If able to get the type info from the parent's type info, prefer this approach + // since it is more efficient. + if c.parent != nil { + parentTypeInfo, parentErr := c.parent.TypeInfo() + if parentErr != nil { + c.typeInfoErr = parentErr + return nil, parentErr + } + if parentTypeInfo != nil && c.typeInfoAccessor != nil { + c.typeInfo = c.typeInfoAccessor.accessTypeInfo(parentTypeInfo) + if c.typeInfo != nil { + return c.typeInfo, nil + } + } + } + // If unable to get the type info from the parent, convert the jsonSchema to type info. + // This is expensive for large schemas. + c.typeInfo, c.typeInfoErr = c.converter(c.jsonSchema, c.parent == nil || c.jsonSchema.XEmbeddedResource) + return c.typeInfo, c.typeInfoErr +} + +// CELTypeInfo represents all the typeInfo needed by CEL to compile x-kubernetes-validations rules for a schema node. +type CELTypeInfo struct { + // Schema is a structural schema for this CELSchemaContext node. It must be non-nil. + Schema *structuralschema.Structural + // DeclType is a CEL declaration representation of Schema of this CELSchemaContext node. It must be non-nil. + DeclType *cel.DeclType +} + +// converter converts from JSON schema to a structural schema and a CEL declType, or returns an error if the conversion +// fails. This should be defaultConverter except in tests where it is useful to wrap it with a converter that tracks +// how many conversions have been performed. +type converter func(schema *apiextensions.JSONSchemaProps, isRoot bool) (*CELTypeInfo, error) + +func defaultConverter(schema *apiextensions.JSONSchemaProps, isRoot bool) (*CELTypeInfo, error) { + structural, err := structuralschema.NewStructural(schema) + if err != nil { + return nil, err + } + declType := model.SchemaDeclType(structural, isRoot) + if declType == nil { + return nil, fmt.Errorf("unable to convert structural schema to CEL declarations") + } + return &CELTypeInfo{structural, declType}, nil +} + +// RootCELContext constructs CELSchemaContext for the given root schema. +func RootCELContext(schema *apiextensions.JSONSchemaProps) *CELSchemaContext { + rootCardinality := uint64(1) + r := &CELSchemaContext{ + jsonSchema: schema, + withinValidationRuleScope: len(schema.XValidations) > 0, + MaxCardinality: &rootCardinality, + TotalCost: &TotalCost{}, + converter: defaultConverter, + } + return r +} + +// ChildPropertyContext returns nil, nil if this CELSchemaContext is nil, otherwise constructs and returns a +// CELSchemaContext for propertyName. +func (c *CELSchemaContext) ChildPropertyContext(propSchema *apiextensions.JSONSchemaProps, propertyName string) *CELSchemaContext { + if c == nil { + return nil + } + return c.childContext(propSchema, propertyTypeInfoAccessor{propertyName: propertyName}) +} + +// ChildAdditionalPropertiesContext returns nil, nil if this CELSchemaContext is nil, otherwise it constructs and returns +// a CELSchemaContext for the properties of an object if this CELSchemaContext is an object. +// schema must be non-nil and have a non-nil schema.AdditionalProperties. +func (c *CELSchemaContext) ChildAdditionalPropertiesContext(propsSchema *apiextensions.JSONSchemaProps) *CELSchemaContext { + if c == nil { + return nil + } + return c.childContext(propsSchema, additionalItemsTypeInfoAccessor{}) +} + +// ChildItemsContext returns nil, nil if this CELSchemaContext is nil, otherwise it constructs and returns a CELSchemaContext +// for the items of an array if this CELSchemaContext is an array. +func (c *CELSchemaContext) ChildItemsContext(itemsSchema *apiextensions.JSONSchemaProps) *CELSchemaContext { + if c == nil { + return nil + } + return c.childContext(itemsSchema, itemsTypeInfoAccessor{}) +} + +// childContext returns nil, nil if this CELSchemaContext is nil, otherwise it constructs a new CELSchemaContext for the +// given child schema of the current schema context. +// accessor optionally provides a way to access CELTypeInfo of the child from the current schema context's CELTypeInfo. +// childContext returns a CELSchemaContext where the MaxCardinality is multiplied by the +// factor that the schema increases the cardinality of its children. If the CELSchemaContext's +// MaxCardinality is unbounded (nil) or the factor that the schema increase the cardinality +// is unbounded, the resulting CELSchemaContext's MaxCardinality is also unbounded. +func (c *CELSchemaContext) childContext(child *apiextensions.JSONSchemaProps, accessor typeInfoAccessor) *CELSchemaContext { + result := &CELSchemaContext{ + parent: c, + typeInfoAccessor: accessor, + withinValidationRuleScope: c.withinValidationRuleScope, + TotalCost: c.TotalCost, + MaxCardinality: unbounded, + converter: c.converter, + } + if child != nil { + result.jsonSchema = child + if len(child.XValidations) > 0 { + result.withinValidationRuleScope = true + } + } + if c.jsonSchema == nil { + // nil schemas can be passed since we call ChildSchemaContext + // before ValidateCustomResourceDefinitionOpenAPISchema performs its nil check + return result + } + if c.MaxCardinality == unbounded { + return result + } + maxElements := extractMaxElements(c.jsonSchema) + if maxElements == unbounded { + return result + } + result.MaxCardinality = uint64ptr(multiplyWithOverflowGuard(*c.MaxCardinality, *maxElements)) + return result +} + +type typeInfoAccessor interface { + // accessTypeInfo looks up type information for a child schema from a non-nil parentTypeInfo and returns it, + // or returns nil if the child schema information is not accessible. For example, a nil + // return value is expected when a property name is unescapable in CEL. + // The caller MUST ensure the provided parentTypeInfo is non-nil. + accessTypeInfo(parentTypeInfo *CELTypeInfo) *CELTypeInfo +} + +type propertyTypeInfoAccessor struct { + // propertyName is the property name in the parent schema that this schema is declared at. + propertyName string +} + +func (c propertyTypeInfoAccessor) accessTypeInfo(parentTypeInfo *CELTypeInfo) *CELTypeInfo { + if parentTypeInfo.Schema.Properties != nil { + propSchema := parentTypeInfo.Schema.Properties[c.propertyName] + if escapedPropName, ok := cel.Escape(c.propertyName); ok { + if fieldDeclType, ok := parentTypeInfo.DeclType.Fields[escapedPropName]; ok { + return &CELTypeInfo{Schema: &propSchema, DeclType: fieldDeclType.Type} + } // else fields with unknown types are omitted from CEL validation entirely + } // fields with unescapable names are expected to be absent + } + return nil +} + +type itemsTypeInfoAccessor struct{} + +func (c itemsTypeInfoAccessor) accessTypeInfo(parentTypeInfo *CELTypeInfo) *CELTypeInfo { + if parentTypeInfo.Schema.Items != nil { + itemsSchema := parentTypeInfo.Schema.Items + itemsDeclType := parentTypeInfo.DeclType.ElemType + return &CELTypeInfo{Schema: itemsSchema, DeclType: itemsDeclType} + } + return nil +} + +type additionalItemsTypeInfoAccessor struct{} + +func (c additionalItemsTypeInfoAccessor) accessTypeInfo(parentTypeInfo *CELTypeInfo) *CELTypeInfo { + if parentTypeInfo.Schema.AdditionalProperties != nil { + propsSchema := parentTypeInfo.Schema.AdditionalProperties.Structural + valuesDeclType := parentTypeInfo.DeclType.ElemType + return &CELTypeInfo{Schema: propsSchema, DeclType: valuesDeclType} + } + return nil +} + +// TotalCost tracks the total cost of evaluating all the x-kubernetes-validations rules of a CustomResourceDefinition. +type TotalCost struct { + // Total accumulates the x-kubernetes-validations estimated rule cost total. + Total uint64 + // MostExpensive accumulates the top 4 most expensive rules contributing to the Total. Only rules + // that accumulate at least 1% of total cost limit are included. + MostExpensive []RuleCost +} + +// ObserveExpressionCost accumulates the cost of evaluating a -kubernetes-validations rule. +func (c *TotalCost) ObserveExpressionCost(path *field.Path, cost uint64) { + if math.MaxUint64-c.Total < cost { + c.Total = math.MaxUint64 + } else { + c.Total += cost + } + + if cost < StaticEstimatedCRDCostLimit/100 { // ignore rules that contribute < 1% of total cost limit + return + } + c.MostExpensive = append(c.MostExpensive, RuleCost{Path: path, Cost: cost}) + sort.Slice(c.MostExpensive, func(i, j int) bool { + // sort in descending order so the most expensive rule is first + return c.MostExpensive[i].Cost > c.MostExpensive[j].Cost + }) + if len(c.MostExpensive) > 4 { + c.MostExpensive = c.MostExpensive[:4] + } +} + +// RuleCost represents the cost of evaluating a single x-kubernetes-validations rule. +type RuleCost struct { + Path *field.Path + Cost uint64 +} + +// extractMaxElements returns the factor by which the schema increases the cardinality +// (number of possible data elements) of its children. If schema is a map and has +// MaxProperties or an array has MaxItems, the int pointer of the max value is returned. +// If schema is a map or array and does not have MaxProperties or MaxItems, +// unbounded (nil) is returned to indicate that there is no limit to the possible +// number of data elements imposed by the current schema. If the schema is an object, 1 is +// returned to indicate that there is no increase to the number of possible data elements +// for its children. Primitives do not have children, but 1 is returned for simplicity. +func extractMaxElements(schema *apiextensions.JSONSchemaProps) *uint64 { + switch schema.Type { + case "object": + if schema.AdditionalProperties != nil { + if schema.MaxProperties != nil { + maxProps := uint64(zeroIfNegative(*schema.MaxProperties)) + return &maxProps + } + return unbounded + } + // return 1 to indicate that all fields of an object exist at most one for + // each occurrence of the object they are fields of + return uint64ptr(1) + case "array": + if schema.MaxItems != nil { + maxItems := uint64(zeroIfNegative(*schema.MaxItems)) + return &maxItems + } + return unbounded + default: + return uint64ptr(1) + } +} + +func zeroIfNegative(v int64) int64 { + if v < 0 { + return 0 + } + return v +} + +func uint64ptr(i uint64) *uint64 { + return &i +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go index b97493d040b..e47a30d3a79 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go @@ -22,8 +22,8 @@ import ( "math" "reflect" "regexp" - "sort" "strings" + "sync" "unicode" "unicode/utf8" @@ -35,6 +35,8 @@ import ( "k8s.io/apimachinery/pkg/util/sets" utilvalidation "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" + celconfig "k8s.io/apiserver/pkg/apis/cel" + apiservercel "k8s.io/apiserver/pkg/cel" "k8s.io/apiserver/pkg/util/webhook" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -723,34 +725,43 @@ func validateCustomResourceDefinitionValidation(ctx context.Context, customResou requireValidPropertyType: opts.requireValidPropertyType, } - costInfo := rootCostInfo() - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema, fldPath.Child("openAPIV3Schema"), openAPIV3Schema, true, &opts, costInfo)...) - - if costInfo.TotalCost != nil { - if costInfo.TotalCost.totalCost > StaticEstimatedCRDCostLimit { - for _, expensive := range costInfo.TotalCost.mostExpensive { - costErrorMsg := fmt.Sprintf("contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema") - allErrs = append(allErrs, field.Forbidden(expensive.path, costErrorMsg)) - } - - costErrorMsg := getCostErrorMessage("x-kubernetes-validations estimated rule cost total for entire OpenAPIv3 schema", costInfo.TotalCost.totalCost, StaticEstimatedCRDCostLimit) - allErrs = append(allErrs, field.Forbidden(fldPath.Child("openAPIV3Schema"), costErrorMsg)) - } - } - + var celContext *CELSchemaContext + var structuralSchemaInitErrs field.ErrorList if opts.requireStructuralSchema { if ss, err := structuralschema.NewStructural(schema); err != nil { - // if the generic schema validation did its job, we should never get an error here. Hence, we hide it if there are validation errors already. - if len(allErrs) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("openAPIV3Schema"), "", err.Error())) - } + // These validation errors overlap with OpenAPISchema validation errors so we keep track of them + // separately and only show them if OpenAPISchema validation does not report any errors. + structuralSchemaInitErrs = append(structuralSchemaInitErrs, field.Invalid(fldPath.Child("openAPIV3Schema"), "", err.Error())) } else if validationErrors := structuralschema.ValidateStructural(fldPath.Child("openAPIV3Schema"), ss); len(validationErrors) > 0 { allErrs = append(allErrs, validationErrors...) } else if validationErrors, err := structuraldefaulting.ValidateDefaults(ctx, fldPath.Child("openAPIV3Schema"), ss, true, opts.requirePrunedDefaults); err != nil { // this should never happen allErrs = append(allErrs, field.Invalid(fldPath.Child("openAPIV3Schema"), "", err.Error())) - } else { + } else if len(validationErrors) > 0 { allErrs = append(allErrs, validationErrors...) + } else { + // Only initialize CEL rule validation context if the structural schemas are valid. + // A nil CELSchemaContext indicates that no CEL validation should be attempted. + celContext = RootCELContext(schema) + } + } + allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema, fldPath.Child("openAPIV3Schema"), openAPIV3Schema, true, &opts, celContext).AllErrors()...) + + if len(allErrs) == 0 && len(structuralSchemaInitErrs) > 0 { + // Structural schema initialization errors overlap with OpenAPISchema validation errors so we only show them + // if there are no OpenAPISchema validation errors. + allErrs = append(allErrs, structuralSchemaInitErrs...) + } + + if celContext != nil && celContext.TotalCost != nil { + if celContext.TotalCost.Total > StaticEstimatedCRDCostLimit { + for _, expensive := range celContext.TotalCost.MostExpensive { + costErrorMsg := fmt.Sprintf("contributed to estimated rule cost total exceeding cost limit for entire OpenAPIv3 schema") + allErrs = append(allErrs, field.Forbidden(expensive.Path, costErrorMsg)) + } + + costErrorMsg := getCostErrorMessage("x-kubernetes-validations estimated rule cost total for entire OpenAPIv3 schema", celContext.TotalCost.Total, StaticEstimatedCRDCostLimit) + allErrs = append(allErrs, field.Forbidden(fldPath.Child("openAPIV3Schema"), costErrorMsg)) } } } @@ -764,143 +775,43 @@ func validateCustomResourceDefinitionValidation(ctx context.Context, customResou return allErrs } -// unbounded uses nil to represent an unbounded cardinality value. -var unbounded *uint64 = nil - -type costInfo struct { - // MaxCardinality represents a limit to the number of data elements that can exist for the current - // schema based on MaxProperties or MaxItems limits present on parent schemas, If all parent - // map and array schemas have MaxProperties or MaxItems limits declared MaxCardinality is - // an int pointer representing the product of these limits. If least one parent map or list schema - // does not have a MaxProperties or MaxItems limits set, the MaxCardinality is nil, indicating - // that the parent schemas offer no bound to the number of times a data element for the current - // schema can exist. - MaxCardinality *uint64 - // TotalCost accumulates the x-kubernetes-validators estimated rule cost total for an entire custom resource - // definition. A single totalCost is allocated for each validation call and passed through the stack as the - // custom resource definition's OpenAPIv3 schema is recursively validated. - TotalCost *totalCost -} +var metaFields = sets.NewString("metadata", "kind", "apiVersion") -type totalCost struct { - // totalCost accumulates the x-kubernetes-validators estimated rule cost total. - totalCost uint64 - // mostExpensive accumulates the top 4 most expensive rules contributing to the totalCost. Only rules - // that accumulate at least 1% of total cost limit are included. - mostExpensive []ruleCost +// OpenAPISchemaErrorList tracks all validation errors reported ValidateCustomResourceDefinitionOpenAPISchema +// with CEL related errors kept separate from schema related errors. +type OpenAPISchemaErrorList struct { + SchemaErrors field.ErrorList + CELErrors field.ErrorList } -func (c *totalCost) observeExpressionCost(path *field.Path, cost uint64) { - if math.MaxUint64-c.totalCost < cost { - c.totalCost = math.MaxUint64 - } else { - c.totalCost += cost - } - - if cost < StaticEstimatedCRDCostLimit/100 { // ignore rules that contribute < 1% of total cost limit +// AppendErrors appends all errors in the provided list with the errors of this list. +func (o *OpenAPISchemaErrorList) AppendErrors(list *OpenAPISchemaErrorList) { + if o == nil || list == nil { return } - c.mostExpensive = append(c.mostExpensive, ruleCost{path: path, cost: cost}) - sort.Slice(c.mostExpensive, func(i, j int) bool { - // sort in descending order so the most expensive rule is first - return c.mostExpensive[i].cost > c.mostExpensive[j].cost - }) - if len(c.mostExpensive) > 4 { - c.mostExpensive = c.mostExpensive[:4] - } -} - -type ruleCost struct { - path *field.Path - cost uint64 + o.SchemaErrors = append(o.SchemaErrors, list.SchemaErrors...) + o.CELErrors = append(o.CELErrors, list.CELErrors...) } -// MultiplyByElementCost returns a costInfo where the MaxCardinality is multiplied by the -// factor that the schema increases the cardinality of its children. If the costInfo's -// MaxCardinality is unbounded (nil) or the factor that the schema increase the cardinality -// is unbounded, the resulting costInfo's MaxCardinality is also unbounded. -func (c *costInfo) MultiplyByElementCost(schema *apiextensions.JSONSchemaProps) costInfo { - result := costInfo{TotalCost: c.TotalCost, MaxCardinality: unbounded} - if schema == nil { - // nil schemas can be passed since we call MultiplyByElementCost - // before ValidateCustomResourceDefinitionOpenAPISchema performs its nil check - return result - } - if c.MaxCardinality == unbounded { - return result - } - maxElements := extractMaxElements(schema) - if maxElements == unbounded { - return result - } - result.MaxCardinality = uint64ptr(multiplyWithOverflowGuard(*c.MaxCardinality, *maxElements)) - return result -} - -// extractMaxElements returns the factor by which the schema increases the cardinality -// (number of possible data elements) of its children. If schema is a map and has -// MaxProperties or an array has MaxItems, the int pointer of the max value is returned. -// If schema is a map or array and does not have MaxProperties or MaxItems, -// unbounded (nil) is returned to indicate that there is no limit to the possible -// number of data elements imposed by the current schema. If the schema is an object, 1 is -// returned to indicate that there is no increase to the number of possible data elements -// for its children. Primitives do not have children, but 1 is returned for simplicity. -func extractMaxElements(schema *apiextensions.JSONSchemaProps) *uint64 { - switch schema.Type { - case "object": - if schema.AdditionalProperties != nil { - if schema.MaxProperties != nil { - maxProps := uint64(zeroIfNegative(*schema.MaxProperties)) - return &maxProps - } - return unbounded - } - // return 1 to indicate that all fields of an object exist at most one for - // each occurrence of the object they are fields of - return uint64ptr(1) - case "array": - if schema.MaxItems != nil { - maxItems := uint64(zeroIfNegative(*schema.MaxItems)) - return &maxItems - } - return unbounded - default: - return uint64ptr(1) - } -} - -func zeroIfNegative(v int64) int64 { - if v < 0 { - return 0 - } - return v -} - -func uint64ptr(i uint64) *uint64 { - return &i -} - -func rootCostInfo() costInfo { - rootCardinality := uint64(1) - return costInfo{ - MaxCardinality: &rootCardinality, - TotalCost: &totalCost{}, +// AllErrors returns a list containing both schema and CEL errors. +func (o *OpenAPISchemaErrorList) AllErrors() field.ErrorList { + if o == nil { + return field.ErrorList{} } + return append(o.SchemaErrors, o.CELErrors...) } -var metaFields = sets.NewString("metadata", "kind", "apiVersion") - // ValidateCustomResourceDefinitionOpenAPISchema statically validates -func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSchemaProps, fldPath *field.Path, ssv specStandardValidator, isRoot bool, opts *validationOptions, nodeCostInfo costInfo) field.ErrorList { - allErrs := field.ErrorList{} +func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSchemaProps, fldPath *field.Path, ssv specStandardValidator, isRoot bool, opts *validationOptions, celContext *CELSchemaContext) *OpenAPISchemaErrorList { + allErrs := &OpenAPISchemaErrorList{SchemaErrors: field.ErrorList{}, CELErrors: field.ErrorList{}} if schema == nil { return allErrs } - allErrs = append(allErrs, ssv.validate(schema, fldPath)...) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, ssv.validate(schema, fldPath)...) if schema.UniqueItems == true { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("uniqueItems"), "uniqueItems cannot be set to true since the runtime complexity becomes quadratic")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Forbidden(fldPath.Child("uniqueItems"), "uniqueItems cannot be set to true since the runtime complexity becomes quadratic")) } // additionalProperties and properties are mutual exclusive because otherwise they @@ -915,7 +826,7 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch if schema.AdditionalProperties != nil { if len(schema.Properties) != 0 { if schema.AdditionalProperties.Allows == false || schema.AdditionalProperties.Schema != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("additionalProperties"), "additionalProperties and properties are mutual exclusive")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Forbidden(fldPath.Child("additionalProperties"), "additionalProperties and properties are mutual exclusive")) } } // Note: we forbid additionalProperties at resource root, both embedded and top-level. @@ -925,7 +836,7 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch // we have to forbid defaults inside additionalProperties because pruning without actual value is ambiguous subSsv = ssv.withForbiddenDefaults("inside additionalProperties applying to object metadata") } - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema.AdditionalProperties.Schema, fldPath.Child("additionalProperties"), subSsv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(schema.AdditionalProperties.Schema, fldPath.Child("additionalProperties"), subSsv, false, opts, celContext.ChildAdditionalPropertiesContext(schema.AdditionalProperties.Schema))) } if len(schema.Properties) != 0 { @@ -943,33 +854,38 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch subSsv = subSsv.withForbiddenDefaults(fmt.Sprintf("in top-level %s", property)) } } - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("properties").Key(property), subSsv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + propertySchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&propertySchema, fldPath.Child("properties").Key(property), subSsv, false, opts, celContext.ChildPropertyContext(&propertySchema, property))) } } - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema.Not, fldPath.Child("not"), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(schema.Not, fldPath.Child("not"), ssv, false, opts, nil)) if len(schema.AllOf) != 0 { for i, jsonSchema := range schema.AllOf { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("allOf").Index(i), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + allOfSchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&allOfSchema, fldPath.Child("allOf").Index(i), ssv, false, opts, nil)) } } if len(schema.OneOf) != 0 { for i, jsonSchema := range schema.OneOf { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("oneOf").Index(i), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + oneOfSchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&oneOfSchema, fldPath.Child("oneOf").Index(i), ssv, false, opts, nil)) } } if len(schema.AnyOf) != 0 { for i, jsonSchema := range schema.AnyOf { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("anyOf").Index(i), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + anyOfSchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&anyOfSchema, fldPath.Child("anyOf").Index(i), ssv, false, opts, nil)) } } if len(schema.Definitions) != 0 { for definition, jsonSchema := range schema.Definitions { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("definitions").Key(definition), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + definitionSchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&definitionSchema, fldPath.Child("definitions").Key(definition), ssv, false, opts, nil)) } } @@ -983,83 +899,84 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch subSsv = subSsv.withForbidOldSelfValidations(fldPath) } - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema.Items.Schema, fldPath.Child("items"), subSsv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(schema.Items.Schema, fldPath.Child("items"), subSsv, false, opts, celContext.ChildItemsContext(schema.Items.Schema))) if len(schema.Items.JSONSchemas) != 0 { for i, jsonSchema := range schema.Items.JSONSchemas { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(&jsonSchema, fldPath.Child("items").Index(i), subSsv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + itemsSchema := jsonSchema + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(&itemsSchema, fldPath.Child("items").Index(i), subSsv, false, opts, celContext.ChildItemsContext(&itemsSchema))) } } } if schema.Dependencies != nil { for dependency, jsonSchemaPropsOrStringArray := range schema.Dependencies { - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(jsonSchemaPropsOrStringArray.Schema, fldPath.Child("dependencies").Key(dependency), ssv, false, opts, nodeCostInfo.MultiplyByElementCost(schema))...) + allErrs.AppendErrors(ValidateCustomResourceDefinitionOpenAPISchema(jsonSchemaPropsOrStringArray.Schema, fldPath.Child("dependencies").Key(dependency), ssv, false, opts, nil)) } } if schema.XPreserveUnknownFields != nil && *schema.XPreserveUnknownFields == false { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-preserve-unknown-fields"), *schema.XPreserveUnknownFields, "must be true or undefined")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-preserve-unknown-fields"), *schema.XPreserveUnknownFields, "must be true or undefined")) } if schema.XMapType != nil && schema.Type != "object" { if len(schema.Type) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("type"), "must be object if x-kubernetes-map-type is specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("type"), "must be object if x-kubernetes-map-type is specified")) } else { - allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), schema.Type, "must be object if x-kubernetes-map-type is specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("type"), schema.Type, "must be object if x-kubernetes-map-type is specified")) } } if schema.XMapType != nil && *schema.XMapType != "atomic" && *schema.XMapType != "granular" { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("x-kubernetes-map-type"), *schema.XMapType, []string{"atomic", "granular"})) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.NotSupported(fldPath.Child("x-kubernetes-map-type"), *schema.XMapType, []string{"atomic", "granular"})) } if schema.XListType != nil && schema.Type != "array" { if len(schema.Type) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("type"), "must be array if x-kubernetes-list-type is specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("type"), "must be array if x-kubernetes-list-type is specified")) } else { - allErrs = append(allErrs, field.Invalid(fldPath.Child("type"), schema.Type, "must be array if x-kubernetes-list-type is specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("type"), schema.Type, "must be array if x-kubernetes-list-type is specified")) } } else if opts.requireAtomicSetType && schema.XListType != nil && *schema.XListType == "set" && schema.Items != nil && schema.Items.Schema != nil { // by structural schema items are present is := schema.Items.Schema switch is.Type { case "array": if is.XListType != nil && *is.XListType != "atomic" { // atomic is the implicit default behaviour if unset, hence != atomic is wrong - allErrs = append(allErrs, field.Invalid(fldPath.Child("items").Child("x-kubernetes-list-type"), is.XListType, "must be atomic as item of a list with x-kubernetes-list-type=set")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("items").Child("x-kubernetes-list-type"), is.XListType, "must be atomic as item of a list with x-kubernetes-list-type=set")) } case "object": if is.XMapType == nil || *is.XMapType != "atomic" { // granular is the implicit default behaviour if unset, hence nil and != atomic are wrong - allErrs = append(allErrs, field.Invalid(fldPath.Child("items").Child("x-kubernetes-map-type"), is.XListType, "must be atomic as item of a list with x-kubernetes-list-type=set")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("items").Child("x-kubernetes-map-type"), is.XListType, "must be atomic as item of a list with x-kubernetes-list-type=set")) } } } if schema.XListType != nil && *schema.XListType != "atomic" && *schema.XListType != "set" && *schema.XListType != "map" { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("x-kubernetes-list-type"), *schema.XListType, []string{"atomic", "set", "map"})) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.NotSupported(fldPath.Child("x-kubernetes-list-type"), *schema.XListType, []string{"atomic", "set", "map"})) } if len(schema.XListMapKeys) > 0 { if schema.XListType == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("x-kubernetes-list-type"), "must be map if x-kubernetes-list-map-keys is non-empty")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("x-kubernetes-list-type"), "must be map if x-kubernetes-list-map-keys is non-empty")) } else if *schema.XListType != "map" { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-list-type"), *schema.XListType, "must be map if x-kubernetes-list-map-keys is non-empty")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-list-type"), *schema.XListType, "must be map if x-kubernetes-list-map-keys is non-empty")) } } if schema.XListType != nil && *schema.XListType == "map" { if len(schema.XListMapKeys) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("x-kubernetes-list-map-keys"), "must not be empty if x-kubernetes-list-type is map")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("x-kubernetes-list-map-keys"), "must not be empty if x-kubernetes-list-type is map")) } if schema.Items == nil { - allErrs = append(allErrs, field.Required(fldPath.Child("items"), "must have a schema if x-kubernetes-list-type is map")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("items"), "must have a schema if x-kubernetes-list-type is map")) } if schema.Items != nil && schema.Items.Schema == nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("items"), schema.Items, "must only have a single schema if x-kubernetes-list-type is map")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("items"), schema.Items, "must only have a single schema if x-kubernetes-list-type is map")) } if schema.Items != nil && schema.Items.Schema != nil && schema.Items.Schema.Type != "object" { - allErrs = append(allErrs, field.Invalid(fldPath.Child("items").Child("type"), schema.Items.Schema.Type, "must be object if parent array's x-kubernetes-list-type is map")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("items").Child("type"), schema.Items.Schema.Type, "must be object if parent array's x-kubernetes-list-type is map")) } if schema.Items != nil && schema.Items.Schema != nil && schema.Items.Schema.Type == "object" { @@ -1067,59 +984,90 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch for _, k := range schema.XListMapKeys { if s, ok := schema.Items.Schema.Properties[k]; ok { if s.Type == "array" || s.Type == "object" { - allErrs = append(allErrs, field.Invalid(fldPath.Child("items").Child("properties").Key(k).Child("type"), schema.Items.Schema.Type, "must be a scalar type if parent array's x-kubernetes-list-type is map")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("items").Child("properties").Key(k).Child("type"), schema.Items.Schema.Type, "must be a scalar type if parent array's x-kubernetes-list-type is map")) } } else { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-list-map-keys"), schema.XListMapKeys, "entries must all be names of item properties")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-list-map-keys"), schema.XListMapKeys, "entries must all be names of item properties")) } if _, ok := keys[k]; ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-list-map-keys"), schema.XListMapKeys, "must not contain duplicate entries")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-list-map-keys"), schema.XListMapKeys, "must not contain duplicate entries")) } keys[k] = struct{}{} } } } + if opts.requireMapListKeysMapSetValidation { + allErrs.SchemaErrors = append(allErrs.SchemaErrors, validateMapListKeysMapSet(schema, fldPath)...) + } + if len(schema.XValidations) > 0 { for i, rule := range schema.XValidations { trimmedRule := strings.TrimSpace(rule.Rule) trimmedMsg := strings.TrimSpace(rule.Message) + trimmedMsgExpr := strings.TrimSpace(rule.MessageExpression) if len(trimmedRule) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), "rule is not specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), "rule is not specified")) } else if len(rule.Message) > 0 && len(trimmedMsg) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), rule.Message, "message must be non-empty if specified")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), rule.Message, "message must be non-empty if specified")) } else if hasNewlines(trimmedMsg) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), rule.Message, "message must not contain line breaks")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), rule.Message, "message must not contain line breaks")) } else if hasNewlines(trimmedRule) && len(trimmedMsg) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), "message must be specified if rule contains line breaks")) + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("message"), "message must be specified if rule contains line breaks")) + } + if len(rule.MessageExpression) > 0 && len(trimmedMsgExpr) == 0 { + allErrs.SchemaErrors = append(allErrs.SchemaErrors, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("messageExpression"), "messageExpression must be non-empty if specified")) } } - structural, err := structuralschema.NewStructural(schema) - if err == nil { - compResults, err := cel.Compile(structural, isRoot, cel.PerCallLimit) + // If any schema related validation errors have been found at this level or deeper, skip CEL expression validation. + // Invalid OpenAPISchemas are not always possible to convert into valid CEL DeclTypes, and can lead to CEL + // validation error messages that are not actionable (will go away once the schema errors are resolved) and that + // are difficult for CEL expression authors to understand. + if len(allErrs.SchemaErrors) == 0 && celContext != nil { + typeInfo, err := celContext.TypeInfo() if err != nil { - allErrs = append(allErrs, field.InternalError(fldPath.Child("x-kubernetes-validations"), err)) + allErrs.CELErrors = append(allErrs.CELErrors, field.InternalError(fldPath.Child("x-kubernetes-validations"), fmt.Errorf("internal error: failed to construct type information for x-kubernetes-validations rules: %s", err))) + } else if typeInfo == nil { + allErrs.CELErrors = append(allErrs.CELErrors, field.InternalError(fldPath.Child("x-kubernetes-validations"), fmt.Errorf("internal error: failed to retrieve type information for x-kubernetes-validations"))) } else { - for i, cr := range compResults { - expressionCost := getExpressionCost(cr, nodeCostInfo) - if expressionCost > StaticEstimatedCostLimit { - costErrorMsg := getCostErrorMessage("estimated rule cost", expressionCost, StaticEstimatedCostLimit) - allErrs = append(allErrs, field.Forbidden(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), costErrorMsg)) - } - if nodeCostInfo.TotalCost != nil { - nodeCostInfo.TotalCost.observeExpressionCost(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), expressionCost) - } - if cr.Error != nil { - if cr.Error.Type == cel.ErrorTypeRequired { - allErrs = append(allErrs, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), cr.Error.Detail)) + compResults, err := cel.Compile(typeInfo.Schema, typeInfo.DeclType, celconfig.PerCallLimit) + if err != nil { + allErrs.CELErrors = append(allErrs.CELErrors, field.InternalError(fldPath.Child("x-kubernetes-validations"), err)) + } else { + for i, cr := range compResults { + expressionCost := getExpressionCost(cr, celContext) + if expressionCost > StaticEstimatedCostLimit { + costErrorMsg := getCostErrorMessage("estimated rule cost", expressionCost, StaticEstimatedCostLimit) + allErrs.CELErrors = append(allErrs.CELErrors, field.Forbidden(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), costErrorMsg)) + } + if celContext.TotalCost != nil { + celContext.TotalCost.ObserveExpressionCost(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), expressionCost) + } + if cr.Error != nil { + if cr.Error.Type == apiservercel.ErrorTypeRequired { + allErrs.CELErrors = append(allErrs.CELErrors, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), cr.Error.Detail)) + } else { + allErrs.CELErrors = append(allErrs.CELErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), schema.XValidations[i], cr.Error.Detail)) + } + } + if cr.MessageExpressionError != nil { + allErrs.CELErrors = append(allErrs.CELErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("messageExpression"), schema.XValidations[i], cr.MessageExpressionError.Detail)) } else { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), schema.XValidations[i], cr.Error.Detail)) + if cr.MessageExpression != nil { + if cr.MessageExpressionMaxCost > StaticEstimatedCostLimit { + costErrorMsg := getCostErrorMessage("estimated messageExpression cost", cr.MessageExpressionMaxCost, StaticEstimatedCostLimit) + allErrs.CELErrors = append(allErrs.CELErrors, field.Forbidden(fldPath.Child("x-kubernetes-validations").Index(i).Child("messageExpression"), costErrorMsg)) + } + if celContext.TotalCost != nil { + celContext.TotalCost.ObserveExpressionCost(fldPath.Child("x-kubernetes-validations").Index(i).Child("messageExpression"), cr.MessageExpressionMaxCost) + } + } } - } - if cr.TransitionRule { - if uncorrelatablePath := ssv.forbidOldSelfValidations(); uncorrelatablePath != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), schema.XValidations[i].Rule, fmt.Sprintf("oldSelf cannot be used on the uncorrelatable portion of the schema within %v", uncorrelatablePath))) + if cr.TransitionRule { + if uncorrelatablePath := ssv.forbidOldSelfValidations(); uncorrelatablePath != nil { + allErrs.CELErrors = append(allErrs.CELErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), schema.XValidations[i].Rule, fmt.Sprintf("oldSelf cannot be used on the uncorrelatable portion of the schema within %v", uncorrelatablePath))) + } } } } @@ -1127,10 +1075,6 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch } } - if opts.requireMapListKeysMapSetValidation { - allErrs = append(allErrs, validateMapListKeysMapSet(schema, fldPath)...) - } - return allErrs } @@ -1146,7 +1090,7 @@ func multiplyWithOverflowGuard(baseCost, cardinality uint64) uint64 { return baseCost * cardinality } -func getExpressionCost(cr cel.CompilationResult, cardinalityCost costInfo) uint64 { +func getExpressionCost(cr cel.CompilationResult, cardinalityCost *CELSchemaContext) uint64 { if cardinalityCost.MaxCardinality != unbounded { return multiplyWithOverflowGuard(cr.MaxCost, *cardinalityCost.MaxCardinality) } @@ -1439,6 +1383,27 @@ func HasSchemaWith(spec *apiextensions.CustomResourceDefinitionSpec, pred func(s return false } +var schemaPool = sync.Pool{ + New: func() any { + return new(apiextensions.JSONSchemaProps) + }, +} + +func schemaHasRecurse(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSONSchemaProps) bool) bool { + if s == nil { + return false + } + schema := schemaPool.Get().(*apiextensions.JSONSchemaProps) + defer schemaPool.Put(schema) + *schema = *s + return SchemaHas(schema, pred) +} + +// SchemaHas recursively traverses the Schema and calls the `pred` +// predicate to see if the schema contains specific values. +// +// The predicate MUST NOT keep a copy of the json schema NOR modify the +// schema. func SchemaHas(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSONSchemaProps) bool) bool { if s == nil { return false @@ -1449,60 +1414,60 @@ func SchemaHas(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSON } if s.Items != nil { - if s.Items != nil && SchemaHas(s.Items.Schema, pred) { + if s.Items != nil && schemaHasRecurse(s.Items.Schema, pred) { return true } - for _, s := range s.Items.JSONSchemas { - if SchemaHas(&s, pred) { + for i := range s.Items.JSONSchemas { + if schemaHasRecurse(&s.Items.JSONSchemas[i], pred) { return true } } } - for _, s := range s.AllOf { - if SchemaHas(&s, pred) { + for i := range s.AllOf { + if schemaHasRecurse(&s.AllOf[i], pred) { return true } } - for _, s := range s.AnyOf { - if SchemaHas(&s, pred) { + for i := range s.AnyOf { + if schemaHasRecurse(&s.AnyOf[i], pred) { return true } } - for _, s := range s.OneOf { - if SchemaHas(&s, pred) { + for i := range s.OneOf { + if schemaHasRecurse(&s.OneOf[i], pred) { return true } } - if SchemaHas(s.Not, pred) { + if schemaHasRecurse(s.Not, pred) { return true } for _, s := range s.Properties { - if SchemaHas(&s, pred) { + if schemaHasRecurse(&s, pred) { return true } } if s.AdditionalProperties != nil { - if SchemaHas(s.AdditionalProperties.Schema, pred) { + if schemaHasRecurse(s.AdditionalProperties.Schema, pred) { return true } } for _, s := range s.PatternProperties { - if SchemaHas(&s, pred) { + if schemaHasRecurse(&s, pred) { return true } } if s.AdditionalItems != nil { - if SchemaHas(s.AdditionalItems.Schema, pred) { + if schemaHasRecurse(s.AdditionalItems.Schema, pred) { return true } } for _, s := range s.Definitions { - if SchemaHas(&s, pred) { + if schemaHasRecurse(&s, pred) { return true } } for _, d := range s.Dependencies { - if SchemaHas(d.Schema, pred) { + if schemaHasRecurse(d.Schema, pred) { return true } } @@ -1681,7 +1646,7 @@ func validatePreserveUnknownFields(crd, oldCRD *apiextensions.CustomResourceDefi var errs field.ErrorList if crd != nil && crd.Spec.PreserveUnknownFields != nil && *crd.Spec.PreserveUnknownFields { // disallow changing spec.preserveUnknownFields=false to spec.preserveUnknownFields=true - errs = append(errs, field.Invalid(field.NewPath("spec").Child("preserveUnknownFields"), crd.Spec.PreserveUnknownFields, "cannot set to true, set x-preserve-unknown-fields to true in spec.versions[*].schema instead")) + errs = append(errs, field.Invalid(field.NewPath("spec").Child("preserveUnknownFields"), crd.Spec.PreserveUnknownFields, "cannot set to true, set x-kubernetes-preserve-unknown-fields to true in spec.versions[*].schema instead")) } return errs } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go index 61b0eee0602..35d5d604335 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go @@ -19,18 +19,18 @@ package cel import ( "fmt" "strings" + "sync" "time" "github.com/google/cel-go/cel" "github.com/google/cel-go/checker" - "github.com/google/cel-go/checker/decls" - expr "google.golang.org/genproto/googleapis/api/expr/v1alpha1" - "google.golang.org/protobuf/proto" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" - "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library" - celmodel "k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model" + celconfig "k8s.io/apiserver/pkg/apis/cel" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/library" + "k8s.io/apiserver/pkg/cel/metrics" ) const ( @@ -41,24 +41,12 @@ const ( // OldScopedVarName is the variable name assigned to the existing value of the locally scoped data element of a // CEL validation expression. OldScopedVarName = "oldSelf" - - // PerCallLimit specify the actual cost limit per CEL validation call - // current PerCallLimit gives roughly 0.1 second for each expression validation call - PerCallLimit = 1000000 - - // RuntimeCELCostBudget is the overall cost budget for runtime CEL validation cost per CustomResource - // current RuntimeCELCostBudget gives roughly 1 seconds for CR validation - RuntimeCELCostBudget = 10000000 - - // checkFrequency configures the number of iterations within a comprehension to evaluate - // before checking whether the function evaluation has been interrupted - checkFrequency = 100 ) // CompilationResult represents the cel compilation result for one rule type CompilationResult struct { Program cel.Program - Error *Error + Error *apiservercel.Error // If true, the compiled expression contains a reference to the identifier "oldSelf", and its corresponding rule // is implicitly a transition rule. TransitionRule bool @@ -67,63 +55,98 @@ type CompilationResult struct { // MaxCardinality represents the worse case number of times this validation rule could be invoked if contained under an // unbounded map or list in an OpenAPIv3 schema. MaxCardinality uint64 + // MessageExpression represents the cel Program that should be evaluated to generate an error message if the rule + // fails to validate. If no MessageExpression was given, or if this expression failed to compile, this will be nil. + MessageExpression cel.Program + // MessageExpressionError represents an error encountered during compilation of MessageExpression. If no error was + // encountered, this will be nil. + MessageExpressionError *apiservercel.Error + // MessageExpressionMaxCost represents the worst-case cost of the compiled MessageExpression in terms of CEL's cost units, + // as used by cel.EstimateCost. + MessageExpressionMaxCost uint64 +} + +var ( + initEnvOnce sync.Once + initEnv *cel.Env + initEnvErr error +) + +// This func is duplicated in k8s.io/apiserver/pkg/admission/plugin/cel/validator.go +// If any changes are made here, consider to make the same changes there as well. +func getBaseEnv() (*cel.Env, error) { + initEnvOnce.Do(func() { + var opts []cel.EnvOption + opts = append(opts, cel.HomogeneousAggregateLiterals()) + // Validate function declarations once during base env initialization, + // so they don't need to be evaluated each time a CEL rule is compiled. + // This is a relatively expensive operation. + opts = append(opts, cel.EagerlyValidateDeclarations(true), cel.DefaultUTCTimeZone(true)) + opts = append(opts, library.ExtensionLibs...) + + initEnv, initEnvErr = cel.NewEnv(opts...) + }) + return initEnv, initEnvErr } // Compile compiles all the XValidations rules (without recursing into the schema) and returns a slice containing a -// CompilationResult for each ValidationRule, or an error. +// CompilationResult for each ValidationRule, or an error. declType is expected to be a CEL DeclType corresponding +// to the structural schema. // Each CompilationResult may contain: -/// - non-nil Program, nil Error: The program was compiled successfully -// - nil Program, non-nil Error: Compilation resulted in an error -// - nil Program, nil Error: The provided rule was empty so compilation was not attempted -// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit as input. -func Compile(s *schema.Structural, isResourceRoot bool, perCallLimit uint64) ([]CompilationResult, error) { +// - non-nil Program, nil Error: The program was compiled successfully +// - nil Program, non-nil Error: Compilation resulted in an error +// - nil Program, nil Error: The provided rule was empty so compilation was not attempted +// +// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func Compile(s *schema.Structural, declType *apiservercel.DeclType, perCallLimit uint64) ([]CompilationResult, error) { + t := time.Now() + defer func() { + metrics.Metrics.ObserveCompilation(time.Since(t)) + }() + if len(s.Extensions.XValidations) == 0 { return nil, nil } celRules := s.Extensions.XValidations - var propDecls []*expr.Decl - var root *celmodel.DeclType + var propDecls []cel.EnvOption + var root *apiservercel.DeclType var ok bool - env, err := cel.NewEnv( - cel.HomogeneousAggregateLiterals(), - ) + baseEnv, err := getBaseEnv() if err != nil { return nil, err } - reg := celmodel.NewRegistry(env) + reg := apiservercel.NewRegistry(baseEnv) scopedTypeName := generateUniqueSelfTypeName() - rt, err := celmodel.NewRuleTypes(scopedTypeName, s, isResourceRoot, reg) + rt, err := apiservercel.NewRuleTypes(scopedTypeName, declType, reg) if err != nil { return nil, err } if rt == nil { return nil, nil } - opts, err := rt.EnvOptions(env.TypeProvider()) + opts, err := rt.EnvOptions(baseEnv.TypeProvider()) if err != nil { return nil, err } root, ok = rt.FindDeclType(scopedTypeName) if !ok { - rootDecl := celmodel.SchemaDeclType(s, isResourceRoot) - if rootDecl == nil { + if declType == nil { return nil, fmt.Errorf("rule declared on schema that does not support validation rules type: '%s' x-kubernetes-preserve-unknown-fields: '%t'", s.Type, s.XPreserveUnknownFields) } - root = rootDecl.MaybeAssignTypeName(scopedTypeName) + root = declType.MaybeAssignTypeName(scopedTypeName) } - propDecls = append(propDecls, decls.NewVar(ScopedVarName, root.ExprType())) - propDecls = append(propDecls, decls.NewVar(OldScopedVarName, root.ExprType())) - opts = append(opts, cel.Declarations(propDecls...), cel.HomogeneousAggregateLiterals()) - opts = append(opts, library.ExtensionLibs...) - env, err = env.Extend(opts...) + propDecls = append(propDecls, cel.Variable(ScopedVarName, root.CelType())) + propDecls = append(propDecls, cel.Variable(OldScopedVarName, root.CelType())) + opts = append(opts, propDecls...) + env, err := baseEnv.Extend(opts...) if err != nil { return nil, err } estimator := newCostEstimator(root) // compResults is the return value which saves a list of compilation results in the same order as x-kubernetes-validations rules. compResults := make([]CompilationResult, len(celRules)) - maxCardinality := celmodel.MaxCardinality(s) + maxCardinality := maxCardinality(root.MinSerializedSize) for i, rule := range celRules { compResults[i] = compileRule(rule, env, perCallLimit, estimator, maxCardinality) } @@ -139,18 +162,18 @@ func compileRule(rule apiextensions.ValidationRule, env *cel.Env, perCallLimit u } ast, issues := env.Compile(rule.Rule) if issues != nil { - compilationResult.Error = &Error{ErrorTypeInvalid, "compilation failed: " + issues.String()} + compilationResult.Error = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "compilation failed: " + issues.String()} return } - if !proto.Equal(ast.ResultType(), decls.Bool) { - compilationResult.Error = &Error{ErrorTypeInvalid, "cel expression must evaluate to a bool"} + if ast.OutputType() != cel.BoolType { + compilationResult.Error = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "cel expression must evaluate to a bool"} return } checkedExpr, err := cel.AstToCheckedExpr(ast) if err != nil { // should be impossible since env.Compile returned no issues - compilationResult.Error = &Error{ErrorTypeInternal, "unexpected compilation error: " + err.Error()} + compilationResult.Error = &apiservercel.Error{Type: apiservercel.ErrorTypeInternal, Detail: "unexpected compilation error: " + err.Error()} return } for _, ref := range checkedExpr.ReferenceMap { @@ -166,20 +189,56 @@ func compileRule(rule apiextensions.ValidationRule, env *cel.Env, perCallLimit u cel.CostLimit(perCallLimit), cel.CostTracking(estimator), cel.OptimizeRegex(library.ExtensionLibRegexOptimizations...), - cel.InterruptCheckFrequency(checkFrequency), + cel.InterruptCheckFrequency(celconfig.CheckFrequency), ) if err != nil { - compilationResult.Error = &Error{ErrorTypeInvalid, "program instantiation failed: " + err.Error()} + compilationResult.Error = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "program instantiation failed: " + err.Error()} return } costEst, err := env.EstimateCost(ast, estimator) if err != nil { - compilationResult.Error = &Error{ErrorTypeInternal, "cost estimation failed: " + err.Error()} + compilationResult.Error = &apiservercel.Error{Type: apiservercel.ErrorTypeInternal, Detail: "cost estimation failed: " + err.Error()} return } compilationResult.MaxCost = costEst.Max compilationResult.MaxCardinality = maxCardinality compilationResult.Program = prog + if rule.MessageExpression != "" { + ast, issues := env.Compile(rule.MessageExpression) + if issues != nil { + compilationResult.MessageExpressionError = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "messageExpression compilation failed: " + issues.String()} + return + } + if ast.OutputType() != cel.StringType { + compilationResult.MessageExpressionError = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "messageExpression must evaluate to a string"} + return + } + + _, err := cel.AstToCheckedExpr(ast) + if err != nil { + compilationResult.MessageExpressionError = &apiservercel.Error{Type: apiservercel.ErrorTypeInternal, Detail: "unexpected messageExpression compilation error: " + err.Error()} + return + } + + msgProg, err := env.Program(ast, + cel.EvalOptions(cel.OptOptimize, cel.OptTrackCost), + cel.CostLimit(perCallLimit), + cel.CostTracking(estimator), + cel.OptimizeRegex(library.ExtensionLibRegexOptimizations...), + cel.InterruptCheckFrequency(celconfig.CheckFrequency), + ) + if err != nil { + compilationResult.MessageExpressionError = &apiservercel.Error{Type: apiservercel.ErrorTypeInvalid, Detail: "messageExpression instantiation failed: " + err.Error()} + return + } + costEst, err := env.EstimateCost(ast, estimator) + if err != nil { + compilationResult.MessageExpressionError = &apiservercel.Error{Type: apiservercel.ErrorTypeInternal, Detail: "cost estimation failed for messageExpression: " + err.Error()} + return + } + compilationResult.MessageExpression = msgProg + compilationResult.MessageExpressionMaxCost = costEst.Max + } return } @@ -191,12 +250,12 @@ func generateUniqueSelfTypeName() string { return fmt.Sprintf("selfType%d", time.Now().Nanosecond()) } -func newCostEstimator(root *celmodel.DeclType) *library.CostEstimator { +func newCostEstimator(root *apiservercel.DeclType) *library.CostEstimator { return &library.CostEstimator{SizeEstimator: &sizeEstimator{root: root}} } type sizeEstimator struct { - root *celmodel.DeclType + root *apiservercel.DeclType } func (c *sizeEstimator) EstimateSize(element checker.AstNode) *checker.SizeEstimate { @@ -236,3 +295,14 @@ func (c *sizeEstimator) EstimateSize(element checker.AstNode) *checker.SizeEstim func (c *sizeEstimator) EstimateCallCost(function, overloadID string, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { return nil } + +// maxCardinality returns the maximum number of times data conforming to the minimum size given could possibly exist in +// an object serialized to JSON. For cases where a schema is contained under map or array schemas of unbounded +// size, this can be used as an estimate as the worst case number of times data matching the schema could be repeated. +// Note that this only assumes a single comma between data elements, so if the schema is contained under only maps, +// this estimates a higher cardinality that would be possible. DeclType.MinSerializedSize is meant to be passed to +// this function. +func maxCardinality(minSize int64) uint64 { + sz := minSize + 1 // assume at least one comma between elements + return uint64(celconfig.MaxRequestSizeBytes / sz) +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/lists.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/lists.go deleted file mode 100644 index 1c0f60b5b00..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/lists.go +++ /dev/null @@ -1,386 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package library - -import ( - "fmt" - - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - "github.com/google/cel-go/interpreter/functions" - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" -) - -// Lists provides a CEL function library extension of list utility functions. -// -// isSorted -// -// Returns true if the provided list of comparable elements is sorted, else returns false. -// -// >.isSorted() , T must be a comparable type -// -// Examples: -// -// [1, 2, 3].isSorted() // return true -// ['a', 'b', 'b', 'c'].isSorted() // return true -// [2.0, 1.0].isSorted() // return false -// [1].isSorted() // return true -// [].isSorted() // return true -// -// -// sum -// -// Returns the sum of the elements of the provided list. Supports CEL number (int, uint, double) and duration types. -// -// >.sum() , T must be a numeric type or a duration -// -// Examples: -// -// [1, 3].sum() // returns 4 -// [1.0, 3.0].sum() // returns 4.0 -// ['1m', '1s'].sum() // returns '1m1s' -// emptyIntList.sum() // returns 0 -// emptyDoubleList.sum() // returns 0.0 -// [].sum() // returns 0 -// -// -// min / max -// -// Returns the minimum/maximum valued element of the provided list. Supports all comparable types. -// If the list is empty, an error is returned. -// -// >.min() , T must be a comparable type -// >.max() , T must be a comparable type -// -// Examples: -// -// [1, 3].min() // returns 1 -// [1, 3].max() // returns 3 -// [].min() // error -// [1].min() // returns 1 -// ([0] + emptyList).min() // returns 0 -// -// -// indexOf / lastIndexOf -// -// Returns either the first or last positional index of the provided element in the list. -// If the element is not found, -1 is returned. Supports all equatable types. -// -// >.indexOf() , T must be an equatable type -// >.lastIndexOf() , T must be an equatable type -// -// Examples: -// -// [1, 2, 2, 3].indexOf(2) // returns 1 -// ['a', 'b', 'b', 'c'].lastIndexOf('b') // returns 2 -// [1.0].indexOf(1.1) // returns -1 -// [].indexOf('string') // returns -1 -// -func Lists() cel.EnvOption { - return cel.Lib(listsLib) -} - -var listsLib = &lists{} - -type lists struct{} - -var paramA = decls.NewTypeParamType("A") - -// CEL typeParams can be used to constraint to a specific trait (e.g. traits.ComparableType) if the 1st operand is the type to constrain. -// But the functions we need to constrain are >, not just . -var summableTypes = map[string]*exprpb.Type{"int": decls.Int, "uint": decls.Uint, "double": decls.Double, "duration": decls.Duration} -var comparableTypes = map[string]*exprpb.Type{"bool": decls.Bool, "int": decls.Int, "uint": decls.Uint, "double": decls.Double, - "duration": decls.Duration, "timestamp": decls.Timestamp, "string": decls.String, "bytes": decls.Bytes} - -// WARNING: All library additions or modifications must follow -// https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2876-crd-validation-expression-language#function-library-updates -var listsLibraryDecls = []*exprpb.Decl{ - decls.NewFunction("isSorted", - templatedOverloads(comparableTypes, func(name string, paramType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { - return decls.NewInstanceOverload(fmt.Sprintf("list_%s_is_sorted_bool", name), - []*exprpb.Type{decls.NewListType(paramType)}, - decls.Bool) - })..., - ), - decls.NewFunction("sum", - templatedOverloads(summableTypes, func(name string, paramType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { - return decls.NewInstanceOverload(fmt.Sprintf("list_%s_sum_%s", name, name), - []*exprpb.Type{decls.NewListType(paramType)}, - paramType) - })..., - ), - decls.NewFunction("max", - templatedOverloads(comparableTypes, func(name string, paramType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { - return decls.NewInstanceOverload(fmt.Sprintf("list_%s_max_%s", name, name), - []*exprpb.Type{decls.NewListType(paramType)}, - paramType) - })..., - ), - decls.NewFunction("min", - templatedOverloads(comparableTypes, func(name string, paramType *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload { - return decls.NewInstanceOverload(fmt.Sprintf("list_%s_min_%s", name, name), - []*exprpb.Type{decls.NewListType(paramType)}, - paramType) - })..., - ), - decls.NewFunction("indexOf", - decls.NewInstanceOverload("list_a_index_of_int", - []*exprpb.Type{decls.NewListType(paramA), paramA}, - decls.Int), - ), - decls.NewFunction("lastIndexOf", - decls.NewInstanceOverload("list_a_last_index_of_int", - []*exprpb.Type{decls.NewListType(paramA), paramA}, - decls.Int), - ), -} - -func (*lists) CompileOptions() []cel.EnvOption { - return []cel.EnvOption{ - cel.Declarations(listsLibraryDecls...), - } -} - -func (*lists) ProgramOptions() []cel.ProgramOption { - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "isSorted", - Unary: isSorted, - }, - // if 'sum' is called directly, it is via dynamic dispatch, and we infer the type from the 1st element of the - // list if it has one, otherwise we return int64(0) - &functions.Overload{ - Operator: "sum", - Unary: dynSum(), - }, - // use overload names for sum so an initial accumulator value can be assigned to each - &functions.Overload{ - Operator: "list_int_sum_int", - Unary: sum(func() ref.Val { - return types.Int(0) - }), - }, - &functions.Overload{ - Operator: "list_uint_sum_uint", - Unary: sum(func() ref.Val { - return types.Uint(0) - }), - }, - &functions.Overload{ - Operator: "list_double_sum_double", - Unary: sum(func() ref.Val { - return types.Double(0.0) - }), - }, - &functions.Overload{ - Operator: "list_duration_sum_duration", - Unary: sum(func() ref.Val { - return types.Duration{Duration: 0} - }), - }, - &functions.Overload{ - Operator: "max", - Unary: max(), - }, - &functions.Overload{ - Operator: "min", - Unary: min(), - }, - // use overload names for indexOf and lastIndexOf to de-conflict with function of same name in strings extension library - &functions.Overload{ - Operator: "list_a_index_of_int", - Binary: indexOf, - }, - &functions.Overload{ - Operator: "list_a_last_index_of_int", - Binary: lastIndexOf, - }, - ), - } -} - -func isSorted(val ref.Val) ref.Val { - var prev traits.Comparer - iterable, ok := val.(traits.Iterable) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - for it := iterable.Iterator(); it.HasNext() == types.True; { - next := it.Next() - nextCmp, ok := next.(traits.Comparer) - if !ok { - return types.MaybeNoSuchOverloadErr(next) - } - if prev != nil { - cmp := prev.Compare(next) - if cmp == types.IntOne { - return types.False - } - } - prev = nextCmp - } - return types.True -} - -func dynSum() functions.UnaryOp { - return func(val ref.Val) ref.Val { - iterable, ok := val.(traits.Iterable) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - it := iterable.Iterator() - var initval ref.Val - if it.HasNext() == types.True { - first := it.Next() - switch first.Type() { - case types.IntType: - initval = types.Int(0) - case types.UintType: - initval = types.Uint(0) - case types.DoubleType: - initval = types.Double(0.0) - case types.DurationType: - initval = types.Duration{Duration: 0} - default: - return types.MaybeNoSuchOverloadErr(first) - } - } else { - initval = types.Int(0) - } - initFn := func() ref.Val { - return initval - } - return sum(initFn)(val) - } -} - -func sum(init func() ref.Val) functions.UnaryOp { - return func(val ref.Val) ref.Val { - i := init() - acc, ok := i.(traits.Adder) - if !ok { - // Should never happen since all passed in init values are valid - return types.MaybeNoSuchOverloadErr(i) - } - iterable, ok := val.(traits.Iterable) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - for it := iterable.Iterator(); it.HasNext() == types.True; { - next := it.Next() - nextAdder, ok := next.(traits.Adder) - if !ok { - // Should never happen for type checked CEL programs - return types.MaybeNoSuchOverloadErr(next) - } - if acc != nil { - s := acc.Add(next) - sum, ok := s.(traits.Adder) - if !ok { - // Should never happen for type checked CEL programs - return types.MaybeNoSuchOverloadErr(s) - } - acc = sum - } else { - acc = nextAdder - } - } - return acc.(ref.Val) - } -} - -func min() functions.UnaryOp { - return cmp("min", types.IntOne) -} - -func max() functions.UnaryOp { - return cmp("max", types.IntNegOne) -} - -func cmp(opName string, opPreferCmpResult ref.Val) functions.UnaryOp { - return func(val ref.Val) ref.Val { - var result traits.Comparer - iterable, ok := val.(traits.Iterable) - if !ok { - return types.MaybeNoSuchOverloadErr(val) - } - for it := iterable.Iterator(); it.HasNext() == types.True; { - next := it.Next() - nextCmp, ok := next.(traits.Comparer) - if !ok { - // Should never happen for type checked CEL programs - return types.MaybeNoSuchOverloadErr(next) - } - if result == nil { - result = nextCmp - } else { - cmp := result.Compare(next) - if cmp == opPreferCmpResult { - result = nextCmp - } - } - } - if result == nil { - return types.NewErr("%s called on empty list", opName) - } - return result.(ref.Val) - } -} - -func indexOf(list ref.Val, item ref.Val) ref.Val { - lister, ok := list.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(list) - } - sz := lister.Size().(types.Int) - for i := types.Int(0); i < sz; i++ { - if lister.Get(types.Int(i)).Equal(item) == types.True { - return types.Int(i) - } - } - return types.Int(-1) -} - -func lastIndexOf(list ref.Val, item ref.Val) ref.Val { - lister, ok := list.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(list) - } - sz := lister.Size().(types.Int) - for i := sz - 1; i >= 0; i-- { - if lister.Get(types.Int(i)).Equal(item) == types.True { - return types.Int(i) - } - } - return types.Int(-1) -} - -// templatedOverloads returns overloads for each of the provided types. The template function is called with each type -// name (map key) and type to construct the overloads. -func templatedOverloads(types map[string]*exprpb.Type, template func(name string, t *exprpb.Type) *exprpb.Decl_FunctionDecl_Overload) []*exprpb.Decl_FunctionDecl_Overload { - overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(types)) - i := 0 - for name, t := range types { - overloads[i] = template(name, t) - i++ - } - return overloads -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/regex.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/regex.go deleted file mode 100644 index e44f82090ab..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/regex.go +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package library - -import ( - "regexp" - - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/interpreter/functions" - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" -) - -// Regex provides a CEL function library extension of regex utility functions. -// -// find / findAll -// -// Returns substrings that match the provided regular expression. find returns the first match. findAll may optionally -// be provided a limit. If the limit is set and >= 0, no more than the limit number of matches are returned. -// -// .find() -// .findAll() > -// .findAll(, ) > -// -// Examples: -// -// "abc 123".find('[0-9]*') // returns '123' -// "abc 123".find('xyz') // returns '' -// "123 abc 456".findAll('[0-9]*') // returns ['123', '456'] -// "123 abc 456".findAll('[0-9]*', 1) // returns ['123'] -// "123 abc 456".findAll('xyz') // returns [] -// -func Regex() cel.EnvOption { - return cel.Lib(regexLib) -} - -var regexLib = ®ex{} - -type regex struct{} - -var regexLibraryDecls = []*exprpb.Decl{ - - decls.NewFunction("find", - decls.NewInstanceOverload("string_find_string", - []*exprpb.Type{decls.String, decls.String}, - decls.String), - ), - decls.NewFunction("findAll", - decls.NewInstanceOverload("string_find_all_string", - []*exprpb.Type{decls.String, decls.String}, - decls.NewListType(decls.String)), - decls.NewInstanceOverload("string_find_all_string_int", - []*exprpb.Type{decls.String, decls.String, decls.Int}, - decls.NewListType(decls.String)), - ), -} - -func (*regex) CompileOptions() []cel.EnvOption { - return []cel.EnvOption{ - cel.Declarations(regexLibraryDecls...), - } -} - -func (*regex) ProgramOptions() []cel.ProgramOption { - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "find", - Binary: find, - }, - &functions.Overload{ - Operator: "string_find_string", - Binary: find, - }, - &functions.Overload{ - Operator: "findAll", - Binary: func(str, regex ref.Val) ref.Val { - return findAll(str, regex, types.Int(-1)) - }, - Function: findAll, - }, - &functions.Overload{ - Operator: "string_find_all_string", - Binary: func(str, regex ref.Val) ref.Val { - return findAll(str, regex, types.Int(-1)) - }, - }, - &functions.Overload{ - Operator: "string_find_all_string_int", - Function: findAll, - }, - ), - } -} - -func find(strVal ref.Val, regexVal ref.Val) ref.Val { - str, ok := strVal.Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(strVal) - } - regex, ok := regexVal.Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(regexVal) - } - re, err := regexp.Compile(regex) - if err != nil { - return types.NewErr("Illegal regex: %v", err.Error()) - } - result := re.FindString(str) - return types.String(result) -} - -func findAll(args ...ref.Val) ref.Val { - argn := len(args) - if argn < 2 || argn > 3 { - return types.NoSuchOverloadErr() - } - str, ok := args[0].Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - regex, ok := args[1].Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(args[1]) - } - n := int64(-1) - if argn == 3 { - n, ok = args[2].Value().(int64) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - } - - re, err := regexp.Compile(regex) - if err != nil { - return types.NewErr("Illegal regex: %v", err.Error()) - } - - result := re.FindAllString(str, int(n)) - - return types.NewStringList(types.DefaultTypeAdapter, result) -} - -// FindRegexOptimization optimizes the 'find' function by compiling the regex pattern and -// reporting any compilation errors at program creation time, and using the compiled regex pattern for all function -// call invocations. -var FindRegexOptimization = &interpreter.RegexOptimization{ - Function: "find", - RegexIndex: 1, - Factory: func(call interpreter.InterpretableCall, regexPattern string) (interpreter.InterpretableCall, error) { - compiledRegex, err := regexp.Compile(regexPattern) - if err != nil { - return nil, err - } - return interpreter.NewCall(call.ID(), call.Function(), call.OverloadID(), call.Args(), func(args ...ref.Val) ref.Val { - if len(args) != 2 { - return types.NoSuchOverloadErr() - } - in, ok := args[0].Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - return types.String(compiledRegex.FindString(in)) - }), nil - }, -} - -// FindAllRegexOptimization optimizes the 'findAll' function by compiling the regex pattern and -// reporting any compilation errors at program creation time, and using the compiled regex pattern for all function -// call invocations. -var FindAllRegexOptimization = &interpreter.RegexOptimization{ - Function: "findAll", - RegexIndex: 1, - Factory: func(call interpreter.InterpretableCall, regexPattern string) (interpreter.InterpretableCall, error) { - compiledRegex, err := regexp.Compile(regexPattern) - if err != nil { - return nil, err - } - return interpreter.NewCall(call.ID(), call.Function(), call.OverloadID(), call.Args(), func(args ...ref.Val) ref.Val { - argn := len(args) - if argn < 2 || argn > 3 { - return types.NoSuchOverloadErr() - } - str, ok := args[0].Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(args[0]) - } - n := int64(-1) - if argn == 3 { - n, ok = args[2].Value().(int64) - if !ok { - return types.MaybeNoSuchOverloadErr(args[2]) - } - } - - result := compiledRegex.FindAllString(str, int(n)) - return types.NewStringList(types.DefaultTypeAdapter, result) - }), nil - }, -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/urls.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/urls.go deleted file mode 100644 index 8e47bb45ae7..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/urls.go +++ /dev/null @@ -1,315 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package library - -import ( - "net/url" - - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter/functions" - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" - - "k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model" -) - -// URLs provides a CEL function library extension of URL parsing functions. -// -// url -// -// Converts a string to a URL or results in an error if the string is not a valid URL. The URL must be an absolute URI -// or an absolute path. -// -// url() -// -// Examples: -// -// url('https://user:pass@example.com:80/path?query=val#fragment') // returns a URL -// url('/absolute-path') // returns a URL -// url('https://a:b:c/') // error -// url('../relative-path') // error -// -// isURL -// -// Returns true if a string is a valid URL. The URL must be an absolute URI or an absolute path. -// -// isURL( ) -// -// Examples: -// -// isURL('https://user:pass@example.com:80/path?query=val#fragment') // returns true -// isURL('/absolute-path') // returns true -// isURL('https://a:b:c/') // returns false -// isURL('../relative-path') // returns false -// -// -// getScheme / getHost / getHostname / getPort / getEscapedPath / getQuery -// -// Return the parsed components of a URL. -// - getScheme: If absent in the URL, returns an empty string. -// - getHostname: IPv6 addresses are returned with braces, e.g. "[::1]". If absent in the URL, returns an empty string. -// - getHost: IPv6 addresses are returned without braces, e.g. "::1". If absent in the URL, returns an empty string. -// - getEscapedPath: The string returned by getEscapedPath is URL escaped, e.g. "with space" becomes "with%20space". -// If absent in the URL, returns an empty string. -// - getPort: If absent in the URL, returns an empty string. -// - getQuery: Returns the query parameters in "matrix" form where a repeated query key is interpreted to -// mean that there are multiple values for that key. The keys and values are returned unescaped. -// If absent in the URL, returns an empty map. -// -// .getScheme() -// .getHost() -// .getHostname() -// .getPort() -// .getEscapedPath() -// .getQuery() , > -// -// Examples: -// -// url('/path').getScheme() // returns '' -// url('https://example.com/').getScheme() // returns 'https' -// url('https://example.com:80/').getHost() // returns 'example.com:80' -// url('https://example.com/').getHost() // returns 'example.com' -// url('https://[::1]:80/').getHost() // returns '[::1]:80' -// url('https://[::1]/').getHost() // returns '[::1]' -// url('/path').getHost() // returns '' -// url('https://example.com:80/').getHostname() // returns 'example.com' -// url('https://127.0.0.1:80/').getHostname() // returns '127.0.0.1' -// url('https://[::1]:80/').getHostname() // returns '::1' -// url('/path').getHostname() // returns '' -// url('https://example.com:80/').getPort() // returns '80' -// url('https://example.com/').getPort() // returns '' -// url('/path').getPort() // returns '' -// url('https://example.com/path').getEscapedPath() // returns '/path' -// url('https://example.com/path with spaces/').getEscapedPath() // returns '/path%20with%20spaces/' -// url('https://example.com').getEscapedPath() // returns '' -// url('https://example.com/path?k1=a&k2=b&k2=c').getQuery() // returns { 'k1': ['a'], 'k2': ['b', 'c']} -// url('https://example.com/path?key with spaces=value with spaces').getQuery() // returns { 'key with spaces': ['value with spaces']} -// url('https://example.com/path?').getQuery() // returns {} -// url('https://example.com/path').getQuery() // returns {} -// -func URLs() cel.EnvOption { - return cel.Lib(urlsLib) -} - -var urlsLib = &urls{} - -type urls struct{} - -var urlLibraryDecls = []*exprpb.Decl{ - decls.NewFunction("url", - decls.NewOverload("string_to_url", - []*exprpb.Type{decls.String}, - model.URLObject), - ), - decls.NewFunction("getScheme", - decls.NewInstanceOverload("url_get_scheme", - []*exprpb.Type{model.URLObject}, - decls.String), - ), - decls.NewFunction("getHost", - decls.NewInstanceOverload("url_get_host", - []*exprpb.Type{model.URLObject}, - decls.String), - ), - decls.NewFunction("getHostname", - decls.NewInstanceOverload("url_get_hostname", - []*exprpb.Type{model.URLObject}, - decls.String), - ), - decls.NewFunction("getPort", - decls.NewInstanceOverload("url_get_port", - []*exprpb.Type{model.URLObject}, - decls.String), - ), - decls.NewFunction("getEscapedPath", - decls.NewInstanceOverload("url_get_escaped_path", - []*exprpb.Type{model.URLObject}, - decls.String), - ), - decls.NewFunction("getQuery", - decls.NewInstanceOverload("url_get_query", - []*exprpb.Type{model.URLObject}, - decls.NewMapType(decls.String, decls.NewListType(decls.String))), - ), - decls.NewFunction("isURL", - decls.NewOverload("is_url_string", - []*exprpb.Type{decls.String}, - decls.Bool), - ), -} - -func (*urls) CompileOptions() []cel.EnvOption { - return []cel.EnvOption{ - cel.Declarations(urlLibraryDecls...), - } -} - -func (*urls) ProgramOptions() []cel.ProgramOption { - return []cel.ProgramOption{ - cel.Functions( - &functions.Overload{ - Operator: "url", - Unary: stringToUrl, - }, - &functions.Overload{ - Operator: "string_to_url", - Unary: stringToUrl, - }, - &functions.Overload{ - Operator: "getScheme", - Unary: getScheme, - }, - &functions.Overload{ - Operator: "url_get_scheme", - Unary: getScheme, - }, - &functions.Overload{ - Operator: "getHost", - Unary: getHost, - }, - &functions.Overload{ - Operator: "url_get_host", - Unary: getHost, - }, - &functions.Overload{ - Operator: "getHostname", - Unary: getHostname, - }, - &functions.Overload{ - Operator: "url_get_hostname", - Unary: getHostname, - }, - &functions.Overload{ - Operator: "getPort", - Unary: getPort, - }, - &functions.Overload{ - Operator: "url_get_port", - Unary: getPort, - }, - &functions.Overload{ - Operator: "getEscapedPath", - Unary: getEscapedPath, - }, - &functions.Overload{ - Operator: "url_get_escaped_path", - Unary: getEscapedPath, - }, - &functions.Overload{ - Operator: "getQuery", - Unary: getQuery, - }, - &functions.Overload{ - Operator: "url_get_query", - Unary: getQuery, - }, - &functions.Overload{ - Operator: "isURL", - Unary: isURL, - }, - &functions.Overload{ - Operator: "is_url_string", - Unary: isURL, - }, - ), - } -} - -func stringToUrl(arg ref.Val) ref.Val { - s, ok := arg.Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - // Use ParseRequestURI to check the URL before conversion. - // ParseRequestURI requires absolute URLs and is used by the OpenAPIv3 'uri' format. - _, err := url.ParseRequestURI(s) - if err != nil { - return types.NewErr("URL parse error during conversion from string: %v", err) - } - // We must parse again with Parse since ParseRequestURI incorrectly parses URLs that contain a fragment - // part and will incorrectly append the fragment to either the path or the query, depending on which it was adjacent to. - u, err := url.Parse(s) - if err != nil { - // Errors are not expected here since Parse is a more lenient parser than ParseRequestURI. - return types.NewErr("URL parse error during conversion from string: %v", err) - } - return model.URL{URL: u} -} - -func getScheme(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - return types.String(u.Scheme) -} - -func getHost(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - return types.String(u.Host) -} - -func getHostname(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - return types.String(u.Hostname()) -} - -func getPort(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - return types.String(u.Port()) -} - -func getEscapedPath(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - return types.String(u.EscapedPath()) -} - -func getQuery(arg ref.Val) ref.Val { - u, ok := arg.Value().(*url.URL) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - - result := map[ref.Val]ref.Val{} - for k, v := range u.Query() { - result[types.String(k)] = types.NewStringList(types.DefaultTypeAdapter, v) - } - return types.NewRefValMap(types.DefaultTypeAdapter, result) -} - -func isURL(arg ref.Val) ref.Val { - s, ok := arg.Value().(string) - if !ok { - return types.MaybeNoSuchOverloadErr(arg) - } - _, err := url.ParseRequestURI(s) - return types.Bool(err == nil) -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/maplist.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/maplist.go index 7e26ad956fc..32cdf86fef4 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/maplist.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/maplist.go @@ -17,162 +17,14 @@ limitations under the License. package cel import ( - "fmt" - "strings" - "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model" + "k8s.io/apiserver/pkg/cel/common" ) -// mapList provides a "lookup by key" operation for lists (arrays) with x-kubernetes-list-type=map. -type mapList interface { - // get returns the first element having given key, for all - // x-kubernetes-list-map-keys, to the provided object. If the provided object isn't itself a valid mapList element, - // get returns nil. - get(interface{}) interface{} -} - -type keyStrategy interface { - // CompositeKeyFor returns a composite key for the provided object, if possible, and a - // boolean that indicates whether or not a key could be generated for the provided object. - CompositeKeyFor(map[string]interface{}) (interface{}, bool) -} - -// singleKeyStrategy is a cheaper strategy for associative lists that have exactly one key. -type singleKeyStrategy struct { - key string -} - -// CompositeKeyFor directly returns the value of the single key to -// use as a composite key. -func (ks *singleKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { - v, ok := obj[ks.key] - if !ok { - return nil, false - } - - switch v.(type) { - case bool, float64, int64, string: - return v, true - default: - return nil, false // non-scalar - } -} - -// multiKeyStrategy computes a composite key of all key values. -type multiKeyStrategy struct { - sts *schema.Structural -} - -// CompositeKeyFor returns a composite key computed from the values of all -// keys. -func (ks *multiKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { - const keyDelimiter = "\x00" // 0 byte should never appear in the composite key except as delimiter - - var delimited strings.Builder - for _, key := range ks.sts.XListMapKeys { - v, ok := obj[key] - if !ok { - return nil, false - } - - switch v.(type) { - case bool: - fmt.Fprintf(&delimited, keyDelimiter+"%t", v) - case float64: - fmt.Fprintf(&delimited, keyDelimiter+"%f", v) - case int64: - fmt.Fprintf(&delimited, keyDelimiter+"%d", v) - case string: - fmt.Fprintf(&delimited, keyDelimiter+"%q", v) - default: - return nil, false // values must be scalars - } - } - return delimited.String(), true -} - -// emptyMapList is a mapList containing no elements. -type emptyMapList struct{} - -func (emptyMapList) get(interface{}) interface{} { - return nil -} - -type mapListImpl struct { - sts *schema.Structural - ks keyStrategy - // keyedItems contains all lazily keyed map items - keyedItems map[interface{}]interface{} - // unkeyedItems contains all map items that have not yet been keyed - unkeyedItems []interface{} -} - -func (a *mapListImpl) get(obj interface{}) interface{} { - mobj, ok := obj.(map[string]interface{}) - if !ok { - return nil - } - - key, ok := a.ks.CompositeKeyFor(mobj) - if !ok { - return nil - } - if match, ok := a.keyedItems[key]; ok { - return match - } - // keep keying items until we either find a match or run out of unkeyed items - for len(a.unkeyedItems) > 0 { - // dequeue an unkeyed item - item := a.unkeyedItems[0] - a.unkeyedItems = a.unkeyedItems[1:] - - // key the item - mitem, ok := item.(map[string]interface{}) - if !ok { - continue - } - itemKey, ok := a.ks.CompositeKeyFor(mitem) - if !ok { - continue - } - if _, exists := a.keyedItems[itemKey]; !exists { - a.keyedItems[itemKey] = mitem - } - - // if it matches, short-circuit - if itemKey == key { - return mitem - } - } - - return nil -} - -func makeKeyStrategy(sts *schema.Structural) keyStrategy { - if len(sts.XListMapKeys) == 1 { - key := sts.XListMapKeys[0] - return &singleKeyStrategy{ - key: key, - } - } - - return &multiKeyStrategy{ - sts: sts, - } -} - // makeMapList returns a queryable interface over the provided x-kubernetes-list-type=map // keyedItems. If the provided schema is _not_ an array with x-kubernetes-list-type=map, returns an // empty mapList. -func makeMapList(sts *schema.Structural, items []interface{}) (rv mapList) { - if sts.Type != "array" || sts.XListType == nil || *sts.XListType != "map" || len(sts.XListMapKeys) == 0 || len(items) == 0 { - return emptyMapList{} - } - ks := makeKeyStrategy(sts) - return &mapListImpl{ - sts: sts, - ks: ks, - keyedItems: map[interface{}]interface{}{}, - unkeyedItems: items, - } +func makeMapList(sts *schema.Structural, items []interface{}) (rv common.MapList) { + return common.MakeMapList(&model.Structural{Structural: sts}, items) } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/adaptor.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/adaptor.go new file mode 100644 index 00000000000..e3e940afa0b --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/adaptor.go @@ -0,0 +1,152 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package model + +import ( + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" + "k8s.io/apiserver/pkg/cel/common" +) + +var _ common.Schema = (*Structural)(nil) +var _ common.SchemaOrBool = (*StructuralOrBool)(nil) + +type Structural struct { + Structural *schema.Structural +} + +type StructuralOrBool struct { + StructuralOrBool *schema.StructuralOrBool +} + +func (sb *StructuralOrBool) Schema() common.Schema { + if sb.StructuralOrBool.Structural == nil { + return nil + } + return &Structural{Structural: sb.StructuralOrBool.Structural} +} + +func (sb *StructuralOrBool) Allows() bool { + return sb.StructuralOrBool.Bool +} + +func (s *Structural) Type() string { + return s.Structural.Type +} + +func (s *Structural) Format() string { + if s.Structural.ValueValidation == nil { + return "" + } + return s.Structural.ValueValidation.Format +} + +func (s *Structural) Items() common.Schema { + return &Structural{Structural: s.Structural.Items} +} + +func (s *Structural) Properties() map[string]common.Schema { + if s.Structural.Properties == nil { + return nil + } + res := make(map[string]common.Schema, len(s.Structural.Properties)) + for n, prop := range s.Structural.Properties { + s := prop + res[n] = &Structural{Structural: &s} + } + return res +} + +func (s *Structural) AdditionalProperties() common.SchemaOrBool { + if s.Structural.AdditionalProperties == nil { + return nil + } + return &StructuralOrBool{StructuralOrBool: s.Structural.AdditionalProperties} +} + +func (s *Structural) Default() any { + return s.Structural.Default.Object +} + +func (s *Structural) MaxItems() *int64 { + if s.Structural.ValueValidation == nil { + return nil + } + return s.Structural.ValueValidation.MaxItems +} + +func (s *Structural) MaxLength() *int64 { + if s.Structural.ValueValidation == nil { + return nil + } + return s.Structural.ValueValidation.MaxLength +} + +func (s *Structural) MaxProperties() *int64 { + if s.Structural.ValueValidation == nil { + return nil + } + return s.Structural.ValueValidation.MaxProperties +} + +func (s *Structural) Required() []string { + if s.Structural.ValueValidation == nil { + return nil + } + return s.Structural.ValueValidation.Required +} + +func (s *Structural) Enum() []any { + if s.Structural.ValueValidation == nil { + return nil + } + ret := make([]any, 0, len(s.Structural.ValueValidation.Enum)) + for _, e := range s.Structural.ValueValidation.Enum { + ret = append(ret, e.Object) + } + return ret +} + +func (s *Structural) Nullable() bool { + return s.Structural.Nullable +} + +func (s *Structural) IsXIntOrString() bool { + return s.Structural.XIntOrString +} + +func (s *Structural) IsXEmbeddedResource() bool { + return s.Structural.XEmbeddedResource +} + +func (s *Structural) IsXPreserveUnknownFields() bool { + return s.Structural.XPreserveUnknownFields +} + +func (s *Structural) XListType() string { + if s.Structural.XListType == nil { + return "" + } + return *s.Structural.XListType +} + +func (s *Structural) XListMapKeys() []string { + return s.Structural.XListMapKeys +} + +func (s *Structural) WithTypeAndObjectMeta() common.Schema { + return &Structural{Structural: WithTypeAndObjectMeta(s.Structural)} +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/schemas.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/schemas.go new file mode 100644 index 00000000000..6b49e67a404 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model/schemas.go @@ -0,0 +1,73 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package model + +import ( + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/common" + + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" +) + +// SchemaDeclType converts the structural schema to a CEL declaration, or returns nil if the +// structural schema should not be exposed in CEL expressions. +// Set isResourceRoot to true for the root of a custom resource or embedded resource. +// +// Schemas with XPreserveUnknownFields not exposed unless they are objects. Array and "maps" schemas +// are not exposed if their items or additionalProperties schemas are not exposed. Object Properties are not exposed +// if their schema is not exposed. +// +// The CEL declaration for objects with XPreserveUnknownFields does not expose unknown fields. +func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *apiservercel.DeclType { + return common.SchemaDeclType(&Structural{Structural: s}, isResourceRoot) +} + +// WithTypeAndObjectMeta ensures the kind, apiVersion and +// metadata.name and metadata.generateName properties are specified, making a shallow copy of the provided schema if needed. +func WithTypeAndObjectMeta(s *schema.Structural) *schema.Structural { + if s.Properties != nil && + s.Properties["kind"].Type == "string" && + s.Properties["apiVersion"].Type == "string" && + s.Properties["metadata"].Type == "object" && + s.Properties["metadata"].Properties != nil && + s.Properties["metadata"].Properties["name"].Type == "string" && + s.Properties["metadata"].Properties["generateName"].Type == "string" { + return s + } + result := &schema.Structural{ + Generic: s.Generic, + Extensions: s.Extensions, + ValueValidation: s.ValueValidation, + } + props := make(map[string]schema.Structural, len(s.Properties)) + for k, prop := range s.Properties { + props[k] = prop + } + stringType := schema.Structural{Generic: schema.Generic{Type: "string"}} + props["kind"] = stringType + props["apiVersion"] = stringType + props["metadata"] = schema.Structural{ + Generic: schema.Generic{Type: "object"}, + Properties: map[string]schema.Structural{ + "name": stringType, + "generateName": stringType, + }, + } + result.Properties = props + + return result +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation.go index e3562b7c9ee..2b630e97786 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation.go @@ -21,16 +21,24 @@ import ( "fmt" "math" "reflect" + "regexp" "strings" + "time" + celgo "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/google/cel-go/interpreter" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" - "k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/metrics" + "k8s.io/klog/v2" + + celconfig "k8s.io/apiserver/pkg/apis/cel" ) // Validator parallels the structure of schema.Structural and includes the compiled CEL programs @@ -51,37 +59,72 @@ type Validator struct { // isResourceRoot is true if this validator node is for the root of a resource. Either the root of the // custom resource being validated, or the root of an XEmbeddedResource object. isResourceRoot bool + + // celActivationFactory produces an Activation, which resolves identifiers (e.g. self and + // oldSelf) to CEL values. + celActivationFactory func(sts *schema.Structural, obj, oldObj interface{}) interpreter.Activation } // NewValidator returns compiles all the CEL programs defined in x-kubernetes-validations extensions // of the Structural schema and returns a custom resource validator that contains nested // validators for all items, properties and additionalProperties that transitively contain validator rules. -// Returns nil only if there no validator rules in the Structural schema. May return a validator containing -// only errors. -// Adding perCallLimit as input arg for testing purpose only. Callers should always use const PerCallLimit as input -func NewValidator(s *schema.Structural, perCallLimit uint64) *Validator { - return validator(s, true, perCallLimit) +// Returns nil if there are no validator rules in the Structural schema. May return a validator containing only errors. +// Adding perCallLimit as input arg for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input +func NewValidator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64) *Validator { + if !hasXValidations(s) { + return nil + } + return validator(s, isResourceRoot, model.SchemaDeclType(s, isResourceRoot), perCallLimit) } -func validator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64) *Validator { - compiledRules, err := Compile(s, isResourceRoot, perCallLimit) +// validator creates a Validator for all x-kubernetes-validations at the level of the provided schema and lower and +// returns the Validator if any x-kubernetes-validations exist in the schema, or nil if no x-kubernetes-validations +// exist. declType is expected to be a CEL DeclType corresponding to the structural schema. +// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func validator(s *schema.Structural, isResourceRoot bool, declType *cel.DeclType, perCallLimit uint64) *Validator { + compiledRules, err := Compile(s, declType, perCallLimit) var itemsValidator, additionalPropertiesValidator *Validator var propertiesValidators map[string]Validator if s.Items != nil { - itemsValidator = validator(s.Items, s.Items.XEmbeddedResource, perCallLimit) + itemsValidator = validator(s.Items, s.Items.XEmbeddedResource, declType.ElemType, perCallLimit) } if len(s.Properties) > 0 { propertiesValidators = make(map[string]Validator, len(s.Properties)) - for k, prop := range s.Properties { - if p := validator(&prop, prop.XEmbeddedResource, perCallLimit); p != nil { + for k, p := range s.Properties { + prop := p + var fieldType *cel.DeclType + if escapedPropName, ok := cel.Escape(k); ok { + if f, ok := declType.Fields[escapedPropName]; ok { + fieldType = f.Type + } else { + // fields with unknown types are omitted from CEL validation entirely + continue + } + } else { + // field may be absent from declType if the property name is unescapable, in which case we should convert + // the field value type to a DeclType. + fieldType = model.SchemaDeclType(&prop, prop.XEmbeddedResource) + if fieldType == nil { + continue + } + } + if p := validator(&prop, prop.XEmbeddedResource, fieldType, perCallLimit); p != nil { propertiesValidators[k] = *p } } } if s.AdditionalProperties != nil && s.AdditionalProperties.Structural != nil { - additionalPropertiesValidator = validator(s.AdditionalProperties.Structural, s.AdditionalProperties.Structural.XEmbeddedResource, perCallLimit) + additionalPropertiesValidator = validator(s.AdditionalProperties.Structural, s.AdditionalProperties.Structural.XEmbeddedResource, declType.ElemType, perCallLimit) } if len(compiledRules) > 0 || err != nil || itemsValidator != nil || additionalPropertiesValidator != nil || len(propertiesValidators) > 0 { + var activationFactory func(*schema.Structural, interface{}, interface{}) interpreter.Activation = validationActivationWithoutOldSelf + for _, rule := range compiledRules { + if rule.TransitionRule { + activationFactory = validationActivationWithOldSelf + break + } + } + return &Validator{ compiledRules: compiledRules, compilationErr: err, @@ -89,6 +132,7 @@ func validator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64) * Items: itemsValidator, AdditionalProperties: additionalPropertiesValidator, Properties: propertiesValidators, + celActivationFactory: activationFactory, } } @@ -100,6 +144,10 @@ func validator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64) * // Most callers can ignore the returned remainingBudget value unless another validate call is going to be made // context is passed for supporting context cancellation during cel validation func (s *Validator) Validate(ctx context.Context, fldPath *field.Path, sts *schema.Structural, obj, oldObj interface{}, costBudget int64) (errs field.ErrorList, remainingBudget int64) { + t := time.Now() + defer func() { + metrics.Metrics.ObserveEvaluation(time.Since(t)) + }() remainingBudget = costBudget if s == nil || obj == nil { return nil, remainingBudget @@ -131,7 +179,7 @@ func (s *Validator) validateExpressions(ctx context.Context, fldPath *field.Path if oldObj != nil { v := reflect.ValueOf(oldObj) switch v.Kind() { - case reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: + case reflect.Map, reflect.Pointer, reflect.Interface, reflect.Slice: if v.IsNil() { oldObj = nil // +k8s:verify-mutation:reason=clone } @@ -159,7 +207,7 @@ func (s *Validator) validateExpressions(ctx context.Context, fldPath *field.Path if s.isResourceRoot { sts = model.WithTypeAndObjectMeta(sts) } - var activation interpreter.Activation = NewValidationActivation(obj, oldObj, sts) + activation := s.celActivationFactory(sts, obj, oldObj) for i, compiled := range s.compiledRules { rule := sts.XValidations[i] if compiled.Error != nil { @@ -209,16 +257,102 @@ func (s *Validator) validateExpressions(ctx context.Context, fldPath *field.Path continue } if evalResult != types.True { - if len(rule.Message) != 0 { - errs = append(errs, field.Invalid(fldPath, sts.Type, rule.Message)) + if compiled.MessageExpression != nil { + messageExpression, newRemainingBudget, msgErr := evalMessageExpression(ctx, compiled.MessageExpression, rule.MessageExpression, activation, remainingBudget) + if msgErr != nil { + if msgErr.Type == cel.ErrorTypeInternal { + errs = append(errs, field.InternalError(fldPath, msgErr)) + return errs, -1 + } else if msgErr.Type == cel.ErrorTypeInvalid { + errs = append(errs, field.Invalid(fldPath, sts.Type, msgErr.Error())) + return errs, -1 + } else { + klog.V(2).ErrorS(msgErr, "messageExpression evaluation failed") + errs = append(errs, field.Invalid(fldPath, sts.Type, ruleMessageOrDefault(rule))) + remainingBudget = newRemainingBudget + } + } else { + errs = append(errs, field.Invalid(fldPath, sts.Type, messageExpression)) + remainingBudget = newRemainingBudget + } } else { - errs = append(errs, field.Invalid(fldPath, sts.Type, fmt.Sprintf("failed rule: %s", ruleErrorString(rule)))) + errs = append(errs, field.Invalid(fldPath, sts.Type, ruleMessageOrDefault(rule))) } } } return errs, remainingBudget } +// evalMessageExpression evaluates the given message expression and returns the evaluated string form and the remaining budget, or an error if one +// occurred during evaluation. +func evalMessageExpression(ctx context.Context, expr celgo.Program, exprSrc string, activation interpreter.Activation, remainingBudget int64) (string, int64, *cel.Error) { + evalResult, evalDetails, err := expr.ContextEval(ctx, activation) + if evalDetails == nil { + return "", -1, &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("runtime cost could not be calculated for messageExpression: %q", exprSrc), + } + } + rtCost := evalDetails.ActualCost() + if rtCost == nil { + return "", -1, &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("runtime cost could not be calculated for messageExpression: %q", exprSrc), + } + } else if *rtCost > math.MaxInt64 || int64(*rtCost) > remainingBudget { + return "", -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: "messageExpression evaluation failed due to running out of cost budget, no further validation rules will be run", + } + } + if err != nil { + if strings.HasPrefix(err.Error(), "operation cancelled: actual cost limit exceeded") { + return "", -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("no further validation rules will be run due to call cost exceeds limit for messageExpression: %q", exprSrc), + } + } + return "", remainingBudget - int64(*rtCost), &cel.Error{ + Detail: fmt.Sprintf("messageExpression evaluation failed due to: %v", err.Error()), + } + } + messageStr, ok := evalResult.Value().(string) + if !ok { + return "", remainingBudget - int64(*rtCost), &cel.Error{ + Detail: "messageExpression failed to convert to string", + } + } + trimmedMsgStr := strings.TrimSpace(messageStr) + if len(trimmedMsgStr) > celconfig.MaxEvaluatedMessageExpressionSizeBytes { + return "", remainingBudget - int64(*rtCost), &cel.Error{ + Detail: fmt.Sprintf("messageExpression beyond allowable length of %d", celconfig.MaxEvaluatedMessageExpressionSizeBytes), + } + } else if hasNewlines(trimmedMsgStr) { + return "", remainingBudget - int64(*rtCost), &cel.Error{ + Detail: "messageExpression should not contain line breaks", + } + } else if len(trimmedMsgStr) == 0 { + return "", remainingBudget - int64(*rtCost), &cel.Error{ + Detail: "messageExpression should evaluate to a non-empty string", + } + } + return trimmedMsgStr, remainingBudget - int64(*rtCost), nil +} + +var newlineMatcher = regexp.MustCompile(`[\n]+`) + +func hasNewlines(s string) bool { + return newlineMatcher.MatchString(s) +} + +func ruleMessageOrDefault(rule apiextensions.ValidationRule) string { + if len(rule.Message) == 0 { + return fmt.Sprintf("failed rule: %s", ruleErrorString(rule)) + } else { + return strings.TrimSpace(rule.Message) + } +} + func ruleErrorString(rule apiextensions.ValidationRule) string { if len(rule.Message) > 0 { return strings.TrimSpace(rule.Message) @@ -231,17 +365,23 @@ type validationActivation struct { hasOldSelf bool } -func NewValidationActivation(obj, oldObj interface{}, structural *schema.Structural) *validationActivation { +func validationActivationWithOldSelf(sts *schema.Structural, obj, oldObj interface{}) interpreter.Activation { va := &validationActivation{ - self: UnstructuredToVal(obj, structural), + self: UnstructuredToVal(obj, sts), } if oldObj != nil { - va.oldSelf = UnstructuredToVal(oldObj, structural) // +k8s:verify-mutation:reason=clone - va.hasOldSelf = true // +k8s:verify-mutation:reason=clone + va.oldSelf = UnstructuredToVal(oldObj, sts) // +k8s:verify-mutation:reason=clone + va.hasOldSelf = true // +k8s:verify-mutation:reason=clone } return va } +func validationActivationWithoutOldSelf(sts *schema.Structural, obj, _ interface{}) interpreter.Activation { + return &validationActivation{ + self: UnstructuredToVal(obj, sts), + } +} + func (a *validationActivation) ResolveName(name string) (interface{}, bool) { switch name { case ScopedVarName: @@ -318,7 +458,7 @@ func (s *Validator) validateArray(ctx context.Context, fldPath *field.Path, sts correlatableOldItems := makeMapList(sts, oldObj) for i := range obj { var err field.ErrorList - err, remainingBudget = s.Items.Validate(ctx, fldPath.Index(i), sts.Items, obj[i], correlatableOldItems.get(obj[i]), remainingBudget) + err, remainingBudget = s.Items.Validate(ctx, fldPath.Index(i), sts.Items, obj[i], correlatableOldItems.Get(obj[i]), remainingBudget) errs = append(errs, err...) if remainingBudget < 0 { return errs, remainingBudget @@ -335,3 +475,26 @@ func MapIsCorrelatable(mapType *string) bool { // if a third map type is introduced, assume it's not correlatable. granular is the default if unspecified. return mapType == nil || *mapType == "granular" || *mapType == "atomic" } + +func hasXValidations(s *schema.Structural) bool { + if s == nil { + return false + } + if len(s.XValidations) > 0 { + return true + } + if hasXValidations(s.Items) { + return true + } + if s.AdditionalProperties != nil && hasXValidations(s.AdditionalProperties.Structural) { + return true + } + if s.Properties != nil { + for _, prop := range s.Properties { + if hasXValidations(&prop) { + return true + } + } + } + return false +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/values.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/values.go index 4fa90ab106f..8b879eaf206 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/values.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/values.go @@ -17,687 +17,16 @@ limitations under the License. package cel import ( - "fmt" - "reflect" - "sync" - "time" - - "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - "k8s.io/apimachinery/pkg/api/equality" structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" - "k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model" - "k8s.io/kube-openapi/pkg/validation/strfmt" + "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model" + celopenapi "k8s.io/apiserver/pkg/cel/common" ) // UnstructuredToVal converts a Kubernetes unstructured data element to a CEL Val. // The root schema of custom resource schema is expected contain type meta and object meta schemas. // If Embedded resources do not contain type meta and object meta schemas, they will be added automatically. func UnstructuredToVal(unstructured interface{}, schema *structuralschema.Structural) ref.Val { - if unstructured == nil { - if schema.Nullable { - return types.NullValue - } - return types.NewErr("invalid data, got null for schema with nullable=false") - } - if schema.XIntOrString { - switch v := unstructured.(type) { - case string: - return types.String(v) - case int: - return types.Int(v) - case int32: - return types.Int(v) - case int64: - return types.Int(v) - } - return types.NewErr("invalid data, expected XIntOrString value to be either a string or integer") - } - if schema.Type == "object" { - m, ok := unstructured.(map[string]interface{}) - if !ok { - return types.NewErr("invalid data, expected a map for the provided schema with type=object") - } - if schema.XEmbeddedResource || schema.Properties != nil { - if schema.XEmbeddedResource { - schema = model.WithTypeAndObjectMeta(schema) - } - return &unstructuredMap{ - value: m, - schema: schema, - propSchema: func(key string) (*structuralschema.Structural, bool) { - if schema, ok := schema.Properties[key]; ok { - return &schema, true - } - return nil, false - }, - } - } - if schema.AdditionalProperties != nil && schema.AdditionalProperties.Structural != nil { - return &unstructuredMap{ - value: m, - schema: schema, - propSchema: func(key string) (*structuralschema.Structural, bool) { - return schema.AdditionalProperties.Structural, true - }, - } - } - // A object with x-preserve-unknown-fields but no properties or additionalProperties is treated - // as an empty object. - if schema.XPreserveUnknownFields { - return &unstructuredMap{ - value: m, - schema: schema, - propSchema: func(key string) (*structuralschema.Structural, bool) { - return nil, false - }, - } - } - return types.NewErr("invalid object type, expected either Properties or AdditionalProperties with Allows=true and non-empty Schema") - } - - if schema.Type == "array" { - l, ok := unstructured.([]interface{}) - if !ok { - return types.NewErr("invalid data, expected an array for the provided schema with type=array") - } - if schema.Items == nil { - return types.NewErr("invalid array type, expected Items with a non-empty Schema") - } - typedList := unstructuredList{elements: l, itemsSchema: schema.Items} - listType := schema.XListType - if listType != nil { - switch *listType { - case "map": - mapKeys := schema.Extensions.XListMapKeys - return &unstructuredMapList{unstructuredList: typedList, escapedKeyProps: escapeKeyProps(mapKeys)} - case "set": - return &unstructuredSetList{unstructuredList: typedList} - case "atomic": - return &typedList - default: - return types.NewErr("invalid x-kubernetes-list-type, expected 'map', 'set' or 'atomic' but got %s", *listType) - } - } - return &typedList - } - - if schema.Type == "string" { - str, ok := unstructured.(string) - if !ok { - return types.NewErr("invalid data, expected string, got %T", unstructured) - } - if schema.ValueValidation != nil { - switch schema.ValueValidation.Format { - case "duration": - d, err := strfmt.ParseDuration(str) - if err != nil { - return types.NewErr("Invalid duration %s: %v", str, err) - } - return types.Duration{Duration: d} - case "date": - d, err := time.Parse(strfmt.RFC3339FullDate, str) // strfmt uses this format for OpenAPIv3 value validation - if err != nil { - return types.NewErr("Invalid date formatted string %s: %v", str, err) - } - return types.Timestamp{Time: d} - case "date-time": - d, err := strfmt.ParseDateTime(str) - if err != nil { - return types.NewErr("Invalid date-time formatted string %s: %v", str, err) - } - return types.Timestamp{Time: time.Time(d)} - case "byte": - base64 := strfmt.Base64{} - err := base64.UnmarshalText([]byte(str)) - if err != nil { - return types.NewErr("Invalid byte formatted string %s: %v", str, err) - } - return types.Bytes(base64) - } - } - return types.String(str) - } - if schema.Type == "number" { - switch v := unstructured.(type) { - // float representations of whole numbers (e.g. 1.0, 0.0) can convert to int representations (e.g. 1, 0) in yaml - // to json translation, and then get parsed as int64s - case int: - return types.Double(v) - case int32: - return types.Double(v) - case int64: - return types.Double(v) - - case float32: - return types.Double(v) - case float64: - return types.Double(v) - default: - return types.NewErr("invalid data, expected float, got %T", unstructured) - } - } - if schema.Type == "integer" { - switch v := unstructured.(type) { - case int: - return types.Int(v) - case int32: - return types.Int(v) - case int64: - return types.Int(v) - default: - return types.NewErr("invalid data, expected int, got %T", unstructured) - } - } - if schema.Type == "boolean" { - b, ok := unstructured.(bool) - if !ok { - return types.NewErr("invalid data, expected bool, got %T", unstructured) - } - return types.Bool(b) - } - - if schema.XPreserveUnknownFields { - return &unknownPreserved{u: unstructured} - } - - return types.NewErr("invalid type, expected object, array, number, integer, boolean or string, or no type with x-kubernetes-int-or-string or x-kubernetes-preserve-unknown-fields is true, got %s", schema.Type) -} - -// unknownPreserved represents unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields. -// It preserves the data at runtime without assuming it is of any particular type and supports only equality checking. -// unknownPreserved should be used only for values are not directly accessible in CEL expressions, i.e. for data -// where there is no corresponding CEL type declaration. -type unknownPreserved struct { - u interface{} -} - -func (t *unknownPreserved) ConvertToNative(refType reflect.Type) (interface{}, error) { - return nil, fmt.Errorf("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", refType) -} - -func (t *unknownPreserved) ConvertToType(typeValue ref.Type) ref.Val { - return types.NewErr("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", typeValue.TypeName()) -} - -func (t *unknownPreserved) Equal(other ref.Val) ref.Val { - return types.Bool(equality.Semantic.DeepEqual(t.u, other.Value())) -} - -func (t *unknownPreserved) Type() ref.Type { - return types.UnknownType -} - -func (t *unknownPreserved) Value() interface{} { - return t.u // used by Equal checks -} - -// unstructuredMapList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=map. -type unstructuredMapList struct { - unstructuredList - escapedKeyProps []string - - sync.Once // for for lazy load of mapOfList since it is only needed if Equals is called - mapOfList map[interface{}]interface{} -} - -func (t *unstructuredMapList) getMap() map[interface{}]interface{} { - t.Do(func() { - t.mapOfList = make(map[interface{}]interface{}, len(t.elements)) - for _, e := range t.elements { - t.mapOfList[t.toMapKey(e)] = e - } - }) - return t.mapOfList -} - -// toMapKey returns a valid golang map key for the given element of the map list. -// element must be a valid map list entry where all map key props are scalar types (which are comparable in go -// and valid for use in a golang map key). -func (t *unstructuredMapList) toMapKey(element interface{}) interface{} { - eObj, ok := element.(map[string]interface{}) - if !ok { - return types.NewErr("unexpected data format for element of array with x-kubernetes-list-type=map: %T", element) - } - // Arrays are comparable in go and may be used as map keys, but maps and slices are not. - // So we can special case small numbers of key props as arrays and fall back to serialization - // for larger numbers of key props - if len(t.escapedKeyProps) == 1 { - return eObj[t.escapedKeyProps[0]] - } - if len(t.escapedKeyProps) == 2 { - return [2]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]]} - } - if len(t.escapedKeyProps) == 3 { - return [3]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]], eObj[t.escapedKeyProps[2]]} - } - - key := make([]interface{}, len(t.escapedKeyProps)) - for i, kf := range t.escapedKeyProps { - key[i] = eObj[kf] - } - return fmt.Sprintf("%v", key) -} - -// Equal on a map list ignores list element order. -func (t *unstructuredMapList) Equal(other ref.Val) ref.Val { - oMapList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - sz := types.Int(len(t.elements)) - if sz != oMapList.Size() { - return types.False - } - tMap := t.getMap() - for it := oMapList.Iterator(); it.HasNext() == types.True; { - v := it.Next() - k := t.toMapKey(v.Value()) - tVal, ok := tMap[k] - if !ok { - return types.False - } - eq := UnstructuredToVal(tVal, t.itemsSchema).Equal(v) - if eq != types.True { - return eq // either false or error - } - } - return types.True -} - -// Add for a map list `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values -// are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with -// non-intersecting keys are appended, retaining their partial order. -func (t *unstructuredMapList) Add(other ref.Val) ref.Val { - oMapList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - elements := make([]interface{}, len(t.elements)) - keyToIdx := map[interface{}]int{} - for i, e := range t.elements { - k := t.toMapKey(e) - keyToIdx[k] = i - elements[i] = e - } - for it := oMapList.Iterator(); it.HasNext() == types.True; { - v := it.Next().Value() - k := t.toMapKey(v) - if overwritePosition, ok := keyToIdx[k]; ok { - elements[overwritePosition] = v - } else { - elements = append(elements, v) - } - } - return &unstructuredMapList{ - unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, - escapedKeyProps: t.escapedKeyProps, - } -} - -// escapeKeyProps returns identifiers with Escape applied to each. -// Identifiers that cannot be escaped are left as-is. They are inaccessible to CEL programs but are -// are still needed internally to perform equality checks. -func escapeKeyProps(idents []string) []string { - result := make([]string, len(idents)) - for i, prop := range idents { - if escaped, ok := model.Escape(prop); ok { - result[i] = escaped - } else { - result[i] = prop - } - } - return result -} - -// unstructuredSetList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=set. -type unstructuredSetList struct { - unstructuredList - escapedKeyProps []string - - sync.Once // for for lazy load of setOfList since it is only needed if Equals is called - set map[interface{}]struct{} -} - -func (t *unstructuredSetList) getSet() map[interface{}]struct{} { - // sets are only allowed to contain scalar elements, which are comparable in go, and can safely be used as - // golang map keys - t.Do(func() { - t.set = make(map[interface{}]struct{}, len(t.elements)) - for _, e := range t.elements { - t.set[e] = struct{}{} - } - }) - return t.set -} - -// Equal on a map list ignores list element order. -func (t *unstructuredSetList) Equal(other ref.Val) ref.Val { - oSetList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - sz := types.Int(len(t.elements)) - if sz != oSetList.Size() { - return types.False - } - tSet := t.getSet() - for it := oSetList.Iterator(); it.HasNext() == types.True; { - next := it.Next().Value() - _, ok := tSet[next] - if !ok { - return types.False - } - } - return types.True -} - -// Add for a set list `X + Y` performs a union where the array positions of all elements in `X` are preserved and -// non-intersecting elements in `Y` are appended, retaining their partial order. -func (t *unstructuredSetList) Add(other ref.Val) ref.Val { - oSetList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - elements := t.elements - set := t.getSet() - for it := oSetList.Iterator(); it.HasNext() == types.True; { - next := it.Next().Value() - if _, ok := set[next]; !ok { - set[next] = struct{}{} - elements = append(elements, next) - } - } - return &unstructuredSetList{ - unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, - escapedKeyProps: t.escapedKeyProps, - } -} - -// unstructuredList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=atomic (the default). -type unstructuredList struct { - elements []interface{} - itemsSchema *structuralschema.Structural -} - -var _ = traits.Lister(&unstructuredList{}) - -func (t *unstructuredList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - switch typeDesc.Kind() { - case reflect.Slice: - return t.elements, nil - } - return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) -} - -func (t *unstructuredList) ConvertToType(typeValue ref.Type) ref.Val { - switch typeValue { - case types.ListType: - return t - case types.TypeType: - return types.ListType - } - return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) -} - -func (t *unstructuredList) Equal(other ref.Val) ref.Val { - oList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - sz := types.Int(len(t.elements)) - if sz != oList.Size() { - return types.False - } - for i := types.Int(0); i < sz; i++ { - eq := t.Get(i).Equal(oList.Get(i)) - if eq != types.True { - return eq // either false or error - } - } - return types.True -} - -func (t *unstructuredList) Type() ref.Type { - return types.ListType -} - -func (t *unstructuredList) Value() interface{} { - return t.elements -} - -func (t *unstructuredList) Add(other ref.Val) ref.Val { - oList, ok := other.(traits.Lister) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - elements := t.elements - for it := oList.Iterator(); it.HasNext() == types.True; { - next := it.Next().Value() - elements = append(elements, next) - } - - return &unstructuredList{elements: elements, itemsSchema: t.itemsSchema} -} - -func (t *unstructuredList) Contains(val ref.Val) ref.Val { - if types.IsUnknownOrError(val) { - return val - } - var err ref.Val - sz := len(t.elements) - for i := 0; i < sz; i++ { - elem := UnstructuredToVal(t.elements[i], t.itemsSchema) - cmp := elem.Equal(val) - b, ok := cmp.(types.Bool) - if !ok && err == nil { - err = types.MaybeNoSuchOverloadErr(cmp) - } - if b == types.True { - return types.True - } - } - if err != nil { - return err - } - return types.False -} - -func (t *unstructuredList) Get(idx ref.Val) ref.Val { - iv, isInt := idx.(types.Int) - if !isInt { - return types.ValOrErr(idx, "unsupported index: %v", idx) - } - i := int(iv) - if i < 0 || i >= len(t.elements) { - return types.NewErr("index out of bounds: %v", idx) - } - return UnstructuredToVal(t.elements[i], t.itemsSchema) -} - -func (t *unstructuredList) Iterator() traits.Iterator { - items := make([]ref.Val, len(t.elements)) - for i, item := range t.elements { - itemCopy := item - items[i] = UnstructuredToVal(itemCopy, t.itemsSchema) - } - return &listIterator{unstructuredList: t, items: items} -} - -type listIterator struct { - *unstructuredList - items []ref.Val - idx int -} - -func (it *listIterator) HasNext() ref.Val { - return types.Bool(it.idx < len(it.items)) -} - -func (it *listIterator) Next() ref.Val { - item := it.items[it.idx] - it.idx++ - return item -} - -func (t *unstructuredList) Size() ref.Val { - return types.Int(len(t.elements)) -} - -// unstructuredMap represented an unstructured data instance of an OpenAPI object. -type unstructuredMap struct { - value map[string]interface{} - schema *structuralschema.Structural - // propSchema finds the schema to use for a particular map key. - propSchema func(key string) (*structuralschema.Structural, bool) -} - -var _ = traits.Mapper(&unstructuredMap{}) - -func (t *unstructuredMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - switch typeDesc.Kind() { - case reflect.Map: - return t.value, nil - } - return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) -} - -func (t *unstructuredMap) ConvertToType(typeValue ref.Type) ref.Val { - switch typeValue { - case types.MapType: - return t - case types.TypeType: - return types.MapType - } - return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) -} - -func (t *unstructuredMap) Equal(other ref.Val) ref.Val { - oMap, isMap := other.(traits.Mapper) - if !isMap { - return types.MaybeNoSuchOverloadErr(other) - } - if t.Size() != oMap.Size() { - return types.False - } - for key, value := range t.value { - if propSchema, ok := t.propSchema(key); ok { - ov, found := oMap.Find(types.String(key)) - if !found { - return types.False - } - v := UnstructuredToVal(value, propSchema) - vEq := v.Equal(ov) - if vEq != types.True { - return vEq // either false or error - } - } else { - // Must be an object with properties. - // Since we've encountered an unknown field, fallback to unstructured equality checking. - ouMap, ok := other.(*unstructuredMap) - if !ok { - // The compiler ensures equality is against the same type of object, so this should be unreachable - return types.MaybeNoSuchOverloadErr(other) - } - if oValue, ok := ouMap.value[key]; ok { - if !equality.Semantic.DeepEqual(value, oValue) { - return types.False - } - } - } - } - return types.True -} - -func (t *unstructuredMap) Type() ref.Type { - return types.MapType -} - -func (t *unstructuredMap) Value() interface{} { - return t.value -} - -func (t *unstructuredMap) Contains(key ref.Val) ref.Val { - v, found := t.Find(key) - if v != nil && types.IsUnknownOrError(v) { - return v - } - - return types.Bool(found) -} - -func (t *unstructuredMap) Get(key ref.Val) ref.Val { - v, found := t.Find(key) - if found { - return v - } - return types.ValOrErr(key, "no such key: %v", key) -} - -func (t *unstructuredMap) Iterator() traits.Iterator { - isObject := t.schema.Properties != nil - keys := make([]ref.Val, len(t.value)) - i := 0 - for k := range t.value { - if _, ok := t.propSchema(k); ok { - mapKey := k - if isObject { - if escaped, ok := model.Escape(k); ok { - mapKey = escaped - } - } - keys[i] = types.String(mapKey) - i++ - } - } - return &mapIterator{unstructuredMap: t, keys: keys} -} - -type mapIterator struct { - *unstructuredMap - keys []ref.Val - idx int -} - -func (it *mapIterator) HasNext() ref.Val { - return types.Bool(it.idx < len(it.keys)) -} - -func (it *mapIterator) Next() ref.Val { - key := it.keys[it.idx] - it.idx++ - return key -} - -func (t *unstructuredMap) Size() ref.Val { - return types.Int(len(t.value)) -} - -func (t *unstructuredMap) Find(key ref.Val) (ref.Val, bool) { - isObject := t.schema.Properties != nil - keyStr, ok := key.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(key), true - } - k := keyStr.Value().(string) - if isObject { - k, ok = model.Unescape(k) - if !ok { - return nil, false - } - } - if v, ok := t.value[k]; ok { - // If this is an object with properties, not an object with additionalProperties, - // then null valued nullable fields are treated the same as absent optional fields. - if isObject && v == nil { - return nil, false - } - if propSchema, ok := t.propSchema(k); ok { - return UnstructuredToVal(v, propSchema), true - } - } - - return nil, false + return celopenapi.UnstructuredToVal(unstructured, &model.Structural{Structural: schema}) } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/surroundingobject.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/surroundingobject.go index cb75c2b9fd3..fba2b75af5f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/surroundingobject.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/surroundingobject.go @@ -34,8 +34,8 @@ type AccessorFunc func(obj map[string]interface{}) (x interface{}, found bool, e // // With obj, acc, _ := someSurroundingObjectFunc(x) we get: // -// acc(obj) == x -// reflect.DeepEqual(acc(DeepCopy(obj), x) == x +// acc(obj) == x +// reflect.DeepEqual(acc(DeepCopy(obj), x) == x // // where x is the original instance for slices and maps. // @@ -44,19 +44,19 @@ type AccessorFunc func(obj map[string]interface{}) (x interface{}, found bool, e // // Example (ignoring the last two return values): // -// NewRootObjectFunc()(x) == x -// NewRootObjectFunc().Index()(x) == [x] -// NewRootObjectFunc().Index().Child("foo") == [{"foo": x}] -// NewRootObjectFunc().Index().Child("foo").Child("bar") == [{"foo": {"bar":x}}] -// NewRootObjectFunc().Index().Child("foo").Child("bar").Index() == [{"foo": {"bar":[x]}}] +// NewRootObjectFunc()(x) == x +// NewRootObjectFunc().Index()(x) == [x] +// NewRootObjectFunc().Index().Child("foo") == [{"foo": x}] +// NewRootObjectFunc().Index().Child("foo").Child("bar") == [{"foo": {"bar":x}}] +// NewRootObjectFunc().Index().Child("foo").Child("bar").Index() == [{"foo": {"bar":[x]}}] // // and: // -// NewRootObjectFunc(), then acc(x) == x -// NewRootObjectFunc().Index(), then acc([x]) == x -// NewRootObjectFunc().Index().Child("foo"), then acc([{"foo": x}]) == x -// NewRootObjectFunc().Index().Child("foo").Child("bar"), then acc([{"foo": {"bar":x}}]) == x -// NewRootObjectFunc().Index().Child("foo").Child("bar").Index(), then acc([{"foo": {"bar":[x]}}]) == x +// NewRootObjectFunc(), then acc(x) == x +// NewRootObjectFunc().Index(), then acc([x]) == x +// NewRootObjectFunc().Index().Child("foo"), then acc([{"foo": x}]) == x +// NewRootObjectFunc().Index().Child("foo").Child("bar"), then acc([{"foo": {"bar":x}}]) == x +// NewRootObjectFunc().Index().Child("foo").Child("bar").Index(), then acc([{"foo": {"bar":[x]}}]) == x type SurroundingObjectFunc func(focus interface{}) (map[string]interface{}, AccessorFunc, error) // NewRootObjectFunc returns the identity function. The passed focus value diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/validation.go index 40e1218c2d6..cd7c6e07558 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting/validation.go @@ -32,6 +32,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" + celconfig "k8s.io/apiserver/pkg/apis/cel" ) // ValidateDefaults checks that default values validate and are properly pruned. @@ -50,7 +51,7 @@ func ValidateDefaults(ctx context.Context, pth *field.Path, s *structuralschema. } } - allErr, error, _ := validate(ctx, pth, s, s, f, false, requirePrunedDefaults, cel.RuntimeCELCostBudget) + allErr, error, _ := validate(ctx, pth, s, s, f, false, requirePrunedDefaults, celconfig.RuntimeCELCostBudget) return allErr, error } @@ -70,6 +71,8 @@ func validate(ctx context.Context, pth *field.Path, s *structuralschema.Structur rootSchema = s } + isResourceRoot := s == rootSchema + if s.Default.Object != nil { validator := kubeopenapivalidate.NewSchemaValidator(s.ToKubeOpenAPI(), nil, "", strfmt.Default) @@ -89,7 +92,7 @@ func validate(ctx context.Context, pth *field.Path, s *structuralschema.Structur allErrs = append(allErrs, field.Invalid(pth.Child("default"), s.Default.Object, fmt.Sprintf("must result in valid metadata: %v", errs.ToAggregate()))) } else if errs := apiservervalidation.ValidateCustomResource(pth.Child("default"), s.Default.Object, validator); len(errs) > 0 { allErrs = append(allErrs, errs...) - } else if celValidator := cel.NewValidator(s, cel.PerCallLimit); celValidator != nil { + } else if celValidator := cel.NewValidator(s, isResourceRoot, celconfig.PerCallLimit); celValidator != nil { celErrs, rmCost := celValidator.Validate(ctx, pth.Child("default"), s, s.Default.Object, s.Default.Object, remainingCost) remainingCost = rmCost allErrs = append(allErrs, celErrs...) @@ -114,7 +117,7 @@ func validate(ctx context.Context, pth *field.Path, s *structuralschema.Structur allErrs = append(allErrs, errs...) } else if errs := apiservervalidation.ValidateCustomResource(pth.Child("default"), s.Default.Object, validator); len(errs) > 0 { allErrs = append(allErrs, errs...) - } else if celValidator := cel.NewValidator(s, cel.PerCallLimit); celValidator != nil { + } else if celValidator := cel.NewValidator(s, isResourceRoot, celconfig.PerCallLimit); celValidator != nil { celErrs, rmCost := celValidator.Validate(ctx, pth.Child("default"), s, s.Default.Object, s.Default.Object, remainingCost) remainingCost = rmCost allErrs = append(allErrs, celErrs...) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/algorithm.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/algorithm.go index 4cd32c1293b..811c38377b8 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/algorithm.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/algorithm.go @@ -17,15 +17,34 @@ limitations under the License. package objectmeta import ( + "sort" + structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/validation/field" ) +// CoerceOptions gives the ability to ReturnUnknownFieldPaths for fields +// unrecognized by the schema or DropInvalidFields for fields that are a part +// of the schema, but are malformed. +type CoerceOptions struct { + // DropInvalidFields discards malformed serialized metadata fields that + // cannot be successfully decoded to the corresponding ObjectMeta field. + // This only applies to fields that are recognized as part of the schema, + // but of an invalid type (i.e. cause an error when unmarshaling, rather + // than being dropped or causing a strictErr). + DropInvalidFields bool + // ReturnUnknownFieldPaths will return the paths to fields that are not + // recognized as part of the schema. + ReturnUnknownFieldPaths bool +} + // Coerce checks types of embedded ObjectMeta and TypeMeta and prunes unknown fields inside the former. // It does coerce ObjectMeta and TypeMeta at the root if isResourceRoot is true. -// If dropInvalidFields is true, fields of wrong type will be dropped. -func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot, dropInvalidFields bool) *field.Error { +// If opts.ReturnUnknownFieldPaths is true, it will return the paths of any fields that are not a part of the +// schema that are dropped when unmarshaling. +// If opts.DropInvalidFields is true, fields of wrong type will be dropped. +func CoerceWithOptions(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts CoerceOptions) (*field.Error, []string) { if isResourceRoot { if s == nil { s = &structuralschema.Structural{} @@ -36,36 +55,57 @@ func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, is s = &clone } } - c := coercer{dropInvalidFields: dropInvalidFields} - return c.coerce(pth, obj, s) + c := coercer{DropInvalidFields: opts.DropInvalidFields, ReturnUnknownFieldPaths: opts.ReturnUnknownFieldPaths} + schemaOpts := &structuralschema.UnknownFieldPathOptions{ + TrackUnknownFieldPaths: opts.ReturnUnknownFieldPaths, + } + fieldErr := c.coerce(pth, obj, s, schemaOpts) + sort.Strings(schemaOpts.UnknownFieldPaths) + return fieldErr, schemaOpts.UnknownFieldPaths +} + +// Coerce calls CoerceWithOptions without returning unknown field paths. +func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot, dropInvalidFields bool) *field.Error { + fieldErr, _ := CoerceWithOptions(pth, obj, s, isResourceRoot, CoerceOptions{DropInvalidFields: dropInvalidFields}) + return fieldErr } type coercer struct { - dropInvalidFields bool + DropInvalidFields bool + ReturnUnknownFieldPaths bool } -func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Structural) *field.Error { +func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) *field.Error { if s == nil { return nil } + origPathLen := len(opts.ParentPath) + defer func() { + opts.ParentPath = opts.ParentPath[:origPathLen] + }() switch x := x.(type) { case map[string]interface{}: for k, v := range x { if s.XEmbeddedResource { switch k { case "apiVersion", "kind": - if _, ok := v.(string); !ok && c.dropInvalidFields { + if _, ok := v.(string); !ok && c.DropInvalidFields { delete(x, k) } else if !ok { return field.Invalid(pth.Child(k), v, "must be a string") } case "metadata": - meta, found, err := GetObjectMeta(x, c.dropInvalidFields) + meta, found, unknownFields, err := GetObjectMetaWithOptions(x, ObjectMetaOptions{ + DropMalformedFields: c.DropInvalidFields, + ReturnUnknownFieldPaths: c.ReturnUnknownFieldPaths, + ParentPath: pth, + }) + opts.UnknownFieldPaths = append(opts.UnknownFieldPaths, unknownFields...) if err != nil { - if !c.dropInvalidFields { + if !c.DropInvalidFields { return field.Invalid(pth.Child("metadata"), v, err.Error()) } - // pass through on error if dropInvalidFields is true + // pass through on error if DropInvalidFields is true } else if found { if err := SetObjectMeta(x, meta); err != nil { return field.Invalid(pth.Child("metadata"), v, err.Error()) @@ -78,20 +118,26 @@ func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Str } prop, ok := s.Properties[k] if ok { - if err := c.coerce(pth.Child(k), v, &prop); err != nil { + opts.AppendKey(k) + if err := c.coerce(pth.Child(k), v, &prop, opts); err != nil { return err } + opts.ParentPath = opts.ParentPath[:origPathLen] } else if s.AdditionalProperties != nil { - if err := c.coerce(pth.Key(k), v, s.AdditionalProperties.Structural); err != nil { + opts.AppendKey(k) + if err := c.coerce(pth.Key(k), v, s.AdditionalProperties.Structural, opts); err != nil { return err } + opts.ParentPath = opts.ParentPath[:origPathLen] } } case []interface{}: for i, v := range x { - if err := c.coerce(pth.Index(i), v, s.Items); err != nil { + opts.AppendIndex(i) + if err := c.coerce(pth.Index(i), v, s.Items, opts); err != nil { return err } + opts.ParentPath = opts.ParentPath[:origPathLen] } default: // scalars, do nothing diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/coerce.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/coerce.go index d9c486c37ef..42b968b8ac4 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/coerce.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta/coerce.go @@ -23,35 +23,83 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" utiljson "k8s.io/apimachinery/pkg/util/json" + "k8s.io/apimachinery/pkg/util/validation/field" + kjson "sigs.k8s.io/json" ) -// GetObjectMeta does conversion of JSON to ObjectMeta. It first tries json.Unmarshal into a metav1.ObjectMeta -// type. If that does not work and dropMalformedFields is true, it does field-by-field best-effort conversion -// throwing away fields which lead to errors. +// GetObjectMeta calls GetObjectMetaWithOptions without returning unknown field paths. func GetObjectMeta(obj map[string]interface{}, dropMalformedFields bool) (*metav1.ObjectMeta, bool, error) { + meta, found, _, err := GetObjectMetaWithOptions(obj, ObjectMetaOptions{ + DropMalformedFields: dropMalformedFields, + }) + return meta, found, err +} + +// ObjectMetaOptions provides the options for how GetObjectMeta should retrieve the object meta. +type ObjectMetaOptions struct { + // DropMalformedFields discards malformed serialized metadata fields that + // cannot be successfully decoded to the corresponding ObjectMeta field. + // This only applies to fields that are recognized as part of the schema, + // but of an invalid type (i.e. cause an error when unmarshaling, rather + // than being dropped or causing a strictErr). + DropMalformedFields bool + // ReturnUnknownFieldPaths will return the paths to fields that are not + // recognized as part of the schema. + ReturnUnknownFieldPaths bool + // ParentPath provides the current path up to the given ObjectMeta. + // If nil, the metadata is assumed to be at the root of the object. + ParentPath *field.Path +} + +// GetObjectMetaWithOptions does conversion of JSON to ObjectMeta. +// It first tries json.Unmarshal into a metav1.ObjectMeta +// type. If that does not work and opts.DropMalformedFields is true, it does field-by-field best-effort conversion +// throwing away fields which lead to errors. +// If opts.ReturnedUnknownFields is true, it will UnmarshalStrict instead, returning the paths of any unknown fields +// it encounters (i.e. paths returned as strict errs from UnmarshalStrict) +func GetObjectMetaWithOptions(obj map[string]interface{}, opts ObjectMetaOptions) (*metav1.ObjectMeta, bool, []string, error) { metadata, found := obj["metadata"] if !found { - return nil, false, nil + return nil, false, nil, nil } // round-trip through JSON first, hoping that unmarshalling just works objectMeta := &metav1.ObjectMeta{} metadataBytes, err := utiljson.Marshal(metadata) if err != nil { - return nil, false, err + return nil, false, nil, err } - if err = utiljson.Unmarshal(metadataBytes, objectMeta); err == nil { - // if successful, return - return objectMeta, true, nil + var unmarshalErr error + if opts.ReturnUnknownFieldPaths { + var strictErrs []error + strictErrs, unmarshalErr = kjson.UnmarshalStrict(metadataBytes, objectMeta) + if unmarshalErr == nil { + if len(strictErrs) > 0 { + unknownPaths := []string{} + prefix := opts.ParentPath.Child("metadata").String() + for _, err := range strictErrs { + if fieldPathErr, ok := err.(kjson.FieldError); ok { + unknownPaths = append(unknownPaths, prefix+"."+fieldPathErr.FieldPath()) + } + } + return objectMeta, true, unknownPaths, nil + } + return objectMeta, true, nil, nil + } + } else { + if unmarshalErr = utiljson.Unmarshal(metadataBytes, objectMeta); unmarshalErr == nil { + // if successful, return + return objectMeta, true, nil, nil + } } - if !dropMalformedFields { + if !opts.DropMalformedFields { // if we're not trying to drop malformed fields, return the error - return nil, true, err + return nil, true, nil, unmarshalErr } metadataMap, ok := metadata.(map[string]interface{}) if !ok { - return nil, false, fmt.Errorf("invalid metadata: expected object, got %T", metadata) + return nil, false, nil, fmt.Errorf("invalid metadata: expected object, got %T", metadata) } // Go field by field accumulating into the metadata object. @@ -59,18 +107,31 @@ func GetObjectMeta(obj map[string]interface{}, dropMalformedFields bool) (*metav // each iteration preserving the old key-values. accumulatedObjectMeta := &metav1.ObjectMeta{} testObjectMeta := &metav1.ObjectMeta{} + var unknownFields []string for k, v := range metadataMap { // serialize a single field if singleFieldBytes, err := utiljson.Marshal(map[string]interface{}{k: v}); err == nil { // do a test unmarshal if utiljson.Unmarshal(singleFieldBytes, testObjectMeta) == nil { // if that succeeds, unmarshal for real - utiljson.Unmarshal(singleFieldBytes, accumulatedObjectMeta) + if opts.ReturnUnknownFieldPaths { + strictErrs, _ := kjson.UnmarshalStrict(singleFieldBytes, accumulatedObjectMeta) + if len(strictErrs) > 0 { + prefix := opts.ParentPath.Child("metadata").String() + for _, err := range strictErrs { + if fieldPathErr, ok := err.(kjson.FieldError); ok { + unknownFields = append(unknownFields, prefix+"."+fieldPathErr.FieldPath()) + } + } + } + } else { + utiljson.Unmarshal(singleFieldBytes, accumulatedObjectMeta) + } } } } - return accumulatedObjectMeta, true, nil + return accumulatedObjectMeta, true, unknownFields, nil } // SetObjectMeta writes back ObjectMeta into a JSON data structure. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/options.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/options.go new file mode 100644 index 00000000000..547e5917519 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/options.go @@ -0,0 +1,67 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schema + +import ( + "strconv" + "strings" +) + +// UnknownFieldPathOptions allow for tracking paths to unknown fields. +type UnknownFieldPathOptions struct { + // TrackUnknownFieldPaths determines whether or not unknown field + // paths should be stored or not. + TrackUnknownFieldPaths bool + // ParentPath builds the path to unknown fields as the object + // is recursively traversed. + ParentPath []string + // UnknownFieldPaths is the list of all unknown fields identified. + UnknownFieldPaths []string +} + +// RecordUnknownFields adds a path to an unknown field to the +// record of UnknownFieldPaths, if TrackUnknownFieldPaths is true +func (o *UnknownFieldPathOptions) RecordUnknownField(field string) { + if !o.TrackUnknownFieldPaths { + return + } + l := len(o.ParentPath) + o.AppendKey(field) + o.UnknownFieldPaths = append(o.UnknownFieldPaths, strings.Join(o.ParentPath, "")) + o.ParentPath = o.ParentPath[:l] +} + +// AppendKey adds a key (i.e. field) to the current parent +// path, if TrackUnknownFieldPaths is true. +func (o *UnknownFieldPathOptions) AppendKey(key string) { + if !o.TrackUnknownFieldPaths { + return + } + if len(o.ParentPath) > 0 { + o.ParentPath = append(o.ParentPath, ".") + } + o.ParentPath = append(o.ParentPath, key) +} + +// AppendIndex adds an index to the most recent field of +// the current parent path, if TrackUnknownFieldPaths is true. +func (o *UnknownFieldPathOptions) AppendIndex(index int) { + if !o.TrackUnknownFieldPaths { + return + } + o.ParentPath = append(o.ParentPath, "[", strconv.Itoa(index), "]") +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning/algorithm.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning/algorithm.go index b2b1bf81fbd..a929e52522c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning/algorithm.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning/algorithm.go @@ -18,37 +18,15 @@ package pruning import ( "sort" - "strconv" - "strings" structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" ) -// PruneOptions sets options for pruning -// unknown fields -type PruneOptions struct { - // parentPath collects the path that the pruning - // takes as it traverses the object. - // It is used to report the full path to any unknown - // fields that the pruning encounters. - // It is only populated if ReturnPruned is true. - parentPath []string - - // prunedPaths collects pruned field paths resulting from - // calls to recordPrunedKey. - // It is only populated if ReturnPruned is true. - prunedPaths []string - - // ReturnPruned defines whether we want to track the - // fields that are pruned - ReturnPruned bool -} - // PruneWithOptions removes object fields in obj which are not specified in s. It skips TypeMeta // and ObjectMeta fields if XEmbeddedResource is set to true, or for the root if isResourceRoot=true, // i.e. it does not prune unknown metadata fields. -// It returns the set of fields that it prunes if opts.ReturnPruned is true -func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts PruneOptions) []string { +// It returns the set of fields that it prunes if opts.TrackUnknownFieldPaths is true +func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts structuralschema.UnknownFieldPathOptions) []string { if isResourceRoot { if s == nil { s = &structuralschema.Structural{} @@ -60,14 +38,14 @@ func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourc } } prune(obj, s, &opts) - sort.Strings(opts.prunedPaths) - return opts.prunedPaths + sort.Strings(opts.UnknownFieldPaths) + return opts.UnknownFieldPaths } // Prune is equivalent to -// PruneWithOptions(obj, s, isResourceRoot, PruneOptions{}) +// PruneWithOptions(obj, s, isResourceRoot, structuralschema.UnknownFieldPathOptions{}) func Prune(obj interface{}, s *structuralschema.Structural, isResourceRoot bool) { - PruneWithOptions(obj, s, isResourceRoot, PruneOptions{}) + PruneWithOptions(obj, s, isResourceRoot, structuralschema.UnknownFieldPathOptions{}) } var metaFields = map[string]bool{ @@ -76,48 +54,21 @@ var metaFields = map[string]bool{ "metadata": true, } -func (p *PruneOptions) recordPrunedKey(key string) { - if !p.ReturnPruned { - return - } - l := len(p.parentPath) - p.appendKey(key) - p.prunedPaths = append(p.prunedPaths, strings.Join(p.parentPath, "")) - p.parentPath = p.parentPath[:l] -} - -func (p *PruneOptions) appendKey(key string) { - if !p.ReturnPruned { - return - } - if len(p.parentPath) > 0 { - p.parentPath = append(p.parentPath, ".") - } - p.parentPath = append(p.parentPath, key) -} - -func (p *PruneOptions) appendIndex(index int) { - if !p.ReturnPruned { - return - } - p.parentPath = append(p.parentPath, "[", strconv.Itoa(index), "]") -} - -func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) { +func prune(x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) { if s != nil && s.XPreserveUnknownFields { skipPrune(x, s, opts) return } - origPathLen := len(opts.parentPath) + origPathLen := len(opts.ParentPath) defer func() { - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] }() switch x := x.(type) { case map[string]interface{}: if s == nil { for k := range x { - opts.recordPrunedKey(k) + opts.RecordUnknownField(k) delete(x, k) } return @@ -128,16 +79,16 @@ func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) { } prop, ok := s.Properties[k] if ok { - opts.appendKey(k) + opts.AppendKey(k) prune(v, &prop, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } else if s.AdditionalProperties != nil { - opts.appendKey(k) + opts.AppendKey(k) prune(v, s.AdditionalProperties.Structural, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } else { - if !metaFields[k] || len(opts.parentPath) > 0 { - opts.recordPrunedKey(k) + if !metaFields[k] || len(opts.ParentPath) > 0 { + opts.RecordUnknownField(k) } delete(x, k) } @@ -145,29 +96,29 @@ func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) { case []interface{}: if s == nil { for i, v := range x { - opts.appendIndex(i) + opts.AppendIndex(i) prune(v, nil, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } return } for i, v := range x { - opts.appendIndex(i) + opts.AppendIndex(i) prune(v, s.Items, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } default: // scalars, do nothing } } -func skipPrune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) { +func skipPrune(x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) { if s == nil { return } - origPathLen := len(opts.parentPath) + origPathLen := len(opts.ParentPath) defer func() { - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] }() switch x := x.(type) { @@ -177,20 +128,20 @@ func skipPrune(x interface{}, s *structuralschema.Structural, opts *PruneOptions continue } if prop, ok := s.Properties[k]; ok { - opts.appendKey(k) + opts.AppendKey(k) prune(v, &prop, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } else if s.AdditionalProperties != nil { - opts.appendKey(k) + opts.AppendKey(k) prune(v, s.AdditionalProperties.Structural, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } } case []interface{}: for i, v := range x { - opts.appendIndex(i) + opts.AppendIndex(i) skipPrune(v, s.Items, opts) - opts.parentPath = opts.parentPath[:origPathLen] + opts.ParentPath = opts.ParentPath[:origPathLen] } default: // scalars, do nothing diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/validation.go index e2966341a7b..f7f29e70c4b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/validation.go @@ -48,14 +48,14 @@ const ( // * RawExtension: for every schema with `x-kubernetes-embedded-resource: true`, `x-kubernetes-preserve-unknown-fields: true` and `type: object` are set // * IntOrString: for `x-kubernetes-int-or-string: true` either `type` is empty under `anyOf` and `allOf` or the schema structure is one of these: // -// 1) anyOf: -// - type: integer -// - type: string -// 2) allOf: -// - anyOf: -// - type: integer -// - type: string -// - ... zero or more +// 1. anyOf: +// - type: integer +// - type: string +// 2. allOf: +// - anyOf: +// - type: integer +// - type: string +// - ... zero or more // // * every specified field or array in s is also specified outside of value validation. // * metadata at the root can only restrict the name and generateName, and not be specified at all in nested contexts. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go index 65ae76067df..13fc8159426 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go @@ -35,8 +35,7 @@ type Interface interface { ApiextensionsV1() apiextensionsv1.ApiextensionsV1Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient apiextensionsV1beta1 *apiextensionsv1beta1.ApiextensionsV1beta1Client diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go deleted file mode 100644 index ee865e56d1d..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. -package clientset diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go index 144c20666d2..25fca99178b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go @@ -39,14 +39,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/LICENSE b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/LICENSE deleted file mode 100644 index 7a4a3ea2424..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/README.md b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/README.md deleted file mode 100644 index 6b38d871535..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/README.md +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains a port of https://github.com/google/cel-policy-templates-go/tree/master/policy/model modified in a few ways: - -- Uses the Structural schema types -- All template related code has been removed diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/escaping.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/escaping.go deleted file mode 100644 index 2f841b58bfc..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/escaping.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package model - -import ( - "regexp" - - "k8s.io/apimachinery/pkg/util/sets" -) - -// celReservedSymbols is a list of RESERVED symbols defined in the CEL lexer. -// No identifiers are allowed to collide with these symbols. -// https://github.com/google/cel-spec/blob/master/doc/langdef.md#syntax -var celReservedSymbols = sets.NewString( - "true", "false", "null", "in", - "as", "break", "const", "continue", "else", - "for", "function", "if", "import", "let", - "loop", "package", "namespace", "return", // !! 'namespace' is used heavily in Kubernetes - "var", "void", "while", -) - -// expandMatcher matches the escape sequence, characters that are escaped, and characters that are unsupported -var expandMatcher = regexp.MustCompile(`(__|[-./]|[^a-zA-Z0-9-./_])`) - -// Escape escapes ident and returns a CEL identifier (of the form '[a-zA-Z_][a-zA-Z0-9_]*'), or returns -// false if the ident does not match the supported input format of `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*`. -// Escaping Rules: -// - '__' escapes to '__underscores__' -// - '.' escapes to '__dot__' -// - '-' escapes to '__dash__' -// - '/' escapes to '__slash__' -// - Identifiers that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are: "true", "false", -// "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if", "import", "let", loop", "package", -// "namespace", "return". -func Escape(ident string) (string, bool) { - if len(ident) == 0 || ('0' <= ident[0] && ident[0] <= '9') { - return "", false - } - if celReservedSymbols.Has(ident) { - return "__" + ident + "__", true - } - ok := true - ident = expandMatcher.ReplaceAllStringFunc(ident, func(s string) string { - switch s { - case "__": - return "__underscores__" - case ".": - return "__dot__" - case "-": - return "__dash__" - case "/": - return "__slash__" - default: // matched a unsupported supported - ok = false - return "" - } - }) - if !ok { - return "", false - } - return ident, true -} - -var unexpandMatcher = regexp.MustCompile(`(_{2}[^_]+_{2})`) - -// Unescape unescapes an CEL identifier containing the escape sequences described in Escape, or return false if the -// string contains invalid escape sequences. The escaped input is expected to be a valid CEL identifier, but is -// not checked. -func Unescape(escaped string) (string, bool) { - ok := true - escaped = unexpandMatcher.ReplaceAllStringFunc(escaped, func(s string) string { - contents := s[2 : len(s)-2] - switch contents { - case "underscores": - return "__" - case "dot": - return "." - case "dash": - return "-" - case "slash": - return "/" - } - if celReservedSymbols.Has(contents) { - if len(s) != len(escaped) { - ok = false - } - return contents - } - ok = false - return "" - }) - if !ok { - return "", false - } - return escaped, true -} diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/registry.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/registry.go deleted file mode 100644 index 120c49fc64a..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/registry.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sync" - - "github.com/google/cel-go/cel" - "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" -) - -// Resolver declares methods to find policy templates and related configuration objects. -type Resolver interface { - // FindType returns a DeclType instance corresponding to the given fully-qualified name, if - // present. - FindType(name string) (*DeclType, bool) -} - -// NewRegistry create a registry for keeping track of environments, schemas, templates, and more -// from a base cel.Env expression environment. -func NewRegistry(stdExprEnv *cel.Env) *Registry { - return &Registry{ - exprEnvs: map[string]*cel.Env{"": stdExprEnv}, - schemas: map[string]*schema.Structural{}, - types: map[string]*DeclType{ - BoolType.TypeName(): BoolType, - BytesType.TypeName(): BytesType, - DoubleType.TypeName(): DoubleType, - DurationType.TypeName(): DurationType, - IntType.TypeName(): IntType, - NullType.TypeName(): NullType, - StringType.TypeName(): StringType, - TimestampType.TypeName(): TimestampType, - UintType.TypeName(): UintType, - ListType.TypeName(): ListType, - MapType.TypeName(): MapType, - }, - } -} - -// Registry defines a repository of environment, schema, template, and type definitions. -// -// Registry instances are concurrency-safe. -type Registry struct { - rwMux sync.RWMutex - exprEnvs map[string]*cel.Env - schemas map[string]*schema.Structural - types map[string]*DeclType -} - -// FindType implements the Resolver interface method. -func (r *Registry) FindType(name string) (*DeclType, bool) { - r.rwMux.RLock() - defer r.rwMux.RUnlock() - typ, found := r.types[name] - if found { - return typ, true - } - return typ, found -} - -// SetType registers a DeclType descriptor by its fully qualified name. -func (r *Registry) SetType(name string, declType *DeclType) error { - r.rwMux.Lock() - defer r.rwMux.Unlock() - r.types[name] = declType - return nil -} diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/schemas.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/schemas.go deleted file mode 100644 index b6a92a938e8..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/schemas.go +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "time" - - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - - "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" -) - -const ( - // the largest request that will be accepted is 3MB - // TODO(DangerOnTheRanger): wire in MaxRequestBodyBytes from apiserver/pkg/server/options/server_run_options.go to make this configurable - maxRequestSizeBytes = int64(3 * 1024 * 1024) - // OpenAPI duration strings follow RFC 3339, section 5.6 - see the comment on maxDatetimeSizeJSON - maxDurationSizeJSON = 32 - // OpenAPI datetime strings follow RFC 3339, section 5.6, and the longest possible - // such string is 9999-12-31T23:59:59.999999999Z, which has length 30 - we add 2 - // to allow for quotation marks - maxDatetimeSizeJSON = 32 - // Golang allows a string of 0 to be parsed as a duration, so that plus 2 to account for - // quotation marks makes 3 - minDurationSizeJSON = 3 - // RFC 3339 dates require YYYY-MM-DD, and then we add 2 to allow for quotation marks - dateSizeJSON = 12 - // RFC 3339 times require 2-digit 24-hour time at the very least plus a capital T at the start, - // e.g., T23, and we add 2 to allow for quotation marks as usual - minTimeSizeJSON = 5 - // RFC 3339 datetimes require a full date (YYYY-MM-DD) and full time (HH:MM:SS), and we add 3 for - // quotation marks like always in addition to the capital T that separates the date and time - minDatetimeSizeJSON = 21 -) - -// SchemaDeclType converts the structural schema to a CEL declaration, or returns nil if the -// the structural schema should not be exposed in CEL expressions. -// Set isResourceRoot to true for the root of a custom resource or embedded resource. -// -// Schemas with XPreserveUnknownFields not exposed unless they are objects. Array and "maps" schemas -// are not exposed if their items or additionalProperties schemas are not exposed. Object Properties are not exposed -// if their schema is not exposed. -// -// The CEL declaration for objects with XPreserveUnknownFields does not expose unknown fields. -func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType { - if s == nil { - return nil - } - if s.XIntOrString { - // schemas using XIntOrString are not required to have a type. - - // intOrStringType represents the x-kubernetes-int-or-string union type in CEL expressions. - // In CEL, the type is represented as dynamic value, which can be thought of as a union type of all types. - // All type checking for XIntOrString is deferred to runtime, so all access to values of this type must - // be guarded with a type check, e.g.: - // - // To require that the string representation be a percentage: - // `type(intOrStringField) == string && intOrStringField.matches(r'(\d+(\.\d+)?%)')` - // To validate requirements on both the int and string representation: - // `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5 - // - dyn := newSimpleType("dyn", decls.Dyn, nil) - // handle x-kubernetes-int-or-string by returning the max length of the largest possible string - dyn.MaxElements = maxRequestSizeBytes - 2 - return dyn - } - - // We ignore XPreserveUnknownFields since we don't support validation rules on - // data that we don't have schema information for. - - if isResourceRoot { - // 'apiVersion', 'kind', 'metadata.name' and 'metadata.generateName' are always accessible to validator rules - // at the root of resources, even if not specified in the schema. - // This includes the root of a custom resource and the root of XEmbeddedResource objects. - s = WithTypeAndObjectMeta(s) - } - - switch s.Type { - case "array": - if s.Items != nil { - itemsType := SchemaDeclType(s.Items, s.Items.XEmbeddedResource) - var maxItems int64 - if s.ValueValidation != nil && s.ValueValidation.MaxItems != nil { - maxItems = zeroIfNegative(*s.ValueValidation.MaxItems) - } else { - maxItems = estimateMaxArrayItemsPerRequest(s.Items) - } - if itemsType != nil { - return NewListType(itemsType, maxItems) - } - } - return nil - case "object": - if s.AdditionalProperties != nil && s.AdditionalProperties.Structural != nil { - propsType := SchemaDeclType(s.AdditionalProperties.Structural, s.AdditionalProperties.Structural.XEmbeddedResource) - if propsType != nil { - var maxProperties int64 - if s.ValueValidation != nil && s.ValueValidation.MaxProperties != nil { - maxProperties = zeroIfNegative(*s.ValueValidation.MaxProperties) - } else { - maxProperties = estimateMaxAdditionalPropertiesPerRequest(s.AdditionalProperties.Structural) - } - return NewMapType(StringType, propsType, maxProperties) - } - return nil - } - fields := make(map[string]*DeclField, len(s.Properties)) - - required := map[string]bool{} - if s.ValueValidation != nil { - for _, f := range s.ValueValidation.Required { - required[f] = true - } - } - for name, prop := range s.Properties { - var enumValues []interface{} - if prop.ValueValidation != nil { - for _, e := range prop.ValueValidation.Enum { - enumValues = append(enumValues, e.Object) - } - } - if fieldType := SchemaDeclType(&prop, prop.XEmbeddedResource); fieldType != nil { - if propName, ok := Escape(name); ok { - fields[propName] = &DeclField{ - Name: propName, - Required: required[name], - Type: fieldType, - defaultValue: prop.Default.Object, - enumValues: enumValues, // Enum values are represented as strings in CEL - } - } - } - } - return NewObjectType("object", fields) - case "string": - if s.ValueValidation != nil { - switch s.ValueValidation.Format { - case "byte": - byteWithMaxLength := newSimpleType("bytes", decls.Bytes, types.Bytes([]byte{})) - if s.ValueValidation.MaxLength != nil { - byteWithMaxLength.MaxElements = zeroIfNegative(*s.ValueValidation.MaxLength) - } else { - byteWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) - } - return byteWithMaxLength - case "duration": - durationWithMaxLength := newSimpleType("duration", decls.Duration, types.Duration{Duration: time.Duration(0)}) - durationWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) - return durationWithMaxLength - case "date", "date-time": - timestampWithMaxLength := newSimpleType("timestamp", decls.Timestamp, types.Timestamp{Time: time.Time{}}) - timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) - return timestampWithMaxLength - } - } - strWithMaxLength := newSimpleType("string", decls.String, types.String("")) - if s.ValueValidation != nil && s.ValueValidation.MaxLength != nil { - // multiply the user-provided max length by 4 in the case of an otherwise-untyped string - // we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points, - // but we need to reason about length for things like request size, so we use bytes in this code (and an individual - // unicode code point can be up to 4 bytes long) - strWithMaxLength.MaxElements = zeroIfNegative(*s.ValueValidation.MaxLength) * 4 - } else { - strWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) - } - return strWithMaxLength - case "boolean": - return BoolType - case "number": - return DoubleType - case "integer": - return IntType - } - return nil -} - -func zeroIfNegative(v int64) int64 { - if v < 0 { - return 0 - } - return v -} - -// WithTypeAndObjectMeta ensures the kind, apiVersion and -// metadata.name and metadata.generateName properties are specified, making a shallow copy of the provided schema if needed. -func WithTypeAndObjectMeta(s *schema.Structural) *schema.Structural { - if s.Properties != nil && - s.Properties["kind"].Type == "string" && - s.Properties["apiVersion"].Type == "string" && - s.Properties["metadata"].Type == "object" && - s.Properties["metadata"].Properties != nil && - s.Properties["metadata"].Properties["name"].Type == "string" && - s.Properties["metadata"].Properties["generateName"].Type == "string" { - return s - } - result := &schema.Structural{ - Generic: s.Generic, - Extensions: s.Extensions, - ValueValidation: s.ValueValidation, - } - props := make(map[string]schema.Structural, len(s.Properties)) - for k, prop := range s.Properties { - props[k] = prop - } - stringType := schema.Structural{Generic: schema.Generic{Type: "string"}} - props["kind"] = stringType - props["apiVersion"] = stringType - props["metadata"] = schema.Structural{ - Generic: schema.Generic{Type: "object"}, - Properties: map[string]schema.Structural{ - "name": stringType, - "generateName": stringType, - }, - } - result.Properties = props - - return result -} - -// MaxCardinality returns the maximum number of times data conforming to the schema could possibly exist in -// an object serialized to JSON. For cases where a schema is contained under map or array schemas of unbounded -// size, this can be used as an estimate as the worst case number of times data matching the schema could be repeated. -// Note that this only assumes a single comma between data elements, so if the schema is contained under only maps, -// this estimates a higher cardinality that would be possible. -func MaxCardinality(s *schema.Structural) uint64 { - sz := estimateMinSizeJSON(s) + 1 // assume at least one comma between elements - return uint64(maxRequestSizeBytes / sz) -} - -// estimateMinSizeJSON estimates the minimum size in bytes of the given schema when serialized in JSON. -// minLength/minProperties/minItems are not currently taken into account, so if these limits are set the -// minimum size might be higher than what estimateMinSizeJSON returns. -func estimateMinSizeJSON(s *schema.Structural) int64 { - if s == nil { - // minimum valid JSON token has length 1 (single-digit number like `0`) - return 1 - } - switch s.Type { - case "boolean": - // true - return 4 - case "number", "integer": - // 0 - return 1 - case "string": - if s.ValueValidation != nil { - switch s.ValueValidation.Format { - case "duration": - return minDurationSizeJSON - case "date": - return dateSizeJSON - case "date-time": - return minDatetimeSizeJSON - } - } - // "" - return 2 - case "array": - // [] - return 2 - case "object": - // {} - objSize := int64(2) - // exclude optional fields since the request can omit them - if s.ValueValidation != nil { - for _, propName := range s.ValueValidation.Required { - if prop, ok := s.Properties[propName]; ok { - if prop.Default.Object != nil { - // exclude fields with a default, those are filled in server-side - continue - } - // add 4, 2 for quotations around the property name, 1 for the colon, and 1 for a comma - objSize += int64(len(propName)) + estimateMinSizeJSON(&prop) + 4 - } - } - } - return objSize - } - if s.XIntOrString { - // 0 - return 1 - } - // this code should be unreachable, so return the safest possible value considering this can be used as - // a divisor - return 1 -} - -// estimateMaxArrayItemsPerRequest estimates the maximum number of array items with -// the provided schema that can fit into a single request. -func estimateMaxArrayItemsPerRequest(itemSchema *schema.Structural) int64 { - // subtract 2 to account for [ and ] - return (maxRequestSizeBytes - 2) / (estimateMinSizeJSON(itemSchema) + 1) -} - -// estimateMaxStringLengthPerRequest estimates the maximum string length (in characters) -// of a string compatible with the format requirements in the provided schema. -// must only be called on schemas of type "string" or x-kubernetes-int-or-string: true -func estimateMaxStringLengthPerRequest(s *schema.Structural) int64 { - if s.ValueValidation == nil || s.XIntOrString { - // subtract 2 to account for "" - return (maxRequestSizeBytes - 2) - } - switch s.ValueValidation.Format { - case "duration": - return maxDurationSizeJSON - case "date": - return dateSizeJSON - case "date-time": - return maxDatetimeSizeJSON - default: - // subtract 2 to account for "" - return (maxRequestSizeBytes - 2) - } -} - -// estimateMaxAdditionalPropertiesPerRequest estimates the maximum number of additional properties -// with the provided schema that can fit into a single request. -func estimateMaxAdditionalPropertiesPerRequest(additionalPropertiesSchema *schema.Structural) int64 { - // 2 bytes for key + "" + colon + comma + smallest possible value, realistically the actual keys - // will all vary in length - keyValuePairSize := estimateMinSizeJSON(additionalPropertiesSchema) + 6 - // subtract 2 to account for { and } - return (maxRequestSizeBytes - 2) / keyValuePairSize -} diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/types.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/types.go deleted file mode 100644 index 2f0a5b59dcd..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/types.go +++ /dev/null @@ -1,562 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "math" - "time" - - "github.com/google/cel-go/cel" - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" - "google.golang.org/protobuf/proto" - - "k8s.io/apiextensions-apiserver/pkg/apiserver/schema" -) - -const ( - noMaxLength = math.MaxInt -) - -// NewListType returns a parameterized list type with a specified element type. -func NewListType(elem *DeclType, maxItems int64) *DeclType { - return &DeclType{ - name: "list", - ElemType: elem, - MaxElements: maxItems, - exprType: decls.NewListType(elem.ExprType()), - defaultValue: NewListValue(), - } -} - -// NewMapType returns a parameterized map type with the given key and element types. -func NewMapType(key, elem *DeclType, maxProperties int64) *DeclType { - return &DeclType{ - name: "map", - KeyType: key, - ElemType: elem, - MaxElements: maxProperties, - exprType: decls.NewMapType(key.ExprType(), elem.ExprType()), - defaultValue: NewMapValue(), - } -} - -// NewObjectType creates an object type with a qualified name and a set of field declarations. -func NewObjectType(name string, fields map[string]*DeclField) *DeclType { - t := &DeclType{ - name: name, - Fields: fields, - exprType: decls.NewObjectType(name), - traitMask: traits.FieldTesterType | traits.IndexerType, - } - t.defaultValue = NewObjectValue(t) - return t -} - -// NewObjectTypeRef returns a reference to an object type by name -func NewObjectTypeRef(name string) *DeclType { - t := &DeclType{ - name: name, - exprType: decls.NewObjectType(name), - traitMask: traits.FieldTesterType | traits.IndexerType, - } - return t -} - -// NewTypeParam creates a type parameter type with a simple name. -// -// Type parameters are resolved at compilation time to concrete types, or CEL 'dyn' type if no -// type assignment can be inferred. -func NewTypeParam(name string) *DeclType { - return &DeclType{ - name: name, - TypeParam: true, - exprType: decls.NewTypeParamType(name), - } -} - -func newSimpleType(name string, exprType *exprpb.Type, zeroVal ref.Val) *DeclType { - return &DeclType{ - name: name, - exprType: exprType, - defaultValue: zeroVal, - } -} - -// DeclType represents the universal type descriptor for OpenAPIv3 types. -type DeclType struct { - fmt.Stringer - - name string - Fields map[string]*DeclField - KeyType *DeclType - ElemType *DeclType - TypeParam bool - Metadata map[string]string - MaxElements int64 - - exprType *exprpb.Type - traitMask int - defaultValue ref.Val -} - -// MaybeAssignTypeName attempts to set the DeclType name to a fully qualified name, if the type -// is of `object` type. -// -// The DeclType must return true for `IsObject` or this assignment will error. -func (t *DeclType) MaybeAssignTypeName(name string) *DeclType { - if t.IsObject() { - objUpdated := false - if t.name != "object" { - name = t.name - } else { - objUpdated = true - } - fieldMap := make(map[string]*DeclField, len(t.Fields)) - for fieldName, field := range t.Fields { - fieldType := field.Type - fieldTypeName := fmt.Sprintf("%s.%s", name, fieldName) - updated := fieldType.MaybeAssignTypeName(fieldTypeName) - if updated == fieldType { - fieldMap[fieldName] = field - continue - } - objUpdated = true - fieldMap[fieldName] = &DeclField{ - Name: fieldName, - Type: updated, - Required: field.Required, - enumValues: field.enumValues, - defaultValue: field.defaultValue, - } - } - if !objUpdated { - return t - } - return &DeclType{ - name: name, - Fields: fieldMap, - KeyType: t.KeyType, - ElemType: t.ElemType, - TypeParam: t.TypeParam, - Metadata: t.Metadata, - exprType: decls.NewObjectType(name), - traitMask: t.traitMask, - defaultValue: t.defaultValue, - } - } - if t.IsMap() { - elemTypeName := fmt.Sprintf("%s.@elem", name) - updated := t.ElemType.MaybeAssignTypeName(elemTypeName) - if updated == t.ElemType { - return t - } - return NewMapType(t.KeyType, updated, t.MaxElements) - } - if t.IsList() { - elemTypeName := fmt.Sprintf("%s.@idx", name) - updated := t.ElemType.MaybeAssignTypeName(elemTypeName) - if updated == t.ElemType { - return t - } - return NewListType(updated, t.MaxElements) - } - return t -} - -// ExprType returns the CEL expression type of this declaration. -func (t *DeclType) ExprType() *exprpb.Type { - return t.exprType -} - -// FindField returns the DeclField with the given name if present. -func (t *DeclType) FindField(name string) (*DeclField, bool) { - f, found := t.Fields[name] - return f, found -} - -// HasTrait implements the CEL ref.Type interface making this type declaration suitable for use -// within the CEL evaluator. -func (t *DeclType) HasTrait(trait int) bool { - if t.traitMask&trait == trait { - return true - } - if t.defaultValue == nil { - return false - } - _, isDecl := t.defaultValue.Type().(*DeclType) - if isDecl { - return false - } - return t.defaultValue.Type().HasTrait(trait) -} - -// IsList returns whether the declaration is a `list` type which defines a parameterized element -// type, but not a parameterized key type or fields. -func (t *DeclType) IsList() bool { - return t.KeyType == nil && t.ElemType != nil && t.Fields == nil -} - -// IsMap returns whether the declaration is a 'map' type which defines parameterized key and -// element types, but not fields. -func (t *DeclType) IsMap() bool { - return t.KeyType != nil && t.ElemType != nil && t.Fields == nil -} - -// IsObject returns whether the declartion is an 'object' type which defined a set of typed fields. -func (t *DeclType) IsObject() bool { - return t.KeyType == nil && t.ElemType == nil && t.Fields != nil -} - -// String implements the fmt.Stringer interface method. -func (t *DeclType) String() string { - return t.name -} - -// TypeName returns the fully qualified type name for the DeclType. -func (t *DeclType) TypeName() string { - return t.name -} - -// DefaultValue returns the CEL ref.Val representing the default value for this object type, -// if one exists. -func (t *DeclType) DefaultValue() ref.Val { - return t.defaultValue -} - -// FieldTypeMap constructs a map of the field and object types nested within a given type. -func FieldTypeMap(path string, t *DeclType) map[string]*DeclType { - if t.IsObject() && t.TypeName() != "object" { - path = t.TypeName() - } - types := make(map[string]*DeclType) - buildDeclTypes(path, t, types) - return types -} - -func buildDeclTypes(path string, t *DeclType, types map[string]*DeclType) { - // Ensure object types are properly named according to where they appear in the schema. - if t.IsObject() { - // Hack to ensure that names are uniquely qualified and work well with the type - // resolution steps which require fully qualified type names for field resolution - // to function properly. - types[t.TypeName()] = t - for name, field := range t.Fields { - fieldPath := fmt.Sprintf("%s.%s", path, name) - buildDeclTypes(fieldPath, field.Type, types) - } - } - // Map element properties to type names if needed. - if t.IsMap() { - mapElemPath := fmt.Sprintf("%s.@elem", path) - buildDeclTypes(mapElemPath, t.ElemType, types) - types[path] = t - } - // List element properties. - if t.IsList() { - listIdxPath := fmt.Sprintf("%s.@idx", path) - buildDeclTypes(listIdxPath, t.ElemType, types) - types[path] = t - } -} - -// DeclField describes the name, ordinal, and optionality of a field declaration within a type. -type DeclField struct { - Name string - Type *DeclType - Required bool - enumValues []interface{} - defaultValue interface{} -} - -// TypeName returns the string type name of the field. -func (f *DeclField) TypeName() string { - return f.Type.TypeName() -} - -// DefaultValue returns the zero value associated with the field. -func (f *DeclField) DefaultValue() ref.Val { - if f.defaultValue != nil { - return types.DefaultTypeAdapter.NativeToValue(f.defaultValue) - } - return f.Type.DefaultValue() -} - -// EnumValues returns the set of values that this field may take. -func (f *DeclField) EnumValues() []ref.Val { - if f.enumValues == nil || len(f.enumValues) == 0 { - return []ref.Val{} - } - ev := make([]ref.Val, len(f.enumValues)) - for i, e := range f.enumValues { - ev[i] = types.DefaultTypeAdapter.NativeToValue(e) - } - return ev -} - -// NewRuleTypes returns an Open API Schema-based type-system which is CEL compatible. -func NewRuleTypes(kind string, - schema *schema.Structural, - isResourceRoot bool, - res Resolver) (*RuleTypes, error) { - // Note, if the schema indicates that it's actually based on another proto - // then prefer the proto definition. For expressions in the proto, a new field - // annotation will be needed to indicate the expected environment and type of - // the expression. - schemaTypes, err := newSchemaTypeProvider(kind, schema, isResourceRoot) - if err != nil { - return nil, err - } - if schemaTypes == nil { - return nil, nil - } - return &RuleTypes{ - Schema: schema, - ruleSchemaDeclTypes: schemaTypes, - resolver: res, - }, nil -} - -// RuleTypes extends the CEL ref.TypeProvider interface and provides an Open API Schema-based -// type-system. -type RuleTypes struct { - ref.TypeProvider - Schema *schema.Structural - ruleSchemaDeclTypes *schemaTypeProvider - typeAdapter ref.TypeAdapter - resolver Resolver -} - -// EnvOptions returns a set of cel.EnvOption values which includes the declaration set -// as well as a custom ref.TypeProvider. -// -// Note, the standard declaration set includes 'rule' which is defined as the top-level rule-schema -// type if one is configured. -// -// If the RuleTypes value is nil, an empty []cel.EnvOption set is returned. -func (rt *RuleTypes) EnvOptions(tp ref.TypeProvider) ([]cel.EnvOption, error) { - if rt == nil { - return []cel.EnvOption{}, nil - } - var ta ref.TypeAdapter = types.DefaultTypeAdapter - tpa, ok := tp.(ref.TypeAdapter) - if ok { - ta = tpa - } - rtWithTypes := &RuleTypes{ - TypeProvider: tp, - typeAdapter: ta, - Schema: rt.Schema, - ruleSchemaDeclTypes: rt.ruleSchemaDeclTypes, - resolver: rt.resolver, - } - for name, declType := range rt.ruleSchemaDeclTypes.types { - tpType, found := tp.FindType(name) - if found && !proto.Equal(tpType, declType.ExprType()) { - return nil, fmt.Errorf( - "type %s definition differs between CEL environment and rule", name) - } - } - return []cel.EnvOption{ - cel.CustomTypeProvider(rtWithTypes), - cel.CustomTypeAdapter(rtWithTypes), - cel.Declarations( - decls.NewVar("rule", rt.ruleSchemaDeclTypes.root.ExprType()), - ), - }, nil -} - -// FindType attempts to resolve the typeName provided from the rule's rule-schema, or if not -// from the embedded ref.TypeProvider. -// -// FindType overrides the default type-finding behavior of the embedded TypeProvider. -// -// Note, when the type name is based on the Open API Schema, the name will reflect the object path -// where the type definition appears. -func (rt *RuleTypes) FindType(typeName string) (*exprpb.Type, bool) { - if rt == nil { - return nil, false - } - declType, found := rt.findDeclType(typeName) - if found { - return declType.ExprType(), found - } - return rt.TypeProvider.FindType(typeName) -} - -// FindDeclType returns the CPT type description which can be mapped to a CEL type. -func (rt *RuleTypes) FindDeclType(typeName string) (*DeclType, bool) { - if rt == nil { - return nil, false - } - return rt.findDeclType(typeName) -} - -// FindFieldType returns a field type given a type name and field name, if found. -// -// Note, the type name for an Open API Schema type is likely to be its qualified object path. -// If, in the future an object instance rather than a type name were provided, the field -// resolution might more accurately reflect the expected type model. However, in this case -// concessions were made to align with the existing CEL interfaces. -func (rt *RuleTypes) FindFieldType(typeName, fieldName string) (*ref.FieldType, bool) { - st, found := rt.findDeclType(typeName) - if !found { - return rt.TypeProvider.FindFieldType(typeName, fieldName) - } - - f, found := st.Fields[fieldName] - if found { - ft := f.Type - return &ref.FieldType{ - Type: ft.ExprType(), - }, true - } - // This could be a dynamic map. - if st.IsMap() { - et := st.ElemType - return &ref.FieldType{ - Type: et.ExprType(), - }, true - } - return nil, false -} - -// NativeToValue is an implementation of the ref.TypeAdapater interface which supports conversion -// of rule values to CEL ref.Val instances. -func (rt *RuleTypes) NativeToValue(val interface{}) ref.Val { - return rt.typeAdapter.NativeToValue(val) -} - -// TypeNames returns the list of type names declared within the RuleTypes object. -func (rt *RuleTypes) TypeNames() []string { - typeNames := make([]string, len(rt.ruleSchemaDeclTypes.types)) - i := 0 - for name := range rt.ruleSchemaDeclTypes.types { - typeNames[i] = name - i++ - } - return typeNames -} - -func (rt *RuleTypes) findDeclType(typeName string) (*DeclType, bool) { - declType, found := rt.ruleSchemaDeclTypes.types[typeName] - if found { - return declType, true - } - declType, found = rt.resolver.FindType(typeName) - if found { - return declType, true - } - return nil, false -} - -func (rt *RuleTypes) convertToCustomType(dyn *DynValue, declType *DeclType) *DynValue { - switch v := dyn.Value().(type) { - case *MapValue: - if declType.IsObject() { - obj := v.ConvertToObject(declType) - for name, f := range obj.fieldMap { - field := declType.Fields[name] - f.Ref = rt.convertToCustomType(f.Ref, field.Type) - } - dyn.SetValue(obj) - return dyn - } - fieldType := declType.ElemType - for _, f := range v.fieldMap { - f.Ref = rt.convertToCustomType(f.Ref, fieldType) - } - return dyn - case *ListValue: - for i := 0; i < len(v.Entries); i++ { - elem := v.Entries[i] - elem = rt.convertToCustomType(elem, declType.ElemType) - v.Entries[i] = elem - } - return dyn - default: - return dyn - } -} - -func newSchemaTypeProvider(kind string, schema *schema.Structural, isResourceRoot bool) (*schemaTypeProvider, error) { - delType := SchemaDeclType(schema, isResourceRoot) - if delType == nil { - return nil, nil - } - root := delType.MaybeAssignTypeName(kind) - types := FieldTypeMap(kind, root) - return &schemaTypeProvider{ - root: root, - types: types, - }, nil -} - -type schemaTypeProvider struct { - root *DeclType - types map[string]*DeclType -} - -var ( - // AnyType is equivalent to the CEL 'protobuf.Any' type in that the value may have any of the - // types supported. - AnyType = newSimpleType("any", decls.Any, nil) - - // BoolType is equivalent to the CEL 'bool' type. - BoolType = newSimpleType("bool", decls.Bool, types.False) - - // BytesType is equivalent to the CEL 'bytes' type. - BytesType = newSimpleType("bytes", decls.Bytes, types.Bytes([]byte{})) - - // DoubleType is equivalent to the CEL 'double' type which is a 64-bit floating point value. - DoubleType = newSimpleType("double", decls.Double, types.Double(0)) - - // DurationType is equivalent to the CEL 'duration' type. - DurationType = newSimpleType("duration", decls.Duration, types.Duration{Duration: time.Duration(0)}) - - // DateType is equivalent to the CEL 'date' type. - DateType = newSimpleType("date", decls.Timestamp, types.Timestamp{Time: time.Time{}}) - - // DynType is the equivalent of the CEL 'dyn' concept which indicates that the type will be - // determined at runtime rather than compile time. - DynType = newSimpleType("dyn", decls.Dyn, nil) - - // IntType is equivalent to the CEL 'int' type which is a 64-bit signed int. - IntType = newSimpleType("int", decls.Int, types.IntZero) - - // NullType is equivalent to the CEL 'null_type'. - NullType = newSimpleType("null_type", decls.Null, types.NullValue) - - // StringType is equivalent to the CEL 'string' type which is expected to be a UTF-8 string. - // StringType values may either be string literals or expression strings. - StringType = newSimpleType("string", decls.String, types.String("")) - - // TimestampType corresponds to the well-known protobuf.Timestamp type supported within CEL. - TimestampType = newSimpleType("timestamp", decls.Timestamp, types.Timestamp{Time: time.Time{}}) - - // UintType is equivalent to the CEL 'uint' type. - UintType = newSimpleType("uint", decls.Uint, types.Uint(0)) - - // ListType is equivalent to the CEL 'list' type. - ListType = NewListType(AnyType, noMaxLength) - - // MapType is equivalent to the CEL 'map' type. - MapType = NewMapType(AnyType, AnyType, noMaxLength) -) diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/url.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/url.go deleted file mode 100644 index 34d2d0eab7c..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/url.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "net/url" - "reflect" - - "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" -) - -// URL provides a CEL representation of a URL. -type URL struct { - *url.URL -} - -var ( - URLObject = decls.NewObjectType("kubernetes.URL") - typeValue = types.NewTypeValue("kubernetes.URL") -) - -// ConvertToNative implements ref.Val.ConvertToNative. -func (d URL) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - if reflect.TypeOf(d.URL).AssignableTo(typeDesc) { - return d.URL, nil - } - if reflect.TypeOf("").AssignableTo(typeDesc) { - return d.URL.String(), nil - } - return nil, fmt.Errorf("type conversion error from 'URL' to '%v'", typeDesc) -} - -// ConvertToType implements ref.Val.ConvertToType. -func (d URL) ConvertToType(typeVal ref.Type) ref.Val { - switch typeVal { - case typeValue: - return d - case types.TypeType: - return typeValue - } - return types.NewErr("type conversion error from '%s' to '%s'", typeValue, typeVal) -} - -// Equal implements ref.Val.Equal. -func (d URL) Equal(other ref.Val) ref.Val { - otherDur, ok := other.(URL) - if !ok { - return types.MaybeNoSuchOverloadErr(other) - } - return types.Bool(d.URL.String() == otherDur.URL.String()) -} - -// Type implements ref.Val.Type. -func (d URL) Type() ref.Type { - return typeValue -} - -// Value implements ref.Val.Value. -func (d URL) Value() interface{} { - return d.URL -} diff --git a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/value.go b/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/value.go deleted file mode 100644 index eb827893b8f..00000000000 --- a/vendor/k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model/value.go +++ /dev/null @@ -1,769 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "reflect" - "sync" - "time" - - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" -) - -// EncodeStyle is a hint for string encoding of parsed values. -type EncodeStyle int - -const ( - // BlockValueStyle is the default string encoding which preserves whitespace and newlines. - BlockValueStyle EncodeStyle = iota - - // FlowValueStyle indicates that the string is an inline representation of complex types. - FlowValueStyle - - // FoldedValueStyle is a multiline string with whitespace and newlines trimmed to a single - // a whitespace. Repeated newlines are replaced with a single newline rather than a single - // whitespace. - FoldedValueStyle - - // LiteralStyle is a multiline string that preserves newlines, but trims all other whitespace - // to a single character. - LiteralStyle -) - -// NewEmptyDynValue returns the zero-valued DynValue. -func NewEmptyDynValue() *DynValue { - // note: 0 is not a valid parse node identifier. - dv, _ := NewDynValue(0, nil) - return dv -} - -// NewDynValue returns a DynValue that corresponds to a parse node id and value. -func NewDynValue(id int64, val interface{}) (*DynValue, error) { - dv := &DynValue{ID: id} - err := dv.SetValue(val) - return dv, err -} - -// DynValue is a dynamically typed value used to describe unstructured content. -// Whether the value has the desired type is determined by where it is used within the Instance or -// Template, and whether there are schemas which might enforce a more rigid type definition. -type DynValue struct { - ID int64 - EncodeStyle EncodeStyle - value interface{} - exprValue ref.Val - declType *DeclType -} - -// DeclType returns the policy model type of the dyn value. -func (dv *DynValue) DeclType() *DeclType { - return dv.declType -} - -// ConvertToNative is an implementation of the CEL ref.Val method used to adapt between CEL types -// and Go-native types. -// -// The default behavior of this method is to first convert to a CEL type which has a well-defined -// set of conversion behaviors and proxy to the CEL ConvertToNative method for the type. -func (dv *DynValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - ev := dv.ExprValue() - if types.IsError(ev) { - return nil, ev.(*types.Err) - } - return ev.ConvertToNative(typeDesc) -} - -// Equal returns whether the dyn value is equal to a given CEL value. -func (dv *DynValue) Equal(other ref.Val) ref.Val { - dvType := dv.Type() - otherType := other.Type() - // Preserve CEL's homogeneous equality constraint. - if dvType.TypeName() != otherType.TypeName() { - return types.MaybeNoSuchOverloadErr(other) - } - switch v := dv.value.(type) { - case ref.Val: - return v.Equal(other) - case PlainTextValue: - return celBool(string(v) == other.Value().(string)) - case *MultilineStringValue: - return celBool(v.Value == other.Value().(string)) - case time.Duration: - otherDuration := other.Value().(time.Duration) - return celBool(v == otherDuration) - case time.Time: - otherTimestamp := other.Value().(time.Time) - return celBool(v.Equal(otherTimestamp)) - default: - return celBool(reflect.DeepEqual(v, other.Value())) - } -} - -// ExprValue converts the DynValue into a CEL value. -func (dv *DynValue) ExprValue() ref.Val { - return dv.exprValue -} - -// Value returns the underlying value held by this reference. -func (dv *DynValue) Value() interface{} { - return dv.value -} - -// SetValue updates the underlying value held by this reference. -func (dv *DynValue) SetValue(value interface{}) error { - dv.value = value - var err error - dv.exprValue, dv.declType, err = exprValue(value) - return err -} - -// Type returns the CEL type for the given value. -func (dv *DynValue) Type() ref.Type { - return dv.ExprValue().Type() -} - -func exprValue(value interface{}) (ref.Val, *DeclType, error) { - switch v := value.(type) { - case bool: - return types.Bool(v), BoolType, nil - case []byte: - return types.Bytes(v), BytesType, nil - case float64: - return types.Double(v), DoubleType, nil - case int64: - return types.Int(v), IntType, nil - case string: - return types.String(v), StringType, nil - case uint64: - return types.Uint(v), UintType, nil - case time.Duration: - return types.Duration{Duration: v}, DurationType, nil - case time.Time: - return types.Timestamp{Time: v}, TimestampType, nil - case types.Null: - return v, NullType, nil - case *ListValue: - return v, ListType, nil - case *MapValue: - return v, MapType, nil - case *ObjectValue: - return v, v.objectType, nil - default: - return nil, unknownType, fmt.Errorf("unsupported type: (%T)%v", v, v) - } -} - -// PlainTextValue is a text string literal which must not be treated as an expression. -type PlainTextValue string - -// MultilineStringValue is a multiline string value which has been parsed in a way which omits -// whitespace as well as a raw form which preserves whitespace. -type MultilineStringValue struct { - Value string - Raw string -} - -func newStructValue() *structValue { - return &structValue{ - Fields: []*Field{}, - fieldMap: map[string]*Field{}, - } -} - -type structValue struct { - Fields []*Field - fieldMap map[string]*Field -} - -// AddField appends a MapField to the MapValue and indexes the field by name. -func (sv *structValue) AddField(field *Field) { - sv.Fields = append(sv.Fields, field) - sv.fieldMap[field.Name] = field -} - -// ConvertToNative converts the MapValue type to a native go types. -func (sv *structValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - if typeDesc.Kind() != reflect.Map && - typeDesc.Kind() != reflect.Struct && - typeDesc.Kind() != reflect.Ptr && - typeDesc.Kind() != reflect.Interface { - return nil, fmt.Errorf("type conversion error from object to '%v'", typeDesc) - } - - // Unwrap pointers, but track their use. - isPtr := false - if typeDesc.Kind() == reflect.Ptr { - tk := typeDesc - typeDesc = typeDesc.Elem() - if typeDesc.Kind() == reflect.Ptr { - return nil, fmt.Errorf("unsupported type conversion to '%v'", tk) - } - isPtr = true - } - - if typeDesc.Kind() == reflect.Map { - keyType := typeDesc.Key() - if keyType.Kind() != reflect.String && keyType.Kind() != reflect.Interface { - return nil, fmt.Errorf("object fields cannot be converted to type '%v'", keyType) - } - elemType := typeDesc.Elem() - sz := len(sv.fieldMap) - ntvMap := reflect.MakeMapWithSize(typeDesc, sz) - for name, val := range sv.fieldMap { - refVal, err := val.Ref.ConvertToNative(elemType) - if err != nil { - return nil, err - } - ntvMap.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(refVal)) - } - return ntvMap.Interface(), nil - } - - if typeDesc.Kind() == reflect.Struct { - ntvObjPtr := reflect.New(typeDesc) - ntvObj := ntvObjPtr.Elem() - for name, val := range sv.fieldMap { - f := ntvObj.FieldByName(name) - if !f.IsValid() { - return nil, fmt.Errorf("type conversion error, no such field %s in type %v", - name, typeDesc) - } - fv, err := val.Ref.ConvertToNative(f.Type()) - if err != nil { - return nil, err - } - f.Set(reflect.ValueOf(fv)) - } - if isPtr { - return ntvObjPtr.Interface(), nil - } - return ntvObj.Interface(), nil - } - return nil, fmt.Errorf("type conversion error from object to '%v'", typeDesc) -} - -// GetField returns a MapField by name if one exists. -func (sv *structValue) GetField(name string) (*Field, bool) { - field, found := sv.fieldMap[name] - return field, found -} - -// IsSet returns whether the given field, which is defined, has also been set. -func (sv *structValue) IsSet(key ref.Val) ref.Val { - k, ok := key.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(key) - } - name := string(k) - _, found := sv.fieldMap[name] - return celBool(found) -} - -// NewObjectValue creates a struct value with a schema type and returns the empty ObjectValue. -func NewObjectValue(sType *DeclType) *ObjectValue { - return &ObjectValue{ - structValue: newStructValue(), - objectType: sType, - } -} - -// ObjectValue is a struct with a custom schema type which indicates the fields and types -// associated with the structure. -type ObjectValue struct { - *structValue - objectType *DeclType -} - -// ConvertToType is an implementation of the CEL ref.Val interface method. -func (o *ObjectValue) ConvertToType(t ref.Type) ref.Val { - if t == types.TypeType { - return types.NewObjectTypeValue(o.objectType.TypeName()) - } - if t.TypeName() == o.objectType.TypeName() { - return o - } - return types.NewErr("type conversion error from '%s' to '%s'", o.Type(), t) -} - -// Equal returns true if the two object types are equal and their field values are equal. -func (o *ObjectValue) Equal(other ref.Val) ref.Val { - // Preserve CEL's homogeneous equality semantics. - if o.objectType.TypeName() != other.Type().TypeName() { - return types.MaybeNoSuchOverloadErr(other) - } - o2 := other.(traits.Indexer) - for name := range o.objectType.Fields { - k := types.String(name) - v := o.Get(k) - ov := o2.Get(k) - vEq := v.Equal(ov) - if vEq != types.True { - return vEq - } - } - return types.True -} - -// Get returns the value of the specified field. -// -// If the field is set, its value is returned. If the field is not set, the default value for the -// field is returned thus allowing for safe-traversal and preserving proto-like field traversal -// semantics for Open API Schema backed types. -func (o *ObjectValue) Get(name ref.Val) ref.Val { - n, ok := name.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(n) - } - nameStr := string(n) - field, found := o.fieldMap[nameStr] - if found { - return field.Ref.ExprValue() - } - fieldDef, found := o.objectType.Fields[nameStr] - if !found { - return types.NewErr("no such field: %s", nameStr) - } - defValue := fieldDef.DefaultValue() - if defValue != nil { - return defValue - } - return types.NewErr("no default for type: %s", fieldDef.TypeName()) -} - -// Type returns the CEL type value of the object. -func (o *ObjectValue) Type() ref.Type { - return o.objectType -} - -// Value returns the Go-native representation of the object. -func (o *ObjectValue) Value() interface{} { - return o -} - -// NewMapValue returns an empty MapValue. -func NewMapValue() *MapValue { - return &MapValue{ - structValue: newStructValue(), - } -} - -// MapValue declares an object with a set of named fields whose values are dynamically typed. -type MapValue struct { - *structValue -} - -// ConvertToObject produces an ObjectValue from the MapValue with the associated schema type. -// -// The conversion is shallow and the memory shared between the Object and Map as all references -// to the map are expected to be replaced with the Object reference. -func (m *MapValue) ConvertToObject(declType *DeclType) *ObjectValue { - return &ObjectValue{ - structValue: m.structValue, - objectType: declType, - } -} - -// Contains returns whether the given key is contained in the MapValue. -func (m *MapValue) Contains(key ref.Val) ref.Val { - v, found := m.Find(key) - if v != nil && types.IsUnknownOrError(v) { - return v - } - return celBool(found) -} - -// ConvertToType converts the MapValue to another CEL type, if possible. -func (m *MapValue) ConvertToType(t ref.Type) ref.Val { - switch t { - case types.MapType: - return m - case types.TypeType: - return types.MapType - } - return types.NewErr("type conversion error from '%s' to '%s'", m.Type(), t) -} - -// Equal returns true if the maps are of the same size, have the same keys, and the key-values -// from each map are equal. -func (m *MapValue) Equal(other ref.Val) ref.Val { - oMap, isMap := other.(traits.Mapper) - if !isMap { - return types.MaybeNoSuchOverloadErr(other) - } - if m.Size() != oMap.Size() { - return types.False - } - for name, field := range m.fieldMap { - k := types.String(name) - ov, found := oMap.Find(k) - if !found { - return types.False - } - v := field.Ref.ExprValue() - vEq := v.Equal(ov) - if vEq != types.True { - return vEq - } - } - return types.True -} - -// Find returns the value for the key in the map, if found. -func (m *MapValue) Find(name ref.Val) (ref.Val, bool) { - // Currently only maps with string keys are supported as this is best aligned with JSON, - // and also much simpler to support. - n, ok := name.(types.String) - if !ok { - return types.MaybeNoSuchOverloadErr(n), true - } - nameStr := string(n) - field, found := m.fieldMap[nameStr] - if found { - return field.Ref.ExprValue(), true - } - return nil, false -} - -// Get returns the value for the key in the map, or error if not found. -func (m *MapValue) Get(key ref.Val) ref.Val { - v, found := m.Find(key) - if found { - return v - } - return types.ValOrErr(key, "no such key: %v", key) -} - -// Iterator produces a traits.Iterator which walks over the map keys. -// -// The Iterator is frequently used within comprehensions. -func (m *MapValue) Iterator() traits.Iterator { - keys := make([]ref.Val, len(m.fieldMap)) - i := 0 - for k := range m.fieldMap { - keys[i] = types.String(k) - i++ - } - return &baseMapIterator{ - baseVal: &baseVal{}, - keys: keys, - } -} - -// Size returns the number of keys in the map. -func (m *MapValue) Size() ref.Val { - return types.Int(len(m.Fields)) -} - -// Type returns the CEL ref.Type for the map. -func (m *MapValue) Type() ref.Type { - return types.MapType -} - -// Value returns the Go-native representation of the MapValue. -func (m *MapValue) Value() interface{} { - return m -} - -type baseMapIterator struct { - *baseVal - keys []ref.Val - idx int -} - -// HasNext implements the traits.Iterator interface method. -func (it *baseMapIterator) HasNext() ref.Val { - if it.idx < len(it.keys) { - return types.True - } - return types.False -} - -// Next implements the traits.Iterator interface method. -func (it *baseMapIterator) Next() ref.Val { - key := it.keys[it.idx] - it.idx++ - return key -} - -// Type implements the CEL ref.Val interface metohd. -func (it *baseMapIterator) Type() ref.Type { - return types.IteratorType -} - -// NewField returns a MapField instance with an empty DynValue that refers to the -// specified parse node id and field name. -func NewField(id int64, name string) *Field { - return &Field{ - ID: id, - Name: name, - Ref: NewEmptyDynValue(), - } -} - -// Field specifies a field name and a reference to a dynamic value. -type Field struct { - ID int64 - Name string - Ref *DynValue -} - -// NewListValue returns an empty ListValue instance. -func NewListValue() *ListValue { - return &ListValue{ - Entries: []*DynValue{}, - } -} - -// ListValue contains a list of dynamically typed entries. -type ListValue struct { - Entries []*DynValue - initValueSet sync.Once - valueSet map[ref.Val]struct{} -} - -// Add concatenates two lists together to produce a new CEL list value. -func (lv *ListValue) Add(other ref.Val) ref.Val { - oArr, isArr := other.(traits.Lister) - if !isArr { - return types.MaybeNoSuchOverloadErr(other) - } - szRight := len(lv.Entries) - szLeft := int(oArr.Size().(types.Int)) - sz := szRight + szLeft - combo := make([]ref.Val, sz) - for i := 0; i < szRight; i++ { - combo[i] = lv.Entries[i].ExprValue() - } - for i := 0; i < szLeft; i++ { - combo[i+szRight] = oArr.Get(types.Int(i)) - } - return types.DefaultTypeAdapter.NativeToValue(combo) -} - -// Append adds another entry into the ListValue. -func (lv *ListValue) Append(entry *DynValue) { - lv.Entries = append(lv.Entries, entry) - // The append resets all previously built indices. - lv.initValueSet = sync.Once{} -} - -// Contains returns whether the input `val` is equal to an element in the list. -// -// If any pair-wise comparison between the input value and the list element is an error, the -// operation will return an error. -func (lv *ListValue) Contains(val ref.Val) ref.Val { - if types.IsUnknownOrError(val) { - return val - } - lv.initValueSet.Do(lv.finalizeValueSet) - if lv.valueSet != nil { - _, found := lv.valueSet[val] - if found { - return types.True - } - // Instead of returning false, ensure that CEL's heterogeneous equality constraint - // is satisfied by allowing pair-wise equality behavior to determine the outcome. - } - var err ref.Val - sz := len(lv.Entries) - for i := 0; i < sz; i++ { - elem := lv.Entries[i] - cmp := elem.Equal(val) - b, ok := cmp.(types.Bool) - if !ok && err == nil { - err = types.MaybeNoSuchOverloadErr(cmp) - } - if b == types.True { - return types.True - } - } - if err != nil { - return err - } - return types.False -} - -// ConvertToNative is an implementation of the CEL ref.Val method used to adapt between CEL types -// and Go-native array-like types. -func (lv *ListValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - // Non-list conversion. - if typeDesc.Kind() != reflect.Slice && - typeDesc.Kind() != reflect.Array && - typeDesc.Kind() != reflect.Interface { - return nil, fmt.Errorf("type conversion error from list to '%v'", typeDesc) - } - - // If the list is already assignable to the desired type return it. - if reflect.TypeOf(lv).AssignableTo(typeDesc) { - return lv, nil - } - - // List conversion. - otherElem := typeDesc.Elem() - - // Allow the element ConvertToNative() function to determine whether conversion is possible. - sz := len(lv.Entries) - nativeList := reflect.MakeSlice(typeDesc, int(sz), int(sz)) - for i := 0; i < sz; i++ { - elem := lv.Entries[i] - nativeElemVal, err := elem.ConvertToNative(otherElem) - if err != nil { - return nil, err - } - nativeList.Index(int(i)).Set(reflect.ValueOf(nativeElemVal)) - } - return nativeList.Interface(), nil -} - -// ConvertToType converts the ListValue to another CEL type. -func (lv *ListValue) ConvertToType(t ref.Type) ref.Val { - switch t { - case types.ListType: - return lv - case types.TypeType: - return types.ListType - } - return types.NewErr("type conversion error from '%s' to '%s'", ListType, t) -} - -// Equal returns true if two lists are of the same size, and the values at each index are also -// equal. -func (lv *ListValue) Equal(other ref.Val) ref.Val { - oArr, isArr := other.(traits.Lister) - if !isArr { - return types.MaybeNoSuchOverloadErr(other) - } - sz := types.Int(len(lv.Entries)) - if sz != oArr.Size() { - return types.False - } - for i := types.Int(0); i < sz; i++ { - cmp := lv.Get(i).Equal(oArr.Get(i)) - if cmp != types.True { - return cmp - } - } - return types.True -} - -// Get returns the value at the given index. -// -// If the index is negative or greater than the size of the list, an error is returned. -func (lv *ListValue) Get(idx ref.Val) ref.Val { - iv, isInt := idx.(types.Int) - if !isInt { - return types.ValOrErr(idx, "unsupported index: %v", idx) - } - i := int(iv) - if i < 0 || i >= len(lv.Entries) { - return types.NewErr("index out of bounds: %v", idx) - } - return lv.Entries[i].ExprValue() -} - -// Iterator produces a traits.Iterator suitable for use in CEL comprehension macros. -func (lv *ListValue) Iterator() traits.Iterator { - return &baseListIterator{ - getter: lv.Get, - sz: len(lv.Entries), - } -} - -// Size returns the number of elements in the list. -func (lv *ListValue) Size() ref.Val { - return types.Int(len(lv.Entries)) -} - -// Type returns the CEL ref.Type for the list. -func (lv *ListValue) Type() ref.Type { - return types.ListType -} - -// Value returns the Go-native value. -func (lv *ListValue) Value() interface{} { - return lv -} - -// finalizeValueSet inspects the ListValue entries in order to make internal optimizations once all list -// entries are known. -func (lv *ListValue) finalizeValueSet() { - valueSet := make(map[ref.Val]struct{}) - for _, e := range lv.Entries { - switch e.value.(type) { - case bool, float64, int64, string, uint64, types.Null, PlainTextValue: - if valueSet != nil { - valueSet[e.ExprValue()] = struct{}{} - } - default: - lv.valueSet = nil - return - } - } - lv.valueSet = valueSet -} - -type baseVal struct{} - -func (*baseVal) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { - return nil, fmt.Errorf("unsupported native conversion to: %v", typeDesc) -} - -func (*baseVal) ConvertToType(t ref.Type) ref.Val { - return types.NewErr("unsupported type conversion to: %v", t) -} - -func (*baseVal) Equal(other ref.Val) ref.Val { - return types.NewErr("unsupported equality test between instances") -} - -func (v *baseVal) Value() interface{} { - return nil -} - -type baseListIterator struct { - *baseVal - getter func(idx ref.Val) ref.Val - sz int - idx int -} - -func (it *baseListIterator) HasNext() ref.Val { - if it.idx < it.sz { - return types.True - } - return types.False -} - -func (it *baseListIterator) Next() ref.Val { - v := it.getter(types.Int(it.idx)) - it.idx++ - return v -} - -func (it *baseListIterator) Type() ref.Type { - return types.IteratorType -} - -func celBool(pred bool) ref.Val { - if pred { - return types.True - } - return types.False -} - -var unknownType = &DeclType{name: "unknown"} diff --git a/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go index fab187a6a09..57e0e71f672 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/api/errors/errors.go @@ -87,21 +87,21 @@ func (e *StatusError) DebugError() (string, []interface{}) { // HasStatusCause returns true if the provided error has a details cause // with the provided type name. +// It supports wrapped errors and returns false when the error is nil. func HasStatusCause(err error, name metav1.CauseType) bool { _, ok := StatusCause(err, name) return ok } // StatusCause returns the named cause from the provided error if it exists and -// the error is of the type APIStatus. Otherwise it returns false. +// the error unwraps to the type APIStatus. Otherwise it returns false. func StatusCause(err error, name metav1.CauseType) (metav1.StatusCause, bool) { - apierr, ok := err.(APIStatus) - if !ok || apierr == nil || apierr.Status().Details == nil { - return metav1.StatusCause{}, false - } - for _, cause := range apierr.Status().Details.Causes { - if cause.Type == name { - return cause, true + status, ok := err.(APIStatus) + if (ok || errors.As(err, &status)) && status.Status().Details != nil { + for _, cause := range status.Status().Details.Causes { + if cause.Type == name { + return cause, true + } } } return metav1.StatusCause{}, false @@ -757,7 +757,8 @@ func IsRequestEntityTooLargeError(err error) bool { // and may be the result of another HTTP actor. // It supports wrapped errors and returns false when the error is nil. func IsUnexpectedServerError(err error) bool { - if status := APIStatus(nil); errors.As(err, &status) && status.Status().Details != nil { + status, ok := err.(APIStatus) + if (ok || errors.As(err, &status)) && status.Status().Details != nil { for _, cause := range status.Status().Details.Causes { if cause.Type == metav1.CauseTypeUnexpectedServerResponse { return true @@ -770,8 +771,8 @@ func IsUnexpectedServerError(err error) bool { // IsUnexpectedObjectError determines if err is due to an unexpected object from the master. // It supports wrapped errors and returns false when the error is nil. func IsUnexpectedObjectError(err error) bool { - uoe := &UnexpectedObjectError{} - return err != nil && errors.As(err, &uoe) + uoe, ok := err.(*UnexpectedObjectError) + return err != nil && (ok || errors.As(err, &uoe)) } // SuggestsClientDelay returns true if this error suggests a client delay as well as the @@ -780,7 +781,8 @@ func IsUnexpectedObjectError(err error) bool { // request delay without retry. // It supports wrapped errors and returns false when the error is nil. func SuggestsClientDelay(err error) (int, bool) { - if t := APIStatus(nil); errors.As(err, &t) && t.Status().Details != nil { + t, ok := err.(APIStatus) + if (ok || errors.As(err, &t)) && t.Status().Details != nil { switch t.Status().Reason { // this StatusReason explicitly requests the caller to delay the action case metav1.StatusReasonServerTimeout: @@ -798,14 +800,14 @@ func SuggestsClientDelay(err error) (int, bool) { // It supports wrapped errors and returns StatusReasonUnknown when // the error is nil or doesn't have a status. func ReasonForError(err error) metav1.StatusReason { - if status := APIStatus(nil); errors.As(err, &status) { + if status, ok := err.(APIStatus); ok || errors.As(err, &status) { return status.Status().Reason } return metav1.StatusReasonUnknown } func reasonAndCodeForError(err error) (metav1.StatusReason, int32) { - if status := APIStatus(nil); errors.As(err, &status) { + if status, ok := err.(APIStatus); ok || errors.As(err, &status) { return status.Status().Reason, status.Status().Code } return metav1.StatusReasonUnknown, 0 diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go b/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go index 00874f89cc6..60c8209de02 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/conditions.go @@ -24,9 +24,9 @@ import ( // SetStatusCondition sets the corresponding condition in conditions to newCondition. // conditions must be non-nil. -// 1. if the condition of the specified type already exists (all fields of the existing condition are updated to -// newCondition, LastTransitionTime is set to now if the new status differs from the old status) -// 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended) +// 1. if the condition of the specified type already exists (all fields of the existing condition are updated to +// newCondition, LastTransitionTime is set to now if the new status differs from the old status) +// 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended) func SetStatusCondition(conditions *[]metav1.Condition, newCondition metav1.Condition) { if conditions == nil { return diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/errors.go b/vendor/k8s.io/apimachinery/pkg/api/meta/errors.go index cbf5d0263c6..f36aa4ec22a 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/errors.go @@ -17,6 +17,7 @@ limitations under the License. package meta import ( + "errors" "fmt" "k8s.io/apimachinery/pkg/runtime/schema" @@ -43,6 +44,11 @@ func (e *AmbiguousResourceError) Error() string { return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialResource) } +func (*AmbiguousResourceError) Is(target error) bool { + _, ok := target.(*AmbiguousResourceError) + return ok +} + // AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind type AmbiguousKindError struct { PartialKind schema.GroupVersionKind @@ -63,16 +69,16 @@ func (e *AmbiguousKindError) Error() string { return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialKind) } +func (*AmbiguousKindError) Is(target error) bool { + _, ok := target.(*AmbiguousKindError) + return ok +} + func IsAmbiguousError(err error) bool { if err == nil { return false } - switch err.(type) { - case *AmbiguousResourceError, *AmbiguousKindError: - return true - default: - return false - } + return errors.Is(err, &AmbiguousResourceError{}) || errors.Is(err, &AmbiguousKindError{}) } // NoResourceMatchError is returned if the RESTMapper can't find any match for a resource @@ -84,6 +90,11 @@ func (e *NoResourceMatchError) Error() string { return fmt.Sprintf("no matches for %v", e.PartialResource) } +func (*NoResourceMatchError) Is(target error) bool { + _, ok := target.(*NoResourceMatchError) + return ok +} + // NoKindMatchError is returned if the RESTMapper can't find any match for a kind type NoKindMatchError struct { // GroupKind is the API group and kind that was searched @@ -108,14 +119,14 @@ func (e *NoKindMatchError) Error() string { } } +func (*NoKindMatchError) Is(target error) bool { + _, ok := target.(*NoKindMatchError) + return ok +} + func IsNoMatchError(err error) bool { if err == nil { return false } - switch err.(type) { - case *NoResourceMatchError, *NoKindMatchError: - return true - default: - return false - } + return errors.Is(err, &NoResourceMatchError{}) || errors.Is(err, &NoKindMatchError{}) } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go index 50468b5330d..1bf6b06d47f 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go @@ -40,7 +40,7 @@ var ( // IsListType returns true if the provided Object has a slice called Items. // TODO: Replace the code in this check with an interface comparison by -// creating and enforcing that lists implement a list accessor. +// creating and enforcing that lists implement a list accessor. func IsListType(obj runtime.Object) bool { switch t := obj.(type) { case runtime.Unstructured: @@ -97,7 +97,7 @@ func getItemsPtr(list runtime.Object) (interface{}, error) { return nil, errExpectFieldItems } switch items.Kind() { - case reflect.Interface, reflect.Ptr: + case reflect.Interface, reflect.Pointer: target := reflect.TypeOf(items.Interface()).Elem() if target.Kind() != reflect.Slice { return nil, errExpectSliceItems @@ -130,7 +130,7 @@ func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error { return nil } takeAddr := false - if elemType := items.Type().Elem(); elemType.Kind() != reflect.Ptr && elemType.Kind() != reflect.Interface { + if elemType := items.Type().Elem(); elemType.Kind() != reflect.Pointer && elemType.Kind() != reflect.Interface { if !items.Index(0).CanAddr() { return fmt.Errorf("unable to take address of items in %T for EachListItem", obj) } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go b/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go index 81403393fb6..2551f07f5cf 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go @@ -130,7 +130,6 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1.PartialObjectMetadata { Annotations: m.GetAnnotations(), OwnerReferences: m.GetOwnerReferences(), Finalizers: m.GetFinalizers(), - ZZZ_DeprecatedClusterName: m.GetZZZ_DeprecatedClusterName(), ManagedFields: m.GetManagedFields(), }, } @@ -600,7 +599,7 @@ func (a genericAccessor) SetFinalizers(finalizers []string) { func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { var ret []metav1.OwnerReference s := a.ownerReferences - if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice { + if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { klog.Errorf("expect %v to be a pointer to slice", s) return ret } @@ -618,7 +617,7 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) { s := a.ownerReferences - if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice { + if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { klog.Errorf("expect %v to be a pointer to slice", s) } s = s.Elem() diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto b/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto index 79abc0ff5e7..ddd0db8fbd1 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto @@ -30,8 +30,11 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource"; // // The serialization format is: // +// ``` // ::= -// (Note that may be empty, from the "" case in .) +// +// (Note that may be empty, from the "" case in .) +// // ::= 0 | 1 | ... | 9 // ::= | // ::= | . | . | . @@ -39,10 +42,15 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource"; // ::= | // ::= | | // ::= Ki | Mi | Gi | Ti | Pi | Ei -// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) +// +// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) +// // ::= m | "" | k | M | G | T | P | E -// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) +// +// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) +// // ::= "e" | "E" +// ``` // // No matter which of the three exponent forms is used, no quantity may represent // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal @@ -56,14 +64,17 @@ option go_package = "k8s.io/apimachinery/pkg/api/resource"; // Before serializing, Quantity will be put in "canonical form". // This means that Exponent/suffix will be adjusted up or down (with a // corresponding increase or decrease in Mantissa) such that: -// a. No precision is lost -// b. No fractional digits will be emitted -// c. The exponent (or suffix) is as large as possible. +// +// - No precision is lost +// - No fractional digits will be emitted +// - The exponent (or suffix) is as large as possible. +// // The sign will be omitted unless the number is negative. // // Examples: -// 1.5 will be serialized as "1500m" -// 1.5Gi will be serialized as "1536Mi" +// +// - 1.5 will be serialized as "1500m" +// - 1.5Gi will be serialized as "1536Mi" // // Note that the quantity will NEVER be internally represented by a // floating point number. That is the whole point of this exercise. diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go index 1ca31d8caf5..b47d554b3c5 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go +++ b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go @@ -34,8 +34,11 @@ import ( // // The serialization format is: // +// ``` // ::= -// (Note that may be empty, from the "" case in .) +// +// (Note that may be empty, from the "" case in .) +// // ::= 0 | 1 | ... | 9 // ::= | // ::= | . | . | . @@ -43,10 +46,15 @@ import ( // ::= | // ::= | | // ::= Ki | Mi | Gi | Ti | Pi | Ei -// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) +// +// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html) +// // ::= m | "" | k | M | G | T | P | E -// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) +// +// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.) +// // ::= "e" | "E" +// ``` // // No matter which of the three exponent forms is used, no quantity may represent // a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal @@ -60,14 +68,17 @@ import ( // Before serializing, Quantity will be put in "canonical form". // This means that Exponent/suffix will be adjusted up or down (with a // corresponding increase or decrease in Mantissa) such that: -// a. No precision is lost -// b. No fractional digits will be emitted -// c. The exponent (or suffix) is as large as possible. +// +// - No precision is lost +// - No fractional digits will be emitted +// - The exponent (or suffix) is as large as possible. +// // The sign will be omitted unless the number is negative. // // Examples: -// 1.5 will be serialized as "1500m" -// 1.5Gi will be serialized as "1536Mi" +// +// - 1.5 will be serialized as "1500m" +// - 1.5Gi will be serialized as "1536Mi" // // Note that the quantity will NEVER be internally represented by a // floating point number. That is the whole point of this exercise. @@ -404,10 +415,10 @@ func (Quantity) OpenAPIV3OneOfTypes() []string { return []string{"string", "numb // CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity). // // Note about BinarySI: -// * If q.Format is set to BinarySI and q.Amount represents a non-zero value between -// -1 and +1, it will be emitted as if q.Format were DecimalSI. -// * Otherwise, if q.Format is set to BinarySI, fractional parts of q.Amount will be -// rounded up. (1.1i becomes 2i.) +// - If q.Format is set to BinarySI and q.Amount represents a non-zero value between +// -1 and +1, it will be emitted as if q.Format were DecimalSI. +// - Otherwise, if q.Format is set to BinarySI, fractional parts of q.Amount will be +// rounded up. (1.1i becomes 2i.) func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) { if q.IsZero() { return zeroBytes, nil @@ -643,7 +654,7 @@ func (q Quantity) MarshalJSON() ([]byte, error) { copy(out[1:], q.s) return out, nil } - result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes) + result := make([]byte, int64QuantityExpectedBytes) result[0] = '"' number, suffix := q.CanonicalizeBytes(result[1:1]) // if the same slice was returned to us that we passed in, avoid another allocation by copying number into diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/suffix.go b/vendor/k8s.io/apimachinery/pkg/api/resource/suffix.go index 5ed7abe6651..6ec527f9c00 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/resource/suffix.go +++ b/vendor/k8s.io/apimachinery/pkg/api/resource/suffix.go @@ -165,7 +165,7 @@ func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s if exponent == 0 { return nil, true } - result := make([]byte, 8, 8) + result := make([]byte, 8) result[0] = 'e' number := strconv.AppendInt(result[1:1], int64(exponent), 10) if &result[1] == &number[0] { diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go index 9a1fe073146..593d7ba8cf7 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go @@ -40,13 +40,11 @@ var BannedOwners = map[schema.GroupVersionKind]struct{}{ {Group: "", Version: "v1", Kind: "Event"}: {}, } -// ValidateZZZ_DeprecatedClusterName can be used to check whether the given cluster name is valid. -var ValidateZZZ_DeprecatedClusterName = NameIsDNS1035Label - // ValidateAnnotations validates that a set of annotations are correctly defined. func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for k := range annotations { + // The rule is QualifiedName except that case doesn't matter, so convert to lowercase before checking. for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) { allErrs = append(allErrs, field.Invalid(fldPath, k, msg)) } @@ -93,15 +91,16 @@ func validateOwnerReference(ownerReference metav1.OwnerReference, fldPath *field // ValidateOwnerReferences validates that a set of owner references are correctly defined. func ValidateOwnerReferences(ownerReferences []metav1.OwnerReference, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - controllerName := "" + firstControllerName := "" for _, ref := range ownerReferences { allErrs = append(allErrs, validateOwnerReference(ref, fldPath)...) if ref.Controller != nil && *ref.Controller { - if controllerName != "" { + curControllerName := ref.Kind + "/" + ref.Name + if firstControllerName != "" { allErrs = append(allErrs, field.Invalid(fldPath, ownerReferences, - fmt.Sprintf("Only one reference can have Controller set to true. Found \"true\" in references for %v and %v", controllerName, ref.Name))) + fmt.Sprintf("Only one reference can have Controller set to true. Found \"true\" in references for %v and %v", firstControllerName, curControllerName))) } else { - controllerName = ref.Name + firstControllerName = curControllerName } } } @@ -184,11 +183,6 @@ func ValidateObjectMetaAccessor(meta metav1.Object, requiresNamespace bool, name allErrs = append(allErrs, field.Forbidden(fldPath.Child("namespace"), "not allowed on this type")) } } - if len(meta.GetZZZ_DeprecatedClusterName()) != 0 { - for _, msg := range ValidateZZZ_DeprecatedClusterName(meta.GetZZZ_DeprecatedClusterName(), false) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.GetZZZ_DeprecatedClusterName(), msg)) - } - } allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...) allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...) @@ -261,7 +255,6 @@ func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *f allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionTimestamp(), oldMeta.GetDeletionTimestamp(), fldPath.Child("deletionTimestamp"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionGracePeriodSeconds(), oldMeta.GetDeletionGracePeriodSeconds(), fldPath.Child("deletionGracePeriodSeconds"))...) - allErrs = append(allErrs, ValidateImmutableField(newMeta.GetZZZ_DeprecatedClusterName(), oldMeta.GetZZZ_DeprecatedClusterName(), fldPath.Child("clusterName"))...) allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...) allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...) diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go new file mode 100644 index 00000000000..29c6a48b6a1 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go @@ -0,0 +1,38 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internalversion + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// SetListOptionsDefaults sets defaults on the provided ListOptions if applicable. +// +// TODO(#115478): once the watch-list fg is always on we register this function in the scheme (via AddTypeDefaultingFunc). +// TODO(#115478): when the function is registered in the scheme remove all callers of this method. +func SetListOptionsDefaults(obj *ListOptions, isWatchListFeatureEnabled bool) { + if !isWatchListFeatureEnabled { + return + } + if obj.SendInitialEvents != nil || len(obj.ResourceVersionMatch) != 0 { + return + } + legacy := obj.ResourceVersion == "" || obj.ResourceVersion == "0" + if obj.Watch && legacy { + turnOnInitialEvents := true + obj.SendInitialEvents = &turnOnInitialEvents + obj.ResourceVersionMatch = metav1.ResourceVersionMatchNotOlderThan + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go index a49b5f2befc..00d2b8c6891 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go @@ -66,6 +66,31 @@ type ListOptions struct { // it does not recognize and will return a 410 error if the token can no longer be used because // it has expired. Continue string + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + SendInitialEvents *bool } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go index 6d212b846a4..a6552c276ee 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go @@ -115,6 +115,7 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds)) out.Limit = in.Limit out.Continue = in.Continue + out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) return nil } @@ -137,6 +138,7 @@ func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOption out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds)) out.Limit = in.Limit out.Continue = in.Continue + out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go index 6e1eac5c75a..af66a2ac4c9 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go @@ -75,6 +75,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) { *out = new(int64) **out = **in } + if in.SendInitialEvents != nil { + in, out := &in.SendInitialEvents, &out.SendInitialEvents + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go index 6e5f5e61b3e..1a641e7c122 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go @@ -1326,187 +1326,187 @@ func init() { } var fileDescriptor_cf52fa777ced5367 = []byte{ - // 2879 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0xcd, 0x6f, 0x24, 0x47, - 0xbd, 0xee, 0x19, 0x8f, 0x3d, 0xf3, 0x1b, 0x8f, 0x3f, 0x6a, 0xbd, 0xef, 0xcd, 0xfa, 0xe9, 0x79, - 0x9c, 0x4e, 0x14, 0x6d, 0xde, 0x4b, 0xc6, 0xd9, 0x25, 0x44, 0x9b, 0x0d, 0x09, 0x78, 0x3c, 0xeb, - 0x8d, 0x93, 0x75, 0x6c, 0x95, 0x77, 0x17, 0x58, 0x22, 0x48, 0xbb, 0xbb, 0x3c, 0x6e, 0xdc, 0xd3, - 0x3d, 0xa9, 0xea, 0xf1, 0x66, 0xe0, 0x40, 0x0e, 0x20, 0x82, 0x84, 0xa2, 0x70, 0xe3, 0x84, 0x12, - 0xc1, 0x1f, 0x80, 0xb8, 0xc0, 0x1f, 0x80, 0x44, 0x8e, 0x41, 0x5c, 0x22, 0x81, 0x46, 0x89, 0x39, - 0x70, 0x44, 0x5c, 0x7d, 0x01, 0xd5, 0x47, 0x77, 0x57, 0xcf, 0xc7, 0xba, 0x27, 0xbb, 0x44, 0xdc, - 0xa6, 0x7f, 0xdf, 0x55, 0xf5, 0xab, 0xdf, 0x57, 0x0d, 0xec, 0x1c, 0x5f, 0x63, 0x75, 0x37, 0x58, - 0x3f, 0xee, 0x1e, 0x10, 0xea, 0x93, 0x90, 0xb0, 0xf5, 0x13, 0xe2, 0x3b, 0x01, 0x5d, 0x57, 0x08, - 0xab, 0xe3, 0xb6, 0x2d, 0xfb, 0xc8, 0xf5, 0x09, 0xed, 0xad, 0x77, 0x8e, 0x5b, 0x1c, 0xc0, 0xd6, - 0xdb, 0x24, 0xb4, 0xd6, 0x4f, 0xae, 0xac, 0xb7, 0x88, 0x4f, 0xa8, 0x15, 0x12, 0xa7, 0xde, 0xa1, - 0x41, 0x18, 0xa0, 0x27, 0x24, 0x57, 0x5d, 0xe7, 0xaa, 0x77, 0x8e, 0x5b, 0x1c, 0xc0, 0xea, 0x9c, - 0xab, 0x7e, 0x72, 0x65, 0xe5, 0x99, 0x96, 0x1b, 0x1e, 0x75, 0x0f, 0xea, 0x76, 0xd0, 0x5e, 0x6f, - 0x05, 0xad, 0x60, 0x5d, 0x30, 0x1f, 0x74, 0x0f, 0xc5, 0x97, 0xf8, 0x10, 0xbf, 0xa4, 0xd0, 0x95, - 0xb1, 0xa6, 0xd0, 0xae, 0x1f, 0xba, 0x6d, 0x32, 0x68, 0xc5, 0xca, 0xf3, 0xe7, 0x31, 0x30, 0xfb, - 0x88, 0xb4, 0xad, 0x41, 0x3e, 0xf3, 0x0f, 0x79, 0x28, 0x6e, 0xec, 0x6d, 0xdf, 0xa4, 0x41, 0xb7, - 0x83, 0xd6, 0x60, 0xda, 0xb7, 0xda, 0xa4, 0x6a, 0xac, 0x19, 0x97, 0x4b, 0x8d, 0xb9, 0x8f, 0xfa, - 0xb5, 0xa9, 0xd3, 0x7e, 0x6d, 0xfa, 0x75, 0xab, 0x4d, 0xb0, 0xc0, 0x20, 0x0f, 0x8a, 0x27, 0x84, - 0x32, 0x37, 0xf0, 0x59, 0x35, 0xb7, 0x96, 0xbf, 0x5c, 0xbe, 0xfa, 0x72, 0x3d, 0xcb, 0xfa, 0xeb, - 0x42, 0xc1, 0x5d, 0xc9, 0xba, 0x15, 0xd0, 0xa6, 0xcb, 0xec, 0xe0, 0x84, 0xd0, 0x5e, 0x63, 0x51, - 0x69, 0x29, 0x2a, 0x24, 0xc3, 0xb1, 0x06, 0xf4, 0x43, 0x03, 0x16, 0x3b, 0x94, 0x1c, 0x12, 0x4a, - 0x89, 0xa3, 0xf0, 0xd5, 0xfc, 0x9a, 0xf1, 0x08, 0xd4, 0x56, 0x95, 0xda, 0xc5, 0xbd, 0x01, 0xf9, - 0x78, 0x48, 0x23, 0xfa, 0xa5, 0x01, 0x2b, 0x8c, 0xd0, 0x13, 0x42, 0x37, 0x1c, 0x87, 0x12, 0xc6, - 0x1a, 0xbd, 0x4d, 0xcf, 0x25, 0x7e, 0xb8, 0xb9, 0xdd, 0xc4, 0xac, 0x3a, 0x2d, 0xf6, 0xe1, 0xab, - 0xd9, 0x0c, 0xda, 0x1f, 0x27, 0xa7, 0x61, 0x2a, 0x8b, 0x56, 0xc6, 0x92, 0x30, 0xfc, 0x00, 0x33, - 0xcc, 0x43, 0x98, 0x8b, 0x0e, 0xf2, 0x96, 0xcb, 0x42, 0x74, 0x17, 0x66, 0x5a, 0xfc, 0x83, 0x55, - 0x0d, 0x61, 0x60, 0x3d, 0x9b, 0x81, 0x91, 0x8c, 0xc6, 0xbc, 0xb2, 0x67, 0x46, 0x7c, 0x32, 0xac, - 0xa4, 0x99, 0x3f, 0x99, 0x86, 0xf2, 0xc6, 0xde, 0x36, 0x26, 0x2c, 0xe8, 0x52, 0x9b, 0x64, 0x70, - 0x9a, 0x6b, 0x30, 0xc7, 0x5c, 0xbf, 0xd5, 0xf5, 0x2c, 0xca, 0xa1, 0xd5, 0x19, 0x41, 0xb9, 0xac, - 0x28, 0xe7, 0xf6, 0x35, 0x1c, 0x4e, 0x51, 0xa2, 0xab, 0x00, 0x5c, 0x02, 0xeb, 0x58, 0x36, 0x71, - 0xaa, 0xb9, 0x35, 0xe3, 0x72, 0xb1, 0x81, 0x14, 0x1f, 0xbc, 0x1e, 0x63, 0xb0, 0x46, 0x85, 0x1e, - 0x87, 0x82, 0xb0, 0xb4, 0x5a, 0x14, 0x6a, 0x2a, 0x8a, 0xbc, 0x20, 0x96, 0x81, 0x25, 0x0e, 0x3d, - 0x05, 0xb3, 0xca, 0xcb, 0xaa, 0x25, 0x41, 0xb6, 0xa0, 0xc8, 0x66, 0x23, 0x37, 0x88, 0xf0, 0x7c, - 0x7d, 0xc7, 0xae, 0xef, 0x08, 0xbf, 0xd3, 0xd6, 0xf7, 0x9a, 0xeb, 0x3b, 0x58, 0x60, 0xd0, 0x2d, - 0x28, 0x9c, 0x10, 0x7a, 0xc0, 0x3d, 0x81, 0xbb, 0xe6, 0xff, 0x67, 0xdb, 0xe8, 0xbb, 0x9c, 0xa5, - 0x51, 0xe2, 0xa6, 0x89, 0x9f, 0x58, 0x0a, 0x41, 0x75, 0x00, 0x76, 0x14, 0xd0, 0x50, 0x2c, 0xaf, - 0x5a, 0x58, 0xcb, 0x5f, 0x2e, 0x35, 0xe6, 0xf9, 0x7a, 0xf7, 0x63, 0x28, 0xd6, 0x28, 0x38, 0xbd, - 0x6d, 0x85, 0xa4, 0x15, 0x50, 0x97, 0xb0, 0xea, 0x6c, 0x42, 0xbf, 0x19, 0x43, 0xb1, 0x46, 0x81, - 0x5e, 0x05, 0xc4, 0xc2, 0x80, 0x5a, 0x2d, 0xa2, 0x96, 0xfa, 0x8a, 0xc5, 0x8e, 0xaa, 0x20, 0x56, - 0xb7, 0xa2, 0x56, 0x87, 0xf6, 0x87, 0x28, 0xf0, 0x08, 0x2e, 0xf3, 0x37, 0x06, 0x2c, 0x68, 0xbe, - 0x20, 0xfc, 0xee, 0x1a, 0xcc, 0xb5, 0xb4, 0x5b, 0xa7, 0xfc, 0x22, 0x3e, 0x6d, 0xfd, 0x46, 0xe2, - 0x14, 0x25, 0x22, 0x50, 0xa2, 0x4a, 0x52, 0x14, 0x5d, 0xae, 0x64, 0x76, 0xda, 0xc8, 0x86, 0x44, - 0x93, 0x06, 0x64, 0x38, 0x91, 0x6c, 0xfe, 0xcd, 0x10, 0x0e, 0x1c, 0xc5, 0x1b, 0x74, 0x59, 0x8b, - 0x69, 0x86, 0xd8, 0xbe, 0xb9, 0x31, 0xf1, 0xe8, 0x9c, 0x40, 0x90, 0xfb, 0x8f, 0x08, 0x04, 0xd7, - 0x8b, 0x3f, 0xff, 0xa0, 0x36, 0xf5, 0xce, 0x5f, 0xd6, 0xa6, 0xcc, 0x9f, 0x19, 0x30, 0xb7, 0xd1, - 0xe9, 0x78, 0xbd, 0xdd, 0x4e, 0x28, 0x16, 0x60, 0xc2, 0x8c, 0x43, 0x7b, 0xb8, 0xeb, 0xab, 0x85, - 0x02, 0xbf, 0xdf, 0x4d, 0x01, 0xc1, 0x0a, 0xc3, 0xef, 0xcf, 0x61, 0x40, 0x6d, 0xa2, 0xae, 0x5b, - 0x7c, 0x7f, 0xb6, 0x38, 0x10, 0x4b, 0x1c, 0x3f, 0xe4, 0x43, 0x97, 0x78, 0xce, 0x8e, 0xe5, 0x5b, - 0x2d, 0x42, 0xd5, 0xe5, 0x88, 0xb7, 0x7e, 0x4b, 0xc3, 0xe1, 0x14, 0xa5, 0xf9, 0xcf, 0x1c, 0x94, - 0x36, 0x03, 0xdf, 0x71, 0x43, 0x75, 0xb9, 0xc2, 0x5e, 0x67, 0x28, 0x78, 0xdc, 0xee, 0x75, 0x08, - 0x16, 0x18, 0xf4, 0x02, 0xcc, 0xb0, 0xd0, 0x0a, 0xbb, 0x4c, 0xd8, 0x53, 0x6a, 0x3c, 0x16, 0x85, - 0xa5, 0x7d, 0x01, 0x3d, 0xeb, 0xd7, 0x16, 0x62, 0x71, 0x12, 0x84, 0x15, 0x03, 0xf7, 0xf4, 0xe0, - 0x40, 0x6c, 0x94, 0x73, 0x53, 0xa6, 0xbd, 0x28, 0x7f, 0xe4, 0x13, 0x4f, 0xdf, 0x1d, 0xa2, 0xc0, - 0x23, 0xb8, 0xd0, 0x09, 0x20, 0xcf, 0x62, 0xe1, 0x6d, 0x6a, 0xf9, 0x4c, 0xe8, 0xba, 0xed, 0xb6, - 0x89, 0xba, 0xf0, 0xff, 0x97, 0xed, 0xc4, 0x39, 0x47, 0xa2, 0xf7, 0xd6, 0x90, 0x34, 0x3c, 0x42, - 0x03, 0x7a, 0x12, 0x66, 0x28, 0xb1, 0x58, 0xe0, 0x57, 0x0b, 0x62, 0xf9, 0x71, 0x54, 0xc6, 0x02, - 0x8a, 0x15, 0x96, 0x07, 0xb4, 0x36, 0x61, 0xcc, 0x6a, 0x45, 0xe1, 0x35, 0x0e, 0x68, 0x3b, 0x12, - 0x8c, 0x23, 0xbc, 0xf9, 0x6b, 0x03, 0x2a, 0x9b, 0x94, 0x58, 0x21, 0x99, 0xc4, 0x2d, 0x3e, 0xf7, - 0x89, 0xa3, 0x0d, 0x58, 0x10, 0xdf, 0x77, 0x2d, 0xcf, 0x75, 0xe4, 0x19, 0x4c, 0x0b, 0xe6, 0xff, - 0x56, 0xcc, 0x0b, 0x5b, 0x69, 0x34, 0x1e, 0xa4, 0x37, 0x7f, 0x9c, 0x87, 0x4a, 0x93, 0x78, 0x24, - 0x31, 0x79, 0x0b, 0x50, 0x8b, 0x5a, 0x36, 0xd9, 0x23, 0xd4, 0x0d, 0x9c, 0x7d, 0x62, 0x07, 0xbe, - 0xc3, 0x84, 0x1b, 0xe5, 0x1b, 0xff, 0xc5, 0xf7, 0xf7, 0xe6, 0x10, 0x16, 0x8f, 0xe0, 0x40, 0x1e, - 0x54, 0x3a, 0x54, 0xfc, 0x16, 0x7b, 0x2e, 0xbd, 0xac, 0x7c, 0xf5, 0x4b, 0xd9, 0x8e, 0x74, 0x4f, - 0x67, 0x6d, 0x2c, 0x9d, 0xf6, 0x6b, 0x95, 0x14, 0x08, 0xa7, 0x85, 0xa3, 0xaf, 0xc1, 0x62, 0x40, - 0x3b, 0x47, 0x96, 0xdf, 0x24, 0x1d, 0xe2, 0x3b, 0xc4, 0x0f, 0x99, 0xd8, 0xc8, 0x62, 0x63, 0x99, - 0xd7, 0x22, 0xbb, 0x03, 0x38, 0x3c, 0x44, 0x8d, 0xee, 0xc1, 0x52, 0x87, 0x06, 0x1d, 0xab, 0x25, - 0x36, 0x66, 0x2f, 0xf0, 0x5c, 0xbb, 0xa7, 0xb6, 0xf3, 0xe9, 0xd3, 0x7e, 0x6d, 0x69, 0x6f, 0x10, - 0x79, 0xd6, 0xaf, 0x5d, 0x10, 0x5b, 0xc7, 0x21, 0x09, 0x12, 0x0f, 0x8b, 0xd1, 0xdc, 0xa0, 0x30, - 0xce, 0x0d, 0xcc, 0x6d, 0x28, 0x36, 0xbb, 0xea, 0x4e, 0xbc, 0x04, 0x45, 0x47, 0xfd, 0x56, 0x3b, - 0x1f, 0x5d, 0xce, 0x98, 0xe6, 0xac, 0x5f, 0xab, 0xf0, 0xf2, 0xb3, 0x1e, 0x01, 0x70, 0xcc, 0x62, - 0x3e, 0x09, 0x45, 0x71, 0xf0, 0xec, 0xee, 0x15, 0xb4, 0x08, 0x79, 0x6c, 0xdd, 0x17, 0x52, 0xe6, - 0x30, 0xff, 0xa9, 0x45, 0xb1, 0x5d, 0x80, 0x9b, 0x24, 0x8c, 0x0e, 0x7e, 0x03, 0x16, 0xa2, 0x50, - 0x9e, 0xce, 0x30, 0xb1, 0x37, 0xe1, 0x34, 0x1a, 0x0f, 0xd2, 0x9b, 0x6f, 0x40, 0x49, 0x64, 0x21, - 0x9e, 0xc2, 0x93, 0x72, 0xc1, 0x78, 0x40, 0xb9, 0x10, 0xd5, 0x00, 0xb9, 0x71, 0x35, 0x80, 0x66, - 0xae, 0x07, 0x15, 0xc9, 0x1b, 0x15, 0x48, 0x99, 0x34, 0x3c, 0x0d, 0xc5, 0xc8, 0x4c, 0xa5, 0x25, - 0x2e, 0x8c, 0x23, 0x41, 0x38, 0xa6, 0xd0, 0xb4, 0x1d, 0x41, 0x2a, 0xa3, 0x66, 0x53, 0xa6, 0x55, - 0x3f, 0xb9, 0x07, 0x57, 0x3f, 0x9a, 0xa6, 0x1f, 0x40, 0x75, 0x5c, 0x35, 0xfd, 0x10, 0x39, 0x3f, - 0xbb, 0x29, 0xe6, 0x7b, 0x06, 0x2c, 0xea, 0x92, 0xb2, 0x1f, 0x5f, 0x76, 0x25, 0xe7, 0x57, 0x7b, - 0xda, 0x8e, 0xfc, 0xc2, 0x80, 0xe5, 0xd4, 0xd2, 0x26, 0x3a, 0xf1, 0x09, 0x8c, 0xd2, 0x9d, 0x23, - 0x3f, 0x81, 0x73, 0xfc, 0x29, 0x07, 0x95, 0x5b, 0xd6, 0x01, 0xf1, 0xf6, 0x89, 0x47, 0xec, 0x30, - 0xa0, 0xe8, 0xfb, 0x50, 0x6e, 0x5b, 0xa1, 0x7d, 0x24, 0xa0, 0x51, 0x67, 0xd0, 0xcc, 0x16, 0xec, - 0x52, 0x92, 0xea, 0x3b, 0x89, 0x98, 0x1b, 0x7e, 0x48, 0x7b, 0x8d, 0x0b, 0xca, 0xa4, 0xb2, 0x86, - 0xc1, 0xba, 0x36, 0xd1, 0xce, 0x89, 0xef, 0x1b, 0x6f, 0x77, 0x78, 0xd9, 0x32, 0x79, 0x17, 0x99, - 0x32, 0x01, 0x93, 0xb7, 0xba, 0x2e, 0x25, 0x6d, 0xe2, 0x87, 0x49, 0x3b, 0xb7, 0x33, 0x20, 0x1f, - 0x0f, 0x69, 0x5c, 0x79, 0x19, 0x16, 0x07, 0x8d, 0xe7, 0xf1, 0xe7, 0x98, 0xf4, 0xe4, 0x79, 0x61, - 0xfe, 0x13, 0x2d, 0x43, 0xe1, 0xc4, 0xf2, 0xba, 0xea, 0x36, 0x62, 0xf9, 0x71, 0x3d, 0x77, 0xcd, - 0x30, 0x7f, 0x65, 0x40, 0x75, 0x9c, 0x21, 0xe8, 0x7f, 0x35, 0x41, 0x8d, 0xb2, 0xb2, 0x2a, 0xff, - 0x1a, 0xe9, 0x49, 0xa9, 0x37, 0xa0, 0x18, 0x74, 0x78, 0x4d, 0x11, 0x50, 0x75, 0xea, 0x4f, 0x45, - 0x27, 0xb9, 0xab, 0xe0, 0x67, 0xfd, 0xda, 0xc5, 0x94, 0xf8, 0x08, 0x81, 0x63, 0x56, 0x1e, 0xa9, - 0x85, 0x3d, 0x3c, 0x7b, 0xc4, 0x91, 0xfa, 0xae, 0x80, 0x60, 0x85, 0x31, 0x7f, 0x67, 0xc0, 0xb4, - 0x28, 0xc8, 0xdf, 0x80, 0x22, 0xdf, 0x3f, 0xc7, 0x0a, 0x2d, 0x61, 0x57, 0xe6, 0x56, 0x90, 0x73, - 0xef, 0x90, 0xd0, 0x4a, 0xbc, 0x2d, 0x82, 0xe0, 0x58, 0x22, 0xc2, 0x50, 0x70, 0x43, 0xd2, 0x8e, - 0x0e, 0xf2, 0x99, 0xb1, 0xa2, 0xd5, 0x20, 0xa2, 0x8e, 0xad, 0xfb, 0x37, 0xde, 0x0e, 0x89, 0xcf, - 0x0f, 0x23, 0xb9, 0x1a, 0xdb, 0x5c, 0x06, 0x96, 0xa2, 0xcc, 0x7f, 0x18, 0x10, 0xab, 0xe2, 0xce, - 0xcf, 0x88, 0x77, 0x78, 0xcb, 0xf5, 0x8f, 0xd5, 0xb6, 0xc6, 0xe6, 0xec, 0x2b, 0x38, 0x8e, 0x29, - 0x46, 0xa5, 0x87, 0xdc, 0x64, 0xe9, 0x81, 0x2b, 0xb4, 0x03, 0x3f, 0x74, 0xfd, 0xee, 0xd0, 0x6d, - 0xdb, 0x54, 0x70, 0x1c, 0x53, 0xf0, 0x42, 0x84, 0x92, 0xb6, 0xe5, 0xfa, 0xae, 0xdf, 0xe2, 0x8b, - 0xd8, 0x0c, 0xba, 0x7e, 0x28, 0x32, 0xb2, 0x2a, 0x44, 0xf0, 0x10, 0x16, 0x8f, 0xe0, 0x30, 0x7f, - 0x3b, 0x0d, 0x65, 0xbe, 0xe6, 0x28, 0xcf, 0xbd, 0x08, 0x15, 0x4f, 0xf7, 0x02, 0xb5, 0xf6, 0x8b, - 0xca, 0x94, 0xf4, 0xbd, 0xc6, 0x69, 0x5a, 0xce, 0x2c, 0x4a, 0xa8, 0x98, 0x39, 0x97, 0x66, 0xde, - 0xd2, 0x91, 0x38, 0x4d, 0xcb, 0xa3, 0xd7, 0x7d, 0x7e, 0x3f, 0x54, 0x65, 0x12, 0x1f, 0xd1, 0xd7, - 0x39, 0x10, 0x4b, 0x1c, 0xda, 0x81, 0x0b, 0x96, 0xe7, 0x05, 0xf7, 0x05, 0xb0, 0x11, 0x04, 0xc7, - 0x6d, 0x8b, 0x1e, 0x33, 0xd1, 0x4c, 0x17, 0x1b, 0xff, 0xa3, 0x58, 0x2e, 0x6c, 0x0c, 0x93, 0xe0, - 0x51, 0x7c, 0xa3, 0x8e, 0x6d, 0x7a, 0xc2, 0x63, 0x3b, 0x82, 0xe5, 0x01, 0x90, 0xb8, 0xe5, 0xaa, - 0xb3, 0x7d, 0x4e, 0xc9, 0x59, 0xc6, 0x23, 0x68, 0xce, 0xc6, 0xc0, 0xf1, 0x48, 0x89, 0xe8, 0x3a, - 0xcc, 0x73, 0x4f, 0x0e, 0xba, 0x61, 0x54, 0x77, 0x16, 0xc4, 0x71, 0xa3, 0xd3, 0x7e, 0x6d, 0xfe, - 0x76, 0x0a, 0x83, 0x07, 0x28, 0xf9, 0xe6, 0x7a, 0x6e, 0xdb, 0x0d, 0xab, 0xb3, 0x82, 0x25, 0xde, - 0xdc, 0x5b, 0x1c, 0x88, 0x25, 0x2e, 0xe5, 0x81, 0xc5, 0xf3, 0x3c, 0xd0, 0xfc, 0x63, 0x1e, 0x90, - 0xac, 0xb5, 0x1d, 0x59, 0x4f, 0xc9, 0x90, 0xc6, 0x3b, 0x02, 0x55, 0xab, 0x1b, 0x03, 0x1d, 0x81, - 0x2a, 0xd3, 0x23, 0x3c, 0xda, 0x81, 0x92, 0x0c, 0x2d, 0xc9, 0x75, 0x59, 0x57, 0xc4, 0xa5, 0xdd, - 0x08, 0x71, 0xd6, 0xaf, 0xad, 0xa4, 0xd4, 0xc4, 0x18, 0xd1, 0xad, 0x25, 0x12, 0xd0, 0x55, 0x00, - 0xab, 0xe3, 0xea, 0xf3, 0xba, 0x52, 0x32, 0xb5, 0x49, 0x3a, 0x6f, 0xac, 0x51, 0xa1, 0x57, 0x60, - 0x3a, 0xfc, 0x7c, 0x1d, 0x55, 0x51, 0x34, 0x8c, 0xbc, 0x7f, 0x12, 0x12, 0xb8, 0x76, 0xe1, 0xcf, - 0x8c, 0x9b, 0xa5, 0x9a, 0xa1, 0x58, 0xfb, 0x56, 0x8c, 0xc1, 0x1a, 0x15, 0xfa, 0x06, 0x14, 0x0f, - 0x55, 0x29, 0x2a, 0x0e, 0x26, 0x73, 0x88, 0x8c, 0x0a, 0x58, 0x39, 0x32, 0x88, 0xbe, 0x70, 0x2c, - 0x0d, 0x7d, 0x19, 0xca, 0xac, 0x7b, 0x10, 0x67, 0x6f, 0x79, 0x9a, 0x71, 0xaa, 0xdc, 0x4f, 0x50, - 0x58, 0xa7, 0x33, 0xdf, 0x82, 0xd2, 0x8e, 0x6b, 0xd3, 0x40, 0xf4, 0x80, 0x4f, 0xc1, 0x2c, 0x4b, - 0x35, 0x38, 0xf1, 0x49, 0x46, 0x5e, 0x16, 0xe1, 0xb9, 0x7b, 0xf9, 0x96, 0x1f, 0xc8, 0x36, 0xa6, - 0x90, 0xb8, 0xd7, 0xeb, 0x1c, 0x88, 0x25, 0xee, 0xfa, 0x32, 0x2f, 0x10, 0xde, 0xfd, 0xb0, 0x36, - 0xf5, 0xfe, 0x87, 0xb5, 0xa9, 0x0f, 0x3e, 0x54, 0xc5, 0xc2, 0xbb, 0x65, 0x80, 0xdd, 0x83, 0xef, - 0x12, 0x5b, 0x86, 0xdd, 0x4c, 0x63, 0xbd, 0x68, 0x9a, 0x2c, 0xc6, 0x7a, 0xb9, 0x81, 0xa2, 0x4f, - 0xc3, 0xe1, 0x14, 0x25, 0x5a, 0x87, 0x52, 0x3c, 0xb0, 0x53, 0xfe, 0xb1, 0x14, 0xf9, 0x5b, 0x3c, - 0xd5, 0xc3, 0x09, 0x4d, 0x2a, 0x07, 0x4c, 0x9f, 0x9b, 0x03, 0x1a, 0x90, 0xef, 0xba, 0x8e, 0x6a, - 0x98, 0x9f, 0x8d, 0x72, 0xf0, 0x9d, 0xed, 0xe6, 0x59, 0xbf, 0xf6, 0xd8, 0xb8, 0x39, 0x79, 0xd8, - 0xeb, 0x10, 0x56, 0xbf, 0xb3, 0xdd, 0xc4, 0x9c, 0x79, 0x54, 0x40, 0x9a, 0x99, 0x30, 0x20, 0x5d, - 0x05, 0x68, 0x25, 0x63, 0x07, 0x79, 0xdf, 0x63, 0x47, 0xd4, 0xc6, 0x0d, 0x1a, 0x15, 0x62, 0xb0, - 0x64, 0xf3, 0xd6, 0x5c, 0xb5, 0xff, 0x2c, 0xb4, 0xda, 0x72, 0x90, 0x39, 0xd9, 0x9d, 0xb8, 0xa4, - 0xd4, 0x2c, 0x6d, 0x0e, 0x0a, 0xc3, 0xc3, 0xf2, 0x51, 0x00, 0x4b, 0x8e, 0xea, 0x10, 0x13, 0xa5, - 0xa5, 0x89, 0x95, 0x5e, 0xe4, 0x0a, 0x9b, 0x83, 0x82, 0xf0, 0xb0, 0x6c, 0xf4, 0x6d, 0x58, 0x89, - 0x80, 0xc3, 0x6d, 0xba, 0x08, 0xd8, 0xf9, 0xc6, 0xea, 0x69, 0xbf, 0xb6, 0xd2, 0x1c, 0x4b, 0x85, - 0x1f, 0x20, 0x01, 0x39, 0x30, 0xe3, 0xc9, 0x02, 0xb7, 0x2c, 0x8a, 0x92, 0xaf, 0x64, 0x5b, 0x45, - 0xe2, 0xfd, 0x75, 0xbd, 0xb0, 0x8d, 0x47, 0x2e, 0xaa, 0xa6, 0x55, 0xb2, 0xd1, 0xdb, 0x50, 0xb6, - 0x7c, 0x3f, 0x08, 0x2d, 0x39, 0x38, 0x98, 0x13, 0xaa, 0x36, 0x26, 0x56, 0xb5, 0x91, 0xc8, 0x18, - 0x28, 0xa4, 0x35, 0x0c, 0xd6, 0x55, 0xa1, 0xfb, 0xb0, 0x10, 0xdc, 0xf7, 0x09, 0xc5, 0xe4, 0x90, - 0x50, 0xe2, 0xdb, 0x84, 0x55, 0x2b, 0x42, 0xfb, 0x73, 0x19, 0xb5, 0xa7, 0x98, 0x13, 0x97, 0x4e, - 0xc3, 0x19, 0x1e, 0xd4, 0x82, 0xea, 0x3c, 0xb6, 0xfa, 0x96, 0xe7, 0x7e, 0x8f, 0x50, 0x56, 0x9d, - 0x4f, 0x66, 0xcd, 0x5b, 0x31, 0x14, 0x6b, 0x14, 0x68, 0x13, 0xca, 0xb6, 0xd7, 0x65, 0x21, 0x91, - 0x83, 0xff, 0x85, 0xd4, 0x04, 0xef, 0xd2, 0xbd, 0x7b, 0xf7, 0xbe, 0xd3, 0x24, 0x1d, 0x4a, 0x6c, - 0x2b, 0x24, 0xce, 0x66, 0x42, 0x88, 0x75, 0x2e, 0xd4, 0x85, 0x4a, 0x5b, 0xcf, 0x3b, 0xd5, 0x25, - 0xb1, 0xd6, 0x6b, 0xd9, 0xd6, 0x3a, 0x9c, 0x19, 0x93, 0x32, 0x28, 0x85, 0xc3, 0x69, 0x2d, 0x2b, - 0x2f, 0x40, 0xf9, 0x73, 0x76, 0x08, 0xbc, 0xc3, 0x18, 0x3c, 0xd5, 0x89, 0x3a, 0x8c, 0xdf, 0xe7, - 0x60, 0x3e, 0x7d, 0x16, 0x03, 0x39, 0xb5, 0x90, 0x29, 0xa7, 0x46, 0xbd, 0xac, 0x31, 0xf6, 0xe5, - 0x22, 0x0a, 0xf2, 0xf9, 0xb1, 0x41, 0x5e, 0xc5, 0xd2, 0xe9, 0x87, 0x89, 0xa5, 0x75, 0x00, 0x5e, - 0xac, 0xd0, 0xc0, 0xf3, 0x08, 0x15, 0x61, 0xb4, 0xa8, 0x5e, 0x28, 0x62, 0x28, 0xd6, 0x28, 0x78, - 0x49, 0x7d, 0xe0, 0x05, 0xf6, 0xb1, 0xd8, 0x82, 0x28, 0x04, 0x88, 0x00, 0x5a, 0x94, 0x25, 0x75, - 0x63, 0x08, 0x8b, 0x47, 0x70, 0x98, 0x3d, 0xb8, 0xb8, 0x67, 0xd1, 0xd0, 0xb5, 0xbc, 0xe4, 0xba, - 0x89, 0x9e, 0xe5, 0xcd, 0xa1, 0x8e, 0xe8, 0xd9, 0x49, 0xaf, 0x6d, 0xb2, 0xf9, 0x09, 0x2c, 0xe9, - 0x8a, 0xcc, 0x3f, 0x1b, 0x70, 0x69, 0xa4, 0xee, 0x2f, 0xa0, 0x23, 0x7b, 0x33, 0xdd, 0x91, 0xbd, - 0x98, 0x71, 0x94, 0x39, 0xca, 0xda, 0x31, 0xfd, 0xd9, 0x2c, 0x14, 0xf6, 0x78, 0x25, 0x6c, 0x7e, - 0x6c, 0xc0, 0x9c, 0xf8, 0x35, 0xc9, 0x24, 0xb9, 0x96, 0x7e, 0x60, 0x28, 0x3d, 0xba, 0xc7, 0x85, - 0x47, 0x31, 0x6a, 0x7e, 0xcf, 0x80, 0xf4, 0x0c, 0x17, 0xbd, 0x2c, 0xaf, 0x80, 0x11, 0x0f, 0x59, - 0x27, 0x74, 0xff, 0x97, 0xc6, 0xb5, 0xa4, 0x17, 0x32, 0x4d, 0x2b, 0x9f, 0x86, 0x12, 0x0e, 0x82, - 0x70, 0xcf, 0x0a, 0x8f, 0x18, 0xdf, 0xbb, 0x0e, 0xff, 0xa1, 0xb6, 0x57, 0xec, 0x9d, 0xc0, 0x60, - 0x09, 0x37, 0x7f, 0x6a, 0xc0, 0xa5, 0xb1, 0xef, 0x46, 0x3c, 0x8a, 0xd8, 0xf1, 0x97, 0x5a, 0x51, - 0xec, 0xc8, 0x09, 0x1d, 0xd6, 0xa8, 0x78, 0x2f, 0x99, 0x7a, 0x6c, 0x1a, 0xec, 0x25, 0x53, 0xda, - 0x70, 0x9a, 0xd6, 0xfc, 0x7b, 0x0e, 0xd4, 0x43, 0xcd, 0xbf, 0xd9, 0xe9, 0x9f, 0x1c, 0x78, 0x26, - 0x9a, 0x4f, 0x3f, 0x13, 0xc5, 0x6f, 0x42, 0xda, 0x3b, 0x49, 0xfe, 0xc1, 0xef, 0x24, 0xe8, 0xf9, - 0xf8, 0xe9, 0x45, 0xfa, 0xd0, 0x6a, 0xfa, 0xe9, 0xe5, 0xac, 0x5f, 0x9b, 0x53, 0xc2, 0xd3, 0x4f, - 0x31, 0xf7, 0x60, 0xd6, 0x21, 0xa1, 0xe5, 0x7a, 0xb2, 0x2f, 0xcc, 0xfc, 0x98, 0x20, 0x85, 0x35, - 0x25, 0x6b, 0xa3, 0xcc, 0x6d, 0x52, 0x1f, 0x38, 0x12, 0xc8, 0x03, 0xb6, 0x1d, 0x38, 0xb2, 0xad, - 0x29, 0x24, 0x01, 0x7b, 0x33, 0x70, 0x08, 0x16, 0x18, 0xf3, 0x7d, 0x03, 0xca, 0x52, 0xd2, 0xa6, - 0xd5, 0x65, 0x04, 0x5d, 0x89, 0x57, 0x21, 0x8f, 0xfb, 0x92, 0xfe, 0xc6, 0x76, 0xd6, 0xaf, 0x95, - 0x04, 0x99, 0xe8, 0x88, 0x46, 0xbc, 0x25, 0xe5, 0xce, 0xd9, 0xa3, 0xc7, 0xa1, 0x20, 0x2e, 0x90, - 0xda, 0xcc, 0xe4, 0xb1, 0x90, 0x03, 0xb1, 0xc4, 0x99, 0x9f, 0xe6, 0xa0, 0x92, 0x5a, 0x5c, 0x86, - 0xe6, 0x22, 0x1e, 0xa1, 0xe6, 0x32, 0x8c, 0xe5, 0xc7, 0x3f, 0xcd, 0xab, 0xf4, 0x35, 0xf3, 0x30, - 0xe9, 0xeb, 0x9b, 0x30, 0x63, 0xf3, 0x3d, 0x8a, 0xfe, 0xe9, 0x71, 0x65, 0x92, 0xe3, 0x14, 0xbb, - 0x9b, 0x78, 0xa3, 0xf8, 0x64, 0x58, 0x09, 0x44, 0x37, 0x61, 0x89, 0x92, 0x90, 0xf6, 0x36, 0x0e, - 0x43, 0x42, 0xf5, 0x61, 0x42, 0x21, 0x29, 0xe1, 0xf1, 0x20, 0x01, 0x1e, 0xe6, 0x31, 0x0f, 0x60, - 0xee, 0xb6, 0x75, 0xe0, 0xc5, 0xcf, 0x63, 0x18, 0x2a, 0xae, 0x6f, 0x7b, 0x5d, 0x87, 0xc8, 0x80, - 0x1e, 0x45, 0xaf, 0xe8, 0xd2, 0x6e, 0xeb, 0xc8, 0xb3, 0x7e, 0xed, 0x42, 0x0a, 0x20, 0xdf, 0x83, - 0x70, 0x5a, 0x84, 0xe9, 0xc1, 0xf4, 0x17, 0xd8, 0x8e, 0x7e, 0x0b, 0x4a, 0x49, 0xc3, 0xf0, 0x88, - 0x55, 0x9a, 0x6f, 0x42, 0x91, 0x7b, 0x7c, 0xd4, 0xe8, 0x9e, 0x53, 0x25, 0xa5, 0x6b, 0xaf, 0x5c, - 0x96, 0xda, 0x4b, 0x3c, 0xb2, 0xde, 0xe9, 0x38, 0x0f, 0xf9, 0xc8, 0x9a, 0x7b, 0x98, 0xcc, 0x97, - 0x9f, 0x30, 0xf3, 0x5d, 0x05, 0xf9, 0x47, 0x14, 0x9e, 0x64, 0x64, 0x01, 0xa1, 0x25, 0x19, 0x3d, - 0xff, 0x6b, 0x2f, 0x0c, 0x3f, 0x32, 0x00, 0xc4, 0x28, 0xef, 0xc6, 0x09, 0xf1, 0xc3, 0x0c, 0xcf, - 0xf9, 0x77, 0x60, 0x26, 0x90, 0x1e, 0x29, 0x1f, 0x5a, 0x27, 0x9c, 0x17, 0xc7, 0x17, 0x49, 0xfa, - 0x24, 0x56, 0xc2, 0x1a, 0xaf, 0x7e, 0xf4, 0xd9, 0xea, 0xd4, 0xc7, 0x9f, 0xad, 0x4e, 0x7d, 0xf2, - 0xd9, 0xea, 0xd4, 0x3b, 0xa7, 0xab, 0xc6, 0x47, 0xa7, 0xab, 0xc6, 0xc7, 0xa7, 0xab, 0xc6, 0x27, - 0xa7, 0xab, 0xc6, 0xa7, 0xa7, 0xab, 0xc6, 0xfb, 0x7f, 0x5d, 0x9d, 0xba, 0xf7, 0x44, 0x96, 0x3f, - 0xf8, 0xfd, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x2d, 0x24, 0x60, 0xec, 0x20, 0x28, 0x00, 0x00, + // 2867 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1a, 0x4b, 0x6f, 0x24, 0x47, + 0xd9, 0x3d, 0x0f, 0x7b, 0xe6, 0x9b, 0x19, 0x3f, 0x6a, 0xbd, 0x30, 0x6b, 0x84, 0xc7, 0xe9, 0x44, + 0xd1, 0x06, 0x92, 0x71, 0x76, 0x09, 0xd1, 0x66, 0x43, 0x02, 0x1e, 0xcf, 0x7a, 0xe3, 0x64, 0x1d, + 0x5b, 0xe5, 0xdd, 0x05, 0x42, 0x84, 0xd2, 0x9e, 0x2e, 0x8f, 0x1b, 0xf7, 0x74, 0x4f, 0xaa, 0x7a, + 0xbc, 0x19, 0x38, 0x90, 0x03, 0x08, 0x90, 0x50, 0x14, 0x6e, 0x9c, 0x50, 0x22, 0xf8, 0x01, 0x88, + 0x13, 0x77, 0x90, 0xc8, 0x31, 0x88, 0x4b, 0x24, 0xd0, 0x28, 0x31, 0x07, 0x8e, 0x88, 0xab, 0x85, + 0x04, 0xaa, 0x47, 0x77, 0x57, 0xcf, 0x63, 0xdd, 0x93, 0x5d, 0x22, 0x6e, 0xd3, 0xdf, 0xbb, 0xaa, + 0xbe, 0xfa, 0xea, 0x7b, 0x0c, 0xec, 0x1c, 0x5f, 0x63, 0x75, 0xc7, 0x5f, 0x3f, 0xee, 0x1d, 0x10, + 0xea, 0x91, 0x80, 0xb0, 0xf5, 0x13, 0xe2, 0xd9, 0x3e, 0x5d, 0x57, 0x08, 0xab, 0xeb, 0x74, 0xac, + 0xd6, 0x91, 0xe3, 0x11, 0xda, 0x5f, 0xef, 0x1e, 0xb7, 0x39, 0x80, 0xad, 0x77, 0x48, 0x60, 0xad, + 0x9f, 0x5c, 0x59, 0x6f, 0x13, 0x8f, 0x50, 0x2b, 0x20, 0x76, 0xbd, 0x4b, 0xfd, 0xc0, 0x47, 0x8f, + 0x49, 0xae, 0xba, 0xce, 0x55, 0xef, 0x1e, 0xb7, 0x39, 0x80, 0xd5, 0x39, 0x57, 0xfd, 0xe4, 0xca, + 0xca, 0x53, 0x6d, 0x27, 0x38, 0xea, 0x1d, 0xd4, 0x5b, 0x7e, 0x67, 0xbd, 0xed, 0xb7, 0xfd, 0x75, + 0xc1, 0x7c, 0xd0, 0x3b, 0x14, 0x5f, 0xe2, 0x43, 0xfc, 0x92, 0x42, 0x57, 0x26, 0x9a, 0x42, 0x7b, + 0x5e, 0xe0, 0x74, 0xc8, 0xb0, 0x15, 0x2b, 0xcf, 0x9e, 0xc7, 0xc0, 0x5a, 0x47, 0xa4, 0x63, 0x0d, + 0xf3, 0x99, 0x7f, 0xca, 0x42, 0x61, 0x63, 0x6f, 0xfb, 0x26, 0xf5, 0x7b, 0x5d, 0xb4, 0x06, 0x39, + 0xcf, 0xea, 0x90, 0xaa, 0xb1, 0x66, 0x5c, 0x2e, 0x36, 0xca, 0x1f, 0x0c, 0x6a, 0x33, 0xa7, 0x83, + 0x5a, 0xee, 0x55, 0xab, 0x43, 0xb0, 0xc0, 0x20, 0x17, 0x0a, 0x27, 0x84, 0x32, 0xc7, 0xf7, 0x58, + 0x35, 0xb3, 0x96, 0xbd, 0x5c, 0xba, 0xfa, 0x62, 0x3d, 0xcd, 0xfa, 0xeb, 0x42, 0xc1, 0x5d, 0xc9, + 0xba, 0xe5, 0xd3, 0xa6, 0xc3, 0x5a, 0xfe, 0x09, 0xa1, 0xfd, 0xc6, 0xa2, 0xd2, 0x52, 0x50, 0x48, + 0x86, 0x23, 0x0d, 0xe8, 0x47, 0x06, 0x2c, 0x76, 0x29, 0x39, 0x24, 0x94, 0x12, 0x5b, 0xe1, 0xab, + 0xd9, 0x35, 0xe3, 0x21, 0xa8, 0xad, 0x2a, 0xb5, 0x8b, 0x7b, 0x43, 0xf2, 0xf1, 0x88, 0x46, 0xf4, + 0x6b, 0x03, 0x56, 0x18, 0xa1, 0x27, 0x84, 0x6e, 0xd8, 0x36, 0x25, 0x8c, 0x35, 0xfa, 0x9b, 0xae, + 0x43, 0xbc, 0x60, 0x73, 0xbb, 0x89, 0x59, 0x35, 0x27, 0xf6, 0xe1, 0xeb, 0xe9, 0x0c, 0xda, 0x9f, + 0x24, 0xa7, 0x61, 0x2a, 0x8b, 0x56, 0x26, 0x92, 0x30, 0x7c, 0x1f, 0x33, 0xcc, 0x43, 0x28, 0x87, + 0x07, 0x79, 0xcb, 0x61, 0x01, 0xba, 0x0b, 0xb3, 0x6d, 0xfe, 0xc1, 0xaa, 0x86, 0x30, 0xb0, 0x9e, + 0xce, 0xc0, 0x50, 0x46, 0x63, 0x5e, 0xd9, 0x33, 0x2b, 0x3e, 0x19, 0x56, 0xd2, 0xcc, 0x9f, 0xe5, + 0xa0, 0xb4, 0xb1, 0xb7, 0x8d, 0x09, 0xf3, 0x7b, 0xb4, 0x45, 0x52, 0x38, 0xcd, 0x35, 0x28, 0x33, + 0xc7, 0x6b, 0xf7, 0x5c, 0x8b, 0x72, 0x68, 0x75, 0x56, 0x50, 0x2e, 0x2b, 0xca, 0xf2, 0xbe, 0x86, + 0xc3, 0x09, 0x4a, 0x74, 0x15, 0x80, 0x4b, 0x60, 0x5d, 0xab, 0x45, 0xec, 0x6a, 0x66, 0xcd, 0xb8, + 0x5c, 0x68, 0x20, 0xc5, 0x07, 0xaf, 0x46, 0x18, 0xac, 0x51, 0xa1, 0x47, 0x21, 0x2f, 0x2c, 0xad, + 0x16, 0x84, 0x9a, 0x8a, 0x22, 0xcf, 0x8b, 0x65, 0x60, 0x89, 0x43, 0x4f, 0xc0, 0x9c, 0xf2, 0xb2, + 0x6a, 0x51, 0x90, 0x2d, 0x28, 0xb2, 0xb9, 0xd0, 0x0d, 0x42, 0x3c, 0x5f, 0xdf, 0xb1, 0xe3, 0xd9, + 0xc2, 0xef, 0xb4, 0xf5, 0xbd, 0xe2, 0x78, 0x36, 0x16, 0x18, 0x74, 0x0b, 0xf2, 0x27, 0x84, 0x1e, + 0x70, 0x4f, 0xe0, 0xae, 0xf9, 0xe5, 0x74, 0x1b, 0x7d, 0x97, 0xb3, 0x34, 0x8a, 0xdc, 0x34, 0xf1, + 0x13, 0x4b, 0x21, 0xa8, 0x0e, 0xc0, 0x8e, 0x7c, 0x1a, 0x88, 0xe5, 0x55, 0xf3, 0x6b, 0xd9, 0xcb, + 0xc5, 0xc6, 0x3c, 0x5f, 0xef, 0x7e, 0x04, 0xc5, 0x1a, 0x05, 0xa7, 0x6f, 0x59, 0x01, 0x69, 0xfb, + 0xd4, 0x21, 0xac, 0x3a, 0x17, 0xd3, 0x6f, 0x46, 0x50, 0xac, 0x51, 0xa0, 0x97, 0x01, 0xb1, 0xc0, + 0xa7, 0x56, 0x9b, 0xa8, 0xa5, 0xbe, 0x64, 0xb1, 0xa3, 0x2a, 0x88, 0xd5, 0xad, 0xa8, 0xd5, 0xa1, + 0xfd, 0x11, 0x0a, 0x3c, 0x86, 0xcb, 0xfc, 0x9d, 0x01, 0x0b, 0x9a, 0x2f, 0x08, 0xbf, 0xbb, 0x06, + 0xe5, 0xb6, 0x76, 0xeb, 0x94, 0x5f, 0x44, 0xa7, 0xad, 0xdf, 0x48, 0x9c, 0xa0, 0x44, 0x04, 0x8a, + 0x54, 0x49, 0x0a, 0xa3, 0xcb, 0x95, 0xd4, 0x4e, 0x1b, 0xda, 0x10, 0x6b, 0xd2, 0x80, 0x0c, 0xc7, + 0x92, 0xcd, 0x7f, 0x18, 0xc2, 0x81, 0xc3, 0x78, 0x83, 0x2e, 0x6b, 0x31, 0xcd, 0x10, 0xdb, 0x57, + 0x9e, 0x10, 0x8f, 0xce, 0x09, 0x04, 0x99, 0xff, 0x8b, 0x40, 0x70, 0xbd, 0xf0, 0xcb, 0xf7, 0x6a, + 0x33, 0x6f, 0xff, 0x6d, 0x6d, 0xc6, 0xfc, 0x85, 0x01, 0xe5, 0x8d, 0x6e, 0xd7, 0xed, 0xef, 0x76, + 0x03, 0xb1, 0x00, 0x13, 0x66, 0x6d, 0xda, 0xc7, 0x3d, 0x4f, 0x2d, 0x14, 0xf8, 0xfd, 0x6e, 0x0a, + 0x08, 0x56, 0x18, 0x7e, 0x7f, 0x0e, 0x7d, 0xda, 0x22, 0xea, 0xba, 0x45, 0xf7, 0x67, 0x8b, 0x03, + 0xb1, 0xc4, 0xf1, 0x43, 0x3e, 0x74, 0x88, 0x6b, 0xef, 0x58, 0x9e, 0xd5, 0x26, 0x54, 0x5d, 0x8e, + 0x68, 0xeb, 0xb7, 0x34, 0x1c, 0x4e, 0x50, 0x9a, 0xff, 0xc9, 0x40, 0x71, 0xd3, 0xf7, 0x6c, 0x27, + 0x50, 0x97, 0x2b, 0xe8, 0x77, 0x47, 0x82, 0xc7, 0xed, 0x7e, 0x97, 0x60, 0x81, 0x41, 0xcf, 0xc1, + 0x2c, 0x0b, 0xac, 0xa0, 0xc7, 0x84, 0x3d, 0xc5, 0xc6, 0x23, 0x61, 0x58, 0xda, 0x17, 0xd0, 0xb3, + 0x41, 0x6d, 0x21, 0x12, 0x27, 0x41, 0x58, 0x31, 0x70, 0x4f, 0xf7, 0x0f, 0xc4, 0x46, 0xd9, 0x37, + 0xe5, 0xb3, 0x17, 0xbe, 0x1f, 0xd9, 0xd8, 0xd3, 0x77, 0x47, 0x28, 0xf0, 0x18, 0x2e, 0x74, 0x02, + 0xc8, 0xb5, 0x58, 0x70, 0x9b, 0x5a, 0x1e, 0x13, 0xba, 0x6e, 0x3b, 0x1d, 0xa2, 0x2e, 0xfc, 0x97, + 0xd2, 0x9d, 0x38, 0xe7, 0x88, 0xf5, 0xde, 0x1a, 0x91, 0x86, 0xc7, 0x68, 0x40, 0x8f, 0xc3, 0x2c, + 0x25, 0x16, 0xf3, 0xbd, 0x6a, 0x5e, 0x2c, 0x3f, 0x8a, 0xca, 0x58, 0x40, 0xb1, 0xc2, 0xf2, 0x80, + 0xd6, 0x21, 0x8c, 0x59, 0xed, 0x30, 0xbc, 0x46, 0x01, 0x6d, 0x47, 0x82, 0x71, 0x88, 0x37, 0x7f, + 0x6b, 0x40, 0x65, 0x93, 0x12, 0x2b, 0x20, 0xd3, 0xb8, 0xc5, 0xa7, 0x3e, 0x71, 0xb4, 0x01, 0x0b, + 0xe2, 0xfb, 0xae, 0xe5, 0x3a, 0xb6, 0x3c, 0x83, 0x9c, 0x60, 0xfe, 0xbc, 0x62, 0x5e, 0xd8, 0x4a, + 0xa2, 0xf1, 0x30, 0xbd, 0xf9, 0x93, 0x2c, 0x54, 0x9a, 0xc4, 0x25, 0xb1, 0xc9, 0x5b, 0x80, 0xda, + 0xd4, 0x6a, 0x91, 0x3d, 0x42, 0x1d, 0xdf, 0xde, 0x27, 0x2d, 0xdf, 0xb3, 0x99, 0x70, 0xa3, 0x6c, + 0xe3, 0x73, 0x7c, 0x7f, 0x6f, 0x8e, 0x60, 0xf1, 0x18, 0x0e, 0xe4, 0x42, 0xa5, 0x4b, 0xc5, 0x6f, + 0xb1, 0xe7, 0xd2, 0xcb, 0x4a, 0x57, 0xbf, 0x92, 0xee, 0x48, 0xf7, 0x74, 0xd6, 0xc6, 0xd2, 0xe9, + 0xa0, 0x56, 0x49, 0x80, 0x70, 0x52, 0x38, 0xfa, 0x06, 0x2c, 0xfa, 0xb4, 0x7b, 0x64, 0x79, 0x4d, + 0xd2, 0x25, 0x9e, 0x4d, 0xbc, 0x80, 0x89, 0x8d, 0x2c, 0x34, 0x96, 0x79, 0x2e, 0xb2, 0x3b, 0x84, + 0xc3, 0x23, 0xd4, 0xe8, 0x35, 0x58, 0xea, 0x52, 0xbf, 0x6b, 0xb5, 0xc5, 0xc6, 0xec, 0xf9, 0xae, + 0xd3, 0xea, 0xab, 0xed, 0x7c, 0xf2, 0x74, 0x50, 0x5b, 0xda, 0x1b, 0x46, 0x9e, 0x0d, 0x6a, 0x17, + 0xc4, 0xd6, 0x71, 0x48, 0x8c, 0xc4, 0xa3, 0x62, 0x34, 0x37, 0xc8, 0x4f, 0x72, 0x03, 0x73, 0x1b, + 0x0a, 0xcd, 0x9e, 0xba, 0x13, 0x2f, 0x40, 0xc1, 0x56, 0xbf, 0xd5, 0xce, 0x87, 0x97, 0x33, 0xa2, + 0x39, 0x1b, 0xd4, 0x2a, 0x3c, 0xfd, 0xac, 0x87, 0x00, 0x1c, 0xb1, 0x98, 0x8f, 0x43, 0x41, 0x1c, + 0x3c, 0xbb, 0x7b, 0x05, 0x2d, 0x42, 0x16, 0x5b, 0xf7, 0x84, 0x94, 0x32, 0xe6, 0x3f, 0xb5, 0x28, + 0xb6, 0x0b, 0x70, 0x93, 0x04, 0xe1, 0xc1, 0x6f, 0xc0, 0x42, 0x18, 0xca, 0x93, 0x2f, 0x4c, 0xe4, + 0x4d, 0x38, 0x89, 0xc6, 0xc3, 0xf4, 0xe6, 0xeb, 0x50, 0x14, 0xaf, 0x10, 0x7f, 0xc2, 0xe3, 0x74, + 0xc1, 0xb8, 0x4f, 0xba, 0x10, 0xe6, 0x00, 0x99, 0x49, 0x39, 0x80, 0x66, 0xae, 0x0b, 0x15, 0xc9, + 0x1b, 0x26, 0x48, 0xa9, 0x34, 0x3c, 0x09, 0x85, 0xd0, 0x4c, 0xa5, 0x25, 0x4a, 0x8c, 0x43, 0x41, + 0x38, 0xa2, 0xd0, 0xb4, 0x1d, 0x41, 0xe2, 0x45, 0x4d, 0xa7, 0x4c, 0xcb, 0x7e, 0x32, 0xf7, 0xcf, + 0x7e, 0x34, 0x4d, 0x3f, 0x84, 0xea, 0xa4, 0x6c, 0xfa, 0x01, 0xde, 0xfc, 0xf4, 0xa6, 0x98, 0xef, + 0x18, 0xb0, 0xa8, 0x4b, 0x4a, 0x7f, 0x7c, 0xe9, 0x95, 0x9c, 0x9f, 0xed, 0x69, 0x3b, 0xf2, 0x2b, + 0x03, 0x96, 0x13, 0x4b, 0x9b, 0xea, 0xc4, 0xa7, 0x30, 0x4a, 0x77, 0x8e, 0xec, 0x14, 0xce, 0xf1, + 0x97, 0x0c, 0x54, 0x6e, 0x59, 0x07, 0xc4, 0xdd, 0x27, 0x2e, 0x69, 0x05, 0x3e, 0x45, 0x3f, 0x80, + 0x52, 0xc7, 0x0a, 0x5a, 0x47, 0x02, 0x1a, 0x56, 0x06, 0xcd, 0x74, 0xc1, 0x2e, 0x21, 0xa9, 0xbe, + 0x13, 0x8b, 0xb9, 0xe1, 0x05, 0xb4, 0xdf, 0xb8, 0xa0, 0x4c, 0x2a, 0x69, 0x18, 0xac, 0x6b, 0x13, + 0xe5, 0x9c, 0xf8, 0xbe, 0xf1, 0x56, 0x97, 0xa7, 0x2d, 0xd3, 0x57, 0x91, 0x09, 0x13, 0x30, 0x79, + 0xb3, 0xe7, 0x50, 0xd2, 0x21, 0x5e, 0x10, 0x97, 0x73, 0x3b, 0x43, 0xf2, 0xf1, 0x88, 0xc6, 0x95, + 0x17, 0x61, 0x71, 0xd8, 0x78, 0x1e, 0x7f, 0x8e, 0x49, 0x5f, 0x9e, 0x17, 0xe6, 0x3f, 0xd1, 0x32, + 0xe4, 0x4f, 0x2c, 0xb7, 0xa7, 0x6e, 0x23, 0x96, 0x1f, 0xd7, 0x33, 0xd7, 0x0c, 0xf3, 0x37, 0x06, + 0x54, 0x27, 0x19, 0x82, 0xbe, 0xa8, 0x09, 0x6a, 0x94, 0x94, 0x55, 0xd9, 0x57, 0x48, 0x5f, 0x4a, + 0xbd, 0x01, 0x05, 0xbf, 0xcb, 0x73, 0x0a, 0x9f, 0xaa, 0x53, 0x7f, 0x22, 0x3c, 0xc9, 0x5d, 0x05, + 0x3f, 0x1b, 0xd4, 0x2e, 0x26, 0xc4, 0x87, 0x08, 0x1c, 0xb1, 0xf2, 0x48, 0x2d, 0xec, 0xe1, 0xaf, + 0x47, 0x14, 0xa9, 0xef, 0x0a, 0x08, 0x56, 0x18, 0xf3, 0xf7, 0x06, 0xe4, 0x44, 0x42, 0xfe, 0x3a, + 0x14, 0xf8, 0xfe, 0xd9, 0x56, 0x60, 0x09, 0xbb, 0x52, 0x97, 0x82, 0x9c, 0x7b, 0x87, 0x04, 0x56, + 0xec, 0x6d, 0x21, 0x04, 0x47, 0x12, 0x11, 0x86, 0xbc, 0x13, 0x90, 0x4e, 0x78, 0x90, 0x4f, 0x4d, + 0x14, 0xad, 0x1a, 0x11, 0x75, 0x6c, 0xdd, 0xbb, 0xf1, 0x56, 0x40, 0x3c, 0x7e, 0x18, 0xf1, 0xd5, + 0xd8, 0xe6, 0x32, 0xb0, 0x14, 0x65, 0xfe, 0xcb, 0x80, 0x48, 0x15, 0x77, 0x7e, 0x46, 0xdc, 0xc3, + 0x5b, 0x8e, 0x77, 0xac, 0xb6, 0x35, 0x32, 0x67, 0x5f, 0xc1, 0x71, 0x44, 0x31, 0xee, 0x79, 0xc8, + 0x4c, 0xf7, 0x3c, 0x70, 0x85, 0x2d, 0xdf, 0x0b, 0x1c, 0xaf, 0x37, 0x72, 0xdb, 0x36, 0x15, 0x1c, + 0x47, 0x14, 0x3c, 0x11, 0xa1, 0xa4, 0x63, 0x39, 0x9e, 0xe3, 0xb5, 0xf9, 0x22, 0x36, 0xfd, 0x9e, + 0x17, 0x88, 0x17, 0x59, 0x25, 0x22, 0x78, 0x04, 0x8b, 0xc7, 0x70, 0x98, 0xff, 0xce, 0x41, 0x89, + 0xaf, 0x39, 0x7c, 0xe7, 0x9e, 0x87, 0x8a, 0xab, 0x7b, 0x81, 0x5a, 0xfb, 0x45, 0x65, 0x4a, 0xf2, + 0x5e, 0xe3, 0x24, 0x2d, 0x67, 0x16, 0x29, 0x54, 0xc4, 0x9c, 0x49, 0x32, 0x6f, 0xe9, 0x48, 0x9c, + 0xa4, 0xe5, 0xd1, 0xeb, 0x1e, 0xbf, 0x1f, 0x2a, 0x33, 0x89, 0x8e, 0xe8, 0x9b, 0x1c, 0x88, 0x25, + 0x0e, 0xed, 0xc0, 0x05, 0xcb, 0x75, 0xfd, 0x7b, 0x02, 0xd8, 0xf0, 0xfd, 0xe3, 0x8e, 0x45, 0x8f, + 0x99, 0x28, 0xa6, 0x0b, 0x8d, 0x2f, 0x28, 0x96, 0x0b, 0x1b, 0xa3, 0x24, 0x78, 0x1c, 0xdf, 0xb8, + 0x63, 0xcb, 0x4d, 0x79, 0x6c, 0x47, 0xb0, 0x3c, 0x04, 0x12, 0xb7, 0x5c, 0x55, 0xb6, 0xcf, 0x28, + 0x39, 0xcb, 0x78, 0x0c, 0xcd, 0xd9, 0x04, 0x38, 0x1e, 0x2b, 0x11, 0x5d, 0x87, 0x79, 0xee, 0xc9, + 0x7e, 0x2f, 0x08, 0xf3, 0xce, 0xbc, 0x38, 0x6e, 0x74, 0x3a, 0xa8, 0xcd, 0xdf, 0x4e, 0x60, 0xf0, + 0x10, 0x25, 0xdf, 0x5c, 0xd7, 0xe9, 0x38, 0x41, 0x75, 0x4e, 0xb0, 0x44, 0x9b, 0x7b, 0x8b, 0x03, + 0xb1, 0xc4, 0x25, 0x3c, 0xb0, 0x70, 0xae, 0x07, 0x6e, 0xc2, 0x12, 0x23, 0x9e, 0xbd, 0xed, 0x39, + 0x81, 0x63, 0xb9, 0x37, 0x4e, 0x44, 0x56, 0x59, 0x12, 0x07, 0x71, 0x91, 0xa7, 0x84, 0xfb, 0xc3, + 0x48, 0x3c, 0x4a, 0x6f, 0xfe, 0x39, 0x0b, 0x48, 0x26, 0xec, 0xb6, 0x4c, 0xca, 0x64, 0x5c, 0xe4, + 0x65, 0x85, 0x4a, 0xf8, 0x8d, 0xa1, 0xb2, 0x42, 0xe5, 0xfa, 0x21, 0x1e, 0xed, 0x40, 0x51, 0xc6, + 0xa7, 0xf8, 0xce, 0xad, 0x2b, 0xe2, 0xe2, 0x6e, 0x88, 0x38, 0x1b, 0xd4, 0x56, 0x12, 0x6a, 0x22, + 0x8c, 0x28, 0xf9, 0x62, 0x09, 0xe8, 0x2a, 0x80, 0xd5, 0x75, 0xf4, 0xa6, 0x5f, 0x31, 0x6e, 0xfd, + 0xc4, 0xe5, 0x3b, 0xd6, 0xa8, 0xd0, 0x4b, 0x90, 0x0b, 0x3e, 0x5d, 0x59, 0x56, 0x10, 0x55, 0x27, + 0x2f, 0xc2, 0x84, 0x04, 0xae, 0x5d, 0x5c, 0x0a, 0xc6, 0xcd, 0x52, 0x15, 0x55, 0xa4, 0x7d, 0x2b, + 0xc2, 0x60, 0x8d, 0x0a, 0x7d, 0x0b, 0x0a, 0x87, 0x2a, 0x9f, 0x15, 0xa7, 0x9b, 0x3a, 0xce, 0x86, + 0x59, 0xb0, 0xec, 0x3b, 0x84, 0x5f, 0x38, 0x92, 0x86, 0xbe, 0x0a, 0x25, 0xd6, 0x3b, 0x88, 0x52, + 0x00, 0xe9, 0x12, 0xd1, 0x7b, 0xbb, 0x1f, 0xa3, 0xb0, 0x4e, 0x67, 0xbe, 0x09, 0xc5, 0x1d, 0xa7, + 0x45, 0x7d, 0x51, 0x48, 0x3e, 0x01, 0x73, 0x2c, 0x51, 0x25, 0x45, 0x27, 0x19, 0xba, 0x6a, 0x88, + 0xe7, 0x3e, 0xea, 0x59, 0x9e, 0x2f, 0x6b, 0xa1, 0x7c, 0xec, 0xa3, 0xaf, 0x72, 0x20, 0x96, 0xb8, + 0xeb, 0xcb, 0x3c, 0xcb, 0xf8, 0xe9, 0xfb, 0xb5, 0x99, 0x77, 0xdf, 0xaf, 0xcd, 0xbc, 0xf7, 0xbe, + 0xca, 0x38, 0xfe, 0x00, 0x00, 0xbb, 0x07, 0xdf, 0x23, 0x2d, 0x19, 0xbb, 0x53, 0xf5, 0x06, 0xc3, + 0x96, 0xb4, 0xe8, 0x0d, 0x66, 0x86, 0x32, 0x47, 0x0d, 0x87, 0x13, 0x94, 0x68, 0x1d, 0x8a, 0x51, + 0xd7, 0x4f, 0xf9, 0xc7, 0x52, 0xe8, 0x6f, 0x51, 0x6b, 0x10, 0xc7, 0x34, 0x89, 0x87, 0x24, 0x77, + 0xee, 0x43, 0xd2, 0x80, 0x6c, 0xcf, 0xb1, 0x55, 0xd5, 0xfd, 0x74, 0xf8, 0x90, 0xdf, 0xd9, 0x6e, + 0x9e, 0x0d, 0x6a, 0x8f, 0x4c, 0x6a, 0xb6, 0x07, 0xfd, 0x2e, 0x61, 0xf5, 0x3b, 0xdb, 0x4d, 0xcc, + 0x99, 0xc7, 0x45, 0xb5, 0xd9, 0x29, 0xa3, 0xda, 0x55, 0x80, 0x76, 0xdc, 0xbb, 0x90, 0x41, 0x23, + 0x72, 0x44, 0xad, 0x67, 0xa1, 0x51, 0x21, 0x06, 0x4b, 0x2d, 0x5e, 0xdf, 0xab, 0x1e, 0x02, 0x0b, + 0xac, 0x8e, 0xec, 0x86, 0x4e, 0x77, 0x27, 0x2e, 0x29, 0x35, 0x4b, 0x9b, 0xc3, 0xc2, 0xf0, 0xa8, + 0x7c, 0xe4, 0xc3, 0x92, 0xad, 0xca, 0xcc, 0x58, 0x69, 0x71, 0x6a, 0xa5, 0x22, 0x62, 0x35, 0x87, + 0x05, 0xe1, 0x51, 0xd9, 0xe8, 0xbb, 0xb0, 0x12, 0x02, 0x47, 0x6b, 0x7d, 0x11, 0xf5, 0xb3, 0x8d, + 0xd5, 0xd3, 0x41, 0x6d, 0xa5, 0x39, 0x91, 0x0a, 0xdf, 0x47, 0x02, 0xb2, 0x61, 0xd6, 0x95, 0x59, + 0x72, 0x49, 0x64, 0x36, 0x5f, 0x4b, 0xb7, 0x8a, 0xd8, 0xfb, 0xeb, 0x7a, 0x76, 0x1c, 0xf5, 0x6d, + 0x54, 0x62, 0xac, 0x64, 0xa3, 0xb7, 0xa0, 0x64, 0x79, 0x9e, 0x1f, 0x58, 0xb2, 0xfb, 0x50, 0x16, + 0xaa, 0x36, 0xa6, 0x56, 0xb5, 0x11, 0xcb, 0x18, 0xca, 0xc6, 0x35, 0x0c, 0xd6, 0x55, 0xa1, 0x7b, + 0xb0, 0xe0, 0xdf, 0xf3, 0x08, 0xc5, 0xe4, 0x90, 0x50, 0xe2, 0xb5, 0x08, 0xab, 0x56, 0x84, 0xf6, + 0x67, 0x52, 0x6a, 0x4f, 0x30, 0xc7, 0x2e, 0x9d, 0x84, 0x33, 0x3c, 0xac, 0x05, 0xd5, 0x79, 0x6c, + 0xf5, 0x2c, 0xd7, 0xf9, 0x3e, 0xa1, 0xac, 0x3a, 0x1f, 0x37, 0xac, 0xb7, 0x22, 0x28, 0xd6, 0x28, + 0x50, 0x0f, 0x2a, 0x1d, 0xfd, 0xc9, 0xa8, 0x2e, 0x09, 0x33, 0xaf, 0xa5, 0x33, 0x73, 0xf4, 0x51, + 0x8b, 0xd3, 0xa0, 0x04, 0x0e, 0x27, 0xb5, 0xac, 0x3c, 0x07, 0xa5, 0x4f, 0x59, 0x21, 0xf0, 0x0a, + 0x63, 0xf8, 0x40, 0xa6, 0xaa, 0x30, 0xfe, 0x98, 0x81, 0xf9, 0xe4, 0x36, 0x0e, 0x3d, 0x87, 0xf9, + 0x54, 0xcf, 0x61, 0x58, 0xcb, 0x1a, 0x13, 0x27, 0x17, 0x61, 0x7c, 0xce, 0x4e, 0x8c, 0xcf, 0x2a, + 0x0c, 0xe6, 0x1e, 0x24, 0x0c, 0xd6, 0x01, 0x78, 0xb2, 0x42, 0x7d, 0xd7, 0x25, 0x54, 0x44, 0xc0, + 0x82, 0x9a, 0x50, 0x44, 0x50, 0xac, 0x51, 0xf0, 0x94, 0xfa, 0xc0, 0xf5, 0x5b, 0xc7, 0x62, 0x0b, + 0xc2, 0xdb, 0x2b, 0x62, 0x5f, 0x41, 0xa6, 0xd4, 0x8d, 0x11, 0x2c, 0x1e, 0xc3, 0x61, 0xf6, 0xe1, + 0xe2, 0x9e, 0x45, 0x79, 0x92, 0x13, 0xdf, 0x14, 0x51, 0xb3, 0xbc, 0x31, 0x52, 0x11, 0x3d, 0x3d, + 0xed, 0x8d, 0x8b, 0x37, 0x3f, 0x86, 0xc5, 0x55, 0x91, 0xf9, 0x57, 0x03, 0x2e, 0x8d, 0xd5, 0xfd, + 0x19, 0x54, 0x64, 0x6f, 0x24, 0x2b, 0xb2, 0xe7, 0x53, 0xb6, 0x32, 0xc7, 0x59, 0x3b, 0xa1, 0x3e, + 0x9b, 0x83, 0xfc, 0x1e, 0xcf, 0x84, 0xcd, 0x0f, 0x0d, 0x28, 0x8b, 0x5f, 0xd3, 0x74, 0x92, 0x6b, + 0xc9, 0x01, 0x43, 0xf1, 0xe1, 0x0d, 0x17, 0x1e, 0x46, 0xab, 0xf9, 0x1d, 0x03, 0x92, 0x3d, 0x5c, + 0xf4, 0xa2, 0xbc, 0x02, 0x46, 0xd4, 0x64, 0x9d, 0xd2, 0xfd, 0x5f, 0x98, 0x54, 0x92, 0x5e, 0x48, + 0xd5, 0xad, 0x7c, 0x12, 0x8a, 0xd8, 0xf7, 0x83, 0x3d, 0x2b, 0x38, 0x62, 0x7c, 0xef, 0xba, 0xfc, + 0x87, 0xda, 0x5e, 0xb1, 0x77, 0x02, 0x83, 0x25, 0xdc, 0xfc, 0xb9, 0x01, 0x97, 0x26, 0xce, 0x8d, + 0x78, 0x14, 0x69, 0x45, 0x5f, 0x6a, 0x45, 0x91, 0x23, 0xc7, 0x74, 0x58, 0xa3, 0xe2, 0xb5, 0x64, + 0x62, 0xd8, 0x34, 0x5c, 0x4b, 0x26, 0xb4, 0xe1, 0x24, 0xad, 0xf9, 0xcf, 0x0c, 0xa8, 0x41, 0xcd, + 0xff, 0xd8, 0xe9, 0x1f, 0x1f, 0x1a, 0x13, 0xcd, 0x27, 0xc7, 0x44, 0xd1, 0x4c, 0x48, 0x9b, 0x93, + 0x64, 0xef, 0x3f, 0x27, 0x41, 0xcf, 0x46, 0xa3, 0x17, 0xe9, 0x43, 0xab, 0xc9, 0xd1, 0xcb, 0xd9, + 0xa0, 0x56, 0x56, 0xc2, 0x93, 0xa3, 0x98, 0xd7, 0x60, 0xce, 0x26, 0x81, 0xe5, 0xb8, 0xb2, 0x2e, + 0x4c, 0x3d, 0x4c, 0x90, 0xc2, 0x9a, 0x92, 0xb5, 0x51, 0xe2, 0x36, 0xa9, 0x0f, 0x1c, 0x0a, 0xe4, + 0x01, 0xbb, 0xe5, 0xdb, 0xb2, 0x22, 0xc9, 0xc7, 0x01, 0x7b, 0xd3, 0xb7, 0x09, 0x16, 0x18, 0xf3, + 0x5d, 0x03, 0x4a, 0x52, 0xd2, 0xa6, 0xd5, 0x63, 0x04, 0x5d, 0x89, 0x56, 0x21, 0x8f, 0xfb, 0x92, + 0x3e, 0x63, 0x3b, 0x1b, 0xd4, 0x8a, 0x82, 0x4c, 0x14, 0x33, 0x63, 0x66, 0x49, 0x99, 0x73, 0xf6, + 0xe8, 0x51, 0xc8, 0x8b, 0x0b, 0xa4, 0x36, 0x33, 0x1e, 0x16, 0x72, 0x20, 0x96, 0x38, 0xf3, 0xe3, + 0x0c, 0x54, 0x12, 0x8b, 0x4b, 0x51, 0x17, 0x44, 0x2d, 0xd4, 0x4c, 0x8a, 0xb6, 0xfc, 0xe4, 0xd1, + 0xbc, 0x7a, 0xbe, 0x66, 0x1f, 0xe4, 0xf9, 0xfa, 0x36, 0xcc, 0xb6, 0xf8, 0x1e, 0x85, 0xff, 0xf4, + 0xb8, 0x32, 0xcd, 0x71, 0x8a, 0xdd, 0x8d, 0xbd, 0x51, 0x7c, 0x32, 0xac, 0x04, 0xa2, 0x9b, 0xb0, + 0x44, 0x49, 0x40, 0xfb, 0x1b, 0x87, 0x01, 0xa1, 0x7a, 0x33, 0x21, 0x1f, 0x67, 0xdf, 0x78, 0x98, + 0x00, 0x8f, 0xf2, 0x98, 0x07, 0x50, 0xbe, 0x6d, 0x1d, 0xb8, 0xd1, 0x78, 0x0c, 0x43, 0xc5, 0xf1, + 0x5a, 0x6e, 0xcf, 0x26, 0x32, 0xa0, 0x87, 0xd1, 0x2b, 0xbc, 0xb4, 0xdb, 0x3a, 0xf2, 0x6c, 0x50, + 0xbb, 0x90, 0x00, 0xc8, 0x79, 0x10, 0x4e, 0x8a, 0x30, 0x5d, 0xc8, 0x7d, 0x86, 0x95, 0xe4, 0x77, + 0xa0, 0x18, 0xe7, 0xfa, 0x0f, 0x59, 0xa5, 0xf9, 0x06, 0x14, 0xb8, 0xc7, 0x87, 0x35, 0xea, 0x39, + 0x59, 0x52, 0x32, 0xf7, 0xca, 0xa4, 0xc9, 0xbd, 0xc4, 0x90, 0xf5, 0x4e, 0xd7, 0x7e, 0xc0, 0x21, + 0x6b, 0xe6, 0x41, 0x5e, 0xbe, 0xec, 0x94, 0x2f, 0xdf, 0x55, 0x90, 0x7f, 0x44, 0xe1, 0x8f, 0x8c, + 0x4c, 0x20, 0xb4, 0x47, 0x46, 0x7f, 0xff, 0xb5, 0x09, 0xc3, 0x8f, 0x0d, 0x00, 0xd1, 0xca, 0x13, + 0x6d, 0xa4, 0x14, 0xe3, 0xfc, 0x3b, 0x30, 0xeb, 0x4b, 0x8f, 0x94, 0x83, 0xd6, 0x29, 0xfb, 0xc5, + 0xd1, 0x45, 0x92, 0x3e, 0x89, 0x95, 0xb0, 0xc6, 0xcb, 0x1f, 0x7c, 0xb2, 0x3a, 0xf3, 0xe1, 0x27, + 0xab, 0x33, 0x1f, 0x7d, 0xb2, 0x3a, 0xf3, 0xf6, 0xe9, 0xaa, 0xf1, 0xc1, 0xe9, 0xaa, 0xf1, 0xe1, + 0xe9, 0xaa, 0xf1, 0xd1, 0xe9, 0xaa, 0xf1, 0xf1, 0xe9, 0xaa, 0xf1, 0xee, 0xdf, 0x57, 0x67, 0x5e, + 0x7b, 0x2c, 0xcd, 0x1f, 0xfc, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x28, 0x27, 0x65, 0xab, 0x20, + 0x28, 0x00, 0x00, } func (m *APIGroup) Marshal() (dAtA []byte, err error) { @@ -2505,6 +2505,16 @@ func (m *ListOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SendInitialEvents != nil { + i-- + if *m.SendInitialEvents { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } i -= len(m.ResourceVersionMatch) copy(dAtA[i:], m.ResourceVersionMatch) i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceVersionMatch))) @@ -2665,11 +2675,6 @@ func (m *ObjectMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x8a } } - i -= len(m.ZZZ_DeprecatedClusterName) - copy(dAtA[i:], m.ZZZ_DeprecatedClusterName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ZZZ_DeprecatedClusterName))) - i-- - dAtA[i] = 0x7a if len(m.Finalizers) > 0 { for iNdEx := len(m.Finalizers) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Finalizers[iNdEx]) @@ -3915,6 +3920,9 @@ func (m *ListOptions) Size() (n int) { n += 2 l = len(m.ResourceVersionMatch) n += 1 + l + sovGenerated(uint64(l)) + if m.SendInitialEvents != nil { + n += 2 + } return n } @@ -4001,8 +4009,6 @@ func (m *ObjectMeta) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } - l = len(m.ZZZ_DeprecatedClusterName) - n += 1 + l + sovGenerated(uint64(l)) if len(m.ManagedFields) > 0 { for _, e := range m.ManagedFields { l = e.Size() @@ -4526,6 +4532,7 @@ func (this *ListOptions) String() string { `Continue:` + fmt.Sprintf("%v", this.Continue) + `,`, `AllowWatchBookmarks:` + fmt.Sprintf("%v", this.AllowWatchBookmarks) + `,`, `ResourceVersionMatch:` + fmt.Sprintf("%v", this.ResourceVersionMatch) + `,`, + `SendInitialEvents:` + valueToStringGenerated(this.SendInitialEvents) + `,`, `}`, }, "") return s @@ -4595,7 +4602,6 @@ func (this *ObjectMeta) String() string { `Annotations:` + mapStringForAnnotations + `,`, `OwnerReferences:` + repeatedStringForOwnerReferences + `,`, `Finalizers:` + fmt.Sprintf("%v", this.Finalizers) + `,`, - `ZZZ_DeprecatedClusterName:` + fmt.Sprintf("%v", this.ZZZ_DeprecatedClusterName) + `,`, `ManagedFields:` + repeatedStringForManagedFields + `,`, `}`, }, "") @@ -8260,6 +8266,27 @@ func (m *ListOptions) Unmarshal(dAtA []byte) error { } m.ResourceVersionMatch = ResourceVersionMatch(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SendInitialEvents", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.SendInitialEvents = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9212,38 +9239,6 @@ func (m *ObjectMeta) Unmarshal(dAtA []byte) error { } m.Finalizers = append(m.Finalizers, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 15: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ZZZ_DeprecatedClusterName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ZZZ_DeprecatedClusterName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 17: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ManagedFields", wireType) diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index b6c77351527..48955dca85b 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -162,17 +162,18 @@ message ApplyOptions { // Condition contains details for one aspect of the current state of this API Resource. // --- // This struct is intended for direct use as an array at the field path .status.conditions. For example, -// type FooStatus struct{ -// // Represents the observations of a foo's current state. -// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" -// // +patchMergeKey=type -// // +patchStrategy=merge -// // +listType=map -// // +listMapKey=type -// Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // -// // other fields -// } +// type FooStatus struct{ +// // Represents the observations of a foo's current state. +// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" +// // +patchMergeKey=type +// // +patchStrategy=merge +// // +listType=map +// // +listMapKey=type +// Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +// +// // other fields +// } message Condition { // type of condition in CamelCase or in foo.example.com/CamelCase. // --- @@ -245,19 +246,16 @@ message CreateOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -574,6 +572,32 @@ message ListOptions { // This field is not supported when watch is true. Clients may start a watch from the last // resourceVersion value returned by the server and not miss any modifications. optional string continue = 8; + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + // +optional + optional bool sendInitialEvents = 11; } // ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource @@ -644,7 +668,7 @@ message ObjectMeta { // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names // +optional optional string name = 1; @@ -670,7 +694,7 @@ message ObjectMeta { // // Must be a DNS_LABEL. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/namespaces + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces // +optional optional string namespace = 3; @@ -684,7 +708,7 @@ message ObjectMeta { // // Populated by the system. // Read-only. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional optional string uid = 5; @@ -748,14 +772,14 @@ message ObjectMeta { // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. - // More info: http://kubernetes.io/docs/user-guide/labels + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels // +optional map labels = 11; // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. - // More info: http://kubernetes.io/docs/user-guide/annotations + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations // +optional map annotations = 12; @@ -785,15 +809,6 @@ message ObjectMeta { // +patchStrategy=merge repeated string finalizers = 14; - // Deprecated: ClusterName is a legacy field that was always cleared by - // the system and never used; it will be removed completely in 1.25. - // - // The name in the go struct is changed to help clients detect - // accidental use. - // - // +optional - optional string clusterName = 15; - // ManagedFields maps workflow-id and version to the set of fields // that are managed by that workflow. This is mostly for internal // housekeeping, and users typically shouldn't need to set or @@ -819,11 +834,11 @@ message OwnerReference { optional string kind = 1; // Name of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names optional string name = 3; // UID of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids optional string uid = 4; // If true, this reference points to the managing controller. @@ -897,19 +912,16 @@ message PatchOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -1032,7 +1044,7 @@ message StatusDetails { // UID of the resource. // (when there is a single resource which can be described). - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional optional string uid = 6; @@ -1136,19 +1148,16 @@ message UpdateOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go index 2b6a30b655a..592dcb8a746 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go @@ -58,7 +58,7 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { case LabelSelectorOpDoesNotExist: op = selection.DoesNotExist default: - return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) + return nil, fmt.Errorf("%q is not a valid label selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, append([]string(nil), expr.Values...)) if err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go index 1ea90de1eda..92d3ed5e012 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go @@ -59,8 +59,6 @@ type Object interface { SetFinalizers(finalizers []string) GetOwnerReferences() []OwnerReference SetOwnerReferences([]OwnerReference) - GetZZZ_DeprecatedClusterName() string - SetZZZ_DeprecatedClusterName(clusterName string) GetManagedFields() []ManagedFieldsEntry SetManagedFields(managedFields []ManagedFieldsEntry) } @@ -172,10 +170,6 @@ func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference { return m func (meta *ObjectMeta) SetOwnerReferences(references []OwnerReference) { meta.OwnerReferences = references } -func (meta *ObjectMeta) GetZZZ_DeprecatedClusterName() string { return meta.ZZZ_DeprecatedClusterName } -func (meta *ObjectMeta) SetZZZ_DeprecatedClusterName(clusterName string) { - meta.ZZZ_DeprecatedClusterName = clusterName -} func (meta *ObjectMeta) GetManagedFields() []ManagedFieldsEntry { return meta.ManagedFields } func (meta *ObjectMeta) SetManagedFields(managedFields []ManagedFieldsEntry) { meta.ManagedFields = managedFields diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index eb071d410bc..352d58ebc24 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -17,10 +17,11 @@ limitations under the License. // Package v1 contains API types that are common to all versions. // // The package contains two categories of types: -// - external (serialized) types that lack their own version (e.g TypeMeta) -// - internal (never-serialized) types that are needed by several different -// api groups, and so live here, to avoid duplication and/or import loops -// (e.g. LabelSelector). +// - external (serialized) types that lack their own version (e.g TypeMeta) +// - internal (never-serialized) types that are needed by several different +// api groups, and so live here, to avoid duplication and/or import loops +// (e.g. LabelSelector). +// // In the future, we will probably move these categories of objects into // separate packages. package v1 @@ -113,7 +114,7 @@ type ObjectMeta struct { // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names // +optional Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` @@ -139,7 +140,7 @@ type ObjectMeta struct { // // Must be a DNS_LABEL. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/namespaces + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` @@ -153,7 +154,7 @@ type ObjectMeta struct { // // Populated by the system. // Read-only. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"` @@ -217,14 +218,14 @@ type ObjectMeta struct { // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. - // More info: http://kubernetes.io/docs/user-guide/labels + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels // +optional Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"` // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. - // More info: http://kubernetes.io/docs/user-guide/annotations + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations // +optional Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"` @@ -254,14 +255,9 @@ type ObjectMeta struct { // +patchStrategy=merge Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"` - // Deprecated: ClusterName is a legacy field that was always cleared by - // the system and never used; it will be removed completely in 1.25. - // - // The name in the go struct is changed to help clients detect - // accidental use. - // - // +optional - ZZZ_DeprecatedClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"` + // Tombstone: ClusterName was a legacy field that was always cleared by + // the system and never used. + // ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"` // ManagedFields maps workflow-id and version to the set of fields // that are managed by that workflow. This is mostly for internal @@ -299,10 +295,10 @@ type OwnerReference struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // Name of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // UID of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` // If true, this reference points to the managing controller. // +optional @@ -404,6 +400,32 @@ type ListOptions struct { // This field is not supported when watch is true. Clients may start a watch from the last // resourceVersion value returned by the server and not miss any modifications. Continue string `json:"continue,omitempty" protobuf:"bytes,8,opt,name=continue"` + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + // +optional + SendInitialEvents *bool `json:"sendInitialEvents,omitempty" protobuf:"varint,11,opt,name=sendInitialEvents"` } // resourceVersionMatch specifies how the resourceVersion parameter is applied. resourceVersionMatch @@ -546,19 +568,16 @@ type CreateOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -601,19 +620,16 @@ type PatchOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -678,19 +694,16 @@ type UpdateOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -765,7 +778,7 @@ type StatusDetails struct { Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` // UID of the resource. // (when there is a single resource which can be described). - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` // The Causes array includes more details associated with the StatusReason @@ -1453,17 +1466,18 @@ type PartialObjectMetadataList struct { // Condition contains details for one aspect of the current state of this API Resource. // --- // This struct is intended for direct use as an array at the field path .status.conditions. For example, -// type FooStatus struct{ -// // Represents the observations of a foo's current state. -// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" -// // +patchMergeKey=type -// // +patchStrategy=merge -// // +listType=map -// // +listMapKey=type -// Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // -// // other fields -// } +// type FooStatus struct{ +// // Represents the observations of a foo's current state. +// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" +// // +patchMergeKey=type +// // +patchStrategy=merge +// // +listType=map +// // +listMapKey=type +// Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +// +// // other fields +// } type Condition struct { // type of condition in CamelCase or in foo.example.com/CamelCase. // --- diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go index d002b03c8b2..b736e837126 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_APIGroup = map[string]string{ @@ -115,7 +115,7 @@ var map_CreateOptions = map[string]string{ "": "CreateOptions may be provided when creating an API object.", "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (CreateOptions) SwaggerDoc() map[string]string { @@ -216,6 +216,7 @@ var map_ListOptions = map[string]string{ "timeoutSeconds": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", "limit": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", "continue": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "sendInitialEvents": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", } func (ListOptions) SwaggerDoc() map[string]string { @@ -239,21 +240,20 @@ func (ManagedFieldsEntry) SwaggerDoc() map[string]string { var map_ObjectMeta = map[string]string{ "": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", - "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", "generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", - "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces", "selfLink": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", - "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", "generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", "creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", - "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", - "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels", + "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations", "ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", "finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", - "clusterName": "Deprecated: ClusterName is a legacy field that was always cleared by the system and never used; it will be removed completely in 1.25.\n\nThe name in the go struct is changed to help clients detect accidental use.", "managedFields": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", } @@ -265,8 +265,8 @@ var map_OwnerReference = map[string]string{ "": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "apiVersion": "API version of the referent.", "kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "uid": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "name": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", + "uid": "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "controller": "If true, this reference points to the managing controller.", "blockOwnerDeletion": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", } @@ -307,7 +307,7 @@ var map_PatchOptions = map[string]string{ "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "force": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (PatchOptions) SwaggerDoc() map[string]string { @@ -373,7 +373,7 @@ var map_StatusDetails = map[string]string{ "name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", "group": "The group attribute of the resource associated with the status StatusReason.", "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "uid": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "uid": "UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", } @@ -452,7 +452,7 @@ var map_UpdateOptions = map[string]string{ "": "UpdateOptions may be provided when updating an API object. All fields in UpdateOptions should also be present in PatchOptions.", "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (UpdateOptions) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go index f0fad90fd47..a499eee8ebb 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go @@ -444,18 +444,6 @@ func (u *Unstructured) SetFinalizers(finalizers []string) { u.setNestedStringSlice(finalizers, "metadata", "finalizers") } -func (u *Unstructured) GetZZZ_DeprecatedClusterName() string { - return getNestedString(u.Object, "metadata", "clusterName") -} - -func (u *Unstructured) SetZZZ_DeprecatedClusterName(clusterName string) { - if len(clusterName) == 0 { - RemoveNestedField(u.Object, "metadata", "clusterName") - return - } - u.setNestedField(clusterName, "metadata", "clusterName") -} - func (u *Unstructured) GetManagedFields() []metav1.ManagedFieldsEntry { items, found, err := NestedSlice(u.Object, "metadata", "managedFields") if !found || err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go index 4c09898b8b9..a0f709ad862 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go @@ -28,19 +28,46 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -func ValidateLabelSelector(ps *metav1.LabelSelector, fldPath *field.Path) field.ErrorList { +// LabelSelectorValidationOptions is a struct that can be passed to ValidateLabelSelector to record the validate options +type LabelSelectorValidationOptions struct { + // Allow invalid label value in selector + AllowInvalidLabelValueInSelector bool +} + +// LabelSelectorHasInvalidLabelValue returns true if the given selector contains an invalid label value in a match expression. +// This is useful for determining whether AllowInvalidLabelValueInSelector should be set to true when validating an update +// based on existing persisted invalid values. +func LabelSelectorHasInvalidLabelValue(ps *metav1.LabelSelector) bool { + if ps == nil { + return false + } + for _, e := range ps.MatchExpressions { + for _, v := range e.Values { + if len(validation.IsValidLabelValue(v)) > 0 { + return true + } + } + } + return false +} + +// ValidateLabelSelector validate the LabelSelector according to the opts and returns any validation errors. +// opts.AllowInvalidLabelValueInSelector is only expected to be set to true when required for backwards compatibility with existing invalid data. +func ValidateLabelSelector(ps *metav1.LabelSelector, opts LabelSelectorValidationOptions, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if ps == nil { return allErrs } allErrs = append(allErrs, ValidateLabels(ps.MatchLabels, fldPath.Child("matchLabels"))...) for i, expr := range ps.MatchExpressions { - allErrs = append(allErrs, ValidateLabelSelectorRequirement(expr, fldPath.Child("matchExpressions").Index(i))...) + allErrs = append(allErrs, ValidateLabelSelectorRequirement(expr, opts, fldPath.Child("matchExpressions").Index(i))...) } return allErrs } -func ValidateLabelSelectorRequirement(sr metav1.LabelSelectorRequirement, fldPath *field.Path) field.ErrorList { +// ValidateLabelSelectorRequirement validate the requirement according to the opts and returns any validation errors. +// opts.AllowInvalidLabelValueInSelector is only expected to be set to true when required for backwards compatibility with existing invalid data. +func ValidateLabelSelectorRequirement(sr metav1.LabelSelectorRequirement, opts LabelSelectorValidationOptions, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} switch sr.Operator { case metav1.LabelSelectorOpIn, metav1.LabelSelectorOpNotIn: @@ -55,6 +82,13 @@ func ValidateLabelSelectorRequirement(sr metav1.LabelSelectorRequirement, fldPat allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), sr.Operator, "not a valid selector operator")) } allErrs = append(allErrs, ValidateLabelName(sr.Key, fldPath.Child("key"))...) + if !opts.AllowInvalidLabelValueInSelector { + for valueIndex, value := range sr.Values { + for _, msg := range validation.IsValidLabelValue(value) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("values").Index(valueIndex), value, msg)) + } + } + } return allErrs } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go index b7590f0b313..afe01ed5a44 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go @@ -426,6 +426,13 @@ func autoConvert_url_Values_To_v1_ListOptions(in *url.Values, out *ListOptions, } else { out.Continue = "" } + if values, ok := map[string][]string(*in)["sendInitialEvents"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_Pointer_bool(&values, &out.SendInitialEvents, s); err != nil { + return err + } + } else { + out.SendInitialEvents = nil + } return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go index 418e6099f40..7d29c504ab9 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go @@ -602,6 +602,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) { *out = new(int64) **out = **in } + if in.SendInitialEvents != nil { + in, out := &in.SendInitialEvents, &out.SendInitialEvents + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go index ef7e7c1e901..dff735dcf35 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PartialObjectMetadataList = map[string]string{ diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/converter.go b/vendor/k8s.io/apimachinery/pkg/conversion/converter.go index d9b5772278f..76b76247c7f 100644 --- a/vendor/k8s.io/apimachinery/pkg/conversion/converter.go +++ b/vendor/k8s.io/apimachinery/pkg/conversion/converter.go @@ -115,10 +115,10 @@ type ConversionFuncs struct { // previously defined functions. func (c ConversionFuncs) AddUntyped(a, b interface{}, fn ConversionFunc) error { tA, tB := reflect.TypeOf(a), reflect.TypeOf(b) - if tA.Kind() != reflect.Ptr { + if tA.Kind() != reflect.Pointer { return fmt.Errorf("the type %T must be a pointer to register as an untyped conversion", a) } - if tB.Kind() != reflect.Ptr { + if tB.Kind() != reflect.Pointer { return fmt.Errorf("the type %T must be a pointer to register as an untyped conversion", b) } c.untyped[typePair{tA, tB}] = fn @@ -179,10 +179,10 @@ func (c *Converter) RegisterGeneratedUntypedConversionFunc(a, b interface{}, fn func (c *Converter) RegisterIgnoredConversion(from, to interface{}) error { typeFrom := reflect.TypeOf(from) typeTo := reflect.TypeOf(to) - if typeFrom.Kind() != reflect.Ptr { + if typeFrom.Kind() != reflect.Pointer { return fmt.Errorf("expected pointer arg for 'from' param 0, got: %v", typeFrom) } - if typeTo.Kind() != reflect.Ptr { + if typeTo.Kind() != reflect.Pointer { return fmt.Errorf("expected pointer arg for 'to' param 1, got: %v", typeTo) } c.ignoredUntypedConversions[typePair{typeFrom, typeTo}] = struct{}{} diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/deep_equal.go b/vendor/k8s.io/apimachinery/pkg/conversion/deep_equal.go index f21abe1e53a..25b2923f223 100644 --- a/vendor/k8s.io/apimachinery/pkg/conversion/deep_equal.go +++ b/vendor/k8s.io/apimachinery/pkg/conversion/deep_equal.go @@ -34,3 +34,14 @@ func EqualitiesOrDie(funcs ...interface{}) Equalities { } return e } + +// Performs a shallow copy of the equalities map +func (e Equalities) Copy() Equalities { + result := Equalities{reflect.Equalities{}} + + for key, value := range e.Equalities { + result.Equalities[key] = value + } + + return result +} diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/helper.go b/vendor/k8s.io/apimachinery/pkg/conversion/helper.go index 4ebc1ebc511..7fadd27a46c 100644 --- a/vendor/k8s.io/apimachinery/pkg/conversion/helper.go +++ b/vendor/k8s.io/apimachinery/pkg/conversion/helper.go @@ -26,7 +26,7 @@ import ( // Returns an error if this is not possible. func EnforcePtr(obj interface{}) (reflect.Value, error) { v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { + if v.Kind() != reflect.Pointer { if v.Kind() == reflect.Invalid { return reflect.Value{}, fmt.Errorf("expected pointer, but got invalid kind") } diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go index 2f0dd0074af..b0a9246d973 100644 --- a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go +++ b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go @@ -55,7 +55,7 @@ func jsonTag(field reflect.StructField) (string, bool) { } func isPointerKind(kind reflect.Kind) bool { - return kind == reflect.Ptr + return kind == reflect.Pointer } func isStructKind(kind reflect.Kind) bool { @@ -139,7 +139,7 @@ func Convert(obj interface{}) (url.Values, error) { } var sv reflect.Value switch reflect.TypeOf(obj).Kind() { - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: sv = reflect.ValueOf(obj).Elem() default: return nil, fmt.Errorf("expecting a pointer or interface") diff --git a/vendor/k8s.io/apimachinery/pkg/labels/labels.go b/vendor/k8s.io/apimachinery/pkg/labels/labels.go index 8360d842b6c..19d823cef7b 100644 --- a/vendor/k8s.io/apimachinery/pkg/labels/labels.go +++ b/vendor/k8s.io/apimachinery/pkg/labels/labels.go @@ -77,6 +77,8 @@ func (ls Set) AsValidatedSelector() (Selector, error) { // perform any validation. // According to our measurements this is significantly faster // in codepaths that matter at high scale. +// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector +// instead, which does not copy. func (ls Set) AsSelectorPreValidated() Selector { return SelectorFromValidatedSet(ls) } diff --git a/vendor/k8s.io/apimachinery/pkg/labels/selector.go b/vendor/k8s.io/apimachinery/pkg/labels/selector.go index 2434429b9f8..5e601424051 100644 --- a/vendor/k8s.io/apimachinery/pkg/labels/selector.go +++ b/vendor/k8s.io/apimachinery/pkg/labels/selector.go @@ -74,9 +74,12 @@ type Selector interface { RequiresExactMatch(label string) (value string, found bool) } +// Sharing this saves 1 alloc per use; this is safe because it's immutable. +var sharedEverythingSelector Selector = internalSelector{} + // Everything returns a selector that matches all labels. func Everything() Selector { - return internalSelector{} + return sharedEverythingSelector } type nothingSelector struct{} @@ -91,9 +94,12 @@ func (n nothingSelector) RequiresExactMatch(label string) (value string, found b return "", false } +// Sharing this saves 1 alloc per use; this is safe because it's immutable. +var sharedNothingSelector Selector = nothingSelector{} + // Nothing returns a selector that matches no labels func Nothing() Selector { - return nothingSelector{} + return sharedNothingSelector } // NewSelector returns a nil selector @@ -143,13 +149,12 @@ type Requirement struct { // NewRequirement is the constructor for a Requirement. // If any of these rules is violated, an error is returned: -// (1) The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist. -// (2) If the operator is In or NotIn, the values set must be non-empty. -// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value. -// (4) If the operator is Exists or DoesNotExist, the value set must be empty. -// (5) If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer. -// (6) The key is invalid due to its length, or sequence -// of characters. See validateLabelKey for more details. +// 1. The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist. +// 2. If the operator is In or NotIn, the values set must be non-empty. +// 3. If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value. +// 4. If the operator is Exists or DoesNotExist, the value set must be empty. +// 5. If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer. +// 6. The key is invalid due to its length, or sequence of characters. See validateLabelKey for more details. // // The empty string is a valid value in the input values set. // Returned error, if not nil, is guaranteed to be an aggregated field.ErrorList @@ -206,14 +211,14 @@ func (r *Requirement) hasValue(value string) bool { // Matches returns true if the Requirement matches the input Labels. // There is a match in the following cases: -// (1) The operator is Exists and Labels has the Requirement's key. -// (2) The operator is In, Labels has the Requirement's key and Labels' +// 1. The operator is Exists and Labels has the Requirement's key. +// 2. The operator is In, Labels has the Requirement's key and Labels' // value for that key is in Requirement's value set. -// (3) The operator is NotIn, Labels has the Requirement's key and +// 3. The operator is NotIn, Labels has the Requirement's key and // Labels' value for that key is not in Requirement's value set. -// (4) The operator is DoesNotExist or NotIn and Labels does not have the +// 4. The operator is DoesNotExist or NotIn and Labels does not have the // Requirement's key. -// (5) The operator is GreaterThanOperator or LessThanOperator, and Labels has +// 5. The operator is GreaterThanOperator or LessThanOperator, and Labels has // the Requirement's key and the corresponding value satisfies mathematical inequality. func (r *Requirement) Matches(ls Labels) bool { switch r.operator { @@ -840,32 +845,32 @@ func (p *Parser) parseExactValue() (sets.String, error) { // as they parse different selectors with different syntaxes. // The input will cause an error if it does not follow this form: // -// ::= | "," -// ::= [!] KEY [ | ] -// ::= "" | -// ::= | -// ::= "notin" -// ::= "in" -// ::= "(" ")" -// ::= VALUE | VALUE "," -// ::= ["="|"=="|"!="] VALUE +// ::= | "," +// ::= [!] KEY [ | ] +// ::= "" | +// ::= | +// ::= "notin" +// ::= "in" +// ::= "(" ")" +// ::= VALUE | VALUE "," +// ::= ["="|"=="|"!="] VALUE // // KEY is a sequence of one or more characters following [ DNS_SUBDOMAIN "/" ] DNS_LABEL. Max length is 63 characters. // VALUE is a sequence of zero or more characters "([A-Za-z0-9_-\.])". Max length is 63 characters. // Delimiter is white space: (' ', '\t') // Example of valid syntax: -// "x in (foo,,baz),y,z notin ()" // -// Note: -// (1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the -// VALUEs in its requirement -// (2) Exclusion - " notin " - denotes that the KEY is not equal to any -// of the VALUEs in its requirement or does not exist -// (3) The empty string is a valid VALUE -// (4) A requirement with just a KEY - as in "y" above - denotes that -// the KEY exists and can be any VALUE. -// (5) A requirement with just !KEY requires that the KEY not exist. +// "x in (foo,,baz),y,z notin ()" // +// Note: +// 1. Inclusion - " in " - denotes that the KEY exists and is equal to any of the +// VALUEs in its requirement +// 2. Exclusion - " notin " - denotes that the KEY is not equal to any +// of the VALUEs in its requirement or does not exist +// 3. The empty string is a valid VALUE +// 4. A requirement with just a KEY - as in "y" above - denotes that +// the KEY exists and can be any VALUE. +// 5. A requirement with just !KEY requires that the KEY not exist. func Parse(selector string, opts ...field.PathOption) (Selector, error) { parsedSelector, err := parse(selector, field.ToPath(opts...)) if err == nil { @@ -933,6 +938,8 @@ func ValidatedSelectorFromSet(ls Set) (Selector, error) { // SelectorFromValidatedSet returns a Selector which will match exactly the given Set. // A nil and empty Sets are considered equivalent to Everything(). // It assumes that Set is already validated and doesn't do any validation. +// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector +// instead, which does not copy. func SelectorFromValidatedSet(ls Set) Selector { if ls == nil || len(ls) == 0 { return internalSelector{} @@ -954,3 +961,76 @@ func SelectorFromValidatedSet(ls Set) Selector { func ParseToRequirements(selector string, opts ...field.PathOption) ([]Requirement, error) { return parse(selector, field.ToPath(opts...)) } + +// ValidatedSetSelector wraps a Set, allowing it to implement the Selector interface. Unlike +// Set.AsSelectorPreValidated (which copies the input Set), this type simply wraps the underlying +// Set. As a result, it is substantially more efficient. A nil and empty Sets are considered +// equivalent to Everything(). +// +// Callers MUST ensure the underlying Set is not mutated, and that it is already validated. If these +// constraints are not met, Set.AsValidatedSelector should be preferred +// +// None of the Selector methods mutate the underlying Set, but Add() and Requirements() convert to +// the less optimized version. +type ValidatedSetSelector Set + +func (s ValidatedSetSelector) Matches(labels Labels) bool { + for k, v := range s { + if !labels.Has(k) || v != labels.Get(k) { + return false + } + } + return true +} + +func (s ValidatedSetSelector) Empty() bool { + return len(s) == 0 +} + +func (s ValidatedSetSelector) String() string { + keys := make([]string, 0, len(s)) + for k := range s { + keys = append(keys, k) + } + // Ensure deterministic output + sort.Strings(keys) + b := strings.Builder{} + for i, key := range keys { + v := s[key] + b.Grow(len(key) + 2 + len(v)) + if i != 0 { + b.WriteString(",") + } + b.WriteString(key) + b.WriteString("=") + b.WriteString(v) + } + return b.String() +} + +func (s ValidatedSetSelector) Add(r ...Requirement) Selector { + return s.toFullSelector().Add(r...) +} + +func (s ValidatedSetSelector) Requirements() (requirements Requirements, selectable bool) { + return s.toFullSelector().Requirements() +} + +func (s ValidatedSetSelector) DeepCopySelector() Selector { + res := make(ValidatedSetSelector, len(s)) + for k, v := range s { + res[k] = v + } + return res +} + +func (s ValidatedSetSelector) RequiresExactMatch(label string) (value string, found bool) { + v, f := s[label] + return v, f +} + +func (s ValidatedSetSelector) toFullSelector() Selector { + return SelectorFromValidatedSet(Set(s)) +} + +var _ Selector = ValidatedSetSelector{} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/allocator.go b/vendor/k8s.io/apimachinery/pkg/runtime/allocator.go index 0d00d8c3a3b..8bf22ae8acd 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/allocator.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/allocator.go @@ -24,12 +24,14 @@ import ( // by caching created but unused items for later reuse, relieving pressure on the garbage collector. // // Usage: -// memoryAllocator := runtime.AllocatorPool.Get().(*runtime.Allocator) -// defer runtime.AllocatorPool.Put(memoryAllocator) +// +// memoryAllocator := runtime.AllocatorPool.Get().(*runtime.Allocator) +// defer runtime.AllocatorPool.Put(memoryAllocator) // // A note for future: -// consider introducing multiple pools for storing buffers of different sizes -// perhaps this could allow us to be more efficient. +// +// consider introducing multiple pools for storing buffers of different sizes +// perhaps this could allow us to be more efficient. var AllocatorPool = sync.Pool{ New: func() interface{} { return &Allocator{} @@ -58,7 +60,7 @@ func (a *Allocator) Allocate(n uint64) []byte { } // grow the buffer size := uint64(2*cap(a.buf)) + n - a.buf = make([]byte, size, size) + a.buf = make([]byte, size) a.buf = a.buf[:n] return a.buf } @@ -70,5 +72,5 @@ type SimpleAllocator struct{} var _ MemoryAllocator = &SimpleAllocator{} func (sa *SimpleAllocator) Allocate(n uint64) []byte { - return make([]byte, n, n) + return make([]byte, n) } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go index a92863139ed..7fc513dd0e7 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go @@ -344,14 +344,15 @@ func NewMultiGroupVersioner(gv schema.GroupVersion, groupKinds ...schema.GroupKi // Incoming kinds that match the provided groupKinds are preferred. // Kind may be empty in the provided group kind, in which case any kind will match. // Examples: -// gv=mygroup/__internal, groupKinds=mygroup/Foo, anothergroup/Bar -// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group/kind) // -// gv=mygroup/__internal, groupKinds=mygroup, anothergroup -// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group) +// gv=mygroup/__internal, groupKinds=mygroup/Foo, anothergroup/Bar +// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group/kind) // -// gv=mygroup/__internal, groupKinds=mygroup, anothergroup -// KindForGroupVersionKinds(yetanother/v1/Baz, yetanother/v1/Bar) -> mygroup/__internal/Baz (no preferred group/kind match, uses first kind in list) +// gv=mygroup/__internal, groupKinds=mygroup, anothergroup +// KindForGroupVersionKinds(yetanother/v1/Baz, anothergroup/v1/Bar) -> mygroup/__internal/Bar (matched preferred group) +// +// gv=mygroup/__internal, groupKinds=mygroup, anothergroup +// KindForGroupVersionKinds(yetanother/v1/Baz, yetanother/v1/Bar) -> mygroup/__internal/Baz (no preferred group/kind match, uses first kind in list) func NewCoercingMultiGroupVersioner(gv schema.GroupVersion, groupKinds ...schema.GroupKind) GroupVersioner { return multiGroupVersioner{target: gv, acceptedGroupKinds: groupKinds, coerce: true} } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go b/vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go index 00022806171..e884007766b 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go @@ -30,7 +30,7 @@ import ( // TODO: verify that the correct external version is chosen on encode... func CheckCodec(c Codec, internalType Object, externalTypes ...schema.GroupVersionKind) error { if _, err := Encode(c, internalType); err != nil { - return fmt.Errorf("Internal type not encodable: %v", err) + return fmt.Errorf("internal type not encodable: %v", err) } for _, et := range externalTypes { typeMeta := TypeMeta{ diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go index b640a9e768f..62eb27afc19 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go @@ -231,13 +231,13 @@ func (c *fromUnstructuredContext) pushKey(key string) { } -// FromUnstructuredWIthValidation converts an object from map[string]interface{} representation into a concrete type. +// FromUnstructuredWithValidation converts an object from map[string]interface{} representation into a concrete type. // It uses encoding/json/Unmarshaler if object implements it or reflection if not. // It takes a validationDirective that indicates how to behave when it encounters unknown fields. func (c *unstructuredConverter) FromUnstructuredWithValidation(u map[string]interface{}, obj interface{}, returnUnknownFields bool) error { t := reflect.TypeOf(obj) value := reflect.ValueOf(obj) - if t.Kind() != reflect.Ptr || value.IsNil() { + if t.Kind() != reflect.Pointer || value.IsNil() { return fmt.Errorf("FromUnstructured requires a non-nil pointer to an object, got %v", t) } @@ -291,7 +291,7 @@ func fromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error st, dt := sv.Type(), dv.Type() switch dt.Kind() { - case reflect.Map, reflect.Slice, reflect.Ptr, reflect.Struct, reflect.Interface: + case reflect.Map, reflect.Slice, reflect.Pointer, reflect.Struct, reflect.Interface: // Those require non-trivial conversion. default: // This should handle all simple types. @@ -353,7 +353,7 @@ func fromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error return mapFromUnstructured(sv, dv, ctx) case reflect.Slice: return sliceFromUnstructured(sv, dv, ctx) - case reflect.Ptr: + case reflect.Pointer: return pointerFromUnstructured(sv, dv, ctx) case reflect.Struct: return structFromUnstructured(sv, dv, ctx) @@ -465,7 +465,7 @@ func sliceFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) e } dv.SetBytes(data) } else { - dv.Set(reflect.Zero(dt)) + dv.Set(reflect.MakeSlice(dt, 0, 0)) } return nil } @@ -496,13 +496,13 @@ func sliceFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) e func pointerFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error { st, dt := sv.Type(), dv.Type() - if st.Kind() == reflect.Ptr && sv.IsNil() { + if st.Kind() == reflect.Pointer && sv.IsNil() { dv.Set(reflect.Zero(dt)) return nil } dv.Set(reflect.New(dt.Elem())) switch st.Kind() { - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: return fromUnstructured(sv.Elem(), dv.Elem(), ctx) default: return fromUnstructured(sv, dv.Elem(), ctx) @@ -579,7 +579,7 @@ func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]inte } else { t := reflect.TypeOf(obj) value := reflect.ValueOf(obj) - if t.Kind() != reflect.Ptr || value.IsNil() { + if t.Kind() != reflect.Pointer || value.IsNil() { return nil, fmt.Errorf("ToUnstructured requires a non-nil pointer to an object, got %v", t) } u = map[string]interface{}{} @@ -686,7 +686,7 @@ func toUnstructured(sv, dv reflect.Value) error { return mapToUnstructured(sv, dv) case reflect.Slice: return sliceToUnstructured(sv, dv) - case reflect.Ptr: + case reflect.Pointer: return pointerToUnstructured(sv, dv) case reflect.Struct: return structToUnstructured(sv, dv) @@ -790,7 +790,7 @@ func isZero(v reflect.Value) bool { case reflect.Map, reflect.Slice: // TODO: It seems that 0-len maps are ignored in it. return v.IsNil() || v.Len() == 0 - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: return v.IsNil() } return false diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto b/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto index de634e2c64e..5f06cc5743d 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto @@ -31,32 +31,37 @@ option go_package = "k8s.io/apimachinery/pkg/runtime"; // various plugin types. // // // Internal package: -// type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// MyPlugin runtime.Object `json:"myPlugin"` -// } -// type PluginA struct { -// AOption string `json:"aOption"` -// } +// +// type MyAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// MyPlugin runtime.Object `json:"myPlugin"` +// } +// +// type PluginA struct { +// AOption string `json:"aOption"` +// } // // // External package: -// type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// MyPlugin runtime.RawExtension `json:"myPlugin"` -// } -// type PluginA struct { -// AOption string `json:"aOption"` -// } +// +// type MyAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// MyPlugin runtime.RawExtension `json:"myPlugin"` +// } +// +// type PluginA struct { +// AOption string `json:"aOption"` +// } // // // On the wire, the JSON will look something like this: -// { -// "kind":"MyAPIObject", -// "apiVersion":"v1", -// "myPlugin": { -// "kind":"PluginA", -// "aOption":"foo", -// }, -// } +// +// { +// "kind":"MyAPIObject", +// "apiVersion":"v1", +// "myPlugin": { +// "kind":"PluginA", +// "aOption":"foo", +// }, +// } // // So what happens? Decode first uses json or yaml to unmarshal the serialized data into // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. @@ -78,10 +83,12 @@ message RawExtension { // TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, // like this: -// type MyAwesomeAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// ... // other fields -// } +// +// type MyAwesomeAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// ... // other fields +// } +// // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind // // TypeMeta is provided here for convenience. You may use it directly from this package or define diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go index 994a3e3fa81..54ccb7a74c7 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go @@ -191,7 +191,7 @@ func (gv GroupVersion) Identifier() string { // if none of the options match the group. It prefers a match to group and version over just group. // TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme. // TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) -// in fewer places. +// in fewer places. func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) { for _, gvk := range kinds { if gvk.Group == gv.Group && gvk.Version == gv.Version { @@ -239,7 +239,7 @@ func (gv GroupVersion) WithResource(resource string) GroupVersionResource { // GroupVersions can be used to represent a set of desired group versions. // TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme. // TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) -// in fewer places. +// in fewer places. type GroupVersions []GroupVersion // Identifier implements runtime.GroupVersioner interface. diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go index a9d656f8ea4..a5b116718d5 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go @@ -118,7 +118,7 @@ func (s *Scheme) Converter() *conversion.Converter { // API group and version that would never be updated. // // TODO: there is discussion about removing unversioned and replacing it with objects that are manifest into -// every version with particular schemas. Resolve this method at that point. +// every version with particular schemas. Resolve this method at that point. func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Object) { s.addObservedVersion(version) s.AddKnownTypes(version, types...) @@ -141,7 +141,7 @@ func (s *Scheme) AddKnownTypes(gv schema.GroupVersion, types ...Object) { s.addObservedVersion(gv) for _, obj := range types { t := reflect.TypeOf(obj) - if t.Kind() != reflect.Ptr { + if t.Kind() != reflect.Pointer { panic("All types must be pointers to structs.") } t = t.Elem() @@ -159,7 +159,7 @@ func (s *Scheme) AddKnownTypeWithName(gvk schema.GroupVersionKind, obj Object) { if len(gvk.Version) == 0 { panic(fmt.Sprintf("version is required on all types: %s %v", gvk, t)) } - if t.Kind() != reflect.Ptr { + if t.Kind() != reflect.Pointer { panic("All types must be pointers to structs.") } t = t.Elem() @@ -462,7 +462,7 @@ func (s *Scheme) convertToVersion(copy bool, in Object, target GroupVersioner) ( } else { // determine the incoming kinds with as few allocations as possible. t = reflect.TypeOf(in) - if t.Kind() != reflect.Ptr { + if t.Kind() != reflect.Pointer { return nil, fmt.Errorf("only pointer types may be converted: %v", t) } t = t.Elem() diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go index 9de35e791c0..ff982084204 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go @@ -259,7 +259,7 @@ func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo { // invoke CodecForVersions. Callers that need only to read data should use UniversalDecoder(). // // TODO: make this call exist only in pkg/api, and initialize it with the set of default versions. -// All other callers will be forced to request a Codec directly. +// All other callers will be forced to request a Codec directly. func (f CodecFactory) LegacyCodec(version ...schema.GroupVersion) runtime.Codec { return versioning.NewDefaultingCodecForScheme(f.scheme, f.legacySerializer, f.universal, schema.GroupVersions(version), runtime.InternalGroupVersioner) } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index 4466331829e..25f955ed758 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -147,7 +147,7 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru } if d, ok := obj.(runtime.NestedObjectDecoder); ok { - if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil { + if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{Decoder: c.decoder}); err != nil { if strictErr, ok := runtime.AsStrictDecodingError(err); ok { // save the strictDecodingError let and the caller decide what to do with it strictDecodingErrs = append(strictDecodingErrs, strictErr.Errors()...) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/types.go b/vendor/k8s.io/apimachinery/pkg/runtime/types.go index 31359f35f45..ce77c7910a9 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/types.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/types.go @@ -21,10 +21,12 @@ package runtime // TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, // like this: -// type MyAwesomeAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// ... // other fields -// } +// +// type MyAwesomeAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// ... // other fields +// } +// // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind // // TypeMeta is provided here for convenience. You may use it directly from this package or define @@ -53,32 +55,37 @@ const ( // various plugin types. // // // Internal package: -// type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// MyPlugin runtime.Object `json:"myPlugin"` -// } -// type PluginA struct { -// AOption string `json:"aOption"` -// } +// +// type MyAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// MyPlugin runtime.Object `json:"myPlugin"` +// } +// +// type PluginA struct { +// AOption string `json:"aOption"` +// } // // // External package: -// type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` -// MyPlugin runtime.RawExtension `json:"myPlugin"` -// } -// type PluginA struct { -// AOption string `json:"aOption"` -// } +// +// type MyAPIObject struct { +// runtime.TypeMeta `json:",inline"` +// MyPlugin runtime.RawExtension `json:"myPlugin"` +// } +// +// type PluginA struct { +// AOption string `json:"aOption"` +// } // // // On the wire, the JSON will look something like this: -// { -// "kind":"MyAPIObject", -// "apiVersion":"v1", -// "myPlugin": { -// "kind":"PluginA", -// "aOption":"foo", -// }, -// } +// +// { +// "kind":"MyAPIObject", +// "apiVersion":"v1", +// "myPlugin": { +// "kind":"PluginA", +// "aOption":"foo", +// }, +// } // // So what happens? Decode first uses json or yaml to unmarshal the serialized data into // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. @@ -116,7 +123,7 @@ type Unknown struct { // Raw will hold the complete serialized object which couldn't be matched // with a registered type. Most likely, nothing should be done with this // except for passing it through the system. - Raw []byte `protobuf:"bytes,2,opt,name=raw"` + Raw []byte `json:"-" protobuf:"bytes,2,opt,name=raw"` // ContentEncoding is encoding used to encode 'Raw' data. // Unspecified means no encoding. ContentEncoding string `protobuf:"bytes,3,opt,name=contentEncoding"` diff --git a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go index b19750f3a0b..db18ce1ce21 100644 --- a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go +++ b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go @@ -37,3 +37,14 @@ const ( func (n NamespacedName) String() string { return n.Namespace + string(Separator) + n.Name } + +// MarshalLog emits a struct containing required key/value pair +func (n NamespacedName) MarshalLog() interface{} { + return struct { + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + }{ + Name: n.Name, + Namespace: n.Namespace, + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/types/nodename.go b/vendor/k8s.io/apimachinery/pkg/types/nodename.go index fee348d7e76..cff9ca67176 100644 --- a/vendor/k8s.io/apimachinery/pkg/types/nodename.go +++ b/vendor/k8s.io/apimachinery/pkg/types/nodename.go @@ -23,21 +23,21 @@ package types // // To clarify the various types: // -// * Node.Name is the Name field of the Node in the API. This should be stored in a NodeName. -// Unfortunately, because Name is part of ObjectMeta, we can't store it as a NodeName at the API level. +// - Node.Name is the Name field of the Node in the API. This should be stored in a NodeName. +// Unfortunately, because Name is part of ObjectMeta, we can't store it as a NodeName at the API level. // -// * Hostname is the hostname of the local machine (from uname -n). -// However, some components allow the user to pass in a --hostname-override flag, -// which will override this in most places. In the absence of anything more meaningful, -// kubelet will use Hostname as the Node.Name when it creates the Node. +// - Hostname is the hostname of the local machine (from uname -n). +// However, some components allow the user to pass in a --hostname-override flag, +// which will override this in most places. In the absence of anything more meaningful, +// kubelet will use Hostname as the Node.Name when it creates the Node. // // * The cloudproviders have the own names: GCE has InstanceName, AWS has InstanceId. // -// For GCE, InstanceName is the Name of an Instance object in the GCE API. On GCE, Instance.Name becomes the -// Hostname, and thus it makes sense also to use it as the Node.Name. But that is GCE specific, and it is up -// to the cloudprovider how to do this mapping. +// For GCE, InstanceName is the Name of an Instance object in the GCE API. On GCE, Instance.Name becomes the +// Hostname, and thus it makes sense also to use it as the Node.Name. But that is GCE specific, and it is up +// to the cloudprovider how to do this mapping. // -// For AWS, the InstanceID is not yet suitable for use as a Node.Name, so we actually use the -// PrivateDnsName for the Node.Name. And this is _not_ always the same as the hostname: if -// we are using a custom DHCP domain it won't be. +// For AWS, the InstanceID is not yet suitable for use as a Node.Name, so we actually use the +// PrivateDnsName for the Node.Name. And this is _not_ always the same as the hostname: if +// we are using a custom DHCP domain it won't be. type NodeName string diff --git a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go index fa9ffa51b74..ec4002e38a2 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go +++ b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go @@ -135,7 +135,7 @@ func IgnoreUnset() cmp.Option { if v2.Len() == 0 { return true } - case reflect.Interface, reflect.Ptr: + case reflect.Interface, reflect.Pointer: if v2.IsNil() { return true } diff --git a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go index 1f5a04fd41c..1b60d145c68 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go @@ -214,7 +214,7 @@ func CreateAggregateFromMessageCountMap(m MessageCountMap) Aggregate { return NewAggregate(result) } -// Reduce will return err or, if err is an Aggregate and only has one item, +// Reduce will return err or nil, if err is an Aggregate and only has one item, // the first item in the aggregate. func Reduce(err error) error { if agg, ok := err.(Aggregate); ok && err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go index 10df0d99cd5..9b3c9c8d5ac 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go +++ b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go @@ -32,7 +32,7 @@ func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer { return &lengthDelimitedFrameWriter{w: w} } -// Write writes a single frame to the nested writer, prepending it with the length in +// Write writes a single frame to the nested writer, prepending it with the length // in bytes of data (as a 4 byte, bigendian uint32). func (w *lengthDelimitedFrameWriter) Write(data []byte) (int, error) { binary.BigEndian.PutUint32(w.h[:], uint32(len(data))) @@ -56,10 +56,10 @@ type lengthDelimitedFrameReader struct { // // The protocol is: // -// stream: message ... -// message: prefix body -// prefix: 4 byte uint32 in BigEndian order, denotes length of body -// body: bytes (0..prefix) +// stream: message ... +// message: prefix body +// prefix: 4 byte uint32 in BigEndian order, denotes length of body +// body: bytes (0..prefix) // // If the buffer passed to Read is not long enough to contain an entire frame, io.ErrShortRead // will be returned along with the number of bytes read. diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go index c27380c19c6..5e800970453 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go +++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go @@ -145,7 +145,7 @@ func ValueOrDefault(intOrPercent *IntOrString, defaultValue IntOrString) *IntOrS // GetScaledValueFromIntOrPercent is meant to replace GetValueFromIntOrPercent. // This method returns a scaled value from an IntOrString type. If the IntOrString // is a percentage string value it's treated as a percentage and scaled appropriately -// in accordance to the total, if it's an int value it's treated as a a simple value and +// in accordance to the total, if it's an int value it's treated as a simple value and // if it is a string value which is either non-numeric or numeric but lacking a trailing '%' it returns an error. func GetScaledValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) { if intOrPercent == nil { diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml new file mode 100644 index 00000000000..a667e983426 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml @@ -0,0 +1,7018 @@ +apiVersion: v1 +kind: Endpoints +metadata: + creationTimestamp: '2016-10-04T17:45:58Z' + labels: + app: my-app + name: app-server + namespace: default + resourceVersion: '184597135' + selfLink: /self/link + uid: 6826f086-8a5a-11e6-8d09-42010a800005 +subsets: +- addresses: + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0000 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0001 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0002 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0003 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0004 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0005 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0006 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0007 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0008 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0009 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0010 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0011 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0012 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0013 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0014 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0015 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0016 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0017 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0018 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0019 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0020 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0021 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0022 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0023 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0024 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0025 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0026 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0027 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0028 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0029 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0030 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0031 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0032 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0033 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0034 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0035 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0036 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0037 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0038 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0039 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0040 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0041 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0042 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0043 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0044 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0045 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0046 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0047 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0048 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0049 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0050 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0051 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0052 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0053 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0054 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0055 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0056 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0057 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0058 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0059 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0060 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0061 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0062 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0063 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0064 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0065 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0066 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0067 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0068 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0069 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0070 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0071 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0072 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0073 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0074 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0075 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0076 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0077 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0078 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0079 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0080 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0081 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0082 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0083 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0084 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0085 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0086 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0087 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0088 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0089 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0090 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0091 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0092 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0093 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0094 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0095 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0096 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0097 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0098 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0099 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0100 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0101 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0102 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0103 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0104 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0105 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0106 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0107 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0108 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0109 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0110 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0111 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0112 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0113 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0114 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0115 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0116 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0117 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0118 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0119 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0120 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0121 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0122 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0123 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0124 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0125 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0126 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0127 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0128 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0129 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0130 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0131 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0132 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0133 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0134 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0135 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0136 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0137 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0138 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0139 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0140 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0141 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0142 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0143 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0144 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0145 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0146 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0147 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0148 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0149 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0150 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0151 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0152 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0153 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0154 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0155 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0156 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0157 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0158 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0159 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0160 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0161 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0162 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0163 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0164 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0165 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0166 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0167 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0168 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0169 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0170 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0171 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0172 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0173 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0174 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0175 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0176 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0177 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0178 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0179 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0180 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0181 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0182 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0183 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0184 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0185 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0186 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0187 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0188 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0189 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0190 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0191 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0192 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0193 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0194 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0195 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0196 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0197 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0198 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0199 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0200 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0201 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0202 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0203 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0204 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0205 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0206 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0207 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0208 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0209 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0210 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0211 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0212 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0213 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0214 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0215 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0216 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0217 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0218 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0219 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0220 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0221 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0222 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0223 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0224 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0225 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0226 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0227 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0228 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0229 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0230 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0231 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0232 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0233 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0234 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0235 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0236 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0237 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0238 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0239 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0240 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0241 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0242 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0243 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0244 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0245 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0246 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0247 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0248 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0249 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0250 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0251 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0252 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0253 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0254 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0255 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0256 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0257 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0258 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0259 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0260 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0261 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0262 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0263 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0264 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0265 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0266 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0267 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0268 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0269 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0270 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0271 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0272 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0273 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0274 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0275 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0276 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0277 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0278 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0279 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0280 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0281 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0282 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0283 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0284 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0285 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0286 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0287 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0288 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0289 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0290 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0291 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0292 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0293 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0294 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0295 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0296 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0297 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0298 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0299 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0300 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0301 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0302 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0303 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0304 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0305 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0306 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0307 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0308 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0309 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0310 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0311 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0312 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0313 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0314 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0315 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0316 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0317 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0318 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0319 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0320 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0321 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0322 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0323 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0324 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0325 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0326 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0327 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0328 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0329 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0330 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0331 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0332 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0333 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0334 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0335 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0336 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0337 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0338 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0339 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0340 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0341 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0342 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0343 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0344 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0345 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0346 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0347 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0348 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0349 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0350 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0351 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0352 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0353 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0354 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0355 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0356 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0357 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0358 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0359 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0360 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0361 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0362 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0363 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0364 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0365 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0366 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0367 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0368 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0369 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0370 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0371 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0372 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0373 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0374 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0375 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0376 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0377 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0378 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0379 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0380 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0381 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0382 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0383 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0384 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0385 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0386 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0387 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0388 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0389 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0390 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0391 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0392 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0393 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0394 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0395 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0396 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0397 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0398 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0399 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0400 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0401 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0402 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0403 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0404 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0405 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0406 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0407 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0408 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0409 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0410 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0411 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0412 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0413 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0414 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0415 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0416 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0417 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0418 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0419 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0420 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0421 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0422 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0423 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0424 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0425 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0426 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0427 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0428 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0429 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0430 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0431 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0432 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0433 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0434 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0435 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0436 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0437 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0438 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0439 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0440 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0441 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0442 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0443 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0444 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0445 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0446 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0447 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0448 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0449 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0450 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0451 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0452 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0453 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0454 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0455 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0456 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0457 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0458 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0459 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0460 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0461 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0462 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0463 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0464 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0465 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0466 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0467 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0468 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0469 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0470 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0471 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0472 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0473 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0474 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0475 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0476 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0477 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0478 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0479 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0480 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0481 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0482 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0483 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0484 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0485 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0486 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0487 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0488 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0489 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0490 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0491 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0492 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0493 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0494 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0495 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0496 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0497 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0498 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0499 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0500 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0501 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0502 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0503 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0504 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0505 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0506 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0507 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0508 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0509 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0510 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0511 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0512 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0513 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0514 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0515 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0516 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0517 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0518 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0519 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0520 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0521 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0522 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0523 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0524 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0525 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0526 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0527 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0528 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0529 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0530 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0531 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0532 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0533 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0534 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0535 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0536 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0537 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0538 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0539 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0540 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0541 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0542 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0543 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0544 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0545 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0546 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0547 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0548 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0549 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0550 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0551 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0552 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0553 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0554 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0555 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0556 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0557 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0558 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0559 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0560 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0561 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0562 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0563 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0564 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0565 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0566 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0567 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0568 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0569 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0570 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0571 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0572 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0573 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0574 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0575 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0576 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0577 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0578 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0579 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0580 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0581 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0582 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0583 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0584 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0585 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0586 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0587 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0588 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0589 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0590 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0591 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0592 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0593 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0594 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0595 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0596 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0597 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0598 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0599 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0600 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0601 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0602 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0603 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0604 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0605 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0606 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0607 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0608 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0609 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0610 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0611 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0612 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0613 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0614 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0615 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0616 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0617 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0618 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0619 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0620 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0621 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0622 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0623 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0624 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0625 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0626 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0627 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0628 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0629 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0630 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0631 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0632 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0633 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0634 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0635 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0636 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0637 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0638 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0639 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0640 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0641 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0642 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0643 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0644 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0645 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0646 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0647 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0648 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0649 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0650 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0651 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0652 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0653 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0654 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0655 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0656 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0657 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0658 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0659 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0660 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0661 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0662 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0663 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0664 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0665 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0666 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0667 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0668 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0669 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0670 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0671 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0672 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0673 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0674 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0675 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0676 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0677 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0678 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0679 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0680 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0681 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0682 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0683 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0684 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0685 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0686 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0687 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0688 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0689 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0690 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0691 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0692 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0693 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0694 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0695 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0696 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0697 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0698 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0699 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0700 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0701 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0702 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0703 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0704 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0705 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0706 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0707 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0708 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0709 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0710 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0711 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0712 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0713 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0714 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0715 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0716 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0717 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0718 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0719 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0720 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0721 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0722 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0723 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0724 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0725 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0726 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0727 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0728 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0729 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0730 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0731 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0732 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0733 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0734 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0735 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0736 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0737 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0738 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0739 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0740 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0741 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0742 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0743 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0744 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0745 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0746 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0747 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0748 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0749 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0750 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0751 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0752 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0753 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0754 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0755 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0756 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0757 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0758 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0759 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0760 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0761 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0762 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0763 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0764 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0765 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0766 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0767 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0768 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0769 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0770 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0771 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0772 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0773 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0774 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0775 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0776 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0777 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0778 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0779 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0780 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0781 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0782 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0783 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0784 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0785 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0786 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0787 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0788 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0789 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0790 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0791 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0792 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0793 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0794 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0795 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0796 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0797 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0798 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0799 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0800 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0801 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0802 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0803 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0804 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0805 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0806 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0807 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0808 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0809 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0810 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0811 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0812 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0813 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0814 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0815 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0816 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0817 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0818 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0819 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0820 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0821 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0822 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0823 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0824 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0825 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0826 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0827 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0828 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0829 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0830 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0831 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0832 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0833 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0834 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0835 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0836 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0837 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0838 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0839 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0840 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0841 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0842 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0843 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0844 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0845 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0846 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0847 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0848 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0849 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0850 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0851 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0852 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0853 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0854 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0855 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0856 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0857 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0858 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0859 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0860 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0861 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0862 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0863 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0864 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0865 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0866 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0867 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0868 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0869 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0870 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0871 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0872 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0873 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0874 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0875 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0876 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0877 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0878 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0879 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0880 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0881 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0882 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0883 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0884 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0885 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0886 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0887 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0888 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0889 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0890 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0891 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0892 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0893 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0894 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0895 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0896 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0897 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0898 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0899 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0900 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0901 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0902 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0903 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0904 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0905 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0906 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0907 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0908 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0909 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0910 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0911 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0912 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0913 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0914 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0915 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0916 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0917 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0918 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0919 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0920 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0921 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0922 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0923 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0924 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0925 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0926 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0927 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0928 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0929 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0930 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0931 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0932 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0933 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0934 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0935 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0936 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0937 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0938 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0939 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0940 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0941 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0942 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0943 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0944 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0945 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0946 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0947 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0948 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0949 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0950 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0951 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0952 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0953 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0954 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0955 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0956 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0957 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0958 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0959 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0960 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0961 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0962 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0963 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0964 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0965 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0966 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0967 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0968 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0969 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0970 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0971 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0972 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0973 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0974 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0975 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0976 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0977 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0978 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0979 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0980 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0981 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0982 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0983 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0984 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0985 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0986 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0987 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0988 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0989 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0990 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0991 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0992 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0993 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0994 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0995 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0996 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0997 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0998 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0999 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + ports: + - name: port-name + port: 8080 + protocol: TCP + diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go index 792badbc3d5..d2ce66c1bda 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go @@ -45,7 +45,7 @@ import ( // and their field paths and types are exactly the same, then ExtractInto can be // called with the root resource as the object and the subresource as the // applyConfiguration. This works for "status", obviously, because status is -// represented by the exact same object as the root resource. This this does NOT +// represented by the exact same object as the root resource. This does NOT // work, for example, with the "scale" subresources of Deployment, ReplicaSet and // StatefulSet. While the spec.replicas, status.replicas fields are in the same // exact field path locations as they are in autoscaling.Scale, the selector diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go new file mode 100644 index 00000000000..978ffb3c3e6 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go @@ -0,0 +1,57 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package managedfields + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/managedfields/internal" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// FieldManager updates the managed fields and merges applied +// configurations. +type FieldManager = internal.FieldManager + +// NewDefaultFieldManager creates a new FieldManager that merges apply requests +// and update managed fields for other types of requests. +func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (*FieldManager, error) { + f, err := internal.NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) + if err != nil { + return nil, fmt.Errorf("failed to create field manager: %v", err) + } + return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil +} + +// NewDefaultCRDFieldManager creates a new FieldManager specifically for +// CRDs. This allows for the possibility of fields which are not defined +// in models, as well as having no models defined at all. +func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ *FieldManager, err error) { + f, err := internal.NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) + if err != nil { + return nil, fmt.Errorf("failed to create field manager: %v", err) + } + return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil +} + +func ValidateManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) error { + _, err := internal.DecodeManagedFields(encodedManagedFields) + return err +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go new file mode 100644 index 00000000000..b75ef7416e7 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go @@ -0,0 +1,60 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "sync" + "time" +) + +// AtMostEvery will never run the method more than once every specified +// duration. +type AtMostEvery struct { + delay time.Duration + lastCall time.Time + mutex sync.Mutex +} + +// NewAtMostEvery creates a new AtMostEvery, that will run the method at +// most every given duration. +func NewAtMostEvery(delay time.Duration) *AtMostEvery { + return &AtMostEvery{ + delay: delay, + } +} + +// updateLastCall returns true if the lastCall time has been updated, +// false if it was too early. +func (s *AtMostEvery) updateLastCall() bool { + s.mutex.Lock() + defer s.mutex.Unlock() + if time.Since(s.lastCall) < s.delay { + return false + } + s.lastCall = time.Now() + return true +} + +// Do will run the method if enough time has passed, and return true. +// Otherwise, it does nothing and returns false. +func (s *AtMostEvery) Do(fn func()) bool { + if !s.updateLastCall() { + return false + } + fn() + return true +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go new file mode 100644 index 00000000000..fa342ca1351 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go @@ -0,0 +1,74 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type buildManagerInfoManager struct { + fieldManager Manager + groupVersion schema.GroupVersion + subresource string +} + +var _ Manager = &buildManagerInfoManager{} + +// NewBuildManagerInfoManager creates a new Manager that converts the manager name into a unique identifier +// combining operation and version for update requests, and just operation for apply requests. +func NewBuildManagerInfoManager(f Manager, gv schema.GroupVersion, subresource string) Manager { + return &buildManagerInfoManager{ + fieldManager: f, + groupVersion: gv, + subresource: subresource, + } +} + +// Update implements Manager. +func (f *buildManagerInfoManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + manager, err := f.buildManagerInfo(manager, metav1.ManagedFieldsOperationUpdate) + if err != nil { + return nil, nil, fmt.Errorf("failed to build manager identifier: %v", err) + } + return f.fieldManager.Update(liveObj, newObj, managed, manager) +} + +// Apply implements Manager. +func (f *buildManagerInfoManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) { + manager, err := f.buildManagerInfo(manager, metav1.ManagedFieldsOperationApply) + if err != nil { + return nil, nil, fmt.Errorf("failed to build manager identifier: %v", err) + } + return f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force) +} + +func (f *buildManagerInfoManager) buildManagerInfo(prefix string, operation metav1.ManagedFieldsOperationType) (string, error) { + managerInfo := metav1.ManagedFieldsEntry{ + Manager: prefix, + Operation: operation, + APIVersion: f.groupVersion.String(), + Subresource: f.subresource, + } + if managerInfo.Manager == "" { + managerInfo.Manager = "unknown" + } + return BuildManagerIdentifier(&managerInfo) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go new file mode 100644 index 00000000000..8951932ba42 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go @@ -0,0 +1,133 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + "sort" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +type capManagersManager struct { + fieldManager Manager + maxUpdateManagers int + oldUpdatesManagerName string +} + +var _ Manager = &capManagersManager{} + +// NewCapManagersManager creates a new wrapped FieldManager which ensures that the number of managers from updates +// does not exceed maxUpdateManagers, by merging some of the oldest entries on each update. +func NewCapManagersManager(fieldManager Manager, maxUpdateManagers int) Manager { + return &capManagersManager{ + fieldManager: fieldManager, + maxUpdateManagers: maxUpdateManagers, + oldUpdatesManagerName: "ancient-changes", + } +} + +// Update implements Manager. +func (f *capManagersManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, manager) + if err != nil { + return object, managed, err + } + if managed, err = f.capUpdateManagers(managed); err != nil { + return nil, nil, fmt.Errorf("failed to cap update managers: %v", err) + } + return object, managed, nil +} + +// Apply implements Manager. +func (f *capManagersManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) { + return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force) +} + +// capUpdateManagers merges a number of the oldest update entries into versioned buckets, +// such that the number of entries from updates does not exceed f.maxUpdateManagers. +func (f *capManagersManager) capUpdateManagers(managed Managed) (newManaged Managed, err error) { + // Gather all entries from updates + updaters := []string{} + for manager, fields := range managed.Fields() { + if !fields.Applied() { + updaters = append(updaters, manager) + } + } + if len(updaters) <= f.maxUpdateManagers { + return managed, nil + } + + // If we have more than the maximum, sort the update entries by time, oldest first. + sort.Slice(updaters, func(i, j int) bool { + iTime, jTime, iSeconds, jSeconds := managed.Times()[updaters[i]], managed.Times()[updaters[j]], int64(0), int64(0) + if iTime != nil { + iSeconds = iTime.Unix() + } + if jTime != nil { + jSeconds = jTime.Unix() + } + if iSeconds != jSeconds { + return iSeconds < jSeconds + } + return updaters[i] < updaters[j] + }) + + // Merge the oldest updaters with versioned bucket managers until the number of updaters is under the cap + versionToFirstManager := map[string]string{} + for i, length := 0, len(updaters); i < len(updaters) && length > f.maxUpdateManagers; i++ { + manager := updaters[i] + vs := managed.Fields()[manager] + time := managed.Times()[manager] + version := string(vs.APIVersion()) + + // Create a new manager identifier for the versioned bucket entry. + // The version for this manager comes from the version of the update being merged into the bucket. + bucket, err := BuildManagerIdentifier(&metav1.ManagedFieldsEntry{ + Manager: f.oldUpdatesManagerName, + Operation: metav1.ManagedFieldsOperationUpdate, + APIVersion: version, + }) + if err != nil { + return managed, fmt.Errorf("failed to create bucket manager for version %v: %v", version, err) + } + + // Merge the fieldets if this is not the first time the version was seen. + // Otherwise just record the manager name in versionToFirstManager + if first, ok := versionToFirstManager[version]; ok { + // If the bucket doesn't exists yet, create one. + if _, ok := managed.Fields()[bucket]; !ok { + s := managed.Fields()[first] + delete(managed.Fields(), first) + managed.Fields()[bucket] = s + } + + managed.Fields()[bucket] = fieldpath.NewVersionedSet(vs.Set().Union(managed.Fields()[bucket].Set()), vs.APIVersion(), vs.Applied()) + delete(managed.Fields(), manager) + length-- + + // Use the time from the update being merged into the bucket, since it is more recent. + managed.Times()[bucket] = time + } else { + versionToFirstManager[version] = manager + } + } + + return managed, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go new file mode 100644 index 00000000000..8c044c91570 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "encoding/json" + "fmt" + "sort" + "strings" + "time" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" +) + +// NewConflictError returns an error including details on the requests apply conflicts +func NewConflictError(conflicts merge.Conflicts) *errors.StatusError { + causes := []metav1.StatusCause{} + for _, conflict := range conflicts { + causes = append(causes, metav1.StatusCause{ + Type: metav1.CauseTypeFieldManagerConflict, + Message: fmt.Sprintf("conflict with %v", printManager(conflict.Manager)), + Field: conflict.Path.String(), + }) + } + return errors.NewApplyConflict(causes, getConflictMessage(conflicts)) +} + +func getConflictMessage(conflicts merge.Conflicts) string { + if len(conflicts) == 1 { + return fmt.Sprintf("Apply failed with 1 conflict: conflict with %v: %v", printManager(conflicts[0].Manager), conflicts[0].Path) + } + + m := map[string][]fieldpath.Path{} + for _, conflict := range conflicts { + m[conflict.Manager] = append(m[conflict.Manager], conflict.Path) + } + + uniqueManagers := []string{} + for manager := range m { + uniqueManagers = append(uniqueManagers, manager) + } + + // Print conflicts by sorted managers. + sort.Strings(uniqueManagers) + + messages := []string{} + for _, manager := range uniqueManagers { + messages = append(messages, fmt.Sprintf("conflicts with %v:", printManager(manager))) + for _, path := range m[manager] { + messages = append(messages, fmt.Sprintf("- %v", path)) + } + } + return fmt.Sprintf("Apply failed with %d conflicts: %s", len(conflicts), strings.Join(messages, "\n")) +} + +func printManager(manager string) string { + encodedManager := &metav1.ManagedFieldsEntry{} + if err := json.Unmarshal([]byte(manager), encodedManager); err != nil { + return fmt.Sprintf("%q", manager) + } + managerStr := fmt.Sprintf("%q", encodedManager.Manager) + if encodedManager.Subresource != "" { + managerStr = fmt.Sprintf("%s with subresource %q", managerStr, encodedManager.Subresource) + } + if encodedManager.Operation == metav1.ManagedFieldsOperationUpdate { + if encodedManager.Time == nil { + return fmt.Sprintf("%s using %v", managerStr, encodedManager.APIVersion) + } + return fmt.Sprintf("%s using %v at %v", managerStr, encodedManager.APIVersion, encodedManager.Time.UTC().Format(time.RFC3339)) + } + return managerStr +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go new file mode 100644 index 00000000000..f3111d4bc72 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go @@ -0,0 +1,206 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + "reflect" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" + "sigs.k8s.io/structured-merge-diff/v4/merge" +) + +// DefaultMaxUpdateManagers defines the default maximum retained number of managedFields entries from updates +// if the number of update managers exceeds this, the oldest entries will be merged until the number is below the maximum. +// TODO(jennybuckley): Determine if this is really the best value. Ideally we wouldn't unnecessarily merge too many entries. +const DefaultMaxUpdateManagers int = 10 + +// DefaultTrackOnCreateProbability defines the default probability that the field management of an object +// starts being tracked from the object's creation, instead of from the first time the object is applied to. +const DefaultTrackOnCreateProbability float32 = 1 + +var atMostEverySecond = NewAtMostEvery(time.Second) + +// FieldManager updates the managed fields and merges applied +// configurations. +type FieldManager struct { + fieldManager Manager + subresource string +} + +// NewFieldManager creates a new FieldManager that decodes, manages, then re-encodes managedFields +// on update and apply requests. +func NewFieldManager(f Manager, subresource string) *FieldManager { + return &FieldManager{fieldManager: f, subresource: subresource} +} + +// newDefaultFieldManager is a helper function which wraps a Manager with certain default logic. +func NewDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager { + return NewFieldManager( + NewLastAppliedUpdater( + NewLastAppliedManager( + NewProbabilisticSkipNonAppliedManager( + NewCapManagersManager( + NewBuildManagerInfoManager( + NewManagedFieldsUpdater( + NewStripMetaManager(f), + ), kind.GroupVersion(), subresource, + ), DefaultMaxUpdateManagers, + ), objectCreater, kind, DefaultTrackOnCreateProbability, + ), typeConverter, objectConverter, kind.GroupVersion()), + ), subresource, + ) +} + +func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequestObject bool) (Managed, error) { + liveAccessor, err := meta.Accessor(liveObj) + if err != nil { + return nil, err + } + + // We take the managedFields of the live object in case the request tries to + // manually set managedFields via a subresource. + if ignoreManagedFieldsFromRequestObject { + return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields())) + } + + // If the object doesn't have metadata, we should just return without trying to + // set the managedFields at all, so creates/updates/patches will work normally. + newAccessor, err := meta.Accessor(newObj) + if err != nil { + return nil, err + } + + if isResetManagedFields(newAccessor.GetManagedFields()) { + return NewEmptyManaged(), nil + } + + // If the managed field is empty or we failed to decode it, + // let's try the live object. This is to prevent clients who + // don't understand managedFields from deleting it accidentally. + managed, err := DecodeManagedFields(newAccessor.GetManagedFields()) + if err != nil || len(managed.Fields()) == 0 { + return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields())) + } + return managed, nil +} + +func emptyManagedFieldsOnErr(managed Managed, err error) (Managed, error) { + if err != nil { + return NewEmptyManaged(), nil + } + return managed, nil +} + +// Update is used when the object has already been merged (non-apply +// use-case), and simply updates the managed fields in the output +// object. +func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (object runtime.Object, err error) { + // First try to decode the managed fields provided in the update, + // This is necessary to allow directly updating managed fields. + isSubresource := f.subresource != "" + managed, err := decodeLiveOrNew(liveObj, newObj, isSubresource) + if err != nil { + return newObj, nil + } + + RemoveObjectManagedFields(newObj) + + if object, managed, err = f.fieldManager.Update(liveObj, newObj, managed, manager); err != nil { + return nil, err + } + + if err = EncodeObjectManagedFields(object, managed); err != nil { + return nil, fmt.Errorf("failed to encode managed fields: %v", err) + } + + return object, nil +} + +// UpdateNoErrors is the same as Update, but it will not return +// errors. If an error happens, the object is returned with +// managedFields cleared. +func (f *FieldManager) UpdateNoErrors(liveObj, newObj runtime.Object, manager string) runtime.Object { + obj, err := f.Update(liveObj, newObj, manager) + if err != nil { + atMostEverySecond.Do(func() { + ns, name := "unknown", "unknown" + if accessor, err := meta.Accessor(newObj); err == nil { + ns = accessor.GetNamespace() + name = accessor.GetName() + } + + klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "versionKind", + newObj.GetObjectKind().GroupVersionKind(), "namespace", ns, "name", name) + }) + // Explicitly remove managedFields on failure, so that + // we can't have garbage in it. + RemoveObjectManagedFields(newObj) + return newObj + } + return obj +} + +// Returns true if the managedFields indicate that the user is trying to +// reset the managedFields, i.e. if the list is non-nil but empty, or if +// the list has one empty item. +func isResetManagedFields(managedFields []metav1.ManagedFieldsEntry) bool { + if len(managedFields) == 0 { + return managedFields != nil + } + + if len(managedFields) == 1 { + return reflect.DeepEqual(managedFields[0], metav1.ManagedFieldsEntry{}) + } + + return false +} + +// Apply is used when server-side apply is called, as it merges the +// object and updates the managed fields. +func (f *FieldManager) Apply(liveObj, appliedObj runtime.Object, manager string, force bool) (object runtime.Object, err error) { + // If the object doesn't have metadata, apply isn't allowed. + accessor, err := meta.Accessor(liveObj) + if err != nil { + return nil, fmt.Errorf("couldn't get accessor: %v", err) + } + + // Decode the managed fields in the live object, since it isn't allowed in the patch. + managed, err := DecodeManagedFields(accessor.GetManagedFields()) + if err != nil { + return nil, fmt.Errorf("failed to decode managed fields: %v", err) + } + + object, managed, err = f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force) + if err != nil { + if conflicts, ok := err.(merge.Conflicts); ok { + return nil, NewConflictError(conflicts) + } + return nil, err + } + + if err = EncodeObjectManagedFields(object, managed); err != nil { + return nil, fmt.Errorf("failed to encode managed fields: %v", err) + } + + return object, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go new file mode 100644 index 00000000000..08186191a71 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go @@ -0,0 +1,47 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "bytes" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// EmptyFields represents a set with no paths +// It looks like metav1.Fields{Raw: []byte("{}")} +var EmptyFields = func() metav1.FieldsV1 { + f, err := SetToFields(*fieldpath.NewSet()) + if err != nil { + panic("should never happen") + } + return f +}() + +// FieldsToSet creates a set paths from an input trie of fields +func FieldsToSet(f metav1.FieldsV1) (s fieldpath.Set, err error) { + err = s.FromJSON(bytes.NewReader(f.Raw)) + return s, err +} + +// SetToFields creates a trie of fields from an input set of paths +func SetToFields(s fieldpath.Set) (f metav1.FieldsV1, err error) { + f.Raw, err = s.ToJSON() + return f, err +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go new file mode 100644 index 00000000000..b00b6b8298a --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go @@ -0,0 +1,50 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime" +) + +// LastAppliedConfigAnnotation is the annotation used to store the previous +// configuration of a resource for use in a three way diff by UpdateApplyAnnotation. +// +// This is a copy of the corev1 annotation since we don't want to depend on the whole package. +const LastAppliedConfigAnnotation = "kubectl.kubernetes.io/last-applied-configuration" + +// SetLastApplied sets the last-applied annotation the given value in +// the object. +func SetLastApplied(obj runtime.Object, value string) error { + accessor, err := meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + var annotations = accessor.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations[LastAppliedConfigAnnotation] = value + if err := apimachineryvalidation.ValidateAnnotationsSize(annotations); err != nil { + delete(annotations, LastAppliedConfigAnnotation) + } + accessor.SetAnnotations(annotations) + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go new file mode 100644 index 00000000000..3f6cf88210c --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go @@ -0,0 +1,171 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "encoding/json" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" +) + +type lastAppliedManager struct { + fieldManager Manager + typeConverter TypeConverter + objectConverter runtime.ObjectConvertor + groupVersion schema.GroupVersion +} + +var _ Manager = &lastAppliedManager{} + +// NewLastAppliedManager converts the client-side apply annotation to +// server-side apply managed fields +func NewLastAppliedManager(fieldManager Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, groupVersion schema.GroupVersion) Manager { + return &lastAppliedManager{ + fieldManager: fieldManager, + typeConverter: typeConverter, + objectConverter: objectConverter, + groupVersion: groupVersion, + } +} + +// Update implements Manager. +func (f *lastAppliedManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + return f.fieldManager.Update(liveObj, newObj, managed, manager) +} + +// Apply will consider the last-applied annotation +// for upgrading an object managed by client-side apply to server-side apply +// without conflicts. +func (f *lastAppliedManager) Apply(liveObj, newObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) { + newLiveObj, newManaged, newErr := f.fieldManager.Apply(liveObj, newObj, managed, manager, force) + // Upgrade the client-side apply annotation only from kubectl server-side-apply. + // To opt-out of this behavior, users may specify a different field manager. + if manager != "kubectl" { + return newLiveObj, newManaged, newErr + } + + // Check if we have conflicts + if newErr == nil { + return newLiveObj, newManaged, newErr + } + conflicts, ok := newErr.(merge.Conflicts) + if !ok { + return newLiveObj, newManaged, newErr + } + conflictSet := conflictsToSet(conflicts) + + // Check if conflicts are allowed due to client-side apply, + // and if so, then force apply + allowedConflictSet, err := f.allowedConflictsFromLastApplied(liveObj) + if err != nil { + return newLiveObj, newManaged, newErr + } + if !conflictSet.Difference(allowedConflictSet).Empty() { + newConflicts := conflictsDifference(conflicts, allowedConflictSet) + return newLiveObj, newManaged, newConflicts + } + + return f.fieldManager.Apply(liveObj, newObj, managed, manager, true) +} + +func (f *lastAppliedManager) allowedConflictsFromLastApplied(liveObj runtime.Object) (*fieldpath.Set, error) { + var accessor, err = meta.Accessor(liveObj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + + // If there is no client-side apply annotation, then there is nothing to do + var annotations = accessor.GetAnnotations() + if annotations == nil { + return nil, fmt.Errorf("no last applied annotation") + } + var lastApplied, ok = annotations[LastAppliedConfigAnnotation] + if !ok || lastApplied == "" { + return nil, fmt.Errorf("no last applied annotation") + } + + liveObjVersioned, err := f.objectConverter.ConvertToVersion(liveObj, f.groupVersion) + if err != nil { + return nil, fmt.Errorf("failed to convert live obj to versioned: %v", err) + } + + liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned) + if err != nil { + return nil, fmt.Errorf("failed to convert live obj to typed: %v", err) + } + + var lastAppliedObj = &unstructured.Unstructured{Object: map[string]interface{}{}} + err = json.Unmarshal([]byte(lastApplied), lastAppliedObj) + if err != nil { + return nil, fmt.Errorf("failed to decode last applied obj: %v in '%s'", err, lastApplied) + } + + if lastAppliedObj.GetAPIVersion() != f.groupVersion.String() { + return nil, fmt.Errorf("expected version of last applied to match live object '%s', but got '%s': %v", f.groupVersion.String(), lastAppliedObj.GetAPIVersion(), err) + } + + lastAppliedObjTyped, err := f.typeConverter.ObjectToTyped(lastAppliedObj) + if err != nil { + return nil, fmt.Errorf("failed to convert last applied to typed: %v", err) + } + + lastAppliedObjFieldSet, err := lastAppliedObjTyped.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create fieldset for last applied object: %v", err) + } + + comparison, err := lastAppliedObjTyped.Compare(liveObjTyped) + if err != nil { + return nil, fmt.Errorf("failed to compare last applied object and live object: %v", err) + } + + // Remove fields in last applied that are different, added, or missing in + // the live object. + // Because last-applied fields don't match the live object fields, + // then we don't own these fields. + lastAppliedObjFieldSet = lastAppliedObjFieldSet. + Difference(comparison.Modified). + Difference(comparison.Added). + Difference(comparison.Removed) + + return lastAppliedObjFieldSet, nil +} + +// TODO: replace with merge.Conflicts.ToSet() +func conflictsToSet(conflicts merge.Conflicts) *fieldpath.Set { + conflictSet := fieldpath.NewSet() + for _, conflict := range []merge.Conflict(conflicts) { + conflictSet.Insert(conflict.Path) + } + return conflictSet +} + +func conflictsDifference(conflicts merge.Conflicts, s *fieldpath.Set) merge.Conflicts { + newConflicts := []merge.Conflict{} + for _, conflict := range []merge.Conflict(conflicts) { + if !s.Has(conflict.Path) { + newConflicts = append(newConflicts, conflict) + } + } + return newConflicts +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go new file mode 100644 index 00000000000..06e6c5d8ce5 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go @@ -0,0 +1,102 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +type lastAppliedUpdater struct { + fieldManager Manager +} + +var _ Manager = &lastAppliedUpdater{} + +// NewLastAppliedUpdater sets the client-side apply annotation up to date with +// server-side apply managed fields +func NewLastAppliedUpdater(fieldManager Manager) Manager { + return &lastAppliedUpdater{ + fieldManager: fieldManager, + } +} + +// Update implements Manager. +func (f *lastAppliedUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + return f.fieldManager.Update(liveObj, newObj, managed, manager) +} + +// server-side apply managed fields +func (f *lastAppliedUpdater) Apply(liveObj, newObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) { + liveObj, managed, err := f.fieldManager.Apply(liveObj, newObj, managed, manager, force) + if err != nil { + return liveObj, managed, err + } + + // Sync the client-side apply annotation only from kubectl server-side apply. + // To opt-out of this behavior, users may specify a different field manager. + // + // If the client-side apply annotation doesn't exist, + // then continue because we have no annotation to update + if manager == "kubectl" && hasLastApplied(liveObj) { + lastAppliedValue, err := buildLastApplied(newObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to build last-applied annotation: %v", err) + } + err = SetLastApplied(liveObj, lastAppliedValue) + if err != nil { + return nil, nil, fmt.Errorf("failed to set last-applied annotation: %v", err) + } + } + return liveObj, managed, err +} + +func hasLastApplied(obj runtime.Object) bool { + var accessor, err = meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + var annotations = accessor.GetAnnotations() + if annotations == nil { + return false + } + lastApplied, ok := annotations[LastAppliedConfigAnnotation] + return ok && len(lastApplied) > 0 +} + +func buildLastApplied(obj runtime.Object) (string, error) { + obj = obj.DeepCopyObject() + + var accessor, err = meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + + // Remove the annotation from the object before encoding the object + var annotations = accessor.GetAnnotations() + delete(annotations, LastAppliedConfigAnnotation) + accessor.SetAnnotations(annotations) + + lastApplied, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) + if err != nil { + return "", fmt.Errorf("couldn't encode object into last applied annotation: %v", err) + } + return string(lastApplied), nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go new file mode 100644 index 00000000000..9b4c2032628 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go @@ -0,0 +1,248 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "encoding/json" + "fmt" + "sort" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// ManagedInterface groups a fieldpath.ManagedFields together with the timestamps associated with each operation. +type ManagedInterface interface { + // Fields gets the fieldpath.ManagedFields. + Fields() fieldpath.ManagedFields + + // Times gets the timestamps associated with each operation. + Times() map[string]*metav1.Time +} + +type managedStruct struct { + fields fieldpath.ManagedFields + times map[string]*metav1.Time +} + +var _ ManagedInterface = &managedStruct{} + +// Fields implements ManagedInterface. +func (m *managedStruct) Fields() fieldpath.ManagedFields { + return m.fields +} + +// Times implements ManagedInterface. +func (m *managedStruct) Times() map[string]*metav1.Time { + return m.times +} + +// NewEmptyManaged creates an empty ManagedInterface. +func NewEmptyManaged() ManagedInterface { + return NewManaged(fieldpath.ManagedFields{}, map[string]*metav1.Time{}) +} + +// NewManaged creates a ManagedInterface from a fieldpath.ManagedFields and the timestamps associated with each operation. +func NewManaged(f fieldpath.ManagedFields, t map[string]*metav1.Time) ManagedInterface { + return &managedStruct{ + fields: f, + times: t, + } +} + +// RemoveObjectManagedFields removes the ManagedFields from the object +// before we merge so that it doesn't appear in the ManagedFields +// recursively. +func RemoveObjectManagedFields(obj runtime.Object) { + accessor, err := meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + accessor.SetManagedFields(nil) +} + +// EncodeObjectManagedFields converts and stores the fieldpathManagedFields into the objects ManagedFields +func EncodeObjectManagedFields(obj runtime.Object, managed ManagedInterface) error { + accessor, err := meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + + encodedManagedFields, err := encodeManagedFields(managed) + if err != nil { + return fmt.Errorf("failed to convert back managed fields to API: %v", err) + } + accessor.SetManagedFields(encodedManagedFields) + + return nil +} + +// DecodeManagedFields converts ManagedFields from the wire format (api format) +// to the format used by sigs.k8s.io/structured-merge-diff +func DecodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (ManagedInterface, error) { + managed := managedStruct{} + managed.fields = make(fieldpath.ManagedFields, len(encodedManagedFields)) + managed.times = make(map[string]*metav1.Time, len(encodedManagedFields)) + + for i, encodedVersionedSet := range encodedManagedFields { + switch encodedVersionedSet.Operation { + case metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate: + default: + return nil, fmt.Errorf("operation must be `Apply` or `Update`") + } + if len(encodedVersionedSet.APIVersion) < 1 { + return nil, fmt.Errorf("apiVersion must not be empty") + } + switch encodedVersionedSet.FieldsType { + case "FieldsV1": + // Valid case. + case "": + return nil, fmt.Errorf("missing fieldsType in managed fields entry %d", i) + default: + return nil, fmt.Errorf("invalid fieldsType %q in managed fields entry %d", encodedVersionedSet.FieldsType, i) + } + manager, err := BuildManagerIdentifier(&encodedVersionedSet) + if err != nil { + return nil, fmt.Errorf("error decoding manager from %v: %v", encodedVersionedSet, err) + } + managed.fields[manager], err = decodeVersionedSet(&encodedVersionedSet) + if err != nil { + return nil, fmt.Errorf("error decoding versioned set from %v: %v", encodedVersionedSet, err) + } + managed.times[manager] = encodedVersionedSet.Time + } + return &managed, nil +} + +// BuildManagerIdentifier creates a manager identifier string from a ManagedFieldsEntry +func BuildManagerIdentifier(encodedManager *metav1.ManagedFieldsEntry) (manager string, err error) { + encodedManagerCopy := *encodedManager + + // Never include fields type in the manager identifier + encodedManagerCopy.FieldsType = "" + + // Never include the fields in the manager identifier + encodedManagerCopy.FieldsV1 = nil + + // Never include the time in the manager identifier + encodedManagerCopy.Time = nil + + // For appliers, don't include the APIVersion in the manager identifier, + // so it will always have the same manager identifier each time it applied. + if encodedManager.Operation == metav1.ManagedFieldsOperationApply { + encodedManagerCopy.APIVersion = "" + } + + // Use the remaining fields to build the manager identifier + b, err := json.Marshal(&encodedManagerCopy) + if err != nil { + return "", fmt.Errorf("error marshalling manager identifier: %v", err) + } + + return string(b), nil +} + +func decodeVersionedSet(encodedVersionedSet *metav1.ManagedFieldsEntry) (versionedSet fieldpath.VersionedSet, err error) { + fields := EmptyFields + if encodedVersionedSet.FieldsV1 != nil { + fields = *encodedVersionedSet.FieldsV1 + } + set, err := FieldsToSet(fields) + if err != nil { + return nil, fmt.Errorf("error decoding set: %v", err) + } + return fieldpath.NewVersionedSet(&set, fieldpath.APIVersion(encodedVersionedSet.APIVersion), encodedVersionedSet.Operation == metav1.ManagedFieldsOperationApply), nil +} + +// encodeManagedFields converts ManagedFields from the format used by +// sigs.k8s.io/structured-merge-diff to the wire format (api format) +func encodeManagedFields(managed ManagedInterface) (encodedManagedFields []metav1.ManagedFieldsEntry, err error) { + if len(managed.Fields()) == 0 { + return nil, nil + } + encodedManagedFields = []metav1.ManagedFieldsEntry{} + for manager := range managed.Fields() { + versionedSet := managed.Fields()[manager] + v, err := encodeManagerVersionedSet(manager, versionedSet) + if err != nil { + return nil, fmt.Errorf("error encoding versioned set for %v: %v", manager, err) + } + if t, ok := managed.Times()[manager]; ok { + v.Time = t + } + encodedManagedFields = append(encodedManagedFields, *v) + } + return sortEncodedManagedFields(encodedManagedFields) +} + +func sortEncodedManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (sortedManagedFields []metav1.ManagedFieldsEntry, err error) { + sort.Slice(encodedManagedFields, func(i, j int) bool { + p, q := encodedManagedFields[i], encodedManagedFields[j] + + if p.Operation != q.Operation { + return p.Operation < q.Operation + } + + pSeconds, qSeconds := int64(0), int64(0) + if p.Time != nil { + pSeconds = p.Time.Unix() + } + if q.Time != nil { + qSeconds = q.Time.Unix() + } + if pSeconds != qSeconds { + return pSeconds < qSeconds + } + + if p.Manager != q.Manager { + return p.Manager < q.Manager + } + + if p.APIVersion != q.APIVersion { + return p.APIVersion < q.APIVersion + } + return p.Subresource < q.Subresource + }) + + return encodedManagedFields, nil +} + +func encodeManagerVersionedSet(manager string, versionedSet fieldpath.VersionedSet) (encodedVersionedSet *metav1.ManagedFieldsEntry, err error) { + encodedVersionedSet = &metav1.ManagedFieldsEntry{} + + // Get as many fields as we can from the manager identifier + err = json.Unmarshal([]byte(manager), encodedVersionedSet) + if err != nil { + return nil, fmt.Errorf("error unmarshalling manager identifier %v: %v", manager, err) + } + + // Get the APIVersion, Operation, and Fields from the VersionedSet + encodedVersionedSet.APIVersion = string(versionedSet.APIVersion()) + if versionedSet.Applied() { + encodedVersionedSet.Operation = metav1.ManagedFieldsOperationApply + } + encodedVersionedSet.FieldsType = "FieldsV1" + fields, err := SetToFields(*versionedSet.Set()) + if err != nil { + return nil, fmt.Errorf("error encoding set: %v", err) + } + encodedVersionedSet.FieldsV1 = &fields + + return encodedVersionedSet, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go new file mode 100644 index 00000000000..376eed6b207 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go @@ -0,0 +1,82 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +type managedFieldsUpdater struct { + fieldManager Manager +} + +var _ Manager = &managedFieldsUpdater{} + +// NewManagedFieldsUpdater is responsible for updating the managedfields +// in the object, updating the time of the operation as necessary. For +// updates, it uses a hard-coded manager to detect if things have +// changed, and swaps back the correct manager after the operation is +// done. +func NewManagedFieldsUpdater(fieldManager Manager) Manager { + return &managedFieldsUpdater{ + fieldManager: fieldManager, + } +} + +// Update implements Manager. +func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + self := "current-operation" + object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, self) + if err != nil { + return object, managed, err + } + + // If the current operation took any fields from anything, it means the object changed, + // so update the timestamp of the managedFieldsEntry and merge with any previous updates from the same manager + if vs, ok := managed.Fields()[self]; ok { + delete(managed.Fields(), self) + + if previous, ok := managed.Fields()[manager]; ok { + managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied()) + } else { + managed.Fields()[manager] = vs + } + + managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()} + } + + return object, managed, nil +} + +// Apply implements Manager. +func (f *managedFieldsUpdater) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) { + object, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force) + if err != nil { + return object, managed, err + } + if object != nil { + managed.Times()[fieldManager] = &metav1.Time{Time: time.Now().UTC()} + } else { + object = liveObj.DeepCopyObject() + RemoveObjectManagedFields(object) + } + return object, managed, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go new file mode 100644 index 00000000000..053936103d7 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go @@ -0,0 +1,52 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation. +type Managed interface { + // Fields gets the fieldpath.ManagedFields. + Fields() fieldpath.ManagedFields + + // Times gets the timestamps associated with each operation. + Times() map[string]*metav1.Time +} + +// Manager updates the managed fields and merges applied configurations. +type Manager interface { + // Update is used when the object has already been merged (non-apply + // use-case), and simply updates the managed fields in the output + // object. + // * `liveObj` is not mutated by this function + // * `newObj` may be mutated by this function + // Returns the new object with managedFields removed, and the object's new + // proposed managedFields separately. + Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) + + // Apply is used when server-side apply is called, as it merges the + // object and updates the managed fields. + // * `liveObj` is not mutated by this function + // * `newObj` may be mutated by this function + // Returns the new object with managedFields removed, and the object's new + // proposed managedFields separately. + Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go new file mode 100644 index 00000000000..1954d65d32e --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go @@ -0,0 +1,140 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/value" +) + +const ( + // Field indicates that the content of this path element is a field's name + Field = "f" + + // Value indicates that the content of this path element is a field's value + Value = "v" + + // Index indicates that the content of this path element is an index in an array + Index = "i" + + // Key indicates that the content of this path element is a key value map + Key = "k" + + // Separator separates the type of a path element from the contents + Separator = ":" +) + +// NewPathElement parses a serialized path element +func NewPathElement(s string) (fieldpath.PathElement, error) { + split := strings.SplitN(s, Separator, 2) + if len(split) < 2 { + return fieldpath.PathElement{}, fmt.Errorf("missing colon: %v", s) + } + switch split[0] { + case Field: + return fieldpath.PathElement{ + FieldName: &split[1], + }, nil + case Value: + val, err := value.FromJSON([]byte(split[1])) + if err != nil { + return fieldpath.PathElement{}, err + } + return fieldpath.PathElement{ + Value: &val, + }, nil + case Index: + i, err := strconv.Atoi(split[1]) + if err != nil { + return fieldpath.PathElement{}, err + } + return fieldpath.PathElement{ + Index: &i, + }, nil + case Key: + kv := map[string]json.RawMessage{} + err := json.Unmarshal([]byte(split[1]), &kv) + if err != nil { + return fieldpath.PathElement{}, err + } + fields := value.FieldList{} + for k, v := range kv { + b, err := json.Marshal(v) + if err != nil { + return fieldpath.PathElement{}, err + } + val, err := value.FromJSON(b) + if err != nil { + return fieldpath.PathElement{}, err + } + + fields = append(fields, value.Field{ + Name: k, + Value: val, + }) + } + return fieldpath.PathElement{ + Key: &fields, + }, nil + default: + // Ignore unknown key types + return fieldpath.PathElement{}, nil + } +} + +// PathElementString serializes a path element +func PathElementString(pe fieldpath.PathElement) (string, error) { + switch { + case pe.FieldName != nil: + return Field + Separator + *pe.FieldName, nil + case pe.Key != nil: + kv := map[string]json.RawMessage{} + for _, k := range *pe.Key { + b, err := value.ToJSON(k.Value) + if err != nil { + return "", err + } + m := json.RawMessage{} + err = json.Unmarshal(b, &m) + if err != nil { + return "", err + } + kv[k.Name] = m + } + b, err := json.Marshal(kv) + if err != nil { + return "", err + } + return Key + ":" + string(b), nil + case pe.Value != nil: + b, err := value.ToJSON(*pe.Value) + if err != nil { + return "", err + } + return Value + ":" + string(b), nil + case pe.Index != nil: + return Index + ":" + strconv.Itoa(*pe.Index), nil + default: + return "", errors.New("Invalid type of path element") + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go new file mode 100644 index 00000000000..6b281ec1e57 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go @@ -0,0 +1,91 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + "math/rand" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type skipNonAppliedManager struct { + fieldManager Manager + objectCreater runtime.ObjectCreater + gvk schema.GroupVersionKind + beforeApplyManagerName string + probability float32 +} + +var _ Manager = &skipNonAppliedManager{} + +// NewSkipNonAppliedManager creates a new wrapped FieldManager that only starts tracking managers after the first apply. +func NewSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind) Manager { + return NewProbabilisticSkipNonAppliedManager(fieldManager, objectCreater, gvk, 0.0) +} + +// NewProbabilisticSkipNonAppliedManager creates a new wrapped FieldManager that starts tracking managers after the first apply, +// or starts tracking on create with p probability. +func NewProbabilisticSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind, p float32) Manager { + return &skipNonAppliedManager{ + fieldManager: fieldManager, + objectCreater: objectCreater, + gvk: gvk, + beforeApplyManagerName: "before-first-apply", + probability: p, + } +} + +// Update implements Manager. +func (f *skipNonAppliedManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + accessor, err := meta.Accessor(liveObj) + if err != nil { + return newObj, managed, nil + } + + // If managed fields is empty, we need to determine whether to skip tracking managed fields. + if len(managed.Fields()) == 0 { + // Check if the operation is a create, by checking whether lastObj's UID is empty. + // If the operation is create, P(tracking managed fields) = f.probability + // If the operation is update, skip tracking managed fields, since we already know managed fields is empty. + if len(accessor.GetUID()) == 0 { + if f.probability <= rand.Float32() { + return newObj, managed, nil + } + } else { + return newObj, managed, nil + } + } + return f.fieldManager.Update(liveObj, newObj, managed, manager) +} + +// Apply implements Manager. +func (f *skipNonAppliedManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) { + if len(managed.Fields()) == 0 { + emptyObj, err := f.objectCreater.New(f.gvk) + if err != nil { + return nil, nil, fmt.Errorf("failed to create empty object of type %v: %v", f.gvk, err) + } + liveObj, managed, err = f.fieldManager.Update(emptyObj, liveObj, managed, f.beforeApplyManagerName) + if err != nil { + return nil, nil, fmt.Errorf("failed to create manager for existing fields: %v", err) + } + } + return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go new file mode 100644 index 00000000000..9b61f3a6f35 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go @@ -0,0 +1,90 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +type stripMetaManager struct { + fieldManager Manager + + // stripSet is the list of fields that should never be part of a mangedFields. + stripSet *fieldpath.Set +} + +var _ Manager = &stripMetaManager{} + +// NewStripMetaManager creates a new Manager that strips metadata and typemeta fields from the manager's fieldset. +func NewStripMetaManager(fieldManager Manager) Manager { + return &stripMetaManager{ + fieldManager: fieldManager, + stripSet: fieldpath.NewSet( + fieldpath.MakePathOrDie("apiVersion"), + fieldpath.MakePathOrDie("kind"), + fieldpath.MakePathOrDie("metadata"), + fieldpath.MakePathOrDie("metadata", "name"), + fieldpath.MakePathOrDie("metadata", "namespace"), + fieldpath.MakePathOrDie("metadata", "creationTimestamp"), + fieldpath.MakePathOrDie("metadata", "selfLink"), + fieldpath.MakePathOrDie("metadata", "uid"), + fieldpath.MakePathOrDie("metadata", "clusterName"), + fieldpath.MakePathOrDie("metadata", "generation"), + fieldpath.MakePathOrDie("metadata", "managedFields"), + fieldpath.MakePathOrDie("metadata", "resourceVersion"), + ), + } +} + +// Update implements Manager. +func (f *stripMetaManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + newObj, managed, err := f.fieldManager.Update(liveObj, newObj, managed, manager) + if err != nil { + return nil, nil, err + } + f.stripFields(managed.Fields(), manager) + return newObj, managed, nil +} + +// Apply implements Manager. +func (f *stripMetaManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) { + newObj, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force) + if err != nil { + return nil, nil, err + } + f.stripFields(managed.Fields(), manager) + return newObj, managed, nil +} + +// stripFields removes a predefined set of paths found in typed from managed +func (f *stripMetaManager) stripFields(managed fieldpath.ManagedFields, manager string) { + vs, ok := managed[manager] + if ok { + if vs == nil { + panic(fmt.Sprintf("Found unexpected nil manager which should never happen: %s", manager)) + } + newSet := vs.Set().Difference(f.stripSet) + if newSet.Empty() { + delete(managed, manager) + } else { + managed[manager] = fieldpath.NewVersionedSet(newSet, vs.APIVersion(), vs.Applied()) + } + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go new file mode 100644 index 00000000000..eb5598ac3bf --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go @@ -0,0 +1,183 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" +) + +type structuredMergeManager struct { + typeConverter TypeConverter + objectConverter runtime.ObjectConvertor + objectDefaulter runtime.ObjectDefaulter + groupVersion schema.GroupVersion + hubVersion schema.GroupVersion + updater merge.Updater +} + +var _ Manager = &structuredMergeManager{} + +// NewStructuredMergeManager creates a new Manager that merges apply requests +// and update managed fields for other types of requests. +func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (Manager, error) { + return &structuredMergeManager{ + typeConverter: typeConverter, + objectConverter: objectConverter, + objectDefaulter: objectDefaulter, + groupVersion: gv, + hubVersion: hub, + updater: merge.Updater{ + Converter: newVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s + IgnoredFields: resetFields, + }, + }, nil +} + +// NewCRDStructuredMergeManager creates a new Manager specifically for +// CRDs. This allows for the possibility of fields which are not defined +// in models, as well as having no models defined at all. +func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ Manager, err error) { + return &structuredMergeManager{ + typeConverter: typeConverter, + objectConverter: objectConverter, + objectDefaulter: objectDefaulter, + groupVersion: gv, + hubVersion: hub, + updater: merge.Updater{ + Converter: newCRDVersionConverter(typeConverter, objectConverter, hub), + IgnoredFields: resetFields, + }, + }, nil +} + +func objectGVKNN(obj runtime.Object) string { + name := "" + namespace := "" + if accessor, err := meta.Accessor(obj); err == nil { + name = accessor.GetName() + namespace = accessor.GetNamespace() + } + + return fmt.Sprintf("%v/%v; %v", namespace, name, obj.GetObjectKind().GroupVersionKind()) +} + +// Update implements Manager. +func (f *structuredMergeManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) { + newObjVersioned, err := f.toVersioned(newObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert new object (%v) to proper version (%v): %v", objectGVKNN(newObj), f.groupVersion, err) + } + liveObjVersioned, err := f.toVersioned(liveObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert live object (%v) to proper version: %v", objectGVKNN(liveObj), err) + } + newObjTyped, err := f.typeConverter.ObjectToTyped(newObjVersioned) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert new object (%v) to smd typed: %v", objectGVKNN(newObjVersioned), err) + } + liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert live object (%v) to smd typed: %v", objectGVKNN(liveObjVersioned), err) + } + apiVersion := fieldpath.APIVersion(f.groupVersion.String()) + + // TODO(apelisse) use the first return value when unions are implemented + _, managedFields, err := f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed.Fields(), manager) + if err != nil { + return nil, nil, fmt.Errorf("failed to update ManagedFields (%v): %v", objectGVKNN(newObjVersioned), err) + } + managed = NewManaged(managedFields, managed.Times()) + + return newObj, managed, nil +} + +// Apply implements Manager. +func (f *structuredMergeManager) Apply(liveObj, patchObj runtime.Object, managed Managed, manager string, force bool) (runtime.Object, Managed, error) { + // Check that the patch object has the same version as the live object + if patchVersion := patchObj.GetObjectKind().GroupVersionKind().GroupVersion(); patchVersion != f.groupVersion { + return nil, nil, + errors.NewBadRequest( + fmt.Sprintf("Incorrect version specified in apply patch. "+ + "Specified patch version: %s, expected: %s", + patchVersion, f.groupVersion)) + } + + patchObjMeta, err := meta.Accessor(patchObj) + if err != nil { + return nil, nil, fmt.Errorf("couldn't get accessor: %v", err) + } + if patchObjMeta.GetManagedFields() != nil { + return nil, nil, errors.NewBadRequest("metadata.managedFields must be nil") + } + + liveObjVersioned, err := f.toVersioned(liveObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert live object (%v) to proper version: %v", objectGVKNN(liveObj), err) + } + + patchObjTyped, err := f.typeConverter.ObjectToTyped(patchObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to create typed patch object (%v): %v", objectGVKNN(patchObj), err) + } + liveObjTyped, err := f.typeConverter.ObjectToTyped(liveObjVersioned) + if err != nil { + return nil, nil, fmt.Errorf("failed to create typed live object (%v): %v", objectGVKNN(liveObjVersioned), err) + } + + apiVersion := fieldpath.APIVersion(f.groupVersion.String()) + newObjTyped, managedFields, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed.Fields(), manager, force) + if err != nil { + return nil, nil, err + } + managed = NewManaged(managedFields, managed.Times()) + + if newObjTyped == nil { + return nil, managed, nil + } + + newObj, err := f.typeConverter.TypedToObject(newObjTyped) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert new typed object (%v) to object: %v", objectGVKNN(patchObj), err) + } + + newObjVersioned, err := f.toVersioned(newObj) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert new object (%v) to proper version: %v", objectGVKNN(patchObj), err) + } + f.objectDefaulter.Default(newObjVersioned) + + newObjUnversioned, err := f.toUnversioned(newObjVersioned) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert to unversioned (%v): %v", objectGVKNN(patchObj), err) + } + return newObjUnversioned, managed, nil +} + +func (f *structuredMergeManager) toVersioned(obj runtime.Object) (runtime.Object, error) { + return f.objectConverter.ConvertToVersion(obj, f.groupVersion) +} + +func (f *structuredMergeManager) toUnversioned(obj runtime.Object) (runtime.Object, error) { + return f.objectConverter.ConvertToVersion(obj, f.hubVersion) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go new file mode 100644 index 00000000000..1ac96d7f7bd --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go @@ -0,0 +1,193 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kube-openapi/pkg/schemaconv" + "k8s.io/kube-openapi/pkg/validation/spec" + smdschema "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/typed" + "sigs.k8s.io/structured-merge-diff/v4/value" +) + +// TypeConverter allows you to convert from runtime.Object to +// typed.TypedValue and the other way around. +type TypeConverter interface { + ObjectToTyped(runtime.Object) (*typed.TypedValue, error) + TypedToObject(*typed.TypedValue) (runtime.Object, error) +} + +type typeConverter struct { + parser map[schema.GroupVersionKind]*typed.ParseableType +} + +var _ TypeConverter = &typeConverter{} + +func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) { + typeSchema, err := schemaconv.ToSchemaFromOpenAPI(openapiSpec, preserveUnknownFields) + if err != nil { + return nil, fmt.Errorf("failed to convert models to schema: %v", err) + } + + typeParser := typed.Parser{Schema: smdschema.Schema{Types: typeSchema.Types}} + tr := indexModels(&typeParser, openapiSpec) + + return &typeConverter{parser: tr}, nil +} + +func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { + gvk := obj.GetObjectKind().GroupVersionKind() + t := c.parser[gvk] + if t == nil { + return nil, NewNoCorrespondingTypeError(gvk) + } + switch o := obj.(type) { + case *unstructured.Unstructured: + return t.FromUnstructured(o.UnstructuredContent()) + default: + return t.FromStructured(obj) + } +} + +func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { + return valueToObject(value.AsValue()) +} + +type deducedTypeConverter struct{} + +// DeducedTypeConverter is a TypeConverter for CRDs that don't have a +// schema. It does implement the same interface though (and create the +// same types of objects), so that everything can still work the same. +// CRDs are merged with all their fields being "atomic" (lists +// included). +func NewDeducedTypeConverter() TypeConverter { + return deducedTypeConverter{} +} + +// ObjectToTyped converts an object into a TypedValue with a "deduced type". +func (deducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { + switch o := obj.(type) { + case *unstructured.Unstructured: + return typed.DeducedParseableType.FromUnstructured(o.UnstructuredContent()) + default: + return typed.DeducedParseableType.FromStructured(obj) + } +} + +// TypedToObject transforms the typed value into a runtime.Object. That +// is not specific to deduced type. +func (deducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { + return valueToObject(value.AsValue()) +} + +func valueToObject(val value.Value) (runtime.Object, error) { + vu := val.Unstructured() + switch o := vu.(type) { + case map[string]interface{}: + return &unstructured.Unstructured{Object: o}, nil + default: + return nil, fmt.Errorf("failed to convert value to unstructured for type %T", vu) + } +} + +func indexModels( + typeParser *typed.Parser, + openAPISchemas map[string]*spec.Schema, +) map[schema.GroupVersionKind]*typed.ParseableType { + tr := map[schema.GroupVersionKind]*typed.ParseableType{} + for modelName, model := range openAPISchemas { + gvkList := parseGroupVersionKind(model.Extensions) + if len(gvkList) == 0 { + continue + } + + parsedType := typeParser.Type(modelName) + for _, gvk := range gvkList { + if len(gvk.Kind) > 0 { + tr[schema.GroupVersionKind(gvk)] = &parsedType + } + } + } + return tr +} + +// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one. +func parseGroupVersionKind(extensions map[string]interface{}) []schema.GroupVersionKind { + gvkListResult := []schema.GroupVersionKind{} + + // Get the extensions + gvkExtension, ok := extensions["x-kubernetes-group-version-kind"] + if !ok { + return []schema.GroupVersionKind{} + } + + // gvk extension must be a list of at least 1 element. + gvkList, ok := gvkExtension.([]interface{}) + if !ok { + return []schema.GroupVersionKind{} + } + + for _, gvk := range gvkList { + var group, version, kind string + + // gvk extension list must be a map with group, version, and + // kind fields + if gvkMap, ok := gvk.(map[interface{}]interface{}); ok { + group, ok = gvkMap["group"].(string) + if !ok { + continue + } + version, ok = gvkMap["version"].(string) + if !ok { + continue + } + kind, ok = gvkMap["kind"].(string) + if !ok { + continue + } + + } else if gvkMap, ok := gvk.(map[string]interface{}); ok { + group, ok = gvkMap["group"].(string) + if !ok { + continue + } + version, ok = gvkMap["version"].(string) + if !ok { + continue + } + kind, ok = gvkMap["kind"].(string) + if !ok { + continue + } + } else { + continue + } + + gvkListResult = append(gvkListResult, schema.GroupVersionKind{ + Group: group, + Version: version, + Kind: kind, + }) + } + + return gvkListResult +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go new file mode 100644 index 00000000000..45855fa4ca2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go @@ -0,0 +1,123 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/merge" + "sigs.k8s.io/structured-merge-diff/v4/typed" +) + +// versionConverter is an implementation of +// sigs.k8s.io/structured-merge-diff/merge.Converter +type versionConverter struct { + typeConverter TypeConverter + objectConvertor runtime.ObjectConvertor + hubGetter func(from schema.GroupVersion) schema.GroupVersion +} + +var _ merge.Converter = &versionConverter{} + +// NewVersionConverter builds a VersionConverter from a TypeConverter and an ObjectConvertor. +func newVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { + return &versionConverter{ + typeConverter: t, + objectConvertor: o, + hubGetter: func(from schema.GroupVersion) schema.GroupVersion { + return schema.GroupVersion{ + Group: from.Group, + Version: h.Version, + } + }, + } +} + +// NewCRDVersionConverter builds a VersionConverter for CRDs from a TypeConverter and an ObjectConvertor. +func newCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema.GroupVersion) merge.Converter { + return &versionConverter{ + typeConverter: t, + objectConvertor: o, + hubGetter: func(from schema.GroupVersion) schema.GroupVersion { + return h + }, + } +} + +// Convert implements sigs.k8s.io/structured-merge-diff/merge.Converter +func (v *versionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) { + // Convert the smd typed value to a kubernetes object. + objectToConvert, err := v.typeConverter.TypedToObject(object) + if err != nil { + return object, err + } + + // Parse the target groupVersion. + groupVersion, err := schema.ParseGroupVersion(string(version)) + if err != nil { + return object, err + } + + // If attempting to convert to the same version as we already have, just return it. + fromVersion := objectToConvert.GetObjectKind().GroupVersionKind().GroupVersion() + if fromVersion == groupVersion { + return object, nil + } + + // Convert to internal + internalObject, err := v.objectConvertor.ConvertToVersion(objectToConvert, v.hubGetter(fromVersion)) + if err != nil { + return object, err + } + + // Convert the object into the target version + convertedObject, err := v.objectConvertor.ConvertToVersion(internalObject, groupVersion) + if err != nil { + return object, err + } + + // Convert the object back to a smd typed value and return it. + return v.typeConverter.ObjectToTyped(convertedObject) +} + +// IsMissingVersionError +func (v *versionConverter) IsMissingVersionError(err error) bool { + return runtime.IsNotRegisteredError(err) || isNoCorrespondingTypeError(err) +} + +type noCorrespondingTypeErr struct { + gvk schema.GroupVersionKind +} + +func NewNoCorrespondingTypeError(gvk schema.GroupVersionKind) error { + return &noCorrespondingTypeErr{gvk: gvk} +} + +func (k *noCorrespondingTypeErr) Error() string { + return fmt.Sprintf("no corresponding type for %v", k.gvk) +} + +func isNoCorrespondingTypeError(err error) bool { + if err == nil { + return false + } + _, ok := err.(*noCorrespondingTypeErr) + return ok +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml new file mode 100644 index 00000000000..66e849f23fb --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml @@ -0,0 +1,261 @@ +apiVersion: v1 +kind: Node +metadata: + annotations: + container.googleapis.com/instance_id: "123456789321654789" + node.alpha.kubernetes.io/ttl: "0" + volumes.kubernetes.io/controller-managed-attach-detach: "true" + creationTimestamp: "2019-07-09T16:17:29Z" + labels: + kubernetes.io/arch: amd64 + beta.kubernetes.io/fluentd-ds-ready: "true" + beta.kubernetes.io/instance-type: n1-standard-4 + kubernetes.io/os: linux + cloud.google.com/gke-nodepool: default-pool + cloud.google.com/gke-os-distribution: cos + failure-domain.beta.kubernetes.io/region: us-central1 + failure-domain.beta.kubernetes.io/zone: us-central1-b + topology.kubernetes.io/region: us-central1 + topology.kubernetes.io/zone: us-central1-b + kubernetes.io/hostname: node-default-pool-something + name: node-default-pool-something + resourceVersion: "211582541" + selfLink: /api/v1/nodes/node-default-pool-something + uid: 0c24d0e1-a265-11e9-abe4-42010a80026b +spec: + podCIDR: 10.0.0.1/24 + providerID: some-provider-id-of-some-sort +status: + addresses: + - address: 10.0.0.1 + type: InternalIP + - address: 192.168.0.1 + type: ExternalIP + - address: node-default-pool-something + type: Hostname + allocatable: + cpu: 3920m + ephemeral-storage: "104638878617" + hugepages-2Mi: "0" + memory: 12700100Ki + pods: "110" + capacity: + cpu: "4" + ephemeral-storage: 202086868Ki + hugepages-2Mi: "0" + memory: 15399364Ki + pods: "110" + conditions: + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:08Z" + message: containerd is functioning properly + reason: FrequentContainerdRestart + status: "False" + type: FrequentContainerdRestart + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: docker overlay2 is functioning properly + reason: CorruptDockerOverlay2 + status: "False" + type: CorruptDockerOverlay2 + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: node is functioning properly + reason: UnregisterNetDevice + status: "False" + type: FrequentUnregisterNetDevice + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:17:04Z" + message: kernel has no deadlock + reason: KernelHasNoDeadlock + status: "False" + type: KernelDeadlock + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:17:04Z" + message: Filesystem is not read-only + reason: FilesystemIsNotReadOnly + status: "False" + type: ReadonlyFilesystem + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:05Z" + message: kubelet is functioning properly + reason: FrequentKubeletRestart + status: "False" + type: FrequentKubeletRestart + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: docker is functioning properly + reason: FrequentDockerRestart + status: "False" + type: FrequentDockerRestart + - lastHeartbeatTime: "2019-07-09T16:17:47Z" + lastTransitionTime: "2019-07-09T16:17:47Z" + message: RouteController created a route + reason: RouteCreated + status: "False" + type: NetworkUnavailable + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient disk space available + reason: KubeletHasSufficientDisk + status: "False" + type: OutOfDisk + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient memory available + reason: KubeletHasSufficientMemory + status: "False" + type: MemoryPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has no disk pressure + reason: KubeletHasNoDiskPressure + status: "False" + type: DiskPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient PID available + reason: KubeletHasSufficientPID + status: "False" + type: PIDPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:49Z" + message: kubelet is posting ready status. AppArmor enabled + reason: KubeletReady + status: "True" + type: Ready + daemonEndpoints: + kubeletEndpoint: + Port: 10250 + images: + - names: + - grafana/grafana@sha256:80e5e113a984d74836aa16f5b4524012099436b1a50df293f00ac6377fb512c8 + - grafana/grafana:4.4.2 + sizeBytes: 287008013 + - names: + - registry.k8s.io/node-problem-detector@sha256:f95cab985c26b2f46e9bd43283e0bfa88860c14e0fb0649266babe8b65e9eb2b + - registry.k8s.io/node-problem-detector:v0.4.1 + sizeBytes: 286572743 + - names: + - grafana/grafana@sha256:7ff7f9b2501a5d55b55ce3f58d21771b1c5af1f2a4ab7dbf11bef7142aae7033 + - grafana/grafana:4.2.0 + sizeBytes: 277940263 + - names: + - influxdb@sha256:7dddf03376348876ed4bdf33d6dfa3326f45a2bae0930dbd80781a374eb519bc + - influxdb:1.2.2 + sizeBytes: 223948571 + - names: + - gcr.io/stackdriver-agents/stackdriver-logging-agent@sha256:f8d5231b67b9c53f60068b535a11811d29d1b3efd53d2b79f2a2591ea338e4f2 + - gcr.io/stackdriver-agents/stackdriver-logging-agent:0.6-1.6.0-1 + sizeBytes: 223242132 + - names: + - nginx@sha256:35779791c05d119df4fe476db8f47c0bee5943c83eba5656a15fc046db48178b + - nginx:1.10.1 + sizeBytes: 180708613 + - names: + - registry.k8s.io/fluentd-elasticsearch@sha256:b8c94527b489fb61d3d81ce5ad7f3ddbb7be71e9620a3a36e2bede2f2e487d73 + - registry.k8s.io/fluentd-elasticsearch:v2.0.4 + sizeBytes: 135716379 + - names: + - nginx@sha256:00be67d6ba53d5318cd91c57771530f5251cfbe028b7be2c4b70526f988cfc9f + - nginx:latest + sizeBytes: 109357355 + - names: + - registry.k8s.io/kubernetes-dashboard-amd64@sha256:dc4026c1b595435ef5527ca598e1e9c4343076926d7d62b365c44831395adbd0 + - registry.k8s.io/kubernetes-dashboard-amd64:v1.8.3 + sizeBytes: 102319441 + - names: + - gcr.io/google_containers/kube-proxy:v1.11.10-gke.5 + - registry.k8s.io/kube-proxy:v1.11.10-gke.5 + sizeBytes: 102279340 + - names: + - registry.k8s.io/event-exporter@sha256:7f9cd7cb04d6959b0aa960727d04fa86759008048c785397b7b0d9dff0007516 + - registry.k8s.io/event-exporter:v0.2.3 + sizeBytes: 94171943 + - names: + - registry.k8s.io/prometheus-to-sd@sha256:6c0c742475363d537ff059136e5d5e4ab1f512ee0fd9b7ca42ea48bc309d1662 + - registry.k8s.io/prometheus-to-sd:v0.3.1 + sizeBytes: 88077694 + - names: + - registry.k8s.io/fluentd-gcp-scaler@sha256:a5ace7506d393c4ed65eb2cbb6312c64ab357fcea16dff76b9055bc6e498e5ff + - registry.k8s.io/fluentd-gcp-scaler:0.5.1 + sizeBytes: 86637208 + - names: + - registry.k8s.io/heapster-amd64@sha256:9fae0af136ce0cf4f88393b3670f7139ffc464692060c374d2ae748e13144521 + - registry.k8s.io/heapster-amd64:v1.6.0-beta.1 + sizeBytes: 76016169 + - names: + - registry.k8s.io/ingress-glbc-amd64@sha256:31d36bbd9c44caffa135fc78cf0737266fcf25e3cf0cd1c2fcbfbc4f7309cc52 + - registry.k8s.io/ingress-glbc-amd64:v1.1.1 + sizeBytes: 67801919 + - names: + - registry.k8s.io/kube-addon-manager@sha256:d53486c3a0b49ebee019932878dc44232735d5622a51dbbdcec7124199020d09 + - registry.k8s.io/kube-addon-manager:v8.7 + sizeBytes: 63322109 + - names: + - nginx@sha256:4aacdcf186934dcb02f642579314075910f1855590fd3039d8fa4c9f96e48315 + - nginx:1.10-alpine + sizeBytes: 54042627 + - names: + - registry.k8s.io/cpvpa-amd64@sha256:cfe7b0a11c9c8e18c87b1eb34fef9a7cbb8480a8da11fc2657f78dbf4739f869 + - registry.k8s.io/cpvpa-amd64:v0.6.0 + sizeBytes: 51785854 + - names: + - registry.k8s.io/cluster-proportional-autoscaler-amd64@sha256:003f98d9f411ddfa6ff6d539196355e03ddd69fa4ed38c7ffb8fec6f729afe2d + - registry.k8s.io/cluster-proportional-autoscaler-amd64:1.1.2-r2 + sizeBytes: 49648481 + - names: + - registry.k8s.io/ip-masq-agent-amd64@sha256:1ffda57d87901bc01324c82ceb2145fe6a0448d3f0dd9cb65aa76a867cd62103 + - registry.k8s.io/ip-masq-agent-amd64:v2.1.1 + sizeBytes: 49612505 + - names: + - registry.k8s.io/k8s-dns-kube-dns-amd64@sha256:b99fc3eee2a9f052f7eb4cc00f15eb12fc405fa41019baa2d6b79847ae7284a8 + - registry.k8s.io/k8s-dns-kube-dns-amd64:1.14.10 + sizeBytes: 49549457 + - names: + - registry.k8s.io/rescheduler@sha256:156cfbfd05a5a815206fd2eeb6cbdaf1596d71ea4b415d3a6c43071dd7b99450 + - registry.k8s.io/rescheduler:v0.4.0 + sizeBytes: 48973149 + - names: + - registry.k8s.io/event-exporter@sha256:16ca66e2b5dc7a1ce6a5aafcb21d0885828b75cdfc08135430480f7ad2364adc + - registry.k8s.io/event-exporter:v0.2.4 + sizeBytes: 47261019 + - names: + - registry.k8s.io/coredns@sha256:db2bf53126ed1c761d5a41f24a1b82a461c85f736ff6e90542e9522be4757848 + - registry.k8s.io/coredns:1.1.3 + sizeBytes: 45587362 + - names: + - prom/prometheus@sha256:483f4c9d7733699ba79facca9f8bcce1cef1af43dfc3e7c5a1882aa85f53cb74 + - prom/prometheus:v1.1.3 + sizeBytes: 45493941 + nodeInfo: + architecture: amd64 + bootID: a32eca78-4ad4-4b76-9252-f143d6c2ae61 + containerRuntimeVersion: docker://17.3.2 + kernelVersion: 4.14.127+ + kubeProxyVersion: v1.11.10-gke.5 + kubeletVersion: v1.11.10-gke.5 + machineID: 1739555e5b231057f0f9a0b5fa29511b + operatingSystem: linux + osImage: Container-Optimized OS from Google + systemUUID: 1739555E-5B23-1057-F0F9-A0B5FA29511B + volumesAttached: + - devicePath: /dev/disk/by-id/b9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 + - devicePath: /dev/disk/by-id/b9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + volumesInUse: + - kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + - kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml new file mode 100644 index 00000000000..3fb0877d67c --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml @@ -0,0 +1,121 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app: some-app + plugin1: some-value + plugin2: some-value + plugin3: some-value + plugin4: some-value + name: some-name + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: some-name + uid: 0a9d2b9e-779e-11e7-b422-42010a8001be +spec: + containers: + - args: + - one + - two + - three + - four + - five + - six + - seven + - eight + - nine + env: + - name: VAR_3 + valueFrom: + secretKeyRef: + key: some-other-key + name: some-oher-name + - name: VAR_2 + valueFrom: + secretKeyRef: + key: other-key + name: other-name + - name: VAR_1 + valueFrom: + secretKeyRef: + key: some-key + name: some-name + image: some-image-name + imagePullPolicy: IfNotPresent + name: some-name + resources: + requests: + cpu: '0' + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: default-token-hu5jz + readOnly: true + dnsPolicy: ClusterFirst + nodeName: node-name + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: default-token-hu5jz + secret: + defaultMode: 420 + secretName: default-token-hu5jz +status: + conditions: + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:31:18Z' + status: 'True' + type: Initialized + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:41:59Z' + status: 'True' + type: Ready + - lastProbeTime: null + lastTransitionTime: null + status: 'True' + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:31:18Z' + status: 'True' + type: PodScheduled + containerStatuses: + - containerID: docker://885e82a1ed0b7356541bb410a0126921ac42439607c09875cd8097dd5d7b5376 + image: some-image-name + imageID: docker-pullable://some-image-id + lastState: + terminated: + containerID: docker://d57290f9e00fad626b20d2dd87a3cf69bbc22edae07985374f86a8b2b4e39565 + exitCode: 255 + finishedAt: '2019-07-08T09:39:09Z' + reason: Error + startedAt: '2019-07-08T09:38:54Z' + name: name + ready: true + restartCount: 6 + state: + running: + startedAt: '2019-07-08T09:41:59Z' + hostIP: 10.0.0.1 + phase: Running + podIP: 10.0.0.1 + qosClass: BestEffort + startTime: '2019-07-08T09:31:18Z' diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go new file mode 100644 index 00000000000..48b774cece2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go @@ -0,0 +1,174 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package managedfields + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/managedfields/internal" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +var ( + scaleGroupVersion = schema.GroupVersion{Group: "autoscaling", Version: "v1"} + replicasPathInScale = fieldpath.MakePathOrDie("spec", "replicas") +) + +// ResourcePathMappings maps a group/version to its replicas path. The +// assumption is that all the paths correspond to leaf fields. +type ResourcePathMappings map[string]fieldpath.Path + +// ScaleHandler manages the conversion of managed fields between a main +// resource and the scale subresource +type ScaleHandler struct { + parentEntries []metav1.ManagedFieldsEntry + groupVersion schema.GroupVersion + mappings ResourcePathMappings +} + +// NewScaleHandler creates a new ScaleHandler +func NewScaleHandler(parentEntries []metav1.ManagedFieldsEntry, groupVersion schema.GroupVersion, mappings ResourcePathMappings) *ScaleHandler { + return &ScaleHandler{ + parentEntries: parentEntries, + groupVersion: groupVersion, + mappings: mappings, + } +} + +// ToSubresource filter the managed fields of the main resource and convert +// them so that they can be handled by scale. +// For the managed fields that have a replicas path it performs two changes: +// 1. APIVersion is changed to the APIVersion of the scale subresource +// 2. Replicas path of the main resource is transformed to the replicas path of +// the scale subresource +func (h *ScaleHandler) ToSubresource() ([]metav1.ManagedFieldsEntry, error) { + managed, err := internal.DecodeManagedFields(h.parentEntries) + if err != nil { + return nil, err + } + + f := fieldpath.ManagedFields{} + t := map[string]*metav1.Time{} + for manager, versionedSet := range managed.Fields() { + path, ok := h.mappings[string(versionedSet.APIVersion())] + // Skip the entry if the APIVersion is unknown + if !ok || path == nil { + continue + } + + if versionedSet.Set().Has(path) { + newVersionedSet := fieldpath.NewVersionedSet( + fieldpath.NewSet(replicasPathInScale), + fieldpath.APIVersion(scaleGroupVersion.String()), + versionedSet.Applied(), + ) + + f[manager] = newVersionedSet + t[manager] = managed.Times()[manager] + } + } + + return managedFieldsEntries(internal.NewManaged(f, t)) +} + +// ToParent merges `scaleEntries` with the entries of the main resource and +// transforms them accordingly +func (h *ScaleHandler) ToParent(scaleEntries []metav1.ManagedFieldsEntry) ([]metav1.ManagedFieldsEntry, error) { + decodedParentEntries, err := internal.DecodeManagedFields(h.parentEntries) + if err != nil { + return nil, err + } + parentFields := decodedParentEntries.Fields() + + decodedScaleEntries, err := internal.DecodeManagedFields(scaleEntries) + if err != nil { + return nil, err + } + scaleFields := decodedScaleEntries.Fields() + + f := fieldpath.ManagedFields{} + t := map[string]*metav1.Time{} + + for manager, versionedSet := range parentFields { + // Get the main resource "replicas" path + path, ok := h.mappings[string(versionedSet.APIVersion())] + // Drop the entry if the APIVersion is unknown. + if !ok { + continue + } + + // If the parent entry does not have the replicas path or it is nil, just + // keep it as it is. The path is nil for Custom Resources without scale + // subresource. + if path == nil || !versionedSet.Set().Has(path) { + f[manager] = versionedSet + t[manager] = decodedParentEntries.Times()[manager] + continue + } + + if _, ok := scaleFields[manager]; !ok { + // "Steal" the replicas path from the main resource entry + newSet := versionedSet.Set().Difference(fieldpath.NewSet(path)) + + if !newSet.Empty() { + newVersionedSet := fieldpath.NewVersionedSet( + newSet, + versionedSet.APIVersion(), + versionedSet.Applied(), + ) + f[manager] = newVersionedSet + t[manager] = decodedParentEntries.Times()[manager] + } + } else { + // Field wasn't stolen, let's keep the entry as it is. + f[manager] = versionedSet + t[manager] = decodedParentEntries.Times()[manager] + delete(scaleFields, manager) + } + } + + for manager, versionedSet := range scaleFields { + if !versionedSet.Set().Has(replicasPathInScale) { + continue + } + newVersionedSet := fieldpath.NewVersionedSet( + fieldpath.NewSet(h.mappings[h.groupVersion.String()]), + fieldpath.APIVersion(h.groupVersion.String()), + versionedSet.Applied(), + ) + f[manager] = newVersionedSet + t[manager] = decodedParentEntries.Times()[manager] + } + + return managedFieldsEntries(internal.NewManaged(f, t)) +} + +func managedFieldsEntries(entries internal.ManagedInterface) ([]metav1.ManagedFieldsEntry, error) { + obj := &unstructured.Unstructured{Object: map[string]interface{}{}} + if err := internal.EncodeObjectManagedFields(obj, entries); err != nil { + return nil, err + } + accessor, err := meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + return accessor.GetManagedFields(), nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go new file mode 100644 index 00000000000..d031eefaa3a --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go @@ -0,0 +1,47 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package managedfields + +import ( + "k8s.io/apimachinery/pkg/util/managedfields/internal" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// TypeConverter allows you to convert from runtime.Object to +// typed.TypedValue and the other way around. +type TypeConverter = internal.TypeConverter + +// NewDeducedTypeConverter creates a TypeConverter for CRDs that don't +// have a schema. It does implement the same interface though (and +// create the same types of objects), so that everything can still work +// the same. CRDs are merged with all their fields being "atomic" (lists +// included). +func NewDeducedTypeConverter() TypeConverter { + return internal.NewDeducedTypeConverter() +} + +// NewTypeConverter builds a TypeConverter from a map of OpenAPIV3 schemas. +// This will automatically find the proper version of the object, and the +// corresponding schema information. +// The keys to the map must be consistent with the names +// used by Refs within the schemas. +// The schemas should conform to the Kubernetes Structural Schema OpenAPI +// restrictions found in docs: +// https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema +func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) { + return internal.NewTypeConverter(openapiSpec, preserveUnknownFields) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go index 990fa0d43a6..a20efd18715 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go +++ b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go @@ -88,7 +88,7 @@ func toYAML(v interface{}) (string, error) { // supports JSON merge patch semantics. // // NOTE: Numbers with different types (e.g. int(0) vs int64(0)) will be detected as conflicts. -// Make sure the unmarshaling of left and right are consistent (e.g. use the same library). +// Make sure the unmarshaling of left and right are consistent (e.g. use the same library). func HasConflicts(left, right interface{}) (bool, error) { switch typedLeft := left.(type) { case map[string]interface{}: diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/interface.go b/vendor/k8s.io/apimachinery/pkg/util/net/interface.go index 82241680648..01d028e727d 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/net/interface.go +++ b/vendor/k8s.io/apimachinery/pkg/util/net/interface.go @@ -339,7 +339,7 @@ func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFam for _, addr := range addrs { ip, _, err := netutils.ParseCIDRSloppy(addr.String()) if err != nil { - return nil, fmt.Errorf("Unable to parse CIDR for interface %q: %s", intf.Name, err) + return nil, fmt.Errorf("unable to parse CIDR for interface %q: %s", intf.Name, err) } if !memberOf(ip, family) { klog.V(4).Infof("Skipping: no address family match for %q on interface %q.", ip, intf.Name) diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/port_split.go b/vendor/k8s.io/apimachinery/pkg/util/net/port_split.go index c0fd4e20fe5..f54bb1e71c9 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/net/port_split.go +++ b/vendor/k8s.io/apimachinery/pkg/util/net/port_split.go @@ -25,9 +25,9 @@ import ( var validSchemes = sets.NewString("http", "https", "") // SplitSchemeNamePort takes a string of the following forms: -// * "", returns "", "","", true -// * ":", returns "", "","",true -// * "::", returns "","","",true +// - "", returns "", "","", true +// - ":", returns "", "","",true +// - "::", returns "","","",true // // Name must be non-empty or valid will be returned false. // Scheme must be "http" or "https" if specified @@ -57,9 +57,10 @@ func SplitSchemeNamePort(id string) (scheme, name, port string, valid bool) { } // JoinSchemeNamePort returns a string that specifies the scheme, name, and port: -// * "" -// * ":" -// * "::" +// - "" +// - ":" +// - "::" +// // None of the parameters may contain a ':' character // Name is required // Scheme must be "", "http", or "https" diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/util.go b/vendor/k8s.io/apimachinery/pkg/util/net/util.go index 5950087e022..1c2aba55f7b 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/net/util.go +++ b/vendor/k8s.io/apimachinery/pkg/util/net/util.go @@ -25,6 +25,7 @@ import ( // IPNetEqual checks if the two input IPNets are representing the same subnet. // For example, +// // 10.0.0.1/24 and 10.0.0.0/24 are the same subnet. // 10.0.0.1/24 and 10.0.0.0/25 are not the same subnet. func IPNetEqual(ipnet1, ipnet2 *net.IPNet) bool { diff --git a/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go new file mode 100644 index 00000000000..82a473bb146 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go @@ -0,0 +1,127 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package rand provides utilities related to randomization. +package rand + +import ( + "math/rand" + "sync" + "time" +) + +var rng = struct { + sync.Mutex + rand *rand.Rand +}{ + rand: rand.New(rand.NewSource(time.Now().UnixNano())), +} + +// Int returns a non-negative pseudo-random int. +func Int() int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int() +} + +// Intn generates an integer in range [0,max). +// By design this should panic if input is invalid, <= 0. +func Intn(max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max) +} + +// IntnRange generates an integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func IntnRange(min, max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max-min) + min +} + +// IntnRange generates an int64 integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func Int63nRange(min, max int64) int64 { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int63n(max-min) + min +} + +// Seed seeds the rng with the provided seed. +func Seed(seed int64) { + rng.Lock() + defer rng.Unlock() + + rng.rand = rand.New(rand.NewSource(seed)) +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n) +// from the default Source. +func Perm(n int) []int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Perm(n) +} + +const ( + // We omit vowels from the set of available characters to reduce the chances + // of "bad words" being formed. + alphanums = "bcdfghjklmnpqrstvwxz2456789" + // No. of bits required to index into alphanums string. + alphanumsIdxBits = 5 + // Mask used to extract last alphanumsIdxBits of an int. + alphanumsIdxMask = 1<>= alphanumsIdxBits + remaining-- + } + return string(b) +} + +// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and +// ensures that strings generated from hash functions appear consistent throughout the API. +func SafeEncodeString(s string) string { + r := make([]byte, len(s)) + for i, b := range []rune(s) { + r[i] = alphanums[(int(b) % len(alphanums))] + } + return string(r) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go index 9f834fa538d..d738725caf0 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go +++ b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go @@ -142,7 +142,7 @@ func GetCaller() string { runtime.Callers(3, pc[:]) f := runtime.FuncForPC(pc[0]) if f == nil { - return fmt.Sprintf("Unable to find caller") + return "Unable to find caller" } return f.Name() } diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/byte.go b/vendor/k8s.io/apimachinery/pkg/util/sets/byte.go index 9bfa85d43d4..4d7a17c3afa 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/byte.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/byte.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,93 +14,75 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets -import ( - "reflect" - "sort" -) - -// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption. +// Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption. +// +// Deprecated: use generic Set instead. +// new ways: +// s1 := Set[byte]{} +// s2 := New[byte]() type Byte map[byte]Empty // NewByte creates a Byte from a list of values. func NewByte(items ...byte) Byte { - ss := Byte{} - ss.Insert(items...) - return ss + return Byte(New[byte](items...)) } // ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}). // If the value passed in is not actually a map, this will panic. -func ByteKeySet(theMap interface{}) Byte { - v := reflect.ValueOf(theMap) - ret := Byte{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(byte)) - } - return ret +func ByteKeySet[T any](theMap map[byte]T) Byte { + return Byte(KeySet(theMap)) } // Insert adds items to the set. func (s Byte) Insert(items ...byte) Byte { - for _, item := range items { - s[item] = Empty{} - } - return s + return Byte(cast(s).Insert(items...)) } // Delete removes all items from the set. func (s Byte) Delete(items ...byte) Byte { - for _, item := range items { - delete(s, item) - } - return s + return Byte(cast(s).Delete(items...)) } // Has returns true if and only if item is contained in the set. func (s Byte) Has(item byte) bool { - _, contained := s[item] - return contained + return cast(s).Has(item) } // HasAll returns true if and only if all items are contained in the set. func (s Byte) HasAll(items ...byte) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true + return cast(s).HasAll(items...) } // HasAny returns true if any items are contained in the set. func (s Byte) HasAny(items ...byte) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return cast(s).HasAny(items...) } -// Difference returns a set of objects that are not in s2 +// Clone returns a new set which is a copy of the current set. +func (s Byte) Clone() Byte { + return Byte(cast(s).Clone()) +} + +// Difference returns a set of objects that are not in s2. // For example: // s1 = {a1, a2, a3} // s2 = {a1, a2, a4, a5} // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5} -func (s Byte) Difference(s2 Byte) Byte { - result := NewByte() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result +func (s1 Byte) Difference(s2 Byte) Byte { + return Byte(cast(s1).Difference(cast(s2))) +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 Byte) SymmetricDifference(s2 Byte) Byte { + return Byte(cast(s1).SymmetricDifference(cast(s2))) } // Union returns a new set which includes items in either s1 or s2. @@ -110,14 +92,7 @@ func (s Byte) Difference(s2 Byte) Byte { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4} func (s1 Byte) Union(s2 Byte) Byte { - result := NewByte() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result + return Byte(cast(s1).Union(cast(s2))) } // Intersection returns a new set which includes the item in BOTH s1 and s2 @@ -126,80 +101,37 @@ func (s1 Byte) Union(s2 Byte) Byte { // s2 = {a2, a3} // s1.Intersection(s2) = {a2} func (s1 Byte) Intersection(s2 Byte) Byte { - var walk, other Byte - result := NewByte() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result + return Byte(cast(s1).Intersection(cast(s2))) } // IsSuperset returns true if and only if s1 is a superset of s2. func (s1 Byte) IsSuperset(s2 Byte) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true + return cast(s1).IsSuperset(cast(s2)) } // Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 Byte) Equal(s2 Byte) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) + return cast(s1).Equal(cast(s2)) } -type sortableSliceOfByte []byte - -func (s sortableSliceOfByte) Len() int { return len(s) } -func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) } -func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - // List returns the contents as a sorted byte slice. func (s Byte) List() []byte { - res := make(sortableSliceOfByte, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []byte(res) + return List(cast(s)) } // UnsortedList returns the slice with contents in random order. func (s Byte) UnsortedList() []byte { - res := make([]byte, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res + return cast(s).UnsortedList() } -// Returns a single element from the set. +// PopAny returns a single element from the set. func (s Byte) PopAny() (byte, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue byte - return zeroValue, false + return cast(s).PopAny() } // Len returns the size of the set. func (s Byte) Len() int { return len(s) } - -func lessByte(lhs, rhs byte) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go b/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go index b152a0bf00f..194883390cf 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - -// Package sets has auto-generated set types. +// Package sets has generic set and specified sets. Generic set will +// replace specified ones over time. And specific ones are deprecated. package sets diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/empty.go b/vendor/k8s.io/apimachinery/pkg/util/sets/empty.go index e11e622c5ba..fbb1df06d92 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/empty.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/empty.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets // Empty is public since it is used by some internal API objects for conversions between external diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/int.go b/vendor/k8s.io/apimachinery/pkg/util/sets/int.go index 88bd7096791..5876fc9deb9 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/int.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/int.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,93 +14,75 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets -import ( - "reflect" - "sort" -) - -// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption. +// Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption. +// +// Deprecated: use generic Set instead. +// new ways: +// s1 := Set[int]{} +// s2 := New[int]() type Int map[int]Empty // NewInt creates a Int from a list of values. func NewInt(items ...int) Int { - ss := Int{} - ss.Insert(items...) - return ss + return Int(New[int](items...)) } // IntKeySet creates a Int from a keys of a map[int](? extends interface{}). // If the value passed in is not actually a map, this will panic. -func IntKeySet(theMap interface{}) Int { - v := reflect.ValueOf(theMap) - ret := Int{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(int)) - } - return ret +func IntKeySet[T any](theMap map[int]T) Int { + return Int(KeySet(theMap)) } // Insert adds items to the set. func (s Int) Insert(items ...int) Int { - for _, item := range items { - s[item] = Empty{} - } - return s + return Int(cast(s).Insert(items...)) } // Delete removes all items from the set. func (s Int) Delete(items ...int) Int { - for _, item := range items { - delete(s, item) - } - return s + return Int(cast(s).Delete(items...)) } // Has returns true if and only if item is contained in the set. func (s Int) Has(item int) bool { - _, contained := s[item] - return contained + return cast(s).Has(item) } // HasAll returns true if and only if all items are contained in the set. func (s Int) HasAll(items ...int) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true + return cast(s).HasAll(items...) } // HasAny returns true if any items are contained in the set. func (s Int) HasAny(items ...int) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return cast(s).HasAny(items...) } -// Difference returns a set of objects that are not in s2 +// Clone returns a new set which is a copy of the current set. +func (s Int) Clone() Int { + return Int(cast(s).Clone()) +} + +// Difference returns a set of objects that are not in s2. // For example: // s1 = {a1, a2, a3} // s2 = {a1, a2, a4, a5} // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5} -func (s Int) Difference(s2 Int) Int { - result := NewInt() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result +func (s1 Int) Difference(s2 Int) Int { + return Int(cast(s1).Difference(cast(s2))) +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 Int) SymmetricDifference(s2 Int) Int { + return Int(cast(s1).SymmetricDifference(cast(s2))) } // Union returns a new set which includes items in either s1 or s2. @@ -110,14 +92,7 @@ func (s Int) Difference(s2 Int) Int { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4} func (s1 Int) Union(s2 Int) Int { - result := NewInt() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result + return Int(cast(s1).Union(cast(s2))) } // Intersection returns a new set which includes the item in BOTH s1 and s2 @@ -126,80 +101,37 @@ func (s1 Int) Union(s2 Int) Int { // s2 = {a2, a3} // s1.Intersection(s2) = {a2} func (s1 Int) Intersection(s2 Int) Int { - var walk, other Int - result := NewInt() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result + return Int(cast(s1).Intersection(cast(s2))) } // IsSuperset returns true if and only if s1 is a superset of s2. func (s1 Int) IsSuperset(s2 Int) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true + return cast(s1).IsSuperset(cast(s2)) } // Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 Int) Equal(s2 Int) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) + return cast(s1).Equal(cast(s2)) } -type sortableSliceOfInt []int - -func (s sortableSliceOfInt) Len() int { return len(s) } -func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) } -func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - // List returns the contents as a sorted int slice. func (s Int) List() []int { - res := make(sortableSliceOfInt, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []int(res) + return List(cast(s)) } // UnsortedList returns the slice with contents in random order. func (s Int) UnsortedList() []int { - res := make([]int, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res + return cast(s).UnsortedList() } -// Returns a single element from the set. +// PopAny returns a single element from the set. func (s Int) PopAny() (int, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue int - return zeroValue, false + return cast(s).PopAny() } // Len returns the size of the set. func (s Int) Len() int { return len(s) } - -func lessInt(lhs, rhs int) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/int32.go b/vendor/k8s.io/apimachinery/pkg/util/sets/int32.go index 96a48555426..2c640c5d0f1 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/int32.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/int32.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,93 +14,75 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets -import ( - "reflect" - "sort" -) - -// sets.Int32 is a set of int32s, implemented via map[int32]struct{} for minimal memory consumption. +// Int32 is a set of int32s, implemented via map[int32]struct{} for minimal memory consumption. +// +// Deprecated: use generic Set instead. +// new ways: +// s1 := Set[int32]{} +// s2 := New[int32]() type Int32 map[int32]Empty // NewInt32 creates a Int32 from a list of values. func NewInt32(items ...int32) Int32 { - ss := Int32{} - ss.Insert(items...) - return ss + return Int32(New[int32](items...)) } // Int32KeySet creates a Int32 from a keys of a map[int32](? extends interface{}). // If the value passed in is not actually a map, this will panic. -func Int32KeySet(theMap interface{}) Int32 { - v := reflect.ValueOf(theMap) - ret := Int32{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(int32)) - } - return ret +func Int32KeySet[T any](theMap map[int32]T) Int32 { + return Int32(KeySet(theMap)) } // Insert adds items to the set. func (s Int32) Insert(items ...int32) Int32 { - for _, item := range items { - s[item] = Empty{} - } - return s + return Int32(cast(s).Insert(items...)) } // Delete removes all items from the set. func (s Int32) Delete(items ...int32) Int32 { - for _, item := range items { - delete(s, item) - } - return s + return Int32(cast(s).Delete(items...)) } // Has returns true if and only if item is contained in the set. func (s Int32) Has(item int32) bool { - _, contained := s[item] - return contained + return cast(s).Has(item) } // HasAll returns true if and only if all items are contained in the set. func (s Int32) HasAll(items ...int32) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true + return cast(s).HasAll(items...) } // HasAny returns true if any items are contained in the set. func (s Int32) HasAny(items ...int32) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return cast(s).HasAny(items...) } -// Difference returns a set of objects that are not in s2 +// Clone returns a new set which is a copy of the current set. +func (s Int32) Clone() Int32 { + return Int32(cast(s).Clone()) +} + +// Difference returns a set of objects that are not in s2. // For example: // s1 = {a1, a2, a3} // s2 = {a1, a2, a4, a5} // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5} -func (s Int32) Difference(s2 Int32) Int32 { - result := NewInt32() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result +func (s1 Int32) Difference(s2 Int32) Int32 { + return Int32(cast(s1).Difference(cast(s2))) +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 Int32) SymmetricDifference(s2 Int32) Int32 { + return Int32(cast(s1).SymmetricDifference(cast(s2))) } // Union returns a new set which includes items in either s1 or s2. @@ -110,14 +92,7 @@ func (s Int32) Difference(s2 Int32) Int32 { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4} func (s1 Int32) Union(s2 Int32) Int32 { - result := NewInt32() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result + return Int32(cast(s1).Union(cast(s2))) } // Intersection returns a new set which includes the item in BOTH s1 and s2 @@ -126,80 +101,37 @@ func (s1 Int32) Union(s2 Int32) Int32 { // s2 = {a2, a3} // s1.Intersection(s2) = {a2} func (s1 Int32) Intersection(s2 Int32) Int32 { - var walk, other Int32 - result := NewInt32() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result + return Int32(cast(s1).Intersection(cast(s2))) } // IsSuperset returns true if and only if s1 is a superset of s2. func (s1 Int32) IsSuperset(s2 Int32) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true + return cast(s1).IsSuperset(cast(s2)) } // Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 Int32) Equal(s2 Int32) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) + return cast(s1).Equal(cast(s2)) } -type sortableSliceOfInt32 []int32 - -func (s sortableSliceOfInt32) Len() int { return len(s) } -func (s sortableSliceOfInt32) Less(i, j int) bool { return lessInt32(s[i], s[j]) } -func (s sortableSliceOfInt32) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - // List returns the contents as a sorted int32 slice. func (s Int32) List() []int32 { - res := make(sortableSliceOfInt32, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []int32(res) + return List(cast(s)) } // UnsortedList returns the slice with contents in random order. func (s Int32) UnsortedList() []int32 { - res := make([]int32, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res + return cast(s).UnsortedList() } -// Returns a single element from the set. +// PopAny returns a single element from the set. func (s Int32) PopAny() (int32, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue int32 - return zeroValue, false + return cast(s).PopAny() } // Len returns the size of the set. func (s Int32) Len() int { return len(s) } - -func lessInt32(lhs, rhs int32) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/int64.go b/vendor/k8s.io/apimachinery/pkg/util/sets/int64.go index b375a1b065c..bf3eb3ffa25 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/int64.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/int64.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,93 +14,75 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets -import ( - "reflect" - "sort" -) - -// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption. +// Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption. +// +// Deprecated: use generic Set instead. +// new ways: +// s1 := Set[int64]{} +// s2 := New[int64]() type Int64 map[int64]Empty // NewInt64 creates a Int64 from a list of values. func NewInt64(items ...int64) Int64 { - ss := Int64{} - ss.Insert(items...) - return ss + return Int64(New[int64](items...)) } // Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}). // If the value passed in is not actually a map, this will panic. -func Int64KeySet(theMap interface{}) Int64 { - v := reflect.ValueOf(theMap) - ret := Int64{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(int64)) - } - return ret +func Int64KeySet[T any](theMap map[int64]T) Int64 { + return Int64(KeySet(theMap)) } // Insert adds items to the set. func (s Int64) Insert(items ...int64) Int64 { - for _, item := range items { - s[item] = Empty{} - } - return s + return Int64(cast(s).Insert(items...)) } // Delete removes all items from the set. func (s Int64) Delete(items ...int64) Int64 { - for _, item := range items { - delete(s, item) - } - return s + return Int64(cast(s).Delete(items...)) } // Has returns true if and only if item is contained in the set. func (s Int64) Has(item int64) bool { - _, contained := s[item] - return contained + return cast(s).Has(item) } // HasAll returns true if and only if all items are contained in the set. func (s Int64) HasAll(items ...int64) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true + return cast(s).HasAll(items...) } // HasAny returns true if any items are contained in the set. func (s Int64) HasAny(items ...int64) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return cast(s).HasAny(items...) } -// Difference returns a set of objects that are not in s2 +// Clone returns a new set which is a copy of the current set. +func (s Int64) Clone() Int64 { + return Int64(cast(s).Clone()) +} + +// Difference returns a set of objects that are not in s2. // For example: // s1 = {a1, a2, a3} // s2 = {a1, a2, a4, a5} // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5} -func (s Int64) Difference(s2 Int64) Int64 { - result := NewInt64() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result +func (s1 Int64) Difference(s2 Int64) Int64 { + return Int64(cast(s1).Difference(cast(s2))) +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 Int64) SymmetricDifference(s2 Int64) Int64 { + return Int64(cast(s1).SymmetricDifference(cast(s2))) } // Union returns a new set which includes items in either s1 or s2. @@ -110,14 +92,7 @@ func (s Int64) Difference(s2 Int64) Int64 { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4} func (s1 Int64) Union(s2 Int64) Int64 { - result := NewInt64() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result + return Int64(cast(s1).Union(cast(s2))) } // Intersection returns a new set which includes the item in BOTH s1 and s2 @@ -126,80 +101,37 @@ func (s1 Int64) Union(s2 Int64) Int64 { // s2 = {a2, a3} // s1.Intersection(s2) = {a2} func (s1 Int64) Intersection(s2 Int64) Int64 { - var walk, other Int64 - result := NewInt64() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result + return Int64(cast(s1).Intersection(cast(s2))) } // IsSuperset returns true if and only if s1 is a superset of s2. func (s1 Int64) IsSuperset(s2 Int64) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true + return cast(s1).IsSuperset(cast(s2)) } // Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 Int64) Equal(s2 Int64) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) + return cast(s1).Equal(cast(s2)) } -type sortableSliceOfInt64 []int64 - -func (s sortableSliceOfInt64) Len() int { return len(s) } -func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) } -func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - // List returns the contents as a sorted int64 slice. func (s Int64) List() []int64 { - res := make(sortableSliceOfInt64, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []int64(res) + return List(cast(s)) } // UnsortedList returns the slice with contents in random order. func (s Int64) UnsortedList() []int64 { - res := make([]int64, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res + return cast(s).UnsortedList() } -// Returns a single element from the set. +// PopAny returns a single element from the set. func (s Int64) PopAny() (int64, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue int64 - return zeroValue, false + return cast(s).PopAny() } // Len returns the size of the set. func (s Int64) Len() int { return len(s) } - -func lessInt64(lhs, rhs int64) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go b/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go new file mode 100644 index 00000000000..443dac62eb3 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go @@ -0,0 +1,53 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sets + +// ordered is a constraint that permits any ordered type: any type +// that supports the operators < <= >= >. +// If future releases of Go add new ordered types, +// this constraint will be modified to include them. +type ordered interface { + integer | float | ~string +} + +// integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type integer interface { + signed | unsigned +} + +// float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type float interface { + ~float32 | ~float64 +} + +// signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/set.go b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go new file mode 100644 index 00000000000..d50526f4262 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go @@ -0,0 +1,241 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sets + +import ( + "sort" +) + +// Set is a set of the same type elements, implemented via map[comparable]struct{} for minimal memory consumption. +type Set[T comparable] map[T]Empty + +// cast transforms specified set to generic Set[T]. +func cast[T comparable](s map[T]Empty) Set[T] { return s } + +// New creates a Set from a list of values. +// NOTE: type param must be explicitly instantiated if given items are empty. +func New[T comparable](items ...T) Set[T] { + ss := make(Set[T], len(items)) + ss.Insert(items...) + return ss +} + +// KeySet creates a Set from a keys of a map[comparable](? extends interface{}). +// If the value passed in is not actually a map, this will panic. +func KeySet[T comparable, V any](theMap map[T]V) Set[T] { + ret := Set[T]{} + for keyValue := range theMap { + ret.Insert(keyValue) + } + return ret +} + +// Insert adds items to the set. +func (s Set[T]) Insert(items ...T) Set[T] { + for _, item := range items { + s[item] = Empty{} + } + return s +} + +func Insert[T comparable](set Set[T], items ...T) Set[T] { + return set.Insert(items...) +} + +// Delete removes all items from the set. +func (s Set[T]) Delete(items ...T) Set[T] { + for _, item := range items { + delete(s, item) + } + return s +} + +// Clear empties the set. +// It is preferable to replace the set with a newly constructed set, +// but not all callers can do that (when there are other references to the map). +// In some cases the set *won't* be fully cleared, e.g. a Set[float32] containing NaN +// can't be cleared because NaN can't be removed. +// For sets containing items of a type that is reflexive for ==, +// this is optimized to a single call to runtime.mapclear(). +func (s Set[T]) Clear() Set[T] { + for key := range s { + delete(s, key) + } + return s +} + +// Has returns true if and only if item is contained in the set. +func (s Set[T]) Has(item T) bool { + _, contained := s[item] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s Set[T]) HasAll(items ...T) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// HasAny returns true if any items are contained in the set. +func (s Set[T]) HasAny(items ...T) bool { + for _, item := range items { + if s.Has(item) { + return true + } + } + return false +} + +// Clone returns a new set which is a copy of the current set. +func (s Set[T]) Clone() Set[T] { + result := make(Set[T], len(s)) + for key := range s { + result.Insert(key) + } + return result +} + +// Difference returns a set of objects that are not in s2. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s1 Set[T]) Difference(s2 Set[T]) Set[T] { + result := New[T]() + for key := range s1 { + if !s2.Has(key) { + result.Insert(key) + } + } + return result +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] { + return s1.Difference(s2).Union(s2.Difference(s1)) +} + +// Union returns a new set which includes items in either s1 or s2. +// For example: +// s1 = {a1, a2} +// s2 = {a3, a4} +// s1.Union(s2) = {a1, a2, a3, a4} +// s2.Union(s1) = {a1, a2, a3, a4} +func (s1 Set[T]) Union(s2 Set[T]) Set[T] { + result := s1.Clone() + for key := range s2 { + result.Insert(key) + } + return result +} + +// Intersection returns a new set which includes the item in BOTH s1 and s2 +// For example: +// s1 = {a1, a2} +// s2 = {a2, a3} +// s1.Intersection(s2) = {a2} +func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] { + var walk, other Set[T] + result := New[T]() + if s1.Len() < s2.Len() { + walk = s1 + other = s2 + } else { + walk = s2 + other = s1 + } + for key := range walk { + if other.Has(key) { + result.Insert(key) + } + } + return result +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 Set[T]) IsSuperset(s2 Set[T]) bool { + for item := range s2 { + if !s1.Has(item) { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 Set[T]) Equal(s2 Set[T]) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +type sortableSliceOfGeneric[T ordered] []T + +func (g sortableSliceOfGeneric[T]) Len() int { return len(g) } +func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) } +func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i] } + +// List returns the contents as a sorted T slice. +// +// This is a separate function and not a method because not all types supported +// by Generic are ordered and only those can be sorted. +func List[T ordered](s Set[T]) []T { + res := make(sortableSliceOfGeneric[T], 0, len(s)) + for key := range s { + res = append(res, key) + } + sort.Sort(res) + return res +} + +// UnsortedList returns the slice with contents in random order. +func (s Set[T]) UnsortedList() []T { + res := make([]T, 0, len(s)) + for key := range s { + res = append(res, key) + } + return res +} + +// PopAny returns a single element from the set. +func (s Set[T]) PopAny() (T, bool) { + for key := range s { + s.Delete(key) + return key, true + } + var zeroValue T + return zeroValue, false +} + +// Len returns the size of the set. +func (s Set[T]) Len() int { + return len(s) +} + +func less[T ordered](lhs, rhs T) bool { + return lhs < rhs +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/string.go b/vendor/k8s.io/apimachinery/pkg/util/sets/string.go index e6f37db8874..1dab6d13cc7 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/string.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/string.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,93 +14,75 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - package sets -import ( - "reflect" - "sort" -) - -// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. +// String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. +// +// Deprecated: use generic Set instead. +// new ways: +// s1 := Set[string]{} +// s2 := New[string]() type String map[string]Empty // NewString creates a String from a list of values. func NewString(items ...string) String { - ss := String{} - ss.Insert(items...) - return ss + return String(New[string](items...)) } // StringKeySet creates a String from a keys of a map[string](? extends interface{}). // If the value passed in is not actually a map, this will panic. -func StringKeySet(theMap interface{}) String { - v := reflect.ValueOf(theMap) - ret := String{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(string)) - } - return ret +func StringKeySet[T any](theMap map[string]T) String { + return String(KeySet(theMap)) } // Insert adds items to the set. func (s String) Insert(items ...string) String { - for _, item := range items { - s[item] = Empty{} - } - return s + return String(cast(s).Insert(items...)) } // Delete removes all items from the set. func (s String) Delete(items ...string) String { - for _, item := range items { - delete(s, item) - } - return s + return String(cast(s).Delete(items...)) } // Has returns true if and only if item is contained in the set. func (s String) Has(item string) bool { - _, contained := s[item] - return contained + return cast(s).Has(item) } // HasAll returns true if and only if all items are contained in the set. func (s String) HasAll(items ...string) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true + return cast(s).HasAll(items...) } // HasAny returns true if any items are contained in the set. func (s String) HasAny(items ...string) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false + return cast(s).HasAny(items...) } -// Difference returns a set of objects that are not in s2 +// Clone returns a new set which is a copy of the current set. +func (s String) Clone() String { + return String(cast(s).Clone()) +} + +// Difference returns a set of objects that are not in s2. // For example: // s1 = {a1, a2, a3} // s2 = {a1, a2, a4, a5} // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5} -func (s String) Difference(s2 String) String { - result := NewString() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result +func (s1 String) Difference(s2 String) String { + return String(cast(s1).Difference(cast(s2))) +} + +// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.SymmetricDifference(s2) = {a3, a4, a5} +// s2.SymmetricDifference(s1) = {a3, a4, a5} +func (s1 String) SymmetricDifference(s2 String) String { + return String(cast(s1).SymmetricDifference(cast(s2))) } // Union returns a new set which includes items in either s1 or s2. @@ -110,14 +92,7 @@ func (s String) Difference(s2 String) String { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4} func (s1 String) Union(s2 String) String { - result := NewString() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result + return String(cast(s1).Union(cast(s2))) } // Intersection returns a new set which includes the item in BOTH s1 and s2 @@ -126,80 +101,37 @@ func (s1 String) Union(s2 String) String { // s2 = {a2, a3} // s1.Intersection(s2) = {a2} func (s1 String) Intersection(s2 String) String { - var walk, other String - result := NewString() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result + return String(cast(s1).Intersection(cast(s2))) } // IsSuperset returns true if and only if s1 is a superset of s2. func (s1 String) IsSuperset(s2 String) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true + return cast(s1).IsSuperset(cast(s2)) } // Equal returns true if and only if s1 is equal (as a set) to s2. // Two sets are equal if their membership is identical. // (In practice, this means same elements, order doesn't matter) func (s1 String) Equal(s2 String) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) + return cast(s1).Equal(cast(s2)) } -type sortableSliceOfString []string - -func (s sortableSliceOfString) Len() int { return len(s) } -func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) } -func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - // List returns the contents as a sorted string slice. func (s String) List() []string { - res := make(sortableSliceOfString, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []string(res) + return List(cast(s)) } // UnsortedList returns the slice with contents in random order. func (s String) UnsortedList() []string { - res := make([]string, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res + return cast(s).UnsortedList() } -// Returns a single element from the set. +// PopAny returns a single element from the set. func (s String) PopAny() (string, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue string - return zeroValue, false + return cast(s).PopAny() } // Len returns the size of the set. func (s String) Len() int { return len(s) } - -func lessString(lhs, rhs string) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS index 4443bafd137..73244449f2c 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS @@ -1,6 +1,7 @@ # See the OWNERS docs at https://go.k8s.io/owners approvers: + - apelisse - pwittrock reviewers: - apelisse diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go index d49a56536c3..df305b712c5 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go @@ -105,7 +105,7 @@ func (s PatchMetaFromStruct) LookupPatchMetadataForSlice(key string) (LookupPatc // If the underlying element is neither an array nor a slice, the pointer is pointing to a slice, // e.g. https://github.com/kubernetes/kubernetes/blob/bc22e206c79282487ea0bf5696d5ccec7e839a76/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go#L2782-L2822 // If the underlying element is either an array or a slice, return its element type. - case reflect.Ptr: + case reflect.Pointer: t = t.Elem() if t.Kind() == reflect.Array || t.Kind() == reflect.Slice { t = t.Elem() @@ -129,7 +129,7 @@ func getTagStructType(dataStruct interface{}) (reflect.Type, error) { t := reflect.TypeOf(dataStruct) // Get the underlying type for pointers - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go index 6fb36973213..3ee683b9970 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go @@ -1106,7 +1106,7 @@ func applyRetainKeysDirective(original, patch map[string]interface{}, options Me // Then, sort them by the relative order in setElementOrder, patch list and live list. // The precedence is $setElementOrder > order in patch list > order in live list. // This function will delete the item after merging it to prevent process it again in the future. -// Ref: https://git.k8s.io/community/contributors/design-proposals/cli/preserve-order-in-strategic-merge-patch.md +// Ref: https://git.k8s.io/design-proposals-archive/cli/preserve-order-in-strategic-merge-patch.md func mergePatchIntoOriginal(original, patch map[string]interface{}, schema LookupPatchMeta, mergeOptions MergeOptions) error { for key, patchV := range patch { // Do nothing if there is no ordering directive diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go index b7abf39b5d5..ae73bda9666 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go @@ -42,9 +42,9 @@ func (v *Error) Error() string { return fmt.Sprintf("%s: %s", v.Field, v.ErrorBody()) } -type omitValueType struct{} +type OmitValueType struct{} -var omitValue = omitValueType{} +var omitValue = OmitValueType{} // ErrorBody returns the error message without the field name. This is useful // for building nice-looking higher-level error reporting. @@ -66,7 +66,7 @@ func (v *Error) ErrorBody() string { valueType := reflect.TypeOf(value) if value == nil || valueType == nil { value = "null" - } else if valueType.Kind() == reflect.Ptr { + } else if valueType.Kind() == reflect.Pointer { if reflectValue := reflect.ValueOf(value); reflectValue.IsNil() { value = "null" } else { diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go index 83df4fb8d42..0b8a6cb354a 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go @@ -191,7 +191,13 @@ func IsDNS1123Label(value string) []string { errs = append(errs, MaxLenError(DNS1123LabelMaxLength)) } if !dns1123LabelRegexp.MatchString(value) { - errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc")) + if dns1123SubdomainRegexp.MatchString(value) { + // It was a valid subdomain and not a valid label. Since we + // already checked length, it must be dots. + errs = append(errs, "must not contain dots") + } else { + errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc")) + } } return errs } @@ -334,7 +340,7 @@ func IsValidPortName(port string) []string { errs = append(errs, "must contain only alpha-numeric characters (a-z, 0-9), and hyphens (-)") } if !portNameOneLetterRegexp.MatchString(port) { - errs = append(errs, "must contain at least one letter or number (a-z, 0-9)") + errs = append(errs, "must contain at least one letter (a-z)") } if strings.Contains(port, "--") { errs = append(errs, "must not contain consecutive hyphens") diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go new file mode 100644 index 00000000000..4187619256e --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go @@ -0,0 +1,502 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "context" + "math" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/utils/clock" +) + +// Backoff holds parameters applied to a Backoff function. +type Backoff struct { + // The initial duration. + Duration time.Duration + // Duration is multiplied by factor each iteration, if factor is not zero + // and the limits imposed by Steps and Cap have not been reached. + // Should not be negative. + // The jitter does not contribute to the updates to the duration parameter. + Factor float64 + // The sleep at each iteration is the duration plus an additional + // amount chosen uniformly at random from the interval between + // zero and `jitter*duration`. + Jitter float64 + // The remaining number of iterations in which the duration + // parameter may change (but progress can be stopped earlier by + // hitting the cap). If not positive, the duration is not + // changed. Used for exponential backoff in combination with + // Factor and Cap. + Steps int + // A limit on revised values of the duration parameter. If a + // multiplication by the factor parameter would make the duration + // exceed the cap then the duration is set to the cap and the + // steps parameter is set to zero. + Cap time.Duration +} + +// Step returns an amount of time to sleep determined by the original +// Duration and Jitter. The backoff is mutated to update its Steps and +// Duration. A nil Backoff always has a zero-duration step. +func (b *Backoff) Step() time.Duration { + if b == nil { + return 0 + } + var nextDuration time.Duration + nextDuration, b.Duration, b.Steps = delay(b.Steps, b.Duration, b.Cap, b.Factor, b.Jitter) + return nextDuration +} + +// DelayFunc returns a function that will compute the next interval to +// wait given the arguments in b. It does not mutate the original backoff +// but the function is safe to use only from a single goroutine. +func (b Backoff) DelayFunc() DelayFunc { + steps := b.Steps + duration := b.Duration + cap := b.Cap + factor := b.Factor + jitter := b.Jitter + + return func() time.Duration { + var nextDuration time.Duration + // jitter is applied per step and is not cumulative over multiple steps + nextDuration, duration, steps = delay(steps, duration, cap, factor, jitter) + return nextDuration + } +} + +// Timer returns a timer implementation appropriate to this backoff's parameters +// for use with wait functions. +func (b Backoff) Timer() Timer { + if b.Steps > 1 || b.Jitter != 0 { + return &variableTimer{new: internalClock.NewTimer, fn: b.DelayFunc()} + } + if b.Duration > 0 { + return &fixedTimer{new: internalClock.NewTicker, interval: b.Duration} + } + return newNoopTimer() +} + +// delay implements the core delay algorithm used in this package. +func delay(steps int, duration, cap time.Duration, factor, jitter float64) (_ time.Duration, next time.Duration, nextSteps int) { + // when steps is non-positive, do not alter the base duration + if steps < 1 { + if jitter > 0 { + return Jitter(duration, jitter), duration, 0 + } + return duration, duration, 0 + } + steps-- + + // calculate the next step's interval + if factor != 0 { + next = time.Duration(float64(duration) * factor) + if cap > 0 && next > cap { + next = cap + steps = 0 + } + } else { + next = duration + } + + // add jitter for this step + if jitter > 0 { + duration = Jitter(duration, jitter) + } + + return duration, next, steps + +} + +// DelayWithReset returns a DelayFunc that will return the appropriate next interval to +// wait. Every resetInterval the backoff parameters are reset to their initial state. +// This method is safe to invoke from multiple goroutines, but all calls will advance +// the backoff state when Factor is set. If Factor is zero, this method is the same as +// invoking b.DelayFunc() since Steps has no impact without Factor. If resetInterval is +// zero no backoff will be performed as the same calling DelayFunc with a zero factor +// and steps. +func (b Backoff) DelayWithReset(c clock.Clock, resetInterval time.Duration) DelayFunc { + if b.Factor <= 0 { + return b.DelayFunc() + } + if resetInterval <= 0 { + b.Steps = 0 + b.Factor = 0 + return b.DelayFunc() + } + return (&backoffManager{ + backoff: b, + initialBackoff: b, + resetInterval: resetInterval, + + clock: c, + lastStart: c.Now(), + timer: nil, + }).Step +} + +// Until loops until stop channel is closed, running f every period. +// +// Until is syntactic sugar on top of JitterUntil with zero jitter factor and +// with sliding = true (which means the timer for period starts after the f +// completes). +func Until(f func(), period time.Duration, stopCh <-chan struct{}) { + JitterUntil(f, period, 0.0, true, stopCh) +} + +// UntilWithContext loops until context is done, running f every period. +// +// UntilWithContext is syntactic sugar on top of JitterUntilWithContext +// with zero jitter factor and with sliding = true (which means the timer +// for period starts after the f completes). +func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { + JitterUntilWithContext(ctx, f, period, 0.0, true) +} + +// NonSlidingUntil loops until stop channel is closed, running f every +// period. +// +// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter +// factor, with sliding = false (meaning the timer for period starts at the same +// time as the function starts). +func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) { + JitterUntil(f, period, 0.0, false, stopCh) +} + +// NonSlidingUntilWithContext loops until context is done, running f every +// period. +// +// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext +// with zero jitter factor, with sliding = false (meaning the timer for period +// starts at the same time as the function starts). +func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { + JitterUntilWithContext(ctx, f, period, 0.0, false) +} + +// JitterUntil loops until stop channel is closed, running f every period. +// +// If jitterFactor is positive, the period is jittered before every run of f. +// If jitterFactor is not positive, the period is unchanged and not jittered. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +// +// Close stopCh to stop. f may not be invoked if stop channel is already +// closed. Pass NeverStop to if you don't want it stop. +func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { + BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh) +} + +// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) { + var t clock.Timer + for { + select { + case <-stopCh: + return + default: + } + + if !sliding { + t = backoff.Backoff() + } + + func() { + defer runtime.HandleCrash() + f() + }() + + if sliding { + t = backoff.Backoff() + } + + // NOTE: b/c there is no priority selection in golang + // it is possible for this to race, meaning we could + // trigger t.C and stopCh, and t.C select falls through. + // In order to mitigate we re-check stopCh at the beginning + // of every loop to prevent extra executions of f(). + select { + case <-stopCh: + if !t.Stop() { + <-t.C() + } + return + case <-t.C(): + } + } +} + +// JitterUntilWithContext loops until context is done, running f every period. +// +// If jitterFactor is positive, the period is jittered before every run of f. +// If jitterFactor is not positive, the period is unchanged and not jittered. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +// +// Cancel context to stop. f may not be invoked if context is already expired. +func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) { + JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done()) +} + +// backoffManager provides simple backoff behavior in a threadsafe manner to a caller. +type backoffManager struct { + backoff Backoff + initialBackoff Backoff + resetInterval time.Duration + + clock clock.Clock + + lock sync.Mutex + lastStart time.Time + timer clock.Timer +} + +// Step returns the expected next duration to wait. +func (b *backoffManager) Step() time.Duration { + b.lock.Lock() + defer b.lock.Unlock() + + switch { + case b.resetInterval == 0: + b.backoff = b.initialBackoff + case b.clock.Now().Sub(b.lastStart) > b.resetInterval: + b.backoff = b.initialBackoff + b.lastStart = b.clock.Now() + } + return b.backoff.Step() +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer +// for exponential backoff. The returned timer must be drained before calling Backoff() the second +// time. +func (b *backoffManager) Backoff() clock.Timer { + b.lock.Lock() + defer b.lock.Unlock() + if b.timer == nil { + b.timer = b.clock.NewTimer(b.Step()) + } else { + b.timer.Reset(b.Step()) + } + return b.timer +} + +// Timer returns a new Timer instance that shares the clock and the reset behavior with all other +// timers. +func (b *backoffManager) Timer() Timer { + return DelayFunc(b.Step).Timer(b.clock) +} + +// BackoffManager manages backoff with a particular scheme based on its underlying implementation. +type BackoffManager interface { + // Backoff returns a shared clock.Timer that is Reset on every invocation. This method is not + // safe for use from multiple threads. It returns a timer for backoff, and caller shall backoff + // until Timer.C() drains. If the second Backoff() is called before the timer from the first + // Backoff() call finishes, the first timer will NOT be drained and result in undetermined + // behavior. + Backoff() clock.Timer +} + +// Deprecated: Will be removed when the legacy polling functions are removed. +type exponentialBackoffManagerImpl struct { + backoff *Backoff + backoffTimer clock.Timer + lastBackoffStart time.Time + initialBackoff time.Duration + backoffResetDuration time.Duration + clock clock.Clock +} + +// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and +// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset. +// This backoff manager is used to reduce load during upstream unhealthiness. +// +// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a +// Backoff struct, use DelayWithReset() to get a DelayFunc that periodically resets itself, and then +// invoke Timer() when calling wait.BackoffUntil. +// +// Instead of: +// +// bm := wait.NewExponentialBackoffManager(init, max, reset, factor, jitter, clock) +// ... +// wait.BackoffUntil(..., bm.Backoff, ...) +// +// Use: +// +// delayFn := wait.Backoff{ +// Duration: init, +// Cap: max, +// Steps: int(math.Ceil(float64(max) / float64(init))), // now a required argument +// Factor: factor, +// Jitter: jitter, +// }.DelayWithReset(reset, clock) +// wait.BackoffUntil(..., delayFn.Timer(), ...) +func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager { + return &exponentialBackoffManagerImpl{ + backoff: &Backoff{ + Duration: initBackoff, + Factor: backoffFactor, + Jitter: jitter, + + // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not + // what we ideally need here, we set it to max int and assume we will never use up the steps + Steps: math.MaxInt32, + Cap: maxBackoff, + }, + backoffTimer: nil, + initialBackoff: initBackoff, + lastBackoffStart: c.Now(), + backoffResetDuration: resetDuration, + clock: c, + } +} + +func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration { + if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration { + b.backoff.Steps = math.MaxInt32 + b.backoff.Duration = b.initialBackoff + } + b.lastBackoffStart = b.clock.Now() + return b.backoff.Step() +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff. +// The returned timer must be drained before calling Backoff() the second time +func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer { + if b.backoffTimer == nil { + b.backoffTimer = b.clock.NewTimer(b.getNextBackoff()) + } else { + b.backoffTimer.Reset(b.getNextBackoff()) + } + return b.backoffTimer +} + +// Deprecated: Will be removed when the legacy polling functions are removed. +type jitteredBackoffManagerImpl struct { + clock clock.Clock + duration time.Duration + jitter float64 + backoffTimer clock.Timer +} + +// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter +// is negative, backoff will not be jittered. +// +// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a +// Backoff struct and invoke Timer() when calling wait.BackoffUntil. +// +// Instead of: +// +// bm := wait.NewJitteredBackoffManager(duration, jitter, clock) +// ... +// wait.BackoffUntil(..., bm.Backoff, ...) +// +// Use: +// +// wait.BackoffUntil(..., wait.Backoff{Duration: duration, Jitter: jitter}.Timer(), ...) +func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager { + return &jitteredBackoffManagerImpl{ + clock: c, + duration: duration, + jitter: jitter, + backoffTimer: nil, + } +} + +func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration { + jitteredPeriod := j.duration + if j.jitter > 0.0 { + jitteredPeriod = Jitter(j.duration, j.jitter) + } + return jitteredPeriod +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff. +// The returned timer must be drained before calling Backoff() the second time +func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer { + backoff := j.getNextBackoff() + if j.backoffTimer == nil { + j.backoffTimer = j.clock.NewTimer(backoff) + } else { + j.backoffTimer.Reset(backoff) + } + return j.backoffTimer +} + +// ExponentialBackoff repeats a condition check with exponential backoff. +// +// It repeatedly checks the condition and then sleeps, using `backoff.Step()` +// to determine the length of the sleep and adjust Duration and Steps. +// Stops and returns as soon as: +// 1. the condition check returns true or an error, +// 2. `backoff.Steps` checks of the condition have been done, or +// 3. a sleep truncated by the cap on duration has been completed. +// In case (1) the returned error is what the condition function returned. +// In all other cases, ErrWaitTimeout is returned. +// +// Since backoffs are often subject to cancellation, we recommend using +// ExponentialBackoffWithContext and passing a context to the method. +func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error { + for backoff.Steps > 0 { + if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { + return err + } + if backoff.Steps == 1 { + break + } + time.Sleep(backoff.Step()) + } + return ErrWaitTimeout +} + +// ExponentialBackoffWithContext repeats a condition check with exponential backoff. +// It immediately returns an error if the condition returns an error, the context is cancelled +// or hits the deadline, or if the maximum attempts defined in backoff is exceeded (ErrWaitTimeout). +// If an error is returned by the condition the backoff stops immediately. The condition will +// never be invoked more than backoff.Steps times. +func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionWithContextFunc) error { + for backoff.Steps > 0 { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + if ok, err := runConditionWithCrashProtectionWithContext(ctx, condition); err != nil || ok { + return err + } + + if backoff.Steps == 1 { + break + } + + waitBeforeRetry := backoff.Step() + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(waitBeforeRetry): + } + } + + return ErrWaitTimeout +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go new file mode 100644 index 00000000000..1d3dcaa74ec --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go @@ -0,0 +1,51 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "context" + "sync" + "time" + + "k8s.io/utils/clock" +) + +// DelayFunc returns the next time interval to wait. +type DelayFunc func() time.Duration + +// Timer takes an arbitrary delay function and returns a timer that can handle arbitrary interval changes. +// Use Backoff{...}.Timer() for simple delays and more efficient timers. +func (fn DelayFunc) Timer(c clock.Clock) Timer { + return &variableTimer{fn: fn, new: c.NewTimer} +} + +// Until takes an arbitrary delay function and runs until cancelled or the condition indicates exit. This +// offers all of the functionality of the methods in this package. +func (fn DelayFunc) Until(ctx context.Context, immediate, sliding bool, condition ConditionWithContextFunc) error { + return loopConditionUntilContext(ctx, &variableTimer{fn: fn, new: internalClock.NewTimer}, immediate, sliding, condition) +} + +// Concurrent returns a version of this DelayFunc that is safe for use by multiple goroutines that +// wish to share a single delay timer. +func (fn DelayFunc) Concurrent() DelayFunc { + var lock sync.Mutex + return func() time.Duration { + lock.Lock() + defer lock.Unlock() + return fn() + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/error.go b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go new file mode 100644 index 00000000000..dd75801d829 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go @@ -0,0 +1,96 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "context" + "errors" +) + +// ErrWaitTimeout is returned when the condition was not satisfied in time. +// +// Deprecated: This type will be made private in favor of Interrupted() +// for checking errors or ErrorInterrupted(err) for returning a wrapped error. +var ErrWaitTimeout = ErrorInterrupted(errors.New("timed out waiting for the condition")) + +// Interrupted returns true if the error indicates a Poll, ExponentialBackoff, or +// Until loop exited for any reason besides the condition returning true or an +// error. A loop is considered interrupted if the calling context is cancelled, +// the context reaches its deadline, or a backoff reaches its maximum allowed +// steps. +// +// Callers should use this method instead of comparing the error value directly to +// ErrWaitTimeout, as methods that cancel a context may not return that error. +// +// Instead of: +// +// err := wait.Poll(...) +// if err == wait.ErrWaitTimeout { +// log.Infof("Wait for operation exceeded") +// } else ... +// +// Use: +// +// err := wait.Poll(...) +// if wait.Interrupted(err) { +// log.Infof("Wait for operation exceeded") +// } else ... +func Interrupted(err error) bool { + switch { + case errors.Is(err, errWaitTimeout), + errors.Is(err, context.Canceled), + errors.Is(err, context.DeadlineExceeded): + return true + default: + return false + } +} + +// errInterrupted +type errInterrupted struct { + cause error +} + +// ErrorInterrupted returns an error that indicates the wait was ended +// early for a given reason. If no cause is provided a generic error +// will be used but callers are encouraged to provide a real cause for +// clarity in debugging. +func ErrorInterrupted(cause error) error { + switch cause.(type) { + case errInterrupted: + // no need to wrap twice since errInterrupted is only needed + // once in a chain + return cause + default: + return errInterrupted{cause} + } +} + +// errWaitTimeout is the private version of the previous ErrWaitTimeout +// and is private to prevent direct comparison. Use ErrorInterrupted(err) +// to get an error that will return true for Interrupted(err). +var errWaitTimeout = errInterrupted{} + +func (e errInterrupted) Unwrap() error { return e.cause } +func (e errInterrupted) Is(target error) bool { return target == errWaitTimeout } +func (e errInterrupted) Error() string { + if e.cause == nil { + // returns the same error message as historical behavior + return "timed out waiting for the condition" + } + return e.cause.Error() +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go new file mode 100644 index 00000000000..0dd13c626c8 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go @@ -0,0 +1,97 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "context" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// loopConditionUntilContext executes the provided condition at intervals defined by +// the provided timer until the provided context is cancelled, the condition returns +// true, or the condition returns an error. If sliding is true, the period is computed +// after condition runs. If it is false then period includes the runtime for condition. +// If immediate is false the first delay happens before any call to condition, if +// immediate is true the condition will be invoked before waiting and guarantees that +// the condition is invoked at least once, regardless of whether the context has been +// cancelled. The returned error is the error returned by the last condition or the +// context error if the context was terminated. +// +// This is the common loop construct for all polling in the wait package. +func loopConditionUntilContext(ctx context.Context, t Timer, immediate, sliding bool, condition ConditionWithContextFunc) error { + defer t.Stop() + + var timeCh <-chan time.Time + doneCh := ctx.Done() + + // if immediate is true the condition is + // guaranteed to be executed at least once, + // if we haven't requested immediate execution, delay once + if immediate { + if ok, err := func() (bool, error) { + defer runtime.HandleCrash() + return condition(ctx) + }(); err != nil || ok { + return err + } + } else { + timeCh = t.C() + select { + case <-doneCh: + return ctx.Err() + case <-timeCh: + } + } + + for { + // checking ctx.Err() is slightly faster than checking a select + if err := ctx.Err(); err != nil { + return err + } + + if !sliding { + t.Next() + } + if ok, err := func() (bool, error) { + defer runtime.HandleCrash() + return condition(ctx) + }(); err != nil || ok { + return err + } + if sliding { + t.Next() + } + + if timeCh == nil { + timeCh = t.C() + } + + // NOTE: b/c there is no priority selection in golang + // it is possible for this to race, meaning we could + // trigger t.C and doneCh, and t.C select falls through. + // In order to mitigate we re-check doneCh at the beginning + // of every loop to guarantee at-most one extra execution + // of condition. + select { + case <-doneCh: + return ctx.Err() + case <-timeCh: + } + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go new file mode 100644 index 00000000000..32e8688ca0f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go @@ -0,0 +1,315 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "context" + "time" +) + +// PollUntilContextCancel tries a condition func until it returns true, an error, or the context +// is cancelled or hits a deadline. condition will be invoked after the first interval if the +// context is not cancelled first. The returned error will be from ctx.Err(), the condition's +// err return value, or nil. If invoking condition takes longer than interval the next condition +// will be invoked immediately. When using very short intervals, condition may be invoked multiple +// times before a context cancellation is detected. If immediate is true, condition will be +// invoked before waiting and guarantees that condition is invoked at least once, regardless of +// whether the context has been cancelled. +func PollUntilContextCancel(ctx context.Context, interval time.Duration, immediate bool, condition ConditionWithContextFunc) error { + return loopConditionUntilContext(ctx, Backoff{Duration: interval}.Timer(), immediate, false, condition) +} + +// PollUntilContextTimeout will terminate polling after timeout duration by setting a context +// timeout. This is provided as a convenience function for callers not currently executing under +// a deadline and is equivalent to: +// +// deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) +// err := PollUntilContextCancel(ctx, interval, immediate, condition) +// +// The deadline context will be cancelled if the Poll succeeds before the timeout, simplifying +// inline usage. All other behavior is identical to PollWithContextTimeout. +func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duration, immediate bool, condition ConditionWithContextFunc) error { + deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) + defer deadlineCancel() + return loopConditionUntilContext(deadlineCtx, Backoff{Duration: interval}.Timer(), immediate, false, condition) +} + +// Poll tries a condition func until it returns true, an error, or the timeout +// is reached. +// +// Poll always waits the interval before the run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to Poll something forever, see PollInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func Poll(interval, timeout time.Duration, condition ConditionFunc) error { + return PollWithContext(context.Background(), interval, timeout, condition.WithContext()) +} + +// PollWithContext tries a condition func until it returns true, an error, +// or when the context expires or the timeout is reached, whichever +// happens first. +// +// PollWithContext always waits the interval before the run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to Poll something forever, see PollInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, timeout), condition) +} + +// PollUntil tries a condition func until it returns true, an error or stopCh is +// closed. +// +// PollUntil always waits interval before the first run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { + return PollUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext()) +} + +// PollUntilWithContext tries a condition func until it returns true, +// an error or the specified context is cancelled or expired. +// +// PollUntilWithContext always waits interval before the first run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, 0), condition) +} + +// PollInfinite tries a condition func until it returns true or an error +// +// PollInfinite always waits the interval before the run of 'condition'. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollInfinite(interval time.Duration, condition ConditionFunc) error { + return PollInfiniteWithContext(context.Background(), interval, condition.WithContext()) +} + +// PollInfiniteWithContext tries a condition func until it returns true or an error +// +// PollInfiniteWithContext always waits the interval before the run of 'condition'. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, 0), condition) +} + +// PollImmediate tries a condition func until it returns true, an error, or the timeout +// is reached. +// +// PollImmediate always checks 'condition' before waiting for the interval. 'condition' +// will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to immediately Poll something forever, see PollImmediateInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error { + return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext()) +} + +// PollImmediateWithContext tries a condition func until it returns true, an error, +// or the timeout is reached or the specified context expires, whichever happens first. +// +// PollImmediateWithContext always checks 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to immediately Poll something forever, see PollImmediateInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, timeout), condition) +} + +// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed. +// +// PollImmediateUntil runs the 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { + return PollImmediateUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext()) +} + +// PollImmediateUntilWithContext tries a condition func until it returns true, +// an error or the specified context is cancelled or expired. +// +// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, 0), condition) +} + +// PollImmediateInfinite tries a condition func until it returns true or an error +// +// PollImmediateInfinite runs the 'condition' before waiting for the interval. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error { + return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext()) +} + +// PollImmediateInfiniteWithContext tries a condition func until it returns true +// or an error or the specified context gets cancelled or expired. +// +// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, 0), condition) +} + +// Internally used, each of the public 'Poll*' function defined in this +// package should invoke this internal function with appropriate parameters. +// ctx: the context specified by the caller, for infinite polling pass +// a context that never gets cancelled or expired. +// immediate: if true, the 'condition' will be invoked before waiting for the interval, +// in this case 'condition' will always be invoked at least once. +// wait: user specified WaitFunc function that controls at what interval the condition +// function should be invoked periodically and whether it is bound by a timeout. +// condition: user specified ConditionWithContextFunc function. +// +// Deprecated: will be removed in favor of loopConditionUntilContext. +func poll(ctx context.Context, immediate bool, wait waitWithContextFunc, condition ConditionWithContextFunc) error { + if immediate { + done, err := runConditionWithCrashProtectionWithContext(ctx, condition) + if err != nil { + return err + } + if done { + return nil + } + } + + select { + case <-ctx.Done(): + // returning ctx.Err() will break backward compatibility, use new PollUntilContext* + // methods instead + return ErrWaitTimeout + default: + return waitForWithContext(ctx, wait, condition) + } +} + +// poller returns a WaitFunc that will send to the channel every interval until +// timeout has elapsed and then closes the channel. +// +// Over very short intervals you may receive no ticks before the channel is +// closed. A timeout of 0 is interpreted as an infinity, and in such a case +// it would be the caller's responsibility to close the done channel. +// Failure to do so would result in a leaked goroutine. +// +// Output ticks are not buffered. If the channel is not ready to receive an +// item, the tick is skipped. +// +// Deprecated: Will be removed in a future release. +func poller(interval, timeout time.Duration) waitWithContextFunc { + return waitWithContextFunc(func(ctx context.Context) <-chan struct{} { + ch := make(chan struct{}) + + go func() { + defer close(ch) + + tick := time.NewTicker(interval) + defer tick.Stop() + + var after <-chan time.Time + if timeout != 0 { + // time.After is more convenient, but it + // potentially leaves timers around much longer + // than necessary if we exit early. + timer := time.NewTimer(timeout) + after = timer.C + defer timer.Stop() + } + + for { + select { + case <-tick.C: + // If the consumer isn't ready for this signal drop it and + // check the other channels. + select { + case ch <- struct{}{}: + default: + } + case <-after: + return + case <-ctx.Done(): + return + } + } + }() + + return ch + }) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go new file mode 100644 index 00000000000..3efba321325 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go @@ -0,0 +1,121 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package wait + +import ( + "time" + + "k8s.io/utils/clock" +) + +// Timer abstracts how wait functions interact with time runtime efficiently. Test +// code may implement this interface directly but package consumers are encouraged +// to use the Backoff type as the primary mechanism for acquiring a Timer. The +// interface is a simplification of clock.Timer to prevent misuse. Timers are not +// expected to be safe for calls from multiple goroutines. +type Timer interface { + // C returns a channel that will receive a struct{} each time the timer fires. + // The channel should not be waited on after Stop() is invoked. It is allowed + // to cache the returned value of C() for the lifetime of the Timer. + C() <-chan time.Time + // Next is invoked by wait functions to signal timers that the next interval + // should begin. You may only use Next() if you have drained the channel C(). + // You should not call Next() after Stop() is invoked. + Next() + // Stop releases the timer. It is safe to invoke if no other methods have been + // called. + Stop() +} + +type noopTimer struct { + closedCh <-chan time.Time +} + +// newNoopTimer creates a timer with a unique channel to avoid contention +// for the channel's lock across multiple unrelated timers. +func newNoopTimer() noopTimer { + ch := make(chan time.Time) + close(ch) + return noopTimer{closedCh: ch} +} + +func (t noopTimer) C() <-chan time.Time { + return t.closedCh +} +func (noopTimer) Next() {} +func (noopTimer) Stop() {} + +type variableTimer struct { + fn DelayFunc + t clock.Timer + new func(time.Duration) clock.Timer +} + +func (t *variableTimer) C() <-chan time.Time { + if t.t == nil { + d := t.fn() + t.t = t.new(d) + } + return t.t.C() +} +func (t *variableTimer) Next() { + if t.t == nil { + return + } + d := t.fn() + t.t.Reset(d) +} +func (t *variableTimer) Stop() { + if t.t == nil { + return + } + t.t.Stop() + t.t = nil +} + +type fixedTimer struct { + interval time.Duration + t clock.Ticker + new func(time.Duration) clock.Ticker +} + +func (t *fixedTimer) C() <-chan time.Time { + if t.t == nil { + t.t = t.new(t.interval) + } + return t.t.C() +} +func (t *fixedTimer) Next() { + // no-op for fixed timers +} +func (t *fixedTimer) Stop() { + if t.t == nil { + return + } + t.t.Stop() + t.t = nil +} + +var ( + // RealTimer can be passed to methods that need a clock.Timer. + RealTimer = clock.RealClock{}.NewTimer +) + +var ( + // internalClock is used for test injection of clocks + internalClock = clock.RealClock{} +) diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go index ec5be90b825..6805e8cf948 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go @@ -18,20 +18,19 @@ package wait import ( "context" - "errors" - "math" "math/rand" "sync" "time" "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/utils/clock" ) // For any test of the style: -// ... -// <- time.After(timeout): -// t.Errorf("Timed out") +// +// ... +// <- time.After(timeout): +// t.Errorf("Timed out") +// // The value for timeout should effectively be "forever." Obviously we don't want our tests to truly lock up forever, but 30s // is long enough that it is effectively forever for the things that can slow down a run on a heavily contended machine // (GC, seeks, etc), but not so long as to make a developer ctrl-c a test run if they do happen to break that test. @@ -81,113 +80,6 @@ func Forever(f func(), period time.Duration) { Until(f, period, NeverStop) } -// Until loops until stop channel is closed, running f every period. -// -// Until is syntactic sugar on top of JitterUntil with zero jitter factor and -// with sliding = true (which means the timer for period starts after the f -// completes). -func Until(f func(), period time.Duration, stopCh <-chan struct{}) { - JitterUntil(f, period, 0.0, true, stopCh) -} - -// UntilWithContext loops until context is done, running f every period. -// -// UntilWithContext is syntactic sugar on top of JitterUntilWithContext -// with zero jitter factor and with sliding = true (which means the timer -// for period starts after the f completes). -func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { - JitterUntilWithContext(ctx, f, period, 0.0, true) -} - -// NonSlidingUntil loops until stop channel is closed, running f every -// period. -// -// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter -// factor, with sliding = false (meaning the timer for period starts at the same -// time as the function starts). -func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) { - JitterUntil(f, period, 0.0, false, stopCh) -} - -// NonSlidingUntilWithContext loops until context is done, running f every -// period. -// -// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext -// with zero jitter factor, with sliding = false (meaning the timer for period -// starts at the same time as the function starts). -func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { - JitterUntilWithContext(ctx, f, period, 0.0, false) -} - -// JitterUntil loops until stop channel is closed, running f every period. -// -// If jitterFactor is positive, the period is jittered before every run of f. -// If jitterFactor is not positive, the period is unchanged and not jittered. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -// -// Close stopCh to stop. f may not be invoked if stop channel is already -// closed. Pass NeverStop to if you don't want it stop. -func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { - BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh) -} - -// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) { - var t clock.Timer - for { - select { - case <-stopCh: - return - default: - } - - if !sliding { - t = backoff.Backoff() - } - - func() { - defer runtime.HandleCrash() - f() - }() - - if sliding { - t = backoff.Backoff() - } - - // NOTE: b/c there is no priority selection in golang - // it is possible for this to race, meaning we could - // trigger t.C and stopCh, and t.C select falls through. - // In order to mitigate we re-check stopCh at the beginning - // of every loop to prevent extra executions of f(). - select { - case <-stopCh: - if !t.Stop() { - <-t.C() - } - return - case <-t.C(): - } - } -} - -// JitterUntilWithContext loops until context is done, running f every period. -// -// If jitterFactor is positive, the period is jittered before every run of f. -// If jitterFactor is not positive, the period is unchanged and not jittered. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -// -// Cancel context to stop. f may not be invoked if context is already expired. -func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) { - JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done()) -} - // Jitter returns a time.Duration between duration and duration + maxFactor * // duration. // @@ -201,9 +93,6 @@ func Jitter(duration time.Duration, maxFactor float64) time.Duration { return wait } -// ErrWaitTimeout is returned when the condition exited without success. -var ErrWaitTimeout = errors.New("timed out waiting for the condition") - // ConditionFunc returns true if the condition is satisfied, or an error // if the loop should be aborted. type ConditionFunc func() (done bool, err error) @@ -221,425 +110,80 @@ func (cf ConditionFunc) WithContext() ConditionWithContextFunc { } } -// runConditionWithCrashProtection runs a ConditionFunc with crash protection -func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) { - return runConditionWithCrashProtectionWithContext(context.TODO(), condition.WithContext()) -} - -// runConditionWithCrashProtectionWithContext runs a -// ConditionWithContextFunc with crash protection. -func runConditionWithCrashProtectionWithContext(ctx context.Context, condition ConditionWithContextFunc) (bool, error) { - defer runtime.HandleCrash() - return condition(ctx) +// ContextForChannel provides a context that will be treated as cancelled +// when the provided parentCh is closed. The implementation returns +// context.Canceled for Err() if and only if the parentCh is closed. +func ContextForChannel(parentCh <-chan struct{}) context.Context { + return channelContext{stopCh: parentCh} } -// Backoff holds parameters applied to a Backoff function. -type Backoff struct { - // The initial duration. - Duration time.Duration - // Duration is multiplied by factor each iteration, if factor is not zero - // and the limits imposed by Steps and Cap have not been reached. - // Should not be negative. - // The jitter does not contribute to the updates to the duration parameter. - Factor float64 - // The sleep at each iteration is the duration plus an additional - // amount chosen uniformly at random from the interval between - // zero and `jitter*duration`. - Jitter float64 - // The remaining number of iterations in which the duration - // parameter may change (but progress can be stopped earlier by - // hitting the cap). If not positive, the duration is not - // changed. Used for exponential backoff in combination with - // Factor and Cap. - Steps int - // A limit on revised values of the duration parameter. If a - // multiplication by the factor parameter would make the duration - // exceed the cap then the duration is set to the cap and the - // steps parameter is set to zero. - Cap time.Duration -} +var _ context.Context = channelContext{} -// Step (1) returns an amount of time to sleep determined by the -// original Duration and Jitter and (2) mutates the provided Backoff -// to update its Steps and Duration. -func (b *Backoff) Step() time.Duration { - if b.Steps < 1 { - if b.Jitter > 0 { - return Jitter(b.Duration, b.Jitter) - } - return b.Duration - } - b.Steps-- - - duration := b.Duration - - // calculate the next step - if b.Factor != 0 { - b.Duration = time.Duration(float64(b.Duration) * b.Factor) - if b.Cap > 0 && b.Duration > b.Cap { - b.Duration = b.Cap - b.Steps = 0 - } - } - - if b.Jitter > 0 { - duration = Jitter(duration, b.Jitter) - } - return duration -} - -// contextForChannel derives a child context from a parent channel. -// -// The derived context's Done channel is closed when the returned cancel function -// is called or when the parent channel is closed, whichever happens first. -// -// Note the caller must *always* call the CancelFunc, otherwise resources may be leaked. -func contextForChannel(parentCh <-chan struct{}) (context.Context, context.CancelFunc) { - ctx, cancel := context.WithCancel(context.Background()) - - go func() { - select { - case <-parentCh: - cancel() - case <-ctx.Done(): - } - }() - return ctx, cancel -} - -// BackoffManager manages backoff with a particular scheme based on its underlying implementation. It provides -// an interface to return a timer for backoff, and caller shall backoff until Timer.C() drains. If the second Backoff() -// is called before the timer from the first Backoff() call finishes, the first timer will NOT be drained and result in -// undetermined behavior. -// The BackoffManager is supposed to be called in a single-threaded environment. -type BackoffManager interface { - Backoff() clock.Timer -} - -type exponentialBackoffManagerImpl struct { - backoff *Backoff - backoffTimer clock.Timer - lastBackoffStart time.Time - initialBackoff time.Duration - backoffResetDuration time.Duration - clock clock.Clock -} - -// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and -// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset. -// This backoff manager is used to reduce load during upstream unhealthiness. -func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager { - return &exponentialBackoffManagerImpl{ - backoff: &Backoff{ - Duration: initBackoff, - Factor: backoffFactor, - Jitter: jitter, - - // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not - // what we ideally need here, we set it to max int and assume we will never use up the steps - Steps: math.MaxInt32, - Cap: maxBackoff, - }, - backoffTimer: nil, - initialBackoff: initBackoff, - lastBackoffStart: c.Now(), - backoffResetDuration: resetDuration, - clock: c, - } -} - -func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration { - if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration { - b.backoff.Steps = math.MaxInt32 - b.backoff.Duration = b.initialBackoff - } - b.lastBackoffStart = b.clock.Now() - return b.backoff.Step() -} - -// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff. -// The returned timer must be drained before calling Backoff() the second time -func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer { - if b.backoffTimer == nil { - b.backoffTimer = b.clock.NewTimer(b.getNextBackoff()) - } else { - b.backoffTimer.Reset(b.getNextBackoff()) - } - return b.backoffTimer -} - -type jitteredBackoffManagerImpl struct { - clock clock.Clock - duration time.Duration - jitter float64 - backoffTimer clock.Timer -} - -// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter -// is negative, backoff will not be jittered. -func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager { - return &jitteredBackoffManagerImpl{ - clock: c, - duration: duration, - jitter: jitter, - backoffTimer: nil, - } -} - -func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration { - jitteredPeriod := j.duration - if j.jitter > 0.0 { - jitteredPeriod = Jitter(j.duration, j.jitter) - } - return jitteredPeriod -} - -// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff. -// The returned timer must be drained before calling Backoff() the second time -func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer { - backoff := j.getNextBackoff() - if j.backoffTimer == nil { - j.backoffTimer = j.clock.NewTimer(backoff) - } else { - j.backoffTimer.Reset(backoff) - } - return j.backoffTimer -} - -// ExponentialBackoff repeats a condition check with exponential backoff. -// -// It repeatedly checks the condition and then sleeps, using `backoff.Step()` -// to determine the length of the sleep and adjust Duration and Steps. -// Stops and returns as soon as: -// 1. the condition check returns true or an error, -// 2. `backoff.Steps` checks of the condition have been done, or -// 3. a sleep truncated by the cap on duration has been completed. -// In case (1) the returned error is what the condition function returned. -// In all other cases, ErrWaitTimeout is returned. -func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error { - for backoff.Steps > 0 { - if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { - return err - } - if backoff.Steps == 1 { - break - } - time.Sleep(backoff.Step()) - } - return ErrWaitTimeout -} - -// Poll tries a condition func until it returns true, an error, or the timeout -// is reached. -// -// Poll always waits the interval before the run of 'condition'. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to Poll something forever, see PollInfinite. -func Poll(interval, timeout time.Duration, condition ConditionFunc) error { - return PollWithContext(context.Background(), interval, timeout, condition.WithContext()) -} - -// PollWithContext tries a condition func until it returns true, an error, -// or when the context expires or the timeout is reached, whichever -// happens first. -// -// PollWithContext always waits the interval before the run of 'condition'. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to Poll something forever, see PollInfinite. -func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, timeout), condition) -} - -// PollUntil tries a condition func until it returns true, an error or stopCh is +// channelContext will behave as if the context were cancelled when stopCh is // closed. -// -// PollUntil always waits interval before the first run of 'condition'. -// 'condition' will always be invoked at least once. -func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { - ctx, cancel := contextForChannel(stopCh) - defer cancel() - return PollUntilWithContext(ctx, interval, condition.WithContext()) -} - -// PollUntilWithContext tries a condition func until it returns true, -// an error or the specified context is cancelled or expired. -// -// PollUntilWithContext always waits interval before the first run of 'condition'. -// 'condition' will always be invoked at least once. -func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, 0), condition) -} - -// PollInfinite tries a condition func until it returns true or an error -// -// PollInfinite always waits the interval before the run of 'condition'. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollInfinite(interval time.Duration, condition ConditionFunc) error { - return PollInfiniteWithContext(context.Background(), interval, condition.WithContext()) -} - -// PollInfiniteWithContext tries a condition func until it returns true or an error -// -// PollInfiniteWithContext always waits the interval before the run of 'condition'. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, 0), condition) -} - -// PollImmediate tries a condition func until it returns true, an error, or the timeout -// is reached. -// -// PollImmediate always checks 'condition' before waiting for the interval. 'condition' -// will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to immediately Poll something forever, see PollImmediateInfinite. -func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error { - return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext()) -} - -// PollImmediateWithContext tries a condition func until it returns true, an error, -// or the timeout is reached or the specified context expires, whichever happens first. -// -// PollImmediateWithContext always checks 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to immediately Poll something forever, see PollImmediateInfinite. -func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, timeout), condition) -} - -// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed. -// -// PollImmediateUntil runs the 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { - ctx, cancel := contextForChannel(stopCh) - defer cancel() - return PollImmediateUntilWithContext(ctx, interval, condition.WithContext()) +type channelContext struct { + stopCh <-chan struct{} } -// PollImmediateUntilWithContext tries a condition func until it returns true, -// an error or the specified context is cancelled or expired. -// -// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, 0), condition) +func (c channelContext) Done() <-chan struct{} { return c.stopCh } +func (c channelContext) Err() error { + select { + case <-c.stopCh: + return context.Canceled + default: + return nil + } } +func (c channelContext) Deadline() (time.Time, bool) { return time.Time{}, false } +func (c channelContext) Value(key any) any { return nil } -// PollImmediateInfinite tries a condition func until it returns true or an error -// -// PollImmediateInfinite runs the 'condition' before waiting for the interval. +// runConditionWithCrashProtection runs a ConditionFunc with crash protection. // -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error { - return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext()) +// Deprecated: Will be removed when the legacy polling methods are removed. +func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) { + defer runtime.HandleCrash() + return condition() } -// PollImmediateInfiniteWithContext tries a condition func until it returns true -// or an error or the specified context gets cancelled or expired. -// -// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval. +// runConditionWithCrashProtectionWithContext runs a ConditionWithContextFunc +// with crash protection. // -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, 0), condition) -} - -// Internally used, each of the the public 'Poll*' function defined in this -// package should invoke this internal function with appropriate parameters. -// ctx: the context specified by the caller, for infinite polling pass -// a context that never gets cancelled or expired. -// immediate: if true, the 'condition' will be invoked before waiting for the interval, -// in this case 'condition' will always be invoked at least once. -// wait: user specified WaitFunc function that controls at what interval the condition -// function should be invoked periodically and whether it is bound by a timeout. -// condition: user specified ConditionWithContextFunc function. -func poll(ctx context.Context, immediate bool, wait WaitWithContextFunc, condition ConditionWithContextFunc) error { - if immediate { - done, err := runConditionWithCrashProtectionWithContext(ctx, condition) - if err != nil { - return err - } - if done { - return nil - } - } - - select { - case <-ctx.Done(): - // returning ctx.Err() will break backward compatibility - return ErrWaitTimeout - default: - return WaitForWithContext(ctx, wait, condition) - } +// Deprecated: Will be removed when the legacy polling methods are removed. +func runConditionWithCrashProtectionWithContext(ctx context.Context, condition ConditionWithContextFunc) (bool, error) { + defer runtime.HandleCrash() + return condition(ctx) } -// WaitFunc creates a channel that receives an item every time a test +// waitFunc creates a channel that receives an item every time a test // should be executed and is closed when the last test should be invoked. -type WaitFunc func(done <-chan struct{}) <-chan struct{} +// +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +type waitFunc func(done <-chan struct{}) <-chan struct{} // WithContext converts the WaitFunc to an equivalent WaitWithContextFunc -func (w WaitFunc) WithContext() WaitWithContextFunc { +func (w waitFunc) WithContext() waitWithContextFunc { return func(ctx context.Context) <-chan struct{} { return w(ctx.Done()) } } -// WaitWithContextFunc creates a channel that receives an item every time a test +// waitWithContextFunc creates a channel that receives an item every time a test // should be executed and is closed when the last test should be invoked. // // When the specified context gets cancelled or expires the function // stops sending item and returns immediately. -type WaitWithContextFunc func(ctx context.Context) <-chan struct{} - -// WaitFor continually checks 'fn' as driven by 'wait'. -// -// WaitFor gets a channel from 'wait()'', and then invokes 'fn' once for every value -// placed on the channel and once more when the channel is closed. If the channel is closed -// and 'fn' returns false without error, WaitFor returns ErrWaitTimeout. -// -// If 'fn' returns an error the loop ends and that error is returned. If -// 'fn' returns true the loop ends and nil is returned. -// -// ErrWaitTimeout will be returned if the 'done' channel is closed without fn ever -// returning true. // -// When the done channel is closed, because the golang `select` statement is -// "uniform pseudo-random", the `fn` might still run one or multiple time, -// though eventually `WaitFor` will return. -func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error { - ctx, cancel := contextForChannel(done) - defer cancel() - return WaitForWithContext(ctx, wait.WithContext(), fn.WithContext()) -} +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +type waitWithContextFunc func(ctx context.Context) <-chan struct{} -// WaitForWithContext continually checks 'fn' as driven by 'wait'. +// waitForWithContext continually checks 'fn' as driven by 'wait'. // -// WaitForWithContext gets a channel from 'wait()'', and then invokes 'fn' +// waitForWithContext gets a channel from 'wait()”, and then invokes 'fn' // once for every value placed on the channel and once more when the // channel is closed. If the channel is closed and 'fn' -// returns false without error, WaitForWithContext returns ErrWaitTimeout. +// returns false without error, waitForWithContext returns ErrWaitTimeout. // // If 'fn' returns an error the loop ends and that error is returned. If // 'fn' returns true the loop ends and nil is returned. @@ -649,8 +193,11 @@ func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error { // // When the ctx.Done() channel is closed, because the golang `select` statement is // "uniform pseudo-random", the `fn` might still run one or multiple times, -// though eventually `WaitForWithContext` will return. -func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn ConditionWithContextFunc) error { +// though eventually `waitForWithContext` will return. +// +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +func waitForWithContext(ctx context.Context, wait waitWithContextFunc, fn ConditionWithContextFunc) error { waitCtx, cancel := context.WithCancel(context.Background()) defer cancel() c := wait(waitCtx) @@ -668,88 +215,9 @@ func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn Condit return ErrWaitTimeout } case <-ctx.Done(): - // returning ctx.Err() will break backward compatibility + // returning ctx.Err() will break backward compatibility, use new PollUntilContext* + // methods instead return ErrWaitTimeout } } } - -// poller returns a WaitFunc that will send to the channel every interval until -// timeout has elapsed and then closes the channel. -// -// Over very short intervals you may receive no ticks before the channel is -// closed. A timeout of 0 is interpreted as an infinity, and in such a case -// it would be the caller's responsibility to close the done channel. -// Failure to do so would result in a leaked goroutine. -// -// Output ticks are not buffered. If the channel is not ready to receive an -// item, the tick is skipped. -func poller(interval, timeout time.Duration) WaitWithContextFunc { - return WaitWithContextFunc(func(ctx context.Context) <-chan struct{} { - ch := make(chan struct{}) - - go func() { - defer close(ch) - - tick := time.NewTicker(interval) - defer tick.Stop() - - var after <-chan time.Time - if timeout != 0 { - // time.After is more convenient, but it - // potentially leaves timers around much longer - // than necessary if we exit early. - timer := time.NewTimer(timeout) - after = timer.C - defer timer.Stop() - } - - for { - select { - case <-tick.C: - // If the consumer isn't ready for this signal drop it and - // check the other channels. - select { - case ch <- struct{}{}: - default: - } - case <-after: - return - case <-ctx.Done(): - return - } - } - }() - - return ch - }) -} - -// ExponentialBackoffWithContext works with a request context and a Backoff. It ensures that the retry wait never -// exceeds the deadline specified by the request context. -func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionFunc) error { - for backoff.Steps > 0 { - select { - case <-ctx.Done(): - return ctx.Err() - default: - } - - if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { - return err - } - - if backoff.Steps == 1 { - break - } - - waitBeforeRetry := backoff.Step() - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(waitBeforeRetry): - } - } - - return ErrWaitTimeout -} diff --git a/vendor/k8s.io/apimachinery/pkg/watch/filter.go b/vendor/k8s.io/apimachinery/pkg/watch/filter.go index 22c9449f59c..a5735a0b47a 100644 --- a/vendor/k8s.io/apimachinery/pkg/watch/filter.go +++ b/vendor/k8s.io/apimachinery/pkg/watch/filter.go @@ -32,7 +32,6 @@ type FilterFunc func(in Event) (out Event, keep bool) // WARNING: filter has a fatal flaw, in that it can't properly update the // Type field (Add/Modified/Deleted) to reflect items beginning to pass the // filter when they previously didn't. -// func Filter(w Interface, f FilterFunc) Interface { fw := &filteredWatch{ incoming: w, diff --git a/vendor/k8s.io/apimachinery/pkg/watch/mux.go b/vendor/k8s.io/apimachinery/pkg/watch/mux.go index e01d519060b..d51f9567e42 100644 --- a/vendor/k8s.io/apimachinery/pkg/watch/mux.go +++ b/vendor/k8s.io/apimachinery/pkg/watch/mux.go @@ -17,6 +17,7 @@ limitations under the License. package watch import ( + "fmt" "sync" "k8s.io/apimachinery/pkg/runtime" @@ -44,8 +45,11 @@ type Broadcaster struct { nextWatcher int64 distributing sync.WaitGroup - incoming chan Event - stopped chan struct{} + // incomingBlock allows us to ensure we don't race and end up sending events + // to a closed channel following a broadcaster shutdown. + incomingBlock sync.Mutex + incoming chan Event + stopped chan struct{} // How large to make watcher's channel. watchQueueLength int @@ -111,6 +115,8 @@ func (obj functionFakeRuntimeObject) DeepCopyObject() runtime.Object { // won't ever see that event, and will always see any event after they are // added. func (m *Broadcaster) blockQueue(f func()) { + m.incomingBlock.Lock() + defer m.incomingBlock.Unlock() select { case <-m.stopped: return @@ -132,7 +138,7 @@ func (m *Broadcaster) blockQueue(f func()) { // Note: new watchers will only receive new events. They won't get an entire history // of previous events. It will block until the watcher is actually added to the // broadcaster. -func (m *Broadcaster) Watch() Interface { +func (m *Broadcaster) Watch() (Interface, error) { var w *broadcasterWatcher m.blockQueue(func() { id := m.nextWatcher @@ -146,11 +152,9 @@ func (m *Broadcaster) Watch() Interface { m.watchers[id] = w }) if w == nil { - // The panic here is to be consistent with the previous interface behavior - // we are willing to re-evaluate in the future. - panic("broadcaster already stopped") + return nil, fmt.Errorf("broadcaster already stopped") } - return w + return w, nil } // WatchWithPrefix adds a new watcher to the list and returns an Interface for it. It sends @@ -158,7 +162,7 @@ func (m *Broadcaster) Watch() Interface { // The returned watch will have a queue length that is at least large enough to accommodate // all of the items in queuedEvents. It will block until the watcher is actually added to // the broadcaster. -func (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) Interface { +func (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) (Interface, error) { var w *broadcasterWatcher m.blockQueue(func() { id := m.nextWatcher @@ -179,11 +183,9 @@ func (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) Interface { } }) if w == nil { - // The panic here is to be consistent with the previous interface behavior - // we are willing to re-evaluate in the future. - panic("broadcaster already stopped") + return nil, fmt.Errorf("broadcaster already stopped") } - return w + return w, nil } // stopWatching stops the given watcher and removes it from the list. @@ -210,19 +212,38 @@ func (m *Broadcaster) closeAll() { } // Action distributes the given event among all watchers. -func (m *Broadcaster) Action(action EventType, obj runtime.Object) { +func (m *Broadcaster) Action(action EventType, obj runtime.Object) error { + m.incomingBlock.Lock() + defer m.incomingBlock.Unlock() + select { + case <-m.stopped: + return fmt.Errorf("broadcaster already stopped") + default: + } + m.incoming <- Event{action, obj} + return nil } // Action distributes the given event among all watchers, or drops it on the floor // if too many incoming actions are queued up. Returns true if the action was sent, // false if dropped. -func (m *Broadcaster) ActionOrDrop(action EventType, obj runtime.Object) bool { +func (m *Broadcaster) ActionOrDrop(action EventType, obj runtime.Object) (bool, error) { + m.incomingBlock.Lock() + defer m.incomingBlock.Unlock() + + // Ensure that if the broadcaster is stopped we do not send events to it. + select { + case <-m.stopped: + return false, fmt.Errorf("broadcaster already stopped") + default: + } + select { case m.incoming <- Event{action, obj}: - return true + return true, nil default: - return false + return false, nil } } diff --git a/vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go b/vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go index 8205a4dd138..5b8514b3fab 100644 --- a/vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go +++ b/vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go @@ -28,7 +28,7 @@ const ( // TODO: fix the returned errors to be introspectable. func LookupPatchMetadataForStruct(t reflect.Type, jsonField string) ( elemType reflect.Type, patchStrategies []string, patchMergeKey string, e error) { - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } @@ -183,7 +183,7 @@ func typeFields(t reflect.Type) []field { index[len(f.index)] = i ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { + if ft.Name() == "" && ft.Kind() == reflect.Pointer { // Follow pointer. ft = ft.Elem() } diff --git a/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go b/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go index 6be80349ab6..511e625b63d 100644 --- a/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go +++ b/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go @@ -100,7 +100,8 @@ func makeUsefulPanic(v reflect.Value) { // Tests for deep equality using reflected types. The map argument tracks // comparisons that have already been seen, which allows short circuiting on // recursive types. -func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool { +// equateNilAndEmpty controls whether empty maps/slices are equivalent to nil +func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, equateNilAndEmpty bool, depth int) bool { defer makeUsefulPanic(v1) if !v1.IsValid() || !v2.IsValid() { @@ -150,17 +151,36 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, // We don't need to check length here because length is part of // an array's type, which has already been filtered for. for i := 0; i < v1.Len(); i++ { - if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) { + if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, equateNilAndEmpty, depth+1) { return false } } return true case reflect.Slice: - if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { - return false - } - if v1.IsNil() || v1.Len() == 0 { - return true + if equateNilAndEmpty { + if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { + return false + } + + if v1.IsNil() || v1.Len() == 0 { + return true + } + } else { + if v1.IsNil() != v2.IsNil() { + return false + } + + // Optimize nil and empty cases + // Two lists that are BOTH nil are equal + // No need to check v2 is nil since v1.IsNil == v2.IsNil from above + if v1.IsNil() { + return true + } + + // Two lists that are both empty and both non nil are equal + if v1.Len() == 0 || v2.Len() == 0 { + return true + } } if v1.Len() != v2.Len() { return false @@ -169,7 +189,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, return true } for i := 0; i < v1.Len(); i++ { - if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) { + if !e.deepValueEqual(v1.Index(i), v2.Index(i), visited, equateNilAndEmpty, depth+1) { return false } } @@ -178,22 +198,40 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, if v1.IsNil() || v2.IsNil() { return v1.IsNil() == v2.IsNil() } - return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) + return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, equateNilAndEmpty, depth+1) case reflect.Ptr: - return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1) + return e.deepValueEqual(v1.Elem(), v2.Elem(), visited, equateNilAndEmpty, depth+1) case reflect.Struct: for i, n := 0, v1.NumField(); i < n; i++ { - if !e.deepValueEqual(v1.Field(i), v2.Field(i), visited, depth+1) { + if !e.deepValueEqual(v1.Field(i), v2.Field(i), visited, equateNilAndEmpty, depth+1) { return false } } return true case reflect.Map: - if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { - return false - } - if v1.IsNil() || v1.Len() == 0 { - return true + if equateNilAndEmpty { + if (v1.IsNil() || v1.Len() == 0) != (v2.IsNil() || v2.Len() == 0) { + return false + } + if v1.IsNil() || v1.Len() == 0 { + return true + } + } else { + if v1.IsNil() != v2.IsNil() { + return false + } + + // Optimize nil and empty cases + // Two maps that are BOTH nil are equal + // No need to check v2 is nil since v1.IsNil == v2.IsNil from above + if v1.IsNil() { + return true + } + + // Two maps that are both empty and both non nil are equal + if v1.Len() == 0 || v2.Len() == 0 { + return true + } } if v1.Len() != v2.Len() { return false @@ -202,7 +240,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, return true } for _, k := range v1.MapKeys() { - if !e.deepValueEqual(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) { + if !e.deepValueEqual(v1.MapIndex(k), v2.MapIndex(k), visited, equateNilAndEmpty, depth+1) { return false } } @@ -232,6 +270,14 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, // Unexported field members cannot be compared and will cause an informative panic; you must add an Equality // function for these types. func (e Equalities) DeepEqual(a1, a2 interface{}) bool { + return e.deepEqual(a1, a2, true) +} + +func (e Equalities) DeepEqualWithNilDifferentFromEmpty(a1, a2 interface{}) bool { + return e.deepEqual(a1, a2, false) +} + +func (e Equalities) deepEqual(a1, a2 interface{}, equateNilAndEmpty bool) bool { if a1 == nil || a2 == nil { return a1 == a2 } @@ -240,7 +286,7 @@ func (e Equalities) DeepEqual(a1, a2 interface{}) bool { if v1.Type() != v2.Type() { return false } - return e.deepValueEqual(v1, v2, make(map[visit]bool), 0) + return e.deepValueEqual(v1, v2, make(map[visit]bool), equateNilAndEmpty, 0) } func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool, depth int) bool { @@ -327,7 +373,7 @@ func (e Equalities) deepValueDerive(v1, v2 reflect.Value, visited map[visit]bool return true } return e.deepValueDerive(v1.Elem(), v2.Elem(), visited, depth+1) - case reflect.Ptr: + case reflect.Pointer: if v1.IsNil() { return true } diff --git a/vendor/k8s.io/apiserver/pkg/admission/attributes.go b/vendor/k8s.io/apiserver/pkg/admission/attributes.go new file mode 100644 index 00000000000..1d291f6b22e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/attributes.go @@ -0,0 +1,211 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "fmt" + "strings" + "sync" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/authentication/user" +) + +type attributesRecord struct { + kind schema.GroupVersionKind + namespace string + name string + resource schema.GroupVersionResource + subresource string + operation Operation + options runtime.Object + dryRun bool + object runtime.Object + oldObject runtime.Object + userInfo user.Info + + // other elements are always accessed in single goroutine. + // But ValidatingAdmissionWebhook add annotations concurrently. + annotations map[string]annotation + annotationsLock sync.RWMutex + + reinvocationContext ReinvocationContext +} + +type annotation struct { + level auditinternal.Level + value string +} + +func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind schema.GroupVersionKind, namespace, name string, resource schema.GroupVersionResource, subresource string, operation Operation, operationOptions runtime.Object, dryRun bool, userInfo user.Info) Attributes { + return &attributesRecord{ + kind: kind, + namespace: namespace, + name: name, + resource: resource, + subresource: subresource, + operation: operation, + options: operationOptions, + dryRun: dryRun, + object: object, + oldObject: oldObject, + userInfo: userInfo, + reinvocationContext: &reinvocationContext{}, + } +} + +func (record *attributesRecord) GetKind() schema.GroupVersionKind { + return record.kind +} + +func (record *attributesRecord) GetNamespace() string { + return record.namespace +} + +func (record *attributesRecord) GetName() string { + return record.name +} + +func (record *attributesRecord) GetResource() schema.GroupVersionResource { + return record.resource +} + +func (record *attributesRecord) GetSubresource() string { + return record.subresource +} + +func (record *attributesRecord) GetOperation() Operation { + return record.operation +} + +func (record *attributesRecord) GetOperationOptions() runtime.Object { + return record.options +} + +func (record *attributesRecord) IsDryRun() bool { + return record.dryRun +} + +func (record *attributesRecord) GetObject() runtime.Object { + return record.object +} + +func (record *attributesRecord) GetOldObject() runtime.Object { + return record.oldObject +} + +func (record *attributesRecord) GetUserInfo() user.Info { + return record.userInfo +} + +// getAnnotations implements privateAnnotationsGetter.It's a private method used +// by WithAudit decorator. +func (record *attributesRecord) getAnnotations(maxLevel auditinternal.Level) map[string]string { + record.annotationsLock.RLock() + defer record.annotationsLock.RUnlock() + + if record.annotations == nil { + return nil + } + cp := make(map[string]string, len(record.annotations)) + for key, value := range record.annotations { + if value.level.Less(maxLevel) || value.level == maxLevel { + cp[key] = value.value + } + } + return cp +} + +// AddAnnotation adds an annotation to attributesRecord with Metadata audit level +func (record *attributesRecord) AddAnnotation(key, value string) error { + return record.AddAnnotationWithLevel(key, value, auditinternal.LevelMetadata) +} + +func (record *attributesRecord) AddAnnotationWithLevel(key, value string, level auditinternal.Level) error { + if err := checkKeyFormat(key); err != nil { + return err + } + if level.Less(auditinternal.LevelMetadata) { + return fmt.Errorf("admission annotations are not allowed to be set at audit level lower than Metadata, key: %q, level: %s", key, level) + } + record.annotationsLock.Lock() + defer record.annotationsLock.Unlock() + + if record.annotations == nil { + record.annotations = make(map[string]annotation) + } + annotation := annotation{level: level, value: value} + if v, ok := record.annotations[key]; ok && v != annotation { + return fmt.Errorf("admission annotations are not allowd to be overwritten, key:%q, old value: %v, new value: %v", key, record.annotations[key], annotation) + } + record.annotations[key] = annotation + return nil +} + +func (record *attributesRecord) GetReinvocationContext() ReinvocationContext { + return record.reinvocationContext +} + +type reinvocationContext struct { + // isReinvoke is true when admission plugins are being reinvoked + isReinvoke bool + // reinvokeRequested is true when an admission plugin requested a re-invocation of the chain + reinvokeRequested bool + // values stores reinvoke context values per plugin. + values map[string]interface{} +} + +func (rc *reinvocationContext) IsReinvoke() bool { + return rc.isReinvoke +} + +func (rc *reinvocationContext) SetIsReinvoke() { + rc.isReinvoke = true +} + +func (rc *reinvocationContext) ShouldReinvoke() bool { + return rc.reinvokeRequested +} + +func (rc *reinvocationContext) SetShouldReinvoke() { + rc.reinvokeRequested = true +} + +func (rc *reinvocationContext) SetValue(plugin string, v interface{}) { + if rc.values == nil { + rc.values = map[string]interface{}{} + } + rc.values[plugin] = v +} + +func (rc *reinvocationContext) Value(plugin string) interface{} { + return rc.values[plugin] +} + +func checkKeyFormat(key string) error { + parts := strings.Split(key, "/") + if len(parts) != 2 { + return fmt.Errorf("annotation key has invalid format, the right format is a DNS subdomain prefix and '/' and key name. (e.g. 'podsecuritypolicy.admission.k8s.io/admit-policy')") + } + if msgs := validation.IsQualifiedName(key); len(msgs) != 0 { + return fmt.Errorf("annotation key has invalid format %s. A qualified name like 'podsecuritypolicy.admission.k8s.io/admit-policy' is required.", strings.Join(msgs, ",")) + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/audit.go b/vendor/k8s.io/apiserver/pkg/admission/audit.go new file mode 100644 index 00000000000..7c0993f0908 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/audit.go @@ -0,0 +1,102 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "fmt" + + "k8s.io/apiserver/pkg/audit" +) + +// auditHandler logs annotations set by other admission handlers +type auditHandler struct { + Interface +} + +var _ Interface = &auditHandler{} +var _ MutationInterface = &auditHandler{} +var _ ValidationInterface = &auditHandler{} + +// WithAudit is a decorator for a admission phase. It saves annotations +// of attribute into the audit event. Attributes passed to the Admit and +// Validate function must be instance of privateAnnotationsGetter or +// AnnotationsGetter, otherwise an error is returned. +func WithAudit(i Interface) Interface { + if i == nil { + return i + } + return &auditHandler{Interface: i} +} + +func (handler *auditHandler) Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error { + if !handler.Interface.Handles(a.GetOperation()) { + return nil + } + if err := ensureAnnotationGetter(a); err != nil { + return err + } + var err error + if mutator, ok := handler.Interface.(MutationInterface); ok { + err = mutator.Admit(ctx, a, o) + handler.logAnnotations(ctx, a) + } + return err +} + +func (handler *auditHandler) Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error { + if !handler.Interface.Handles(a.GetOperation()) { + return nil + } + if err := ensureAnnotationGetter(a); err != nil { + return err + } + var err error + if validator, ok := handler.Interface.(ValidationInterface); ok { + err = validator.Validate(ctx, a, o) + handler.logAnnotations(ctx, a) + } + return err +} + +func ensureAnnotationGetter(a Attributes) error { + _, okPrivate := a.(privateAnnotationsGetter) + _, okPublic := a.(AnnotationsGetter) + if okPrivate || okPublic { + return nil + } + return fmt.Errorf("attributes must be an instance of privateAnnotationsGetter or AnnotationsGetter") +} + +func (handler *auditHandler) logAnnotations(ctx context.Context, a Attributes) { + ae := audit.AuditEventFrom(ctx) + if ae == nil { + return + } + + var annotations map[string]string + switch a := a.(type) { + case privateAnnotationsGetter: + annotations = a.getAnnotations(ae.Level) + case AnnotationsGetter: + annotations = a.GetAnnotations(ae.Level) + default: + // this will never happen, because we have already checked it in ensureAnnotationGetter + } + + audit.AddAuditAnnotationsMap(ctx, annotations) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go b/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go new file mode 100644 index 00000000000..9f8a941105a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go @@ -0,0 +1,123 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "context" + "time" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + metricsNamespace = "apiserver" + metricsSubsystem = "validating_admission_policy" +) + +var ( + // Metrics provides access to validation admission metrics. + Metrics = newValidationAdmissionMetrics() +) + +// ValidatingAdmissionPolicyMetrics aggregates Prometheus metrics related to validation admission control. +type ValidatingAdmissionPolicyMetrics struct { + policyCheck *metrics.CounterVec + policyDefinition *metrics.CounterVec + policyLatency *metrics.HistogramVec +} + +func newValidationAdmissionMetrics() *ValidatingAdmissionPolicyMetrics { + check := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubsystem, + Name: "check_total", + Help: "Validation admission policy check total, labeled by policy and further identified by binding, enforcement action taken, and state.", + StabilityLevel: metrics.ALPHA, + }, + []string{"policy", "policy_binding", "enforcement_action", "state"}, + ) + definition := metrics.NewCounterVec(&metrics.CounterOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubsystem, + Name: "definition_total", + Help: "Validation admission policy count total, labeled by state and enforcement action.", + StabilityLevel: metrics.ALPHA, + }, + []string{"state", "enforcement_action"}, + ) + latency := metrics.NewHistogramVec(&metrics.HistogramOpts{ + Namespace: metricsNamespace, + Subsystem: metricsSubsystem, + Name: "check_duration_seconds", + Help: "Validation admission latency for individual validation expressions in seconds, labeled by policy and further including binding, state and enforcement action taken.", + // the bucket distribution here is based oo the benchmark suite at + // github.com/DangerOnTheRanger/cel-benchmark performed on 16-core Intel Xeon + // the lowest bucket was based around the 180ns/op figure for BenchmarkAccess, + // plus some additional leeway to account for the apiserver doing other things + // the largest bucket was chosen based on the fact that benchmarks indicate the + // same Xeon running a CEL expression close to the estimated cost limit takes + // around 760ms, so that bucket should only ever have the slowest CEL expressions + // in it + Buckets: []float64{0.0000005, 0.001, 0.01, 0.1, 1.0}, + StabilityLevel: metrics.ALPHA, + }, + []string{"policy", "policy_binding", "enforcement_action", "state"}, + ) + + legacyregistry.MustRegister(check) + legacyregistry.MustRegister(definition) + legacyregistry.MustRegister(latency) + return &ValidatingAdmissionPolicyMetrics{policyCheck: check, policyDefinition: definition, policyLatency: latency} +} + +// Reset resets all validation admission-related Prometheus metrics. +func (m *ValidatingAdmissionPolicyMetrics) Reset() { + m.policyCheck.Reset() + m.policyDefinition.Reset() + m.policyLatency.Reset() +} + +// ObserveDefinition observes a policy definition. +func (m *ValidatingAdmissionPolicyMetrics) ObserveDefinition(ctx context.Context, state, enforcementAction string) { + m.policyDefinition.WithContext(ctx).WithLabelValues(state, enforcementAction).Inc() +} + +// ObserveAdmissionWithError observes a policy validation error that was ignored due to failure policy. +func (m *ValidatingAdmissionPolicyMetrics) ObserveAdmissionWithError(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "allow", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "allow", state).Observe(elapsed.Seconds()) +} + +// ObserveRejection observes a policy validation error that was at least one of the reasons for a deny. +func (m *ValidatingAdmissionPolicyMetrics) ObserveRejection(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Observe(elapsed.Seconds()) +} + +// ObserveAudit observes a policy validation audit annotation was published for a validation failure. +func (m *ValidatingAdmissionPolicyMetrics) ObserveAudit(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "audit", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "audit", state).Observe(elapsed.Seconds()) +} + +// ObserveWarn observes a policy validation warning was published for a validation failure. +func (m *ValidatingAdmissionPolicyMetrics) ObserveWarn(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "warn", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "warn", state).Observe(elapsed.Seconds()) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/chain.go b/vendor/k8s.io/apiserver/pkg/admission/chain.go new file mode 100644 index 00000000000..f2af01ef3c5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/chain.go @@ -0,0 +1,70 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import "context" + +// chainAdmissionHandler is an instance of admission.NamedHandler that performs admission control using +// a chain of admission handlers +type chainAdmissionHandler []Interface + +// NewChainHandler creates a new chain handler from an array of handlers. Used for testing. +func NewChainHandler(handlers ...Interface) chainAdmissionHandler { + return chainAdmissionHandler(handlers) +} + +// Admit performs an admission control check using a chain of handlers, and returns immediately on first error +func (admissionHandler chainAdmissionHandler) Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error { + for _, handler := range admissionHandler { + if !handler.Handles(a.GetOperation()) { + continue + } + if mutator, ok := handler.(MutationInterface); ok { + err := mutator.Admit(ctx, a, o) + if err != nil { + return err + } + } + } + return nil +} + +// Validate performs an admission control check using a chain of handlers, and returns immediately on first error +func (admissionHandler chainAdmissionHandler) Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error { + for _, handler := range admissionHandler { + if !handler.Handles(a.GetOperation()) { + continue + } + if validator, ok := handler.(ValidationInterface); ok { + err := validator.Validate(ctx, a, o) + if err != nil { + return err + } + } + } + return nil +} + +// Handles will return true if any of the handlers handles the given operation +func (admissionHandler chainAdmissionHandler) Handles(operation Operation) bool { + for _, handler := range admissionHandler { + if handler.Handles(operation) { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/config.go b/vendor/k8s.io/apiserver/pkg/admission/config.go new file mode 100644 index 00000000000..43613321b94 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/config.go @@ -0,0 +1,175 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "path/filepath" + + "k8s.io/klog/v2" + "sigs.k8s.io/yaml" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/apis/apiserver" + apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" +) + +func makeAbs(path, base string) (string, error) { + if filepath.IsAbs(path) { + return path, nil + } + if len(base) == 0 || base == "." { + cwd, err := os.Getwd() + if err != nil { + return "", err + } + base = cwd + } + return filepath.Join(base, path), nil +} + +// ReadAdmissionConfiguration reads the admission configuration at the specified path. +// It returns the loaded admission configuration if the input file aligns with the required syntax. +// If it does not align with the provided syntax, it returns a default configuration for the enumerated +// set of pluginNames whose config location references the specified configFilePath. +// It does this to preserve backward compatibility when admission control files were opaque. +// It returns an error if the file did not exist. +func ReadAdmissionConfiguration(pluginNames []string, configFilePath string, configScheme *runtime.Scheme) (ConfigProvider, error) { + if configFilePath == "" { + return configProvider{config: &apiserver.AdmissionConfiguration{}}, nil + } + // a file was provided, so we just read it. + data, err := ioutil.ReadFile(configFilePath) + if err != nil { + return nil, fmt.Errorf("unable to read admission control configuration from %q [%v]", configFilePath, err) + } + codecs := serializer.NewCodecFactory(configScheme) + decoder := codecs.UniversalDecoder() + decodedObj, err := runtime.Decode(decoder, data) + // we were able to decode the file successfully + if err == nil { + decodedConfig, ok := decodedObj.(*apiserver.AdmissionConfiguration) + if !ok { + return nil, fmt.Errorf("unexpected type: %T", decodedObj) + } + baseDir := path.Dir(configFilePath) + for i := range decodedConfig.Plugins { + if decodedConfig.Plugins[i].Path == "" { + continue + } + // we update relative file paths to absolute paths + absPath, err := makeAbs(decodedConfig.Plugins[i].Path, baseDir) + if err != nil { + return nil, err + } + decodedConfig.Plugins[i].Path = absPath + } + return configProvider{ + config: decodedConfig, + }, nil + } + // we got an error where the decode wasn't related to a missing type + if !(runtime.IsMissingVersion(err) || runtime.IsMissingKind(err) || runtime.IsNotRegisteredError(err)) { + return nil, err + } + + // Only tolerate load errors if the file appears to be one of the two legacy plugin configs + unstructuredData := map[string]interface{}{} + if err2 := yaml.Unmarshal(data, &unstructuredData); err2 != nil { + return nil, err + } + _, isLegacyImagePolicy := unstructuredData["imagePolicy"] + _, isLegacyPodNodeSelector := unstructuredData["podNodeSelectorPluginConfig"] + if !isLegacyImagePolicy && !isLegacyPodNodeSelector { + return nil, err + } + + // convert the legacy format to the new admission control format + // in order to preserve backwards compatibility, we set plugins that + // previously read input from a non-versioned file configuration to the + // current input file. + legacyPluginsWithUnversionedConfig := sets.NewString("ImagePolicyWebhook", "PodNodeSelector") + externalConfig := &apiserverv1.AdmissionConfiguration{} + for _, pluginName := range pluginNames { + if legacyPluginsWithUnversionedConfig.Has(pluginName) { + externalConfig.Plugins = append(externalConfig.Plugins, + apiserverv1.AdmissionPluginConfiguration{ + Name: pluginName, + Path: configFilePath}) + } + } + configScheme.Default(externalConfig) + internalConfig := &apiserver.AdmissionConfiguration{} + if err := configScheme.Convert(externalConfig, internalConfig, nil); err != nil { + return nil, err + } + return configProvider{ + config: internalConfig, + }, nil +} + +type configProvider struct { + config *apiserver.AdmissionConfiguration +} + +// GetAdmissionPluginConfigurationFor returns a reader that holds the admission plugin configuration. +func GetAdmissionPluginConfigurationFor(pluginCfg apiserver.AdmissionPluginConfiguration) (io.Reader, error) { + // if there is a nest object, return it directly + if pluginCfg.Configuration != nil { + return bytes.NewBuffer(pluginCfg.Configuration.Raw), nil + } + // there is nothing nested, so we delegate to path + if pluginCfg.Path != "" { + content, err := ioutil.ReadFile(pluginCfg.Path) + if err != nil { + klog.Fatalf("Couldn't open admission plugin configuration %s: %#v", pluginCfg.Path, err) + return nil, err + } + return bytes.NewBuffer(content), nil + } + // there is no special config at all + return nil, nil +} + +// ConfigFor returns a reader for the specified plugin. +// If no specific configuration is present, we return a nil reader. +func (p configProvider) ConfigFor(pluginName string) (io.Reader, error) { + // there is no config, so there is no potential config + if p.config == nil { + return nil, nil + } + // look for matching plugin and get configuration + for _, pluginCfg := range p.config.Plugins { + if pluginName != pluginCfg.Name { + continue + } + pluginConfig, err := GetAdmissionPluginConfigurationFor(pluginCfg) + if err != nil { + return nil, err + } + return pluginConfig, nil + } + // there is no registered config that matches on plugin name. + return nil, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/conversion.go b/vendor/k8s.io/apiserver/pkg/admission/conversion.go new file mode 100644 index 00000000000..a2b313a9834 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/conversion.go @@ -0,0 +1,136 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// VersionedAttributes is a wrapper around the original admission attributes, adding versioned +// variants of the object and old object. +type VersionedAttributes struct { + // Attributes holds the original admission attributes + Attributes + // VersionedOldObject holds Attributes.OldObject (if non-nil), converted to VersionedKind. + // It must never be mutated. + VersionedOldObject runtime.Object + // VersionedObject holds Attributes.Object (if non-nil), converted to VersionedKind. + // If mutated, Dirty must be set to true by the mutator. + VersionedObject runtime.Object + // VersionedKind holds the fully qualified kind + VersionedKind schema.GroupVersionKind + // Dirty indicates VersionedObject has been modified since being converted from Attributes.Object + Dirty bool +} + +// GetObject overrides the Attributes.GetObject() +func (v *VersionedAttributes) GetObject() runtime.Object { + if v.VersionedObject != nil { + return v.VersionedObject + } + return v.Attributes.GetObject() +} + +// ConvertToGVK converts object to the desired gvk. +func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o ObjectInterfaces) (runtime.Object, error) { + // Unlike other resources, custom resources do not have internal version, so + // if obj is a custom resource, it should not need conversion. + if obj.GetObjectKind().GroupVersionKind() == gvk { + return obj, nil + } + out, err := o.GetObjectCreater().New(gvk) + if err != nil { + return nil, err + } + err = o.GetObjectConvertor().Convert(obj, out, nil) + if err != nil { + return nil, err + } + // Explicitly set the GVK + out.GetObjectKind().SetGroupVersionKind(gvk) + return out, nil +} + +// NewVersionedAttributes returns versioned attributes with the old and new object (if non-nil) converted to the requested kind +func NewVersionedAttributes(attr Attributes, gvk schema.GroupVersionKind, o ObjectInterfaces) (*VersionedAttributes, error) { + // convert the old and new objects to the requested version + versionedAttr := &VersionedAttributes{ + Attributes: attr, + VersionedKind: gvk, + } + if oldObj := attr.GetOldObject(); oldObj != nil { + out, err := ConvertToGVK(oldObj, gvk, o) + if err != nil { + return nil, err + } + versionedAttr.VersionedOldObject = out + } + if obj := attr.GetObject(); obj != nil { + out, err := ConvertToGVK(obj, gvk, o) + if err != nil { + return nil, err + } + versionedAttr.VersionedObject = out + } + return versionedAttr, nil +} + +// ConvertVersionedAttributes converts VersionedObject and VersionedOldObject to the specified kind, if needed. +// If attr.VersionedKind already matches the requested kind, no conversion is performed. +// If conversion is required: +// * attr.VersionedObject is used as the source for the new object if Dirty=true (and is round-tripped through attr.Attributes.Object, clearing Dirty in the process) +// * attr.Attributes.Object is used as the source for the new object if Dirty=false +// * attr.Attributes.OldObject is used as the source for the old object +func ConvertVersionedAttributes(attr *VersionedAttributes, gvk schema.GroupVersionKind, o ObjectInterfaces) error { + // we already have the desired kind, we're done + if attr.VersionedKind == gvk { + return nil + } + + // convert the original old object to the desired GVK + if oldObj := attr.Attributes.GetOldObject(); oldObj != nil { + out, err := ConvertToGVK(oldObj, gvk, o) + if err != nil { + return err + } + attr.VersionedOldObject = out + } + + if attr.VersionedObject != nil { + // convert the existing versioned object to internal + if attr.Dirty { + err := o.GetObjectConvertor().Convert(attr.VersionedObject, attr.Attributes.GetObject(), nil) + if err != nil { + return err + } + } + + // and back to external + out, err := ConvertToGVK(attr.Attributes.GetObject(), gvk, o) + if err != nil { + return err + } + attr.VersionedObject = out + } + + // Remember we converted to this version + attr.VersionedKind = gvk + attr.Dirty = false + + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/decorator.go b/vendor/k8s.io/apiserver/pkg/admission/decorator.go new file mode 100644 index 00000000000..a4b0b28b552 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/decorator.go @@ -0,0 +1,39 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +type Decorator interface { + Decorate(handler Interface, name string) Interface +} + +type DecoratorFunc func(handler Interface, name string) Interface + +func (d DecoratorFunc) Decorate(handler Interface, name string) Interface { + return d(handler, name) +} + +type Decorators []Decorator + +// Decorate applies the decorator in inside-out order, i.e. the first decorator in the slice is first applied to the given handler. +func (d Decorators) Decorate(handler Interface, name string) Interface { + result := handler + for _, d := range d { + result = d.Decorate(result, name) + } + + return result +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/errors.go b/vendor/k8s.io/apiserver/pkg/admission/errors.go new file mode 100644 index 00000000000..9a069a2c994 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/errors.go @@ -0,0 +1,72 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" + utilerrors "k8s.io/apimachinery/pkg/util/errors" +) + +func extractResourceName(a Attributes) (name string, resource schema.GroupResource, err error) { + resource = a.GetResource().GroupResource() + + if len(a.GetName()) > 0 { + return a.GetName(), resource, nil + } + + name = "Unknown" + obj := a.GetObject() + if obj != nil { + accessor, err := meta.Accessor(obj) + if err != nil { + // not all object have ObjectMeta. If we don't, return a name with a slash (always illegal) + return "Unknown/errorGettingName", resource, nil + } + + // this is necessary because name object name generation has not occurred yet + if len(accessor.GetName()) > 0 { + name = accessor.GetName() + } else if len(accessor.GetGenerateName()) > 0 { + name = accessor.GetGenerateName() + } + } + return name, resource, nil +} + +// NewForbidden is a utility function to return a well-formatted admission control error response +func NewForbidden(a Attributes, internalError error) error { + // do not double wrap an error of same type + if apierrors.IsForbidden(internalError) { + return internalError + } + name, resource, err := extractResourceName(a) + if err != nil { + return apierrors.NewInternalError(utilerrors.NewAggregate([]error{internalError, err})) + } + return apierrors.NewForbidden(resource, name, internalError) +} + +// NewNotFound is a utility function to return a well-formatted admission control error response +func NewNotFound(a Attributes) error { + name, resource, err := extractResourceName(a) + if err != nil { + return apierrors.NewInternalError(err) + } + return apierrors.NewNotFound(resource, name) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/handler.go b/vendor/k8s.io/apiserver/pkg/admission/handler.go new file mode 100644 index 00000000000..d2a9e7d4cf7 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/handler.go @@ -0,0 +1,79 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "time" + + "k8s.io/apimachinery/pkg/util/sets" +) + +const ( + // timeToWaitForReady is the amount of time to wait to let an admission controller to be ready to satisfy a request. + // this is useful when admission controllers need to warm their caches before letting requests through. + timeToWaitForReady = 10 * time.Second +) + +// ReadyFunc is a function that returns true if the admission controller is ready to handle requests. +type ReadyFunc func() bool + +// Handler is a base for admission control handlers that +// support a predefined set of operations +type Handler struct { + operations sets.String + readyFunc ReadyFunc +} + +// Handles returns true for methods that this handler supports +func (h *Handler) Handles(operation Operation) bool { + return h.operations.Has(string(operation)) +} + +// NewHandler creates a new base handler that handles the passed +// in operations +func NewHandler(ops ...Operation) *Handler { + operations := sets.NewString() + for _, op := range ops { + operations.Insert(string(op)) + } + return &Handler{ + operations: operations, + } +} + +// SetReadyFunc allows late registration of a ReadyFunc to know if the handler is ready to process requests. +func (h *Handler) SetReadyFunc(readyFunc ReadyFunc) { + h.readyFunc = readyFunc +} + +// WaitForReady will wait for the readyFunc (if registered) to return ready, and in case of timeout, will return false. +func (h *Handler) WaitForReady() bool { + // there is no ready func configured, so we return immediately + if h.readyFunc == nil { + return true + } + + timeout := time.After(timeToWaitForReady) + for !h.readyFunc() { + select { + case <-time.After(100 * time.Millisecond): + case <-timeout: + return h.readyFunc() + } + } + return true +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/initializer/initializer.go b/vendor/k8s.io/apiserver/pkg/admission/initializer/initializer.go new file mode 100644 index 00000000000..2d293d79ac6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/initializer/initializer.go @@ -0,0 +1,88 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package initializer + +import ( + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/component-base/featuregate" +) + +type pluginInitializer struct { + externalClient kubernetes.Interface + dynamicClient dynamic.Interface + externalInformers informers.SharedInformerFactory + authorizer authorizer.Authorizer + featureGates featuregate.FeatureGate + stopCh <-chan struct{} +} + +// New creates an instance of admission plugins initializer. +// This constructor is public with a long param list so that callers immediately know that new information can be expected +// during compilation when they update a level. +func New( + extClientset kubernetes.Interface, + dynamicClient dynamic.Interface, + extInformers informers.SharedInformerFactory, + authz authorizer.Authorizer, + featureGates featuregate.FeatureGate, + stopCh <-chan struct{}, +) pluginInitializer { + return pluginInitializer{ + externalClient: extClientset, + dynamicClient: dynamicClient, + externalInformers: extInformers, + authorizer: authz, + featureGates: featureGates, + stopCh: stopCh, + } +} + +// Initialize checks the initialization interfaces implemented by a plugin +// and provide the appropriate initialization data +func (i pluginInitializer) Initialize(plugin admission.Interface) { + // First tell the plugin about drained notification, so it can pass it to further initializations. + if wants, ok := plugin.(WantsDrainedNotification); ok { + wants.SetDrainedNotification(i.stopCh) + } + + // Second tell the plugin about enabled features, so it can decide whether to start informers or not + if wants, ok := plugin.(WantsFeatures); ok { + wants.InspectFeatureGates(i.featureGates) + } + + if wants, ok := plugin.(WantsExternalKubeClientSet); ok { + wants.SetExternalKubeClientSet(i.externalClient) + } + + if wants, ok := plugin.(WantsDynamicClient); ok { + wants.SetDynamicClient(i.dynamicClient) + } + + if wants, ok := plugin.(WantsExternalKubeInformerFactory); ok { + wants.SetExternalKubeInformerFactory(i.externalInformers) + } + + if wants, ok := plugin.(WantsAuthorizer); ok { + wants.SetAuthorizer(i.authorizer) + } +} + +var _ admission.PluginInitializer = pluginInitializer{} diff --git a/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go new file mode 100644 index 00000000000..6077c89de84 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go @@ -0,0 +1,91 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package initializer + +import ( + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + quota "k8s.io/apiserver/pkg/quota/v1" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/component-base/featuregate" +) + +// WantsExternalKubeClientSet defines a function which sets external ClientSet for admission plugins that need it +type WantsExternalKubeClientSet interface { + SetExternalKubeClientSet(kubernetes.Interface) + admission.InitializationValidator +} + +// WantsExternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it +type WantsExternalKubeInformerFactory interface { + SetExternalKubeInformerFactory(informers.SharedInformerFactory) + admission.InitializationValidator +} + +// WantsAuthorizer defines a function which sets Authorizer for admission plugins that need it. +type WantsAuthorizer interface { + SetAuthorizer(authorizer.Authorizer) + admission.InitializationValidator +} + +// WantsQuotaConfiguration defines a function which sets quota configuration for admission plugins that need it. +type WantsQuotaConfiguration interface { + SetQuotaConfiguration(quota.Configuration) + admission.InitializationValidator +} + +// WantsDrainedNotification defines a function which sets the notification of where the apiserver +// has already been drained for admission plugins that need it. +// After receiving that notification, Admit/Validate calls won't be called anymore. +type WantsDrainedNotification interface { + SetDrainedNotification(<-chan struct{}) + admission.InitializationValidator +} + +// WantsFeatureGate defines a function which passes the featureGates for inspection by an admission plugin. +// Admission plugins should not hold a reference to the featureGates. Instead, they should query a particular one +// and assign it to a simple bool in the admission plugin struct. +// +// func (a *admissionPlugin) InspectFeatureGates(features featuregate.FeatureGate){ +// a.myFeatureIsOn = features.Enabled("my-feature") +// } +type WantsFeatures interface { + InspectFeatureGates(featuregate.FeatureGate) + admission.InitializationValidator +} + +type WantsDynamicClient interface { + SetDynamicClient(dynamic.Interface) + admission.InitializationValidator +} + +// WantsRESTMapper defines a function which sets RESTMapper for admission plugins that need it. +type WantsRESTMapper interface { + SetRESTMapper(meta.RESTMapper) + admission.InitializationValidator +} + +// WantsSchemaResolver defines a function which sets the SchemaResolver for +// an admission plugin that needs it. +type WantsSchemaResolver interface { + SetSchemaResolver(resolver resolver.SchemaResolver) + admission.InitializationValidator +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/interfaces.go b/vendor/k8s.io/apiserver/pkg/admission/interfaces.go new file mode 100644 index 00000000000..ba979c973f1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/interfaces.go @@ -0,0 +1,172 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "context" + "io" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/authentication/user" +) + +// Attributes is an interface used by AdmissionController to get information about a request +// that is used to make an admission decision. +type Attributes interface { + // GetName returns the name of the object as presented in the request. On a CREATE operation, the client + // may omit name and rely on the server to generate the name. If that is the case, this method will return + // the empty string + GetName() string + // GetNamespace is the namespace associated with the request (if any) + GetNamespace() string + // GetResource is the name of the resource being requested. This is not the kind. For example: pods + GetResource() schema.GroupVersionResource + // GetSubresource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind. + // For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod" + // (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding". + GetSubresource() string + // GetOperation is the operation being performed + GetOperation() Operation + // GetOperationOptions is the options for the operation being performed + GetOperationOptions() runtime.Object + // IsDryRun indicates that modifications will definitely not be persisted for this request. This is to prevent + // admission controllers with side effects and a method of reconciliation from being overwhelmed. + // However, a value of false for this does not mean that the modification will be persisted, because it + // could still be rejected by a subsequent validation step. + IsDryRun() bool + // GetObject is the object from the incoming request prior to default values being applied + GetObject() runtime.Object + // GetOldObject is the existing object. Only populated for UPDATE and DELETE requests. + GetOldObject() runtime.Object + // GetKind is the type of object being manipulated. For example: Pod + GetKind() schema.GroupVersionKind + // GetUserInfo is information about the requesting user + GetUserInfo() user.Info + + // AddAnnotation sets annotation according to key-value pair. The key should be qualified, e.g., podsecuritypolicy.admission.k8s.io/admit-policy, where + // "podsecuritypolicy" is the name of the plugin, "admission.k8s.io" is the name of the organization, "admit-policy" is the key name. + // An error is returned if the format of key is invalid. When trying to overwrite annotation with a new value, an error is returned. + // Both ValidationInterface and MutationInterface are allowed to add Annotations. + // By default, an annotation gets logged into audit event if the request's audit level is greater or + // equal to Metadata. + AddAnnotation(key, value string) error + + // AddAnnotationWithLevel sets annotation according to key-value pair with additional intended audit level. + // An Annotation gets logged into audit event if the request's audit level is greater or equal to the + // intended audit level. + AddAnnotationWithLevel(key, value string, level auditinternal.Level) error + + // GetReinvocationContext tracks the admission request information relevant to the re-invocation policy. + GetReinvocationContext() ReinvocationContext +} + +// ObjectInterfaces is an interface used by AdmissionController to get object interfaces +// such as Converter or Defaulter. These interfaces are normally coming from Request Scope +// to handle special cases like CRDs. +type ObjectInterfaces interface { + // GetObjectCreater is the ObjectCreator appropriate for the requested object. + GetObjectCreater() runtime.ObjectCreater + // GetObjectTyper is the ObjectTyper appropriate for the requested object. + GetObjectTyper() runtime.ObjectTyper + // GetObjectDefaulter is the ObjectDefaulter appropriate for the requested object. + GetObjectDefaulter() runtime.ObjectDefaulter + // GetObjectConvertor is the ObjectConvertor appropriate for the requested object. + GetObjectConvertor() runtime.ObjectConvertor + // GetEquivalentResourceMapper is the EquivalentResourceMapper appropriate for finding equivalent resources and expected kind for the requested object. + GetEquivalentResourceMapper() runtime.EquivalentResourceMapper +} + +// privateAnnotationsGetter is a private interface which allows users to get annotations from Attributes. +type privateAnnotationsGetter interface { + getAnnotations(maxLevel auditinternal.Level) map[string]string +} + +// AnnotationsGetter allows users to get annotations from Attributes. An alternate Attribute should implement +// this interface. +type AnnotationsGetter interface { + GetAnnotations(maxLevel auditinternal.Level) map[string]string +} + +// ReinvocationContext provides access to the admission related state required to implement the re-invocation policy. +type ReinvocationContext interface { + // IsReinvoke returns true if the current admission check is a re-invocation. + IsReinvoke() bool + // SetIsReinvoke sets the current admission check as a re-invocation. + SetIsReinvoke() + // ShouldReinvoke returns true if any plugin has requested a re-invocation. + ShouldReinvoke() bool + // SetShouldReinvoke signals that a re-invocation is desired. + SetShouldReinvoke() + // AddValue set a value for a plugin name, possibly overriding a previous value. + SetValue(plugin string, v interface{}) + // Value reads a value for a webhook. + Value(plugin string) interface{} +} + +// Interface is an abstract, pluggable interface for Admission Control decisions. +type Interface interface { + // Handles returns true if this admission controller can handle the given operation + // where operation can be one of CREATE, UPDATE, DELETE, or CONNECT + Handles(operation Operation) bool +} + +type MutationInterface interface { + Interface + + // Admit makes an admission decision based on the request attributes. + // Context is used only for timeout/deadline/cancellation and tracing information. + Admit(ctx context.Context, a Attributes, o ObjectInterfaces) (err error) +} + +// ValidationInterface is an abstract, pluggable interface for Admission Control decisions. +type ValidationInterface interface { + Interface + + // Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate + // Context is used only for timeout/deadline/cancellation and tracing information. + Validate(ctx context.Context, a Attributes, o ObjectInterfaces) (err error) +} + +// Operation is the type of resource operation being checked for admission control +type Operation string + +// Operation constants +const ( + Create Operation = "CREATE" + Update Operation = "UPDATE" + Delete Operation = "DELETE" + Connect Operation = "CONNECT" +) + +// PluginInitializer is used for initialization of shareable resources between admission plugins. +// After initialization the resources have to be set separately +type PluginInitializer interface { + Initialize(plugin Interface) +} + +// InitializationValidator holds ValidateInitialization functions, which are responsible for validation of initialized +// shared resources and should be implemented on admission plugins +type InitializationValidator interface { + ValidateInitialization() error +} + +// ConfigProvider provides a way to get configuration for an admission plugin based on its name +type ConfigProvider interface { + ConfigFor(pluginName string) (io.Reader, error) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go new file mode 100644 index 00000000000..26b82c37e39 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go @@ -0,0 +1,315 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "strconv" + "time" + + "k8s.io/apiserver/pkg/admission" + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +// WebhookRejectionErrorType defines different error types that happen in a webhook rejection. +type WebhookRejectionErrorType string + +const ( + namespace = "apiserver" + subsystem = "admission" + + // WebhookRejectionCallingWebhookError identifies a calling webhook error which causes + // a webhook admission to reject a request + WebhookRejectionCallingWebhookError WebhookRejectionErrorType = "calling_webhook_error" + // WebhookRejectionAPIServerInternalError identifies an apiserver internal error which + // causes a webhook admission to reject a request + WebhookRejectionAPIServerInternalError WebhookRejectionErrorType = "apiserver_internal_error" + // WebhookRejectionNoError identifies a webhook properly rejected a request + WebhookRejectionNoError WebhookRejectionErrorType = "no_error" +) + +var ( + latencySummaryMaxAge = 5 * time.Hour + + // Metrics provides access to all admission metrics. + Metrics = newAdmissionMetrics() +) + +// ObserverFunc is a func that emits metrics. +type ObserverFunc func(ctx context.Context, elapsed time.Duration, rejected bool, attr admission.Attributes, stepType string, extraLabels ...string) + +const ( + stepValidate = "validate" + stepAdmit = "admit" +) + +// WithControllerMetrics is a decorator for named admission handlers. +func WithControllerMetrics(i admission.Interface, name string) admission.Interface { + return WithMetrics(i, Metrics.ObserveAdmissionController, name) +} + +// WithStepMetrics is a decorator for a whole admission phase, i.e. admit or validation.admission step. +func WithStepMetrics(i admission.Interface) admission.Interface { + return WithMetrics(i, Metrics.ObserveAdmissionStep) +} + +// WithMetrics is a decorator for admission handlers with a generic observer func. +func WithMetrics(i admission.Interface, observer ObserverFunc, extraLabels ...string) admission.Interface { + return &pluginHandlerWithMetrics{ + Interface: i, + observer: observer, + extraLabels: extraLabels, + } +} + +// pluginHandlerWithMetrics decorates a admission handler with metrics. +type pluginHandlerWithMetrics struct { + admission.Interface + observer ObserverFunc + extraLabels []string +} + +// Admit performs a mutating admission control check and emit metrics. +func (p pluginHandlerWithMetrics) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { + mutatingHandler, ok := p.Interface.(admission.MutationInterface) + if !ok { + return nil + } + + start := time.Now() + err := mutatingHandler.Admit(ctx, a, o) + p.observer(ctx, time.Since(start), err != nil, a, stepAdmit, p.extraLabels...) + return err +} + +// Validate performs a non-mutating admission control check and emits metrics. +func (p pluginHandlerWithMetrics) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { + validatingHandler, ok := p.Interface.(admission.ValidationInterface) + if !ok { + return nil + } + + start := time.Now() + err := validatingHandler.Validate(ctx, a, o) + p.observer(ctx, time.Since(start), err != nil, a, stepValidate, p.extraLabels...) + return err +} + +// AdmissionMetrics instruments admission with prometheus metrics. +type AdmissionMetrics struct { + step *metricSet + controller *metricSet + webhook *metricSet + webhookRejection *metrics.CounterVec + webhookFailOpen *metrics.CounterVec + webhookRequest *metrics.CounterVec + matchConditionEvalErrors *metrics.CounterVec +} + +// newAdmissionMetrics create a new AdmissionMetrics, configured with default metric names. +func newAdmissionMetrics() *AdmissionMetrics { + // Admission metrics for a step of the admission flow. The entire admission flow is broken down into a series of steps + // Each step is identified by a distinct type label value. + // Use buckets ranging from 5 ms to 2.5 seconds. + step := &metricSet{ + latencies: metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "step_admission_duration_seconds", + Help: "Admission sub-step latency histogram in seconds, broken out for each operation and API resource and step type (validate or admit).", + Buckets: []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, + StabilityLevel: metrics.STABLE, + }, + []string{"type", "operation", "rejected"}, + ), + + latenciesSummary: metrics.NewSummaryVec( + &metrics.SummaryOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "step_admission_duration_seconds_summary", + Help: "Admission sub-step latency summary in seconds, broken out for each operation and API resource and step type (validate or admit).", + MaxAge: latencySummaryMaxAge, + StabilityLevel: metrics.ALPHA, + }, + []string{"type", "operation", "rejected"}, + ), + } + + // Built-in admission controller metrics. Each admission controller is identified by name. + // Use buckets ranging from 5 ms to 2.5 seconds. + controller := &metricSet{ + latencies: metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "controller_admission_duration_seconds", + Help: "Admission controller latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit).", + Buckets: []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, + StabilityLevel: metrics.STABLE, + }, + []string{"name", "type", "operation", "rejected"}, + ), + + latenciesSummary: nil, + } + + // Admission webhook metrics. Each webhook is identified by name. + // Use buckets ranging from 5 ms to 2.5 seconds (admission webhooks timeout at 30 seconds by default). + webhook := &metricSet{ + latencies: metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "webhook_admission_duration_seconds", + Help: "Admission webhook latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit).", + Buckets: []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5, 10, 25}, + StabilityLevel: metrics.STABLE, + }, + []string{"name", "type", "operation", "rejected"}, + ), + + latenciesSummary: nil, + } + + webhookRejection := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "webhook_rejection_count", + Help: "Admission webhook rejection count, identified by name and broken out for each admission type (validating or admit) and operation. Additional labels specify an error type (calling_webhook_error or apiserver_internal_error if an error occurred; no_error otherwise) and optionally a non-zero rejection code if the webhook rejects the request with an HTTP status code (honored by the apiserver when the code is greater or equal to 400). Codes greater than 600 are truncated to 600, to keep the metrics cardinality bounded.", + StabilityLevel: metrics.ALPHA, + }, + []string{"name", "type", "operation", "error_type", "rejection_code"}) + + webhookFailOpen := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "webhook_fail_open_count", + Help: "Admission webhook fail open count, identified by name and broken out for each admission type (validating or mutating).", + StabilityLevel: metrics.ALPHA, + }, + []string{"name", "type"}) + + webhookRequest := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "webhook_request_total", + Help: "Admission webhook request total, identified by name and broken out for each admission type (validating or mutating) and operation. Additional labels specify whether the request was rejected or not and an HTTP status code. Codes greater than 600 are truncated to 600, to keep the metrics cardinality bounded.", + StabilityLevel: metrics.ALPHA, + }, + []string{"name", "type", "operation", "code", "rejected"}) + + matchConditionEvalError := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "admission_match_condition_evaluation_errors_total", + Help: "Admission match condition evaluation errors count, identified by name of resource containing the match condition and broken out for each admission type (validating or mutating).", + StabilityLevel: metrics.ALPHA, + }, + []string{"name", "type"}) + + step.mustRegister() + controller.mustRegister() + webhook.mustRegister() + legacyregistry.MustRegister(webhookRejection) + legacyregistry.MustRegister(webhookFailOpen) + legacyregistry.MustRegister(webhookRequest) + legacyregistry.MustRegister(matchConditionEvalError) + return &AdmissionMetrics{step: step, controller: controller, webhook: webhook, webhookRejection: webhookRejection, webhookFailOpen: webhookFailOpen, webhookRequest: webhookRequest, matchConditionEvalErrors: matchConditionEvalError} +} + +func (m *AdmissionMetrics) reset() { + m.step.reset() + m.controller.reset() + m.webhook.reset() +} + +// ObserveAdmissionStep records admission related metrics for a admission step, identified by step type. +func (m *AdmissionMetrics) ObserveAdmissionStep(ctx context.Context, elapsed time.Duration, rejected bool, attr admission.Attributes, stepType string, extraLabels ...string) { + m.step.observe(ctx, elapsed, append(extraLabels, stepType, string(attr.GetOperation()), strconv.FormatBool(rejected))...) +} + +// ObserveAdmissionController records admission related metrics for a built-in admission controller, identified by it's plugin handler name. +func (m *AdmissionMetrics) ObserveAdmissionController(ctx context.Context, elapsed time.Duration, rejected bool, attr admission.Attributes, stepType string, extraLabels ...string) { + m.controller.observe(ctx, elapsed, append(extraLabels, stepType, string(attr.GetOperation()), strconv.FormatBool(rejected))...) +} + +// ObserveWebhook records admission related metrics for a admission webhook. +func (m *AdmissionMetrics) ObserveWebhook(ctx context.Context, name string, elapsed time.Duration, rejected bool, attr admission.Attributes, stepType string, code int) { + // We truncate codes greater than 600 to keep the cardinality bounded. + if code > 600 { + code = 600 + } + m.webhookRequest.WithContext(ctx).WithLabelValues(name, stepType, string(attr.GetOperation()), strconv.Itoa(code), strconv.FormatBool(rejected)).Inc() + m.webhook.observe(ctx, elapsed, name, stepType, string(attr.GetOperation()), strconv.FormatBool(rejected)) +} + +// ObserveWebhookRejection records admission related metrics for an admission webhook rejection. +func (m *AdmissionMetrics) ObserveWebhookRejection(ctx context.Context, name, stepType, operation string, errorType WebhookRejectionErrorType, rejectionCode int) { + // We truncate codes greater than 600 to keep the cardinality bounded. + // This should be rarely done by a malfunctioning webhook server. + if rejectionCode > 600 { + rejectionCode = 600 + } + m.webhookRejection.WithContext(ctx).WithLabelValues(name, stepType, operation, string(errorType), strconv.Itoa(rejectionCode)).Inc() +} + +// ObserveWebhookFailOpen records validating or mutating webhook that fail open. +func (m *AdmissionMetrics) ObserveWebhookFailOpen(ctx context.Context, name, stepType string) { + m.webhookFailOpen.WithContext(ctx).WithLabelValues(name, stepType).Inc() +} + +// ObserveMatchConditionEvalError records validating or mutating webhook that are not called due to match conditions +func (m *AdmissionMetrics) ObserveMatchConditionEvalError(ctx context.Context, name, stepType string) { + m.matchConditionEvalErrors.WithContext(ctx).WithLabelValues(name, stepType).Inc() +} + +type metricSet struct { + latencies *metrics.HistogramVec + latenciesSummary *metrics.SummaryVec +} + +// MustRegister registers all the prometheus metrics in the metricSet. +func (m *metricSet) mustRegister() { + legacyregistry.MustRegister(m.latencies) + if m.latenciesSummary != nil { + legacyregistry.MustRegister(m.latenciesSummary) + } +} + +// Reset resets all the prometheus metrics in the metricSet. +func (m *metricSet) reset() { + m.latencies.Reset() + if m.latenciesSummary != nil { + m.latenciesSummary.Reset() + } +} + +// Observe records an observed admission event to all metrics in the metricSet. +func (m *metricSet) observe(ctx context.Context, elapsed time.Duration, labels ...string) { + elapsedSeconds := elapsed.Seconds() + m.latencies.WithContext(ctx).WithLabelValues(labels...).Observe(elapsedSeconds) + if m.latenciesSummary != nil { + m.latenciesSummary.WithContext(ctx).WithLabelValues(labels...).Observe(elapsedSeconds) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS new file mode 100644 index 00000000000..6a637d28d58 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - jpbetz + - cici37 + - alexzielenski +reviewers: + - jpbetz + - cici37 + - alexzielenski diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go new file mode 100644 index 00000000000..bb122de5faf --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go @@ -0,0 +1,281 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "fmt" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "sync" + + "github.com/google/cel-go/cel" + + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/library" +) + +const ( + ObjectVarName = "object" + OldObjectVarName = "oldObject" + ParamsVarName = "params" + RequestVarName = "request" + AuthorizerVarName = "authorizer" + RequestResourceAuthorizerVarName = "authorizer.requestResource" +) + +var ( + initEnvsOnce sync.Once + initEnvs envs + initEnvsErr error +) + +func getEnvs() (envs, error) { + initEnvsOnce.Do(func() { + requiredVarsEnv, err := buildRequiredVarsEnv() + if err != nil { + initEnvsErr = err + return + } + + initEnvs, err = buildWithOptionalVarsEnvs(requiredVarsEnv) + if err != nil { + initEnvsErr = err + return + } + }) + return initEnvs, initEnvsErr +} + +// This is a similar code as in k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/compilation.go +// If any changes are made here, consider to make the same changes there as well. +func buildBaseEnv() (*cel.Env, error) { + var opts []cel.EnvOption + opts = append(opts, cel.HomogeneousAggregateLiterals()) + // Validate function declarations once during base env initialization, + // so they don't need to be evaluated each time a CEL rule is compiled. + // This is a relatively expensive operation. + opts = append(opts, cel.EagerlyValidateDeclarations(true), cel.DefaultUTCTimeZone(true)) + opts = append(opts, library.ExtensionLibs...) + + return cel.NewEnv(opts...) +} + +func buildRequiredVarsEnv() (*cel.Env, error) { + baseEnv, err := buildBaseEnv() + if err != nil { + return nil, err + } + var propDecls []cel.EnvOption + reg := apiservercel.NewRegistry(baseEnv) + + requestType := BuildRequestType() + rt, err := apiservercel.NewRuleTypes(requestType.TypeName(), requestType, reg) + if err != nil { + return nil, err + } + if rt == nil { + return nil, nil + } + opts, err := rt.EnvOptions(baseEnv.TypeProvider()) + if err != nil { + return nil, err + } + propDecls = append(propDecls, cel.Variable(ObjectVarName, cel.DynType)) + propDecls = append(propDecls, cel.Variable(OldObjectVarName, cel.DynType)) + propDecls = append(propDecls, cel.Variable(RequestVarName, requestType.CelType())) + + opts = append(opts, propDecls...) + env, err := baseEnv.Extend(opts...) + if err != nil { + return nil, err + } + return env, nil +} + +type envs map[OptionalVariableDeclarations]*cel.Env + +func buildEnvWithVars(baseVarsEnv *cel.Env, options OptionalVariableDeclarations) (*cel.Env, error) { + var opts []cel.EnvOption + if options.HasParams { + opts = append(opts, cel.Variable(ParamsVarName, cel.DynType)) + } + if options.HasAuthorizer { + opts = append(opts, cel.Variable(AuthorizerVarName, library.AuthorizerType)) + opts = append(opts, cel.Variable(RequestResourceAuthorizerVarName, library.ResourceCheckType)) + } + return baseVarsEnv.Extend(opts...) +} + +func buildWithOptionalVarsEnvs(requiredVarsEnv *cel.Env) (envs, error) { + envs := make(envs, 4) // since the number of variable combinations is small, pre-build a environment for each + for _, hasParams := range []bool{false, true} { + for _, hasAuthorizer := range []bool{false, true} { + opts := OptionalVariableDeclarations{HasParams: hasParams, HasAuthorizer: hasAuthorizer} + env, err := buildEnvWithVars(requiredVarsEnv, opts) + if err != nil { + return nil, err + } + envs[opts] = env + } + } + return envs, nil +} + +// BuildRequestType generates a DeclType for AdmissionRequest. This may be replaced with a utility that +// converts the native type definition to apiservercel.DeclType once such a utility becomes available. +// The 'uid' field is omitted since it is not needed for in-process admission review. +// The 'object' and 'oldObject' fields are omitted since they are exposed as root level CEL variables. +func BuildRequestType() *apiservercel.DeclType { + field := func(name string, declType *apiservercel.DeclType, required bool) *apiservercel.DeclField { + return apiservercel.NewDeclField(name, declType, required, nil, nil) + } + fields := func(fields ...*apiservercel.DeclField) map[string]*apiservercel.DeclField { + result := make(map[string]*apiservercel.DeclField, len(fields)) + for _, f := range fields { + result[f.Name] = f + } + return result + } + gvkType := apiservercel.NewObjectType("kubernetes.GroupVersionKind", fields( + field("group", apiservercel.StringType, true), + field("version", apiservercel.StringType, true), + field("kind", apiservercel.StringType, true), + )) + gvrType := apiservercel.NewObjectType("kubernetes.GroupVersionResource", fields( + field("group", apiservercel.StringType, true), + field("version", apiservercel.StringType, true), + field("resource", apiservercel.StringType, true), + )) + userInfoType := apiservercel.NewObjectType("kubernetes.UserInfo", fields( + field("username", apiservercel.StringType, false), + field("uid", apiservercel.StringType, false), + field("groups", apiservercel.NewListType(apiservercel.StringType, -1), false), + field("extra", apiservercel.NewMapType(apiservercel.StringType, apiservercel.NewListType(apiservercel.StringType, -1), -1), false), + )) + return apiservercel.NewObjectType("kubernetes.AdmissionRequest", fields( + field("kind", gvkType, true), + field("resource", gvrType, true), + field("subResource", apiservercel.StringType, false), + field("requestKind", gvkType, true), + field("requestResource", gvrType, true), + field("requestSubResource", apiservercel.StringType, false), + field("name", apiservercel.StringType, true), + field("namespace", apiservercel.StringType, false), + field("operation", apiservercel.StringType, true), + field("userInfo", userInfoType, true), + field("dryRun", apiservercel.BoolType, false), + field("options", apiservercel.DynType, false), + )) +} + +// CompilationResult represents a compiled validations expression. +type CompilationResult struct { + Program cel.Program + Error *apiservercel.Error + ExpressionAccessor ExpressionAccessor +} + +// CompileCELExpression returns a compiled CEL expression. +// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func CompileCELExpression(expressionAccessor ExpressionAccessor, optionalVars OptionalVariableDeclarations, perCallLimit uint64) CompilationResult { + var env *cel.Env + envs, err := getEnvs() + if err != nil { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInternal, + Detail: "compiler initialization failed: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + env, ok := envs[optionalVars] + if !ok { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: fmt.Sprintf("compiler initialization failed: failed to load environment for %v", optionalVars), + }, + ExpressionAccessor: expressionAccessor, + } + } + + ast, issues := env.Compile(expressionAccessor.GetExpression()) + if issues != nil { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: "compilation failed: " + issues.String(), + }, + ExpressionAccessor: expressionAccessor, + } + } + found := false + returnTypes := expressionAccessor.ReturnTypes() + for _, returnType := range returnTypes { + if ast.OutputType() == returnType { + found = true + break + } + } + if !found { + var reason string + if len(returnTypes) == 1 { + reason = fmt.Sprintf("must evaluate to %v", returnTypes[0].String()) + } else { + reason = fmt.Sprintf("must evaluate to one of %v", returnTypes) + } + + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: reason, + }, + ExpressionAccessor: expressionAccessor, + } + } + + _, err = cel.AstToCheckedExpr(ast) + if err != nil { + // should be impossible since env.Compile returned no issues + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInternal, + Detail: "unexpected compilation error: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + prog, err := env.Program(ast, + cel.EvalOptions(cel.OptOptimize, cel.OptTrackCost), + cel.OptimizeRegex(library.ExtensionLibRegexOptimizations...), + cel.InterruptCheckFrequency(celconfig.CheckFrequency), + cel.CostLimit(perCallLimit), + ) + if err != nil { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: "program instantiation failed: " + err.Error(), + }, + ExpressionAccessor: expressionAccessor, + } + } + return CompilationResult{ + Program: prog, + ExpressionAccessor: expressionAccessor, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go new file mode 100644 index 00000000000..6e504897c5a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go @@ -0,0 +1,296 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "context" + "fmt" + "math" + "reflect" + "time" + + "github.com/google/cel-go/interpreter" + + admissionv1 "k8s.io/api/admission/v1" + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/library" +) + +// filterCompiler implement the interface FilterCompiler. +type filterCompiler struct { +} + +func NewFilterCompiler() FilterCompiler { + return &filterCompiler{} +} + +type evaluationActivation struct { + object, oldObject, params, request, authorizer, requestResourceAuthorizer interface{} +} + +// ResolveName returns a value from the activation by qualified name, or false if the name +// could not be found. +func (a *evaluationActivation) ResolveName(name string) (interface{}, bool) { + switch name { + case ObjectVarName: + return a.object, true + case OldObjectVarName: + return a.oldObject, true + case ParamsVarName: + return a.params, true // params may be null + case RequestVarName: + return a.request, true + case AuthorizerVarName: + return a.authorizer, a.authorizer != nil + case RequestResourceAuthorizerVarName: + return a.requestResourceAuthorizer, a.requestResourceAuthorizer != nil + default: + return nil, false + } +} + +// Parent returns the parent of the current activation, may be nil. +// If non-nil, the parent will be searched during resolve calls. +func (a *evaluationActivation) Parent() interpreter.Activation { + return nil +} + +// Compile compiles the cel expressions defined in the ExpressionAccessors into a Filter +func (c *filterCompiler) Compile(expressionAccessors []ExpressionAccessor, options OptionalVariableDeclarations, perCallLimit uint64) Filter { + compilationResults := make([]CompilationResult, len(expressionAccessors)) + for i, expressionAccessor := range expressionAccessors { + if expressionAccessor == nil { + continue + } + compilationResults[i] = CompileCELExpression(expressionAccessor, options, perCallLimit) + } + return NewFilter(compilationResults) +} + +// filter implements the Filter interface +type filter struct { + compilationResults []CompilationResult +} + +func NewFilter(compilationResults []CompilationResult) Filter { + return &filter{ + compilationResults, + } +} + +func convertObjectToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { + if obj == nil || reflect.ValueOf(obj).IsNil() { + return &unstructured.Unstructured{Object: nil}, nil + } + ret, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + return &unstructured.Unstructured{Object: ret}, nil +} + +func objectToResolveVal(r runtime.Object) (interface{}, error) { + if r == nil || reflect.ValueOf(r).IsNil() { + return nil, nil + } + v, err := convertObjectToUnstructured(r) + if err != nil { + return nil, err + } + return v.Object, nil +} + +// ForInput evaluates the compiled CEL expressions converting them into CELEvaluations +// errors per evaluation are returned on the Evaluation object +// runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func (f *filter) ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, int64, error) { + // TODO: replace unstructured with ref.Val for CEL variables when native type support is available + evaluations := make([]EvaluationResult, len(f.compilationResults)) + var err error + + oldObjectVal, err := objectToResolveVal(versionedAttr.VersionedOldObject) + if err != nil { + return nil, -1, err + } + objectVal, err := objectToResolveVal(versionedAttr.VersionedObject) + if err != nil { + return nil, -1, err + } + var paramsVal, authorizerVal, requestResourceAuthorizerVal any + if inputs.VersionedParams != nil { + paramsVal, err = objectToResolveVal(inputs.VersionedParams) + if err != nil { + return nil, -1, err + } + } + + if inputs.Authorizer != nil { + authorizerVal = library.NewAuthorizerVal(versionedAttr.GetUserInfo(), inputs.Authorizer) + requestResourceAuthorizerVal = library.NewResourceAuthorizerVal(versionedAttr.GetUserInfo(), inputs.Authorizer, versionedAttr) + } + + requestVal, err := convertObjectToUnstructured(request) + if err != nil { + return nil, -1, err + } + va := &evaluationActivation{ + object: objectVal, + oldObject: oldObjectVal, + params: paramsVal, + request: requestVal.Object, + authorizer: authorizerVal, + requestResourceAuthorizer: requestResourceAuthorizerVal, + } + + remainingBudget := runtimeCELCostBudget + for i, compilationResult := range f.compilationResults { + var evaluation = &evaluations[i] + if compilationResult.ExpressionAccessor == nil { // in case of placeholder + continue + } + evaluation.ExpressionAccessor = compilationResult.ExpressionAccessor + if compilationResult.Error != nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("compilation error: %v", compilationResult.Error), + } + continue + } + if compilationResult.Program == nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("unexpected internal error compiling expression"), + } + continue + } + t1 := time.Now() + evalResult, evalDetails, err := compilationResult.Program.ContextEval(ctx, va) + elapsed := time.Since(t1) + evaluation.Elapsed = elapsed + if evalDetails == nil { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("runtime cost could not be calculated for expression: %v, no further expression will be run", compilationResult.ExpressionAccessor.GetExpression()), + } + } else { + rtCost := evalDetails.ActualCost() + if rtCost == nil { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("runtime cost could not be calculated for expression: %v, no further expression will be run", compilationResult.ExpressionAccessor.GetExpression()), + } + } else { + if *rtCost > math.MaxInt64 || int64(*rtCost) > remainingBudget { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("validation failed due to running out of cost budget, no further validation rules will be run"), + } + } + remainingBudget -= int64(*rtCost) + } + } + if err != nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("expression '%v' resulted in error: %v", compilationResult.ExpressionAccessor.GetExpression(), err), + } + } else { + evaluation.EvalResult = evalResult + } + } + + return evaluations, remainingBudget, nil +} + +// TODO: to reuse https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go#L154 +func CreateAdmissionRequest(attr admission.Attributes) *admissionv1.AdmissionRequest { + // FIXME: how to get resource GVK, GVR and subresource? + gvk := attr.GetKind() + gvr := attr.GetResource() + subresource := attr.GetSubresource() + + requestGVK := attr.GetKind() + requestGVR := attr.GetResource() + requestSubResource := attr.GetSubresource() + + aUserInfo := attr.GetUserInfo() + var userInfo authenticationv1.UserInfo + if aUserInfo != nil { + userInfo = authenticationv1.UserInfo{ + Extra: make(map[string]authenticationv1.ExtraValue), + Groups: aUserInfo.GetGroups(), + UID: aUserInfo.GetUID(), + Username: aUserInfo.GetName(), + } + // Convert the extra information in the user object + for key, val := range aUserInfo.GetExtra() { + userInfo.Extra[key] = authenticationv1.ExtraValue(val) + } + } + + dryRun := attr.IsDryRun() + + return &admissionv1.AdmissionRequest{ + Kind: metav1.GroupVersionKind{ + Group: gvk.Group, + Kind: gvk.Kind, + Version: gvk.Version, + }, + Resource: metav1.GroupVersionResource{ + Group: gvr.Group, + Resource: gvr.Resource, + Version: gvr.Version, + }, + SubResource: subresource, + RequestKind: &metav1.GroupVersionKind{ + Group: requestGVK.Group, + Kind: requestGVK.Kind, + Version: requestGVK.Version, + }, + RequestResource: &metav1.GroupVersionResource{ + Group: requestGVR.Group, + Resource: requestGVR.Resource, + Version: requestGVR.Version, + }, + RequestSubResource: requestSubResource, + Name: attr.GetName(), + Namespace: attr.GetNamespace(), + Operation: admissionv1.Operation(attr.GetOperation()), + UserInfo: userInfo, + // Leave Object and OldObject unset since we don't provide access to them via request + DryRun: &dryRun, + Options: runtime.RawExtension{ + Object: attr.GetOperationOptions(), + }, + } +} + +// CompilationErrors returns a list of all the errors from the compilation of the evaluator +func (e *filter) CompilationErrors() []error { + compilationErrors := []error{} + for _, result := range e.compilationResults { + if result.Error != nil { + compilationErrors = append(compilationErrors, result.Error) + } + } + return compilationErrors +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go new file mode 100644 index 00000000000..d3c4a0217d1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go @@ -0,0 +1,87 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "context" + "time" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + + v1 "k8s.io/api/admission/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +type ExpressionAccessor interface { + GetExpression() string + ReturnTypes() []*cel.Type +} + +// EvaluationResult contains the minimal required fields and metadata of a cel evaluation +type EvaluationResult struct { + EvalResult ref.Val + ExpressionAccessor ExpressionAccessor + Elapsed time.Duration + Error error +} + +// OptionalVariableDeclarations declares which optional CEL variables +// are declared for an expression. +type OptionalVariableDeclarations struct { + // HasParams specifies if the "params" variable is declared. + // The "params" variable may still be bound to "null" when declared. + HasParams bool + // HasAuthorizer specifies if the"authorizer" and "authorizer.requestResource" + // variables are declared. When declared, the authorizer variables are + // expected to be non-null. + HasAuthorizer bool +} + +// FilterCompiler contains a function to assist with converting types and values to/from CEL-typed values. +type FilterCompiler interface { + // Compile is used for the cel expression compilation + // perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. + Compile(expressions []ExpressionAccessor, optionalDecls OptionalVariableDeclarations, perCallLimit uint64) Filter +} + +// OptionalVariableBindings provides expression bindings for optional CEL variables. +type OptionalVariableBindings struct { + // VersionedParams provides the "params" variable binding. This variable binding may + // be set to nil even when OptionalVariableDeclarations.HashParams is set to true. + VersionedParams runtime.Object + // Authorizer provides the authorizer used for the "authorizer" and + // "authorizer.requestResource" variable bindings. If the expression was compiled with + // OptionalVariableDeclarations.HasAuthorizer set to true this must be non-nil. + Authorizer authorizer.Authorizer +} + +// Filter contains a function to evaluate compiled CEL-typed values +// It expects the inbound object to already have been converted to the version expected +// by the underlying CEL code (which is indicated by the match criteria of a policy definition). +// versionedParams may be nil. +type Filter interface { + // ForInput converts compiled CEL-typed values into evaluated CEL-typed value. + // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. + // If cost budget is calculated, the filter should return the remaining budget. + ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *v1.AdmissionRequest, optionalVars OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, int64, error) + + // CompilationErrors returns a list of errors from the compilation of the evaluator + CompilationErrors() []error +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/OWNERS b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/OWNERS new file mode 100644 index 00000000000..6a637d28d58 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - jpbetz + - cici37 + - alexzielenski +reviewers: + - jpbetz + - cici37 + - alexzielenski diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go new file mode 100644 index 00000000000..9a514b46319 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go @@ -0,0 +1,205 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + "errors" + "fmt" + "io" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + "k8s.io/apiserver/pkg/features" + "k8s.io/client-go/dynamic" + "k8s.io/component-base/featuregate" + + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" +) + +//////////////////////////////////////////////////////////////////////////////// +// Plugin Definition +//////////////////////////////////////////////////////////////////////////////// + +// Definition for CEL admission plugin. This is the entry point into the +// CEL admission control system. +// +// Each plugin is asked to validate every object update. + +const ( + // PluginName indicates the name of admission plug-in + PluginName = "ValidatingAdmissionPolicy" +) + +// Register registers a plugin +func Register(plugins *admission.Plugins) { + plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { + return NewPlugin() + }) +} + +//////////////////////////////////////////////////////////////////////////////// +// Plugin Initialization & Dependency Injection +//////////////////////////////////////////////////////////////////////////////// + +type celAdmissionPlugin struct { + *admission.Handler + evaluator CELPolicyEvaluator + + inspectedFeatureGates bool + enabled bool + + // Injected Dependencies + informerFactory informers.SharedInformerFactory + client kubernetes.Interface + restMapper meta.RESTMapper + dynamicClient dynamic.Interface + stopCh <-chan struct{} + authorizer authorizer.Authorizer + schemaResolver resolver.SchemaResolver +} + +var _ initializer.WantsExternalKubeInformerFactory = &celAdmissionPlugin{} +var _ initializer.WantsExternalKubeClientSet = &celAdmissionPlugin{} +var _ initializer.WantsRESTMapper = &celAdmissionPlugin{} +var _ initializer.WantsDynamicClient = &celAdmissionPlugin{} +var _ initializer.WantsDrainedNotification = &celAdmissionPlugin{} +var _ initializer.WantsAuthorizer = &celAdmissionPlugin{} +var _ initializer.WantsSchemaResolver = &celAdmissionPlugin{} +var _ admission.InitializationValidator = &celAdmissionPlugin{} +var _ admission.ValidationInterface = &celAdmissionPlugin{} + +func NewPlugin() (admission.Interface, error) { + return &celAdmissionPlugin{ + Handler: admission.NewHandler(admission.Connect, admission.Create, admission.Delete, admission.Update), + }, nil +} + +func (c *celAdmissionPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { + c.informerFactory = f +} + +func (c *celAdmissionPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { + c.client = client +} + +func (c *celAdmissionPlugin) SetRESTMapper(mapper meta.RESTMapper) { + c.restMapper = mapper +} + +func (c *celAdmissionPlugin) SetDynamicClient(client dynamic.Interface) { + c.dynamicClient = client +} + +func (c *celAdmissionPlugin) SetDrainedNotification(stopCh <-chan struct{}) { + c.stopCh = stopCh +} + +func (c *celAdmissionPlugin) SetAuthorizer(authorizer authorizer.Authorizer) { + c.authorizer = authorizer +} + +func (c *celAdmissionPlugin) SetSchemaResolver(resolver resolver.SchemaResolver) { + c.schemaResolver = resolver +} + +func (c *celAdmissionPlugin) InspectFeatureGates(featureGates featuregate.FeatureGate) { + if featureGates.Enabled(features.ValidatingAdmissionPolicy) { + c.enabled = true + } + c.inspectedFeatureGates = true +} + +// ValidateInitialization - once clientset and informer factory are provided, creates and starts the admission controller +func (c *celAdmissionPlugin) ValidateInitialization() error { + if !c.inspectedFeatureGates { + return fmt.Errorf("%s did not see feature gates", PluginName) + } + if !c.enabled { + return nil + } + if c.informerFactory == nil { + return errors.New("missing informer factory") + } + if c.client == nil { + return errors.New("missing kubernetes client") + } + if c.restMapper == nil { + return errors.New("missing rest mapper") + } + if c.dynamicClient == nil { + return errors.New("missing dynamic client") + } + if c.stopCh == nil { + return errors.New("missing stop channel") + } + if c.authorizer == nil { + return errors.New("missing authorizer") + } + c.evaluator = NewAdmissionController(c.informerFactory, c.client, c.restMapper, c.schemaResolver /* (optional) */, c.dynamicClient, c.authorizer) + if err := c.evaluator.ValidateInitialization(); err != nil { + return err + } + + c.SetReadyFunc(c.evaluator.HasSynced) + go c.evaluator.Run(c.stopCh) + return nil +} + +//////////////////////////////////////////////////////////////////////////////// +// admission.ValidationInterface +//////////////////////////////////////////////////////////////////////////////// + +func (c *celAdmissionPlugin) Handles(operation admission.Operation) bool { + return true +} + +func (c *celAdmissionPlugin) Validate( + ctx context.Context, + a admission.Attributes, + o admission.ObjectInterfaces, +) (err error) { + if !c.enabled { + return nil + } + + // isPolicyResource determines if an admission.Attributes object is describing + // the admission of a ValidatingAdmissionPolicy or a ValidatingAdmissionPolicyBinding + if isPolicyResource(a) { + return + } + + if !c.WaitForReady() { + return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request")) + } + + return c.evaluator.Validate(ctx, a, o) +} + +func isPolicyResource(attr admission.Attributes) bool { + gvk := attr.GetResource() + if gvk.Group == "admissionregistration.k8s.io" { + if gvk.Resource == "validatingadmissionpolicies" || gvk.Resource == "validatingadmissionpolicybindings" { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go new file mode 100644 index 00000000000..f54f1acb36f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go @@ -0,0 +1,502 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + "sync/atomic" + "time" + + "k8s.io/klog/v2" + + "k8s.io/api/admissionregistration/v1alpha1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + utiljson "k8s.io/apimachinery/pkg/util/json" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/admission" + celmetrics "k8s.io/apiserver/pkg/admission/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + "k8s.io/apiserver/pkg/warning" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" +) + +var _ CELPolicyEvaluator = &celAdmissionController{} + +// celAdmissionController is the top-level controller for admission control using CEL +// it is responsible for watching policy definitions, bindings, and config param CRDs +type celAdmissionController struct { + // Controller which manages book-keeping for the cluster's dynamic policy + // information. + policyController *policyController + + // atomic []policyData + // list of every known policy definition, and all informatoin required to + // validate its bindings against an object. + // A snapshot of the current policy configuration is synced with this field + // asynchronously + definitions atomic.Value +} + +// Everything someone might need to validate a single ValidatingPolicyDefinition +// against all of its registered bindings. +type policyData struct { + definitionInfo + paramController generic.Controller[runtime.Object] + bindings []bindingInfo +} + +// contains the cel PolicyDecisions along with the ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding +// that determined the decision +type policyDecisionWithMetadata struct { + PolicyDecision + Definition *v1alpha1.ValidatingAdmissionPolicy + Binding *v1alpha1.ValidatingAdmissionPolicyBinding +} + +// namespaceName is used as a key in definitionInfo and bindingInfos +type namespacedName struct { + namespace, name string +} + +type definitionInfo struct { + // Error about the state of the definition's configuration and the cluster + // preventing its enforcement or compilation. + // Reset every reconciliation + configurationError error + + // Last value seen by this controller to be used in policy enforcement + // May not be nil + lastReconciledValue *v1alpha1.ValidatingAdmissionPolicy +} + +type bindingInfo struct { + // Compiled CEL expression turned into an validator + validator Validator + + // Last value seen by this controller to be used in policy enforcement + // May not be nil + lastReconciledValue *v1alpha1.ValidatingAdmissionPolicyBinding +} + +type paramInfo struct { + // Controller which is watching this param CRD + controller generic.Controller[runtime.Object] + + // Function to call to stop the informer and clean up the controller + stop func() + + // Policy Definitions which refer to this param CRD + dependentDefinitions sets.Set[namespacedName] +} + +func NewAdmissionController( + // Injected Dependencies + informerFactory informers.SharedInformerFactory, + client kubernetes.Interface, + restMapper meta.RESTMapper, + schemaResolver resolver.SchemaResolver, + dynamicClient dynamic.Interface, + authz authorizer.Authorizer, +) CELPolicyEvaluator { + var typeChecker *TypeChecker + if schemaResolver != nil { + typeChecker = &TypeChecker{schemaResolver: schemaResolver, restMapper: restMapper} + } + return &celAdmissionController{ + definitions: atomic.Value{}, + policyController: newPolicyController( + restMapper, + client, + dynamicClient, + typeChecker, + cel.NewFilterCompiler(), + NewMatcher(matching.NewMatcher(informerFactory.Core().V1().Namespaces().Lister(), client)), + generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicy]( + informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies().Informer()), + generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicyBinding]( + informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings().Informer()), + authz, + ), + } +} + +func (c *celAdmissionController) Run(stopCh <-chan struct{}) { + ctx, cancel := context.WithCancel(context.Background()) + wg := sync.WaitGroup{} + + wg.Add(1) + go func() { + defer wg.Done() + c.policyController.Run(ctx) + }() + + wg.Add(1) + go func() { + defer wg.Done() + + // Wait indefinitely until policies/bindings are listed & handled before + // allowing policies to be refreshed + if !cache.WaitForNamedCacheSync("cel-admission-controller", ctx.Done(), c.policyController.HasSynced) { + return + } + + // Loop every 1 second until context is cancelled, refreshing policies + wait.Until(c.refreshPolicies, 1*time.Second, ctx.Done()) + }() + + <-stopCh + cancel() + wg.Wait() +} + +const maxAuditAnnotationValueLength = 10 * 1024 + +func (c *celAdmissionController) Validate( + ctx context.Context, + a admission.Attributes, + o admission.ObjectInterfaces, +) (err error) { + if !c.HasSynced() { + return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request")) + } + + var deniedDecisions []policyDecisionWithMetadata + + addConfigError := func(err error, definition *v1alpha1.ValidatingAdmissionPolicy, binding *v1alpha1.ValidatingAdmissionPolicyBinding) { + // we always default the FailurePolicy if it is unset and validate it in API level + var policy v1alpha1.FailurePolicyType + if definition.Spec.FailurePolicy == nil { + policy = v1alpha1.Fail + } else { + policy = *definition.Spec.FailurePolicy + } + + // apply FailurePolicy specified in ValidatingAdmissionPolicy, the default would be Fail + switch policy { + case v1alpha1.Ignore: + // TODO: add metrics for ignored error here + return + case v1alpha1.Fail: + var message string + if binding == nil { + message = fmt.Errorf("failed to configure policy: %w", err).Error() + } else { + message = fmt.Errorf("failed to configure binding: %w", err).Error() + } + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Message: message, + }, + Definition: definition, + Binding: binding, + }) + default: + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(), + }, + Definition: definition, + Binding: binding, + }) + } + } + policyDatas := c.definitions.Load().([]policyData) + + for _, definitionInfo := range policyDatas { + definition := definitionInfo.lastReconciledValue + matches, matchKind, err := c.policyController.matcher.DefinitionMatches(a, o, definition) + if err != nil { + // Configuration error. + addConfigError(err, definition, nil) + continue + } + if !matches { + // Policy definition does not match request + continue + } else if definitionInfo.configurationError != nil { + // Configuration error. + addConfigError(definitionInfo.configurationError, definition, nil) + continue + } + + auditAnnotationCollector := newAuditAnnotationCollector() + for _, bindingInfo := range definitionInfo.bindings { + // If the key is inside dependentBindings, there is guaranteed to + // be a bindingInfo for it + binding := bindingInfo.lastReconciledValue + matches, err := c.policyController.matcher.BindingMatches(a, o, binding) + if err != nil { + // Configuration error. + addConfigError(err, definition, binding) + continue + } + if !matches { + continue + } + + var param runtime.Object + + // versionedAttributes will be set to non-nil inside of the loop, but + // is scoped outside of the param loop so we only convert once. We defer + // conversion so that it is only performed when we know a policy matches, + // saving the cost of converting non-matching requests. + var versionedAttr *admission.VersionedAttributes + + // If definition has paramKind, paramRef is required in binding. + // If definition has no paramKind, paramRef set in binding will be ignored. + paramKind := definition.Spec.ParamKind + paramRef := binding.Spec.ParamRef + if paramKind != nil && paramRef != nil { + paramController := definitionInfo.paramController + if paramController == nil { + addConfigError(fmt.Errorf("paramKind kind `%v` not known", + paramKind.String()), definition, binding) + continue + } + + // If the param informer for this admission policy has not yet + // had time to perform an initial listing, don't attempt to use + // it. + timeoutCtx, cancel := context.WithTimeout(c.policyController.context, 1*time.Second) + defer cancel() + + if !cache.WaitForCacheSync(timeoutCtx.Done(), paramController.HasSynced) { + addConfigError(fmt.Errorf("paramKind kind `%v` not yet synced to use for admission", + paramKind.String()), definition, binding) + continue + } + + if len(paramRef.Namespace) == 0 { + param, err = paramController.Informer().Get(paramRef.Name) + } else { + param, err = paramController.Informer().Namespaced(paramRef.Namespace).Get(paramRef.Name) + } + + if err != nil { + // Apply failure policy + addConfigError(err, definition, binding) + + if k8serrors.IsInvalid(err) { + // Param mis-configured + // require to set paramRef.namespace for namespaced resource and unset paramRef.namespace for cluster scoped resource + continue + } else if k8serrors.IsNotFound(err) { + // Param not yet available. User may need to wait a bit + // before being able to use it for validation. + continue + } + + // There was a bad internal error + utilruntime.HandleError(err) + continue + } + } + + if versionedAttr == nil { + va, err := admission.NewVersionedAttributes(a, matchKind, o) + if err != nil { + wrappedErr := fmt.Errorf("failed to convert object version: %w", err) + addConfigError(wrappedErr, definition, binding) + continue + } + versionedAttr = va + } + + validationResult := bindingInfo.validator.Validate(ctx, versionedAttr, param, celconfig.RuntimeCELCostBudget) + if err != nil { + // runtime error. Apply failure policy + wrappedError := fmt.Errorf("failed to evaluate CEL expression: %w", err) + addConfigError(wrappedError, definition, binding) + continue + } + + for i, decision := range validationResult.Decisions { + switch decision.Action { + case ActionAdmit: + if decision.Evaluation == EvalError { + celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + } + case ActionDeny: + for _, action := range binding.Spec.ValidationActions { + switch action { + case v1alpha1.Deny: + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + Definition: definition, + Binding: binding, + PolicyDecision: decision, + }) + celmetrics.Metrics.ObserveRejection(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + case v1alpha1.Audit: + c.publishValidationFailureAnnotation(binding, i, decision, versionedAttr) + celmetrics.Metrics.ObserveAudit(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + case v1alpha1.Warn: + warning.AddWarning(ctx, "", fmt.Sprintf("Validation failed for ValidatingAdmissionPolicy '%s' with binding '%s': %s", definition.Name, binding.Name, decision.Message)) + celmetrics.Metrics.ObserveWarn(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + } + } + default: + return fmt.Errorf("unrecognized evaluation decision '%s' for ValidatingAdmissionPolicyBinding '%s' with ValidatingAdmissionPolicy '%s'", + decision.Action, binding.Name, definition.Name) + } + } + + for _, auditAnnotation := range validationResult.AuditAnnotations { + switch auditAnnotation.Action { + case AuditAnnotationActionPublish: + value := auditAnnotation.Value + if len(auditAnnotation.Value) > maxAuditAnnotationValueLength { + value = value[:maxAuditAnnotationValueLength] + } + auditAnnotationCollector.add(auditAnnotation.Key, value) + case AuditAnnotationActionError: + // When failurePolicy=fail, audit annotation errors result in deny + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + Definition: definition, + Binding: binding, + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Evaluation: EvalError, + Message: auditAnnotation.Error, + Elapsed: auditAnnotation.Elapsed, + }, + }) + celmetrics.Metrics.ObserveRejection(ctx, auditAnnotation.Elapsed, definition.Name, binding.Name, "active") + case AuditAnnotationActionExclude: // skip it + default: + return fmt.Errorf("unsupported AuditAnnotation Action: %s", auditAnnotation.Action) + } + } + } + auditAnnotationCollector.publish(definition.Name, a) + } + + if len(deniedDecisions) > 0 { + // TODO: refactor admission.NewForbidden so the name extraction is reusable but the code/reason is customizable + var message string + deniedDecision := deniedDecisions[0] + if deniedDecision.Binding != nil { + message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' with binding '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Binding.Name, deniedDecision.Message) + } else { + message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Message) + } + err := admission.NewForbidden(a, errors.New(message)).(*k8serrors.StatusError) + reason := deniedDecision.Reason + if len(reason) == 0 { + reason = metav1.StatusReasonInvalid + } + err.ErrStatus.Reason = reason + err.ErrStatus.Code = reasonToCode(reason) + err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Message: message}) + return err + } + return nil +} + +func (c *celAdmissionController) publishValidationFailureAnnotation(binding *v1alpha1.ValidatingAdmissionPolicyBinding, expressionIndex int, decision PolicyDecision, attributes admission.Attributes) { + key := "validation.policy.admission.k8s.io/validation_failure" + // Marshal to a list of failures since, in the future, we may need to support multiple failures + valueJson, err := utiljson.Marshal([]validationFailureValue{{ + ExpressionIndex: expressionIndex, + Message: decision.Message, + ValidationActions: binding.Spec.ValidationActions, + Binding: binding.Name, + Policy: binding.Spec.PolicyName, + }}) + if err != nil { + klog.Warningf("Failed to set admission audit annotation %s for ValidatingAdmissionPolicy %s and ValidatingAdmissionPolicyBinding %s: %v", key, binding.Spec.PolicyName, binding.Name, err) + } + value := string(valueJson) + if err := attributes.AddAnnotation(key, value); err != nil { + klog.Warningf("Failed to set admission audit annotation %s to %s for ValidatingAdmissionPolicy %s and ValidatingAdmissionPolicyBinding %s: %v", key, value, binding.Spec.PolicyName, binding.Name, err) + } +} + +func (c *celAdmissionController) HasSynced() bool { + return c.policyController.HasSynced() && c.definitions.Load() != nil +} + +func (c *celAdmissionController) ValidateInitialization() error { + return c.policyController.matcher.ValidateInitialization() +} + +func (c *celAdmissionController) refreshPolicies() { + c.definitions.Store(c.policyController.latestPolicyData()) +} + +// validationFailureValue defines the JSON format of a "validation.policy.admission.k8s.io/validation_failure" audit +// annotation value. +type validationFailureValue struct { + Message string `json:"message"` + Policy string `json:"policy"` + Binding string `json:"binding"` + ExpressionIndex int `json:"expressionIndex"` + ValidationActions []v1alpha1.ValidationAction `json:"validationActions"` +} + +type auditAnnotationCollector struct { + annotations map[string][]string +} + +func newAuditAnnotationCollector() auditAnnotationCollector { + return auditAnnotationCollector{annotations: map[string][]string{}} +} + +func (a auditAnnotationCollector) add(key, value string) { + // If multiple bindings produces the exact same key and value for an audit annotation, + // ignore the duplicates. + for _, v := range a.annotations[key] { + if v == value { + return + } + } + a.annotations[key] = append(a.annotations[key], value) +} + +func (a auditAnnotationCollector) publish(policyName string, attributes admission.Attributes) { + for key, bindingAnnotations := range a.annotations { + var value string + if len(bindingAnnotations) == 1 { + value = bindingAnnotations[0] + } else { + // Multiple distinct values can exist when binding params are used in the valueExpression of an auditAnnotation. + // When this happens, the values are concatenated into a comma-separated list. + value = strings.Join(bindingAnnotations, ", ") + } + if err := attributes.AddAnnotation(policyName+"/"+key, value); err != nil { + klog.Warningf("Failed to set admission audit annotation %s to %s for ValidatingAdmissionPolicy %s: %v", key, value, policyName, err) + } + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go new file mode 100644 index 00000000000..296ac416aa2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go @@ -0,0 +1,604 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + "fmt" + "sync" + "time" + + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/api/admissionregistration/v1alpha1" + corev1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + celmetrics "k8s.io/apiserver/pkg/admission/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamicinformer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + k8sscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/cache" +) + +type policyController struct { + once sync.Once + context context.Context + dynamicClient dynamic.Interface + restMapper meta.RESTMapper + policyDefinitionsController generic.Controller[*v1alpha1.ValidatingAdmissionPolicy] + policyBindingController generic.Controller[*v1alpha1.ValidatingAdmissionPolicyBinding] + + // Provided to the policy's Compile function as an injected dependency to + // assist with compiling its expressions to CEL + filterCompiler cel.FilterCompiler + + matcher Matcher + + newValidator + + // The TypeCheck checks the policy's expressions for type errors. + // Type of params is defined in policy.Spec.ParamsKind + // Types of object are calculated from policy.Spec.MatchingConstraints + typeChecker *TypeChecker + + // Lock which protects: + // - cachedPolicies + // - paramCRDControllers + // - definitionInfo + // - bindingInfos + // - definitionsToBindings + // All other fields should be assumed constant + mutex sync.RWMutex + + cachedPolicies []policyData + + // controller and metadata + paramsCRDControllers map[v1alpha1.ParamKind]*paramInfo + + // Index for each definition namespace/name, contains all binding + // namespace/names known to exist for that definition + definitionInfo map[namespacedName]*definitionInfo + + // Index for each bindings namespace/name. Contains compiled templates + // for the binding depending on the policy/param combination. + bindingInfos map[namespacedName]*bindingInfo + + // Map from namespace/name of a definition to a set of namespace/name + // of bindings which depend on it. + // All keys must have at least one dependent binding + // All binding names MUST exist as a key bindingInfos + definitionsToBindings map[namespacedName]sets.Set[namespacedName] + + client kubernetes.Interface + + authz authorizer.Authorizer +} + +type newValidator func(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failurePolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator + +func newPolicyController( + restMapper meta.RESTMapper, + client kubernetes.Interface, + dynamicClient dynamic.Interface, + typeChecker *TypeChecker, + filterCompiler cel.FilterCompiler, + matcher Matcher, + policiesInformer generic.Informer[*v1alpha1.ValidatingAdmissionPolicy], + bindingsInformer generic.Informer[*v1alpha1.ValidatingAdmissionPolicyBinding], + authz authorizer.Authorizer, +) *policyController { + res := &policyController{} + *res = policyController{ + filterCompiler: filterCompiler, + typeChecker: typeChecker, + definitionInfo: make(map[namespacedName]*definitionInfo), + bindingInfos: make(map[namespacedName]*bindingInfo), + paramsCRDControllers: make(map[v1alpha1.ParamKind]*paramInfo), + definitionsToBindings: make(map[namespacedName]sets.Set[namespacedName]), + matcher: matcher, + newValidator: NewValidator, + policyDefinitionsController: generic.NewController( + policiesInformer, + res.reconcilePolicyDefinition, + generic.ControllerOptions{ + Workers: 1, + Name: "cel-policy-definitions", + }, + ), + policyBindingController: generic.NewController( + bindingsInformer, + res.reconcilePolicyBinding, + generic.ControllerOptions{ + Workers: 1, + Name: "cel-policy-bindings", + }, + ), + restMapper: restMapper, + dynamicClient: dynamicClient, + client: client, + authz: authz, + } + return res +} + +func (c *policyController) Run(ctx context.Context) { + // Only support being run once + c.once.Do(func() { + c.context = ctx + + wg := sync.WaitGroup{} + + wg.Add(1) + go func() { + defer wg.Done() + c.policyDefinitionsController.Run(ctx) + }() + + wg.Add(1) + go func() { + defer wg.Done() + c.policyBindingController.Run(ctx) + }() + + <-ctx.Done() + wg.Wait() + }) +} + +func (c *policyController) HasSynced() bool { + return c.policyDefinitionsController.HasSynced() && c.policyBindingController.HasSynced() +} + +func (c *policyController) reconcilePolicyDefinition(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { + c.mutex.Lock() + defer c.mutex.Unlock() + err := c.reconcilePolicyDefinitionSpec(namespace, name, definition) + if err != nil { + return err + } + if c.typeChecker != nil { + err = c.reconcilePolicyStatus(namespace, name, definition) + } + return err +} + +func (c *policyController) reconcilePolicyDefinitionSpec(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { + c.cachedPolicies = nil // invalidate cachedPolicies + + // Namespace for policydefinition is empty. + nn := getNamespaceName(namespace, name) + info, ok := c.definitionInfo[nn] + if !ok { + info = &definitionInfo{} + c.definitionInfo[nn] = info + // TODO(DangerOnTheRanger): add support for "warn" being a valid enforcementAction + celmetrics.Metrics.ObserveDefinition(context.TODO(), "active", "deny") + } + + // Skip reconcile if the spec of the definition is unchanged + if info.lastReconciledValue != nil && definition != nil && + apiequality.Semantic.DeepEqual(info.lastReconciledValue.Spec, definition.Spec) { + return nil + } + + var paramSource *v1alpha1.ParamKind + if definition != nil { + paramSource = definition.Spec.ParamKind + } + + // If param source has changed, remove definition as dependent of old params + // If there are no more dependents of old param, stop and clean up controller + if info.lastReconciledValue != nil && info.lastReconciledValue.Spec.ParamKind != nil { + oldParamSource := *info.lastReconciledValue.Spec.ParamKind + + // If we are: + // - switching from having a param to not having a param (includes deletion) + // - or from having a param to a different one + // we remove dependency on the controller. + if paramSource == nil || *paramSource != oldParamSource { + if oldParamInfo, ok := c.paramsCRDControllers[oldParamSource]; ok { + oldParamInfo.dependentDefinitions.Delete(nn) + if len(oldParamInfo.dependentDefinitions) == 0 { + oldParamInfo.stop() + delete(c.paramsCRDControllers, oldParamSource) + } + } + } + } + + // Reset all previously compiled evaluators in case something relevant in + // definition has changed. + for key := range c.definitionsToBindings[nn] { + bindingInfo := c.bindingInfos[key] + bindingInfo.validator = nil + c.bindingInfos[key] = bindingInfo + } + + if definition == nil { + delete(c.definitionInfo, nn) + return nil + } + + // Update definition info + info.lastReconciledValue = definition + info.configurationError = nil + + if paramSource == nil { + // Skip setting up controller for empty param type + return nil + } + + // find GVR for params + // Parse param source into a GVK + + paramSourceGV, err := schema.ParseGroupVersion(paramSource.APIVersion) + if err != nil { + // Failed to resolve. Return error so we retry again (rate limited) + // Save a record of this definition with an evaluator that unconditionally + info.configurationError = fmt.Errorf("failed to parse apiVersion of paramKind '%v' with error: %w", paramSource.String(), err) + + // Return nil, since this error cannot be resolved by waiting more time + return nil + } + + paramsGVR, err := c.restMapper.RESTMapping(schema.GroupKind{ + Group: paramSourceGV.Group, + Kind: paramSource.Kind, + }, paramSourceGV.Version) + + if err != nil { + // Failed to resolve. Return error so we retry again (rate limited) + // Save a record of this definition with an evaluator that unconditionally + // + info.configurationError = fmt.Errorf("failed to find resource referenced by paramKind: '%v'", paramSourceGV.WithKind(paramSource.Kind)) + return info.configurationError + } + + if info, ok := c.paramsCRDControllers[*paramSource]; ok { + // If a param controller is already active for this paramsource, make + // sure it is tracking this policy's dependency upon it + info.dependentDefinitions.Insert(nn) + + } else { + instanceContext, instanceCancel := context.WithCancel(c.context) + + var informer cache.SharedIndexInformer + + // Informer Factory is optional + if c.client != nil { + // Create temporary informer factory + // Cannot use the k8s shared informer factory for dynamic params informer. + // Would leak unnecessary informers when we are done since we would have to + // call informerFactory.Start() with a longer-lived stopCh than necessary. + // SharedInformerFactory does not support temporary usage. + dynamicFactory := informers.NewSharedInformerFactory(c.client, 10*time.Minute) + + // Look for a typed informer. If it does not exist + genericInformer, err := dynamicFactory.ForResource(paramsGVR.Resource) + + // Ignore error. We fallback to dynamic informer if there is no + // typed informer + if err != nil { + informer = nil + } else { + informer = genericInformer.Informer() + + // Set transformer on the informer to workaround inconsistency + // where typed objects have TypeMeta wiped out but dynamic + // objects keep kind/apiVersion fields + informer.SetTransform(func(i interface{}) (interface{}, error) { + // Ensure param is populated with its GVK for consistency + // (CRD dynamic informer always returns objects with kind/apiversion, + // but native types do not include populated TypeMeta. + if param := i.(runtime.Object); param != nil { + if param.GetObjectKind().GroupVersionKind().Empty() { + // https://github.com/kubernetes/client-go/issues/413#issue-324586398 + gvks, _, _ := k8sscheme.Scheme.ObjectKinds(param) + for _, gvk := range gvks { + if len(gvk.Kind) == 0 { + continue + } + if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal { + continue + } + param.GetObjectKind().SetGroupVersionKind(gvk) + break + } + } + } + + return i, nil + }) + } + } + + if informer == nil { + // Dynamic JSON informer fallback. + // Cannot use shared dynamic informer since it would be impossible + // to clean CRD informers properly with multiple dependents + // (cannot start ahead of time, and cannot track dependencies via stopCh) + informer = dynamicinformer.NewFilteredDynamicInformer( + c.dynamicClient, + paramsGVR.Resource, + corev1.NamespaceAll, + // Use same interval as is used for k8s typed sharedInformerFactory + // https://github.com/kubernetes/kubernetes/blob/7e0923899fed622efbc8679cca6b000d43633e38/cmd/kube-apiserver/app/server.go#L430 + 10*time.Minute, + cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, + nil, + ).Informer() + } + + controller := generic.NewController( + generic.NewInformer[runtime.Object](informer), + c.reconcileParams, + generic.ControllerOptions{ + Workers: 1, + Name: paramSource.String() + "-controller", + }, + ) + + c.paramsCRDControllers[*paramSource] = ¶mInfo{ + controller: controller, + stop: instanceCancel, + dependentDefinitions: sets.New(nn), + } + + go controller.Run(instanceContext) + go informer.Run(instanceContext.Done()) + } + + return nil +} + +func (c *policyController) reconcilePolicyBinding(namespace, name string, binding *v1alpha1.ValidatingAdmissionPolicyBinding) error { + c.mutex.Lock() + defer c.mutex.Unlock() + + c.cachedPolicies = nil // invalidate cachedPolicies + + // Namespace for PolicyBinding is empty. In the future a namespaced binding + // may be added + // https://github.com/kubernetes/enhancements/blob/bf5c3c81ea2081d60c1dc7c832faa98479e06209/keps/sig-api-machinery/3488-cel-admission-control/README.md?plain=1#L1042 + nn := getNamespaceName(namespace, name) + info, ok := c.bindingInfos[nn] + if !ok { + info = &bindingInfo{} + c.bindingInfos[nn] = info + } + + // Skip if the spec of the binding is unchanged. + if info.lastReconciledValue != nil && binding != nil && + apiequality.Semantic.DeepEqual(info.lastReconciledValue.Spec, binding.Spec) { + return nil + } + + var oldNamespacedDefinitionName namespacedName + if info.lastReconciledValue != nil { + // All validating policies are cluster-scoped so have empty namespace + oldNamespacedDefinitionName = getNamespaceName("", info.lastReconciledValue.Spec.PolicyName) + } + + var namespacedDefinitionName namespacedName + if binding != nil { + // All validating policies are cluster-scoped so have empty namespace + namespacedDefinitionName = getNamespaceName("", binding.Spec.PolicyName) + } + + // Remove record of binding from old definition if the referred policy + // has changed + if oldNamespacedDefinitionName != namespacedDefinitionName { + if dependentBindings, ok := c.definitionsToBindings[oldNamespacedDefinitionName]; ok { + dependentBindings.Delete(nn) + + // if there are no more dependent bindings, remove knowledge of the + // definition altogether + if len(dependentBindings) == 0 { + delete(c.definitionsToBindings, oldNamespacedDefinitionName) + } + } + } + + if binding == nil { + delete(c.bindingInfos, nn) + return nil + } + + // Add record of binding to new definition + if dependentBindings, ok := c.definitionsToBindings[namespacedDefinitionName]; ok { + dependentBindings.Insert(nn) + } else { + c.definitionsToBindings[namespacedDefinitionName] = sets.New(nn) + } + + // Remove compiled template for old binding + info.validator = nil + info.lastReconciledValue = binding + return nil +} + +func (c *policyController) reconcilePolicyStatus(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { + if definition != nil && definition.Status.ObservedGeneration < definition.Generation { + st := c.calculatePolicyStatus(definition) + newDefinition := definition.DeepCopy() + newDefinition.Status = *st + _, err := c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().UpdateStatus(c.context, newDefinition, metav1.UpdateOptions{}) + if err != nil { + // ignore error when the controller is not able to + // mutate the definition, and to avoid infinite requeue. + utilruntime.HandleError(err) + } + } + return nil +} + +func (c *policyController) calculatePolicyStatus(definition *v1alpha1.ValidatingAdmissionPolicy) *v1alpha1.ValidatingAdmissionPolicyStatus { + expressionWarnings := c.typeChecker.Check(definition) + // modifying a deepcopy of the original status, preserving unrelated existing data + status := definition.Status.DeepCopy() + status.ObservedGeneration = definition.Generation + status.TypeChecking = &v1alpha1.TypeChecking{ExpressionWarnings: expressionWarnings} + return status +} + +func (c *policyController) reconcileParams(namespace, name string, params runtime.Object) error { + // Do nothing. + // When we add informational type checking we will need to compile in the + // reconcile loops instead of lazily so we can add compiler errors / type + // checker errors to the status of the resources. + return nil +} + +// Fetches the latest set of policy data or recalculates it if it has changed +// since it was last fetched +func (c *policyController) latestPolicyData() []policyData { + existing := func() []policyData { + c.mutex.RLock() + defer c.mutex.RUnlock() + + return c.cachedPolicies + }() + + if existing != nil { + return existing + } + + c.mutex.Lock() + defer c.mutex.Unlock() + + var res []policyData + for definitionNN, definitionInfo := range c.definitionInfo { + var bindingInfos []bindingInfo + for bindingNN := range c.definitionsToBindings[definitionNN] { + bindingInfo := c.bindingInfos[bindingNN] + if bindingInfo.validator == nil && definitionInfo.configurationError == nil { + hasParam := false + if definitionInfo.lastReconciledValue.Spec.ParamKind != nil { + hasParam = true + } + optionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: true} + expressionOptionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: false} + failurePolicy := convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(definitionInfo.lastReconciledValue.Spec.FailurePolicy) + var matcher matchconditions.Matcher = nil + matchConditions := definitionInfo.lastReconciledValue.Spec.MatchConditions + if len(matchConditions) > 0 { + matchExpressionAccessors := make([]cel.ExpressionAccessor, len(matchConditions)) + for i := range matchConditions { + matchExpressionAccessors[i] = (*matchconditions.MatchCondition)(&matchConditions[i]) + } + matcher = matchconditions.NewMatcher(c.filterCompiler.Compile(matchExpressionAccessors, optionalVars, celconfig.PerCallLimit), c.authz, failurePolicy, "validatingadmissionpolicy", definitionInfo.lastReconciledValue.Name) + } + bindingInfo.validator = c.newValidator( + c.filterCompiler.Compile(convertv1alpha1Validations(definitionInfo.lastReconciledValue.Spec.Validations), optionalVars, celconfig.PerCallLimit), + matcher, + c.filterCompiler.Compile(convertv1alpha1AuditAnnotations(definitionInfo.lastReconciledValue.Spec.AuditAnnotations), optionalVars, celconfig.PerCallLimit), + c.filterCompiler.Compile(convertV1Alpha1MessageExpressions(definitionInfo.lastReconciledValue.Spec.Validations), expressionOptionalVars, celconfig.PerCallLimit), + failurePolicy, + c.authz, + ) + } + bindingInfos = append(bindingInfos, *bindingInfo) + } + + var paramController generic.Controller[runtime.Object] + if paramKind := definitionInfo.lastReconciledValue.Spec.ParamKind; paramKind != nil { + if info, ok := c.paramsCRDControllers[*paramKind]; ok { + paramController = info.controller + } + } + + res = append(res, policyData{ + definitionInfo: *definitionInfo, + paramController: paramController, + bindings: bindingInfos, + }) + } + + c.cachedPolicies = res + return res +} + +func convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(policyType *v1alpha1.FailurePolicyType) *v1.FailurePolicyType { + if policyType == nil { + return nil + } + + var v1FailPolicy v1.FailurePolicyType + if *policyType == v1alpha1.Fail { + v1FailPolicy = v1.Fail + } else if *policyType == v1alpha1.Ignore { + v1FailPolicy = v1.Ignore + } + return &v1FailPolicy +} + +func convertv1alpha1Validations(inputValidations []v1alpha1.Validation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + validation := ValidationCondition{ + Expression: validation.Expression, + Message: validation.Message, + Reason: validation.Reason, + } + celExpressionAccessor[i] = &validation + } + return celExpressionAccessor +} + +func convertV1Alpha1MessageExpressions(inputValidations []v1alpha1.Validation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + if validation.MessageExpression != "" { + condition := MessageExpressionCondition{ + MessageExpression: validation.MessageExpression, + } + celExpressionAccessor[i] = &condition + } + } + return celExpressionAccessor +} + +func convertv1alpha1AuditAnnotations(inputValidations []v1alpha1.AuditAnnotation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + validation := AuditAnnotationCondition{ + Key: validation.Key, + ValueExpression: validation.ValueExpression, + } + celExpressionAccessor[i] = &validation + } + return celExpressionAccessor +} + +func getNamespaceName(namespace, name string) namespacedName { + return namespacedName{ + namespace: namespace, + name: name, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go new file mode 100644 index 00000000000..15b75798585 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go @@ -0,0 +1,31 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + + "k8s.io/apiserver/pkg/admission" +) + +type CELPolicyEvaluator interface { + admission.InitializationValidator + + Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error + HasSynced() bool + Run(stopCh <-chan struct{}) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go new file mode 100644 index 00000000000..0f84152e8b4 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + + celgo "github.com/google/cel-go/cel" + + "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/cel" +) + +var _ cel.ExpressionAccessor = &ValidationCondition{} + +// ValidationCondition contains the inputs needed to compile, evaluate and validate a cel expression +type ValidationCondition struct { + Expression string + Message string + Reason *metav1.StatusReason +} + +func (v *ValidationCondition) GetExpression() string { + return v.Expression +} + +func (v *ValidationCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.BoolType} +} + +// AuditAnnotationCondition contains the inputs needed to compile, evaluate and publish a cel audit annotation +type AuditAnnotationCondition struct { + Key string + ValueExpression string +} + +func (v *AuditAnnotationCondition) GetExpression() string { + return v.ValueExpression +} + +func (v *AuditAnnotationCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.StringType, celgo.NullType} +} + +// Matcher is used for matching ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding to attributes +type Matcher interface { + admission.InitializationValidator + + // DefinitionMatches says whether this policy definition matches the provided admission + // resource request + DefinitionMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicy) (bool, schema.GroupVersionKind, error) + + // BindingMatches says whether this policy definition matches the provided admission + // resource request + BindingMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicyBinding) (bool, error) +} + +// ValidateResult defines the result of a Validator.Validate operation. +type ValidateResult struct { + // Decisions specifies the outcome of the validation as well as the details about the decision. + Decisions []PolicyDecision + // AuditAnnotations specifies the audit annotations that should be recorded for the validation. + AuditAnnotations []PolicyAuditAnnotation +} + +// Validator is contains logic for converting ValidationEvaluation to PolicyDecisions +type Validator interface { + // Validate is used to take cel evaluations and convert into decisions + // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. + Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go new file mode 100644 index 00000000000..4334c0dd82c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go @@ -0,0 +1,293 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "context" + "errors" + "fmt" + "sync" + "sync/atomic" + "time" + + kerrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/cache/synctrack" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" +) + +var _ Controller[runtime.Object] = &controller[runtime.Object]{} + +type controller[T runtime.Object] struct { + informer Informer[T] + queue workqueue.RateLimitingInterface + + // Returns an error if there was a transient error during reconciliation + // and the object should be tried again later. + reconciler func(namespace, name string, newObj T) error + + options ControllerOptions + + // must hold a func() bool or nil + notificationsDelivered atomic.Value + + hasProcessed synctrack.AsyncTracker[string] +} + +type ControllerOptions struct { + Name string + Workers uint +} + +func (c *controller[T]) Informer() Informer[T] { + return c.informer +} + +func NewController[T runtime.Object]( + informer Informer[T], + reconciler func(namepace, name string, newObj T) error, + options ControllerOptions, +) Controller[T] { + if options.Workers == 0 { + options.Workers = 2 + } + + if len(options.Name) == 0 { + options.Name = fmt.Sprintf("%T-controller", *new(T)) + } + + c := &controller[T]{ + options: options, + informer: informer, + reconciler: reconciler, + queue: nil, + } + c.hasProcessed.UpstreamHasSynced = func() bool { + f := c.notificationsDelivered.Load() + if f == nil { + return false + } + return f.(func() bool)() + } + return c +} + +// Runs the controller and returns an error explaining why running was stopped. +// Reconciliation ends as soon as the context completes. If there are events +// waiting to be processed at that itme, they will be dropped. +func (c *controller[T]) Run(ctx context.Context) error { + klog.Infof("starting %s", c.options.Name) + defer klog.Infof("stopping %s", c.options.Name) + + c.queue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), c.options.Name) + + // Forcefully shutdown workqueue. Drop any enqueued items. + // Important to do this in a `defer` at the start of `Run`. + // Otherwise, if there are any early returns without calling this, we + // would never shut down the workqueue + defer c.queue.ShutDown() + + enqueue := func(obj interface{}, isInInitialList bool) { + var key string + var err error + if key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err != nil { + utilruntime.HandleError(err) + return + } + if isInInitialList { + c.hasProcessed.Start(key) + } + + c.queue.Add(key) + } + + registration, err := c.informer.AddEventHandler(cache.ResourceEventHandlerDetailedFuncs{ + AddFunc: enqueue, + UpdateFunc: func(oldObj, newObj interface{}) { + oldMeta, err1 := meta.Accessor(oldObj) + newMeta, err2 := meta.Accessor(newObj) + + if err1 != nil || err2 != nil { + if err1 != nil { + utilruntime.HandleError(err1) + } + + if err2 != nil { + utilruntime.HandleError(err2) + } + return + } else if oldMeta.GetResourceVersion() == newMeta.GetResourceVersion() { + if len(oldMeta.GetResourceVersion()) == 0 { + klog.Warningf("%v throwing out update with empty RV. this is likely to happen if a test did not supply a resource version on an updated object", c.options.Name) + } + return + } + + enqueue(newObj, false) + }, + DeleteFunc: func(obj interface{}) { + // Enqueue + enqueue(obj, false) + }, + }) + + // Error might be raised if informer was started and stopped already + if err != nil { + return err + } + + c.notificationsDelivered.Store(registration.HasSynced) + + // Make sure event handler is removed from informer in case return early from + // an error + defer func() { + c.notificationsDelivered.Store(func() bool { return false }) + // Remove event handler and Handle Error here. Error should only be raised + // for improper usage of event handler API. + if err := c.informer.RemoveEventHandler(registration); err != nil { + utilruntime.HandleError(err) + } + }() + + // Wait for initial cache list to complete before beginning to reconcile + // objects. + if !cache.WaitForNamedCacheSync(c.options.Name, ctx.Done(), c.informer.HasSynced) { + // ctx cancelled during cache sync. return early + err := ctx.Err() + if err == nil { + // if context wasnt cancelled then the sync failed for another reason + err = errors.New("cache sync failed") + } + return err + } + + waitGroup := sync.WaitGroup{} + + for i := uint(0); i < c.options.Workers; i++ { + waitGroup.Add(1) + go func() { + defer waitGroup.Done() + wait.Until(c.runWorker, time.Second, ctx.Done()) + }() + } + + klog.Infof("Started %v workers for %v", c.options.Workers, c.options.Name) + + // Wait for context cancel. + <-ctx.Done() + + // Forcefully shutdown workqueue. Drop any enqueued items. + c.queue.ShutDown() + + // Workqueue shutdown signals for workers to stop. Wait for all workers to + // clean up + waitGroup.Wait() + + // Only way for workers to ever stop is for caller to cancel the context + return ctx.Err() +} + +func (c *controller[T]) HasSynced() bool { + return c.hasProcessed.HasSynced() +} + +func (c *controller[T]) runWorker() { + for { + key, shutdown := c.queue.Get() + if shutdown { + return + } + + // We wrap this block in a func so we can defer c.workqueue.Done. + err := func(obj interface{}) error { + // We call Done here so the workqueue knows we have finished + // processing this item. We also must remember to call Forget if we + // do not want this work item being re-queued. For example, we do + // not call Forget if a transient error occurs, instead the item is + // put back on the workqueue and attempted again after a back-off + // period. + defer c.queue.Done(obj) + var key string + var ok bool + // We expect strings to come off the workqueue. These are of the + // form namespace/name. We do this as the delayed nature of the + // workqueue means the items in the informer cache may actually be + // more up to date that when the item was initially put onto the + // workqueue. + if key, ok = obj.(string); !ok { + // How did an incorrectly formatted key get in the workqueue? + // Done is sufficient. (Forget resets rate limiter for the key, + // but the key is invalid so there is no point in doing that) + return fmt.Errorf("expected string in workqueue but got %#v", obj) + } + defer c.hasProcessed.Finished(key) + + if err := c.reconcile(key); err != nil { + // Put the item back on the workqueue to handle any transient errors. + c.queue.AddRateLimited(key) + return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) + } + // Finally, if no error occurs we Forget this item so it is allowed + // to be re-enqueued without a long rate limit + c.queue.Forget(obj) + klog.V(4).Infof("syncAdmissionPolicy(%q)", key) + return nil + }(key) + + if err != nil { + utilruntime.HandleError(err) + } + } +} + +func (c *controller[T]) reconcile(key string) error { + var newObj T + var err error + var namespace string + var name string + var lister NamespacedLister[T] + + // Convert the namespace/name string into a distinct namespace and name + namespace, name, err = cache.SplitMetaNamespaceKey(key) + if err != nil { + utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key)) + return nil + } + + if len(namespace) > 0 { + lister = c.informer.Namespaced(namespace) + } else { + lister = c.informer + } + + newObj, err = lister.Get(name) + if err != nil { + if !kerrors.IsNotFound(err) { + return err + } + + // Deleted object. Inform reconciler with empty + } + + return c.reconciler(namespace, name, newObj) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/doc.go new file mode 100644 index 00000000000..2acfad989f6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/doc.go @@ -0,0 +1,29 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package generic contains a typed wrapper over cache SharedIndexInformer +// and Lister (maybe eventually should have a home there?) +// +// This interface is being experimented with as an easier way to write controllers +// with a bit less boilerplate. +// +// Informer/Lister classes are thin wrappers providing a type-safe interface +// over regular interface{}-based Informers/Listers +// +// Controller[T] provides a reusable way to reconcile objects out of an informer +// using the tried and true controller design pattern found all over k8s +// codebase based upon syncFunc/reconcile +package generic diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/informer.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/informer.go new file mode 100644 index 00000000000..3025aa19533 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/informer.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +var _ Informer[runtime.Object] = informer[runtime.Object]{} + +type informer[T runtime.Object] struct { + cache.SharedIndexInformer + lister[T] +} + +func NewInformer[T runtime.Object](informe cache.SharedIndexInformer) Informer[T] { + return informer[T]{ + SharedIndexInformer: informe, + lister: NewLister[T](informe.GetIndexer()), + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/interface.go new file mode 100644 index 00000000000..a17821e777e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/interface.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "context" + + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +type Controller[T runtime.Object] interface { + // Meant to be run inside a goroutine + // Waits for and reacts to changes in whatever type the controller + // is concerned with. + // + // Returns an error always non-nil explaining why the worker stopped + Run(ctx context.Context) error + + // Retrieves the informer used to back this controller + Informer() Informer[T] + + // Returns true if the informer cache has synced, and all the objects from + // the initial list have been reconciled at least once. + HasSynced() bool +} + +type NamespacedLister[T any] interface { + // List lists all ValidationRuleSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []T, err error) + // Get retrieves the ValidationRuleSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (T, error) +} + +type Informer[T any] interface { + cache.SharedIndexInformer + Lister[T] +} + +// Lister[T] helps list Ts. +// All objects returned here must be treated as read-only. +type Lister[T any] interface { + NamespacedLister[T] + Namespaced(namespace string) NamespacedLister[T] +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/lister.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/lister.go new file mode 100644 index 00000000000..aa6b090324c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/lister.go @@ -0,0 +1,100 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generic + +import ( + "fmt" + "net/http" + + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +var _ Lister[runtime.Object] = lister[runtime.Object]{} + +type namespacedLister[T runtime.Object] struct { + indexer cache.Indexer + namespace string +} + +func (w namespacedLister[T]) List(selector labels.Selector) (ret []T, err error) { + err = cache.ListAllByNamespace(w.indexer, w.namespace, selector, func(m interface{}) { + ret = append(ret, m.(T)) + }) + return ret, err +} + +func (w namespacedLister[T]) Get(name string) (T, error) { + var result T + + obj, exists, err := w.indexer.GetByKey(w.namespace + "/" + name) + if err != nil { + return result, err + } + if !exists { + return result, &kerrors.StatusError{ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Code: http.StatusNotFound, + Reason: metav1.StatusReasonNotFound, + Message: fmt.Sprintf("%s not found", name), + }} + } + result = obj.(T) + return result, nil +} + +type lister[T runtime.Object] struct { + indexer cache.Indexer +} + +func (w lister[T]) List(selector labels.Selector) (ret []T, err error) { + err = cache.ListAll(w.indexer, selector, func(m interface{}) { + ret = append(ret, m.(T)) + }) + return ret, err +} + +func (w lister[T]) Get(name string) (T, error) { + var result T + + obj, exists, err := w.indexer.GetByKey(name) + if err != nil { + return result, err + } + if !exists { + // kerrors.StatusNotFound requires a GroupResource we cannot provide + return result, &kerrors.StatusError{ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Code: http.StatusNotFound, + Reason: metav1.StatusReasonNotFound, + Message: fmt.Sprintf("%s not found", name), + }} + } + result = obj.(T) + return result, nil +} + +func (w lister[T]) Namespaced(namespace string) NamespacedLister[T] { + return namespacedLister[T]{namespace: namespace, indexer: w.indexer} +} + +func NewLister[T runtime.Object](indexer cache.Indexer) lister[T] { + return lister[T]{indexer: indexer} +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go new file mode 100644 index 00000000000..a659a99f14c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go @@ -0,0 +1,78 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" +) + +var _ matching.MatchCriteria = &matchCriteria{} + +type matchCriteria struct { + constraints *v1alpha1.MatchResources +} + +// GetParsedNamespaceSelector returns the converted LabelSelector which implements labels.Selector +func (m *matchCriteria) GetParsedNamespaceSelector() (labels.Selector, error) { + return metav1.LabelSelectorAsSelector(m.constraints.NamespaceSelector) +} + +// GetParsedObjectSelector returns the converted LabelSelector which implements labels.Selector +func (m *matchCriteria) GetParsedObjectSelector() (labels.Selector, error) { + return metav1.LabelSelectorAsSelector(m.constraints.ObjectSelector) +} + +// GetMatchResources returns the matchConstraints +func (m *matchCriteria) GetMatchResources() v1alpha1.MatchResources { + return *m.constraints +} + +type matcher struct { + Matcher *matching.Matcher +} + +func NewMatcher(m *matching.Matcher) Matcher { + return &matcher{ + Matcher: m, + } +} + +// ValidateInitialization checks if Matcher is initialized. +func (c *matcher) ValidateInitialization() error { + return c.Matcher.ValidateInitialization() +} + +// DefinitionMatches returns whether this ValidatingAdmissionPolicy matches the provided admission resource request +func (c *matcher) DefinitionMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicy) (bool, schema.GroupVersionKind, error) { + criteria := matchCriteria{constraints: definition.Spec.MatchConstraints} + return c.Matcher.Matches(a, o, &criteria) +} + +// BindingMatches returns whether this ValidatingAdmissionPolicyBinding matches the provided admission resource request +func (c *matcher) BindingMatches(a admission.Attributes, o admission.ObjectInterfaces, binding *v1alpha1.ValidatingAdmissionPolicyBinding) (bool, error) { + if binding.Spec.MatchResources == nil { + return true, nil + } + criteria := matchCriteria{constraints: binding.Spec.MatchResources} + isMatch, _, err := c.Matcher.Matches(a, o, &criteria) + return isMatch, err +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching/matching.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching/matching.go new file mode 100644 index 00000000000..c4f7e64af2d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching/matching.go @@ -0,0 +1,192 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package matching + +import ( + "fmt" + + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/client-go/kubernetes" + listersv1 "k8s.io/client-go/listers/core/v1" + + "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace" + "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object" + "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules" +) + +type MatchCriteria interface { + namespace.NamespaceSelectorProvider + object.ObjectSelectorProvider + + GetMatchResources() v1alpha1.MatchResources +} + +// Matcher decides if a request matches against matchCriteria +type Matcher struct { + namespaceMatcher *namespace.Matcher + objectMatcher *object.Matcher +} + +// NewMatcher initialize the matcher with dependencies requires +func NewMatcher( + namespaceLister listersv1.NamespaceLister, + client kubernetes.Interface, +) *Matcher { + return &Matcher{ + namespaceMatcher: &namespace.Matcher{ + NamespaceLister: namespaceLister, + Client: client, + }, + objectMatcher: &object.Matcher{}, + } +} + +// ValidateInitialization verify if the matcher is ready before use +func (m *Matcher) ValidateInitialization() error { + if err := m.namespaceMatcher.Validate(); err != nil { + return fmt.Errorf("namespaceMatcher is not properly setup: %v", err) + } + return nil +} + +func (m *Matcher) Matches(attr admission.Attributes, o admission.ObjectInterfaces, criteria MatchCriteria) (bool, schema.GroupVersionKind, error) { + matches, matchNsErr := m.namespaceMatcher.MatchNamespaceSelector(criteria, attr) + // Should not return an error here for policy which do not apply to the request, even if err is an unexpected scenario. + if !matches && matchNsErr == nil { + return false, schema.GroupVersionKind{}, nil + } + + matches, matchObjErr := m.objectMatcher.MatchObjectSelector(criteria, attr) + // Should not return an error here for policy which do not apply to the request, even if err is an unexpected scenario. + if !matches && matchObjErr == nil { + return false, schema.GroupVersionKind{}, nil + } + + matchResources := criteria.GetMatchResources() + matchPolicy := matchResources.MatchPolicy + if isExcluded, _, err := matchesResourceRules(matchResources.ExcludeResourceRules, matchPolicy, attr, o); isExcluded || err != nil { + return false, schema.GroupVersionKind{}, err + } + + var ( + isMatch bool + matchKind schema.GroupVersionKind + matchErr error + ) + if len(matchResources.ResourceRules) == 0 { + isMatch = true + matchKind = attr.GetKind() + } else { + isMatch, matchKind, matchErr = matchesResourceRules(matchResources.ResourceRules, matchPolicy, attr, o) + } + if matchErr != nil { + return false, schema.GroupVersionKind{}, matchErr + } + if !isMatch { + return false, schema.GroupVersionKind{}, nil + } + + // now that we know this applies to this request otherwise, if there were selector errors, return them + if matchNsErr != nil { + return false, schema.GroupVersionKind{}, matchNsErr + } + if matchObjErr != nil { + return false, schema.GroupVersionKind{}, matchObjErr + } + + return true, matchKind, nil +} + +func matchesResourceRules(namedRules []v1alpha1.NamedRuleWithOperations, matchPolicy *v1alpha1.MatchPolicyType, attr admission.Attributes, o admission.ObjectInterfaces) (bool, schema.GroupVersionKind, error) { + matchKind := attr.GetKind() + for _, namedRule := range namedRules { + rule := v1.RuleWithOperations(namedRule.RuleWithOperations) + ruleMatcher := rules.Matcher{ + Rule: rule, + Attr: attr, + } + if !ruleMatcher.Matches() { + continue + } + // an empty name list always matches + if len(namedRule.ResourceNames) == 0 { + return true, matchKind, nil + } + // TODO: GetName() can return an empty string if the user is relying on + // the API server to generate the name... figure out what to do for this edge case + name := attr.GetName() + for _, matchedName := range namedRule.ResourceNames { + if name == matchedName { + return true, matchKind, nil + } + } + } + + // if match policy is undefined or exact, don't perform fuzzy matching + // note that defaulting to fuzzy matching is set by the API + if matchPolicy == nil || *matchPolicy == v1alpha1.Exact { + return false, schema.GroupVersionKind{}, nil + } + + attrWithOverride := &attrWithResourceOverride{Attributes: attr} + equivalents := o.GetEquivalentResourceMapper().EquivalentResourcesFor(attr.GetResource(), attr.GetSubresource()) + for _, namedRule := range namedRules { + for _, equivalent := range equivalents { + if equivalent == attr.GetResource() { + // we have already checked the original resource + continue + } + attrWithOverride.resource = equivalent + rule := v1.RuleWithOperations(namedRule.RuleWithOperations) + m := rules.Matcher{ + Rule: rule, + Attr: attrWithOverride, + } + if !m.Matches() { + continue + } + matchKind = o.GetEquivalentResourceMapper().KindFor(equivalent, attr.GetSubresource()) + if matchKind.Empty() { + return false, schema.GroupVersionKind{}, fmt.Errorf("unable to convert to %v: unknown kind", equivalent) + } + // an empty name list always matches + if len(namedRule.ResourceNames) == 0 { + return true, matchKind, nil + } + + // TODO: GetName() can return an empty string if the user is relying on + // the API server to generate the name... figure out what to do for this edge case + name := attr.GetName() + for _, matchedName := range namedRule.ResourceNames { + if name == matchedName { + return true, matchKind, nil + } + } + } + } + return false, schema.GroupVersionKind{}, nil +} + +type attrWithResourceOverride struct { + admission.Attributes + resource schema.GroupVersionResource +} + +func (a *attrWithResourceOverride) GetResource() schema.GroupVersionResource { return a.resource } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go new file mode 100644 index 00000000000..772891e3c8b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + celgo "github.com/google/cel-go/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" +) + +var _ cel.ExpressionAccessor = (*MessageExpressionCondition)(nil) + +type MessageExpressionCondition struct { + MessageExpression string +} + +func (m *MessageExpressionCondition) GetExpression() string { + return m.MessageExpression +} + +func (m *MessageExpressionCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.StringType} +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go new file mode 100644 index 00000000000..939cbea70c0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go @@ -0,0 +1,87 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "net/http" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type PolicyDecisionAction string + +const ( + ActionAdmit PolicyDecisionAction = "admit" + ActionDeny PolicyDecisionAction = "deny" +) + +type PolicyDecisionEvaluation string + +const ( + EvalAdmit PolicyDecisionEvaluation = "admit" + EvalError PolicyDecisionEvaluation = "error" + EvalDeny PolicyDecisionEvaluation = "deny" +) + +// PolicyDecision contains the action determined from a cel evaluation along with metadata such as message, reason and duration +type PolicyDecision struct { + Action PolicyDecisionAction + Evaluation PolicyDecisionEvaluation + Message string + Reason metav1.StatusReason + Elapsed time.Duration +} + +type PolicyAuditAnnotationAction string + +const ( + // AuditAnnotationActionPublish indicates that the audit annotation should be + // published with the audit event. + AuditAnnotationActionPublish PolicyAuditAnnotationAction = "publish" + // AuditAnnotationActionError indicates that the valueExpression resulted + // in an error. + AuditAnnotationActionError PolicyAuditAnnotationAction = "error" + // AuditAnnotationActionExclude indicates that the audit annotation should be excluded + // because the valueExpression evaluated to null, or because FailurePolicy is Ignore + // and the expression failed with a parse error, type check error, or runtime error. + AuditAnnotationActionExclude PolicyAuditAnnotationAction = "exclude" +) + +type PolicyAuditAnnotation struct { + Key string + Value string + Elapsed time.Duration + Action PolicyAuditAnnotationAction + Error string +} + +func reasonToCode(r metav1.StatusReason) int32 { + switch r { + case metav1.StatusReasonForbidden: + return http.StatusForbidden + case metav1.StatusReasonUnauthorized: + return http.StatusUnauthorized + case metav1.StatusReasonRequestEntityTooLarge: + return http.StatusRequestEntityTooLarge + case metav1.StatusReasonInvalid: + return http.StatusUnprocessableEntity + default: + // It should not reach here since we only allow above reason to be set from API level + return http.StatusUnprocessableEntity + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go new file mode 100644 index 00000000000..7b128e38185 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go @@ -0,0 +1,435 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "errors" + "fmt" + "sort" + "strings" + "sync" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation/field" + plugincel "k8s.io/apiserver/pkg/admission/plugin/cel" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/common" + "k8s.io/apiserver/pkg/cel/library" + "k8s.io/apiserver/pkg/cel/openapi" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + "k8s.io/klog/v2" +) + +const maxTypesToCheck = 10 + +type TypeChecker struct { + schemaResolver resolver.SchemaResolver + restMapper meta.RESTMapper +} + +type typeOverwrite struct { + object *apiservercel.DeclType + params *apiservercel.DeclType +} + +// typeCheckingResult holds the issues found during type checking, any returned +// error, and the gvk that the type checking is performed against. +type typeCheckingResult struct { + gvk schema.GroupVersionKind + + issues *cel.Issues + err error +} + +// Check preforms the type check against the given policy, and format the result +// as []ExpressionWarning that is ready to be set in policy.Status +// The result is nil if type checking returns no warning. +// The policy object is NOT mutated. The caller should update Status accordingly +func (c *TypeChecker) Check(policy *v1alpha1.ValidatingAdmissionPolicy) []v1alpha1.ExpressionWarning { + exps := make([]string, 0, len(policy.Spec.Validations)) + // check main validation expressions, located in spec.validations[*] + fieldRef := field.NewPath("spec", "validations") + for _, v := range policy.Spec.Validations { + exps = append(exps, v.Expression) + } + msgs := c.CheckExpressions(exps, policy.Spec.ParamKind != nil, policy) + var results []v1alpha1.ExpressionWarning // intentionally not setting capacity + for i, msg := range msgs { + if msg != "" { + results = append(results, v1alpha1.ExpressionWarning{ + FieldRef: fieldRef.Index(i).Child("expression").String(), + Warning: msg, + }) + } + } + return results +} + +// CheckExpressions checks a set of compiled CEL programs against the GVKs defined in +// policy.Spec.MatchConstraints +// The result is a human-readable form that describe which expressions +// violate what types at what place. The indexes of the return []string +// matches these of the input expressions. +// TODO: It is much more useful to have machine-readable output and let the +// client format it. That requires an update to the KEP, probably in coming +// releases. +func (c *TypeChecker) CheckExpressions(expressions []string, hasParams bool, policy *v1alpha1.ValidatingAdmissionPolicy) []string { + var allWarnings []string + allGvks := c.typesToCheck(policy) + gvks := make([]schema.GroupVersionKind, 0, len(allGvks)) + schemas := make([]common.Schema, 0, len(allGvks)) + for _, gvk := range allGvks { + s, err := c.schemaResolver.ResolveSchema(gvk) + if err != nil { + // type checking errors MUST NOT alter the behavior of the policy + // even if an error occurs. + if !errors.Is(err, resolver.ErrSchemaNotFound) { + // Anything except ErrSchemaNotFound is an internal error + klog.ErrorS(err, "internal error: schema resolution failure", "gvk", gvk) + } + // skip if an unrecoverable error occurs. + continue + } + gvks = append(gvks, gvk) + schemas = append(schemas, &openapi.Schema{Schema: s}) + } + + paramsType := c.paramsType(policy) + paramsDeclType, err := c.declType(paramsType) + if err != nil { + if !errors.Is(err, resolver.ErrSchemaNotFound) { + klog.V(2).ErrorS(err, "cannot resolve schema for params", "gvk", paramsType) + } + paramsDeclType = nil + } + + for _, exp := range expressions { + var results []typeCheckingResult + for i, gvk := range gvks { + s := schemas[i] + issues, err := c.checkExpression(exp, hasParams, typeOverwrite{ + object: common.SchemaDeclType(s, true), + params: paramsDeclType, + }) + // save even if no issues are found, for the sake of formatting. + results = append(results, typeCheckingResult{ + gvk: gvk, + issues: issues, + err: err, + }) + } + allWarnings = append(allWarnings, c.formatWarning(results)) + } + + return allWarnings +} + +// formatWarning converts the resulting issues and possible error during +// type checking into a human-readable string +func (c *TypeChecker) formatWarning(results []typeCheckingResult) string { + var sb strings.Builder + for _, result := range results { + if result.issues == nil && result.err == nil { + continue + } + if result.err != nil { + sb.WriteString(fmt.Sprintf("%v: type checking error: %v\n", result.gvk, result.err)) + } else { + sb.WriteString(fmt.Sprintf("%v: %s\n", result.gvk, result.issues)) + } + } + return strings.TrimSuffix(sb.String(), "\n") +} + +func (c *TypeChecker) declType(gvk schema.GroupVersionKind) (*apiservercel.DeclType, error) { + if gvk.Empty() { + return nil, nil + } + s, err := c.schemaResolver.ResolveSchema(gvk) + if err != nil { + return nil, err + } + return common.SchemaDeclType(&openapi.Schema{Schema: s}, true), nil +} + +func (c *TypeChecker) paramsType(policy *v1alpha1.ValidatingAdmissionPolicy) schema.GroupVersionKind { + if policy.Spec.ParamKind == nil { + return schema.GroupVersionKind{} + } + gv, err := schema.ParseGroupVersion(policy.Spec.ParamKind.APIVersion) + if err != nil { + return schema.GroupVersionKind{} + } + return gv.WithKind(policy.Spec.ParamKind.Kind) +} + +func (c *TypeChecker) checkExpression(expression string, hasParams bool, types typeOverwrite) (*cel.Issues, error) { + env, err := buildEnv(hasParams, types) + if err != nil { + return nil, err + } + + // We cannot reuse an AST that is parsed by another env, so reparse it here. + // Compile = Parse + Check, we especially want the results of Check. + // + // Paradoxically, we discard the type-checked result and let the admission + // controller use the dynamic typed program. + // This is a compromise that is defined in the KEP. We can revisit this + // decision and expect a change with limited size. + _, issues := env.Compile(expression) + return issues, nil +} + +// typesToCheck extracts a list of GVKs that needs type checking from the policy +// the result is sorted in the order of Group, Version, and Kind +func (c *TypeChecker) typesToCheck(p *v1alpha1.ValidatingAdmissionPolicy) []schema.GroupVersionKind { + gvks := sets.New[schema.GroupVersionKind]() + if p.Spec.MatchConstraints == nil || len(p.Spec.MatchConstraints.ResourceRules) == 0 { + return nil + } + + for _, rule := range p.Spec.MatchConstraints.ResourceRules { + groups := extractGroups(&rule.Rule) + if len(groups) == 0 { + continue + } + versions := extractVersions(&rule.Rule) + if len(versions) == 0 { + continue + } + resources := extractResources(&rule.Rule) + if len(resources) == 0 { + continue + } + // sort GVRs so that the loop below provides + // consistent results. + sort.Strings(groups) + sort.Strings(versions) + sort.Strings(resources) + count := 0 + for _, group := range groups { + for _, version := range versions { + for _, resource := range resources { + gvr := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + resolved, err := c.restMapper.KindsFor(gvr) + if err != nil { + continue + } + for _, r := range resolved { + if !r.Empty() { + gvks.Insert(r) + count++ + // early return if maximum number of types are already + // collected + if count == maxTypesToCheck { + if gvks.Len() == 0 { + return nil + } + return sortGVKList(gvks.UnsortedList()) + } + } + } + } + } + } + } + if gvks.Len() == 0 { + return nil + } + return sortGVKList(gvks.UnsortedList()) +} + +func extractGroups(rule *v1alpha1.Rule) []string { + groups := make([]string, 0, len(rule.APIGroups)) + for _, group := range rule.APIGroups { + // give up if wildcard + if strings.ContainsAny(group, "*") { + return nil + } + groups = append(groups, group) + } + return groups +} + +func extractVersions(rule *v1alpha1.Rule) []string { + versions := make([]string, 0, len(rule.APIVersions)) + for _, version := range rule.APIVersions { + if strings.ContainsAny(version, "*") { + return nil + } + versions = append(versions, version) + } + return versions +} + +func extractResources(rule *v1alpha1.Rule) []string { + resources := make([]string, 0, len(rule.Resources)) + for _, resource := range rule.Resources { + // skip wildcard and subresources + if strings.ContainsAny(resource, "*/") { + continue + } + resources = append(resources, resource) + } + return resources +} + +// sortGVKList sorts the list by Group, Version, and Kind +// returns the list itself. +func sortGVKList(list []schema.GroupVersionKind) []schema.GroupVersionKind { + sort.Slice(list, func(i, j int) bool { + if g := strings.Compare(list[i].Group, list[j].Group); g != 0 { + return g < 0 + } + if v := strings.Compare(list[i].Version, list[j].Version); v != 0 { + return v < 0 + } + return strings.Compare(list[i].Kind, list[j].Kind) < 0 + }) + return list +} + +func buildEnv(hasParams bool, types typeOverwrite) (*cel.Env, error) { + baseEnv, err := getBaseEnv() + if err != nil { + return nil, err + } + reg := apiservercel.NewRegistry(baseEnv) + requestType := plugincel.BuildRequestType() + + var varOpts []cel.EnvOption + var rts []*apiservercel.RuleTypes + + // request, hand-crafted type + rt, opts, err := createRuleTypesAndOptions(reg, requestType, plugincel.RequestVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + + // object and oldObject, same type, type(s) resolved from constraints + rt, opts, err = createRuleTypesAndOptions(reg, types.object, plugincel.ObjectVarName, plugincel.OldObjectVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + + // params, defined by ParamKind + if hasParams { + rt, opts, err := createRuleTypesAndOptions(reg, types.params, plugincel.ParamsVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + } + + opts, err = ruleTypesOpts(rts, baseEnv.TypeProvider()) + if err != nil { + return nil, err + } + opts = append(opts, varOpts...) // add variables after ruleTypes. + env, err := baseEnv.Extend(opts...) + if err != nil { + return nil, err + } + return env, nil +} + +// createRuleTypeAndOptions creates the cel RuleTypes and a slice of EnvOption +// that can be used for creating a CEL env containing variables of declType. +// declType can be nil, in which case the variables will be of DynType. +func createRuleTypesAndOptions(registry *apiservercel.Registry, declType *apiservercel.DeclType, variables ...string) (*apiservercel.RuleTypes, []cel.EnvOption, error) { + opts := make([]cel.EnvOption, 0, len(variables)) + // untyped, use DynType + if declType == nil { + for _, v := range variables { + opts = append(opts, cel.Variable(v, cel.DynType)) + } + return nil, opts, nil + } + // create a RuleType for the given type + rt, err := apiservercel.NewRuleTypes(declType.TypeName(), declType, registry) + if err != nil { + return nil, nil, err + } + if rt == nil { + return nil, nil, nil + } + for _, v := range variables { + opts = append(opts, cel.Variable(v, declType.CelType())) + } + return rt, opts, nil +} + +func ruleTypesOpts(ruleTypes []*apiservercel.RuleTypes, underlyingTypeProvider ref.TypeProvider) ([]cel.EnvOption, error) { + var providers []ref.TypeProvider // may be unused, too small to matter + var adapters []ref.TypeAdapter + for _, rt := range ruleTypes { + if rt != nil { + withTP, err := rt.WithTypeProvider(underlyingTypeProvider) + if err != nil { + return nil, err + } + providers = append(providers, withTP) + adapters = append(adapters, withTP) + } + } + var tp ref.TypeProvider + var ta ref.TypeAdapter + switch len(providers) { + case 0: + return nil, nil + case 1: + tp = providers[0] + ta = adapters[0] + default: + tp = &apiservercel.CompositedTypeProvider{Providers: providers} + ta = &apiservercel.CompositedTypeAdapter{Adapters: adapters} + } + return []cel.EnvOption{cel.CustomTypeProvider(tp), cel.CustomTypeAdapter(ta)}, nil +} + +func getBaseEnv() (*cel.Env, error) { + typeCheckingBaseEnvInit.Do(func() { + var opts []cel.EnvOption + opts = append(opts, cel.HomogeneousAggregateLiterals()) + // Validate function declarations once during base env initialization, + // so they don't need to be evaluated each time a CEL rule is compiled. + // This is a relatively expensive operation. + opts = append(opts, cel.EagerlyValidateDeclarations(true), cel.DefaultUTCTimeZone(true)) + opts = append(opts, library.ExtensionLibs...) + typeCheckingBaseEnv, typeCheckingBaseEnvError = cel.NewEnv(opts...) + }) + return typeCheckingBaseEnv, typeCheckingBaseEnvError +} + +var typeCheckingBaseEnv *cel.Env +var typeCheckingBaseEnvError error +var typeCheckingBaseEnvInit sync.Once diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go new file mode 100644 index 00000000000..448750c9199 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go @@ -0,0 +1,248 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package validatingadmissionpolicy + +import ( + "context" + "fmt" + "strings" + + celtypes "github.com/google/cel-go/common/types" + + v1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/klog/v2" +) + +// validator implements the Validator interface +type validator struct { + celMatcher matchconditions.Matcher + validationFilter cel.Filter + auditAnnotationFilter cel.Filter + messageFilter cel.Filter + failPolicy *v1.FailurePolicyType + authorizer authorizer.Authorizer +} + +func NewValidator(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failPolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator { + return &validator{ + celMatcher: celMatcher, + validationFilter: validationFilter, + auditAnnotationFilter: auditAnnotationFilter, + messageFilter: messageFilter, + failPolicy: failPolicy, + authorizer: authorizer, + } +} + +func policyDecisionActionForError(f v1.FailurePolicyType) PolicyDecisionAction { + if f == v1.Ignore { + return ActionAdmit + } + return ActionDeny +} + +func auditAnnotationEvaluationForError(f v1.FailurePolicyType) PolicyAuditAnnotationAction { + if f == v1.Ignore { + return AuditAnnotationActionExclude + } + return AuditAnnotationActionError +} + +// Validate takes a list of Evaluation and a failure policy and converts them into actionable PolicyDecisions +// runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func (v *validator) Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + var f v1.FailurePolicyType + if v.failPolicy == nil { + f = v1.Fail + } else { + f = *v.failPolicy + } + + if v.celMatcher != nil { + matchResults := v.celMatcher.Match(ctx, versionedAttr, versionedParams) + if matchResults.Error != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: matchResults.Error.Error(), + }, + }, + } + } + + // if preconditions are not met, then do not return any validations + if !matchResults.Matches { + return ValidateResult{} + } + } + + optionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams, Authorizer: v.authorizer} + expressionOptionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams} + admissionRequest := cel.CreateAdmissionRequest(versionedAttr.Attributes) + evalResults, remainingBudget, err := v.validationFilter.ForInput(ctx, versionedAttr, admissionRequest, optionalVars, runtimeCELCostBudget) + if err != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: err.Error(), + }, + }, + } + } + decisions := make([]PolicyDecision, len(evalResults)) + messageResults, _, err := v.messageFilter.ForInput(ctx, versionedAttr, admissionRequest, expressionOptionalVars, remainingBudget) + for i, evalResult := range evalResults { + var decision = &decisions[i] + // TODO: move this to generics + validation, ok := evalResult.ExpressionAccessor.(*ValidationCondition) + if !ok { + klog.Error("Invalid type conversion to ValidationCondition") + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = "Invalid type sent to validator, expected ValidationCondition" + continue + } + + var messageResult *cel.EvaluationResult + var messageError *apiservercel.Error + if len(messageResults) > i { + messageResult = &messageResults[i] + } + messageError, _ = err.(*apiservercel.Error) + if evalResult.Error != nil { + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = evalResult.Error.Error() + } else if messageError != nil && + (messageError.Type == apiservercel.ErrorTypeInternal || + (messageError.Type == apiservercel.ErrorTypeInvalid && + strings.HasPrefix(messageError.Detail, "validation failed due to running out of cost budget"))) { + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = fmt.Sprintf("failed messageExpression: %s", err) + } else if evalResult.EvalResult != celtypes.True { + decision.Action = ActionDeny + if validation.Reason == nil { + decision.Reason = metav1.StatusReasonInvalid + } else { + decision.Reason = *validation.Reason + } + // decide the failure message + var message string + // attempt to set message with messageExpression result + if messageResult != nil && messageResult.Error == nil && messageResult.EvalResult != nil { + // also fallback if the eval result is non-string (including null) or + // whitespaces. + if message, ok = messageResult.EvalResult.Value().(string); ok { + message = strings.TrimSpace(message) + // deny excessively long message from EvalResult + if len(message) > celconfig.MaxEvaluatedMessageExpressionSizeBytes { + klog.V(2).InfoS("excessively long message denied", "message", message) + message = "" + } + // deny message that contains newlines + if strings.ContainsAny(message, "\n") { + klog.V(2).InfoS("multi-line message denied", "message", message) + message = "" + } + } + } + if messageResult != nil && messageResult.Error != nil { + // log any error with messageExpression + klog.V(2).ErrorS(messageResult.Error, "error while evaluating messageExpression") + } + // fallback to set message to the custom message + if message == "" && len(validation.Message) > 0 { + message = strings.TrimSpace(validation.Message) + } + // fallback to use the expression to compose a message + if message == "" { + message = fmt.Sprintf("failed expression: %v", strings.TrimSpace(validation.Expression)) + } + decision.Message = message + } else { + decision.Action = ActionAdmit + decision.Evaluation = EvalAdmit + } + } + + options := cel.OptionalVariableBindings{VersionedParams: versionedParams} + auditAnnotationEvalResults, _, err := v.auditAnnotationFilter.ForInput(ctx, versionedAttr, cel.CreateAdmissionRequest(versionedAttr.Attributes), options, runtimeCELCostBudget) + if err != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: err.Error(), + }, + }, + } + } + + auditAnnotationResults := make([]PolicyAuditAnnotation, len(auditAnnotationEvalResults)) + for i, evalResult := range auditAnnotationEvalResults { + if evalResult.ExpressionAccessor == nil { + continue + } + var auditAnnotationResult = &auditAnnotationResults[i] + // TODO: move this to generics + validation, ok := evalResult.ExpressionAccessor.(*AuditAnnotationCondition) + if !ok { + klog.Error("Invalid type conversion to AuditAnnotationCondition") + auditAnnotationResult.Action = auditAnnotationEvaluationForError(f) + auditAnnotationResult.Error = fmt.Sprintf("Invalid type sent to validator, expected AuditAnnotationCondition but got %T", evalResult.ExpressionAccessor) + continue + } + auditAnnotationResult.Key = validation.Key + + if evalResult.Error != nil { + auditAnnotationResult.Action = auditAnnotationEvaluationForError(f) + auditAnnotationResult.Error = evalResult.Error.Error() + } else { + switch evalResult.EvalResult.Type() { + case celtypes.StringType: + value := strings.TrimSpace(evalResult.EvalResult.Value().(string)) + if len(value) == 0 { + auditAnnotationResult.Action = AuditAnnotationActionExclude + } else { + auditAnnotationResult.Action = AuditAnnotationActionPublish + auditAnnotationResult.Value = value + } + case celtypes.NullType: + auditAnnotationResult.Action = AuditAnnotationActionExclude + default: + auditAnnotationResult.Action = AuditAnnotationActionError + auditAnnotationResult.Error = fmt.Sprintf("valueExpression '%v' resulted in unsupported return type: %v. "+ + "Return type must be either string or null.", validation.ValueExpression, evalResult.EvalResult.Type()) + } + } + } + return ValidateResult{Decisions: decisions, AuditAnnotations: auditAnnotationResults} +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go new file mode 100644 index 00000000000..09468655bd0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package matchconditions + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" +) + +type MatchResult struct { + Matches bool + Error error + FailedConditionName string +} + +// Matcher contains logic for converting Evaluations to bool of matches or does not match +type Matcher interface { + // Match is used to take cel evaluations and convert into decisions + Match(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object) MatchResult +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go new file mode 100644 index 00000000000..09a500dd39c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go @@ -0,0 +1,139 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package matchconditions + +import ( + "context" + "errors" + "fmt" + + "github.com/google/cel-go/cel" + celtypes "github.com/google/cel-go/common/types" + + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/runtime" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apiserver/pkg/admission" + admissionmetrics "k8s.io/apiserver/pkg/admission/metrics" + celplugin "k8s.io/apiserver/pkg/admission/plugin/cel" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/klog/v2" +) + +var _ celplugin.ExpressionAccessor = &MatchCondition{} + +// MatchCondition contains the inputs needed to compile, evaluate and match a cel expression +type MatchCondition v1.MatchCondition + +func (v *MatchCondition) GetExpression() string { + return v.Expression +} + +func (v *MatchCondition) ReturnTypes() []*cel.Type { + return []*cel.Type{cel.BoolType} +} + +var _ Matcher = &matcher{} + +// matcher evaluates compiled cel expressions and determines if they match the given request or not +type matcher struct { + filter celplugin.Filter + authorizer authorizer.Authorizer + failPolicy v1.FailurePolicyType + matcherType string + objectName string +} + +func NewMatcher(filter celplugin.Filter, authorizer authorizer.Authorizer, failPolicy *v1.FailurePolicyType, matcherType, objectName string) Matcher { + var f v1.FailurePolicyType + if failPolicy == nil { + f = v1.Fail + } else { + f = *failPolicy + } + return &matcher{ + filter: filter, + authorizer: authorizer, + failPolicy: f, + matcherType: matcherType, + objectName: objectName, + } +} + +func (m *matcher) Match(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object) MatchResult { + evalResults, _, err := m.filter.ForInput(ctx, versionedAttr, celplugin.CreateAdmissionRequest(versionedAttr.Attributes), celplugin.OptionalVariableBindings{ + VersionedParams: versionedParams, + Authorizer: m.authorizer, + }, celconfig.RuntimeCELCostBudgetMatchConditions) + + if err != nil { + // filter returning error is unexpected and not an evaluation error so not incrementing metric here + if m.failPolicy == v1.Fail { + return MatchResult{ + Error: err, + } + } else if m.failPolicy == v1.Ignore { + return MatchResult{ + Matches: false, + } + } + //TODO: add default so that if in future we add different failure types it doesn't fall through + } + + errorList := []error{} + for _, evalResult := range evalResults { + matchCondition, ok := evalResult.ExpressionAccessor.(*MatchCondition) + if !ok { + // This shouldnt happen, but if it does treat same as eval error + klog.Error("Invalid type conversion to MatchCondition") + errorList = append(errorList, errors.New(fmt.Sprintf("internal error converting ExpressionAccessor to MatchCondition"))) + continue + } + if evalResult.Error != nil { + errorList = append(errorList, evalResult.Error) + //TODO: what's the best way to handle this metric since its reused by VAP for match conditions + admissionmetrics.Metrics.ObserveMatchConditionEvalError(ctx, m.objectName, m.matcherType) + } + if evalResult.EvalResult == celtypes.False { + // If any condition false, skip calling webhook always + return MatchResult{ + Matches: false, + FailedConditionName: matchCondition.Name, + } + } + } + if len(errorList) > 0 { + // If mix of true and eval errors then resort to fail policy + if m.failPolicy == v1.Fail { + // mix of true and errors with fail policy fail should fail request without calling webhook + err = utilerrors.NewAggregate(errorList) + return MatchResult{ + Error: err, + } + } else if m.failPolicy == v1.Ignore { + // if fail policy ignore then skip call to webhook + return MatchResult{ + Matches: false, + } + } + } + // if no results eval to false, return matches true with list of any errors encountered + return MatchResult{ + Matches: true, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/doc.go new file mode 100644 index 00000000000..660001dff78 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package namespace defines the utilities that are used by the webhook +// plugin to decide if a webhook should be applied to an object based on its +// namespace. +package namespace // import "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace" diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go new file mode 100644 index 00000000000..459e3f5df6b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go @@ -0,0 +1,125 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package namespace + +import ( + "context" + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apiserver/pkg/admission" + clientset "k8s.io/client-go/kubernetes" + corelisters "k8s.io/client-go/listers/core/v1" +) + +type NamespaceSelectorProvider interface { + // GetNamespaceSelector gets the webhook NamespaceSelector field. + GetParsedNamespaceSelector() (labels.Selector, error) +} + +// Matcher decides if a request is exempted by the NamespaceSelector of a +// webhook configuration. +type Matcher struct { + NamespaceLister corelisters.NamespaceLister + Client clientset.Interface +} + +// Validate checks if the Matcher has a NamespaceLister and Client. +func (m *Matcher) Validate() error { + var errs []error + if m.NamespaceLister == nil { + errs = append(errs, fmt.Errorf("the namespace matcher requires a namespaceLister")) + } + if m.Client == nil { + errs = append(errs, fmt.Errorf("the namespace matcher requires a client")) + } + return utilerrors.NewAggregate(errs) +} + +// GetNamespaceLabels gets the labels of the namespace related to the attr. +func (m *Matcher) GetNamespaceLabels(attr admission.Attributes) (map[string]string, error) { + // If the request itself is creating or updating a namespace, then get the + // labels from attr.Object, because namespaceLister doesn't have the latest + // namespace yet. + // + // However, if the request is deleting a namespace, then get the label from + // the namespace in the namespaceLister, because a delete request is not + // going to change the object, and attr.Object will be a DeleteOptions + // rather than a namespace object. + if attr.GetResource().Resource == "namespaces" && + len(attr.GetSubresource()) == 0 && + (attr.GetOperation() == admission.Create || attr.GetOperation() == admission.Update) { + accessor, err := meta.Accessor(attr.GetObject()) + if err != nil { + return nil, err + } + return accessor.GetLabels(), nil + } + + namespaceName := attr.GetNamespace() + namespace, err := m.NamespaceLister.Get(namespaceName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + if apierrors.IsNotFound(err) { + // in case of latency in our caches, make a call direct to storage to verify that it truly exists or not + namespace, err = m.Client.CoreV1().Namespaces().Get(context.TODO(), namespaceName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + } + return namespace.Labels, nil +} + +// MatchNamespaceSelector decideds whether the request matches the +// namespaceSelctor of the webhook. Only when they match, the webhook is called. +func (m *Matcher) MatchNamespaceSelector(p NamespaceSelectorProvider, attr admission.Attributes) (bool, *apierrors.StatusError) { + namespaceName := attr.GetNamespace() + if len(namespaceName) == 0 && attr.GetResource().Resource != "namespaces" { + // If the request is about a cluster scoped resource, and it is not a + // namespace, it is never exempted. + // TODO: figure out a way selective exempt cluster scoped resources. + // Also update the comment in types.go + return true, nil + } + selector, err := p.GetParsedNamespaceSelector() + if err != nil { + return false, apierrors.NewInternalError(err) + } + if selector.Empty() { + return true, nil + } + + namespaceLabels, err := m.GetNamespaceLabels(attr) + // this means the namespace is not found, for backwards compatibility, + // return a 404 + if apierrors.IsNotFound(err) { + status, ok := err.(apierrors.APIStatus) + if !ok { + return false, apierrors.NewInternalError(err) + } + return false, &apierrors.StatusError{ErrStatus: status.Status()} + } + if err != nil { + return false, apierrors.NewInternalError(err) + } + return selector.Matches(labels.Set(namespaceLabels)), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/doc.go new file mode 100644 index 00000000000..8964afa6c5f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package object defines the utilities that are used by the webhook plugin to +// decide if a webhook should run, as long as either the old object or the new +// object has labels matching the webhook config's objectSelector. +package object // import "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object" diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/matcher.go new file mode 100644 index 00000000000..aadf9073277 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/matcher.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package object + +import ( + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/klog/v2" +) + +type ObjectSelectorProvider interface { + // GetObjectSelector gets the webhook ObjectSelector field. + GetParsedObjectSelector() (labels.Selector, error) +} + +// Matcher decides if a request selected by the ObjectSelector. +type Matcher struct { +} + +func matchObject(obj runtime.Object, selector labels.Selector) bool { + if obj == nil { + return false + } + accessor, err := meta.Accessor(obj) + if err != nil { + klog.V(5).InfoS("Accessing metadata failed", "object", obj, "err", err) + return false + } + return selector.Matches(labels.Set(accessor.GetLabels())) + +} + +// MatchObjectSelector decideds whether the request matches the ObjectSelector +// of the webhook. Only when they match, the webhook is called. +func (m *Matcher) MatchObjectSelector(p ObjectSelectorProvider, attr admission.Attributes) (bool, *apierrors.StatusError) { + selector, err := p.GetParsedObjectSelector() + if err != nil { + return false, apierrors.NewInternalError(err) + } + if selector.Empty() { + return true, nil + } + return matchObject(attr.GetObject(), selector) || matchObject(attr.GetOldObject(), selector), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules/rules.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules/rules.go new file mode 100644 index 00000000000..b926f65dc10 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules/rules.go @@ -0,0 +1,129 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rules + +import ( + "strings" + + "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" +) + +// Matcher determines if the Attr matches the Rule. +type Matcher struct { + Rule v1.RuleWithOperations + Attr admission.Attributes +} + +// Matches returns if the Attr matches the Rule. +func (r *Matcher) Matches() bool { + return r.scope() && + r.operation() && + r.group() && + r.version() && + r.resource() +} + +func exactOrWildcard(items []string, requested string) bool { + for _, item := range items { + if item == "*" { + return true + } + if item == requested { + return true + } + } + + return false +} + +var namespaceResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"} + +func (r *Matcher) scope() bool { + if r.Rule.Scope == nil || *r.Rule.Scope == v1.AllScopes { + return true + } + // attr.GetNamespace() is set to the name of the namespace for requests of the namespace object itself. + switch *r.Rule.Scope { + case v1.NamespacedScope: + // first make sure that we are not requesting a namespace object (namespace objects are cluster-scoped) + return r.Attr.GetResource() != namespaceResource && r.Attr.GetNamespace() != metav1.NamespaceNone + case v1.ClusterScope: + // also return true if the request is for a namespace object (namespace objects are cluster-scoped) + return r.Attr.GetResource() == namespaceResource || r.Attr.GetNamespace() == metav1.NamespaceNone + default: + return false + } +} + +func (r *Matcher) group() bool { + return exactOrWildcard(r.Rule.APIGroups, r.Attr.GetResource().Group) +} + +func (r *Matcher) version() bool { + return exactOrWildcard(r.Rule.APIVersions, r.Attr.GetResource().Version) +} + +func (r *Matcher) operation() bool { + attrOp := r.Attr.GetOperation() + for _, op := range r.Rule.Operations { + if op == v1.OperationAll { + return true + } + // The constants are the same such that this is a valid cast (and this + // is tested). + if op == v1.OperationType(attrOp) { + return true + } + } + return false +} + +func splitResource(resSub string) (res, sub string) { + parts := strings.SplitN(resSub, "/", 2) + if len(parts) == 2 { + return parts[0], parts[1] + } + return parts[0], "" +} + +func (r *Matcher) resource() bool { + opRes, opSub := r.Attr.GetResource().Resource, r.Attr.GetSubresource() + for _, res := range r.Rule.Resources { + res, sub := splitResource(res) + resMatch := res == "*" || res == opRes + subMatch := sub == "*" || sub == opSub + if resMatch && subMatch { + return true + } + } + return false +} + +// IsExemptAdmissionConfigurationResource determines if an admission.Attributes object is describing +// the admission of a ValidatingWebhookConfiguration or a MutatingWebhookConfiguration or a ValidatingAdmissionPolicy or a ValidatingAdmissionPolicyBinding +func IsExemptAdmissionConfigurationResource(attr admission.Attributes) bool { + gvk := attr.GetKind() + if gvk.Group == "admissionregistration.k8s.io" { + if gvk.Kind == "ValidatingWebhookConfiguration" || gvk.Kind == "MutatingWebhookConfiguration" || gvk.Kind == "ValidatingAdmissionPolicy" || gvk.Kind == "ValidatingAdmissionPolicyBinding" { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugins.go b/vendor/k8s.io/apiserver/pkg/admission/plugins.go new file mode 100644 index 00000000000..1afb480dd7f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugins.go @@ -0,0 +1,208 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "reflect" + "sort" + "strings" + "sync" + + "k8s.io/klog/v2" +) + +// Factory is a function that returns an Interface for admission decisions. +// The config parameter provides an io.Reader handler to the factory in +// order to load specific configurations. If no configuration is provided +// the parameter is nil. +type Factory func(config io.Reader) (Interface, error) + +type Plugins struct { + lock sync.Mutex + registry map[string]Factory +} + +func NewPlugins() *Plugins { + return &Plugins{} +} + +// All registered admission options. +var ( + // PluginEnabledFn checks whether a plugin is enabled. By default, if you ask about it, it's enabled. + PluginEnabledFn = func(name string, config io.Reader) bool { + return true + } +) + +// PluginEnabledFunc is a function type that can provide an external check on whether an admission plugin may be enabled +type PluginEnabledFunc func(name string, config io.Reader) bool + +// Registered enumerates the names of all registered plugins. +func (ps *Plugins) Registered() []string { + ps.lock.Lock() + defer ps.lock.Unlock() + keys := []string{} + for k := range ps.registry { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +// Register registers a plugin Factory by name. This +// is expected to happen during app startup. +func (ps *Plugins) Register(name string, plugin Factory) { + ps.lock.Lock() + defer ps.lock.Unlock() + if ps.registry != nil { + _, found := ps.registry[name] + if found { + klog.Fatalf("Admission plugin %q was registered twice", name) + } + } else { + ps.registry = map[string]Factory{} + } + + klog.V(1).InfoS("Registered admission plugin", "plugin", name) + ps.registry[name] = plugin +} + +// getPlugin creates an instance of the named plugin. It returns `false` if +// the name is not known. The error is returned only when the named provider was +// known but failed to initialize. The config parameter specifies the io.Reader +// handler of the configuration file for the cloud provider, or nil for no configuration. +func (ps *Plugins) getPlugin(name string, config io.Reader) (Interface, bool, error) { + ps.lock.Lock() + defer ps.lock.Unlock() + f, found := ps.registry[name] + if !found { + return nil, false, nil + } + + config1, config2, err := splitStream(config) + if err != nil { + return nil, true, err + } + if !PluginEnabledFn(name, config1) { + return nil, true, nil + } + + ret, err := f(config2) + return ret, true, err +} + +// splitStream reads the stream bytes and constructs two copies of it. +func splitStream(config io.Reader) (io.Reader, io.Reader, error) { + if config == nil || reflect.ValueOf(config).IsNil() { + return nil, nil, nil + } + + configBytes, err := ioutil.ReadAll(config) + if err != nil { + return nil, nil, err + } + + return bytes.NewBuffer(configBytes), bytes.NewBuffer(configBytes), nil +} + +// NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all +// the given plugins. +func (ps *Plugins) NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer, decorator Decorator) (Interface, error) { + handlers := []Interface{} + mutationPlugins := []string{} + validationPlugins := []string{} + for _, pluginName := range pluginNames { + pluginConfig, err := configProvider.ConfigFor(pluginName) + if err != nil { + return nil, err + } + + plugin, err := ps.InitPlugin(pluginName, pluginConfig, pluginInitializer) + if err != nil { + return nil, err + } + if plugin != nil { + if decorator != nil { + handlers = append(handlers, decorator.Decorate(plugin, pluginName)) + } else { + handlers = append(handlers, plugin) + } + + if _, ok := plugin.(MutationInterface); ok { + mutationPlugins = append(mutationPlugins, pluginName) + } + if _, ok := plugin.(ValidationInterface); ok { + validationPlugins = append(validationPlugins, pluginName) + } + } + } + if len(mutationPlugins) != 0 { + klog.Infof("Loaded %d mutating admission controller(s) successfully in the following order: %s.", len(mutationPlugins), strings.Join(mutationPlugins, ",")) + } + if len(validationPlugins) != 0 { + klog.Infof("Loaded %d validating admission controller(s) successfully in the following order: %s.", len(validationPlugins), strings.Join(validationPlugins, ",")) + } + return newReinvocationHandler(chainAdmissionHandler(handlers)), nil +} + +// InitPlugin creates an instance of the named interface. +func (ps *Plugins) InitPlugin(name string, config io.Reader, pluginInitializer PluginInitializer) (Interface, error) { + if name == "" { + klog.Info("No admission plugin specified.") + return nil, nil + } + + plugin, found, err := ps.getPlugin(name, config) + if err != nil { + return nil, fmt.Errorf("couldn't init admission plugin %q: %v", name, err) + } + if !found { + return nil, fmt.Errorf("unknown admission plugin: %s", name) + } + + pluginInitializer.Initialize(plugin) + // ensure that plugins have been properly initialized + if err := ValidateInitialization(plugin); err != nil { + return nil, fmt.Errorf("failed to initialize admission plugin %q: %v", name, err) + } + + return plugin, nil +} + +// ValidateInitialization will call the InitializationValidate function in each plugin if they implement +// the InitializationValidator interface. +func ValidateInitialization(plugin Interface) error { + if validater, ok := plugin.(InitializationValidator); ok { + err := validater.ValidateInitialization() + if err != nil { + return err + } + } + return nil +} + +type PluginInitializers []PluginInitializer + +func (pp PluginInitializers) Initialize(plugin Interface) { + for _, p := range pp { + p.Initialize(plugin) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/reinvocation.go b/vendor/k8s.io/apiserver/pkg/admission/reinvocation.go new file mode 100644 index 00000000000..f93c703a11c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/reinvocation.go @@ -0,0 +1,64 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import "context" + +// newReinvocationHandler creates a handler that wraps the provided admission chain and reinvokes it +// if needed according to re-invocation policy of the webhooks. +func newReinvocationHandler(admissionChain Interface) Interface { + return &reinvoker{admissionChain} +} + +type reinvoker struct { + admissionChain Interface +} + +// Admit performs an admission control check using the wrapped admission chain, reinvoking the +// admission chain if needed according to the reinvocation policy. Plugins are expected to check +// the admission attributes' reinvocation context against their reinvocation policy to decide if +// they should re-run, and to update the reinvocation context if they perform any mutations. +func (r *reinvoker) Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error { + if mutator, ok := r.admissionChain.(MutationInterface); ok { + err := mutator.Admit(ctx, a, o) + if err != nil { + return err + } + s := a.GetReinvocationContext() + if s.ShouldReinvoke() { + s.SetIsReinvoke() + // Calling admit a second time will reinvoke all in-tree plugins + // as well as any webhook plugins that need to be reinvoked based on the + // reinvocation policy. + return mutator.Admit(ctx, a, o) + } + } + return nil +} + +// Validate performs an admission control check using the wrapped admission chain, and returns immediately on first error. +func (r *reinvoker) Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error { + if validator, ok := r.admissionChain.(ValidationInterface); ok { + return validator.Validate(ctx, a, o) + } + return nil +} + +// Handles will return true if any of the admission chain handlers handle the given operation. +func (r *reinvoker) Handles(operation Operation) bool { + return r.admissionChain.Handles(operation) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/util.go b/vendor/k8s.io/apiserver/pkg/admission/util.go new file mode 100644 index 00000000000..842932f73e7 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/util.go @@ -0,0 +1,47 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package admission + +import "k8s.io/apimachinery/pkg/runtime" + +type RuntimeObjectInterfaces struct { + runtime.ObjectCreater + runtime.ObjectTyper + runtime.ObjectDefaulter + runtime.ObjectConvertor + runtime.EquivalentResourceMapper +} + +func NewObjectInterfacesFromScheme(scheme *runtime.Scheme) ObjectInterfaces { + return &RuntimeObjectInterfaces{scheme, scheme, scheme, scheme, runtime.NewEquivalentResourceRegistry()} +} + +func (r *RuntimeObjectInterfaces) GetObjectCreater() runtime.ObjectCreater { + return r.ObjectCreater +} +func (r *RuntimeObjectInterfaces) GetObjectTyper() runtime.ObjectTyper { + return r.ObjectTyper +} +func (r *RuntimeObjectInterfaces) GetObjectDefaulter() runtime.ObjectDefaulter { + return r.ObjectDefaulter +} +func (r *RuntimeObjectInterfaces) GetObjectConvertor() runtime.ObjectConvertor { + return r.ObjectConvertor +} +func (r *RuntimeObjectInterfaces) GetEquivalentResourceMapper() runtime.EquivalentResourceMapper { + return r.EquivalentResourceMapper +} diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go index 1d723d5e362..dcb082e0953 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -19,6 +19,7 @@ package apiserver import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -153,16 +154,6 @@ type TLSConfig struct { type TracingConfiguration struct { metav1.TypeMeta - // +optional - // Endpoint of the collector that's running on the control-plane node. - // The APIServer uses the egressType ControlPlane when sending data to the collector. - // The syntax is defined in https://github.com/grpc/grpc/blob/master/doc/naming.md. - // Defaults to the otlp grpc default, localhost:4317 - // The connection is insecure, and does not currently support TLS. - Endpoint *string - - // +optional - // SamplingRatePerMillion is the number of samples to collect per million spans. - // Defaults to 0. - SamplingRatePerMillion *int32 + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index cd937f1c7f0..b18d84d9d3c 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -19,6 +19,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -154,16 +155,6 @@ type TLSConfig struct { type TracingConfiguration struct { metav1.TypeMeta `json:",inline"` - // +optional - // Endpoint of the collector that's running on the control-plane node. - // The APIServer uses the egressType ControlPlane when sending data to the collector. - // The syntax is defined in https://github.com/grpc/grpc/blob/master/doc/naming.md. - // Defaults to the otlpgrpc default, localhost:4317 - // The connection is insecure, and does not support TLS. - Endpoint *string `json:"endpoint,omitempty" protobuf:"bytes,1,opt,name=endpoint"` - - // +optional - // SamplingRatePerMillion is the number of samples to collect per million spans. - // Defaults to 0. - SamplingRatePerMillion *int32 `json:"samplingRatePerMillion,omitempty" protobuf:"varint,2,opt,name=samplingRatePerMillion"` + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration `json:",inline"` } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go index e60f2f3b70b..41b350c48e2 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go @@ -313,8 +313,7 @@ func Convert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in *apiserver.TLSConfig, } func autoConvert_v1alpha1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { - out.Endpoint = (*string)(unsafe.Pointer(in.Endpoint)) - out.SamplingRatePerMillion = (*int32)(unsafe.Pointer(in.SamplingRatePerMillion)) + out.TracingConfiguration = in.TracingConfiguration return nil } @@ -324,8 +323,7 @@ func Convert_v1alpha1_TracingConfiguration_To_apiserver_TracingConfiguration(in } func autoConvert_apiserver_TracingConfiguration_To_v1alpha1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { - out.Endpoint = (*string)(unsafe.Pointer(in.Endpoint)) - out.SamplingRatePerMillion = (*int32)(unsafe.Pointer(in.SamplingRatePerMillion)) + out.TracingConfiguration = in.TracingConfiguration return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go index 0e95103e01c..f8ac34035fd 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go @@ -189,16 +189,7 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - if in.Endpoint != nil { - in, out := &in.Endpoint, &out.Endpoint - *out = new(string) - **out = **in - } - if in.SamplingRatePerMillion != nil { - in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion - *out = new(int32) - **out = **in - } + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) return } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go index 9ea529472f3..705d2e5eb31 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go @@ -23,10 +23,14 @@ import ( ) const GroupName = "apiserver.k8s.io" +const ConfigGroupName = "apiserver.config.k8s.io" // SchemeGroupVersion is group version used to register these objects var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} +// ConfigSchemeGroupVersion is group version used to register these objects +var ConfigSchemeGroupVersion = schema.GroupVersion{Group: ConfigGroupName, Version: "v1beta1"} + var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. @@ -47,6 +51,9 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &EgressSelectorConfiguration{}, ) + scheme.AddKnownTypes(ConfigSchemeGroupVersion, + &TracingConfiguration{}, + ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go index ea22b403a33..c61baea9ff1 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go @@ -18,6 +18,7 @@ package v1beta1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -118,3 +119,13 @@ type TLSConfig struct { // +optional ClientCert string `json:"clientCert,omitempty"` } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TracingConfiguration provides versioned configuration for tracing clients. +type TracingConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration `json:",inline"` +} diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go index 37b0f2f7b76..ebf810b055b 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go @@ -81,6 +81,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*TracingConfiguration)(nil), (*apiserver.TracingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(a.(*TracingConfiguration), b.(*apiserver.TracingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiserver.TracingConfiguration)(nil), (*TracingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(a.(*apiserver.TracingConfiguration), b.(*TracingConfiguration), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*Transport)(nil), (*apiserver.Transport)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_Transport_To_apiserver_Transport(a.(*Transport), b.(*apiserver.Transport), scope) }); err != nil { @@ -238,6 +248,26 @@ func Convert_apiserver_TLSConfig_To_v1beta1_TLSConfig(in *apiserver.TLSConfig, o return autoConvert_apiserver_TLSConfig_To_v1beta1_TLSConfig(in, out, s) } +func autoConvert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { + out.TracingConfiguration = in.TracingConfiguration + return nil +} + +// Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration is an autogenerated conversion function. +func Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in, out, s) +} + +func autoConvert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { + out.TracingConfiguration = in.TracingConfiguration + return nil +} + +// Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration is an autogenerated conversion function. +func Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { + return autoConvert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in, out, s) +} + func autoConvert_v1beta1_Transport_To_apiserver_Transport(in *Transport, out *apiserver.Transport, s conversion.Scope) error { out.TCP = (*apiserver.TCPTransport)(unsafe.Pointer(in.TCP)) out.UDS = (*apiserver.UDSTransport)(unsafe.Pointer(in.UDS)) diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go index bb1819cac65..beb0b50b57b 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go @@ -132,6 +132,32 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingConfiguration. +func (in *TracingConfiguration) DeepCopy() *TracingConfiguration { + if in == nil { + return nil + } + out := new(TracingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TracingConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Transport) DeepCopyInto(out *Transport) { *out = *in diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go index 86acce65f88..40c8b4a6e9b 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go @@ -189,16 +189,7 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - if in.Endpoint != nil { - in, out := &in.Endpoint, &out.Endpoint - *out = new(string) - **out = **in - } - if in.SamplingRatePerMillion != nil { - in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion - *out = new(int32) - **out = **in - } + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) return } diff --git a/vendor/k8s.io/apiserver/pkg/apis/cel/config.go b/vendor/k8s.io/apiserver/pkg/apis/cel/config.go new file mode 100644 index 00000000000..319548cd537 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/apis/cel/config.go @@ -0,0 +1,45 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +const ( + // PerCallLimit specify the actual cost limit per CEL validation call + // current PerCallLimit gives roughly 0.1 second for each expression validation call + PerCallLimit = 1000000 + + // RuntimeCELCostBudget is the overall cost budget for runtime CEL validation cost per ValidatingAdmissionPolicyBinding or CustomResource + // current RuntimeCELCostBudget gives roughly 1 seconds for the validation + RuntimeCELCostBudget = 10000000 + + // RuntimeCELCostBudgetMatchConditions is the overall cost budget for runtime CEL validation cost on matchConditions per object with matchConditions + // this is per webhook for validatingwebhookconfigurations and mutatingwebhookconfigurations or per ValidatingAdmissionPolicyBinding + // current RuntimeCELCostBudgetMatchConditions gives roughly 1/4 seconds for the validation + RuntimeCELCostBudgetMatchConditions = 2500000 + + // CheckFrequency configures the number of iterations within a comprehension to evaluate + // before checking whether the function evaluation has been interrupted + CheckFrequency = 100 + + // MaxRequestSizeBytes is the maximum size of a request to the API server + // TODO(DangerOnTheRanger): wire in MaxRequestBodyBytes from apiserver/pkg/server/options/server_run_options.go to make this configurable + // Note that even if server_run_options.go becomes configurable in the future, this cost constant should be fixed and it should be the max allowed request size for the server + MaxRequestSizeBytes = int64(3 * 1024 * 1024) + + // MaxEvaluatedMessageExpressionSizeBytes represents the largest-allowable string generated + // by a messageExpression field + MaxEvaluatedMessageExpressionSizeBytes = 5 * 1024 +) diff --git a/vendor/k8s.io/apiserver/pkg/audit/context.go b/vendor/k8s.io/apiserver/pkg/audit/context.go index df429af37d5..95a18bcd5ce 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/context.go +++ b/vendor/k8s.io/apiserver/pkg/audit/context.go @@ -20,6 +20,7 @@ import ( "context" "sync" + "k8s.io/apimachinery/pkg/types" auditinternal "k8s.io/apiserver/pkg/apis/audit" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog/v2" @@ -28,38 +29,31 @@ import ( // The key type is unexported to prevent collisions type key int -const ( - // auditAnnotationsKey is the context key for the audit annotations. - // TODO: consolidate all audit info under the AuditContext, rather than storing 3 separate keys. - auditAnnotationsKey key = iota +// auditKey is the context key for storing the audit context that is being +// captured and the evaluated policy that applies to the given request. +const auditKey key = iota - // auditKey is the context key for storing the audit event that is being - // captured and the evaluated policy that applies to the given request. - auditKey +// AuditContext holds the information for constructing the audit events for the current request. +type AuditContext struct { + // RequestAuditConfig is the audit configuration that applies to the request + RequestAuditConfig RequestAuditConfig - // auditAnnotationsMutexKey is the context key for the audit annotations mutex. - auditAnnotationsMutexKey -) + // Event is the audit Event object that is being captured to be written in + // the API audit log. It is set to nil when the request is not being audited. + Event *auditinternal.Event -// annotations = *[]annotation instead of a map to preserve order of insertions -type annotation struct { - key, value string -} + // annotations holds audit annotations that are recorded before the event has been initialized. + // This is represented as a slice rather than a map to preserve order. + annotations []annotation + // annotationMutex guards annotations AND event.Annotations + annotationMutex sync.Mutex -// WithAuditAnnotations returns a new context that can store audit annotations -// via the AddAuditAnnotation function. This function is meant to be called from -// an early request handler to allow all later layers to set audit annotations. -// This is required to support flows where handlers that come before WithAudit -// (such as WithAuthentication) wish to set audit annotations. -func WithAuditAnnotations(parent context.Context) context.Context { - // this should never really happen, but prevent double registration of this slice - if _, ok := parent.Value(auditAnnotationsKey).(*[]annotation); ok { - return parent - } - parent = withAuditAnnotationsMutex(parent) + // auditID is the Audit ID associated with this request. + auditID types.UID +} - var annotations []annotation // avoid allocations until we actually need it - return genericapirequest.WithValue(parent, auditAnnotationsKey, &annotations) +type annotation struct { + key, value string } // AddAuditAnnotation sets the audit annotation for the given key, value pair. @@ -70,102 +64,79 @@ func WithAuditAnnotations(parent context.Context) context.Context { // Handlers that are unaware of their position in the overall request flow should // prefer AddAuditAnnotation over LogAnnotation to avoid dropping annotations. func AddAuditAnnotation(ctx context.Context, key, value string) { - mutex, ok := auditAnnotationsMutex(ctx) - if !ok { + ac := AuditContextFrom(ctx) + if ac == nil { // auditing is not enabled return } - mutex.Lock() - defer mutex.Unlock() + ac.annotationMutex.Lock() + defer ac.annotationMutex.Unlock() - ae := AuditEventFrom(ctx) - var ctxAnnotations *[]annotation - if ae == nil { - ctxAnnotations, _ = ctx.Value(auditAnnotationsKey).(*[]annotation) - } - - addAuditAnnotationLocked(ae, ctxAnnotations, key, value) + addAuditAnnotationLocked(ac, key, value) } // AddAuditAnnotations is a bulk version of AddAuditAnnotation. Refer to AddAuditAnnotation for // restrictions on when this can be called. // keysAndValues are the key-value pairs to add, and must have an even number of items. func AddAuditAnnotations(ctx context.Context, keysAndValues ...string) { - mutex, ok := auditAnnotationsMutex(ctx) - if !ok { + ac := AuditContextFrom(ctx) + if ac == nil { // auditing is not enabled return } - mutex.Lock() - defer mutex.Unlock() - - ae := AuditEventFrom(ctx) - var ctxAnnotations *[]annotation - if ae == nil { - ctxAnnotations, _ = ctx.Value(auditAnnotationsKey).(*[]annotation) - } + ac.annotationMutex.Lock() + defer ac.annotationMutex.Unlock() if len(keysAndValues)%2 != 0 { klog.Errorf("Dropping mismatched audit annotation %q", keysAndValues[len(keysAndValues)-1]) } for i := 0; i < len(keysAndValues); i += 2 { - addAuditAnnotationLocked(ae, ctxAnnotations, keysAndValues[i], keysAndValues[i+1]) + addAuditAnnotationLocked(ac, keysAndValues[i], keysAndValues[i+1]) } } // AddAuditAnnotationsMap is a bulk version of AddAuditAnnotation. Refer to AddAuditAnnotation for // restrictions on when this can be called. func AddAuditAnnotationsMap(ctx context.Context, annotations map[string]string) { - mutex, ok := auditAnnotationsMutex(ctx) - if !ok { + ac := AuditContextFrom(ctx) + if ac == nil { // auditing is not enabled return } - mutex.Lock() - defer mutex.Unlock() - - ae := AuditEventFrom(ctx) - var ctxAnnotations *[]annotation - if ae == nil { - ctxAnnotations, _ = ctx.Value(auditAnnotationsKey).(*[]annotation) - } + ac.annotationMutex.Lock() + defer ac.annotationMutex.Unlock() for k, v := range annotations { - addAuditAnnotationLocked(ae, ctxAnnotations, k, v) + addAuditAnnotationLocked(ac, k, v) } } // addAuditAnnotationLocked is the shared code for recording an audit annotation. This method should // only be called while the auditAnnotationsMutex is locked. -func addAuditAnnotationLocked(ae *auditinternal.Event, annotations *[]annotation, key, value string) { - if ae != nil { - logAnnotation(ae, key, value) - } else if annotations != nil { - *annotations = append(*annotations, annotation{key: key, value: value}) +func addAuditAnnotationLocked(ac *AuditContext, key, value string) { + if ac.Event != nil { + logAnnotation(ac.Event, key, value) + } else { + ac.annotations = append(ac.annotations, annotation{key: key, value: value}) } } // This is private to prevent reads/write to the slice from outside of this package. // The audit event should be directly read to get access to the annotations. func addAuditAnnotationsFrom(ctx context.Context, ev *auditinternal.Event) { - mutex, ok := auditAnnotationsMutex(ctx) - if !ok { + ac := AuditContextFrom(ctx) + if ac == nil { // auditing is not enabled return } - mutex.Lock() - defer mutex.Unlock() + ac.annotationMutex.Lock() + defer ac.annotationMutex.Unlock() - annotations, ok := ctx.Value(auditAnnotationsKey).(*[]annotation) - if !ok { - return // no annotations to copy - } - - for _, kv := range *annotations { + for _, kv := range ac.annotations { logAnnotation(ev, kv.key, kv.value) } } @@ -185,12 +156,13 @@ func logAnnotation(ae *auditinternal.Event, key, value string) { ae.Annotations[key] = value } -// WithAuditContext returns a new context that stores the pair of the audit -// configuration object that applies to the given request and -// the audit event that is going to be written to the API audit log. -func WithAuditContext(parent context.Context, ev *AuditContext) context.Context { - parent = withAuditAnnotationsMutex(parent) - return genericapirequest.WithValue(parent, auditKey, ev) +// WithAuditContext returns a new context that stores the AuditContext. +func WithAuditContext(parent context.Context) context.Context { + if AuditContextFrom(parent) != nil { + return parent // Avoid double registering. + } + + return genericapirequest.WithValue(parent, auditKey, &AuditContext{}) } // AuditEventFrom returns the audit event struct on the ctx @@ -209,17 +181,46 @@ func AuditContextFrom(ctx context.Context) *AuditContext { return ev } -// WithAuditAnnotationMutex adds a mutex for guarding context.AddAuditAnnotation. -func withAuditAnnotationsMutex(parent context.Context) context.Context { - if _, ok := parent.Value(auditAnnotationsMutexKey).(*sync.Mutex); ok { - return parent +// WithAuditID sets the AuditID on the AuditContext. The AuditContext must already be present in the +// request context. If the specified auditID is empty, no value is set. +func WithAuditID(ctx context.Context, auditID types.UID) { + if auditID == "" { + return + } + ac := AuditContextFrom(ctx) + if ac == nil { + return + } + ac.auditID = auditID + if ac.Event != nil { + ac.Event.AuditID = auditID } - var mutex sync.Mutex - return genericapirequest.WithValue(parent, auditAnnotationsMutexKey, &mutex) } -// AuditAnnotationsMutex returns the audit annotations mutex from the context. -func auditAnnotationsMutex(ctx context.Context) (*sync.Mutex, bool) { - mutex, ok := ctx.Value(auditAnnotationsMutexKey).(*sync.Mutex) - return mutex, ok +// AuditIDFrom returns the value of the audit ID from the request context. +func AuditIDFrom(ctx context.Context) (types.UID, bool) { + if ac := AuditContextFrom(ctx); ac != nil { + return ac.auditID, ac.auditID != "" + } + return "", false +} + +// GetAuditIDTruncated returns the audit ID (truncated) from the request context. +// If the length of the Audit-ID value exceeds the limit, we truncate it to keep +// the first N (maxAuditIDLength) characters. +// This is intended to be used in logging only. +func GetAuditIDTruncated(ctx context.Context) string { + auditID, ok := AuditIDFrom(ctx) + if !ok { + return "" + } + + // if the user has specified a very long audit ID then we will use the first N characters + // Note: assuming Audit-ID header is in ASCII + const maxAuditIDLength = 64 + if len(auditID) > maxAuditIDLength { + auditID = auditID[:maxAuditIDLength] + } + + return string(auditID) } diff --git a/vendor/k8s.io/apiserver/pkg/audit/evaluator.go b/vendor/k8s.io/apiserver/pkg/audit/evaluator.go index d5e40428c00..f9664fef69c 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/evaluator.go +++ b/vendor/k8s.io/apiserver/pkg/audit/evaluator.go @@ -21,22 +21,13 @@ import ( "k8s.io/apiserver/pkg/authorization/authorizer" ) -// AuditContext is a pair of the audit configuration object that applies to -// a given request and the audit Event object that is being captured. -// It's a convenient placeholder to store both these objects in the request context. -type AuditContext struct { - // RequestAuditConfig is the audit configuration that applies to the request - RequestAuditConfig RequestAuditConfig - - // Event is the audit Event object that is being captured to be written in - // the API audit log. It is set to nil when the request is not being audited. - Event *audit.Event -} - // RequestAuditConfig is the evaluated audit configuration that is applicable to // a given request. PolicyRuleEvaluator evaluates the audit policy against the // authorizer attributes and returns a RequestAuditConfig that applies to the request. type RequestAuditConfig struct { + // Level at which the request is being audited at + Level audit.Level + // OmitStages is the stages that need to be omitted from being audited. OmitStages []audit.Stage @@ -45,21 +36,10 @@ type RequestAuditConfig struct { OmitManagedFields bool } -// RequestAuditConfigWithLevel includes Level at which the request is being audited. -// PolicyRuleEvaluator evaluates the audit configuration for a request -// against the authorizer attributes and returns an RequestAuditConfigWithLevel -// that applies to the request. -type RequestAuditConfigWithLevel struct { - RequestAuditConfig - - // Level at which the request is being audited at - Level audit.Level -} - // PolicyRuleEvaluator exposes methods for evaluating the policy rules. type PolicyRuleEvaluator interface { // EvaluatePolicyRule evaluates the audit policy of the apiserver against // the given authorizer attributes and returns the audit configuration that // is applicable to the given equest. - EvaluatePolicyRule(authorizer.Attributes) RequestAuditConfigWithLevel + EvaluatePolicyRule(authorizer.Attributes) RequestAuditConfig } diff --git a/vendor/k8s.io/apiserver/pkg/audit/request.go b/vendor/k8s.io/apiserver/pkg/audit/request.go index 57a10e62b02..972669536ed 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/request.go +++ b/vendor/k8s.io/apiserver/pkg/audit/request.go @@ -21,7 +21,6 @@ import ( "context" "fmt" "net/http" - "reflect" "time" authnv1 "k8s.io/api/authentication/v1" @@ -34,7 +33,6 @@ import ( auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" - "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog/v2" "github.com/google/uuid" @@ -54,7 +52,7 @@ func NewEventFromRequest(req *http.Request, requestReceivedTimestamp time.Time, Level: level, } - auditID, found := request.AuditIDFrom(req.Context()) + auditID, found := AuditIDFrom(req.Context()) if !found { auditID = types.UID(uuid.New().String()) } @@ -154,7 +152,7 @@ func LogRequestObject(ctx context.Context, obj runtime.Object, objGV schema.Grou if shouldOmitManagedFields(ctx) { copy, ok, err := copyWithoutManagedFields(obj) if err != nil { - klog.Warningf("error while dropping managed fields from the request for %q error: %v", reflect.TypeOf(obj).Name(), err) + klog.ErrorS(err, "Error while dropping managed fields from the request", "auditID", ae.AuditID) } if ok { obj = copy @@ -166,7 +164,7 @@ func LogRequestObject(ctx context.Context, obj runtime.Object, objGV schema.Grou ae.RequestObject, err = encodeObject(obj, objGV, s) if err != nil { // TODO(audit): add error slice to audit event struct - klog.Warningf("Auditing failed of %v request: %v", reflect.TypeOf(obj).Name(), err) + klog.ErrorS(err, "Encoding failed of request object", "auditID", ae.AuditID, "gvr", gvr.String(), "obj", obj) return } } @@ -209,7 +207,7 @@ func LogResponseObject(ctx context.Context, obj runtime.Object, gv schema.GroupV if shouldOmitManagedFields(ctx) { copy, ok, err := copyWithoutManagedFields(obj) if err != nil { - klog.Warningf("error while dropping managed fields from the response for %q error: %v", reflect.TypeOf(obj).Name(), err) + klog.ErrorS(err, "Error while dropping managed fields from the response", "auditID", ae.AuditID) } if ok { obj = copy @@ -220,7 +218,7 @@ func LogResponseObject(ctx context.Context, obj runtime.Object, gv schema.GroupV var err error ae.ResponseObject, err = encodeObject(obj, gv, s) if err != nil { - klog.Warningf("Audit failed for %q response: %v", reflect.TypeOf(obj).Name(), err) + klog.ErrorS(err, "Encoding failed of response object", "auditID", ae.AuditID, "obj", obj) } } @@ -239,7 +237,7 @@ func encodeObject(obj runtime.Object, gv schema.GroupVersion, serializer runtime return &runtime.Unknown{ Raw: buf.Bytes(), - ContentType: runtime.ContentTypeJSON, + ContentType: mediaType, }, nil } diff --git a/vendor/k8s.io/apiserver/pkg/authentication/serviceaccount/util.go b/vendor/k8s.io/apiserver/pkg/authentication/serviceaccount/util.go new file mode 100644 index 00000000000..f0dc0767639 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/authentication/serviceaccount/util.go @@ -0,0 +1,183 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serviceaccount + +import ( + "context" + "fmt" + "strings" + + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + + "k8s.io/klog/v2" +) + +const ( + ServiceAccountUsernamePrefix = "system:serviceaccount:" + ServiceAccountUsernameSeparator = ":" + ServiceAccountGroupPrefix = "system:serviceaccounts:" + AllServiceAccountsGroup = "system:serviceaccounts" + // PodNameKey is the key used in a user's "extra" to specify the pod name of + // the authenticating request. + PodNameKey = "authentication.kubernetes.io/pod-name" + // PodUIDKey is the key used in a user's "extra" to specify the pod UID of + // the authenticating request. + PodUIDKey = "authentication.kubernetes.io/pod-uid" +) + +// MakeUsername generates a username from the given namespace and ServiceAccount name. +// The resulting username can be passed to SplitUsername to extract the original namespace and ServiceAccount name. +func MakeUsername(namespace, name string) string { + return ServiceAccountUsernamePrefix + namespace + ServiceAccountUsernameSeparator + name +} + +// MatchesUsername checks whether the provided username matches the namespace and name without +// allocating. Use this when checking a service account namespace and name against a known string. +func MatchesUsername(namespace, name string, username string) bool { + if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) { + return false + } + username = username[len(ServiceAccountUsernamePrefix):] + + if !strings.HasPrefix(username, namespace) { + return false + } + username = username[len(namespace):] + + if !strings.HasPrefix(username, ServiceAccountUsernameSeparator) { + return false + } + username = username[len(ServiceAccountUsernameSeparator):] + + return username == name +} + +var invalidUsernameErr = fmt.Errorf("Username must be in the form %s", MakeUsername("namespace", "name")) + +// SplitUsername returns the namespace and ServiceAccount name embedded in the given username, +// or an error if the username is not a valid name produced by MakeUsername +func SplitUsername(username string) (string, string, error) { + if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) { + return "", "", invalidUsernameErr + } + trimmed := strings.TrimPrefix(username, ServiceAccountUsernamePrefix) + parts := strings.Split(trimmed, ServiceAccountUsernameSeparator) + if len(parts) != 2 { + return "", "", invalidUsernameErr + } + namespace, name := parts[0], parts[1] + if len(apimachineryvalidation.ValidateNamespaceName(namespace, false)) != 0 { + return "", "", invalidUsernameErr + } + if len(apimachineryvalidation.ValidateServiceAccountName(name, false)) != 0 { + return "", "", invalidUsernameErr + } + return namespace, name, nil +} + +// MakeGroupNames generates service account group names for the given namespace +func MakeGroupNames(namespace string) []string { + return []string{ + AllServiceAccountsGroup, + MakeNamespaceGroupName(namespace), + } +} + +// MakeNamespaceGroupName returns the name of the group all service accounts in the namespace are included in +func MakeNamespaceGroupName(namespace string) string { + return ServiceAccountGroupPrefix + namespace +} + +// UserInfo returns a user.Info interface for the given namespace, service account name and UID +func UserInfo(namespace, name, uid string) user.Info { + return (&ServiceAccountInfo{ + Name: name, + Namespace: namespace, + UID: uid, + }).UserInfo() +} + +type ServiceAccountInfo struct { + Name, Namespace, UID string + PodName, PodUID string +} + +func (sa *ServiceAccountInfo) UserInfo() user.Info { + info := &user.DefaultInfo{ + Name: MakeUsername(sa.Namespace, sa.Name), + UID: sa.UID, + Groups: MakeGroupNames(sa.Namespace), + } + if sa.PodName != "" && sa.PodUID != "" { + info.Extra = map[string][]string{ + PodNameKey: {sa.PodName}, + PodUIDKey: {sa.PodUID}, + } + } + return info +} + +// IsServiceAccountToken returns true if the secret is a valid api token for the service account +func IsServiceAccountToken(secret *v1.Secret, sa *v1.ServiceAccount) bool { + if secret.Type != v1.SecretTypeServiceAccountToken { + return false + } + + name := secret.Annotations[v1.ServiceAccountNameKey] + uid := secret.Annotations[v1.ServiceAccountUIDKey] + if name != sa.Name { + // Name must match + return false + } + if len(uid) > 0 && uid != string(sa.UID) { + // If UID is specified, it must match + return false + } + + return true +} + +func GetOrCreateServiceAccount(coreClient v1core.CoreV1Interface, namespace, name string) (*v1.ServiceAccount, error) { + sa, err := coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err == nil { + return sa, nil + } + if !apierrors.IsNotFound(err) { + return nil, err + } + + // Create the namespace if we can't verify it exists. + // Tolerate errors, since we don't know whether this component has namespace creation permissions. + if _, err := coreClient.Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}); apierrors.IsNotFound(err) { + if _, err = coreClient.Namespaces().Create(context.TODO(), &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { + klog.Warningf("create non-exist namespace %s failed:%v", namespace, err) + } + } + + // Create the service account + sa, err = coreClient.ServiceAccounts(namespace).Create(context.TODO(), &v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}, metav1.CreateOptions{}) + if apierrors.IsAlreadyExists(err) { + // If we're racing to init and someone else already created it, re-fetch + return coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + } + return sa, err +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/OWNERS b/vendor/k8s.io/apiserver/pkg/cel/OWNERS new file mode 100644 index 00000000000..f550fc17944 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/OWNERS @@ -0,0 +1,11 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Kubernetes CEL library authors and maintainers +approvers: + - jpbetz + - cici37 + - jiahuif +reviewers: + - jpbetz + - cici37 + - jiahuif diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go b/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go new file mode 100644 index 00000000000..c28d6ce510a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go @@ -0,0 +1,81 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +// Schema is the adapted type for an OpenAPI schema that CEL uses. +// This schema does not cover all OpenAPI fields but only these CEL requires +// are exposed as getters. +type Schema interface { + // Type returns the OpenAPI type. + // Multiple types are not supported. It should return + // empty string if no type is specified. + Type() string + + // Format returns the OpenAPI format. May be empty + Format() string + + // Items returns the OpenAPI items. or nil of this field does not exist or + // contains no schema. + Items() Schema + + // Properties returns the OpenAPI properties, or nil if this field does not + // exist. + // The values of the returned map are of the adapted type. + Properties() map[string]Schema + + // AdditionalProperties returns the OpenAPI additional properties field, + // or nil if this field does not exist. + AdditionalProperties() SchemaOrBool + + // Default returns the OpenAPI default field, or nil if this field does not exist. + Default() any + + Validations + KubeExtensions + + // WithTypeAndObjectMeta returns a schema that has the type and object meta set. + // the type includes "kind", "apiVersion" field + // the "metadata" field requires "name" and "generateName" to be set + // The original schema must not be mutated. Make a copy if necessary. + WithTypeAndObjectMeta() Schema +} + +// Validations contains OpenAPI validation that the CEL library uses. +type Validations interface { + MaxItems() *int64 + MaxLength() *int64 + MaxProperties() *int64 + Required() []string + Enum() []any + Nullable() bool +} + +// KubeExtensions contains Kubernetes-specific extensions to the OpenAPI schema. +type KubeExtensions interface { + IsXIntOrString() bool + IsXEmbeddedResource() bool + IsXPreserveUnknownFields() bool + XListType() string + XListMapKeys() []string +} + +// SchemaOrBool contains either a schema or a boolean indicating if the object +// can contain any fields. +type SchemaOrBool interface { + Schema() Schema + Allows() bool +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go b/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go new file mode 100644 index 00000000000..99fda092e4b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go @@ -0,0 +1,177 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "fmt" + "strings" +) + +// MapList provides a "lookup by key" operation for lists (arrays) with x-kubernetes-list-type=map. +type MapList interface { + // Get returns the first element having given key, for all + // x-kubernetes-list-map-keys, to the provided object. If the provided object isn't itself a valid MapList element, + // get returns nil. + Get(interface{}) interface{} +} + +type keyStrategy interface { + // CompositeKeyFor returns a composite key for the provided object, if possible, and a + // boolean that indicates whether or not a key could be generated for the provided object. + CompositeKeyFor(map[string]interface{}) (interface{}, bool) +} + +// singleKeyStrategy is a cheaper strategy for associative lists that have exactly one key. +type singleKeyStrategy struct { + key string +} + +// CompositeKeyFor directly returns the value of the single key to +// use as a composite key. +func (ks *singleKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { + v, ok := obj[ks.key] + if !ok { + return nil, false + } + + switch v.(type) { + case bool, float64, int64, string: + return v, true + default: + return nil, false // non-scalar + } +} + +// multiKeyStrategy computes a composite key of all key values. +type multiKeyStrategy struct { + sts Schema +} + +// CompositeKeyFor returns a composite key computed from the values of all +// keys. +func (ks *multiKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { + const keyDelimiter = "\x00" // 0 byte should never appear in the composite key except as delimiter + + var delimited strings.Builder + for _, key := range ks.sts.XListMapKeys() { + v, ok := obj[key] + if !ok { + return nil, false + } + + switch v.(type) { + case bool: + fmt.Fprintf(&delimited, keyDelimiter+"%t", v) + case float64: + fmt.Fprintf(&delimited, keyDelimiter+"%f", v) + case int64: + fmt.Fprintf(&delimited, keyDelimiter+"%d", v) + case string: + fmt.Fprintf(&delimited, keyDelimiter+"%q", v) + default: + return nil, false // values must be scalars + } + } + return delimited.String(), true +} + +// emptyMapList is a MapList containing no elements. +type emptyMapList struct{} + +func (emptyMapList) Get(interface{}) interface{} { + return nil +} + +type mapListImpl struct { + sts Schema + ks keyStrategy + // keyedItems contains all lazily keyed map items + keyedItems map[interface{}]interface{} + // unkeyedItems contains all map items that have not yet been keyed + unkeyedItems []interface{} +} + +func (a *mapListImpl) Get(obj interface{}) interface{} { + mobj, ok := obj.(map[string]interface{}) + if !ok { + return nil + } + + key, ok := a.ks.CompositeKeyFor(mobj) + if !ok { + return nil + } + if match, ok := a.keyedItems[key]; ok { + return match + } + // keep keying items until we either find a match or run out of unkeyed items + for len(a.unkeyedItems) > 0 { + // dequeue an unkeyed item + item := a.unkeyedItems[0] + a.unkeyedItems = a.unkeyedItems[1:] + + // key the item + mitem, ok := item.(map[string]interface{}) + if !ok { + continue + } + itemKey, ok := a.ks.CompositeKeyFor(mitem) + if !ok { + continue + } + if _, exists := a.keyedItems[itemKey]; !exists { + a.keyedItems[itemKey] = mitem + } + + // if it matches, short-circuit + if itemKey == key { + return mitem + } + } + + return nil +} + +func makeKeyStrategy(sts Schema) keyStrategy { + listMapKeys := sts.XListMapKeys() + if len(listMapKeys) == 1 { + key := listMapKeys[0] + return &singleKeyStrategy{ + key: key, + } + } + + return &multiKeyStrategy{ + sts: sts, + } +} + +// MakeMapList returns a queryable interface over the provided x-kubernetes-list-type=map +// keyedItems. If the provided schema is _not_ an array with x-kubernetes-list-type=map, returns an +// empty mapList. +func MakeMapList(sts Schema, items []interface{}) (rv MapList) { + if sts.Type() != "array" || sts.XListType() != "map" || len(sts.XListMapKeys()) == 0 || len(items) == 0 { + return emptyMapList{} + } + ks := makeKeyStrategy(sts) + return &mapListImpl{ + sts: sts, + ks: ks, + keyedItems: map[interface{}]interface{}{}, + unkeyedItems: items, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go b/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go new file mode 100644 index 00000000000..3fdd3a6c8ba --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go @@ -0,0 +1,257 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "time" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const maxRequestSizeBytes = apiservercel.DefaultMaxRequestSizeBytes + +// SchemaDeclType converts the structural schema to a CEL declaration, or returns nil if the +// structural schema should not be exposed in CEL expressions. +// Set isResourceRoot to true for the root of a custom resource or embedded resource. +// +// Schemas with XPreserveUnknownFields not exposed unless they are objects. Array and "maps" schemas +// are not exposed if their items or additionalProperties schemas are not exposed. Object Properties are not exposed +// if their schema is not exposed. +// +// The CEL declaration for objects with XPreserveUnknownFields does not expose unknown fields. +func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType { + if s == nil { + return nil + } + if s.IsXIntOrString() { + // schemas using XIntOrString are not required to have a type. + + // intOrStringType represents the x-kubernetes-int-or-string union type in CEL expressions. + // In CEL, the type is represented as dynamic value, which can be thought of as a union type of all types. + // All type checking for XIntOrString is deferred to runtime, so all access to values of this type must + // be guarded with a type check, e.g.: + // + // To require that the string representation be a percentage: + // `type(intOrStringField) == string && intOrStringField.matches(r'(\d+(\.\d+)?%)')` + // To validate requirements on both the int and string representation: + // `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5 + // + dyn := apiservercel.NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) // smallest value for a serialized x-kubernetes-int-or-string is 0 + // handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string + dyn.MaxElements = maxRequestSizeBytes - 2 + return dyn + } + + // We ignore XPreserveUnknownFields since we don't support validation rules on + // data that we don't have schema information for. + + if isResourceRoot { + // 'apiVersion', 'kind', 'metadata.name' and 'metadata.generateName' are always accessible to validator rules + // at the root of resources, even if not specified in the schema. + // This includes the root of a custom resource and the root of XEmbeddedResource objects. + s = s.WithTypeAndObjectMeta() + } + + switch s.Type() { + case "array": + if s.Items() != nil { + itemsType := SchemaDeclType(s.Items(), s.Items().IsXEmbeddedResource()) + if itemsType == nil { + return nil + } + var maxItems int64 + if s.MaxItems() != nil { + maxItems = zeroIfNegative(*s.MaxItems()) + } else { + maxItems = estimateMaxArrayItemsFromMinSize(itemsType.MinSerializedSize) + } + return apiservercel.NewListType(itemsType, maxItems) + } + return nil + case "object": + if s.AdditionalProperties() != nil && s.AdditionalProperties().Schema() != nil { + propsType := SchemaDeclType(s.AdditionalProperties().Schema(), s.AdditionalProperties().Schema().IsXEmbeddedResource()) + if propsType != nil { + var maxProperties int64 + if s.MaxProperties() != nil { + maxProperties = zeroIfNegative(*s.MaxProperties()) + } else { + maxProperties = estimateMaxAdditionalPropertiesFromMinSize(propsType.MinSerializedSize) + } + return apiservercel.NewMapType(apiservercel.StringType, propsType, maxProperties) + } + return nil + } + fields := make(map[string]*apiservercel.DeclField, len(s.Properties())) + + required := map[string]bool{} + if s.Required() != nil { + for _, f := range s.Required() { + required[f] = true + } + } + // an object will always be serialized at least as {}, so account for that + minSerializedSize := int64(2) + for name, prop := range s.Properties() { + var enumValues []interface{} + if prop.Enum() != nil { + for _, e := range prop.Enum() { + enumValues = append(enumValues, e) + } + } + if fieldType := SchemaDeclType(prop, prop.IsXEmbeddedResource()); fieldType != nil { + if propName, ok := apiservercel.Escape(name); ok { + fields[propName] = apiservercel.NewDeclField(propName, fieldType, required[name], enumValues, prop.Default()) + } + // the min serialized size for an object is 2 (for {}) plus the min size of all its required + // properties + // only include required properties without a default value; default values are filled in + // server-side + if required[name] && prop.Default() == nil { + minSerializedSize += int64(len(name)) + fieldType.MinSerializedSize + 4 + } + } + } + objType := apiservercel.NewObjectType("object", fields) + objType.MinSerializedSize = minSerializedSize + return objType + case "string": + switch s.Format() { + case "byte": + byteWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), apiservercel.MinStringSize) + if s.MaxLength() != nil { + byteWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) + } else { + byteWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + } + return byteWithMaxLength + case "duration": + durationWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, int64(apiservercel.MinDurationSizeJSON)) + durationWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return durationWithMaxLength + case "date": + timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.JSONDateSize)) + timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return timestampWithMaxLength + case "date-time": + timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.MinDatetimeSizeJSON)) + timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return timestampWithMaxLength + } + + strWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), apiservercel.MinStringSize) + if s.MaxLength() != nil { + // multiply the user-provided max length by 4 in the case of an otherwise-untyped string + // we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points, + // but we need to reason about length for things like request size, so we use bytes in this code (and an individual + // unicode code point can be up to 4 bytes long) + strWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) * 4 + } else { + strWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + } + return strWithMaxLength + case "boolean": + return apiservercel.BoolType + case "number": + return apiservercel.DoubleType + case "integer": + return apiservercel.IntType + } + return nil +} + +func zeroIfNegative(v int64) int64 { + if v < 0 { + return 0 + } + return v +} + +// WithTypeAndObjectMeta ensures the kind, apiVersion and +// metadata.name and metadata.generateName properties are specified, making a shallow copy of the provided schema if needed. +func WithTypeAndObjectMeta(s *spec.Schema) *spec.Schema { + if s.Properties != nil && + s.Properties["kind"].Type.Contains("string") && + s.Properties["apiVersion"].Type.Contains("string") && + s.Properties["metadata"].Type.Contains("object") && + s.Properties["metadata"].Properties != nil && + s.Properties["metadata"].Properties["name"].Type.Contains("string") && + s.Properties["metadata"].Properties["generateName"].Type.Contains("string") { + return s + } + result := *s + props := make(map[string]spec.Schema, len(s.Properties)) + for k, prop := range s.Properties { + props[k] = prop + } + stringType := spec.StringProperty() + props["kind"] = *stringType + props["apiVersion"] = *stringType + props["metadata"] = spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": *stringType, + "generateName": *stringType, + }, + }, + } + result.Properties = props + + return &result +} + +// estimateMaxStringLengthPerRequest estimates the maximum string length (in characters) +// of a string compatible with the format requirements in the provided schema. +// must only be called on schemas of type "string" or x-kubernetes-int-or-string: true +func estimateMaxStringLengthPerRequest(s Schema) int64 { + if s.IsXIntOrString() { + return maxRequestSizeBytes - 2 + } + switch s.Format() { + case "duration": + return apiservercel.MaxDurationSizeJSON + case "date": + return apiservercel.JSONDateSize + case "date-time": + return apiservercel.MaxDatetimeSizeJSON + default: + // subtract 2 to account for "" + return maxRequestSizeBytes - 2 + } +} + +// estimateMaxArrayItemsPerRequest estimates the maximum number of array items with +// the provided minimum serialized size that can fit into a single request. +func estimateMaxArrayItemsFromMinSize(minSize int64) int64 { + // subtract 2 to account for [ and ] + return (maxRequestSizeBytes - 2) / (minSize + 1) +} + +// estimateMaxAdditionalPropertiesPerRequest estimates the maximum number of additional properties +// with the provided minimum serialized size that can fit into a single request. +func estimateMaxAdditionalPropertiesFromMinSize(minSize int64) int64 { + // 2 bytes for key + "" + colon + comma + smallest possible value, realistically the actual keys + // will all vary in length + keyValuePairSize := minSize + 6 + // subtract 2 to account for { and } + return (maxRequestSizeBytes - 2) / keyValuePairSize +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/values.go b/vendor/k8s.io/apiserver/pkg/cel/common/values.go new file mode 100644 index 00000000000..d9034a80fb2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/values.go @@ -0,0 +1,717 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "fmt" + "reflect" + "sync" + "time" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + "k8s.io/kube-openapi/pkg/validation/strfmt" + + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apiserver/pkg/cel" +) + +// UnstructuredToVal converts a Kubernetes unstructured data element to a CEL Val. +// The root schema of custom resource schema is expected contain type meta and object meta schemas. +// If Embedded resources do not contain type meta and object meta schemas, they will be added automatically. +func UnstructuredToVal(unstructured interface{}, schema Schema) ref.Val { + if unstructured == nil { + if schema.Nullable() { + return types.NullValue + } + return types.NewErr("invalid data, got null for schema with nullable=false") + } + if schema.IsXIntOrString() { + switch v := unstructured.(type) { + case string: + return types.String(v) + case int: + return types.Int(v) + case int32: + return types.Int(v) + case int64: + return types.Int(v) + } + return types.NewErr("invalid data, expected XIntOrString value to be either a string or integer") + } + if schema.Type() == "object" { + m, ok := unstructured.(map[string]interface{}) + if !ok { + return types.NewErr("invalid data, expected a map for the provided schema with type=object") + } + if schema.IsXEmbeddedResource() || schema.Properties() != nil { + if schema.IsXEmbeddedResource() { + schema = schema.WithTypeAndObjectMeta() + } + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + if schema, ok := schema.Properties()[key]; ok { + return schema, true + } + return nil, false + }, + } + } + if schema.AdditionalProperties() != nil && schema.AdditionalProperties().Schema() != nil { + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + return schema.AdditionalProperties().Schema(), true + }, + } + } + // A object with x-kubernetes-preserve-unknown-fields but no properties or additionalProperties is treated + // as an empty object. + if schema.IsXPreserveUnknownFields() { + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + return nil, false + }, + } + } + return types.NewErr("invalid object type, expected either Properties or AdditionalProperties with Allows=true and non-empty Schema") + } + + if schema.Type() == "array" { + l, ok := unstructured.([]interface{}) + if !ok { + return types.NewErr("invalid data, expected an array for the provided schema with type=array") + } + if schema.Items() == nil { + return types.NewErr("invalid array type, expected Items with a non-empty Schema") + } + typedList := unstructuredList{elements: l, itemsSchema: schema.Items()} + listType := schema.XListType() + if listType != "" { + switch listType { + case "map": + mapKeys := schema.XListMapKeys() + return &unstructuredMapList{unstructuredList: typedList, escapedKeyProps: escapeKeyProps(mapKeys)} + case "set": + return &unstructuredSetList{unstructuredList: typedList} + case "atomic": + return &typedList + default: + return types.NewErr("invalid x-kubernetes-list-type, expected 'map', 'set' or 'atomic' but got %s", listType) + } + } + return &typedList + } + + if schema.Type() == "string" { + str, ok := unstructured.(string) + if !ok { + return types.NewErr("invalid data, expected string, got %T", unstructured) + } + switch schema.Format() { + case "duration": + d, err := strfmt.ParseDuration(str) + if err != nil { + return types.NewErr("Invalid duration %s: %v", str, err) + } + return types.Duration{Duration: d} + case "date": + d, err := time.Parse(strfmt.RFC3339FullDate, str) // strfmt uses this format for OpenAPIv3 value validation + if err != nil { + return types.NewErr("Invalid date formatted string %s: %v", str, err) + } + return types.Timestamp{Time: d} + case "date-time": + d, err := strfmt.ParseDateTime(str) + if err != nil { + return types.NewErr("Invalid date-time formatted string %s: %v", str, err) + } + return types.Timestamp{Time: time.Time(d)} + case "byte": + base64 := strfmt.Base64{} + err := base64.UnmarshalText([]byte(str)) + if err != nil { + return types.NewErr("Invalid byte formatted string %s: %v", str, err) + } + return types.Bytes(base64) + } + + return types.String(str) + } + if schema.Type() == "number" { + switch v := unstructured.(type) { + // float representations of whole numbers (e.g. 1.0, 0.0) can convert to int representations (e.g. 1, 0) in yaml + // to json translation, and then get parsed as int64s + case int: + return types.Double(v) + case int32: + return types.Double(v) + case int64: + return types.Double(v) + + case float32: + return types.Double(v) + case float64: + return types.Double(v) + default: + return types.NewErr("invalid data, expected float, got %T", unstructured) + } + } + if schema.Type() == "integer" { + switch v := unstructured.(type) { + case int: + return types.Int(v) + case int32: + return types.Int(v) + case int64: + return types.Int(v) + default: + return types.NewErr("invalid data, expected int, got %T", unstructured) + } + } + if schema.Type() == "boolean" { + b, ok := unstructured.(bool) + if !ok { + return types.NewErr("invalid data, expected bool, got %T", unstructured) + } + return types.Bool(b) + } + + if schema.IsXPreserveUnknownFields() { + return &unknownPreserved{u: unstructured} + } + + return types.NewErr("invalid type, expected object, array, number, integer, boolean or string, or no type with x-kubernetes-int-or-string or x-kubernetes-preserve-unknown-fields is true, got %s", schema.Type()) +} + +// unknownPreserved represents unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields. +// It preserves the data at runtime without assuming it is of any particular type and supports only equality checking. +// unknownPreserved should be used only for values are not directly accessible in CEL expressions, i.e. for data +// where there is no corresponding CEL type declaration. +type unknownPreserved struct { + u interface{} +} + +func (t *unknownPreserved) ConvertToNative(refType reflect.Type) (interface{}, error) { + return nil, fmt.Errorf("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", refType) +} + +func (t *unknownPreserved) ConvertToType(typeValue ref.Type) ref.Val { + return types.NewErr("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", typeValue.TypeName()) +} + +func (t *unknownPreserved) Equal(other ref.Val) ref.Val { + return types.Bool(equality.Semantic.DeepEqual(t.u, other.Value())) +} + +func (t *unknownPreserved) Type() ref.Type { + return types.UnknownType +} + +func (t *unknownPreserved) Value() interface{} { + return t.u // used by Equal checks +} + +// unstructuredMapList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=map. +type unstructuredMapList struct { + unstructuredList + escapedKeyProps []string + + sync.Once // for for lazy load of mapOfList since it is only needed if Equals is called + mapOfList map[interface{}]interface{} +} + +func (t *unstructuredMapList) getMap() map[interface{}]interface{} { + t.Do(func() { + t.mapOfList = make(map[interface{}]interface{}, len(t.elements)) + for _, e := range t.elements { + t.mapOfList[t.toMapKey(e)] = e + } + }) + return t.mapOfList +} + +// toMapKey returns a valid golang map key for the given element of the map list. +// element must be a valid map list entry where all map key props are scalar types (which are comparable in go +// and valid for use in a golang map key). +func (t *unstructuredMapList) toMapKey(element interface{}) interface{} { + eObj, ok := element.(map[string]interface{}) + if !ok { + return types.NewErr("unexpected data format for element of array with x-kubernetes-list-type=map: %T", element) + } + // Arrays are comparable in go and may be used as map keys, but maps and slices are not. + // So we can special case small numbers of key props as arrays and fall back to serialization + // for larger numbers of key props + if len(t.escapedKeyProps) == 1 { + return eObj[t.escapedKeyProps[0]] + } + if len(t.escapedKeyProps) == 2 { + return [2]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]]} + } + if len(t.escapedKeyProps) == 3 { + return [3]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]], eObj[t.escapedKeyProps[2]]} + } + + key := make([]interface{}, len(t.escapedKeyProps)) + for i, kf := range t.escapedKeyProps { + key[i] = eObj[kf] + } + return fmt.Sprintf("%v", key) +} + +// Equal on a map list ignores list element order. +func (t *unstructuredMapList) Equal(other ref.Val) ref.Val { + oMapList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oMapList.Size() { + return types.False + } + tMap := t.getMap() + for it := oMapList.Iterator(); it.HasNext() == types.True; { + v := it.Next() + k := t.toMapKey(v.Value()) + tVal, ok := tMap[k] + if !ok { + return types.False + } + eq := UnstructuredToVal(tVal, t.itemsSchema).Equal(v) + if eq != types.True { + return eq // either false or error + } + } + return types.True +} + +// Add for a map list `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values +// are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with +// non-intersecting keys are appended, retaining their partial order. +func (t *unstructuredMapList) Add(other ref.Val) ref.Val { + oMapList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := make([]interface{}, len(t.elements)) + keyToIdx := map[interface{}]int{} + for i, e := range t.elements { + k := t.toMapKey(e) + keyToIdx[k] = i + elements[i] = e + } + for it := oMapList.Iterator(); it.HasNext() == types.True; { + v := it.Next().Value() + k := t.toMapKey(v) + if overwritePosition, ok := keyToIdx[k]; ok { + elements[overwritePosition] = v + } else { + elements = append(elements, v) + } + } + return &unstructuredMapList{ + unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, + escapedKeyProps: t.escapedKeyProps, + } +} + +// escapeKeyProps returns identifiers with Escape applied to each. +// Identifiers that cannot be escaped are left as-is. They are inaccessible to CEL programs but are +// are still needed internally to perform equality checks. +func escapeKeyProps(idents []string) []string { + result := make([]string, len(idents)) + for i, prop := range idents { + if escaped, ok := cel.Escape(prop); ok { + result[i] = escaped + } else { + result[i] = prop + } + } + return result +} + +// unstructuredSetList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=set. +type unstructuredSetList struct { + unstructuredList + escapedKeyProps []string + + sync.Once // for for lazy load of setOfList since it is only needed if Equals is called + set map[interface{}]struct{} +} + +func (t *unstructuredSetList) getSet() map[interface{}]struct{} { + // sets are only allowed to contain scalar elements, which are comparable in go, and can safely be used as + // golang map keys + t.Do(func() { + t.set = make(map[interface{}]struct{}, len(t.elements)) + for _, e := range t.elements { + t.set[e] = struct{}{} + } + }) + return t.set +} + +// Equal on a map list ignores list element order. +func (t *unstructuredSetList) Equal(other ref.Val) ref.Val { + oSetList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oSetList.Size() { + return types.False + } + tSet := t.getSet() + for it := oSetList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + _, ok := tSet[next] + if !ok { + return types.False + } + } + return types.True +} + +// Add for a set list `X + Y` performs a union where the array positions of all elements in `X` are preserved and +// non-intersecting elements in `Y` are appended, retaining their partial order. +func (t *unstructuredSetList) Add(other ref.Val) ref.Val { + oSetList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := t.elements + set := t.getSet() + for it := oSetList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + if _, ok := set[next]; !ok { + set[next] = struct{}{} + elements = append(elements, next) + } + } + return &unstructuredSetList{ + unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, + escapedKeyProps: t.escapedKeyProps, + } +} + +// unstructuredList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=atomic (the default). +type unstructuredList struct { + elements []interface{} + itemsSchema Schema +} + +var _ = traits.Lister(&unstructuredList{}) + +func (t *unstructuredList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Slice: + switch t.itemsSchema.Type() { + // Workaround for https://github.com/kubernetes/kubernetes/issues/117590 until we + // resolve the desired behavior in cel-go via https://github.com/google/cel-go/issues/688 + case "string": + var result []string + for _, e := range t.elements { + s, ok := e.(string) + if !ok { + return nil, fmt.Errorf("expected all elements to be of type string, but got %T", e) + } + result = append(result, s) + } + return result, nil + default: + return t.elements, nil + } + } + return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) +} + +func (t *unstructuredList) ConvertToType(typeValue ref.Type) ref.Val { + switch typeValue { + case types.ListType: + return t + case types.TypeType: + return types.ListType + } + return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) +} + +func (t *unstructuredList) Equal(other ref.Val) ref.Val { + oList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oList.Size() { + return types.False + } + for i := types.Int(0); i < sz; i++ { + eq := t.Get(i).Equal(oList.Get(i)) + if eq != types.True { + return eq // either false or error + } + } + return types.True +} + +func (t *unstructuredList) Type() ref.Type { + return types.ListType +} + +func (t *unstructuredList) Value() interface{} { + return t.elements +} + +func (t *unstructuredList) Add(other ref.Val) ref.Val { + oList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := t.elements + for it := oList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + elements = append(elements, next) + } + + return &unstructuredList{elements: elements, itemsSchema: t.itemsSchema} +} + +func (t *unstructuredList) Contains(val ref.Val) ref.Val { + if types.IsUnknownOrError(val) { + return val + } + var err ref.Val + sz := len(t.elements) + for i := 0; i < sz; i++ { + elem := UnstructuredToVal(t.elements[i], t.itemsSchema) + cmp := elem.Equal(val) + b, ok := cmp.(types.Bool) + if !ok && err == nil { + err = types.MaybeNoSuchOverloadErr(cmp) + } + if b == types.True { + return types.True + } + } + if err != nil { + return err + } + return types.False +} + +func (t *unstructuredList) Get(idx ref.Val) ref.Val { + iv, isInt := idx.(types.Int) + if !isInt { + return types.ValOrErr(idx, "unsupported index: %v", idx) + } + i := int(iv) + if i < 0 || i >= len(t.elements) { + return types.NewErr("index out of bounds: %v", idx) + } + return UnstructuredToVal(t.elements[i], t.itemsSchema) +} + +func (t *unstructuredList) Iterator() traits.Iterator { + items := make([]ref.Val, len(t.elements)) + for i, item := range t.elements { + itemCopy := item + items[i] = UnstructuredToVal(itemCopy, t.itemsSchema) + } + return &listIterator{unstructuredList: t, items: items} +} + +type listIterator struct { + *unstructuredList + items []ref.Val + idx int +} + +func (it *listIterator) HasNext() ref.Val { + return types.Bool(it.idx < len(it.items)) +} + +func (it *listIterator) Next() ref.Val { + item := it.items[it.idx] + it.idx++ + return item +} + +func (t *unstructuredList) Size() ref.Val { + return types.Int(len(t.elements)) +} + +// unstructuredMap represented an unstructured data instance of an OpenAPI object. +type unstructuredMap struct { + value map[string]interface{} + schema Schema + // propSchema finds the schema to use for a particular map key. + propSchema func(key string) (Schema, bool) +} + +var _ = traits.Mapper(&unstructuredMap{}) + +func (t *unstructuredMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Map: + return t.value, nil + } + return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) +} + +func (t *unstructuredMap) ConvertToType(typeValue ref.Type) ref.Val { + switch typeValue { + case types.MapType: + return t + case types.TypeType: + return types.MapType + } + return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) +} + +func (t *unstructuredMap) Equal(other ref.Val) ref.Val { + oMap, isMap := other.(traits.Mapper) + if !isMap { + return types.MaybeNoSuchOverloadErr(other) + } + if t.Size() != oMap.Size() { + return types.False + } + for key, value := range t.value { + if propSchema, ok := t.propSchema(key); ok { + ov, found := oMap.Find(types.String(key)) + if !found { + return types.False + } + v := UnstructuredToVal(value, propSchema) + vEq := v.Equal(ov) + if vEq != types.True { + return vEq // either false or error + } + } else { + // Must be an object with properties. + // Since we've encountered an unknown field, fallback to unstructured equality checking. + ouMap, ok := other.(*unstructuredMap) + if !ok { + // The compiler ensures equality is against the same type of object, so this should be unreachable + return types.MaybeNoSuchOverloadErr(other) + } + if oValue, ok := ouMap.value[key]; ok { + if !equality.Semantic.DeepEqual(value, oValue) { + return types.False + } + } + } + } + return types.True +} + +func (t *unstructuredMap) Type() ref.Type { + return types.MapType +} + +func (t *unstructuredMap) Value() interface{} { + return t.value +} + +func (t *unstructuredMap) Contains(key ref.Val) ref.Val { + v, found := t.Find(key) + if v != nil && types.IsUnknownOrError(v) { + return v + } + + return types.Bool(found) +} + +func (t *unstructuredMap) Get(key ref.Val) ref.Val { + v, found := t.Find(key) + if found { + return v + } + return types.ValOrErr(key, "no such key: %v", key) +} + +func (t *unstructuredMap) Iterator() traits.Iterator { + isObject := t.schema.Properties() != nil + keys := make([]ref.Val, len(t.value)) + i := 0 + for k := range t.value { + if _, ok := t.propSchema(k); ok { + mapKey := k + if isObject { + if escaped, ok := cel.Escape(k); ok { + mapKey = escaped + } + } + keys[i] = types.String(mapKey) + i++ + } + } + return &mapIterator{unstructuredMap: t, keys: keys} +} + +type mapIterator struct { + *unstructuredMap + keys []ref.Val + idx int +} + +func (it *mapIterator) HasNext() ref.Val { + return types.Bool(it.idx < len(it.keys)) +} + +func (it *mapIterator) Next() ref.Val { + key := it.keys[it.idx] + it.idx++ + return key +} + +func (t *unstructuredMap) Size() ref.Val { + return types.Int(len(t.value)) +} + +func (t *unstructuredMap) Find(key ref.Val) (ref.Val, bool) { + isObject := t.schema.Properties() != nil + keyStr, ok := key.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(key), true + } + k := keyStr.Value().(string) + if isObject { + k, ok = cel.Unescape(k) + if !ok { + return nil, false + } + } + if v, ok := t.value[k]; ok { + // If this is an object with properties, not an object with additionalProperties, + // then null valued nullable fields are treated the same as absent optional fields. + if isObject && v == nil { + return nil, false + } + if propSchema, ok := t.propSchema(k); ok { + return UnstructuredToVal(v, propSchema), true + } + } + + return nil, false +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/composited.go b/vendor/k8s.io/apiserver/pkg/cel/composited.go new file mode 100644 index 00000000000..9e5e634d0c3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/composited.go @@ -0,0 +1,119 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "github.com/google/cel-go/common/types/ref" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var _ ref.TypeProvider = (*CompositedTypeProvider)(nil) +var _ ref.TypeAdapter = (*CompositedTypeAdapter)(nil) + +// CompositedTypeProvider is the provider that tries each of the underlying +// providers in order, and returns result of the first successful attempt. +type CompositedTypeProvider struct { + // Providers contains the underlying type providers. + // If Providers is empty, the CompositedTypeProvider becomes no-op provider. + Providers []ref.TypeProvider +} + +// EnumValue finds out the numeric value of the given enum name. +// The result comes from first provider that returns non-nil. +func (c *CompositedTypeProvider) EnumValue(enumName string) ref.Val { + for _, p := range c.Providers { + val := p.EnumValue(enumName) + if val != nil { + return val + } + } + return nil +} + +// FindIdent takes a qualified identifier name and returns a Value if one +// exists. The result comes from first provider that returns non-nil. +func (c *CompositedTypeProvider) FindIdent(identName string) (ref.Val, bool) { + for _, p := range c.Providers { + val, ok := p.FindIdent(identName) + if ok { + return val, ok + } + } + return nil, false +} + +// FindType finds the Type given a qualified type name, or return false +// if none of the providers finds the type. +// If any of the providers find the type, the first provider that returns true +// will be the result. +func (c *CompositedTypeProvider) FindType(typeName string) (*exprpb.Type, bool) { + for _, p := range c.Providers { + typ, ok := p.FindType(typeName) + if ok { + return typ, ok + } + } + return nil, false +} + +// FindFieldType returns the field type for a checked type value. Returns +// false if none of the providers can find the type. +// If multiple providers can find the field, the result is taken from +// the first that does. +func (c *CompositedTypeProvider) FindFieldType(messageType string, fieldName string) (*ref.FieldType, bool) { + for _, p := range c.Providers { + ft, ok := p.FindFieldType(messageType, fieldName) + if ok { + return ft, ok + } + } + return nil, false +} + +// NewValue creates a new type value from a qualified name and map of field +// name to value. +// If multiple providers can create the new type, the first that returns +// non-nil will decide the result. +func (c *CompositedTypeProvider) NewValue(typeName string, fields map[string]ref.Val) ref.Val { + for _, p := range c.Providers { + v := p.NewValue(typeName, fields) + if v != nil { + return v + } + } + return nil +} + +// CompositedTypeAdapter is the adapter that tries each of the underlying +// type adapter in order until the first successfully conversion. +type CompositedTypeAdapter struct { + // Adapters contains underlying type adapters. + // If Adapters is empty, the CompositedTypeAdapter becomes a no-op adapter. + Adapters []ref.TypeAdapter +} + +// NativeToValue takes the value and convert it into a ref.Val +// The result comes from the first TypeAdapter that returns non-nil. +func (c *CompositedTypeAdapter) NativeToValue(value interface{}) ref.Val { + for _, a := range c.Adapters { + v := a.NativeToValue(value) + if v != nil { + return v + } + } + return nil +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/errors.go b/vendor/k8s.io/apiserver/pkg/cel/errors.go similarity index 100% rename from vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/errors.go rename to vendor/k8s.io/apiserver/pkg/cel/errors.go diff --git a/vendor/k8s.io/apiserver/pkg/cel/escaping.go b/vendor/k8s.io/apiserver/pkg/cel/escaping.go new file mode 100644 index 00000000000..705c353a2b9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/escaping.go @@ -0,0 +1,170 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "regexp" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// celReservedSymbols is a list of RESERVED symbols defined in the CEL lexer. +// No identifiers are allowed to collide with these symbols. +// https://github.com/google/cel-spec/blob/master/doc/langdef.md#syntax +var celReservedSymbols = sets.NewString( + "true", "false", "null", "in", + "as", "break", "const", "continue", "else", + "for", "function", "if", "import", "let", + "loop", "package", "namespace", "return", // !! 'namespace' is used heavily in Kubernetes + "var", "void", "while", +) + +// expandMatcher matches the escape sequence, characters that are escaped, and characters that are unsupported +var expandMatcher = regexp.MustCompile(`(__|[-./]|[^a-zA-Z0-9-./_])`) + +// newCharacterFilter returns a boolean array to indicate the allowed characters +func newCharacterFilter(characters string) []bool { + maxChar := 0 + for _, c := range characters { + if maxChar < int(c) { + maxChar = int(c) + } + } + filter := make([]bool, maxChar+1) + + for _, c := range characters { + filter[int(c)] = true + } + + return filter +} + +type escapeCheck struct { + canSkipRegex bool + invalidCharFound bool +} + +// skipRegexCheck checks if escape would be skipped. +// if invalidCharFound is true, it must have invalid character; if invalidCharFound is false, not sure if it has invalid character or not +func skipRegexCheck(ident string) escapeCheck { + escapeCheck := escapeCheck{canSkipRegex: true, invalidCharFound: false} + // skip escape if possible + previous_underscore := false + for _, c := range ident { + if c == '/' || c == '-' || c == '.' { + escapeCheck.canSkipRegex = false + return escapeCheck + } + intc := int(c) + if intc < 0 || intc >= len(validCharacterFilter) || !validCharacterFilter[intc] { + escapeCheck.invalidCharFound = true + return escapeCheck + } + if c == '_' && previous_underscore { + escapeCheck.canSkipRegex = false + return escapeCheck + } + + previous_underscore = c == '_' + } + return escapeCheck +} + +// validCharacterFilter indicates the allowed characters. +var validCharacterFilter = newCharacterFilter("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") + +// Escape escapes ident and returns a CEL identifier (of the form '[a-zA-Z_][a-zA-Z0-9_]*'), or returns +// false if the ident does not match the supported input format of `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*`. +// Escaping Rules: +// - '__' escapes to '__underscores__' +// - '.' escapes to '__dot__' +// - '-' escapes to '__dash__' +// - '/' escapes to '__slash__' +// - Identifiers that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are: "true", "false", +// "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if", "import", "let", loop", "package", +// "namespace", "return". +func Escape(ident string) (string, bool) { + if len(ident) == 0 || ('0' <= ident[0] && ident[0] <= '9') { + return "", false + } + if celReservedSymbols.Has(ident) { + return "__" + ident + "__", true + } + + escapeCheck := skipRegexCheck(ident) + if escapeCheck.invalidCharFound { + return "", false + } + if escapeCheck.canSkipRegex { + return ident, true + } + + ok := true + ident = expandMatcher.ReplaceAllStringFunc(ident, func(s string) string { + switch s { + case "__": + return "__underscores__" + case ".": + return "__dot__" + case "-": + return "__dash__" + case "/": + return "__slash__" + default: // matched a unsupported supported + ok = false + return "" + } + }) + if !ok { + return "", false + } + return ident, true +} + +var unexpandMatcher = regexp.MustCompile(`(_{2}[^_]+_{2})`) + +// Unescape unescapes an CEL identifier containing the escape sequences described in Escape, or return false if the +// string contains invalid escape sequences. The escaped input is expected to be a valid CEL identifier, but is +// not checked. +func Unescape(escaped string) (string, bool) { + ok := true + escaped = unexpandMatcher.ReplaceAllStringFunc(escaped, func(s string) string { + contents := s[2 : len(s)-2] + switch contents { + case "underscores": + return "__" + case "dot": + return "." + case "dash": + return "-" + case "slash": + return "/" + } + if celReservedSymbols.Has(contents) { + if len(s) != len(escaped) { + ok = false + } + return contents + } + ok = false + return "" + }) + if !ok { + return "", false + } + return escaped, true +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/authz.go b/vendor/k8s.io/apiserver/pkg/cel/library/authz.go new file mode 100644 index 00000000000..606e5769adb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/library/authz.go @@ -0,0 +1,580 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package library + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +// Authz provides a CEL function library extension for performing authorization checks. +// Note that authorization checks are only supported for CEL expression fields in the API +// where an 'authorizer' variable is provided to the CEL expression. See the +// documentation of API fields where CEL expressions are used to learn if the 'authorizer' +// variable is provided. +// +// path +// +// Returns a PathCheck configured to check authorization for a non-resource request +// path (e.g. /healthz). If path is an empty string, an error is returned. +// Note that the leading '/' is not required. +// +// .path() +// +// Examples: +// +// authorizer.path('/healthz') // returns a PathCheck for the '/healthz' API path +// authorizer.path('') // results in "path must not be empty" error +// authorizer.path(' ') // results in "path must not be empty" error +// +// group +// +// Returns a GroupCheck configured to check authorization for the API resources for +// a particular API group. +// Note that authorization checks are only supported for CEL expression fields in the API +// where an 'authorizer' variable is provided to the CEL expression. Check the +// documentation of API fields where CEL expressions are used to learn if the 'authorizer' +// variable is provided. +// +// .group() +// +// Examples: +// +// authorizer.group('apps') // returns a GroupCheck for the 'apps' API group +// authorizer.group('') // returns a GroupCheck for the core API group +// authorizer.group('example.com') // returns a GroupCheck for the custom resources in the 'example.com' API group +// +// serviceAccount +// +// Returns an Authorizer configured to check authorization for the provided service account namespace and name. +// If the name is not a valid DNS subdomain string (as defined by RFC 1123), an error is returned. +// If the namespace is not a valid DNS label (as defined by RFC 1123), an error is returned. +// +// .serviceAccount(, ) +// +// Examples: +// +// authorizer.serviceAccount('default', 'myserviceaccount') // returns an Authorizer for the service account with namespace 'default' and name 'myserviceaccount' +// authorizer.serviceAccount('not@a#valid!namespace', 'validname') // returns an error +// authorizer.serviceAccount('valid.example.com', 'invalid@*name') // returns an error +// +// resource +// +// Returns a ResourceCheck configured to check authorization for a particular API resource. +// Note that the provided resource string should be a lower case plural name of a Kubernetes API resource. +// +// .resource() +// +// Examples: +// +// authorizer.group('apps').resource('deployments') // returns a ResourceCheck for the 'deployments' resources in the 'apps' group. +// authorizer.group('').resource('pods') // returns a ResourceCheck for the 'pods' resources in the core group. +// authorizer.group('apps').resource('') // results in "resource must not be empty" error +// authorizer.group('apps').resource(' ') // results in "resource must not be empty" error +// +// subresource +// +// Returns a ResourceCheck configured to check authorization for a particular subresource of an API resource. +// If subresource is set to "", the subresource field of this ResourceCheck is considered unset. +// +// .subresource() +// +// Examples: +// +// authorizer.group('').resource('pods').subresource('status') // returns a ResourceCheck the 'status' subresource of 'pods' +// authorizer.group('apps').resource('deployments').subresource('scale') // returns a ResourceCheck the 'scale' subresource of 'deployments' +// authorizer.group('example.com').resource('widgets').subresource('scale') // returns a ResourceCheck for the 'scale' subresource of the 'widgets' custom resource +// authorizer.group('example.com').resource('widgets').subresource('') // returns a ResourceCheck for the 'widgets' resource. +// +// namespace +// +// Returns a ResourceCheck configured to check authorization for a particular namespace. +// For cluster scoped resources, namespace() does not need to be called; namespace defaults +// to "", which is the correct namespace value to use to check cluster scoped resources. +// If namespace is set to "", the ResourceCheck will check authorization for the cluster scope. +// +// .namespace() +// +// Examples: +// +// authorizer.group('apps').resource('deployments').namespace('test') // returns a ResourceCheck for 'deployments' in the 'test' namespace +// authorizer.group('').resource('pods').namespace('default') // returns a ResourceCheck for 'pods' in the 'default' namespace +// authorizer.group('').resource('widgets').namespace('') // returns a ResourceCheck for 'widgets' in the cluster scope +// +// name +// +// Returns a ResourceCheck configured to check authorization for a particular resource name. +// If name is set to "", the name field of this ResourceCheck is considered unset. +// +// .name() +// +// Examples: +// +// authorizer.group('apps').resource('deployments').namespace('test').name('backend') // returns a ResourceCheck for the 'backend' 'deployments' resource in the 'test' namespace +// authorizer.group('apps').resource('deployments').namespace('test').name('') // returns a ResourceCheck for the 'deployments' resource in the 'test' namespace +// +// check +// +// For PathCheck, checks if the principal (user or service account) that sent the request is authorized for the HTTP request verb of the path. +// For ResourceCheck, checks if the principal (user or service account) that sent the request is authorized for the API verb and the configured authorization checks of the ResourceCheck. +// The check operation can be expensive, particularly in clusters using the webhook authorization mode. +// +// .check() +// .check() +// +// Examples: +// +// authorizer.group('').resource('pods').namespace('default').check('create') // Checks if the principal (user or service account) is authorized create pods in the 'default' namespace. +// authorizer.path('/healthz').check('get') // Checks if the principal (user or service account) is authorized to make HTTP GET requests to the /healthz API path. +// +// allowed +// +// Returns true if the authorizer's decision for the check is "allow". Note that if the authorizer's decision is +// "no opinion", that the 'allowed' function will return false. +// +// .allowed() +// +// Examples: +// +// authorizer.group('').resource('pods').namespace('default').check('create').allowed() // Returns true if the principal (user or service account) is allowed create pods in the 'default' namespace. +// authorizer.path('/healthz').check('get').allowed() // Returns true if the principal (user or service account) is allowed to make HTTP GET requests to the /healthz API path. +// +// reason +// +// Returns a string reason for the authorization decision +// +// .reason() +// +// Examples: +// +// authorizer.path('/healthz').check('GET').reason() +func Authz() cel.EnvOption { + return cel.Lib(authzLib) +} + +var authzLib = &authz{} + +type authz struct{} + +var authzLibraryDecls = map[string][]cel.FunctionOpt{ + "path": { + cel.MemberOverload("authorizer_path", []*cel.Type{AuthorizerType, cel.StringType}, PathCheckType, + cel.BinaryBinding(authorizerPath))}, + "group": { + cel.MemberOverload("authorizer_group", []*cel.Type{AuthorizerType, cel.StringType}, GroupCheckType, + cel.BinaryBinding(authorizerGroup))}, + "serviceAccount": { + cel.MemberOverload("authorizer_serviceaccount", []*cel.Type{AuthorizerType, cel.StringType, cel.StringType}, AuthorizerType, + cel.FunctionBinding(authorizerServiceAccount))}, + "resource": { + cel.MemberOverload("groupcheck_resource", []*cel.Type{GroupCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(groupCheckResource))}, + "subresource": { + cel.MemberOverload("resourcecheck_subresource", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckSubresource))}, + "namespace": { + cel.MemberOverload("resourcecheck_namespace", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckNamespace))}, + "name": { + cel.MemberOverload("resourcecheck_name", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckName))}, + "check": { + cel.MemberOverload("pathcheck_check", []*cel.Type{PathCheckType, cel.StringType}, DecisionType, + cel.BinaryBinding(pathCheckCheck)), + cel.MemberOverload("resourcecheck_check", []*cel.Type{ResourceCheckType, cel.StringType}, DecisionType, + cel.BinaryBinding(resourceCheckCheck))}, + "allowed": { + cel.MemberOverload("decision_allowed", []*cel.Type{DecisionType}, cel.BoolType, + cel.UnaryBinding(decisionAllowed))}, + "reason": { + cel.MemberOverload("decision_reason", []*cel.Type{DecisionType}, cel.StringType, + cel.UnaryBinding(decisionReason))}, +} + +func (*authz) CompileOptions() []cel.EnvOption { + options := make([]cel.EnvOption, 0, len(authzLibraryDecls)) + for name, overloads := range authzLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*authz) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func authorizerPath(arg1, arg2 ref.Val) ref.Val { + authz, ok := arg1.(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + path, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + if len(strings.TrimSpace(path)) == 0 { + return types.NewErr("path must not be empty") + } + + return authz.pathCheck(path) +} + +func authorizerGroup(arg1, arg2 ref.Val) ref.Val { + authz, ok := arg1.(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + group, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return authz.groupCheck(group) +} + +func authorizerServiceAccount(args ...ref.Val) ref.Val { + argn := len(args) + if argn != 3 { + return types.NoSuchOverloadErr() + } + + authz, ok := args[0].(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(args[0]) + } + + namespace, ok := args[1].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[1]) + } + + name, ok := args[2].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[2]) + } + + if errors := apimachineryvalidation.ValidateServiceAccountName(name, false); len(errors) > 0 { + return types.NewErr("Invalid service account name") + } + if errors := apimachineryvalidation.ValidateNamespaceName(namespace, false); len(errors) > 0 { + return types.NewErr("Invalid service account namespace") + } + return authz.serviceAccount(namespace, name) +} + +func groupCheckResource(arg1, arg2 ref.Val) ref.Val { + groupCheck, ok := arg1.(groupCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + resource, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + if len(strings.TrimSpace(resource)) == 0 { + return types.NewErr("resource must not be empty") + } + return groupCheck.resourceCheck(resource) +} + +func resourceCheckSubresource(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + subresource, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.subresource = subresource + return result +} + +func resourceCheckNamespace(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + namespace, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.namespace = namespace + return result +} + +func resourceCheckName(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + name, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.name = name + return result +} + +func pathCheckCheck(arg1, arg2 ref.Val) ref.Val { + pathCheck, ok := arg1.(pathCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + httpRequestVerb, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return pathCheck.Authorize(context.TODO(), httpRequestVerb) +} + +func resourceCheckCheck(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + apiVerb, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return resourceCheck.Authorize(context.TODO(), apiVerb) +} + +func decisionAllowed(arg ref.Val) ref.Val { + decision, ok := arg.(decisionVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.Bool(decision.authDecision == authorizer.DecisionAllow) +} + +func decisionReason(arg ref.Val) ref.Val { + decision, ok := arg.(decisionVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.String(decision.reason) +} + +var ( + AuthorizerType = cel.ObjectType("kubernetes.authorization.Authorizer") + PathCheckType = cel.ObjectType("kubernetes.authorization.PathCheck") + GroupCheckType = cel.ObjectType("kubernetes.authorization.GroupCheck") + ResourceCheckType = cel.ObjectType("kubernetes.authorization.ResourceCheck") + DecisionType = cel.ObjectType("kubernetes.authorization.Decision") +) + +// Resource represents an API resource +type Resource interface { + // GetName returns the name of the object as presented in the request. On a CREATE operation, the client + // may omit name and rely on the server to generate the name. If that is the case, this method will return + // the empty string + GetName() string + // GetNamespace is the namespace associated with the request (if any) + GetNamespace() string + // GetResource is the name of the resource being requested. This is not the kind. For example: pods + GetResource() schema.GroupVersionResource + // GetSubresource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind. + // For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod" + // (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding". + GetSubresource() string +} + +func NewAuthorizerVal(userInfo user.Info, authorizer authorizer.Authorizer) ref.Val { + return authorizerVal{receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), userInfo: userInfo, authAuthorizer: authorizer} +} + +func NewResourceAuthorizerVal(userInfo user.Info, authorizer authorizer.Authorizer, requestResource Resource) ref.Val { + a := authorizerVal{receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), userInfo: userInfo, authAuthorizer: authorizer} + resource := requestResource.GetResource() + g := a.groupCheck(resource.Group) + r := g.resourceCheck(resource.Resource) + r.subresource = requestResource.GetSubresource() + r.namespace = requestResource.GetNamespace() + r.name = requestResource.GetName() + return r +} + +type authorizerVal struct { + receiverOnlyObjectVal + userInfo user.Info + authAuthorizer authorizer.Authorizer +} + +func (a authorizerVal) pathCheck(path string) pathCheckVal { + return pathCheckVal{receiverOnlyObjectVal: receiverOnlyVal(PathCheckType), authorizer: a, path: path} +} + +func (a authorizerVal) groupCheck(group string) groupCheckVal { + return groupCheckVal{receiverOnlyObjectVal: receiverOnlyVal(GroupCheckType), authorizer: a, group: group} +} + +func (a authorizerVal) serviceAccount(namespace, name string) authorizerVal { + sa := &serviceaccount.ServiceAccountInfo{Name: name, Namespace: namespace} + return authorizerVal{ + receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), + userInfo: sa.UserInfo(), + authAuthorizer: a.authAuthorizer, + } +} + +type pathCheckVal struct { + receiverOnlyObjectVal + authorizer authorizerVal + path string +} + +func (a pathCheckVal) Authorize(ctx context.Context, verb string) ref.Val { + attr := &authorizer.AttributesRecord{ + Path: a.path, + Verb: verb, + User: a.authorizer.userInfo, + } + + decision, reason, err := a.authorizer.authAuthorizer.Authorize(ctx, attr) + if err != nil { + return types.NewErr("error in authorization check: %v", err) + } + return newDecision(decision, reason) +} + +type groupCheckVal struct { + receiverOnlyObjectVal + authorizer authorizerVal + group string +} + +func (g groupCheckVal) resourceCheck(resource string) resourceCheckVal { + return resourceCheckVal{receiverOnlyObjectVal: receiverOnlyVal(ResourceCheckType), groupCheck: g, resource: resource} +} + +type resourceCheckVal struct { + receiverOnlyObjectVal + groupCheck groupCheckVal + resource string + subresource string + namespace string + name string +} + +func (a resourceCheckVal) Authorize(ctx context.Context, verb string) ref.Val { + attr := &authorizer.AttributesRecord{ + ResourceRequest: true, + APIGroup: a.groupCheck.group, + APIVersion: "*", + Resource: a.resource, + Subresource: a.subresource, + Namespace: a.namespace, + Name: a.name, + Verb: verb, + User: a.groupCheck.authorizer.userInfo, + } + decision, reason, err := a.groupCheck.authorizer.authAuthorizer.Authorize(ctx, attr) + if err != nil { + return types.NewErr("error in authorization check: %v", err) + } + return newDecision(decision, reason) +} + +func newDecision(authDecision authorizer.Decision, reason string) decisionVal { + return decisionVal{receiverOnlyObjectVal: receiverOnlyVal(DecisionType), authDecision: authDecision, reason: reason} +} + +type decisionVal struct { + receiverOnlyObjectVal + authDecision authorizer.Decision + reason string +} + +// receiverOnlyObjectVal provides an implementation of ref.Val for +// any object type that has receiver functions but does not expose any fields to +// CEL. +type receiverOnlyObjectVal struct { + typeValue *types.TypeValue +} + +// receiverOnlyVal returns a receiverOnlyObjectVal for the given type. +func receiverOnlyVal(objectType *cel.Type) receiverOnlyObjectVal { + return receiverOnlyObjectVal{typeValue: types.NewTypeValue(objectType.String())} +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (a receiverOnlyObjectVal) ConvertToNative(typeDesc reflect.Type) (any, error) { + return nil, fmt.Errorf("type conversion error from '%s' to '%v'", a.typeValue.String(), typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (a receiverOnlyObjectVal) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case a.typeValue: + return a + case types.TypeType: + return a.typeValue + } + return types.NewErr("type conversion error from '%s' to '%s'", a.typeValue, typeVal) +} + +// Equal implements ref.Val.Equal. +func (a receiverOnlyObjectVal) Equal(other ref.Val) ref.Val { + o, ok := other.(receiverOnlyObjectVal) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + return types.Bool(a == o) +} + +// Type implements ref.Val.Type. +func (a receiverOnlyObjectVal) Type() ref.Type { + return a.typeValue +} + +// Value implements ref.Val.Value. +func (a receiverOnlyObjectVal) Value() any { + return types.NoSuchOverloadErr() +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/cost.go b/vendor/k8s.io/apiserver/pkg/cel/library/cost.go similarity index 91% rename from vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/cost.go rename to vendor/k8s.io/apiserver/pkg/cel/library/cost.go index 39098e3f605..6cc6290323f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/cost.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/cost.go @@ -36,6 +36,15 @@ type CostEstimator struct { func (l *CostEstimator) CallCost(function, overloadId string, args []ref.Val, result ref.Val) *uint64 { switch function { + case "check": + // An authorization check has a fixed cost + // This cost is set to allow for only two authorization checks per expression + cost := uint64(350000) + return &cost + case "serviceAccount", "path", "group", "resource", "subresource", "namespace", "name", "allowed", "denied", "reason": + // All authorization builder and accessor functions have a nominal cost + cost := uint64(1) + return &cost case "isSorted", "sum", "max", "min", "indexOf", "lastIndexOf": var cost uint64 if len(args) > 0 { @@ -78,6 +87,13 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch // WARNING: Any changes to this code impact API compatibility! The estimated cost is used to determine which CEL rules may be written to a // CRD and any change (cost increases and cost decreases) are breaking. switch function { + case "check": + // An authorization check has a fixed cost + // This cost is set to allow for only two authorization checks per expression + return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 350000, Max: 350000}} + case "serviceAccount", "path", "group", "resource", "subresource", "namespace", "name", "allowed", "denied", "reason": + // All authorization builder and accessor functions have a nominal cost + return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: 1}} case "isSorted", "sum", "max", "min", "indexOf", "lastIndexOf": if target != nil { // Charge 1 cost for comparing each element in the list @@ -94,7 +110,6 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch } else { // the target is a string, which is supported by indexOf and lastIndexOf return &checker.CallEstimate{CostEstimate: l.sizeEstimate(*target).MultiplyByCostFactor(common.StringTraversalCostFactor)} } - } case "url": if len(args) == 1 { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/libraries.go b/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go similarity index 99% rename from vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/libraries.go rename to vendor/k8s.io/apiserver/pkg/cel/library/libraries.go index 18f6d7a7c2e..e2e8fc29bd1 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library/libraries.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go @@ -29,6 +29,7 @@ var k8sExtensionLibs = []cel.EnvOption{ URLs(), Regex(), Lists(), + Authz(), } var ExtensionLibRegexOptimizations = []*interpreter.RegexOptimization{FindRegexOptimization, FindAllRegexOptimization} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/lists.go b/vendor/k8s.io/apiserver/pkg/cel/library/lists.go new file mode 100644 index 00000000000..fe51dc87fdb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/library/lists.go @@ -0,0 +1,312 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package library + +import ( + "fmt" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + "github.com/google/cel-go/interpreter/functions" +) + +// Lists provides a CEL function library extension of list utility functions. +// +// isSorted +// +// Returns true if the provided list of comparable elements is sorted, else returns false. +// +// >.isSorted() , T must be a comparable type +// +// Examples: +// +// [1, 2, 3].isSorted() // return true +// ['a', 'b', 'b', 'c'].isSorted() // return true +// [2.0, 1.0].isSorted() // return false +// [1].isSorted() // return true +// [].isSorted() // return true +// +// sum +// +// Returns the sum of the elements of the provided list. Supports CEL number (int, uint, double) and duration types. +// +// >.sum() , T must be a numeric type or a duration +// +// Examples: +// +// [1, 3].sum() // returns 4 +// [1.0, 3.0].sum() // returns 4.0 +// ['1m', '1s'].sum() // returns '1m1s' +// emptyIntList.sum() // returns 0 +// emptyDoubleList.sum() // returns 0.0 +// [].sum() // returns 0 +// +// min / max +// +// Returns the minimum/maximum valued element of the provided list. Supports all comparable types. +// If the list is empty, an error is returned. +// +// >.min() , T must be a comparable type +// >.max() , T must be a comparable type +// +// Examples: +// +// [1, 3].min() // returns 1 +// [1, 3].max() // returns 3 +// [].min() // error +// [1].min() // returns 1 +// ([0] + emptyList).min() // returns 0 +// +// indexOf / lastIndexOf +// +// Returns either the first or last positional index of the provided element in the list. +// If the element is not found, -1 is returned. Supports all equatable types. +// +// >.indexOf() , T must be an equatable type +// >.lastIndexOf() , T must be an equatable type +// +// Examples: +// +// [1, 2, 2, 3].indexOf(2) // returns 1 +// ['a', 'b', 'b', 'c'].lastIndexOf('b') // returns 2 +// [1.0].indexOf(1.1) // returns -1 +// [].indexOf('string') // returns -1 +func Lists() cel.EnvOption { + return cel.Lib(listsLib) +} + +var listsLib = &lists{} + +type lists struct{} + +var paramA = cel.TypeParamType("A") + +// CEL typeParams can be used to constraint to a specific trait (e.g. traits.ComparableType) if the 1st operand is the type to constrain. +// But the functions we need to constrain are >, not just . +// Make sure the order of overload set is deterministic +type namedCELType struct { + typeName string + celType *cel.Type +} + +var summableTypes = []namedCELType{ + {typeName: "int", celType: cel.IntType}, + {typeName: "uint", celType: cel.UintType}, + {typeName: "double", celType: cel.DoubleType}, + {typeName: "duration", celType: cel.DurationType}, +} + +var zeroValuesOfSummableTypes = map[string]ref.Val{ + "int": types.Int(0), + "uint": types.Uint(0), + "double": types.Double(0.0), + "duration": types.Duration{Duration: 0}, +} +var comparableTypes = []namedCELType{ + {typeName: "int", celType: cel.IntType}, + {typeName: "uint", celType: cel.UintType}, + {typeName: "double", celType: cel.DoubleType}, + {typeName: "bool", celType: cel.BoolType}, + {typeName: "duration", celType: cel.DurationType}, + {typeName: "timestamp", celType: cel.TimestampType}, + {typeName: "string", celType: cel.StringType}, + {typeName: "bytes", celType: cel.BytesType}, +} + +// WARNING: All library additions or modifications must follow +// https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2876-crd-validation-expression-language#function-library-updates +var listsLibraryDecls = map[string][]cel.FunctionOpt{ + "isSorted": templatedOverloads(comparableTypes, func(name string, paramType *cel.Type) cel.FunctionOpt { + return cel.MemberOverload(fmt.Sprintf("list_%s_is_sorted_bool", name), + []*cel.Type{cel.ListType(paramType)}, cel.BoolType, cel.UnaryBinding(isSorted)) + }), + "sum": templatedOverloads(summableTypes, func(name string, paramType *cel.Type) cel.FunctionOpt { + return cel.MemberOverload(fmt.Sprintf("list_%s_sum_%s", name, name), + []*cel.Type{cel.ListType(paramType)}, paramType, cel.UnaryBinding(func(list ref.Val) ref.Val { + return sum( + func() ref.Val { + return zeroValuesOfSummableTypes[name] + })(list) + })) + }), + "max": templatedOverloads(comparableTypes, func(name string, paramType *cel.Type) cel.FunctionOpt { + return cel.MemberOverload(fmt.Sprintf("list_%s_max_%s", name, name), + []*cel.Type{cel.ListType(paramType)}, paramType, cel.UnaryBinding(max())) + }), + "min": templatedOverloads(comparableTypes, func(name string, paramType *cel.Type) cel.FunctionOpt { + return cel.MemberOverload(fmt.Sprintf("list_%s_min_%s", name, name), + []*cel.Type{cel.ListType(paramType)}, paramType, cel.UnaryBinding(min())) + }), + "indexOf": { + cel.MemberOverload("list_a_index_of_int", []*cel.Type{cel.ListType(paramA), paramA}, cel.IntType, + cel.BinaryBinding(indexOf)), + }, + "lastIndexOf": { + cel.MemberOverload("list_a_last_index_of_int", []*cel.Type{cel.ListType(paramA), paramA}, cel.IntType, + cel.BinaryBinding(lastIndexOf)), + }, +} + +func (*lists) CompileOptions() []cel.EnvOption { + options := []cel.EnvOption{} + for name, overloads := range listsLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*lists) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func isSorted(val ref.Val) ref.Val { + var prev traits.Comparer + iterable, ok := val.(traits.Iterable) + if !ok { + return types.MaybeNoSuchOverloadErr(val) + } + for it := iterable.Iterator(); it.HasNext() == types.True; { + next := it.Next() + nextCmp, ok := next.(traits.Comparer) + if !ok { + return types.MaybeNoSuchOverloadErr(next) + } + if prev != nil { + cmp := prev.Compare(next) + if cmp == types.IntOne { + return types.False + } + } + prev = nextCmp + } + return types.True +} + +func sum(init func() ref.Val) functions.UnaryOp { + return func(val ref.Val) ref.Val { + i := init() + acc, ok := i.(traits.Adder) + if !ok { + // Should never happen since all passed in init values are valid + return types.MaybeNoSuchOverloadErr(i) + } + iterable, ok := val.(traits.Iterable) + if !ok { + return types.MaybeNoSuchOverloadErr(val) + } + for it := iterable.Iterator(); it.HasNext() == types.True; { + next := it.Next() + nextAdder, ok := next.(traits.Adder) + if !ok { + // Should never happen for type checked CEL programs + return types.MaybeNoSuchOverloadErr(next) + } + if acc != nil { + s := acc.Add(next) + sum, ok := s.(traits.Adder) + if !ok { + // Should never happen for type checked CEL programs + return types.MaybeNoSuchOverloadErr(s) + } + acc = sum + } else { + acc = nextAdder + } + } + return acc.(ref.Val) + } +} + +func min() functions.UnaryOp { + return cmp("min", types.IntOne) +} + +func max() functions.UnaryOp { + return cmp("max", types.IntNegOne) +} + +func cmp(opName string, opPreferCmpResult ref.Val) functions.UnaryOp { + return func(val ref.Val) ref.Val { + var result traits.Comparer + iterable, ok := val.(traits.Iterable) + if !ok { + return types.MaybeNoSuchOverloadErr(val) + } + for it := iterable.Iterator(); it.HasNext() == types.True; { + next := it.Next() + nextCmp, ok := next.(traits.Comparer) + if !ok { + // Should never happen for type checked CEL programs + return types.MaybeNoSuchOverloadErr(next) + } + if result == nil { + result = nextCmp + } else { + cmp := result.Compare(next) + if cmp == opPreferCmpResult { + result = nextCmp + } + } + } + if result == nil { + return types.NewErr("%s called on empty list", opName) + } + return result.(ref.Val) + } +} + +func indexOf(list ref.Val, item ref.Val) ref.Val { + lister, ok := list.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(list) + } + sz := lister.Size().(types.Int) + for i := types.Int(0); i < sz; i++ { + if lister.Get(types.Int(i)).Equal(item) == types.True { + return types.Int(i) + } + } + return types.Int(-1) +} + +func lastIndexOf(list ref.Val, item ref.Val) ref.Val { + lister, ok := list.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(list) + } + sz := lister.Size().(types.Int) + for i := sz - 1; i >= 0; i-- { + if lister.Get(types.Int(i)).Equal(item) == types.True { + return types.Int(i) + } + } + return types.Int(-1) +} + +// templatedOverloads returns overloads for each of the provided types. The template function is called with each type +// name (map key) and type to construct the overloads. +func templatedOverloads(types []namedCELType, template func(name string, t *cel.Type) cel.FunctionOpt) []cel.FunctionOpt { + overloads := make([]cel.FunctionOpt, len(types)) + i := 0 + for _, t := range types { + overloads[i] = template(t.typeName, t.celType) + i++ + } + return overloads +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/regex.go b/vendor/k8s.io/apiserver/pkg/cel/library/regex.go new file mode 100644 index 00000000000..6db5ef19575 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/library/regex.go @@ -0,0 +1,187 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package library + +import ( + "regexp" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/interpreter" +) + +// Regex provides a CEL function library extension of regex utility functions. +// +// find / findAll +// +// Returns substrings that match the provided regular expression. find returns the first match. findAll may optionally +// be provided a limit. If the limit is set and >= 0, no more than the limit number of matches are returned. +// +// .find() +// .findAll() > +// .findAll(, ) > +// +// Examples: +// +// "abc 123".find('[0-9]*') // returns '123' +// "abc 123".find('xyz') // returns '' +// "123 abc 456".findAll('[0-9]*') // returns ['123', '456'] +// "123 abc 456".findAll('[0-9]*', 1) // returns ['123'] +// "123 abc 456".findAll('xyz') // returns [] +func Regex() cel.EnvOption { + return cel.Lib(regexLib) +} + +var regexLib = ®ex{} + +type regex struct{} + +var regexLibraryDecls = map[string][]cel.FunctionOpt{ + "find": { + cel.MemberOverload("string_find_string", []*cel.Type{cel.StringType, cel.StringType}, cel.StringType, + cel.BinaryBinding(find))}, + "findAll": { + cel.MemberOverload("string_find_all_string", []*cel.Type{cel.StringType, cel.StringType}, + cel.ListType(cel.StringType), + cel.BinaryBinding(func(str, regex ref.Val) ref.Val { + return findAll(str, regex, types.Int(-1)) + })), + cel.MemberOverload("string_find_all_string_int", + []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, + cel.ListType(cel.StringType), + cel.FunctionBinding(findAll)), + }, +} + +func (*regex) CompileOptions() []cel.EnvOption { + options := []cel.EnvOption{} + for name, overloads := range regexLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*regex) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func find(strVal ref.Val, regexVal ref.Val) ref.Val { + str, ok := strVal.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(strVal) + } + regex, ok := regexVal.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(regexVal) + } + re, err := regexp.Compile(regex) + if err != nil { + return types.NewErr("Illegal regex: %v", err.Error()) + } + result := re.FindString(str) + return types.String(result) +} + +func findAll(args ...ref.Val) ref.Val { + argn := len(args) + if argn < 2 || argn > 3 { + return types.NoSuchOverloadErr() + } + str, ok := args[0].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[0]) + } + regex, ok := args[1].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[1]) + } + n := int64(-1) + if argn == 3 { + n, ok = args[2].Value().(int64) + if !ok { + return types.MaybeNoSuchOverloadErr(args[2]) + } + } + + re, err := regexp.Compile(regex) + if err != nil { + return types.NewErr("Illegal regex: %v", err.Error()) + } + + result := re.FindAllString(str, int(n)) + + return types.NewStringList(types.DefaultTypeAdapter, result) +} + +// FindRegexOptimization optimizes the 'find' function by compiling the regex pattern and +// reporting any compilation errors at program creation time, and using the compiled regex pattern for all function +// call invocations. +var FindRegexOptimization = &interpreter.RegexOptimization{ + Function: "find", + RegexIndex: 1, + Factory: func(call interpreter.InterpretableCall, regexPattern string) (interpreter.InterpretableCall, error) { + compiledRegex, err := regexp.Compile(regexPattern) + if err != nil { + return nil, err + } + return interpreter.NewCall(call.ID(), call.Function(), call.OverloadID(), call.Args(), func(args ...ref.Val) ref.Val { + if len(args) != 2 { + return types.NoSuchOverloadErr() + } + in, ok := args[0].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[0]) + } + return types.String(compiledRegex.FindString(in)) + }), nil + }, +} + +// FindAllRegexOptimization optimizes the 'findAll' function by compiling the regex pattern and +// reporting any compilation errors at program creation time, and using the compiled regex pattern for all function +// call invocations. +var FindAllRegexOptimization = &interpreter.RegexOptimization{ + Function: "findAll", + RegexIndex: 1, + Factory: func(call interpreter.InterpretableCall, regexPattern string) (interpreter.InterpretableCall, error) { + compiledRegex, err := regexp.Compile(regexPattern) + if err != nil { + return nil, err + } + return interpreter.NewCall(call.ID(), call.Function(), call.OverloadID(), call.Args(), func(args ...ref.Val) ref.Val { + argn := len(args) + if argn < 2 || argn > 3 { + return types.NoSuchOverloadErr() + } + str, ok := args[0].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[0]) + } + n := int64(-1) + if argn == 3 { + n, ok = args[2].Value().(int64) + if !ok { + return types.MaybeNoSuchOverloadErr(args[2]) + } + } + + result := compiledRegex.FindAllString(str, int(n)) + return types.NewStringList(types.DefaultTypeAdapter, result) + }), nil + }, +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/urls.go b/vendor/k8s.io/apiserver/pkg/cel/library/urls.go new file mode 100644 index 00000000000..7be054ece37 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/library/urls.go @@ -0,0 +1,236 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package library + +import ( + "net/url" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + apiservercel "k8s.io/apiserver/pkg/cel" +) + +// URLs provides a CEL function library extension of URL parsing functions. +// +// url +// +// Converts a string to a URL or results in an error if the string is not a valid URL. The URL must be an absolute URI +// or an absolute path. +// +// url() +// +// Examples: +// +// url('https://user:pass@example.com:80/path?query=val#fragment') // returns a URL +// url('/absolute-path') // returns a URL +// url('https://a:b:c/') // error +// url('../relative-path') // error +// +// isURL +// +// Returns true if a string is a valid URL. The URL must be an absolute URI or an absolute path. +// +// isURL( ) +// +// Examples: +// +// isURL('https://user:pass@example.com:80/path?query=val#fragment') // returns true +// isURL('/absolute-path') // returns true +// isURL('https://a:b:c/') // returns false +// isURL('../relative-path') // returns false +// +// getScheme / getHost / getHostname / getPort / getEscapedPath / getQuery +// +// Return the parsed components of a URL. +// +// - getScheme: If absent in the URL, returns an empty string. +// +// - getHostname: IPv6 addresses are returned without braces, e.g. "::1". If absent in the URL, returns an empty string. +// +// - getHost: IPv6 addresses are returned with braces, e.g. "[::1]". If absent in the URL, returns an empty string. +// +// - getEscapedPath: The string returned by getEscapedPath is URL escaped, e.g. "with space" becomes "with%20space". +// If absent in the URL, returns an empty string. +// +// - getPort: If absent in the URL, returns an empty string. +// +// - getQuery: Returns the query parameters in "matrix" form where a repeated query key is interpreted to +// mean that there are multiple values for that key. The keys and values are returned unescaped. +// If absent in the URL, returns an empty map. +// +// .getScheme() +// .getHost() +// .getHostname() +// .getPort() +// .getEscapedPath() +// .getQuery() , > +// +// Examples: +// +// url('/path').getScheme() // returns '' +// url('https://example.com/').getScheme() // returns 'https' +// url('https://example.com:80/').getHost() // returns 'example.com:80' +// url('https://example.com/').getHost() // returns 'example.com' +// url('https://[::1]:80/').getHost() // returns '[::1]:80' +// url('https://[::1]/').getHost() // returns '[::1]' +// url('/path').getHost() // returns '' +// url('https://example.com:80/').getHostname() // returns 'example.com' +// url('https://127.0.0.1:80/').getHostname() // returns '127.0.0.1' +// url('https://[::1]:80/').getHostname() // returns '::1' +// url('/path').getHostname() // returns '' +// url('https://example.com:80/').getPort() // returns '80' +// url('https://example.com/').getPort() // returns '' +// url('/path').getPort() // returns '' +// url('https://example.com/path').getEscapedPath() // returns '/path' +// url('https://example.com/path with spaces/').getEscapedPath() // returns '/path%20with%20spaces/' +// url('https://example.com').getEscapedPath() // returns '' +// url('https://example.com/path?k1=a&k2=b&k2=c').getQuery() // returns { 'k1': ['a'], 'k2': ['b', 'c']} +// url('https://example.com/path?key with spaces=value with spaces').getQuery() // returns { 'key with spaces': ['value with spaces']} +// url('https://example.com/path?').getQuery() // returns {} +// url('https://example.com/path').getQuery() // returns {} +func URLs() cel.EnvOption { + return cel.Lib(urlsLib) +} + +var urlsLib = &urls{} + +type urls struct{} + +var urlLibraryDecls = map[string][]cel.FunctionOpt{ + "url": { + cel.Overload("string_to_url", []*cel.Type{cel.StringType}, apiservercel.URLType, + cel.UnaryBinding(stringToUrl))}, + "getScheme": { + cel.MemberOverload("url_get_scheme", []*cel.Type{apiservercel.URLType}, cel.StringType, + cel.UnaryBinding(getScheme))}, + "getHost": { + cel.MemberOverload("url_get_host", []*cel.Type{apiservercel.URLType}, cel.StringType, + cel.UnaryBinding(getHost))}, + "getHostname": { + cel.MemberOverload("url_get_hostname", []*cel.Type{apiservercel.URLType}, cel.StringType, + cel.UnaryBinding(getHostname))}, + "getPort": { + cel.MemberOverload("url_get_port", []*cel.Type{apiservercel.URLType}, cel.StringType, + cel.UnaryBinding(getPort))}, + "getEscapedPath": { + cel.MemberOverload("url_get_escaped_path", []*cel.Type{apiservercel.URLType}, cel.StringType, + cel.UnaryBinding(getEscapedPath))}, + "getQuery": { + cel.MemberOverload("url_get_query", []*cel.Type{apiservercel.URLType}, + cel.MapType(cel.StringType, cel.ListType(cel.StringType)), + cel.UnaryBinding(getQuery))}, + "isURL": { + cel.Overload("is_url_string", []*cel.Type{cel.StringType}, cel.BoolType, + cel.UnaryBinding(isURL))}, +} + +func (*urls) CompileOptions() []cel.EnvOption { + options := []cel.EnvOption{} + for name, overloads := range urlLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*urls) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func stringToUrl(arg ref.Val) ref.Val { + s, ok := arg.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + // Use ParseRequestURI to check the URL before conversion. + // ParseRequestURI requires absolute URLs and is used by the OpenAPIv3 'uri' format. + _, err := url.ParseRequestURI(s) + if err != nil { + return types.NewErr("URL parse error during conversion from string: %v", err) + } + // We must parse again with Parse since ParseRequestURI incorrectly parses URLs that contain a fragment + // part and will incorrectly append the fragment to either the path or the query, depending on which it was adjacent to. + u, err := url.Parse(s) + if err != nil { + // Errors are not expected here since Parse is a more lenient parser than ParseRequestURI. + return types.NewErr("URL parse error during conversion from string: %v", err) + } + return apiservercel.URL{URL: u} +} + +func getScheme(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.String(u.Scheme) +} + +func getHost(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.String(u.Host) +} + +func getHostname(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.String(u.Hostname()) +} + +func getPort(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.String(u.Port()) +} + +func getEscapedPath(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + return types.String(u.EscapedPath()) +} + +func getQuery(arg ref.Val) ref.Val { + u, ok := arg.Value().(*url.URL) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + result := map[ref.Val]ref.Val{} + for k, v := range u.Query() { + result[types.String(k)] = types.NewStringList(types.DefaultTypeAdapter, v) + } + return types.NewRefValMap(types.DefaultTypeAdapter, result) +} + +func isURL(arg ref.Val) ref.Val { + s, ok := arg.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + _, err := url.ParseRequestURI(s) + return types.Bool(err == nil) +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/limits.go b/vendor/k8s.io/apiserver/pkg/cel/limits.go new file mode 100644 index 00000000000..65c6ad5f3a3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/limits.go @@ -0,0 +1,50 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import celconfig "k8s.io/apiserver/pkg/apis/cel" + +const ( + // DefaultMaxRequestSizeBytes is the size of the largest request that will be accepted + DefaultMaxRequestSizeBytes = celconfig.MaxRequestSizeBytes + + // MaxDurationSizeJSON + // OpenAPI duration strings follow RFC 3339, section 5.6 - see the comment on maxDatetimeSizeJSON + MaxDurationSizeJSON = 32 + // MaxDatetimeSizeJSON + // OpenAPI datetime strings follow RFC 3339, section 5.6, and the longest possible + // such string is 9999-12-31T23:59:59.999999999Z, which has length 30 - we add 2 + // to allow for quotation marks + MaxDatetimeSizeJSON = 32 + // MinDurationSizeJSON + // Golang allows a string of 0 to be parsed as a duration, so that plus 2 to account for + // quotation marks makes 3 + MinDurationSizeJSON = 3 + // JSONDateSize is the size of a date serialized as part of a JSON object + // RFC 3339 dates require YYYY-MM-DD, and then we add 2 to allow for quotation marks + JSONDateSize = 12 + // MinDatetimeSizeJSON is the minimal length of a datetime formatted as RFC 3339 + // RFC 3339 datetimes require a full date (YYYY-MM-DD) and full time (HH:MM:SS), and we add 3 for + // quotation marks like always in addition to the capital T that separates the date and time + MinDatetimeSizeJSON = 21 + // MinStringSize is the size of literal "" + MinStringSize = 2 + // MinBoolSize is the length of literal true + MinBoolSize = 4 + // MinNumberSize is the length of literal 0 + MinNumberSize = 1 +) diff --git a/vendor/k8s.io/apiserver/pkg/cel/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/cel/metrics/metrics.go new file mode 100644 index 00000000000..66b7dd8cfb0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/metrics/metrics.go @@ -0,0 +1,74 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "time" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +// TODO(jiahuif) CEL is to be used in multiple components, revise naming when that happens. +const ( + namespace = "apiserver" + subsystem = "cel" +) + +// Metrics provides access to CEL metrics. +var Metrics = newCelMetrics() + +type CelMetrics struct { + compilationTime *metrics.Histogram + evaluationTime *metrics.Histogram +} + +func newCelMetrics() *CelMetrics { + m := &CelMetrics{ + compilationTime: metrics.NewHistogram(&metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "compilation_duration_seconds", + Help: "CEL compilation time in seconds.", + StabilityLevel: metrics.ALPHA, + }), + evaluationTime: metrics.NewHistogram(&metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "evaluation_duration_seconds", + Help: "CEL evaluation time in seconds.", + StabilityLevel: metrics.ALPHA, + }), + } + + legacyregistry.MustRegister(m.compilationTime) + legacyregistry.MustRegister(m.evaluationTime) + + return m +} + +// ObserveCompilation records a CEL compilation with the time the compilation took. +func (m *CelMetrics) ObserveCompilation(elapsed time.Duration) { + seconds := elapsed.Seconds() + m.compilationTime.Observe(seconds) +} + +// ObserveEvaluation records a CEL evaluation with the time the evaluation took. +func (m *CelMetrics) ObserveEvaluation(elapsed time.Duration) { + seconds := elapsed.Seconds() + m.evaluationTime.Observe(seconds) +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go new file mode 100644 index 00000000000..0e2cc6e2b2e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go @@ -0,0 +1,147 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package openapi + +import ( + "github.com/google/cel-go/common/types/ref" + + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +var _ common.Schema = (*Schema)(nil) +var _ common.SchemaOrBool = (*SchemaOrBool)(nil) + +type Schema struct { + Schema *spec.Schema +} + +type SchemaOrBool struct { + SchemaOrBool *spec.SchemaOrBool +} + +func (sb *SchemaOrBool) Schema() common.Schema { + return &Schema{Schema: sb.SchemaOrBool.Schema} +} + +func (sb *SchemaOrBool) Allows() bool { + return sb.SchemaOrBool.Allows +} + +func (s *Schema) Type() string { + if len(s.Schema.Type) == 0 { + return "" + } + return s.Schema.Type[0] +} + +func (s *Schema) Format() string { + return s.Schema.Format +} + +func (s *Schema) Items() common.Schema { + if s.Schema.Items == nil || s.Schema.Items.Schema == nil { + return nil + } + return &Schema{Schema: s.Schema.Items.Schema} +} + +func (s *Schema) Properties() map[string]common.Schema { + if s.Schema.Properties == nil { + return nil + } + res := make(map[string]common.Schema, len(s.Schema.Properties)) + for n, prop := range s.Schema.Properties { + // map value is unaddressable, create a shallow copy + // this is a shallow non-recursive copy + s := prop + res[n] = &Schema{Schema: &s} + } + return res +} + +func (s *Schema) AdditionalProperties() common.SchemaOrBool { + if s.Schema.AdditionalProperties == nil { + return nil + } + return &SchemaOrBool{SchemaOrBool: s.Schema.AdditionalProperties} +} + +func (s *Schema) Default() any { + return s.Schema.Default +} + +func (s *Schema) MaxItems() *int64 { + return s.Schema.MaxItems +} + +func (s *Schema) MaxLength() *int64 { + return s.Schema.MaxLength +} + +func (s *Schema) MaxProperties() *int64 { + return s.Schema.MaxProperties +} + +func (s *Schema) Required() []string { + return s.Schema.Required +} + +func (s *Schema) Enum() []any { + return s.Schema.Enum +} + +func (s *Schema) Nullable() bool { + return s.Schema.Nullable +} + +func (s *Schema) IsXIntOrString() bool { + return isXIntOrString(s.Schema) +} + +func (s *Schema) IsXEmbeddedResource() bool { + return isXEmbeddedResource(s.Schema) +} + +func (s *Schema) IsXPreserveUnknownFields() bool { + return isXPreserveUnknownFields(s.Schema) +} + +func (s *Schema) XListType() string { + return getXListType(s.Schema) +} + +func (s *Schema) XListMapKeys() []string { + return getXListMapKeys(s.Schema) +} + +func (s *Schema) WithTypeAndObjectMeta() common.Schema { + return &Schema{common.WithTypeAndObjectMeta(s.Schema)} +} + +func UnstructuredToVal(unstructured any, schema *spec.Schema) ref.Val { + return common.UnstructuredToVal(unstructured, &Schema{schema}) +} + +func SchemaDeclType(s *spec.Schema, isResourceRoot bool) *apiservercel.DeclType { + return common.SchemaDeclType(&Schema{Schema: s}, isResourceRoot) +} + +func MakeMapList(sts *spec.Schema, items []interface{}) (rv common.MapList) { + return common.MakeMapList(&Schema{Schema: sts}, items) +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go new file mode 100644 index 00000000000..6a2f830320b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package openapi + +import ( + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +var intOrStringFormat = intstr.IntOrString{}.OpenAPISchemaFormat() + +func isExtension(schema *spec.Schema, key string) bool { + v, ok := schema.Extensions.GetBool(key) + return v && ok +} + +func isXIntOrString(schema *spec.Schema) bool { + // built-in types have the Format while CRDs use extension + // both are valid, checking both + return schema.Format == intOrStringFormat || isExtension(schema, extIntOrString) +} + +func isXEmbeddedResource(schema *spec.Schema) bool { + return isExtension(schema, extEmbeddedResource) +} + +func isXPreserveUnknownFields(schema *spec.Schema) bool { + return isExtension(schema, extPreserveUnknownFields) +} + +func getXListType(schema *spec.Schema) string { + s, _ := schema.Extensions.GetString(extListType) + return s +} + +func getXListMapKeys(schema *spec.Schema) []string { + mapKeys, ok := schema.Extensions.GetStringSlice(extListMapKeys) + if !ok { + return nil + } + return mapKeys +} + +const extIntOrString = "x-kubernetes-int-or-string" +const extEmbeddedResource = "x-kubernetes-embedded-resource" +const extPreserveUnknownFields = "x-kubernetes-preserve-unknown-fields" +const extListType = "x-kubernetes-list-type" +const extListMapKeys = "x-kubernetes-list-map-keys" diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go new file mode 100644 index 00000000000..df7357f7785 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go @@ -0,0 +1,115 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolver + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/openapi" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// DefinitionsSchemaResolver resolves the schema of a built-in type +// by looking up the OpenAPI definitions. +type DefinitionsSchemaResolver struct { + defs map[string]common.OpenAPIDefinition + gvkToSchema map[schema.GroupVersionKind]*spec.Schema +} + +// NewDefinitionsSchemaResolver creates a new DefinitionsSchemaResolver. +// An example working setup: +// scheme = "k8s.io/client-go/kubernetes/scheme".Scheme +// getDefinitions = "k8s.io/kubernetes/pkg/generated/openapi".GetOpenAPIDefinitions +func NewDefinitionsSchemaResolver(scheme *runtime.Scheme, getDefinitions common.GetOpenAPIDefinitions) *DefinitionsSchemaResolver { + gvkToSchema := make(map[schema.GroupVersionKind]*spec.Schema) + namer := openapi.NewDefinitionNamer(scheme) + defs := getDefinitions(func(path string) spec.Ref { + return spec.MustCreateRef(path) + }) + for name, def := range defs { + _, e := namer.GetDefinitionName(name) + gvks := extensionsToGVKs(e) + s := def.Schema // map value not addressable, make copy + for _, gvk := range gvks { + gvkToSchema[gvk] = &s + } + } + return &DefinitionsSchemaResolver{ + gvkToSchema: gvkToSchema, + defs: defs, + } +} + +func (d *DefinitionsSchemaResolver) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) { + s, ok := d.gvkToSchema[gvk] + if !ok { + return nil, fmt.Errorf("cannot resolve %v: %w", gvk, ErrSchemaNotFound) + } + s, err := populateRefs(func(ref string) (*spec.Schema, bool) { + // find the schema by the ref string, and return a deep copy + def, ok := d.defs[ref] + if !ok { + return nil, false + } + s := def.Schema + return &s, true + }, s) + if err != nil { + return nil, err + } + return s, nil +} + +func extensionsToGVKs(extensions spec.Extensions) []schema.GroupVersionKind { + gvksAny, ok := extensions[extGVK] + if !ok { + return nil + } + gvks, ok := gvksAny.([]any) + if !ok { + return nil + } + result := make([]schema.GroupVersionKind, 0, len(gvks)) + for _, gvkAny := range gvks { + // type check the map and all fields + gvkMap, ok := gvkAny.(map[string]any) + if !ok { + return nil + } + g, ok := gvkMap["group"].(string) + if !ok { + return nil + } + v, ok := gvkMap["version"].(string) + if !ok { + return nil + } + k, ok := gvkMap["kind"].(string) + if !ok { + return nil + } + result = append(result, schema.GroupVersionKind{ + Group: g, + Version: v, + Kind: k, + }) + } + return result +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go new file mode 100644 index 00000000000..53cbc7054b3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go @@ -0,0 +1,104 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolver + +import ( + "encoding/json" + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// ClientDiscoveryResolver uses client-go discovery to resolve schemas at run time. +type ClientDiscoveryResolver struct { + Discovery discovery.DiscoveryInterface +} + +var _ SchemaResolver = (*ClientDiscoveryResolver)(nil) + +func (r *ClientDiscoveryResolver) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) { + p, err := r.Discovery.OpenAPIV3().Paths() + if err != nil { + return nil, err + } + resourcePath := resourcePathFromGV(gvk.GroupVersion()) + c, ok := p[resourcePath] + if !ok { + return nil, fmt.Errorf("cannot resolve group version %q: %w", gvk.GroupVersion(), ErrSchemaNotFound) + } + b, err := c.Schema(runtime.ContentTypeJSON) + if err != nil { + return nil, err + } + resp := new(schemaResponse) + err = json.Unmarshal(b, resp) + if err != nil { + return nil, err + } + s, err := resolveType(resp, gvk) + if err != nil { + return nil, err + } + s, err = populateRefs(func(ref string) (*spec.Schema, bool) { + s, ok := resp.Components.Schemas[strings.TrimPrefix(ref, refPrefix)] + return s, ok + }, s) + if err != nil { + return nil, err + } + return s, nil +} + +func resolveType(resp *schemaResponse, gvk schema.GroupVersionKind) (*spec.Schema, error) { + for _, s := range resp.Components.Schemas { + var gvks []schema.GroupVersionKind + err := s.Extensions.GetObject(extGVK, &gvks) + if err != nil { + return nil, err + } + for _, g := range gvks { + if g == gvk { + return s, nil + } + } + } + return nil, fmt.Errorf("cannot resolve group version kind %q: %w", gvk, ErrSchemaNotFound) +} + +func resourcePathFromGV(gv schema.GroupVersion) string { + var resourcePath string + if len(gv.Group) == 0 { + resourcePath = fmt.Sprintf("api/%s", gv.Version) + } else { + resourcePath = fmt.Sprintf("apis/%s/%s", gv.Group, gv.Version) + } + return resourcePath +} + +type schemaResponse struct { + Components struct { + Schemas map[string]*spec.Schema `json:"schemas"` + } `json:"components"` +} + +const refPrefix = "#/components/schemas/" + +const extGVK = "x-kubernetes-group-version-kind" diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go new file mode 100644 index 00000000000..49321bab47d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go @@ -0,0 +1,100 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolver + +import ( + "fmt" + + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// populateRefs recursively replaces Refs in the schema with the referred one. +// schemaOf is the callback to find the corresponding schema by the ref. +// This function will not mutate the original schema. If the schema needs to be +// mutated, a copy will be returned, otherwise it returns the original schema. +func populateRefs(schemaOf func(ref string) (*spec.Schema, bool), schema *spec.Schema) (*spec.Schema, error) { + result := *schema + changed := false + + ref, isRef := refOf(schema) + if isRef { + // replace the whole schema with the referred one. + resolved, ok := schemaOf(ref) + if !ok { + return nil, fmt.Errorf("internal error: cannot resolve Ref %q: %w", ref, ErrSchemaNotFound) + } + result = *resolved + changed = true + } + // schema is an object, populate its properties and additionalProperties + props := make(map[string]spec.Schema, len(schema.Properties)) + propsChanged := false + for name, prop := range result.Properties { + populated, err := populateRefs(schemaOf, &prop) + if err != nil { + return nil, err + } + if populated != &prop { + propsChanged = true + } + props[name] = *populated + } + if propsChanged { + changed = true + result.Properties = props + } + if result.AdditionalProperties != nil && result.AdditionalProperties.Schema != nil { + populated, err := populateRefs(schemaOf, result.AdditionalProperties.Schema) + if err != nil { + return nil, err + } + if populated != result.AdditionalProperties.Schema { + changed = true + result.AdditionalProperties.Schema = populated + } + } + // schema is a list, populate its items + if result.Items != nil && result.Items.Schema != nil { + populated, err := populateRefs(schemaOf, result.Items.Schema) + if err != nil { + return nil, err + } + if populated != result.Items.Schema { + changed = true + result.Items.Schema = populated + } + } + if changed { + return &result, nil + } + return schema, nil +} + +func refOf(schema *spec.Schema) (string, bool) { + if schema.Ref.GetURL() != nil { + return schema.Ref.String(), true + } + // A Ref may be wrapped in allOf to preserve its description + // see https://github.com/kubernetes/kubernetes/issues/106387 + // For kube-openapi, allOf is only used for wrapping a Ref. + for _, allOf := range schema.AllOf { + if ref, isRef := refOf(&allOf); isRef { + return ref, isRef + } + } + return "", false +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go new file mode 100644 index 00000000000..4060c86cefc --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go @@ -0,0 +1,39 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolver + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// SchemaResolver finds the OpenAPI schema for the given GroupVersionKind. +// This interface uses the type defined by k8s.io/kube-openapi +type SchemaResolver interface { + // ResolveSchema takes a GroupVersionKind (GVK) and returns the OpenAPI schema + // identified by the GVK. + // The function returns a non-nil error if the schema cannot be found or fail + // to resolve. The returned error wraps ErrSchemaNotFound if the resolution is + // attempted but the corresponding schema cannot be found. + ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) +} + +// ErrSchemaNotFound is wrapped and returned if the schema cannot be located +// by the resolver. +var ErrSchemaNotFound = fmt.Errorf("schema not found") diff --git a/vendor/k8s.io/apiserver/pkg/cel/registry.go b/vendor/k8s.io/apiserver/pkg/cel/registry.go new file mode 100644 index 00000000000..1aee3a127d6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/registry.go @@ -0,0 +1,79 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "sync" + + "github.com/google/cel-go/cel" +) + +// Resolver declares methods to find policy templates and related configuration objects. +type Resolver interface { + // FindType returns a DeclType instance corresponding to the given fully-qualified name, if + // present. + FindType(name string) (*DeclType, bool) +} + +// NewRegistry create a registry for keeping track of environments and types +// from a base cel.Env expression environment. +func NewRegistry(stdExprEnv *cel.Env) *Registry { + return &Registry{ + exprEnvs: map[string]*cel.Env{"": stdExprEnv}, + types: map[string]*DeclType{ + BoolType.TypeName(): BoolType, + BytesType.TypeName(): BytesType, + DoubleType.TypeName(): DoubleType, + DurationType.TypeName(): DurationType, + IntType.TypeName(): IntType, + NullType.TypeName(): NullType, + StringType.TypeName(): StringType, + TimestampType.TypeName(): TimestampType, + UintType.TypeName(): UintType, + ListType.TypeName(): ListType, + MapType.TypeName(): MapType, + }, + } +} + +// Registry defines a repository of environment, schema, template, and type definitions. +// +// Registry instances are concurrency-safe. +type Registry struct { + rwMux sync.RWMutex + exprEnvs map[string]*cel.Env + types map[string]*DeclType +} + +// FindType implements the Resolver interface method. +func (r *Registry) FindType(name string) (*DeclType, bool) { + r.rwMux.RLock() + defer r.rwMux.RUnlock() + typ, found := r.types[name] + if found { + return typ, true + } + return typ, found +} + +// SetType registers a DeclType descriptor by its fully qualified name. +func (r *Registry) SetType(name string, declType *DeclType) error { + r.rwMux.Lock() + defer r.rwMux.Unlock() + r.types[name] = declType + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/types.go b/vendor/k8s.io/apiserver/pkg/cel/types.go new file mode 100644 index 00000000000..b2cc92d59eb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/types.go @@ -0,0 +1,565 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "fmt" + "math" + "time" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" + "google.golang.org/protobuf/proto" +) + +const ( + noMaxLength = math.MaxInt +) + +// NewListType returns a parameterized list type with a specified element type. +func NewListType(elem *DeclType, maxItems int64) *DeclType { + return &DeclType{ + name: "list", + ElemType: elem, + MaxElements: maxItems, + celType: cel.ListType(elem.CelType()), + defaultValue: NewListValue(), + // a list can always be represented as [] in JSON, so hardcode the min size + // to 2 + MinSerializedSize: 2, + } +} + +// NewMapType returns a parameterized map type with the given key and element types. +func NewMapType(key, elem *DeclType, maxProperties int64) *DeclType { + return &DeclType{ + name: "map", + KeyType: key, + ElemType: elem, + MaxElements: maxProperties, + celType: cel.MapType(key.CelType(), elem.CelType()), + defaultValue: NewMapValue(), + // a map can always be represented as {} in JSON, so hardcode the min size + // to 2 + MinSerializedSize: 2, + } +} + +// NewObjectType creates an object type with a qualified name and a set of field declarations. +func NewObjectType(name string, fields map[string]*DeclField) *DeclType { + t := &DeclType{ + name: name, + Fields: fields, + celType: cel.ObjectType(name), + traitMask: traits.FieldTesterType | traits.IndexerType, + // an object could potentially be larger than the min size we default to here ({}), + // but we rely upon the caller to change MinSerializedSize accordingly if they add + // properties to the object + MinSerializedSize: 2, + } + t.defaultValue = NewObjectValue(t) + return t +} + +func NewSimpleTypeWithMinSize(name string, celType *cel.Type, zeroVal ref.Val, minSize int64) *DeclType { + return &DeclType{ + name: name, + celType: celType, + defaultValue: zeroVal, + MinSerializedSize: minSize, + } +} + +// DeclType represents the universal type descriptor for OpenAPIv3 types. +type DeclType struct { + fmt.Stringer + + name string + // Fields contains a map of escaped CEL identifier field names to field declarations. + Fields map[string]*DeclField + KeyType *DeclType + ElemType *DeclType + TypeParam bool + Metadata map[string]string + MaxElements int64 + // MinSerializedSize represents the smallest possible size in bytes that + // the DeclType could be serialized to in JSON. + MinSerializedSize int64 + + celType *cel.Type + traitMask int + defaultValue ref.Val +} + +// MaybeAssignTypeName attempts to set the DeclType name to a fully qualified name, if the type +// is of `object` type. +// +// The DeclType must return true for `IsObject` or this assignment will error. +func (t *DeclType) MaybeAssignTypeName(name string) *DeclType { + if t.IsObject() { + objUpdated := false + if t.name != "object" { + name = t.name + } else { + objUpdated = true + } + fieldMap := make(map[string]*DeclField, len(t.Fields)) + for fieldName, field := range t.Fields { + fieldType := field.Type + fieldTypeName := fmt.Sprintf("%s.%s", name, fieldName) + updated := fieldType.MaybeAssignTypeName(fieldTypeName) + if updated == fieldType { + fieldMap[fieldName] = field + continue + } + objUpdated = true + fieldMap[fieldName] = &DeclField{ + Name: fieldName, + Type: updated, + Required: field.Required, + enumValues: field.enumValues, + defaultValue: field.defaultValue, + } + } + if !objUpdated { + return t + } + return &DeclType{ + name: name, + Fields: fieldMap, + KeyType: t.KeyType, + ElemType: t.ElemType, + TypeParam: t.TypeParam, + Metadata: t.Metadata, + celType: cel.ObjectType(name), + traitMask: t.traitMask, + defaultValue: t.defaultValue, + MinSerializedSize: t.MinSerializedSize, + } + } + if t.IsMap() { + elemTypeName := fmt.Sprintf("%s.@elem", name) + updated := t.ElemType.MaybeAssignTypeName(elemTypeName) + if updated == t.ElemType { + return t + } + return NewMapType(t.KeyType, updated, t.MaxElements) + } + if t.IsList() { + elemTypeName := fmt.Sprintf("%s.@idx", name) + updated := t.ElemType.MaybeAssignTypeName(elemTypeName) + if updated == t.ElemType { + return t + } + return NewListType(updated, t.MaxElements) + } + return t +} + +// ExprType returns the CEL expression type of this declaration. +func (t *DeclType) ExprType() (*exprpb.Type, error) { + return cel.TypeToExprType(t.celType) +} + +// CelType returns the CEL type of this declaration. +func (t *DeclType) CelType() *cel.Type { + return t.celType +} + +// FindField returns the DeclField with the given name if present. +func (t *DeclType) FindField(name string) (*DeclField, bool) { + f, found := t.Fields[name] + return f, found +} + +// HasTrait implements the CEL ref.Type interface making this type declaration suitable for use +// within the CEL evaluator. +func (t *DeclType) HasTrait(trait int) bool { + if t.traitMask&trait == trait { + return true + } + if t.defaultValue == nil { + return false + } + _, isDecl := t.defaultValue.Type().(*DeclType) + if isDecl { + return false + } + return t.defaultValue.Type().HasTrait(trait) +} + +// IsList returns whether the declaration is a `list` type which defines a parameterized element +// type, but not a parameterized key type or fields. +func (t *DeclType) IsList() bool { + return t.KeyType == nil && t.ElemType != nil && t.Fields == nil +} + +// IsMap returns whether the declaration is a 'map' type which defines parameterized key and +// element types, but not fields. +func (t *DeclType) IsMap() bool { + return t.KeyType != nil && t.ElemType != nil && t.Fields == nil +} + +// IsObject returns whether the declartion is an 'object' type which defined a set of typed fields. +func (t *DeclType) IsObject() bool { + return t.KeyType == nil && t.ElemType == nil && t.Fields != nil +} + +// String implements the fmt.Stringer interface method. +func (t *DeclType) String() string { + return t.name +} + +// TypeName returns the fully qualified type name for the DeclType. +func (t *DeclType) TypeName() string { + return t.name +} + +// DefaultValue returns the CEL ref.Val representing the default value for this object type, +// if one exists. +func (t *DeclType) DefaultValue() ref.Val { + return t.defaultValue +} + +// FieldTypeMap constructs a map of the field and object types nested within a given type. +func FieldTypeMap(path string, t *DeclType) map[string]*DeclType { + if t.IsObject() && t.TypeName() != "object" { + path = t.TypeName() + } + types := make(map[string]*DeclType) + buildDeclTypes(path, t, types) + return types +} + +func buildDeclTypes(path string, t *DeclType, types map[string]*DeclType) { + // Ensure object types are properly named according to where they appear in the schema. + if t.IsObject() { + // Hack to ensure that names are uniquely qualified and work well with the type + // resolution steps which require fully qualified type names for field resolution + // to function properly. + types[t.TypeName()] = t + for name, field := range t.Fields { + fieldPath := fmt.Sprintf("%s.%s", path, name) + buildDeclTypes(fieldPath, field.Type, types) + } + } + // Map element properties to type names if needed. + if t.IsMap() { + mapElemPath := fmt.Sprintf("%s.@elem", path) + buildDeclTypes(mapElemPath, t.ElemType, types) + types[path] = t + } + // List element properties. + if t.IsList() { + listIdxPath := fmt.Sprintf("%s.@idx", path) + buildDeclTypes(listIdxPath, t.ElemType, types) + types[path] = t + } +} + +// DeclField describes the name, ordinal, and optionality of a field declaration within a type. +type DeclField struct { + Name string + Type *DeclType + Required bool + enumValues []interface{} + defaultValue interface{} +} + +func NewDeclField(name string, declType *DeclType, required bool, enumValues []interface{}, defaultValue interface{}) *DeclField { + return &DeclField{ + Name: name, + Type: declType, + Required: required, + enumValues: enumValues, + defaultValue: defaultValue, + } +} + +// TypeName returns the string type name of the field. +func (f *DeclField) TypeName() string { + return f.Type.TypeName() +} + +// DefaultValue returns the zero value associated with the field. +func (f *DeclField) DefaultValue() ref.Val { + if f.defaultValue != nil { + return types.DefaultTypeAdapter.NativeToValue(f.defaultValue) + } + return f.Type.DefaultValue() +} + +// EnumValues returns the set of values that this field may take. +func (f *DeclField) EnumValues() []ref.Val { + if f.enumValues == nil || len(f.enumValues) == 0 { + return []ref.Val{} + } + ev := make([]ref.Val, len(f.enumValues)) + for i, e := range f.enumValues { + ev[i] = types.DefaultTypeAdapter.NativeToValue(e) + } + return ev +} + +// NewRuleTypes returns an Open API Schema-based type-system which is CEL compatible. +func NewRuleTypes(kind string, + declType *DeclType, + res Resolver) (*RuleTypes, error) { + // Note, if the schema indicates that it's actually based on another proto + // then prefer the proto definition. For expressions in the proto, a new field + // annotation will be needed to indicate the expected environment and type of + // the expression. + schemaTypes, err := newSchemaTypeProvider(kind, declType) + if err != nil { + return nil, err + } + if schemaTypes == nil { + return nil, nil + } + return &RuleTypes{ + ruleSchemaDeclTypes: schemaTypes, + resolver: res, + }, nil +} + +// RuleTypes extends the CEL ref.TypeProvider interface and provides an Open API Schema-based +// type-system. +type RuleTypes struct { + ref.TypeProvider + ruleSchemaDeclTypes *schemaTypeProvider + typeAdapter ref.TypeAdapter + resolver Resolver +} + +// EnvOptions returns a set of cel.EnvOption values which includes the declaration set +// as well as a custom ref.TypeProvider. +// +// Note, the standard declaration set includes 'rule' which is defined as the top-level rule-schema +// type if one is configured. +// +// If the RuleTypes value is nil, an empty []cel.EnvOption set is returned. +func (rt *RuleTypes) EnvOptions(tp ref.TypeProvider) ([]cel.EnvOption, error) { + if rt == nil { + return []cel.EnvOption{}, nil + } + rtWithTypes, err := rt.WithTypeProvider(tp) + if err != nil { + return nil, err + } + return []cel.EnvOption{ + cel.CustomTypeProvider(rtWithTypes), + cel.CustomTypeAdapter(rtWithTypes), + cel.Variable("rule", rt.ruleSchemaDeclTypes.root.CelType()), + }, nil +} + +// WithTypeProvider returns a new RuleTypes that sets the given TypeProvider +// If the original RuleTypes is nil, the returned RuleTypes is still nil. +func (rt *RuleTypes) WithTypeProvider(tp ref.TypeProvider) (*RuleTypes, error) { + if rt == nil { + return nil, nil + } + var ta ref.TypeAdapter = types.DefaultTypeAdapter + tpa, ok := tp.(ref.TypeAdapter) + if ok { + ta = tpa + } + rtWithTypes := &RuleTypes{ + TypeProvider: tp, + typeAdapter: ta, + ruleSchemaDeclTypes: rt.ruleSchemaDeclTypes, + resolver: rt.resolver, + } + for name, declType := range rt.ruleSchemaDeclTypes.types { + tpType, found := tp.FindType(name) + expT, err := declType.ExprType() + if err != nil { + return nil, fmt.Errorf("fail to get cel type: %s", err) + } + if found && !proto.Equal(tpType, expT) { + return nil, fmt.Errorf( + "type %s definition differs between CEL environment and rule", name) + } + } + return rtWithTypes, nil +} + +// FindType attempts to resolve the typeName provided from the rule's rule-schema, or if not +// from the embedded ref.TypeProvider. +// +// FindType overrides the default type-finding behavior of the embedded TypeProvider. +// +// Note, when the type name is based on the Open API Schema, the name will reflect the object path +// where the type definition appears. +func (rt *RuleTypes) FindType(typeName string) (*exprpb.Type, bool) { + if rt == nil { + return nil, false + } + declType, found := rt.findDeclType(typeName) + if found { + expT, err := declType.ExprType() + if err != nil { + return expT, false + } + return expT, found + } + return rt.TypeProvider.FindType(typeName) +} + +// FindDeclType returns the CPT type description which can be mapped to a CEL type. +func (rt *RuleTypes) FindDeclType(typeName string) (*DeclType, bool) { + if rt == nil { + return nil, false + } + return rt.findDeclType(typeName) +} + +// FindFieldType returns a field type given a type name and field name, if found. +// +// Note, the type name for an Open API Schema type is likely to be its qualified object path. +// If, in the future an object instance rather than a type name were provided, the field +// resolution might more accurately reflect the expected type model. However, in this case +// concessions were made to align with the existing CEL interfaces. +func (rt *RuleTypes) FindFieldType(typeName, fieldName string) (*ref.FieldType, bool) { + st, found := rt.findDeclType(typeName) + if !found { + return rt.TypeProvider.FindFieldType(typeName, fieldName) + } + + f, found := st.Fields[fieldName] + if found { + ft := f.Type + expT, err := ft.ExprType() + if err != nil { + return nil, false + } + return &ref.FieldType{ + Type: expT, + }, true + } + // This could be a dynamic map. + if st.IsMap() { + et := st.ElemType + expT, err := et.ExprType() + if err != nil { + return nil, false + } + return &ref.FieldType{ + Type: expT, + }, true + } + return nil, false +} + +// NativeToValue is an implementation of the ref.TypeAdapater interface which supports conversion +// of rule values to CEL ref.Val instances. +func (rt *RuleTypes) NativeToValue(val interface{}) ref.Val { + return rt.typeAdapter.NativeToValue(val) +} + +// TypeNames returns the list of type names declared within the RuleTypes object. +func (rt *RuleTypes) TypeNames() []string { + typeNames := make([]string, len(rt.ruleSchemaDeclTypes.types)) + i := 0 + for name := range rt.ruleSchemaDeclTypes.types { + typeNames[i] = name + i++ + } + return typeNames +} + +func (rt *RuleTypes) findDeclType(typeName string) (*DeclType, bool) { + declType, found := rt.ruleSchemaDeclTypes.types[typeName] + if found { + return declType, true + } + declType, found = rt.resolver.FindType(typeName) + if found { + return declType, true + } + return nil, false +} + +func newSchemaTypeProvider(kind string, declType *DeclType) (*schemaTypeProvider, error) { + if declType == nil { + return nil, nil + } + root := declType.MaybeAssignTypeName(kind) + types := FieldTypeMap(kind, root) + return &schemaTypeProvider{ + root: root, + types: types, + }, nil +} + +type schemaTypeProvider struct { + root *DeclType + types map[string]*DeclType +} + +var ( + // AnyType is equivalent to the CEL 'protobuf.Any' type in that the value may have any of the + // types supported. + AnyType = NewSimpleTypeWithMinSize("any", cel.AnyType, nil, 1) + + // BoolType is equivalent to the CEL 'bool' type. + BoolType = NewSimpleTypeWithMinSize("bool", cel.BoolType, types.False, MinBoolSize) + + // BytesType is equivalent to the CEL 'bytes' type. + BytesType = NewSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), MinStringSize) + + // DoubleType is equivalent to the CEL 'double' type which is a 64-bit floating point value. + DoubleType = NewSimpleTypeWithMinSize("double", cel.DoubleType, types.Double(0), MinNumberSize) + + // DurationType is equivalent to the CEL 'duration' type. + DurationType = NewSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, MinDurationSizeJSON) + + // DateType is equivalent to the CEL 'date' type. + DateType = NewSimpleTypeWithMinSize("date", cel.TimestampType, types.Timestamp{Time: time.Time{}}, JSONDateSize) + + // DynType is the equivalent of the CEL 'dyn' concept which indicates that the type will be + // determined at runtime rather than compile time. + DynType = NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) + + // IntType is equivalent to the CEL 'int' type which is a 64-bit signed int. + IntType = NewSimpleTypeWithMinSize("int", cel.IntType, types.IntZero, MinNumberSize) + + // NullType is equivalent to the CEL 'null_type'. + NullType = NewSimpleTypeWithMinSize("null_type", cel.NullType, types.NullValue, 4) + + // StringType is equivalent to the CEL 'string' type which is expected to be a UTF-8 string. + // StringType values may either be string literals or expression strings. + StringType = NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), MinStringSize) + + // TimestampType corresponds to the well-known protobuf.Timestamp type supported within CEL. + // Note that both the OpenAPI date and date-time types map onto TimestampType, so not all types + // labeled as Timestamp will necessarily have the same MinSerializedSize. + TimestampType = NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, JSONDateSize) + + // UintType is equivalent to the CEL 'uint' type. + UintType = NewSimpleTypeWithMinSize("uint", cel.UintType, types.Uint(0), 1) + + // ListType is equivalent to the CEL 'list' type. + ListType = NewListType(AnyType, noMaxLength) + + // MapType is equivalent to the CEL 'map' type. + MapType = NewMapType(AnyType, AnyType, noMaxLength) +) diff --git a/vendor/k8s.io/apiserver/pkg/cel/url.go b/vendor/k8s.io/apiserver/pkg/cel/url.go new file mode 100644 index 00000000000..6800205c9a9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/url.go @@ -0,0 +1,80 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "fmt" + "net/url" + "reflect" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/checker/decls" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" +) + +// URL provides a CEL representation of a URL. +type URL struct { + *url.URL +} + +var ( + URLObject = decls.NewObjectType("kubernetes.URL") + typeValue = types.NewTypeValue("kubernetes.URL") + URLType = cel.ObjectType("kubernetes.URL") +) + +// ConvertToNative implements ref.Val.ConvertToNative. +func (d URL) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + if reflect.TypeOf(d.URL).AssignableTo(typeDesc) { + return d.URL, nil + } + if reflect.TypeOf("").AssignableTo(typeDesc) { + return d.URL.String(), nil + } + return nil, fmt.Errorf("type conversion error from 'URL' to '%v'", typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (d URL) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case typeValue: + return d + case types.TypeType: + return typeValue + } + return types.NewErr("type conversion error from '%s' to '%s'", typeValue, typeVal) +} + +// Equal implements ref.Val.Equal. +func (d URL) Equal(other ref.Val) ref.Val { + otherDur, ok := other.(URL) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + return types.Bool(d.URL.String() == otherDur.URL.String()) +} + +// Type implements ref.Val.Type. +func (d URL) Type() ref.Type { + return typeValue +} + +// Value implements ref.Val.Value. +func (d URL) Value() interface{} { + return d.URL +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/value.go b/vendor/k8s.io/apiserver/pkg/cel/value.go new file mode 100644 index 00000000000..01c7f20acc9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/value.go @@ -0,0 +1,769 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cel + +import ( + "fmt" + "reflect" + "sync" + "time" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" +) + +// EncodeStyle is a hint for string encoding of parsed values. +type EncodeStyle int + +const ( + // BlockValueStyle is the default string encoding which preserves whitespace and newlines. + BlockValueStyle EncodeStyle = iota + + // FlowValueStyle indicates that the string is an inline representation of complex types. + FlowValueStyle + + // FoldedValueStyle is a multiline string with whitespace and newlines trimmed to a single + // a whitespace. Repeated newlines are replaced with a single newline rather than a single + // whitespace. + FoldedValueStyle + + // LiteralStyle is a multiline string that preserves newlines, but trims all other whitespace + // to a single character. + LiteralStyle +) + +// NewEmptyDynValue returns the zero-valued DynValue. +func NewEmptyDynValue() *DynValue { + // note: 0 is not a valid parse node identifier. + dv, _ := NewDynValue(0, nil) + return dv +} + +// NewDynValue returns a DynValue that corresponds to a parse node id and value. +func NewDynValue(id int64, val interface{}) (*DynValue, error) { + dv := &DynValue{ID: id} + err := dv.SetValue(val) + return dv, err +} + +// DynValue is a dynamically typed value used to describe unstructured content. +// Whether the value has the desired type is determined by where it is used within the Instance or +// Template, and whether there are schemas which might enforce a more rigid type definition. +type DynValue struct { + ID int64 + EncodeStyle EncodeStyle + value interface{} + exprValue ref.Val + declType *DeclType +} + +// DeclType returns the policy model type of the dyn value. +func (dv *DynValue) DeclType() *DeclType { + return dv.declType +} + +// ConvertToNative is an implementation of the CEL ref.Val method used to adapt between CEL types +// and Go-native types. +// +// The default behavior of this method is to first convert to a CEL type which has a well-defined +// set of conversion behaviors and proxy to the CEL ConvertToNative method for the type. +func (dv *DynValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + ev := dv.ExprValue() + if types.IsError(ev) { + return nil, ev.(*types.Err) + } + return ev.ConvertToNative(typeDesc) +} + +// Equal returns whether the dyn value is equal to a given CEL value. +func (dv *DynValue) Equal(other ref.Val) ref.Val { + dvType := dv.Type() + otherType := other.Type() + // Preserve CEL's homogeneous equality constraint. + if dvType.TypeName() != otherType.TypeName() { + return types.MaybeNoSuchOverloadErr(other) + } + switch v := dv.value.(type) { + case ref.Val: + return v.Equal(other) + case PlainTextValue: + return celBool(string(v) == other.Value().(string)) + case *MultilineStringValue: + return celBool(v.Value == other.Value().(string)) + case time.Duration: + otherDuration := other.Value().(time.Duration) + return celBool(v == otherDuration) + case time.Time: + otherTimestamp := other.Value().(time.Time) + return celBool(v.Equal(otherTimestamp)) + default: + return celBool(reflect.DeepEqual(v, other.Value())) + } +} + +// ExprValue converts the DynValue into a CEL value. +func (dv *DynValue) ExprValue() ref.Val { + return dv.exprValue +} + +// Value returns the underlying value held by this reference. +func (dv *DynValue) Value() interface{} { + return dv.value +} + +// SetValue updates the underlying value held by this reference. +func (dv *DynValue) SetValue(value interface{}) error { + dv.value = value + var err error + dv.exprValue, dv.declType, err = exprValue(value) + return err +} + +// Type returns the CEL type for the given value. +func (dv *DynValue) Type() ref.Type { + return dv.ExprValue().Type() +} + +func exprValue(value interface{}) (ref.Val, *DeclType, error) { + switch v := value.(type) { + case bool: + return types.Bool(v), BoolType, nil + case []byte: + return types.Bytes(v), BytesType, nil + case float64: + return types.Double(v), DoubleType, nil + case int64: + return types.Int(v), IntType, nil + case string: + return types.String(v), StringType, nil + case uint64: + return types.Uint(v), UintType, nil + case time.Duration: + return types.Duration{Duration: v}, DurationType, nil + case time.Time: + return types.Timestamp{Time: v}, TimestampType, nil + case types.Null: + return v, NullType, nil + case *ListValue: + return v, ListType, nil + case *MapValue: + return v, MapType, nil + case *ObjectValue: + return v, v.objectType, nil + default: + return nil, unknownType, fmt.Errorf("unsupported type: (%T)%v", v, v) + } +} + +// PlainTextValue is a text string literal which must not be treated as an expression. +type PlainTextValue string + +// MultilineStringValue is a multiline string value which has been parsed in a way which omits +// whitespace as well as a raw form which preserves whitespace. +type MultilineStringValue struct { + Value string + Raw string +} + +func newStructValue() *structValue { + return &structValue{ + Fields: []*Field{}, + fieldMap: map[string]*Field{}, + } +} + +type structValue struct { + Fields []*Field + fieldMap map[string]*Field +} + +// AddField appends a MapField to the MapValue and indexes the field by name. +func (sv *structValue) AddField(field *Field) { + sv.Fields = append(sv.Fields, field) + sv.fieldMap[field.Name] = field +} + +// ConvertToNative converts the MapValue type to a native go types. +func (sv *structValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + if typeDesc.Kind() != reflect.Map && + typeDesc.Kind() != reflect.Struct && + typeDesc.Kind() != reflect.Pointer && + typeDesc.Kind() != reflect.Interface { + return nil, fmt.Errorf("type conversion error from object to '%v'", typeDesc) + } + + // Unwrap pointers, but track their use. + isPtr := false + if typeDesc.Kind() == reflect.Pointer { + tk := typeDesc + typeDesc = typeDesc.Elem() + if typeDesc.Kind() == reflect.Pointer { + return nil, fmt.Errorf("unsupported type conversion to '%v'", tk) + } + isPtr = true + } + + if typeDesc.Kind() == reflect.Map { + keyType := typeDesc.Key() + if keyType.Kind() != reflect.String && keyType.Kind() != reflect.Interface { + return nil, fmt.Errorf("object fields cannot be converted to type '%v'", keyType) + } + elemType := typeDesc.Elem() + sz := len(sv.fieldMap) + ntvMap := reflect.MakeMapWithSize(typeDesc, sz) + for name, val := range sv.fieldMap { + refVal, err := val.Ref.ConvertToNative(elemType) + if err != nil { + return nil, err + } + ntvMap.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(refVal)) + } + return ntvMap.Interface(), nil + } + + if typeDesc.Kind() == reflect.Struct { + ntvObjPtr := reflect.New(typeDesc) + ntvObj := ntvObjPtr.Elem() + for name, val := range sv.fieldMap { + f := ntvObj.FieldByName(name) + if !f.IsValid() { + return nil, fmt.Errorf("type conversion error, no such field %s in type %v", + name, typeDesc) + } + fv, err := val.Ref.ConvertToNative(f.Type()) + if err != nil { + return nil, err + } + f.Set(reflect.ValueOf(fv)) + } + if isPtr { + return ntvObjPtr.Interface(), nil + } + return ntvObj.Interface(), nil + } + return nil, fmt.Errorf("type conversion error from object to '%v'", typeDesc) +} + +// GetField returns a MapField by name if one exists. +func (sv *structValue) GetField(name string) (*Field, bool) { + field, found := sv.fieldMap[name] + return field, found +} + +// IsSet returns whether the given field, which is defined, has also been set. +func (sv *structValue) IsSet(key ref.Val) ref.Val { + k, ok := key.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(key) + } + name := string(k) + _, found := sv.fieldMap[name] + return celBool(found) +} + +// NewObjectValue creates a struct value with a schema type and returns the empty ObjectValue. +func NewObjectValue(sType *DeclType) *ObjectValue { + return &ObjectValue{ + structValue: newStructValue(), + objectType: sType, + } +} + +// ObjectValue is a struct with a custom schema type which indicates the fields and types +// associated with the structure. +type ObjectValue struct { + *structValue + objectType *DeclType +} + +// ConvertToType is an implementation of the CEL ref.Val interface method. +func (o *ObjectValue) ConvertToType(t ref.Type) ref.Val { + if t == types.TypeType { + return types.NewObjectTypeValue(o.objectType.TypeName()) + } + if t.TypeName() == o.objectType.TypeName() { + return o + } + return types.NewErr("type conversion error from '%s' to '%s'", o.Type(), t) +} + +// Equal returns true if the two object types are equal and their field values are equal. +func (o *ObjectValue) Equal(other ref.Val) ref.Val { + // Preserve CEL's homogeneous equality semantics. + if o.objectType.TypeName() != other.Type().TypeName() { + return types.MaybeNoSuchOverloadErr(other) + } + o2 := other.(traits.Indexer) + for name := range o.objectType.Fields { + k := types.String(name) + v := o.Get(k) + ov := o2.Get(k) + vEq := v.Equal(ov) + if vEq != types.True { + return vEq + } + } + return types.True +} + +// Get returns the value of the specified field. +// +// If the field is set, its value is returned. If the field is not set, the default value for the +// field is returned thus allowing for safe-traversal and preserving proto-like field traversal +// semantics for Open API Schema backed types. +func (o *ObjectValue) Get(name ref.Val) ref.Val { + n, ok := name.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(n) + } + nameStr := string(n) + field, found := o.fieldMap[nameStr] + if found { + return field.Ref.ExprValue() + } + fieldDef, found := o.objectType.Fields[nameStr] + if !found { + return types.NewErr("no such field: %s", nameStr) + } + defValue := fieldDef.DefaultValue() + if defValue != nil { + return defValue + } + return types.NewErr("no default for type: %s", fieldDef.TypeName()) +} + +// Type returns the CEL type value of the object. +func (o *ObjectValue) Type() ref.Type { + return o.objectType +} + +// Value returns the Go-native representation of the object. +func (o *ObjectValue) Value() interface{} { + return o +} + +// NewMapValue returns an empty MapValue. +func NewMapValue() *MapValue { + return &MapValue{ + structValue: newStructValue(), + } +} + +// MapValue declares an object with a set of named fields whose values are dynamically typed. +type MapValue struct { + *structValue +} + +// ConvertToObject produces an ObjectValue from the MapValue with the associated schema type. +// +// The conversion is shallow and the memory shared between the Object and Map as all references +// to the map are expected to be replaced with the Object reference. +func (m *MapValue) ConvertToObject(declType *DeclType) *ObjectValue { + return &ObjectValue{ + structValue: m.structValue, + objectType: declType, + } +} + +// Contains returns whether the given key is contained in the MapValue. +func (m *MapValue) Contains(key ref.Val) ref.Val { + v, found := m.Find(key) + if v != nil && types.IsUnknownOrError(v) { + return v + } + return celBool(found) +} + +// ConvertToType converts the MapValue to another CEL type, if possible. +func (m *MapValue) ConvertToType(t ref.Type) ref.Val { + switch t { + case types.MapType: + return m + case types.TypeType: + return types.MapType + } + return types.NewErr("type conversion error from '%s' to '%s'", m.Type(), t) +} + +// Equal returns true if the maps are of the same size, have the same keys, and the key-values +// from each map are equal. +func (m *MapValue) Equal(other ref.Val) ref.Val { + oMap, isMap := other.(traits.Mapper) + if !isMap { + return types.MaybeNoSuchOverloadErr(other) + } + if m.Size() != oMap.Size() { + return types.False + } + for name, field := range m.fieldMap { + k := types.String(name) + ov, found := oMap.Find(k) + if !found { + return types.False + } + v := field.Ref.ExprValue() + vEq := v.Equal(ov) + if vEq != types.True { + return vEq + } + } + return types.True +} + +// Find returns the value for the key in the map, if found. +func (m *MapValue) Find(name ref.Val) (ref.Val, bool) { + // Currently only maps with string keys are supported as this is best aligned with JSON, + // and also much simpler to support. + n, ok := name.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(n), true + } + nameStr := string(n) + field, found := m.fieldMap[nameStr] + if found { + return field.Ref.ExprValue(), true + } + return nil, false +} + +// Get returns the value for the key in the map, or error if not found. +func (m *MapValue) Get(key ref.Val) ref.Val { + v, found := m.Find(key) + if found { + return v + } + return types.ValOrErr(key, "no such key: %v", key) +} + +// Iterator produces a traits.Iterator which walks over the map keys. +// +// The Iterator is frequently used within comprehensions. +func (m *MapValue) Iterator() traits.Iterator { + keys := make([]ref.Val, len(m.fieldMap)) + i := 0 + for k := range m.fieldMap { + keys[i] = types.String(k) + i++ + } + return &baseMapIterator{ + baseVal: &baseVal{}, + keys: keys, + } +} + +// Size returns the number of keys in the map. +func (m *MapValue) Size() ref.Val { + return types.Int(len(m.Fields)) +} + +// Type returns the CEL ref.Type for the map. +func (m *MapValue) Type() ref.Type { + return types.MapType +} + +// Value returns the Go-native representation of the MapValue. +func (m *MapValue) Value() interface{} { + return m +} + +type baseMapIterator struct { + *baseVal + keys []ref.Val + idx int +} + +// HasNext implements the traits.Iterator interface method. +func (it *baseMapIterator) HasNext() ref.Val { + if it.idx < len(it.keys) { + return types.True + } + return types.False +} + +// Next implements the traits.Iterator interface method. +func (it *baseMapIterator) Next() ref.Val { + key := it.keys[it.idx] + it.idx++ + return key +} + +// Type implements the CEL ref.Val interface metohd. +func (it *baseMapIterator) Type() ref.Type { + return types.IteratorType +} + +// NewField returns a MapField instance with an empty DynValue that refers to the +// specified parse node id and field name. +func NewField(id int64, name string) *Field { + return &Field{ + ID: id, + Name: name, + Ref: NewEmptyDynValue(), + } +} + +// Field specifies a field name and a reference to a dynamic value. +type Field struct { + ID int64 + Name string + Ref *DynValue +} + +// NewListValue returns an empty ListValue instance. +func NewListValue() *ListValue { + return &ListValue{ + Entries: []*DynValue{}, + } +} + +// ListValue contains a list of dynamically typed entries. +type ListValue struct { + Entries []*DynValue + initValueSet sync.Once + valueSet map[ref.Val]struct{} +} + +// Add concatenates two lists together to produce a new CEL list value. +func (lv *ListValue) Add(other ref.Val) ref.Val { + oArr, isArr := other.(traits.Lister) + if !isArr { + return types.MaybeNoSuchOverloadErr(other) + } + szRight := len(lv.Entries) + szLeft := int(oArr.Size().(types.Int)) + sz := szRight + szLeft + combo := make([]ref.Val, sz) + for i := 0; i < szRight; i++ { + combo[i] = lv.Entries[i].ExprValue() + } + for i := 0; i < szLeft; i++ { + combo[i+szRight] = oArr.Get(types.Int(i)) + } + return types.DefaultTypeAdapter.NativeToValue(combo) +} + +// Append adds another entry into the ListValue. +func (lv *ListValue) Append(entry *DynValue) { + lv.Entries = append(lv.Entries, entry) + // The append resets all previously built indices. + lv.initValueSet = sync.Once{} +} + +// Contains returns whether the input `val` is equal to an element in the list. +// +// If any pair-wise comparison between the input value and the list element is an error, the +// operation will return an error. +func (lv *ListValue) Contains(val ref.Val) ref.Val { + if types.IsUnknownOrError(val) { + return val + } + lv.initValueSet.Do(lv.finalizeValueSet) + if lv.valueSet != nil { + _, found := lv.valueSet[val] + if found { + return types.True + } + // Instead of returning false, ensure that CEL's heterogeneous equality constraint + // is satisfied by allowing pair-wise equality behavior to determine the outcome. + } + var err ref.Val + sz := len(lv.Entries) + for i := 0; i < sz; i++ { + elem := lv.Entries[i] + cmp := elem.Equal(val) + b, ok := cmp.(types.Bool) + if !ok && err == nil { + err = types.MaybeNoSuchOverloadErr(cmp) + } + if b == types.True { + return types.True + } + } + if err != nil { + return err + } + return types.False +} + +// ConvertToNative is an implementation of the CEL ref.Val method used to adapt between CEL types +// and Go-native array-like types. +func (lv *ListValue) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + // Non-list conversion. + if typeDesc.Kind() != reflect.Slice && + typeDesc.Kind() != reflect.Array && + typeDesc.Kind() != reflect.Interface { + return nil, fmt.Errorf("type conversion error from list to '%v'", typeDesc) + } + + // If the list is already assignable to the desired type return it. + if reflect.TypeOf(lv).AssignableTo(typeDesc) { + return lv, nil + } + + // List conversion. + otherElem := typeDesc.Elem() + + // Allow the element ConvertToNative() function to determine whether conversion is possible. + sz := len(lv.Entries) + nativeList := reflect.MakeSlice(typeDesc, int(sz), int(sz)) + for i := 0; i < sz; i++ { + elem := lv.Entries[i] + nativeElemVal, err := elem.ConvertToNative(otherElem) + if err != nil { + return nil, err + } + nativeList.Index(int(i)).Set(reflect.ValueOf(nativeElemVal)) + } + return nativeList.Interface(), nil +} + +// ConvertToType converts the ListValue to another CEL type. +func (lv *ListValue) ConvertToType(t ref.Type) ref.Val { + switch t { + case types.ListType: + return lv + case types.TypeType: + return types.ListType + } + return types.NewErr("type conversion error from '%s' to '%s'", ListType, t) +} + +// Equal returns true if two lists are of the same size, and the values at each index are also +// equal. +func (lv *ListValue) Equal(other ref.Val) ref.Val { + oArr, isArr := other.(traits.Lister) + if !isArr { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(lv.Entries)) + if sz != oArr.Size() { + return types.False + } + for i := types.Int(0); i < sz; i++ { + cmp := lv.Get(i).Equal(oArr.Get(i)) + if cmp != types.True { + return cmp + } + } + return types.True +} + +// Get returns the value at the given index. +// +// If the index is negative or greater than the size of the list, an error is returned. +func (lv *ListValue) Get(idx ref.Val) ref.Val { + iv, isInt := idx.(types.Int) + if !isInt { + return types.ValOrErr(idx, "unsupported index: %v", idx) + } + i := int(iv) + if i < 0 || i >= len(lv.Entries) { + return types.NewErr("index out of bounds: %v", idx) + } + return lv.Entries[i].ExprValue() +} + +// Iterator produces a traits.Iterator suitable for use in CEL comprehension macros. +func (lv *ListValue) Iterator() traits.Iterator { + return &baseListIterator{ + getter: lv.Get, + sz: len(lv.Entries), + } +} + +// Size returns the number of elements in the list. +func (lv *ListValue) Size() ref.Val { + return types.Int(len(lv.Entries)) +} + +// Type returns the CEL ref.Type for the list. +func (lv *ListValue) Type() ref.Type { + return types.ListType +} + +// Value returns the Go-native value. +func (lv *ListValue) Value() interface{} { + return lv +} + +// finalizeValueSet inspects the ListValue entries in order to make internal optimizations once all list +// entries are known. +func (lv *ListValue) finalizeValueSet() { + valueSet := make(map[ref.Val]struct{}) + for _, e := range lv.Entries { + switch e.value.(type) { + case bool, float64, int64, string, uint64, types.Null, PlainTextValue: + valueSet[e.ExprValue()] = struct{}{} + default: + lv.valueSet = nil + return + } + } + lv.valueSet = valueSet +} + +type baseVal struct{} + +func (*baseVal) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + return nil, fmt.Errorf("unsupported native conversion to: %v", typeDesc) +} + +func (*baseVal) ConvertToType(t ref.Type) ref.Val { + return types.NewErr("unsupported type conversion to: %v", t) +} + +func (*baseVal) Equal(other ref.Val) ref.Val { + return types.NewErr("unsupported equality test between instances") +} + +func (v *baseVal) Value() interface{} { + return nil +} + +type baseListIterator struct { + *baseVal + getter func(idx ref.Val) ref.Val + sz int + idx int +} + +func (it *baseListIterator) HasNext() ref.Val { + if it.idx < it.sz { + return types.True + } + return types.False +} + +func (it *baseListIterator) Next() ref.Val { + v := it.getter(types.Int(it.idx)) + it.idx++ + return v +} + +func (it *baseListIterator) Type() ref.Type { + return types.IteratorType +} + +func celBool(pred bool) ref.Val { + if pred { + return types.True + } + return types.False +} + +var unknownType = &DeclType{name: "unknown", MinSerializedSize: 1} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/openapi/openapi.go b/vendor/k8s.io/apiserver/pkg/endpoints/openapi/openapi.go new file mode 100644 index 00000000000..e61f444399e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/openapi/openapi.go @@ -0,0 +1,191 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package openapi + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" + "unicode" + + restful "github.com/emicklei/go-restful/v3" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kube-openapi/pkg/util" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +var verbs = util.NewTrie([]string{"get", "log", "read", "replace", "patch", "delete", "deletecollection", "watch", "connect", "proxy", "list", "create", "patch"}) + +const ( + extensionGVK = "x-kubernetes-group-version-kind" +) + +// ToValidOperationID makes an string a valid op ID (e.g. removing punctuations and whitespaces and make it camel case) +func ToValidOperationID(s string, capitalizeFirstLetter bool) string { + var buffer bytes.Buffer + capitalize := capitalizeFirstLetter + for i, r := range s { + if unicode.IsLetter(r) || r == '_' || (i != 0 && unicode.IsDigit(r)) { + if capitalize { + buffer.WriteRune(unicode.ToUpper(r)) + capitalize = false + } else { + buffer.WriteRune(r) + } + } else { + capitalize = true + } + } + return buffer.String() +} + +// GetOperationIDAndTags returns a customize operation ID and a list of tags for kubernetes API server's OpenAPI spec to prevent duplicate IDs. +func GetOperationIDAndTags(r *restful.Route) (string, []string, error) { + op := r.Operation + path := r.Path + var tags []string + prefix, exists := verbs.GetPrefix(op) + if !exists { + return op, tags, fmt.Errorf("operation names should start with a verb. Cannot determine operation verb from %v", op) + } + op = op[len(prefix):] + parts := strings.Split(strings.Trim(path, "/"), "/") + // Assume /api is /apis/core, remove this when we actually server /api/... on /apis/core/... + if len(parts) >= 1 && parts[0] == "api" { + parts = append([]string{"apis", "core"}, parts[1:]...) + } + if len(parts) >= 2 && parts[0] == "apis" { + trimmed := strings.TrimSuffix(parts[1], ".k8s.io") + prefix = prefix + ToValidOperationID(trimmed, prefix != "") + tag := ToValidOperationID(trimmed, false) + if len(parts) > 2 { + prefix = prefix + ToValidOperationID(parts[2], prefix != "") + tag = tag + "_" + ToValidOperationID(parts[2], false) + } + tags = append(tags, tag) + } else if len(parts) >= 1 { + tags = append(tags, ToValidOperationID(parts[0], false)) + } + return prefix + ToValidOperationID(op, prefix != ""), tags, nil +} + +type groupVersionKinds []v1.GroupVersionKind + +func (s groupVersionKinds) Len() int { + return len(s) +} + +func (s groupVersionKinds) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s groupVersionKinds) Less(i, j int) bool { + if s[i].Group == s[j].Group { + if s[i].Version == s[j].Version { + return s[i].Kind < s[j].Kind + } + return s[i].Version < s[j].Version + } + return s[i].Group < s[j].Group +} + +func (s groupVersionKinds) JSON() []interface{} { + j := []interface{}{} + for _, gvk := range s { + j = append(j, map[string]interface{}{ + "group": gvk.Group, + "version": gvk.Version, + "kind": gvk.Kind, + }) + } + return j +} + +// DefinitionNamer is the type to customize OpenAPI definition name. +type DefinitionNamer struct { + typeGroupVersionKinds map[string]groupVersionKinds +} + +func gvkConvert(gvk schema.GroupVersionKind) v1.GroupVersionKind { + return v1.GroupVersionKind{ + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func friendlyName(name string) string { + nameParts := strings.Split(name, "/") + // Reverse first part. e.g., io.k8s... instead of k8s.io... + if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { + parts := strings.Split(nameParts[0], ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + nameParts[0] = strings.Join(parts, ".") + } + return strings.Join(nameParts, ".") +} + +func typeName(t reflect.Type) string { + path := t.PkgPath() + if strings.Contains(path, "/vendor/") { + path = path[strings.Index(path, "/vendor/")+len("/vendor/"):] + } + return fmt.Sprintf("%s.%s", path, t.Name()) +} + +// NewDefinitionNamer constructs a new DefinitionNamer to be used to customize OpenAPI spec. +func NewDefinitionNamer(schemes ...*runtime.Scheme) *DefinitionNamer { + ret := &DefinitionNamer{ + typeGroupVersionKinds: map[string]groupVersionKinds{}, + } + for _, s := range schemes { + for gvk, rtype := range s.AllKnownTypes() { + newGVK := gvkConvert(gvk) + exists := false + for _, existingGVK := range ret.typeGroupVersionKinds[typeName(rtype)] { + if newGVK == existingGVK { + exists = true + break + } + } + if !exists { + ret.typeGroupVersionKinds[typeName(rtype)] = append(ret.typeGroupVersionKinds[typeName(rtype)], newGVK) + } + } + } + for _, gvk := range ret.typeGroupVersionKinds { + sort.Sort(gvk) + } + return ret +} + +// GetDefinitionName returns the name and tags for a given definition +func (d *DefinitionNamer) GetDefinitionName(name string) (string, spec.Extensions) { + if groupVersionKinds, ok := d.typeGroupVersionKinds[name]; ok { + return friendlyName(name), spec.Extensions{ + extensionGVK: groupVersionKinds.JSON(), + } + } + return friendlyName(name), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/auditid.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/auditid.go deleted file mode 100644 index a7b3d84addb..00000000000 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/auditid.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package request - -import ( - "context" - "net/http" - - "k8s.io/apimachinery/pkg/types" -) - -type auditIDKeyType int - -// auditIDKey is the key to associate the Audit-ID value of a request. -const auditIDKey auditIDKeyType = iota - -// WithAuditID returns a copy of the parent context into which the Audit-ID -// associated with the request is set. -// -// If the specified auditID is empty, no value is set and the parent context is returned as is. -func WithAuditID(parent context.Context, auditID types.UID) context.Context { - if auditID == "" { - return parent - } - return WithValue(parent, auditIDKey, auditID) -} - -// AuditIDFrom returns the value of the audit ID from the request context. -func AuditIDFrom(ctx context.Context) (types.UID, bool) { - auditID, ok := ctx.Value(auditIDKey).(types.UID) - return auditID, ok -} - -// GetAuditIDTruncated returns the audit ID (truncated) associated with a request. -// If the length of the Audit-ID value exceeds the limit, we truncate it to keep -// the first N (maxAuditIDLength) characters. -// This is intended to be used in logging only. -func GetAuditIDTruncated(req *http.Request) string { - auditID, ok := AuditIDFrom(req.Context()) - if !ok { - return "" - } - - // if the user has specified a very long audit ID then we will use the first N characters - // Note: assuming Audit-ID header is in ASCII - const maxAuditIDLength = 64 - if len(auditID) > maxAuditIDLength { - auditID = auditID[0:maxAuditIDLength] - } - - return string(auditID) -} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go index 2bc00a66e7b..2558494bd9a 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go @@ -211,7 +211,7 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er opts := metainternalversion.ListOptions{} if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), metav1.SchemeGroupVersion, &opts); err != nil { // An error in parsing request will result in default to "list" and not setting "name" field. - klog.ErrorS(err, "Couldn't parse request", "Request", req.URL.Query()) + klog.ErrorS(err, "Couldn't parse request", "request", req.URL.Query()) // Reset opts to not rely on partial results from parsing. // However, if watch is set, let's report it. opts = metainternalversion.ListOptions{} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go new file mode 100644 index 00000000000..d06275b8337 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go @@ -0,0 +1,55 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package request + +import ( + "context" +) + +// The serverShutdownSignalKeyType type is unexported to prevent collisions +type serverShutdownSignalKeyType int + +// serverShutdownSignalKey is the context key for storing the +// watch termination interface instance for a WATCH request. +const serverShutdownSignalKey serverShutdownSignalKeyType = iota + +// ServerShutdownSignal is associated with the request context so +// the request handler logic has access to signals rlated to +// the server shutdown events +type ServerShutdownSignal interface { + // Signaled when the apiserver is not receiving any new request + ShuttingDown() <-chan struct{} +} + +// ServerShutdownSignalFrom returns the ServerShutdownSignal instance +// associated with the request context. +// If there is no ServerShutdownSignal asscoaied with the context, +// nil is returned. +func ServerShutdownSignalFrom(ctx context.Context) ServerShutdownSignal { + ev, _ := ctx.Value(serverShutdownSignalKey).(ServerShutdownSignal) + return ev +} + +// WithServerShutdownSignal returns a new context that stores +// the ServerShutdownSignal interface instance. +func WithServerShutdownSignal(parent context.Context, window ServerShutdownSignal) context.Context { + if ServerShutdownSignalFrom(parent) != nil { + return parent // Avoid double registering. + } + + return context.WithValue(parent, serverShutdownSignalKey, window) +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go index 120bc46bf8b..612c671d85b 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go @@ -116,6 +116,10 @@ type LatencyTrackers struct { // Validate webhooks are done in parallel, so max function is used. ValidatingWebhookTracker DurationTracker + // APFQueueWaitTracker tracks the latency incurred by queue wait times + // from priority & fairness. + APFQueueWaitTracker DurationTracker + // StorageTracker tracks the latency incurred inside the storage layer, // it accounts for the time it takes to send data to the underlying // storage layer (etcd) and get the complete response back. @@ -168,6 +172,7 @@ func WithLatencyTrackersAndCustomClock(parent context.Context, c clock.Clock) co return WithValue(parent, latencyTrackersKey, &LatencyTrackers{ MutatingWebhookTracker: newSumLatencyTracker(c), ValidatingWebhookTracker: newMaxLatencyTracker(c), + APFQueueWaitTracker: newMaxLatencyTracker(c), StorageTracker: newSumLatencyTracker(c), TransformTracker: newSumLatencyTracker(c), SerializationTracker: newSumLatencyTracker(c), @@ -230,6 +235,14 @@ func TrackResponseWriteLatency(ctx context.Context, d time.Duration) { } } +// TrackAPFQueueWaitLatency is used to track latency incurred +// by priority and fairness queues. +func TrackAPFQueueWaitLatency(ctx context.Context, d time.Duration) { + if tracker, ok := LatencyTrackersFrom(ctx); ok { + tracker.APFQueueWaitTracker.TrackDuration(d) + } +} + // AuditAnnotationsFromLatencyTrackers will inspect each latency tracker // associated with the request context and return a set of audit // annotations that can be added to the API audit entry. diff --git a/vendor/k8s.io/apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiserver/pkg/features/kube_features.go index 01820d127af..72cd493758b 100644 --- a/vendor/k8s.io/apiserver/pkg/features/kube_features.go +++ b/vendor/k8s.io/apiserver/pkg/features/kube_features.go @@ -28,24 +28,27 @@ const ( // // // owner: @username // // alpha: v1.4 - // MyFeature() bool + // MyFeature featuregate.Feature = "MyFeature" + // + // Feature gates should be listed in alphabetical, case-sensitive + // (upper before any lower case character) order. This reduces the risk + // of code conflicts because changes are more likely to be scattered + // across the file. - // owner: @tallclair - // alpha: v1.7 - // beta: v1.8 - // GA: v1.12 + // owner: @ivelichkovich, @tallclair + // alpha: v1.27 + // kep: https://kep.k8s.io/3716 // - // AdvancedAuditing enables a much more general API auditing pipeline, which includes support for - // pluggable output backends and an audit policy specifying how different requests should be - // audited. - AdvancedAuditing featuregate.Feature = "AdvancedAuditing" + // Enables usage of MatchConditions fields to use CEL expressions for matching on admission webhooks + AdmissionWebhookMatchConditions featuregate.Feature = "AdmissionWebhookMatchConditions" - // owner: @ilackams - // alpha: v1.7 - // beta: v1.16 + // owner: @jefftree @alexzielenski + // alpha: v1.26 + // beta: v1.27 // - // Enables compression of REST responses (GET and LIST only) - APIResponseCompression featuregate.Feature = "APIResponseCompression" + // Enables an single HTTP endpoint /discovery/ which supports native HTTP + // caching with ETags containing all APIResources known to the apiserver. + AggregatedDiscoveryEndpoint featuregate.Feature = "AggregatedDiscoveryEndpoint" // owner: @smarterclayton // alpha: v1.8 @@ -55,78 +58,69 @@ const ( // all at once. APIListChunking featuregate.Feature = "APIListChunking" - // owner: @apelisse - // alpha: v1.12 - // beta: v1.13 - // stable: v1.18 - // - // Allow requests to be processed but not stored, so that - // validation, merging, mutation can be tested without - // committing. - DryRun featuregate.Feature = "DryRun" - - // owner: @caesarxuchao - // alpha: v1.15 - // beta: v1.16 + // owner: @MikeSpreitzer @yue9944882 + // alpha: v1.18 + // beta: v1.20 // - // Allow apiservers to show a count of remaining items in the response - // to a chunking list request. - RemainingItemCount featuregate.Feature = "RemainingItemCount" + // Enables managing request concurrency with prioritization and fairness at each server. + // The FeatureGate was introduced in release 1.15 but the feature + // was not really implemented before 1.18. + APIPriorityAndFairness featuregate.Feature = "APIPriorityAndFairness" - // owner: @apelisse, @lavalamp - // alpha: v1.14 + // owner: @ilackams + // alpha: v1.7 // beta: v1.16 - // stable: v1.22 // - // Server-side apply. Merging happens on the server. - ServerSideApply featuregate.Feature = "ServerSideApply" + // Enables compression of REST responses (GET and LIST only) + APIResponseCompression featuregate.Feature = "APIResponseCompression" - // owner: @caesarxuchao - // alpha: v1.14 - // beta: v1.15 + // owner: @roycaihw + // alpha: v1.20 // - // Allow apiservers to expose the storage version hash in the discovery - // document. - StorageVersionHash featuregate.Feature = "StorageVersionHash" + // Assigns each kube-apiserver an ID in a cluster. + APIServerIdentity featuregate.Feature = "APIServerIdentity" - // owner: @caesarxuchao @roycaihw - // alpha: v1.20 + // owner: @dashpole + // alpha: v1.22 + // beta: v1.27 // - // Enable the storage version API. - StorageVersionAPI featuregate.Feature = "StorageVersionAPI" + // Add support for distributed tracing in the API Server + APIServerTracing featuregate.Feature = "APIServerTracing" - // owner: @wojtek-t - // alpha: v1.15 - // beta: v1.16 - // GA: v1.17 + // owner: @tallclair + // alpha: v1.7 + // beta: v1.8 + // GA: v1.12 // - // Enables support for watch bookmark events. - WatchBookmark featuregate.Feature = "WatchBookmark" + // AdvancedAuditing enables a much more general API auditing pipeline, which includes support for + // pluggable output backends and an audit policy specifying how different requests should be + // audited. + AdvancedAuditing featuregate.Feature = "AdvancedAuditing" - // owner: @MikeSpreitzer @yue9944882 - // alpha: v1.18 - // beta: v1.20 + // owner: @cici37 @jpbetz + // kep: http://kep.k8s.io/3488 + // alpha: v1.26 // - // Enables managing request concurrency with prioritization and fairness at each server. - // The FeatureGate was introduced in release 1.15 but the feature - // was not really implemented before 1.18. - APIPriorityAndFairness featuregate.Feature = "APIPriorityAndFairness" + // Enables expression validation in Admission Control + ValidatingAdmissionPolicy featuregate.Feature = "ValidatingAdmissionPolicy" - // owner: @wojtek-t - // alpha: v1.16 - // beta: v1.20 - // GA: v1.24 + // owner: @cici37 + // kep: https://kep.k8s.io/2876 + // alpha: v1.23 + // beta: v1.25 // - // Deprecates and removes SelfLink from ObjectMeta and ListMeta. - RemoveSelfLink featuregate.Feature = "RemoveSelfLink" + // Enables expression validation for Custom Resource + CustomResourceValidationExpressions featuregate.Feature = "CustomResourceValidationExpressions" - // owner: @shaloulcy, @wojtek-t - // alpha: v1.18 - // beta: v1.19 - // GA: v1.20 + // owner: @apelisse + // alpha: v1.12 + // beta: v1.13 + // stable: v1.18 // - // Allows label and field based indexes in apiserver watch cache to accelerate list operations. - SelectorIndex featuregate.Feature = "SelectorIndex" + // Allow requests to be processed but not stored, so that + // validation, merging, mutation can be tested without + // committing. + DryRun featuregate.Feature = "DryRun" // owner: @wojtek-t // alpha: v1.20 @@ -136,20 +130,16 @@ const ( // Allows for updating watchcache resource version with progress notify events. EfficientWatchResumption featuregate.Feature = "EfficientWatchResumption" - // owner: @roycaihw - // alpha: v1.20 + // owner: @aramase + // kep: https://kep.k8s.io/3299 + // alpha: v1.25 + // beta: v1.27 // - // Assigns each kube-apiserver an ID in a cluster. - APIServerIdentity featuregate.Feature = "APIServerIdentity" - - // owner: @dashpole - // alpha: v1.22 - // - // Add support for distributed tracing in the API Server - APIServerTracing featuregate.Feature = "APIServerTracing" + // Enables KMS v2 API for encryption at rest. + KMSv2 featuregate.Feature = "KMSv2" // owner: @jiahuif - // kep: http://kep.k8s.io/2887 + // kep: https://kep.k8s.io/2887 // alpha: v1.23 // beta: v1.24 // @@ -157,27 +147,81 @@ const ( // in the spec returned from kube-apiserver. OpenAPIEnums featuregate.Feature = "OpenAPIEnums" - // owner: @cici37 - // kep: http://kep.k8s.io/2876 - // alpha: v1.23 - // - // Enables expression validation for Custom Resource - CustomResourceValidationExpressions featuregate.Feature = "CustomResourceValidationExpressions" - // owner: @jefftree - // kep: http://kep.k8s.io/2896 + // kep: https://kep.k8s.io/2896 // alpha: v1.23 // beta: v1.24 + // stable: v1.27 // // Enables kubernetes to publish OpenAPI v3 OpenAPIV3 featuregate.Feature = "OpenAPIV3" + // owner: @caesarxuchao + // alpha: v1.15 + // beta: v1.16 + // + // Allow apiservers to show a count of remaining items in the response + // to a chunking list request. + RemainingItemCount featuregate.Feature = "RemainingItemCount" + + // owner: @wojtek-t + // alpha: v1.16 + // beta: v1.20 + // GA: v1.24 + // + // Deprecates and removes SelfLink from ObjectMeta and ListMeta. + RemoveSelfLink featuregate.Feature = "RemoveSelfLink" + + // owner: @apelisse, @lavalamp + // alpha: v1.14 + // beta: v1.16 + // stable: v1.22 + // + // Server-side apply. Merging happens on the server. + ServerSideApply featuregate.Feature = "ServerSideApply" + // owner: @kevindelgado - // kep: http://kep.k8s.io/2885 + // kep: https://kep.k8s.io/2885 // alpha: v1.23 + // beta: v1.24 // // Enables server-side field validation. ServerSideFieldValidation featuregate.Feature = "ServerSideFieldValidation" + + // owner: @caesarxuchao @roycaihw + // alpha: v1.20 + // + // Enable the storage version API. + StorageVersionAPI featuregate.Feature = "StorageVersionAPI" + + // owner: @caesarxuchao + // alpha: v1.14 + // beta: v1.15 + // + // Allow apiservers to expose the storage version hash in the discovery + // document. + StorageVersionHash featuregate.Feature = "StorageVersionHash" + + // owner: @wojtek-t + // alpha: v1.15 + // beta: v1.16 + // GA: v1.17 + // + // Enables support for watch bookmark events. + WatchBookmark featuregate.Feature = "WatchBookmark" + + // owner: @vinaykul + // kep: http://kep.k8s.io/1287 + // alpha: v1.27 + // + // Enables In-Place Pod Vertical Scaling + InPlacePodVerticalScaling featuregate.Feature = "InPlacePodVerticalScaling" + + // owner: @p0lyn0mial + // alpha: v1.27 + // + // Allow the API server to stream individual items instead of chunking + WatchList featuregate.Feature = "WatchList" ) func init() { @@ -188,23 +232,52 @@ func init() { // To add a new feature, define a key for it above and add it here. The features will be // available throughout Kubernetes binaries. var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ - AdvancedAuditing: {Default: true, PreRelease: featuregate.GA}, - APIResponseCompression: {Default: true, PreRelease: featuregate.Beta}, - APIListChunking: {Default: true, PreRelease: featuregate.Beta}, - DryRun: {Default: true, PreRelease: featuregate.GA}, - RemainingItemCount: {Default: true, PreRelease: featuregate.Beta}, - ServerSideApply: {Default: true, PreRelease: featuregate.GA}, - StorageVersionHash: {Default: true, PreRelease: featuregate.Beta}, - StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha}, - WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta}, - RemoveSelfLink: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - SelectorIndex: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - APIServerIdentity: {Default: false, PreRelease: featuregate.Alpha}, - APIServerTracing: {Default: false, PreRelease: featuregate.Alpha}, - OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta}, - CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha}, - OpenAPIV3: {Default: true, PreRelease: featuregate.Beta}, - ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha}, + + AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta}, + + AdmissionWebhookMatchConditions: {Default: false, PreRelease: featuregate.Alpha}, + + APIListChunking: {Default: true, PreRelease: featuregate.Beta}, + + APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta}, + + APIResponseCompression: {Default: true, PreRelease: featuregate.Beta}, + + APIServerIdentity: {Default: true, PreRelease: featuregate.Beta}, + + APIServerTracing: {Default: true, PreRelease: featuregate.Beta}, + + AdvancedAuditing: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 + + ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Alpha}, + + CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.Beta}, + + DryRun: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 + + EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + + KMSv2: {Default: true, PreRelease: featuregate.Beta}, + + OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta}, + + OpenAPIV3: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 + + RemainingItemCount: {Default: true, PreRelease: featuregate.Beta}, + + RemoveSelfLink: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + + ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 + + ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 + + StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha}, + + StorageVersionHash: {Default: true, PreRelease: featuregate.Beta}, + + WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + + InPlacePodVerticalScaling: {Default: false, PreRelease: featuregate.Alpha}, + + WatchList: {Default: false, PreRelease: featuregate.Alpha}, } diff --git a/vendor/k8s.io/apiserver/pkg/quota/v1/OWNERS b/vendor/k8s.io/apiserver/pkg/quota/v1/OWNERS new file mode 100644 index 00000000000..104836035af --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/quota/v1/OWNERS @@ -0,0 +1,13 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - deads2k + - derekwaynecarr +reviewers: + - deads2k + - derekwaynecarr + - smarterclayton +labels: + - sig/api-machinery +emeritus_approvers: + - vishh diff --git a/vendor/k8s.io/apiserver/pkg/quota/v1/interfaces.go b/vendor/k8s.io/apiserver/pkg/quota/v1/interfaces.go new file mode 100644 index 00000000000..511e8818c73 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/quota/v1/interfaces.go @@ -0,0 +1,88 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/client-go/tools/cache" +) + +// UsageStatsOptions is an options structs that describes how stats should be calculated +type UsageStatsOptions struct { + // Namespace where stats should be calculate + Namespace string + // Scopes that must match counted objects + Scopes []corev1.ResourceQuotaScope + // Resources are the set of resources to include in the measurement + Resources []corev1.ResourceName + ScopeSelector *corev1.ScopeSelector +} + +// UsageStats is result of measuring observed resource use in the system +type UsageStats struct { + // Used maps resource to quantity used + Used corev1.ResourceList +} + +// Evaluator knows how to evaluate quota usage for a particular group resource +type Evaluator interface { + // Constraints ensures that each required resource is present on item + Constraints(required []corev1.ResourceName, item runtime.Object) error + // GroupResource returns the groupResource that this object knows how to evaluate + GroupResource() schema.GroupResource + // Handles determines if quota could be impacted by the specified attribute. + // If true, admission control must perform quota processing for the operation, otherwise it is safe to ignore quota. + Handles(operation admission.Attributes) bool + // Matches returns true if the specified quota matches the input item + Matches(resourceQuota *corev1.ResourceQuota, item runtime.Object) (bool, error) + // MatchingScopes takes the input specified list of scopes and input object and returns the set of scopes that matches input object. + MatchingScopes(item runtime.Object, scopes []corev1.ScopedResourceSelectorRequirement) ([]corev1.ScopedResourceSelectorRequirement, error) + // UncoveredQuotaScopes takes the input matched scopes which are limited by configuration and the matched quota scopes. It returns the scopes which are in limited scopes but don't have a corresponding covering quota scope + UncoveredQuotaScopes(limitedScopes []corev1.ScopedResourceSelectorRequirement, matchedQuotaScopes []corev1.ScopedResourceSelectorRequirement) ([]corev1.ScopedResourceSelectorRequirement, error) + // MatchingResources takes the input specified list of resources and returns the set of resources evaluator matches. + MatchingResources(input []corev1.ResourceName) []corev1.ResourceName + // Usage returns the resource usage for the specified object + Usage(item runtime.Object) (corev1.ResourceList, error) + // UsageStats calculates latest observed usage stats for all objects + UsageStats(options UsageStatsOptions) (UsageStats, error) +} + +// Configuration defines how the quota system is configured. +type Configuration interface { + // IgnoredResources are ignored by quota. + IgnoredResources() map[schema.GroupResource]struct{} + // Evaluators for quota evaluation. + Evaluators() []Evaluator +} + +// Registry maintains a list of evaluators +type Registry interface { + // Add to registry + Add(e Evaluator) + // Remove from registry + Remove(e Evaluator) + // Get by group resource + Get(gr schema.GroupResource) Evaluator + // List from registry + List() []Evaluator +} + +// ListerForResourceFunc knows how to get a lister for a specific resource +type ListerForResourceFunc func(schema.GroupVersionResource) (cache.GenericLister, error) diff --git a/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go b/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go new file mode 100644 index 00000000000..b6647192099 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go @@ -0,0 +1,304 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "sort" + "strings" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" +) + +// Equals returns true if the two lists are equivalent +func Equals(a corev1.ResourceList, b corev1.ResourceList) bool { + if len(a) != len(b) { + return false + } + + for key, value1 := range a { + value2, found := b[key] + if !found { + return false + } + if value1.Cmp(value2) != 0 { + return false + } + } + + return true +} + +// LessThanOrEqual returns true if a < b for each key in b +// If false, it returns the keys in a that exceeded b +func LessThanOrEqual(a corev1.ResourceList, b corev1.ResourceList) (bool, []corev1.ResourceName) { + result := true + resourceNames := []corev1.ResourceName{} + for key, value := range b { + if other, found := a[key]; found { + if other.Cmp(value) > 0 { + result = false + resourceNames = append(resourceNames, key) + } + } + } + return result, resourceNames +} + +// Max returns the result of Max(a, b) for each named resource +func Max(a corev1.ResourceList, b corev1.ResourceList) corev1.ResourceList { + result := corev1.ResourceList{} + for key, value := range a { + if other, found := b[key]; found { + if value.Cmp(other) <= 0 { + result[key] = other.DeepCopy() + continue + } + } + result[key] = value.DeepCopy() + } + for key, value := range b { + if _, found := result[key]; !found { + result[key] = value.DeepCopy() + } + } + return result +} + +// Add returns the result of a + b for each named resource +func Add(a corev1.ResourceList, b corev1.ResourceList) corev1.ResourceList { + result := corev1.ResourceList{} + for key, value := range a { + quantity := value.DeepCopy() + if other, found := b[key]; found { + quantity.Add(other) + } + result[key] = quantity + } + for key, value := range b { + if _, found := result[key]; !found { + result[key] = value.DeepCopy() + } + } + return result +} + +// SubtractWithNonNegativeResult - subtracts and returns result of a - b but +// makes sure we don't return negative values to prevent negative resource usage. +func SubtractWithNonNegativeResult(a corev1.ResourceList, b corev1.ResourceList) corev1.ResourceList { + zero := resource.MustParse("0") + + result := corev1.ResourceList{} + for key, value := range a { + quantity := value.DeepCopy() + if other, found := b[key]; found { + quantity.Sub(other) + } + if quantity.Cmp(zero) > 0 { + result[key] = quantity + } else { + result[key] = zero + } + } + + for key := range b { + if _, found := result[key]; !found { + result[key] = zero + } + } + return result +} + +// Subtract returns the result of a - b for each named resource +func Subtract(a corev1.ResourceList, b corev1.ResourceList) corev1.ResourceList { + result := corev1.ResourceList{} + for key, value := range a { + quantity := value.DeepCopy() + if other, found := b[key]; found { + quantity.Sub(other) + } + result[key] = quantity + } + for key, value := range b { + if _, found := result[key]; !found { + quantity := value.DeepCopy() + quantity.Neg() + result[key] = quantity + } + } + return result +} + +// Mask returns a new resource list that only has the values with the specified names +func Mask(resources corev1.ResourceList, names []corev1.ResourceName) corev1.ResourceList { + nameSet := ToSet(names) + result := corev1.ResourceList{} + for key, value := range resources { + if nameSet.Has(string(key)) { + result[key] = value.DeepCopy() + } + } + return result +} + +// ResourceNames returns a list of all resource names in the ResourceList +func ResourceNames(resources corev1.ResourceList) []corev1.ResourceName { + result := []corev1.ResourceName{} + for resourceName := range resources { + result = append(result, resourceName) + } + return result +} + +// Contains returns true if the specified item is in the list of items +func Contains(items []corev1.ResourceName, item corev1.ResourceName) bool { + for _, i := range items { + if i == item { + return true + } + } + return false +} + +// ContainsPrefix returns true if the specified item has a prefix that contained in given prefix Set +func ContainsPrefix(prefixSet []string, item corev1.ResourceName) bool { + for _, prefix := range prefixSet { + if strings.HasPrefix(string(item), prefix) { + return true + } + } + return false +} + +// Intersection returns the intersection of both list of resources, deduped and sorted +func Intersection(a []corev1.ResourceName, b []corev1.ResourceName) []corev1.ResourceName { + result := make([]corev1.ResourceName, 0, len(a)) + for _, item := range a { + if Contains(result, item) { + continue + } + if !Contains(b, item) { + continue + } + result = append(result, item) + } + sort.Slice(result, func(i, j int) bool { return result[i] < result[j] }) + return result +} + +// Difference returns the list of resources resulting from a-b, deduped and sorted +func Difference(a []corev1.ResourceName, b []corev1.ResourceName) []corev1.ResourceName { + result := make([]corev1.ResourceName, 0, len(a)) + for _, item := range a { + if Contains(b, item) || Contains(result, item) { + continue + } + result = append(result, item) + } + sort.Slice(result, func(i, j int) bool { return result[i] < result[j] }) + return result +} + +// IsZero returns true if each key maps to the quantity value 0 +func IsZero(a corev1.ResourceList) bool { + zero := resource.MustParse("0") + for _, v := range a { + if v.Cmp(zero) != 0 { + return false + } + } + return true +} + +// RemoveZeros returns a new resource list that only has no zero values +func RemoveZeros(a corev1.ResourceList) corev1.ResourceList { + result := corev1.ResourceList{} + for key, value := range a { + if !value.IsZero() { + result[key] = value + } + } + return result +} + +// IsNegative returns the set of resource names that have a negative value. +func IsNegative(a corev1.ResourceList) []corev1.ResourceName { + results := []corev1.ResourceName{} + zero := resource.MustParse("0") + for k, v := range a { + if v.Cmp(zero) < 0 { + results = append(results, k) + } + } + return results +} + +// ToSet takes a list of resource names and converts to a string set +func ToSet(resourceNames []corev1.ResourceName) sets.String { + result := sets.NewString() + for _, resourceName := range resourceNames { + result.Insert(string(resourceName)) + } + return result +} + +// CalculateUsage calculates and returns the requested ResourceList usage. +// If an error is returned, usage only contains the resources which encountered no calculation errors. +func CalculateUsage(namespaceName string, scopes []corev1.ResourceQuotaScope, hardLimits corev1.ResourceList, registry Registry, scopeSelector *corev1.ScopeSelector) (corev1.ResourceList, error) { + // find the intersection between the hard resources on the quota + // and the resources this controller can track to know what we can + // look to measure updated usage stats for + hardResources := ResourceNames(hardLimits) + potentialResources := []corev1.ResourceName{} + evaluators := registry.List() + for _, evaluator := range evaluators { + potentialResources = append(potentialResources, evaluator.MatchingResources(hardResources)...) + } + // NOTE: the intersection just removes duplicates since the evaluator match intersects with hard + matchedResources := Intersection(hardResources, potentialResources) + + errors := []error{} + + // sum the observed usage from each evaluator + newUsage := corev1.ResourceList{} + for _, evaluator := range evaluators { + // only trigger the evaluator if it matches a resource in the quota, otherwise, skip calculating anything + intersection := evaluator.MatchingResources(matchedResources) + if len(intersection) == 0 { + continue + } + + usageStatsOptions := UsageStatsOptions{Namespace: namespaceName, Scopes: scopes, Resources: intersection, ScopeSelector: scopeSelector} + stats, err := evaluator.UsageStats(usageStatsOptions) + if err != nil { + // remember the error + errors = append(errors, err) + // exclude resources which encountered calculation errors + matchedResources = Difference(matchedResources, intersection) + continue + } + newUsage = Add(newUsage, stats.Used) + } + + // mask the observed usage to only the set of resources tracked by this quota + // merge our observed usage with the quota usage status + // if the new usage is different than the last usage, we will need to do an update + newUsage = Mask(newUsage, matchedResources) + return newUsage, utilerrors.NewAggregate(errors) +} diff --git a/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index 9da0e2a099c..0936d6ef4e2 100644 --- a/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -29,18 +29,25 @@ import ( "strings" "time" + "go.opentelemetry.io/otel/attribute" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/apis/apiserver" egressmetrics "k8s.io/apiserver/pkg/server/egressselector/metrics" + "k8s.io/component-base/metrics/legacyregistry" + "k8s.io/component-base/tracing" "k8s.io/klog/v2" - utiltrace "k8s.io/utils/trace" client "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client" ) var directDialer utilnet.DialFunc = http.DefaultTransport.(*http.Transport).DialContext +func init() { + client.Metrics.RegisterMetrics(legacyregistry.Registerer()) +} + // EgressSelector is the map of network context type to context dialer, for network egress. type EgressSelector struct { egressToDialer map[EgressType]utilnet.DialFunc @@ -157,7 +164,11 @@ func (g *grpcProxier) proxy(ctx context.Context, addr string) (net.Conn, error) type proxyServerConnector interface { // connect establishes connection to the proxy server, and returns a // proxier based on the connection. - connect() (proxier, error) + // + // The provided Context must be non-nil. The context is used for connecting to the proxy only. + // If the context expires before the connection is complete, an error is returned. + // Once successfully connected to the proxy, any expiration of the context will not affect the connection. + connect(context.Context) (proxier, error) } type tcpHTTPConnectConnector struct { @@ -165,8 +176,11 @@ type tcpHTTPConnectConnector struct { tlsConfig *tls.Config } -func (t *tcpHTTPConnectConnector) connect() (proxier, error) { - conn, err := tls.Dial("tcp", t.proxyAddress, t.tlsConfig) +func (t *tcpHTTPConnectConnector) connect(ctx context.Context) (proxier, error) { + d := tls.Dialer{ + Config: t.tlsConfig, + } + conn, err := d.DialContext(ctx, "tcp", t.proxyAddress) if err != nil { return nil, err } @@ -177,8 +191,9 @@ type udsHTTPConnectConnector struct { udsName string } -func (u *udsHTTPConnectConnector) connect() (proxier, error) { - conn, err := net.Dial("unix", u.udsName) +func (u *udsHTTPConnectConnector) connect(ctx context.Context) (proxier, error) { + var d net.Dialer + conn, err := d.DialContext(ctx, "unix", u.udsName) if err != nil { return nil, err } @@ -189,18 +204,28 @@ type udsGRPCConnector struct { udsName string } -func (u *udsGRPCConnector) connect() (proxier, error) { +// connect establishes a connection to a proxy over gRPC. +// TODO At the moment, it does not use the provided context. +func (u *udsGRPCConnector) connect(_ context.Context) (proxier, error) { udsName := u.udsName - dialOption := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { - c, err := net.Dial("unix", udsName) + dialOption := grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + var d net.Dialer + c, err := d.DialContext(ctx, "unix", udsName) if err != nil { klog.Errorf("failed to create connection to uds name %s, error: %v", udsName, err) } return c, err }) - ctx := context.TODO() - tunnel, err := client.CreateSingleUseGrpcTunnel(ctx, udsName, dialOption, grpc.WithInsecure()) + // CreateSingleUseGrpcTunnel() unfortunately couples dial and connection contexts. Because of that, + // we cannot use ctx just for dialing and control the connection lifetime separately. + // See https://github.com/kubernetes-sigs/apiserver-network-proxy/issues/357. + tunnelCtx := context.TODO() + tunnel, err := client.CreateSingleUseGrpcTunnel(tunnelCtx, udsName, dialOption, + grpc.WithBlock(), + grpc.WithReturnConnectionError(), + grpc.WithTimeout(30*time.Second), // matches http.DefaultTransport dial timeout + grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, err } @@ -223,10 +248,11 @@ func (d *dialerCreator) createDialer() utilnet.DialFunc { return directDialer } return func(ctx context.Context, network, addr string) (net.Conn, error) { - trace := utiltrace.New(fmt.Sprintf("Proxy via %s protocol over %s", d.options.protocol, d.options.transport), utiltrace.Field{Key: "address", Value: addr}) - defer trace.LogIfLong(500 * time.Millisecond) + ctx, span := tracing.Start(ctx, fmt.Sprintf("Proxy via %s protocol over %s", d.options.protocol, d.options.transport), attribute.String("address", addr)) + defer span.End(500 * time.Millisecond) start := egressmetrics.Metrics.Clock().Now() - proxier, err := d.connector.connect() + egressmetrics.Metrics.ObserveDialStart(d.options.protocol, d.options.transport) + proxier, err := d.connector.connect(ctx) if err != nil { egressmetrics.Metrics.ObserveDialFailure(d.options.protocol, d.options.transport, egressmetrics.StageConnect) return nil, err diff --git a/vendor/k8s.io/apiserver/pkg/server/egressselector/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/server/egressselector/metrics/metrics.go index af384618181..2e39947cd5e 100644 --- a/vendor/k8s.io/apiserver/pkg/server/egressselector/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/server/egressselector/metrics/metrics.go @@ -53,12 +53,24 @@ var ( // DialMetrics instruments dials to proxy server with prometheus metrics. type DialMetrics struct { clock clock.Clock + starts *metrics.CounterVec latencies *metrics.HistogramVec failures *metrics.CounterVec } // newDialMetrics create a new DialMetrics, configured with default metric names. func newDialMetrics() *DialMetrics { + starts := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dial_start_total", + Help: "Dial starts, labeled by the protocol (http-connect or grpc) and transport (tcp or uds).", + StabilityLevel: metrics.ALPHA, + }, + []string{"protocol", "transport"}, + ) + latencies := metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace: namespace, @@ -82,9 +94,10 @@ func newDialMetrics() *DialMetrics { []string{"protocol", "transport", "stage"}, ) + legacyregistry.MustRegister(starts) legacyregistry.MustRegister(latencies) legacyregistry.MustRegister(failures) - return &DialMetrics{latencies: latencies, failures: failures, clock: clock.RealClock{}} + return &DialMetrics{starts: starts, latencies: latencies, failures: failures, clock: clock.RealClock{}} } // Clock returns the clock. @@ -99,10 +112,16 @@ func (m *DialMetrics) SetClock(c clock.Clock) { // Reset resets the metrics. func (m *DialMetrics) Reset() { + m.starts.Reset() m.latencies.Reset() m.failures.Reset() } +// ObserveDialStart records the start of a dial attempt, labeled by protocol, transport. +func (m *DialMetrics) ObserveDialStart(protocol, transport string) { + m.starts.WithLabelValues(protocol, transport).Inc() +} + // ObserveDialLatency records the latency of a dial, labeled by protocol, transport. func (m *DialMetrics) ObserveDialLatency(elapsed time.Duration, protocol, transport string) { m.latencies.WithLabelValues(protocol, transport).Observe(elapsed.Seconds()) diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/authentication.go b/vendor/k8s.io/apiserver/pkg/util/webhook/authentication.go index d61e46aaf76..a69506de690 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/authentication.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/authentication.go @@ -35,7 +35,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/component-base/traces" + tracing "k8s.io/component-base/tracing" ) // AuthenticationInfoResolverWrapper can be used to inject Dial function to the @@ -47,7 +47,7 @@ func NewDefaultAuthenticationInfoResolverWrapper( proxyTransport *http.Transport, egressSelector *egressselector.EgressSelector, kubeapiserverClientConfig *rest.Config, - tp *trace.TracerProvider) AuthenticationInfoResolverWrapper { + tp trace.TracerProvider) AuthenticationInfoResolverWrapper { webhookAuthResolverWrapper := func(delegate AuthenticationInfoResolver) AuthenticationInfoResolver { return &AuthenticationInfoResolverDelegator{ @@ -60,7 +60,7 @@ func NewDefaultAuthenticationInfoResolverWrapper( return nil, err } if feature.DefaultFeatureGate.Enabled(features.APIServerTracing) { - ret.Wrap(traces.WrapperFor(tp)) + ret.Wrap(tracing.WrapperFor(tp)) } if egressSelector != nil { @@ -85,7 +85,7 @@ func NewDefaultAuthenticationInfoResolverWrapper( return nil, err } if feature.DefaultFeatureGate.Enabled(features.APIServerTracing) { - ret.Wrap(traces.WrapperFor(tp)) + ret.Wrap(tracing.WrapperFor(tp)) } if egressSelector != nil { diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/client.go b/vendor/k8s.io/apiserver/pkg/util/webhook/client.go index 514fd9551cc..ec3585b45a9 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/client.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/client.go @@ -141,7 +141,7 @@ func (cm *ClientManager) HookClient(cc ClientConfig) (*rest.RESTClient, error) { // Use http/1.1 instead of http/2. // This is a workaround for http/2-enabled clients not load-balancing concurrent requests to multiple backends. - // See http://issue.k8s.io/75791 for details. + // See https://issue.k8s.io/75791 for details. cfg.NextProtos = []string{"http/1.1"} cfg.ContentConfig.NegotiatedSerializer = cm.negotiatedSerializer diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/serviceresolver.go b/vendor/k8s.io/apiserver/pkg/util/webhook/serviceresolver.go index da140b1f0db..fcd953da3cd 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/serviceresolver.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/serviceresolver.go @@ -38,7 +38,8 @@ func NewDefaultServiceResolver() ServiceResolver { // note that the name, namespace, and port are required and by default all // created addresses use HTTPS scheme. // for example: -// name=ross namespace=andromeda resolves to https://ross.andromeda.svc:443 +// +// name=ross namespace=andromeda resolves to https://ross.andromeda.svc:443 func (sr defaultServiceResolver) ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) { if len(name) == 0 || len(namespace) == 0 || port == 0 { return nil, errors.New("cannot resolve an empty service name or namespace or port") diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/validation.go b/vendor/k8s.io/apiserver/pkg/util/webhook/validation.go index c46cc9d6b80..695c00d1763 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/validation.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/validation.go @@ -36,7 +36,7 @@ func ValidateWebhookURL(fldPath *field.Path, URL string, forceHttps bool) field. allErrors = append(allErrors, field.Invalid(fldPath, u.Scheme, "'https' is the only allowed URL scheme"+form)) } if len(u.Host) == 0 { - allErrors = append(allErrors, field.Invalid(fldPath, u.Host, "host must be provided"+form)) + allErrors = append(allErrors, field.Invalid(fldPath, u.Host, "host must be specified"+form)) } if u.User != nil { allErrors = append(allErrors, field.Invalid(fldPath, u.User.String(), "user information is not permitted in the URL")) diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go index 06a74c1cd31..45143bf6efb 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go @@ -121,7 +121,7 @@ func WithExponentialBackoff(ctx context.Context, retryBackoff wait.Backoff, webh // having a webhook error allows us to track the last actual webhook error for requests that // are later cancelled or time out. var webhookErr error - err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func() (bool, error) { + err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func(_ context.Context) (bool, error) { webhookErr = webhookFn() if shouldRetry(webhookErr) { return false, nil diff --git a/vendor/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go b/vendor/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go index 9f1e34c4d44..464510ea8f1 100644 --- a/vendor/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go +++ b/vendor/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go @@ -75,17 +75,17 @@ func (c *counterRaiser) IncreaseMetricsCounter(req *http.Request) { // NewDeprecatedCertificateRoundTripperWrapperConstructor returns a RoundTripper wrapper that's usable within ClientConfig.Wrap. // // It increases the `missingSAN` counter whenever: -// 1. we get a x509.HostnameError with string `x509: certificate relies on legacy Common Name field` -// which indicates an error caused by the deprecation of Common Name field when veryfing remote -// hostname -// 2. the server certificate in response contains no SAN. This indicates that this binary run -// with the GODEBUG=x509ignoreCN=0 in env +// 1. we get a x509.HostnameError with string `x509: certificate relies on legacy Common Name field` +// which indicates an error caused by the deprecation of Common Name field when veryfing remote +// hostname +// 2. the server certificate in response contains no SAN. This indicates that this binary run +// with the GODEBUG=x509ignoreCN=0 in env // // It increases the `sha1` counter whenever: -// 1. we get a x509.InsecureAlgorithmError with string `SHA1` -// which indicates an error caused by an insecure SHA1 signature -// 2. the server certificate in response contains a SHA1WithRSA or ECDSAWithSHA1 signature. -// This indicates that this binary run with the GODEBUG=x509sha1=1 in env +// 1. we get a x509.InsecureAlgorithmError with string `SHA1` +// which indicates an error caused by an insecure SHA1 signature +// 2. the server certificate in response contains a SHA1WithRSA or ECDSAWithSHA1 signature. +// This indicates that this binary run with the GODEBUG=x509sha1=1 in env func NewDeprecatedCertificateRoundTripperWrapperConstructor(missingSAN, sha1 *metrics.Counter) func(rt http.RoundTripper) http.RoundTripper { return func(rt http.RoundTripper) http.RoundTripper { return &x509DeprecatedCertificateMetricsRTWrapper{ diff --git a/vendor/k8s.io/apiserver/pkg/warning/context.go b/vendor/k8s.io/apiserver/pkg/warning/context.go new file mode 100644 index 00000000000..2009225458a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/warning/context.go @@ -0,0 +1,60 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package warning + +import ( + "context" +) + +// The key type is unexported to prevent collisions +type key int + +const ( + // warningRecorderKey is the context key for the warning recorder. + warningRecorderKey key = iota +) + +// Recorder provides a method for recording warnings +type Recorder interface { + // AddWarning adds the specified warning to the response. + // agent must be valid UTF-8, and must not contain spaces, quotes, backslashes, or control characters. + // text must be valid UTF-8, and must not contain control characters. + AddWarning(agent, text string) +} + +// WithWarningRecorder returns a new context that wraps the provided context and contains the provided Recorder implementation. +// The returned context can be passed to AddWarning(). +func WithWarningRecorder(ctx context.Context, recorder Recorder) context.Context { + return context.WithValue(ctx, warningRecorderKey, recorder) +} + +func warningRecorderFrom(ctx context.Context) (Recorder, bool) { + recorder, ok := ctx.Value(warningRecorderKey).(Recorder) + return recorder, ok +} + +// AddWarning records a warning for the specified agent and text to the Recorder added to the provided context using WithWarningRecorder(). +// If no Recorder exists in the provided context, this is a no-op. +// agent must be valid UTF-8, and must not contain spaces, quotes, backslashes, or control characters. +// text must be valid UTF-8, and must not contain control characters. +func AddWarning(ctx context.Context, agent string, text string) { + recorder, ok := warningRecorderFrom(ctx) + if !ok { + return + } + recorder.AddWarning(agent, text) +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go new file mode 100644 index 00000000000..ea1dc377b97 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go index eba37bafdbd..faff51a0415 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go @@ -37,6 +37,7 @@ type MutatingWebhookApplyConfiguration struct { TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -139,3 +140,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go index d0691de107c..613856bac7f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go @@ -36,6 +36,7 @@ type ValidatingWebhookApplyConfiguration struct { SideEffects *admissionregistrationv1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -130,3 +131,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go new file mode 100644 index 00000000000..023695139d4 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// AuditAnnotationApplyConfiguration represents an declarative configuration of the AuditAnnotation type for use +// with apply. +type AuditAnnotationApplyConfiguration struct { + Key *string `json:"key,omitempty"` + ValueExpression *string `json:"valueExpression,omitempty"` +} + +// AuditAnnotationApplyConfiguration constructs an declarative configuration of the AuditAnnotation type for use with +// apply. +func AuditAnnotation() *AuditAnnotationApplyConfiguration { + return &AuditAnnotationApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithKey(value string) *AuditAnnotationApplyConfiguration { + b.Key = &value + return b +} + +// WithValueExpression sets the ValueExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ValueExpression field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithValueExpression(value string) *AuditAnnotationApplyConfiguration { + b.ValueExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go new file mode 100644 index 00000000000..f8b511f512b --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ExpressionWarningApplyConfiguration represents an declarative configuration of the ExpressionWarning type for use +// with apply. +type ExpressionWarningApplyConfiguration struct { + FieldRef *string `json:"fieldRef,omitempty"` + Warning *string `json:"warning,omitempty"` +} + +// ExpressionWarningApplyConfiguration constructs an declarative configuration of the ExpressionWarning type for use with +// apply. +func ExpressionWarning() *ExpressionWarningApplyConfiguration { + return &ExpressionWarningApplyConfiguration{} +} + +// WithFieldRef sets the FieldRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the FieldRef field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithFieldRef(value string) *ExpressionWarningApplyConfiguration { + b.FieldRef = &value + return b +} + +// WithWarning sets the Warning field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Warning field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithWarning(value string) *ExpressionWarningApplyConfiguration { + b.Warning = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go new file mode 100644 index 00000000000..186c750f96e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go new file mode 100644 index 00000000000..a6710ac7ed9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// MatchResourcesApplyConfiguration represents an declarative configuration of the MatchResources type for use +// with apply. +type MatchResourcesApplyConfiguration struct { + NamespaceSelector *v1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` + ObjectSelector *v1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` + ResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"resourceRules,omitempty"` + ExcludeResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"excludeResourceRules,omitempty"` + MatchPolicy *admissionregistrationv1alpha1.MatchPolicyType `json:"matchPolicy,omitempty"` +} + +// MatchResourcesApplyConfiguration constructs an declarative configuration of the MatchResources type for use with +// apply. +func MatchResources() *MatchResourcesApplyConfiguration { + return &MatchResourcesApplyConfiguration{} +} + +// WithNamespaceSelector sets the NamespaceSelector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NamespaceSelector field is set to the value of the last call. +func (b *MatchResourcesApplyConfiguration) WithNamespaceSelector(value *v1.LabelSelectorApplyConfiguration) *MatchResourcesApplyConfiguration { + b.NamespaceSelector = value + return b +} + +// WithObjectSelector sets the ObjectSelector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObjectSelector field is set to the value of the last call. +func (b *MatchResourcesApplyConfiguration) WithObjectSelector(value *v1.LabelSelectorApplyConfiguration) *MatchResourcesApplyConfiguration { + b.ObjectSelector = value + return b +} + +// WithResourceRules adds the given value to the ResourceRules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceRules field. +func (b *MatchResourcesApplyConfiguration) WithResourceRules(values ...*NamedRuleWithOperationsApplyConfiguration) *MatchResourcesApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceRules") + } + b.ResourceRules = append(b.ResourceRules, *values[i]) + } + return b +} + +// WithExcludeResourceRules adds the given value to the ExcludeResourceRules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ExcludeResourceRules field. +func (b *MatchResourcesApplyConfiguration) WithExcludeResourceRules(values ...*NamedRuleWithOperationsApplyConfiguration) *MatchResourcesApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithExcludeResourceRules") + } + b.ExcludeResourceRules = append(b.ExcludeResourceRules, *values[i]) + } + return b +} + +// WithMatchPolicy sets the MatchPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchPolicy field is set to the value of the last call. +func (b *MatchResourcesApplyConfiguration) WithMatchPolicy(value admissionregistrationv1alpha1.MatchPolicyType) *MatchResourcesApplyConfiguration { + b.MatchPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go new file mode 100644 index 00000000000..bb2a7ba890f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go @@ -0,0 +1,95 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + v1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" +) + +// NamedRuleWithOperationsApplyConfiguration represents an declarative configuration of the NamedRuleWithOperations type for use +// with apply. +type NamedRuleWithOperationsApplyConfiguration struct { + ResourceNames []string `json:"resourceNames,omitempty"` + v1.RuleWithOperationsApplyConfiguration `json:",inline"` +} + +// NamedRuleWithOperationsApplyConfiguration constructs an declarative configuration of the NamedRuleWithOperations type for use with +// apply. +func NamedRuleWithOperations() *NamedRuleWithOperationsApplyConfiguration { + return &NamedRuleWithOperationsApplyConfiguration{} +} + +// WithResourceNames adds the given value to the ResourceNames field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceNames field. +func (b *NamedRuleWithOperationsApplyConfiguration) WithResourceNames(values ...string) *NamedRuleWithOperationsApplyConfiguration { + for i := range values { + b.ResourceNames = append(b.ResourceNames, values[i]) + } + return b +} + +// WithOperations adds the given value to the Operations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Operations field. +func (b *NamedRuleWithOperationsApplyConfiguration) WithOperations(values ...admissionregistrationv1.OperationType) *NamedRuleWithOperationsApplyConfiguration { + for i := range values { + b.Operations = append(b.Operations, values[i]) + } + return b +} + +// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the APIGroups field. +func (b *NamedRuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *NamedRuleWithOperationsApplyConfiguration { + for i := range values { + b.APIGroups = append(b.APIGroups, values[i]) + } + return b +} + +// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the APIVersions field. +func (b *NamedRuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *NamedRuleWithOperationsApplyConfiguration { + for i := range values { + b.APIVersions = append(b.APIVersions, values[i]) + } + return b +} + +// WithResources adds the given value to the Resources field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Resources field. +func (b *NamedRuleWithOperationsApplyConfiguration) WithResources(values ...string) *NamedRuleWithOperationsApplyConfiguration { + for i := range values { + b.Resources = append(b.Resources, values[i]) + } + return b +} + +// WithScope sets the Scope field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Scope field is set to the value of the last call. +func (b *NamedRuleWithOperationsApplyConfiguration) WithScope(value admissionregistrationv1.ScopeType) *NamedRuleWithOperationsApplyConfiguration { + b.Scope = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go new file mode 100644 index 00000000000..350993cea0f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ParamKindApplyConfiguration represents an declarative configuration of the ParamKind type for use +// with apply. +type ParamKindApplyConfiguration struct { + APIVersion *string `json:"apiVersion,omitempty"` + Kind *string `json:"kind,omitempty"` +} + +// ParamKindApplyConfiguration constructs an declarative configuration of the ParamKind type for use with +// apply. +func ParamKind() *ParamKindApplyConfiguration { + return &ParamKindApplyConfiguration{} +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ParamKindApplyConfiguration) WithAPIVersion(value string) *ParamKindApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ParamKindApplyConfiguration) WithKind(value string) *ParamKindApplyConfiguration { + b.Kind = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go new file mode 100644 index 00000000000..1102f65f31a --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ParamRefApplyConfiguration represents an declarative configuration of the ParamRef type for use +// with apply. +type ParamRefApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Namespace *string `json:"namespace,omitempty"` +} + +// ParamRefApplyConfiguration constructs an declarative configuration of the ParamRef type for use with +// apply. +func ParamRef() *ParamRefApplyConfiguration { + return &ParamRefApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ParamRefApplyConfiguration) WithName(value string) *ParamRefApplyConfiguration { + b.Name = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ParamRefApplyConfiguration) WithNamespace(value string) *ParamRefApplyConfiguration { + b.Namespace = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go new file mode 100644 index 00000000000..42a91707105 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// TypeCheckingApplyConfiguration represents an declarative configuration of the TypeChecking type for use +// with apply. +type TypeCheckingApplyConfiguration struct { + ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` +} + +// TypeCheckingApplyConfiguration constructs an declarative configuration of the TypeChecking type for use with +// apply. +func TypeChecking() *TypeCheckingApplyConfiguration { + return &TypeCheckingApplyConfiguration{} +} + +// WithExpressionWarnings adds the given value to the ExpressionWarnings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ExpressionWarnings field. +func (b *TypeCheckingApplyConfiguration) WithExpressionWarnings(values ...*ExpressionWarningApplyConfiguration) *TypeCheckingApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithExpressionWarnings") + } + b.ExpressionWarnings = append(b.ExpressionWarnings, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go new file mode 100644 index 00000000000..c860b85cf74 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -0,0 +1,256 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ValidatingAdmissionPolicyApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicy type for use +// with apply. +type ValidatingAdmissionPolicyApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` + Status *ValidatingAdmissionPolicyStatusApplyConfiguration `json:"status,omitempty"` +} + +// ValidatingAdmissionPolicy constructs an declarative configuration of the ValidatingAdmissionPolicy type for use with +// apply. +func ValidatingAdmissionPolicy(name string) *ValidatingAdmissionPolicyApplyConfiguration { + b := &ValidatingAdmissionPolicyApplyConfiguration{} + b.WithName(name) + b.WithKind("ValidatingAdmissionPolicy") + b.WithAPIVersion("admissionregistration.k8s.io/v1alpha1") + return b +} + +// ExtractValidatingAdmissionPolicy extracts the applied configuration owned by fieldManager from +// validatingAdmissionPolicy. If no managedFields are found in validatingAdmissionPolicy for fieldManager, a +// ValidatingAdmissionPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// validatingAdmissionPolicy must be a unmodified ValidatingAdmissionPolicy API object that was retrieved from the Kubernetes API. +// ExtractValidatingAdmissionPolicy provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractValidatingAdmissionPolicy(validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, fieldManager string) (*ValidatingAdmissionPolicyApplyConfiguration, error) { + return extractValidatingAdmissionPolicy(validatingAdmissionPolicy, fieldManager, "") +} + +// ExtractValidatingAdmissionPolicyStatus is the same as ExtractValidatingAdmissionPolicy except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractValidatingAdmissionPolicyStatus(validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, fieldManager string) (*ValidatingAdmissionPolicyApplyConfiguration, error) { + return extractValidatingAdmissionPolicy(validatingAdmissionPolicy, fieldManager, "status") +} + +func extractValidatingAdmissionPolicy(validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, fieldManager string, subresource string) (*ValidatingAdmissionPolicyApplyConfiguration, error) { + b := &ValidatingAdmissionPolicyApplyConfiguration{} + err := managedfields.ExtractInto(validatingAdmissionPolicy, internal.Parser().Type("io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(validatingAdmissionPolicy.Name) + + b.WithKind("ValidatingAdmissionPolicy") + b.WithAPIVersion("admissionregistration.k8s.io/v1alpha1") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithKind(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithAPIVersion(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithName(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithGenerateName(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithNamespace(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithUID(value types.UID) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithResourceVersion(value string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithGeneration(value int64) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithLabels(entries map[string]string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithFinalizers(values ...string) *ValidatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ValidatingAdmissionPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithSpec(value *ValidatingAdmissionPolicySpecApplyConfiguration) *ValidatingAdmissionPolicyApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithStatus(value *ValidatingAdmissionPolicyStatusApplyConfiguration) *ValidatingAdmissionPolicyApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go new file mode 100644 index 00000000000..dc08226404f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -0,0 +1,247 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ValidatingAdmissionPolicyBindingApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyBinding type for use +// with apply. +type ValidatingAdmissionPolicyBindingApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ValidatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` +} + +// ValidatingAdmissionPolicyBinding constructs an declarative configuration of the ValidatingAdmissionPolicyBinding type for use with +// apply. +func ValidatingAdmissionPolicyBinding(name string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b := &ValidatingAdmissionPolicyBindingApplyConfiguration{} + b.WithName(name) + b.WithKind("ValidatingAdmissionPolicyBinding") + b.WithAPIVersion("admissionregistration.k8s.io/v1alpha1") + return b +} + +// ExtractValidatingAdmissionPolicyBinding extracts the applied configuration owned by fieldManager from +// validatingAdmissionPolicyBinding. If no managedFields are found in validatingAdmissionPolicyBinding for fieldManager, a +// ValidatingAdmissionPolicyBindingApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// validatingAdmissionPolicyBinding must be a unmodified ValidatingAdmissionPolicyBinding API object that was retrieved from the Kubernetes API. +// ExtractValidatingAdmissionPolicyBinding provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractValidatingAdmissionPolicyBinding(validatingAdmissionPolicyBinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, fieldManager string) (*ValidatingAdmissionPolicyBindingApplyConfiguration, error) { + return extractValidatingAdmissionPolicyBinding(validatingAdmissionPolicyBinding, fieldManager, "") +} + +// ExtractValidatingAdmissionPolicyBindingStatus is the same as ExtractValidatingAdmissionPolicyBinding except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractValidatingAdmissionPolicyBindingStatus(validatingAdmissionPolicyBinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, fieldManager string) (*ValidatingAdmissionPolicyBindingApplyConfiguration, error) { + return extractValidatingAdmissionPolicyBinding(validatingAdmissionPolicyBinding, fieldManager, "status") +} + +func extractValidatingAdmissionPolicyBinding(validatingAdmissionPolicyBinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, fieldManager string, subresource string) (*ValidatingAdmissionPolicyBindingApplyConfiguration, error) { + b := &ValidatingAdmissionPolicyBindingApplyConfiguration{} + err := managedfields.ExtractInto(validatingAdmissionPolicyBinding, internal.Parser().Type("io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(validatingAdmissionPolicyBinding.Name) + + b.WithKind("ValidatingAdmissionPolicyBinding") + b.WithAPIVersion("admissionregistration.k8s.io/v1alpha1") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithKind(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithAPIVersion(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithName(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithGenerateName(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithNamespace(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithUID(value types.UID) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithResourceVersion(value string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithGeneration(value int64) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithLabels(entries map[string]string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithAnnotations(entries map[string]string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithFinalizers(values ...string) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingApplyConfiguration) WithSpec(value *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) *ValidatingAdmissionPolicyBindingApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go new file mode 100644 index 00000000000..c9a4ff7ab42 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go @@ -0,0 +1,72 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" +) + +// ValidatingAdmissionPolicyBindingSpecApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use +// with apply. +type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { + PolicyName *string `json:"policyName,omitempty"` + ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` + MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` + ValidationActions []admissionregistrationv1alpha1.ValidationAction `json:"validationActions,omitempty"` +} + +// ValidatingAdmissionPolicyBindingSpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use with +// apply. +func ValidatingAdmissionPolicyBindingSpec() *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + return &ValidatingAdmissionPolicyBindingSpecApplyConfiguration{} +} + +// WithPolicyName sets the PolicyName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PolicyName field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithPolicyName(value string) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + b.PolicyName = &value + return b +} + +// WithParamRef sets the ParamRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParamRef field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithParamRef(value *ParamRefApplyConfiguration) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + b.ParamRef = value + return b +} + +// WithMatchResources sets the MatchResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchResources field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithMatchResources(value *MatchResourcesApplyConfiguration) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + b.MatchResources = value + return b +} + +// WithValidationActions adds the given value to the ValidationActions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ValidationActions field. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithValidationActions(values ...admissionregistrationv1alpha1.ValidationAction) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + for i := range values { + b.ValidationActions = append(b.ValidationActions, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go new file mode 100644 index 00000000000..f674b5b1ec2 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go @@ -0,0 +1,103 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" +) + +// ValidatingAdmissionPolicySpecApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicySpec type for use +// with apply. +type ValidatingAdmissionPolicySpecApplyConfiguration struct { + ParamKind *ParamKindApplyConfiguration `json:"paramKind,omitempty"` + MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` + Validations []ValidationApplyConfiguration `json:"validations,omitempty"` + FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"` + AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` +} + +// ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with +// apply. +func ValidatingAdmissionPolicySpec() *ValidatingAdmissionPolicySpecApplyConfiguration { + return &ValidatingAdmissionPolicySpecApplyConfiguration{} +} + +// WithParamKind sets the ParamKind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParamKind field is set to the value of the last call. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithParamKind(value *ParamKindApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + b.ParamKind = value + return b +} + +// WithMatchConstraints sets the MatchConstraints field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchConstraints field is set to the value of the last call. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConstraints(value *MatchResourcesApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + b.MatchConstraints = value + return b +} + +// WithValidations adds the given value to the Validations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Validations field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithValidations(values ...*ValidationApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithValidations") + } + b.Validations = append(b.Validations, *values[i]) + } + return b +} + +// WithFailurePolicy sets the FailurePolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the FailurePolicy field is set to the value of the last call. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithFailurePolicy(value admissionregistrationv1alpha1.FailurePolicyType) *ValidatingAdmissionPolicySpecApplyConfiguration { + b.FailurePolicy = &value + return b +} + +// WithAuditAnnotations adds the given value to the AuditAnnotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the AuditAnnotations field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithAuditAnnotations(values ...*AuditAnnotationApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithAuditAnnotations") + } + b.AuditAnnotations = append(b.AuditAnnotations, *values[i]) + } + return b +} + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go new file mode 100644 index 00000000000..821184c8a85 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ValidatingAdmissionPolicyStatusApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyStatus type for use +// with apply. +type ValidatingAdmissionPolicyStatusApplyConfiguration struct { + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ValidatingAdmissionPolicyStatusApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyStatus type for use with +// apply. +func ValidatingAdmissionPolicyStatus() *ValidatingAdmissionPolicyStatusApplyConfiguration { + return &ValidatingAdmissionPolicyStatusApplyConfiguration{} +} + +// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObservedGeneration field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithObservedGeneration(value int64) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.ObservedGeneration = &value + return b +} + +// WithTypeChecking sets the TypeChecking field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TypeChecking field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithTypeChecking(value *TypeCheckingApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.TypeChecking = value + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go new file mode 100644 index 00000000000..9a5fc8475a7 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ValidationApplyConfiguration represents an declarative configuration of the Validation type for use +// with apply. +type ValidationApplyConfiguration struct { + Expression *string `json:"expression,omitempty"` + Message *string `json:"message,omitempty"` + Reason *v1.StatusReason `json:"reason,omitempty"` + MessageExpression *string `json:"messageExpression,omitempty"` +} + +// ValidationApplyConfiguration constructs an declarative configuration of the Validation type for use with +// apply. +func Validation() *ValidationApplyConfiguration { + return &ValidationApplyConfiguration{} +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithExpression(value string) *ValidationApplyConfiguration { + b.Expression = &value + return b +} + +// WithMessage sets the Message field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Message field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithMessage(value string) *ValidationApplyConfiguration { + b.Message = &value + return b +} + +// WithReason sets the Reason field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Reason field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithReason(value v1.StatusReason) *ValidationApplyConfiguration { + b.Reason = &value + return b +} + +// WithMessageExpression sets the MessageExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MessageExpression field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithMessageExpression(value string) *ValidationApplyConfiguration { + b.MessageExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go new file mode 100644 index 00000000000..d099b6b6eae --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go index ddb728aff8f..54845341f48 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go @@ -20,7 +20,8 @@ package v1beta1 import ( admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" + v1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" ) // MutatingWebhookApplyConfiguration represents an declarative configuration of the MutatingWebhook type for use @@ -28,15 +29,16 @@ import ( type MutatingWebhookApplyConfiguration struct { Name *string `json:"name,omitempty"` ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - Rules []RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` + Rules []v1.RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` FailurePolicy *admissionregistrationv1beta1.FailurePolicyType `json:"failurePolicy,omitempty"` MatchPolicy *admissionregistrationv1beta1.MatchPolicyType `json:"matchPolicy,omitempty"` - NamespaceSelector *v1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - ObjectSelector *v1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` + NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` + ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1beta1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -64,7 +66,7 @@ func (b *MutatingWebhookApplyConfiguration) WithClientConfig(value *WebhookClien // WithRules adds the given value to the Rules field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Rules field. -func (b *MutatingWebhookApplyConfiguration) WithRules(values ...*RuleWithOperationsApplyConfiguration) *MutatingWebhookApplyConfiguration { +func (b *MutatingWebhookApplyConfiguration) WithRules(values ...*v1.RuleWithOperationsApplyConfiguration) *MutatingWebhookApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithRules") @@ -93,7 +95,7 @@ func (b *MutatingWebhookApplyConfiguration) WithMatchPolicy(value admissionregis // WithNamespaceSelector sets the NamespaceSelector field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the NamespaceSelector field is set to the value of the last call. -func (b *MutatingWebhookApplyConfiguration) WithNamespaceSelector(value *v1.LabelSelectorApplyConfiguration) *MutatingWebhookApplyConfiguration { +func (b *MutatingWebhookApplyConfiguration) WithNamespaceSelector(value *metav1.LabelSelectorApplyConfiguration) *MutatingWebhookApplyConfiguration { b.NamespaceSelector = value return b } @@ -101,7 +103,7 @@ func (b *MutatingWebhookApplyConfiguration) WithNamespaceSelector(value *v1.Labe // WithObjectSelector sets the ObjectSelector field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ObjectSelector field is set to the value of the last call. -func (b *MutatingWebhookApplyConfiguration) WithObjectSelector(value *v1.LabelSelectorApplyConfiguration) *MutatingWebhookApplyConfiguration { +func (b *MutatingWebhookApplyConfiguration) WithObjectSelector(value *metav1.LabelSelectorApplyConfiguration) *MutatingWebhookApplyConfiguration { b.ObjectSelector = value return b } @@ -139,3 +141,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go deleted file mode 100644 index 21151b99809..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/admissionregistration/v1beta1" -) - -// RuleApplyConfiguration represents an declarative configuration of the Rule type for use -// with apply. -type RuleApplyConfiguration struct { - APIGroups []string `json:"apiGroups,omitempty"` - APIVersions []string `json:"apiVersions,omitempty"` - Resources []string `json:"resources,omitempty"` - Scope *v1beta1.ScopeType `json:"scope,omitempty"` -} - -// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with -// apply. -func Rule() *RuleApplyConfiguration { - return &RuleApplyConfiguration{} -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleApplyConfiguration) WithAPIGroups(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleApplyConfiguration) WithAPIVersions(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleApplyConfiguration) WithResources(values ...string) *RuleApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleApplyConfiguration) WithScope(value v1beta1.ScopeType) *RuleApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go deleted file mode 100644 index e072edb85a1..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/admissionregistration/v1beta1" -) - -// RuleWithOperationsApplyConfiguration represents an declarative configuration of the RuleWithOperations type for use -// with apply. -type RuleWithOperationsApplyConfiguration struct { - Operations []v1beta1.OperationType `json:"operations,omitempty"` - RuleApplyConfiguration `json:",inline"` -} - -// RuleWithOperationsApplyConfiguration constructs an declarative configuration of the RuleWithOperations type for use with -// apply. -func RuleWithOperations() *RuleWithOperationsApplyConfiguration { - return &RuleWithOperationsApplyConfiguration{} -} - -// WithOperations adds the given value to the Operations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Operations field. -func (b *RuleWithOperationsApplyConfiguration) WithOperations(values ...v1beta1.OperationType) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Operations = append(b.Operations, values[i]) - } - return b -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleWithOperationsApplyConfiguration) WithResources(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleWithOperationsApplyConfiguration) WithScope(value v1beta1.ScopeType) *RuleWithOperationsApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go index 8ca0e9cbeb6..8c5c341bade 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go @@ -20,7 +20,8 @@ package v1beta1 import ( admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" + v1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" ) // ValidatingWebhookApplyConfiguration represents an declarative configuration of the ValidatingWebhook type for use @@ -28,14 +29,15 @@ import ( type ValidatingWebhookApplyConfiguration struct { Name *string `json:"name,omitempty"` ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - Rules []RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` + Rules []v1.RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` FailurePolicy *admissionregistrationv1beta1.FailurePolicyType `json:"failurePolicy,omitempty"` MatchPolicy *admissionregistrationv1beta1.MatchPolicyType `json:"matchPolicy,omitempty"` - NamespaceSelector *v1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - ObjectSelector *v1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` + NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` + ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -63,7 +65,7 @@ func (b *ValidatingWebhookApplyConfiguration) WithClientConfig(value *WebhookCli // WithRules adds the given value to the Rules field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Rules field. -func (b *ValidatingWebhookApplyConfiguration) WithRules(values ...*RuleWithOperationsApplyConfiguration) *ValidatingWebhookApplyConfiguration { +func (b *ValidatingWebhookApplyConfiguration) WithRules(values ...*v1.RuleWithOperationsApplyConfiguration) *ValidatingWebhookApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithRules") @@ -92,7 +94,7 @@ func (b *ValidatingWebhookApplyConfiguration) WithMatchPolicy(value admissionreg // WithNamespaceSelector sets the NamespaceSelector field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the NamespaceSelector field is set to the value of the last call. -func (b *ValidatingWebhookApplyConfiguration) WithNamespaceSelector(value *v1.LabelSelectorApplyConfiguration) *ValidatingWebhookApplyConfiguration { +func (b *ValidatingWebhookApplyConfiguration) WithNamespaceSelector(value *metav1.LabelSelectorApplyConfiguration) *ValidatingWebhookApplyConfiguration { b.NamespaceSelector = value return b } @@ -100,7 +102,7 @@ func (b *ValidatingWebhookApplyConfiguration) WithNamespaceSelector(value *v1.La // WithObjectSelector sets the ObjectSelector field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ObjectSelector field is set to the value of the last call. -func (b *ValidatingWebhookApplyConfiguration) WithObjectSelector(value *v1.LabelSelectorApplyConfiguration) *ValidatingWebhookApplyConfiguration { +func (b *ValidatingWebhookApplyConfiguration) WithObjectSelector(value *metav1.LabelSelectorApplyConfiguration) *ValidatingWebhookApplyConfiguration { b.ObjectSelector = value return b } @@ -130,3 +132,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetordinals.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetordinals.go new file mode 100644 index 00000000000..9778f1c4a04 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetordinals.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// StatefulSetOrdinalsApplyConfiguration represents an declarative configuration of the StatefulSetOrdinals type for use +// with apply. +type StatefulSetOrdinalsApplyConfiguration struct { + Start *int32 `json:"start,omitempty"` +} + +// StatefulSetOrdinalsApplyConfiguration constructs an declarative configuration of the StatefulSetOrdinals type for use with +// apply. +func StatefulSetOrdinals() *StatefulSetOrdinalsApplyConfiguration { + return &StatefulSetOrdinalsApplyConfiguration{} +} + +// WithStart sets the Start field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Start field is set to the value of the last call. +func (b *StatefulSetOrdinalsApplyConfiguration) WithStart(value int32) *StatefulSetOrdinalsApplyConfiguration { + b.Start = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetspec.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetspec.go index ee0ed40a569..81afdca5960 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1/statefulsetspec.go @@ -37,6 +37,7 @@ type StatefulSetSpecApplyConfiguration struct { RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicyApplyConfiguration `json:"persistentVolumeClaimRetentionPolicy,omitempty"` + Ordinals *StatefulSetOrdinalsApplyConfiguration `json:"ordinals,omitempty"` } // StatefulSetSpecApplyConfiguration constructs an declarative configuration of the StatefulSetSpec type for use with @@ -129,3 +130,11 @@ func (b *StatefulSetSpecApplyConfiguration) WithPersistentVolumeClaimRetentionPo b.PersistentVolumeClaimRetentionPolicy = value return b } + +// WithOrdinals sets the Ordinals field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Ordinals field is set to the value of the last call. +func (b *StatefulSetSpecApplyConfiguration) WithOrdinals(value *StatefulSetOrdinalsApplyConfiguration) *StatefulSetSpecApplyConfiguration { + b.Ordinals = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetordinals.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetordinals.go new file mode 100644 index 00000000000..8f349a2d27c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetordinals.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// StatefulSetOrdinalsApplyConfiguration represents an declarative configuration of the StatefulSetOrdinals type for use +// with apply. +type StatefulSetOrdinalsApplyConfiguration struct { + Start *int32 `json:"start,omitempty"` +} + +// StatefulSetOrdinalsApplyConfiguration constructs an declarative configuration of the StatefulSetOrdinals type for use with +// apply. +func StatefulSetOrdinals() *StatefulSetOrdinalsApplyConfiguration { + return &StatefulSetOrdinalsApplyConfiguration{} +} + +// WithStart sets the Start field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Start field is set to the value of the last call. +func (b *StatefulSetOrdinalsApplyConfiguration) WithStart(value int32) *StatefulSetOrdinalsApplyConfiguration { + b.Start = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetspec.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetspec.go index 886433d9ea3..1eb1ba7b039 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta1/statefulsetspec.go @@ -37,6 +37,7 @@ type StatefulSetSpecApplyConfiguration struct { RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicyApplyConfiguration `json:"persistentVolumeClaimRetentionPolicy,omitempty"` + Ordinals *StatefulSetOrdinalsApplyConfiguration `json:"ordinals,omitempty"` } // StatefulSetSpecApplyConfiguration constructs an declarative configuration of the StatefulSetSpec type for use with @@ -129,3 +130,11 @@ func (b *StatefulSetSpecApplyConfiguration) WithPersistentVolumeClaimRetentionPo b.PersistentVolumeClaimRetentionPolicy = value return b } + +// WithOrdinals sets the Ordinals field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Ordinals field is set to the value of the last call. +func (b *StatefulSetSpecApplyConfiguration) WithOrdinals(value *StatefulSetOrdinalsApplyConfiguration) *StatefulSetSpecApplyConfiguration { + b.Ordinals = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetordinals.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetordinals.go new file mode 100644 index 00000000000..c586da775ce --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetordinals.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +// StatefulSetOrdinalsApplyConfiguration represents an declarative configuration of the StatefulSetOrdinals type for use +// with apply. +type StatefulSetOrdinalsApplyConfiguration struct { + Start *int32 `json:"start,omitempty"` +} + +// StatefulSetOrdinalsApplyConfiguration constructs an declarative configuration of the StatefulSetOrdinals type for use with +// apply. +func StatefulSetOrdinals() *StatefulSetOrdinalsApplyConfiguration { + return &StatefulSetOrdinalsApplyConfiguration{} +} + +// WithStart sets the Start field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Start field is set to the value of the last call. +func (b *StatefulSetOrdinalsApplyConfiguration) WithStart(value int32) *StatefulSetOrdinalsApplyConfiguration { + b.Start = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetspec.go b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetspec.go index 08922cea576..b6165fbd9a2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apps/v1beta2/statefulsetspec.go @@ -37,6 +37,7 @@ type StatefulSetSpecApplyConfiguration struct { RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicyApplyConfiguration `json:"persistentVolumeClaimRetentionPolicy,omitempty"` + Ordinals *StatefulSetOrdinalsApplyConfiguration `json:"ordinals,omitempty"` } // StatefulSetSpecApplyConfiguration constructs an declarative configuration of the StatefulSetSpec type for use with @@ -129,3 +130,11 @@ func (b *StatefulSetSpecApplyConfiguration) WithPersistentVolumeClaimRetentionPo b.PersistentVolumeClaimRetentionPolicy = value return b } + +// WithOrdinals sets the Ordinals field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Ordinals field is set to the value of the last call. +func (b *StatefulSetSpecApplyConfiguration) WithOrdinals(value *StatefulSetOrdinalsApplyConfiguration) *StatefulSetSpecApplyConfiguration { + b.Ordinals = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go deleted file mode 100644 index 86601cc48a8..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// PodResourceMetricSourceApplyConfiguration represents an declarative configuration of the PodResourceMetricSource type for use -// with apply. -type PodResourceMetricSourceApplyConfiguration struct { - Name *v1.ResourceName `json:"name,omitempty"` - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// PodResourceMetricSourceApplyConfiguration constructs an declarative configuration of the PodResourceMetricSource type for use with -// apply. -func PodResourceMetricSource() *PodResourceMetricSourceApplyConfiguration { - return &PodResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *PodResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *PodResourceMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/jobspec.go b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/jobspec.go index e1424488947..839d88b64ec 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/jobspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/jobspec.go @@ -21,7 +21,7 @@ package v1 import ( batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/client-go/applyconfigurations/core/v1" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" ) // JobSpecApplyConfiguration represents an declarative configuration of the JobSpec type for use @@ -30,8 +30,9 @@ type JobSpecApplyConfiguration struct { Parallelism *int32 `json:"parallelism,omitempty"` Completions *int32 `json:"completions,omitempty"` ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"` + PodFailurePolicy *PodFailurePolicyApplyConfiguration `json:"podFailurePolicy,omitempty"` BackoffLimit *int32 `json:"backoffLimit,omitempty"` - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` + Selector *metav1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` ManualSelector *bool `json:"manualSelector,omitempty"` Template *corev1.PodTemplateSpecApplyConfiguration `json:"template,omitempty"` TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"` @@ -69,6 +70,14 @@ func (b *JobSpecApplyConfiguration) WithActiveDeadlineSeconds(value int64) *JobS return b } +// WithPodFailurePolicy sets the PodFailurePolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PodFailurePolicy field is set to the value of the last call. +func (b *JobSpecApplyConfiguration) WithPodFailurePolicy(value *PodFailurePolicyApplyConfiguration) *JobSpecApplyConfiguration { + b.PodFailurePolicy = value + return b +} + // WithBackoffLimit sets the BackoffLimit field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the BackoffLimit field is set to the value of the last call. @@ -80,7 +89,7 @@ func (b *JobSpecApplyConfiguration) WithBackoffLimit(value int32) *JobSpecApplyC // WithSelector sets the Selector field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Selector field is set to the value of the last call. -func (b *JobSpecApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *JobSpecApplyConfiguration { +func (b *JobSpecApplyConfiguration) WithSelector(value *metav1.LabelSelectorApplyConfiguration) *JobSpecApplyConfiguration { b.Selector = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicy.go b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicy.go new file mode 100644 index 00000000000..6da98386c9b --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicy.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// PodFailurePolicyApplyConfiguration represents an declarative configuration of the PodFailurePolicy type for use +// with apply. +type PodFailurePolicyApplyConfiguration struct { + Rules []PodFailurePolicyRuleApplyConfiguration `json:"rules,omitempty"` +} + +// PodFailurePolicyApplyConfiguration constructs an declarative configuration of the PodFailurePolicy type for use with +// apply. +func PodFailurePolicy() *PodFailurePolicyApplyConfiguration { + return &PodFailurePolicyApplyConfiguration{} +} + +// WithRules adds the given value to the Rules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Rules field. +func (b *PodFailurePolicyApplyConfiguration) WithRules(values ...*PodFailurePolicyRuleApplyConfiguration) *PodFailurePolicyApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithRules") + } + b.Rules = append(b.Rules, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonexitcodesrequirement.go b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonexitcodesrequirement.go new file mode 100644 index 00000000000..65f6251810e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonexitcodesrequirement.go @@ -0,0 +1,63 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/batch/v1" +) + +// PodFailurePolicyOnExitCodesRequirementApplyConfiguration represents an declarative configuration of the PodFailurePolicyOnExitCodesRequirement type for use +// with apply. +type PodFailurePolicyOnExitCodesRequirementApplyConfiguration struct { + ContainerName *string `json:"containerName,omitempty"` + Operator *v1.PodFailurePolicyOnExitCodesOperator `json:"operator,omitempty"` + Values []int32 `json:"values,omitempty"` +} + +// PodFailurePolicyOnExitCodesRequirementApplyConfiguration constructs an declarative configuration of the PodFailurePolicyOnExitCodesRequirement type for use with +// apply. +func PodFailurePolicyOnExitCodesRequirement() *PodFailurePolicyOnExitCodesRequirementApplyConfiguration { + return &PodFailurePolicyOnExitCodesRequirementApplyConfiguration{} +} + +// WithContainerName sets the ContainerName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ContainerName field is set to the value of the last call. +func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithContainerName(value string) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration { + b.ContainerName = &value + return b +} + +// WithOperator sets the Operator field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Operator field is set to the value of the last call. +func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithOperator(value v1.PodFailurePolicyOnExitCodesOperator) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration { + b.Operator = &value + return b +} + +// WithValues adds the given value to the Values field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Values field. +func (b *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) WithValues(values ...int32) *PodFailurePolicyOnExitCodesRequirementApplyConfiguration { + for i := range values { + b.Values = append(b.Values, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonpodconditionspattern.go b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonpodconditionspattern.go new file mode 100644 index 00000000000..da1556ff8bf --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyonpodconditionspattern.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// PodFailurePolicyOnPodConditionsPatternApplyConfiguration represents an declarative configuration of the PodFailurePolicyOnPodConditionsPattern type for use +// with apply. +type PodFailurePolicyOnPodConditionsPatternApplyConfiguration struct { + Type *v1.PodConditionType `json:"type,omitempty"` + Status *v1.ConditionStatus `json:"status,omitempty"` +} + +// PodFailurePolicyOnPodConditionsPatternApplyConfiguration constructs an declarative configuration of the PodFailurePolicyOnPodConditionsPattern type for use with +// apply. +func PodFailurePolicyOnPodConditionsPattern() *PodFailurePolicyOnPodConditionsPatternApplyConfiguration { + return &PodFailurePolicyOnPodConditionsPatternApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *PodFailurePolicyOnPodConditionsPatternApplyConfiguration) WithType(value v1.PodConditionType) *PodFailurePolicyOnPodConditionsPatternApplyConfiguration { + b.Type = &value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PodFailurePolicyOnPodConditionsPatternApplyConfiguration) WithStatus(value v1.ConditionStatus) *PodFailurePolicyOnPodConditionsPatternApplyConfiguration { + b.Status = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyrule.go b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyrule.go new file mode 100644 index 00000000000..d435243531f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/batch/v1/podfailurepolicyrule.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/batch/v1" +) + +// PodFailurePolicyRuleApplyConfiguration represents an declarative configuration of the PodFailurePolicyRule type for use +// with apply. +type PodFailurePolicyRuleApplyConfiguration struct { + Action *v1.PodFailurePolicyAction `json:"action,omitempty"` + OnExitCodes *PodFailurePolicyOnExitCodesRequirementApplyConfiguration `json:"onExitCodes,omitempty"` + OnPodConditions []PodFailurePolicyOnPodConditionsPatternApplyConfiguration `json:"onPodConditions,omitempty"` +} + +// PodFailurePolicyRuleApplyConfiguration constructs an declarative configuration of the PodFailurePolicyRule type for use with +// apply. +func PodFailurePolicyRule() *PodFailurePolicyRuleApplyConfiguration { + return &PodFailurePolicyRuleApplyConfiguration{} +} + +// WithAction sets the Action field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Action field is set to the value of the last call. +func (b *PodFailurePolicyRuleApplyConfiguration) WithAction(value v1.PodFailurePolicyAction) *PodFailurePolicyRuleApplyConfiguration { + b.Action = &value + return b +} + +// WithOnExitCodes sets the OnExitCodes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the OnExitCodes field is set to the value of the last call. +func (b *PodFailurePolicyRuleApplyConfiguration) WithOnExitCodes(value *PodFailurePolicyOnExitCodesRequirementApplyConfiguration) *PodFailurePolicyRuleApplyConfiguration { + b.OnExitCodes = value + return b +} + +// WithOnPodConditions adds the given value to the OnPodConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OnPodConditions field. +func (b *PodFailurePolicyRuleApplyConfiguration) WithOnPodConditions(values ...*PodFailurePolicyOnPodConditionsPatternApplyConfiguration) *PodFailurePolicyRuleApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOnPodConditions") + } + b.OnPodConditions = append(b.OnPodConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 00000000000..788d2a07dcb --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,247 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterTrustBundleApplyConfiguration represents an declarative configuration of the ClusterTrustBundle type for use +// with apply. +type ClusterTrustBundleApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ClusterTrustBundleSpecApplyConfiguration `json:"spec,omitempty"` +} + +// ClusterTrustBundle constructs an declarative configuration of the ClusterTrustBundle type for use with +// apply. +func ClusterTrustBundle(name string) *ClusterTrustBundleApplyConfiguration { + b := &ClusterTrustBundleApplyConfiguration{} + b.WithName(name) + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") + return b +} + +// ExtractClusterTrustBundle extracts the applied configuration owned by fieldManager from +// clusterTrustBundle. If no managedFields are found in clusterTrustBundle for fieldManager, a +// ClusterTrustBundleApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// clusterTrustBundle must be a unmodified ClusterTrustBundle API object that was retrieved from the Kubernetes API. +// ExtractClusterTrustBundle provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "") +} + +// ExtractClusterTrustBundleStatus is the same as ExtractClusterTrustBundle except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractClusterTrustBundleStatus(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "status") +} + +func extractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string, subresource string) (*ClusterTrustBundleApplyConfiguration, error) { + b := &ClusterTrustBundleApplyConfiguration{} + err := managedfields.ExtractInto(clusterTrustBundle, internal.Parser().Type("io.k8s.api.certificates.v1alpha1.ClusterTrustBundle"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(clusterTrustBundle.Name) + + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithKind(value string) *ClusterTrustBundleApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithAPIVersion(value string) *ClusterTrustBundleApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithName(value string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithGenerateName(value string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithNamespace(value string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithUID(value types.UID) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithResourceVersion(value string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithGeneration(value int64) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ClusterTrustBundleApplyConfiguration) WithLabels(entries map[string]string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ClusterTrustBundleApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ClusterTrustBundleApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ClusterTrustBundleApplyConfiguration) WithFinalizers(values ...string) *ClusterTrustBundleApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ClusterTrustBundleApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ClusterTrustBundleApplyConfiguration) WithSpec(value *ClusterTrustBundleSpecApplyConfiguration) *ClusterTrustBundleApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go new file mode 100644 index 00000000000..d1aea1d6dc3 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterTrustBundleSpecApplyConfiguration represents an declarative configuration of the ClusterTrustBundleSpec type for use +// with apply. +type ClusterTrustBundleSpecApplyConfiguration struct { + SignerName *string `json:"signerName,omitempty"` + TrustBundle *string `json:"trustBundle,omitempty"` +} + +// ClusterTrustBundleSpecApplyConfiguration constructs an declarative configuration of the ClusterTrustBundleSpec type for use with +// apply. +func ClusterTrustBundleSpec() *ClusterTrustBundleSpecApplyConfiguration { + return &ClusterTrustBundleSpecApplyConfiguration{} +} + +// WithSignerName sets the SignerName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SignerName field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithSignerName(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.SignerName = &value + return b +} + +// WithTrustBundle sets the TrustBundle field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TrustBundle field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithTrustBundle(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.TrustBundle = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/claimsource.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/claimsource.go new file mode 100644 index 00000000000..2153570fc08 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/claimsource.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ClaimSourceApplyConfiguration represents an declarative configuration of the ClaimSource type for use +// with apply. +type ClaimSourceApplyConfiguration struct { + ResourceClaimName *string `json:"resourceClaimName,omitempty"` + ResourceClaimTemplateName *string `json:"resourceClaimTemplateName,omitempty"` +} + +// ClaimSourceApplyConfiguration constructs an declarative configuration of the ClaimSource type for use with +// apply. +func ClaimSource() *ClaimSourceApplyConfiguration { + return &ClaimSourceApplyConfiguration{} +} + +// WithResourceClaimName sets the ResourceClaimName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimName field is set to the value of the last call. +func (b *ClaimSourceApplyConfiguration) WithResourceClaimName(value string) *ClaimSourceApplyConfiguration { + b.ResourceClaimName = &value + return b +} + +// WithResourceClaimTemplateName sets the ResourceClaimTemplateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimTemplateName field is set to the value of the last call. +func (b *ClaimSourceApplyConfiguration) WithResourceClaimTemplateName(value string) *ClaimSourceApplyConfiguration { + b.ResourceClaimTemplateName = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go index d3b066d9c45..9ada59ee20a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go @@ -25,28 +25,29 @@ import ( // ContainerApplyConfiguration represents an declarative configuration of the Container type for use // with apply. type ContainerApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // ContainerApplyConfiguration constructs an declarative configuration of the Container type for use with @@ -146,6 +147,19 @@ func (b *ContainerApplyConfiguration) WithResources(value *ResourceRequirementsA return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *ContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *ContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go new file mode 100644 index 00000000000..bbbcbc9f138 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// ContainerResizePolicyApplyConfiguration represents an declarative configuration of the ContainerResizePolicy type for use +// with apply. +type ContainerResizePolicyApplyConfiguration struct { + ResourceName *v1.ResourceName `json:"resourceName,omitempty"` + RestartPolicy *v1.ResourceResizeRestartPolicy `json:"restartPolicy,omitempty"` +} + +// ContainerResizePolicyApplyConfiguration constructs an declarative configuration of the ContainerResizePolicy type for use with +// apply. +func ContainerResizePolicy() *ContainerResizePolicyApplyConfiguration { + return &ContainerResizePolicyApplyConfiguration{} +} + +// WithResourceName sets the ResourceName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceName field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithResourceName(value v1.ResourceName) *ContainerResizePolicyApplyConfiguration { + b.ResourceName = &value + return b +} + +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithRestartPolicy(value v1.ResourceResizeRestartPolicy) *ContainerResizePolicyApplyConfiguration { + b.RestartPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go index 18d2925c175..2b98c4658f2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go @@ -18,18 +18,24 @@ limitations under the License. package v1 +import ( + corev1 "k8s.io/api/core/v1" +) + // ContainerStatusApplyConfiguration represents an declarative configuration of the ContainerStatus type for use // with apply. type ContainerStatusApplyConfiguration struct { - Name *string `json:"name,omitempty"` - State *ContainerStateApplyConfiguration `json:"state,omitempty"` - LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` - Ready *bool `json:"ready,omitempty"` - RestartCount *int32 `json:"restartCount,omitempty"` - Image *string `json:"image,omitempty"` - ImageID *string `json:"imageID,omitempty"` - ContainerID *string `json:"containerID,omitempty"` - Started *bool `json:"started,omitempty"` + Name *string `json:"name,omitempty"` + State *ContainerStateApplyConfiguration `json:"state,omitempty"` + LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` + Ready *bool `json:"ready,omitempty"` + RestartCount *int32 `json:"restartCount,omitempty"` + Image *string `json:"image,omitempty"` + ImageID *string `json:"imageID,omitempty"` + ContainerID *string `json:"containerID,omitempty"` + Started *bool `json:"started,omitempty"` + AllocatedResources *corev1.ResourceList `json:"allocatedResources,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` } // ContainerStatusApplyConfiguration constructs an declarative configuration of the ContainerStatus type for use with @@ -109,3 +115,19 @@ func (b *ContainerStatusApplyConfiguration) WithStarted(value bool) *ContainerSt b.Started = &value return b } + +// WithAllocatedResources sets the AllocatedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocatedResources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithAllocatedResources(value corev1.ResourceList) *ContainerStatusApplyConfiguration { + b.AllocatedResources = &value + return b +} + +// WithResources sets the Resources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithResources(value *ResourceRequirementsApplyConfiguration) *ContainerStatusApplyConfiguration { + b.Resources = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/csipersistentvolumesource.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/csipersistentvolumesource.go index b8165445d00..2fc681604e2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/csipersistentvolumesource.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/csipersistentvolumesource.go @@ -30,6 +30,7 @@ type CSIPersistentVolumeSourceApplyConfiguration struct { NodeStageSecretRef *SecretReferenceApplyConfiguration `json:"nodeStageSecretRef,omitempty"` NodePublishSecretRef *SecretReferenceApplyConfiguration `json:"nodePublishSecretRef,omitempty"` ControllerExpandSecretRef *SecretReferenceApplyConfiguration `json:"controllerExpandSecretRef,omitempty"` + NodeExpandSecretRef *SecretReferenceApplyConfiguration `json:"nodeExpandSecretRef,omitempty"` } // CSIPersistentVolumeSourceApplyConfiguration constructs an declarative configuration of the CSIPersistentVolumeSource type for use with @@ -115,3 +116,11 @@ func (b *CSIPersistentVolumeSourceApplyConfiguration) WithControllerExpandSecret b.ControllerExpandSecretRef = value return b } + +// WithNodeExpandSecretRef sets the NodeExpandSecretRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeExpandSecretRef field is set to the value of the last call. +func (b *CSIPersistentVolumeSourceApplyConfiguration) WithNodeExpandSecretRef(value *SecretReferenceApplyConfiguration) *CSIPersistentVolumeSourceApplyConfiguration { + b.NodeExpandSecretRef = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go index 6c24cd419d3..c51049ba1f2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go @@ -126,6 +126,19 @@ func (b *EphemeralContainerApplyConfiguration) WithResources(value *ResourceRequ return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go index 67e658cfab7..764b830e049 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go @@ -25,28 +25,29 @@ import ( // EphemeralContainerCommonApplyConfiguration represents an declarative configuration of the EphemeralContainerCommon type for use // with apply. type EphemeralContainerCommonApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // EphemeralContainerCommonApplyConfiguration constructs an declarative configuration of the EphemeralContainerCommon type for use with @@ -146,6 +147,19 @@ func (b *EphemeralContainerCommonApplyConfiguration) WithResources(value *Resour return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerCommonApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerCommonApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumeclaimspec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumeclaimspec.go index e22d04b0d59..f324584aba2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumeclaimspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumeclaimspec.go @@ -33,7 +33,7 @@ type PersistentVolumeClaimSpecApplyConfiguration struct { StorageClassName *string `json:"storageClassName,omitempty"` VolumeMode *v1.PersistentVolumeMode `json:"volumeMode,omitempty"` DataSource *TypedLocalObjectReferenceApplyConfiguration `json:"dataSource,omitempty"` - DataSourceRef *TypedLocalObjectReferenceApplyConfiguration `json:"dataSourceRef,omitempty"` + DataSourceRef *TypedObjectReferenceApplyConfiguration `json:"dataSourceRef,omitempty"` } // PersistentVolumeClaimSpecApplyConfiguration constructs an declarative configuration of the PersistentVolumeClaimSpec type for use with @@ -103,7 +103,7 @@ func (b *PersistentVolumeClaimSpecApplyConfiguration) WithDataSource(value *Type // WithDataSourceRef sets the DataSourceRef field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DataSourceRef field is set to the value of the last call. -func (b *PersistentVolumeClaimSpecApplyConfiguration) WithDataSourceRef(value *TypedLocalObjectReferenceApplyConfiguration) *PersistentVolumeClaimSpecApplyConfiguration { +func (b *PersistentVolumeClaimSpecApplyConfiguration) WithDataSourceRef(value *TypedObjectReferenceApplyConfiguration) *PersistentVolumeClaimSpecApplyConfiguration { b.DataSourceRef = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go new file mode 100644 index 00000000000..69b250d474f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// PodResourceClaimApplyConfiguration represents an declarative configuration of the PodResourceClaim type for use +// with apply. +type PodResourceClaimApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Source *ClaimSourceApplyConfiguration `json:"source,omitempty"` +} + +// PodResourceClaimApplyConfiguration constructs an declarative configuration of the PodResourceClaim type for use with +// apply. +func PodResourceClaim() *PodResourceClaimApplyConfiguration { + return &PodResourceClaimApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodResourceClaimApplyConfiguration) WithName(value string) *PodResourceClaimApplyConfiguration { + b.Name = &value + return b +} + +// WithSource sets the Source field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Source field is set to the value of the last call. +func (b *PodResourceClaimApplyConfiguration) WithSource(value *ClaimSourceApplyConfiguration) *PodResourceClaimApplyConfiguration { + b.Source = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggate.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggate.go new file mode 100644 index 00000000000..f7649c2e921 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggate.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// PodSchedulingGateApplyConfiguration represents an declarative configuration of the PodSchedulingGate type for use +// with apply. +type PodSchedulingGateApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// PodSchedulingGateApplyConfiguration constructs an declarative configuration of the PodSchedulingGate type for use with +// apply. +func PodSchedulingGate() *PodSchedulingGateApplyConfiguration { + return &PodSchedulingGateApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodSchedulingGateApplyConfiguration) WithName(value string) *PodSchedulingGateApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go index 015859e9a38..a9acd36fc7c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go @@ -61,6 +61,9 @@ type PodSpecApplyConfiguration struct { TopologySpreadConstraints []TopologySpreadConstraintApplyConfiguration `json:"topologySpreadConstraints,omitempty"` SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty"` OS *PodOSApplyConfiguration `json:"os,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty"` + SchedulingGates []PodSchedulingGateApplyConfiguration `json:"schedulingGates,omitempty"` + ResourceClaims []PodResourceClaimApplyConfiguration `json:"resourceClaims,omitempty"` } // PodSpecApplyConfiguration constructs an declarative configuration of the PodSpec type for use with @@ -407,3 +410,37 @@ func (b *PodSpecApplyConfiguration) WithOS(value *PodOSApplyConfiguration) *PodS b.OS = value return b } + +// WithHostUsers sets the HostUsers field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostUsers field is set to the value of the last call. +func (b *PodSpecApplyConfiguration) WithHostUsers(value bool) *PodSpecApplyConfiguration { + b.HostUsers = &value + return b +} + +// WithSchedulingGates adds the given value to the SchedulingGates field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the SchedulingGates field. +func (b *PodSpecApplyConfiguration) WithSchedulingGates(values ...*PodSchedulingGateApplyConfiguration) *PodSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithSchedulingGates") + } + b.SchedulingGates = append(b.SchedulingGates, *values[i]) + } + return b +} + +// WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceClaims field. +func (b *PodSpecApplyConfiguration) WithResourceClaims(values ...*PodResourceClaimApplyConfiguration) *PodSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceClaims") + } + b.ResourceClaims = append(b.ResourceClaims, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go index 7ee5b9955f6..e9d8e5b28f2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go @@ -39,6 +39,7 @@ type PodStatusApplyConfiguration struct { ContainerStatuses []ContainerStatusApplyConfiguration `json:"containerStatuses,omitempty"` QOSClass *v1.PodQOSClass `json:"qosClass,omitempty"` EphemeralContainerStatuses []ContainerStatusApplyConfiguration `json:"ephemeralContainerStatuses,omitempty"` + Resize *v1.PodResizeStatus `json:"resize,omitempty"` } // PodStatusApplyConfiguration constructs an declarative configuration of the PodStatus type for use with @@ -175,3 +176,11 @@ func (b *PodStatusApplyConfiguration) WithEphemeralContainerStatuses(values ...* } return b } + +// WithResize sets the Resize field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resize field is set to the value of the last call. +func (b *PodStatusApplyConfiguration) WithResize(value v1.PodResizeStatus) *PodStatusApplyConfiguration { + b.Resize = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourceclaim.go new file mode 100644 index 00000000000..064dd4e2e41 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourceclaim.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ResourceClaimApplyConfiguration represents an declarative configuration of the ResourceClaim type for use +// with apply. +type ResourceClaimApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// ResourceClaimApplyConfiguration constructs an declarative configuration of the ResourceClaim type for use with +// apply. +func ResourceClaim() *ResourceClaimApplyConfiguration { + return &ResourceClaimApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithName(value string) *ResourceClaimApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcerequirements.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcerequirements.go index d22f3847945..9482b8d7134 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcerequirements.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcerequirements.go @@ -25,8 +25,9 @@ import ( // ResourceRequirementsApplyConfiguration represents an declarative configuration of the ResourceRequirements type for use // with apply. type ResourceRequirementsApplyConfiguration struct { - Limits *v1.ResourceList `json:"limits,omitempty"` - Requests *v1.ResourceList `json:"requests,omitempty"` + Limits *v1.ResourceList `json:"limits,omitempty"` + Requests *v1.ResourceList `json:"requests,omitempty"` + Claims []ResourceClaimApplyConfiguration `json:"claims,omitempty"` } // ResourceRequirementsApplyConfiguration constructs an declarative configuration of the ResourceRequirements type for use with @@ -50,3 +51,16 @@ func (b *ResourceRequirementsApplyConfiguration) WithRequests(value v1.ResourceL b.Requests = &value return b } + +// WithClaims adds the given value to the Claims field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Claims field. +func (b *ResourceRequirementsApplyConfiguration) WithClaims(values ...*ResourceClaimApplyConfiguration) *ResourceRequirementsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithClaims") + } + b.Claims = append(b.Claims, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go index 856cd4f9d82..493af6fb3c1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go @@ -35,15 +35,15 @@ type ServiceSpecApplyConfiguration struct { LoadBalancerIP *string `json:"loadBalancerIP,omitempty"` LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty"` ExternalName *string `json:"externalName,omitempty"` - ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty"` + ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty"` HealthCheckNodePort *int32 `json:"healthCheckNodePort,omitempty"` PublishNotReadyAddresses *bool `json:"publishNotReadyAddresses,omitempty"` SessionAffinityConfig *SessionAffinityConfigApplyConfiguration `json:"sessionAffinityConfig,omitempty"` IPFamilies []corev1.IPFamily `json:"ipFamilies,omitempty"` - IPFamilyPolicy *corev1.IPFamilyPolicyType `json:"ipFamilyPolicy,omitempty"` + IPFamilyPolicy *corev1.IPFamilyPolicy `json:"ipFamilyPolicy,omitempty"` AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty"` LoadBalancerClass *string `json:"loadBalancerClass,omitempty"` - InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty"` + InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty"` } // ServiceSpecApplyConfiguration constructs an declarative configuration of the ServiceSpec type for use with @@ -152,7 +152,7 @@ func (b *ServiceSpecApplyConfiguration) WithExternalName(value string) *ServiceS // WithExternalTrafficPolicy sets the ExternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ExternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.ExternalTrafficPolicy = &value return b } @@ -194,7 +194,7 @@ func (b *ServiceSpecApplyConfiguration) WithIPFamilies(values ...corev1.IPFamily // WithIPFamilyPolicy sets the IPFamilyPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the IPFamilyPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithIPFamilyPolicy(value corev1.IPFamilyPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithIPFamilyPolicy(value corev1.IPFamilyPolicy) *ServiceSpecApplyConfiguration { b.IPFamilyPolicy = &value return b } @@ -218,7 +218,7 @@ func (b *ServiceSpecApplyConfiguration) WithLoadBalancerClass(value string) *Ser // WithInternalTrafficPolicy sets the InternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the InternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.InternalTrafficPolicy = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/topologyspreadconstraint.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/topologyspreadconstraint.go index 867cc89f20c..fbfa8fa886c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/topologyspreadconstraint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/topologyspreadconstraint.go @@ -26,11 +26,14 @@ import ( // TopologySpreadConstraintApplyConfiguration represents an declarative configuration of the TopologySpreadConstraint type for use // with apply. type TopologySpreadConstraintApplyConfiguration struct { - MaxSkew *int32 `json:"maxSkew,omitempty"` - TopologyKey *string `json:"topologyKey,omitempty"` - WhenUnsatisfiable *v1.UnsatisfiableConstraintAction `json:"whenUnsatisfiable,omitempty"` - LabelSelector *metav1.LabelSelectorApplyConfiguration `json:"labelSelector,omitempty"` - MinDomains *int32 `json:"minDomains,omitempty"` + MaxSkew *int32 `json:"maxSkew,omitempty"` + TopologyKey *string `json:"topologyKey,omitempty"` + WhenUnsatisfiable *v1.UnsatisfiableConstraintAction `json:"whenUnsatisfiable,omitempty"` + LabelSelector *metav1.LabelSelectorApplyConfiguration `json:"labelSelector,omitempty"` + MinDomains *int32 `json:"minDomains,omitempty"` + NodeAffinityPolicy *v1.NodeInclusionPolicy `json:"nodeAffinityPolicy,omitempty"` + NodeTaintsPolicy *v1.NodeInclusionPolicy `json:"nodeTaintsPolicy,omitempty"` + MatchLabelKeys []string `json:"matchLabelKeys,omitempty"` } // TopologySpreadConstraintApplyConfiguration constructs an declarative configuration of the TopologySpreadConstraint type for use with @@ -78,3 +81,29 @@ func (b *TopologySpreadConstraintApplyConfiguration) WithMinDomains(value int32) b.MinDomains = &value return b } + +// WithNodeAffinityPolicy sets the NodeAffinityPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeAffinityPolicy field is set to the value of the last call. +func (b *TopologySpreadConstraintApplyConfiguration) WithNodeAffinityPolicy(value v1.NodeInclusionPolicy) *TopologySpreadConstraintApplyConfiguration { + b.NodeAffinityPolicy = &value + return b +} + +// WithNodeTaintsPolicy sets the NodeTaintsPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeTaintsPolicy field is set to the value of the last call. +func (b *TopologySpreadConstraintApplyConfiguration) WithNodeTaintsPolicy(value v1.NodeInclusionPolicy) *TopologySpreadConstraintApplyConfiguration { + b.NodeTaintsPolicy = &value + return b +} + +// WithMatchLabelKeys adds the given value to the MatchLabelKeys field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchLabelKeys field. +func (b *TopologySpreadConstraintApplyConfiguration) WithMatchLabelKeys(values ...string) *TopologySpreadConstraintApplyConfiguration { + for i := range values { + b.MatchLabelKeys = append(b.MatchLabelKeys, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/typedobjectreference.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/typedobjectreference.go new file mode 100644 index 00000000000..d9a01c9c3a0 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/typedobjectreference.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// TypedObjectReferenceApplyConfiguration represents an declarative configuration of the TypedObjectReference type for use +// with apply. +type TypedObjectReferenceApplyConfiguration struct { + APIGroup *string `json:"apiGroup,omitempty"` + Kind *string `json:"kind,omitempty"` + Name *string `json:"name,omitempty"` + Namespace *string `json:"namespace,omitempty"` +} + +// TypedObjectReferenceApplyConfiguration constructs an declarative configuration of the TypedObjectReference type for use with +// apply. +func TypedObjectReference() *TypedObjectReferenceApplyConfiguration { + return &TypedObjectReferenceApplyConfiguration{} +} + +// WithAPIGroup sets the APIGroup field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIGroup field is set to the value of the last call. +func (b *TypedObjectReferenceApplyConfiguration) WithAPIGroup(value string) *TypedObjectReferenceApplyConfiguration { + b.APIGroup = &value + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *TypedObjectReferenceApplyConfiguration) WithKind(value string) *TypedObjectReferenceApplyConfiguration { + b.Kind = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *TypedObjectReferenceApplyConfiguration) WithName(value string) *TypedObjectReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *TypedObjectReferenceApplyConfiguration) WithNamespace(value string) *TypedObjectReferenceApplyConfiguration { + b.Namespace = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go deleted file mode 100644 index 27b49bf1538..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedCSIDriverApplyConfiguration represents an declarative configuration of the AllowedCSIDriver type for use -// with apply. -type AllowedCSIDriverApplyConfiguration struct { - Name *string `json:"name,omitempty"` -} - -// AllowedCSIDriverApplyConfiguration constructs an declarative configuration of the AllowedCSIDriver type for use with -// apply. -func AllowedCSIDriver() *AllowedCSIDriverApplyConfiguration { - return &AllowedCSIDriverApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *AllowedCSIDriverApplyConfiguration) WithName(value string) *AllowedCSIDriverApplyConfiguration { - b.Name = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go deleted file mode 100644 index 30c3724cfee..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedFlexVolumeApplyConfiguration represents an declarative configuration of the AllowedFlexVolume type for use -// with apply. -type AllowedFlexVolumeApplyConfiguration struct { - Driver *string `json:"driver,omitempty"` -} - -// AllowedFlexVolumeApplyConfiguration constructs an declarative configuration of the AllowedFlexVolume type for use with -// apply. -func AllowedFlexVolume() *AllowedFlexVolumeApplyConfiguration { - return &AllowedFlexVolumeApplyConfiguration{} -} - -// WithDriver sets the Driver field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Driver field is set to the value of the last call. -func (b *AllowedFlexVolumeApplyConfiguration) WithDriver(value string) *AllowedFlexVolumeApplyConfiguration { - b.Driver = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go deleted file mode 100644 index 493815d8d4a..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedHostPathApplyConfiguration represents an declarative configuration of the AllowedHostPath type for use -// with apply. -type AllowedHostPathApplyConfiguration struct { - PathPrefix *string `json:"pathPrefix,omitempty"` - ReadOnly *bool `json:"readOnly,omitempty"` -} - -// AllowedHostPathApplyConfiguration constructs an declarative configuration of the AllowedHostPath type for use with -// apply. -func AllowedHostPath() *AllowedHostPathApplyConfiguration { - return &AllowedHostPathApplyConfiguration{} -} - -// WithPathPrefix sets the PathPrefix field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PathPrefix field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithPathPrefix(value string) *AllowedHostPathApplyConfiguration { - b.PathPrefix = &value - return b -} - -// WithReadOnly sets the ReadOnly field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnly field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithReadOnly(value bool) *AllowedHostPathApplyConfiguration { - b.ReadOnly = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go deleted file mode 100644 index c7434a6af00..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// FSGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the FSGroupStrategyOptions type for use -// with apply. -type FSGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.FSGroupStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// FSGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the FSGroupStrategyOptions type for use with -// apply. -func FSGroupStrategyOptions() *FSGroupStrategyOptionsApplyConfiguration { - return &FSGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.FSGroupStrategyType) *FSGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *FSGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go deleted file mode 100644 index 7c796881393..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// HostPortRangeApplyConfiguration represents an declarative configuration of the HostPortRange type for use -// with apply. -type HostPortRangeApplyConfiguration struct { - Min *int32 `json:"min,omitempty"` - Max *int32 `json:"max,omitempty"` -} - -// HostPortRangeApplyConfiguration constructs an declarative configuration of the HostPortRange type for use with -// apply. -func HostPortRange() *HostPortRangeApplyConfiguration { - return &HostPortRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMin(value int32) *HostPortRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMax(value int32) *HostPortRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go deleted file mode 100644 index af46f76581a..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// IDRangeApplyConfiguration represents an declarative configuration of the IDRange type for use -// with apply. -type IDRangeApplyConfiguration struct { - Min *int64 `json:"min,omitempty"` - Max *int64 `json:"max,omitempty"` -} - -// IDRangeApplyConfiguration constructs an declarative configuration of the IDRange type for use with -// apply. -func IDRange() *IDRangeApplyConfiguration { - return &IDRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMin(value int64) *IDRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMax(value int64) *IDRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalanceringress.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalanceringress.go new file mode 100644 index 00000000000..20bf6378054 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalanceringress.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// IngressLoadBalancerIngressApplyConfiguration represents an declarative configuration of the IngressLoadBalancerIngress type for use +// with apply. +type IngressLoadBalancerIngressApplyConfiguration struct { + IP *string `json:"ip,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Ports []IngressPortStatusApplyConfiguration `json:"ports,omitempty"` +} + +// IngressLoadBalancerIngressApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerIngress type for use with +// apply. +func IngressLoadBalancerIngress() *IngressLoadBalancerIngressApplyConfiguration { + return &IngressLoadBalancerIngressApplyConfiguration{} +} + +// WithIP sets the IP field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IP field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithIP(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.IP = &value + return b +} + +// WithHostname sets the Hostname field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Hostname field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithHostname(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.Hostname = &value + return b +} + +// WithPorts adds the given value to the Ports field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ports field. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithPorts(values ...*IngressPortStatusApplyConfiguration) *IngressLoadBalancerIngressApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPorts") + } + b.Ports = append(b.Ports, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalancerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalancerstatus.go new file mode 100644 index 00000000000..e16dd236333 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressloadbalancerstatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// IngressLoadBalancerStatusApplyConfiguration represents an declarative configuration of the IngressLoadBalancerStatus type for use +// with apply. +type IngressLoadBalancerStatusApplyConfiguration struct { + Ingress []IngressLoadBalancerIngressApplyConfiguration `json:"ingress,omitempty"` +} + +// IngressLoadBalancerStatusApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerStatus type for use with +// apply. +func IngressLoadBalancerStatus() *IngressLoadBalancerStatusApplyConfiguration { + return &IngressLoadBalancerStatusApplyConfiguration{} +} + +// WithIngress adds the given value to the Ingress field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ingress field. +func (b *IngressLoadBalancerStatusApplyConfiguration) WithIngress(values ...*IngressLoadBalancerIngressApplyConfiguration) *IngressLoadBalancerStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithIngress") + } + b.Ingress = append(b.Ingress, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressportstatus.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressportstatus.go new file mode 100644 index 00000000000..0836537979e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressportstatus.go @@ -0,0 +1,61 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// IngressPortStatusApplyConfiguration represents an declarative configuration of the IngressPortStatus type for use +// with apply. +type IngressPortStatusApplyConfiguration struct { + Port *int32 `json:"port,omitempty"` + Protocol *v1.Protocol `json:"protocol,omitempty"` + Error *string `json:"error,omitempty"` +} + +// IngressPortStatusApplyConfiguration constructs an declarative configuration of the IngressPortStatus type for use with +// apply. +func IngressPortStatus() *IngressPortStatusApplyConfiguration { + return &IngressPortStatusApplyConfiguration{} +} + +// WithPort sets the Port field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Port field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithPort(value int32) *IngressPortStatusApplyConfiguration { + b.Port = &value + return b +} + +// WithProtocol sets the Protocol field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Protocol field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithProtocol(value v1.Protocol) *IngressPortStatusApplyConfiguration { + b.Protocol = &value + return b +} + +// WithError sets the Error field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Error field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithError(value string) *IngressPortStatusApplyConfiguration { + b.Error = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressstatus.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressstatus.go index 941769594ec..faa7e2446fa 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/ingressstatus.go @@ -18,14 +18,10 @@ limitations under the License. package v1beta1 -import ( - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - // IngressStatusApplyConfiguration represents an declarative configuration of the IngressStatus type for use // with apply. type IngressStatusApplyConfiguration struct { - LoadBalancer *v1.LoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` + LoadBalancer *IngressLoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` } // IngressStatusApplyConfiguration constructs an declarative configuration of the IngressStatus type for use with @@ -37,7 +33,7 @@ func IngressStatus() *IngressStatusApplyConfiguration { // WithLoadBalancer sets the LoadBalancer field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the LoadBalancer field is set to the value of the last call. -func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *v1.LoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { +func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *IngressLoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { b.LoadBalancer = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index c70906cfafd..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,247 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - managedfields "k8s.io/apimachinery/pkg/util/managedfields" - internal "k8s.io/client-go/applyconfigurations/internal" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// PodSecurityPolicyApplyConfiguration represents an declarative configuration of the PodSecurityPolicy type for use -// with apply. -type PodSecurityPolicyApplyConfiguration struct { - v1.TypeMetaApplyConfiguration `json:",inline"` - *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *PodSecurityPolicySpecApplyConfiguration `json:"spec,omitempty"` -} - -// PodSecurityPolicy constructs an declarative configuration of the PodSecurityPolicy type for use with -// apply. -func PodSecurityPolicy(name string) *PodSecurityPolicyApplyConfiguration { - b := &PodSecurityPolicyApplyConfiguration{} - b.WithName(name) - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") - return b -} - -// ExtractPodSecurityPolicy extracts the applied configuration owned by fieldManager from -// podSecurityPolicy. If no managedFields are found in podSecurityPolicy for fieldManager, a -// PodSecurityPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable), -// APIVersion and Kind populated. It is possible that no managed fields were found for because other -// field managers have taken ownership of all the fields previously owned by fieldManager, or because -// the fieldManager never owned fields any fields. -// podSecurityPolicy must be a unmodified PodSecurityPolicy API object that was retrieved from the Kubernetes API. -// ExtractPodSecurityPolicy provides a way to perform a extract/modify-in-place/apply workflow. -// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously -// applied if another fieldManager has updated or force applied any of the previously applied fields. -// Experimental! -func ExtractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "") -} - -// ExtractPodSecurityPolicyStatus is the same as ExtractPodSecurityPolicy except -// that it extracts the status subresource applied configuration. -// Experimental! -func ExtractPodSecurityPolicyStatus(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "status") -} - -func extractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string, subresource string) (*PodSecurityPolicyApplyConfiguration, error) { - b := &PodSecurityPolicyApplyConfiguration{} - err := managedfields.ExtractInto(podSecurityPolicy, internal.Parser().Type("io.k8s.api.extensions.v1beta1.PodSecurityPolicy"), fieldManager, b, subresource) - if err != nil { - return nil, err - } - b.WithName(podSecurityPolicy.Name) - - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") - return b, nil -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithKind(value string) *PodSecurityPolicyApplyConfiguration { - b.Kind = &value - return b -} - -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithAPIVersion(value string) *PodSecurityPolicyApplyConfiguration { - b.APIVersion = &value - return b -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithName(value string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.Name = &value - return b -} - -// WithGenerateName sets the GenerateName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGenerateName(value string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.GenerateName = &value - return b -} - -// WithNamespace sets the Namespace field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Namespace field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithNamespace(value string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.Namespace = &value - return b -} - -// WithUID sets the UID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the UID field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithUID(value types.UID) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.UID = &value - return b -} - -// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithResourceVersion(value string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.ResourceVersion = &value - return b -} - -// WithGeneration sets the Generation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Generation field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGeneration(value int64) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.Generation = &value - return b -} - -// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.CreationTimestamp = &value - return b -} - -// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.DeletionTimestamp = &value - return b -} - -// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - b.DeletionGracePeriodSeconds = &value - return b -} - -// WithLabels puts the entries into the Labels field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, the entries provided by each call will be put on the Labels field, -// overwriting an existing map entries in Labels field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithLabels(entries map[string]string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - if b.Labels == nil && len(entries) > 0 { - b.Labels = make(map[string]string, len(entries)) - } - for k, v := range entries { - b.Labels[k] = v - } - return b -} - -// WithAnnotations puts the entries into the Annotations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, the entries provided by each call will be put on the Annotations field, -// overwriting an existing map entries in Annotations field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - if b.Annotations == nil && len(entries) > 0 { - b.Annotations = make(map[string]string, len(entries)) - } - for k, v := range entries { - b.Annotations[k] = v - } - return b -} - -// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PodSecurityPolicyApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - for i := range values { - if values[i] == nil { - panic("nil value passed to WithOwnerReferences") - } - b.OwnerReferences = append(b.OwnerReferences, *values[i]) - } - return b -} - -// WithFinalizers adds the given value to the Finalizers field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PodSecurityPolicyApplyConfiguration) WithFinalizers(values ...string) *PodSecurityPolicyApplyConfiguration { - b.ensureObjectMetaApplyConfigurationExists() - for i := range values { - b.Finalizers = append(b.Finalizers, values[i]) - } - return b -} - -func (b *PodSecurityPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { - if b.ObjectMetaApplyConfiguration == nil { - b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} - } -} - -// WithSpec sets the Spec field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Spec field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithSpec(value *PodSecurityPolicySpecApplyConfiguration) *PodSecurityPolicyApplyConfiguration { - b.Spec = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go deleted file mode 100644 index de3949dc92d..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1 "k8s.io/api/core/v1" - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// PodSecurityPolicySpecApplyConfiguration represents an declarative configuration of the PodSecurityPolicySpec type for use -// with apply. -type PodSecurityPolicySpecApplyConfiguration struct { - Privileged *bool `json:"privileged,omitempty"` - DefaultAddCapabilities []v1.Capability `json:"defaultAddCapabilities,omitempty"` - RequiredDropCapabilities []v1.Capability `json:"requiredDropCapabilities,omitempty"` - AllowedCapabilities []v1.Capability `json:"allowedCapabilities,omitempty"` - Volumes []v1beta1.FSType `json:"volumes,omitempty"` - HostNetwork *bool `json:"hostNetwork,omitempty"` - HostPorts []HostPortRangeApplyConfiguration `json:"hostPorts,omitempty"` - HostPID *bool `json:"hostPID,omitempty"` - HostIPC *bool `json:"hostIPC,omitempty"` - SELinux *SELinuxStrategyOptionsApplyConfiguration `json:"seLinux,omitempty"` - RunAsUser *RunAsUserStrategyOptionsApplyConfiguration `json:"runAsUser,omitempty"` - RunAsGroup *RunAsGroupStrategyOptionsApplyConfiguration `json:"runAsGroup,omitempty"` - SupplementalGroups *SupplementalGroupsStrategyOptionsApplyConfiguration `json:"supplementalGroups,omitempty"` - FSGroup *FSGroupStrategyOptionsApplyConfiguration `json:"fsGroup,omitempty"` - ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty"` - DefaultAllowPrivilegeEscalation *bool `json:"defaultAllowPrivilegeEscalation,omitempty"` - AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty"` - AllowedHostPaths []AllowedHostPathApplyConfiguration `json:"allowedHostPaths,omitempty"` - AllowedFlexVolumes []AllowedFlexVolumeApplyConfiguration `json:"allowedFlexVolumes,omitempty"` - AllowedCSIDrivers []AllowedCSIDriverApplyConfiguration `json:"allowedCSIDrivers,omitempty"` - AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty"` - ForbiddenSysctls []string `json:"forbiddenSysctls,omitempty"` - AllowedProcMountTypes []v1.ProcMountType `json:"allowedProcMountTypes,omitempty"` - RuntimeClass *RuntimeClassStrategyOptionsApplyConfiguration `json:"runtimeClass,omitempty"` -} - -// PodSecurityPolicySpecApplyConfiguration constructs an declarative configuration of the PodSecurityPolicySpec type for use with -// apply. -func PodSecurityPolicySpec() *PodSecurityPolicySpecApplyConfiguration { - return &PodSecurityPolicySpecApplyConfiguration{} -} - -// WithPrivileged sets the Privileged field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Privileged field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithPrivileged(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.Privileged = &value - return b -} - -// WithDefaultAddCapabilities adds the given value to the DefaultAddCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the DefaultAddCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAddCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.DefaultAddCapabilities = append(b.DefaultAddCapabilities, values[i]) - } - return b -} - -// WithRequiredDropCapabilities adds the given value to the RequiredDropCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the RequiredDropCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRequiredDropCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.RequiredDropCapabilities = append(b.RequiredDropCapabilities, values[i]) - } - return b -} - -// WithAllowedCapabilities adds the given value to the AllowedCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedCapabilities = append(b.AllowedCapabilities, values[i]) - } - return b -} - -// WithVolumes adds the given value to the Volumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Volumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithVolumes(values ...v1beta1.FSType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.Volumes = append(b.Volumes, values[i]) - } - return b -} - -// WithHostNetwork sets the HostNetwork field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostNetwork field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostNetwork(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostNetwork = &value - return b -} - -// WithHostPorts adds the given value to the HostPorts field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the HostPorts field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPorts(values ...*HostPortRangeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithHostPorts") - } - b.HostPorts = append(b.HostPorts, *values[i]) - } - return b -} - -// WithHostPID sets the HostPID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostPID field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPID(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostPID = &value - return b -} - -// WithHostIPC sets the HostIPC field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostIPC field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostIPC(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostIPC = &value - return b -} - -// WithSELinux sets the SELinux field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinux field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSELinux(value *SELinuxStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SELinux = value - return b -} - -// WithRunAsUser sets the RunAsUser field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsUser field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsUser(value *RunAsUserStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsUser = value - return b -} - -// WithRunAsGroup sets the RunAsGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsGroup(value *RunAsGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsGroup = value - return b -} - -// WithSupplementalGroups sets the SupplementalGroups field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SupplementalGroups field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSupplementalGroups(value *SupplementalGroupsStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SupplementalGroups = value - return b -} - -// WithFSGroup sets the FSGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the FSGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithFSGroup(value *FSGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.FSGroup = value - return b -} - -// WithReadOnlyRootFilesystem sets the ReadOnlyRootFilesystem field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnlyRootFilesystem field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithReadOnlyRootFilesystem(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.ReadOnlyRootFilesystem = &value - return b -} - -// WithDefaultAllowPrivilegeEscalation sets the DefaultAllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultAllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.DefaultAllowPrivilegeEscalation = &value - return b -} - -// WithAllowPrivilegeEscalation sets the AllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.AllowPrivilegeEscalation = &value - return b -} - -// WithAllowedHostPaths adds the given value to the AllowedHostPaths field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedHostPaths field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedHostPaths(values ...*AllowedHostPathApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedHostPaths") - } - b.AllowedHostPaths = append(b.AllowedHostPaths, *values[i]) - } - return b -} - -// WithAllowedFlexVolumes adds the given value to the AllowedFlexVolumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedFlexVolumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedFlexVolumes(values ...*AllowedFlexVolumeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedFlexVolumes") - } - b.AllowedFlexVolumes = append(b.AllowedFlexVolumes, *values[i]) - } - return b -} - -// WithAllowedCSIDrivers adds the given value to the AllowedCSIDrivers field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCSIDrivers field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCSIDrivers(values ...*AllowedCSIDriverApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedCSIDrivers") - } - b.AllowedCSIDrivers = append(b.AllowedCSIDrivers, *values[i]) - } - return b -} - -// WithAllowedUnsafeSysctls adds the given value to the AllowedUnsafeSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedUnsafeSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedUnsafeSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedUnsafeSysctls = append(b.AllowedUnsafeSysctls, values[i]) - } - return b -} - -// WithForbiddenSysctls adds the given value to the ForbiddenSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the ForbiddenSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithForbiddenSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.ForbiddenSysctls = append(b.ForbiddenSysctls, values[i]) - } - return b -} - -// WithAllowedProcMountTypes adds the given value to the AllowedProcMountTypes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedProcMountTypes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedProcMountTypes(values ...v1.ProcMountType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedProcMountTypes = append(b.AllowedProcMountTypes, values[i]) - } - return b -} - -// WithRuntimeClass sets the RuntimeClass field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RuntimeClass field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRuntimeClass(value *RuntimeClassStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RuntimeClass = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go deleted file mode 100644 index 75e76e85fd1..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsGroupStrategyOptions type for use -// with apply. -type RunAsGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsGroupStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsGroupStrategyOptions type for use with -// apply. -func RunAsGroupStrategyOptions() *RunAsGroupStrategyOptionsApplyConfiguration { - return &RunAsGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsGroupStrategy) *RunAsGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go deleted file mode 100644 index 712c1675ac9..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsUserStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsUserStrategyOptions type for use -// with apply. -type RunAsUserStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsUserStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsUserStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsUserStrategyOptions type for use with -// apply. -func RunAsUserStrategyOptions() *RunAsUserStrategyOptionsApplyConfiguration { - return &RunAsUserStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsUserStrategy) *RunAsUserStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsUserStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go deleted file mode 100644 index c19a7ce6175..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// RuntimeClassStrategyOptionsApplyConfiguration represents an declarative configuration of the RuntimeClassStrategyOptions type for use -// with apply. -type RuntimeClassStrategyOptionsApplyConfiguration struct { - AllowedRuntimeClassNames []string `json:"allowedRuntimeClassNames,omitempty"` - DefaultRuntimeClassName *string `json:"defaultRuntimeClassName,omitempty"` -} - -// RuntimeClassStrategyOptionsApplyConfiguration constructs an declarative configuration of the RuntimeClassStrategyOptions type for use with -// apply. -func RuntimeClassStrategyOptions() *RuntimeClassStrategyOptionsApplyConfiguration { - return &RuntimeClassStrategyOptionsApplyConfiguration{} -} - -// WithAllowedRuntimeClassNames adds the given value to the AllowedRuntimeClassNames field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedRuntimeClassNames field. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithAllowedRuntimeClassNames(values ...string) *RuntimeClassStrategyOptionsApplyConfiguration { - for i := range values { - b.AllowedRuntimeClassNames = append(b.AllowedRuntimeClassNames, values[i]) - } - return b -} - -// WithDefaultRuntimeClassName sets the DefaultRuntimeClassName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultRuntimeClassName field is set to the value of the last call. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithDefaultRuntimeClassName(value string) *RuntimeClassStrategyOptionsApplyConfiguration { - b.DefaultRuntimeClassName = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go deleted file mode 100644 index 265906a73a5..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - -// SELinuxStrategyOptionsApplyConfiguration represents an declarative configuration of the SELinuxStrategyOptions type for use -// with apply. -type SELinuxStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SELinuxStrategy `json:"rule,omitempty"` - SELinuxOptions *v1.SELinuxOptionsApplyConfiguration `json:"seLinuxOptions,omitempty"` -} - -// SELinuxStrategyOptionsApplyConfiguration constructs an declarative configuration of the SELinuxStrategyOptions type for use with -// apply. -func SELinuxStrategyOptions() *SELinuxStrategyOptionsApplyConfiguration { - return &SELinuxStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SELinuxStrategy) *SELinuxStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithSELinuxOptions sets the SELinuxOptions field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinuxOptions field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithSELinuxOptions(value *v1.SELinuxOptionsApplyConfiguration) *SELinuxStrategyOptionsApplyConfiguration { - b.SELinuxOptions = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go deleted file mode 100644 index ec431381245..00000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// SupplementalGroupsStrategyOptionsApplyConfiguration represents an declarative configuration of the SupplementalGroupsStrategyOptions type for use -// with apply. -type SupplementalGroupsStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SupplementalGroupsStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// SupplementalGroupsStrategyOptionsApplyConfiguration constructs an declarative configuration of the SupplementalGroupsStrategyOptions type for use with -// apply. -func SupplementalGroupsStrategyOptions() *SupplementalGroupsStrategyOptionsApplyConfiguration { - return &SupplementalGroupsStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SupplementalGroupsStrategyType) *SupplementalGroupsStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *SupplementalGroupsStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1/limitedprioritylevelconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1/limitedprioritylevelconfiguration.go index df3fecbd7fa..10660e81aaf 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1/limitedprioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1/limitedprioritylevelconfiguration.go @@ -23,6 +23,8 @@ package v1alpha1 type LimitedPriorityLevelConfigurationApplyConfiguration struct { AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"` LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"` + LendablePercent *int32 `json:"lendablePercent,omitempty"` + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"` } // LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with @@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse( b.LimitResponse = value return b } + +// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LendablePercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.LendablePercent = &value + return b +} + +// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.BorrowingLimitPercent = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1/limitedprioritylevelconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1/limitedprioritylevelconfiguration.go index f7f77f9b294..6f57169e1ff 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1/limitedprioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1/limitedprioritylevelconfiguration.go @@ -23,6 +23,8 @@ package v1beta1 type LimitedPriorityLevelConfigurationApplyConfiguration struct { AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"` LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"` + LendablePercent *int32 `json:"lendablePercent,omitempty"` + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"` } // LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with @@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse( b.LimitResponse = value return b } + +// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LendablePercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.LendablePercent = &value + return b +} + +// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.BorrowingLimitPercent = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2/limitedprioritylevelconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2/limitedprioritylevelconfiguration.go index e25f7f6b06c..563b185c74a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2/limitedprioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2/limitedprioritylevelconfiguration.go @@ -23,6 +23,8 @@ package v1beta2 type LimitedPriorityLevelConfigurationApplyConfiguration struct { AssuredConcurrencyShares *int32 `json:"assuredConcurrencyShares,omitempty"` LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"` + LendablePercent *int32 `json:"lendablePercent,omitempty"` + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"` } // LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with @@ -46,3 +48,19 @@ func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse( b.LimitResponse = value return b } + +// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LendablePercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.LendablePercent = &value + return b +} + +// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.BorrowingLimitPercent = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowdistinguishermethod.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowdistinguishermethod.go new file mode 100644 index 00000000000..cd45725932d --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowdistinguishermethod.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" +) + +// FlowDistinguisherMethodApplyConfiguration represents an declarative configuration of the FlowDistinguisherMethod type for use +// with apply. +type FlowDistinguisherMethodApplyConfiguration struct { + Type *v1beta3.FlowDistinguisherMethodType `json:"type,omitempty"` +} + +// FlowDistinguisherMethodApplyConfiguration constructs an declarative configuration of the FlowDistinguisherMethod type for use with +// apply. +func FlowDistinguisherMethod() *FlowDistinguisherMethodApplyConfiguration { + return &FlowDistinguisherMethodApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *FlowDistinguisherMethodApplyConfiguration) WithType(value v1beta3.FlowDistinguisherMethodType) *FlowDistinguisherMethodApplyConfiguration { + b.Type = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschema.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschema.go new file mode 100644 index 00000000000..c95635360ee --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschema.go @@ -0,0 +1,256 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// FlowSchemaApplyConfiguration represents an declarative configuration of the FlowSchema type for use +// with apply. +type FlowSchemaApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *FlowSchemaSpecApplyConfiguration `json:"spec,omitempty"` + Status *FlowSchemaStatusApplyConfiguration `json:"status,omitempty"` +} + +// FlowSchema constructs an declarative configuration of the FlowSchema type for use with +// apply. +func FlowSchema(name string) *FlowSchemaApplyConfiguration { + b := &FlowSchemaApplyConfiguration{} + b.WithName(name) + b.WithKind("FlowSchema") + b.WithAPIVersion("flowcontrol.apiserver.k8s.io/v1beta3") + return b +} + +// ExtractFlowSchema extracts the applied configuration owned by fieldManager from +// flowSchema. If no managedFields are found in flowSchema for fieldManager, a +// FlowSchemaApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// flowSchema must be a unmodified FlowSchema API object that was retrieved from the Kubernetes API. +// ExtractFlowSchema provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractFlowSchema(flowSchema *flowcontrolv1beta3.FlowSchema, fieldManager string) (*FlowSchemaApplyConfiguration, error) { + return extractFlowSchema(flowSchema, fieldManager, "") +} + +// ExtractFlowSchemaStatus is the same as ExtractFlowSchema except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractFlowSchemaStatus(flowSchema *flowcontrolv1beta3.FlowSchema, fieldManager string) (*FlowSchemaApplyConfiguration, error) { + return extractFlowSchema(flowSchema, fieldManager, "status") +} + +func extractFlowSchema(flowSchema *flowcontrolv1beta3.FlowSchema, fieldManager string, subresource string) (*FlowSchemaApplyConfiguration, error) { + b := &FlowSchemaApplyConfiguration{} + err := managedfields.ExtractInto(flowSchema, internal.Parser().Type("io.k8s.api.flowcontrol.v1beta3.FlowSchema"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(flowSchema.Name) + + b.WithKind("FlowSchema") + b.WithAPIVersion("flowcontrol.apiserver.k8s.io/v1beta3") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithKind(value string) *FlowSchemaApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithAPIVersion(value string) *FlowSchemaApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithName(value string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithGenerateName(value string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithNamespace(value string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithUID(value types.UID) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithResourceVersion(value string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithGeneration(value int64) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithCreationTimestamp(value metav1.Time) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *FlowSchemaApplyConfiguration) WithLabels(entries map[string]string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *FlowSchemaApplyConfiguration) WithAnnotations(entries map[string]string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *FlowSchemaApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *FlowSchemaApplyConfiguration) WithFinalizers(values ...string) *FlowSchemaApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *FlowSchemaApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithSpec(value *FlowSchemaSpecApplyConfiguration) *FlowSchemaApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *FlowSchemaApplyConfiguration) WithStatus(value *FlowSchemaStatusApplyConfiguration) *FlowSchemaApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemacondition.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemacondition.go new file mode 100644 index 00000000000..0ef3a2c9214 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemacondition.go @@ -0,0 +1,80 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// FlowSchemaConditionApplyConfiguration represents an declarative configuration of the FlowSchemaCondition type for use +// with apply. +type FlowSchemaConditionApplyConfiguration struct { + Type *v1beta3.FlowSchemaConditionType `json:"type,omitempty"` + Status *v1beta3.ConditionStatus `json:"status,omitempty"` + LastTransitionTime *v1.Time `json:"lastTransitionTime,omitempty"` + Reason *string `json:"reason,omitempty"` + Message *string `json:"message,omitempty"` +} + +// FlowSchemaConditionApplyConfiguration constructs an declarative configuration of the FlowSchemaCondition type for use with +// apply. +func FlowSchemaCondition() *FlowSchemaConditionApplyConfiguration { + return &FlowSchemaConditionApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *FlowSchemaConditionApplyConfiguration) WithType(value v1beta3.FlowSchemaConditionType) *FlowSchemaConditionApplyConfiguration { + b.Type = &value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *FlowSchemaConditionApplyConfiguration) WithStatus(value v1beta3.ConditionStatus) *FlowSchemaConditionApplyConfiguration { + b.Status = &value + return b +} + +// WithLastTransitionTime sets the LastTransitionTime field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LastTransitionTime field is set to the value of the last call. +func (b *FlowSchemaConditionApplyConfiguration) WithLastTransitionTime(value v1.Time) *FlowSchemaConditionApplyConfiguration { + b.LastTransitionTime = &value + return b +} + +// WithReason sets the Reason field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Reason field is set to the value of the last call. +func (b *FlowSchemaConditionApplyConfiguration) WithReason(value string) *FlowSchemaConditionApplyConfiguration { + b.Reason = &value + return b +} + +// WithMessage sets the Message field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Message field is set to the value of the last call. +func (b *FlowSchemaConditionApplyConfiguration) WithMessage(value string) *FlowSchemaConditionApplyConfiguration { + b.Message = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemaspec.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemaspec.go new file mode 100644 index 00000000000..e077ed3fde5 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemaspec.go @@ -0,0 +1,71 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// FlowSchemaSpecApplyConfiguration represents an declarative configuration of the FlowSchemaSpec type for use +// with apply. +type FlowSchemaSpecApplyConfiguration struct { + PriorityLevelConfiguration *PriorityLevelConfigurationReferenceApplyConfiguration `json:"priorityLevelConfiguration,omitempty"` + MatchingPrecedence *int32 `json:"matchingPrecedence,omitempty"` + DistinguisherMethod *FlowDistinguisherMethodApplyConfiguration `json:"distinguisherMethod,omitempty"` + Rules []PolicyRulesWithSubjectsApplyConfiguration `json:"rules,omitempty"` +} + +// FlowSchemaSpecApplyConfiguration constructs an declarative configuration of the FlowSchemaSpec type for use with +// apply. +func FlowSchemaSpec() *FlowSchemaSpecApplyConfiguration { + return &FlowSchemaSpecApplyConfiguration{} +} + +// WithPriorityLevelConfiguration sets the PriorityLevelConfiguration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityLevelConfiguration field is set to the value of the last call. +func (b *FlowSchemaSpecApplyConfiguration) WithPriorityLevelConfiguration(value *PriorityLevelConfigurationReferenceApplyConfiguration) *FlowSchemaSpecApplyConfiguration { + b.PriorityLevelConfiguration = value + return b +} + +// WithMatchingPrecedence sets the MatchingPrecedence field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchingPrecedence field is set to the value of the last call. +func (b *FlowSchemaSpecApplyConfiguration) WithMatchingPrecedence(value int32) *FlowSchemaSpecApplyConfiguration { + b.MatchingPrecedence = &value + return b +} + +// WithDistinguisherMethod sets the DistinguisherMethod field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DistinguisherMethod field is set to the value of the last call. +func (b *FlowSchemaSpecApplyConfiguration) WithDistinguisherMethod(value *FlowDistinguisherMethodApplyConfiguration) *FlowSchemaSpecApplyConfiguration { + b.DistinguisherMethod = value + return b +} + +// WithRules adds the given value to the Rules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Rules field. +func (b *FlowSchemaSpecApplyConfiguration) WithRules(values ...*PolicyRulesWithSubjectsApplyConfiguration) *FlowSchemaSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithRules") + } + b.Rules = append(b.Rules, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemastatus.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemastatus.go new file mode 100644 index 00000000000..18db1c93250 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/flowschemastatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// FlowSchemaStatusApplyConfiguration represents an declarative configuration of the FlowSchemaStatus type for use +// with apply. +type FlowSchemaStatusApplyConfiguration struct { + Conditions []FlowSchemaConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// FlowSchemaStatusApplyConfiguration constructs an declarative configuration of the FlowSchemaStatus type for use with +// apply. +func FlowSchemaStatus() *FlowSchemaStatusApplyConfiguration { + return &FlowSchemaStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *FlowSchemaStatusApplyConfiguration) WithConditions(values ...*FlowSchemaConditionApplyConfiguration) *FlowSchemaStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/groupsubject.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/groupsubject.go new file mode 100644 index 00000000000..b919b711b34 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/groupsubject.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// GroupSubjectApplyConfiguration represents an declarative configuration of the GroupSubject type for use +// with apply. +type GroupSubjectApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// GroupSubjectApplyConfiguration constructs an declarative configuration of the GroupSubject type for use with +// apply. +func GroupSubject() *GroupSubjectApplyConfiguration { + return &GroupSubjectApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *GroupSubjectApplyConfiguration) WithName(value string) *GroupSubjectApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitedprioritylevelconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitedprioritylevelconfiguration.go new file mode 100644 index 00000000000..269a48721c1 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitedprioritylevelconfiguration.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// LimitedPriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the LimitedPriorityLevelConfiguration type for use +// with apply. +type LimitedPriorityLevelConfigurationApplyConfiguration struct { + NominalConcurrencyShares *int32 `json:"nominalConcurrencyShares,omitempty"` + LimitResponse *LimitResponseApplyConfiguration `json:"limitResponse,omitempty"` + LendablePercent *int32 `json:"lendablePercent,omitempty"` + BorrowingLimitPercent *int32 `json:"borrowingLimitPercent,omitempty"` +} + +// LimitedPriorityLevelConfigurationApplyConfiguration constructs an declarative configuration of the LimitedPriorityLevelConfiguration type for use with +// apply. +func LimitedPriorityLevelConfiguration() *LimitedPriorityLevelConfigurationApplyConfiguration { + return &LimitedPriorityLevelConfigurationApplyConfiguration{} +} + +// WithNominalConcurrencyShares sets the NominalConcurrencyShares field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NominalConcurrencyShares field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithNominalConcurrencyShares(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.NominalConcurrencyShares = &value + return b +} + +// WithLimitResponse sets the LimitResponse field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LimitResponse field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLimitResponse(value *LimitResponseApplyConfiguration) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.LimitResponse = value + return b +} + +// WithLendablePercent sets the LendablePercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LendablePercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithLendablePercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.LendablePercent = &value + return b +} + +// WithBorrowingLimitPercent sets the BorrowingLimitPercent field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BorrowingLimitPercent field is set to the value of the last call. +func (b *LimitedPriorityLevelConfigurationApplyConfiguration) WithBorrowingLimitPercent(value int32) *LimitedPriorityLevelConfigurationApplyConfiguration { + b.BorrowingLimitPercent = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitresponse.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitresponse.go new file mode 100644 index 00000000000..b7a64ebfee2 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/limitresponse.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" +) + +// LimitResponseApplyConfiguration represents an declarative configuration of the LimitResponse type for use +// with apply. +type LimitResponseApplyConfiguration struct { + Type *v1beta3.LimitResponseType `json:"type,omitempty"` + Queuing *QueuingConfigurationApplyConfiguration `json:"queuing,omitempty"` +} + +// LimitResponseApplyConfiguration constructs an declarative configuration of the LimitResponse type for use with +// apply. +func LimitResponse() *LimitResponseApplyConfiguration { + return &LimitResponseApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *LimitResponseApplyConfiguration) WithType(value v1beta3.LimitResponseType) *LimitResponseApplyConfiguration { + b.Type = &value + return b +} + +// WithQueuing sets the Queuing field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Queuing field is set to the value of the last call. +func (b *LimitResponseApplyConfiguration) WithQueuing(value *QueuingConfigurationApplyConfiguration) *LimitResponseApplyConfiguration { + b.Queuing = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/nonresourcepolicyrule.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/nonresourcepolicyrule.go new file mode 100644 index 00000000000..ecb47f52cf1 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/nonresourcepolicyrule.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// NonResourcePolicyRuleApplyConfiguration represents an declarative configuration of the NonResourcePolicyRule type for use +// with apply. +type NonResourcePolicyRuleApplyConfiguration struct { + Verbs []string `json:"verbs,omitempty"` + NonResourceURLs []string `json:"nonResourceURLs,omitempty"` +} + +// NonResourcePolicyRuleApplyConfiguration constructs an declarative configuration of the NonResourcePolicyRule type for use with +// apply. +func NonResourcePolicyRule() *NonResourcePolicyRuleApplyConfiguration { + return &NonResourcePolicyRuleApplyConfiguration{} +} + +// WithVerbs adds the given value to the Verbs field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Verbs field. +func (b *NonResourcePolicyRuleApplyConfiguration) WithVerbs(values ...string) *NonResourcePolicyRuleApplyConfiguration { + for i := range values { + b.Verbs = append(b.Verbs, values[i]) + } + return b +} + +// WithNonResourceURLs adds the given value to the NonResourceURLs field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the NonResourceURLs field. +func (b *NonResourcePolicyRuleApplyConfiguration) WithNonResourceURLs(values ...string) *NonResourcePolicyRuleApplyConfiguration { + for i := range values { + b.NonResourceURLs = append(b.NonResourceURLs, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/policyruleswithsubjects.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/policyruleswithsubjects.go new file mode 100644 index 00000000000..e30aace1941 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/policyruleswithsubjects.go @@ -0,0 +1,72 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// PolicyRulesWithSubjectsApplyConfiguration represents an declarative configuration of the PolicyRulesWithSubjects type for use +// with apply. +type PolicyRulesWithSubjectsApplyConfiguration struct { + Subjects []SubjectApplyConfiguration `json:"subjects,omitempty"` + ResourceRules []ResourcePolicyRuleApplyConfiguration `json:"resourceRules,omitempty"` + NonResourceRules []NonResourcePolicyRuleApplyConfiguration `json:"nonResourceRules,omitempty"` +} + +// PolicyRulesWithSubjectsApplyConfiguration constructs an declarative configuration of the PolicyRulesWithSubjects type for use with +// apply. +func PolicyRulesWithSubjects() *PolicyRulesWithSubjectsApplyConfiguration { + return &PolicyRulesWithSubjectsApplyConfiguration{} +} + +// WithSubjects adds the given value to the Subjects field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Subjects field. +func (b *PolicyRulesWithSubjectsApplyConfiguration) WithSubjects(values ...*SubjectApplyConfiguration) *PolicyRulesWithSubjectsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithSubjects") + } + b.Subjects = append(b.Subjects, *values[i]) + } + return b +} + +// WithResourceRules adds the given value to the ResourceRules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceRules field. +func (b *PolicyRulesWithSubjectsApplyConfiguration) WithResourceRules(values ...*ResourcePolicyRuleApplyConfiguration) *PolicyRulesWithSubjectsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceRules") + } + b.ResourceRules = append(b.ResourceRules, *values[i]) + } + return b +} + +// WithNonResourceRules adds the given value to the NonResourceRules field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the NonResourceRules field. +func (b *PolicyRulesWithSubjectsApplyConfiguration) WithNonResourceRules(values ...*NonResourcePolicyRuleApplyConfiguration) *PolicyRulesWithSubjectsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithNonResourceRules") + } + b.NonResourceRules = append(b.NonResourceRules, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfiguration.go new file mode 100644 index 00000000000..6fbbbea8fe9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfiguration.go @@ -0,0 +1,256 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// PriorityLevelConfigurationApplyConfiguration represents an declarative configuration of the PriorityLevelConfiguration type for use +// with apply. +type PriorityLevelConfigurationApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *PriorityLevelConfigurationSpecApplyConfiguration `json:"spec,omitempty"` + Status *PriorityLevelConfigurationStatusApplyConfiguration `json:"status,omitempty"` +} + +// PriorityLevelConfiguration constructs an declarative configuration of the PriorityLevelConfiguration type for use with +// apply. +func PriorityLevelConfiguration(name string) *PriorityLevelConfigurationApplyConfiguration { + b := &PriorityLevelConfigurationApplyConfiguration{} + b.WithName(name) + b.WithKind("PriorityLevelConfiguration") + b.WithAPIVersion("flowcontrol.apiserver.k8s.io/v1beta3") + return b +} + +// ExtractPriorityLevelConfiguration extracts the applied configuration owned by fieldManager from +// priorityLevelConfiguration. If no managedFields are found in priorityLevelConfiguration for fieldManager, a +// PriorityLevelConfigurationApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// priorityLevelConfiguration must be a unmodified PriorityLevelConfiguration API object that was retrieved from the Kubernetes API. +// ExtractPriorityLevelConfiguration provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractPriorityLevelConfiguration(priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfiguration, fieldManager string) (*PriorityLevelConfigurationApplyConfiguration, error) { + return extractPriorityLevelConfiguration(priorityLevelConfiguration, fieldManager, "") +} + +// ExtractPriorityLevelConfigurationStatus is the same as ExtractPriorityLevelConfiguration except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractPriorityLevelConfigurationStatus(priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfiguration, fieldManager string) (*PriorityLevelConfigurationApplyConfiguration, error) { + return extractPriorityLevelConfiguration(priorityLevelConfiguration, fieldManager, "status") +} + +func extractPriorityLevelConfiguration(priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfiguration, fieldManager string, subresource string) (*PriorityLevelConfigurationApplyConfiguration, error) { + b := &PriorityLevelConfigurationApplyConfiguration{} + err := managedfields.ExtractInto(priorityLevelConfiguration, internal.Parser().Type("io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfiguration"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(priorityLevelConfiguration.Name) + + b.WithKind("PriorityLevelConfiguration") + b.WithAPIVersion("flowcontrol.apiserver.k8s.io/v1beta3") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithKind(value string) *PriorityLevelConfigurationApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithAPIVersion(value string) *PriorityLevelConfigurationApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithName(value string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithGenerateName(value string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithNamespace(value string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithUID(value types.UID) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithResourceVersion(value string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithGeneration(value int64) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *PriorityLevelConfigurationApplyConfiguration) WithLabels(entries map[string]string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *PriorityLevelConfigurationApplyConfiguration) WithAnnotations(entries map[string]string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *PriorityLevelConfigurationApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *PriorityLevelConfigurationApplyConfiguration) WithFinalizers(values ...string) *PriorityLevelConfigurationApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *PriorityLevelConfigurationApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithSpec(value *PriorityLevelConfigurationSpecApplyConfiguration) *PriorityLevelConfigurationApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PriorityLevelConfigurationApplyConfiguration) WithStatus(value *PriorityLevelConfigurationStatusApplyConfiguration) *PriorityLevelConfigurationApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationcondition.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationcondition.go new file mode 100644 index 00000000000..6e36b6a079f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationcondition.go @@ -0,0 +1,80 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// PriorityLevelConfigurationConditionApplyConfiguration represents an declarative configuration of the PriorityLevelConfigurationCondition type for use +// with apply. +type PriorityLevelConfigurationConditionApplyConfiguration struct { + Type *v1beta3.PriorityLevelConfigurationConditionType `json:"type,omitempty"` + Status *v1beta3.ConditionStatus `json:"status,omitempty"` + LastTransitionTime *v1.Time `json:"lastTransitionTime,omitempty"` + Reason *string `json:"reason,omitempty"` + Message *string `json:"message,omitempty"` +} + +// PriorityLevelConfigurationConditionApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationCondition type for use with +// apply. +func PriorityLevelConfigurationCondition() *PriorityLevelConfigurationConditionApplyConfiguration { + return &PriorityLevelConfigurationConditionApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *PriorityLevelConfigurationConditionApplyConfiguration) WithType(value v1beta3.PriorityLevelConfigurationConditionType) *PriorityLevelConfigurationConditionApplyConfiguration { + b.Type = &value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PriorityLevelConfigurationConditionApplyConfiguration) WithStatus(value v1beta3.ConditionStatus) *PriorityLevelConfigurationConditionApplyConfiguration { + b.Status = &value + return b +} + +// WithLastTransitionTime sets the LastTransitionTime field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LastTransitionTime field is set to the value of the last call. +func (b *PriorityLevelConfigurationConditionApplyConfiguration) WithLastTransitionTime(value v1.Time) *PriorityLevelConfigurationConditionApplyConfiguration { + b.LastTransitionTime = &value + return b +} + +// WithReason sets the Reason field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Reason field is set to the value of the last call. +func (b *PriorityLevelConfigurationConditionApplyConfiguration) WithReason(value string) *PriorityLevelConfigurationConditionApplyConfiguration { + b.Reason = &value + return b +} + +// WithMessage sets the Message field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Message field is set to the value of the last call. +func (b *PriorityLevelConfigurationConditionApplyConfiguration) WithMessage(value string) *PriorityLevelConfigurationConditionApplyConfiguration { + b.Message = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationreference.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationreference.go new file mode 100644 index 00000000000..cb827b1e62c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationreference.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// PriorityLevelConfigurationReferenceApplyConfiguration represents an declarative configuration of the PriorityLevelConfigurationReference type for use +// with apply. +type PriorityLevelConfigurationReferenceApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// PriorityLevelConfigurationReferenceApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationReference type for use with +// apply. +func PriorityLevelConfigurationReference() *PriorityLevelConfigurationReferenceApplyConfiguration { + return &PriorityLevelConfigurationReferenceApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PriorityLevelConfigurationReferenceApplyConfiguration) WithName(value string) *PriorityLevelConfigurationReferenceApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationspec.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationspec.go new file mode 100644 index 00000000000..f67f3944556 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationspec.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" +) + +// PriorityLevelConfigurationSpecApplyConfiguration represents an declarative configuration of the PriorityLevelConfigurationSpec type for use +// with apply. +type PriorityLevelConfigurationSpecApplyConfiguration struct { + Type *v1beta3.PriorityLevelEnablement `json:"type,omitempty"` + Limited *LimitedPriorityLevelConfigurationApplyConfiguration `json:"limited,omitempty"` +} + +// PriorityLevelConfigurationSpecApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationSpec type for use with +// apply. +func PriorityLevelConfigurationSpec() *PriorityLevelConfigurationSpecApplyConfiguration { + return &PriorityLevelConfigurationSpecApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithType(value v1beta3.PriorityLevelEnablement) *PriorityLevelConfigurationSpecApplyConfiguration { + b.Type = &value + return b +} + +// WithLimited sets the Limited field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Limited field is set to the value of the last call. +func (b *PriorityLevelConfigurationSpecApplyConfiguration) WithLimited(value *LimitedPriorityLevelConfigurationApplyConfiguration) *PriorityLevelConfigurationSpecApplyConfiguration { + b.Limited = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationstatus.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationstatus.go new file mode 100644 index 00000000000..0ee9e306ebc --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/prioritylevelconfigurationstatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// PriorityLevelConfigurationStatusApplyConfiguration represents an declarative configuration of the PriorityLevelConfigurationStatus type for use +// with apply. +type PriorityLevelConfigurationStatusApplyConfiguration struct { + Conditions []PriorityLevelConfigurationConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// PriorityLevelConfigurationStatusApplyConfiguration constructs an declarative configuration of the PriorityLevelConfigurationStatus type for use with +// apply. +func PriorityLevelConfigurationStatus() *PriorityLevelConfigurationStatusApplyConfiguration { + return &PriorityLevelConfigurationStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *PriorityLevelConfigurationStatusApplyConfiguration) WithConditions(values ...*PriorityLevelConfigurationConditionApplyConfiguration) *PriorityLevelConfigurationStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/queuingconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/queuingconfiguration.go new file mode 100644 index 00000000000..fc86c444317 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/queuingconfiguration.go @@ -0,0 +1,57 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// QueuingConfigurationApplyConfiguration represents an declarative configuration of the QueuingConfiguration type for use +// with apply. +type QueuingConfigurationApplyConfiguration struct { + Queues *int32 `json:"queues,omitempty"` + HandSize *int32 `json:"handSize,omitempty"` + QueueLengthLimit *int32 `json:"queueLengthLimit,omitempty"` +} + +// QueuingConfigurationApplyConfiguration constructs an declarative configuration of the QueuingConfiguration type for use with +// apply. +func QueuingConfiguration() *QueuingConfigurationApplyConfiguration { + return &QueuingConfigurationApplyConfiguration{} +} + +// WithQueues sets the Queues field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Queues field is set to the value of the last call. +func (b *QueuingConfigurationApplyConfiguration) WithQueues(value int32) *QueuingConfigurationApplyConfiguration { + b.Queues = &value + return b +} + +// WithHandSize sets the HandSize field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HandSize field is set to the value of the last call. +func (b *QueuingConfigurationApplyConfiguration) WithHandSize(value int32) *QueuingConfigurationApplyConfiguration { + b.HandSize = &value + return b +} + +// WithQueueLengthLimit sets the QueueLengthLimit field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the QueueLengthLimit field is set to the value of the last call. +func (b *QueuingConfigurationApplyConfiguration) WithQueueLengthLimit(value int32) *QueuingConfigurationApplyConfiguration { + b.QueueLengthLimit = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/resourcepolicyrule.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/resourcepolicyrule.go new file mode 100644 index 00000000000..72623ffe49c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/resourcepolicyrule.go @@ -0,0 +1,83 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// ResourcePolicyRuleApplyConfiguration represents an declarative configuration of the ResourcePolicyRule type for use +// with apply. +type ResourcePolicyRuleApplyConfiguration struct { + Verbs []string `json:"verbs,omitempty"` + APIGroups []string `json:"apiGroups,omitempty"` + Resources []string `json:"resources,omitempty"` + ClusterScope *bool `json:"clusterScope,omitempty"` + Namespaces []string `json:"namespaces,omitempty"` +} + +// ResourcePolicyRuleApplyConfiguration constructs an declarative configuration of the ResourcePolicyRule type for use with +// apply. +func ResourcePolicyRule() *ResourcePolicyRuleApplyConfiguration { + return &ResourcePolicyRuleApplyConfiguration{} +} + +// WithVerbs adds the given value to the Verbs field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Verbs field. +func (b *ResourcePolicyRuleApplyConfiguration) WithVerbs(values ...string) *ResourcePolicyRuleApplyConfiguration { + for i := range values { + b.Verbs = append(b.Verbs, values[i]) + } + return b +} + +// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the APIGroups field. +func (b *ResourcePolicyRuleApplyConfiguration) WithAPIGroups(values ...string) *ResourcePolicyRuleApplyConfiguration { + for i := range values { + b.APIGroups = append(b.APIGroups, values[i]) + } + return b +} + +// WithResources adds the given value to the Resources field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Resources field. +func (b *ResourcePolicyRuleApplyConfiguration) WithResources(values ...string) *ResourcePolicyRuleApplyConfiguration { + for i := range values { + b.Resources = append(b.Resources, values[i]) + } + return b +} + +// WithClusterScope sets the ClusterScope field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ClusterScope field is set to the value of the last call. +func (b *ResourcePolicyRuleApplyConfiguration) WithClusterScope(value bool) *ResourcePolicyRuleApplyConfiguration { + b.ClusterScope = &value + return b +} + +// WithNamespaces adds the given value to the Namespaces field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Namespaces field. +func (b *ResourcePolicyRuleApplyConfiguration) WithNamespaces(values ...string) *ResourcePolicyRuleApplyConfiguration { + for i := range values { + b.Namespaces = append(b.Namespaces, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/serviceaccountsubject.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/serviceaccountsubject.go new file mode 100644 index 00000000000..e2d6b1b213f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/serviceaccountsubject.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// ServiceAccountSubjectApplyConfiguration represents an declarative configuration of the ServiceAccountSubject type for use +// with apply. +type ServiceAccountSubjectApplyConfiguration struct { + Namespace *string `json:"namespace,omitempty"` + Name *string `json:"name,omitempty"` +} + +// ServiceAccountSubjectApplyConfiguration constructs an declarative configuration of the ServiceAccountSubject type for use with +// apply. +func ServiceAccountSubject() *ServiceAccountSubjectApplyConfiguration { + return &ServiceAccountSubjectApplyConfiguration{} +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ServiceAccountSubjectApplyConfiguration) WithNamespace(value string) *ServiceAccountSubjectApplyConfiguration { + b.Namespace = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ServiceAccountSubjectApplyConfiguration) WithName(value string) *ServiceAccountSubjectApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/subject.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/subject.go new file mode 100644 index 00000000000..f13b8f3ec5a --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/subject.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" +) + +// SubjectApplyConfiguration represents an declarative configuration of the Subject type for use +// with apply. +type SubjectApplyConfiguration struct { + Kind *v1beta3.SubjectKind `json:"kind,omitempty"` + User *UserSubjectApplyConfiguration `json:"user,omitempty"` + Group *GroupSubjectApplyConfiguration `json:"group,omitempty"` + ServiceAccount *ServiceAccountSubjectApplyConfiguration `json:"serviceAccount,omitempty"` +} + +// SubjectApplyConfiguration constructs an declarative configuration of the Subject type for use with +// apply. +func Subject() *SubjectApplyConfiguration { + return &SubjectApplyConfiguration{} +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *SubjectApplyConfiguration) WithKind(value v1beta3.SubjectKind) *SubjectApplyConfiguration { + b.Kind = &value + return b +} + +// WithUser sets the User field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the User field is set to the value of the last call. +func (b *SubjectApplyConfiguration) WithUser(value *UserSubjectApplyConfiguration) *SubjectApplyConfiguration { + b.User = value + return b +} + +// WithGroup sets the Group field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Group field is set to the value of the last call. +func (b *SubjectApplyConfiguration) WithGroup(value *GroupSubjectApplyConfiguration) *SubjectApplyConfiguration { + b.Group = value + return b +} + +// WithServiceAccount sets the ServiceAccount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceAccount field is set to the value of the last call. +func (b *SubjectApplyConfiguration) WithServiceAccount(value *ServiceAccountSubjectApplyConfiguration) *SubjectApplyConfiguration { + b.ServiceAccount = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/usersubject.go b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/usersubject.go new file mode 100644 index 00000000000..3db3abbc1a1 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/usersubject.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta3 + +// UserSubjectApplyConfiguration represents an declarative configuration of the UserSubject type for use +// with apply. +type UserSubjectApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// UserSubjectApplyConfiguration constructs an declarative configuration of the UserSubject type for use with +// apply. +func UserSubject() *UserSubjectApplyConfiguration { + return &UserSubjectApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *UserSubjectApplyConfiguration) WithName(value string) *UserSubjectApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go index f8e9eec8ff9..361b2f4e855 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -39,6 +39,17 @@ func Parser() *typed.Parser { var parserOnce sync.Once var parser *typed.Parser var schemaYAML = typed.YAMLObject(`types: +- name: io.k8s.api.admissionregistration.v1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1.MutatingWebhook map: fields: @@ -55,6 +66,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -167,6 +186,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -225,51 +252,152 @@ var schemaYAML = typed.YAMLObject(`types: - name: url type: scalar: string -- name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook +- name: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation map: fields: - - name: admissionReviewVersions + - name: key type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: clientConfig + scalar: string + default: "" + - name: valueExpression type: - namedType: io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig - default: {} - - name: failurePolicy + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning + map: + fields: + - name: fieldRef type: scalar: string - - name: matchPolicy + default: "" + - name: warning + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + map: + fields: + - name: expression type: scalar: string + default: "" - name: name type: scalar: string default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.MatchResources + map: + fields: + - name: excludeResourceRules + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.NamedRuleWithOperations + elementRelationship: atomic + - name: matchPolicy + type: + scalar: string - name: namespaceSelector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - name: objectSelector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: reinvocationPolicy + - name: resourceRules + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.NamedRuleWithOperations + elementRelationship: atomic + elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.NamedRuleWithOperations + map: + fields: + - name: apiGroups + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: apiVersions + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: operations + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: resourceNames + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: resources + type: + list: + elementType: + scalar: string + elementRelationship: atomic + - name: scope type: scalar: string - - name: rules + elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.ParamKind + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.ParamRef + map: + fields: + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.TypeChecking + map: + fields: + - name: expressionWarnings type: list: elementType: - namedType: io.k8s.api.admissionregistration.v1beta1.RuleWithOperations + namedType: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning elementRelationship: atomic - - name: sideEffects +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy + map: + fields: + - name: apiVersion type: scalar: string - - name: timeoutSeconds + - name: kind type: - scalar: numeric -- name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhookConfiguration + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec + default: {} + - name: status + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + default: {} +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding map: fields: - name: apiVersion @@ -282,62 +410,105 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta default: {} - - name: webhooks + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingSpec + default: {} +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingSpec + map: + fields: + - name: matchResources + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources + - name: paramRef + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ParamRef + - name: policyName + type: + scalar: string + - name: validationActions type: list: elementType: - namedType: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook + scalar: string elementRelationship: associative - keys: - - name -- name: io.k8s.api.admissionregistration.v1beta1.RuleWithOperations +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec map: fields: - - name: apiGroups + - name: auditAnnotations type: list: elementType: - scalar: string + namedType: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation elementRelationship: atomic - - name: apiVersions + - name: failurePolicy + type: + scalar: string + - name: matchConditions type: list: elementType: - scalar: string - elementRelationship: atomic - - name: operations + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + elementRelationship: associative + keys: + - name + - name: matchConstraints + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources + - name: paramKind + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ParamKind + - name: validations type: list: elementType: - scalar: string + namedType: io.k8s.api.admissionregistration.v1alpha1.Validation elementRelationship: atomic - - name: resources +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + map: + fields: + - name: conditions type: list: elementType: - scalar: string - elementRelationship: atomic - - name: scope + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: observedGeneration type: - scalar: string -- name: io.k8s.api.admissionregistration.v1beta1.ServiceReference + scalar: numeric + - name: typeChecking + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.TypeChecking +- name: io.k8s.api.admissionregistration.v1alpha1.Validation map: fields: - - name: name + - name: expression type: scalar: string default: "" - - name: namespace + - name: message type: scalar: string - default: "" - - name: path + - name: messageExpression type: scalar: string - - name: port + - name: reason type: - scalar: numeric -- name: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhook + scalar: string +- name: io.k8s.api.admissionregistration.v1beta1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook map: fields: - name: admissionReviewVersions @@ -353,6 +524,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -366,11 +545,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: objectSelector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: reinvocationPolicy + type: + scalar: string - name: rules type: list: elementType: - namedType: io.k8s.api.admissionregistration.v1beta1.RuleWithOperations + namedType: io.k8s.api.admissionregistration.v1.RuleWithOperations elementRelationship: atomic - name: sideEffects type: @@ -378,7 +560,7 @@ var schemaYAML = typed.YAMLObject(`types: - name: timeoutSeconds type: scalar: numeric -- name: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhookConfiguration +- name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhookConfiguration map: fields: - name: apiVersion @@ -395,49 +577,136 @@ var schemaYAML = typed.YAMLObject(`types: type: list: elementType: - namedType: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhook + namedType: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook elementRelationship: associative keys: - name -- name: io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig +- name: io.k8s.api.admissionregistration.v1beta1.ServiceReference map: fields: - - name: caBundle + - name: name type: scalar: string - - name: service + default: "" + - name: namespace type: - namedType: io.k8s.api.admissionregistration.v1beta1.ServiceReference - - name: url + scalar: string + default: "" + - name: path type: scalar: string -- name: io.k8s.api.apiserverinternal.v1alpha1.ServerStorageVersion + - name: port + type: + scalar: numeric +- name: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhook map: fields: - - name: apiServerID - type: - scalar: string - - name: decodableVersions + - name: admissionReviewVersions type: list: elementType: scalar: string - elementRelationship: associative - - name: encodingVersion - type: - scalar: string -- name: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion - map: - fields: - - name: apiVersion + elementRelationship: atomic + - name: clientConfig type: - scalar: string - - name: kind + namedType: io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig + default: {} + - name: failurePolicy type: scalar: string - - name: metadata + - name: matchConditions type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name + - name: matchPolicy + type: + scalar: string + - name: name + type: + scalar: string + default: "" + - name: namespaceSelector + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: objectSelector + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: rules + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.RuleWithOperations + elementRelationship: atomic + - name: sideEffects + type: + scalar: string + - name: timeoutSeconds + type: + scalar: numeric +- name: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhookConfiguration + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: webhooks + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.ValidatingWebhook + elementRelationship: associative + keys: + - name +- name: io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig + map: + fields: + - name: caBundle + type: + scalar: string + - name: service + type: + namedType: io.k8s.api.admissionregistration.v1beta1.ServiceReference + - name: url + type: + scalar: string +- name: io.k8s.api.apiserverinternal.v1alpha1.ServerStorageVersion + map: + fields: + - name: apiServerID + type: + scalar: string + - name: decodableVersions + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: encodingVersion + type: + scalar: string +- name: io.k8s.api.apiserverinternal.v1alpha1.StorageVersion + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta default: {} - name: spec type: @@ -910,6 +1179,13 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.apps.v1.StatefulSetOrdinals + map: + fields: + - name: start + type: + scalar: numeric + default: 0 - name: io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy map: fields: @@ -925,6 +1201,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: minReadySeconds type: scalar: numeric + - name: ordinals + type: + namedType: io.k8s.api.apps.v1.StatefulSetOrdinals - name: persistentVolumeClaimRetentionPolicy type: namedType: io.k8s.api.apps.v1.StatefulSetPersistentVolumeClaimRetentionPolicy @@ -1213,6 +1492,13 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.apps.v1beta1.StatefulSetOrdinals + map: + fields: + - name: start + type: + scalar: numeric + default: 0 - name: io.k8s.api.apps.v1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy map: fields: @@ -1228,6 +1514,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: minReadySeconds type: scalar: numeric + - name: ordinals + type: + namedType: io.k8s.api.apps.v1beta1.StatefulSetOrdinals - name: persistentVolumeClaimRetentionPolicy type: namedType: io.k8s.api.apps.v1beta1.StatefulSetPersistentVolumeClaimRetentionPolicy @@ -1714,6 +2003,13 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.apps.v1beta2.StatefulSetOrdinals + map: + fields: + - name: start + type: + scalar: numeric + default: 0 - name: io.k8s.api.apps.v1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy map: fields: @@ -1729,6 +2025,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: minReadySeconds type: scalar: numeric + - name: ordinals + type: + namedType: io.k8s.api.apps.v1beta2.StatefulSetOrdinals - name: persistentVolumeClaimRetentionPolicy type: namedType: io.k8s.api.apps.v1beta2.StatefulSetPersistentVolumeClaimRetentionPolicy @@ -3041,6 +3340,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: parallelism type: scalar: numeric + - name: podFailurePolicy + type: + namedType: io.k8s.api.batch.v1.PodFailurePolicy - name: selector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector @@ -3098,6 +3400,58 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.api.batch.v1.JobSpec default: {} +- name: io.k8s.api.batch.v1.PodFailurePolicy + map: + fields: + - name: rules + type: + list: + elementType: + namedType: io.k8s.api.batch.v1.PodFailurePolicyRule + elementRelationship: atomic +- name: io.k8s.api.batch.v1.PodFailurePolicyOnExitCodesRequirement + map: + fields: + - name: containerName + type: + scalar: string + - name: operator + type: + scalar: string + default: "" + - name: values + type: + list: + elementType: + scalar: numeric + elementRelationship: associative +- name: io.k8s.api.batch.v1.PodFailurePolicyOnPodConditionsPattern + map: + fields: + - name: status + type: + scalar: string + default: "" + - name: type + type: + scalar: string + default: "" +- name: io.k8s.api.batch.v1.PodFailurePolicyRule + map: + fields: + - name: action + type: + scalar: string + default: "" + - name: onExitCodes + type: + namedType: io.k8s.api.batch.v1.PodFailurePolicyOnExitCodesRequirement + - name: onPodConditions + type: + list: + elementType: + namedType: io.k8s.api.batch.v1.PodFailurePolicyOnPodConditionsPattern + elementRelationship: atomic - name: io.k8s.api.batch.v1.UncountedTerminatedPods map: fields: @@ -3288,6 +3642,33 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundle + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + default: {} +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + map: + fields: + - name: signerName + type: + scalar: string + - name: trustBundle + type: + scalar: string + default: "" - name: io.k8s.api.certificates.v1beta1.CertificateSigningRequest map: fields: @@ -3565,6 +3946,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: fsType type: scalar: string + - name: nodeExpandSecretRef + type: + namedType: io.k8s.api.core.v1.SecretReference - name: nodePublishSecretRef type: namedType: io.k8s.api.core.v1.SecretReference @@ -3699,6 +4083,15 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.core.v1.ClaimSource + map: + fields: + - name: resourceClaimName + type: + scalar: string + - name: resourceClaimTemplateName + type: + scalar: string - name: io.k8s.api.core.v1.ClientIPConfig map: fields: @@ -3903,6 +4296,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -3979,6 +4378,17 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: TCP +- name: io.k8s.api.core.v1.ContainerResizePolicy + map: + fields: + - name: resourceName + type: + scalar: string + default: "" + - name: restartPolicy + type: + scalar: string + default: "" - name: io.k8s.api.core.v1.ContainerState map: fields: @@ -4037,6 +4447,11 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.core.v1.ContainerStatus map: fields: + - name: allocatedResources + type: + map: + elementType: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - name: containerID type: scalar: string @@ -4060,6 +4475,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: boolean default: false + - name: resources + type: + namedType: io.k8s.api.core.v1.ResourceRequirements - name: restartCount type: scalar: numeric @@ -4295,6 +4713,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -5327,7 +5751,7 @@ var schemaYAML = typed.YAMLObject(`types: namedType: io.k8s.api.core.v1.TypedLocalObjectReference - name: dataSourceRef type: - namedType: io.k8s.api.core.v1.TypedLocalObjectReference + namedType: io.k8s.api.core.v1.TypedObjectReference - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -5430,6 +5854,7 @@ var schemaYAML = typed.YAMLObject(`types: - name: claimRef type: namedType: io.k8s.api.core.v1.ObjectReference + elementRelationship: separable - name: csi type: namedType: io.k8s.api.core.v1.CSIPersistentVolumeSource @@ -5666,6 +6091,24 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.core.v1.PodResourceClaim + map: + fields: + - name: name + type: + scalar: string + default: "" + - name: source + type: + namedType: io.k8s.api.core.v1.ClaimSource + default: {} +- name: io.k8s.api.core.v1.PodSchedulingGate + map: + fields: + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.core.v1.PodSecurityContext map: fields: @@ -5759,6 +6202,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: hostPID type: scalar: boolean + - name: hostUsers + type: + scalar: boolean - name: hostname type: scalar: string @@ -5810,6 +6256,14 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.core.v1.PodReadinessGate elementRelationship: atomic + - name: resourceClaims + type: + list: + elementType: + namedType: io.k8s.api.core.v1.PodResourceClaim + elementRelationship: associative + keys: + - name - name: restartPolicy type: scalar: string @@ -5819,6 +6273,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: schedulerName type: scalar: string + - name: schedulingGates + type: + list: + elementType: + namedType: io.k8s.api.core.v1.PodSchedulingGate + elementRelationship: associative + keys: + - name - name: securityContext type: namedType: io.k8s.api.core.v1.PodSecurityContext @@ -5921,6 +6383,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: reason type: scalar: string + - name: resize + type: + scalar: string - name: startTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time @@ -6207,6 +6672,13 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 +- name: io.k8s.api.core.v1.ResourceClaim + map: + fields: + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.core.v1.ResourceFieldSelector map: fields: @@ -6276,6 +6748,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.core.v1.ResourceRequirements map: fields: + - name: claims + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ResourceClaim + elementRelationship: associative + keys: + - name - name: limits type: map: @@ -6855,13 +7335,25 @@ var schemaYAML = typed.YAMLObject(`types: - name: labelSelector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: maxSkew + - name: matchLabelKeys type: - scalar: numeric - default: 0 + list: + elementType: + scalar: string + elementRelationship: atomic + - name: maxSkew + type: + scalar: numeric + default: 0 - name: minDomains type: scalar: numeric + - name: nodeAffinityPolicy + type: + scalar: string + - name: nodeTaintsPolicy + type: + scalar: string - name: topologyKey type: scalar: string @@ -6885,6 +7377,23 @@ var schemaYAML = typed.YAMLObject(`types: scalar: string default: "" elementRelationship: atomic +- name: io.k8s.api.core.v1.TypedObjectReference + map: + fields: + - name: apiGroup + type: + scalar: string + - name: kind + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" + - name: namespace + type: + scalar: string - name: io.k8s.api.core.v1.Volume map: fields: @@ -7426,29 +7935,6 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime default: {} -- name: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - map: - fields: - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - map: - fields: - - name: driver - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedHostPath - map: - fields: - - name: pathPrefix - type: - scalar: string - - name: readOnly - type: - scalar: boolean - name: io.k8s.api.extensions.v1beta1.DaemonSet map: fields: @@ -7684,18 +8170,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - name: io.k8s.api.extensions.v1beta1.HTTPIngressPath map: fields: @@ -7718,28 +8192,6 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.extensions.v1beta1.HTTPIngressPath elementRelationship: atomic -- name: io.k8s.api.extensions.v1beta1.HostPortRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 -- name: io.k8s.api.extensions.v1beta1.IDRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 - name: io.k8s.api.extensions.v1beta1.IPBlock map: fields: @@ -7787,6 +8239,44 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.util.intstr.IntOrString default: {} +- name: io.k8s.api.extensions.v1beta1.IngressLoadBalancerIngress + map: + fields: + - name: hostname + type: + scalar: string + - name: ip + type: + scalar: string + - name: ports + type: + list: + elementType: + namedType: io.k8s.api.extensions.v1beta1.IngressPortStatus + elementRelationship: atomic +- name: io.k8s.api.extensions.v1beta1.IngressLoadBalancerStatus + map: + fields: + - name: ingress + type: + list: + elementType: + namedType: io.k8s.api.extensions.v1beta1.IngressLoadBalancerIngress + elementRelationship: atomic +- name: io.k8s.api.extensions.v1beta1.IngressPortStatus + map: + fields: + - name: error + type: + scalar: string + - name: port + type: + scalar: numeric + default: 0 + - name: protocol + type: + scalar: string + default: "" - name: io.k8s.api.extensions.v1beta1.IngressRule map: fields: @@ -7822,7 +8312,7 @@ var schemaYAML = typed.YAMLObject(`types: fields: - name: loadBalancer type: - namedType: io.k8s.api.core.v1.LoadBalancerStatus + namedType: io.k8s.api.extensions.v1beta1.IngressLoadBalancerStatus default: {} - name: io.k8s.api.extensions.v1beta1.IngressTLS map: @@ -7947,135 +8437,6 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicy - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - default: {} -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - map: - fields: - - name: allowPrivilegeEscalation - type: - scalar: boolean - - name: allowedCSIDrivers - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - elementRelationship: atomic - - name: allowedCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedFlexVolumes - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - elementRelationship: atomic - - name: allowedHostPaths - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedHostPath - elementRelationship: atomic - - name: allowedProcMountTypes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedUnsafeSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAddCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAllowPrivilegeEscalation - type: - scalar: boolean - - name: forbiddenSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: fsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - default: {} - - name: hostIPC - type: - scalar: boolean - - name: hostNetwork - type: - scalar: boolean - - name: hostPID - type: - scalar: boolean - - name: hostPorts - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.HostPortRange - elementRelationship: atomic - - name: privileged - type: - scalar: boolean - - name: readOnlyRootFilesystem - type: - scalar: boolean - - name: requiredDropCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: runAsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions - - name: runAsUser - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions - default: {} - - name: runtimeClass - type: - namedType: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - - name: seLinux - type: - namedType: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - default: {} - - name: supplementalGroups - type: - namedType: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions - default: {} - - name: volumes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - name: io.k8s.api.extensions.v1beta1.ReplicaSet map: fields: @@ -8185,74 +8546,328 @@ var schemaYAML = typed.YAMLObject(`types: - name: maxUnavailable type: namedType: io.k8s.apimachinery.pkg.util.intstr.IntOrString -- name: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions +- name: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod map: fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule + - name: type type: scalar: string default: "" -- name: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions +- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchema map: fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule + - name: apiVersion type: scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - map: - fields: - - name: allowedRuntimeClassNames - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultRuntimeClassName + - name: kind type: scalar: string -- name: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - map: + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaSpec + default: {} + - name: status + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaStatus + default: {} +- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaCondition + map: fields: - - name: rule + - name: lastTransitionTime + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + default: {} + - name: message + type: + scalar: string + - name: reason + type: + scalar: string + - name: status + type: + scalar: string + - name: type + type: + scalar: string +- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaSpec + map: + fields: + - name: distinguisherMethod + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod + - name: matchingPrecedence + type: + scalar: numeric + default: 0 + - name: priorityLevelConfiguration + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationReference + default: {} + - name: rules + type: + list: + elementType: + namedType: io.k8s.api.flowcontrol.v1alpha1.PolicyRulesWithSubjects + elementRelationship: atomic +- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaCondition + elementRelationship: associative + keys: + - type +- name: io.k8s.api.flowcontrol.v1alpha1.GroupSubject + map: + fields: + - name: name type: scalar: string default: "" - - name: seLinuxOptions +- name: io.k8s.api.flowcontrol.v1alpha1.LimitResponse + map: + fields: + - name: queuing type: - namedType: io.k8s.api.core.v1.SELinuxOptions -- name: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions + namedType: io.k8s.api.flowcontrol.v1alpha1.QueuingConfiguration + - name: type + type: + scalar: string + default: "" + unions: + - discriminator: type + fields: + - fieldName: queuing + discriminatorValue: Queuing +- name: io.k8s.api.flowcontrol.v1alpha1.LimitedPriorityLevelConfiguration map: fields: - - name: ranges + - name: assuredConcurrencyShares + type: + scalar: numeric + default: 0 + - name: borrowingLimitPercent + type: + scalar: numeric + - name: lendablePercent + type: + scalar: numeric + - name: limitResponse + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.LimitResponse + default: {} +- name: io.k8s.api.flowcontrol.v1alpha1.NonResourcePolicyRule + map: + fields: + - name: nonResourceURLs + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: verbs + type: + list: + elementType: + scalar: string + elementRelationship: associative +- name: io.k8s.api.flowcontrol.v1alpha1.PolicyRulesWithSubjects + map: + fields: + - name: nonResourceRules type: list: elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange + namedType: io.k8s.api.flowcontrol.v1alpha1.NonResourcePolicyRule elementRelationship: atomic - - name: rule + - name: resourceRules + type: + list: + elementType: + namedType: io.k8s.api.flowcontrol.v1alpha1.ResourcePolicyRule + elementRelationship: atomic + - name: subjects + type: + list: + elementType: + namedType: io.k8s.api.flowcontrol.v1alpha1.Subject + elementRelationship: atomic +- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfiguration + map: + fields: + - name: apiVersion type: scalar: string -- name: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationSpec + default: {} + - name: status + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationStatus + default: {} +- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationCondition + map: + fields: + - name: lastTransitionTime + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + default: {} + - name: message + type: + scalar: string + - name: reason + type: + scalar: string + - name: status + type: + scalar: string + - name: type + type: + scalar: string +- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationReference map: fields: + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationSpec + map: + fields: + - name: limited + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.LimitedPriorityLevelConfiguration - name: type type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchema + unions: + - discriminator: type + fields: + - fieldName: limited + discriminatorValue: Limited +- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationCondition + elementRelationship: associative + keys: + - type +- name: io.k8s.api.flowcontrol.v1alpha1.QueuingConfiguration + map: + fields: + - name: handSize + type: + scalar: numeric + default: 0 + - name: queueLengthLimit + type: + scalar: numeric + default: 0 + - name: queues + type: + scalar: numeric + default: 0 +- name: io.k8s.api.flowcontrol.v1alpha1.ResourcePolicyRule + map: + fields: + - name: apiGroups + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: clusterScope + type: + scalar: boolean + - name: namespaces + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: resources + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: verbs + type: + list: + elementType: + scalar: string + elementRelationship: associative +- name: io.k8s.api.flowcontrol.v1alpha1.ServiceAccountSubject + map: + fields: + - name: name + type: + scalar: string + default: "" + - name: namespace + type: + scalar: string + default: "" +- name: io.k8s.api.flowcontrol.v1alpha1.Subject + map: + fields: + - name: group + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.GroupSubject + - name: kind + type: + scalar: string + default: "" + - name: serviceAccount + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.ServiceAccountSubject + - name: user + type: + namedType: io.k8s.api.flowcontrol.v1alpha1.UserSubject + unions: + - discriminator: kind + fields: + - fieldName: group + discriminatorValue: Group + - fieldName: serviceAccount + discriminatorValue: ServiceAccount + - fieldName: user + discriminatorValue: User +- name: io.k8s.api.flowcontrol.v1alpha1.UserSubject + map: + fields: + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod + map: + fields: + - name: type + type: + scalar: string + default: "" +- name: io.k8s.api.flowcontrol.v1beta1.FlowSchema map: fields: - name: apiVersion @@ -8267,13 +8882,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaSpec + namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaStatus + namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaStatus default: {} -- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaCondition +- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaCondition map: fields: - name: lastTransitionTime @@ -8292,50 +8907,50 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaSpec +- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec map: fields: - name: distinguisherMethod type: - namedType: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod + namedType: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod - name: matchingPrecedence type: scalar: numeric default: 0 - name: priorityLevelConfiguration type: - namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationReference + namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference default: {} - name: rules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.PolicyRulesWithSubjects + namedType: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaStatus +- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.FlowSchemaCondition + namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1alpha1.GroupSubject +- name: io.k8s.api.flowcontrol.v1beta1.GroupSubject map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1alpha1.LimitResponse +- name: io.k8s.api.flowcontrol.v1beta1.LimitResponse map: fields: - name: queuing type: - namedType: io.k8s.api.flowcontrol.v1alpha1.QueuingConfiguration + namedType: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration - name: type type: scalar: string @@ -8345,18 +8960,24 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: queuing discriminatorValue: Queuing -- name: io.k8s.api.flowcontrol.v1alpha1.LimitedPriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration map: fields: - name: assuredConcurrencyShares type: scalar: numeric default: 0 + - name: borrowingLimitPercent + type: + scalar: numeric + - name: lendablePercent + type: + scalar: numeric - name: limitResponse type: - namedType: io.k8s.api.flowcontrol.v1alpha1.LimitResponse + namedType: io.k8s.api.flowcontrol.v1beta1.LimitResponse default: {} -- name: io.k8s.api.flowcontrol.v1alpha1.NonResourcePolicyRule +- name: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule map: fields: - name: nonResourceURLs @@ -8371,28 +8992,28 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1alpha1.PolicyRulesWithSubjects +- name: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects map: fields: - name: nonResourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.NonResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule elementRelationship: atomic - name: resourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.ResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule elementRelationship: atomic - name: subjects type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.Subject + namedType: io.k8s.api.flowcontrol.v1beta1.Subject elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration map: fields: - name: apiVersion @@ -8407,13 +9028,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationSpec + namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationStatus + namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationStatus default: {} -- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationCondition +- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationCondition map: fields: - name: lastTransitionTime @@ -8432,19 +9053,19 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationReference +- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationSpec +- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec map: fields: - name: limited type: - namedType: io.k8s.api.flowcontrol.v1alpha1.LimitedPriorityLevelConfiguration + namedType: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration - name: type type: scalar: string @@ -8454,18 +9075,18 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: limited discriminatorValue: Limited -- name: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationStatus +- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1alpha1.PriorityLevelConfigurationCondition + namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1alpha1.QueuingConfiguration +- name: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration map: fields: - name: handSize @@ -8480,7 +9101,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 -- name: io.k8s.api.flowcontrol.v1alpha1.ResourcePolicyRule +- name: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule map: fields: - name: apiGroups @@ -8510,7 +9131,7 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1alpha1.ServiceAccountSubject +- name: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject map: fields: - name: name @@ -8521,22 +9142,22 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1alpha1.Subject +- name: io.k8s.api.flowcontrol.v1beta1.Subject map: fields: - name: group type: - namedType: io.k8s.api.flowcontrol.v1alpha1.GroupSubject + namedType: io.k8s.api.flowcontrol.v1beta1.GroupSubject - name: kind type: scalar: string default: "" - name: serviceAccount type: - namedType: io.k8s.api.flowcontrol.v1alpha1.ServiceAccountSubject + namedType: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject - name: user type: - namedType: io.k8s.api.flowcontrol.v1alpha1.UserSubject + namedType: io.k8s.api.flowcontrol.v1beta1.UserSubject unions: - discriminator: kind fields: @@ -8546,21 +9167,21 @@ var schemaYAML = typed.YAMLObject(`types: discriminatorValue: ServiceAccount - fieldName: user discriminatorValue: User -- name: io.k8s.api.flowcontrol.v1alpha1.UserSubject +- name: io.k8s.api.flowcontrol.v1beta1.UserSubject map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod +- name: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod map: fields: - name: type type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta1.FlowSchema +- name: io.k8s.api.flowcontrol.v1beta2.FlowSchema map: fields: - name: apiVersion @@ -8575,13 +9196,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec + namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaStatus + namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaStatus default: {} -- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaCondition +- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaCondition map: fields: - name: lastTransitionTime @@ -8600,50 +9221,50 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaSpec +- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec map: fields: - name: distinguisherMethod type: - namedType: io.k8s.api.flowcontrol.v1beta1.FlowDistinguisherMethod + namedType: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod - name: matchingPrecedence type: scalar: numeric default: 0 - name: priorityLevelConfiguration type: - namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference + namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference default: {} - name: rules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects + namedType: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1beta1.FlowSchemaStatus +- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.FlowSchemaCondition + namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1beta1.GroupSubject +- name: io.k8s.api.flowcontrol.v1beta2.GroupSubject map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta1.LimitResponse +- name: io.k8s.api.flowcontrol.v1beta2.LimitResponse map: fields: - name: queuing type: - namedType: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration + namedType: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration - name: type type: scalar: string @@ -8653,18 +9274,24 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: queuing discriminatorValue: Queuing -- name: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration map: fields: - name: assuredConcurrencyShares type: scalar: numeric default: 0 + - name: borrowingLimitPercent + type: + scalar: numeric + - name: lendablePercent + type: + scalar: numeric - name: limitResponse type: - namedType: io.k8s.api.flowcontrol.v1beta1.LimitResponse + namedType: io.k8s.api.flowcontrol.v1beta2.LimitResponse default: {} -- name: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule +- name: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule map: fields: - name: nonResourceURLs @@ -8679,28 +9306,28 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1beta1.PolicyRulesWithSubjects +- name: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects map: fields: - name: nonResourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.NonResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule elementRelationship: atomic - name: resourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule elementRelationship: atomic - name: subjects type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.Subject + namedType: io.k8s.api.flowcontrol.v1beta2.Subject elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration map: fields: - name: apiVersion @@ -8715,13 +9342,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec + namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationStatus + namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationStatus default: {} -- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationCondition +- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationCondition map: fields: - name: lastTransitionTime @@ -8740,19 +9367,19 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationReference +- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationSpec +- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec map: fields: - name: limited type: - namedType: io.k8s.api.flowcontrol.v1beta1.LimitedPriorityLevelConfiguration + namedType: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration - name: type type: scalar: string @@ -8762,18 +9389,18 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: limited discriminatorValue: Limited -- name: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationStatus +- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta1.PriorityLevelConfigurationCondition + namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1beta1.QueuingConfiguration +- name: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration map: fields: - name: handSize @@ -8788,7 +9415,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 -- name: io.k8s.api.flowcontrol.v1beta1.ResourcePolicyRule +- name: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule map: fields: - name: apiGroups @@ -8818,7 +9445,7 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject +- name: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject map: fields: - name: name @@ -8829,22 +9456,22 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta1.Subject +- name: io.k8s.api.flowcontrol.v1beta2.Subject map: fields: - name: group type: - namedType: io.k8s.api.flowcontrol.v1beta1.GroupSubject + namedType: io.k8s.api.flowcontrol.v1beta2.GroupSubject - name: kind type: scalar: string default: "" - name: serviceAccount type: - namedType: io.k8s.api.flowcontrol.v1beta1.ServiceAccountSubject + namedType: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject - name: user type: - namedType: io.k8s.api.flowcontrol.v1beta1.UserSubject + namedType: io.k8s.api.flowcontrol.v1beta2.UserSubject unions: - discriminator: kind fields: @@ -8854,21 +9481,21 @@ var schemaYAML = typed.YAMLObject(`types: discriminatorValue: ServiceAccount - fieldName: user discriminatorValue: User -- name: io.k8s.api.flowcontrol.v1beta1.UserSubject +- name: io.k8s.api.flowcontrol.v1beta2.UserSubject map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod +- name: io.k8s.api.flowcontrol.v1beta3.FlowDistinguisherMethod map: fields: - name: type type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta2.FlowSchema +- name: io.k8s.api.flowcontrol.v1beta3.FlowSchema map: fields: - name: apiVersion @@ -8883,13 +9510,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec + namedType: io.k8s.api.flowcontrol.v1beta3.FlowSchemaSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaStatus + namedType: io.k8s.api.flowcontrol.v1beta3.FlowSchemaStatus default: {} -- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaCondition +- name: io.k8s.api.flowcontrol.v1beta3.FlowSchemaCondition map: fields: - name: lastTransitionTime @@ -8908,50 +9535,50 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaSpec +- name: io.k8s.api.flowcontrol.v1beta3.FlowSchemaSpec map: fields: - name: distinguisherMethod type: - namedType: io.k8s.api.flowcontrol.v1beta2.FlowDistinguisherMethod + namedType: io.k8s.api.flowcontrol.v1beta3.FlowDistinguisherMethod - name: matchingPrecedence type: scalar: numeric default: 0 - name: priorityLevelConfiguration type: - namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference + namedType: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationReference default: {} - name: rules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects + namedType: io.k8s.api.flowcontrol.v1beta3.PolicyRulesWithSubjects elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1beta2.FlowSchemaStatus +- name: io.k8s.api.flowcontrol.v1beta3.FlowSchemaStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.FlowSchemaCondition + namedType: io.k8s.api.flowcontrol.v1beta3.FlowSchemaCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1beta2.GroupSubject +- name: io.k8s.api.flowcontrol.v1beta3.GroupSubject map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta2.LimitResponse +- name: io.k8s.api.flowcontrol.v1beta3.LimitResponse map: fields: - name: queuing type: - namedType: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration + namedType: io.k8s.api.flowcontrol.v1beta3.QueuingConfiguration - name: type type: scalar: string @@ -8961,18 +9588,24 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: queuing discriminatorValue: Queuing -- name: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration map: fields: - - name: assuredConcurrencyShares + - name: borrowingLimitPercent + type: + scalar: numeric + - name: lendablePercent type: scalar: numeric - default: 0 - name: limitResponse type: - namedType: io.k8s.api.flowcontrol.v1beta2.LimitResponse + namedType: io.k8s.api.flowcontrol.v1beta3.LimitResponse default: {} -- name: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule + - name: nominalConcurrencyShares + type: + scalar: numeric + default: 0 +- name: io.k8s.api.flowcontrol.v1beta3.NonResourcePolicyRule map: fields: - name: nonResourceURLs @@ -8987,28 +9620,28 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1beta2.PolicyRulesWithSubjects +- name: io.k8s.api.flowcontrol.v1beta3.PolicyRulesWithSubjects map: fields: - name: nonResourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.NonResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta3.NonResourcePolicyRule elementRelationship: atomic - name: resourceRules type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule + namedType: io.k8s.api.flowcontrol.v1beta3.ResourcePolicyRule elementRelationship: atomic - name: subjects type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.Subject + namedType: io.k8s.api.flowcontrol.v1beta3.Subject elementRelationship: atomic -- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfiguration +- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfiguration map: fields: - name: apiVersion @@ -9023,13 +9656,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec + namedType: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationSpec default: {} - name: status type: - namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationStatus + namedType: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationStatus default: {} -- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationCondition +- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationCondition map: fields: - name: lastTransitionTime @@ -9048,19 +9681,19 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationReference +- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationReference map: fields: - name: name type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationSpec +- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationSpec map: fields: - name: limited type: - namedType: io.k8s.api.flowcontrol.v1beta2.LimitedPriorityLevelConfiguration + namedType: io.k8s.api.flowcontrol.v1beta3.LimitedPriorityLevelConfiguration - name: type type: scalar: string @@ -9070,18 +9703,18 @@ var schemaYAML = typed.YAMLObject(`types: fields: - fieldName: limited discriminatorValue: Limited -- name: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationStatus +- name: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationStatus map: fields: - name: conditions type: list: elementType: - namedType: io.k8s.api.flowcontrol.v1beta2.PriorityLevelConfigurationCondition + namedType: io.k8s.api.flowcontrol.v1beta3.PriorityLevelConfigurationCondition elementRelationship: associative keys: - type -- name: io.k8s.api.flowcontrol.v1beta2.QueuingConfiguration +- name: io.k8s.api.flowcontrol.v1beta3.QueuingConfiguration map: fields: - name: handSize @@ -9096,7 +9729,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 -- name: io.k8s.api.flowcontrol.v1beta2.ResourcePolicyRule +- name: io.k8s.api.flowcontrol.v1beta3.ResourcePolicyRule map: fields: - name: apiGroups @@ -9126,7 +9759,7 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject +- name: io.k8s.api.flowcontrol.v1beta3.ServiceAccountSubject map: fields: - name: name @@ -9137,22 +9770,22 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.flowcontrol.v1beta2.Subject +- name: io.k8s.api.flowcontrol.v1beta3.Subject map: fields: - name: group type: - namedType: io.k8s.api.flowcontrol.v1beta2.GroupSubject + namedType: io.k8s.api.flowcontrol.v1beta3.GroupSubject - name: kind type: scalar: string default: "" - name: serviceAccount type: - namedType: io.k8s.api.flowcontrol.v1beta2.ServiceAccountSubject + namedType: io.k8s.api.flowcontrol.v1beta3.ServiceAccountSubject - name: user type: - namedType: io.k8s.api.flowcontrol.v1beta2.UserSubject + namedType: io.k8s.api.flowcontrol.v1beta3.UserSubject unions: - discriminator: kind fields: @@ -9162,7 +9795,7 @@ var schemaYAML = typed.YAMLObject(`types: discriminatorValue: ServiceAccount - fieldName: user discriminatorValue: User -- name: io.k8s.api.flowcontrol.v1beta2.UserSubject +- name: io.k8s.api.flowcontrol.v1beta3.UserSubject map: fields: - name: name @@ -9339,6 +9972,44 @@ var schemaYAML = typed.YAMLObject(`types: - name: parameters type: namedType: io.k8s.api.networking.v1.IngressClassParametersReference +- name: io.k8s.api.networking.v1.IngressLoadBalancerIngress + map: + fields: + - name: hostname + type: + scalar: string + - name: ip + type: + scalar: string + - name: ports + type: + list: + elementType: + namedType: io.k8s.api.networking.v1.IngressPortStatus + elementRelationship: atomic +- name: io.k8s.api.networking.v1.IngressLoadBalancerStatus + map: + fields: + - name: ingress + type: + list: + elementType: + namedType: io.k8s.api.networking.v1.IngressLoadBalancerIngress + elementRelationship: atomic +- name: io.k8s.api.networking.v1.IngressPortStatus + map: + fields: + - name: error + type: + scalar: string + - name: port + type: + scalar: numeric + default: 0 + - name: protocol + type: + scalar: string + default: "" - name: io.k8s.api.networking.v1.IngressRule map: fields: @@ -9385,7 +10056,7 @@ var schemaYAML = typed.YAMLObject(`types: fields: - name: loadBalancer type: - namedType: io.k8s.api.core.v1.LoadBalancerStatus + namedType: io.k8s.api.networking.v1.IngressLoadBalancerStatus default: {} - name: io.k8s.api.networking.v1.IngressTLS map: @@ -9502,23 +10173,99 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.networking.v1.NetworkPolicyStatus map: fields: - - name: conditions + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type +- name: io.k8s.api.networking.v1.ServiceBackendPort + map: + fields: + - name: name + type: + scalar: string + - name: number + type: + scalar: numeric +- name: io.k8s.api.networking.v1alpha1.ClusterCIDR + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.networking.v1alpha1.ClusterCIDRSpec + default: {} +- name: io.k8s.api.networking.v1alpha1.ClusterCIDRSpec + map: + fields: + - name: ipv4 + type: + scalar: string + default: "" + - name: ipv6 + type: + scalar: string + default: "" + - name: nodeSelector + type: + namedType: io.k8s.api.core.v1.NodeSelector + - name: perNodeHostBits + type: + scalar: numeric + default: 0 +- name: io.k8s.api.networking.v1alpha1.IPAddress + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.networking.v1alpha1.IPAddressSpec + default: {} +- name: io.k8s.api.networking.v1alpha1.IPAddressSpec + map: + fields: + - name: parentRef type: - list: - elementType: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition - elementRelationship: associative - keys: - - type -- name: io.k8s.api.networking.v1.ServiceBackendPort + namedType: io.k8s.api.networking.v1alpha1.ParentReference +- name: io.k8s.api.networking.v1alpha1.ParentReference map: fields: + - name: group + type: + scalar: string - name: name type: scalar: string - - name: number + - name: namespace type: - scalar: numeric + scalar: string + - name: resource + type: + scalar: string + - name: uid + type: + scalar: string - name: io.k8s.api.networking.v1beta1.HTTPIngressPath map: fields: @@ -9621,6 +10368,44 @@ var schemaYAML = typed.YAMLObject(`types: - name: parameters type: namedType: io.k8s.api.networking.v1beta1.IngressClassParametersReference +- name: io.k8s.api.networking.v1beta1.IngressLoadBalancerIngress + map: + fields: + - name: hostname + type: + scalar: string + - name: ip + type: + scalar: string + - name: ports + type: + list: + elementType: + namedType: io.k8s.api.networking.v1beta1.IngressPortStatus + elementRelationship: atomic +- name: io.k8s.api.networking.v1beta1.IngressLoadBalancerStatus + map: + fields: + - name: ingress + type: + list: + elementType: + namedType: io.k8s.api.networking.v1beta1.IngressLoadBalancerIngress + elementRelationship: atomic +- name: io.k8s.api.networking.v1beta1.IngressPortStatus + map: + fields: + - name: error + type: + scalar: string + - name: port + type: + scalar: numeric + default: 0 + - name: protocol + type: + scalar: string + default: "" - name: io.k8s.api.networking.v1beta1.IngressRule map: fields: @@ -9656,7 +10441,7 @@ var schemaYAML = typed.YAMLObject(`types: fields: - name: loadBalancer type: - namedType: io.k8s.api.core.v1.LoadBalancerStatus + namedType: io.k8s.api.networking.v1beta1.IngressLoadBalancerStatus default: {} - name: io.k8s.api.networking.v1beta1.IngressTLS map: @@ -9864,6 +10649,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: selector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: unhealthyPodEvictionPolicy + type: + scalar: string - name: io.k8s.api.policy.v1.PodDisruptionBudgetStatus map: fields: @@ -10005,6 +10793,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: selector type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: unhealthyPodEvictionPolicy + type: + scalar: string - name: io.k8s.api.policy.v1beta1.PodDisruptionBudgetStatus map: fields: @@ -10714,6 +11505,240 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string +- name: io.k8s.api.resource.v1alpha2.AllocationResult + map: + fields: + - name: availableOnNodes + type: + namedType: io.k8s.api.core.v1.NodeSelector + - name: resourceHandles + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceHandle + elementRelationship: atomic + - name: shareable + type: + scalar: boolean +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContext + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec + default: {} + - name: status + type: + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus + default: {} +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec + map: + fields: + - name: potentialNodes + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: selectedNode + type: + scalar: string +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus + map: + fields: + - name: resourceClaims + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus + elementRelationship: associative + keys: + - name +- name: io.k8s.api.resource.v1alpha2.ResourceClaim + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec + default: {} + - name: status + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimStatus + default: {} +- name: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference + map: + fields: + - name: apiGroup + type: + scalar: string + - name: name + type: + scalar: string + default: "" + - name: resource + type: + scalar: string + default: "" + - name: uid + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference + map: + fields: + - name: apiGroup + type: + scalar: string + - name: kind + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus + map: + fields: + - name: name + type: + scalar: string + - name: unsuitableNodes + type: + list: + elementType: + scalar: string + elementRelationship: associative +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSpec + map: + fields: + - name: allocationMode + type: + scalar: string + - name: parametersRef + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference + - name: resourceClassName + type: + scalar: string + default: "" +- name: io.k8s.api.resource.v1alpha2.ResourceClaimStatus + map: + fields: + - name: allocation + type: + namedType: io.k8s.api.resource.v1alpha2.AllocationResult + - name: deallocationRequested + type: + scalar: boolean + - name: driverName + type: + scalar: string + - name: reservedFor + type: + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference + elementRelationship: associative + keys: + - uid +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplate + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec + default: {} +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec + map: + fields: + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec + default: {} +- name: io.k8s.api.resource.v1alpha2.ResourceClass + map: + fields: + - name: apiVersion + type: + scalar: string + - name: driverName + type: + scalar: string + default: "" + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: parametersRef + type: + namedType: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference + - name: suitableNodes + type: + namedType: io.k8s.api.core.v1.NodeSelector +- name: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference + map: + fields: + - name: apiGroup + type: + scalar: string + - name: kind + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" + - name: namespace + type: + scalar: string +- name: io.k8s.api.resource.v1alpha2.ResourceHandle + map: + fields: + - name: data + type: + scalar: string + - name: driverName + type: + scalar: string - name: io.k8s.api.scheduling.v1.PriorityClass map: fields: @@ -10824,6 +11849,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: requiresRepublish type: scalar: boolean + - name: seLinuxMount + type: + scalar: boolean - name: storageCapacity type: scalar: boolean @@ -11176,6 +12204,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: requiresRepublish type: scalar: boolean + - name: seLinuxMount + type: + scalar: boolean - name: storageCapacity type: scalar: boolean @@ -11530,9 +12561,6 @@ var schemaYAML = typed.YAMLObject(`types: map: elementType: scalar: string - - name: clusterName - type: - scalar: string - name: creationTimestamp type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalanceringress.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalanceringress.go new file mode 100644 index 00000000000..444275a127e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalanceringress.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// IngressLoadBalancerIngressApplyConfiguration represents an declarative configuration of the IngressLoadBalancerIngress type for use +// with apply. +type IngressLoadBalancerIngressApplyConfiguration struct { + IP *string `json:"ip,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Ports []IngressPortStatusApplyConfiguration `json:"ports,omitempty"` +} + +// IngressLoadBalancerIngressApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerIngress type for use with +// apply. +func IngressLoadBalancerIngress() *IngressLoadBalancerIngressApplyConfiguration { + return &IngressLoadBalancerIngressApplyConfiguration{} +} + +// WithIP sets the IP field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IP field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithIP(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.IP = &value + return b +} + +// WithHostname sets the Hostname field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Hostname field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithHostname(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.Hostname = &value + return b +} + +// WithPorts adds the given value to the Ports field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ports field. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithPorts(values ...*IngressPortStatusApplyConfiguration) *IngressLoadBalancerIngressApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPorts") + } + b.Ports = append(b.Ports, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalancerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalancerstatus.go new file mode 100644 index 00000000000..8e01a301ac5 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressloadbalancerstatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// IngressLoadBalancerStatusApplyConfiguration represents an declarative configuration of the IngressLoadBalancerStatus type for use +// with apply. +type IngressLoadBalancerStatusApplyConfiguration struct { + Ingress []IngressLoadBalancerIngressApplyConfiguration `json:"ingress,omitempty"` +} + +// IngressLoadBalancerStatusApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerStatus type for use with +// apply. +func IngressLoadBalancerStatus() *IngressLoadBalancerStatusApplyConfiguration { + return &IngressLoadBalancerStatusApplyConfiguration{} +} + +// WithIngress adds the given value to the Ingress field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ingress field. +func (b *IngressLoadBalancerStatusApplyConfiguration) WithIngress(values ...*IngressLoadBalancerIngressApplyConfiguration) *IngressLoadBalancerStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithIngress") + } + b.Ingress = append(b.Ingress, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressportstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressportstatus.go new file mode 100644 index 00000000000..82b5babd9ca --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressportstatus.go @@ -0,0 +1,61 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// IngressPortStatusApplyConfiguration represents an declarative configuration of the IngressPortStatus type for use +// with apply. +type IngressPortStatusApplyConfiguration struct { + Port *int32 `json:"port,omitempty"` + Protocol *v1.Protocol `json:"protocol,omitempty"` + Error *string `json:"error,omitempty"` +} + +// IngressPortStatusApplyConfiguration constructs an declarative configuration of the IngressPortStatus type for use with +// apply. +func IngressPortStatus() *IngressPortStatusApplyConfiguration { + return &IngressPortStatusApplyConfiguration{} +} + +// WithPort sets the Port field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Port field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithPort(value int32) *IngressPortStatusApplyConfiguration { + b.Port = &value + return b +} + +// WithProtocol sets the Protocol field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Protocol field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithProtocol(value v1.Protocol) *IngressPortStatusApplyConfiguration { + b.Protocol = &value + return b +} + +// WithError sets the Error field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Error field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithError(value string) *IngressPortStatusApplyConfiguration { + b.Error = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressstatus.go index dd8b25d836f..7131bf8d0dc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ingressstatus.go @@ -18,14 +18,10 @@ limitations under the License. package v1 -import ( - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - // IngressStatusApplyConfiguration represents an declarative configuration of the IngressStatus type for use // with apply. type IngressStatusApplyConfiguration struct { - LoadBalancer *v1.LoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` + LoadBalancer *IngressLoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` } // IngressStatusApplyConfiguration constructs an declarative configuration of the IngressStatus type for use with @@ -37,7 +33,7 @@ func IngressStatus() *IngressStatusApplyConfiguration { // WithLoadBalancer sets the LoadBalancer field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the LoadBalancer field is set to the value of the last call. -func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *v1.LoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { +func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *IngressLoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { b.LoadBalancer = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidr.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidr.go new file mode 100644 index 00000000000..ad0eae9198e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidr.go @@ -0,0 +1,247 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterCIDRApplyConfiguration represents an declarative configuration of the ClusterCIDR type for use +// with apply. +type ClusterCIDRApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ClusterCIDRSpecApplyConfiguration `json:"spec,omitempty"` +} + +// ClusterCIDR constructs an declarative configuration of the ClusterCIDR type for use with +// apply. +func ClusterCIDR(name string) *ClusterCIDRApplyConfiguration { + b := &ClusterCIDRApplyConfiguration{} + b.WithName(name) + b.WithKind("ClusterCIDR") + b.WithAPIVersion("networking.k8s.io/v1alpha1") + return b +} + +// ExtractClusterCIDR extracts the applied configuration owned by fieldManager from +// clusterCIDR. If no managedFields are found in clusterCIDR for fieldManager, a +// ClusterCIDRApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// clusterCIDR must be a unmodified ClusterCIDR API object that was retrieved from the Kubernetes API. +// ExtractClusterCIDR provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractClusterCIDR(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string) (*ClusterCIDRApplyConfiguration, error) { + return extractClusterCIDR(clusterCIDR, fieldManager, "") +} + +// ExtractClusterCIDRStatus is the same as ExtractClusterCIDR except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractClusterCIDRStatus(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string) (*ClusterCIDRApplyConfiguration, error) { + return extractClusterCIDR(clusterCIDR, fieldManager, "status") +} + +func extractClusterCIDR(clusterCIDR *networkingv1alpha1.ClusterCIDR, fieldManager string, subresource string) (*ClusterCIDRApplyConfiguration, error) { + b := &ClusterCIDRApplyConfiguration{} + err := managedfields.ExtractInto(clusterCIDR, internal.Parser().Type("io.k8s.api.networking.v1alpha1.ClusterCIDR"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(clusterCIDR.Name) + + b.WithKind("ClusterCIDR") + b.WithAPIVersion("networking.k8s.io/v1alpha1") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithKind(value string) *ClusterCIDRApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithAPIVersion(value string) *ClusterCIDRApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithName(value string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithGenerateName(value string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithNamespace(value string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithUID(value types.UID) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithResourceVersion(value string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithGeneration(value int64) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ClusterCIDRApplyConfiguration) WithLabels(entries map[string]string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ClusterCIDRApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ClusterCIDRApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ClusterCIDRApplyConfiguration) WithFinalizers(values ...string) *ClusterCIDRApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ClusterCIDRApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ClusterCIDRApplyConfiguration) WithSpec(value *ClusterCIDRSpecApplyConfiguration) *ClusterCIDRApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidrspec.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidrspec.go new file mode 100644 index 00000000000..8d5fa406b09 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/clustercidrspec.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/core/v1" +) + +// ClusterCIDRSpecApplyConfiguration represents an declarative configuration of the ClusterCIDRSpec type for use +// with apply. +type ClusterCIDRSpecApplyConfiguration struct { + NodeSelector *v1.NodeSelectorApplyConfiguration `json:"nodeSelector,omitempty"` + PerNodeHostBits *int32 `json:"perNodeHostBits,omitempty"` + IPv4 *string `json:"ipv4,omitempty"` + IPv6 *string `json:"ipv6,omitempty"` +} + +// ClusterCIDRSpecApplyConfiguration constructs an declarative configuration of the ClusterCIDRSpec type for use with +// apply. +func ClusterCIDRSpec() *ClusterCIDRSpecApplyConfiguration { + return &ClusterCIDRSpecApplyConfiguration{} +} + +// WithNodeSelector sets the NodeSelector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeSelector field is set to the value of the last call. +func (b *ClusterCIDRSpecApplyConfiguration) WithNodeSelector(value *v1.NodeSelectorApplyConfiguration) *ClusterCIDRSpecApplyConfiguration { + b.NodeSelector = value + return b +} + +// WithPerNodeHostBits sets the PerNodeHostBits field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PerNodeHostBits field is set to the value of the last call. +func (b *ClusterCIDRSpecApplyConfiguration) WithPerNodeHostBits(value int32) *ClusterCIDRSpecApplyConfiguration { + b.PerNodeHostBits = &value + return b +} + +// WithIPv4 sets the IPv4 field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IPv4 field is set to the value of the last call. +func (b *ClusterCIDRSpecApplyConfiguration) WithIPv4(value string) *ClusterCIDRSpecApplyConfiguration { + b.IPv4 = &value + return b +} + +// WithIPv6 sets the IPv6 field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IPv6 field is set to the value of the last call. +func (b *ClusterCIDRSpecApplyConfiguration) WithIPv6(value string) *ClusterCIDRSpecApplyConfiguration { + b.IPv6 = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go new file mode 100644 index 00000000000..da6822111db --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go @@ -0,0 +1,247 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// IPAddressApplyConfiguration represents an declarative configuration of the IPAddress type for use +// with apply. +type IPAddressApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *IPAddressSpecApplyConfiguration `json:"spec,omitempty"` +} + +// IPAddress constructs an declarative configuration of the IPAddress type for use with +// apply. +func IPAddress(name string) *IPAddressApplyConfiguration { + b := &IPAddressApplyConfiguration{} + b.WithName(name) + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") + return b +} + +// ExtractIPAddress extracts the applied configuration owned by fieldManager from +// iPAddress. If no managedFields are found in iPAddress for fieldManager, a +// IPAddressApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// iPAddress must be a unmodified IPAddress API object that was retrieved from the Kubernetes API. +// ExtractIPAddress provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "") +} + +// ExtractIPAddressStatus is the same as ExtractIPAddress except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractIPAddressStatus(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "status") +} + +func extractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string, subresource string) (*IPAddressApplyConfiguration, error) { + b := &IPAddressApplyConfiguration{} + err := managedfields.ExtractInto(iPAddress, internal.Parser().Type("io.k8s.api.networking.v1alpha1.IPAddress"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(iPAddress.Name) + + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithKind(value string) *IPAddressApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithAPIVersion(value string) *IPAddressApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithName(value string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithGenerateName(value string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithNamespace(value string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithUID(value types.UID) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithResourceVersion(value string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithGeneration(value int64) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithCreationTimestamp(value metav1.Time) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *IPAddressApplyConfiguration) WithLabels(entries map[string]string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *IPAddressApplyConfiguration) WithAnnotations(entries map[string]string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *IPAddressApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *IPAddressApplyConfiguration) WithFinalizers(values ...string) *IPAddressApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *IPAddressApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *IPAddressApplyConfiguration) WithSpec(value *IPAddressSpecApplyConfiguration) *IPAddressApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go new file mode 100644 index 00000000000..064963d691e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// IPAddressSpecApplyConfiguration represents an declarative configuration of the IPAddressSpec type for use +// with apply. +type IPAddressSpecApplyConfiguration struct { + ParentRef *ParentReferenceApplyConfiguration `json:"parentRef,omitempty"` +} + +// IPAddressSpecApplyConfiguration constructs an declarative configuration of the IPAddressSpec type for use with +// apply. +func IPAddressSpec() *IPAddressSpecApplyConfiguration { + return &IPAddressSpecApplyConfiguration{} +} + +// WithParentRef sets the ParentRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParentRef field is set to the value of the last call. +func (b *IPAddressSpecApplyConfiguration) WithParentRef(value *ParentReferenceApplyConfiguration) *IPAddressSpecApplyConfiguration { + b.ParentRef = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go new file mode 100644 index 00000000000..14b10b19ff6 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go @@ -0,0 +1,79 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + types "k8s.io/apimachinery/pkg/types" +) + +// ParentReferenceApplyConfiguration represents an declarative configuration of the ParentReference type for use +// with apply. +type ParentReferenceApplyConfiguration struct { + Group *string `json:"group,omitempty"` + Resource *string `json:"resource,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Name *string `json:"name,omitempty"` + UID *types.UID `json:"uid,omitempty"` +} + +// ParentReferenceApplyConfiguration constructs an declarative configuration of the ParentReference type for use with +// apply. +func ParentReference() *ParentReferenceApplyConfiguration { + return &ParentReferenceApplyConfiguration{} +} + +// WithGroup sets the Group field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Group field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithGroup(value string) *ParentReferenceApplyConfiguration { + b.Group = &value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithResource(value string) *ParentReferenceApplyConfiguration { + b.Resource = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithNamespace(value string) *ParentReferenceApplyConfiguration { + b.Namespace = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithName(value string) *ParentReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithUID(value types.UID) *ParentReferenceApplyConfiguration { + b.UID = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalanceringress.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalanceringress.go new file mode 100644 index 00000000000..20bf6378054 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalanceringress.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// IngressLoadBalancerIngressApplyConfiguration represents an declarative configuration of the IngressLoadBalancerIngress type for use +// with apply. +type IngressLoadBalancerIngressApplyConfiguration struct { + IP *string `json:"ip,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Ports []IngressPortStatusApplyConfiguration `json:"ports,omitempty"` +} + +// IngressLoadBalancerIngressApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerIngress type for use with +// apply. +func IngressLoadBalancerIngress() *IngressLoadBalancerIngressApplyConfiguration { + return &IngressLoadBalancerIngressApplyConfiguration{} +} + +// WithIP sets the IP field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IP field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithIP(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.IP = &value + return b +} + +// WithHostname sets the Hostname field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Hostname field is set to the value of the last call. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithHostname(value string) *IngressLoadBalancerIngressApplyConfiguration { + b.Hostname = &value + return b +} + +// WithPorts adds the given value to the Ports field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ports field. +func (b *IngressLoadBalancerIngressApplyConfiguration) WithPorts(values ...*IngressPortStatusApplyConfiguration) *IngressLoadBalancerIngressApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPorts") + } + b.Ports = append(b.Ports, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalancerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalancerstatus.go new file mode 100644 index 00000000000..e16dd236333 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressloadbalancerstatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// IngressLoadBalancerStatusApplyConfiguration represents an declarative configuration of the IngressLoadBalancerStatus type for use +// with apply. +type IngressLoadBalancerStatusApplyConfiguration struct { + Ingress []IngressLoadBalancerIngressApplyConfiguration `json:"ingress,omitempty"` +} + +// IngressLoadBalancerStatusApplyConfiguration constructs an declarative configuration of the IngressLoadBalancerStatus type for use with +// apply. +func IngressLoadBalancerStatus() *IngressLoadBalancerStatusApplyConfiguration { + return &IngressLoadBalancerStatusApplyConfiguration{} +} + +// WithIngress adds the given value to the Ingress field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Ingress field. +func (b *IngressLoadBalancerStatusApplyConfiguration) WithIngress(values ...*IngressLoadBalancerIngressApplyConfiguration) *IngressLoadBalancerStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithIngress") + } + b.Ingress = append(b.Ingress, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressportstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressportstatus.go new file mode 100644 index 00000000000..0836537979e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressportstatus.go @@ -0,0 +1,61 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// IngressPortStatusApplyConfiguration represents an declarative configuration of the IngressPortStatus type for use +// with apply. +type IngressPortStatusApplyConfiguration struct { + Port *int32 `json:"port,omitempty"` + Protocol *v1.Protocol `json:"protocol,omitempty"` + Error *string `json:"error,omitempty"` +} + +// IngressPortStatusApplyConfiguration constructs an declarative configuration of the IngressPortStatus type for use with +// apply. +func IngressPortStatus() *IngressPortStatusApplyConfiguration { + return &IngressPortStatusApplyConfiguration{} +} + +// WithPort sets the Port field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Port field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithPort(value int32) *IngressPortStatusApplyConfiguration { + b.Port = &value + return b +} + +// WithProtocol sets the Protocol field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Protocol field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithProtocol(value v1.Protocol) *IngressPortStatusApplyConfiguration { + b.Protocol = &value + return b +} + +// WithError sets the Error field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Error field is set to the value of the last call. +func (b *IngressPortStatusApplyConfiguration) WithError(value string) *IngressPortStatusApplyConfiguration { + b.Error = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressstatus.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressstatus.go index 941769594ec..faa7e2446fa 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1beta1/ingressstatus.go @@ -18,14 +18,10 @@ limitations under the License. package v1beta1 -import ( - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - // IngressStatusApplyConfiguration represents an declarative configuration of the IngressStatus type for use // with apply. type IngressStatusApplyConfiguration struct { - LoadBalancer *v1.LoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` + LoadBalancer *IngressLoadBalancerStatusApplyConfiguration `json:"loadBalancer,omitempty"` } // IngressStatusApplyConfiguration constructs an declarative configuration of the IngressStatus type for use with @@ -37,7 +33,7 @@ func IngressStatus() *IngressStatusApplyConfiguration { // WithLoadBalancer sets the LoadBalancer field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the LoadBalancer field is set to the value of the last call. -func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *v1.LoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { +func (b *IngressStatusApplyConfiguration) WithLoadBalancer(value *IngressLoadBalancerStatusApplyConfiguration) *IngressStatusApplyConfiguration { b.LoadBalancer = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/policy/v1/poddisruptionbudgetspec.go b/vendor/k8s.io/client-go/applyconfigurations/policy/v1/poddisruptionbudgetspec.go index e2f49f528cd..67d9ba6bba6 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/policy/v1/poddisruptionbudgetspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/policy/v1/poddisruptionbudgetspec.go @@ -19,6 +19,7 @@ limitations under the License. package v1 import ( + policyv1 "k8s.io/api/policy/v1" intstr "k8s.io/apimachinery/pkg/util/intstr" v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) @@ -26,9 +27,10 @@ import ( // PodDisruptionBudgetSpecApplyConfiguration represents an declarative configuration of the PodDisruptionBudgetSpec type for use // with apply. type PodDisruptionBudgetSpecApplyConfiguration struct { - MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"` - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"` + Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` + MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + UnhealthyPodEvictionPolicy *policyv1.UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty"` } // PodDisruptionBudgetSpecApplyConfiguration constructs an declarative configuration of the PodDisruptionBudgetSpec type for use with @@ -60,3 +62,11 @@ func (b *PodDisruptionBudgetSpecApplyConfiguration) WithMaxUnavailable(value int b.MaxUnavailable = &value return b } + +// WithUnhealthyPodEvictionPolicy sets the UnhealthyPodEvictionPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UnhealthyPodEvictionPolicy field is set to the value of the last call. +func (b *PodDisruptionBudgetSpecApplyConfiguration) WithUnhealthyPodEvictionPolicy(value policyv1.UnhealthyPodEvictionPolicyType) *PodDisruptionBudgetSpecApplyConfiguration { + b.UnhealthyPodEvictionPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/policy/v1beta1/poddisruptionbudgetspec.go b/vendor/k8s.io/client-go/applyconfigurations/policy/v1beta1/poddisruptionbudgetspec.go index b5d17d3fe0b..0ba3ea1c2e6 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/policy/v1beta1/poddisruptionbudgetspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/policy/v1beta1/poddisruptionbudgetspec.go @@ -19,6 +19,7 @@ limitations under the License. package v1beta1 import ( + v1beta1 "k8s.io/api/policy/v1beta1" intstr "k8s.io/apimachinery/pkg/util/intstr" v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) @@ -26,9 +27,10 @@ import ( // PodDisruptionBudgetSpecApplyConfiguration represents an declarative configuration of the PodDisruptionBudgetSpec type for use // with apply. type PodDisruptionBudgetSpecApplyConfiguration struct { - MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"` - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"` + Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` + MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + UnhealthyPodEvictionPolicy *v1beta1.UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty"` } // PodDisruptionBudgetSpecApplyConfiguration constructs an declarative configuration of the PodDisruptionBudgetSpec type for use with @@ -60,3 +62,11 @@ func (b *PodDisruptionBudgetSpecApplyConfiguration) WithMaxUnavailable(value int b.MaxUnavailable = &value return b } + +// WithUnhealthyPodEvictionPolicy sets the UnhealthyPodEvictionPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UnhealthyPodEvictionPolicy field is set to the value of the last call. +func (b *PodDisruptionBudgetSpecApplyConfiguration) WithUnhealthyPodEvictionPolicy(value v1beta1.UnhealthyPodEvictionPolicyType) *PodDisruptionBudgetSpecApplyConfiguration { + b.UnhealthyPodEvictionPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go new file mode 100644 index 00000000000..bc6078aa941 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1 "k8s.io/client-go/applyconfigurations/core/v1" +) + +// AllocationResultApplyConfiguration represents an declarative configuration of the AllocationResult type for use +// with apply. +type AllocationResultApplyConfiguration struct { + ResourceHandles []ResourceHandleApplyConfiguration `json:"resourceHandles,omitempty"` + AvailableOnNodes *v1.NodeSelectorApplyConfiguration `json:"availableOnNodes,omitempty"` + Shareable *bool `json:"shareable,omitempty"` +} + +// AllocationResultApplyConfiguration constructs an declarative configuration of the AllocationResult type for use with +// apply. +func AllocationResult() *AllocationResultApplyConfiguration { + return &AllocationResultApplyConfiguration{} +} + +// WithResourceHandles adds the given value to the ResourceHandles field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceHandles field. +func (b *AllocationResultApplyConfiguration) WithResourceHandles(values ...*ResourceHandleApplyConfiguration) *AllocationResultApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceHandles") + } + b.ResourceHandles = append(b.ResourceHandles, *values[i]) + } + return b +} + +// WithAvailableOnNodes sets the AvailableOnNodes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AvailableOnNodes field is set to the value of the last call. +func (b *AllocationResultApplyConfiguration) WithAvailableOnNodes(value *v1.NodeSelectorApplyConfiguration) *AllocationResultApplyConfiguration { + b.AvailableOnNodes = value + return b +} + +// WithShareable sets the Shareable field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Shareable field is set to the value of the last call. +func (b *AllocationResultApplyConfiguration) WithShareable(value bool) *AllocationResultApplyConfiguration { + b.Shareable = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 00000000000..1dfb6ff97b8 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,258 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// PodSchedulingContextApplyConfiguration represents an declarative configuration of the PodSchedulingContext type for use +// with apply. +type PodSchedulingContextApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *PodSchedulingContextSpecApplyConfiguration `json:"spec,omitempty"` + Status *PodSchedulingContextStatusApplyConfiguration `json:"status,omitempty"` +} + +// PodSchedulingContext constructs an declarative configuration of the PodSchedulingContext type for use with +// apply. +func PodSchedulingContext(name, namespace string) *PodSchedulingContextApplyConfiguration { + b := &PodSchedulingContextApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractPodSchedulingContext extracts the applied configuration owned by fieldManager from +// podSchedulingContext. If no managedFields are found in podSchedulingContext for fieldManager, a +// PodSchedulingContextApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// podSchedulingContext must be a unmodified PodSchedulingContext API object that was retrieved from the Kubernetes API. +// ExtractPodSchedulingContext provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "") +} + +// ExtractPodSchedulingContextStatus is the same as ExtractPodSchedulingContext except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractPodSchedulingContextStatus(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "status") +} + +func extractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string, subresource string) (*PodSchedulingContextApplyConfiguration, error) { + b := &PodSchedulingContextApplyConfiguration{} + err := managedfields.ExtractInto(podSchedulingContext, internal.Parser().Type("io.k8s.api.resource.v1alpha2.PodSchedulingContext"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(podSchedulingContext.Name) + b.WithNamespace(podSchedulingContext.Namespace) + + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithKind(value string) *PodSchedulingContextApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithAPIVersion(value string) *PodSchedulingContextApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGenerateName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithNamespace(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithUID(value types.UID) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithResourceVersion(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGeneration(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithLabels(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithAnnotations(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *PodSchedulingContextApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *PodSchedulingContextApplyConfiguration) WithFinalizers(values ...string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *PodSchedulingContextApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithSpec(value *PodSchedulingContextSpecApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithStatus(value *PodSchedulingContextStatusApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go new file mode 100644 index 00000000000..c95d3295e80 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go @@ -0,0 +1,50 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodSchedulingContextSpecApplyConfiguration represents an declarative configuration of the PodSchedulingContextSpec type for use +// with apply. +type PodSchedulingContextSpecApplyConfiguration struct { + SelectedNode *string `json:"selectedNode,omitempty"` + PotentialNodes []string `json:"potentialNodes,omitempty"` +} + +// PodSchedulingContextSpecApplyConfiguration constructs an declarative configuration of the PodSchedulingContextSpec type for use with +// apply. +func PodSchedulingContextSpec() *PodSchedulingContextSpecApplyConfiguration { + return &PodSchedulingContextSpecApplyConfiguration{} +} + +// WithSelectedNode sets the SelectedNode field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SelectedNode field is set to the value of the last call. +func (b *PodSchedulingContextSpecApplyConfiguration) WithSelectedNode(value string) *PodSchedulingContextSpecApplyConfiguration { + b.SelectedNode = &value + return b +} + +// WithPotentialNodes adds the given value to the PotentialNodes field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the PotentialNodes field. +func (b *PodSchedulingContextSpecApplyConfiguration) WithPotentialNodes(values ...string) *PodSchedulingContextSpecApplyConfiguration { + for i := range values { + b.PotentialNodes = append(b.PotentialNodes, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go new file mode 100644 index 00000000000..a8b10b9a0e8 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodSchedulingContextStatusApplyConfiguration represents an declarative configuration of the PodSchedulingContextStatus type for use +// with apply. +type PodSchedulingContextStatusApplyConfiguration struct { + ResourceClaims []ResourceClaimSchedulingStatusApplyConfiguration `json:"resourceClaims,omitempty"` +} + +// PodSchedulingContextStatusApplyConfiguration constructs an declarative configuration of the PodSchedulingContextStatus type for use with +// apply. +func PodSchedulingContextStatus() *PodSchedulingContextStatusApplyConfiguration { + return &PodSchedulingContextStatusApplyConfiguration{} +} + +// WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceClaims field. +func (b *PodSchedulingContextStatusApplyConfiguration) WithResourceClaims(values ...*ResourceClaimSchedulingStatusApplyConfiguration) *PodSchedulingContextStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceClaims") + } + b.ResourceClaims = append(b.ResourceClaims, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go new file mode 100644 index 00000000000..6c219f837b6 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go @@ -0,0 +1,258 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClaimApplyConfiguration represents an declarative configuration of the ResourceClaim type for use +// with apply. +type ResourceClaimApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ResourceClaimSpecApplyConfiguration `json:"spec,omitempty"` + Status *ResourceClaimStatusApplyConfiguration `json:"status,omitempty"` +} + +// ResourceClaim constructs an declarative configuration of the ResourceClaim type for use with +// apply. +func ResourceClaim(name, namespace string) *ResourceClaimApplyConfiguration { + b := &ResourceClaimApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("ResourceClaim") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractResourceClaim extracts the applied configuration owned by fieldManager from +// resourceClaim. If no managedFields are found in resourceClaim for fieldManager, a +// ResourceClaimApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// resourceClaim must be a unmodified ResourceClaim API object that was retrieved from the Kubernetes API. +// ExtractResourceClaim provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { + return extractResourceClaim(resourceClaim, fieldManager, "") +} + +// ExtractResourceClaimStatus is the same as ExtractResourceClaim except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractResourceClaimStatus(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { + return extractResourceClaim(resourceClaim, fieldManager, "status") +} + +func extractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string, subresource string) (*ResourceClaimApplyConfiguration, error) { + b := &ResourceClaimApplyConfiguration{} + err := managedfields.ExtractInto(resourceClaim, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaim"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(resourceClaim.Name) + b.WithNamespace(resourceClaim.Namespace) + + b.WithKind("ResourceClaim") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithKind(value string) *ResourceClaimApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithAPIVersion(value string) *ResourceClaimApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithName(value string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithGenerateName(value string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithNamespace(value string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithUID(value types.UID) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithResourceVersion(value string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithGeneration(value int64) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClaimApplyConfiguration) WithLabels(entries map[string]string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClaimApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClaimApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClaimApplyConfiguration) WithFinalizers(values ...string) *ResourceClaimApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClaimApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithSpec(value *ResourceClaimSpecApplyConfiguration) *ResourceClaimApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ResourceClaimApplyConfiguration) WithStatus(value *ResourceClaimStatusApplyConfiguration) *ResourceClaimApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go new file mode 100644 index 00000000000..41bb9e9a141 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + types "k8s.io/apimachinery/pkg/types" +) + +// ResourceClaimConsumerReferenceApplyConfiguration represents an declarative configuration of the ResourceClaimConsumerReference type for use +// with apply. +type ResourceClaimConsumerReferenceApplyConfiguration struct { + APIGroup *string `json:"apiGroup,omitempty"` + Resource *string `json:"resource,omitempty"` + Name *string `json:"name,omitempty"` + UID *types.UID `json:"uid,omitempty"` +} + +// ResourceClaimConsumerReferenceApplyConfiguration constructs an declarative configuration of the ResourceClaimConsumerReference type for use with +// apply. +func ResourceClaimConsumerReference() *ResourceClaimConsumerReferenceApplyConfiguration { + return &ResourceClaimConsumerReferenceApplyConfiguration{} +} + +// WithAPIGroup sets the APIGroup field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIGroup field is set to the value of the last call. +func (b *ResourceClaimConsumerReferenceApplyConfiguration) WithAPIGroup(value string) *ResourceClaimConsumerReferenceApplyConfiguration { + b.APIGroup = &value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *ResourceClaimConsumerReferenceApplyConfiguration) WithResource(value string) *ResourceClaimConsumerReferenceApplyConfiguration { + b.Resource = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimConsumerReferenceApplyConfiguration) WithName(value string) *ResourceClaimConsumerReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClaimConsumerReferenceApplyConfiguration) WithUID(value types.UID) *ResourceClaimConsumerReferenceApplyConfiguration { + b.UID = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go new file mode 100644 index 00000000000..27820ede60c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go @@ -0,0 +1,57 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceClaimParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClaimParametersReference type for use +// with apply. +type ResourceClaimParametersReferenceApplyConfiguration struct { + APIGroup *string `json:"apiGroup,omitempty"` + Kind *string `json:"kind,omitempty"` + Name *string `json:"name,omitempty"` +} + +// ResourceClaimParametersReferenceApplyConfiguration constructs an declarative configuration of the ResourceClaimParametersReference type for use with +// apply. +func ResourceClaimParametersReference() *ResourceClaimParametersReferenceApplyConfiguration { + return &ResourceClaimParametersReferenceApplyConfiguration{} +} + +// WithAPIGroup sets the APIGroup field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIGroup field is set to the value of the last call. +func (b *ResourceClaimParametersReferenceApplyConfiguration) WithAPIGroup(value string) *ResourceClaimParametersReferenceApplyConfiguration { + b.APIGroup = &value + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClaimParametersReferenceApplyConfiguration) WithKind(value string) *ResourceClaimParametersReferenceApplyConfiguration { + b.Kind = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimParametersReferenceApplyConfiguration) WithName(value string) *ResourceClaimParametersReferenceApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go new file mode 100644 index 00000000000..e74679aed3a --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go @@ -0,0 +1,50 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceClaimSchedulingStatusApplyConfiguration represents an declarative configuration of the ResourceClaimSchedulingStatus type for use +// with apply. +type ResourceClaimSchedulingStatusApplyConfiguration struct { + Name *string `json:"name,omitempty"` + UnsuitableNodes []string `json:"unsuitableNodes,omitempty"` +} + +// ResourceClaimSchedulingStatusApplyConfiguration constructs an declarative configuration of the ResourceClaimSchedulingStatus type for use with +// apply. +func ResourceClaimSchedulingStatus() *ResourceClaimSchedulingStatusApplyConfiguration { + return &ResourceClaimSchedulingStatusApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimSchedulingStatusApplyConfiguration) WithName(value string) *ResourceClaimSchedulingStatusApplyConfiguration { + b.Name = &value + return b +} + +// WithUnsuitableNodes adds the given value to the UnsuitableNodes field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the UnsuitableNodes field. +func (b *ResourceClaimSchedulingStatusApplyConfiguration) WithUnsuitableNodes(values ...string) *ResourceClaimSchedulingStatusApplyConfiguration { + for i := range values { + b.UnsuitableNodes = append(b.UnsuitableNodes, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go new file mode 100644 index 00000000000..0c73e64e9ed --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go @@ -0,0 +1,61 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" +) + +// ResourceClaimSpecApplyConfiguration represents an declarative configuration of the ResourceClaimSpec type for use +// with apply. +type ResourceClaimSpecApplyConfiguration struct { + ResourceClassName *string `json:"resourceClassName,omitempty"` + ParametersRef *ResourceClaimParametersReferenceApplyConfiguration `json:"parametersRef,omitempty"` + AllocationMode *resourcev1alpha2.AllocationMode `json:"allocationMode,omitempty"` +} + +// ResourceClaimSpecApplyConfiguration constructs an declarative configuration of the ResourceClaimSpec type for use with +// apply. +func ResourceClaimSpec() *ResourceClaimSpecApplyConfiguration { + return &ResourceClaimSpecApplyConfiguration{} +} + +// WithResourceClassName sets the ResourceClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClassName field is set to the value of the last call. +func (b *ResourceClaimSpecApplyConfiguration) WithResourceClassName(value string) *ResourceClaimSpecApplyConfiguration { + b.ResourceClassName = &value + return b +} + +// WithParametersRef sets the ParametersRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParametersRef field is set to the value of the last call. +func (b *ResourceClaimSpecApplyConfiguration) WithParametersRef(value *ResourceClaimParametersReferenceApplyConfiguration) *ResourceClaimSpecApplyConfiguration { + b.ParametersRef = value + return b +} + +// WithAllocationMode sets the AllocationMode field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocationMode field is set to the value of the last call. +func (b *ResourceClaimSpecApplyConfiguration) WithAllocationMode(value resourcev1alpha2.AllocationMode) *ResourceClaimSpecApplyConfiguration { + b.AllocationMode = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go new file mode 100644 index 00000000000..c6fa610906f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go @@ -0,0 +1,71 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceClaimStatusApplyConfiguration represents an declarative configuration of the ResourceClaimStatus type for use +// with apply. +type ResourceClaimStatusApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + Allocation *AllocationResultApplyConfiguration `json:"allocation,omitempty"` + ReservedFor []ResourceClaimConsumerReferenceApplyConfiguration `json:"reservedFor,omitempty"` + DeallocationRequested *bool `json:"deallocationRequested,omitempty"` +} + +// ResourceClaimStatusApplyConfiguration constructs an declarative configuration of the ResourceClaimStatus type for use with +// apply. +func ResourceClaimStatus() *ResourceClaimStatusApplyConfiguration { + return &ResourceClaimStatusApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceClaimStatusApplyConfiguration) WithDriverName(value string) *ResourceClaimStatusApplyConfiguration { + b.DriverName = &value + return b +} + +// WithAllocation sets the Allocation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Allocation field is set to the value of the last call. +func (b *ResourceClaimStatusApplyConfiguration) WithAllocation(value *AllocationResultApplyConfiguration) *ResourceClaimStatusApplyConfiguration { + b.Allocation = value + return b +} + +// WithReservedFor adds the given value to the ReservedFor field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ReservedFor field. +func (b *ResourceClaimStatusApplyConfiguration) WithReservedFor(values ...*ResourceClaimConsumerReferenceApplyConfiguration) *ResourceClaimStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithReservedFor") + } + b.ReservedFor = append(b.ReservedFor, *values[i]) + } + return b +} + +// WithDeallocationRequested sets the DeallocationRequested field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeallocationRequested field is set to the value of the last call. +func (b *ResourceClaimStatusApplyConfiguration) WithDeallocationRequested(value bool) *ResourceClaimStatusApplyConfiguration { + b.DeallocationRequested = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go new file mode 100644 index 00000000000..fc2209b8f09 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go @@ -0,0 +1,249 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClaimTemplateApplyConfiguration represents an declarative configuration of the ResourceClaimTemplate type for use +// with apply. +type ResourceClaimTemplateApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ResourceClaimTemplateSpecApplyConfiguration `json:"spec,omitempty"` +} + +// ResourceClaimTemplate constructs an declarative configuration of the ResourceClaimTemplate type for use with +// apply. +func ResourceClaimTemplate(name, namespace string) *ResourceClaimTemplateApplyConfiguration { + b := &ResourceClaimTemplateApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("ResourceClaimTemplate") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractResourceClaimTemplate extracts the applied configuration owned by fieldManager from +// resourceClaimTemplate. If no managedFields are found in resourceClaimTemplate for fieldManager, a +// ResourceClaimTemplateApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// resourceClaimTemplate must be a unmodified ResourceClaimTemplate API object that was retrieved from the Kubernetes API. +// ExtractResourceClaimTemplate provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { + return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "") +} + +// ExtractResourceClaimTemplateStatus is the same as ExtractResourceClaimTemplate except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractResourceClaimTemplateStatus(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { + return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "status") +} + +func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string, subresource string) (*ResourceClaimTemplateApplyConfiguration, error) { + b := &ResourceClaimTemplateApplyConfiguration{} + err := managedfields.ExtractInto(resourceClaimTemplate, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaimTemplate"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(resourceClaimTemplate.Name) + b.WithNamespace(resourceClaimTemplate.Namespace) + + b.WithKind("ResourceClaimTemplate") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithKind(value string) *ResourceClaimTemplateApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithAPIVersion(value string) *ResourceClaimTemplateApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithName(value string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithGenerateName(value string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithNamespace(value string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithUID(value types.UID) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithResourceVersion(value string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithGeneration(value int64) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClaimTemplateApplyConfiguration) WithLabels(entries map[string]string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClaimTemplateApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClaimTemplateApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClaimTemplateApplyConfiguration) WithFinalizers(values ...string) *ResourceClaimTemplateApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClaimTemplateApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ResourceClaimTemplateApplyConfiguration) WithSpec(value *ResourceClaimTemplateSpecApplyConfiguration) *ResourceClaimTemplateApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go new file mode 100644 index 00000000000..2f38ea03668 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go @@ -0,0 +1,188 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClaimTemplateSpecApplyConfiguration represents an declarative configuration of the ResourceClaimTemplateSpec type for use +// with apply. +type ResourceClaimTemplateSpecApplyConfiguration struct { + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ResourceClaimSpecApplyConfiguration `json:"spec,omitempty"` +} + +// ResourceClaimTemplateSpecApplyConfiguration constructs an declarative configuration of the ResourceClaimTemplateSpec type for use with +// apply. +func ResourceClaimTemplateSpec() *ResourceClaimTemplateSpecApplyConfiguration { + return &ResourceClaimTemplateSpecApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithName(value string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithGenerateName(value string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithNamespace(value string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithUID(value types.UID) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithResourceVersion(value string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithGeneration(value int64) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithLabels(entries map[string]string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithFinalizers(values ...string) *ResourceClaimTemplateSpecApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClaimTemplateSpecApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ResourceClaimTemplateSpecApplyConfiguration) WithSpec(value *ResourceClaimSpecApplyConfiguration) *ResourceClaimTemplateSpecApplyConfiguration { + b.Spec = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go new file mode 100644 index 00000000000..724c9e88e00 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go @@ -0,0 +1,266 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourceClassApplyConfiguration represents an declarative configuration of the ResourceClass type for use +// with apply. +type ResourceClassApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + DriverName *string `json:"driverName,omitempty"` + ParametersRef *ResourceClassParametersReferenceApplyConfiguration `json:"parametersRef,omitempty"` + SuitableNodes *corev1.NodeSelectorApplyConfiguration `json:"suitableNodes,omitempty"` +} + +// ResourceClass constructs an declarative configuration of the ResourceClass type for use with +// apply. +func ResourceClass(name string) *ResourceClassApplyConfiguration { + b := &ResourceClassApplyConfiguration{} + b.WithName(name) + b.WithKind("ResourceClass") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractResourceClass extracts the applied configuration owned by fieldManager from +// resourceClass. If no managedFields are found in resourceClass for fieldManager, a +// ResourceClassApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// resourceClass must be a unmodified ResourceClass API object that was retrieved from the Kubernetes API. +// ExtractResourceClass provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { + return extractResourceClass(resourceClass, fieldManager, "") +} + +// ExtractResourceClassStatus is the same as ExtractResourceClass except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractResourceClassStatus(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { + return extractResourceClass(resourceClass, fieldManager, "status") +} + +func extractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string, subresource string) (*ResourceClassApplyConfiguration, error) { + b := &ResourceClassApplyConfiguration{} + err := managedfields.ExtractInto(resourceClass, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClass"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(resourceClass.Name) + + b.WithKind("ResourceClass") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithKind(value string) *ResourceClassApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithAPIVersion(value string) *ResourceClassApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithName(value string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithGenerateName(value string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithNamespace(value string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithUID(value types.UID) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithResourceVersion(value string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithGeneration(value int64) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ResourceClassApplyConfiguration) WithLabels(entries map[string]string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ResourceClassApplyConfiguration) WithAnnotations(entries map[string]string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ResourceClassApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ResourceClassApplyConfiguration) WithFinalizers(values ...string) *ResourceClassApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *ResourceClassApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithDriverName(value string) *ResourceClassApplyConfiguration { + b.DriverName = &value + return b +} + +// WithParametersRef sets the ParametersRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParametersRef field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithParametersRef(value *ResourceClassParametersReferenceApplyConfiguration) *ResourceClassApplyConfiguration { + b.ParametersRef = value + return b +} + +// WithSuitableNodes sets the SuitableNodes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SuitableNodes field is set to the value of the last call. +func (b *ResourceClassApplyConfiguration) WithSuitableNodes(value *corev1.NodeSelectorApplyConfiguration) *ResourceClassApplyConfiguration { + b.SuitableNodes = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go new file mode 100644 index 00000000000..d67e4d39771 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceClassParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClassParametersReference type for use +// with apply. +type ResourceClassParametersReferenceApplyConfiguration struct { + APIGroup *string `json:"apiGroup,omitempty"` + Kind *string `json:"kind,omitempty"` + Name *string `json:"name,omitempty"` + Namespace *string `json:"namespace,omitempty"` +} + +// ResourceClassParametersReferenceApplyConfiguration constructs an declarative configuration of the ResourceClassParametersReference type for use with +// apply. +func ResourceClassParametersReference() *ResourceClassParametersReferenceApplyConfiguration { + return &ResourceClassParametersReferenceApplyConfiguration{} +} + +// WithAPIGroup sets the APIGroup field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIGroup field is set to the value of the last call. +func (b *ResourceClassParametersReferenceApplyConfiguration) WithAPIGroup(value string) *ResourceClassParametersReferenceApplyConfiguration { + b.APIGroup = &value + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ResourceClassParametersReferenceApplyConfiguration) WithKind(value string) *ResourceClassParametersReferenceApplyConfiguration { + b.Kind = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ResourceClassParametersReferenceApplyConfiguration) WithName(value string) *ResourceClassParametersReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ResourceClassParametersReferenceApplyConfiguration) WithNamespace(value string) *ResourceClassParametersReferenceApplyConfiguration { + b.Namespace = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go new file mode 100644 index 00000000000..028cbaa1a7e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go @@ -0,0 +1,48 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceHandleApplyConfiguration represents an declarative configuration of the ResourceHandle type for use +// with apply. +type ResourceHandleApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + Data *string `json:"data,omitempty"` +} + +// ResourceHandleApplyConfiguration constructs an declarative configuration of the ResourceHandle type for use with +// apply. +func ResourceHandle() *ResourceHandleApplyConfiguration { + return &ResourceHandleApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithDriverName(value string) *ResourceHandleApplyConfiguration { + b.DriverName = &value + return b +} + +// WithData sets the Data field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Data field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithData(value string) *ResourceHandleApplyConfiguration { + b.Data = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go index 1dc17ce96a8..a1ef00656bb 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go @@ -32,6 +32,7 @@ type CSIDriverSpecApplyConfiguration struct { FSGroupPolicy *v1.FSGroupPolicy `json:"fsGroupPolicy,omitempty"` TokenRequests []TokenRequestApplyConfiguration `json:"tokenRequests,omitempty"` RequiresRepublish *bool `json:"requiresRepublish,omitempty"` + SELinuxMount *bool `json:"seLinuxMount,omitempty"` } // CSIDriverSpecApplyConfiguration constructs an declarative configuration of the CSIDriverSpec type for use with @@ -102,3 +103,11 @@ func (b *CSIDriverSpecApplyConfiguration) WithRequiresRepublish(value bool) *CSI b.RequiresRepublish = &value return b } + +// WithSELinuxMount sets the SELinuxMount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SELinuxMount field is set to the value of the last call. +func (b *CSIDriverSpecApplyConfiguration) WithSELinuxMount(value bool) *CSIDriverSpecApplyConfiguration { + b.SELinuxMount = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go b/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go index 1d943cbfffe..6097a615be2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go @@ -32,6 +32,7 @@ type CSIDriverSpecApplyConfiguration struct { FSGroupPolicy *v1beta1.FSGroupPolicy `json:"fsGroupPolicy,omitempty"` TokenRequests []TokenRequestApplyConfiguration `json:"tokenRequests,omitempty"` RequiresRepublish *bool `json:"requiresRepublish,omitempty"` + SELinuxMount *bool `json:"seLinuxMount,omitempty"` } // CSIDriverSpecApplyConfiguration constructs an declarative configuration of the CSIDriverSpec type for use with @@ -102,3 +103,11 @@ func (b *CSIDriverSpecApplyConfiguration) WithRequiresRepublish(value bool) *CSI b.RequiresRepublish = &value return b } + +// WithSELinuxMount sets the SELinuxMount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SELinuxMount field is set to the value of the last call. +func (b *CSIDriverSpecApplyConfiguration) WithSELinuxMount(value bool) *CSIDriverSpecApplyConfiguration { + b.SELinuxMount = &value + return b +} diff --git a/vendor/k8s.io/client-go/discovery/aggregated_discovery.go b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go new file mode 100644 index 00000000000..7470259dc86 --- /dev/null +++ b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go @@ -0,0 +1,154 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package discovery + +import ( + "fmt" + + apidiscovery "k8s.io/api/apidiscovery/v2beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// StaleGroupVersionError encasulates failed GroupVersion marked "stale" +// in the returned AggregatedDiscovery format. +type StaleGroupVersionError struct { + gv schema.GroupVersion +} + +func (s StaleGroupVersionError) Error() string { + return fmt.Sprintf("stale GroupVersion discovery: %v", s.gv) +} + +// SplitGroupsAndResources transforms "aggregated" discovery top-level structure into +// the previous "unaggregated" discovery groups and resources. +func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList) ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { + // Aggregated group list will contain the entirety of discovery, including + // groups, versions, and resources. GroupVersions marked "stale" are failed. + groups := []*metav1.APIGroup{} + failedGVs := map[schema.GroupVersion]error{} + resourcesByGV := map[schema.GroupVersion]*metav1.APIResourceList{} + for _, aggGroup := range aggregatedGroups.Items { + group, resources, failed := convertAPIGroup(aggGroup) + groups = append(groups, group) + for gv, resourceList := range resources { + resourcesByGV[gv] = resourceList + } + for gv, err := range failed { + failedGVs[gv] = err + } + } + // Transform slice of groups to group list before returning. + groupList := &metav1.APIGroupList{} + groupList.Groups = make([]metav1.APIGroup, 0, len(groups)) + for _, group := range groups { + groupList.Groups = append(groupList.Groups, *group) + } + return groupList, resourcesByGV, failedGVs +} + +// convertAPIGroup tranforms an "aggregated" APIGroupDiscovery to an "legacy" APIGroup, +// also returning the map of APIResourceList for resources within GroupVersions. +func convertAPIGroup(g apidiscovery.APIGroupDiscovery) ( + *metav1.APIGroup, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { + // Iterate through versions to convert to group and resources. + group := &metav1.APIGroup{} + gvResources := map[schema.GroupVersion]*metav1.APIResourceList{} + failedGVs := map[schema.GroupVersion]error{} + group.Name = g.ObjectMeta.Name + for _, v := range g.Versions { + gv := schema.GroupVersion{Group: g.Name, Version: v.Version} + if v.Freshness == apidiscovery.DiscoveryFreshnessStale { + failedGVs[gv] = StaleGroupVersionError{gv: gv} + continue + } + version := metav1.GroupVersionForDiscovery{} + version.GroupVersion = gv.String() + version.Version = v.Version + group.Versions = append(group.Versions, version) + // PreferredVersion is first non-stale Version + if group.PreferredVersion == (metav1.GroupVersionForDiscovery{}) { + group.PreferredVersion = version + } + resourceList := &metav1.APIResourceList{} + resourceList.GroupVersion = gv.String() + for _, r := range v.Resources { + resource, err := convertAPIResource(r) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, resource) + } + // Subresources field in new format get transformed into full APIResources. + // It is possible a partial result with an error was returned to be used + // as the parent resource for the subresource. + for _, subresource := range r.Subresources { + sr, err := convertAPISubresource(resource, subresource) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, sr) + } + } + } + gvResources[gv] = resourceList + } + return group, gvResources, failedGVs +} + +// convertAPIResource tranforms a APIResourceDiscovery to an APIResource. We are +// resilient to missing GVK, since this resource might be the parent resource +// for a subresource. If the parent is missing a GVK, it is not returned in +// discovery, and the subresource MUST have the GVK. +func convertAPIResource(in apidiscovery.APIResourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{ + Name: in.Resource, + SingularName: in.SingularResource, + Namespaced: in.Scope == apidiscovery.ScopeNamespace, + Verbs: in.Verbs, + ShortNames: in.ShortNames, + Categories: in.Categories, + } + var err error + if in.ResponseKind != nil { + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + } else { + err = fmt.Errorf("discovery resource %s missing GVK", in.Resource) + } + // Can return partial result with error, which can be the parent for a + // subresource. Do not add this result to the returned discovery resources. + return result, err +} + +// convertAPISubresource tranforms a APISubresourceDiscovery to an APIResource. +func convertAPISubresource(parent metav1.APIResource, in apidiscovery.APISubresourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{} + if in.ResponseKind == nil { + return result, fmt.Errorf("subresource %s/%s missing GVK", parent.Name, in.Subresource) + } + result.Name = fmt.Sprintf("%s/%s", parent.Name, in.Subresource) + result.SingularName = parent.SingularName + result.Namespaced = parent.Namespaced + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + result.Verbs = in.Verbs + return result, nil +} diff --git a/vendor/k8s.io/client-go/discovery/discovery_client.go b/vendor/k8s.io/client-go/discovery/discovery_client.go index baf87884621..1253fa1f44a 100644 --- a/vendor/k8s.io/client-go/discovery/discovery_client.go +++ b/vendor/k8s.io/client-go/discovery/discovery_client.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "mime" "net/http" "net/url" "sort" @@ -31,6 +32,7 @@ import ( "github.com/golang/protobuf/proto" openapi_v2 "github.com/google/gnostic/openapiv2" + apidiscovery "k8s.io/api/apidiscovery/v2beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -52,6 +54,17 @@ const ( // defaultTimeout is the maximum amount of time per request when no timeout has been set on a RESTClient. // Defaults to 32s in order to have a distinguishable length of time, relative to other timeouts that exist. defaultTimeout = 32 * time.Second + + // defaultBurst is the default burst to be used with the discovery client's token bucket rate limiter + defaultBurst = 300 + + AcceptV1 = runtime.ContentTypeJSON + // Aggregated discovery content-type (v2beta1). NOTE: content-type parameters + // MUST be ordered (g, v, as) for server in "Accept" header (BUT we are resilient + // to ordering when comparing returned values in "Content-Type" header). + AcceptV2Beta1 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList" + // Prioritize aggregated discovery by placing first in the order of discovery accept types. + acceptDiscoveryFormats = AcceptV2Beta1 + "," + AcceptV1 ) // DiscoveryInterface holds the methods that discover server-supported API groups, @@ -63,6 +76,19 @@ type DiscoveryInterface interface { ServerVersionInterface OpenAPISchemaInterface OpenAPIV3SchemaInterface + // Returns copy of current discovery client that will only + // receive the legacy discovery format, or pointer to current + // discovery client if it does not support legacy-only discovery. + WithLegacy() DiscoveryInterface +} + +// AggregatedDiscoveryInterface extends DiscoveryInterface to include a method to possibly +// return discovery resources along with the discovery groups, which is what the newer +// aggregated discovery format does (APIGroupDiscoveryList). +type AggregatedDiscoveryInterface interface { + DiscoveryInterface + + GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error, error) } // CachedDiscoveryInterface is a DiscoveryInterface with cache invalidation and freshness. @@ -134,8 +160,12 @@ type DiscoveryClient struct { restClient restclient.Interface LegacyPrefix string + // Forces the client to request only "unaggregated" (legacy) discovery. + UseLegacyDiscovery bool } +var _ AggregatedDiscoveryInterface = &DiscoveryClient{} + // Convert metav1.APIVersions to metav1.APIGroup. APIVersions is used by legacy v1, so // group would be "". func apiVersionsToAPIGroup(apiVersions *metav1.APIVersions) (apiGroup metav1.APIGroup) { @@ -153,36 +183,186 @@ func apiVersionsToAPIGroup(apiVersions *metav1.APIVersions) (apiGroup metav1.API return } -// ServerGroups returns the supported groups, with information like supported versions and the -// preferred version. -func (d *DiscoveryClient) ServerGroups() (apiGroupList *metav1.APIGroupList, err error) { - // Get the groupVersions exposed at /api - v := &metav1.APIVersions{} - err = d.restClient.Get().AbsPath(d.LegacyPrefix).Do(context.TODO()).Into(v) - apiGroup := metav1.APIGroup{} - if err == nil && len(v.Versions) != 0 { - apiGroup = apiVersionsToAPIGroup(v) - } - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, err +// GroupsAndMaybeResources returns the discovery groups, and (if new aggregated +// discovery format) the resources keyed by group/version. Merges discovery groups +// and resources from /api and /apis (either aggregated or not). Legacy groups +// must be ordered first. The server will either return both endpoints (/api, /apis) +// as aggregated discovery format or legacy format. For safety, resources will only +// be returned if both endpoints returned resources. Returned "failedGVs" can be +// empty, but will only be nil in the case an error is returned. +func (d *DiscoveryClient) GroupsAndMaybeResources() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { + // Legacy group ordered first (there is only one -- core/v1 group). Returned groups must + // be non-nil, but it could be empty. Returned resources, apiResources map could be nil. + groups, resources, failedGVs, err := d.downloadLegacy() + if err != nil { + return nil, nil, nil, err + } + // Discovery groups and (possibly) resources downloaded from /apis. + apiGroups, apiResources, failedApisGVs, aerr := d.downloadAPIs() + if aerr != nil { + return nil, nil, nil, aerr + } + // Merge apis groups into the legacy groups. + for _, group := range apiGroups.Groups { + groups.Groups = append(groups.Groups, group) + } + // For safety, only return resources if both endpoints returned resources. + if resources != nil && apiResources != nil { + for gv, resourceList := range apiResources { + resources[gv] = resourceList + } + } else if resources != nil { + resources = nil } + // Merge failed GroupVersions from /api and /apis + for gv, err := range failedApisGVs { + failedGVs[gv] = err + } + return groups, resources, failedGVs, err +} - // Get the groupVersions exposed at /apis - apiGroupList = &metav1.APIGroupList{} - err = d.restClient.Get().AbsPath("/apis").Do(context.TODO()).Into(apiGroupList) - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, err +// downloadLegacy returns the discovery groups and possibly resources +// for the legacy v1 GVR at /api, or an error if one occurred. It is +// possible for the resource map to be nil if the server returned +// the unaggregated discovery. Returned "failedGVs" can be empty, but +// will only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadLegacy() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { + accept := acceptDiscoveryFormats + if d.UseLegacyDiscovery { + accept = AcceptV1 + } + var responseContentType string + body, err := d.restClient.Get(). + AbsPath("/api"). + SetHeader("Accept", accept). + Do(context.TODO()). + ContentType(&responseContentType). + Raw() + apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} + if err != nil { + // Tolerate 404, since aggregated api servers can return it. + if errors.IsNotFound(err) { + // Return empty structures and no error. + emptyGVMap := map[schema.GroupVersion]*metav1.APIResourceList{} + return apiGroupList, emptyGVMap, failedGVs, nil + } else { + return nil, nil, nil, err + } + } + + var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList + // Switch on content-type server responded with: aggregated or unaggregated. + switch { + case isV2Beta1ContentType(responseContentType): + var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList + err = json.Unmarshal(body, &aggregatedDiscovery) + if err != nil { + return nil, nil, nil, err + } + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) + default: + // Default is unaggregated discovery v1. + var v metav1.APIVersions + err = json.Unmarshal(body, &v) + if err != nil { + return nil, nil, nil, err + } + apiGroup := metav1.APIGroup{} + if len(v.Versions) != 0 { + apiGroup = apiVersionsToAPIGroup(&v) + } + apiGroupList.Groups = []metav1.APIGroup{apiGroup} + } + + return apiGroupList, resourcesByGV, failedGVs, nil +} + +// downloadAPIs returns the discovery groups and (if aggregated format) the +// discovery resources. The returned groups will always exist, but the +// resources map may be nil. Returned "failedGVs" can be empty, but will +// only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadAPIs() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { + accept := acceptDiscoveryFormats + if d.UseLegacyDiscovery { + accept = AcceptV1 + } + var responseContentType string + body, err := d.restClient.Get(). + AbsPath("/apis"). + SetHeader("Accept", accept). + Do(context.TODO()). + ContentType(&responseContentType). + Raw() + if err != nil { + return nil, nil, nil, err + } + + apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} + var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList + // Switch on content-type server responded with: aggregated or unaggregated. + switch { + case isV2Beta1ContentType(responseContentType): + var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList + err = json.Unmarshal(body, &aggregatedDiscovery) + if err != nil { + return nil, nil, nil, err + } + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) + default: + // Default is unaggregated discovery v1. + err = json.Unmarshal(body, apiGroupList) + if err != nil { + return nil, nil, nil, err + } } - // to be compatible with a v1.0 server, if it's a 403 or 404, ignore and return whatever we got from /api - if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - apiGroupList = &metav1.APIGroupList{} + + return apiGroupList, resourcesByGV, failedGVs, nil +} + +// isV2Beta1ContentType checks of the content-type string is both +// "application/json" and contains the v2beta1 content-type params. +// NOTE: This function is resilient to the ordering of the +// content-type parameters, as well as parameters added by +// intermediaries such as proxies or gateways. Examples: +// +// "application/json; g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList" = true +// "application/json; as=APIGroupDiscoveryList;v=v2beta1;g=apidiscovery.k8s.io" = true +// "application/json; as=APIGroupDiscoveryList;v=v2beta1;g=apidiscovery.k8s.io;charset=utf-8" = true +// "application/json" = false +// "application/json; charset=UTF-8" = false +func isV2Beta1ContentType(contentType string) bool { + base, params, err := mime.ParseMediaType(contentType) + if err != nil { + return false } + return runtime.ContentTypeJSON == base && + params["g"] == "apidiscovery.k8s.io" && + params["v"] == "v2beta1" && + params["as"] == "APIGroupDiscoveryList" +} - // prepend the group retrieved from /api to the list if not empty - if len(v.Versions) != 0 { - apiGroupList.Groups = append([]metav1.APIGroup{apiGroup}, apiGroupList.Groups...) +// ServerGroups returns the supported groups, with information like supported versions and the +// preferred version. +func (d *DiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) { + groups, _, _, err := d.GroupsAndMaybeResources() + if err != nil { + return nil, err } - return apiGroupList, nil + return groups, nil } // ServerResourcesForGroupVersion returns the supported resources for a group and version. @@ -201,8 +381,10 @@ func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (r } err = d.restClient.Get().AbsPath(url.String()).Do(context.TODO()).Into(resources) if err != nil { - // ignore 403 or 404 error to be compatible with an v1.0 server. - if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) { + // Tolerate core/v1 not found response by returning empty resource list; + // this probably should not happen. But we should verify all callers are + // not depending on this toleration before removal. + if groupVersion == "v1" && errors.IsNotFound(err) { return resources, nil } return nil, err @@ -241,7 +423,23 @@ func IsGroupDiscoveryFailedError(err error) bool { } func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) { - sgs, err := d.ServerGroups() + var sgs *metav1.APIGroupList + var resources []*metav1.APIResourceList + var failedGVs map[schema.GroupVersion]error + var err error + + // If the passed discovery object implements the wider AggregatedDiscoveryInterface, + // then attempt to retrieve aggregated discovery with both groups and the resources. + if ad, ok := d.(AggregatedDiscoveryInterface); ok { + var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList + sgs, resourcesByGV, failedGVs, err = ad.GroupsAndMaybeResources() + for _, resourceList := range resourcesByGV { + resources = append(resources, resourceList) + } + } else { + sgs, err = d.ServerGroups() + } + if sgs == nil { return nil, nil, err } @@ -249,6 +447,16 @@ func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*meta for i := range sgs.Groups { resultGroups = append(resultGroups, &sgs.Groups[i]) } + // resources is non-nil if aggregated discovery succeeded. + if resources != nil { + // Any stale Group/Versions returned by aggregated discovery + // must be surfaced to the caller as failed Group/Versions. + var ferr error + if len(failedGVs) > 0 { + ferr = &ErrGroupDiscoveryFailed{Groups: failedGVs} + } + return resultGroups, resources, ferr + } groupVersionResources, failedGroups := fetchGroupVersionResources(d, sgs) @@ -272,12 +480,27 @@ func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*meta // ServerPreferredResources uses the provided discovery interface to look up preferred resources func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) { - serverGroupList, err := d.ServerGroups() + var serverGroupList *metav1.APIGroupList + var failedGroups map[schema.GroupVersion]error + var groupVersionResources map[schema.GroupVersion]*metav1.APIResourceList + var err error + + // If the passed discovery object implements the wider AggregatedDiscoveryInterface, + // then it is attempt to retrieve both the groups and the resources. "failedGroups" + // are Group/Versions returned as stale in AggregatedDiscovery format. + ad, ok := d.(AggregatedDiscoveryInterface) + if ok { + serverGroupList, groupVersionResources, failedGroups, err = ad.GroupsAndMaybeResources() + } else { + serverGroupList, err = d.ServerGroups() + } if err != nil { return nil, err } - - groupVersionResources, failedGroups := fetchGroupVersionResources(d, serverGroupList) + // Non-aggregated discovery must fetch resources from Groups. + if groupVersionResources == nil { + groupVersionResources, failedGroups = fetchGroupVersionResources(d, serverGroupList) + } result := []*metav1.APIResourceList{} grVersions := map[schema.GroupResource]string{} // selected version of a GroupResource @@ -433,6 +656,14 @@ func (d *DiscoveryClient) OpenAPIV3() openapi.Client { return openapi.NewClient(d.restClient) } +// WithLegacy returns copy of current discovery client that will only +// receive the legacy discovery format. +func (d *DiscoveryClient) WithLegacy() DiscoveryInterface { + client := *d + client.UseLegacyDiscovery = true + return &client +} + // withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns. func withRetries(maxRetries int, f func() ([]*metav1.APIGroup, []*metav1.APIResourceList, error)) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) { var result []*metav1.APIResourceList @@ -456,12 +687,13 @@ func setDiscoveryDefaults(config *restclient.Config) error { if config.Timeout == 0 { config.Timeout = defaultTimeout } - if config.Burst == 0 && config.QPS < 100 { + // if a burst limit is not already configured + if config.Burst == 0 { // discovery is expected to be bursty, increase the default burst // to accommodate looking up resource info for many API groups. // matches burst set by ConfigFlags#ToDiscoveryClient(). // see https://issue.k8s.io/86149 - config.Burst = 100 + config.Burst = defaultBurst } codec := runtime.NoopEncoder{Decoder: scheme.Codecs.UniversalDecoder()} config.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}) @@ -496,7 +728,7 @@ func NewDiscoveryClientForConfigAndClient(c *restclient.Config, httpClient *http return nil, err } client, err := restclient.UnversionedRESTClientForConfigAndClient(&config, httpClient) - return &DiscoveryClient{restClient: client, LegacyPrefix: "/api"}, err + return &DiscoveryClient{restClient: client, LegacyPrefix: "/api", UseLegacyDiscovery: false}, err } // NewDiscoveryClientForConfigOrDie creates a new DiscoveryClient for the given config. If @@ -512,7 +744,7 @@ func NewDiscoveryClientForConfigOrDie(c *restclient.Config) *DiscoveryClient { // NewDiscoveryClient returns a new DiscoveryClient for the given RESTClient. func NewDiscoveryClient(c restclient.Interface) *DiscoveryClient { - return &DiscoveryClient{restClient: c, LegacyPrefix: "/api"} + return &DiscoveryClient{restClient: c, LegacyPrefix: "/api", UseLegacyDiscovery: false} } // RESTClient returns a RESTClient that is used to communicate diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go new file mode 100644 index 00000000000..62d01339db4 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go @@ -0,0 +1,188 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dynamicinformer + +import ( + "context" + "sync" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamiclister" + "k8s.io/client-go/informers" + "k8s.io/client-go/tools/cache" +) + +// NewDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory for all namespaces. +func NewDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration) DynamicSharedInformerFactory { + return NewFilteredDynamicSharedInformerFactory(client, defaultResync, metav1.NamespaceAll, nil) +} + +// NewFilteredDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory. +// Listers obtained via this factory will be subject to the same filters as specified here. +func NewFilteredDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration, namespace string, tweakListOptions TweakListOptionsFunc) DynamicSharedInformerFactory { + return &dynamicSharedInformerFactory{ + client: client, + defaultResync: defaultResync, + namespace: namespace, + informers: map[schema.GroupVersionResource]informers.GenericInformer{}, + startedInformers: make(map[schema.GroupVersionResource]bool), + tweakListOptions: tweakListOptions, + } +} + +type dynamicSharedInformerFactory struct { + client dynamic.Interface + defaultResync time.Duration + namespace string + + lock sync.Mutex + informers map[schema.GroupVersionResource]informers.GenericInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[schema.GroupVersionResource]bool + tweakListOptions TweakListOptionsFunc + + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool +} + +var _ DynamicSharedInformerFactory = &dynamicSharedInformerFactory{} + +func (f *dynamicSharedInformerFactory) ForResource(gvr schema.GroupVersionResource) informers.GenericInformer { + f.lock.Lock() + defer f.lock.Unlock() + + key := gvr + informer, exists := f.informers[key] + if exists { + return informer + } + + informer = NewFilteredDynamicInformer(f.client, gvr, f.namespace, f.defaultResync, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + f.informers[key] = informer + + return informer +} + +// Start initializes all requested informers. +func (f *dynamicSharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.shuttingDown { + return + } + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer.Informer() + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() + f.startedInformers[informerType] = true + } + } +} + +// WaitForCacheSync waits for all started informers' cache were synced. +func (f *dynamicSharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool { + informers := func() map[schema.GroupVersionResource]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[schema.GroupVersionResource]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer.Informer() + } + } + return informers + }() + + res := map[schema.GroupVersionResource]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +func (f *dynamicSharedInformerFactory) Shutdown() { + // Will return immediately if there is nothing to wait for. + defer f.wg.Wait() + + f.lock.Lock() + defer f.lock.Unlock() + f.shuttingDown = true +} + +// NewFilteredDynamicInformer constructs a new informer for a dynamic type. +func NewFilteredDynamicInformer(client dynamic.Interface, gvr schema.GroupVersionResource, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions TweakListOptionsFunc) informers.GenericInformer { + return &dynamicInformer{ + gvr: gvr, + informer: cache.NewSharedIndexInformerWithOptions( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).Watch(context.TODO(), options) + }, + }, + &unstructured.Unstructured{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: resyncPeriod, + Indexers: indexers, + ObjectDescription: gvr.String(), + }, + ), + } +} + +type dynamicInformer struct { + informer cache.SharedIndexInformer + gvr schema.GroupVersionResource +} + +var _ informers.GenericInformer = &dynamicInformer{} + +func (d *dynamicInformer) Informer() cache.SharedIndexInformer { + return d.informer +} + +func (d *dynamicInformer) Lister() cache.GenericLister { + return dynamiclister.NewRuntimeObjectShim(dynamiclister.New(d.informer.GetIndexer(), d.gvr)) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go new file mode 100644 index 00000000000..0419ef4f864 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go @@ -0,0 +1,53 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dynamicinformer + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/informers" +) + +// DynamicSharedInformerFactory provides access to a shared informer and lister for dynamic client +type DynamicSharedInformerFactory interface { + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // ForResource gives generic access to a shared informer of the matching type. + ForResource(gvr schema.GroupVersionResource) informers.GenericInformer + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. + WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() +} + +// TweakListOptionsFunc defines the signature of a helper function +// that wants to provide more listing options to API +type TweakListOptionsFunc func(*metav1.ListOptions) diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go new file mode 100644 index 00000000000..c39cbee925b --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go @@ -0,0 +1,40 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dynamiclister + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" +) + +// Lister helps list resources. +type Lister interface { + // List lists all resources in the indexer. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer with the given name + Get(name string) (*unstructured.Unstructured, error) + // Namespace returns an object that can list and get resources in a given namespace. + Namespace(namespace string) NamespaceLister +} + +// NamespaceLister helps list and get resources. +type NamespaceLister interface { + // List lists all resources in the indexer for a given namespace. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer for a given namespace and name. + Get(name string) (*unstructured.Unstructured, error) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go new file mode 100644 index 00000000000..a50fc471e90 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go @@ -0,0 +1,91 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dynamiclister + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" +) + +var _ Lister = &dynamicLister{} +var _ NamespaceLister = &dynamicNamespaceLister{} + +// dynamicLister implements the Lister interface. +type dynamicLister struct { + indexer cache.Indexer + gvr schema.GroupVersionResource +} + +// New returns a new Lister. +func New(indexer cache.Indexer, gvr schema.GroupVersionResource) Lister { + return &dynamicLister{indexer: indexer, gvr: gvr} +} + +// List lists all resources in the indexer. +func (l *dynamicLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAll(l.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer with the given name +func (l *dynamicLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} + +// Namespace returns an object that can list and get resources from a given namespace. +func (l *dynamicLister) Namespace(namespace string) NamespaceLister { + return &dynamicNamespaceLister{indexer: l.indexer, namespace: namespace, gvr: l.gvr} +} + +// dynamicNamespaceLister implements the NamespaceLister interface. +type dynamicNamespaceLister struct { + indexer cache.Indexer + namespace string + gvr schema.GroupVersionResource +} + +// List lists all resources in the indexer for a given namespace. +func (l *dynamicNamespaceLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAllByNamespace(l.indexer, l.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer for a given namespace and name. +func (l *dynamicNamespaceLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(l.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go new file mode 100644 index 00000000000..92a5f54af97 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go @@ -0,0 +1,87 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package dynamiclister + +import ( + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +var _ cache.GenericLister = &dynamicListerShim{} +var _ cache.GenericNamespaceLister = &dynamicNamespaceListerShim{} + +// dynamicListerShim implements the cache.GenericLister interface. +type dynamicListerShim struct { + lister Lister +} + +// NewRuntimeObjectShim returns a new shim for Lister. +// It wraps Lister so that it implements cache.GenericLister interface +func NewRuntimeObjectShim(lister Lister) cache.GenericLister { + return &dynamicListerShim{lister: lister} +} + +// List will return all objects across namespaces +func (s *dynamicListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := s.lister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve assuming that name==key +func (s *dynamicListerShim) Get(name string) (runtime.Object, error) { + return s.lister.Get(name) +} + +func (s *dynamicListerShim) ByNamespace(namespace string) cache.GenericNamespaceLister { + return &dynamicNamespaceListerShim{ + namespaceLister: s.lister.Namespace(namespace), + } +} + +// dynamicNamespaceListerShim implements the NamespaceLister interface. +// It wraps NamespaceLister so that it implements cache.GenericNamespaceLister interface +type dynamicNamespaceListerShim struct { + namespaceLister NamespaceLister +} + +// List will return all objects in this namespace +func (ns *dynamicNamespaceListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := ns.namespaceLister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve by namespace and name +func (ns *dynamicNamespaceListerShim) Get(name string) (runtime.Object, error) { + return ns.namespaceLister.Get(name) +} diff --git a/vendor/k8s.io/client-go/dynamic/interface.go b/vendor/k8s.io/client-go/dynamic/interface.go index b08067c341d..a310b63e5ef 100644 --- a/vendor/k8s.io/client-go/dynamic/interface.go +++ b/vendor/k8s.io/client-go/dynamic/interface.go @@ -40,6 +40,8 @@ type ResourceInterface interface { List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) + Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) + ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions) (*unstructured.Unstructured, error) } type NamespaceableResourceInterface interface { diff --git a/vendor/k8s.io/client-go/dynamic/simple.go b/vendor/k8s.io/client-go/dynamic/simple.go index 87594bf2e16..4b548595302 100644 --- a/vendor/k8s.io/client-go/dynamic/simple.go +++ b/vendor/k8s.io/client-go/dynamic/simple.go @@ -31,11 +31,11 @@ import ( "k8s.io/client-go/rest" ) -type dynamicClient struct { - client *rest.RESTClient +type DynamicClient struct { + client rest.Interface } -var _ Interface = &dynamicClient{} +var _ Interface = &DynamicClient{} // ConfigFor returns a copy of the provided config with the // appropriate dynamic client defaults set. @@ -50,9 +50,14 @@ func ConfigFor(inConfig *rest.Config) *rest.Config { return config } -// NewForConfigOrDie creates a new Interface for the given config and +// New creates a new DynamicClient for the given RESTClient. +func New(c rest.Interface) *DynamicClient { + return &DynamicClient{client: c} +} + +// NewForConfigOrDie creates a new DynamicClient for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) Interface { +func NewForConfigOrDie(c *rest.Config) *DynamicClient { ret, err := NewForConfig(c) if err != nil { panic(err) @@ -63,7 +68,7 @@ func NewForConfigOrDie(c *rest.Config) Interface { // NewForConfig creates a new dynamic client or returns an error. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(inConfig *rest.Config) (Interface, error) { +func NewForConfig(inConfig *rest.Config) (*DynamicClient, error) { config := ConfigFor(inConfig) httpClient, err := rest.HTTPClientFor(config) @@ -75,7 +80,7 @@ func NewForConfig(inConfig *rest.Config) (Interface, error) { // NewForConfigAndClient creates a new dynamic client for the given config and http client. // Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (Interface, error) { +func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (*DynamicClient, error) { config := ConfigFor(inConfig) // for serializing the options config.GroupVersion = &schema.GroupVersion{} @@ -85,16 +90,16 @@ func NewForConfigAndClient(inConfig *rest.Config, h *http.Client) (Interface, er if err != nil { return nil, err } - return &dynamicClient{client: restClient}, nil + return &DynamicClient{client: restClient}, nil } type dynamicResourceClient struct { - client *dynamicClient + client *DynamicClient namespace string resource schema.GroupVersionResource } -func (c *dynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface { +func (c *DynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface { return &dynamicResourceClient{client: c, resource: resource} } @@ -120,6 +125,9 @@ func (c *dynamicResourceClient) Create(ctx context.Context, obj *unstructured.Un return nil, fmt.Errorf("name is required") } } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } result := c.client.client. Post(). @@ -152,6 +160,9 @@ func (c *dynamicResourceClient) Update(ctx context.Context, obj *unstructured.Un if len(name) == 0 { return nil, fmt.Errorf("name is required") } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) if err != nil { return nil, err @@ -188,7 +199,9 @@ func (c *dynamicResourceClient) UpdateStatus(ctx context.Context, obj *unstructu if len(name) == 0 { return nil, fmt.Errorf("name is required") } - + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) if err != nil { return nil, err @@ -220,6 +233,9 @@ func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts me if len(name) == 0 { return fmt.Errorf("name is required") } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return err + } deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts) if err != nil { return err @@ -235,6 +251,10 @@ func (c *dynamicResourceClient) Delete(ctx context.Context, name string, opts me } func (c *dynamicResourceClient) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOptions metav1.ListOptions) error { + if err := validateNamespaceWithOptionalName(c.namespace); err != nil { + return err + } + deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), &opts) if err != nil { return err @@ -254,6 +274,9 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav if len(name) == 0 { return nil, fmt.Errorf("name is required") } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } result := c.client.client.Get().AbsPath(append(c.makeURLSegments(name), subresources...)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx) if err := result.Error(); err != nil { return nil, err @@ -270,6 +293,9 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav } func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) { + if err := validateNamespaceWithOptionalName(c.namespace); err != nil { + return nil, err + } result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do(ctx) if err := result.Error(); err != nil { return nil, err @@ -295,6 +321,9 @@ func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOption func (c *dynamicResourceClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { opts.Watch = true + if err := validateNamespaceWithOptionalName(c.namespace); err != nil { + return nil, err + } return c.client.client.Get().AbsPath(c.makeURLSegments("")...). SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1). Watch(ctx) @@ -304,6 +333,9 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types if len(name) == 0 { return nil, fmt.Errorf("name is required") } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } result := c.client.client. Patch(pt). AbsPath(append(c.makeURLSegments(name), subresources...)...). @@ -324,6 +356,65 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types return uncastObj.(*unstructured.Unstructured), nil } +func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + if len(name) == 0 { + return nil, fmt.Errorf("name is required") + } + if err := validateNamespaceWithOptionalName(c.namespace, name); err != nil { + return nil, err + } + outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) + if err != nil { + return nil, err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + managedFields := accessor.GetManagedFields() + if len(managedFields) > 0 { + return nil, fmt.Errorf(`cannot apply an object with managed fields already set. + Use the client-go/applyconfigurations "UnstructructuredExtractor" to obtain the unstructured ApplyConfiguration for the given field manager that you can use/modify here to apply`) + } + patchOpts := opts.ToPatchOptions() + + result := c.client.client. + Patch(types.ApplyPatchType). + AbsPath(append(c.makeURLSegments(name), subresources...)...). + Body(outBytes). + SpecificallyVersionedParams(&patchOpts, dynamicParameterCodec, versionV1). + Do(ctx) + if err := result.Error(); err != nil { + return nil, err + } + retBytes, err := result.Raw() + if err != nil { + return nil, err + } + uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes) + if err != nil { + return nil, err + } + return uncastObj.(*unstructured.Unstructured), nil +} +func (c *dynamicResourceClient) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions) (*unstructured.Unstructured, error) { + return c.Apply(ctx, name, obj, opts, "status") +} + +func validateNamespaceWithOptionalName(namespace string, name ...string) error { + if msgs := rest.IsValidPathSegmentName(namespace); len(msgs) != 0 { + return fmt.Errorf("invalid namespace %q: %v", namespace, msgs) + } + if len(name) > 1 { + panic("Invalid number of names") + } else if len(name) == 1 { + if msgs := rest.IsValidPathSegmentName(name[0]); len(msgs) != 0 { + return fmt.Errorf("invalid resource name %q: %v", name[0], msgs) + } + } + return nil +} + func (c *dynamicResourceClient) makeURLSegments(name string) []string { url := []string{} if len(c.resource.Group) == 0 { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/interface.go b/vendor/k8s.io/client-go/informers/admissionregistration/interface.go new file mode 100644 index 00000000000..7cd8d72766a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package admissionregistration + +import ( + v1 "k8s.io/client-go/informers/admissionregistration/v1" + v1alpha1 "k8s.io/client-go/informers/admissionregistration/v1alpha1" + v1beta1 "k8s.io/client-go/informers/admissionregistration/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go new file mode 100644 index 00000000000..1ecae9ecf70 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. + MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer + // ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. + ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. +func (v *version) MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer { + return &mutatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. +func (v *version) ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer { + return &validatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go new file mode 100644 index 00000000000..b768f6f7f39 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/admissionregistration/v1" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingWebhookConfigurationInformer provides access to a shared informer and lister for +// MutatingWebhookConfigurations. +type MutatingWebhookConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.MutatingWebhookConfigurationLister +} + +type mutatingWebhookConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1.MutatingWebhookConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *mutatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1.MutatingWebhookConfiguration{}, f.defaultInformer) +} + +func (f *mutatingWebhookConfigurationInformer) Lister() v1.MutatingWebhookConfigurationLister { + return v1.NewMutatingWebhookConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go new file mode 100644 index 00000000000..8ddcdf2d905 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/admissionregistration/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ValidatingWebhookConfigurationInformer provides access to a shared informer and lister for +// ValidatingWebhookConfigurations. +type ValidatingWebhookConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ValidatingWebhookConfigurationLister +} + +type validatingWebhookConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1.ValidatingWebhookConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *validatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1.ValidatingWebhookConfiguration{}, f.defaultInformer) +} + +func (f *validatingWebhookConfigurationInformer) Lister() v1.ValidatingWebhookConfigurationLister { + return v1.NewValidatingWebhookConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/interface.go new file mode 100644 index 00000000000..738063ee72e --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ValidatingAdmissionPolicies returns a ValidatingAdmissionPolicyInformer. + ValidatingAdmissionPolicies() ValidatingAdmissionPolicyInformer + // ValidatingAdmissionPolicyBindings returns a ValidatingAdmissionPolicyBindingInformer. + ValidatingAdmissionPolicyBindings() ValidatingAdmissionPolicyBindingInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ValidatingAdmissionPolicies returns a ValidatingAdmissionPolicyInformer. +func (v *version) ValidatingAdmissionPolicies() ValidatingAdmissionPolicyInformer { + return &validatingAdmissionPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ValidatingAdmissionPolicyBindings returns a ValidatingAdmissionPolicyBindingInformer. +func (v *version) ValidatingAdmissionPolicyBindings() ValidatingAdmissionPolicyBindingInformer { + return &validatingAdmissionPolicyBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go new file mode 100644 index 00000000000..01b8a4ab8e3 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/admissionregistration/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ValidatingAdmissionPolicyInformer provides access to a shared informer and lister for +// ValidatingAdmissionPolicies. +type ValidatingAdmissionPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ValidatingAdmissionPolicyLister +} + +type validatingAdmissionPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewValidatingAdmissionPolicyInformer constructs a new informer for ValidatingAdmissionPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredValidatingAdmissionPolicyInformer constructs a new informer for ValidatingAdmissionPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *validatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *validatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1alpha1.ValidatingAdmissionPolicy{}, f.defaultInformer) +} + +func (f *validatingAdmissionPolicyInformer) Lister() v1alpha1.ValidatingAdmissionPolicyLister { + return v1alpha1.NewValidatingAdmissionPolicyLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go new file mode 100644 index 00000000000..bd531512b60 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/admissionregistration/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ValidatingAdmissionPolicyBindingInformer provides access to a shared informer and lister for +// ValidatingAdmissionPolicyBindings. +type ValidatingAdmissionPolicyBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ValidatingAdmissionPolicyBindingLister +} + +type validatingAdmissionPolicyBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewValidatingAdmissionPolicyBindingInformer constructs a new informer for ValidatingAdmissionPolicyBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredValidatingAdmissionPolicyBindingInformer constructs a new informer for ValidatingAdmissionPolicyBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *validatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *validatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}, f.defaultInformer) +} + +func (f *validatingAdmissionPolicyBindingInformer) Lister() v1alpha1.ValidatingAdmissionPolicyBindingLister { + return v1alpha1.NewValidatingAdmissionPolicyBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/interface.go new file mode 100644 index 00000000000..d1e2b61be25 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. + MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer + // ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. + ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. +func (v *version) MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer { + return &mutatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ValidatingWebhookConfigurations returns a ValidatingWebhookConfigurationInformer. +func (v *version) ValidatingWebhookConfigurations() ValidatingWebhookConfigurationInformer { + return &validatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go new file mode 100644 index 00000000000..12c8ec1fbdd --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/admissionregistration/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingWebhookConfigurationInformer provides access to a shared informer and lister for +// MutatingWebhookConfigurations. +type MutatingWebhookConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.MutatingWebhookConfigurationLister +} + +type mutatingWebhookConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1beta1.MutatingWebhookConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *mutatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1beta1.MutatingWebhookConfiguration{}, f.defaultInformer) +} + +func (f *mutatingWebhookConfigurationInformer) Lister() v1beta1.MutatingWebhookConfigurationLister { + return v1beta1.NewMutatingWebhookConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go new file mode 100644 index 00000000000..05eb05097f5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/admissionregistration/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// ValidatingWebhookConfigurationInformer provides access to a shared informer and lister for +// ValidatingWebhookConfigurations. +type ValidatingWebhookConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ValidatingWebhookConfigurationLister +} + +type validatingWebhookConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(context.TODO(), options) + }, + }, + &admissionregistrationv1beta1.ValidatingWebhookConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *validatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&admissionregistrationv1beta1.ValidatingWebhookConfiguration{}, f.defaultInformer) +} + +func (f *validatingWebhookConfigurationInformer) Lister() v1beta1.ValidatingWebhookConfigurationLister { + return v1beta1.NewValidatingWebhookConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apiserverinternal/interface.go b/vendor/k8s.io/client-go/informers/apiserverinternal/interface.go new file mode 100644 index 00000000000..122c030998d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apiserverinternal/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package apiserverinternal + +import ( + v1alpha1 "k8s.io/client-go/informers/apiserverinternal/v1alpha1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/interface.go new file mode 100644 index 00000000000..9778325c65c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // StorageVersions returns a StorageVersionInformer. + StorageVersions() StorageVersionInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// StorageVersions returns a StorageVersionInformer. +func (v *version) StorageVersions() StorageVersionInformer { + return &storageVersionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go new file mode 100644 index 00000000000..34175b522d8 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + apiserverinternalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/apiserverinternal/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// StorageVersionInformer provides access to a shared informer and lister for +// StorageVersions. +type StorageVersionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.StorageVersionLister +} + +type storageVersionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewStorageVersionInformer constructs a new informer for StorageVersion type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageVersionInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStorageVersionInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredStorageVersionInformer constructs a new informer for StorageVersion type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStorageVersionInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.InternalV1alpha1().StorageVersions().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.InternalV1alpha1().StorageVersions().Watch(context.TODO(), options) + }, + }, + &apiserverinternalv1alpha1.StorageVersion{}, + resyncPeriod, + indexers, + ) +} + +func (f *storageVersionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStorageVersionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *storageVersionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiserverinternalv1alpha1.StorageVersion{}, f.defaultInformer) +} + +func (f *storageVersionInformer) Lister() v1alpha1.StorageVersionLister { + return v1alpha1.NewStorageVersionLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/interface.go b/vendor/k8s.io/client-go/informers/apps/interface.go new file mode 100644 index 00000000000..02eefe5842e --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package apps + +import ( + v1 "k8s.io/client-go/informers/apps/v1" + v1beta1 "k8s.io/client-go/informers/apps/v1beta1" + v1beta2 "k8s.io/client-go/informers/apps/v1beta2" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface + // V1beta2 provides access to shared informers for resources in V1beta2. + V1beta2() v1beta2.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta2 returns a new v1beta2.Interface. +func (g *group) V1beta2() v1beta2.Interface { + return v1beta2.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go new file mode 100644 index 00000000000..31e2b74d0f3 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/apps/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionInformer provides access to a shared informer and lister for +// ControllerRevisions. +type ControllerRevisionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ControllerRevisionLister +} + +type controllerRevisionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ControllerRevisions(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ControllerRevisions(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.ControllerRevision{}, + resyncPeriod, + indexers, + ) +} + +func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ControllerRevision{}, f.defaultInformer) +} + +func (f *controllerRevisionInformer) Lister() v1.ControllerRevisionLister { + return v1.NewControllerRevisionLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go b/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go new file mode 100644 index 00000000000..da7fe9509b9 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/apps/v1" + cache "k8s.io/client-go/tools/cache" +) + +// DaemonSetInformer provides access to a shared informer and lister for +// DaemonSets. +type DaemonSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.DaemonSetLister +} + +type daemonSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().DaemonSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().DaemonSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.DaemonSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.DaemonSet{}, f.defaultInformer) +} + +func (f *daemonSetInformer) Lister() v1.DaemonSetLister { + return v1.NewDaemonSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1/deployment.go new file mode 100644 index 00000000000..bd639bb3d90 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/deployment.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/apps/v1" + cache "k8s.io/client-go/tools/cache" +) + +// DeploymentInformer provides access to a shared informer and lister for +// Deployments. +type DeploymentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.DeploymentLister +} + +type deploymentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Deployments(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Deployments(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.Deployment{}, + resyncPeriod, + indexers, + ) +} + +func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *deploymentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.Deployment{}, f.defaultInformer) +} + +func (f *deploymentInformer) Lister() v1.DeploymentLister { + return v1.NewDeploymentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/interface.go b/vendor/k8s.io/client-go/informers/apps/v1/interface.go new file mode 100644 index 00000000000..fab1e76bd91 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/interface.go @@ -0,0 +1,73 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ControllerRevisions returns a ControllerRevisionInformer. + ControllerRevisions() ControllerRevisionInformer + // DaemonSets returns a DaemonSetInformer. + DaemonSets() DaemonSetInformer + // Deployments returns a DeploymentInformer. + Deployments() DeploymentInformer + // ReplicaSets returns a ReplicaSetInformer. + ReplicaSets() ReplicaSetInformer + // StatefulSets returns a StatefulSetInformer. + StatefulSets() StatefulSetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ControllerRevisions returns a ControllerRevisionInformer. +func (v *version) ControllerRevisions() ControllerRevisionInformer { + return &controllerRevisionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// DaemonSets returns a DaemonSetInformer. +func (v *version) DaemonSets() DaemonSetInformer { + return &daemonSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Deployments returns a DeploymentInformer. +func (v *version) Deployments() DeploymentInformer { + return &deploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ReplicaSets returns a ReplicaSetInformer. +func (v *version) ReplicaSets() ReplicaSetInformer { + return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// StatefulSets returns a StatefulSetInformer. +func (v *version) StatefulSets() StatefulSetInformer { + return &statefulSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go b/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go new file mode 100644 index 00000000000..6d81a471a44 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/apps/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ReplicaSetInformer provides access to a shared informer and lister for +// ReplicaSets. +type ReplicaSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ReplicaSetLister +} + +type replicaSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ReplicaSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ReplicaSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.ReplicaSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ReplicaSet{}, f.defaultInformer) +} + +func (f *replicaSetInformer) Lister() v1.ReplicaSetLister { + return v1.NewReplicaSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go new file mode 100644 index 00000000000..c99bbb73ed8 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/apps/v1" + cache "k8s.io/client-go/tools/cache" +) + +// StatefulSetInformer provides access to a shared informer and lister for +// StatefulSets. +type StatefulSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.StatefulSetLister +} + +type statefulSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().StatefulSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().StatefulSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.StatefulSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.StatefulSet{}, f.defaultInformer) +} + +func (f *statefulSetInformer) Lister() v1.StatefulSetLister { + return v1.NewStatefulSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go new file mode 100644 index 00000000000..cb36bd7fd84 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + appsv1beta1 "k8s.io/api/apps/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/apps/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionInformer provides access to a shared informer and lister for +// ControllerRevisions. +type ControllerRevisionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ControllerRevisionLister +} + +type controllerRevisionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().ControllerRevisions(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().ControllerRevisions(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta1.ControllerRevision{}, + resyncPeriod, + indexers, + ) +} + +func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta1.ControllerRevision{}, f.defaultInformer) +} + +func (f *controllerRevisionInformer) Lister() v1beta1.ControllerRevisionLister { + return v1beta1.NewControllerRevisionLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go new file mode 100644 index 00000000000..e02a13c2f4c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + appsv1beta1 "k8s.io/api/apps/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/apps/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// DeploymentInformer provides access to a shared informer and lister for +// Deployments. +type DeploymentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.DeploymentLister +} + +type deploymentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().Deployments(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().Deployments(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta1.Deployment{}, + resyncPeriod, + indexers, + ) +} + +func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *deploymentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta1.Deployment{}, f.defaultInformer) +} + +func (f *deploymentInformer) Lister() v1beta1.DeploymentLister { + return v1beta1.NewDeploymentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/interface.go new file mode 100644 index 00000000000..326939cd121 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/interface.go @@ -0,0 +1,59 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ControllerRevisions returns a ControllerRevisionInformer. + ControllerRevisions() ControllerRevisionInformer + // Deployments returns a DeploymentInformer. + Deployments() DeploymentInformer + // StatefulSets returns a StatefulSetInformer. + StatefulSets() StatefulSetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ControllerRevisions returns a ControllerRevisionInformer. +func (v *version) ControllerRevisions() ControllerRevisionInformer { + return &controllerRevisionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Deployments returns a DeploymentInformer. +func (v *version) Deployments() DeploymentInformer { + return &deploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// StatefulSets returns a StatefulSetInformer. +func (v *version) StatefulSets() StatefulSetInformer { + return &statefulSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go new file mode 100644 index 00000000000..b845cc99c98 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + appsv1beta1 "k8s.io/api/apps/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/apps/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// StatefulSetInformer provides access to a shared informer and lister for +// StatefulSets. +type StatefulSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.StatefulSetLister +} + +type statefulSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().StatefulSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta1().StatefulSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta1.StatefulSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta1.StatefulSet{}, f.defaultInformer) +} + +func (f *statefulSetInformer) Lister() v1beta1.StatefulSetLister { + return v1beta1.NewStatefulSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go new file mode 100644 index 00000000000..4d0e91320b6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/apps/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionInformer provides access to a shared informer and lister for +// ControllerRevisions. +type ControllerRevisionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.ControllerRevisionLister +} + +type controllerRevisionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().ControllerRevisions(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().ControllerRevisions(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta2.ControllerRevision{}, + resyncPeriod, + indexers, + ) +} + +func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta2.ControllerRevision{}, f.defaultInformer) +} + +func (f *controllerRevisionInformer) Lister() v1beta2.ControllerRevisionLister { + return v1beta2.NewControllerRevisionLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go new file mode 100644 index 00000000000..280e2fe4656 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/apps/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// DaemonSetInformer provides access to a shared informer and lister for +// DaemonSets. +type DaemonSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.DaemonSetLister +} + +type daemonSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().DaemonSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().DaemonSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta2.DaemonSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta2.DaemonSet{}, f.defaultInformer) +} + +func (f *daemonSetInformer) Lister() v1beta2.DaemonSetLister { + return v1beta2.NewDaemonSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go new file mode 100644 index 00000000000..67bdb79720a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/apps/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// DeploymentInformer provides access to a shared informer and lister for +// Deployments. +type DeploymentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.DeploymentLister +} + +type deploymentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().Deployments(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().Deployments(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta2.Deployment{}, + resyncPeriod, + indexers, + ) +} + +func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *deploymentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta2.Deployment{}, f.defaultInformer) +} + +func (f *deploymentInformer) Lister() v1beta2.DeploymentLister { + return v1beta2.NewDeploymentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/interface.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/interface.go new file mode 100644 index 00000000000..ded89bd5bed --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/interface.go @@ -0,0 +1,73 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ControllerRevisions returns a ControllerRevisionInformer. + ControllerRevisions() ControllerRevisionInformer + // DaemonSets returns a DaemonSetInformer. + DaemonSets() DaemonSetInformer + // Deployments returns a DeploymentInformer. + Deployments() DeploymentInformer + // ReplicaSets returns a ReplicaSetInformer. + ReplicaSets() ReplicaSetInformer + // StatefulSets returns a StatefulSetInformer. + StatefulSets() StatefulSetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ControllerRevisions returns a ControllerRevisionInformer. +func (v *version) ControllerRevisions() ControllerRevisionInformer { + return &controllerRevisionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// DaemonSets returns a DaemonSetInformer. +func (v *version) DaemonSets() DaemonSetInformer { + return &daemonSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Deployments returns a DeploymentInformer. +func (v *version) Deployments() DeploymentInformer { + return &deploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ReplicaSets returns a ReplicaSetInformer. +func (v *version) ReplicaSets() ReplicaSetInformer { + return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// StatefulSets returns a StatefulSetInformer. +func (v *version) StatefulSets() StatefulSetInformer { + return &statefulSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go new file mode 100644 index 00000000000..85d12bb65da --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/apps/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// ReplicaSetInformer provides access to a shared informer and lister for +// ReplicaSets. +type ReplicaSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.ReplicaSetLister +} + +type replicaSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().ReplicaSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().ReplicaSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta2.ReplicaSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta2.ReplicaSet{}, f.defaultInformer) +} + +func (f *replicaSetInformer) Lister() v1beta2.ReplicaSetLister { + return v1beta2.NewReplicaSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go new file mode 100644 index 00000000000..2fab6f7b2bf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/apps/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// StatefulSetInformer provides access to a shared informer and lister for +// StatefulSets. +type StatefulSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.StatefulSetLister +} + +type statefulSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().StatefulSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1beta2().StatefulSets(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1beta2.StatefulSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1beta2.StatefulSet{}, f.defaultInformer) +} + +func (f *statefulSetInformer) Lister() v1beta2.StatefulSetLister { + return v1beta2.NewStatefulSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/interface.go new file mode 100644 index 00000000000..2b3b2d0e50e --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/interface.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package autoscaling + +import ( + v1 "k8s.io/client-go/informers/autoscaling/v1" + v2 "k8s.io/client-go/informers/autoscaling/v2" + v2beta1 "k8s.io/client-go/informers/autoscaling/v2beta1" + v2beta2 "k8s.io/client-go/informers/autoscaling/v2beta2" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V2 provides access to shared informers for resources in V2. + V2() v2.Interface + // V2beta1 provides access to shared informers for resources in V2beta1. + V2beta1() v2beta1.Interface + // V2beta2 provides access to shared informers for resources in V2beta2. + V2beta2() v2beta2.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V2 returns a new v2.Interface. +func (g *group) V2() v2.Interface { + return v2.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V2beta1 returns a new v2beta1.Interface. +func (g *group) V2beta1() v2beta1.Interface { + return v2beta1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V2beta2 returns a new v2beta2.Interface. +func (g *group) V2beta2() v2beta2.Interface { + return v2beta2.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go new file mode 100644 index 00000000000..44f041e906b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + autoscalingv1 "k8s.io/api/autoscaling/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/autoscaling/v1" + cache "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for +// HorizontalPodAutoscalers. +type HorizontalPodAutoscalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.HorizontalPodAutoscalerLister +} + +type horizontalPodAutoscalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(context.TODO(), options) + }, + }, + &autoscalingv1.HorizontalPodAutoscaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&autoscalingv1.HorizontalPodAutoscaler{}, f.defaultInformer) +} + +func (f *horizontalPodAutoscalerInformer) Lister() v1.HorizontalPodAutoscalerLister { + return v1.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v1/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v1/interface.go new file mode 100644 index 00000000000..601d0f77f13 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. + HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. +func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { + return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go new file mode 100644 index 00000000000..5ddb3b015f2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2 + +import ( + "context" + time "time" + + autoscalingv2 "k8s.io/api/autoscaling/v2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v2 "k8s.io/client-go/listers/autoscaling/v2" + cache "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for +// HorizontalPodAutoscalers. +type HorizontalPodAutoscalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v2.HorizontalPodAutoscalerLister +} + +type horizontalPodAutoscalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Watch(context.TODO(), options) + }, + }, + &autoscalingv2.HorizontalPodAutoscaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&autoscalingv2.HorizontalPodAutoscaler{}, f.defaultInformer) +} + +func (f *horizontalPodAutoscalerInformer) Lister() v2.HorizontalPodAutoscalerLister { + return v2.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v2/interface.go new file mode 100644 index 00000000000..2c71908e403 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. + HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. +func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { + return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go new file mode 100644 index 00000000000..6385a2a190a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2beta1 + +import ( + "context" + time "time" + + autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v2beta1 "k8s.io/client-go/listers/autoscaling/v2beta1" + cache "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for +// HorizontalPodAutoscalers. +type HorizontalPodAutoscalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v2beta1.HorizontalPodAutoscalerLister +} + +type horizontalPodAutoscalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).Watch(context.TODO(), options) + }, + }, + &autoscalingv2beta1.HorizontalPodAutoscaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&autoscalingv2beta1.HorizontalPodAutoscaler{}, f.defaultInformer) +} + +func (f *horizontalPodAutoscalerInformer) Lister() v2beta1.HorizontalPodAutoscalerLister { + return v2beta1.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go new file mode 100644 index 00000000000..ff5d44b09d6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. + HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. +func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { + return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go new file mode 100644 index 00000000000..f1ac3f0737c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2beta2 + +import ( + "context" + time "time" + + autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v2beta2 "k8s.io/client-go/listers/autoscaling/v2beta2" + cache "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for +// HorizontalPodAutoscalers. +type HorizontalPodAutoscalerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v2beta2.HorizontalPodAutoscalerLister +} + +type horizontalPodAutoscalerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Watch(context.TODO(), options) + }, + }, + &autoscalingv2beta2.HorizontalPodAutoscaler{}, + resyncPeriod, + indexers, + ) +} + +func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&autoscalingv2beta2.HorizontalPodAutoscaler{}, f.defaultInformer) +} + +func (f *horizontalPodAutoscalerInformer) Lister() v2beta2.HorizontalPodAutoscalerLister { + return v2beta2.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go new file mode 100644 index 00000000000..e482c57925f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v2beta2 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. + HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. +func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { + return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/batch/interface.go b/vendor/k8s.io/client-go/informers/batch/interface.go new file mode 100644 index 00000000000..53b81c7ecc6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/interface.go @@ -0,0 +1,54 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package batch + +import ( + v1 "k8s.io/client-go/informers/batch/v1" + v1beta1 "k8s.io/client-go/informers/batch/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go b/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go new file mode 100644 index 00000000000..fdfb655134d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + batchv1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/batch/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CronJobInformer provides access to a shared informer and lister for +// CronJobs. +type CronJobInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CronJobLister +} + +type cronJobInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCronJobInformer constructs a new informer for CronJob type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCronJobInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCronJobInformer constructs a new informer for CronJob type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1().CronJobs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1().CronJobs(namespace).Watch(context.TODO(), options) + }, + }, + &batchv1.CronJob{}, + resyncPeriod, + indexers, + ) +} + +func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cronJobInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&batchv1.CronJob{}, f.defaultInformer) +} + +func (f *cronJobInformer) Lister() v1.CronJobLister { + return v1.NewCronJobLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/batch/v1/interface.go b/vendor/k8s.io/client-go/informers/batch/v1/interface.go new file mode 100644 index 00000000000..84567fb592b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/v1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CronJobs returns a CronJobInformer. + CronJobs() CronJobInformer + // Jobs returns a JobInformer. + Jobs() JobInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CronJobs returns a CronJobInformer. +func (v *version) CronJobs() CronJobInformer { + return &cronJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Jobs returns a JobInformer. +func (v *version) Jobs() JobInformer { + return &jobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/batch/v1/job.go b/vendor/k8s.io/client-go/informers/batch/v1/job.go new file mode 100644 index 00000000000..4992f522863 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/v1/job.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + batchv1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/batch/v1" + cache "k8s.io/client-go/tools/cache" +) + +// JobInformer provides access to a shared informer and lister for +// Jobs. +type JobInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.JobLister +} + +type jobInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewJobInformer constructs a new informer for Job type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredJobInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredJobInformer constructs a new informer for Job type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1().Jobs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1().Jobs(namespace).Watch(context.TODO(), options) + }, + }, + &batchv1.Job{}, + resyncPeriod, + indexers, + ) +} + +func (f *jobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *jobInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&batchv1.Job{}, f.defaultInformer) +} + +func (f *jobInformer) Lister() v1.JobLister { + return v1.NewJobLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go b/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go new file mode 100644 index 00000000000..820c93eaaaf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + batchv1beta1 "k8s.io/api/batch/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/batch/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// CronJobInformer provides access to a shared informer and lister for +// CronJobs. +type CronJobInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.CronJobLister +} + +type cronJobInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCronJobInformer constructs a new informer for CronJob type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCronJobInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCronJobInformer constructs a new informer for CronJob type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1beta1().CronJobs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.BatchV1beta1().CronJobs(namespace).Watch(context.TODO(), options) + }, + }, + &batchv1beta1.CronJob{}, + resyncPeriod, + indexers, + ) +} + +func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cronJobInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&batchv1beta1.CronJob{}, f.defaultInformer) +} + +func (f *cronJobInformer) Lister() v1beta1.CronJobLister { + return v1beta1.NewCronJobLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/batch/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/batch/v1beta1/interface.go new file mode 100644 index 00000000000..76cae22d68f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/batch/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CronJobs returns a CronJobInformer. + CronJobs() CronJobInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CronJobs returns a CronJobInformer. +func (v *version) CronJobs() CronJobInformer { + return &cronJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/certificates/interface.go b/vendor/k8s.io/client-go/informers/certificates/interface.go new file mode 100644 index 00000000000..39a4e291113 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package certificates + +import ( + v1 "k8s.io/client-go/informers/certificates/v1" + v1alpha1 "k8s.io/client-go/informers/certificates/v1alpha1" + v1beta1 "k8s.io/client-go/informers/certificates/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go b/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go new file mode 100644 index 00000000000..73d33a914ce --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + certificatesv1 "k8s.io/api/certificates/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/certificates/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CertificateSigningRequestInformer provides access to a shared informer and lister for +// CertificateSigningRequests. +type CertificateSigningRequestInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CertificateSigningRequestLister +} + +type certificateSigningRequestInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1().CertificateSigningRequests().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1().CertificateSigningRequests().Watch(context.TODO(), options) + }, + }, + &certificatesv1.CertificateSigningRequest{}, + resyncPeriod, + indexers, + ) +} + +func (f *certificateSigningRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&certificatesv1.CertificateSigningRequest{}, f.defaultInformer) +} + +func (f *certificateSigningRequestInformer) Lister() v1.CertificateSigningRequestLister { + return v1.NewCertificateSigningRequestLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1/interface.go b/vendor/k8s.io/client-go/informers/certificates/v1/interface.go new file mode 100644 index 00000000000..91ccfb715df --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CertificateSigningRequests returns a CertificateSigningRequestInformer. + CertificateSigningRequests() CertificateSigningRequestInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CertificateSigningRequests returns a CertificateSigningRequestInformer. +func (v *version) CertificateSigningRequests() CertificateSigningRequestInformer { + return &certificateSigningRequestInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 00000000000..e8b34158702 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/certificates/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterTrustBundleInformer provides access to a shared informer and lister for +// ClusterTrustBundles. +type ClusterTrustBundleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterTrustBundleLister +} + +type clusterTrustBundleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1alpha1().ClusterTrustBundles().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(context.TODO(), options) + }, + }, + &certificatesv1alpha1.ClusterTrustBundle{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&certificatesv1alpha1.ClusterTrustBundle{}, f.defaultInformer) +} + +func (f *clusterTrustBundleInformer) Lister() v1alpha1.ClusterTrustBundleLister { + return v1alpha1.NewClusterTrustBundleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go new file mode 100644 index 00000000000..40ce8f42dbb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterTrustBundles returns a ClusterTrustBundleInformer. + ClusterTrustBundles() ClusterTrustBundleInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterTrustBundles returns a ClusterTrustBundleInformer. +func (v *version) ClusterTrustBundles() ClusterTrustBundleInformer { + return &clusterTrustBundleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go b/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go new file mode 100644 index 00000000000..4e167ab8b13 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + certificatesv1beta1 "k8s.io/api/certificates/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/certificates/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// CertificateSigningRequestInformer provides access to a shared informer and lister for +// CertificateSigningRequests. +type CertificateSigningRequestInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.CertificateSigningRequestLister +} + +type certificateSigningRequestInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1beta1().CertificateSigningRequests().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CertificatesV1beta1().CertificateSigningRequests().Watch(context.TODO(), options) + }, + }, + &certificatesv1beta1.CertificateSigningRequest{}, + resyncPeriod, + indexers, + ) +} + +func (f *certificateSigningRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&certificatesv1beta1.CertificateSigningRequest{}, f.defaultInformer) +} + +func (f *certificateSigningRequestInformer) Lister() v1beta1.CertificateSigningRequestLister { + return v1beta1.NewCertificateSigningRequestLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/certificates/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/certificates/v1beta1/interface.go new file mode 100644 index 00000000000..258dd1d0e61 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CertificateSigningRequests returns a CertificateSigningRequestInformer. + CertificateSigningRequests() CertificateSigningRequestInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CertificateSigningRequests returns a CertificateSigningRequestInformer. +func (v *version) CertificateSigningRequests() CertificateSigningRequestInformer { + return &certificateSigningRequestInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/coordination/interface.go b/vendor/k8s.io/client-go/informers/coordination/interface.go new file mode 100644 index 00000000000..54cfd7b9f26 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/coordination/interface.go @@ -0,0 +1,54 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package coordination + +import ( + v1 "k8s.io/client-go/informers/coordination/v1" + v1beta1 "k8s.io/client-go/informers/coordination/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/coordination/v1/interface.go b/vendor/k8s.io/client-go/informers/coordination/v1/interface.go new file mode 100644 index 00000000000..05c4acbef8b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/coordination/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Leases returns a LeaseInformer. + Leases() LeaseInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Leases returns a LeaseInformer. +func (v *version) Leases() LeaseInformer { + return &leaseInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/coordination/v1/lease.go b/vendor/k8s.io/client-go/informers/coordination/v1/lease.go new file mode 100644 index 00000000000..e538923a86b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/coordination/v1/lease.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + coordinationv1 "k8s.io/api/coordination/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/coordination/v1" + cache "k8s.io/client-go/tools/cache" +) + +// LeaseInformer provides access to a shared informer and lister for +// Leases. +type LeaseInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.LeaseLister +} + +type leaseInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewLeaseInformer constructs a new informer for Lease type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredLeaseInformer constructs a new informer for Lease type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoordinationV1().Leases(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoordinationV1().Leases(namespace).Watch(context.TODO(), options) + }, + }, + &coordinationv1.Lease{}, + resyncPeriod, + indexers, + ) +} + +func (f *leaseInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *leaseInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&coordinationv1.Lease{}, f.defaultInformer) +} + +func (f *leaseInformer) Lister() v1.LeaseLister { + return v1.NewLeaseLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/coordination/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/coordination/v1beta1/interface.go new file mode 100644 index 00000000000..360266206cf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/coordination/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Leases returns a LeaseInformer. + Leases() LeaseInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Leases returns a LeaseInformer. +func (v *version) Leases() LeaseInformer { + return &leaseInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go b/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go new file mode 100644 index 00000000000..5a6959c0ba9 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + coordinationv1beta1 "k8s.io/api/coordination/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/coordination/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// LeaseInformer provides access to a shared informer and lister for +// Leases. +type LeaseInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.LeaseLister +} + +type leaseInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewLeaseInformer constructs a new informer for Lease type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredLeaseInformer constructs a new informer for Lease type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoordinationV1beta1().Leases(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoordinationV1beta1().Leases(namespace).Watch(context.TODO(), options) + }, + }, + &coordinationv1beta1.Lease{}, + resyncPeriod, + indexers, + ) +} + +func (f *leaseInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *leaseInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&coordinationv1beta1.Lease{}, f.defaultInformer) +} + +func (f *leaseInformer) Lister() v1beta1.LeaseLister { + return v1beta1.NewLeaseLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/interface.go b/vendor/k8s.io/client-go/informers/core/interface.go new file mode 100644 index 00000000000..de8396b5164 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package core + +import ( + v1 "k8s.io/client-go/informers/core/v1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go b/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go new file mode 100644 index 00000000000..ccdee535bc2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ComponentStatusInformer provides access to a shared informer and lister for +// ComponentStatuses. +type ComponentStatusInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ComponentStatusLister +} + +type componentStatusInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewComponentStatusInformer constructs a new informer for ComponentStatus type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredComponentStatusInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredComponentStatusInformer constructs a new informer for ComponentStatus type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ComponentStatuses().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ComponentStatuses().Watch(context.TODO(), options) + }, + }, + &corev1.ComponentStatus{}, + resyncPeriod, + indexers, + ) +} + +func (f *componentStatusInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredComponentStatusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *componentStatusInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.ComponentStatus{}, f.defaultInformer) +} + +func (f *componentStatusInformer) Lister() v1.ComponentStatusLister { + return v1.NewComponentStatusLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/configmap.go b/vendor/k8s.io/client-go/informers/core/v1/configmap.go new file mode 100644 index 00000000000..6253581784e --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/configmap.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ConfigMapInformer provides access to a shared informer and lister for +// ConfigMaps. +type ConfigMapInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ConfigMapLister +} + +type configMapInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewConfigMapInformer constructs a new informer for ConfigMap type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConfigMapInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredConfigMapInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredConfigMapInformer constructs a new informer for ConfigMap type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredConfigMapInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ConfigMaps(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ConfigMaps(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.ConfigMap{}, + resyncPeriod, + indexers, + ) +} + +func (f *configMapInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredConfigMapInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *configMapInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.ConfigMap{}, f.defaultInformer) +} + +func (f *configMapInformer) Lister() v1.ConfigMapLister { + return v1.NewConfigMapLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/endpoints.go b/vendor/k8s.io/client-go/informers/core/v1/endpoints.go new file mode 100644 index 00000000000..cd0f25b7f70 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/endpoints.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// EndpointsInformer provides access to a shared informer and lister for +// Endpoints. +type EndpointsInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.EndpointsLister +} + +type endpointsInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEndpointsInformer constructs a new informer for Endpoints type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointsInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEndpointsInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEndpointsInformer constructs a new informer for Endpoints type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEndpointsInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Endpoints(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Endpoints(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.Endpoints{}, + resyncPeriod, + indexers, + ) +} + +func (f *endpointsInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEndpointsInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *endpointsInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Endpoints{}, f.defaultInformer) +} + +func (f *endpointsInformer) Lister() v1.EndpointsLister { + return v1.NewEndpointsLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/event.go b/vendor/k8s.io/client-go/informers/core/v1/event.go new file mode 100644 index 00000000000..8825e9b7a49 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/event.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// EventInformer provides access to a shared informer and lister for +// Events. +type EventInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.EventLister +} + +type eventInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Events(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Events(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.Event{}, + resyncPeriod, + indexers, + ) +} + +func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *eventInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Event{}, f.defaultInformer) +} + +func (f *eventInformer) Lister() v1.EventLister { + return v1.NewEventLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/interface.go b/vendor/k8s.io/client-go/informers/core/v1/interface.go new file mode 100644 index 00000000000..b2216a05c88 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/interface.go @@ -0,0 +1,150 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ComponentStatuses returns a ComponentStatusInformer. + ComponentStatuses() ComponentStatusInformer + // ConfigMaps returns a ConfigMapInformer. + ConfigMaps() ConfigMapInformer + // Endpoints returns a EndpointsInformer. + Endpoints() EndpointsInformer + // Events returns a EventInformer. + Events() EventInformer + // LimitRanges returns a LimitRangeInformer. + LimitRanges() LimitRangeInformer + // Namespaces returns a NamespaceInformer. + Namespaces() NamespaceInformer + // Nodes returns a NodeInformer. + Nodes() NodeInformer + // PersistentVolumes returns a PersistentVolumeInformer. + PersistentVolumes() PersistentVolumeInformer + // PersistentVolumeClaims returns a PersistentVolumeClaimInformer. + PersistentVolumeClaims() PersistentVolumeClaimInformer + // Pods returns a PodInformer. + Pods() PodInformer + // PodTemplates returns a PodTemplateInformer. + PodTemplates() PodTemplateInformer + // ReplicationControllers returns a ReplicationControllerInformer. + ReplicationControllers() ReplicationControllerInformer + // ResourceQuotas returns a ResourceQuotaInformer. + ResourceQuotas() ResourceQuotaInformer + // Secrets returns a SecretInformer. + Secrets() SecretInformer + // Services returns a ServiceInformer. + Services() ServiceInformer + // ServiceAccounts returns a ServiceAccountInformer. + ServiceAccounts() ServiceAccountInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ComponentStatuses returns a ComponentStatusInformer. +func (v *version) ComponentStatuses() ComponentStatusInformer { + return &componentStatusInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ConfigMaps returns a ConfigMapInformer. +func (v *version) ConfigMaps() ConfigMapInformer { + return &configMapInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Endpoints returns a EndpointsInformer. +func (v *version) Endpoints() EndpointsInformer { + return &endpointsInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Events returns a EventInformer. +func (v *version) Events() EventInformer { + return &eventInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// LimitRanges returns a LimitRangeInformer. +func (v *version) LimitRanges() LimitRangeInformer { + return &limitRangeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Namespaces returns a NamespaceInformer. +func (v *version) Namespaces() NamespaceInformer { + return &namespaceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// Nodes returns a NodeInformer. +func (v *version) Nodes() NodeInformer { + return &nodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PersistentVolumes returns a PersistentVolumeInformer. +func (v *version) PersistentVolumes() PersistentVolumeInformer { + return &persistentVolumeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PersistentVolumeClaims returns a PersistentVolumeClaimInformer. +func (v *version) PersistentVolumeClaims() PersistentVolumeClaimInformer { + return &persistentVolumeClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Pods returns a PodInformer. +func (v *version) Pods() PodInformer { + return &podInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// PodTemplates returns a PodTemplateInformer. +func (v *version) PodTemplates() PodTemplateInformer { + return &podTemplateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ReplicationControllers returns a ReplicationControllerInformer. +func (v *version) ReplicationControllers() ReplicationControllerInformer { + return &replicationControllerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ResourceQuotas returns a ResourceQuotaInformer. +func (v *version) ResourceQuotas() ResourceQuotaInformer { + return &resourceQuotaInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Secrets returns a SecretInformer. +func (v *version) Secrets() SecretInformer { + return &secretInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Services returns a ServiceInformer. +func (v *version) Services() ServiceInformer { + return &serviceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ServiceAccounts returns a ServiceAccountInformer. +func (v *version) ServiceAccounts() ServiceAccountInformer { + return &serviceAccountInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/limitrange.go b/vendor/k8s.io/client-go/informers/core/v1/limitrange.go new file mode 100644 index 00000000000..4cbfda1f7a6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/limitrange.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// LimitRangeInformer provides access to a shared informer and lister for +// LimitRanges. +type LimitRangeInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.LimitRangeLister +} + +type limitRangeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewLimitRangeInformer constructs a new informer for LimitRange type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLimitRangeInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredLimitRangeInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredLimitRangeInformer constructs a new informer for LimitRange type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredLimitRangeInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().LimitRanges(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().LimitRanges(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.LimitRange{}, + resyncPeriod, + indexers, + ) +} + +func (f *limitRangeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredLimitRangeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *limitRangeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.LimitRange{}, f.defaultInformer) +} + +func (f *limitRangeInformer) Lister() v1.LimitRangeLister { + return v1.NewLimitRangeLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/namespace.go b/vendor/k8s.io/client-go/informers/core/v1/namespace.go new file mode 100644 index 00000000000..506f930a7d5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/namespace.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// NamespaceInformer provides access to a shared informer and lister for +// Namespaces. +type NamespaceInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.NamespaceLister +} + +type namespaceInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewNamespaceInformer constructs a new informer for Namespace type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredNamespaceInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredNamespaceInformer constructs a new informer for Namespace type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Namespaces().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Namespaces().Watch(context.TODO(), options) + }, + }, + &corev1.Namespace{}, + resyncPeriod, + indexers, + ) +} + +func (f *namespaceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredNamespaceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *namespaceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Namespace{}, f.defaultInformer) +} + +func (f *namespaceInformer) Lister() v1.NamespaceLister { + return v1.NewNamespaceLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/node.go b/vendor/k8s.io/client-go/informers/core/v1/node.go new file mode 100644 index 00000000000..9939fc2cb6c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/node.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// NodeInformer provides access to a shared informer and lister for +// Nodes. +type NodeInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.NodeLister +} + +type nodeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewNodeInformer constructs a new informer for Node type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredNodeInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredNodeInformer constructs a new informer for Node type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Nodes().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Nodes().Watch(context.TODO(), options) + }, + }, + &corev1.Node{}, + resyncPeriod, + indexers, + ) +} + +func (f *nodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredNodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *nodeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Node{}, f.defaultInformer) +} + +func (f *nodeInformer) Lister() v1.NodeLister { + return v1.NewNodeLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go b/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go new file mode 100644 index 00000000000..c82445997ca --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PersistentVolumeInformer provides access to a shared informer and lister for +// PersistentVolumes. +type PersistentVolumeInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PersistentVolumeLister +} + +type persistentVolumeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPersistentVolumeInformer constructs a new informer for PersistentVolume type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPersistentVolumeInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPersistentVolumeInformer constructs a new informer for PersistentVolume type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PersistentVolumes().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PersistentVolumes().Watch(context.TODO(), options) + }, + }, + &corev1.PersistentVolume{}, + resyncPeriod, + indexers, + ) +} + +func (f *persistentVolumeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPersistentVolumeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *persistentVolumeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.PersistentVolume{}, f.defaultInformer) +} + +func (f *persistentVolumeInformer) Lister() v1.PersistentVolumeLister { + return v1.NewPersistentVolumeLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go b/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go new file mode 100644 index 00000000000..7a7df1cff81 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PersistentVolumeClaimInformer provides access to a shared informer and lister for +// PersistentVolumeClaims. +type PersistentVolumeClaimInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PersistentVolumeClaimLister +} + +type persistentVolumeClaimInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPersistentVolumeClaimInformer constructs a new informer for PersistentVolumeClaim type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPersistentVolumeClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPersistentVolumeClaimInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPersistentVolumeClaimInformer constructs a new informer for PersistentVolumeClaim type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPersistentVolumeClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PersistentVolumeClaims(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PersistentVolumeClaims(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.PersistentVolumeClaim{}, + resyncPeriod, + indexers, + ) +} + +func (f *persistentVolumeClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPersistentVolumeClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *persistentVolumeClaimInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.PersistentVolumeClaim{}, f.defaultInformer) +} + +func (f *persistentVolumeClaimInformer) Lister() v1.PersistentVolumeClaimLister { + return v1.NewPersistentVolumeClaimLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/pod.go b/vendor/k8s.io/client-go/informers/core/v1/pod.go new file mode 100644 index 00000000000..5c713a9b6f4 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/pod.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PodInformer provides access to a shared informer and lister for +// Pods. +type PodInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PodLister +} + +type podInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodInformer constructs a new informer for Pod type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodInformer constructs a new informer for Pod type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Pods(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Pods(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.Pod{}, + resyncPeriod, + indexers, + ) +} + +func (f *podInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Pod{}, f.defaultInformer) +} + +func (f *podInformer) Lister() v1.PodLister { + return v1.NewPodLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go b/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go new file mode 100644 index 00000000000..2a16e910dbe --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PodTemplateInformer provides access to a shared informer and lister for +// PodTemplates. +type PodTemplateInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PodTemplateLister +} + +type podTemplateInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodTemplateInformer constructs a new informer for PodTemplate type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodTemplateInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodTemplateInformer constructs a new informer for PodTemplate type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PodTemplates(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().PodTemplates(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.PodTemplate{}, + resyncPeriod, + indexers, + ) +} + +func (f *podTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podTemplateInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.PodTemplate{}, f.defaultInformer) +} + +func (f *podTemplateInformer) Lister() v1.PodTemplateLister { + return v1.NewPodTemplateLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go b/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go new file mode 100644 index 00000000000..930beb4cd5f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ReplicationControllerInformer provides access to a shared informer and lister for +// ReplicationControllers. +type ReplicationControllerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ReplicationControllerLister +} + +type replicationControllerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewReplicationControllerInformer constructs a new informer for ReplicationController type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicationControllerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredReplicationControllerInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredReplicationControllerInformer constructs a new informer for ReplicationController type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredReplicationControllerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ReplicationControllers(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ReplicationControllers(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.ReplicationController{}, + resyncPeriod, + indexers, + ) +} + +func (f *replicationControllerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredReplicationControllerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *replicationControllerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.ReplicationController{}, f.defaultInformer) +} + +func (f *replicationControllerInformer) Lister() v1.ReplicationControllerLister { + return v1.NewReplicationControllerLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go b/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go new file mode 100644 index 00000000000..619262a6128 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceQuotaInformer provides access to a shared informer and lister for +// ResourceQuotas. +type ResourceQuotaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ResourceQuotaLister +} + +type resourceQuotaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewResourceQuotaInformer constructs a new informer for ResourceQuota type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceQuotaInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceQuotaInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceQuotaInformer constructs a new informer for ResourceQuota type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceQuotaInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ResourceQuotas(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ResourceQuotas(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.ResourceQuota{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceQuotaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceQuotaInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceQuotaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.ResourceQuota{}, f.defaultInformer) +} + +func (f *resourceQuotaInformer) Lister() v1.ResourceQuotaLister { + return v1.NewResourceQuotaLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/secret.go b/vendor/k8s.io/client-go/informers/core/v1/secret.go new file mode 100644 index 00000000000..a6be0706930 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/secret.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// SecretInformer provides access to a shared informer and lister for +// Secrets. +type SecretInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.SecretLister +} + +type secretInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewSecretInformer constructs a new informer for Secret type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewSecretInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredSecretInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredSecretInformer constructs a new informer for Secret type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredSecretInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Secrets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Secrets(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.Secret{}, + resyncPeriod, + indexers, + ) +} + +func (f *secretInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredSecretInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *secretInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Secret{}, f.defaultInformer) +} + +func (f *secretInformer) Lister() v1.SecretLister { + return v1.NewSecretLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/service.go b/vendor/k8s.io/client-go/informers/core/v1/service.go new file mode 100644 index 00000000000..3d9ecc6e954 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/service.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ServiceInformer provides access to a shared informer and lister for +// Services. +type ServiceInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ServiceLister +} + +type serviceInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServiceInformer constructs a new informer for Service type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServiceInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServiceInformer constructs a new informer for Service type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredServiceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Services(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().Services(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.Service{}, + resyncPeriod, + indexers, + ) +} + +func (f *serviceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServiceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serviceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.Service{}, f.defaultInformer) +} + +func (f *serviceInformer) Lister() v1.ServiceLister { + return v1.NewServiceLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go b/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go new file mode 100644 index 00000000000..44371c9fa4f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ServiceAccountInformer provides access to a shared informer and lister for +// ServiceAccounts. +type ServiceAccountInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ServiceAccountLister +} + +type serviceAccountInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServiceAccountInformer constructs a new informer for ServiceAccount type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceAccountInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServiceAccountInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServiceAccountInformer constructs a new informer for ServiceAccount type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredServiceAccountInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ServiceAccounts(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CoreV1().ServiceAccounts(namespace).Watch(context.TODO(), options) + }, + }, + &corev1.ServiceAccount{}, + resyncPeriod, + indexers, + ) +} + +func (f *serviceAccountInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServiceAccountInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serviceAccountInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&corev1.ServiceAccount{}, f.defaultInformer) +} + +func (f *serviceAccountInformer) Lister() v1.ServiceAccountLister { + return v1.NewServiceAccountLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/discovery/interface.go b/vendor/k8s.io/client-go/informers/discovery/interface.go new file mode 100644 index 00000000000..37da9371f6b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/discovery/interface.go @@ -0,0 +1,54 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package discovery + +import ( + v1 "k8s.io/client-go/informers/discovery/v1" + v1beta1 "k8s.io/client-go/informers/discovery/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go b/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go new file mode 100644 index 00000000000..6c6c3372bfc --- /dev/null +++ b/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + discoveryv1 "k8s.io/api/discovery/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/discovery/v1" + cache "k8s.io/client-go/tools/cache" +) + +// EndpointSliceInformer provides access to a shared informer and lister for +// EndpointSlices. +type EndpointSliceInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.EndpointSliceLister +} + +type endpointSliceInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEndpointSliceInformer constructs a new informer for EndpointSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEndpointSliceInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEndpointSliceInformer constructs a new informer for EndpointSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.DiscoveryV1().EndpointSlices(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.DiscoveryV1().EndpointSlices(namespace).Watch(context.TODO(), options) + }, + }, + &discoveryv1.EndpointSlice{}, + resyncPeriod, + indexers, + ) +} + +func (f *endpointSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEndpointSliceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *endpointSliceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&discoveryv1.EndpointSlice{}, f.defaultInformer) +} + +func (f *endpointSliceInformer) Lister() v1.EndpointSliceLister { + return v1.NewEndpointSliceLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/discovery/v1/interface.go b/vendor/k8s.io/client-go/informers/discovery/v1/interface.go new file mode 100644 index 00000000000..d90c63c0a94 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/discovery/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // EndpointSlices returns a EndpointSliceInformer. + EndpointSlices() EndpointSliceInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// EndpointSlices returns a EndpointSliceInformer. +func (v *version) EndpointSlices() EndpointSliceInformer { + return &endpointSliceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go b/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go new file mode 100644 index 00000000000..69ae38a91a1 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + discoveryv1beta1 "k8s.io/api/discovery/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/discovery/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// EndpointSliceInformer provides access to a shared informer and lister for +// EndpointSlices. +type EndpointSliceInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.EndpointSliceLister +} + +type endpointSliceInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEndpointSliceInformer constructs a new informer for EndpointSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEndpointSliceInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEndpointSliceInformer constructs a new informer for EndpointSlice type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.DiscoveryV1beta1().EndpointSlices(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(context.TODO(), options) + }, + }, + &discoveryv1beta1.EndpointSlice{}, + resyncPeriod, + indexers, + ) +} + +func (f *endpointSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEndpointSliceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *endpointSliceInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&discoveryv1beta1.EndpointSlice{}, f.defaultInformer) +} + +func (f *endpointSliceInformer) Lister() v1beta1.EndpointSliceLister { + return v1beta1.NewEndpointSliceLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/discovery/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/discovery/v1beta1/interface.go new file mode 100644 index 00000000000..4661646e013 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/discovery/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // EndpointSlices returns a EndpointSliceInformer. + EndpointSlices() EndpointSliceInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// EndpointSlices returns a EndpointSliceInformer. +func (v *version) EndpointSlices() EndpointSliceInformer { + return &endpointSliceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/doc.go b/vendor/k8s.io/client-go/informers/doc.go new file mode 100644 index 00000000000..231bffb69bd --- /dev/null +++ b/vendor/k8s.io/client-go/informers/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package informers provides generated informers for Kubernetes APIs. +package informers diff --git a/vendor/k8s.io/client-go/informers/events/interface.go b/vendor/k8s.io/client-go/informers/events/interface.go new file mode 100644 index 00000000000..b350dde5b6c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/events/interface.go @@ -0,0 +1,54 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package events + +import ( + v1 "k8s.io/client-go/informers/events/v1" + v1beta1 "k8s.io/client-go/informers/events/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/events/v1/event.go b/vendor/k8s.io/client-go/informers/events/v1/event.go new file mode 100644 index 00000000000..f8d35ee15cc --- /dev/null +++ b/vendor/k8s.io/client-go/informers/events/v1/event.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + eventsv1 "k8s.io/api/events/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/events/v1" + cache "k8s.io/client-go/tools/cache" +) + +// EventInformer provides access to a shared informer and lister for +// Events. +type EventInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.EventLister +} + +type eventInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventsV1().Events(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventsV1().Events(namespace).Watch(context.TODO(), options) + }, + }, + &eventsv1.Event{}, + resyncPeriod, + indexers, + ) +} + +func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *eventInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&eventsv1.Event{}, f.defaultInformer) +} + +func (f *eventInformer) Lister() v1.EventLister { + return v1.NewEventLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/events/v1/interface.go b/vendor/k8s.io/client-go/informers/events/v1/interface.go new file mode 100644 index 00000000000..cd06e233593 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/events/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Events returns a EventInformer. + Events() EventInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Events returns a EventInformer. +func (v *version) Events() EventInformer { + return &eventInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/events/v1beta1/event.go b/vendor/k8s.io/client-go/informers/events/v1beta1/event.go new file mode 100644 index 00000000000..025f6a5cf36 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/events/v1beta1/event.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + eventsv1beta1 "k8s.io/api/events/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/events/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// EventInformer provides access to a shared informer and lister for +// Events. +type EventInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.EventLister +} + +type eventInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEventInformer constructs a new informer for Event type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventsV1beta1().Events(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventsV1beta1().Events(namespace).Watch(context.TODO(), options) + }, + }, + &eventsv1beta1.Event{}, + resyncPeriod, + indexers, + ) +} + +func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *eventInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&eventsv1beta1.Event{}, f.defaultInformer) +} + +func (f *eventInformer) Lister() v1beta1.EventLister { + return v1beta1.NewEventLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/events/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/events/v1beta1/interface.go new file mode 100644 index 00000000000..c71888c9a42 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/events/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Events returns a EventInformer. + Events() EventInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Events returns a EventInformer. +func (v *version) Events() EventInformer { + return &eventInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/extensions/interface.go b/vendor/k8s.io/client-go/informers/extensions/interface.go new file mode 100644 index 00000000000..94a66d3853d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package extensions + +import ( + v1beta1 "k8s.io/client-go/informers/extensions/v1beta1" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go new file mode 100644 index 00000000000..050080a5986 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// DaemonSetInformer provides access to a shared informer and lister for +// DaemonSets. +type DaemonSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.DaemonSetLister +} + +type daemonSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().DaemonSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().DaemonSets(namespace).Watch(context.TODO(), options) + }, + }, + &extensionsv1beta1.DaemonSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&extensionsv1beta1.DaemonSet{}, f.defaultInformer) +} + +func (f *daemonSetInformer) Lister() v1beta1.DaemonSetLister { + return v1beta1.NewDaemonSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go new file mode 100644 index 00000000000..1b16c5cc919 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// DeploymentInformer provides access to a shared informer and lister for +// Deployments. +type DeploymentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.DeploymentLister +} + +type deploymentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDeploymentInformer constructs a new informer for Deployment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().Deployments(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().Deployments(namespace).Watch(context.TODO(), options) + }, + }, + &extensionsv1beta1.Deployment{}, + resyncPeriod, + indexers, + ) +} + +func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *deploymentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&extensionsv1beta1.Deployment{}, f.defaultInformer) +} + +func (f *deploymentInformer) Lister() v1beta1.DeploymentLister { + return v1beta1.NewDeploymentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go new file mode 100644 index 00000000000..f01a8876174 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// IngressInformer provides access to a shared informer and lister for +// Ingresses. +type IngressInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.IngressLister +} + +type ingressInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().Ingresses(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().Ingresses(namespace).Watch(context.TODO(), options) + }, + }, + &extensionsv1beta1.Ingress{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&extensionsv1beta1.Ingress{}, f.defaultInformer) +} + +func (f *ingressInformer) Lister() v1beta1.IngressLister { + return v1beta1.NewIngressLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go new file mode 100644 index 00000000000..600741e3a27 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go @@ -0,0 +1,73 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // DaemonSets returns a DaemonSetInformer. + DaemonSets() DaemonSetInformer + // Deployments returns a DeploymentInformer. + Deployments() DeploymentInformer + // Ingresses returns a IngressInformer. + Ingresses() IngressInformer + // NetworkPolicies returns a NetworkPolicyInformer. + NetworkPolicies() NetworkPolicyInformer + // ReplicaSets returns a ReplicaSetInformer. + ReplicaSets() ReplicaSetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// DaemonSets returns a DaemonSetInformer. +func (v *version) DaemonSets() DaemonSetInformer { + return &daemonSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Deployments returns a DeploymentInformer. +func (v *version) Deployments() DeploymentInformer { + return &deploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// Ingresses returns a IngressInformer. +func (v *version) Ingresses() IngressInformer { + return &ingressInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// NetworkPolicies returns a NetworkPolicyInformer. +func (v *version) NetworkPolicies() NetworkPolicyInformer { + return &networkPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ReplicaSets returns a ReplicaSetInformer. +func (v *version) ReplicaSets() ReplicaSetInformer { + return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go new file mode 100644 index 00000000000..4a924619fb2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// NetworkPolicyInformer provides access to a shared informer and lister for +// NetworkPolicies. +type NetworkPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.NetworkPolicyLister +} + +type networkPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewNetworkPolicyInformer constructs a new informer for NetworkPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredNetworkPolicyInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredNetworkPolicyInformer constructs a new informer for NetworkPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().NetworkPolicies(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().NetworkPolicies(namespace).Watch(context.TODO(), options) + }, + }, + &extensionsv1beta1.NetworkPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *networkPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredNetworkPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *networkPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&extensionsv1beta1.NetworkPolicy{}, f.defaultInformer) +} + +func (f *networkPolicyInformer) Lister() v1beta1.NetworkPolicyLister { + return v1beta1.NewNetworkPolicyLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go new file mode 100644 index 00000000000..f7e224bcfbf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// ReplicaSetInformer provides access to a shared informer and lister for +// ReplicaSets. +type ReplicaSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ReplicaSetLister +} + +type replicaSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().ReplicaSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExtensionsV1beta1().ReplicaSets(namespace).Watch(context.TODO(), options) + }, + }, + &extensionsv1beta1.ReplicaSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&extensionsv1beta1.ReplicaSet{}, f.defaultInformer) +} + +func (f *replicaSetInformer) Lister() v1beta1.ReplicaSetLister { + return v1beta1.NewReplicaSetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/factory.go b/vendor/k8s.io/client-go/informers/factory.go new file mode 100644 index 00000000000..8e7a7e36de2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/factory.go @@ -0,0 +1,359 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package informers + +import ( + reflect "reflect" + sync "sync" + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + admissionregistration "k8s.io/client-go/informers/admissionregistration" + apiserverinternal "k8s.io/client-go/informers/apiserverinternal" + apps "k8s.io/client-go/informers/apps" + autoscaling "k8s.io/client-go/informers/autoscaling" + batch "k8s.io/client-go/informers/batch" + certificates "k8s.io/client-go/informers/certificates" + coordination "k8s.io/client-go/informers/coordination" + core "k8s.io/client-go/informers/core" + discovery "k8s.io/client-go/informers/discovery" + events "k8s.io/client-go/informers/events" + extensions "k8s.io/client-go/informers/extensions" + flowcontrol "k8s.io/client-go/informers/flowcontrol" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + networking "k8s.io/client-go/informers/networking" + node "k8s.io/client-go/informers/node" + policy "k8s.io/client-go/informers/policy" + rbac "k8s.io/client-go/informers/rbac" + resource "k8s.io/client-go/informers/resource" + scheduling "k8s.io/client-go/informers/scheduling" + storage "k8s.io/client-go/informers/storage" + kubernetes "k8s.io/client-go/kubernetes" + cache "k8s.io/client-go/tools/cache" +) + +// SharedInformerOption defines the functional option type for SharedInformerFactory. +type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory + +type sharedInformerFactory struct { + client kubernetes.Interface + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc + lock sync.Mutex + defaultResync time.Duration + customResync map[reflect.Type]time.Duration + + informers map[reflect.Type]cache.SharedIndexInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool +} + +// WithCustomResyncConfig sets a custom resync period for the specified informer types. +func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + for k, v := range resyncConfig { + factory.customResync[reflect.TypeOf(k)] = v + } + return factory + } +} + +// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. +func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.tweakListOptions = tweakListOptions + return factory + } +} + +// WithNamespace limits the SharedInformerFactory to the specified namespace. +func WithNamespace(namespace string) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.namespace = namespace + return factory + } +} + +// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. +func NewSharedInformerFactory(client kubernetes.Interface, defaultResync time.Duration) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync) +} + +// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. +// Listers obtained via this SharedInformerFactory will be subject to the same filters +// as specified here. +// Deprecated: Please use NewSharedInformerFactoryWithOptions instead +func NewFilteredSharedInformerFactory(client kubernetes.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) +} + +// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. +func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { + factory := &sharedInformerFactory{ + client: client, + namespace: v1.NamespaceAll, + defaultResync: defaultResync, + informers: make(map[reflect.Type]cache.SharedIndexInformer), + startedInformers: make(map[reflect.Type]bool), + customResync: make(map[reflect.Type]time.Duration), + } + + // Apply all options + for _, opt := range options { + factory = opt(factory) + } + + return factory +} + +func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.shuttingDown { + return + } + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() + f.startedInformers[informerType] = true + } + } +} + +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + +func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + informers := func() map[reflect.Type]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[reflect.Type]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer + } + } + return informers + }() + + res := map[reflect.Type]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +// InternalInformerFor returns the SharedIndexInformer for obj using an internal +// client. +func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informerType := reflect.TypeOf(obj) + informer, exists := f.informers[informerType] + if exists { + return informer + } + + resyncPeriod, exists := f.customResync[informerType] + if !exists { + resyncPeriod = f.defaultResync + } + + informer = newFunc(f.client, resyncPeriod) + f.informers[informerType] = informer + + return informer +} + +// SharedInformerFactory provides shared informers for resources in all known +// API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) +type SharedInformerFactory interface { + internalinterfaces.SharedInformerFactory + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. + WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + + Admissionregistration() admissionregistration.Interface + Internal() apiserverinternal.Interface + Apps() apps.Interface + Autoscaling() autoscaling.Interface + Batch() batch.Interface + Certificates() certificates.Interface + Coordination() coordination.Interface + Core() core.Interface + Discovery() discovery.Interface + Events() events.Interface + Extensions() extensions.Interface + Flowcontrol() flowcontrol.Interface + Networking() networking.Interface + Node() node.Interface + Policy() policy.Interface + Rbac() rbac.Interface + Resource() resource.Interface + Scheduling() scheduling.Interface + Storage() storage.Interface +} + +func (f *sharedInformerFactory) Admissionregistration() admissionregistration.Interface { + return admissionregistration.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Internal() apiserverinternal.Interface { + return apiserverinternal.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Apps() apps.Interface { + return apps.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Autoscaling() autoscaling.Interface { + return autoscaling.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Batch() batch.Interface { + return batch.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Certificates() certificates.Interface { + return certificates.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Coordination() coordination.Interface { + return coordination.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Core() core.Interface { + return core.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Discovery() discovery.Interface { + return discovery.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Events() events.Interface { + return events.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Extensions() extensions.Interface { + return extensions.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Flowcontrol() flowcontrol.Interface { + return flowcontrol.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Networking() networking.Interface { + return networking.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Node() node.Interface { + return node.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Policy() policy.Interface { + return policy.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Rbac() rbac.Interface { + return rbac.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Resource() resource.Interface { + return resource.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Scheduling() scheduling.Interface { + return scheduling.New(f, f.namespace, f.tweakListOptions) +} + +func (f *sharedInformerFactory) Storage() storage.Interface { + return storage.New(f, f.namespace, f.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/interface.go b/vendor/k8s.io/client-go/informers/flowcontrol/interface.go new file mode 100644 index 00000000000..1d3ca09efc9 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/interface.go @@ -0,0 +1,70 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package flowcontrol + +import ( + v1alpha1 "k8s.io/client-go/informers/flowcontrol/v1alpha1" + v1beta1 "k8s.io/client-go/informers/flowcontrol/v1beta1" + v1beta2 "k8s.io/client-go/informers/flowcontrol/v1beta2" + v1beta3 "k8s.io/client-go/informers/flowcontrol/v1beta3" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface + // V1beta2 provides access to shared informers for resources in V1beta2. + V1beta2() v1beta2.Interface + // V1beta3 provides access to shared informers for resources in V1beta3. + V1beta3() v1beta3.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta2 returns a new v1beta2.Interface. +func (g *group) V1beta2() v1beta2.Interface { + return v1beta2.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta3 returns a new v1beta3.Interface. +func (g *group) V1beta3() v1beta3.Interface { + return v1beta3.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/flowschema.go new file mode 100644 index 00000000000..9a4a904481d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/flowschema.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/flowcontrol/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// FlowSchemaInformer provides access to a shared informer and lister for +// FlowSchemas. +type FlowSchemaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.FlowSchemaLister +} + +type flowSchemaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1alpha1().FlowSchemas().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1alpha1().FlowSchemas().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1alpha1.FlowSchema{}, + resyncPeriod, + indexers, + ) +} + +func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1alpha1.FlowSchema{}, f.defaultInformer) +} + +func (f *flowSchemaInformer) Lister() v1alpha1.FlowSchemaLister { + return v1alpha1.NewFlowSchemaLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/interface.go new file mode 100644 index 00000000000..7097c0058bf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // FlowSchemas returns a FlowSchemaInformer. + FlowSchemas() FlowSchemaInformer + // PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. + PriorityLevelConfigurations() PriorityLevelConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// FlowSchemas returns a FlowSchemaInformer. +func (v *version) FlowSchemas() FlowSchemaInformer { + return &flowSchemaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. +func (v *version) PriorityLevelConfigurations() PriorityLevelConfigurationInformer { + return &priorityLevelConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/prioritylevelconfiguration.go new file mode 100644 index 00000000000..b81f5c9c36b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1alpha1/prioritylevelconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/flowcontrol/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationInformer provides access to a shared informer and lister for +// PriorityLevelConfigurations. +type PriorityLevelConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.PriorityLevelConfigurationLister +} + +type priorityLevelConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1alpha1().PriorityLevelConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1alpha1().PriorityLevelConfigurations().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1alpha1.PriorityLevelConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1alpha1.PriorityLevelConfiguration{}, f.defaultInformer) +} + +func (f *priorityLevelConfigurationInformer) Lister() v1alpha1.PriorityLevelConfigurationLister { + return v1alpha1.NewPriorityLevelConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go new file mode 100644 index 00000000000..13f4ff09339 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/flowcontrol/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// FlowSchemaInformer provides access to a shared informer and lister for +// FlowSchemas. +type FlowSchemaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.FlowSchemaLister +} + +type flowSchemaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta1().FlowSchemas().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta1().FlowSchemas().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta1.FlowSchema{}, + resyncPeriod, + indexers, + ) +} + +func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta1.FlowSchema{}, f.defaultInformer) +} + +func (f *flowSchemaInformer) Lister() v1beta1.FlowSchemaLister { + return v1beta1.NewFlowSchemaLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/interface.go new file mode 100644 index 00000000000..50329bb0ac0 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // FlowSchemas returns a FlowSchemaInformer. + FlowSchemas() FlowSchemaInformer + // PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. + PriorityLevelConfigurations() PriorityLevelConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// FlowSchemas returns a FlowSchemaInformer. +func (v *version) FlowSchemas() FlowSchemaInformer { + return &flowSchemaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. +func (v *version) PriorityLevelConfigurations() PriorityLevelConfigurationInformer { + return &priorityLevelConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go new file mode 100644 index 00000000000..fa4835906a9 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/flowcontrol/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationInformer provides access to a shared informer and lister for +// PriorityLevelConfigurations. +type PriorityLevelConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.PriorityLevelConfigurationLister +} + +type priorityLevelConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta1.PriorityLevelConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta1.PriorityLevelConfiguration{}, f.defaultInformer) +} + +func (f *priorityLevelConfigurationInformer) Lister() v1beta1.PriorityLevelConfigurationLister { + return v1beta1.NewPriorityLevelConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go new file mode 100644 index 00000000000..6f6abecea8a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/flowcontrol/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// FlowSchemaInformer provides access to a shared informer and lister for +// FlowSchemas. +type FlowSchemaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.FlowSchemaLister +} + +type flowSchemaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta2().FlowSchemas().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta2().FlowSchemas().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta2.FlowSchema{}, + resyncPeriod, + indexers, + ) +} + +func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta2.FlowSchema{}, f.defaultInformer) +} + +func (f *flowSchemaInformer) Lister() v1beta2.FlowSchemaLister { + return v1beta2.NewFlowSchemaLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/interface.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/interface.go new file mode 100644 index 00000000000..142d552896a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // FlowSchemas returns a FlowSchemaInformer. + FlowSchemas() FlowSchemaInformer + // PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. + PriorityLevelConfigurations() PriorityLevelConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// FlowSchemas returns a FlowSchemaInformer. +func (v *version) FlowSchemas() FlowSchemaInformer { + return &flowSchemaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. +func (v *version) PriorityLevelConfigurations() PriorityLevelConfigurationInformer { + return &priorityLevelConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go new file mode 100644 index 00000000000..306a9018517 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + time "time" + + flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta2 "k8s.io/client-go/listers/flowcontrol/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationInformer provides access to a shared informer and lister for +// PriorityLevelConfigurations. +type PriorityLevelConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta2.PriorityLevelConfigurationLister +} + +type priorityLevelConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta2.PriorityLevelConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta2.PriorityLevelConfiguration{}, f.defaultInformer) +} + +func (f *priorityLevelConfigurationInformer) Lister() v1beta2.PriorityLevelConfigurationLister { + return v1beta2.NewPriorityLevelConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go new file mode 100644 index 00000000000..56d8c8b1126 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta3 + +import ( + "context" + time "time" + + flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta3 "k8s.io/client-go/listers/flowcontrol/v1beta3" + cache "k8s.io/client-go/tools/cache" +) + +// FlowSchemaInformer provides access to a shared informer and lister for +// FlowSchemas. +type FlowSchemaInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta3.FlowSchemaLister +} + +type flowSchemaInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta3().FlowSchemas().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta3().FlowSchemas().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta3.FlowSchema{}, + resyncPeriod, + indexers, + ) +} + +func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta3.FlowSchema{}, f.defaultInformer) +} + +func (f *flowSchemaInformer) Lister() v1beta3.FlowSchemaLister { + return v1beta3.NewFlowSchemaLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/interface.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/interface.go new file mode 100644 index 00000000000..54c5414a2bd --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta3 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // FlowSchemas returns a FlowSchemaInformer. + FlowSchemas() FlowSchemaInformer + // PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. + PriorityLevelConfigurations() PriorityLevelConfigurationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// FlowSchemas returns a FlowSchemaInformer. +func (v *version) FlowSchemas() FlowSchemaInformer { + return &flowSchemaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer. +func (v *version) PriorityLevelConfigurations() PriorityLevelConfigurationInformer { + return &priorityLevelConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go new file mode 100644 index 00000000000..71f8d5b07f5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta3 + +import ( + "context" + time "time" + + flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta3 "k8s.io/client-go/listers/flowcontrol/v1beta3" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationInformer provides access to a shared informer and lister for +// PriorityLevelConfigurations. +type PriorityLevelConfigurationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta3.PriorityLevelConfigurationLister +} + +type priorityLevelConfigurationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().Watch(context.TODO(), options) + }, + }, + &flowcontrolv1beta3.PriorityLevelConfiguration{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&flowcontrolv1beta3.PriorityLevelConfiguration{}, f.defaultInformer) +} + +func (f *priorityLevelConfigurationInformer) Lister() v1beta3.PriorityLevelConfigurationLister { + return v1beta3.NewPriorityLevelConfigurationLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/generic.go b/vendor/k8s.io/client-go/informers/generic.go new file mode 100644 index 00000000000..2b63a8028cb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/generic.go @@ -0,0 +1,413 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package informers + +import ( + "fmt" + + v1 "k8s.io/api/admissionregistration/v1" + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1beta1 "k8s.io/api/admissionregistration/v1beta1" + apiserverinternalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" + appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + v1beta2 "k8s.io/api/apps/v1beta2" + autoscalingv1 "k8s.io/api/autoscaling/v1" + v2 "k8s.io/api/autoscaling/v2" + v2beta1 "k8s.io/api/autoscaling/v2beta1" + v2beta2 "k8s.io/api/autoscaling/v2beta2" + batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" + certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" + certificatesv1beta1 "k8s.io/api/certificates/v1beta1" + coordinationv1 "k8s.io/api/coordination/v1" + coordinationv1beta1 "k8s.io/api/coordination/v1beta1" + corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" + discoveryv1beta1 "k8s.io/api/discovery/v1beta1" + eventsv1 "k8s.io/api/events/v1" + eventsv1beta1 "k8s.io/api/events/v1beta1" + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" + flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + networkingv1 "k8s.io/api/networking/v1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" + nodev1 "k8s.io/api/node/v1" + nodev1alpha1 "k8s.io/api/node/v1alpha1" + nodev1beta1 "k8s.io/api/node/v1beta1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" + rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + v1alpha2 "k8s.io/api/resource/v1alpha2" + schedulingv1 "k8s.io/api/scheduling/v1" + schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" + storagev1 "k8s.io/api/storage/v1" + storagev1alpha1 "k8s.io/api/storage/v1alpha1" + storagev1beta1 "k8s.io/api/storage/v1beta1" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// GenericInformer is type of SharedIndexInformer which will locate and delegate to other +// sharedInformers based on type +type GenericInformer interface { + Informer() cache.SharedIndexInformer + Lister() cache.GenericLister +} + +type genericInformer struct { + informer cache.SharedIndexInformer + resource schema.GroupResource +} + +// Informer returns the SharedIndexInformer. +func (f *genericInformer) Informer() cache.SharedIndexInformer { + return f.informer +} + +// Lister returns the GenericLister. +func (f *genericInformer) Lister() cache.GenericLister { + return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) +} + +// ForResource gives generic access to a shared informer of the matching type +// TODO extend this to unknown resources with a client pool +func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { + switch resource { + // Group=admissionregistration.k8s.io, Version=v1 + case v1.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1().MutatingWebhookConfigurations().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("validatingwebhookconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1().ValidatingWebhookConfigurations().Informer()}, nil + + // Group=admissionregistration.k8s.io, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("validatingadmissionpolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("validatingadmissionpolicybindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings().Informer()}, nil + + // Group=admissionregistration.k8s.io, Version=v1beta1 + case v1beta1.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1beta1().MutatingWebhookConfigurations().Informer()}, nil + case v1beta1.SchemeGroupVersion.WithResource("validatingwebhookconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1beta1().ValidatingWebhookConfigurations().Informer()}, nil + + // Group=apps, Version=v1 + case appsv1.SchemeGroupVersion.WithResource("controllerrevisions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ControllerRevisions().Informer()}, nil + case appsv1.SchemeGroupVersion.WithResource("daemonsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().DaemonSets().Informer()}, nil + case appsv1.SchemeGroupVersion.WithResource("deployments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().Deployments().Informer()}, nil + case appsv1.SchemeGroupVersion.WithResource("replicasets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ReplicaSets().Informer()}, nil + case appsv1.SchemeGroupVersion.WithResource("statefulsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().StatefulSets().Informer()}, nil + + // Group=apps, Version=v1beta1 + case appsv1beta1.SchemeGroupVersion.WithResource("controllerrevisions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta1().ControllerRevisions().Informer()}, nil + case appsv1beta1.SchemeGroupVersion.WithResource("deployments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta1().Deployments().Informer()}, nil + case appsv1beta1.SchemeGroupVersion.WithResource("statefulsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta1().StatefulSets().Informer()}, nil + + // Group=apps, Version=v1beta2 + case v1beta2.SchemeGroupVersion.WithResource("controllerrevisions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta2().ControllerRevisions().Informer()}, nil + case v1beta2.SchemeGroupVersion.WithResource("daemonsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta2().DaemonSets().Informer()}, nil + case v1beta2.SchemeGroupVersion.WithResource("deployments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta2().Deployments().Informer()}, nil + case v1beta2.SchemeGroupVersion.WithResource("replicasets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta2().ReplicaSets().Informer()}, nil + case v1beta2.SchemeGroupVersion.WithResource("statefulsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta2().StatefulSets().Informer()}, nil + + // Group=autoscaling, Version=v1 + case autoscalingv1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V1().HorizontalPodAutoscalers().Informer()}, nil + + // Group=autoscaling, Version=v2 + case v2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2().HorizontalPodAutoscalers().Informer()}, nil + + // Group=autoscaling, Version=v2beta1 + case v2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2beta1().HorizontalPodAutoscalers().Informer()}, nil + + // Group=autoscaling, Version=v2beta2 + case v2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2beta2().HorizontalPodAutoscalers().Informer()}, nil + + // Group=batch, Version=v1 + case batchv1.SchemeGroupVersion.WithResource("cronjobs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().V1().CronJobs().Informer()}, nil + case batchv1.SchemeGroupVersion.WithResource("jobs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().V1().Jobs().Informer()}, nil + + // Group=batch, Version=v1beta1 + case batchv1beta1.SchemeGroupVersion.WithResource("cronjobs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().V1beta1().CronJobs().Informer()}, nil + + // Group=certificates.k8s.io, Version=v1 + case certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1().CertificateSigningRequests().Informer()}, nil + + // Group=certificates.k8s.io, Version=v1alpha1 + case certificatesv1alpha1.SchemeGroupVersion.WithResource("clustertrustbundles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1alpha1().ClusterTrustBundles().Informer()}, nil + + // Group=certificates.k8s.io, Version=v1beta1 + case certificatesv1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1beta1().CertificateSigningRequests().Informer()}, nil + + // Group=coordination.k8s.io, Version=v1 + case coordinationv1.SchemeGroupVersion.WithResource("leases"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Coordination().V1().Leases().Informer()}, nil + + // Group=coordination.k8s.io, Version=v1beta1 + case coordinationv1beta1.SchemeGroupVersion.WithResource("leases"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Coordination().V1beta1().Leases().Informer()}, nil + + // Group=core, Version=v1 + case corev1.SchemeGroupVersion.WithResource("componentstatuses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ComponentStatuses().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("configmaps"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ConfigMaps().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("endpoints"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Endpoints().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("events"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Events().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("limitranges"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().LimitRanges().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("namespaces"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Namespaces().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("nodes"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Nodes().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("persistentvolumes"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().PersistentVolumes().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("persistentvolumeclaims"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().PersistentVolumeClaims().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("pods"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Pods().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("podtemplates"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().PodTemplates().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("replicationcontrollers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ReplicationControllers().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("resourcequotas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ResourceQuotas().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("secrets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Secrets().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("services"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().Services().Informer()}, nil + case corev1.SchemeGroupVersion.WithResource("serviceaccounts"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ServiceAccounts().Informer()}, nil + + // Group=discovery.k8s.io, Version=v1 + case discoveryv1.SchemeGroupVersion.WithResource("endpointslices"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Discovery().V1().EndpointSlices().Informer()}, nil + + // Group=discovery.k8s.io, Version=v1beta1 + case discoveryv1beta1.SchemeGroupVersion.WithResource("endpointslices"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Discovery().V1beta1().EndpointSlices().Informer()}, nil + + // Group=events.k8s.io, Version=v1 + case eventsv1.SchemeGroupVersion.WithResource("events"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Events().V1().Events().Informer()}, nil + + // Group=events.k8s.io, Version=v1beta1 + case eventsv1beta1.SchemeGroupVersion.WithResource("events"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Events().V1beta1().Events().Informer()}, nil + + // Group=extensions, Version=v1beta1 + case extensionsv1beta1.SchemeGroupVersion.WithResource("daemonsets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().DaemonSets().Informer()}, nil + case extensionsv1beta1.SchemeGroupVersion.WithResource("deployments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().Deployments().Informer()}, nil + case extensionsv1beta1.SchemeGroupVersion.WithResource("ingresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().Ingresses().Informer()}, nil + case extensionsv1beta1.SchemeGroupVersion.WithResource("networkpolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().NetworkPolicies().Informer()}, nil + case extensionsv1beta1.SchemeGroupVersion.WithResource("replicasets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().ReplicaSets().Informer()}, nil + + // Group=flowcontrol.apiserver.k8s.io, Version=v1alpha1 + case flowcontrolv1alpha1.SchemeGroupVersion.WithResource("flowschemas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1alpha1().FlowSchemas().Informer()}, nil + case flowcontrolv1alpha1.SchemeGroupVersion.WithResource("prioritylevelconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1alpha1().PriorityLevelConfigurations().Informer()}, nil + + // Group=flowcontrol.apiserver.k8s.io, Version=v1beta1 + case flowcontrolv1beta1.SchemeGroupVersion.WithResource("flowschemas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta1().FlowSchemas().Informer()}, nil + case flowcontrolv1beta1.SchemeGroupVersion.WithResource("prioritylevelconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta1().PriorityLevelConfigurations().Informer()}, nil + + // Group=flowcontrol.apiserver.k8s.io, Version=v1beta2 + case flowcontrolv1beta2.SchemeGroupVersion.WithResource("flowschemas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta2().FlowSchemas().Informer()}, nil + case flowcontrolv1beta2.SchemeGroupVersion.WithResource("prioritylevelconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta2().PriorityLevelConfigurations().Informer()}, nil + + // Group=flowcontrol.apiserver.k8s.io, Version=v1beta3 + case v1beta3.SchemeGroupVersion.WithResource("flowschemas"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta3().FlowSchemas().Informer()}, nil + case v1beta3.SchemeGroupVersion.WithResource("prioritylevelconfigurations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1beta3().PriorityLevelConfigurations().Informer()}, nil + + // Group=internal.apiserver.k8s.io, Version=v1alpha1 + case apiserverinternalv1alpha1.SchemeGroupVersion.WithResource("storageversions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Internal().V1alpha1().StorageVersions().Informer()}, nil + + // Group=networking.k8s.io, Version=v1 + case networkingv1.SchemeGroupVersion.WithResource("ingresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1().Ingresses().Informer()}, nil + case networkingv1.SchemeGroupVersion.WithResource("ingressclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1().IngressClasses().Informer()}, nil + case networkingv1.SchemeGroupVersion.WithResource("networkpolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1().NetworkPolicies().Informer()}, nil + + // Group=networking.k8s.io, Version=v1alpha1 + case networkingv1alpha1.SchemeGroupVersion.WithResource("clustercidrs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().ClusterCIDRs().Informer()}, nil + case networkingv1alpha1.SchemeGroupVersion.WithResource("ipaddresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().IPAddresses().Informer()}, nil + + // Group=networking.k8s.io, Version=v1beta1 + case networkingv1beta1.SchemeGroupVersion.WithResource("ingresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1beta1().Ingresses().Informer()}, nil + case networkingv1beta1.SchemeGroupVersion.WithResource("ingressclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1beta1().IngressClasses().Informer()}, nil + + // Group=node.k8s.io, Version=v1 + case nodev1.SchemeGroupVersion.WithResource("runtimeclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Node().V1().RuntimeClasses().Informer()}, nil + + // Group=node.k8s.io, Version=v1alpha1 + case nodev1alpha1.SchemeGroupVersion.WithResource("runtimeclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Node().V1alpha1().RuntimeClasses().Informer()}, nil + + // Group=node.k8s.io, Version=v1beta1 + case nodev1beta1.SchemeGroupVersion.WithResource("runtimeclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Node().V1beta1().RuntimeClasses().Informer()}, nil + + // Group=policy, Version=v1 + case policyv1.SchemeGroupVersion.WithResource("poddisruptionbudgets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1().PodDisruptionBudgets().Informer()}, nil + + // Group=policy, Version=v1beta1 + case policyv1beta1.SchemeGroupVersion.WithResource("poddisruptionbudgets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1beta1().PodDisruptionBudgets().Informer()}, nil + case policyv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1beta1().PodSecurityPolicies().Informer()}, nil + + // Group=rbac.authorization.k8s.io, Version=v1 + case rbacv1.SchemeGroupVersion.WithResource("clusterroles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1().ClusterRoles().Informer()}, nil + case rbacv1.SchemeGroupVersion.WithResource("clusterrolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1().ClusterRoleBindings().Informer()}, nil + case rbacv1.SchemeGroupVersion.WithResource("roles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1().Roles().Informer()}, nil + case rbacv1.SchemeGroupVersion.WithResource("rolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1().RoleBindings().Informer()}, nil + + // Group=rbac.authorization.k8s.io, Version=v1alpha1 + case rbacv1alpha1.SchemeGroupVersion.WithResource("clusterroles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1alpha1().ClusterRoles().Informer()}, nil + case rbacv1alpha1.SchemeGroupVersion.WithResource("clusterrolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1alpha1().ClusterRoleBindings().Informer()}, nil + case rbacv1alpha1.SchemeGroupVersion.WithResource("roles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1alpha1().Roles().Informer()}, nil + case rbacv1alpha1.SchemeGroupVersion.WithResource("rolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1alpha1().RoleBindings().Informer()}, nil + + // Group=rbac.authorization.k8s.io, Version=v1beta1 + case rbacv1beta1.SchemeGroupVersion.WithResource("clusterroles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().ClusterRoles().Informer()}, nil + case rbacv1beta1.SchemeGroupVersion.WithResource("clusterrolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().ClusterRoleBindings().Informer()}, nil + case rbacv1beta1.SchemeGroupVersion.WithResource("roles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().Roles().Informer()}, nil + case rbacv1beta1.SchemeGroupVersion.WithResource("rolebindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().RoleBindings().Informer()}, nil + + // Group=resource.k8s.io, Version=v1alpha2 + case v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().PodSchedulingContexts().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaims"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaims().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaimtemplates"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaimTemplates().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClasses().Informer()}, nil + + // Group=scheduling.k8s.io, Version=v1 + case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1().PriorityClasses().Informer()}, nil + + // Group=scheduling.k8s.io, Version=v1alpha1 + case schedulingv1alpha1.SchemeGroupVersion.WithResource("priorityclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1alpha1().PriorityClasses().Informer()}, nil + + // Group=scheduling.k8s.io, Version=v1beta1 + case schedulingv1beta1.SchemeGroupVersion.WithResource("priorityclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1beta1().PriorityClasses().Informer()}, nil + + // Group=storage.k8s.io, Version=v1 + case storagev1.SchemeGroupVersion.WithResource("csidrivers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSIDrivers().Informer()}, nil + case storagev1.SchemeGroupVersion.WithResource("csinodes"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSINodes().Informer()}, nil + case storagev1.SchemeGroupVersion.WithResource("csistoragecapacities"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSIStorageCapacities().Informer()}, nil + case storagev1.SchemeGroupVersion.WithResource("storageclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().StorageClasses().Informer()}, nil + case storagev1.SchemeGroupVersion.WithResource("volumeattachments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().VolumeAttachments().Informer()}, nil + + // Group=storage.k8s.io, Version=v1alpha1 + case storagev1alpha1.SchemeGroupVersion.WithResource("csistoragecapacities"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1alpha1().CSIStorageCapacities().Informer()}, nil + case storagev1alpha1.SchemeGroupVersion.WithResource("volumeattachments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1alpha1().VolumeAttachments().Informer()}, nil + + // Group=storage.k8s.io, Version=v1beta1 + case storagev1beta1.SchemeGroupVersion.WithResource("csidrivers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1beta1().CSIDrivers().Informer()}, nil + case storagev1beta1.SchemeGroupVersion.WithResource("csinodes"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1beta1().CSINodes().Informer()}, nil + case storagev1beta1.SchemeGroupVersion.WithResource("csistoragecapacities"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1beta1().CSIStorageCapacities().Informer()}, nil + case storagev1beta1.SchemeGroupVersion.WithResource("storageclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1beta1().StorageClasses().Informer()}, nil + case storagev1beta1.SchemeGroupVersion.WithResource("volumeattachments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1beta1().VolumeAttachments().Informer()}, nil + + } + + return nil, fmt.Errorf("no informer found for %v", resource) +} diff --git a/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go b/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go new file mode 100644 index 00000000000..b00ed70cfdb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go @@ -0,0 +1,40 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package internalinterfaces + +import ( + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + kubernetes "k8s.io/client-go/kubernetes" + cache "k8s.io/client-go/tools/cache" +) + +// NewInformerFunc takes kubernetes.Interface and time.Duration to return a SharedIndexInformer. +type NewInformerFunc func(kubernetes.Interface, time.Duration) cache.SharedIndexInformer + +// SharedInformerFactory a small interface to allow for adding an informer without an import cycle +type SharedInformerFactory interface { + Start(stopCh <-chan struct{}) + InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer +} + +// TweakListOptionsFunc is a function that transforms a v1.ListOptions. +type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/vendor/k8s.io/client-go/informers/networking/interface.go b/vendor/k8s.io/client-go/informers/networking/interface.go new file mode 100644 index 00000000000..1c775c465b6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package networking + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/networking/v1" + v1alpha1 "k8s.io/client-go/informers/networking/v1alpha1" + v1beta1 "k8s.io/client-go/informers/networking/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1/ingress.go b/vendor/k8s.io/client-go/informers/networking/v1/ingress.go new file mode 100644 index 00000000000..06c317ad313 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1/ingress.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/networking/v1" + cache "k8s.io/client-go/tools/cache" +) + +// IngressInformer provides access to a shared informer and lister for +// Ingresses. +type IngressInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.IngressLister +} + +type ingressInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().Ingresses(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().Ingresses(namespace).Watch(context.TODO(), options) + }, + }, + &networkingv1.Ingress{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1.Ingress{}, f.defaultInformer) +} + +func (f *ingressInformer) Lister() v1.IngressLister { + return v1.NewIngressLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go b/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go new file mode 100644 index 00000000000..15514745bfc --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/networking/v1" + cache "k8s.io/client-go/tools/cache" +) + +// IngressClassInformer provides access to a shared informer and lister for +// IngressClasses. +type IngressClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.IngressClassLister +} + +type ingressClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewIngressClassInformer constructs a new informer for IngressClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressClassInformer constructs a new informer for IngressClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().IngressClasses().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().IngressClasses().Watch(context.TODO(), options) + }, + }, + &networkingv1.IngressClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1.IngressClass{}, f.defaultInformer) +} + +func (f *ingressClassInformer) Lister() v1.IngressClassLister { + return v1.NewIngressClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1/interface.go b/vendor/k8s.io/client-go/informers/networking/v1/interface.go new file mode 100644 index 00000000000..a48d92c4ef3 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1/interface.go @@ -0,0 +1,59 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Ingresses returns a IngressInformer. + Ingresses() IngressInformer + // IngressClasses returns a IngressClassInformer. + IngressClasses() IngressClassInformer + // NetworkPolicies returns a NetworkPolicyInformer. + NetworkPolicies() NetworkPolicyInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Ingresses returns a IngressInformer. +func (v *version) Ingresses() IngressInformer { + return &ingressInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// IngressClasses returns a IngressClassInformer. +func (v *version) IngressClasses() IngressClassInformer { + return &ingressClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// NetworkPolicies returns a NetworkPolicyInformer. +func (v *version) NetworkPolicies() NetworkPolicyInformer { + return &networkPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go b/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go new file mode 100644 index 00000000000..a75c9ac21f2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/networking/v1" + cache "k8s.io/client-go/tools/cache" +) + +// NetworkPolicyInformer provides access to a shared informer and lister for +// NetworkPolicies. +type NetworkPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.NetworkPolicyLister +} + +type networkPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewNetworkPolicyInformer constructs a new informer for NetworkPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredNetworkPolicyInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredNetworkPolicyInformer constructs a new informer for NetworkPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().NetworkPolicies(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1().NetworkPolicies(namespace).Watch(context.TODO(), options) + }, + }, + &networkingv1.NetworkPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *networkPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredNetworkPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *networkPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1.NetworkPolicy{}, f.defaultInformer) +} + +func (f *networkPolicyInformer) Lister() v1.NetworkPolicyLister { + return v1.NewNetworkPolicyLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1alpha1/clustercidr.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/clustercidr.go new file mode 100644 index 00000000000..cefd0f8a1ee --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/clustercidr.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/networking/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterCIDRInformer provides access to a shared informer and lister for +// ClusterCIDRs. +type ClusterCIDRInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterCIDRLister +} + +type clusterCIDRInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterCIDRInformer constructs a new informer for ClusterCIDR type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterCIDRInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterCIDRInformer constructs a new informer for ClusterCIDR type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1alpha1().ClusterCIDRs().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1alpha1().ClusterCIDRs().Watch(context.TODO(), options) + }, + }, + &networkingv1alpha1.ClusterCIDR{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterCIDRInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterCIDRInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterCIDRInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1alpha1.ClusterCIDR{}, f.defaultInformer) +} + +func (f *clusterCIDRInformer) Lister() v1alpha1.ClusterCIDRLister { + return v1alpha1.NewClusterCIDRLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go new file mode 100644 index 00000000000..07e7d208ca2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterCIDRs returns a ClusterCIDRInformer. + ClusterCIDRs() ClusterCIDRInformer + // IPAddresses returns a IPAddressInformer. + IPAddresses() IPAddressInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterCIDRs returns a ClusterCIDRInformer. +func (v *version) ClusterCIDRs() ClusterCIDRInformer { + return &clusterCIDRInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// IPAddresses returns a IPAddressInformer. +func (v *version) IPAddresses() IPAddressInformer { + return &iPAddressInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go new file mode 100644 index 00000000000..a1083dbf0a5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/networking/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// IPAddressInformer provides access to a shared informer and lister for +// IPAddresses. +type IPAddressInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.IPAddressLister +} + +type iPAddressInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewIPAddressInformer constructs a new informer for IPAddress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredIPAddressInformer constructs a new informer for IPAddress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1alpha1().IPAddresses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1alpha1().IPAddresses().Watch(context.TODO(), options) + }, + }, + &networkingv1alpha1.IPAddress{}, + resyncPeriod, + indexers, + ) +} + +func (f *iPAddressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *iPAddressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1alpha1.IPAddress{}, f.defaultInformer) +} + +func (f *iPAddressInformer) Lister() v1alpha1.IPAddressLister { + return v1alpha1.NewIPAddressLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go new file mode 100644 index 00000000000..8800d6c9cd8 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + networkingv1beta1 "k8s.io/api/networking/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/networking/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// IngressInformer provides access to a shared informer and lister for +// Ingresses. +type IngressInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.IngressLister +} + +type ingressInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressInformer constructs a new informer for Ingress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1beta1().Ingresses(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1beta1().Ingresses(namespace).Watch(context.TODO(), options) + }, + }, + &networkingv1beta1.Ingress{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1beta1.Ingress{}, f.defaultInformer) +} + +func (f *ingressInformer) Lister() v1beta1.IngressLister { + return v1beta1.NewIngressLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go new file mode 100644 index 00000000000..17864299bcb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + networkingv1beta1 "k8s.io/api/networking/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/networking/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// IngressClassInformer provides access to a shared informer and lister for +// IngressClasses. +type IngressClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.IngressClassLister +} + +type ingressClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewIngressClassInformer constructs a new informer for IngressClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIngressClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredIngressClassInformer constructs a new informer for IngressClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1beta1().IngressClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NetworkingV1beta1().IngressClasses().Watch(context.TODO(), options) + }, + }, + &networkingv1beta1.IngressClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *ingressClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIngressClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ingressClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1beta1.IngressClass{}, f.defaultInformer) +} + +func (f *ingressClassInformer) Lister() v1beta1.IngressClassLister { + return v1beta1.NewIngressClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/interface.go new file mode 100644 index 00000000000..2dcc3129a54 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Ingresses returns a IngressInformer. + Ingresses() IngressInformer + // IngressClasses returns a IngressClassInformer. + IngressClasses() IngressClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// Ingresses returns a IngressInformer. +func (v *version) Ingresses() IngressInformer { + return &ingressInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// IngressClasses returns a IngressClassInformer. +func (v *version) IngressClasses() IngressClassInformer { + return &ingressClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/node/interface.go b/vendor/k8s.io/client-go/informers/node/interface.go new file mode 100644 index 00000000000..61ed5af76ae --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package node + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/node/v1" + v1alpha1 "k8s.io/client-go/informers/node/v1alpha1" + v1beta1 "k8s.io/client-go/informers/node/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/node/v1/interface.go b/vendor/k8s.io/client-go/informers/node/v1/interface.go new file mode 100644 index 00000000000..913fec4acaa --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // RuntimeClasses returns a RuntimeClassInformer. + RuntimeClasses() RuntimeClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// RuntimeClasses returns a RuntimeClassInformer. +func (v *version) RuntimeClasses() RuntimeClassInformer { + return &runtimeClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go new file mode 100644 index 00000000000..293f4e2e2b6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + nodev1 "k8s.io/api/node/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/node/v1" + cache "k8s.io/client-go/tools/cache" +) + +// RuntimeClassInformer provides access to a shared informer and lister for +// RuntimeClasses. +type RuntimeClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.RuntimeClassLister +} + +type runtimeClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1().RuntimeClasses().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1().RuntimeClasses().Watch(context.TODO(), options) + }, + }, + &nodev1.RuntimeClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&nodev1.RuntimeClass{}, f.defaultInformer) +} + +func (f *runtimeClassInformer) Lister() v1.RuntimeClassLister { + return v1.NewRuntimeClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/node/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/node/v1alpha1/interface.go new file mode 100644 index 00000000000..c56442957e5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // RuntimeClasses returns a RuntimeClassInformer. + RuntimeClasses() RuntimeClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// RuntimeClasses returns a RuntimeClassInformer. +func (v *version) RuntimeClasses() RuntimeClassInformer { + return &runtimeClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go new file mode 100644 index 00000000000..d314a9573c6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + nodev1alpha1 "k8s.io/api/node/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/node/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// RuntimeClassInformer provides access to a shared informer and lister for +// RuntimeClasses. +type RuntimeClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.RuntimeClassLister +} + +type runtimeClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1alpha1().RuntimeClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1alpha1().RuntimeClasses().Watch(context.TODO(), options) + }, + }, + &nodev1alpha1.RuntimeClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&nodev1alpha1.RuntimeClass{}, f.defaultInformer) +} + +func (f *runtimeClassInformer) Lister() v1alpha1.RuntimeClassLister { + return v1alpha1.NewRuntimeClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/node/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/node/v1beta1/interface.go new file mode 100644 index 00000000000..44a1defb6b7 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // RuntimeClasses returns a RuntimeClassInformer. + RuntimeClasses() RuntimeClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// RuntimeClasses returns a RuntimeClassInformer. +func (v *version) RuntimeClasses() RuntimeClassInformer { + return &runtimeClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go new file mode 100644 index 00000000000..07619b2306f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + nodev1beta1 "k8s.io/api/node/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/node/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// RuntimeClassInformer provides access to a shared informer and lister for +// RuntimeClasses. +type RuntimeClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.RuntimeClassLister +} + +type runtimeClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1beta1().RuntimeClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.NodeV1beta1().RuntimeClasses().Watch(context.TODO(), options) + }, + }, + &nodev1beta1.RuntimeClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&nodev1beta1.RuntimeClass{}, f.defaultInformer) +} + +func (f *runtimeClassInformer) Lister() v1beta1.RuntimeClassLister { + return v1beta1.NewRuntimeClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/policy/interface.go b/vendor/k8s.io/client-go/informers/policy/interface.go new file mode 100644 index 00000000000..889cb8152c9 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/interface.go @@ -0,0 +1,54 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package policy + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/policy/v1" + v1beta1 "k8s.io/client-go/informers/policy/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/policy/v1/interface.go b/vendor/k8s.io/client-go/informers/policy/v1/interface.go new file mode 100644 index 00000000000..2c42e1993c4 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PodDisruptionBudgets returns a PodDisruptionBudgetInformer. + PodDisruptionBudgets() PodDisruptionBudgetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PodDisruptionBudgets returns a PodDisruptionBudgetInformer. +func (v *version) PodDisruptionBudgets() PodDisruptionBudgetInformer { + return &podDisruptionBudgetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go b/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go new file mode 100644 index 00000000000..436598512af --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + policyv1 "k8s.io/api/policy/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/policy/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PodDisruptionBudgetInformer provides access to a shared informer and lister for +// PodDisruptionBudgets. +type PodDisruptionBudgetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PodDisruptionBudgetLister +} + +type podDisruptionBudgetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodDisruptionBudgetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1().PodDisruptionBudgets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1().PodDisruptionBudgets(namespace).Watch(context.TODO(), options) + }, + }, + &policyv1.PodDisruptionBudget{}, + resyncPeriod, + indexers, + ) +} + +func (f *podDisruptionBudgetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodDisruptionBudgetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podDisruptionBudgetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyv1.PodDisruptionBudget{}, f.defaultInformer) +} + +func (f *podDisruptionBudgetInformer) Lister() v1.PodDisruptionBudgetLister { + return v1.NewPodDisruptionBudgetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/policy/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/policy/v1beta1/interface.go new file mode 100644 index 00000000000..a6c1825d278 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/v1beta1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PodDisruptionBudgets returns a PodDisruptionBudgetInformer. + PodDisruptionBudgets() PodDisruptionBudgetInformer + // PodSecurityPolicies returns a PodSecurityPolicyInformer. + PodSecurityPolicies() PodSecurityPolicyInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PodDisruptionBudgets returns a PodDisruptionBudgetInformer. +func (v *version) PodDisruptionBudgets() PodDisruptionBudgetInformer { + return &podDisruptionBudgetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// PodSecurityPolicies returns a PodSecurityPolicyInformer. +func (v *version) PodSecurityPolicies() PodSecurityPolicyInformer { + return &podSecurityPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go b/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go new file mode 100644 index 00000000000..4530343ecc0 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + policyv1beta1 "k8s.io/api/policy/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/policy/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// PodDisruptionBudgetInformer provides access to a shared informer and lister for +// PodDisruptionBudgets. +type PodDisruptionBudgetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.PodDisruptionBudgetLister +} + +type podDisruptionBudgetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodDisruptionBudgetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).Watch(context.TODO(), options) + }, + }, + &policyv1beta1.PodDisruptionBudget{}, + resyncPeriod, + indexers, + ) +} + +func (f *podDisruptionBudgetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodDisruptionBudgetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podDisruptionBudgetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyv1beta1.PodDisruptionBudget{}, f.defaultInformer) +} + +func (f *podDisruptionBudgetInformer) Lister() v1beta1.PodDisruptionBudgetLister { + return v1beta1.NewPodDisruptionBudgetLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/policy/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/informers/policy/v1beta1/podsecuritypolicy.go new file mode 100644 index 00000000000..b87d23434ef --- /dev/null +++ b/vendor/k8s.io/client-go/informers/policy/v1beta1/podsecuritypolicy.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + policyv1beta1 "k8s.io/api/policy/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/policy/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// PodSecurityPolicyInformer provides access to a shared informer and lister for +// PodSecurityPolicies. +type PodSecurityPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.PodSecurityPolicyLister +} + +type podSecurityPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodSecurityPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodSecurityPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1beta1().PodSecurityPolicies().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1beta1().PodSecurityPolicies().Watch(context.TODO(), options) + }, + }, + &policyv1beta1.PodSecurityPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *podSecurityPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podSecurityPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyv1beta1.PodSecurityPolicy{}, f.defaultInformer) +} + +func (f *podSecurityPolicyInformer) Lister() v1beta1.PodSecurityPolicyLister { + return v1beta1.NewPodSecurityPolicyLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/interface.go b/vendor/k8s.io/client-go/informers/rbac/interface.go new file mode 100644 index 00000000000..228811f8a2d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package rbac + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/rbac/v1" + v1alpha1 "k8s.io/client-go/informers/rbac/v1alpha1" + v1beta1 "k8s.io/client-go/informers/rbac/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go new file mode 100644 index 00000000000..0572be264bb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/rbac/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleInformer provides access to a shared informer and lister for +// ClusterRoles. +type ClusterRoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ClusterRoleLister +} + +type clusterRoleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().ClusterRoles().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().ClusterRoles().Watch(context.TODO(), options) + }, + }, + &rbacv1.ClusterRole{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1.ClusterRole{}, f.defaultInformer) +} + +func (f *clusterRoleInformer) Lister() v1.ClusterRoleLister { + return v1.NewClusterRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go new file mode 100644 index 00000000000..51026c05580 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/rbac/v1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingInformer provides access to a shared informer and lister for +// ClusterRoleBindings. +type ClusterRoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ClusterRoleBindingLister +} + +type clusterRoleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().ClusterRoleBindings().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().ClusterRoleBindings().Watch(context.TODO(), options) + }, + }, + &rbacv1.ClusterRoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1.ClusterRoleBinding{}, f.defaultInformer) +} + +func (f *clusterRoleBindingInformer) Lister() v1.ClusterRoleBindingLister { + return v1.NewClusterRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/interface.go b/vendor/k8s.io/client-go/informers/rbac/v1/interface.go new file mode 100644 index 00000000000..7f99c9454bb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1/interface.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterRoles returns a ClusterRoleInformer. + ClusterRoles() ClusterRoleInformer + // ClusterRoleBindings returns a ClusterRoleBindingInformer. + ClusterRoleBindings() ClusterRoleBindingInformer + // Roles returns a RoleInformer. + Roles() RoleInformer + // RoleBindings returns a RoleBindingInformer. + RoleBindings() RoleBindingInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterRoles returns a ClusterRoleInformer. +func (v *version) ClusterRoles() ClusterRoleInformer { + return &clusterRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ClusterRoleBindings returns a ClusterRoleBindingInformer. +func (v *version) ClusterRoleBindings() ClusterRoleBindingInformer { + return &clusterRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// Roles returns a RoleInformer. +func (v *version) Roles() RoleInformer { + return &roleInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// RoleBindings returns a RoleBindingInformer. +func (v *version) RoleBindings() RoleBindingInformer { + return &roleBindingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1/role.go new file mode 100644 index 00000000000..986a5f29f4a --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1/role.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/rbac/v1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleInformer provides access to a shared informer and lister for +// Roles. +type RoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.RoleLister +} + +type roleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().Roles(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().Roles(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1.Role{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1.Role{}, f.defaultInformer) +} + +func (f *roleInformer) Lister() v1.RoleLister { + return v1.NewRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go new file mode 100644 index 00000000000..0264049fb0e --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/rbac/v1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleBindingInformer provides access to a shared informer and lister for +// RoleBindings. +type RoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.RoleBindingLister +} + +type roleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().RoleBindings(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1().RoleBindings(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1.RoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1.RoleBinding{}, f.defaultInformer) +} + +func (f *roleBindingInformer) Lister() v1.RoleBindingLister { + return v1.NewRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go new file mode 100644 index 00000000000..70d9885f0a0 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/rbac/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleInformer provides access to a shared informer and lister for +// ClusterRoles. +type ClusterRoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterRoleLister +} + +type clusterRoleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().ClusterRoles().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().ClusterRoles().Watch(context.TODO(), options) + }, + }, + &rbacv1alpha1.ClusterRole{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1alpha1.ClusterRole{}, f.defaultInformer) +} + +func (f *clusterRoleInformer) Lister() v1alpha1.ClusterRoleLister { + return v1alpha1.NewClusterRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go new file mode 100644 index 00000000000..8c18f679284 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/rbac/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingInformer provides access to a shared informer and lister for +// ClusterRoleBindings. +type ClusterRoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterRoleBindingLister +} + +type clusterRoleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().ClusterRoleBindings().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().ClusterRoleBindings().Watch(context.TODO(), options) + }, + }, + &rbacv1alpha1.ClusterRoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1alpha1.ClusterRoleBinding{}, f.defaultInformer) +} + +func (f *clusterRoleBindingInformer) Lister() v1alpha1.ClusterRoleBindingLister { + return v1alpha1.NewClusterRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/interface.go new file mode 100644 index 00000000000..d27c79987fa --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/interface.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterRoles returns a ClusterRoleInformer. + ClusterRoles() ClusterRoleInformer + // ClusterRoleBindings returns a ClusterRoleBindingInformer. + ClusterRoleBindings() ClusterRoleBindingInformer + // Roles returns a RoleInformer. + Roles() RoleInformer + // RoleBindings returns a RoleBindingInformer. + RoleBindings() RoleBindingInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterRoles returns a ClusterRoleInformer. +func (v *version) ClusterRoles() ClusterRoleInformer { + return &clusterRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ClusterRoleBindings returns a ClusterRoleBindingInformer. +func (v *version) ClusterRoleBindings() ClusterRoleBindingInformer { + return &clusterRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// Roles returns a RoleInformer. +func (v *version) Roles() RoleInformer { + return &roleInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// RoleBindings returns a RoleBindingInformer. +func (v *version) RoleBindings() RoleBindingInformer { + return &roleBindingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go new file mode 100644 index 00000000000..7dc4551d927 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/rbac/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleInformer provides access to a shared informer and lister for +// Roles. +type RoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.RoleLister +} + +type roleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().Roles(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().Roles(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1alpha1.Role{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1alpha1.Role{}, f.defaultInformer) +} + +func (f *roleInformer) Lister() v1alpha1.RoleLister { + return v1alpha1.NewRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go new file mode 100644 index 00000000000..d49ec8b362b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/rbac/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleBindingInformer provides access to a shared informer and lister for +// RoleBindings. +type RoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.RoleBindingLister +} + +type roleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().RoleBindings(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1alpha1().RoleBindings(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1alpha1.RoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1alpha1.RoleBinding{}, f.defaultInformer) +} + +func (f *roleBindingInformer) Lister() v1alpha1.RoleBindingLister { + return v1alpha1.NewRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go new file mode 100644 index 00000000000..e50e1d39354 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/rbac/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleInformer provides access to a shared informer and lister for +// ClusterRoles. +type ClusterRoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ClusterRoleLister +} + +type clusterRoleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().ClusterRoles().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().ClusterRoles().Watch(context.TODO(), options) + }, + }, + &rbacv1beta1.ClusterRole{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1beta1.ClusterRole{}, f.defaultInformer) +} + +func (f *clusterRoleInformer) Lister() v1beta1.ClusterRoleLister { + return v1beta1.NewClusterRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go new file mode 100644 index 00000000000..a7ea4cd38d5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/rbac/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingInformer provides access to a shared informer and lister for +// ClusterRoleBindings. +type ClusterRoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ClusterRoleBindingLister +} + +type clusterRoleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().ClusterRoleBindings().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().ClusterRoleBindings().Watch(context.TODO(), options) + }, + }, + &rbacv1beta1.ClusterRoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1beta1.ClusterRoleBinding{}, f.defaultInformer) +} + +func (f *clusterRoleBindingInformer) Lister() v1beta1.ClusterRoleBindingLister { + return v1beta1.NewClusterRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/interface.go new file mode 100644 index 00000000000..04add43afac --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/interface.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterRoles returns a ClusterRoleInformer. + ClusterRoles() ClusterRoleInformer + // ClusterRoleBindings returns a ClusterRoleBindingInformer. + ClusterRoleBindings() ClusterRoleBindingInformer + // Roles returns a RoleInformer. + Roles() RoleInformer + // RoleBindings returns a RoleBindingInformer. + RoleBindings() RoleBindingInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterRoles returns a ClusterRoleInformer. +func (v *version) ClusterRoles() ClusterRoleInformer { + return &clusterRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ClusterRoleBindings returns a ClusterRoleBindingInformer. +func (v *version) ClusterRoleBindings() ClusterRoleBindingInformer { + return &clusterRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// Roles returns a RoleInformer. +func (v *version) Roles() RoleInformer { + return &roleInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// RoleBindings returns a RoleBindingInformer. +func (v *version) RoleBindings() RoleBindingInformer { + return &roleBindingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go new file mode 100644 index 00000000000..e56961e81e7 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/rbac/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleInformer provides access to a shared informer and lister for +// Roles. +type RoleInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.RoleLister +} + +type roleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleInformer constructs a new informer for Role type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().Roles(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().Roles(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1beta1.Role{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1beta1.Role{}, f.defaultInformer) +} + +func (f *roleInformer) Lister() v1beta1.RoleLister { + return v1beta1.NewRoleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go new file mode 100644 index 00000000000..d893882db35 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/rbac/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// RoleBindingInformer provides access to a shared informer and lister for +// RoleBindings. +type RoleBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.RoleBindingLister +} + +type roleBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().RoleBindings(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.RbacV1beta1().RoleBindings(namespace).Watch(context.TODO(), options) + }, + }, + &rbacv1beta1.RoleBinding{}, + resyncPeriod, + indexers, + ) +} + +func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&rbacv1beta1.RoleBinding{}, f.defaultInformer) +} + +func (f *roleBindingInformer) Lister() v1beta1.RoleBindingLister { + return v1beta1.NewRoleBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/interface.go b/vendor/k8s.io/client-go/informers/resource/interface.go new file mode 100644 index 00000000000..3fcce8ae9dc --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package resource + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1alpha2 "k8s.io/client-go/informers/resource/v1alpha2" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha2 provides access to shared informers for resources in V1alpha2. + V1alpha2() v1alpha2.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha2 returns a new v1alpha2.Interface. +func (g *group) V1alpha2() v1alpha2.Interface { + return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go new file mode 100644 index 00000000000..23f817c62eb --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go @@ -0,0 +1,66 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PodSchedulingContexts returns a PodSchedulingContextInformer. + PodSchedulingContexts() PodSchedulingContextInformer + // ResourceClaims returns a ResourceClaimInformer. + ResourceClaims() ResourceClaimInformer + // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. + ResourceClaimTemplates() ResourceClaimTemplateInformer + // ResourceClasses returns a ResourceClassInformer. + ResourceClasses() ResourceClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PodSchedulingContexts returns a PodSchedulingContextInformer. +func (v *version) PodSchedulingContexts() PodSchedulingContextInformer { + return &podSchedulingContextInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ResourceClaims returns a ResourceClaimInformer. +func (v *version) ResourceClaims() ResourceClaimInformer { + return &resourceClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ResourceClaimTemplates returns a ResourceClaimTemplateInformer. +func (v *version) ResourceClaimTemplates() ResourceClaimTemplateInformer { + return &resourceClaimTemplateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ResourceClasses returns a ResourceClassInformer. +func (v *version) ResourceClasses() ResourceClassInformer { + return &resourceClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 00000000000..b4aabb3761c --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextInformer provides access to a shared informer and lister for +// PodSchedulingContexts. +type PodSchedulingContextInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.PodSchedulingContextLister +} + +type podSchedulingContextInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodSchedulingContextInformer constructs a new informer for PodSchedulingContext type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodSchedulingContextInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodSchedulingContextInformer constructs a new informer for PodSchedulingContext type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodSchedulingContextInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().PodSchedulingContexts(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().PodSchedulingContexts(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.PodSchedulingContext{}, + resyncPeriod, + indexers, + ) +} + +func (f *podSchedulingContextInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podSchedulingContextInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.PodSchedulingContext{}, f.defaultInformer) +} + +func (f *podSchedulingContextInformer) Lister() v1alpha2.PodSchedulingContextLister { + return v1alpha2.NewPodSchedulingContextLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go new file mode 100644 index 00000000000..3af93689191 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceClaimInformer provides access to a shared informer and lister for +// ResourceClaims. +type ResourceClaimInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ResourceClaimLister +} + +type resourceClaimInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewResourceClaimInformer constructs a new informer for ResourceClaim type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceClaimInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceClaimInformer constructs a new informer for ResourceClaim type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaims(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaims(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.ResourceClaim{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaim{}, f.defaultInformer) +} + +func (f *resourceClaimInformer) Lister() v1alpha2.ResourceClaimLister { + return v1alpha2.NewResourceClaimLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go new file mode 100644 index 00000000000..13f4ad835cf --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceClaimTemplateInformer provides access to a shared informer and lister for +// ResourceClaimTemplates. +type ResourceClaimTemplateInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ResourceClaimTemplateLister +} + +type resourceClaimTemplateInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewResourceClaimTemplateInformer constructs a new informer for ResourceClaimTemplate type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceClaimTemplateInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceClaimTemplateInformer constructs a new informer for ResourceClaimTemplate type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.ResourceClaimTemplate{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceClaimTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaimTemplate{}, f.defaultInformer) +} + +func (f *resourceClaimTemplateInformer) Lister() v1alpha2.ResourceClaimTemplateLister { + return v1alpha2.NewResourceClaimTemplateLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go new file mode 100644 index 00000000000..cb76d78fe49 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// ResourceClassInformer provides access to a shared informer and lister for +// ResourceClasses. +type ResourceClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.ResourceClassLister +} + +type resourceClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewResourceClassInformer constructs a new informer for ResourceClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredResourceClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredResourceClassInformer constructs a new informer for ResourceClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().ResourceClasses().Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.ResourceClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *resourceClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredResourceClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *resourceClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.ResourceClass{}, f.defaultInformer) +} + +func (f *resourceClassInformer) Lister() v1alpha2.ResourceClassLister { + return v1alpha2.NewResourceClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/interface.go b/vendor/k8s.io/client-go/informers/scheduling/interface.go new file mode 100644 index 00000000000..659089b531f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package scheduling + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/scheduling/v1" + v1alpha1 "k8s.io/client-go/informers/scheduling/v1alpha1" + v1beta1 "k8s.io/client-go/informers/scheduling/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1/interface.go b/vendor/k8s.io/client-go/informers/scheduling/v1/interface.go new file mode 100644 index 00000000000..fd7931f34ab --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PriorityClasses returns a PriorityClassInformer. + PriorityClasses() PriorityClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PriorityClasses returns a PriorityClassInformer. +func (v *version) PriorityClasses() PriorityClassInformer { + return &priorityClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go new file mode 100644 index 00000000000..730616b4a52 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + schedulingv1 "k8s.io/api/scheduling/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/scheduling/v1" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityClassInformer provides access to a shared informer and lister for +// PriorityClasses. +type PriorityClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.PriorityClassLister +} + +type priorityClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1().PriorityClasses().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1().PriorityClasses().Watch(context.TODO(), options) + }, + }, + &schedulingv1.PriorityClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulingv1.PriorityClass{}, f.defaultInformer) +} + +func (f *priorityClassInformer) Lister() v1.PriorityClassLister { + return v1.NewPriorityClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go new file mode 100644 index 00000000000..cd908d14e6f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PriorityClasses returns a PriorityClassInformer. + PriorityClasses() PriorityClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PriorityClasses returns a PriorityClassInformer. +func (v *version) PriorityClasses() PriorityClassInformer { + return &priorityClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go new file mode 100644 index 00000000000..f82b6643690 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/scheduling/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityClassInformer provides access to a shared informer and lister for +// PriorityClasses. +type PriorityClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.PriorityClassLister +} + +type priorityClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1alpha1().PriorityClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1alpha1().PriorityClasses().Watch(context.TODO(), options) + }, + }, + &schedulingv1alpha1.PriorityClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulingv1alpha1.PriorityClass{}, f.defaultInformer) +} + +func (f *priorityClassInformer) Lister() v1alpha1.PriorityClassLister { + return v1alpha1.NewPriorityClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/interface.go new file mode 100644 index 00000000000..52840a9cee2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // PriorityClasses returns a PriorityClassInformer. + PriorityClasses() PriorityClassInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// PriorityClasses returns a PriorityClassInformer. +func (v *version) PriorityClasses() PriorityClassInformer { + return &priorityClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go new file mode 100644 index 00000000000..fc7848891ee --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/scheduling/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// PriorityClassInformer provides access to a shared informer and lister for +// PriorityClasses. +type PriorityClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.PriorityClassLister +} + +type priorityClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1beta1().PriorityClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulingV1beta1().PriorityClasses().Watch(context.TODO(), options) + }, + }, + &schedulingv1beta1.PriorityClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulingv1beta1.PriorityClass{}, f.defaultInformer) +} + +func (f *priorityClassInformer) Lister() v1beta1.PriorityClassLister { + return v1beta1.NewPriorityClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/interface.go b/vendor/k8s.io/client-go/informers/storage/interface.go new file mode 100644 index 00000000000..8245aa60c99 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/interface.go @@ -0,0 +1,62 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package storage + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + v1 "k8s.io/client-go/informers/storage/v1" + v1alpha1 "k8s.io/client-go/informers/storage/v1alpha1" + v1beta1 "k8s.io/client-go/informers/storage/v1beta1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go b/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go new file mode 100644 index 00000000000..6fd1e678d95 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIDriverInformer provides access to a shared informer and lister for +// CSIDrivers. +type CSIDriverInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CSIDriverLister +} + +type cSIDriverInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCSIDriverInformer constructs a new informer for CSIDriver type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIDriverInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIDriverInformer constructs a new informer for CSIDriver type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIDrivers().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIDrivers().Watch(context.TODO(), options) + }, + }, + &storagev1.CSIDriver{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIDriverInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIDriverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIDriverInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.CSIDriver{}, f.defaultInformer) +} + +func (f *cSIDriverInformer) Lister() v1.CSIDriverLister { + return v1.NewCSIDriverLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csinode.go b/vendor/k8s.io/client-go/informers/storage/v1/csinode.go new file mode 100644 index 00000000000..96416967fb8 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/csinode.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CSINodeInformer provides access to a shared informer and lister for +// CSINodes. +type CSINodeInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CSINodeLister +} + +type cSINodeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCSINodeInformer constructs a new informer for CSINode type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSINodeInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCSINodeInformer constructs a new informer for CSINode type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSINodes().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSINodes().Watch(context.TODO(), options) + }, + }, + &storagev1.CSINode{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSINodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSINodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSINodeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.CSINode{}, f.defaultInformer) +} + +func (f *cSINodeInformer) Lister() v1.CSINodeLister { + return v1.NewCSINodeLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go new file mode 100644 index 00000000000..9b9095f3aec --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityInformer provides access to a shared informer and lister for +// CSIStorageCapacities. +type CSIStorageCapacityInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CSIStorageCapacityLister +} + +type cSIStorageCapacityInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIStorageCapacities(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().CSIStorageCapacities(namespace).Watch(context.TODO(), options) + }, + }, + &storagev1.CSIStorageCapacity{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.CSIStorageCapacity{}, f.defaultInformer) +} + +func (f *cSIStorageCapacityInformer) Lister() v1.CSIStorageCapacityLister { + return v1.NewCSIStorageCapacityLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/interface.go b/vendor/k8s.io/client-go/informers/storage/v1/interface.go new file mode 100644 index 00000000000..4f017b0864f --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/interface.go @@ -0,0 +1,73 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CSIDrivers returns a CSIDriverInformer. + CSIDrivers() CSIDriverInformer + // CSINodes returns a CSINodeInformer. + CSINodes() CSINodeInformer + // CSIStorageCapacities returns a CSIStorageCapacityInformer. + CSIStorageCapacities() CSIStorageCapacityInformer + // StorageClasses returns a StorageClassInformer. + StorageClasses() StorageClassInformer + // VolumeAttachments returns a VolumeAttachmentInformer. + VolumeAttachments() VolumeAttachmentInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CSIDrivers returns a CSIDriverInformer. +func (v *version) CSIDrivers() CSIDriverInformer { + return &cSIDriverInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// CSINodes returns a CSINodeInformer. +func (v *version) CSINodes() CSINodeInformer { + return &cSINodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// CSIStorageCapacities returns a CSIStorageCapacityInformer. +func (v *version) CSIStorageCapacities() CSIStorageCapacityInformer { + return &cSIStorageCapacityInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// StorageClasses returns a StorageClassInformer. +func (v *version) StorageClasses() StorageClassInformer { + return &storageClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// VolumeAttachments returns a VolumeAttachmentInformer. +func (v *version) VolumeAttachments() VolumeAttachmentInformer { + return &volumeAttachmentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go b/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go new file mode 100644 index 00000000000..8cde79d9a3b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// StorageClassInformer provides access to a shared informer and lister for +// StorageClasses. +type StorageClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.StorageClassLister +} + +type storageClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewStorageClassInformer constructs a new informer for StorageClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStorageClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredStorageClassInformer constructs a new informer for StorageClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().StorageClasses().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().StorageClasses().Watch(context.TODO(), options) + }, + }, + &storagev1.StorageClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *storageClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStorageClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *storageClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.StorageClass{}, f.defaultInformer) +} + +func (f *storageClassInformer) Lister() v1.StorageClassLister { + return v1.NewStorageClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go new file mode 100644 index 00000000000..be605ff48c6 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/listers/storage/v1" + cache "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentInformer provides access to a shared informer and lister for +// VolumeAttachments. +type VolumeAttachmentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.VolumeAttachmentLister +} + +type volumeAttachmentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().VolumeAttachments().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1().VolumeAttachments().Watch(context.TODO(), options) + }, + }, + &storagev1.VolumeAttachment{}, + resyncPeriod, + indexers, + ) +} + +func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1.VolumeAttachment{}, f.defaultInformer) +} + +func (f *volumeAttachmentInformer) Lister() v1.VolumeAttachmentLister { + return v1.NewVolumeAttachmentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go new file mode 100644 index 00000000000..e59dfab2d11 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + storagev1alpha1 "k8s.io/api/storage/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/storage/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityInformer provides access to a shared informer and lister for +// CSIStorageCapacities. +type CSIStorageCapacityInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.CSIStorageCapacityLister +} + +type cSIStorageCapacityInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1alpha1().CSIStorageCapacities(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1alpha1().CSIStorageCapacities(namespace).Watch(context.TODO(), options) + }, + }, + &storagev1alpha1.CSIStorageCapacity{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1alpha1.CSIStorageCapacity{}, f.defaultInformer) +} + +func (f *cSIStorageCapacityInformer) Lister() v1alpha1.CSIStorageCapacityLister { + return v1alpha1.NewCSIStorageCapacityLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/interface.go new file mode 100644 index 00000000000..033d3b10aa1 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CSIStorageCapacities returns a CSIStorageCapacityInformer. + CSIStorageCapacities() CSIStorageCapacityInformer + // VolumeAttachments returns a VolumeAttachmentInformer. + VolumeAttachments() VolumeAttachmentInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CSIStorageCapacities returns a CSIStorageCapacityInformer. +func (v *version) CSIStorageCapacities() CSIStorageCapacityInformer { + return &cSIStorageCapacityInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// VolumeAttachments returns a VolumeAttachmentInformer. +func (v *version) VolumeAttachments() VolumeAttachmentInformer { + return &volumeAttachmentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go new file mode 100644 index 00000000000..445496dade4 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + storagev1alpha1 "k8s.io/api/storage/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha1 "k8s.io/client-go/listers/storage/v1alpha1" + cache "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentInformer provides access to a shared informer and lister for +// VolumeAttachments. +type VolumeAttachmentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.VolumeAttachmentLister +} + +type volumeAttachmentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1alpha1().VolumeAttachments().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1alpha1().VolumeAttachments().Watch(context.TODO(), options) + }, + }, + &storagev1alpha1.VolumeAttachment{}, + resyncPeriod, + indexers, + ) +} + +func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1alpha1.VolumeAttachment{}, f.defaultInformer) +} + +func (f *volumeAttachmentInformer) Lister() v1alpha1.VolumeAttachmentLister { + return v1alpha1.NewVolumeAttachmentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go new file mode 100644 index 00000000000..f138a915b88 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + storagev1beta1 "k8s.io/api/storage/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/storage/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIDriverInformer provides access to a shared informer and lister for +// CSIDrivers. +type CSIDriverInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.CSIDriverLister +} + +type cSIDriverInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCSIDriverInformer constructs a new informer for CSIDriver type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIDriverInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIDriverInformer constructs a new informer for CSIDriver type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSIDrivers().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSIDrivers().Watch(context.TODO(), options) + }, + }, + &storagev1beta1.CSIDriver{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIDriverInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIDriverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIDriverInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1beta1.CSIDriver{}, f.defaultInformer) +} + +func (f *cSIDriverInformer) Lister() v1beta1.CSIDriverLister { + return v1beta1.NewCSIDriverLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go new file mode 100644 index 00000000000..6ba63172a34 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + storagev1beta1 "k8s.io/api/storage/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/storage/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// CSINodeInformer provides access to a shared informer and lister for +// CSINodes. +type CSINodeInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.CSINodeLister +} + +type cSINodeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewCSINodeInformer constructs a new informer for CSINode type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSINodeInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredCSINodeInformer constructs a new informer for CSINode type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSINodes().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSINodes().Watch(context.TODO(), options) + }, + }, + &storagev1beta1.CSINode{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSINodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSINodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSINodeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1beta1.CSINode{}, f.defaultInformer) +} + +func (f *cSINodeInformer) Lister() v1beta1.CSINodeLister { + return v1beta1.NewCSINodeLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go new file mode 100644 index 00000000000..8f0cc466879 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + storagev1beta1 "k8s.io/api/storage/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/storage/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityInformer provides access to a shared informer and lister for +// CSIStorageCapacities. +type CSIStorageCapacityInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.CSIStorageCapacityLister +} + +type cSIStorageCapacityInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSIStorageCapacities(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().CSIStorageCapacities(namespace).Watch(context.TODO(), options) + }, + }, + &storagev1beta1.CSIStorageCapacity{}, + resyncPeriod, + indexers, + ) +} + +func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1beta1.CSIStorageCapacity{}, f.defaultInformer) +} + +func (f *cSIStorageCapacityInformer) Lister() v1beta1.CSIStorageCapacityLister { + return v1beta1.NewCSIStorageCapacityLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/interface.go new file mode 100644 index 00000000000..77b77c08ee2 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/interface.go @@ -0,0 +1,73 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CSIDrivers returns a CSIDriverInformer. + CSIDrivers() CSIDriverInformer + // CSINodes returns a CSINodeInformer. + CSINodes() CSINodeInformer + // CSIStorageCapacities returns a CSIStorageCapacityInformer. + CSIStorageCapacities() CSIStorageCapacityInformer + // StorageClasses returns a StorageClassInformer. + StorageClasses() StorageClassInformer + // VolumeAttachments returns a VolumeAttachmentInformer. + VolumeAttachments() VolumeAttachmentInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CSIDrivers returns a CSIDriverInformer. +func (v *version) CSIDrivers() CSIDriverInformer { + return &cSIDriverInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// CSINodes returns a CSINodeInformer. +func (v *version) CSINodes() CSINodeInformer { + return &cSINodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// CSIStorageCapacities returns a CSIStorageCapacityInformer. +func (v *version) CSIStorageCapacities() CSIStorageCapacityInformer { + return &cSIStorageCapacityInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// StorageClasses returns a StorageClassInformer. +func (v *version) StorageClasses() StorageClassInformer { + return &storageClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// VolumeAttachments returns a VolumeAttachmentInformer. +func (v *version) VolumeAttachments() VolumeAttachmentInformer { + return &volumeAttachmentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go new file mode 100644 index 00000000000..a6582bf3d61 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + storagev1beta1 "k8s.io/api/storage/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/storage/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// StorageClassInformer provides access to a shared informer and lister for +// StorageClasses. +type StorageClassInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.StorageClassLister +} + +type storageClassInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewStorageClassInformer constructs a new informer for StorageClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStorageClassInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredStorageClassInformer constructs a new informer for StorageClass type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().StorageClasses().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().StorageClasses().Watch(context.TODO(), options) + }, + }, + &storagev1beta1.StorageClass{}, + resyncPeriod, + indexers, + ) +} + +func (f *storageClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStorageClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *storageClassInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1beta1.StorageClass{}, f.defaultInformer) +} + +func (f *storageClassInformer) Lister() v1beta1.StorageClassLister { + return v1beta1.NewStorageClassLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go new file mode 100644 index 00000000000..e8942463490 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + storagev1beta1 "k8s.io/api/storage/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1beta1 "k8s.io/client-go/listers/storage/v1beta1" + cache "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentInformer provides access to a shared informer and lister for +// VolumeAttachments. +type VolumeAttachmentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.VolumeAttachmentLister +} + +type volumeAttachmentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().VolumeAttachments().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.StorageV1beta1().VolumeAttachments().Watch(context.TODO(), options) + }, + }, + &storagev1beta1.VolumeAttachment{}, + resyncPeriod, + indexers, + ) +} + +func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&storagev1beta1.VolumeAttachment{}, f.defaultInformer) +} + +func (f *volumeAttachmentInformer) Lister() v1beta1.VolumeAttachmentLister { + return v1beta1.NewVolumeAttachmentLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/kubernetes/clientset.go b/vendor/k8s.io/client-go/kubernetes/clientset.go index e46c0537f78..6345f2fb626 100644 --- a/vendor/k8s.io/client-go/kubernetes/clientset.go +++ b/vendor/k8s.io/client-go/kubernetes/clientset.go @@ -24,12 +24,14 @@ import ( discovery "k8s.io/client-go/discovery" admissionregistrationv1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" + admissionregistrationv1alpha1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1" admissionregistrationv1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1" internalv1alpha1 "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1" appsv1 "k8s.io/client-go/kubernetes/typed/apps/v1" appsv1beta1 "k8s.io/client-go/kubernetes/typed/apps/v1beta1" appsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" authenticationv1 "k8s.io/client-go/kubernetes/typed/authentication/v1" + authenticationv1alpha1 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1" authenticationv1beta1 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1" authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" authorizationv1beta1 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1" @@ -40,6 +42,7 @@ import ( batchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" batchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" certificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1" + certificatesv1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1" coordinationv1beta1 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" @@ -52,7 +55,9 @@ import ( flowcontrolv1alpha1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1" flowcontrolv1beta1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1" flowcontrolv1beta2 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2" + flowcontrolv1beta3 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1" + networkingv1alpha1 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1" networkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1" nodev1 "k8s.io/client-go/kubernetes/typed/node/v1" nodev1alpha1 "k8s.io/client-go/kubernetes/typed/node/v1alpha1" @@ -62,6 +67,7 @@ import ( rbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" rbacv1alpha1 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" rbacv1beta1 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" + resourcev1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" @@ -75,12 +81,14 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface AdmissionregistrationV1() admissionregistrationv1.AdmissionregistrationV1Interface + AdmissionregistrationV1alpha1() admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Interface AdmissionregistrationV1beta1() admissionregistrationv1beta1.AdmissionregistrationV1beta1Interface InternalV1alpha1() internalv1alpha1.InternalV1alpha1Interface AppsV1() appsv1.AppsV1Interface AppsV1beta1() appsv1beta1.AppsV1beta1Interface AppsV1beta2() appsv1beta2.AppsV1beta2Interface AuthenticationV1() authenticationv1.AuthenticationV1Interface + AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface AuthorizationV1() authorizationv1.AuthorizationV1Interface AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface @@ -92,6 +100,7 @@ type Interface interface { BatchV1beta1() batchv1beta1.BatchV1beta1Interface CertificatesV1() certificatesv1.CertificatesV1Interface CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface + CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface CoordinationV1() coordinationv1.CoordinationV1Interface CoreV1() corev1.CoreV1Interface @@ -103,7 +112,9 @@ type Interface interface { FlowcontrolV1alpha1() flowcontrolv1alpha1.FlowcontrolV1alpha1Interface FlowcontrolV1beta1() flowcontrolv1beta1.FlowcontrolV1beta1Interface FlowcontrolV1beta2() flowcontrolv1beta2.FlowcontrolV1beta2Interface + FlowcontrolV1beta3() flowcontrolv1beta3.FlowcontrolV1beta3Interface NetworkingV1() networkingv1.NetworkingV1Interface + NetworkingV1alpha1() networkingv1alpha1.NetworkingV1alpha1Interface NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface NodeV1() nodev1.NodeV1Interface NodeV1alpha1() nodev1alpha1.NodeV1alpha1Interface @@ -113,6 +124,7 @@ type Interface interface { RbacV1() rbacv1.RbacV1Interface RbacV1beta1() rbacv1beta1.RbacV1beta1Interface RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface + ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface SchedulingV1() schedulingv1.SchedulingV1Interface @@ -121,55 +133,60 @@ type Interface interface { StorageV1alpha1() storagev1alpha1.StorageV1alpha1Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient - admissionregistrationV1 *admissionregistrationv1.AdmissionregistrationV1Client - admissionregistrationV1beta1 *admissionregistrationv1beta1.AdmissionregistrationV1beta1Client - internalV1alpha1 *internalv1alpha1.InternalV1alpha1Client - appsV1 *appsv1.AppsV1Client - appsV1beta1 *appsv1beta1.AppsV1beta1Client - appsV1beta2 *appsv1beta2.AppsV1beta2Client - authenticationV1 *authenticationv1.AuthenticationV1Client - authenticationV1beta1 *authenticationv1beta1.AuthenticationV1beta1Client - authorizationV1 *authorizationv1.AuthorizationV1Client - authorizationV1beta1 *authorizationv1beta1.AuthorizationV1beta1Client - autoscalingV1 *autoscalingv1.AutoscalingV1Client - autoscalingV2 *autoscalingv2.AutoscalingV2Client - autoscalingV2beta1 *autoscalingv2beta1.AutoscalingV2beta1Client - autoscalingV2beta2 *autoscalingv2beta2.AutoscalingV2beta2Client - batchV1 *batchv1.BatchV1Client - batchV1beta1 *batchv1beta1.BatchV1beta1Client - certificatesV1 *certificatesv1.CertificatesV1Client - certificatesV1beta1 *certificatesv1beta1.CertificatesV1beta1Client - coordinationV1beta1 *coordinationv1beta1.CoordinationV1beta1Client - coordinationV1 *coordinationv1.CoordinationV1Client - coreV1 *corev1.CoreV1Client - discoveryV1 *discoveryv1.DiscoveryV1Client - discoveryV1beta1 *discoveryv1beta1.DiscoveryV1beta1Client - eventsV1 *eventsv1.EventsV1Client - eventsV1beta1 *eventsv1beta1.EventsV1beta1Client - extensionsV1beta1 *extensionsv1beta1.ExtensionsV1beta1Client - flowcontrolV1alpha1 *flowcontrolv1alpha1.FlowcontrolV1alpha1Client - flowcontrolV1beta1 *flowcontrolv1beta1.FlowcontrolV1beta1Client - flowcontrolV1beta2 *flowcontrolv1beta2.FlowcontrolV1beta2Client - networkingV1 *networkingv1.NetworkingV1Client - networkingV1beta1 *networkingv1beta1.NetworkingV1beta1Client - nodeV1 *nodev1.NodeV1Client - nodeV1alpha1 *nodev1alpha1.NodeV1alpha1Client - nodeV1beta1 *nodev1beta1.NodeV1beta1Client - policyV1 *policyv1.PolicyV1Client - policyV1beta1 *policyv1beta1.PolicyV1beta1Client - rbacV1 *rbacv1.RbacV1Client - rbacV1beta1 *rbacv1beta1.RbacV1beta1Client - rbacV1alpha1 *rbacv1alpha1.RbacV1alpha1Client - schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client - schedulingV1beta1 *schedulingv1beta1.SchedulingV1beta1Client - schedulingV1 *schedulingv1.SchedulingV1Client - storageV1beta1 *storagev1beta1.StorageV1beta1Client - storageV1 *storagev1.StorageV1Client - storageV1alpha1 *storagev1alpha1.StorageV1alpha1Client + admissionregistrationV1 *admissionregistrationv1.AdmissionregistrationV1Client + admissionregistrationV1alpha1 *admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Client + admissionregistrationV1beta1 *admissionregistrationv1beta1.AdmissionregistrationV1beta1Client + internalV1alpha1 *internalv1alpha1.InternalV1alpha1Client + appsV1 *appsv1.AppsV1Client + appsV1beta1 *appsv1beta1.AppsV1beta1Client + appsV1beta2 *appsv1beta2.AppsV1beta2Client + authenticationV1 *authenticationv1.AuthenticationV1Client + authenticationV1alpha1 *authenticationv1alpha1.AuthenticationV1alpha1Client + authenticationV1beta1 *authenticationv1beta1.AuthenticationV1beta1Client + authorizationV1 *authorizationv1.AuthorizationV1Client + authorizationV1beta1 *authorizationv1beta1.AuthorizationV1beta1Client + autoscalingV1 *autoscalingv1.AutoscalingV1Client + autoscalingV2 *autoscalingv2.AutoscalingV2Client + autoscalingV2beta1 *autoscalingv2beta1.AutoscalingV2beta1Client + autoscalingV2beta2 *autoscalingv2beta2.AutoscalingV2beta2Client + batchV1 *batchv1.BatchV1Client + batchV1beta1 *batchv1beta1.BatchV1beta1Client + certificatesV1 *certificatesv1.CertificatesV1Client + certificatesV1beta1 *certificatesv1beta1.CertificatesV1beta1Client + certificatesV1alpha1 *certificatesv1alpha1.CertificatesV1alpha1Client + coordinationV1beta1 *coordinationv1beta1.CoordinationV1beta1Client + coordinationV1 *coordinationv1.CoordinationV1Client + coreV1 *corev1.CoreV1Client + discoveryV1 *discoveryv1.DiscoveryV1Client + discoveryV1beta1 *discoveryv1beta1.DiscoveryV1beta1Client + eventsV1 *eventsv1.EventsV1Client + eventsV1beta1 *eventsv1beta1.EventsV1beta1Client + extensionsV1beta1 *extensionsv1beta1.ExtensionsV1beta1Client + flowcontrolV1alpha1 *flowcontrolv1alpha1.FlowcontrolV1alpha1Client + flowcontrolV1beta1 *flowcontrolv1beta1.FlowcontrolV1beta1Client + flowcontrolV1beta2 *flowcontrolv1beta2.FlowcontrolV1beta2Client + flowcontrolV1beta3 *flowcontrolv1beta3.FlowcontrolV1beta3Client + networkingV1 *networkingv1.NetworkingV1Client + networkingV1alpha1 *networkingv1alpha1.NetworkingV1alpha1Client + networkingV1beta1 *networkingv1beta1.NetworkingV1beta1Client + nodeV1 *nodev1.NodeV1Client + nodeV1alpha1 *nodev1alpha1.NodeV1alpha1Client + nodeV1beta1 *nodev1beta1.NodeV1beta1Client + policyV1 *policyv1.PolicyV1Client + policyV1beta1 *policyv1beta1.PolicyV1beta1Client + rbacV1 *rbacv1.RbacV1Client + rbacV1beta1 *rbacv1beta1.RbacV1beta1Client + rbacV1alpha1 *rbacv1alpha1.RbacV1alpha1Client + resourceV1alpha2 *resourcev1alpha2.ResourceV1alpha2Client + schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client + schedulingV1beta1 *schedulingv1beta1.SchedulingV1beta1Client + schedulingV1 *schedulingv1.SchedulingV1Client + storageV1beta1 *storagev1beta1.StorageV1beta1Client + storageV1 *storagev1.StorageV1Client + storageV1alpha1 *storagev1alpha1.StorageV1alpha1Client } // AdmissionregistrationV1 retrieves the AdmissionregistrationV1Client @@ -177,6 +194,11 @@ func (c *Clientset) AdmissionregistrationV1() admissionregistrationv1.Admissionr return c.admissionregistrationV1 } +// AdmissionregistrationV1alpha1 retrieves the AdmissionregistrationV1alpha1Client +func (c *Clientset) AdmissionregistrationV1alpha1() admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Interface { + return c.admissionregistrationV1alpha1 +} + // AdmissionregistrationV1beta1 retrieves the AdmissionregistrationV1beta1Client func (c *Clientset) AdmissionregistrationV1beta1() admissionregistrationv1beta1.AdmissionregistrationV1beta1Interface { return c.admissionregistrationV1beta1 @@ -207,6 +229,11 @@ func (c *Clientset) AuthenticationV1() authenticationv1.AuthenticationV1Interfac return c.authenticationV1 } +// AuthenticationV1alpha1 retrieves the AuthenticationV1alpha1Client +func (c *Clientset) AuthenticationV1alpha1() authenticationv1alpha1.AuthenticationV1alpha1Interface { + return c.authenticationV1alpha1 +} + // AuthenticationV1beta1 retrieves the AuthenticationV1beta1Client func (c *Clientset) AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface { return c.authenticationV1beta1 @@ -262,6 +289,11 @@ func (c *Clientset) CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta return c.certificatesV1beta1 } +// CertificatesV1alpha1 retrieves the CertificatesV1alpha1Client +func (c *Clientset) CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface { + return c.certificatesV1alpha1 +} + // CoordinationV1beta1 retrieves the CoordinationV1beta1Client func (c *Clientset) CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface { return c.coordinationV1beta1 @@ -317,11 +349,21 @@ func (c *Clientset) FlowcontrolV1beta2() flowcontrolv1beta2.FlowcontrolV1beta2In return c.flowcontrolV1beta2 } +// FlowcontrolV1beta3 retrieves the FlowcontrolV1beta3Client +func (c *Clientset) FlowcontrolV1beta3() flowcontrolv1beta3.FlowcontrolV1beta3Interface { + return c.flowcontrolV1beta3 +} + // NetworkingV1 retrieves the NetworkingV1Client func (c *Clientset) NetworkingV1() networkingv1.NetworkingV1Interface { return c.networkingV1 } +// NetworkingV1alpha1 retrieves the NetworkingV1alpha1Client +func (c *Clientset) NetworkingV1alpha1() networkingv1alpha1.NetworkingV1alpha1Interface { + return c.networkingV1alpha1 +} + // NetworkingV1beta1 retrieves the NetworkingV1beta1Client func (c *Clientset) NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface { return c.networkingV1beta1 @@ -367,6 +409,11 @@ func (c *Clientset) RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface { return c.rbacV1alpha1 } +// ResourceV1alpha2 retrieves the ResourceV1alpha2Client +func (c *Clientset) ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface { + return c.resourceV1alpha2 +} + // SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client func (c *Clientset) SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface { return c.schedulingV1alpha1 @@ -445,6 +492,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.admissionregistrationV1alpha1, err = admissionregistrationv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.admissionregistrationV1beta1, err = admissionregistrationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -469,6 +520,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.authenticationV1alpha1, err = authenticationv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.authenticationV1beta1, err = authenticationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -513,6 +568,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.certificatesV1alpha1, err = certificatesv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.coordinationV1beta1, err = coordinationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -557,10 +616,18 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.flowcontrolV1beta3, err = flowcontrolv1beta3.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.networkingV1, err = networkingv1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } + cs.networkingV1alpha1, err = networkingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.networkingV1beta1, err = networkingv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -597,6 +664,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.resourceV1alpha2, err = resourcev1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.schedulingV1alpha1, err = schedulingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -643,12 +714,14 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.admissionregistrationV1 = admissionregistrationv1.New(c) + cs.admissionregistrationV1alpha1 = admissionregistrationv1alpha1.New(c) cs.admissionregistrationV1beta1 = admissionregistrationv1beta1.New(c) cs.internalV1alpha1 = internalv1alpha1.New(c) cs.appsV1 = appsv1.New(c) cs.appsV1beta1 = appsv1beta1.New(c) cs.appsV1beta2 = appsv1beta2.New(c) cs.authenticationV1 = authenticationv1.New(c) + cs.authenticationV1alpha1 = authenticationv1alpha1.New(c) cs.authenticationV1beta1 = authenticationv1beta1.New(c) cs.authorizationV1 = authorizationv1.New(c) cs.authorizationV1beta1 = authorizationv1beta1.New(c) @@ -660,6 +733,7 @@ func New(c rest.Interface) *Clientset { cs.batchV1beta1 = batchv1beta1.New(c) cs.certificatesV1 = certificatesv1.New(c) cs.certificatesV1beta1 = certificatesv1beta1.New(c) + cs.certificatesV1alpha1 = certificatesv1alpha1.New(c) cs.coordinationV1beta1 = coordinationv1beta1.New(c) cs.coordinationV1 = coordinationv1.New(c) cs.coreV1 = corev1.New(c) @@ -671,7 +745,9 @@ func New(c rest.Interface) *Clientset { cs.flowcontrolV1alpha1 = flowcontrolv1alpha1.New(c) cs.flowcontrolV1beta1 = flowcontrolv1beta1.New(c) cs.flowcontrolV1beta2 = flowcontrolv1beta2.New(c) + cs.flowcontrolV1beta3 = flowcontrolv1beta3.New(c) cs.networkingV1 = networkingv1.New(c) + cs.networkingV1alpha1 = networkingv1alpha1.New(c) cs.networkingV1beta1 = networkingv1beta1.New(c) cs.nodeV1 = nodev1.New(c) cs.nodeV1alpha1 = nodev1alpha1.New(c) @@ -681,6 +757,7 @@ func New(c rest.Interface) *Clientset { cs.rbacV1 = rbacv1.New(c) cs.rbacV1beta1 = rbacv1beta1.New(c) cs.rbacV1alpha1 = rbacv1alpha1.New(c) + cs.resourceV1alpha2 = resourcev1alpha2.New(c) cs.schedulingV1alpha1 = schedulingv1alpha1.New(c) cs.schedulingV1beta1 = schedulingv1beta1.New(c) cs.schedulingV1 = schedulingv1.New(c) diff --git a/vendor/k8s.io/client-go/kubernetes/doc.go b/vendor/k8s.io/client-go/kubernetes/doc.go index b272334ad0e..9cef4242f2f 100644 --- a/vendor/k8s.io/client-go/kubernetes/doc.go +++ b/vendor/k8s.io/client-go/kubernetes/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2023 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. +// Package kubernetes holds packages which implement a clientset for Kubernetes +// APIs. package kubernetes diff --git a/vendor/k8s.io/client-go/kubernetes/scheme/register.go b/vendor/k8s.io/client-go/kubernetes/scheme/register.go index b41466151d4..64d3ce2a7b7 100644 --- a/vendor/k8s.io/client-go/kubernetes/scheme/register.go +++ b/vendor/k8s.io/client-go/kubernetes/scheme/register.go @@ -20,12 +20,14 @@ package scheme import ( admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" internalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" appsv1 "k8s.io/api/apps/v1" appsv1beta1 "k8s.io/api/apps/v1beta1" appsv1beta2 "k8s.io/api/apps/v1beta2" authenticationv1 "k8s.io/api/authentication/v1" + authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1" authenticationv1beta1 "k8s.io/api/authentication/v1beta1" authorizationv1 "k8s.io/api/authorization/v1" authorizationv1beta1 "k8s.io/api/authorization/v1beta1" @@ -36,6 +38,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -48,7 +51,9 @@ import ( flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" flowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" + flowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" networkingv1 "k8s.io/api/networking/v1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" networkingv1beta1 "k8s.io/api/networking/v1beta1" nodev1 "k8s.io/api/node/v1" nodev1alpha1 "k8s.io/api/node/v1alpha1" @@ -58,6 +63,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -76,12 +82,14 @@ var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ admissionregistrationv1.AddToScheme, + admissionregistrationv1alpha1.AddToScheme, admissionregistrationv1beta1.AddToScheme, internalv1alpha1.AddToScheme, appsv1.AddToScheme, appsv1beta1.AddToScheme, appsv1beta2.AddToScheme, authenticationv1.AddToScheme, + authenticationv1alpha1.AddToScheme, authenticationv1beta1.AddToScheme, authorizationv1.AddToScheme, authorizationv1beta1.AddToScheme, @@ -93,6 +101,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ batchv1beta1.AddToScheme, certificatesv1.AddToScheme, certificatesv1beta1.AddToScheme, + certificatesv1alpha1.AddToScheme, coordinationv1beta1.AddToScheme, coordinationv1.AddToScheme, corev1.AddToScheme, @@ -104,7 +113,9 @@ var localSchemeBuilder = runtime.SchemeBuilder{ flowcontrolv1alpha1.AddToScheme, flowcontrolv1beta1.AddToScheme, flowcontrolv1beta2.AddToScheme, + flowcontrolv1beta3.AddToScheme, networkingv1.AddToScheme, + networkingv1alpha1.AddToScheme, networkingv1beta1.AddToScheme, nodev1.AddToScheme, nodev1alpha1.AddToScheme, @@ -114,6 +125,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ rbacv1.AddToScheme, rbacv1beta1.AddToScheme, rbacv1alpha1.AddToScheme, + resourcev1alpha2.AddToScheme, schedulingv1alpha1.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, @@ -125,14 +137,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/admissionregistration_client.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/admissionregistration_client.go new file mode 100644 index 00000000000..f6102d25ae2 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/admissionregistration_client.go @@ -0,0 +1,112 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type AdmissionregistrationV1alpha1Interface interface { + RESTClient() rest.Interface + ValidatingAdmissionPoliciesGetter + ValidatingAdmissionPolicyBindingsGetter +} + +// AdmissionregistrationV1alpha1Client is used to interact with features provided by the admissionregistration.k8s.io group. +type AdmissionregistrationV1alpha1Client struct { + restClient rest.Interface +} + +func (c *AdmissionregistrationV1alpha1Client) ValidatingAdmissionPolicies() ValidatingAdmissionPolicyInterface { + return newValidatingAdmissionPolicies(c) +} + +func (c *AdmissionregistrationV1alpha1Client) ValidatingAdmissionPolicyBindings() ValidatingAdmissionPolicyBindingInterface { + return newValidatingAdmissionPolicyBindings(c) +} + +// NewForConfig creates a new AdmissionregistrationV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*AdmissionregistrationV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new AdmissionregistrationV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AdmissionregistrationV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &AdmissionregistrationV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new AdmissionregistrationV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AdmissionregistrationV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AdmissionregistrationV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *AdmissionregistrationV1alpha1Client { + return &AdmissionregistrationV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AdmissionregistrationV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/doc.go new file mode 100644 index 00000000000..df51baa4d4c --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..94562da5943 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ValidatingAdmissionPolicyExpansion interface{} + +type ValidatingAdmissionPolicyBindingExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go new file mode 100644 index 00000000000..1d994b5abf7 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -0,0 +1,243 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + admissionregistrationv1alpha1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ValidatingAdmissionPoliciesGetter has a method to return a ValidatingAdmissionPolicyInterface. +// A group's client should implement this interface. +type ValidatingAdmissionPoliciesGetter interface { + ValidatingAdmissionPolicies() ValidatingAdmissionPolicyInterface +} + +// ValidatingAdmissionPolicyInterface has methods to work with ValidatingAdmissionPolicy resources. +type ValidatingAdmissionPolicyInterface interface { + Create(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.CreateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + Update(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ValidatingAdmissionPolicyList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicy, err error) + Apply(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) + ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) + ValidatingAdmissionPolicyExpansion +} + +// validatingAdmissionPolicies implements ValidatingAdmissionPolicyInterface +type validatingAdmissionPolicies struct { + client rest.Interface +} + +// newValidatingAdmissionPolicies returns a ValidatingAdmissionPolicies +func newValidatingAdmissionPolicies(c *AdmissionregistrationV1alpha1Client) *validatingAdmissionPolicies { + return &validatingAdmissionPolicies{ + client: c.RESTClient(), + } +} + +// Get takes name of the validatingAdmissionPolicy, and returns the corresponding validatingAdmissionPolicy object, and an error if there is any. +func (c *validatingAdmissionPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Get(). + Resource("validatingadmissionpolicies"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ValidatingAdmissionPolicies that match those selectors. +func (c *validatingAdmissionPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ValidatingAdmissionPolicyList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ValidatingAdmissionPolicyList{} + err = c.client.Get(). + Resource("validatingadmissionpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested validatingAdmissionPolicies. +func (c *validatingAdmissionPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("validatingadmissionpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a validatingAdmissionPolicy and creates it. Returns the server's representation of the validatingAdmissionPolicy, and an error, if there is any. +func (c *validatingAdmissionPolicies) Create(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.CreateOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Post(). + Resource("validatingadmissionpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicy). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a validatingAdmissionPolicy and updates it. Returns the server's representation of the validatingAdmissionPolicy, and an error, if there is any. +func (c *validatingAdmissionPolicies) Update(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Put(). + Resource("validatingadmissionpolicies"). + Name(validatingAdmissionPolicy.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicy). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *validatingAdmissionPolicies) UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Put(). + Resource("validatingadmissionpolicies"). + Name(validatingAdmissionPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicy). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the validatingAdmissionPolicy and deletes it. Returns an error if one occurs. +func (c *validatingAdmissionPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("validatingadmissionpolicies"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *validatingAdmissionPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("validatingadmissionpolicies"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched validatingAdmissionPolicy. +func (c *validatingAdmissionPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Patch(pt). + Resource("validatingadmissionpolicies"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied validatingAdmissionPolicy. +func (c *validatingAdmissionPolicies) Apply(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + if validatingAdmissionPolicy == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(validatingAdmissionPolicy) + if err != nil { + return nil, err + } + name := validatingAdmissionPolicy.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy.Name must be provided to Apply") + } + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Patch(types.ApplyPatchType). + Resource("validatingadmissionpolicies"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *validatingAdmissionPolicies) ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + if validatingAdmissionPolicy == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(validatingAdmissionPolicy) + if err != nil { + return nil, err + } + + name := validatingAdmissionPolicy.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy.Name must be provided to Apply") + } + + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Patch(types.ApplyPatchType). + Resource("validatingadmissionpolicies"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go new file mode 100644 index 00000000000..39823ca82b1 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -0,0 +1,197 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + admissionregistrationv1alpha1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ValidatingAdmissionPolicyBindingsGetter has a method to return a ValidatingAdmissionPolicyBindingInterface. +// A group's client should implement this interface. +type ValidatingAdmissionPolicyBindingsGetter interface { + ValidatingAdmissionPolicyBindings() ValidatingAdmissionPolicyBindingInterface +} + +// ValidatingAdmissionPolicyBindingInterface has methods to work with ValidatingAdmissionPolicyBinding resources. +type ValidatingAdmissionPolicyBindingInterface interface { + Create(ctx context.Context, validatingAdmissionPolicyBinding *v1alpha1.ValidatingAdmissionPolicyBinding, opts v1.CreateOptions) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) + Update(ctx context.Context, validatingAdmissionPolicyBinding *v1alpha1.ValidatingAdmissionPolicyBinding, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ValidatingAdmissionPolicyBindingList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) + Apply(ctx context.Context, validatingAdmissionPolicyBinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBindingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) + ValidatingAdmissionPolicyBindingExpansion +} + +// validatingAdmissionPolicyBindings implements ValidatingAdmissionPolicyBindingInterface +type validatingAdmissionPolicyBindings struct { + client rest.Interface +} + +// newValidatingAdmissionPolicyBindings returns a ValidatingAdmissionPolicyBindings +func newValidatingAdmissionPolicyBindings(c *AdmissionregistrationV1alpha1Client) *validatingAdmissionPolicyBindings { + return &validatingAdmissionPolicyBindings{ + client: c.RESTClient(), + } +} + +// Get takes name of the validatingAdmissionPolicyBinding, and returns the corresponding validatingAdmissionPolicyBinding object, and an error if there is any. +func (c *validatingAdmissionPolicyBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + result = &v1alpha1.ValidatingAdmissionPolicyBinding{} + err = c.client.Get(). + Resource("validatingadmissionpolicybindings"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ValidatingAdmissionPolicyBindings that match those selectors. +func (c *validatingAdmissionPolicyBindings) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ValidatingAdmissionPolicyBindingList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ValidatingAdmissionPolicyBindingList{} + err = c.client.Get(). + Resource("validatingadmissionpolicybindings"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested validatingAdmissionPolicyBindings. +func (c *validatingAdmissionPolicyBindings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("validatingadmissionpolicybindings"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a validatingAdmissionPolicyBinding and creates it. Returns the server's representation of the validatingAdmissionPolicyBinding, and an error, if there is any. +func (c *validatingAdmissionPolicyBindings) Create(ctx context.Context, validatingAdmissionPolicyBinding *v1alpha1.ValidatingAdmissionPolicyBinding, opts v1.CreateOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + result = &v1alpha1.ValidatingAdmissionPolicyBinding{} + err = c.client.Post(). + Resource("validatingadmissionpolicybindings"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicyBinding). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a validatingAdmissionPolicyBinding and updates it. Returns the server's representation of the validatingAdmissionPolicyBinding, and an error, if there is any. +func (c *validatingAdmissionPolicyBindings) Update(ctx context.Context, validatingAdmissionPolicyBinding *v1alpha1.ValidatingAdmissionPolicyBinding, opts v1.UpdateOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + result = &v1alpha1.ValidatingAdmissionPolicyBinding{} + err = c.client.Put(). + Resource("validatingadmissionpolicybindings"). + Name(validatingAdmissionPolicyBinding.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicyBinding). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the validatingAdmissionPolicyBinding and deletes it. Returns an error if one occurs. +func (c *validatingAdmissionPolicyBindings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("validatingadmissionpolicybindings"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *validatingAdmissionPolicyBindings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("validatingadmissionpolicybindings"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched validatingAdmissionPolicyBinding. +func (c *validatingAdmissionPolicyBindings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + result = &v1alpha1.ValidatingAdmissionPolicyBinding{} + err = c.client.Patch(pt). + Resource("validatingadmissionpolicybindings"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied validatingAdmissionPolicyBinding. +func (c *validatingAdmissionPolicyBindings) Apply(ctx context.Context, validatingAdmissionPolicyBinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBindingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + if validatingAdmissionPolicyBinding == nil { + return nil, fmt.Errorf("validatingAdmissionPolicyBinding provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(validatingAdmissionPolicyBinding) + if err != nil { + return nil, err + } + name := validatingAdmissionPolicyBinding.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicyBinding.Name must be provided to Apply") + } + result = &v1alpha1.ValidatingAdmissionPolicyBinding{} + err = c.client.Patch(types.ApplyPatchType). + Resource("validatingadmissionpolicybindings"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/authentication_client.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/authentication_client.go new file mode 100644 index 00000000000..18739266156 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/authentication_client.go @@ -0,0 +1,107 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/authentication/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type AuthenticationV1alpha1Interface interface { + RESTClient() rest.Interface + SelfSubjectReviewsGetter +} + +// AuthenticationV1alpha1Client is used to interact with features provided by the authentication.k8s.io group. +type AuthenticationV1alpha1Client struct { + restClient rest.Interface +} + +func (c *AuthenticationV1alpha1Client) SelfSubjectReviews() SelfSubjectReviewInterface { + return newSelfSubjectReviews(c) +} + +// NewForConfig creates a new AuthenticationV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*AuthenticationV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new AuthenticationV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AuthenticationV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &AuthenticationV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new AuthenticationV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AuthenticationV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AuthenticationV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *AuthenticationV1alpha1Client { + return &AuthenticationV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AuthenticationV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/doc.go new file mode 100644 index 00000000000..df51baa4d4c --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..6a648364b00 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type SelfSubjectReviewExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/selfsubjectreview.go new file mode 100644 index 00000000000..7f8b12a46f2 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/selfsubjectreview.go @@ -0,0 +1,64 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + + v1alpha1 "k8s.io/api/authentication/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// SelfSubjectReviewsGetter has a method to return a SelfSubjectReviewInterface. +// A group's client should implement this interface. +type SelfSubjectReviewsGetter interface { + SelfSubjectReviews() SelfSubjectReviewInterface +} + +// SelfSubjectReviewInterface has methods to work with SelfSubjectReview resources. +type SelfSubjectReviewInterface interface { + Create(ctx context.Context, selfSubjectReview *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (*v1alpha1.SelfSubjectReview, error) + SelfSubjectReviewExpansion +} + +// selfSubjectReviews implements SelfSubjectReviewInterface +type selfSubjectReviews struct { + client rest.Interface +} + +// newSelfSubjectReviews returns a SelfSubjectReviews +func newSelfSubjectReviews(c *AuthenticationV1alpha1Client) *selfSubjectReviews { + return &selfSubjectReviews{ + client: c.RESTClient(), + } +} + +// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. +func (c *selfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (result *v1alpha1.SelfSubjectReview, err error) { + result = &v1alpha1.SelfSubjectReview{} + err = c.client.Post(). + Resource("selfsubjectreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(selfSubjectReview). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go index 218cb60c317..7823729e09c 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go @@ -28,6 +28,7 @@ import ( type AuthenticationV1beta1Interface interface { RESTClient() rest.Interface + SelfSubjectReviewsGetter TokenReviewsGetter } @@ -36,6 +37,10 @@ type AuthenticationV1beta1Client struct { restClient rest.Interface } +func (c *AuthenticationV1beta1Client) SelfSubjectReviews() SelfSubjectReviewInterface { + return newSelfSubjectReviews(c) +} + func (c *AuthenticationV1beta1Client) TokenReviews() TokenReviewInterface { return newTokenReviews(c) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go index 60bf15ab996..527a458d745 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go @@ -18,4 +18,6 @@ limitations under the License. package v1beta1 +type SelfSubjectReviewExpansion interface{} + type TokenReviewExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go new file mode 100644 index 00000000000..9d54826a31c --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go @@ -0,0 +1,64 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + + v1beta1 "k8s.io/api/authentication/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// SelfSubjectReviewsGetter has a method to return a SelfSubjectReviewInterface. +// A group's client should implement this interface. +type SelfSubjectReviewsGetter interface { + SelfSubjectReviews() SelfSubjectReviewInterface +} + +// SelfSubjectReviewInterface has methods to work with SelfSubjectReview resources. +type SelfSubjectReviewInterface interface { + Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (*v1beta1.SelfSubjectReview, error) + SelfSubjectReviewExpansion +} + +// selfSubjectReviews implements SelfSubjectReviewInterface +type selfSubjectReviews struct { + client rest.Interface +} + +// newSelfSubjectReviews returns a SelfSubjectReviews +func newSelfSubjectReviews(c *AuthenticationV1beta1Client) *selfSubjectReviews { + return &selfSubjectReviews{ + client: c.RESTClient(), + } +} + +// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. +func (c *selfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectReview, err error) { + result = &v1beta1.SelfSubjectReview{} + err = c.client.Post(). + Resource("selfsubjectreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(selfSubjectReview). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go new file mode 100644 index 00000000000..a9050af9456 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go @@ -0,0 +1,107 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type CertificatesV1alpha1Interface interface { + RESTClient() rest.Interface + ClusterTrustBundlesGetter +} + +// CertificatesV1alpha1Client is used to interact with features provided by the certificates.k8s.io group. +type CertificatesV1alpha1Client struct { + restClient rest.Interface +} + +func (c *CertificatesV1alpha1Client) ClusterTrustBundles() ClusterTrustBundleInterface { + return newClusterTrustBundles(c) +} + +// NewForConfig creates a new CertificatesV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new CertificatesV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &CertificatesV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new CertificatesV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CertificatesV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CertificatesV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *CertificatesV1alpha1Client { + return &CertificatesV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CertificatesV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 00000000000..970fb15e6e8 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,197 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + certificatesv1alpha1 "k8s.io/client-go/applyconfigurations/certificates/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ClusterTrustBundlesGetter has a method to return a ClusterTrustBundleInterface. +// A group's client should implement this interface. +type ClusterTrustBundlesGetter interface { + ClusterTrustBundles() ClusterTrustBundleInterface +} + +// ClusterTrustBundleInterface has methods to work with ClusterTrustBundle resources. +type ClusterTrustBundleInterface interface { + Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (*v1alpha1.ClusterTrustBundle, error) + Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (*v1alpha1.ClusterTrustBundle, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterTrustBundle, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterTrustBundleList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) + Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) + ClusterTrustBundleExpansion +} + +// clusterTrustBundles implements ClusterTrustBundleInterface +type clusterTrustBundles struct { + client rest.Interface +} + +// newClusterTrustBundles returns a ClusterTrustBundles +func newClusterTrustBundles(c *CertificatesV1alpha1Client) *clusterTrustBundles { + return &clusterTrustBundles{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterTrustBundle, and returns the corresponding clusterTrustBundle object, and an error if there is any. +func (c *clusterTrustBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Get(). + Resource("clustertrustbundles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterTrustBundles that match those selectors. +func (c *clusterTrustBundles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterTrustBundleList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterTrustBundleList{} + err = c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterTrustBundles. +func (c *clusterTrustBundles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterTrustBundle and creates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Post(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterTrustBundle and updates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Put(). + Resource("clustertrustbundles"). + Name(clusterTrustBundle.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterTrustBundle and deletes it. Returns an error if one occurs. +func (c *clusterTrustBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustertrustbundles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterTrustBundles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustertrustbundles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterTrustBundle. +func (c *clusterTrustBundles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(pt). + Resource("clustertrustbundles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied clusterTrustBundle. +func (c *clusterTrustBundles) Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + if clusterTrustBundle == nil { + return nil, fmt.Errorf("clusterTrustBundle provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(clusterTrustBundle) + if err != nil { + return nil, err + } + name := clusterTrustBundle.Name + if name == nil { + return nil, fmt.Errorf("clusterTrustBundle.Name must be provided to Apply") + } + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(types.ApplyPatchType). + Resource("clustertrustbundles"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go new file mode 100644 index 00000000000..df51baa4d4c --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..43cc534b375 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ClusterTrustBundleExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go index 7213193bf1b..562f8d5e45e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go @@ -82,7 +82,7 @@ func (e *events) UpdateWithEventNamespace(event *v1beta1.Event) (*v1beta1.Event, // It returns the copy of the event that the server returns, or an error. // The namespace and name of the target event is deduced from the event. // The namespace must either match this event client's namespace, or this event client must -// have been created with the "" namespace. +// have been created with the "" namespace. func (e *events) PatchWithEventNamespace(event *v1beta1.Event, data []byte) (*v1beta1.Event, error) { if e.ns != "" && event.Namespace != e.ns { return nil, fmt.Errorf("can't patch an event with namespace '%v' in namespace '%v'", event.Namespace, e.ns) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go index 827b514df6f..4725d2cd16f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go @@ -32,7 +32,6 @@ type ExtensionsV1beta1Interface interface { DeploymentsGetter IngressesGetter NetworkPoliciesGetter - PodSecurityPoliciesGetter ReplicaSetsGetter } @@ -57,10 +56,6 @@ func (c *ExtensionsV1beta1Client) NetworkPolicies(namespace string) NetworkPolic return newNetworkPolicies(c, namespace) } -func (c *ExtensionsV1beta1Client) PodSecurityPolicies() PodSecurityPolicyInterface { - return newPodSecurityPolicies(c) -} - func (c *ExtensionsV1beta1Client) ReplicaSets(namespace string) ReplicaSetInterface { return newReplicaSets(c, namespace) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go index 41d28f0417c..67fcf4992b0 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go @@ -24,6 +24,4 @@ type IngressExpansion interface{} type NetworkPolicyExpansion interface{} -type PodSecurityPolicyExpansion interface{} - type ReplicaSetExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index 3f38c3133d6..00000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1beta1 - -import ( - "context" - json "encoding/json" - "fmt" - "time" - - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// PodSecurityPoliciesGetter has a method to return a PodSecurityPolicyInterface. -// A group's client should implement this interface. -type PodSecurityPoliciesGetter interface { - PodSecurityPolicies() PodSecurityPolicyInterface -} - -// PodSecurityPolicyInterface has methods to work with PodSecurityPolicy resources. -type PodSecurityPolicyInterface interface { - Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (*v1beta1.PodSecurityPolicy, error) - Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (*v1beta1.PodSecurityPolicy, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.PodSecurityPolicy, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta1.PodSecurityPolicyList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) - Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) - PodSecurityPolicyExpansion -} - -// podSecurityPolicies implements PodSecurityPolicyInterface -type podSecurityPolicies struct { - client rest.Interface -} - -// newPodSecurityPolicies returns a PodSecurityPolicies -func newPodSecurityPolicies(c *ExtensionsV1beta1Client) *podSecurityPolicies { - return &podSecurityPolicies{ - client: c.RESTClient(), - } -} - -// Get takes name of the podSecurityPolicy, and returns the corresponding podSecurityPolicy object, and an error if there is any. -func (c *podSecurityPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of PodSecurityPolicies that match those selectors. -func (c *podSecurityPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PodSecurityPolicyList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1beta1.PodSecurityPolicyList{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested podSecurityPolicies. -func (c *podSecurityPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a podSecurityPolicy and creates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Post(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a podSecurityPolicy and updates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Put(). - Resource("podsecuritypolicies"). - Name(podSecurityPolicy.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the podSecurityPolicy and deletes it. Returns an error if one occurs. -func (c *podSecurityPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Resource("podsecuritypolicies"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *podSecurityPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Resource("podsecuritypolicies"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched podSecurityPolicy. -func (c *podSecurityPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(pt). - Resource("podsecuritypolicies"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podSecurityPolicy. -func (c *podSecurityPolicies) Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) { - if podSecurityPolicy == nil { - return nil, fmt.Errorf("podSecurityPolicy provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podSecurityPolicy) - if err != nil { - return nil, err - } - name := podSecurityPolicy.Name - if name == nil { - return nil, fmt.Errorf("podSecurityPolicy.Name must be provided to Apply") - } - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(types.ApplyPatchType). - Resource("podsecuritypolicies"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/doc.go new file mode 100644 index 00000000000..09b1d25b085 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta3 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowcontrol_client.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowcontrol_client.go new file mode 100644 index 00000000000..461120bd3b1 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowcontrol_client.go @@ -0,0 +1,112 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta3 + +import ( + "net/http" + + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type FlowcontrolV1beta3Interface interface { + RESTClient() rest.Interface + FlowSchemasGetter + PriorityLevelConfigurationsGetter +} + +// FlowcontrolV1beta3Client is used to interact with features provided by the flowcontrol.apiserver.k8s.io group. +type FlowcontrolV1beta3Client struct { + restClient rest.Interface +} + +func (c *FlowcontrolV1beta3Client) FlowSchemas() FlowSchemaInterface { + return newFlowSchemas(c) +} + +func (c *FlowcontrolV1beta3Client) PriorityLevelConfigurations() PriorityLevelConfigurationInterface { + return newPriorityLevelConfigurations(c) +} + +// NewForConfig creates a new FlowcontrolV1beta3Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*FlowcontrolV1beta3Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new FlowcontrolV1beta3Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*FlowcontrolV1beta3Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &FlowcontrolV1beta3Client{client}, nil +} + +// NewForConfigOrDie creates a new FlowcontrolV1beta3Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *FlowcontrolV1beta3Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new FlowcontrolV1beta3Client for the given RESTClient. +func New(c rest.Interface) *FlowcontrolV1beta3Client { + return &FlowcontrolV1beta3Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta3.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FlowcontrolV1beta3Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowschema.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowschema.go new file mode 100644 index 00000000000..5fa39d6bafa --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/flowschema.go @@ -0,0 +1,243 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta3 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + flowcontrolv1beta3 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// FlowSchemasGetter has a method to return a FlowSchemaInterface. +// A group's client should implement this interface. +type FlowSchemasGetter interface { + FlowSchemas() FlowSchemaInterface +} + +// FlowSchemaInterface has methods to work with FlowSchema resources. +type FlowSchemaInterface interface { + Create(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.CreateOptions) (*v1beta3.FlowSchema, error) + Update(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.UpdateOptions) (*v1beta3.FlowSchema, error) + UpdateStatus(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.UpdateOptions) (*v1beta3.FlowSchema, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta3.FlowSchema, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta3.FlowSchemaList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta3.FlowSchema, err error) + Apply(ctx context.Context, flowSchema *flowcontrolv1beta3.FlowSchemaApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.FlowSchema, err error) + ApplyStatus(ctx context.Context, flowSchema *flowcontrolv1beta3.FlowSchemaApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.FlowSchema, err error) + FlowSchemaExpansion +} + +// flowSchemas implements FlowSchemaInterface +type flowSchemas struct { + client rest.Interface +} + +// newFlowSchemas returns a FlowSchemas +func newFlowSchemas(c *FlowcontrolV1beta3Client) *flowSchemas { + return &flowSchemas{ + client: c.RESTClient(), + } +} + +// Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any. +func (c *flowSchemas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta3.FlowSchema, err error) { + result = &v1beta3.FlowSchema{} + err = c.client.Get(). + Resource("flowschemas"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of FlowSchemas that match those selectors. +func (c *flowSchemas) List(ctx context.Context, opts v1.ListOptions) (result *v1beta3.FlowSchemaList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta3.FlowSchemaList{} + err = c.client.Get(). + Resource("flowschemas"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested flowSchemas. +func (c *flowSchemas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("flowschemas"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a flowSchema and creates it. Returns the server's representation of the flowSchema, and an error, if there is any. +func (c *flowSchemas) Create(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.CreateOptions) (result *v1beta3.FlowSchema, err error) { + result = &v1beta3.FlowSchema{} + err = c.client.Post(). + Resource("flowschemas"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(flowSchema). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a flowSchema and updates it. Returns the server's representation of the flowSchema, and an error, if there is any. +func (c *flowSchemas) Update(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.UpdateOptions) (result *v1beta3.FlowSchema, err error) { + result = &v1beta3.FlowSchema{} + err = c.client.Put(). + Resource("flowschemas"). + Name(flowSchema.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(flowSchema). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *flowSchemas) UpdateStatus(ctx context.Context, flowSchema *v1beta3.FlowSchema, opts v1.UpdateOptions) (result *v1beta3.FlowSchema, err error) { + result = &v1beta3.FlowSchema{} + err = c.client.Put(). + Resource("flowschemas"). + Name(flowSchema.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(flowSchema). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the flowSchema and deletes it. Returns an error if one occurs. +func (c *flowSchemas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("flowschemas"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *flowSchemas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("flowschemas"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched flowSchema. +func (c *flowSchemas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta3.FlowSchema, err error) { + result = &v1beta3.FlowSchema{} + err = c.client.Patch(pt). + Resource("flowschemas"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied flowSchema. +func (c *flowSchemas) Apply(ctx context.Context, flowSchema *flowcontrolv1beta3.FlowSchemaApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.FlowSchema, err error) { + if flowSchema == nil { + return nil, fmt.Errorf("flowSchema provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(flowSchema) + if err != nil { + return nil, err + } + name := flowSchema.Name + if name == nil { + return nil, fmt.Errorf("flowSchema.Name must be provided to Apply") + } + result = &v1beta3.FlowSchema{} + err = c.client.Patch(types.ApplyPatchType). + Resource("flowschemas"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *flowSchemas) ApplyStatus(ctx context.Context, flowSchema *flowcontrolv1beta3.FlowSchemaApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.FlowSchema, err error) { + if flowSchema == nil { + return nil, fmt.Errorf("flowSchema provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(flowSchema) + if err != nil { + return nil, err + } + + name := flowSchema.Name + if name == nil { + return nil, fmt.Errorf("flowSchema.Name must be provided to Apply") + } + + result = &v1beta3.FlowSchema{} + err = c.client.Patch(types.ApplyPatchType). + Resource("flowschemas"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/generated_expansion.go new file mode 100644 index 00000000000..51ae8d1f3bb --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta3 + +type FlowSchemaExpansion interface{} + +type PriorityLevelConfigurationExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/prioritylevelconfiguration.go new file mode 100644 index 00000000000..49f05257c9b --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/prioritylevelconfiguration.go @@ -0,0 +1,243 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta3 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + flowcontrolv1beta3 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// PriorityLevelConfigurationsGetter has a method to return a PriorityLevelConfigurationInterface. +// A group's client should implement this interface. +type PriorityLevelConfigurationsGetter interface { + PriorityLevelConfigurations() PriorityLevelConfigurationInterface +} + +// PriorityLevelConfigurationInterface has methods to work with PriorityLevelConfiguration resources. +type PriorityLevelConfigurationInterface interface { + Create(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.CreateOptions) (*v1beta3.PriorityLevelConfiguration, error) + Update(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.UpdateOptions) (*v1beta3.PriorityLevelConfiguration, error) + UpdateStatus(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.UpdateOptions) (*v1beta3.PriorityLevelConfiguration, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta3.PriorityLevelConfiguration, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta3.PriorityLevelConfigurationList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta3.PriorityLevelConfiguration, err error) + Apply(ctx context.Context, priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.PriorityLevelConfiguration, err error) + ApplyStatus(ctx context.Context, priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.PriorityLevelConfiguration, err error) + PriorityLevelConfigurationExpansion +} + +// priorityLevelConfigurations implements PriorityLevelConfigurationInterface +type priorityLevelConfigurations struct { + client rest.Interface +} + +// newPriorityLevelConfigurations returns a PriorityLevelConfigurations +func newPriorityLevelConfigurations(c *FlowcontrolV1beta3Client) *priorityLevelConfigurations { + return &priorityLevelConfigurations{ + client: c.RESTClient(), + } +} + +// Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any. +func (c *priorityLevelConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Get(). + Resource("prioritylevelconfigurations"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PriorityLevelConfigurations that match those selectors. +func (c *priorityLevelConfigurations) List(ctx context.Context, opts v1.ListOptions) (result *v1beta3.PriorityLevelConfigurationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta3.PriorityLevelConfigurationList{} + err = c.client.Get(). + Resource("prioritylevelconfigurations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested priorityLevelConfigurations. +func (c *priorityLevelConfigurations) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("prioritylevelconfigurations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a priorityLevelConfiguration and creates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any. +func (c *priorityLevelConfigurations) Create(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.CreateOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Post(). + Resource("prioritylevelconfigurations"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(priorityLevelConfiguration). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a priorityLevelConfiguration and updates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any. +func (c *priorityLevelConfigurations) Update(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.UpdateOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Put(). + Resource("prioritylevelconfigurations"). + Name(priorityLevelConfiguration.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(priorityLevelConfiguration). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *priorityLevelConfigurations) UpdateStatus(ctx context.Context, priorityLevelConfiguration *v1beta3.PriorityLevelConfiguration, opts v1.UpdateOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Put(). + Resource("prioritylevelconfigurations"). + Name(priorityLevelConfiguration.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(priorityLevelConfiguration). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the priorityLevelConfiguration and deletes it. Returns an error if one occurs. +func (c *priorityLevelConfigurations) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("prioritylevelconfigurations"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *priorityLevelConfigurations) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("prioritylevelconfigurations"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched priorityLevelConfiguration. +func (c *priorityLevelConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta3.PriorityLevelConfiguration, err error) { + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Patch(pt). + Resource("prioritylevelconfigurations"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied priorityLevelConfiguration. +func (c *priorityLevelConfigurations) Apply(ctx context.Context, priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + if priorityLevelConfiguration == nil { + return nil, fmt.Errorf("priorityLevelConfiguration provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(priorityLevelConfiguration) + if err != nil { + return nil, err + } + name := priorityLevelConfiguration.Name + if name == nil { + return nil, fmt.Errorf("priorityLevelConfiguration.Name must be provided to Apply") + } + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Patch(types.ApplyPatchType). + Resource("prioritylevelconfigurations"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *priorityLevelConfigurations) ApplyStatus(ctx context.Context, priorityLevelConfiguration *flowcontrolv1beta3.PriorityLevelConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { + if priorityLevelConfiguration == nil { + return nil, fmt.Errorf("priorityLevelConfiguration provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(priorityLevelConfiguration) + if err != nil { + return nil, err + } + + name := priorityLevelConfiguration.Name + if name == nil { + return nil, fmt.Errorf("priorityLevelConfiguration.Name must be provided to Apply") + } + + result = &v1beta3.PriorityLevelConfiguration{} + err = c.client.Patch(types.ApplyPatchType). + Resource("prioritylevelconfigurations"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/clustercidr.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/clustercidr.go new file mode 100644 index 00000000000..9df76351db8 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/clustercidr.go @@ -0,0 +1,197 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ClusterCIDRsGetter has a method to return a ClusterCIDRInterface. +// A group's client should implement this interface. +type ClusterCIDRsGetter interface { + ClusterCIDRs() ClusterCIDRInterface +} + +// ClusterCIDRInterface has methods to work with ClusterCIDR resources. +type ClusterCIDRInterface interface { + Create(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.CreateOptions) (*v1alpha1.ClusterCIDR, error) + Update(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.UpdateOptions) (*v1alpha1.ClusterCIDR, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterCIDR, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterCIDRList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCIDR, err error) + Apply(ctx context.Context, clusterCIDR *networkingv1alpha1.ClusterCIDRApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterCIDR, err error) + ClusterCIDRExpansion +} + +// clusterCIDRs implements ClusterCIDRInterface +type clusterCIDRs struct { + client rest.Interface +} + +// newClusterCIDRs returns a ClusterCIDRs +func newClusterCIDRs(c *NetworkingV1alpha1Client) *clusterCIDRs { + return &clusterCIDRs{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterCIDR, and returns the corresponding clusterCIDR object, and an error if there is any. +func (c *clusterCIDRs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCIDR, err error) { + result = &v1alpha1.ClusterCIDR{} + err = c.client.Get(). + Resource("clustercidrs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterCIDRs that match those selectors. +func (c *clusterCIDRs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterCIDRList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterCIDRList{} + err = c.client.Get(). + Resource("clustercidrs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterCIDRs. +func (c *clusterCIDRs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustercidrs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterCIDR and creates it. Returns the server's representation of the clusterCIDR, and an error, if there is any. +func (c *clusterCIDRs) Create(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.CreateOptions) (result *v1alpha1.ClusterCIDR, err error) { + result = &v1alpha1.ClusterCIDR{} + err = c.client.Post(). + Resource("clustercidrs"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCIDR). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterCIDR and updates it. Returns the server's representation of the clusterCIDR, and an error, if there is any. +func (c *clusterCIDRs) Update(ctx context.Context, clusterCIDR *v1alpha1.ClusterCIDR, opts v1.UpdateOptions) (result *v1alpha1.ClusterCIDR, err error) { + result = &v1alpha1.ClusterCIDR{} + err = c.client.Put(). + Resource("clustercidrs"). + Name(clusterCIDR.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCIDR). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterCIDR and deletes it. Returns an error if one occurs. +func (c *clusterCIDRs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustercidrs"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterCIDRs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustercidrs"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterCIDR. +func (c *clusterCIDRs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCIDR, err error) { + result = &v1alpha1.ClusterCIDR{} + err = c.client.Patch(pt). + Resource("clustercidrs"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied clusterCIDR. +func (c *clusterCIDRs) Apply(ctx context.Context, clusterCIDR *networkingv1alpha1.ClusterCIDRApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterCIDR, err error) { + if clusterCIDR == nil { + return nil, fmt.Errorf("clusterCIDR provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(clusterCIDR) + if err != nil { + return nil, err + } + name := clusterCIDR.Name + if name == nil { + return nil, fmt.Errorf("clusterCIDR.Name must be provided to Apply") + } + result = &v1alpha1.ClusterCIDR{} + err = c.client.Patch(types.ApplyPatchType). + Resource("clustercidrs"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/doc.go new file mode 100644 index 00000000000..df51baa4d4c --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..9c2979d6c44 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ClusterCIDRExpansion interface{} + +type IPAddressExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go new file mode 100644 index 00000000000..fff193d68d1 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go @@ -0,0 +1,197 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// IPAddressesGetter has a method to return a IPAddressInterface. +// A group's client should implement this interface. +type IPAddressesGetter interface { + IPAddresses() IPAddressInterface +} + +// IPAddressInterface has methods to work with IPAddress resources. +type IPAddressInterface interface { + Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (*v1alpha1.IPAddress, error) + Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (*v1alpha1.IPAddress, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.IPAddress, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.IPAddressList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) + Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) + IPAddressExpansion +} + +// iPAddresses implements IPAddressInterface +type iPAddresses struct { + client rest.Interface +} + +// newIPAddresses returns a IPAddresses +func newIPAddresses(c *NetworkingV1alpha1Client) *iPAddresses { + return &iPAddresses{ + client: c.RESTClient(), + } +} + +// Get takes name of the iPAddress, and returns the corresponding iPAddress object, and an error if there is any. +func (c *iPAddresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Get(). + Resource("ipaddresses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of IPAddresses that match those selectors. +func (c *iPAddresses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.IPAddressList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.IPAddressList{} + err = c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested iPAddresses. +func (c *iPAddresses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a iPAddress and creates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Post(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a iPAddress and updates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Put(). + Resource("ipaddresses"). + Name(iPAddress.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the iPAddress and deletes it. Returns an error if one occurs. +func (c *iPAddresses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("ipaddresses"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *iPAddresses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("ipaddresses"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched iPAddress. +func (c *iPAddresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Patch(pt). + Resource("ipaddresses"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied iPAddress. +func (c *iPAddresses) Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) { + if iPAddress == nil { + return nil, fmt.Errorf("iPAddress provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(iPAddress) + if err != nil { + return nil, err + } + name := iPAddress.Name + if name == nil { + return nil, fmt.Errorf("iPAddress.Name must be provided to Apply") + } + result = &v1alpha1.IPAddress{} + err = c.client.Patch(types.ApplyPatchType). + Resource("ipaddresses"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go new file mode 100644 index 00000000000..884c846f598 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go @@ -0,0 +1,112 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type NetworkingV1alpha1Interface interface { + RESTClient() rest.Interface + ClusterCIDRsGetter + IPAddressesGetter +} + +// NetworkingV1alpha1Client is used to interact with features provided by the networking.k8s.io group. +type NetworkingV1alpha1Client struct { + restClient rest.Interface +} + +func (c *NetworkingV1alpha1Client) ClusterCIDRs() ClusterCIDRInterface { + return newClusterCIDRs(c) +} + +func (c *NetworkingV1alpha1Client) IPAddresses() IPAddressInterface { + return newIPAddresses(c) +} + +// NewForConfig creates a new NetworkingV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*NetworkingV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new NetworkingV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*NetworkingV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &NetworkingV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new NetworkingV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *NetworkingV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new NetworkingV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *NetworkingV1alpha1Client { + return &NetworkingV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *NetworkingV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go new file mode 100644 index 00000000000..baaf2d98537 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha2 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go new file mode 100644 index 00000000000..2c02e9ce74e --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +type PodSchedulingContextExpansion interface{} + +type ResourceClaimExpansion interface{} + +type ResourceClaimTemplateExpansion interface{} + +type ResourceClassExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 00000000000..72e81a29e31 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,256 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// PodSchedulingContextsGetter has a method to return a PodSchedulingContextInterface. +// A group's client should implement this interface. +type PodSchedulingContextsGetter interface { + PodSchedulingContexts(namespace string) PodSchedulingContextInterface +} + +// PodSchedulingContextInterface has methods to work with PodSchedulingContext resources. +type PodSchedulingContextInterface interface { + Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (*v1alpha2.PodSchedulingContext, error) + Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.PodSchedulingContext, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.PodSchedulingContextList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) + Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + PodSchedulingContextExpansion +} + +// podSchedulingContexts implements PodSchedulingContextInterface +type podSchedulingContexts struct { + client rest.Interface + ns string +} + +// newPodSchedulingContexts returns a PodSchedulingContexts +func newPodSchedulingContexts(c *ResourceV1alpha2Client, namespace string) *podSchedulingContexts { + return &podSchedulingContexts{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the podSchedulingContext, and returns the corresponding podSchedulingContext object, and an error if there is any. +func (c *podSchedulingContexts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PodSchedulingContexts that match those selectors. +func (c *podSchedulingContexts) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.PodSchedulingContextList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.PodSchedulingContextList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested podSchedulingContexts. +func (c *podSchedulingContexts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a podSchedulingContext and creates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Post(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a podSchedulingContext and updates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *podSchedulingContexts) UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the podSchedulingContext and deletes it. Returns an error if one occurs. +func (c *podSchedulingContexts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *podSchedulingContexts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched podSchedulingContext. +func (c *podSchedulingContexts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied podSchedulingContext. +func (c *podSchedulingContexts) Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *podSchedulingContexts) ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go new file mode 100644 index 00000000000..d5795fd6286 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go @@ -0,0 +1,122 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "net/http" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type ResourceV1alpha2Interface interface { + RESTClient() rest.Interface + PodSchedulingContextsGetter + ResourceClaimsGetter + ResourceClaimTemplatesGetter + ResourceClassesGetter +} + +// ResourceV1alpha2Client is used to interact with features provided by the resource.k8s.io group. +type ResourceV1alpha2Client struct { + restClient rest.Interface +} + +func (c *ResourceV1alpha2Client) PodSchedulingContexts(namespace string) PodSchedulingContextInterface { + return newPodSchedulingContexts(c, namespace) +} + +func (c *ResourceV1alpha2Client) ResourceClaims(namespace string) ResourceClaimInterface { + return newResourceClaims(c, namespace) +} + +func (c *ResourceV1alpha2Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { + return newResourceClaimTemplates(c, namespace) +} + +func (c *ResourceV1alpha2Client) ResourceClasses() ResourceClassInterface { + return newResourceClasses(c) +} + +// NewForConfig creates a new ResourceV1alpha2Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*ResourceV1alpha2Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new ResourceV1alpha2Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha2Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &ResourceV1alpha2Client{client}, nil +} + +// NewForConfigOrDie creates a new ResourceV1alpha2Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha2Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ResourceV1alpha2Client for the given RESTClient. +func New(c rest.Interface) *ResourceV1alpha2Client { + return &ResourceV1alpha2Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha2.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *ResourceV1alpha2Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go new file mode 100644 index 00000000000..cfb27c9db68 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go @@ -0,0 +1,256 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceClaimsGetter has a method to return a ResourceClaimInterface. +// A group's client should implement this interface. +type ResourceClaimsGetter interface { + ResourceClaims(namespace string) ResourceClaimInterface +} + +// ResourceClaimInterface has methods to work with ResourceClaim resources. +type ResourceClaimInterface interface { + Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (*v1alpha2.ResourceClaim, error) + Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) + UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaim, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) + Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) + ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) + ResourceClaimExpansion +} + +// resourceClaims implements ResourceClaimInterface +type resourceClaims struct { + client rest.Interface + ns string +} + +// newResourceClaims returns a ResourceClaims +func newResourceClaims(c *ResourceV1alpha2Client, namespace string) *resourceClaims { + return &resourceClaims{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the resourceClaim, and returns the corresponding resourceClaim object, and an error if there is any. +func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaims"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceClaims that match those selectors. +func (c *resourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceClaimList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaims"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceClaims. +func (c *resourceClaims) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("resourceclaims"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceClaim and creates it. Returns the server's representation of the resourceClaim, and an error, if there is any. +func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} + err = c.client.Post(). + Namespace(c.ns). + Resource("resourceclaims"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaim). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceClaim and updates it. Returns the server's representation of the resourceClaim, and an error, if there is any. +func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} + err = c.client.Put(). + Namespace(c.ns). + Resource("resourceclaims"). + Name(resourceClaim.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaim). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *resourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} + err = c.client.Put(). + Namespace(c.ns). + Resource("resourceclaims"). + Name(resourceClaim.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaim). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceClaim and deletes it. Returns an error if one occurs. +func (c *resourceClaims) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaims"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceClaims) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaims"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceClaim. +func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("resourceclaims"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaim. +func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { + if resourceClaim == nil { + return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClaim) + if err != nil { + return nil, err + } + name := resourceClaim.Name + if name == nil { + return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") + } + result = &v1alpha2.ResourceClaim{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("resourceclaims"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { + if resourceClaim == nil { + return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClaim) + if err != nil { + return nil, err + } + + name := resourceClaim.Name + if name == nil { + return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") + } + + result = &v1alpha2.ResourceClaim{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("resourceclaims"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go new file mode 100644 index 00000000000..3f4e3200642 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go @@ -0,0 +1,208 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceClaimTemplatesGetter has a method to return a ResourceClaimTemplateInterface. +// A group's client should implement this interface. +type ResourceClaimTemplatesGetter interface { + ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface +} + +// ResourceClaimTemplateInterface has methods to work with ResourceClaimTemplate resources. +type ResourceClaimTemplateInterface interface { + Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (*v1alpha2.ResourceClaimTemplate, error) + Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (*v1alpha2.ResourceClaimTemplate, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaimTemplate, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimTemplateList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) + Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) + ResourceClaimTemplateExpansion +} + +// resourceClaimTemplates implements ResourceClaimTemplateInterface +type resourceClaimTemplates struct { + client rest.Interface + ns string +} + +// newResourceClaimTemplates returns a ResourceClaimTemplates +func newResourceClaimTemplates(c *ResourceV1alpha2Client, namespace string) *resourceClaimTemplates { + return &resourceClaimTemplates{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the resourceClaimTemplate, and returns the corresponding resourceClaimTemplate object, and an error if there is any. +func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceClaimTemplates that match those selectors. +func (c *resourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimTemplateList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceClaimTemplateList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceClaimTemplates. +func (c *resourceClaimTemplates) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceClaimTemplate and creates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. +func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} + err = c.client.Post(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaimTemplate). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceClaimTemplate and updates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. +func (c *resourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} + err = c.client.Put(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + Name(resourceClaimTemplate.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClaimTemplate). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceClaimTemplate and deletes it. Returns an error if one occurs. +func (c *resourceClaimTemplates) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceClaimTemplates) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceClaimTemplate. +func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimTemplate. +func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + if resourceClaimTemplate == nil { + return nil, fmt.Errorf("resourceClaimTemplate provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClaimTemplate) + if err != nil { + return nil, err + } + name := resourceClaimTemplate.Name + if name == nil { + return nil, fmt.Errorf("resourceClaimTemplate.Name must be provided to Apply") + } + result = &v1alpha2.ResourceClaimTemplate{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("resourceclaimtemplates"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go new file mode 100644 index 00000000000..95a4ac5668e --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go @@ -0,0 +1,197 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ResourceClassesGetter has a method to return a ResourceClassInterface. +// A group's client should implement this interface. +type ResourceClassesGetter interface { + ResourceClasses() ResourceClassInterface +} + +// ResourceClassInterface has methods to work with ResourceClass resources. +type ResourceClassInterface interface { + Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (*v1alpha2.ResourceClass, error) + Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (*v1alpha2.ResourceClass, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClass, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClassList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) + Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) + ResourceClassExpansion +} + +// resourceClasses implements ResourceClassInterface +type resourceClasses struct { + client rest.Interface +} + +// newResourceClasses returns a ResourceClasses +func newResourceClasses(c *ResourceV1alpha2Client) *resourceClasses { + return &resourceClasses{ + client: c.RESTClient(), + } +} + +// Get takes name of the resourceClass, and returns the corresponding resourceClass object, and an error if there is any. +func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} + err = c.client.Get(). + Resource("resourceclasses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ResourceClasses that match those selectors. +func (c *resourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.ResourceClassList{} + err = c.client.Get(). + Resource("resourceclasses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested resourceClasses. +func (c *resourceClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("resourceclasses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a resourceClass and creates it. Returns the server's representation of the resourceClass, and an error, if there is any. +func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} + err = c.client.Post(). + Resource("resourceclasses"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClass). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a resourceClass and updates it. Returns the server's representation of the resourceClass, and an error, if there is any. +func (c *resourceClasses) Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} + err = c.client.Put(). + Resource("resourceclasses"). + Name(resourceClass.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(resourceClass). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the resourceClass and deletes it. Returns an error if one occurs. +func (c *resourceClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("resourceclasses"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *resourceClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("resourceclasses"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched resourceClass. +func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} + err = c.client.Patch(pt). + Resource("resourceclasses"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied resourceClass. +func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) { + if resourceClass == nil { + return nil, fmt.Errorf("resourceClass provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(resourceClass) + if err != nil { + return nil, err + } + name := resourceClass.Name + if name == nil { + return nil, fmt.Errorf("resourceClass.Name must be provided to Apply") + } + result = &v1alpha2.ResourceClass{} + err = c.client.Patch(types.ApplyPatchType). + Resource("resourceclasses"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go new file mode 100644 index 00000000000..e121ae41a3e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// MutatingWebhookConfigurationListerExpansion allows custom methods to be added to +// MutatingWebhookConfigurationLister. +type MutatingWebhookConfigurationListerExpansion interface{} + +// ValidatingWebhookConfigurationListerExpansion allows custom methods to be added to +// ValidatingWebhookConfigurationLister. +type ValidatingWebhookConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingwebhookconfiguration.go new file mode 100644 index 00000000000..fe9e27985de --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingwebhookconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// MutatingWebhookConfigurationLister helps list MutatingWebhookConfigurations. +// All objects returned here must be treated as read-only. +type MutatingWebhookConfigurationLister interface { + // List lists all MutatingWebhookConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.MutatingWebhookConfiguration, err error) + // Get retrieves the MutatingWebhookConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.MutatingWebhookConfiguration, error) + MutatingWebhookConfigurationListerExpansion +} + +// mutatingWebhookConfigurationLister implements the MutatingWebhookConfigurationLister interface. +type mutatingWebhookConfigurationLister struct { + indexer cache.Indexer +} + +// NewMutatingWebhookConfigurationLister returns a new MutatingWebhookConfigurationLister. +func NewMutatingWebhookConfigurationLister(indexer cache.Indexer) MutatingWebhookConfigurationLister { + return &mutatingWebhookConfigurationLister{indexer: indexer} +} + +// List lists all MutatingWebhookConfigurations in the indexer. +func (s *mutatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*v1.MutatingWebhookConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.MutatingWebhookConfiguration)) + }) + return ret, err +} + +// Get retrieves the MutatingWebhookConfiguration from the index for a given name. +func (s *mutatingWebhookConfigurationLister) Get(name string) (*v1.MutatingWebhookConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("mutatingwebhookconfiguration"), name) + } + return obj.(*v1.MutatingWebhookConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/validatingwebhookconfiguration.go new file mode 100644 index 00000000000..1579a0ebb76 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/validatingwebhookconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ValidatingWebhookConfigurationLister helps list ValidatingWebhookConfigurations. +// All objects returned here must be treated as read-only. +type ValidatingWebhookConfigurationLister interface { + // List lists all ValidatingWebhookConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ValidatingWebhookConfiguration, err error) + // Get retrieves the ValidatingWebhookConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ValidatingWebhookConfiguration, error) + ValidatingWebhookConfigurationListerExpansion +} + +// validatingWebhookConfigurationLister implements the ValidatingWebhookConfigurationLister interface. +type validatingWebhookConfigurationLister struct { + indexer cache.Indexer +} + +// NewValidatingWebhookConfigurationLister returns a new ValidatingWebhookConfigurationLister. +func NewValidatingWebhookConfigurationLister(indexer cache.Indexer) ValidatingWebhookConfigurationLister { + return &validatingWebhookConfigurationLister{indexer: indexer} +} + +// List lists all ValidatingWebhookConfigurations in the indexer. +func (s *validatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*v1.ValidatingWebhookConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ValidatingWebhookConfiguration)) + }) + return ret, err +} + +// Get retrieves the ValidatingWebhookConfiguration from the index for a given name. +func (s *validatingWebhookConfigurationLister) Get(name string) (*v1.ValidatingWebhookConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("validatingwebhookconfiguration"), name) + } + return obj.(*v1.ValidatingWebhookConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..3f8b7819ce0 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ValidatingAdmissionPolicyListerExpansion allows custom methods to be added to +// ValidatingAdmissionPolicyLister. +type ValidatingAdmissionPolicyListerExpansion interface{} + +// ValidatingAdmissionPolicyBindingListerExpansion allows custom methods to be added to +// ValidatingAdmissionPolicyBindingLister. +type ValidatingAdmissionPolicyBindingListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicy.go new file mode 100644 index 00000000000..ae500183a7a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ValidatingAdmissionPolicyLister helps list ValidatingAdmissionPolicies. +// All objects returned here must be treated as read-only. +type ValidatingAdmissionPolicyLister interface { + // List lists all ValidatingAdmissionPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ValidatingAdmissionPolicy, err error) + // Get retrieves the ValidatingAdmissionPolicy from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ValidatingAdmissionPolicy, error) + ValidatingAdmissionPolicyListerExpansion +} + +// validatingAdmissionPolicyLister implements the ValidatingAdmissionPolicyLister interface. +type validatingAdmissionPolicyLister struct { + indexer cache.Indexer +} + +// NewValidatingAdmissionPolicyLister returns a new ValidatingAdmissionPolicyLister. +func NewValidatingAdmissionPolicyLister(indexer cache.Indexer) ValidatingAdmissionPolicyLister { + return &validatingAdmissionPolicyLister{indexer: indexer} +} + +// List lists all ValidatingAdmissionPolicies in the indexer. +func (s *validatingAdmissionPolicyLister) List(selector labels.Selector) (ret []*v1alpha1.ValidatingAdmissionPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ValidatingAdmissionPolicy)) + }) + return ret, err +} + +// Get retrieves the ValidatingAdmissionPolicy from the index for a given name. +func (s *validatingAdmissionPolicyLister) Get(name string) (*v1alpha1.ValidatingAdmissionPolicy, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("validatingadmissionpolicy"), name) + } + return obj.(*v1alpha1.ValidatingAdmissionPolicy), nil +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go new file mode 100644 index 00000000000..552854daf26 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ValidatingAdmissionPolicyBindingLister helps list ValidatingAdmissionPolicyBindings. +// All objects returned here must be treated as read-only. +type ValidatingAdmissionPolicyBindingLister interface { + // List lists all ValidatingAdmissionPolicyBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ValidatingAdmissionPolicyBinding, err error) + // Get retrieves the ValidatingAdmissionPolicyBinding from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) + ValidatingAdmissionPolicyBindingListerExpansion +} + +// validatingAdmissionPolicyBindingLister implements the ValidatingAdmissionPolicyBindingLister interface. +type validatingAdmissionPolicyBindingLister struct { + indexer cache.Indexer +} + +// NewValidatingAdmissionPolicyBindingLister returns a new ValidatingAdmissionPolicyBindingLister. +func NewValidatingAdmissionPolicyBindingLister(indexer cache.Indexer) ValidatingAdmissionPolicyBindingLister { + return &validatingAdmissionPolicyBindingLister{indexer: indexer} +} + +// List lists all ValidatingAdmissionPolicyBindings in the indexer. +func (s *validatingAdmissionPolicyBindingLister) List(selector labels.Selector) (ret []*v1alpha1.ValidatingAdmissionPolicyBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ValidatingAdmissionPolicyBinding)) + }) + return ret, err +} + +// Get retrieves the ValidatingAdmissionPolicyBinding from the index for a given name. +func (s *validatingAdmissionPolicyBindingLister) Get(name string) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("validatingadmissionpolicybinding"), name) + } + return obj.(*v1alpha1.ValidatingAdmissionPolicyBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..8960abc4f48 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// MutatingWebhookConfigurationListerExpansion allows custom methods to be added to +// MutatingWebhookConfigurationLister. +type MutatingWebhookConfigurationListerExpansion interface{} + +// ValidatingWebhookConfigurationListerExpansion allows custom methods to be added to +// ValidatingWebhookConfigurationLister. +type ValidatingWebhookConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go new file mode 100644 index 00000000000..93c6096ee9e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/admissionregistration/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// MutatingWebhookConfigurationLister helps list MutatingWebhookConfigurations. +// All objects returned here must be treated as read-only. +type MutatingWebhookConfigurationLister interface { + // List lists all MutatingWebhookConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.MutatingWebhookConfiguration, err error) + // Get retrieves the MutatingWebhookConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.MutatingWebhookConfiguration, error) + MutatingWebhookConfigurationListerExpansion +} + +// mutatingWebhookConfigurationLister implements the MutatingWebhookConfigurationLister interface. +type mutatingWebhookConfigurationLister struct { + indexer cache.Indexer +} + +// NewMutatingWebhookConfigurationLister returns a new MutatingWebhookConfigurationLister. +func NewMutatingWebhookConfigurationLister(indexer cache.Indexer) MutatingWebhookConfigurationLister { + return &mutatingWebhookConfigurationLister{indexer: indexer} +} + +// List lists all MutatingWebhookConfigurations in the indexer. +func (s *mutatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*v1beta1.MutatingWebhookConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.MutatingWebhookConfiguration)) + }) + return ret, err +} + +// Get retrieves the MutatingWebhookConfiguration from the index for a given name. +func (s *mutatingWebhookConfigurationLister) Get(name string) (*v1beta1.MutatingWebhookConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("mutatingwebhookconfiguration"), name) + } + return obj.(*v1beta1.MutatingWebhookConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/validatingwebhookconfiguration.go new file mode 100644 index 00000000000..7c17fccb2e2 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1beta1/validatingwebhookconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/admissionregistration/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ValidatingWebhookConfigurationLister helps list ValidatingWebhookConfigurations. +// All objects returned here must be treated as read-only. +type ValidatingWebhookConfigurationLister interface { + // List lists all ValidatingWebhookConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ValidatingWebhookConfiguration, err error) + // Get retrieves the ValidatingWebhookConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ValidatingWebhookConfiguration, error) + ValidatingWebhookConfigurationListerExpansion +} + +// validatingWebhookConfigurationLister implements the ValidatingWebhookConfigurationLister interface. +type validatingWebhookConfigurationLister struct { + indexer cache.Indexer +} + +// NewValidatingWebhookConfigurationLister returns a new ValidatingWebhookConfigurationLister. +func NewValidatingWebhookConfigurationLister(indexer cache.Indexer) ValidatingWebhookConfigurationLister { + return &validatingWebhookConfigurationLister{indexer: indexer} +} + +// List lists all ValidatingWebhookConfigurations in the indexer. +func (s *validatingWebhookConfigurationLister) List(selector labels.Selector) (ret []*v1beta1.ValidatingWebhookConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ValidatingWebhookConfiguration)) + }) + return ret, err +} + +// Get retrieves the ValidatingWebhookConfiguration from the index for a given name. +func (s *validatingWebhookConfigurationLister) Get(name string) (*v1beta1.ValidatingWebhookConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("validatingwebhookconfiguration"), name) + } + return obj.(*v1beta1.ValidatingWebhookConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..ad860c7c959 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// StorageVersionListerExpansion allows custom methods to be added to +// StorageVersionLister. +type StorageVersionListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/storageversion.go b/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/storageversion.go new file mode 100644 index 00000000000..9a6d74b2bf5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apiserverinternal/v1alpha1/storageversion.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StorageVersionLister helps list StorageVersions. +// All objects returned here must be treated as read-only. +type StorageVersionLister interface { + // List lists all StorageVersions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.StorageVersion, err error) + // Get retrieves the StorageVersion from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.StorageVersion, error) + StorageVersionListerExpansion +} + +// storageVersionLister implements the StorageVersionLister interface. +type storageVersionLister struct { + indexer cache.Indexer +} + +// NewStorageVersionLister returns a new StorageVersionLister. +func NewStorageVersionLister(indexer cache.Indexer) StorageVersionLister { + return &storageVersionLister{indexer: indexer} +} + +// List lists all StorageVersions in the indexer. +func (s *storageVersionLister) List(selector labels.Selector) (ret []*v1alpha1.StorageVersion, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.StorageVersion)) + }) + return ret, err +} + +// Get retrieves the StorageVersion from the index for a given name. +func (s *storageVersionLister) Get(name string) (*v1alpha1.StorageVersion, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("storageversion"), name) + } + return obj.(*v1alpha1.StorageVersion), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/controllerrevision.go b/vendor/k8s.io/client-go/listers/apps/v1/controllerrevision.go new file mode 100644 index 00000000000..9e2f973746b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/controllerrevision.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionLister helps list ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionLister interface { + // List lists all ControllerRevisions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ControllerRevision, err error) + // ControllerRevisions returns an object that can list and get ControllerRevisions. + ControllerRevisions(namespace string) ControllerRevisionNamespaceLister + ControllerRevisionListerExpansion +} + +// controllerRevisionLister implements the ControllerRevisionLister interface. +type controllerRevisionLister struct { + indexer cache.Indexer +} + +// NewControllerRevisionLister returns a new ControllerRevisionLister. +func NewControllerRevisionLister(indexer cache.Indexer) ControllerRevisionLister { + return &controllerRevisionLister{indexer: indexer} +} + +// List lists all ControllerRevisions in the indexer. +func (s *controllerRevisionLister) List(selector labels.Selector) (ret []*v1.ControllerRevision, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ControllerRevision)) + }) + return ret, err +} + +// ControllerRevisions returns an object that can list and get ControllerRevisions. +func (s *controllerRevisionLister) ControllerRevisions(namespace string) ControllerRevisionNamespaceLister { + return controllerRevisionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ControllerRevisionNamespaceLister helps list and get ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionNamespaceLister interface { + // List lists all ControllerRevisions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ControllerRevision, err error) + // Get retrieves the ControllerRevision from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ControllerRevision, error) + ControllerRevisionNamespaceListerExpansion +} + +// controllerRevisionNamespaceLister implements the ControllerRevisionNamespaceLister +// interface. +type controllerRevisionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ControllerRevisions in the indexer for a given namespace. +func (s controllerRevisionNamespaceLister) List(selector labels.Selector) (ret []*v1.ControllerRevision, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ControllerRevision)) + }) + return ret, err +} + +// Get retrieves the ControllerRevision from the indexer for a given namespace and name. +func (s controllerRevisionNamespaceLister) Get(name string) (*v1.ControllerRevision, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("controllerrevision"), name) + } + return obj.(*v1.ControllerRevision), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/daemonset.go b/vendor/k8s.io/client-go/listers/apps/v1/daemonset.go new file mode 100644 index 00000000000..061959e3daf --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/daemonset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DaemonSetLister helps list DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetLister interface { + // List lists all DaemonSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.DaemonSet, err error) + // DaemonSets returns an object that can list and get DaemonSets. + DaemonSets(namespace string) DaemonSetNamespaceLister + DaemonSetListerExpansion +} + +// daemonSetLister implements the DaemonSetLister interface. +type daemonSetLister struct { + indexer cache.Indexer +} + +// NewDaemonSetLister returns a new DaemonSetLister. +func NewDaemonSetLister(indexer cache.Indexer) DaemonSetLister { + return &daemonSetLister{indexer: indexer} +} + +// List lists all DaemonSets in the indexer. +func (s *daemonSetLister) List(selector labels.Selector) (ret []*v1.DaemonSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.DaemonSet)) + }) + return ret, err +} + +// DaemonSets returns an object that can list and get DaemonSets. +func (s *daemonSetLister) DaemonSets(namespace string) DaemonSetNamespaceLister { + return daemonSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DaemonSetNamespaceLister helps list and get DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetNamespaceLister interface { + // List lists all DaemonSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.DaemonSet, err error) + // Get retrieves the DaemonSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.DaemonSet, error) + DaemonSetNamespaceListerExpansion +} + +// daemonSetNamespaceLister implements the DaemonSetNamespaceLister +// interface. +type daemonSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all DaemonSets in the indexer for a given namespace. +func (s daemonSetNamespaceLister) List(selector labels.Selector) (ret []*v1.DaemonSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.DaemonSet)) + }) + return ret, err +} + +// Get retrieves the DaemonSet from the indexer for a given namespace and name. +func (s daemonSetNamespaceLister) Get(name string) (*v1.DaemonSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("daemonset"), name) + } + return obj.(*v1.DaemonSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/daemonset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1/daemonset_expansion.go new file mode 100644 index 00000000000..667d6fb88ea --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/daemonset_expansion.go @@ -0,0 +1,114 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// DaemonSetListerExpansion allows custom methods to be added to +// DaemonSetLister. +type DaemonSetListerExpansion interface { + GetPodDaemonSets(pod *v1.Pod) ([]*apps.DaemonSet, error) + GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*apps.DaemonSet, error) +} + +// DaemonSetNamespaceListerExpansion allows custom methods to be added to +// DaemonSetNamespaceLister. +type DaemonSetNamespaceListerExpansion interface{} + +// GetPodDaemonSets returns a list of DaemonSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetPodDaemonSets(pod *v1.Pod) ([]*apps.DaemonSet, error) { + var selector labels.Selector + var daemonSet *apps.DaemonSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.DaemonSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*apps.DaemonSet + for i := range list { + daemonSet = list[i] + if daemonSet.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + daemonSets = append(daemonSets, daemonSet) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return daemonSets, nil +} + +// GetHistoryDaemonSets returns a list of DaemonSets that potentially +// match a ControllerRevision. Only the one specified in the ControllerRevision's ControllerRef +// will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*apps.DaemonSet, error) { + if len(history.Labels) == 0 { + return nil, fmt.Errorf("no DaemonSet found for ControllerRevision %s because it has no labels", history.Name) + } + + list, err := s.DaemonSets(history.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*apps.DaemonSet + for _, ds := range list { + selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the history + continue + } + // If a DaemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(history.Labels)) { + continue + } + daemonSets = append(daemonSets, ds) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find DaemonSets for ControllerRevision %s in namespace %s with labels: %v", history.Name, history.Namespace, history.Labels) + } + + return daemonSets, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/deployment.go b/vendor/k8s.io/client-go/listers/apps/v1/deployment.go new file mode 100644 index 00000000000..77040341729 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/deployment.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DeploymentLister helps list Deployments. +// All objects returned here must be treated as read-only. +type DeploymentLister interface { + // List lists all Deployments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Deployment, err error) + // Deployments returns an object that can list and get Deployments. + Deployments(namespace string) DeploymentNamespaceLister + DeploymentListerExpansion +} + +// deploymentLister implements the DeploymentLister interface. +type deploymentLister struct { + indexer cache.Indexer +} + +// NewDeploymentLister returns a new DeploymentLister. +func NewDeploymentLister(indexer cache.Indexer) DeploymentLister { + return &deploymentLister{indexer: indexer} +} + +// List lists all Deployments in the indexer. +func (s *deploymentLister) List(selector labels.Selector) (ret []*v1.Deployment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Deployment)) + }) + return ret, err +} + +// Deployments returns an object that can list and get Deployments. +func (s *deploymentLister) Deployments(namespace string) DeploymentNamespaceLister { + return deploymentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DeploymentNamespaceLister helps list and get Deployments. +// All objects returned here must be treated as read-only. +type DeploymentNamespaceLister interface { + // List lists all Deployments in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Deployment, err error) + // Get retrieves the Deployment from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Deployment, error) + DeploymentNamespaceListerExpansion +} + +// deploymentNamespaceLister implements the DeploymentNamespaceLister +// interface. +type deploymentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Deployments in the indexer for a given namespace. +func (s deploymentNamespaceLister) List(selector labels.Selector) (ret []*v1.Deployment, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Deployment)) + }) + return ret, err +} + +// Get retrieves the Deployment from the indexer for a given namespace and name. +func (s deploymentNamespaceLister) Get(name string) (*v1.Deployment, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("deployment"), name) + } + return obj.(*v1.Deployment), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/apps/v1/expansion_generated.go new file mode 100644 index 00000000000..0c357589d07 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/expansion_generated.go @@ -0,0 +1,35 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// ControllerRevisionListerExpansion allows custom methods to be added to +// ControllerRevisionLister. +type ControllerRevisionListerExpansion interface{} + +// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to +// ControllerRevisionNamespaceLister. +type ControllerRevisionNamespaceListerExpansion interface{} + +// DeploymentListerExpansion allows custom methods to be added to +// DeploymentLister. +type DeploymentListerExpansion interface{} + +// DeploymentNamespaceListerExpansion allows custom methods to be added to +// DeploymentNamespaceLister. +type DeploymentNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/replicaset.go b/vendor/k8s.io/client-go/listers/apps/v1/replicaset.go new file mode 100644 index 00000000000..3ca7757eb94 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/replicaset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ReplicaSetLister helps list ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetLister interface { + // List lists all ReplicaSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ReplicaSet, err error) + // ReplicaSets returns an object that can list and get ReplicaSets. + ReplicaSets(namespace string) ReplicaSetNamespaceLister + ReplicaSetListerExpansion +} + +// replicaSetLister implements the ReplicaSetLister interface. +type replicaSetLister struct { + indexer cache.Indexer +} + +// NewReplicaSetLister returns a new ReplicaSetLister. +func NewReplicaSetLister(indexer cache.Indexer) ReplicaSetLister { + return &replicaSetLister{indexer: indexer} +} + +// List lists all ReplicaSets in the indexer. +func (s *replicaSetLister) List(selector labels.Selector) (ret []*v1.ReplicaSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ReplicaSet)) + }) + return ret, err +} + +// ReplicaSets returns an object that can list and get ReplicaSets. +func (s *replicaSetLister) ReplicaSets(namespace string) ReplicaSetNamespaceLister { + return replicaSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ReplicaSetNamespaceLister helps list and get ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetNamespaceLister interface { + // List lists all ReplicaSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ReplicaSet, err error) + // Get retrieves the ReplicaSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ReplicaSet, error) + ReplicaSetNamespaceListerExpansion +} + +// replicaSetNamespaceLister implements the ReplicaSetNamespaceLister +// interface. +type replicaSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ReplicaSets in the indexer for a given namespace. +func (s replicaSetNamespaceLister) List(selector labels.Selector) (ret []*v1.ReplicaSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ReplicaSet)) + }) + return ret, err +} + +// Get retrieves the ReplicaSet from the indexer for a given namespace and name. +func (s replicaSetNamespaceLister) Get(name string) (*v1.ReplicaSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("replicaset"), name) + } + return obj.(*v1.ReplicaSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/replicaset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1/replicaset_expansion.go new file mode 100644 index 00000000000..8e093de0a01 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/replicaset_expansion.go @@ -0,0 +1,74 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// ReplicaSetListerExpansion allows custom methods to be added to +// ReplicaSetLister. +type ReplicaSetListerExpansion interface { + GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) +} + +// ReplicaSetNamespaceListerExpansion allows custom methods to be added to +// ReplicaSetNamespaceLister. +type ReplicaSetNamespaceListerExpansion interface{} + +// GetPodReplicaSets returns a list of ReplicaSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching ReplicaSets are found. +func (s *replicaSetLister) GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) { + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var rss []*apps.ReplicaSet + for _, rs := range list { + if rs.Namespace != pod.Namespace { + continue + } + selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + rss = append(rss, rs) + } + + if len(rss) == 0 { + return nil, fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return rss, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/statefulset.go b/vendor/k8s.io/client-go/listers/apps/v1/statefulset.go new file mode 100644 index 00000000000..f6899d5ff9b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/statefulset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StatefulSetLister helps list StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetLister interface { + // List lists all StatefulSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.StatefulSet, err error) + // StatefulSets returns an object that can list and get StatefulSets. + StatefulSets(namespace string) StatefulSetNamespaceLister + StatefulSetListerExpansion +} + +// statefulSetLister implements the StatefulSetLister interface. +type statefulSetLister struct { + indexer cache.Indexer +} + +// NewStatefulSetLister returns a new StatefulSetLister. +func NewStatefulSetLister(indexer cache.Indexer) StatefulSetLister { + return &statefulSetLister{indexer: indexer} +} + +// List lists all StatefulSets in the indexer. +func (s *statefulSetLister) List(selector labels.Selector) (ret []*v1.StatefulSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.StatefulSet)) + }) + return ret, err +} + +// StatefulSets returns an object that can list and get StatefulSets. +func (s *statefulSetLister) StatefulSets(namespace string) StatefulSetNamespaceLister { + return statefulSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// StatefulSetNamespaceLister helps list and get StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetNamespaceLister interface { + // List lists all StatefulSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.StatefulSet, err error) + // Get retrieves the StatefulSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.StatefulSet, error) + StatefulSetNamespaceListerExpansion +} + +// statefulSetNamespaceLister implements the StatefulSetNamespaceLister +// interface. +type statefulSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all StatefulSets in the indexer for a given namespace. +func (s statefulSetNamespaceLister) List(selector labels.Selector) (ret []*v1.StatefulSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.StatefulSet)) + }) + return ret, err +} + +// Get retrieves the StatefulSet from the indexer for a given namespace and name. +func (s statefulSetNamespaceLister) Get(name string) (*v1.StatefulSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("statefulset"), name) + } + return obj.(*v1.StatefulSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1/statefulset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1/statefulset_expansion.go new file mode 100644 index 00000000000..e79f8a2b46a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1/statefulset_expansion.go @@ -0,0 +1,78 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// StatefulSetListerExpansion allows custom methods to be added to +// StatefulSetLister. +type StatefulSetListerExpansion interface { + GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) +} + +// StatefulSetNamespaceListerExpansion allows custom methods to be added to +// StatefulSetNamespaceLister. +type StatefulSetNamespaceListerExpansion interface{} + +// GetPodStatefulSets returns a list of StatefulSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching StatefulSets are found. +func (s *statefulSetLister) GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) { + var selector labels.Selector + var ps *apps.StatefulSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.StatefulSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var psList []*apps.StatefulSet + for i := range list { + ps = list[i] + if ps.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + psList = append(psList, ps) + } + + if len(psList) == 0 { + return nil, fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return psList, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta1/controllerrevision.go b/vendor/k8s.io/client-go/listers/apps/v1beta1/controllerrevision.go new file mode 100644 index 00000000000..fc73de723fe --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta1/controllerrevision.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/apps/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionLister helps list ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionLister interface { + // List lists all ControllerRevisions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ControllerRevision, err error) + // ControllerRevisions returns an object that can list and get ControllerRevisions. + ControllerRevisions(namespace string) ControllerRevisionNamespaceLister + ControllerRevisionListerExpansion +} + +// controllerRevisionLister implements the ControllerRevisionLister interface. +type controllerRevisionLister struct { + indexer cache.Indexer +} + +// NewControllerRevisionLister returns a new ControllerRevisionLister. +func NewControllerRevisionLister(indexer cache.Indexer) ControllerRevisionLister { + return &controllerRevisionLister{indexer: indexer} +} + +// List lists all ControllerRevisions in the indexer. +func (s *controllerRevisionLister) List(selector labels.Selector) (ret []*v1beta1.ControllerRevision, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ControllerRevision)) + }) + return ret, err +} + +// ControllerRevisions returns an object that can list and get ControllerRevisions. +func (s *controllerRevisionLister) ControllerRevisions(namespace string) ControllerRevisionNamespaceLister { + return controllerRevisionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ControllerRevisionNamespaceLister helps list and get ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionNamespaceLister interface { + // List lists all ControllerRevisions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ControllerRevision, err error) + // Get retrieves the ControllerRevision from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ControllerRevision, error) + ControllerRevisionNamespaceListerExpansion +} + +// controllerRevisionNamespaceLister implements the ControllerRevisionNamespaceLister +// interface. +type controllerRevisionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ControllerRevisions in the indexer for a given namespace. +func (s controllerRevisionNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ControllerRevision, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ControllerRevision)) + }) + return ret, err +} + +// Get retrieves the ControllerRevision from the indexer for a given namespace and name. +func (s controllerRevisionNamespaceLister) Get(name string) (*v1beta1.ControllerRevision, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("controllerrevision"), name) + } + return obj.(*v1beta1.ControllerRevision), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta1/deployment.go b/vendor/k8s.io/client-go/listers/apps/v1beta1/deployment.go new file mode 100644 index 00000000000..3fb70794cad --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta1/deployment.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/apps/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DeploymentLister helps list Deployments. +// All objects returned here must be treated as read-only. +type DeploymentLister interface { + // List lists all Deployments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) + // Deployments returns an object that can list and get Deployments. + Deployments(namespace string) DeploymentNamespaceLister + DeploymentListerExpansion +} + +// deploymentLister implements the DeploymentLister interface. +type deploymentLister struct { + indexer cache.Indexer +} + +// NewDeploymentLister returns a new DeploymentLister. +func NewDeploymentLister(indexer cache.Indexer) DeploymentLister { + return &deploymentLister{indexer: indexer} +} + +// List lists all Deployments in the indexer. +func (s *deploymentLister) List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Deployment)) + }) + return ret, err +} + +// Deployments returns an object that can list and get Deployments. +func (s *deploymentLister) Deployments(namespace string) DeploymentNamespaceLister { + return deploymentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DeploymentNamespaceLister helps list and get Deployments. +// All objects returned here must be treated as read-only. +type DeploymentNamespaceLister interface { + // List lists all Deployments in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) + // Get retrieves the Deployment from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Deployment, error) + DeploymentNamespaceListerExpansion +} + +// deploymentNamespaceLister implements the DeploymentNamespaceLister +// interface. +type deploymentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Deployments in the indexer for a given namespace. +func (s deploymentNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Deployment)) + }) + return ret, err +} + +// Get retrieves the Deployment from the indexer for a given namespace and name. +func (s deploymentNamespaceLister) Get(name string) (*v1beta1.Deployment, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("deployment"), name) + } + return obj.(*v1beta1.Deployment), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..c73cf98c7a5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta1/expansion_generated.go @@ -0,0 +1,35 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// ControllerRevisionListerExpansion allows custom methods to be added to +// ControllerRevisionLister. +type ControllerRevisionListerExpansion interface{} + +// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to +// ControllerRevisionNamespaceLister. +type ControllerRevisionNamespaceListerExpansion interface{} + +// DeploymentListerExpansion allows custom methods to be added to +// DeploymentLister. +type DeploymentListerExpansion interface{} + +// DeploymentNamespaceListerExpansion allows custom methods to be added to +// DeploymentNamespaceLister. +type DeploymentNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset.go b/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset.go new file mode 100644 index 00000000000..e3556bc398f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/apps/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StatefulSetLister helps list StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetLister interface { + // List lists all StatefulSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) + // StatefulSets returns an object that can list and get StatefulSets. + StatefulSets(namespace string) StatefulSetNamespaceLister + StatefulSetListerExpansion +} + +// statefulSetLister implements the StatefulSetLister interface. +type statefulSetLister struct { + indexer cache.Indexer +} + +// NewStatefulSetLister returns a new StatefulSetLister. +func NewStatefulSetLister(indexer cache.Indexer) StatefulSetLister { + return &statefulSetLister{indexer: indexer} +} + +// List lists all StatefulSets in the indexer. +func (s *statefulSetLister) List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.StatefulSet)) + }) + return ret, err +} + +// StatefulSets returns an object that can list and get StatefulSets. +func (s *statefulSetLister) StatefulSets(namespace string) StatefulSetNamespaceLister { + return statefulSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// StatefulSetNamespaceLister helps list and get StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetNamespaceLister interface { + // List lists all StatefulSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) + // Get retrieves the StatefulSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.StatefulSet, error) + StatefulSetNamespaceListerExpansion +} + +// statefulSetNamespaceLister implements the StatefulSetNamespaceLister +// interface. +type statefulSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all StatefulSets in the indexer for a given namespace. +func (s statefulSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.StatefulSet)) + }) + return ret, err +} + +// Get retrieves the StatefulSet from the indexer for a given namespace and name. +func (s statefulSetNamespaceLister) Get(name string) (*v1beta1.StatefulSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("statefulset"), name) + } + return obj.(*v1beta1.StatefulSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset_expansion.go new file mode 100644 index 00000000000..7d2c4d9b07a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta1/statefulset_expansion.go @@ -0,0 +1,78 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1beta1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// StatefulSetListerExpansion allows custom methods to be added to +// StatefulSetLister. +type StatefulSetListerExpansion interface { + GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) +} + +// StatefulSetNamespaceListerExpansion allows custom methods to be added to +// StatefulSetNamespaceLister. +type StatefulSetNamespaceListerExpansion interface{} + +// GetPodStatefulSets returns a list of StatefulSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching StatefulSets are found. +func (s *statefulSetLister) GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) { + var selector labels.Selector + var ps *apps.StatefulSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.StatefulSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var psList []*apps.StatefulSet + for i := range list { + ps = list[i] + if ps.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + psList = append(psList, ps) + } + + if len(psList) == 0 { + return nil, fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return psList, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/controllerrevision.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/controllerrevision.go new file mode 100644 index 00000000000..da2ce860054 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/controllerrevision.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ControllerRevisionLister helps list ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionLister interface { + // List lists all ControllerRevisions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.ControllerRevision, err error) + // ControllerRevisions returns an object that can list and get ControllerRevisions. + ControllerRevisions(namespace string) ControllerRevisionNamespaceLister + ControllerRevisionListerExpansion +} + +// controllerRevisionLister implements the ControllerRevisionLister interface. +type controllerRevisionLister struct { + indexer cache.Indexer +} + +// NewControllerRevisionLister returns a new ControllerRevisionLister. +func NewControllerRevisionLister(indexer cache.Indexer) ControllerRevisionLister { + return &controllerRevisionLister{indexer: indexer} +} + +// List lists all ControllerRevisions in the indexer. +func (s *controllerRevisionLister) List(selector labels.Selector) (ret []*v1beta2.ControllerRevision, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.ControllerRevision)) + }) + return ret, err +} + +// ControllerRevisions returns an object that can list and get ControllerRevisions. +func (s *controllerRevisionLister) ControllerRevisions(namespace string) ControllerRevisionNamespaceLister { + return controllerRevisionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ControllerRevisionNamespaceLister helps list and get ControllerRevisions. +// All objects returned here must be treated as read-only. +type ControllerRevisionNamespaceLister interface { + // List lists all ControllerRevisions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.ControllerRevision, err error) + // Get retrieves the ControllerRevision from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.ControllerRevision, error) + ControllerRevisionNamespaceListerExpansion +} + +// controllerRevisionNamespaceLister implements the ControllerRevisionNamespaceLister +// interface. +type controllerRevisionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ControllerRevisions in the indexer for a given namespace. +func (s controllerRevisionNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.ControllerRevision, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.ControllerRevision)) + }) + return ret, err +} + +// Get retrieves the ControllerRevision from the indexer for a given namespace and name. +func (s controllerRevisionNamespaceLister) Get(name string) (*v1beta2.ControllerRevision, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("controllerrevision"), name) + } + return obj.(*v1beta2.ControllerRevision), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset.go new file mode 100644 index 00000000000..4b7aedd7586 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DaemonSetLister helps list DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetLister interface { + // List lists all DaemonSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.DaemonSet, err error) + // DaemonSets returns an object that can list and get DaemonSets. + DaemonSets(namespace string) DaemonSetNamespaceLister + DaemonSetListerExpansion +} + +// daemonSetLister implements the DaemonSetLister interface. +type daemonSetLister struct { + indexer cache.Indexer +} + +// NewDaemonSetLister returns a new DaemonSetLister. +func NewDaemonSetLister(indexer cache.Indexer) DaemonSetLister { + return &daemonSetLister{indexer: indexer} +} + +// List lists all DaemonSets in the indexer. +func (s *daemonSetLister) List(selector labels.Selector) (ret []*v1beta2.DaemonSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.DaemonSet)) + }) + return ret, err +} + +// DaemonSets returns an object that can list and get DaemonSets. +func (s *daemonSetLister) DaemonSets(namespace string) DaemonSetNamespaceLister { + return daemonSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DaemonSetNamespaceLister helps list and get DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetNamespaceLister interface { + // List lists all DaemonSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.DaemonSet, err error) + // Get retrieves the DaemonSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.DaemonSet, error) + DaemonSetNamespaceListerExpansion +} + +// daemonSetNamespaceLister implements the DaemonSetNamespaceLister +// interface. +type daemonSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all DaemonSets in the indexer for a given namespace. +func (s daemonSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.DaemonSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.DaemonSet)) + }) + return ret, err +} + +// Get retrieves the DaemonSet from the indexer for a given namespace and name. +func (s daemonSetNamespaceLister) Get(name string) (*v1beta2.DaemonSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("daemonset"), name) + } + return obj.(*v1beta2.DaemonSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset_expansion.go new file mode 100644 index 00000000000..e722b63b680 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/daemonset_expansion.go @@ -0,0 +1,114 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta2 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1beta2" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// DaemonSetListerExpansion allows custom methods to be added to +// DaemonSetLister. +type DaemonSetListerExpansion interface { + GetPodDaemonSets(pod *v1.Pod) ([]*apps.DaemonSet, error) + GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*apps.DaemonSet, error) +} + +// DaemonSetNamespaceListerExpansion allows custom methods to be added to +// DaemonSetNamespaceLister. +type DaemonSetNamespaceListerExpansion interface{} + +// GetPodDaemonSets returns a list of DaemonSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetPodDaemonSets(pod *v1.Pod) ([]*apps.DaemonSet, error) { + var selector labels.Selector + var daemonSet *apps.DaemonSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.DaemonSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*apps.DaemonSet + for i := range list { + daemonSet = list[i] + if daemonSet.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + daemonSets = append(daemonSets, daemonSet) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return daemonSets, nil +} + +// GetHistoryDaemonSets returns a list of DaemonSets that potentially +// match a ControllerRevision. Only the one specified in the ControllerRevision's ControllerRef +// will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*apps.DaemonSet, error) { + if len(history.Labels) == 0 { + return nil, fmt.Errorf("no DaemonSet found for ControllerRevision %s because it has no labels", history.Name) + } + + list, err := s.DaemonSets(history.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*apps.DaemonSet + for _, ds := range list { + selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the history object + continue + } + // If a DaemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(history.Labels)) { + continue + } + daemonSets = append(daemonSets, ds) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find DaemonSets for ControllerRevision %s in namespace %s with labels: %v", history.Name, history.Namespace, history.Labels) + } + + return daemonSets, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/deployment.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/deployment.go new file mode 100644 index 00000000000..c2857bbc366 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/deployment.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DeploymentLister helps list Deployments. +// All objects returned here must be treated as read-only. +type DeploymentLister interface { + // List lists all Deployments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.Deployment, err error) + // Deployments returns an object that can list and get Deployments. + Deployments(namespace string) DeploymentNamespaceLister + DeploymentListerExpansion +} + +// deploymentLister implements the DeploymentLister interface. +type deploymentLister struct { + indexer cache.Indexer +} + +// NewDeploymentLister returns a new DeploymentLister. +func NewDeploymentLister(indexer cache.Indexer) DeploymentLister { + return &deploymentLister{indexer: indexer} +} + +// List lists all Deployments in the indexer. +func (s *deploymentLister) List(selector labels.Selector) (ret []*v1beta2.Deployment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.Deployment)) + }) + return ret, err +} + +// Deployments returns an object that can list and get Deployments. +func (s *deploymentLister) Deployments(namespace string) DeploymentNamespaceLister { + return deploymentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DeploymentNamespaceLister helps list and get Deployments. +// All objects returned here must be treated as read-only. +type DeploymentNamespaceLister interface { + // List lists all Deployments in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.Deployment, err error) + // Get retrieves the Deployment from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.Deployment, error) + DeploymentNamespaceListerExpansion +} + +// deploymentNamespaceLister implements the DeploymentNamespaceLister +// interface. +type deploymentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Deployments in the indexer for a given namespace. +func (s deploymentNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.Deployment, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.Deployment)) + }) + return ret, err +} + +// Get retrieves the Deployment from the indexer for a given namespace and name. +func (s deploymentNamespaceLister) Get(name string) (*v1beta2.Deployment, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("deployment"), name) + } + return obj.(*v1beta2.Deployment), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go new file mode 100644 index 00000000000..b6d202118ed --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/expansion_generated.go @@ -0,0 +1,35 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +// ControllerRevisionListerExpansion allows custom methods to be added to +// ControllerRevisionLister. +type ControllerRevisionListerExpansion interface{} + +// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to +// ControllerRevisionNamespaceLister. +type ControllerRevisionNamespaceListerExpansion interface{} + +// DeploymentListerExpansion allows custom methods to be added to +// DeploymentLister. +type DeploymentListerExpansion interface{} + +// DeploymentNamespaceListerExpansion allows custom methods to be added to +// DeploymentNamespaceLister. +type DeploymentNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset.go new file mode 100644 index 00000000000..26b350ce8f8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ReplicaSetLister helps list ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetLister interface { + // List lists all ReplicaSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.ReplicaSet, err error) + // ReplicaSets returns an object that can list and get ReplicaSets. + ReplicaSets(namespace string) ReplicaSetNamespaceLister + ReplicaSetListerExpansion +} + +// replicaSetLister implements the ReplicaSetLister interface. +type replicaSetLister struct { + indexer cache.Indexer +} + +// NewReplicaSetLister returns a new ReplicaSetLister. +func NewReplicaSetLister(indexer cache.Indexer) ReplicaSetLister { + return &replicaSetLister{indexer: indexer} +} + +// List lists all ReplicaSets in the indexer. +func (s *replicaSetLister) List(selector labels.Selector) (ret []*v1beta2.ReplicaSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.ReplicaSet)) + }) + return ret, err +} + +// ReplicaSets returns an object that can list and get ReplicaSets. +func (s *replicaSetLister) ReplicaSets(namespace string) ReplicaSetNamespaceLister { + return replicaSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ReplicaSetNamespaceLister helps list and get ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetNamespaceLister interface { + // List lists all ReplicaSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.ReplicaSet, err error) + // Get retrieves the ReplicaSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.ReplicaSet, error) + ReplicaSetNamespaceListerExpansion +} + +// replicaSetNamespaceLister implements the ReplicaSetNamespaceLister +// interface. +type replicaSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ReplicaSets in the indexer for a given namespace. +func (s replicaSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.ReplicaSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.ReplicaSet)) + }) + return ret, err +} + +// Get retrieves the ReplicaSet from the indexer for a given namespace and name. +func (s replicaSetNamespaceLister) Get(name string) (*v1beta2.ReplicaSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("replicaset"), name) + } + return obj.(*v1beta2.ReplicaSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset_expansion.go new file mode 100644 index 00000000000..bc014b5a69d --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/replicaset_expansion.go @@ -0,0 +1,74 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta2 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1beta2" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// ReplicaSetListerExpansion allows custom methods to be added to +// ReplicaSetLister. +type ReplicaSetListerExpansion interface { + GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) +} + +// ReplicaSetNamespaceListerExpansion allows custom methods to be added to +// ReplicaSetNamespaceLister. +type ReplicaSetNamespaceListerExpansion interface{} + +// GetPodReplicaSets returns a list of ReplicaSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching ReplicaSets are found. +func (s *replicaSetLister) GetPodReplicaSets(pod *v1.Pod) ([]*apps.ReplicaSet, error) { + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var rss []*apps.ReplicaSet + for _, rs := range list { + if rs.Namespace != pod.Namespace { + continue + } + selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + rss = append(rss, rs) + } + + if len(rss) == 0 { + return nil, fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return rss, nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset.go new file mode 100644 index 00000000000..fbbaf0133f7 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/apps/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StatefulSetLister helps list StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetLister interface { + // List lists all StatefulSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.StatefulSet, err error) + // StatefulSets returns an object that can list and get StatefulSets. + StatefulSets(namespace string) StatefulSetNamespaceLister + StatefulSetListerExpansion +} + +// statefulSetLister implements the StatefulSetLister interface. +type statefulSetLister struct { + indexer cache.Indexer +} + +// NewStatefulSetLister returns a new StatefulSetLister. +func NewStatefulSetLister(indexer cache.Indexer) StatefulSetLister { + return &statefulSetLister{indexer: indexer} +} + +// List lists all StatefulSets in the indexer. +func (s *statefulSetLister) List(selector labels.Selector) (ret []*v1beta2.StatefulSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.StatefulSet)) + }) + return ret, err +} + +// StatefulSets returns an object that can list and get StatefulSets. +func (s *statefulSetLister) StatefulSets(namespace string) StatefulSetNamespaceLister { + return statefulSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// StatefulSetNamespaceLister helps list and get StatefulSets. +// All objects returned here must be treated as read-only. +type StatefulSetNamespaceLister interface { + // List lists all StatefulSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.StatefulSet, err error) + // Get retrieves the StatefulSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.StatefulSet, error) + StatefulSetNamespaceListerExpansion +} + +// statefulSetNamespaceLister implements the StatefulSetNamespaceLister +// interface. +type statefulSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all StatefulSets in the indexer for a given namespace. +func (s statefulSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.StatefulSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.StatefulSet)) + }) + return ret, err +} + +// Get retrieves the StatefulSet from the indexer for a given namespace and name. +func (s statefulSetNamespaceLister) Get(name string) (*v1beta2.StatefulSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("statefulset"), name) + } + return obj.(*v1beta2.StatefulSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset_expansion.go b/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset_expansion.go new file mode 100644 index 00000000000..eae31b82f83 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/apps/v1beta2/statefulset_expansion.go @@ -0,0 +1,78 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta2 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1beta2" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// StatefulSetListerExpansion allows custom methods to be added to +// StatefulSetLister. +type StatefulSetListerExpansion interface { + GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) +} + +// StatefulSetNamespaceListerExpansion allows custom methods to be added to +// StatefulSetNamespaceLister. +type StatefulSetNamespaceListerExpansion interface{} + +// GetPodStatefulSets returns a list of StatefulSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching StatefulSets are found. +func (s *statefulSetLister) GetPodStatefulSets(pod *v1.Pod) ([]*apps.StatefulSet, error) { + var selector labels.Selector + var ps *apps.StatefulSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.StatefulSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var psList []*apps.StatefulSet + for i := range list { + ps = list[i] + if ps.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + psList = append(psList, ps) + } + + if len(psList) == 0 { + return nil, fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return psList, nil +} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v1/expansion_generated.go new file mode 100644 index 00000000000..05253c77030 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerLister. +type HorizontalPodAutoscalerListerExpansion interface{} + +// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerNamespaceLister. +type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v1/horizontalpodautoscaler.go new file mode 100644 index 00000000000..8447f059d45 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v1/horizontalpodautoscaler.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/autoscaling/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerLister interface { + // List lists all HorizontalPodAutoscalers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.HorizontalPodAutoscaler, err error) + // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. + HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister + HorizontalPodAutoscalerListerExpansion +} + +// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. +type horizontalPodAutoscalerLister struct { + indexer cache.Indexer +} + +// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. +func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { + return &horizontalPodAutoscalerLister{indexer: indexer} +} + +// List lists all HorizontalPodAutoscalers in the indexer. +func (s *horizontalPodAutoscalerLister) List(selector labels.Selector) (ret []*v1.HorizontalPodAutoscaler, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. +func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { + return horizontalPodAutoscalerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerNamespaceLister interface { + // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.HorizontalPodAutoscaler, err error) + // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.HorizontalPodAutoscaler, error) + HorizontalPodAutoscalerNamespaceListerExpansion +} + +// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister +// interface. +type horizontalPodAutoscalerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all HorizontalPodAutoscalers in the indexer for a given namespace. +func (s horizontalPodAutoscalerNamespaceLister) List(selector labels.Selector) (ret []*v1.HorizontalPodAutoscaler, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. +func (s horizontalPodAutoscalerNamespaceLister) Get(name string) (*v1.HorizontalPodAutoscaler, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("horizontalpodautoscaler"), name) + } + return obj.(*v1.HorizontalPodAutoscaler), nil +} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v2/expansion_generated.go new file mode 100644 index 00000000000..97742b77b29 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2 + +// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerLister. +type HorizontalPodAutoscalerListerExpansion interface{} + +// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerNamespaceLister. +type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v2/horizontalpodautoscaler.go new file mode 100644 index 00000000000..a5cef277257 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2/horizontalpodautoscaler.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2 + +import ( + v2 "k8s.io/api/autoscaling/v2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerLister interface { + // List lists all HorizontalPodAutoscalers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) + // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. + HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister + HorizontalPodAutoscalerListerExpansion +} + +// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. +type horizontalPodAutoscalerLister struct { + indexer cache.Indexer +} + +// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. +func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { + return &horizontalPodAutoscalerLister{indexer: indexer} +} + +// List lists all HorizontalPodAutoscalers in the indexer. +func (s *horizontalPodAutoscalerLister) List(selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v2.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. +func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { + return horizontalPodAutoscalerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerNamespaceLister interface { + // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) + // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v2.HorizontalPodAutoscaler, error) + HorizontalPodAutoscalerNamespaceListerExpansion +} + +// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister +// interface. +type horizontalPodAutoscalerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all HorizontalPodAutoscalers in the indexer for a given namespace. +func (s horizontalPodAutoscalerNamespaceLister) List(selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v2.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. +func (s horizontalPodAutoscalerNamespaceLister) Get(name string) (*v2.HorizontalPodAutoscaler, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v2.Resource("horizontalpodautoscaler"), name) + } + return obj.(*v2.HorizontalPodAutoscaler), nil +} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go new file mode 100644 index 00000000000..8d46a4b6e31 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2beta1 + +// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerLister. +type HorizontalPodAutoscalerListerExpansion interface{} + +// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerNamespaceLister. +type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go new file mode 100644 index 00000000000..f1804e995b6 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2beta1 + +import ( + v2beta1 "k8s.io/api/autoscaling/v2beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerLister interface { + // List lists all HorizontalPodAutoscalers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2beta1.HorizontalPodAutoscaler, err error) + // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. + HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister + HorizontalPodAutoscalerListerExpansion +} + +// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. +type horizontalPodAutoscalerLister struct { + indexer cache.Indexer +} + +// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. +func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { + return &horizontalPodAutoscalerLister{indexer: indexer} +} + +// List lists all HorizontalPodAutoscalers in the indexer. +func (s *horizontalPodAutoscalerLister) List(selector labels.Selector) (ret []*v2beta1.HorizontalPodAutoscaler, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v2beta1.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. +func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { + return horizontalPodAutoscalerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerNamespaceLister interface { + // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2beta1.HorizontalPodAutoscaler, err error) + // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v2beta1.HorizontalPodAutoscaler, error) + HorizontalPodAutoscalerNamespaceListerExpansion +} + +// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister +// interface. +type horizontalPodAutoscalerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all HorizontalPodAutoscalers in the indexer for a given namespace. +func (s horizontalPodAutoscalerNamespaceLister) List(selector labels.Selector) (ret []*v2beta1.HorizontalPodAutoscaler, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v2beta1.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. +func (s horizontalPodAutoscalerNamespaceLister) Get(name string) (*v2beta1.HorizontalPodAutoscaler, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v2beta1.Resource("horizontalpodautoscaler"), name) + } + return obj.(*v2beta1.HorizontalPodAutoscaler), nil +} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go new file mode 100644 index 00000000000..5127945a9c7 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2beta2 + +// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerLister. +type HorizontalPodAutoscalerListerExpansion interface{} + +// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to +// HorizontalPodAutoscalerNamespaceLister. +type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go new file mode 100644 index 00000000000..b0dbaf9eb0a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v2beta2 + +import ( + v2beta2 "k8s.io/api/autoscaling/v2beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerLister interface { + // List lists all HorizontalPodAutoscalers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2beta2.HorizontalPodAutoscaler, err error) + // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. + HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister + HorizontalPodAutoscalerListerExpansion +} + +// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. +type horizontalPodAutoscalerLister struct { + indexer cache.Indexer +} + +// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. +func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { + return &horizontalPodAutoscalerLister{indexer: indexer} +} + +// List lists all HorizontalPodAutoscalers in the indexer. +func (s *horizontalPodAutoscalerLister) List(selector labels.Selector) (ret []*v2beta2.HorizontalPodAutoscaler, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v2beta2.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. +func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { + return horizontalPodAutoscalerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. +// All objects returned here must be treated as read-only. +type HorizontalPodAutoscalerNamespaceLister interface { + // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v2beta2.HorizontalPodAutoscaler, err error) + // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v2beta2.HorizontalPodAutoscaler, error) + HorizontalPodAutoscalerNamespaceListerExpansion +} + +// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister +// interface. +type horizontalPodAutoscalerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all HorizontalPodAutoscalers in the indexer for a given namespace. +func (s horizontalPodAutoscalerNamespaceLister) List(selector labels.Selector) (ret []*v2beta2.HorizontalPodAutoscaler, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v2beta2.HorizontalPodAutoscaler)) + }) + return ret, err +} + +// Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. +func (s horizontalPodAutoscalerNamespaceLister) Get(name string) (*v2beta2.HorizontalPodAutoscaler, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v2beta2.Resource("horizontalpodautoscaler"), name) + } + return obj.(*v2beta2.HorizontalPodAutoscaler), nil +} diff --git a/vendor/k8s.io/client-go/listers/batch/v1/cronjob.go b/vendor/k8s.io/client-go/listers/batch/v1/cronjob.go new file mode 100644 index 00000000000..8e49ed959fa --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1/cronjob.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CronJobLister helps list CronJobs. +// All objects returned here must be treated as read-only. +type CronJobLister interface { + // List lists all CronJobs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CronJob, err error) + // CronJobs returns an object that can list and get CronJobs. + CronJobs(namespace string) CronJobNamespaceLister + CronJobListerExpansion +} + +// cronJobLister implements the CronJobLister interface. +type cronJobLister struct { + indexer cache.Indexer +} + +// NewCronJobLister returns a new CronJobLister. +func NewCronJobLister(indexer cache.Indexer) CronJobLister { + return &cronJobLister{indexer: indexer} +} + +// List lists all CronJobs in the indexer. +func (s *cronJobLister) List(selector labels.Selector) (ret []*v1.CronJob, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CronJob)) + }) + return ret, err +} + +// CronJobs returns an object that can list and get CronJobs. +func (s *cronJobLister) CronJobs(namespace string) CronJobNamespaceLister { + return cronJobNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CronJobNamespaceLister helps list and get CronJobs. +// All objects returned here must be treated as read-only. +type CronJobNamespaceLister interface { + // List lists all CronJobs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CronJob, err error) + // Get retrieves the CronJob from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CronJob, error) + CronJobNamespaceListerExpansion +} + +// cronJobNamespaceLister implements the CronJobNamespaceLister +// interface. +type cronJobNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CronJobs in the indexer for a given namespace. +func (s cronJobNamespaceLister) List(selector labels.Selector) (ret []*v1.CronJob, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CronJob)) + }) + return ret, err +} + +// Get retrieves the CronJob from the indexer for a given namespace and name. +func (s cronJobNamespaceLister) Get(name string) (*v1.CronJob, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("cronjob"), name) + } + return obj.(*v1.CronJob), nil +} diff --git a/vendor/k8s.io/client-go/listers/batch/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/batch/v1/expansion_generated.go new file mode 100644 index 00000000000..22097627903 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// CronJobListerExpansion allows custom methods to be added to +// CronJobLister. +type CronJobListerExpansion interface{} + +// CronJobNamespaceListerExpansion allows custom methods to be added to +// CronJobNamespaceLister. +type CronJobNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/batch/v1/job.go b/vendor/k8s.io/client-go/listers/batch/v1/job.go new file mode 100644 index 00000000000..3aba6b95fa6 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1/job.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// JobLister helps list Jobs. +// All objects returned here must be treated as read-only. +type JobLister interface { + // List lists all Jobs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Job, err error) + // Jobs returns an object that can list and get Jobs. + Jobs(namespace string) JobNamespaceLister + JobListerExpansion +} + +// jobLister implements the JobLister interface. +type jobLister struct { + indexer cache.Indexer +} + +// NewJobLister returns a new JobLister. +func NewJobLister(indexer cache.Indexer) JobLister { + return &jobLister{indexer: indexer} +} + +// List lists all Jobs in the indexer. +func (s *jobLister) List(selector labels.Selector) (ret []*v1.Job, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Job)) + }) + return ret, err +} + +// Jobs returns an object that can list and get Jobs. +func (s *jobLister) Jobs(namespace string) JobNamespaceLister { + return jobNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// JobNamespaceLister helps list and get Jobs. +// All objects returned here must be treated as read-only. +type JobNamespaceLister interface { + // List lists all Jobs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Job, err error) + // Get retrieves the Job from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Job, error) + JobNamespaceListerExpansion +} + +// jobNamespaceLister implements the JobNamespaceLister +// interface. +type jobNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Jobs in the indexer for a given namespace. +func (s jobNamespaceLister) List(selector labels.Selector) (ret []*v1.Job, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Job)) + }) + return ret, err +} + +// Get retrieves the Job from the indexer for a given namespace and name. +func (s jobNamespaceLister) Get(name string) (*v1.Job, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("job"), name) + } + return obj.(*v1.Job), nil +} diff --git a/vendor/k8s.io/client-go/listers/batch/v1/job_expansion.go b/vendor/k8s.io/client-go/listers/batch/v1/job_expansion.go new file mode 100644 index 00000000000..8dc5db7885e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1/job_expansion.go @@ -0,0 +1,72 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + batch "k8s.io/api/batch/v1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// JobListerExpansion allows custom methods to be added to +// JobLister. +type JobListerExpansion interface { + // GetPodJobs returns a list of Jobs that potentially + // match a Pod. Only the one specified in the Pod's ControllerRef + // will actually manage it. + // Returns an error only if no matching Jobs are found. + GetPodJobs(pod *v1.Pod) (jobs []batch.Job, err error) +} + +// GetPodJobs returns a list of Jobs that potentially +// match a Pod. Only the one specified in the Pod's ControllerRef +// will actually manage it. +// Returns an error only if no matching Jobs are found. +func (l *jobLister) GetPodJobs(pod *v1.Pod) (jobs []batch.Job, err error) { + if len(pod.Labels) == 0 { + err = fmt.Errorf("no jobs found for pod %v because it has no labels", pod.Name) + return + } + + var list []*batch.Job + list, err = l.Jobs(pod.Namespace).List(labels.Everything()) + if err != nil { + return + } + for _, job := range list { + selector, err := metav1.LabelSelectorAsSelector(job.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + if !selector.Matches(labels.Set(pod.Labels)) { + continue + } + jobs = append(jobs, *job) + } + if len(jobs) == 0 { + err = fmt.Errorf("could not find jobs for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} + +// JobNamespaceListerExpansion allows custom methods to be added to +// JobNamespaceLister. +type JobNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/batch/v1beta1/cronjob.go b/vendor/k8s.io/client-go/listers/batch/v1beta1/cronjob.go new file mode 100644 index 00000000000..4842d5e5a15 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1beta1/cronjob.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/batch/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CronJobLister helps list CronJobs. +// All objects returned here must be treated as read-only. +type CronJobLister interface { + // List lists all CronJobs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CronJob, err error) + // CronJobs returns an object that can list and get CronJobs. + CronJobs(namespace string) CronJobNamespaceLister + CronJobListerExpansion +} + +// cronJobLister implements the CronJobLister interface. +type cronJobLister struct { + indexer cache.Indexer +} + +// NewCronJobLister returns a new CronJobLister. +func NewCronJobLister(indexer cache.Indexer) CronJobLister { + return &cronJobLister{indexer: indexer} +} + +// List lists all CronJobs in the indexer. +func (s *cronJobLister) List(selector labels.Selector) (ret []*v1beta1.CronJob, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CronJob)) + }) + return ret, err +} + +// CronJobs returns an object that can list and get CronJobs. +func (s *cronJobLister) CronJobs(namespace string) CronJobNamespaceLister { + return cronJobNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CronJobNamespaceLister helps list and get CronJobs. +// All objects returned here must be treated as read-only. +type CronJobNamespaceLister interface { + // List lists all CronJobs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CronJob, err error) + // Get retrieves the CronJob from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.CronJob, error) + CronJobNamespaceListerExpansion +} + +// cronJobNamespaceLister implements the CronJobNamespaceLister +// interface. +type cronJobNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CronJobs in the indexer for a given namespace. +func (s cronJobNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.CronJob, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CronJob)) + }) + return ret, err +} + +// Get retrieves the CronJob from the indexer for a given namespace and name. +func (s cronJobNamespaceLister) Get(name string) (*v1beta1.CronJob, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("cronjob"), name) + } + return obj.(*v1beta1.CronJob), nil +} diff --git a/vendor/k8s.io/client-go/listers/batch/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/batch/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..be2742ef615 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/batch/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// CronJobListerExpansion allows custom methods to be added to +// CronJobLister. +type CronJobListerExpansion interface{} + +// CronJobNamespaceListerExpansion allows custom methods to be added to +// CronJobNamespaceLister. +type CronJobNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1/certificatesigningrequest.go b/vendor/k8s.io/client-go/listers/certificates/v1/certificatesigningrequest.go new file mode 100644 index 00000000000..0d04e118dbc --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1/certificatesigningrequest.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/certificates/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CertificateSigningRequestLister helps list CertificateSigningRequests. +// All objects returned here must be treated as read-only. +type CertificateSigningRequestLister interface { + // List lists all CertificateSigningRequests in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CertificateSigningRequest, err error) + // Get retrieves the CertificateSigningRequest from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CertificateSigningRequest, error) + CertificateSigningRequestListerExpansion +} + +// certificateSigningRequestLister implements the CertificateSigningRequestLister interface. +type certificateSigningRequestLister struct { + indexer cache.Indexer +} + +// NewCertificateSigningRequestLister returns a new CertificateSigningRequestLister. +func NewCertificateSigningRequestLister(indexer cache.Indexer) CertificateSigningRequestLister { + return &certificateSigningRequestLister{indexer: indexer} +} + +// List lists all CertificateSigningRequests in the indexer. +func (s *certificateSigningRequestLister) List(selector labels.Selector) (ret []*v1.CertificateSigningRequest, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CertificateSigningRequest)) + }) + return ret, err +} + +// Get retrieves the CertificateSigningRequest from the index for a given name. +func (s *certificateSigningRequestLister) Get(name string) (*v1.CertificateSigningRequest, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("certificatesigningrequest"), name) + } + return obj.(*v1.CertificateSigningRequest), nil +} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/certificates/v1/expansion_generated.go new file mode 100644 index 00000000000..616a1f1a092 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// CertificateSigningRequestListerExpansion allows custom methods to be added to +// CertificateSigningRequestLister. +type CertificateSigningRequestListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 00000000000..b8049a76181 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterTrustBundleLister helps list ClusterTrustBundles. +// All objects returned here must be treated as read-only. +type ClusterTrustBundleLister interface { + // List lists all ClusterTrustBundles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) + // Get retrieves the ClusterTrustBundle from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterTrustBundle, error) + ClusterTrustBundleListerExpansion +} + +// clusterTrustBundleLister implements the ClusterTrustBundleLister interface. +type clusterTrustBundleLister struct { + indexer cache.Indexer +} + +// NewClusterTrustBundleLister returns a new ClusterTrustBundleLister. +func NewClusterTrustBundleLister(indexer cache.Indexer) ClusterTrustBundleLister { + return &clusterTrustBundleLister{indexer: indexer} +} + +// List lists all ClusterTrustBundles in the indexer. +func (s *clusterTrustBundleLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterTrustBundle)) + }) + return ret, err +} + +// Get retrieves the ClusterTrustBundle from the index for a given name. +func (s *clusterTrustBundleLister) Get(name string) (*v1alpha1.ClusterTrustBundle, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clustertrustbundle"), name) + } + return obj.(*v1alpha1.ClusterTrustBundle), nil +} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..d77258cb2d4 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterTrustBundleListerExpansion allows custom methods to be added to +// ClusterTrustBundleLister. +type ClusterTrustBundleListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go b/vendor/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go new file mode 100644 index 00000000000..471b5629b33 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/certificates/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CertificateSigningRequestLister helps list CertificateSigningRequests. +// All objects returned here must be treated as read-only. +type CertificateSigningRequestLister interface { + // List lists all CertificateSigningRequests in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CertificateSigningRequest, err error) + // Get retrieves the CertificateSigningRequest from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.CertificateSigningRequest, error) + CertificateSigningRequestListerExpansion +} + +// certificateSigningRequestLister implements the CertificateSigningRequestLister interface. +type certificateSigningRequestLister struct { + indexer cache.Indexer +} + +// NewCertificateSigningRequestLister returns a new CertificateSigningRequestLister. +func NewCertificateSigningRequestLister(indexer cache.Indexer) CertificateSigningRequestLister { + return &certificateSigningRequestLister{indexer: indexer} +} + +// List lists all CertificateSigningRequests in the indexer. +func (s *certificateSigningRequestLister) List(selector labels.Selector) (ret []*v1beta1.CertificateSigningRequest, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CertificateSigningRequest)) + }) + return ret, err +} + +// Get retrieves the CertificateSigningRequest from the index for a given name. +func (s *certificateSigningRequestLister) Get(name string) (*v1beta1.CertificateSigningRequest, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("certificatesigningrequest"), name) + } + return obj.(*v1beta1.CertificateSigningRequest), nil +} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/certificates/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..68f993cd6e9 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1beta1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// CertificateSigningRequestListerExpansion allows custom methods to be added to +// CertificateSigningRequestLister. +type CertificateSigningRequestListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/coordination/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/coordination/v1/expansion_generated.go new file mode 100644 index 00000000000..ddc494f1c36 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/coordination/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// LeaseListerExpansion allows custom methods to be added to +// LeaseLister. +type LeaseListerExpansion interface{} + +// LeaseNamespaceListerExpansion allows custom methods to be added to +// LeaseNamespaceLister. +type LeaseNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/coordination/v1/lease.go b/vendor/k8s.io/client-go/listers/coordination/v1/lease.go new file mode 100644 index 00000000000..de366d0e11a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/coordination/v1/lease.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/coordination/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// LeaseLister helps list Leases. +// All objects returned here must be treated as read-only. +type LeaseLister interface { + // List lists all Leases in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Lease, err error) + // Leases returns an object that can list and get Leases. + Leases(namespace string) LeaseNamespaceLister + LeaseListerExpansion +} + +// leaseLister implements the LeaseLister interface. +type leaseLister struct { + indexer cache.Indexer +} + +// NewLeaseLister returns a new LeaseLister. +func NewLeaseLister(indexer cache.Indexer) LeaseLister { + return &leaseLister{indexer: indexer} +} + +// List lists all Leases in the indexer. +func (s *leaseLister) List(selector labels.Selector) (ret []*v1.Lease, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Lease)) + }) + return ret, err +} + +// Leases returns an object that can list and get Leases. +func (s *leaseLister) Leases(namespace string) LeaseNamespaceLister { + return leaseNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// LeaseNamespaceLister helps list and get Leases. +// All objects returned here must be treated as read-only. +type LeaseNamespaceLister interface { + // List lists all Leases in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Lease, err error) + // Get retrieves the Lease from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Lease, error) + LeaseNamespaceListerExpansion +} + +// leaseNamespaceLister implements the LeaseNamespaceLister +// interface. +type leaseNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Leases in the indexer for a given namespace. +func (s leaseNamespaceLister) List(selector labels.Selector) (ret []*v1.Lease, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Lease)) + }) + return ret, err +} + +// Get retrieves the Lease from the indexer for a given namespace and name. +func (s leaseNamespaceLister) Get(name string) (*v1.Lease, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("lease"), name) + } + return obj.(*v1.Lease), nil +} diff --git a/vendor/k8s.io/client-go/listers/coordination/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/coordination/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..dddc53107b0 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/coordination/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// LeaseListerExpansion allows custom methods to be added to +// LeaseLister. +type LeaseListerExpansion interface{} + +// LeaseNamespaceListerExpansion allows custom methods to be added to +// LeaseNamespaceLister. +type LeaseNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/coordination/v1beta1/lease.go b/vendor/k8s.io/client-go/listers/coordination/v1beta1/lease.go new file mode 100644 index 00000000000..8dfdc1e9bc0 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/coordination/v1beta1/lease.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/coordination/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// LeaseLister helps list Leases. +// All objects returned here must be treated as read-only. +type LeaseLister interface { + // List lists all Leases in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Lease, err error) + // Leases returns an object that can list and get Leases. + Leases(namespace string) LeaseNamespaceLister + LeaseListerExpansion +} + +// leaseLister implements the LeaseLister interface. +type leaseLister struct { + indexer cache.Indexer +} + +// NewLeaseLister returns a new LeaseLister. +func NewLeaseLister(indexer cache.Indexer) LeaseLister { + return &leaseLister{indexer: indexer} +} + +// List lists all Leases in the indexer. +func (s *leaseLister) List(selector labels.Selector) (ret []*v1beta1.Lease, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Lease)) + }) + return ret, err +} + +// Leases returns an object that can list and get Leases. +func (s *leaseLister) Leases(namespace string) LeaseNamespaceLister { + return leaseNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// LeaseNamespaceLister helps list and get Leases. +// All objects returned here must be treated as read-only. +type LeaseNamespaceLister interface { + // List lists all Leases in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Lease, err error) + // Get retrieves the Lease from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Lease, error) + LeaseNamespaceListerExpansion +} + +// leaseNamespaceLister implements the LeaseNamespaceLister +// interface. +type leaseNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Leases in the indexer for a given namespace. +func (s leaseNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Lease, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Lease)) + }) + return ret, err +} + +// Get retrieves the Lease from the indexer for a given namespace and name. +func (s leaseNamespaceLister) Get(name string) (*v1beta1.Lease, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("lease"), name) + } + return obj.(*v1beta1.Lease), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/componentstatus.go b/vendor/k8s.io/client-go/listers/core/v1/componentstatus.go new file mode 100644 index 00000000000..5fcdac3c764 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/componentstatus.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ComponentStatusLister helps list ComponentStatuses. +// All objects returned here must be treated as read-only. +type ComponentStatusLister interface { + // List lists all ComponentStatuses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ComponentStatus, err error) + // Get retrieves the ComponentStatus from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ComponentStatus, error) + ComponentStatusListerExpansion +} + +// componentStatusLister implements the ComponentStatusLister interface. +type componentStatusLister struct { + indexer cache.Indexer +} + +// NewComponentStatusLister returns a new ComponentStatusLister. +func NewComponentStatusLister(indexer cache.Indexer) ComponentStatusLister { + return &componentStatusLister{indexer: indexer} +} + +// List lists all ComponentStatuses in the indexer. +func (s *componentStatusLister) List(selector labels.Selector) (ret []*v1.ComponentStatus, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ComponentStatus)) + }) + return ret, err +} + +// Get retrieves the ComponentStatus from the index for a given name. +func (s *componentStatusLister) Get(name string) (*v1.ComponentStatus, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("componentstatus"), name) + } + return obj.(*v1.ComponentStatus), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/configmap.go b/vendor/k8s.io/client-go/listers/core/v1/configmap.go new file mode 100644 index 00000000000..6a410e47c4a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/configmap.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ConfigMapLister helps list ConfigMaps. +// All objects returned here must be treated as read-only. +type ConfigMapLister interface { + // List lists all ConfigMaps in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ConfigMap, err error) + // ConfigMaps returns an object that can list and get ConfigMaps. + ConfigMaps(namespace string) ConfigMapNamespaceLister + ConfigMapListerExpansion +} + +// configMapLister implements the ConfigMapLister interface. +type configMapLister struct { + indexer cache.Indexer +} + +// NewConfigMapLister returns a new ConfigMapLister. +func NewConfigMapLister(indexer cache.Indexer) ConfigMapLister { + return &configMapLister{indexer: indexer} +} + +// List lists all ConfigMaps in the indexer. +func (s *configMapLister) List(selector labels.Selector) (ret []*v1.ConfigMap, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ConfigMap)) + }) + return ret, err +} + +// ConfigMaps returns an object that can list and get ConfigMaps. +func (s *configMapLister) ConfigMaps(namespace string) ConfigMapNamespaceLister { + return configMapNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ConfigMapNamespaceLister helps list and get ConfigMaps. +// All objects returned here must be treated as read-only. +type ConfigMapNamespaceLister interface { + // List lists all ConfigMaps in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ConfigMap, err error) + // Get retrieves the ConfigMap from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ConfigMap, error) + ConfigMapNamespaceListerExpansion +} + +// configMapNamespaceLister implements the ConfigMapNamespaceLister +// interface. +type configMapNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ConfigMaps in the indexer for a given namespace. +func (s configMapNamespaceLister) List(selector labels.Selector) (ret []*v1.ConfigMap, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ConfigMap)) + }) + return ret, err +} + +// Get retrieves the ConfigMap from the indexer for a given namespace and name. +func (s configMapNamespaceLister) Get(name string) (*v1.ConfigMap, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("configmap"), name) + } + return obj.(*v1.ConfigMap), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/endpoints.go b/vendor/k8s.io/client-go/listers/core/v1/endpoints.go new file mode 100644 index 00000000000..4759ce808fe --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/endpoints.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EndpointsLister helps list Endpoints. +// All objects returned here must be treated as read-only. +type EndpointsLister interface { + // List lists all Endpoints in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Endpoints, err error) + // Endpoints returns an object that can list and get Endpoints. + Endpoints(namespace string) EndpointsNamespaceLister + EndpointsListerExpansion +} + +// endpointsLister implements the EndpointsLister interface. +type endpointsLister struct { + indexer cache.Indexer +} + +// NewEndpointsLister returns a new EndpointsLister. +func NewEndpointsLister(indexer cache.Indexer) EndpointsLister { + return &endpointsLister{indexer: indexer} +} + +// List lists all Endpoints in the indexer. +func (s *endpointsLister) List(selector labels.Selector) (ret []*v1.Endpoints, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Endpoints)) + }) + return ret, err +} + +// Endpoints returns an object that can list and get Endpoints. +func (s *endpointsLister) Endpoints(namespace string) EndpointsNamespaceLister { + return endpointsNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EndpointsNamespaceLister helps list and get Endpoints. +// All objects returned here must be treated as read-only. +type EndpointsNamespaceLister interface { + // List lists all Endpoints in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Endpoints, err error) + // Get retrieves the Endpoints from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Endpoints, error) + EndpointsNamespaceListerExpansion +} + +// endpointsNamespaceLister implements the EndpointsNamespaceLister +// interface. +type endpointsNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Endpoints in the indexer for a given namespace. +func (s endpointsNamespaceLister) List(selector labels.Selector) (ret []*v1.Endpoints, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Endpoints)) + }) + return ret, err +} + +// Get retrieves the Endpoints from the indexer for a given namespace and name. +func (s endpointsNamespaceLister) Get(name string) (*v1.Endpoints, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("endpoints"), name) + } + return obj.(*v1.Endpoints), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/event.go b/vendor/k8s.io/client-go/listers/core/v1/event.go new file mode 100644 index 00000000000..4416e20120b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/event.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EventLister helps list Events. +// All objects returned here must be treated as read-only. +type EventLister interface { + // List lists all Events in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Event, err error) + // Events returns an object that can list and get Events. + Events(namespace string) EventNamespaceLister + EventListerExpansion +} + +// eventLister implements the EventLister interface. +type eventLister struct { + indexer cache.Indexer +} + +// NewEventLister returns a new EventLister. +func NewEventLister(indexer cache.Indexer) EventLister { + return &eventLister{indexer: indexer} +} + +// List lists all Events in the indexer. +func (s *eventLister) List(selector labels.Selector) (ret []*v1.Event, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Event)) + }) + return ret, err +} + +// Events returns an object that can list and get Events. +func (s *eventLister) Events(namespace string) EventNamespaceLister { + return eventNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EventNamespaceLister helps list and get Events. +// All objects returned here must be treated as read-only. +type EventNamespaceLister interface { + // List lists all Events in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Event, err error) + // Get retrieves the Event from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Event, error) + EventNamespaceListerExpansion +} + +// eventNamespaceLister implements the EventNamespaceLister +// interface. +type eventNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Events in the indexer for a given namespace. +func (s eventNamespaceLister) List(selector labels.Selector) (ret []*v1.Event, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Event)) + }) + return ret, err +} + +// Get retrieves the Event from the indexer for a given namespace and name. +func (s eventNamespaceLister) Get(name string) (*v1.Event, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("event"), name) + } + return obj.(*v1.Event), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/core/v1/expansion_generated.go new file mode 100644 index 00000000000..2168a7f4834 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/expansion_generated.go @@ -0,0 +1,123 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// ComponentStatusListerExpansion allows custom methods to be added to +// ComponentStatusLister. +type ComponentStatusListerExpansion interface{} + +// ConfigMapListerExpansion allows custom methods to be added to +// ConfigMapLister. +type ConfigMapListerExpansion interface{} + +// ConfigMapNamespaceListerExpansion allows custom methods to be added to +// ConfigMapNamespaceLister. +type ConfigMapNamespaceListerExpansion interface{} + +// EndpointsListerExpansion allows custom methods to be added to +// EndpointsLister. +type EndpointsListerExpansion interface{} + +// EndpointsNamespaceListerExpansion allows custom methods to be added to +// EndpointsNamespaceLister. +type EndpointsNamespaceListerExpansion interface{} + +// EventListerExpansion allows custom methods to be added to +// EventLister. +type EventListerExpansion interface{} + +// EventNamespaceListerExpansion allows custom methods to be added to +// EventNamespaceLister. +type EventNamespaceListerExpansion interface{} + +// LimitRangeListerExpansion allows custom methods to be added to +// LimitRangeLister. +type LimitRangeListerExpansion interface{} + +// LimitRangeNamespaceListerExpansion allows custom methods to be added to +// LimitRangeNamespaceLister. +type LimitRangeNamespaceListerExpansion interface{} + +// NamespaceListerExpansion allows custom methods to be added to +// NamespaceLister. +type NamespaceListerExpansion interface{} + +// NodeListerExpansion allows custom methods to be added to +// NodeLister. +type NodeListerExpansion interface{} + +// PersistentVolumeListerExpansion allows custom methods to be added to +// PersistentVolumeLister. +type PersistentVolumeListerExpansion interface{} + +// PersistentVolumeClaimListerExpansion allows custom methods to be added to +// PersistentVolumeClaimLister. +type PersistentVolumeClaimListerExpansion interface{} + +// PersistentVolumeClaimNamespaceListerExpansion allows custom methods to be added to +// PersistentVolumeClaimNamespaceLister. +type PersistentVolumeClaimNamespaceListerExpansion interface{} + +// PodListerExpansion allows custom methods to be added to +// PodLister. +type PodListerExpansion interface{} + +// PodNamespaceListerExpansion allows custom methods to be added to +// PodNamespaceLister. +type PodNamespaceListerExpansion interface{} + +// PodTemplateListerExpansion allows custom methods to be added to +// PodTemplateLister. +type PodTemplateListerExpansion interface{} + +// PodTemplateNamespaceListerExpansion allows custom methods to be added to +// PodTemplateNamespaceLister. +type PodTemplateNamespaceListerExpansion interface{} + +// ResourceQuotaListerExpansion allows custom methods to be added to +// ResourceQuotaLister. +type ResourceQuotaListerExpansion interface{} + +// ResourceQuotaNamespaceListerExpansion allows custom methods to be added to +// ResourceQuotaNamespaceLister. +type ResourceQuotaNamespaceListerExpansion interface{} + +// SecretListerExpansion allows custom methods to be added to +// SecretLister. +type SecretListerExpansion interface{} + +// SecretNamespaceListerExpansion allows custom methods to be added to +// SecretNamespaceLister. +type SecretNamespaceListerExpansion interface{} + +// ServiceListerExpansion allows custom methods to be added to +// ServiceLister. +type ServiceListerExpansion interface{} + +// ServiceNamespaceListerExpansion allows custom methods to be added to +// ServiceNamespaceLister. +type ServiceNamespaceListerExpansion interface{} + +// ServiceAccountListerExpansion allows custom methods to be added to +// ServiceAccountLister. +type ServiceAccountListerExpansion interface{} + +// ServiceAccountNamespaceListerExpansion allows custom methods to be added to +// ServiceAccountNamespaceLister. +type ServiceAccountNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/core/v1/limitrange.go b/vendor/k8s.io/client-go/listers/core/v1/limitrange.go new file mode 100644 index 00000000000..d8fa569cd38 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/limitrange.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// LimitRangeLister helps list LimitRanges. +// All objects returned here must be treated as read-only. +type LimitRangeLister interface { + // List lists all LimitRanges in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.LimitRange, err error) + // LimitRanges returns an object that can list and get LimitRanges. + LimitRanges(namespace string) LimitRangeNamespaceLister + LimitRangeListerExpansion +} + +// limitRangeLister implements the LimitRangeLister interface. +type limitRangeLister struct { + indexer cache.Indexer +} + +// NewLimitRangeLister returns a new LimitRangeLister. +func NewLimitRangeLister(indexer cache.Indexer) LimitRangeLister { + return &limitRangeLister{indexer: indexer} +} + +// List lists all LimitRanges in the indexer. +func (s *limitRangeLister) List(selector labels.Selector) (ret []*v1.LimitRange, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.LimitRange)) + }) + return ret, err +} + +// LimitRanges returns an object that can list and get LimitRanges. +func (s *limitRangeLister) LimitRanges(namespace string) LimitRangeNamespaceLister { + return limitRangeNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// LimitRangeNamespaceLister helps list and get LimitRanges. +// All objects returned here must be treated as read-only. +type LimitRangeNamespaceLister interface { + // List lists all LimitRanges in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.LimitRange, err error) + // Get retrieves the LimitRange from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.LimitRange, error) + LimitRangeNamespaceListerExpansion +} + +// limitRangeNamespaceLister implements the LimitRangeNamespaceLister +// interface. +type limitRangeNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all LimitRanges in the indexer for a given namespace. +func (s limitRangeNamespaceLister) List(selector labels.Selector) (ret []*v1.LimitRange, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.LimitRange)) + }) + return ret, err +} + +// Get retrieves the LimitRange from the indexer for a given namespace and name. +func (s limitRangeNamespaceLister) Get(name string) (*v1.LimitRange, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("limitrange"), name) + } + return obj.(*v1.LimitRange), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/namespace.go b/vendor/k8s.io/client-go/listers/core/v1/namespace.go new file mode 100644 index 00000000000..454aa1a0a23 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/namespace.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// NamespaceLister helps list Namespaces. +// All objects returned here must be treated as read-only. +type NamespaceLister interface { + // List lists all Namespaces in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Namespace, err error) + // Get retrieves the Namespace from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Namespace, error) + NamespaceListerExpansion +} + +// namespaceLister implements the NamespaceLister interface. +type namespaceLister struct { + indexer cache.Indexer +} + +// NewNamespaceLister returns a new NamespaceLister. +func NewNamespaceLister(indexer cache.Indexer) NamespaceLister { + return &namespaceLister{indexer: indexer} +} + +// List lists all Namespaces in the indexer. +func (s *namespaceLister) List(selector labels.Selector) (ret []*v1.Namespace, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Namespace)) + }) + return ret, err +} + +// Get retrieves the Namespace from the index for a given name. +func (s *namespaceLister) Get(name string) (*v1.Namespace, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("namespace"), name) + } + return obj.(*v1.Namespace), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/node.go b/vendor/k8s.io/client-go/listers/core/v1/node.go new file mode 100644 index 00000000000..596049857f1 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/node.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// NodeLister helps list Nodes. +// All objects returned here must be treated as read-only. +type NodeLister interface { + // List lists all Nodes in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Node, err error) + // Get retrieves the Node from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Node, error) + NodeListerExpansion +} + +// nodeLister implements the NodeLister interface. +type nodeLister struct { + indexer cache.Indexer +} + +// NewNodeLister returns a new NodeLister. +func NewNodeLister(indexer cache.Indexer) NodeLister { + return &nodeLister{indexer: indexer} +} + +// List lists all Nodes in the indexer. +func (s *nodeLister) List(selector labels.Selector) (ret []*v1.Node, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Node)) + }) + return ret, err +} + +// Get retrieves the Node from the index for a given name. +func (s *nodeLister) Get(name string) (*v1.Node, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("node"), name) + } + return obj.(*v1.Node), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/persistentvolume.go b/vendor/k8s.io/client-go/listers/core/v1/persistentvolume.go new file mode 100644 index 00000000000..e7dfd4ac9f6 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/persistentvolume.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PersistentVolumeLister helps list PersistentVolumes. +// All objects returned here must be treated as read-only. +type PersistentVolumeLister interface { + // List lists all PersistentVolumes in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PersistentVolume, err error) + // Get retrieves the PersistentVolume from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.PersistentVolume, error) + PersistentVolumeListerExpansion +} + +// persistentVolumeLister implements the PersistentVolumeLister interface. +type persistentVolumeLister struct { + indexer cache.Indexer +} + +// NewPersistentVolumeLister returns a new PersistentVolumeLister. +func NewPersistentVolumeLister(indexer cache.Indexer) PersistentVolumeLister { + return &persistentVolumeLister{indexer: indexer} +} + +// List lists all PersistentVolumes in the indexer. +func (s *persistentVolumeLister) List(selector labels.Selector) (ret []*v1.PersistentVolume, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PersistentVolume)) + }) + return ret, err +} + +// Get retrieves the PersistentVolume from the index for a given name. +func (s *persistentVolumeLister) Get(name string) (*v1.PersistentVolume, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("persistentvolume"), name) + } + return obj.(*v1.PersistentVolume), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/persistentvolumeclaim.go b/vendor/k8s.io/client-go/listers/core/v1/persistentvolumeclaim.go new file mode 100644 index 00000000000..fc71bb5a1fd --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/persistentvolumeclaim.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PersistentVolumeClaimLister helps list PersistentVolumeClaims. +// All objects returned here must be treated as read-only. +type PersistentVolumeClaimLister interface { + // List lists all PersistentVolumeClaims in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) + // PersistentVolumeClaims returns an object that can list and get PersistentVolumeClaims. + PersistentVolumeClaims(namespace string) PersistentVolumeClaimNamespaceLister + PersistentVolumeClaimListerExpansion +} + +// persistentVolumeClaimLister implements the PersistentVolumeClaimLister interface. +type persistentVolumeClaimLister struct { + indexer cache.Indexer +} + +// NewPersistentVolumeClaimLister returns a new PersistentVolumeClaimLister. +func NewPersistentVolumeClaimLister(indexer cache.Indexer) PersistentVolumeClaimLister { + return &persistentVolumeClaimLister{indexer: indexer} +} + +// List lists all PersistentVolumeClaims in the indexer. +func (s *persistentVolumeClaimLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PersistentVolumeClaim)) + }) + return ret, err +} + +// PersistentVolumeClaims returns an object that can list and get PersistentVolumeClaims. +func (s *persistentVolumeClaimLister) PersistentVolumeClaims(namespace string) PersistentVolumeClaimNamespaceLister { + return persistentVolumeClaimNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PersistentVolumeClaimNamespaceLister helps list and get PersistentVolumeClaims. +// All objects returned here must be treated as read-only. +type PersistentVolumeClaimNamespaceLister interface { + // List lists all PersistentVolumeClaims in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) + // Get retrieves the PersistentVolumeClaim from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.PersistentVolumeClaim, error) + PersistentVolumeClaimNamespaceListerExpansion +} + +// persistentVolumeClaimNamespaceLister implements the PersistentVolumeClaimNamespaceLister +// interface. +type persistentVolumeClaimNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PersistentVolumeClaims in the indexer for a given namespace. +func (s persistentVolumeClaimNamespaceLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PersistentVolumeClaim)) + }) + return ret, err +} + +// Get retrieves the PersistentVolumeClaim from the indexer for a given namespace and name. +func (s persistentVolumeClaimNamespaceLister) Get(name string) (*v1.PersistentVolumeClaim, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("persistentvolumeclaim"), name) + } + return obj.(*v1.PersistentVolumeClaim), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/pod.go b/vendor/k8s.io/client-go/listers/core/v1/pod.go new file mode 100644 index 00000000000..ab8f0946c3d --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/pod.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodLister helps list Pods. +// All objects returned here must be treated as read-only. +type PodLister interface { + // List lists all Pods in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Pod, err error) + // Pods returns an object that can list and get Pods. + Pods(namespace string) PodNamespaceLister + PodListerExpansion +} + +// podLister implements the PodLister interface. +type podLister struct { + indexer cache.Indexer +} + +// NewPodLister returns a new PodLister. +func NewPodLister(indexer cache.Indexer) PodLister { + return &podLister{indexer: indexer} +} + +// List lists all Pods in the indexer. +func (s *podLister) List(selector labels.Selector) (ret []*v1.Pod, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Pod)) + }) + return ret, err +} + +// Pods returns an object that can list and get Pods. +func (s *podLister) Pods(namespace string) PodNamespaceLister { + return podNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodNamespaceLister helps list and get Pods. +// All objects returned here must be treated as read-only. +type PodNamespaceLister interface { + // List lists all Pods in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Pod, err error) + // Get retrieves the Pod from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Pod, error) + PodNamespaceListerExpansion +} + +// podNamespaceLister implements the PodNamespaceLister +// interface. +type podNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Pods in the indexer for a given namespace. +func (s podNamespaceLister) List(selector labels.Selector) (ret []*v1.Pod, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Pod)) + }) + return ret, err +} + +// Get retrieves the Pod from the indexer for a given namespace and name. +func (s podNamespaceLister) Get(name string) (*v1.Pod, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("pod"), name) + } + return obj.(*v1.Pod), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/podtemplate.go b/vendor/k8s.io/client-go/listers/core/v1/podtemplate.go new file mode 100644 index 00000000000..6c310045b71 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/podtemplate.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodTemplateLister helps list PodTemplates. +// All objects returned here must be treated as read-only. +type PodTemplateLister interface { + // List lists all PodTemplates in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PodTemplate, err error) + // PodTemplates returns an object that can list and get PodTemplates. + PodTemplates(namespace string) PodTemplateNamespaceLister + PodTemplateListerExpansion +} + +// podTemplateLister implements the PodTemplateLister interface. +type podTemplateLister struct { + indexer cache.Indexer +} + +// NewPodTemplateLister returns a new PodTemplateLister. +func NewPodTemplateLister(indexer cache.Indexer) PodTemplateLister { + return &podTemplateLister{indexer: indexer} +} + +// List lists all PodTemplates in the indexer. +func (s *podTemplateLister) List(selector labels.Selector) (ret []*v1.PodTemplate, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PodTemplate)) + }) + return ret, err +} + +// PodTemplates returns an object that can list and get PodTemplates. +func (s *podTemplateLister) PodTemplates(namespace string) PodTemplateNamespaceLister { + return podTemplateNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodTemplateNamespaceLister helps list and get PodTemplates. +// All objects returned here must be treated as read-only. +type PodTemplateNamespaceLister interface { + // List lists all PodTemplates in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PodTemplate, err error) + // Get retrieves the PodTemplate from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.PodTemplate, error) + PodTemplateNamespaceListerExpansion +} + +// podTemplateNamespaceLister implements the PodTemplateNamespaceLister +// interface. +type podTemplateNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodTemplates in the indexer for a given namespace. +func (s podTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1.PodTemplate, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PodTemplate)) + }) + return ret, err +} + +// Get retrieves the PodTemplate from the indexer for a given namespace and name. +func (s podTemplateNamespaceLister) Get(name string) (*v1.PodTemplate, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("podtemplate"), name) + } + return obj.(*v1.PodTemplate), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller.go b/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller.go new file mode 100644 index 00000000000..e28e2ef768e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ReplicationControllerLister helps list ReplicationControllers. +// All objects returned here must be treated as read-only. +type ReplicationControllerLister interface { + // List lists all ReplicationControllers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ReplicationController, err error) + // ReplicationControllers returns an object that can list and get ReplicationControllers. + ReplicationControllers(namespace string) ReplicationControllerNamespaceLister + ReplicationControllerListerExpansion +} + +// replicationControllerLister implements the ReplicationControllerLister interface. +type replicationControllerLister struct { + indexer cache.Indexer +} + +// NewReplicationControllerLister returns a new ReplicationControllerLister. +func NewReplicationControllerLister(indexer cache.Indexer) ReplicationControllerLister { + return &replicationControllerLister{indexer: indexer} +} + +// List lists all ReplicationControllers in the indexer. +func (s *replicationControllerLister) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ReplicationController)) + }) + return ret, err +} + +// ReplicationControllers returns an object that can list and get ReplicationControllers. +func (s *replicationControllerLister) ReplicationControllers(namespace string) ReplicationControllerNamespaceLister { + return replicationControllerNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ReplicationControllerNamespaceLister helps list and get ReplicationControllers. +// All objects returned here must be treated as read-only. +type ReplicationControllerNamespaceLister interface { + // List lists all ReplicationControllers in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ReplicationController, err error) + // Get retrieves the ReplicationController from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ReplicationController, error) + ReplicationControllerNamespaceListerExpansion +} + +// replicationControllerNamespaceLister implements the ReplicationControllerNamespaceLister +// interface. +type replicationControllerNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ReplicationControllers in the indexer for a given namespace. +func (s replicationControllerNamespaceLister) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ReplicationController)) + }) + return ret, err +} + +// Get retrieves the ReplicationController from the indexer for a given namespace and name. +func (s replicationControllerNamespaceLister) Get(name string) (*v1.ReplicationController, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("replicationcontroller"), name) + } + return obj.(*v1.ReplicationController), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller_expansion.go b/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller_expansion.go new file mode 100644 index 00000000000..b031d52173a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/replicationcontroller_expansion.go @@ -0,0 +1,66 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// ReplicationControllerListerExpansion allows custom methods to be added to +// ReplicationControllerLister. +type ReplicationControllerListerExpansion interface { + GetPodControllers(pod *v1.Pod) ([]*v1.ReplicationController, error) +} + +// ReplicationControllerNamespaceListerExpansion allows custom methods to be added to +// ReplicationControllerNamespaceLister. +type ReplicationControllerNamespaceListerExpansion interface{} + +// GetPodControllers returns a list of ReplicationControllers that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching ReplicationControllers are found. +func (s *replicationControllerLister) GetPodControllers(pod *v1.Pod) ([]*v1.ReplicationController, error) { + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name) + } + + items, err := s.ReplicationControllers(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var controllers []*v1.ReplicationController + for i := range items { + rc := items[i] + selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated() + + // If an rc with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + controllers = append(controllers, rc) + } + + if len(controllers) == 0 { + return nil, fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return controllers, nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/resourcequota.go b/vendor/k8s.io/client-go/listers/core/v1/resourcequota.go new file mode 100644 index 00000000000..9c00b49d4f5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/resourcequota.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceQuotaLister helps list ResourceQuotas. +// All objects returned here must be treated as read-only. +type ResourceQuotaLister interface { + // List lists all ResourceQuotas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ResourceQuota, err error) + // ResourceQuotas returns an object that can list and get ResourceQuotas. + ResourceQuotas(namespace string) ResourceQuotaNamespaceLister + ResourceQuotaListerExpansion +} + +// resourceQuotaLister implements the ResourceQuotaLister interface. +type resourceQuotaLister struct { + indexer cache.Indexer +} + +// NewResourceQuotaLister returns a new ResourceQuotaLister. +func NewResourceQuotaLister(indexer cache.Indexer) ResourceQuotaLister { + return &resourceQuotaLister{indexer: indexer} +} + +// List lists all ResourceQuotas in the indexer. +func (s *resourceQuotaLister) List(selector labels.Selector) (ret []*v1.ResourceQuota, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ResourceQuota)) + }) + return ret, err +} + +// ResourceQuotas returns an object that can list and get ResourceQuotas. +func (s *resourceQuotaLister) ResourceQuotas(namespace string) ResourceQuotaNamespaceLister { + return resourceQuotaNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ResourceQuotaNamespaceLister helps list and get ResourceQuotas. +// All objects returned here must be treated as read-only. +type ResourceQuotaNamespaceLister interface { + // List lists all ResourceQuotas in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ResourceQuota, err error) + // Get retrieves the ResourceQuota from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ResourceQuota, error) + ResourceQuotaNamespaceListerExpansion +} + +// resourceQuotaNamespaceLister implements the ResourceQuotaNamespaceLister +// interface. +type resourceQuotaNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ResourceQuotas in the indexer for a given namespace. +func (s resourceQuotaNamespaceLister) List(selector labels.Selector) (ret []*v1.ResourceQuota, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ResourceQuota)) + }) + return ret, err +} + +// Get retrieves the ResourceQuota from the indexer for a given namespace and name. +func (s resourceQuotaNamespaceLister) Get(name string) (*v1.ResourceQuota, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("resourcequota"), name) + } + return obj.(*v1.ResourceQuota), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/secret.go b/vendor/k8s.io/client-go/listers/core/v1/secret.go new file mode 100644 index 00000000000..d386d4d5cbd --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/secret.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// SecretLister helps list Secrets. +// All objects returned here must be treated as read-only. +type SecretLister interface { + // List lists all Secrets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Secret, err error) + // Secrets returns an object that can list and get Secrets. + Secrets(namespace string) SecretNamespaceLister + SecretListerExpansion +} + +// secretLister implements the SecretLister interface. +type secretLister struct { + indexer cache.Indexer +} + +// NewSecretLister returns a new SecretLister. +func NewSecretLister(indexer cache.Indexer) SecretLister { + return &secretLister{indexer: indexer} +} + +// List lists all Secrets in the indexer. +func (s *secretLister) List(selector labels.Selector) (ret []*v1.Secret, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Secret)) + }) + return ret, err +} + +// Secrets returns an object that can list and get Secrets. +func (s *secretLister) Secrets(namespace string) SecretNamespaceLister { + return secretNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// SecretNamespaceLister helps list and get Secrets. +// All objects returned here must be treated as read-only. +type SecretNamespaceLister interface { + // List lists all Secrets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Secret, err error) + // Get retrieves the Secret from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Secret, error) + SecretNamespaceListerExpansion +} + +// secretNamespaceLister implements the SecretNamespaceLister +// interface. +type secretNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Secrets in the indexer for a given namespace. +func (s secretNamespaceLister) List(selector labels.Selector) (ret []*v1.Secret, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Secret)) + }) + return ret, err +} + +// Get retrieves the Secret from the indexer for a given namespace and name. +func (s secretNamespaceLister) Get(name string) (*v1.Secret, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("secret"), name) + } + return obj.(*v1.Secret), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/service.go b/vendor/k8s.io/client-go/listers/core/v1/service.go new file mode 100644 index 00000000000..51026d7b4b6 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/service.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ServiceLister helps list Services. +// All objects returned here must be treated as read-only. +type ServiceLister interface { + // List lists all Services in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Service, err error) + // Services returns an object that can list and get Services. + Services(namespace string) ServiceNamespaceLister + ServiceListerExpansion +} + +// serviceLister implements the ServiceLister interface. +type serviceLister struct { + indexer cache.Indexer +} + +// NewServiceLister returns a new ServiceLister. +func NewServiceLister(indexer cache.Indexer) ServiceLister { + return &serviceLister{indexer: indexer} +} + +// List lists all Services in the indexer. +func (s *serviceLister) List(selector labels.Selector) (ret []*v1.Service, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Service)) + }) + return ret, err +} + +// Services returns an object that can list and get Services. +func (s *serviceLister) Services(namespace string) ServiceNamespaceLister { + return serviceNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServiceNamespaceLister helps list and get Services. +// All objects returned here must be treated as read-only. +type ServiceNamespaceLister interface { + // List lists all Services in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Service, err error) + // Get retrieves the Service from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Service, error) + ServiceNamespaceListerExpansion +} + +// serviceNamespaceLister implements the ServiceNamespaceLister +// interface. +type serviceNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Services in the indexer for a given namespace. +func (s serviceNamespaceLister) List(selector labels.Selector) (ret []*v1.Service, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Service)) + }) + return ret, err +} + +// Get retrieves the Service from the indexer for a given namespace and name. +func (s serviceNamespaceLister) Get(name string) (*v1.Service, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("service"), name) + } + return obj.(*v1.Service), nil +} diff --git a/vendor/k8s.io/client-go/listers/core/v1/serviceaccount.go b/vendor/k8s.io/client-go/listers/core/v1/serviceaccount.go new file mode 100644 index 00000000000..aa9554d8bb5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/core/v1/serviceaccount.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ServiceAccountLister helps list ServiceAccounts. +// All objects returned here must be treated as read-only. +type ServiceAccountLister interface { + // List lists all ServiceAccounts in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) + // ServiceAccounts returns an object that can list and get ServiceAccounts. + ServiceAccounts(namespace string) ServiceAccountNamespaceLister + ServiceAccountListerExpansion +} + +// serviceAccountLister implements the ServiceAccountLister interface. +type serviceAccountLister struct { + indexer cache.Indexer +} + +// NewServiceAccountLister returns a new ServiceAccountLister. +func NewServiceAccountLister(indexer cache.Indexer) ServiceAccountLister { + return &serviceAccountLister{indexer: indexer} +} + +// List lists all ServiceAccounts in the indexer. +func (s *serviceAccountLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ServiceAccount)) + }) + return ret, err +} + +// ServiceAccounts returns an object that can list and get ServiceAccounts. +func (s *serviceAccountLister) ServiceAccounts(namespace string) ServiceAccountNamespaceLister { + return serviceAccountNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServiceAccountNamespaceLister helps list and get ServiceAccounts. +// All objects returned here must be treated as read-only. +type ServiceAccountNamespaceLister interface { + // List lists all ServiceAccounts in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) + // Get retrieves the ServiceAccount from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ServiceAccount, error) + ServiceAccountNamespaceListerExpansion +} + +// serviceAccountNamespaceLister implements the ServiceAccountNamespaceLister +// interface. +type serviceAccountNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ServiceAccounts in the indexer for a given namespace. +func (s serviceAccountNamespaceLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ServiceAccount)) + }) + return ret, err +} + +// Get retrieves the ServiceAccount from the indexer for a given namespace and name. +func (s serviceAccountNamespaceLister) Get(name string) (*v1.ServiceAccount, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("serviceaccount"), name) + } + return obj.(*v1.ServiceAccount), nil +} diff --git a/vendor/k8s.io/client-go/listers/discovery/v1/endpointslice.go b/vendor/k8s.io/client-go/listers/discovery/v1/endpointslice.go new file mode 100644 index 00000000000..4dd46ff1bf9 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/discovery/v1/endpointslice.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/discovery/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EndpointSliceLister helps list EndpointSlices. +// All objects returned here must be treated as read-only. +type EndpointSliceLister interface { + // List lists all EndpointSlices in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.EndpointSlice, err error) + // EndpointSlices returns an object that can list and get EndpointSlices. + EndpointSlices(namespace string) EndpointSliceNamespaceLister + EndpointSliceListerExpansion +} + +// endpointSliceLister implements the EndpointSliceLister interface. +type endpointSliceLister struct { + indexer cache.Indexer +} + +// NewEndpointSliceLister returns a new EndpointSliceLister. +func NewEndpointSliceLister(indexer cache.Indexer) EndpointSliceLister { + return &endpointSliceLister{indexer: indexer} +} + +// List lists all EndpointSlices in the indexer. +func (s *endpointSliceLister) List(selector labels.Selector) (ret []*v1.EndpointSlice, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.EndpointSlice)) + }) + return ret, err +} + +// EndpointSlices returns an object that can list and get EndpointSlices. +func (s *endpointSliceLister) EndpointSlices(namespace string) EndpointSliceNamespaceLister { + return endpointSliceNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EndpointSliceNamespaceLister helps list and get EndpointSlices. +// All objects returned here must be treated as read-only. +type EndpointSliceNamespaceLister interface { + // List lists all EndpointSlices in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.EndpointSlice, err error) + // Get retrieves the EndpointSlice from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.EndpointSlice, error) + EndpointSliceNamespaceListerExpansion +} + +// endpointSliceNamespaceLister implements the EndpointSliceNamespaceLister +// interface. +type endpointSliceNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all EndpointSlices in the indexer for a given namespace. +func (s endpointSliceNamespaceLister) List(selector labels.Selector) (ret []*v1.EndpointSlice, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.EndpointSlice)) + }) + return ret, err +} + +// Get retrieves the EndpointSlice from the indexer for a given namespace and name. +func (s endpointSliceNamespaceLister) Get(name string) (*v1.EndpointSlice, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("endpointslice"), name) + } + return obj.(*v1.EndpointSlice), nil +} diff --git a/vendor/k8s.io/client-go/listers/discovery/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/discovery/v1/expansion_generated.go new file mode 100644 index 00000000000..660163eeef3 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/discovery/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// EndpointSliceListerExpansion allows custom methods to be added to +// EndpointSliceLister. +type EndpointSliceListerExpansion interface{} + +// EndpointSliceNamespaceListerExpansion allows custom methods to be added to +// EndpointSliceNamespaceLister. +type EndpointSliceNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/discovery/v1beta1/endpointslice.go b/vendor/k8s.io/client-go/listers/discovery/v1beta1/endpointslice.go new file mode 100644 index 00000000000..e92872d5f45 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/discovery/v1beta1/endpointslice.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/discovery/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EndpointSliceLister helps list EndpointSlices. +// All objects returned here must be treated as read-only. +type EndpointSliceLister interface { + // List lists all EndpointSlices in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.EndpointSlice, err error) + // EndpointSlices returns an object that can list and get EndpointSlices. + EndpointSlices(namespace string) EndpointSliceNamespaceLister + EndpointSliceListerExpansion +} + +// endpointSliceLister implements the EndpointSliceLister interface. +type endpointSliceLister struct { + indexer cache.Indexer +} + +// NewEndpointSliceLister returns a new EndpointSliceLister. +func NewEndpointSliceLister(indexer cache.Indexer) EndpointSliceLister { + return &endpointSliceLister{indexer: indexer} +} + +// List lists all EndpointSlices in the indexer. +func (s *endpointSliceLister) List(selector labels.Selector) (ret []*v1beta1.EndpointSlice, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.EndpointSlice)) + }) + return ret, err +} + +// EndpointSlices returns an object that can list and get EndpointSlices. +func (s *endpointSliceLister) EndpointSlices(namespace string) EndpointSliceNamespaceLister { + return endpointSliceNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EndpointSliceNamespaceLister helps list and get EndpointSlices. +// All objects returned here must be treated as read-only. +type EndpointSliceNamespaceLister interface { + // List lists all EndpointSlices in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.EndpointSlice, err error) + // Get retrieves the EndpointSlice from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.EndpointSlice, error) + EndpointSliceNamespaceListerExpansion +} + +// endpointSliceNamespaceLister implements the EndpointSliceNamespaceLister +// interface. +type endpointSliceNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all EndpointSlices in the indexer for a given namespace. +func (s endpointSliceNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.EndpointSlice, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.EndpointSlice)) + }) + return ret, err +} + +// Get retrieves the EndpointSlice from the indexer for a given namespace and name. +func (s endpointSliceNamespaceLister) Get(name string) (*v1beta1.EndpointSlice, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("endpointslice"), name) + } + return obj.(*v1beta1.EndpointSlice), nil +} diff --git a/vendor/k8s.io/client-go/listers/discovery/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/discovery/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..9619bbd8dd7 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/discovery/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// EndpointSliceListerExpansion allows custom methods to be added to +// EndpointSliceLister. +type EndpointSliceListerExpansion interface{} + +// EndpointSliceNamespaceListerExpansion allows custom methods to be added to +// EndpointSliceNamespaceLister. +type EndpointSliceNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/events/v1/event.go b/vendor/k8s.io/client-go/listers/events/v1/event.go new file mode 100644 index 00000000000..4abe841e265 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/events/v1/event.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/events/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EventLister helps list Events. +// All objects returned here must be treated as read-only. +type EventLister interface { + // List lists all Events in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Event, err error) + // Events returns an object that can list and get Events. + Events(namespace string) EventNamespaceLister + EventListerExpansion +} + +// eventLister implements the EventLister interface. +type eventLister struct { + indexer cache.Indexer +} + +// NewEventLister returns a new EventLister. +func NewEventLister(indexer cache.Indexer) EventLister { + return &eventLister{indexer: indexer} +} + +// List lists all Events in the indexer. +func (s *eventLister) List(selector labels.Selector) (ret []*v1.Event, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Event)) + }) + return ret, err +} + +// Events returns an object that can list and get Events. +func (s *eventLister) Events(namespace string) EventNamespaceLister { + return eventNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EventNamespaceLister helps list and get Events. +// All objects returned here must be treated as read-only. +type EventNamespaceLister interface { + // List lists all Events in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Event, err error) + // Get retrieves the Event from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Event, error) + EventNamespaceListerExpansion +} + +// eventNamespaceLister implements the EventNamespaceLister +// interface. +type eventNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Events in the indexer for a given namespace. +func (s eventNamespaceLister) List(selector labels.Selector) (ret []*v1.Event, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Event)) + }) + return ret, err +} + +// Get retrieves the Event from the indexer for a given namespace and name. +func (s eventNamespaceLister) Get(name string) (*v1.Event, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("event"), name) + } + return obj.(*v1.Event), nil +} diff --git a/vendor/k8s.io/client-go/listers/events/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/events/v1/expansion_generated.go new file mode 100644 index 00000000000..348e784d745 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/events/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// EventListerExpansion allows custom methods to be added to +// EventLister. +type EventListerExpansion interface{} + +// EventNamespaceListerExpansion allows custom methods to be added to +// EventNamespaceLister. +type EventNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/events/v1beta1/event.go b/vendor/k8s.io/client-go/listers/events/v1beta1/event.go new file mode 100644 index 00000000000..41a521be6f4 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/events/v1beta1/event.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/events/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EventLister helps list Events. +// All objects returned here must be treated as read-only. +type EventLister interface { + // List lists all Events in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Event, err error) + // Events returns an object that can list and get Events. + Events(namespace string) EventNamespaceLister + EventListerExpansion +} + +// eventLister implements the EventLister interface. +type eventLister struct { + indexer cache.Indexer +} + +// NewEventLister returns a new EventLister. +func NewEventLister(indexer cache.Indexer) EventLister { + return &eventLister{indexer: indexer} +} + +// List lists all Events in the indexer. +func (s *eventLister) List(selector labels.Selector) (ret []*v1beta1.Event, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Event)) + }) + return ret, err +} + +// Events returns an object that can list and get Events. +func (s *eventLister) Events(namespace string) EventNamespaceLister { + return eventNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EventNamespaceLister helps list and get Events. +// All objects returned here must be treated as read-only. +type EventNamespaceLister interface { + // List lists all Events in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Event, err error) + // Get retrieves the Event from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Event, error) + EventNamespaceListerExpansion +} + +// eventNamespaceLister implements the EventNamespaceLister +// interface. +type eventNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Events in the indexer for a given namespace. +func (s eventNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Event, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Event)) + }) + return ret, err +} + +// Get retrieves the Event from the indexer for a given namespace and name. +func (s eventNamespaceLister) Get(name string) (*v1beta1.Event, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("event"), name) + } + return obj.(*v1beta1.Event), nil +} diff --git a/vendor/k8s.io/client-go/listers/events/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/events/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..d311691d9da --- /dev/null +++ b/vendor/k8s.io/client-go/listers/events/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// EventListerExpansion allows custom methods to be added to +// EventLister. +type EventListerExpansion interface{} + +// EventNamespaceListerExpansion allows custom methods to be added to +// EventNamespaceLister. +type EventNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset.go new file mode 100644 index 00000000000..900475410b5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DaemonSetLister helps list DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetLister interface { + // List lists all DaemonSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.DaemonSet, err error) + // DaemonSets returns an object that can list and get DaemonSets. + DaemonSets(namespace string) DaemonSetNamespaceLister + DaemonSetListerExpansion +} + +// daemonSetLister implements the DaemonSetLister interface. +type daemonSetLister struct { + indexer cache.Indexer +} + +// NewDaemonSetLister returns a new DaemonSetLister. +func NewDaemonSetLister(indexer cache.Indexer) DaemonSetLister { + return &daemonSetLister{indexer: indexer} +} + +// List lists all DaemonSets in the indexer. +func (s *daemonSetLister) List(selector labels.Selector) (ret []*v1beta1.DaemonSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.DaemonSet)) + }) + return ret, err +} + +// DaemonSets returns an object that can list and get DaemonSets. +func (s *daemonSetLister) DaemonSets(namespace string) DaemonSetNamespaceLister { + return daemonSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DaemonSetNamespaceLister helps list and get DaemonSets. +// All objects returned here must be treated as read-only. +type DaemonSetNamespaceLister interface { + // List lists all DaemonSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.DaemonSet, err error) + // Get retrieves the DaemonSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.DaemonSet, error) + DaemonSetNamespaceListerExpansion +} + +// daemonSetNamespaceLister implements the DaemonSetNamespaceLister +// interface. +type daemonSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all DaemonSets in the indexer for a given namespace. +func (s daemonSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.DaemonSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.DaemonSet)) + }) + return ret, err +} + +// Get retrieves the DaemonSet from the indexer for a given namespace and name. +func (s daemonSetNamespaceLister) Get(name string) (*v1beta1.DaemonSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("daemonset"), name) + } + return obj.(*v1beta1.DaemonSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset_expansion.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset_expansion.go new file mode 100644 index 00000000000..f6dd7a963e8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/daemonset_expansion.go @@ -0,0 +1,115 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "fmt" + + apps "k8s.io/api/apps/v1beta1" + "k8s.io/api/core/v1" + "k8s.io/api/extensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// DaemonSetListerExpansion allows custom methods to be added to +// DaemonSetLister. +type DaemonSetListerExpansion interface { + GetPodDaemonSets(pod *v1.Pod) ([]*v1beta1.DaemonSet, error) + GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*v1beta1.DaemonSet, error) +} + +// DaemonSetNamespaceListerExpansion allows custom methods to be added to +// DaemonSetNamespaceLister. +type DaemonSetNamespaceListerExpansion interface{} + +// GetPodDaemonSets returns a list of DaemonSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetPodDaemonSets(pod *v1.Pod) ([]*v1beta1.DaemonSet, error) { + var selector labels.Selector + var daemonSet *v1beta1.DaemonSet + + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.DaemonSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*v1beta1.DaemonSet + for i := range list { + daemonSet = list[i] + if daemonSet.Namespace != pod.Namespace { + continue + } + selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + daemonSets = append(daemonSets, daemonSet) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return daemonSets, nil +} + +// GetHistoryDaemonSets returns a list of DaemonSets that potentially +// match a ControllerRevision. Only the one specified in the ControllerRevision's ControllerRef +// will actually manage it. +// Returns an error only if no matching DaemonSets are found. +func (s *daemonSetLister) GetHistoryDaemonSets(history *apps.ControllerRevision) ([]*v1beta1.DaemonSet, error) { + if len(history.Labels) == 0 { + return nil, fmt.Errorf("no DaemonSet found for ControllerRevision %s because it has no labels", history.Name) + } + + list, err := s.DaemonSets(history.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var daemonSets []*v1beta1.DaemonSet + for _, ds := range list { + selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the history object + continue + } + // If a DaemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(history.Labels)) { + continue + } + daemonSets = append(daemonSets, ds) + } + + if len(daemonSets) == 0 { + return nil, fmt.Errorf("could not find DaemonSets for ControllerRevision %s in namespace %s with labels: %v", history.Name, history.Namespace, history.Labels) + } + + return daemonSets, nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/deployment.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/deployment.go new file mode 100644 index 00000000000..42b5a07231b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/deployment.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DeploymentLister helps list Deployments. +// All objects returned here must be treated as read-only. +type DeploymentLister interface { + // List lists all Deployments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) + // Deployments returns an object that can list and get Deployments. + Deployments(namespace string) DeploymentNamespaceLister + DeploymentListerExpansion +} + +// deploymentLister implements the DeploymentLister interface. +type deploymentLister struct { + indexer cache.Indexer +} + +// NewDeploymentLister returns a new DeploymentLister. +func NewDeploymentLister(indexer cache.Indexer) DeploymentLister { + return &deploymentLister{indexer: indexer} +} + +// List lists all Deployments in the indexer. +func (s *deploymentLister) List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Deployment)) + }) + return ret, err +} + +// Deployments returns an object that can list and get Deployments. +func (s *deploymentLister) Deployments(namespace string) DeploymentNamespaceLister { + return deploymentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DeploymentNamespaceLister helps list and get Deployments. +// All objects returned here must be treated as read-only. +type DeploymentNamespaceLister interface { + // List lists all Deployments in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) + // Get retrieves the Deployment from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Deployment, error) + DeploymentNamespaceListerExpansion +} + +// deploymentNamespaceLister implements the DeploymentNamespaceLister +// interface. +type deploymentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Deployments in the indexer for a given namespace. +func (s deploymentNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Deployment, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Deployment)) + }) + return ret, err +} + +// Get retrieves the Deployment from the indexer for a given namespace and name. +func (s deploymentNamespaceLister) Get(name string) (*v1beta1.Deployment, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("deployment"), name) + } + return obj.(*v1beta1.Deployment), nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..4c65dbf7645 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// DeploymentListerExpansion allows custom methods to be added to +// DeploymentLister. +type DeploymentListerExpansion interface{} + +// DeploymentNamespaceListerExpansion allows custom methods to be added to +// DeploymentNamespaceLister. +type DeploymentNamespaceListerExpansion interface{} + +// IngressListerExpansion allows custom methods to be added to +// IngressLister. +type IngressListerExpansion interface{} + +// IngressNamespaceListerExpansion allows custom methods to be added to +// IngressNamespaceLister. +type IngressNamespaceListerExpansion interface{} + +// NetworkPolicyListerExpansion allows custom methods to be added to +// NetworkPolicyLister. +type NetworkPolicyListerExpansion interface{} + +// NetworkPolicyNamespaceListerExpansion allows custom methods to be added to +// NetworkPolicyNamespaceLister. +type NetworkPolicyNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/ingress.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/ingress.go new file mode 100644 index 00000000000..1cb7677bd80 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/ingress.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressLister helps list Ingresses. +// All objects returned here must be treated as read-only. +type IngressLister interface { + // List lists all Ingresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) + // Ingresses returns an object that can list and get Ingresses. + Ingresses(namespace string) IngressNamespaceLister + IngressListerExpansion +} + +// ingressLister implements the IngressLister interface. +type ingressLister struct { + indexer cache.Indexer +} + +// NewIngressLister returns a new IngressLister. +func NewIngressLister(indexer cache.Indexer) IngressLister { + return &ingressLister{indexer: indexer} +} + +// List lists all Ingresses in the indexer. +func (s *ingressLister) List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Ingress)) + }) + return ret, err +} + +// Ingresses returns an object that can list and get Ingresses. +func (s *ingressLister) Ingresses(namespace string) IngressNamespaceLister { + return ingressNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// IngressNamespaceLister helps list and get Ingresses. +// All objects returned here must be treated as read-only. +type IngressNamespaceLister interface { + // List lists all Ingresses in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) + // Get retrieves the Ingress from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Ingress, error) + IngressNamespaceListerExpansion +} + +// ingressNamespaceLister implements the IngressNamespaceLister +// interface. +type ingressNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Ingresses in the indexer for a given namespace. +func (s ingressNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Ingress)) + }) + return ret, err +} + +// Get retrieves the Ingress from the indexer for a given namespace and name. +func (s ingressNamespaceLister) Get(name string) (*v1beta1.Ingress, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("ingress"), name) + } + return obj.(*v1beta1.Ingress), nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/networkpolicy.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/networkpolicy.go new file mode 100644 index 00000000000..84419a8e966 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/networkpolicy.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// NetworkPolicyLister helps list NetworkPolicies. +// All objects returned here must be treated as read-only. +type NetworkPolicyLister interface { + // List lists all NetworkPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.NetworkPolicy, err error) + // NetworkPolicies returns an object that can list and get NetworkPolicies. + NetworkPolicies(namespace string) NetworkPolicyNamespaceLister + NetworkPolicyListerExpansion +} + +// networkPolicyLister implements the NetworkPolicyLister interface. +type networkPolicyLister struct { + indexer cache.Indexer +} + +// NewNetworkPolicyLister returns a new NetworkPolicyLister. +func NewNetworkPolicyLister(indexer cache.Indexer) NetworkPolicyLister { + return &networkPolicyLister{indexer: indexer} +} + +// List lists all NetworkPolicies in the indexer. +func (s *networkPolicyLister) List(selector labels.Selector) (ret []*v1beta1.NetworkPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.NetworkPolicy)) + }) + return ret, err +} + +// NetworkPolicies returns an object that can list and get NetworkPolicies. +func (s *networkPolicyLister) NetworkPolicies(namespace string) NetworkPolicyNamespaceLister { + return networkPolicyNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// NetworkPolicyNamespaceLister helps list and get NetworkPolicies. +// All objects returned here must be treated as read-only. +type NetworkPolicyNamespaceLister interface { + // List lists all NetworkPolicies in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.NetworkPolicy, err error) + // Get retrieves the NetworkPolicy from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.NetworkPolicy, error) + NetworkPolicyNamespaceListerExpansion +} + +// networkPolicyNamespaceLister implements the NetworkPolicyNamespaceLister +// interface. +type networkPolicyNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all NetworkPolicies in the indexer for a given namespace. +func (s networkPolicyNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.NetworkPolicy, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.NetworkPolicy)) + }) + return ret, err +} + +// Get retrieves the NetworkPolicy from the indexer for a given namespace and name. +func (s networkPolicyNamespaceLister) Get(name string) (*v1beta1.NetworkPolicy, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("networkpolicy"), name) + } + return obj.(*v1beta1.NetworkPolicy), nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset.go new file mode 100644 index 00000000000..a5ec3229bc3 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ReplicaSetLister helps list ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetLister interface { + // List lists all ReplicaSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ReplicaSet, err error) + // ReplicaSets returns an object that can list and get ReplicaSets. + ReplicaSets(namespace string) ReplicaSetNamespaceLister + ReplicaSetListerExpansion +} + +// replicaSetLister implements the ReplicaSetLister interface. +type replicaSetLister struct { + indexer cache.Indexer +} + +// NewReplicaSetLister returns a new ReplicaSetLister. +func NewReplicaSetLister(indexer cache.Indexer) ReplicaSetLister { + return &replicaSetLister{indexer: indexer} +} + +// List lists all ReplicaSets in the indexer. +func (s *replicaSetLister) List(selector labels.Selector) (ret []*v1beta1.ReplicaSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ReplicaSet)) + }) + return ret, err +} + +// ReplicaSets returns an object that can list and get ReplicaSets. +func (s *replicaSetLister) ReplicaSets(namespace string) ReplicaSetNamespaceLister { + return replicaSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ReplicaSetNamespaceLister helps list and get ReplicaSets. +// All objects returned here must be treated as read-only. +type ReplicaSetNamespaceLister interface { + // List lists all ReplicaSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ReplicaSet, err error) + // Get retrieves the ReplicaSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ReplicaSet, error) + ReplicaSetNamespaceListerExpansion +} + +// replicaSetNamespaceLister implements the ReplicaSetNamespaceLister +// interface. +type replicaSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ReplicaSets in the indexer for a given namespace. +func (s replicaSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ReplicaSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ReplicaSet)) + }) + return ret, err +} + +// Get retrieves the ReplicaSet from the indexer for a given namespace and name. +func (s replicaSetNamespaceLister) Get(name string) (*v1beta1.ReplicaSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("replicaset"), name) + } + return obj.(*v1beta1.ReplicaSet), nil +} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset_expansion.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset_expansion.go new file mode 100644 index 00000000000..74114c2bd7d --- /dev/null +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/replicaset_expansion.go @@ -0,0 +1,74 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "fmt" + + "k8s.io/api/core/v1" + extensions "k8s.io/api/extensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// ReplicaSetListerExpansion allows custom methods to be added to +// ReplicaSetLister. +type ReplicaSetListerExpansion interface { + GetPodReplicaSets(pod *v1.Pod) ([]*extensions.ReplicaSet, error) +} + +// ReplicaSetNamespaceListerExpansion allows custom methods to be added to +// ReplicaSetNamespaceLister. +type ReplicaSetNamespaceListerExpansion interface{} + +// GetPodReplicaSets returns a list of ReplicaSets that potentially match a pod. +// Only the one specified in the Pod's ControllerRef will actually manage it. +// Returns an error only if no matching ReplicaSets are found. +func (s *replicaSetLister) GetPodReplicaSets(pod *v1.Pod) ([]*extensions.ReplicaSet, error) { + if len(pod.Labels) == 0 { + return nil, fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) + } + + list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var rss []*extensions.ReplicaSet + for _, rs := range list { + if rs.Namespace != pod.Namespace { + continue + } + selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + rss = append(rss, rs) + } + + if len(rss) == 0 { + return nil, fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return rss, nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..3e74051681c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// FlowSchemaListerExpansion allows custom methods to be added to +// FlowSchemaLister. +type FlowSchemaListerExpansion interface{} + +// PriorityLevelConfigurationListerExpansion allows custom methods to be added to +// PriorityLevelConfigurationLister. +type PriorityLevelConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/flowschema.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/flowschema.go new file mode 100644 index 00000000000..c8a595cd29c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/flowschema.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// FlowSchemaLister helps list FlowSchemas. +// All objects returned here must be treated as read-only. +type FlowSchemaLister interface { + // List lists all FlowSchemas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.FlowSchema, err error) + // Get retrieves the FlowSchema from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.FlowSchema, error) + FlowSchemaListerExpansion +} + +// flowSchemaLister implements the FlowSchemaLister interface. +type flowSchemaLister struct { + indexer cache.Indexer +} + +// NewFlowSchemaLister returns a new FlowSchemaLister. +func NewFlowSchemaLister(indexer cache.Indexer) FlowSchemaLister { + return &flowSchemaLister{indexer: indexer} +} + +// List lists all FlowSchemas in the indexer. +func (s *flowSchemaLister) List(selector labels.Selector) (ret []*v1alpha1.FlowSchema, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.FlowSchema)) + }) + return ret, err +} + +// Get retrieves the FlowSchema from the index for a given name. +func (s *flowSchemaLister) Get(name string) (*v1alpha1.FlowSchema, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("flowschema"), name) + } + return obj.(*v1alpha1.FlowSchema), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/prioritylevelconfiguration.go new file mode 100644 index 00000000000..daa4ff31d93 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1alpha1/prioritylevelconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/flowcontrol/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationLister helps list PriorityLevelConfigurations. +// All objects returned here must be treated as read-only. +type PriorityLevelConfigurationLister interface { + // List lists all PriorityLevelConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.PriorityLevelConfiguration, err error) + // Get retrieves the PriorityLevelConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.PriorityLevelConfiguration, error) + PriorityLevelConfigurationListerExpansion +} + +// priorityLevelConfigurationLister implements the PriorityLevelConfigurationLister interface. +type priorityLevelConfigurationLister struct { + indexer cache.Indexer +} + +// NewPriorityLevelConfigurationLister returns a new PriorityLevelConfigurationLister. +func NewPriorityLevelConfigurationLister(indexer cache.Indexer) PriorityLevelConfigurationLister { + return &priorityLevelConfigurationLister{indexer: indexer} +} + +// List lists all PriorityLevelConfigurations in the indexer. +func (s *priorityLevelConfigurationLister) List(selector labels.Selector) (ret []*v1alpha1.PriorityLevelConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.PriorityLevelConfiguration)) + }) + return ret, err +} + +// Get retrieves the PriorityLevelConfiguration from the index for a given name. +func (s *priorityLevelConfigurationLister) Get(name string) (*v1alpha1.PriorityLevelConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("prioritylevelconfiguration"), name) + } + return obj.(*v1alpha1.PriorityLevelConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..c674e951e0e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// FlowSchemaListerExpansion allows custom methods to be added to +// FlowSchemaLister. +type FlowSchemaListerExpansion interface{} + +// PriorityLevelConfigurationListerExpansion allows custom methods to be added to +// PriorityLevelConfigurationLister. +type PriorityLevelConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/flowschema.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/flowschema.go new file mode 100644 index 00000000000..7927a8411ee --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/flowschema.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/flowcontrol/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// FlowSchemaLister helps list FlowSchemas. +// All objects returned here must be treated as read-only. +type FlowSchemaLister interface { + // List lists all FlowSchemas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.FlowSchema, err error) + // Get retrieves the FlowSchema from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.FlowSchema, error) + FlowSchemaListerExpansion +} + +// flowSchemaLister implements the FlowSchemaLister interface. +type flowSchemaLister struct { + indexer cache.Indexer +} + +// NewFlowSchemaLister returns a new FlowSchemaLister. +func NewFlowSchemaLister(indexer cache.Indexer) FlowSchemaLister { + return &flowSchemaLister{indexer: indexer} +} + +// List lists all FlowSchemas in the indexer. +func (s *flowSchemaLister) List(selector labels.Selector) (ret []*v1beta1.FlowSchema, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.FlowSchema)) + }) + return ret, err +} + +// Get retrieves the FlowSchema from the index for a given name. +func (s *flowSchemaLister) Get(name string) (*v1beta1.FlowSchema, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("flowschema"), name) + } + return obj.(*v1beta1.FlowSchema), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/prioritylevelconfiguration.go new file mode 100644 index 00000000000..c94aaa4c1d1 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta1/prioritylevelconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/flowcontrol/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationLister helps list PriorityLevelConfigurations. +// All objects returned here must be treated as read-only. +type PriorityLevelConfigurationLister interface { + // List lists all PriorityLevelConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.PriorityLevelConfiguration, err error) + // Get retrieves the PriorityLevelConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.PriorityLevelConfiguration, error) + PriorityLevelConfigurationListerExpansion +} + +// priorityLevelConfigurationLister implements the PriorityLevelConfigurationLister interface. +type priorityLevelConfigurationLister struct { + indexer cache.Indexer +} + +// NewPriorityLevelConfigurationLister returns a new PriorityLevelConfigurationLister. +func NewPriorityLevelConfigurationLister(indexer cache.Indexer) PriorityLevelConfigurationLister { + return &priorityLevelConfigurationLister{indexer: indexer} +} + +// List lists all PriorityLevelConfigurations in the indexer. +func (s *priorityLevelConfigurationLister) List(selector labels.Selector) (ret []*v1beta1.PriorityLevelConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.PriorityLevelConfiguration)) + }) + return ret, err +} + +// Get retrieves the PriorityLevelConfiguration from the index for a given name. +func (s *priorityLevelConfigurationLister) Get(name string) (*v1beta1.PriorityLevelConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("prioritylevelconfiguration"), name) + } + return obj.(*v1beta1.PriorityLevelConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/expansion_generated.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/expansion_generated.go new file mode 100644 index 00000000000..b658de6549c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +// FlowSchemaListerExpansion allows custom methods to be added to +// FlowSchemaLister. +type FlowSchemaListerExpansion interface{} + +// PriorityLevelConfigurationListerExpansion allows custom methods to be added to +// PriorityLevelConfigurationLister. +type PriorityLevelConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/flowschema.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/flowschema.go new file mode 100644 index 00000000000..2710f263060 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/flowschema.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/flowcontrol/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// FlowSchemaLister helps list FlowSchemas. +// All objects returned here must be treated as read-only. +type FlowSchemaLister interface { + // List lists all FlowSchemas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.FlowSchema, err error) + // Get retrieves the FlowSchema from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.FlowSchema, error) + FlowSchemaListerExpansion +} + +// flowSchemaLister implements the FlowSchemaLister interface. +type flowSchemaLister struct { + indexer cache.Indexer +} + +// NewFlowSchemaLister returns a new FlowSchemaLister. +func NewFlowSchemaLister(indexer cache.Indexer) FlowSchemaLister { + return &flowSchemaLister{indexer: indexer} +} + +// List lists all FlowSchemas in the indexer. +func (s *flowSchemaLister) List(selector labels.Selector) (ret []*v1beta2.FlowSchema, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.FlowSchema)) + }) + return ret, err +} + +// Get retrieves the FlowSchema from the index for a given name. +func (s *flowSchemaLister) Get(name string) (*v1beta2.FlowSchema, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("flowschema"), name) + } + return obj.(*v1beta2.FlowSchema), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/prioritylevelconfiguration.go new file mode 100644 index 00000000000..00ede00709a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta2/prioritylevelconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1beta2 "k8s.io/api/flowcontrol/v1beta2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationLister helps list PriorityLevelConfigurations. +// All objects returned here must be treated as read-only. +type PriorityLevelConfigurationLister interface { + // List lists all PriorityLevelConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta2.PriorityLevelConfiguration, err error) + // Get retrieves the PriorityLevelConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta2.PriorityLevelConfiguration, error) + PriorityLevelConfigurationListerExpansion +} + +// priorityLevelConfigurationLister implements the PriorityLevelConfigurationLister interface. +type priorityLevelConfigurationLister struct { + indexer cache.Indexer +} + +// NewPriorityLevelConfigurationLister returns a new PriorityLevelConfigurationLister. +func NewPriorityLevelConfigurationLister(indexer cache.Indexer) PriorityLevelConfigurationLister { + return &priorityLevelConfigurationLister{indexer: indexer} +} + +// List lists all PriorityLevelConfigurations in the indexer. +func (s *priorityLevelConfigurationLister) List(selector labels.Selector) (ret []*v1beta2.PriorityLevelConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta2.PriorityLevelConfiguration)) + }) + return ret, err +} + +// Get retrieves the PriorityLevelConfiguration from the index for a given name. +func (s *priorityLevelConfigurationLister) Get(name string) (*v1beta2.PriorityLevelConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta2.Resource("prioritylevelconfiguration"), name) + } + return obj.(*v1beta2.PriorityLevelConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/expansion_generated.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/expansion_generated.go new file mode 100644 index 00000000000..5c14f337b73 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta3 + +// FlowSchemaListerExpansion allows custom methods to be added to +// FlowSchemaLister. +type FlowSchemaListerExpansion interface{} + +// PriorityLevelConfigurationListerExpansion allows custom methods to be added to +// PriorityLevelConfigurationLister. +type PriorityLevelConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/flowschema.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/flowschema.go new file mode 100644 index 00000000000..ef01b5a76eb --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/flowschema.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// FlowSchemaLister helps list FlowSchemas. +// All objects returned here must be treated as read-only. +type FlowSchemaLister interface { + // List lists all FlowSchemas in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta3.FlowSchema, err error) + // Get retrieves the FlowSchema from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta3.FlowSchema, error) + FlowSchemaListerExpansion +} + +// flowSchemaLister implements the FlowSchemaLister interface. +type flowSchemaLister struct { + indexer cache.Indexer +} + +// NewFlowSchemaLister returns a new FlowSchemaLister. +func NewFlowSchemaLister(indexer cache.Indexer) FlowSchemaLister { + return &flowSchemaLister{indexer: indexer} +} + +// List lists all FlowSchemas in the indexer. +func (s *flowSchemaLister) List(selector labels.Selector) (ret []*v1beta3.FlowSchema, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta3.FlowSchema)) + }) + return ret, err +} + +// Get retrieves the FlowSchema from the index for a given name. +func (s *flowSchemaLister) Get(name string) (*v1beta3.FlowSchema, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta3.Resource("flowschema"), name) + } + return obj.(*v1beta3.FlowSchema), nil +} diff --git a/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/prioritylevelconfiguration.go new file mode 100644 index 00000000000..d05613949f9 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/flowcontrol/v1beta3/prioritylevelconfiguration.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta3 + +import ( + v1beta3 "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityLevelConfigurationLister helps list PriorityLevelConfigurations. +// All objects returned here must be treated as read-only. +type PriorityLevelConfigurationLister interface { + // List lists all PriorityLevelConfigurations in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta3.PriorityLevelConfiguration, err error) + // Get retrieves the PriorityLevelConfiguration from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta3.PriorityLevelConfiguration, error) + PriorityLevelConfigurationListerExpansion +} + +// priorityLevelConfigurationLister implements the PriorityLevelConfigurationLister interface. +type priorityLevelConfigurationLister struct { + indexer cache.Indexer +} + +// NewPriorityLevelConfigurationLister returns a new PriorityLevelConfigurationLister. +func NewPriorityLevelConfigurationLister(indexer cache.Indexer) PriorityLevelConfigurationLister { + return &priorityLevelConfigurationLister{indexer: indexer} +} + +// List lists all PriorityLevelConfigurations in the indexer. +func (s *priorityLevelConfigurationLister) List(selector labels.Selector) (ret []*v1beta3.PriorityLevelConfiguration, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta3.PriorityLevelConfiguration)) + }) + return ret, err +} + +// Get retrieves the PriorityLevelConfiguration from the index for a given name. +func (s *priorityLevelConfigurationLister) Get(name string) (*v1beta3.PriorityLevelConfiguration, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta3.Resource("prioritylevelconfiguration"), name) + } + return obj.(*v1beta3.PriorityLevelConfiguration), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/networking/v1/expansion_generated.go new file mode 100644 index 00000000000..a380c2418fc --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1/expansion_generated.go @@ -0,0 +1,39 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// IngressListerExpansion allows custom methods to be added to +// IngressLister. +type IngressListerExpansion interface{} + +// IngressNamespaceListerExpansion allows custom methods to be added to +// IngressNamespaceLister. +type IngressNamespaceListerExpansion interface{} + +// IngressClassListerExpansion allows custom methods to be added to +// IngressClassLister. +type IngressClassListerExpansion interface{} + +// NetworkPolicyListerExpansion allows custom methods to be added to +// NetworkPolicyLister. +type NetworkPolicyListerExpansion interface{} + +// NetworkPolicyNamespaceListerExpansion allows custom methods to be added to +// NetworkPolicyNamespaceLister. +type NetworkPolicyNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/networking/v1/ingress.go b/vendor/k8s.io/client-go/listers/networking/v1/ingress.go new file mode 100644 index 00000000000..0f49d4f572c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1/ingress.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressLister helps list Ingresses. +// All objects returned here must be treated as read-only. +type IngressLister interface { + // List lists all Ingresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Ingress, err error) + // Ingresses returns an object that can list and get Ingresses. + Ingresses(namespace string) IngressNamespaceLister + IngressListerExpansion +} + +// ingressLister implements the IngressLister interface. +type ingressLister struct { + indexer cache.Indexer +} + +// NewIngressLister returns a new IngressLister. +func NewIngressLister(indexer cache.Indexer) IngressLister { + return &ingressLister{indexer: indexer} +} + +// List lists all Ingresses in the indexer. +func (s *ingressLister) List(selector labels.Selector) (ret []*v1.Ingress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Ingress)) + }) + return ret, err +} + +// Ingresses returns an object that can list and get Ingresses. +func (s *ingressLister) Ingresses(namespace string) IngressNamespaceLister { + return ingressNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// IngressNamespaceLister helps list and get Ingresses. +// All objects returned here must be treated as read-only. +type IngressNamespaceLister interface { + // List lists all Ingresses in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Ingress, err error) + // Get retrieves the Ingress from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Ingress, error) + IngressNamespaceListerExpansion +} + +// ingressNamespaceLister implements the IngressNamespaceLister +// interface. +type ingressNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Ingresses in the indexer for a given namespace. +func (s ingressNamespaceLister) List(selector labels.Selector) (ret []*v1.Ingress, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Ingress)) + }) + return ret, err +} + +// Get retrieves the Ingress from the indexer for a given namespace and name. +func (s ingressNamespaceLister) Get(name string) (*v1.Ingress, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("ingress"), name) + } + return obj.(*v1.Ingress), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1/ingressclass.go b/vendor/k8s.io/client-go/listers/networking/v1/ingressclass.go new file mode 100644 index 00000000000..1480cb13fdf --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1/ingressclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressClassLister helps list IngressClasses. +// All objects returned here must be treated as read-only. +type IngressClassLister interface { + // List lists all IngressClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.IngressClass, err error) + // Get retrieves the IngressClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.IngressClass, error) + IngressClassListerExpansion +} + +// ingressClassLister implements the IngressClassLister interface. +type ingressClassLister struct { + indexer cache.Indexer +} + +// NewIngressClassLister returns a new IngressClassLister. +func NewIngressClassLister(indexer cache.Indexer) IngressClassLister { + return &ingressClassLister{indexer: indexer} +} + +// List lists all IngressClasses in the indexer. +func (s *ingressClassLister) List(selector labels.Selector) (ret []*v1.IngressClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.IngressClass)) + }) + return ret, err +} + +// Get retrieves the IngressClass from the index for a given name. +func (s *ingressClassLister) Get(name string) (*v1.IngressClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("ingressclass"), name) + } + return obj.(*v1.IngressClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1/networkpolicy.go b/vendor/k8s.io/client-go/listers/networking/v1/networkpolicy.go new file mode 100644 index 00000000000..34cabf0577a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1/networkpolicy.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// NetworkPolicyLister helps list NetworkPolicies. +// All objects returned here must be treated as read-only. +type NetworkPolicyLister interface { + // List lists all NetworkPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.NetworkPolicy, err error) + // NetworkPolicies returns an object that can list and get NetworkPolicies. + NetworkPolicies(namespace string) NetworkPolicyNamespaceLister + NetworkPolicyListerExpansion +} + +// networkPolicyLister implements the NetworkPolicyLister interface. +type networkPolicyLister struct { + indexer cache.Indexer +} + +// NewNetworkPolicyLister returns a new NetworkPolicyLister. +func NewNetworkPolicyLister(indexer cache.Indexer) NetworkPolicyLister { + return &networkPolicyLister{indexer: indexer} +} + +// List lists all NetworkPolicies in the indexer. +func (s *networkPolicyLister) List(selector labels.Selector) (ret []*v1.NetworkPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.NetworkPolicy)) + }) + return ret, err +} + +// NetworkPolicies returns an object that can list and get NetworkPolicies. +func (s *networkPolicyLister) NetworkPolicies(namespace string) NetworkPolicyNamespaceLister { + return networkPolicyNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// NetworkPolicyNamespaceLister helps list and get NetworkPolicies. +// All objects returned here must be treated as read-only. +type NetworkPolicyNamespaceLister interface { + // List lists all NetworkPolicies in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.NetworkPolicy, err error) + // Get retrieves the NetworkPolicy from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.NetworkPolicy, error) + NetworkPolicyNamespaceListerExpansion +} + +// networkPolicyNamespaceLister implements the NetworkPolicyNamespaceLister +// interface. +type networkPolicyNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all NetworkPolicies in the indexer for a given namespace. +func (s networkPolicyNamespaceLister) List(selector labels.Selector) (ret []*v1.NetworkPolicy, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.NetworkPolicy)) + }) + return ret, err +} + +// Get retrieves the NetworkPolicy from the indexer for a given namespace and name. +func (s networkPolicyNamespaceLister) Get(name string) (*v1.NetworkPolicy, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("networkpolicy"), name) + } + return obj.(*v1.NetworkPolicy), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/clustercidr.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/clustercidr.go new file mode 100644 index 00000000000..dca9d7bf0cb --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/clustercidr.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/networking/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterCIDRLister helps list ClusterCIDRs. +// All objects returned here must be treated as read-only. +type ClusterCIDRLister interface { + // List lists all ClusterCIDRs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterCIDR, err error) + // Get retrieves the ClusterCIDR from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterCIDR, error) + ClusterCIDRListerExpansion +} + +// clusterCIDRLister implements the ClusterCIDRLister interface. +type clusterCIDRLister struct { + indexer cache.Indexer +} + +// NewClusterCIDRLister returns a new ClusterCIDRLister. +func NewClusterCIDRLister(indexer cache.Indexer) ClusterCIDRLister { + return &clusterCIDRLister{indexer: indexer} +} + +// List lists all ClusterCIDRs in the indexer. +func (s *clusterCIDRLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterCIDR, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterCIDR)) + }) + return ret, err +} + +// Get retrieves the ClusterCIDR from the index for a given name. +func (s *clusterCIDRLister) Get(name string) (*v1alpha1.ClusterCIDR, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clustercidr"), name) + } + return obj.(*v1alpha1.ClusterCIDR), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..d57b71b0059 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterCIDRListerExpansion allows custom methods to be added to +// ClusterCIDRLister. +type ClusterCIDRListerExpansion interface{} + +// IPAddressListerExpansion allows custom methods to be added to +// IPAddressLister. +type IPAddressListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go new file mode 100644 index 00000000000..b3dfe27971f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/networking/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IPAddressLister helps list IPAddresses. +// All objects returned here must be treated as read-only. +type IPAddressLister interface { + // List lists all IPAddresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) + // Get retrieves the IPAddress from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.IPAddress, error) + IPAddressListerExpansion +} + +// iPAddressLister implements the IPAddressLister interface. +type iPAddressLister struct { + indexer cache.Indexer +} + +// NewIPAddressLister returns a new IPAddressLister. +func NewIPAddressLister(indexer cache.Indexer) IPAddressLister { + return &iPAddressLister{indexer: indexer} +} + +// List lists all IPAddresses in the indexer. +func (s *iPAddressLister) List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.IPAddress)) + }) + return ret, err +} + +// Get retrieves the IPAddress from the index for a given name. +func (s *iPAddressLister) Get(name string) (*v1alpha1.IPAddress, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("ipaddress"), name) + } + return obj.(*v1alpha1.IPAddress), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/networking/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..d8c99c186e5 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1beta1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// IngressListerExpansion allows custom methods to be added to +// IngressLister. +type IngressListerExpansion interface{} + +// IngressNamespaceListerExpansion allows custom methods to be added to +// IngressNamespaceLister. +type IngressNamespaceListerExpansion interface{} + +// IngressClassListerExpansion allows custom methods to be added to +// IngressClassLister. +type IngressClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/networking/v1beta1/ingress.go b/vendor/k8s.io/client-go/listers/networking/v1beta1/ingress.go new file mode 100644 index 00000000000..b8f4d355802 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1beta1/ingress.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/networking/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressLister helps list Ingresses. +// All objects returned here must be treated as read-only. +type IngressLister interface { + // List lists all Ingresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) + // Ingresses returns an object that can list and get Ingresses. + Ingresses(namespace string) IngressNamespaceLister + IngressListerExpansion +} + +// ingressLister implements the IngressLister interface. +type ingressLister struct { + indexer cache.Indexer +} + +// NewIngressLister returns a new IngressLister. +func NewIngressLister(indexer cache.Indexer) IngressLister { + return &ingressLister{indexer: indexer} +} + +// List lists all Ingresses in the indexer. +func (s *ingressLister) List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Ingress)) + }) + return ret, err +} + +// Ingresses returns an object that can list and get Ingresses. +func (s *ingressLister) Ingresses(namespace string) IngressNamespaceLister { + return ingressNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// IngressNamespaceLister helps list and get Ingresses. +// All objects returned here must be treated as read-only. +type IngressNamespaceLister interface { + // List lists all Ingresses in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) + // Get retrieves the Ingress from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Ingress, error) + IngressNamespaceListerExpansion +} + +// ingressNamespaceLister implements the IngressNamespaceLister +// interface. +type ingressNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Ingresses in the indexer for a given namespace. +func (s ingressNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Ingress, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Ingress)) + }) + return ret, err +} + +// Get retrieves the Ingress from the indexer for a given namespace and name. +func (s ingressNamespaceLister) Get(name string) (*v1beta1.Ingress, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("ingress"), name) + } + return obj.(*v1beta1.Ingress), nil +} diff --git a/vendor/k8s.io/client-go/listers/networking/v1beta1/ingressclass.go b/vendor/k8s.io/client-go/listers/networking/v1beta1/ingressclass.go new file mode 100644 index 00000000000..ebcd6ba85b1 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1beta1/ingressclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/networking/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IngressClassLister helps list IngressClasses. +// All objects returned here must be treated as read-only. +type IngressClassLister interface { + // List lists all IngressClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.IngressClass, err error) + // Get retrieves the IngressClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.IngressClass, error) + IngressClassListerExpansion +} + +// ingressClassLister implements the IngressClassLister interface. +type ingressClassLister struct { + indexer cache.Indexer +} + +// NewIngressClassLister returns a new IngressClassLister. +func NewIngressClassLister(indexer cache.Indexer) IngressClassLister { + return &ingressClassLister{indexer: indexer} +} + +// List lists all IngressClasses in the indexer. +func (s *ingressClassLister) List(selector labels.Selector) (ret []*v1beta1.IngressClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.IngressClass)) + }) + return ret, err +} + +// Get retrieves the IngressClass from the index for a given name. +func (s *ingressClassLister) Get(name string) (*v1beta1.IngressClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("ingressclass"), name) + } + return obj.(*v1beta1.IngressClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/node/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/node/v1/expansion_generated.go new file mode 100644 index 00000000000..4f010b87c30 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// RuntimeClassListerExpansion allows custom methods to be added to +// RuntimeClassLister. +type RuntimeClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/node/v1/runtimeclass.go b/vendor/k8s.io/client-go/listers/node/v1/runtimeclass.go new file mode 100644 index 00000000000..6e00cf1a592 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1/runtimeclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/node/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RuntimeClassLister helps list RuntimeClasses. +// All objects returned here must be treated as read-only. +type RuntimeClassLister interface { + // List lists all RuntimeClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.RuntimeClass, err error) + // Get retrieves the RuntimeClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.RuntimeClass, error) + RuntimeClassListerExpansion +} + +// runtimeClassLister implements the RuntimeClassLister interface. +type runtimeClassLister struct { + indexer cache.Indexer +} + +// NewRuntimeClassLister returns a new RuntimeClassLister. +func NewRuntimeClassLister(indexer cache.Indexer) RuntimeClassLister { + return &runtimeClassLister{indexer: indexer} +} + +// List lists all RuntimeClasses in the indexer. +func (s *runtimeClassLister) List(selector labels.Selector) (ret []*v1.RuntimeClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RuntimeClass)) + }) + return ret, err +} + +// Get retrieves the RuntimeClass from the index for a given name. +func (s *runtimeClassLister) Get(name string) (*v1.RuntimeClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("runtimeclass"), name) + } + return obj.(*v1.RuntimeClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/node/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/node/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..a65c208fac3 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// RuntimeClassListerExpansion allows custom methods to be added to +// RuntimeClassLister. +type RuntimeClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/node/v1alpha1/runtimeclass.go b/vendor/k8s.io/client-go/listers/node/v1alpha1/runtimeclass.go new file mode 100644 index 00000000000..31f3357990b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1alpha1/runtimeclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/node/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RuntimeClassLister helps list RuntimeClasses. +// All objects returned here must be treated as read-only. +type RuntimeClassLister interface { + // List lists all RuntimeClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.RuntimeClass, err error) + // Get retrieves the RuntimeClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.RuntimeClass, error) + RuntimeClassListerExpansion +} + +// runtimeClassLister implements the RuntimeClassLister interface. +type runtimeClassLister struct { + indexer cache.Indexer +} + +// NewRuntimeClassLister returns a new RuntimeClassLister. +func NewRuntimeClassLister(indexer cache.Indexer) RuntimeClassLister { + return &runtimeClassLister{indexer: indexer} +} + +// List lists all RuntimeClasses in the indexer. +func (s *runtimeClassLister) List(selector labels.Selector) (ret []*v1alpha1.RuntimeClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.RuntimeClass)) + }) + return ret, err +} + +// Get retrieves the RuntimeClass from the index for a given name. +func (s *runtimeClassLister) Get(name string) (*v1alpha1.RuntimeClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("runtimeclass"), name) + } + return obj.(*v1alpha1.RuntimeClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/node/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/node/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..a6744055ce4 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1beta1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// RuntimeClassListerExpansion allows custom methods to be added to +// RuntimeClassLister. +type RuntimeClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/node/v1beta1/runtimeclass.go b/vendor/k8s.io/client-go/listers/node/v1beta1/runtimeclass.go new file mode 100644 index 00000000000..7dbd6ab268b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/node/v1beta1/runtimeclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/node/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RuntimeClassLister helps list RuntimeClasses. +// All objects returned here must be treated as read-only. +type RuntimeClassLister interface { + // List lists all RuntimeClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.RuntimeClass, err error) + // Get retrieves the RuntimeClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.RuntimeClass, error) + RuntimeClassListerExpansion +} + +// runtimeClassLister implements the RuntimeClassLister interface. +type runtimeClassLister struct { + indexer cache.Indexer +} + +// NewRuntimeClassLister returns a new RuntimeClassLister. +func NewRuntimeClassLister(indexer cache.Indexer) RuntimeClassLister { + return &runtimeClassLister{indexer: indexer} +} + +// List lists all RuntimeClasses in the indexer. +func (s *runtimeClassLister) List(selector labels.Selector) (ret []*v1beta1.RuntimeClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.RuntimeClass)) + }) + return ret, err +} + +// Get retrieves the RuntimeClass from the index for a given name. +func (s *runtimeClassLister) Get(name string) (*v1beta1.RuntimeClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("runtimeclass"), name) + } + return obj.(*v1beta1.RuntimeClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1/eviction.go b/vendor/k8s.io/client-go/listers/policy/v1/eviction.go new file mode 100644 index 00000000000..dc5ffa0740f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1/eviction.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/policy/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EvictionLister helps list Evictions. +// All objects returned here must be treated as read-only. +type EvictionLister interface { + // List lists all Evictions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Eviction, err error) + // Evictions returns an object that can list and get Evictions. + Evictions(namespace string) EvictionNamespaceLister + EvictionListerExpansion +} + +// evictionLister implements the EvictionLister interface. +type evictionLister struct { + indexer cache.Indexer +} + +// NewEvictionLister returns a new EvictionLister. +func NewEvictionLister(indexer cache.Indexer) EvictionLister { + return &evictionLister{indexer: indexer} +} + +// List lists all Evictions in the indexer. +func (s *evictionLister) List(selector labels.Selector) (ret []*v1.Eviction, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Eviction)) + }) + return ret, err +} + +// Evictions returns an object that can list and get Evictions. +func (s *evictionLister) Evictions(namespace string) EvictionNamespaceLister { + return evictionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EvictionNamespaceLister helps list and get Evictions. +// All objects returned here must be treated as read-only. +type EvictionNamespaceLister interface { + // List lists all Evictions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Eviction, err error) + // Get retrieves the Eviction from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Eviction, error) + EvictionNamespaceListerExpansion +} + +// evictionNamespaceLister implements the EvictionNamespaceLister +// interface. +type evictionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Evictions in the indexer for a given namespace. +func (s evictionNamespaceLister) List(selector labels.Selector) (ret []*v1.Eviction, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Eviction)) + }) + return ret, err +} + +// Get retrieves the Eviction from the indexer for a given namespace and name. +func (s evictionNamespaceLister) Get(name string) (*v1.Eviction, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("eviction"), name) + } + return obj.(*v1.Eviction), nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/policy/v1/expansion_generated.go new file mode 100644 index 00000000000..8e2d55a9117 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// EvictionListerExpansion allows custom methods to be added to +// EvictionLister. +type EvictionListerExpansion interface{} + +// EvictionNamespaceListerExpansion allows custom methods to be added to +// EvictionNamespaceLister. +type EvictionNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget.go b/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget.go new file mode 100644 index 00000000000..8470d38bb29 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/policy/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodDisruptionBudgetLister helps list PodDisruptionBudgets. +// All objects returned here must be treated as read-only. +type PodDisruptionBudgetLister interface { + // List lists all PodDisruptionBudgets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PodDisruptionBudget, err error) + // PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. + PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister + PodDisruptionBudgetListerExpansion +} + +// podDisruptionBudgetLister implements the PodDisruptionBudgetLister interface. +type podDisruptionBudgetLister struct { + indexer cache.Indexer +} + +// NewPodDisruptionBudgetLister returns a new PodDisruptionBudgetLister. +func NewPodDisruptionBudgetLister(indexer cache.Indexer) PodDisruptionBudgetLister { + return &podDisruptionBudgetLister{indexer: indexer} +} + +// List lists all PodDisruptionBudgets in the indexer. +func (s *podDisruptionBudgetLister) List(selector labels.Selector) (ret []*v1.PodDisruptionBudget, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PodDisruptionBudget)) + }) + return ret, err +} + +// PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. +func (s *podDisruptionBudgetLister) PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister { + return podDisruptionBudgetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodDisruptionBudgetNamespaceLister helps list and get PodDisruptionBudgets. +// All objects returned here must be treated as read-only. +type PodDisruptionBudgetNamespaceLister interface { + // List lists all PodDisruptionBudgets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PodDisruptionBudget, err error) + // Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.PodDisruptionBudget, error) + PodDisruptionBudgetNamespaceListerExpansion +} + +// podDisruptionBudgetNamespaceLister implements the PodDisruptionBudgetNamespaceLister +// interface. +type podDisruptionBudgetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodDisruptionBudgets in the indexer for a given namespace. +func (s podDisruptionBudgetNamespaceLister) List(selector labels.Selector) (ret []*v1.PodDisruptionBudget, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PodDisruptionBudget)) + }) + return ret, err +} + +// Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. +func (s podDisruptionBudgetNamespaceLister) Get(name string) (*v1.PodDisruptionBudget, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("poddisruptionbudget"), name) + } + return obj.(*v1.PodDisruptionBudget), nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget_expansion.go b/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget_expansion.go new file mode 100644 index 00000000000..115ee3f0047 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1/poddisruptionbudget_expansion.go @@ -0,0 +1,68 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + "k8s.io/api/core/v1" + policy "k8s.io/api/policy/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// PodDisruptionBudgetListerExpansion allows custom methods to be added to +// PodDisruptionBudgetLister. +type PodDisruptionBudgetListerExpansion interface { + GetPodPodDisruptionBudgets(pod *v1.Pod) ([]*policy.PodDisruptionBudget, error) +} + +// PodDisruptionBudgetNamespaceListerExpansion allows custom methods to be added to +// PodDisruptionBudgetNamespaceLister. +type PodDisruptionBudgetNamespaceListerExpansion interface{} + +// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. +func (s *podDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *v1.Pod) ([]*policy.PodDisruptionBudget, error) { + var selector labels.Selector + + list, err := s.PodDisruptionBudgets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var pdbList []*policy.PodDisruptionBudget + for i := range list { + pdb := list[i] + selector, err = metav1.LabelSelectorAsSelector(pdb.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // Unlike the v1beta version, here we let an empty selector match everything. + if !selector.Matches(labels.Set(pod.Labels)) { + continue + } + pdbList = append(pdbList, pdb) + } + + if len(pdbList) == 0 { + return nil, fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return pdbList, nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1beta1/eviction.go b/vendor/k8s.io/client-go/listers/policy/v1beta1/eviction.go new file mode 100644 index 00000000000..e1d40d0b32f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1beta1/eviction.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/policy/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// EvictionLister helps list Evictions. +// All objects returned here must be treated as read-only. +type EvictionLister interface { + // List lists all Evictions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Eviction, err error) + // Evictions returns an object that can list and get Evictions. + Evictions(namespace string) EvictionNamespaceLister + EvictionListerExpansion +} + +// evictionLister implements the EvictionLister interface. +type evictionLister struct { + indexer cache.Indexer +} + +// NewEvictionLister returns a new EvictionLister. +func NewEvictionLister(indexer cache.Indexer) EvictionLister { + return &evictionLister{indexer: indexer} +} + +// List lists all Evictions in the indexer. +func (s *evictionLister) List(selector labels.Selector) (ret []*v1beta1.Eviction, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Eviction)) + }) + return ret, err +} + +// Evictions returns an object that can list and get Evictions. +func (s *evictionLister) Evictions(namespace string) EvictionNamespaceLister { + return evictionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EvictionNamespaceLister helps list and get Evictions. +// All objects returned here must be treated as read-only. +type EvictionNamespaceLister interface { + // List lists all Evictions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Eviction, err error) + // Get retrieves the Eviction from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Eviction, error) + EvictionNamespaceListerExpansion +} + +// evictionNamespaceLister implements the EvictionNamespaceLister +// interface. +type evictionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Evictions in the indexer for a given namespace. +func (s evictionNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Eviction, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Eviction)) + }) + return ret, err +} + +// Get retrieves the Eviction from the indexer for a given namespace and name. +func (s evictionNamespaceLister) Get(name string) (*v1beta1.Eviction, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("eviction"), name) + } + return obj.(*v1beta1.Eviction), nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/policy/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..9a005f20bb8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1beta1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// EvictionListerExpansion allows custom methods to be added to +// EvictionLister. +type EvictionListerExpansion interface{} + +// EvictionNamespaceListerExpansion allows custom methods to be added to +// EvictionNamespaceLister. +type EvictionNamespaceListerExpansion interface{} + +// PodSecurityPolicyListerExpansion allows custom methods to be added to +// PodSecurityPolicyLister. +type PodSecurityPolicyListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget.go b/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget.go new file mode 100644 index 00000000000..aa08f813eef --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/policy/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodDisruptionBudgetLister helps list PodDisruptionBudgets. +// All objects returned here must be treated as read-only. +type PodDisruptionBudgetLister interface { + // List lists all PodDisruptionBudgets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.PodDisruptionBudget, err error) + // PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. + PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister + PodDisruptionBudgetListerExpansion +} + +// podDisruptionBudgetLister implements the PodDisruptionBudgetLister interface. +type podDisruptionBudgetLister struct { + indexer cache.Indexer +} + +// NewPodDisruptionBudgetLister returns a new PodDisruptionBudgetLister. +func NewPodDisruptionBudgetLister(indexer cache.Indexer) PodDisruptionBudgetLister { + return &podDisruptionBudgetLister{indexer: indexer} +} + +// List lists all PodDisruptionBudgets in the indexer. +func (s *podDisruptionBudgetLister) List(selector labels.Selector) (ret []*v1beta1.PodDisruptionBudget, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.PodDisruptionBudget)) + }) + return ret, err +} + +// PodDisruptionBudgets returns an object that can list and get PodDisruptionBudgets. +func (s *podDisruptionBudgetLister) PodDisruptionBudgets(namespace string) PodDisruptionBudgetNamespaceLister { + return podDisruptionBudgetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodDisruptionBudgetNamespaceLister helps list and get PodDisruptionBudgets. +// All objects returned here must be treated as read-only. +type PodDisruptionBudgetNamespaceLister interface { + // List lists all PodDisruptionBudgets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.PodDisruptionBudget, err error) + // Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.PodDisruptionBudget, error) + PodDisruptionBudgetNamespaceListerExpansion +} + +// podDisruptionBudgetNamespaceLister implements the PodDisruptionBudgetNamespaceLister +// interface. +type podDisruptionBudgetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodDisruptionBudgets in the indexer for a given namespace. +func (s podDisruptionBudgetNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.PodDisruptionBudget, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.PodDisruptionBudget)) + }) + return ret, err +} + +// Get retrieves the PodDisruptionBudget from the indexer for a given namespace and name. +func (s podDisruptionBudgetNamespaceLister) Get(name string) (*v1beta1.PodDisruptionBudget, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("poddisruptionbudget"), name) + } + return obj.(*v1beta1.PodDisruptionBudget), nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget_expansion.go b/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget_expansion.go new file mode 100644 index 00000000000..994947c4f3c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1beta1/poddisruptionbudget_expansion.go @@ -0,0 +1,68 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "fmt" + + "k8s.io/api/core/v1" + policy "k8s.io/api/policy/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// PodDisruptionBudgetListerExpansion allows custom methods to be added to +// PodDisruptionBudgetLister. +type PodDisruptionBudgetListerExpansion interface { + GetPodPodDisruptionBudgets(pod *v1.Pod) ([]*policy.PodDisruptionBudget, error) +} + +// PodDisruptionBudgetNamespaceListerExpansion allows custom methods to be added to +// PodDisruptionBudgetNamespaceLister. +type PodDisruptionBudgetNamespaceListerExpansion interface{} + +// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found. +func (s *podDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *v1.Pod) ([]*policy.PodDisruptionBudget, error) { + var selector labels.Selector + + list, err := s.PodDisruptionBudgets(pod.Namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var pdbList []*policy.PodDisruptionBudget + for i := range list { + pdb := list[i] + selector, err = metav1.LabelSelectorAsSelector(pdb.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + + // If a PDB with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + pdbList = append(pdbList, pdb) + } + + if len(pdbList) == 0 { + return nil, fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return pdbList, nil +} diff --git a/vendor/k8s.io/client-go/listers/policy/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/listers/policy/v1beta1/podsecuritypolicy.go new file mode 100644 index 00000000000..7e73161b25a --- /dev/null +++ b/vendor/k8s.io/client-go/listers/policy/v1beta1/podsecuritypolicy.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/policy/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodSecurityPolicyLister helps list PodSecurityPolicies. +// All objects returned here must be treated as read-only. +type PodSecurityPolicyLister interface { + // List lists all PodSecurityPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.PodSecurityPolicy, err error) + // Get retrieves the PodSecurityPolicy from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.PodSecurityPolicy, error) + PodSecurityPolicyListerExpansion +} + +// podSecurityPolicyLister implements the PodSecurityPolicyLister interface. +type podSecurityPolicyLister struct { + indexer cache.Indexer +} + +// NewPodSecurityPolicyLister returns a new PodSecurityPolicyLister. +func NewPodSecurityPolicyLister(indexer cache.Indexer) PodSecurityPolicyLister { + return &podSecurityPolicyLister{indexer: indexer} +} + +// List lists all PodSecurityPolicies in the indexer. +func (s *podSecurityPolicyLister) List(selector labels.Selector) (ret []*v1beta1.PodSecurityPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.PodSecurityPolicy)) + }) + return ret, err +} + +// Get retrieves the PodSecurityPolicy from the index for a given name. +func (s *podSecurityPolicyLister) Get(name string) (*v1beta1.PodSecurityPolicy, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("podsecuritypolicy"), name) + } + return obj.(*v1beta1.PodSecurityPolicy), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1/clusterrole.go b/vendor/k8s.io/client-go/listers/rbac/v1/clusterrole.go new file mode 100644 index 00000000000..84dc003ca2e --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1/clusterrole.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleLister helps list ClusterRoles. +// All objects returned here must be treated as read-only. +type ClusterRoleLister interface { + // List lists all ClusterRoles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ClusterRole, err error) + // Get retrieves the ClusterRole from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ClusterRole, error) + ClusterRoleListerExpansion +} + +// clusterRoleLister implements the ClusterRoleLister interface. +type clusterRoleLister struct { + indexer cache.Indexer +} + +// NewClusterRoleLister returns a new ClusterRoleLister. +func NewClusterRoleLister(indexer cache.Indexer) ClusterRoleLister { + return &clusterRoleLister{indexer: indexer} +} + +// List lists all ClusterRoles in the indexer. +func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1.ClusterRole, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ClusterRole)) + }) + return ret, err +} + +// Get retrieves the ClusterRole from the index for a given name. +func (s *clusterRoleLister) Get(name string) (*v1.ClusterRole, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("clusterrole"), name) + } + return obj.(*v1.ClusterRole), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go new file mode 100644 index 00000000000..ff061d4b2b8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingLister helps list ClusterRoleBindings. +// All objects returned here must be treated as read-only. +type ClusterRoleBindingLister interface { + // List lists all ClusterRoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ClusterRoleBinding, err error) + // Get retrieves the ClusterRoleBinding from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ClusterRoleBinding, error) + ClusterRoleBindingListerExpansion +} + +// clusterRoleBindingLister implements the ClusterRoleBindingLister interface. +type clusterRoleBindingLister struct { + indexer cache.Indexer +} + +// NewClusterRoleBindingLister returns a new ClusterRoleBindingLister. +func NewClusterRoleBindingLister(indexer cache.Indexer) ClusterRoleBindingLister { + return &clusterRoleBindingLister{indexer: indexer} +} + +// List lists all ClusterRoleBindings in the indexer. +func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1.ClusterRoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ClusterRoleBinding)) + }) + return ret, err +} + +// Get retrieves the ClusterRoleBinding from the index for a given name. +func (s *clusterRoleBindingLister) Get(name string) (*v1.ClusterRoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("clusterrolebinding"), name) + } + return obj.(*v1.ClusterRoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/rbac/v1/expansion_generated.go new file mode 100644 index 00000000000..0eb2a6d114f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// ClusterRoleListerExpansion allows custom methods to be added to +// ClusterRoleLister. +type ClusterRoleListerExpansion interface{} + +// ClusterRoleBindingListerExpansion allows custom methods to be added to +// ClusterRoleBindingLister. +type ClusterRoleBindingListerExpansion interface{} + +// RoleListerExpansion allows custom methods to be added to +// RoleLister. +type RoleListerExpansion interface{} + +// RoleNamespaceListerExpansion allows custom methods to be added to +// RoleNamespaceLister. +type RoleNamespaceListerExpansion interface{} + +// RoleBindingListerExpansion allows custom methods to be added to +// RoleBindingLister. +type RoleBindingListerExpansion interface{} + +// RoleBindingNamespaceListerExpansion allows custom methods to be added to +// RoleBindingNamespaceLister. +type RoleBindingNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1/role.go b/vendor/k8s.io/client-go/listers/rbac/v1/role.go new file mode 100644 index 00000000000..503f013b520 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1/role.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleLister helps list Roles. +// All objects returned here must be treated as read-only. +type RoleLister interface { + // List lists all Roles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Role, err error) + // Roles returns an object that can list and get Roles. + Roles(namespace string) RoleNamespaceLister + RoleListerExpansion +} + +// roleLister implements the RoleLister interface. +type roleLister struct { + indexer cache.Indexer +} + +// NewRoleLister returns a new RoleLister. +func NewRoleLister(indexer cache.Indexer) RoleLister { + return &roleLister{indexer: indexer} +} + +// List lists all Roles in the indexer. +func (s *roleLister) List(selector labels.Selector) (ret []*v1.Role, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Role)) + }) + return ret, err +} + +// Roles returns an object that can list and get Roles. +func (s *roleLister) Roles(namespace string) RoleNamespaceLister { + return roleNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleNamespaceLister helps list and get Roles. +// All objects returned here must be treated as read-only. +type RoleNamespaceLister interface { + // List lists all Roles in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Role, err error) + // Get retrieves the Role from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Role, error) + RoleNamespaceListerExpansion +} + +// roleNamespaceLister implements the RoleNamespaceLister +// interface. +type roleNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Roles in the indexer for a given namespace. +func (s roleNamespaceLister) List(selector labels.Selector) (ret []*v1.Role, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Role)) + }) + return ret, err +} + +// Get retrieves the Role from the indexer for a given namespace and name. +func (s roleNamespaceLister) Get(name string) (*v1.Role, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("role"), name) + } + return obj.(*v1.Role), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1/rolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1/rolebinding.go new file mode 100644 index 00000000000..ea50c641360 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1/rolebinding.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleBindingLister helps list RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingLister interface { + // List lists all RoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.RoleBinding, err error) + // RoleBindings returns an object that can list and get RoleBindings. + RoleBindings(namespace string) RoleBindingNamespaceLister + RoleBindingListerExpansion +} + +// roleBindingLister implements the RoleBindingLister interface. +type roleBindingLister struct { + indexer cache.Indexer +} + +// NewRoleBindingLister returns a new RoleBindingLister. +func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister { + return &roleBindingLister{indexer: indexer} +} + +// List lists all RoleBindings in the indexer. +func (s *roleBindingLister) List(selector labels.Selector) (ret []*v1.RoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RoleBinding)) + }) + return ret, err +} + +// RoleBindings returns an object that can list and get RoleBindings. +func (s *roleBindingLister) RoleBindings(namespace string) RoleBindingNamespaceLister { + return roleBindingNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleBindingNamespaceLister helps list and get RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingNamespaceLister interface { + // List lists all RoleBindings in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.RoleBinding, err error) + // Get retrieves the RoleBinding from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.RoleBinding, error) + RoleBindingNamespaceListerExpansion +} + +// roleBindingNamespaceLister implements the RoleBindingNamespaceLister +// interface. +type roleBindingNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all RoleBindings in the indexer for a given namespace. +func (s roleBindingNamespaceLister) List(selector labels.Selector) (ret []*v1.RoleBinding, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RoleBinding)) + }) + return ret, err +} + +// Get retrieves the RoleBinding from the indexer for a given namespace and name. +func (s roleBindingNamespaceLister) Get(name string) (*v1.RoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("rolebinding"), name) + } + return obj.(*v1.RoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go new file mode 100644 index 00000000000..181ea95a7d4 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/rbac/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleLister helps list ClusterRoles. +// All objects returned here must be treated as read-only. +type ClusterRoleLister interface { + // List lists all ClusterRoles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterRole, err error) + // Get retrieves the ClusterRole from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterRole, error) + ClusterRoleListerExpansion +} + +// clusterRoleLister implements the ClusterRoleLister interface. +type clusterRoleLister struct { + indexer cache.Indexer +} + +// NewClusterRoleLister returns a new ClusterRoleLister. +func NewClusterRoleLister(indexer cache.Indexer) ClusterRoleLister { + return &clusterRoleLister{indexer: indexer} +} + +// List lists all ClusterRoles in the indexer. +func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterRole, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterRole)) + }) + return ret, err +} + +// Get retrieves the ClusterRole from the index for a given name. +func (s *clusterRoleLister) Get(name string) (*v1alpha1.ClusterRole, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clusterrole"), name) + } + return obj.(*v1alpha1.ClusterRole), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go new file mode 100644 index 00000000000..29d283b6cf2 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/rbac/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingLister helps list ClusterRoleBindings. +// All objects returned here must be treated as read-only. +type ClusterRoleBindingLister interface { + // List lists all ClusterRoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterRoleBinding, err error) + // Get retrieves the ClusterRoleBinding from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterRoleBinding, error) + ClusterRoleBindingListerExpansion +} + +// clusterRoleBindingLister implements the ClusterRoleBindingLister interface. +type clusterRoleBindingLister struct { + indexer cache.Indexer +} + +// NewClusterRoleBindingLister returns a new ClusterRoleBindingLister. +func NewClusterRoleBindingLister(indexer cache.Indexer) ClusterRoleBindingLister { + return &clusterRoleBindingLister{indexer: indexer} +} + +// List lists all ClusterRoleBindings in the indexer. +func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterRoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterRoleBinding)) + }) + return ret, err +} + +// Get retrieves the ClusterRoleBinding from the index for a given name. +func (s *clusterRoleBindingLister) Get(name string) (*v1alpha1.ClusterRoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clusterrolebinding"), name) + } + return obj.(*v1alpha1.ClusterRoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..2d4ad1756e8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterRoleListerExpansion allows custom methods to be added to +// ClusterRoleLister. +type ClusterRoleListerExpansion interface{} + +// ClusterRoleBindingListerExpansion allows custom methods to be added to +// ClusterRoleBindingLister. +type ClusterRoleBindingListerExpansion interface{} + +// RoleListerExpansion allows custom methods to be added to +// RoleLister. +type RoleListerExpansion interface{} + +// RoleNamespaceListerExpansion allows custom methods to be added to +// RoleNamespaceLister. +type RoleNamespaceListerExpansion interface{} + +// RoleBindingListerExpansion allows custom methods to be added to +// RoleBindingLister. +type RoleBindingListerExpansion interface{} + +// RoleBindingNamespaceListerExpansion allows custom methods to be added to +// RoleBindingNamespaceLister. +type RoleBindingNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1alpha1/role.go b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/role.go new file mode 100644 index 00000000000..13a64137aed --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/role.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/rbac/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleLister helps list Roles. +// All objects returned here must be treated as read-only. +type RoleLister interface { + // List lists all Roles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.Role, err error) + // Roles returns an object that can list and get Roles. + Roles(namespace string) RoleNamespaceLister + RoleListerExpansion +} + +// roleLister implements the RoleLister interface. +type roleLister struct { + indexer cache.Indexer +} + +// NewRoleLister returns a new RoleLister. +func NewRoleLister(indexer cache.Indexer) RoleLister { + return &roleLister{indexer: indexer} +} + +// List lists all Roles in the indexer. +func (s *roleLister) List(selector labels.Selector) (ret []*v1alpha1.Role, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Role)) + }) + return ret, err +} + +// Roles returns an object that can list and get Roles. +func (s *roleLister) Roles(namespace string) RoleNamespaceLister { + return roleNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleNamespaceLister helps list and get Roles. +// All objects returned here must be treated as read-only. +type RoleNamespaceLister interface { + // List lists all Roles in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.Role, err error) + // Get retrieves the Role from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.Role, error) + RoleNamespaceListerExpansion +} + +// roleNamespaceLister implements the RoleNamespaceLister +// interface. +type roleNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Roles in the indexer for a given namespace. +func (s roleNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Role, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Role)) + }) + return ret, err +} + +// Get retrieves the Role from the indexer for a given namespace and name. +func (s roleNamespaceLister) Get(name string) (*v1alpha1.Role, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("role"), name) + } + return obj.(*v1alpha1.Role), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1alpha1/rolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/rolebinding.go new file mode 100644 index 00000000000..0ad3d0eba06 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1alpha1/rolebinding.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/rbac/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleBindingLister helps list RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingLister interface { + // List lists all RoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.RoleBinding, err error) + // RoleBindings returns an object that can list and get RoleBindings. + RoleBindings(namespace string) RoleBindingNamespaceLister + RoleBindingListerExpansion +} + +// roleBindingLister implements the RoleBindingLister interface. +type roleBindingLister struct { + indexer cache.Indexer +} + +// NewRoleBindingLister returns a new RoleBindingLister. +func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister { + return &roleBindingLister{indexer: indexer} +} + +// List lists all RoleBindings in the indexer. +func (s *roleBindingLister) List(selector labels.Selector) (ret []*v1alpha1.RoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.RoleBinding)) + }) + return ret, err +} + +// RoleBindings returns an object that can list and get RoleBindings. +func (s *roleBindingLister) RoleBindings(namespace string) RoleBindingNamespaceLister { + return roleBindingNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleBindingNamespaceLister helps list and get RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingNamespaceLister interface { + // List lists all RoleBindings in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.RoleBinding, err error) + // Get retrieves the RoleBinding from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.RoleBinding, error) + RoleBindingNamespaceListerExpansion +} + +// roleBindingNamespaceLister implements the RoleBindingNamespaceLister +// interface. +type roleBindingNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all RoleBindings in the indexer for a given namespace. +func (s roleBindingNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.RoleBinding, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.RoleBinding)) + }) + return ret, err +} + +// Get retrieves the RoleBinding from the indexer for a given namespace and name. +func (s roleBindingNamespaceLister) Get(name string) (*v1alpha1.RoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("rolebinding"), name) + } + return obj.(*v1alpha1.RoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go b/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go new file mode 100644 index 00000000000..bf6cd99cb14 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/rbac/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleLister helps list ClusterRoles. +// All objects returned here must be treated as read-only. +type ClusterRoleLister interface { + // List lists all ClusterRoles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ClusterRole, err error) + // Get retrieves the ClusterRole from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ClusterRole, error) + ClusterRoleListerExpansion +} + +// clusterRoleLister implements the ClusterRoleLister interface. +type clusterRoleLister struct { + indexer cache.Indexer +} + +// NewClusterRoleLister returns a new ClusterRoleLister. +func NewClusterRoleLister(indexer cache.Indexer) ClusterRoleLister { + return &clusterRoleLister{indexer: indexer} +} + +// List lists all ClusterRoles in the indexer. +func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1beta1.ClusterRole, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ClusterRole)) + }) + return ret, err +} + +// Get retrieves the ClusterRole from the index for a given name. +func (s *clusterRoleLister) Get(name string) (*v1beta1.ClusterRole, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("clusterrole"), name) + } + return obj.(*v1beta1.ClusterRole), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go new file mode 100644 index 00000000000..00bab2330bd --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/rbac/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterRoleBindingLister helps list ClusterRoleBindings. +// All objects returned here must be treated as read-only. +type ClusterRoleBindingLister interface { + // List lists all ClusterRoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ClusterRoleBinding, err error) + // Get retrieves the ClusterRoleBinding from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ClusterRoleBinding, error) + ClusterRoleBindingListerExpansion +} + +// clusterRoleBindingLister implements the ClusterRoleBindingLister interface. +type clusterRoleBindingLister struct { + indexer cache.Indexer +} + +// NewClusterRoleBindingLister returns a new ClusterRoleBindingLister. +func NewClusterRoleBindingLister(indexer cache.Indexer) ClusterRoleBindingLister { + return &clusterRoleBindingLister{indexer: indexer} +} + +// List lists all ClusterRoleBindings in the indexer. +func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1beta1.ClusterRoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ClusterRoleBinding)) + }) + return ret, err +} + +// Get retrieves the ClusterRoleBinding from the index for a given name. +func (s *clusterRoleBindingLister) Get(name string) (*v1beta1.ClusterRoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("clusterrolebinding"), name) + } + return obj.(*v1beta1.ClusterRoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/rbac/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..51f674bd0fd --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1beta1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// ClusterRoleListerExpansion allows custom methods to be added to +// ClusterRoleLister. +type ClusterRoleListerExpansion interface{} + +// ClusterRoleBindingListerExpansion allows custom methods to be added to +// ClusterRoleBindingLister. +type ClusterRoleBindingListerExpansion interface{} + +// RoleListerExpansion allows custom methods to be added to +// RoleLister. +type RoleListerExpansion interface{} + +// RoleNamespaceListerExpansion allows custom methods to be added to +// RoleNamespaceLister. +type RoleNamespaceListerExpansion interface{} + +// RoleBindingListerExpansion allows custom methods to be added to +// RoleBindingLister. +type RoleBindingListerExpansion interface{} + +// RoleBindingNamespaceListerExpansion allows custom methods to be added to +// RoleBindingNamespaceLister. +type RoleBindingNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1beta1/role.go b/vendor/k8s.io/client-go/listers/rbac/v1beta1/role.go new file mode 100644 index 00000000000..9cd9b9042df --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1beta1/role.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/rbac/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleLister helps list Roles. +// All objects returned here must be treated as read-only. +type RoleLister interface { + // List lists all Roles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Role, err error) + // Roles returns an object that can list and get Roles. + Roles(namespace string) RoleNamespaceLister + RoleListerExpansion +} + +// roleLister implements the RoleLister interface. +type roleLister struct { + indexer cache.Indexer +} + +// NewRoleLister returns a new RoleLister. +func NewRoleLister(indexer cache.Indexer) RoleLister { + return &roleLister{indexer: indexer} +} + +// List lists all Roles in the indexer. +func (s *roleLister) List(selector labels.Selector) (ret []*v1beta1.Role, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Role)) + }) + return ret, err +} + +// Roles returns an object that can list and get Roles. +func (s *roleLister) Roles(namespace string) RoleNamespaceLister { + return roleNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleNamespaceLister helps list and get Roles. +// All objects returned here must be treated as read-only. +type RoleNamespaceLister interface { + // List lists all Roles in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.Role, err error) + // Get retrieves the Role from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.Role, error) + RoleNamespaceListerExpansion +} + +// roleNamespaceLister implements the RoleNamespaceLister +// interface. +type roleNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Roles in the indexer for a given namespace. +func (s roleNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Role, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.Role)) + }) + return ret, err +} + +// Get retrieves the Role from the indexer for a given namespace and name. +func (s roleNamespaceLister) Get(name string) (*v1beta1.Role, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("role"), name) + } + return obj.(*v1beta1.Role), nil +} diff --git a/vendor/k8s.io/client-go/listers/rbac/v1beta1/rolebinding.go b/vendor/k8s.io/client-go/listers/rbac/v1beta1/rolebinding.go new file mode 100644 index 00000000000..7c7c91bf3f7 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/rbac/v1beta1/rolebinding.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/rbac/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RoleBindingLister helps list RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingLister interface { + // List lists all RoleBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.RoleBinding, err error) + // RoleBindings returns an object that can list and get RoleBindings. + RoleBindings(namespace string) RoleBindingNamespaceLister + RoleBindingListerExpansion +} + +// roleBindingLister implements the RoleBindingLister interface. +type roleBindingLister struct { + indexer cache.Indexer +} + +// NewRoleBindingLister returns a new RoleBindingLister. +func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister { + return &roleBindingLister{indexer: indexer} +} + +// List lists all RoleBindings in the indexer. +func (s *roleBindingLister) List(selector labels.Selector) (ret []*v1beta1.RoleBinding, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.RoleBinding)) + }) + return ret, err +} + +// RoleBindings returns an object that can list and get RoleBindings. +func (s *roleBindingLister) RoleBindings(namespace string) RoleBindingNamespaceLister { + return roleBindingNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RoleBindingNamespaceLister helps list and get RoleBindings. +// All objects returned here must be treated as read-only. +type RoleBindingNamespaceLister interface { + // List lists all RoleBindings in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.RoleBinding, err error) + // Get retrieves the RoleBinding from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.RoleBinding, error) + RoleBindingNamespaceListerExpansion +} + +// roleBindingNamespaceLister implements the RoleBindingNamespaceLister +// interface. +type roleBindingNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all RoleBindings in the indexer for a given namespace. +func (s roleBindingNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.RoleBinding, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.RoleBinding)) + }) + return ret, err +} + +// Get retrieves the RoleBinding from the indexer for a given namespace and name. +func (s roleBindingNamespaceLister) Get(name string) (*v1beta1.RoleBinding, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("rolebinding"), name) + } + return obj.(*v1beta1.RoleBinding), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go new file mode 100644 index 00000000000..3b16e44290c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go @@ -0,0 +1,47 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +// PodSchedulingContextListerExpansion allows custom methods to be added to +// PodSchedulingContextLister. +type PodSchedulingContextListerExpansion interface{} + +// PodSchedulingContextNamespaceListerExpansion allows custom methods to be added to +// PodSchedulingContextNamespaceLister. +type PodSchedulingContextNamespaceListerExpansion interface{} + +// ResourceClaimListerExpansion allows custom methods to be added to +// ResourceClaimLister. +type ResourceClaimListerExpansion interface{} + +// ResourceClaimNamespaceListerExpansion allows custom methods to be added to +// ResourceClaimNamespaceLister. +type ResourceClaimNamespaceListerExpansion interface{} + +// ResourceClaimTemplateListerExpansion allows custom methods to be added to +// ResourceClaimTemplateLister. +type ResourceClaimTemplateListerExpansion interface{} + +// ResourceClaimTemplateNamespaceListerExpansion allows custom methods to be added to +// ResourceClaimTemplateNamespaceLister. +type ResourceClaimTemplateNamespaceListerExpansion interface{} + +// ResourceClassListerExpansion allows custom methods to be added to +// ResourceClassLister. +type ResourceClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 00000000000..c50b3f88902 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextLister helps list PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextLister interface { + // List lists all PodSchedulingContexts in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. + PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister + PodSchedulingContextListerExpansion +} + +// podSchedulingContextLister implements the PodSchedulingContextLister interface. +type podSchedulingContextLister struct { + indexer cache.Indexer +} + +// NewPodSchedulingContextLister returns a new PodSchedulingContextLister. +func NewPodSchedulingContextLister(indexer cache.Indexer) PodSchedulingContextLister { + return &podSchedulingContextLister{indexer: indexer} +} + +// List lists all PodSchedulingContexts in the indexer. +func (s *podSchedulingContextLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. +func (s *podSchedulingContextLister) PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister { + return podSchedulingContextNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodSchedulingContextNamespaceLister helps list and get PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextNamespaceLister interface { + // List lists all PodSchedulingContexts in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.PodSchedulingContext, error) + PodSchedulingContextNamespaceListerExpansion +} + +// podSchedulingContextNamespaceLister implements the PodSchedulingContextNamespaceLister +// interface. +type podSchedulingContextNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodSchedulingContexts in the indexer for a given namespace. +func (s podSchedulingContextNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. +func (s podSchedulingContextNamespaceLister) Get(name string) (*v1alpha2.PodSchedulingContext, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("podschedulingcontext"), name) + } + return obj.(*v1alpha2.PodSchedulingContext), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go new file mode 100644 index 00000000000..273f16af31f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceClaimLister helps list ResourceClaims. +// All objects returned here must be treated as read-only. +type ResourceClaimLister interface { + // List lists all ResourceClaims in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) + // ResourceClaims returns an object that can list and get ResourceClaims. + ResourceClaims(namespace string) ResourceClaimNamespaceLister + ResourceClaimListerExpansion +} + +// resourceClaimLister implements the ResourceClaimLister interface. +type resourceClaimLister struct { + indexer cache.Indexer +} + +// NewResourceClaimLister returns a new ResourceClaimLister. +func NewResourceClaimLister(indexer cache.Indexer) ResourceClaimLister { + return &resourceClaimLister{indexer: indexer} +} + +// List lists all ResourceClaims in the indexer. +func (s *resourceClaimLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaim)) + }) + return ret, err +} + +// ResourceClaims returns an object that can list and get ResourceClaims. +func (s *resourceClaimLister) ResourceClaims(namespace string) ResourceClaimNamespaceLister { + return resourceClaimNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ResourceClaimNamespaceLister helps list and get ResourceClaims. +// All objects returned here must be treated as read-only. +type ResourceClaimNamespaceLister interface { + // List lists all ResourceClaims in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) + // Get retrieves the ResourceClaim from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceClaim, error) + ResourceClaimNamespaceListerExpansion +} + +// resourceClaimNamespaceLister implements the ResourceClaimNamespaceLister +// interface. +type resourceClaimNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ResourceClaims in the indexer for a given namespace. +func (s resourceClaimNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaim)) + }) + return ret, err +} + +// Get retrieves the ResourceClaim from the indexer for a given namespace and name. +func (s resourceClaimNamespaceLister) Get(name string) (*v1alpha2.ResourceClaim, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaim"), name) + } + return obj.(*v1alpha2.ResourceClaim), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go new file mode 100644 index 00000000000..91a488b1749 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceClaimTemplateLister helps list ResourceClaimTemplates. +// All objects returned here must be treated as read-only. +type ResourceClaimTemplateLister interface { + // List lists all ResourceClaimTemplates in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) + // ResourceClaimTemplates returns an object that can list and get ResourceClaimTemplates. + ResourceClaimTemplates(namespace string) ResourceClaimTemplateNamespaceLister + ResourceClaimTemplateListerExpansion +} + +// resourceClaimTemplateLister implements the ResourceClaimTemplateLister interface. +type resourceClaimTemplateLister struct { + indexer cache.Indexer +} + +// NewResourceClaimTemplateLister returns a new ResourceClaimTemplateLister. +func NewResourceClaimTemplateLister(indexer cache.Indexer) ResourceClaimTemplateLister { + return &resourceClaimTemplateLister{indexer: indexer} +} + +// List lists all ResourceClaimTemplates in the indexer. +func (s *resourceClaimTemplateLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) + }) + return ret, err +} + +// ResourceClaimTemplates returns an object that can list and get ResourceClaimTemplates. +func (s *resourceClaimTemplateLister) ResourceClaimTemplates(namespace string) ResourceClaimTemplateNamespaceLister { + return resourceClaimTemplateNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ResourceClaimTemplateNamespaceLister helps list and get ResourceClaimTemplates. +// All objects returned here must be treated as read-only. +type ResourceClaimTemplateNamespaceLister interface { + // List lists all ResourceClaimTemplates in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) + // Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceClaimTemplate, error) + ResourceClaimTemplateNamespaceListerExpansion +} + +// resourceClaimTemplateNamespaceLister implements the ResourceClaimTemplateNamespaceLister +// interface. +type resourceClaimTemplateNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ResourceClaimTemplates in the indexer for a given namespace. +func (s resourceClaimTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) + }) + return ret, err +} + +// Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. +func (s resourceClaimTemplateNamespaceLister) Get(name string) (*v1alpha2.ResourceClaimTemplate, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaimtemplate"), name) + } + return obj.(*v1alpha2.ResourceClaimTemplate), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go new file mode 100644 index 00000000000..eeb2fc33794 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ResourceClassLister helps list ResourceClasses. +// All objects returned here must be treated as read-only. +type ResourceClassLister interface { + // List lists all ResourceClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) + // Get retrieves the ResourceClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.ResourceClass, error) + ResourceClassListerExpansion +} + +// resourceClassLister implements the ResourceClassLister interface. +type resourceClassLister struct { + indexer cache.Indexer +} + +// NewResourceClassLister returns a new ResourceClassLister. +func NewResourceClassLister(indexer cache.Indexer) ResourceClassLister { + return &resourceClassLister{indexer: indexer} +} + +// List lists all ResourceClasses in the indexer. +func (s *resourceClassLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.ResourceClass)) + }) + return ret, err +} + +// Get retrieves the ResourceClass from the index for a given name. +func (s *resourceClassLister) Get(name string) (*v1alpha2.ResourceClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclass"), name) + } + return obj.(*v1alpha2.ResourceClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/scheduling/v1/expansion_generated.go new file mode 100644 index 00000000000..d0c45d01255 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// PriorityClassListerExpansion allows custom methods to be added to +// PriorityClassLister. +type PriorityClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1/priorityclass.go b/vendor/k8s.io/client-go/listers/scheduling/v1/priorityclass.go new file mode 100644 index 00000000000..4da84ccf8a3 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1/priorityclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/scheduling/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityClassLister helps list PriorityClasses. +// All objects returned here must be treated as read-only. +type PriorityClassLister interface { + // List lists all PriorityClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.PriorityClass, err error) + // Get retrieves the PriorityClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.PriorityClass, error) + PriorityClassListerExpansion +} + +// priorityClassLister implements the PriorityClassLister interface. +type priorityClassLister struct { + indexer cache.Indexer +} + +// NewPriorityClassLister returns a new PriorityClassLister. +func NewPriorityClassLister(indexer cache.Indexer) PriorityClassLister { + return &priorityClassLister{indexer: indexer} +} + +// List lists all PriorityClasses in the indexer. +func (s *priorityClassLister) List(selector labels.Selector) (ret []*v1.PriorityClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.PriorityClass)) + }) + return ret, err +} + +// Get retrieves the PriorityClass from the index for a given name. +func (s *priorityClassLister) Get(name string) (*v1.PriorityClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("priorityclass"), name) + } + return obj.(*v1.PriorityClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..bde8b6206c8 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// PriorityClassListerExpansion allows custom methods to be added to +// PriorityClassLister. +type PriorityClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go new file mode 100644 index 00000000000..3d25dc80af3 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/scheduling/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityClassLister helps list PriorityClasses. +// All objects returned here must be treated as read-only. +type PriorityClassLister interface { + // List lists all PriorityClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.PriorityClass, err error) + // Get retrieves the PriorityClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.PriorityClass, error) + PriorityClassListerExpansion +} + +// priorityClassLister implements the PriorityClassLister interface. +type priorityClassLister struct { + indexer cache.Indexer +} + +// NewPriorityClassLister returns a new PriorityClassLister. +func NewPriorityClassLister(indexer cache.Indexer) PriorityClassLister { + return &priorityClassLister{indexer: indexer} +} + +// List lists all PriorityClasses in the indexer. +func (s *priorityClassLister) List(selector labels.Selector) (ret []*v1alpha1.PriorityClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.PriorityClass)) + }) + return ret, err +} + +// Get retrieves the PriorityClass from the index for a given name. +func (s *priorityClassLister) Get(name string) (*v1alpha1.PriorityClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("priorityclass"), name) + } + return obj.(*v1alpha1.PriorityClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/scheduling/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..b806e8cf80c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1beta1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// PriorityClassListerExpansion allows custom methods to be added to +// PriorityClassLister. +type PriorityClassListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1beta1/priorityclass.go b/vendor/k8s.io/client-go/listers/scheduling/v1beta1/priorityclass.go new file mode 100644 index 00000000000..c848d035afc --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1beta1/priorityclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/scheduling/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PriorityClassLister helps list PriorityClasses. +// All objects returned here must be treated as read-only. +type PriorityClassLister interface { + // List lists all PriorityClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.PriorityClass, err error) + // Get retrieves the PriorityClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.PriorityClass, error) + PriorityClassListerExpansion +} + +// priorityClassLister implements the PriorityClassLister interface. +type priorityClassLister struct { + indexer cache.Indexer +} + +// NewPriorityClassLister returns a new PriorityClassLister. +func NewPriorityClassLister(indexer cache.Indexer) PriorityClassLister { + return &priorityClassLister{indexer: indexer} +} + +// List lists all PriorityClasses in the indexer. +func (s *priorityClassLister) List(selector labels.Selector) (ret []*v1beta1.PriorityClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.PriorityClass)) + }) + return ret, err +} + +// Get retrieves the PriorityClass from the index for a given name. +func (s *priorityClassLister) Get(name string) (*v1beta1.PriorityClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("priorityclass"), name) + } + return obj.(*v1beta1.PriorityClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/csidriver.go b/vendor/k8s.io/client-go/listers/storage/v1/csidriver.go new file mode 100644 index 00000000000..4e8ab909007 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/csidriver.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIDriverLister helps list CSIDrivers. +// All objects returned here must be treated as read-only. +type CSIDriverLister interface { + // List lists all CSIDrivers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSIDriver, err error) + // Get retrieves the CSIDriver from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CSIDriver, error) + CSIDriverListerExpansion +} + +// cSIDriverLister implements the CSIDriverLister interface. +type cSIDriverLister struct { + indexer cache.Indexer +} + +// NewCSIDriverLister returns a new CSIDriverLister. +func NewCSIDriverLister(indexer cache.Indexer) CSIDriverLister { + return &cSIDriverLister{indexer: indexer} +} + +// List lists all CSIDrivers in the indexer. +func (s *cSIDriverLister) List(selector labels.Selector) (ret []*v1.CSIDriver, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSIDriver)) + }) + return ret, err +} + +// Get retrieves the CSIDriver from the index for a given name. +func (s *cSIDriverLister) Get(name string) (*v1.CSIDriver, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("csidriver"), name) + } + return obj.(*v1.CSIDriver), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/csinode.go b/vendor/k8s.io/client-go/listers/storage/v1/csinode.go new file mode 100644 index 00000000000..93f869572ca --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/csinode.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSINodeLister helps list CSINodes. +// All objects returned here must be treated as read-only. +type CSINodeLister interface { + // List lists all CSINodes in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSINode, err error) + // Get retrieves the CSINode from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CSINode, error) + CSINodeListerExpansion +} + +// cSINodeLister implements the CSINodeLister interface. +type cSINodeLister struct { + indexer cache.Indexer +} + +// NewCSINodeLister returns a new CSINodeLister. +func NewCSINodeLister(indexer cache.Indexer) CSINodeLister { + return &cSINodeLister{indexer: indexer} +} + +// List lists all CSINodes in the indexer. +func (s *cSINodeLister) List(selector labels.Selector) (ret []*v1.CSINode, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSINode)) + }) + return ret, err +} + +// Get retrieves the CSINode from the index for a given name. +func (s *cSINodeLister) Get(name string) (*v1.CSINode, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("csinode"), name) + } + return obj.(*v1.CSINode), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/csistoragecapacity.go b/vendor/k8s.io/client-go/listers/storage/v1/csistoragecapacity.go new file mode 100644 index 00000000000..a72328c9a3f --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/csistoragecapacity.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityLister helps list CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityLister interface { + // List lists all CSIStorageCapacities in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) + // CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. + CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister + CSIStorageCapacityListerExpansion +} + +// cSIStorageCapacityLister implements the CSIStorageCapacityLister interface. +type cSIStorageCapacityLister struct { + indexer cache.Indexer +} + +// NewCSIStorageCapacityLister returns a new CSIStorageCapacityLister. +func NewCSIStorageCapacityLister(indexer cache.Indexer) CSIStorageCapacityLister { + return &cSIStorageCapacityLister{indexer: indexer} +} + +// List lists all CSIStorageCapacities in the indexer. +func (s *cSIStorageCapacityLister) List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSIStorageCapacity)) + }) + return ret, err +} + +// CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. +func (s *cSIStorageCapacityLister) CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister { + return cSIStorageCapacityNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CSIStorageCapacityNamespaceLister helps list and get CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityNamespaceLister interface { + // List lists all CSIStorageCapacities in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) + // Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CSIStorageCapacity, error) + CSIStorageCapacityNamespaceListerExpansion +} + +// cSIStorageCapacityNamespaceLister implements the CSIStorageCapacityNamespaceLister +// interface. +type cSIStorageCapacityNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CSIStorageCapacities in the indexer for a given namespace. +func (s cSIStorageCapacityNamespaceLister) List(selector labels.Selector) (ret []*v1.CSIStorageCapacity, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CSIStorageCapacity)) + }) + return ret, err +} + +// Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. +func (s cSIStorageCapacityNamespaceLister) Get(name string) (*v1.CSIStorageCapacity, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("csistoragecapacity"), name) + } + return obj.(*v1.CSIStorageCapacity), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/storage/v1/expansion_generated.go new file mode 100644 index 00000000000..196b787e7ea --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// CSIDriverListerExpansion allows custom methods to be added to +// CSIDriverLister. +type CSIDriverListerExpansion interface{} + +// CSINodeListerExpansion allows custom methods to be added to +// CSINodeLister. +type CSINodeListerExpansion interface{} + +// CSIStorageCapacityListerExpansion allows custom methods to be added to +// CSIStorageCapacityLister. +type CSIStorageCapacityListerExpansion interface{} + +// CSIStorageCapacityNamespaceListerExpansion allows custom methods to be added to +// CSIStorageCapacityNamespaceLister. +type CSIStorageCapacityNamespaceListerExpansion interface{} + +// StorageClassListerExpansion allows custom methods to be added to +// StorageClassLister. +type StorageClassListerExpansion interface{} + +// VolumeAttachmentListerExpansion allows custom methods to be added to +// VolumeAttachmentLister. +type VolumeAttachmentListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/storageclass.go b/vendor/k8s.io/client-go/listers/storage/v1/storageclass.go new file mode 100644 index 00000000000..ffa3d19f50b --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/storageclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StorageClassLister helps list StorageClasses. +// All objects returned here must be treated as read-only. +type StorageClassLister interface { + // List lists all StorageClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.StorageClass, err error) + // Get retrieves the StorageClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.StorageClass, error) + StorageClassListerExpansion +} + +// storageClassLister implements the StorageClassLister interface. +type storageClassLister struct { + indexer cache.Indexer +} + +// NewStorageClassLister returns a new StorageClassLister. +func NewStorageClassLister(indexer cache.Indexer) StorageClassLister { + return &storageClassLister{indexer: indexer} +} + +// List lists all StorageClasses in the indexer. +func (s *storageClassLister) List(selector labels.Selector) (ret []*v1.StorageClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.StorageClass)) + }) + return ret, err +} + +// Get retrieves the StorageClass from the index for a given name. +func (s *storageClassLister) Get(name string) (*v1.StorageClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("storageclass"), name) + } + return obj.(*v1.StorageClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1/volumeattachment.go b/vendor/k8s.io/client-go/listers/storage/v1/volumeattachment.go new file mode 100644 index 00000000000..fbc735c9394 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1/volumeattachment.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentLister helps list VolumeAttachments. +// All objects returned here must be treated as read-only. +type VolumeAttachmentLister interface { + // List lists all VolumeAttachments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.VolumeAttachment, err error) + // Get retrieves the VolumeAttachment from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.VolumeAttachment, error) + VolumeAttachmentListerExpansion +} + +// volumeAttachmentLister implements the VolumeAttachmentLister interface. +type volumeAttachmentLister struct { + indexer cache.Indexer +} + +// NewVolumeAttachmentLister returns a new VolumeAttachmentLister. +func NewVolumeAttachmentLister(indexer cache.Indexer) VolumeAttachmentLister { + return &volumeAttachmentLister{indexer: indexer} +} + +// List lists all VolumeAttachments in the indexer. +func (s *volumeAttachmentLister) List(selector labels.Selector) (ret []*v1.VolumeAttachment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.VolumeAttachment)) + }) + return ret, err +} + +// Get retrieves the VolumeAttachment from the index for a given name. +func (s *volumeAttachmentLister) Get(name string) (*v1.VolumeAttachment, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("volumeattachment"), name) + } + return obj.(*v1.VolumeAttachment), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1alpha1/csistoragecapacity.go b/vendor/k8s.io/client-go/listers/storage/v1alpha1/csistoragecapacity.go new file mode 100644 index 00000000000..0c1b5f26474 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1alpha1/csistoragecapacity.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/storage/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityLister helps list CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityLister interface { + // List lists all CSIStorageCapacities in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CSIStorageCapacity, err error) + // CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. + CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister + CSIStorageCapacityListerExpansion +} + +// cSIStorageCapacityLister implements the CSIStorageCapacityLister interface. +type cSIStorageCapacityLister struct { + indexer cache.Indexer +} + +// NewCSIStorageCapacityLister returns a new CSIStorageCapacityLister. +func NewCSIStorageCapacityLister(indexer cache.Indexer) CSIStorageCapacityLister { + return &cSIStorageCapacityLister{indexer: indexer} +} + +// List lists all CSIStorageCapacities in the indexer. +func (s *cSIStorageCapacityLister) List(selector labels.Selector) (ret []*v1alpha1.CSIStorageCapacity, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CSIStorageCapacity)) + }) + return ret, err +} + +// CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. +func (s *cSIStorageCapacityLister) CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister { + return cSIStorageCapacityNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CSIStorageCapacityNamespaceLister helps list and get CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityNamespaceLister interface { + // List lists all CSIStorageCapacities in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CSIStorageCapacity, err error) + // Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.CSIStorageCapacity, error) + CSIStorageCapacityNamespaceListerExpansion +} + +// cSIStorageCapacityNamespaceLister implements the CSIStorageCapacityNamespaceLister +// interface. +type cSIStorageCapacityNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CSIStorageCapacities in the indexer for a given namespace. +func (s cSIStorageCapacityNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.CSIStorageCapacity, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CSIStorageCapacity)) + }) + return ret, err +} + +// Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. +func (s cSIStorageCapacityNamespaceLister) Get(name string) (*v1alpha1.CSIStorageCapacity, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("csistoragecapacity"), name) + } + return obj.(*v1alpha1.CSIStorageCapacity), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/storage/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..edefe6d05ed --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1alpha1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// CSIStorageCapacityListerExpansion allows custom methods to be added to +// CSIStorageCapacityLister. +type CSIStorageCapacityListerExpansion interface{} + +// CSIStorageCapacityNamespaceListerExpansion allows custom methods to be added to +// CSIStorageCapacityNamespaceLister. +type CSIStorageCapacityNamespaceListerExpansion interface{} + +// VolumeAttachmentListerExpansion allows custom methods to be added to +// VolumeAttachmentLister. +type VolumeAttachmentListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/storage/v1alpha1/volumeattachment.go b/vendor/k8s.io/client-go/listers/storage/v1alpha1/volumeattachment.go new file mode 100644 index 00000000000..3d5e2b7b712 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1alpha1/volumeattachment.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/storage/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentLister helps list VolumeAttachments. +// All objects returned here must be treated as read-only. +type VolumeAttachmentLister interface { + // List lists all VolumeAttachments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.VolumeAttachment, err error) + // Get retrieves the VolumeAttachment from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.VolumeAttachment, error) + VolumeAttachmentListerExpansion +} + +// volumeAttachmentLister implements the VolumeAttachmentLister interface. +type volumeAttachmentLister struct { + indexer cache.Indexer +} + +// NewVolumeAttachmentLister returns a new VolumeAttachmentLister. +func NewVolumeAttachmentLister(indexer cache.Indexer) VolumeAttachmentLister { + return &volumeAttachmentLister{indexer: indexer} +} + +// List lists all VolumeAttachments in the indexer. +func (s *volumeAttachmentLister) List(selector labels.Selector) (ret []*v1alpha1.VolumeAttachment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.VolumeAttachment)) + }) + return ret, err +} + +// Get retrieves the VolumeAttachment from the index for a given name. +func (s *volumeAttachmentLister) Get(name string) (*v1alpha1.VolumeAttachment, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("volumeattachment"), name) + } + return obj.(*v1alpha1.VolumeAttachment), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/csidriver.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/csidriver.go new file mode 100644 index 00000000000..c6787aa01ba --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/csidriver.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIDriverLister helps list CSIDrivers. +// All objects returned here must be treated as read-only. +type CSIDriverLister interface { + // List lists all CSIDrivers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CSIDriver, err error) + // Get retrieves the CSIDriver from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.CSIDriver, error) + CSIDriverListerExpansion +} + +// cSIDriverLister implements the CSIDriverLister interface. +type cSIDriverLister struct { + indexer cache.Indexer +} + +// NewCSIDriverLister returns a new CSIDriverLister. +func NewCSIDriverLister(indexer cache.Indexer) CSIDriverLister { + return &cSIDriverLister{indexer: indexer} +} + +// List lists all CSIDrivers in the indexer. +func (s *cSIDriverLister) List(selector labels.Selector) (ret []*v1beta1.CSIDriver, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CSIDriver)) + }) + return ret, err +} + +// Get retrieves the CSIDriver from the index for a given name. +func (s *cSIDriverLister) Get(name string) (*v1beta1.CSIDriver, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("csidriver"), name) + } + return obj.(*v1beta1.CSIDriver), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/csinode.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/csinode.go new file mode 100644 index 00000000000..809efaa3696 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/csinode.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSINodeLister helps list CSINodes. +// All objects returned here must be treated as read-only. +type CSINodeLister interface { + // List lists all CSINodes in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CSINode, err error) + // Get retrieves the CSINode from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.CSINode, error) + CSINodeListerExpansion +} + +// cSINodeLister implements the CSINodeLister interface. +type cSINodeLister struct { + indexer cache.Indexer +} + +// NewCSINodeLister returns a new CSINodeLister. +func NewCSINodeLister(indexer cache.Indexer) CSINodeLister { + return &cSINodeLister{indexer: indexer} +} + +// List lists all CSINodes in the indexer. +func (s *cSINodeLister) List(selector labels.Selector) (ret []*v1beta1.CSINode, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CSINode)) + }) + return ret, err +} + +// Get retrieves the CSINode from the index for a given name. +func (s *cSINodeLister) Get(name string) (*v1beta1.CSINode, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("csinode"), name) + } + return obj.(*v1beta1.CSINode), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/csistoragecapacity.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/csistoragecapacity.go new file mode 100644 index 00000000000..4680ffb7c82 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/csistoragecapacity.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CSIStorageCapacityLister helps list CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityLister interface { + // List lists all CSIStorageCapacities in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CSIStorageCapacity, err error) + // CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. + CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister + CSIStorageCapacityListerExpansion +} + +// cSIStorageCapacityLister implements the CSIStorageCapacityLister interface. +type cSIStorageCapacityLister struct { + indexer cache.Indexer +} + +// NewCSIStorageCapacityLister returns a new CSIStorageCapacityLister. +func NewCSIStorageCapacityLister(indexer cache.Indexer) CSIStorageCapacityLister { + return &cSIStorageCapacityLister{indexer: indexer} +} + +// List lists all CSIStorageCapacities in the indexer. +func (s *cSIStorageCapacityLister) List(selector labels.Selector) (ret []*v1beta1.CSIStorageCapacity, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CSIStorageCapacity)) + }) + return ret, err +} + +// CSIStorageCapacities returns an object that can list and get CSIStorageCapacities. +func (s *cSIStorageCapacityLister) CSIStorageCapacities(namespace string) CSIStorageCapacityNamespaceLister { + return cSIStorageCapacityNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CSIStorageCapacityNamespaceLister helps list and get CSIStorageCapacities. +// All objects returned here must be treated as read-only. +type CSIStorageCapacityNamespaceLister interface { + // List lists all CSIStorageCapacities in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.CSIStorageCapacity, err error) + // Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.CSIStorageCapacity, error) + CSIStorageCapacityNamespaceListerExpansion +} + +// cSIStorageCapacityNamespaceLister implements the CSIStorageCapacityNamespaceLister +// interface. +type cSIStorageCapacityNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CSIStorageCapacities in the indexer for a given namespace. +func (s cSIStorageCapacityNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.CSIStorageCapacity, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.CSIStorageCapacity)) + }) + return ret, err +} + +// Get retrieves the CSIStorageCapacity from the indexer for a given namespace and name. +func (s cSIStorageCapacityNamespaceLister) Get(name string) (*v1beta1.CSIStorageCapacity, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("csistoragecapacity"), name) + } + return obj.(*v1beta1.CSIStorageCapacity), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/expansion_generated.go new file mode 100644 index 00000000000..c2b0d5b17df --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/expansion_generated.go @@ -0,0 +1,43 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// CSIDriverListerExpansion allows custom methods to be added to +// CSIDriverLister. +type CSIDriverListerExpansion interface{} + +// CSINodeListerExpansion allows custom methods to be added to +// CSINodeLister. +type CSINodeListerExpansion interface{} + +// CSIStorageCapacityListerExpansion allows custom methods to be added to +// CSIStorageCapacityLister. +type CSIStorageCapacityListerExpansion interface{} + +// CSIStorageCapacityNamespaceListerExpansion allows custom methods to be added to +// CSIStorageCapacityNamespaceLister. +type CSIStorageCapacityNamespaceListerExpansion interface{} + +// StorageClassListerExpansion allows custom methods to be added to +// StorageClassLister. +type StorageClassListerExpansion interface{} + +// VolumeAttachmentListerExpansion allows custom methods to be added to +// VolumeAttachmentLister. +type VolumeAttachmentListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/storageclass.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/storageclass.go new file mode 100644 index 00000000000..eb7b8315c69 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/storageclass.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StorageClassLister helps list StorageClasses. +// All objects returned here must be treated as read-only. +type StorageClassLister interface { + // List lists all StorageClasses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.StorageClass, err error) + // Get retrieves the StorageClass from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.StorageClass, error) + StorageClassListerExpansion +} + +// storageClassLister implements the StorageClassLister interface. +type storageClassLister struct { + indexer cache.Indexer +} + +// NewStorageClassLister returns a new StorageClassLister. +func NewStorageClassLister(indexer cache.Indexer) StorageClassLister { + return &storageClassLister{indexer: indexer} +} + +// List lists all StorageClasses in the indexer. +func (s *storageClassLister) List(selector labels.Selector) (ret []*v1beta1.StorageClass, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.StorageClass)) + }) + return ret, err +} + +// Get retrieves the StorageClass from the index for a given name. +func (s *storageClassLister) Get(name string) (*v1beta1.StorageClass, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("storageclass"), name) + } + return obj.(*v1beta1.StorageClass), nil +} diff --git a/vendor/k8s.io/client-go/listers/storage/v1beta1/volumeattachment.go b/vendor/k8s.io/client-go/listers/storage/v1beta1/volumeattachment.go new file mode 100644 index 00000000000..bab2d317c79 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/storage/v1beta1/volumeattachment.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// VolumeAttachmentLister helps list VolumeAttachments. +// All objects returned here must be treated as read-only. +type VolumeAttachmentLister interface { + // List lists all VolumeAttachments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.VolumeAttachment, err error) + // Get retrieves the VolumeAttachment from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.VolumeAttachment, error) + VolumeAttachmentListerExpansion +} + +// volumeAttachmentLister implements the VolumeAttachmentLister interface. +type volumeAttachmentLister struct { + indexer cache.Indexer +} + +// NewVolumeAttachmentLister returns a new VolumeAttachmentLister. +func NewVolumeAttachmentLister(indexer cache.Indexer) VolumeAttachmentLister { + return &volumeAttachmentLister{indexer: indexer} +} + +// List lists all VolumeAttachments in the indexer. +func (s *volumeAttachmentLister) List(selector labels.Selector) (ret []*v1beta1.VolumeAttachment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.VolumeAttachment)) + }) + return ret, err +} + +// Get retrieves the VolumeAttachment from the index for a given name. +func (s *volumeAttachmentLister) Get(name string) (*v1beta1.VolumeAttachment, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("volumeattachment"), name) + } + return obj.(*v1beta1.VolumeAttachment), nil +} diff --git a/vendor/k8s.io/client-go/openapi/OWNERS b/vendor/k8s.io/client-go/openapi/OWNERS new file mode 100644 index 00000000000..e6100942426 --- /dev/null +++ b/vendor/k8s.io/client-go/openapi/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - apelisse diff --git a/vendor/k8s.io/client-go/openapi/client.go b/vendor/k8s.io/client-go/openapi/client.go index 7b58762acfd..6a43057187e 100644 --- a/vendor/k8s.io/client-go/openapi/client.go +++ b/vendor/k8s.io/client-go/openapi/client.go @@ -19,6 +19,7 @@ package openapi import ( "context" "encoding/json" + "strings" "k8s.io/client-go/rest" "k8s.io/kube-openapi/pkg/handler3" @@ -58,7 +59,11 @@ func (c *client) Paths() (map[string]GroupVersion, error) { // Create GroupVersions for each element of the result result := map[string]GroupVersion{} for k, v := range discoMap.Paths { - result[k] = newGroupVersion(c, v) + // If the server returned a URL rooted at /openapi/v3, preserve any additional client-side prefix. + // If the server returned a URL not rooted at /openapi/v3, treat it as an actual server-relative URL. + // See https://github.com/kubernetes/kubernetes/issues/117463 for details + useClientPrefix := strings.HasPrefix(v.ServerRelativeURL, "/openapi/v3") + result[k] = newGroupVersion(c, v, useClientPrefix) } return result, nil } diff --git a/vendor/k8s.io/client-go/openapi/groupversion.go b/vendor/k8s.io/client-go/openapi/groupversion.go index 7c35833b483..601dcbe3ccb 100644 --- a/vendor/k8s.io/client-go/openapi/groupversion.go +++ b/vendor/k8s.io/client-go/openapi/groupversion.go @@ -18,42 +18,53 @@ package openapi import ( "context" + "net/url" - openapi_v3 "github.com/google/gnostic/openapiv3" - "google.golang.org/protobuf/proto" "k8s.io/kube-openapi/pkg/handler3" ) -const openAPIV3mimePb = "application/com.github.proto-openapi.spec.v3@v1.0+protobuf" +const ContentTypeOpenAPIV3PB = "application/com.github.proto-openapi.spec.v3@v1.0+protobuf" type GroupVersion interface { - Schema() (*openapi_v3.Document, error) + Schema(contentType string) ([]byte, error) } type groupversion struct { - client *client - item handler3.OpenAPIV3DiscoveryGroupVersion + client *client + item handler3.OpenAPIV3DiscoveryGroupVersion + useClientPrefix bool } -func newGroupVersion(client *client, item handler3.OpenAPIV3DiscoveryGroupVersion) *groupversion { - return &groupversion{client: client, item: item} +func newGroupVersion(client *client, item handler3.OpenAPIV3DiscoveryGroupVersion, useClientPrefix bool) *groupversion { + return &groupversion{client: client, item: item, useClientPrefix: useClientPrefix} } -func (g *groupversion) Schema() (*openapi_v3.Document, error) { - data, err := g.client.restClient.Get(). - RequestURI(g.item.ServerRelativeURL). - SetHeader("Accept", openAPIV3mimePb). - Do(context.TODO()). - Raw() +func (g *groupversion) Schema(contentType string) ([]byte, error) { + if !g.useClientPrefix { + return g.client.restClient.Get(). + RequestURI(g.item.ServerRelativeURL). + SetHeader("Accept", contentType). + Do(context.TODO()). + Raw() + } + locator, err := url.Parse(g.item.ServerRelativeURL) if err != nil { return nil, err } - document := &openapi_v3.Document{} - if err := proto.Unmarshal(data, document); err != nil { - return nil, err + path := g.client.restClient.Get(). + AbsPath(locator.Path). + SetHeader("Accept", contentType) + + // Other than root endpoints(openapiv3/apis), resources have hash query parameter to support etags. + // However, absPath does not support handling query parameters internally, + // so that hash query parameter is added manually + for k, value := range locator.Query() { + for _, v := range value { + path.Param(k, v) + } } - return document, nil + return path.Do(context.TODO()).Raw() } diff --git a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/types.go b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/types.go index 1b6322da510..dae1bf1b077 100644 --- a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/types.go +++ b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/types.go @@ -98,6 +98,11 @@ type Cluster struct { // cluster. // +optional ProxyURL string + // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful + // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on + // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. + // +optional + DisableCompression bool // Config holds additional config data that is specific to the exec // plugin with regards to the cluster being authenticated to. // diff --git a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/types.go b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/types.go index 0c4754dd269..b9082e81455 100644 --- a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/types.go +++ b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/types.go @@ -96,6 +96,11 @@ type Cluster struct { // cluster. // +optional ProxyURL string `json:"proxy-url,omitempty"` + // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful + // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on + // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. + // +optional + DisableCompression bool `json:"disable-compression,omitempty"` // Config holds additional config data that is specific to the exec // plugin with regards to the cluster being authenticated to. // diff --git a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/zz_generated.conversion.go b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/zz_generated.conversion.go index 82fe94ca915..9c3f63fca8f 100644 --- a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1/zz_generated.conversion.go @@ -86,6 +86,7 @@ func autoConvert_v1_Cluster_To_clientauthentication_Cluster(in *Cluster, out *cl out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Config, &out.Config, s); err != nil { return err } @@ -103,6 +104,7 @@ func autoConvert_clientauthentication_Cluster_To_v1_Cluster(in *clientauthentica out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Config, &out.Config, s); err != nil { return err } diff --git a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/types.go b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/types.go index 714b0273ae9..918eb11e149 100644 --- a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/types.go +++ b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/types.go @@ -96,6 +96,11 @@ type Cluster struct { // cluster. // +optional ProxyURL string `json:"proxy-url,omitempty"` + // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful + // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on + // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. + // +optional + DisableCompression bool `json:"disable-compression,omitempty"` // Config holds additional config data that is specific to the exec // plugin with regards to the cluster being authenticated to. // diff --git a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/zz_generated.conversion.go index 8c4d43fea5e..5372da1513b 100644 --- a/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1/zz_generated.conversion.go @@ -86,6 +86,7 @@ func autoConvert_v1beta1_Cluster_To_clientauthentication_Cluster(in *Cluster, ou out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Config, &out.Config, s); err != nil { return err } @@ -103,6 +104,7 @@ func autoConvert_clientauthentication_Cluster_To_v1beta1_Cluster(in *clientauthe out.InsecureSkipTLSVerify = in.InsecureSkipTLSVerify out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Config, &out.Config, s); err != nil { return err } diff --git a/vendor/k8s.io/client-go/pkg/version/base.go b/vendor/k8s.io/client-go/pkg/version/base.go index 51e34dda334..676d51d3217 100644 --- a/vendor/k8s.io/client-go/pkg/version/base.go +++ b/vendor/k8s.io/client-go/pkg/version/base.go @@ -43,7 +43,8 @@ var ( gitMinor string = "" // minor version, numeric possibly followed by "+" // semantic version, derived by build scripts (see - // https://git.k8s.io/community/contributors/design-proposals/release/versioning.md + // https://github.com/kubernetes/sig-release/blob/master/release-engineering/versioning.md#kubernetes-release-versioning + // https://kubernetes.io/releases/version-skew-policy/ // for a detailed discussion of this field) // // TODO: This field is still called "gitVersion" for legacy diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go index 73876f6887e..5331b237a70 100644 --- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go +++ b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go @@ -308,17 +308,18 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error { if c.HasCertCallback() { return errors.New("can't add TLS certificate callback: transport.Config.TLS.GetCert already set") } - c.TLS.GetCert = a.getCert.GetCert c.TLS.GetCertHolder = a.getCert // comparable for TLS config caching - if c.Dial != nil { + if c.DialHolder != nil { + if c.DialHolder.Dial == nil { + return errors.New("invalid transport.Config.DialHolder: wrapped Dial function is nil") + } + // if c has a custom dialer, we have to wrap it // TLS config caching is not supported for this config - d := connrotation.NewDialerWithTracker(c.Dial, a.connTracker) - c.Dial = d.DialContext - c.DialHolder = nil + d := connrotation.NewDialerWithTracker(c.DialHolder.Dial, a.connTracker) + c.DialHolder = &transport.DialHolder{Dial: d.DialContext} } else { - c.Dial = a.dial.Dial c.DialHolder = a.dial // comparable for TLS config caching } diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/OWNERS b/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/OWNERS deleted file mode 100644 index 727c970aec4..00000000000 --- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - cjcullen -reviewers: - - cjcullen -emeritus_approvers: - - jlowdermilk diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go deleted file mode 100644 index 209376bc29d..00000000000 --- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go +++ /dev/null @@ -1,390 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gcp - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "os/exec" - "strings" - "sync" - "time" - - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" - "k8s.io/apimachinery/pkg/util/net" - "k8s.io/apimachinery/pkg/util/yaml" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/util/jsonpath" - "k8s.io/klog/v2" -) - -func init() { - if err := restclient.RegisterAuthProviderPlugin("gcp", newGCPAuthProvider); err != nil { - klog.Fatalf("Failed to register gcp auth plugin: %v", err) - } -} - -var ( - // Stubbable for testing - execCommand = exec.Command - - // defaultScopes: - // - cloud-platform is the base scope to authenticate to GCP. - // - userinfo.email is used to authenticate to GKE APIs with gserviceaccount - // email instead of numeric uniqueID. - defaultScopes = []string{ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/userinfo.email"} -) - -// gcpAuthProvider is an auth provider plugin that uses GCP credentials to provide -// tokens for kubectl to authenticate itself to the apiserver. A sample json config -// is provided below with all recognized options described. -// -// { -// 'auth-provider': { -// # Required -// "name": "gcp", -// -// 'config': { -// # Authentication options -// # These options are used while getting a token. -// -// # comma-separated list of GCP API scopes. default value of this field -// # is "https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email". -// # to override the API scopes, specify this field explicitly. -// "scopes": "https://www.googleapis.com/auth/cloud-platform" -// -// # Caching options -// -// # Raw string data representing cached access token. -// "access-token": "ya29.CjWdA4GiBPTt", -// # RFC3339Nano expiration timestamp for cached access token. -// "expiry": "2016-10-31 22:31:9.123", -// -// # Command execution options -// # These options direct the plugin to execute a specified command and parse -// # token and expiry time from the output of the command. -// -// # Command to execute for access token. Command output will be parsed as JSON. -// # If "cmd-args" is not present, this value will be split on whitespace, with -// # the first element interpreted as the command, remaining elements as args. -// "cmd-path": "/usr/bin/gcloud", -// -// # Arguments to pass to command to execute for access token. -// "cmd-args": "config config-helper --output=json" -// -// # JSONPath to the string field that represents the access token in -// # command output. If omitted, defaults to "{.access_token}". -// "token-key": "{.credential.access_token}", -// -// # JSONPath to the string field that represents expiration timestamp -// # of the access token in the command output. If omitted, defaults to -// # "{.token_expiry}" -// "expiry-key": ""{.credential.token_expiry}", -// -// # golang reference time in the format that the expiration timestamp uses. -// # If omitted, defaults to time.RFC3339Nano -// "time-fmt": "2006-01-02 15:04:05.999999999" -// } -// } -// } -// -type gcpAuthProvider struct { - tokenSource oauth2.TokenSource - persister restclient.AuthProviderConfigPersister -} - -var warnOnce sync.Once - -func newGCPAuthProvider(_ string, gcpConfig map[string]string, persister restclient.AuthProviderConfigPersister) (restclient.AuthProvider, error) { - warnOnce.Do(func() { - klog.Warningf(`WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.25+; use gcloud instead. -To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke`) - }) - - ts, err := tokenSource(isCmdTokenSource(gcpConfig), gcpConfig) - if err != nil { - return nil, err - } - cts, err := newCachedTokenSource(gcpConfig["access-token"], gcpConfig["expiry"], persister, ts, gcpConfig) - if err != nil { - return nil, err - } - return &gcpAuthProvider{cts, persister}, nil -} - -func isCmdTokenSource(gcpConfig map[string]string) bool { - _, ok := gcpConfig["cmd-path"] - return ok -} - -func tokenSource(isCmd bool, gcpConfig map[string]string) (oauth2.TokenSource, error) { - // Command-based token source - if isCmd { - cmd := gcpConfig["cmd-path"] - if len(cmd) == 0 { - return nil, fmt.Errorf("missing access token cmd") - } - if gcpConfig["scopes"] != "" { - return nil, fmt.Errorf("scopes can only be used when kubectl is using a gcp service account key") - } - var args []string - if cmdArgs, ok := gcpConfig["cmd-args"]; ok { - args = strings.Fields(cmdArgs) - } else { - fields := strings.Fields(cmd) - cmd = fields[0] - args = fields[1:] - } - return newCmdTokenSource(cmd, args, gcpConfig["token-key"], gcpConfig["expiry-key"], gcpConfig["time-fmt"]), nil - } - - // Google Application Credentials-based token source - scopes := parseScopes(gcpConfig) - ts, err := google.DefaultTokenSource(context.Background(), scopes...) - if err != nil { - return nil, fmt.Errorf("cannot construct google default token source: %v", err) - } - return ts, nil -} - -// parseScopes constructs a list of scopes that should be included in token source -// from the config map. -func parseScopes(gcpConfig map[string]string) []string { - scopes, ok := gcpConfig["scopes"] - if !ok { - return defaultScopes - } - if scopes == "" { - return []string{} - } - return strings.Split(gcpConfig["scopes"], ",") -} - -func (g *gcpAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper { - var resetCache map[string]string - if cts, ok := g.tokenSource.(*cachedTokenSource); ok { - resetCache = cts.baseCache() - } else { - resetCache = make(map[string]string) - } - return &conditionalTransport{&oauth2.Transport{Source: g.tokenSource, Base: rt}, g.persister, resetCache} -} - -func (g *gcpAuthProvider) Login() error { return nil } - -type cachedTokenSource struct { - lk sync.Mutex - source oauth2.TokenSource - accessToken string `datapolicy:"token"` - expiry time.Time - persister restclient.AuthProviderConfigPersister - cache map[string]string -} - -func newCachedTokenSource(accessToken, expiry string, persister restclient.AuthProviderConfigPersister, ts oauth2.TokenSource, cache map[string]string) (*cachedTokenSource, error) { - var expiryTime time.Time - if parsedTime, err := time.Parse(time.RFC3339Nano, expiry); err == nil { - expiryTime = parsedTime - } - if cache == nil { - cache = make(map[string]string) - } - return &cachedTokenSource{ - source: ts, - accessToken: accessToken, - expiry: expiryTime, - persister: persister, - cache: cache, - }, nil -} - -func (t *cachedTokenSource) Token() (*oauth2.Token, error) { - tok := t.cachedToken() - if tok.Valid() && !tok.Expiry.IsZero() { - return tok, nil - } - tok, err := t.source.Token() - if err != nil { - return nil, err - } - cache := t.update(tok) - if t.persister != nil { - if err := t.persister.Persist(cache); err != nil { - klog.V(4).Infof("Failed to persist token: %v", err) - } - } - return tok, nil -} - -func (t *cachedTokenSource) cachedToken() *oauth2.Token { - t.lk.Lock() - defer t.lk.Unlock() - return &oauth2.Token{ - AccessToken: t.accessToken, - TokenType: "Bearer", - Expiry: t.expiry, - } -} - -func (t *cachedTokenSource) update(tok *oauth2.Token) map[string]string { - t.lk.Lock() - defer t.lk.Unlock() - t.accessToken = tok.AccessToken - t.expiry = tok.Expiry - ret := map[string]string{} - for k, v := range t.cache { - ret[k] = v - } - ret["access-token"] = t.accessToken - ret["expiry"] = t.expiry.Format(time.RFC3339Nano) - return ret -} - -// baseCache is the base configuration value for this TokenSource, without any cached ephemeral tokens. -func (t *cachedTokenSource) baseCache() map[string]string { - t.lk.Lock() - defer t.lk.Unlock() - ret := map[string]string{} - for k, v := range t.cache { - ret[k] = v - } - delete(ret, "access-token") - delete(ret, "expiry") - return ret -} - -type commandTokenSource struct { - cmd string - args []string - tokenKey string `datapolicy:"token"` - expiryKey string `datapolicy:"secret-key"` - timeFmt string -} - -func newCmdTokenSource(cmd string, args []string, tokenKey, expiryKey, timeFmt string) *commandTokenSource { - if len(timeFmt) == 0 { - timeFmt = time.RFC3339Nano - } - if len(tokenKey) == 0 { - tokenKey = "{.access_token}" - } - if len(expiryKey) == 0 { - expiryKey = "{.token_expiry}" - } - return &commandTokenSource{ - cmd: cmd, - args: args, - tokenKey: tokenKey, - expiryKey: expiryKey, - timeFmt: timeFmt, - } -} - -func (c *commandTokenSource) Token() (*oauth2.Token, error) { - fullCmd := strings.Join(append([]string{c.cmd}, c.args...), " ") - cmd := execCommand(c.cmd, c.args...) - var stderr bytes.Buffer - cmd.Stderr = &stderr - output, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("error executing access token command %q: err=%v output=%s stderr=%s", fullCmd, err, output, string(stderr.Bytes())) - } - token, err := c.parseTokenCmdOutput(output) - if err != nil { - return nil, fmt.Errorf("error parsing output for access token command %q: %v", fullCmd, err) - } - return token, nil -} - -func (c *commandTokenSource) parseTokenCmdOutput(output []byte) (*oauth2.Token, error) { - output, err := yaml.ToJSON(output) - if err != nil { - return nil, err - } - var data interface{} - if err := json.Unmarshal(output, &data); err != nil { - return nil, err - } - - accessToken, err := parseJSONPath(data, "token-key", c.tokenKey) - if err != nil { - return nil, fmt.Errorf("error parsing token-key %q from %q: %v", c.tokenKey, string(output), err) - } - expiryStr, err := parseJSONPath(data, "expiry-key", c.expiryKey) - if err != nil { - return nil, fmt.Errorf("error parsing expiry-key %q from %q: %v", c.expiryKey, string(output), err) - } - var expiry time.Time - if t, err := time.Parse(c.timeFmt, expiryStr); err != nil { - klog.V(4).Infof("Failed to parse token expiry from %s (fmt=%s): %v", expiryStr, c.timeFmt, err) - } else { - expiry = t - } - - return &oauth2.Token{ - AccessToken: accessToken, - TokenType: "Bearer", - Expiry: expiry, - }, nil -} - -func parseJSONPath(input interface{}, name, template string) (string, error) { - j := jsonpath.New(name) - buf := new(bytes.Buffer) - if err := j.Parse(template); err != nil { - return "", err - } - if err := j.Execute(buf, input); err != nil { - return "", err - } - return buf.String(), nil -} - -type conditionalTransport struct { - oauthTransport *oauth2.Transport - persister restclient.AuthProviderConfigPersister - resetCache map[string]string -} - -var _ net.RoundTripperWrapper = &conditionalTransport{} - -func (t *conditionalTransport) RoundTrip(req *http.Request) (*http.Response, error) { - if len(req.Header.Get("Authorization")) != 0 { - return t.oauthTransport.Base.RoundTrip(req) - } - - res, err := t.oauthTransport.RoundTrip(req) - - if err != nil { - return nil, err - } - - if res.StatusCode == 401 { - klog.V(4).Infof("The credentials that were supplied are invalid for the target cluster") - t.persister.Persist(t.resetCache) - } - - return res, nil -} - -func (t *conditionalTransport) WrappedRoundTripper() http.RoundTripper { return t.oauthTransport.Base } diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp_stub.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp_stub.go new file mode 100644 index 00000000000..99585f93917 --- /dev/null +++ b/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp_stub.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package gcp + +import ( + "errors" + + "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +func init() { + if err := rest.RegisterAuthProviderPlugin("gcp", newGCPAuthProvider); err != nil { + klog.Fatalf("Failed to register gcp auth plugin: %v", err) + } +} + +func newGCPAuthProvider(_ string, _ map[string]string, _ rest.AuthProviderConfigPersister) (rest.AuthProvider, error) { + return nil, errors.New(`The gcp auth plugin has been removed. +Please use the "gke-gcloud-auth-plugin" kubectl/client-go credential plugin instead. +See https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke for further details`) +} diff --git a/vendor/k8s.io/client-go/rest/client.go b/vendor/k8s.io/client-go/rest/client.go index c969300494c..60df7e568c3 100644 --- a/vendor/k8s.io/client-go/rest/client.go +++ b/vendor/k8s.io/client-go/rest/client.go @@ -52,7 +52,7 @@ type Interface interface { // ClientContentConfig controls how RESTClient communicates with the server. // // TODO: ContentConfig will be updated to accept a Negotiator instead of a -// NegotiatedSerializer and NegotiatedSerializer will be removed. +// NegotiatedSerializer and NegotiatedSerializer will be removed. type ClientContentConfig struct { // AcceptContentTypes specifies the types the client will accept and is optional. // If not set, ContentType will be used to define the Accept header @@ -159,13 +159,14 @@ func readExpBackoffConfig() BackoffManager { // c, err := NewRESTClient(...) // if err != nil { ... } // resp, err := c.Verb("GET"). -// Path("pods"). -// SelectorParam("labels", "area=staging"). -// Timeout(10*time.Second). -// Do() +// +// Path("pods"). +// SelectorParam("labels", "area=staging"). +// Timeout(10*time.Second). +// Do() +// // if err != nil { ... } // list, ok := resp.(*api.PodList) -// func (c *RESTClient) Verb(verb string) *Request { return NewRequest(c).Verb(verb) } diff --git a/vendor/k8s.io/client-go/rest/config.go b/vendor/k8s.io/client-go/rest/config.go index 4909dc53abb..81e3cbd6897 100644 --- a/vendor/k8s.io/client-go/rest/config.go +++ b/vendor/k8s.io/client-go/rest/config.go @@ -20,7 +20,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "net" "net/http" "net/url" @@ -519,7 +518,7 @@ func InClusterConfig() (*Config, error) { return nil, ErrNotInCluster } - token, err := ioutil.ReadFile(tokenFile) + token, err := os.ReadFile(tokenFile) if err != nil { return nil, err } @@ -572,10 +571,7 @@ func LoadTLSFiles(c *Config) error { } c.KeyData, err = dataFromSliceOrFile(c.KeyData, c.KeyFile) - if err != nil { - return err - } - return nil + return err } // dataFromSliceOrFile returns data from the slice (if non-empty), or from the file, @@ -585,7 +581,7 @@ func dataFromSliceOrFile(data []byte, file string) ([]byte, error) { return data, nil } if len(file) > 0 { - fileData, err := ioutil.ReadFile(file) + fileData, err := os.ReadFile(file) if err != nil { return []byte{}, err } diff --git a/vendor/k8s.io/client-go/rest/exec.go b/vendor/k8s.io/client-go/rest/exec.go index 5f3b43c55a8..96f5dba3570 100644 --- a/vendor/k8s.io/client-go/rest/exec.go +++ b/vendor/k8s.io/client-go/rest/exec.go @@ -21,7 +21,6 @@ import ( "net/http" "net/url" - "k8s.io/client-go/pkg/apis/clientauthentication" clientauthenticationapi "k8s.io/client-go/pkg/apis/clientauthentication" ) @@ -50,12 +49,13 @@ func ConfigToExecCluster(config *Config) (*clientauthenticationapi.Cluster, erro } } - return &clientauthentication.Cluster{ + return &clientauthenticationapi.Cluster{ Server: config.Host, TLSServerName: config.ServerName, InsecureSkipTLSVerify: config.Insecure, CertificateAuthorityData: caData, ProxyURL: proxyURL, + DisableCompression: config.DisableCompression, Config: config.ExecProvider.Config, }, nil } @@ -63,7 +63,7 @@ func ConfigToExecCluster(config *Config) (*clientauthenticationapi.Cluster, erro // ExecClusterToConfig creates a Config with the corresponding fields from the provided // clientauthenticationapi.Cluster. The returned Config will be anonymous (i.e., it will not have // any authentication-related fields set). -func ExecClusterToConfig(cluster *clientauthentication.Cluster) (*Config, error) { +func ExecClusterToConfig(cluster *clientauthenticationapi.Cluster) (*Config, error) { var proxy func(*http.Request) (*url.URL, error) if cluster.ProxyURL != "" { proxyURL, err := url.Parse(cluster.ProxyURL) @@ -80,6 +80,7 @@ func ExecClusterToConfig(cluster *clientauthentication.Cluster) (*Config, error) ServerName: cluster.TLSServerName, CAData: cluster.CertificateAuthorityData, }, - Proxy: proxy, + Proxy: proxy, + DisableCompression: cluster.DisableCompression, }, nil } diff --git a/vendor/k8s.io/client-go/rest/plugin.go b/vendor/k8s.io/client-go/rest/plugin.go index c2b3dfc0f5e..ae5cbdc2c4c 100644 --- a/vendor/k8s.io/client-go/rest/plugin.go +++ b/vendor/k8s.io/client-go/rest/plugin.go @@ -36,9 +36,10 @@ type AuthProvider interface { } // Factory generates an AuthProvider plugin. -// clusterAddress is the address of the current cluster. -// config is the initial configuration for this plugin. -// persister allows the plugin to save updated configuration. +// +// clusterAddress is the address of the current cluster. +// config is the initial configuration for this plugin. +// persister allows the plugin to save updated configuration. type Factory func(clusterAddress string, config map[string]string, persister AuthProviderConfigPersister) (AuthProvider, error) // AuthProviderConfigPersister allows a plugin to persist configuration info diff --git a/vendor/k8s.io/client-go/rest/request.go b/vendor/k8s.io/client-go/rest/request.go index e3830623383..bb6fb4decb7 100644 --- a/vendor/k8s.io/client-go/rest/request.go +++ b/vendor/k8s.io/client-go/rest/request.go @@ -22,10 +22,10 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" "mime" "net/http" "net/url" + "os" "path" "reflect" "strconv" @@ -34,6 +34,7 @@ import ( "time" "golang.org/x/net/http2" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -116,8 +117,11 @@ type Request struct { subresource string // output - err error - body io.Reader + err error + + // only one of body / bodyBytes may be set. requests using body are not retriable. + body io.Reader + bodyBytes []byte retryFn requestRetryFunc } @@ -437,18 +441,21 @@ func (r *Request) Body(obj interface{}) *Request { } switch t := obj.(type) { case string: - data, err := ioutil.ReadFile(t) + data, err := os.ReadFile(t) if err != nil { r.err = err return r } glogBody("Request Body", data) - r.body = bytes.NewReader(data) + r.body = nil + r.bodyBytes = data case []byte: glogBody("Request Body", t) - r.body = bytes.NewReader(t) + r.body = nil + r.bodyBytes = t case io.Reader: r.body = t + r.bodyBytes = nil case runtime.Object: // callers may pass typed interface pointers, therefore we must check nil with reflection if reflect.ValueOf(t).IsNil() { @@ -465,7 +472,8 @@ func (r *Request) Body(obj interface{}) *Request { return r } glogBody("Request Body", data) - r.body = bytes.NewReader(data) + r.body = nil + r.bodyBytes = data r.SetHeader("Content-Type", r.c.content.ContentType) default: r.err = fmt.Errorf("unknown type used for body: %+v", obj) @@ -473,7 +481,13 @@ func (r *Request) Body(obj interface{}) *Request { return r } -// URL returns the current working URL. +// Error returns any error encountered constructing the request, if any. +func (r *Request) Error() error { + return r.err +} + +// URL returns the current working URL. Check the result of Error() to ensure +// that the returned URL is valid. func (r *Request) URL() *url.URL { p := r.pathPrefix if r.namespaceSet && len(r.namespace) > 0 { @@ -718,7 +732,6 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) { } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err == nil && resp.StatusCode == http.StatusOK { return r.newStreamWatcher(resp) @@ -778,22 +791,36 @@ func (r *Request) newStreamWatcher(resp *http.Response) (watch.Interface, error) ), nil } -// updateURLMetrics is a convenience function for pushing metrics. -// It also handles corner cases for incomplete/invalid request data. -func updateURLMetrics(ctx context.Context, req *Request, resp *http.Response, err error) { - url := "none" +// updateRequestResultMetric increments the RequestResult metric counter, +// it should be called with the (response, err) tuple from the final +// reply from the server. +func updateRequestResultMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestResult.Increment(ctx, code, req.verb, host) +} + +// updateRequestRetryMetric increments the RequestRetry metric counter, +// it should be called with the (response, err) tuple for each retry +// except for the final attempt. +func updateRequestRetryMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestRetry.IncrementRetry(ctx, code, req.verb, host) +} + +func sanitize(req *Request, resp *http.Response, err error) (string, string) { + host := "none" if req.c.base != nil { - url = req.c.base.Host + host = req.c.base.Host } // Errors can be arbitrary strings. Unbound label cardinality is not suitable for a metric // system so we just report them as ``. - if err != nil { - metrics.RequestResult.Increment(ctx, "", req.verb, url) - } else { - //Metrics for failure codes - metrics.RequestResult.Increment(ctx, strconv.Itoa(resp.StatusCode), req.verb, url) + code := "" + if resp != nil { + code = strconv.Itoa(resp.StatusCode) } + + return code, host } // Stream formats and executes the request, and offers streaming of the response. @@ -825,11 +852,7 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) { if err != nil { return nil, err } - if r.body != nil { - req.Body = ioutil.NopCloser(r.body) - } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err != nil { // we only retry on an HTTP response with 'Retry-After' header @@ -889,8 +912,20 @@ func (r *Request) requestPreflightCheck() error { } func (r *Request) newHTTPRequest(ctx context.Context) (*http.Request, error) { + var body io.Reader + switch { + case r.body != nil && r.bodyBytes != nil: + return nil, fmt.Errorf("cannot set both body and bodyBytes") + case r.body != nil: + body = r.body + case r.bodyBytes != nil: + // Create a new reader specifically for this request. + // Giving each request a dedicated reader allows retries to avoid races resetting the request body. + body = bytes.NewReader(r.bodyBytes) + } + url := r.URL().String() - req, err := http.NewRequest(r.verb, url, r.body) + req, err := http.NewRequest(r.verb, url, body) if err != nil { return nil, err } @@ -904,7 +939,7 @@ func (r *Request) newHTTPRequest(ctx context.Context) (*http.Request, error) { // fn at most once. It will return an error if a problem occurred prior to connecting to the // server - the provided function is responsible for handling server errors. func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Response)) error { - //Metrics for total request latency + // Metrics for total request latency start := time.Now() defer func() { metrics.RequestLatency.Observe(ctx, r.verb, r.finalURLTemplate(), time.Since(start)) @@ -962,7 +997,6 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp return err } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) // The value -1 or a value of 0 with a non-nil Body indicates that the length is unknown. // https://pkg.go.dev/net/http#Request if req.ContentLength >= 0 && !(req.Body != nil && req.ContentLength == 0) { @@ -973,7 +1007,7 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp done := func() bool { defer readAndCloseResponseBody(resp) - // if the the server returns an error in err, the response will be nil. + // if the server returns an error in err, the response will be nil. f := func(req *http.Request, resp *http.Response) { if resp == nil { return @@ -998,8 +1032,8 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp // processing. // // Error type: -// * If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError -// * http.Client.Do errors are returned directly. +// - If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError +// - http.Client.Do errors are returned directly. func (r *Request) Do(ctx context.Context) Result { var result Result err := r.request(ctx, func(req *http.Request, resp *http.Response) { @@ -1018,7 +1052,7 @@ func (r *Request) Do(ctx context.Context) Result { func (r *Request) DoRaw(ctx context.Context) ([]byte, error) { var result Result err := r.request(ctx, func(req *http.Request, resp *http.Response) { - result.body, result.err = ioutil.ReadAll(resp.Body) + result.body, result.err = io.ReadAll(resp.Body) glogBody("Response Body", result.body) if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent { result.err = r.transformUnstructuredResponseError(resp, req, result.body) @@ -1037,7 +1071,7 @@ func (r *Request) DoRaw(ctx context.Context) ([]byte, error) { func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result { var body []byte if resp.Body != nil { - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) switch err.(type) { case nil: body = data @@ -1166,20 +1200,20 @@ const maxUnstructuredResponseTextBytes = 2048 // unexpected responses. The rough structure is: // // 1. Assume the server sends you something sane - JSON + well defined error objects + proper codes -// - this is the happy path -// - when you get this output, trust what the server sends -// 2. Guard against empty fields / bodies in received JSON and attempt to cull sufficient info from them to -// generate a reasonable facsimile of the original failure. -// - Be sure to use a distinct error type or flag that allows a client to distinguish between this and error 1 above -// 3. Handle true disconnect failures / completely malformed data by moving up to a more generic client error -// 4. Distinguish between various connection failures like SSL certificates, timeouts, proxy errors, unexpected -// initial contact, the presence of mismatched body contents from posted content types -// - Give these a separate distinct error type and capture as much as possible of the original message +// - this is the happy path +// - when you get this output, trust what the server sends +// 2. Guard against empty fields / bodies in received JSON and attempt to cull sufficient info from them to +// generate a reasonable facsimile of the original failure. +// - Be sure to use a distinct error type or flag that allows a client to distinguish between this and error 1 above +// 3. Handle true disconnect failures / completely malformed data by moving up to a more generic client error +// 4. Distinguish between various connection failures like SSL certificates, timeouts, proxy errors, unexpected +// initial contact, the presence of mismatched body contents from posted content types +// - Give these a separate distinct error type and capture as much as possible of the original message // // TODO: introduce transformation of generic http.Client.Do() errors that separates 4. func (r *Request) transformUnstructuredResponseError(resp *http.Response, req *http.Request, body []byte) error { if body == nil && resp.Body != nil { - if data, err := ioutil.ReadAll(&io.LimitedReader{R: resp.Body, N: maxUnstructuredResponseTextBytes}); err == nil { + if data, err := io.ReadAll(&io.LimitedReader{R: resp.Body, N: maxUnstructuredResponseTextBytes}); err == nil { body = data } } @@ -1288,6 +1322,14 @@ func (r Result) StatusCode(statusCode *int) Result { return r } +// ContentType returns the "Content-Type" response header into the passed +// string, returning the Result for possible chaining. (Only valid if no +// error code was returned.) +func (r Result) ContentType(contentType *string) Result { + *contentType = r.contentType + return r +} + // Into stores the result into obj, if possible. If obj is nil it is ignored. // If the returned object is of type Status and has .Status != StatusSuccess, the // additional information in Status will be used to enrich the error. diff --git a/vendor/k8s.io/client-go/rest/transport.go b/vendor/k8s.io/client-go/rest/transport.go index 7c38c6d92c1..53f986cbf31 100644 --- a/vendor/k8s.io/client-go/rest/transport.go +++ b/vendor/k8s.io/client-go/rest/transport.go @@ -108,10 +108,13 @@ func (c *Config) TransportConfig() (*transport.Config, error) { Groups: c.Impersonate.Groups, Extra: c.Impersonate.Extra, }, - Dial: c.Dial, Proxy: c.Proxy, } + if c.Dial != nil { + conf.DialHolder = &transport.DialHolder{Dial: c.Dial} + } + if c.ExecProvider != nil && c.AuthProvider != nil { return nil, errors.New("execProvider and authProvider cannot be used in combination") } diff --git a/vendor/k8s.io/client-go/rest/warnings.go b/vendor/k8s.io/client-go/rest/warnings.go index 18476f5ff90..ad493659f22 100644 --- a/vendor/k8s.io/client-go/rest/warnings.go +++ b/vendor/k8s.io/client-go/rest/warnings.go @@ -40,9 +40,9 @@ var ( // SetDefaultWarningHandler sets the default handler clients use when warning headers are encountered. // By default, warnings are logged. Several built-in implementations are provided: -// - NoWarnings suppresses warnings. -// - WarningLogger logs warnings. -// - NewWarningWriter() outputs warnings to the provided writer. +// - NoWarnings suppresses warnings. +// - WarningLogger logs warnings. +// - NewWarningWriter() outputs warnings to the provided writer. func SetDefaultWarningHandler(l WarningHandler) { defaultWarningHandlerLock.Lock() defer defaultWarningHandlerLock.Unlock() diff --git a/vendor/k8s.io/client-go/rest/with_retry.go b/vendor/k8s.io/client-go/rest/with_retry.go index 497d2608f88..eaaadc6a4c3 100644 --- a/vendor/k8s.io/client-go/rest/with_retry.go +++ b/vendor/k8s.io/client-go/rest/with_retry.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net/http" "net/url" "time" @@ -154,6 +153,11 @@ func (r *withRetry) IsNextRetry(ctx context.Context, restReq *Request, httpReq * return false } + if restReq.body != nil { + // we have an opaque reader, we can't safely reset it + return false + } + r.attempts++ r.retryAfter = &RetryAfter{Attempt: r.attempts} if r.attempts > r.maxRetries { @@ -204,30 +208,19 @@ func (r *withRetry) Before(ctx context.Context, request *Request) error { if r.retryAfter == nil { // we do a backoff sleep before the first attempt is made, // (preserving current behavior). - request.backoff.Sleep(request.backoff.CalculateBackoff(url)) - return nil - } - - // At this point we've made atleast one attempt, post which the response - // body should have been fully read and closed in order for it to be safe - // to reset the request body before we reconnect, in order for us to reuse - // the same TCP connection. - if seeker, ok := request.body.(io.Seeker); ok && request.body != nil { - if _, err := seeker.Seek(0, io.SeekStart); err != nil { - err = fmt.Errorf("failed to reset the request body while retrying a request: %v", err) - r.trackPreviousError(err) - return err + if request.backoff != nil { + request.backoff.Sleep(request.backoff.CalculateBackoff(url)) } + return nil } - // if we are here, we have made attempt(s) al least once before. + // if we are here, we have made attempt(s) at least once before. if request.backoff != nil { - // TODO(tkashem) with default set to use exponential backoff - // we can merge these two sleeps: - // BackOffManager.Sleep(max(backoffManager.CalculateBackoff(), retryAfter)) - // see https://github.com/kubernetes/kubernetes/issues/108302 - request.backoff.Sleep(r.retryAfter.Wait) - request.backoff.Sleep(request.backoff.CalculateBackoff(url)) + delay := request.backoff.CalculateBackoff(url) + if r.retryAfter.Wait > delay { + delay = r.retryAfter.Wait + } + request.backoff.Sleep(delay) } // We are retrying the request that we already send to @@ -249,8 +242,20 @@ func (r *withRetry) After(ctx context.Context, request *Request, resp *http.Resp // parameters calculated from the (response, err) tuple from // attempt N-1, so r.retryAfter is outdated and should not be // referred to here. + isRetry := r.retryAfter != nil r.retryAfter = nil + // the client finishes a single request after N attempts (1..N) + // - all attempts (1..N) are counted to the rest_client_requests_total + // metric (current behavior). + // - every attempt after the first (2..N) are counted to the + // rest_client_request_retries_total metric. + updateRequestResultMetric(ctx, request, resp, err) + if isRetry { + // this is attempt 2 or later + updateRequestRetryMetric(ctx, request, resp, err) + } + if request.c.base != nil { if err != nil { request.backoff.UpdateBackoff(request.URL(), err, 0) @@ -344,13 +349,21 @@ func readAndCloseResponseBody(resp *http.Response) { defer resp.Body.Close() if resp.ContentLength <= maxBodySlurpSize { - io.Copy(ioutil.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize}) + io.Copy(io.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize}) } } func retryAfterResponse() *http.Response { + return retryAfterResponseWithDelay("1") +} + +func retryAfterResponseWithDelay(delay string) *http.Response { + return retryAfterResponseWithCodeAndDelay(http.StatusInternalServerError, delay) +} + +func retryAfterResponseWithCodeAndDelay(code int, delay string) *http.Response { return &http.Response{ - StatusCode: http.StatusInternalServerError, - Header: http.Header{"Retry-After": []string{"1"}}, + StatusCode: code, + Header: http.Header{"Retry-After": []string{delay}}, } } diff --git a/vendor/k8s.io/client-go/restmapper/shortcut.go b/vendor/k8s.io/client-go/restmapper/shortcut.go index 714ba90a7aa..7ab3cd46fe3 100644 --- a/vendor/k8s.io/client-go/restmapper/shortcut.go +++ b/vendor/k8s.io/client-go/restmapper/shortcut.go @@ -43,7 +43,18 @@ func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInt // KindFor fulfills meta.RESTMapper func (e shortcutExpander) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { - return e.RESTMapper.KindFor(e.expandResourceShortcut(resource)) + // expandResourceShortcut works with current API resources as read from discovery cache. + // In case of new CRDs this means we potentially don't have current state of discovery. + // In the current wiring in k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go#toRESTMapper, + // we are using DeferredDiscoveryRESTMapper which on KindFor failure will clear the + // cache and fetch all data from a cluster (see vendor/k8s.io/client-go/restmapper/discovery.go#KindFor). + // Thus another call to expandResourceShortcut, after a NoMatchError should successfully + // read Kind to the user or an error. + gvk, err := e.RESTMapper.KindFor(e.expandResourceShortcut(resource)) + if meta.IsNoMatchError(err) { + return e.RESTMapper.KindFor(e.expandResourceShortcut(resource)) + } + return gvk, err } // KindsFor fulfills meta.RESTMapper diff --git a/vendor/k8s.io/client-go/testing/actions.go b/vendor/k8s.io/client-go/testing/actions.go new file mode 100644 index 00000000000..c8ae0aaf5d4 --- /dev/null +++ b/vendor/k8s.io/client-go/testing/actions.go @@ -0,0 +1,698 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "fmt" + "path" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" +) + +func NewRootGetAction(resource schema.GroupVersionResource, name string) GetActionImpl { + action := GetActionImpl{} + action.Verb = "get" + action.Resource = resource + action.Name = name + + return action +} + +func NewGetAction(resource schema.GroupVersionResource, namespace, name string) GetActionImpl { + action := GetActionImpl{} + action.Verb = "get" + action.Resource = resource + action.Namespace = namespace + action.Name = name + + return action +} + +func NewGetSubresourceAction(resource schema.GroupVersionResource, namespace, subresource, name string) GetActionImpl { + action := GetActionImpl{} + action.Verb = "get" + action.Resource = resource + action.Subresource = subresource + action.Namespace = namespace + action.Name = name + + return action +} + +func NewRootGetSubresourceAction(resource schema.GroupVersionResource, subresource, name string) GetActionImpl { + action := GetActionImpl{} + action.Verb = "get" + action.Resource = resource + action.Subresource = subresource + action.Name = name + + return action +} + +func NewRootListAction(resource schema.GroupVersionResource, kind schema.GroupVersionKind, opts interface{}) ListActionImpl { + action := ListActionImpl{} + action.Verb = "list" + action.Resource = resource + action.Kind = kind + labelSelector, fieldSelector, _ := ExtractFromListOptions(opts) + action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector} + + return action +} + +func NewListAction(resource schema.GroupVersionResource, kind schema.GroupVersionKind, namespace string, opts interface{}) ListActionImpl { + action := ListActionImpl{} + action.Verb = "list" + action.Resource = resource + action.Kind = kind + action.Namespace = namespace + labelSelector, fieldSelector, _ := ExtractFromListOptions(opts) + action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector} + + return action +} + +func NewRootCreateAction(resource schema.GroupVersionResource, object runtime.Object) CreateActionImpl { + action := CreateActionImpl{} + action.Verb = "create" + action.Resource = resource + action.Object = object + + return action +} + +func NewCreateAction(resource schema.GroupVersionResource, namespace string, object runtime.Object) CreateActionImpl { + action := CreateActionImpl{} + action.Verb = "create" + action.Resource = resource + action.Namespace = namespace + action.Object = object + + return action +} + +func NewRootCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource string, object runtime.Object) CreateActionImpl { + action := CreateActionImpl{} + action.Verb = "create" + action.Resource = resource + action.Subresource = subresource + action.Name = name + action.Object = object + + return action +} + +func NewCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource, namespace string, object runtime.Object) CreateActionImpl { + action := CreateActionImpl{} + action.Verb = "create" + action.Resource = resource + action.Namespace = namespace + action.Subresource = subresource + action.Name = name + action.Object = object + + return action +} + +func NewRootUpdateAction(resource schema.GroupVersionResource, object runtime.Object) UpdateActionImpl { + action := UpdateActionImpl{} + action.Verb = "update" + action.Resource = resource + action.Object = object + + return action +} + +func NewUpdateAction(resource schema.GroupVersionResource, namespace string, object runtime.Object) UpdateActionImpl { + action := UpdateActionImpl{} + action.Verb = "update" + action.Resource = resource + action.Namespace = namespace + action.Object = object + + return action +} + +func NewRootPatchAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Name = name + action.PatchType = pt + action.Patch = patch + + return action +} + +func NewPatchAction(resource schema.GroupVersionResource, namespace string, name string, pt types.PatchType, patch []byte) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Namespace = namespace + action.Name = name + action.PatchType = pt + action.Patch = patch + + return action +} + +func NewRootPatchSubresourceAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Subresource = path.Join(subresources...) + action.Name = name + action.PatchType = pt + action.Patch = patch + + return action +} + +func NewPatchSubresourceAction(resource schema.GroupVersionResource, namespace, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl { + action := PatchActionImpl{} + action.Verb = "patch" + action.Resource = resource + action.Subresource = path.Join(subresources...) + action.Namespace = namespace + action.Name = name + action.PatchType = pt + action.Patch = patch + + return action +} + +func NewRootUpdateSubresourceAction(resource schema.GroupVersionResource, subresource string, object runtime.Object) UpdateActionImpl { + action := UpdateActionImpl{} + action.Verb = "update" + action.Resource = resource + action.Subresource = subresource + action.Object = object + + return action +} +func NewUpdateSubresourceAction(resource schema.GroupVersionResource, subresource string, namespace string, object runtime.Object) UpdateActionImpl { + action := UpdateActionImpl{} + action.Verb = "update" + action.Resource = resource + action.Subresource = subresource + action.Namespace = namespace + action.Object = object + + return action +} + +func NewRootDeleteAction(resource schema.GroupVersionResource, name string) DeleteActionImpl { + return NewRootDeleteActionWithOptions(resource, name, metav1.DeleteOptions{}) +} + +func NewRootDeleteActionWithOptions(resource schema.GroupVersionResource, name string, opts metav1.DeleteOptions) DeleteActionImpl { + action := DeleteActionImpl{} + action.Verb = "delete" + action.Resource = resource + action.Name = name + action.DeleteOptions = opts + + return action +} + +func NewRootDeleteSubresourceAction(resource schema.GroupVersionResource, subresource string, name string) DeleteActionImpl { + action := DeleteActionImpl{} + action.Verb = "delete" + action.Resource = resource + action.Subresource = subresource + action.Name = name + + return action +} + +func NewDeleteAction(resource schema.GroupVersionResource, namespace, name string) DeleteActionImpl { + return NewDeleteActionWithOptions(resource, namespace, name, metav1.DeleteOptions{}) +} + +func NewDeleteActionWithOptions(resource schema.GroupVersionResource, namespace, name string, opts metav1.DeleteOptions) DeleteActionImpl { + action := DeleteActionImpl{} + action.Verb = "delete" + action.Resource = resource + action.Namespace = namespace + action.Name = name + action.DeleteOptions = opts + + return action +} + +func NewDeleteSubresourceAction(resource schema.GroupVersionResource, subresource, namespace, name string) DeleteActionImpl { + action := DeleteActionImpl{} + action.Verb = "delete" + action.Resource = resource + action.Subresource = subresource + action.Namespace = namespace + action.Name = name + + return action +} + +func NewRootDeleteCollectionAction(resource schema.GroupVersionResource, opts interface{}) DeleteCollectionActionImpl { + action := DeleteCollectionActionImpl{} + action.Verb = "delete-collection" + action.Resource = resource + labelSelector, fieldSelector, _ := ExtractFromListOptions(opts) + action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector} + + return action +} + +func NewDeleteCollectionAction(resource schema.GroupVersionResource, namespace string, opts interface{}) DeleteCollectionActionImpl { + action := DeleteCollectionActionImpl{} + action.Verb = "delete-collection" + action.Resource = resource + action.Namespace = namespace + labelSelector, fieldSelector, _ := ExtractFromListOptions(opts) + action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector} + + return action +} + +func NewRootWatchAction(resource schema.GroupVersionResource, opts interface{}) WatchActionImpl { + action := WatchActionImpl{} + action.Verb = "watch" + action.Resource = resource + labelSelector, fieldSelector, resourceVersion := ExtractFromListOptions(opts) + action.WatchRestrictions = WatchRestrictions{labelSelector, fieldSelector, resourceVersion} + + return action +} + +func ExtractFromListOptions(opts interface{}) (labelSelector labels.Selector, fieldSelector fields.Selector, resourceVersion string) { + var err error + switch t := opts.(type) { + case metav1.ListOptions: + labelSelector, err = labels.Parse(t.LabelSelector) + if err != nil { + panic(fmt.Errorf("invalid selector %q: %v", t.LabelSelector, err)) + } + fieldSelector, err = fields.ParseSelector(t.FieldSelector) + if err != nil { + panic(fmt.Errorf("invalid selector %q: %v", t.FieldSelector, err)) + } + resourceVersion = t.ResourceVersion + default: + panic(fmt.Errorf("expect a ListOptions %T", opts)) + } + if labelSelector == nil { + labelSelector = labels.Everything() + } + if fieldSelector == nil { + fieldSelector = fields.Everything() + } + return labelSelector, fieldSelector, resourceVersion +} + +func NewWatchAction(resource schema.GroupVersionResource, namespace string, opts interface{}) WatchActionImpl { + action := WatchActionImpl{} + action.Verb = "watch" + action.Resource = resource + action.Namespace = namespace + labelSelector, fieldSelector, resourceVersion := ExtractFromListOptions(opts) + action.WatchRestrictions = WatchRestrictions{labelSelector, fieldSelector, resourceVersion} + + return action +} + +func NewProxyGetAction(resource schema.GroupVersionResource, namespace, scheme, name, port, path string, params map[string]string) ProxyGetActionImpl { + action := ProxyGetActionImpl{} + action.Verb = "get" + action.Resource = resource + action.Namespace = namespace + action.Scheme = scheme + action.Name = name + action.Port = port + action.Path = path + action.Params = params + return action +} + +type ListRestrictions struct { + Labels labels.Selector + Fields fields.Selector +} +type WatchRestrictions struct { + Labels labels.Selector + Fields fields.Selector + ResourceVersion string +} + +type Action interface { + GetNamespace() string + GetVerb() string + GetResource() schema.GroupVersionResource + GetSubresource() string + Matches(verb, resource string) bool + + // DeepCopy is used to copy an action to avoid any risk of accidental mutation. Most people never need to call this + // because the invocation logic deep copies before calls to storage and reactors. + DeepCopy() Action +} + +type GenericAction interface { + Action + GetValue() interface{} +} + +type GetAction interface { + Action + GetName() string +} + +type ListAction interface { + Action + GetListRestrictions() ListRestrictions +} + +type CreateAction interface { + Action + GetObject() runtime.Object +} + +type UpdateAction interface { + Action + GetObject() runtime.Object +} + +type DeleteAction interface { + Action + GetName() string + GetDeleteOptions() metav1.DeleteOptions +} + +type DeleteCollectionAction interface { + Action + GetListRestrictions() ListRestrictions +} + +type PatchAction interface { + Action + GetName() string + GetPatchType() types.PatchType + GetPatch() []byte +} + +type WatchAction interface { + Action + GetWatchRestrictions() WatchRestrictions +} + +type ProxyGetAction interface { + Action + GetScheme() string + GetName() string + GetPort() string + GetPath() string + GetParams() map[string]string +} + +type ActionImpl struct { + Namespace string + Verb string + Resource schema.GroupVersionResource + Subresource string +} + +func (a ActionImpl) GetNamespace() string { + return a.Namespace +} +func (a ActionImpl) GetVerb() string { + return a.Verb +} +func (a ActionImpl) GetResource() schema.GroupVersionResource { + return a.Resource +} +func (a ActionImpl) GetSubresource() string { + return a.Subresource +} +func (a ActionImpl) Matches(verb, resource string) bool { + // Stay backwards compatible. + if !strings.Contains(resource, "/") { + return strings.EqualFold(verb, a.Verb) && + strings.EqualFold(resource, a.Resource.Resource) + } + + parts := strings.SplitN(resource, "/", 2) + topresource, subresource := parts[0], parts[1] + + return strings.EqualFold(verb, a.Verb) && + strings.EqualFold(topresource, a.Resource.Resource) && + strings.EqualFold(subresource, a.Subresource) +} +func (a ActionImpl) DeepCopy() Action { + ret := a + return ret +} + +type GenericActionImpl struct { + ActionImpl + Value interface{} +} + +func (a GenericActionImpl) GetValue() interface{} { + return a.Value +} + +func (a GenericActionImpl) DeepCopy() Action { + return GenericActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + // TODO this is wrong, but no worse than before + Value: a.Value, + } +} + +type GetActionImpl struct { + ActionImpl + Name string +} + +func (a GetActionImpl) GetName() string { + return a.Name +} + +func (a GetActionImpl) DeepCopy() Action { + return GetActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Name: a.Name, + } +} + +type ListActionImpl struct { + ActionImpl + Kind schema.GroupVersionKind + Name string + ListRestrictions ListRestrictions +} + +func (a ListActionImpl) GetKind() schema.GroupVersionKind { + return a.Kind +} + +func (a ListActionImpl) GetListRestrictions() ListRestrictions { + return a.ListRestrictions +} + +func (a ListActionImpl) DeepCopy() Action { + return ListActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Kind: a.Kind, + Name: a.Name, + ListRestrictions: ListRestrictions{ + Labels: a.ListRestrictions.Labels.DeepCopySelector(), + Fields: a.ListRestrictions.Fields.DeepCopySelector(), + }, + } +} + +type CreateActionImpl struct { + ActionImpl + Name string + Object runtime.Object +} + +func (a CreateActionImpl) GetObject() runtime.Object { + return a.Object +} + +func (a CreateActionImpl) DeepCopy() Action { + return CreateActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Name: a.Name, + Object: a.Object.DeepCopyObject(), + } +} + +type UpdateActionImpl struct { + ActionImpl + Object runtime.Object +} + +func (a UpdateActionImpl) GetObject() runtime.Object { + return a.Object +} + +func (a UpdateActionImpl) DeepCopy() Action { + return UpdateActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Object: a.Object.DeepCopyObject(), + } +} + +type PatchActionImpl struct { + ActionImpl + Name string + PatchType types.PatchType + Patch []byte +} + +func (a PatchActionImpl) GetName() string { + return a.Name +} + +func (a PatchActionImpl) GetPatch() []byte { + return a.Patch +} + +func (a PatchActionImpl) GetPatchType() types.PatchType { + return a.PatchType +} + +func (a PatchActionImpl) DeepCopy() Action { + patch := make([]byte, len(a.Patch)) + copy(patch, a.Patch) + return PatchActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Name: a.Name, + PatchType: a.PatchType, + Patch: patch, + } +} + +type DeleteActionImpl struct { + ActionImpl + Name string + DeleteOptions metav1.DeleteOptions +} + +func (a DeleteActionImpl) GetName() string { + return a.Name +} + +func (a DeleteActionImpl) GetDeleteOptions() metav1.DeleteOptions { + return a.DeleteOptions +} + +func (a DeleteActionImpl) DeepCopy() Action { + return DeleteActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Name: a.Name, + DeleteOptions: *a.DeleteOptions.DeepCopy(), + } +} + +type DeleteCollectionActionImpl struct { + ActionImpl + ListRestrictions ListRestrictions +} + +func (a DeleteCollectionActionImpl) GetListRestrictions() ListRestrictions { + return a.ListRestrictions +} + +func (a DeleteCollectionActionImpl) DeepCopy() Action { + return DeleteCollectionActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + ListRestrictions: ListRestrictions{ + Labels: a.ListRestrictions.Labels.DeepCopySelector(), + Fields: a.ListRestrictions.Fields.DeepCopySelector(), + }, + } +} + +type WatchActionImpl struct { + ActionImpl + WatchRestrictions WatchRestrictions +} + +func (a WatchActionImpl) GetWatchRestrictions() WatchRestrictions { + return a.WatchRestrictions +} + +func (a WatchActionImpl) DeepCopy() Action { + return WatchActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + WatchRestrictions: WatchRestrictions{ + Labels: a.WatchRestrictions.Labels.DeepCopySelector(), + Fields: a.WatchRestrictions.Fields.DeepCopySelector(), + ResourceVersion: a.WatchRestrictions.ResourceVersion, + }, + } +} + +type ProxyGetActionImpl struct { + ActionImpl + Scheme string + Name string + Port string + Path string + Params map[string]string +} + +func (a ProxyGetActionImpl) GetScheme() string { + return a.Scheme +} + +func (a ProxyGetActionImpl) GetName() string { + return a.Name +} + +func (a ProxyGetActionImpl) GetPort() string { + return a.Port +} + +func (a ProxyGetActionImpl) GetPath() string { + return a.Path +} + +func (a ProxyGetActionImpl) GetParams() map[string]string { + return a.Params +} + +func (a ProxyGetActionImpl) DeepCopy() Action { + params := map[string]string{} + for k, v := range a.Params { + params[k] = v + } + return ProxyGetActionImpl{ + ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl), + Scheme: a.Scheme, + Name: a.Name, + Port: a.Port, + Path: a.Path, + Params: params, + } +} diff --git a/vendor/k8s.io/client-go/testing/fake.go b/vendor/k8s.io/client-go/testing/fake.go new file mode 100644 index 00000000000..3ab9c1b075d --- /dev/null +++ b/vendor/k8s.io/client-go/testing/fake.go @@ -0,0 +1,220 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "fmt" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + restclient "k8s.io/client-go/rest" +) + +// Fake implements client.Interface. Meant to be embedded into a struct to get +// a default implementation. This makes faking out just the method you want to +// test easier. +type Fake struct { + sync.RWMutex + actions []Action // these may be castable to other types, but "Action" is the minimum + + // ReactionChain is the list of reactors that will be attempted for every + // request in the order they are tried. + ReactionChain []Reactor + // WatchReactionChain is the list of watch reactors that will be attempted + // for every request in the order they are tried. + WatchReactionChain []WatchReactor + // ProxyReactionChain is the list of proxy reactors that will be attempted + // for every request in the order they are tried. + ProxyReactionChain []ProxyReactor + + Resources []*metav1.APIResourceList +} + +// Reactor is an interface to allow the composition of reaction functions. +type Reactor interface { + // Handles indicates whether or not this Reactor deals with a given + // action. + Handles(action Action) bool + // React handles the action and returns results. It may choose to + // delegate by indicated handled=false. + React(action Action) (handled bool, ret runtime.Object, err error) +} + +// WatchReactor is an interface to allow the composition of watch functions. +type WatchReactor interface { + // Handles indicates whether or not this Reactor deals with a given + // action. + Handles(action Action) bool + // React handles a watch action and returns results. It may choose to + // delegate by indicating handled=false. + React(action Action) (handled bool, ret watch.Interface, err error) +} + +// ProxyReactor is an interface to allow the composition of proxy get +// functions. +type ProxyReactor interface { + // Handles indicates whether or not this Reactor deals with a given + // action. + Handles(action Action) bool + // React handles a watch action and returns results. It may choose to + // delegate by indicating handled=false. + React(action Action) (handled bool, ret restclient.ResponseWrapper, err error) +} + +// ReactionFunc is a function that returns an object or error for a given +// Action. If "handled" is false, then the test client will ignore the +// results and continue to the next ReactionFunc. A ReactionFunc can describe +// reactions on subresources by testing the result of the action's +// GetSubresource() method. +type ReactionFunc func(action Action) (handled bool, ret runtime.Object, err error) + +// WatchReactionFunc is a function that returns a watch interface. If +// "handled" is false, then the test client will ignore the results and +// continue to the next ReactionFunc. +type WatchReactionFunc func(action Action) (handled bool, ret watch.Interface, err error) + +// ProxyReactionFunc is a function that returns a ResponseWrapper interface +// for a given Action. If "handled" is false, then the test client will +// ignore the results and continue to the next ProxyReactionFunc. +type ProxyReactionFunc func(action Action) (handled bool, ret restclient.ResponseWrapper, err error) + +// AddReactor appends a reactor to the end of the chain. +func (c *Fake) AddReactor(verb, resource string, reaction ReactionFunc) { + c.ReactionChain = append(c.ReactionChain, &SimpleReactor{verb, resource, reaction}) +} + +// PrependReactor adds a reactor to the beginning of the chain. +func (c *Fake) PrependReactor(verb, resource string, reaction ReactionFunc) { + c.ReactionChain = append([]Reactor{&SimpleReactor{verb, resource, reaction}}, c.ReactionChain...) +} + +// AddWatchReactor appends a reactor to the end of the chain. +func (c *Fake) AddWatchReactor(resource string, reaction WatchReactionFunc) { + c.Lock() + defer c.Unlock() + c.WatchReactionChain = append(c.WatchReactionChain, &SimpleWatchReactor{resource, reaction}) +} + +// PrependWatchReactor adds a reactor to the beginning of the chain. +func (c *Fake) PrependWatchReactor(resource string, reaction WatchReactionFunc) { + c.Lock() + defer c.Unlock() + c.WatchReactionChain = append([]WatchReactor{&SimpleWatchReactor{resource, reaction}}, c.WatchReactionChain...) +} + +// AddProxyReactor appends a reactor to the end of the chain. +func (c *Fake) AddProxyReactor(resource string, reaction ProxyReactionFunc) { + c.ProxyReactionChain = append(c.ProxyReactionChain, &SimpleProxyReactor{resource, reaction}) +} + +// PrependProxyReactor adds a reactor to the beginning of the chain. +func (c *Fake) PrependProxyReactor(resource string, reaction ProxyReactionFunc) { + c.ProxyReactionChain = append([]ProxyReactor{&SimpleProxyReactor{resource, reaction}}, c.ProxyReactionChain...) +} + +// Invokes records the provided Action and then invokes the ReactionFunc that +// handles the action if one exists. defaultReturnObj is expected to be of the +// same type a normal call would return. +func (c *Fake) Invokes(action Action, defaultReturnObj runtime.Object) (runtime.Object, error) { + c.Lock() + defer c.Unlock() + + actionCopy := action.DeepCopy() + c.actions = append(c.actions, action.DeepCopy()) + for _, reactor := range c.ReactionChain { + if !reactor.Handles(actionCopy) { + continue + } + + handled, ret, err := reactor.React(actionCopy) + if !handled { + continue + } + + return ret, err + } + + return defaultReturnObj, nil +} + +// InvokesWatch records the provided Action and then invokes the ReactionFunc +// that handles the action if one exists. +func (c *Fake) InvokesWatch(action Action) (watch.Interface, error) { + c.Lock() + defer c.Unlock() + + actionCopy := action.DeepCopy() + c.actions = append(c.actions, action.DeepCopy()) + for _, reactor := range c.WatchReactionChain { + if !reactor.Handles(actionCopy) { + continue + } + + handled, ret, err := reactor.React(actionCopy) + if !handled { + continue + } + + return ret, err + } + + return nil, fmt.Errorf("unhandled watch: %#v", action) +} + +// InvokesProxy records the provided Action and then invokes the ReactionFunc +// that handles the action if one exists. +func (c *Fake) InvokesProxy(action Action) restclient.ResponseWrapper { + c.Lock() + defer c.Unlock() + + actionCopy := action.DeepCopy() + c.actions = append(c.actions, action.DeepCopy()) + for _, reactor := range c.ProxyReactionChain { + if !reactor.Handles(actionCopy) { + continue + } + + handled, ret, err := reactor.React(actionCopy) + if !handled || err != nil { + continue + } + + return ret + } + + return nil +} + +// ClearActions clears the history of actions called on the fake client. +func (c *Fake) ClearActions() { + c.Lock() + defer c.Unlock() + + c.actions = make([]Action, 0) +} + +// Actions returns a chronologically ordered slice fake actions called on the +// fake client. +func (c *Fake) Actions() []Action { + c.RLock() + defer c.RUnlock() + fa := make([]Action, len(c.actions)) + copy(fa, c.actions) + return fa +} diff --git a/vendor/k8s.io/client-go/testing/fixture.go b/vendor/k8s.io/client-go/testing/fixture.go new file mode 100644 index 00000000000..396840670fd --- /dev/null +++ b/vendor/k8s.io/client-go/testing/fixture.go @@ -0,0 +1,581 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "fmt" + "reflect" + "sort" + "strings" + "sync" + + jsonpatch "github.com/evanphx/json-patch" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/json" + "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/watch" + restclient "k8s.io/client-go/rest" +) + +// ObjectTracker keeps track of objects. It is intended to be used to +// fake calls to a server by returning objects based on their kind, +// namespace and name. +type ObjectTracker interface { + // Add adds an object to the tracker. If object being added + // is a list, its items are added separately. + Add(obj runtime.Object) error + + // Get retrieves the object by its kind, namespace and name. + Get(gvr schema.GroupVersionResource, ns, name string) (runtime.Object, error) + + // Create adds an object to the tracker in the specified namespace. + Create(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error + + // Update updates an existing object in the tracker in the specified namespace. + Update(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error + + // List retrieves all objects of a given kind in the given + // namespace. Only non-List kinds are accepted. + List(gvr schema.GroupVersionResource, gvk schema.GroupVersionKind, ns string) (runtime.Object, error) + + // Delete deletes an existing object from the tracker. If object + // didn't exist in the tracker prior to deletion, Delete returns + // no error. + Delete(gvr schema.GroupVersionResource, ns, name string) error + + // Watch watches objects from the tracker. Watch returns a channel + // which will push added / modified / deleted object. + Watch(gvr schema.GroupVersionResource, ns string) (watch.Interface, error) +} + +// ObjectScheme abstracts the implementation of common operations on objects. +type ObjectScheme interface { + runtime.ObjectCreater + runtime.ObjectTyper +} + +// ObjectReaction returns a ReactionFunc that applies core.Action to +// the given tracker. +func ObjectReaction(tracker ObjectTracker) ReactionFunc { + return func(action Action) (bool, runtime.Object, error) { + ns := action.GetNamespace() + gvr := action.GetResource() + // Here and below we need to switch on implementation types, + // not on interfaces, as some interfaces are identical + // (e.g. UpdateAction and CreateAction), so if we use them, + // updates and creates end up matching the same case branch. + switch action := action.(type) { + + case ListActionImpl: + obj, err := tracker.List(gvr, action.GetKind(), ns) + return true, obj, err + + case GetActionImpl: + obj, err := tracker.Get(gvr, ns, action.GetName()) + return true, obj, err + + case CreateActionImpl: + objMeta, err := meta.Accessor(action.GetObject()) + if err != nil { + return true, nil, err + } + if action.GetSubresource() == "" { + err = tracker.Create(gvr, action.GetObject(), ns) + } else { + oldObj, getOldObjErr := tracker.Get(gvr, ns, objMeta.GetName()) + if getOldObjErr != nil { + return true, nil, getOldObjErr + } + // Check whether the existing historical object type is the same as the current operation object type that needs to be updated, and if it is the same, perform the update operation. + if reflect.TypeOf(oldObj) == reflect.TypeOf(action.GetObject()) { + // TODO: Currently we're handling subresource creation as an update + // on the enclosing resource. This works for some subresources but + // might not be generic enough. + err = tracker.Update(gvr, action.GetObject(), ns) + } else { + // If the historical object type is different from the current object type, need to make sure we return the object submitted,don't persist the submitted object in the tracker. + return true, action.GetObject(), nil + } + } + if err != nil { + return true, nil, err + } + obj, err := tracker.Get(gvr, ns, objMeta.GetName()) + return true, obj, err + + case UpdateActionImpl: + objMeta, err := meta.Accessor(action.GetObject()) + if err != nil { + return true, nil, err + } + err = tracker.Update(gvr, action.GetObject(), ns) + if err != nil { + return true, nil, err + } + obj, err := tracker.Get(gvr, ns, objMeta.GetName()) + return true, obj, err + + case DeleteActionImpl: + err := tracker.Delete(gvr, ns, action.GetName()) + if err != nil { + return true, nil, err + } + return true, nil, nil + + case PatchActionImpl: + obj, err := tracker.Get(gvr, ns, action.GetName()) + if err != nil { + return true, nil, err + } + + old, err := json.Marshal(obj) + if err != nil { + return true, nil, err + } + + // reset the object in preparation to unmarshal, since unmarshal does not guarantee that fields + // in obj that are removed by patch are cleared + value := reflect.ValueOf(obj) + value.Elem().Set(reflect.New(value.Type().Elem()).Elem()) + + switch action.GetPatchType() { + case types.JSONPatchType: + patch, err := jsonpatch.DecodePatch(action.GetPatch()) + if err != nil { + return true, nil, err + } + modified, err := patch.Apply(old) + if err != nil { + return true, nil, err + } + + if err = json.Unmarshal(modified, obj); err != nil { + return true, nil, err + } + case types.MergePatchType: + modified, err := jsonpatch.MergePatch(old, action.GetPatch()) + if err != nil { + return true, nil, err + } + + if err := json.Unmarshal(modified, obj); err != nil { + return true, nil, err + } + case types.StrategicMergePatchType, types.ApplyPatchType: + mergedByte, err := strategicpatch.StrategicMergePatch(old, action.GetPatch(), obj) + if err != nil { + return true, nil, err + } + if err = json.Unmarshal(mergedByte, obj); err != nil { + return true, nil, err + } + default: + return true, nil, fmt.Errorf("PatchType is not supported") + } + + if err = tracker.Update(gvr, obj, ns); err != nil { + return true, nil, err + } + + return true, obj, nil + + default: + return false, nil, fmt.Errorf("no reaction implemented for %s", action) + } + } +} + +type tracker struct { + scheme ObjectScheme + decoder runtime.Decoder + lock sync.RWMutex + objects map[schema.GroupVersionResource]map[types.NamespacedName]runtime.Object + // The value type of watchers is a map of which the key is either a namespace or + // all/non namespace aka "" and its value is list of fake watchers. + // Manipulations on resources will broadcast the notification events into the + // watchers' channel. Note that too many unhandled events (currently 100, + // see apimachinery/pkg/watch.DefaultChanSize) will cause a panic. + watchers map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher +} + +var _ ObjectTracker = &tracker{} + +// NewObjectTracker returns an ObjectTracker that can be used to keep track +// of objects for the fake clientset. Mostly useful for unit tests. +func NewObjectTracker(scheme ObjectScheme, decoder runtime.Decoder) ObjectTracker { + return &tracker{ + scheme: scheme, + decoder: decoder, + objects: make(map[schema.GroupVersionResource]map[types.NamespacedName]runtime.Object), + watchers: make(map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher), + } +} + +func (t *tracker) List(gvr schema.GroupVersionResource, gvk schema.GroupVersionKind, ns string) (runtime.Object, error) { + // Heuristic for list kind: original kind + List suffix. Might + // not always be true but this tracker has a pretty limited + // understanding of the actual API model. + listGVK := gvk + listGVK.Kind = listGVK.Kind + "List" + // GVK does have the concept of "internal version". The scheme recognizes + // the runtime.APIVersionInternal, but not the empty string. + if listGVK.Version == "" { + listGVK.Version = runtime.APIVersionInternal + } + + list, err := t.scheme.New(listGVK) + if err != nil { + return nil, err + } + + if !meta.IsListType(list) { + return nil, fmt.Errorf("%q is not a list type", listGVK.Kind) + } + + t.lock.RLock() + defer t.lock.RUnlock() + + objs, ok := t.objects[gvr] + if !ok { + return list, nil + } + + matchingObjs, err := filterByNamespace(objs, ns) + if err != nil { + return nil, err + } + if err := meta.SetList(list, matchingObjs); err != nil { + return nil, err + } + return list.DeepCopyObject(), nil +} + +func (t *tracker) Watch(gvr schema.GroupVersionResource, ns string) (watch.Interface, error) { + t.lock.Lock() + defer t.lock.Unlock() + + fakewatcher := watch.NewRaceFreeFake() + + if _, exists := t.watchers[gvr]; !exists { + t.watchers[gvr] = make(map[string][]*watch.RaceFreeFakeWatcher) + } + t.watchers[gvr][ns] = append(t.watchers[gvr][ns], fakewatcher) + return fakewatcher, nil +} + +func (t *tracker) Get(gvr schema.GroupVersionResource, ns, name string) (runtime.Object, error) { + errNotFound := errors.NewNotFound(gvr.GroupResource(), name) + + t.lock.RLock() + defer t.lock.RUnlock() + + objs, ok := t.objects[gvr] + if !ok { + return nil, errNotFound + } + + matchingObj, ok := objs[types.NamespacedName{Namespace: ns, Name: name}] + if !ok { + return nil, errNotFound + } + + // Only one object should match in the tracker if it works + // correctly, as Add/Update methods enforce kind/namespace/name + // uniqueness. + obj := matchingObj.DeepCopyObject() + if status, ok := obj.(*metav1.Status); ok { + if status.Status != metav1.StatusSuccess { + return nil, &errors.StatusError{ErrStatus: *status} + } + } + + return obj, nil +} + +func (t *tracker) Add(obj runtime.Object) error { + if meta.IsListType(obj) { + return t.addList(obj, false) + } + objMeta, err := meta.Accessor(obj) + if err != nil { + return err + } + gvks, _, err := t.scheme.ObjectKinds(obj) + if err != nil { + return err + } + + if partial, ok := obj.(*metav1.PartialObjectMetadata); ok && len(partial.TypeMeta.APIVersion) > 0 { + gvks = []schema.GroupVersionKind{partial.TypeMeta.GroupVersionKind()} + } + + if len(gvks) == 0 { + return fmt.Errorf("no registered kinds for %v", obj) + } + for _, gvk := range gvks { + // NOTE: UnsafeGuessKindToResource is a heuristic and default match. The + // actual registration in apiserver can specify arbitrary route for a + // gvk. If a test uses such objects, it cannot preset the tracker with + // objects via Add(). Instead, it should trigger the Create() function + // of the tracker, where an arbitrary gvr can be specified. + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + // Resource doesn't have the concept of "__internal" version, just set it to "". + if gvr.Version == runtime.APIVersionInternal { + gvr.Version = "" + } + + err := t.add(gvr, obj, objMeta.GetNamespace(), false) + if err != nil { + return err + } + } + return nil +} + +func (t *tracker) Create(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + return t.add(gvr, obj, ns, false) +} + +func (t *tracker) Update(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + return t.add(gvr, obj, ns, true) +} + +func (t *tracker) getWatches(gvr schema.GroupVersionResource, ns string) []*watch.RaceFreeFakeWatcher { + watches := []*watch.RaceFreeFakeWatcher{} + if t.watchers[gvr] != nil { + if w := t.watchers[gvr][ns]; w != nil { + watches = append(watches, w...) + } + if ns != metav1.NamespaceAll { + if w := t.watchers[gvr][metav1.NamespaceAll]; w != nil { + watches = append(watches, w...) + } + } + } + return watches +} + +func (t *tracker) add(gvr schema.GroupVersionResource, obj runtime.Object, ns string, replaceExisting bool) error { + t.lock.Lock() + defer t.lock.Unlock() + + gr := gvr.GroupResource() + + // To avoid the object from being accidentally modified by caller + // after it's been added to the tracker, we always store the deep + // copy. + obj = obj.DeepCopyObject() + + newMeta, err := meta.Accessor(obj) + if err != nil { + return err + } + + // Propagate namespace to the new object if hasn't already been set. + if len(newMeta.GetNamespace()) == 0 { + newMeta.SetNamespace(ns) + } + + if ns != newMeta.GetNamespace() { + msg := fmt.Sprintf("request namespace does not match object namespace, request: %q object: %q", ns, newMeta.GetNamespace()) + return errors.NewBadRequest(msg) + } + + _, ok := t.objects[gvr] + if !ok { + t.objects[gvr] = make(map[types.NamespacedName]runtime.Object) + } + + namespacedName := types.NamespacedName{Namespace: newMeta.GetNamespace(), Name: newMeta.GetName()} + if _, ok = t.objects[gvr][namespacedName]; ok { + if replaceExisting { + for _, w := range t.getWatches(gvr, ns) { + // To avoid the object from being accidentally modified by watcher + w.Modify(obj.DeepCopyObject()) + } + t.objects[gvr][namespacedName] = obj + return nil + } + return errors.NewAlreadyExists(gr, newMeta.GetName()) + } + + if replaceExisting { + // Tried to update but no matching object was found. + return errors.NewNotFound(gr, newMeta.GetName()) + } + + t.objects[gvr][namespacedName] = obj + + for _, w := range t.getWatches(gvr, ns) { + // To avoid the object from being accidentally modified by watcher + w.Add(obj.DeepCopyObject()) + } + + return nil +} + +func (t *tracker) addList(obj runtime.Object, replaceExisting bool) error { + list, err := meta.ExtractList(obj) + if err != nil { + return err + } + errs := runtime.DecodeList(list, t.decoder) + if len(errs) > 0 { + return errs[0] + } + for _, obj := range list { + if err := t.Add(obj); err != nil { + return err + } + } + return nil +} + +func (t *tracker) Delete(gvr schema.GroupVersionResource, ns, name string) error { + t.lock.Lock() + defer t.lock.Unlock() + + objs, ok := t.objects[gvr] + if !ok { + return errors.NewNotFound(gvr.GroupResource(), name) + } + + namespacedName := types.NamespacedName{Namespace: ns, Name: name} + obj, ok := objs[namespacedName] + if !ok { + return errors.NewNotFound(gvr.GroupResource(), name) + } + + delete(objs, namespacedName) + for _, w := range t.getWatches(gvr, ns) { + w.Delete(obj.DeepCopyObject()) + } + return nil +} + +// filterByNamespace returns all objects in the collection that +// match provided namespace. Empty namespace matches +// non-namespaced objects. +func filterByNamespace(objs map[types.NamespacedName]runtime.Object, ns string) ([]runtime.Object, error) { + var res []runtime.Object + + for _, obj := range objs { + acc, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + if ns != "" && acc.GetNamespace() != ns { + continue + } + res = append(res, obj) + } + + // Sort res to get deterministic order. + sort.Slice(res, func(i, j int) bool { + acc1, _ := meta.Accessor(res[i]) + acc2, _ := meta.Accessor(res[j]) + if acc1.GetNamespace() != acc2.GetNamespace() { + return acc1.GetNamespace() < acc2.GetNamespace() + } + return acc1.GetName() < acc2.GetName() + }) + return res, nil +} + +func DefaultWatchReactor(watchInterface watch.Interface, err error) WatchReactionFunc { + return func(action Action) (bool, watch.Interface, error) { + return true, watchInterface, err + } +} + +// SimpleReactor is a Reactor. Each reaction function is attached to a given verb,resource tuple. "*" in either field matches everything for that value. +// For instance, *,pods matches all verbs on pods. This allows for easier composition of reaction functions +type SimpleReactor struct { + Verb string + Resource string + + Reaction ReactionFunc +} + +func (r *SimpleReactor) Handles(action Action) bool { + verbCovers := r.Verb == "*" || r.Verb == action.GetVerb() + if !verbCovers { + return false + } + + return resourceCovers(r.Resource, action) +} + +func (r *SimpleReactor) React(action Action) (bool, runtime.Object, error) { + return r.Reaction(action) +} + +// SimpleWatchReactor is a WatchReactor. Each reaction function is attached to a given resource. "*" matches everything for that value. +// For instance, *,pods matches all verbs on pods. This allows for easier composition of reaction functions +type SimpleWatchReactor struct { + Resource string + + Reaction WatchReactionFunc +} + +func (r *SimpleWatchReactor) Handles(action Action) bool { + return resourceCovers(r.Resource, action) +} + +func (r *SimpleWatchReactor) React(action Action) (bool, watch.Interface, error) { + return r.Reaction(action) +} + +// SimpleProxyReactor is a ProxyReactor. Each reaction function is attached to a given resource. "*" matches everything for that value. +// For instance, *,pods matches all verbs on pods. This allows for easier composition of reaction functions. +type SimpleProxyReactor struct { + Resource string + + Reaction ProxyReactionFunc +} + +func (r *SimpleProxyReactor) Handles(action Action) bool { + return resourceCovers(r.Resource, action) +} + +func (r *SimpleProxyReactor) React(action Action) (bool, restclient.ResponseWrapper, error) { + return r.Reaction(action) +} + +func resourceCovers(resource string, action Action) bool { + if resource == "*" { + return true + } + + if resource == action.GetResource().Resource { + return true + } + + if index := strings.Index(resource, "/"); index != -1 && + resource[:index] == action.GetResource().Resource && + resource[index+1:] == action.GetSubresource() { + return true + } + + return false +} diff --git a/vendor/k8s.io/client-go/testing/interface.go b/vendor/k8s.io/client-go/testing/interface.go new file mode 100644 index 00000000000..266c6ba3f54 --- /dev/null +++ b/vendor/k8s.io/client-go/testing/interface.go @@ -0,0 +1,66 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + restclient "k8s.io/client-go/rest" +) + +type FakeClient interface { + // Tracker gives access to the ObjectTracker internal to the fake client. + Tracker() ObjectTracker + + // AddReactor appends a reactor to the end of the chain. + AddReactor(verb, resource string, reaction ReactionFunc) + + // PrependReactor adds a reactor to the beginning of the chain. + PrependReactor(verb, resource string, reaction ReactionFunc) + + // AddWatchReactor appends a reactor to the end of the chain. + AddWatchReactor(resource string, reaction WatchReactionFunc) + + // PrependWatchReactor adds a reactor to the beginning of the chain. + PrependWatchReactor(resource string, reaction WatchReactionFunc) + + // AddProxyReactor appends a reactor to the end of the chain. + AddProxyReactor(resource string, reaction ProxyReactionFunc) + + // PrependProxyReactor adds a reactor to the beginning of the chain. + PrependProxyReactor(resource string, reaction ProxyReactionFunc) + + // Invokes records the provided Action and then invokes the ReactionFunc that + // handles the action if one exists. defaultReturnObj is expected to be of the + // same type a normal call would return. + Invokes(action Action, defaultReturnObj runtime.Object) (runtime.Object, error) + + // InvokesWatch records the provided Action and then invokes the ReactionFunc + // that handles the action if one exists. + InvokesWatch(action Action) (watch.Interface, error) + + // InvokesProxy records the provided Action and then invokes the ReactionFunc + // that handles the action if one exists. + InvokesProxy(action Action) restclient.ResponseWrapper + + // ClearActions clears the history of actions called on the fake client. + ClearActions() + + // Actions returns a chronologically ordered slice fake actions called on the + // fake client. + Actions() []Action +} diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go b/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go deleted file mode 100644 index 739fd3509ce..00000000000 --- a/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go +++ /dev/null @@ -1,94 +0,0 @@ -//This package is copied from Go library text/template. -//The original private functions indirect and printableValue -//are exported as public functions. -package template - -import ( - "fmt" - "reflect" -) - -var Indirect = indirect -var PrintableValue = printableValue - -var ( - errorType = reflect.TypeOf((*error)(nil)).Elem() - fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() -) - -// indirect returns the item at the end of indirection, and a bool to indicate if it's nil. -// We indirect through pointers and empty interfaces (only) because -// non-empty interfaces have methods we might need. -func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { - for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { - if v.IsNil() { - return v, true - } - if v.Kind() == reflect.Interface && v.NumMethod() > 0 { - break - } - } - return v, false -} - -// printableValue returns the, possibly indirected, interface value inside v that -// is best for a call to formatted printer. -func printableValue(v reflect.Value) (interface{}, bool) { - if v.Kind() == reflect.Ptr { - v, _ = indirect(v) // fmt.Fprint handles nil. - } - if !v.IsValid() { - return "", true - } - - if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { - if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) { - v = v.Addr() - } else { - switch v.Kind() { - case reflect.Chan, reflect.Func: - return nil, false - } - } - } - return v.Interface(), true -} - -// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero. -func canBeNil(typ reflect.Type) bool { - switch typ.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return true - } - return false -} - -// isTrue reports whether the value is 'true', in the sense of not the zero of its type, -// and whether the value has a meaningful truth value. -func isTrue(val reflect.Value) (truth, ok bool) { - if !val.IsValid() { - // Something like var x interface{}, never set. It's a form of nil. - return false, true - } - switch val.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - truth = val.Len() > 0 - case reflect.Bool: - truth = val.Bool() - case reflect.Complex64, reflect.Complex128: - truth = val.Complex() != 0 - case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: - truth = !val.IsNil() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - truth = val.Int() != 0 - case reflect.Float32, reflect.Float64: - truth = val.Float() != 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - truth = val.Uint() != 0 - case reflect.Struct: - truth = true // Struct values are always true. - default: - return - } - return truth, true -} diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go b/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go deleted file mode 100644 index 27a008b0a7e..00000000000 --- a/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go +++ /dev/null @@ -1,599 +0,0 @@ -//This package is copied from Go library text/template. -//The original private functions eq, ge, gt, le, lt, and ne -//are exported as public functions. -package template - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/url" - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -var Equal = eq -var GreaterEqual = ge -var Greater = gt -var LessEqual = le -var Less = lt -var NotEqual = ne - -// FuncMap is the type of the map defining the mapping from names to functions. -// Each function must have either a single return value, or two return values of -// which the second has type error. In that case, if the second (error) -// return value evaluates to non-nil during execution, execution terminates and -// Execute returns that error. -type FuncMap map[string]interface{} - -var builtins = FuncMap{ - "and": and, - "call": call, - "html": HTMLEscaper, - "index": index, - "js": JSEscaper, - "len": length, - "not": not, - "or": or, - "print": fmt.Sprint, - "printf": fmt.Sprintf, - "println": fmt.Sprintln, - "urlquery": URLQueryEscaper, - - // Comparisons - "eq": eq, // == - "ge": ge, // >= - "gt": gt, // > - "le": le, // <= - "lt": lt, // < - "ne": ne, // != -} - -var builtinFuncs = createValueFuncs(builtins) - -// createValueFuncs turns a FuncMap into a map[string]reflect.Value -func createValueFuncs(funcMap FuncMap) map[string]reflect.Value { - m := make(map[string]reflect.Value) - addValueFuncs(m, funcMap) - return m -} - -// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values. -func addValueFuncs(out map[string]reflect.Value, in FuncMap) { - for name, fn := range in { - v := reflect.ValueOf(fn) - if v.Kind() != reflect.Func { - panic("value for " + name + " not a function") - } - if !goodFunc(v.Type()) { - panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut())) - } - out[name] = v - } -} - -// AddFuncs adds to values the functions in funcs. It does no checking of the input - -// call addValueFuncs first. -func addFuncs(out, in FuncMap) { - for name, fn := range in { - out[name] = fn - } -} - -// goodFunc checks that the function or method has the right result signature. -func goodFunc(typ reflect.Type) bool { - // We allow functions with 1 result or 2 results where the second is an error. - switch { - case typ.NumOut() == 1: - return true - case typ.NumOut() == 2 && typ.Out(1) == errorType: - return true - } - return false -} - -// findFunction looks for a function in the template, and global map. -func findFunction(name string) (reflect.Value, bool) { - if fn := builtinFuncs[name]; fn.IsValid() { - return fn, true - } - return reflect.Value{}, false -} - -// Indexing. - -// index returns the result of indexing its first argument by the following -// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each -// indexed item must be a map, slice, or array. -func index(item interface{}, indices ...interface{}) (interface{}, error) { - v := reflect.ValueOf(item) - for _, i := range indices { - index := reflect.ValueOf(i) - var isNil bool - if v, isNil = indirect(v); isNil { - return nil, fmt.Errorf("index of nil pointer") - } - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.String: - var x int64 - switch index.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - x = index.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - x = int64(index.Uint()) - default: - return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type()) - } - if x < 0 || x >= int64(v.Len()) { - return nil, fmt.Errorf("index out of range: %d", x) - } - v = v.Index(int(x)) - case reflect.Map: - if !index.IsValid() { - index = reflect.Zero(v.Type().Key()) - } - if !index.Type().AssignableTo(v.Type().Key()) { - return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type()) - } - if x := v.MapIndex(index); x.IsValid() { - v = x - } else { - v = reflect.Zero(v.Type().Elem()) - } - default: - return nil, fmt.Errorf("can't index item of type %s", v.Type()) - } - } - return v.Interface(), nil -} - -// Length - -// length returns the length of the item, with an error if it has no defined length. -func length(item interface{}) (int, error) { - v, isNil := indirect(reflect.ValueOf(item)) - if isNil { - return 0, fmt.Errorf("len of nil pointer") - } - switch v.Kind() { - case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: - return v.Len(), nil - } - return 0, fmt.Errorf("len of type %s", v.Type()) -} - -// Function invocation - -// call returns the result of evaluating the first argument as a function. -// The function must return 1 result, or 2 results, the second of which is an error. -func call(fn interface{}, args ...interface{}) (interface{}, error) { - v := reflect.ValueOf(fn) - typ := v.Type() - if typ.Kind() != reflect.Func { - return nil, fmt.Errorf("non-function of type %s", typ) - } - if !goodFunc(typ) { - return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut()) - } - numIn := typ.NumIn() - var dddType reflect.Type - if typ.IsVariadic() { - if len(args) < numIn-1 { - return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1) - } - dddType = typ.In(numIn - 1).Elem() - } else { - if len(args) != numIn { - return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn) - } - } - argv := make([]reflect.Value, len(args)) - for i, arg := range args { - value := reflect.ValueOf(arg) - // Compute the expected type. Clumsy because of variadics. - var argType reflect.Type - if !typ.IsVariadic() || i < numIn-1 { - argType = typ.In(i) - } else { - argType = dddType - } - if !value.IsValid() && canBeNil(argType) { - value = reflect.Zero(argType) - } - if !value.Type().AssignableTo(argType) { - return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType) - } - argv[i] = value - } - result := v.Call(argv) - if len(result) == 2 && !result[1].IsNil() { - return result[0].Interface(), result[1].Interface().(error) - } - return result[0].Interface(), nil -} - -// Boolean logic. - -func truth(a interface{}) bool { - t, _ := isTrue(reflect.ValueOf(a)) - return t -} - -// and computes the Boolean AND of its arguments, returning -// the first false argument it encounters, or the last argument. -func and(arg0 interface{}, args ...interface{}) interface{} { - if !truth(arg0) { - return arg0 - } - for i := range args { - arg0 = args[i] - if !truth(arg0) { - break - } - } - return arg0 -} - -// or computes the Boolean OR of its arguments, returning -// the first true argument it encounters, or the last argument. -func or(arg0 interface{}, args ...interface{}) interface{} { - if truth(arg0) { - return arg0 - } - for i := range args { - arg0 = args[i] - if truth(arg0) { - break - } - } - return arg0 -} - -// not returns the Boolean negation of its argument. -func not(arg interface{}) (truth bool) { - truth, _ = isTrue(reflect.ValueOf(arg)) - return !truth -} - -// Comparison. - -// TODO: Perhaps allow comparison between signed and unsigned integers. - -var ( - errBadComparisonType = errors.New("invalid type for comparison") - errBadComparison = errors.New("incompatible types for comparison") - errNoComparison = errors.New("missing argument for comparison") -) - -type kind int - -const ( - invalidKind kind = iota - boolKind - complexKind - intKind - floatKind - integerKind - stringKind - uintKind -) - -func basicKind(v reflect.Value) (kind, error) { - switch v.Kind() { - case reflect.Bool: - return boolKind, nil - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return intKind, nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return uintKind, nil - case reflect.Float32, reflect.Float64: - return floatKind, nil - case reflect.Complex64, reflect.Complex128: - return complexKind, nil - case reflect.String: - return stringKind, nil - } - return invalidKind, errBadComparisonType -} - -// eq evaluates the comparison a == b || a == c || ... -func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) { - v1 := reflect.ValueOf(arg1) - k1, err := basicKind(v1) - if err != nil { - return false, err - } - if len(arg2) == 0 { - return false, errNoComparison - } - for _, arg := range arg2 { - v2 := reflect.ValueOf(arg) - k2, err := basicKind(v2) - if err != nil { - return false, err - } - truth := false - if k1 != k2 { - // Special case: Can compare integer values regardless of type's sign. - switch { - case k1 == intKind && k2 == uintKind: - truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() - case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) - default: - return false, errBadComparison - } - } else { - switch k1 { - case boolKind: - truth = v1.Bool() == v2.Bool() - case complexKind: - truth = v1.Complex() == v2.Complex() - case floatKind: - truth = v1.Float() == v2.Float() - case intKind: - truth = v1.Int() == v2.Int() - case stringKind: - truth = v1.String() == v2.String() - case uintKind: - truth = v1.Uint() == v2.Uint() - default: - panic("invalid kind") - } - } - if truth { - return true, nil - } - } - return false, nil -} - -// ne evaluates the comparison a != b. -func ne(arg1, arg2 interface{}) (bool, error) { - // != is the inverse of ==. - equal, err := eq(arg1, arg2) - return !equal, err -} - -// lt evaluates the comparison a < b. -func lt(arg1, arg2 interface{}) (bool, error) { - v1 := reflect.ValueOf(arg1) - k1, err := basicKind(v1) - if err != nil { - return false, err - } - v2 := reflect.ValueOf(arg2) - k2, err := basicKind(v2) - if err != nil { - return false, err - } - truth := false - if k1 != k2 { - // Special case: Can compare integer values regardless of type's sign. - switch { - case k1 == intKind && k2 == uintKind: - truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() - case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int()) - default: - return false, errBadComparison - } - } else { - switch k1 { - case boolKind, complexKind: - return false, errBadComparisonType - case floatKind: - truth = v1.Float() < v2.Float() - case intKind: - truth = v1.Int() < v2.Int() - case stringKind: - truth = v1.String() < v2.String() - case uintKind: - truth = v1.Uint() < v2.Uint() - default: - panic("invalid kind") - } - } - return truth, nil -} - -// le evaluates the comparison <= b. -func le(arg1, arg2 interface{}) (bool, error) { - // <= is < or ==. - lessThan, err := lt(arg1, arg2) - if lessThan || err != nil { - return lessThan, err - } - return eq(arg1, arg2) -} - -// gt evaluates the comparison a > b. -func gt(arg1, arg2 interface{}) (bool, error) { - // > is the inverse of <=. - lessOrEqual, err := le(arg1, arg2) - if err != nil { - return false, err - } - return !lessOrEqual, nil -} - -// ge evaluates the comparison a >= b. -func ge(arg1, arg2 interface{}) (bool, error) { - // >= is the inverse of <. - lessThan, err := lt(arg1, arg2) - if err != nil { - return false, err - } - return !lessThan, nil -} - -// HTML escaping. - -var ( - htmlQuot = []byte(""") // shorter than """ - htmlApos = []byte("'") // shorter than "'" and apos was not in HTML until HTML5 - htmlAmp = []byte("&") - htmlLt = []byte("<") - htmlGt = []byte(">") -) - -// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b. -func HTMLEscape(w io.Writer, b []byte) { - last := 0 - for i, c := range b { - var html []byte - switch c { - case '"': - html = htmlQuot - case '\'': - html = htmlApos - case '&': - html = htmlAmp - case '<': - html = htmlLt - case '>': - html = htmlGt - default: - continue - } - w.Write(b[last:i]) - w.Write(html) - last = i + 1 - } - w.Write(b[last:]) -} - -// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s. -func HTMLEscapeString(s string) string { - // Avoid allocation if we can. - if strings.IndexAny(s, `'"&<>`) < 0 { - return s - } - var b bytes.Buffer - HTMLEscape(&b, []byte(s)) - return b.String() -} - -// HTMLEscaper returns the escaped HTML equivalent of the textual -// representation of its arguments. -func HTMLEscaper(args ...interface{}) string { - return HTMLEscapeString(evalArgs(args)) -} - -// JavaScript escaping. - -var ( - jsLowUni = []byte(`\u00`) - hex = []byte("0123456789ABCDEF") - - jsBackslash = []byte(`\\`) - jsApos = []byte(`\'`) - jsQuot = []byte(`\"`) - jsLt = []byte(`\x3C`) - jsGt = []byte(`\x3E`) -) - -// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. -func JSEscape(w io.Writer, b []byte) { - last := 0 - for i := 0; i < len(b); i++ { - c := b[i] - - if !jsIsSpecial(rune(c)) { - // fast path: nothing to do - continue - } - w.Write(b[last:i]) - - if c < utf8.RuneSelf { - // Quotes, slashes and angle brackets get quoted. - // Control characters get written as \u00XX. - switch c { - case '\\': - w.Write(jsBackslash) - case '\'': - w.Write(jsApos) - case '"': - w.Write(jsQuot) - case '<': - w.Write(jsLt) - case '>': - w.Write(jsGt) - default: - w.Write(jsLowUni) - t, b := c>>4, c&0x0f - w.Write(hex[t : t+1]) - w.Write(hex[b : b+1]) - } - } else { - // Unicode rune. - r, size := utf8.DecodeRune(b[i:]) - if unicode.IsPrint(r) { - w.Write(b[i : i+size]) - } else { - fmt.Fprintf(w, "\\u%04X", r) - } - i += size - 1 - } - last = i + 1 - } - w.Write(b[last:]) -} - -// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s. -func JSEscapeString(s string) string { - // Avoid allocation if we can. - if strings.IndexFunc(s, jsIsSpecial) < 0 { - return s - } - var b bytes.Buffer - JSEscape(&b, []byte(s)) - return b.String() -} - -func jsIsSpecial(r rune) bool { - switch r { - case '\\', '\'', '"', '<', '>': - return true - } - return r < ' ' || utf8.RuneSelf <= r -} - -// JSEscaper returns the escaped JavaScript equivalent of the textual -// representation of its arguments. -func JSEscaper(args ...interface{}) string { - return JSEscapeString(evalArgs(args)) -} - -// URLQueryEscaper returns the escaped value of the textual representation of -// its arguments in a form suitable for embedding in a URL query. -func URLQueryEscaper(args ...interface{}) string { - return url.QueryEscape(evalArgs(args)) -} - -// evalArgs formats the list of arguments into a string. It is therefore equivalent to -// fmt.Sprint(args...) -// except that each argument is indirected (if a pointer), as required, -// using the same rules as the default string evaluation during template -// execution. -func evalArgs(args []interface{}) string { - ok := false - var s string - // Fast path for simple common case. - if len(args) == 1 { - s, ok = args[0].(string) - } - if !ok { - for i, arg := range args { - a, ok := printableValue(reflect.ValueOf(arg)) - if ok { - args[i] = a - } // else left fmt do its thing - } - s = fmt.Sprint(args...) - } - return s -} diff --git a/vendor/k8s.io/client-go/tools/auth/clientauth.go b/vendor/k8s.io/client-go/tools/auth/clientauth.go index 4c24f79977f..5a256c1c3e7 100644 --- a/vendor/k8s.io/client-go/tools/auth/clientauth.go +++ b/vendor/k8s.io/client-go/tools/auth/clientauth.go @@ -32,7 +32,7 @@ Having a defined format allows: The file format is json, marshalled from a struct authcfg.Info. -Clinet libraries in other languages should use the same format. +Client libraries in other languages should use the same format. It is not intended to store general preferences, such as default namespace, output options, etc. CLIs (such as kubectl) and UIs should @@ -45,27 +45,26 @@ client.Client from an authcfg.Info. Example: - import ( - "pkg/client" - "pkg/client/auth" - ) - - info, err := auth.LoadFromFile(filename) - if err != nil { - // handle error - } - clientConfig = client.Config{} - clientConfig.Host = "example.com:4901" - clientConfig = info.MergeWithConfig() - client := client.New(clientConfig) - client.Pods(ns).List() + import ( + "pkg/client" + "pkg/client/auth" + ) + + info, err := auth.LoadFromFile(filename) + if err != nil { + // handle error + } + clientConfig = client.Config{} + clientConfig.Host = "example.com:4901" + clientConfig = info.MergeWithConfig() + client := client.New(clientConfig) + client.Pods(ns).List() */ package auth // TODO: need a way to rotate Tokens. Therefore, need a way for client object to be reset when the authcfg is updated. import ( "encoding/json" - "io/ioutil" "os" restclient "k8s.io/client-go/rest" @@ -90,7 +89,7 @@ func LoadFromFile(path string) (*Info, error) { if _, err := os.Stat(path); os.IsNotExist(err) { return nil, err } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/vendor/k8s.io/client-go/tools/cache/controller.go b/vendor/k8s.io/client-go/tools/cache/controller.go index ff4c22de00b..f437f286166 100644 --- a/vendor/k8s.io/client-go/tools/cache/controller.go +++ b/vendor/k8s.io/client-go/tools/cache/controller.go @@ -18,6 +18,7 @@ package cache import ( "errors" + "os" "sync" "time" @@ -50,11 +51,12 @@ type Config struct { Process ProcessFunc // ObjectType is an example object of the type this controller is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // expected to handle. ObjectType runtime.Object + // ObjectDescription is the description to use when logging type-specific information about this controller. + ObjectDescription string + // FullResyncPeriod is the period at which ShouldResync is considered. FullResyncPeriod time.Duration @@ -84,7 +86,7 @@ type Config struct { type ShouldResyncFunc func() bool // ProcessFunc processes a single object. -type ProcessFunc func(obj interface{}) error +type ProcessFunc func(obj interface{}, isInInitialList bool) error // `*controller` implements Controller type controller struct { @@ -131,18 +133,24 @@ func (c *controller) Run(stopCh <-chan struct{}) { <-stopCh c.config.Queue.Close() }() - r := NewReflector( + r := NewReflectorWithOptions( c.config.ListerWatcher, c.config.ObjectType, c.config.Queue, - c.config.FullResyncPeriod, + ReflectorOptions{ + ResyncPeriod: c.config.FullResyncPeriod, + TypeDescription: c.config.ObjectDescription, + Clock: c.clock, + }, ) r.ShouldResync = c.config.ShouldResync r.WatchListPageSize = c.config.WatchListPageSize - r.clock = c.clock if c.config.WatchErrorHandler != nil { r.watchErrorHandler = c.config.WatchErrorHandler } + if s := os.Getenv("ENABLE_CLIENT_GO_WATCH_LIST_ALPHA"); len(s) > 0 { + r.UseWatchList = true + } c.reflectorMutex.Lock() c.reflector = r @@ -199,19 +207,19 @@ func (c *controller) processLoop() { // can't return an error. The handlers MUST NOT modify the objects // received; this concerns not only the top level of structure but all // the data structures reachable from it. -// * OnAdd is called when an object is added. -// * OnUpdate is called when an object is modified. Note that oldObj is the -// last known state of the object-- it is possible that several changes -// were combined together, so you can't use this to see every single -// change. OnUpdate is also called when a re-list happens, and it will -// get called even if nothing changed. This is useful for periodically -// evaluating or syncing something. -// * OnDelete will get the final state of the item if it is known, otherwise -// it will get an object of type DeletedFinalStateUnknown. This can -// happen if the watch is closed and misses the delete event and we don't -// notice the deletion until the subsequent re-list. +// - OnAdd is called when an object is added. +// - OnUpdate is called when an object is modified. Note that oldObj is the +// last known state of the object-- it is possible that several changes +// were combined together, so you can't use this to see every single +// change. OnUpdate is also called when a re-list happens, and it will +// get called even if nothing changed. This is useful for periodically +// evaluating or syncing something. +// - OnDelete will get the final state of the item if it is known, otherwise +// it will get an object of type DeletedFinalStateUnknown. This can +// happen if the watch is closed and misses the delete event and we don't +// notice the deletion until the subsequent re-list. type ResourceEventHandler interface { - OnAdd(obj interface{}) + OnAdd(obj interface{}, isInInitialList bool) OnUpdate(oldObj, newObj interface{}) OnDelete(obj interface{}) } @@ -220,6 +228,9 @@ type ResourceEventHandler interface { // as few of the notification functions as you want while still implementing // ResourceEventHandler. This adapter does not remove the prohibition against // modifying the objects. +// +// See ResourceEventHandlerDetailedFuncs if your use needs to propagate +// HasSynced. type ResourceEventHandlerFuncs struct { AddFunc func(obj interface{}) UpdateFunc func(oldObj, newObj interface{}) @@ -227,7 +238,7 @@ type ResourceEventHandlerFuncs struct { } // OnAdd calls AddFunc if it's not nil. -func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}) { +func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}, isInInitialList bool) { if r.AddFunc != nil { r.AddFunc(obj) } @@ -247,6 +258,36 @@ func (r ResourceEventHandlerFuncs) OnDelete(obj interface{}) { } } +// ResourceEventHandlerDetailedFuncs is exactly like ResourceEventHandlerFuncs +// except its AddFunc accepts the isInInitialList parameter, for propagating +// HasSynced. +type ResourceEventHandlerDetailedFuncs struct { + AddFunc func(obj interface{}, isInInitialList bool) + UpdateFunc func(oldObj, newObj interface{}) + DeleteFunc func(obj interface{}) +} + +// OnAdd calls AddFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnAdd(obj interface{}, isInInitialList bool) { + if r.AddFunc != nil { + r.AddFunc(obj, isInInitialList) + } +} + +// OnUpdate calls UpdateFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnUpdate(oldObj, newObj interface{}) { + if r.UpdateFunc != nil { + r.UpdateFunc(oldObj, newObj) + } +} + +// OnDelete calls DeleteFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnDelete(obj interface{}) { + if r.DeleteFunc != nil { + r.DeleteFunc(obj) + } +} + // FilteringResourceEventHandler applies the provided filter to all events coming // in, ensuring the appropriate nested handler method is invoked. An object // that starts passing the filter after an update is considered an add, and an @@ -258,11 +299,11 @@ type FilteringResourceEventHandler struct { } // OnAdd calls the nested handler only if the filter succeeds -func (r FilteringResourceEventHandler) OnAdd(obj interface{}) { +func (r FilteringResourceEventHandler) OnAdd(obj interface{}, isInInitialList bool) { if !r.FilterFunc(obj) { return } - r.Handler.OnAdd(obj) + r.Handler.OnAdd(obj, isInInitialList) } // OnUpdate ensures the proper handler is called depending on whether the filter matches @@ -273,7 +314,7 @@ func (r FilteringResourceEventHandler) OnUpdate(oldObj, newObj interface{}) { case newer && older: r.Handler.OnUpdate(oldObj, newObj) case newer && !older: - r.Handler.OnAdd(newObj) + r.Handler.OnAdd(newObj, false) case !newer && older: r.Handler.OnDelete(oldObj) default: @@ -305,15 +346,14 @@ func DeletionHandlingMetaNamespaceKeyFunc(obj interface{}) (string, error) { // notifications to be faulty. // // Parameters: -// * lw is list and watch functions for the source of the resource you want to -// be informed of. -// * objType is an object of the type that you expect to receive. -// * resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate -// calls, even if nothing changed). Otherwise, re-list will be delayed as -// long as possible (until the upstream source closes the watch or times out, -// or you stop the controller). -// * h is the object you want notifications sent to. -// +// - lw is list and watch functions for the source of the resource you want to +// be informed of. +// - objType is an object of the type that you expect to receive. +// - resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate +// calls, even if nothing changed). Otherwise, re-list will be delayed as +// long as possible (until the upstream source closes the watch or times out, +// or you stop the controller). +// - h is the object you want notifications sent to. func NewInformer( lw ListerWatcher, objType runtime.Object, @@ -332,16 +372,15 @@ func NewInformer( // notifications to be faulty. // // Parameters: -// * lw is list and watch functions for the source of the resource you want to -// be informed of. -// * objType is an object of the type that you expect to receive. -// * resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate -// calls, even if nothing changed). Otherwise, re-list will be delayed as -// long as possible (until the upstream source closes the watch or times out, -// or you stop the controller). -// * h is the object you want notifications sent to. -// * indexers is the indexer for the received object type. -// +// - lw is list and watch functions for the source of the resource you want to +// be informed of. +// - objType is an object of the type that you expect to receive. +// - resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate +// calls, even if nothing changed). Otherwise, re-list will be delayed as +// long as possible (until the upstream source closes the watch or times out, +// or you stop the controller). +// - h is the object you want notifications sent to. +// - indexers is the indexer for the received object type. func NewIndexerInformer( lw ListerWatcher, objType runtime.Object, @@ -355,17 +394,6 @@ func NewIndexerInformer( return clientState, newInformer(lw, objType, resyncPeriod, h, clientState, nil) } -// TransformFunc allows for transforming an object before it will be processed -// and put into the controller cache and before the corresponding handlers will -// be called on it. -// TransformFunc (similarly to ResourceEventHandler functions) should be able -// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown -// -// The most common usage pattern is to clean-up some parts of the object to -// reduce component memory usage if a given component doesn't care about them. -// given controller doesn't care for them -type TransformFunc func(interface{}) (interface{}, error) - // NewTransformingInformer returns a Store and a controller for populating // the store while also providing event notifications. You should only used // the returned Store for Get/List operations; Add/Modify/Deletes will cause @@ -413,19 +441,12 @@ func processDeltas( // Object which receives event notifications from the given deltas handler ResourceEventHandler, clientState Store, - transformer TransformFunc, deltas Deltas, + isInInitialList bool, ) error { // from oldest to newest for _, d := range deltas { obj := d.Object - if transformer != nil { - var err error - obj, err = transformer(obj) - if err != nil { - return err - } - } switch d.Type { case Sync, Replaced, Added, Updated: @@ -438,7 +459,7 @@ func processDeltas( if err := clientState.Add(obj); err != nil { return err } - handler.OnAdd(obj) + handler.OnAdd(obj, isInInitialList) } case Deleted: if err := clientState.Delete(obj); err != nil { @@ -454,16 +475,15 @@ func processDeltas( // providing event notifications. // // Parameters -// * lw is list and watch functions for the source of the resource you want to -// be informed of. -// * objType is an object of the type that you expect to receive. -// * resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate -// calls, even if nothing changed). Otherwise, re-list will be delayed as -// long as possible (until the upstream source closes the watch or times out, -// or you stop the controller). -// * h is the object you want notifications sent to. -// * clientState is the store you want to populate -// +// - lw is list and watch functions for the source of the resource you want to +// be informed of. +// - objType is an object of the type that you expect to receive. +// - resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate +// calls, even if nothing changed). Otherwise, re-list will be delayed as +// long as possible (until the upstream source closes the watch or times out, +// or you stop the controller). +// - h is the object you want notifications sent to. +// - clientState is the store you want to populate func newInformer( lw ListerWatcher, objType runtime.Object, @@ -478,6 +498,7 @@ func newInformer( fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: clientState, EmitDeltaTypeReplaced: true, + Transformer: transformer, }) cfg := &Config{ @@ -487,9 +508,9 @@ func newInformer( FullResyncPeriod: resyncPeriod, RetryOnError: false, - Process: func(obj interface{}) error { + Process: func(obj interface{}, isInInitialList bool) error { if deltas, ok := obj.(Deltas); ok { - return processDeltas(h, clientState, transformer, deltas) + return processDeltas(h, clientState, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") }, diff --git a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go index 2da2933ab74..7160bb1ee72 100644 --- a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go @@ -51,6 +51,10 @@ type DeltaFIFOOptions struct { // When true, `Replaced` events will be sent for items passed to a Replace() call. // When false, `Sync` events will be sent instead. EmitDeltaTypeReplaced bool + + // If set, will be called for objects before enqueueing them. Please + // see the comment on TransformFunc for details. + Transformer TransformFunc } // DeltaFIFO is like FIFO, but differs in two ways. One is that the @@ -74,11 +78,11 @@ type DeltaFIFOOptions struct { // the Pop() method. // // DeltaFIFO solves this use case: -// * You want to process every object change (delta) at most once. -// * When you process an object, you want to see everything -// that's happened to it since you last processed it. -// * You want to process the deletion of some of the objects. -// * You might want to periodically reprocess objects. +// - You want to process every object change (delta) at most once. +// - When you process an object, you want to see everything +// that's happened to it since you last processed it. +// - You want to process the deletion of some of the objects. +// - You might want to periodically reprocess objects. // // DeltaFIFO's Pop(), Get(), and GetByKey() methods return // interface{} to satisfy the Store/Queue interfaces, but they @@ -129,8 +133,32 @@ type DeltaFIFO struct { // emitDeltaTypeReplaced is whether to emit the Replaced or Sync // DeltaType when Replace() is called (to preserve backwards compat). emitDeltaTypeReplaced bool + + // Called with every object if non-nil. + transformer TransformFunc } +// TransformFunc allows for transforming an object before it will be processed. +// TransformFunc (similarly to ResourceEventHandler functions) should be able +// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown. +// +// New in v1.27: In such cases, the contained object will already have gone +// through the transform object separately (when it was added / updated prior +// to the delete), so the TransformFunc can likely safely ignore such objects +// (i.e., just return the input object). +// +// The most common usage pattern is to clean-up some parts of the object to +// reduce component memory usage if a given component doesn't care about them. +// +// New in v1.27: unless the object is a DeletedFinalStateUnknown, TransformFunc +// sees the object before any other actor, and it is now safe to mutate the +// object in place instead of making a copy. +// +// Note that TransformFunc is called while inserting objects into the +// notification queue and is therefore extremely performance sensitive; please +// do not do anything that will take a long time. +type TransformFunc func(interface{}) (interface{}, error) + // DeltaType is the type of a change (addition, deletion, etc) type DeltaType string @@ -179,21 +207,21 @@ type Deltas []Delta // "known" keys when Pop() is called. Have to think about how that // affects error retrying. // -// NOTE: It is possible to misuse this and cause a race when using an -// external known object source. -// Whether there is a potential race depends on how the consumer -// modifies knownObjects. In Pop(), process function is called under -// lock, so it is safe to update data structures in it that need to be -// in sync with the queue (e.g. knownObjects). +// NOTE: It is possible to misuse this and cause a race when using an +// external known object source. +// Whether there is a potential race depends on how the consumer +// modifies knownObjects. In Pop(), process function is called under +// lock, so it is safe to update data structures in it that need to be +// in sync with the queue (e.g. knownObjects). // -// Example: -// In case of sharedIndexInformer being a consumer -// (https://github.com/kubernetes/kubernetes/blob/0cdd940f/staging/src/k8s.io/client-go/tools/cache/shared_informer.go#L192), -// there is no race as knownObjects (s.indexer) is modified safely -// under DeltaFIFO's lock. The only exceptions are GetStore() and -// GetIndexer() methods, which expose ways to modify the underlying -// storage. Currently these two methods are used for creating Lister -// and internal tests. +// Example: +// In case of sharedIndexInformer being a consumer +// (https://github.com/kubernetes/kubernetes/blob/0cdd940f/staging/src/k8s.io/client-go/tools/cache/shared_informer.go#L192), +// there is no race as knownObjects (s.indexer) is modified safely +// under DeltaFIFO's lock. The only exceptions are GetStore() and +// GetIndexer() methods, which expose ways to modify the underlying +// storage. Currently these two methods are used for creating Lister +// and internal tests. // // Also see the comment on DeltaFIFO. // @@ -227,6 +255,7 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { knownObjects: opts.KnownObjects, emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, + transformer: opts.Transformer, } f.cond.L = &f.lock return f @@ -271,6 +300,10 @@ func (f *DeltaFIFO) KeyOf(obj interface{}) (string, error) { func (f *DeltaFIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *DeltaFIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -411,6 +444,21 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err if err != nil { return KeyError{obj, err} } + + // Every object comes through this code path once, so this is a good + // place to call the transform func. If obj is a + // DeletedFinalStateUnknown tombstone, then the containted inner object + // will already have gone through the transformer, but we document that + // this can happen. In cases involving Replace(), such an object can + // come through multiple times. + if f.transformer != nil { + var err error + obj, err = f.transformer(obj) + if err != nil { + return err + } + } + oldDeltas := f.items[id] newDeltas := append(oldDeltas, Delta{actionType, obj}) newDeltas = dedupDeltas(newDeltas) @@ -526,6 +574,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] depth := len(f.queue) @@ -551,7 +600,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { utiltrace.Field{Key: "Reason", Value: "slow event handlers blocking the queue"}) defer trace.LogIfLong(100 * time.Millisecond) } - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err @@ -566,12 +615,11 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { // using the Sync or Replace DeltaType and then (2) it does some deletions. // In particular: for every pre-existing key K that is not the key of // an object in `list` there is the effect of -// `Delete(DeletedFinalStateUnknown{K, O})` where O is current object -// of K. If `f.knownObjects == nil` then the pre-existing keys are -// those in `f.items` and the current object of K is the `.Newest()` -// of the Deltas associated with K. Otherwise the pre-existing keys -// are those listed by `f.knownObjects` and the current object of K is -// what `f.knownObjects.GetByKey(K)` returns. +// `Delete(DeletedFinalStateUnknown{K, O})` where O is the latest known +// object of K. The pre-existing keys are those in the union set of the keys in +// `f.items` and `f.knownObjects` (if not nil). The last known object for key K is +// the one present in the last delta in `f.items`. If there is no delta for K +// in `f.items`, it is the object in `f.knownObjects` func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { f.lock.Lock() defer f.lock.Unlock() @@ -595,51 +643,23 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { } } - if f.knownObjects == nil { - // Do deletion detection against our own list. - queuedDeletions := 0 - for k, oldItem := range f.items { - if keys.Has(k) { - continue - } - // Delete pre-existing items not in the new list. - // This could happen if watch deletion event was missed while - // disconnected from apiserver. - var deletedObj interface{} - if n := oldItem.Newest(); n != nil { - deletedObj = n.Object - } - queuedDeletions++ - if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { - return err - } - } - - if !f.populated { - f.populated = true - // While there shouldn't be any queued deletions in the initial - // population of the queue, it's better to be on the safe side. - f.initialPopulationCount = keys.Len() + queuedDeletions - } - - return nil - } - - // Detect deletions not already in the queue. - knownKeys := f.knownObjects.ListKeys() + // Do deletion detection against objects in the queue queuedDeletions := 0 - for _, k := range knownKeys { + for k, oldItem := range f.items { if keys.Has(k) { continue } - - deletedObj, exists, err := f.knownObjects.GetByKey(k) - if err != nil { - deletedObj = nil - klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) - } else if !exists { - deletedObj = nil - klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) + // Delete pre-existing items not in the new list. + // This could happen if watch deletion event was missed while + // disconnected from apiserver. + var deletedObj interface{} + if n := oldItem.Newest(); n != nil { + deletedObj = n.Object + + // if the previous object is a DeletedFinalStateUnknown, we have to extract the actual Object + if d, ok := deletedObj.(DeletedFinalStateUnknown); ok { + deletedObj = d.Obj + } } queuedDeletions++ if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { @@ -647,6 +667,32 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { } } + if f.knownObjects != nil { + // Detect deletions for objects not present in the queue, but present in KnownObjects + knownKeys := f.knownObjects.ListKeys() + for _, k := range knownKeys { + if keys.Has(k) { + continue + } + if len(f.items[k]) > 0 { + continue + } + + deletedObj, exists, err := f.knownObjects.GetByKey(k) + if err != nil { + deletedObj = nil + klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) + } else if !exists { + deletedObj = nil + klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) + } + queuedDeletions++ + if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { + return err + } + } + } + if !f.populated { f.populated = true f.initialPopulationCount = keys.Len() + queuedDeletions diff --git a/vendor/k8s.io/client-go/tools/cache/expiration_cache.go b/vendor/k8s.io/client-go/tools/cache/expiration_cache.go index 7abdae73742..813916ebf00 100644 --- a/vendor/k8s.io/client-go/tools/cache/expiration_cache.go +++ b/vendor/k8s.io/client-go/tools/cache/expiration_cache.go @@ -20,18 +20,18 @@ import ( "sync" "time" - "k8s.io/klog/v2" "k8s.io/utils/clock" ) // ExpirationCache implements the store interface -// 1. All entries are automatically time stamped on insert -// a. The key is computed based off the original item/keyFunc -// b. The value inserted under that key is the timestamped item -// 2. Expiration happens lazily on read based on the expiration policy -// a. No item can be inserted into the store while we're expiring -// *any* item in the cache. -// 3. Time-stamps are stripped off unexpired entries before return +// 1. All entries are automatically time stamped on insert +// a. The key is computed based off the original item/keyFunc +// b. The value inserted under that key is the timestamped item +// 2. Expiration happens lazily on read based on the expiration policy +// a. No item can be inserted into the store while we're expiring +// *any* item in the cache. +// 3. Time-stamps are stripped off unexpired entries before return +// // Note that the ExpirationCache is inherently slower than a normal // threadSafeStore because it takes a write lock every time it checks if // an item has expired. @@ -99,7 +99,6 @@ func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) { return nil, false } if c.expirationPolicy.IsExpired(timestampedItem) { - klog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.Obj) c.cacheStorage.Delete(key) return nil, false } diff --git a/vendor/k8s.io/client-go/tools/cache/fifo.go b/vendor/k8s.io/client-go/tools/cache/fifo.go index 5c9255027a0..dd13c4ea774 100644 --- a/vendor/k8s.io/client-go/tools/cache/fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/fifo.go @@ -25,7 +25,7 @@ import ( // PopProcessFunc is passed to Pop() method of Queue interface. // It is supposed to process the accumulator popped from the queue. -type PopProcessFunc func(interface{}) error +type PopProcessFunc func(obj interface{}, isInInitialList bool) error // ErrRequeue may be returned by a PopProcessFunc to safely requeue // the current item. The value of Err will be returned from Pop. @@ -82,9 +82,12 @@ type Queue interface { // Pop is helper function for popping from Queue. // WARNING: Do NOT use this function in non-test code to avoid races // unless you really really really really know what you are doing. +// +// NOTE: This function is deprecated and may be removed in the future without +// additional warning. func Pop(queue Queue) interface{} { var result interface{} - queue.Pop(func(obj interface{}) error { + queue.Pop(func(obj interface{}, isInInitialList bool) error { result = obj return nil }) @@ -103,10 +106,11 @@ func Pop(queue Queue) interface{} { // recent version will be processed. This can't be done with a channel // // FIFO solves this use case: -// * You want to process every object (exactly) once. -// * You want to process the most recent version of the object when you process it. -// * You do not want to process deleted objects, they should be removed from the queue. -// * You do not want to periodically reprocess objects. +// - You want to process every object (exactly) once. +// - You want to process the most recent version of the object when you process it. +// - You do not want to process deleted objects, they should be removed from the queue. +// - You do not want to periodically reprocess objects. +// // Compare with DeltaFIFO for other use cases. type FIFO struct { lock sync.RWMutex @@ -148,6 +152,10 @@ func (f *FIFO) Close() { func (f *FIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *FIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -286,6 +294,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] if f.initialPopulationCount > 0 { @@ -297,7 +306,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { continue } delete(f.items, id) - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err diff --git a/vendor/k8s.io/client-go/tools/cache/index.go b/vendor/k8s.io/client-go/tools/cache/index.go index 1d6aae560af..b78d3086b8c 100644 --- a/vendor/k8s.io/client-go/tools/cache/index.go +++ b/vendor/k8s.io/client-go/tools/cache/index.go @@ -28,10 +28,10 @@ import ( // Delete). // // There are three kinds of strings here: -// 1. a storage key, as defined in the Store interface, -// 2. a name of an index, and -// 3. an "indexed value", which is produced by an IndexFunc and -// can be a field value or any other string computed from the object. +// 1. a storage key, as defined in the Store interface, +// 2. a name of an index, and +// 3. an "indexed value", which is produced by an IndexFunc and +// can be a field value or any other string computed from the object. type Indexer interface { Store // Index returns the stored objects whose set of indexed values @@ -47,7 +47,7 @@ type Indexer interface { // ByIndex returns the stored objects whose set of indexed values // for the named index includes the given indexed value ByIndex(indexName, indexedValue string) ([]interface{}, error) - // GetIndexer return the indexers + // GetIndexers return the indexers GetIndexers() Indexers // AddIndexers adds more indexers to this store. If you call this after you already have data diff --git a/vendor/k8s.io/client-go/tools/cache/listers.go b/vendor/k8s.io/client-go/tools/cache/listers.go index 7885d2f760b..420ca7b2aca 100644 --- a/vendor/k8s.io/client-go/tools/cache/listers.go +++ b/vendor/k8s.io/client-go/tools/cache/listers.go @@ -53,24 +53,8 @@ func ListAll(store Store, selector labels.Selector, appendFn AppendFunc) error { // ListAllByNamespace used to list items belongs to namespace from Indexer. func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selector, appendFn AppendFunc) error { - selectAll := selector.Empty() if namespace == metav1.NamespaceAll { - for _, m := range indexer.List() { - if selectAll { - // Avoid computing labels of the objects to speed up common flows - // of listing all objects. - appendFn(m) - continue - } - metadata, err := meta.Accessor(m) - if err != nil { - return err - } - if selector.Matches(labels.Set(metadata.GetLabels())) { - appendFn(m) - } - } - return nil + return ListAll(indexer, selector, appendFn) } items, err := indexer.Index(NamespaceIndex, &metav1.ObjectMeta{Namespace: namespace}) @@ -89,6 +73,8 @@ func ListAllByNamespace(indexer Indexer, namespace string, selector labels.Selec } return nil } + + selectAll := selector.Empty() for _, m := range items { if selectAll { // Avoid computing labels of the objects to speed up common flows diff --git a/vendor/k8s.io/client-go/tools/cache/reflector.go b/vendor/k8s.io/client-go/tools/cache/reflector.go index 84f242116b9..2b335c104c8 100644 --- a/vendor/k8s.io/client-go/tools/cache/reflector.go +++ b/vendor/k8s.io/client-go/tools/cache/reflector.go @@ -23,6 +23,7 @@ import ( "io" "math/rand" "reflect" + "strings" "sync" "time" @@ -40,6 +41,7 @@ import ( "k8s.io/client-go/tools/pager" "k8s.io/klog/v2" "k8s.io/utils/clock" + "k8s.io/utils/pointer" "k8s.io/utils/trace" ) @@ -49,12 +51,11 @@ const defaultExpectedTypeName = "" type Reflector struct { // name identifies this reflector. By default it will be a file:line if possible. name string - // The name of the type we expect to place in the store. The name // will be the stringification of expectedGVK if provided, and the // stringification of expectedType otherwise. It is for display // only, and should not be used for parsing or comparison. - expectedTypeName string + typeDescription string // An example object of the type we expect to place in the store. // Only the type needs to be right, except that when that is // `unstructured.Unstructured` the object's `"apiVersion"` and @@ -66,15 +67,11 @@ type Reflector struct { store Store // listerWatcher is used to perform lists and watches. listerWatcher ListerWatcher - // backoff manages backoff of ListWatch backoffManager wait.BackoffManager // initConnBackoffManager manages backoff the initial connection with the Watch call of ListAndWatch. initConnBackoffManager wait.BackoffManager - - resyncPeriod time.Duration - // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked - ShouldResync func() bool + resyncPeriod time.Duration // clock allows tests to manipulate time clock clock.Clock // paginatedResult defines whether pagination should be forced for list calls. @@ -89,6 +86,8 @@ type Reflector struct { isLastSyncResourceVersionUnavailable bool // lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion lastSyncResourceVersionMutex sync.RWMutex + // Called whenever the ListAndWatch drops the connection with an error. + watchErrorHandler WatchErrorHandler // WatchListPageSize is the requested chunk size of initial and resync watch lists. // If unset, for consistent reads (RV="") or reads that opt-into arbitrarily old data // (RV="0") it will default to pager.PageSize, for the rest (RV != "" && RV != "0") @@ -97,8 +96,19 @@ type Reflector struct { // etcd, which is significantly less efficient and may lead to serious performance and // scalability problems. WatchListPageSize int64 - // Called whenever the ListAndWatch drops the connection with an error. - watchErrorHandler WatchErrorHandler + // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked + ShouldResync func() bool + // MaxInternalErrorRetryDuration defines how long we should retry internal errors returned by watch. + MaxInternalErrorRetryDuration time.Duration + // UseWatchList if turned on instructs the reflector to open a stream to bring data from the API server. + // Streaming has the primary advantage of using fewer server's resources to fetch data. + // + // The old behaviour establishes a LIST request which gets data in chunks. + // Paginated list is less efficient and depending on the actual size of objects + // might result in an increased memory consumption of the APIServer. + // + // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#design-details + UseWatchList bool } // ResourceVersionUpdater is an interface that allows store implementation to @@ -129,13 +139,13 @@ func DefaultWatchErrorHandler(r *Reflector, err error) { // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case err == io.EOF: // watch closed normally case err == io.ErrUnexpectedEOF: - klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedTypeName, err) + klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.typeDescription, err) default: - utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedTypeName, err)) + utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.typeDescription, err)) } } @@ -153,7 +163,40 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa return indexer, reflector } -// NewReflector creates a new Reflector object which will keep the +// NewReflector creates a new Reflector with its name defaulted to the closest source_file.go:line in the call stack +// that is outside this package. See NewReflectorWithOptions for further information. +func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{ResyncPeriod: resyncPeriod}) +} + +// NewNamedReflector creates a new Reflector with the specified name. See NewReflectorWithOptions for further +// information. +func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{Name: name, ResyncPeriod: resyncPeriod}) +} + +// ReflectorOptions configures a Reflector. +type ReflectorOptions struct { + // Name is the Reflector's name. If unset/unspecified, the name defaults to the closest source_file.go:line + // in the call stack that is outside this package. + Name string + + // TypeDescription is the Reflector's type description. If unset/unspecified, the type description is defaulted + // using the following rules: if the expectedType passed to NewReflectorWithOptions was nil, the type description is + // "". If the expectedType is an instance of *unstructured.Unstructured and its apiVersion and kind fields + // are set, the type description is the string encoding of those. Otherwise, the type description is set to the + // go type of expectedType.. + TypeDescription string + + // ResyncPeriod is the Reflector's resync period. If unset/unspecified, the resync period defaults to 0 + // (do not resync). + ResyncPeriod time.Duration + + // Clock allows tests to control time. If unset defaults to clock.RealClock{} + Clock clock.Clock +} + +// NewReflectorWithOptions creates a new Reflector object which will keep the // given store up to date with the server's contents for the given // resource. Reflector promises to only put things in the store that // have the type of expectedType, unless expectedType is nil. If @@ -163,49 +206,74 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa // "yes". This enables you to use reflectors to periodically process // everything as well as incrementally processing the things that // change. -func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - return NewNamedReflector(naming.GetNameFromCallsite(internalPackages...), lw, expectedType, store, resyncPeriod) -} - -// NewNamedReflector same as NewReflector, but with a specified name for logging -func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - realClock := &clock.RealClock{} +func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store Store, options ReflectorOptions) *Reflector { + reflectorClock := options.Clock + if reflectorClock == nil { + reflectorClock = clock.RealClock{} + } r := &Reflector{ - name: name, - listerWatcher: lw, - store: store, + name: options.Name, + resyncPeriod: options.ResyncPeriod, + typeDescription: options.TypeDescription, + listerWatcher: lw, + store: store, // We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when // API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is // 0.22 QPS. If we don't backoff for 2min, assume API server is healthy and we reset the backoff. - backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - resyncPeriod: resyncPeriod, - clock: realClock, + backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + clock: reflectorClock, watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler), + expectedType: reflect.TypeOf(expectedType), + } + + if r.name == "" { + r.name = naming.GetNameFromCallsite(internalPackages...) + } + + if r.typeDescription == "" { + r.typeDescription = getTypeDescriptionFromObject(expectedType) } - r.setExpectedType(expectedType) + + if r.expectedGVK == nil { + r.expectedGVK = getExpectedGVKFromObject(expectedType) + } + return r } -func (r *Reflector) setExpectedType(expectedType interface{}) { - r.expectedType = reflect.TypeOf(expectedType) - if r.expectedType == nil { - r.expectedTypeName = defaultExpectedTypeName - return +func getTypeDescriptionFromObject(expectedType interface{}) string { + if expectedType == nil { + return defaultExpectedTypeName } - r.expectedTypeName = r.expectedType.String() + reflectDescription := reflect.TypeOf(expectedType).String() - if obj, ok := expectedType.(*unstructured.Unstructured); ok { - // Use gvk to check that watch event objects are of the desired type. - gvk := obj.GroupVersionKind() - if gvk.Empty() { - klog.V(4).Infof("Reflector from %s configured with expectedType of *unstructured.Unstructured with empty GroupVersionKind.", r.name) - return - } - r.expectedGVK = &gvk - r.expectedTypeName = gvk.String() + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return reflectDescription } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return reflectDescription + } + + return gvk.String() +} + +func getExpectedGVKFromObject(expectedType interface{}) *schema.GroupVersionKind { + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return nil + } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return nil + } + + return &gvk } // internalPackages are packages that ignored when creating a default reflector name. These packages are in the common @@ -216,13 +284,13 @@ var internalPackages = []string{"client-go/tools/cache/"} // objects and subsequent deltas. // Run will exit when stopCh is closed. func (r *Reflector) Run(stopCh <-chan struct{}) { - klog.V(3).Infof("Starting reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Starting reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) wait.BackoffUntil(func() { if err := r.ListAndWatch(stopCh); err != nil { r.watchErrorHandler(r, err) } }, r.backoffManager, true, stopCh) - klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) } var ( @@ -252,143 +320,74 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) { // and then use the resource version to watch. // It returns error if ListAndWatch didn't even try to initialize watch. func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { - klog.V(3).Infof("Listing and watching %v from %s", r.expectedTypeName, r.name) - var resourceVersion string - - options := metav1.ListOptions{ResourceVersion: r.relistResourceVersion()} - - if err := func() error { - initTrace := trace.New("Reflector ListAndWatch", trace.Field{Key: "name", Value: r.name}) - defer initTrace.LogIfLong(10 * time.Second) - var list runtime.Object - var paginatedResult bool - var err error - listCh := make(chan struct{}, 1) - panicCh := make(chan interface{}, 1) - go func() { - defer func() { - if r := recover(); r != nil { - panicCh <- r - } - }() - // Attempt to gather list in chunks, if supported by listerWatcher, if not, the first - // list request will return the full response. - pager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) { - return r.listerWatcher.List(opts) - })) - switch { - case r.WatchListPageSize != 0: - pager.PageSize = r.WatchListPageSize - case r.paginatedResult: - // We got a paginated result initially. Assume this resource and server honor - // paging requests (i.e. watch cache is probably disabled) and leave the default - // pager size set. - case options.ResourceVersion != "" && options.ResourceVersion != "0": - // User didn't explicitly request pagination. - // - // With ResourceVersion != "", we have a possibility to list from watch cache, - // but we do that (for ResourceVersion != "0") only if Limit is unset. - // To avoid thundering herd on etcd (e.g. on master upgrades), we explicitly - // switch off pagination to force listing from watch cache (if enabled). - // With the existing semantic of RV (result is at least as fresh as provided RV), - // this is correct and doesn't lead to going back in time. - // - // We also don't turn off pagination for ResourceVersion="0", since watch cache - // is ignoring Limit in that case anyway, and if watch cache is not enabled - // we don't introduce regression. - pager.PageSize = 0 - } - - list, paginatedResult, err = pager.List(context.Background(), options) - if isExpiredError(err) || isTooLargeResourceVersionError(err) { - r.setIsLastSyncResourceVersionUnavailable(true) - // Retry immediately if the resource version used to list is unavailable. - // The pager already falls back to full list if paginated list calls fail due to an "Expired" error on - // continuation pages, but the pager might not be enabled, the full list might fail because the - // resource version it is listing at is expired or the cache may not yet be synced to the provided - // resource version. So we need to fallback to resourceVersion="" in all to recover and ensure - // the reflector makes forward progress. - list, paginatedResult, err = pager.List(context.Background(), metav1.ListOptions{ResourceVersion: r.relistResourceVersion()}) - } - close(listCh) - }() - select { - case <-stopCh: + klog.V(3).Infof("Listing and watching %v from %s", r.typeDescription, r.name) + var err error + var w watch.Interface + fallbackToList := !r.UseWatchList + + if r.UseWatchList { + w, err = r.watchList(stopCh) + if w == nil && err == nil { + // stopCh was closed return nil - case r := <-panicCh: - panic(r) - case <-listCh: } - initTrace.Step("Objects listed", trace.Field{Key: "error", Value: err}) if err != nil { - klog.Warningf("%s: failed to list %v: %v", r.name, r.expectedTypeName, err) - return fmt.Errorf("failed to list %v: %v", r.expectedTypeName, err) - } - - // We check if the list was paginated and if so set the paginatedResult based on that. - // However, we want to do that only for the initial list (which is the only case - // when we set ResourceVersion="0"). The reasoning behind it is that later, in some - // situations we may force listing directly from etcd (by setting ResourceVersion="") - // which will return paginated result, even if watch cache is enabled. However, in - // that case, we still want to prefer sending requests to watch cache if possible. - // - // Paginated result returned for request with ResourceVersion="0" mean that watch - // cache is disabled and there are a lot of objects of a given type. In such case, - // there is no need to prefer listing from watch cache. - if options.ResourceVersion == "0" && paginatedResult { - r.paginatedResult = true + if !apierrors.IsInvalid(err) { + return err + } + klog.Warning("the watch-list feature is not supported by the server, falling back to the previous LIST/WATCH semantic") + fallbackToList = true + // Ensure that we won't accidentally pass some garbage down the watch. + w = nil } + } - r.setIsLastSyncResourceVersionUnavailable(false) // list was successful - listMetaInterface, err := meta.ListAccessor(list) - if err != nil { - return fmt.Errorf("unable to understand list result %#v: %v", list, err) - } - resourceVersion = listMetaInterface.GetResourceVersion() - initTrace.Step("Resource version extracted") - items, err := meta.ExtractList(list) + if fallbackToList { + err = r.list(stopCh) if err != nil { - return fmt.Errorf("unable to understand list result %#v (%v)", list, err) - } - initTrace.Step("Objects extracted") - if err := r.syncWith(items, resourceVersion); err != nil { - return fmt.Errorf("unable to sync list result: %v", err) + return err } - initTrace.Step("SyncWith done") - r.setLastSyncResourceVersion(resourceVersion) - initTrace.Step("Resource version updated") - return nil - }(); err != nil { - return err } resyncerrc := make(chan error, 1) cancelCh := make(chan struct{}) defer close(cancelCh) - go func() { - resyncCh, cleanup := r.resyncChan() - defer func() { - cleanup() // Call the last one written into cleanup - }() - for { - select { - case <-resyncCh: - case <-stopCh: - return - case <-cancelCh: + go r.startResync(stopCh, cancelCh, resyncerrc) + return r.watch(w, stopCh, resyncerrc) +} + +// startResync periodically calls r.store.Resync() method. +// Note that this method is blocking and should be +// called in a separate goroutine. +func (r *Reflector) startResync(stopCh <-chan struct{}, cancelCh <-chan struct{}, resyncerrc chan error) { + resyncCh, cleanup := r.resyncChan() + defer func() { + cleanup() // Call the last one written into cleanup + }() + for { + select { + case <-resyncCh: + case <-stopCh: + return + case <-cancelCh: + return + } + if r.ShouldResync == nil || r.ShouldResync() { + klog.V(4).Infof("%s: forcing resync", r.name) + if err := r.store.Resync(); err != nil { + resyncerrc <- err return } - if r.ShouldResync == nil || r.ShouldResync() { - klog.V(4).Infof("%s: forcing resync", r.name) - if err := r.store.Resync(); err != nil { - resyncerrc <- err - return - } - } - cleanup() - resyncCh, cleanup = r.resyncChan() } - }() + cleanup() + resyncCh, cleanup = r.resyncChan() + } +} + +// watch simply starts a watch request with the server. +func (r *Reflector) watch(w watch.Interface, stopCh <-chan struct{}, resyncerrc chan error) error { + var err error + retry := NewRetryWithDeadline(r.MaxInternalErrorRetryDuration, time.Minute, apierrors.IsInternalError, r.clock) for { // give the stopCh a chance to stop the loop, even in case of continue statements further down on errors @@ -398,48 +397,63 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { default: } - timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) - options = metav1.ListOptions{ - ResourceVersion: resourceVersion, - // We want to avoid situations of hanging watchers. Stop any watchers that do not - // receive any events within the timeout window. - TimeoutSeconds: &timeoutSeconds, - // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. - // Reflector doesn't assume bookmarks are returned at all (if the server do not support - // watch bookmarks, it will ignore this field). - AllowWatchBookmarks: true, - } - // start the clock before sending the request, since some proxies won't flush headers until after the first watch event is sent start := r.clock.Now() - w, err := r.listerWatcher.Watch(options) - if err != nil { - // If this is "connection refused" error, it means that most likely apiserver is not responsive. - // It doesn't make sense to re-list all objects because most likely we will be able to restart - // watch where we ended. - // If that's the case begin exponentially backing off and resend watch request. - // Do the same for "429" errors. - if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { - <-r.initConnBackoffManager.Backoff().C() - continue + + if w == nil { + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: r.LastSyncResourceVersion(), + // We want to avoid situations of hanging watchers. Stop any watchers that do not + // receive any events within the timeout window. + TimeoutSeconds: &timeoutSeconds, + // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. + // Reflector doesn't assume bookmarks are returned at all (if the server do not support + // watch bookmarks, it will ignore this field). + AllowWatchBookmarks: true, + } + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(4).Infof("%s: watch of %v returned %v - backing off", r.name, r.typeDescription, err) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } + } + return err } - return err } - if err := r.watchHandler(start, w, &resourceVersion, resyncerrc, stopCh); err != nil { + err = watchHandler(start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.typeDescription, r.setLastSyncResourceVersion, nil, r.clock, resyncerrc, stopCh) + // Ensure that watch will not be reused across iterations. + w.Stop() + w = nil + retry.After(err) + if err != nil { if err != errorStopRequested { switch { case isExpiredError(err): // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case apierrors.IsTooManyRequests(err): - klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.expectedTypeName) - <-r.initConnBackoffManager.Backoff().C() + klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.typeDescription) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } + case apierrors.IsInternalError(err) && retry.ShouldRetry(): + klog.V(2).Infof("%s: retrying watch of %v internal error: %v", r.name, r.typeDescription, err) continue default: - klog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedTypeName, err) + klog.Warningf("%s: watch of %v ended with: %v", r.name, r.typeDescription, err) } } return nil @@ -447,6 +461,222 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { } } +// list simply lists all items and records a resource version obtained from the server at the moment of the call. +// the resource version can be used for further progress notification (aka. watch). +func (r *Reflector) list(stopCh <-chan struct{}) error { + var resourceVersion string + options := metav1.ListOptions{ResourceVersion: r.relistResourceVersion()} + + initTrace := trace.New("Reflector ListAndWatch", trace.Field{Key: "name", Value: r.name}) + defer initTrace.LogIfLong(10 * time.Second) + var list runtime.Object + var paginatedResult bool + var err error + listCh := make(chan struct{}, 1) + panicCh := make(chan interface{}, 1) + go func() { + defer func() { + if r := recover(); r != nil { + panicCh <- r + } + }() + // Attempt to gather list in chunks, if supported by listerWatcher, if not, the first + // list request will return the full response. + pager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) { + return r.listerWatcher.List(opts) + })) + switch { + case r.WatchListPageSize != 0: + pager.PageSize = r.WatchListPageSize + case r.paginatedResult: + // We got a paginated result initially. Assume this resource and server honor + // paging requests (i.e. watch cache is probably disabled) and leave the default + // pager size set. + case options.ResourceVersion != "" && options.ResourceVersion != "0": + // User didn't explicitly request pagination. + // + // With ResourceVersion != "", we have a possibility to list from watch cache, + // but we do that (for ResourceVersion != "0") only if Limit is unset. + // To avoid thundering herd on etcd (e.g. on master upgrades), we explicitly + // switch off pagination to force listing from watch cache (if enabled). + // With the existing semantic of RV (result is at least as fresh as provided RV), + // this is correct and doesn't lead to going back in time. + // + // We also don't turn off pagination for ResourceVersion="0", since watch cache + // is ignoring Limit in that case anyway, and if watch cache is not enabled + // we don't introduce regression. + pager.PageSize = 0 + } + + list, paginatedResult, err = pager.List(context.Background(), options) + if isExpiredError(err) || isTooLargeResourceVersionError(err) { + r.setIsLastSyncResourceVersionUnavailable(true) + // Retry immediately if the resource version used to list is unavailable. + // The pager already falls back to full list if paginated list calls fail due to an "Expired" error on + // continuation pages, but the pager might not be enabled, the full list might fail because the + // resource version it is listing at is expired or the cache may not yet be synced to the provided + // resource version. So we need to fallback to resourceVersion="" in all to recover and ensure + // the reflector makes forward progress. + list, paginatedResult, err = pager.List(context.Background(), metav1.ListOptions{ResourceVersion: r.relistResourceVersion()}) + } + close(listCh) + }() + select { + case <-stopCh: + return nil + case r := <-panicCh: + panic(r) + case <-listCh: + } + initTrace.Step("Objects listed", trace.Field{Key: "error", Value: err}) + if err != nil { + klog.Warningf("%s: failed to list %v: %v", r.name, r.typeDescription, err) + return fmt.Errorf("failed to list %v: %w", r.typeDescription, err) + } + + // We check if the list was paginated and if so set the paginatedResult based on that. + // However, we want to do that only for the initial list (which is the only case + // when we set ResourceVersion="0"). The reasoning behind it is that later, in some + // situations we may force listing directly from etcd (by setting ResourceVersion="") + // which will return paginated result, even if watch cache is enabled. However, in + // that case, we still want to prefer sending requests to watch cache if possible. + // + // Paginated result returned for request with ResourceVersion="0" mean that watch + // cache is disabled and there are a lot of objects of a given type. In such case, + // there is no need to prefer listing from watch cache. + if options.ResourceVersion == "0" && paginatedResult { + r.paginatedResult = true + } + + r.setIsLastSyncResourceVersionUnavailable(false) // list was successful + listMetaInterface, err := meta.ListAccessor(list) + if err != nil { + return fmt.Errorf("unable to understand list result %#v: %v", list, err) + } + resourceVersion = listMetaInterface.GetResourceVersion() + initTrace.Step("Resource version extracted") + items, err := meta.ExtractList(list) + if err != nil { + return fmt.Errorf("unable to understand list result %#v (%v)", list, err) + } + initTrace.Step("Objects extracted") + if err := r.syncWith(items, resourceVersion); err != nil { + return fmt.Errorf("unable to sync list result: %v", err) + } + initTrace.Step("SyncWith done") + r.setLastSyncResourceVersion(resourceVersion) + initTrace.Step("Resource version updated") + return nil +} + +// watchList establishes a stream to get a consistent snapshot of data +// from the server as described in https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#proposal +// +// case 1: start at Most Recent (RV="", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a consistent stream with the server. +// That means the returned data is consistent, as if, served directly from etcd via a quorum read. +// It begins with synthetic "Added" events of all resources up to the most recent ResourceVersion. +// It ends with a synthetic "Bookmark" event containing the most recent ResourceVersion. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +// +// case 2: start at Exact (RV>"0", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a stream with the server at the provided resource version. +// To establish the initial state the server begins with synthetic "Added" events. +// It ends with a synthetic "Bookmark" event containing the provided or newer resource version. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +func (r *Reflector) watchList(stopCh <-chan struct{}) (watch.Interface, error) { + var w watch.Interface + var err error + var temporaryStore Store + var resourceVersion string + // TODO(#115478): see if this function could be turned + // into a method and see if error handling + // could be unified with the r.watch method + isErrorRetriableWithSideEffectsFn := func(err error) bool { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(2).Infof("%s: watch-list of %v returned %v - backing off", r.name, r.typeDescription, err) + <-r.initConnBackoffManager.Backoff().C() + return true + } + if isExpiredError(err) || isTooLargeResourceVersionError(err) { + // we tried to re-establish a watch request but the provided RV + // has either expired or it is greater than the server knows about. + // In that case we reset the RV and + // try to get a consistent snapshot from the watch cache (case 1) + r.setIsLastSyncResourceVersionUnavailable(true) + return true + } + return false + } + + initTrace := trace.New("Reflector WatchList", trace.Field{Key: "name", Value: r.name}) + defer initTrace.LogIfLong(10 * time.Second) + for { + select { + case <-stopCh: + return nil, nil + default: + } + + resourceVersion = "" + lastKnownRV := r.rewatchResourceVersion() + temporaryStore = NewStore(DeletionHandlingMetaNamespaceKeyFunc) + // TODO(#115478): large "list", slow clients, slow network, p&f + // might slow down streaming and eventually fail. + // maybe in such a case we should retry with an increased timeout? + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: lastKnownRV, + AllowWatchBookmarks: true, + SendInitialEvents: pointer.Bool(true), + ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, + TimeoutSeconds: &timeoutSeconds, + } + start := r.clock.Now() + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + bookmarkReceived := pointer.Bool(false) + err = watchHandler(start, w, temporaryStore, r.expectedType, r.expectedGVK, r.name, r.typeDescription, + func(rv string) { resourceVersion = rv }, + bookmarkReceived, + r.clock, make(chan error), stopCh) + if err != nil { + w.Stop() // stop and retry with clean state + if err == errorStopRequested { + return nil, nil + } + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + if *bookmarkReceived { + break + } + } + // We successfully got initial state from watch-list confirmed by the + // "k8s.io/initial-events-end" bookmark. + initTrace.Step("Objects streamed", trace.Field{Key: "count", Value: len(temporaryStore.List())}) + r.setIsLastSyncResourceVersionUnavailable(false) + if err = r.store.Replace(temporaryStore.List(), resourceVersion); err != nil { + return nil, fmt.Errorf("unable to sync watch-list result: %v", err) + } + initTrace.Step("SyncWith done") + r.setLastSyncResourceVersion(resourceVersion) + + return w, nil +} + // syncWith replaces the store's items with the given list. func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) error { found := make([]interface{}, 0, len(items)) @@ -456,13 +686,26 @@ func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) err return r.store.Replace(found, resourceVersion) } -// watchHandler watches w and keeps *resourceVersion up to date. -func (r *Reflector) watchHandler(start time.Time, w watch.Interface, resourceVersion *string, errc chan error, stopCh <-chan struct{}) error { +// watchHandler watches w and sets setLastSyncResourceVersion +func watchHandler(start time.Time, + w watch.Interface, + store Store, + expectedType reflect.Type, + expectedGVK *schema.GroupVersionKind, + name string, + expectedTypeName string, + setLastSyncResourceVersion func(string), + exitOnInitialEventsEndBookmark *bool, + clock clock.Clock, + errc chan error, + stopCh <-chan struct{}, +) error { eventCount := 0 - - // Stopping the watcher should be idempotent and if we return from this function there's no way - // we're coming back in with the same watch interface. - defer w.Stop() + if exitOnInitialEventsEndBookmark != nil { + // set it to false just in case somebody + // made it positive + *exitOnInitialEventsEndBookmark = false + } loop: for { @@ -478,62 +721,71 @@ loop: if event.Type == watch.Error { return apierrors.FromObject(event.Object) } - if r.expectedType != nil { - if e, a := r.expectedType, reflect.TypeOf(event.Object); e != a { - utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", r.name, e, a)) + if expectedType != nil { + if e, a := expectedType, reflect.TypeOf(event.Object); e != a { + utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", name, e, a)) continue } } - if r.expectedGVK != nil { - if e, a := *r.expectedGVK, event.Object.GetObjectKind().GroupVersionKind(); e != a { - utilruntime.HandleError(fmt.Errorf("%s: expected gvk %v, but watch event object had gvk %v", r.name, e, a)) + if expectedGVK != nil { + if e, a := *expectedGVK, event.Object.GetObjectKind().GroupVersionKind(); e != a { + utilruntime.HandleError(fmt.Errorf("%s: expected gvk %v, but watch event object had gvk %v", name, e, a)) continue } } meta, err := meta.Accessor(event.Object) if err != nil { - utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event)) + utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", name, event)) continue } - newResourceVersion := meta.GetResourceVersion() + resourceVersion := meta.GetResourceVersion() switch event.Type { case watch.Added: - err := r.store.Add(event.Object) + err := store.Add(event.Object) if err != nil { - utilruntime.HandleError(fmt.Errorf("%s: unable to add watch event object (%#v) to store: %v", r.name, event.Object, err)) + utilruntime.HandleError(fmt.Errorf("%s: unable to add watch event object (%#v) to store: %v", name, event.Object, err)) } case watch.Modified: - err := r.store.Update(event.Object) + err := store.Update(event.Object) if err != nil { - utilruntime.HandleError(fmt.Errorf("%s: unable to update watch event object (%#v) to store: %v", r.name, event.Object, err)) + utilruntime.HandleError(fmt.Errorf("%s: unable to update watch event object (%#v) to store: %v", name, event.Object, err)) } case watch.Deleted: // TODO: Will any consumers need access to the "last known // state", which is passed in event.Object? If so, may need // to change this. - err := r.store.Delete(event.Object) + err := store.Delete(event.Object) if err != nil { - utilruntime.HandleError(fmt.Errorf("%s: unable to delete watch event object (%#v) from store: %v", r.name, event.Object, err)) + utilruntime.HandleError(fmt.Errorf("%s: unable to delete watch event object (%#v) from store: %v", name, event.Object, err)) } case watch.Bookmark: // A `Bookmark` means watch has synced here, just update the resourceVersion + if _, ok := meta.GetAnnotations()["k8s.io/initial-events-end"]; ok { + if exitOnInitialEventsEndBookmark != nil { + *exitOnInitialEventsEndBookmark = true + } + } default: - utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event)) + utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", name, event)) } - *resourceVersion = newResourceVersion - r.setLastSyncResourceVersion(newResourceVersion) - if rvu, ok := r.store.(ResourceVersionUpdater); ok { - rvu.UpdateResourceVersion(newResourceVersion) + setLastSyncResourceVersion(resourceVersion) + if rvu, ok := store.(ResourceVersionUpdater); ok { + rvu.UpdateResourceVersion(resourceVersion) } eventCount++ + if exitOnInitialEventsEndBookmark != nil && *exitOnInitialEventsEndBookmark { + watchDuration := clock.Since(start) + klog.V(4).Infof("exiting %v Watch because received the bookmark that marks the end of initial events stream, total %v items received in %v", name, eventCount, watchDuration) + return nil + } } } - watchDuration := r.clock.Since(start) + watchDuration := clock.Since(start) if watchDuration < 1*time.Second && eventCount == 0 { - return fmt.Errorf("very short watch: %s: Unexpected watch close - watch lasted less than a second and no items received", r.name) + return fmt.Errorf("very short watch: %s: Unexpected watch close - watch lasted less than a second and no items received", name) } - klog.V(4).Infof("%s: Watch close - %v total %v items received", r.name, r.expectedTypeName, eventCount) + klog.V(4).Infof("%s: Watch close - %v total %v items received", name, expectedTypeName, eventCount) return nil } @@ -574,6 +826,18 @@ func (r *Reflector) relistResourceVersion() string { return r.lastSyncResourceVersion } +// rewatchResourceVersion determines the resource version the reflector should start streaming from. +func (r *Reflector) rewatchResourceVersion() string { + r.lastSyncResourceVersionMutex.RLock() + defer r.lastSyncResourceVersionMutex.RUnlock() + if r.isLastSyncResourceVersionUnavailable { + // initial stream should return data at the most recent resource version. + // the returned data must be consistent i.e. as if served from etcd via a quorum read + return "" + } + return r.lastSyncResourceVersion +} + // setIsLastSyncResourceVersionUnavailable sets if the last list or watch request with lastSyncResourceVersion returned // "expired" or "too large resource version" error. func (r *Reflector) setIsLastSyncResourceVersionUnavailable(isUnavailable bool) { @@ -612,5 +876,25 @@ func isTooLargeResourceVersionError(err error) bool { return true } } + + // Matches the message returned by api server before 1.17.0 + if strings.Contains(apierr.Status().Message, "Too large resource version") { + return true + } + + return false +} + +// isWatchErrorRetriable determines if it is safe to retry +// a watch error retrieved from the server. +func isWatchErrorRetriable(err error) bool { + // If this is "connection refused" error, it means that most likely apiserver is not responsive. + // It doesn't make sense to re-list all objects because most likely we will be able to restart + // watch where we ended. + // If that's the case begin exponentially backing off and resend watch request. + // Do the same for "429" errors. + if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { + return true + } return false } diff --git a/vendor/k8s.io/client-go/tools/cache/retry_with_deadline.go b/vendor/k8s.io/client-go/tools/cache/retry_with_deadline.go new file mode 100644 index 00000000000..8201fb1532a --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/retry_with_deadline.go @@ -0,0 +1,78 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cache + +import ( + "k8s.io/utils/clock" + "time" +) + +type RetryWithDeadline interface { + After(error) + ShouldRetry() bool +} + +type retryWithDeadlineImpl struct { + firstErrorTime time.Time + lastErrorTime time.Time + maxRetryDuration time.Duration + minResetPeriod time.Duration + isRetryable func(error) bool + clock clock.Clock +} + +func NewRetryWithDeadline(maxRetryDuration, minResetPeriod time.Duration, isRetryable func(error) bool, clock clock.Clock) RetryWithDeadline { + return &retryWithDeadlineImpl{ + firstErrorTime: time.Time{}, + lastErrorTime: time.Time{}, + maxRetryDuration: maxRetryDuration, + minResetPeriod: minResetPeriod, + isRetryable: isRetryable, + clock: clock, + } +} + +func (r *retryWithDeadlineImpl) reset() { + r.firstErrorTime = time.Time{} + r.lastErrorTime = time.Time{} +} + +func (r *retryWithDeadlineImpl) After(err error) { + if r.isRetryable(err) { + if r.clock.Now().Sub(r.lastErrorTime) >= r.minResetPeriod { + r.reset() + } + + if r.firstErrorTime.IsZero() { + r.firstErrorTime = r.clock.Now() + } + r.lastErrorTime = r.clock.Now() + } +} + +func (r *retryWithDeadlineImpl) ShouldRetry() bool { + if r.maxRetryDuration <= time.Duration(0) { + return false + } + + if r.clock.Now().Sub(r.firstErrorTime) <= r.maxRetryDuration { + return true + } + + r.reset() + return false +} diff --git a/vendor/k8s.io/client-go/tools/cache/shared_informer.go b/vendor/k8s.io/client-go/tools/cache/shared_informer.go index 9f42782d179..a889fdbc36b 100644 --- a/vendor/k8s.io/client-go/tools/cache/shared_informer.go +++ b/vendor/k8s.io/client-go/tools/cache/shared_informer.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache/synctrack" "k8s.io/utils/buffer" "k8s.io/utils/clock" @@ -132,10 +133,14 @@ import ( // state, except that its ResourceVersion is replaced with a // ResourceVersion in which the object is actually absent. type SharedInformer interface { - // AddEventHandler adds an event handler to the shared informer using the shared informer's resync - // period. Events to a single handler are delivered sequentially, but there is no coordination - // between different handlers. - AddEventHandler(handler ResourceEventHandler) + // AddEventHandler adds an event handler to the shared informer using + // the shared informer's resync period. Events to a single handler are + // delivered sequentially, but there is no coordination between + // different handlers. + // It returns a registration handle for the handler that can be used to + // remove the handler again, or to tell if the handler is synced (has + // seen every item in the initial list). + AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error) // AddEventHandlerWithResyncPeriod adds an event handler to the // shared informer with the requested resync period; zero means // this handler does not care about resyncs. The resync operation @@ -150,7 +155,13 @@ type SharedInformer interface { // between any two resyncs may be longer than the nominal period // because the implementation takes time to do work and there may // be competing load and scheduling noise. - AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) + // It returns a registration handle for the handler that can be used to remove + // the handler again and an error if the handler cannot be added. + AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) (ResourceEventHandlerRegistration, error) + // RemoveEventHandler removes a formerly added event handler given by + // its registration handle. + // This function is guaranteed to be idempotent, and thread-safe. + RemoveEventHandler(handle ResourceEventHandlerRegistration) error // GetStore returns the informer's local cache as a Store. GetStore() Store // GetController is deprecated, it does nothing useful @@ -161,6 +172,10 @@ type SharedInformer interface { // HasSynced returns true if the shared informer's store has been // informed by at least one full LIST of the authoritative state // of the informer's object collection. This is unrelated to "resync". + // + // Note that this doesn't tell you if an individual handler is synced!! + // For that, please call HasSynced on the handle returned by + // AddEventHandler. HasSynced() bool // LastSyncResourceVersion is the resource version observed when last synced with the underlying // store. The value returned is not synchronized with access to the underlying store and is not @@ -190,11 +205,25 @@ type SharedInformer interface { // // Must be set before starting the informer. // - // Note: Since the object given to the handler may be already shared with - // other goroutines, it is advisable to copy the object being - // transform before mutating it at all and returning the copy to prevent - // data races. + // Please see the comment on TransformFunc for more details. SetTransform(handler TransformFunc) error + + // IsStopped reports whether the informer has already been stopped. + // Adding event handlers to already stopped informers is not possible. + // An informer already stopped will never be started again. + IsStopped() bool +} + +// Opaque interface representing the registration of ResourceEventHandler for +// a SharedInformer. Must be supplied back to the same SharedInformer's +// `RemoveEventHandler` to unregister the handlers. +// +// Also used to tell if the handler is synced (has had all items in the initial +// list delivered). +type ResourceEventHandlerRegistration interface { + // HasSynced reports if both the parent has synced and all pre-sync + // events have been delivered. + HasSynced() bool } // SharedIndexInformer provides add and get Indexers ability based on SharedInformer. @@ -205,14 +234,26 @@ type SharedIndexInformer interface { GetIndexer() Indexer } -// NewSharedInformer creates a new instance for the listwatcher. +// NewSharedInformer creates a new instance for the ListerWatcher. See NewSharedIndexInformerWithOptions for full details. func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration) SharedInformer { return NewSharedIndexInformer(lw, exampleObject, defaultEventHandlerResyncPeriod, Indexers{}) } -// NewSharedIndexInformer creates a new instance for the listwatcher. -// The created informer will not do resyncs if the given -// defaultEventHandlerResyncPeriod is zero. Otherwise: for each +// NewSharedIndexInformer creates a new instance for the ListerWatcher and specified Indexers. See +// NewSharedIndexInformerWithOptions for full details. +func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { + return NewSharedIndexInformerWithOptions( + lw, + exampleObject, + SharedIndexInformerOptions{ + ResyncPeriod: defaultEventHandlerResyncPeriod, + Indexers: indexers, + }, + ) +} + +// NewSharedIndexInformerWithOptions creates a new instance for the ListerWatcher. +// The created informer will not do resyncs if options.ResyncPeriod is zero. Otherwise: for each // handler that with a non-zero requested resync period, whether added // before or after the informer starts, the nominal resync period is // the requested resync period rounded up to a multiple of the @@ -220,21 +261,36 @@ func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEv // checking period is established when the informer starts running, // and is the maximum of (a) the minimum of the resync periods // requested before the informer starts and the -// defaultEventHandlerResyncPeriod given here and (b) the constant +// options.ResyncPeriod given here and (b) the constant // `minimumResyncPeriod` defined in this file. -func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { +func NewSharedIndexInformerWithOptions(lw ListerWatcher, exampleObject runtime.Object, options SharedIndexInformerOptions) SharedIndexInformer { realClock := &clock.RealClock{} - sharedIndexInformer := &sharedIndexInformer{ + + return &sharedIndexInformer{ + indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers), processor: &sharedProcessor{clock: realClock}, - indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers), listerWatcher: lw, objectType: exampleObject, - resyncCheckPeriod: defaultEventHandlerResyncPeriod, - defaultEventHandlerResyncPeriod: defaultEventHandlerResyncPeriod, - cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), + objectDescription: options.ObjectDescription, + resyncCheckPeriod: options.ResyncPeriod, + defaultEventHandlerResyncPeriod: options.ResyncPeriod, clock: realClock, + cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), } - return sharedIndexInformer +} + +// SharedIndexInformerOptions configures a sharedIndexInformer. +type SharedIndexInformerOptions struct { + // ResyncPeriod is the default event handler resync period and resync check + // period. If unset/unspecified, these are defaulted to 0 (do not resync). + ResyncPeriod time.Duration + + // Indexers is the sharedIndexInformer's indexers. If unset/unspecified, no indexers are configured. + Indexers Indexers + + // ObjectDescription is the sharedIndexInformer's object description. This is passed through to the + // underlying Reflector's type description. + ObjectDescription string } // InformerSynced is a function that can be used to determine if an informer has synced. This is useful for determining if caches have synced. @@ -308,12 +364,13 @@ type sharedIndexInformer struct { listerWatcher ListerWatcher - // objectType is an example object of the type this informer is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // objectType is an example object of the type this informer is expected to handle. If set, an event + // with an object with a mismatching type is dropped instead of being delivered to listeners. objectType runtime.Object + // objectDescription is the description of this informer's objects. This typically defaults to + objectDescription string + // resyncCheckPeriod is how often we want the reflector's resync timer to fire so it can call // shouldResync to check if any of our listeners need a resync. resyncCheckPeriod time.Duration @@ -363,7 +420,8 @@ type updateNotification struct { } type addNotification struct { - newObj interface{} + newObj interface{} + isInInitialList bool } type deleteNotification struct { @@ -404,15 +462,17 @@ func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: s.indexer, EmitDeltaTypeReplaced: true, + Transformer: s.transform, }) cfg := &Config{ - Queue: fifo, - ListerWatcher: s.listerWatcher, - ObjectType: s.objectType, - FullResyncPeriod: s.resyncCheckPeriod, - RetryOnError: false, - ShouldResync: s.processor.shouldResync, + Queue: fifo, + ListerWatcher: s.listerWatcher, + ObjectType: s.objectType, + ObjectDescription: s.objectDescription, + FullResyncPeriod: s.resyncCheckPeriod, + RetryOnError: false, + ShouldResync: s.processor.shouldResync, Process: s.HandleDeltas, WatchErrorHandler: s.watchErrorHandler, @@ -492,8 +552,8 @@ func (s *sharedIndexInformer) GetController() Controller { return &dummyController{informer: s} } -func (s *sharedIndexInformer) AddEventHandler(handler ResourceEventHandler) { - s.AddEventHandlerWithResyncPeriod(handler, s.defaultEventHandlerResyncPeriod) +func (s *sharedIndexInformer) AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error) { + return s.AddEventHandlerWithResyncPeriod(handler, s.defaultEventHandlerResyncPeriod) } func determineResyncPeriod(desired, check time.Duration) time.Duration { @@ -513,13 +573,12 @@ func determineResyncPeriod(desired, check time.Duration) time.Duration { const minimumResyncPeriod = 1 * time.Second -func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) { +func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration) (ResourceEventHandlerRegistration, error) { s.startedLock.Lock() defer s.startedLock.Unlock() if s.stopped { - klog.V(2).Infof("Handler %v was not added to shared informer because it has stopped already", handler) - return + return nil, fmt.Errorf("handler %v was not added to shared informer because it has stopped already", handler) } if resyncPeriod > 0 { @@ -542,11 +601,10 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv } } - listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize) + listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize, s.HasSynced) if !s.started { - s.processor.addListener(listener) - return + return s.processor.addListener(listener), nil } // in order to safely join, we have to @@ -557,28 +615,37 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv s.blockDeltas.Lock() defer s.blockDeltas.Unlock() - s.processor.addListener(listener) + handle := s.processor.addListener(listener) for _, item := range s.indexer.List() { - listener.add(addNotification{newObj: item}) + // Note that we enqueue these notifications with the lock held + // and before returning the handle. That means there is never a + // chance for anyone to call the handle's HasSynced method in a + // state when it would falsely return true (i.e., when the + // shared informer is synced but it has not observed an Add + // with isInitialList being true, nor when the thread + // processing notifications somehow goes faster than this + // thread adding them and the counter is temporarily zero). + listener.add(addNotification{newObj: item, isInInitialList: true}) } + return handle, nil } -func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error { +func (s *sharedIndexInformer) HandleDeltas(obj interface{}, isInInitialList bool) error { s.blockDeltas.Lock() defer s.blockDeltas.Unlock() if deltas, ok := obj.(Deltas); ok { - return processDeltas(s, s.indexer, s.transform, deltas) + return processDeltas(s, s.indexer, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") } // Conforms to ResourceEventHandler -func (s *sharedIndexInformer) OnAdd(obj interface{}) { +func (s *sharedIndexInformer) OnAdd(obj interface{}, isInInitialList bool) { // Invocation of this function is locked under s.blockDeltas, so it is // save to distribute the notification s.cacheMutationDetector.AddObject(obj) - s.processor.distribute(addNotification{newObj: obj}, false) + s.processor.distribute(addNotification{newObj: obj, isInInitialList: isInInitialList}, false) } // Conforms to ResourceEventHandler @@ -610,6 +677,26 @@ func (s *sharedIndexInformer) OnDelete(old interface{}) { s.processor.distribute(deleteNotification{oldObj: old}, false) } +// IsStopped reports whether the informer has already been stopped +func (s *sharedIndexInformer) IsStopped() bool { + s.startedLock.Lock() + defer s.startedLock.Unlock() + return s.stopped +} + +func (s *sharedIndexInformer) RemoveEventHandler(handle ResourceEventHandlerRegistration) error { + s.startedLock.Lock() + defer s.startedLock.Unlock() + + // in order to safely remove, we have to + // 1. stop sending add/update/delete notifications + // 2. remove and stop listener + // 3. unblock + s.blockDeltas.Lock() + defer s.blockDeltas.Unlock() + return s.processor.removeListener(handle) +} + // sharedProcessor has a collection of processorListener and can // distribute a notification object to its listeners. There are two // kinds of distribute operations. The sync distributions go to a @@ -619,39 +706,85 @@ func (s *sharedIndexInformer) OnDelete(old interface{}) { type sharedProcessor struct { listenersStarted bool listenersLock sync.RWMutex - listeners []*processorListener - syncingListeners []*processorListener - clock clock.Clock - wg wait.Group + // Map from listeners to whether or not they are currently syncing + listeners map[*processorListener]bool + clock clock.Clock + wg wait.Group } -func (p *sharedProcessor) addListener(listener *processorListener) { +func (p *sharedProcessor) getListener(registration ResourceEventHandlerRegistration) *processorListener { + p.listenersLock.RLock() + defer p.listenersLock.RUnlock() + + if p.listeners == nil { + return nil + } + + if result, ok := registration.(*processorListener); ok { + if _, exists := p.listeners[result]; exists { + return result + } + } + + return nil +} + +func (p *sharedProcessor) addListener(listener *processorListener) ResourceEventHandlerRegistration { p.listenersLock.Lock() defer p.listenersLock.Unlock() - p.addListenerLocked(listener) + if p.listeners == nil { + p.listeners = make(map[*processorListener]bool) + } + + p.listeners[listener] = true + if p.listenersStarted { p.wg.Start(listener.run) p.wg.Start(listener.pop) } + + return listener } -func (p *sharedProcessor) addListenerLocked(listener *processorListener) { - p.listeners = append(p.listeners, listener) - p.syncingListeners = append(p.syncingListeners, listener) +func (p *sharedProcessor) removeListener(handle ResourceEventHandlerRegistration) error { + p.listenersLock.Lock() + defer p.listenersLock.Unlock() + + listener, ok := handle.(*processorListener) + if !ok { + return fmt.Errorf("invalid key type %t", handle) + } else if p.listeners == nil { + // No listeners are registered, do nothing + return nil + } else if _, exists := p.listeners[listener]; !exists { + // Listener is not registered, just do nothing + return nil + } + + delete(p.listeners, listener) + + if p.listenersStarted { + close(listener.addCh) + } + + return nil } func (p *sharedProcessor) distribute(obj interface{}, sync bool) { p.listenersLock.RLock() defer p.listenersLock.RUnlock() - if sync { - for _, listener := range p.syncingListeners { + for listener, isSyncing := range p.listeners { + switch { + case !sync: + // non-sync messages are delivered to every listener listener.add(obj) - } - } else { - for _, listener := range p.listeners { + case isSyncing: + // sync messages are delivered to every syncing listener listener.add(obj) + default: + // skipping a sync obj for a non-syncing listener } } } @@ -660,18 +793,27 @@ func (p *sharedProcessor) run(stopCh <-chan struct{}) { func() { p.listenersLock.RLock() defer p.listenersLock.RUnlock() - for _, listener := range p.listeners { + for listener := range p.listeners { p.wg.Start(listener.run) p.wg.Start(listener.pop) } p.listenersStarted = true }() <-stopCh - p.listenersLock.RLock() - defer p.listenersLock.RUnlock() - for _, listener := range p.listeners { + + p.listenersLock.Lock() + defer p.listenersLock.Unlock() + for listener := range p.listeners { close(listener.addCh) // Tell .pop() to stop. .pop() will tell .run() to stop } + + // Wipe out list of listeners since they are now closed + // (processorListener cannot be re-used) + p.listeners = nil + + // Reset to false since no listeners are running + p.listenersStarted = false + p.wg.Wait() // Wait for all .pop() and .run() to stop } @@ -681,16 +823,16 @@ func (p *sharedProcessor) shouldResync() bool { p.listenersLock.Lock() defer p.listenersLock.Unlock() - p.syncingListeners = []*processorListener{} - resyncNeeded := false now := p.clock.Now() - for _, listener := range p.listeners { + for listener := range p.listeners { // need to loop through all the listeners to see if they need to resync so we can prepare any // listeners that are going to be resyncing. - if listener.shouldResync(now) { + shouldResync := listener.shouldResync(now) + p.listeners[listener] = shouldResync + + if shouldResync { resyncNeeded = true - p.syncingListeners = append(p.syncingListeners, listener) listener.determineNextResync(now) } } @@ -701,8 +843,9 @@ func (p *sharedProcessor) resyncCheckPeriodChanged(resyncCheckPeriod time.Durati p.listenersLock.RLock() defer p.listenersLock.RUnlock() - for _, listener := range p.listeners { - resyncPeriod := determineResyncPeriod(listener.requestedResyncPeriod, resyncCheckPeriod) + for listener := range p.listeners { + resyncPeriod := determineResyncPeriod( + listener.requestedResyncPeriod, resyncCheckPeriod) listener.setResyncPeriod(resyncPeriod) } } @@ -724,6 +867,8 @@ type processorListener struct { handler ResourceEventHandler + syncTracker *synctrack.SingleFileTracker + // pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed. // There is one per listener, but a failing/stalled listener will have infinite pendingNotifications // added until we OOM. @@ -754,11 +899,18 @@ type processorListener struct { resyncLock sync.Mutex } -func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int) *processorListener { +// HasSynced returns true if the source informer has synced, and all +// corresponding events have been delivered. +func (p *processorListener) HasSynced() bool { + return p.syncTracker.HasSynced() +} + +func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int, hasSynced func() bool) *processorListener { ret := &processorListener{ nextCh: make(chan interface{}), addCh: make(chan interface{}), handler: handler, + syncTracker: &synctrack.SingleFileTracker{UpstreamHasSynced: hasSynced}, pendingNotifications: *buffer.NewRingGrowing(bufferSize), requestedResyncPeriod: requestedResyncPeriod, resyncPeriod: resyncPeriod, @@ -770,6 +922,9 @@ func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, res } func (p *processorListener) add(notification interface{}) { + if a, ok := notification.(addNotification); ok && a.isInInitialList { + p.syncTracker.Start() + } p.addCh <- notification } @@ -815,7 +970,10 @@ func (p *processorListener) run() { case updateNotification: p.handler.OnUpdate(notification.oldObj, notification.newObj) case addNotification: - p.handler.OnAdd(notification.newObj) + p.handler.OnAdd(notification.newObj, notification.isInInitialList) + if notification.isInInitialList { + p.syncTracker.Finished() + } case deleteNotification: p.handler.OnDelete(notification.oldObj) default: diff --git a/vendor/k8s.io/client-go/tools/cache/store.go b/vendor/k8s.io/client-go/tools/cache/store.go index 24ffabab7b5..5308ea74800 100644 --- a/vendor/k8s.io/client-go/tools/cache/store.go +++ b/vendor/k8s.io/client-go/tools/cache/store.go @@ -199,8 +199,11 @@ func (c *cache) Index(indexName string, obj interface{}) ([]interface{}, error) return c.cacheStorage.Index(indexName, obj) } -func (c *cache) IndexKeys(indexName, indexKey string) ([]string, error) { - return c.cacheStorage.IndexKeys(indexName, indexKey) +// IndexKeys returns the storage keys of the stored objects whose set of +// indexed values for the named index includes the given indexed value. +// The returned keys are suitable to pass to GetByKey(). +func (c *cache) IndexKeys(indexName, indexedValue string) ([]string, error) { + return c.cacheStorage.IndexKeys(indexName, indexedValue) } // ListIndexFuncValues returns the list of generated values of an Index func @@ -208,8 +211,10 @@ func (c *cache) ListIndexFuncValues(indexName string) []string { return c.cacheStorage.ListIndexFuncValues(indexName) } -func (c *cache) ByIndex(indexName, indexKey string) ([]interface{}, error) { - return c.cacheStorage.ByIndex(indexName, indexKey) +// ByIndex returns the stored objects whose set of indexed values +// for the named index includes the given indexed value. +func (c *cache) ByIndex(indexName, indexedValue string) ([]interface{}, error) { + return c.cacheStorage.ByIndex(indexName, indexedValue) } func (c *cache) AddIndexers(newIndexers Indexers) error { diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go new file mode 100644 index 00000000000..ce51da9af35 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go @@ -0,0 +1,83 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package synctrack + +import ( + "sync" + "sync/atomic" +) + +// Lazy defers the computation of `Evaluate` to when it is necessary. It is +// possible that Evaluate will be called in parallel from multiple goroutines. +type Lazy[T any] struct { + Evaluate func() (T, error) + + cache atomic.Pointer[cacheEntry[T]] +} + +type cacheEntry[T any] struct { + eval func() (T, error) + lock sync.RWMutex + result *T +} + +func (e *cacheEntry[T]) get() (T, error) { + if cur := func() *T { + e.lock.RLock() + defer e.lock.RUnlock() + return e.result + }(); cur != nil { + return *cur, nil + } + + e.lock.Lock() + defer e.lock.Unlock() + if e.result != nil { + return *e.result, nil + } + r, err := e.eval() + if err == nil { + e.result = &r + } + return r, err +} + +func (z *Lazy[T]) newCacheEntry() *cacheEntry[T] { + return &cacheEntry[T]{eval: z.Evaluate} +} + +// Notify should be called when something has changed necessitating a new call +// to Evaluate. +func (z *Lazy[T]) Notify() { z.cache.Swap(z.newCacheEntry()) } + +// Get should be called to get the current result of a call to Evaluate. If the +// current cached value is stale (due to a call to Notify), then Evaluate will +// be called synchronously. If subsequent calls to Get happen (without another +// Notify), they will all wait for the same return value. +// +// Error returns are not cached and will cause multiple calls to evaluate! +func (z *Lazy[T]) Get() (T, error) { + e := z.cache.Load() + if e == nil { + // Since we don't force a constructor, nil is a possible value. + // If multiple Gets race to set this, the swap makes sure only + // one wins. + z.cache.CompareAndSwap(nil, z.newCacheEntry()) + e = z.cache.Load() + } + return e.get() +} diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go new file mode 100644 index 00000000000..3fa2beb6b71 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go @@ -0,0 +1,120 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package synctrack contains utilities for helping controllers track whether +// they are "synced" or not, that is, whether they have processed all items +// from the informer's initial list. +package synctrack + +import ( + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// AsyncTracker helps propagate HasSynced in the face of multiple worker threads. +type AsyncTracker[T comparable] struct { + UpstreamHasSynced func() bool + + lock sync.Mutex + waiting sets.Set[T] +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *AsyncTracker[T]) Start(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting == nil { + t.waiting = sets.New[T](key) + } else { + t.waiting.Insert(key) + } +} + +// Finished should be called when finished processing a key which was part of +// the initial list. Since keys are tracked individually, nothing bad happens +// if you call Finished without a corresponding call to Start. This makes it +// easier to use this in combination with e.g. queues which don't make it easy +// to plumb through the isInInitialList boolean. +func (t *AsyncTracker[T]) Finished(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting != nil { + t.waiting.Delete(key) + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *AsyncTracker[T]) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we can't hold our lock while + // waiting on that or a user is likely to get a deadlock. + if !t.UpstreamHasSynced() { + return false + } + t.lock.Lock() + defer t.lock.Unlock() + return t.waiting.Len() == 0 +} + +// SingleFileTracker helps propagate HasSynced when events are processed in +// order (i.e. via a queue). +type SingleFileTracker struct { + // Important: count is used with atomic operations so it must be 64-bit + // aligned, otherwise atomic operations will panic. Having it at the top of + // the struct will guarantee that, even on 32-bit arches. + // See https://pkg.go.dev/sync/atomic#pkg-note-BUG for more information. + count int64 + + UpstreamHasSynced func() bool +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *SingleFileTracker) Start() { + atomic.AddInt64(&t.count, 1) +} + +// Finished should be called when finished processing a key which was part of +// the initial list. You must never call Finished() before (or without) its +// corresponding Start(), that is a logic error that could cause HasSynced to +// return a wrong value. To help you notice this should it happen, Finished() +// will panic if the internal counter goes negative. +func (t *SingleFileTracker) Finished() { + result := atomic.AddInt64(&t.count, -1) + if result < 0 { + panic("synctrack: negative counter; this logic error means HasSynced may return incorrect value") + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *SingleFileTracker) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we don't want to then act on a + // stale count value. + if !t.UpstreamHasSynced() { + return false + } + return atomic.LoadInt64(&t.count) <= 0 +} diff --git a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go index 6d58c0d690d..145e93ee535 100644 --- a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go +++ b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go @@ -47,9 +47,9 @@ type ThreadSafeStore interface { ListKeys() []string Replace(map[string]interface{}, string) Index(indexName string, obj interface{}) ([]interface{}, error) - IndexKeys(indexName, indexKey string) ([]string, error) + IndexKeys(indexName, indexedValue string) ([]string, error) ListIndexFuncValues(name string) []string - ByIndex(indexName, indexKey string) ([]interface{}, error) + ByIndex(indexName, indexedValue string) ([]interface{}, error) GetIndexers() Indexers // AddIndexers adds more indexers to this store. If you call this after you already have data @@ -59,15 +59,159 @@ type ThreadSafeStore interface { Resync() error } +// storeIndex implements the indexing functionality for Store interface +type storeIndex struct { + // indexers maps a name to an IndexFunc + indexers Indexers + // indices maps a name to an Index + indices Indices +} + +func (i *storeIndex) reset() { + i.indices = Indices{} +} + +func (i *storeIndex) getKeysFromIndex(indexName string, obj interface{}) (sets.String, error) { + indexFunc := i.indexers[indexName] + if indexFunc == nil { + return nil, fmt.Errorf("Index with name %s does not exist", indexName) + } + + indexedValues, err := indexFunc(obj) + if err != nil { + return nil, err + } + index := i.indices[indexName] + + var storeKeySet sets.String + if len(indexedValues) == 1 { + // In majority of cases, there is exactly one value matching. + // Optimize the most common path - deduping is not needed here. + storeKeySet = index[indexedValues[0]] + } else { + // Need to de-dupe the return list. + // Since multiple keys are allowed, this can happen. + storeKeySet = sets.String{} + for _, indexedValue := range indexedValues { + for key := range index[indexedValue] { + storeKeySet.Insert(key) + } + } + } + + return storeKeySet, nil +} + +func (i *storeIndex) getKeysByIndex(indexName, indexedValue string) (sets.String, error) { + indexFunc := i.indexers[indexName] + if indexFunc == nil { + return nil, fmt.Errorf("Index with name %s does not exist", indexName) + } + + index := i.indices[indexName] + return index[indexedValue], nil +} + +func (i *storeIndex) getIndexValues(indexName string) []string { + index := i.indices[indexName] + names := make([]string, 0, len(index)) + for key := range index { + names = append(names, key) + } + return names +} + +func (i *storeIndex) addIndexers(newIndexers Indexers) error { + oldKeys := sets.StringKeySet(i.indexers) + newKeys := sets.StringKeySet(newIndexers) + + if oldKeys.HasAny(newKeys.List()...) { + return fmt.Errorf("indexer conflict: %v", oldKeys.Intersection(newKeys)) + } + + for k, v := range newIndexers { + i.indexers[k] = v + } + return nil +} + +// updateIndices modifies the objects location in the managed indexes: +// - for create you must provide only the newObj +// - for update you must provide both the oldObj and the newObj +// - for delete you must provide only the oldObj +// updateIndices must be called from a function that already has a lock on the cache +func (i *storeIndex) updateIndices(oldObj interface{}, newObj interface{}, key string) { + var oldIndexValues, indexValues []string + var err error + for name, indexFunc := range i.indexers { + if oldObj != nil { + oldIndexValues, err = indexFunc(oldObj) + } else { + oldIndexValues = oldIndexValues[:0] + } + if err != nil { + panic(fmt.Errorf("unable to calculate an index entry for key %q on index %q: %v", key, name, err)) + } + + if newObj != nil { + indexValues, err = indexFunc(newObj) + } else { + indexValues = indexValues[:0] + } + if err != nil { + panic(fmt.Errorf("unable to calculate an index entry for key %q on index %q: %v", key, name, err)) + } + + index := i.indices[name] + if index == nil { + index = Index{} + i.indices[name] = index + } + + if len(indexValues) == 1 && len(oldIndexValues) == 1 && indexValues[0] == oldIndexValues[0] { + // We optimize for the most common case where indexFunc returns a single value which has not been changed + continue + } + + for _, value := range oldIndexValues { + i.deleteKeyFromIndex(key, value, index) + } + for _, value := range indexValues { + i.addKeyToIndex(key, value, index) + } + } +} + +func (i *storeIndex) addKeyToIndex(key, indexValue string, index Index) { + set := index[indexValue] + if set == nil { + set = sets.String{} + index[indexValue] = set + } + set.Insert(key) +} + +func (i *storeIndex) deleteKeyFromIndex(key, indexValue string, index Index) { + set := index[indexValue] + if set == nil { + return + } + set.Delete(key) + // If we don't delete the set when zero, indices with high cardinality + // short lived resources can cause memory to increase over time from + // unused empty sets. See `kubernetes/kubernetes/issues/84959`. + if len(set) == 0 { + delete(index, indexValue) + } +} + // threadSafeMap implements ThreadSafeStore type threadSafeMap struct { lock sync.RWMutex items map[string]interface{} - // indexers maps a name to an IndexFunc - indexers Indexers - // indices maps a name to an Index - indices Indices + // index implements the indexing functionality + index *storeIndex } func (c *threadSafeMap) Add(key string, obj interface{}) { @@ -79,14 +223,14 @@ func (c *threadSafeMap) Update(key string, obj interface{}) { defer c.lock.Unlock() oldObject := c.items[key] c.items[key] = obj - c.updateIndices(oldObject, obj, key) + c.index.updateIndices(oldObject, obj, key) } func (c *threadSafeMap) Delete(key string) { c.lock.Lock() defer c.lock.Unlock() if obj, exists := c.items[key]; exists { - c.updateIndices(obj, nil, key) + c.index.updateIndices(obj, nil, key) delete(c.items, key) } } @@ -126,9 +270,9 @@ func (c *threadSafeMap) Replace(items map[string]interface{}, resourceVersion st c.items = items // rebuild any index - c.indices = Indices{} + c.index.reset() for key, item := range c.items { - c.updateIndices(nil, item, key) + c.index.updateIndices(nil, item, key) } } @@ -138,32 +282,10 @@ func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, c.lock.RLock() defer c.lock.RUnlock() - indexFunc := c.indexers[indexName] - if indexFunc == nil { - return nil, fmt.Errorf("Index with name %s does not exist", indexName) - } - - indexedValues, err := indexFunc(obj) + storeKeySet, err := c.index.getKeysFromIndex(indexName, obj) if err != nil { return nil, err } - index := c.indices[indexName] - - var storeKeySet sets.String - if len(indexedValues) == 1 { - // In majority of cases, there is exactly one value matching. - // Optimize the most common path - deduping is not needed here. - storeKeySet = index[indexedValues[0]] - } else { - // Need to de-dupe the return list. - // Since multiple keys are allowed, this can happen. - storeKeySet = sets.String{} - for _, indexedValue := range indexedValues { - for key := range index[indexedValue] { - storeKeySet.Insert(key) - } - } - } list := make([]interface{}, 0, storeKeySet.Len()) for storeKey := range storeKeySet { @@ -177,14 +299,10 @@ func (c *threadSafeMap) ByIndex(indexName, indexedValue string) ([]interface{}, c.lock.RLock() defer c.lock.RUnlock() - indexFunc := c.indexers[indexName] - if indexFunc == nil { - return nil, fmt.Errorf("Index with name %s does not exist", indexName) + set, err := c.index.getKeysByIndex(indexName, indexedValue) + if err != nil { + return nil, err } - - index := c.indices[indexName] - - set := index[indexedValue] list := make([]interface{}, 0, set.Len()) for key := range set { list = append(list, c.items[key]) @@ -199,14 +317,10 @@ func (c *threadSafeMap) IndexKeys(indexName, indexedValue string) ([]string, err c.lock.RLock() defer c.lock.RUnlock() - indexFunc := c.indexers[indexName] - if indexFunc == nil { - return nil, fmt.Errorf("Index with name %s does not exist", indexName) + set, err := c.index.getKeysByIndex(indexName, indexedValue) + if err != nil { + return nil, err } - - index := c.indices[indexName] - - set := index[indexedValue] return set.List(), nil } @@ -214,16 +328,11 @@ func (c *threadSafeMap) ListIndexFuncValues(indexName string) []string { c.lock.RLock() defer c.lock.RUnlock() - index := c.indices[indexName] - names := make([]string, 0, len(index)) - for key := range index { - names = append(names, key) - } - return names + return c.index.getIndexValues(indexName) } func (c *threadSafeMap) GetIndexers() Indexers { - return c.indexers + return c.index.indexers } func (c *threadSafeMap) AddIndexers(newIndexers Indexers) error { @@ -234,87 +343,7 @@ func (c *threadSafeMap) AddIndexers(newIndexers Indexers) error { return fmt.Errorf("cannot add indexers to running index") } - oldKeys := sets.StringKeySet(c.indexers) - newKeys := sets.StringKeySet(newIndexers) - - if oldKeys.HasAny(newKeys.List()...) { - return fmt.Errorf("indexer conflict: %v", oldKeys.Intersection(newKeys)) - } - - for k, v := range newIndexers { - c.indexers[k] = v - } - return nil -} - -// updateIndices modifies the objects location in the managed indexes: -// - for create you must provide only the newObj -// - for update you must provide both the oldObj and the newObj -// - for delete you must provide only the oldObj -// updateIndices must be called from a function that already has a lock on the cache -func (c *threadSafeMap) updateIndices(oldObj interface{}, newObj interface{}, key string) { - var oldIndexValues, indexValues []string - var err error - for name, indexFunc := range c.indexers { - if oldObj != nil { - oldIndexValues, err = indexFunc(oldObj) - } else { - oldIndexValues = oldIndexValues[:0] - } - if err != nil { - panic(fmt.Errorf("unable to calculate an index entry for key %q on index %q: %v", key, name, err)) - } - - if newObj != nil { - indexValues, err = indexFunc(newObj) - } else { - indexValues = indexValues[:0] - } - if err != nil { - panic(fmt.Errorf("unable to calculate an index entry for key %q on index %q: %v", key, name, err)) - } - - index := c.indices[name] - if index == nil { - index = Index{} - c.indices[name] = index - } - - if len(indexValues) == 1 && len(oldIndexValues) == 1 && indexValues[0] == oldIndexValues[0] { - // We optimize for the most common case where indexFunc returns a single value which has not been changed - continue - } - - for _, value := range oldIndexValues { - c.deleteKeyFromIndex(key, value, index) - } - for _, value := range indexValues { - c.addKeyToIndex(key, value, index) - } - } -} - -func (c *threadSafeMap) addKeyToIndex(key, indexValue string, index Index) { - set := index[indexValue] - if set == nil { - set = sets.String{} - index[indexValue] = set - } - set.Insert(key) -} - -func (c *threadSafeMap) deleteKeyFromIndex(key, indexValue string, index Index) { - set := index[indexValue] - if set == nil { - return - } - set.Delete(key) - // If we don't delete the set when zero, indices with high cardinality - // short lived resources can cause memory to increase over time from - // unused empty sets. See `kubernetes/kubernetes/issues/84959`. - if len(set) == 0 { - delete(index, indexValue) - } + return c.index.addIndexers(newIndexers) } func (c *threadSafeMap) Resync() error { @@ -325,8 +354,10 @@ func (c *threadSafeMap) Resync() error { // NewThreadSafeStore creates a new instance of ThreadSafeStore. func NewThreadSafeStore(indexers Indexers, indices Indices) ThreadSafeStore { return &threadSafeMap{ - items: map[string]interface{}{}, - indexers: indexers, - indices: indices, + items: map[string]interface{}{}, + index: &storeIndex{ + indexers: indexers, + indices: indices, + }, } } diff --git a/vendor/k8s.io/client-go/tools/clientcmd/api/helpers.go b/vendor/k8s.io/client-go/tools/clientcmd/api/helpers.go index d677d6519be..dd5f9180673 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/api/helpers.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/api/helpers.go @@ -20,10 +20,11 @@ import ( "encoding/base64" "errors" "fmt" - "io/ioutil" "os" "path" "path/filepath" + "reflect" + "strings" ) func init() { @@ -82,21 +83,21 @@ func MinifyConfig(config *Config) error { } var ( - redactedBytes []byte dataOmittedBytes []byte + redactedBytes []byte ) -// Flatten redacts raw data entries from the config object for a human-readable view. +// ShortenConfig redacts raw data entries from the config object for a human-readable view. func ShortenConfig(config *Config) { - // trick json encoder into printing a human readable string in the raw data + // trick json encoder into printing a human-readable string in the raw data // by base64 decoding what we want to print. Relies on implementation of // http://golang.org/pkg/encoding/json/#Marshal using base64 to encode []byte for key, authInfo := range config.AuthInfos { if len(authInfo.ClientKeyData) > 0 { - authInfo.ClientKeyData = redactedBytes + authInfo.ClientKeyData = dataOmittedBytes } if len(authInfo.ClientCertificateData) > 0 { - authInfo.ClientCertificateData = redactedBytes + authInfo.ClientCertificateData = dataOmittedBytes } if len(authInfo.Token) > 0 { authInfo.Token = "REDACTED" @@ -111,7 +112,7 @@ func ShortenConfig(config *Config) { } } -// Flatten changes the config object into a self contained config (useful for making secrets) +// FlattenConfig changes the config object into a self-contained config (useful for making secrets) func FlattenConfig(config *Config) error { for key, authInfo := range config.AuthInfos { baseDir, err := MakeAbs(path.Dir(authInfo.LocationOfOrigin), "") @@ -152,7 +153,7 @@ func FlattenContent(path *string, contents *[]byte, baseDir string) error { var err error absPath := ResolvePath(*path, baseDir) - *contents, err = ioutil.ReadFile(absPath) + *contents, err = os.ReadFile(absPath) if err != nil { return err } @@ -189,3 +190,77 @@ func MakeAbs(path, base string) (string, error) { } return filepath.Join(base, path), nil } + +// RedactSecrets replaces any sensitive values with REDACTED +func RedactSecrets(config *Config) error { + return redactSecrets(reflect.ValueOf(config), false) +} + +func redactSecrets(curr reflect.Value, redact bool) error { + redactedBytes = []byte("REDACTED") + if !curr.IsValid() { + return nil + } + + actualCurrValue := curr + if curr.Kind() == reflect.Ptr { + actualCurrValue = curr.Elem() + } + + switch actualCurrValue.Kind() { + case reflect.Map: + for _, v := range actualCurrValue.MapKeys() { + err := redactSecrets(actualCurrValue.MapIndex(v), false) + if err != nil { + return err + } + } + return nil + + case reflect.String: + if redact { + if !actualCurrValue.IsZero() { + actualCurrValue.SetString("REDACTED") + } + } + return nil + + case reflect.Slice: + if actualCurrValue.Type() == reflect.TypeOf([]byte{}) && redact { + if !actualCurrValue.IsNil() { + actualCurrValue.SetBytes(redactedBytes) + } + return nil + } + for i := 0; i < actualCurrValue.Len(); i++ { + err := redactSecrets(actualCurrValue.Index(i), false) + if err != nil { + return err + } + } + return nil + + case reflect.Struct: + for fieldIndex := 0; fieldIndex < actualCurrValue.NumField(); fieldIndex++ { + currFieldValue := actualCurrValue.Field(fieldIndex) + currFieldType := actualCurrValue.Type().Field(fieldIndex) + currYamlTag := currFieldType.Tag.Get("datapolicy") + currFieldTypeYamlName := strings.Split(currYamlTag, ",")[0] + if currFieldTypeYamlName != "" { + err := redactSecrets(currFieldValue, true) + if err != nil { + return err + } + } else { + err := redactSecrets(currFieldValue, false) + if err != nil { + return err + } + } + } + return nil + + default: + return nil + } +} diff --git a/vendor/k8s.io/client-go/tools/clientcmd/api/types.go b/vendor/k8s.io/client-go/tools/clientcmd/api/types.go index 44a2fb94b15..71fb821b1e8 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/api/types.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/api/types.go @@ -93,6 +93,11 @@ type Cluster struct { // attach, port forward). // +optional ProxyURL string `json:"proxy-url,omitempty"` + // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful + // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on + // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. + // +optional + DisableCompression bool `json:"disable-compression,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // +optional Extensions map[string]runtime.Object `json:"extensions,omitempty"` diff --git a/vendor/k8s.io/client-go/tools/clientcmd/api/v1/types.go b/vendor/k8s.io/client-go/tools/clientcmd/api/v1/types.go index 757ed817b29..5018a72b1c0 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/api/v1/types.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/api/v1/types.go @@ -86,6 +86,11 @@ type Cluster struct { // attach, port forward). // +optional ProxyURL string `json:"proxy-url,omitempty"` + // DisableCompression allows client to opt-out of response compression for all requests to the server. This is useful + // to speed up requests (specifically lists) when client-server network bandwidth is ample, by saving time on + // compression (server-side) and decompression (client-side): https://github.com/kubernetes/kubernetes/issues/112296. + // +optional + DisableCompression bool `json:"disable-compression,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // +optional Extensions []NamedExtension `json:"extensions,omitempty"` diff --git a/vendor/k8s.io/client-go/tools/clientcmd/api/v1/zz_generated.conversion.go b/vendor/k8s.io/client-go/tools/clientcmd/api/v1/zz_generated.conversion.go index a13bae64da3..bdedc166695 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/api/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/api/v1/zz_generated.conversion.go @@ -257,6 +257,7 @@ func autoConvert_v1_Cluster_To_api_Cluster(in *Cluster, out *api.Cluster, s conv out.CertificateAuthority = in.CertificateAuthority out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := Convert_Slice_v1_NamedExtension_To_Map_string_To_runtime_Object(&in.Extensions, &out.Extensions, s); err != nil { return err } @@ -276,6 +277,7 @@ func autoConvert_api_Cluster_To_v1_Cluster(in *api.Cluster, out *Cluster, s conv out.CertificateAuthority = in.CertificateAuthority out.CertificateAuthorityData = *(*[]byte)(unsafe.Pointer(&in.CertificateAuthorityData)) out.ProxyURL = in.ProxyURL + out.DisableCompression = in.DisableCompression if err := Convert_Map_string_To_runtime_Object_To_Slice_v1_NamedExtension(&in.Extensions, &out.Extensions, s); err != nil { return err } diff --git a/vendor/k8s.io/client-go/tools/clientcmd/auth_loaders.go b/vendor/k8s.io/client-go/tools/clientcmd/auth_loaders.go index 5153a95a2a3..ce951e88d5f 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/auth_loaders.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/auth_loaders.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "golang.org/x/term" @@ -59,7 +58,7 @@ func (a *PromptingAuthLoader) LoadAuth(path string) (*clientauth.Info, error) { if err != nil { return &auth, err } - err = ioutil.WriteFile(path, data, 0600) + err = os.WriteFile(path, data, 0600) return &auth, err } authPtr, err := clientauth.LoadFromFile(path) diff --git a/vendor/k8s.io/client-go/tools/clientcmd/client_config.go b/vendor/k8s.io/client-go/tools/clientcmd/client_config.go index cc37c9fbf6b..ae0f01f3257 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/client_config.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/client_config.go @@ -19,7 +19,6 @@ package clientcmd import ( "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -165,6 +164,8 @@ func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) { clientConfig.Proxy = http.ProxyURL(u) } + clientConfig.DisableCompression = configClusterInfo.DisableCompression + if config.overrides != nil && len(config.overrides.Timeout) > 0 { timeout, err := ParseTimeout(config.overrides.Timeout) if err != nil { @@ -246,7 +247,7 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI mergedConfig.BearerToken = configAuthInfo.Token mergedConfig.BearerTokenFile = configAuthInfo.TokenFile } else if len(configAuthInfo.TokenFile) > 0 { - tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile) + tokenBytes, err := os.ReadFile(configAuthInfo.TokenFile) if err != nil { return nil, err } @@ -586,7 +587,7 @@ func (config *inClusterClientConfig) Namespace() (string, bool, error) { } // Fall back to the namespace associated with the service account token, if available - if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil { + if data, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil { if ns := strings.TrimSpace(string(data)); len(ns) > 0 { return ns, false, nil } diff --git a/vendor/k8s.io/client-go/tools/clientcmd/loader.go b/vendor/k8s.io/client-go/tools/clientcmd/loader.go index 78bd9ed8d5c..44de1d41d83 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/loader.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/loader.go @@ -18,7 +18,6 @@ package clientcmd import ( "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -160,8 +159,10 @@ func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules { // Load starts by running the MigrationRules and then // takes the loading rules and returns a Config object based on following rules. -// if the ExplicitPath, return the unmerged explicit file -// Otherwise, return a merged config based on the Precedence slice +// +// if the ExplicitPath, return the unmerged explicit file +// Otherwise, return a merged config based on the Precedence slice +// // A missing ExplicitPath file produces an error. Empty filenames or other missing files are ignored. // Read errors or files with non-deserializable content produce errors. // The first file to set a particular map key wins and map key's value is never changed. @@ -281,12 +282,12 @@ func (rules *ClientConfigLoadingRules) Migrate() error { return fmt.Errorf("cannot migrate %v to %v because it is a directory", source, destination) } - data, err := ioutil.ReadFile(source) + data, err := os.ReadFile(source) if err != nil { return err } // destination is created with mode 0666 before umask - err = ioutil.WriteFile(destination, data, 0666) + err = os.WriteFile(destination, data, 0666) if err != nil { return err } @@ -361,7 +362,7 @@ func (rules *ClientConfigLoadingRules) IsDefaultConfig(config *restclient.Config // LoadFromFile takes a filename and deserializes the contents into Config object func LoadFromFile(filename string) (*clientcmdapi.Config, error) { - kubeconfigBytes, err := ioutil.ReadFile(filename) + kubeconfigBytes, err := os.ReadFile(filename) if err != nil { return nil, err } @@ -427,7 +428,7 @@ func WriteToFile(config clientcmdapi.Config, filename string) error { } } - if err := ioutil.WriteFile(filename, content, 0600); err != nil { + if err := os.WriteFile(filename, content, 0600); err != nil { return err } return nil diff --git a/vendor/k8s.io/client-go/tools/clientcmd/overrides.go b/vendor/k8s.io/client-go/tools/clientcmd/overrides.go index 4c290db5547..483e515320d 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/overrides.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/overrides.go @@ -74,6 +74,7 @@ type ClusterOverrideFlags struct { InsecureSkipTLSVerify FlagInfo TLSServerName FlagInfo ProxyURL FlagInfo + DisableCompression FlagInfo } // FlagInfo contains information about how to register a flag. This struct is useful if you want to provide a way for an extender to @@ -143,25 +144,26 @@ func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo { } const ( - FlagClusterName = "cluster" - FlagAuthInfoName = "user" - FlagContext = "context" - FlagNamespace = "namespace" - FlagAPIServer = "server" - FlagTLSServerName = "tls-server-name" - FlagInsecure = "insecure-skip-tls-verify" - FlagCertFile = "client-certificate" - FlagKeyFile = "client-key" - FlagCAFile = "certificate-authority" - FlagEmbedCerts = "embed-certs" - FlagBearerToken = "token" - FlagImpersonate = "as" - FlagImpersonateUID = "as-uid" - FlagImpersonateGroup = "as-group" - FlagUsername = "username" - FlagPassword = "password" - FlagTimeout = "request-timeout" - FlagProxyURL = "proxy-url" + FlagClusterName = "cluster" + FlagAuthInfoName = "user" + FlagContext = "context" + FlagNamespace = "namespace" + FlagAPIServer = "server" + FlagTLSServerName = "tls-server-name" + FlagInsecure = "insecure-skip-tls-verify" + FlagCertFile = "client-certificate" + FlagKeyFile = "client-key" + FlagCAFile = "certificate-authority" + FlagEmbedCerts = "embed-certs" + FlagBearerToken = "token" + FlagImpersonate = "as" + FlagImpersonateUID = "as-uid" + FlagImpersonateGroup = "as-group" + FlagUsername = "username" + FlagPassword = "password" + FlagTimeout = "request-timeout" + FlagProxyURL = "proxy-url" + FlagDisableCompression = "disable-compression" ) // RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing @@ -198,6 +200,7 @@ func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags { InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"}, TLSServerName: FlagInfo{prefix + FlagTLSServerName, "", "", "If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used."}, ProxyURL: FlagInfo{prefix + FlagProxyURL, "", "", "If provided, this URL will be used to connect via proxy"}, + DisableCompression: FlagInfo{prefix + FlagDisableCompression, "", "", "If true, opt-out of response compression for all requests to the server"}, } } @@ -238,6 +241,7 @@ func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, f flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify) flagNames.TLSServerName.BindStringFlag(flags, &clusterInfo.TLSServerName) flagNames.ProxyURL.BindStringFlag(flags, &clusterInfo.ProxyURL) + flagNames.DisableCompression.BindBoolFlag(flags, &clusterInfo.DisableCompression) } // BindFlags is a convenience method to bind the specified flags to their associated variables diff --git a/vendor/k8s.io/client-go/tools/clientcmd/validation.go b/vendor/k8s.io/client-go/tools/clientcmd/validation.go index 2ae1eb706af..088972ef65c 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/validation.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/validation.go @@ -204,8 +204,19 @@ func ConfirmUsable(config clientcmdapi.Config, passedContextName string) error { if exists { validationErrors = append(validationErrors, validateContext(contextName, *context, config)...) - validationErrors = append(validationErrors, validateAuthInfo(context.AuthInfo, *config.AuthInfos[context.AuthInfo])...) - validationErrors = append(validationErrors, validateClusterInfo(context.Cluster, *config.Clusters[context.Cluster])...) + + // Default to empty users and clusters and let the validation function report an error. + authInfo := config.AuthInfos[context.AuthInfo] + if authInfo == nil { + authInfo = &clientcmdapi.AuthInfo{} + } + validationErrors = append(validationErrors, validateAuthInfo(context.AuthInfo, *authInfo)...) + + cluster := config.Clusters[context.Cluster] + if cluster == nil { + cluster = &clientcmdapi.Cluster{} + } + validationErrors = append(validationErrors, validateClusterInfo(context.Cluster, *cluster)...) } return newErrConfigurationInvalid(validationErrors) diff --git a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go index 03a13e6b63f..940e716175a 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go @@ -64,9 +64,8 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" rl "k8s.io/client-go/tools/leaderelection/resourcelock" - "k8s.io/utils/clock" - "k8s.io/klog/v2" + "k8s.io/utils/clock" ) const ( @@ -161,7 +160,7 @@ type LeaderElectionConfig struct { // lifecycle events of the LeaderElector. These are invoked asynchronously. // // possible future callbacks: -// * OnChallenge() +// - OnChallenge() type LeaderCallbacks struct { // OnStartedLeading is called when a LeaderElector client starts leading OnStartedLeading func(context.Context) @@ -199,9 +198,7 @@ type LeaderElector struct { // stopped holding the leader lease func (le *LeaderElector) Run(ctx context.Context) { defer runtime.HandleCrash() - defer func() { - le.config.Callbacks.OnStoppedLeading() - }() + defer le.config.Callbacks.OnStoppedLeading() if !le.acquire(ctx) { return // ctx signalled done @@ -263,6 +260,7 @@ func (le *LeaderElector) acquire(ctx context.Context) bool { // renew loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew fails or ctx signals done. func (le *LeaderElector) renew(ctx context.Context) { + defer le.config.Lock.RecordEvent("stopped leading") ctx, cancel := context.WithCancel(ctx) defer cancel() wait.Until(func() { @@ -278,7 +276,6 @@ func (le *LeaderElector) renew(ctx context.Context) { klog.V(5).Infof("successfully renewed lease %v", desc) return } - le.config.Lock.RecordEvent("stopped leading") le.metrics.leaderOff(le.config.Name) klog.Infof("failed to renew lease %v: %v", desc, err) cancel() @@ -295,7 +292,7 @@ func (le *LeaderElector) release() bool { if !le.IsLeader() { return true } - now := metav1.Now() + now := metav1.NewTime(le.clock.Now()) leaderElectionRecord := rl.LeaderElectionRecord{ LeaderTransitions: le.observedRecord.LeaderTransitions, LeaseDurationSeconds: 1, @@ -315,7 +312,7 @@ func (le *LeaderElector) release() bool { // else it tries to renew the lease if it has already been acquired. Returns true // on success else returns false. func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool { - now := metav1.Now() + now := metav1.NewTime(le.clock.Now()) leaderElectionRecord := rl.LeaderElectionRecord{ HolderIdentity: le.config.Lock.Identity(), LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second), @@ -347,7 +344,7 @@ func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool { le.observedRawRecord = oldLeaderElectionRawRecord } if len(oldLeaderElectionRecord.HolderIdentity) > 0 && - le.observedTime.Add(le.config.LeaseDuration).After(now.Time) && + le.observedTime.Add(time.Second*time.Duration(oldLeaderElectionRecord.LeaseDurationSeconds)).After(now.Time) && !le.IsLeader() { klog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity) return false diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/configmaplock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/configmaplock.go index 5702728982c..e811fff03c5 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/configmaplock.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/configmaplock.go @@ -44,11 +44,11 @@ type configMapLock struct { // Get returns the election record from a ConfigMap Annotation func (cml *configMapLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) { var record LeaderElectionRecord - var err error - cml.cm, err = cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Get(ctx, cml.ConfigMapMeta.Name, metav1.GetOptions{}) + cm, err := cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Get(ctx, cml.ConfigMapMeta.Name, metav1.GetOptions{}) if err != nil { return nil, nil, err } + cml.cm = cm if cml.cm.Annotations == nil { cml.cm.Annotations = make(map[string]string) } diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/endpointslock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/endpointslock.go index af3fa162695..eb36d2210a3 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/endpointslock.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/endpointslock.go @@ -39,11 +39,11 @@ type endpointsLock struct { // Get returns the election record from a Endpoints Annotation func (el *endpointsLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) { var record LeaderElectionRecord - var err error - el.e, err = el.Client.Endpoints(el.EndpointsMeta.Namespace).Get(ctx, el.EndpointsMeta.Name, metav1.GetOptions{}) + ep, err := el.Client.Endpoints(el.EndpointsMeta.Namespace).Get(ctx, el.EndpointsMeta.Name, metav1.GetOptions{}) if err != nil { return nil, nil, err } + el.e = ep if el.e.Annotations == nil { el.e.Annotations = make(map[string]string) } diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go index c6e23bda161..05b5b202379 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go @@ -68,7 +68,7 @@ const ( // name: '*' // namespace: kube-system EndpointsLeasesResourceLock = "endpointsleases" - // When using EndpointsLeasesResourceLock, you need to ensure that + // When using ConfigMapsLeasesResourceLock, you need to ensure that // API Priority & Fairness is configured with non-default flow-schema // that will catch the necessary operations on leader-election related // configmap objects. diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go index ab80d7f1588..8a9d7d60f2d 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go @@ -39,11 +39,11 @@ type LeaseLock struct { // Get returns the election record from a Lease spec func (ll *LeaseLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) { - var err error - ll.lease, err = ll.Client.Leases(ll.LeaseMeta.Namespace).Get(ctx, ll.LeaseMeta.Name, metav1.GetOptions{}) + lease, err := ll.Client.Leases(ll.LeaseMeta.Namespace).Get(ctx, ll.LeaseMeta.Name, metav1.GetOptions{}) if err != nil { return nil, nil, err } + ll.lease = lease record := LeaseSpecToLeaderElectionRecord(&ll.lease.Spec) recordByte, err := json.Marshal(*record) if err != nil { @@ -117,10 +117,10 @@ func LeaseSpecToLeaderElectionRecord(spec *coordinationv1.LeaseSpec) *LeaderElec r.LeaderTransitions = int(*spec.LeaseTransitions) } if spec.AcquireTime != nil { - r.AcquireTime = metav1.Time{spec.AcquireTime.Time} + r.AcquireTime = metav1.Time{Time: spec.AcquireTime.Time} } if spec.RenewTime != nil { - r.RenewTime = metav1.Time{spec.RenewTime.Time} + r.RenewTime = metav1.Time{Time: spec.RenewTime.Time} } return &r @@ -132,8 +132,8 @@ func LeaderElectionRecordToLeaseSpec(ler *LeaderElectionRecord) coordinationv1.L return coordinationv1.LeaseSpec{ HolderIdentity: &ler.HolderIdentity, LeaseDurationSeconds: &leaseDurationSeconds, - AcquireTime: &metav1.MicroTime{ler.AcquireTime.Time}, - RenewTime: &metav1.MicroTime{ler.RenewTime.Time}, + AcquireTime: &metav1.MicroTime{Time: ler.AcquireTime.Time}, + RenewTime: &metav1.MicroTime{Time: ler.RenewTime.Time}, LeaseTransitions: &leaseTransitions, } } diff --git a/vendor/k8s.io/client-go/tools/metrics/metrics.go b/vendor/k8s.io/client-go/tools/metrics/metrics.go index 6c684c7fa12..f36430dc3ed 100644 --- a/vendor/k8s.io/client-go/tools/metrics/metrics.go +++ b/vendor/k8s.io/client-go/tools/metrics/metrics.go @@ -58,6 +58,12 @@ type CallsMetric interface { Increment(exitCode int, callStatus string) } +// RetryMetric counts the number of retries sent to the server +// partitioned by code, method, and host. +type RetryMetric interface { + IncrementRetry(ctx context.Context, code string, method string, host string) +} + var ( // ClientCertExpiry is the expiry time of a client certificate ClientCertExpiry ExpiryMetric = noopExpiry{} @@ -76,6 +82,9 @@ var ( // ExecPluginCalls is the number of calls made to an exec plugin, partitioned by // exit code and call status. ExecPluginCalls CallsMetric = noopCalls{} + // RequestRetry is the retry metric that tracks the number of + // retries sent to the server. + RequestRetry RetryMetric = noopRetry{} ) // RegisterOpts contains all the metrics to register. Metrics may be nil. @@ -88,6 +97,7 @@ type RegisterOpts struct { RateLimiterLatency LatencyMetric RequestResult ResultMetric ExecPluginCalls CallsMetric + RequestRetry RetryMetric } // Register registers metrics for the rest client to use. This can @@ -118,6 +128,9 @@ func Register(opts RegisterOpts) { if opts.ExecPluginCalls != nil { ExecPluginCalls = opts.ExecPluginCalls } + if opts.RequestRetry != nil { + RequestRetry = opts.RequestRetry + } }) } @@ -144,3 +157,7 @@ func (noopResult) Increment(context.Context, string, string, string) {} type noopCalls struct{} func (noopCalls) Increment(int, string) {} + +type noopRetry struct{} + +func (noopRetry) IncrementRetry(context.Context, string, string, string) {} diff --git a/vendor/k8s.io/client-go/tools/pager/pager.go b/vendor/k8s.io/client-go/tools/pager/pager.go index 805859e092b..9ba988f6856 100644 --- a/vendor/k8s.io/client-go/tools/pager/pager.go +++ b/vendor/k8s.io/client-go/tools/pager/pager.go @@ -203,6 +203,11 @@ func (p *ListPager) eachListChunkBuffered(ctx context.Context, options metav1.Li }() for o := range chunkC { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } err := fn(o) if err != nil { return err // any fn error should be returned immediately diff --git a/vendor/k8s.io/client-go/tools/record/event.go b/vendor/k8s.io/client-go/tools/record/event.go index b901d2e8a0a..4899b362dff 100644 --- a/vendor/k8s.io/client-go/tools/record/event.go +++ b/vendor/k8s.io/client-go/tools/record/event.go @@ -17,6 +17,7 @@ limitations under the License. package record import ( + "context" "fmt" "math/rand" "time" @@ -92,7 +93,7 @@ type EventRecorder interface { // Event constructs an event from the given information and puts it in the queue for sending. // 'object' is the object this event is about. Event will make a reference-- or you may also // pass a reference to the object directly. - // 'type' of this event, and can be one of Normal, Warning. New types could be added in future + // 'eventtype' of this event, and can be one of Normal, Warning. New types could be added in future // 'reason' is the reason this event is generated. 'reason' should be short and unique; it // should be in UpperCamelCase format (starting with a capital letter). "reason" will be used // to automate handling of events, so imagine people writing switch statements to handle them. @@ -132,7 +133,9 @@ type EventBroadcaster interface { // with the event source set to the given event source. NewRecorder(scheme *runtime.Scheme, source v1.EventSource) EventRecorder - // Shutdown shuts down the broadcaster + // Shutdown shuts down the broadcaster. Once the broadcaster is shut + // down, it will only try to record an event in a sink once before + // giving up on it with an error message. Shutdown() } @@ -157,31 +160,34 @@ func (a *EventRecorderAdapter) Eventf(regarding, _ runtime.Object, eventtype, re // Creates a new event broadcaster. func NewBroadcaster() EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) } func NewBroadcasterForTests(sleepDuration time.Duration) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: sleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), sleepDuration) } func NewBroadcasterWithCorrelatorOptions(options CorrelatorOptions) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - options: options, + eventBroadcaster := newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) + eventBroadcaster.options = options + return eventBroadcaster +} + +func newEventBroadcaster(broadcaster *watch.Broadcaster, sleepDuration time.Duration) *eventBroadcasterImpl { + eventBroadcaster := &eventBroadcasterImpl{ + Broadcaster: broadcaster, + sleepDuration: sleepDuration, } + eventBroadcaster.cancelationCtx, eventBroadcaster.cancel = context.WithCancel(context.Background()) + return eventBroadcaster } type eventBroadcasterImpl struct { *watch.Broadcaster - sleepDuration time.Duration - options CorrelatorOptions + sleepDuration time.Duration + options CorrelatorOptions + cancelationCtx context.Context + cancel func() } // StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink. @@ -191,15 +197,16 @@ func (e *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interf eventCorrelator := NewEventCorrelatorWithOptions(e.options) return e.StartEventWatcher( func(event *v1.Event) { - recordToSink(sink, event, eventCorrelator, e.sleepDuration) + e.recordToSink(sink, event, eventCorrelator) }) } func (e *eventBroadcasterImpl) Shutdown() { e.Broadcaster.Shutdown() + e.cancel() } -func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, sleepDuration time.Duration) { +func (e *eventBroadcasterImpl) recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator) { // Make a copy before modification, because there could be multiple listeners. // Events are safe to copy like this. eventCopy := *event @@ -221,12 +228,18 @@ func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrela klog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event) break } + // Randomize the first sleep so that various clients won't all be // synced up if the master goes down. + delay := e.sleepDuration if tries == 1 { - time.Sleep(time.Duration(float64(sleepDuration) * rand.Float64())) - } else { - time.Sleep(sleepDuration) + delay = time.Duration(float64(delay) * rand.Float64()) + } + select { + case <-e.cancelationCtx.Done(): + klog.Errorf("Unable to write event '%#v' (broadcaster is shut down)", event) + return + case <-time.After(delay): } } } @@ -298,7 +311,10 @@ func (e *eventBroadcasterImpl) StartStructuredLogging(verbosity klog.Level) watc // StartEventWatcher starts sending events received from this EventBroadcaster to the given event handler function. // The return value can be ignored or used to stop recording, if desired. func (e *eventBroadcasterImpl) StartEventWatcher(eventHandler func(*v1.Event)) watch.Interface { - watcher := e.Watch() + watcher, err := e.Watch() + if err != nil { + klog.Errorf("Unable start event watcher: '%v' (will not retry!)", err) + } go func() { defer utilruntime.HandleCrash() for watchEvent := range watcher.ResultChan() { @@ -346,7 +362,12 @@ func (recorder *recorderImpl) generateEvent(object runtime.Object, annotations m // when we go to shut down this broadcaster. Just drop events if we get overloaded, // and log an error if that happens (we've configured the broadcaster to drop // outgoing events anyway). - if sent := recorder.ActionOrDrop(watch.Added, event); !sent { + sent, err := recorder.ActionOrDrop(watch.Added, event) + if err != nil { + klog.Errorf("unable to record event: %v (will not retry!)", err) + return + } + if !sent { klog.Errorf("unable to record event: too many queued events, dropped event %#v", event) } } diff --git a/vendor/k8s.io/client-go/tools/record/events_cache.go b/vendor/k8s.io/client-go/tools/record/events_cache.go index 4f041e8fd26..abba06362aa 100644 --- a/vendor/k8s.io/client-go/tools/record/events_cache.go +++ b/vendor/k8s.io/client-go/tools/record/events_cache.go @@ -235,10 +235,10 @@ type aggregateRecord struct { // EventAggregate checks if a similar event has been seen according to the // aggregation configuration (max events, max interval, etc) and returns: // -// - The (potentially modified) event that should be created -// - The cache key for the event, for correlation purposes. This will be set to -// the full key for normal events, and to the result of -// EventAggregatorMessageFunc for aggregate events. +// - The (potentially modified) event that should be created +// - The cache key for the event, for correlation purposes. This will be set to +// the full key for normal events, and to the result of +// EventAggregatorMessageFunc for aggregate events. func (e *EventAggregator) EventAggregate(newEvent *v1.Event) (*v1.Event, string) { now := metav1.NewTime(e.clock.Now()) var record aggregateRecord @@ -427,14 +427,14 @@ type EventCorrelateResult struct { // prior to interacting with the API server to record the event. // // The default behavior is as follows: -// * Aggregation is performed if a similar event is recorded 10 times +// - Aggregation is performed if a similar event is recorded 10 times // in a 10 minute rolling interval. A similar event is an event that varies only by // the Event.Message field. Rather than recording the precise event, aggregation // will create a new event whose message reports that it has combined events with // the same reason. -// * Events are incrementally counted if the exact same event is encountered multiple +// - Events are incrementally counted if the exact same event is encountered multiple // times. -// * A source may burst 25 events about an object, but has a refill rate budget +// - A source may burst 25 events about an object, but has a refill rate budget // per object of 1 event every 5 minutes to control long-tail of spam. func NewEventCorrelator(clock clock.PassiveClock) *EventCorrelator { cacheSize := maxLruCacheEntries diff --git a/vendor/k8s.io/client-go/tools/record/fake.go b/vendor/k8s.io/client-go/tools/record/fake.go index 0b3f344a977..fda4ad8ff8a 100644 --- a/vendor/k8s.io/client-go/tools/record/fake.go +++ b/vendor/k8s.io/client-go/tools/record/fake.go @@ -41,20 +41,31 @@ func objectString(object runtime.Object, includeObject bool) string { ) } -func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { - if f.Events != nil { - f.Events <- fmt.Sprintf("%s %s %s%s", eventtype, reason, message, objectString(object, f.IncludeObject)) +func annotationsString(annotations map[string]string) string { + if len(annotations) == 0 { + return "" + } else { + return " " + fmt.Sprint(annotations) } } -func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { +func (f *FakeRecorder) writeEvent(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { if f.Events != nil { - f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + objectString(object, f.IncludeObject) + f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + + objectString(object, f.IncludeObject) + annotationsString(annotations) } } +func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { + f.writeEvent(object, nil, eventtype, reason, "%s", message) +} + +func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + f.writeEvent(object, nil, eventtype, reason, messageFmt, args...) +} + func (f *FakeRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { - f.Eventf(object, eventtype, reason, messageFmt, args...) + f.writeEvent(object, annotations, eventtype, reason, messageFmt, args...) } // NewFakeRecorder creates new fake event recorder with event channel with diff --git a/vendor/k8s.io/client-go/tools/reference/ref.go b/vendor/k8s.io/client-go/tools/reference/ref.go index 442a991cc47..5d4ec374345 100644 --- a/vendor/k8s.io/client-go/tools/reference/ref.go +++ b/vendor/k8s.io/client-go/tools/reference/ref.go @@ -34,7 +34,7 @@ var ( // GetReference returns an ObjectReference which refers to the given // object, or an error if the object doesn't follow the conventions // that would allow this. -// TODO: should take a meta.Interface see http://issue.k8s.io/7127 +// TODO: should take a meta.Interface see https://issue.k8s.io/7127 func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*v1.ObjectReference, error) { if obj == nil { return nil, ErrNilObject diff --git a/vendor/k8s.io/client-go/transport/cache.go b/vendor/k8s.io/client-go/transport/cache.go index f4a864d0536..edcc6d1d481 100644 --- a/vendor/k8s.io/client-go/transport/cache.go +++ b/vendor/k8s.io/client-go/transport/cache.go @@ -37,6 +37,11 @@ type tlsTransportCache struct { transports map[tlsCacheKey]*http.Transport } +// DialerStopCh is stop channel that is passed down to dynamic cert dialer. +// It's exposed as variable for testing purposes to avoid testing for goroutine +// leakages. +var DialerStopCh = wait.NeverStop + const idleConnsPerHost = 25 var tlsCache = &tlsTransportCache{transports: make(map[tlsCacheKey]*http.Transport)} @@ -88,13 +93,13 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { return nil, err } // The options didn't require a custom TLS config - if tlsConfig == nil && config.Dial == nil && config.Proxy == nil { + if tlsConfig == nil && config.DialHolder == nil && config.Proxy == nil { return http.DefaultTransport, nil } var dial func(ctx context.Context, network, address string) (net.Conn, error) - if config.Dial != nil { - dial = config.Dial + if config.DialHolder != nil { + dial = config.DialHolder.Dial } else { dial = (&net.Dialer{ Timeout: 30 * time.Second, @@ -104,11 +109,11 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { // If we use are reloading files, we need to handle certificate rotation properly // TODO(jackkleeman): We can also add rotation here when config.HasCertCallback() is true - if config.TLS.ReloadTLSFiles { + if config.TLS.ReloadTLSFiles && tlsConfig != nil && tlsConfig.GetClientCertificate != nil { dynamicCertDialer := certRotatingDialer(tlsConfig.GetClientCertificate, dial) tlsConfig.GetClientCertificate = dynamicCertDialer.GetClientCertificate dial = dynamicCertDialer.connDialer.DialContext - go dynamicCertDialer.Run(wait.NeverStop) + go dynamicCertDialer.Run(DialerStopCh) } proxy := http.ProxyFromEnvironment @@ -144,14 +149,6 @@ func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) { // cannot determine equality for functions return tlsCacheKey{}, false, nil } - if c.Dial != nil && c.DialHolder == nil { - // cannot determine equality for dial function that doesn't have non-nil DialHolder set as well - return tlsCacheKey{}, false, nil - } - if c.TLS.GetCert != nil && c.TLS.GetCertHolder == nil { - // cannot determine equality for getCert function that doesn't have non-nil GetCertHolder set as well - return tlsCacheKey{}, false, nil - } k := tlsCacheKey{ insecure: c.TLS.Insecure, diff --git a/vendor/k8s.io/client-go/transport/cache_go118.go b/vendor/k8s.io/client-go/transport/cache_go118.go new file mode 100644 index 00000000000..d21d5137d4d --- /dev/null +++ b/vendor/k8s.io/client-go/transport/cache_go118.go @@ -0,0 +1,24 @@ +//go:build go1.18 + +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package transport + +// assert at compile time that tlsCacheKey is comparable in a way that will never panic at runtime. +var _ = isComparable[tlsCacheKey] + +func isComparable[T comparable]() {} diff --git a/vendor/k8s.io/client-go/transport/config.go b/vendor/k8s.io/client-go/transport/config.go index fd853c0b39d..d8a3d64b309 100644 --- a/vendor/k8s.io/client-go/transport/config.go +++ b/vendor/k8s.io/client-go/transport/config.go @@ -67,11 +67,8 @@ type Config struct { // instead of setting this value directly. WrapTransport WrapperFunc - // Dial specifies the dial function for creating unencrypted TCP connections. - // If specified, this transport will be non-cacheable unless DialHolder is also set. - Dial func(ctx context.Context, network, address string) (net.Conn, error) - // DialHolder can be populated to make transport configs cacheable. - // If specified, DialHolder.Dial must be equal to Dial. + // DialHolder specifies the dial function for creating unencrypted TCP connections. + // This struct indirection is used to make transport configs cacheable. DialHolder *DialHolder // Proxy is the proxy func to be used for all requests made by this @@ -121,7 +118,7 @@ func (c *Config) HasCertAuth() bool { // HasCertCallback returns whether the configuration has certificate callback or not. func (c *Config) HasCertCallback() bool { - return c.TLS.GetCert != nil + return c.TLS.GetCertHolder != nil } // Wrap adds a transport middleware function that will give the caller @@ -153,10 +150,7 @@ type TLSConfig struct { NextProtos []string // Callback that returns a TLS client certificate. CertData, CertFile, KeyData and KeyFile supercede this field. - // If specified, this transport is non-cacheable unless CertHolder is populated. - GetCert func() (*tls.Certificate, error) - // CertHolder can be populated to make transport configs that set GetCert cacheable. - // If set, CertHolder.GetCert must be equal to GetCert. + // This struct indirection is used to make transport configs cacheable. GetCertHolder *GetCertHolder } diff --git a/vendor/k8s.io/client-go/transport/round_trippers.go b/vendor/k8s.io/client-go/transport/round_trippers.go index 26a89f93be4..e2d1dcc9a9c 100644 --- a/vendor/k8s.io/client-go/transport/round_trippers.go +++ b/vendor/k8s.io/client-go/transport/round_trippers.go @@ -491,7 +491,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e DNSDone: func(info httptrace.DNSDoneInfo) { reqInfo.muTrace.Lock() defer reqInfo.muTrace.Unlock() - reqInfo.DNSLookup = time.Now().Sub(dnsStart) + reqInfo.DNSLookup = time.Since(dnsStart) klog.Infof("HTTP Trace: DNS Lookup for %s resolved to %v", host, info.Addrs) }, // Dial @@ -503,7 +503,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e ConnectDone: func(network, addr string, err error) { reqInfo.muTrace.Lock() defer reqInfo.muTrace.Unlock() - reqInfo.Dialing = time.Now().Sub(dialStart) + reqInfo.Dialing = time.Since(dialStart) if err != nil { klog.Infof("HTTP Trace: Dial to %s:%s failed: %v", network, addr, err) } else { @@ -517,7 +517,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e TLSHandshakeDone: func(_ tls.ConnectionState, _ error) { reqInfo.muTrace.Lock() defer reqInfo.muTrace.Unlock() - reqInfo.TLSHandshake = time.Now().Sub(tlsStart) + reqInfo.TLSHandshake = time.Since(tlsStart) }, // Connection (it can be DNS + Dial or just the time to get one from the connection pool) GetConn: func(hostPort string) { @@ -526,7 +526,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e GotConn: func(info httptrace.GotConnInfo) { reqInfo.muTrace.Lock() defer reqInfo.muTrace.Unlock() - reqInfo.GetConnection = time.Now().Sub(getConn) + reqInfo.GetConnection = time.Since(getConn) reqInfo.ConnectionReused = info.Reused }, // Server Processing (time since we wrote the request until first byte is received) @@ -538,7 +538,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e GotFirstResponseByte: func() { reqInfo.muTrace.Lock() defer reqInfo.muTrace.Unlock() - reqInfo.ServerProcessing = time.Now().Sub(serverStart) + reqInfo.ServerProcessing = time.Since(serverStart) }, } req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) diff --git a/vendor/k8s.io/client-go/transport/token_source.go b/vendor/k8s.io/client-go/transport/token_source.go index 68a0a704fe4..8e312800f73 100644 --- a/vendor/k8s.io/client-go/transport/token_source.go +++ b/vendor/k8s.io/client-go/transport/token_source.go @@ -18,8 +18,8 @@ package transport import ( "fmt" - "io/ioutil" "net/http" + "os" "strings" "sync" "time" @@ -132,7 +132,7 @@ type fileTokenSource struct { var _ = oauth2.TokenSource(&fileTokenSource{}) func (ts *fileTokenSource) Token() (*oauth2.Token, error) { - tokb, err := ioutil.ReadFile(ts.path) + tokb, err := os.ReadFile(ts.path) if err != nil { return nil, fmt.Errorf("failed to read token file %q: %v", ts.path, err) } diff --git a/vendor/k8s.io/client-go/transport/transport.go b/vendor/k8s.io/client-go/transport/transport.go index eabfce72d08..78060719a98 100644 --- a/vendor/k8s.io/client-go/transport/transport.go +++ b/vendor/k8s.io/client-go/transport/transport.go @@ -22,9 +22,8 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io/ioutil" "net/http" - "reflect" + "os" "sync" "time" @@ -62,20 +61,12 @@ func New(config *Config) (http.RoundTripper, error) { } func isValidHolders(config *Config) bool { - if config.TLS.GetCertHolder != nil { - if config.TLS.GetCertHolder.GetCert == nil || - config.TLS.GetCert == nil || - reflect.ValueOf(config.TLS.GetCertHolder.GetCert).Pointer() != reflect.ValueOf(config.TLS.GetCert).Pointer() { - return false - } + if config.TLS.GetCertHolder != nil && config.TLS.GetCertHolder.GetCert == nil { + return false } - if config.DialHolder != nil { - if config.DialHolder.Dial == nil || - config.Dial == nil || - reflect.ValueOf(config.DialHolder.Dial).Pointer() != reflect.ValueOf(config.Dial).Pointer() { - return false - } + if config.DialHolder != nil && config.DialHolder.Dial == nil { + return false } return true @@ -141,7 +132,7 @@ func TLSConfigFor(c *Config) (*tls.Config, error) { return dynamicCertLoader() } if c.HasCertCallback() { - cert, err := c.TLS.GetCert() + cert, err := c.TLS.GetCertHolder.GetCert() if err != nil { return nil, err } @@ -182,10 +173,7 @@ func loadTLSFiles(c *Config) error { } c.TLS.KeyData, err = dataFromSliceOrFile(c.TLS.KeyData, c.TLS.KeyFile) - if err != nil { - return err - } - return nil + return err } // dataFromSliceOrFile returns data from the slice (if non-empty), or from the file, @@ -195,7 +183,7 @@ func dataFromSliceOrFile(data []byte, file string) ([]byte, error) { return data, nil } if len(file) > 0 { - fileData, err := ioutil.ReadFile(file) + fileData, err := os.ReadFile(file) if err != nil { return []byte{}, err } diff --git a/vendor/k8s.io/client-go/util/cert/cert.go b/vendor/k8s.io/client-go/util/cert/cert.go index 75143ec0717..37b023ef25d 100644 --- a/vendor/k8s.io/client-go/util/cert/cert.go +++ b/vendor/k8s.io/client-go/util/cert/cert.go @@ -25,9 +25,10 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" - "io/ioutil" + "math" "math/big" "net" + "os" "path/filepath" "strings" "time" @@ -57,8 +58,14 @@ type AltNames struct { // NewSelfSignedCACert creates a CA certificate func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, error) { now := time.Now() + // returns a uniform random value in [0, max-1), then add 1 to serial to make it a uniform random value in [1, max). + serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64-1)) + if err != nil { + return nil, err + } + serial = new(big.Int).Add(serial, big.NewInt(1)) tmpl := x509.Certificate{ - SerialNumber: new(big.Int).SetInt64(0), + SerialNumber: serial, Subject: pkix.Name{ CommonName: cfg.CommonName, Organization: cfg.Organization, @@ -101,9 +108,9 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a certFixturePath := filepath.Join(fixtureDirectory, baseName+".crt") keyFixturePath := filepath.Join(fixtureDirectory, baseName+".key") if len(fixtureDirectory) > 0 { - cert, err := ioutil.ReadFile(certFixturePath) + cert, err := os.ReadFile(certFixturePath) if err == nil { - key, err := ioutil.ReadFile(keyFixturePath) + key, err := os.ReadFile(keyFixturePath) if err == nil { return cert, key, nil } @@ -116,9 +123,14 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a if err != nil { return nil, nil, err } - + // returns a uniform random value in [0, max-1), then add 1 to serial to make it a uniform random value in [1, max). + serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64-1)) + if err != nil { + return nil, nil, err + } + serial = new(big.Int).Add(serial, big.NewInt(1)) caTemplate := x509.Certificate{ - SerialNumber: big.NewInt(1), + SerialNumber: serial, Subject: pkix.Name{ CommonName: fmt.Sprintf("%s-ca@%d", host, time.Now().Unix()), }, @@ -144,9 +156,14 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a if err != nil { return nil, nil, err } - + // returns a uniform random value in [0, max-1), then add 1 to serial to make it a uniform random value in [1, max). + serial, err = cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64-1)) + if err != nil { + return nil, nil, err + } + serial = new(big.Int).Add(serial, big.NewInt(1)) template := x509.Certificate{ - SerialNumber: big.NewInt(2), + SerialNumber: serial, Subject: pkix.Name{ CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix()), }, @@ -188,10 +205,10 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a } if len(fixtureDirectory) > 0 { - if err := ioutil.WriteFile(certFixturePath, certBuffer.Bytes(), 0644); err != nil { + if err := os.WriteFile(certFixturePath, certBuffer.Bytes(), 0644); err != nil { return nil, nil, fmt.Errorf("failed to write cert fixture to %s: %v", certFixturePath, err) } - if err := ioutil.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0644); err != nil { + if err := os.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0600); err != nil { return nil, nil, fmt.Errorf("failed to write key fixture to %s: %v", certFixturePath, err) } } diff --git a/vendor/k8s.io/client-go/util/cert/io.go b/vendor/k8s.io/client-go/util/cert/io.go index 35fde68a498..a70e5132719 100644 --- a/vendor/k8s.io/client-go/util/cert/io.go +++ b/vendor/k8s.io/client-go/util/cert/io.go @@ -19,7 +19,6 @@ package cert import ( "crypto/x509" "fmt" - "io/ioutil" "os" "path/filepath" ) @@ -66,13 +65,13 @@ func WriteCert(certPath string, data []byte) error { if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil { return err } - return ioutil.WriteFile(certPath, data, os.FileMode(0644)) + return os.WriteFile(certPath, data, os.FileMode(0644)) } // NewPool returns an x509.CertPool containing the certificates in the given PEM-encoded file. // Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates func NewPool(filename string) (*x509.CertPool, error) { - pemBlock, err := ioutil.ReadFile(filename) + pemBlock, err := os.ReadFile(filename) if err != nil { return nil, err } @@ -101,7 +100,7 @@ func NewPoolFromBytes(pemBlock []byte) (*x509.CertPool, error) { // CertsFromFile returns the x509.Certificates contained in the given PEM-encoded file. // Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates func CertsFromFile(file string) ([]*x509.Certificate, error) { - pemBlock, err := ioutil.ReadFile(file) + pemBlock, err := os.ReadFile(file) if err != nil { return nil, err } diff --git a/vendor/k8s.io/client-go/util/jsonpath/doc.go b/vendor/k8s.io/client-go/util/jsonpath/doc.go deleted file mode 100644 index 0effb15c411..00000000000 --- a/vendor/k8s.io/client-go/util/jsonpath/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// package jsonpath is a template engine using jsonpath syntax, -// which can be seen at http://goessner.net/articles/JsonPath/. -// In addition, it has {range} {end} function to iterate list and slice. -package jsonpath // import "k8s.io/client-go/util/jsonpath" diff --git a/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go b/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go deleted file mode 100644 index 49ecd1465ae..00000000000 --- a/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go +++ /dev/null @@ -1,579 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "reflect" - "strings" - - "k8s.io/client-go/third_party/forked/golang/template" -) - -type JSONPath struct { - name string - parser *Parser - beginRange int - inRange int - endRange int - - lastEndNode *Node - - allowMissingKeys bool - outputJSON bool -} - -// New creates a new JSONPath with the given name. -func New(name string) *JSONPath { - return &JSONPath{ - name: name, - beginRange: 0, - inRange: 0, - endRange: 0, - } -} - -// AllowMissingKeys allows a caller to specify whether they want an error if a field or map key -// cannot be located, or simply an empty result. The receiver is returned for chaining. -func (j *JSONPath) AllowMissingKeys(allow bool) *JSONPath { - j.allowMissingKeys = allow - return j -} - -// Parse parses the given template and returns an error. -func (j *JSONPath) Parse(text string) error { - var err error - j.parser, err = Parse(j.name, text) - return err -} - -// Execute bounds data into template and writes the result. -func (j *JSONPath) Execute(wr io.Writer, data interface{}) error { - fullResults, err := j.FindResults(data) - if err != nil { - return err - } - for ix := range fullResults { - if err := j.PrintResults(wr, fullResults[ix]); err != nil { - return err - } - } - return nil -} - -func (j *JSONPath) FindResults(data interface{}) ([][]reflect.Value, error) { - if j.parser == nil { - return nil, fmt.Errorf("%s is an incomplete jsonpath template", j.name) - } - - cur := []reflect.Value{reflect.ValueOf(data)} - nodes := j.parser.Root.Nodes - fullResult := [][]reflect.Value{} - for i := 0; i < len(nodes); i++ { - node := nodes[i] - results, err := j.walk(cur, node) - if err != nil { - return nil, err - } - - // encounter an end node, break the current block - if j.endRange > 0 && j.endRange <= j.inRange { - j.endRange-- - j.lastEndNode = &nodes[i] - break - } - // encounter a range node, start a range loop - if j.beginRange > 0 { - j.beginRange-- - j.inRange++ - if len(results) > 0 { - for _, value := range results { - j.parser.Root.Nodes = nodes[i+1:] - nextResults, err := j.FindResults(value.Interface()) - if err != nil { - return nil, err - } - fullResult = append(fullResult, nextResults...) - } - } else { - // If the range has no results, we still need to process the nodes within the range - // so the position will advance to the end node - j.parser.Root.Nodes = nodes[i+1:] - _, err := j.FindResults(nil) - if err != nil { - return nil, err - } - } - j.inRange-- - - // Fast forward to resume processing after the most recent end node that was encountered - for k := i + 1; k < len(nodes); k++ { - if &nodes[k] == j.lastEndNode { - i = k - break - } - } - continue - } - fullResult = append(fullResult, results) - } - return fullResult, nil -} - -// EnableJSONOutput changes the PrintResults behavior to return a JSON array of results -func (j *JSONPath) EnableJSONOutput(v bool) { - j.outputJSON = v -} - -// PrintResults writes the results into writer -func (j *JSONPath) PrintResults(wr io.Writer, results []reflect.Value) error { - if j.outputJSON { - // convert the []reflect.Value to something that json - // will be able to marshal - r := make([]interface{}, 0, len(results)) - for i := range results { - r = append(r, results[i].Interface()) - } - results = []reflect.Value{reflect.ValueOf(r)} - } - for i, r := range results { - var text []byte - var err error - outputJSON := true - kind := r.Kind() - if kind == reflect.Interface { - kind = r.Elem().Kind() - } - switch kind { - case reflect.Map: - case reflect.Array: - case reflect.Slice: - case reflect.Struct: - default: - outputJSON = false - } - switch { - case outputJSON || j.outputJSON: - if j.outputJSON { - text, err = json.MarshalIndent(r.Interface(), "", " ") - text = append(text, '\n') - } else { - text, err = json.Marshal(r.Interface()) - } - default: - text, err = j.evalToText(r) - } - if err != nil { - return err - } - if i != len(results)-1 { - text = append(text, ' ') - } - if _, err = wr.Write(text); err != nil { - return err - } - } - - return nil - -} - -// walk visits tree rooted at the given node in DFS order -func (j *JSONPath) walk(value []reflect.Value, node Node) ([]reflect.Value, error) { - switch node := node.(type) { - case *ListNode: - return j.evalList(value, node) - case *TextNode: - return []reflect.Value{reflect.ValueOf(node.Text)}, nil - case *FieldNode: - return j.evalField(value, node) - case *ArrayNode: - return j.evalArray(value, node) - case *FilterNode: - return j.evalFilter(value, node) - case *IntNode: - return j.evalInt(value, node) - case *BoolNode: - return j.evalBool(value, node) - case *FloatNode: - return j.evalFloat(value, node) - case *WildcardNode: - return j.evalWildcard(value, node) - case *RecursiveNode: - return j.evalRecursive(value, node) - case *UnionNode: - return j.evalUnion(value, node) - case *IdentifierNode: - return j.evalIdentifier(value, node) - default: - return value, fmt.Errorf("unexpected Node %v", node) - } -} - -// evalInt evaluates IntNode -func (j *JSONPath) evalInt(input []reflect.Value, node *IntNode) ([]reflect.Value, error) { - result := make([]reflect.Value, len(input)) - for i := range input { - result[i] = reflect.ValueOf(node.Value) - } - return result, nil -} - -// evalFloat evaluates FloatNode -func (j *JSONPath) evalFloat(input []reflect.Value, node *FloatNode) ([]reflect.Value, error) { - result := make([]reflect.Value, len(input)) - for i := range input { - result[i] = reflect.ValueOf(node.Value) - } - return result, nil -} - -// evalBool evaluates BoolNode -func (j *JSONPath) evalBool(input []reflect.Value, node *BoolNode) ([]reflect.Value, error) { - result := make([]reflect.Value, len(input)) - for i := range input { - result[i] = reflect.ValueOf(node.Value) - } - return result, nil -} - -// evalList evaluates ListNode -func (j *JSONPath) evalList(value []reflect.Value, node *ListNode) ([]reflect.Value, error) { - var err error - curValue := value - for _, node := range node.Nodes { - curValue, err = j.walk(curValue, node) - if err != nil { - return curValue, err - } - } - return curValue, nil -} - -// evalIdentifier evaluates IdentifierNode -func (j *JSONPath) evalIdentifier(input []reflect.Value, node *IdentifierNode) ([]reflect.Value, error) { - results := []reflect.Value{} - switch node.Name { - case "range": - j.beginRange++ - results = input - case "end": - if j.inRange > 0 { - j.endRange++ - } else { - return results, fmt.Errorf("not in range, nothing to end") - } - default: - return input, fmt.Errorf("unrecognized identifier %v", node.Name) - } - return results, nil -} - -// evalArray evaluates ArrayNode -func (j *JSONPath) evalArray(input []reflect.Value, node *ArrayNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, value := range input { - - value, isNil := template.Indirect(value) - if isNil { - continue - } - if value.Kind() != reflect.Array && value.Kind() != reflect.Slice { - return input, fmt.Errorf("%v is not array or slice", value.Type()) - } - params := node.Params - if !params[0].Known { - params[0].Value = 0 - } - if params[0].Value < 0 { - params[0].Value += value.Len() - } - if !params[1].Known { - params[1].Value = value.Len() - } - - if params[1].Value < 0 || (params[1].Value == 0 && params[1].Derived) { - params[1].Value += value.Len() - } - sliceLength := value.Len() - if params[1].Value != params[0].Value { // if you're requesting zero elements, allow it through. - if params[0].Value >= sliceLength || params[0].Value < 0 { - return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[0].Value, sliceLength) - } - if params[1].Value > sliceLength || params[1].Value < 0 { - return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[1].Value-1, sliceLength) - } - if params[0].Value > params[1].Value { - return input, fmt.Errorf("starting index %d is greater than ending index %d", params[0].Value, params[1].Value) - } - } else { - return result, nil - } - - value = value.Slice(params[0].Value, params[1].Value) - - step := 1 - if params[2].Known { - if params[2].Value <= 0 { - return input, fmt.Errorf("step must be > 0") - } - step = params[2].Value - } - for i := 0; i < value.Len(); i += step { - result = append(result, value.Index(i)) - } - } - return result, nil -} - -// evalUnion evaluates UnionNode -func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, listNode := range node.Nodes { - temp, err := j.evalList(input, listNode) - if err != nil { - return input, err - } - result = append(result, temp...) - } - return result, nil -} - -func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) { - t := value.Type() - var inlineValue *reflect.Value - for ix := 0; ix < t.NumField(); ix++ { - f := t.Field(ix) - jsonTag := f.Tag.Get("json") - parts := strings.Split(jsonTag, ",") - if len(parts) == 0 { - continue - } - if parts[0] == node.Value { - return value.Field(ix), nil - } - if len(parts[0]) == 0 { - val := value.Field(ix) - inlineValue = &val - } - } - if inlineValue != nil { - if inlineValue.Kind() == reflect.Struct { - // handle 'inline' - match, err := j.findFieldInValue(inlineValue, node) - if err != nil { - return reflect.Value{}, err - } - if match.IsValid() { - return match, nil - } - } - } - return value.FieldByName(node.Value), nil -} - -// evalField evaluates field of struct or key of map. -func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.Value, error) { - results := []reflect.Value{} - // If there's no input, there's no output - if len(input) == 0 { - return results, nil - } - for _, value := range input { - var result reflect.Value - value, isNil := template.Indirect(value) - if isNil { - continue - } - - if value.Kind() == reflect.Struct { - var err error - if result, err = j.findFieldInValue(&value, node); err != nil { - return nil, err - } - } else if value.Kind() == reflect.Map { - mapKeyType := value.Type().Key() - nodeValue := reflect.ValueOf(node.Value) - // node value type must be convertible to map key type - if !nodeValue.Type().ConvertibleTo(mapKeyType) { - return results, fmt.Errorf("%s is not convertible to %s", nodeValue, mapKeyType) - } - result = value.MapIndex(nodeValue.Convert(mapKeyType)) - } - if result.IsValid() { - results = append(results, result) - } - } - if len(results) == 0 { - if j.allowMissingKeys { - return results, nil - } - return results, fmt.Errorf("%s is not found", node.Value) - } - return results, nil -} - -// evalWildcard extracts all contents of the given value -func (j *JSONPath) evalWildcard(input []reflect.Value, node *WildcardNode) ([]reflect.Value, error) { - results := []reflect.Value{} - for _, value := range input { - value, isNil := template.Indirect(value) - if isNil { - continue - } - - kind := value.Kind() - if kind == reflect.Struct { - for i := 0; i < value.NumField(); i++ { - results = append(results, value.Field(i)) - } - } else if kind == reflect.Map { - for _, key := range value.MapKeys() { - results = append(results, value.MapIndex(key)) - } - } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String { - for i := 0; i < value.Len(); i++ { - results = append(results, value.Index(i)) - } - } - } - return results, nil -} - -// evalRecursive visits the given value recursively and pushes all of them to result -func (j *JSONPath) evalRecursive(input []reflect.Value, node *RecursiveNode) ([]reflect.Value, error) { - result := []reflect.Value{} - for _, value := range input { - results := []reflect.Value{} - value, isNil := template.Indirect(value) - if isNil { - continue - } - - kind := value.Kind() - if kind == reflect.Struct { - for i := 0; i < value.NumField(); i++ { - results = append(results, value.Field(i)) - } - } else if kind == reflect.Map { - for _, key := range value.MapKeys() { - results = append(results, value.MapIndex(key)) - } - } else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String { - for i := 0; i < value.Len(); i++ { - results = append(results, value.Index(i)) - } - } - if len(results) != 0 { - result = append(result, value) - output, err := j.evalRecursive(results, node) - if err != nil { - return result, err - } - result = append(result, output...) - } - } - return result, nil -} - -// evalFilter filters array according to FilterNode -func (j *JSONPath) evalFilter(input []reflect.Value, node *FilterNode) ([]reflect.Value, error) { - results := []reflect.Value{} - for _, value := range input { - value, _ = template.Indirect(value) - - if value.Kind() != reflect.Array && value.Kind() != reflect.Slice { - return input, fmt.Errorf("%v is not array or slice and cannot be filtered", value) - } - for i := 0; i < value.Len(); i++ { - temp := []reflect.Value{value.Index(i)} - lefts, err := j.evalList(temp, node.Left) - - //case exists - if node.Operator == "exists" { - if len(lefts) > 0 { - results = append(results, value.Index(i)) - } - continue - } - - if err != nil { - return input, err - } - - var left, right interface{} - switch { - case len(lefts) == 0: - continue - case len(lefts) > 1: - return input, fmt.Errorf("can only compare one element at a time") - } - left = lefts[0].Interface() - - rights, err := j.evalList(temp, node.Right) - if err != nil { - return input, err - } - switch { - case len(rights) == 0: - continue - case len(rights) > 1: - return input, fmt.Errorf("can only compare one element at a time") - } - right = rights[0].Interface() - - pass := false - switch node.Operator { - case "<": - pass, err = template.Less(left, right) - case ">": - pass, err = template.Greater(left, right) - case "==": - pass, err = template.Equal(left, right) - case "!=": - pass, err = template.NotEqual(left, right) - case "<=": - pass, err = template.LessEqual(left, right) - case ">=": - pass, err = template.GreaterEqual(left, right) - default: - return results, fmt.Errorf("unrecognized filter operator %s", node.Operator) - } - if err != nil { - return results, err - } - if pass { - results = append(results, value.Index(i)) - } - } - } - return results, nil -} - -// evalToText translates reflect value to corresponding text -func (j *JSONPath) evalToText(v reflect.Value) ([]byte, error) { - iface, ok := template.PrintableValue(v) - if !ok { - return nil, fmt.Errorf("can't print type %s", v.Type()) - } - var buffer bytes.Buffer - fmt.Fprint(&buffer, iface) - return buffer.Bytes(), nil -} diff --git a/vendor/k8s.io/client-go/util/jsonpath/node.go b/vendor/k8s.io/client-go/util/jsonpath/node.go deleted file mode 100644 index 83abe8b0377..00000000000 --- a/vendor/k8s.io/client-go/util/jsonpath/node.go +++ /dev/null @@ -1,256 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import "fmt" - -// NodeType identifies the type of a parse tree node. -type NodeType int - -// Type returns itself and provides an easy default implementation -func (t NodeType) Type() NodeType { - return t -} - -func (t NodeType) String() string { - return NodeTypeName[t] -} - -const ( - NodeText NodeType = iota - NodeArray - NodeList - NodeField - NodeIdentifier - NodeFilter - NodeInt - NodeFloat - NodeWildcard - NodeRecursive - NodeUnion - NodeBool -) - -var NodeTypeName = map[NodeType]string{ - NodeText: "NodeText", - NodeArray: "NodeArray", - NodeList: "NodeList", - NodeField: "NodeField", - NodeIdentifier: "NodeIdentifier", - NodeFilter: "NodeFilter", - NodeInt: "NodeInt", - NodeFloat: "NodeFloat", - NodeWildcard: "NodeWildcard", - NodeRecursive: "NodeRecursive", - NodeUnion: "NodeUnion", - NodeBool: "NodeBool", -} - -type Node interface { - Type() NodeType - String() string -} - -// ListNode holds a sequence of nodes. -type ListNode struct { - NodeType - Nodes []Node // The element nodes in lexical order. -} - -func newList() *ListNode { - return &ListNode{NodeType: NodeList} -} - -func (l *ListNode) append(n Node) { - l.Nodes = append(l.Nodes, n) -} - -func (l *ListNode) String() string { - return l.Type().String() -} - -// TextNode holds plain text. -type TextNode struct { - NodeType - Text string // The text; may span newlines. -} - -func newText(text string) *TextNode { - return &TextNode{NodeType: NodeText, Text: text} -} - -func (t *TextNode) String() string { - return fmt.Sprintf("%s: %s", t.Type(), t.Text) -} - -// FieldNode holds field of struct -type FieldNode struct { - NodeType - Value string -} - -func newField(value string) *FieldNode { - return &FieldNode{NodeType: NodeField, Value: value} -} - -func (f *FieldNode) String() string { - return fmt.Sprintf("%s: %s", f.Type(), f.Value) -} - -// IdentifierNode holds an identifier -type IdentifierNode struct { - NodeType - Name string -} - -func newIdentifier(value string) *IdentifierNode { - return &IdentifierNode{ - NodeType: NodeIdentifier, - Name: value, - } -} - -func (f *IdentifierNode) String() string { - return fmt.Sprintf("%s: %s", f.Type(), f.Name) -} - -// ParamsEntry holds param information for ArrayNode -type ParamsEntry struct { - Value int - Known bool // whether the value is known when parse it - Derived bool -} - -// ArrayNode holds start, end, step information for array index selection -type ArrayNode struct { - NodeType - Params [3]ParamsEntry // start, end, step -} - -func newArray(params [3]ParamsEntry) *ArrayNode { - return &ArrayNode{ - NodeType: NodeArray, - Params: params, - } -} - -func (a *ArrayNode) String() string { - return fmt.Sprintf("%s: %v", a.Type(), a.Params) -} - -// FilterNode holds operand and operator information for filter -type FilterNode struct { - NodeType - Left *ListNode - Right *ListNode - Operator string -} - -func newFilter(left, right *ListNode, operator string) *FilterNode { - return &FilterNode{ - NodeType: NodeFilter, - Left: left, - Right: right, - Operator: operator, - } -} - -func (f *FilterNode) String() string { - return fmt.Sprintf("%s: %s %s %s", f.Type(), f.Left, f.Operator, f.Right) -} - -// IntNode holds integer value -type IntNode struct { - NodeType - Value int -} - -func newInt(num int) *IntNode { - return &IntNode{NodeType: NodeInt, Value: num} -} - -func (i *IntNode) String() string { - return fmt.Sprintf("%s: %d", i.Type(), i.Value) -} - -// FloatNode holds float value -type FloatNode struct { - NodeType - Value float64 -} - -func newFloat(num float64) *FloatNode { - return &FloatNode{NodeType: NodeFloat, Value: num} -} - -func (i *FloatNode) String() string { - return fmt.Sprintf("%s: %f", i.Type(), i.Value) -} - -// WildcardNode means a wildcard -type WildcardNode struct { - NodeType -} - -func newWildcard() *WildcardNode { - return &WildcardNode{NodeType: NodeWildcard} -} - -func (i *WildcardNode) String() string { - return i.Type().String() -} - -// RecursiveNode means a recursive descent operator -type RecursiveNode struct { - NodeType -} - -func newRecursive() *RecursiveNode { - return &RecursiveNode{NodeType: NodeRecursive} -} - -func (r *RecursiveNode) String() string { - return r.Type().String() -} - -// UnionNode is union of ListNode -type UnionNode struct { - NodeType - Nodes []*ListNode -} - -func newUnion(nodes []*ListNode) *UnionNode { - return &UnionNode{NodeType: NodeUnion, Nodes: nodes} -} - -func (u *UnionNode) String() string { - return u.Type().String() -} - -// BoolNode holds bool value -type BoolNode struct { - NodeType - Value bool -} - -func newBool(value bool) *BoolNode { - return &BoolNode{NodeType: NodeBool, Value: value} -} - -func (b *BoolNode) String() string { - return fmt.Sprintf("%s: %t", b.Type(), b.Value) -} diff --git a/vendor/k8s.io/client-go/util/jsonpath/parser.go b/vendor/k8s.io/client-go/util/jsonpath/parser.go deleted file mode 100644 index b84016a9f9c..00000000000 --- a/vendor/k8s.io/client-go/util/jsonpath/parser.go +++ /dev/null @@ -1,527 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package jsonpath - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -const eof = -1 - -const ( - leftDelim = "{" - rightDelim = "}" -) - -type Parser struct { - Name string - Root *ListNode - input string - pos int - start int - width int -} - -var ( - ErrSyntax = errors.New("invalid syntax") - dictKeyRex = regexp.MustCompile(`^'([^']*)'$`) - sliceOperatorRex = regexp.MustCompile(`^(-?[\d]*)(:-?[\d]*)?(:-?[\d]*)?$`) -) - -// Parse parsed the given text and return a node Parser. -// If an error is encountered, parsing stops and an empty -// Parser is returned with the error -func Parse(name, text string) (*Parser, error) { - p := NewParser(name) - err := p.Parse(text) - if err != nil { - p = nil - } - return p, err -} - -func NewParser(name string) *Parser { - return &Parser{ - Name: name, - } -} - -// parseAction parsed the expression inside delimiter -func parseAction(name, text string) (*Parser, error) { - p, err := Parse(name, fmt.Sprintf("%s%s%s", leftDelim, text, rightDelim)) - // when error happens, p will be nil, so we need to return here - if err != nil { - return p, err - } - p.Root = p.Root.Nodes[0].(*ListNode) - return p, nil -} - -func (p *Parser) Parse(text string) error { - p.input = text - p.Root = newList() - p.pos = 0 - return p.parseText(p.Root) -} - -// consumeText return the parsed text since last cosumeText -func (p *Parser) consumeText() string { - value := p.input[p.start:p.pos] - p.start = p.pos - return value -} - -// next returns the next rune in the input. -func (p *Parser) next() rune { - if p.pos >= len(p.input) { - p.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(p.input[p.pos:]) - p.width = w - p.pos += p.width - return r -} - -// peek returns but does not consume the next rune in the input. -func (p *Parser) peek() rune { - r := p.next() - p.backup() - return r -} - -// backup steps back one rune. Can only be called once per call of next. -func (p *Parser) backup() { - p.pos -= p.width -} - -func (p *Parser) parseText(cur *ListNode) error { - for { - if strings.HasPrefix(p.input[p.pos:], leftDelim) { - if p.pos > p.start { - cur.append(newText(p.consumeText())) - } - return p.parseLeftDelim(cur) - } - if p.next() == eof { - break - } - } - // Correctly reached EOF. - if p.pos > p.start { - cur.append(newText(p.consumeText())) - } - return nil -} - -// parseLeftDelim scans the left delimiter, which is known to be present. -func (p *Parser) parseLeftDelim(cur *ListNode) error { - p.pos += len(leftDelim) - p.consumeText() - newNode := newList() - cur.append(newNode) - cur = newNode - return p.parseInsideAction(cur) -} - -func (p *Parser) parseInsideAction(cur *ListNode) error { - prefixMap := map[string]func(*ListNode) error{ - rightDelim: p.parseRightDelim, - "[?(": p.parseFilter, - "..": p.parseRecursive, - } - for prefix, parseFunc := range prefixMap { - if strings.HasPrefix(p.input[p.pos:], prefix) { - return parseFunc(cur) - } - } - - switch r := p.next(); { - case r == eof || isEndOfLine(r): - return fmt.Errorf("unclosed action") - case r == ' ': - p.consumeText() - case r == '@' || r == '$': //the current object, just pass it - p.consumeText() - case r == '[': - return p.parseArray(cur) - case r == '"' || r == '\'': - return p.parseQuote(cur, r) - case r == '.': - return p.parseField(cur) - case r == '+' || r == '-' || unicode.IsDigit(r): - p.backup() - return p.parseNumber(cur) - case isAlphaNumeric(r): - p.backup() - return p.parseIdentifier(cur) - default: - return fmt.Errorf("unrecognized character in action: %#U", r) - } - return p.parseInsideAction(cur) -} - -// parseRightDelim scans the right delimiter, which is known to be present. -func (p *Parser) parseRightDelim(cur *ListNode) error { - p.pos += len(rightDelim) - p.consumeText() - return p.parseText(p.Root) -} - -// parseIdentifier scans build-in keywords, like "range" "end" -func (p *Parser) parseIdentifier(cur *ListNode) error { - var r rune - for { - r = p.next() - if isTerminator(r) { - p.backup() - break - } - } - value := p.consumeText() - - if isBool(value) { - v, err := strconv.ParseBool(value) - if err != nil { - return fmt.Errorf("can not parse bool '%s': %s", value, err.Error()) - } - - cur.append(newBool(v)) - } else { - cur.append(newIdentifier(value)) - } - - return p.parseInsideAction(cur) -} - -// parseRecursive scans the recursive descent operator .. -func (p *Parser) parseRecursive(cur *ListNode) error { - if lastIndex := len(cur.Nodes) - 1; lastIndex >= 0 && cur.Nodes[lastIndex].Type() == NodeRecursive { - return fmt.Errorf("invalid multiple recursive descent") - } - p.pos += len("..") - p.consumeText() - cur.append(newRecursive()) - if r := p.peek(); isAlphaNumeric(r) { - return p.parseField(cur) - } - return p.parseInsideAction(cur) -} - -// parseNumber scans number -func (p *Parser) parseNumber(cur *ListNode) error { - r := p.peek() - if r == '+' || r == '-' { - p.next() - } - for { - r = p.next() - if r != '.' && !unicode.IsDigit(r) { - p.backup() - break - } - } - value := p.consumeText() - i, err := strconv.Atoi(value) - if err == nil { - cur.append(newInt(i)) - return p.parseInsideAction(cur) - } - d, err := strconv.ParseFloat(value, 64) - if err == nil { - cur.append(newFloat(d)) - return p.parseInsideAction(cur) - } - return fmt.Errorf("cannot parse number %s", value) -} - -// parseArray scans array index selection -func (p *Parser) parseArray(cur *ListNode) error { -Loop: - for { - switch p.next() { - case eof, '\n': - return fmt.Errorf("unterminated array") - case ']': - break Loop - } - } - text := p.consumeText() - text = text[1 : len(text)-1] - if text == "*" { - text = ":" - } - - //union operator - strs := strings.Split(text, ",") - if len(strs) > 1 { - union := []*ListNode{} - for _, str := range strs { - parser, err := parseAction("union", fmt.Sprintf("[%s]", strings.Trim(str, " "))) - if err != nil { - return err - } - union = append(union, parser.Root) - } - cur.append(newUnion(union)) - return p.parseInsideAction(cur) - } - - // dict key - value := dictKeyRex.FindStringSubmatch(text) - if value != nil { - parser, err := parseAction("arraydict", fmt.Sprintf(".%s", value[1])) - if err != nil { - return err - } - for _, node := range parser.Root.Nodes { - cur.append(node) - } - return p.parseInsideAction(cur) - } - - //slice operator - value = sliceOperatorRex.FindStringSubmatch(text) - if value == nil { - return fmt.Errorf("invalid array index %s", text) - } - value = value[1:] - params := [3]ParamsEntry{} - for i := 0; i < 3; i++ { - if value[i] != "" { - if i > 0 { - value[i] = value[i][1:] - } - if i > 0 && value[i] == "" { - params[i].Known = false - } else { - var err error - params[i].Known = true - params[i].Value, err = strconv.Atoi(value[i]) - if err != nil { - return fmt.Errorf("array index %s is not a number", value[i]) - } - } - } else { - if i == 1 { - params[i].Known = true - params[i].Value = params[0].Value + 1 - params[i].Derived = true - } else { - params[i].Known = false - params[i].Value = 0 - } - } - } - cur.append(newArray(params)) - return p.parseInsideAction(cur) -} - -// parseFilter scans filter inside array selection -func (p *Parser) parseFilter(cur *ListNode) error { - p.pos += len("[?(") - p.consumeText() - begin := false - end := false - var pair rune - -Loop: - for { - r := p.next() - switch r { - case eof, '\n': - return fmt.Errorf("unterminated filter") - case '"', '\'': - if begin == false { - //save the paired rune - begin = true - pair = r - continue - } - //only add when met paired rune - if p.input[p.pos-2] != '\\' && r == pair { - end = true - } - case ')': - //in rightParser below quotes only appear zero or once - //and must be paired at the beginning and end - if begin == end { - break Loop - } - } - } - if p.next() != ']' { - return fmt.Errorf("unclosed array expect ]") - } - reg := regexp.MustCompile(`^([^!<>=]+)([!<>=]+)(.+?)$`) - text := p.consumeText() - text = text[:len(text)-2] - value := reg.FindStringSubmatch(text) - if value == nil { - parser, err := parseAction("text", text) - if err != nil { - return err - } - cur.append(newFilter(parser.Root, newList(), "exists")) - } else { - leftParser, err := parseAction("left", value[1]) - if err != nil { - return err - } - rightParser, err := parseAction("right", value[3]) - if err != nil { - return err - } - cur.append(newFilter(leftParser.Root, rightParser.Root, value[2])) - } - return p.parseInsideAction(cur) -} - -// parseQuote unquotes string inside double or single quote -func (p *Parser) parseQuote(cur *ListNode, end rune) error { -Loop: - for { - switch p.next() { - case eof, '\n': - return fmt.Errorf("unterminated quoted string") - case end: - //if it's not escape break the Loop - if p.input[p.pos-2] != '\\' { - break Loop - } - } - } - value := p.consumeText() - s, err := UnquoteExtend(value) - if err != nil { - return fmt.Errorf("unquote string %s error %v", value, err) - } - cur.append(newText(s)) - return p.parseInsideAction(cur) -} - -// parseField scans a field until a terminator -func (p *Parser) parseField(cur *ListNode) error { - p.consumeText() - for p.advance() { - } - value := p.consumeText() - if value == "*" { - cur.append(newWildcard()) - } else { - cur.append(newField(strings.Replace(value, "\\", "", -1))) - } - return p.parseInsideAction(cur) -} - -// advance scans until next non-escaped terminator -func (p *Parser) advance() bool { - r := p.next() - if r == '\\' { - p.next() - } else if isTerminator(r) { - p.backup() - return false - } - return true -} - -// isTerminator reports whether the input is at valid termination character to appear after an identifier. -func isTerminator(r rune) bool { - if isSpace(r) || isEndOfLine(r) { - return true - } - switch r { - case eof, '.', ',', '[', ']', '$', '@', '{', '}': - return true - } - return false -} - -// isSpace reports whether r is a space character. -func isSpace(r rune) bool { - return r == ' ' || r == '\t' -} - -// isEndOfLine reports whether r is an end-of-line character. -func isEndOfLine(r rune) bool { - return r == '\r' || r == '\n' -} - -// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. -func isAlphaNumeric(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) -} - -// isBool reports whether s is a boolean value. -func isBool(s string) bool { - return s == "true" || s == "false" -} - -//UnquoteExtend is almost same as strconv.Unquote(), but it support parse single quotes as a string -func UnquoteExtend(s string) (string, error) { - n := len(s) - if n < 2 { - return "", ErrSyntax - } - quote := s[0] - if quote != s[n-1] { - return "", ErrSyntax - } - s = s[1 : n-1] - - if quote != '"' && quote != '\'' { - return "", ErrSyntax - } - - // Is it trivial? Avoid allocation. - if !contains(s, '\\') && !contains(s, quote) { - return s, nil - } - - var runeTmp [utf8.UTFMax]byte - buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations. - for len(s) > 0 { - c, multibyte, ss, err := strconv.UnquoteChar(s, quote) - if err != nil { - return "", err - } - s = ss - if c < utf8.RuneSelf || !multibyte { - buf = append(buf, byte(c)) - } else { - n := utf8.EncodeRune(runeTmp[:], c) - buf = append(buf, runeTmp[:n]...) - } - } - return string(buf), nil -} - -func contains(s string, c byte) bool { - for i := 0; i < len(s); i++ { - if s[i] == c { - return true - } - } - return false -} diff --git a/vendor/k8s.io/client-go/util/keyutil/key.go b/vendor/k8s.io/client-go/util/keyutil/key.go index 83c2c6254e0..ecd3e4710fe 100644 --- a/vendor/k8s.io/client-go/util/keyutil/key.go +++ b/vendor/k8s.io/client-go/util/keyutil/key.go @@ -26,7 +26,6 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io/ioutil" "os" "path/filepath" ) @@ -69,13 +68,13 @@ func WriteKey(keyPath string, data []byte) error { if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil { return err } - return ioutil.WriteFile(keyPath, data, os.FileMode(0600)) + return os.WriteFile(keyPath, data, os.FileMode(0600)) } // LoadOrGenerateKeyFile looks for a key in the file at the given path. If it // can't find one, it will generate a new key and store it there. func LoadOrGenerateKeyFile(keyPath string) (data []byte, wasGenerated bool, err error) { - loadedData, err := ioutil.ReadFile(keyPath) + loadedData, err := os.ReadFile(keyPath) // Call verifyKeyData to ensure the file wasn't empty/corrupt. if err == nil && verifyKeyData(loadedData) { return loadedData, false, err @@ -122,7 +121,7 @@ func MarshalPrivateKeyToPEM(privateKey crypto.PrivateKey) ([]byte, error) { // PrivateKeyFromFile returns the private key in rsa.PrivateKey or ecdsa.PrivateKey format from a given PEM-encoded file. // Returns an error if the file could not be read or if the private key could not be parsed. func PrivateKeyFromFile(file string) (interface{}, error) { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return nil, err } @@ -136,7 +135,7 @@ func PrivateKeyFromFile(file string) (interface{}, error) { // PublicKeysFromFile returns the public keys in rsa.PublicKey or ecdsa.PublicKey format from a given PEM-encoded file. // Reads public keys from both public and private key files. func PublicKeysFromFile(file string) ([]interface{}, error) { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return nil, err } diff --git a/vendor/k8s.io/client-go/util/retry/util.go b/vendor/k8s.io/client-go/util/retry/util.go index 772f5bd7a77..0c6e504a6dc 100644 --- a/vendor/k8s.io/client-go/util/retry/util.go +++ b/vendor/k8s.io/client-go/util/retry/util.go @@ -74,30 +74,30 @@ func OnError(backoff wait.Backoff, retriable func(error) bool, fn func() error) // backoff, and then try again. On a non-"Conflict" error, or if it retries too many times // and gives up, RetryOnConflict will return an error to the caller. // -// err := retry.RetryOnConflict(retry.DefaultRetry, func() error { -// // Fetch the resource here; you need to refetch it on every try, since -// // if you got a conflict on the last update attempt then you need to get -// // the current version before making your own changes. -// pod, err := c.Pods("mynamespace").Get(name, metav1.GetOptions{}) -// if err != nil { -// return err -// } +// err := retry.RetryOnConflict(retry.DefaultRetry, func() error { +// // Fetch the resource here; you need to refetch it on every try, since +// // if you got a conflict on the last update attempt then you need to get +// // the current version before making your own changes. +// pod, err := c.Pods("mynamespace").Get(name, metav1.GetOptions{}) +// if err != nil { +// return err +// } // -// // Make whatever updates to the resource are needed -// pod.Status.Phase = v1.PodFailed +// // Make whatever updates to the resource are needed +// pod.Status.Phase = v1.PodFailed // -// // Try to update -// _, err = c.Pods("mynamespace").UpdateStatus(pod) -// // You have to return err itself here (not wrapped inside another error) -// // so that RetryOnConflict can identify it correctly. -// return err -// }) -// if err != nil { -// // May be conflict if max retries were hit, or may be something unrelated -// // like permissions or a network error -// return err -// } -// ... +// // Try to update +// _, err = c.Pods("mynamespace").UpdateStatus(pod) +// // You have to return err itself here (not wrapped inside another error) +// // so that RetryOnConflict can identify it correctly. +// return err +// }) +// if err != nil { +// // May be conflict if max retries were hit, or may be something unrelated +// // like permissions or a network error +// return err +// } +// ... // // TODO: Make Backoff an interface? func RetryOnConflict(backoff wait.Backoff, fn func() error) error { diff --git a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go index 26eacc2ba77..c1df7203021 100644 --- a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go @@ -33,38 +33,81 @@ type DelayingInterface interface { AddAfter(item interface{}, duration time.Duration) } +// DelayingQueueConfig specifies optional configurations to customize a DelayingInterface. +type DelayingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // Queue optionally allows injecting custom queue Interface instead of the default one. + Queue Interface +} + // NewDelayingQueue constructs a new workqueue with delayed queuing ability. // NewDelayingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedDelayingQueue instead. +// NewDelayingQueueWithConfig instead and specify a name. func NewDelayingQueue() DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, "") + return NewDelayingQueueWithConfig(DelayingQueueConfig{}) +} + +// NewDelayingQueueWithConfig constructs a new workqueue with options to +// customize different properties. +func NewDelayingQueueWithConfig(config DelayingQueueConfig) DelayingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.Queue == nil { + config.Queue = NewWithConfig(QueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + + return newDelayingQueue(config.Clock, config.Queue, config.Name, config.MetricsProvider) } // NewDelayingQueueWithCustomQueue constructs a new workqueue with ability to // inject custom queue Interface instead of the default one +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomQueue(q Interface, name string) DelayingInterface { - return newDelayingQueue(clock.RealClock{}, q, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Queue: q, + }) } -// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability +// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewNamedDelayingQueue(name string) DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{Name: name}) } // NewDelayingQueueWithCustomClock constructs a new named workqueue -// with ability to inject real or fake clock for testing purposes +// with ability to inject real or fake clock for testing purposes. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomClock(clock clock.WithTicker, name string) DelayingInterface { - return newDelayingQueue(clock, NewNamed(name), name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Clock: clock, + }) } -func newDelayingQueue(clock clock.WithTicker, q Interface, name string) *delayingType { +func newDelayingQueue(clock clock.WithTicker, q Interface, name string, provider MetricsProvider) *delayingType { ret := &delayingType{ Interface: q, clock: clock, heartbeat: clock.NewTicker(maxWait), stopCh: make(chan struct{}), waitingForAddCh: make(chan *waitFor, 1000), - metrics: newRetryMetrics(name), + metrics: newRetryMetrics(name, provider), } go ret.waitingLoop() diff --git a/vendor/k8s.io/client-go/util/workqueue/doc.go b/vendor/k8s.io/client-go/util/workqueue/doc.go index a5c976e0f9c..8555aa95fe1 100644 --- a/vendor/k8s.io/client-go/util/workqueue/doc.go +++ b/vendor/k8s.io/client-go/util/workqueue/doc.go @@ -16,11 +16,11 @@ limitations under the License. // Package workqueue provides a simple queue that supports the following // features: -// * Fair: items processed in the order in which they are added. -// * Stingy: a single item will not be processed multiple times concurrently, -// and if an item is added multiple times before it can be processed, it -// will only be processed once. -// * Multiple consumers and producers. In particular, it is allowed for an -// item to be reenqueued while it is being processed. -// * Shutdown notifications. +// - Fair: items processed in the order in which they are added. +// - Stingy: a single item will not be processed multiple times concurrently, +// and if an item is added multiple times before it can be processed, it +// will only be processed once. +// - Multiple consumers and producers. In particular, it is allowed for an +// item to be reenqueued while it is being processed. +// - Shutdown notifications. package workqueue // import "k8s.io/client-go/util/workqueue" diff --git a/vendor/k8s.io/client-go/util/workqueue/metrics.go b/vendor/k8s.io/client-go/util/workqueue/metrics.go index 4b0a69616d3..f012ccc5548 100644 --- a/vendor/k8s.io/client-go/util/workqueue/metrics.go +++ b/vendor/k8s.io/client-go/util/workqueue/metrics.go @@ -244,13 +244,18 @@ func (f *queueMetricsFactory) newQueueMetrics(name string, clock clock.Clock) qu } } -func newRetryMetrics(name string) retryMetrics { +func newRetryMetrics(name string, provider MetricsProvider) retryMetrics { var ret *defaultRetryMetrics if len(name) == 0 { return ret } + + if provider == nil { + provider = globalMetricsFactory.metricsProvider + } + return &defaultRetryMetrics{ - retries: globalMetricsFactory.metricsProvider.NewRetriesMetric(name), + retries: provider.NewRetriesMetric(name), } } diff --git a/vendor/k8s.io/client-go/util/workqueue/queue.go b/vendor/k8s.io/client-go/util/workqueue/queue.go index 6f7063269fb..380c0645526 100644 --- a/vendor/k8s.io/client-go/util/workqueue/queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/queue.go @@ -33,17 +33,60 @@ type Interface interface { ShuttingDown() bool } +// QueueConfig specifies optional configurations to customize an Interface. +type QueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock ability to inject real or fake clock for testing purposes. + Clock clock.WithTicker +} + // New constructs a new work queue (see the package comment). func New() *Type { - return NewNamed("") + return NewWithConfig(QueueConfig{ + Name: "", + }) } +// NewWithConfig constructs a new workqueue with ability to +// customize different properties. +func NewWithConfig(config QueueConfig) *Type { + return newQueueWithConfig(config, defaultUnfinishedWorkUpdatePeriod) +} + +// NewNamed creates a new named queue. +// Deprecated: Use NewWithConfig instead. func NewNamed(name string) *Type { - rc := clock.RealClock{} + return NewWithConfig(QueueConfig{ + Name: name, + }) +} + +// newQueueWithConfig constructs a new named workqueue +// with the ability to customize different properties for testing purposes +func newQueueWithConfig(config QueueConfig, updatePeriod time.Duration) *Type { + var metricsFactory *queueMetricsFactory + if config.MetricsProvider != nil { + metricsFactory = &queueMetricsFactory{ + metricsProvider: config.MetricsProvider, + } + } else { + metricsFactory = &globalMetricsFactory + } + + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + return newQueue( - rc, - globalMetricsFactory.newQueueMetrics(name, rc), - defaultUnfinishedWorkUpdatePeriod, + config.Clock, + metricsFactory.newQueueMetrics(config.Name, config.Clock), + updatePeriod, ) } diff --git a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go index 267f4ff4084..3e4016fb04f 100644 --- a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go @@ -16,6 +16,8 @@ limitations under the License. package workqueue +import "k8s.io/utils/clock" + // RateLimitingInterface is an interface that rate limits items being added to the queue. type RateLimitingInterface interface { DelayingInterface @@ -32,22 +34,68 @@ type RateLimitingInterface interface { NumRequeues(item interface{}) int } +// RateLimitingQueueConfig specifies optional configurations to customize a RateLimitingInterface. + +type RateLimitingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // DelayingQueue optionally allows injecting custom delaying queue DelayingInterface instead of the default one. + DelayingQueue DelayingInterface +} + // NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability // Remember to call Forget! If you don't, you may end up tracking failures forever. // NewRateLimitingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedRateLimitingQueue instead. +// NewRateLimitingQueueWithConfig instead and specify a name. func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface { + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{}) +} + +// NewRateLimitingQueueWithConfig constructs a new workqueue with rateLimited queuing ability +// with options to customize different properties. +// Remember to call Forget! If you don't, you may end up tracking failures forever. +func NewRateLimitingQueueWithConfig(rateLimiter RateLimiter, config RateLimitingQueueConfig) RateLimitingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.DelayingQueue == nil { + config.DelayingQueue = NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + return &rateLimitingType{ - DelayingInterface: NewDelayingQueue(), + DelayingInterface: config.DelayingQueue, rateLimiter: rateLimiter, } } +// NewNamedRateLimitingQueue constructs a new named workqueue with rateLimited queuing ability. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. func NewNamedRateLimitingQueue(rateLimiter RateLimiter, name string) RateLimitingInterface { - return &rateLimitingType{ - DelayingInterface: NewNamedDelayingQueue(name), - rateLimiter: rateLimiter, - } + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + Name: name, + }) +} + +// NewRateLimitingQueueWithDelayingInterface constructs a new named workqueue with rateLimited queuing ability +// with the option to inject a custom delaying queue instead of the default one. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. +func NewRateLimitingQueueWithDelayingInterface(di DelayingInterface, rateLimiter RateLimiter) RateLimitingInterface { + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + DelayingQueue: di, + }) } // rateLimitingType wraps an Interface and provides rateLimited re-enquing diff --git a/vendor/k8s.io/component-base/config/types.go b/vendor/k8s.io/component-base/config/types.go index 4a4c13a5da6..e1b9469d76e 100644 --- a/vendor/k8s.io/component-base/config/types.go +++ b/vendor/k8s.io/component-base/config/types.go @@ -17,14 +17,6 @@ limitations under the License. package config import ( - "fmt" - "strconv" - "strings" - "time" - - "github.com/spf13/pflag" - - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -82,131 +74,7 @@ type LeaderElectionConfiguration struct { type DebuggingConfiguration struct { // enableProfiling enables profiling via web interface host:port/debug/pprof/ EnableProfiling bool - // enableContentionProfiling enables lock contention profiling, if + // enableContentionProfiling enables block profiling, if // enableProfiling is true. EnableContentionProfiling bool } - -// LoggingConfiguration contains logging options -// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information. -type LoggingConfiguration struct { - // Format Flag specifies the structure of log messages. - // default value of format is `text` - Format string - // Maximum number of nanoseconds (i.e. 1s = 1000000000) between log - // flushes. Ignored if the selected logging backend writes log - // messages without buffering. - FlushFrequency time.Duration - // Verbosity is the threshold that determines which log messages are - // logged. Default is zero which logs only the most important - // messages. Higher values enable additional messages. Error messages - // are always logged. - Verbosity VerbosityLevel - // VModule overrides the verbosity threshold for individual files. - // Only supported for "text" log format. - VModule VModuleConfiguration - // [Experimental] Options holds additional parameters that are specific - // to the different logging formats. Only the options for the selected - // format get used, but all of them get validated. - Options FormatOptions -} - -// FormatOptions contains options for the different logging formats. -type FormatOptions struct { - // [Experimental] JSON contains options for logging format "json". - JSON JSONOptions -} - -// JSONOptions contains options for logging format "json". -type JSONOptions struct { - // [Experimental] SplitStream redirects error messages to stderr while - // info messages go to stdout, with buffering. The default is to write - // both to stdout, without buffering. - SplitStream bool - // [Experimental] InfoBufferSize sets the size of the info stream when - // using split streams. The default is zero, which disables buffering. - InfoBufferSize resource.QuantityValue -} - -// VModuleConfiguration is a collection of individual file names or patterns -// and the corresponding verbosity threshold. -type VModuleConfiguration []VModuleItem - -var _ pflag.Value = &VModuleConfiguration{} - -// VModuleItem defines verbosity for one or more files which match a certain -// glob pattern. -type VModuleItem struct { - // FilePattern is a base file name (i.e. minus the ".go" suffix and - // directory) or a "glob" pattern for such a name. It must not contain - // comma and equal signs because those are separators for the - // corresponding klog command line argument. - FilePattern string - // Verbosity is the threshold for log messages emitted inside files - // that match the pattern. - Verbosity VerbosityLevel -} - -// String returns the -vmodule parameter (comma-separated list of pattern=N). -func (vmodule *VModuleConfiguration) String() string { - var patterns []string - for _, item := range *vmodule { - patterns = append(patterns, fmt.Sprintf("%s=%d", item.FilePattern, item.Verbosity)) - } - return strings.Join(patterns, ",") -} - -// Set parses the -vmodule parameter (comma-separated list of pattern=N). -func (vmodule *VModuleConfiguration) Set(value string) error { - // This code mirrors https://github.com/kubernetes/klog/blob/9ad246211af1ed84621ee94a26fcce0038b69cd1/klog.go#L287-L313 - - for _, pat := range strings.Split(value, ",") { - if len(pat) == 0 { - // Empty strings such as from a trailing comma can be ignored. - continue - } - patLev := strings.Split(pat, "=") - if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 { - return fmt.Errorf("%q does not have the pattern=N format", pat) - } - pattern := patLev[0] - // 31 instead of 32 to ensure that it also fits into int32. - v, err := strconv.ParseUint(patLev[1], 10, 31) - if err != nil { - return fmt.Errorf("parsing verbosity in %q: %v", pat, err) - } - *vmodule = append(*vmodule, VModuleItem{FilePattern: pattern, Verbosity: VerbosityLevel(v)}) - } - return nil -} - -func (vmodule *VModuleConfiguration) Type() string { - return "pattern=N,..." -} - -// VerbosityLevel represents a klog or logr verbosity threshold. -type VerbosityLevel uint32 - -var _ pflag.Value = new(VerbosityLevel) - -func (l *VerbosityLevel) String() string { - return strconv.FormatInt(int64(*l), 10) -} - -func (l *VerbosityLevel) Get() interface{} { - return *l -} - -func (l *VerbosityLevel) Set(value string) error { - // Limited to int32 for compatibility with klog. - v, err := strconv.ParseUint(value, 10, 31) - if err != nil { - return err - } - *l = VerbosityLevel(v) - return nil -} - -func (l *VerbosityLevel) Type() string { - return "Level" -} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go index abf35c6d910..e2951e310d5 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/conversion.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go @@ -51,11 +51,3 @@ func Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfig func Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error { return autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in, out, s) } - -func Convert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in *LoggingConfiguration, out *config.LoggingConfiguration, s conversion.Scope) error { - return autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in, out, s) -} - -func Convert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in *config.LoggingConfiguration, out *LoggingConfiguration, s conversion.Scope) error { - return autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in, out, s) -} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/defaults.go b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go index 57d066edacc..cd7f820e97e 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/defaults.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go @@ -19,7 +19,6 @@ package v1alpha1 import ( "time" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilpointer "k8s.io/utils/pointer" ) @@ -97,32 +96,3 @@ func NewRecommendedDebuggingConfiguration() *DebuggingConfiguration { RecommendedDebuggingConfiguration(ret) return ret } - -// RecommendedLoggingConfiguration defaults logging configuration. -// This will set the recommended default -// values, but they may be subject to change between API versions. This function -// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` -// function to allow consumers of this type to set whatever defaults for their -// embedded configs. Forcing consumers to use these defaults would be problematic -// as defaulting in the scheme is done as part of the conversion, and there would -// be no easy way to opt-out. Instead, if you want to use this defaulting method -// run it in your wrapper struct of this type in its `SetDefaults_` method. -func RecommendedLoggingConfiguration(obj *LoggingConfiguration) { - if obj.Format == "" { - obj.Format = "text" - } - var empty resource.QuantityValue - if obj.Options.JSON.InfoBufferSize == empty { - obj.Options.JSON.InfoBufferSize = resource.QuantityValue{ - // This is similar, but not quite the same as a default - // constructed instance. - Quantity: *resource.NewQuantity(0, resource.DecimalSI), - } - // This sets the unexported Quantity.s which will be compared - // by reflect.DeepEqual in some tests. - _ = obj.Options.JSON.InfoBufferSize.String() - } - if obj.FlushFrequency == 0 { - obj.FlushFrequency = 5 * time.Second - } -} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/types.go b/vendor/k8s.io/component-base/config/v1alpha1/types.go index 71a2e9e8875..3c5f004f27d 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/types.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/types.go @@ -17,9 +17,6 @@ limitations under the License. package v1alpha1 import ( - "time" - - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -63,7 +60,7 @@ type LeaderElectionConfiguration struct { type DebuggingConfiguration struct { // enableProfiling enables profiling via web interface host:port/debug/pprof/ EnableProfiling *bool `json:"enableProfiling,omitempty"` - // enableContentionProfiling enables lock contention profiling, if + // enableContentionProfiling enables block profiling, if // enableProfiling is true. EnableContentionProfiling *bool `json:"enableContentionProfiling,omitempty"` } @@ -83,61 +80,3 @@ type ClientConnectionConfiguration struct { // burst allows extra queries to accumulate when a client is exceeding its rate. Burst int32 `json:"burst"` } - -// LoggingConfiguration contains logging options -// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information. -type LoggingConfiguration struct { - // Format Flag specifies the structure of log messages. - // default value of format is `text` - Format string `json:"format,omitempty"` - // Maximum number of nanoseconds (i.e. 1s = 1000000000) between log - // flushes. Ignored if the selected logging backend writes log - // messages without buffering. - FlushFrequency time.Duration `json:"flushFrequency"` - // Verbosity is the threshold that determines which log messages are - // logged. Default is zero which logs only the most important - // messages. Higher values enable additional messages. Error messages - // are always logged. - Verbosity uint32 `json:"verbosity"` - // VModule overrides the verbosity threshold for individual files. - // Only supported for "text" log format. - VModule VModuleConfiguration `json:"vmodule,omitempty"` - // [Experimental] Options holds additional parameters that are specific - // to the different logging formats. Only the options for the selected - // format get used, but all of them get validated. - Options FormatOptions `json:"options,omitempty"` -} - -// FormatOptions contains options for the different logging formats. -type FormatOptions struct { - // [Experimental] JSON contains options for logging format "json". - JSON JSONOptions `json:"json,omitempty"` -} - -// JSONOptions contains options for logging format "json". -type JSONOptions struct { - // [Experimental] SplitStream redirects error messages to stderr while - // info messages go to stdout, with buffering. The default is to write - // both to stdout, without buffering. - SplitStream bool `json:"splitStream,omitempty"` - // [Experimental] InfoBufferSize sets the size of the info stream when - // using split streams. The default is zero, which disables buffering. - InfoBufferSize resource.QuantityValue `json:"infoBufferSize,omitempty"` -} - -// VModuleConfiguration is a collection of individual file names or patterns -// and the corresponding verbosity threshold. -type VModuleConfiguration []VModuleItem - -// VModuleItem defines verbosity for one or more files which match a certain -// glob pattern. -type VModuleItem struct { - // FilePattern is a base file name (i.e. minus the ".go" suffix and - // directory) or a "glob" pattern for such a name. It must not contain - // comma and equal signs because those are separators for the - // corresponding klog command line argument. - FilePattern string `json:"filePattern"` - // Verbosity is the threshold for log messages emitted inside files - // that match the pattern. - Verbosity uint32 `json:"verbosity"` -} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go index 4162e095dc9..a911bb50d8a 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go @@ -22,9 +22,6 @@ limitations under the License. package v1alpha1 import ( - time "time" - unsafe "unsafe" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" @@ -38,36 +35,6 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { - if err := s.AddGeneratedConversionFunc((*FormatOptions)(nil), (*config.FormatOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_FormatOptions_To_config_FormatOptions(a.(*FormatOptions), b.(*config.FormatOptions), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.FormatOptions)(nil), (*FormatOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_FormatOptions_To_v1alpha1_FormatOptions(a.(*config.FormatOptions), b.(*FormatOptions), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*JSONOptions)(nil), (*config.JSONOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_JSONOptions_To_config_JSONOptions(a.(*JSONOptions), b.(*config.JSONOptions), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.JSONOptions)(nil), (*JSONOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_JSONOptions_To_v1alpha1_JSONOptions(a.(*config.JSONOptions), b.(*JSONOptions), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*VModuleItem)(nil), (*config.VModuleItem)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_VModuleItem_To_config_VModuleItem(a.(*VModuleItem), b.(*config.VModuleItem), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.VModuleItem)(nil), (*VModuleItem)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_VModuleItem_To_v1alpha1_VModuleItem(a.(*config.VModuleItem), b.(*VModuleItem), scope) - }); err != nil { - return err - } if err := s.AddConversionFunc((*config.ClientConnectionConfiguration)(nil), (*ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(a.(*config.ClientConnectionConfiguration), b.(*ClientConnectionConfiguration), scope) }); err != nil { @@ -83,11 +50,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*config.LoggingConfiguration)(nil), (*LoggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(a.(*config.LoggingConfiguration), b.(*LoggingConfiguration), scope) - }); err != nil { - return err - } if err := s.AddConversionFunc((*ClientConnectionConfiguration)(nil), (*config.ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(a.(*ClientConnectionConfiguration), b.(*config.ClientConnectionConfiguration), scope) }); err != nil { @@ -103,11 +65,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*LoggingConfiguration)(nil), (*config.LoggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(a.(*LoggingConfiguration), b.(*config.LoggingConfiguration), scope) - }); err != nil { - return err - } return nil } @@ -149,52 +106,6 @@ func autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguratio return nil } -func autoConvert_v1alpha1_FormatOptions_To_config_FormatOptions(in *FormatOptions, out *config.FormatOptions, s conversion.Scope) error { - if err := Convert_v1alpha1_JSONOptions_To_config_JSONOptions(&in.JSON, &out.JSON, s); err != nil { - return err - } - return nil -} - -// Convert_v1alpha1_FormatOptions_To_config_FormatOptions is an autogenerated conversion function. -func Convert_v1alpha1_FormatOptions_To_config_FormatOptions(in *FormatOptions, out *config.FormatOptions, s conversion.Scope) error { - return autoConvert_v1alpha1_FormatOptions_To_config_FormatOptions(in, out, s) -} - -func autoConvert_config_FormatOptions_To_v1alpha1_FormatOptions(in *config.FormatOptions, out *FormatOptions, s conversion.Scope) error { - if err := Convert_config_JSONOptions_To_v1alpha1_JSONOptions(&in.JSON, &out.JSON, s); err != nil { - return err - } - return nil -} - -// Convert_config_FormatOptions_To_v1alpha1_FormatOptions is an autogenerated conversion function. -func Convert_config_FormatOptions_To_v1alpha1_FormatOptions(in *config.FormatOptions, out *FormatOptions, s conversion.Scope) error { - return autoConvert_config_FormatOptions_To_v1alpha1_FormatOptions(in, out, s) -} - -func autoConvert_v1alpha1_JSONOptions_To_config_JSONOptions(in *JSONOptions, out *config.JSONOptions, s conversion.Scope) error { - out.SplitStream = in.SplitStream - out.InfoBufferSize = in.InfoBufferSize - return nil -} - -// Convert_v1alpha1_JSONOptions_To_config_JSONOptions is an autogenerated conversion function. -func Convert_v1alpha1_JSONOptions_To_config_JSONOptions(in *JSONOptions, out *config.JSONOptions, s conversion.Scope) error { - return autoConvert_v1alpha1_JSONOptions_To_config_JSONOptions(in, out, s) -} - -func autoConvert_config_JSONOptions_To_v1alpha1_JSONOptions(in *config.JSONOptions, out *JSONOptions, s conversion.Scope) error { - out.SplitStream = in.SplitStream - out.InfoBufferSize = in.InfoBufferSize - return nil -} - -// Convert_config_JSONOptions_To_v1alpha1_JSONOptions is an autogenerated conversion function. -func Convert_config_JSONOptions_To_v1alpha1_JSONOptions(in *config.JSONOptions, out *JSONOptions, s conversion.Scope) error { - return autoConvert_config_JSONOptions_To_v1alpha1_JSONOptions(in, out, s) -} - func autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error { if err := v1.Convert_Pointer_bool_To_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil { return err @@ -220,47 +131,3 @@ func autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionCo out.ResourceNamespace = in.ResourceNamespace return nil } - -func autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in *LoggingConfiguration, out *config.LoggingConfiguration, s conversion.Scope) error { - out.Format = in.Format - out.FlushFrequency = time.Duration(in.FlushFrequency) - out.Verbosity = config.VerbosityLevel(in.Verbosity) - out.VModule = *(*config.VModuleConfiguration)(unsafe.Pointer(&in.VModule)) - if err := Convert_v1alpha1_FormatOptions_To_config_FormatOptions(&in.Options, &out.Options, s); err != nil { - return err - } - return nil -} - -func autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in *config.LoggingConfiguration, out *LoggingConfiguration, s conversion.Scope) error { - out.Format = in.Format - out.FlushFrequency = time.Duration(in.FlushFrequency) - out.Verbosity = uint32(in.Verbosity) - out.VModule = *(*VModuleConfiguration)(unsafe.Pointer(&in.VModule)) - if err := Convert_config_FormatOptions_To_v1alpha1_FormatOptions(&in.Options, &out.Options, s); err != nil { - return err - } - return nil -} - -func autoConvert_v1alpha1_VModuleItem_To_config_VModuleItem(in *VModuleItem, out *config.VModuleItem, s conversion.Scope) error { - out.FilePattern = in.FilePattern - out.Verbosity = config.VerbosityLevel(in.Verbosity) - return nil -} - -// Convert_v1alpha1_VModuleItem_To_config_VModuleItem is an autogenerated conversion function. -func Convert_v1alpha1_VModuleItem_To_config_VModuleItem(in *VModuleItem, out *config.VModuleItem, s conversion.Scope) error { - return autoConvert_v1alpha1_VModuleItem_To_config_VModuleItem(in, out, s) -} - -func autoConvert_config_VModuleItem_To_v1alpha1_VModuleItem(in *config.VModuleItem, out *VModuleItem, s conversion.Scope) error { - out.FilePattern = in.FilePattern - out.Verbosity = uint32(in.Verbosity) - return nil -} - -// Convert_config_VModuleItem_To_v1alpha1_VModuleItem is an autogenerated conversion function. -func Convert_config_VModuleItem_To_v1alpha1_VModuleItem(in *config.VModuleItem, out *VModuleItem, s conversion.Scope) error { - return autoConvert_config_VModuleItem_To_v1alpha1_VModuleItem(in, out, s) -} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go index 5503e7a869d..92176d9944c 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go @@ -63,40 +63,6 @@ func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FormatOptions) DeepCopyInto(out *FormatOptions) { - *out = *in - in.JSON.DeepCopyInto(&out.JSON) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FormatOptions. -func (in *FormatOptions) DeepCopy() *FormatOptions { - if in == nil { - return nil - } - out := new(FormatOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JSONOptions) DeepCopyInto(out *JSONOptions) { - *out = *in - in.InfoBufferSize.DeepCopyInto(&out.InfoBufferSize) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONOptions. -func (in *JSONOptions) DeepCopy() *JSONOptions { - if in == nil { - return nil - } - out := new(JSONOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { *out = *in @@ -120,61 +86,3 @@ func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LoggingConfiguration) DeepCopyInto(out *LoggingConfiguration) { - *out = *in - if in.VModule != nil { - in, out := &in.VModule, &out.VModule - *out = make(VModuleConfiguration, len(*in)) - copy(*out, *in) - } - in.Options.DeepCopyInto(&out.Options) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfiguration. -func (in *LoggingConfiguration) DeepCopy() *LoggingConfiguration { - if in == nil { - return nil - } - out := new(LoggingConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in VModuleConfiguration) DeepCopyInto(out *VModuleConfiguration) { - { - in := &in - *out = make(VModuleConfiguration, len(*in)) - copy(*out, *in) - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleConfiguration. -func (in VModuleConfiguration) DeepCopy() VModuleConfiguration { - if in == nil { - return nil - } - out := new(VModuleConfiguration) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VModuleItem) DeepCopyInto(out *VModuleItem) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleItem. -func (in *VModuleItem) DeepCopy() *VModuleItem { - if in == nil { - return nil - } - out := new(VModuleItem) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go index ede25cd32f3..fb0c1f1e6a8 100644 --- a/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go +++ b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go @@ -53,40 +53,6 @@ func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FormatOptions) DeepCopyInto(out *FormatOptions) { - *out = *in - in.JSON.DeepCopyInto(&out.JSON) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FormatOptions. -func (in *FormatOptions) DeepCopy() *FormatOptions { - if in == nil { - return nil - } - out := new(FormatOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JSONOptions) DeepCopyInto(out *JSONOptions) { - *out = *in - in.InfoBufferSize.DeepCopyInto(&out.InfoBufferSize) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONOptions. -func (in *JSONOptions) DeepCopy() *JSONOptions { - if in == nil { - return nil - } - out := new(JSONOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { *out = *in @@ -105,61 +71,3 @@ func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LoggingConfiguration) DeepCopyInto(out *LoggingConfiguration) { - *out = *in - if in.VModule != nil { - in, out := &in.VModule, &out.VModule - *out = make(VModuleConfiguration, len(*in)) - copy(*out, *in) - } - in.Options.DeepCopyInto(&out.Options) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfiguration. -func (in *LoggingConfiguration) DeepCopy() *LoggingConfiguration { - if in == nil { - return nil - } - out := new(LoggingConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in VModuleConfiguration) DeepCopyInto(out *VModuleConfiguration) { - { - in := &in - *out = make(VModuleConfiguration, len(*in)) - copy(*out, *in) - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleConfiguration. -func (in VModuleConfiguration) DeepCopy() VModuleConfiguration { - if in == nil { - return nil - } - out := new(VModuleConfiguration) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VModuleItem) DeepCopyInto(out *VModuleItem) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleItem. -func (in *VModuleItem) DeepCopy() *VModuleItem { - if in == nil { - return nil - } - out := new(VModuleItem) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/component-base/featuregate/feature_gate.go b/vendor/k8s.io/component-base/featuregate/feature_gate.go index c7166d80b84..a826b0e67ef 100644 --- a/vendor/k8s.io/component-base/featuregate/feature_gate.go +++ b/vendor/k8s.io/component-base/featuregate/feature_gate.go @@ -17,6 +17,7 @@ limitations under the License. package featuregate import ( + "context" "fmt" "sort" "strconv" @@ -27,6 +28,7 @@ import ( "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/util/naming" + featuremetrics "k8s.io/component-base/metrics/prometheus/feature" "k8s.io/klog/v2" ) @@ -111,6 +113,8 @@ type MutableFeatureGate interface { Add(features map[Feature]FeatureSpec) error // GetAll returns a copy of the map of known feature names to feature specs. GetAll() map[Feature]FeatureSpec + // AddMetrics adds feature enablement metrics + AddMetrics() } // featureGate implements FeatureGate as well as pflag.Value for flag parsing. @@ -329,6 +333,12 @@ func (f *featureGate) AddFlag(fs *pflag.FlagSet) { "Options are:\n"+strings.Join(known, "\n")) } +func (f *featureGate) AddMetrics() { + for feature, featureSpec := range f.GetAll() { + featuremetrics.RecordFeatureInfo(context.Background(), string(feature), string(featureSpec.PreRelease), f.Enabled(feature)) + } +} + // KnownFeatures returns a slice of strings describing the FeatureGate's known features. // Deprecated and GA features are hidden from the list. func (f *featureGate) KnownFeatures() []string { diff --git a/vendor/k8s.io/component-base/metrics/buckets.go b/vendor/k8s.io/component-base/metrics/buckets.go new file mode 100644 index 00000000000..48d3093e0cd --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/buckets.go @@ -0,0 +1,43 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +// DefBuckets is a wrapper for prometheus.DefBuckets +var DefBuckets = prometheus.DefBuckets + +// LinearBuckets is a wrapper for prometheus.LinearBuckets. +func LinearBuckets(start, width float64, count int) []float64 { + return prometheus.LinearBuckets(start, width, count) +} + +// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets. +func ExponentialBuckets(start, factor float64, count int) []float64 { + return prometheus.ExponentialBuckets(start, factor, count) +} + +// MergeBuckets merges buckets together +func MergeBuckets(buckets ...[]float64) []float64 { + result := make([]float64, 1) + for _, s := range buckets { + result = append(result, s...) + } + return result +} diff --git a/vendor/k8s.io/component-base/metrics/collector.go b/vendor/k8s.io/component-base/metrics/collector.go index 113b903ec27..0718b6e1358 100644 --- a/vendor/k8s.io/component-base/metrics/collector.go +++ b/vendor/k8s.io/component-base/metrics/collector.go @@ -45,9 +45,9 @@ type StableCollector interface { HiddenMetrics() []string } -// BaseStableCollector which implements almost all of the methods defined by StableCollector +// BaseStableCollector which implements almost all methods defined by StableCollector // is a convenient assistant for custom collectors. -// It is recommend that inherit BaseStableCollector when implementing custom collectors. +// It is recommended to inherit BaseStableCollector when implementing custom collectors. type BaseStableCollector struct { descriptors map[string]*Desc // stores all descriptors by pair, these are collected from DescribeWithStability(). registerable map[string]*Desc // stores registerable descriptors by pair, is a subset of descriptors. @@ -62,7 +62,7 @@ func (bsc *BaseStableCollector) DescribeWithStability(ch chan<- *Desc) { } // Describe sends all descriptors to the provided channel. -// It intend to be called by prometheus registry. +// It intended to be called by prometheus registry. func (bsc *BaseStableCollector) Describe(ch chan<- *prometheus.Desc) { for _, d := range bsc.registerable { ch <- d.toPrometheusDesc() diff --git a/vendor/k8s.io/component-base/metrics/counter.go b/vendor/k8s.io/component-base/metrics/counter.go index 7342dc37d1e..5664a68a900 100644 --- a/vendor/k8s.io/component-base/metrics/counter.go +++ b/vendor/k8s.io/component-base/metrics/counter.go @@ -18,6 +18,7 @@ package metrics import ( "context" + "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" @@ -43,7 +44,7 @@ func NewCounter(opts *CounterOpts) *Counter { kc := &Counter{ CounterOpts: opts, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } kc.setPrometheusCounter(noop) kc.lazyInit(kc, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)) @@ -106,9 +107,14 @@ type CounterVec struct { originalLabels []string } -// NewCounterVec returns an object which satisfies the kubeCollector and CounterVecMetric interfaces. +var _ kubeCollector = &CounterVec{} + +// TODO: make this true: var _ CounterVecMetric = &CounterVec{} + +// NewCounterVec returns an object which satisfies the kubeCollector and (almost) CounterVecMetric interfaces. // However, the object returned will not measure anything unless the collector is first -// registered, since the metric is lazily instantiated. +// registered, since the metric is lazily instantiated, and only members extracted after +// registration will actually measure anything. func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec { opts.StabilityLevel.setDefaults() @@ -123,7 +129,7 @@ func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec { CounterVec: noopCounterVec, CounterOpts: opts, originalLabels: labels, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } cv.lazyInit(cv, fqName) return cv @@ -149,13 +155,16 @@ func (v *CounterVec) initializeDeprecatedMetric() { v.initializeMetric() } -// Default Prometheus behavior actually results in the creation of a new metric -// if a metric with the unique label values is not found in the underlying stored metricMap. +// Default Prometheus Vec behavior is that member extraction results in creation of a new element +// if one with the unique label values is not found in the underlying stored metricMap. // This means that if this function is called but the underlying metric is not registered // (which means it will never be exposed externally nor consumed), the metric will exist in memory // for perpetuity (i.e. throughout application lifecycle). // // For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/counter.go#L179-L197 +// +// In contrast, the Vec behavior in this package is that member extraction before registration +// returns a permanent noop object. // WithLabelValues returns the Counter for the given slice of label // values (same order as the VariableLabels in Desc). If that combination of diff --git a/vendor/k8s.io/component-base/metrics/desc.go b/vendor/k8s.io/component-base/metrics/desc.go index 50eefd587fb..2ca9cfa7c21 100644 --- a/vendor/k8s.io/component-base/metrics/desc.go +++ b/vendor/k8s.io/component-base/metrics/desc.go @@ -218,8 +218,8 @@ func (d *Desc) initializeDeprecatedDesc() { // GetRawDesc will returns a new *Desc with original parameters provided to NewDesc(). // // It will be useful in testing scenario that the same Desc be registered to different registry. -// 1. Desc `D` is registered to registry 'A' in TestA (Note: `D` maybe created) -// 2. Desc `D` is registered to registry 'B' in TestB (Note: since 'D' has been created once, thus will be ignored by registry 'B') +// 1. Desc `D` is registered to registry 'A' in TestA (Note: `D` maybe created) +// 2. Desc `D` is registered to registry 'B' in TestB (Note: since 'D' has been created once, thus will be ignored by registry 'B') func (d *Desc) GetRawDesc() *Desc { return NewDesc(d.fqName, d.help, d.variableLabels, d.constLabels, d.stabilityLevel, d.deprecatedVersion) } diff --git a/vendor/k8s.io/component-base/metrics/gauge.go b/vendor/k8s.io/component-base/metrics/gauge.go index 168221ecdd5..89631115acb 100644 --- a/vendor/k8s.io/component-base/metrics/gauge.go +++ b/vendor/k8s.io/component-base/metrics/gauge.go @@ -18,6 +18,7 @@ package metrics import ( "context" + "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" @@ -33,7 +34,11 @@ type Gauge struct { selfCollector } -// NewGauge returns an object which satisfies the kubeCollector and KubeGauge interfaces. +var _ GaugeMetric = &Gauge{} +var _ Registerable = &Gauge{} +var _ kubeCollector = &Gauge{} + +// NewGauge returns an object which satisfies the kubeCollector, Registerable, and Gauge interfaces. // However, the object returned will not measure anything unless the collector is first // registered, since the metric is lazily instantiated. func NewGauge(opts *GaugeOpts) *Gauge { @@ -41,7 +46,7 @@ func NewGauge(opts *GaugeOpts) *Gauge { kc := &Gauge{ GaugeOpts: opts, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } kc.setPrometheusGauge(noop) kc.lazyInit(kc, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)) @@ -88,9 +93,14 @@ type GaugeVec struct { originalLabels []string } -// NewGaugeVec returns an object which satisfies the kubeCollector and KubeGaugeVec interfaces. +var _ GaugeVecMetric = &GaugeVec{} +var _ Registerable = &GaugeVec{} +var _ kubeCollector = &GaugeVec{} + +// NewGaugeVec returns an object which satisfies the kubeCollector, Registerable, and GaugeVecMetric interfaces. // However, the object returned will not measure anything unless the collector is first -// registered, since the metric is lazily instantiated. +// registered, since the metric is lazily instantiated, and only members extracted after +// registration will actually measure anything. func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec { opts.StabilityLevel.setDefaults() @@ -105,7 +115,7 @@ func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec { GaugeVec: noopGaugeVec, GaugeOpts: opts, originalLabels: labels, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } cv.lazyInit(cv, fqName) return cv @@ -130,26 +140,55 @@ func (v *GaugeVec) initializeDeprecatedMetric() { v.initializeMetric() } -// Default Prometheus behavior actually results in the creation of a new metric -// if a metric with the unique label values is not found in the underlying stored metricMap. +func (v *GaugeVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) { + if !v.IsCreated() { + if v.IsHidden() { + return noop, nil + } + return noop, errNotRegistered // return no-op gauge + } + if v.LabelValueAllowLists != nil { + v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs) + } + elt, err := v.GaugeVec.GetMetricWithLabelValues(lvs...) + return elt, err +} + +// Default Prometheus Vec behavior is that member extraction results in creation of a new element +// if one with the unique label values is not found in the underlying stored metricMap. // This means that if this function is called but the underlying metric is not registered // (which means it will never be exposed externally nor consumed), the metric will exist in memory // for perpetuity (i.e. throughout application lifecycle). // // For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/gauge.go#L190-L208 +// +// In contrast, the Vec behavior in this package is that member extraction before registration +// returns a permanent noop object. // WithLabelValues returns the GaugeMetric for the given slice of label // values (same order as the VariableLabels in Desc). If that combination of // label values is accessed for the first time, a new GaugeMetric is created IFF the gaugeVec // has been registered to a metrics registry. func (v *GaugeVec) WithLabelValues(lvs ...string) GaugeMetric { + ans, err := v.WithLabelValuesChecked(lvs...) + if err == nil || ErrIsNotRegistered(err) { + return ans + } + panic(err) +} + +func (v *GaugeVec) WithChecked(labels map[string]string) (GaugeMetric, error) { if !v.IsCreated() { - return noop // return no-op gauge + if v.IsHidden() { + return noop, nil + } + return noop, errNotRegistered // return no-op gauge } if v.LabelValueAllowLists != nil { - v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs) + v.LabelValueAllowLists.ConstrainLabelMap(labels) } - return v.GaugeVec.WithLabelValues(lvs...) + elt, err := v.GaugeVec.GetMetricWith(labels) + return elt, err } // With returns the GaugeMetric for the given Labels map (the label names @@ -157,13 +196,11 @@ func (v *GaugeVec) WithLabelValues(lvs ...string) GaugeMetric { // accessed for the first time, a new GaugeMetric is created IFF the gaugeVec has // been registered to a metrics registry. func (v *GaugeVec) With(labels map[string]string) GaugeMetric { - if !v.IsCreated() { - return noop // return no-op gauge + ans, err := v.WithChecked(labels) + if err == nil || ErrIsNotRegistered(err) { + return ans } - if v.LabelValueAllowLists != nil { - v.LabelValueAllowLists.ConstrainLabelMap(labels) - } - return v.GaugeVec.With(labels) + panic(err) } // Delete deletes the metric where the variable labels are the same as those @@ -219,6 +256,10 @@ func (v *GaugeVec) WithContext(ctx context.Context) *GaugeVecWithContext { } } +func (v *GaugeVec) InterfaceWithContext(ctx context.Context) GaugeVecMetric { + return v.WithContext(ctx) +} + // GaugeVecWithContext is the wrapper of GaugeVec with context. type GaugeVecWithContext struct { *GaugeVec diff --git a/vendor/k8s.io/component-base/metrics/histogram.go b/vendor/k8s.io/component-base/metrics/histogram.go index e93c7a4b3ff..e6884f35c6f 100644 --- a/vendor/k8s.io/component-base/metrics/histogram.go +++ b/vendor/k8s.io/component-base/metrics/histogram.go @@ -18,23 +18,11 @@ package metrics import ( "context" + "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" ) -// DefBuckets is a wrapper for prometheus.DefBuckets -var DefBuckets = prometheus.DefBuckets - -// LinearBuckets is a wrapper for prometheus.LinearBuckets. -func LinearBuckets(start, width float64, count int) []float64 { - return prometheus.LinearBuckets(start, width, count) -} - -// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets. -func ExponentialBuckets(start, factor float64, count int) []float64 { - return prometheus.ExponentialBuckets(start, factor, count) -} - // Histogram is our internal representation for our wrapping struct around prometheus // histograms. Summary implements both kubeCollector and ObserverMetric type Histogram struct { @@ -51,7 +39,7 @@ func NewHistogram(opts *HistogramOpts) *Histogram { h := &Histogram{ HistogramOpts: opts, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } h.setPrometheusHistogram(noopMetric{}) h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)) @@ -100,7 +88,10 @@ type HistogramVec struct { // NewHistogramVec returns an object which satisfies kubeCollector and wraps the // prometheus.HistogramVec object. However, the object returned will not measure -// anything unless the collector is first registered, since the metric is lazily instantiated. +// anything unless the collector is first registered, since the metric is lazily instantiated, +// and only members extracted after +// registration will actually measure anything. + func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec { opts.StabilityLevel.setDefaults() @@ -115,7 +106,7 @@ func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec { HistogramVec: noopHistogramVec, HistogramOpts: opts, originalLabels: labels, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } v.lazyInit(v, fqName) return v @@ -136,13 +127,16 @@ func (v *HistogramVec) initializeDeprecatedMetric() { v.initializeMetric() } -// Default Prometheus behavior actually results in the creation of a new metric -// if a metric with the unique label values is not found in the underlying stored metricMap. +// Default Prometheus Vec behavior is that member extraction results in creation of a new element +// if one with the unique label values is not found in the underlying stored metricMap. // This means that if this function is called but the underlying metric is not registered // (which means it will never be exposed externally nor consumed), the metric will exist in memory // for perpetuity (i.e. throughout application lifecycle). // // For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/histogram.go#L460-L470 +// +// In contrast, the Vec behavior in this package is that member extraction before registration +// returns a permanent noop object. // WithLabelValues returns the ObserverMetric for the given slice of label // values (same order as the VariableLabels in Desc). If that combination of diff --git a/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go b/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go index c0092a36577..79c806d8b2a 100644 --- a/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go +++ b/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go @@ -20,6 +20,7 @@ import ( "net/http" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "k8s.io/component-base/metrics" @@ -41,13 +42,15 @@ var ( // Register registers a collectable metric but uses the global registry Register = defaultRegistry.Register + + // Registerer exposes the global registerer + Registerer = defaultRegistry.Registerer ) func init() { - //nolint:staticcheck // SA1019 - replacement function still calls prometheus.NewProcessCollector(). - RawMustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) - //nolint:staticcheck // SA1019 - replacement function still calls prometheus.NewGoCollector(). - RawMustRegister(prometheus.NewGoCollector()) + RawMustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{})) + RawMustRegister(collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll))) + defaultRegistry.RegisterMetaMetrics() } // Handler returns an HTTP handler for the DefaultGatherer. It is diff --git a/vendor/k8s.io/component-base/metrics/metric.go b/vendor/k8s.io/component-base/metrics/metric.go index c72aecfc6b4..3b22d21ef25 100644 --- a/vendor/k8s.io/component-base/metrics/metric.go +++ b/vendor/k8s.io/component-base/metrics/metric.go @@ -22,6 +22,7 @@ import ( "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" + promext "k8s.io/component-base/metrics/prometheusextension" "k8s.io/klog/v2" ) @@ -71,6 +72,7 @@ type lazyMetric struct { markDeprecationOnce sync.Once createOnce sync.Once self kubeCollector + stabilityLevel StabilityLevel } func (r *lazyMetric) IsCreated() bool { @@ -90,13 +92,13 @@ func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) { // preprocessMetric figures out whether the lazy metric should be hidden or not. // This method takes a Version argument which should be the version of the binary in which // this code is currently being executed. A metric can be hidden under two conditions: -// 1. if the metric is deprecated and is outside the grace period (i.e. has been -// deprecated for more than one release -// 2. if the metric is manually disabled via a CLI flag. +// 1. if the metric is deprecated and is outside the grace period (i.e. has been +// deprecated for more than one release +// 2. if the metric is manually disabled via a CLI flag. // // Disclaimer: disabling a metric via a CLI flag has higher precedence than -// deprecation and will override show-hidden-metrics for the explicitly -// disabled metric. +// deprecation and will override show-hidden-metrics for the explicitly +// disabled metric. func (r *lazyMetric) preprocessMetric(version semver.Version) { disabledMetricsLock.RLock() defer disabledMetricsLock.RUnlock() @@ -147,6 +149,7 @@ func (r *lazyMetric) Create(version *semver.Version) bool { if r.IsHidden() { return false } + r.createOnce.Do(func() { r.createLock.Lock() defer r.createLock.Unlock() @@ -157,6 +160,13 @@ func (r *lazyMetric) Create(version *semver.Version) bool { r.self.initializeMetric() } }) + sl := r.stabilityLevel + deprecatedV := r.self.DeprecatedVersion() + dv := "" + if deprecatedV != nil { + dv = deprecatedV.String() + } + registeredMetrics.WithLabelValues(string(sl), dv).Inc() return r.IsCreated() } @@ -203,41 +213,23 @@ func (c *selfCollector) Collect(ch chan<- prometheus.Metric) { // no-op vecs for convenience var noopCounterVec = &prometheus.CounterVec{} var noopHistogramVec = &prometheus.HistogramVec{} +var noopTimingHistogramVec = &promext.TimingHistogramVec{} var noopGaugeVec = &prometheus.GaugeVec{} -var noopObserverVec = &noopObserverVector{} // just use a convenience struct for all the no-ops var noop = &noopMetric{} type noopMetric struct{} -func (noopMetric) Inc() {} -func (noopMetric) Add(float64) {} -func (noopMetric) Dec() {} -func (noopMetric) Set(float64) {} -func (noopMetric) Sub(float64) {} -func (noopMetric) Observe(float64) {} -func (noopMetric) SetToCurrentTime() {} -func (noopMetric) Desc() *prometheus.Desc { return nil } -func (noopMetric) Write(*dto.Metric) error { return nil } -func (noopMetric) Describe(chan<- *prometheus.Desc) {} -func (noopMetric) Collect(chan<- prometheus.Metric) {} - -type noopObserverVector struct{} - -func (noopObserverVector) GetMetricWith(prometheus.Labels) (prometheus.Observer, error) { - return noop, nil -} -func (noopObserverVector) GetMetricWithLabelValues(...string) (prometheus.Observer, error) { - return noop, nil -} -func (noopObserverVector) With(prometheus.Labels) prometheus.Observer { return noop } -func (noopObserverVector) WithLabelValues(...string) prometheus.Observer { return noop } -func (noopObserverVector) CurryWith(prometheus.Labels) (prometheus.ObserverVec, error) { - return noopObserverVec, nil -} -func (noopObserverVector) MustCurryWith(prometheus.Labels) prometheus.ObserverVec { - return noopObserverVec -} -func (noopObserverVector) Describe(chan<- *prometheus.Desc) {} -func (noopObserverVector) Collect(chan<- prometheus.Metric) {} +func (noopMetric) Inc() {} +func (noopMetric) Add(float64) {} +func (noopMetric) Dec() {} +func (noopMetric) Set(float64) {} +func (noopMetric) Sub(float64) {} +func (noopMetric) Observe(float64) {} +func (noopMetric) ObserveWithWeight(float64, uint64) {} +func (noopMetric) SetToCurrentTime() {} +func (noopMetric) Desc() *prometheus.Desc { return nil } +func (noopMetric) Write(*dto.Metric) error { return nil } +func (noopMetric) Describe(chan<- *prometheus.Desc) {} +func (noopMetric) Collect(chan<- prometheus.Metric) {} diff --git a/vendor/k8s.io/component-base/metrics/opts.go b/vendor/k8s.io/component-base/metrics/opts.go index 04203b74e0a..49d2d40bbf7 100644 --- a/vendor/k8s.io/component-base/metrics/opts.go +++ b/vendor/k8s.io/component-base/metrics/opts.go @@ -24,6 +24,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "k8s.io/apimachinery/pkg/util/sets" + promext "k8s.io/component-base/metrics/prometheusextension" ) var ( @@ -65,9 +66,15 @@ func BuildFQName(namespace, subsystem, name string) string { type StabilityLevel string const ( + // INTERNAL metrics have no stability guarantees, as such, labels may + // be arbitrarily added/removed and the metric may be deleted at any time. + INTERNAL StabilityLevel = "INTERNAL" // ALPHA metrics have no stability guarantees, as such, labels may // be arbitrarily added/removed and the metric may be deleted at any time. ALPHA StabilityLevel = "ALPHA" + // BETA metrics are governed by the deprecation policy outlined in by + // the control plane metrics stability KEP. + BETA StabilityLevel = "BETA" // STABLE metrics are guaranteed not be mutated and removal is governed by // the deprecation policy outlined in by the control plane metrics stability KEP. STABLE StabilityLevel = "STABLE" @@ -189,6 +196,54 @@ func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts { } } +// TimingHistogramOpts bundles the options for creating a TimingHistogram metric. It is +// mandatory to set Name to a non-empty string. All other fields are optional +// and can safely be left at their zero value, although it is strongly +// encouraged to set a Help string. +type TimingHistogramOpts struct { + Namespace string + Subsystem string + Name string + Help string + ConstLabels map[string]string + Buckets []float64 + InitialValue float64 + DeprecatedVersion string + deprecateOnce sync.Once + annotateOnce sync.Once + StabilityLevel StabilityLevel + LabelValueAllowLists *MetricLabelAllowList +} + +// Modify help description on the metric description. +func (o *TimingHistogramOpts) markDeprecated() { + o.deprecateOnce.Do(func() { + o.Help = fmt.Sprintf("(Deprecated since %v) %v", o.DeprecatedVersion, o.Help) + }) +} + +// annotateStabilityLevel annotates help description on the metric description with the stability level +// of the metric +func (o *TimingHistogramOpts) annotateStabilityLevel() { + o.annotateOnce.Do(func() { + o.Help = fmt.Sprintf("[%v] %v", o.StabilityLevel, o.Help) + }) +} + +// convenience function to allow easy transformation to the prometheus +// counterpart. This will do more once we have a proper label abstraction +func (o *TimingHistogramOpts) toPromHistogramOpts() promext.TimingHistogramOpts { + return promext.TimingHistogramOpts{ + Namespace: o.Namespace, + Subsystem: o.Subsystem, + Name: o.Name, + Help: o.Help, + ConstLabels: o.ConstLabels, + Buckets: o.Buckets, + InitialValue: o.InitialValue, + } +} + // SummaryOpts bundles the options for creating a Summary metric. It is // mandatory to set Name to a non-empty string. While all other fields are // optional and can safely be left at their zero value, it is recommended to set diff --git a/vendor/k8s.io/component-base/metrics/prometheus/feature/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/feature/metrics.go new file mode 100644 index 00000000000..d19357fde55 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/feature/metrics.go @@ -0,0 +1,53 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package feature + +import ( + "context" + + k8smetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +var ( + // featureInfo is a Prometheus Gauge metrics used for recording the enablement of a k8s feature. + featureInfo = k8smetrics.NewGaugeVec( + &k8smetrics.GaugeOpts{ + Namespace: "kubernetes", + Name: "feature_enabled", + Help: "This metric records the data about the stage and enablement of a k8s feature.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "stage"}, + ) +) + +func init() { + legacyregistry.MustRegister(featureInfo) +} + +func ResetFeatureInfoMetric() { + featureInfo.Reset() +} + +func RecordFeatureInfo(ctx context.Context, name string, stage string, enabled bool) { + value := 0.0 + if enabled { + value = 1.0 + } + featureInfo.WithContext(ctx).WithLabelValues(name, stage).Set(value) +} diff --git a/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go b/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go new file mode 100644 index 00000000000..be07977e281 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go @@ -0,0 +1,189 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prometheusextension + +import ( + "errors" + "time" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" +) + +// GaugeOps is the part of `prometheus.Gauge` that is relevant to +// instrumented code. +// This factoring should be in prometheus, analogous to the way +// it already factors out the Observer interface for histograms and summaries. +type GaugeOps interface { + // Set is the same as Gauge.Set + Set(float64) + // Inc is the same as Gauge.inc + Inc() + // Dec is the same as Gauge.Dec + Dec() + // Add is the same as Gauge.Add + Add(float64) + // Sub is the same as Gauge.Sub + Sub(float64) + + // SetToCurrentTime the same as Gauge.SetToCurrentTime + SetToCurrentTime() +} + +// A TimingHistogram tracks how long a `float64` variable spends in +// ranges defined by buckets. Time is counted in nanoseconds. The +// histogram's sum is the integral over time (in nanoseconds, from +// creation of the histogram) of the variable's value. +type TimingHistogram interface { + prometheus.Metric + prometheus.Collector + GaugeOps +} + +// TimingHistogramOpts is the parameters of the TimingHistogram constructor +type TimingHistogramOpts struct { + Namespace string + Subsystem string + Name string + Help string + ConstLabels prometheus.Labels + + // Buckets defines the buckets into which observations are + // accumulated. Each element in the slice is the upper + // inclusive bound of a bucket. The values must be sorted in + // strictly increasing order. There is no need to add a + // highest bucket with +Inf bound. The default value is + // prometheus.DefBuckets. + Buckets []float64 + + // The initial value of the variable. + InitialValue float64 +} + +// NewTimingHistogram creates a new TimingHistogram +func NewTimingHistogram(opts TimingHistogramOpts) (TimingHistogram, error) { + return NewTestableTimingHistogram(time.Now, opts) +} + +// NewTestableTimingHistogram creates a TimingHistogram that uses a mockable clock +func NewTestableTimingHistogram(nowFunc func() time.Time, opts TimingHistogramOpts) (TimingHistogram, error) { + desc := prometheus.NewDesc( + prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), + wrapTimingHelp(opts.Help), + nil, + opts.ConstLabels, + ) + return newTimingHistogram(nowFunc, desc, opts) +} + +func wrapTimingHelp(given string) string { + return "EXPERIMENTAL: " + given +} + +func newTimingHistogram(nowFunc func() time.Time, desc *prometheus.Desc, opts TimingHistogramOpts, variableLabelValues ...string) (TimingHistogram, error) { + allLabelsM := prometheus.Labels{} + allLabelsS := prometheus.MakeLabelPairs(desc, variableLabelValues) + for _, pair := range allLabelsS { + if pair == nil || pair.Name == nil || pair.Value == nil { + return nil, errors.New("prometheus.MakeLabelPairs returned a nil") + } + allLabelsM[*pair.Name] = *pair.Value + } + weighted, err := newWeightedHistogram(desc, WeightedHistogramOpts{ + Namespace: opts.Namespace, + Subsystem: opts.Subsystem, + Name: opts.Name, + Help: opts.Help, + ConstLabels: allLabelsM, + Buckets: opts.Buckets, + }, variableLabelValues...) + if err != nil { + return nil, err + } + return &timingHistogram{ + nowFunc: nowFunc, + weighted: weighted, + lastSetTime: nowFunc(), + value: opts.InitialValue, + }, nil +} + +type timingHistogram struct { + nowFunc func() time.Time + weighted *weightedHistogram + + // The following fields must only be accessed with weighted's lock held + + lastSetTime time.Time // identifies when value was last set + value float64 +} + +var _ TimingHistogram = &timingHistogram{} + +func (th *timingHistogram) Set(newValue float64) { + th.update(func(float64) float64 { return newValue }) +} + +func (th *timingHistogram) Inc() { + th.update(func(oldValue float64) float64 { return oldValue + 1 }) +} + +func (th *timingHistogram) Dec() { + th.update(func(oldValue float64) float64 { return oldValue - 1 }) +} + +func (th *timingHistogram) Add(delta float64) { + th.update(func(oldValue float64) float64 { return oldValue + delta }) +} + +func (th *timingHistogram) Sub(delta float64) { + th.update(func(oldValue float64) float64 { return oldValue - delta }) +} + +func (th *timingHistogram) SetToCurrentTime() { + th.update(func(oldValue float64) float64 { return th.nowFunc().Sub(time.Unix(0, 0)).Seconds() }) +} + +func (th *timingHistogram) update(updateFn func(float64) float64) { + th.weighted.lock.Lock() + defer th.weighted.lock.Unlock() + now := th.nowFunc() + delta := now.Sub(th.lastSetTime) + value := th.value + if delta > 0 { + th.weighted.observeWithWeightLocked(value, uint64(delta)) + th.lastSetTime = now + } + th.value = updateFn(value) +} + +func (th *timingHistogram) Desc() *prometheus.Desc { + return th.weighted.Desc() +} + +func (th *timingHistogram) Write(dest *dto.Metric) error { + th.Add(0) // account for time since last update + return th.weighted.Write(dest) +} + +func (th *timingHistogram) Describe(ch chan<- *prometheus.Desc) { + ch <- th.weighted.Desc() +} + +func (th *timingHistogram) Collect(ch chan<- prometheus.Metric) { + ch <- th +} diff --git a/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go b/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go new file mode 100644 index 00000000000..7af1a45860a --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go @@ -0,0 +1,111 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prometheusextension + +import ( + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +// GaugeVecOps is a bunch of Gauge that have the same +// Desc and are distinguished by the values for their variable labels. +type GaugeVecOps interface { + GetMetricWith(prometheus.Labels) (GaugeOps, error) + GetMetricWithLabelValues(lvs ...string) (GaugeOps, error) + With(prometheus.Labels) GaugeOps + WithLabelValues(...string) GaugeOps + CurryWith(prometheus.Labels) (GaugeVecOps, error) + MustCurryWith(prometheus.Labels) GaugeVecOps +} + +type TimingHistogramVec struct { + *prometheus.MetricVec +} + +var _ GaugeVecOps = &TimingHistogramVec{} +var _ prometheus.Collector = &TimingHistogramVec{} + +func NewTimingHistogramVec(opts TimingHistogramOpts, labelNames ...string) *TimingHistogramVec { + return NewTestableTimingHistogramVec(time.Now, opts, labelNames...) +} + +func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts TimingHistogramOpts, labelNames ...string) *TimingHistogramVec { + desc := prometheus.NewDesc( + prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), + wrapTimingHelp(opts.Help), + labelNames, + opts.ConstLabels, + ) + return &TimingHistogramVec{ + MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric { + metric, err := newTimingHistogram(nowFunc, desc, opts, lvs...) + if err != nil { + panic(err) // like in prometheus.newHistogram + } + return metric + }), + } +} + +func (hv *TimingHistogramVec) GetMetricWith(labels prometheus.Labels) (GaugeOps, error) { + metric, err := hv.MetricVec.GetMetricWith(labels) + if metric != nil { + return metric.(GaugeOps), err + } + return nil, err +} + +func (hv *TimingHistogramVec) GetMetricWithLabelValues(lvs ...string) (GaugeOps, error) { + metric, err := hv.MetricVec.GetMetricWithLabelValues(lvs...) + if metric != nil { + return metric.(GaugeOps), err + } + return nil, err +} + +func (hv *TimingHistogramVec) With(labels prometheus.Labels) GaugeOps { + h, err := hv.GetMetricWith(labels) + if err != nil { + panic(err) + } + return h +} + +func (hv *TimingHistogramVec) WithLabelValues(lvs ...string) GaugeOps { + h, err := hv.GetMetricWithLabelValues(lvs...) + if err != nil { + panic(err) + } + return h +} + +func (hv *TimingHistogramVec) CurryWith(labels prometheus.Labels) (GaugeVecOps, error) { + vec, err := hv.MetricVec.CurryWith(labels) + if vec != nil { + return &TimingHistogramVec{MetricVec: vec}, err + } + return nil, err +} + +func (hv *TimingHistogramVec) MustCurryWith(labels prometheus.Labels) GaugeVecOps { + vec, err := hv.CurryWith(labels) + if err != nil { + panic(err) + } + return vec +} diff --git a/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go b/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go new file mode 100644 index 00000000000..a060019b254 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go @@ -0,0 +1,203 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prometheusextension + +import ( + "fmt" + "math" + "sort" + "sync" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" +) + +// WeightedHistogram generalizes Histogram: each observation has +// an associated _weight_. For a given `x` and `N`, +// `1` call on `ObserveWithWeight(x, N)` has the same meaning as +// `N` calls on `ObserveWithWeight(x, 1)`. +// The weighted sum might differ slightly due to the use of +// floating point, although the implementation takes some steps +// to mitigate that. +// If every weight were 1, +// this would be the same as the existing Histogram abstraction. +type WeightedHistogram interface { + prometheus.Metric + prometheus.Collector + WeightedObserver +} + +// WeightedObserver generalizes the Observer interface. +type WeightedObserver interface { + // Set the variable to the given value with the given weight. + ObserveWithWeight(value float64, weight uint64) +} + +// WeightedHistogramOpts is the same as for an ordinary Histogram +type WeightedHistogramOpts = prometheus.HistogramOpts + +// NewWeightedHistogram creates a new WeightedHistogram +func NewWeightedHistogram(opts WeightedHistogramOpts) (WeightedHistogram, error) { + desc := prometheus.NewDesc( + prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), + wrapWeightedHelp(opts.Help), + nil, + opts.ConstLabels, + ) + return newWeightedHistogram(desc, opts) +} + +func wrapWeightedHelp(given string) string { + return "EXPERIMENTAL: " + given +} + +func newWeightedHistogram(desc *prometheus.Desc, opts WeightedHistogramOpts, variableLabelValues ...string) (*weightedHistogram, error) { + if len(opts.Buckets) == 0 { + opts.Buckets = prometheus.DefBuckets + } + + for i, upperBound := range opts.Buckets { + if i < len(opts.Buckets)-1 { + if upperBound >= opts.Buckets[i+1] { + return nil, fmt.Errorf( + "histogram buckets must be in increasing order: %f >= %f", + upperBound, opts.Buckets[i+1], + ) + } + } else { + if math.IsInf(upperBound, +1) { + // The +Inf bucket is implicit. Remove it here. + opts.Buckets = opts.Buckets[:i] + } + } + } + upperBounds := make([]float64, len(opts.Buckets)) + copy(upperBounds, opts.Buckets) + + return &weightedHistogram{ + desc: desc, + variableLabelValues: variableLabelValues, + upperBounds: upperBounds, + buckets: make([]uint64, len(upperBounds)+1), + hotCount: initialHotCount, + }, nil +} + +type weightedHistogram struct { + desc *prometheus.Desc + variableLabelValues []string + upperBounds []float64 // exclusive of +Inf + + lock sync.Mutex // applies to all the following + + // buckets is longer by one than upperBounds. + // For 0 <= idx < len(upperBounds), buckets[idx] holds the + // accumulated time.Duration that value has been <= + // upperBounds[idx] but not <= upperBounds[idx-1]. + // buckets[len(upperBounds)] holds the accumulated + // time.Duration when value fit in no other bucket. + buckets []uint64 + + // sumHot + sumCold is the weighted sum of value. + // Rather than risk loss of precision in one + // float64, we do this sum hierarchically. Many successive + // increments are added into sumHot; once in a while + // the magnitude of sumHot is compared to the magnitude + // of sumCold and, if the ratio is high enough, + // sumHot is transferred into sumCold. + sumHot float64 + sumCold float64 + + transferThreshold float64 // = math.Abs(sumCold) / 2^26 (that's about half of the bits of precision in a float64) + + // hotCount is used to decide when to consider dumping sumHot into sumCold. + // hotCount counts upward from initialHotCount to zero. + hotCount int +} + +// initialHotCount is the negative of the number of terms +// that are summed into sumHot before considering whether +// to transfer to sumCold. This only has to be big enough +// to make the extra floating point operations occur in a +// distinct minority of cases. +const initialHotCount = -15 + +var _ WeightedHistogram = &weightedHistogram{} +var _ prometheus.Metric = &weightedHistogram{} +var _ prometheus.Collector = &weightedHistogram{} + +func (sh *weightedHistogram) ObserveWithWeight(value float64, weight uint64) { + idx := sort.SearchFloat64s(sh.upperBounds, value) + sh.lock.Lock() + defer sh.lock.Unlock() + sh.updateLocked(idx, value, weight) +} + +func (sh *weightedHistogram) observeWithWeightLocked(value float64, weight uint64) { + idx := sort.SearchFloat64s(sh.upperBounds, value) + sh.updateLocked(idx, value, weight) +} + +func (sh *weightedHistogram) updateLocked(idx int, value float64, weight uint64) { + sh.buckets[idx] += weight + newSumHot := sh.sumHot + float64(weight)*value + sh.hotCount++ + if sh.hotCount >= 0 { + sh.hotCount = initialHotCount + if math.Abs(newSumHot) > sh.transferThreshold { + newSumCold := sh.sumCold + newSumHot + sh.sumCold = newSumCold + sh.transferThreshold = math.Abs(newSumCold / 67108864) + sh.sumHot = 0 + return + } + } + sh.sumHot = newSumHot +} + +func (sh *weightedHistogram) Desc() *prometheus.Desc { + return sh.desc +} + +func (sh *weightedHistogram) Write(dest *dto.Metric) error { + count, sum, buckets := func() (uint64, float64, map[float64]uint64) { + sh.lock.Lock() + defer sh.lock.Unlock() + nBounds := len(sh.upperBounds) + buckets := make(map[float64]uint64, nBounds) + var count uint64 + for idx, upperBound := range sh.upperBounds { + count += sh.buckets[idx] + buckets[upperBound] = count + } + count += sh.buckets[nBounds] + return count, sh.sumHot + sh.sumCold, buckets + }() + metric, err := prometheus.NewConstHistogram(sh.desc, count, sum, buckets, sh.variableLabelValues...) + if err != nil { + return err + } + return metric.Write(dest) +} + +func (sh *weightedHistogram) Describe(ch chan<- *prometheus.Desc) { + ch <- sh.desc +} + +func (sh *weightedHistogram) Collect(ch chan<- prometheus.Metric) { + ch <- sh +} diff --git a/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go b/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go new file mode 100644 index 00000000000..2ca95f0a7ff --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go @@ -0,0 +1,106 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prometheusextension + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +// WeightedObserverVec is a bunch of WeightedObservers that have the same +// Desc and are distinguished by the values for their variable labels. +type WeightedObserverVec interface { + GetMetricWith(prometheus.Labels) (WeightedObserver, error) + GetMetricWithLabelValues(lvs ...string) (WeightedObserver, error) + With(prometheus.Labels) WeightedObserver + WithLabelValues(...string) WeightedObserver + CurryWith(prometheus.Labels) (WeightedObserverVec, error) + MustCurryWith(prometheus.Labels) WeightedObserverVec +} + +// WeightedHistogramVec implements WeightedObserverVec +type WeightedHistogramVec struct { + *prometheus.MetricVec +} + +var _ WeightedObserverVec = &WeightedHistogramVec{} +var _ prometheus.Collector = &WeightedHistogramVec{} + +func NewWeightedHistogramVec(opts WeightedHistogramOpts, labelNames ...string) *WeightedHistogramVec { + desc := prometheus.NewDesc( + prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), + wrapWeightedHelp(opts.Help), + labelNames, + opts.ConstLabels, + ) + return &WeightedHistogramVec{ + MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric { + metric, err := newWeightedHistogram(desc, opts, lvs...) + if err != nil { + panic(err) // like in prometheus.newHistogram + } + return metric + }), + } +} + +func (hv *WeightedHistogramVec) GetMetricWith(labels prometheus.Labels) (WeightedObserver, error) { + metric, err := hv.MetricVec.GetMetricWith(labels) + if metric != nil { + return metric.(WeightedObserver), err + } + return nil, err +} + +func (hv *WeightedHistogramVec) GetMetricWithLabelValues(lvs ...string) (WeightedObserver, error) { + metric, err := hv.MetricVec.GetMetricWithLabelValues(lvs...) + if metric != nil { + return metric.(WeightedObserver), err + } + return nil, err +} + +func (hv *WeightedHistogramVec) With(labels prometheus.Labels) WeightedObserver { + h, err := hv.GetMetricWith(labels) + if err != nil { + panic(err) + } + return h +} + +func (hv *WeightedHistogramVec) WithLabelValues(lvs ...string) WeightedObserver { + h, err := hv.GetMetricWithLabelValues(lvs...) + if err != nil { + panic(err) + } + return h +} + +func (hv *WeightedHistogramVec) CurryWith(labels prometheus.Labels) (WeightedObserverVec, error) { + vec, err := hv.MetricVec.CurryWith(labels) + if vec != nil { + return &WeightedHistogramVec{MetricVec: vec}, err + } + return nil, err +} + +func (hv *WeightedHistogramVec) MustCurryWith(labels prometheus.Labels) WeightedObserverVec { + vec, err := hv.CurryWith(labels) + if err != nil { + panic(err) + } + return vec +} diff --git a/vendor/k8s.io/component-base/metrics/registry.go b/vendor/k8s.io/component-base/metrics/registry.go index 6c97bb504ff..9a7138c11f8 100644 --- a/vendor/k8s.io/component-base/metrics/registry.go +++ b/vendor/k8s.io/component-base/metrics/registry.go @@ -32,10 +32,35 @@ import ( var ( showHiddenOnce sync.Once disabledMetricsLock sync.RWMutex - showHidden atomic.Value + showHidden atomic.Bool registries []*kubeRegistry // stores all registries created by NewKubeRegistry() registriesLock sync.RWMutex disabledMetrics = map[string]struct{}{} + + registeredMetrics = NewCounterVec( + &CounterOpts{ + Name: "registered_metric_total", + Help: "The count of registered metrics broken by stability level and deprecation version.", + StabilityLevel: ALPHA, + }, + []string{"stability_level", "deprecated_version"}, + ) + + disabledMetricsTotal = NewCounter( + &CounterOpts{ + Name: "disabled_metric_total", + Help: "The count of disabled metrics.", + StabilityLevel: ALPHA, + }, + ) + + hiddenMetricsTotal = NewCounter( + &CounterOpts{ + Name: "hidden_metric_total", + Help: "The count of hidden metrics.", + StabilityLevel: ALPHA, + }, + ) ) // shouldHide be used to check if a specific metric with deprecated version should be hidden @@ -67,6 +92,7 @@ func SetDisabledMetric(name string) { disabledMetricsLock.Lock() defer disabledMetricsLock.Unlock() disabledMetrics[name] = struct{}{} + disabledMetricsTotal.Inc() } // SetShowHidden will enable showing hidden metrics. This will no-opt @@ -87,7 +113,7 @@ func SetShowHidden() { // is enabled. While the primary usecase for this is internal (to determine // registration behavior) this can also be used to introspect func ShouldShowHidden() bool { - return showHidden.Load() != nil && showHidden.Load().(bool) + return showHidden.Load() } // Registerable is an interface for a collector metric which we @@ -129,6 +155,12 @@ type KubeRegistry interface { // Reset invokes the Reset() function on all items in the registry // which are added as resettables. Reset() + // RegisterMetaMetrics registers metrics about the number of registered metrics. + RegisterMetaMetrics() + // Registerer exposes the underlying prometheus registerer + Registerer() prometheus.Registerer + // Gatherer exposes the underlying prometheus gatherer + Gatherer() prometheus.Gatherer } // kubeRegistry is a wrapper around a prometheus registry-type object. Upon initialization @@ -160,6 +192,16 @@ func (kr *kubeRegistry) Register(c Registerable) error { return nil } +// Registerer exposes the underlying prometheus.Registerer +func (kr *kubeRegistry) Registerer() prometheus.Registerer { + return kr.PromRegistry +} + +// Gatherer exposes the underlying prometheus.Gatherer +func (kr *kubeRegistry) Gatherer() prometheus.Gatherer { + return kr.PromRegistry +} + // MustRegister works like Register but registers any number of // Collectors and panics upon the first registration that causes an // error. @@ -250,6 +292,7 @@ func (kr *kubeRegistry) trackHiddenCollector(c Registerable) { defer kr.hiddenCollectorsLock.Unlock() kr.hiddenCollectors[c.FQName()] = c + hiddenMetricsTotal.Inc() } // trackStableCollectors stores all custom collectors. @@ -329,9 +372,14 @@ func newKubeRegistry(v apimachineryversion.Info) *kubeRegistry { return r } -// NewKubeRegistry creates a new vanilla Registry without any Collectors -// pre-registered. +// NewKubeRegistry creates a new vanilla Registry func NewKubeRegistry() KubeRegistry { r := newKubeRegistry(BuildVersion()) return r } + +func (r *kubeRegistry) RegisterMetaMetrics() { + r.MustRegister(registeredMetrics) + r.MustRegister(disabledMetricsTotal) + r.MustRegister(hiddenMetricsTotal) +} diff --git a/vendor/k8s.io/component-base/metrics/summary.go b/vendor/k8s.io/component-base/metrics/summary.go index fb1108f9245..d40421645af 100644 --- a/vendor/k8s.io/component-base/metrics/summary.go +++ b/vendor/k8s.io/component-base/metrics/summary.go @@ -18,10 +18,17 @@ package metrics import ( "context" + "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" ) +const ( + DefAgeBuckets = prometheus.DefAgeBuckets + DefBufCap = prometheus.DefBufCap + DefMaxAge = prometheus.DefMaxAge +) + // Summary is our internal representation for our wrapping struct around prometheus // summaries. Summary implements both kubeCollector and ObserverMetric // @@ -42,7 +49,7 @@ func NewSummary(opts *SummaryOpts) *Summary { s := &Summary{ SummaryOpts: opts, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } s.setPrometheusSummary(noopMetric{}) s.lazyInit(s, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)) @@ -93,7 +100,9 @@ type SummaryVec struct { // NewSummaryVec returns an object which satisfies kubeCollector and wraps the // prometheus.SummaryVec object. However, the object returned will not measure -// anything unless the collector is first registered, since the metric is lazily instantiated. +// anything unless the collector is first registered, since the metric is lazily instantiated, +// and only members extracted after +// registration will actually measure anything. // // DEPRECATED: as per the metrics overhaul KEP func NewSummaryVec(opts *SummaryOpts, labels []string) *SummaryVec { @@ -109,7 +118,7 @@ func NewSummaryVec(opts *SummaryOpts, labels []string) *SummaryVec { v := &SummaryVec{ SummaryOpts: opts, originalLabels: labels, - lazyMetric: lazyMetric{}, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, } v.lazyInit(v, fqName) return v @@ -130,13 +139,16 @@ func (v *SummaryVec) initializeDeprecatedMetric() { v.initializeMetric() } -// Default Prometheus behavior actually results in the creation of a new metric -// if a metric with the unique label values is not found in the underlying stored metricMap. +// Default Prometheus Vec behavior is that member extraction results in creation of a new element +// if one with the unique label values is not found in the underlying stored metricMap. // This means that if this function is called but the underlying metric is not registered // (which means it will never be exposed externally nor consumed), the metric will exist in memory // for perpetuity (i.e. throughout application lifecycle). // -// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/summary.go#L485-L495 +// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/histogram.go#L460-L470 +// +// In contrast, the Vec behavior in this package is that member extraction before registration +// returns a permanent noop object. // WithLabelValues returns the ObserverMetric for the given slice of label // values (same order as the VariableLabels in Desc). If that combination of diff --git a/vendor/k8s.io/component-base/metrics/timing_histogram.go b/vendor/k8s.io/component-base/metrics/timing_histogram.go new file mode 100644 index 00000000000..a0f0b253c7d --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/timing_histogram.go @@ -0,0 +1,270 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "time" + + "github.com/blang/semver/v4" + promext "k8s.io/component-base/metrics/prometheusextension" +) + +// PrometheusTimingHistogram is the abstraction of the underlying histogram +// that we want to promote from the wrapper. +type PrometheusTimingHistogram interface { + GaugeMetric +} + +// TimingHistogram is our internal representation for our wrapping struct around +// timing histograms. It implements both kubeCollector and GaugeMetric +type TimingHistogram struct { + PrometheusTimingHistogram + *TimingHistogramOpts + nowFunc func() time.Time + lazyMetric + selfCollector +} + +var _ GaugeMetric = &TimingHistogram{} +var _ Registerable = &TimingHistogram{} +var _ kubeCollector = &TimingHistogram{} + +// NewTimingHistogram returns an object which is TimingHistogram-like. However, nothing +// will be measured until the histogram is registered somewhere. +func NewTimingHistogram(opts *TimingHistogramOpts) *TimingHistogram { + return NewTestableTimingHistogram(time.Now, opts) +} + +// NewTestableTimingHistogram adds injection of the clock +func NewTestableTimingHistogram(nowFunc func() time.Time, opts *TimingHistogramOpts) *TimingHistogram { + opts.StabilityLevel.setDefaults() + + h := &TimingHistogram{ + TimingHistogramOpts: opts, + nowFunc: nowFunc, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, + } + h.setPrometheusHistogram(noopMetric{}) + h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)) + return h +} + +// setPrometheusHistogram sets the underlying KubeGauge object, i.e. the thing that does the measurement. +func (h *TimingHistogram) setPrometheusHistogram(histogram promext.TimingHistogram) { + h.PrometheusTimingHistogram = histogram + h.initSelfCollection(histogram) +} + +// DeprecatedVersion returns a pointer to the Version or nil +func (h *TimingHistogram) DeprecatedVersion() *semver.Version { + return parseSemver(h.TimingHistogramOpts.DeprecatedVersion) +} + +// initializeMetric invokes the actual prometheus.Histogram object instantiation +// and stores a reference to it +func (h *TimingHistogram) initializeMetric() { + h.TimingHistogramOpts.annotateStabilityLevel() + // this actually creates the underlying prometheus gauge. + histogram, err := promext.NewTestableTimingHistogram(h.nowFunc, h.TimingHistogramOpts.toPromHistogramOpts()) + if err != nil { + panic(err) // handle as for regular histograms + } + h.setPrometheusHistogram(histogram) +} + +// initializeDeprecatedMetric invokes the actual prometheus.Histogram object instantiation +// but modifies the Help description prior to object instantiation. +func (h *TimingHistogram) initializeDeprecatedMetric() { + h.TimingHistogramOpts.markDeprecated() + h.initializeMetric() +} + +// WithContext allows the normal TimingHistogram metric to pass in context. The context is no-op now. +func (h *TimingHistogram) WithContext(ctx context.Context) GaugeMetric { + return h.PrometheusTimingHistogram +} + +// TimingHistogramVec is the internal representation of our wrapping struct around prometheus +// TimingHistogramVecs. +type TimingHistogramVec struct { + *promext.TimingHistogramVec + *TimingHistogramOpts + nowFunc func() time.Time + lazyMetric + originalLabels []string +} + +var _ GaugeVecMetric = &TimingHistogramVec{} +var _ Registerable = &TimingHistogramVec{} +var _ kubeCollector = &TimingHistogramVec{} + +// NewTimingHistogramVec returns an object which satisfies the kubeCollector, Registerable, and GaugeVecMetric interfaces +// and wraps an underlying promext.TimingHistogramVec object. Note well the way that +// behavior depends on registration and whether this is hidden. +func NewTimingHistogramVec(opts *TimingHistogramOpts, labels []string) *TimingHistogramVec { + return NewTestableTimingHistogramVec(time.Now, opts, labels) +} + +// NewTestableTimingHistogramVec adds injection of the clock. +func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts *TimingHistogramOpts, labels []string) *TimingHistogramVec { + opts.StabilityLevel.setDefaults() + + fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name) + allowListLock.RLock() + if allowList, ok := labelValueAllowLists[fqName]; ok { + opts.LabelValueAllowLists = allowList + } + allowListLock.RUnlock() + + v := &TimingHistogramVec{ + TimingHistogramVec: noopTimingHistogramVec, + TimingHistogramOpts: opts, + nowFunc: nowFunc, + originalLabels: labels, + lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel}, + } + v.lazyInit(v, fqName) + return v +} + +// DeprecatedVersion returns a pointer to the Version or nil +func (v *TimingHistogramVec) DeprecatedVersion() *semver.Version { + return parseSemver(v.TimingHistogramOpts.DeprecatedVersion) +} + +func (v *TimingHistogramVec) initializeMetric() { + v.TimingHistogramOpts.annotateStabilityLevel() + v.TimingHistogramVec = promext.NewTestableTimingHistogramVec(v.nowFunc, v.TimingHistogramOpts.toPromHistogramOpts(), v.originalLabels...) +} + +func (v *TimingHistogramVec) initializeDeprecatedMetric() { + v.TimingHistogramOpts.markDeprecated() + v.initializeMetric() +} + +// WithLabelValuesChecked, if called before this vector has been registered in +// at least one registry, will return a noop gauge and +// an error that passes ErrIsNotRegistered. +// If called on a hidden vector, +// will return a noop gauge and a nil error. +// If called with a syntactic problem in the labels, will +// return a noop gauge and an error about the labels. +// If none of the above apply, this method will return +// the appropriate vector member and a nil error. +func (v *TimingHistogramVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) { + if !v.IsCreated() { + if v.IsHidden() { + return noop, nil + } + return noop, errNotRegistered + } + if v.LabelValueAllowLists != nil { + v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs) + } + ops, err := v.TimingHistogramVec.GetMetricWithLabelValues(lvs...) + if err != nil { + return noop, err + } + return ops.(GaugeMetric), err +} + +// WithLabelValues calls WithLabelValuesChecked +// and handles errors as follows. +// An error that passes ErrIsNotRegistered is ignored +// and the noop gauge is returned; +// all other errors cause a panic. +func (v *TimingHistogramVec) WithLabelValues(lvs ...string) GaugeMetric { + ans, err := v.WithLabelValuesChecked(lvs...) + if err == nil || ErrIsNotRegistered(err) { + return ans + } + panic(err) +} + +// WithChecked, if called before this vector has been registered in +// at least one registry, will return a noop gauge and +// an error that passes ErrIsNotRegistered. +// If called on a hidden vector, +// will return a noop gauge and a nil error. +// If called with a syntactic problem in the labels, will +// return a noop gauge and an error about the labels. +// If none of the above apply, this method will return +// the appropriate vector member and a nil error. +func (v *TimingHistogramVec) WithChecked(labels map[string]string) (GaugeMetric, error) { + if !v.IsCreated() { + if v.IsHidden() { + return noop, nil + } + return noop, errNotRegistered + } + if v.LabelValueAllowLists != nil { + v.LabelValueAllowLists.ConstrainLabelMap(labels) + } + ops, err := v.TimingHistogramVec.GetMetricWith(labels) + return ops.(GaugeMetric), err +} + +// With calls WithChecked and handles errors as follows. +// An error that passes ErrIsNotRegistered is ignored +// and the noop gauge is returned; +// all other errors cause a panic. +func (v *TimingHistogramVec) With(labels map[string]string) GaugeMetric { + ans, err := v.WithChecked(labels) + if err == nil || ErrIsNotRegistered(err) { + return ans + } + panic(err) +} + +// Delete deletes the metric where the variable labels are the same as those +// passed in as labels. It returns true if a metric was deleted. +// +// It is not an error if the number and names of the Labels are inconsistent +// with those of the VariableLabels in Desc. However, such inconsistent Labels +// can never match an actual metric, so the method will always return false in +// that case. +func (v *TimingHistogramVec) Delete(labels map[string]string) bool { + if !v.IsCreated() { + return false // since we haven't created the metric, we haven't deleted a metric with the passed in values + } + return v.TimingHistogramVec.Delete(labels) +} + +// Reset deletes all metrics in this vector. +func (v *TimingHistogramVec) Reset() { + if !v.IsCreated() { + return + } + + v.TimingHistogramVec.Reset() +} + +// WithContext returns wrapped TimingHistogramVec with context +func (v *TimingHistogramVec) InterfaceWithContext(ctx context.Context) GaugeVecMetric { + return &TimingHistogramVecWithContext{ + ctx: ctx, + TimingHistogramVec: v, + } +} + +// TimingHistogramVecWithContext is the wrapper of TimingHistogramVec with context. +// Currently the context is ignored. +type TimingHistogramVecWithContext struct { + *TimingHistogramVec + ctx context.Context +} diff --git a/vendor/k8s.io/component-base/metrics/value.go b/vendor/k8s.io/component-base/metrics/value.go index 4a19aaa3bf9..4a405048cf8 100644 --- a/vendor/k8s.io/component-base/metrics/value.go +++ b/vendor/k8s.io/component-base/metrics/value.go @@ -47,10 +47,20 @@ func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelVal return prometheus.MustNewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...) } +// NewConstMetric is a helper of NewConstMetric. +// +// Note: If the metrics described by the desc is hidden, the metrics will not be created. +func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) { + if desc.IsHidden() { + return nil, nil + } + return prometheus.NewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...) +} + // NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp. // // Warning: the Metric 'm' must be the one created by NewLazyConstMetric(), -// otherwise, no stability guarantees would be offered. +// otherwise, no stability guarantees would be offered. func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric { if m == nil { return nil diff --git a/vendor/k8s.io/component-base/metrics/wrappers.go b/vendor/k8s.io/component-base/metrics/wrappers.go index 6ae8a458acb..679590aad92 100644 --- a/vendor/k8s.io/component-base/metrics/wrappers.go +++ b/vendor/k8s.io/component-base/metrics/wrappers.go @@ -17,6 +17,8 @@ limitations under the License. package metrics import ( + "errors" + "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" ) @@ -65,6 +67,64 @@ type GaugeMetric interface { SetToCurrentTime() } +// GaugeVecMetric is a collection of Gauges that differ only in label values. +type GaugeVecMetric interface { + // Default Prometheus Vec behavior is that member extraction results in creation of a new element + // if one with the unique label values is not found in the underlying stored metricMap. + // This means that if this function is called but the underlying metric is not registered + // (which means it will never be exposed externally nor consumed), the metric would exist in memory + // for perpetuity (i.e. throughout application lifecycle). + // + // For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/gauge.go#L190-L208 + // + // In contrast, the Vec behavior in this package is that member extraction before registration + // returns a permanent noop object. + + // WithLabelValuesChecked, if called before this vector has been registered in + // at least one registry, will return a noop gauge and + // an error that passes ErrIsNotRegistered. + // If called on a hidden vector, + // will return a noop gauge and a nil error. + // If called with a syntactic problem in the labels, will + // return a noop gauge and an error about the labels. + // If none of the above apply, this method will return + // the appropriate vector member and a nil error. + WithLabelValuesChecked(labelValues ...string) (GaugeMetric, error) + + // WithLabelValues calls WithLabelValuesChecked + // and handles errors as follows. + // An error that passes ErrIsNotRegistered is ignored + // and the noop gauge is returned; + // all other errors cause a panic. + WithLabelValues(labelValues ...string) GaugeMetric + + // WithChecked, if called before this vector has been registered in + // at least one registry, will return a noop gauge and + // an error that passes ErrIsNotRegistered. + // If called on a hidden vector, + // will return a noop gauge and a nil error. + // If called with a syntactic problem in the labels, will + // return a noop gauge and an error about the labels. + // If none of the above apply, this method will return + // the appropriate vector member and a nil error. + WithChecked(labels map[string]string) (GaugeMetric, error) + + // With calls WithChecked and handles errors as follows. + // An error that passes ErrIsNotRegistered is ignored + // and the noop gauge is returned; + // all other errors cause a panic. + With(labels map[string]string) GaugeMetric + + // Delete asserts that the vec should have no member for the given label set. + // The returned bool indicates whether there was a change. + // The return will certainly be `false` if the given label set has the wrong + // set of label names. + Delete(map[string]string) bool + + // Reset removes all the members + Reset() +} + // ObserverMetric captures individual observations. type ObserverMetric interface { Observe(float64) @@ -85,6 +145,12 @@ type Gatherer interface { prometheus.Gatherer } +// Registerer is the interface for the part of a registry in charge of registering +// the collected metrics. +type Registerer interface { + prometheus.Registerer +} + // GaugeFunc is a Gauge whose value is determined at collect time by calling a // provided function. // @@ -93,3 +159,9 @@ type GaugeFunc interface { Metric Collector } + +func ErrIsNotRegistered(err error) bool { + return err == errNotRegistered +} + +var errNotRegistered = errors.New("metric vec is not registered yet") diff --git a/vendor/k8s.io/component-base/traces/utils.go b/vendor/k8s.io/component-base/traces/utils.go deleted file mode 100644 index 5b271fd1afb..00000000000 --- a/vendor/k8s.io/component-base/traces/utils.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package traces - -import ( - "context" - "net/http" - - "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - "go.opentelemetry.io/otel/exporters/otlp" - "go.opentelemetry.io/otel/exporters/otlp/otlpgrpc" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" - - "k8s.io/client-go/transport" - "k8s.io/klog/v2" -) - -// NewProvider initializes tracing in the component, and enforces recommended tracing behavior. -func NewProvider(ctx context.Context, baseSampler sdktrace.Sampler, resourceOpts []resource.Option, opts ...otlpgrpc.Option) trace.TracerProvider { - opts = append(opts, otlpgrpc.WithInsecure()) - driver := otlpgrpc.NewDriver(opts...) - exporter, err := otlp.NewExporter(ctx, driver) - if err != nil { - klog.Fatalf("Failed to create OTLP exporter: %v", err) - } - - res, err := resource.New(ctx, resourceOpts...) - if err != nil { - klog.Fatalf("Failed to create resource: %v", err) - } - - bsp := sdktrace.NewBatchSpanProcessor(exporter) - - return sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.ParentBased(baseSampler)), - sdktrace.WithSpanProcessor(bsp), - sdktrace.WithResource(res), - ) -} - -// WrapperFor can be used to add tracing to a *rest.Config. Example usage: -// tp := traces.NewProvider(...) -// config, _ := rest.InClusterConfig() -// config.Wrap(traces.WrapperFor(&tp)) -// kubeclient, _ := clientset.NewForConfig(config) -func WrapperFor(tp *trace.TracerProvider) transport.WrapperFunc { - return func(rt http.RoundTripper) http.RoundTripper { - opts := []otelhttp.Option{ - otelhttp.WithPropagators(Propagators()), - } - if tp != nil { - opts = append(opts, otelhttp.WithTracerProvider(*tp)) - } - // Even if there is no TracerProvider, the otelhttp still handles context propagation. - // See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough - return otelhttp.NewTransport(rt, opts...) - } -} - -// Propagators returns the recommended set of propagators. -func Propagators() propagation.TextMapPropagator { - return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) -} diff --git a/vendor/k8s.io/component-base/traces/OWNERS b/vendor/k8s.io/component-base/tracing/OWNERS similarity index 100% rename from vendor/k8s.io/component-base/traces/OWNERS rename to vendor/k8s.io/component-base/tracing/OWNERS diff --git a/vendor/k8s.io/component-base/tracing/api/v1/config.go b/vendor/k8s.io/component-base/tracing/api/v1/config.go new file mode 100644 index 00000000000..ae9bbbfc092 --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/api/v1/config.go @@ -0,0 +1,88 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + "net/url" + "strings" + + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/component-base/featuregate" +) + +var ( + maxSamplingRatePerMillion = int32(1000000) +) + +// ValidateTracingConfiguration validates the tracing configuration +func ValidateTracingConfiguration(traceConfig *TracingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if traceConfig == nil { + return allErrs + } + if traceConfig.SamplingRatePerMillion != nil { + allErrs = append(allErrs, validateSamplingRate(*traceConfig.SamplingRatePerMillion, fldPath.Child("samplingRatePerMillion"))...) + } + if traceConfig.Endpoint != nil { + allErrs = append(allErrs, validateEndpoint(*traceConfig.Endpoint, fldPath.Child("endpoint"))...) + } + return allErrs +} + +func validateSamplingRate(rate int32, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + if rate < 0 { + errs = append(errs, field.Invalid( + fldPath, rate, + "sampling rate must be positive", + )) + } + if rate > maxSamplingRatePerMillion { + errs = append(errs, field.Invalid( + fldPath, rate, + "sampling rate per million must be less than or equal to one million", + )) + } + return errs +} + +func validateEndpoint(endpoint string, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + if !strings.Contains(endpoint, "//") { + endpoint = "dns://" + endpoint + } + url, err := url.Parse(endpoint) + if err != nil { + errs = append(errs, field.Invalid( + fldPath, endpoint, + err.Error(), + )) + return errs + } + switch url.Scheme { + case "dns": + case "unix": + case "unix-abstract": + default: + errs = append(errs, field.Invalid( + fldPath, endpoint, + fmt.Sprintf("unsupported scheme: %v. Options are none, dns, unix, or unix-abstract. See https://github.com/grpc/grpc/blob/master/doc/naming.md", url.Scheme), + )) + } + return errs +} diff --git a/vendor/k8s.io/component-base/tracing/api/v1/doc.go b/vendor/k8s.io/component-base/tracing/api/v1/doc.go new file mode 100644 index 00000000000..ffe36aef6f0 --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/api/v1/doc.go @@ -0,0 +1,29 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package + +// Package v1 contains the configuration API for tracing. +// +// The intention is to only have a single version of this API, potentially with +// new fields added over time in a backwards-compatible manner. Fields for +// alpha or beta features are allowed as long as they are defined so that not +// changing the defaults leaves those features disabled. +// +// The "v1" package name is just a reminder that API compatibility rules apply, +// not an indication of the stability of all features covered by it. + +package v1 // import "k8s.io/component-base/tracing/api/v1" diff --git a/vendor/k8s.io/component-base/tracing/api/v1/types.go b/vendor/k8s.io/component-base/tracing/api/v1/types.go new file mode 100644 index 00000000000..a59d564050f --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/api/v1/types.go @@ -0,0 +1,32 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +// TracingConfiguration provides versioned configuration for OpenTelemetry tracing clients. +type TracingConfiguration struct { + // Endpoint of the collector this component will report traces to. + // The connection is insecure, and does not currently support TLS. + // Recommended is unset, and endpoint is the otlp grpc default, localhost:4317. + // +optional + Endpoint *string `json:"endpoint,omitempty"` + + // SamplingRatePerMillion is the number of samples to collect per million spans. + // Recommended is unset. If unset, sampler respects its parent span's sampling + // rate, but otherwise never samples. + // +optional + SamplingRatePerMillion *int32 `json:"samplingRatePerMillion,omitempty"` +} diff --git a/vendor/k8s.io/component-base/tracing/api/v1/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/tracing/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..2afc68117b0 --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,48 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(string) + **out = **in + } + if in.SamplingRatePerMillion != nil { + in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingConfiguration. +func (in *TracingConfiguration) DeepCopy() *TracingConfiguration { + if in == nil { + return nil + } + out := new(TracingConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/component-base/tracing/tracing.go b/vendor/k8s.io/component-base/tracing/tracing.go new file mode 100644 index 00000000000..50894eb3b9b --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/tracing.go @@ -0,0 +1,92 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tracing + +import ( + "context" + "time" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + + utiltrace "k8s.io/utils/trace" +) + +const instrumentationScope = "k8s.io/component-base/tracing" + +// Start creates spans using both OpenTelemetry, and the k8s.io/utils/trace package. +// It only creates an OpenTelemetry span if the incoming context already includes a span. +func Start(ctx context.Context, name string, attributes ...attribute.KeyValue) (context.Context, *Span) { + // If the incoming context already includes an OpenTelemetry span, create a child span with the provided name and attributes. + // If the caller is not using OpenTelemetry, or has tracing disabled (e.g. with a component-specific feature flag), this is a noop. + ctx, otelSpan := trace.SpanFromContext(ctx).TracerProvider().Tracer(instrumentationScope).Start(ctx, name, trace.WithAttributes(attributes...)) + // If there is already a utiltrace span in the context, use that as our parent span. + utilSpan := utiltrace.FromContext(ctx).Nest(name, attributesToFields(attributes)...) + // Set the trace as active in the context so that subsequent Start calls create nested spans. + return utiltrace.ContextWithTrace(ctx, utilSpan), &Span{ + otelSpan: otelSpan, + utilSpan: utilSpan, + } +} + +// Span is a component part of a trace. It represents a single named +// and timed operation of a workflow being observed. +// This Span is a combination of an OpenTelemetry and k8s.io/utils/trace span +// to facilitate the migration to OpenTelemetry. +type Span struct { + otelSpan trace.Span + utilSpan *utiltrace.Trace +} + +// AddEvent adds a point-in-time event with a name and attributes. +func (s *Span) AddEvent(name string, attributes ...attribute.KeyValue) { + s.otelSpan.AddEvent(name, trace.WithAttributes(attributes...)) + if s.utilSpan != nil { + s.utilSpan.Step(name, attributesToFields(attributes)...) + } +} + +// End ends the span, and logs if the span duration is greater than the logThreshold. +func (s *Span) End(logThreshold time.Duration) { + s.otelSpan.End() + if s.utilSpan != nil { + s.utilSpan.LogIfLong(logThreshold) + } +} + +func attributesToFields(attributes []attribute.KeyValue) []utiltrace.Field { + fields := make([]utiltrace.Field, len(attributes)) + for i := range attributes { + attr := attributes[i] + fields[i] = utiltrace.Field{Key: string(attr.Key), Value: attr.Value.AsInterface()} + } + return fields +} + +// SpanFromContext returns the *Span from the current context. It is composed of the active +// OpenTelemetry and k8s.io/utils/trace spans. +func SpanFromContext(ctx context.Context) *Span { + return &Span{ + otelSpan: trace.SpanFromContext(ctx), + utilSpan: utiltrace.FromContext(ctx), + } +} + +// ContextWithSpan returns a context with the Span included in the context. +func ContextWithSpan(ctx context.Context, s *Span) context.Context { + return trace.ContextWithSpan(utiltrace.ContextWithTrace(ctx, s.utilSpan), s.otelSpan) +} diff --git a/vendor/k8s.io/component-base/tracing/utils.go b/vendor/k8s.io/component-base/tracing/utils.go new file mode 100644 index 00000000000..ae894a8091c --- /dev/null +++ b/vendor/k8s.io/component-base/tracing/utils.go @@ -0,0 +1,124 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tracing + +import ( + "context" + "net/http" + + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + oteltrace "go.opentelemetry.io/otel/trace" + + "k8s.io/client-go/transport" + "k8s.io/component-base/tracing/api/v1" +) + +// TracerProvider is an OpenTelemetry TracerProvider which can be shut down +type TracerProvider interface { + oteltrace.TracerProvider + Shutdown(context.Context) error +} + +type noopTracerProvider struct { + oteltrace.TracerProvider +} + +func (n *noopTracerProvider) Shutdown(context.Context) error { + return nil +} + +func NewNoopTracerProvider() TracerProvider { + return &noopTracerProvider{TracerProvider: oteltrace.NewNoopTracerProvider()} +} + +// NewProvider creates a TracerProvider in a component, and enforces recommended tracing behavior +func NewProvider(ctx context.Context, + tracingConfig *v1.TracingConfiguration, + addedOpts []otlptracegrpc.Option, + resourceOpts []resource.Option, +) (TracerProvider, error) { + if tracingConfig == nil { + return NewNoopTracerProvider(), nil + } + opts := append([]otlptracegrpc.Option{}, addedOpts...) + if tracingConfig.Endpoint != nil { + opts = append(opts, otlptracegrpc.WithEndpoint(*tracingConfig.Endpoint)) + } + opts = append(opts, otlptracegrpc.WithInsecure()) + exporter, err := otlptracegrpc.New(ctx, opts...) + if err != nil { + return nil, err + } + res, err := resource.New(ctx, resourceOpts...) + if err != nil { + return nil, err + } + + // sampler respects parent span's sampling rate or + // otherwise never samples. + sampler := sdktrace.NeverSample() + // Or, emit spans for a fraction of transactions + if tracingConfig.SamplingRatePerMillion != nil && *tracingConfig.SamplingRatePerMillion > 0 { + sampler = sdktrace.TraceIDRatioBased(float64(*tracingConfig.SamplingRatePerMillion) / float64(1000000)) + } + // batch span processor to aggregate spans before export. + bsp := sdktrace.NewBatchSpanProcessor(exporter) + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.ParentBased(sampler)), + sdktrace.WithSpanProcessor(bsp), + sdktrace.WithResource(res), + ) + return tp, nil +} + +// WithTracing adds tracing to requests if the incoming request is sampled +func WithTracing(handler http.Handler, tp oteltrace.TracerProvider, serviceName string) http.Handler { + opts := []otelhttp.Option{ + otelhttp.WithPropagators(Propagators()), + otelhttp.WithTracerProvider(tp), + } + // With Noop TracerProvider, the otelhttp still handles context propagation. + // See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough + return otelhttp.NewHandler(handler, serviceName, opts...) +} + +// WrapperFor can be used to add tracing to a *rest.Config. +// Example usage: +// tp := NewProvider(...) +// config, _ := rest.InClusterConfig() +// config.Wrap(WrapperFor(tp)) +// kubeclient, _ := clientset.NewForConfig(config) +func WrapperFor(tp oteltrace.TracerProvider) transport.WrapperFunc { + return func(rt http.RoundTripper) http.RoundTripper { + opts := []otelhttp.Option{ + otelhttp.WithPropagators(Propagators()), + otelhttp.WithTracerProvider(tp), + } + // With Noop TracerProvider, the otelhttp still handles context propagation. + // See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough + return otelhttp.NewTransport(rt, opts...) + } +} + +// Propagators returns the recommended set of propagators. +func Propagators() propagation.TextMapPropagator { + return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) +} diff --git a/vendor/k8s.io/klog/v2/OWNERS b/vendor/k8s.io/klog/v2/OWNERS index 8cccebf2e9c..a2fe8f351bf 100644 --- a/vendor/k8s.io/klog/v2/OWNERS +++ b/vendor/k8s.io/klog/v2/OWNERS @@ -1,5 +1,6 @@ # See the OWNERS docs at https://go.k8s.io/owners reviewers: + - harshanarayana - pohly approvers: - dims diff --git a/vendor/k8s.io/klog/v2/contextual.go b/vendor/k8s.io/klog/v2/contextual.go index 65ac479ab6a..005513f2a76 100644 --- a/vendor/k8s.io/klog/v2/contextual.go +++ b/vendor/k8s.io/klog/v2/contextual.go @@ -47,8 +47,9 @@ var ( // If set, all log lines will be suppressed from the regular output, and // redirected to the logr implementation. // Use as: -// ... -// klog.SetLogger(zapr.NewLogger(zapLog)) +// +// ... +// klog.SetLogger(zapr.NewLogger(zapLog)) // // To remove a backing logr implemention, use ClearLogger. Setting an // empty logger with SetLogger(logr.Logger{}) does not work. @@ -69,11 +70,14 @@ func SetLogger(logger logr.Logger) { // routing log entries through klogr into klog and then into the actual Logger // backend. func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) { - logging.logger = &logger logging.loggerOptions = loggerOptions{} for _, opt := range opts { opt(&logging.loggerOptions) } + logging.logger = &logWriter{ + Logger: logger, + writeKlogBuffer: logging.loggerOptions.writeKlogBuffer, + } } // ContextualLogger determines whether the logger passed to @@ -92,6 +96,22 @@ func FlushLogger(flush func()) LoggerOption { } } +// WriteKlogBuffer sets a callback that will be invoked by klog to write output +// produced by non-structured log calls like Infof. +// +// The buffer will contain exactly the same data that klog normally would write +// into its own output stream(s). In particular this includes the header, if +// klog is configured to write one. The callback then can divert that data into +// its own output streams. The buffer may or may not end in a line break. +// +// Without such a callback, klog will call the logger's Info or Error method +// with just the message string (i.e. no header). +func WriteKlogBuffer(write func([]byte)) LoggerOption { + return func(o *loggerOptions) { + o.writeKlogBuffer = write + } +} + // LoggerOption implements the functional parameter paradigm for // SetLoggerWithOptions. type LoggerOption func(o *loggerOptions) @@ -99,6 +119,13 @@ type LoggerOption func(o *loggerOptions) type loggerOptions struct { contextualLogger bool flush func() + writeKlogBuffer func([]byte) +} + +// logWriter combines a logger (always set) with a write callback (optional). +type logWriter struct { + Logger + writeKlogBuffer func([]byte) } // ClearLogger removes a backing Logger implementation if one was set earlier @@ -151,7 +178,7 @@ func Background() Logger { if logging.loggerOptions.contextualLogger { // Is non-nil because logging.loggerOptions.contextualLogger is // only true if a logger was set. - return *logging.logger + return logging.logger.Logger } return klogLogger diff --git a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go index ac88682a2c4..f325ded5e9e 100644 --- a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go +++ b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go @@ -40,44 +40,33 @@ type Buffer struct { next *Buffer } -// Buffers manages the reuse of individual buffer instances. It is thread-safe. -type Buffers struct { - // mu protects the free list. It is separate from the main mutex - // so buffers can be grabbed and printed to without holding the main lock, - // for better parallelization. - mu sync.Mutex - - // freeList is a list of byte buffers, maintained under mu. - freeList *Buffer +var buffers = sync.Pool{ + New: func() interface{} { + return new(Buffer) + }, } // GetBuffer returns a new, ready-to-use buffer. -func (bl *Buffers) GetBuffer() *Buffer { - bl.mu.Lock() - b := bl.freeList - if b != nil { - bl.freeList = b.next - } - bl.mu.Unlock() - if b == nil { - b = new(Buffer) - } else { - b.next = nil - b.Reset() - } +func GetBuffer() *Buffer { + b := buffers.Get().(*Buffer) + b.Reset() return b } // PutBuffer returns a buffer to the free list. -func (bl *Buffers) PutBuffer(b *Buffer) { +func PutBuffer(b *Buffer) { if b.Len() >= 256 { - // Let big buffers die a natural death. + // Let big buffers die a natural death, without relying on + // sync.Pool behavior. The documentation implies that items may + // get deallocated while stored there ("If the Pool holds the + // only reference when this [= be removed automatically] + // happens, the item might be deallocated."), but + // https://github.com/golang/go/issues/23199 leans more towards + // having such a size limit. return } - bl.mu.Lock() - b.next = bl.freeList - bl.freeList = b - bl.mu.Unlock() + + buffers.Put(b) } // Some custom tiny helper functions to print the log header efficiently. @@ -121,7 +110,8 @@ func (buf *Buffer) someDigits(i, d int) int { return copy(buf.Tmp[i:], buf.Tmp[j:]) } -// FormatHeader formats a log header using the provided file name and line number. +// FormatHeader formats a log header using the provided file name and line number +// and writes it into the buffer. func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now time.Time) { if line < 0 { line = 0 // not a real line number, but acceptable to someDigits @@ -157,3 +147,30 @@ func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now buf.Tmp[n+2] = ' ' buf.Write(buf.Tmp[:n+3]) } + +// SprintHeader formats a log header and returns a string. This is a simpler +// version of FormatHeader for use in ktesting. +func (buf *Buffer) SprintHeader(s severity.Severity, now time.Time) string { + if s > severity.FatalLog { + s = severity.InfoLog // for safety. + } + + // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. + // It's worth about 3X. Fprintf is hard. + _, month, day := now.Date() + hour, minute, second := now.Clock() + // Lmmdd hh:mm:ss.uuuuuu threadid file:line] + buf.Tmp[0] = severity.Char[s] + buf.twoDigits(1, int(month)) + buf.twoDigits(3, day) + buf.Tmp[5] = ' ' + buf.twoDigits(6, hour) + buf.Tmp[8] = ':' + buf.twoDigits(9, minute) + buf.Tmp[11] = ':' + buf.twoDigits(12, second) + buf.Tmp[14] = '.' + buf.nDigits(6, 15, now.Nanosecond()/1000, '0') + buf.Tmp[21] = ']' + return string(buf.Tmp[:22]) +} diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go index f85d7ccf83b..1dc81a15fa6 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -24,6 +24,10 @@ import ( "github.com/go-logr/logr" ) +type textWriter interface { + WriteText(*bytes.Buffer) +} + // WithValues implements LogSink.WithValues. The old key/value pairs are // assumed to be well-formed, the new ones are checked and padded if // necessary. It returns a new slice. @@ -91,11 +95,66 @@ func MergeKVs(first, second []interface{}) []interface{} { return merged } +type Formatter struct { + AnyToStringHook AnyToStringFunc +} + +type AnyToStringFunc func(v interface{}) string + +// MergeKVsInto is a variant of MergeKVs which directly formats the key/value +// pairs into a buffer. +func (f Formatter) MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { + if len(first) == 0 && len(second) == 0 { + // Nothing to do at all. + return + } + + if len(first) == 0 && len(second)%2 == 0 { + // Nothing to be overridden, second slice is well-formed + // and can be used directly. + for i := 0; i < len(second); i += 2 { + f.KVFormat(b, second[i], second[i+1]) + } + return + } + + // Determine which keys are in the second slice so that we can skip + // them when iterating over the first one. The code intentionally + // favors performance over completeness: we assume that keys are string + // constants and thus compare equal when the string values are equal. A + // string constant being overridden by, for example, a fmt.Stringer is + // not handled. + overrides := map[interface{}]bool{} + for i := 0; i < len(second); i += 2 { + overrides[second[i]] = true + } + for i := 0; i < len(first); i += 2 { + key := first[i] + if overrides[key] { + continue + } + f.KVFormat(b, key, first[i+1]) + } + // Round down. + l := len(second) + l = l / 2 * 2 + for i := 1; i < l; i += 2 { + f.KVFormat(b, second[i-1], second[i]) + } + if len(second)%2 == 1 { + f.KVFormat(b, second[len(second)-1], missingValue) + } +} + +func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { + Formatter{}.MergeAndFormatKVs(b, first, second) +} + const missingValue = "(MISSING)" // KVListFormat serializes all key/value pairs into the provided buffer. // A space gets inserted before the first pair and between each pair. -func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { +func (f Formatter) KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { for i := 0; i < len(keysAndValues); i += 2 { var v interface{} k := keysAndValues[i] @@ -104,69 +163,93 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { } else { v = missingValue } - b.WriteByte(' ') - // Keys are assumed to be well-formed according to - // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments - // for the sake of performance. Keys with spaces, - // special characters, etc. will break parsing. - if sK, ok := k.(string); ok { - // Avoid one allocation when the key is a string, which - // normally it should be. - b.WriteString(sK) - } else { - b.WriteString(fmt.Sprintf("%s", k)) - } + f.KVFormat(b, k, v) + } +} + +func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { + Formatter{}.KVListFormat(b, keysAndValues...) +} - // The type checks are sorted so that more frequently used ones - // come first because that is then faster in the common - // cases. In Kubernetes, ObjectRef (a Stringer) is more common - // than plain strings - // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). - switch v := v.(type) { - case fmt.Stringer: - writeStringValue(b, true, StringerToString(v)) +// KVFormat serializes one key/value pair into the provided buffer. +// A space gets inserted before the pair. +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { + b.WriteByte(' ') + // Keys are assumed to be well-formed according to + // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments + // for the sake of performance. Keys with spaces, + // special characters, etc. will break parsing. + if sK, ok := k.(string); ok { + // Avoid one allocation when the key is a string, which + // normally it should be. + b.WriteString(sK) + } else { + b.WriteString(fmt.Sprintf("%s", k)) + } + + // The type checks are sorted so that more frequently used ones + // come first because that is then faster in the common + // cases. In Kubernetes, ObjectRef (a Stringer) is more common + // than plain strings + // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). + switch v := v.(type) { + case textWriter: + writeTextWriterValue(b, v) + case fmt.Stringer: + writeStringValue(b, true, StringerToString(v)) + case string: + writeStringValue(b, true, v) + case error: + writeStringValue(b, true, ErrorToString(v)) + case logr.Marshaler: + value := MarshalerToValue(v) + // A marshaler that returns a string is useful for + // delayed formatting of complex values. We treat this + // case like a normal string. This is useful for + // multi-line support. + // + // We could do this by recursively formatting a value, + // but that comes with the risk of infinite recursion + // if a marshaler returns itself. Instead we call it + // only once and rely on it returning the intended + // value directly. + switch value := value.(type) { case string: - writeStringValue(b, true, v) - case error: - writeStringValue(b, true, ErrorToString(v)) - case logr.Marshaler: - value := MarshalerToValue(v) - // A marshaler that returns a string is useful for - // delayed formatting of complex values. We treat this - // case like a normal string. This is useful for - // multi-line support. - // - // We could do this by recursively formatting a value, - // but that comes with the risk of infinite recursion - // if a marshaler returns itself. Instead we call it - // only once and rely on it returning the intended - // value directly. - switch value := value.(type) { - case string: - writeStringValue(b, true, value) - default: - writeStringValue(b, false, fmt.Sprintf("%+v", v)) - } - case []byte: - // In https://github.com/kubernetes/klog/pull/237 it was decided - // to format byte slices with "%+q". The advantages of that are: - // - readable output if the bytes happen to be printable - // - non-printable bytes get represented as unicode escape - // sequences (\uxxxx) - // - // The downsides are that we cannot use the faster - // strconv.Quote here and that multi-line output is not - // supported. If developers know that a byte array is - // printable and they want multi-line output, they can - // convert the value to string before logging it. - b.WriteByte('=') - b.WriteString(fmt.Sprintf("%+q", v)) + writeStringValue(b, true, value) default: - writeStringValue(b, false, fmt.Sprintf("%+v", v)) + writeStringValue(b, false, f.AnyToString(value)) } + case []byte: + // In https://github.com/kubernetes/klog/pull/237 it was decided + // to format byte slices with "%+q". The advantages of that are: + // - readable output if the bytes happen to be printable + // - non-printable bytes get represented as unicode escape + // sequences (\uxxxx) + // + // The downsides are that we cannot use the faster + // strconv.Quote here and that multi-line output is not + // supported. If developers know that a byte array is + // printable and they want multi-line output, they can + // convert the value to string before logging it. + b.WriteByte('=') + b.WriteString(fmt.Sprintf("%+q", v)) + default: + writeStringValue(b, false, f.AnyToString(v)) } } +func KVFormat(b *bytes.Buffer, k, v interface{}) { + Formatter{}.KVFormat(b, k, v) +} + +// AnyToString is the historic fallback formatter. +func (f Formatter) AnyToString(v interface{}) string { + if f.AnyToStringHook != nil { + return f.AnyToStringHook(v) + } + return fmt.Sprintf("%+v", v) +} + // StringerToString converts a Stringer to a string, // handling panics if they occur. func StringerToString(s fmt.Stringer) (ret string) { @@ -203,6 +286,16 @@ func ErrorToString(err error) (ret string) { return } +func writeTextWriterValue(b *bytes.Buffer, v textWriter) { + b.WriteRune('=') + defer func() { + if err := recover(); err != nil { + fmt.Fprintf(b, `""`, err) + } + }() + v.WriteText(b) +} + func writeStringValue(b *bytes.Buffer, quote bool, v string) { data := []byte(v) index := bytes.IndexByte(data, '\n') diff --git a/vendor/k8s.io/klog/v2/k8s_references.go b/vendor/k8s.io/klog/v2/k8s_references.go index 2c218f698c7..ecd3f8b6903 100644 --- a/vendor/k8s.io/klog/v2/k8s_references.go +++ b/vendor/k8s.io/klog/v2/k8s_references.go @@ -17,8 +17,10 @@ limitations under the License. package klog import ( + "bytes" "fmt" "reflect" + "strings" "github.com/go-logr/logr" ) @@ -31,11 +33,30 @@ type ObjectRef struct { func (ref ObjectRef) String() string { if ref.Namespace != "" { - return fmt.Sprintf("%s/%s", ref.Namespace, ref.Name) + var builder strings.Builder + builder.Grow(len(ref.Namespace) + len(ref.Name) + 1) + builder.WriteString(ref.Namespace) + builder.WriteRune('/') + builder.WriteString(ref.Name) + return builder.String() } return ref.Name } +func (ref ObjectRef) WriteText(out *bytes.Buffer) { + out.WriteRune('"') + ref.writeUnquoted(out) + out.WriteRune('"') +} + +func (ref ObjectRef) writeUnquoted(out *bytes.Buffer) { + if ref.Namespace != "" { + out.WriteString(ref.Namespace) + out.WriteRune('/') + } + out.WriteString(ref.Name) +} + // MarshalLog ensures that loggers with support for structured output will log // as a struct by removing the String method via a custom type. func (ref ObjectRef) MarshalLog() interface{} { @@ -117,31 +138,31 @@ var _ fmt.Stringer = kobjSlice{} var _ logr.Marshaler = kobjSlice{} func (ks kobjSlice) String() string { - objectRefs, err := ks.process() - if err != nil { - return err.Error() + objectRefs, errStr := ks.process() + if errStr != "" { + return errStr } return fmt.Sprintf("%v", objectRefs) } func (ks kobjSlice) MarshalLog() interface{} { - objectRefs, err := ks.process() - if err != nil { - return err.Error() + objectRefs, errStr := ks.process() + if errStr != "" { + return errStr } return objectRefs } -func (ks kobjSlice) process() ([]interface{}, error) { +func (ks kobjSlice) process() (objs []interface{}, err string) { s := reflect.ValueOf(ks.arg) switch s.Kind() { case reflect.Invalid: // nil parameter, print as nil. - return nil, nil + return nil, "" case reflect.Slice: // Okay, handle below. default: - return nil, fmt.Errorf("", ks.arg) + return nil, fmt.Sprintf("", ks.arg) } objectRefs := make([]interface{}, 0, s.Len()) for i := 0; i < s.Len(); i++ { @@ -151,8 +172,41 @@ func (ks kobjSlice) process() ([]interface{}, error) { } else if v, ok := item.(KMetadata); ok { objectRefs = append(objectRefs, KObj(v)) } else { - return nil, fmt.Errorf("", item) + return nil, fmt.Sprintf("", item) + } + } + return objectRefs, "" +} + +var nilToken = []byte("") + +func (ks kobjSlice) WriteText(out *bytes.Buffer) { + s := reflect.ValueOf(ks.arg) + switch s.Kind() { + case reflect.Invalid: + // nil parameter, print as empty slice. + out.WriteString("[]") + return + case reflect.Slice: + // Okay, handle below. + default: + fmt.Fprintf(out, `""`, ks.arg) + return + } + out.Write([]byte{'['}) + defer out.Write([]byte{']'}) + for i := 0; i < s.Len(); i++ { + if i > 0 { + out.Write([]byte{' '}) + } + item := s.Index(i).Interface() + if item == nil { + out.Write(nilToken) + } else if v, ok := item.(KMetadata); ok { + KObj(v).writeUnquoted(out) + } else { + fmt.Fprintf(out, "", item) + return } } - return objectRefs, nil } diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index 652fadcd4e4..466eeaf265b 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -39,39 +39,38 @@ // This package provides several flags that modify this behavior. // As a result, flag.Parse must be called before any logging is done. // -// -logtostderr=true -// Logs are written to standard error instead of to files. -// This shortcuts most of the usual output routing: -// -alsologtostderr, -stderrthreshold and -log_dir have no -// effect and output redirection at runtime with SetOutput is -// ignored. -// -alsologtostderr=false -// Logs are written to standard error as well as to files. -// -stderrthreshold=ERROR -// Log events at or above this severity are logged to standard -// error as well as to files. -// -log_dir="" -// Log files will be written to this directory instead of the -// default temporary directory. +// -logtostderr=true +// Logs are written to standard error instead of to files. +// This shortcuts most of the usual output routing: +// -alsologtostderr, -stderrthreshold and -log_dir have no +// effect and output redirection at runtime with SetOutput is +// ignored. +// -alsologtostderr=false +// Logs are written to standard error as well as to files. +// -stderrthreshold=ERROR +// Log events at or above this severity are logged to standard +// error as well as to files. +// -log_dir="" +// Log files will be written to this directory instead of the +// default temporary directory. // -// Other flags provide aids to debugging. -// -// -log_backtrace_at="" -// When set to a file and line number holding a logging statement, -// such as -// -log_backtrace_at=gopherflakes.go:234 -// a stack trace will be written to the Info log whenever execution -// hits that statement. (Unlike with -vmodule, the ".go" must be -// present.) -// -v=0 -// Enable V-leveled logging at the specified level. -// -vmodule="" -// The syntax of the argument is a comma-separated list of pattern=N, -// where pattern is a literal file name (minus the ".go" suffix) or -// "glob" pattern and N is a V level. For instance, -// -vmodule=gopher*=3 -// sets the V level to 3 in all Go files whose names begin "gopher". +// Other flags provide aids to debugging. // +// -log_backtrace_at="" +// When set to a file and line number holding a logging statement, +// such as +// -log_backtrace_at=gopherflakes.go:234 +// a stack trace will be written to the Info log whenever execution +// hits that statement. (Unlike with -vmodule, the ".go" must be +// present.) +// -v=0 +// Enable V-leveled logging at the specified level. +// -vmodule="" +// The syntax of the argument is a comma-separated list of pattern=N, +// where pattern is a literal file name (minus the ".go" suffix) or +// "glob" pattern and N is a V level. For instance, +// -vmodule=gopher*=3 +// sets the V level to 3 in all Go files whose names begin "gopher". package klog import ( @@ -92,8 +91,6 @@ import ( "sync/atomic" "time" - "github.com/go-logr/logr" - "k8s.io/klog/v2/internal/buffer" "k8s.io/klog/v2/internal/clock" "k8s.io/klog/v2/internal/dbg" @@ -397,45 +394,48 @@ type flushSyncWriter interface { io.Writer } -// init sets up the defaults. +var logging loggingT +var commandLine flag.FlagSet + +// init sets up the defaults and creates command line flags. func init() { + commandLine.StringVar(&logging.logDir, "log_dir", "", "If non-empty, write log files in this directory (no effect when -logtostderr=true)") + commandLine.StringVar(&logging.logFile, "log_file", "", "If non-empty, use this log file (no effect when -logtostderr=true)") + commandLine.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", 1800, + "Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. "+ + "If the value is 0, the maximum file size is unlimited.") + commandLine.BoolVar(&logging.toStderr, "logtostderr", true, "log to standard error instead of files") + commandLine.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files (no effect when -logtostderr=true)") + logging.setVState(0, nil, false) + commandLine.Var(&logging.verbosity, "v", "number for the log level verbosity") + commandLine.BoolVar(&logging.addDirHeader, "add_dir_header", false, "If true, adds the file directory to the header of the log messages") + commandLine.BoolVar(&logging.skipHeaders, "skip_headers", false, "If true, avoid header prefixes in the log messages") + commandLine.BoolVar(&logging.oneOutput, "one_output", false, "If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)") + commandLine.BoolVar(&logging.skipLogHeaders, "skip_log_headers", false, "If true, avoid headers when opening log files (no effect when -logtostderr=true)") logging.stderrThreshold = severityValue{ Severity: severity.ErrorLog, // Default stderrThreshold is ERROR. } - logging.setVState(0, nil, false) - logging.logDir = "" - logging.logFile = "" - logging.logFileMaxSizeMB = 1800 - logging.toStderr = true - logging.alsoToStderr = false - logging.skipHeaders = false - logging.addDirHeader = false - logging.skipLogHeaders = false - logging.oneOutput = false + commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false)") + commandLine.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") + commandLine.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") + + logging.settings.contextualLoggingEnabled = true logging.flushD = newFlushDaemon(logging.lockAndFlushAll, nil) } // InitFlags is for explicitly initializing the flags. +// It may get called repeatedly for different flagsets, but not +// twice for the same one. May get called concurrently +// to other goroutines using klog. However, only some flags +// may get set concurrently (see implementation). func InitFlags(flagset *flag.FlagSet) { if flagset == nil { flagset = flag.CommandLine } - flagset.StringVar(&logging.logDir, "log_dir", logging.logDir, "If non-empty, write log files in this directory (no effect when -logtostderr=true)") - flagset.StringVar(&logging.logFile, "log_file", logging.logFile, "If non-empty, use this log file (no effect when -logtostderr=true)") - flagset.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", logging.logFileMaxSizeMB, - "Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. "+ - "If the value is 0, the maximum file size is unlimited.") - flagset.BoolVar(&logging.toStderr, "logtostderr", logging.toStderr, "log to standard error instead of files") - flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", logging.alsoToStderr, "log to standard error as well as files (no effect when -logtostderr=true)") - flagset.Var(&logging.verbosity, "v", "number for the log level verbosity") - flagset.BoolVar(&logging.addDirHeader, "add_dir_header", logging.addDirHeader, "If true, adds the file directory to the header of the log messages") - flagset.BoolVar(&logging.skipHeaders, "skip_headers", logging.skipHeaders, "If true, avoid header prefixes in the log messages") - flagset.BoolVar(&logging.oneOutput, "one_output", logging.oneOutput, "If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)") - flagset.BoolVar(&logging.skipLogHeaders, "skip_log_headers", logging.skipLogHeaders, "If true, avoid headers when opening log files (no effect when -logtostderr=true)") - flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false)") - flagset.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") - flagset.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") + commandLine.VisitAll(func(f *flag.Flag) { + flagset.Var(f.Value, f.Name, f.Usage) + }) } // Flush flushes all pending log I/O. @@ -451,7 +451,7 @@ type settings struct { // logger is the global Logger chosen by users of klog, nil if // none is available. - logger *Logger + logger *logWriter // loggerOptions contains the options that were supplied for // globalLogger. @@ -523,6 +523,11 @@ func (s settings) deepCopy() settings { } s.vmodule.filter = filter + if s.logger != nil { + logger := *s.logger + s.logger = &logger + } + return s } @@ -530,11 +535,6 @@ func (s settings) deepCopy() settings { type loggingT struct { settings - // bufferCache maintains the free list. It uses its own mutex - // so buffers can be grabbed and printed to without holding the main lock, - // for better parallelization. - bufferCache buffer.Buffers - // flushD holds a flushDaemon that frequently flushes log file buffers. // Uses its own mutex. flushD *flushDaemon @@ -550,12 +550,6 @@ type loggingT struct { vmap map[uintptr]Level } -var logging = loggingT{ - settings: settings{ - contextualLoggingEnabled: true, - }, -} - // setVState sets a consistent state for V logging. // l.mu is held. func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) { @@ -633,8 +627,11 @@ It returns a buffer containing the formatted header and the user's file and line The depth specifies how many stack frames above lives the source line to be identified in the log message. Log lines have this form: + Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... + where the fields are defined as follows: + L A single character, representing the log level (eg 'I' for INFO) mm The month (zero padded; ie May is '05') dd The day (zero padded) @@ -665,7 +662,7 @@ func (l *loggingT) header(s severity.Severity, depth int) (*buffer.Buffer, strin // formatHeader formats a log header using the provided file name and line number. func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buffer.Buffer { - buf := l.bufferCache.GetBuffer() + buf := buffer.GetBuffer() if l.skipHeaders { return buf } @@ -674,17 +671,18 @@ func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buf return buf } -func (l *loggingT) println(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { +func (l *loggingT) println(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) { l.printlnDepth(s, logger, filter, 1, args...) } -func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { +func (l *loggingT) printlnDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logger is set, we clear the generated header as we rely on the backing - // logger implementation to print headers - if logger != nil { - l.bufferCache.PutBuffer(buf) - buf = l.bufferCache.GetBuffer() + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { + buffer.PutBuffer(buf) + buf = buffer.GetBuffer() } if filter != nil { args = filter.Filter(args) @@ -693,17 +691,18 @@ func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter l.output(s, logger, buf, depth, file, line, false) } -func (l *loggingT) print(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { +func (l *loggingT) print(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) { l.printDepth(s, logger, filter, 1, args...) } -func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { +func (l *loggingT) printDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { - l.bufferCache.PutBuffer(buf) - buf = l.bufferCache.GetBuffer() + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { + buffer.PutBuffer(buf) + buf = buffer.GetBuffer() } if filter != nil { args = filter.Filter(args) @@ -715,17 +714,18 @@ func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter L l.output(s, logger, buf, depth, file, line, false) } -func (l *loggingT) printf(s severity.Severity, logger *logr.Logger, filter LogFilter, format string, args ...interface{}) { +func (l *loggingT) printf(s severity.Severity, logger *logWriter, filter LogFilter, format string, args ...interface{}) { l.printfDepth(s, logger, filter, 1, format, args...) } -func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, format string, args ...interface{}) { +func (l *loggingT) printfDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, format string, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { - l.bufferCache.PutBuffer(buf) - buf = l.bufferCache.GetBuffer() + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { + buffer.PutBuffer(buf) + buf = buffer.GetBuffer() } if filter != nil { format, args = filter.FilterF(format, args) @@ -740,13 +740,14 @@ func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter // printWithFileLine behaves like print but uses the provided file and line number. If // alsoLogToStderr is true, the log message always appears on standard error; it // will also appear in the log file unless --logtostderr is set. -func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { +func (l *loggingT) printWithFileLine(s severity.Severity, logger *logWriter, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { buf := l.formatHeader(s, file, line) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { - l.bufferCache.PutBuffer(buf) - buf = l.bufferCache.GetBuffer() + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { + buffer.PutBuffer(buf) + buf = buffer.GetBuffer() } if filter != nil { args = filter.Filter(args) @@ -759,7 +760,7 @@ func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, f } // if loggr is specified, will call loggr.Error, otherwise output with logging module. -func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) errorS(err error, logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } @@ -771,7 +772,7 @@ func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, dept } // if loggr is specified, will call loggr.Info, otherwise output with logging module. -func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } @@ -786,7 +787,7 @@ func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg s // set log severity by s func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) { // Only create a new buffer if we don't have one cached. - b := l.bufferCache.GetBuffer() + b := buffer.GetBuffer() // The message is always quoted, even if it contains line breaks. // If developers want multi-line output, they should use a small, fixed // message and put the multi-line output into a value. @@ -797,7 +798,7 @@ func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, serialize.KVListFormat(&b.Buffer, keysAndValues...) l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer) // Make the buffer available for reuse. - l.bufferCache.PutBuffer(b) + buffer.PutBuffer(b) } // redirectBuffer is used to set an alternate destination for the logs @@ -852,7 +853,7 @@ func LogToStderr(stderr bool) { } // output writes the data to the log files and releases the buffer. -func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { +func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { var isLocked = true l.mu.Lock() defer func() { @@ -868,13 +869,17 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf } } data := buf.Bytes() - if log != nil { - // TODO: set 'severity' and caller information as structured log info - // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} - if s == severity.ErrorLog { - logging.logger.WithCallDepth(depth+3).Error(nil, string(data)) + if logger != nil { + if logger.writeKlogBuffer != nil { + logger.writeKlogBuffer(data) } else { - log.WithCallDepth(depth + 3).Info(string(data)) + // TODO: set 'severity' and caller information as structured log info + // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} + if s == severity.ErrorLog { + logger.WithCallDepth(depth+3).Error(nil, string(data)) + } else { + logger.WithCallDepth(depth + 3).Info(string(data)) + } } } else if l.toStderr { os.Stderr.Write(data) @@ -949,7 +954,7 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf timeoutFlush(ExitFlushTimeout) OsExit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. } - l.bufferCache.PutBuffer(buf) + buffer.PutBuffer(buf) if stats := severityStats[s]; stats != nil { atomic.AddInt64(&stats.lines, 1) @@ -1283,7 +1288,7 @@ func (l *loggingT) setV(pc uintptr) Level { // See the documentation of V for more information. type Verbose struct { enabled bool - logr *logr.Logger + logger *logWriter } func newVerbose(level Level, b bool) Verbose { @@ -1291,16 +1296,20 @@ func newVerbose(level Level, b bool) Verbose { return Verbose{b, nil} } v := logging.logger.V(int(level)) - return Verbose{b, &v} + return Verbose{b, &logWriter{Logger: v, writeKlogBuffer: logging.loggerOptions.writeKlogBuffer}} } // V reports whether verbosity at the call site is at least the requested level. // The returned value is a struct of type Verbose, which implements Info, Infoln // and Infof. These methods will write to the Info log if called. // Thus, one may write either +// // if klog.V(2).Enabled() { klog.Info("log this") } +// // or +// // klog.V(2).Info("log this") +// // The second form is shorter but the first is cheaper if logging is off because it does // not evaluate its arguments. // @@ -1310,6 +1319,13 @@ func newVerbose(level Level, b bool) Verbose { // less than or equal to the value of the -vmodule pattern matching the source file // containing the call. func V(level Level) Verbose { + return VDepth(1, level) +} + +// VDepth is a variant of V that accepts a number of stack frames that will be +// skipped when checking the -vmodule patterns. VDepth(0) is equivalent to +// V(). +func VDepth(depth int, level Level) Verbose { // This function tries hard to be cheap unless there's work to do. // The fast path is two atomic loads and compares. @@ -1326,7 +1342,7 @@ func V(level Level) Verbose { // but if V logging is enabled we're slow anyway. logging.mu.Lock() defer logging.mu.Unlock() - if runtime.Callers(2, logging.pcs[:]) == 0 { + if runtime.Callers(2+depth, logging.pcs[:]) == 0 { return newVerbose(level, false) } // runtime.Callers returns "return PCs", but we want @@ -1354,7 +1370,7 @@ func (v Verbose) Enabled() bool { // See the documentation of V for usage. func (v Verbose) Info(args ...interface{}) { if v.enabled { - logging.print(severity.InfoLog, v.logr, logging.filter, args...) + logging.print(severity.InfoLog, v.logger, logging.filter, args...) } } @@ -1362,7 +1378,7 @@ func (v Verbose) Info(args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoDepth(depth int, args ...interface{}) { if v.enabled { - logging.printDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + logging.printDepth(severity.InfoLog, v.logger, logging.filter, depth, args...) } } @@ -1370,7 +1386,7 @@ func (v Verbose) InfoDepth(depth int, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) Infoln(args ...interface{}) { if v.enabled { - logging.println(severity.InfoLog, v.logr, logging.filter, args...) + logging.println(severity.InfoLog, v.logger, logging.filter, args...) } } @@ -1378,7 +1394,7 @@ func (v Verbose) Infoln(args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfolnDepth(depth int, args ...interface{}) { if v.enabled { - logging.printlnDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + logging.printlnDepth(severity.InfoLog, v.logger, logging.filter, depth, args...) } } @@ -1386,7 +1402,7 @@ func (v Verbose) InfolnDepth(depth int, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) Infof(format string, args ...interface{}) { if v.enabled { - logging.printf(severity.InfoLog, v.logr, logging.filter, format, args...) + logging.printf(severity.InfoLog, v.logger, logging.filter, format, args...) } } @@ -1394,7 +1410,7 @@ func (v Verbose) Infof(format string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { if v.enabled { - logging.printfDepth(severity.InfoLog, v.logr, logging.filter, depth, format, args...) + logging.printfDepth(severity.InfoLog, v.logger, logging.filter, depth, format, args...) } } @@ -1402,7 +1418,7 @@ func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) { if v.enabled { - logging.infoS(v.logr, logging.filter, 0, msg, keysAndValues...) + logging.infoS(v.logger, logging.filter, 0, msg, keysAndValues...) } } @@ -1416,14 +1432,14 @@ func InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { if v.enabled { - logging.infoS(v.logr, logging.filter, depth, msg, keysAndValues...) + logging.infoS(v.logger, logging.filter, depth, msg, keysAndValues...) } } // Deprecated: Use ErrorS instead. func (v Verbose) Error(err error, msg string, args ...interface{}) { if v.enabled { - logging.errorS(err, v.logr, logging.filter, 0, msg, args...) + logging.errorS(err, v.logger, logging.filter, 0, msg, args...) } } @@ -1431,7 +1447,7 @@ func (v Verbose) Error(err error, msg string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) { if v.enabled { - logging.errorS(err, v.logr, logging.filter, 0, msg, keysAndValues...) + logging.errorS(err, v.logger, logging.filter, 0, msg, keysAndValues...) } } @@ -1582,10 +1598,10 @@ func ErrorSDepth(depth int, err error, msg string, keysAndValues ...interface{}) // // Callers who want more control over handling of fatal events may instead use a // combination of different functions: -// - some info or error logging function, optionally with a stack trace -// value generated by github.com/go-logr/lib/dbg.Backtrace -// - Flush to flush pending log data -// - panic, os.Exit or returning to the caller with an error +// - some info or error logging function, optionally with a stack trace +// value generated by github.com/go-logr/lib/dbg.Backtrace +// - Flush to flush pending log data +// - panic, os.Exit or returning to the caller with an error // // Arguments are handled in the manner of fmt.Print; a newline is appended if missing. func Fatal(args ...interface{}) { diff --git a/vendor/k8s.io/klog/v2/klogr.go b/vendor/k8s.io/klog/v2/klogr.go index 027a4014af5..15de00e21fb 100644 --- a/vendor/k8s.io/klog/v2/klogr.go +++ b/vendor/k8s.io/klog/v2/klogr.go @@ -42,19 +42,21 @@ func (l *klogger) Init(info logr.RuntimeInfo) { l.callDepth += info.CallDepth } -func (l klogger) Info(level int, msg string, kvList ...interface{}) { +func (l *klogger) Info(level int, msg string, kvList ...interface{}) { merged := serialize.MergeKVs(l.values, kvList) if l.prefix != "" { msg = l.prefix + ": " + msg } - V(Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) + // Skip this function. + VDepth(l.callDepth+1, Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) } -func (l klogger) Enabled(level int) bool { - return V(Level(level)).Enabled() +func (l *klogger) Enabled(level int) bool { + // Skip this function and logr.Logger.Info where Enabled is called. + return VDepth(l.callDepth+2, Level(level)).Enabled() } -func (l klogger) Error(err error, msg string, kvList ...interface{}) { +func (l *klogger) Error(err error, msg string, kvList ...interface{}) { merged := serialize.MergeKVs(l.values, kvList) if l.prefix != "" { msg = l.prefix + ": " + msg diff --git a/vendor/k8s.io/kube-openapi/pkg/cached/cache.go b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go new file mode 100644 index 00000000000..16e34853af7 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go @@ -0,0 +1,264 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package cache provides a cache mechanism based on etags to lazily +// build, and/or cache results from expensive operation such that those +// operations are not repeated unnecessarily. The operations can be +// created as a tree, and replaced dynamically as needed. +// +// # Dependencies and types of caches +// +// This package uses a source/transform/sink model of caches to build +// the dependency tree, and can be used as follows: +// - [NewSource]: A source cache that recomputes the content every time. +// - [NewStaticSource]: A source cache that always produces the +// same content, it is only called once. +// - [NewTransformer]: A cache that transforms data from one format to +// another. It's only refreshed when the source changes. +// - [NewMerger]: A cache that aggregates multiple caches into one. +// It's only refreshed when the source changes. +// - [Replaceable]: A cache adapter that can be atomically +// replaced with a new one, and saves the previous results in case an +// error pops-up. +// +// # Atomicity +// +// Most of the operations are not atomic/thread-safe, except for +// [Replaceable.Replace] which can be performed while the objects +// are being read. +// +// # Etags +// +// Etags in this library is a cache version identifier. It doesn't +// necessarily strictly match to the semantics of http `etags`, but are +// somewhat inspired from it and function with the same principles. +// Hashing the content is a good way to guarantee that your function is +// never going to be called spuriously. In Kubernetes world, this could +// be a `resourceVersion`, this can be an actual etag, a hash, a UUID +// (if the cache always changes), or even a made-up string when the +// content of the cache never changes. +package cached + +import ( + "fmt" + "sync/atomic" +) + +// Result is the content returned from a call to a cache. It can either +// be created with [NewResultOK] if the call was a success, or +// [NewResultErr] if the call resulted in an error. +type Result[T any] struct { + Data T + Etag string + Err error +} + +// NewResultOK creates a new [Result] for a successful operation. +func NewResultOK[T any](data T, etag string) Result[T] { + return Result[T]{ + Data: data, + Etag: etag, + } +} + +// NewResultErr creates a new [Result] when an error has happened. +func NewResultErr[T any](err error) Result[T] { + return Result[T]{ + Err: err, + } +} + +// Result can be treated as a [Data] if necessary. +func (r Result[T]) Get() Result[T] { + return r +} + +// Data is a cache that performs an action whose result data will be +// cached. It also returns an "etag" identifier to version the cache, so +// that the caller can know if they have the most recent version of the +// cache (and can decide to cache some operation based on that). +// +// The [NewMerger] and [NewTransformer] automatically handle +// that for you by checking if the etag is updated before calling the +// merging or transforming function. +type Data[T any] interface { + // Returns the cached data, as well as an "etag" to identify the + // version of the cache, or an error if something happened. + Get() Result[T] +} + +// T is the source type, V is the destination type. +type merger[K comparable, T, V any] struct { + mergeFn func(map[K]Result[T]) Result[V] + caches map[K]Data[T] + cacheResults map[K]Result[T] + result Result[V] +} + +// NewMerger creates a new merge cache, a cache that merges the result +// of other caches. The function only gets called if any of the +// dependency has changed. +// +// If any of the dependency returned an error before, or any of the +// dependency returned an error this time, or if the mergeFn failed +// before, then the function is reran. +// +// The caches and results are mapped by K so that associated data can be +// retrieved. The map of dependencies can not be modified after +// creation, and a new merger should be created (and probably replaced +// using a [Replaceable]). +// +// Note that this assumes there is no "partial" merge, the merge +// function will remerge all the dependencies together everytime. Since +// the list of dependencies is constant, there is no way to save some +// partial merge information either. +func NewMerger[K comparable, T, V any](mergeFn func(results map[K]Result[T]) Result[V], caches map[K]Data[T]) Data[V] { + return &merger[K, T, V]{ + mergeFn: mergeFn, + caches: caches, + } +} + +func (c *merger[K, T, V]) prepareResults() map[K]Result[T] { + cacheResults := make(map[K]Result[T], len(c.caches)) + for key, cache := range c.caches { + cacheResults[key] = cache.Get() + } + return cacheResults +} + +// Rerun if: +// - The last run resulted in an error +// - Any of the dependency previously returned an error +// - Any of the dependency just returned an error +// - Any of the dependency's etag changed +func (c *merger[K, T, V]) needsRunning(results map[K]Result[T]) bool { + if c.cacheResults == nil { + return true + } + if c.result.Err != nil { + return true + } + if len(results) != len(c.cacheResults) { + panic(fmt.Errorf("invalid number of results: %v (expected %v)", len(results), len(c.cacheResults))) + } + for key, oldResult := range c.cacheResults { + newResult, ok := results[key] + if !ok { + panic(fmt.Errorf("unknown cache entry: %v", key)) + } + + if newResult.Etag != oldResult.Etag || newResult.Err != nil || oldResult.Err != nil { + return true + } + } + return false +} + +func (c *merger[K, T, V]) Get() Result[V] { + cacheResults := c.prepareResults() + if c.needsRunning(cacheResults) { + c.cacheResults = cacheResults + c.result = c.mergeFn(c.cacheResults) + } + return c.result +} + +type transformerCacheKeyType struct{} + +// NewTransformer creates a new cache that transforms the result of +// another cache. The transformFn will only be called if the source +// cache has updated the output, otherwise, the cached result will be +// returned. +// +// If the dependency returned an error before, or it returns an error +// this time, or if the transformerFn failed before, the function is +// reran. +func NewTransformer[T, V any](transformerFn func(Result[T]) Result[V], source Data[T]) Data[V] { + return NewMerger(func(caches map[transformerCacheKeyType]Result[T]) Result[V] { + cache, ok := caches[transformerCacheKeyType{}] + if len(caches) != 1 || !ok { + panic(fmt.Errorf("invalid cache for transformer cache: %v", caches)) + } + return transformerFn(cache) + }, map[transformerCacheKeyType]Data[T]{ + {}: source, + }) +} + +// NewSource creates a new cache that generates some data. This +// will always be called since we don't know the origin of the data and +// if it needs to be updated or not. +func NewSource[T any](sourceFn func() Result[T]) Data[T] { + c := source[T](sourceFn) + return &c +} + +type source[T any] func() Result[T] + +func (c *source[T]) Get() Result[T] { + return (*c)() +} + +// NewStaticSource creates a new cache that always generates the +// same data. This will only be called once (lazily). +func NewStaticSource[T any](staticFn func() Result[T]) Data[T] { + return &static[T]{ + fn: staticFn, + } +} + +type static[T any] struct { + fn func() Result[T] + result *Result[T] +} + +func (c *static[T]) Get() Result[T] { + if c.result == nil { + result := c.fn() + c.result = &result + } + return *c.result +} + +// Replaceable is a cache that carries the result even when the +// cache is replaced. The cache can be replaced atomically (without any +// lock held). This is the type that should typically be stored in +// structs. +type Replaceable[T any] struct { + cache atomic.Pointer[Data[T]] + result *Result[T] +} + +// Get retrieves the data from the underlying source. [Replaceable] +// implements the [Data] interface itself. This is a pass-through +// that calls the most recent underlying cache. If the cache fails but +// previously had returned a success, that success will be returned +// instead. If the cache fails but we never returned a success, that +// failure is returned. +func (c *Replaceable[T]) Get() Result[T] { + result := (*c.cache.Load()).Get() + if result.Err != nil && c.result != nil && c.result.Err == nil { + return *c.result + } + c.result = &result + return *c.result +} + +// Replace changes the cache in a thread-safe way. +func (c *Replaceable[T]) Replace(cache Data[T]) { + c.cache.Swap(&cache) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/common.go b/vendor/k8s.io/kube-openapi/pkg/common/common.go index c84ca703160..1a6c12e17a5 100644 --- a/vendor/k8s.io/kube-openapi/pkg/common/common.go +++ b/vendor/k8s.io/kube-openapi/pkg/common/common.go @@ -20,7 +20,7 @@ import ( "net/http" "strings" - "github.com/emicklei/go-restful" + "github.com/emicklei/go-restful/v3" "k8s.io/kube-openapi/pkg/openapiconv" "k8s.io/kube-openapi/pkg/spec3" @@ -246,38 +246,42 @@ var schemaTypeFormatMap = map[string]typeInfo{ // the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple // type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation. // Example: -// type Sample struct { -// ... -// // port of the server -// port IntOrString -// ... -// } +// +// type Sample struct { +// ... +// // port of the server +// port IntOrString +// ... +// } +// // // IntOrString documentation... // type IntOrString { ... } // // Adding IntOrString to this function: -// "port" : { -// format: "string", -// type: "int-or-string", -// Description: "port of the server" -// } +// +// "port" : { +// format: "string", +// type: "int-or-string", +// Description: "port of the server" +// } // // Implement OpenAPIDefinitionGetter for IntOrString: // -// "port" : { -// $Ref: "#/definitions/IntOrString" -// Description: "port of the server" -// } +// "port" : { +// $Ref: "#/definitions/IntOrString" +// Description: "port of the server" +// } +// // ... // definitions: -// { -// "IntOrString": { -// format: "string", -// type: "int-or-string", -// Description: "IntOrString documentation..." // new -// } -// } // +// { +// "IntOrString": { +// format: "string", +// type: "int-or-string", +// Description: "IntOrString documentation..." // new +// } +// } func OpenAPITypeFormat(typeName string) (string, string) { mapped, ok := schemaTypeFormatMap[typeName] if !ok { diff --git a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go index ec4adcdec2a..66b7a68da67 100644 --- a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go +++ b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go @@ -21,11 +21,9 @@ import ( "crypto/sha512" "encoding/json" "fmt" - "mime" "net/http" "net/url" "path" - "sort" "strconv" "strings" "sync" @@ -33,23 +31,18 @@ import ( "github.com/golang/protobuf/proto" openapi_v3 "github.com/google/gnostic/openapiv3" + "github.com/google/uuid" "github.com/munnerz/goautoneg" + "k8s.io/klog/v2" + "k8s.io/kube-openapi/pkg/cached" "k8s.io/kube-openapi/pkg/common" - "k8s.io/kube-openapi/pkg/internal/handler" "k8s.io/kube-openapi/pkg/spec3" - "k8s.io/kube-openapi/pkg/validation/spec" ) const ( - jsonExt = ".json" - - mimeJson = "application/json" - // TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags. - mimePb = "application/com.github.googleapis.gnostic.OpenAPIv3@68f4ded+protobuf" - mimePbGz = "application/x-gzip" - - subTypeProtobuf = "com.github.proto-openapi.spec.v3@v1.0+protobuf" - subTypeJSON = "json" + subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v3@v1.0+protobuf" + subTypeProtobuf = "com.github.proto-openapi.spec.v3.v1.0+protobuf" + subTypeJSON = "json" ) // OpenAPIV3Discovery is the format of the Discovery document for OpenAPI V3 @@ -65,29 +58,63 @@ type OpenAPIV3DiscoveryGroupVersion struct { ServerRelativeURL string `json:"serverRelativeURL"` } -// OpenAPIService is the service responsible for serving OpenAPI spec. It has -// the ability to safely change the spec while serving it. -type OpenAPIService struct { - // rwMutex protects All members of this service. - rwMutex sync.RWMutex +func ToV3ProtoBinary(json []byte) ([]byte, error) { + document, err := openapi_v3.ParseDocument(json) + if err != nil { + return nil, err + } + return proto.Marshal(document) +} + +type timedSpec struct { + spec []byte lastModified time.Time - v3Schema map[string]*OpenAPIV3Group } -type OpenAPIV3Group struct { - rwMutex sync.RWMutex +// This type is protected by the lock on OpenAPIService. +type openAPIV3Group struct { + specCache cached.Replaceable[*spec3.OpenAPI] + pbCache cached.Data[timedSpec] + jsonCache cached.Data[timedSpec] +} - lastModified time.Time +func newOpenAPIV3Group() *openAPIV3Group { + o := &openAPIV3Group{} + o.jsonCache = cached.NewTransformer[*spec3.OpenAPI](func(result cached.Result[*spec3.OpenAPI]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + json, err := json.Marshal(result.Data) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: json, lastModified: time.Now()}, computeETag(json)) + }, &o.specCache) + o.pbCache = cached.NewTransformer(func(result cached.Result[timedSpec]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + proto, err := ToV3ProtoBinary(result.Data.spec) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: proto, lastModified: result.Data.lastModified}, result.Etag) + }, o.jsonCache) + return o +} - pbCache handler.HandlerCache - jsonCache handler.HandlerCache - etagCache handler.HandlerCache +func (o *openAPIV3Group) UpdateSpec(openapi cached.Data[*spec3.OpenAPI]) { + o.specCache.Replace(openapi) } -func init() { - mime.AddExtensionType(".json", mimeJson) - mime.AddExtensionType(".pb-v1", mimePb) - mime.AddExtensionType(".gz", mimePbGz) +// OpenAPIService is the service responsible for serving OpenAPI spec. It has +// the ability to safely change the spec while serving it. +type OpenAPIService struct { + // Mutex protects the schema map. + mutex sync.Mutex + v3Schema map[string]*openAPIV3Group + + discoveryCache cached.Replaceable[timedSpec] } func computeETag(data []byte) string { @@ -106,92 +133,90 @@ func constructServerRelativeURL(gvString, etag string) string { } // NewOpenAPIService builds an OpenAPIService starting with the given spec. -func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) { +func NewOpenAPIService() *OpenAPIService { o := &OpenAPIService{} - o.v3Schema = make(map[string]*OpenAPIV3Group) - return o, nil + o.v3Schema = make(map[string]*openAPIV3Group) + // We're not locked because we haven't shared the structure yet. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) + return o } -func (o *OpenAPIService) getGroupBytes() ([]byte, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() - keys := make([]string, len(o.v3Schema)) - i := 0 - for k := range o.v3Schema { - keys[i] = k - i++ +func (o *OpenAPIService) buildDiscoveryCacheLocked() cached.Data[timedSpec] { + caches := make(map[string]cached.Data[timedSpec], len(o.v3Schema)) + for gvName, group := range o.v3Schema { + caches[gvName] = group.jsonCache } - - sort.Strings(keys) - discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} - for gvString, groupVersion := range o.v3Schema { - etagBytes, err := groupVersion.etagCache.Get() - if err != nil { - return nil, err + return cached.NewMerger(func(results map[string]cached.Result[timedSpec]) cached.Result[timedSpec] { + discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} + for gvName, result := range results { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + discovery.Paths[gvName] = OpenAPIV3DiscoveryGroupVersion{ + ServerRelativeURL: constructServerRelativeURL(gvName, result.Etag), + } } - discovery.Paths[gvString] = OpenAPIV3DiscoveryGroupVersion{ - ServerRelativeURL: constructServerRelativeURL(gvString, string(etagBytes)), + j, err := json.Marshal(discovery) + if err != nil { + return cached.NewResultErr[timedSpec](err) } - } - j, err := json.Marshal(discovery) - if err != nil { - return nil, err - } - return j, nil + return cached.NewResultOK(timedSpec{spec: j, lastModified: time.Now()}, computeETag(j)) + }, caches) } func (o *OpenAPIService) getSingleGroupBytes(getType string, group string) ([]byte, string, time.Time, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() + o.mutex.Lock() + defer o.mutex.Unlock() v, ok := o.v3Schema[group] if !ok { return nil, "", time.Now(), fmt.Errorf("Cannot find CRD group %s", group) } - if getType == subTypeJSON { - specBytes, err := v.jsonCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specBytes, string(etagBytes), v.lastModified, err - } else if getType == subTypeProtobuf { - specPb, err := v.pbCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specPb, string(etagBytes), v.lastModified, err + result := cached.Result[timedSpec]{} + switch getType { + case subTypeJSON: + result = v.jsonCache.Get() + case subTypeProtobuf, subTypeProtobufDeprecated: + result = v.pbCache.Get() + default: + return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) } - return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) + return result.Data.spec, result.Etag, result.Data.lastModified, result.Err } -func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - +// UpdateGroupVersionLazy adds or updates an existing group with the new cached. +func (o *OpenAPIService) UpdateGroupVersionLazy(group string, openapi cached.Data[*spec3.OpenAPI]) { + o.mutex.Lock() + defer o.mutex.Unlock() if _, ok := o.v3Schema[group]; !ok { - o.v3Schema[group] = &OpenAPIV3Group{} + o.v3Schema[group] = newOpenAPIV3Group() + // Since there is a new item, we need to re-build the cache map. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } - return o.v3Schema[group].UpdateSpec(openapi) + o.v3Schema[group].UpdateSpec(openapi) } -func (o *OpenAPIService) DeleteGroupVersion(group string) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - delete(o.v3Schema, group) +func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) { + o.UpdateGroupVersionLazy(group, cached.NewResultOK(openapi, uuid.New().String())) } -func ToV3ProtoBinary(json []byte) ([]byte, error) { - document, err := openapi_v3.ParseDocument(json) - if err != nil { - return nil, err - } - return proto.Marshal(document) +func (o *OpenAPIService) DeleteGroupVersion(group string) { + o.mutex.Lock() + defer o.mutex.Unlock() + delete(o.v3Schema, group) + // Rebuild the merge cache map since the items have changed. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } func (o *OpenAPIService) HandleDiscovery(w http.ResponseWriter, r *http.Request) { - data, _ := o.getGroupBytes() - http.ServeContent(w, r, "/openapi/v3", time.Now(), bytes.NewReader(data)) + result := o.discoveryCache.Get() + if result.Err != nil { + klog.Errorf("Error serving discovery: %s", result.Err) + w.WriteHeader(http.StatusInternalServerError) + return + } + w.Header().Set("Etag", strconv.Quote(result.Etag)) + w.Header().Set("Content-Type", "application/json") + http.ServeContent(w, r, "/openapi/v3", result.Data.lastModified, bytes.NewReader(result.Data.spec)) } func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Request) { @@ -210,11 +235,13 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque } accepted := []struct { - Type string - SubType string + Type string + SubType string + ReturnedContentType string }{ - {"application", subTypeJSON}, - {"application", subTypeProtobuf}, + {"application", subTypeJSON, "application/" + subTypeJSON}, + {"application", subTypeProtobuf, "application/" + subTypeProtobuf}, + {"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf}, } for _, clause := range clauses { @@ -229,6 +256,9 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque if err != nil { return } + // Set Content-Type header in the reponse + w.Header().Set("Content-Type", accepts.ReturnedContentType) + // ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag w.Header().Set("Etag", strconv.Quote(etag)) @@ -262,30 +292,3 @@ func (o *OpenAPIService) RegisterOpenAPIV3VersionedService(servePath string, han handler.HandlePrefix(servePath+"/", http.HandlerFunc(o.HandleGroupVersion)) return nil } - -func (o *OpenAPIV3Group) UpdateSpec(openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - - o.jsonCache = o.jsonCache.New(func() ([]byte, error) { - return json.Marshal(openapi) - }) - o.pbCache = o.pbCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return ToV3ProtoBinary(json) - }) - // TODO: This forces a json marshal of corresponding group-versions. - // We should look to replace this with a faster hashing mechanism. - o.etagCache = o.etagCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return []byte(computeETag(json)), nil - }) - o.lastModified = time.Now() - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/flags.go b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go new file mode 100644 index 00000000000..bef60378231 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +// Used by tests to selectively disable experimental JSON unmarshaler +var UseOptimizedJSONUnmarshaling bool = true +var UseOptimizedJSONUnmarshalingV3 bool = true + +// Used by tests to selectively disable experimental JSON marshaler +var UseOptimizedJSONMarshaling bool = true diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go b/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go deleted file mode 100644 index e128c26ebee..00000000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package handler - -import ( - "sync" -) - -// HandlerCache represents a lazy cache for generating a byte array -// It is used to lazily marshal OpenAPI v2/v3 and lazily generate the ETag -type HandlerCache struct { - BuildCache func() ([]byte, error) - once sync.Once - bytes []byte - err error -} - -// Get either returns the cached value or calls BuildCache() once before caching and returning -// its results. If BuildCache returns an error, the last valid value for the cache (from prior -// calls to New()) is used instead if possible. -func (c *HandlerCache) Get() ([]byte, error) { - c.once.Do(func() { - bytes, err := c.BuildCache() - // if there is an error updating the cache, there can be situations where - // c.bytes contains a valid value (carried over from the previous update) - // but c.err is also not nil; the cache user is expected to check for this - c.err = err - if c.err == nil { - // don't override previous spec if we had an error - c.bytes = bytes - } - }) - return c.bytes, c.err -} - -// New creates a new HandlerCache for situations where a cache refresh is needed. -// This function is not thread-safe and should not be called at the same time as Get(). -func (c *HandlerCache) New(cacheBuilder func() ([]byte, error)) HandlerCache { - return HandlerCache{ - bytes: c.bytes, - BuildCache: cacheBuilder, - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go new file mode 100644 index 00000000000..7393bacf704 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "github.com/go-openapi/jsonreference" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" +) + +// DeterministicMarshal calls the jsonv2 library with the deterministic +// flag in order to have stable marshaling. +func DeterministicMarshal(in any) ([]byte, error) { + return jsonv2.MarshalOptions{Deterministic: true}.Marshal(jsonv2.EncodeOptions{}, in) +} + +// JSONRefFromMap populates a json reference object if the map v contains a $ref key. +func JSONRefFromMap(jsonRef *jsonreference.Ref, v map[string]interface{}) error { + if v == nil { + return nil + } + if vv, ok := v["$ref"]; ok { + if str, ok := vv.(string); ok { + ref, err := jsonreference.New(str) + if err != nil { + return err + } + *jsonRef = ref + } + } + return nil +} + +// SanitizeExtensions sanitizes the input map such that non extension +// keys (non x-*, X-*) keys are dropped from the map. Returns the new +// modified map, or nil if the map is now empty. +func SanitizeExtensions(e map[string]interface{}) map[string]interface{} { + for k := range e { + if !IsExtensionKey(k) { + delete(e, k) + } + } + if len(e) == 0 { + e = nil + } + return e +} + +// IsExtensionKey returns true if the input string is of format x-* or X-* +func IsExtensionKey(k string) bool { + return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-' +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/AUTHORS b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/AUTHORS new file mode 100644 index 00000000000..2b00ddba0df --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at https://tip.golang.org/AUTHORS. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/CONTRIBUTORS b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/CONTRIBUTORS new file mode 100644 index 00000000000..1fbd3e976fa --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at https://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/LICENSE b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/LICENSE new file mode 100644 index 00000000000..2441273007b --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2020 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md new file mode 100644 index 00000000000..0349adf69d2 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md @@ -0,0 +1,321 @@ +# JSON Serialization (v2) + +[![GoDev](https://img.shields.io/static/v1?label=godev&message=reference&color=00add8)](https://pkg.go.dev/github.com/go-json-experiment/json) +[![Build Status](https://github.com/go-json-experiment/json/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/go-json-experiment/json/actions) + +This module hosts an experimental implementation of v2 `encoding/json`. +The API is unstable and breaking changes will regularly be made. +Do not depend on this in publicly available modules. + +## Goals and objectives + +* **Mostly backwards compatible:** If possible, v2 should aim to be _mostly_ +compatible with v1 in terms of both API and default behavior to ease migration. +For example, the `Marshal` and `Unmarshal` functions are the most widely used +declarations in the v1 package. It seems sensible for equivalent functionality +in v2 to be named the same and have the same signature. +Behaviorally, we should aim for 95% to 99% backwards compatibility. +We do not aim for 100% compatibility since we want the freedom to break +certain behaviors that are now considered to have been a mistake. +We may provide options that can bring the v2 implementation to 100% compatibility, +but it will not be the default. + +* **More flexible:** There is a +[long list of feature requests](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+encoding%2Fjson+in%3Atitle). +We should aim to provide the most flexible features that addresses most usages. +We do not want to over fit the v2 API to handle every possible use case. +Ideally, the features provided should be orthogonal in nature such that +any combination of features results in as few surprising edge cases as possible. + +* **More performant:** JSON serialization is widely used and any bit of extra +performance gains will be greatly appreciated. Some rarely used behaviors of v1 +may be dropped in favor of better performance. For example, +despite `Encoder` and `Decoder` operating on an `io.Writer` and `io.Reader`, +they do not operate in a truly streaming manner, +leading to a loss in performance. The v2 implementation should aim to be truly +streaming by default (see [#33714](https://golang.org/issue/33714)). + +* **Easy to use (hard to misuse):** The v2 API should aim to make +the common case easy and the less common case at least possible. +The API should avoid behavior that goes contrary to user expectation, +which may result in subtle bugs (see [#36225](https://golang.org/issue/36225)). + +* **v1 and v2 maintainability:** Since the v1 implementation must stay forever, +it would be beneficial if v1 could be implemented under the hood with v2, +allowing for less maintenance burden in the future. This probably implies that +behavioral changes in v2 relative to v1 need to be exposed as options. + +* **Avoid unsafe:** Standard library packages generally avoid the use of +package `unsafe` even if it could provide a performance boost. +We aim to preserve this property. + +## Expectations + +While this module aims to possibly be the v2 implementation of `encoding/json`, +there is no guarantee that this outcome will occur. As with any major change +to the Go standard library, this will eventually go through the +[Go proposal process](https://github.com/golang/proposal#readme). +At the present moment, this is still in the design and experimentation phase +and is not ready for a formal proposal. + +There are several possible outcomes from this experiment: +1. We determine that a v2 `encoding/json` would not provide sufficient benefit +over the existing v1 `encoding/json` package. Thus, we abandon this effort. +2. We propose a v2 `encoding/json` design, but it is rejected in favor of some +other design that is considered superior. +3. We propose a v2 `encoding/json` design, but rather than adding an entirely +new v2 `encoding/json` package, we decide to merge its functionality into +the existing v1 `encoding/json` package. +4. We propose a v2 `encoding/json` design and it is accepted, resulting in +its addition to the standard library. +5. Some other unforeseen outcome (among the infinite number of possibilities). + +## Development + +This module is primarily developed by +[@dsnet](https://github.com/dsnet), +[@mvdan](https://github.com/mvdan), and +[@johanbrandhorst](https://github.com/johanbrandhorst) +with feedback provided by +[@rogpeppe](https://github.com/rogpeppe), +[@ChrisHines](https://github.com/ChrisHines), and +[@rsc](https://github.com/rsc). + +Discussion about semantics occur semi-regularly, where a +[record of past meetings can be found here](https://docs.google.com/document/d/1rovrOTd-wTawGMPPlPuKhwXaYBg9VszTXR9AQQL5LfI/edit?usp=sharing). + +## Design overview + +This package aims to provide a clean separation between syntax and semantics. +Syntax deals with the structural representation of JSON (as specified in +[RFC 4627](https://tools.ietf.org/html/rfc4627), +[RFC 7159](https://tools.ietf.org/html/rfc7159), +[RFC 7493](https://tools.ietf.org/html/rfc7493), +[RFC 8259](https://tools.ietf.org/html/rfc8259), and +[RFC 8785](https://tools.ietf.org/html/rfc8785)). +Semantics deals with the meaning of syntactic data as usable application data. + +The `Encoder` and `Decoder` types are streaming tokenizers concerned with the +packing or parsing of JSON data. They operate on `Token` and `RawValue` types +which represent the common data structures that are representable in JSON. +`Encoder` and `Decoder` do not aim to provide any interpretation of the data. + +Functions like `Marshal`, `MarshalFull`, `MarshalNext`, `Unmarshal`, +`UnmarshalFull`, and `UnmarshalNext` provide semantic meaning by correlating +any arbitrary Go type with some JSON representation of that type (as stored in +data types like `[]byte`, `io.Writer`, `io.Reader`, `Encoder`, or `Decoder`). + +![API overview](api.png) + +This diagram provides a high-level overview of the v2 `json` package. +Purple blocks represent types, while blue blocks represent functions or methods. +The arrows and their direction represent the approximate flow of data. +The bottom half of the diagram contains functionality that is only concerned +with syntax, while the upper half contains functionality that assigns +semantic meaning to syntactic data handled by the bottom half. + +In contrast to v1 `encoding/json`, options are represented as separate types +rather than being setter methods on the `Encoder` or `Decoder` types. + +## Behavior changes + +The v2 `json` package changes the default behavior of `Marshal` and `Unmarshal` +relative to the v1 `json` package to be more sensible. +Some of these behavior changes have options and workarounds to opt into +behavior similar to what v1 provided. + +This table shows an overview of the changes: + +| v1 | v2 | Details | +| -- | -- | ------- | +| JSON object members are unmarshaled into a Go struct using a **case-insensitive name match**. | JSON object members are unmarshaled into a Go struct using a **case-sensitive name match**. | [CaseSensitivity](/diff_test.go#:~:text=TestCaseSensitivity) | +| When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value is an empty Go value**, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. | When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value would encode as an empty JSON value**, which is defined as a JSON null, or an empty JSON string, object, or array. | [OmitEmptyOption](/diff_test.go#:~:text=TestOmitEmptyOption) | +| The `string` option **does affect** Go bools. | The `string` option **does not affect** Go bools. | [StringOption](/diff_test.go#:~:text=TestStringOption) | +| The `string` option **does not recursively affect** sub-values of the Go field value. | The `string` option **does recursively affect** sub-values of the Go field value. | [StringOption](/diff_test.go#:~:text=TestStringOption) | +| The `string` option **sometimes accepts** a JSON null escaped within a JSON string. | The `string` option **never accepts** a JSON null escaped within a JSON string. | [StringOption](/diff_test.go#:~:text=TestStringOption) | +| A nil Go slice is marshaled as a **JSON null**. | A nil Go slice is marshaled as an **empty JSON array**. | [NilSlicesAndMaps](/diff_test.go#:~:text=TestNilSlicesAndMaps) | +| A nil Go map is marshaled as a **JSON null**. | A nil Go map is marshaled as an **empty JSON object**. | [NilSlicesAndMaps](/diff_test.go#:~:text=TestNilSlicesAndMaps) | +| A Go array may be unmarshaled from a **JSON array of any length**. | A Go array must be unmarshaled from a **JSON array of the same length**. | [Arrays](/diff_test.go#:~:text=Arrays) | +| A Go byte array is represented as a **JSON array of JSON numbers**. | A Go byte array is represented as a **Base64-encoded JSON string**. | [ByteArrays](/diff_test.go#:~:text=TestByteArrays) | +| `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **inconsistently called**. | `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **consistently called**. | [PointerReceiver](/diff_test.go#:~:text=TestPointerReceiver) | +| A Go map is marshaled in a **deterministic order**. | A Go map is marshaled in a **non-deterministic order**. | [MapDeterminism](/diff_test.go#:~:text=TestMapDeterminism) | +| JSON strings are encoded **with HTML-specific characters being escaped**. | JSON strings are encoded **without any characters being escaped** (unless necessary). | [EscapeHTML](/diff_test.go#:~:text=TestEscapeHTML) | +| When marshaling, invalid UTF-8 within a Go string **are silently replaced**. | When marshaling, invalid UTF-8 within a Go string **results in an error**. | [InvalidUTF8](/diff_test.go#:~:text=TestInvalidUTF8) | +| When unmarshaling, invalid UTF-8 within a JSON string **are silently replaced**. | When unmarshaling, invalid UTF-8 within a JSON string **results in an error**. | [InvalidUTF8](/diff_test.go#:~:text=TestInvalidUTF8) | +| When marshaling, **an error does not occur** if the output JSON value contains objects with duplicate names. | When marshaling, **an error does occur** if the output JSON value contains objects with duplicate names. | [DuplicateNames](/diff_test.go#:~:text=TestDuplicateNames) | +| When unmarshaling, **an error does not occur** if the input JSON value contains objects with duplicate names. | When unmarshaling, **an error does occur** if the input JSON value contains objects with duplicate names. | [DuplicateNames](/diff_test.go#:~:text=TestDuplicateNames) | +| Unmarshaling a JSON null into a non-empty Go value **inconsistently clears the value or does nothing**. | Unmarshaling a JSON null into a non-empty Go value **always clears the value**. | [MergeNull](/diff_test.go#:~:text=TestMergeNull) | +| Unmarshaling a JSON value into a non-empty Go value **follows inconsistent and bizarre behavior**. | Unmarshaling a JSON value into a non-empty Go value **always merges if the input is an object, and otherwise replaces**. | [MergeComposite](/diff_test.go#:~:text=TestMergeComposite) | +| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` is represented as a **JSON string containing the formatted duration (e.g., "1h2m3.456s")**. | [TimeDurations](/diff_test.go#:~:text=TestTimeDurations) | +| Unmarshaling a JSON number into a Go float beyond its representation **results in an error**. | Unmarshaling a JSON number into a Go float beyond its representation **uses the closest representable value (e.g., ±`math.MaxFloat`)**. | [MaxFloats](/diff_test.go#:~:text=TestMaxFloats) | +| A Go struct with only unexported fields **can be serialized**. | A Go struct with only unexported fields **cannot be serialized**. | [EmptyStructs](/diff_test.go#:~:text=TestEmptyStructs) | +| A Go struct that embeds an unexported struct type **can sometimes be serialized**. | A Go struct that embeds an unexported struct type **cannot be serialized**. | [EmbedUnexported](/diff_test.go#:~:text=TestEmbedUnexported) | + +See [diff_test.go](/diff_test.go) for details about every change. + +## Performance + +One of the goals of the v2 module is to be more performant than v1. + +Each of the charts below show the performance across +several different JSON implementations: + +* `JSONv1` is `encoding/json` at `v1.18.2` +* `JSONv2` is `github.com/go-json-experiment/json` at `v0.0.0-20220524042235-dd8be80fc4a7` +* `JSONIterator` is `github.com/json-iterator/go` at `v1.1.12` +* `SegmentJSON` is `github.com/segmentio/encoding/json` at `v0.3.5` +* `GoJSON` is `github.com/goccy/go-json` at `v0.9.7` +* `SonicJSON` is `github.com/bytedance/sonic` at `v1.3.0` + +Benchmarks were run across various datasets: + +* `CanadaGeometry` is a GeoJSON (RFC 7946) representation of Canada. + It contains many JSON arrays of arrays of two-element arrays of numbers. +* `CITMCatalog` contains many JSON objects using numeric names. +* `SyntheaFHIR` is sample JSON data from the healthcare industry. + It contains many nested JSON objects with mostly string values, + where the set of unique string values is relatively small. +* `TwitterStatus` is the JSON response from the Twitter API. + It contains a mix of all different JSON kinds, where string values + are a mix of both single-byte ASCII and multi-byte Unicode. +* `GolangSource` is a simple tree representing the Go source code. + It contains many nested JSON objects, each with the same schema. +* `StringUnicode` contains many strings with multi-byte Unicode runes. + +All of the implementations other than `JSONv1` and `JSONv2` make +extensive use of `unsafe`. As such, we expect those to generally be faster, +but at the cost of memory and type safety. `SonicJSON` goes a step even further +and uses just-in-time compilation to generate machine code specialized +for the Go type being marshaled or unmarshaled. +Also, `SonicJSON` does not validate JSON strings for valid UTF-8, +and so gains a notable performance boost on datasets with multi-byte Unicode. +Benchmarks are performed based on the default marshal and unmarshal behavior +of each package. Note that `JSONv2` aims to be safe and correct by default, +which may not be the most performant strategy. + +`JSONv2` has several semantic changes relative to `JSONv1` that +impacts performance: + +1. When marshaling, `JSONv2` no longer sorts the keys of a Go map. + This will improve performance. +2. When marshaling or unmarshaling, `JSONv2` always checks + to make sure JSON object names are unique. + This will hurt performance, but is more correct. +3. When marshaling or unmarshaling, `JSONv2` always + shallow copies the underlying value for a Go interface and + shallow copies the key and value for entries in a Go map. + This is done to keep the value as addressable so that `JSONv2` can + call methods and functions that operate on a pointer receiver. + This will hurt performance, but is more correct. + +All of the charts are unit-less since the values are normalized +relative to `JSONv1`, which is why `JSONv1` always has a value of 1. +A lower value is better (i.e., runs faster). + +Benchmarks were performed on an AMD Ryzen 9 5900X. + +The code for the benchmarks is located at +https://github.com/go-json-experiment/jsonbench. + +### Marshal Performance + +#### Concrete types + +![Benchmark Marshal Concrete](benchmark-marshal-concrete.png) + +* This compares marshal performance when serializing + [from concrete types](/testdata_test.go). +* The `JSONv1` implementation is close to optimal (without the use of `unsafe`). +* Relative to `JSONv1`, `JSONv2` is generally as fast or slightly faster. +* Relative to `JSONIterator`, `JSONv2` is up to 1.3x faster. +* Relative to `SegmentJSON`, `JSONv2` is up to 1.8x slower. +* Relative to `GoJSON`, `JSONv2` is up to 2.0x slower. +* Relative to `SonicJSON`, `JSONv2` is about 1.8x to 3.2x slower + (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). +* For `JSONv1` and `JSONv2`, marshaling from concrete types is + mostly limited by the performance of Go reflection. + +#### Interface types + +![Benchmark Marshal Interface](benchmark-marshal-interface.png) + +* This compares marshal performance when serializing from + `any`, `map[string]any`, and `[]any` types. +* Relative to `JSONv1`, `JSONv2` is about 1.5x to 4.2x faster. +* Relative to `JSONIterator`, `JSONv2` is about 1.1x to 2.4x faster. +* Relative to `SegmentJSON`, `JSONv2` is about 1.2x to 1.8x faster. +* Relative to `GoJSON`, `JSONv2` is about 1.1x to 2.5x faster. +* Relative to `SonicJSON`, `JSONv2` is up to 1.5x slower + (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). +* `JSONv2` is faster than the alternatives. + One advantange is because it does not sort the keys for a `map[string]any`, + while alternatives (except `SonicJSON` and `JSONIterator`) do sort the keys. + +#### RawValue types + +![Benchmark Marshal Rawvalue](benchmark-marshal-rawvalue.png) + +* This compares performance when marshaling from a `json.RawValue`. + This mostly exercises the underlying encoder and + hides the cost of Go reflection. +* Relative to `JSONv1`, `JSONv2` is about 3.5x to 7.8x faster. +* `JSONIterator` is blazingly fast because + [it does not validate whether the raw value is valid](https://go.dev/play/p/bun9IXQCKRe) + and simply copies it to the output. +* Relative to `SegmentJSON`, `JSONv2` is about 1.5x to 2.7x faster. +* Relative to `GoJSON`, `JSONv2` is up to 2.2x faster. +* Relative to `SonicJSON`, `JSONv2` is up to 1.5x faster. +* Aside from `JSONIterator`, `JSONv2` is generally the fastest. + +### Unmarshal Performance + +#### Concrete types + +![Benchmark Unmarshal Concrete](benchmark-unmarshal-concrete.png) + +* This compares unmarshal performance when deserializing + [into concrete types](/testdata_test.go). +* Relative to `JSONv1`, `JSONv2` is about 1.8x to 5.7x faster. +* Relative to `JSONIterator`, `JSONv2` is about 1.1x to 1.6x slower. +* Relative to `SegmentJSON`, `JSONv2` is up to 2.5x slower. +* Relative to `GoJSON`, `JSONv2` is about 1.4x to 2.1x slower. +* Relative to `SonicJSON`, `JSONv2` is up to 4.0x slower + (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). +* For `JSONv1` and `JSONv2`, unmarshaling into concrete types is + mostly limited by the performance of Go reflection. + +#### Interface types + +![Benchmark Unmarshal Interface](benchmark-unmarshal-interface.png) + +* This compares unmarshal performance when deserializing into + `any`, `map[string]any`, and `[]any` types. +* Relative to `JSONv1`, `JSONv2` is about 1.tx to 4.3x faster. +* Relative to `JSONIterator`, `JSONv2` is up to 1.5x faster. +* Relative to `SegmentJSON`, `JSONv2` is about 1.5 to 3.7x faster. +* Relative to `GoJSON`, `JSONv2` is up to 1.3x faster. +* Relative to `SonicJSON`, `JSONv2` is up to 1.5x slower + (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). +* Aside from `SonicJSON`, `JSONv2` is generally just as fast + or faster than all the alternatives. + +#### RawValue types + +![Benchmark Unmarshal Rawvalue](benchmark-unmarshal-rawvalue.png) + +* This compares performance when unmarshaling into a `json.RawValue`. + This mostly exercises the underlying decoder and + hides away most of the cost of Go reflection. +* Relative to `JSONv1`, `JSONv2` is about 8.3x to 17.0x faster. +* Relative to `JSONIterator`, `JSONv2` is up to 2.0x faster. +* Relative to `SegmentJSON`, `JSONv2` is up to 1.6x faster or 1.7x slower. +* Relative to `GoJSON`, `JSONv2` is up to 1.9x faster or 2.1x slower. +* Relative to `SonicJSON`, `JSONv2` is up to 2.0x faster + (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). +* `JSONv1` takes a + [lexical scanning approach](https://talks.golang.org/2011/lex.slide#1), + which performs a virtual function call for every byte of input. + In contrast, `JSONv2` makes heavy use of iterative and linear parsing logic + (with extra complexity to resume parsing when encountering segmented buffers). +* `JSONv2` is comparable to the alternatives that use `unsafe`. + Generally it is faster, but sometimes it is slower. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go new file mode 100644 index 00000000000..e6c6216ff32 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go @@ -0,0 +1,513 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "errors" + "io" + "reflect" + "sync" +) + +// MarshalOptions configures how Go data is serialized as JSON data. +// The zero value is equivalent to the default marshal settings. +type MarshalOptions struct { + requireKeyedLiterals + nonComparable + + // Marshalers is a list of type-specific marshalers to use. + Marshalers *Marshalers + + // StringifyNumbers specifies that numeric Go types should be serialized + // as a JSON string containing the equivalent JSON number value. + // + // According to RFC 8259, section 6, a JSON implementation may choose to + // limit the representation of a JSON number to an IEEE 754 binary64 value. + // This may cause decoders to lose precision for int64 and uint64 types. + // Escaping JSON numbers as a JSON string preserves the exact precision. + StringifyNumbers bool + + // DiscardUnknownMembers specifies that marshaling should ignore any + // JSON object members stored in Go struct fields dedicated to storing + // unknown JSON object members. + DiscardUnknownMembers bool + + // Deterministic specifies that the same input value will be serialized + // as the exact same output bytes. Different processes of + // the same program will serialize equal values to the same bytes, + // but different versions of the same program are not guaranteed + // to produce the exact same sequence of bytes. + Deterministic bool + + // formatDepth is the depth at which we respect the format flag. + formatDepth int + // format is custom formatting for the value at the specified depth. + format string +} + +// Marshal serializes a Go value as a []byte with default options. +// It is a thin wrapper over MarshalOptions.Marshal. +func Marshal(in any) (out []byte, err error) { + return MarshalOptions{}.Marshal(EncodeOptions{}, in) +} + +// MarshalFull serializes a Go value into an io.Writer with default options. +// It is a thin wrapper over MarshalOptions.MarshalFull. +func MarshalFull(out io.Writer, in any) error { + return MarshalOptions{}.MarshalFull(EncodeOptions{}, out, in) +} + +// Marshal serializes a Go value as a []byte according to the provided +// marshal and encode options. It does not terminate the output with a newline. +// See MarshalNext for details about the conversion of a Go value into JSON. +func (mo MarshalOptions) Marshal(eo EncodeOptions, in any) (out []byte, err error) { + enc := getBufferedEncoder(eo) + defer putBufferedEncoder(enc) + enc.options.omitTopLevelNewline = true + err = mo.MarshalNext(enc, in) + // TODO(https://go.dev/issue/45038): Use bytes.Clone. + return append([]byte(nil), enc.buf...), err +} + +// MarshalFull serializes a Go value into an io.Writer according to the provided +// marshal and encode options. It does not terminate the output with a newline. +// See MarshalNext for details about the conversion of a Go value into JSON. +func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) error { + enc := getStreamingEncoder(out, eo) + defer putStreamingEncoder(enc) + enc.options.omitTopLevelNewline = true + err := mo.MarshalNext(enc, in) + return err +} + +// MarshalNext encodes a Go value as the next JSON value according to +// the provided marshal options. +// +// Type-specific marshal functions and methods take precedence +// over the default representation of a value. +// Functions or methods that operate on *T are only called when encoding +// a value of type T (by taking its address) or a non-nil value of *T. +// MarshalNext ensures that a value is always addressable +// (by boxing it on the heap if necessary) so that +// these functions and methods can be consistently called. For performance, +// it is recommended that MarshalNext be passed a non-nil pointer to the value. +// +// The input value is encoded as JSON according the following rules: +// +// - If any type-specific functions in MarshalOptions.Marshalers match +// the value type, then those functions are called to encode the value. +// If all applicable functions return SkipFunc, +// then the value is encoded according to subsequent rules. +// +// - If the value type implements MarshalerV2, +// then the MarshalNextJSON method is called to encode the value. +// +// - If the value type implements MarshalerV1, +// then the MarshalJSON method is called to encode the value. +// +// - If the value type implements encoding.TextMarshaler, +// then the MarshalText method is called to encode the value and +// subsequently encode its result as a JSON string. +// +// - Otherwise, the value is encoded according to the value's type +// as described in detail below. +// +// Most Go types have a default JSON representation. +// Certain types support specialized formatting according to +// a format flag optionally specified in the Go struct tag +// for the struct field that contains the current value +// (see the “JSON Representation of Go structs” section for more details). +// +// The representation of each type is as follows: +// +// - A Go boolean is encoded as a JSON boolean (e.g., true or false). +// It does not support any custom format flags. +// +// - A Go string is encoded as a JSON string. +// It does not support any custom format flags. +// +// - A Go []byte or [N]byte is encoded as a JSON string containing +// the binary value encoded using RFC 4648. +// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. +// If the format is "base64url", then this uses RFC 4648, section 5. +// If the format is "base32", then this uses RFC 4648, section 6. +// If the format is "base32hex", then this uses RFC 4648, section 7. +// If the format is "base16" or "hex", then this uses RFC 4648, section 8. +// If the format is "array", then the bytes value is encoded as a JSON array +// where each byte is recursively JSON-encoded as each JSON array element. +// +// - A Go integer is encoded as a JSON number without fractions or exponents. +// If MarshalOptions.StringifyNumbers is specified, then the JSON number is +// encoded within a JSON string. It does not support any custom format +// flags. +// +// - A Go float is encoded as a JSON number. +// If MarshalOptions.StringifyNumbers is specified, +// then the JSON number is encoded within a JSON string. +// If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as +// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. +// Otherwise, the presence of non-finite numbers results in a SemanticError. +// +// - A Go map is encoded as a JSON object, where each Go map key and value +// is recursively encoded as a name and value pair in the JSON object. +// The Go map key must encode as a JSON string, otherwise this results +// in a SemanticError. When encoding keys, MarshalOptions.StringifyNumbers +// is automatically applied so that numeric keys encode as JSON strings. +// The Go map is traversed in a non-deterministic order. +// For deterministic encoding, consider using RawValue.Canonicalize. +// If the format is "emitnull", then a nil map is encoded as a JSON null. +// Otherwise by default, a nil map is encoded as an empty JSON object. +// +// - A Go struct is encoded as a JSON object. +// See the “JSON Representation of Go structs” section +// in the package-level documentation for more details. +// +// - A Go slice is encoded as a JSON array, where each Go slice element +// is recursively JSON-encoded as the elements of the JSON array. +// If the format is "emitnull", then a nil slice is encoded as a JSON null. +// Otherwise by default, a nil slice is encoded as an empty JSON array. +// +// - A Go array is encoded as a JSON array, where each Go array element +// is recursively JSON-encoded as the elements of the JSON array. +// The JSON array length is always identical to the Go array length. +// It does not support any custom format flags. +// +// - A Go pointer is encoded as a JSON null if nil, otherwise it is +// the recursively JSON-encoded representation of the underlying value. +// Format flags are forwarded to the encoding of the underlying value. +// +// - A Go interface is encoded as a JSON null if nil, otherwise it is +// the recursively JSON-encoded representation of the underlying value. +// It does not support any custom format flags. +// +// - A Go time.Time is encoded as a JSON string containing the timestamp +// formatted in RFC 3339 with nanosecond resolution. +// If the format matches one of the format constants declared +// in the time package (e.g., RFC1123), then that format is used. +// Otherwise, the format is used as-is with time.Time.Format if non-empty. +// +// - A Go time.Duration is encoded as a JSON string containing the duration +// formatted according to time.Duration.String. +// If the format is "nanos", it is encoded as a JSON number +// containing the number of nanoseconds in the duration. +// +// - All other Go types (e.g., complex numbers, channels, and functions) +// have no default representation and result in a SemanticError. +// +// JSON cannot represent cyclic data structures and +// MarshalNext does not handle them. +// Passing cyclic structures will result in an error. +func (mo MarshalOptions) MarshalNext(out *Encoder, in any) error { + v := reflect.ValueOf(in) + if !v.IsValid() || (v.Kind() == reflect.Pointer && v.IsNil()) { + return out.WriteToken(Null) + } + // Shallow copy non-pointer values to obtain an addressable value. + // It is beneficial to performance to always pass pointers to avoid this. + if v.Kind() != reflect.Pointer { + v2 := reflect.New(v.Type()) + v2.Elem().Set(v) + v = v2 + } + va := addressableValue{v.Elem()} // dereferenced pointer is always addressable + t := va.Type() + + // Lookup and call the marshal function for this type. + marshal := lookupArshaler(t).marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, t) + } + if err := marshal(mo, out, va); err != nil { + if !out.options.AllowDuplicateNames { + out.tokens.invalidateDisabledNamespaces() + } + return err + } + return nil +} + +// UnmarshalOptions configures how JSON data is deserialized as Go data. +// The zero value is equivalent to the default unmarshal settings. +type UnmarshalOptions struct { + requireKeyedLiterals + nonComparable + + // Unmarshalers is a list of type-specific unmarshalers to use. + Unmarshalers *Unmarshalers + + // StringifyNumbers specifies that numeric Go types can be deserialized + // from either a JSON number or a JSON string containing a JSON number + // without any surrounding whitespace. + StringifyNumbers bool + + // RejectUnknownMembers specifies that unknown members should be rejected + // when unmarshaling a JSON object, regardless of whether there is a field + // to store unknown members. + RejectUnknownMembers bool + + // formatDepth is the depth at which we respect the format flag. + formatDepth int + // format is custom formatting for the value at the specified depth. + format string +} + +// Unmarshal deserializes a Go value from a []byte with default options. +// It is a thin wrapper over UnmarshalOptions.Unmarshal. +func Unmarshal(in []byte, out any) error { + return UnmarshalOptions{}.Unmarshal(DecodeOptions{}, in, out) +} + +// UnmarshalFull deserializes a Go value from an io.Reader with default options. +// It is a thin wrapper over UnmarshalOptions.UnmarshalFull. +func UnmarshalFull(in io.Reader, out any) error { + return UnmarshalOptions{}.UnmarshalFull(DecodeOptions{}, in, out) +} + +// Unmarshal deserializes a Go value from a []byte according to the +// provided unmarshal and decode options. The output must be a non-nil pointer. +// The input must be a single JSON value with optional whitespace interspersed. +// See UnmarshalNext for details about the conversion of JSON into a Go value. +func (uo UnmarshalOptions) Unmarshal(do DecodeOptions, in []byte, out any) error { + dec := getBufferedDecoder(in, do) + defer putBufferedDecoder(dec) + return uo.unmarshalFull(dec, out) +} + +// UnmarshalFull deserializes a Go value from an io.Reader according to the +// provided unmarshal and decode options. The output must be a non-nil pointer. +// The input must be a single JSON value with optional whitespace interspersed. +// It consumes the entirety of io.Reader until io.EOF is encountered. +// See UnmarshalNext for details about the conversion of JSON into a Go value. +func (uo UnmarshalOptions) UnmarshalFull(do DecodeOptions, in io.Reader, out any) error { + dec := getStreamingDecoder(in, do) + defer putStreamingDecoder(dec) + return uo.unmarshalFull(dec, out) +} +func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { + switch err := uo.UnmarshalNext(in, out); err { + case nil: + return in.checkEOF() + case io.EOF: + return io.ErrUnexpectedEOF + default: + return err + } +} + +// UnmarshalNext decodes the next JSON value into a Go value according to +// the provided unmarshal options. The output must be a non-nil pointer. +// +// Type-specific unmarshal functions and methods take precedence +// over the default representation of a value. +// Functions or methods that operate on *T are only called when decoding +// a value of type T (by taking its address) or a non-nil value of *T. +// UnmarshalNext ensures that a value is always addressable +// (by boxing it on the heap if necessary) so that +// these functions and methods can be consistently called. +// +// The input is decoded into the output according the following rules: +// +// - If any type-specific functions in UnmarshalOptions.Unmarshalers match +// the value type, then those functions are called to decode the JSON +// value. If all applicable functions return SkipFunc, +// then the input is decoded according to subsequent rules. +// +// - If the value type implements UnmarshalerV2, +// then the UnmarshalNextJSON method is called to decode the JSON value. +// +// - If the value type implements UnmarshalerV1, +// then the UnmarshalJSON method is called to decode the JSON value. +// +// - If the value type implements encoding.TextUnmarshaler, +// then the input is decoded as a JSON string and +// the UnmarshalText method is called with the decoded string value. +// This fails with a SemanticError if the input is not a JSON string. +// +// - Otherwise, the JSON value is decoded according to the value's type +// as described in detail below. +// +// Most Go types have a default JSON representation. +// Certain types support specialized formatting according to +// a format flag optionally specified in the Go struct tag +// for the struct field that contains the current value +// (see the “JSON Representation of Go structs” section for more details). +// A JSON null may be decoded into every supported Go value where +// it is equivalent to storing the zero value of the Go value. +// If the input JSON kind is not handled by the current Go value type, +// then this fails with a SemanticError. Unless otherwise specified, +// the decoded value replaces any pre-existing value. +// +// The representation of each type is as follows: +// +// - A Go boolean is decoded from a JSON boolean (e.g., true or false). +// It does not support any custom format flags. +// +// - A Go string is decoded from a JSON string. +// It does not support any custom format flags. +// +// - A Go []byte or [N]byte is decoded from a JSON string +// containing the binary value encoded using RFC 4648. +// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. +// If the format is "base64url", then this uses RFC 4648, section 5. +// If the format is "base32", then this uses RFC 4648, section 6. +// If the format is "base32hex", then this uses RFC 4648, section 7. +// If the format is "base16" or "hex", then this uses RFC 4648, section 8. +// If the format is "array", then the Go slice or array is decoded from a +// JSON array where each JSON element is recursively decoded for each byte. +// When decoding into a non-nil []byte, the slice length is reset to zero +// and the decoded input is appended to it. +// When decoding into a [N]byte, the input must decode to exactly N bytes, +// otherwise it fails with a SemanticError. +// +// - A Go integer is decoded from a JSON number. +// It may also be decoded from a JSON string containing a JSON number +// if UnmarshalOptions.StringifyNumbers is specified. +// It fails with a SemanticError if the JSON number +// has a fractional or exponent component. +// It also fails if it overflows the representation of the Go integer type. +// It does not support any custom format flags. +// +// - A Go float is decoded from a JSON number. +// It may also be decoded from a JSON string containing a JSON number +// if UnmarshalOptions.StringifyNumbers is specified. +// The JSON number is parsed as the closest representable Go float value. +// If the format is "nonfinite", then the JSON strings +// "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. +// Otherwise, the presence of such strings results in a SemanticError. +// +// - A Go map is decoded from a JSON object, +// where each JSON object name and value pair is recursively decoded +// as the Go map key and value. When decoding keys, +// UnmarshalOptions.StringifyNumbers is automatically applied so that +// numeric keys can decode from JSON strings. Maps are not cleared. +// If the Go map is nil, then a new map is allocated to decode into. +// If the decoded key matches an existing Go map entry, the entry value +// is reused by decoding the JSON object value into it. +// The only supported format is "emitnull" and has no effect when decoding. +// +// - A Go struct is decoded from a JSON object. +// See the “JSON Representation of Go structs” section +// in the package-level documentation for more details. +// +// - A Go slice is decoded from a JSON array, where each JSON element +// is recursively decoded and appended to the Go slice. +// Before appending into a Go slice, a new slice is allocated if it is nil, +// otherwise the slice length is reset to zero. +// The only supported format is "emitnull" and has no effect when decoding. +// +// - A Go array is decoded from a JSON array, where each JSON array element +// is recursively decoded as each corresponding Go array element. +// Each Go array element is zeroed before decoding into it. +// It fails with a SemanticError if the JSON array does not contain +// the exact same number of elements as the Go array. +// It does not support any custom format flags. +// +// - A Go pointer is decoded based on the JSON kind and underlying Go type. +// If the input is a JSON null, then this stores a nil pointer. +// Otherwise, it allocates a new underlying value if the pointer is nil, +// and recursively JSON decodes into the underlying value. +// Format flags are forwarded to the decoding of the underlying type. +// +// - A Go interface is decoded based on the JSON kind and underlying Go type. +// If the input is a JSON null, then this stores a nil interface value. +// Otherwise, a nil interface value of an empty interface type is initialized +// with a zero Go bool, string, float64, map[string]any, or []any if the +// input is a JSON boolean, string, number, object, or array, respectively. +// If the interface value is still nil, then this fails with a SemanticError +// since decoding could not determine an appropriate Go type to decode into. +// For example, unmarshaling into a nil io.Reader fails since +// there is no concrete type to populate the interface value with. +// Otherwise an underlying value exists and it recursively decodes +// the JSON input into it. It does not support any custom format flags. +// +// - A Go time.Time is decoded from a JSON string containing the time +// formatted in RFC 3339 with nanosecond resolution. +// If the format matches one of the format constants declared in +// the time package (e.g., RFC1123), then that format is used for parsing. +// Otherwise, the format is used as-is with time.Time.Parse if non-empty. +// +// - A Go time.Duration is decoded from a JSON string by +// passing the decoded string to time.ParseDuration. +// If the format is "nanos", it is instead decoded from a JSON number +// containing the number of nanoseconds in the duration. +// +// - All other Go types (e.g., complex numbers, channels, and functions) +// have no default representation and result in a SemanticError. +// +// In general, unmarshaling follows merge semantics (similar to RFC 7396) +// where the decoded Go value replaces the destination value +// for any JSON kind other than an object. +// For JSON objects, the input object is merged into the destination value +// where matching object members recursively apply merge semantics. +func (uo UnmarshalOptions) UnmarshalNext(in *Decoder, out any) error { + v := reflect.ValueOf(out) + if !v.IsValid() || v.Kind() != reflect.Pointer || v.IsNil() { + var t reflect.Type + if v.IsValid() { + t = v.Type() + if t.Kind() == reflect.Pointer { + t = t.Elem() + } + } + err := errors.New("value must be passed as a non-nil pointer reference") + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + va := addressableValue{v.Elem()} // dereferenced pointer is always addressable + t := va.Type() + + // Lookup and call the unmarshal function for this type. + unmarshal := lookupArshaler(t).unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t) + } + if err := unmarshal(uo, in, va); err != nil { + if !in.options.AllowDuplicateNames { + in.tokens.invalidateDisabledNamespaces() + } + return err + } + return nil +} + +// addressableValue is a reflect.Value that is guaranteed to be addressable +// such that calling the Addr and Set methods do not panic. +// +// There is no compile magic that enforces this property, +// but rather the need to construct this type makes it easier to examine each +// construction site to ensure that this property is upheld. +type addressableValue struct{ reflect.Value } + +// newAddressableValue constructs a new addressable value of type t. +func newAddressableValue(t reflect.Type) addressableValue { + return addressableValue{reflect.New(t).Elem()} +} + +// All marshal and unmarshal behavior is implemented using these signatures. +type ( + marshaler = func(MarshalOptions, *Encoder, addressableValue) error + unmarshaler = func(UnmarshalOptions, *Decoder, addressableValue) error +) + +type arshaler struct { + marshal marshaler + unmarshal unmarshaler + nonDefault bool +} + +var lookupArshalerCache sync.Map // map[reflect.Type]*arshaler + +func lookupArshaler(t reflect.Type) *arshaler { + if v, ok := lookupArshalerCache.Load(t); ok { + return v.(*arshaler) + } + + fncs := makeDefaultArshaler(t) + fncs = makeMethodArshaler(fncs, t) + fncs = makeTimeArshaler(fncs, t) + + // Use the last stored so that duplicate arshalers can be garbage collected. + v, _ := lookupArshalerCache.LoadOrStore(t, fncs) + return v.(*arshaler) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go new file mode 100644 index 00000000000..c62b1f32035 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go @@ -0,0 +1,238 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import "reflect" + +// This files contains an optimized marshal and unmarshal implementation +// for the any type. This type is often used when the Go program has +// no knowledge of the JSON schema. This is a common enough occurrence +// to justify the complexity of adding logic for this. + +func marshalValueAny(mo MarshalOptions, enc *Encoder, val any) error { + switch val := val.(type) { + case nil: + return enc.WriteToken(Null) + case bool: + return enc.WriteToken(Bool(val)) + case string: + return enc.WriteToken(String(val)) + case float64: + return enc.WriteToken(Float(val)) + case map[string]any: + return marshalObjectAny(mo, enc, val) + case []any: + return marshalArrayAny(mo, enc, val) + default: + v := newAddressableValue(reflect.TypeOf(val)) + v.Set(reflect.ValueOf(val)) + marshal := lookupArshaler(v.Type()).marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, v.Type()) + } + return marshal(mo, enc, v) + } +} + +func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { + switch k := dec.PeekKind(); k { + case '{': + return unmarshalObjectAny(uo, dec) + case '[': + return unmarshalArrayAny(uo, dec) + default: + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return nil, err + } + switch val.Kind() { + case 'n': + return nil, nil + case 'f': + return false, nil + case 't': + return true, nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + if dec.stringCache == nil { + dec.stringCache = new(stringCache) + } + return dec.stringCache.make(val), nil + case '0': + fv, _ := parseFloat(val, 64) // ignore error since readValue guarantees val is valid + return fv, nil + default: + panic("BUG: invalid kind: " + k.String()) + } + } +} + +func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error { + // Check for cycles. + if enc.tokens.depth() > startDetectingCyclesAfter { + v := reflect.ValueOf(obj) + if err := enc.seenPointers.visit(v); err != nil { + return err + } + defer enc.seenPointers.leave(v) + } + + // Optimize for marshaling an empty map without any preceding whitespace. + if len(obj) == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '{') + enc.buf = append(enc.buf, "{}"...) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + if err := enc.WriteToken(ObjectStart); err != nil { + return err + } + // A Go map guarantees that each entry has a unique key + // The only possibility of duplicates is due to invalid UTF-8. + if !enc.options.AllowInvalidUTF8 { + enc.tokens.last.disableNamespace() + } + if !mo.Deterministic || len(obj) <= 1 { + for name, val := range obj { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, val); err != nil { + return err + } + } + } else { + names := getStrings(len(obj)) + var i int + for name := range obj { + (*names)[i] = name + i++ + } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, obj[name]); err != nil { + return err + } + } + putStrings(names) + } + if err := enc.WriteToken(ObjectEnd); err != nil { + return err + } + return nil +} + +func unmarshalObjectAny(uo UnmarshalOptions, dec *Decoder) (map[string]any, error) { + tok, err := dec.ReadToken() + if err != nil { + return nil, err + } + k := tok.Kind() + switch k { + case 'n': + return nil, nil + case '{': + obj := make(map[string]any) + // A Go map guarantees that each entry has a unique key + // The only possibility of duplicates is due to invalid UTF-8. + if !dec.options.AllowInvalidUTF8 { + dec.tokens.last.disableNamespace() + } + for dec.PeekKind() != '}' { + tok, err := dec.ReadToken() + if err != nil { + return obj, err + } + name := tok.String() + + // Manually check for duplicate names. + if _, ok := obj[name]; ok { + name := dec.previousBuffer() + err := &SyntacticError{str: "duplicate name " + string(name) + " in object"} + return obj, err.withOffset(dec.InputOffset() - int64(len(name))) + } + + val, err := unmarshalValueAny(uo, dec) + obj[name] = val + if err != nil { + return obj, err + } + } + if _, err := dec.ReadToken(); err != nil { + return obj, err + } + return obj, nil + } + return nil, &SemanticError{action: "unmarshal", JSONKind: k, GoType: mapStringAnyType} +} + +func marshalArrayAny(mo MarshalOptions, enc *Encoder, arr []any) error { + // Check for cycles. + if enc.tokens.depth() > startDetectingCyclesAfter { + v := reflect.ValueOf(arr) + if err := enc.seenPointers.visit(v); err != nil { + return err + } + defer enc.seenPointers.leave(v) + } + + // Optimize for marshaling an empty slice without any preceding whitespace. + if len(arr) == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '[') + enc.buf = append(enc.buf, "[]"...) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + if err := enc.WriteToken(ArrayStart); err != nil { + return err + } + for _, val := range arr { + if err := marshalValueAny(mo, enc, val); err != nil { + return err + } + } + if err := enc.WriteToken(ArrayEnd); err != nil { + return err + } + return nil +} + +func unmarshalArrayAny(uo UnmarshalOptions, dec *Decoder) ([]any, error) { + tok, err := dec.ReadToken() + if err != nil { + return nil, err + } + k := tok.Kind() + switch k { + case 'n': + return nil, nil + case '[': + arr := []any{} + for dec.PeekKind() != ']' { + val, err := unmarshalValueAny(uo, dec) + arr = append(arr, val) + if err != nil { + return arr, err + } + } + if _, err := dec.ReadToken(); err != nil { + return arr, err + } + return arr, nil + } + return nil, &SemanticError{action: "unmarshal", JSONKind: k, GoType: sliceAnyType} +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go new file mode 100644 index 00000000000..fd26eba3528 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go @@ -0,0 +1,1485 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "encoding/base32" + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "sync" +) + +// optimizeCommon specifies whether to use optimizations targeted for certain +// common patterns, rather than using the slower, but more general logic. +// All tests should pass regardless of whether this is true or not. +const optimizeCommon = true + +var ( + // Most natural Go type that correspond with each JSON type. + anyType = reflect.TypeOf((*any)(nil)).Elem() // JSON value + boolType = reflect.TypeOf((*bool)(nil)).Elem() // JSON bool + stringType = reflect.TypeOf((*string)(nil)).Elem() // JSON string + float64Type = reflect.TypeOf((*float64)(nil)).Elem() // JSON number + mapStringAnyType = reflect.TypeOf((*map[string]any)(nil)).Elem() // JSON object + sliceAnyType = reflect.TypeOf((*[]any)(nil)).Elem() // JSON array + + bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() + emptyStructType = reflect.TypeOf((*struct{})(nil)).Elem() +) + +const startDetectingCyclesAfter = 1000 + +type seenPointers map[typedPointer]struct{} + +type typedPointer struct { + typ reflect.Type + ptr any // always stores unsafe.Pointer, but avoids depending on unsafe +} + +// visit visits pointer p of type t, reporting an error if seen before. +// If successfully visited, then the caller must eventually call leave. +func (m *seenPointers) visit(v reflect.Value) error { + p := typedPointer{v.Type(), v.UnsafePointer()} + if _, ok := (*m)[p]; ok { + return &SemanticError{action: "marshal", GoType: p.typ, Err: errors.New("encountered a cycle")} + } + if *m == nil { + *m = make(map[typedPointer]struct{}) + } + (*m)[p] = struct{}{} + return nil +} +func (m *seenPointers) leave(v reflect.Value) { + p := typedPointer{v.Type(), v.UnsafePointer()} + delete(*m, p) +} + +func makeDefaultArshaler(t reflect.Type) *arshaler { + switch t.Kind() { + case reflect.Bool: + return makeBoolArshaler(t) + case reflect.String: + return makeStringArshaler(t) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return makeIntArshaler(t) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return makeUintArshaler(t) + case reflect.Float32, reflect.Float64: + return makeFloatArshaler(t) + case reflect.Map: + return makeMapArshaler(t) + case reflect.Struct: + return makeStructArshaler(t) + case reflect.Slice: + fncs := makeSliceArshaler(t) + if t.AssignableTo(bytesType) { + return makeBytesArshaler(t, fncs) + } + return fncs + case reflect.Array: + fncs := makeArrayArshaler(t) + if reflect.SliceOf(t.Elem()).AssignableTo(bytesType) { + return makeBytesArshaler(t, fncs) + } + return fncs + case reflect.Pointer: + return makePointerArshaler(t) + case reflect.Interface: + return makeInterfaceArshaler(t) + default: + return makeInvalidArshaler(t) + } +} + +func makeBoolArshaler(t reflect.Type) *arshaler { + var fncs arshaler + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + + // Optimize for marshaling without preceding whitespace. + if optimizeCommon && !enc.options.multiline && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, 't') + if va.Bool() { + enc.buf = append(enc.buf, "true"...) + } else { + enc.buf = append(enc.buf, "false"...) + } + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + return enc.WriteToken(Bool(va.Bool())) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + tok, err := dec.ReadToken() + if err != nil { + return err + } + k := tok.Kind() + switch k { + case 'n': + va.SetBool(false) + return nil + case 't', 'f': + va.SetBool(tok.Bool()) + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makeStringArshaler(t reflect.Type) *arshaler { + var fncs arshaler + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + return enc.WriteToken(String(va.String())) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + va.SetString("") + return nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + if dec.stringCache == nil { + dec.stringCache = new(stringCache) + } + str := dec.stringCache.make(val) + va.SetString(str) + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +var ( + encodeBase16 = func(dst, src []byte) { hex.Encode(dst, src) } + encodeBase32 = base32.StdEncoding.Encode + encodeBase32Hex = base32.HexEncoding.Encode + encodeBase64 = base64.StdEncoding.Encode + encodeBase64URL = base64.URLEncoding.Encode + encodedLenBase16 = hex.EncodedLen + encodedLenBase32 = base32.StdEncoding.EncodedLen + encodedLenBase32Hex = base32.HexEncoding.EncodedLen + encodedLenBase64 = base64.StdEncoding.EncodedLen + encodedLenBase64URL = base64.URLEncoding.EncodedLen + decodeBase16 = hex.Decode + decodeBase32 = base32.StdEncoding.Decode + decodeBase32Hex = base32.HexEncoding.Decode + decodeBase64 = base64.StdEncoding.Decode + decodeBase64URL = base64.URLEncoding.Decode + decodedLenBase16 = hex.DecodedLen + decodedLenBase32 = base32.StdEncoding.WithPadding(base32.NoPadding).DecodedLen + decodedLenBase32Hex = base32.HexEncoding.WithPadding(base32.NoPadding).DecodedLen + decodedLenBase64 = base64.StdEncoding.WithPadding(base64.NoPadding).DecodedLen + decodedLenBase64URL = base64.URLEncoding.WithPadding(base64.NoPadding).DecodedLen +) + +func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { + // NOTE: This handles both []byte and [N]byte. + marshalDefault := fncs.marshal + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + encode, encodedLen := encodeBase64, encodedLenBase64 + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + switch mo.format { + case "base64": + encode, encodedLen = encodeBase64, encodedLenBase64 + case "base64url": + encode, encodedLen = encodeBase64URL, encodedLenBase64URL + case "base32": + encode, encodedLen = encodeBase32, encodedLenBase32 + case "base32hex": + encode, encodedLen = encodeBase32Hex, encodedLenBase32Hex + case "base16", "hex": + encode, encodedLen = encodeBase16, encodedLenBase16 + case "array": + mo.format = "" + return marshalDefault(mo, enc, va) + default: + return newInvalidFormatError("marshal", t, mo.format) + } + } + val := enc.UnusedBuffer() + b := va.Bytes() + n := len(`"`) + encodedLen(len(b)) + len(`"`) + if cap(val) < n { + val = make([]byte, n) + } else { + val = val[:n] + } + val[0] = '"' + encode(val[len(`"`):len(val)-len(`"`)], b) + val[len(val)-1] = '"' + return enc.WriteValue(val) + } + unmarshalDefault := fncs.unmarshal + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + decode, decodedLen, encodedLen := decodeBase64, decodedLenBase64, encodedLenBase64 + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + switch uo.format { + case "base64": + decode, decodedLen, encodedLen = decodeBase64, decodedLenBase64, encodedLenBase64 + case "base64url": + decode, decodedLen, encodedLen = decodeBase64URL, decodedLenBase64URL, encodedLenBase64URL + case "base32": + decode, decodedLen, encodedLen = decodeBase32, decodedLenBase32, encodedLenBase32 + case "base32hex": + decode, decodedLen, encodedLen = decodeBase32Hex, decodedLenBase32Hex, encodedLenBase32Hex + case "base16", "hex": + decode, decodedLen, encodedLen = decodeBase16, decodedLenBase16, encodedLenBase16 + case "array": + uo.format = "" + return unmarshalDefault(uo, dec, va) + default: + return newInvalidFormatError("unmarshal", t, uo.format) + } + } + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + va.Set(reflect.Zero(t)) + return nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + + // For base64 and base32, decodedLen computes the maximum output size + // when given the original input size. To compute the exact size, + // adjust the input size by excluding trailing padding characters. + // This is unnecessary for base16, but also harmless. + n := len(val) + for n > 0 && val[n-1] == '=' { + n-- + } + n = decodedLen(n) + b := va.Bytes() + if va.Kind() == reflect.Array { + if n != len(b) { + err := fmt.Errorf("decoded base64 length of %d mismatches array length of %d", n, len(b)) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + } else { + if b == nil || cap(b) < n { + b = make([]byte, n) + } else { + b = b[:n] + } + } + n2, err := decode(b, val) + if err == nil && len(val) != encodedLen(n2) { + // TODO(https://go.dev/issue/53845): RFC 4648, section 3.3, + // specifies that non-alphabet characters must be rejected. + // Unfortunately, the "base32" and "base64" packages allow + // '\r' and '\n' characters by default. + err = errors.New("illegal data at input byte " + strconv.Itoa(bytes.IndexAny(val, "\r\n"))) + } + if err != nil { + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + if va.Kind() == reflect.Slice { + va.SetBytes(b) + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return fncs +} + +func makeIntArshaler(t reflect.Type) *arshaler { + var fncs arshaler + bits := t.Bits() + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + + // Optimize for marshaling without preceding whitespace or string escaping. + if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') + enc.buf = strconv.AppendInt(enc.buf, va.Int(), 10) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + x := math.Float64frombits(uint64(va.Int())) + return enc.writeNumber(x, rawIntNumber, mo.StringifyNumbers) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + va.SetInt(0) + return nil + case '"': + if !uo.StringifyNumbers { + break + } + val = unescapeStringMayCopy(val, flags.isVerbatim()) + fallthrough + case '0': + var negOffset int + neg := val[0] == '-' + if neg { + negOffset = 1 + } + n, ok := parseDecUint(val[negOffset:]) + maxInt := uint64(1) << (bits - 1) + overflow := (neg && n > maxInt) || (!neg && n > maxInt-1) + if !ok { + if n != math.MaxUint64 { + err := fmt.Errorf("cannot parse %q as signed integer: %w", val, strconv.ErrSyntax) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + overflow = true + } + if overflow { + err := fmt.Errorf("cannot parse %q as signed integer: %w", val, strconv.ErrRange) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + if neg { + va.SetInt(int64(-n)) + } else { + va.SetInt(int64(+n)) + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makeUintArshaler(t reflect.Type) *arshaler { + var fncs arshaler + bits := t.Bits() + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + + // Optimize for marshaling without preceding whitespace or string escaping. + if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') + enc.buf = strconv.AppendUint(enc.buf, va.Uint(), 10) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + x := math.Float64frombits(va.Uint()) + return enc.writeNumber(x, rawUintNumber, mo.StringifyNumbers) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + va.SetUint(0) + return nil + case '"': + if !uo.StringifyNumbers { + break + } + val = unescapeStringMayCopy(val, flags.isVerbatim()) + fallthrough + case '0': + n, ok := parseDecUint(val) + maxUint := uint64(1) << bits + overflow := n > maxUint-1 + if !ok { + if n != math.MaxUint64 { + err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrSyntax) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + overflow = true + } + if overflow { + err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrRange) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + va.SetUint(n) + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makeFloatArshaler(t reflect.Type) *arshaler { + var fncs arshaler + bits := t.Bits() + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + var allowNonFinite bool + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + if mo.format == "nonfinite" { + allowNonFinite = true + } else { + return newInvalidFormatError("marshal", t, mo.format) + } + } + + fv := va.Float() + if math.IsNaN(fv) || math.IsInf(fv, 0) { + if !allowNonFinite { + err := fmt.Errorf("invalid value: %v", fv) + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return enc.WriteToken(Float(fv)) + } + + // Optimize for marshaling without preceding whitespace or string escaping. + if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') + enc.buf = appendNumber(enc.buf, fv, bits) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + return enc.writeNumber(fv, bits, mo.StringifyNumbers) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + var allowNonFinite bool + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + if uo.format == "nonfinite" { + allowNonFinite = true + } else { + return newInvalidFormatError("unmarshal", t, uo.format) + } + } + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + va.SetFloat(0) + return nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + if allowNonFinite { + switch string(val) { + case "NaN": + va.SetFloat(math.NaN()) + return nil + case "Infinity": + va.SetFloat(math.Inf(+1)) + return nil + case "-Infinity": + va.SetFloat(math.Inf(-1)) + return nil + } + } + if !uo.StringifyNumbers { + break + } + if n, err := consumeNumber(val); n != len(val) || err != nil { + err := fmt.Errorf("cannot parse %q as JSON number: %w", val, strconv.ErrSyntax) + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + fallthrough + case '0': + // NOTE: Floating-point parsing is by nature a lossy operation. + // We never report an overflow condition since we can always + // round the input to the closest representable finite value. + // For extremely large numbers, the closest value is ±MaxFloat. + fv, _ := parseFloat(val, bits) + va.SetFloat(fv) + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makeMapArshaler(t reflect.Type) *arshaler { + // NOTE: The logic below disables namespaces for tracking duplicate names + // when handling map keys with a unique representation. + + // NOTE: Values retrieved from a map are not addressable, + // so we shallow copy the values to make them addressable and + // store them back into the map afterwards. + + var fncs arshaler + var ( + once sync.Once + keyFncs *arshaler + valFncs *arshaler + ) + init := func() { + keyFncs = lookupArshaler(t.Key()) + valFncs = lookupArshaler(t.Elem()) + } + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + // Check for cycles. + if enc.tokens.depth() > startDetectingCyclesAfter { + if err := enc.seenPointers.visit(va.Value); err != nil { + return err + } + defer enc.seenPointers.leave(va.Value) + } + + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + if mo.format == "emitnull" { + if va.IsNil() { + return enc.WriteToken(Null) + } + mo.format = "" + } else { + return newInvalidFormatError("marshal", t, mo.format) + } + } + + // Optimize for marshaling an empty map without any preceding whitespace. + n := va.Len() + if optimizeCommon && n == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '{') + enc.buf = append(enc.buf, "{}"...) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + once.Do(init) + if err := enc.WriteToken(ObjectStart); err != nil { + return err + } + if n > 0 { + // Handle maps with numeric key types by stringifying them. + mko := mo + mko.StringifyNumbers = true + + nonDefaultKey := keyFncs.nonDefault + marshalKey := keyFncs.marshal + marshalVal := valFncs.marshal + if mo.Marshalers != nil { + var ok bool + marshalKey, ok = mo.Marshalers.lookup(marshalKey, t.Key()) + marshalVal, _ = mo.Marshalers.lookup(marshalVal, t.Elem()) + nonDefaultKey = nonDefaultKey || ok + } + k := newAddressableValue(t.Key()) + v := newAddressableValue(t.Elem()) + + // A Go map guarantees that each entry has a unique key. + // As such, disable the expensive duplicate name check if we know + // that every Go key will serialize as a unique JSON string. + if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), enc.options.AllowInvalidUTF8) { + enc.tokens.last.disableNamespace() + } + + switch { + case !mo.Deterministic || n <= 1: + for iter := va.Value.MapRange(); iter.Next(); { + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + v.SetIterValue(iter) + if err := marshalVal(mo, enc, v); err != nil { + return err + } + } + case !nonDefaultKey && t.Key().Kind() == reflect.String: + names := getStrings(n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + k.SetIterKey(iter) + (*names)[i] = k.String() + } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + k.SetString(name) + v.Set(va.MapIndex(k.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } + } + putStrings(names) + default: + type member struct { + name string // unquoted name + key addressableValue + } + members := make([]member, n) + keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + // Marshal the member name. + k := addressableValue{keys.Index(i)} // indexed slice element is always addressable + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + name := enc.unwriteOnlyObjectMemberName() + members[i] = member{name, k} + } + // TODO: If AllowDuplicateNames is enabled, then sort according + // to reflect.Value as well if the names are equal. + // See internal/fmtsort. + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Slice(members, func(i, j int) bool { + return lessUTF16(members[i].name, members[j].name) + }) + for _, member := range members { + if err := enc.WriteToken(String(member.name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + v.Set(va.MapIndex(member.key.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } + } + } + } + if err := enc.WriteToken(ObjectEnd); err != nil { + return err + } + return nil + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + if uo.format == "emitnull" { + uo.format = "" // only relevant for marshaling + } else { + return newInvalidFormatError("unmarshal", t, uo.format) + } + } + tok, err := dec.ReadToken() + if err != nil { + return err + } + k := tok.Kind() + switch k { + case 'n': + va.Set(reflect.Zero(t)) + return nil + case '{': + once.Do(init) + if va.IsNil() { + va.Set(reflect.MakeMap(t)) + } + + // Handle maps with numeric key types by stringifying them. + uko := uo + uko.StringifyNumbers = true + + nonDefaultKey := keyFncs.nonDefault + unmarshalKey := keyFncs.unmarshal + unmarshalVal := valFncs.unmarshal + if uo.Unmarshalers != nil { + var ok bool + unmarshalKey, ok = uo.Unmarshalers.lookup(unmarshalKey, t.Key()) + unmarshalVal, _ = uo.Unmarshalers.lookup(unmarshalVal, t.Elem()) + nonDefaultKey = nonDefaultKey || ok + } + k := newAddressableValue(t.Key()) + v := newAddressableValue(t.Elem()) + + // Manually check for duplicate entries by virtue of whether the + // unmarshaled key already exists in the destination Go map. + // Consequently, syntactically different names (e.g., "0" and "-0") + // will be rejected as duplicates since they semantically refer + // to the same Go value. This is an unusual interaction + // between syntax and semantics, but is more correct. + if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), dec.options.AllowInvalidUTF8) { + dec.tokens.last.disableNamespace() + } + + // In the rare case where the map is not already empty, + // then we need to manually track which keys we already saw + // since existing presence alone is insufficient to indicate + // whether the input had a duplicate name. + var seen reflect.Value + if !dec.options.AllowDuplicateNames && va.Len() > 0 { + seen = reflect.MakeMap(reflect.MapOf(k.Type(), emptyStructType)) + } + + for dec.PeekKind() != '}' { + k.Set(reflect.Zero(t.Key())) + if err := unmarshalKey(uko, dec, k); err != nil { + return err + } + if k.Kind() == reflect.Interface && !k.IsNil() && !k.Elem().Type().Comparable() { + err := fmt.Errorf("invalid incomparable key type %v", k.Elem().Type()) + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + + if v2 := va.MapIndex(k.Value); v2.IsValid() { + if !dec.options.AllowDuplicateNames && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) { + // TODO: Unread the object name. + name := dec.previousBuffer() + err := &SyntacticError{str: "duplicate name " + string(name) + " in object"} + return err.withOffset(dec.InputOffset() - int64(len(name))) + } + v.Set(v2) + } else { + v.Set(reflect.Zero(v.Type())) + } + err := unmarshalVal(uo, dec, v) + va.SetMapIndex(k.Value, v.Value) + if seen.IsValid() { + seen.SetMapIndex(k.Value, reflect.Zero(emptyStructType)) + } + if err != nil { + return err + } + } + if _, err := dec.ReadToken(); err != nil { + return err + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +// mapKeyWithUniqueRepresentation reports whether all possible values of k +// marshal to a different JSON value, and whether all possible JSON values +// that can unmarshal into k unmarshal to different Go values. +// In other words, the representation must be a bijective. +func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool { + switch k { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.String: + // For strings, we have to be careful since names with invalid UTF-8 + // maybe unescape to the same Go string value. + return !allowInvalidUTF8 + default: + // Floating-point kinds are not listed above since NaNs + // can appear multiple times and all serialize as "NaN". + return false + } +} + +func makeStructArshaler(t reflect.Type) *arshaler { + // NOTE: The logic below disables namespaces for tracking duplicate names + // and does the tracking locally with an efficient bit-set based on which + // Go struct fields were seen. + + var fncs arshaler + var ( + once sync.Once + fields structFields + errInit *SemanticError + ) + init := func() { + fields, errInit = makeStructFields(t) + } + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + once.Do(init) + if errInit != nil { + err := *errInit // shallow copy SemanticError + err.action = "marshal" + return &err + } + if err := enc.WriteToken(ObjectStart); err != nil { + return err + } + var seenIdxs uintSet + prevIdx := -1 + enc.tokens.last.disableNamespace() // we manually ensure unique names below + for i := range fields.flattened { + f := &fields.flattened[i] + v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable + if len(f.index) > 1 { + v = v.fieldByIndex(f.index[1:], false) + if !v.IsValid() { + continue // implies a nil inlined field + } + } + + // OmitZero skips the field if the Go value is zero, + // which we can determine up front without calling the marshaler. + if f.omitzero && ((f.isZero == nil && v.IsZero()) || (f.isZero != nil && f.isZero(v))) { + continue + } + + marshal := f.fncs.marshal + nonDefault := f.fncs.nonDefault + if mo.Marshalers != nil { + var ok bool + marshal, ok = mo.Marshalers.lookup(marshal, f.typ) + nonDefault = nonDefault || ok + } + + // OmitEmpty skips the field if the marshaled JSON value is empty, + // which we can know up front if there are no custom marshalers, + // otherwise we must marshal the value and unwrite it if empty. + if f.omitempty && !nonDefault && f.isEmpty != nil && f.isEmpty(v) { + continue // fast path for omitempty + } + + // Write the object member name. + // + // The logic below is semantically equivalent to: + // enc.WriteToken(String(f.name)) + // but specialized and simplified because: + // 1. The Encoder must be expecting an object name. + // 2. The object namespace is guaranteed to be disabled. + // 3. The object name is guaranteed to be valid and pre-escaped. + // 4. There is no need to flush the buffer (for unwrite purposes). + // 5. There is no possibility of an error occurring. + if optimizeCommon { + // Append any delimiters or optional whitespace. + if enc.tokens.last.length() > 0 { + enc.buf = append(enc.buf, ',') + } + if enc.options.multiline { + enc.buf = enc.appendIndent(enc.buf, enc.tokens.needIndent('"')) + } + + // Append the token to the output and to the state machine. + n0 := len(enc.buf) // offset before calling appendString + if enc.options.EscapeRune == nil { + enc.buf = append(enc.buf, f.quotedName...) + } else { + enc.buf, _ = appendString(enc.buf, f.name, false, enc.options.EscapeRune) + } + if !enc.options.AllowDuplicateNames { + enc.names.replaceLastQuotedOffset(n0) + } + enc.tokens.last.increment() + } else { + if err := enc.WriteToken(String(f.name)); err != nil { + return err + } + } + + // Write the object member value. + mo2 := mo + if f.string { + mo2.StringifyNumbers = true + } + if f.format != "" { + mo2.formatDepth = enc.tokens.depth() + mo2.format = f.format + } + if err := marshal(mo2, enc, v); err != nil { + return err + } + + // Try unwriting the member if empty (slow path for omitempty). + if f.omitempty { + var prevName *string + if prevIdx >= 0 { + prevName = &fields.flattened[prevIdx].name + } + if enc.unwriteEmptyObjectMember(prevName) { + continue + } + } + + // Remember the previous written object member. + // The set of seen fields only needs to be updated to detect + // duplicate names with those from the inlined fallback. + if !enc.options.AllowDuplicateNames && fields.inlinedFallback != nil { + seenIdxs.insert(uint(f.id)) + } + prevIdx = f.id + } + if fields.inlinedFallback != nil && !(mo.DiscardUnknownMembers && fields.inlinedFallback.unknown) { + var insertUnquotedName func([]byte) bool + if !enc.options.AllowDuplicateNames { + insertUnquotedName = func(name []byte) bool { + // Check that the name from inlined fallback does not match + // one of the previously marshaled names from known fields. + if foldedFields := fields.byFoldedName[string(foldName(name))]; len(foldedFields) > 0 { + if f := fields.byActualName[string(name)]; f != nil { + return seenIdxs.insert(uint(f.id)) + } + for _, f := range foldedFields { + if f.nocase { + return seenIdxs.insert(uint(f.id)) + } + } + } + + // Check that the name does not match any other name + // previously marshaled from the inlined fallback. + return enc.namespaces.last().insertUnquoted(name) + } + } + if err := marshalInlinedFallbackAll(mo, enc, va, fields.inlinedFallback, insertUnquotedName); err != nil { + return err + } + } + if err := enc.WriteToken(ObjectEnd); err != nil { + return err + } + return nil + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + tok, err := dec.ReadToken() + if err != nil { + return err + } + k := tok.Kind() + switch k { + case 'n': + va.Set(reflect.Zero(t)) + return nil + case '{': + once.Do(init) + if errInit != nil { + err := *errInit // shallow copy SemanticError + err.action = "unmarshal" + return &err + } + var seenIdxs uintSet + dec.tokens.last.disableNamespace() + for dec.PeekKind() != '}' { + // Process the object member name. + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err + } + name := unescapeStringMayCopy(val, flags.isVerbatim()) + f := fields.byActualName[string(name)] + if f == nil { + for _, f2 := range fields.byFoldedName[string(foldName(name))] { + if f2.nocase { + f = f2 + break + } + } + if f == nil { + if uo.RejectUnknownMembers && (fields.inlinedFallback == nil || fields.inlinedFallback.unknown) { + return &SemanticError{action: "unmarshal", GoType: t, Err: fmt.Errorf("unknown name %s", val)} + } + if !dec.options.AllowDuplicateNames && !dec.namespaces.last().insertUnquoted(name) { + // TODO: Unread the object name. + err := &SyntacticError{str: "duplicate name " + string(val) + " in object"} + return err.withOffset(dec.InputOffset() - int64(len(val))) + } + + if fields.inlinedFallback == nil { + // Skip unknown value since we have no place to store it. + if err := dec.SkipValue(); err != nil { + return err + } + } else { + // Marshal into value capable of storing arbitrary object members. + if err := unmarshalInlinedFallbackNext(uo, dec, va, fields.inlinedFallback, val, name); err != nil { + return err + } + } + continue + } + } + if !dec.options.AllowDuplicateNames && !seenIdxs.insert(uint(f.id)) { + // TODO: Unread the object name. + err := &SyntacticError{str: "duplicate name " + string(val) + " in object"} + return err.withOffset(dec.InputOffset() - int64(len(val))) + } + + // Process the object member value. + unmarshal := f.fncs.unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, f.typ) + } + uo2 := uo + if f.string { + uo2.StringifyNumbers = true + } + if f.format != "" { + uo2.formatDepth = dec.tokens.depth() + uo2.format = f.format + } + v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable + if len(f.index) > 1 { + v = v.fieldByIndex(f.index[1:], true) + } + if err := unmarshal(uo2, dec, v); err != nil { + return err + } + } + if _, err := dec.ReadToken(); err != nil { + return err + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func (va addressableValue) fieldByIndex(index []int, mayAlloc bool) addressableValue { + for _, i := range index { + va = va.indirect(mayAlloc) + if !va.IsValid() { + return va + } + va = addressableValue{va.Field(i)} // addressable if struct value is addressable + } + return va +} + +func (va addressableValue) indirect(mayAlloc bool) addressableValue { + if va.Kind() == reflect.Pointer { + if va.IsNil() { + if !mayAlloc { + return addressableValue{} + } + va.Set(reflect.New(va.Type().Elem())) + } + va = addressableValue{va.Elem()} // dereferenced pointer is always addressable + } + return va +} + +func makeSliceArshaler(t reflect.Type) *arshaler { + var fncs arshaler + var ( + once sync.Once + valFncs *arshaler + ) + init := func() { + valFncs = lookupArshaler(t.Elem()) + } + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + // Check for cycles. + if enc.tokens.depth() > startDetectingCyclesAfter { + if err := enc.seenPointers.visit(va.Value); err != nil { + return err + } + defer enc.seenPointers.leave(va.Value) + } + + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + if mo.format == "emitnull" { + if va.IsNil() { + return enc.WriteToken(Null) + } + mo.format = "" + } else { + return newInvalidFormatError("marshal", t, mo.format) + } + } + + // Optimize for marshaling an empty slice without any preceding whitespace. + n := va.Len() + if optimizeCommon && n == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { + enc.buf = enc.tokens.mayAppendDelim(enc.buf, '[') + enc.buf = append(enc.buf, "[]"...) + enc.tokens.last.increment() + if enc.needFlush() { + return enc.flush() + } + return nil + } + + once.Do(init) + if err := enc.WriteToken(ArrayStart); err != nil { + return err + } + marshal := valFncs.marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + } + for i := 0; i < n; i++ { + v := addressableValue{va.Index(i)} // indexed slice element is always addressable + if err := marshal(mo, enc, v); err != nil { + return err + } + } + if err := enc.WriteToken(ArrayEnd); err != nil { + return err + } + return nil + } + emptySlice := reflect.MakeSlice(t, 0, 0) + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + if uo.format == "emitnull" { + uo.format = "" // only relevant for marshaling + } else { + return newInvalidFormatError("unmarshal", t, uo.format) + } + } + + tok, err := dec.ReadToken() + if err != nil { + return err + } + k := tok.Kind() + switch k { + case 'n': + va.Set(reflect.Zero(t)) + return nil + case '[': + once.Do(init) + unmarshal := valFncs.unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + } + mustZero := true // we do not know the cleanliness of unused capacity + cap := va.Cap() + if cap > 0 { + va.SetLen(cap) + } + var i int + for dec.PeekKind() != ']' { + if i == cap { + // TODO(https://go.dev/issue/48000): Use reflect.Value.Append. + va.Set(reflect.Append(va.Value, reflect.Zero(t.Elem()))) + cap = va.Cap() + va.SetLen(cap) + mustZero = false // append guarantees that unused capacity is zero-initialized + } + v := addressableValue{va.Index(i)} // indexed slice element is always addressable + i++ + if mustZero { + v.Set(reflect.Zero(t.Elem())) + } + if err := unmarshal(uo, dec, v); err != nil { + va.SetLen(i) + return err + } + } + if i == 0 { + va.Set(emptySlice) + } else { + va.SetLen(i) + } + if _, err := dec.ReadToken(); err != nil { + return err + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makeArrayArshaler(t reflect.Type) *arshaler { + var fncs arshaler + var ( + once sync.Once + valFncs *arshaler + ) + init := func() { + valFncs = lookupArshaler(t.Elem()) + } + n := t.Len() + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + once.Do(init) + if err := enc.WriteToken(ArrayStart); err != nil { + return err + } + marshal := valFncs.marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + } + for i := 0; i < n; i++ { + v := addressableValue{va.Index(i)} // indexed array element is addressable if array is addressable + if err := marshal(mo, enc, v); err != nil { + return err + } + } + if err := enc.WriteToken(ArrayEnd); err != nil { + return err + } + return nil + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + tok, err := dec.ReadToken() + if err != nil { + return err + } + k := tok.Kind() + switch k { + case 'n': + va.Set(reflect.Zero(t)) + return nil + case '[': + once.Do(init) + unmarshal := valFncs.unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + } + var i int + for dec.PeekKind() != ']' { + if i >= n { + err := errors.New("too many array elements") + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + v := addressableValue{va.Index(i)} // indexed array element is addressable if array is addressable + v.Set(reflect.Zero(v.Type())) + if err := unmarshal(uo, dec, v); err != nil { + return err + } + i++ + } + if _, err := dec.ReadToken(); err != nil { + return err + } + if i < n { + err := errors.New("too few array elements") + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + return nil + } + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + return &fncs +} + +func makePointerArshaler(t reflect.Type) *arshaler { + var fncs arshaler + var ( + once sync.Once + valFncs *arshaler + ) + init := func() { + valFncs = lookupArshaler(t.Elem()) + } + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + // Check for cycles. + if enc.tokens.depth() > startDetectingCyclesAfter { + if err := enc.seenPointers.visit(va.Value); err != nil { + return err + } + defer enc.seenPointers.leave(va.Value) + } + + // NOTE: MarshalOptions.format is forwarded to underlying marshal. + if va.IsNil() { + return enc.WriteToken(Null) + } + once.Do(init) + marshal := valFncs.marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + } + v := addressableValue{va.Elem()} // dereferenced pointer is always addressable + return marshal(mo, enc, v) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + // NOTE: UnmarshalOptions.format is forwarded to underlying unmarshal. + if dec.PeekKind() == 'n' { + if _, err := dec.ReadToken(); err != nil { + return err + } + va.Set(reflect.Zero(t)) + return nil + } + once.Do(init) + unmarshal := valFncs.unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + } + if va.IsNil() { + va.Set(reflect.New(t.Elem())) + } + v := addressableValue{va.Elem()} // dereferenced pointer is always addressable + return unmarshal(uo, dec, v) + } + return &fncs +} + +func makeInterfaceArshaler(t reflect.Type) *arshaler { + // NOTE: Values retrieved from an interface are not addressable, + // so we shallow copy the values to make them addressable and + // store them back into the interface afterwards. + + var fncs arshaler + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + return newInvalidFormatError("marshal", t, mo.format) + } + if va.IsNil() { + return enc.WriteToken(Null) + } + v := newAddressableValue(va.Elem().Type()) + v.Set(va.Elem()) + marshal := lookupArshaler(v.Type()).marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.lookup(marshal, v.Type()) + } + // Optimize for the any type if there are no special options. + if optimizeCommon && t == anyType && !mo.StringifyNumbers && mo.format == "" && (mo.Marshalers == nil || !mo.Marshalers.fromAny) { + return marshalValueAny(mo, enc, va.Elem().Interface()) + } + return marshal(mo, enc, v) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + return newInvalidFormatError("unmarshal", t, uo.format) + } + if dec.PeekKind() == 'n' { + if _, err := dec.ReadToken(); err != nil { + return err + } + va.Set(reflect.Zero(t)) + return nil + } + var v addressableValue + if va.IsNil() { + // Optimize for the any type if there are no special options. + // We do not care about stringified numbers since JSON strings + // are always unmarshaled into an any value as Go strings. + // Duplicate name check must be enforced since unmarshalValueAny + // does not implement merge semantics. + if optimizeCommon && t == anyType && uo.format == "" && (uo.Unmarshalers == nil || !uo.Unmarshalers.fromAny) && !dec.options.AllowDuplicateNames { + v, err := unmarshalValueAny(uo, dec) + // We must check for nil interface values up front. + // See https://go.dev/issue/52310. + if v != nil { + va.Set(reflect.ValueOf(v)) + } + return err + } + + k := dec.PeekKind() + if !isAnyType(t) { + err := errors.New("cannot derive concrete type for non-empty interface") + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + switch k { + case 'f', 't': + v = newAddressableValue(boolType) + case '"': + v = newAddressableValue(stringType) + case '0': + v = newAddressableValue(float64Type) + case '{': + v = newAddressableValue(mapStringAnyType) + case '[': + v = newAddressableValue(sliceAnyType) + default: + // If k is invalid (e.g., due to an I/O or syntax error), then + // that will be cached by PeekKind and returned by ReadValue. + // If k is '}' or ']', then ReadValue must error since + // those are invalid kinds at the start of a JSON value. + _, err := dec.ReadValue() + return err + } + } else { + // Shallow copy the existing value to keep it addressable. + // Any mutations at the top-level of the value will be observable + // since we always store this value back into the interface value. + v = newAddressableValue(va.Elem().Type()) + v.Set(va.Elem()) + } + unmarshal := lookupArshaler(v.Type()).unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, v.Type()) + } + err := unmarshal(uo, dec, v) + va.Set(v.Value) + return err + } + return &fncs +} + +// isAnyType reports wether t is equivalent to the any interface type. +func isAnyType(t reflect.Type) bool { + // This is forward compatible if the Go language permits type sets within + // ordinary interfaces where an interface with zero methods does not + // necessarily mean it can hold every possible Go type. + // See https://go.dev/issue/45346. + return t == anyType || anyType.Implements(t) +} + +func makeInvalidArshaler(t reflect.Type) *arshaler { + var fncs arshaler + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + return &SemanticError{action: "marshal", GoType: t} + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + return &SemanticError{action: "unmarshal", GoType: t} + } + return &fncs +} + +func newInvalidFormatError(action string, t reflect.Type, format string) error { + err := fmt.Errorf("invalid format flag: %q", format) + return &SemanticError{action: action, GoType: t, Err: err} +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go new file mode 100644 index 00000000000..8a4e7008399 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go @@ -0,0 +1,387 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "errors" + "fmt" + "reflect" + "sync" +) + +// SkipFunc may be returned by MarshalFuncV2 and UnmarshalFuncV2 functions. +// +// Any function that returns SkipFunc must not cause observable side effects +// on the provided Encoder or Decoder. For example, it is permissible to call +// Decoder.PeekKind, but not permissible to call Decoder.ReadToken or +// Encoder.WriteToken since such methods mutate the state. +const SkipFunc = jsonError("skip function") + +// Marshalers is a list of functions that may override the marshal behavior +// of specific types. Populate MarshalOptions.Marshalers to use it. +// A nil *Marshalers is equivalent to an empty list. +type Marshalers = typedMarshalers + +// NewMarshalers constructs a flattened list of marshal functions. +// If multiple functions in the list are applicable for a value of a given type, +// then those earlier in the list take precedence over those that come later. +// If a function returns SkipFunc, then the next applicable function is called, +// otherwise the default marshaling behavior is used. +// +// For example: +// +// m1 := NewMarshalers(f1, f2) +// m2 := NewMarshalers(f0, m1, f3) // equivalent to m3 +// m3 := NewMarshalers(f0, f1, f2, f3) // equivalent to m2 +func NewMarshalers(ms ...*Marshalers) *Marshalers { + return newMarshalers(ms...) +} + +// Unmarshalers is a list of functions that may override the unmarshal behavior +// of specific types. Populate UnmarshalOptions.Unmarshalers to use it. +// A nil *Unmarshalers is equivalent to an empty list. +type Unmarshalers = typedUnmarshalers + +// NewUnmarshalers constructs a flattened list of unmarshal functions. +// If multiple functions in the list are applicable for a value of a given type, +// then those earlier in the list take precedence over those that come later. +// If a function returns SkipFunc, then the next applicable function is called, +// otherwise the default unmarshaling behavior is used. +// +// For example: +// +// u1 := NewUnmarshalers(f1, f2) +// u2 := NewUnmarshalers(f0, u1, f3) // equivalent to u3 +// u3 := NewUnmarshalers(f0, f1, f2, f3) // equivalent to u2 +func NewUnmarshalers(us ...*Unmarshalers) *Unmarshalers { + return newUnmarshalers(us...) +} + +type typedMarshalers = typedArshalers[MarshalOptions, Encoder] +type typedUnmarshalers = typedArshalers[UnmarshalOptions, Decoder] +type typedArshalers[Options, Coder any] struct { + nonComparable + + fncVals []typedArshaler[Options, Coder] + fncCache sync.Map // map[reflect.Type]arshaler + + // fromAny reports whether any of Go types used to represent arbitrary JSON + // (i.e., any, bool, string, float64, map[string]any, or []any) matches + // any of the provided type-specific arshalers. + // + // This bit of information is needed in arshal_default.go to determine + // whether to use the specialized logic in arshal_any.go to handle + // the any interface type. The logic in arshal_any.go does not support + // type-specific arshal functions, so we must avoid using that logic + // if this is true. + fromAny bool +} +type typedMarshaler = typedArshaler[MarshalOptions, Encoder] +type typedUnmarshaler = typedArshaler[UnmarshalOptions, Decoder] +type typedArshaler[Options, Coder any] struct { + typ reflect.Type + fnc func(Options, *Coder, addressableValue) error + maySkip bool +} + +func newMarshalers(ms ...*Marshalers) *Marshalers { return newTypedArshalers(ms...) } +func newUnmarshalers(us ...*Unmarshalers) *Unmarshalers { return newTypedArshalers(us...) } +func newTypedArshalers[Options, Coder any](as ...*typedArshalers[Options, Coder]) *typedArshalers[Options, Coder] { + var a typedArshalers[Options, Coder] + for _, a2 := range as { + if a2 != nil { + a.fncVals = append(a.fncVals, a2.fncVals...) + a.fromAny = a.fromAny || a2.fromAny + } + } + if len(a.fncVals) == 0 { + return nil + } + return &a +} + +func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addressableValue) error, t reflect.Type) (func(Options, *Coder, addressableValue) error, bool) { + if a == nil { + return fnc, false + } + if v, ok := a.fncCache.Load(t); ok { + if v == nil { + return fnc, false + } + return v.(func(Options, *Coder, addressableValue) error), true + } + + // Collect a list of arshalers that can be called for this type. + // This list may be longer than 1 since some arshalers can be skipped. + var fncs []func(Options, *Coder, addressableValue) error + for _, fncVal := range a.fncVals { + if !castableTo(t, fncVal.typ) { + continue + } + fncs = append(fncs, fncVal.fnc) + if !fncVal.maySkip { + break // subsequent arshalers will never be called + } + } + + if len(fncs) == 0 { + a.fncCache.Store(t, nil) // nil to indicate that no funcs found + return fnc, false + } + + // Construct an arshaler that may call every applicable arshaler. + fncDefault := fnc + fnc = func(o Options, c *Coder, v addressableValue) error { + for _, fnc := range fncs { + if err := fnc(o, c, v); err != SkipFunc { + return err // may be nil or non-nil + } + } + return fncDefault(o, c, v) + } + + // Use the first stored so duplicate work can be garbage collected. + v, _ := a.fncCache.LoadOrStore(t, fnc) + return v.(func(Options, *Coder, addressableValue) error), true +} + +// MarshalFuncV1 constructs a type-specific marshaler that +// specifies how to marshal values of type T. +// T can be any type except a named pointer. +// The function is always provided with a non-nil pointer value +// if T is an interface or pointer type. +// +// The function must marshal exactly one JSON value. +// The value of T must not be retained outside the function call. +// It may not return SkipFunc. +func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers { + t := reflect.TypeOf((*T)(nil)).Elem() + assertCastableTo(t, true) + typFnc := typedMarshaler{ + typ: t, + fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + val, err := fn(va.castTo(t).Interface().(T)) + if err != nil { + err = wrapSkipFunc(err, "marshal function of type func(T) ([]byte, error)") + // TODO: Avoid wrapping semantic errors. + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + if err := enc.WriteValue(val); err != nil { + // TODO: Avoid wrapping semantic or I/O errors. + return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err} + } + return nil + }, + } + return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} +} + +// MarshalFuncV2 constructs a type-specific marshaler that +// specifies how to marshal values of type T. +// T can be any type except a named pointer. +// The function is always provided with a non-nil pointer value +// if T is an interface or pointer type. +// +// The function must marshal exactly one JSON value by calling write methods +// on the provided encoder. It may return SkipFunc such that marshaling can +// move on to the next marshal function. However, no mutable method calls may +// be called on the encoder if SkipFunc is returned. +// The pointer to Encoder and the value of T must not be retained +// outside the function call. +func MarshalFuncV2[T any](fn func(MarshalOptions, *Encoder, T) error) *Marshalers { + t := reflect.TypeOf((*T)(nil)).Elem() + assertCastableTo(t, true) + typFnc := typedMarshaler{ + typ: t, + fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + prevDepth, prevLength := enc.tokens.depthLength() + err := fn(mo, enc, va.castTo(t).Interface().(T)) + currDepth, currLength := enc.tokens.depthLength() + if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { + err = errors.New("must write exactly one JSON value") + } + if err != nil { + if err == SkipFunc { + if prevDepth == currDepth && prevLength == currLength { + return SkipFunc + } + err = errors.New("must not write any JSON tokens when skipping") + } + // TODO: Avoid wrapping semantic or I/O errors. + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return nil + }, + maySkip: true, + } + return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} +} + +// UnmarshalFuncV1 constructs a type-specific unmarshaler that +// specifies how to unmarshal values of type T. +// T must be an unnamed pointer or an interface type. +// The function is always provided with a non-nil pointer value. +// +// The function must unmarshal exactly one JSON value. +// The input []byte must not be mutated. +// The input []byte and value T must not be retained outside the function call. +// It may not return SkipFunc. +func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers { + t := reflect.TypeOf((*T)(nil)).Elem() + assertCastableTo(t, false) + typFnc := typedUnmarshaler{ + typ: t, + fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + val, err := dec.ReadValue() + if err != nil { + return err // must be a syntactic or I/O error + } + err = fn(val, va.castTo(t).Interface().(T)) + if err != nil { + err = wrapSkipFunc(err, "unmarshal function of type func([]byte, T) error") + // TODO: Avoid wrapping semantic, syntactic, or I/O errors. + return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + } + return nil + }, + } + return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)} +} + +// UnmarshalFuncV2 constructs a type-specific unmarshaler that +// specifies how to unmarshal values of type T. +// T must be an unnamed pointer or an interface type. +// The function is always provided with a non-nil pointer value. +// +// The function must unmarshal exactly one JSON value by calling read methods +// on the provided decoder. It may return SkipFunc such that unmarshaling can +// move on to the next unmarshal function. However, no mutable method calls may +// be called on the decoder if SkipFunc is returned. +// The pointer to Decoder and the value of T must not be retained +// outside the function call. +func UnmarshalFuncV2[T any](fn func(UnmarshalOptions, *Decoder, T) error) *Unmarshalers { + t := reflect.TypeOf((*T)(nil)).Elem() + assertCastableTo(t, false) + typFnc := typedUnmarshaler{ + typ: t, + fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + prevDepth, prevLength := dec.tokens.depthLength() + err := fn(uo, dec, va.castTo(t).Interface().(T)) + currDepth, currLength := dec.tokens.depthLength() + if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { + err = errors.New("must read exactly one JSON value") + } + if err != nil { + if err == SkipFunc { + if prevDepth == currDepth && prevLength == currLength { + return SkipFunc + } + err = errors.New("must not read any JSON tokens when skipping") + } + // TODO: Avoid wrapping semantic, syntactic, or I/O errors. + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + return nil + }, + maySkip: true, + } + return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)} +} + +// assertCastableTo asserts that "to" is a valid type to be casted to. +// These are the Go types that type-specific arshalers may operate upon. +// +// Let AllTypes be the universal set of all possible Go types. +// This function generally asserts that: +// +// len([from for from in AllTypes if castableTo(from, to)]) > 0 +// +// otherwise it panics. +// +// As a special-case if marshal is false, then we forbid any non-pointer or +// non-interface type since it is almost always a bug trying to unmarshal +// into something where the end-user caller did not pass in an addressable value +// since they will not observe the mutations. +func assertCastableTo(to reflect.Type, marshal bool) { + switch to.Kind() { + case reflect.Interface: + return + case reflect.Pointer: + // Only allow unnamed pointers to be consistent with the fact that + // taking the address of a value produces an unnamed pointer type. + if to.Name() == "" { + return + } + default: + // Technically, non-pointer types are permissible for unmarshal. + // However, they are often a bug since the receiver would be immutable. + // Thus, only allow them for marshaling. + if marshal { + return + } + } + if marshal { + panic(fmt.Sprintf("input type %v must be an interface type, an unnamed pointer type, or a non-pointer type", to)) + } else { + panic(fmt.Sprintf("input type %v must be an interface type or an unnamed pointer type", to)) + } +} + +// castableTo checks whether values of type "from" can be casted to type "to". +// Nil pointer or interface "from" values are never considered castable. +// +// This function must be kept in sync with addressableValue.castTo. +func castableTo(from, to reflect.Type) bool { + switch to.Kind() { + case reflect.Interface: + // TODO: This breaks when ordinary interfaces can have type sets + // since interfaces now exist where only the value form of a type (T) + // implements the interface, but not the pointer variant (*T). + // See https://go.dev/issue/45346. + return reflect.PointerTo(from).Implements(to) + case reflect.Pointer: + // Common case for unmarshaling. + // From must be a concrete or interface type. + return reflect.PointerTo(from) == to + default: + // Common case for marshaling. + // From must be a concrete type. + return from == to + } +} + +// castTo casts va to the specified type. +// If the type is an interface, then the underlying type will always +// be a non-nil pointer to a concrete type. +// +// Requirement: castableTo(va.Type(), to) must hold. +func (va addressableValue) castTo(to reflect.Type) reflect.Value { + switch to.Kind() { + case reflect.Interface: + return va.Addr().Convert(to) + case reflect.Pointer: + return va.Addr() + default: + return va.Value + } +} + +// castableToFromAny reports whether "to" can be casted to from any +// of the dynamic types used to represent arbitrary JSON. +func castableToFromAny(to reflect.Type) bool { + for _, from := range []reflect.Type{anyType, boolType, stringType, float64Type, mapStringAnyType, sliceAnyType} { + if castableTo(from, to) { + return true + } + } + return false +} + +func wrapSkipFunc(err error, what string) error { + if err == SkipFunc { + return errors.New(what + " cannot be skipped") + } + return err +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go new file mode 100644 index 00000000000..258a98247d6 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go @@ -0,0 +1,213 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "errors" + "reflect" +) + +// This package supports "inlining" a Go struct field, where the contents +// of the serialized field (which must be a JSON object) are treated as if +// they are part of the parent Go struct (which represents a JSON object). +// +// Generally, inlined fields are of a Go struct type, where the fields of the +// nested struct are virtually hoisted up to the parent struct using rules +// similar to how Go embedding works (but operating within the JSON namespace). +// +// However, inlined fields may also be of a Go map type with a string key +// or a RawValue. Such inlined fields are called "fallback" fields since they +// represent any arbitrary JSON object member. Explicitly named fields take +// precedence over the inlined fallback. Only one inlined fallback is allowed. + +var rawValueType = reflect.TypeOf((*RawValue)(nil)).Elem() + +// marshalInlinedFallbackAll marshals all the members in an inlined fallback. +func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableValue, f *structField, insertUnquotedName func([]byte) bool) error { + v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable + if len(f.index) > 1 { + v = v.fieldByIndex(f.index[1:], false) + if !v.IsValid() { + return nil // implies a nil inlined field + } + } + v = v.indirect(false) + if !v.IsValid() { + return nil + } + + if v.Type() == rawValueType { + b := v.Interface().(RawValue) + if len(b) == 0 { // TODO: Should this be nil? What if it were all whitespace? + return nil + } + + dec := getBufferedDecoder(b, DecodeOptions{AllowDuplicateNames: true, AllowInvalidUTF8: true}) + defer putBufferedDecoder(dec) + + tok, err := dec.ReadToken() + if err != nil { + return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + } + if tok.Kind() != '{' { + err := errors.New("inlined raw value must be a JSON object") + return &SemanticError{action: "marshal", JSONKind: tok.Kind(), GoType: rawValueType, Err: err} + } + for dec.PeekKind() != '}' { + // Parse the JSON object name. + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + } + if insertUnquotedName != nil { + name := unescapeStringMayCopy(val, flags.isVerbatim()) + if !insertUnquotedName(name) { + return &SyntacticError{str: "duplicate name " + string(val) + " in object"} + } + } + if err := enc.WriteValue(val); err != nil { + return err + } + + // Parse the JSON object value. + val, err = dec.readValue(&flags) + if err != nil { + return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + } + if err := enc.WriteValue(val); err != nil { + return err + } + } + if _, err := dec.ReadToken(); err != nil { + return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + } + if err := dec.checkEOF(); err != nil { + return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + } + return nil + } else { + m := v // must be a map[string]V + n := m.Len() + if n == 0 { + return nil + } + mk := newAddressableValue(stringType) + mv := newAddressableValue(m.Type().Elem()) + marshalKey := func(mk addressableValue) error { + b, err := appendString(enc.UnusedBuffer(), mk.String(), !enc.options.AllowInvalidUTF8, nil) + if err != nil { + return err + } + if insertUnquotedName != nil { + isVerbatim := bytes.IndexByte(b, '\\') < 0 + name := unescapeStringMayCopy(b, isVerbatim) + if !insertUnquotedName(name) { + return &SyntacticError{str: "duplicate name " + string(b) + " in object"} + } + } + return enc.WriteValue(b) + } + marshalVal := f.fncs.marshal + if mo.Marshalers != nil { + marshalVal, _ = mo.Marshalers.lookup(marshalVal, mv.Type()) + } + if !mo.Deterministic || n <= 1 { + for iter := m.MapRange(); iter.Next(); { + mk.SetIterKey(iter) + if err := marshalKey(mk); err != nil { + return err + } + mv.Set(iter.Value()) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } + } + } else { + names := getStrings(n) + for i, iter := 0, m.Value.MapRange(); i < n && iter.Next(); i++ { + mk.SetIterKey(iter) + (*names)[i] = mk.String() + } + names.Sort() + for _, name := range *names { + mk.SetString(name) + if err := marshalKey(mk); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use mv.SetMapIndexOf. + mv.Set(m.MapIndex(mk.Value)) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } + } + putStrings(names) + } + return nil + } +} + +// unmarshalInlinedFallbackNext unmarshals only the next member in an inlined fallback. +func unmarshalInlinedFallbackNext(uo UnmarshalOptions, dec *Decoder, va addressableValue, f *structField, quotedName, unquotedName []byte) error { + v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable + if len(f.index) > 1 { + v = v.fieldByIndex(f.index[1:], true) + } + v = v.indirect(true) + + if v.Type() == rawValueType { + b := v.Addr().Interface().(*RawValue) + if len(*b) == 0 { // TODO: Should this be nil? What if it were all whitespace? + *b = append(*b, '{') + } else { + *b = trimSuffixWhitespace(*b) + if hasSuffixByte(*b, '}') { + // TODO: When merging into an object for the first time, + // should we verify that it is valid? + *b = trimSuffixByte(*b, '}') + *b = trimSuffixWhitespace(*b) + if !hasSuffixByte(*b, ',') && !hasSuffixByte(*b, '{') { + *b = append(*b, ',') + } + } else { + err := errors.New("inlined raw value must be a JSON object") + return &SemanticError{action: "unmarshal", GoType: rawValueType, Err: err} + } + } + *b = append(*b, quotedName...) + *b = append(*b, ':') + rawValue, err := dec.ReadValue() + if err != nil { + return err + } + *b = append(*b, rawValue...) + *b = append(*b, '}') + return nil + } else { + name := string(unquotedName) // TODO: Intern this? + + m := v // must be a map[string]V + if m.IsNil() { + m.Set(reflect.MakeMap(m.Type())) + } + mk := reflect.ValueOf(name) + mv := newAddressableValue(v.Type().Elem()) // TODO: Cache across calls? + if v2 := m.MapIndex(mk); v2.IsValid() { + mv.Set(v2) + } + + unmarshal := f.fncs.unmarshal + if uo.Unmarshalers != nil { + unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, mv.Type()) + } + err := unmarshal(uo, dec, mv) + m.SetMapIndex(mk, mv.Value) + if err != nil { + return err + } + return nil + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go new file mode 100644 index 00000000000..20899c868ca --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go @@ -0,0 +1,229 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "encoding" + "errors" + "reflect" +) + +// Interfaces for custom serialization. +var ( + jsonMarshalerV1Type = reflect.TypeOf((*MarshalerV1)(nil)).Elem() + jsonMarshalerV2Type = reflect.TypeOf((*MarshalerV2)(nil)).Elem() + jsonUnmarshalerV1Type = reflect.TypeOf((*UnmarshalerV1)(nil)).Elem() + jsonUnmarshalerV2Type = reflect.TypeOf((*UnmarshalerV2)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +// MarshalerV1 is implemented by types that can marshal themselves. +// It is recommended that types implement MarshalerV2 unless the implementation +// is trying to avoid a hard dependency on the "jsontext" package. +// +// It is recommended that implementations return a buffer that is safe +// for the caller to retain and potentially mutate. +type MarshalerV1 interface { + MarshalJSON() ([]byte, error) +} + +// MarshalerV2 is implemented by types that can marshal themselves. +// It is recommended that types implement MarshalerV2 instead of MarshalerV1 +// since this is both more performant and flexible. +// If a type implements both MarshalerV1 and MarshalerV2, +// then MarshalerV2 takes precedence. In such a case, both implementations +// should aim to have equivalent behavior for the default marshal options. +// +// The implementation must write only one JSON value to the Encoder and +// must not retain the pointer to Encoder. +type MarshalerV2 interface { + MarshalNextJSON(MarshalOptions, *Encoder) error + + // TODO: Should users call the MarshalOptions.MarshalNext method or + // should/can they call this method directly? Does it matter? +} + +// UnmarshalerV1 is implemented by types that can unmarshal themselves. +// It is recommended that types implement UnmarshalerV2 unless +// the implementation is trying to avoid a hard dependency on this package. +// +// The input can be assumed to be a valid encoding of a JSON value +// if called from unmarshal functionality in this package. +// UnmarshalJSON must copy the JSON data if it is retained after returning. +// It is recommended that UnmarshalJSON implement merge semantics when +// unmarshaling into a pre-populated value. +// +// Implementations must not retain or mutate the input []byte. +type UnmarshalerV1 interface { + UnmarshalJSON([]byte) error +} + +// UnmarshalerV2 is implemented by types that can unmarshal themselves. +// It is recommended that types implement UnmarshalerV2 instead of UnmarshalerV1 +// since this is both more performant and flexible. +// If a type implements both UnmarshalerV1 and UnmarshalerV2, +// then UnmarshalerV2 takes precedence. In such a case, both implementations +// should aim to have equivalent behavior for the default unmarshal options. +// +// The implementation must read only one JSON value from the Decoder. +// It is recommended that UnmarshalNextJSON implement merge semantics when +// unmarshaling into a pre-populated value. +// +// Implementations must not retain the pointer to Decoder. +type UnmarshalerV2 interface { + UnmarshalNextJSON(UnmarshalOptions, *Decoder) error + + // TODO: Should users call the UnmarshalOptions.UnmarshalNext method or + // should/can they call this method directly? Does it matter? +} + +func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { + // Avoid injecting method arshaler on the pointer or interface version + // to avoid ever calling the method on a nil pointer or interface receiver. + // Let it be injected on the value receiver (which is always addressable). + if t.Kind() == reflect.Pointer || t.Kind() == reflect.Interface { + return fncs + } + + // Handle custom marshaler. + switch which, needAddr := implementsWhich(t, jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType); which { + case jsonMarshalerV2Type: + fncs.nonDefault = true + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + prevDepth, prevLength := enc.tokens.depthLength() + err := va.addrWhen(needAddr).Interface().(MarshalerV2).MarshalNextJSON(mo, enc) + currDepth, currLength := enc.tokens.depthLength() + if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { + err = errors.New("must write exactly one JSON value") + } + if err != nil { + err = wrapSkipFunc(err, "marshal method") + // TODO: Avoid wrapping semantic or I/O errors. + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return nil + } + case jsonMarshalerV1Type: + fncs.nonDefault = true + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + marshaler := va.addrWhen(needAddr).Interface().(MarshalerV1) + val, err := marshaler.MarshalJSON() + if err != nil { + err = wrapSkipFunc(err, "marshal method") + // TODO: Avoid wrapping semantic errors. + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + if err := enc.WriteValue(val); err != nil { + // TODO: Avoid wrapping semantic or I/O errors. + return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err} + } + return nil + } + case textMarshalerType: + fncs.nonDefault = true + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + marshaler := va.addrWhen(needAddr).Interface().(encoding.TextMarshaler) + s, err := marshaler.MarshalText() + if err != nil { + err = wrapSkipFunc(err, "marshal method") + // TODO: Avoid wrapping semantic errors. + return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + } + val := enc.UnusedBuffer() + val, err = appendString(val, string(s), true, nil) + if err != nil { + return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + } + if err := enc.WriteValue(val); err != nil { + // TODO: Avoid wrapping syntactic or I/O errors. + return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + } + return nil + } + } + + // Handle custom unmarshaler. + switch which, needAddr := implementsWhich(t, jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType); which { + case jsonUnmarshalerV2Type: + fncs.nonDefault = true + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + prevDepth, prevLength := dec.tokens.depthLength() + err := va.addrWhen(needAddr).Interface().(UnmarshalerV2).UnmarshalNextJSON(uo, dec) + currDepth, currLength := dec.tokens.depthLength() + if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { + err = errors.New("must read exactly one JSON value") + } + if err != nil { + err = wrapSkipFunc(err, "unmarshal method") + // TODO: Avoid wrapping semantic, syntactic, or I/O errors. + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + return nil + } + case jsonUnmarshalerV1Type: + fncs.nonDefault = true + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + val, err := dec.ReadValue() + if err != nil { + return err // must be a syntactic or I/O error + } + unmarshaler := va.addrWhen(needAddr).Interface().(UnmarshalerV1) + if err := unmarshaler.UnmarshalJSON(val); err != nil { + err = wrapSkipFunc(err, "unmarshal method") + // TODO: Avoid wrapping semantic, syntactic, or I/O errors. + return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + } + return nil + } + case textUnmarshalerType: + fncs.nonDefault = true + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + var flags valueFlags + val, err := dec.readValue(&flags) + if err != nil { + return err // must be a syntactic or I/O error + } + if val.Kind() != '"' { + err = errors.New("JSON value must be string type") + return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + } + s := unescapeStringMayCopy(val, flags.isVerbatim()) + unmarshaler := va.addrWhen(needAddr).Interface().(encoding.TextUnmarshaler) + if err := unmarshaler.UnmarshalText(s); err != nil { + err = wrapSkipFunc(err, "unmarshal method") + // TODO: Avoid wrapping semantic, syntactic, or I/O errors. + return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + } + return nil + } + } + + return fncs +} + +// implementsWhich is like t.Implements(ifaceType) for a list of interfaces, +// but checks whether either t or reflect.PointerTo(t) implements the interface. +// It returns the first interface type that matches and whether a value of t +// needs to be addressed first before it implements the interface. +func implementsWhich(t reflect.Type, ifaceTypes ...reflect.Type) (which reflect.Type, needAddr bool) { + for _, ifaceType := range ifaceTypes { + switch { + case t.Implements(ifaceType): + return ifaceType, false + case reflect.PointerTo(t).Implements(ifaceType): + return ifaceType, true + } + } + return nil, false +} + +// addrWhen returns va.Addr if addr is specified, otherwise it returns itself. +func (va addressableValue) addrWhen(addr bool) reflect.Value { + if addr { + return va.Addr() + } + return va.Value +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go new file mode 100644 index 00000000000..fc8d5b00703 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go @@ -0,0 +1,241 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "errors" + "fmt" + "reflect" + "strings" + "time" +) + +var ( + timeDurationType = reflect.TypeOf((*time.Duration)(nil)).Elem() + timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem() +) + +func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { + // Ideally, time types would implement MarshalerV2 and UnmarshalerV2, + // but that would incur a dependency on package json from package time. + // Given how widely used time is, it is more acceptable that we incur a + // dependency on time from json. + // + // Injecting the arshaling functionality like this will not be identical + // to actually declaring methods on the time types since embedding of the + // time types will not be able to forward this functionality. + switch t { + case timeDurationType: + fncs.nonDefault = true + marshalNanos := fncs.marshal + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + if mo.format == "nanos" { + mo.format = "" + return marshalNanos(mo, enc, va) + } else { + return newInvalidFormatError("marshal", t, mo.format) + } + } + + td := va.Interface().(time.Duration) + b := enc.UnusedBuffer() + b = append(b, '"') + b = append(b, td.String()...) // never contains special characters + b = append(b, '"') + return enc.WriteValue(b) + } + unmarshalNanos := fncs.unmarshal + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + // TODO: Should there be a flag that specifies that we can unmarshal + // from either form since there would be no ambiguity? + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + if uo.format == "nanos" { + uo.format = "" + return unmarshalNanos(uo, dec, va) + } else { + return newInvalidFormatError("unmarshal", t, uo.format) + } + } + + var flags valueFlags + td := va.Addr().Interface().(*time.Duration) + val, err := dec.readValue(&flags) + if err != nil { + return err + } + switch k := val.Kind(); k { + case 'n': + *td = time.Duration(0) + return nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + td2, err := time.ParseDuration(string(val)) + if err != nil { + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + *td = td2 + return nil + default: + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + } + case timeTimeType: + fncs.nonDefault = true + fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + format := time.RFC3339Nano + isRFC3339 := true + if mo.format != "" && mo.formatDepth == enc.tokens.depth() { + var err error + format, isRFC3339, err = checkTimeFormat(mo.format) + if err != nil { + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + } + + tt := va.Interface().(time.Time) + b := enc.UnusedBuffer() + b = append(b, '"') + b = tt.AppendFormat(b, format) + b = append(b, '"') + if isRFC3339 { + // Not all Go timestamps can be represented as valid RFC 3339. + // Explicitly check for these edge cases. + // See https://go.dev/issue/4556 and https://go.dev/issue/54580. + var err error + switch b := b[len(`"`) : len(b)-len(`"`)]; { + case b[len("9999")] != '-': // year must be exactly 4 digits wide + err = errors.New("year outside of range [0,9999]") + case b[len(b)-1] != 'Z': + c := b[len(b)-len("Z07:00")] + if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 { + err = errors.New("timezone hour outside of range [0,23]") + } + } + if err != nil { + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return enc.WriteValue(b) // RFC 3339 never needs JSON escaping + } + // The format may contain special characters that need escaping. + // Verify that the result is a valid JSON string (common case), + // otherwise escape the string correctly (slower case). + if consumeSimpleString(b) != len(b) { + b, _ = appendString(nil, string(b[len(`"`):len(b)-len(`"`)]), true, nil) + } + return enc.WriteValue(b) + } + fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + format := time.RFC3339 + isRFC3339 := true + if uo.format != "" && uo.formatDepth == dec.tokens.depth() { + var err error + format, isRFC3339, err = checkTimeFormat(uo.format) + if err != nil { + return &SemanticError{action: "unmarshal", GoType: t, Err: err} + } + } + + var flags valueFlags + tt := va.Addr().Interface().(*time.Time) + val, err := dec.readValue(&flags) + if err != nil { + return err + } + k := val.Kind() + switch k { + case 'n': + *tt = time.Time{} + return nil + case '"': + val = unescapeStringMayCopy(val, flags.isVerbatim()) + tt2, err := time.Parse(format, string(val)) + if isRFC3339 && err == nil { + // TODO(https://go.dev/issue/54580): RFC 3339 specifies + // the exact grammar of a valid timestamp. However, + // the parsing functionality in "time" is too loose and + // incorrectly accepts invalid timestamps as valid. + // Remove these manual checks when "time" checks it for us. + newParseError := func(layout, value, layoutElem, valueElem, message string) error { + return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message} + } + switch { + case val[len("2006-01-02T")+1] == ':': // hour must be two digits + err = newParseError(format, string(val), "15", string(val[len("2006-01-02T"):][:1]), "") + case val[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period + err = newParseError(format, string(val), ".", ",", "") + case val[len(val)-1] != 'Z': + switch { + case parseDec2(val[len(val)-len("07:00"):]) >= 24: // timezone hour must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone hour out of range") + case parseDec2(val[len(val)-len("00"):]) >= 60: // timezone minute must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone minute out of range") + } + } + } + if err != nil { + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + } + *tt = tt2 + return nil + default: + return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + } + } + } + return fncs +} + +func checkTimeFormat(format string) (string, bool, error) { + // We assume that an exported constant in the time package will + // always start with an uppercase ASCII letter. + if len(format) > 0 && 'A' <= format[0] && format[0] <= 'Z' { + switch format { + case "ANSIC": + return time.ANSIC, false, nil + case "UnixDate": + return time.UnixDate, false, nil + case "RubyDate": + return time.RubyDate, false, nil + case "RFC822": + return time.RFC822, false, nil + case "RFC822Z": + return time.RFC822Z, false, nil + case "RFC850": + return time.RFC850, false, nil + case "RFC1123": + return time.RFC1123, false, nil + case "RFC1123Z": + return time.RFC1123Z, false, nil + case "RFC3339": + return time.RFC3339, true, nil + case "RFC3339Nano": + return time.RFC3339Nano, true, nil + case "Kitchen": + return time.Kitchen, false, nil + case "Stamp": + return time.Stamp, false, nil + case "StampMilli": + return time.StampMilli, false, nil + case "StampMicro": + return time.StampMicro, false, nil + case "StampNano": + return time.StampNano, false, nil + default: + // Reject any format that is an exported Go identifier in case + // new format constants are added to the time package. + if strings.TrimFunc(format, isLetterOrDigit) == "" { + return "", false, fmt.Errorf("undefined format layout: %v", format) + } + } + } + return format, false, nil +} + +// parseDec2 parses b as an unsigned, base-10, 2-digit number. +// It panics if len(b) < 2. The result is undefined if digits are not base-10. +func parseDec2(b []byte) byte { + return 10*(b[0]-'0') + (b[1] - '0') +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go new file mode 100644 index 00000000000..0d68b32338e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go @@ -0,0 +1,1655 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "errors" + "io" + "math" + "strconv" + "unicode/utf16" + "unicode/utf8" +) + +// NOTE: The logic for decoding is complicated by the fact that reading from +// an io.Reader into a temporary buffer means that the buffer may contain a +// truncated portion of some valid input, requiring the need to fetch more data. +// +// This file is structured in the following way: +// +// - consumeXXX functions parse an exact JSON token from a []byte. +// If the buffer appears truncated, then it returns io.ErrUnexpectedEOF. +// The consumeSimpleXXX functions are so named because they only handle +// a subset of the grammar for the JSON token being parsed. +// They do not handle the full grammar to keep these functions inlineable. +// +// - Decoder.consumeXXX methods parse the next JSON token from Decoder.buf, +// automatically fetching more input if necessary. These methods take +// a position relative to the start of Decoder.buf as an argument and +// return the end of the consumed JSON token as a position, +// also relative to the start of Decoder.buf. +// +// - In the event of an I/O errors or state machine violations, +// the implementation avoids mutating the state of Decoder +// (aside from the book-keeping needed to implement Decoder.fetch). +// For this reason, only Decoder.ReadToken and Decoder.ReadValue are +// responsible for updated Decoder.prevStart and Decoder.prevEnd. +// +// - For performance, much of the implementation uses the pattern of calling +// the inlineable consumeXXX functions first, and if more work is necessary, +// then it calls the slower Decoder.consumeXXX methods. +// TODO: Revisit this pattern if the Go compiler provides finer control +// over exactly which calls are inlined or not. + +// DecodeOptions configures how JSON decoding operates. +// The zero value is equivalent to the default settings, +// which is compliant with both RFC 7493 and RFC 8259. +type DecodeOptions struct { + requireKeyedLiterals + nonComparable + + // AllowDuplicateNames specifies that JSON objects may contain + // duplicate member names. Disabling the duplicate name check may provide + // computational and performance benefits, but breaks compliance with + // RFC 7493, section 2.3. The input will still be compliant with RFC 8259, + // which leaves the handling of duplicate names as unspecified behavior. + AllowDuplicateNames bool + + // AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, + // which will be mangled as the Unicode replacement character, U+FFFD. + // This causes the decoder to break compliance with + // RFC 7493, section 2.1, and RFC 8259, section 8.1. + AllowInvalidUTF8 bool +} + +// Decoder is a streaming decoder for raw JSON tokens and values. +// It is used to read a stream of top-level JSON values, +// each separated by optional whitespace characters. +// +// ReadToken and ReadValue calls may be interleaved. +// For example, the following JSON value: +// +// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} +// +// can be parsed with the following calls (ignoring errors for brevity): +// +// d.ReadToken() // { +// d.ReadToken() // "name" +// d.ReadToken() // "value" +// d.ReadValue() // "array" +// d.ReadToken() // [ +// d.ReadToken() // null +// d.ReadToken() // false +// d.ReadValue() // true +// d.ReadToken() // 3.14159 +// d.ReadToken() // ] +// d.ReadValue() // "object" +// d.ReadValue() // {"k":"v"} +// d.ReadToken() // } +// +// The above is one of many possible sequence of calls and +// may not represent the most sensible method to call for any given token/value. +// For example, it is probably more common to call ReadToken to obtain a +// string token for object names. +type Decoder struct { + state + decodeBuffer + options DecodeOptions + + stringCache *stringCache // only used when unmarshaling +} + +// decodeBuffer is a buffer split into 4 segments: +// +// - buf[0:prevEnd] // already read portion of the buffer +// - buf[prevStart:prevEnd] // previously read value +// - buf[prevEnd:len(buf)] // unread portion of the buffer +// - buf[len(buf):cap(buf)] // unused portion of the buffer +// +// Invariants: +// +// 0 ≤ prevStart ≤ prevEnd ≤ len(buf) ≤ cap(buf) +type decodeBuffer struct { + peekPos int // non-zero if valid offset into buf for start of next token + peekErr error // implies peekPos is -1 + + buf []byte // may alias rd if it is a bytes.Buffer + prevStart int + prevEnd int + + // baseOffset is added to prevStart and prevEnd to obtain + // the absolute offset relative to the start of io.Reader stream. + baseOffset int64 + + rd io.Reader +} + +// NewDecoder constructs a new streaming decoder reading from r. +// +// If r is a bytes.Buffer, then the decoder parses directly from the buffer +// without first copying the contents to an intermediate buffer. +// Additional writes to the buffer must not occur while the decoder is in use. +func NewDecoder(r io.Reader) *Decoder { + return DecodeOptions{}.NewDecoder(r) +} + +// NewDecoder constructs a new streaming decoder reading from r +// configured with the provided options. +func (o DecodeOptions) NewDecoder(r io.Reader) *Decoder { + d := new(Decoder) + o.ResetDecoder(d, r) + return d +} + +// ResetDecoder resets a decoder such that it is reading afresh from r and +// configured with the provided options. +func (o DecodeOptions) ResetDecoder(d *Decoder, r io.Reader) { + if d == nil { + panic("json: invalid nil Decoder") + } + if r == nil { + panic("json: invalid nil io.Reader") + } + d.reset(nil, r, o) +} + +func (d *Decoder) reset(b []byte, r io.Reader, o DecodeOptions) { + d.state.reset() + d.decodeBuffer = decodeBuffer{buf: b, rd: r} + d.options = o +} + +// Reset resets a decoder such that it is reading afresh from r but +// keep any pre-existing decoder options. +func (d *Decoder) Reset(r io.Reader) { + d.options.ResetDecoder(d, r) +} + +var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next") + +// fetch reads at least 1 byte from the underlying io.Reader. +// It returns io.ErrUnexpectedEOF if zero bytes were read and io.EOF was seen. +func (d *Decoder) fetch() error { + if d.rd == nil { + return io.ErrUnexpectedEOF + } + + // Inform objectNameStack that we are about to fetch new buffer content. + d.names.copyQuotedBuffer(d.buf) + + // Specialize bytes.Buffer for better performance. + if bb, ok := d.rd.(*bytes.Buffer); ok { + switch { + case bb.Len() == 0: + return io.ErrUnexpectedEOF + case len(d.buf) == 0: + d.buf = bb.Next(bb.Len()) // "read" all data in the buffer + return nil + default: + // This only occurs if a partially filled bytes.Buffer was provided + // and more data is written to it while Decoder is reading from it. + // This practice will lead to data corruption since future writes + // may overwrite the contents of the current buffer. + // + // The user is trying to use a bytes.Buffer as a pipe, + // but a bytes.Buffer is poor implementation of a pipe, + // the purpose-built io.Pipe should be used instead. + return &ioError{action: "read", err: errBufferWriteAfterNext} + } + } + + // Allocate initial buffer if empty. + if cap(d.buf) == 0 { + d.buf = make([]byte, 0, 64) + } + + // Check whether to grow the buffer. + const maxBufferSize = 4 << 10 + const growthSizeFactor = 2 // higher value is faster + const growthRateFactor = 2 // higher value is slower + // By default, grow if below the maximum buffer size. + grow := cap(d.buf) <= maxBufferSize/growthSizeFactor + // Growing can be expensive, so only grow + // if a sufficient number of bytes have been processed. + grow = grow && int64(cap(d.buf)) < d.previousOffsetEnd()/growthRateFactor + // If prevStart==0, then fetch was called in order to fetch more data + // to finish consuming a large JSON value contiguously. + // Grow if less than 25% of the remaining capacity is available. + // Note that this may cause the input buffer to exceed maxBufferSize. + grow = grow || (d.prevStart == 0 && len(d.buf) >= 3*cap(d.buf)/4) + + if grow { + // Allocate a new buffer and copy the contents of the old buffer over. + // TODO: Provide a hard limit on the maximum internal buffer size? + buf := make([]byte, 0, cap(d.buf)*growthSizeFactor) + d.buf = append(buf, d.buf[d.prevStart:]...) + } else { + // Move unread portion of the data to the front. + n := copy(d.buf[:cap(d.buf)], d.buf[d.prevStart:]) + d.buf = d.buf[:n] + } + d.baseOffset += int64(d.prevStart) + d.prevEnd -= d.prevStart + d.prevStart = 0 + + // Read more data into the internal buffer. + for { + n, err := d.rd.Read(d.buf[len(d.buf):cap(d.buf)]) + switch { + case n > 0: + d.buf = d.buf[:len(d.buf)+n] + return nil // ignore errors if any bytes are read + case err == io.EOF: + return io.ErrUnexpectedEOF + case err != nil: + return &ioError{action: "read", err: err} + default: + continue // Read returned (0, nil) + } + } +} + +const invalidateBufferByte = '#' // invalid starting character for JSON grammar + +// invalidatePreviousRead invalidates buffers returned by Peek and Read calls +// so that the first byte is an invalid character. +// This Hyrum-proofs the API against faulty application code that assumes +// values returned by ReadValue remain valid past subsequent Read calls. +func (d *decodeBuffer) invalidatePreviousRead() { + // Avoid mutating the buffer if d.rd is nil which implies that d.buf + // is provided by the user code and may not expect mutations. + isBytesBuffer := func(r io.Reader) bool { + _, ok := r.(*bytes.Buffer) + return ok + } + if d.rd != nil && !isBytesBuffer(d.rd) && d.prevStart < d.prevEnd && uint(d.prevStart) < uint(len(d.buf)) { + d.buf[d.prevStart] = invalidateBufferByte + d.prevStart = d.prevEnd + } +} + +// needMore reports whether there are no more unread bytes. +func (d *decodeBuffer) needMore(pos int) bool { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + return pos == len(d.buf) +} + +// injectSyntacticErrorWithPosition wraps a SyntacticError with the position, +// otherwise it returns the error as is. +// It takes a position relative to the start of the start of d.buf. +func (d *decodeBuffer) injectSyntacticErrorWithPosition(err error, pos int) error { + if serr, ok := err.(*SyntacticError); ok { + return serr.withOffset(d.baseOffset + int64(pos)) + } + return err +} + +func (d *decodeBuffer) previousOffsetStart() int64 { return d.baseOffset + int64(d.prevStart) } +func (d *decodeBuffer) previousOffsetEnd() int64 { return d.baseOffset + int64(d.prevEnd) } +func (d *decodeBuffer) previousBuffer() []byte { return d.buf[d.prevStart:d.prevEnd] } +func (d *decodeBuffer) unreadBuffer() []byte { return d.buf[d.prevEnd:len(d.buf)] } + +// PeekKind retrieves the next token kind, but does not advance the read offset. +// It returns 0 if there are no more tokens. +func (d *Decoder) PeekKind() Kind { + // Check whether we have a cached peek result. + if d.peekPos > 0 { + return Kind(d.buf[d.peekPos]).normalize() + } + + var err error + d.invalidatePreviousRead() + pos := d.prevEnd + + // Consume leading whitespace. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + d.peekPos, d.peekErr = -1, err + return invalidKind + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + d.peekPos, d.peekErr = -1, err + return invalidKind + } + } + } + next := Kind(d.buf[pos]).normalize() + if d.tokens.needDelim(next) != delim { + pos = d.prevEnd // restore position to right after leading whitespace + pos += consumeWhitespace(d.buf[pos:]) + err = d.tokens.checkDelim(delim, next) + err = d.injectSyntacticErrorWithPosition(err, pos) + d.peekPos, d.peekErr = -1, err + return invalidKind + } + + // This may set peekPos to zero, which is indistinguishable from + // the uninitialized state. While a small hit to performance, it is correct + // since ReadValue and ReadToken will disregard the cached result and + // recompute the next kind. + d.peekPos, d.peekErr = pos, nil + return next +} + +// SkipValue is semantically equivalent to calling ReadValue and discarding +// the result except that memory is not wasted trying to hold the entire result. +func (d *Decoder) SkipValue() error { + switch d.PeekKind() { + case '{', '[': + // For JSON objects and arrays, keep skipping all tokens + // until the depth matches the starting depth. + depth := d.tokens.depth() + for { + if _, err := d.ReadToken(); err != nil { + return err + } + if depth >= d.tokens.depth() { + return nil + } + } + default: + // Trying to skip a value when the next token is a '}' or ']' + // will result in an error being returned here. + if _, err := d.ReadValue(); err != nil { + return err + } + return nil + } +} + +// ReadToken reads the next Token, advancing the read offset. +// The returned token is only valid until the next Peek, Read, or Skip call. +// It returns io.EOF if there are no more tokens. +func (d *Decoder) ReadToken() (Token, error) { + // Determine the next kind. + var err error + var next Kind + pos := d.peekPos + if pos != 0 { + // Use cached peek result. + if d.peekErr != nil { + err := d.peekErr + d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error + return Token{}, err + } + next = Kind(d.buf[pos]).normalize() + d.peekPos = 0 // reset cache + } else { + d.invalidatePreviousRead() + pos = d.prevEnd + + // Consume leading whitespace. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + return Token{}, err + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return Token{}, err + } + } + } + next = Kind(d.buf[pos]).normalize() + if d.tokens.needDelim(next) != delim { + pos = d.prevEnd // restore position to right after leading whitespace + pos += consumeWhitespace(d.buf[pos:]) + err = d.tokens.checkDelim(delim, next) + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } + + // Handle the next token. + var n int + switch next { + case 'n': + if consumeNull(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "null") + if err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } else { + pos += len("null") + } + if err = d.tokens.appendLiteral(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("null")) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return Null, nil + + case 'f': + if consumeFalse(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "false") + if err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } else { + pos += len("false") + } + if err = d.tokens.appendLiteral(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("false")) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return False, nil + + case 't': + if consumeTrue(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "true") + if err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } else { + pos += len("true") + } + if err = d.tokens.appendLiteral(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("true")) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return True, nil + + case '"': + var flags valueFlags // TODO: Preserve this in Token? + if n = consumeSimpleString(d.buf[pos:]); n == 0 { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeString(&flags, pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + if err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } else { + pos += n + } + if !d.options.AllowDuplicateNames && d.tokens.last.needObjectName() { + if !d.tokens.last.isValidNamespace() { + return Token{}, errInvalidNamespace + } + if d.tokens.last.isActiveNamespace() && !d.namespaces.last().insertQuoted(d.buf[pos-n:pos], flags.isVerbatim()) { + err = &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of string + } + d.names.replaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds + } + if err = d.tokens.appendString(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of string + } + d.prevStart, d.prevEnd = pos-n, pos + return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil + + case '0': + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if n = consumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeNumber(pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + if err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + } else { + pos += n + } + if err = d.tokens.appendNumber(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of number + } + d.prevStart, d.prevEnd = pos-n, pos + return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil + + case '{': + if err = d.tokens.pushObject(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + if !d.options.AllowDuplicateNames { + d.names.push() + d.namespaces.push() + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return ObjectStart, nil + + case '}': + if err = d.tokens.popObject(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + if !d.options.AllowDuplicateNames { + d.names.pop() + d.namespaces.pop() + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return ObjectEnd, nil + + case '[': + if err = d.tokens.pushArray(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return ArrayStart, nil + + case ']': + if err = d.tokens.popArray(); err != nil { + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return ArrayEnd, nil + + default: + err = newInvalidCharacterError(d.buf[pos:], "at start of token") + return Token{}, d.injectSyntacticErrorWithPosition(err, pos) + } +} + +type valueFlags uint + +const ( + _ valueFlags = (1 << iota) / 2 // powers of two starting with zero + + stringNonVerbatim // string cannot be naively treated as valid UTF-8 + stringNonCanonical // string not formatted according to RFC 8785, section 3.2.2.2. + // TODO: Track whether a number is a non-integer? +) + +func (f *valueFlags) set(f2 valueFlags) { *f |= f2 } +func (f valueFlags) isVerbatim() bool { return f&stringNonVerbatim == 0 } +func (f valueFlags) isCanonical() bool { return f&stringNonCanonical == 0 } + +// ReadValue returns the next raw JSON value, advancing the read offset. +// The value is stripped of any leading or trailing whitespace. +// The returned value is only valid until the next Peek, Read, or Skip call and +// may not be mutated while the Decoder remains in use. +// If the decoder is currently at the end token for an object or array, +// then it reports a SyntacticError and the internal state remains unchanged. +// It returns io.EOF if there are no more values. +func (d *Decoder) ReadValue() (RawValue, error) { + var flags valueFlags + return d.readValue(&flags) +} +func (d *Decoder) readValue(flags *valueFlags) (RawValue, error) { + // Determine the next kind. + var err error + var next Kind + pos := d.peekPos + if pos != 0 { + // Use cached peek result. + if d.peekErr != nil { + err := d.peekErr + d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error + return nil, err + } + next = Kind(d.buf[pos]).normalize() + d.peekPos = 0 // reset cache + } else { + d.invalidatePreviousRead() + pos = d.prevEnd + + // Consume leading whitespace. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + return nil, err + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return nil, err + } + } + } + next = Kind(d.buf[pos]).normalize() + if d.tokens.needDelim(next) != delim { + pos = d.prevEnd // restore position to right after leading whitespace + pos += consumeWhitespace(d.buf[pos:]) + err = d.tokens.checkDelim(delim, next) + return nil, d.injectSyntacticErrorWithPosition(err, pos) + } + } + + // Handle the next value. + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeValue(flags, pos) + newAbsPos := d.baseOffset + int64(pos) + n := int(newAbsPos - oldAbsPos) + if err != nil { + return nil, d.injectSyntacticErrorWithPosition(err, pos) + } + switch next { + case 'n', 't', 'f': + err = d.tokens.appendLiteral() + case '"': + if !d.options.AllowDuplicateNames && d.tokens.last.needObjectName() { + if !d.tokens.last.isValidNamespace() { + err = errInvalidNamespace + break + } + if d.tokens.last.isActiveNamespace() && !d.namespaces.last().insertQuoted(d.buf[pos-n:pos], flags.isVerbatim()) { + err = &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} + break + } + d.names.replaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds + } + err = d.tokens.appendString() + case '0': + err = d.tokens.appendNumber() + case '{': + if err = d.tokens.pushObject(); err != nil { + break + } + if err = d.tokens.popObject(); err != nil { + panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) + } + case '[': + if err = d.tokens.pushArray(); err != nil { + break + } + if err = d.tokens.popArray(); err != nil { + panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) + } + } + if err != nil { + return nil, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of value + } + d.prevEnd = pos + d.prevStart = pos - n + return d.buf[pos-n : pos : pos], nil +} + +// checkEOF verifies that the input has no more data. +func (d *Decoder) checkEOF() error { + switch pos, err := d.consumeWhitespace(d.prevEnd); err { + case nil: + return newInvalidCharacterError(d.buf[pos:], "after top-level value") + case io.ErrUnexpectedEOF: + return nil + default: + return err + } +} + +// consumeWhitespace consumes all whitespace starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the last whitespace. +// If it returns nil, there is guaranteed to at least be one unread byte. +// +// The following pattern is common in this implementation: +// +// pos += consumeWhitespace(d.buf[pos:]) +// if d.needMore(pos) { +// if pos, err = d.consumeWhitespace(pos); err != nil { +// return ... +// } +// } +// +// It is difficult to simplify this without sacrificing performance since +// consumeWhitespace must be inlined. The body of the if statement is +// executed only in rare situations where we need to fetch more data. +// Since fetching may return an error, we also need to check the error. +func (d *Decoder) consumeWhitespace(pos int) (newPos int, err error) { + for { + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos, err + } + continue + } + return pos, nil + } +} + +// consumeValue consumes a single JSON value starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the value. +func (d *Decoder) consumeValue(flags *valueFlags, pos int) (newPos int, err error) { + for { + var n int + var err error + switch next := Kind(d.buf[pos]).normalize(); next { + case 'n': + if n = consumeNull(d.buf[pos:]); n == 0 { + n, err = consumeLiteral(d.buf[pos:], "null") + } + case 'f': + if n = consumeFalse(d.buf[pos:]); n == 0 { + n, err = consumeLiteral(d.buf[pos:], "false") + } + case 't': + if n = consumeTrue(d.buf[pos:]); n == 0 { + n, err = consumeLiteral(d.buf[pos:], "true") + } + case '"': + if n = consumeSimpleString(d.buf[pos:]); n == 0 { + return d.consumeString(flags, pos) + } + case '0': + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if n = consumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { + return d.consumeNumber(pos) + } + case '{': + return d.consumeObject(flags, pos) + case '[': + return d.consumeArray(flags, pos) + default: + return pos, newInvalidCharacterError(d.buf[pos:], "at start of value") + } + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos, err + } + continue + } + return pos + n, err + } +} + +// consumeLiteral consumes a single JSON literal starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the literal. +func (d *Decoder) consumeLiteral(pos int, lit string) (newPos int, err error) { + for { + n, err := consumeLiteral(d.buf[pos:], lit) + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos, err + } + continue + } + return pos + n, err + } +} + +// consumeString consumes a single JSON string starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the string. +func (d *Decoder) consumeString(flags *valueFlags, pos int) (newPos int, err error) { + var n int + for { + n, err = consumeStringResumable(flags, d.buf[pos:], n, !d.options.AllowInvalidUTF8) + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos, err + } + continue + } + return pos + n, err + } +} + +// consumeNumber consumes a single JSON number starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the number. +func (d *Decoder) consumeNumber(pos int) (newPos int, err error) { + var n int + var state consumeNumberState + for { + n, state, err = consumeNumberResumable(d.buf[pos:], n, state) + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if err == io.ErrUnexpectedEOF || d.needMore(pos+n) { + mayTerminate := err == nil + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + if mayTerminate && err == io.ErrUnexpectedEOF { + return pos + n, nil + } + return pos, err + } + continue + } + return pos + n, err + } +} + +// consumeObject consumes a single JSON object starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the object. +func (d *Decoder) consumeObject(flags *valueFlags, pos int) (newPos int, err error) { + var n int + var names *objectNamespace + if !d.options.AllowDuplicateNames { + d.namespaces.push() + defer d.namespaces.pop() + names = d.namespaces.last() + } + + // Handle before start. + if d.buf[pos] != '{' { + panic("BUG: consumeObject must be called with a buffer that starts with '{'") + } + pos++ + + // Handle after start. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + if d.buf[pos] == '}' { + pos++ + return pos, nil + } + + for { + // Handle before name. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + var flags2 valueFlags + if n = consumeSimpleString(d.buf[pos:]); n == 0 { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeString(&flags2, pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + flags.set(flags2) + if err != nil { + return pos, err + } + } else { + pos += n + } + if !d.options.AllowDuplicateNames && !names.insertQuoted(d.buf[pos-n:pos], flags2.isVerbatim()) { + return pos - n, &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} + } + + // Handle after name. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + if d.buf[pos] != ':' { + return pos, newInvalidCharacterError(d.buf[pos:], "after object name (expecting ':')") + } + pos++ + + // Handle before value. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + pos, err = d.consumeValue(flags, pos) + if err != nil { + return pos, err + } + + // Handle after value. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + switch d.buf[pos] { + case ',': + pos++ + continue + case '}': + pos++ + return pos, nil + default: + return pos, newInvalidCharacterError(d.buf[pos:], "after object value (expecting ',' or '}')") + } + } +} + +// consumeArray consumes a single JSON array starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the array. +func (d *Decoder) consumeArray(flags *valueFlags, pos int) (newPos int, err error) { + // Handle before start. + if d.buf[pos] != '[' { + panic("BUG: consumeArray must be called with a buffer that starts with '['") + } + pos++ + + // Handle after start. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + if d.buf[pos] == ']' { + pos++ + return pos, nil + } + + for { + // Handle before value. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + pos, err = d.consumeValue(flags, pos) + if err != nil { + return pos, err + } + + // Handle after value. + pos += consumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + switch d.buf[pos] { + case ',': + pos++ + continue + case ']': + pos++ + return pos, nil + default: + return pos, newInvalidCharacterError(d.buf[pos:], "after array value (expecting ',' or ']')") + } + } +} + +// InputOffset returns the current input byte offset. It gives the location +// of the next byte immediately after the most recently returned token or value. +// The number of bytes actually read from the underlying io.Reader may be more +// than this offset due to internal buffering effects. +func (d *Decoder) InputOffset() int64 { + return d.previousOffsetEnd() +} + +// UnreadBuffer returns the data remaining in the unread buffer, +// which may contain zero or more bytes. +// The returned buffer must not be mutated while Decoder continues to be used. +// The buffer contents are valid until the next Peek, Read, or Skip call. +func (d *Decoder) UnreadBuffer() []byte { + return d.unreadBuffer() +} + +// StackDepth returns the depth of the state machine for read JSON data. +// Each level on the stack represents a nested JSON object or array. +// It is incremented whenever an ObjectStart or ArrayStart token is encountered +// and decremented whenever an ObjectEnd or ArrayEnd token is encountered. +// The depth is zero-indexed, where zero represents the top-level JSON value. +func (d *Decoder) StackDepth() int { + // NOTE: Keep in sync with Encoder.StackDepth. + return d.tokens.depth() - 1 +} + +// StackIndex returns information about the specified stack level. +// It must be a number between 0 and StackDepth, inclusive. +// For each level, it reports the kind: +// +// - 0 for a level of zero, +// - '{' for a level representing a JSON object, and +// - '[' for a level representing a JSON array. +// +// It also reports the length of that JSON object or array. +// Each name and value in a JSON object is counted separately, +// so the effective number of members would be half the length. +// A complete JSON object must have an even length. +func (d *Decoder) StackIndex(i int) (Kind, int) { + // NOTE: Keep in sync with Encoder.StackIndex. + switch s := d.tokens.index(i); { + case i > 0 && s.isObject(): + return '{', s.length() + case i > 0 && s.isArray(): + return '[', s.length() + default: + return 0, s.length() + } +} + +// StackPointer returns a JSON Pointer (RFC 6901) to the most recently read value. +// Object names are only present if AllowDuplicateNames is false, otherwise +// object members are represented using their index within the object. +func (d *Decoder) StackPointer() string { + d.names.copyQuotedBuffer(d.buf) + return string(d.appendStackPointer(nil)) +} + +// consumeWhitespace consumes leading JSON whitespace per RFC 7159, section 2. +func consumeWhitespace(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + for len(b) > n && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { + n++ + } + return n +} + +// consumeNull consumes the next JSON null literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func consumeNull(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + const literal = "null" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// consumeFalse consumes the next JSON false literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func consumeFalse(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + const literal = "false" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// consumeTrue consumes the next JSON true literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func consumeTrue(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + const literal = "true" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// consumeLiteral consumes the next JSON literal per RFC 7159, section 3. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +func consumeLiteral(b []byte, lit string) (n int, err error) { + for i := 0; i < len(b) && i < len(lit); i++ { + if b[i] != lit[i] { + return i, newInvalidCharacterError(b[i:], "within literal "+lit+" (expecting "+strconv.QuoteRune(rune(lit[i]))+")") + } + } + if len(b) < len(lit) { + return len(b), io.ErrUnexpectedEOF + } + return len(lit), nil +} + +// consumeSimpleString consumes the next JSON string per RFC 7159, section 7 +// but is limited to the grammar for an ASCII string without escape sequences. +// It returns 0 if it is invalid or more complicated than a simple string, +// in which case consumeString should be called. +func consumeSimpleString(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + if len(b) > 0 && b[0] == '"' { + n++ + for len(b) > n && (' ' <= b[n] && b[n] != '\\' && b[n] != '"' && b[n] < utf8.RuneSelf) { + n++ + } + if len(b) > n && b[n] == '"' { + n++ + return n + } + } + return 0 +} + +// consumeString consumes the next JSON string per RFC 7159, section 7. +// If validateUTF8 is false, then this allows the presence of invalid UTF-8 +// characters within the string itself. +// It reports the number of bytes consumed and whether an error was encountered. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +func consumeString(flags *valueFlags, b []byte, validateUTF8 bool) (n int, err error) { + return consumeStringResumable(flags, b, 0, validateUTF8) +} + +// consumeStringResumable is identical to consumeString but supports resuming +// from a previous call that returned io.ErrUnexpectedEOF. +func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, validateUTF8 bool) (n int, err error) { + // Consume the leading double quote. + switch { + case resumeOffset > 0: + n = resumeOffset // already handled the leading quote + case uint(len(b)) == 0: + return n, io.ErrUnexpectedEOF + case b[0] == '"': + n++ + default: + return n, newInvalidCharacterError(b[n:], `at start of string (expecting '"')`) + } + + // Consume every character in the string. + for uint(len(b)) > uint(n) { + // Optimize for long sequences of unescaped characters. + noEscape := func(c byte) bool { + return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' + } + for uint(len(b)) > uint(n) && noEscape(b[n]) { + n++ + } + if uint(len(b)) <= uint(n) { + return n, io.ErrUnexpectedEOF + } + + // Check for terminating double quote. + if b[n] == '"' { + n++ + return n, nil + } + + switch r, rn := utf8.DecodeRune(b[n:]); { + // Handle UTF-8 encoded byte sequence. + // Due to specialized handling of ASCII above, we know that + // all normal sequences at this point must be 2 bytes or larger. + case rn > 1: + n += rn + // Handle escape sequence. + case r == '\\': + flags.set(stringNonVerbatim) + resumeOffset = n + if uint(len(b)) < uint(n+2) { + return resumeOffset, io.ErrUnexpectedEOF + } + switch r := b[n+1]; r { + case '/': + // Forward slash is the only character with 3 representations. + // Per RFC 8785, section 3.2.2.2., this must not be escaped. + flags.set(stringNonCanonical) + n += 2 + case '"', '\\', 'b', 'f', 'n', 'r', 't': + n += 2 + case 'u': + if uint(len(b)) < uint(n+6) { + if !hasEscapeSequencePrefix(b[n:]) { + flags.set(stringNonCanonical) + return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:])) + " within string"} + } + return resumeOffset, io.ErrUnexpectedEOF + } + v1, ok := parseHexUint16(b[n+2 : n+6]) + if !ok { + flags.set(stringNonCanonical) + return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} + } + // Only certain control characters can use the \uFFFF notation + // for canonical formatting (per RFC 8785, section 3.2.2.2.). + switch v1 { + // \uFFFF notation not permitted for these characters. + case '\b', '\f', '\n', '\r', '\t': + flags.set(stringNonCanonical) + default: + // \uFFFF notation only permitted for control characters. + if v1 >= ' ' { + flags.set(stringNonCanonical) + } else { + // \uFFFF notation must be lower case. + for _, c := range b[n+2 : n+6] { + if 'A' <= c && c <= 'F' { + flags.set(stringNonCanonical) + } + } + } + } + n += 6 + + if validateUTF8 && utf16.IsSurrogate(rune(v1)) { + if uint(len(b)) >= uint(n+2) && (b[n] != '\\' || b[n+1] != 'u') { + return n, &SyntacticError{str: "invalid unpaired surrogate half within string"} + } + if uint(len(b)) < uint(n+6) { + if !hasEscapeSequencePrefix(b[n:]) { + flags.set(stringNonCanonical) + return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:])) + " within string"} + } + return resumeOffset, io.ErrUnexpectedEOF + } + v2, ok := parseHexUint16(b[n+2 : n+6]) + if !ok { + return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} + } + if utf16.DecodeRune(rune(v1), rune(v2)) == utf8.RuneError { + return n, &SyntacticError{str: "invalid surrogate pair in string"} + } + n += 6 + } + default: + flags.set(stringNonCanonical) + return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+2])) + " within string"} + } + // Handle invalid UTF-8. + case r == utf8.RuneError: + if !utf8.FullRune(b[n:]) { + return n, io.ErrUnexpectedEOF + } + flags.set(stringNonVerbatim | stringNonCanonical) + if validateUTF8 { + return n, &SyntacticError{str: "invalid UTF-8 within string"} + } + n++ + // Handle invalid control characters. + case r < ' ': + flags.set(stringNonVerbatim | stringNonCanonical) + return n, newInvalidCharacterError(b[n:], "within string (expecting non-control character)") + default: + panic("BUG: unhandled character " + quoteRune(b[n:])) + } + } + return n, io.ErrUnexpectedEOF +} + +// hasEscapeSequencePrefix reports whether b is possibly +// the truncated prefix of a \uFFFF escape sequence. +func hasEscapeSequencePrefix(b []byte) bool { + for i, c := range b { + switch { + case i == 0 && c != '\\': + return false + case i == 1 && c != 'u': + return false + case i >= 2 && i < 6 && !('0' <= c && c <= '9') && !('a' <= c && c <= 'f') && !('A' <= c && c <= 'F'): + return false + } + } + return true +} + +// unescapeString appends the unescaped form of a JSON string in src to dst. +// Any invalid UTF-8 within the string will be replaced with utf8.RuneError. +// The input must be an entire JSON string with no surrounding whitespace. +func unescapeString(dst, src []byte) (v []byte, ok bool) { + // Consume leading double quote. + if uint(len(src)) == 0 || src[0] != '"' { + return dst, false + } + i, n := 1, 1 + + // Consume every character until completion. + for uint(len(src)) > uint(n) { + // Optimize for long sequences of unescaped characters. + noEscape := func(c byte) bool { + return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' + } + for uint(len(src)) > uint(n) && noEscape(src[n]) { + n++ + } + if uint(len(src)) <= uint(n) { + break + } + + // Check for terminating double quote. + if src[n] == '"' { + dst = append(dst, src[i:n]...) + n++ + return dst, len(src) == n + } + + switch r, rn := utf8.DecodeRune(src[n:]); { + // Handle UTF-8 encoded byte sequence. + // Due to specialized handling of ASCII above, we know that + // all normal sequences at this point must be 2 bytes or larger. + case rn > 1: + n += rn + // Handle escape sequence. + case r == '\\': + dst = append(dst, src[i:n]...) + if r < ' ' { + return dst, false // invalid control character or unescaped quote + } + + // Handle escape sequence. + if uint(len(src)) < uint(n+2) { + return dst, false // truncated escape sequence + } + switch r := src[n+1]; r { + case '"', '\\', '/': + dst = append(dst, r) + n += 2 + case 'b': + dst = append(dst, '\b') + n += 2 + case 'f': + dst = append(dst, '\f') + n += 2 + case 'n': + dst = append(dst, '\n') + n += 2 + case 'r': + dst = append(dst, '\r') + n += 2 + case 't': + dst = append(dst, '\t') + n += 2 + case 'u': + if uint(len(src)) < uint(n+6) { + return dst, false // truncated escape sequence + } + v1, ok := parseHexUint16(src[n+2 : n+6]) + if !ok { + return dst, false // invalid escape sequence + } + n += 6 + + // Check whether this is a surrogate half. + r := rune(v1) + if utf16.IsSurrogate(r) { + r = utf8.RuneError // assume failure unless the following succeeds + if uint(len(src)) >= uint(n+6) && src[n+0] == '\\' && src[n+1] == 'u' { + if v2, ok := parseHexUint16(src[n+2 : n+6]); ok { + if r = utf16.DecodeRune(rune(v1), rune(v2)); r != utf8.RuneError { + n += 6 + } + } + } + } + + dst = utf8.AppendRune(dst, r) + default: + return dst, false // invalid escape sequence + } + i = n + // Handle invalid UTF-8. + case r == utf8.RuneError: + // NOTE: An unescaped string may be longer than the escaped string + // because invalid UTF-8 bytes are being replaced. + dst = append(dst, src[i:n]...) + dst = append(dst, "\uFFFD"...) + n += rn + i = n + // Handle invalid control characters. + case r < ' ': + dst = append(dst, src[i:n]...) + return dst, false // invalid control character or unescaped quote + default: + panic("BUG: unhandled character " + quoteRune(src[n:])) + } + } + dst = append(dst, src[i:n]...) + return dst, false // truncated input +} + +// unescapeStringMayCopy returns the unescaped form of b. +// If there are no escaped characters, the output is simply a subslice of +// the input with the surrounding quotes removed. +// Otherwise, a new buffer is allocated for the output. +func unescapeStringMayCopy(b []byte, isVerbatim bool) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + if isVerbatim { + return b[len(`"`) : len(b)-len(`"`)] + } + b, _ = unescapeString(make([]byte, 0, len(b)), b) + return b +} + +// consumeSimpleNumber consumes the next JSON number per RFC 7159, section 6 +// but is limited to the grammar for a positive integer. +// It returns 0 if it is invalid or more complicated than a simple integer, +// in which case consumeNumber should be called. +func consumeSimpleNumber(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + if len(b) > 0 { + if b[0] == '0' { + n++ + } else if '1' <= b[0] && b[0] <= '9' { + n++ + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + } else { + return 0 + } + if len(b) == n || !(b[n] == '.' || b[n] == 'e' || b[n] == 'E') { + return n + } + } + return 0 +} + +type consumeNumberState uint + +const ( + consumeNumberInit consumeNumberState = iota + beforeIntegerDigits + withinIntegerDigits + beforeFractionalDigits + withinFractionalDigits + beforeExponentDigits + withinExponentDigits +) + +// consumeNumber consumes the next JSON number per RFC 7159, section 6. +// It reports the number of bytes consumed and whether an error was encountered. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +// +// Note that JSON numbers are not self-terminating. +// If the entire input is consumed, then the caller needs to consider whether +// there may be subsequent unread data that may still be part of this number. +func consumeNumber(b []byte) (n int, err error) { + n, _, err = consumeNumberResumable(b, 0, consumeNumberInit) + return n, err +} + +// consumeNumberResumable is identical to consumeNumber but supports resuming +// from a previous call that returned io.ErrUnexpectedEOF. +func consumeNumberResumable(b []byte, resumeOffset int, state consumeNumberState) (n int, _ consumeNumberState, err error) { + // Jump to the right state when resuming from a partial consumption. + n = resumeOffset + if state > consumeNumberInit { + switch state { + case withinIntegerDigits, withinFractionalDigits, withinExponentDigits: + // Consume leading digits. + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + if len(b) == n { + return n, state, nil // still within the same state + } + state++ // switches "withinX" to "beforeY" where Y is the state after X + } + switch state { + case beforeIntegerDigits: + goto beforeInteger + case beforeFractionalDigits: + goto beforeFractional + case beforeExponentDigits: + goto beforeExponent + default: + return n, state, nil + } + } + + // Consume required integer component (with optional minus sign). +beforeInteger: + resumeOffset = n + if len(b) > 0 && b[0] == '-' { + n++ + } + switch { + case len(b) == n: + return resumeOffset, beforeIntegerDigits, io.ErrUnexpectedEOF + case b[n] == '0': + n++ + state = beforeFractionalDigits + case '1' <= b[n] && b[n] <= '9': + n++ + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinIntegerDigits + default: + return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") + } + + // Consume optional fractional component. +beforeFractional: + if len(b) > n && b[n] == '.' { + resumeOffset = n + n++ + switch { + case len(b) == n: + return resumeOffset, beforeFractionalDigits, io.ErrUnexpectedEOF + case '0' <= b[n] && b[n] <= '9': + n++ + default: + return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") + } + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinFractionalDigits + } + + // Consume optional exponent component. +beforeExponent: + if len(b) > n && (b[n] == 'e' || b[n] == 'E') { + resumeOffset = n + n++ + if len(b) > n && (b[n] == '-' || b[n] == '+') { + n++ + } + switch { + case len(b) == n: + return resumeOffset, beforeExponentDigits, io.ErrUnexpectedEOF + case '0' <= b[n] && b[n] <= '9': + n++ + default: + return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") + } + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinExponentDigits + } + + return n, state, nil +} + +// parseHexUint16 is similar to strconv.ParseUint, +// but operates directly on []byte and is optimized for base-16. +// See https://go.dev/issue/42429. +func parseHexUint16(b []byte) (v uint16, ok bool) { + if len(b) != 4 { + return 0, false + } + for _, c := range b[:4] { + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = 10 + c - 'a' + case 'A' <= c && c <= 'F': + c = 10 + c - 'A' + default: + return 0, false + } + v = v*16 + uint16(c) + } + return v, true +} + +// parseDecUint is similar to strconv.ParseUint, +// but operates directly on []byte and is optimized for base-10. +// If the number is syntactically valid but overflows uint64, +// then it returns (math.MaxUint64, false). +// See https://go.dev/issue/42429. +func parseDecUint(b []byte) (v uint64, ok bool) { + // Overflow logic is based on strconv/atoi.go:138-149 from Go1.15, where: + // - cutoff is equal to math.MaxUint64/10+1, and + // - the n1 > maxVal check is unnecessary + // since maxVal is equivalent to math.MaxUint64. + var n int + var overflow bool + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + overflow = overflow || v >= math.MaxUint64/10+1 + v *= 10 + + v1 := v + uint64(b[n]-'0') + overflow = overflow || v1 < v + v = v1 + + n++ + } + if n == 0 || len(b) != n { + return 0, false + } + if overflow { + return math.MaxUint64, false + } + return v, true +} + +// parseFloat parses a floating point number according to the Go float grammar. +// Note that the JSON number grammar is a strict subset. +// +// If the number overflows the finite representation of a float, +// then we return MaxFloat since any finite value will always be infinitely +// more accurate at representing another finite value than an infinite value. +func parseFloat(b []byte, bits int) (v float64, ok bool) { + // Fast path for exact integer numbers which fit in the + // 24-bit or 53-bit significand of a float32 or float64. + var negLen int // either 0 or 1 + if len(b) > 0 && b[0] == '-' { + negLen = 1 + } + u, ok := parseDecUint(b[negLen:]) + if ok && ((bits == 32 && u <= 1<<24) || (bits == 64 && u <= 1<<53)) { + return math.Copysign(float64(u), float64(-1*negLen)), true + } + + // Note that the []byte->string conversion unfortunately allocates. + // See https://go.dev/issue/42429 for more information. + fv, err := strconv.ParseFloat(string(b), bits) + if math.IsInf(fv, 0) { + switch { + case bits == 32 && math.IsInf(fv, +1): + return +math.MaxFloat32, true + case bits == 64 && math.IsInf(fv, +1): + return +math.MaxFloat64, true + case bits == 32 && math.IsInf(fv, -1): + return -math.MaxFloat32, true + case bits == 64 && math.IsInf(fv, -1): + return -math.MaxFloat64, true + } + } + return fv, err == nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go new file mode 100644 index 00000000000..e4eefa3de9f --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go @@ -0,0 +1,182 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package json implements serialization of JSON +// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785. +// JSON is a simple data interchange format that can represent +// primitive data types such as booleans, strings, and numbers, +// in addition to structured data types such as objects and arrays. +// +// # Terminology +// +// This package uses the terms "encode" and "decode" for syntactic functionality +// that is concerned with processing JSON based on its grammar, and +// uses the terms "marshal" and "unmarshal" for semantic functionality +// that determines the meaning of JSON values as Go values and vice-versa. +// It aims to provide a clear distinction between functionality that +// is purely concerned with encoding versus that of marshaling. +// For example, one can directly encode a stream of JSON tokens without +// needing to marshal a concrete Go value representing them. +// Similarly, one can decode a stream of JSON tokens without +// needing to unmarshal them into a concrete Go value. +// +// This package uses JSON terminology when discussing JSON, which may differ +// from related concepts in Go or elsewhere in computing literature. +// +// - A JSON "object" refers to an unordered collection of name/value members. +// - A JSON "array" refers to an ordered sequence of elements. +// - A JSON "value" refers to either a literal (i.e., null, false, or true), +// string, number, object, or array. +// +// See RFC 8259 for more information. +// +// # Specifications +// +// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, +// and RFC 8785. Each RFC is generally a stricter subset of another RFC. +// In increasing order of strictness: +// +// - RFC 4627 and RFC 7159 do not require (but recommend) the use of UTF-8 +// and also do not require (but recommend) that object names be unique. +// - RFC 8259 requires the use of UTF-8, +// but does not require (but recommends) that object names be unique. +// - RFC 7493 requires the use of UTF-8 +// and also requires that object names be unique. +// - RFC 8785 defines a canonical representation. It requires the use of UTF-8 +// and also requires that object names be unique and in a specific ordering. +// It specifies exactly how strings and numbers must be formatted. +// +// The primary difference between RFC 4627 and RFC 7159 is that the former +// restricted top-level values to only JSON objects and arrays, while +// RFC 7159 and subsequent RFCs permit top-level values to additionally be +// JSON nulls, booleans, strings, or numbers. +// +// By default, this package operates on RFC 7493, but can be configured +// to operate according to the other RFC specifications. +// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it. +// In particular, it makes specific choices about behavior that RFC 8259 +// leaves as undefined in order to ensure greater interoperability. +// +// # JSON Representation of Go structs +// +// A Go struct is naturally represented as a JSON object, +// where each Go struct field corresponds with a JSON object member. +// When marshaling, all Go struct fields are recursively encoded in depth-first +// order as JSON object members except those that are ignored or omitted. +// When unmarshaling, JSON object members are recursively decoded +// into the corresponding Go struct fields. +// Object members that do not match any struct fields, +// also known as “unknown members”, are ignored by default or rejected +// if UnmarshalOptions.RejectUnknownMembers is specified. +// +// The representation of each struct field can be customized in the +// "json" struct field tag, where the tag is a comma separated list of options. +// As a special case, if the entire tag is `json:"-"`, +// then the field is ignored with regard to its JSON representation. +// +// The first option is the JSON object name override for the Go struct field. +// If the name is not specified, then the Go struct field name +// is used as the JSON object name. JSON names containing commas or quotes, +// or names identical to "" or "-", can be specified using +// a single-quoted string literal, where the syntax is identical to +// the Go grammar for a double-quoted string literal, +// but instead uses single quotes as the delimiters. +// By default, unmarshaling uses case-sensitive matching to identify +// the Go struct field associated with a JSON object name. +// +// After the name, the following tag options are supported: +// +// - omitzero: When marshaling, the "omitzero" option specifies that +// the struct field should be omitted if the field value is zero +// as determined by the "IsZero() bool" method if present, +// otherwise based on whether the field is the zero Go value. +// This option has no effect when unmarshaling. +// +// - omitempty: When marshaling, the "omitempty" option specifies that +// the struct field should be omitted if the field value would have been +// encoded as a JSON null, empty string, empty object, or empty array. +// This option has no effect when unmarshaling. +// +// - string: The "string" option specifies that +// MarshalOptions.StringifyNumbers and UnmarshalOptions.StringifyNumbers +// be set when marshaling or unmarshaling a struct field value. +// This causes numeric types to be encoded as a JSON number +// within a JSON string, and to be decoded from either a JSON number or +// a JSON string containing a JSON number. +// This extra level of encoding is often necessary since +// many JSON parsers cannot precisely represent 64-bit integers. +// +// - nocase: When unmarshaling, the "nocase" option specifies that +// if the JSON object name does not exactly match the JSON name +// for any of the struct fields, then it attempts to match the struct field +// using a case-insensitive match that also ignores dashes and underscores. +// If multiple fields match, the first declared field in breadth-first order +// takes precedence. This option has no effect when marshaling. +// +// - inline: The "inline" option specifies that +// the JSON representable content of this field type is to be promoted +// as if they were specified in the parent struct. +// It is the JSON equivalent of Go struct embedding. +// A Go embedded field is implicitly inlined unless an explicit JSON name +// is specified. The inlined field must be a Go struct +// (that does not implement any JSON methods), RawValue, map[string]T, +// or an unnamed pointer to such types. When marshaling, +// inlined fields from a pointer type are omitted if it is nil. +// Inlined fields of type RawValue and map[string]T are called +// “inlined fallbacks” as they can represent all possible +// JSON object members not directly handled by the parent struct. +// Only one inlined fallback field may be specified in a struct, +// while many non-fallback fields may be specified. This option +// must not be specified with any other option (including the JSON name). +// +// - unknown: The "unknown" option is a specialized variant +// of the inlined fallback to indicate that this Go struct field +// contains any number of unknown JSON object members. The field type +// must be a RawValue, map[string]T, or an unnamed pointer to such types. +// If MarshalOptions.DiscardUnknownMembers is specified when marshaling, +// the contents of this field are ignored. +// If UnmarshalOptions.RejectUnknownMembers is specified when unmarshaling, +// any unknown object members are rejected regardless of whether +// an inlined fallback with the "unknown" option exists. This option +// must not be specified with any other option (including the JSON name). +// +// - format: The "format" option specifies a format flag +// used to specialize the formatting of the field value. +// The option is a key-value pair specified as "format:value" where +// the value must be either a literal consisting of letters and numbers +// (e.g., "format:RFC3339") or a single-quoted string literal +// (e.g., "format:'2006-01-02'"). The interpretation of the format flag +// is determined by the struct field type. +// +// The "omitzero" and "omitempty" options are mostly semantically identical. +// The former is defined in terms of the Go type system, +// while the latter in terms of the JSON type system. +// Consequently they behave differently in some circumstances. +// For example, only a nil slice or map is omitted under "omitzero", while +// an empty slice or map is omitted under "omitempty" regardless of nilness. +// The "omitzero" option is useful for types with a well-defined zero value +// (e.g., netip.Addr) or have an IsZero method (e.g., time.Time). +// +// Every Go struct corresponds to a list of JSON representable fields +// which is constructed by performing a breadth-first search over +// all struct fields (excluding unexported or ignored fields), +// where the search recursively descends into inlined structs. +// The set of non-inlined fields in a struct must have unique JSON names. +// If multiple fields all have the same JSON name, then the one +// at shallowest depth takes precedence and the other fields at deeper depths +// are excluded from the list of JSON representable fields. +// If multiple fields at the shallowest depth have the same JSON name, +// then all of those fields are excluded from the list. This is analogous to +// Go visibility rules for struct field selection with embedded struct types. +// +// Marshaling or unmarshaling a non-empty struct +// without any JSON representable fields results in a SemanticError. +// Unexported fields must not have any `json` tags except for `json:"-"`. +package json + +// requireKeyedLiterals can be embedded in a struct to require keyed literals. +type requireKeyedLiterals struct{} + +// nonComparable can be embedded in a struct to prevent comparability. +type nonComparable [0]func() diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go new file mode 100644 index 00000000000..5b81ca15af9 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go @@ -0,0 +1,1170 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "io" + "math" + "math/bits" + "strconv" + "unicode/utf16" + "unicode/utf8" +) + +// EncodeOptions configures how JSON encoding operates. +// The zero value is equivalent to the default settings, +// which is compliant with both RFC 7493 and RFC 8259. +type EncodeOptions struct { + requireKeyedLiterals + nonComparable + + // multiline specifies whether the encoder should emit multiline output. + multiline bool + + // omitTopLevelNewline specifies whether to omit the newline + // that is appended after every top-level JSON value when streaming. + omitTopLevelNewline bool + + // AllowDuplicateNames specifies that JSON objects may contain + // duplicate member names. Disabling the duplicate name check may provide + // performance benefits, but breaks compliance with RFC 7493, section 2.3. + // The output will still be compliant with RFC 8259, + // which leaves the handling of duplicate names as unspecified behavior. + AllowDuplicateNames bool + + // AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, + // which will be mangled as the Unicode replacement character, U+FFFD. + // This causes the encoder to break compliance with + // RFC 7493, section 2.1, and RFC 8259, section 8.1. + AllowInvalidUTF8 bool + + // preserveRawStrings specifies that WriteToken and WriteValue should not + // reformat any JSON string, but keep the formatting verbatim. + preserveRawStrings bool + + // canonicalizeNumbers specifies that WriteToken and WriteValue should + // reformat any JSON numbers according to RFC 8785, section 3.2.2.3. + canonicalizeNumbers bool + + // EscapeRune reports whether the provided character should be escaped + // as a hexadecimal Unicode codepoint (e.g., \ufffd). + // If nil, the shortest and simplest encoding will be used, + // which is also the formatting specified by RFC 8785, section 3.2.2.2. + EscapeRune func(rune) bool + + // Indent (if non-empty) specifies that the encoder should emit multiline + // output where each element in a JSON object or array begins on a new, + // indented line beginning with the indent prefix followed by one or more + // copies of indent according to the indentation nesting. + // It may only be composed of space or tab characters. + Indent string + + // IndentPrefix is prepended to each line within a JSON object or array. + // The purpose of the indent prefix is to encode data that can more easily + // be embedded inside other formatted JSON data. + // It may only be composed of space or tab characters. + // It is ignored if Indent is empty. + IndentPrefix string +} + +// Encoder is a streaming encoder from raw JSON tokens and values. +// It is used to write a stream of top-level JSON values, +// each terminated with a newline character. +// +// WriteToken and WriteValue calls may be interleaved. +// For example, the following JSON value: +// +// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} +// +// can be composed with the following calls (ignoring errors for brevity): +// +// e.WriteToken(ObjectStart) // { +// e.WriteToken(String("name")) // "name" +// e.WriteToken(String("value")) // "value" +// e.WriteValue(RawValue(`"array"`)) // "array" +// e.WriteToken(ArrayStart) // [ +// e.WriteToken(Null) // null +// e.WriteToken(False) // false +// e.WriteValue(RawValue("true")) // true +// e.WriteToken(Float(3.14159)) // 3.14159 +// e.WriteToken(ArrayEnd) // ] +// e.WriteValue(RawValue(`"object"`)) // "object" +// e.WriteValue(RawValue(`{"k":"v"}`)) // {"k":"v"} +// e.WriteToken(ObjectEnd) // } +// +// The above is one of many possible sequence of calls and +// may not represent the most sensible method to call for any given token/value. +// For example, it is probably more common to call WriteToken with a string +// for object names. +type Encoder struct { + state + encodeBuffer + options EncodeOptions + + seenPointers seenPointers // only used when marshaling +} + +// encodeBuffer is a buffer split into 2 segments: +// +// - buf[0:len(buf)] // written (but unflushed) portion of the buffer +// - buf[len(buf):cap(buf)] // unused portion of the buffer +type encodeBuffer struct { + buf []byte // may alias wr if it is a bytes.Buffer + + // baseOffset is added to len(buf) to obtain the absolute offset + // relative to the start of io.Writer stream. + baseOffset int64 + + wr io.Writer + + // maxValue is the approximate maximum RawValue size passed to WriteValue. + maxValue int + // unusedCache is the buffer returned by the UnusedBuffer method. + unusedCache []byte + // bufStats is statistics about buffer utilization. + // It is only used with pooled encoders in pools.go. + bufStats bufferStatistics +} + +// NewEncoder constructs a new streaming encoder writing to w. +func NewEncoder(w io.Writer) *Encoder { + return EncodeOptions{}.NewEncoder(w) +} + +// NewEncoder constructs a new streaming encoder writing to w +// configured with the provided options. +// It flushes the internal buffer when the buffer is sufficiently full or +// when a top-level value has been written. +// +// If w is a bytes.Buffer, then the encoder appends directly into the buffer +// without copying the contents from an intermediate buffer. +func (o EncodeOptions) NewEncoder(w io.Writer) *Encoder { + e := new(Encoder) + o.ResetEncoder(e, w) + return e +} + +// ResetEncoder resets an encoder such that it is writing afresh to w and +// configured with the provided options. +func (o EncodeOptions) ResetEncoder(e *Encoder, w io.Writer) { + if e == nil { + panic("json: invalid nil Encoder") + } + if w == nil { + panic("json: invalid nil io.Writer") + } + e.reset(nil, w, o) +} + +func (e *Encoder) reset(b []byte, w io.Writer, o EncodeOptions) { + if len(o.Indent) > 0 { + o.multiline = true + if s := trimLeftSpaceTab(o.IndentPrefix); len(s) > 0 { + panic("json: invalid character " + quoteRune([]byte(s)) + " in indent prefix") + } + if s := trimLeftSpaceTab(o.Indent); len(s) > 0 { + panic("json: invalid character " + quoteRune([]byte(s)) + " in indent") + } + } + e.state.reset() + e.encodeBuffer = encodeBuffer{buf: b, wr: w, bufStats: e.bufStats} + e.options = o + if bb, ok := w.(*bytes.Buffer); ok && bb != nil { + e.buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb + } +} + +// Reset resets an encoder such that it is writing afresh to w but +// keeps any pre-existing encoder options. +func (e *Encoder) Reset(w io.Writer) { + e.options.ResetEncoder(e, w) +} + +// needFlush determines whether to flush at this point. +func (e *Encoder) needFlush() bool { + // NOTE: This function is carefully written to be inlineable. + + // Avoid flushing if e.wr is nil since there is no underlying writer. + // Flush if less than 25% of the capacity remains. + // Flushing at some constant fraction ensures that the buffer stops growing + // so long as the largest Token or Value fits within that unused capacity. + return e.wr != nil && (e.tokens.depth() == 1 || len(e.buf) > 3*cap(e.buf)/4) +} + +// flush flushes the buffer to the underlying io.Writer. +// It may append a trailing newline after the top-level value. +func (e *Encoder) flush() error { + if e.wr == nil || e.avoidFlush() { + return nil + } + + // In streaming mode, always emit a newline after the top-level value. + if e.tokens.depth() == 1 && !e.options.omitTopLevelNewline { + e.buf = append(e.buf, '\n') + } + + // Inform objectNameStack that we are about to flush the buffer content. + e.names.copyQuotedBuffer(e.buf) + + // Specialize bytes.Buffer for better performance. + if bb, ok := e.wr.(*bytes.Buffer); ok { + // If e.buf already aliases the internal buffer of bb, + // then the Write call simply increments the internal offset, + // otherwise Write operates as expected. + // See https://go.dev/issue/42986. + n, _ := bb.Write(e.buf) // never fails unless bb is nil + e.baseOffset += int64(n) + + // If the internal buffer of bytes.Buffer is too small, + // append operations elsewhere in the Encoder may grow the buffer. + // This would be semantically correct, but hurts performance. + // As such, ensure 25% of the current length is always available + // to reduce the probability that other appends must allocate. + if avail := bb.Cap() - bb.Len(); avail < bb.Len()/4 { + bb.Grow(avail + 1) + } + + e.buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb + return nil + } + + // Flush the internal buffer to the underlying io.Writer. + n, err := e.wr.Write(e.buf) + e.baseOffset += int64(n) + if err != nil { + // In the event of an error, preserve the unflushed portion. + // Thus, write errors aren't fatal so long as the io.Writer + // maintains consistent state after errors. + if n > 0 { + e.buf = e.buf[:copy(e.buf, e.buf[n:])] + } + return &ioError{action: "write", err: err} + } + e.buf = e.buf[:0] + + // Check whether to grow the buffer. + // Note that cap(e.buf) may already exceed maxBufferSize since + // an append elsewhere already grew it to store a large token. + const maxBufferSize = 4 << 10 + const growthSizeFactor = 2 // higher value is faster + const growthRateFactor = 2 // higher value is slower + // By default, grow if below the maximum buffer size. + grow := cap(e.buf) <= maxBufferSize/growthSizeFactor + // Growing can be expensive, so only grow + // if a sufficient number of bytes have been processed. + grow = grow && int64(cap(e.buf)) < e.previousOffsetEnd()/growthRateFactor + if grow { + e.buf = make([]byte, 0, cap(e.buf)*growthSizeFactor) + } + + return nil +} + +func (e *encodeBuffer) previousOffsetEnd() int64 { return e.baseOffset + int64(len(e.buf)) } +func (e *encodeBuffer) unflushedBuffer() []byte { return e.buf } + +// avoidFlush indicates whether to avoid flushing to ensure there is always +// enough in the buffer to unwrite the last object member if it were empty. +func (e *Encoder) avoidFlush() bool { + switch { + case e.tokens.last.length() == 0: + // Never flush after ObjectStart or ArrayStart since we don't know yet + // if the object or array will end up being empty. + return true + case e.tokens.last.needObjectValue(): + // Never flush before the object value since we don't know yet + // if the object value will end up being empty. + return true + case e.tokens.last.needObjectName() && len(e.buf) >= 2: + // Never flush after the object value if it does turn out to be empty. + switch string(e.buf[len(e.buf)-2:]) { + case `ll`, `""`, `{}`, `[]`: // last two bytes of every empty value + return true + } + } + return false +} + +// unwriteEmptyObjectMember unwrites the last object member if it is empty +// and reports whether it performed an unwrite operation. +func (e *Encoder) unwriteEmptyObjectMember(prevName *string) bool { + if last := e.tokens.last; !last.isObject() || !last.needObjectName() || last.length() == 0 { + panic("BUG: must be called on an object after writing a value") + } + + // The flushing logic is modified to never flush a trailing empty value. + // The encoder never writes trailing whitespace eagerly. + b := e.unflushedBuffer() + + // Detect whether the last value was empty. + var n int + if len(b) >= 3 { + switch string(b[len(b)-2:]) { + case "ll": // last two bytes of `null` + n = len(`null`) + case `""`: + // It is possible for a non-empty string to have `""` as a suffix + // if the second to the last quote was escaped. + if b[len(b)-3] == '\\' { + return false // e.g., `"\""` is not empty + } + n = len(`""`) + case `{}`: + n = len(`{}`) + case `[]`: + n = len(`[]`) + } + } + if n == 0 { + return false + } + + // Unwrite the value, whitespace, colon, name, whitespace, and comma. + b = b[:len(b)-n] + b = trimSuffixWhitespace(b) + b = trimSuffixByte(b, ':') + b = trimSuffixString(b) + b = trimSuffixWhitespace(b) + b = trimSuffixByte(b, ',') + e.buf = b // store back truncated unflushed buffer + + // Undo state changes. + e.tokens.last.decrement() // for object member value + e.tokens.last.decrement() // for object member name + if !e.options.AllowDuplicateNames { + if e.tokens.last.isActiveNamespace() { + e.namespaces.last().removeLast() + } + e.names.clearLast() + if prevName != nil { + e.names.copyQuotedBuffer(e.buf) // required by objectNameStack.replaceLastUnquotedName + e.names.replaceLastUnquotedName(*prevName) + } + } + return true +} + +// unwriteOnlyObjectMemberName unwrites the only object member name +// and returns the unquoted name. +func (e *Encoder) unwriteOnlyObjectMemberName() string { + if last := e.tokens.last; !last.isObject() || last.length() != 1 { + panic("BUG: must be called on an object after writing first name") + } + + // Unwrite the name and whitespace. + b := trimSuffixString(e.buf) + isVerbatim := bytes.IndexByte(e.buf[len(b):], '\\') < 0 + name := string(unescapeStringMayCopy(e.buf[len(b):], isVerbatim)) + e.buf = trimSuffixWhitespace(b) + + // Undo state changes. + e.tokens.last.decrement() + if !e.options.AllowDuplicateNames { + if e.tokens.last.isActiveNamespace() { + e.namespaces.last().removeLast() + } + e.names.clearLast() + } + return name +} + +func trimSuffixWhitespace(b []byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + n := len(b) - 1 + for n >= 0 && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { + n-- + } + return b[:n+1] +} + +func trimSuffixString(b []byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + if len(b) > 0 && b[len(b)-1] == '"' { + b = b[:len(b)-1] + } + for len(b) >= 2 && !(b[len(b)-1] == '"' && b[len(b)-2] != '\\') { + b = b[:len(b)-1] // trim all characters except an unescaped quote + } + if len(b) > 0 && b[len(b)-1] == '"' { + b = b[:len(b)-1] + } + return b +} + +func hasSuffixByte(b []byte, c byte) bool { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + return len(b) > 0 && b[len(b)-1] == c +} + +func trimSuffixByte(b []byte, c byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlineable. + if len(b) > 0 && b[len(b)-1] == c { + return b[:len(b)-1] + } + return b +} + +// WriteToken writes the next token and advances the internal write offset. +// +// The provided token kind must be consistent with the JSON grammar. +// For example, it is an error to provide a number when the encoder +// is expecting an object name (which is always a string), or +// to provide an end object delimiter when the encoder is finishing an array. +// If the provided token is invalid, then it reports a SyntacticError and +// the internal state remains unchanged. +func (e *Encoder) WriteToken(t Token) error { + k := t.Kind() + b := e.buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.tokens.mayAppendDelim(b, k) + if e.options.multiline { + b = e.appendWhitespace(b, k) + } + + // Append the token to the output and to the state machine. + var err error + switch k { + case 'n': + b = append(b, "null"...) + err = e.tokens.appendLiteral() + case 'f': + b = append(b, "false"...) + err = e.tokens.appendLiteral() + case 't': + b = append(b, "true"...) + err = e.tokens.appendLiteral() + case '"': + n0 := len(b) // offset before calling t.appendString + if b, err = t.appendString(b, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune); err != nil { + break + } + if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { + if !e.tokens.last.isValidNamespace() { + err = errInvalidNamespace + break + } + if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { + err = &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} + break + } + e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds + } + err = e.tokens.appendString() + case '0': + if b, err = t.appendNumber(b, e.options.canonicalizeNumbers); err != nil { + break + } + err = e.tokens.appendNumber() + case '{': + b = append(b, '{') + if err = e.tokens.pushObject(); err != nil { + break + } + if !e.options.AllowDuplicateNames { + e.names.push() + e.namespaces.push() + } + case '}': + b = append(b, '}') + if err = e.tokens.popObject(); err != nil { + break + } + if !e.options.AllowDuplicateNames { + e.names.pop() + e.namespaces.pop() + } + case '[': + b = append(b, '[') + err = e.tokens.pushArray() + case ']': + b = append(b, ']') + err = e.tokens.popArray() + default: + return &SyntacticError{str: "invalid json.Token"} + } + if err != nil { + return err + } + + // Finish off the buffer and store it back into e. + e.buf = b + if e.needFlush() { + return e.flush() + } + return nil +} + +const ( + rawIntNumber = -1 + rawUintNumber = -2 +) + +// writeNumber is specialized version of WriteToken, but optimized for numbers. +// As a special-case, if bits is -1 or -2, it will treat v as +// the raw-encoded bits of an int64 or uint64, respectively. +// It is only called from arshal_default.go. +func (e *Encoder) writeNumber(v float64, bits int, quote bool) error { + b := e.buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.tokens.mayAppendDelim(b, '0') + if e.options.multiline { + b = e.appendWhitespace(b, '0') + } + + if quote { + // Append the value to the output. + n0 := len(b) // offset before appending the number + b = append(b, '"') + switch bits { + case rawIntNumber: + b = strconv.AppendInt(b, int64(math.Float64bits(v)), 10) + case rawUintNumber: + b = strconv.AppendUint(b, uint64(math.Float64bits(v)), 10) + default: + b = appendNumber(b, v, bits) + } + b = append(b, '"') + + // Escape the string if necessary. + if e.options.EscapeRune != nil { + b2 := append(e.unusedCache, b[n0+len(`"`):len(b)-len(`"`)]...) + b, _ = appendString(b[:n0], string(b2), false, e.options.EscapeRune) + e.unusedCache = b2[:0] + } + + // Update the state machine. + if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { + if !e.tokens.last.isValidNamespace() { + return errInvalidNamespace + } + if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { + return &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} + } + e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds + } + if err := e.tokens.appendString(); err != nil { + return err + } + } else { + switch bits { + case rawIntNumber: + b = strconv.AppendInt(b, int64(math.Float64bits(v)), 10) + case rawUintNumber: + b = strconv.AppendUint(b, uint64(math.Float64bits(v)), 10) + default: + b = appendNumber(b, v, bits) + } + if err := e.tokens.appendNumber(); err != nil { + return err + } + } + + // Finish off the buffer and store it back into e. + e.buf = b + if e.needFlush() { + return e.flush() + } + return nil +} + +// WriteValue writes the next raw value and advances the internal write offset. +// The Encoder does not simply copy the provided value verbatim, but +// parses it to ensure that it is syntactically valid and reformats it +// according to how the Encoder is configured to format whitespace and strings. +// +// The provided value kind must be consistent with the JSON grammar +// (see examples on Encoder.WriteToken). If the provided value is invalid, +// then it reports a SyntacticError and the internal state remains unchanged. +func (e *Encoder) WriteValue(v RawValue) error { + e.maxValue |= len(v) // bitwise OR is a fast approximation of max + + k := v.Kind() + b := e.buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.tokens.mayAppendDelim(b, k) + if e.options.multiline { + b = e.appendWhitespace(b, k) + } + + // Append the value the output. + var err error + v = v[consumeWhitespace(v):] + n0 := len(b) // offset before calling e.reformatValue + b, v, err = e.reformatValue(b, v, e.tokens.depth()) + if err != nil { + return err + } + v = v[consumeWhitespace(v):] + if len(v) > 0 { + return newInvalidCharacterError(v[0:], "after top-level value") + } + + // Append the kind to the state machine. + switch k { + case 'n', 'f', 't': + err = e.tokens.appendLiteral() + case '"': + if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { + if !e.tokens.last.isValidNamespace() { + err = errInvalidNamespace + break + } + if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { + err = &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} + break + } + e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds + } + err = e.tokens.appendString() + case '0': + err = e.tokens.appendNumber() + case '{': + if err = e.tokens.pushObject(); err != nil { + break + } + if err = e.tokens.popObject(); err != nil { + panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) + } + case '[': + if err = e.tokens.pushArray(); err != nil { + break + } + if err = e.tokens.popArray(); err != nil { + panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) + } + } + if err != nil { + return err + } + + // Finish off the buffer and store it back into e. + e.buf = b + if e.needFlush() { + return e.flush() + } + return nil +} + +// appendWhitespace appends whitespace that immediately precedes the next token. +func (e *Encoder) appendWhitespace(b []byte, next Kind) []byte { + if e.tokens.needDelim(next) == ':' { + return append(b, ' ') + } else { + return e.appendIndent(b, e.tokens.needIndent(next)) + } +} + +// appendIndent appends the appropriate number of indentation characters +// for the current nested level, n. +func (e *Encoder) appendIndent(b []byte, n int) []byte { + if n == 0 { + return b + } + b = append(b, '\n') + b = append(b, e.options.IndentPrefix...) + for ; n > 1; n-- { + b = append(b, e.options.Indent...) + } + return b +} + +// reformatValue parses a JSON value from the start of src and +// appends it to the end of dst, reformatting whitespace and strings as needed. +// It returns the updated versions of dst and src. +func (e *Encoder) reformatValue(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { + // TODO: Should this update valueFlags as input? + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + var n int + var err error + switch k := Kind(src[0]).normalize(); k { + case 'n': + if n = consumeNull(src); n == 0 { + n, err = consumeLiteral(src, "null") + } + case 'f': + if n = consumeFalse(src); n == 0 { + n, err = consumeLiteral(src, "false") + } + case 't': + if n = consumeTrue(src); n == 0 { + n, err = consumeLiteral(src, "true") + } + case '"': + if n := consumeSimpleString(src); n > 0 && e.options.EscapeRune == nil { + dst, src = append(dst, src[:n]...), src[n:] // copy simple strings verbatim + return dst, src, nil + } + return reformatString(dst, src, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune) + case '0': + if n := consumeSimpleNumber(src); n > 0 && !e.options.canonicalizeNumbers { + dst, src = append(dst, src[:n]...), src[n:] // copy simple numbers verbatim + return dst, src, nil + } + return reformatNumber(dst, src, e.options.canonicalizeNumbers) + case '{': + return e.reformatObject(dst, src, depth) + case '[': + return e.reformatArray(dst, src, depth) + default: + return dst, src, newInvalidCharacterError(src, "at start of value") + } + if err != nil { + return dst, src, err + } + dst, src = append(dst, src[:n]...), src[n:] + return dst, src, nil +} + +// reformatObject parses a JSON object from the start of src and +// appends it to the end of src, reformatting whitespace and strings as needed. +// It returns the updated versions of dst and src. +func (e *Encoder) reformatObject(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { + // Append object start. + if src[0] != '{' { + panic("BUG: reformatObject must be called with a buffer that starts with '{'") + } + dst, src = append(dst, '{'), src[1:] + + // Append (possible) object end. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + if src[0] == '}' { + dst, src = append(dst, '}'), src[1:] + return dst, src, nil + } + + var err error + var names *objectNamespace + if !e.options.AllowDuplicateNames { + e.namespaces.push() + defer e.namespaces.pop() + names = e.namespaces.last() + } + depth++ + for { + // Append optional newline and indentation. + if e.options.multiline { + dst = e.appendIndent(dst, depth) + } + + // Append object name. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + n0 := len(dst) // offset before calling reformatString + n := consumeSimpleString(src) + if n > 0 && e.options.EscapeRune == nil { + dst, src = append(dst, src[:n]...), src[n:] // copy simple strings verbatim + } else { + dst, src, err = reformatString(dst, src, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune) + } + if err != nil { + return dst, src, err + } + if !e.options.AllowDuplicateNames && !names.insertQuoted(dst[n0:], false) { + return dst, src, &SyntacticError{str: "duplicate name " + string(dst[n0:]) + " in object"} + } + + // Append colon. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + if src[0] != ':' { + return dst, src, newInvalidCharacterError(src, "after object name (expecting ':')") + } + dst, src = append(dst, ':'), src[1:] + if e.options.multiline { + dst = append(dst, ' ') + } + + // Append object value. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + dst, src, err = e.reformatValue(dst, src, depth) + if err != nil { + return dst, src, err + } + + // Append comma or object end. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + switch src[0] { + case ',': + dst, src = append(dst, ','), src[1:] + continue + case '}': + if e.options.multiline { + dst = e.appendIndent(dst, depth-1) + } + dst, src = append(dst, '}'), src[1:] + return dst, src, nil + default: + return dst, src, newInvalidCharacterError(src, "after object value (expecting ',' or '}')") + } + } +} + +// reformatArray parses a JSON array from the start of src and +// appends it to the end of dst, reformatting whitespace and strings as needed. +// It returns the updated versions of dst and src. +func (e *Encoder) reformatArray(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { + // Append array start. + if src[0] != '[' { + panic("BUG: reformatArray must be called with a buffer that starts with '['") + } + dst, src = append(dst, '['), src[1:] + + // Append (possible) array end. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + if src[0] == ']' { + dst, src = append(dst, ']'), src[1:] + return dst, src, nil + } + + var err error + depth++ + for { + // Append optional newline and indentation. + if e.options.multiline { + dst = e.appendIndent(dst, depth) + } + + // Append array value. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + dst, src, err = e.reformatValue(dst, src, depth) + if err != nil { + return dst, src, err + } + + // Append comma or array end. + src = src[consumeWhitespace(src):] + if len(src) == 0 { + return dst, src, io.ErrUnexpectedEOF + } + switch src[0] { + case ',': + dst, src = append(dst, ','), src[1:] + continue + case ']': + if e.options.multiline { + dst = e.appendIndent(dst, depth-1) + } + dst, src = append(dst, ']'), src[1:] + return dst, src, nil + default: + return dst, src, newInvalidCharacterError(src, "after array value (expecting ',' or ']')") + } + } +} + +// OutputOffset returns the current output byte offset. It gives the location +// of the next byte immediately after the most recently written token or value. +// The number of bytes actually written to the underlying io.Writer may be less +// than this offset due to internal buffering effects. +func (e *Encoder) OutputOffset() int64 { + return e.previousOffsetEnd() +} + +// UnusedBuffer returns a zero-length buffer with a possible non-zero capacity. +// This buffer is intended to be used to populate a RawValue +// being passed to an immediately succeeding WriteValue call. +// +// Example usage: +// +// b := d.UnusedBuffer() +// b = append(b, '"') +// b = appendString(b, v) // append the string formatting of v +// b = append(b, '"') +// ... := d.WriteValue(b) +// +// It is the user's responsibility to ensure that the value is valid JSON. +func (e *Encoder) UnusedBuffer() []byte { + // NOTE: We don't return e.buf[len(e.buf):cap(e.buf)] since WriteValue would + // need to take special care to avoid mangling the data while reformatting. + // WriteValue can't easily identify whether the input RawValue aliases e.buf + // without using unsafe.Pointer. Thus, we just return a different buffer. + // Should this ever alias e.buf, we need to consider how it operates with + // the specialized performance optimization for bytes.Buffer. + n := 1 << bits.Len(uint(e.maxValue|63)) // fast approximation for max length + if cap(e.unusedCache) < n { + e.unusedCache = make([]byte, 0, n) + } + return e.unusedCache +} + +// StackDepth returns the depth of the state machine for written JSON data. +// Each level on the stack represents a nested JSON object or array. +// It is incremented whenever an ObjectStart or ArrayStart token is encountered +// and decremented whenever an ObjectEnd or ArrayEnd token is encountered. +// The depth is zero-indexed, where zero represents the top-level JSON value. +func (e *Encoder) StackDepth() int { + // NOTE: Keep in sync with Decoder.StackDepth. + return e.tokens.depth() - 1 +} + +// StackIndex returns information about the specified stack level. +// It must be a number between 0 and StackDepth, inclusive. +// For each level, it reports the kind: +// +// - 0 for a level of zero, +// - '{' for a level representing a JSON object, and +// - '[' for a level representing a JSON array. +// +// It also reports the length of that JSON object or array. +// Each name and value in a JSON object is counted separately, +// so the effective number of members would be half the length. +// A complete JSON object must have an even length. +func (e *Encoder) StackIndex(i int) (Kind, int) { + // NOTE: Keep in sync with Decoder.StackIndex. + switch s := e.tokens.index(i); { + case i > 0 && s.isObject(): + return '{', s.length() + case i > 0 && s.isArray(): + return '[', s.length() + default: + return 0, s.length() + } +} + +// StackPointer returns a JSON Pointer (RFC 6901) to the most recently written value. +// Object names are only present if AllowDuplicateNames is false, otherwise +// object members are represented using their index within the object. +func (e *Encoder) StackPointer() string { + e.names.copyQuotedBuffer(e.buf) + return string(e.appendStackPointer(nil)) +} + +// appendString appends src to dst as a JSON string per RFC 7159, section 7. +// +// If validateUTF8 is specified, this rejects input that contains invalid UTF-8 +// otherwise invalid bytes are replaced with the Unicode replacement character. +// If escapeRune is provided, it specifies which runes to escape using +// hexadecimal sequences. If nil, the shortest representable form is used, +// which is also the canonical form for strings (RFC 8785, section 3.2.2.2). +// +// Note that this API allows full control over the formatting of strings +// except for whether a forward solidus '/' may be formatted as '\/' and +// the casing of hexadecimal Unicode escape sequences. +func appendString(dst []byte, src string, validateUTF8 bool, escapeRune func(rune) bool) ([]byte, error) { + appendEscapedASCII := func(dst []byte, c byte) []byte { + switch c { + case '"', '\\': + dst = append(dst, '\\', c) + case '\b': + dst = append(dst, "\\b"...) + case '\f': + dst = append(dst, "\\f"...) + case '\n': + dst = append(dst, "\\n"...) + case '\r': + dst = append(dst, "\\r"...) + case '\t': + dst = append(dst, "\\t"...) + default: + dst = append(dst, "\\u"...) + dst = appendHexUint16(dst, uint16(c)) + } + return dst + } + appendEscapedUnicode := func(dst []byte, r rune) []byte { + if r1, r2 := utf16.EncodeRune(r); r1 != '\ufffd' && r2 != '\ufffd' { + dst = append(dst, "\\u"...) + dst = appendHexUint16(dst, uint16(r1)) + dst = append(dst, "\\u"...) + dst = appendHexUint16(dst, uint16(r2)) + } else { + dst = append(dst, "\\u"...) + dst = appendHexUint16(dst, uint16(r)) + } + return dst + } + + // Optimize for when escapeRune is nil. + if escapeRune == nil { + var i, n int + dst = append(dst, '"') + for uint(len(src)) > uint(n) { + // Handle single-byte ASCII. + if c := src[n]; c < utf8.RuneSelf { + n++ + if c < ' ' || c == '"' || c == '\\' { + dst = append(dst, src[i:n-1]...) + dst = appendEscapedASCII(dst, c) + i = n + } + continue + } + + // Handle multi-byte Unicode. + _, rn := utf8.DecodeRuneInString(src[n:]) + n += rn + if rn == 1 { // must be utf8.RuneError since we already checked for single-byte ASCII + dst = append(dst, src[i:n-rn]...) + if validateUTF8 { + return dst, &SyntacticError{str: "invalid UTF-8 within string"} + } + dst = append(dst, "\ufffd"...) + i = n + } + } + dst = append(dst, src[i:n]...) + dst = append(dst, '"') + return dst, nil + } + + // Slower implementation for when escapeRune is non-nil. + var i, n int + dst = append(dst, '"') + for uint(len(src)) > uint(n) { + switch r, rn := utf8.DecodeRuneInString(src[n:]); { + case r == utf8.RuneError && rn == 1: + dst = append(dst, src[i:n]...) + if validateUTF8 { + return dst, &SyntacticError{str: "invalid UTF-8 within string"} + } + if escapeRune('\ufffd') { + dst = append(dst, `\ufffd`...) + } else { + dst = append(dst, "\ufffd"...) + } + n += rn + i = n + case escapeRune(r): + dst = append(dst, src[i:n]...) + dst = appendEscapedUnicode(dst, r) + n += rn + i = n + case r < ' ' || r == '"' || r == '\\': + dst = append(dst, src[i:n]...) + dst = appendEscapedASCII(dst, byte(r)) + n += rn + i = n + default: + n += rn + } + } + dst = append(dst, src[i:n]...) + dst = append(dst, '"') + return dst, nil +} + +// reformatString consumes a JSON string from src and appends it to dst, +// reformatting it if necessary for the given escapeRune parameter. +// It returns the appended output and the remainder of the input. +func reformatString(dst, src []byte, validateUTF8, preserveRaw bool, escapeRune func(rune) bool) ([]byte, []byte, error) { + // TODO: Should this update valueFlags as input? + var flags valueFlags + n, err := consumeString(&flags, src, validateUTF8) + if err != nil { + return dst, src[n:], err + } + if preserveRaw || (escapeRune == nil && flags.isCanonical()) { + dst = append(dst, src[:n]...) // copy the string verbatim + return dst, src[n:], nil + } + + // TODO: Implement a direct, raw-to-raw reformat for strings. + // If the escapeRune option would have resulted in no changes to the output, + // it would be faster to simply append src to dst without going through + // an intermediary representation in a separate buffer. + b, _ := unescapeString(make([]byte, 0, n), src[:n]) + dst, _ = appendString(dst, string(b), validateUTF8, escapeRune) + return dst, src[n:], nil +} + +// appendNumber appends src to dst as a JSON number per RFC 7159, section 6. +// It formats numbers similar to the ES6 number-to-string conversion. +// See https://go.dev/issue/14135. +// +// The output is identical to ECMA-262, 6th edition, section 7.1.12.1 and with +// RFC 8785, section 3.2.2.3 for 64-bit floating-point numbers except for -0, +// which is formatted as -0 instead of just 0. +// +// For 32-bit floating-point numbers, +// the output is a 32-bit equivalent of the algorithm. +// Note that ECMA-262 specifies no algorithm for 32-bit numbers. +func appendNumber(dst []byte, src float64, bits int) []byte { + if bits == 32 { + src = float64(float32(src)) + } + + abs := math.Abs(src) + fmt := byte('f') + if abs != 0 { + if bits == 64 && (float64(abs) < 1e-6 || float64(abs) >= 1e21) || + bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { + fmt = 'e' + } + } + dst = strconv.AppendFloat(dst, src, fmt, -1, bits) + if fmt == 'e' { + // Clean up e-09 to e-9. + n := len(dst) + if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' { + dst[n-2] = dst[n-1] + dst = dst[:n-1] + } + } + return dst +} + +// reformatNumber consumes a JSON string from src and appends it to dst, +// canonicalizing it if specified. +// It returns the appended output and the remainder of the input. +func reformatNumber(dst, src []byte, canonicalize bool) ([]byte, []byte, error) { + n, err := consumeNumber(src) + if err != nil { + return dst, src[n:], err + } + if !canonicalize { + dst = append(dst, src[:n]...) // copy the number verbatim + return dst, src[n:], nil + } + + // Canonicalize the number per RFC 8785, section 3.2.2.3. + // As an optimization, we can copy integer numbers below 2⁵³ verbatim. + const maxExactIntegerDigits = 16 // len(strconv.AppendUint(nil, 1<<53, 10)) + if n < maxExactIntegerDigits && consumeSimpleNumber(src[:n]) == n { + dst = append(dst, src[:n]...) // copy the number verbatim + return dst, src[n:], nil + } + fv, _ := strconv.ParseFloat(string(src[:n]), 64) + switch { + case fv == 0: + fv = 0 // normalize negative zero as just zero + case math.IsInf(fv, +1): + fv = +math.MaxFloat64 + case math.IsInf(fv, -1): + fv = -math.MaxFloat64 + } + return appendNumber(dst, fv, 64), src[n:], nil +} + +// appendHexUint16 appends src to dst as a 4-byte hexadecimal number. +func appendHexUint16(dst []byte, src uint16) []byte { + dst = append(dst, "0000"[1+(bits.Len16(src)-1)/4:]...) + dst = strconv.AppendUint(dst, uint64(src), 16) + return dst +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go new file mode 100644 index 00000000000..35be8601eae --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go @@ -0,0 +1,183 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "errors" + "reflect" + "strconv" + "strings" + "unicode/utf8" +) + +const errorPrefix = "json: " + +// Error matches errors returned by this package according to errors.Is. +const Error = jsonError("json error") + +type jsonError string + +func (e jsonError) Error() string { + return string(e) +} +func (e jsonError) Is(target error) bool { + return e == target || target == Error +} + +type ioError struct { + action string // either "read" or "write" + err error +} + +func (e *ioError) Error() string { + return errorPrefix + e.action + " error: " + e.err.Error() +} +func (e *ioError) Unwrap() error { + return e.err +} +func (e *ioError) Is(target error) bool { + return e == target || target == Error || errors.Is(e.err, target) +} + +// SemanticError describes an error determining the meaning +// of JSON data as Go data or vice-versa. +// +// The contents of this error as produced by this package may change over time. +type SemanticError struct { + requireKeyedLiterals + nonComparable + + action string // either "marshal" or "unmarshal" + + // ByteOffset indicates that an error occurred after this byte offset. + ByteOffset int64 + // JSONPointer indicates that an error occurred within this JSON value + // as indicated using the JSON Pointer notation (see RFC 6901). + JSONPointer string + + // JSONKind is the JSON kind that could not be handled. + JSONKind Kind // may be zero if unknown + // GoType is the Go type that could not be handled. + GoType reflect.Type // may be nil if unknown + + // Err is the underlying error. + Err error // may be nil +} + +func (e *SemanticError) Error() string { + var sb strings.Builder + sb.WriteString(errorPrefix) + + // Hyrum-proof the error message by deliberately switching between + // two equivalent renderings of the same error message. + // The randomization is tied to the Hyrum-proofing already applied + // on map iteration in Go. + for phrase := range map[string]struct{}{"cannot": {}, "unable to": {}} { + sb.WriteString(phrase) + break // use whichever phrase we get in the first iteration + } + + // Format action. + var preposition string + switch e.action { + case "marshal": + sb.WriteString(" marshal") + preposition = " from" + case "unmarshal": + sb.WriteString(" unmarshal") + preposition = " into" + default: + sb.WriteString(" handle") + preposition = " with" + } + + // Format JSON kind. + var omitPreposition bool + switch e.JSONKind { + case 'n': + sb.WriteString(" JSON null") + case 'f', 't': + sb.WriteString(" JSON boolean") + case '"': + sb.WriteString(" JSON string") + case '0': + sb.WriteString(" JSON number") + case '{', '}': + sb.WriteString(" JSON object") + case '[', ']': + sb.WriteString(" JSON array") + default: + omitPreposition = true + } + + // Format Go type. + if e.GoType != nil { + if !omitPreposition { + sb.WriteString(preposition) + } + sb.WriteString(" Go value of type ") + sb.WriteString(e.GoType.String()) + } + + // Format where. + switch { + case e.JSONPointer != "": + sb.WriteString(" within JSON value at ") + sb.WriteString(strconv.Quote(e.JSONPointer)) + case e.ByteOffset > 0: + sb.WriteString(" after byte offset ") + sb.WriteString(strconv.FormatInt(e.ByteOffset, 10)) + } + + // Format underlying error. + if e.Err != nil { + sb.WriteString(": ") + sb.WriteString(e.Err.Error()) + } + + return sb.String() +} +func (e *SemanticError) Is(target error) bool { + return e == target || target == Error || errors.Is(e.Err, target) +} +func (e *SemanticError) Unwrap() error { + return e.Err +} + +// SyntacticError is a description of a syntactic error that occurred when +// encoding or decoding JSON according to the grammar. +// +// The contents of this error as produced by this package may change over time. +type SyntacticError struct { + requireKeyedLiterals + nonComparable + + // ByteOffset indicates that an error occurred after this byte offset. + ByteOffset int64 + str string +} + +func (e *SyntacticError) Error() string { + return errorPrefix + e.str +} +func (e *SyntacticError) Is(target error) bool { + return e == target || target == Error +} +func (e *SyntacticError) withOffset(pos int64) error { + return &SyntacticError{ByteOffset: pos, str: e.str} +} + +func newInvalidCharacterError(prefix []byte, where string) *SyntacticError { + what := quoteRune(prefix) + return &SyntacticError{str: "invalid character " + what + " " + where} +} + +func quoteRune(b []byte) string { + r, n := utf8.DecodeRune(b) + if r == utf8.RuneError && n == 1 { + return `'\x` + strconv.FormatUint(uint64(b[0]), 16) + `'` + } + return strconv.QuoteRune(r) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go new file mode 100644 index 00000000000..c0ee3616683 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go @@ -0,0 +1,509 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "errors" + "fmt" + "io" + "reflect" + "sort" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +var errIgnoredField = errors.New("ignored field") + +type isZeroer interface { + IsZero() bool +} + +var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem() + +type structFields struct { + flattened []structField // listed in depth-first ordering + byActualName map[string]*structField + byFoldedName map[string][]*structField + inlinedFallback *structField +} + +type structField struct { + id int // unique numeric ID in breadth-first ordering + index []int // index into a struct according to reflect.Type.FieldByIndex + typ reflect.Type + fncs *arshaler + isZero func(addressableValue) bool + isEmpty func(addressableValue) bool + fieldOptions +} + +func makeStructFields(root reflect.Type) (structFields, *SemanticError) { + var fs structFields + fs.byActualName = make(map[string]*structField, root.NumField()) + fs.byFoldedName = make(map[string][]*structField, root.NumField()) + + // ambiguous is a sentinel value to indicate that at least two fields + // at the same depth have the same name, and thus cancel each other out. + // This follows the same rules as selecting a field on embedded structs + // where the shallowest field takes precedence. If more than one field + // exists at the shallowest depth, then the selection is illegal. + // See https://go.dev/ref/spec#Selectors. + ambiguous := new(structField) + + // Setup a queue for a breath-first search. + var queueIndex int + type queueEntry struct { + typ reflect.Type + index []int + visitChildren bool // whether to recursively visit inlined field in this struct + } + queue := []queueEntry{{root, nil, true}} + seen := map[reflect.Type]bool{root: true} + + // Perform a breadth-first search over all reachable fields. + // This ensures that len(f.index) will be monotonically increasing. + for queueIndex < len(queue) { + qe := queue[queueIndex] + queueIndex++ + + t := qe.typ + inlinedFallbackIndex := -1 // index of last inlined fallback field in current struct + namesIndex := make(map[string]int) // index of each field with a given JSON object name in current struct + var hasAnyJSONTag bool // whether any Go struct field has a `json` tag + var hasAnyJSONField bool // whether any JSON serializable fields exist in current struct + for i := 0; i < t.NumField(); i++ { + sf := t.Field(i) + _, hasTag := sf.Tag.Lookup("json") + hasAnyJSONTag = hasAnyJSONTag || hasTag + options, err := parseFieldOptions(sf) + if err != nil { + if err == errIgnoredField { + continue + } + return structFields{}, &SemanticError{GoType: t, Err: err} + } + hasAnyJSONField = true + f := structField{ + // Allocate a new slice (len=N+1) to hold both + // the parent index (len=N) and the current index (len=1). + // Do this to avoid clobbering the memory of the parent index. + index: append(append(make([]int, 0, len(qe.index)+1), qe.index...), i), + typ: sf.Type, + fieldOptions: options, + } + if sf.Anonymous && !f.hasName { + f.inline = true // implied by use of Go embedding without an explicit name + } + if f.inline || f.unknown { + // Handle an inlined field that serializes to/from + // zero or more JSON object members. + + if f.inline && f.unknown { + err := fmt.Errorf("Go struct field %s cannot have both `inline` and `unknown` specified", sf.Name) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + switch f.fieldOptions { + case fieldOptions{name: f.name, quotedName: f.quotedName, inline: true}: + case fieldOptions{name: f.name, quotedName: f.quotedName, unknown: true}: + default: + err := fmt.Errorf("Go struct field %s cannot have any options other than `inline` or `unknown` specified", sf.Name) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + + // Unwrap one level of pointer indirection similar to how Go + // only allows embedding either T or *T, but not **T. + tf := f.typ + if tf.Kind() == reflect.Pointer && tf.Name() == "" { + tf = tf.Elem() + } + // Reject any types with custom serialization otherwise + // it becomes impossible to know what sub-fields to inline. + if which, _ := implementsWhich(tf, + jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType, + jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType, + ); which != nil && tf != rawValueType { + err := fmt.Errorf("inlined Go struct field %s of type %s must not implement JSON marshal or unmarshal methods", sf.Name, tf) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + + // Handle an inlined field that serializes to/from + // a finite number of JSON object members backed by a Go struct. + if tf.Kind() == reflect.Struct { + if f.unknown { + err := fmt.Errorf("inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a json.RawValue", sf.Name, tf) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + if qe.visitChildren { + queue = append(queue, queueEntry{tf, f.index, !seen[tf]}) + } + seen[tf] = true + continue + } + + // Handle an inlined field that serializes to/from any number of + // JSON object members back by a Go map or RawValue. + switch { + case tf == rawValueType: + f.fncs = nil // specially handled in arshal_inlined.go + case tf.Kind() == reflect.Map && tf.Key() == stringType: + f.fncs = lookupArshaler(tf.Elem()) + default: + err := fmt.Errorf("inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or json.RawValue", sf.Name, tf) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + + // Reject multiple inlined fallback fields within the same struct. + if inlinedFallbackIndex >= 0 { + err := fmt.Errorf("inlined Go struct fields %s and %s cannot both be a Go map or json.RawValue", t.Field(inlinedFallbackIndex).Name, sf.Name) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + inlinedFallbackIndex = i + + // Multiple inlined fallback fields across different structs + // follow the same precedence rules as Go struct embedding. + if fs.inlinedFallback == nil { + fs.inlinedFallback = &f // store first occurrence at lowest depth + } else if len(fs.inlinedFallback.index) == len(f.index) { + fs.inlinedFallback = ambiguous // at least two occurrences at same depth + } + } else { + // Handle normal Go struct field that serializes to/from + // a single JSON object member. + + // Provide a function that uses a type's IsZero method. + switch { + case sf.Type.Kind() == reflect.Interface && sf.Type.Implements(isZeroerType): + f.isZero = func(va addressableValue) bool { + // Avoid panics calling IsZero on a nil interface or + // non-nil interface with nil pointer. + return va.IsNil() || (va.Elem().Kind() == reflect.Pointer && va.Elem().IsNil()) || va.Interface().(isZeroer).IsZero() + } + case sf.Type.Kind() == reflect.Pointer && sf.Type.Implements(isZeroerType): + f.isZero = func(va addressableValue) bool { + // Avoid panics calling IsZero on nil pointer. + return va.IsNil() || va.Interface().(isZeroer).IsZero() + } + case sf.Type.Implements(isZeroerType): + f.isZero = func(va addressableValue) bool { return va.Interface().(isZeroer).IsZero() } + case reflect.PointerTo(sf.Type).Implements(isZeroerType): + f.isZero = func(va addressableValue) bool { return va.Addr().Interface().(isZeroer).IsZero() } + } + + // Provide a function that can determine whether the value would + // serialize as an empty JSON value. + switch sf.Type.Kind() { + case reflect.String, reflect.Map, reflect.Array, reflect.Slice: + f.isEmpty = func(va addressableValue) bool { return va.Len() == 0 } + case reflect.Pointer, reflect.Interface: + f.isEmpty = func(va addressableValue) bool { return va.IsNil() } + } + + f.id = len(fs.flattened) + f.fncs = lookupArshaler(sf.Type) + fs.flattened = append(fs.flattened, f) + + // Reject user-specified names with invalid UTF-8. + if !utf8.ValidString(f.name) { + err := fmt.Errorf("Go struct field %s has JSON object name %q with invalid UTF-8", sf.Name, f.name) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + // Reject multiple fields with same name within the same struct. + if j, ok := namesIndex[f.name]; ok { + err := fmt.Errorf("Go struct fields %s and %s conflict over JSON object name %q", t.Field(j).Name, sf.Name, f.name) + return structFields{}, &SemanticError{GoType: t, Err: err} + } + namesIndex[f.name] = i + + // Multiple fields of the same name across different structs + // follow the same precedence rules as Go struct embedding. + if f2 := fs.byActualName[f.name]; f2 == nil { + fs.byActualName[f.name] = &fs.flattened[len(fs.flattened)-1] // store first occurrence at lowest depth + } else if len(f2.index) == len(f.index) { + fs.byActualName[f.name] = ambiguous // at least two occurrences at same depth + } + } + } + + // NOTE: New users to the json package are occasionally surprised that + // unexported fields are ignored. This occurs by necessity due to our + // inability to directly introspect such fields with Go reflection + // without the use of unsafe. + // + // To reduce friction here, refuse to serialize any Go struct that + // has no JSON serializable fields, has at least one Go struct field, + // and does not have any `json` tags present. For example, + // errors returned by errors.New would fail to serialize. + isEmptyStruct := t.NumField() == 0 + if !isEmptyStruct && !hasAnyJSONTag && !hasAnyJSONField { + err := errors.New("Go struct has no exported fields") + return structFields{}, &SemanticError{GoType: t, Err: err} + } + } + + // Remove all fields that are duplicates. + // This may move elements forward to fill the holes from removed fields. + var n int + for _, f := range fs.flattened { + switch f2 := fs.byActualName[f.name]; { + case f2 == ambiguous: + delete(fs.byActualName, f.name) + case f2 == nil: + continue // may be nil due to previous delete + // TODO(https://go.dev/issue/45955): Use slices.Equal. + case reflect.DeepEqual(f.index, f2.index): + f.id = n + fs.flattened[n] = f + fs.byActualName[f.name] = &fs.flattened[n] // fix pointer to new location + n++ + } + } + fs.flattened = fs.flattened[:n] + if fs.inlinedFallback == ambiguous { + fs.inlinedFallback = nil + } + if len(fs.flattened) != len(fs.byActualName) { + panic(fmt.Sprintf("BUG: flattened list of fields mismatches fields mapped by name: %d != %d", len(fs.flattened), len(fs.byActualName))) + } + + // Sort the fields according to a depth-first ordering. + // This operation will cause pointers in byActualName to become incorrect, + // which we will correct in another loop shortly thereafter. + sort.Slice(fs.flattened, func(i, j int) bool { + si := fs.flattened[i].index + sj := fs.flattened[j].index + for len(si) > 0 && len(sj) > 0 { + switch { + case si[0] < sj[0]: + return true + case si[0] > sj[0]: + return false + default: + si = si[1:] + sj = sj[1:] + } + } + return len(si) < len(sj) + }) + + // Recompute the mapping of fields in the byActualName map. + // Pre-fold all names so that we can lookup folded names quickly. + for i, f := range fs.flattened { + foldedName := string(foldName([]byte(f.name))) + fs.byActualName[f.name] = &fs.flattened[i] + fs.byFoldedName[foldedName] = append(fs.byFoldedName[foldedName], &fs.flattened[i]) + } + for foldedName, fields := range fs.byFoldedName { + if len(fields) > 1 { + // The precedence order for conflicting nocase names + // is by breadth-first order, rather than depth-first order. + sort.Slice(fields, func(i, j int) bool { + return fields[i].id < fields[j].id + }) + fs.byFoldedName[foldedName] = fields + } + } + + return fs, nil +} + +type fieldOptions struct { + name string + quotedName string // quoted name per RFC 8785, section 3.2.2.2. + hasName bool + nocase bool + inline bool + unknown bool + omitzero bool + omitempty bool + string bool + format string +} + +// parseFieldOptions parses the `json` tag in a Go struct field as +// a structured set of options configuring parameters such as +// the JSON member name and other features. +// As a special case, it returns errIgnoredField if the field is ignored. +func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { + tag, hasTag := sf.Tag.Lookup("json") + + // Check whether this field is explicitly ignored. + if tag == "-" { + return fieldOptions{}, errIgnoredField + } + + // Check whether this field is unexported. + if !sf.IsExported() { + // In contrast to v1, v2 no longer forwards exported fields from + // embedded fields of unexported types since Go reflection does not + // allow the same set of operations that are available in normal cases + // of purely exported fields. + // See https://go.dev/issue/21357 and https://go.dev/issue/24153. + if sf.Anonymous { + return fieldOptions{}, fmt.Errorf("embedded Go struct field %s of an unexported type must be explicitly ignored with a `json:\"-\"` tag", sf.Type.Name()) + } + // Tag options specified on an unexported field suggests user error. + if hasTag { + return fieldOptions{}, fmt.Errorf("unexported Go struct field %s cannot have non-ignored `json:%q` tag", sf.Name, tag) + } + return fieldOptions{}, errIgnoredField + } + + // Determine the JSON member name for this Go field. A user-specified name + // may be provided as either an identifier or a single-quoted string. + // The single-quoted string allows arbitrary characters in the name. + // See https://go.dev/issue/2718 and https://go.dev/issue/3546. + out.name = sf.Name // always starts with an uppercase character + if len(tag) > 0 && !strings.HasPrefix(tag, ",") { + // For better compatibility with v1, accept almost any unescaped name. + n := len(tag) - len(strings.TrimLeftFunc(tag, func(r rune) bool { + return !strings.ContainsRune(",\\'\"`", r) // reserve comma, backslash, and quotes + })) + opt := tag[:n] + if n == 0 { + // Allow a single quoted string for arbitrary names. + opt, n, err = consumeTagOption(tag) + if err != nil { + return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err) + } + } + out.hasName = true + out.name = opt + tag = tag[n:] + } + b, _ := appendString(nil, out.name, false, nil) + out.quotedName = string(b) + + // Handle any additional tag options (if any). + var wasFormat bool + seenOpts := make(map[string]bool) + for len(tag) > 0 { + // Consume comma delimiter. + if tag[0] != ',' { + return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid character %q before next option (expecting ',')", sf.Name, tag[0]) + } + tag = tag[len(","):] + if len(tag) == 0 { + return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid trailing ',' character", sf.Name) + } + + // Consume and process the tag option. + opt, n, err := consumeTagOption(tag) + if err != nil { + return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err) + } + rawOpt := tag[:n] + tag = tag[n:] + switch { + case wasFormat: + return fieldOptions{}, fmt.Errorf("Go struct field %s has `format` tag option that was not specified last", sf.Name) + case strings.HasPrefix(rawOpt, "'") && strings.TrimFunc(opt, isLetterOrDigit) == "": + return fieldOptions{}, fmt.Errorf("Go struct field %s has unnecessarily quoted appearance of `%s` tag option; specify `%s` instead", sf.Name, rawOpt, opt) + } + switch opt { + case "nocase": + out.nocase = true + case "inline": + out.inline = true + case "unknown": + out.unknown = true + case "omitzero": + out.omitzero = true + case "omitempty": + out.omitempty = true + case "string": + out.string = true + case "format": + if !strings.HasPrefix(tag, ":") { + return fieldOptions{}, fmt.Errorf("Go struct field %s is missing value for `format` tag option", sf.Name) + } + tag = tag[len(":"):] + opt, n, err := consumeTagOption(tag) + if err != nil { + return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed value for `format` tag option: %v", sf.Name, err) + } + tag = tag[n:] + out.format = opt + wasFormat = true + default: + // Reject keys that resemble one of the supported options. + // This catches invalid mutants such as "omitEmpty" or "omit_empty". + normOpt := strings.ReplaceAll(strings.ToLower(opt), "_", "") + switch normOpt { + case "nocase", "inline", "unknown", "omitzero", "omitempty", "string", "format": + return fieldOptions{}, fmt.Errorf("Go struct field %s has invalid appearance of `%s` tag option; specify `%s` instead", sf.Name, opt, normOpt) + } + + // NOTE: Everything else is ignored. This does not mean it is + // forward compatible to insert arbitrary tag options since + // a future version of this package may understand that tag. + } + + // Reject duplicates. + if seenOpts[opt] { + return fieldOptions{}, fmt.Errorf("Go struct field %s has duplicate appearance of `%s` tag option", sf.Name, rawOpt) + } + seenOpts[opt] = true + } + return out, nil +} + +func consumeTagOption(in string) (string, int, error) { + switch r, _ := utf8.DecodeRuneInString(in); { + // Option as a Go identifier. + case r == '_' || unicode.IsLetter(r): + n := len(in) - len(strings.TrimLeftFunc(in, isLetterOrDigit)) + return in[:n], n, nil + // Option as a single-quoted string. + case r == '\'': + // The grammar is nearly identical to a double-quoted Go string literal, + // but uses single quotes as the terminators. The reason for a custom + // grammar is because both backtick and double quotes cannot be used + // verbatim in a struct tag. + // + // Convert a single-quoted string to a double-quote string and rely on + // strconv.Unquote to handle the rest. + var inEscape bool + b := []byte{'"'} + n := len(`'`) + for len(in) > n { + r, rn := utf8.DecodeRuneInString(in[n:]) + switch { + case inEscape: + if r == '\'' { + b = b[:len(b)-1] // remove escape character: `\'` => `'` + } + inEscape = false + case r == '\\': + inEscape = true + case r == '"': + b = append(b, '\\') // insert escape character: `"` => `\"` + case r == '\'': + b = append(b, '"') + n += len(`'`) + out, err := strconv.Unquote(string(b)) + if err != nil { + return "", 0, fmt.Errorf("invalid single-quoted string: %s", in[:n]) + } + return out, n, nil + } + b = append(b, in[n:][:rn]...) + n += rn + } + if n > 10 { + n = 10 // limit the amount of context printed in the error + } + return "", 0, fmt.Errorf("single-quoted string not terminated: %s...", in[:n]) + case len(in) == 0: + return "", 0, io.ErrUnexpectedEOF + default: + return "", 0, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r) + } +} + +func isLetterOrDigit(r rune) bool { + return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go new file mode 100644 index 00000000000..9ab735814cf --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go @@ -0,0 +1,56 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "unicode" + "unicode/utf8" +) + +// foldName returns a folded string such that foldName(x) == foldName(y) +// is similar to strings.EqualFold(x, y), but ignores underscore and dashes. +// This allows foldName to match common naming conventions. +func foldName(in []byte) []byte { + // This is inlinable to take advantage of "function outlining". + // See https://blog.filippo.io/efficient-go-apis-with-the-inliner/ + var arr [32]byte // large enough for most JSON names + return appendFoldedName(arr[:0], in) +} +func appendFoldedName(out, in []byte) []byte { + for i := 0; i < len(in); { + // Handle single-byte ASCII. + if c := in[i]; c < utf8.RuneSelf { + if c != '_' && c != '-' { + if 'a' <= c && c <= 'z' { + c -= 'a' - 'A' + } + out = append(out, c) + } + i++ + continue + } + // Handle multi-byte Unicode. + r, n := utf8.DecodeRune(in[i:]) + out = utf8.AppendRune(out, foldRune(r)) + i += n + } + return out +} + +// foldRune is a variation on unicode.SimpleFold that returns the same rune +// for all runes in the same fold set. +// +// Invariant: +// +// foldRune(x) == foldRune(y) ⇔ strings.EqualFold(string(x), string(y)) +func foldRune(r rune) rune { + for { + r2 := unicode.SimpleFold(r) + if r2 <= r { + return r2 // smallest character in the fold set + } + r = r2 + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go new file mode 100644 index 00000000000..700a56db0b9 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go @@ -0,0 +1,86 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "encoding/binary" + "math/bits" +) + +// stringCache is a cache for strings converted from a []byte. +type stringCache [256]string // 256*unsafe.Sizeof(string("")) => 4KiB + +// make returns the string form of b. +// It returns a pre-allocated string from c if present, otherwise +// it allocates a new string, inserts it into the cache, and returns it. +func (c *stringCache) make(b []byte) string { + const ( + minCachedLen = 2 // single byte strings are already interned by the runtime + maxCachedLen = 256 // large enough for UUIDs, IPv6 addresses, SHA-256 checksums, etc. + ) + if c == nil || len(b) < minCachedLen || len(b) > maxCachedLen { + return string(b) + } + + // Compute a hash from the fixed-width prefix and suffix of the string. + // This ensures hashing a string is a constant time operation. + var h uint32 + switch { + case len(b) >= 8: + lo := binary.LittleEndian.Uint64(b[:8]) + hi := binary.LittleEndian.Uint64(b[len(b)-8:]) + h = hash64(uint32(lo), uint32(lo>>32)) ^ hash64(uint32(hi), uint32(hi>>32)) + case len(b) >= 4: + lo := binary.LittleEndian.Uint32(b[:4]) + hi := binary.LittleEndian.Uint32(b[len(b)-4:]) + h = hash64(lo, hi) + case len(b) >= 2: + lo := binary.LittleEndian.Uint16(b[:2]) + hi := binary.LittleEndian.Uint16(b[len(b)-2:]) + h = hash64(uint32(lo), uint32(hi)) + } + + // Check the cache for the string. + i := h % uint32(len(*c)) + if s := (*c)[i]; s == string(b) { + return s + } + s := string(b) + (*c)[i] = s + return s +} + +// hash64 returns the hash of two uint32s as a single uint32. +func hash64(lo, hi uint32) uint32 { + // If avalanche=true, this is identical to XXH32 hash on a 8B string: + // var b [8]byte + // binary.LittleEndian.PutUint32(b[:4], lo) + // binary.LittleEndian.PutUint32(b[4:], hi) + // return xxhash.Sum32(b[:]) + const ( + prime1 = 0x9e3779b1 + prime2 = 0x85ebca77 + prime3 = 0xc2b2ae3d + prime4 = 0x27d4eb2f + prime5 = 0x165667b1 + ) + h := prime5 + uint32(8) + h += lo * prime3 + h = bits.RotateLeft32(h, 17) * prime4 + h += hi * prime3 + h = bits.RotateLeft32(h, 17) * prime4 + // Skip final mix (avalanche) step of XXH32 for performance reasons. + // Empirical testing shows that the improvements in unbiased distribution + // does not outweigh the extra cost in computational complexity. + const avalanche = false + if avalanche { + h ^= h >> 15 + h *= prime2 + h ^= h >> 13 + h *= prime3 + h ^= h >> 16 + } + return h +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go new file mode 100644 index 00000000000..60e93270fb1 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go @@ -0,0 +1,182 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "io" + "math/bits" + "sort" + "sync" +) + +// TODO(https://go.dev/issue/47657): Use sync.PoolOf. + +var ( + // This owns the internal buffer since there is no io.Writer to output to. + // Since the buffer can get arbitrarily large in normal usage, + // there is statistical tracking logic to determine whether to recycle + // the internal buffer or not based on a history of utilization. + bufferedEncoderPool = &sync.Pool{New: func() any { return new(Encoder) }} + + // This owns the internal buffer, but it is only used to temporarily store + // buffered JSON before flushing it to the underlying io.Writer. + // In a sufficiently efficient streaming mode, we do not expect the buffer + // to grow arbitrarily large. Thus, we avoid recycling large buffers. + streamingEncoderPool = &sync.Pool{New: func() any { return new(Encoder) }} + + // This does not own the internal buffer since + // it is taken directly from the provided bytes.Buffer. + bytesBufferEncoderPool = &sync.Pool{New: func() any { return new(Encoder) }} +) + +// bufferStatistics is statistics to track buffer utilization. +// It is used to determine whether to recycle a buffer or not +// to avoid https://go.dev/issue/23199. +type bufferStatistics struct { + strikes int // number of times the buffer was under-utilized + prevLen int // length of previous buffer +} + +func getBufferedEncoder(o EncodeOptions) *Encoder { + e := bufferedEncoderPool.Get().(*Encoder) + if e.buf == nil { + // Round up to nearest 2ⁿ to make best use of malloc size classes. + // See runtime/sizeclasses.go on Go1.15. + // Logical OR with 63 to ensure 64 as the minimum buffer size. + n := 1 << bits.Len(uint(e.bufStats.prevLen|63)) + e.buf = make([]byte, 0, n) + } + e.reset(e.buf[:0], nil, o) + return e +} +func putBufferedEncoder(e *Encoder) { + // Recycle large buffers only if sufficiently utilized. + // If a buffer is under-utilized enough times sequentially, + // then it is discarded, ensuring that a single large buffer + // won't be kept alive by a continuous stream of small usages. + // + // The worst case utilization is computed as: + // MIN_UTILIZATION_THRESHOLD / (1 + MAX_NUM_STRIKES) + // + // For the constants chosen below, this is (25%)/(1+4) ⇒ 5%. + // This may seem low, but it ensures a lower bound on + // the absolute worst-case utilization. Without this check, + // this would be theoretically 0%, which is infinitely worse. + // + // See https://go.dev/issue/27735. + switch { + case cap(e.buf) <= 4<<10: // always recycle buffers smaller than 4KiB + e.bufStats.strikes = 0 + case cap(e.buf)/4 <= len(e.buf): // at least 25% utilization + e.bufStats.strikes = 0 + case e.bufStats.strikes < 4: // at most 4 strikes + e.bufStats.strikes++ + default: // discard the buffer; too large and too often under-utilized + e.bufStats.strikes = 0 + e.bufStats.prevLen = len(e.buf) // heuristic for size to allocate next time + e.buf = nil + } + bufferedEncoderPool.Put(e) +} + +func getStreamingEncoder(w io.Writer, o EncodeOptions) *Encoder { + if _, ok := w.(*bytes.Buffer); ok { + e := bytesBufferEncoderPool.Get().(*Encoder) + e.reset(nil, w, o) // buffer taken from bytes.Buffer + return e + } else { + e := streamingEncoderPool.Get().(*Encoder) + e.reset(e.buf[:0], w, o) // preserve existing buffer + return e + } +} +func putStreamingEncoder(e *Encoder) { + if _, ok := e.wr.(*bytes.Buffer); ok { + bytesBufferEncoderPool.Put(e) + } else { + if cap(e.buf) > 64<<10 { + e.buf = nil // avoid pinning arbitrarily large amounts of memory + } + streamingEncoderPool.Put(e) + } +} + +var ( + // This does not own the internal buffer since it is externally provided. + bufferedDecoderPool = &sync.Pool{New: func() any { return new(Decoder) }} + + // This owns the internal buffer, but it is only used to temporarily store + // buffered JSON fetched from the underlying io.Reader. + // In a sufficiently efficient streaming mode, we do not expect the buffer + // to grow arbitrarily large. Thus, we avoid recycling large buffers. + streamingDecoderPool = &sync.Pool{New: func() any { return new(Decoder) }} + + // This does not own the internal buffer since + // it is taken directly from the provided bytes.Buffer. + bytesBufferDecoderPool = bufferedDecoderPool +) + +func getBufferedDecoder(b []byte, o DecodeOptions) *Decoder { + d := bufferedDecoderPool.Get().(*Decoder) + d.reset(b, nil, o) + return d +} +func putBufferedDecoder(d *Decoder) { + bufferedDecoderPool.Put(d) +} + +func getStreamingDecoder(r io.Reader, o DecodeOptions) *Decoder { + if _, ok := r.(*bytes.Buffer); ok { + d := bytesBufferDecoderPool.Get().(*Decoder) + d.reset(nil, r, o) // buffer taken from bytes.Buffer + return d + } else { + d := streamingDecoderPool.Get().(*Decoder) + d.reset(d.buf[:0], r, o) // preserve existing buffer + return d + } +} +func putStreamingDecoder(d *Decoder) { + if _, ok := d.rd.(*bytes.Buffer); ok { + bytesBufferDecoderPool.Put(d) + } else { + if cap(d.buf) > 64<<10 { + d.buf = nil // avoid pinning arbitrarily large amounts of memory + } + streamingDecoderPool.Put(d) + } +} + +var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }} + +type stringSlice []string + +// getStrings returns a non-nil pointer to a slice with length n. +func getStrings(n int) *stringSlice { + s := stringsPools.Get().(*stringSlice) + if cap(*s) < n { + *s = make([]string, n) + } + *s = (*s)[:n] + return s +} + +func putStrings(s *stringSlice) { + if cap(*s) > 1<<10 { + *s = nil // avoid pinning arbitrarily large amounts of memory + } + stringsPools.Put(s) +} + +// Sort sorts the string slice according to RFC 8785, section 3.2.3. +func (ss *stringSlice) Sort() { + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Sort(ss) +} + +func (ss *stringSlice) Len() int { return len(*ss) } +func (ss *stringSlice) Less(i, j int) bool { return lessUTF16((*ss)[i], (*ss)[j]) } +func (ss *stringSlice) Swap(i, j int) { (*ss)[i], (*ss)[j] = (*ss)[j], (*ss)[i] } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go new file mode 100644 index 00000000000..ee14c753fee --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go @@ -0,0 +1,747 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "math" + "strconv" +) + +var ( + errMissingName = &SyntacticError{str: "missing string for object name"} + errMissingColon = &SyntacticError{str: "missing character ':' after object name"} + errMissingValue = &SyntacticError{str: "missing value after object name"} + errMissingComma = &SyntacticError{str: "missing character ',' after object or array value"} + errMismatchDelim = &SyntacticError{str: "mismatching structural token for object or array"} +) + +const errInvalidNamespace = jsonError("object namespace is in an invalid state") + +type state struct { + // tokens validates whether the next token kind is valid. + tokens stateMachine + + // names is a stack of object names. + // Not used if AllowDuplicateNames is true. + names objectNameStack + + // namespaces is a stack of object namespaces. + // For performance reasons, Encoder or Decoder may not update this + // if Marshal or Unmarshal is able to track names in a more efficient way. + // See makeMapArshaler and makeStructArshaler. + // Not used if AllowDuplicateNames is true. + namespaces objectNamespaceStack +} + +func (s *state) reset() { + s.tokens.reset() + s.names.reset() + s.namespaces.reset() +} + +// appendStackPointer appends a JSON Pointer (RFC 6901) to the current value. +// The returned pointer is only accurate if s.names is populated, +// otherwise it uses the numeric index as the object member name. +// +// Invariant: Must call s.names.copyQuotedBuffer beforehand. +func (s state) appendStackPointer(b []byte) []byte { + var objectDepth int + for i := 1; i < s.tokens.depth(); i++ { + e := s.tokens.index(i) + if e.length() == 0 { + break // empty object or array + } + b = append(b, '/') + switch { + case e.isObject(): + if objectDepth < s.names.length() { + for _, c := range s.names.getUnquoted(objectDepth) { + // Per RFC 6901, section 3, escape '~' and '/' characters. + switch c { + case '~': + b = append(b, "~0"...) + case '/': + b = append(b, "~1"...) + default: + b = append(b, c) + } + } + } else { + // Since the names stack is unpopulated, the name is unknown. + // As a best-effort replacement, use the numeric member index. + // While inaccurate, it produces a syntactically valid pointer. + b = strconv.AppendUint(b, uint64((e.length()-1)/2), 10) + } + objectDepth++ + case e.isArray(): + b = strconv.AppendUint(b, uint64(e.length()-1), 10) + } + } + return b +} + +// stateMachine is a push-down automaton that validates whether +// a sequence of tokens is valid or not according to the JSON grammar. +// It is useful for both encoding and decoding. +// +// It is a stack where each entry represents a nested JSON object or array. +// The stack has a minimum depth of 1 where the first level is a +// virtual JSON array to handle a stream of top-level JSON values. +// The top-level virtual JSON array is special in that it doesn't require commas +// between each JSON value. +// +// For performance, most methods are carefully written to be inlineable. +// The zero value is a valid state machine ready for use. +type stateMachine struct { + stack []stateEntry + last stateEntry +} + +// reset resets the state machine. +// The machine always starts with a minimum depth of 1. +func (m *stateMachine) reset() { + m.stack = m.stack[:0] + if cap(m.stack) > 1<<10 { + m.stack = nil + } + m.last = stateTypeArray +} + +// depth is the current nested depth of JSON objects and arrays. +// It is one-indexed (i.e., top-level values have a depth of 1). +func (m stateMachine) depth() int { + return len(m.stack) + 1 +} + +// index returns a reference to the ith entry. +// It is only valid until the next push method call. +func (m *stateMachine) index(i int) *stateEntry { + if i == len(m.stack) { + return &m.last + } + return &m.stack[i] +} + +// depthLength reports the current nested depth and +// the length of the last JSON object or array. +func (m stateMachine) depthLength() (int, int) { + return m.depth(), m.last.length() +} + +// appendLiteral appends a JSON literal as the next token in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) appendLiteral() error { + switch { + case m.last.needObjectName(): + return errMissingName + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last.increment() + return nil + } +} + +// appendString appends a JSON string as the next token in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) appendString() error { + switch { + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last.increment() + return nil + } +} + +// appendNumber appends a JSON number as the next token in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) appendNumber() error { + return m.appendLiteral() +} + +// pushObject appends a JSON start object token as next in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) pushObject() error { + switch { + case m.last.needObjectName(): + return errMissingName + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last.increment() + m.stack = append(m.stack, m.last) + m.last = stateTypeObject + return nil + } +} + +// popObject appends a JSON end object token as next in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) popObject() error { + switch { + case !m.last.isObject(): + return errMismatchDelim + case m.last.needObjectValue(): + return errMissingValue + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last = m.stack[len(m.stack)-1] + m.stack = m.stack[:len(m.stack)-1] + return nil + } +} + +// pushArray appends a JSON start array token as next in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) pushArray() error { + switch { + case m.last.needObjectName(): + return errMissingName + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last.increment() + m.stack = append(m.stack, m.last) + m.last = stateTypeArray + return nil + } +} + +// popArray appends a JSON end array token as next in the sequence. +// If an error is returned, the state is not mutated. +func (m *stateMachine) popArray() error { + switch { + case !m.last.isArray() || len(m.stack) == 0: // forbid popping top-level virtual JSON array + return errMismatchDelim + case !m.last.isValidNamespace(): + return errInvalidNamespace + default: + m.last = m.stack[len(m.stack)-1] + m.stack = m.stack[:len(m.stack)-1] + return nil + } +} + +// needIndent reports whether indent whitespace should be injected. +// A zero value means that no whitespace should be injected. +// A positive value means '\n', indentPrefix, and (n-1) copies of indentBody +// should be appended to the output immediately before the next token. +func (m stateMachine) needIndent(next Kind) (n int) { + willEnd := next == '}' || next == ']' + switch { + case m.depth() == 1: + return 0 // top-level values are never indented + case m.last.length() == 0 && willEnd: + return 0 // an empty object or array is never indented + case m.last.length() == 0 || m.last.needImplicitComma(next): + return m.depth() + case willEnd: + return m.depth() - 1 + default: + return 0 + } +} + +// mayAppendDelim appends a colon or comma that may precede the next token. +func (m stateMachine) mayAppendDelim(b []byte, next Kind) []byte { + switch { + case m.last.needImplicitColon(): + return append(b, ':') + case m.last.needImplicitComma(next) && len(m.stack) != 0: // comma not needed for top-level values + return append(b, ',') + default: + return b + } +} + +// needDelim reports whether a colon or comma token should be implicitly emitted +// before the next token of the specified kind. +// A zero value means no delimiter should be emitted. +func (m stateMachine) needDelim(next Kind) (delim byte) { + switch { + case m.last.needImplicitColon(): + return ':' + case m.last.needImplicitComma(next) && len(m.stack) != 0: // comma not needed for top-level values + return ',' + default: + return 0 + } +} + +// checkDelim reports whether the specified delimiter should be there given +// the kind of the next token that appears immediately afterwards. +func (m stateMachine) checkDelim(delim byte, next Kind) error { + switch needDelim := m.needDelim(next); { + case needDelim == delim: + return nil + case needDelim == ':': + return errMissingColon + case needDelim == ',': + return errMissingComma + default: + return newInvalidCharacterError([]byte{delim}, "before next token") + } +} + +// invalidateDisabledNamespaces marks all disabled namespaces as invalid. +// +// For efficiency, Marshal and Unmarshal may disable namespaces since there are +// more efficient ways to track duplicate names. However, if an error occurs, +// the namespaces in Encoder or Decoder will be left in an inconsistent state. +// Mark the namespaces as invalid so that future method calls on +// Encoder or Decoder will return an error. +func (m *stateMachine) invalidateDisabledNamespaces() { + for i := 0; i < m.depth(); i++ { + e := m.index(i) + if !e.isActiveNamespace() { + e.invalidateNamespace() + } + } +} + +// stateEntry encodes several artifacts within a single unsigned integer: +// - whether this represents a JSON object or array, +// - whether this object should check for duplicate names, and +// - how many elements are in this JSON object or array. +type stateEntry uint64 + +const ( + // The type mask (1 bit) records whether this is a JSON object or array. + stateTypeMask stateEntry = 0x8000_0000_0000_0000 + stateTypeObject stateEntry = 0x8000_0000_0000_0000 + stateTypeArray stateEntry = 0x0000_0000_0000_0000 + + // The name check mask (2 bit) records whether to update + // the namespaces for the current JSON object and + // whether the namespace is valid. + stateNamespaceMask stateEntry = 0x6000_0000_0000_0000 + stateDisableNamespace stateEntry = 0x4000_0000_0000_0000 + stateInvalidNamespace stateEntry = 0x2000_0000_0000_0000 + + // The count mask (61 bits) records the number of elements. + stateCountMask stateEntry = 0x1fff_ffff_ffff_ffff + stateCountLSBMask stateEntry = 0x0000_0000_0000_0001 + stateCountOdd stateEntry = 0x0000_0000_0000_0001 + stateCountEven stateEntry = 0x0000_0000_0000_0000 +) + +// length reports the number of elements in the JSON object or array. +// Each name and value in an object entry is treated as a separate element. +func (e stateEntry) length() int { + return int(e & stateCountMask) +} + +// isObject reports whether this is a JSON object. +func (e stateEntry) isObject() bool { + return e&stateTypeMask == stateTypeObject +} + +// isArray reports whether this is a JSON array. +func (e stateEntry) isArray() bool { + return e&stateTypeMask == stateTypeArray +} + +// needObjectName reports whether the next token must be a JSON string, +// which is necessary for JSON object names. +func (e stateEntry) needObjectName() bool { + return e&(stateTypeMask|stateCountLSBMask) == stateTypeObject|stateCountEven +} + +// needImplicitColon reports whether an colon should occur next, +// which always occurs after JSON object names. +func (e stateEntry) needImplicitColon() bool { + return e.needObjectValue() +} + +// needObjectValue reports whether the next token must be a JSON value, +// which is necessary after every JSON object name. +func (e stateEntry) needObjectValue() bool { + return e&(stateTypeMask|stateCountLSBMask) == stateTypeObject|stateCountOdd +} + +// needImplicitComma reports whether an comma should occur next, +// which always occurs after a value in a JSON object or array +// before the next value (or name). +func (e stateEntry) needImplicitComma(next Kind) bool { + return !e.needObjectValue() && e.length() > 0 && next != '}' && next != ']' +} + +// increment increments the number of elements for the current object or array. +// This assumes that overflow won't practically be an issue since +// 1< 0. +func (e *stateEntry) decrement() { + (*e)-- +} + +// disableNamespace disables the JSON object namespace such that the +// Encoder or Decoder no longer updates the namespace. +func (e *stateEntry) disableNamespace() { + *e |= stateDisableNamespace +} + +// isActiveNamespace reports whether the JSON object namespace is actively +// being updated and used for duplicate name checks. +func (e stateEntry) isActiveNamespace() bool { + return e&(stateDisableNamespace) == 0 +} + +// invalidateNamespace marks the JSON object namespace as being invalid. +func (e *stateEntry) invalidateNamespace() { + *e |= stateInvalidNamespace +} + +// isValidNamespace reports whether the JSON object namespace is valid. +func (e stateEntry) isValidNamespace() bool { + return e&(stateInvalidNamespace) == 0 +} + +// objectNameStack is a stack of names when descending into a JSON object. +// In contrast to objectNamespaceStack, this only has to remember a single name +// per JSON object. +// +// This data structure may contain offsets to encodeBuffer or decodeBuffer. +// It violates clean abstraction of layers, but is significantly more efficient. +// This ensures that popping and pushing in the common case is a trivial +// push/pop of an offset integer. +// +// The zero value is an empty names stack ready for use. +type objectNameStack struct { + // offsets is a stack of offsets for each name. + // A non-negative offset is the ending offset into the local names buffer. + // A negative offset is the bit-wise inverse of a starting offset into + // a remote buffer (e.g., encodeBuffer or decodeBuffer). + // A math.MinInt offset at the end implies that the last object is empty. + // Invariant: Positive offsets always occur before negative offsets. + offsets []int + // unquotedNames is a back-to-back concatenation of names. + unquotedNames []byte +} + +func (ns *objectNameStack) reset() { + ns.offsets = ns.offsets[:0] + ns.unquotedNames = ns.unquotedNames[:0] + if cap(ns.offsets) > 1<<6 { + ns.offsets = nil // avoid pinning arbitrarily large amounts of memory + } + if cap(ns.unquotedNames) > 1<<10 { + ns.unquotedNames = nil // avoid pinning arbitrarily large amounts of memory + } +} + +func (ns *objectNameStack) length() int { + return len(ns.offsets) +} + +// getUnquoted retrieves the ith unquoted name in the namespace. +// It returns an empty string if the last object is empty. +// +// Invariant: Must call copyQuotedBuffer beforehand. +func (ns *objectNameStack) getUnquoted(i int) []byte { + ns.ensureCopiedBuffer() + if i == 0 { + return ns.unquotedNames[:ns.offsets[0]] + } else { + return ns.unquotedNames[ns.offsets[i-1]:ns.offsets[i-0]] + } +} + +// invalidOffset indicates that the last JSON object currently has no name. +const invalidOffset = math.MinInt + +// push descends into a nested JSON object. +func (ns *objectNameStack) push() { + ns.offsets = append(ns.offsets, invalidOffset) +} + +// replaceLastQuotedOffset replaces the last name with the starting offset +// to the quoted name in some remote buffer. All offsets provided must be +// relative to the same buffer until copyQuotedBuffer is called. +func (ns *objectNameStack) replaceLastQuotedOffset(i int) { + // Use bit-wise inversion instead of naive multiplication by -1 to avoid + // ambiguity regarding zero (which is a valid offset into the names field). + // Bit-wise inversion is mathematically equivalent to -i-1, + // such that 0 becomes -1, 1 becomes -2, and so forth. + // This ensures that remote offsets are always negative. + ns.offsets[len(ns.offsets)-1] = ^i +} + +// replaceLastUnquotedName replaces the last name with the provided name. +// +// Invariant: Must call copyQuotedBuffer beforehand. +func (ns *objectNameStack) replaceLastUnquotedName(s string) { + ns.ensureCopiedBuffer() + var startOffset int + if len(ns.offsets) > 1 { + startOffset = ns.offsets[len(ns.offsets)-2] + } + ns.unquotedNames = append(ns.unquotedNames[:startOffset], s...) + ns.offsets[len(ns.offsets)-1] = len(ns.unquotedNames) +} + +// clearLast removes any name in the last JSON object. +// It is semantically equivalent to ns.push followed by ns.pop. +func (ns *objectNameStack) clearLast() { + ns.offsets[len(ns.offsets)-1] = invalidOffset +} + +// pop ascends out of a nested JSON object. +func (ns *objectNameStack) pop() { + ns.offsets = ns.offsets[:len(ns.offsets)-1] +} + +// copyQuotedBuffer copies names from the remote buffer into the local names +// buffer so that there are no more offset references into the remote buffer. +// This allows the remote buffer to change contents without affecting +// the names that this data structure is trying to remember. +func (ns *objectNameStack) copyQuotedBuffer(b []byte) { + // Find the first negative offset. + var i int + for i = len(ns.offsets) - 1; i >= 0 && ns.offsets[i] < 0; i-- { + continue + } + + // Copy each name from the remote buffer into the local buffer. + for i = i + 1; i < len(ns.offsets); i++ { + if i == len(ns.offsets)-1 && ns.offsets[i] == invalidOffset { + if i == 0 { + ns.offsets[i] = 0 + } else { + ns.offsets[i] = ns.offsets[i-1] + } + break // last JSON object had a push without any names + } + + // As a form of Hyrum proofing, we write an invalid character into the + // buffer to make misuse of Decoder.ReadToken more obvious. + // We need to undo that mutation here. + quotedName := b[^ns.offsets[i]:] + if quotedName[0] == invalidateBufferByte { + quotedName[0] = '"' + } + + // Append the unquoted name to the local buffer. + var startOffset int + if i > 0 { + startOffset = ns.offsets[i-1] + } + if n := consumeSimpleString(quotedName); n > 0 { + ns.unquotedNames = append(ns.unquotedNames[:startOffset], quotedName[len(`"`):n-len(`"`)]...) + } else { + ns.unquotedNames, _ = unescapeString(ns.unquotedNames[:startOffset], quotedName) + } + ns.offsets[i] = len(ns.unquotedNames) + } +} + +func (ns *objectNameStack) ensureCopiedBuffer() { + if len(ns.offsets) > 0 && ns.offsets[len(ns.offsets)-1] < 0 { + panic("BUG: copyQuotedBuffer not called beforehand") + } +} + +// objectNamespaceStack is a stack of object namespaces. +// This data structure assists in detecting duplicate names. +type objectNamespaceStack []objectNamespace + +// reset resets the object namespace stack. +func (nss *objectNamespaceStack) reset() { + if cap(*nss) > 1<<10 { + *nss = nil + } + *nss = (*nss)[:0] +} + +// push starts a new namespace for a nested JSON object. +func (nss *objectNamespaceStack) push() { + if cap(*nss) > len(*nss) { + *nss = (*nss)[:len(*nss)+1] + nss.last().reset() + } else { + *nss = append(*nss, objectNamespace{}) + } +} + +// last returns a pointer to the last JSON object namespace. +func (nss objectNamespaceStack) last() *objectNamespace { + return &nss[len(nss)-1] +} + +// pop terminates the namespace for a nested JSON object. +func (nss *objectNamespaceStack) pop() { + *nss = (*nss)[:len(*nss)-1] +} + +// objectNamespace is the namespace for a JSON object. +// In contrast to objectNameStack, this needs to remember a all names +// per JSON object. +// +// The zero value is an empty namespace ready for use. +type objectNamespace struct { + // It relies on a linear search over all the names before switching + // to use a Go map for direct lookup. + + // endOffsets is a list of offsets to the end of each name in buffers. + // The length of offsets is the number of names in the namespace. + endOffsets []uint + // allUnquotedNames is a back-to-back concatenation of every name in the namespace. + allUnquotedNames []byte + // mapNames is a Go map containing every name in the namespace. + // Only valid if non-nil. + mapNames map[string]struct{} +} + +// reset resets the namespace to be empty. +func (ns *objectNamespace) reset() { + ns.endOffsets = ns.endOffsets[:0] + ns.allUnquotedNames = ns.allUnquotedNames[:0] + ns.mapNames = nil + if cap(ns.endOffsets) > 1<<6 { + ns.endOffsets = nil // avoid pinning arbitrarily large amounts of memory + } + if cap(ns.allUnquotedNames) > 1<<10 { + ns.allUnquotedNames = nil // avoid pinning arbitrarily large amounts of memory + } +} + +// length reports the number of names in the namespace. +func (ns *objectNamespace) length() int { + return len(ns.endOffsets) +} + +// getUnquoted retrieves the ith unquoted name in the namespace. +func (ns *objectNamespace) getUnquoted(i int) []byte { + if i == 0 { + return ns.allUnquotedNames[:ns.endOffsets[0]] + } else { + return ns.allUnquotedNames[ns.endOffsets[i-1]:ns.endOffsets[i-0]] + } +} + +// lastUnquoted retrieves the last name in the namespace. +func (ns *objectNamespace) lastUnquoted() []byte { + return ns.getUnquoted(ns.length() - 1) +} + +// insertQuoted inserts a name and reports whether it was inserted, +// which only occurs if name is not already in the namespace. +// The provided name must be a valid JSON string. +func (ns *objectNamespace) insertQuoted(name []byte, isVerbatim bool) bool { + if isVerbatim { + name = name[len(`"`) : len(name)-len(`"`)] + } + return ns.insert(name, !isVerbatim) +} +func (ns *objectNamespace) insertUnquoted(name []byte) bool { + return ns.insert(name, false) +} +func (ns *objectNamespace) insert(name []byte, quoted bool) bool { + var allNames []byte + if quoted { + allNames, _ = unescapeString(ns.allUnquotedNames, name) + } else { + allNames = append(ns.allUnquotedNames, name...) + } + name = allNames[len(ns.allUnquotedNames):] + + // Switch to a map if the buffer is too large for linear search. + // This does not add the current name to the map. + if ns.mapNames == nil && (ns.length() > 64 || len(ns.allUnquotedNames) > 1024) { + ns.mapNames = make(map[string]struct{}) + var startOffset uint + for _, endOffset := range ns.endOffsets { + name := ns.allUnquotedNames[startOffset:endOffset] + ns.mapNames[string(name)] = struct{}{} // allocates a new string + startOffset = endOffset + } + } + + if ns.mapNames == nil { + // Perform linear search over the buffer to find matching names. + // It provides O(n) lookup, but does not require any allocations. + var startOffset uint + for _, endOffset := range ns.endOffsets { + if string(ns.allUnquotedNames[startOffset:endOffset]) == string(name) { + return false + } + startOffset = endOffset + } + } else { + // Use the map if it is populated. + // It provides O(1) lookup, but requires a string allocation per name. + if _, ok := ns.mapNames[string(name)]; ok { + return false + } + ns.mapNames[string(name)] = struct{}{} // allocates a new string + } + + ns.allUnquotedNames = allNames + ns.endOffsets = append(ns.endOffsets, uint(len(ns.allUnquotedNames))) + return true +} + +// removeLast removes the last name in the namespace. +func (ns *objectNamespace) removeLast() { + if ns.mapNames != nil { + delete(ns.mapNames, string(ns.lastUnquoted())) + } + if ns.length()-1 == 0 { + ns.endOffsets = ns.endOffsets[:0] + ns.allUnquotedNames = ns.allUnquotedNames[:0] + } else { + ns.endOffsets = ns.endOffsets[:ns.length()-1] + ns.allUnquotedNames = ns.allUnquotedNames[:ns.endOffsets[ns.length()-1]] + } +} + +type uintSet64 uint64 + +func (s uintSet64) has(i uint) bool { return s&(1< 0 } +func (s *uintSet64) set(i uint) { *s |= 1 << i } + +// uintSet is a set of unsigned integers. +// It is optimized for most integers being close to zero. +type uintSet struct { + lo uintSet64 + hi []uintSet64 +} + +// has reports whether i is in the set. +func (s *uintSet) has(i uint) bool { + if i < 64 { + return s.lo.has(i) + } else { + i -= 64 + iHi, iLo := int(i/64), i%64 + return iHi < len(s.hi) && s.hi[iHi].has(iLo) + } +} + +// insert inserts i into the set and reports whether it was the first insertion. +func (s *uintSet) insert(i uint) bool { + // TODO: Make this inlineable at least for the lower 64-bit case. + if i < 64 { + has := s.lo.has(i) + s.lo.set(i) + return !has + } else { + i -= 64 + iHi, iLo := int(i/64), i%64 + if iHi >= len(s.hi) { + s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...) + s.hi = s.hi[:cap(s.hi)] + } + has := s.hi[iHi].has(iLo) + s.hi[iHi].set(iLo) + return !has + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go new file mode 100644 index 00000000000..9acba7dadff --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go @@ -0,0 +1,522 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "math" + "strconv" +) + +// NOTE: Token is analogous to v1 json.Token. + +const ( + maxInt64 = math.MaxInt64 + minInt64 = math.MinInt64 + maxUint64 = math.MaxUint64 + minUint64 = 0 // for consistency and readability purposes + + invalidTokenPanic = "invalid json.Token; it has been voided by a subsequent json.Decoder call" +) + +// Token represents a lexical JSON token, which may be one of the following: +// - a JSON literal (i.e., null, true, or false) +// - a JSON string (e.g., "hello, world!") +// - a JSON number (e.g., 123.456) +// - a start or end delimiter for a JSON object (i.e., { or } ) +// - a start or end delimiter for a JSON array (i.e., [ or ] ) +// +// A Token cannot represent entire array or object values, while a RawValue can. +// There is no Token to represent commas and colons since +// these structural tokens can be inferred from the surrounding context. +type Token struct { + nonComparable + + // Tokens can exist in either a "raw" or an "exact" form. + // Tokens produced by the Decoder are in the "raw" form. + // Tokens returned by constructors are usually in the "exact" form. + // The Encoder accepts Tokens in either the "raw" or "exact" form. + // + // The following chart shows the possible values for each Token type: + // ╔═════════════════╦════════════╤════════════╤════════════╗ + // ║ Token type ║ raw field │ str field │ num field ║ + // ╠═════════════════╬════════════╪════════════╪════════════╣ + // ║ null (raw) ║ "null" │ "" │ 0 ║ + // ║ false (raw) ║ "false" │ "" │ 0 ║ + // ║ true (raw) ║ "true" │ "" │ 0 ║ + // ║ string (raw) ║ non-empty │ "" │ offset ║ + // ║ string (string) ║ nil │ non-empty │ 0 ║ + // ║ number (raw) ║ non-empty │ "" │ offset ║ + // ║ number (float) ║ nil │ "f" │ non-zero ║ + // ║ number (int64) ║ nil │ "i" │ non-zero ║ + // ║ number (uint64) ║ nil │ "u" │ non-zero ║ + // ║ object (delim) ║ "{" or "}" │ "" │ 0 ║ + // ║ array (delim) ║ "[" or "]" │ "" │ 0 ║ + // ╚═════════════════╩════════════╧════════════╧════════════╝ + // + // Notes: + // - For tokens stored in "raw" form, the num field contains the + // absolute offset determined by raw.previousOffsetStart(). + // The buffer itself is stored in raw.previousBuffer(). + // - JSON literals and structural characters are always in the "raw" form. + // - JSON strings and numbers can be in either "raw" or "exact" forms. + // - The exact zero value of JSON strings and numbers in the "exact" forms + // have ambiguous representation. Thus, they are always represented + // in the "raw" form. + + // raw contains a reference to the raw decode buffer. + // If non-nil, then its value takes precedence over str and num. + // It is only valid if num == raw.previousOffsetStart(). + raw *decodeBuffer + + // str is the unescaped JSON string if num is zero. + // Otherwise, it is "f", "i", or "u" if num should be interpreted + // as a float64, int64, or uint64, respectively. + str string + + // num is a float64, int64, or uint64 stored as a uint64 value. + // It is non-zero for any JSON number in the "exact" form. + num uint64 +} + +// TODO: Does representing 1-byte delimiters as *decodeBuffer cause performance issues? + +var ( + Null Token = rawToken("null") + False Token = rawToken("false") + True Token = rawToken("true") + + ObjectStart Token = rawToken("{") + ObjectEnd Token = rawToken("}") + ArrayStart Token = rawToken("[") + ArrayEnd Token = rawToken("]") + + zeroString Token = rawToken(`""`) + zeroNumber Token = rawToken(`0`) + + nanString Token = String("NaN") + pinfString Token = String("Infinity") + ninfString Token = String("-Infinity") +) + +func rawToken(s string) Token { + return Token{raw: &decodeBuffer{buf: []byte(s), prevStart: 0, prevEnd: len(s)}} +} + +// Bool constructs a Token representing a JSON boolean. +func Bool(b bool) Token { + if b { + return True + } + return False +} + +// String constructs a Token representing a JSON string. +// The provided string should contain valid UTF-8, otherwise invalid characters +// may be mangled as the Unicode replacement character. +func String(s string) Token { + if len(s) == 0 { + return zeroString + } + return Token{str: s} +} + +// Float constructs a Token representing a JSON number. +// The values NaN, +Inf, and -Inf will be represented +// as a JSON string with the values "NaN", "Infinity", and "-Infinity". +func Float(n float64) Token { + switch { + case math.Float64bits(n) == 0: + return zeroNumber + case math.IsNaN(n): + return nanString + case math.IsInf(n, +1): + return pinfString + case math.IsInf(n, -1): + return ninfString + } + return Token{str: "f", num: math.Float64bits(n)} +} + +// Int constructs a Token representing a JSON number from an int64. +func Int(n int64) Token { + if n == 0 { + return zeroNumber + } + return Token{str: "i", num: uint64(n)} +} + +// Uint constructs a Token representing a JSON number from a uint64. +func Uint(n uint64) Token { + if n == 0 { + return zeroNumber + } + return Token{str: "u", num: uint64(n)} +} + +// Clone makes a copy of the Token such that its value remains valid +// even after a subsequent Decoder.Read call. +func (t Token) Clone() Token { + // TODO: Allow caller to avoid any allocations? + if raw := t.raw; raw != nil { + // Avoid copying globals. + if t.raw.prevStart == 0 { + switch t.raw { + case Null.raw: + return Null + case False.raw: + return False + case True.raw: + return True + case ObjectStart.raw: + return ObjectStart + case ObjectEnd.raw: + return ObjectEnd + case ArrayStart.raw: + return ArrayStart + case ArrayEnd.raw: + return ArrayEnd + } + } + + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + // TODO(https://go.dev/issue/45038): Use bytes.Clone. + buf := append([]byte(nil), raw.previousBuffer()...) + return Token{raw: &decodeBuffer{buf: buf, prevStart: 0, prevEnd: len(buf)}} + } + return t +} + +// Bool returns the value for a JSON boolean. +// It panics if the token kind is not a JSON boolean. +func (t Token) Bool() bool { + switch t.raw { + case True.raw: + return true + case False.raw: + return false + default: + panic("invalid JSON token kind: " + t.Kind().String()) + } +} + +// appendString appends a JSON string to dst and returns it. +// It panics if t is not a JSON string. +func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRune func(rune) bool) ([]byte, error) { + if raw := t.raw; raw != nil { + // Handle raw string value. + buf := raw.previousBuffer() + if Kind(buf[0]) == '"' { + if escapeRune == nil && consumeSimpleString(buf) == len(buf) { + return append(dst, buf...), nil + } + dst, _, err := reformatString(dst, buf, validateUTF8, preserveRaw, escapeRune) + return dst, err + } + } else if len(t.str) != 0 && t.num == 0 { + // Handle exact string value. + return appendString(dst, t.str, validateUTF8, escapeRune) + } + + panic("invalid JSON token kind: " + t.Kind().String()) +} + +// String returns the unescaped string value for a JSON string. +// For other JSON kinds, this returns the raw JSON representation. +func (t Token) String() string { + // This is inlinable to take advantage of "function outlining". + // This avoids an allocation for the string(b) conversion + // if the caller does not use the string in an escaping manner. + // See https://blog.filippo.io/efficient-go-apis-with-the-inliner/ + s, b := t.string() + if len(b) > 0 { + return string(b) + } + return s +} +func (t Token) string() (string, []byte) { + if raw := t.raw; raw != nil { + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + buf := raw.previousBuffer() + if buf[0] == '"' { + // TODO: Preserve valueFlags in Token? + isVerbatim := consumeSimpleString(buf) == len(buf) + return "", unescapeStringMayCopy(buf, isVerbatim) + } + // Handle tokens that are not JSON strings for fmt.Stringer. + return "", buf + } + if len(t.str) != 0 && t.num == 0 { + return t.str, nil + } + // Handle tokens that are not JSON strings for fmt.Stringer. + if t.num > 0 { + switch t.str[0] { + case 'f': + return string(appendNumber(nil, math.Float64frombits(t.num), 64)), nil + case 'i': + return strconv.FormatInt(int64(t.num), 10), nil + case 'u': + return strconv.FormatUint(uint64(t.num), 10), nil + } + } + return "", nil +} + +// appendNumber appends a JSON number to dst and returns it. +// It panics if t is not a JSON number. +func (t Token) appendNumber(dst []byte, canonicalize bool) ([]byte, error) { + if raw := t.raw; raw != nil { + // Handle raw number value. + buf := raw.previousBuffer() + if Kind(buf[0]).normalize() == '0' { + if !canonicalize { + return append(dst, buf...), nil + } + dst, _, err := reformatNumber(dst, buf, canonicalize) + return dst, err + } + } else if t.num != 0 { + // Handle exact number value. + switch t.str[0] { + case 'f': + return appendNumber(dst, math.Float64frombits(t.num), 64), nil + case 'i': + return strconv.AppendInt(dst, int64(t.num), 10), nil + case 'u': + return strconv.AppendUint(dst, uint64(t.num), 10), nil + } + } + + panic("invalid JSON token kind: " + t.Kind().String()) +} + +// Float returns the floating-point value for a JSON number. +// It returns a NaN, +Inf, or -Inf value for any JSON string +// with the values "NaN", "Infinity", or "-Infinity". +// It panics for all other cases. +func (t Token) Float() float64 { + if raw := t.raw; raw != nil { + // Handle raw number value. + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + buf := raw.previousBuffer() + if Kind(buf[0]).normalize() == '0' { + fv, _ := parseFloat(buf, 64) + return fv + } + } else if t.num != 0 { + // Handle exact number value. + switch t.str[0] { + case 'f': + return math.Float64frombits(t.num) + case 'i': + return float64(int64(t.num)) + case 'u': + return float64(uint64(t.num)) + } + } + + // Handle string values with "NaN", "Infinity", or "-Infinity". + if t.Kind() == '"' { + switch t.String() { + case "NaN": + return math.NaN() + case "Infinity": + return math.Inf(+1) + case "-Infinity": + return math.Inf(-1) + } + } + + panic("invalid JSON token kind: " + t.Kind().String()) +} + +// Int returns the signed integer value for a JSON number. +// The fractional component of any number is ignored (truncation toward zero). +// Any number beyond the representation of an int64 will be saturated +// to the closest representable value. +// It panics if the token kind is not a JSON number. +func (t Token) Int() int64 { + if raw := t.raw; raw != nil { + // Handle raw integer value. + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + neg := false + buf := raw.previousBuffer() + if len(buf) > 0 && buf[0] == '-' { + neg, buf = true, buf[1:] + } + if numAbs, ok := parseDecUint(buf); ok { + if neg { + if numAbs > -minInt64 { + return minInt64 + } + return -1 * int64(numAbs) + } else { + if numAbs > +maxInt64 { + return maxInt64 + } + return +1 * int64(numAbs) + } + } + } else if t.num != 0 { + // Handle exact integer value. + switch t.str[0] { + case 'i': + return int64(t.num) + case 'u': + if t.num > maxInt64 { + return maxInt64 + } + return int64(t.num) + } + } + + // Handle JSON number that is a floating-point value. + if t.Kind() == '0' { + switch fv := t.Float(); { + case fv >= maxInt64: + return maxInt64 + case fv <= minInt64: + return minInt64 + default: + return int64(fv) // truncation toward zero + } + } + + panic("invalid JSON token kind: " + t.Kind().String()) +} + +// Uint returns the unsigned integer value for a JSON number. +// The fractional component of any number is ignored (truncation toward zero). +// Any number beyond the representation of an uint64 will be saturated +// to the closest representable value. +// It panics if the token kind is not a JSON number. +func (t Token) Uint() uint64 { + // NOTE: This accessor returns 0 for any negative JSON number, + // which might be surprising, but is at least consistent with the behavior + // of saturating out-of-bounds numbers to the closest representable number. + + if raw := t.raw; raw != nil { + // Handle raw integer value. + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + neg := false + buf := raw.previousBuffer() + if len(buf) > 0 && buf[0] == '-' { + neg, buf = true, buf[1:] + } + if num, ok := parseDecUint(buf); ok { + if neg { + return minUint64 + } + return num + } + } else if t.num != 0 { + // Handle exact integer value. + switch t.str[0] { + case 'u': + return t.num + case 'i': + if int64(t.num) < minUint64 { + return minUint64 + } + return uint64(int64(t.num)) + } + } + + // Handle JSON number that is a floating-point value. + if t.Kind() == '0' { + switch fv := t.Float(); { + case fv >= maxUint64: + return maxUint64 + case fv <= minUint64: + return minUint64 + default: + return uint64(fv) // truncation toward zero + } + } + + panic("invalid JSON token kind: " + t.Kind().String()) +} + +// Kind returns the token kind. +func (t Token) Kind() Kind { + switch { + case t.raw != nil: + raw := t.raw + if uint64(raw.previousOffsetStart()) != t.num { + panic(invalidTokenPanic) + } + return Kind(t.raw.buf[raw.prevStart]).normalize() + case t.num != 0: + return '0' + case len(t.str) != 0: + return '"' + default: + return invalidKind + } +} + +// Kind represents each possible JSON token kind with a single byte, +// which is conveniently the first byte of that kind's grammar +// with the restriction that numbers always be represented with '0': +// +// - 'n': null +// - 'f': false +// - 't': true +// - '"': string +// - '0': number +// - '{': object start +// - '}': object end +// - '[': array start +// - ']': array end +// +// An invalid kind is usually represented using 0, +// but may be non-zero due to invalid JSON data. +type Kind byte + +const invalidKind Kind = 0 + +// String prints the kind in a humanly readable fashion. +func (k Kind) String() string { + switch k { + case 'n': + return "null" + case 'f': + return "false" + case 't': + return "true" + case '"': + return "string" + case '0': + return "number" + case '{': + return "{" + case '}': + return "}" + case '[': + return "[" + case ']': + return "]" + default: + return "" + } +} + +// normalize coalesces all possible starting characters of a number as just '0'. +func (k Kind) normalize() Kind { + if k == '-' || ('0' <= k && k <= '9') { + return '0' + } + return k +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go new file mode 100644 index 00000000000..e0bd1b31d7a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go @@ -0,0 +1,381 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json + +import ( + "bytes" + "errors" + "io" + "sort" + "sync" + "unicode/utf16" + "unicode/utf8" +) + +// NOTE: RawValue is analogous to v1 json.RawMessage. + +// RawValue represents a single raw JSON value, which may be one of the following: +// - a JSON literal (i.e., null, true, or false) +// - a JSON string (e.g., "hello, world!") +// - a JSON number (e.g., 123.456) +// - an entire JSON object (e.g., {"fizz":"buzz"} ) +// - an entire JSON array (e.g., [1,2,3] ) +// +// RawValue can represent entire array or object values, while Token cannot. +// RawValue may contain leading and/or trailing whitespace. +type RawValue []byte + +// Clone returns a copy of v. +func (v RawValue) Clone() RawValue { + if v == nil { + return nil + } + return append(RawValue{}, v...) +} + +// String returns the string formatting of v. +func (v RawValue) String() string { + if v == nil { + return "null" + } + return string(v) +} + +// IsValid reports whether the raw JSON value is syntactically valid +// according to RFC 7493. +// +// It verifies whether the input is properly encoded as UTF-8, +// that escape sequences within strings decode to valid Unicode codepoints, and +// that all names in each object are unique. +// It does not verify whether numbers are representable within the limits +// of any common numeric type (e.g., float64, int64, or uint64). +func (v RawValue) IsValid() bool { + d := getBufferedDecoder(v, DecodeOptions{}) + defer putBufferedDecoder(d) + _, errVal := d.ReadValue() + _, errEOF := d.ReadToken() + return errVal == nil && errEOF == io.EOF +} + +// Compact removes all whitespace from the raw JSON value. +// +// It does not reformat JSON strings to use any other representation. +// It is guaranteed to succeed if the input is valid. +// If the value is already compacted, then the buffer is not mutated. +func (v *RawValue) Compact() error { + return v.reformat(false, false, "", "") +} + +// Indent reformats the whitespace in the raw JSON value so that each element +// in a JSON object or array begins on a new, indented line beginning with +// prefix followed by one or more copies of indent according to the nesting. +// The value does not begin with the prefix nor any indention, +// to make it easier to embed inside other formatted JSON data. +// +// It does not reformat JSON strings to use any other representation. +// It is guaranteed to succeed if the input is valid. +// If the value is already indented properly, then the buffer is not mutated. +func (v *RawValue) Indent(prefix, indent string) error { + return v.reformat(false, true, prefix, indent) +} + +// Canonicalize canonicalizes the raw JSON value according to the +// JSON Canonicalization Scheme (JCS) as defined by RFC 8785 +// where it produces a stable representation of a JSON value. +// +// The output stability is dependent on the stability of the application data +// (see RFC 8785, Appendix E). It cannot produce stable output from +// fundamentally unstable input. For example, if the JSON value +// contains ephemeral data (e.g., a frequently changing timestamp), +// then the value is still unstable regardless of whether this is called. +// +// Note that JCS treats all JSON numbers as IEEE 754 double precision numbers. +// Any numbers with precision beyond what is representable by that form +// will lose their precision when canonicalized. For example, integer values +// beyond ±2⁵³ will lose their precision. It is recommended that +// int64 and uint64 data types be represented as a JSON string. +// +// It is guaranteed to succeed if the input is valid. +// If the value is already canonicalized, then the buffer is not mutated. +func (v *RawValue) Canonicalize() error { + return v.reformat(true, false, "", "") +} + +// TODO: Instead of implementing the v1 Marshaler/Unmarshaler, +// consider implementing the v2 versions instead. + +// MarshalJSON returns v as the JSON encoding of v. +// It returns the stored value as the raw JSON output without any validation. +// If v is nil, then this returns a JSON null. +func (v RawValue) MarshalJSON() ([]byte, error) { + // NOTE: This matches the behavior of v1 json.RawMessage.MarshalJSON. + if v == nil { + return []byte("null"), nil + } + return v, nil +} + +// UnmarshalJSON sets v as the JSON encoding of b. +// It stores a copy of the provided raw JSON input without any validation. +func (v *RawValue) UnmarshalJSON(b []byte) error { + // NOTE: This matches the behavior of v1 json.RawMessage.UnmarshalJSON. + if v == nil { + return errors.New("json.RawValue: UnmarshalJSON on nil pointer") + } + *v = append((*v)[:0], b...) + return nil +} + +// Kind returns the starting token kind. +// For a valid value, this will never include '}' or ']'. +func (v RawValue) Kind() Kind { + if v := v[consumeWhitespace(v):]; len(v) > 0 { + return Kind(v[0]).normalize() + } + return invalidKind +} + +func (v *RawValue) reformat(canonical, multiline bool, prefix, indent string) error { + var eo EncodeOptions + if canonical { + eo.AllowInvalidUTF8 = false // per RFC 8785, section 3.2.4 + eo.AllowDuplicateNames = false // per RFC 8785, section 3.1 + eo.canonicalizeNumbers = true // per RFC 8785, section 3.2.2.3 + eo.EscapeRune = nil // per RFC 8785, section 3.2.2.2 + eo.multiline = false // per RFC 8785, section 3.2.1 + } else { + if s := trimLeftSpaceTab(prefix); len(s) > 0 { + panic("json: invalid character " + quoteRune([]byte(s)) + " in indent prefix") + } + if s := trimLeftSpaceTab(indent); len(s) > 0 { + panic("json: invalid character " + quoteRune([]byte(s)) + " in indent") + } + eo.AllowInvalidUTF8 = true + eo.AllowDuplicateNames = true + eo.preserveRawStrings = true + eo.multiline = multiline // in case indent is empty + eo.IndentPrefix = prefix + eo.Indent = indent + } + eo.omitTopLevelNewline = true + + // Write the entire value to reformat all tokens and whitespace. + e := getBufferedEncoder(eo) + defer putBufferedEncoder(e) + if err := e.WriteValue(*v); err != nil { + return err + } + + // For canonical output, we may need to reorder object members. + if canonical { + // Obtain a buffered encoder just to use its internal buffer as + // a scratch buffer in reorderObjects for reordering object members. + e2 := getBufferedEncoder(EncodeOptions{}) + defer putBufferedEncoder(e2) + + // Disable redundant checks performed earlier during encoding. + d := getBufferedDecoder(e.buf, DecodeOptions{AllowInvalidUTF8: true, AllowDuplicateNames: true}) + defer putBufferedDecoder(d) + reorderObjects(d, &e2.buf) // per RFC 8785, section 3.2.3 + } + + // Store the result back into the value if different. + if !bytes.Equal(*v, e.buf) { + *v = append((*v)[:0], e.buf...) + } + return nil +} + +func trimLeftSpaceTab(s string) string { + for i, r := range s { + switch r { + case ' ', '\t': + default: + return s[i:] + } + } + return "" +} + +type memberName struct { + // name is the unescaped name. + name []byte + // before and after are byte offsets into Decoder.buf that represents + // the entire name/value pair. It may contain leading commas. + before, after int64 +} + +var memberNamePool = sync.Pool{New: func() any { return new(memberNames) }} + +func getMemberNames() *memberNames { + ns := memberNamePool.Get().(*memberNames) + *ns = (*ns)[:0] + return ns +} +func putMemberNames(ns *memberNames) { + if cap(*ns) < 1<<10 { + for i := range *ns { + (*ns)[i] = memberName{} // avoid pinning name + } + memberNamePool.Put(ns) + } +} + +type memberNames []memberName + +func (m *memberNames) Len() int { return len(*m) } +func (m *memberNames) Less(i, j int) bool { return lessUTF16((*m)[i].name, (*m)[j].name) } +func (m *memberNames) Swap(i, j int) { (*m)[i], (*m)[j] = (*m)[j], (*m)[i] } + +// reorderObjects recursively reorders all object members in place +// according to the ordering specified in RFC 8785, section 3.2.3. +// +// Pre-conditions: +// - The value is valid (i.e., no decoder errors should ever occur). +// - The value is compact (i.e., no whitespace is present). +// - Initial call is provided a Decoder reading from the start of v. +// +// Post-conditions: +// - Exactly one JSON value is read from the Decoder. +// - All fully-parsed JSON objects are reordered by directly moving +// the members in the value buffer. +// +// The runtime is approximately O(n·log(n)) + O(m·log(m)), +// where n is len(v) and m is the total number of object members. +func reorderObjects(d *Decoder, scratch *[]byte) { + switch tok, _ := d.ReadToken(); tok.Kind() { + case '{': + // Iterate and collect the name and offsets for every object member. + members := getMemberNames() + defer putMemberNames(members) + var prevName []byte + isSorted := true + + beforeBody := d.InputOffset() // offset after '{' + for d.PeekKind() != '}' { + beforeName := d.InputOffset() + var flags valueFlags + name, _ := d.readValue(&flags) + name = unescapeStringMayCopy(name, flags.isVerbatim()) + reorderObjects(d, scratch) + afterValue := d.InputOffset() + + if isSorted && len(*members) > 0 { + isSorted = lessUTF16(prevName, []byte(name)) + } + *members = append(*members, memberName{name, beforeName, afterValue}) + prevName = name + } + afterBody := d.InputOffset() // offset before '}' + d.ReadToken() + + // Sort the members; return early if it's already sorted. + if isSorted { + return + } + // TODO(https://go.dev/issue/47619): Use slices.Sort. + sort.Sort(members) + + // Append the reordered members to a new buffer, + // then copy the reordered members back over the original members. + // Avoid swapping in place since each member may be a different size + // where moving a member over a smaller member may corrupt the data + // for subsequent members before they have been moved. + // + // The following invariant must hold: + // sum([m.after-m.before for m in members]) == afterBody-beforeBody + sorted := (*scratch)[:0] + for i, member := range *members { + if d.buf[member.before] == ',' { + member.before++ // trim leading comma + } + sorted = append(sorted, d.buf[member.before:member.after]...) + if i < len(*members)-1 { + sorted = append(sorted, ',') // append trailing comma + } + } + if int(afterBody-beforeBody) != len(sorted) { + panic("BUG: length invariant violated") + } + copy(d.buf[beforeBody:afterBody], sorted) + + // Update scratch buffer to the largest amount ever used. + if len(sorted) > len(*scratch) { + *scratch = sorted + } + case '[': + for d.PeekKind() != ']' { + reorderObjects(d, scratch) + } + d.ReadToken() + } +} + +// lessUTF16 reports whether x is lexicographically less than y according +// to the UTF-16 codepoints of the UTF-8 encoded input strings. +// This implements the ordering specified in RFC 8785, section 3.2.3. +// The inputs must be valid UTF-8, otherwise this may panic. +func lessUTF16[Bytes []byte | string](x, y Bytes) bool { + // NOTE: This is an optimized, allocation-free implementation + // of lessUTF16Simple in fuzz_test.go. FuzzLessUTF16 verifies that the + // two implementations agree on the result of comparing any two strings. + + isUTF16Self := func(r rune) bool { + return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF') + } + + var invalidUTF8 bool + x0, y0 := x, y + for { + if len(x) == 0 || len(y) == 0 { + if len(x) == len(y) && invalidUTF8 { + return string(x0) < string(y0) + } + return len(x) < len(y) + } + + // ASCII fast-path. + if x[0] < utf8.RuneSelf || y[0] < utf8.RuneSelf { + if x[0] != y[0] { + return x[0] < y[0] + } + x, y = x[1:], y[1:] + continue + } + + // Decode next pair of runes as UTF-8. + // TODO(https://go.dev/issue/56948): Use a generic implementation + // of utf8.DecodeRune, or rely on a compiler optimization to statically + // hide the cost of a type switch (https://go.dev/issue/57072). + var rx, ry rune + var nx, ny int + switch any(x).(type) { + case string: + rx, nx = utf8.DecodeRuneInString(string(x)) + ry, ny = utf8.DecodeRuneInString(string(y)) + case []byte: + rx, nx = utf8.DecodeRune([]byte(x)) + ry, ny = utf8.DecodeRune([]byte(y)) + } + + selfx := isUTF16Self(rx) + selfy := isUTF16Self(ry) + switch { + // The x rune is a single UTF-16 codepoint, while + // the y rune is a surrogate pair of UTF-16 codepoints. + case selfx && !selfy: + ry, _ = utf16.EncodeRune(ry) + // The y rune is a single UTF-16 codepoint, while + // the x rune is a surrogate pair of UTF-16 codepoints. + case selfy && !selfx: + rx, _ = utf16.EncodeRune(rx) + } + if rx != ry { + return rx < ry + } + invalidUTF8 = invalidUTF8 || (rx == utf8.RuneError && nx == 1) || (ry == utf8.RuneError && ny == 1) + x, y = x[nx:], y[ny:] + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go new file mode 100644 index 00000000000..61141a500d4 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go @@ -0,0 +1,260 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/validation/spec" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchemaFromOpenAPI converts a directory of OpenAPI schemas to an smd Schema. +// - models: a map from definition name to OpenAPI V3 structural schema for each definition. +// Key in map is used to resolve references in the schema. +// - preserveUnknownFields: flag indicating whether unknown fields in all schemas should be preserved. +// - returns: nil and an error if there is a parse error, or if schema does not satisfy a +// required structural schema invariant for conversion. If no error, returns +// a new smd schema. +// +// Schema should be validated as structural before using with this function, or +// there may be information lost. +func ToSchemaFromOpenAPI(models map[string]*spec.Schema, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + + for name, spec := range models { + // Skip/Ignore top-level references + if len(spec.Ref.String()) > 0 { + continue + } + + var a schema.Atom + + // Hard-coded schemas for now as proto_models implementation functions. + // https://github.com/kubernetes/kube-openapi/issues/364 + if name == quantityResource { + a = schema.Atom{ + Scalar: untypedDef.Atom.Scalar, + } + } else if name == rawExtensionResource { + a = untypedDef.Atom + } else { + c2 := c.push(name, &a) + c2.visitSpec(spec) + c.pop(c2) + } + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) visitSpec(m *spec.Schema) { + // Check if this schema opts its descendants into preserve-unknown-fields + if p, ok := m.Extensions["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + c.preserveUnknownFields = true + } + a := c.top() + *a = c.parseSchema(m) +} + +func (c *convert) parseSchema(m *spec.Schema) schema.Atom { + // k8s-generated OpenAPI specs have historically used only one value for + // type and starting with OpenAPIV3 it is only allowed to be + // a single string. + typ := "" + if len(m.Type) > 0 { + typ = m.Type[0] + } + + // Structural Schemas produced by kubernetes follow very specific rules which + // we can use to infer the SMD type: + switch typ { + case "": + // According to Swagger docs: + // https://swagger.io/docs/specification/data-models/data-types/#any + // + // If no type is specified, it is equivalent to accepting any type. + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + List: c.parseList(m), + Map: c.parseObject(m), + } + + case "object": + return schema.Atom{ + Map: c.parseObject(m), + } + case "array": + return schema.Atom{ + List: c.parseList(m), + } + case "integer", "boolean", "number", "string": + return convertPrimitive(typ, m.Format) + default: + c.reportError("unrecognized type: '%v'", typ) + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + } + } +} + +func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { + refString := specSchema.Ref.String() + + // Special-case handling for $ref stored inside a single-element allOf + if len(refString) == 0 && len(specSchema.AllOf) == 1 && len(specSchema.AllOf[0].Ref.String()) > 0 { + refString = specSchema.AllOf[0].Ref.String() + } + + if _, n := path.Split(refString); len(n) > 0 { + //!TODO: Refactor the field ElementRelationship override + // we can generate the types with overrides ahead of time rather than + // requiring the hacky runtime support + // (could just create a normalized key struct containing all customizations + // to deduplicate) + mapRelationship, err := getMapElementRelationship(specSchema.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + if len(mapRelationship) > 0 { + return schema.TypeRef{ + NamedType: &n, + ElementRelationship: &mapRelationship, + } + } + + return schema.TypeRef{ + NamedType: &n, + } + + } + var inlined schema.Atom + + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &inlined) + c2.preserveUnknownFields = c.preserveUnknownFields + c2.visitSpec(specSchema) + c.pop(c2) + + return schema.TypeRef{ + Inlined: inlined, + } +} + +func (c *convert) parseObject(s *spec.Schema) *schema.Map { + var fields []schema.StructField + for name, member := range s.Properties { + fields = append(fields, schema.StructField{ + Name: name, + Type: c.makeOpenAPIRef(&member), + Default: member.Default, + }) + } + + // AdditionalProperties informs the schema of any "unknown" keys + // Unknown keys are enforced by the ElementType field. + elementType := func() schema.TypeRef { + if s.AdditionalProperties == nil { + // According to openAPI spec, an object without properties and without + // additionalProperties is assumed to be a free-form object. + if c.preserveUnknownFields || len(s.Properties) == 0 { + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + // If properties are specified, do not implicitly allow unknown + // fields + return schema.TypeRef{} + } else if s.AdditionalProperties.Schema != nil { + // Unknown fields use the referred schema + return c.makeOpenAPIRef(s.AdditionalProperties.Schema) + + } else if s.AdditionalProperties.Allows { + // A boolean instead of a schema was provided. Deduce the + // type from the value provided at runtime. + return schema.TypeRef{ + NamedType: &deducedName, + } + } else { + // Additional Properties are explicitly disallowed by the user. + // Ensure element type is empty. + return schema.TypeRef{} + } + }() + + relationship, err := getMapElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + return &schema.Map{ + Fields: fields, + ElementRelationship: relationship, + ElementType: elementType, + } +} + +func (c *convert) parseList(s *spec.Schema) *schema.List { + relationship, mapKeys, err := getListElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + elementType := func() schema.TypeRef { + if s.Items != nil { + if s.Items.Schema == nil || s.Items.Len() != 1 { + c.reportError("structural schema arrays must have exactly one member subtype") + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + subSchema := s.Items.Schema + if subSchema == nil { + subSchema = &s.Items.Schemas[0] + } + return c.makeOpenAPIRef(subSchema) + } else if len(s.Type) > 0 && len(s.Type[0]) > 0 { + c.reportError("`items` must be specified on arrays") + } + + // A list with no items specified is treated as "untyped". + return schema.TypeRef{ + NamedType: &untypedName, + } + + }() + + return &schema.List{ + ElementRelationship: relationship, + Keys: mapKeys, + ElementType: elementType, + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go new file mode 100644 index 00000000000..2c6fd76a911 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go @@ -0,0 +1,178 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/util/proto" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchema converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2). +func ToSchema(models proto.Models) (*schema.Schema, error) { + return ToSchemaWithPreserveUnknownFields(models, false) +} + +// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. +func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + for _, name := range models.ListModels() { + model := models.LookupModel(name) + + var a schema.Atom + c2 := c.push(name, &a) + model.Accept(c2) + c.pop(c2) + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { + var tr schema.TypeRef + if r, ok := model.(*proto.Ref); ok { + if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { + return schema.TypeRef{ + NamedType: &untypedName, + } + } + // reference a named type + _, n := path.Split(r.Reference()) + tr.NamedType = &n + + mapRelationship, err := getMapElementRelationship(model.GetExtensions()) + + if err != nil { + c.reportError(err.Error()) + } + + // empty string means unset. + if len(mapRelationship) > 0 { + tr.ElementRelationship = &mapRelationship + } + } else { + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &tr.Inlined) + c2.preserveUnknownFields = preserveUnknownFields + model.Accept(c2) + c.pop(c2) + + if tr == (schema.TypeRef{}) { + // emit warning? + tr.NamedType = &untypedName + } + } + return tr +} + +func (c *convert) VisitKind(k *proto.Kind) { + preserveUnknownFields := c.preserveUnknownFields + if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + preserveUnknownFields = true + } + + a := c.top() + a.Map = &schema.Map{} + for _, name := range k.FieldOrder { + member := k.Fields[name] + tr := c.makeRef(member, preserveUnknownFields) + a.Map.Fields = append(a.Map.Fields, schema.StructField{ + Name: name, + Type: tr, + Default: member.GetDefault(), + }) + } + + unions, err := makeUnions(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + return + } + // TODO: We should check that the fields and discriminator + // specified in the union are actual fields in the struct. + a.Map.Unions = unions + + if preserveUnknownFields { + a.Map.ElementType = schema.TypeRef{ + NamedType: &deducedName, + } + } + + a.Map.ElementRelationship, err = getMapElementRelationship(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } +} + +func (c *convert) VisitArray(a *proto.Array) { + relationship, mapKeys, err := getListElementRelationship(a.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + atom := c.top() + atom.List = &schema.List{ + ElementType: c.makeRef(a.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + Keys: mapKeys, + } +} + +func (c *convert) VisitMap(m *proto.Map) { + relationship, err := getMapElementRelationship(m.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + a := c.top() + a.Map = &schema.Map{ + ElementType: c.makeRef(m.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + } +} + +func (c *convert) VisitPrimitive(p *proto.Primitive) { + a := c.top() + if c.currentName == quantityResource { + a.Scalar = ptr(schema.Scalar("untyped")) + } else { + *a = convertPrimitive(p.Type, p.Format) + } +} + +func (c *convert) VisitArbitrary(a *proto.Arbitrary) { + *c.top() = deducedDef.Atom +} + +func (c *convert) VisitReference(proto.Reference) { + // Do nothing, we handle references specially +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go index 35241fde647..799d866d51f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go @@ -17,43 +17,18 @@ limitations under the License. package schemaconv import ( - "errors" "fmt" - "path" "sort" - "strings" - "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/schema" ) const ( - quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + rawExtensionResource = "io.k8s.apimachinery.pkg.runtime.RawExtension" ) -// ToSchema converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2). -func ToSchema(models proto.Models) (*schema.Schema, error) { - return ToSchemaWithPreserveUnknownFields(models, false) -} - -// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. -func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { - c := convert{ - input: models, - preserveUnknownFields: preserveUnknownFields, - output: &schema.Schema{}, - } - if err := c.convertAll(); err != nil { - return nil, err - } - c.addCommonTypes() - return c.output, nil -} - type convert struct { - input proto.Models preserveUnknownFields bool output *schema.Schema @@ -64,7 +39,6 @@ type convert struct { func (c *convert) push(name string, a *schema.Atom) *convert { return &convert{ - input: c.input, preserveUnknownFields: c.preserveUnknownFields, output: c.output, currentName: name, @@ -78,30 +52,17 @@ func (c *convert) pop(c2 *convert) { c.errorMessages = append(c.errorMessages, c2.errorMessages...) } -func (c *convert) convertAll() error { - for _, name := range c.input.ListModels() { - model := c.input.LookupModel(name) - c.insertTypeDef(name, model) - } - if len(c.errorMessages) > 0 { - return errors.New(strings.Join(c.errorMessages, "\n")) - } - return nil -} - func (c *convert) reportError(format string, args ...interface{}) { c.errorMessages = append(c.errorMessages, c.currentName+": "+fmt.Sprintf(format, args...), ) } -func (c *convert) insertTypeDef(name string, model proto.Schema) { +func (c *convert) insertTypeDef(name string, atom schema.Atom) { def := schema.TypeDef{ Name: name, + Atom: atom, } - c2 := c.push(name, &def.Atom) - model.Accept(c2) - c.pop(c2) if def.Atom == (schema.Atom{}) { // This could happen if there were a top-level reference. return @@ -156,32 +117,6 @@ var deducedDef schema.TypeDef = schema.TypeDef{ }, } -func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { - var tr schema.TypeRef - if r, ok := model.(*proto.Ref); ok { - if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { - return schema.TypeRef{ - NamedType: &untypedName, - } - } - // reference a named type - _, n := path.Split(r.Reference()) - tr.NamedType = &n - } else { - // compute the type inline - c2 := c.push("inlined in "+c.currentName, &tr.Inlined) - c2.preserveUnknownFields = preserveUnknownFields - model.Accept(c2) - c.pop(c2) - - if tr == (schema.TypeRef{}) { - // emit warning? - tr.NamedType = &untypedName - } - } - return tr -} - func makeUnions(extensions map[string]interface{}) ([]schema.Union, error) { schemaUnions := []schema.Union{} if iunions, ok := extensions["x-kubernetes-unions"]; ok { @@ -285,52 +220,6 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) { return union, nil } -func (c *convert) VisitKind(k *proto.Kind) { - preserveUnknownFields := c.preserveUnknownFields - if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { - preserveUnknownFields = true - } - - a := c.top() - a.Map = &schema.Map{} - for _, name := range k.FieldOrder { - member := k.Fields[name] - tr := c.makeRef(member, preserveUnknownFields) - a.Map.Fields = append(a.Map.Fields, schema.StructField{ - Name: name, - Type: tr, - Default: member.GetDefault(), - }) - } - - unions, err := makeUnions(k.GetExtensions()) - if err != nil { - c.reportError(err.Error()) - return - } - // TODO: We should check that the fields and discriminator - // specified in the union are actual fields in the struct. - a.Map.Unions = unions - - if preserveUnknownFields { - a.Map.ElementType = schema.TypeRef{ - NamedType: &deducedName, - } - } - - ext := k.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable - default: - c.reportError("unknown map type %v", val) - } - } -} - func toStringSlice(o interface{}) (out []string, ok bool) { switch t := o.(type) { case []interface{}: @@ -341,117 +230,108 @@ func toStringSlice(o interface{}) (out []string, ok bool) { } } return out, true + case []string: + return t, true } return nil, false } -func (c *convert) VisitArray(a *proto.Array) { - atom := c.top() - atom.List = &schema.List{ - ElementRelationship: schema.Atomic, - } - l := atom.List - l.ElementType = c.makeRef(a.SubType, c.preserveUnknownFields) - - ext := a.GetExtensions() +func ptr(s schema.Scalar) *schema.Scalar { return &s } - if val, ok := ext["x-kubernetes-list-type"]; ok { - if val == "atomic" { - l.ElementRelationship = schema.Atomic - } else if val == "set" { - l.ElementRelationship = schema.Associative - } else if val == "map" { - l.ElementRelationship = schema.Associative - if keys, ok := ext["x-kubernetes-list-map-keys"]; ok { - if keyNames, ok := toStringSlice(keys); ok { - l.Keys = keyNames - } else { - c.reportError("uninterpreted map keys: %#v", keys) - } - } else { - c.reportError("missing map keys") - } - } else { - c.reportError("unknown list type %v", val) - l.ElementRelationship = schema.Atomic - } - } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { - if val == "merge" || val == "merge,retainKeys" { - l.ElementRelationship = schema.Associative - if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { - if keyName, ok := key.(string); ok { - l.Keys = []string{keyName} - } else { - c.reportError("uninterpreted merge key: %#v", key) - } - } else { - // It's not an error for this to be absent, it - // means it's a set. - } - } else if val == "retainKeys" { - } else { - c.reportError("unknown patch strategy %v", val) - l.ElementRelationship = schema.Atomic +// Basic conversion functions to convert OpenAPI schema definitions to +// SMD Schema atoms +func convertPrimitive(typ string, format string) (a schema.Atom) { + switch typ { + case "integer": + a.Scalar = ptr(schema.Numeric) + case "number": + a.Scalar = ptr(schema.Numeric) + case "string": + switch format { + case "": + a.Scalar = ptr(schema.String) + case "byte": + // byte really means []byte and is encoded as a string. + a.Scalar = ptr(schema.String) + case "int-or-string": + a.Scalar = ptr(schema.Scalar("untyped")) + case "date-time": + a.Scalar = ptr(schema.Scalar("untyped")) + default: + a.Scalar = ptr(schema.Scalar("untyped")) } + case "boolean": + a.Scalar = ptr(schema.Boolean) + default: + a.Scalar = ptr(schema.Scalar("untyped")) } -} -func (c *convert) VisitMap(m *proto.Map) { - a := c.top() - a.Map = &schema.Map{} - a.Map.ElementType = c.makeRef(m.SubType, c.preserveUnknownFields) + return a +} - ext := m.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { +func getListElementRelationship(ext map[string]any) (schema.ElementRelationship, []string, error) { + if val, ok := ext["x-kubernetes-list-type"]; ok { switch val { case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable + return schema.Atomic, nil, nil + case "set": + return schema.Associative, nil, nil + case "map": + keys, ok := ext["x-kubernetes-list-map-keys"] + + if !ok { + return schema.Associative, nil, fmt.Errorf("missing map keys") + } + + keyNames, ok := toStringSlice(keys) + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted map keys: %#v", keys) + } + + return schema.Associative, keyNames, nil default: - c.reportError("unknown map type %v", val) + return schema.Atomic, nil, fmt.Errorf("unknown list type %v", val) } - } -} + } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { + switch val { + case "merge", "merge,retainKeys": + if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { + keyName, ok := key.(string) -func ptr(s schema.Scalar) *schema.Scalar { return &s } + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted merge key: %#v", key) + } -func (c *convert) VisitPrimitive(p *proto.Primitive) { - a := c.top() - if c.currentName == quantityResource { - a.Scalar = ptr(schema.Scalar("untyped")) - } else { - switch p.Type { - case proto.Integer: - a.Scalar = ptr(schema.Numeric) - case proto.Number: - a.Scalar = ptr(schema.Numeric) - case proto.String: - switch p.Format { - case "": - a.Scalar = ptr(schema.String) - case "byte": - // byte really means []byte and is encoded as a string. - a.Scalar = ptr(schema.String) - case "int-or-string": - a.Scalar = ptr(schema.Scalar("untyped")) - case "date-time": - a.Scalar = ptr(schema.Scalar("untyped")) - default: - a.Scalar = ptr(schema.Scalar("untyped")) + return schema.Associative, []string{keyName}, nil } - case proto.Boolean: - a.Scalar = ptr(schema.Boolean) + // It's not an error for x-kubernetes-patch-merge-key to be absent, + // it means it's a set + return schema.Associative, nil, nil + case "retainKeys": + return schema.Atomic, nil, nil default: - a.Scalar = ptr(schema.Scalar("untyped")) + return schema.Atomic, nil, fmt.Errorf("unknown patch strategy %v", val) } } -} -func (c *convert) VisitArbitrary(a *proto.Arbitrary) { - *c.top() = deducedDef.Atom + // Treat as atomic by default + return schema.Atomic, nil, nil } -func (c *convert) VisitReference(proto.Reference) { - // Do nothing, we handle references specially +// Returns map element relationship if specified, or empty string if unspecified +func getMapElementRelationship(ext map[string]any) (schema.ElementRelationship, error) { + val, ok := ext["x-kubernetes-map-type"] + if !ok { + // unset Map element relationship + return "", nil + } + + switch val { + case "atomic": + return schema.Atomic, nil + case "granular": + return schema.Separable, nil + default: + return "", fmt.Errorf("unknown map type %v", val) + } } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go index 51dac4bdf01..699291f1d8e 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -41,6 +44,9 @@ func (e *Encoding) MarshalJSON() ([]byte, error) { } func (e *Encoding) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.EncodingProps); err != nil { return err } @@ -50,6 +56,20 @@ func (e *Encoding) UnmarshalJSON(data []byte) error { return nil } +func (e *Encoding) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + EncodingProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.EncodingProps = x.EncodingProps + return nil +} + type EncodingProps struct { // Content Type for encoding a specific property ContentType string `json:"contentType,omitempty"` @@ -58,7 +78,7 @@ type EncodingProps struct { // Describes how a specific property value will be serialized depending on its type Style string `json:"style,omitempty"` // When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect - Explode string `json:"explode,omitempty"` + Explode bool `json:"explode,omitempty"` // AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 AllowReserved bool `json:"allowReserved,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go index 0f5ab983cc9..03b8727170f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go @@ -19,8 +19,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + + "k8s.io/kube-openapi/pkg/validation/spec" ) // Example https://swagger.io/specification/#example-object @@ -49,6 +52,9 @@ func (e *Example) MarshalJSON() ([]byte, error) { } func (e *Example) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.Refable); err != nil { return err } @@ -61,6 +67,23 @@ func (e *Example) UnmarshalJSON(data []byte) error { return nil } +func (e *Example) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExampleProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&e.Ref.Ref, x.Extensions); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExampleProps = x.ExampleProps + + return nil +} + type ExampleProps struct { // Summary holds a short description of the example Summary string `json:"summary,omitempty"` diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go index 117113e7a79..e79956721ac 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go @@ -18,8 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type ExternalDocumentation struct { @@ -48,6 +51,9 @@ func (e *ExternalDocumentation) MarshalJSON() ([]byte, error) { } func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.ExternalDocumentationProps); err != nil { return err } @@ -56,3 +62,16 @@ func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { } return nil } + +func (e *ExternalDocumentation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExternalDocumentationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExternalDocumentationProps = x.ExternalDocumentationProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go new file mode 100644 index 00000000000..bc19dd48ed6 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go @@ -0,0 +1,254 @@ +package spec3 + +import ( + "math/rand" + "strings" + + fuzz "github.com/google/gofuzz" + + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// refChance is the chance that a particular component will use a $ref +// instead of fuzzed. Expressed as a fraction 1/n, currently there is +// a 1/3 chance that a ref will be used. +const refChance = 3 + +const alphaNumChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func randAlphanumString() string { + arr := make([]string, rand.Intn(10)+5) + for i := 0; i < len(arr); i++ { + arr[i] = string(alphaNumChars[rand.Intn(len(alphaNumChars))]) + } + return strings.Join(arr, "") +} + +var OpenAPIV3FuzzFuncs []interface{} = []interface{}{ + func(s *string, c fuzz.Continue) { + // All OpenAPI V3 map keys must follow the corresponding + // regex. Note that this restricts the range for all other + // string values as well. + str := randAlphanumString() + *s = str + }, + func(o *OpenAPI, c fuzz.Continue) { + c.FuzzNoCustom(o) + o.Version = "3.0.0" + }, + func(r *interface{}, c fuzz.Continue) { + switch c.Intn(3) { + case 0: + *r = nil + case 1: + n := c.RandString() + "x" + *r = n + case 2: + n := c.Float64() + *r = n + } + }, + func(v **spec.Info, c fuzz.Continue) { + // Info is never nil + *v = &spec.Info{} + c.FuzzNoCustom(*v) + (*v).Title = c.RandString() + "x" + }, + func(v *Paths, c fuzz.Continue) { + c.Fuzz(&v.VendorExtensible) + num := c.Intn(5) + if num > 0 { + v.Paths = make(map[string]*Path) + } + for i := 0; i < num; i++ { + val := Path{} + c.Fuzz(&val) + v.Paths["/"+c.RandString()] = &val + } + }, + func(v *SecurityScheme, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + switch c.Intn(4) { + case 0: + v.Type = "apiKey" + v.Name = c.RandString() + "x" + switch c.Intn(3) { + case 0: + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + case 1: + v.Type = "http" + case 2: + v.Type = "oauth2" + v.Flows = make(map[string]*OAuthFlow) + flow := OAuthFlow{} + flow.AuthorizationUrl = c.RandString() + "x" + v.Flows["implicit"] = &flow + flow.Scopes = make(map[string]string) + flow.Scopes["foo"] = "bar" + case 3: + v.Type = "openIdConnect" + v.OpenIdConnectUrl = "https://" + c.RandString() + } + v.Scheme = "basic" + }, + func(v *spec.Ref, c fuzz.Continue) { + switch c.Intn(7) { + case 0: + *v = spec.MustCreateRef("#/components/schemas/" + randAlphanumString()) + case 1: + *v = spec.MustCreateRef("#/components/responses/" + randAlphanumString()) + case 2: + *v = spec.MustCreateRef("#/components/headers/" + randAlphanumString()) + case 3: + *v = spec.MustCreateRef("#/components/securitySchemes/" + randAlphanumString()) + case 5: + *v = spec.MustCreateRef("#/components/parameters/" + randAlphanumString()) + case 6: + *v = spec.MustCreateRef("#/components/requestBodies/" + randAlphanumString()) + } + }, + func(v *Parameter, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ParameterProps) + c.Fuzz(&v.VendorExtensible) + + switch c.Intn(3) { + case 0: + // Header param + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + }, + func(v *RequestBody, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.RequestBodyProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *Header, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.HeaderProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *ResponsesProps, c fuzz.Continue) { + c.Fuzz(&v.Default) + n := c.Intn(5) + for i := 0; i < n; i++ { + r2 := Response{} + c.Fuzz(&r2) + // HTTP Status code in 100-599 Range + code := c.Intn(500) + 100 + v.StatusCodeResponses = make(map[int]*Response) + v.StatusCodeResponses[code] = &r2 + } + }, + func(v *Response, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ResponseProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *spec.Extensions, c fuzz.Continue) { + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + if *v == nil { + *v = spec.Extensions{} + } + (*v)["x-"+c.RandString()] = c.RandString() + } + }, + func(v *spec.ExternalDocumentation, c fuzz.Continue) { + c.Fuzz(&v.Description) + v.URL = "https://" + randAlphanumString() + }, + func(v *spec.SchemaURL, c fuzz.Continue) { + *v = spec.SchemaURL("https://" + randAlphanumString()) + }, + func(v *spec.SchemaOrBool, c fuzz.Continue) { + *v = spec.SchemaOrBool{} + + if c.RandBool() { + v.Allows = c.RandBool() + } else { + v.Schema = &spec.Schema{} + v.Allows = true + c.Fuzz(&v.Schema) + } + }, + func(v *spec.SchemaOrArray, c fuzz.Continue) { + *v = spec.SchemaOrArray{} + if c.RandBool() { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schema = &schema + } else { + v.Schemas = []spec.Schema{} + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schemas = append(v.Schemas, schema) + } + + } + + }, + func(v *spec.SchemaOrStringArray, c fuzz.Continue) { + if c.RandBool() { + *v = spec.SchemaOrStringArray{} + if c.RandBool() { + c.Fuzz(&v.Property) + } else { + c.Fuzz(&v.Schema) + } + } + }, + func(v *spec.Schema, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Ref) + return + } + if c.RandBool() { + // file schema + c.Fuzz(&v.Default) + c.Fuzz(&v.Description) + c.Fuzz(&v.Example) + c.Fuzz(&v.ExternalDocs) + + c.Fuzz(&v.Format) + c.Fuzz(&v.ReadOnly) + c.Fuzz(&v.Required) + c.Fuzz(&v.Title) + v.Type = spec.StringOrArray{"file"} + + } else { + // normal schema + c.Fuzz(&v.SchemaProps) + c.Fuzz(&v.SwaggerSchemaProps) + c.Fuzz(&v.VendorExtensible) + c.Fuzz(&v.ExtraProps) + } + + }, +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go index cead4b15d1a..ee5a30f797a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,9 @@ func (h *Header) MarshalJSON() ([]byte, error) { } func (h *Header) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, h) + } if err := json.Unmarshal(data, &h.Refable); err != nil { return err } @@ -63,6 +68,22 @@ func (h *Header) UnmarshalJSON(data []byte) error { return nil } +func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + HeaderProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&h.Ref.Ref, x.Extensions); err != nil { + return err + } + h.Extensions = internal.SanitizeExtensions(x.Extensions) + h.HeaderProps = x.HeaderProps + return nil +} + // HeaderProps a struct that describes a header object type HeaderProps struct { // Description holds a brief description of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go index 828fd8dc56a..d390e69bcf7 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -44,6 +47,9 @@ func (m *MediaType) MarshalJSON() ([]byte, error) { } func (m *MediaType) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, m) + } if err := json.Unmarshal(data, &m.MediaTypeProps); err != nil { return err } @@ -53,10 +59,24 @@ func (m *MediaType) UnmarshalJSON(data []byte) error { return nil } +func (m *MediaType) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + MediaTypeProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + m.Extensions = internal.SanitizeExtensions(x.Extensions) + m.MediaTypeProps = x.MediaTypeProps + + return nil +} + // MediaTypeProps a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject type MediaTypeProps struct { // Schema holds the schema defining the type used for the media type - Schema *spec.Schema `json:"schema,omitempty"` + Schema *spec.Schema `json:"schema,omitempty"` // Example of the media type Example interface{} `json:"example,omitempty"` // Examples of the media type. Each example object should match the media type and specific schema if present diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go index de8aa46021c..28230610bd4 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Operation describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject @@ -46,12 +48,28 @@ func (o *Operation) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (o *Operation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, o) + } if err := json.Unmarshal(data, &o.OperationProps); err != nil { return err } return json.Unmarshal(data, &o.VendorExtensible) } +func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + OperationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + o.Extensions = internal.SanitizeExtensions(x.Extensions) + o.OperationProps = x.OperationProps + return nil +} + // OperationProps describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject type OperationProps struct { // Tags holds a list of tags for API documentation control @@ -73,7 +91,7 @@ type OperationProps struct { // Deprecated declares this operation to be deprecated Deprecated bool `json:"deprecated,omitempty"` // SecurityRequirement holds a declaration of which security mechanisms can be used for this operation - SecurityRequirement []*SecurityRequirement `json:"security,omitempty"` + SecurityRequirement []map[string][]string `json:"security,omitempty"` // Servers contains an alternative server array to service this operation Servers []*Server `json:"servers,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go index 0d7180e506e..613da71a6d3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,10 @@ func (p *Parameter) MarshalJSON() ([]byte, error) { } func (p *Parameter) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } + if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -63,6 +69,22 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return nil } +func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ParameterProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.ParameterProps = x.ParameterProps + return nil +} + // ParameterProps a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject type ParameterProps struct { // Name holds the name of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go index bc48c504deb..40d9061aceb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strings" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Paths describes the available paths and operations for the API, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject @@ -45,6 +48,9 @@ func (p *Paths) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Paths) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { return err @@ -74,6 +80,59 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } +func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *p = Paths{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + + if tok.Kind() == '}' { + return nil + } + + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if p.Extensions == nil { + p.Extensions = make(map[string]any) + } + p.Extensions[k] = ext + case len(k) > 0 && k[0] == '/': + pi := Path{} + if err := opts.UnmarshalNext(dec, &pi); err != nil { + return err + } + + if p.Paths == nil { + p.Paths = make(map[string]*Path) + } + p.Paths[k] = &pi + default: + _, err := dec.ReadValue() // skip value + if err != nil { + return err + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Path describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject // // Note that this struct is actually a thin wrapper around PathProps to make it referable and extensible @@ -101,6 +160,9 @@ func (p *Path) MarshalJSON() ([]byte, error) { } func (p *Path) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -113,6 +175,24 @@ func (p *Path) UnmarshalJSON(data []byte) error { return nil } +func (p *Path) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + PathProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathProps = x.PathProps + + return nil +} + // PathProps describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject type PathProps struct { // Summary holds a summary for all operations in this path diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go index 0adc628266b..33267ce675e 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // RequestBody describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject @@ -50,6 +52,9 @@ func (r *RequestBody) MarshalJSON() ([]byte, error) { } func (r *RequestBody) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -71,3 +76,19 @@ type RequestBodyProps struct { // Required determines if the request body is required in the request Required bool `json:"required,omitempty"` } + +func (r *RequestBody) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + RequestBodyProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.RequestBodyProps = x.RequestBodyProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go index ccd73369f75..95b388e6c60 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strconv" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Responses holds the list of possible responses as they are returned from executing this operation @@ -46,13 +49,15 @@ func (r *Responses) MarshalJSON() ([]byte, error) { } func (r *Responses) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { return err } if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } - return nil } @@ -78,25 +83,91 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals responses from JSON func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]*Response + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { - return nil + return err } if v, ok := res["default"]; ok { - r.Default = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.Default = &value delete(res, "default") } for k, v := range res { + // Take all integral keys if nk, err := strconv.Atoi(k); err == nil { if r.StatusCodeResponses == nil { r.StatusCodeResponses = map[int]*Response{} } - r.StatusCodeResponses[nk] = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.StatusCodeResponses[nk] = &value } } return nil } +func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *r = Responses{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + if tok.Kind() == '}' { + return nil + } + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if r.Extensions == nil { + r.Extensions = make(map[string]any) + } + r.Extensions[k] = ext + case k == "default": + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + r.ResponsesProps.Default = &resp + default: + if nk, err := strconv.Atoi(k); err == nil { + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + + if r.StatusCodeResponses == nil { + r.StatusCodeResponses = map[int]*Response{} + } + r.StatusCodeResponses[nk] = &resp + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Response describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject // // Note that this struct is actually a thin wrapper around ResponseProps to make it referable and extensible @@ -124,6 +195,9 @@ func (r *Response) MarshalJSON() ([]byte, error) { } func (r *Response) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -133,7 +207,22 @@ func (r *Response) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } + return nil +} +func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ResponseProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps return nil } @@ -149,7 +238,6 @@ type ResponseProps struct { Links map[string]*Link `json:"links,omitempty"` } - // Link represents a possible design-time link for a response, more at https://swagger.io/specification/#link-object type Link struct { spec.Refable @@ -175,6 +263,9 @@ func (r *Link) MarshalJSON() ([]byte, error) { } func (r *Link) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -188,6 +279,22 @@ func (r *Link) UnmarshalJSON(data []byte) error { return nil } +func (l *Link) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + LinkProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&l.Ref.Ref, x.Extensions); err != nil { + return err + } + l.Extensions = internal.SanitizeExtensions(x.Extensions) + l.LinkProps = x.LinkProps + return nil +} + // LinkProps describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject type LinkProps struct { // OperationId is the name of an existing, resolvable OAS operation diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go deleted file mode 100644 index 0ce8924efd7..00000000000 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package spec3 - -import ( - "encoding/json" - - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" -) - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -// -// Note that this struct is actually a thin wrapper around SecurityRequirementProps to make it referable and extensible -type SecurityRequirement struct { - SecurityRequirementProps - spec.VendorExtensible -} - -// MarshalJSON is a custom marshal function that knows how to encode SecurityRequirement as JSON -func (s *SecurityRequirement) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SecurityRequirementProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (s *SecurityRequirement) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &s.SecurityRequirementProps); err != nil { - return err - } - return json.Unmarshal(data, &s.VendorExtensible) -} - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -type SecurityRequirementProps map[string][]string diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go index 9b1352f4e3f..edf7e6de3f6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go @@ -19,8 +19,8 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/validation/spec" ) // SecurityScheme defines reusable Security Scheme Object, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go index a505fb2218b..d5df0a78110 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go @@ -18,9 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type Server struct { @@ -51,6 +53,10 @@ func (s *Server) MarshalJSON() ([]byte, error) { } func (s *Server) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } + if err := json.Unmarshal(data, &s.ServerProps); err != nil { return err } @@ -60,6 +66,20 @@ func (s *Server) UnmarshalJSON(data []byte) error { return nil } +func (s *Server) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerProps = x.ServerProps + + return nil +} + type ServerVariable struct { ServerVariableProps spec.VendorExtensible @@ -88,6 +108,9 @@ func (s *ServerVariable) MarshalJSON() ([]byte, error) { } func (s *ServerVariable) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } if err := json.Unmarshal(data, &s.ServerVariableProps); err != nil { return err } @@ -96,3 +119,17 @@ func (s *ServerVariable) UnmarshalJSON(data []byte) error { } return nil } + +func (s *ServerVariable) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerVariableProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerVariableProps = x.ServerVariableProps + + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go index 3ff48a3c3d7..bed096fb76b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go @@ -17,6 +17,10 @@ limitations under the License. package spec3 import ( + "encoding/json" + + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -35,3 +39,12 @@ type OpenAPI struct { // ExternalDocs holds additional external documentation ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` } + +func (o *OpenAPI) UnmarshalJSON(data []byte) error { + type OpenAPIWithNoFunctions OpenAPI + p := (*OpenAPIWithNoFunctions)(o) + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, &p) + } + return json.Unmarshal(data, &p) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go index a3f476d5d85..519dcf2ebae 100644 --- a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go +++ b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go @@ -120,7 +120,7 @@ func (d *Definitions) ParseSchemaV3(s *openapi_v3.Schema, path *Path) (Schema, e switch s.GetType() { case object: for _, extension := range s.GetSpecificationExtension() { - if extension.Name == "x-kuberentes-group-version-kind" { + if extension.Name == "x-kubernetes-group-version-kind" { // Objects with x-kubernetes-group-version-kind are always top // level types. return d.parseV3Kind(s, path) @@ -285,7 +285,7 @@ func parseV3Interface(def *yaml.Node) (interface{}, error) { func (d *Definitions) parseV3BaseSchema(s *openapi_v3.Schema, path *Path) (*BaseSchema, error) { if s == nil { - return nil, fmt.Errorf("cannot initializae BaseSchema from nil") + return nil, fmt.Errorf("cannot initialize BaseSchema from nil") } def, err := parseV3Interface(s.GetDefault().ToRawInfo()) diff --git a/vendor/k8s.io/kube-openapi/pkg/util/trie.go b/vendor/k8s.io/kube-openapi/pkg/util/trie.go new file mode 100644 index 00000000000..a9a76c17914 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/trie.go @@ -0,0 +1,79 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +// A simple trie implementation with Add and HasPrefix methods only. +type Trie struct { + children map[byte]*Trie + wordTail bool + word string +} + +// NewTrie creates a Trie and add all strings in the provided list to it. +func NewTrie(list []string) Trie { + ret := Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + for _, v := range list { + ret.Add(v) + } + return ret +} + +// Add adds a word to this trie +func (t *Trie) Add(v string) { + root := t + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + child = &Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + root.children[b] = child + } + root = child + } + root.wordTail = true + root.word = v +} + +// HasPrefix returns true of v has any of the prefixes stored in this trie. +func (t *Trie) HasPrefix(v string) bool { + _, has := t.GetPrefix(v) + return has +} + +// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise. +func (t *Trie) GetPrefix(v string) (string, bool) { + root := t + if root.wordTail { + return root.word, true + } + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + return "", false + } + if child.wordTail { + return child.word, true + } + root = child + } + return "", false +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/util.go b/vendor/k8s.io/kube-openapi/pkg/util/util.go new file mode 100644 index 00000000000..6eee935b22a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/util.go @@ -0,0 +1,115 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "reflect" + "strings" +) + +// [DEPRECATED] ToCanonicalName converts Golang package/type canonical name into REST friendly OpenAPI name. +// This method is deprecated because it has a misleading name. Please use ToRESTFriendlyName +// instead +// +// NOTE: actually the "canonical name" in this method should be named "REST friendly OpenAPI name", +// which is different from "canonical name" defined in GetCanonicalTypeName. The "canonical name" defined +// in GetCanonicalTypeName means Go type names with full package path. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToCanonicalName(name string) string { + return ToRESTFriendlyName(name) +} + +// ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToRESTFriendlyName(name string) string { + nameParts := strings.Split(name, "/") + // Reverse first part. e.g., io.k8s... instead of k8s.io... + if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { + parts := strings.Split(nameParts[0], ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + nameParts[0] = strings.Join(parts, ".") + } + return strings.Join(nameParts, ".") +} + +// OpenAPICanonicalTypeNamer is an interface for models without Go type to seed model name. +// +// OpenAPI canonical names are Go type names with full package path, for uniquely indentifying +// a model / Go type. If a Go type is vendored from another package, only the path after "/vendor/" +// should be used. For custom resource definition (CRD), the canonical name is expected to be +// +// group/version.kind +// +// Examples of canonical name: +// +// Go type: k8s.io/kubernetes/pkg/apis/core.Pod +// CRD: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// +// Example for vendored Go type: +// +// Original full path: k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +// +// Original full path: vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +type OpenAPICanonicalTypeNamer interface { + OpenAPICanonicalTypeName() string +} + +// GetCanonicalTypeName will find the canonical type name of a sample object, removing +// the "vendor" part of the path +func GetCanonicalTypeName(model interface{}) string { + if namer, ok := model.(OpenAPICanonicalTypeNamer); ok { + return namer.OpenAPICanonicalTypeName() + } + t := reflect.TypeOf(model) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.PkgPath() == "" { + return t.Name() + } + path := t.PkgPath() + if strings.Contains(path, "/vendor/") { + path = path[strings.Index(path, "/vendor/")+len("/vendor/"):] + } else if strings.HasPrefix(path, "vendor/") { + path = strings.TrimPrefix(path, "vendor/") + } + return path + "." + t.Name() +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go index 963d4274078..af01190ce61 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go @@ -13,7 +13,6 @@ // limitations under the License. /* - Package errors provides an Error interface and several concrete types implementing this interface to manage API errors and JSON-schema validation errors. @@ -23,6 +22,5 @@ it defines. It is used throughout the various go-openapi toolkit libraries (https://github.com/go-openapi). - */ package errors diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/fuzz.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/fuzz.go new file mode 100644 index 00000000000..c66f998f519 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/fuzz.go @@ -0,0 +1,502 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package spec + +import ( + "github.com/go-openapi/jsonreference" + "github.com/google/go-cmp/cmp" + fuzz "github.com/google/gofuzz" +) + +var SwaggerFuzzFuncs []interface{} = []interface{}{ + func(v *Responses, c fuzz.Continue) { + c.FuzzNoCustom(v) + if v.Default != nil { + // Check if we hit maxDepth and left an incomplete value + if v.Default.Description == "" { + v.Default = nil + v.StatusCodeResponses = nil + } + } + + // conversion has no way to discern empty statusCodeResponses from + // nil, since "default" is always included in the map. + // So avoid empty responses list + if len(v.StatusCodeResponses) == 0 { + v.StatusCodeResponses = nil + } + }, + func(v *Operation, c fuzz.Continue) { + c.FuzzNoCustom(v) + + if v != nil { + // force non-nil + v.Responses = &Responses{} + c.Fuzz(v.Responses) + + v.Schemes = nil + if c.RandBool() { + v.Schemes = append(v.Schemes, "http") + } + + if c.RandBool() { + v.Schemes = append(v.Schemes, "https") + } + + if c.RandBool() { + v.Schemes = append(v.Schemes, "ws") + } + + if c.RandBool() { + v.Schemes = append(v.Schemes, "wss") + } + + // Gnostic unconditionally makes security values non-null + // So do not fuzz null values into the array. + for i, val := range v.Security { + if val == nil { + v.Security[i] = make(map[string][]string) + } + + for k, v := range val { + if v == nil { + val[k] = make([]string, 0) + } + } + } + } + }, + func(v map[int]Response, c fuzz.Continue) { + n := 0 + c.Fuzz(&n) + if n == 0 { + // Test that fuzzer is not at maxDepth so we do not + // end up with empty elements + return + } + + // Prevent negative numbers + num := c.Intn(4) + for i := 0; i < num+2; i++ { + val := Response{} + c.Fuzz(&val) + + val.Description = c.RandString() + "x" + v[100*(i+1)+c.Intn(100)] = val + } + }, + func(v map[string]PathItem, c fuzz.Continue) { + n := 0 + c.Fuzz(&n) + if n == 0 { + // Test that fuzzer is not at maxDepth so we do not + // end up with empty elements + return + } + + num := c.Intn(5) + for i := 0; i < num+2; i++ { + val := PathItem{} + c.Fuzz(&val) + + // Ref params are only allowed in certain locations, so + // possibly add a few to PathItems + numRefsToAdd := c.Intn(5) + for i := 0; i < numRefsToAdd; i++ { + theRef := Parameter{} + c.Fuzz(&theRef.Refable) + + val.Parameters = append(val.Parameters, theRef) + } + + v["/"+c.RandString()] = val + } + }, + func(v *SchemaOrArray, c fuzz.Continue) { + *v = SchemaOrArray{} + // gnostic parser just doesn't support more + // than one Schema here + v.Schema = &Schema{} + c.Fuzz(&v.Schema) + + }, + func(v *SchemaOrBool, c fuzz.Continue) { + *v = SchemaOrBool{} + + if c.RandBool() { + v.Allows = c.RandBool() + } else { + v.Schema = &Schema{} + v.Allows = true + c.Fuzz(&v.Schema) + } + }, + func(v map[string]Response, c fuzz.Continue) { + n := 0 + c.Fuzz(&n) + if n == 0 { + // Test that fuzzer is not at maxDepth so we do not + // end up with empty elements + return + } + + // Response definitions are not allowed to + // be refs + for i := 0; i < c.Intn(5)+1; i++ { + resp := &Response{} + + c.Fuzz(resp) + resp.Ref = Ref{} + resp.Description = c.RandString() + "x" + + // Response refs are not vendor extensible by gnostic + resp.VendorExtensible.Extensions = nil + v[c.RandString()+"x"] = *resp + } + }, + func(v *Header, c fuzz.Continue) { + if v != nil { + c.FuzzNoCustom(v) + + // descendant Items of Header may not be refs + cur := v.Items + for cur != nil { + cur.Ref = Ref{} + cur = cur.Items + } + } + }, + func(v *Ref, c fuzz.Continue) { + *v = Ref{} + v.Ref, _ = jsonreference.New("http://asd.com/" + c.RandString()) + }, + func(v *Response, c fuzz.Continue) { + *v = Response{} + if c.RandBool() { + v.Ref = Ref{} + v.Ref.Ref, _ = jsonreference.New("http://asd.com/" + c.RandString()) + } else { + c.Fuzz(&v.VendorExtensible) + c.Fuzz(&v.Schema) + c.Fuzz(&v.ResponseProps) + + v.Headers = nil + v.Ref = Ref{} + + n := 0 + c.Fuzz(&n) + if n != 0 { + // Test that fuzzer is not at maxDepth so we do not + // end up with empty elements + num := c.Intn(4) + for i := 0; i < num; i++ { + if v.Headers == nil { + v.Headers = make(map[string]Header) + } + hdr := Header{} + c.Fuzz(&hdr) + if hdr.Type == "" { + // hit maxDepth, just abort trying to make haders + v.Headers = nil + break + } + v.Headers[c.RandString()+"x"] = hdr + } + } else { + v.Headers = nil + } + } + + v.Description = c.RandString() + "x" + + // Gnostic parses empty as nil, so to keep avoid putting empty + if len(v.Headers) == 0 { + v.Headers = nil + } + }, + func(v **Info, c fuzz.Continue) { + // Info is never nil + *v = &Info{} + c.FuzzNoCustom(*v) + + (*v).Title = c.RandString() + "x" + }, + func(v *Extensions, c fuzz.Continue) { + // gnostic parser only picks up x- vendor extensions + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + if *v == nil { + *v = Extensions{} + } + (*v)["x-"+c.RandString()] = c.RandString() + } + }, + func(v *Swagger, c fuzz.Continue) { + c.FuzzNoCustom(v) + + if v.Paths == nil { + // Force paths non-nil since it does not have omitempty in json tag. + // This means a perfect roundtrip (via json) is impossible, + // since we can't tell the difference between empty/unspecified paths + v.Paths = &Paths{} + c.Fuzz(v.Paths) + } + + v.Swagger = "2.0" + + // Gnostic support serializing ID at all + // unavoidable data loss + v.ID = "" + + v.Schemes = nil + if c.RandUint64()%2 == 1 { + v.Schemes = append(v.Schemes, "http") + } + + if c.RandUint64()%2 == 1 { + v.Schemes = append(v.Schemes, "https") + } + + if c.RandUint64()%2 == 1 { + v.Schemes = append(v.Schemes, "ws") + } + + if c.RandUint64()%2 == 1 { + v.Schemes = append(v.Schemes, "wss") + } + + // Gnostic unconditionally makes security values non-null + // So do not fuzz null values into the array. + for i, val := range v.Security { + if val == nil { + v.Security[i] = make(map[string][]string) + } + + for k, v := range val { + if v == nil { + val[k] = make([]string, 0) + } + } + } + }, + func(v *SecurityScheme, c fuzz.Continue) { + v.Description = c.RandString() + "x" + c.Fuzz(&v.VendorExtensible) + + switch c.Intn(3) { + case 0: + v.Type = "basic" + case 1: + v.Type = "apiKey" + switch c.Intn(2) { + case 0: + v.In = "header" + case 1: + v.In = "query" + default: + panic("unreachable") + } + v.Name = "x" + c.RandString() + case 2: + v.Type = "oauth2" + + switch c.Intn(4) { + case 0: + v.Flow = "accessCode" + v.TokenURL = "https://" + c.RandString() + v.AuthorizationURL = "https://" + c.RandString() + case 1: + v.Flow = "application" + v.TokenURL = "https://" + c.RandString() + case 2: + v.Flow = "implicit" + v.AuthorizationURL = "https://" + c.RandString() + case 3: + v.Flow = "password" + v.TokenURL = "https://" + c.RandString() + default: + panic("unreachable") + } + c.Fuzz(&v.Scopes) + default: + panic("unreachable") + } + }, + func(v *interface{}, c fuzz.Continue) { + *v = c.RandString() + "x" + }, + func(v *string, c fuzz.Continue) { + *v = c.RandString() + "x" + }, + func(v *ExternalDocumentation, c fuzz.Continue) { + v.Description = c.RandString() + "x" + v.URL = c.RandString() + "x" + }, + func(v *SimpleSchema, c fuzz.Continue) { + c.FuzzNoCustom(v) + + switch c.Intn(5) { + case 0: + v.Type = "string" + case 1: + v.Type = "number" + case 2: + v.Type = "boolean" + case 3: + v.Type = "integer" + case 4: + v.Type = "array" + default: + panic("unreachable") + } + + switch c.Intn(5) { + case 0: + v.CollectionFormat = "csv" + case 1: + v.CollectionFormat = "ssv" + case 2: + v.CollectionFormat = "tsv" + case 3: + v.CollectionFormat = "pipes" + case 4: + v.CollectionFormat = "" + default: + panic("unreachable") + } + + // None of the types which include SimpleSchema in our definitions + // actually support "example" in the official spec + v.Example = nil + + // unsupported by openapi + v.Nullable = false + }, + func(v *int64, c fuzz.Continue) { + c.Fuzz(v) + + // Gnostic does not differentiate between 0 and non-specified + // so avoid using 0 for fuzzer + if *v == 0 { + *v = 1 + } + }, + func(v *float64, c fuzz.Continue) { + c.Fuzz(v) + + // Gnostic does not differentiate between 0 and non-specified + // so avoid using 0 for fuzzer + if *v == 0.0 { + *v = 1.0 + } + }, + func(v *Parameter, c fuzz.Continue) { + if v == nil { + return + } + c.Fuzz(&v.VendorExtensible) + if c.RandBool() { + // body param + v.Description = c.RandString() + "x" + v.Name = c.RandString() + "x" + v.In = "body" + c.Fuzz(&v.Description) + c.Fuzz(&v.Required) + + v.Schema = &Schema{} + c.Fuzz(&v.Schema) + + } else { + c.Fuzz(&v.SimpleSchema) + c.Fuzz(&v.CommonValidations) + v.AllowEmptyValue = false + v.Description = c.RandString() + "x" + v.Name = c.RandString() + "x" + + switch c.Intn(4) { + case 0: + // Header param + v.In = "header" + case 1: + // Form data param + v.In = "formData" + v.AllowEmptyValue = c.RandBool() + case 2: + // Query param + v.In = "query" + v.AllowEmptyValue = c.RandBool() + case 3: + // Path param + v.In = "path" + v.Required = true + default: + panic("unreachable") + } + + // descendant Items of Parameter may not be refs + cur := v.Items + for cur != nil { + cur.Ref = Ref{} + cur = cur.Items + } + } + }, + func(v *Schema, c fuzz.Continue) { + if c.RandBool() { + // file schema + c.Fuzz(&v.Default) + c.Fuzz(&v.Description) + c.Fuzz(&v.Example) + c.Fuzz(&v.ExternalDocs) + + c.Fuzz(&v.Format) + c.Fuzz(&v.ReadOnly) + c.Fuzz(&v.Required) + c.Fuzz(&v.Title) + v.Type = StringOrArray{"file"} + + } else { + // normal schema + c.Fuzz(&v.SchemaProps) + c.Fuzz(&v.SwaggerSchemaProps) + c.Fuzz(&v.VendorExtensible) + // c.Fuzz(&v.ExtraProps) + // ExtraProps will not roundtrip - gnostic throws out + // unrecognized keys + } + + // Not supported by official openapi v2 spec + // and stripped by k8s apiserver + v.ID = "" + v.AnyOf = nil + v.OneOf = nil + v.Not = nil + v.Nullable = false + v.AdditionalItems = nil + v.Schema = "" + v.PatternProperties = nil + v.Definitions = nil + v.Dependencies = nil + }, +} + +var SwaggerDiffOptions = []cmp.Option{ + // cmp.Diff panics on Ref since jsonreference.Ref uses unexported fields + cmp.Comparer(func(a Ref, b Ref) bool { + return a.String() == b.String() + }), +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/gnostic.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/gnostic.go index 35fd579201c..406a09d9d1e 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/gnostic.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/gnostic.go @@ -219,8 +219,8 @@ func (k *Ref) FromGnostic(g string) error { // Caveats: // // - gnostic v2 documents treats zero as unspecified for numerical fields of -//CommonValidations fields such as Maximum, Minimum, MaximumItems, etc. -//There will always be data loss if one of the values of these fields is set to zero. +// CommonValidations fields such as Maximum, Minimum, MaximumItems, etc. +// There will always be data loss if one of the values of these fields is set to zero. // // Returns: // @@ -1263,6 +1263,8 @@ func (k *Schema) FromGnostic(g *openapi_v2.Schema) (ok bool, err error) { k.AdditionalProperties.Allows = g.AdditionalProperties.GetBoolean() } else { k.AdditionalProperties.Schema = &Schema{} + k.AdditionalProperties.Allows = true + if nok, err := k.AdditionalProperties.Schema.FromGnostic(g.AdditionalProperties.GetSchema()); err != nil { return false, err } else if !nok { diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go index 597fc96312c..05310c46b36 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) const ( @@ -41,6 +43,9 @@ type Header struct { // MarshalJSON marshal this to JSON func (h Header) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(h) + } b1, err := json.Marshal(h.CommonValidations) if err != nil { return nil, err @@ -60,8 +65,26 @@ func (h Header) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4), nil } +func (h Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Extensions + HeaderProps + } + x.CommonValidations = commonValidationsOmitZero(h.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(h.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(h.Extensions) + x.HeaderProps = h.HeaderProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals this header from JSON func (h *Header) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, h) + } + if err := json.Unmarshal(data, &h.CommonValidations); err != nil { return err } @@ -73,3 +96,23 @@ func (h *Header) UnmarshalJSON(data []byte) error { } return json.Unmarshal(data, &h.HeaderProps) } + +func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + CommonValidations + SimpleSchema + Extensions + HeaderProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + h.CommonValidations = x.CommonValidations + h.SimpleSchema = x.SimpleSchema + h.Extensions = internal.SanitizeExtensions(x.Extensions) + h.HeaderProps = x.HeaderProps + + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go index 51a2f5781f0..d667b705be6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go @@ -19,6 +19,8 @@ import ( "strings" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // Extensions vendor specific extensions @@ -87,6 +89,19 @@ func (e Extensions) GetObject(key string, out interface{}) error { return nil } +func (e Extensions) sanitizeWithExtra() (extra map[string]any) { + for k, v := range e { + if !internal.IsExtensionKey(k) { + if extra == nil { + extra = make(map[string]any) + } + extra[k] = v + delete(e, k) + } + } + return extra +} + // VendorExtensible composition block. type VendorExtensible struct { Extensions Extensions @@ -154,6 +169,9 @@ type Info struct { // MarshalJSON marshal this to JSON func (i Info) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.InfoProps) if err != nil { return nil, err @@ -165,10 +183,37 @@ func (i Info) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (i Info) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + InfoProps + } + x.Extensions = i.Extensions + x.InfoProps = i.InfoProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (i *Info) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, i) + } + if err := json.Unmarshal(data, &i.InfoProps); err != nil { return err } return json.Unmarshal(data, &i.VendorExtensible) } + +func (i *Info) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + Extensions + InfoProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + i.Extensions = internal.SanitizeExtensions(x.Extensions) + i.InfoProps = x.InfoProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go index b75aefe164a..4132467d243 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) const ( @@ -35,6 +37,18 @@ type SimpleSchema struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type simpleSchemaOmitZero struct { + Type string `json:"type,omitempty"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Items *Items `json:"items,omitzero"` + CollectionFormat string `json:"collectionFormat,omitempty"` + Default interface{} `json:"default,omitempty"` + Example interface{} `json:"example,omitempty"` +} + // CommonValidations describe common JSON-schema validations type CommonValidations struct { Maximum *float64 `json:"maximum,omitempty"` @@ -51,6 +65,23 @@ type CommonValidations struct { Enum []interface{} `json:"enum,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type commonValidationsOmitZero struct { + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` +} + // Items a limited subset of JSON-Schema's items object. // It is used by parameter definitions that are not located in "body". // @@ -64,6 +95,10 @@ type Items struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (i *Items) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, i) + } + var validations CommonValidations if err := json.Unmarshal(data, &validations); err != nil { return err @@ -87,8 +122,30 @@ func (i *Items) UnmarshalJSON(data []byte) error { return nil } +func (i *Items) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + CommonValidations + SimpleSchema + Extensions + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := i.Refable.Ref.fromMap(x.Extensions); err != nil { + return err + } + + i.CommonValidations = x.CommonValidations + i.SimpleSchema = x.SimpleSchema + i.Extensions = internal.SanitizeExtensions(x.Extensions) + return nil +} + // MarshalJSON converts this items object to JSON func (i Items) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.CommonValidations) if err != nil { return nil, err @@ -107,3 +164,17 @@ func (i Items) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b4, b3, b1, b2), nil } + +func (i Items) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(i.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(i.SimpleSchema) + x.Ref = i.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(i.Extensions) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go index c7acd8672ce..63eed34601a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // OperationProps describes an operation @@ -40,6 +42,23 @@ type OperationProps struct { Responses *Responses `json:"responses,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type operationPropsOmitZero struct { + Description string `json:"description,omitempty"` + Consumes []string `json:"consumes,omitempty"` + Produces []string `json:"produces,omitempty"` + Schemes []string `json:"schemes,omitempty"` + Tags []string `json:"tags,omitempty"` + Summary string `json:"summary,omitempty"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + ID string `json:"operationId,omitempty"` + Deprecated bool `json:"deprecated,omitempty,omitzero"` + Security []map[string][]string `json:"security,omitempty"` + Parameters []Parameter `json:"parameters,omitempty"` + Responses *Responses `json:"responses,omitzero"` +} + // MarshalJSON takes care of serializing operation properties to JSON // // We use a custom marhaller here to handle a special cases related to @@ -75,14 +94,35 @@ type Operation struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (o *Operation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, o) + } + if err := json.Unmarshal(data, &o.OperationProps); err != nil { return err } return json.Unmarshal(data, &o.VendorExtensible) } +func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + type OperationPropsNoMethods OperationProps // strip MarshalJSON method + var x struct { + Extensions + OperationPropsNoMethods + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + o.Extensions = internal.SanitizeExtensions(x.Extensions) + o.OperationProps = OperationProps(x.OperationPropsNoMethods) + return nil +} + // MarshalJSON converts this items object to JSON func (o Operation) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(o) + } b1, err := json.Marshal(o.OperationProps) if err != nil { return nil, err @@ -94,3 +134,13 @@ func (o Operation) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (o Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + OperationProps operationPropsOmitZero `json:",inline"` + } + x.Extensions = internal.SanitizeExtensions(o.Extensions) + x.OperationProps = operationPropsOmitZero(o.OperationProps) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go index 21851397400..53d1e0aa944 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // ParamProps describes the specific attributes of an operation parameter @@ -34,30 +36,46 @@ type ParamProps struct { AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type paramPropsOmitZero struct { + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + In string `json:"in,omitempty"` + Required bool `json:"required,omitzero"` + Schema *Schema `json:"schema,omitzero"` + AllowEmptyValue bool `json:"allowEmptyValue,omitzero"` +} + // Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). // // There are five possible parameter types. // * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part -// of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, -// the path parameter is `itemId`. +// +// of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, +// the path parameter is `itemId`. +// // * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`. // * Header - Custom headers that are expected as part of the request. // * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be -// _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for -// documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist -// together for the same operation. +// +// _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for +// documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist +// together for the same operation. +// // * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or -// `multipart/form-data` are used as the content type of the request (in Swagger's definition, -// the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used -// to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be -// declared together with a body parameter for the same operation. Form parameters have a different format based on -// the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4). -// * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. -// For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple -// parameters that are being transferred. -// * `multipart/form-data` - each parameter takes a section in the payload with an internal header. -// For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is -// `submit-name`. This type of form parameters is more commonly used for file transfers. +// +// `multipart/form-data` are used as the content type of the request (in Swagger's definition, +// the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used +// to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be +// declared together with a body parameter for the same operation. Form parameters have a different format based on +// the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4). +// * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. +// For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple +// parameters that are being transferred. +// * `multipart/form-data` - each parameter takes a section in the payload with an internal header. +// For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is +// `submit-name`. This type of form parameters is more commonly used for file transfers. // // For more information: http://goo.gl/8us55a#parameterObject type Parameter struct { @@ -70,6 +88,10 @@ type Parameter struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Parameter) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, p) + } + if err := json.Unmarshal(data, &p.CommonValidations); err != nil { return err } @@ -85,8 +107,31 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &p.ParamProps) } +func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + CommonValidations + SimpleSchema + Extensions + ParamProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { + return err + } + p.CommonValidations = x.CommonValidations + p.SimpleSchema = x.SimpleSchema + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.ParamProps = x.ParamProps + return nil +} + // MarshalJSON converts this items object to JSON func (p Parameter) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.CommonValidations) if err != nil { return nil, err @@ -109,3 +154,19 @@ func (p Parameter) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b3, b1, b2, b4, b5), nil } + +func (p Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + ParamProps paramPropsOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(p.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(p.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.ParamProps = paramPropsOmitZero(p.ParamProps) + x.Ref = p.Refable.Ref.String() + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go index 04de58f00f0..1d1588cb92c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // PathItemProps the path item specific properties @@ -46,6 +48,10 @@ type PathItem struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *PathItem) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, p) + } + if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -55,8 +61,29 @@ func (p *PathItem) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &p.PathItemProps) } +func (p *PathItem) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + Extensions + PathItemProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathItemProps = x.PathItemProps + + return nil +} + // MarshalJSON converts this items object to JSON func (p PathItem) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b3, err := json.Marshal(p.Refable) if err != nil { return nil, err @@ -72,3 +99,15 @@ func (p PathItem) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b3, b4, b5) return concated, nil } + +func (p PathItem) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + PathItemProps + } + x.Ref = p.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.PathItemProps = p.PathItemProps + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go index 319aba879ab..18f6a9f4297 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go @@ -16,9 +16,12 @@ package spec import ( "encoding/json" + "fmt" "strings" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // Paths holds the relative paths to the individual endpoints. @@ -34,6 +37,10 @@ type Paths struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Paths) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, p) + } + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { return err @@ -63,8 +70,65 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } +func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + tok, err := dec.ReadToken() + if err != nil { + return err + } + var ext any + var pi PathItem + switch k := tok.Kind(); k { + case 'n': + return nil // noop + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + + if tok.Kind() == '}' { + return nil + } + + switch k := tok.String(); { + case internal.IsExtensionKey(k): + ext = nil + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if p.Extensions == nil { + p.Extensions = make(map[string]any) + } + p.Extensions[k] = ext + case len(k) > 0 && k[0] == '/': + pi = PathItem{} + if err := opts.UnmarshalNext(dec, &pi); err != nil { + return err + } + + if p.Paths == nil { + p.Paths = make(map[string]PathItem) + } + p.Paths[k] = pi + default: + _, err := dec.ReadValue() // skip value + if err != nil { + return err + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // MarshalJSON converts this items object to JSON func (p Paths) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.VendorExtensible) if err != nil { return nil, err @@ -83,3 +147,18 @@ func (p Paths) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + m := make(map[string]any, len(p.Extensions)+len(p.Paths)) + for k, v := range p.Extensions { + if internal.IsExtensionKey(k) { + m[k] = v + } + } + for k, v := range p.Paths { + if strings.HasPrefix(k, "/") { + m[k] = v + } + } + return opts.MarshalNext(enc, m) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go index 1405bfd8ee2..775b3b0c367 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go @@ -21,6 +21,8 @@ import ( "path/filepath" "github.com/go-openapi/jsonreference" + + "k8s.io/kube-openapi/pkg/internal" ) // Refable is a struct for things that accept a $ref property @@ -149,19 +151,5 @@ func (r *Ref) UnmarshalJSON(d []byte) error { } func (r *Ref) fromMap(v map[string]interface{}) error { - if v == nil { - return nil - } - - if vv, ok := v["$ref"]; ok { - if str, ok := vv.(string); ok { - ref, err := jsonreference.New(str) - if err != nil { - return err - } - *r = Ref{Ref: ref} - } - } - - return nil + return internal.JSONRefFromMap(&r.Ref, v) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go index 9fd717ec3fd..3ff1fe13227 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // ResponseProps properties specific to a response @@ -28,6 +30,15 @@ type ResponseProps struct { Examples map[string]interface{} `json:"examples,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type responsePropsOmitZero struct { + Description string `json:"description,omitempty"` + Schema *Schema `json:"schema,omitzero"` + Headers map[string]Header `json:"headers,omitempty"` + Examples map[string]interface{} `json:"examples,omitempty"` +} + // Response describes a single response from an API Operation. // // For more information: http://goo.gl/8us55a#responseObject @@ -39,17 +50,47 @@ type Response struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (r *Response) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, r) + } + if err := json.Unmarshal(data, &r.ResponseProps); err != nil { return err } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } - return json.Unmarshal(data, &r.VendorExtensible) + if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { + return err + } + + return nil +} + +func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + ResponseProps + Extensions + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + if err := r.Refable.Ref.fromMap(x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps + + return nil } // MarshalJSON converts this items object to JSON func (r Response) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponseProps) if err != nil { return nil, err @@ -65,6 +106,18 @@ func (r Response) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } +func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + ResponseProps responsePropsOmitZero `json:",inline"` + } + x.Ref = r.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(r.Extensions) + x.ResponseProps = responsePropsOmitZero(r.ResponseProps) + return opts.MarshalNext(enc, x) +} + // NewResponse creates a new response instance func NewResponse() *Response { return new(Response) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go index b2c3883a9f6..d9ad760a43f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go @@ -16,10 +16,13 @@ package spec import ( "encoding/json" + "fmt" "reflect" "strconv" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // Responses is a container for the expected responses of an operation. @@ -42,6 +45,10 @@ type Responses struct { // UnmarshalJSON hydrates this items instance with the data from JSON func (r *Responses) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, r) + } + if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { return err } @@ -56,6 +63,9 @@ func (r *Responses) UnmarshalJSON(data []byte) error { // MarshalJSON converts this items object to JSON func (r Responses) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponsesProps) if err != nil { return nil, err @@ -68,6 +78,25 @@ func (r Responses) MarshalJSON() ([]byte, error) { return concated, nil } +func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + Default *Response `json:"default,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses)) + for k, v := range r.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range r.StatusCodeResponses { + x.ArbitraryKeys[strconv.Itoa(k)] = v + } + x.Default = r.Default + return opts.MarshalNext(enc, x) +} + // ResponsesProps describes all responses for an operation. // It tells what is the default response and maps all responses with a // HTTP status code. @@ -90,21 +119,90 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals responses from JSON func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]Response + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, r) + } + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { - return nil + return err } if v, ok := res["default"]; ok { - r.Default = &v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.Default = &value delete(res, "default") } for k, v := range res { + // Take all integral keys if nk, err := strconv.Atoi(k); err == nil { if r.StatusCodeResponses == nil { r.StatusCodeResponses = map[int]Response{} } - r.StatusCodeResponses[nk] = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.StatusCodeResponses[nk] = value } } return nil } + +func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { + tok, err := dec.ReadToken() + if err != nil { + return err + } + var ext any + var resp Response + switch k := tok.Kind(); k { + case 'n': + return nil // noop + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + if tok.Kind() == '}' { + return nil + } + switch k := tok.String(); { + case internal.IsExtensionKey(k): + ext = nil + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if r.Extensions == nil { + r.Extensions = make(map[string]any) + } + r.Extensions[k] = ext + case k == "default": + resp = Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + + respCopy := resp + r.ResponsesProps.Default = &respCopy + default: + if nk, err := strconv.Atoi(k); err == nil { + resp = Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + + if r.StatusCodeResponses == nil { + r.StatusCodeResponses = map[int]Response{} + } + r.StatusCodeResponses[nk] = resp + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go index b0aeeb0d0e1..dfbb2e05cba 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go @@ -21,6 +21,8 @@ import ( "strings" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // BooleanProperty creates a boolean property @@ -194,6 +196,46 @@ type SchemaProps struct { Definitions Definitions `json:"definitions,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type schemaPropsOmitZero struct { + ID string `json:"id,omitempty"` + Ref Ref `json:"-"` + Schema SchemaURL `json:"-"` + Description string `json:"description,omitempty"` + Type StringOrArray `json:"type,omitzero"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Title string `json:"title,omitempty"` + Default interface{} `json:"default,omitzero"` + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` + MaxProperties *int64 `json:"maxProperties,omitempty"` + MinProperties *int64 `json:"minProperties,omitempty"` + Required []string `json:"required,omitempty"` + Items *SchemaOrArray `json:"items,omitzero"` + AllOf []Schema `json:"allOf,omitempty"` + OneOf []Schema `json:"oneOf,omitempty"` + AnyOf []Schema `json:"anyOf,omitempty"` + Not *Schema `json:"not,omitzero"` + Properties map[string]Schema `json:"properties,omitempty"` + AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitzero"` + PatternProperties map[string]Schema `json:"patternProperties,omitempty"` + Dependencies Dependencies `json:"dependencies,omitempty"` + AdditionalItems *SchemaOrBool `json:"additionalItems,omitzero"` + Definitions Definitions `json:"definitions,omitempty"` +} + // SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4) type SwaggerSchemaProps struct { Discriminator string `json:"discriminator,omitempty"` @@ -202,6 +244,15 @@ type SwaggerSchemaProps struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type swaggerSchemaPropsOmitZero struct { + Discriminator string `json:"discriminator,omitempty"` + ReadOnly bool `json:"readOnly,omitzero"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + Example interface{} `json:"example,omitempty"` +} + // Schema the schema object allows the definition of input and output data types. // These types can be objects, but also primitives and arrays. // This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/) @@ -432,6 +483,9 @@ func (s *Schema) WithExternalDocs(description, url string) *Schema { // MarshalJSON marshal this to JSON func (s Schema) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SchemaProps) if err != nil { return nil, fmt.Errorf("schema props %v", err) @@ -463,8 +517,37 @@ func (s Schema) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil } +func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + SchemaProps schemaPropsOmitZero `json:",inline"` + SwaggerSchemaProps swaggerSchemaPropsOmitZero `json:",inline"` + Schema string `json:"$schema,omitempty"` + Ref string `json:"$ref,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(s.Extensions)+len(s.ExtraProps)) + for k, v := range s.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range s.ExtraProps { + x.ArbitraryKeys[k] = v + } + x.SchemaProps = schemaPropsOmitZero(s.SchemaProps) + x.SwaggerSchemaProps = swaggerSchemaPropsOmitZero(s.SwaggerSchemaProps) + x.Ref = s.Ref.String() + x.Schema = string(s.Schema) + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *Schema) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } + props := struct { SchemaProps SwaggerSchemaProps @@ -511,3 +594,38 @@ func (s *Schema) UnmarshalJSON(data []byte) error { return nil } + +func (s *Schema) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + Extensions + SchemaProps + SwaggerSchemaProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + if err := x.Ref.fromMap(x.Extensions); err != nil { + return err + } + + if err := x.Schema.fromMap(x.Extensions); err != nil { + return err + } + + delete(x.Extensions, "$ref") + delete(x.Extensions, "$schema") + + for _, pn := range swag.DefaultJSONNameProvider.GetJSONNames(s) { + delete(x.Extensions, pn) + } + if len(x.Extensions) == 0 { + x.Extensions = nil + } + + s.ExtraProps = x.Extensions.sanitizeWithExtra() + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.SchemaProps = x.SchemaProps + s.SwaggerSchemaProps = x.SwaggerSchemaProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go index 563b9b95e41..e2b7da14cf8 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // SecuritySchemeProps describes a swagger security scheme in the securityDefinitions section @@ -44,6 +46,9 @@ type SecurityScheme struct { // MarshalJSON marshal this to JSON func (s SecurityScheme) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SecuritySchemeProps) if err != nil { return nil, err @@ -55,6 +60,16 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (s SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SecuritySchemeProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SecuritySchemeProps = s.SecuritySchemeProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *SecurityScheme) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil { @@ -62,3 +77,16 @@ func (s *SecurityScheme) UnmarshalJSON(data []byte) error { } return json.Unmarshal(data, &s.VendorExtensible) } + +func (s *SecurityScheme) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + Extensions + SecuritySchemeProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.SecuritySchemeProps = x.SecuritySchemeProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go index be66d1ddd68..c8f3beaa352 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go @@ -19,6 +19,8 @@ import ( "fmt" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // Swagger this is the root document object for the API specification. @@ -33,6 +35,9 @@ type Swagger struct { // MarshalJSON marshals this swagger structure to json func (s Swagger) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SwaggerProps) if err != nil { return nil, err @@ -44,8 +49,22 @@ func (s Swagger) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +// MarshalJSON marshals this swagger structure to json +func (s Swagger) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SwaggerProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SwaggerProps = s.SwaggerProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals a swagger spec from json func (s *Swagger) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } var sw Swagger if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil { return err @@ -57,6 +76,23 @@ func (s *Swagger) UnmarshalJSON(data []byte) error { return nil } +func (s *Swagger) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + // Note: If you're willing to make breaking changes, it is possible to + // optimize this and other usages of this pattern: + // https://github.com/kubernetes/kube-openapi/pull/319#discussion_r983165948 + var x struct { + Extensions + SwaggerProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.SwaggerProps = x.SwaggerProps + return nil +} + // SwaggerProps captures the top-level properties of an Api specification // // NOTE: validation rules @@ -96,6 +132,9 @@ var jsFalse = []byte("false") // MarshalJSON convert this object to JSON func (s SchemaOrBool) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if s.Schema != nil { return json.Marshal(s.Schema) } @@ -106,23 +145,59 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) { return jsTrue, nil } +// MarshalJSON convert this object to JSON +func (s SchemaOrBool) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + + if s.Schema == nil && !s.Allows { + return enc.WriteToken(jsonv2.False) + } + return enc.WriteToken(jsonv2.True) +} + // UnmarshalJSON converts this bool or schema object from a JSON structure func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } + var nw SchemaOrBool - if len(data) >= 4 { - if data[0] == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch + if len(data) > 0 && data[0] == '{' { + var sch Schema + if err := json.Unmarshal(data, &sch); err != nil { + return err } - nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e') + nw.Schema = &sch + nw.Allows = true + } else { + json.Unmarshal(data, &nw.Allows) } *s = nw return nil } +func (s *SchemaOrBool) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + switch k := dec.PeekKind(); k { + case '{': + err := opts.UnmarshalNext(dec, &s.Schema) + if err != nil { + return err + } + s.Allows = true + return nil + case 't', 'f': + err := opts.UnmarshalNext(dec, &s.Allows) + if err != nil { + return err + } + return nil + default: + return fmt.Errorf("expected object or bool, not '%v'", k.String()) + } +} + // SchemaOrStringArray represents a schema or a string array type SchemaOrStringArray struct { Schema *Schema @@ -131,6 +206,9 @@ type SchemaOrStringArray struct { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if len(s.Property) > 0 { return json.Marshal(s.Property) } @@ -140,8 +218,23 @@ func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { return []byte("null"), nil } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrStringArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if len(s.Property) > 0 { + return opts.MarshalNext(enc, s.Property) + } + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + return enc.WriteToken(jsonv2.Null) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } + var first byte if len(data) > 1 { first = data[0] @@ -163,6 +256,18 @@ func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { return nil } +func (s *SchemaOrStringArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + switch dec.PeekKind() { + case '{': + return opts.UnmarshalNext(dec, &s.Schema) + case '[': + return opts.UnmarshalNext(dec, &s.Property) + default: + _, err := dec.ReadValue() + return err + } +} + // Definitions contains the models explicitly defined in this spec // An object to hold data types that can be consumed and produced by operations. // These data types can be primitives, arrays or models. @@ -193,6 +298,10 @@ func (s StringOrArray) Contains(value string) bool { // UnmarshalJSON unmarshals this string or array object from a JSON array or JSON string func (s *StringOrArray) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } + var first byte if len(data) > 1 { first = data[0] @@ -223,6 +332,23 @@ func (s *StringOrArray) UnmarshalJSON(data []byte) error { } } +func (s *StringOrArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + switch k := dec.PeekKind(); k { + case '[': + *s = StringOrArray{} + return opts.UnmarshalNext(dec, (*[]string)(s)) + case '"': + *s = StringOrArray{""} + return opts.UnmarshalNext(dec, &(*s)[0]) + case 'n': + // Throw out null token + _, _ = dec.ReadToken() + return nil + default: + return fmt.Errorf("expected string or array, not '%v'", k.String()) + } +} + // MarshalJSON converts this string or array to a JSON array or JSON string func (s StringOrArray) MarshalJSON() ([]byte, error) { if len(s) == 1 { @@ -256,14 +382,29 @@ func (s *SchemaOrArray) ContainsType(name string) bool { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrArray) MarshalJSON() ([]byte, error) { - if len(s.Schemas) > 0 { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } + if s.Schemas != nil { return json.Marshal(s.Schemas) } return json.Marshal(s.Schema) } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schemas != nil { + return opts.MarshalNext(enc, s.Schemas) + } + return opts.MarshalNext(enc, s.Schema) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, s) + } + var nw SchemaOrArray var first byte if len(data) > 1 { @@ -284,3 +425,15 @@ func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { *s = nw return nil } + +func (s *SchemaOrArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + switch dec.PeekKind() { + case '{': + return opts.UnmarshalNext(dec, &s.Schema) + case '[': + return opts.UnmarshalNext(dec, &s.Schemas) + default: + _, err := dec.ReadValue() + return err + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go index ddd1eac7efa..d105d52ca47 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go @@ -18,6 +18,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) // TagProps describe a tag entry in the top level tags section of a swagger spec @@ -39,6 +41,9 @@ type Tag struct { // MarshalJSON marshal this to JSON func (t Tag) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(t) + } b1, err := json.Marshal(t.TagProps) if err != nil { return nil, err @@ -50,10 +55,37 @@ func (t Tag) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (t Tag) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + TagProps + } + x.Extensions = internal.SanitizeExtensions(t.Extensions) + x.TagProps = t.TagProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (t *Tag) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshaling { + return jsonv2.Unmarshal(data, t) + } + if err := json.Unmarshal(data, &t.TagProps); err != nil { return err } return json.Unmarshal(data, &t.VendorExtensible) } + +func (t *Tag) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + Extensions + TagProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + t.Extensions = internal.SanitizeExtensions(x.Extensions) + t.TagProps = x.TagProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/validate/values.go b/vendor/k8s.io/kube-openapi/pkg/validation/validate/values.go index 7d7f9b8f1c6..2a1291667fd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/validate/values.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/validate/values.go @@ -184,7 +184,7 @@ func MinimumUint(path, in string, data, min uint64, exclusive bool) *errors.Vali // MultipleOf validates if the provided number is a multiple of the factor func MultipleOf(path, in string, data, factor float64) *errors.Validation { // multipleOf factor must be positive - if factor < 0 { + if factor <= 0 { return errors.MultipleOfMustBePositive(path, in, factor) } var mult float64 @@ -202,7 +202,7 @@ func MultipleOf(path, in string, data, factor float64) *errors.Validation { // MultipleOfInt validates if the provided integer is a multiple of the factor func MultipleOfInt(path, in string, data int64, factor int64) *errors.Validation { // multipleOf factor must be positive - if factor < 0 { + if factor <= 0 { return errors.MultipleOfMustBePositive(path, in, factor) } mult := data / factor @@ -214,6 +214,10 @@ func MultipleOfInt(path, in string, data int64, factor int64) *errors.Validation // MultipleOfUint validates if the provided unsigned integer is a multiple of the factor func MultipleOfUint(path, in string, data, factor uint64) *errors.Validation { + // multipleOf factor must be positive + if factor == 0 { + return errors.MultipleOfMustBePositive(path, in, factor) + } mult := data / factor if mult*factor != data { return errors.NotMultipleOf(path, in, factor, data) diff --git a/vendor/k8s.io/utils/lru/lru.go b/vendor/k8s.io/utils/lru/lru.go index 5d0077abfbb..47f13528134 100644 --- a/vendor/k8s.io/utils/lru/lru.go +++ b/vendor/k8s.io/utils/lru/lru.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,6 +22,7 @@ import ( ) type Key = groupcache.Key +type EvictionFunc = func(key Key, value interface{}) // Cache is a thread-safe fixed size LRU cache. type Cache struct { @@ -36,6 +37,13 @@ func New(size int) *Cache { } } +// NewWithEvictionFunc creates an LRU of the given size with the given eviction func. +func NewWithEvictionFunc(size int, f EvictionFunc) *Cache { + c := New(size) + c.cache.OnEvicted = f + return c +} + // Add adds a value to the cache. func (c *Cache) Add(key Key, value interface{}) { c.lock.Lock() diff --git a/vendor/k8s.io/utils/net/ipfamily.go b/vendor/k8s.io/utils/net/ipfamily.go new file mode 100644 index 00000000000..1a51fa39189 --- /dev/null +++ b/vendor/k8s.io/utils/net/ipfamily.go @@ -0,0 +1,181 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package net + +import ( + "fmt" + "net" +) + +// IPFamily refers to a specific family if not empty, i.e. "4" or "6". +type IPFamily string + +// Constants for valid IPFamilys: +const ( + IPFamilyUnknown IPFamily = "" + + IPv4 IPFamily = "4" + IPv6 IPFamily = "6" +) + +// IsDualStackIPs returns true if: +// - all elements of ips are valid +// - at least one IP from each family (v4 and v6) is present +func IsDualStackIPs(ips []net.IP) (bool, error) { + v4Found := false + v6Found := false + for i, ip := range ips { + switch IPFamilyOf(ip) { + case IPv4: + v4Found = true + case IPv6: + v6Found = true + default: + return false, fmt.Errorf("invalid IP[%d]: %v", i, ip) + } + } + + return (v4Found && v6Found), nil +} + +// IsDualStackIPStrings returns true if: +// - all elements of ips can be parsed as IPs +// - at least one IP from each family (v4 and v6) is present +func IsDualStackIPStrings(ips []string) (bool, error) { + parsedIPs := make([]net.IP, 0, len(ips)) + for i, ip := range ips { + parsedIP := ParseIPSloppy(ip) + if parsedIP == nil { + return false, fmt.Errorf("invalid IP[%d]: %v", i, ip) + } + parsedIPs = append(parsedIPs, parsedIP) + } + return IsDualStackIPs(parsedIPs) +} + +// IsDualStackCIDRs returns true if: +// - all elements of cidrs are non-nil +// - at least one CIDR from each family (v4 and v6) is present +func IsDualStackCIDRs(cidrs []*net.IPNet) (bool, error) { + v4Found := false + v6Found := false + for i, cidr := range cidrs { + switch IPFamilyOfCIDR(cidr) { + case IPv4: + v4Found = true + case IPv6: + v6Found = true + default: + return false, fmt.Errorf("invalid CIDR[%d]: %v", i, cidr) + } + } + + return (v4Found && v6Found), nil +} + +// IsDualStackCIDRStrings returns if +// - all elements of cidrs can be parsed as CIDRs +// - at least one CIDR from each family (v4 and v6) is present +func IsDualStackCIDRStrings(cidrs []string) (bool, error) { + parsedCIDRs, err := ParseCIDRs(cidrs) + if err != nil { + return false, err + } + return IsDualStackCIDRs(parsedCIDRs) +} + +// IPFamilyOf returns the IP family of ip, or IPFamilyUnknown if it is invalid. +func IPFamilyOf(ip net.IP) IPFamily { + switch { + case ip.To4() != nil: + return IPv4 + case ip.To16() != nil: + return IPv6 + default: + return IPFamilyUnknown + } +} + +// IPFamilyOfString returns the IP family of ip, or IPFamilyUnknown if ip cannot +// be parsed as an IP. +func IPFamilyOfString(ip string) IPFamily { + return IPFamilyOf(ParseIPSloppy(ip)) +} + +// IPFamilyOfCIDR returns the IP family of cidr. +func IPFamilyOfCIDR(cidr *net.IPNet) IPFamily { + if cidr == nil { + return IPFamilyUnknown + } + return IPFamilyOf(cidr.IP) +} + +// IPFamilyOfCIDRString returns the IP family of cidr. +func IPFamilyOfCIDRString(cidr string) IPFamily { + ip, _, _ := ParseCIDRSloppy(cidr) + return IPFamilyOf(ip) +} + +// IsIPv6 returns true if netIP is IPv6 (and false if it is IPv4, nil, or invalid). +func IsIPv6(netIP net.IP) bool { + return IPFamilyOf(netIP) == IPv6 +} + +// IsIPv6String returns true if ip contains a single IPv6 address and nothing else. It +// returns false if ip is an empty string, an IPv4 address, or anything else that is not a +// single IPv6 address. +func IsIPv6String(ip string) bool { + return IPFamilyOfString(ip) == IPv6 +} + +// IsIPv6CIDR returns true if a cidr is a valid IPv6 CIDR. It returns false if cidr is +// nil or an IPv4 CIDR. Its behavior is not defined if cidr is invalid. +func IsIPv6CIDR(cidr *net.IPNet) bool { + return IPFamilyOfCIDR(cidr) == IPv6 +} + +// IsIPv6CIDRString returns true if cidr contains a single IPv6 CIDR and nothing else. It +// returns false if cidr is an empty string, an IPv4 CIDR, or anything else that is not a +// single valid IPv6 CIDR. +func IsIPv6CIDRString(cidr string) bool { + return IPFamilyOfCIDRString(cidr) == IPv6 +} + +// IsIPv4 returns true if netIP is IPv4 (and false if it is IPv6, nil, or invalid). +func IsIPv4(netIP net.IP) bool { + return IPFamilyOf(netIP) == IPv4 +} + +// IsIPv4String returns true if ip contains a single IPv4 address and nothing else. It +// returns false if ip is an empty string, an IPv6 address, or anything else that is not a +// single IPv4 address. +func IsIPv4String(ip string) bool { + return IPFamilyOfString(ip) == IPv4 +} + +// IsIPv4CIDR returns true if cidr is a valid IPv4 CIDR. It returns false if cidr is nil +// or an IPv6 CIDR. Its behavior is not defined if cidr is invalid. +func IsIPv4CIDR(cidr *net.IPNet) bool { + return IPFamilyOfCIDR(cidr) == IPv4 +} + +// IsIPv4CIDRString returns true if cidr contains a single IPv4 CIDR and nothing else. It +// returns false if cidr is an empty string, an IPv6 CIDR, or anything else that is not a +// single valid IPv4 CIDR. +func IsIPv4CIDRString(cidr string) bool { + return IPFamilyOfCIDRString(cidr) == IPv4 +} diff --git a/vendor/k8s.io/utils/net/net.go b/vendor/k8s.io/utils/net/net.go index b7c08e2e003..704c1f232ae 100644 --- a/vendor/k8s.io/utils/net/net.go +++ b/vendor/k8s.io/utils/net/net.go @@ -29,138 +29,16 @@ import ( // order is maintained func ParseCIDRs(cidrsString []string) ([]*net.IPNet, error) { cidrs := make([]*net.IPNet, 0, len(cidrsString)) - for _, cidrString := range cidrsString { + for i, cidrString := range cidrsString { _, cidr, err := ParseCIDRSloppy(cidrString) if err != nil { - return nil, fmt.Errorf("failed to parse cidr value:%q with error:%v", cidrString, err) + return nil, fmt.Errorf("invalid CIDR[%d]: %v (%v)", i, cidr, err) } cidrs = append(cidrs, cidr) } return cidrs, nil } -// IsDualStackIPs returns if a slice of ips is: -// - all are valid ips -// - at least one ip from each family (v4 or v6) -func IsDualStackIPs(ips []net.IP) (bool, error) { - v4Found := false - v6Found := false - for _, ip := range ips { - if ip == nil { - return false, fmt.Errorf("ip %v is invalid", ip) - } - - if v4Found && v6Found { - continue - } - - if IsIPv6(ip) { - v6Found = true - continue - } - - v4Found = true - } - - return (v4Found && v6Found), nil -} - -// IsDualStackIPStrings returns if -// - all are valid ips -// - at least one ip from each family (v4 or v6) -func IsDualStackIPStrings(ips []string) (bool, error) { - parsedIPs := make([]net.IP, 0, len(ips)) - for _, ip := range ips { - parsedIP := ParseIPSloppy(ip) - parsedIPs = append(parsedIPs, parsedIP) - } - return IsDualStackIPs(parsedIPs) -} - -// IsDualStackCIDRs returns if -// - all are valid cidrs -// - at least one cidr from each family (v4 or v6) -func IsDualStackCIDRs(cidrs []*net.IPNet) (bool, error) { - v4Found := false - v6Found := false - for _, cidr := range cidrs { - if cidr == nil { - return false, fmt.Errorf("cidr %v is invalid", cidr) - } - - if v4Found && v6Found { - continue - } - - if IsIPv6(cidr.IP) { - v6Found = true - continue - } - v4Found = true - } - - return v4Found && v6Found, nil -} - -// IsDualStackCIDRStrings returns if -// - all are valid cidrs -// - at least one cidr from each family (v4 or v6) -func IsDualStackCIDRStrings(cidrs []string) (bool, error) { - parsedCIDRs, err := ParseCIDRs(cidrs) - if err != nil { - return false, err - } - return IsDualStackCIDRs(parsedCIDRs) -} - -// IsIPv6 returns if netIP is IPv6. -func IsIPv6(netIP net.IP) bool { - return netIP != nil && netIP.To4() == nil -} - -// IsIPv6String returns if ip is IPv6. -func IsIPv6String(ip string) bool { - netIP := ParseIPSloppy(ip) - return IsIPv6(netIP) -} - -// IsIPv6CIDRString returns if cidr is IPv6. -// This assumes cidr is a valid CIDR. -func IsIPv6CIDRString(cidr string) bool { - ip, _, _ := ParseCIDRSloppy(cidr) - return IsIPv6(ip) -} - -// IsIPv6CIDR returns if a cidr is ipv6 -func IsIPv6CIDR(cidr *net.IPNet) bool { - ip := cidr.IP - return IsIPv6(ip) -} - -// IsIPv4 returns if netIP is IPv4. -func IsIPv4(netIP net.IP) bool { - return netIP != nil && netIP.To4() != nil -} - -// IsIPv4String returns if ip is IPv4. -func IsIPv4String(ip string) bool { - netIP := ParseIPSloppy(ip) - return IsIPv4(netIP) -} - -// IsIPv4CIDR returns if a cidr is ipv4 -func IsIPv4CIDR(cidr *net.IPNet) bool { - ip := cidr.IP - return IsIPv4(ip) -} - -// IsIPv4CIDRString returns if cidr is IPv4. -// This assumes cidr is a valid CIDR. -func IsIPv4CIDRString(cidr string) bool { - ip, _, _ := ParseCIDRSloppy(cidr) - return IsIPv4(ip) -} - // ParsePort parses a string representing an IP port. If the string is not a // valid port number, this returns an error. func ParsePort(port string, allowZero bool) (int, error) { diff --git a/vendor/k8s.io/utils/net/port.go b/vendor/k8s.io/utils/net/port.go index 7ac04f0dc98..c6a53fa02b1 100644 --- a/vendor/k8s.io/utils/net/port.go +++ b/vendor/k8s.io/utils/net/port.go @@ -23,15 +23,6 @@ import ( "strings" ) -// IPFamily refers to a specific family if not empty, i.e. "4" or "6". -type IPFamily string - -// Constants for valid IPFamilys: -const ( - IPv4 IPFamily = "4" - IPv6 = "6" -) - // Protocol is a network protocol support by LocalPort. type Protocol string @@ -67,7 +58,7 @@ func NewLocalPort(desc, ip string, ipFamily IPFamily, port int, protocol Protoco if protocol != TCP && protocol != UDP { return nil, fmt.Errorf("Unsupported protocol %s", protocol) } - if ipFamily != "" && ipFamily != "4" && ipFamily != "6" { + if ipFamily != IPFamilyUnknown && ipFamily != IPv4 && ipFamily != IPv6 { return nil, fmt.Errorf("Invalid IP family %s", ipFamily) } if ip != "" { @@ -75,9 +66,10 @@ func NewLocalPort(desc, ip string, ipFamily IPFamily, port int, protocol Protoco if parsedIP == nil { return nil, fmt.Errorf("invalid ip address %s", ip) } - asIPv4 := parsedIP.To4() - if asIPv4 == nil && ipFamily == IPv4 || asIPv4 != nil && ipFamily == IPv6 { - return nil, fmt.Errorf("ip address and family mismatch %s, %s", ip, ipFamily) + if ipFamily != IPFamilyUnknown { + if IPFamily(parsedIP) != ipFamily { + return nil, fmt.Errorf("ip address and family mismatch %s, %s", ip, ipFamily) + } } } return &LocalPort{Description: desc, IP: ip, IPFamily: ipFamily, Port: port, Protocol: protocol}, nil diff --git a/vendor/k8s.io/utils/pointer/pointer.go b/vendor/k8s.io/utils/pointer/pointer.go index f5802d2e81b..b8103223adc 100644 --- a/vendor/k8s.io/utils/pointer/pointer.go +++ b/vendor/k8s.io/utils/pointer/pointer.go @@ -52,6 +52,9 @@ func Int(i int) *int { return &i } +// IntPtr is a function variable referring to Int. +// +// Deprecated: Use Int instead. var IntPtr = Int // for back-compat // IntDeref dereferences the int ptr and returns it if not nil, or else @@ -63,6 +66,9 @@ func IntDeref(ptr *int, def int) int { return def } +// IntPtrDerefOr is a function variable referring to IntDeref. +// +// Deprecated: Use IntDeref instead. var IntPtrDerefOr = IntDeref // for back-compat // Int32 returns a pointer to an int32. @@ -70,6 +76,9 @@ func Int32(i int32) *int32 { return &i } +// Int32Ptr is a function variable referring to Int32. +// +// Deprecated: Use Int32 instead. var Int32Ptr = Int32 // for back-compat // Int32Deref dereferences the int32 ptr and returns it if not nil, or else @@ -81,6 +90,9 @@ func Int32Deref(ptr *int32, def int32) int32 { return def } +// Int32PtrDerefOr is a function variable referring to Int32Deref. +// +// Deprecated: Use Int32Deref instead. var Int32PtrDerefOr = Int32Deref // for back-compat // Int32Equal returns true if both arguments are nil or both arguments @@ -95,11 +107,74 @@ func Int32Equal(a, b *int32) bool { return *a == *b } +// Uint returns a pointer to an uint +func Uint(i uint) *uint { + return &i +} + +// UintPtr is a function variable referring to Uint. +// +// Deprecated: Use Uint instead. +var UintPtr = Uint // for back-compat + +// UintDeref dereferences the uint ptr and returns it if not nil, or else +// returns def. +func UintDeref(ptr *uint, def uint) uint { + if ptr != nil { + return *ptr + } + return def +} + +// UintPtrDerefOr is a function variable referring to UintDeref. +// +// Deprecated: Use UintDeref instead. +var UintPtrDerefOr = UintDeref // for back-compat + +// Uint32 returns a pointer to an uint32. +func Uint32(i uint32) *uint32 { + return &i +} + +// Uint32Ptr is a function variable referring to Uint32. +// +// Deprecated: Use Uint32 instead. +var Uint32Ptr = Uint32 // for back-compat + +// Uint32Deref dereferences the uint32 ptr and returns it if not nil, or else +// returns def. +func Uint32Deref(ptr *uint32, def uint32) uint32 { + if ptr != nil { + return *ptr + } + return def +} + +// Uint32PtrDerefOr is a function variable referring to Uint32Deref. +// +// Deprecated: Use Uint32Deref instead. +var Uint32PtrDerefOr = Uint32Deref // for back-compat + +// Uint32Equal returns true if both arguments are nil or both arguments +// dereference to the same value. +func Uint32Equal(a, b *uint32) bool { + if (a == nil) != (b == nil) { + return false + } + if a == nil { + return true + } + return *a == *b +} + // Int64 returns a pointer to an int64. func Int64(i int64) *int64 { return &i } +// Int64Ptr is a function variable referring to Int64. +// +// Deprecated: Use Int64 instead. var Int64Ptr = Int64 // for back-compat // Int64Deref dereferences the int64 ptr and returns it if not nil, or else @@ -111,6 +186,9 @@ func Int64Deref(ptr *int64, def int64) int64 { return def } +// Int64PtrDerefOr is a function variable referring to Int64Deref. +// +// Deprecated: Use Int64Deref instead. var Int64PtrDerefOr = Int64Deref // for back-compat // Int64Equal returns true if both arguments are nil or both arguments @@ -125,11 +203,50 @@ func Int64Equal(a, b *int64) bool { return *a == *b } +// Uint64 returns a pointer to an uint64. +func Uint64(i uint64) *uint64 { + return &i +} + +// Uint64Ptr is a function variable referring to Uint64. +// +// Deprecated: Use Uint64 instead. +var Uint64Ptr = Uint64 // for back-compat + +// Uint64Deref dereferences the uint64 ptr and returns it if not nil, or else +// returns def. +func Uint64Deref(ptr *uint64, def uint64) uint64 { + if ptr != nil { + return *ptr + } + return def +} + +// Uint64PtrDerefOr is a function variable referring to Uint64Deref. +// +// Deprecated: Use Uint64Deref instead. +var Uint64PtrDerefOr = Uint64Deref // for back-compat + +// Uint64Equal returns true if both arguments are nil or both arguments +// dereference to the same value. +func Uint64Equal(a, b *uint64) bool { + if (a == nil) != (b == nil) { + return false + } + if a == nil { + return true + } + return *a == *b +} + // Bool returns a pointer to a bool. func Bool(b bool) *bool { return &b } +// BoolPtr is a function variable referring to Bool. +// +// Deprecated: Use Bool instead. var BoolPtr = Bool // for back-compat // BoolDeref dereferences the bool ptr and returns it if not nil, or else @@ -141,6 +258,9 @@ func BoolDeref(ptr *bool, def bool) bool { return def } +// BoolPtrDerefOr is a function variable referring to BoolDeref. +// +// Deprecated: Use BoolDeref instead. var BoolPtrDerefOr = BoolDeref // for back-compat // BoolEqual returns true if both arguments are nil or both arguments @@ -160,6 +280,9 @@ func String(s string) *string { return &s } +// StringPtr is a function variable referring to String. +// +// Deprecated: Use String instead. var StringPtr = String // for back-compat // StringDeref dereferences the string ptr and returns it if not nil, or else @@ -171,6 +294,9 @@ func StringDeref(ptr *string, def string) string { return def } +// StringPtrDerefOr is a function variable referring to StringDeref. +// +// Deprecated: Use StringDeref instead. var StringPtrDerefOr = StringDeref // for back-compat // StringEqual returns true if both arguments are nil or both arguments @@ -190,6 +316,9 @@ func Float32(i float32) *float32 { return &i } +// Float32Ptr is a function variable referring to Float32. +// +// Deprecated: Use Float32 instead. var Float32Ptr = Float32 // Float32Deref dereferences the float32 ptr and returns it if not nil, or else @@ -201,6 +330,9 @@ func Float32Deref(ptr *float32, def float32) float32 { return def } +// Float32PtrDerefOr is a function variable referring to Float32Deref. +// +// Deprecated: Use Float32Deref instead. var Float32PtrDerefOr = Float32Deref // for back-compat // Float32Equal returns true if both arguments are nil or both arguments @@ -220,6 +352,9 @@ func Float64(i float64) *float64 { return &i } +// Float64Ptr is a function variable referring to Float64. +// +// Deprecated: Use Float64 instead. var Float64Ptr = Float64 // Float64Deref dereferences the float64 ptr and returns it if not nil, or else @@ -231,6 +366,9 @@ func Float64Deref(ptr *float64, def float64) float64 { return def } +// Float64PtrDerefOr is a function variable referring to Float64Deref. +// +// Deprecated: Use Float64Deref instead. var Float64PtrDerefOr = Float64Deref // for back-compat // Float64Equal returns true if both arguments are nil or both arguments diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go index 3023d1066e3..a0b07a6d788 100644 --- a/vendor/k8s.io/utils/trace/trace.go +++ b/vendor/k8s.io/utils/trace/trace.go @@ -21,6 +21,7 @@ import ( "context" "fmt" "math/rand" + "sync" "time" "k8s.io/klog/v2" @@ -93,13 +94,16 @@ func (s traceStep) writeItem(b *bytes.Buffer, formatter string, startTime time.T // Trace keeps track of a set of "steps" and allows us to log a specific // step if it took longer than its share of the total allowed time type Trace struct { + // constant fields name string fields []Field - threshold *time.Duration startTime time.Time - endTime *time.Time - traceItems []traceItem parentTrace *Trace + // fields guarded by a lock + lock sync.RWMutex + threshold *time.Duration + endTime *time.Time + traceItems []traceItem } func (t *Trace) time() time.Time { @@ -138,6 +142,8 @@ func New(name string, fields ...Field) *Trace { // how long it took. The Fields add key value pairs to provide additional details about the trace // step. func (t *Trace) Step(msg string, fields ...Field) { + t.lock.Lock() + defer t.lock.Unlock() if t.traceItems == nil { // traces almost always have less than 6 steps, do this to avoid more than a single allocation t.traceItems = make([]traceItem, 0, 6) @@ -153,7 +159,9 @@ func (t *Trace) Nest(msg string, fields ...Field) *Trace { newTrace := New(msg, fields...) if t != nil { newTrace.parentTrace = t + t.lock.Lock() t.traceItems = append(t.traceItems, newTrace) + t.lock.Unlock() } return newTrace } @@ -163,7 +171,9 @@ func (t *Trace) Nest(msg string, fields ...Field) *Trace { // is logged. func (t *Trace) Log() { endTime := time.Now() + t.lock.Lock() t.endTime = &endTime + t.lock.Unlock() // an explicit logging request should dump all the steps out at the higher level if t.parentTrace == nil { // We don't start logging until Log or LogIfLong is called on the root trace t.logTrace() @@ -178,13 +188,17 @@ func (t *Trace) Log() { // If the Trace is nested it is not immediately logged. Instead, it is logged when the trace it // is nested within is logged. func (t *Trace) LogIfLong(threshold time.Duration) { + t.lock.Lock() t.threshold = &threshold + t.lock.Unlock() t.Log() } // logTopLevelTraces finds all traces in a hierarchy of nested traces that should be logged but do not have any // parents that will be logged, due to threshold limits, and logs them as top level traces. func (t *Trace) logTrace() { + t.lock.RLock() + defer t.lock.RUnlock() if t.durationIsWithinThreshold() { var buffer bytes.Buffer traceNum := rand.Int31() @@ -244,9 +258,13 @@ func (t *Trace) calculateStepThreshold() *time.Duration { traceThreshold := *t.threshold for _, s := range t.traceItems { nestedTrace, ok := s.(*Trace) - if ok && nestedTrace.threshold != nil { - traceThreshold = traceThreshold - *nestedTrace.threshold - lenTrace-- + if ok { + nestedTrace.lock.RLock() + if nestedTrace.threshold != nil { + traceThreshold = traceThreshold - *nestedTrace.threshold + lenTrace-- + } + nestedTrace.lock.RUnlock() } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 03162ffa1a8..699c36115fc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,13 +1,18 @@ -# cloud.google.com/go/compute v1.6.1 -## explicit; go 1.15 +# cloud.google.com/go/compute v1.21.0 +## explicit; go 1.19 +cloud.google.com/go/compute/internal +# cloud.google.com/go/compute/metadata v0.2.3 +## explicit; go 1.19 cloud.google.com/go/compute/metadata -# cloud.google.com/go/monitoring v1.5.0 -## explicit; go 1.16 +# cloud.google.com/go/monitoring v1.15.1 +## explicit; go 1.19 cloud.google.com/go/monitoring/apiv3/v2 +cloud.google.com/go/monitoring/apiv3/v2/monitoringpb cloud.google.com/go/monitoring/internal -# cloud.google.com/go/trace v1.2.0 -## explicit; go 1.16 +# cloud.google.com/go/trace v1.10.1 +## explicit; go 1.19 cloud.google.com/go/trace/apiv2 +cloud.google.com/go/trace/apiv2/tracepb cloud.google.com/go/trace/internal # contrib.go.opencensus.io/exporter/ocagent v0.7.0 ## explicit; go 1.13 @@ -21,23 +26,29 @@ contrib.go.opencensus.io/exporter/stackdriver contrib.go.opencensus.io/exporter/stackdriver/monitoredresource contrib.go.opencensus.io/exporter/stackdriver/monitoredresource/aws contrib.go.opencensus.io/exporter/stackdriver/monitoredresource/gcp +# github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 +## explicit; go 1.20 +github.com/AdaLogics/go-fuzz-headers # github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 ## explicit; go 1.16 github.com/Azure/go-ansiterm github.com/Azure/go-ansiterm/winterm +# github.com/Microsoft/hcsshim v0.11.0 +## explicit; go 1.18 +github.com/Microsoft/hcsshim/osversion # github.com/OneOfOne/xxhash v1.2.8 ## explicit; go 1.11 github.com/OneOfOne/xxhash # github.com/agnivade/levenshtein v1.1.1 ## explicit; go 1.13 github.com/agnivade/levenshtein -# github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e +# github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 ## explicit; go 1.16 github.com/antlr/antlr4/runtime/Go/antlr # github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d ## explicit; go 1.13 github.com/asaskevich/govalidator -# github.com/aws/aws-sdk-go v1.44.23 +# github.com/aws/aws-sdk-go v1.43.31 ## explicit; go 1.11 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/awserr @@ -85,19 +96,25 @@ github.com/beorn7/perks/quantile # github.com/blang/semver/v4 v4.0.0 ## explicit; go 1.14 github.com/blang/semver/v4 -# github.com/census-instrumentation/opencensus-proto v0.3.0 -## explicit +# github.com/cenkalti/backoff/v4 v4.2.1 +## explicit; go 1.18 +github.com/cenkalti/backoff/v4 +# github.com/census-instrumentation/opencensus-proto v0.4.1 +## explicit; go 1.18 github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1 github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1 github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1 github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1 github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1 github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1 -# github.com/cespare/xxhash/v2 v2.1.2 +# github.com/cespare/xxhash/v2 v2.2.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/containerd/containerd v1.6.12 -## explicit; go 1.17 +# github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be +## explicit +github.com/common-nighthawk/go-figure +# github.com/containerd/containerd v1.7.6 +## explicit; go 1.19 github.com/containerd/containerd/archive/compression github.com/containerd/containerd/content github.com/containerd/containerd/content/local @@ -106,24 +123,46 @@ github.com/containerd/containerd/filters github.com/containerd/containerd/images github.com/containerd/containerd/labels github.com/containerd/containerd/log +github.com/containerd/containerd/pkg/randutil github.com/containerd/containerd/platforms github.com/containerd/containerd/reference +github.com/containerd/containerd/reference/docker github.com/containerd/containerd/remotes github.com/containerd/containerd/remotes/docker github.com/containerd/containerd/remotes/docker/auth github.com/containerd/containerd/remotes/docker/schema1 github.com/containerd/containerd/remotes/errors +github.com/containerd/containerd/tracing github.com/containerd/containerd/version +# github.com/dapr/go-sdk v1.8.0 +## explicit; go 1.19 +github.com/dapr/go-sdk/actor +github.com/dapr/go-sdk/actor/api +github.com/dapr/go-sdk/actor/codec +github.com/dapr/go-sdk/actor/codec/constant +github.com/dapr/go-sdk/actor/codec/impl +github.com/dapr/go-sdk/actor/config +github.com/dapr/go-sdk/actor/error +github.com/dapr/go-sdk/actor/manager +github.com/dapr/go-sdk/actor/runtime +github.com/dapr/go-sdk/actor/state +github.com/dapr/go-sdk/client +github.com/dapr/go-sdk/dapr/proto/common/v1 +github.com/dapr/go-sdk/dapr/proto/runtime/v1 +github.com/dapr/go-sdk/service/common +github.com/dapr/go-sdk/service/http +github.com/dapr/go-sdk/service/internal +github.com/dapr/go-sdk/version # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/docker/cli v20.10.21+incompatible +# github.com/docker/cli v24.0.6+incompatible ## explicit github.com/docker/cli/cli/config github.com/docker/cli/cli/config/configfile github.com/docker/cli/cli/config/credentials github.com/docker/cli/cli/config/types -# github.com/docker/distribution v2.8.1+incompatible +# github.com/docker/distribution v2.8.2+incompatible ## explicit github.com/docker/distribution github.com/docker/distribution/digestset @@ -137,7 +176,7 @@ github.com/docker/distribution/registry/client/auth/challenge github.com/docker/distribution/registry/client/transport github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory -# github.com/docker/docker v20.10.21+incompatible +# github.com/docker/docker v24.0.6+incompatible ## explicit github.com/docker/docker/api/types github.com/docker/docker/api/types/blkiodev @@ -150,14 +189,13 @@ github.com/docker/docker/api/types/strslice github.com/docker/docker/api/types/swarm github.com/docker/docker/api/types/swarm/runtime github.com/docker/docker/api/types/versions +github.com/docker/docker/api/types/volume github.com/docker/docker/errdefs github.com/docker/docker/pkg/homedir github.com/docker/docker/pkg/ioutils github.com/docker/docker/pkg/jsonmessage github.com/docker/docker/pkg/longpath -github.com/docker/docker/pkg/stringid github.com/docker/docker/registry -github.com/docker/docker/rootless # github.com/docker/docker-credential-helpers v0.7.0 ## explicit; go 1.18 github.com/docker/docker-credential-helpers/client @@ -169,25 +207,34 @@ github.com/docker/go-connections/tlsconfig # github.com/docker/go-metrics v0.0.1 ## explicit; go 1.11 github.com/docker/go-metrics -# github.com/docker/go-units v0.4.0 +# github.com/docker/go-units v0.5.0 ## explicit github.com/docker/go-units -# github.com/emicklei/go-restful v2.16.0+incompatible -## explicit -github.com/emicklei/go-restful -github.com/emicklei/go-restful/log -# github.com/evanphx/json-patch v5.6.0+incompatible +# github.com/dominikbraun/graph v0.16.2 +## explicit; go 1.18 +github.com/dominikbraun/graph +# github.com/emicklei/go-restful/v3 v3.10.1 +## explicit; go 1.13 +github.com/emicklei/go-restful/v3 +github.com/emicklei/go-restful/v3/log +# github.com/evanphx/json-patch v4.12.0+incompatible ## explicit github.com/evanphx/json-patch +# github.com/evanphx/json-patch/v5 v5.6.0 +## explicit; go 1.12 +github.com/evanphx/json-patch/v5 # github.com/felixge/httpsnoop v1.0.3 ## explicit; go 1.13 github.com/felixge/httpsnoop # github.com/fsnotify/fsnotify v1.6.0 ## explicit; go 1.16 github.com/fsnotify/fsnotify -# github.com/ghodss/yaml v1.0.0 +# github.com/go-chi/chi/v5 v5.0.8 +## explicit; go 1.14 +github.com/go-chi/chi/v5 +# github.com/go-ini/ini v1.67.0 ## explicit -github.com/ghodss/yaml +github.com/go-ini/ini # github.com/go-kit/log v0.2.1 ## explicit; go 1.17 github.com/go-kit/log @@ -195,21 +242,25 @@ github.com/go-kit/log/level # github.com/go-logfmt/logfmt v0.5.1 ## explicit; go 1.17 github.com/go-logfmt/logfmt -# github.com/go-logr/logr v1.2.3 +# github.com/go-logr/logr v1.2.4 ## explicit; go 1.16 github.com/go-logr/logr -# github.com/go-logr/zapr v1.2.3 +github.com/go-logr/logr/funcr +# github.com/go-logr/stdr v1.2.2 +## explicit; go 1.16 +github.com/go-logr/stdr +# github.com/go-logr/zapr v1.2.4 ## explicit; go 1.16 github.com/go-logr/zapr -# github.com/go-openapi/jsonpointer v0.19.5 +# github.com/go-openapi/jsonpointer v0.19.6 ## explicit; go 1.13 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.20.0 +# github.com/go-openapi/jsonreference v0.20.1 ## explicit; go 1.13 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal -# github.com/go-openapi/swag v0.21.1 -## explicit; go 1.11 +# github.com/go-openapi/swag v0.22.3 +## explicit; go 1.18 github.com/go-openapi/swag # github.com/gobwas/glob v0.2.3 ## explicit @@ -225,25 +276,26 @@ github.com/gobwas/glob/util/strings ## explicit; go 1.15 github.com/gogo/protobuf/proto github.com/gogo/protobuf/sortkeys -# github.com/golang/glog v1.0.0 -## explicit; go 1.11 +# github.com/golang/glog v1.1.1 +## explicit; go 1.19 github.com/golang/glog +github.com/golang/glog/internal/logsink +github.com/golang/glog/internal/stackdump # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da ## explicit github.com/golang/groupcache/lru -# github.com/golang/protobuf v1.5.2 +# github.com/golang/protobuf v1.5.3 ## explicit; go 1.9 -github.com/golang/protobuf/descriptor github.com/golang/protobuf/jsonpb github.com/golang/protobuf/proto -github.com/golang/protobuf/protoc-gen-go/descriptor github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration +github.com/golang/protobuf/ptypes/empty github.com/golang/protobuf/ptypes/timestamp github.com/golang/protobuf/ptypes/wrappers -# github.com/google/cel-go v0.10.2 -## explicit; go 1.16 +# github.com/google/cel-go v0.12.6 +## explicit; go 1.17 github.com/google/cel-go/cel github.com/google/cel-go/checker github.com/google/cel-go/checker/decls @@ -262,7 +314,7 @@ github.com/google/cel-go/interpreter github.com/google/cel-go/interpreter/functions github.com/google/cel-go/parser github.com/google/cel-go/parser/gen -# github.com/google/gnostic v0.6.9 +# github.com/google/gnostic v0.5.7-v3refs ## explicit; go 1.12 github.com/google/gnostic/compiler github.com/google/gnostic/extensions @@ -281,11 +333,37 @@ github.com/google/go-cmp/cmp/internal/value ## explicit; go 1.12 github.com/google/gofuzz github.com/google/gofuzz/bytesource -# github.com/google/uuid v1.3.0 +# github.com/google/s2a-go v0.1.4 +## explicit; go 1.16 +github.com/google/s2a-go +github.com/google/s2a-go/fallback +github.com/google/s2a-go/internal/authinfo +github.com/google/s2a-go/internal/handshaker +github.com/google/s2a-go/internal/handshaker/service +github.com/google/s2a-go/internal/proto/common_go_proto +github.com/google/s2a-go/internal/proto/s2a_context_go_proto +github.com/google/s2a-go/internal/proto/s2a_go_proto +github.com/google/s2a-go/internal/proto/v2/common_go_proto +github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto +github.com/google/s2a-go/internal/proto/v2/s2a_go_proto +github.com/google/s2a-go/internal/record +github.com/google/s2a-go/internal/record/internal/aeadcrypter +github.com/google/s2a-go/internal/record/internal/halfconn +github.com/google/s2a-go/internal/tokenmanager +github.com/google/s2a-go/internal/v2 +github.com/google/s2a-go/internal/v2/certverifier +github.com/google/s2a-go/internal/v2/remotesigner +github.com/google/s2a-go/internal/v2/tlsconfigstore +github.com/google/s2a-go/stream +# github.com/google/uuid v1.3.1 ## explicit github.com/google/uuid -# github.com/googleapis/gax-go/v2 v2.4.0 -## explicit; go 1.15 +# github.com/googleapis/enterprise-certificate-proxy v0.2.3 +## explicit; go 1.19 +github.com/googleapis/enterprise-certificate-proxy/client +github.com/googleapis/enterprise-certificate-proxy/client/util +# github.com/googleapis/gax-go/v2 v2.11.0 +## explicit; go 1.19 github.com/googleapis/gax-go/v2 github.com/googleapis/gax-go/v2/apierror github.com/googleapis/gax-go/v2/apierror/internal/proto @@ -293,15 +371,15 @@ github.com/googleapis/gax-go/v2/internal # github.com/gorilla/mux v1.8.0 ## explicit; go 1.12 github.com/gorilla/mux -# github.com/grpc-ecosystem/grpc-gateway v1.16.0 -## explicit; go 1.14 -github.com/grpc-ecosystem/grpc-gateway/internal -github.com/grpc-ecosystem/grpc-gateway/runtime -github.com/grpc-ecosystem/grpc-gateway/utilities +# github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 +## explicit; go 1.17 +github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule +github.com/grpc-ecosystem/grpc-gateway/v2/runtime +github.com/grpc-ecosystem/grpc-gateway/v2/utilities # github.com/imdario/mergo v0.3.13 ## explicit; go 1.13 github.com/imdario/mergo -# github.com/inconshreveable/mousetrap v1.0.1 +# github.com/inconshreveable/mousetrap v1.1.0 ## explicit; go 1.18 github.com/inconshreveable/mousetrap # github.com/jmespath/go-jmespath v0.4.0 @@ -313,11 +391,12 @@ github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go -# github.com/klauspost/compress v1.15.1 -## explicit; go 1.15 +# github.com/klauspost/compress v1.16.0 +## explicit; go 1.18 github.com/klauspost/compress github.com/klauspost/compress/fse github.com/klauspost/compress/huff0 +github.com/klauspost/compress/internal/cpuinfo github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash @@ -351,37 +430,7 @@ github.com/morikuni/aec # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/nxadm/tail v1.4.8 -## explicit; go 1.13 -github.com/nxadm/tail -github.com/nxadm/tail/ratelimiter -github.com/nxadm/tail/util -github.com/nxadm/tail/watch -github.com/nxadm/tail/winfile -# github.com/onsi/ginkgo v1.16.5 -## explicit; go 1.16 -github.com/onsi/ginkgo -github.com/onsi/ginkgo/config -github.com/onsi/ginkgo/extensions/table -github.com/onsi/ginkgo/formatter -github.com/onsi/ginkgo/internal/codelocation -github.com/onsi/ginkgo/internal/containernode -github.com/onsi/ginkgo/internal/failer -github.com/onsi/ginkgo/internal/global -github.com/onsi/ginkgo/internal/leafnodes -github.com/onsi/ginkgo/internal/remote -github.com/onsi/ginkgo/internal/spec -github.com/onsi/ginkgo/internal/spec_iterator -github.com/onsi/ginkgo/internal/specrunner -github.com/onsi/ginkgo/internal/suite -github.com/onsi/ginkgo/internal/testingtproxy -github.com/onsi/ginkgo/internal/writer -github.com/onsi/ginkgo/reporters -github.com/onsi/ginkgo/reporters/stenographer -github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable -github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty -github.com/onsi/ginkgo/types -# github.com/onsi/gomega v1.19.0 +# github.com/onsi/gomega v1.27.7 ## explicit; go 1.18 github.com/onsi/gomega github.com/onsi/gomega/format @@ -393,10 +442,10 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/open-policy-agent/cert-controller v0.4.0 -## explicit; go 1.17 +# github.com/open-policy-agent/cert-controller v0.8.0 +## explicit; go 1.20 github.com/open-policy-agent/cert-controller/pkg/rotator -# github.com/open-policy-agent/frameworks/constraint v0.0.0-20221214024800-b745745c4118 +# github.com/open-policy-agent/frameworks/constraint v0.0.0-20231030230613-2e0cb3d68575 ## explicit; go 1.18 github.com/open-policy-agent/frameworks/constraint/deploy github.com/open-policy-agent/frameworks/constraint/pkg/apis @@ -410,30 +459,43 @@ github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1 github.com/open-policy-agent/frameworks/constraint/pkg/client github.com/open-policy-agent/frameworks/constraint/pkg/client/crds github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers -github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/local +github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel +github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema +github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/temporarydeleteme +github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego +github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego/schema github.com/open-policy-agent/frameworks/constraint/pkg/client/errors github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints github.com/open-policy-agent/frameworks/constraint/pkg/core/templates github.com/open-policy-agent/frameworks/constraint/pkg/externaldata github.com/open-policy-agent/frameworks/constraint/pkg/handler +github.com/open-policy-agent/frameworks/constraint/pkg/instrumentation github.com/open-policy-agent/frameworks/constraint/pkg/regorewriter github.com/open-policy-agent/frameworks/constraint/pkg/schema github.com/open-policy-agent/frameworks/constraint/pkg/types -# github.com/open-policy-agent/opa v0.47.2 -## explicit; go 1.17 +# github.com/open-policy-agent/opa v0.57.1 +## explicit; go 1.19 github.com/open-policy-agent/opa/ast github.com/open-policy-agent/opa/ast/internal/scanner github.com/open-policy-agent/opa/ast/internal/tokens +github.com/open-policy-agent/opa/ast/json github.com/open-policy-agent/opa/ast/location github.com/open-policy-agent/opa/bundle github.com/open-policy-agent/opa/capabilities +github.com/open-policy-agent/opa/config github.com/open-policy-agent/opa/format +github.com/open-policy-agent/opa/hooks github.com/open-policy-agent/opa/internal/bundle github.com/open-policy-agent/opa/internal/cidr/merge +github.com/open-policy-agent/opa/internal/compiler github.com/open-policy-agent/opa/internal/compiler/wasm github.com/open-policy-agent/opa/internal/compiler/wasm/opa +github.com/open-policy-agent/opa/internal/config github.com/open-policy-agent/opa/internal/debug github.com/open-policy-agent/opa/internal/deepcopy +github.com/open-policy-agent/opa/internal/edittree +github.com/open-policy-agent/opa/internal/edittree/bitvector +github.com/open-policy-agent/opa/internal/errors github.com/open-policy-agent/opa/internal/file/archive github.com/open-policy-agent/opa/internal/file/url github.com/open-policy-agent/opa/internal/future @@ -455,11 +517,15 @@ github.com/open-policy-agent/opa/internal/lcss github.com/open-policy-agent/opa/internal/leb128 github.com/open-policy-agent/opa/internal/merge github.com/open-policy-agent/opa/internal/planner -github.com/open-policy-agent/opa/internal/providers +github.com/open-policy-agent/opa/internal/providers/aws +github.com/open-policy-agent/opa/internal/providers/aws/crypto +github.com/open-policy-agent/opa/internal/providers/aws/v4 github.com/open-policy-agent/opa/internal/ref github.com/open-policy-agent/opa/internal/rego/opa +github.com/open-policy-agent/opa/internal/runtime/init github.com/open-policy-agent/opa/internal/semver github.com/open-policy-agent/opa/internal/strings +github.com/open-policy-agent/opa/internal/strvals github.com/open-policy-agent/opa/internal/uuid github.com/open-policy-agent/opa/internal/version github.com/open-policy-agent/opa/internal/wasm/constant @@ -473,11 +539,16 @@ github.com/open-policy-agent/opa/internal/wasm/util github.com/open-policy-agent/opa/ir github.com/open-policy-agent/opa/keys github.com/open-policy-agent/opa/loader +github.com/open-policy-agent/opa/loader/extension github.com/open-policy-agent/opa/loader/filter +github.com/open-policy-agent/opa/logging github.com/open-policy-agent/opa/metrics +github.com/open-policy-agent/opa/plugins +github.com/open-policy-agent/opa/plugins/rest github.com/open-policy-agent/opa/rego github.com/open-policy-agent/opa/resolver github.com/open-policy-agent/opa/resolver/wasm +github.com/open-policy-agent/opa/schemas github.com/open-policy-agent/opa/storage github.com/open-policy-agent/opa/storage/inmem github.com/open-policy-agent/opa/storage/internal/errors @@ -494,8 +565,8 @@ github.com/open-policy-agent/opa/version # github.com/opencontainers/go-digest v1.0.0 ## explicit; go 1.13 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.1.0-rc2 -## explicit; go 1.17 +# github.com/opencontainers/image-spec v1.1.0-rc5 +## explicit; go 1.18 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 # github.com/pkg/errors v0.9.1 @@ -504,22 +575,22 @@ github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/prometheus/client_golang v1.14.0 +# github.com/prometheus/client_golang v1.16.0 ## explicit; go 1.17 github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/collectors github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/promhttp -# github.com/prometheus/client_model v0.3.0 -## explicit; go 1.9 +# github.com/prometheus/client_model v0.4.0 +## explicit; go 1.18 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.37.0 -## explicit; go 1.16 +# github.com/prometheus/common v0.42.0 +## explicit; go 1.18 github.com/prometheus/common/expfmt github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model -# github.com/prometheus/procfs v0.8.0 -## explicit; go 1.17 +# github.com/prometheus/procfs v0.10.1 +## explicit; go 1.19 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util @@ -534,10 +605,10 @@ github.com/prometheus/statsd_exporter/pkg/mapper/fsm # github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 ## explicit github.com/rcrowley/go-metrics -# github.com/sirupsen/logrus v1.9.0 +# github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus -# github.com/spf13/cobra v1.6.1 +# github.com/spf13/cobra v1.7.0 ## explicit; go 1.15 github.com/spf13/cobra # github.com/spf13/pflag v1.0.5 @@ -546,8 +617,8 @@ github.com/spf13/pflag # github.com/stoewer/go-strcase v1.2.0 ## explicit; go 1.11 github.com/stoewer/go-strcase -# github.com/stretchr/testify v1.8.1 -## explicit; go 1.13 +# github.com/stretchr/testify v1.8.4 +## explicit; go 1.20 github.com/stretchr/testify/assert github.com/stretchr/testify/require # github.com/tchap/go-patricia/v2 v2.3.1 @@ -559,10 +630,10 @@ github.com/xeipuuv/gojsonpointer # github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 ## explicit github.com/xeipuuv/gojsonreference -# github.com/yashtewari/glob-intersection v0.1.0 +# github.com/yashtewari/glob-intersection v0.2.0 ## explicit; go 1.17 github.com/yashtewari/glob-intersection -# go.opencensus.io v0.23.0 +# go.opencensus.io v0.24.0 ## explicit; go 1.13 go.opencensus.io go.opencensus.io/internal @@ -583,95 +654,92 @@ go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/propagation go.opencensus.io/trace/tracestate -# go.opentelemetry.io/contrib v0.20.0 -## explicit; go 1.14 -go.opentelemetry.io/contrib -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 -## explicit; go 1.14 +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 +## explicit; go 1.19 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp -# go.opentelemetry.io/otel v1.7.0 => go.opentelemetry.io/otel v0.20.0 -## explicit; go 1.14 +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil +# go.opentelemetry.io/otel v1.19.0 +## explicit; go 1.20 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute +go.opentelemetry.io/otel/baggage go.opentelemetry.io/otel/codes go.opentelemetry.io/otel/internal +go.opentelemetry.io/otel/internal/attribute go.opentelemetry.io/otel/internal/baggage go.opentelemetry.io/otel/internal/global -go.opentelemetry.io/otel/internal/metric -go.opentelemetry.io/otel/internal/trace/noop go.opentelemetry.io/otel/propagation -go.opentelemetry.io/otel/semconv -go.opentelemetry.io/otel/unit -# go.opentelemetry.io/otel/exporters/otlp v0.20.0 -## explicit; go 1.14 -go.opentelemetry.io/otel/exporters/otlp -go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig -go.opentelemetry.io/otel/exporters/otlp/internal/transform -go.opentelemetry.io/otel/exporters/otlp/otlpgrpc -# go.opentelemetry.io/otel/metric v0.30.0 => go.opentelemetry.io/otel/metric v0.20.0 -## explicit; go 1.14 +go.opentelemetry.io/otel/semconv/internal/v2 +go.opentelemetry.io/otel/semconv/v1.17.0 +go.opentelemetry.io/otel/semconv/v1.17.0/httpconv +go.opentelemetry.io/otel/semconv/v1.21.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 +## explicit; go 1.20 +go.opentelemetry.io/otel/exporters/otlp/otlptrace +go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform +# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 +## explicit; go 1.20 +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry +# go.opentelemetry.io/otel/metric v1.19.0 +## explicit; go 1.20 go.opentelemetry.io/otel/metric -go.opentelemetry.io/otel/metric/global -go.opentelemetry.io/otel/metric/number -go.opentelemetry.io/otel/metric/registry -# go.opentelemetry.io/otel/sdk v1.7.0 => go.opentelemetry.io/otel/sdk v0.20.0 -## explicit; go 1.14 +go.opentelemetry.io/otel/metric/embedded +# go.opentelemetry.io/otel/sdk v1.19.0 +## explicit; go 1.20 +go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/instrumentation go.opentelemetry.io/otel/sdk/internal +go.opentelemetry.io/otel/sdk/internal/env go.opentelemetry.io/otel/sdk/resource go.opentelemetry.io/otel/sdk/trace -# go.opentelemetry.io/otel/sdk/export/metric v0.20.0 -## explicit; go 1.14 -go.opentelemetry.io/otel/sdk/export/metric -go.opentelemetry.io/otel/sdk/export/metric/aggregation -# go.opentelemetry.io/otel/sdk/metric v0.20.0 -## explicit; go 1.14 -go.opentelemetry.io/otel/sdk/metric -go.opentelemetry.io/otel/sdk/metric/aggregator -go.opentelemetry.io/otel/sdk/metric/aggregator/exact -go.opentelemetry.io/otel/sdk/metric/aggregator/histogram -go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue -go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount -go.opentelemetry.io/otel/sdk/metric/aggregator/sum -go.opentelemetry.io/otel/sdk/metric/controller/basic -go.opentelemetry.io/otel/sdk/metric/controller/time -go.opentelemetry.io/otel/sdk/metric/processor/basic -go.opentelemetry.io/otel/sdk/metric/selector/simple -# go.opentelemetry.io/otel/trace v1.7.0 => go.opentelemetry.io/otel/trace v0.20.0 -## explicit; go 1.14 +# go.opentelemetry.io/otel/trace v1.19.0 +## explicit; go 1.20 go.opentelemetry.io/otel/trace -# go.opentelemetry.io/proto/otlp v0.16.0 => go.opentelemetry.io/proto/otlp v0.7.0 -## explicit; go 1.15 -go.opentelemetry.io/proto/otlp/collector/metrics/v1 +# go.opentelemetry.io/proto/otlp v1.0.0 +## explicit; go 1.17 go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 -go.opentelemetry.io/proto/otlp/metrics/v1 go.opentelemetry.io/proto/otlp/resource/v1 go.opentelemetry.io/proto/otlp/trace/v1 -# go.uber.org/atomic v1.9.0 -## explicit; go 1.13 +# go.uber.org/atomic v1.11.0 +## explicit; go 1.18 go.uber.org/atomic -# go.uber.org/automaxprocs v1.5.1 +# go.uber.org/automaxprocs v1.5.3 ## explicit; go 1.18 go.uber.org/automaxprocs go.uber.org/automaxprocs/internal/cgroups go.uber.org/automaxprocs/internal/runtime go.uber.org/automaxprocs/maxprocs -# go.uber.org/multierr v1.8.0 -## explicit; go 1.14 +# go.uber.org/multierr v1.6.0 +## explicit; go 1.12 go.uber.org/multierr -# go.uber.org/zap v1.21.0 -## explicit; go 1.13 +# go.uber.org/zap v1.24.0 +## explicit; go 1.19 go.uber.org/zap go.uber.org/zap/buffer +go.uber.org/zap/internal go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/net v0.4.0 +# golang.org/x/crypto v0.14.0 +## explicit; go 1.17 +golang.org/x/crypto/chacha20 +golang.org/x/crypto/chacha20poly1305 +golang.org/x/crypto/cryptobyte +golang.org/x/crypto/cryptobyte/asn1 +golang.org/x/crypto/hkdf +golang.org/x/crypto/internal/alias +golang.org/x/crypto/internal/poly1305 +# golang.org/x/mod v0.10.0 +## explicit; go 1.17 +# golang.org/x/net v0.17.0 ## explicit; go 1.17 golang.org/x/net/context -golang.org/x/net/context/ctxhttp golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset @@ -681,8 +749,8 @@ golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 -## explicit; go 1.15 +# golang.org/x/oauth2 v0.10.0 +## explicit; go 1.17 golang.org/x/oauth2 golang.org/x/oauth2/authhandler golang.org/x/oauth2/google @@ -690,21 +758,22 @@ golang.org/x/oauth2/google/internal/externalaccount golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt -# golang.org/x/sync v0.1.0 -## explicit +# golang.org/x/sync v0.3.0 +## explicit; go 1.17 golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.3.0 +# golang.org/x/sys v0.13.0 ## explicit; go 1.17 +golang.org/x/sys/cpu golang.org/x/sys/execabs -golang.org/x/sys/internal/unsafeheader golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.3.0 +golang.org/x/sys/windows/registry +# golang.org/x/term v0.13.0 ## explicit; go 1.17 golang.org/x/term -# golang.org/x/text v0.5.0 +# golang.org/x/text v0.13.0 ## explicit; go 1.17 golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -727,25 +796,27 @@ golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm golang.org/x/text/width -# golang.org/x/time v0.0.0-20220609170525-579cf78fd858 +# golang.org/x/time v0.3.0 ## explicit golang.org/x/time/rate -# gomodules.xyz/jsonpatch/v2 v2.2.0 -## explicit; go 1.12 +# gomodules.xyz/jsonpatch/v2 v2.3.0 +## explicit; go 1.20 gomodules.xyz/jsonpatch/v2 -# google.golang.org/api v0.81.0 -## explicit; go 1.15 +# google.golang.org/api v0.126.0 +## explicit; go 1.19 google.golang.org/api/googleapi +google.golang.org/api/googleapi/transport google.golang.org/api/internal +google.golang.org/api/internal/cert google.golang.org/api/internal/impersonate google.golang.org/api/internal/third_party/uritemplates google.golang.org/api/iterator google.golang.org/api/option google.golang.org/api/option/internaloption google.golang.org/api/support/bundler -google.golang.org/api/transport/cert google.golang.org/api/transport/grpc -google.golang.org/api/transport/internal/dca +google.golang.org/api/transport/http +google.golang.org/api/transport/http/internal/propagation # google.golang.org/appengine v1.6.7 ## explicit; go 1.11 google.golang.org/appengine @@ -760,8 +831,14 @@ google.golang.org/appengine/internal/socket google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/socket google.golang.org/appengine/urlfetch -# google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 -## explicit; go 1.15 +# google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 +## explicit; go 1.19 +google.golang.org/genproto/googleapis/devtools/cloudtrace/v2 +google.golang.org/genproto/googleapis/monitoring/v3 +google.golang.org/genproto/googleapis/type/calendarperiod +google.golang.org/genproto/internal +# google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 +## explicit; go 1.19 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/api/distribution @@ -770,15 +847,13 @@ google.golang.org/genproto/googleapis/api/httpbody google.golang.org/genproto/googleapis/api/label google.golang.org/genproto/googleapis/api/metric google.golang.org/genproto/googleapis/api/monitoredres -google.golang.org/genproto/googleapis/devtools/cloudtrace/v2 -google.golang.org/genproto/googleapis/monitoring/v3 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 +## explicit; go 1.19 google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -google.golang.org/genproto/googleapis/type/calendarperiod -google.golang.org/genproto/protobuf/field_mask -# google.golang.org/grpc v1.51.0 -## explicit; go 1.17 +# google.golang.org/grpc v1.58.2 +## explicit; go 1.19 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff @@ -807,6 +882,7 @@ google.golang.org/grpc/encoding google.golang.org/grpc/encoding/gzip google.golang.org/grpc/encoding/proto google.golang.org/grpc/grpclog +google.golang.org/grpc/health/grpc_health_v1 google.golang.org/grpc/internal google.golang.org/grpc/internal/backoff google.golang.org/grpc/internal/balancer/gracefulswitch @@ -821,6 +897,7 @@ google.golang.org/grpc/internal/grpclog google.golang.org/grpc/internal/grpcrand google.golang.org/grpc/internal/grpcsync google.golang.org/grpc/internal/grpcutil +google.golang.org/grpc/internal/idle google.golang.org/grpc/internal/metadata google.golang.org/grpc/internal/pretty google.golang.org/grpc/internal/resolver @@ -840,7 +917,8 @@ google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/protobuf v1.28.1 +google.golang.org/grpc/test/bufconn +# google.golang.org/protobuf v1.31.0 ## explicit; go 1.11 google.golang.org/protobuf/encoding/protojson google.golang.org/protobuf/encoding/prototext @@ -882,26 +960,26 @@ google.golang.org/protobuf/types/known/wrapperspb # gopkg.in/inf.v0 v0.9.1 ## explicit gopkg.in/inf.v0 -# gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 -## explicit -gopkg.in/tomb.v1 # gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15 gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# k8s.io/api v0.24.9 -## explicit; go 1.18 +# k8s.io/api v0.27.4 +## explicit; go 1.20 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 k8s.io/api/admissionregistration/v1 +k8s.io/api/admissionregistration/v1alpha1 k8s.io/api/admissionregistration/v1beta1 +k8s.io/api/apidiscovery/v2beta1 k8s.io/api/apiserverinternal/v1alpha1 k8s.io/api/apps/v1 k8s.io/api/apps/v1beta1 k8s.io/api/apps/v1beta2 k8s.io/api/authentication/v1 +k8s.io/api/authentication/v1alpha1 k8s.io/api/authentication/v1beta1 k8s.io/api/authorization/v1 k8s.io/api/authorization/v1beta1 @@ -912,6 +990,7 @@ k8s.io/api/autoscaling/v2beta2 k8s.io/api/batch/v1 k8s.io/api/batch/v1beta1 k8s.io/api/certificates/v1 +k8s.io/api/certificates/v1alpha1 k8s.io/api/certificates/v1beta1 k8s.io/api/coordination/v1 k8s.io/api/coordination/v1beta1 @@ -924,7 +1003,9 @@ k8s.io/api/extensions/v1beta1 k8s.io/api/flowcontrol/v1alpha1 k8s.io/api/flowcontrol/v1beta1 k8s.io/api/flowcontrol/v1beta2 +k8s.io/api/flowcontrol/v1beta3 k8s.io/api/networking/v1 +k8s.io/api/networking/v1alpha1 k8s.io/api/networking/v1beta1 k8s.io/api/node/v1 k8s.io/api/node/v1alpha1 @@ -934,14 +1015,15 @@ k8s.io/api/policy/v1beta1 k8s.io/api/rbac/v1 k8s.io/api/rbac/v1alpha1 k8s.io/api/rbac/v1beta1 +k8s.io/api/resource/v1alpha2 k8s.io/api/scheduling/v1 k8s.io/api/scheduling/v1alpha1 k8s.io/api/scheduling/v1beta1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 -# k8s.io/apiextensions-apiserver v0.24.7 -## explicit; go 1.16 +# k8s.io/apiextensions-apiserver v0.27.4 +## explicit; go 1.20 k8s.io/apiextensions-apiserver/pkg/apihelpers k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 @@ -949,7 +1031,7 @@ k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation k8s.io/apiextensions-apiserver/pkg/apiserver/schema k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel -k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library +k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning @@ -958,9 +1040,8 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 -k8s.io/apiextensions-apiserver/third_party/forked/celopenapi/model -# k8s.io/apimachinery v0.24.9 -## explicit; go 1.18 +# k8s.io/apimachinery v0.27.4 +## explicit; go 1.20 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/meta @@ -994,9 +1075,11 @@ k8s.io/apimachinery/pkg/util/framer k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/util/json k8s.io/apimachinery/pkg/util/managedfields +k8s.io/apimachinery/pkg/util/managedfields/internal k8s.io/apimachinery/pkg/util/mergepatch k8s.io/apimachinery/pkg/util/naming k8s.io/apimachinery/pkg/util/net +k8s.io/apimachinery/pkg/util/rand k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/util/sets k8s.io/apimachinery/pkg/util/strategicpatch @@ -1009,8 +1092,20 @@ k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/json k8s.io/apimachinery/third_party/forked/golang/reflect -# k8s.io/apiserver v0.24.7 -## explicit; go 1.16 +# k8s.io/apiserver v0.27.4 +## explicit; go 1.20 +k8s.io/apiserver/pkg/admission +k8s.io/apiserver/pkg/admission/cel +k8s.io/apiserver/pkg/admission/initializer +k8s.io/apiserver/pkg/admission/metrics +k8s.io/apiserver/pkg/admission/plugin/cel +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching +k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions +k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace +k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object +k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules k8s.io/apiserver/pkg/apis/apiserver k8s.io/apiserver/pkg/apis/apiserver/install k8s.io/apiserver/pkg/apis/apiserver/v1 @@ -1018,19 +1113,31 @@ k8s.io/apiserver/pkg/apis/apiserver/v1alpha1 k8s.io/apiserver/pkg/apis/apiserver/v1beta1 k8s.io/apiserver/pkg/apis/audit k8s.io/apiserver/pkg/apis/audit/v1 +k8s.io/apiserver/pkg/apis/cel k8s.io/apiserver/pkg/audit +k8s.io/apiserver/pkg/authentication/serviceaccount k8s.io/apiserver/pkg/authentication/user k8s.io/apiserver/pkg/authorization/authorizer +k8s.io/apiserver/pkg/cel +k8s.io/apiserver/pkg/cel/common +k8s.io/apiserver/pkg/cel/library +k8s.io/apiserver/pkg/cel/metrics +k8s.io/apiserver/pkg/cel/openapi +k8s.io/apiserver/pkg/cel/openapi/resolver +k8s.io/apiserver/pkg/endpoints/openapi k8s.io/apiserver/pkg/endpoints/request k8s.io/apiserver/pkg/features +k8s.io/apiserver/pkg/quota/v1 k8s.io/apiserver/pkg/server/egressselector k8s.io/apiserver/pkg/server/egressselector/metrics k8s.io/apiserver/pkg/util/feature k8s.io/apiserver/pkg/util/webhook k8s.io/apiserver/pkg/util/x509metrics -# k8s.io/client-go v0.24.9 -## explicit; go 1.18 +k8s.io/apiserver/pkg/warning +# k8s.io/client-go v0.27.4 +## explicit; go 1.20 k8s.io/client-go/applyconfigurations/admissionregistration/v1 +k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1 k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1 k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1 k8s.io/client-go/applyconfigurations/apps/v1 @@ -1043,6 +1150,7 @@ k8s.io/client-go/applyconfigurations/autoscaling/v2beta2 k8s.io/client-go/applyconfigurations/batch/v1 k8s.io/client-go/applyconfigurations/batch/v1beta1 k8s.io/client-go/applyconfigurations/certificates/v1 +k8s.io/client-go/applyconfigurations/certificates/v1alpha1 k8s.io/client-go/applyconfigurations/certificates/v1beta1 k8s.io/client-go/applyconfigurations/coordination/v1 k8s.io/client-go/applyconfigurations/coordination/v1beta1 @@ -1055,9 +1163,11 @@ k8s.io/client-go/applyconfigurations/extensions/v1beta1 k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1 k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1 k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2 +k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3 k8s.io/client-go/applyconfigurations/internal k8s.io/client-go/applyconfigurations/meta/v1 k8s.io/client-go/applyconfigurations/networking/v1 +k8s.io/client-go/applyconfigurations/networking/v1alpha1 k8s.io/client-go/applyconfigurations/networking/v1beta1 k8s.io/client-go/applyconfigurations/node/v1 k8s.io/client-go/applyconfigurations/node/v1alpha1 @@ -1067,6 +1177,7 @@ k8s.io/client-go/applyconfigurations/policy/v1beta1 k8s.io/client-go/applyconfigurations/rbac/v1 k8s.io/client-go/applyconfigurations/rbac/v1alpha1 k8s.io/client-go/applyconfigurations/rbac/v1beta1 +k8s.io/client-go/applyconfigurations/resource/v1alpha2 k8s.io/client-go/applyconfigurations/scheduling/v1 k8s.io/client-go/applyconfigurations/scheduling/v1alpha1 k8s.io/client-go/applyconfigurations/scheduling/v1beta1 @@ -1075,15 +1186,86 @@ k8s.io/client-go/applyconfigurations/storage/v1alpha1 k8s.io/client-go/applyconfigurations/storage/v1beta1 k8s.io/client-go/discovery k8s.io/client-go/dynamic +k8s.io/client-go/dynamic/dynamicinformer +k8s.io/client-go/dynamic/dynamiclister +k8s.io/client-go/informers +k8s.io/client-go/informers/admissionregistration +k8s.io/client-go/informers/admissionregistration/v1 +k8s.io/client-go/informers/admissionregistration/v1alpha1 +k8s.io/client-go/informers/admissionregistration/v1beta1 +k8s.io/client-go/informers/apiserverinternal +k8s.io/client-go/informers/apiserverinternal/v1alpha1 +k8s.io/client-go/informers/apps +k8s.io/client-go/informers/apps/v1 +k8s.io/client-go/informers/apps/v1beta1 +k8s.io/client-go/informers/apps/v1beta2 +k8s.io/client-go/informers/autoscaling +k8s.io/client-go/informers/autoscaling/v1 +k8s.io/client-go/informers/autoscaling/v2 +k8s.io/client-go/informers/autoscaling/v2beta1 +k8s.io/client-go/informers/autoscaling/v2beta2 +k8s.io/client-go/informers/batch +k8s.io/client-go/informers/batch/v1 +k8s.io/client-go/informers/batch/v1beta1 +k8s.io/client-go/informers/certificates +k8s.io/client-go/informers/certificates/v1 +k8s.io/client-go/informers/certificates/v1alpha1 +k8s.io/client-go/informers/certificates/v1beta1 +k8s.io/client-go/informers/coordination +k8s.io/client-go/informers/coordination/v1 +k8s.io/client-go/informers/coordination/v1beta1 +k8s.io/client-go/informers/core +k8s.io/client-go/informers/core/v1 +k8s.io/client-go/informers/discovery +k8s.io/client-go/informers/discovery/v1 +k8s.io/client-go/informers/discovery/v1beta1 +k8s.io/client-go/informers/events +k8s.io/client-go/informers/events/v1 +k8s.io/client-go/informers/events/v1beta1 +k8s.io/client-go/informers/extensions +k8s.io/client-go/informers/extensions/v1beta1 +k8s.io/client-go/informers/flowcontrol +k8s.io/client-go/informers/flowcontrol/v1alpha1 +k8s.io/client-go/informers/flowcontrol/v1beta1 +k8s.io/client-go/informers/flowcontrol/v1beta2 +k8s.io/client-go/informers/flowcontrol/v1beta3 +k8s.io/client-go/informers/internalinterfaces +k8s.io/client-go/informers/networking +k8s.io/client-go/informers/networking/v1 +k8s.io/client-go/informers/networking/v1alpha1 +k8s.io/client-go/informers/networking/v1beta1 +k8s.io/client-go/informers/node +k8s.io/client-go/informers/node/v1 +k8s.io/client-go/informers/node/v1alpha1 +k8s.io/client-go/informers/node/v1beta1 +k8s.io/client-go/informers/policy +k8s.io/client-go/informers/policy/v1 +k8s.io/client-go/informers/policy/v1beta1 +k8s.io/client-go/informers/rbac +k8s.io/client-go/informers/rbac/v1 +k8s.io/client-go/informers/rbac/v1alpha1 +k8s.io/client-go/informers/rbac/v1beta1 +k8s.io/client-go/informers/resource +k8s.io/client-go/informers/resource/v1alpha2 +k8s.io/client-go/informers/scheduling +k8s.io/client-go/informers/scheduling/v1 +k8s.io/client-go/informers/scheduling/v1alpha1 +k8s.io/client-go/informers/scheduling/v1beta1 +k8s.io/client-go/informers/storage +k8s.io/client-go/informers/storage/v1 +k8s.io/client-go/informers/storage/v1alpha1 +k8s.io/client-go/informers/storage/v1beta1 k8s.io/client-go/kubernetes k8s.io/client-go/kubernetes/scheme k8s.io/client-go/kubernetes/typed/admissionregistration/v1 +k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1 k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1 k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1 k8s.io/client-go/kubernetes/typed/apps/v1 k8s.io/client-go/kubernetes/typed/apps/v1beta1 k8s.io/client-go/kubernetes/typed/apps/v1beta2 k8s.io/client-go/kubernetes/typed/authentication/v1 +k8s.io/client-go/kubernetes/typed/authentication/v1alpha1 k8s.io/client-go/kubernetes/typed/authentication/v1beta1 k8s.io/client-go/kubernetes/typed/authorization/v1 k8s.io/client-go/kubernetes/typed/authorization/v1beta1 @@ -1094,6 +1276,7 @@ k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2 k8s.io/client-go/kubernetes/typed/batch/v1 k8s.io/client-go/kubernetes/typed/batch/v1beta1 k8s.io/client-go/kubernetes/typed/certificates/v1 +k8s.io/client-go/kubernetes/typed/certificates/v1alpha1 k8s.io/client-go/kubernetes/typed/certificates/v1beta1 k8s.io/client-go/kubernetes/typed/coordination/v1 k8s.io/client-go/kubernetes/typed/coordination/v1beta1 @@ -1106,7 +1289,9 @@ k8s.io/client-go/kubernetes/typed/extensions/v1beta1 k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1 k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1 k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2 +k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3 k8s.io/client-go/kubernetes/typed/networking/v1 +k8s.io/client-go/kubernetes/typed/networking/v1alpha1 k8s.io/client-go/kubernetes/typed/networking/v1beta1 k8s.io/client-go/kubernetes/typed/node/v1 k8s.io/client-go/kubernetes/typed/node/v1alpha1 @@ -1116,12 +1301,59 @@ k8s.io/client-go/kubernetes/typed/policy/v1beta1 k8s.io/client-go/kubernetes/typed/rbac/v1 k8s.io/client-go/kubernetes/typed/rbac/v1alpha1 k8s.io/client-go/kubernetes/typed/rbac/v1beta1 +k8s.io/client-go/kubernetes/typed/resource/v1alpha2 k8s.io/client-go/kubernetes/typed/scheduling/v1 k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1 k8s.io/client-go/kubernetes/typed/scheduling/v1beta1 k8s.io/client-go/kubernetes/typed/storage/v1 k8s.io/client-go/kubernetes/typed/storage/v1alpha1 k8s.io/client-go/kubernetes/typed/storage/v1beta1 +k8s.io/client-go/listers/admissionregistration/v1 +k8s.io/client-go/listers/admissionregistration/v1alpha1 +k8s.io/client-go/listers/admissionregistration/v1beta1 +k8s.io/client-go/listers/apiserverinternal/v1alpha1 +k8s.io/client-go/listers/apps/v1 +k8s.io/client-go/listers/apps/v1beta1 +k8s.io/client-go/listers/apps/v1beta2 +k8s.io/client-go/listers/autoscaling/v1 +k8s.io/client-go/listers/autoscaling/v2 +k8s.io/client-go/listers/autoscaling/v2beta1 +k8s.io/client-go/listers/autoscaling/v2beta2 +k8s.io/client-go/listers/batch/v1 +k8s.io/client-go/listers/batch/v1beta1 +k8s.io/client-go/listers/certificates/v1 +k8s.io/client-go/listers/certificates/v1alpha1 +k8s.io/client-go/listers/certificates/v1beta1 +k8s.io/client-go/listers/coordination/v1 +k8s.io/client-go/listers/coordination/v1beta1 +k8s.io/client-go/listers/core/v1 +k8s.io/client-go/listers/discovery/v1 +k8s.io/client-go/listers/discovery/v1beta1 +k8s.io/client-go/listers/events/v1 +k8s.io/client-go/listers/events/v1beta1 +k8s.io/client-go/listers/extensions/v1beta1 +k8s.io/client-go/listers/flowcontrol/v1alpha1 +k8s.io/client-go/listers/flowcontrol/v1beta1 +k8s.io/client-go/listers/flowcontrol/v1beta2 +k8s.io/client-go/listers/flowcontrol/v1beta3 +k8s.io/client-go/listers/networking/v1 +k8s.io/client-go/listers/networking/v1alpha1 +k8s.io/client-go/listers/networking/v1beta1 +k8s.io/client-go/listers/node/v1 +k8s.io/client-go/listers/node/v1alpha1 +k8s.io/client-go/listers/node/v1beta1 +k8s.io/client-go/listers/policy/v1 +k8s.io/client-go/listers/policy/v1beta1 +k8s.io/client-go/listers/rbac/v1 +k8s.io/client-go/listers/rbac/v1alpha1 +k8s.io/client-go/listers/rbac/v1beta1 +k8s.io/client-go/listers/resource/v1alpha2 +k8s.io/client-go/listers/scheduling/v1 +k8s.io/client-go/listers/scheduling/v1alpha1 +k8s.io/client-go/listers/scheduling/v1beta1 +k8s.io/client-go/listers/storage/v1 +k8s.io/client-go/listers/storage/v1alpha1 +k8s.io/client-go/listers/storage/v1beta1 k8s.io/client-go/metadata k8s.io/client-go/openapi k8s.io/client-go/pkg/apis/clientauthentication @@ -1134,9 +1366,10 @@ k8s.io/client-go/plugin/pkg/client/auth/gcp k8s.io/client-go/rest k8s.io/client-go/rest/watch k8s.io/client-go/restmapper -k8s.io/client-go/third_party/forked/golang/template +k8s.io/client-go/testing k8s.io/client-go/tools/auth k8s.io/client-go/tools/cache +k8s.io/client-go/tools/cache/synctrack k8s.io/client-go/tools/clientcmd k8s.io/client-go/tools/clientcmd/api k8s.io/client-go/tools/clientcmd/api/latest @@ -1153,20 +1386,22 @@ k8s.io/client-go/util/cert k8s.io/client-go/util/connrotation k8s.io/client-go/util/flowcontrol k8s.io/client-go/util/homedir -k8s.io/client-go/util/jsonpath k8s.io/client-go/util/keyutil k8s.io/client-go/util/retry k8s.io/client-go/util/workqueue -# k8s.io/component-base v0.24.7 -## explicit; go 1.16 +# k8s.io/component-base v0.27.4 +## explicit; go 1.20 k8s.io/component-base/config k8s.io/component-base/config/v1alpha1 k8s.io/component-base/featuregate k8s.io/component-base/metrics k8s.io/component-base/metrics/legacyregistry -k8s.io/component-base/traces +k8s.io/component-base/metrics/prometheus/feature +k8s.io/component-base/metrics/prometheusextension +k8s.io/component-base/tracing +k8s.io/component-base/tracing/api/v1 k8s.io/component-base/version -# k8s.io/klog/v2 v2.70.1 +# k8s.io/klog/v2 v2.90.1 ## explicit; go 1.13 k8s.io/klog/v2 k8s.io/klog/v2/internal/buffer @@ -1174,24 +1409,27 @@ k8s.io/klog/v2/internal/clock k8s.io/klog/v2/internal/dbg k8s.io/klog/v2/internal/serialize k8s.io/klog/v2/internal/severity -# k8s.io/kube-openapi v0.0.0-20220413171646-5e7f5fdc6da6 -## explicit; go 1.16 +# k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f +## explicit; go 1.19 k8s.io/kube-openapi/pkg/builder3/util +k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common k8s.io/kube-openapi/pkg/handler3 -k8s.io/kube-openapi/pkg/internal/handler +k8s.io/kube-openapi/pkg/internal +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json k8s.io/kube-openapi/pkg/openapiconv k8s.io/kube-openapi/pkg/schemaconv k8s.io/kube-openapi/pkg/schemamutation k8s.io/kube-openapi/pkg/spec3 +k8s.io/kube-openapi/pkg/util k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/validation/errors k8s.io/kube-openapi/pkg/validation/spec k8s.io/kube-openapi/pkg/validation/strfmt k8s.io/kube-openapi/pkg/validation/strfmt/bson k8s.io/kube-openapi/pkg/validation/validate -# k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 -## explicit; go 1.12 +# k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 +## explicit; go 1.18 k8s.io/utils/buffer k8s.io/utils/clock k8s.io/utils/clock/testing @@ -1204,7 +1442,7 @@ k8s.io/utils/path k8s.io/utils/pointer k8s.io/utils/strings/slices k8s.io/utils/trace -# oras.land/oras-go v1.2.2 +# oras.land/oras-go v1.2.4 ## explicit; go 1.18 oras.land/oras-go/pkg/artifact oras.land/oras-go/pkg/auth @@ -1212,12 +1450,14 @@ oras.land/oras-go/pkg/auth/docker oras.land/oras-go/pkg/content oras.land/oras-go/pkg/oras oras.land/oras-go/pkg/target -# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 +# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 ## explicit; go 1.17 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client +sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics +sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client -# sigs.k8s.io/controller-runtime v0.12.3 -## explicit; go 1.17 +# sigs.k8s.io/controller-runtime v0.15.0 => ./third_party/sigs.k8s.io/controller-runtime +## explicit; go 1.20 sigs.k8s.io/controller-runtime sigs.k8s.io/controller-runtime/pkg/builder sigs.k8s.io/controller-runtime/pkg/cache @@ -1227,25 +1467,28 @@ sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics sigs.k8s.io/controller-runtime/pkg/client sigs.k8s.io/controller-runtime/pkg/client/apiutil sigs.k8s.io/controller-runtime/pkg/client/config +sigs.k8s.io/controller-runtime/pkg/client/fake +sigs.k8s.io/controller-runtime/pkg/client/interceptor sigs.k8s.io/controller-runtime/pkg/cluster sigs.k8s.io/controller-runtime/pkg/config sigs.k8s.io/controller-runtime/pkg/config/v1alpha1 sigs.k8s.io/controller-runtime/pkg/controller -sigs.k8s.io/controller-runtime/pkg/controller/controllertest sigs.k8s.io/controller-runtime/pkg/controller/controllerutil sigs.k8s.io/controller-runtime/pkg/conversion sigs.k8s.io/controller-runtime/pkg/envtest -sigs.k8s.io/controller-runtime/pkg/envtest/printer sigs.k8s.io/controller-runtime/pkg/event sigs.k8s.io/controller-runtime/pkg/handler sigs.k8s.io/controller-runtime/pkg/healthz sigs.k8s.io/controller-runtime/pkg/internal/controller sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics +sigs.k8s.io/controller-runtime/pkg/internal/field/selector sigs.k8s.io/controller-runtime/pkg/internal/flock sigs.k8s.io/controller-runtime/pkg/internal/httpserver sigs.k8s.io/controller-runtime/pkg/internal/log sigs.k8s.io/controller-runtime/pkg/internal/objectutil sigs.k8s.io/controller-runtime/pkg/internal/recorder +sigs.k8s.io/controller-runtime/pkg/internal/source +sigs.k8s.io/controller-runtime/pkg/internal/syncs sigs.k8s.io/controller-runtime/pkg/internal/testing/addr sigs.k8s.io/controller-runtime/pkg/internal/testing/certs sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane @@ -1260,30 +1503,27 @@ sigs.k8s.io/controller-runtime/pkg/predicate sigs.k8s.io/controller-runtime/pkg/ratelimiter sigs.k8s.io/controller-runtime/pkg/reconcile sigs.k8s.io/controller-runtime/pkg/recorder -sigs.k8s.io/controller-runtime/pkg/runtime/inject sigs.k8s.io/controller-runtime/pkg/scheme sigs.k8s.io/controller-runtime/pkg/source -sigs.k8s.io/controller-runtime/pkg/source/internal sigs.k8s.io/controller-runtime/pkg/webhook sigs.k8s.io/controller-runtime/pkg/webhook/admission sigs.k8s.io/controller-runtime/pkg/webhook/conversion sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics -# sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 -## explicit; go 1.17 +# sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd +## explicit; go 1.18 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json -# sigs.k8s.io/structured-merge-diff/v4 v4.2.1 +# sigs.k8s.io/release-utils v0.7.3 +## explicit; go 1.18 +sigs.k8s.io/release-utils/version +# sigs.k8s.io/structured-merge-diff/v4 v4.2.3 ## explicit; go 1.13 sigs.k8s.io/structured-merge-diff/v4/fieldpath +sigs.k8s.io/structured-merge-diff/v4/merge sigs.k8s.io/structured-merge-diff/v4/schema sigs.k8s.io/structured-merge-diff/v4/typed sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 -# go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0 -# go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v0.20.0 -# go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0 -# go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v0.20.0 -# go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v0.7.0 +# sigs.k8s.io/controller-runtime => ./third_party/sigs.k8s.io/controller-runtime diff --git a/vendor/oras.land/oras-go/pkg/auth/docker/login_tls.go b/vendor/oras.land/oras-go/pkg/auth/docker/login_tls.go index cb92df8187d..7b5c2f8ba9d 100644 --- a/vendor/oras.land/oras-go/pkg/auth/docker/login_tls.go +++ b/vendor/oras.land/oras-go/pkg/auth/docker/login_tls.go @@ -59,7 +59,7 @@ func (lcs loginCredentialStore) SetRefreshToken(u *url.URL, service, token strin // loginWithTLS tries to login to the v2 registry server. // A custom tls.Config is used to override the default TLS configuration of the different registry endpoints. // The tls.Config is created using the provided certificate, certificate key and certificate authority. -func (c *Client) loginWithTLS(ctx context.Context, service registry.Service, certFile, keyFile, caFile string, authConfig *types.AuthConfig, userAgent string) (string, string, error) { +func (c *Client) loginWithTLS(ctx context.Context, service *registry.Service, certFile, keyFile, caFile string, authConfig *types.AuthConfig, userAgent string) (string, string, error) { tlsConfig, err := tlsconfig.Client(tlsconfig.Options{CAFile: caFile, CertFile: certFile, KeyFile: keyFile}) if err != nil { return "", "", err @@ -91,7 +91,7 @@ func (c *Client) loginWithTLS(ctx context.Context, service registry.Service, cer } // getEndpoints returns the endpoints for the given hostname. -func (c *Client) getEndpoints(address string, service registry.Service) ([]registry.APIEndpoint, error) { +func (c *Client) getEndpoints(address string, service *registry.Service) ([]registry.APIEndpoint, error) { var registryHostName = IndexHostname if address != "" { @@ -178,7 +178,7 @@ func newTransport(tlsConfig *tls.Config) *http.Transport { } func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, error) { - challengeManager, _, err := registry.PingV2Registry(endpoint, authTransport) + challengeManager, err := registry.PingV2Registry(endpoint, authTransport) if err != nil { return nil, err } diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go index c55070ae637..541e6a5aa14 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go @@ -29,6 +29,9 @@ import ( "google.golang.org/grpc" "k8s.io/klog/v2" + + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics" + commonmetrics "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics" "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" ) @@ -115,6 +118,8 @@ func (cm *connectionManager) closeAll() { // grpcTunnel implements Tunnel type grpcTunnel struct { stream client.ProxyService_ProxyClient + sendLock sync.Mutex + recvLock sync.Mutex clientConn clientConn pendingDial pendingDialManager conns connectionManager @@ -127,10 +132,18 @@ type grpcTunnel struct { // serving. done chan struct{} + // started is an atomic bool represented as a 0 or 1, and set to true when a single-use tunnel has been started (dialed). + // started should only be accessed through atomic methods. + // TODO: switch this to an atomic.Bool once the client is exclusively buit with go1.19+ + started uint32 + // closing is an atomic bool represented as a 0 or 1, and set to true when the tunnel is being closed. // closing should only be accessed through atomic methods. // TODO: switch this to an atomic.Bool once the client is exclusively buit with go1.19+ closing uint32 + + // Stores the current metrics.ClientConnectionStatus + prevStatus atomic.Value } type clientConn interface { @@ -139,6 +152,11 @@ type clientConn interface { var _ clientConn = &grpc.ClientConn{} +var ( + // Expose metrics for client to register. + Metrics = metrics.Metrics +) + // CreateSingleUseGrpcTunnel creates a Tunnel to dial to a remote server through a // gRPC based proxy service. // Currently, a single tunnel supports a single connection, and the tunnel is closed when the connection is terminated @@ -177,14 +195,45 @@ func CreateSingleUseGrpcTunnelWithContext(createCtx, tunnelCtx context.Context, } func newUnstartedTunnel(stream client.ProxyService_ProxyClient, c clientConn) *grpcTunnel { - return &grpcTunnel{ + t := grpcTunnel{ stream: stream, clientConn: c, pendingDial: pendingDialManager{pendingDials: make(map[int64]pendingDial)}, conns: connectionManager{conns: make(map[int64]*conn)}, readTimeoutSeconds: 10, done: make(chan struct{}), + started: 0, } + s := metrics.ClientConnectionStatusCreated + t.prevStatus.Store(s) + metrics.Metrics.GetClientConnectionsMetric().WithLabelValues(string(s)).Inc() + return &t +} + +func (t *grpcTunnel) updateMetric(status metrics.ClientConnectionStatus) { + select { + case <-t.Done(): + return + default: + } + + prevStatus := t.prevStatus.Swap(status).(metrics.ClientConnectionStatus) + + m := metrics.Metrics.GetClientConnectionsMetric() + m.WithLabelValues(string(prevStatus)).Dec() + m.WithLabelValues(string(status)).Inc() +} + +// closeMetric should be called exactly once to finalize client_connections metric. +func (t *grpcTunnel) closeMetric() { + select { + case <-t.Done(): + return + default: + } + prevStatus := t.prevStatus.Load().(metrics.ClientConnectionStatus) + + metrics.Metrics.GetClientConnectionsMetric().WithLabelValues(string(prevStatus)).Dec() } func (t *grpcTunnel) serve(tunnelCtx context.Context) { @@ -196,19 +245,26 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { // close any channels remaining for these connections. t.conns.closeAll() + t.closeMetric() + close(t.done) }() for { - pkt, err := t.stream.Recv() - if err == io.EOF || t.isClosing() { + pkt, err := t.Recv() + if err == io.EOF { return } + isClosing := t.isClosing() if err != nil || pkt == nil { - klog.ErrorS(err, "stream read failure") + if !isClosing { + klog.ErrorS(err, "stream read failure") + } + return + } + if isClosing { return } - klog.V(5).InfoS("[tracing] recv packet", "type", pkt.Type) switch pkt.Type { @@ -222,13 +278,19 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { // 2. grpcTunnel.DialContext() returned early due to a dial timeout or the client canceling the context // // In either scenario, we should return here and close the tunnel as it is no longer needed. - klog.V(1).InfoS("DialResp not recognized; dropped", "connectionID", resp.ConnectID, "dialID", resp.Random) + kvs := []interface{}{"dialID", resp.Random, "connectID", resp.ConnectID} + if resp.Error != "" { + kvs = append(kvs, "error", resp.Error) + } + klog.V(1).InfoS("DialResp not recognized; dropped", kvs...) return } result := dialResult{connid: resp.ConnectID} if resp.Error != "" { - result.err = &dialFailure{resp.Error, DialFailureEndpoint} + result.err = &dialFailure{resp.Error, metrics.DialFailureEndpoint} + } else { + t.updateMetric(metrics.ClientConnectionStatusOk) } select { // try to send to the result channel @@ -263,7 +325,7 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { klog.V(1).InfoS("DIAL_CLS after dial finished", "dialID", resp.Random) } else { result := dialResult{ - err: &dialFailure{"dial closed", DialFailureDialClosed}, + err: &dialFailure{"dial closed", metrics.DialFailureDialClosed}, } select { case pendingDial.resultCh <- result: @@ -278,11 +340,23 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { case client.PacketType_DATA: resp := pkt.GetData() + if resp.ConnectID == 0 { + klog.ErrorS(nil, "Received packet missing ConnectID", "packetType", "DATA") + continue + } // TODO: flow control conn, ok := t.conns.get(resp.ConnectID) if !ok { - klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID) + klog.ErrorS(nil, "Connection not recognized", "connectionID", resp.ConnectID, "packetType", "DATA") + t.Send(&client.Packet{ + Type: client.PacketType_CLOSE_REQ, + Payload: &client.Packet_CloseRequest{ + CloseRequest: &client.CloseRequest{ + ConnectID: resp.ConnectID, + }, + }, + }) continue } timer := time.NewTimer((time.Duration)(t.readTimeoutSeconds) * time.Second) @@ -301,7 +375,7 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { conn, ok := t.conns.get(resp.ConnectID) if !ok { - klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID) + klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID, "packetType", "CLOSE_RSP") continue } close(conn.readCh) @@ -316,6 +390,20 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { // Dial connects to the address on the named network, similar to // what net.Dial does. The only supported protocol is tcp. func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address string) (net.Conn, error) { + conn, err := t.dialContext(requestCtx, protocol, address) + if err != nil { + _, reason := GetDialFailureReason(err) + metrics.Metrics.ObserveDialFailure(reason) + } + return conn, err +} + +func (t *grpcTunnel) dialContext(requestCtx context.Context, protocol, address string) (net.Conn, error) { + prevStarted := atomic.SwapUint32(&t.started, 1) + if prevStarted != 0 { + return nil, &dialFailure{"single-use dialer already dialed", metrics.DialFailureAlreadyStarted} + } + select { case <-t.done: return nil, errors.New("tunnel is closed") @@ -326,6 +414,8 @@ func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address s return nil, errors.New("protocol not supported") } + t.updateMetric(metrics.ClientConnectionStatusDialing) + random := rand.Int63() /* #nosec G404 */ // This channel is closed once we're returning and no longer waiting on resultCh @@ -350,7 +440,7 @@ func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address s } klog.V(5).InfoS("[tracing] send packet", "type", req.Type) - err := t.stream.Send(req) + err := t.Send(req) if err != nil { return nil, err } @@ -358,7 +448,7 @@ func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address s klog.V(5).Infoln("DIAL_REQ sent to proxy server") c := &conn{ - stream: t.stream, + tunnel: t, random: random, closeTunnel: t.closeTunnel, } @@ -375,14 +465,14 @@ func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address s case <-time.After(30 * time.Second): klog.V(5).InfoS("Timed out waiting for DialResp", "dialID", random) go t.closeDial(random) - return nil, &dialFailure{"dial timeout, backstop", DialFailureTimeout} + return nil, &dialFailure{"dial timeout, backstop", metrics.DialFailureTimeout} case <-requestCtx.Done(): klog.V(5).InfoS("Context canceled waiting for DialResp", "ctxErr", requestCtx.Err(), "dialID", random) go t.closeDial(random) - return nil, &dialFailure{"dial timeout, context", DialFailureContext} + return nil, &dialFailure{"dial timeout, context", metrics.DialFailureContext} case <-t.done: klog.V(5).InfoS("Tunnel closed while waiting for DialResp", "dialID", random) - return nil, &dialFailure{"tunnel closed", DialFailureTunnelClosed} + return nil, &dialFailure{"tunnel closed", metrics.DialFailureTunnelClosed} } return c, nil @@ -402,7 +492,7 @@ func (t *grpcTunnel) closeDial(dialID int64) { }, }, } - if err := t.stream.Send(req); err != nil { + if err := t.Send(req); err != nil { klog.V(5).InfoS("Failed to send DIAL_CLS", "err", err, "dialID", dialID) } t.closeTunnel() @@ -417,38 +507,48 @@ func (t *grpcTunnel) isClosing() bool { return atomic.LoadUint32(&t.closing) != 0 } -func GetDialFailureReason(err error) (isDialFailure bool, reason DialFailureReason) { +func (t *grpcTunnel) Send(pkt *client.Packet) error { + t.sendLock.Lock() + defer t.sendLock.Unlock() + + const segment = commonmetrics.SegmentFromClient + metrics.Metrics.ObservePacket(segment, pkt.Type) + err := t.stream.Send(pkt) + if err != nil && err != io.EOF { + metrics.Metrics.ObserveStreamError(segment, err, pkt.Type) + } + return err +} + +func (t *grpcTunnel) Recv() (*client.Packet, error) { + t.recvLock.Lock() + defer t.recvLock.Unlock() + + const segment = commonmetrics.SegmentToClient + pkt, err := t.stream.Recv() + if err != nil { + if err != io.EOF { + metrics.Metrics.ObserveStreamErrorNoPacket(segment, err) + } + return nil, err + } + metrics.Metrics.ObservePacket(segment, pkt.Type) + return pkt, nil +} + +func GetDialFailureReason(err error) (isDialFailure bool, reason metrics.DialFailureReason) { var df *dialFailure if errors.As(err, &df) { return true, df.reason } - return false, DialFailureUnknown + return false, metrics.DialFailureUnknown } type dialFailure struct { msg string - reason DialFailureReason + reason metrics.DialFailureReason } func (df *dialFailure) Error() string { return df.msg } - -type DialFailureReason string - -const ( - DialFailureUnknown DialFailureReason = "unknown" - // DialFailureTimeout indicates the hard 30 second timeout was hit. - DialFailureTimeout DialFailureReason = "timeout" - // DialFailureContext indicates that the context was cancelled or reached it's deadline before - // the dial response was returned. - DialFailureContext DialFailureReason = "context" - // DialFailureEndpoint indicates that the konnectivity-agent was unable to reach the backend endpoint. - DialFailureEndpoint DialFailureReason = "endpoint" - // DialFailureDialClosed indicates that the client received a CloseDial response, indicating the - // connection was closed before the dial could complete. - DialFailureDialClosed DialFailureReason = "dialclosed" - // DialFailureTunnelClosed indicates that the client connection was closed before the dial could - // complete. - DialFailureTunnelClosed DialFailureReason = "tunnelclosed" -) diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go index f76b1e37a47..f4d3f788652 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go @@ -23,6 +23,7 @@ import ( "time" "k8s.io/klog/v2" + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" ) @@ -35,7 +36,7 @@ var errConnCloseTimeout = errors.New("close timeout") // conn is an implementation of net.Conn, where the data is transported // over an established tunnel defined by a gRPC service ProxyService. type conn struct { - stream client.ProxyService_ProxyClient + tunnel *grpcTunnel connID int64 random int64 readCh chan []byte @@ -62,7 +63,7 @@ func (c *conn) Write(data []byte) (n int, err error) { klog.V(5).InfoS("[tracing] send req", "type", req.Type) - err = c.stream.Send(req) + err = c.tunnel.Send(req) if err != nil { return 0, err } @@ -147,7 +148,7 @@ func (c *conn) Close() error { klog.V(5).InfoS("[tracing] send req", "type", req.Type) - if err := c.stream.Send(req); err != nil { + if err := c.tunnel.Send(req); err != nil { return err } diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go new file mode 100644 index 00000000000..ce942e3ebb8 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go @@ -0,0 +1,164 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "sync" + + "github.com/prometheus/client_golang/prometheus" + + commonmetrics "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics" + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" +) + +const ( + Namespace = "konnectivity_network_proxy" + Subsystem = "client" +) + +var ( + // Metrics provides access to all client metrics. The client + // application is responsible for registering (via Metrics.RegisterMetrics). + Metrics = newMetrics() +) + +// ClientMetrics includes all the metrics of the konnectivity-client. +type ClientMetrics struct { + registerOnce sync.Once + streamPackets *prometheus.CounterVec + streamErrors *prometheus.CounterVec + dialFailures *prometheus.CounterVec + clientConns *prometheus.GaugeVec +} + +type DialFailureReason string + +const ( + DialFailureUnknown DialFailureReason = "unknown" + // DialFailureTimeout indicates the hard 30 second timeout was hit. + DialFailureTimeout DialFailureReason = "timeout" + // DialFailureContext indicates that the context was cancelled or reached it's deadline before + // the dial response was returned. + DialFailureContext DialFailureReason = "context" + // DialFailureEndpoint indicates that the konnectivity-agent was unable to reach the backend endpoint. + DialFailureEndpoint DialFailureReason = "endpoint" + // DialFailureDialClosed indicates that the client received a CloseDial response, indicating the + // connection was closed before the dial could complete. + DialFailureDialClosed DialFailureReason = "dialclosed" + // DialFailureTunnelClosed indicates that the client connection was closed before the dial could + // complete. + DialFailureTunnelClosed DialFailureReason = "tunnelclosed" + // DialFailureAlreadyStarted indicates that a single-use tunnel dialer was already used once. + DialFailureAlreadyStarted DialFailureReason = "tunnelstarted" +) + +type ClientConnectionStatus string + +const ( + // The connection is created but has not yet been dialed. + ClientConnectionStatusCreated ClientConnectionStatus = "created" + // The connection is pending dial response. + ClientConnectionStatusDialing ClientConnectionStatus = "dialing" + // The connection is established. + ClientConnectionStatusOk ClientConnectionStatus = "ok" + // The connection is closing. + ClientConnectionStatusClosing ClientConnectionStatus = "closing" +) + +func newMetrics() *ClientMetrics { + // The denominator (total dials started) for both + // dial_failure_total and dial_duration_seconds is the + // stream_packets_total (common metric), where segment is + // "from_client" and packet_type is "DIAL_REQ". + dialFailures := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: Namespace, + Subsystem: Subsystem, + Name: "dial_failure_total", + Help: "Number of dial failures observed, by reason (example: remote endpoint error)", + }, + []string{ + "reason", + }, + ) + clientConns := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: Subsystem, + Name: "client_connections", + Help: "Number of open client connections, by status (Example: dialing)", + }, + []string{ + "status", + }, + ) + return &ClientMetrics{ + streamPackets: commonmetrics.MakeStreamPacketsTotalMetric(Namespace, Subsystem), + streamErrors: commonmetrics.MakeStreamErrorsTotalMetric(Namespace, Subsystem), + dialFailures: dialFailures, + clientConns: clientConns, + } +} + +// RegisterMetrics registers all metrics with the client application. +func (c *ClientMetrics) RegisterMetrics(r prometheus.Registerer) { + c.registerOnce.Do(func() { + r.MustRegister(c.streamPackets) + r.MustRegister(c.streamErrors) + r.MustRegister(c.dialFailures) + r.MustRegister(c.clientConns) + }) +} + +// LegacyRegisterMetrics registers all metrics via MustRegister func. +// TODO: remove this once https://github.com/kubernetes/kubernetes/pull/114293 is available. +func (c *ClientMetrics) LegacyRegisterMetrics(mustRegisterFn func(...prometheus.Collector)) { + c.registerOnce.Do(func() { + mustRegisterFn(c.streamPackets) + mustRegisterFn(c.streamErrors) + mustRegisterFn(c.dialFailures) + mustRegisterFn(c.clientConns) + }) +} + +// Reset resets the metrics. +func (c *ClientMetrics) Reset() { + c.streamPackets.Reset() + c.streamErrors.Reset() + c.dialFailures.Reset() + c.clientConns.Reset() +} + +func (c *ClientMetrics) ObserveDialFailure(reason DialFailureReason) { + c.dialFailures.WithLabelValues(string(reason)).Inc() +} + +func (c *ClientMetrics) GetClientConnectionsMetric() *prometheus.GaugeVec { + return c.clientConns +} + +func (c *ClientMetrics) ObservePacket(segment commonmetrics.Segment, packetType client.PacketType) { + commonmetrics.ObservePacket(c.streamPackets, segment, packetType) +} + +func (c *ClientMetrics) ObserveStreamErrorNoPacket(segment commonmetrics.Segment, err error) { + commonmetrics.ObserveStreamErrorNoPacket(c.streamErrors, segment, err) +} + +func (c *ClientMetrics) ObserveStreamError(segment commonmetrics.Segment, err error, packetType client.PacketType) { + commonmetrics.ObserveStreamError(c.streamErrors, segment, err, packetType) +} diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics/metrics.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics/metrics.go new file mode 100644 index 00000000000..e8619f47202 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics/metrics.go @@ -0,0 +1,78 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package metrics provides metric definitions and helpers used +// across konnectivity client, server, and agent. +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc/status" + + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" +) + +// Segment identifies one of four tunnel segments (e.g. from server to agent). +type Segment string + +const ( + // SegmentFromClient indicates a packet from client to server. + SegmentFromClient Segment = "from_client" + // SegmentToClient indicates a packet from server to client. + SegmentToClient Segment = "to_client" + // SegmentFromAgent indicates a packet from agent to server. + SegmentFromAgent Segment = "from_agent" + // SegmentToAgent indicates a packet from server to agent. + SegmentToAgent Segment = "to_agent" +) + +func MakeStreamPacketsTotalMetric(namespace, subsystem string) *prometheus.CounterVec { + return prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "stream_packets_total", + Help: "Count of packets processed, by segment and packet type (example: from_client, DIAL_REQ)", + }, + []string{"segment", "packet_type"}, + ) +} + +func MakeStreamErrorsTotalMetric(namespace, subsystem string) *prometheus.CounterVec { + return prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "stream_errors_total", + Help: "Count of gRPC stream errors, by segment, grpc Code, packet type. (example: from_agent, Code.Unavailable, DIAL_RSP)", + }, + []string{"segment", "code", "packet_type"}, + ) +} + +func ObservePacket(m *prometheus.CounterVec, segment Segment, packetType client.PacketType) { + m.WithLabelValues(string(segment), packetType.String()).Inc() +} + +func ObserveStreamErrorNoPacket(m *prometheus.CounterVec, segment Segment, err error) { + code := status.Code(err) + m.WithLabelValues(string(segment), code.String(), "Unknown").Inc() +} + +func ObserveStreamError(m *prometheus.CounterVec, segment Segment, err error, packetType client.PacketType) { + code := status.Code(err) + m.WithLabelValues(string(segment), code.String(), packetType.String()).Inc() +} diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go index 59a797df4cf..6af92b448b0 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go @@ -1,43 +1,38 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 +// Copyright The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.12.4 // source: konnectivity-client/proto/client/client.proto package client import ( - context "context" - fmt "fmt" - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type PacketType int32 @@ -50,99 +45,156 @@ const ( PacketType_DIAL_CLS PacketType = 5 ) -var PacketType_name = map[int32]string{ - 0: "DIAL_REQ", - 1: "DIAL_RSP", - 2: "CLOSE_REQ", - 3: "CLOSE_RSP", - 4: "DATA", - 5: "DIAL_CLS", -} +// Enum value maps for PacketType. +var ( + PacketType_name = map[int32]string{ + 0: "DIAL_REQ", + 1: "DIAL_RSP", + 2: "CLOSE_REQ", + 3: "CLOSE_RSP", + 4: "DATA", + 5: "DIAL_CLS", + } + PacketType_value = map[string]int32{ + "DIAL_REQ": 0, + "DIAL_RSP": 1, + "CLOSE_REQ": 2, + "CLOSE_RSP": 3, + "DATA": 4, + "DIAL_CLS": 5, + } +) -var PacketType_value = map[string]int32{ - "DIAL_REQ": 0, - "DIAL_RSP": 1, - "CLOSE_REQ": 2, - "CLOSE_RSP": 3, - "DATA": 4, - "DIAL_CLS": 5, +func (x PacketType) Enum() *PacketType { + p := new(PacketType) + *p = x + return p } func (x PacketType) String() string { - return proto.EnumName(PacketType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (PacketType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{0} +func (PacketType) Descriptor() protoreflect.EnumDescriptor { + return file_konnectivity_client_proto_client_client_proto_enumTypes[0].Descriptor() } -type Error int32 - -const ( - Error_EOF Error = 0 -) - -var Error_name = map[int32]string{ - 0: "EOF", -} - -var Error_value = map[string]int32{ - "EOF": 0, +func (PacketType) Type() protoreflect.EnumType { + return &file_konnectivity_client_proto_client_client_proto_enumTypes[0] } -func (x Error) String() string { - return proto.EnumName(Error_name, int32(x)) +func (x PacketType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (Error) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{1} +// Deprecated: Use PacketType.Descriptor instead. +func (PacketType) EnumDescriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{0} } type Packet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Type PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=PacketType" json:"type,omitempty"` - // Types that are valid to be assigned to Payload: + // Types that are assignable to Payload: + // // *Packet_DialRequest // *Packet_DialResponse // *Packet_Data // *Packet_CloseRequest // *Packet_CloseResponse // *Packet_CloseDial - Payload isPacket_Payload `protobuf_oneof:"payload"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Payload isPacket_Payload `protobuf_oneof:"payload"` +} + +func (x *Packet) Reset() { + *x = Packet{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Packet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Packet) ProtoMessage() {} + +func (x *Packet) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -func (m *Packet) Reset() { *m = Packet{} } -func (m *Packet) String() string { return proto.CompactTextString(m) } -func (*Packet) ProtoMessage() {} +// Deprecated: Use Packet.ProtoReflect.Descriptor instead. func (*Packet) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{0} + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{0} } -func (m *Packet) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Packet.Unmarshal(m, b) +func (x *Packet) GetType() PacketType { + if x != nil { + return x.Type + } + return PacketType_DIAL_REQ } -func (m *Packet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Packet.Marshal(b, m, deterministic) + +func (m *Packet) GetPayload() isPacket_Payload { + if m != nil { + return m.Payload + } + return nil } -func (m *Packet) XXX_Merge(src proto.Message) { - xxx_messageInfo_Packet.Merge(m, src) + +func (x *Packet) GetDialRequest() *DialRequest { + if x, ok := x.GetPayload().(*Packet_DialRequest); ok { + return x.DialRequest + } + return nil } -func (m *Packet) XXX_Size() int { - return xxx_messageInfo_Packet.Size(m) + +func (x *Packet) GetDialResponse() *DialResponse { + if x, ok := x.GetPayload().(*Packet_DialResponse); ok { + return x.DialResponse + } + return nil } -func (m *Packet) XXX_DiscardUnknown() { - xxx_messageInfo_Packet.DiscardUnknown(m) + +func (x *Packet) GetData() *Data { + if x, ok := x.GetPayload().(*Packet_Data); ok { + return x.Data + } + return nil } -var xxx_messageInfo_Packet proto.InternalMessageInfo +func (x *Packet) GetCloseRequest() *CloseRequest { + if x, ok := x.GetPayload().(*Packet_CloseRequest); ok { + return x.CloseRequest + } + return nil +} -func (m *Packet) GetType() PacketType { - if m != nil { - return m.Type +func (x *Packet) GetCloseResponse() *CloseResponse { + if x, ok := x.GetPayload().(*Packet_CloseResponse); ok { + return x.CloseResponse } - return PacketType_DIAL_REQ + return nil +} + +func (x *Packet) GetCloseDial() *CloseDial { + if x, ok := x.GetPayload().(*Packet_CloseDial); ok { + return x.CloseDial + } + return nil } type isPacket_Payload interface { @@ -185,530 +237,584 @@ func (*Packet_CloseResponse) isPacket_Payload() {} func (*Packet_CloseDial) isPacket_Payload() {} -func (m *Packet) GetPayload() isPacket_Payload { - if m != nil { - return m.Payload - } - return nil -} - -func (m *Packet) GetDialRequest() *DialRequest { - if x, ok := m.GetPayload().(*Packet_DialRequest); ok { - return x.DialRequest - } - return nil -} - -func (m *Packet) GetDialResponse() *DialResponse { - if x, ok := m.GetPayload().(*Packet_DialResponse); ok { - return x.DialResponse - } - return nil -} +type DialRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Packet) GetData() *Data { - if x, ok := m.GetPayload().(*Packet_Data); ok { - return x.Data - } - return nil + // tcp or udp? + Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` + // node:port + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + // random id for client, maybe should be longer + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` } -func (m *Packet) GetCloseRequest() *CloseRequest { - if x, ok := m.GetPayload().(*Packet_CloseRequest); ok { - return x.CloseRequest +func (x *DialRequest) Reset() { + *x = DialRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (m *Packet) GetCloseResponse() *CloseResponse { - if x, ok := m.GetPayload().(*Packet_CloseResponse); ok { - return x.CloseResponse - } - return nil +func (x *DialRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Packet) GetCloseDial() *CloseDial { - if x, ok := m.GetPayload().(*Packet_CloseDial); ok { - return x.CloseDial - } - return nil -} +func (*DialRequest) ProtoMessage() {} -// XXX_OneofWrappers is for the internal use of the proto package. -func (*Packet) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*Packet_DialRequest)(nil), - (*Packet_DialResponse)(nil), - (*Packet_Data)(nil), - (*Packet_CloseRequest)(nil), - (*Packet_CloseResponse)(nil), - (*Packet_CloseDial)(nil), +func (x *DialRequest) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } + return mi.MessageOf(x) } -type DialRequest struct { - // tcp or udp? - Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` - // node:port - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - // random id for client, maybe should be longer - Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DialRequest) Reset() { *m = DialRequest{} } -func (m *DialRequest) String() string { return proto.CompactTextString(m) } -func (*DialRequest) ProtoMessage() {} +// Deprecated: Use DialRequest.ProtoReflect.Descriptor instead. func (*DialRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{1} -} - -func (m *DialRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DialRequest.Unmarshal(m, b) -} -func (m *DialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DialRequest.Marshal(b, m, deterministic) -} -func (m *DialRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DialRequest.Merge(m, src) -} -func (m *DialRequest) XXX_Size() int { - return xxx_messageInfo_DialRequest.Size(m) -} -func (m *DialRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DialRequest.DiscardUnknown(m) + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{1} } -var xxx_messageInfo_DialRequest proto.InternalMessageInfo - -func (m *DialRequest) GetProtocol() string { - if m != nil { - return m.Protocol +func (x *DialRequest) GetProtocol() string { + if x != nil { + return x.Protocol } return "" } -func (m *DialRequest) GetAddress() string { - if m != nil { - return m.Address +func (x *DialRequest) GetAddress() string { + if x != nil { + return x.Address } return "" } -func (m *DialRequest) GetRandom() int64 { - if m != nil { - return m.Random +func (x *DialRequest) GetRandom() int64 { + if x != nil { + return x.Random } return 0 } type DialResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // error failed reason; enum? Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` // connectID indicates the identifier of the connection ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` // random copied from DialRequest - Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` } -func (m *DialResponse) Reset() { *m = DialResponse{} } -func (m *DialResponse) String() string { return proto.CompactTextString(m) } -func (*DialResponse) ProtoMessage() {} -func (*DialResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{2} +func (x *DialResponse) Reset() { + *x = DialResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *DialResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DialResponse.Unmarshal(m, b) -} -func (m *DialResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DialResponse.Marshal(b, m, deterministic) -} -func (m *DialResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DialResponse.Merge(m, src) -} -func (m *DialResponse) XXX_Size() int { - return xxx_messageInfo_DialResponse.Size(m) +func (x *DialResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *DialResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DialResponse.DiscardUnknown(m) + +func (*DialResponse) ProtoMessage() {} + +func (x *DialResponse) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_DialResponse proto.InternalMessageInfo +// Deprecated: Use DialResponse.ProtoReflect.Descriptor instead. +func (*DialResponse) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{2} +} -func (m *DialResponse) GetError() string { - if m != nil { - return m.Error +func (x *DialResponse) GetError() string { + if x != nil { + return x.Error } return "" } -func (m *DialResponse) GetConnectID() int64 { - if m != nil { - return m.ConnectID +func (x *DialResponse) GetConnectID() int64 { + if x != nil { + return x.ConnectID } return 0 } -func (m *DialResponse) GetRandom() int64 { - if m != nil { - return m.Random +func (x *DialResponse) GetRandom() int64 { + if x != nil { + return x.Random } return 0 } type CloseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // connectID of the stream to close - ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` } -func (m *CloseRequest) Reset() { *m = CloseRequest{} } -func (m *CloseRequest) String() string { return proto.CompactTextString(m) } -func (*CloseRequest) ProtoMessage() {} -func (*CloseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{3} +func (x *CloseRequest) Reset() { + *x = CloseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *CloseRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseRequest.Unmarshal(m, b) -} -func (m *CloseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseRequest.Marshal(b, m, deterministic) -} -func (m *CloseRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseRequest.Merge(m, src) +func (x *CloseRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *CloseRequest) XXX_Size() int { - return xxx_messageInfo_CloseRequest.Size(m) -} -func (m *CloseRequest) XXX_DiscardUnknown() { - xxx_messageInfo_CloseRequest.DiscardUnknown(m) + +func (*CloseRequest) ProtoMessage() {} + +func (x *CloseRequest) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_CloseRequest proto.InternalMessageInfo +// Deprecated: Use CloseRequest.ProtoReflect.Descriptor instead. +func (*CloseRequest) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{3} +} -func (m *CloseRequest) GetConnectID() int64 { - if m != nil { - return m.ConnectID +func (x *CloseRequest) GetConnectID() int64 { + if x != nil { + return x.ConnectID } return 0 } type CloseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // error message Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` // connectID indicates the identifier of the connection - ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` } -func (m *CloseResponse) Reset() { *m = CloseResponse{} } -func (m *CloseResponse) String() string { return proto.CompactTextString(m) } -func (*CloseResponse) ProtoMessage() {} -func (*CloseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{4} +func (x *CloseResponse) Reset() { + *x = CloseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *CloseResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseResponse.Unmarshal(m, b) +func (x *CloseResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *CloseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseResponse.Marshal(b, m, deterministic) -} -func (m *CloseResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseResponse.Merge(m, src) -} -func (m *CloseResponse) XXX_Size() int { - return xxx_messageInfo_CloseResponse.Size(m) -} -func (m *CloseResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CloseResponse.DiscardUnknown(m) + +func (*CloseResponse) ProtoMessage() {} + +func (x *CloseResponse) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_CloseResponse proto.InternalMessageInfo +// Deprecated: Use CloseResponse.ProtoReflect.Descriptor instead. +func (*CloseResponse) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{4} +} -func (m *CloseResponse) GetError() string { - if m != nil { - return m.Error +func (x *CloseResponse) GetError() string { + if x != nil { + return x.Error } return "" } -func (m *CloseResponse) GetConnectID() int64 { - if m != nil { - return m.ConnectID +func (x *CloseResponse) GetConnectID() int64 { + if x != nil { + return x.ConnectID } return 0 } type CloseDial struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // random id of the DialRequest - Random int64 `protobuf:"varint,1,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Random int64 `protobuf:"varint,1,opt,name=random,proto3" json:"random,omitempty"` } -func (m *CloseDial) Reset() { *m = CloseDial{} } -func (m *CloseDial) String() string { return proto.CompactTextString(m) } -func (*CloseDial) ProtoMessage() {} -func (*CloseDial) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{5} +func (x *CloseDial) Reset() { + *x = CloseDial{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *CloseDial) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseDial.Unmarshal(m, b) -} -func (m *CloseDial) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseDial.Marshal(b, m, deterministic) +func (x *CloseDial) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *CloseDial) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseDial.Merge(m, src) -} -func (m *CloseDial) XXX_Size() int { - return xxx_messageInfo_CloseDial.Size(m) -} -func (m *CloseDial) XXX_DiscardUnknown() { - xxx_messageInfo_CloseDial.DiscardUnknown(m) + +func (*CloseDial) ProtoMessage() {} + +func (x *CloseDial) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_CloseDial proto.InternalMessageInfo +// Deprecated: Use CloseDial.ProtoReflect.Descriptor instead. +func (*CloseDial) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{5} +} -func (m *CloseDial) GetRandom() int64 { - if m != nil { - return m.Random +func (x *CloseDial) GetRandom() int64 { + if x != nil { + return x.Random } return 0 } type Data struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + // connectID to connect to ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` // error message if error happens Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` // stream data - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` } -func (m *Data) Reset() { *m = Data{} } -func (m *Data) String() string { return proto.CompactTextString(m) } -func (*Data) ProtoMessage() {} -func (*Data) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{6} +func (x *Data) Reset() { + *x = Data{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Data) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Data.Unmarshal(m, b) +func (x *Data) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Data.Marshal(b, m, deterministic) -} -func (m *Data) XXX_Merge(src proto.Message) { - xxx_messageInfo_Data.Merge(m, src) -} -func (m *Data) XXX_Size() int { - return xxx_messageInfo_Data.Size(m) -} -func (m *Data) XXX_DiscardUnknown() { - xxx_messageInfo_Data.DiscardUnknown(m) + +func (*Data) ProtoMessage() {} + +func (x *Data) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Data proto.InternalMessageInfo +// Deprecated: Use Data.ProtoReflect.Descriptor instead. +func (*Data) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{6} +} -func (m *Data) GetConnectID() int64 { - if m != nil { - return m.ConnectID +func (x *Data) GetConnectID() int64 { + if x != nil { + return x.ConnectID } return 0 } -func (m *Data) GetError() string { - if m != nil { - return m.Error +func (x *Data) GetError() string { + if x != nil { + return x.Error } return "" } -func (m *Data) GetData() []byte { - if m != nil { - return m.Data +func (x *Data) GetData() []byte { + if x != nil { + return x.Data } return nil } -func init() { - proto.RegisterEnum("PacketType", PacketType_name, PacketType_value) - proto.RegisterEnum("Error", Error_name, Error_value) - proto.RegisterType((*Packet)(nil), "Packet") - proto.RegisterType((*DialRequest)(nil), "DialRequest") - proto.RegisterType((*DialResponse)(nil), "DialResponse") - proto.RegisterType((*CloseRequest)(nil), "CloseRequest") - proto.RegisterType((*CloseResponse)(nil), "CloseResponse") - proto.RegisterType((*CloseDial)(nil), "CloseDial") - proto.RegisterType((*Data)(nil), "Data") -} - -func init() { - proto.RegisterFile("konnectivity-client/proto/client/client.proto", fileDescriptor_fec4258d9ecd175d) -} - -var fileDescriptor_fec4258d9ecd175d = []byte{ - // 505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x51, 0x8b, 0xd3, 0x40, - 0x18, 0x4c, 0xda, 0xa4, 0x6d, 0xbe, 0xa6, 0x47, 0x58, 0x44, 0xc2, 0x29, 0xdc, 0x11, 0x5f, 0x4a, - 0xb1, 0xe9, 0xd1, 0x03, 0xf1, 0xb5, 0xd7, 0xf4, 0xe8, 0x41, 0xf1, 0xea, 0xf6, 0x9e, 0x4e, 0x50, - 0xd6, 0x64, 0x91, 0xd0, 0x98, 0x8d, 0xbb, 0x6b, 0x35, 0x3f, 0xd3, 0x7f, 0x24, 0xd9, 0xa4, 0x4d, - 0x22, 0xa8, 0x70, 0x4f, 0xed, 0xcc, 0x7e, 0x33, 0x3b, 0x19, 0xbe, 0x85, 0xe9, 0x9e, 0xa5, 0x29, - 0x0d, 0x65, 0x7c, 0x88, 0x65, 0x3e, 0x0d, 0x93, 0x98, 0xa6, 0x72, 0x96, 0x71, 0x26, 0xd9, 0xac, - 0x02, 0xe5, 0x8f, 0xaf, 0x38, 0xef, 0x57, 0x07, 0x7a, 0x5b, 0x12, 0xee, 0xa9, 0x44, 0x17, 0x60, - 0xc8, 0x3c, 0xa3, 0xae, 0x7e, 0xa9, 0x8f, 0xcf, 0xe6, 0x43, 0xbf, 0xa4, 0x1f, 0xf2, 0x8c, 0x62, - 0x75, 0x80, 0xae, 0x60, 0x18, 0xc5, 0x24, 0xc1, 0xf4, 0xdb, 0x77, 0x2a, 0xa4, 0xdb, 0xb9, 0xd4, - 0xc7, 0xc3, 0xb9, 0xed, 0x07, 0x35, 0xb7, 0xd6, 0x70, 0x73, 0x04, 0x5d, 0x83, 0x5d, 0x42, 0x91, - 0xb1, 0x54, 0x50, 0xb7, 0xab, 0x24, 0xa3, 0x4a, 0x52, 0x92, 0x6b, 0x0d, 0xb7, 0x86, 0xd0, 0x0b, - 0x30, 0x22, 0x22, 0x89, 0x6b, 0xa8, 0x61, 0xd3, 0x0f, 0x88, 0x24, 0x6b, 0x0d, 0x2b, 0xb2, 0x70, - 0x0c, 0x13, 0x26, 0xe8, 0x31, 0x84, 0x59, 0x39, 0x2e, 0x1b, 0x64, 0xe1, 0xd8, 0x1c, 0x42, 0x6f, - 0x60, 0x54, 0xe1, 0x2a, 0x47, 0x4f, 0xa9, 0xce, 0x8e, 0xaa, 0x53, 0x90, 0xf6, 0x18, 0x9a, 0x80, - 0xa5, 0x88, 0x22, 0xae, 0xdb, 0x57, 0x1a, 0x28, 0x35, 0x05, 0xb3, 0xd6, 0x70, 0x7d, 0x7c, 0x63, - 0x41, 0x3f, 0x23, 0x79, 0xc2, 0x48, 0xe4, 0x7d, 0x80, 0x61, 0xa3, 0x13, 0x74, 0x0e, 0x03, 0xd5, - 0x75, 0xc8, 0x12, 0xd5, 0xad, 0x85, 0x4f, 0x18, 0xb9, 0xd0, 0x27, 0x51, 0xc4, 0xa9, 0x10, 0xaa, - 0x4e, 0x0b, 0x1f, 0x21, 0x7a, 0x0e, 0x3d, 0x4e, 0xd2, 0x88, 0x7d, 0x55, 0xa5, 0x75, 0x71, 0x85, - 0xbc, 0x47, 0xb0, 0x9b, 0xed, 0xa1, 0x67, 0x60, 0x52, 0xce, 0x19, 0xaf, 0xac, 0x4b, 0x80, 0x5e, - 0x82, 0x15, 0x96, 0x7b, 0x70, 0x17, 0x28, 0xe7, 0x2e, 0xae, 0x89, 0xbf, 0x7a, 0xbf, 0x06, 0xbb, - 0xd9, 0x63, 0xdb, 0x45, 0xff, 0xc3, 0xc5, 0x5b, 0xc2, 0xa8, 0xd5, 0xdf, 0x53, 0xa2, 0x78, 0xaf, - 0xc0, 0x3a, 0x15, 0xda, 0xc8, 0xa5, 0xb7, 0x72, 0xbd, 0x03, 0xa3, 0x58, 0x82, 0x7f, 0xe7, 0xa9, - 0xaf, 0xef, 0x34, 0xaf, 0x47, 0xd5, 0x36, 0x15, 0x5f, 0x6a, 0x97, 0x4b, 0x34, 0xf9, 0x08, 0x50, - 0x2f, 0x37, 0xb2, 0x61, 0x10, 0xdc, 0x2d, 0x36, 0x9f, 0xf0, 0xea, 0xbd, 0xa3, 0xd5, 0x68, 0xb7, - 0x75, 0x74, 0x34, 0x02, 0x6b, 0xb9, 0xb9, 0xdf, 0xad, 0xd4, 0x61, 0xa7, 0x01, 0x77, 0x5b, 0xa7, - 0x8b, 0x06, 0x60, 0x04, 0x8b, 0x87, 0x85, 0x63, 0x9c, 0x54, 0xcb, 0xcd, 0xce, 0x31, 0x27, 0x0e, - 0x98, 0x2b, 0x75, 0x79, 0x1f, 0xba, 0xab, 0xfb, 0x5b, 0x47, 0x9b, 0xcf, 0xc0, 0xde, 0x72, 0xf6, - 0x33, 0xdf, 0x51, 0x7e, 0x88, 0x43, 0x8a, 0x2e, 0xc0, 0x54, 0x18, 0xf5, 0xab, 0x67, 0x76, 0x7e, - 0xfc, 0xe3, 0x69, 0x63, 0xfd, 0x4a, 0xbf, 0xb9, 0x7d, 0x0c, 0x44, 0xfc, 0x45, 0xf8, 0xfb, 0xb7, - 0xc2, 0x8f, 0xd9, 0x8c, 0x64, 0xb1, 0xa0, 0xfc, 0x40, 0xf9, 0x34, 0xa5, 0xf2, 0x07, 0xe3, 0xfb, - 0x69, 0x56, 0xc8, 0x67, 0xff, 0x7b, 0xec, 0x9f, 0x7b, 0x0a, 0x5d, 0xff, 0x0e, 0x00, 0x00, 0xff, - 0xff, 0x38, 0x1b, 0xf6, 0x4f, 0x17, 0x04, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// ProxyServiceClient is the client API for ProxyService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ProxyServiceClient interface { - Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) -} - -type proxyServiceClient struct { - cc *grpc.ClientConn -} - -func NewProxyServiceClient(cc *grpc.ClientConn) ProxyServiceClient { - return &proxyServiceClient{cc} -} +var File_konnectivity_client_proto_client_client_proto protoreflect.FileDescriptor + +var file_konnectivity_client_proto_client_client_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x6b, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2d, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xd1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x64, + 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, + 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x05, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x33, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x09, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x09, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0x5b, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x22, 0x5a, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x2c, 0x0a, 0x0c, + 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x22, 0x43, 0x0a, 0x0d, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x22, + 0x23, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x4e, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5e, 0x0a, 0x0a, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x00, + 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x53, 0x50, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x02, 0x12, 0x0d, 0x0a, + 0x09, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x53, 0x50, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, + 0x44, 0x41, 0x54, 0x41, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x43, + 0x4c, 0x53, 0x10, 0x05, 0x32, 0x2f, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x07, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x1a, 0x07, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x22, + 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x46, 0x5a, 0x44, 0x73, 0x69, 0x67, 0x73, 0x2e, 0x6b, 0x38, + 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6b, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_konnectivity_client_proto_client_client_proto_rawDescOnce sync.Once + file_konnectivity_client_proto_client_client_proto_rawDescData = file_konnectivity_client_proto_client_client_proto_rawDesc +) -func (c *proxyServiceClient) Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) { - stream, err := c.cc.NewStream(ctx, &_ProxyService_serviceDesc.Streams[0], "/ProxyService/Proxy", opts...) - if err != nil { - return nil, err +func file_konnectivity_client_proto_client_client_proto_rawDescGZIP() []byte { + file_konnectivity_client_proto_client_client_proto_rawDescOnce.Do(func() { + file_konnectivity_client_proto_client_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_konnectivity_client_proto_client_client_proto_rawDescData) + }) + return file_konnectivity_client_proto_client_client_proto_rawDescData +} + +var file_konnectivity_client_proto_client_client_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_konnectivity_client_proto_client_client_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_konnectivity_client_proto_client_client_proto_goTypes = []interface{}{ + (PacketType)(0), // 0: PacketType + (*Packet)(nil), // 1: Packet + (*DialRequest)(nil), // 2: DialRequest + (*DialResponse)(nil), // 3: DialResponse + (*CloseRequest)(nil), // 4: CloseRequest + (*CloseResponse)(nil), // 5: CloseResponse + (*CloseDial)(nil), // 6: CloseDial + (*Data)(nil), // 7: Data +} +var file_konnectivity_client_proto_client_client_proto_depIdxs = []int32{ + 0, // 0: Packet.type:type_name -> PacketType + 2, // 1: Packet.dialRequest:type_name -> DialRequest + 3, // 2: Packet.dialResponse:type_name -> DialResponse + 7, // 3: Packet.data:type_name -> Data + 4, // 4: Packet.closeRequest:type_name -> CloseRequest + 5, // 5: Packet.closeResponse:type_name -> CloseResponse + 6, // 6: Packet.closeDial:type_name -> CloseDial + 1, // 7: ProxyService.Proxy:input_type -> Packet + 1, // 8: ProxyService.Proxy:output_type -> Packet + 8, // [8:9] is the sub-list for method output_type + 7, // [7:8] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_konnectivity_client_proto_client_client_proto_init() } +func file_konnectivity_client_proto_client_client_proto_init() { + if File_konnectivity_client_proto_client_client_proto != nil { + return } - x := &proxyServiceProxyClient{stream} - return x, nil -} - -type ProxyService_ProxyClient interface { - Send(*Packet) error - Recv() (*Packet, error) - grpc.ClientStream -} - -type proxyServiceProxyClient struct { - grpc.ClientStream -} - -func (x *proxyServiceProxyClient) Send(m *Packet) error { - return x.ClientStream.SendMsg(m) -} - -func (x *proxyServiceProxyClient) Recv() (*Packet, error) { - m := new(Packet) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err + if !protoimpl.UnsafeEnabled { + file_konnectivity_client_proto_client_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Packet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DialRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DialResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseDial); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Data); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - return m, nil -} - -// ProxyServiceServer is the server API for ProxyService service. -type ProxyServiceServer interface { - Proxy(ProxyService_ProxyServer) error -} - -// UnimplementedProxyServiceServer can be embedded to have forward compatible implementations. -type UnimplementedProxyServiceServer struct { -} - -func (*UnimplementedProxyServiceServer) Proxy(srv ProxyService_ProxyServer) error { - return status.Errorf(codes.Unimplemented, "method Proxy not implemented") -} - -func RegisterProxyServiceServer(s *grpc.Server, srv ProxyServiceServer) { - s.RegisterService(&_ProxyService_serviceDesc, srv) -} - -func _ProxyService_Proxy_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ProxyServiceServer).Proxy(&proxyServiceProxyServer{stream}) -} - -type ProxyService_ProxyServer interface { - Send(*Packet) error - Recv() (*Packet, error) - grpc.ServerStream -} - -type proxyServiceProxyServer struct { - grpc.ServerStream -} - -func (x *proxyServiceProxyServer) Send(m *Packet) error { - return x.ServerStream.SendMsg(m) -} - -func (x *proxyServiceProxyServer) Recv() (*Packet, error) { - m := new(Packet) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err + file_konnectivity_client_proto_client_client_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Packet_DialRequest)(nil), + (*Packet_DialResponse)(nil), + (*Packet_Data)(nil), + (*Packet_CloseRequest)(nil), + (*Packet_CloseResponse)(nil), + (*Packet_CloseDial)(nil), } - return m, nil -} - -var _ProxyService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "ProxyService", - HandlerType: (*ProxyServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "Proxy", - Handler: _ProxyService_Proxy_Handler, - ServerStreams: true, - ClientStreams: true, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_konnectivity_client_proto_client_client_proto_rawDesc, + NumEnums: 1, + NumMessages: 7, + NumExtensions: 0, + NumServices: 1, }, - }, - Metadata: "konnectivity-client/proto/client/client.proto", + GoTypes: file_konnectivity_client_proto_client_client_proto_goTypes, + DependencyIndexes: file_konnectivity_client_proto_client_client_proto_depIdxs, + EnumInfos: file_konnectivity_client_proto_client_client_proto_enumTypes, + MessageInfos: file_konnectivity_client_proto_client_client_proto_msgTypes, + }.Build() + File_konnectivity_client_proto_client_client_proto = out.File + file_konnectivity_client_proto_client_client_proto_rawDesc = nil + file_konnectivity_client_proto_client_client_proto_goTypes = nil + file_konnectivity_client_proto_client_client_proto_depIdxs = nil } diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto index 0c4cff8cd24..811278e62da 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto @@ -32,11 +32,6 @@ enum PacketType { DIAL_CLS = 5; } -enum Error { - EOF = 0; - // ... -} - message Packet { PacketType type = 1; diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go new file mode 100644 index 00000000000..b8d07fe55a2 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go @@ -0,0 +1,150 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.12.4 +// source: konnectivity-client/proto/client/client.proto + +package client + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ProxyServiceClient is the client API for ProxyService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ProxyServiceClient interface { + Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) +} + +type proxyServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProxyServiceClient(cc grpc.ClientConnInterface) ProxyServiceClient { + return &proxyServiceClient{cc} +} + +func (c *proxyServiceClient) Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) { + stream, err := c.cc.NewStream(ctx, &ProxyService_ServiceDesc.Streams[0], "/ProxyService/Proxy", opts...) + if err != nil { + return nil, err + } + x := &proxyServiceProxyClient{stream} + return x, nil +} + +type ProxyService_ProxyClient interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ClientStream +} + +type proxyServiceProxyClient struct { + grpc.ClientStream +} + +func (x *proxyServiceProxyClient) Send(m *Packet) error { + return x.ClientStream.SendMsg(m) +} + +func (x *proxyServiceProxyClient) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ProxyServiceServer is the server API for ProxyService service. +// All implementations should embed UnimplementedProxyServiceServer +// for forward compatibility +type ProxyServiceServer interface { + Proxy(ProxyService_ProxyServer) error +} + +// UnimplementedProxyServiceServer should be embedded to have forward compatible implementations. +type UnimplementedProxyServiceServer struct { +} + +func (UnimplementedProxyServiceServer) Proxy(ProxyService_ProxyServer) error { + return status.Errorf(codes.Unimplemented, "method Proxy not implemented") +} + +// UnsafeProxyServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProxyServiceServer will +// result in compilation errors. +type UnsafeProxyServiceServer interface { + mustEmbedUnimplementedProxyServiceServer() +} + +func RegisterProxyServiceServer(s grpc.ServiceRegistrar, srv ProxyServiceServer) { + s.RegisterService(&ProxyService_ServiceDesc, srv) +} + +func _ProxyService_Proxy_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ProxyServiceServer).Proxy(&proxyServiceProxyServer{stream}) +} + +type ProxyService_ProxyServer interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ServerStream +} + +type proxyServiceProxyServer struct { + grpc.ServerStream +} + +func (x *proxyServiceProxyServer) Send(m *Packet) error { + return x.ServerStream.SendMsg(m) +} + +func (x *proxyServiceProxyServer) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ProxyService_ServiceDesc is the grpc.ServiceDesc for ProxyService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProxyService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ProxyService", + HandlerType: (*ProxyServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Proxy", + Handler: _ProxyService_Proxy_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "konnectivity-client/proto/client/client.proto", +} diff --git a/vendor/sigs.k8s.io/controller-runtime/.gitignore b/vendor/sigs.k8s.io/controller-runtime/.gitignore index c2c72faf34b..294685952b8 100644 --- a/vendor/sigs.k8s.io/controller-runtime/.gitignore +++ b/vendor/sigs.k8s.io/controller-runtime/.gitignore @@ -22,3 +22,6 @@ # Tools binaries. hack/tools/bin + +junit-report.xml +/artifacts \ No newline at end of file diff --git a/vendor/sigs.k8s.io/controller-runtime/.golangci.yml b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml index 77f528ff005..817c2c723bd 100644 --- a/vendor/sigs.k8s.io/controller-runtime/.golangci.yml +++ b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml @@ -1,48 +1,46 @@ linters: disable-all: true enable: - - asciicheck - - bodyclose - - deadcode - - depguard - - dogsled - - errcheck - - errorlint - - exportloopref - - goconst - - gocritic - - gocyclo - - godot - - gofmt - - goimports - - goprintffuncname - - gosec - - gosimple - - govet - - ifshort - - importas - - ineffassign - - misspell - - nakedret - - nilerr - - nolintlint - - prealloc - - revive - - rowserrcheck - - staticcheck - - structcheck - - stylecheck - - typecheck - - unconvert - - unparam - - unused - - varcheck - - whitespace + - asasalint + - asciicheck + - bidichk + - bodyclose + - depguard + - dogsled + - dupl + - errcheck + - errchkjson + - errorlint + - exhaustive + - exportloopref + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - importas + - ineffassign + - makezero + - misspell + - nakedret + - nilerr + - nolintlint + - prealloc + - revive + - staticcheck + - stylecheck + - tagliatelle + - typecheck + - unconvert + - unparam + - unused + - whitespace linters-settings: - ifshort: - # Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax. - max-decl-chars: 50 importas: no-unaliased: true alias: @@ -61,13 +59,42 @@ linters-settings: - pkg: sigs.k8s.io/controller-runtime alias: ctrl staticcheck: - go: "1.18" + go: "1.20" stylecheck: - go: "1.18" + go: "1.20" depguard: include-go-root: true packages: - io/ioutil # https://go.dev/doc/go1.16#ioutil + revive: + rules: + # The following rules are recommended https://github.com/mgechev/revive#recommended-configuration + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + - name: if-return + - name: increment-decrement + - name: var-naming + - name: var-declaration + - name: range + - name: receiver-naming + - name: time-naming + - name: unexported-return + - name: indent-error-flow + - name: errorf + - name: superfluous-else + - name: unreachable-code + - name: redefines-builtin-id + # + # Rules in addition to the recommended configuration above. + # + - name: bool-literal-in-expr + - name: constant-logical-expr issues: max-same-issues: 0 @@ -77,65 +104,71 @@ issues: exclude-use-default: false # List of regexps of issue texts to exclude, empty list by default. exclude: - # The following are being worked on to remove their exclusion. This list should be reduced or go away all together over time. - # If it is decided they will not be addressed they should be moved above this comment. - - Subprocess launch(ed with variable|ing should be audited) - - (G204|G104|G307) - - "ST1000: at least one file in a package should have a package comment" + # The following are being worked on to remove their exclusion. This list should be reduced or go away all together over time. + # If it is decided they will not be addressed they should be moved above this comment. + - Subprocess launch(ed with variable|ing should be audited) + - (G204|G104|G307) + - "ST1000: at least one file in a package should have a package comment" exclude-rules: - - linters: - - gosec - text: "G108: Profiling endpoint is automatically exposed on /debug/pprof" - - linters: - - revive - text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported" - - linters: - - errcheck - text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked - # With Go 1.16, the new embed directive can be used with an un-named import, - # revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us. - # This directive allows the embed package to be imported with an underscore everywhere. - - linters: - - revive - source: _ "embed" - # Exclude some packages or code to require comments, for example test code, or fake clients. - - linters: - - revive - text: exported (method|function|type|const) (.+) should have comment or be unexported - source: (func|type).*Fake.* - - linters: - - revive - text: exported (method|function|type|const) (.+) should have comment or be unexported - path: fake_\.go - # Disable unparam "always receives" which might not be really - # useful when building libraries. - - linters: - - unparam - text: always receives - # Dot imports for gomega or ginkgo are allowed - # within test files. - - path: _test\.go - text: should not use dot imports - - path: _test\.go - text: cyclomatic complexity - - path: _test\.go - text: "G107: Potential HTTP request made with variable url" - # Append should be able to assign to a different var/slice. - - linters: - - gocritic - text: "appendAssign: append result not assigned to the same slice" - - linters: - - gocritic - text: "singleCaseSwitch: should rewrite switch statement to if statement" - # It considers all file access to a filename that comes from a variable problematic, - # which is naiv at best. - - linters: - - gosec - text: "G304: Potential file inclusion via variable" + - linters: + - gosec + text: "G108: Profiling endpoint is automatically exposed on /debug/pprof" + - linters: + - revive + text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported" + - linters: + - errcheck + text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked + - linters: + - staticcheck + text: "SA1019: .*The component config package has been deprecated and will be removed in a future release." + # With Go 1.16, the new embed directive can be used with an un-named import, + # revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us. + # This directive allows the embed package to be imported with an underscore everywhere. + - linters: + - revive + source: _ "embed" + # Exclude some packages or code to require comments, for example test code, or fake clients. + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + source: (func|type).*Fake.* + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + path: fake_\.go + # Disable unparam "always receives" which might not be really + # useful when building libraries. + - linters: + - unparam + text: always receives + # Dot imports for gomega and ginkgo are allowed + # within test files. + - path: _test\.go + text: should not use dot imports + - path: _test\.go + text: cyclomatic complexity + - path: _test\.go + text: "G107: Potential HTTP request made with variable url" + # Append should be able to assign to a different var/slice. + - linters: + - gocritic + text: "appendAssign: append result not assigned to the same slice" + - linters: + - gocritic + text: "singleCaseSwitch: should rewrite switch statement to if statement" + # It considers all file access to a filename that comes from a variable problematic, + # which is naiv at best. + - linters: + - gosec + text: "G304: Potential file inclusion via variable" + - linters: + - dupl + path: _test\.go run: timeout: 10m skip-files: - - "zz_generated.*\\.go$" - - ".*conversion.*\\.go$" + - "zz_generated.*\\.go$" + - ".*conversion.*\\.go$" allow-parallel-runners: true diff --git a/vendor/sigs.k8s.io/controller-runtime/FORK_INFO.md b/vendor/sigs.k8s.io/controller-runtime/FORK_INFO.md new file mode 100644 index 00000000000..d6f185c930f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/FORK_INFO.md @@ -0,0 +1,3 @@ +This is a fork of controller runtime made from the following commit: + +commit 116a1b831fffe7ccc3c8145306c3e1a3b1b14ffa (HEAD, tag: v0.15.0) diff --git a/vendor/sigs.k8s.io/controller-runtime/Makefile b/vendor/sigs.k8s.io/controller-runtime/Makefile index 36647c697f7..71ec644de02 100644 --- a/vendor/sigs.k8s.io/controller-runtime/Makefile +++ b/vendor/sigs.k8s.io/controller-runtime/Makefile @@ -75,7 +75,7 @@ $(CONTROLLER_GEN): $(TOOLS_DIR)/go.mod # Build controller-gen from tools folder. $(GOLANGCI_LINT): .github/workflows/golangci-lint.yml # Download golanci-lint using hack script into tools folder. hack/ensure-golangci-lint.sh \ -b $(TOOLS_BIN_DIR) \ - $(shell cat .github/workflows/golangci-lint.yml | grep version | sed 's/.*version: //') + $(shell cat .github/workflows/golangci-lint.yml | grep "version: v" | sed 's/.*version: //') ## -------------------------------------- ## Linting @@ -117,7 +117,15 @@ clean-bin: ## Remove all generated binaries. rm -rf hack/tools/bin .PHONY: verify-modules -verify-modules: modules - @if !(git diff --quiet HEAD -- go.sum go.mod); then \ +verify-modules: modules ## Verify go modules are up to date + @if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum $(ENVTEST_DIR)/go.mod $(ENVTEST_DIR)/go.sum); then \ + git diff; \ echo "go module files are out of date, please run 'make modules'"; exit 1; \ fi + +.PHONY: verify-generate +verify-generate: generate ## Verify generated files are up to date + @if !(git diff --quiet HEAD); then \ + git diff; \ + echo "generated files are out of date, run make generate"; exit 1; \ + fi diff --git a/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES b/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES index 82f7a2bef40..7848941d534 100644 --- a/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES +++ b/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES @@ -4,30 +4,26 @@ aliases: # active folks who can be contacted to perform admin-related # tasks on the repo, or otherwise approve any PRS. controller-runtime-admins: - - droot - - mengqiy - - pwittrock + - vincepri + - joelanford # non-admin folks who have write-access and can approve any PRs in the repo controller-runtime-maintainers: - - vincepri + - alvaroaleman - joelanford + - sbueringer + - vincepri # non-admin folks who can approve any PRs in the repo controller-runtime-approvers: - - gerred - - shawn-hurley - - alvaroaleman + - fillzpp # folks who can review and LGTM any PRs in the repo (doesn't # include approvers & admins -- those count too via the OWNERS # file) controller-runtime-reviewers: - - alenkacz - - vincepri - - alexeldeib - varshaprasad96 - - fillzpp + - inteon # folks to can approve things in the directly-ported # testing_frameworks portions of the codebase @@ -39,3 +35,7 @@ aliases: # but are no longer directly involved controller-runtime-emeritus-maintainers: - directxman12 + controller-runtime-emeritus-admins: + - droot + - mengqiy + - pwittrock diff --git a/vendor/sigs.k8s.io/controller-runtime/README.md b/vendor/sigs.k8s.io/controller-runtime/README.md index cd358b94f90..e785abdd77b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/README.md +++ b/vendor/sigs.k8s.io/controller-runtime/README.md @@ -16,8 +16,8 @@ Documentation: - [Basic controller using builder](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder#example-Builder) - [Creating a manager](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#example-New) - [Creating a controller](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller#example-New) -- [Examples](https://github.com/kubernetes-sigs/controller-runtime/blob/master/examples) -- [Designs](https://github.com/kubernetes-sigs/controller-runtime/blob/master/designs) +- [Examples](https://github.com/kubernetes-sigs/controller-runtime/blob/main/examples) +- [Designs](https://github.com/kubernetes-sigs/controller-runtime/blob/main/designs) # Versioning, Maintenance, and Compatibility @@ -27,7 +27,7 @@ Users: - We follow [Semantic Versioning (semver)](https://semver.org) - Use releases with your dependency management to ensure that you get compatible code -- The master branch contains all the latest code, some of which may break compatibility (so "normal" `go get` is not recommended) +- The main branch contains all the latest code, some of which may break compatibility (so "normal" `go get` is not recommended) Contributors: @@ -53,7 +53,7 @@ in sig apimachinery. You can reach the maintainers of this project at: -- Slack channel: [#kubebuilder](http://slack.k8s.io/#kubebuilder) +- Slack channel: [#controller-runtime](https://kubernetes.slack.com/archives/C02MRBMN00Z) - Google Group: [kubebuilder@googlegroups.com](https://groups.google.com/forum/#!forum/kubebuilder) ## Contributing diff --git a/vendor/sigs.k8s.io/controller-runtime/RELEASE.md b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md new file mode 100644 index 00000000000..f234494fe1c --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md @@ -0,0 +1,47 @@ +# Release Process + +The Kubernetes controller-runtime Project is released on an as-needed basis. The process is as follows: + +**Note:** Releases are done from the `release-MAJOR.MINOR` branches. For PATCH releases is not required +to create a new branch you will just need to ensure that all big fixes are cherry-picked into the respective +`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/. + +## How to do a release + +### Create the new branch and the release tag + +1. Create a new branch `git checkout -b release-` from main +2. Push the new branch to the remote repository + +### Now, let's generate the changelog + +1. Create the changelog from the new branch `release-` (`git checkout release-`). +You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools] to generate the notes. See [here][release-notes-generation] + +> **Note** +> - You will need to have checkout locally from the remote repository the previous branch +> - Also, ensure that you fetch all tags from the remote `git fetch --all --tags` + +### Draft a new release from GitHub + +1. Create a new tag with the correct version from the new `release-` branch +2. Add the changelog on it and publish. Now, the code source is released ! + +### Add a new Prow test the for the new branch release + +1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime) +for the new `release-` branch. (i.e. for the `0.11.0` release see the PR: https://github.com/kubernetes/test-infra/pull/25205) +2. Ping the infra PR in the controller-runtime slack channel for reviews. + +### Announce the new release: + +1. Publish on the Slack channel the new release, i.e: + +```` +:announce: Controller-Runtime v0.12.0 has been released! +This release includes a Kubernetes dependency bump to v1.24. +For more info, see the release page: https://github.com/kubernetes-sigs/controller-runtime/releases. + :tada: Thanks to all our contributors! +```` + +2. An announcement email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Controller-Runtime $VERSION is released` diff --git a/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS b/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS index 32e6a3b904b..9c5241c6b42 100644 --- a/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS +++ b/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS @@ -10,5 +10,6 @@ # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE # INSTRUCTIONS AT https://kubernetes.io/security/ -pwittrock -droot +alvaroaleman +sbueringer +vincepri diff --git a/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md b/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md index b3cfc665175..97e091fd48a 100644 --- a/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md +++ b/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md @@ -21,7 +21,7 @@ log.Printf("starting reconciliation for pod %s/%s", podNamespace, podName) In controller-runtime, we'd instead write: ```go -logger.Info("starting reconciliation", "pod", req.NamespacedNamed) +logger.Info("starting reconciliation", "pod", req.NamespacedName) ``` or even write @@ -51,7 +51,7 @@ You can configure the logging implementation using `"sigs.k8s.io/controller-runtime/pkg/log".SetLogger`. That package also contains the convenience functions for setting up Zap. -You can get a handle to the the "root" logger using +You can get a handle to the "root" logger using `"sigs.k8s.io/controller-runtime/pkg/log".Log`, and can then call `WithName` to create individual named loggers. You can call `WithName` repeatedly to chain names together: diff --git a/vendor/sigs.k8s.io/controller-runtime/alias.go b/vendor/sigs.k8s.io/controller-runtime/alias.go index 29f964dcbeb..237963889c7 100644 --- a/vendor/sigs.k8s.io/controller-runtime/alias.go +++ b/vendor/sigs.k8s.io/controller-runtime/alias.go @@ -70,6 +70,10 @@ type TypeMeta = metav1.TypeMeta type ObjectMeta = metav1.ObjectMeta var ( + // RegisterFlags registers flag variables to the given FlagSet if not already registered. + // It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. + RegisterFlags = config.RegisterFlags + // GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running // in cluster and use the cluster provided kubeconfig. @@ -95,6 +99,8 @@ var ( // ConfigFile returns the cfg.File function for deferred config file loading, // this is passed into Options{}.From() to populate the Options fields for // the manager. + // + // Deprecated: This is deprecated in favor of using Options directly. ConfigFile = cfg.File // NewControllerManagedBy returns a new controller builder that will be started by the provided Manager. @@ -135,7 +141,7 @@ var ( // The logger, when used with controllers, can be expected to contain basic information about the object // that's being reconciled like: // - `reconciler group` and `reconciler kind` coming from the For(...) object passed in when building a controller. - // - `name` and `namespace` injected from the reconciliation request. + // - `name` and `namespace` from the reconciliation request. // // This is meant to be used with the context supplied in a struct that satisfies the Reconciler interface. LoggerFrom = log.FromContext diff --git a/vendor/sigs.k8s.io/controller-runtime/doc.go b/vendor/sigs.k8s.io/controller-runtime/doc.go index 9f260c4f741..0319bc3ff86 100644 --- a/vendor/sigs.k8s.io/controller-runtime/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/doc.go @@ -23,13 +23,14 @@ limitations under the License. // and uncommon cases should be possible. In general, controller-runtime tries // to guide users towards Kubernetes controller best-practices. // -// Getting Started +// # Getting Started // // The main entrypoint for controller-runtime is this root package, which // contains all of the common types needed to get started building controllers: -// import ( -// ctrl "sigs.k8s.io/controller-runtime" -// ) +// +// import ( +// ctrl "sigs.k8s.io/controller-runtime" +// ) // // The examples in this package walk through a basic controller setup. The // kubebuilder book (https://book.kubebuilder.io) has some more in-depth @@ -38,25 +39,25 @@ limitations under the License. // controller-runtime favors structs with sane defaults over constructors, so // it's fairly common to see structs being used directly in controller-runtime. // -// Organization +// # Organization // // A brief-ish walkthrough of the layout of this library can be found below. Each // package contains more information about how to use it. // // Frequently asked questions about using controller-runtime and designing // controllers can be found at -// https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ.md. +// https://github.com/kubernetes-sigs/controller-runtime/blob/main/FAQ.md. // -// Managers +// # Managers // // Every controller and webhook is ultimately run by a Manager (pkg/manager). A // manager is responsible for running controllers and webhooks, and setting up -// common dependencies (pkg/runtime/inject), like shared caches and clients, as +// common dependencies, like shared caches and clients, as // well as managing leader election (pkg/leaderelection). Managers are // generally configured to gracefully shut down controllers on pod termination // by wiring up a signal handler (pkg/manager/signals). // -// Controllers +// # Controllers // // Controllers (pkg/controller) use events (pkg/event) to eventually trigger // reconcile requests. They may be constructed manually, but are often @@ -67,7 +68,7 @@ limitations under the License. // trigger reconciles. There are pre-written utilities for the common cases, and // interfaces and helpers for advanced cases. // -// Reconcilers +// # Reconcilers // // Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A // Reconciler implements a function which takes a reconcile Request containing @@ -75,7 +76,7 @@ limitations under the License. // and returns a Response or an error indicating whether to requeue for a // second round of processing. // -// Clients and Caches +// # Clients and Caches // // Reconcilers use Clients (pkg/client) to access API objects. The default // client provided by the manager reads from a local shared cache (pkg/cache) @@ -91,19 +92,19 @@ limitations under the License. // may retrieve event recorders (pkg/recorder) to emit events using the // manager. // -// Schemes +// # Schemes // // Clients, Caches, and many other things in Kubernetes use Schemes // (pkg/scheme) to associate Go types to Kubernetes API Kinds // (Group-Version-Kinds, to be specific). // -// Webhooks +// # Webhooks // // Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but // are often constructed using a builder (pkg/webhook/admission/builder). They // are run via a server (pkg/webhook) which is managed by a Manager. // -// Logging and Metrics +// # Logging and Metrics // // Logging (pkg/log) in controller-runtime is done via structured logs, using a // log set of interfaces called logr @@ -117,7 +118,7 @@ limitations under the License. // serve these by an HTTP endpoint, and additional metrics may be registered to // this Registry as normal. // -// Testing +// # Testing // // You can easily build integration and unit tests for your controllers and // webhooks using the test Environment (pkg/envtest). This will automatically diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go index eedda4932f3..570cfd63d03 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go @@ -17,6 +17,7 @@ limitations under the License. package builder import ( + "errors" "fmt" "strings" @@ -29,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" + internalsource "sigs.k8s.io/controller-runtime/pkg/internal/source" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -95,14 +97,20 @@ func (blder *Builder) For(object client.Object, opts ...ForOption) *Builder { // OwnsInput represents the information set by Owns method. type OwnsInput struct { + matchEveryOwner bool object client.Object predicates []predicate.Predicate objectProjection objectProjection } // Owns defines types of Objects being *generated* by the ControllerManagedBy, and configures the ControllerManagedBy to respond to -// create / delete / update events by *reconciling the owner object*. This is the equivalent of calling -// Watches(&source.Kind{Type: }, &handler.EnqueueRequestForOwner{OwnerType: apiType, IsController: true}). +// create / delete / update events by *reconciling the owner object*. +// +// The default behavior reconciles only the first controller-type OwnerReference of the given type. +// Use Owns(object, builder.MatchEveryOwner) to reconcile all owners. +// +// By default, this is the equivalent of calling +// Watches(object, handler.EnqueueRequestForOwner([...], ownerType, OnlyControllerOwner())). func (blder *Builder) Owns(object client.Object, opts ...OwnsOption) *Builder { input := OwnsInput{object: object} for _, opt := range opts { @@ -121,10 +129,54 @@ type WatchesInput struct { objectProjection objectProjection } -// Watches exposes the lower-level ControllerManagedBy Watches functions through the builder. Consider using -// Owns or For instead of Watches directly. +// Watches defines the type of Object to watch, and configures the ControllerManagedBy to respond to create / delete / +// update events by *reconciling the object* with the given EventHandler. +// +// This is the equivalent of calling +// WatchesRawSource(source.Kind(scheme, object), eventhandler, opts...). +func (blder *Builder) Watches(object client.Object, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder { + src := source.Kind(blder.mgr.GetCache(), object) + return blder.WatchesRawSource(src, eventhandler, opts...) +} + +// WatchesMetadata is the same as Watches, but forces the internal cache to only watch PartialObjectMetadata. +// +// This is useful when watching lots of objects, really big objects, or objects for which you only know +// the GVK, but not the structure. You'll need to pass metav1.PartialObjectMetadata to the client +// when fetching objects in your reconciler, otherwise you'll end up with a duplicate structured or unstructured cache. +// +// When watching a resource with metadata only, for example the v1.Pod, you should not Get and List using the v1.Pod type. +// Instead, you should use the special metav1.PartialObjectMetadata type. +// +// ❌ Incorrect: +// +// pod := &v1.Pod{} +// mgr.GetClient().Get(ctx, nsAndName, pod) +// +// ✅ Correct: +// +// pod := &metav1.PartialObjectMetadata{} +// pod.SetGroupVersionKind(schema.GroupVersionKind{ +// Group: "", +// Version: "v1", +// Kind: "Pod", +// }) +// mgr.GetClient().Get(ctx, nsAndName, pod) +// +// In the first case, controller-runtime will create another cache for the +// concrete type on top of the metadata cache; this increases memory +// consumption and leads to race conditions as caches are not in sync. +func (blder *Builder) WatchesMetadata(object client.Object, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder { + opts = append(opts, OnlyMetadata) + return blder.Watches(object, eventhandler, opts...) +} + +// WatchesRawSource exposes the lower-level ControllerManagedBy Watches functions through the builder. // Specified predicates are registered only for given source. -func (blder *Builder) Watches(src source.Source, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder { +// +// STOP! Consider using For(...), Owns(...), Watches(...), WatchesMetadata(...) instead. +// This method is only exposed for more advanced use cases, most users should use higher level functions. +func (blder *Builder) WatchesRawSource(src source.Source, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder { input := WatchesInput{src: src, eventhandler: eventhandler} for _, opt := range opts { opt.ApplyToWatches(&input) @@ -182,10 +234,6 @@ func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, erro if blder.forInput.err != nil { return nil, blder.forInput.err } - // Checking the reconcile type exist or not - if blder.forInput.object == nil { - return nil, fmt.Errorf("must provide an object for reconciliation") - } // Set the ControllerManagedBy if err := blder.doController(r); err != nil { @@ -219,28 +267,38 @@ func (blder *Builder) project(obj client.Object, proj objectProjection) (client. func (blder *Builder) doWatch() error { // Reconcile type - typeForSrc, err := blder.project(blder.forInput.object, blder.forInput.objectProjection) - if err != nil { - return err - } - src := &source.Kind{Type: typeForSrc} - hdler := &handler.EnqueueRequestForObject{} - allPredicates := append(blder.globalPredicates, blder.forInput.predicates...) - if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { - return err + if blder.forInput.object != nil { + obj, err := blder.project(blder.forInput.object, blder.forInput.objectProjection) + if err != nil { + return err + } + src := source.Kind(blder.mgr.GetCache(), obj) + hdler := &handler.EnqueueRequestForObject{} + allPredicates := append(blder.globalPredicates, blder.forInput.predicates...) + if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { + return err + } } // Watches the managed types + if len(blder.ownsInput) > 0 && blder.forInput.object == nil { + return errors.New("Owns() can only be used together with For()") + } for _, own := range blder.ownsInput { - typeForSrc, err := blder.project(own.object, own.objectProjection) + obj, err := blder.project(own.object, own.objectProjection) if err != nil { return err } - src := &source.Kind{Type: typeForSrc} - hdler := &handler.EnqueueRequestForOwner{ - OwnerType: blder.forInput.object, - IsController: true, + src := source.Kind(blder.mgr.GetCache(), obj) + opts := []handler.OwnerOption{} + if !own.matchEveryOwner { + opts = append(opts, handler.OnlyControllerOwner()) } + hdler := handler.EnqueueRequestForOwner( + blder.mgr.GetScheme(), blder.mgr.GetRESTMapper(), + blder.forInput.object, + opts..., + ) allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) allPredicates = append(allPredicates, own.predicates...) if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { @@ -249,12 +307,15 @@ func (blder *Builder) doWatch() error { } // Do the watch requests + if len(blder.watchesInput) == 0 && blder.forInput.object == nil { + return errors.New("there are no watches configured, controller will never get triggered. Use For(), Owns() or Watches() to set them up") + } for _, w := range blder.watchesInput { allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) allPredicates = append(allPredicates, w.predicates...) - // If the source of this watch is of type *source.Kind, project it. - if srckind, ok := w.src.(*source.Kind); ok { + // If the source of this watch is of type Kind, project it. + if srckind, ok := w.src.(*internalsource.Kind); ok { typeForSrc, err := blder.project(srckind.Type, w.objectProjection) if err != nil { return err @@ -269,11 +330,14 @@ func (blder *Builder) doWatch() error { return nil } -func (blder *Builder) getControllerName(gvk schema.GroupVersionKind) string { +func (blder *Builder) getControllerName(gvk schema.GroupVersionKind, hasGVK bool) (string, error) { if blder.name != "" { - return blder.name + return blder.name, nil + } + if !hasGVK { + return "", errors.New("one of For() or Named() must be called") } - return strings.ToLower(gvk.Kind) + return strings.ToLower(gvk.Kind), nil } func (blder *Builder) doController(r reconcile.Reconciler) error { @@ -286,13 +350,18 @@ func (blder *Builder) doController(r reconcile.Reconciler) error { // Retrieve the GVK from the object we're reconciling // to prepopulate logger information, and to optionally generate a default name. - gvk, err := getGvk(blder.forInput.object, blder.mgr.GetScheme()) - if err != nil { - return err + var gvk schema.GroupVersionKind + hasGVK := blder.forInput.object != nil + if hasGVK { + var err error + gvk, err = getGvk(blder.forInput.object, blder.mgr.GetScheme()) + if err != nil { + return err + } } // Setup concurrency. - if ctrlOptions.MaxConcurrentReconciles == 0 { + if ctrlOptions.MaxConcurrentReconciles == 0 && hasGVK { groupKind := gvk.GroupKind().String() if concurrency, ok := globalOpts.GroupKindConcurrency[groupKind]; ok && concurrency > 0 { @@ -301,27 +370,34 @@ func (blder *Builder) doController(r reconcile.Reconciler) error { } // Setup cache sync timeout. - if ctrlOptions.CacheSyncTimeout == 0 && globalOpts.CacheSyncTimeout != nil { - ctrlOptions.CacheSyncTimeout = *globalOpts.CacheSyncTimeout + if ctrlOptions.CacheSyncTimeout == 0 && globalOpts.CacheSyncTimeout > 0 { + ctrlOptions.CacheSyncTimeout = globalOpts.CacheSyncTimeout } - controllerName := blder.getControllerName(gvk) + controllerName, err := blder.getControllerName(gvk, hasGVK) + if err != nil { + return err + } // Setup the logger. if ctrlOptions.LogConstructor == nil { log := blder.mgr.GetLogger().WithValues( "controller", controllerName, - "controllerGroup", gvk.Group, - "controllerKind", gvk.Kind, ) - - lowerCamelCaseKind := strings.ToLower(gvk.Kind[:1]) + gvk.Kind[1:] + if hasGVK { + log = log.WithValues( + "controllerGroup", gvk.Group, + "controllerKind", gvk.Kind, + ) + } ctrlOptions.LogConstructor = func(req *reconcile.Request) logr.Logger { log := log if req != nil { + if hasGVK { + log = log.WithValues(gvk.Kind, klog.KRef(req.Namespace, req.Name)) + } log = log.WithValues( - lowerCamelCaseKind, klog.KRef(req.Namespace, req.Name), "namespace", req.Namespace, "name", req.Name, ) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go index c738ba7d10e..bce2065efaf 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go @@ -101,9 +101,9 @@ func (p projectAs) ApplyToWatches(opts *WatchesInput) { var ( // OnlyMetadata tells the controller to *only* cache metadata, and to watch - // the the API server in metadata-only form. This is useful when watching + // the API server in metadata-only form. This is useful when watching // lots of objects, really big objects, or objects for which you only know - // the the GVK, but not the structure. You'll need to pass + // the GVK, but not the structure. You'll need to pass // metav1.PartialObjectMetadata to the client when fetching objects in your // reconciler, otherwise you'll end up with a duplicate structured or // unstructured cache. @@ -138,3 +138,19 @@ var ( ) // }}} + +// MatchEveryOwner determines whether the watch should be filtered based on +// controller ownership. As in, when the OwnerReference.Controller field is set. +// +// If passed as an option, +// the handler receives notification for every owner of the object with the given type. +// If unset (default), the handler receives notification only for the first +// OwnerReference with `Controller: true`. +var MatchEveryOwner = &matchEveryOwner{} + +type matchEveryOwner struct{} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (o matchEveryOwner) ApplyToOwns(opts *OwnsInput) { + opts.matchEveryOwner = true +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go index 18feb1cd749..82fac4d8fa6 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go @@ -22,9 +22,12 @@ import ( "net/url" "strings" + "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/rest" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -33,12 +36,14 @@ import ( // WebhookBuilder builds a Webhook. type WebhookBuilder struct { - apiType runtime.Object - withDefaulter admission.CustomDefaulter - withValidator admission.CustomValidator - gvk schema.GroupVersionKind - mgr manager.Manager - config *rest.Config + apiType runtime.Object + withDefaulter admission.CustomDefaulter + withValidator admission.CustomValidator + gvk schema.GroupVersionKind + mgr manager.Manager + config *rest.Config + recoverPanic bool + logConstructor func(base logr.Logger, req *admission.Request) logr.Logger } // WebhookManagedBy allows inform its manager.Manager. @@ -68,11 +73,26 @@ func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) return blder } +// WithLogConstructor overrides the webhook's LogConstructor. +func (blder *WebhookBuilder) WithLogConstructor(logConstructor func(base logr.Logger, req *admission.Request) logr.Logger) *WebhookBuilder { + blder.logConstructor = logConstructor + return blder +} + +// RecoverPanic indicates whether the panic caused by webhook should be recovered. +func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder { + blder.recoverPanic = true + return blder +} + // Complete builds the webhook. func (blder *WebhookBuilder) Complete() error { // Set the Config blder.loadRestConfig() + // Configure the default LogConstructor + blder.setLogConstructor() + // Set the Webhook if needed return blder.registerWebhooks() } @@ -83,6 +103,26 @@ func (blder *WebhookBuilder) loadRestConfig() { } } +func (blder *WebhookBuilder) setLogConstructor() { + if blder.logConstructor == nil { + blder.logConstructor = func(base logr.Logger, req *admission.Request) logr.Logger { + log := base.WithValues( + "webhookGroup", blder.gvk.Group, + "webhookKind", blder.gvk.Kind, + ) + if req != nil { + return log.WithValues( + blder.gvk.Kind, klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) + } + return log + } + } +} + func (blder *WebhookBuilder) registerWebhooks() error { typ, err := blder.getType() if err != nil { @@ -109,6 +149,7 @@ func (blder *WebhookBuilder) registerWebhooks() error { func (blder *WebhookBuilder) registerDefaultingWebhook() { mwh := blder.getDefaultingWebhook() if mwh != nil { + mwh.LogConstructor = blder.logConstructor path := generateMutatePath(blder.gvk) // Checking if the path is already registered. @@ -124,10 +165,10 @@ func (blder *WebhookBuilder) registerDefaultingWebhook() { func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook { if defaulter := blder.withDefaulter; defaulter != nil { - return admission.WithCustomDefaulter(blder.apiType, defaulter) + return admission.WithCustomDefaulter(blder.mgr.GetScheme(), blder.apiType, defaulter).WithRecoverPanic(blder.recoverPanic) } if defaulter, ok := blder.apiType.(admission.Defaulter); ok { - return admission.DefaultingWebhookFor(defaulter) + return admission.DefaultingWebhookFor(blder.mgr.GetScheme(), defaulter).WithRecoverPanic(blder.recoverPanic) } log.Info( "skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called", @@ -138,6 +179,7 @@ func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook { func (blder *WebhookBuilder) registerValidatingWebhook() { vwh := blder.getValidatingWebhook() if vwh != nil { + vwh.LogConstructor = blder.logConstructor path := generateValidatePath(blder.gvk) // Checking if the path is already registered. @@ -153,10 +195,10 @@ func (blder *WebhookBuilder) registerValidatingWebhook() { func (blder *WebhookBuilder) getValidatingWebhook() *admission.Webhook { if validator := blder.withValidator; validator != nil { - return admission.WithCustomValidator(blder.apiType, validator) + return admission.WithCustomValidator(blder.mgr.GetScheme(), blder.apiType, validator).WithRecoverPanic(blder.recoverPanic) } if validator, ok := blder.apiType.(admission.Validator); ok { - return admission.ValidatingWebhookFor(validator) + return admission.ValidatingWebhookFor(blder.mgr.GetScheme(), validator).WithRecoverPanic(blder.recoverPanic) } log.Info( "skip registering a validating webhook, object does not implement admission.Validator or WithValidator wasn't called", @@ -172,7 +214,7 @@ func (blder *WebhookBuilder) registerConversionWebhook() error { } if ok { if !blder.isAlreadyHandled("/convert") { - blder.mgr.GetWebhookServer().Register("/convert", &conversion.Webhook{}) + blder.mgr.GetWebhookServer().Register("/convert", conversion.NewWebhookHandler(blder.mgr.GetScheme())) } log.Info("Conversion webhook enabled", "GVK", blder.gvk) } @@ -188,10 +230,10 @@ func (blder *WebhookBuilder) getType() (runtime.Object, error) { } func (blder *WebhookBuilder) isAlreadyHandled(path string) bool { - if blder.mgr.GetWebhookServer().WebhookMux == nil { + if blder.mgr.GetWebhookServer().WebhookMux() == nil { return false } - h, p := blder.mgr.GetWebhookServer().WebhookMux.Handler(&http.Request{URL: &url.URL{Path: path}}) + h, p := blder.mgr.GetWebhookServer().WebhookMux().Handler(&http.Request{URL: &url.URL{Path: path}}) if p == path && h != nil { return true } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go index 2a8f53347e7..57e6eb61883 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go @@ -19,21 +19,44 @@ package cache import ( "context" "fmt" + "net/http" "time" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" toolscache "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/cache/internal" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" logf "sigs.k8s.io/controller-runtime/pkg/internal/log" ) -var log = logf.RuntimeLog.WithName("object-cache") +var ( + log = logf.RuntimeLog.WithName("object-cache") + defaultSyncPeriod = 10 * time.Hour + + // BlockUntilSynced determines whether a get request for an informer should block + // until the informer's cache has synced. + BlockUntilSynced = internal.BlockUntilSynced +) + +// InformerGetOption defines an option that alters the behavior of how informers are retrieved. +type InformerGetOption internal.InformerGetOption + +func castInformerGetOptions(opts []InformerGetOption) []internal.InformerGetOption { + out := make([]internal.InformerGetOption, len(opts)) + for i := range opts { + out[i] = internal.InformerGetOption(opts[i]) + } + return out +} // Cache knows how to load Kubernetes objects, fetch informers to request // to receive events for Kubernetes objects (at a low-level), @@ -52,11 +75,11 @@ type Cache interface { type Informers interface { // GetInformer fetches or constructs an informer for the given object that corresponds to a single // API kind and resource. - GetInformer(ctx context.Context, obj client.Object) (Informer, error) + GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) // GetInformerForKind is similar to GetInformer, except that it takes a group-version-kind, instead // of the underlying object. - GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error) + GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) // Start runs all the informers known to this cache until the context is closed. // It blocks. @@ -74,11 +97,19 @@ type Informer interface { // AddEventHandler adds an event handler to the shared informer using the shared informer's resync // period. Events to a single handler are delivered sequentially, but there is no coordination // between different handlers. - AddEventHandler(handler toolscache.ResourceEventHandler) + // It returns a registration handle for the handler that can be used to remove + // the handler again. + AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) // AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the // specified resync period. Events to a single handler are delivered sequentially, but there is // no coordination between different handlers. - AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) + // It returns a registration handle for the handler that can be used to remove + // the handler again and an error if the handler cannot be added. + AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) + // RemoveEventHandler removes a formerly added event handler given by + // its registration handle. + // This function is guaranteed to be idempotent, and thread-safe. + RemoveEventHandler(handle toolscache.ResourceEventHandlerRegistration) error // AddIndexers adds more indexers to this store. If you call this after you already have data // in the store, the results are undefined. AddIndexers(indexers toolscache.Indexers) error @@ -86,117 +117,152 @@ type Informer interface { HasSynced() bool } -// ObjectSelector is an alias name of internal.Selector. -type ObjectSelector internal.Selector - -// SelectorsByObject associate a client.Object's GVK to a field/label selector. -// There is also `DefaultSelector` to set a global default (which will be overridden by -// a more specific setting here, if any). -type SelectorsByObject map[client.Object]ObjectSelector - // Options are the optional arguments for creating a new InformersMap object. type Options struct { + // HTTPClient is the http client to use for the REST client + HTTPClient *http.Client + // Scheme is the scheme to use for mapping objects to GroupVersionKinds Scheme *runtime.Scheme // Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources Mapper meta.RESTMapper - // Resync is the base frequency the informers are resynced. - // Defaults to defaultResyncTime. - // A 10 percent jitter will be added to the Resync period between informers - // So that all informers will not send list requests simultaneously. - Resync *time.Duration - - // Namespace restricts the cache's ListWatch to the desired namespace + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // + // This applies to all controllers. + // + // A period sync happens for two reasons: + // 1. To insure against a bug in the controller that causes an object to not + // be requeued, when it otherwise should be requeued. + // 2. To insure against an unknown bug in controller-runtime, or its dependencies, + // that causes an object to not be requeued, when it otherwise should be + // requeued, or to be removed from the queue, when it otherwise should not + // be removed. + // + // If you want + // 1. to insure against missed watch events, or + // 2. to poll services that cannot be watched, + // then we recommend that, instead of changing the default period, the + // controller requeue, with a constant duration `t`, whenever the controller + // is "done" with an object, and would otherwise not requeue it, i.e., we + // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, + // instead of `reconcile.Result{}`. + SyncPeriod *time.Duration + + // Namespaces restricts the cache's ListWatch to the desired namespaces // Default watches all namespaces - Namespace string + Namespaces []string - // SelectorsByObject restricts the cache's ListWatch to the desired - // fields per GVK at the specified object, the map's value must implement - // Selector [1] using for example a Set [2] - // [1] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Selector - // [2] https://pkg.go.dev/k8s.io/apimachinery/pkg/fields#Set - SelectorsByObject SelectorsByObject + // DefaultLabelSelector will be used as a label selectors for all object types + // unless they have a more specific selector set in ByObject. + DefaultLabelSelector labels.Selector - // DefaultSelector will be used as selectors for all object types - // that do not have a selector in SelectorsByObject defined. - DefaultSelector ObjectSelector + // DefaultFieldSelector will be used as a field selectors for all object types + // unless they have a more specific selector set in ByObject. + DefaultFieldSelector fields.Selector - // UnsafeDisableDeepCopyByObject indicates not to deep copy objects during get or - // list objects per GVK at the specified object. + // DefaultTransform will be used as transform for all object types + // unless they have a more specific transform set in ByObject. + DefaultTransform toolscache.TransformFunc + + // ByObject restricts the cache's ListWatch to the desired fields per GVK at the specified object. + ByObject map[client.Object]ByObject + + // UnsafeDisableDeepCopy indicates not to deep copy objects during get or + // list objects for EVERY object. // Be very careful with this, when enabled you must DeepCopy any object before mutating it, // otherwise you will mutate the object in the cache. - UnsafeDisableDeepCopyByObject DisableDeepCopyByObject + // + // This is a global setting for all objects, and can be overridden by the ByObject setting. + UnsafeDisableDeepCopy *bool +} + +// ByObject offers more fine-grained control over the cache's ListWatch by object. +type ByObject struct { + // Label represents a label selector for the object. + Label labels.Selector + + // Field represents a field selector for the object. + Field fields.Selector - // TransformByObject is a map from GVKs to transformer functions which + // Transform is a map from objects to transformer functions which // get applied when objects of the transformation are about to be committed // to cache. // // This function is called both for new objects to enter the cache, - // and for updated objects. - TransformByObject TransformByObject + // and for updated objects. + Transform toolscache.TransformFunc - // DefaultTransform is the transform used for all GVKs which do - // not have an explicit transform func set in TransformByObject - DefaultTransform toolscache.TransformFunc + // UnsafeDisableDeepCopy indicates not to deep copy objects during get or + // list objects per GVK at the specified object. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + UnsafeDisableDeepCopy *bool } -var defaultResyncTime = 10 * time.Hour +// NewCacheFunc - Function for creating a new cache from the options and a rest config. +type NewCacheFunc func(config *rest.Config, opts Options) (Cache, error) // New initializes and returns a new Cache. func New(config *rest.Config, opts Options) (Cache, error) { - opts, err := defaultOpts(config, opts) - if err != nil { - return nil, err + if len(opts.Namespaces) == 0 { + opts.Namespaces = []string{metav1.NamespaceAll} } - selectorsByGVK, err := convertToSelectorsByGVK(opts.SelectorsByObject, opts.DefaultSelector, opts.Scheme) - if err != nil { - return nil, err + if len(opts.Namespaces) > 1 { + return newMultiNamespaceCache(config, opts) } - disableDeepCopyByGVK, err := convertToDisableDeepCopyByGVK(opts.UnsafeDisableDeepCopyByObject, opts.Scheme) + + opts, err := defaultOpts(config, opts) if err != nil { return nil, err } - transformByGVK, err := convertToTransformByKindAndGVK(opts.TransformByObject, opts.DefaultTransform, opts.Scheme) + + byGVK, err := convertToInformerOptsByGVK(opts.ByObject, opts.Scheme) if err != nil { return nil, err } + // Set the default selector and transform. + byGVK[schema.GroupVersionKind{}] = internal.InformersOptsByGVK{ + Selector: internal.Selector{ + Label: opts.DefaultLabelSelector, + Field: opts.DefaultFieldSelector, + }, + Transform: opts.DefaultTransform, + UnsafeDisableDeepCopy: opts.UnsafeDisableDeepCopy, + } - im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK, disableDeepCopyByGVK, transformByGVK) - return &informerCache{InformersMap: im}, nil + return &informerCache{ + scheme: opts.Scheme, + Informers: internal.NewInformers(config, &internal.InformersOpts{ + HTTPClient: opts.HTTPClient, + Scheme: opts.Scheme, + Mapper: opts.Mapper, + ResyncPeriod: *opts.SyncPeriod, + Namespace: opts.Namespaces[0], + ByGVK: byGVK, + }), + }, nil } -// BuilderWithOptions returns a Cache constructor that will build the a cache -// honoring the options argument, this is useful to specify options like -// SelectorsByObject -// WARNING: if SelectorsByObject is specified. filtered out resources are not -// returned. -// WARNING: if UnsafeDisableDeepCopy is enabled, you must DeepCopy any object -// returned from cache get/list before mutating it. -func BuilderWithOptions(options Options) NewCacheFunc { - return func(config *rest.Config, opts Options) (Cache, error) { - if options.Scheme == nil { - options.Scheme = opts.Scheme - } - if options.Mapper == nil { - options.Mapper = opts.Mapper - } - if options.Resync == nil { - options.Resync = opts.Resync - } - if options.Namespace == "" { - options.Namespace = opts.Namespace - } - if opts.Resync == nil { - opts.Resync = options.Resync - } +func defaultOpts(config *rest.Config, opts Options) (Options, error) { + logger := log.WithName("setup") - return New(config, options) + // Use the rest HTTP client for the provided config if unset + if opts.HTTPClient == nil { + var err error + opts.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + logger.Error(err, "Failed to get HTTP client") + return opts, fmt.Errorf("could not create HTTP client from config: %w", err) + } } -} -func defaultOpts(config *rest.Config, opts Options) (Options, error) { // Use the default Kubernetes Scheme if unset if opts.Scheme == nil { opts.Scheme = scheme.Scheme @@ -205,71 +271,38 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) { // Construct a new Mapper if unset if opts.Mapper == nil { var err error - opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config) + opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config, opts.HTTPClient) if err != nil { - log.WithName("setup").Error(err, "Failed to get API Group-Resources") - return opts, fmt.Errorf("could not create RESTMapper from config") + logger.Error(err, "Failed to get API Group-Resources") + return opts, fmt.Errorf("could not create RESTMapper from config: %w", err) } } // Default the resync period to 10 hours if unset - if opts.Resync == nil { - opts.Resync = &defaultResyncTime + if opts.SyncPeriod == nil { + opts.SyncPeriod = &defaultSyncPeriod } return opts, nil } -func convertToSelectorsByGVK(selectorsByObject SelectorsByObject, defaultSelector ObjectSelector, scheme *runtime.Scheme) (internal.SelectorsByGVK, error) { - selectorsByGVK := internal.SelectorsByGVK{} - for object, selector := range selectorsByObject { +func convertToInformerOptsByGVK(in map[client.Object]ByObject, scheme *runtime.Scheme) (map[schema.GroupVersionKind]internal.InformersOptsByGVK, error) { + out := map[schema.GroupVersionKind]internal.InformersOptsByGVK{} + for object, byObject := range in { gvk, err := apiutil.GVKForObject(object, scheme) if err != nil { return nil, err } - selectorsByGVK[gvk] = internal.Selector(selector) - } - selectorsByGVK[schema.GroupVersionKind{}] = internal.Selector(defaultSelector) - return selectorsByGVK, nil -} - -// DisableDeepCopyByObject associate a client.Object's GVK to disable DeepCopy during get or list from cache. -type DisableDeepCopyByObject map[client.Object]bool - -var _ client.Object = &ObjectAll{} - -// ObjectAll is the argument to represent all objects' types. -type ObjectAll struct { - client.Object -} - -func convertToDisableDeepCopyByGVK(disableDeepCopyByObject DisableDeepCopyByObject, scheme *runtime.Scheme) (internal.DisableDeepCopyByGVK, error) { - disableDeepCopyByGVK := internal.DisableDeepCopyByGVK{} - for obj, disable := range disableDeepCopyByObject { - switch obj.(type) { - case ObjectAll, *ObjectAll: - disableDeepCopyByGVK[internal.GroupVersionKindAll] = disable - default: - gvk, err := apiutil.GVKForObject(obj, scheme) - if err != nil { - return nil, err - } - disableDeepCopyByGVK[gvk] = disable + if _, ok := out[gvk]; ok { + return nil, fmt.Errorf("duplicate cache options for GVK %v, cache.Options.ByObject has multiple types with the same GroupVersionKind", gvk) } - } - return disableDeepCopyByGVK, nil -} - -// TransformByObject associate a client.Object's GVK to a transformer function -// to be applied when storing the object into the cache. -type TransformByObject map[client.Object]toolscache.TransformFunc - -func convertToTransformByKindAndGVK(t TransformByObject, defaultTransform toolscache.TransformFunc, scheme *runtime.Scheme) (internal.TransformFuncByObject, error) { - result := internal.NewTransformFuncByObject() - for obj, transformation := range t { - if err := result.Set(obj, scheme, transformation); err != nil { - return nil, err + out[gvk] = internal.InformersOptsByGVK{ + Selector: internal.Selector{ + Field: byObject.Field, + Label: byObject.Label, + }, + Transform: byObject.Transform, + UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy, } } - result.SetDefault(defaultTransform) - return result, nil + return out, nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go index ac07be2a6e2..e070dbeb606 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go @@ -19,10 +19,10 @@ package cache import ( "context" "fmt" - "reflect" "strings" apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -45,19 +45,21 @@ func (*ErrCacheNotStarted) Error() string { return "the cache is not started, can not read objects" } -// informerCache is a Kubernetes Object cache populated from InformersMap. informerCache wraps an InformersMap. +// informerCache is a Kubernetes Object cache populated from internal.Informers. +// informerCache wraps internal.Informers. type informerCache struct { - *internal.InformersMap + scheme *runtime.Scheme + *internal.Informers } // Get implements Reader. -func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object) error { - gvk, err := apiutil.GVKForObject(out, ip.Scheme) +func (ic *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error { + gvk, err := apiutil.GVKForObject(out, ic.scheme) if err != nil { return err } - started, cache, err := ip.InformersMap.Get(ctx, gvk, out) + started, cache, err := ic.Informers.Get(ctx, gvk, out) if err != nil { return err } @@ -69,13 +71,13 @@ func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out clie } // List implements Reader. -func (ip *informerCache) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error { - gvk, cacheTypeObj, err := ip.objectTypeForListObject(out) +func (ic *informerCache) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error { + gvk, cacheTypeObj, err := ic.objectTypeForListObject(out) if err != nil { return err } - started, cache, err := ip.InformersMap.Get(ctx, *gvk, cacheTypeObj) + started, cache, err := ic.Informers.Get(ctx, *gvk, cacheTypeObj) if err != nil { return err } @@ -90,54 +92,46 @@ func (ip *informerCache) List(ctx context.Context, out client.ObjectList, opts . // objectTypeForListObject tries to find the runtime.Object and associated GVK // for a single object corresponding to the passed-in list type. We need them // because they are used as cache map key. -func (ip *informerCache) objectTypeForListObject(list client.ObjectList) (*schema.GroupVersionKind, runtime.Object, error) { - gvk, err := apiutil.GVKForObject(list, ip.Scheme) +func (ic *informerCache) objectTypeForListObject(list client.ObjectList) (*schema.GroupVersionKind, runtime.Object, error) { + gvk, err := apiutil.GVKForObject(list, ic.scheme) if err != nil { return nil, nil, err } - // we need the non-list GVK, so chop off the "List" from the end of the kind - if strings.HasSuffix(gvk.Kind, "List") && apimeta.IsListType(list) { - gvk.Kind = gvk.Kind[:len(gvk.Kind)-4] - } + // We need the non-list GVK, so chop off the "List" from the end of the kind. + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") - _, isUnstructured := list.(*unstructured.UnstructuredList) - var cacheTypeObj runtime.Object - if isUnstructured { + // Handle unstructured.UnstructuredList. + if _, isUnstructured := list.(runtime.Unstructured); isUnstructured { u := &unstructured.Unstructured{} u.SetGroupVersionKind(gvk) - cacheTypeObj = u - } else { - itemsPtr, err := apimeta.GetItemsPtr(list) - if err != nil { - return nil, nil, err - } - // http://knowyourmeme.com/memes/this-is-fine - elemType := reflect.Indirect(reflect.ValueOf(itemsPtr)).Type().Elem() - if elemType.Kind() != reflect.Ptr { - elemType = reflect.PtrTo(elemType) - } - - cacheTypeValue := reflect.Zero(elemType) - var ok bool - cacheTypeObj, ok = cacheTypeValue.Interface().(runtime.Object) - if !ok { - return nil, nil, fmt.Errorf("cannot get cache for %T, its element %T is not a runtime.Object", list, cacheTypeValue.Interface()) - } + return &gvk, u, nil + } + // Handle metav1.PartialObjectMetadataList. + if _, isPartialObjectMetadata := list.(*metav1.PartialObjectMetadataList); isPartialObjectMetadata { + pom := &metav1.PartialObjectMetadata{} + pom.SetGroupVersionKind(gvk) + return &gvk, pom, nil } + // Any other list type should have a corresponding non-list type registered + // in the scheme. Use that to create a new instance of the non-list type. + cacheTypeObj, err := ic.scheme.New(gvk) + if err != nil { + return nil, nil, err + } return &gvk, cacheTypeObj, nil } // GetInformerForKind returns the informer for the GroupVersionKind. -func (ip *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error) { +func (ic *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { // Map the gvk to an object - obj, err := ip.Scheme.New(gvk) + obj, err := ic.scheme.New(gvk) if err != nil { return nil, err } - _, i, err := ip.InformersMap.Get(ctx, gvk, obj) + _, i, err := ic.Informers.Get(ctx, gvk, obj, castInformerGetOptions(opts)...) if err != nil { return nil, err } @@ -145,13 +139,13 @@ func (ip *informerCache) GetInformerForKind(ctx context.Context, gvk schema.Grou } // GetInformer returns the informer for the obj. -func (ip *informerCache) GetInformer(ctx context.Context, obj client.Object) (Informer, error) { - gvk, err := apiutil.GVKForObject(obj, ip.Scheme) +func (ic *informerCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) if err != nil { return nil, err } - _, i, err := ip.InformersMap.Get(ctx, gvk, obj) + _, i, err := ic.Informers.Get(ctx, gvk, obj, castInformerGetOptions(opts)...) if err != nil { return nil, err } @@ -160,7 +154,7 @@ func (ip *informerCache) GetInformer(ctx context.Context, obj client.Object) (In // NeedLeaderElection implements the LeaderElectionRunnable interface // to indicate that this can be started without requiring the leader lock. -func (ip *informerCache) NeedLeaderElection() bool { +func (ic *informerCache) NeedLeaderElection() bool { return false } @@ -169,14 +163,25 @@ func (ip *informerCache) NeedLeaderElection() bool { // to List. For one-to-one compatibility with "normal" field selectors, only return one value. // The values may be anything. They will automatically be prefixed with the namespace of the // given object, if present. The objects passed are guaranteed to be objects of the correct type. -func (ip *informerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { - informer, err := ip.GetInformer(ctx, obj) +func (ic *informerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + informer, err := ic.GetInformer(ctx, obj) if err != nil { return err } return indexByField(informer, field, extractValue) } +// Remove removes an informer specified by the obj argument from the cache and stops it if it existed. +func (ic *informerCache) Remove(obj client.Object) error { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) + if err != nil { + return err + } + + ic.Informers.Remove(gvk, obj) + return nil +} + func indexByField(indexer Informer, field string, extractor client.IndexerFunc) error { indexFunc := func(objRaw interface{}) ([]string, error) { // TODO(directxman12): check if this is the correct type? diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go index b95af18d78e..3c8355bbde5 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go @@ -23,14 +23,13 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/selection" "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" ) // CacheReader is a client.Reader. @@ -54,7 +53,7 @@ type CacheReader struct { } // Get checks the indexer for the object and writes a copy of it if found. -func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object) error { +func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error { if c.scopeName == apimeta.RESTScopeNameRoot { key.Namespace = "" } @@ -116,7 +115,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli case listOpts.FieldSelector != nil: // TODO(directxman12): support more complicated field selectors by // combining multiple indices, GetIndexers, etc - field, val, requiresExact := requiresExactMatch(listOpts.FieldSelector) + field, val, requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector) if !requiresExact { return fmt.Errorf("non-exact field matches are not supported by the cache") } @@ -148,7 +147,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli } obj, isObj := item.(runtime.Object) if !isObj { - return fmt.Errorf("cache contained %T, which is not an Object", obj) + return fmt.Errorf("cache contained %T, which is not an Object", item) } meta, err := apimeta.Accessor(obj) if err != nil { @@ -162,7 +161,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli } var outObj runtime.Object - if c.disableDeepCopy { + if c.disableDeepCopy || (listOpts.UnsafeDisableDeepCopy != nil && *listOpts.UnsafeDisableDeepCopy) { // skip deep copy which might be unsafe // you must DeepCopy any object before mutating it outside outObj = obj @@ -186,19 +185,6 @@ func objectKeyToStoreKey(k client.ObjectKey) string { return k.Namespace + "/" + k.Name } -// requiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`. -func requiresExactMatch(sel fields.Selector) (field, val string, required bool) { - reqs := sel.Requirements() - if len(reqs) != 1 { - return "", "", false - } - req := reqs[0] - if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals { - return "", "", false - } - return req.Field, req.Value, true -} - // FieldIndexName constructs the name of the index over the given field, // for use with an indexer. func FieldIndexName(field string) string { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/deleg_map.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/deleg_map.go deleted file mode 100644 index 27f46e32781..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/deleg_map.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import ( - "context" - "time" - - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" -) - -// InformersMap create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. -// It uses a standard parameter codec constructed based on the given generated Scheme. -type InformersMap struct { - // we abstract over the details of structured/unstructured/metadata with the specificInformerMaps - // TODO(directxman12): genericize this over different projections now that we have 3 different maps - - structured *specificInformersMap - unstructured *specificInformersMap - metadata *specificInformersMap - - // Scheme maps runtime.Objects to GroupVersionKinds - Scheme *runtime.Scheme -} - -// NewInformersMap creates a new InformersMap that can create informers for -// both structured and unstructured objects. -func NewInformersMap(config *rest.Config, - scheme *runtime.Scheme, - mapper meta.RESTMapper, - resync time.Duration, - namespace string, - selectors SelectorsByGVK, - disableDeepCopy DisableDeepCopyByGVK, - transformers TransformFuncByObject, -) *InformersMap { - return &InformersMap{ - structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers), - unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers), - metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers), - - Scheme: scheme, - } -} - -// Start calls Run on each of the informers and sets started to true. Blocks on the context. -func (m *InformersMap) Start(ctx context.Context) error { - go m.structured.Start(ctx) - go m.unstructured.Start(ctx) - go m.metadata.Start(ctx) - <-ctx.Done() - return nil -} - -// WaitForCacheSync waits until all the caches have been started and synced. -func (m *InformersMap) WaitForCacheSync(ctx context.Context) bool { - syncedFuncs := append([]cache.InformerSynced(nil), m.structured.HasSyncedFuncs()...) - syncedFuncs = append(syncedFuncs, m.unstructured.HasSyncedFuncs()...) - syncedFuncs = append(syncedFuncs, m.metadata.HasSyncedFuncs()...) - - if !m.structured.waitForStarted(ctx) { - return false - } - if !m.unstructured.waitForStarted(ctx) { - return false - } - if !m.metadata.waitForStarted(ctx) { - return false - } - return cache.WaitForCacheSync(ctx.Done(), syncedFuncs...) -} - -// Get will create a new Informer and add it to the map of InformersMap if none exists. Returns -// the Informer from the map. -func (m *InformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *MapEntry, error) { - switch obj.(type) { - case *unstructured.Unstructured: - return m.unstructured.Get(ctx, gvk, obj) - case *unstructured.UnstructuredList: - return m.unstructured.Get(ctx, gvk, obj) - case *metav1.PartialObjectMetadata: - return m.metadata.Get(ctx, gvk, obj) - case *metav1.PartialObjectMetadataList: - return m.metadata.Get(ctx, gvk, obj) - default: - return m.structured.Get(ctx, gvk, obj) - } -} - -// newStructuredInformersMap creates a new InformersMap for structured objects. -func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createStructuredListWatch) -} - -// newUnstructuredInformersMap creates a new InformersMap for unstructured objects. -func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createUnstructuredListWatch) -} - -// newMetadataInformersMap creates a new InformersMap for metadata-only objects. -func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration, - namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap { - return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createMetadataListWatch) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/disabledeepcopy.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/disabledeepcopy.go deleted file mode 100644 index 54bd7eec938..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/disabledeepcopy.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import "k8s.io/apimachinery/pkg/runtime/schema" - -// GroupVersionKindAll is the argument to represent all GroupVersionKind types. -var GroupVersionKindAll = schema.GroupVersionKind{} - -// DisableDeepCopyByGVK associate a GroupVersionKind to disable DeepCopy during get or list from cache. -type DisableDeepCopyByGVK map[schema.GroupVersionKind]bool - -// IsDisabled returns whether a GroupVersionKind is disabled DeepCopy. -func (disableByGVK DisableDeepCopyByGVK) IsDisabled(gvk schema.GroupVersionKind) bool { - if d, ok := disableByGVK[gvk]; ok { - return d - } else if d, ok = disableByGVK[GroupVersionKindAll]; ok { - return d - } - return false -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go new file mode 100644 index 00000000000..bb3a454f1c4 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go @@ -0,0 +1,615 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" + "fmt" + "math/rand" + "net/http" + "sync" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/metadata" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/internal/syncs" +) + +// InformersOpts configures an InformerMap. +type InformersOpts struct { + HTTPClient *http.Client + Scheme *runtime.Scheme + Mapper meta.RESTMapper + ResyncPeriod time.Duration + Namespace string + ByGVK map[schema.GroupVersionKind]InformersOptsByGVK +} + +// InformersOptsByGVK configured additional by group version kind (or object) +// in an InformerMap. +type InformersOptsByGVK struct { + Selector Selector + Transform cache.TransformFunc + UnsafeDisableDeepCopy *bool +} + +// NewInformers creates a new InformersMap that can create informers under the hood. +func NewInformers(config *rest.Config, options *InformersOpts) *Informers { + return &Informers{ + config: config, + httpClient: options.HTTPClient, + scheme: options.Scheme, + mapper: options.Mapper, + tracker: tracker{ + Structured: make(map[schema.GroupVersionKind]*Cache), + Unstructured: make(map[schema.GroupVersionKind]*Cache), + Metadata: make(map[schema.GroupVersionKind]*Cache), + }, + codecs: serializer.NewCodecFactory(options.Scheme), + paramCodec: runtime.NewParameterCodec(options.Scheme), + resync: options.ResyncPeriod, + startWait: make(chan struct{}), + namespace: options.Namespace, + byGVK: options.ByGVK, + } +} + +// Cache contains the cached data for an Cache. +type Cache struct { + // Informer is the cached informer + Informer cache.SharedIndexInformer + + // CacheReader wraps Informer and implements the CacheReader interface for a single type + Reader CacheReader + + // Stop can be used to stop this individual informer. + stop chan struct{} +} + +// Start starts the informer managed by a MapEntry. +// Blocks until the informer stops. The informer can be stopped +// either individually (via the entry's stop channel) or globally +// via the provided stop argument. +func (c *Cache) Start(stop <-chan struct{}) { + // Stop on either the whole map stopping or just this informer being removed. + internalStop, cancel := syncs.MergeChans(stop, c.stop) + defer cancel() + c.Informer.Run(internalStop) +} + +type tracker struct { + Structured map[schema.GroupVersionKind]*Cache + Unstructured map[schema.GroupVersionKind]*Cache + Metadata map[schema.GroupVersionKind]*Cache +} + +// GetOptions provides configuration to customize the behavior when +// getting an informer. +type GetOptions struct { + // DoNotBlockUntilSynced tells Get() to return the informer immediately, + // without waiting for its cache to sync. + DoNotBlockUntilSynced bool +} + +// InformerGetOption defines an option that alters the behavior of how informers are retrieved. +type InformerGetOption func(*GetOptions) + +// BlockUntilSynced determines whether a get request for an informer should block +// until the informer's cache has synced. +func BlockUntilSynced(shouldBlock bool) InformerGetOption { + return func(opts *GetOptions) { + opts.DoNotBlockUntilSynced = !shouldBlock + } +} + +// Informers create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. +// It uses a standard parameter codec constructed based on the given generated Scheme. +type Informers struct { + // httpClient is used to create a new REST client + httpClient *http.Client + + // scheme maps runtime.Objects to GroupVersionKinds + scheme *runtime.Scheme + + // config is used to talk to the apiserver + config *rest.Config + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper + + // tracker tracks informers keyed by their type and groupVersionKind + tracker tracker + + // codecs is used to create a new REST client + codecs serializer.CodecFactory + + // paramCodec is used by list and watch + paramCodec runtime.ParameterCodec + + // resync is the base frequency the informers are resynced + // a 10 percent jitter will be added to the resync period between informers + // so that all informers will not send list requests simultaneously. + resync time.Duration + + // mu guards access to the map + mu sync.RWMutex + + // started is true if the informers have been started + started bool + + // startWait is a channel that is closed after the + // informer has been started. + startWait chan struct{} + + // waitGroup is the wait group that is used to wait for all informers to stop + waitGroup sync.WaitGroup + + // stopped is true if the informers have been stopped + stopped bool + + // ctx is the context to stop informers + ctx context.Context + + // namespace is the namespace that all ListWatches are restricted to + // default or empty string means all namespaces + namespace string + + byGVK map[schema.GroupVersionKind]InformersOptsByGVK +} + +func (ip *Informers) getSelector(gvk schema.GroupVersionKind) Selector { + if ip.byGVK == nil { + return Selector{} + } + if res, ok := ip.byGVK[gvk]; ok { + return res.Selector + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok { + return res.Selector + } + return Selector{} +} + +func (ip *Informers) getTransform(gvk schema.GroupVersionKind) cache.TransformFunc { + if ip.byGVK == nil { + return nil + } + if res, ok := ip.byGVK[gvk]; ok { + return res.Transform + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok { + return res.Transform + } + return nil +} + +func (ip *Informers) getDisableDeepCopy(gvk schema.GroupVersionKind) bool { + if ip.byGVK == nil { + return false + } + if res, ok := ip.byGVK[gvk]; ok && res.UnsafeDisableDeepCopy != nil { + return *res.UnsafeDisableDeepCopy + } + if res, ok := ip.byGVK[schema.GroupVersionKind{}]; ok && res.UnsafeDisableDeepCopy != nil { + return *res.UnsafeDisableDeepCopy + } + return false +} + +// Start calls Run on each of the informers and sets started to true. Blocks on the context. +// It doesn't return start because it can't return an error, and it's not a runnable directly. +func (ip *Informers) Start(ctx context.Context) error { + func() { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Set the context so it can be passed to informers that are added later + ip.ctx = ctx + + // Start each informer + for _, i := range ip.tracker.Structured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Unstructured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Metadata { + ip.startInformerLocked(i) + } + + // Set started to true so we immediately start any informers added later. + ip.started = true + close(ip.startWait) + }() + <-ctx.Done() // Block until the context is done + ip.mu.Lock() + ip.stopped = true // Set stopped to true so we don't start any new informers + ip.mu.Unlock() + ip.waitGroup.Wait() // Block until all informers have stopped + return nil +} + +func (ip *Informers) startInformerLocked(cacheEntry *Cache) { + // Don't start the informer in case we are already waiting for the items in + // the waitGroup to finish, since waitGroups don't support waiting and adding + // at the same time. + if ip.stopped { + return + } + + ip.waitGroup.Add(1) + go func() { + defer ip.waitGroup.Done() + cacheEntry.Start(ip.ctx.Done()) + }() +} + +func (ip *Informers) waitForStarted(ctx context.Context) bool { + select { + case <-ip.startWait: + return true + case <-ctx.Done(): + return false + } +} + +// getHasSyncedFuncs returns all the HasSynced functions for the informers in this map. +func (ip *Informers) getHasSyncedFuncs() []cache.InformerSynced { + ip.mu.RLock() + defer ip.mu.RUnlock() + + res := make([]cache.InformerSynced, 0, + len(ip.tracker.Structured)+len(ip.tracker.Unstructured)+len(ip.tracker.Metadata), + ) + for _, i := range ip.tracker.Structured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Unstructured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Metadata { + res = append(res, i.Informer.HasSynced) + } + return res +} + +// WaitForCacheSync waits until all the caches have been started and synced. +func (ip *Informers) WaitForCacheSync(ctx context.Context) bool { + if !ip.waitForStarted(ctx) { + return false + } + return cache.WaitForCacheSync(ctx.Done(), ip.getHasSyncedFuncs()...) +} + +func (ip *Informers) get(gvk schema.GroupVersionKind, obj runtime.Object) (res *Cache, started bool, ok bool) { + ip.mu.RLock() + defer ip.mu.RUnlock() + i, ok := ip.informersByType(obj)[gvk] + return i, ip.started, ok +} + +// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns +// the Informer from the map. +func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object, opts ...InformerGetOption) (bool, *Cache, error) { + // Return the informer if it is found + i, started, ok := ip.get(gvk, obj) + if !ok { + var err error + if i, started, err = ip.addInformerToMap(gvk, obj); err != nil { + return started, nil, err + } + } + + cfg := &GetOptions{} + for _, opt := range opts { + opt(cfg) + } + + if started && !i.Informer.HasSynced() && !cfg.DoNotBlockUntilSynced { + // Wait for it to sync before returning the Informer so that folks don't read from a stale cache. + if !cache.WaitForCacheSync(ctx.Done(), i.Informer.HasSynced) { + return started, nil, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0) + } + } + + return started, i, nil +} + +// Remove removes an informer entry and stops it if it was running. +func (ip *Informers) Remove(gvk schema.GroupVersionKind, obj runtime.Object) { + ip.mu.Lock() + defer ip.mu.Unlock() + + informerMap := ip.informersByType(obj) + + entry, ok := informerMap[gvk] + if !ok { + return + } + close(entry.stop) + delete(informerMap, gvk) +} + +func (ip *Informers) informersByType(obj runtime.Object) map[schema.GroupVersionKind]*Cache { + switch obj.(type) { + case runtime.Unstructured: + return ip.tracker.Unstructured + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + return ip.tracker.Metadata + default: + return ip.tracker.Structured + } +} + +func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*Cache, bool, error) { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Check the cache to see if we already have an Informer. If we do, return the Informer. + // This is for the case where 2 routines tried to get the informer when it wasn't in the map + // so neither returned early, but the first one created it. + if i, ok := ip.informersByType(obj)[gvk]; ok { + return i, ip.started, nil + } + + // Create a NewSharedIndexInformer and add it to the map. + listWatcher, err := ip.makeListWatcher(gvk, obj) + if err != nil { + return nil, false, err + } + sharedIndexInformer := cache.NewSharedIndexInformer(&cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + ip.getSelector(gvk).ApplyToList(&opts) + return listWatcher.ListFunc(opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + ip.getSelector(gvk).ApplyToList(&opts) + opts.Watch = true // Watch needs to be set to true separately + return listWatcher.WatchFunc(opts) + }, + }, obj, calculateResyncPeriod(ip.resync), cache.Indexers{ + cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, + }) + + // Check to see if there is a transformer for this gvk + if err := sharedIndexInformer.SetTransform(ip.getTransform(gvk)); err != nil { + return nil, false, err + } + + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, false, err + } + + // Create the new entry and set it in the map. + i := &Cache{ + Informer: sharedIndexInformer, + Reader: CacheReader{ + indexer: sharedIndexInformer.GetIndexer(), + groupVersionKind: gvk, + scopeName: mapping.Scope.Name(), + disableDeepCopy: ip.getDisableDeepCopy(gvk), + }, + stop: make(chan struct{}), + } + ip.informersByType(obj)[gvk] = i + + // Start the informer in case the InformersMap has started, otherwise it will be + // started when the InformersMap starts. + if ip.started { + ip.startInformerLocked(i) + } + return i, ip.started, nil +} + +func (ip *Informers) makeListWatcher(gvk schema.GroupVersionKind, obj runtime.Object) (*cache.ListWatch, error) { + // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the + // groupVersionKind to the Resource API we will use. + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + + // Figure out if the GVK we're dealing with is global, or namespace scoped. + var namespace string + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + namespace = restrictNamespaceBySelector(ip.namespace, ip.getSelector(gvk)) + } + + switch obj.(type) { + // + // Unstructured + // + case runtime.Unstructured: + // If the rest configuration has a negotiated serializer passed in, + // we should remove it and use the one that the dynamic client sets for us. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + dynamicClient, err := dynamic.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := dynamicClient.Resource(mapping.Resource) + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + if namespace != "" { + return resources.Namespace(namespace).List(ip.ctx, opts) + } + return resources.List(ip.ctx, opts) + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + if namespace != "" { + return resources.Namespace(namespace).Watch(ip.ctx, opts) + } + return resources.Watch(ip.ctx, opts) + }, + }, nil + // + // Metadata + // + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + // Always clear the negotiated serializer and use the one + // set from the metadata client. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + + // Grab the metadata metadataClient. + metadataClient, err := metadata.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := metadataClient.Resource(mapping.Resource) + + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + var ( + list *metav1.PartialObjectMetadataList + err error + ) + if namespace != "" { + list, err = resources.Namespace(namespace).List(ip.ctx, opts) + } else { + list, err = resources.List(ip.ctx, opts) + } + if list != nil { + for i := range list.Items { + list.Items[i].SetGroupVersionKind(gvk) + } + } + return list, err + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watcher watch.Interface, err error) { + if namespace != "" { + watcher, err = resources.Namespace(namespace).Watch(ip.ctx, opts) + } else { + watcher, err = resources.Watch(ip.ctx, opts) + } + if err != nil { + return nil, err + } + return newGVKFixupWatcher(gvk, watcher), nil + }, + }, nil + // + // Structured. + // + default: + client, err := apiutil.RESTClientForGVK(gvk, false, ip.config, ip.codecs, ip.httpClient) + if err != nil { + return nil, err + } + listGVK := gvk.GroupVersion().WithKind(gvk.Kind + "List") + listObj, err := ip.scheme.New(listGVK) + if err != nil { + return nil, err + } + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + + // Create the resulting object, and execute the request. + res := listObj.DeepCopyObject() + if err := req.Do(ip.ctx).Into(res); err != nil { + return nil, err + } + return res, nil + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + // Call the watch. + return req.Watch(ip.ctx) + }, + }, nil + } +} + +// newGVKFixupWatcher adds a wrapper that preserves the GVK information when +// events come in. +// +// This works around a bug where GVK information is not passed into mapping +// functions when using the OnlyMetadata option in the builder. +// This issue is most likely caused by kubernetes/kubernetes#80609. +// See kubernetes-sigs/controller-runtime#1484. +// +// This was originally implemented as a cache.ResourceEventHandler wrapper but +// that contained a data race which was resolved by setting the GVK in a watch +// wrapper, before the objects are written to the cache. +// See kubernetes-sigs/controller-runtime#1650. +// +// The original watch wrapper was found to be incompatible with +// k8s.io/client-go/tools/cache.Reflector so it has been re-implemented as a +// watch.Filter which is compatible. +// See kubernetes-sigs/controller-runtime#1789. +func newGVKFixupWatcher(gvk schema.GroupVersionKind, watcher watch.Interface) watch.Interface { + return watch.Filter( + watcher, + func(in watch.Event) (watch.Event, bool) { + in.Object.GetObjectKind().SetGroupVersionKind(gvk) + return in, true + }, + ) +} + +// calculateResyncPeriod returns a duration based on the desired input +// this is so that multiple controllers don't get into lock-step and all +// hammer the apiserver with list requests simultaneously. +func calculateResyncPeriod(resync time.Duration) time.Duration { + // the factor will fall into [0.9, 1.1) + factor := rand.Float64()/5.0 + 0.9 //nolint:gosec + return time.Duration(float64(resync.Nanoseconds()) * factor) +} + +// restrictNamespaceBySelector returns either a global restriction for all ListWatches +// if not default/empty, or the namespace that a ListWatch for the specific resource +// is restricted to, based on a specified field selector for metadata.namespace field. +func restrictNamespaceBySelector(namespaceOpt string, s Selector) string { + if namespaceOpt != "" { + // namespace is already restricted + return namespaceOpt + } + fieldSelector := s.Field + if fieldSelector == nil || fieldSelector.Empty() { + return "" + } + // check whether a selector includes the namespace field + value, found := fieldSelector.RequiresExactMatch("metadata.namespace") + if found { + return value + } + return "" +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go deleted file mode 100644 index 1524d2316f5..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go +++ /dev/null @@ -1,480 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import ( - "context" - "fmt" - "math/rand" - "sync" - "time" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/metadata" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" - - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -// clientListWatcherFunc knows how to create a ListWatcher. -type createListWatcherFunc func(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) - -// newSpecificInformersMap returns a new specificInformersMap (like -// the generical InformersMap, except that it doesn't implement WaitForCacheSync). -func newSpecificInformersMap(config *rest.Config, - scheme *runtime.Scheme, - mapper meta.RESTMapper, - resync time.Duration, - namespace string, - selectors SelectorsByGVK, - disableDeepCopy DisableDeepCopyByGVK, - transformers TransformFuncByObject, - createListWatcher createListWatcherFunc, -) *specificInformersMap { - ip := &specificInformersMap{ - config: config, - Scheme: scheme, - mapper: mapper, - informersByGVK: make(map[schema.GroupVersionKind]*MapEntry), - codecs: serializer.NewCodecFactory(scheme), - paramCodec: runtime.NewParameterCodec(scheme), - resync: resync, - startWait: make(chan struct{}), - createListWatcher: createListWatcher, - namespace: namespace, - selectors: selectors.forGVK, - disableDeepCopy: disableDeepCopy, - transformers: transformers, - } - return ip -} - -// MapEntry contains the cached data for an Informer. -type MapEntry struct { - // Informer is the cached informer - Informer cache.SharedIndexInformer - - // CacheReader wraps Informer and implements the CacheReader interface for a single type - Reader CacheReader -} - -// specificInformersMap create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. -// It uses a standard parameter codec constructed based on the given generated Scheme. -type specificInformersMap struct { - // Scheme maps runtime.Objects to GroupVersionKinds - Scheme *runtime.Scheme - - // config is used to talk to the apiserver - config *rest.Config - - // mapper maps GroupVersionKinds to Resources - mapper meta.RESTMapper - - // informersByGVK is the cache of informers keyed by groupVersionKind - informersByGVK map[schema.GroupVersionKind]*MapEntry - - // codecs is used to create a new REST client - codecs serializer.CodecFactory - - // paramCodec is used by list and watch - paramCodec runtime.ParameterCodec - - // stop is the stop channel to stop informers - stop <-chan struct{} - - // resync is the base frequency the informers are resynced - // a 10 percent jitter will be added to the resync period between informers - // so that all informers will not send list requests simultaneously. - resync time.Duration - - // mu guards access to the map - mu sync.RWMutex - - // start is true if the informers have been started - started bool - - // startWait is a channel that is closed after the - // informer has been started. - startWait chan struct{} - - // createClient knows how to create a client and a list object, - // and allows for abstracting over the particulars of structured vs - // unstructured objects. - createListWatcher createListWatcherFunc - - // namespace is the namespace that all ListWatches are restricted to - // default or empty string means all namespaces - namespace string - - // selectors are the label or field selectors that will be added to the - // ListWatch ListOptions. - selectors func(gvk schema.GroupVersionKind) Selector - - // disableDeepCopy indicates not to deep copy objects during get or list objects. - disableDeepCopy DisableDeepCopyByGVK - - // transform funcs are applied to objects before they are committed to the cache - transformers TransformFuncByObject -} - -// Start calls Run on each of the informers and sets started to true. Blocks on the context. -// It doesn't return start because it can't return an error, and it's not a runnable directly. -func (ip *specificInformersMap) Start(ctx context.Context) { - func() { - ip.mu.Lock() - defer ip.mu.Unlock() - - // Set the stop channel so it can be passed to informers that are added later - ip.stop = ctx.Done() - - // Start each informer - for _, informer := range ip.informersByGVK { - go informer.Informer.Run(ctx.Done()) - } - - // Set started to true so we immediately start any informers added later. - ip.started = true - close(ip.startWait) - }() - <-ctx.Done() -} - -func (ip *specificInformersMap) waitForStarted(ctx context.Context) bool { - select { - case <-ip.startWait: - return true - case <-ctx.Done(): - return false - } -} - -// HasSyncedFuncs returns all the HasSynced functions for the informers in this map. -func (ip *specificInformersMap) HasSyncedFuncs() []cache.InformerSynced { - ip.mu.RLock() - defer ip.mu.RUnlock() - syncedFuncs := make([]cache.InformerSynced, 0, len(ip.informersByGVK)) - for _, informer := range ip.informersByGVK { - syncedFuncs = append(syncedFuncs, informer.Informer.HasSynced) - } - return syncedFuncs -} - -// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns -// the Informer from the map. -func (ip *specificInformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *MapEntry, error) { - // Return the informer if it is found - i, started, ok := func() (*MapEntry, bool, bool) { - ip.mu.RLock() - defer ip.mu.RUnlock() - i, ok := ip.informersByGVK[gvk] - return i, ip.started, ok - }() - - if !ok { - var err error - if i, started, err = ip.addInformerToMap(gvk, obj); err != nil { - return started, nil, err - } - } - - if started && !i.Informer.HasSynced() { - // Wait for it to sync before returning the Informer so that folks don't read from a stale cache. - if !cache.WaitForCacheSync(ctx.Done(), i.Informer.HasSynced) { - return started, nil, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0) - } - } - - return started, i, nil -} - -func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*MapEntry, bool, error) { - ip.mu.Lock() - defer ip.mu.Unlock() - - // Check the cache to see if we already have an Informer. If we do, return the Informer. - // This is for the case where 2 routines tried to get the informer when it wasn't in the map - // so neither returned early, but the first one created it. - if i, ok := ip.informersByGVK[gvk]; ok { - return i, ip.started, nil - } - - // Create a NewSharedIndexInformer and add it to the map. - var lw *cache.ListWatch - lw, err := ip.createListWatcher(gvk, ip) - if err != nil { - return nil, false, err - } - ni := cache.NewSharedIndexInformer(lw, obj, resyncPeriod(ip.resync)(), cache.Indexers{ - cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, - }) - - // Check to see if there is a transformer for this gvk - if err := ni.SetTransform(ip.transformers.Get(gvk)); err != nil { - return nil, false, err - } - - rm, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, false, err - } - - i := &MapEntry{ - Informer: ni, - Reader: CacheReader{ - indexer: ni.GetIndexer(), - groupVersionKind: gvk, - scopeName: rm.Scope.Name(), - disableDeepCopy: ip.disableDeepCopy.IsDisabled(gvk), - }, - } - ip.informersByGVK[gvk] = i - - // Start the Informer if need by - // TODO(seans): write thorough tests and document what happens here - can you add indexers? - // can you add eventhandlers? - if ip.started { - go i.Informer.Run(ip.stop) - } - return i, ip.started, nil -} - -// newListWatch returns a new ListWatch object that can be used to create a SharedIndexInformer. -func createStructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - client, err := apiutil.RESTClientForGVK(gvk, false, ip.config, ip.codecs) - if err != nil { - return nil, err - } - listGVK := gvk.GroupVersion().WithKind(gvk.Kind + "List") - listObj, err := ip.Scheme.New(listGVK) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - // Create a new ListWatch for the obj - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors(gvk).ApplyToList(&opts) - res := listObj.DeepCopyObject() - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - isNamespaceScoped := namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot - err := client.Get().NamespaceIfScoped(namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Do(ctx).Into(res) - return res, err - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors(gvk).ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - isNamespaceScoped := namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot - return client.Get().NamespaceIfScoped(namespace, isNamespaceScoped).Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec).Watch(ctx) - }, - }, nil -} - -func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - // If the rest configuration has a negotiated serializer passed in, - // we should remove it and use the one that the dynamic client sets for us. - cfg := rest.CopyConfig(ip.config) - cfg.NegotiatedSerializer = nil - dynamicClient, err := dynamic.NewForConfig(cfg) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - // Create a new ListWatch for the obj - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors(gvk).ApplyToList(&opts) - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return dynamicClient.Resource(mapping.Resource).Namespace(namespace).List(ctx, opts) - } - return dynamicClient.Resource(mapping.Resource).List(ctx, opts) - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors(gvk).ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - return dynamicClient.Resource(mapping.Resource).Namespace(namespace).Watch(ctx, opts) - } - return dynamicClient.Resource(mapping.Resource).Watch(ctx, opts) - }, - }, nil -} - -func createMetadataListWatch(gvk schema.GroupVersionKind, ip *specificInformersMap) (*cache.ListWatch, error) { - // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the - // groupVersionKind to the Resource API we will use. - mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - - // Always clear the negotiated serializer and use the one - // set from the metadata client. - cfg := rest.CopyConfig(ip.config) - cfg.NegotiatedSerializer = nil - - // grab the metadata client - client, err := metadata.NewForConfig(cfg) - if err != nil { - return nil, err - } - - // TODO: the functions that make use of this ListWatch should be adapted to - // pass in their own contexts instead of relying on this fixed one here. - ctx := context.TODO() - - // create the relevant listwatch - return &cache.ListWatch{ - ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - ip.selectors(gvk).ApplyToList(&opts) - - var ( - list *metav1.PartialObjectMetadataList - err error - ) - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - list, err = client.Resource(mapping.Resource).Namespace(namespace).List(ctx, opts) - } else { - list, err = client.Resource(mapping.Resource).List(ctx, opts) - } - if list != nil { - for i := range list.Items { - list.Items[i].SetGroupVersionKind(gvk) - } - } - return list, err - }, - // Setup the watch function - WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { - ip.selectors(gvk).ApplyToList(&opts) - // Watch needs to be set to true separately - opts.Watch = true - - var ( - watcher watch.Interface - err error - ) - namespace := restrictNamespaceBySelector(ip.namespace, ip.selectors(gvk)) - if namespace != "" && mapping.Scope.Name() != meta.RESTScopeNameRoot { - watcher, err = client.Resource(mapping.Resource).Namespace(namespace).Watch(ctx, opts) - } else { - watcher, err = client.Resource(mapping.Resource).Watch(ctx, opts) - } - if watcher != nil { - watcher = newGVKFixupWatcher(gvk, watcher) - } - return watcher, err - }, - }, nil -} - -// newGVKFixupWatcher adds a wrapper that preserves the GVK information when -// events come in. -// -// This works around a bug where GVK information is not passed into mapping -// functions when using the OnlyMetadata option in the builder. -// This issue is most likely caused by kubernetes/kubernetes#80609. -// See kubernetes-sigs/controller-runtime#1484. -// -// This was originally implemented as a cache.ResourceEventHandler wrapper but -// that contained a data race which was resolved by setting the GVK in a watch -// wrapper, before the objects are written to the cache. -// See kubernetes-sigs/controller-runtime#1650. -// -// The original watch wrapper was found to be incompatible with -// k8s.io/client-go/tools/cache.Reflector so it has been re-implemented as a -// watch.Filter which is compatible. -// See kubernetes-sigs/controller-runtime#1789. -func newGVKFixupWatcher(gvk schema.GroupVersionKind, watcher watch.Interface) watch.Interface { - return watch.Filter( - watcher, - func(in watch.Event) (watch.Event, bool) { - in.Object.GetObjectKind().SetGroupVersionKind(gvk) - return in, true - }, - ) -} - -// resyncPeriod returns a function which generates a duration each time it is -// invoked; this is so that multiple controllers don't get into lock-step and all -// hammer the apiserver with list requests simultaneously. -func resyncPeriod(resync time.Duration) func() time.Duration { - return func() time.Duration { - // the factor will fall into [0.9, 1.1) - factor := rand.Float64()/5.0 + 0.9 //nolint:gosec - return time.Duration(float64(resync.Nanoseconds()) * factor) - } -} - -// restrictNamespaceBySelector returns either a global restriction for all ListWatches -// if not default/empty, or the namespace that a ListWatch for the specific resource -// is restricted to, based on a specified field selector for metadata.namespace field. -func restrictNamespaceBySelector(namespaceOpt string, s Selector) string { - if namespaceOpt != "" { - // namespace is already restricted - return namespaceOpt - } - fieldSelector := s.Field - if fieldSelector == nil || fieldSelector.Empty() { - return "" - } - // check whether a selector includes the namespace field - value, found := fieldSelector.RequiresExactMatch("metadata.namespace") - if found { - return value - } - return "" -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go index 4eff32fb35d..c674379b992 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go @@ -20,23 +20,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime/schema" ) -// SelectorsByGVK associate a GroupVersionKind to a field/label selector. -type SelectorsByGVK map[schema.GroupVersionKind]Selector - -func (s SelectorsByGVK) forGVK(gvk schema.GroupVersionKind) Selector { - if specific, found := s[gvk]; found { - return specific - } - if defaultSelector, found := s[schema.GroupVersionKind{}]; found { - return defaultSelector - } - - return Selector{} -} - // Selector specify the label/field selector to fill in ListOptions. type Selector struct { Label labels.Selector diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go index 8cf642c4bd5..0725f550c5e 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go @@ -4,12 +4,13 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) -// TransformFuncByObject provides access to the correct transform function for +// TransformFuncByGVK provides access to the correct transform function for // any given GVK. -type TransformFuncByObject interface { +type TransformFuncByGVK interface { Set(runtime.Object, *runtime.Scheme, cache.TransformFunc) error Get(schema.GroupVersionKind) cache.TransformFunc SetDefault(transformer cache.TransformFunc) @@ -20,12 +21,16 @@ type transformFuncByGVK struct { transformers map[schema.GroupVersionKind]cache.TransformFunc } -// NewTransformFuncByObject creates a new TransformFuncByObject instance. -func NewTransformFuncByObject() TransformFuncByObject { - return &transformFuncByGVK{ - transformers: make(map[schema.GroupVersionKind]cache.TransformFunc), - defaultTransform: nil, +// TransformFuncByGVKFromMap creates a TransformFuncByGVK from a map that +// maps GVKs to TransformFuncs. +func TransformFuncByGVKFromMap(in map[schema.GroupVersionKind]cache.TransformFunc) TransformFuncByGVK { + byGVK := &transformFuncByGVK{} + if defaultFunc, hasDefault := in[schema.GroupVersionKind{}]; hasDefault { + byGVK.defaultTransform = defaultFunc } + delete(in, schema.GroupVersionKind{}) + byGVK.transformers = in + return byGVK } func (t *transformFuncByGVK) SetDefault(transformer cache.TransformFunc) { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go index 47a5bb3b3f7..ff617beab0c 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go @@ -28,12 +28,9 @@ import ( "k8s.io/client-go/rest" toolscache "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/internal/objectutil" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) -// NewCacheFunc - Function for creating a new cache from the options and a rest config. -type NewCacheFunc func(config *rest.Config, opts Options) (Cache, error) - // a new global namespaced cache to handle cluster scoped resources. const globalCache = "_cluster-scope" @@ -43,31 +40,43 @@ const globalCache = "_cluster-scope" // a global cache for cluster scoped resource. Note that this is not intended // to be used for excluding namespaces, this is better done via a Predicate. Also note that // you may face performance issues when using this with a high number of namespaces. +// +// Deprecated: Use cache.Options.Namespaces instead. func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { return func(config *rest.Config, opts Options) (Cache, error) { - opts, err := defaultOpts(config, opts) - if err != nil { - return nil, err - } + opts.Namespaces = namespaces + return newMultiNamespaceCache(config, opts) + } +} - caches := map[string]Cache{} +func newMultiNamespaceCache(config *rest.Config, opts Options) (Cache, error) { + if len(opts.Namespaces) < 2 { + return nil, fmt.Errorf("must specify more than one namespace to use multi-namespace cache") + } + opts, err := defaultOpts(config, opts) + if err != nil { + return nil, err + } - // create a cache for cluster scoped resources - gCache, err := New(config, opts) + // Create every namespace cache. + caches := map[string]Cache{} + for _, ns := range opts.Namespaces { + opts.Namespaces = []string{ns} + c, err := New(config, opts) if err != nil { - return nil, fmt.Errorf("error creating global cache: %w", err) + return nil, err } + caches[ns] = c + } - for _, ns := range namespaces { - opts.Namespace = ns - c, err := New(config, opts) - if err != nil { - return nil, err - } - caches[ns] = c - } - return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil + // Create a cache for cluster scoped resources. + opts.Namespaces = []string{} + gCache, err := New(config, opts) + if err != nil { + return nil, fmt.Errorf("error creating global cache: %w", err) } + + return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil } // multiNamespaceCache knows how to handle multiple namespaced caches @@ -84,17 +93,17 @@ type multiNamespaceCache struct { var _ Cache = &multiNamespaceCache{} // Methods for multiNamespaceCache to conform to the Informers interface. -func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object) (Informer, error) { +func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { informers := map[string]Informer{} // If the object is clusterscoped, get the informer from clusterCache, // if not use the namespaced caches. - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) if err != nil { return nil, err } if !isNamespaced { - clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj) + clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj, opts...) if err != nil { return nil, err } @@ -114,17 +123,17 @@ func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object return &multiNamespaceInformer{namespaceToInformer: informers}, nil } -func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind) (Informer, error) { +func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { informers := map[string]Informer{} // If the object is clusterscoped, get the informer from clusterCache, // if not use the namespaced caches. - isNamespaced, err := objectutil.IsAPINamespacedWithGVK(gvk, c.Scheme, c.RESTMapper) + isNamespaced, err := apiutil.IsGVKNamespaced(gvk, c.RESTMapper) if err != nil { return nil, err } if !isNamespaced { - clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk) + clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk, opts...) if err != nil { return nil, err } @@ -134,7 +143,7 @@ func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema } for ns, cache := range c.namespaceToCache { - informer, err := cache.GetInformerForKind(ctx, gvk) + informer, err := cache.GetInformerForKind(ctx, gvk, opts...) if err != nil { return nil, err } @@ -183,9 +192,9 @@ func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool { } func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) if err != nil { - return nil //nolint:nilerr + return err } if !isNamespaced { @@ -200,8 +209,8 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, return nil } -func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error { - isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper) +func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) if err != nil { return err } @@ -223,7 +232,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, listOpts := client.ListOptions{} listOpts.ApplyOptions(opts) - isNamespaced, err := objectutil.IsAPINamespaced(list, c.Scheme, c.RESTMapper) + isNamespaced, err := apiutil.IsObjectNamespaced(list, c.Scheme, c.RESTMapper) if err != nil { return err } @@ -293,20 +302,71 @@ type multiNamespaceInformer struct { namespaceToInformer map[string]Informer } +type handlerRegistration struct { + handles map[string]toolscache.ResourceEventHandlerRegistration +} + +type syncer interface { + HasSynced() bool +} + +// HasSynced asserts that the handler has been called for the full initial state of the informer. +// This uses syncer to be compatible between client-go 1.27+ and older versions when the interface changed. +func (h handlerRegistration) HasSynced() bool { + for _, reg := range h.handles { + if s, ok := reg.(syncer); ok { + if !s.HasSynced() { + return false + } + } + } + return true +} + var _ Informer = &multiNamespaceInformer{} // AddEventHandler adds the handler to each namespaced informer. -func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) { - for _, informer := range i.namespaceToInformer { - informer.AddEventHandler(handler) +func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))} + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandler(handler) + if err != nil { + return nil, err + } + handles.handles[ns] = registration } + return handles, nil } // AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer. -func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) { - for _, informer := range i.namespaceToInformer { - informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod) +func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))} + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod) + if err != nil { + return nil, err + } + handles.handles[ns] = registration + } + return handles, nil +} + +// RemoveEventHandler removes a formerly added event handler given by its registration handle. +func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error { + handles, ok := h.(handlerRegistration) + if !ok { + return fmt.Errorf("it is not the registration returned by multiNamespaceInformer") } + for ns, informer := range i.namespaceToInformer { + registration, ok := handles.handles[ns] + if !ok { + continue + } + if err := informer.RemoveEventHandler(registration); err != nil { + return err + } + } + return nil } // AddIndexers adds the indexer for each namespaced informer. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go index 1030013db3a..2b9b60d8d77 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go @@ -19,9 +19,14 @@ package certwatcher import ( "context" "crypto/tls" + "fmt" "sync" + "time" "github.com/fsnotify/fsnotify" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics" logf "sigs.k8s.io/controller-runtime/pkg/internal/log" ) @@ -39,6 +44,9 @@ type CertWatcher struct { certPath string keyPath string + + // callback is a function to be invoked when the certificate changes. + callback func(tls.Certificate) } // New returns a new CertWatcher watching the given certificate and key. @@ -63,6 +71,17 @@ func New(certPath, keyPath string) (*CertWatcher, error) { return cw, nil } +// RegisterCallback registers a callback to be invoked when the certificate changes. +func (cw *CertWatcher) RegisterCallback(callback func(tls.Certificate)) { + cw.Lock() + defer cw.Unlock() + // If the current certificate is not nil, invoke the callback immediately. + if cw.currentCert != nil { + callback(*cw.currentCert) + } + cw.callback = callback +} + // GetCertificate fetches the currently loaded certificate, which may be nil. func (cw *CertWatcher) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { cw.RLock() @@ -72,11 +91,22 @@ func (cw *CertWatcher) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, // Start starts the watch on the certificate and key files. func (cw *CertWatcher) Start(ctx context.Context) error { - files := []string{cw.certPath, cw.keyPath} - - for _, f := range files { - if err := cw.watcher.Add(f); err != nil { - return err + files := sets.New(cw.certPath, cw.keyPath) + + { + var watchErr error + if err := wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, func(ctx context.Context) (done bool, err error) { + for _, f := range files.UnsortedList() { + if err := cw.watcher.Add(f); err != nil { + watchErr = err + return false, nil //nolint:nilerr // We want to keep trying. + } + // We've added the watch, remove it from the set. + files.Delete(f) + } + return true, nil + }); err != nil { + return fmt.Errorf("failed to add watches: %w", kerrors.NewAggregate([]error{err, watchErr})) } } @@ -130,6 +160,14 @@ func (cw *CertWatcher) ReadCertificate() error { log.Info("Updated current TLS certificate") + // If a callback is registered, invoke it with the new certificate. + cw.RLock() + defer cw.RUnlock() + if cw.callback != nil { + go func() { + cw.callback(cert) + }() + } return nil } @@ -154,13 +192,13 @@ func (cw *CertWatcher) handleEvent(event fsnotify.Event) { } func isWrite(event fsnotify.Event) bool { - return event.Op&fsnotify.Write == fsnotify.Write + return event.Op.Has(fsnotify.Write) } func isCreate(event fsnotify.Event) bool { - return event.Op&fsnotify.Create == fsnotify.Create + return event.Op.Has(fsnotify.Create) } func isRemove(event fsnotify.Event) bool { - return event.Op&fsnotify.Remove == fsnotify.Remove + return event.Op.Has(fsnotify.Remove) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go index c92b0eaaecb..6a1bfb546ea 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go @@ -20,7 +20,9 @@ limitations under the License. package apiutil import ( + "errors" "fmt" + "net/http" "reflect" "sync" @@ -30,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" @@ -59,9 +62,13 @@ func AddToProtobufScheme(addToScheme func(*runtime.Scheme) error) error { // NewDiscoveryRESTMapper constructs a new RESTMapper based on discovery // information fetched by a new client with the given config. -func NewDiscoveryRESTMapper(c *rest.Config) (meta.RESTMapper, error) { +func NewDiscoveryRESTMapper(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + // Get a mapper - dc, err := discovery.NewDiscoveryClientForConfig(c) + dc, err := discovery.NewDiscoveryClientForConfigAndClient(c, httpClient) if err != nil { return nil, err } @@ -72,6 +79,36 @@ func NewDiscoveryRESTMapper(c *rest.Config) (meta.RESTMapper, error) { return restmapper.NewDiscoveryRESTMapper(gr), nil } +// IsObjectNamespaced returns true if the object is namespace scoped. +// For unstructured objects the gvk is found from the object itself. +func IsObjectNamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper meta.RESTMapper) (bool, error) { + gvk, err := GVKForObject(obj, scheme) + if err != nil { + return false, err + } + + return IsGVKNamespaced(gvk, restmapper) +} + +// IsGVKNamespaced returns true if the object having the provided +// GVK is namespace scoped. +func IsGVKNamespaced(gvk schema.GroupVersionKind, restmapper meta.RESTMapper) (bool, error) { + restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}) + if err != nil { + return false, fmt.Errorf("failed to get restmapping: %w", err) + } + + scope := restmapping.Scope.Name() + if scope == "" { + return false, errors.New("scope cannot be identified, empty scope returned") + } + + if scope != meta.RESTScopeNameRoot { + return true, nil + } + return false, nil +} + // GVKForObject finds the GroupVersionKind associated with the given object, if there is only a single such GVK. func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersionKind, error) { // TODO(directxman12): do we want to generalize this to arbitrary container types? @@ -81,7 +118,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi // (unstructured, partial, etc) // check for PartialObjectMetadata, which is analogous to unstructured, but isn't handled by ObjectKinds - _, isPartial := obj.(*metav1.PartialObjectMetadata) //nolint:ifshort + _, isPartial := obj.(*metav1.PartialObjectMetadata) _, isPartialList := obj.(*metav1.PartialObjectMetadataList) if isPartial || isPartialList { // we require that the GVK be populated in order to recognize the object @@ -95,6 +132,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi return gvk, nil } + // Use the given scheme to retrieve all the GVKs for the object. gvks, isUnversioned, err := scheme.ObjectKinds(obj) if err != nil { return schema.GroupVersionKind{}, err @@ -103,36 +141,49 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi return schema.GroupVersionKind{}, fmt.Errorf("cannot create group-version-kind for unversioned type %T", obj) } - if len(gvks) < 1 { - return schema.GroupVersionKind{}, fmt.Errorf("no group-version-kinds associated with type %T", obj) - } - if len(gvks) > 1 { - // this should only trigger for things like metav1.XYZ -- - // normal versioned types should be fine + switch { + case len(gvks) < 1: + // If the object has no GVK, the object might not have been registered with the scheme. + // or it's not a valid object. + return schema.GroupVersionKind{}, fmt.Errorf("no GroupVersionKind associated with Go type %T, was the type registered with the Scheme?", obj) + case len(gvks) > 1: + err := fmt.Errorf("multiple GroupVersionKinds associated with Go type %T within the Scheme, this can happen when a type is registered for multiple GVKs at the same time", obj) + + // We've found multiple GVKs for the object. + currentGVK := obj.GetObjectKind().GroupVersionKind() + if !currentGVK.Empty() { + // If the base object has a GVK, check if it's in the list of GVKs before using it. + for _, gvk := range gvks { + if gvk == currentGVK { + return gvk, nil + } + } + + return schema.GroupVersionKind{}, fmt.Errorf( + "%w: the object's supplied GroupVersionKind %q was not found in the Scheme's list; refusing to guess at one: %q", err, currentGVK, gvks) + } + + // This should only trigger for things like metav1.XYZ -- + // normal versioned types should be fine. + // + // See https://github.com/kubernetes-sigs/controller-runtime/issues/362 + // for more information. return schema.GroupVersionKind{}, fmt.Errorf( - "multiple group-version-kinds associated with type %T, refusing to guess at one", obj) + "%w: callers can either fix their type registration to only register it once, or specify the GroupVersionKind to use for object passed in; refusing to guess at one: %q", err, gvks) + default: + // In any other case, we've found a single GVK for the object. + return gvks[0], nil } - return gvks[0], nil } // RESTClientForGVK constructs a new rest.Interface capable of accessing the resource associated // with the given GroupVersionKind. The REST client will be configured to use the negotiated serializer from // baseConfig, if set, otherwise a default serializer will be set. -func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) (rest.Interface, error) { - return rest.RESTClientFor(createRestConfig(gvk, isUnstructured, baseConfig, codecs)) -} - -// serializerWithDecodedGVK is a CodecFactory that overrides the DecoderToVersion of a WithoutConversionCodecFactory -// in order to avoid clearing the GVK from the decoded object. -// -// See https://github.com/kubernetes/kubernetes/issues/80609. -type serializerWithDecodedGVK struct { - serializer.WithoutConversionCodecFactory -} - -// DecoderToVersion returns an decoder that does not do conversion. -func (f serializerWithDecodedGVK) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder { - return serializer +func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory, httpClient *http.Client) (rest.Interface, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + return rest.RESTClientForConfigAndClient(createRestConfig(gvk, isUnstructured, baseConfig, codecs), httpClient) } // createRestConfig copies the base config and updates needed fields for a new rest config. @@ -159,9 +210,8 @@ func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConf } if isUnstructured { - // If the object is unstructured, we need to preserve the GVK information. - // Use our own custom serializer. - cfg.NegotiatedSerializer = serializerWithDecodedGVK{serializer.WithoutConversionCodecFactory{CodecFactory: codecs}} + // If the object is unstructured, we use the client-go dynamic serializer. + cfg = dynamic.ConfigFor(cfg) } else { cfg.NegotiatedSerializer = serializerWithTargetZeroingDecode{NegotiatedSerializer: serializer.WithoutConversionCodecFactory{CodecFactory: codecs}} } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/dynamicrestmapper.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/dynamicrestmapper.go deleted file mode 100644 index e6cc51c6e91..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/dynamicrestmapper.go +++ /dev/null @@ -1,294 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package apiutil - -import ( - "errors" - "sync" - "sync/atomic" - - "golang.org/x/time/rate" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - "k8s.io/client-go/rest" - "k8s.io/client-go/restmapper" -) - -// dynamicRESTMapper is a RESTMapper that dynamically discovers resource -// types at runtime. -type dynamicRESTMapper struct { - mu sync.RWMutex // protects the following fields - staticMapper meta.RESTMapper - limiter *rate.Limiter - newMapper func() (meta.RESTMapper, error) - - lazy bool - // Used for lazy init. - inited uint32 - initMtx sync.Mutex -} - -// DynamicRESTMapperOption is a functional option on the dynamicRESTMapper. -type DynamicRESTMapperOption func(*dynamicRESTMapper) error - -// WithLimiter sets the RESTMapper's underlying limiter to lim. -func WithLimiter(lim *rate.Limiter) DynamicRESTMapperOption { - return func(drm *dynamicRESTMapper) error { - drm.limiter = lim - return nil - } -} - -// WithLazyDiscovery prevents the RESTMapper from discovering REST mappings -// until an API call is made. -var WithLazyDiscovery DynamicRESTMapperOption = func(drm *dynamicRESTMapper) error { - drm.lazy = true - return nil -} - -// WithCustomMapper supports setting a custom RESTMapper refresher instead of -// the default method, which uses a discovery client. -// -// This exists mainly for testing, but can be useful if you need tighter control -// over how discovery is performed, which discovery endpoints are queried, etc. -func WithCustomMapper(newMapper func() (meta.RESTMapper, error)) DynamicRESTMapperOption { - return func(drm *dynamicRESTMapper) error { - drm.newMapper = newMapper - return nil - } -} - -// NewDynamicRESTMapper returns a dynamic RESTMapper for cfg. The dynamic -// RESTMapper dynamically discovers resource types at runtime. opts -// configure the RESTMapper. -func NewDynamicRESTMapper(cfg *rest.Config, opts ...DynamicRESTMapperOption) (meta.RESTMapper, error) { - client, err := discovery.NewDiscoveryClientForConfig(cfg) - if err != nil { - return nil, err - } - drm := &dynamicRESTMapper{ - limiter: rate.NewLimiter(rate.Limit(defaultRefillRate), defaultLimitSize), - newMapper: func() (meta.RESTMapper, error) { - groupResources, err := restmapper.GetAPIGroupResources(client) - if err != nil { - return nil, err - } - return restmapper.NewDiscoveryRESTMapper(groupResources), nil - }, - } - for _, opt := range opts { - if err = opt(drm); err != nil { - return nil, err - } - } - if !drm.lazy { - if err := drm.setStaticMapper(); err != nil { - return nil, err - } - } - return drm, nil -} - -var ( - // defaultRefilRate is the default rate at which potential calls are - // added back to the "bucket" of allowed calls. - defaultRefillRate = 5 - // defaultLimitSize is the default starting/max number of potential calls - // per second. Once a call is used, it's added back to the bucket at a rate - // of defaultRefillRate per second. - defaultLimitSize = 5 -) - -// setStaticMapper sets drm's staticMapper by querying its client, regardless -// of reload backoff. -func (drm *dynamicRESTMapper) setStaticMapper() error { - newMapper, err := drm.newMapper() - if err != nil { - return err - } - drm.staticMapper = newMapper - return nil -} - -// init initializes drm only once if drm is lazy. -func (drm *dynamicRESTMapper) init() (err error) { - // skip init if drm is not lazy or has initialized - if !drm.lazy || atomic.LoadUint32(&drm.inited) != 0 { - return nil - } - - drm.initMtx.Lock() - defer drm.initMtx.Unlock() - if drm.inited == 0 { - if err = drm.setStaticMapper(); err == nil { - atomic.StoreUint32(&drm.inited, 1) - } - } - return err -} - -// checkAndReload attempts to call the given callback, which is assumed to be dependent -// on the data in the restmapper. -// -// If the callback returns an error that matches the given error, it will attempt to reload -// the RESTMapper's data and re-call the callback once that's occurred. -// If the callback returns any other error, the function will return immediately regardless. -// -// It will take care of ensuring that reloads are rate-limited and that extraneous calls -// aren't made. If a reload would exceed the limiters rate, it returns the error return by -// the callback. -// It's thread-safe, and worries about thread-safety for the callback (so the callback does -// not need to attempt to lock the restmapper). -func (drm *dynamicRESTMapper) checkAndReload(needsReloadErr error, checkNeedsReload func() error) error { - // first, check the common path -- data is fresh enough - // (use an IIFE for the lock's defer) - err := func() error { - drm.mu.RLock() - defer drm.mu.RUnlock() - - return checkNeedsReload() - }() - - // NB(directxman12): `Is` and `As` have a confusing relationship -- - // `Is` is like `== or does this implement .Is`, whereas `As` says - // `can I type-assert into` - needsReload := errors.As(err, &needsReloadErr) - if !needsReload { - return err - } - - // if the data wasn't fresh, we'll need to try and update it, so grab the lock... - drm.mu.Lock() - defer drm.mu.Unlock() - - // ... and double-check that we didn't reload in the meantime - err = checkNeedsReload() - needsReload = errors.As(err, &needsReloadErr) - if !needsReload { - return err - } - - // we're still stale, so grab a rate-limit token if we can... - if !drm.limiter.Allow() { - // return error from static mapper here, we have refreshed often enough (exceeding rate of provided limiter) - // so that client's can handle this the same way as a "normal" NoResourceMatchError / NoKindMatchError - return err - } - - // ...reload... - if err := drm.setStaticMapper(); err != nil { - return err - } - - // ...and return the results of the closure regardless - return checkNeedsReload() -} - -// TODO: wrap reload errors on NoKindMatchError with go 1.13 errors. - -func (drm *dynamicRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { - if err := drm.init(); err != nil { - return schema.GroupVersionKind{}, err - } - var gvk schema.GroupVersionKind - err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error { - var err error - gvk, err = drm.staticMapper.KindFor(resource) - return err - }) - return gvk, err -} - -func (drm *dynamicRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { - if err := drm.init(); err != nil { - return nil, err - } - var gvks []schema.GroupVersionKind - err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error { - var err error - gvks, err = drm.staticMapper.KindsFor(resource) - return err - }) - return gvks, err -} - -func (drm *dynamicRESTMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) { - if err := drm.init(); err != nil { - return schema.GroupVersionResource{}, err - } - - var gvr schema.GroupVersionResource - err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error { - var err error - gvr, err = drm.staticMapper.ResourceFor(input) - return err - }) - return gvr, err -} - -func (drm *dynamicRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { - if err := drm.init(); err != nil { - return nil, err - } - var gvrs []schema.GroupVersionResource - err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error { - var err error - gvrs, err = drm.staticMapper.ResourcesFor(input) - return err - }) - return gvrs, err -} - -func (drm *dynamicRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) { - if err := drm.init(); err != nil { - return nil, err - } - var mapping *meta.RESTMapping - err := drm.checkAndReload(&meta.NoKindMatchError{}, func() error { - var err error - mapping, err = drm.staticMapper.RESTMapping(gk, versions...) - return err - }) - return mapping, err -} - -func (drm *dynamicRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) { - if err := drm.init(); err != nil { - return nil, err - } - var mappings []*meta.RESTMapping - err := drm.checkAndReload(&meta.NoKindMatchError{}, func() error { - var err error - mappings, err = drm.staticMapper.RESTMappings(gk, versions...) - return err - }) - return mappings, err -} - -func (drm *dynamicRESTMapper) ResourceSingularizer(resource string) (string, error) { - if err := drm.init(); err != nil { - return "", err - } - var singular string - err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error { - var err error - singular, err = drm.staticMapper.ResourceSingularizer(resource) - return err - }) - return singular, err -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go new file mode 100644 index 00000000000..f14f8a9f598 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go @@ -0,0 +1,287 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiutil + +import ( + "fmt" + "net/http" + "sync" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" +) + +// NewDynamicRESTMapper returns a dynamic RESTMapper for cfg. The dynamic +// RESTMapper dynamically discovers resource types at runtime. +func NewDynamicRESTMapper(cfg *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) { + if httpClient == nil { + return nil, fmt.Errorf("httpClient must not be nil, consider using rest.HTTPClientFor(c) to create a client") + } + + client, err := discovery.NewDiscoveryClientForConfigAndClient(cfg, httpClient) + if err != nil { + return nil, err + } + return &mapper{ + mapper: restmapper.NewDiscoveryRESTMapper([]*restmapper.APIGroupResources{}), + client: client, + knownGroups: map[string]*restmapper.APIGroupResources{}, + apiGroups: map[string]*metav1.APIGroup{}, + }, nil +} + +// mapper is a RESTMapper that will lazily query the provided +// client for discovery information to do REST mappings. +type mapper struct { + mapper meta.RESTMapper + client *discovery.DiscoveryClient + knownGroups map[string]*restmapper.APIGroupResources + apiGroups map[string]*metav1.APIGroup + + // mutex to provide thread-safe mapper reloading. + mu sync.RWMutex +} + +// KindFor implements Mapper.KindFor. +func (m *mapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + res, err := m.getMapper().KindFor(resource) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil { + return schema.GroupVersionKind{}, err + } + res, err = m.getMapper().KindFor(resource) + } + + return res, err +} + +// KindsFor implements Mapper.KindsFor. +func (m *mapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { + res, err := m.getMapper().KindsFor(resource) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil { + return nil, err + } + res, err = m.getMapper().KindsFor(resource) + } + + return res, err +} + +// ResourceFor implements Mapper.ResourceFor. +func (m *mapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) { + res, err := m.getMapper().ResourceFor(input) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(input.Group, input.Version); err != nil { + return schema.GroupVersionResource{}, err + } + res, err = m.getMapper().ResourceFor(input) + } + + return res, err +} + +// ResourcesFor implements Mapper.ResourcesFor. +func (m *mapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + res, err := m.getMapper().ResourcesFor(input) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(input.Group, input.Version); err != nil { + return nil, err + } + res, err = m.getMapper().ResourcesFor(input) + } + + return res, err +} + +// RESTMapping implements Mapper.RESTMapping. +func (m *mapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) { + res, err := m.getMapper().RESTMapping(gk, versions...) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(gk.Group, versions...); err != nil { + return nil, err + } + res, err = m.getMapper().RESTMapping(gk, versions...) + } + + return res, err +} + +// RESTMappings implements Mapper.RESTMappings. +func (m *mapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) { + res, err := m.getMapper().RESTMappings(gk, versions...) + if meta.IsNoMatchError(err) { + if err := m.addKnownGroupAndReload(gk.Group, versions...); err != nil { + return nil, err + } + res, err = m.getMapper().RESTMappings(gk, versions...) + } + + return res, err +} + +// ResourceSingularizer implements Mapper.ResourceSingularizer. +func (m *mapper) ResourceSingularizer(resource string) (string, error) { + return m.getMapper().ResourceSingularizer(resource) +} + +func (m *mapper) getMapper() meta.RESTMapper { + m.mu.RLock() + defer m.mu.RUnlock() + return m.mapper +} + +// addKnownGroupAndReload reloads the mapper with updated information about missing API group. +// versions can be specified for partial updates, for instance for v1beta1 version only. +func (m *mapper) addKnownGroupAndReload(groupName string, versions ...string) error { + // If no specific versions are set by user, we will scan all available ones for the API group. + // This operation requires 2 requests: /api and /apis, but only once. For all subsequent calls + // this data will be taken from cache. + if len(versions) == 0 { + apiGroup, err := m.findAPIGroupByName(groupName) + if err != nil { + return err + } + for _, version := range apiGroup.Versions { + versions = append(versions, version.Version) + } + } + + m.mu.Lock() + defer m.mu.Unlock() + + // Create or fetch group resources from cache. + groupResources := &restmapper.APIGroupResources{ + Group: metav1.APIGroup{Name: groupName}, + VersionedResources: make(map[string][]metav1.APIResource), + } + if _, ok := m.knownGroups[groupName]; ok { + groupResources = m.knownGroups[groupName] + } + + // Update information for group resources about versioned resources. + // The number of API calls is equal to the number of versions: /apis//. + groupVersionResources, err := m.fetchGroupVersionResources(groupName, versions...) + if err != nil { + return fmt.Errorf("failed to get API group resources: %w", err) + } + for version, resources := range groupVersionResources { + groupResources.VersionedResources[version.Version] = resources.APIResources + } + + // Update information for group resources about the API group by adding new versions. + // Ignore the versions that are already registered. + for _, version := range versions { + found := false + for _, v := range groupResources.Group.Versions { + if v.Version == version { + found = true + break + } + } + + if !found { + groupResources.Group.Versions = append(groupResources.Group.Versions, metav1.GroupVersionForDiscovery{ + GroupVersion: metav1.GroupVersion{Group: groupName, Version: version}.String(), + Version: version, + }) + } + } + + // Update data in the cache. + m.knownGroups[groupName] = groupResources + + // Finally, update the group with received information and regenerate the mapper. + updatedGroupResources := make([]*restmapper.APIGroupResources, 0, len(m.knownGroups)) + for _, agr := range m.knownGroups { + updatedGroupResources = append(updatedGroupResources, agr) + } + + m.mapper = restmapper.NewDiscoveryRESTMapper(updatedGroupResources) + return nil +} + +// findAPIGroupByNameLocked returns API group by its name. +func (m *mapper) findAPIGroupByName(groupName string) (*metav1.APIGroup, error) { + // Looking in the cache first. + { + m.mu.RLock() + group, ok := m.apiGroups[groupName] + m.mu.RUnlock() + if ok { + return group, nil + } + } + + // Update the cache if nothing was found. + apiGroups, err := m.client.ServerGroups() + if err != nil { + return nil, fmt.Errorf("failed to get server groups: %w", err) + } + if len(apiGroups.Groups) == 0 { + return nil, fmt.Errorf("received an empty API groups list") + } + + m.mu.Lock() + for i := range apiGroups.Groups { + group := &apiGroups.Groups[i] + m.apiGroups[group.Name] = group + } + m.mu.Unlock() + + // Looking in the cache again. + { + m.mu.RLock() + group, ok := m.apiGroups[groupName] + m.mu.RUnlock() + if ok { + return group, nil + } + } + + // If there is still nothing, return an error. + return nil, fmt.Errorf("failed to find API group %q", groupName) +} + +// fetchGroupVersionResources fetches the resources for the specified group and its versions. +func (m *mapper) fetchGroupVersionResources(groupName string, versions ...string) (map[schema.GroupVersion]*metav1.APIResourceList, error) { + groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList) + failedGroups := make(map[schema.GroupVersion]error) + + for _, version := range versions { + groupVersion := schema.GroupVersion{Group: groupName, Version: version} + + apiResourceList, err := m.client.ServerResourcesForGroupVersion(groupVersion.String()) + if err != nil { + failedGroups[groupVersion] = err + } + if apiResourceList != nil { + // even in case of error, some fallback might have been returned. + groupVersionResources[groupVersion] = apiResourceList + } + } + + if len(failedGroups) > 0 { + return nil, &discovery.ErrGroupDiscoveryFailed{Groups: failedGroups} + } + + return groupVersionResources, nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go index bbe36c4673f..21067b6f8fc 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go @@ -18,12 +18,13 @@ package client import ( "context" + "errors" "fmt" + "net/http" "strings" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -35,6 +36,28 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) +// Options are creation options for a Client. +type Options struct { + // HTTPClient is the HTTP client to use for requests. + HTTPClient *http.Client + + // Scheme, if provided, will be used to map go structs to GroupVersionKinds + Scheme *runtime.Scheme + + // Mapper, if provided, will be used to map GroupVersionKinds to Resources + Mapper meta.RESTMapper + + // Cache, if provided, is used to read objects from the cache. + Cache *CacheOptions + + // WarningHandler is used to configure the warning handler responsible for + // surfacing and handling warnings messages sent by the API server. + WarningHandler WarningHandlerOptions + + // DryRun instructs the client to only perform dry run requests. + DryRun *bool +} + // WarningHandlerOptions are options for configuring a // warning handler for the client which is responsible // for surfacing API Server warnings. @@ -45,23 +68,25 @@ type WarningHandlerOptions struct { // AllowDuplicateLogs does not deduplicate the to-be // logged surfaced warnings messages. See // log.WarningHandlerOptions for considerations - // regarding deuplication + // regarding deduplication AllowDuplicateLogs bool } -// Options are creation options for a Client. -type Options struct { - // Scheme, if provided, will be used to map go structs to GroupVersionKinds - Scheme *runtime.Scheme - - // Mapper, if provided, will be used to map GroupVersionKinds to Resources - Mapper meta.RESTMapper - - // Opts is used to configure the warning handler responsible for - // surfacing and handling warnings messages sent by the API server. - Opts WarningHandlerOptions +// CacheOptions are options for creating a cache-backed client. +type CacheOptions struct { + // Reader is a cache-backed reader that will be used to read objects from the cache. + // +required + Reader Reader + // DisableFor is a list of objects that should not be read from the cache. + DisableFor []Object + // Unstructured is a flag that indicates whether the cache-backed client should + // read unstructured objects or lists from the cache. + Unstructured bool } +// NewClientFunc allows a user to define how to create a client. +type NewClientFunc func(config *rest.Config, options Options) (Client, error) + // New returns a new Client using the provided config and Options. // The returned client reads *and* writes directly from the server // (it doesn't use object caches). It understands how to work with @@ -72,8 +97,12 @@ type Options struct { // corresponding group, version, and kind for the given type. In the // case of unstructured types, the group, version, and kind will be extracted // from the corresponding fields on the object. -func New(config *rest.Config, options Options) (Client, error) { - return newClient(config, options) +func New(config *rest.Config, options Options) (c Client, err error) { + c, err = newClient(config, options) + if err == nil && options.DryRun != nil && *options.DryRun { + c = NewDryRunClient(c) + } + return c, err } func newClient(config *rest.Config, options Options) (*client, error) { @@ -81,23 +110,31 @@ func newClient(config *rest.Config, options Options) (*client, error) { return nil, fmt.Errorf("must provide non-nil rest.Config to client.New") } - if !options.Opts.SuppressWarnings { + if !options.WarningHandler.SuppressWarnings { // surface warnings logger := log.Log.WithName("KubeAPIWarningLogger") // Set a WarningHandler, the default WarningHandler // is log.KubeAPIWarningLogger with deduplication enabled. // See log.KubeAPIWarningLoggerOptions for considerations // regarding deduplication. - rest.SetDefaultWarningHandler( - log.NewKubeAPIWarningLogger( - logger, - log.KubeAPIWarningLoggerOptions{ - Deduplicate: !options.Opts.AllowDuplicateLogs, - }, - ), + config = rest.CopyConfig(config) + config.WarningHandler = log.NewKubeAPIWarningLogger( + logger, + log.KubeAPIWarningLoggerOptions{ + Deduplicate: !options.WarningHandler.AllowDuplicateLogs, + }, ) } + // Use the rest HTTP client for the provided config if unset + if options.HTTPClient == nil { + var err error + options.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return nil, err + } + } + // Init a scheme if none provided if options.Scheme == nil { options.Scheme = scheme.Scheme @@ -106,34 +143,35 @@ func newClient(config *rest.Config, options Options) (*client, error) { // Init a Mapper if none provided if options.Mapper == nil { var err error - options.Mapper, err = apiutil.NewDynamicRESTMapper(config) + options.Mapper, err = apiutil.NewDynamicRESTMapper(config, options.HTTPClient) if err != nil { return nil, err } } - clientcache := &clientCache{ - config: config, - scheme: options.Scheme, - mapper: options.Mapper, - codecs: serializer.NewCodecFactory(options.Scheme), + resources := &clientRestResources{ + httpClient: options.HTTPClient, + config: config, + scheme: options.Scheme, + mapper: options.Mapper, + codecs: serializer.NewCodecFactory(options.Scheme), structuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta), unstructuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta), } - rawMetaClient, err := metadata.NewForConfig(config) + rawMetaClient, err := metadata.NewForConfigAndClient(config, options.HTTPClient) if err != nil { return nil, fmt.Errorf("unable to construct metadata-only client for use as part of client: %w", err) } c := &client{ typedClient: typedClient{ - cache: clientcache, + resources: resources, paramCodec: runtime.NewParameterCodec(options.Scheme), }, unstructuredClient: unstructuredClient{ - cache: clientcache, + resources: resources, paramCodec: noConversionParamCodec{}, }, metadataClient: metadataClient{ @@ -143,20 +181,65 @@ func newClient(config *rest.Config, options Options) (*client, error) { scheme: options.Scheme, mapper: options.Mapper, } + if options.Cache == nil || options.Cache.Reader == nil { + return c, nil + } + + // We want a cache if we're here. + // Set the cache. + c.cache = options.Cache.Reader + // Load uncached GVKs. + c.cacheUnstructured = options.Cache.Unstructured + c.uncachedGVKs = map[schema.GroupVersionKind]struct{}{} + for _, obj := range options.Cache.DisableFor { + gvk, err := c.GroupVersionKindFor(obj) + if err != nil { + return nil, err + } + c.uncachedGVKs[gvk] = struct{}{} + } return c, nil } var _ Client = &client{} -// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes -// new clients at the time they are used, and caches the client. +// client is a client.Client that reads and writes directly from/to an API server. +// It lazily initializes new clients at the time they are used. type client struct { typedClient typedClient unstructuredClient unstructuredClient metadataClient metadataClient scheme *runtime.Scheme mapper meta.RESTMapper + + cache Reader + uncachedGVKs map[schema.GroupVersionKind]struct{} + cacheUnstructured bool +} + +func (c *client) shouldBypassCache(obj runtime.Object) (bool, error) { + if c.cache == nil { + return true, nil + } + + gvk, err := c.GroupVersionKindFor(obj) + if err != nil { + return false, err + } + // TODO: this is producing unsafe guesses that don't actually work, + // but it matches ~99% of the cases out there. + if meta.IsListType(obj) { + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + } + if _, isUncached := c.uncachedGVKs[gvk]; isUncached { + return true, nil + } + if !c.cacheUnstructured { + _, isUnstructured := obj.(runtime.Unstructured) + return isUnstructured, nil + } + return false, nil } // resetGroupVersionKind is a helper function to restore and preserve GroupVersionKind on an object. @@ -168,6 +251,16 @@ func (c *client) resetGroupVersionKind(obj runtime.Object, gvk schema.GroupVersi } } +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *client) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return apiutil.GVKForObject(obj, c.scheme) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *client) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return apiutil.IsObjectNamespaced(obj, c.scheme, c.mapper) +} + // Scheme returns the scheme this client is using. func (c *client) Scheme() *runtime.Scheme { return c.scheme @@ -181,7 +274,7 @@ func (c *client) RESTMapper() meta.RESTMapper { // Create implements client.Client. func (c *client) Create(ctx context.Context, obj Object, opts ...CreateOption) error { switch obj.(type) { - case *unstructured.Unstructured: + case runtime.Unstructured: return c.unstructuredClient.Create(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return fmt.Errorf("cannot create using only metadata") @@ -194,7 +287,7 @@ func (c *client) Create(ctx context.Context, obj Object, opts ...CreateOption) e func (c *client) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) switch obj.(type) { - case *unstructured.Unstructured: + case runtime.Unstructured: return c.unstructuredClient.Update(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return fmt.Errorf("cannot update using only metadata -- did you mean to patch?") @@ -206,7 +299,7 @@ func (c *client) Update(ctx context.Context, obj Object, opts ...UpdateOption) e // Delete implements client.Client. func (c *client) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { switch obj.(type) { - case *unstructured.Unstructured: + case runtime.Unstructured: return c.unstructuredClient.Delete(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return c.metadataClient.Delete(ctx, obj, opts...) @@ -218,7 +311,7 @@ func (c *client) Delete(ctx context.Context, obj Object, opts ...DeleteOption) e // DeleteAllOf implements client.Client. func (c *client) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { switch obj.(type) { - case *unstructured.Unstructured: + case runtime.Unstructured: return c.unstructuredClient.DeleteAllOf(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return c.metadataClient.DeleteAllOf(ctx, obj, opts...) @@ -231,7 +324,7 @@ func (c *client) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllO func (c *client) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) switch obj.(type) { - case *unstructured.Unstructured: + case runtime.Unstructured: return c.unstructuredClient.Patch(ctx, obj, patch, opts...) case *metav1.PartialObjectMetadata: return c.metadataClient.Patch(ctx, obj, patch, opts...) @@ -241,23 +334,35 @@ func (c *client) Patch(ctx context.Context, obj Object, patch Patch, opts ...Pat } // Get implements client.Client. -func (c *client) Get(ctx context.Context, key ObjectKey, obj Object) error { +func (c *client) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + if isUncached, err := c.shouldBypassCache(obj); err != nil { + return err + } else if !isUncached { + return c.cache.Get(ctx, key, obj, opts...) + } + switch obj.(type) { - case *unstructured.Unstructured: - return c.unstructuredClient.Get(ctx, key, obj) + case runtime.Unstructured: + return c.unstructuredClient.Get(ctx, key, obj, opts...) case *metav1.PartialObjectMetadata: // Metadata only object should always preserve the GVK coming in from the caller. defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) - return c.metadataClient.Get(ctx, key, obj) + return c.metadataClient.Get(ctx, key, obj, opts...) default: - return c.typedClient.Get(ctx, key, obj) + return c.typedClient.Get(ctx, key, obj, opts...) } } // List implements client.Client. func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { + if isUncached, err := c.shouldBypassCache(obj); err != nil { + return err + } else if !isUncached { + return c.cache.List(ctx, obj, opts...) + } + switch x := obj.(type) { - case *unstructured.UnstructuredList: + case runtime.Unstructured: return c.unstructuredClient.List(ctx, obj, opts...) case *metav1.PartialObjectMetadataList: // Metadata only object should always preserve the GVK. @@ -289,40 +394,194 @@ func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) e } // Status implements client.StatusClient. -func (c *client) Status() StatusWriter { - return &statusWriter{client: c} +func (c *client) Status() SubResourceWriter { + return c.SubResource("status") +} + +func (c *client) SubResource(subResource string) SubResourceClient { + return &subResourceClient{client: c, subResource: subResource} +} + +// subResourceClient is client.SubResourceWriter that writes to subresources. +type subResourceClient struct { + client *client + subResource string } -// statusWriter is client.StatusWriter that writes status subresource. -type statusWriter struct { - client *client +// ensure subResourceClient implements client.SubResourceClient. +var _ SubResourceClient = &subResourceClient{} + +// SubResourceGetOptions holds all the possible configuration +// for a subresource Get request. +type SubResourceGetOptions struct { + Raw *metav1.GetOptions +} + +// ApplyToSubResourceGet updates the configuaration to the given get options. +func (getOpt *SubResourceGetOptions) ApplyToSubResourceGet(o *SubResourceGetOptions) { + if getOpt.Raw != nil { + o.Raw = getOpt.Raw + } +} + +// ApplyOptions applues the given options. +func (getOpt *SubResourceGetOptions) ApplyOptions(opts []SubResourceGetOption) *SubResourceGetOptions { + for _, o := range opts { + o.ApplyToSubResourceGet(getOpt) + } + + return getOpt +} + +// AsGetOptions returns the configured options as *metav1.GetOptions. +func (getOpt *SubResourceGetOptions) AsGetOptions() *metav1.GetOptions { + if getOpt.Raw == nil { + return &metav1.GetOptions{} + } + return getOpt.Raw +} + +// SubResourceUpdateOptions holds all the possible configuration +// for a subresource update request. +type SubResourceUpdateOptions struct { + UpdateOptions + SubResourceBody Object +} + +// ApplyToSubResourceUpdate updates the configuration on the given create options +func (uo *SubResourceUpdateOptions) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) { + uo.UpdateOptions.ApplyToUpdate(&o.UpdateOptions) + if uo.SubResourceBody != nil { + o.SubResourceBody = uo.SubResourceBody + } } -// ensure statusWriter implements client.StatusWriter. -var _ StatusWriter = &statusWriter{} +// ApplyOptions applies the given options. +func (uo *SubResourceUpdateOptions) ApplyOptions(opts []SubResourceUpdateOption) *SubResourceUpdateOptions { + for _, o := range opts { + o.ApplyToSubResourceUpdate(uo) + } + + return uo +} + +// SubResourceUpdateAndPatchOption is an option that can be used for either +// a subresource update or patch request. +type SubResourceUpdateAndPatchOption interface { + SubResourceUpdateOption + SubResourcePatchOption +} + +// WithSubResourceBody returns an option that uses the given body +// for a subresource Update or Patch operation. +func WithSubResourceBody(body Object) SubResourceUpdateAndPatchOption { + return &withSubresourceBody{body: body} +} + +type withSubresourceBody struct { + body Object +} + +func (wsr *withSubresourceBody) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) { + o.SubResourceBody = wsr.body +} + +func (wsr *withSubresourceBody) ApplyToSubResourcePatch(o *SubResourcePatchOptions) { + o.SubResourceBody = wsr.body +} + +// SubResourceCreateOptions are all the possible configurations for a subresource +// create request. +type SubResourceCreateOptions struct { + CreateOptions +} -// Update implements client.StatusWriter. -func (sw *statusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { - defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) +// ApplyOptions applies the given options. +func (co *SubResourceCreateOptions) ApplyOptions(opts []SubResourceCreateOption) *SubResourceCreateOptions { + for _, o := range opts { + o.ApplyToSubResourceCreate(co) + } + + return co +} + +// ApplyToSubresourceCreate applies the the configuration on the given create options. +func (co *SubResourceCreateOptions) ApplyToSubresourceCreate(o *SubResourceCreateOptions) { + co.CreateOptions.ApplyToCreate(&co.CreateOptions) +} + +// SubResourcePatchOptions holds all possible configurations for a subresource patch +// request. +type SubResourcePatchOptions struct { + PatchOptions + SubResourceBody Object +} + +// ApplyOptions applies the given options. +func (po *SubResourcePatchOptions) ApplyOptions(opts []SubResourcePatchOption) *SubResourcePatchOptions { + for _, o := range opts { + o.ApplyToSubResourcePatch(po) + } + + return po +} + +// ApplyToSubResourcePatch applies the configuration on the given patch options. +func (po *SubResourcePatchOptions) ApplyToSubResourcePatch(o *SubResourcePatchOptions) { + po.PatchOptions.ApplyToPatch(&o.PatchOptions) + if po.SubResourceBody != nil { + o.SubResourceBody = po.SubResourceBody + } +} + +func (sc *subResourceClient) Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error { switch obj.(type) { - case *unstructured.Unstructured: - return sw.client.unstructuredClient.UpdateStatus(ctx, obj, opts...) + case runtime.Unstructured: + return sc.client.unstructuredClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...) + case *metav1.PartialObjectMetadata: + return errors.New("can not get subresource using only metadata") + default: + return sc.client.typedClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...) + } +} + +// Create implements client.SubResourceClient +func (sc *subResourceClient) Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + defer sc.client.resetGroupVersionKind(subResource, subResource.GetObjectKind().GroupVersionKind()) + + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...) case *metav1.PartialObjectMetadata: return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?") default: - return sw.client.typedClient.UpdateStatus(ctx, obj, opts...) + return sc.client.typedClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...) } } -// Patch implements client.Client. -func (sw *statusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) +// Update implements client.SubResourceClient +func (sc *subResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) + switch obj.(type) { + case runtime.Unstructured: + return sc.client.unstructuredClient.UpdateSubResource(ctx, obj, sc.subResource, opts...) + case *metav1.PartialObjectMetadata: + return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?") + default: + return sc.client.typedClient.UpdateSubResource(ctx, obj, sc.subResource, opts...) + } +} + +// Patch implements client.SubResourceWriter. +func (sc *subResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { + defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind()) switch obj.(type) { - case *unstructured.Unstructured: - return sw.client.unstructuredClient.PatchStatus(ctx, obj, patch, opts...) + case runtime.Unstructured: + return sc.client.unstructuredClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) case *metav1.PartialObjectMetadata: - return sw.client.metadataClient.PatchStatus(ctx, obj, patch, opts...) + return sc.client.metadataClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) default: - return sw.client.typedClient.PatchStatus(ctx, obj, patch, opts...) + return sc.client.typedClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...) } } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_cache.go deleted file mode 100644 index 857a0b38a72..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_cache.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package client - -import ( - "strings" - "sync" - - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -// clientCache creates and caches rest clients and metadata for Kubernetes types. -type clientCache struct { - // config is the rest.Config to talk to an apiserver - config *rest.Config - - // scheme maps go structs to GroupVersionKinds - scheme *runtime.Scheme - - // mapper maps GroupVersionKinds to Resources - mapper meta.RESTMapper - - // codecs are used to create a REST client for a gvk - codecs serializer.CodecFactory - - // structuredResourceByType caches structured type metadata - structuredResourceByType map[schema.GroupVersionKind]*resourceMeta - // unstructuredResourceByType caches unstructured type metadata - unstructuredResourceByType map[schema.GroupVersionKind]*resourceMeta - mu sync.RWMutex -} - -// newResource maps obj to a Kubernetes Resource and constructs a client for that Resource. -// If the object is a list, the resource represents the item's type instead. -func (c *clientCache) newResource(gvk schema.GroupVersionKind, isList, isUnstructured bool) (*resourceMeta, error) { - if strings.HasSuffix(gvk.Kind, "List") && isList { - // if this was a list, treat it as a request for the item's resource - gvk.Kind = gvk.Kind[:len(gvk.Kind)-4] - } - - client, err := apiutil.RESTClientForGVK(gvk, isUnstructured, c.config, c.codecs) - if err != nil { - return nil, err - } - mapping, err := c.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return nil, err - } - return &resourceMeta{Interface: client, mapping: mapping, gvk: gvk}, nil -} - -// getResource returns the resource meta information for the given type of object. -// If the object is a list, the resource represents the item's type instead. -func (c *clientCache) getResource(obj runtime.Object) (*resourceMeta, error) { - gvk, err := apiutil.GVKForObject(obj, c.scheme) - if err != nil { - return nil, err - } - - _, isUnstructured := obj.(*unstructured.Unstructured) - _, isUnstructuredList := obj.(*unstructured.UnstructuredList) - isUnstructured = isUnstructured || isUnstructuredList - - // It's better to do creation work twice than to not let multiple - // people make requests at once - c.mu.RLock() - resourceByType := c.structuredResourceByType - if isUnstructured { - resourceByType = c.unstructuredResourceByType - } - r, known := resourceByType[gvk] - c.mu.RUnlock() - - if known { - return r, nil - } - - // Initialize a new Client - c.mu.Lock() - defer c.mu.Unlock() - r, err = c.newResource(gvk, meta.IsListType(obj), isUnstructured) - if err != nil { - return nil, err - } - resourceByType[gvk] = r - return r, err -} - -// getObjMeta returns objMeta containing both type and object metadata and state. -func (c *clientCache) getObjMeta(obj runtime.Object) (*objMeta, error) { - r, err := c.getResource(obj) - if err != nil { - return nil, err - } - m, err := meta.Accessor(obj) - if err != nil { - return nil, err - } - return &objMeta{resourceMeta: r, Object: m}, err -} - -// resourceMeta caches state for a Kubernetes type. -type resourceMeta struct { - // client is the rest client used to talk to the apiserver - rest.Interface - // gvk is the GroupVersionKind of the resourceMeta - gvk schema.GroupVersionKind - // mapping is the rest mapping - mapping *meta.RESTMapping -} - -// isNamespaced returns true if the type is namespaced. -func (r *resourceMeta) isNamespaced() bool { - return r.mapping.Scope.Name() != meta.RESTScopeNameRoot -} - -// resource returns the resource name of the type. -func (r *resourceMeta) resource() string { - return r.mapping.Resource.Resource -} - -// objMeta stores type and object information about a Kubernetes type. -type objMeta struct { - // resourceMeta contains type information for the object - *resourceMeta - - // Object contains meta data for the object instance - metav1.Object -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go new file mode 100644 index 00000000000..2d07879520b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/client_rest_resources.go @@ -0,0 +1,151 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "net/http" + "strings" + "sync" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// clientRestResources creates and stores rest clients and metadata for Kubernetes types. +type clientRestResources struct { + // httpClient is the http client to use for requests + httpClient *http.Client + + // config is the rest.Config to talk to an apiserver + config *rest.Config + + // scheme maps go structs to GroupVersionKinds + scheme *runtime.Scheme + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper + + // codecs are used to create a REST client for a gvk + codecs serializer.CodecFactory + + // structuredResourceByType stores structured type metadata + structuredResourceByType map[schema.GroupVersionKind]*resourceMeta + // unstructuredResourceByType stores unstructured type metadata + unstructuredResourceByType map[schema.GroupVersionKind]*resourceMeta + mu sync.RWMutex +} + +// newResource maps obj to a Kubernetes Resource and constructs a client for that Resource. +// If the object is a list, the resource represents the item's type instead. +func (c *clientRestResources) newResource(gvk schema.GroupVersionKind, isList, isUnstructured bool) (*resourceMeta, error) { + if strings.HasSuffix(gvk.Kind, "List") && isList { + // if this was a list, treat it as a request for the item's resource + gvk.Kind = gvk.Kind[:len(gvk.Kind)-4] + } + + client, err := apiutil.RESTClientForGVK(gvk, isUnstructured, c.config, c.codecs, c.httpClient) + if err != nil { + return nil, err + } + mapping, err := c.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + return &resourceMeta{Interface: client, mapping: mapping, gvk: gvk}, nil +} + +// getResource returns the resource meta information for the given type of object. +// If the object is a list, the resource represents the item's type instead. +func (c *clientRestResources) getResource(obj runtime.Object) (*resourceMeta, error) { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return nil, err + } + + _, isUnstructured := obj.(runtime.Unstructured) + + // It's better to do creation work twice than to not let multiple + // people make requests at once + c.mu.RLock() + resourceByType := c.structuredResourceByType + if isUnstructured { + resourceByType = c.unstructuredResourceByType + } + r, known := resourceByType[gvk] + c.mu.RUnlock() + + if known { + return r, nil + } + + // Initialize a new Client + c.mu.Lock() + defer c.mu.Unlock() + r, err = c.newResource(gvk, meta.IsListType(obj), isUnstructured) + if err != nil { + return nil, err + } + resourceByType[gvk] = r + return r, err +} + +// getObjMeta returns objMeta containing both type and object metadata and state. +func (c *clientRestResources) getObjMeta(obj runtime.Object) (*objMeta, error) { + r, err := c.getResource(obj) + if err != nil { + return nil, err + } + m, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + return &objMeta{resourceMeta: r, Object: m}, err +} + +// resourceMeta stores state for a Kubernetes type. +type resourceMeta struct { + // client is the rest client used to talk to the apiserver + rest.Interface + // gvk is the GroupVersionKind of the resourceMeta + gvk schema.GroupVersionKind + // mapping is the rest mapping + mapping *meta.RESTMapping +} + +// isNamespaced returns true if the type is namespaced. +func (r *resourceMeta) isNamespaced() bool { + return r.mapping.Scope.Name() != meta.RESTScopeNameRoot +} + +// resource returns the resource name of the type. +func (r *resourceMeta) resource() string { + return r.mapping.Resource.Resource +} + +// objMeta stores type and object information about a Kubernetes type. +type objMeta struct { + // resourceMeta contains type information for the object + *resourceMeta + + // Object contains meta data for the object instance + metav1.Object +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go index fd27724127f..5f0a6d4b1dd 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go @@ -29,15 +29,32 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/internal/log" ) +// KubeconfigFlagName is the name of the kubeconfig flag +const KubeconfigFlagName = "kubeconfig" + var ( kubeconfig string log = logf.RuntimeLog.WithName("client").WithName("config") ) +// init registers the "kubeconfig" flag to the default command line FlagSet. +// TODO: This should be removed, as it potentially leads to redefined flag errors for users, if they already +// have registered the "kubeconfig" flag to the command line FlagSet in other parts of their code. func init() { - // TODO: Fix this to allow double vendoring this library but still register flags on behalf of users - flag.StringVar(&kubeconfig, "kubeconfig", "", - "Paths to a kubeconfig. Only required if out-of-cluster.") + RegisterFlags(flag.CommandLine) +} + +// RegisterFlags registers flag variables to the given FlagSet if not already registered. +// It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. +func RegisterFlags(fs *flag.FlagSet) { + if fs == nil { + fs = flag.CommandLine + } + if f := fs.Lookup(KubeconfigFlagName); f != nil { + kubeconfig = f.Value.String() + } else { + fs.StringVar(&kubeconfig, KubeconfigFlagName, "", "Paths to a kubeconfig. Only required if out-of-cluster.") + } } // GetConfig creates a *rest.Config for talking to a Kubernetes API server. @@ -47,7 +64,7 @@ func init() { // It also applies saner defaults for QPS and burst based on the Kubernetes // controller manager defaults (20 QPS, 30 burst) // -// Config precedence +// Config precedence: // // * --kubeconfig flag pointing at a file // @@ -67,7 +84,7 @@ func GetConfig() (*rest.Config, error) { // It also applies saner defaults for QPS and burst based on the Kubernetes // controller manager defaults (20 QPS, 30 burst) // -// Config precedence +// Config precedence: // // * --kubeconfig flag pointing at a file // @@ -81,12 +98,12 @@ func GetConfigWithContext(context string) (*rest.Config, error) { if err != nil { return nil, err } - if cfg.QPS == 0.0 { cfg.QPS = 20.0 - cfg.Burst = 30.0 } - + if cfg.Burst == 0 { + cfg.Burst = 30 + } return cfg, nil } @@ -96,7 +113,7 @@ func GetConfigWithContext(context string) (*rest.Config, error) { var loadInClusterConfig = rest.InClusterConfig // loadConfig loads a REST Config as per the rules specified in GetConfig. -func loadConfig(context string) (*rest.Config, error) { +func loadConfig(context string) (config *rest.Config, configErr error) { // If a flag is specified with the config location, use that if len(kubeconfig) > 0 { return loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, context) @@ -106,9 +123,16 @@ func loadConfig(context string) (*rest.Config, error) { // try the in-cluster config. kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar) if len(kubeconfigPath) == 0 { - if c, err := loadInClusterConfig(); err == nil { + c, err := loadInClusterConfig() + if err == nil { return c, nil } + + defer func() { + if configErr != nil { + log.Error(err, "unable to load in-cluster config") + } + }() } // If the recommended kubeconfig env variable is set, or there diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go index 2965e5fa948..b2e20249428 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go @@ -17,7 +17,7 @@ limitations under the License. // Package client contains functionality for interacting with Kubernetes API // servers. // -// Clients +// # Clients // // Clients are split into two interfaces -- Readers and Writers. Readers // get and list, while writers create, update, and delete. @@ -25,18 +25,18 @@ limitations under the License. // The New function can be used to create a new client that talks directly // to the API server. // -// A common pattern in Kubernetes to read from a cache and write to the API -// server. This pattern is covered by the DelegatingClient type, which can -// be used to have a client whose Reader is different from the Writer. +// It is a common pattern in Kubernetes to read from a cache and write to the API +// server. This pattern is covered by the creating the Client with a Cache. // -// Options +// # Options // // Many client operations in Kubernetes support options. These options are // represented as variadic arguments at the end of a given method call. // For instance, to use a label selector on list, you can call -// err := someReader.List(context.Background(), &podList, client.MatchingLabels{"somelabel": "someval"}) // -// Indexing +// err := someReader.List(context.Background(), &podList, client.MatchingLabels{"somelabel": "someval"}) +// +// # Indexing // // Indexes may be added to caches using a FieldIndexer. This allows you to easily // and efficiently look up objects with certain properties. You can then make diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go index ea25ea25308..bbcdd383215 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go @@ -21,6 +21,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewDryRunClient wraps an existing client and enforces DryRun mode @@ -46,6 +47,16 @@ func (c *dryRunClient) RESTMapper() meta.RESTMapper { return c.client.RESTMapper() } +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *dryRunClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return c.client.GroupVersionKindFor(obj) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *dryRunClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return c.client.IsObjectNamespaced(obj) +} + // Create implements client.Client. func (c *dryRunClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { return c.client.Create(ctx, obj, append(opts, DryRunAll)...) @@ -72,8 +83,8 @@ func (c *dryRunClient) Patch(ctx context.Context, obj Object, patch Patch, opts } // Get implements client.Client. -func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object) error { - return c.client.Get(ctx, key, obj) +func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + return c.client.Get(ctx, key, obj, opts...) } // List implements client.Client. @@ -82,25 +93,38 @@ func (c *dryRunClient) List(ctx context.Context, obj ObjectList, opts ...ListOpt } // Status implements client.StatusClient. -func (c *dryRunClient) Status() StatusWriter { - return &dryRunStatusWriter{client: c.client.Status()} +func (c *dryRunClient) Status() SubResourceWriter { + return c.SubResource("status") +} + +// SubResource implements client.SubResourceClient. +func (c *dryRunClient) SubResource(subResource string) SubResourceClient { + return &dryRunSubResourceClient{client: c.client.SubResource(subResource)} } -// ensure dryRunStatusWriter implements client.StatusWriter. -var _ StatusWriter = &dryRunStatusWriter{} +// ensure dryRunSubResourceWriter implements client.SubResourceWriter. +var _ SubResourceWriter = &dryRunSubResourceClient{} -// dryRunStatusWriter is client.StatusWriter that writes status subresource with dryRun mode +// dryRunSubResourceClient is client.SubResourceWriter that writes status subresource with dryRun mode // enforced. -type dryRunStatusWriter struct { - client StatusWriter +type dryRunSubResourceClient struct { + client SubResourceClient +} + +func (sw *dryRunSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error { + return sw.client.Get(ctx, obj, subResource, opts...) +} + +func (sw *dryRunSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error { + return sw.client.Create(ctx, obj, subResource, append(opts, DryRunAll)...) } -// Update implements client.StatusWriter. -func (sw *dryRunStatusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { +// Update implements client.SubResourceWriter. +func (sw *dryRunSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { return sw.client.Update(ctx, obj, append(opts, DryRunAll)...) } -// Patch implements client.StatusWriter. -func (sw *dryRunStatusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { +// Patch implements client.SubResourceWriter. +func (sw *dryRunSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { return sw.client.Patch(ctx, obj, patch, append(opts, DryRunAll)...) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go new file mode 100644 index 00000000000..7167c5505ec --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go @@ -0,0 +1,1283 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "reflect" + "runtime/debug" + "strconv" + "strings" + "sync" + "time" + + // Using v4 to match upstream + jsonpatch "github.com/evanphx/json-patch" + "sigs.k8s.io/controller-runtime/pkg/client/interceptor" + + corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + utilrand "k8s.io/apimachinery/pkg/util/rand" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/testing" + "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/internal/objectutil" +) + +type versionedTracker struct { + testing.ObjectTracker + scheme *runtime.Scheme + withStatusSubresource sets.Set[schema.GroupVersionKind] +} + +type fakeClient struct { + tracker versionedTracker + scheme *runtime.Scheme + restMapper meta.RESTMapper + withStatusSubresource sets.Set[schema.GroupVersionKind] + + // indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK. + // The inner map maps from index name to IndexerFunc. + indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc + + schemeWriteLock sync.Mutex +} + +var _ client.WithWatch = &fakeClient{} + +const ( + maxNameLength = 63 + randomLength = 5 + maxGeneratedNameLength = maxNameLength - randomLength +) + +// NewFakeClient creates a new fake client for testing. +// You can choose to initialize it with a slice of runtime.Object. +// +// Deprecated: Please use NewClientBuilder instead. +func NewFakeClient(initObjs ...runtime.Object) client.WithWatch { + return NewClientBuilder().WithRuntimeObjects(initObjs...).Build() +} + +// NewFakeClientWithScheme creates a new fake client with the given scheme +// for testing. +// You can choose to initialize it with a slice of runtime.Object. +// +// Deprecated: Please use NewClientBuilder instead. +func NewFakeClientWithScheme(clientScheme *runtime.Scheme, initObjs ...runtime.Object) client.WithWatch { + return NewClientBuilder().WithScheme(clientScheme).WithRuntimeObjects(initObjs...).Build() +} + +// NewClientBuilder returns a new builder to create a fake client. +func NewClientBuilder() *ClientBuilder { + return &ClientBuilder{} +} + +// ClientBuilder builds a fake client. +type ClientBuilder struct { + scheme *runtime.Scheme + restMapper meta.RESTMapper + initObject []client.Object + initLists []client.ObjectList + initRuntimeObjects []runtime.Object + withStatusSubresource []client.Object + objectTracker testing.ObjectTracker + interceptorFuncs *interceptor.Funcs + + // indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK. + // The inner map maps from index name to IndexerFunc. + indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc +} + +// WithScheme sets this builder's internal scheme. +// If not set, defaults to client-go's global scheme.Scheme. +func (f *ClientBuilder) WithScheme(scheme *runtime.Scheme) *ClientBuilder { + f.scheme = scheme + return f +} + +// WithRESTMapper sets this builder's restMapper. +// The restMapper is directly set as mapper in the Client. This can be used for example +// with a meta.DefaultRESTMapper to provide a static rest mapping. +// If not set, defaults to an empty meta.DefaultRESTMapper. +func (f *ClientBuilder) WithRESTMapper(restMapper meta.RESTMapper) *ClientBuilder { + f.restMapper = restMapper + return f +} + +// WithObjects can be optionally used to initialize this fake client with client.Object(s). +func (f *ClientBuilder) WithObjects(initObjs ...client.Object) *ClientBuilder { + f.initObject = append(f.initObject, initObjs...) + return f +} + +// WithLists can be optionally used to initialize this fake client with client.ObjectList(s). +func (f *ClientBuilder) WithLists(initLists ...client.ObjectList) *ClientBuilder { + f.initLists = append(f.initLists, initLists...) + return f +} + +// WithRuntimeObjects can be optionally used to initialize this fake client with runtime.Object(s). +func (f *ClientBuilder) WithRuntimeObjects(initRuntimeObjs ...runtime.Object) *ClientBuilder { + f.initRuntimeObjects = append(f.initRuntimeObjects, initRuntimeObjs...) + return f +} + +// WithObjectTracker can be optionally used to initialize this fake client with testing.ObjectTracker. +func (f *ClientBuilder) WithObjectTracker(ot testing.ObjectTracker) *ClientBuilder { + f.objectTracker = ot + return f +} + +// WithIndex can be optionally used to register an index with name `field` and indexer `extractValue` +// for API objects of the same GroupVersionKind (GVK) as `obj` in the fake client. +// It can be invoked multiple times, both with objects of the same GVK or different ones. +// Invoking WithIndex twice with the same `field` and GVK (via `obj`) arguments will panic. +// WithIndex retrieves the GVK of `obj` using the scheme registered via WithScheme if +// WithScheme was previously invoked, the default scheme otherwise. +func (f *ClientBuilder) WithIndex(obj runtime.Object, field string, extractValue client.IndexerFunc) *ClientBuilder { + objScheme := f.scheme + if objScheme == nil { + objScheme = scheme.Scheme + } + + gvk, err := apiutil.GVKForObject(obj, objScheme) + if err != nil { + panic(err) + } + + // If this is the first index being registered, we initialize the map storing all the indexes. + if f.indexes == nil { + f.indexes = make(map[schema.GroupVersionKind]map[string]client.IndexerFunc) + } + + // If this is the first index being registered for the GroupVersionKind of `obj`, we initialize + // the map storing the indexes for that GroupVersionKind. + if f.indexes[gvk] == nil { + f.indexes[gvk] = make(map[string]client.IndexerFunc) + } + + if _, fieldAlreadyIndexed := f.indexes[gvk][field]; fieldAlreadyIndexed { + panic(fmt.Errorf("indexer conflict: field %s for GroupVersionKind %v is already indexed", + field, gvk)) + } + + f.indexes[gvk][field] = extractValue + + return f +} + +// WithStatusSubresource configures the passed object with a status subresource, which means +// calls to Update and Patch will not alter its status. +func (f *ClientBuilder) WithStatusSubresource(o ...client.Object) *ClientBuilder { + f.withStatusSubresource = append(f.withStatusSubresource, o...) + return f +} + +// WithInterceptorFuncs configures the client methods to be intercepted using the provided interceptor.Funcs. +func (f *ClientBuilder) WithInterceptorFuncs(interceptorFuncs interceptor.Funcs) *ClientBuilder { + f.interceptorFuncs = &interceptorFuncs + return f +} + +// Build builds and returns a new fake client. +func (f *ClientBuilder) Build() client.WithWatch { + if f.scheme == nil { + f.scheme = scheme.Scheme + } + if f.restMapper == nil { + f.restMapper = meta.NewDefaultRESTMapper([]schema.GroupVersion{}) + } + + var tracker versionedTracker + + withStatusSubResource := sets.New(inTreeResourcesWithStatus()...) + for _, o := range f.withStatusSubresource { + gvk, err := apiutil.GVKForObject(o, f.scheme) + if err != nil { + panic(fmt.Errorf("failed to get gvk for object %T: %w", withStatusSubResource, err)) + } + withStatusSubResource.Insert(gvk) + } + + if f.objectTracker == nil { + tracker = versionedTracker{ObjectTracker: testing.NewObjectTracker(f.scheme, scheme.Codecs.UniversalDecoder()), scheme: f.scheme, withStatusSubresource: withStatusSubResource} + } else { + tracker = versionedTracker{ObjectTracker: f.objectTracker, scheme: f.scheme, withStatusSubresource: withStatusSubResource} + } + + for _, obj := range f.initObject { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add object %v to fake client: %w", obj, err)) + } + } + for _, obj := range f.initLists { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add list %v to fake client: %w", obj, err)) + } + } + for _, obj := range f.initRuntimeObjects { + if err := tracker.Add(obj); err != nil { + panic(fmt.Errorf("failed to add runtime object %v to fake client: %w", obj, err)) + } + } + + var result client.WithWatch = &fakeClient{ + tracker: tracker, + scheme: f.scheme, + restMapper: f.restMapper, + indexes: f.indexes, + withStatusSubresource: withStatusSubResource, + } + + if f.interceptorFuncs != nil { + result = interceptor.NewClient(result, *f.interceptorFuncs) + } + + return result +} + +const trackerAddResourceVersion = "999" + +func (t versionedTracker) Add(obj runtime.Object) error { + var objects []runtime.Object + if meta.IsListType(obj) { + var err error + objects, err = meta.ExtractList(obj) + if err != nil { + return err + } + } else { + objects = []runtime.Object{obj} + } + for _, obj := range objects { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + if accessor.GetDeletionTimestamp() != nil && len(accessor.GetFinalizers()) == 0 { + return fmt.Errorf("refusing to create obj %s with metadata.deletionTimestamp but no finalizers", accessor.GetName()) + } + if accessor.GetResourceVersion() == "" { + // We use a "magic" value of 999 here because this field + // is parsed as uint and and 0 is already used in Update. + // As we can't go lower, go very high instead so this can + // be recognized + accessor.SetResourceVersion(trackerAddResourceVersion) + } + + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + if err := t.ObjectTracker.Add(obj); err != nil { + return err + } + } + + return nil +} + +func (t versionedTracker) Create(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + if accessor.GetName() == "" { + return apierrors.NewInvalid( + obj.GetObjectKind().GroupVersionKind().GroupKind(), + accessor.GetName(), + field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")}) + } + if accessor.GetResourceVersion() != "" { + return apierrors.NewBadRequest("resourceVersion can not be set for Create requests") + } + accessor.SetResourceVersion("1") + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + if err := t.ObjectTracker.Create(gvr, obj, ns); err != nil { + accessor.SetResourceVersion("") + return err + } + + return nil +} + +// convertFromUnstructuredIfNecessary will convert runtime.Unstructured for a GVK that is recognized +// by the schema into the whatever the schema produces with New() for said GVK. +// This is required because the tracker unconditionally saves on manipulations, but its List() implementation +// tries to assign whatever it finds into a ListType it gets from schema.New() - Thus we have to ensure +// we save as the very same type, otherwise subsequent List requests will fail. +func convertFromUnstructuredIfNecessary(s *runtime.Scheme, o runtime.Object) (runtime.Object, error) { + gvk := o.GetObjectKind().GroupVersionKind() + + u, isUnstructured := o.(runtime.Unstructured) + if !isUnstructured || !s.Recognizes(gvk) { + return o, nil + } + + typed, err := s.New(gvk) + if err != nil { + return nil, fmt.Errorf("scheme recognizes %s but failed to produce an object for it: %w", gvk, err) + } + + unstructuredSerialized, err := json.Marshal(u) + if err != nil { + return nil, fmt.Errorf("failed to serialize %T: %w", unstructuredSerialized, err) + } + if err := json.Unmarshal(unstructuredSerialized, typed); err != nil { + return nil, fmt.Errorf("failed to unmarshal the content of %T into %T: %w", u, typed, err) + } + + return typed, nil +} + +func (t versionedTracker) Update(gvr schema.GroupVersionResource, obj runtime.Object, ns string) error { + isStatus := false + // We apply patches using a client-go reaction that ends up calling the trackers Update. As we can't change + // that reaction, we use the callstack to figure out if this originated from the status client. + if bytes.Contains(debug.Stack(), []byte("sigs.k8s.io/controller-runtime/pkg/client/fake.(*fakeSubResourceClient).Patch")) { + isStatus = true + } + return t.update(gvr, obj, ns, isStatus, false) +} + +func (t versionedTracker) update(gvr schema.GroupVersionResource, obj runtime.Object, ns string, isStatus bool, deleting bool) error { + accessor, err := meta.Accessor(obj) + if err != nil { + return fmt.Errorf("failed to get accessor for object: %w", err) + } + + if accessor.GetName() == "" { + return apierrors.NewInvalid( + obj.GetObjectKind().GroupVersionKind().GroupKind(), + accessor.GetName(), + field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")}) + } + + gvk := obj.GetObjectKind().GroupVersionKind() + if gvk.Empty() { + gvk, err = apiutil.GVKForObject(obj, t.scheme) + if err != nil { + return err + } + } + + oldObject, err := t.ObjectTracker.Get(gvr, ns, accessor.GetName()) + if err != nil { + // If the resource is not found and the resource allows create on update, issue a + // create instead. + if apierrors.IsNotFound(err) && allowsCreateOnUpdate(gvk) { + return t.Create(gvr, obj, ns) + } + return err + } + + if t.withStatusSubresource.Has(gvk) { + if isStatus { // copy everything but status and metadata.ResourceVersion from original object + if err := copyNonStatusFrom(oldObject, obj); err != nil { + return fmt.Errorf("failed to copy non-status field for object with status subresouce: %w", err) + } + } else { // copy status from original object + if err := copyStatusFrom(oldObject, obj); err != nil { + return fmt.Errorf("failed to copy the status for object with status subresource: %w", err) + } + } + } else if isStatus { + return apierrors.NewNotFound(gvr.GroupResource(), accessor.GetName()) + } + + oldAccessor, err := meta.Accessor(oldObject) + if err != nil { + return err + } + + // If the new object does not have the resource version set and it allows unconditional update, + // default it to the resource version of the existing resource + if accessor.GetResourceVersion() == "" && allowsUnconditionalUpdate(gvk) { + accessor.SetResourceVersion(oldAccessor.GetResourceVersion()) + } + if accessor.GetResourceVersion() != oldAccessor.GetResourceVersion() { + return apierrors.NewConflict(gvr.GroupResource(), accessor.GetName(), errors.New("object was modified")) + } + if oldAccessor.GetResourceVersion() == "" { + oldAccessor.SetResourceVersion("0") + } + intResourceVersion, err := strconv.ParseUint(oldAccessor.GetResourceVersion(), 10, 64) + if err != nil { + return fmt.Errorf("can not convert resourceVersion %q to int: %w", oldAccessor.GetResourceVersion(), err) + } + intResourceVersion++ + accessor.SetResourceVersion(strconv.FormatUint(intResourceVersion, 10)) + + if !deleting && !deletionTimestampEqual(accessor, oldAccessor) { + return fmt.Errorf("error: Unable to edit %s: metadata.deletionTimestamp field is immutable", accessor.GetName()) + } + + if !accessor.GetDeletionTimestamp().IsZero() && len(accessor.GetFinalizers()) == 0 { + return t.ObjectTracker.Delete(gvr, accessor.GetNamespace(), accessor.GetName()) + } + obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj) + if err != nil { + return err + } + return t.ObjectTracker.Update(gvr, obj, ns) +} + +func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + o, err := c.tracker.Get(gvr, key.Namespace, key.Name) + if err != nil { + return err + } + + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(gvk.Kind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + return err +} + +func (c *fakeClient) Watch(ctx context.Context, list client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + gvk, err := apiutil.GVKForObject(list, c.scheme) + if err != nil { + return nil, err + } + + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + return c.tracker.Watch(gvr, listOpts.Namespace) +} + +func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + originalKind := gvk.Kind + + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + if _, isUnstructuredList := obj.(runtime.Unstructured); isUnstructuredList && !c.scheme.Recognizes(gvk) { + // We need to register the ListKind with UnstructuredList: + // https://github.com/kubernetes/kubernetes/blob/7b2776b89fb1be28d4e9203bdeec079be903c103/staging/src/k8s.io/client-go/dynamic/fake/simple.go#L44-L51 + c.schemeWriteLock.Lock() + c.scheme.AddKnownTypeWithName(gvk.GroupVersion().WithKind(gvk.Kind+"List"), &unstructured.UnstructuredList{}) + c.schemeWriteLock.Unlock() + } + + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + o, err := c.tracker.List(gvr, gvk, listOpts.Namespace) + if err != nil { + return err + } + + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(originalKind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + if err != nil { + return err + } + + if listOpts.LabelSelector == nil && listOpts.FieldSelector == nil { + return nil + } + + // If we're here, either a label or field selector are specified (or both), so before we return + // the list we must filter it. If both selectors are set, they are ANDed. + objs, err := meta.ExtractList(obj) + if err != nil { + return err + } + + filteredList, err := c.filterList(objs, gvk, listOpts.LabelSelector, listOpts.FieldSelector) + if err != nil { + return err + } + + return meta.SetList(obj, filteredList) +} + +func (c *fakeClient) filterList(list []runtime.Object, gvk schema.GroupVersionKind, ls labels.Selector, fs fields.Selector) ([]runtime.Object, error) { + // Filter the objects with the label selector + filteredList := list + if ls != nil { + objsFilteredByLabel, err := objectutil.FilterWithLabels(list, ls) + if err != nil { + return nil, err + } + filteredList = objsFilteredByLabel + } + + // Filter the result of the previous pass with the field selector + if fs != nil { + objsFilteredByField, err := c.filterWithFields(filteredList, gvk, fs) + if err != nil { + return nil, err + } + filteredList = objsFilteredByField + } + + return filteredList, nil +} + +func (c *fakeClient) filterWithFields(list []runtime.Object, gvk schema.GroupVersionKind, fs fields.Selector) ([]runtime.Object, error) { + // We only allow filtering on the basis of a single field to ensure consistency with the + // behavior of the cache reader (which we're faking here). + fieldKey, fieldVal, requiresExact := selector.RequiresExactMatch(fs) + if !requiresExact { + return nil, fmt.Errorf("field selector %s is not in one of the two supported forms \"key==val\" or \"key=val\"", + fs) + } + + // Field selection is mimicked via indexes, so there's no sane answer this function can give + // if there are no indexes registered for the GroupVersionKind of the objects in the list. + indexes := c.indexes[gvk] + if len(indexes) == 0 || indexes[fieldKey] == nil { + return nil, fmt.Errorf("List on GroupVersionKind %v specifies selector on field %s, but no "+ + "index with name %s has been registered for GroupVersionKind %v", gvk, fieldKey, fieldKey, gvk) + } + + indexExtractor := indexes[fieldKey] + filteredList := make([]runtime.Object, 0, len(list)) + for _, obj := range list { + if c.objMatchesFieldSelector(obj, indexExtractor, fieldVal) { + filteredList = append(filteredList, obj) + } + } + return filteredList, nil +} + +func (c *fakeClient) objMatchesFieldSelector(o runtime.Object, extractIndex client.IndexerFunc, val string) bool { + obj, isClientObject := o.(client.Object) + if !isClientObject { + panic(fmt.Errorf("expected object %v to be of type client.Object, but it's not", o)) + } + + for _, extractedVal := range extractIndex(obj) { + if extractedVal == val { + return true + } + } + + return false +} + +func (c *fakeClient) Scheme() *runtime.Scheme { + return c.scheme +} + +func (c *fakeClient) RESTMapper() meta.RESTMapper { + return c.restMapper +} + +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (c *fakeClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return apiutil.GVKForObject(obj, c.scheme) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (c *fakeClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return apiutil.IsObjectNamespaced(obj, c.scheme, c.restMapper) +} + +func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { + createOptions := &client.CreateOptions{} + createOptions.ApplyOptions(opts) + + for _, dryRunOpt := range createOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + + if accessor.GetName() == "" && accessor.GetGenerateName() != "" { + base := accessor.GetGenerateName() + if len(base) > maxGeneratedNameLength { + base = base[:maxGeneratedNameLength] + } + accessor.SetName(fmt.Sprintf("%s%s", base, utilrand.String(randomLength))) + } + // Ignore attempts to set deletion timestamp + if !accessor.GetDeletionTimestamp().IsZero() { + accessor.SetDeletionTimestamp(nil) + } + + return c.tracker.Create(gvr, obj, accessor.GetNamespace()) +} + +func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + delOptions := client.DeleteOptions{} + delOptions.ApplyOptions(opts) + + for _, dryRunOpt := range delOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + // Check the ResourceVersion if that Precondition was specified. + if delOptions.Preconditions != nil && delOptions.Preconditions.ResourceVersion != nil { + name := accessor.GetName() + dbObj, err := c.tracker.Get(gvr, accessor.GetNamespace(), name) + if err != nil { + return err + } + oldAccessor, err := meta.Accessor(dbObj) + if err != nil { + return err + } + actualRV := oldAccessor.GetResourceVersion() + expectRV := *delOptions.Preconditions.ResourceVersion + if actualRV != expectRV { + msg := fmt.Sprintf( + "the ResourceVersion in the precondition (%s) does not match the ResourceVersion in record (%s). "+ + "The object might have been modified", + expectRV, actualRV) + return apierrors.NewConflict(gvr.GroupResource(), name, errors.New(msg)) + } + } + + return c.deleteObject(gvr, accessor) +} + +func (c *fakeClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + dcOptions := client.DeleteAllOfOptions{} + dcOptions.ApplyOptions(opts) + + for _, dryRunOpt := range dcOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + o, err := c.tracker.List(gvr, gvk, dcOptions.Namespace) + if err != nil { + return err + } + + objs, err := meta.ExtractList(o) + if err != nil { + return err + } + filteredObjs, err := objectutil.FilterWithLabels(objs, dcOptions.LabelSelector) + if err != nil { + return err + } + for _, o := range filteredObjs { + accessor, err := meta.Accessor(o) + if err != nil { + return err + } + err = c.deleteObject(gvr, accessor) + if err != nil { + return err + } + } + return nil +} + +func (c *fakeClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { + return c.update(obj, false, opts...) +} + +func (c *fakeClient) update(obj client.Object, isStatus bool, opts ...client.UpdateOption) error { + updateOptions := &client.UpdateOptions{} + updateOptions.ApplyOptions(opts) + + for _, dryRunOpt := range updateOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + return c.tracker.update(gvr, obj, accessor.GetNamespace(), isStatus, false) +} + +func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + return c.patch(obj, patch, opts...) +} + +func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + patchOptions := &client.PatchOptions{} + patchOptions.ApplyOptions(opts) + + for _, dryRunOpt := range patchOptions.DryRun { + if dryRunOpt == metav1.DryRunAll { + return nil + } + } + + gvr, err := getGVRFromObject(obj, c.scheme) + if err != nil { + return err + } + accessor, err := meta.Accessor(obj) + if err != nil { + return err + } + data, err := patch.Data(obj) + if err != nil { + return err + } + + gvk, err := apiutil.GVKForObject(obj, c.scheme) + if err != nil { + return err + } + + oldObj, err := c.tracker.Get(gvr, accessor.GetNamespace(), accessor.GetName()) + if err != nil { + return err + } + oldAccessor, err := meta.Accessor(oldObj) + if err != nil { + return err + } + + // Apply patch without updating object. + // To remain in accordance with the behavior of k8s api behavior, + // a patch must not allow for changes to the deletionTimestamp of an object. + // The reaction() function applies the patch to the object and calls Update(), + // whereas dryPatch() replicates this behavior but skips the call to Update(). + // This ensures that the patch may be rejected if a deletionTimestamp is modified, prior + // to updating the object. + action := testing.NewPatchAction(gvr, accessor.GetNamespace(), accessor.GetName(), patch.Type(), data) + o, err := dryPatch(action, c.tracker) + if err != nil { + return err + } + newObj, err := meta.Accessor(o) + if err != nil { + return err + } + + // Validate that deletionTimestamp has not been changed + if !deletionTimestampEqual(newObj, oldAccessor) { + return fmt.Errorf("rejected patch, metadata.deletionTimestamp immutable") + } + + reaction := testing.ObjectReaction(c.tracker) + handled, o, err := reaction(action) + if err != nil { + return err + } + if !handled { + panic("tracker could not handle patch method") + } + ta, err := meta.TypeAccessor(o) + if err != nil { + return err + } + ta.SetKind(gvk.Kind) + ta.SetAPIVersion(gvk.GroupVersion().String()) + + j, err := json.Marshal(o) + if err != nil { + return err + } + decoder := scheme.Codecs.UniversalDecoder() + zero(obj) + _, _, err = decoder.Decode(j, nil, obj) + return err +} + +// Applying a patch results in a deletionTimestamp that is truncated to the nearest second. +// Check that the diff between a new and old deletion timestamp is within a reasonable threshold +// to be considered unchanged. +func deletionTimestampEqual(newObj metav1.Object, obj metav1.Object) bool { + newTime := newObj.GetDeletionTimestamp() + oldTime := obj.GetDeletionTimestamp() + + if newTime == nil || oldTime == nil { + return newTime == oldTime + } + return newTime.Time.Sub(oldTime.Time).Abs() < time.Second +} + +// The behavior of applying the patch is pulled out into dryPatch(), +// which applies the patch and returns an object, but does not Update() the object. +// This function returns a patched runtime object that may then be validated before a call to Update() is executed. +// This results in some code duplication, but was found to be a cleaner alternative than unmarshalling and introspecting the patch data +// and easier than refactoring the k8s client-go method upstream. +// Duplicate of upstream: https://github.com/kubernetes/client-go/blob/783d0d33626e59d55d52bfd7696b775851f92107/testing/fixture.go#L146-L194 +func dryPatch(action testing.PatchActionImpl, tracker testing.ObjectTracker) (runtime.Object, error) { + ns := action.GetNamespace() + gvr := action.GetResource() + + obj, err := tracker.Get(gvr, ns, action.GetName()) + if err != nil { + return nil, err + } + + old, err := json.Marshal(obj) + if err != nil { + return nil, err + } + + // reset the object in preparation to unmarshal, since unmarshal does not guarantee that fields + // in obj that are removed by patch are cleared + value := reflect.ValueOf(obj) + value.Elem().Set(reflect.New(value.Type().Elem()).Elem()) + + switch action.GetPatchType() { + case types.JSONPatchType: + patch, err := jsonpatch.DecodePatch(action.GetPatch()) + if err != nil { + return nil, err + } + modified, err := patch.Apply(old) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(modified, obj); err != nil { + return nil, err + } + case types.MergePatchType: + modified, err := jsonpatch.MergePatch(old, action.GetPatch()) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(modified, obj); err != nil { + return nil, err + } + case types.StrategicMergePatchType, types.ApplyPatchType: + mergedByte, err := strategicpatch.StrategicMergePatch(old, action.GetPatch(), obj) + if err != nil { + return nil, err + } + if err = json.Unmarshal(mergedByte, obj); err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("PatchType is not supported") + } + return obj, nil +} + +func copyNonStatusFrom(old, new runtime.Object) error { + newClientObject, ok := new.(client.Object) + if !ok { + return fmt.Errorf("%T is not a client.Object", new) + } + // The only thing other than status we have to retain + rv := newClientObject.GetResourceVersion() + + oldMapStringAny, err := toMapStringAny(old) + if err != nil { + return fmt.Errorf("failed to convert old to *unstructured.Unstructured: %w", err) + } + newMapStringAny, err := toMapStringAny(new) + if err != nil { + return fmt.Errorf("failed to convert new to *unststructured.Unstructured: %w", err) + } + + // delete everything other than status in case it has fields that were not present in + // the old object + for k := range newMapStringAny { + if k != "status" { + delete(newMapStringAny, k) + } + } + // copy everything other than status from the old object + for k := range oldMapStringAny { + if k != "status" { + newMapStringAny[k] = oldMapStringAny[k] + } + } + + newClientObject.SetResourceVersion(rv) + + if err := fromMapStringAny(newMapStringAny, new); err != nil { + return fmt.Errorf("failed to convert back from map[string]any: %w", err) + } + return nil +} + +// copyStatusFrom copies the status from old into new +func copyStatusFrom(old, new runtime.Object) error { + oldMapStringAny, err := toMapStringAny(old) + if err != nil { + return fmt.Errorf("failed to convert old to *unstructured.Unstructured: %w", err) + } + newMapStringAny, err := toMapStringAny(new) + if err != nil { + return fmt.Errorf("failed to convert new to *unststructured.Unstructured: %w", err) + } + + newMapStringAny["status"] = oldMapStringAny["status"] + + if err := fromMapStringAny(newMapStringAny, new); err != nil { + return fmt.Errorf("failed to convert back from map[string]any: %w", err) + } + + return nil +} + +func toMapStringAny(obj runtime.Object) (map[string]any, error) { + if unstructured, isUnstructured := obj.(*unstructured.Unstructured); isUnstructured { + return unstructured.Object, nil + } + + serialized, err := json.Marshal(obj) + if err != nil { + return nil, err + } + + u := map[string]any{} + return u, json.Unmarshal(serialized, &u) +} + +func fromMapStringAny(u map[string]any, target runtime.Object) error { + if targetUnstructured, isUnstructured := target.(*unstructured.Unstructured); isUnstructured { + targetUnstructured.Object = u + return nil + } + + serialized, err := json.Marshal(u) + if err != nil { + return fmt.Errorf("failed to serialize: %w", err) + } + + if err := json.Unmarshal(serialized, &target); err != nil { + return fmt.Errorf("failed to deserialize: %w", err) + } + + return nil +} + +func (c *fakeClient) Status() client.SubResourceWriter { + return c.SubResource("status") +} + +func (c *fakeClient) SubResource(subResource string) client.SubResourceClient { + return &fakeSubResourceClient{client: c, subResource: subResource} +} + +func (c *fakeClient) deleteObject(gvr schema.GroupVersionResource, accessor metav1.Object) error { + old, err := c.tracker.Get(gvr, accessor.GetNamespace(), accessor.GetName()) + if err == nil { + oldAccessor, err := meta.Accessor(old) + if err == nil { + if len(oldAccessor.GetFinalizers()) > 0 { + now := metav1.Now() + oldAccessor.SetDeletionTimestamp(&now) + // Call update directly with mutability parameter set to true to allow + // changes to deletionTimestamp + return c.tracker.update(gvr, old, accessor.GetNamespace(), false, true) + } + } + } + + //TODO: implement propagation + return c.tracker.Delete(gvr, accessor.GetNamespace(), accessor.GetName()) +} + +func getGVRFromObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersionResource, error) { + gvk, err := apiutil.GVKForObject(obj, scheme) + if err != nil { + return schema.GroupVersionResource{}, err + } + gvr, _ := meta.UnsafeGuessKindToResource(gvk) + return gvr, nil +} + +type fakeSubResourceClient struct { + client *fakeClient + subResource string +} + +func (sw *fakeSubResourceClient) Get(ctx context.Context, obj, subResource client.Object, opts ...client.SubResourceGetOption) error { + panic("fakeSubResourceClient does not support get") +} + +func (sw *fakeSubResourceClient) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error { + switch sw.subResource { + case "eviction": + _, isEviction := subResource.(*policyv1beta1.Eviction) + if !isEviction { + _, isEviction = subResource.(*policyv1.Eviction) + } + if !isEviction { + return apierrors.NewBadRequest(fmt.Sprintf("got invalid type %t, expected Eviction", subResource)) + } + if _, isPod := obj.(*corev1.Pod); !isPod { + return apierrors.NewNotFound(schema.GroupResource{}, "") + } + + return sw.client.Delete(ctx, obj) + default: + return fmt.Errorf("fakeSubResourceWriter does not support create for %s", sw.subResource) + } +} + +func (sw *fakeSubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + updateOptions := client.SubResourceUpdateOptions{} + updateOptions.ApplyOptions(opts) + + body := obj + if updateOptions.SubResourceBody != nil { + body = updateOptions.SubResourceBody + } + return sw.client.update(body, true, &updateOptions.UpdateOptions) +} + +func (sw *fakeSubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + patchOptions := client.SubResourcePatchOptions{} + patchOptions.ApplyOptions(opts) + + body := obj + if patchOptions.SubResourceBody != nil { + body = patchOptions.SubResourceBody + } + + return sw.client.patch(body, patch, &patchOptions.PatchOptions) +} + +func allowsUnconditionalUpdate(gvk schema.GroupVersionKind) bool { + switch gvk.Group { + case "apps": + switch gvk.Kind { + case "ControllerRevision", "DaemonSet", "Deployment", "ReplicaSet", "StatefulSet": + return true + } + case "autoscaling": + switch gvk.Kind { + case "HorizontalPodAutoscaler": + return true + } + case "batch": + switch gvk.Kind { + case "CronJob", "Job": + return true + } + case "certificates": + switch gvk.Kind { + case "Certificates": + return true + } + case "flowcontrol": + switch gvk.Kind { + case "FlowSchema", "PriorityLevelConfiguration": + return true + } + case "networking": + switch gvk.Kind { + case "Ingress", "IngressClass", "NetworkPolicy": + return true + } + case "policy": + switch gvk.Kind { + case "PodSecurityPolicy": + return true + } + case "rbac": + switch gvk.Kind { + case "ClusterRole", "ClusterRoleBinding", "Role", "RoleBinding": + return true + } + case "scheduling": + switch gvk.Kind { + case "PriorityClass": + return true + } + case "settings": + switch gvk.Kind { + case "PodPreset": + return true + } + case "storage": + switch gvk.Kind { + case "StorageClass": + return true + } + case "": + switch gvk.Kind { + case "ConfigMap", "Endpoint", "Event", "LimitRange", "Namespace", "Node", + "PersistentVolume", "PersistentVolumeClaim", "Pod", "PodTemplate", + "ReplicationController", "ResourceQuota", "Secret", "Service", + "ServiceAccount", "EndpointSlice": + return true + } + } + + return false +} + +func allowsCreateOnUpdate(gvk schema.GroupVersionKind) bool { + switch gvk.Group { + case "coordination": + switch gvk.Kind { + case "Lease": + return true + } + case "node": + switch gvk.Kind { + case "RuntimeClass": + return true + } + case "rbac": + switch gvk.Kind { + case "ClusterRole", "ClusterRoleBinding", "Role", "RoleBinding": + return true + } + case "": + switch gvk.Kind { + case "Endpoint", "Event", "LimitRange", "Service": + return true + } + } + + return false +} + +func inTreeResourcesWithStatus() []schema.GroupVersionKind { + return []schema.GroupVersionKind{ + {Version: "v1", Kind: "Namespace"}, + {Version: "v1", Kind: "Node"}, + {Version: "v1", Kind: "PersistentVolumeClaim"}, + {Version: "v1", Kind: "PersistentVolume"}, + {Version: "v1", Kind: "Pod"}, + {Version: "v1", Kind: "ReplicationController"}, + {Version: "v1", Kind: "Service"}, + + {Group: "apps", Version: "v1", Kind: "Deployment"}, + {Group: "apps", Version: "v1", Kind: "DaemonSet"}, + {Group: "apps", Version: "v1", Kind: "ReplicaSet"}, + {Group: "apps", Version: "v1", Kind: "StatefulSet"}, + + {Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}, + + {Group: "batch", Version: "v1", Kind: "CronJob"}, + {Group: "batch", Version: "v1", Kind: "Job"}, + + {Group: "certificates.k8s.io", Version: "v1", Kind: "CertificateSigningRequest"}, + + {Group: "networking.k8s.io", Version: "v1", Kind: "Ingress"}, + {Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}, + + {Group: "policy", Version: "v1", Kind: "PodDisruptionBudget"}, + + {Group: "storage.k8s.io", Version: "v1", Kind: "VolumeAttachment"}, + + {Group: "apiextensions.k8s.io", Version: "v1", Kind: "CustomResourceDefinition"}, + + {Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchema"}, + {Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"}, + } +} + +// zero zeros the value of a pointer. +func zero(x interface{}) { + if x == nil { + return + } + res := reflect.ValueOf(x).Elem() + res.Set(reflect.Zero(res.Type())) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go new file mode 100644 index 00000000000..d0614666e37 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package fake provides a fake client for testing. + +A fake client is backed by its simple object store indexed by GroupVersionResource. +You can create a fake client with optional objects. + + client := NewFakeClientWithScheme(scheme, initObjs...) // initObjs is a slice of runtime.Object + +You can invoke the methods defined in the Client interface. + +When in doubt, it's almost always better not to use this package and instead use +envtest.Environment with a real client and API server. + +WARNING: ⚠️ Current Limitations / Known Issues with the fake Client ⚠️ + - This client does not have a way to inject specific errors to test handled vs. unhandled errors. + - There is some support for sub resources which can cause issues with tests if you're trying to update + e.g. metadata and status in the same reconcile. + - No OpenAPI validation is performed when creating or updating objects. + - ObjectMeta's `Generation` and `ResourceVersion` don't behave properly, Patch or Update + operations that rely on these fields will fail, or give false positives. +*/ +package fake diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go new file mode 100644 index 00000000000..3d3f3cb0118 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go @@ -0,0 +1,166 @@ +package interceptor + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Funcs contains functions that are called instead of the underlying client's methods. +type Funcs struct { + Get func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error + List func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error + Create func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error + Delete func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error + DeleteAllOf func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error + Update func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error + Patch func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error + Watch func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) + SubResource func(client client.WithWatch, subResource string) client.SubResourceClient + SubResourceGet func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error + SubResourceCreate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error + SubResourceUpdate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error + SubResourcePatch func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error +} + +// NewClient returns a new interceptor client that calls the functions in funcs instead of the underlying client's methods, if they are not nil. +func NewClient(interceptedClient client.WithWatch, funcs Funcs) client.WithWatch { + return interceptor{ + client: interceptedClient, + funcs: funcs, + } +} + +type interceptor struct { + client client.WithWatch + funcs Funcs +} + +var _ client.WithWatch = &interceptor{} + +func (c interceptor) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return c.client.GroupVersionKindFor(obj) +} + +func (c interceptor) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return c.client.IsObjectNamespaced(obj) +} + +func (c interceptor) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + if c.funcs.Get != nil { + return c.funcs.Get(ctx, c.client, key, obj, opts...) + } + return c.client.Get(ctx, key, obj, opts...) +} + +func (c interceptor) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + if c.funcs.List != nil { + return c.funcs.List(ctx, c.client, list, opts...) + } + return c.client.List(ctx, list, opts...) +} + +func (c interceptor) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { + if c.funcs.Create != nil { + return c.funcs.Create(ctx, c.client, obj, opts...) + } + return c.client.Create(ctx, obj, opts...) +} + +func (c interceptor) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { + if c.funcs.Delete != nil { + return c.funcs.Delete(ctx, c.client, obj, opts...) + } + return c.client.Delete(ctx, obj, opts...) +} + +func (c interceptor) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { + if c.funcs.Update != nil { + return c.funcs.Update(ctx, c.client, obj, opts...) + } + return c.client.Update(ctx, obj, opts...) +} + +func (c interceptor) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { + if c.funcs.Patch != nil { + return c.funcs.Patch(ctx, c.client, obj, patch, opts...) + } + return c.client.Patch(ctx, obj, patch, opts...) +} + +func (c interceptor) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { + if c.funcs.DeleteAllOf != nil { + return c.funcs.DeleteAllOf(ctx, c.client, obj, opts...) + } + return c.client.DeleteAllOf(ctx, obj, opts...) +} + +func (c interceptor) Status() client.SubResourceWriter { + return c.SubResource("status") +} + +func (c interceptor) SubResource(subResource string) client.SubResourceClient { + if c.funcs.SubResource != nil { + return c.funcs.SubResource(c.client, subResource) + } + return subResourceInterceptor{ + subResourceName: subResource, + client: c.client, + funcs: c.funcs, + } +} + +func (c interceptor) Scheme() *runtime.Scheme { + return c.client.Scheme() +} + +func (c interceptor) RESTMapper() meta.RESTMapper { + return c.client.RESTMapper() +} + +func (c interceptor) Watch(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) { + if c.funcs.Watch != nil { + return c.funcs.Watch(ctx, c.client, obj, opts...) + } + return c.client.Watch(ctx, obj, opts...) +} + +type subResourceInterceptor struct { + subResourceName string + client client.Client + funcs Funcs +} + +var _ client.SubResourceClient = &subResourceInterceptor{} + +func (s subResourceInterceptor) Get(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error { + if s.funcs.SubResourceGet != nil { + return s.funcs.SubResourceGet(ctx, s.client, s.subResourceName, obj, subResource, opts...) + } + return s.client.SubResource(s.subResourceName).Get(ctx, obj, subResource, opts...) +} + +func (s subResourceInterceptor) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error { + if s.funcs.SubResourceCreate != nil { + return s.funcs.SubResourceCreate(ctx, s.client, s.subResourceName, obj, subResource, opts...) + } + return s.client.SubResource(s.subResourceName).Create(ctx, obj, subResource, opts...) +} + +func (s subResourceInterceptor) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { + if s.funcs.SubResourceUpdate != nil { + return s.funcs.SubResourceUpdate(ctx, s.client, s.subResourceName, obj, opts...) + } + return s.client.SubResource(s.subResourceName).Update(ctx, obj, opts...) +} + +func (s subResourceInterceptor) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { + if s.funcs.SubResourcePatch != nil { + return s.funcs.SubResourcePatch(ctx, s.client, s.subResourceName, obj, patch, opts...) + } + return s.client.SubResource(s.subResourceName).Patch(ctx, obj, patch, opts...) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go index 58c2ece15b1..0ddda3163d8 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go @@ -20,6 +20,7 @@ import ( "context" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" @@ -50,7 +51,7 @@ type Reader interface { // Get retrieves an obj for the given object key from the Kubernetes Cluster. // obj must be a struct pointer so that obj can be updated with the response // returned by the Server. - Get(ctx context.Context, key ObjectKey, obj Object) error + Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error // List retrieves list of objects for a given namespace and list options. On a // successful call, Items field in the list will be populated with the @@ -60,7 +61,8 @@ type Reader interface { // Writer knows how to create, delete, and update Kubernetes objects. type Writer interface { - // Create saves the object obj in the Kubernetes cluster. + // Create saves the object obj in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. Create(ctx context.Context, obj Object, opts ...CreateOption) error // Delete deletes the given obj from Kubernetes cluster. @@ -81,20 +83,80 @@ type Writer interface { // StatusClient knows how to create a client which can update status subresource // for kubernetes objects. type StatusClient interface { - Status() StatusWriter + Status() SubResourceWriter } -// StatusWriter knows how to update status subresource of a Kubernetes object. -type StatusWriter interface { +// SubResourceClientConstructor knows how to create a client which can update subresource +// for kubernetes objects. +type SubResourceClientConstructor interface { + // SubResourceClientConstructor returns a subresource client for the named subResource. Known + // upstream subResources usages are: + // - ServiceAccount token creation: + // sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // token := &authenticationv1.TokenRequest{} + // c.SubResourceClient("token").Create(ctx, sa, token) + // + // - Pod eviction creation: + // pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // c.SubResourceClient("eviction").Create(ctx, pod, &policyv1.Eviction{}) + // + // - Pod binding creation: + // pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // binding := &corev1.Binding{Target: corev1.ObjectReference{Name: "my-node"}} + // c.SubResourceClient("binding").Create(ctx, pod, binding) + // + // - CertificateSigningRequest approval: + // csr := &certificatesv1.CertificateSigningRequest{ + // ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}, + // Status: certificatesv1.CertificateSigningRequestStatus{ + // Conditions: []certificatesv1.[]CertificateSigningRequestCondition{{ + // Type: certificatesv1.CertificateApproved, + // Status: corev1.ConditionTrue, + // }}, + // }, + // } + // c.SubResourceClient("approval").Update(ctx, csr) + // + // - Scale retrieval: + // dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // scale := &autoscalingv1.Scale{} + // c.SubResourceClient("scale").Get(ctx, dep, scale) + // + // - Scale update: + // dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}} + // scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: 2}} + // c.SubResourceClient("scale").Update(ctx, dep, client.WithSubResourceBody(scale)) + SubResource(subResource string) SubResourceClient +} + +// StatusWriter is kept for backward compatibility. +type StatusWriter = SubResourceWriter + +// SubResourceReader knows how to read SubResources +type SubResourceReader interface { + Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error +} + +// SubResourceWriter knows how to update subresource of a Kubernetes object. +type SubResourceWriter interface { + // Create saves the subResource object in the Kubernetes cluster. obj must be a + // struct pointer so that obj can be updated with the content returned by the Server. + Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error // Update updates the fields corresponding to the status subresource for the // given obj. obj must be a struct pointer so that obj can be updated // with the content returned by the Server. - Update(ctx context.Context, obj Object, opts ...UpdateOption) error + Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error // Patch patches the given object's subresource. obj must be a struct // pointer so that obj can be updated with the content returned by the // Server. - Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error + Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error +} + +// SubResourceClient knows how to perform CRU operations on Kubernetes objects. +type SubResourceClient interface { + SubResourceReader + SubResourceWriter } // Client knows how to perform CRUD operations on Kubernetes objects. @@ -102,11 +164,16 @@ type Client interface { Reader Writer StatusClient + SubResourceClientConstructor // Scheme returns the scheme this client is using. Scheme() *runtime.Scheme // RESTMapper returns the rest this client is using. RESTMapper() meta.RESTMapper + // GroupVersionKindFor returns the GroupVersionKind for the given object. + GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) + // IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. + IsObjectNamespaced(obj runtime.Object) (bool, error) } // WithWatch supports Watch on top of the CRUD operations supported by @@ -143,3 +210,13 @@ func IgnoreNotFound(err error) error { } return err } + +// IgnoreAlreadyExists returns nil on AlreadyExists errors. +// All other values that are not AlreadyExists errors or nil are returned unmodified. +func IgnoreAlreadyExists(err error) error { + if apierrors.IsAlreadyExists(err) { + return nil + } + + return err +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go index db495ca46be..d0c6b8e13ae 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go @@ -116,7 +116,7 @@ func (mc *metadataClient) Patch(ctx context.Context, obj Object, patch Patch, op } // Get implements client.Client. -func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object) error { +func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { metadata, ok := obj.(*metav1.PartialObjectMetadata) if !ok { return fmt.Errorf("metadata client did not understand object: %T", obj) @@ -124,12 +124,15 @@ func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object) er gvk := metadata.GroupVersionKind() + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) + resInt, err := mc.getResourceInterface(gvk, key.Namespace) if err != nil { return err } - res, err := resInt.Get(ctx, key.Name, metav1.GetOptions{}) + res, err := resInt.Get(ctx, key.Name, *getOpts.AsGetOptions()) if err != nil { return err } @@ -165,7 +168,7 @@ func (mc *metadataClient) List(ctx context.Context, obj ObjectList, opts ...List return nil } -func (mc *metadataClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { +func (mc *metadataClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { metadata, ok := obj.(*metav1.PartialObjectMetadata) if !ok { return fmt.Errorf("metadata client did not understand object: %T", obj) @@ -177,16 +180,24 @@ func (mc *metadataClient) PatchStatus(ctx context.Context, obj Object, patch Pat return err } - data, err := patch.Data(obj) + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) if err != nil { return err } - patchOpts := &PatchOptions{} - res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions(), "status") + res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions(), subResource) if err != nil { return err } + *metadata = *res metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata return nil diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go index 45a694543ee..222dc795793 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go @@ -22,7 +22,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/internal/objectutil" + "k8s.io/apimachinery/pkg/runtime/schema" ) // NewNamespacedClient wraps an existing client enforcing the namespace value. @@ -52,9 +52,19 @@ func (n *namespacedClient) RESTMapper() meta.RESTMapper { return n.client.RESTMapper() } -// Create implements clinet.Client. +// GroupVersionKindFor returns the GroupVersionKind for the given object. +func (n *namespacedClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error) { + return n.client.GroupVersionKindFor(obj) +} + +// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced. +func (n *namespacedClient) IsObjectNamespaced(obj runtime.Object) (bool, error) { + return n.client.IsObjectNamespaced(obj) +} + +// Create implements client.Client. func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -72,7 +82,7 @@ func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...Creat // Update implements client.Client. func (n *namespacedClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -90,7 +100,7 @@ func (n *namespacedClient) Update(ctx context.Context, obj Object, opts ...Updat // Delete implements client.Client. func (n *namespacedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -108,7 +118,7 @@ func (n *namespacedClient) Delete(ctx context.Context, obj Object, opts ...Delet // DeleteAllOf implements client.Client. func (n *namespacedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -121,7 +131,7 @@ func (n *namespacedClient) DeleteAllOf(ctx context.Context, obj Object, opts ... // Patch implements client.Client. func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -138,18 +148,18 @@ func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, o } // Get implements client.Client. -func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper()) +func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + isNamespaceScoped, err := n.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } if isNamespaceScoped { if key.Namespace != "" && key.Namespace != n.namespace { - return fmt.Errorf("namespace %s provided for the object %s does not match the namesapce %s on the client", key.Namespace, obj.GetName(), n.namespace) + return fmt.Errorf("namespace %s provided for the object %s does not match the namespace %s on the client", key.Namespace, obj.GetName(), n.namespace) } key.Namespace = n.namespace } - return n.client.Get(ctx, key, obj) + return n.client.Get(ctx, key, obj, opts...) } // List implements client.Client. @@ -161,23 +171,44 @@ func (n *namespacedClient) List(ctx context.Context, obj ObjectList, opts ...Lis } // Status implements client.StatusClient. -func (n *namespacedClient) Status() StatusWriter { - return &namespacedClientStatusWriter{StatusClient: n.client.Status(), namespace: n.namespace, namespacedclient: n} +func (n *namespacedClient) Status() SubResourceWriter { + return n.SubResource("status") } -// ensure namespacedClientStatusWriter implements client.StatusWriter. -var _ StatusWriter = &namespacedClientStatusWriter{} +// SubResource implements client.SubResourceClient. +func (n *namespacedClient) SubResource(subResource string) SubResourceClient { + return &namespacedClientSubResourceClient{client: n.client.SubResource(subResource), namespace: n.namespace, namespacedclient: n} +} -type namespacedClientStatusWriter struct { - StatusClient StatusWriter +// ensure namespacedClientSubResourceClient implements client.SubResourceClient. +var _ SubResourceClient = &namespacedClientSubResourceClient{} + +type namespacedClientSubResourceClient struct { + client SubResourceClient namespace string namespacedclient Client } -// Update implements client.StatusWriter. -func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper()) +func (nsw *namespacedClientSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + + return nsw.client.Get(ctx, obj, subResource, opts...) +} +func (nsw *namespacedClientSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -190,13 +221,31 @@ func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object, if isNamespaceScoped && objectNamespace == "" { obj.SetNamespace(nsw.namespace) } - return nsw.StatusClient.Update(ctx, obj, opts...) + + return nsw.client.Create(ctx, obj, subResource, opts...) } -// Patch implements client.StatusWriter. -func (nsw *namespacedClientStatusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper()) +// Update implements client.SubResourceWriter. +func (nsw *namespacedClientSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) + if err != nil { + return fmt.Errorf("error finding the scope of the object: %w", err) + } + + objectNamespace := obj.GetNamespace() + if objectNamespace != nsw.namespace && objectNamespace != "" { + return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace) + } + + if isNamespaceScoped && objectNamespace == "" { + obj.SetNamespace(nsw.namespace) + } + return nsw.client.Update(ctx, obj, opts...) +} +// Patch implements client.SubResourceWriter. +func (nsw *namespacedClientSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error { + isNamespaceScoped, err := nsw.namespacedclient.IsObjectNamespaced(obj) if err != nil { return fmt.Errorf("error finding the scope of the object: %w", err) } @@ -209,5 +258,5 @@ func (nsw *namespacedClientStatusWriter) Patch(ctx context.Context, obj Object, if isNamespaceScoped && objectNamespace == "" { obj.SetNamespace(nsw.namespace) } - return nsw.StatusClient.Patch(ctx, obj, patch, opts...) + return nsw.client.Patch(ctx, obj, patch, opts...) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go index 7990f56ab09..50a461f1cc6 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go @@ -37,6 +37,12 @@ type DeleteOption interface { ApplyToDelete(*DeleteOptions) } +// GetOption is some configuration that modifies options for a get request. +type GetOption interface { + // ApplyToGet applies this configuration to the given get options. + ApplyToGet(*GetOptions) +} + // ListOption is some configuration that modifies options for a list request. type ListOption interface { // ApplyToList applies this configuration to the given list options. @@ -61,6 +67,29 @@ type DeleteAllOfOption interface { ApplyToDeleteAllOf(*DeleteAllOfOptions) } +// SubResourceGetOption modifies options for a SubResource Get request. +type SubResourceGetOption interface { + ApplyToSubResourceGet(*SubResourceGetOptions) +} + +// SubResourceUpdateOption is some configuration that modifies options for a update request. +type SubResourceUpdateOption interface { + // ApplyToSubResourceUpdate applies this configuration to the given update options. + ApplyToSubResourceUpdate(*SubResourceUpdateOptions) +} + +// SubResourceCreateOption is some configuration that modifies options for a create request. +type SubResourceCreateOption interface { + // ApplyToSubResourceCreate applies this configuration to the given create options. + ApplyToSubResourceCreate(*SubResourceCreateOptions) +} + +// SubResourcePatchOption configures a subresource patch request. +type SubResourcePatchOption interface { + // ApplyToSubResourcePatch applies the configuration on the given patch options. + ApplyToSubResourcePatch(*SubResourcePatchOptions) +} + // }}} // {{{ Multi-Type Options @@ -90,10 +119,23 @@ func (dryRunAll) ApplyToPatch(opts *PatchOptions) { func (dryRunAll) ApplyToDelete(opts *DeleteOptions) { opts.DryRun = []string{metav1.DryRunAll} } + func (dryRunAll) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { opts.DryRun = []string{metav1.DryRunAll} } +func (dryRunAll) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + +func (dryRunAll) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + opts.DryRun = []string{metav1.DryRunAll} +} + // FieldOwner set the field manager name for the given server-side apply patch. type FieldOwner string @@ -112,6 +154,21 @@ func (f FieldOwner) ApplyToUpdate(opts *UpdateOptions) { opts.FieldManager = string(f) } +// ApplyToSubResourcePatch applies this configuration to the given patch options. +func (f FieldOwner) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + opts.FieldManager = string(f) +} + +// ApplyToSubResourceCreate applies this configuration to the given create options. +func (f FieldOwner) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) { + opts.FieldManager = string(f) +} + +// ApplyToSubResourceUpdate applies this configuration to the given update options. +func (f FieldOwner) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) { + opts.FieldManager = string(f) +} + // }}} // {{{ Create Options @@ -311,6 +368,45 @@ func (p PropagationPolicy) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { // }}} +// {{{ Get Options + +// GetOptions contains options for get operation. +// Now it only has a Raw field, with support for specific resourceVersion. +type GetOptions struct { + // Raw represents raw GetOptions, as passed to the API server. Note + // that these may not be respected by all implementations of interface. + Raw *metav1.GetOptions +} + +var _ GetOption = &GetOptions{} + +// ApplyToGet implements GetOption for GetOptions. +func (o *GetOptions) ApplyToGet(lo *GetOptions) { + if o.Raw != nil { + lo.Raw = o.Raw + } +} + +// AsGetOptions returns these options as a flattened metav1.GetOptions. +// This may mutate the Raw field. +func (o *GetOptions) AsGetOptions() *metav1.GetOptions { + if o == nil || o.Raw == nil { + return &metav1.GetOptions{} + } + return o.Raw +} + +// ApplyOptions applies the given get options on these options, +// and then returns itself (for convenient chaining). +func (o *GetOptions) ApplyOptions(opts []GetOption) *GetOptions { + for _, opt := range opts { + opt.ApplyToGet(o) + } + return o +} + +// }}} + // {{{ List Options // ListOptions contains options for limiting or filtering results. @@ -341,6 +437,12 @@ type ListOptions struct { // it has expired. This field is not supported if watch is true in the Raw ListOptions. Continue string + // UnsafeDisableDeepCopy indicates not to deep copy objects during list objects. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + // +optional + UnsafeDisableDeepCopy *bool + // Raw represents raw ListOptions, as passed to the API server. Note // that these may not be respected by all implementations of interface, // and the LabelSelector, FieldSelector, Limit and Continue fields are ignored. @@ -369,6 +471,9 @@ func (o *ListOptions) ApplyToList(lo *ListOptions) { if o.Continue != "" { lo.Continue = o.Continue } + if o.UnsafeDisableDeepCopy != nil { + lo.UnsafeDisableDeepCopy = o.UnsafeDisableDeepCopy + } } // AsListOptions returns these options as a flattened metav1.ListOptions. @@ -501,6 +606,11 @@ func (n InNamespace) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) { n.ApplyToList(&opts.ListOptions) } +// AsSelector returns a selector that matches objects in the given namespace. +func (n InNamespace) AsSelector() fields.Selector { + return fields.SelectorFromSet(fields.Set{"metadata.namespace": string(n)}) +} + // Limit specifies the maximum number of results to return from the server. // Limit does not implement DeleteAllOfOption interface because the server // does not support setting it for deletecollection operations. @@ -511,6 +621,25 @@ func (l Limit) ApplyToList(opts *ListOptions) { opts.Limit = int64(l) } +// UnsafeDisableDeepCopyOption indicates not to deep copy objects during list objects. +// Be very careful with this, when enabled you must DeepCopy any object before mutating it, +// otherwise you will mutate the object in the cache. +type UnsafeDisableDeepCopyOption bool + +// ApplyToList applies this configuration to the given an List options. +func (d UnsafeDisableDeepCopyOption) ApplyToList(opts *ListOptions) { + definitelyTrue := true + definitelyFalse := false + if d { + opts.UnsafeDisableDeepCopy = &definitelyTrue + } else { + opts.UnsafeDisableDeepCopy = &definitelyFalse + } +} + +// UnsafeDisableDeepCopy indicates not to deep copy objects during list objects. +const UnsafeDisableDeepCopy = UnsafeDisableDeepCopyOption(true) + // Continue sets a continuation token to retrieve chunks of results when using limit. // Continue does not implement DeleteAllOfOption interface because the server // does not support setting it for deletecollection operations. @@ -664,6 +793,11 @@ func (forceOwnership) ApplyToPatch(opts *PatchOptions) { opts.Force = &definitelyTrue } +func (forceOwnership) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { + definitelyTrue := true + opts.Force = &definitelyTrue +} + // }}} // {{{ DeleteAllOf Options diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go index 10984c5342e..11d60838856 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go @@ -19,7 +19,7 @@ package client import ( "fmt" - jsonpatch "github.com/evanphx/json-patch" + jsonpatch "github.com/evanphx/json-patch/v5" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/strategicpatch" diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/split.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/split.go deleted file mode 100644 index bf4b861f391..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/split.go +++ /dev/null @@ -1,141 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package client - -import ( - "context" - "strings" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -// NewDelegatingClientInput encapsulates the input parameters to create a new delegating client. -type NewDelegatingClientInput struct { - CacheReader Reader - Client Client - UncachedObjects []Object - CacheUnstructured bool -} - -// NewDelegatingClient creates a new delegating client. -// -// A delegating client forms a Client by composing separate reader, writer and -// statusclient interfaces. This way, you can have an Client that reads from a -// cache and writes to the API server. -func NewDelegatingClient(in NewDelegatingClientInput) (Client, error) { - uncachedGVKs := map[schema.GroupVersionKind]struct{}{} - for _, obj := range in.UncachedObjects { - gvk, err := apiutil.GVKForObject(obj, in.Client.Scheme()) - if err != nil { - return nil, err - } - uncachedGVKs[gvk] = struct{}{} - } - - return &delegatingClient{ - scheme: in.Client.Scheme(), - mapper: in.Client.RESTMapper(), - Reader: &delegatingReader{ - CacheReader: in.CacheReader, - ClientReader: in.Client, - scheme: in.Client.Scheme(), - uncachedGVKs: uncachedGVKs, - cacheUnstructured: in.CacheUnstructured, - }, - Writer: in.Client, - StatusClient: in.Client, - }, nil -} - -type delegatingClient struct { - Reader - Writer - StatusClient - - scheme *runtime.Scheme - mapper meta.RESTMapper -} - -// Scheme returns the scheme this client is using. -func (d *delegatingClient) Scheme() *runtime.Scheme { - return d.scheme -} - -// RESTMapper returns the rest mapper this client is using. -func (d *delegatingClient) RESTMapper() meta.RESTMapper { - return d.mapper -} - -// delegatingReader forms a Reader that will cause Get and List requests for -// unstructured types to use the ClientReader while requests for any other type -// of object with use the CacheReader. This avoids accidentally caching the -// entire cluster in the common case of loading arbitrary unstructured objects -// (e.g. from OwnerReferences). -type delegatingReader struct { - CacheReader Reader - ClientReader Reader - - uncachedGVKs map[schema.GroupVersionKind]struct{} - scheme *runtime.Scheme - cacheUnstructured bool -} - -func (d *delegatingReader) shouldBypassCache(obj runtime.Object) (bool, error) { - gvk, err := apiutil.GVKForObject(obj, d.scheme) - if err != nil { - return false, err - } - // TODO: this is producing unsafe guesses that don't actually work, - // but it matches ~99% of the cases out there. - if meta.IsListType(obj) { - gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") - } - if _, isUncached := d.uncachedGVKs[gvk]; isUncached { - return true, nil - } - if !d.cacheUnstructured { - _, isUnstructured := obj.(*unstructured.Unstructured) - _, isUnstructuredList := obj.(*unstructured.UnstructuredList) - return isUnstructured || isUnstructuredList, nil - } - return false, nil -} - -// Get retrieves an obj for a given object key from the Kubernetes Cluster. -func (d *delegatingReader) Get(ctx context.Context, key ObjectKey, obj Object) error { - if isUncached, err := d.shouldBypassCache(obj); err != nil { - return err - } else if isUncached { - return d.ClientReader.Get(ctx, key, obj) - } - return d.CacheReader.Get(ctx, key, obj) -} - -// List retrieves list of objects for a given namespace and list options. -func (d *delegatingReader) List(ctx context.Context, list ObjectList, opts ...ListOption) error { - if isUncached, err := d.shouldBypassCache(list); err != nil { - return err - } else if isUncached { - return d.ClientReader.List(ctx, list, opts...) - } - return d.CacheReader.List(ctx, list, opts...) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go index dde7b21f258..92afd9a9c25 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go @@ -24,24 +24,22 @@ import ( var _ Reader = &typedClient{} var _ Writer = &typedClient{} -var _ StatusWriter = &typedClient{} -// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes -// new clients at the time they are used, and caches the client. type typedClient struct { - cache *clientCache + resources *clientRestResources paramCodec runtime.ParameterCodec } // Create implements client.Client. func (c *typedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { - o, err := c.cache.getObjMeta(obj) + o, err := c.resources.getObjMeta(obj) if err != nil { return err } createOpts := &CreateOptions{} createOpts.ApplyOptions(opts) + return o.Post(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). @@ -53,13 +51,14 @@ func (c *typedClient) Create(ctx context.Context, obj Object, opts ...CreateOpti // Update implements client.Client. func (c *typedClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { - o, err := c.cache.getObjMeta(obj) + o, err := c.resources.getObjMeta(obj) if err != nil { return err } updateOpts := &UpdateOptions{} updateOpts.ApplyOptions(opts) + return o.Put(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). @@ -72,7 +71,7 @@ func (c *typedClient) Update(ctx context.Context, obj Object, opts ...UpdateOpti // Delete implements client.Client. func (c *typedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { - o, err := c.cache.getObjMeta(obj) + o, err := c.resources.getObjMeta(obj) if err != nil { return err } @@ -91,7 +90,7 @@ func (c *typedClient) Delete(ctx context.Context, obj Object, opts ...DeleteOpti // DeleteAllOf implements client.Client. func (c *typedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { - o, err := c.cache.getObjMeta(obj) + o, err := c.resources.getObjMeta(obj) if err != nil { return err } @@ -110,7 +109,7 @@ func (c *typedClient) DeleteAllOf(ctx context.Context, obj Object, opts ...Delet // Patch implements client.Client. func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - o, err := c.cache.getObjMeta(obj) + o, err := c.resources.getObjMeta(obj) if err != nil { return err } @@ -121,36 +120,43 @@ func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts . } patchOpts := &PatchOptions{} + patchOpts.ApplyOptions(opts) + return o.Patch(patch.Type()). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec). + VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec). Body(data). Do(ctx). Into(obj) } // Get implements client.Client. -func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object) error { - r, err := c.cache.getResource(obj) +func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + r, err := c.resources.getResource(obj) if err != nil { return err } + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) return r.Get(). NamespaceIfScoped(key.Namespace, r.isNamespaced()). Resource(r.resource()). + VersionedParams(getOpts.AsGetOptions(), c.paramCodec). Name(key.Name).Do(ctx).Into(obj) } // List implements client.Client. func (c *typedClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { - r, err := c.cache.getResource(obj) + r, err := c.resources.getResource(obj) if err != nil { return err } + listOpts := ListOptions{} listOpts.ApplyOptions(opts) + return r.Get(). NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). Resource(r.resource()). @@ -159,9 +165,56 @@ func (c *typedClient) List(ctx context.Context, obj ObjectList, opts ...ListOpti Into(obj) } -// UpdateStatus used by StatusWriter to write status. -func (c *typedClient) UpdateStatus(ctx context.Context, obj Object, opts ...UpdateOption) error { - o, err := c.cache.getObjMeta(obj) +func (c *typedClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + getOpts := &SubResourceGetOptions{} + getOpts.ApplyOptions(opts) + + return o.Get(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + VersionedParams(getOpts.AsGetOptions(), c.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (c *typedClient) CreateSubResource(ctx context.Context, obj Object, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error { + o, err := c.resources.getObjMeta(obj) + if err != nil { + return err + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + createOpts := &SubResourceCreateOptions{} + createOpts.ApplyOptions(opts) + + return o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(subResourceObj). + VersionedParams(createOpts.AsCreateOptions(), c.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +// UpdateSubResource used by SubResourceWriter to write status. +func (c *typedClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error { + o, err := c.resources.getObjMeta(obj) if err != nil { return err } @@ -169,37 +222,58 @@ func (c *typedClient) UpdateStatus(ctx context.Context, obj Object, opts ...Upda // wrapped to improve the UX ? // It will be nice to receive an error saying the object doesn't implement // status subresource and check CRD definition + updateOpts := &SubResourceUpdateOptions{} + updateOpts.ApplyOptions(opts) + + body := obj + if updateOpts.SubResourceBody != nil { + body = updateOpts.SubResourceBody + } + if body.GetName() == "" { + body.SetName(obj.GetName()) + } + if body.GetNamespace() == "" { + body.SetNamespace(obj.GetNamespace()) + } + return o.Put(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - SubResource("status"). - Body(obj). - VersionedParams((&UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), c.paramCodec). + SubResource(subResource). + Body(body). + VersionedParams(updateOpts.AsUpdateOptions(), c.paramCodec). Do(ctx). - Into(obj) + Into(body) } -// PatchStatus used by StatusWriter to write status. -func (c *typedClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - o, err := c.cache.getObjMeta(obj) +// PatchSubResource used by SubResourceWriter to write subresource. +func (c *typedClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { + o, err := c.resources.getObjMeta(obj) if err != nil { return err } - data, err := patch.Data(obj) + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) if err != nil { return err } - patchOpts := &PatchOptions{} return o.Patch(patch.Type()). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - SubResource("status"). + SubResource(subResource). Body(data). - VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec). + VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec). Do(ctx). - Into(obj) + Into(body) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go index 819527e7001..b8d4146c9f3 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go @@ -21,37 +21,34 @@ import ( "fmt" "strings" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) var _ Reader = &unstructuredClient{} var _ Writer = &unstructuredClient{} -var _ StatusWriter = &unstructuredClient{} -// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes -// new clients at the time they are used, and caches the client. type unstructuredClient struct { - cache *clientCache + resources *clientRestResources paramCodec runtime.ParameterCodec } // Create implements client.Client. func (uc *unstructuredClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error { - u, ok := obj.(*unstructured.Unstructured) + u, ok := obj.(runtime.Unstructured) if !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - gvk := u.GroupVersionKind() + gvk := u.GetObjectKind().GroupVersionKind() - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } createOpts := &CreateOptions{} createOpts.ApplyOptions(opts) + result := o.Post(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). @@ -60,26 +57,27 @@ func (uc *unstructuredClient) Create(ctx context.Context, obj Object, opts ...Cr Do(ctx). Into(obj) - u.SetGroupVersionKind(gvk) + u.GetObjectKind().SetGroupVersionKind(gvk) return result } // Update implements client.Client. func (uc *unstructuredClient) Update(ctx context.Context, obj Object, opts ...UpdateOption) error { - u, ok := obj.(*unstructured.Unstructured) + u, ok := obj.(runtime.Unstructured) if !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - gvk := u.GroupVersionKind() + gvk := u.GetObjectKind().GroupVersionKind() - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } updateOpts := UpdateOptions{} updateOpts.ApplyOptions(opts) + result := o.Put(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). @@ -89,23 +87,24 @@ func (uc *unstructuredClient) Update(ctx context.Context, obj Object, opts ...Up Do(ctx). Into(obj) - u.SetGroupVersionKind(gvk) + u.GetObjectKind().SetGroupVersionKind(gvk) return result } // Delete implements client.Client. func (uc *unstructuredClient) Delete(ctx context.Context, obj Object, opts ...DeleteOption) error { - if _, ok := obj.(*unstructured.Unstructured); !ok { + if _, ok := obj.(runtime.Unstructured); !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } deleteOpts := DeleteOptions{} deleteOpts.ApplyOptions(opts) + return o.Delete(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). @@ -117,17 +116,18 @@ func (uc *unstructuredClient) Delete(ctx context.Context, obj Object, opts ...De // DeleteAllOf implements client.Client. func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error { - if _, ok := obj.(*unstructured.Unstructured); !ok { + if _, ok := obj.(runtime.Unstructured); !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } deleteAllOfOpts := DeleteAllOfOptions{} deleteAllOfOpts.ApplyOptions(opts) + return o.Delete(). NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.isNamespaced()). Resource(o.resource()). @@ -139,11 +139,11 @@ func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj Object, opts // Patch implements client.Client. func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - if _, ok := obj.(*unstructured.Unstructured); !ok { + if _, ok := obj.(runtime.Unstructured); !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } @@ -154,26 +154,31 @@ func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch } patchOpts := &PatchOptions{} + patchOpts.ApplyOptions(opts) + return o.Patch(patch.Type()). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec). + VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec). Body(data). Do(ctx). Into(obj) } // Get implements client.Client. -func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object) error { - u, ok := obj.(*unstructured.Unstructured) +func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error { + u, ok := obj.(runtime.Unstructured) if !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - gvk := u.GroupVersionKind() + gvk := u.GetObjectKind().GroupVersionKind() + + getOpts := GetOptions{} + getOpts.ApplyOptions(opts) - r, err := uc.cache.getResource(obj) + r, err := uc.resources.getResource(obj) if err != nil { return err } @@ -181,33 +186,34 @@ func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object result := r.Get(). NamespaceIfScoped(key.Namespace, r.isNamespaced()). Resource(r.resource()). + VersionedParams(getOpts.AsGetOptions(), uc.paramCodec). Name(key.Name). Do(ctx). Into(obj) - u.SetGroupVersionKind(gvk) + u.GetObjectKind().SetGroupVersionKind(gvk) return result } // List implements client.Client. func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error { - u, ok := obj.(*unstructured.UnstructuredList) + u, ok := obj.(runtime.Unstructured) if !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - gvk := u.GroupVersionKind() + gvk := u.GetObjectKind().GroupVersionKind() gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") - listOpts := ListOptions{} - listOpts.ApplyOptions(opts) - - r, err := uc.cache.getResource(obj) + r, err := uc.resources.getResource(obj) if err != nil { return err } + listOpts := ListOptions{} + listOpts.ApplyOptions(opts) + return r.Get(). NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). Resource(r.resource()). @@ -216,56 +222,140 @@ func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ... Into(obj) } -func (uc *unstructuredClient) UpdateStatus(ctx context.Context, obj Object, opts ...UpdateOption) error { - if _, ok := obj.(*unstructured.Unstructured); !ok { +func (uc *unstructuredClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", subResource) + } + + if _, ok := subResourceObj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + getOpts := &SubResourceGetOptions{} + getOpts.ApplyOptions(opts) + + return o.Get(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + VersionedParams(getOpts.AsGetOptions(), uc.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (uc *unstructuredClient) CreateSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", subResourceObj) + } + + if _, ok := subResourceObj.(runtime.Unstructured); !ok { + return fmt.Errorf("unstructured client did not understand object: %T", obj) + } + + if subResourceObj.GetName() == "" { + subResourceObj.SetName(obj.GetName()) + } + + o, err := uc.resources.getObjMeta(obj) + if err != nil { + return err + } + + createOpts := &SubResourceCreateOptions{} + createOpts.ApplyOptions(opts) + + return o.Post(). + NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). + Resource(o.resource()). + Name(o.GetName()). + SubResource(subResource). + Body(subResourceObj). + VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec). + Do(ctx). + Into(subResourceObj) +} + +func (uc *unstructuredClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error { + if _, ok := obj.(runtime.Unstructured); !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } + updateOpts := SubResourceUpdateOptions{} + updateOpts.ApplyOptions(opts) + + body := obj + if updateOpts.SubResourceBody != nil { + body = updateOpts.SubResourceBody + } + if body.GetName() == "" { + body.SetName(obj.GetName()) + } + if body.GetNamespace() == "" { + body.SetNamespace(obj.GetNamespace()) + } + return o.Put(). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - SubResource("status"). - Body(obj). - VersionedParams((&UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), uc.paramCodec). + SubResource(subResource). + Body(body). + VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec). Do(ctx). - Into(obj) + Into(body) } -func (uc *unstructuredClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error { - u, ok := obj.(*unstructured.Unstructured) +func (uc *unstructuredClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error { + u, ok := obj.(runtime.Unstructured) if !ok { return fmt.Errorf("unstructured client did not understand object: %T", obj) } - gvk := u.GroupVersionKind() + gvk := u.GetObjectKind().GroupVersionKind() - o, err := uc.cache.getObjMeta(obj) + o, err := uc.resources.getObjMeta(obj) if err != nil { return err } - data, err := patch.Data(obj) + patchOpts := &SubResourcePatchOptions{} + patchOpts.ApplyOptions(opts) + + body := obj + if patchOpts.SubResourceBody != nil { + body = patchOpts.SubResourceBody + } + + data, err := patch.Data(body) if err != nil { return err } - patchOpts := &PatchOptions{} result := o.Patch(patch.Type()). NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()). Resource(o.resource()). Name(o.GetName()). - SubResource("status"). + SubResource(subResource). Body(data). - VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec). + VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec). Do(ctx). - Into(u) + Into(body) - u.SetGroupVersionKind(gvk) + u.GetObjectKind().SetGroupVersionKind(gvk) return result } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/watch.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/watch.go index 70490664bda..181b22a6732 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/watch.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/watch.go @@ -21,9 +21,8 @@ import ( "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" ) @@ -33,21 +32,16 @@ func NewWithWatch(config *rest.Config, options Options) (WithWatch, error) { if err != nil { return nil, err } - dynamicClient, err := dynamic.NewForConfig(config) - if err != nil { - return nil, err - } - return &watchingClient{client: client, dynamic: dynamicClient}, nil + return &watchingClient{client: client}, nil } type watchingClient struct { *client - dynamic dynamic.Interface } func (w *watchingClient) Watch(ctx context.Context, list ObjectList, opts ...ListOption) (watch.Interface, error) { switch l := list.(type) { - case *unstructured.UnstructuredList: + case runtime.Unstructured: return w.unstructuredWatch(ctx, l, opts...) case *metav1.PartialObjectMetadataList: return w.metadataWatch(ctx, l, opts...) @@ -81,25 +75,23 @@ func (w *watchingClient) metadataWatch(ctx context.Context, obj *metav1.PartialO return resInt.Watch(ctx, *listOpts.AsListOptions()) } -func (w *watchingClient) unstructuredWatch(ctx context.Context, obj *unstructured.UnstructuredList, opts ...ListOption) (watch.Interface, error) { - gvk := obj.GroupVersionKind() - gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") - - r, err := w.client.unstructuredClient.cache.getResource(obj) +func (w *watchingClient) unstructuredWatch(ctx context.Context, obj runtime.Unstructured, opts ...ListOption) (watch.Interface, error) { + r, err := w.client.unstructuredClient.resources.getResource(obj) if err != nil { return nil, err } listOpts := w.listOpts(opts...) - if listOpts.Namespace != "" && r.isNamespaced() { - return w.dynamic.Resource(r.mapping.Resource).Namespace(listOpts.Namespace).Watch(ctx, *listOpts.AsListOptions()) - } - return w.dynamic.Resource(r.mapping.Resource).Watch(ctx, *listOpts.AsListOptions()) + return r.Get(). + NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()). + Resource(r.resource()). + VersionedParams(listOpts.AsListOptions(), w.client.unstructuredClient.paramCodec). + Watch(ctx) } func (w *watchingClient) typedWatch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error) { - r, err := w.client.typedClient.cache.getResource(obj) + r, err := w.client.typedClient.resources.getResource(obj) if err != nil { return nil, err } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go index 4b8ee8e7c51..7d00c3c4b0e 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go @@ -19,6 +19,7 @@ package cluster import ( "context" "errors" + "net/http" "time" "github.com/go-logr/logr" @@ -27,6 +28,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/record" + "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" logf "sigs.k8s.io/controller-runtime/pkg/internal/log" @@ -37,14 +39,15 @@ import ( // Cluster provides various methods to interact with a cluster. type Cluster interface { - // SetFields will set any dependencies on an object for which the object has implemented the inject - // interface - e.g. inject.Client. - // Deprecated: use the equivalent Options field to set a field. This method will be removed in v0.10. - SetFields(interface{}) error + // GetHTTPClient returns an HTTP client that can be used to talk to the apiserver + GetHTTPClient() *http.Client // GetConfig returns an initialized Config GetConfig() *rest.Config + // GetCache returns a cache.Cache + GetCache() cache.Cache + // GetScheme returns an initialized Scheme GetScheme() *runtime.Scheme @@ -57,9 +60,6 @@ type Cluster interface { // GetFieldIndexer returns a client.FieldIndexer configured with the client GetFieldIndexer() client.FieldIndexer - // GetCache returns a cache.Cache - GetCache() cache.Cache - // GetEventRecorderFor returns a new EventRecorder for the provided name GetEventRecorderFor(name string) record.EventRecorder @@ -83,7 +83,7 @@ type Options struct { Scheme *runtime.Scheme // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs - MapperProvider func(c *rest.Config) (meta.RESTMapper, error) + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) // Logger is the logger that should be used by this Cluster. // If none is set, it defaults to log.Log global logger. @@ -103,23 +103,54 @@ type Options struct { // Note: If a namespace is specified, controllers can still Watch for a // cluster-scoped resource (e.g Node). For namespaced resources the cache // will only hold objects from the desired namespace. + // + // Deprecated: Use Cache.Namespaces instead. Namespace string + // HTTPClient is the http client that will be used to create the default + // Cache and Client. If not set the rest.HTTPClientFor function will be used + // to create the http client. + HTTPClient *http.Client + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + // NewCache is the function that will create the cache to be used // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. NewCache cache.NewCacheFunc + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + // NewClient is the func that creates the client to be used by the manager. - // If not set this will create the default DelegatingClient that will - // use the cache for reads and the client for writes. - NewClient NewClientFunc + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc // ClientDisableCacheFor tells the client that, if any cache is used, to bypass it // for the given objects. + // + // Deprecated: Use Client.Cache.DisableFor instead. ClientDisableCacheFor []client.Object // DryRunClient specifies whether the client should be configured to enforce // dryRun mode. + // + // Deprecated: Use Client.DryRun instead. DryRunClient bool // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API @@ -136,7 +167,7 @@ type Options struct { makeBroadcaster intrec.EventBroadcasterProducer // Dependency injection for testing - newRecorderProvider func(config *rest.Config, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) } // Option can be used to manipulate Options. @@ -152,52 +183,105 @@ func New(config *rest.Config, opts ...Option) (Cluster, error) { for _, opt := range opts { opt(&options) } - options = setOptionsDefaults(options) + options, err := setOptionsDefaults(options, config) + if err != nil { + options.Logger.Error(err, "Failed to set defaults") + return nil, err + } // Create the mapper provider - mapper, err := options.MapperProvider(config) + mapper, err := options.MapperProvider(config, options.HTTPClient) if err != nil { options.Logger.Error(err, "Failed to get API Group-Resources") return nil, err } // Create the cache for the cached read client and registering informers - cache, err := options.NewCache(config, cache.Options{Scheme: options.Scheme, Mapper: mapper, Resync: options.SyncPeriod, Namespace: options.Namespace}) + cacheOpts := options.Cache + { + if cacheOpts.Scheme == nil { + cacheOpts.Scheme = options.Scheme + } + if cacheOpts.Mapper == nil { + cacheOpts.Mapper = mapper + } + if cacheOpts.HTTPClient == nil { + cacheOpts.HTTPClient = options.HTTPClient + } + if cacheOpts.SyncPeriod == nil { + cacheOpts.SyncPeriod = options.SyncPeriod + } + if len(cacheOpts.Namespaces) == 0 && options.Namespace != "" { + cacheOpts.Namespaces = []string{options.Namespace} + } + } + cache, err := options.NewCache(config, cacheOpts) if err != nil { return nil, err } - clientOptions := client.Options{Scheme: options.Scheme, Mapper: mapper} + // Create the client, and default its options. + clientOpts := options.Client + { + if clientOpts.Scheme == nil { + clientOpts.Scheme = options.Scheme + } + if clientOpts.Mapper == nil { + clientOpts.Mapper = mapper + } + if clientOpts.HTTPClient == nil { + clientOpts.HTTPClient = options.HTTPClient + } + if clientOpts.Cache == nil { + clientOpts.Cache = &client.CacheOptions{ + Unstructured: false, + } + } + if clientOpts.Cache.Reader == nil { + clientOpts.Cache.Reader = cache + } + + // For backward compatibility, the ClientDisableCacheFor option should + // be appended to the DisableFor option in the client. + clientOpts.Cache.DisableFor = append(clientOpts.Cache.DisableFor, options.ClientDisableCacheFor...) - apiReader, err := client.New(config, clientOptions) + if clientOpts.DryRun == nil && options.DryRunClient { + // For backward compatibility, the DryRunClient (if set) option should override + // the DryRun option in the client (if unset). + clientOpts.DryRun = pointer.Bool(true) + } + } + clientWriter, err := options.NewClient(config, clientOpts) if err != nil { return nil, err } - writeObj, err := options.NewClient(cache, config, clientOptions, options.ClientDisableCacheFor...) + // Create the API Reader, a client with no cache. + clientReader, err := client.New(config, client.Options{ + HTTPClient: options.HTTPClient, + Scheme: options.Scheme, + Mapper: mapper, + }) if err != nil { return nil, err } - if options.DryRunClient { - writeObj = client.NewDryRunClient(writeObj) - } - // Create the recorder provider to inject event recorders for the components. // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific // to the particular controller that it's being injected into, rather than a generic one like is here. - recorderProvider, err := options.newRecorderProvider(config, options.Scheme, options.Logger.WithName("events"), options.makeBroadcaster) + recorderProvider, err := options.newRecorderProvider(config, options.HTTPClient, options.Scheme, options.Logger.WithName("events"), options.makeBroadcaster) if err != nil { return nil, err } return &cluster{ config: config, + httpClient: options.HTTPClient, scheme: options.Scheme, cache: cache, fieldIndexes: cache, - client: writeObj, - apiReader: apiReader, + client: clientWriter, + apiReader: clientReader, recorderProvider: recorderProvider, mapper: mapper, logger: options.Logger, @@ -205,21 +289,27 @@ func New(config *rest.Config, opts ...Option) (Cluster, error) { } // setOptionsDefaults set default values for Options fields. -func setOptionsDefaults(options Options) Options { +func setOptionsDefaults(options Options, config *rest.Config) (Options, error) { + if options.HTTPClient == nil { + var err error + options.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return options, err + } + } + // Use the Kubernetes client-go scheme if none is specified if options.Scheme == nil { options.Scheme = scheme.Scheme } if options.MapperProvider == nil { - options.MapperProvider = func(c *rest.Config) (meta.RESTMapper, error) { - return apiutil.NewDynamicRESTMapper(c) - } + options.MapperProvider = apiutil.NewDynamicRESTMapper } // Allow users to define how to create a new client if options.NewClient == nil { - options.NewClient = DefaultNewClient + options.NewClient = client.New } // Allow newCache to be mocked @@ -249,22 +339,5 @@ func setOptionsDefaults(options Options) Options { options.Logger = logf.RuntimeLog.WithName("cluster") } - return options -} - -// NewClientFunc allows a user to define how to create a client. -type NewClientFunc func(cache cache.Cache, config *rest.Config, options client.Options, uncachedObjects ...client.Object) (client.Client, error) - -// DefaultNewClient creates the default caching client. -func DefaultNewClient(cache cache.Cache, config *rest.Config, options client.Options, uncachedObjects ...client.Object) (client.Client, error) { - c, err := client.New(config, options) - if err != nil { - return nil, err - } - - return client.NewDelegatingClient(client.NewDelegatingClientInput{ - CacheReader: cache, - Client: c, - UncachedObjects: uncachedObjects, - }) + return options, nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go index 125e1d144e9..2742764231b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go @@ -18,6 +18,7 @@ package cluster import ( "context" + "net/http" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/api/meta" @@ -28,22 +29,16 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" ) type cluster struct { // config is the rest.config used to talk to the apiserver. Required. config *rest.Config - // scheme is the scheme injected into Controllers, EventHandlers, Sources and Predicates. Defaults - // to scheme.scheme. - scheme *runtime.Scheme - - cache cache.Cache - - // TODO(directxman12): Provide an escape hatch to get individual indexers - // client is the client injected into Controllers (and EventHandlers, Sources and Predicates). - client client.Client + httpClient *http.Client + scheme *runtime.Scheme + cache cache.Cache + client client.Client // apiReader is the reader that will make requests to the api server and not the cache. apiReader client.Reader @@ -64,32 +59,14 @@ type cluster struct { logger logr.Logger } -func (c *cluster) SetFields(i interface{}) error { - if _, err := inject.ConfigInto(c.config, i); err != nil { - return err - } - if _, err := inject.ClientInto(c.client, i); err != nil { - return err - } - if _, err := inject.APIReaderInto(c.apiReader, i); err != nil { - return err - } - if _, err := inject.SchemeInto(c.scheme, i); err != nil { - return err - } - if _, err := inject.CacheInto(c.cache, i); err != nil { - return err - } - if _, err := inject.MapperInto(c.mapper, i); err != nil { - return err - } - return nil -} - func (c *cluster) GetConfig() *rest.Config { return c.config } +func (c *cluster) GetHTTPClient() *http.Client { + return c.httpClient +} + func (c *cluster) GetClient() client.Client { return c.client } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go index 517b172e5b2..9c7b875a860 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go @@ -29,6 +29,8 @@ import ( // ControllerManagerConfiguration defines the functions necessary to parse a config file // and to configure the Options struct for the ctrl.Manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerManagerConfiguration interface { runtime.Object @@ -38,6 +40,8 @@ type ControllerManagerConfiguration interface { // DeferredFileLoader is used to configure the decoder for loading controller // runtime component config types. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type DeferredFileLoader struct { ControllerManagerConfiguration path string @@ -50,8 +54,10 @@ type DeferredFileLoader struct { // this will also configure the defaults for the loader if nothing is // // Defaults: -// Path: "./config.yaml" -// Kind: GenericControllerManagerConfiguration +// * Path: "./config.yaml" +// * Kind: GenericControllerManagerConfiguration +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. func File() *DeferredFileLoader { scheme := runtime.NewScheme() utilruntime.Must(v1alpha1.AddToScheme(scheme)) @@ -83,12 +89,6 @@ func (d *DeferredFileLoader) OfKind(obj ControllerManagerConfiguration) *Deferre return d } -// InjectScheme will configure the scheme to be used for decoding the file. -func (d *DeferredFileLoader) InjectScheme(scheme *runtime.Scheme) error { - d.scheme = scheme - return nil -} - // loadFile is used from the mutex.Once to load the file. func (d *DeferredFileLoader) loadFile() { if d.scheme == nil { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go new file mode 100644 index 00000000000..b37dffaeea4 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go @@ -0,0 +1,49 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import "time" + +// Controller contains configuration options for a controller. +type Controller struct { + // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation + // allowed for that controller. + // + // When a controller is registered within this manager using the builder utilities, + // users have to specify the type the controller reconciles in the For(...) call. + // If the object's kind passed matches one of the keys in this map, the concurrency + // for that controller is set to the number specified. + // + // The key is expected to be consistent in form with GroupKind.String(), + // e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`. + GroupKindConcurrency map[string]int + + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go index ebd8243f32d..47a5a2f1d73 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go @@ -14,12 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package config contains functionality for interacting with ComponentConfig -// files -// -// DeferredFileLoader -// -// This uses a deferred file decoding allowing you to chain your configuration -// setup. You can pass this into manager.Options#File and it will load your -// config. +// Package config contains functionality for interacting with +// configuration for controller-runtime components. package config diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go index 1e3adbafb86..8fdf14d39ad 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go @@ -17,4 +17,6 @@ limitations under the License. // Package v1alpha1 provides the ControllerManagerConfiguration used for // configuring ctrl.Manager // +kubebuilder:object:generate=true +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. package v1alpha1 diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go index 9efdbc06680..ca854bcf300 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go @@ -23,12 +23,18 @@ import ( var ( // GroupVersion is group version used to register these objects. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. GroupVersion = schema.GroupVersion{Group: "controller-runtime.sigs.k8s.io", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} // AddToScheme adds the types in this group-version to the given scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. AddToScheme = SchemeBuilder.AddToScheme ) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go index e67b62e5148..52c8ab300f2 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go @@ -25,6 +25,8 @@ import ( ) // ControllerManagerConfigurationSpec defines the desired state of GenericControllerManagerConfiguration. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerManagerConfigurationSpec struct { // SyncPeriod determines the minimum frequency at which watched resources are // reconciled. A lower period will correct entropy more quickly, but reduce @@ -60,7 +62,7 @@ type ControllerManagerConfigurationSpec struct { // +optional Controller *ControllerConfigurationSpec `json:"controller,omitempty"` - // Metrics contains thw controller metrics configuration + // Metrics contains the controller metrics configuration // +optional Metrics ControllerMetrics `json:"metrics,omitempty"` @@ -75,6 +77,11 @@ type ControllerManagerConfigurationSpec struct { // ControllerConfigurationSpec defines the global configuration for // controllers registered with the manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +// +// Deprecated: Controller global configuration can now be set at the manager level, +// using the manager.Options.Controller field. type ControllerConfigurationSpec struct { // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation // allowed for that controller. @@ -94,9 +101,15 @@ type ControllerConfigurationSpec struct { // Defaults to 2 minutes if not set. // +optional CacheSyncTimeout *time.Duration `json:"cacheSyncTimeout,omitempty"` + + // RecoverPanic indicates if panics should be recovered. + // +optional + RecoverPanic *bool `json:"recoverPanic,omitempty"` } // ControllerMetrics defines the metrics configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerMetrics struct { // BindAddress is the TCP address that the controller should bind to // for serving prometheus metrics. @@ -106,9 +119,12 @@ type ControllerMetrics struct { } // ControllerHealth defines the health configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerHealth struct { // HealthProbeBindAddress is the TCP address that the controller should bind to // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. // +optional HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` @@ -122,6 +138,8 @@ type ControllerHealth struct { } // ControllerWebhook defines the webhook server for the controller. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerWebhook struct { // Port is the port that the webhook server serves at. // It is used to set webhook.Server.Port. @@ -144,6 +162,8 @@ type ControllerWebhook struct { // +kubebuilder:object:root=true // ControllerManagerConfiguration is the Schema for the GenericControllerManagerConfigurations API. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. type ControllerManagerConfiguration struct { metav1.TypeMeta `json:",inline"` @@ -152,6 +172,8 @@ type ControllerManagerConfiguration struct { } // Complete returns the configuration for controller-runtime. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. func (c *ControllerManagerConfigurationSpec) Complete() (ControllerManagerConfigurationSpec, error) { return *c, nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go index 5329bef667a..cdc7c334bef 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go @@ -27,6 +27,11 @@ func (in *ControllerConfigurationSpec) DeepCopyInto(out *ControllerConfiguration *out = new(timex.Duration) **out = **in } + if in.RecoverPanic != nil { + in, out := &in.RecoverPanic, &out.RecoverPanic + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerConfigurationSpec. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go index 8e3d8591d64..6732b6f709d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go @@ -39,6 +39,18 @@ type Options struct { // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. MaxConcurrentReconciles int + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool + // Reconciler reconciles an object Reconciler reconcile.Reconciler @@ -50,13 +62,6 @@ type Options struct { // LogConstructor is used to construct a logger used for this controller and passed // to each reconciliation via the context field. LogConstructor func(request *reconcile.Request) logr.Logger - - // CacheSyncTimeout refers to the time limit set to wait for syncing caches. - // Defaults to 2 minutes if not set. - CacheSyncTimeout time.Duration - - // RecoverPanic indicates whether the panic caused by reconcile should be recovered. - RecoverPanic bool } // Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests @@ -123,20 +128,31 @@ func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller } if options.MaxConcurrentReconciles <= 0 { - options.MaxConcurrentReconciles = 1 + if mgr.GetControllerOptions().MaxConcurrentReconciles > 0 { + options.MaxConcurrentReconciles = mgr.GetControllerOptions().MaxConcurrentReconciles + } else { + options.MaxConcurrentReconciles = 1 + } } if options.CacheSyncTimeout == 0 { - options.CacheSyncTimeout = 2 * time.Minute + if mgr.GetControllerOptions().CacheSyncTimeout != 0 { + options.CacheSyncTimeout = mgr.GetControllerOptions().CacheSyncTimeout + } else { + options.CacheSyncTimeout = 2 * time.Minute + } } if options.RateLimiter == nil { options.RateLimiter = workqueue.DefaultControllerRateLimiter() } - // Inject dependencies into Reconciler - if err := mgr.SetFields(options.Reconciler); err != nil { - return nil, err + if options.RecoverPanic == nil { + options.RecoverPanic = mgr.GetControllerOptions().RecoverPanic + } + + if options.NeedLeaderElection == nil { + options.NeedLeaderElection = mgr.GetControllerOptions().NeedLeaderElection } // Create controller with dependencies set @@ -147,9 +163,12 @@ func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller }, MaxConcurrentReconciles: options.MaxConcurrentReconciles, CacheSyncTimeout: options.CacheSyncTimeout, - SetFields: mgr.SetFields, Name: name, LogConstructor: options.LogConstructor, RecoverPanic: options.RecoverPanic, + LeaderElected: options.NeedLeaderElection, }, nil } + +// ReconcileIDFromContext gets the reconcileID from the current context. +var ReconcileIDFromContext = controller.ReconcileIDFromContext diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go deleted file mode 100644 index b638b4976c9..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllertest/util.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controllertest - -import ( - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" -) - -var _ cache.SharedIndexInformer = &FakeInformer{} - -// FakeInformer provides fake Informer functionality for testing. -type FakeInformer struct { - // Synced is returned by the HasSynced functions to implement the Informer interface - Synced bool - - // RunCount is incremented each time RunInformersAndControllers is called - RunCount int - - handlers []cache.ResourceEventHandler -} - -// AddIndexers does nothing. TODO(community): Implement this. -func (f *FakeInformer) AddIndexers(indexers cache.Indexers) error { - return nil -} - -// GetIndexer does nothing. TODO(community): Implement this. -func (f *FakeInformer) GetIndexer() cache.Indexer { - return nil -} - -// Informer returns the fake Informer. -func (f *FakeInformer) Informer() cache.SharedIndexInformer { - return f -} - -// HasSynced implements the Informer interface. Returns f.Synced. -func (f *FakeInformer) HasSynced() bool { - return f.Synced -} - -// AddEventHandler implements the Informer interface. Adds an EventHandler to the fake Informers. -func (f *FakeInformer) AddEventHandler(handler cache.ResourceEventHandler) { - f.handlers = append(f.handlers, handler) -} - -// Run implements the Informer interface. Increments f.RunCount. -func (f *FakeInformer) Run(<-chan struct{}) { - f.RunCount++ -} - -// Add fakes an Add event for obj. -func (f *FakeInformer) Add(obj metav1.Object) { - for _, h := range f.handlers { - h.OnAdd(obj) - } -} - -// Update fakes an Update event for obj. -func (f *FakeInformer) Update(oldObj, newObj metav1.Object) { - for _, h := range f.handlers { - h.OnUpdate(oldObj, newObj) - } -} - -// Delete fakes an Delete event for obj. -func (f *FakeInformer) Delete(obj metav1.Object) { - for _, h := range f.handlers { - h.OnDelete(obj) - } -} - -// AddEventHandlerWithResyncPeriod does nothing. TODO(community): Implement this. -func (f *FakeInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) { - -} - -// GetStore does nothing. TODO(community): Implement this. -func (f *FakeInformer) GetStore() cache.Store { - return nil -} - -// GetController does nothing. TODO(community): Implement this. -func (f *FakeInformer) GetController() cache.Controller { - return nil -} - -// LastSyncResourceVersion does nothing. TODO(community): Implement this. -func (f *FakeInformer) LastSyncResourceVersion() string { - return "" -} - -// SetWatchErrorHandler does nothing. TODO(community): Implement this. -func (f *FakeInformer) SetWatchErrorHandler(cache.WatchErrorHandler) error { - return nil -} - -// SetTransform does nothing. TODO(community): Implement this. -func (f *FakeInformer) SetTransform(t cache.TransformFunc) error { - return nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go index aa53a77d412..344abcd288c 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go @@ -76,8 +76,8 @@ func SetControllerReference(owner, controlled metav1.Object, scheme *runtime.Sch Kind: gvk.Kind, Name: owner.GetName(), UID: owner.GetUID(), - BlockOwnerDeletion: pointer.BoolPtr(true), - Controller: pointer.BoolPtr(true), + BlockOwnerDeletion: pointer.Bool(true), + Controller: pointer.Bool(true), } // Return early with an error if the object is already controlled. @@ -207,7 +207,7 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f M return OperationResultCreated, nil } - existing := obj.DeepCopyObject() //nolint + existing := obj.DeepCopyObject() if err := mutate(f, key, obj); err != nil { return OperationResultNone, err } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go index 667b14fdd70..228335e9293 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go @@ -17,7 +17,7 @@ limitations under the License. /* Package controller provides types and functions for building Controllers. Controllers implement Kubernetes APIs. -Creation +# Creation To create a new Controller, first create a manager.Manager and pass it to the controller.New function. The Controller MUST be started by calling Manager.Start. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go index 3b52ae8f99a..f9c58ea26a3 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go @@ -84,8 +84,10 @@ type CRDInstallOptions struct { WebhookOptions WebhookInstallOptions } -const defaultPollInterval = 100 * time.Millisecond -const defaultMaxWait = 10 * time.Second +const ( + defaultPollInterval = 100 * time.Millisecond + defaultMaxWait = 10 * time.Second +) // InstallCRDs installs a collection of CRDs into a cluster by reading the crd yaml files from a directory. func InstallCRDs(config *rest.Config, options CRDInstallOptions) ([]*apiextensionsv1.CustomResourceDefinition, error) { @@ -142,7 +144,7 @@ func defaultCRDOptions(o *CRDInstallOptions) { // WaitForCRDs waits for the CRDs to appear in discovery. func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefinition, options CRDInstallOptions) error { // Add each CRD to a map of GroupVersion to Resource - waitingFor := map[schema.GroupVersion]*sets.String{} + waitingFor := map[schema.GroupVersion]*sets.Set[string]{} for _, crd := range crds { gvs := []schema.GroupVersion{} for _, version := range crd.Spec.Versions { @@ -155,7 +157,7 @@ func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefi log.V(1).Info("adding API in waitlist", "GV", gv) if _, found := waitingFor[gv]; !found { // Initialize the set - waitingFor[gv] = &sets.String{} + waitingFor[gv] = &sets.Set[string]{} } // Add the Resource waitingFor[gv].Insert(crd.Spec.Names.Plural) @@ -164,7 +166,7 @@ func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefi // Poll until all resources are found in discovery p := &poller{config: config, waitingFor: waitingFor} - return wait.PollImmediate(options.PollInterval, options.MaxTime, p.poll) + return wait.PollUntilContextTimeout(context.TODO(), options.PollInterval, options.MaxTime, true, p.poll) } // poller checks if all the resources have been found in discovery, and returns false if not. @@ -173,11 +175,11 @@ type poller struct { config *rest.Config // waitingFor is the map of resources keyed by group version that have not yet been found in discovery - waitingFor map[schema.GroupVersion]*sets.String + waitingFor map[schema.GroupVersion]*sets.Set[string] } // poll checks if all the resources have been found in discovery, and returns false if not. -func (p *poller) poll() (done bool, err error) { +func (p *poller) poll(ctx context.Context) (done bool, err error) { // Create a new clientset to avoid any client caching of discovery cs, err := clientset.NewForConfig(p.config) if err != nil { @@ -362,7 +364,7 @@ func modifyConversionWebhooks(crds []*apiextensionsv1.CustomResourceDefinition, if err != nil { return err } - url := pointer.StringPtr(fmt.Sprintf("https://%s/convert", hostPort)) + url := pointer.String(fmt.Sprintf("https://%s/convert", hostPort)) for i := range crds { // Continue if we're preserving unknown fields. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/ginkgo.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/ginkgo.go deleted file mode 100644 index d835dc77215..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/ginkgo.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package printer contains setup for a friendlier Ginkgo printer that's easier -// to parse by test automation. -package printer - -import ( - "fmt" - - "github.com/onsi/ginkgo" - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/types" -) - -var _ ginkgo.Reporter = NewlineReporter{} - -// NewlineReporter is Reporter that Prints a newline after the default Reporter output so that the results -// are correctly parsed by test automation. -// See issue https://github.com/jstemmer/go-junit-report/issues/31 -type NewlineReporter struct{} - -// SpecSuiteWillBegin implements ginkgo.Reporter. -func (NewlineReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { -} - -// BeforeSuiteDidRun implements ginkgo.Reporter. -func (NewlineReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {} - -// AfterSuiteDidRun implements ginkgo.Reporter. -func (NewlineReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {} - -// SpecWillRun implements ginkgo.Reporter. -func (NewlineReporter) SpecWillRun(specSummary *types.SpecSummary) {} - -// SpecDidComplete implements ginkgo.Reporter. -func (NewlineReporter) SpecDidComplete(specSummary *types.SpecSummary) {} - -// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:". -func (NewlineReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { fmt.Printf("\n") } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/prow.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/prow.go deleted file mode 100644 index 2f4009aa034..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/prow.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package printer - -import ( - "fmt" - "os" - "path/filepath" - "sync" - - "github.com/onsi/ginkgo" - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/reporters" - "github.com/onsi/ginkgo/types" - - "k8s.io/apimachinery/pkg/util/sets" -) - -var ( - allRegisteredSuites = sets.String{} - allRegisteredSuitesLock = &sync.Mutex{} -) - -type prowReporter struct { - junitReporter *reporters.JUnitReporter -} - -// NewProwReporter returns a prowReporter that will write out junit if running in Prow and do -// nothing otherwise. -// WARNING: It seems this does not always properly fail the test runs when there are failures, -// see https://github.com/onsi/ginkgo/issues/706 -// When using this you must make sure to grep for failures in your junit xmls and fail the run -// if there are any. -func NewProwReporter(suiteName string) ginkgo.Reporter { - allRegisteredSuitesLock.Lock() - if allRegisteredSuites.Has(suiteName) { - panic(fmt.Sprintf("Suite named %q registered more than once", suiteName)) - } - allRegisteredSuites.Insert(suiteName) - allRegisteredSuitesLock.Unlock() - - if os.Getenv("CI") == "" { - return &prowReporter{} - } - artifactsDir := os.Getenv("ARTIFACTS") - if artifactsDir == "" { - return &prowReporter{} - } - - path := filepath.Join(artifactsDir, fmt.Sprintf("junit_%s_%d.xml", suiteName, config.GinkgoConfig.ParallelNode)) - return &prowReporter{ - junitReporter: reporters.NewJUnitReporter(path), - } -} - -func (pr *prowReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { - if pr.junitReporter != nil { - pr.junitReporter.SpecSuiteWillBegin(config, summary) - } -} - -// BeforeSuiteDidRun implements ginkgo.Reporter. -func (pr *prowReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { - if pr.junitReporter != nil { - pr.junitReporter.BeforeSuiteDidRun(setupSummary) - } -} - -// AfterSuiteDidRun implements ginkgo.Reporter. -func (pr *prowReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { - if pr.junitReporter != nil { - pr.junitReporter.AfterSuiteDidRun(setupSummary) - } -} - -// SpecWillRun implements ginkgo.Reporter. -func (pr *prowReporter) SpecWillRun(specSummary *types.SpecSummary) { - if pr.junitReporter != nil { - pr.junitReporter.SpecWillRun(specSummary) - } -} - -// SpecDidComplete implements ginkgo.Reporter. -func (pr *prowReporter) SpecDidComplete(specSummary *types.SpecSummary) { - if pr.junitReporter != nil { - pr.junitReporter.SpecDidComplete(specSummary) - } -} - -// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:". -func (pr *prowReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { - if pr.junitReporter != nil { - pr.junitReporter.SpecSuiteDidEnd(summary) - } -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go index 5347f074de9..4ee440df9c0 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go @@ -37,15 +37,14 @@ var log = logf.RuntimeLog.WithName("test-env") /* It's possible to override some defaults, by setting the following environment variables: - USE_EXISTING_CLUSTER (boolean): if set to true, envtest will use an existing cluster - TEST_ASSET_KUBE_APISERVER (string): path to the api-server binary to use - TEST_ASSET_ETCD (string): path to the etcd binary to use - TEST_ASSET_KUBECTL (string): path to the kubectl binary to use - KUBEBUILDER_ASSETS (string): directory containing the binaries to use (api-server, etcd and kubectl). Defaults to /usr/local/kubebuilder/bin. - KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. - KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. - KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr - +* USE_EXISTING_CLUSTER (boolean): if set to true, envtest will use an existing cluster +* TEST_ASSET_KUBE_APISERVER (string): path to the api-server binary to use +* TEST_ASSET_ETCD (string): path to the etcd binary to use +* TEST_ASSET_KUBECTL (string): path to the kubectl binary to use +* KUBEBUILDER_ASSETS (string): directory containing the binaries to use (api-server, etcd and kubectl). Defaults to /usr/local/kubebuilder/bin. +* KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. +* KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s. +* KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr */ const ( envUseExistingCluster = "USE_EXISTING_CLUSTER" @@ -231,17 +230,19 @@ func (te *Environment) Start() (*rest.Config, error) { if os.Getenv(envAttachOutput) == "true" { te.AttachControlPlaneOutput = true } - if apiServer.Out == nil && te.AttachControlPlaneOutput { - apiServer.Out = os.Stdout - } - if apiServer.Err == nil && te.AttachControlPlaneOutput { - apiServer.Err = os.Stderr - } - if te.ControlPlane.Etcd.Out == nil && te.AttachControlPlaneOutput { - te.ControlPlane.Etcd.Out = os.Stdout - } - if te.ControlPlane.Etcd.Err == nil && te.AttachControlPlaneOutput { - te.ControlPlane.Etcd.Err = os.Stderr + if te.AttachControlPlaneOutput { + if apiServer.Out == nil { + apiServer.Out = os.Stdout + } + if apiServer.Err == nil { + apiServer.Err = os.Stderr + } + if te.ControlPlane.Etcd.Out == nil { + te.ControlPlane.Etcd.Out = os.Stdout + } + if te.ControlPlane.Etcd.Err == nil { + te.ControlPlane.Etcd.Err = os.Stderr + } } apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go index 9b763b6c24f..f7e43a14802 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go @@ -147,6 +147,8 @@ func (o *WebhookInstallOptions) PrepWithoutInstalling() error { // Install installs specified webhooks to the API server. func (o *WebhookInstallOptions) Install(config *rest.Config) error { + defaultWebhookOptions(o) + if len(o.LocalServingCAData) == 0 { if err := o.PrepWithoutInstalling(); err != nil { return err @@ -168,12 +170,22 @@ func (o *WebhookInstallOptions) Cleanup() error { return nil } +// defaultWebhookOptions sets the default values for Webhooks. +func defaultWebhookOptions(o *WebhookInstallOptions) { + if o.MaxTime == 0 { + o.MaxTime = defaultMaxWait + } + if o.PollInterval == 0 { + o.PollInterval = defaultPollInterval + } +} + // WaitForWebhooks waits for the Webhooks to be available through API server. func WaitForWebhooks(config *rest.Config, mutatingWebhooks []*admissionv1.MutatingWebhookConfiguration, validatingWebhooks []*admissionv1.ValidatingWebhookConfiguration, options WebhookInstallOptions) error { - waitingFor := map[schema.GroupVersionKind]*sets.String{} + waitingFor := map[schema.GroupVersionKind]*sets.Set[string]{} for _, hook := range mutatingWebhooks { h := hook @@ -183,7 +195,7 @@ func WaitForWebhooks(config *rest.Config, } if _, ok := waitingFor[gvk]; !ok { - waitingFor[gvk] = &sets.String{} + waitingFor[gvk] = &sets.Set[string]{} } waitingFor[gvk].Insert(h.GetName()) } @@ -196,14 +208,14 @@ func WaitForWebhooks(config *rest.Config, } if _, ok := waitingFor[gvk]; !ok { - waitingFor[gvk] = &sets.String{} + waitingFor[gvk] = &sets.Set[string]{} } waitingFor[gvk].Insert(hook.GetName()) } // Poll until all resources are found in discovery p := &webhookPoller{config: config, waitingFor: waitingFor} - return wait.PollImmediate(options.PollInterval, options.MaxTime, p.poll) + return wait.PollUntilContextTimeout(context.TODO(), options.PollInterval, options.MaxTime, true, p.poll) } // poller checks if all the resources have been found in discovery, and returns false if not. @@ -212,11 +224,11 @@ type webhookPoller struct { config *rest.Config // waitingFor is the map of resources keyed by group version that have not yet been found in discovery - waitingFor map[schema.GroupVersionKind]*sets.String + waitingFor map[schema.GroupVersionKind]*sets.Set[string] } // poll checks if all the resources have been found in discovery, and returns false if not. -func (p *webhookPoller) poll() (done bool, err error) { +func (p *webhookPoller) poll(ctx context.Context) (done bool, err error) { // Create a new clientset to avoid any client caching of discovery c, err := client.New(p.config, client.Options{}) if err != nil { @@ -229,7 +241,7 @@ func (p *webhookPoller) poll() (done bool, err error) { delete(p.waitingFor, gvk) continue } - for _, name := range names.List() { + for _, name := range names.UnsortedList() { var obj = &unstructured.Unstructured{} obj.SetGroupVersionKind(gvk) err := c.Get(context.Background(), client.ObjectKey{ diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go index 3b5b79048d1..e5fd177aff8 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go @@ -21,7 +21,7 @@ Controller.Watch in order to generate and enqueue reconcile.Request work items. Generally, following premade event handlers should be sufficient for most use cases: -EventHandlers +EventHandlers: EnqueueRequestForObject - Enqueues a reconcile.Request containing the Name and Namespace of the object in the Event. This will cause the object that was the source of the Event (e.g. the created / deleted / updated object) to be diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go index e6d3a4eaabb..c72b2e1ebb1 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go @@ -17,6 +17,8 @@ limitations under the License. package handler import ( + "context" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/event" @@ -36,7 +38,7 @@ var _ EventHandler = &EnqueueRequestForObject{} type EnqueueRequestForObject struct{} // Create implements EventHandler. -func (e *EnqueueRequestForObject) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { +func (e *EnqueueRequestForObject) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { if evt.Object == nil { enqueueLog.Error(nil, "CreateEvent received with no metadata", "event", evt) return @@ -48,7 +50,7 @@ func (e *EnqueueRequestForObject) Create(evt event.CreateEvent, q workqueue.Rate } // Update implements EventHandler. -func (e *EnqueueRequestForObject) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { +func (e *EnqueueRequestForObject) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { switch { case evt.ObjectNew != nil: q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ @@ -66,7 +68,7 @@ func (e *EnqueueRequestForObject) Update(evt event.UpdateEvent, q workqueue.Rate } // Delete implements EventHandler. -func (e *EnqueueRequestForObject) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { +func (e *EnqueueRequestForObject) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { if evt.Object == nil { enqueueLog.Error(nil, "DeleteEvent received with no metadata", "event", evt) return @@ -78,7 +80,7 @@ func (e *EnqueueRequestForObject) Delete(evt event.DeleteEvent, q workqueue.Rate } // Generic implements EventHandler. -func (e *EnqueueRequestForObject) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { +func (e *EnqueueRequestForObject) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { if evt.Object == nil { enqueueLog.Error(nil, "GenericEvent received with no metadata", "event", evt) return diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go index 17401b1fdbe..b55fdde6ba5 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go @@ -17,16 +17,17 @@ limitations under the License. package handler import ( + "context" + "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" ) // MapFunc is the signature required for enqueueing requests from a generic function. // This type is usually used with EnqueueRequestsFromMapFunc when registering an event handler. -type MapFunc func(client.Object) []reconcile.Request +type MapFunc func(context.Context, client.Object) []reconcile.Request // EnqueueRequestsFromMapFunc enqueues Requests by running a transformation function that outputs a collection // of reconcile.Requests on each Event. The reconcile.Requests may be for an arbitrary set of objects @@ -52,32 +53,32 @@ type enqueueRequestsFromMapFunc struct { } // Create implements EventHandler. -func (e *enqueueRequestsFromMapFunc) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestsFromMapFunc) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} - e.mapAndEnqueue(q, evt.Object, reqs) + e.mapAndEnqueue(ctx, q, evt.Object, reqs) } // Update implements EventHandler. -func (e *enqueueRequestsFromMapFunc) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestsFromMapFunc) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} - e.mapAndEnqueue(q, evt.ObjectOld, reqs) - e.mapAndEnqueue(q, evt.ObjectNew, reqs) + e.mapAndEnqueue(ctx, q, evt.ObjectOld, reqs) + e.mapAndEnqueue(ctx, q, evt.ObjectNew, reqs) } // Delete implements EventHandler. -func (e *enqueueRequestsFromMapFunc) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestsFromMapFunc) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} - e.mapAndEnqueue(q, evt.Object, reqs) + e.mapAndEnqueue(ctx, q, evt.Object, reqs) } // Generic implements EventHandler. -func (e *enqueueRequestsFromMapFunc) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestsFromMapFunc) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} - e.mapAndEnqueue(q, evt.Object, reqs) + e.mapAndEnqueue(ctx, q, evt.Object, reqs) } -func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInterface, object client.Object, reqs map[reconcile.Request]empty) { - for _, req := range e.toRequests(object) { +func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(ctx context.Context, q workqueue.RateLimitingInterface, object client.Object, reqs map[reconcile.Request]empty) { + for _, req := range e.toRequests(ctx, object) { _, ok := reqs[req] if !ok { q.Add(req) @@ -85,13 +86,3 @@ func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInter } } } - -// EnqueueRequestsFromMapFunc can inject fields into the mapper. - -// InjectFunc implements inject.Injector. -func (e *enqueueRequestsFromMapFunc) InjectFunc(f inject.Func) error { - if f == nil { - return nil - } - return f(e.toRequests) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go index 63699893fc3..02e7d756f80 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go @@ -17,6 +17,7 @@ limitations under the License. package handler import ( + "context" "fmt" "k8s.io/apimachinery/pkg/api/meta" @@ -25,15 +26,18 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" logf "sigs.k8s.io/controller-runtime/pkg/internal/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" ) -var _ EventHandler = &EnqueueRequestForOwner{} +var _ EventHandler = &enqueueRequestForOwner{} -var log = logf.RuntimeLog.WithName("eventhandler").WithName("EnqueueRequestForOwner") +var log = logf.RuntimeLog.WithName("eventhandler").WithName("enqueueRequestForOwner") + +// OwnerOption modifies an EnqueueRequestForOwner EventHandler. +type OwnerOption func(e *enqueueRequestForOwner) // EnqueueRequestForOwner enqueues Requests for the Owners of an object. E.g. the object that created // the object that was the source of the Event. @@ -42,13 +46,34 @@ var log = logf.RuntimeLog.WithName("eventhandler").WithName("EnqueueRequestForOw // // - a source.Kind Source with Type of Pod. // -// - a handler.EnqueueRequestForOwner EventHandler with an OwnerType of ReplicaSet and IsController set to true. -type EnqueueRequestForOwner struct { - // OwnerType is the type of the Owner object to look for in OwnerReferences. Only Group and Kind are compared. - OwnerType runtime.Object +// - a handler.enqueueRequestForOwner EventHandler with an OwnerType of ReplicaSet and OnlyControllerOwner set to true. +func EnqueueRequestForOwner(scheme *runtime.Scheme, mapper meta.RESTMapper, ownerType client.Object, opts ...OwnerOption) EventHandler { + e := &enqueueRequestForOwner{ + ownerType: ownerType, + mapper: mapper, + } + if err := e.parseOwnerTypeGroupKind(scheme); err != nil { + panic(err) + } + for _, opt := range opts { + opt(e) + } + return e +} + +// OnlyControllerOwner if provided will only look at the first OwnerReference with Controller: true. +func OnlyControllerOwner() OwnerOption { + return func(e *enqueueRequestForOwner) { + e.isController = true + } +} - // IsController if set will only look at the first OwnerReference with Controller: true. - IsController bool +type enqueueRequestForOwner struct { + // ownerType is the type of the Owner object to look for in OwnerReferences. Only Group and Kind are compared. + ownerType runtime.Object + + // isController if set will only look at the first OwnerReference with Controller: true. + isController bool // groupKind is the cached Group and Kind from OwnerType groupKind schema.GroupKind @@ -58,7 +83,7 @@ type EnqueueRequestForOwner struct { } // Create implements EventHandler. -func (e *EnqueueRequestForOwner) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestForOwner) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} e.getOwnerReconcileRequest(evt.Object, reqs) for req := range reqs { @@ -67,7 +92,7 @@ func (e *EnqueueRequestForOwner) Create(evt event.CreateEvent, q workqueue.RateL } // Update implements EventHandler. -func (e *EnqueueRequestForOwner) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestForOwner) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} e.getOwnerReconcileRequest(evt.ObjectOld, reqs) e.getOwnerReconcileRequest(evt.ObjectNew, reqs) @@ -77,7 +102,7 @@ func (e *EnqueueRequestForOwner) Update(evt event.UpdateEvent, q workqueue.RateL } // Delete implements EventHandler. -func (e *EnqueueRequestForOwner) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestForOwner) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} e.getOwnerReconcileRequest(evt.Object, reqs) for req := range reqs { @@ -86,7 +111,7 @@ func (e *EnqueueRequestForOwner) Delete(evt event.DeleteEvent, q workqueue.RateL } // Generic implements EventHandler. -func (e *EnqueueRequestForOwner) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { +func (e *enqueueRequestForOwner) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { reqs := map[reconcile.Request]empty{} e.getOwnerReconcileRequest(evt.Object, reqs) for req := range reqs { @@ -96,17 +121,17 @@ func (e *EnqueueRequestForOwner) Generic(evt event.GenericEvent, q workqueue.Rat // parseOwnerTypeGroupKind parses the OwnerType into a Group and Kind and caches the result. Returns false // if the OwnerType could not be parsed using the scheme. -func (e *EnqueueRequestForOwner) parseOwnerTypeGroupKind(scheme *runtime.Scheme) error { +func (e *enqueueRequestForOwner) parseOwnerTypeGroupKind(scheme *runtime.Scheme) error { // Get the kinds of the type - kinds, _, err := scheme.ObjectKinds(e.OwnerType) + kinds, _, err := scheme.ObjectKinds(e.ownerType) if err != nil { - log.Error(err, "Could not get ObjectKinds for OwnerType", "owner type", fmt.Sprintf("%T", e.OwnerType)) + log.Error(err, "Could not get ObjectKinds for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType)) return err } // Expect only 1 kind. If there is more than one kind this is probably an edge case such as ListOptions. if len(kinds) != 1 { - err := fmt.Errorf("expected exactly 1 kind for OwnerType %T, but found %s kinds", e.OwnerType, kinds) - log.Error(nil, "expected exactly 1 kind for OwnerType", "owner type", fmt.Sprintf("%T", e.OwnerType), "kinds", kinds) + err := fmt.Errorf("expected exactly 1 kind for OwnerType %T, but found %s kinds", e.ownerType, kinds) + log.Error(nil, "expected exactly 1 kind for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType), "kinds", kinds) return err } // Cache the Group and Kind for the OwnerType @@ -116,7 +141,7 @@ func (e *EnqueueRequestForOwner) parseOwnerTypeGroupKind(scheme *runtime.Scheme) // getOwnerReconcileRequest looks at object and builds a map of reconcile.Request to reconcile // owners of object that match e.OwnerType. -func (e *EnqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, result map[reconcile.Request]empty) { +func (e *enqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, result map[reconcile.Request]empty) { // Iterate through the OwnerReferences looking for a match on Group and Kind against what was requested // by the user for _, ref := range e.getOwnersReferences(object) { @@ -138,7 +163,7 @@ func (e *EnqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, Name: ref.Name, }} - // if owner is not namespaced then we should set the namespace to the empty + // if owner is not namespaced then we should not set the namespace mapping, err := e.mapper.RESTMapping(e.groupKind, refGV.Version) if err != nil { log.Error(err, "Could not retrieve rest mapping", "kind", e.groupKind) @@ -153,16 +178,16 @@ func (e *EnqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, } } -// getOwnersReferences returns the OwnerReferences for an object as specified by the EnqueueRequestForOwner +// getOwnersReferences returns the OwnerReferences for an object as specified by the enqueueRequestForOwner // - if IsController is true: only take the Controller OwnerReference (if found) // - if IsController is false: take all OwnerReferences. -func (e *EnqueueRequestForOwner) getOwnersReferences(object metav1.Object) []metav1.OwnerReference { +func (e *enqueueRequestForOwner) getOwnersReferences(object metav1.Object) []metav1.OwnerReference { if object == nil { return nil } // If not filtered as Controller only, then use all the OwnerReferences - if !e.IsController { + if !e.isController { return object.GetOwnerReferences() } // If filtered to a Controller, only take the Controller OwnerReference @@ -172,18 +197,3 @@ func (e *EnqueueRequestForOwner) getOwnersReferences(object metav1.Object) []met // No Controller OwnerReference found return nil } - -var _ inject.Scheme = &EnqueueRequestForOwner{} - -// InjectScheme is called by the Controller to provide a singleton scheme to the EnqueueRequestForOwner. -func (e *EnqueueRequestForOwner) InjectScheme(s *runtime.Scheme) error { - return e.parseOwnerTypeGroupKind(s) -} - -var _ inject.Mapper = &EnqueueRequestForOwner{} - -// InjectMapper is called by the Controller to provide the rest mapper used by the manager. -func (e *EnqueueRequestForOwner) InjectMapper(m meta.RESTMapper) error { - e.mapper = m - return nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go index 8652d22d725..2f380f4fc4d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go @@ -17,6 +17,8 @@ limitations under the License. package handler import ( + "context" + "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/event" ) @@ -41,17 +43,17 @@ import ( // Most users shouldn't need to implement their own EventHandler. type EventHandler interface { // Create is called in response to an create event - e.g. Pod Creation. - Create(event.CreateEvent, workqueue.RateLimitingInterface) + Create(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) // Update is called in response to an update event - e.g. Pod Updated. - Update(event.UpdateEvent, workqueue.RateLimitingInterface) + Update(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) // Delete is called in response to a delete event - e.g. Pod Deleted. - Delete(event.DeleteEvent, workqueue.RateLimitingInterface) + Delete(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) // Generic is called in response to an event of an unknown type or a synthetic event triggered as a cron or // external trigger request - e.g. reconcile Autoscaling, or a Webhook. - Generic(event.GenericEvent, workqueue.RateLimitingInterface) + Generic(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) } var _ EventHandler = Funcs{} @@ -60,45 +62,45 @@ var _ EventHandler = Funcs{} type Funcs struct { // Create is called in response to an add event. Defaults to no-op. // RateLimitingInterface is used to enqueue reconcile.Requests. - CreateFunc func(event.CreateEvent, workqueue.RateLimitingInterface) + CreateFunc func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) // Update is called in response to an update event. Defaults to no-op. // RateLimitingInterface is used to enqueue reconcile.Requests. - UpdateFunc func(event.UpdateEvent, workqueue.RateLimitingInterface) + UpdateFunc func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) // Delete is called in response to a delete event. Defaults to no-op. // RateLimitingInterface is used to enqueue reconcile.Requests. - DeleteFunc func(event.DeleteEvent, workqueue.RateLimitingInterface) + DeleteFunc func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) // GenericFunc is called in response to a generic event. Defaults to no-op. // RateLimitingInterface is used to enqueue reconcile.Requests. - GenericFunc func(event.GenericEvent, workqueue.RateLimitingInterface) + GenericFunc func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) } // Create implements EventHandler. -func (h Funcs) Create(e event.CreateEvent, q workqueue.RateLimitingInterface) { +func (h Funcs) Create(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { if h.CreateFunc != nil { - h.CreateFunc(e, q) + h.CreateFunc(ctx, e, q) } } // Delete implements EventHandler. -func (h Funcs) Delete(e event.DeleteEvent, q workqueue.RateLimitingInterface) { +func (h Funcs) Delete(ctx context.Context, e event.DeleteEvent, q workqueue.RateLimitingInterface) { if h.DeleteFunc != nil { - h.DeleteFunc(e, q) + h.DeleteFunc(ctx, e, q) } } // Update implements EventHandler. -func (h Funcs) Update(e event.UpdateEvent, q workqueue.RateLimitingInterface) { +func (h Funcs) Update(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { if h.UpdateFunc != nil { - h.UpdateFunc(e, q) + h.UpdateFunc(ctx, e, q) } } // Generic implements EventHandler. -func (h Funcs) Generic(e event.GenericEvent, q workqueue.RateLimitingInterface) { +func (h Funcs) Generic(ctx context.Context, e event.GenericEvent, q workqueue.RateLimitingInterface) { if h.GenericFunc != nil { - h.GenericFunc(e, q) + h.GenericFunc(ctx, e, q) } } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go index bd1cc151af4..cfb5dc8d02b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go @@ -70,7 +70,7 @@ func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) { parts = append(parts, checkStatus{name: "ping", healthy: true}) } - for _, c := range excluded.List() { + for _, c := range excluded.UnsortedList() { log.V(1).Info("cannot exclude health check, no matches for it", "checker", c) } @@ -88,7 +88,7 @@ func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) { // any checks that the user requested to have excluded, but weren't actually // known checks. writeStatusAsText is always verbose on failure, and can be // forced to be verbose on success using the given argument. -func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.String, failed, forceVerbose bool) { +func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.Set[string], failed, forceVerbose bool) { resp.Header().Set("Content-Type", "text/plain; charset=utf-8") resp.Header().Set("X-Content-Type-Options", "nosniff") @@ -121,7 +121,7 @@ func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownE } if unknownExcludes.Len() > 0 { - fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.List()...)) + fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.UnsortedList()...)) } if failed { @@ -187,12 +187,12 @@ type Checker func(req *http.Request) error var Ping Checker = func(_ *http.Request) error { return nil } // getExcludedChecks extracts the health check names to be excluded from the query param. -func getExcludedChecks(r *http.Request) sets.String { +func getExcludedChecks(r *http.Request) sets.Set[string] { checks, found := r.URL.Query()["exclude"] if found { - return sets.NewString(checks...) + return sets.New[string](checks...) } - return sets.NewString() + return sets.New[string]() } // formatQuoted returns a formatted string of the health check names, diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go index 3732eea16ef..83aba28cb7b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go @@ -24,6 +24,7 @@ import ( "time" "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/client-go/util/workqueue" @@ -32,12 +33,9 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" "sigs.k8s.io/controller-runtime/pkg/source" ) -var _ inject.Injector = &Controller{} - // Controller implements controller.Controller. type Controller struct { // Name is used to uniquely identify a Controller in tracing, logging and monitoring. Name is required. @@ -60,10 +58,6 @@ type Controller struct { // the Queue for processing Queue workqueue.RateLimitingInterface - // SetFields is used to inject dependencies into other objects such as Sources, EventHandlers and Predicates - // Deprecated: the caller should handle injected fields itself. - SetFields func(i interface{}) error - // mu is used to synchronize Controller setup mu sync.Mutex @@ -91,7 +85,10 @@ type Controller struct { LogConstructor func(request *reconcile.Request) logr.Logger // RecoverPanic indicates whether the panic caused by reconcile should be recovered. - RecoverPanic bool + RecoverPanic *bool + + // LeaderElected indicates whether the controller is leader elected or always running. + LeaderElected *bool } // watchDescription contains all the information necessary to start a watch. @@ -105,7 +102,7 @@ type watchDescription struct { func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) { defer func() { if r := recover(); r != nil { - if c.RecoverPanic { + if c.RecoverPanic != nil && *c.RecoverPanic { for _, fn := range utilruntime.PanicHandlers { fn(r) } @@ -126,19 +123,6 @@ func (c *Controller) Watch(src source.Source, evthdler handler.EventHandler, prc c.mu.Lock() defer c.mu.Unlock() - // Inject Cache into arguments - if err := c.SetFields(src); err != nil { - return err - } - if err := c.SetFields(evthdler); err != nil { - return err - } - for _, pr := range prct { - if err := c.SetFields(pr); err != nil { - return err - } - } - // Controller hasn't started yet, store the watches locally and return. // // These watches are going to be held on the controller struct until the manager or user calls Start(...). @@ -151,6 +135,14 @@ func (c *Controller) Watch(src source.Source, evthdler handler.EventHandler, prc return src.Start(c.ctx, evthdler, c.Queue, prct...) } +// NeedLeaderElection implements the manager.LeaderElectionRunnable interface. +func (c *Controller) NeedLeaderElection() bool { + if c.LeaderElected == nil { + return true + } + return *c.LeaderElected +} + // Start implements controller.Controller. func (c *Controller) Start(ctx context.Context) error { // use an IIFE to get proper lock handling @@ -311,16 +303,22 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) { } log := c.LogConstructor(&req) + reconcileID := uuid.NewUUID() - log = log.WithValues("reconcileID", uuid.NewUUID()) + log = log.WithValues("reconcileID", reconcileID) ctx = logf.IntoContext(ctx, log) + ctx = addReconcileID(ctx, reconcileID) // RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the // resource to be synced. result, err := c.Reconcile(ctx, req) switch { case err != nil: - c.Queue.AddRateLimited(req) + if errors.Is(err, reconcile.TerminalError(nil)) { + ctrlmetrics.TerminalReconcileErrors.WithLabelValues(c.Name).Inc() + } else { + c.Queue.AddRateLimited(req) + } ctrlmetrics.ReconcileErrors.WithLabelValues(c.Name).Inc() ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelError).Inc() log.Error(err, "Reconciler error") @@ -348,13 +346,25 @@ func (c *Controller) GetLogger() logr.Logger { return c.LogConstructor(nil) } -// InjectFunc implement SetFields.Injector. -func (c *Controller) InjectFunc(f inject.Func) error { - c.SetFields = f - return nil -} - // updateMetrics updates prometheus metrics within the controller. func (c *Controller) updateMetrics(reconcileTime time.Duration) { ctrlmetrics.ReconcileTime.WithLabelValues(c.Name).Observe(reconcileTime.Seconds()) } + +// ReconcileIDFromContext gets the reconcileID from the current context. +func ReconcileIDFromContext(ctx context.Context) types.UID { + r, ok := ctx.Value(reconcileIDKey{}).(types.UID) + if !ok { + return "" + } + + return r +} + +// reconcileIDKey is a context.Context Value key. Its associated value should +// be a types.UID. +type reconcileIDKey struct{} + +func addReconcileID(ctx context.Context, reconcileID types.UID) context.Context { + return context.WithValue(ctx, reconcileIDKey{}, reconcileID) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go index baec6692778..b74ce062be7 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go @@ -39,6 +39,13 @@ var ( Help: "Total number of reconciliation errors per controller", }, []string{"controller"}) + // TerminalReconcileErrors is a prometheus counter metrics which holds the total + // number of terminal errors from the Reconciler. + TerminalReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_terminal_reconcile_errors_total", + Help: "Total number of terminal reconciliation errors per controller", + }, []string{"controller"}) + // ReconcileTime is a prometheus metric which keeps track of the duration // of reconciliations. ReconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{ @@ -67,6 +74,7 @@ func init() { metrics.Registry.MustRegister( ReconcileTotal, ReconcileErrors, + TerminalReconcileErrors, ReconcileTime, WorkerCount, ActiveWorkers, diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go new file mode 100644 index 00000000000..4f6d0843184 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go @@ -0,0 +1,35 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package selector + +import ( + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/selection" +) + +// RequiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`. +func RequiresExactMatch(sel fields.Selector) (field, val string, required bool) { + reqs := sel.Requirements() + if len(reqs) != 1 { + return "", "", false + } + req := reqs[0] + if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals { + return "", "", false + } + return req.Field, req.Value, true +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go index 7057f3dbe43..0189c043233 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go @@ -17,14 +17,9 @@ limitations under the License. package objectutil import ( - "errors" - "fmt" - apimeta "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) // FilterWithLabels returns a copy of the items in objs matching labelSel. @@ -45,34 +40,3 @@ func FilterWithLabels(objs []runtime.Object, labelSel labels.Selector) ([]runtim } return outItems, nil } - -// IsAPINamespaced returns true if the object is namespace scoped. -// For unstructured objects the gvk is found from the object itself. -func IsAPINamespaced(obj runtime.Object, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) { - gvk, err := apiutil.GVKForObject(obj, scheme) - if err != nil { - return false, err - } - - return IsAPINamespacedWithGVK(gvk, scheme, restmapper) -} - -// IsAPINamespacedWithGVK returns true if the object having the provided -// GVK is namespace scoped. -func IsAPINamespacedWithGVK(gk schema.GroupVersionKind, scheme *runtime.Scheme, restmapper apimeta.RESTMapper) (bool, error) { - restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gk.Group, Kind: gk.Kind}) - if err != nil { - return false, fmt.Errorf("failed to get restmapping: %w", err) - } - - scope := restmapping.Scope.Name() - - if scope == "" { - return false, errors.New("scope cannot be identified, empty scope returned") - } - - if scope != apimeta.RESTScopeNameRoot { - return true, nil - } - return false, nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go index 46cc1714bdc..21f0146ba3b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go @@ -19,6 +19,7 @@ package recorder import ( "context" "fmt" + "net/http" "sync" "github.com/go-logr/logr" @@ -100,7 +101,7 @@ func (p *Provider) getBroadcaster() record.EventBroadcaster { broadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient}) broadcaster.StartEventWatcher( func(e *corev1.Event) { - p.logger.V(1).Info(e.Type, "object", e.InvolvedObject, "reason", e.Reason, "message", e.Message) + p.logger.V(1).Info(e.Message, "type", e.Type, "object", e.InvolvedObject, "reason", e.Reason) }) p.broadcaster = broadcaster p.stopBroadcaster = stop @@ -110,8 +111,12 @@ func (p *Provider) getBroadcaster() record.EventBroadcaster { } // NewProvider create a new Provider instance. -func NewProvider(config *rest.Config, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) { - corev1Client, err := corev1client.NewForConfig(config) +func NewProvider(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) { + if httpClient == nil { + panic("httpClient must not be nil") + } + + corev1Client, err := corev1client.NewForConfigAndClient(config, httpClient) if err != nil { return nil, fmt.Errorf("failed to init client: %w", err) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go new file mode 100644 index 00000000000..ae8404a1fa4 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go @@ -0,0 +1,170 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" + "fmt" + + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var log = logf.RuntimeLog.WithName("source").WithName("EventHandler") + +// NewEventHandler creates a new EventHandler. +func NewEventHandler(ctx context.Context, queue workqueue.RateLimitingInterface, handler handler.EventHandler, predicates []predicate.Predicate) *EventHandler { + return &EventHandler{ + ctx: ctx, + handler: handler, + queue: queue, + predicates: predicates, + } +} + +// EventHandler adapts a handler.EventHandler interface to a cache.ResourceEventHandler interface. +type EventHandler struct { + // ctx stores the context that created the event handler + // that is used to propagate cancellation signals to each handler function. + ctx context.Context + + handler handler.EventHandler + queue workqueue.RateLimitingInterface + predicates []predicate.Predicate +} + +// HandlerFuncs converts EventHandler to a ResourceEventHandlerFuncs +// TODO: switch to ResourceEventHandlerDetailedFuncs with client-go 1.27 +func (e *EventHandler) HandlerFuncs() cache.ResourceEventHandlerFuncs { + return cache.ResourceEventHandlerFuncs{ + AddFunc: e.OnAdd, + UpdateFunc: e.OnUpdate, + DeleteFunc: e.OnDelete, + } +} + +// OnAdd creates CreateEvent and calls Create on EventHandler. +func (e *EventHandler) OnAdd(obj interface{}) { + c := event.CreateEvent{} + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + c.Object = o + } else { + log.Error(nil, "OnAdd missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Create(c) { + return + } + } + + // Invoke create handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Create(ctx, c, e.queue) +} + +// OnUpdate creates UpdateEvent and calls Update on EventHandler. +func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) { + u := event.UpdateEvent{} + + if o, ok := oldObj.(client.Object); ok { + u.ObjectOld = o + } else { + log.Error(nil, "OnUpdate missing ObjectOld", + "object", oldObj, "type", fmt.Sprintf("%T", oldObj)) + return + } + + // Pull Object out of the object + if o, ok := newObj.(client.Object); ok { + u.ObjectNew = o + } else { + log.Error(nil, "OnUpdate missing ObjectNew", + "object", newObj, "type", fmt.Sprintf("%T", newObj)) + return + } + + for _, p := range e.predicates { + if !p.Update(u) { + return + } + } + + // Invoke update handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Update(ctx, u, e.queue) +} + +// OnDelete creates DeleteEvent and calls Delete on EventHandler. +func (e *EventHandler) OnDelete(obj interface{}) { + d := event.DeleteEvent{} + + // Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a + // DeleteFinalStateUnknown struct, so the object needs to be pulled out. + // Copied from sample-controller + // This should never happen if we aren't missing events, which we have concluded that we are not + // and made decisions off of this belief. Maybe this shouldn't be here? + var ok bool + if _, ok = obj.(client.Object); !ok { + // If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown", + "type", fmt.Sprintf("%T", obj), + "object", obj) + return + } + + // Set DeleteStateUnknown to true + d.DeleteStateUnknown = true + + // Set obj to the tombstone obj + obj = tombstone.Obj + } + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + d.Object = o + } else { + log.Error(nil, "OnDelete missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Delete(d) { + return + } + } + + // Invoke delete handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Delete(ctx, d, e.queue) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go new file mode 100644 index 00000000000..b3a82271256 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go @@ -0,0 +1,117 @@ +package internal + +import ( + "context" + "errors" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). +type Kind struct { + // Type is the type of object to watch. e.g. &v1.Pod{} + Type client.Object + + // Cache used to watch APIs + Cache cache.Cache + + // started may contain an error if one was encountered during startup. If its closed and does not + // contain an error, startup and syncing finished. + started chan error + startCancel func() +} + +// Start is internal and should be called only by the Controller to register an EventHandler with the Informer +// to enqueue reconcile.Requests. +func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + if ks.Type == nil { + return fmt.Errorf("must create Kind with a non-nil object") + } + if ks.Cache == nil { + return fmt.Errorf("must create Kind with a non-nil cache") + } + + // cache.GetInformer will block until its context is cancelled if the cache was already started and it can not + // sync that informer (most commonly due to RBAC issues). + ctx, ks.startCancel = context.WithCancel(ctx) + ks.started = make(chan error) + go func() { + var ( + i cache.Informer + lastErr error + ) + + // Tries to get an informer until it returns true, + // an error or the specified context is cancelled or expired. + if err := wait.PollUntilContextCancel(ctx, 10*time.Second, true, func(ctx context.Context) (bool, error) { + // Lookup the Informer from the Cache and add an EventHandler which populates the Queue + i, lastErr = ks.Cache.GetInformer(ctx, ks.Type) + if lastErr != nil { + kindMatchErr := &meta.NoKindMatchError{} + switch { + case errors.As(lastErr, &kindMatchErr): + log.Error(lastErr, "if kind is a CRD, it should be installed before calling Start", + "kind", kindMatchErr.GroupKind) + case runtime.IsNotRegisteredError(lastErr): + log.Error(lastErr, "kind must be registered to the Scheme") + default: + log.Error(lastErr, "failed to get informer from cache") + } + return false, nil // Retry. + } + return true, nil + }); err != nil { + if lastErr != nil { + ks.started <- fmt.Errorf("failed to get informer from cache: %w", lastErr) + return + } + ks.started <- err + return + } + + _, err := i.AddEventHandler(NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + ks.started <- err + return + } + if !ks.Cache.WaitForCacheSync(ctx) { + // Would be great to return something more informative here + ks.started <- errors.New("cache did not sync") + } + close(ks.started) + }() + + return nil +} + +func (ks *Kind) String() string { + if ks.Type != nil { + return fmt.Sprintf("kind source: %T", ks.Type) + } + return "kind source: unknown type" +} + +// WaitForSync implements SyncingSource to allow controllers to wait with starting +// workers until the cache is synced. +func (ks *Kind) WaitForSync(ctx context.Context) error { + select { + case err := <-ks.started: + return err + case <-ctx.Done(): + ks.startCancel() + if errors.Is(ctx.Err(), context.Canceled) { + return nil + } + return fmt.Errorf("timed out waiting for cache to be synced for Kind %T", ks.Type) + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go new file mode 100644 index 00000000000..84beb1b2654 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go @@ -0,0 +1,37 @@ +package syncs + +import ( + "context" + "reflect" + "sync" +) + +// MergeChans returns a channel that is closed when any of the input channels are signaled. +// The caller must call the returned CancelFunc to ensure no resources are leaked. +func MergeChans[T any](chans ...<-chan T) (<-chan T, context.CancelFunc) { + var once sync.Once + out := make(chan T) + cancel := make(chan T) + cancelFunc := func() { + once.Do(func() { + close(cancel) + }) + } + cases := make([]reflect.SelectCase, len(chans)+1) + for i := range chans { + cases[i] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(chans[i]), + } + } + cases[len(cases)-1] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(cancel), + } + go func() { + defer close(out) + _, _, _ = reflect.Select(cases) + }() + + return out, cancelFunc +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go index 6c2c91e1449..391eec1facf 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go @@ -93,12 +93,12 @@ type TemplateDefaults struct { // TemplateAndArguments joins structured arguments and non-structured arguments, preserving existing // behavior. Namely: // -// 1. if templ has len > 0, it will be rendered against data -// 2. the rendered template values that look like `--foo=bar` will be split -// and appended to args, the rest will be kept around -// 3. the given args will be rendered as string form. If a template is given, -// no defaults will be used, otherwise defaults will be used -// 4. a result of [args..., rest...] will be returned +// 1. if templ has len > 0, it will be rendered against data +// 2. the rendered template values that look like `--foo=bar` will be split +// and appended to args, the rest will be kept around +// 3. the given args will be rendered as string form. If a template is given, +// no defaults will be used, otherwise defaults will be used +// 4. a result of [args..., rest...] will be returned // // It returns the resulting rendered arguments, plus the arguments that were // not transferred to `args` during rendering. @@ -215,9 +215,9 @@ var ( // for passing to exec.Command and friends, making use of the given defaults // as indicated for each particular argument. // -// - Any flag in defaults that's not in Arguments will be present in the output -// - Any flag that's present in Arguments will be passed the corresponding -// defaults to do with as it will (ignore, append-to, suppress, etc). +// - Any flag in defaults that's not in Arguments will be present in the output +// - Any flag that's present in Arguments will be passed the corresponding +// defaults to do with as it will (ignore, append-to, suppress, etc). func (a *Arguments) AsStrings(defaults map[string][]string) []string { // sort for deterministic ordering keysInOrder := make([]string, 0, len(defaults)+len(a.values)) @@ -323,9 +323,9 @@ func (a *Arguments) SetRaw(key string, val Arg) *Arguments { // used in conjunction with SetRaw. For example, to set `--some-flag` to the // API server's CertDir, you could do: // -// server.Configure().SetRaw("--some-flag", FuncArg(func(defaults []string) []string { -// return []string{server.CertDir} -// })) +// server.Configure().SetRaw("--some-flag", FuncArg(func(defaults []string) []string { +// return []string{server.CertDir} +// })) // // FuncArg ignores Appends; if you need to support appending values too, consider implementing // Arg directly. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go index c721ba01af4..af83c70a2fa 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go @@ -184,16 +184,12 @@ func (ps *State) Start(stdout, stderr io.Writer) (err error) { ps.ready = true return nil case <-ps.waitDone: - if pollerStopCh != nil { - close(pollerStopCh) - } + close(pollerStopCh) return fmt.Errorf("timeout waiting for process %s to start successfully "+ "(it may have failed to start, or stopped unexpectedly before becoming ready)", path.Base(ps.Path)) case <-timedOut: - if pollerStopCh != nil { - close(pollerStopCh) - } + close(pollerStopCh) if ps.Cmd != nil { // intentionally ignore this -- we might've crashed, failed to start, etc ps.Cmd.Process.Signal(syscall.SIGTERM) //nolint:errcheck diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go index 6fca630634b..c27b4305f8b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go @@ -25,7 +25,7 @@ import ( // loggerPromise knows how to populate a concrete logr.Logger // with options, given an actual base logger later on down the line. type loggerPromise struct { - logger *DelegatingLogSink + logger *delegatingLogSink childPromises []*loggerPromise promisesLock sync.Mutex @@ -33,7 +33,7 @@ type loggerPromise struct { tags []interface{} } -func (p *loggerPromise) WithName(l *DelegatingLogSink, name string) *loggerPromise { +func (p *loggerPromise) WithName(l *delegatingLogSink, name string) *loggerPromise { res := &loggerPromise{ logger: l, name: &name, @@ -47,7 +47,7 @@ func (p *loggerPromise) WithName(l *DelegatingLogSink, name string) *loggerPromi } // WithValues provides a new Logger with the tags appended. -func (p *loggerPromise) WithValues(l *DelegatingLogSink, tags ...interface{}) *loggerPromise { +func (p *loggerPromise) WithValues(l *delegatingLogSink, tags ...interface{}) *loggerPromise { res := &loggerPromise{ logger: l, tags: tags, @@ -73,6 +73,9 @@ func (p *loggerPromise) Fulfill(parentLogSink logr.LogSink) { p.logger.lock.Lock() p.logger.logger = sink + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + p.logger.logger = withCallDepth.WithCallDepth(1) + } p.logger.promise = nil p.logger.lock.Unlock() @@ -81,12 +84,12 @@ func (p *loggerPromise) Fulfill(parentLogSink logr.LogSink) { } } -// DelegatingLogSink is a logsink that delegates to another logr.LogSink. +// delegatingLogSink is a logsink that delegates to another logr.LogSink. // If the underlying promise is not nil, it registers calls to sub-loggers with // the logging factory to be populated later, and returns a new delegating // logger. It expects to have *some* logr.Logger set at all times (generally // a no-op logger before the promises are fulfilled). -type DelegatingLogSink struct { +type delegatingLogSink struct { lock sync.RWMutex logger logr.LogSink promise *loggerPromise @@ -94,7 +97,8 @@ type DelegatingLogSink struct { } // Init implements logr.LogSink. -func (l *DelegatingLogSink) Init(info logr.RuntimeInfo) { +func (l *delegatingLogSink) Init(info logr.RuntimeInfo) { + eventuallyFulfillRoot() l.lock.Lock() defer l.lock.Unlock() l.info = info @@ -103,7 +107,8 @@ func (l *DelegatingLogSink) Init(info logr.RuntimeInfo) { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info // logs. -func (l *DelegatingLogSink) Enabled(level int) bool { +func (l *delegatingLogSink) Enabled(level int) bool { + eventuallyFulfillRoot() l.lock.RLock() defer l.lock.RUnlock() return l.logger.Enabled(level) @@ -115,7 +120,8 @@ func (l *DelegatingLogSink) Enabled(level int) bool { // the log line. The key/value pairs can then be used to add additional // variable information. The key/value pairs should alternate string // keys and arbitrary values. -func (l *DelegatingLogSink) Info(level int, msg string, keysAndValues ...interface{}) { +func (l *delegatingLogSink) Info(level int, msg string, keysAndValues ...interface{}) { + eventuallyFulfillRoot() l.lock.RLock() defer l.lock.RUnlock() l.logger.Info(level, msg, keysAndValues...) @@ -129,22 +135,28 @@ func (l *DelegatingLogSink) Info(level int, msg string, keysAndValues ...interfa // The msg field should be used to add context to any underlying error, // while the err field should be used to attach the actual error that // triggered this log line, if present. -func (l *DelegatingLogSink) Error(err error, msg string, keysAndValues ...interface{}) { +func (l *delegatingLogSink) Error(err error, msg string, keysAndValues ...interface{}) { + eventuallyFulfillRoot() l.lock.RLock() defer l.lock.RUnlock() l.logger.Error(err, msg, keysAndValues...) } // WithName provides a new Logger with the name appended. -func (l *DelegatingLogSink) WithName(name string) logr.LogSink { +func (l *delegatingLogSink) WithName(name string) logr.LogSink { + eventuallyFulfillRoot() l.lock.RLock() defer l.lock.RUnlock() if l.promise == nil { - return l.logger.WithName(name) + sink := l.logger.WithName(name) + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + sink = withCallDepth.WithCallDepth(-1) + } + return sink } - res := &DelegatingLogSink{logger: l.logger} + res := &delegatingLogSink{logger: l.logger} promise := l.promise.WithName(res, name) res.promise = promise @@ -152,15 +164,20 @@ func (l *DelegatingLogSink) WithName(name string) logr.LogSink { } // WithValues provides a new Logger with the tags appended. -func (l *DelegatingLogSink) WithValues(tags ...interface{}) logr.LogSink { +func (l *delegatingLogSink) WithValues(tags ...interface{}) logr.LogSink { + eventuallyFulfillRoot() l.lock.RLock() defer l.lock.RUnlock() if l.promise == nil { - return l.logger.WithValues(tags...) + sink := l.logger.WithValues(tags...) + if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok { + sink = withCallDepth.WithCallDepth(-1) + } + return sink } - res := &DelegatingLogSink{logger: l.logger} + res := &delegatingLogSink{logger: l.logger} promise := l.promise.WithValues(res, tags...) res.promise = promise @@ -170,16 +187,16 @@ func (l *DelegatingLogSink) WithValues(tags ...interface{}) logr.LogSink { // Fulfill switches the logger over to use the actual logger // provided, instead of the temporary initial one, if this method // has not been previously called. -func (l *DelegatingLogSink) Fulfill(actual logr.LogSink) { +func (l *delegatingLogSink) Fulfill(actual logr.LogSink) { if l.promise != nil { l.promise.Fulfill(actual) } } -// NewDelegatingLogSink constructs a new DelegatingLogSink which uses +// newDelegatingLogSink constructs a new DelegatingLogSink which uses // the given logger before its promise is fulfilled. -func NewDelegatingLogSink(initial logr.LogSink) *DelegatingLogSink { - l := &DelegatingLogSink{ +func newDelegatingLogSink(initial logr.LogSink) *delegatingLogSink { + l := &delegatingLogSink{ logger: initial, promise: &loggerPromise{promisesLock: sync.Mutex{}}, } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go index 3965769c383..a79151c69ed 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go @@ -17,7 +17,7 @@ limitations under the License. // Package log contains utilities for fetching a new logger // when one is not already available. // -// The Log Handle +// # The Log Handle // // This package contains a root logr.Logger Log. It may be used to // get a handle to whatever the root logging implementation is. By @@ -25,7 +25,7 @@ limitations under the License. // to loggers. When the implementation is set using SetLogger, these // "promises" will be converted over to real loggers. // -// Logr +// # Logr // // All logging in controller-runtime is structured, using a set of interfaces // defined by a package called logr @@ -35,7 +35,10 @@ package log import ( "context" - "sync" + "fmt" + "os" + "runtime/debug" + "sync/atomic" "time" "github.com/go-logr/logr" @@ -43,35 +46,24 @@ import ( // SetLogger sets a concrete logging implementation for all deferred Loggers. func SetLogger(l logr.Logger) { - loggerWasSetLock.Lock() - defer loggerWasSetLock.Unlock() - - loggerWasSet = true - dlog.Fulfill(l.GetSink()) + logFullfilled.Store(true) + rootLog.Fulfill(l.GetSink()) } -// It is safe to assume that if this wasn't set within the first 30 seconds of a binaries -// lifetime, it will never get set. The DelegatingLogSink causes a high number of memory -// allocations when not given an actual Logger, so we set a NullLogSink to avoid that. -// -// We need to keep the DelegatingLogSink because we have various inits() that get a logger from -// here. They will always get executed before any code that imports controller-runtime -// has a chance to run and hence to set an actual logger. -func init() { - // Init is blocking, so start a new goroutine - go func() { - time.Sleep(30 * time.Second) - loggerWasSetLock.Lock() - defer loggerWasSetLock.Unlock() - if !loggerWasSet { - dlog.Fulfill(NullLogSink{}) +func eventuallyFulfillRoot() { + if logFullfilled.Load() { + return + } + if time.Since(rootLogCreated).Seconds() >= 30 { + if logFullfilled.CompareAndSwap(false, true) { + fmt.Fprintf(os.Stderr, "[controller-runtime] log.SetLogger(...) was never called, logs will not be displayed:\n%s", debug.Stack()) + SetLogger(logr.New(NullLogSink{})) } - }() + } } var ( - loggerWasSetLock sync.Mutex - loggerWasSet bool + logFullfilled atomic.Bool ) // Log is the base logger used by kubebuilder. It delegates @@ -80,8 +72,10 @@ var ( // the first 30 seconds of a binaries lifetime, it will get // set to a NullLogSink. var ( - dlog = NewDelegatingLogSink(NullLogSink{}) - Log = logr.New(dlog) + rootLog, rootLogCreated = func() (*delegatingLogSink, time.Time) { + return newDelegatingLogSink(NullLogSink{}), time.Now() + }() + Log = logr.New(rootLog) ) // FromContext returns a logger with predefined values from a context.Context. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go index 98244702403..3b4ebfdaa0b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go @@ -24,7 +24,6 @@ import ( "go.uber.org/zap/zapcore" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" ) // KubeAwareEncoder is a Kubernetes-aware Zap Encoder. @@ -41,21 +40,6 @@ type KubeAwareEncoder struct { Verbose bool } -// namespacedNameWrapper is a zapcore.ObjectMarshaler for Kubernetes NamespacedName. -type namespacedNameWrapper struct { - types.NamespacedName -} - -func (w namespacedNameWrapper) MarshalLogObject(enc zapcore.ObjectEncoder) error { - if w.Namespace != "" { - enc.AddString("namespace", w.Namespace) - } - - enc.AddString("name", w.Name) - - return nil -} - // kubeObjectWrapper is a zapcore.ObjectMarshaler for Kubernetes objects. type kubeObjectWrapper struct { obj runtime.Object @@ -119,12 +103,6 @@ func (k *KubeAwareEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Fie Key: field.Key, Interface: kubeObjectWrapper{obj: val}, } - case types.NamespacedName: - fields[i] = zapcore.Field{ - Type: zapcore.ObjectMarshalerType, - Key: field.Key, - Interface: namespacedNameWrapper{NamespacedName: val}, - } } } } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go index 7db4cdda399..ee89a7c6a49 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go @@ -101,7 +101,7 @@ func newConsoleEncoder(opts ...EncoderConfigOption) zapcore.Encoder { return zapcore.NewConsoleEncoder(encoderConfig) } -// Level sets Options.Level, which configures the the minimum enabled logging level e.g Debug, Info. +// Level sets Options.Level, which configures the minimum enabled logging level e.g Debug, Info. // A zap log level should be multiplied by -1 to get the logr verbosity. // For example, to get logr verbosity of 3, pass zapcore.Level(-3) to this Opts. // See https://pkg.go.dev/github.com/go-logr/zapr for how zap level relates to logr verbosity. @@ -168,7 +168,7 @@ type Options struct { // underlying Zap logger. ZapOpts []zap.Option // TimeEncoder specifies the encoder for the timestamps in log messages. - // Defaults to EpochTimeEncoder as this is the default in Zap currently. + // Defaults to RFC3339TimeEncoder. TimeEncoder zapcore.TimeEncoder } @@ -217,7 +217,7 @@ func (o *Options) addDefaults() { } if o.TimeEncoder == nil { - o.TimeEncoder = zapcore.EpochTimeEncoder + o.TimeEncoder = zapcore.RFC3339TimeEncoder } f := func(ecfg *zapcore.EncoderConfig) { ecfg.EncodeTime = o.TimeEncoder @@ -244,21 +244,22 @@ func NewRaw(opts ...Opts) *zap.Logger { // this basically mimics NewConfig, but with a custom sink sink := zapcore.AddSync(o.DestWriter) - o.ZapOpts = append(o.ZapOpts, zap.AddCallerSkip(1), zap.ErrorOutput(sink)) + o.ZapOpts = append(o.ZapOpts, zap.ErrorOutput(sink)) log := zap.New(zapcore.NewCore(&KubeAwareEncoder{Encoder: o.Encoder, Verbose: o.Development}, sink, o.Level)) log = log.WithOptions(o.ZapOpts...) return log } -// BindFlags will parse the given flagset for zap option flags and set the log options accordingly -// zap-devel: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn) -// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) -// zap-encoder: Zap log encoding (one of 'json' or 'console') -// zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', -// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity") -// zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'info', 'error' or 'panic') -// zap-time-encoding: Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano'). -// Defaults to 'epoch'. +// BindFlags will parse the given flagset for zap option flags and set the log options accordingly: +// - zap-devel: +// Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn) +// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) +// - zap-encoder: Zap log encoding (one of 'json' or 'console') +// - zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', +// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity"). +// - zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'info', 'error' or 'panic') +// - zap-time-encoding: Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano'), +// Defaults to 'epoch'. func (o *Options) BindFlags(fs *flag.FlagSet) { // Set Development mode value fs.BoolVar(&o.Development, "zap-devel", o.Development, @@ -298,10 +299,11 @@ func (o *Options) BindFlags(fs *flag.FlagSet) { } // UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI. -// opts := zap.Options{} -// opts.BindFlags(flag.CommandLine) -// flag.Parse() -// log := zap.New(zap.UseFlagOptions(&opts)) +// +// opts := zap.Options{} +// opts.BindFlags(flag.CommandLine) +// flag.Parse() +// log := zap.New(zap.UseFlagOptions(&opts)) func UseFlagOptions(in *Options) Opts { return func(o *Options) { *o = *in diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go index 5b22c628f9f..f298229e570 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go @@ -22,6 +22,7 @@ import ( "fmt" "net" "net/http" + "net/http/pprof" "sync" "sync/atomic" "time" @@ -31,7 +32,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" kerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" "k8s.io/client-go/tools/leaderelection" "k8s.io/client-go/tools/leaderelection/resourcelock" @@ -40,12 +40,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/cluster" - "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/config" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" "sigs.k8s.io/controller-runtime/pkg/metrics" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" "sigs.k8s.io/controller-runtime/pkg/webhook" ) @@ -106,8 +105,11 @@ type controllerManager struct { // Healthz probe handler healthzHandler *healthz.Handler - // controllerOptions are the global controller options. - controllerOptions v1alpha1.ControllerConfigurationSpec + // pprofListener is used to serve pprof + pprofListener net.Listener + + // controllerConfig are the global controller options. + controllerConfig config.Controller // Logger is the logger that should be used by this manager. // If none is set, it defaults to log.Log global logger. @@ -127,20 +129,14 @@ type controllerManager struct { // election was configured. elected chan struct{} - // port is the port that the webhook server serves at. - port int - // host is the hostname that the webhook server binds to. - host string - // CertDir is the directory that contains the server key and certificate. - // if not set, webhook server would look up the server key and certificate in - // {TempDir}/k8s-webhook-server/serving-certs - certDir string - - webhookServer *webhook.Server + webhookServer webhook.Server // webhookServerOnce will be called in GetWebhookServer() to optionally initialize // webhookServer if unset, and Add() it to controllerManager. webhookServerOnce sync.Once + // leaderElectionID is the name of the resource that leader election + // will use for holding the leader lock. + leaderElectionID string // leaseDuration is the duration that non-leader candidates will // wait to force acquire leadership. leaseDuration time.Duration @@ -185,31 +181,9 @@ func (cm *controllerManager) Add(r Runnable) error { } func (cm *controllerManager) add(r Runnable) error { - // Set dependencies on the object - if err := cm.SetFields(r); err != nil { - return err - } return cm.runnables.Add(r) } -// Deprecated: use the equivalent Options field to set a field. This method will be removed in v0.10. -func (cm *controllerManager) SetFields(i interface{}) error { - if err := cm.cluster.SetFields(i); err != nil { - return err - } - if _, err := inject.InjectorInto(cm.SetFields, i); err != nil { - return err - } - if _, err := inject.StopChannelInto(cm.internalProceduresStop, i); err != nil { - return err - } - if _, err := inject.LoggerInto(cm.logger, i); err != nil { - return err - } - - return nil -} - // AddMetricsExtraHandler adds extra handler served on path to the http server that serves metrics. func (cm *controllerManager) AddMetricsExtraHandler(path string, handler http.Handler) error { cm.Lock() @@ -266,6 +240,10 @@ func (cm *controllerManager) AddReadyzCheck(name string, check healthz.Checker) return nil } +func (cm *controllerManager) GetHTTPClient() *http.Client { + return cm.cluster.GetHTTPClient() +} + func (cm *controllerManager) GetConfig() *rest.Config { return cm.cluster.GetConfig() } @@ -298,14 +276,10 @@ func (cm *controllerManager) GetAPIReader() client.Reader { return cm.cluster.GetAPIReader() } -func (cm *controllerManager) GetWebhookServer() *webhook.Server { +func (cm *controllerManager) GetWebhookServer() webhook.Server { cm.webhookServerOnce.Do(func() { if cm.webhookServer == nil { - cm.webhookServer = &webhook.Server{ - Port: cm.port, - Host: cm.host, - CertDir: cm.certDir, - } + panic("webhook should not be nil") } if err := cm.Add(cm.webhookServer); err != nil { panic(fmt.Sprintf("unable to add webhook server to the controller manager: %s", err)) @@ -318,23 +292,29 @@ func (cm *controllerManager) GetLogger() logr.Logger { return cm.logger } -func (cm *controllerManager) GetControllerOptions() v1alpha1.ControllerConfigurationSpec { - return cm.controllerOptions +func (cm *controllerManager) GetControllerOptions() config.Controller { + return cm.controllerConfig } -func (cm *controllerManager) serveMetrics() { +func (cm *controllerManager) addMetricsServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{ ErrorHandling: promhttp.HTTPErrorOnError, }) // TODO(JoelSpeed): Use existing Kubernetes machinery for serving metrics - mux := http.NewServeMux() mux.Handle(defaultMetricsEndpoint, handler) for path, extraHandler := range cm.metricsExtraHandlers { mux.Handle(path, extraHandler) } - server := httpserver.New(mux) - go cm.httpServe("metrics", cm.logger.WithValues("path", defaultMetricsEndpoint), server, cm.metricsListener) + return cm.add(&server{ + Kind: "metrics", + Log: cm.logger.WithValues("path", defaultMetricsEndpoint), + Server: srv, + Listener: cm.metricsListener, + }) } func (cm *controllerManager) serveHealthProbes() { @@ -355,6 +335,24 @@ func (cm *controllerManager) serveHealthProbes() { go cm.httpServe("health probe", cm.logger, server, cm.healthProbeListener) } +func (cm *controllerManager) addPprofServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + + return cm.add(&server{ + Kind: "pprof", + Log: cm.logger, + Server: srv, + Listener: cm.pprofListener, + }) +} + func (cm *controllerManager) httpServe(kind string, log logr.Logger, server *http.Server, ln net.Listener) { log = log.WithValues("kind", kind, "addr", ln.Addr()) @@ -402,6 +400,8 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) { cm.Unlock() return errors.New("manager already started") } + cm.started = true + var ready bool defer func() { // Only unlock the manager if we haven't reached @@ -442,7 +442,9 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) { // (If we don't serve metrics for non-leaders, prometheus will still scrape // the pod but will get a connection refused). if cm.metricsListener != nil { - cm.serveMetrics() + if err := cm.addMetricsServer(); err != nil { + return fmt.Errorf("failed to add metrics server: %w", err) + } } // Serve health probes. @@ -450,6 +452,13 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) { cm.serveHealthProbes() } + // Add pprof server + if cm.pprofListener != nil { + if err := cm.addPprofServer(); err != nil { + return fmt.Errorf("failed to add pprof server: %w", err) + } + } + // First start any webhook servers, which includes conversion, validation, and defaulting // webhooks that are registered. // @@ -457,22 +466,22 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) { // between conversion webhooks and the cache sync (usually initial list) which causes the webhooks // to never start because no cache can be populated. if err := cm.runnables.Webhooks.Start(cm.internalCtx); err != nil { - if !errors.Is(err, wait.ErrWaitTimeout) { - return err + if err != nil { + return fmt.Errorf("failed to start webhooks: %w", err) } } // Start and wait for caches. if err := cm.runnables.Caches.Start(cm.internalCtx); err != nil { - if !errors.Is(err, wait.ErrWaitTimeout) { - return err + if err != nil { + return fmt.Errorf("failed to start caches: %w", err) } } // Start the non-leaderelection Runnables after the cache has synced. if err := cm.runnables.Others.Start(cm.internalCtx); err != nil { - if !errors.Is(err, wait.ErrWaitTimeout) { - return err + if err != nil { + return fmt.Errorf("failed to start other runnables: %w", err) } } @@ -519,7 +528,12 @@ func (cm *controllerManager) engageStopProcedure(stopComplete <-chan struct{}) e // // The shutdown context immediately expires if the gracefulShutdownTimeout is not set. var shutdownCancel context.CancelFunc - cm.shutdownCtx, shutdownCancel = context.WithTimeout(context.Background(), cm.gracefulShutdownTimeout) + if cm.gracefulShutdownTimeout < 0 { + // We want to wait forever for the runnables to stop. + cm.shutdownCtx, shutdownCancel = context.WithCancel(context.Background()) + } else { + cm.shutdownCtx, shutdownCancel = context.WithTimeout(context.Background(), cm.gracefulShutdownTimeout) + } defer shutdownCancel() // Start draining the errors before acquiring the lock to make sure we don't deadlock @@ -633,6 +647,7 @@ func (cm *controllerManager) startLeaderElection(ctx context.Context) (err error }, }, ReleaseOnCancel: cm.leaderElectionReleaseOnCancel, + Name: cm.leaderElectionID, }) if err != nil { return err diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go index 5f76b5a8360..7e65ef0c3ac 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go @@ -18,6 +18,7 @@ package manager import ( "context" + "crypto/tls" "fmt" "net" "net/http" @@ -32,6 +33,7 @@ import ( "k8s.io/client-go/tools/leaderelection/resourcelock" "k8s.io/client-go/tools/record" "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/cluster" @@ -43,7 +45,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/metrics" "sigs.k8s.io/controller-runtime/pkg/recorder" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" "sigs.k8s.io/controller-runtime/pkg/webhook" ) @@ -54,8 +55,7 @@ type Manager interface { cluster.Cluster // Add will set requested dependencies on the component, and cause the component to be - // started when Start is called. Add will inject any dependencies for which the argument - // implements the inject interface - e.g. inject.Client. + // started when Start is called. // Depending on if a Runnable implements LeaderElectionRunnable interface, a Runnable can be run in either // non-leaderelection mode (always running) or leader election mode (managed by leader election if enabled). Add(Runnable) error @@ -87,13 +87,13 @@ type Manager interface { Start(ctx context.Context) error // GetWebhookServer returns a webhook.Server - GetWebhookServer() *webhook.Server + GetWebhookServer() webhook.Server // GetLogger returns this manager's logger. GetLogger() logr.Logger // GetControllerOptions returns controller global configuration options. - GetControllerOptions() v1alpha1.ControllerConfigurationSpec + GetControllerOptions() config.Controller } // Options are the arguments for creating a new Manager. @@ -101,10 +101,44 @@ type Options struct { // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources. // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better // to pass your own scheme in. See the documentation in pkg/scheme for more information. + // + // If set, the Scheme will be used to create the default Client and Cache. Scheme *runtime.Scheme - // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs - MapperProvider func(c *rest.Config) (meta.RESTMapper, error) + // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs. + // + // If set, the RESTMapper returned by this function is used to create the RESTMapper + // used by the Client and Cache. + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + + // NewCache is the function that will create the cache to be used + // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. + NewCache cache.NewCacheFunc + + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + + // NewClient is the func that creates the client to be used by the manager. + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc // SyncPeriod determines the minimum frequency at which watched resources are // reconciled. A lower period will correct entropy more quickly, but reduce @@ -131,6 +165,8 @@ type Options struct { // is "done" with an object, and would otherwise not requeue it, i.e., we // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, // instead of `reconcile.Result{}`. + // + // Deprecated: Use Cache.SyncPeriod instead. SyncPeriod *time.Duration // Logger is the logger that should be used by this manager. @@ -142,18 +178,36 @@ type Options struct { LeaderElection bool // LeaderElectionResourceLock determines which resource lock to use for leader election, - // defaults to "configmapsleases". Change this value only if you know what you are doing. - // Otherwise, users of your controller might end up with multiple running instances that + // defaults to "leases". Change this value only if you know what you are doing. + // + // If you are using `configmaps`/`endpoints` resource lock and want to migrate to "leases", + // you might do so by migrating to the respective multilock first ("configmapsleases" or "endpointsleases"), + // which will acquire a leader lock on both resources. + // After all your users have migrated to the multilock, you can go ahead and migrate to "leases". + // Please also keep in mind, that users might skip versions of your controller. + // + // Note: before controller-runtime version v0.7, it was set to "configmaps". + // And from v0.7 to v0.11, the default was "configmapsleases", which was + // used to migrate from configmaps to leases. + // Since the default was "configmapsleases" for over a year, spanning five minor releases, + // any actively maintained operators are very likely to have a released version that uses + // "configmapsleases". Therefore defaulting to "leases" should be safe since v0.12. + // + // So, what do you have to do when you are updating your controller-runtime dependency + // from a lower version to v0.12 or newer? + // - If your operator matches at least one of these conditions: + // - the LeaderElectionResourceLock in your operator has already been explicitly set to "leases" + // - the old controller-runtime version is between v0.7.0 and v0.11.x and the + // LeaderElectionResourceLock wasn't set or was set to "leases"/"configmapsleases"/"endpointsleases" + // feel free to update controller-runtime to v0.12 or newer. + // - Otherwise, you may have to take these steps: + // 1. update controller-runtime to v0.12 or newer in your go.mod + // 2. set LeaderElectionResourceLock to "configmapsleases" (or "endpointsleases") + // 3. package your operator and upgrade it in all your clusters + // 4. only if you have finished 3, you can remove the LeaderElectionResourceLock to use the default "leases" + // Otherwise, your operator might end up with multiple running instances that // each acquired leadership through different resource locks during upgrades and thus // act on the same resources concurrently. - // If you want to migrate to the "leases" resource lock, you might do so by migrating to the - // respective multilock first ("configmapsleases" or "endpointsleases"), which will acquire a - // leader lock on both resources. After all your users have migrated to the multilock, you can - // go ahead and migrate to "leases". Please also keep in mind, that users might skip versions - // of your controller. - // - // Note: before controller-runtime version v0.7, the resource lock was set to "configmaps". - // Please keep this in mind, when planning a proper migration path for your controller. LeaderElectionResourceLock string // LeaderElectionNamespace determines the namespace in which the leader @@ -175,6 +229,12 @@ type Options struct { // LeaseDuration time first. LeaderElectionReleaseOnCancel bool + // LeaderElectionResourceLockInterface allows to provide a custom resourcelock.Interface that was created outside + // of the controller-runtime. If this value is set the options LeaderElectionID, LeaderElectionNamespace, + // LeaderElectionResourceLock, LeaseDuration, RenewDeadline and RetryPeriod will be ignored. This can be useful if you + // want to use a locking mechanism that is currently not supported, like a MultiLock across two Kubernetes clusters. + LeaderElectionResourceLockInterface resourcelock.Interface + // LeaseDuration is the duration that non-leader candidates will // wait to force acquire leadership. This is measured against time of // last observed ack. Default is 15 seconds. @@ -192,6 +252,8 @@ type Options struct { // Note: If a namespace is specified, controllers can still Watch for a // cluster-scoped resource (e.g Node). For namespaced resources, the cache // will only hold objects from the desired namespace. + // + // Deprecated: Use Cache.Namespaces instead. Namespace string // MetricsBindAddress is the TCP address that the controller should bind to @@ -201,6 +263,7 @@ type Options struct { // HealthProbeBindAddress is the TCP address that the controller should bind to // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. HealthProbeBindAddress string // Readiness probe endpoint name, defaults to "readyz" @@ -209,11 +272,22 @@ type Options struct { // Liveness probe endpoint name, defaults to "healthz" LivenessEndpointName string + // PprofBindAddress is the TCP address that the controller should bind to + // for serving pprof. + // It can be set to "" or "0" to disable the pprof serving. + // Since pprof may contain sensitive information, make sure to protect it + // before exposing it to public. + PprofBindAddress string + // Port is the port that the webhook server serves at. // It is used to set webhook.Server.Port if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. Port int // Host is the hostname that the webhook server binds to. // It is used to set webhook.Server.Host if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. Host string // CertDir is the directory that contains the server key and certificate. @@ -221,23 +295,19 @@ type Options struct { // {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate // must be named tls.key and tls.crt, respectively. // It is used to set webhook.Server.CertDir if WebhookServer is not set. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. CertDir string + // TLSOpts is used to allow configuring the TLS config used for the webhook server. + // + // Deprecated: Use WebhookServer instead. A WebhookServer can be created via webhook.NewServer. + TLSOpts []func(*tls.Config) + // WebhookServer is an externally configured webhook.Server. By default, // a Manager will create a default server using Port, Host, and CertDir; // if this is set, the Manager will use this server instead. - WebhookServer *webhook.Server - - // Functions to allow for a user to customize values that will be injected. - - // NewCache is the function that will create the cache to be used - // by the manager. If not set this will use the default new cache function. - NewCache cache.NewCacheFunc - - // NewClient is the func that creates the client to be used by the manager. - // If not set this will create the default DelegatingClient that will - // use the cache for reads and the client for writes. - NewClient cluster.NewClientFunc + WebhookServer webhook.Server // BaseContext is the function that provides Context values to Runnables // managed by the Manager. If a BaseContext function isn't provided, Runnables @@ -246,10 +316,14 @@ type Options struct { // ClientDisableCacheFor tells the client that, if any cache is used, to bypass it // for the given objects. + // + // Deprecated: Use Client.Cache.DisableCacheFor instead. ClientDisableCacheFor []client.Object // DryRunClient specifies whether the client should be configured to enforce // dryRun mode. + // + // Deprecated: Use Client.DryRun instead. DryRunClient bool // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API @@ -268,7 +342,7 @@ type Options struct { // Controller contains global configuration options for controllers // registered within this manager. // +optional - Controller v1alpha1.ControllerConfigurationSpec + Controller config.Controller // makeBroadcaster allows deferring the creation of the broadcaster to // avoid leaking goroutines if we never call Start on this manager. It also @@ -277,10 +351,11 @@ type Options struct { makeBroadcaster intrec.EventBroadcasterProducer // Dependency injection for testing - newRecorderProvider func(config *rest.Config, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) newResourceLock func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) newMetricsListener func(addr string) (net.Listener, error) newHealthProbeListener func(addr string) (net.Listener, error) + newPprofListener func(addr string) (net.Listener, error) } // BaseContextFunc is a function used to provide a base Context to Runnables @@ -324,12 +399,14 @@ func New(config *rest.Config, options Options) (Manager, error) { clusterOptions.MapperProvider = options.MapperProvider clusterOptions.Logger = options.Logger clusterOptions.SyncPeriod = options.SyncPeriod - clusterOptions.Namespace = options.Namespace clusterOptions.NewCache = options.NewCache clusterOptions.NewClient = options.NewClient - clusterOptions.ClientDisableCacheFor = options.ClientDisableCacheFor - clusterOptions.DryRunClient = options.DryRunClient - clusterOptions.EventBroadcaster = options.EventBroadcaster //nolint:staticcheck + clusterOptions.Cache = options.Cache + clusterOptions.Client = options.Client + clusterOptions.Namespace = options.Namespace //nolint:staticcheck + clusterOptions.ClientDisableCacheFor = options.ClientDisableCacheFor //nolint:staticcheck + clusterOptions.DryRunClient = options.DryRunClient //nolint:staticcheck + clusterOptions.EventBroadcaster = options.EventBroadcaster //nolint:staticcheck }) if err != nil { return nil, err @@ -338,7 +415,7 @@ func New(config *rest.Config, options Options) (Manager, error) { // Create the recorder provider to inject event recorders for the components. // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific // to the particular controller that it's being injected into, rather than a generic one like is here. - recorderProvider, err := options.newRecorderProvider(config, cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) + recorderProvider, err := options.newRecorderProvider(config, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) if err != nil { return nil, err } @@ -352,20 +429,25 @@ func New(config *rest.Config, options Options) (Manager, error) { leaderRecorderProvider = recorderProvider } else { leaderConfig = rest.CopyConfig(options.LeaderElectionConfig) - leaderRecorderProvider, err = options.newRecorderProvider(leaderConfig, cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) + leaderRecorderProvider, err = options.newRecorderProvider(leaderConfig, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) if err != nil { return nil, err } } - resourceLock, err := options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{ - LeaderElection: options.LeaderElection, - LeaderElectionResourceLock: options.LeaderElectionResourceLock, - LeaderElectionID: options.LeaderElectionID, - LeaderElectionNamespace: options.LeaderElectionNamespace, - }) - if err != nil { - return nil, err + var resourceLock resourcelock.Interface + if options.LeaderElectionResourceLockInterface != nil && options.LeaderElection { + resourceLock = options.LeaderElectionResourceLockInterface + } else { + resourceLock, err = options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{ + LeaderElection: options.LeaderElection, + LeaderElectionResourceLock: options.LeaderElectionResourceLock, + LeaderElectionID: options.LeaderElectionID, + LeaderElectionNamespace: options.LeaderElectionNamespace, + }) + if err != nil { + return nil, err + } } // Create the metrics listener. This will throw an error if the metrics bind @@ -385,6 +467,13 @@ func New(config *rest.Config, options Options) (Manager, error) { return nil, err } + // Create pprof listener. This will throw an error if the bind + // address is invalid or already in use. + pprofListener, err := options.newPprofListener(options.PprofBindAddress) + if err != nil { + return nil, fmt.Errorf("failed to new pprof listener: %w", err) + } + errChan := make(chan error) runnables := newRunnables(options.BaseContext, errChan) @@ -397,19 +486,18 @@ func New(config *rest.Config, options Options) (Manager, error) { resourceLock: resourceLock, metricsListener: metricsListener, metricsExtraHandlers: metricsExtraHandlers, - controllerOptions: options.Controller, + controllerConfig: options.Controller, logger: options.Logger, elected: make(chan struct{}), - port: options.Port, - host: options.Host, - certDir: options.CertDir, webhookServer: options.WebhookServer, + leaderElectionID: options.LeaderElectionID, leaseDuration: *options.LeaseDuration, renewDeadline: *options.RenewDeadline, retryPeriod: *options.RetryPeriod, healthProbeListener: healthProbeListener, readinessEndpointName: options.ReadinessEndpointName, livenessEndpointName: options.LivenessEndpointName, + pprofListener: pprofListener, gracefulShutdownTimeout: *options.GracefulShutdownTimeout, internalProceduresStop: make(chan struct{}), leaderElectionStopped: make(chan struct{}), @@ -420,14 +508,14 @@ func New(config *rest.Config, options Options) (Manager, error) { // AndFrom will use a supplied type and convert to Options // any options already set on Options will be ignored, this is used to allow // cli flags to override anything specified in the config file. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, error) { - if inj, wantsScheme := loader.(inject.Scheme); wantsScheme { - err := inj.InjectScheme(o.Scheme) - if err != nil { - return o, err - } - } - newObj, err := loader.Complete() if err != nil { return o, err @@ -462,18 +550,23 @@ func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, if o.Port == 0 && newObj.Webhook.Port != nil { o.Port = *newObj.Webhook.Port } - if o.Host == "" && newObj.Webhook.Host != "" { o.Host = newObj.Webhook.Host } - if o.CertDir == "" && newObj.Webhook.CertDir != "" { o.CertDir = newObj.Webhook.CertDir } + if o.WebhookServer == nil { + o.WebhookServer = webhook.NewServer(webhook.Options{ + Port: o.Port, + Host: o.Host, + CertDir: o.CertDir, + }) + } if newObj.Controller != nil { - if o.Controller.CacheSyncTimeout == nil && newObj.Controller.CacheSyncTimeout != nil { - o.Controller.CacheSyncTimeout = newObj.Controller.CacheSyncTimeout + if o.Controller.CacheSyncTimeout == 0 && newObj.Controller.CacheSyncTimeout != nil { + o.Controller.CacheSyncTimeout = *newObj.Controller.CacheSyncTimeout } if len(o.Controller.GroupKindConcurrency) == 0 && len(newObj.Controller.GroupKindConcurrency) > 0 { @@ -485,6 +578,13 @@ func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, } // AndFromOrDie will use options.AndFrom() and will panic if there are errors. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. func (o Options) AndFromOrDie(loader config.ControllerManagerConfiguration) Options { o, err := o.AndFrom(loader) if err != nil { @@ -543,6 +643,19 @@ func defaultHealthProbeListener(addr string) (net.Listener, error) { return ln, nil } +// defaultPprofListener creates the default pprof listener bound to the given address. +func defaultPprofListener(addr string) (net.Listener, error) { + if addr == "" || addr == "0" { + return nil, nil + } + + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("error listening on %s: %w", addr, err) + } + return ln, nil +} + // defaultBaseContext is used as the BaseContext value in Options if one // has not already been set. func defaultBaseContext() context.Context { @@ -603,6 +716,10 @@ func setOptionsDefaults(options Options) Options { options.newHealthProbeListener = defaultHealthProbeListener } + if options.newPprofListener == nil { + options.newPprofListener = defaultPprofListener + } + if options.GracefulShutdownTimeout == nil { gracefulShutdownTimeout := defaultGracefulShutdownPeriod options.GracefulShutdownTimeout = &gracefulShutdownTimeout @@ -616,5 +733,14 @@ func setOptionsDefaults(options Options) Options { options.BaseContext = defaultBaseContext } + if options.WebhookServer == nil { + options.WebhookServer = webhook.NewServer(webhook.Options{ + Host: options.Host, + Port: options.Port, + CertDir: options.CertDir, + TLSOpts: options.TLSOpts, + }) + } + return options } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go index f7b91a209f6..549741e6e53 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go @@ -56,7 +56,7 @@ func (r *runnables) Add(fn Runnable) error { return r.Caches.Add(fn, func(ctx context.Context) bool { return runnable.GetCache().WaitForCacheSync(ctx) }) - case *webhook.Server: + case webhook.Server: return r.Webhooks.Add(fn, nil) case LeaderElectionRunnable: if !runnable.NeedLeaderElection() { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go new file mode 100644 index 00000000000..b6509f48f24 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "errors" + "net" + "net/http" + + "github.com/go-logr/logr" +) + +// server is a general purpose HTTP server Runnable for a manager +// to serve some internal handlers such as health probes, metrics and profiling. +type server struct { + Kind string + Log logr.Logger + Server *http.Server + Listener net.Listener +} + +func (s *server) Start(ctx context.Context) error { + log := s.Log.WithValues("kind", s.Kind, "addr", s.Listener.Addr()) + + serverShutdown := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("shutting down server") + if err := s.Server.Shutdown(context.Background()); err != nil { + log.Error(err, "error shutting down server") + } + close(serverShutdown) + }() + + log.Info("starting server") + if err := s.Server.Serve(s.Listener); err != nil && !errors.Is(err, http.ErrServerClosed) { + return err + } + + <-serverShutdown + return nil +} + +func (s *server) NeedLeaderElection() bool { + return false +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go index d32ce25348e..ff28998c44c 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go @@ -18,11 +18,8 @@ package metrics import ( "context" - "net/url" - "time" "github.com/prometheus/client_golang/prometheus" - reflectormetrics "k8s.io/client-go/tools/cache" clientmetrics "k8s.io/client-go/tools/metrics" ) @@ -30,115 +27,20 @@ import ( // that client-go registers metrics. We copy the names and formats // from Kubernetes so that we match the core controllers. -// Metrics subsystem and all of the keys used by the rest client. -const ( - RestClientSubsystem = "rest_client" - LatencyKey = "request_latency_seconds" - ResultKey = "requests_total" -) - -// Metrics subsystem and all keys used by the reflectors. -const ( - ReflectorSubsystem = "reflector" - ListsTotalKey = "lists_total" - ListsDurationKey = "list_duration_seconds" - ItemsPerListKey = "items_per_list" - WatchesTotalKey = "watches_total" - ShortWatchesTotalKey = "short_watches_total" - WatchDurationKey = "watch_duration_seconds" - ItemsPerWatchKey = "items_per_watch" - LastResourceVersionKey = "last_resource_version" -) - var ( // client metrics. - // RequestLatency reports the request latency in seconds per verb/URL. - // Deprecated: This metric is deprecated for removal in a future release: using the URL as a - // dimension results in cardinality explosion for some consumers. It was deprecated upstream - // in k8s v1.14 and hidden in v1.17 via https://github.com/kubernetes/kubernetes/pull/83836. - // It is not registered by default. To register: - // import ( - // clientmetrics "k8s.io/client-go/tools/metrics" - // clmetrics "sigs.k8s.io/controller-runtime/metrics" - // ) - // - // func init() { - // clmetrics.Registry.MustRegister(clmetrics.RequestLatency) - // clientmetrics.Register(clientmetrics.RegisterOpts{ - // RequestLatency: clmetrics.LatencyAdapter - // }) - // } - RequestLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{ - Subsystem: RestClientSubsystem, - Name: LatencyKey, - Help: "Request latency in seconds. Broken down by verb and URL.", - Buckets: prometheus.ExponentialBuckets(0.001, 2, 10), - }, []string{"verb", "url"}) - - requestResult = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: RestClientSubsystem, - Name: ResultKey, - Help: "Number of HTTP requests, partitioned by status code, method, and host.", - }, []string{"code", "method", "host"}) - - // reflector metrics. - - // TODO(directxman12): update these to be histograms once the metrics overhaul KEP - // PRs start landing. - - listsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: ReflectorSubsystem, - Name: ListsTotalKey, - Help: "Total number of API lists done by the reflectors", - }, []string{"name"}) - - listsDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: ReflectorSubsystem, - Name: ListsDurationKey, - Help: "How long an API list takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerList = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: ReflectorSubsystem, - Name: ItemsPerListKey, - Help: "How many items an API list returns to the reflectors", - }, []string{"name"}) - - watchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: ReflectorSubsystem, - Name: WatchesTotalKey, - Help: "Total number of API watches done by the reflectors", - }, []string{"name"}) - - shortWatchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Subsystem: ReflectorSubsystem, - Name: ShortWatchesTotalKey, - Help: "Total number of short API watches done by the reflectors", - }, []string{"name"}) - - watchDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: ReflectorSubsystem, - Name: WatchDurationKey, - Help: "How long an API watch takes to return and decode for the reflectors", - }, []string{"name"}) - - itemsPerWatch = prometheus.NewSummaryVec(prometheus.SummaryOpts{ - Subsystem: ReflectorSubsystem, - Name: ItemsPerWatchKey, - Help: "How many items an API watch returns to the reflectors", - }, []string{"name"}) - - lastResourceVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: ReflectorSubsystem, - Name: LastResourceVersionKey, - Help: "Last resource version seen for the reflectors", - }, []string{"name"}) + requestResult = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "rest_client_requests_total", + Help: "Number of HTTP requests, partitioned by status code, method, and host.", + }, + []string{"code", "method", "host"}, + ) ) func init() { registerClientMetrics() - registerReflectorMetrics() } // registerClientMetrics sets up the client latency metrics from client-go. @@ -152,20 +54,6 @@ func registerClientMetrics() { }) } -// registerReflectorMetrics sets up reflector (reconcile) loop metrics. -func registerReflectorMetrics() { - Registry.MustRegister(listsTotal) - Registry.MustRegister(listsDuration) - Registry.MustRegister(itemsPerList) - Registry.MustRegister(watchesTotal) - Registry.MustRegister(shortWatchesTotal) - Registry.MustRegister(watchDuration) - Registry.MustRegister(itemsPerWatch) - Registry.MustRegister(lastResourceVersion) - - reflectormetrics.SetReflectorMetricsProvider(reflectorMetricsProvider{}) -} - // this section contains adapters, implementations, and other sundry organic, artisanally // hand-crafted syntax trees required to convince client-go that it actually wants to let // someone use its metrics. @@ -174,16 +62,6 @@ func registerReflectorMetrics() { // copied (more-or-less directly) from k8s.io/kubernetes setup code // (which isn't anywhere in an easily-importable place). -// LatencyAdapter implements LatencyMetric. -type LatencyAdapter struct { - metric *prometheus.HistogramVec -} - -// Observe increments the request latency metric for the given verb/URL. -func (l *LatencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) { - l.metric.WithLabelValues(verb, u.String()).Observe(latency.Seconds()) -} - type resultAdapter struct { metric *prometheus.CounterVec } @@ -191,41 +69,3 @@ type resultAdapter struct { func (r *resultAdapter) Increment(_ context.Context, code, method, host string) { r.metric.WithLabelValues(code, method, host).Inc() } - -// Reflector metrics provider (method #2 for client-go metrics), -// copied (more-or-less directly) from k8s.io/kubernetes setup code -// (which isn't anywhere in an easily-importable place). - -type reflectorMetricsProvider struct{} - -func (reflectorMetricsProvider) NewListsMetric(name string) reflectormetrics.CounterMetric { - return listsTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewListDurationMetric(name string) reflectormetrics.SummaryMetric { - return listsDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInListMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerList.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchesMetric(name string) reflectormetrics.CounterMetric { - return watchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewShortWatchesMetric(name string) reflectormetrics.CounterMetric { - return shortWatchesTotal.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewWatchDurationMetric(name string) reflectormetrics.SummaryMetric { - return watchDuration.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewItemsInWatchMetric(name string) reflectormetrics.SummaryMetric { - return itemsPerWatch.WithLabelValues(name) -} - -func (reflectorMetricsProvider) NewLastResourceVersionMetric(name string) reflectormetrics.GaugeMetric { - return lastResourceVersion.WithLabelValues(name) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go new file mode 100644 index 00000000000..a19c099602e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go @@ -0,0 +1,40 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/tools/leaderelection" +) + +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/clientgo/leaderelection +// which registers metrics to the k8s legacy Registry. We require very +// similar functionality, but must register metrics to a different Registry. + +var ( + leaderGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "leader_election_master_status", + Help: "Gauge of if the reporting system is master of the relevant lease, 0 indicates backup, 1 indicates master. 'name' is the string used to identify the lease. Please make sure to group by name.", + }, []string{"name"}) +) + +func init() { + Registry.MustRegister(leaderGauge) + leaderelection.SetProvider(leaderelectionMetricsProvider{}) +} + +type leaderelectionMetricsProvider struct{} + +func (leaderelectionMetricsProvider) NewLeaderMetric() leaderelection.SwitchMetric { + return &switchAdapter{gauge: leaderGauge} +} + +type switchAdapter struct { + gauge *prometheus.GaugeVec +} + +func (s *switchAdapter) On(name string) { + s.gauge.WithLabelValues(name).Set(1.0) +} + +func (s *switchAdapter) Off(name string) { + s.gauge.WithLabelValues(name).Set(0.0) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go index 8ca47235dac..277b8788100 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go @@ -21,8 +21,8 @@ import ( "k8s.io/client-go/util/workqueue" ) -// This file is copied and adapted from k8s.io/kubernetes/pkg/util/workqueue/prometheus -// which registers metrics to the default prometheus Registry. We require very +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/workqueue +// which registers metrics to the k8s legacy Registry. We require very // similar functionality, but must register metrics to a different Registry. // Metrics subsystem and all keys used by the workqueue. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go index 8608e22ac6c..314635875e5 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go @@ -24,7 +24,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" logf "sigs.k8s.io/controller-runtime/pkg/internal/log" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" ) var log = logf.RuntimeLog.WithName("predicate").WithName("eventFilters") @@ -50,6 +49,7 @@ var _ Predicate = GenerationChangedPredicate{} var _ Predicate = AnnotationChangedPredicate{} var _ Predicate = or{} var _ Predicate = and{} +var _ Predicate = not{} // Funcs is a function that implements Predicate. type Funcs struct { @@ -176,9 +176,9 @@ func (GenerationChangedPredicate) Update(e event.UpdateEvent) bool { // This predicate will skip update events that have no change in the object's annotation. // It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: // -// Controller.Watch( +// Controller.Watch( // &source.Kind{Type: v1.MyCustomKind}, -// &handler.EnqueueRequestForObject{}, +// &handler.EnqueueRequestForObject{}, // predicate.Or(predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{})) // // This is mostly useful for controllers that needs to trigger both when the resource's generation is incremented @@ -207,9 +207,10 @@ func (AnnotationChangedPredicate) Update(e event.UpdateEvent) bool { // It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: // // Controller.Watch( -// &source.Kind{Type: v1.MyCustomKind}, -// &handler.EnqueueRequestForObject{}, -// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})) +// +// &source.Kind{Type: v1.MyCustomKind}, +// &handler.EnqueueRequestForObject{}, +// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})) // // This will be helpful when object's labels is carrying some extra specification information beyond object's spec, // and the controller will be triggered if any valid spec change (not only in spec, but also in labels) happens. @@ -240,15 +241,6 @@ type and struct { predicates []Predicate } -func (a and) InjectFunc(f inject.Func) error { - for _, p := range a.predicates { - if err := f(p); err != nil { - return err - } - } - return nil -} - func (a and) Create(e event.CreateEvent) bool { for _, p := range a.predicates { if !p.Create(e) { @@ -294,15 +286,6 @@ type or struct { predicates []Predicate } -func (o or) InjectFunc(f inject.Func) error { - for _, p := range o.predicates { - if err := f(p); err != nil { - return err - } - } - return nil -} - func (o or) Create(e event.CreateEvent) bool { for _, p := range o.predicates { if p.Create(e) { @@ -339,6 +322,31 @@ func (o or) Generic(e event.GenericEvent) bool { return false } +// Not returns a predicate that implements a logical NOT of the predicate passed to it. +func Not(predicate Predicate) Predicate { + return not{predicate} +} + +type not struct { + predicate Predicate +} + +func (n not) Create(e event.CreateEvent) bool { + return !n.predicate.Create(e) +} + +func (n not) Update(e event.UpdateEvent) bool { + return !n.predicate.Update(e) +} + +func (n not) Delete(e event.DeleteEvent) bool { + return !n.predicate.Delete(e) +} + +func (n not) Generic(e event.GenericEvent) bool { + return !n.predicate.Generic(e) +} + // LabelSelectorPredicate constructs a Predicate from a LabelSelector. // Only objects matching the LabelSelector will be admitted. func LabelSelectorPredicate(s metav1.LabelSelector) (Predicate, error) { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go index b044e659481..d51cfc34ab9 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go @@ -18,6 +18,7 @@ package reconcile import ( "context" + "errors" "time" "k8s.io/apimachinery/pkg/types" @@ -61,24 +62,24 @@ Deleting Kubernetes objects) or external Events (GitHub Webhooks, polling extern Example reconcile Logic: - * Read an object and all the Pods it owns. - * Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica. - * Create 4 Pods and set their OwnerReferences to the object. +* Read an object and all the Pods it owns. +* Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica. +* Create 4 Pods and set their OwnerReferences to the object. reconcile may be implemented as either a type: - type reconcile struct {} + type reconciler struct {} - func (reconcile) reconcile(controller.Request) (controller.Result, error) { + func (reconciler) Reconcile(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { // Implement business logic of reading and writing objects here - return controller.Result{}, nil + return reconcile.Result{}, nil } Or as a function: - controller.Func(func(o controller.Request) (controller.Result, error) { + reconcile.Func(func(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { // Implement business logic of reading and writing objects here - return controller.Result{}, nil + return reconcile.Result{}, nil }) Reconciliation is level-based, meaning action isn't driven off changes in individual Events, but instead is @@ -100,3 +101,26 @@ var _ Reconciler = Func(nil) // Reconcile implements Reconciler. func (r Func) Reconcile(ctx context.Context, o Request) (Result, error) { return r(ctx, o) } + +// TerminalError is an error that will not be retried but still be logged +// and recorded in metrics. +func TerminalError(wrapped error) error { + return &terminalError{err: wrapped} +} + +type terminalError struct { + err error +} + +func (te *terminalError) Unwrap() error { + return te.err +} + +func (te *terminalError) Error() string { + return "terminal error: " + te.err.Error() +} + +func (te *terminalError) Is(target error) bool { + tp := &terminalError{} + return errors.As(target, &tp) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/doc.go deleted file mode 100644 index 17c60895f07..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package inject defines interfaces and functions for propagating dependencies from a ControllerManager to -the components registered with it. Dependencies are propagated to Reconciler, Source, EventHandler and Predicate -objects which implement the Injectable interfaces. -*/ -package inject diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/inject.go b/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/inject.go deleted file mode 100644 index c8c56ba817b..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/runtime/inject/inject.go +++ /dev/null @@ -1,164 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package inject is used by a Manager to inject types into Sources, EventHandlers, Predicates, and Reconciles. -// Deprecated: Use manager.Options fields directly. This package will be removed in v0.10. -package inject - -import ( - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// Cache is used by the ControllerManager to inject Cache into Sources, EventHandlers, Predicates, and -// Reconciles. -type Cache interface { - InjectCache(cache cache.Cache) error -} - -// CacheInto will set informers on i and return the result if it implements Cache. Returns -// false if i does not implement Cache. -func CacheInto(c cache.Cache, i interface{}) (bool, error) { - if s, ok := i.(Cache); ok { - return true, s.InjectCache(c) - } - return false, nil -} - -// APIReader is used by the Manager to inject the APIReader into necessary types. -type APIReader interface { - InjectAPIReader(client.Reader) error -} - -// APIReaderInto will set APIReader on i and return the result if it implements APIReaderInto. -// Returns false if i does not implement APIReader. -func APIReaderInto(reader client.Reader, i interface{}) (bool, error) { - if s, ok := i.(APIReader); ok { - return true, s.InjectAPIReader(reader) - } - return false, nil -} - -// Config is used by the ControllerManager to inject Config into Sources, EventHandlers, Predicates, and -// Reconciles. -type Config interface { - InjectConfig(*rest.Config) error -} - -// ConfigInto will set config on i and return the result if it implements Config. Returns -// false if i does not implement Config. -func ConfigInto(config *rest.Config, i interface{}) (bool, error) { - if s, ok := i.(Config); ok { - return true, s.InjectConfig(config) - } - return false, nil -} - -// Client is used by the ControllerManager to inject client into Sources, EventHandlers, Predicates, and -// Reconciles. -type Client interface { - InjectClient(client.Client) error -} - -// ClientInto will set client on i and return the result if it implements Client. Returns -// false if i does not implement Client. -func ClientInto(client client.Client, i interface{}) (bool, error) { - if s, ok := i.(Client); ok { - return true, s.InjectClient(client) - } - return false, nil -} - -// Scheme is used by the ControllerManager to inject Scheme into Sources, EventHandlers, Predicates, and -// Reconciles. -type Scheme interface { - InjectScheme(scheme *runtime.Scheme) error -} - -// SchemeInto will set scheme and return the result on i if it implements Scheme. Returns -// false if i does not implement Scheme. -func SchemeInto(scheme *runtime.Scheme, i interface{}) (bool, error) { - if is, ok := i.(Scheme); ok { - return true, is.InjectScheme(scheme) - } - return false, nil -} - -// Stoppable is used by the ControllerManager to inject stop channel into Sources, -// EventHandlers, Predicates, and Reconciles. -type Stoppable interface { - InjectStopChannel(<-chan struct{}) error -} - -// StopChannelInto will set stop channel on i and return the result if it implements Stoppable. -// Returns false if i does not implement Stoppable. -func StopChannelInto(stop <-chan struct{}, i interface{}) (bool, error) { - if s, ok := i.(Stoppable); ok { - return true, s.InjectStopChannel(stop) - } - return false, nil -} - -// Mapper is used to inject the rest mapper to components that may need it. -type Mapper interface { - InjectMapper(meta.RESTMapper) error -} - -// MapperInto will set the rest mapper on i and return the result if it implements Mapper. -// Returns false if i does not implement Mapper. -func MapperInto(mapper meta.RESTMapper, i interface{}) (bool, error) { - if m, ok := i.(Mapper); ok { - return true, m.InjectMapper(mapper) - } - return false, nil -} - -// Func injects dependencies into i. -type Func func(i interface{}) error - -// Injector is used by the ControllerManager to inject Func into Controllers. -type Injector interface { - InjectFunc(f Func) error -} - -// InjectorInto will set f and return the result on i if it implements Injector. Returns -// false if i does not implement Injector. -func InjectorInto(f Func, i interface{}) (bool, error) { - if ii, ok := i.(Injector); ok { - return true, ii.InjectFunc(f) - } - return false, nil -} - -// Logger is used to inject Loggers into components that need them -// and don't otherwise have opinions. -type Logger interface { - InjectLogger(l logr.Logger) error -} - -// LoggerInto will set the logger on the given object if it implements inject.Logger, -// returning true if a InjectLogger was called, and false otherwise. -func LoggerInto(l logr.Logger, i interface{}) (bool, error) { - if injectable, wantsLogger := i.(Logger); wantsLogger { - return true, injectable.InjectLogger(l) - } - return false, nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go index 9dc93a9b213..55ebe217735 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go @@ -21,37 +21,36 @@ limitations under the License. // Each API group should define a utility function // called AddToScheme for adding its types to a Scheme: // -// // in package myapigroupv1... -// var ( -// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"} -// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} -// AddToScheme = SchemeBuilder.AddToScheme -// ) +// // in package myapigroupv1... +// var ( +// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"} +// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} +// AddToScheme = SchemeBuilder.AddToScheme +// ) // -// func init() { -// SchemeBuilder.Register(&MyType{}, &MyTypeList) -// } -// var ( -// scheme *runtime.Scheme = runtime.NewScheme() -// ) +// func init() { +// SchemeBuilder.Register(&MyType{}, &MyTypeList) +// } +// var ( +// scheme *runtime.Scheme = runtime.NewScheme() +// ) // // This also true of the built-in Kubernetes types. Then, in the entrypoint for // your manager, assemble the scheme containing exactly the types you need, // panicing if scheme registration failed. For instance, if our controller needs // types from the core/v1 API group (e.g. Pod), plus types from my.api.group/v1: // -// func init() { -// utilruntime.Must(myapigroupv1.AddToScheme(scheme)) -// utilruntime.Must(kubernetesscheme.AddToScheme(scheme)) -// } -// -// func main() { -// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{ -// Scheme: scheme, -// }) -// // ... -// } +// func init() { +// utilruntime.Must(myapigroupv1.AddToScheme(scheme)) +// utilruntime.Must(kubernetesscheme.AddToScheme(scheme)) +// } // +// func main() { +// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{ +// Scheme: scheme, +// }) +// // ... +// } package scheme import ( diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/source/internal/eventsource.go b/vendor/sigs.k8s.io/controller-runtime/pkg/source/internal/eventsource.go deleted file mode 100644 index f0cfe212ed2..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/source/internal/eventsource.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import ( - "fmt" - - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - logf "sigs.k8s.io/controller-runtime/pkg/internal/log" - - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -var log = logf.RuntimeLog.WithName("source").WithName("EventHandler") - -var _ cache.ResourceEventHandler = EventHandler{} - -// EventHandler adapts a handler.EventHandler interface to a cache.ResourceEventHandler interface. -type EventHandler struct { - EventHandler handler.EventHandler - Queue workqueue.RateLimitingInterface - Predicates []predicate.Predicate -} - -// OnAdd creates CreateEvent and calls Create on EventHandler. -func (e EventHandler) OnAdd(obj interface{}) { - c := event.CreateEvent{} - - // Pull Object out of the object - if o, ok := obj.(client.Object); ok { - c.Object = o - } else { - log.Error(nil, "OnAdd missing Object", - "object", obj, "type", fmt.Sprintf("%T", obj)) - return - } - - for _, p := range e.Predicates { - if !p.Create(c) { - return - } - } - - // Invoke create handler - e.EventHandler.Create(c, e.Queue) -} - -// OnUpdate creates UpdateEvent and calls Update on EventHandler. -func (e EventHandler) OnUpdate(oldObj, newObj interface{}) { - u := event.UpdateEvent{} - - if o, ok := oldObj.(client.Object); ok { - u.ObjectOld = o - } else { - log.Error(nil, "OnUpdate missing ObjectOld", - "object", oldObj, "type", fmt.Sprintf("%T", oldObj)) - return - } - - // Pull Object out of the object - if o, ok := newObj.(client.Object); ok { - u.ObjectNew = o - } else { - log.Error(nil, "OnUpdate missing ObjectNew", - "object", newObj, "type", fmt.Sprintf("%T", newObj)) - return - } - - for _, p := range e.Predicates { - if !p.Update(u) { - return - } - } - - // Invoke update handler - e.EventHandler.Update(u, e.Queue) -} - -// OnDelete creates DeleteEvent and calls Delete on EventHandler. -func (e EventHandler) OnDelete(obj interface{}) { - d := event.DeleteEvent{} - - // Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a - // DeleteFinalStateUnknown struct, so the object needs to be pulled out. - // Copied from sample-controller - // This should never happen if we aren't missing events, which we have concluded that we are not - // and made decisions off of this belief. Maybe this shouldn't be here? - var ok bool - if _, ok = obj.(client.Object); !ok { - // If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown - tombstone, ok := obj.(cache.DeletedFinalStateUnknown) - if !ok { - log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown", - "type", fmt.Sprintf("%T", obj), - "object", obj) - return - } - - // Set obj to the tombstone obj - obj = tombstone.Obj - } - - // Pull Object out of the object - if o, ok := obj.(client.Object); ok { - d.Object = o - } else { - log.Error(nil, "OnDelete missing Object", - "object", obj, "type", fmt.Sprintf("%T", obj)) - return - } - - for _, p := range e.Predicates { - if !p.Delete(d) { - return - } - } - - // Invoke delete handler - e.EventHandler.Delete(d, e.Queue) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go b/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go index 241c582eff2..099c8d68fa4 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go @@ -18,28 +18,19 @@ package source import ( "context" - "errors" "fmt" "sync" - "time" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" - logf "sigs.k8s.io/controller-runtime/pkg/internal/log" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" - "sigs.k8s.io/controller-runtime/pkg/source/internal" + internal "sigs.k8s.io/controller-runtime/pkg/internal/source" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/predicate" ) -var log = logf.RuntimeLog.WithName("source") - const ( // defaultBufferSize is the default number of event notifications that can be buffered. defaultBufferSize = 1024 @@ -52,8 +43,7 @@ const ( // // * Use Channel for events originating outside the cluster (eh.g. GitHub Webhook callback, Polling external urls). // -// Users may build their own Source implementations. If their implementations implement any of the inject package -// interfaces, the dependencies will be injected by the Controller when Watch is called. +// Users may build their own Source implementations. type Source interface { // Start is internal and should be called only by the Controller to register an EventHandler with the Informer // to enqueue reconcile.Requests. @@ -67,136 +57,9 @@ type SyncingSource interface { WaitForSync(ctx context.Context) error } -// NewKindWithCache creates a Source without InjectCache, so that it is assured that the given cache is used -// and not overwritten. It can be used to watch objects in a different cluster by passing the cache -// from that other cluster. -func NewKindWithCache(object client.Object, cache cache.Cache) SyncingSource { - return &kindWithCache{kind: Kind{Type: object, cache: cache}} -} - -type kindWithCache struct { - kind Kind -} - -func (ks *kindWithCache) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, - prct ...predicate.Predicate) error { - return ks.kind.Start(ctx, handler, queue, prct...) -} - -func (ks *kindWithCache) WaitForSync(ctx context.Context) error { - return ks.kind.WaitForSync(ctx) -} - -// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). -type Kind struct { - // Type is the type of object to watch. e.g. &v1.Pod{} - Type client.Object - - // cache used to watch APIs - cache cache.Cache - - // started may contain an error if one was encountered during startup. If its closed and does not - // contain an error, startup and syncing finished. - started chan error - startCancel func() -} - -var _ SyncingSource = &Kind{} - -// Start is internal and should be called only by the Controller to register an EventHandler with the Informer -// to enqueue reconcile.Requests. -func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, - prct ...predicate.Predicate) error { - // Type should have been specified by the user. - if ks.Type == nil { - return fmt.Errorf("must specify Kind.Type") - } - - // cache should have been injected before Start was called - if ks.cache == nil { - return fmt.Errorf("must call CacheInto on Kind before calling Start") - } - - // cache.GetInformer will block until its context is cancelled if the cache was already started and it can not - // sync that informer (most commonly due to RBAC issues). - ctx, ks.startCancel = context.WithCancel(ctx) - ks.started = make(chan error) - go func() { - var ( - i cache.Informer - lastErr error - ) - - // Tries to get an informer until it returns true, - // an error or the specified context is cancelled or expired. - if err := wait.PollImmediateUntilWithContext(ctx, 10*time.Second, func(ctx context.Context) (bool, error) { - // Lookup the Informer from the Cache and add an EventHandler which populates the Queue - i, lastErr = ks.cache.GetInformer(ctx, ks.Type) - if lastErr != nil { - kindMatchErr := &meta.NoKindMatchError{} - switch { - case errors.As(lastErr, &kindMatchErr): - log.Error(lastErr, "if kind is a CRD, it should be installed before calling Start", - "kind", kindMatchErr.GroupKind) - case runtime.IsNotRegisteredError(lastErr): - log.Error(lastErr, "kind must be registered to the Scheme") - default: - log.Error(lastErr, "failed to get informer from cache") - } - return false, nil // Retry. - } - return true, nil - }); err != nil { - if lastErr != nil { - ks.started <- fmt.Errorf("failed to get informer from cache: %w", lastErr) - return - } - ks.started <- err - return - } - - i.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct}) - if !ks.cache.WaitForCacheSync(ctx) { - // Would be great to return something more informative here - ks.started <- errors.New("cache did not sync") - } - close(ks.started) - }() - - return nil -} - -func (ks *Kind) String() string { - if ks.Type != nil { - return fmt.Sprintf("kind source: %T", ks.Type) - } - return "kind source: unknown type" -} - -// WaitForSync implements SyncingSource to allow controllers to wait with starting -// workers until the cache is synced. -func (ks *Kind) WaitForSync(ctx context.Context) error { - select { - case err := <-ks.started: - return err - case <-ctx.Done(): - ks.startCancel() - if errors.Is(ctx.Err(), context.Canceled) { - return nil - } - return errors.New("timed out waiting for cache to be synced") - } -} - -var _ inject.Cache = &Kind{} - -// InjectCache is internal should be called only by the Controller. InjectCache is used to inject -// the Cache dependency initialized by the ControllerManager. -func (ks *Kind) InjectCache(c cache.Cache) error { - if ks.cache == nil { - ks.cache = c - } - return nil +// Kind creates a KindSource with the given cache provider. +func Kind(cache cache.Cache, object client.Object) SyncingSource { + return &internal.Kind{Type: object, Cache: cache} } var _ Source = &Channel{} @@ -211,9 +74,6 @@ type Channel struct { // Source is the source channel to fetch GenericEvents Source <-chan event.GenericEvent - // stop is to end ongoing goroutine, and close the channels - stop <-chan struct{} - // dest is the destination channels of the added event handlers dest []chan event.GenericEvent @@ -229,18 +89,6 @@ func (cs *Channel) String() string { return fmt.Sprintf("channel source: %p", cs) } -var _ inject.Stoppable = &Channel{} - -// InjectStopChannel is internal should be called only by the Controller. -// It is used to inject the stop channel initialized by the ControllerManager. -func (cs *Channel) InjectStopChannel(stop <-chan struct{}) error { - if cs.stop == nil { - cs.stop = stop - } - - return nil -} - // Start implements Source and should only be called by the Controller. func (cs *Channel) Start( ctx context.Context, @@ -252,11 +100,6 @@ func (cs *Channel) Start( return fmt.Errorf("must specify Channel.Source") } - // stop should have been injected before Start was called - if cs.stop == nil { - return fmt.Errorf("must call InjectStop on Channel before calling Start") - } - // use default value if DestBufferSize not specified if cs.DestBufferSize == 0 { cs.DestBufferSize = defaultBufferSize @@ -284,7 +127,11 @@ func (cs *Channel) Start( } if shouldHandle { - handler.Generic(evt, queue) + func() { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + handler.Generic(ctx, evt, queue) + }() } } }() @@ -351,7 +198,10 @@ func (is *Informer) Start(ctx context.Context, handler handler.EventHandler, que return fmt.Errorf("must specify Informer.Informer") } - is.Informer.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct}) + _, err := is.Informer.AddEventHandler(internal.NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + return err + } return nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go index c7cb71b755d..f14f130f7bd 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go @@ -19,7 +19,6 @@ package admission import ( "fmt" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/json" @@ -32,8 +31,11 @@ type Decoder struct { } // NewDecoder creates a Decoder given the runtime.Scheme. -func NewDecoder(scheme *runtime.Scheme) (*Decoder, error) { - return &Decoder{codecs: serializer.NewCodecFactory(scheme)}, nil +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} } // Decode decodes the inlined object in the AdmissionRequest into the passed-in runtime.Object. @@ -62,9 +64,13 @@ func (d *Decoder) DecodeRaw(rawObj runtime.RawExtension, into runtime.Object) er if len(rawObj.Raw) == 0 { return fmt.Errorf("there is no content to decode") } - if unstructuredInto, isUnstructured := into.(*unstructured.Unstructured); isUnstructured { + if unstructuredInto, isUnstructured := into.(runtime.Unstructured); isUnstructured { // unmarshal into unstructured's underlying object to avoid calling the decoder - return json.Unmarshal(rawObj.Raw, &unstructuredInto.Object) + var object map[string]interface{} + if err := json.Unmarshal(rawObj.Raw, &object); err != nil { + return err + } + unstructuredInto.SetUnstructuredContent(object) } deserializer := d.codecs.UniversalDeserializer() diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go index 0d9aa7a838a..a3b72071687 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go @@ -21,6 +21,8 @@ import ( "encoding/json" "net/http" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -31,9 +33,9 @@ type Defaulter interface { } // DefaultingWebhookFor creates a new Webhook for Defaulting the provided type. -func DefaultingWebhookFor(defaulter Defaulter) *Webhook { +func DefaultingWebhookFor(scheme *runtime.Scheme, defaulter Defaulter) *Webhook { return &Webhook{ - Handler: &mutatingHandler{defaulter: defaulter}, + Handler: &mutatingHandler{defaulter: defaulter, decoder: NewDecoder(scheme)}, } } @@ -42,20 +44,26 @@ type mutatingHandler struct { decoder *Decoder } -var _ DecoderInjector = &mutatingHandler{} - -// InjectDecoder injects the decoder into a mutatingHandler. -func (h *mutatingHandler) InjectDecoder(d *Decoder) error { - h.decoder = d - return nil -} - // Handle handles admission requests. func (h *mutatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } if h.defaulter == nil { panic("defaulter should never be nil") } + // always skip when a DELETE operation received in mutation handler + // describe in https://github.com/kubernetes-sigs/controller-runtime/issues/1762 + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + // Get the object in the request obj := h.defaulter.DeepCopyObject().(Defaulter) if err := h.decoder.Decode(req, obj); err != nil { diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go index d65727e62cf..5f697e7dce7 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go @@ -22,7 +22,9 @@ import ( "errors" "net/http" + admissionv1 "k8s.io/api/admission/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -32,9 +34,9 @@ type CustomDefaulter interface { } // WithCustomDefaulter creates a new Webhook for a CustomDefaulter interface. -func WithCustomDefaulter(obj runtime.Object, defaulter CustomDefaulter) *Webhook { +func WithCustomDefaulter(scheme *runtime.Scheme, obj runtime.Object, defaulter CustomDefaulter) *Webhook { return &Webhook{ - Handler: &defaulterForType{object: obj, defaulter: defaulter}, + Handler: &defaulterForType{object: obj, defaulter: defaulter, decoder: NewDecoder(scheme)}, } } @@ -44,15 +46,11 @@ type defaulterForType struct { decoder *Decoder } -var _ DecoderInjector = &defaulterForType{} - -func (h *defaulterForType) InjectDecoder(d *Decoder) error { - h.decoder = d - return nil -} - // Handle handles admission requests. func (h *defaulterForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } if h.defaulter == nil { panic("defaulter should never be nil") } @@ -60,6 +58,16 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response { panic("object should never be nil") } + // Always skip when a DELETE operation received in custom mutation handler. + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + ctx = NewContextWithRequest(ctx, req) // Get the object in the request diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go index 0b274dd02b4..8dc0cbec6f7 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go @@ -20,9 +20,3 @@ Package admission provides implementation for admission webhook and methods to i See examples/mutatingwebhook.go and examples/validatingwebhook.go for examples of admission webhooks. */ package admission - -import ( - logf "sigs.k8s.io/controller-runtime/pkg/internal/log" -) - -var log = logf.RuntimeLog.WithName("admission") diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go index 066cc422564..84ab5e75a4e 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go @@ -52,7 +52,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { var reviewResponse Response if r.Body == nil { err = errors.New("request body is empty") - wh.log.Error(err, "bad request") + wh.getLogger(nil).Error(err, "bad request") reviewResponse = Errored(http.StatusBadRequest, err) wh.writeResponse(w, reviewResponse) return @@ -60,7 +60,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() if body, err = io.ReadAll(r.Body); err != nil { - wh.log.Error(err, "unable to read the body from the incoming request") + wh.getLogger(nil).Error(err, "unable to read the body from the incoming request") reviewResponse = Errored(http.StatusBadRequest, err) wh.writeResponse(w, reviewResponse) return @@ -69,7 +69,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { // verify the content type is accurate if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { err = fmt.Errorf("contentType=%s, expected application/json", contentType) - wh.log.Error(err, "unable to process a request with an unknown content type", "content type", contentType) + wh.getLogger(nil).Error(err, "unable to process a request with unknown content type") reviewResponse = Errored(http.StatusBadRequest, err) wh.writeResponse(w, reviewResponse) return @@ -88,12 +88,12 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { ar.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("AdmissionReview")) _, actualAdmRevGVK, err := admissionCodecs.UniversalDeserializer().Decode(body, nil, &ar) if err != nil { - wh.log.Error(err, "unable to decode the request") + wh.getLogger(nil).Error(err, "unable to decode the request") reviewResponse = Errored(http.StatusBadRequest, err) wh.writeResponse(w, reviewResponse) return } - wh.log.V(1).Info("received request", "UID", req.UID, "kind", req.Kind, "resource", req.Resource) + wh.getLogger(&req).V(4).Info("received request") reviewResponse = wh.Handle(ctx, req) wh.writeResponseTyped(w, reviewResponse, actualAdmRevGVK) @@ -124,7 +124,7 @@ func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, admRevGVK // writeAdmissionResponse writes ar to w. func (wh *Webhook) writeAdmissionResponse(w io.Writer, ar v1.AdmissionReview) { if err := json.NewEncoder(w).Encode(ar); err != nil { - wh.log.Error(err, "unable to encode and write the response") + wh.getLogger(nil).Error(err, "unable to encode and write the response") // Since the `ar v1.AdmissionReview` is a clear and legal object, // it should not have problem to be marshalled into bytes. // The error here is probably caused by the abnormal HTTP connection, @@ -132,15 +132,15 @@ func (wh *Webhook) writeAdmissionResponse(w io.Writer, ar v1.AdmissionReview) { // to avoid endless circular calling. serverError := Errored(http.StatusInternalServerError, err) if err = json.NewEncoder(w).Encode(v1.AdmissionReview{Response: &serverError.AdmissionResponse}); err != nil { - wh.log.Error(err, "still unable to encode and write the InternalServerError response") + wh.getLogger(nil).Error(err, "still unable to encode and write the InternalServerError response") } } else { res := ar.Response - if log := wh.log; log.V(1).Enabled() { + if log := wh.getLogger(nil); log.V(4).Enabled() { if res.Result != nil { - log = log.WithValues("code", res.Result.Code, "reason", res.Result.Reason) + log = log.WithValues("code", res.Result.Code, "reason", res.Result.Reason, "message", res.Result.Message) } - log.V(1).Info("wrote response", "UID", res.UID, "allowed", res.Allowed) + log.V(4).Info("wrote response", "requestID", res.UID, "allowed", res.Allowed) } } } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/inject.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/inject.go deleted file mode 100644 index d5af0d598f0..00000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/inject.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package admission - -// DecoderInjector is used by the ControllerManager to inject decoder into webhook handlers. -type DecoderInjector interface { - InjectDecoder(*Decoder) error -} - -// InjectDecoderInto will set decoder on i and return the result if it implements Decoder. Returns -// false if i does not implement Decoder. -func InjectDecoderInto(decoder *Decoder, i interface{}) (bool, error) { - if s, ok := i.(DecoderInjector); ok { - return true, s.InjectDecoder(decoder) - } - return false, nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go index 26900cf2ebb..2f7820d04b4 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go @@ -25,8 +25,6 @@ import ( jsonpatch "gomodules.xyz/jsonpatch/v2" admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" ) type multiMutating []Handler @@ -62,31 +60,6 @@ func (hs multiMutating) Handle(ctx context.Context, req Request) Response { } } -// InjectFunc injects the field setter into the handlers. -func (hs multiMutating) InjectFunc(f inject.Func) error { - // inject directly into the handlers. It would be more correct - // to do this in a sync.Once in Handle (since we don't have some - // other start/finalize-type method), but it's more efficient to - // do it here, presumably. - for _, handler := range hs { - if err := f(handler); err != nil { - return err - } - } - - return nil -} - -// InjectDecoder injects the decoder into the handlers. -func (hs multiMutating) InjectDecoder(d *Decoder) error { - for _, handler := range hs { - if _, err := InjectDecoderInto(d, handler); err != nil { - return err - } - } - return nil -} - // MultiMutatingHandler combines multiple mutating webhook handlers into a single // mutating webhook handler. Handlers are called in sequential order, and the first // `allowed: false` response may short-circuit the rest. Users must take care to @@ -120,28 +93,3 @@ func (hs multiValidating) Handle(ctx context.Context, req Request) Response { func MultiValidatingHandler(handlers ...Handler) Handler { return multiValidating(handlers) } - -// InjectFunc injects the field setter into the handlers. -func (hs multiValidating) InjectFunc(f inject.Func) error { - // inject directly into the handlers. It would be more correct - // to do this in a sync.Once in Handle (since we don't have some - // other start/finalize-type method), but it's more efficient to - // do it here, presumably. - for _, handler := range hs { - if err := f(handler); err != nil { - return err - } - } - - return nil -} - -// InjectDecoder injects the decoder into the handlers. -func (hs multiValidating) InjectDecoder(d *Decoder) error { - for _, handler := range hs { - if _, err := InjectDecoderInto(d, handler); err != nil { - return err - } - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go index 24ff1dee3c4..ec1c88c989b 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go @@ -26,21 +26,21 @@ import ( // Allowed constructs a response indicating that the given operation // is allowed (without any patches). -func Allowed(reason string) Response { - return ValidationResponse(true, reason) +func Allowed(message string) Response { + return ValidationResponse(true, message) } // Denied constructs a response indicating that the given operation // is not allowed. -func Denied(reason string) Response { - return ValidationResponse(false, reason) +func Denied(message string) Response { + return ValidationResponse(false, message) } // Patched constructs a response indicating that the given operation is // allowed, and that the target object should be modified by the given // JSONPatch operations. -func Patched(reason string, patches ...jsonpatch.JsonPatchOperation) Response { - resp := Allowed(reason) +func Patched(message string, patches ...jsonpatch.JsonPatchOperation) Response { + resp := Allowed(message) resp.Patches = patches return resp @@ -60,21 +60,24 @@ func Errored(code int32, err error) Response { } // ValidationResponse returns a response for admitting a request. -func ValidationResponse(allowed bool, reason string) Response { +func ValidationResponse(allowed bool, message string) Response { code := http.StatusForbidden + reason := metav1.StatusReasonForbidden if allowed { code = http.StatusOK + reason = "" } resp := Response{ AdmissionResponse: admissionv1.AdmissionResponse{ Allowed: allowed, Result: &metav1.Status{ - Code: int32(code), + Code: int32(code), + Reason: reason, }, }, } - if len(reason) > 0 { - resp.Result.Reason = metav1.StatusReason(reason) + if len(message) > 0 { + resp.Result.Message = message } return resp } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go index 4b27e75ede6..00bda8a4ce5 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go @@ -18,7 +18,8 @@ package admission import ( "context" - goerrors "errors" + "errors" + "fmt" "net/http" v1 "k8s.io/api/admission/v1" @@ -26,18 +27,35 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// Warnings represents warning messages. +type Warnings []string + // Validator defines functions for validating an operation. +// The custom resource kind which implements this interface can validate itself. +// To validate the custom resource with another specific struct, use CustomValidator instead. type Validator interface { runtime.Object - ValidateCreate() error - ValidateUpdate(old runtime.Object) error - ValidateDelete() error + + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate() (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. The oldObj is the object before the update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(old runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete() (warnings Warnings, err error) } // ValidatingWebhookFor creates a new Webhook for validating the provided type. -func ValidatingWebhookFor(validator Validator) *Webhook { +func ValidatingWebhookFor(scheme *runtime.Scheme, validator Validator) *Webhook { return &Webhook{ - Handler: &validatingHandler{validator: validator}, + Handler: &validatingHandler{validator: validator, decoder: NewDecoder(scheme)}, } } @@ -46,42 +64,34 @@ type validatingHandler struct { decoder *Decoder } -var _ DecoderInjector = &validatingHandler{} - -// InjectDecoder injects the decoder into a validatingHandler. -func (h *validatingHandler) InjectDecoder(d *Decoder) error { - h.decoder = d - return nil -} - // Handle handles admission requests. func (h *validatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } if h.validator == nil { panic("validator should never be nil") } - // Get the object in the request obj := h.validator.DeepCopyObject().(Validator) - if req.Operation == v1.Create { - err := h.decoder.Decode(req, obj) - if err != nil { - return Errored(http.StatusBadRequest, err) - } - err = obj.ValidateCreate() - if err != nil { - var apiStatus apierrors.APIStatus - if goerrors.As(err, &apiStatus) { - return validationResponseFromStatus(false, apiStatus.Status()) - } - return Denied(err.Error()) + var err error + var warnings []string + + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? + case v1.Create: + if err = h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) } - } - if req.Operation == v1.Update { + warnings, err = obj.ValidateCreate() + case v1.Update: oldObj := obj.DeepCopyObject() - err := h.decoder.DecodeRaw(req.Object, obj) + err = h.decoder.DecodeRaw(req.Object, obj) if err != nil { return Errored(http.StatusBadRequest, err) } @@ -90,33 +100,26 @@ func (h *validatingHandler) Handle(ctx context.Context, req Request) Response { return Errored(http.StatusBadRequest, err) } - err = obj.ValidateUpdate(oldObj) - if err != nil { - var apiStatus apierrors.APIStatus - if goerrors.As(err, &apiStatus) { - return validationResponseFromStatus(false, apiStatus.Status()) - } - return Denied(err.Error()) - } - } - - if req.Operation == v1.Delete { + warnings, err = obj.ValidateUpdate(oldObj) + case v1.Delete: // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 // OldObject contains the object being deleted - err := h.decoder.DecodeRaw(req.OldObject, obj) + err = h.decoder.DecodeRaw(req.OldObject, obj) if err != nil { return Errored(http.StatusBadRequest, err) } - err = obj.ValidateDelete() - if err != nil { - var apiStatus apierrors.APIStatus - if goerrors.As(err, &apiStatus) { - return validationResponseFromStatus(false, apiStatus.Status()) - } - return Denied(err.Error()) - } + warnings, err = obj.ValidateDelete() + default: + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) } - return Allowed("") + if err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) + } + return Denied(err.Error()).WithWarnings(warnings...) + } + return Allowed("").WithWarnings(warnings...) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go index 33252f11342..e99fbd8a857 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go @@ -28,16 +28,29 @@ import ( ) // CustomValidator defines functions for validating an operation. +// The object to be validated is passed into methods as a parameter. type CustomValidator interface { - ValidateCreate(ctx context.Context, obj runtime.Object) error - ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) error - ValidateDelete(ctx context.Context, obj runtime.Object) error + + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) } // WithCustomValidator creates a new Webhook for validating the provided type. -func WithCustomValidator(obj runtime.Object, validator CustomValidator) *Webhook { +func WithCustomValidator(scheme *runtime.Scheme, obj runtime.Object, validator CustomValidator) *Webhook { return &Webhook{ - Handler: &validatorForType{object: obj, validator: validator}, + Handler: &validatorForType{object: obj, validator: validator, decoder: NewDecoder(scheme)}, } } @@ -47,16 +60,11 @@ type validatorForType struct { decoder *Decoder } -var _ DecoderInjector = &validatorForType{} - -// InjectDecoder injects the decoder into a validatingHandler. -func (h *validatorForType) InjectDecoder(d *Decoder) error { - h.decoder = d - return nil -} - // Handle handles admission requests. func (h *validatorForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } if h.validator == nil { panic("validator should never be nil") } @@ -70,13 +78,18 @@ func (h *validatorForType) Handle(ctx context.Context, req Request) Response { obj := h.object.DeepCopyObject() var err error + var warnings []string + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? case v1.Create: if err := h.decoder.Decode(req, obj); err != nil { return Errored(http.StatusBadRequest, err) } - err = h.validator.ValidateCreate(ctx, obj) + warnings, err = h.validator.ValidateCreate(ctx, obj) case v1.Update: oldObj := obj.DeepCopyObject() if err := h.decoder.DecodeRaw(req.Object, obj); err != nil { @@ -86,7 +99,7 @@ func (h *validatorForType) Handle(ctx context.Context, req Request) Response { return Errored(http.StatusBadRequest, err) } - err = h.validator.ValidateUpdate(ctx, oldObj, obj) + warnings, err = h.validator.ValidateUpdate(ctx, oldObj, obj) case v1.Delete: // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 // OldObject contains the object being deleted @@ -94,20 +107,20 @@ func (h *validatorForType) Handle(ctx context.Context, req Request) Response { return Errored(http.StatusBadRequest, err) } - err = h.validator.ValidateDelete(ctx, obj) + warnings, err = h.validator.ValidateDelete(ctx, obj) default: - return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation request %q", req.Operation)) + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) } // Check the error message first. if err != nil { var apiStatus apierrors.APIStatus if errors.As(err, &apiStatus) { - return validationResponseFromStatus(false, apiStatus.Status()) + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) } - return Denied(err.Error()) + return Denied(err.Error()).WithWarnings(warnings...) } // Return allowed if everything succeeded. - return Allowed("") + return Allowed("").WithWarnings(warnings...) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go index cfc46637c33..f1767f31b2e 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go @@ -19,18 +19,19 @@ package admission import ( "context" "errors" + "fmt" "net/http" + "sync" "github.com/go-logr/logr" - jsonpatch "gomodules.xyz/jsonpatch/v2" + "gomodules.xyz/jsonpatch/v2" admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/json" - "k8s.io/client-go/kubernetes/scheme" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" - logf "sigs.k8s.io/controller-runtime/pkg/internal/log" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" + logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" ) @@ -121,101 +122,88 @@ type Webhook struct { // and potentially patches to apply to the handler. Handler Handler + // RecoverPanic indicates whether the panic caused by webhook should be recovered. + RecoverPanic bool + // WithContextFunc will allow you to take the http.Request.Context() and // add any additional information such as passing the request path or // headers thus allowing you to read them from within the handler WithContextFunc func(context.Context, *http.Request) context.Context - // decoder is constructed on receiving a scheme and passed down to then handler - decoder *Decoder + // LogConstructor is used to construct a logger for logging messages during webhook calls + // based on the given base logger (which might carry more values like the webhook's path). + // Note: LogConstructor has to be able to handle nil requests as we are also using it + // outside the context of requests. + LogConstructor func(base logr.Logger, req *Request) logr.Logger - log logr.Logger + setupLogOnce sync.Once + log logr.Logger } -// InjectLogger gets a handle to a logging instance, hopefully with more info about this particular webhook. -func (wh *Webhook) InjectLogger(l logr.Logger) error { - wh.log = l - return nil +// WithRecoverPanic takes a bool flag which indicates whether the panic caused by webhook should be recovered. +func (wh *Webhook) WithRecoverPanic(recoverPanic bool) *Webhook { + wh.RecoverPanic = recoverPanic + return wh } // Handle processes AdmissionRequest. // If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches. // If the webhook is validating type, it delegates the AdmissionRequest to each handler and // deny the request if anyone denies. -func (wh *Webhook) Handle(ctx context.Context, req Request) Response { +func (wh *Webhook) Handle(ctx context.Context, req Request) (response Response) { + if wh.RecoverPanic { + defer func() { + if r := recover(); r != nil { + for _, fn := range utilruntime.PanicHandlers { + fn(r) + } + response = Errored(http.StatusInternalServerError, fmt.Errorf("panic: %v [recovered]", r)) + return + } + }() + } + + reqLog := wh.getLogger(&req) + ctx = logf.IntoContext(ctx, reqLog) + resp := wh.Handler.Handle(ctx, req) if err := resp.Complete(req); err != nil { - wh.log.Error(err, "unable to encode response") + reqLog.Error(err, "unable to encode response") return Errored(http.StatusInternalServerError, errUnableToEncodeResponse) } return resp } -// InjectScheme injects a scheme into the webhook, in order to construct a Decoder. -func (wh *Webhook) InjectScheme(s *runtime.Scheme) error { - // TODO(directxman12): we should have a better way to pass this down - - var err error - wh.decoder, err = NewDecoder(s) - if err != nil { - return err - } - - // inject the decoder here too, just in case the order of calling this is not - // scheme first, then inject func - if wh.Handler != nil { - if _, err := InjectDecoderInto(wh.GetDecoder(), wh.Handler); err != nil { - return err +// getLogger constructs a logger from the injected log and LogConstructor. +func (wh *Webhook) getLogger(req *Request) logr.Logger { + wh.setupLogOnce.Do(func() { + if wh.log.GetSink() == nil { + wh.log = logf.Log.WithName("admission") } - } - - return nil -} + }) -// GetDecoder returns a decoder to decode the objects embedded in admission requests. -// It may be nil if we haven't received a scheme to use to determine object types yet. -func (wh *Webhook) GetDecoder() *Decoder { - return wh.decoder + logConstructor := wh.LogConstructor + if logConstructor == nil { + logConstructor = DefaultLogConstructor + } + return logConstructor(wh.log, req) } -// InjectFunc injects the field setter into the webhook. -func (wh *Webhook) InjectFunc(f inject.Func) error { - // inject directly into the handlers. It would be more correct - // to do this in a sync.Once in Handle (since we don't have some - // other start/finalize-type method), but it's more efficient to - // do it here, presumably. - - // also inject a decoder, and wrap this so that we get a setFields - // that injects a decoder (hopefully things don't ignore the duplicate - // InjectorInto call). - - var setFields inject.Func - setFields = func(target interface{}) error { - if err := f(target); err != nil { - return err - } - - if _, err := inject.InjectorInto(setFields, target); err != nil { - return err - } - - if _, err := InjectDecoderInto(wh.GetDecoder(), target); err != nil { - return err - } - - return nil +// DefaultLogConstructor adds some commonly interesting fields to the given logger. +func DefaultLogConstructor(base logr.Logger, req *Request) logr.Logger { + if req != nil { + return base.WithValues("object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) } - - return setFields(wh.Handler) + return base } // StandaloneOptions let you configure a StandaloneWebhook. type StandaloneOptions struct { - // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources - // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better - // idea to pass your own scheme in. See the documentation in pkg/scheme for more information. - Scheme *runtime.Scheme // Logger to be used by the webhook. // If none is set, it defaults to log.Log global logger. Logger logr.Logger @@ -235,19 +223,9 @@ type StandaloneOptions struct { // in your own server/mux. In order to be accessed by a kubernetes cluster, // all webhook servers require TLS. func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, error) { - if opts.Scheme == nil { - opts.Scheme = scheme.Scheme - } - - if err := hook.InjectScheme(opts.Scheme); err != nil { - return nil, err + if opts.Logger.GetSink() != nil { + hook.log = opts.Logger } - - if opts.Logger.GetSink() == nil { - opts.Logger = logf.RuntimeLog.WithName("webhook") - } - hook.log = opts.Logger - if opts.MetricsPath == "" { return hook, nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go index a5b7a282cee..249a364b381 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go @@ -39,28 +39,20 @@ var ( log = logf.Log.WithName("conversion-webhook") ) -// Webhook implements a CRD conversion webhook HTTP handler. -type Webhook struct { - scheme *runtime.Scheme - decoder *Decoder +func NewWebhookHandler(scheme *runtime.Scheme) http.Handler { + return &webhook{scheme: scheme, decoder: NewDecoder(scheme)} } -// InjectScheme injects a scheme into the webhook, in order to construct a Decoder. -func (wh *Webhook) InjectScheme(s *runtime.Scheme) error { - var err error - wh.scheme = s - wh.decoder, err = NewDecoder(s) - if err != nil { - return err - } - - return nil +// webhook implements a CRD conversion webhook HTTP handler. +type webhook struct { + scheme *runtime.Scheme + decoder *Decoder } // ensure Webhook implements http.Handler -var _ http.Handler = &Webhook{} +var _ http.Handler = &webhook{} -func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (wh *webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { convertReview := &apix.ConversionReview{} err := json.NewDecoder(r.Body).Decode(convertReview) if err != nil { @@ -69,6 +61,12 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + if convertReview.Request == nil { + log.Error(nil, "conversion request is nil") + w.WriteHeader(http.StatusBadRequest) + return + } + // TODO(droot): may be move the conversion logic to a separate module to // decouple it from the http layer ? resp, err := wh.handleConvertRequest(convertReview.Request) @@ -89,7 +87,7 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // handles a version conversion request. -func (wh *Webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.ConversionResponse, error) { +func (wh *webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.ConversionResponse, error) { if req == nil { return nil, fmt.Errorf("conversion request is nil") } @@ -122,7 +120,7 @@ func (wh *Webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.Conv // convertObject will convert given a src object to dst object. // Note(droot): couldn't find a way to reduce the cyclomatic complexity under 10 // without compromising readability, so disabling gocyclo linter -func (wh *Webhook) convertObject(src, dst runtime.Object) error { +func (wh *webhook) convertObject(src, dst runtime.Object) error { srcGVK := src.GetObjectKind().GroupVersionKind() dstGVK := dst.GetObjectKind().GroupVersionKind() @@ -149,7 +147,7 @@ func (wh *Webhook) convertObject(src, dst runtime.Object) error { } } -func (wh *Webhook) convertViaHub(src, dst conversion.Convertible) error { +func (wh *webhook) convertViaHub(src, dst conversion.Convertible) error { hub, err := wh.getHub(src) if err != nil { return err @@ -173,7 +171,7 @@ func (wh *Webhook) convertViaHub(src, dst conversion.Convertible) error { } // getHub returns an instance of the Hub for passed-in object's group/kind. -func (wh *Webhook) getHub(obj runtime.Object) (conversion.Hub, error) { +func (wh *webhook) getHub(obj runtime.Object) (conversion.Hub, error) { gvks, err := objectGVKs(wh.scheme, obj) if err != nil { return nil, err @@ -201,7 +199,7 @@ func (wh *Webhook) getHub(obj runtime.Object) (conversion.Hub, error) { } // allocateDstObject returns an instance for a given GVK. -func (wh *Webhook) allocateDstObject(apiVersion, kind string) (runtime.Object, error) { +func (wh *webhook) allocateDstObject(apiVersion, kind string) (runtime.Object, error) { gvk := schema.FromAPIVersionAndKind(apiVersion, kind) obj, err := wh.scheme.New(gvk) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go index 6a9e9c2365d..b6bb8bd9384 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go @@ -30,8 +30,11 @@ type Decoder struct { } // NewDecoder creates a Decoder given the runtime.Scheme -func NewDecoder(scheme *runtime.Scheme) (*Decoder, error) { - return &Decoder{codecs: serializer.NewCodecFactory(scheme)}, nil +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} } // Decode decodes the inlined object. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go index fa56be5d55e..23d5bf43507 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go @@ -29,12 +29,9 @@ import ( "sync" "time" - "k8s.io/apimachinery/pkg/runtime" - kscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/certwatcher" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" - "sigs.k8s.io/controller-runtime/pkg/runtime/inject" "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" ) @@ -49,7 +46,29 @@ var DefaultPort = 9443 // at the default locations (tls.crt and tls.key). If you do not // want to configure TLS (i.e for testing purposes) run an // admission.StandaloneWebhook in your own server. -type Server struct { +type Server interface { + // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates + // the webhook server doesn't need leader election. + NeedLeaderElection() bool + + // Register marks the given webhook as being served at the given path. + // It panics if two hooks are registered on the same path. + Register(path string, hook http.Handler) + + // Start runs the server. + // It will install the webhook related resources depend on the server configuration. + Start(ctx context.Context) error + + // StartedChecker returns an healthz.Checker which is healthy after the + // server has been started. + StartedChecker() healthz.Checker + + // WebhookMux returns the servers WebhookMux + WebhookMux() *http.ServeMux +} + +// Options are all the available options for a webhook.Server +type Options struct { // Host is the address that the server will listen on. // Defaults to "" - all addresses. Host string @@ -63,9 +82,13 @@ type Server struct { CertDir string // CertName is the server certificate name. Defaults to tls.crt. + // + // Note: This option should only be set when TLSOpts does not override GetCertificate. CertName string // KeyName is the server key name. Defaults to tls.key. + // + // Note: This option should only be set when TLSOpts does not override GetCertificate. KeyName string // ClientCAName is the CA certificate name which server used to verify remote(client)'s certificate. @@ -74,6 +97,7 @@ type Server struct { // TLSVersion is the minimum version of TLS supported. Accepts // "", "1.0", "1.1", "1.2" and "1.3" only ("" is equivalent to "1.0" for backwards compatibility) + // Deprecated: Use TLSOpts instead. TLSMinVersion string // TLSOpts is used to allow configuring the TLS config used for the server @@ -81,13 +105,21 @@ type Server struct { // WebhookMux is the multiplexer that handles different webhooks. WebhookMux *http.ServeMux +} - // webhooks keep track of all registered webhooks for dependency injection, - // and to provide better panic messages on duplicate webhook registration. - webhooks map[string]http.Handler +// NewServer constructs a new Server from the provided options. +func NewServer(o Options) Server { + return &DefaultServer{ + Options: o, + } +} - // setFields allows injecting dependencies from an external source - setFields inject.Func +// DefaultServer is the default implementation used for Server. +type DefaultServer struct { + Options Options + + // webhooks keep track of all registered webhooks + webhooks map[string]http.Handler // defaultingOnce ensures that the default fields are only ever set once. defaultingOnce sync.Once @@ -98,41 +130,49 @@ type Server struct { // mu protects access to the webhook map & setFields for Start, Register, etc mu sync.Mutex + + webhookMux *http.ServeMux } // setDefaults does defaulting for the Server. -func (s *Server) setDefaults() { - s.webhooks = map[string]http.Handler{} - if s.WebhookMux == nil { - s.WebhookMux = http.NewServeMux() +func (o *Options) setDefaults() { + if o.WebhookMux == nil { + o.WebhookMux = http.NewServeMux() } - if s.Port <= 0 { - s.Port = DefaultPort + if o.Port <= 0 { + o.Port = DefaultPort } - if len(s.CertDir) == 0 { - s.CertDir = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs") + if len(o.CertDir) == 0 { + o.CertDir = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs") } - if len(s.CertName) == 0 { - s.CertName = "tls.crt" + if len(o.CertName) == 0 { + o.CertName = "tls.crt" } - if len(s.KeyName) == 0 { - s.KeyName = "tls.key" + if len(o.KeyName) == 0 { + o.KeyName = "tls.key" } } +func (s *DefaultServer) setDefaults() { + s.webhooks = map[string]http.Handler{} + s.Options.setDefaults() + + s.webhookMux = s.Options.WebhookMux +} + // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates // the webhook server doesn't need leader election. -func (*Server) NeedLeaderElection() bool { +func (*DefaultServer) NeedLeaderElection() bool { return false } // Register marks the given webhook as being served at the given path. // It panics if two hooks are registered on the same path. -func (s *Server) Register(path string, hook http.Handler) { +func (s *DefaultServer) Register(path string, hook http.Handler) { s.mu.Lock() defer s.mu.Unlock() @@ -140,51 +180,11 @@ func (s *Server) Register(path string, hook http.Handler) { if _, found := s.webhooks[path]; found { panic(fmt.Errorf("can't register duplicate path: %v", path)) } - // TODO(directxman12): call setfields if we've already started the server s.webhooks[path] = hook - s.WebhookMux.Handle(path, metrics.InstrumentedHook(path, hook)) + s.webhookMux.Handle(path, metrics.InstrumentedHook(path, hook)) regLog := log.WithValues("path", path) regLog.Info("Registering webhook") - - // we've already been "started", inject dependencies here. - // Otherwise, InjectFunc will do this for us later. - if s.setFields != nil { - if err := s.setFields(hook); err != nil { - // TODO(directxman12): swallowing this error isn't great, but we'd have to - // change the signature to fix that - regLog.Error(err, "unable to inject fields into webhook during registration") - } - - baseHookLog := log.WithName("webhooks") - - // NB(directxman12): we don't propagate this further by wrapping setFields because it's - // unclear if this is how we want to deal with log propagation. In this specific instance, - // we want to be able to pass a logger to webhooks because they don't know their own path. - if _, err := inject.LoggerInto(baseHookLog.WithValues("webhook", path), hook); err != nil { - regLog.Error(err, "unable to logger into webhook during registration") - } - } -} - -// StartStandalone runs a webhook server without -// a controller manager. -func (s *Server) StartStandalone(ctx context.Context, scheme *runtime.Scheme) error { - // Use the Kubernetes client-go scheme if none is specified - if scheme == nil { - scheme = kscheme.Scheme - } - - if err := s.InjectFunc(func(i interface{}) error { - if _, err := inject.SchemeInto(scheme, i); err != nil { - return err - } - return nil - }); err != nil { - return err - } - - return s.Start(ctx) } // tlsVersion converts from human-readable TLS version (for example "1.1") @@ -209,41 +209,49 @@ func tlsVersion(version string) (uint16, error) { // Start runs the server. // It will install the webhook related resources depend on the server configuration. -func (s *Server) Start(ctx context.Context) error { +func (s *DefaultServer) Start(ctx context.Context) error { s.defaultingOnce.Do(s.setDefaults) baseHookLog := log.WithName("webhooks") baseHookLog.Info("Starting webhook server") - certPath := filepath.Join(s.CertDir, s.CertName) - keyPath := filepath.Join(s.CertDir, s.KeyName) - - certWatcher, err := certwatcher.New(certPath, keyPath) + tlsMinVersion, err := tlsVersion(s.Options.TLSMinVersion) if err != nil { return err } - go func() { - if err := certWatcher.Start(ctx); err != nil { - log.Error(err, "certificate watcher error") - } - }() - - tlsMinVersion, err := tlsVersion(s.TLSMinVersion) - if err != nil { - return err + cfg := &tls.Config{ //nolint:gosec + NextProtos: []string{"h2"}, + MinVersion: tlsMinVersion, + } + // fallback TLS config ready, will now mutate if passer wants full control over it + for _, op := range s.Options.TLSOpts { + op(cfg) } - cfg := &tls.Config{ //nolint:gosec - NextProtos: []string{"h2"}, - GetCertificate: certWatcher.GetCertificate, - MinVersion: tlsMinVersion, + if cfg.GetCertificate == nil { + certPath := filepath.Join(s.Options.CertDir, s.Options.CertName) + keyPath := filepath.Join(s.Options.CertDir, s.Options.KeyName) + + // Create the certificate watcher and + // set the config's GetCertificate on the TLSConfig + certWatcher, err := certwatcher.New(certPath, keyPath) + if err != nil { + return err + } + cfg.GetCertificate = certWatcher.GetCertificate + + go func() { + if err := certWatcher.Start(ctx); err != nil { + log.Error(err, "certificate watcher error") + } + }() } - // load CA to verify client certificate - if s.ClientCAName != "" { + // Load CA to verify client certificate, if configured. + if s.Options.ClientCAName != "" { certPool := x509.NewCertPool() - clientCABytes, err := os.ReadFile(filepath.Join(s.CertDir, s.ClientCAName)) + clientCABytes, err := os.ReadFile(filepath.Join(s.Options.CertDir, s.Options.ClientCAName)) if err != nil { return fmt.Errorf("failed to read client CA cert: %w", err) } @@ -257,27 +265,23 @@ func (s *Server) Start(ctx context.Context) error { cfg.ClientAuth = tls.RequireAndVerifyClientCert } - // fallback TLS config ready, will now mutate if passer wants full control over it - for _, op := range s.TLSOpts { - op(cfg) - } - - listener, err := tls.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), cfg) + listener, err := tls.Listen("tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), cfg) if err != nil { return err } - log.Info("Serving webhook server", "host", s.Host, "port", s.Port) + log.Info("Serving webhook server", "host", s.Options.Host, "port", s.Options.Port) - srv := httpserver.New(s.WebhookMux) + srv := httpserver.New(s.webhookMux) idleConnsClosed := make(chan struct{}) go func() { <-ctx.Done() - log.Info("shutting down webhook server") + log.Info("Shutting down webhook server with timeout of 1 minute") - // TODO: use a context with reasonable timeout - if err := srv.Shutdown(context.Background()); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { // Error from closing listeners, or context timeout log.Error(err, "error shutting down the HTTP server") } @@ -297,9 +301,9 @@ func (s *Server) Start(ctx context.Context) error { // StartedChecker returns an healthz.Checker which is healthy after the // server has been started. -func (s *Server) StartedChecker() healthz.Checker { +func (s *DefaultServer) StartedChecker() healthz.Checker { config := &tls.Config{ - InsecureSkipVerify: true, // nolint:gosec // config is used to connect to our own webhook port. + InsecureSkipVerify: true, //nolint:gosec // config is used to connect to our own webhook port. } return func(req *http.Request) error { s.mu.Lock() @@ -310,7 +314,7 @@ func (s *Server) StartedChecker() healthz.Checker { } d := &net.Dialer{Timeout: 10 * time.Second} - conn, err := tls.DialWithDialer(d, "tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), config) + conn, err := tls.DialWithDialer(d, "tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), config) if err != nil { return fmt.Errorf("webhook server is not reachable: %w", err) } @@ -323,23 +327,7 @@ func (s *Server) StartedChecker() healthz.Checker { } } -// InjectFunc injects the field setter into the server. -func (s *Server) InjectFunc(f inject.Func) error { - s.setFields = f - - // inject fields here that weren't injected in Register because we didn't have setFields yet. - baseHookLog := log.WithName("webhooks") - for hookPath, webhook := range s.webhooks { - if err := s.setFields(webhook); err != nil { - return err - } - - // NB(directxman12): we don't propagate this further by wrapping setFields because it's - // unclear if this is how we want to deal with log propagation. In this specific instance, - // we want to be able to pass a logger to webhooks because they don't know their own path. - if _, err := inject.LoggerInto(baseHookLog.WithValues("webhook", hookPath), webhook); err != nil { - return err - } - } - return nil +// WebhookMux returns the servers WebhookMux +func (s *DefaultServer) WebhookMux() *http.ServeMux { + return s.webhookMux } diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go index 3a8b64547da..6a13cf2df0a 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go @@ -75,6 +75,8 @@ import ( // either be any string type, an integer, implement json.Unmarshaler, or // implement encoding.TextUnmarshaler. // +// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError. +// // If a JSON value is not appropriate for a given target type, // or if a JSON number overflows the target type, Unmarshal // skips that field and completes the unmarshaling as best it can. @@ -85,15 +87,14 @@ import ( // // The JSON null value unmarshals into an interface, map, pointer, or slice // by setting that Go value to nil. Because null is often used in JSON to mean -// ``not present,'' unmarshaling a JSON null into any other Go type has no effect +// “not present,” unmarshaling a JSON null into any other Go type has no effect // on the value and produces no error. // // When unmarshaling quoted strings, invalid UTF-8 or // invalid UTF-16 surrogate pairs are not treated as an error. // Instead, they are replaced by the Unicode replacement // character U+FFFD. -// -func Unmarshal(data []byte, v interface{}, opts ...UnmarshalOpt) error { +func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error { // Check for well-formedness. // Avoids filling out half a data structure // before discovering a JSON syntax error. @@ -167,16 +168,16 @@ func (e *InvalidUnmarshalError) Error() string { return "json: Unmarshal(nil)" } - if e.Type.Kind() != reflect.Ptr { + if e.Type.Kind() != reflect.Pointer { return "json: Unmarshal(non-pointer " + e.Type.String() + ")" } return "json: Unmarshal(nil " + e.Type.String() + ")" } */ -func (d *decodeState) unmarshal(v interface{}) error { +func (d *decodeState) unmarshal(v any) error { rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr || rv.IsNil() { + if rv.Kind() != reflect.Pointer || rv.IsNil() { return &InvalidUnmarshalError{reflect.TypeOf(v)} } @@ -233,7 +234,7 @@ type decodeState struct { disallowUnknownFields bool savedStrictErrors []error - seenStrictErrors map[string]struct{} + seenStrictErrors map[strictError]struct{} strictFieldStack []string caseSensitive bool @@ -425,7 +426,7 @@ type unquotedValue struct{} // quoted string literal or literal null into an interface value. // If it finds anything other than a quoted string literal or null, // valueQuoted returns unquotedValue{}. -func (d *decodeState) valueQuoted() interface{} { +func (d *decodeState) valueQuoted() any { switch d.opcode { default: panic(phasePanicMsg) @@ -467,7 +468,7 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm // If v is a named type and is addressable, // start with its address, so that if the type has pointer methods, // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() { haveAddr = true v = v.Addr() } @@ -476,14 +477,14 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm // usefully addressable. if v.Kind() == reflect.Interface && !v.IsNil() { e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) { haveAddr = false v = e continue } } - if v.Kind() != reflect.Ptr { + if v.Kind() != reflect.Pointer { break } @@ -678,7 +679,7 @@ func (d *decodeState) object(v reflect.Value) error { reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: default: - if !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) { + if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) { d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) d.skip() return nil @@ -695,7 +696,7 @@ func (d *decodeState) object(v reflect.Value) error { seenKeys = map[string]struct{}{} } if _, seen := seenKeys[fieldName]; seen { - d.saveStrictError(d.newFieldError("duplicate field", fieldName)) + d.saveStrictError(d.newFieldError(duplicateStrictErrType, fieldName)) } else { seenKeys[fieldName] = struct{}{} } @@ -711,7 +712,7 @@ func (d *decodeState) object(v reflect.Value) error { var seenKeys uint64 checkDuplicateField = func(fieldNameIndex int, fieldName string) { if seenKeys&(1< startDetectingCyclesAfter { // We're a large number of nested ptrEncoder.encode calls deep; // start checking if we've run into a pointer cycle. - ptr := v.Pointer() + ptr := v.UnsafePointer() if _, ok := e.ptrSeen[ptr]; ok { e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) } @@ -877,9 +876,9 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { // Here we use a struct to memorize the pointer to the first element of the slice // and its length. ptr := struct { - ptr uintptr + ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe len int - }{v.Pointer(), v.Len()} + }{v.UnsafePointer(), v.Len()} if _, ok := e.ptrSeen[ptr]; ok { e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) } @@ -893,7 +892,7 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { func newSliceEncoder(t reflect.Type) encoderFunc { // Byte slices get special treatment; arrays don't. if t.Elem().Kind() == reflect.Uint8 { - p := reflect.PtrTo(t.Elem()) + p := reflect.PointerTo(t.Elem()) if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) { return encodeByteSlice } @@ -989,7 +988,7 @@ func isValidTag(s string) bool { func typeByIndex(t reflect.Type, index []int) reflect.Type { for _, i := range index { - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } t = t.Field(i).Type @@ -1009,7 +1008,7 @@ func (w *reflectWithString) resolve() error { return nil } if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok { - if w.k.Kind() == reflect.Ptr && w.k.IsNil() { + if w.k.Kind() == reflect.Pointer && w.k.IsNil() { return nil } buf, err := tm.MarshalText() @@ -1243,7 +1242,7 @@ func typeFields(t reflect.Type) structFields { sf := f.typ.Field(i) if sf.Anonymous { t := sf.Type - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } if !sf.IsExported() && t.Kind() != reflect.Struct { @@ -1269,7 +1268,7 @@ func typeFields(t reflect.Type) structFields { index[len(f.index)] = i ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { + if ft.Name() == "" && ft.Kind() == reflect.Pointer { // Follow pointer. ft = ft.Elem() } diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go index 9e170127dba..ab249b2bbed 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go @@ -24,8 +24,9 @@ const ( // 4) simpleLetterEqualFold, no specials, no non-letters. // // The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign +// - S maps to s and to U+017F 'ſ' Latin small letter long s +// - k maps to K and to U+212A 'K' Kelvin sign +// // See https://play.golang.org/p/tTxjOc0OGo // // The returned function is specialized for matching against s and diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go index d3fa2d11138..b8f4ff2c1d6 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build gofuzz -// +build gofuzz package json @@ -12,10 +11,10 @@ import ( ) func Fuzz(data []byte) (score int) { - for _, ctor := range []func() interface{}{ - func() interface{} { return new(interface{}) }, - func() interface{} { return new(map[string]interface{}) }, - func() interface{} { return new([]interface{}) }, + for _, ctor := range []func() any{ + func() any { return new(any) }, + func() any { return new(map[string]any) }, + func() any { return new([]any) }, } { v := ctor() err := Unmarshal(data, v) diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go index cb9ab062717..e1c0a74d9c7 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go @@ -18,7 +18,6 @@ package json import ( gojson "encoding/json" - "fmt" "strconv" "strings" ) @@ -71,32 +70,37 @@ func (d *Decoder) DisallowDuplicateFields() { d.d.disallowDuplicateFields = true } -func (d *decodeState) newFieldError(msg, field string) error { +func (d *decodeState) newFieldError(errType strictErrType, field string) *strictError { if len(d.strictFieldStack) > 0 { - return fmt.Errorf("%s %q", msg, strings.Join(d.strictFieldStack, "")+"."+field) + return &strictError{ + ErrType: errType, + Path: strings.Join(d.strictFieldStack, "") + "." + field, + } } else { - return fmt.Errorf("%s %q", msg, field) + return &strictError{ + ErrType: errType, + Path: field, + } } } // saveStrictError saves a strict decoding error, // for reporting at the end of the unmarshal if no other errors occurred. -func (d *decodeState) saveStrictError(err error) { +func (d *decodeState) saveStrictError(err *strictError) { // prevent excessive numbers of accumulated errors if len(d.savedStrictErrors) >= 100 { return } // dedupe accumulated strict errors if d.seenStrictErrors == nil { - d.seenStrictErrors = map[string]struct{}{} + d.seenStrictErrors = map[strictError]struct{}{} } - msg := err.Error() - if _, seen := d.seenStrictErrors[msg]; seen { + if _, seen := d.seenStrictErrors[*err]; seen { return } // accumulate the error - d.seenStrictErrors[msg] = struct{}{} + d.seenStrictErrors[*err] = struct{}{} d.savedStrictErrors = append(d.savedStrictErrors, err) } @@ -118,6 +122,33 @@ func (d *decodeState) appendStrictFieldStackIndex(i int) { d.strictFieldStack = append(d.strictFieldStack, "[", strconv.Itoa(i), "]") } +type strictErrType string + +const ( + unknownStrictErrType strictErrType = "unknown field" + duplicateStrictErrType strictErrType = "duplicate field" +) + +// strictError is a strict decoding error +// It has an ErrType (either unknown or duplicate) +// and a path to the erroneous field +type strictError struct { + ErrType strictErrType + Path string +} + +func (e *strictError) Error() string { + return string(e.ErrType) + " " + strconv.Quote(e.Path) +} + +func (e *strictError) FieldPath() string { + return e.Path +} + +func (e *strictError) SetFieldPath(path string) { + e.Path = path +} + // UnmarshalStrictError holds errors resulting from use of strict disallow___ decoder directives. // If this is returned from Unmarshal(), it means the decoding was successful in all other respects. type UnmarshalStrictError struct { diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go index 9dc1903e2db..22fc6922da9 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go @@ -27,6 +27,7 @@ func Valid(data []byte) bool { // checkValid verifies that data is valid JSON-encoded data. // scan is passed in for use by checkValid to avoid an allocation. +// checkValid returns nil or a SyntaxError. func checkValid(data []byte, scan *scanner) error { scan.reset() for _, c := range data { @@ -42,6 +43,7 @@ func checkValid(data []byte, scan *scanner) error { } // A SyntaxError is a description of a JSON syntax error. +// Unmarshal will return a SyntaxError if the JSON can't be parsed. type SyntaxError struct { msg string // description of error Offset int64 // error occurred after reading Offset bytes @@ -83,7 +85,7 @@ type scanner struct { } var scannerPool = sync.Pool{ - New: func() interface{} { + New: func() any { return &scanner{} }, } diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go index 5f87df1c628..1967755ac84 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go @@ -45,7 +45,7 @@ func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true // // See the documentation for Unmarshal for details about // the conversion of JSON into a Go value. -func (dec *Decoder) Decode(v interface{}) error { +func (dec *Decoder) Decode(v any) error { if dec.err != nil { return dec.err } @@ -197,7 +197,7 @@ func NewEncoder(w io.Writer) *Encoder { // // See the documentation for Marshal for details about the // conversion of Go values to JSON. -func (enc *Encoder) Encode(v interface{}) error { +func (enc *Encoder) Encode(v any) error { if enc.err != nil { return enc.err } @@ -289,8 +289,7 @@ var _ Unmarshaler = (*RawMessage)(nil) // Number, for JSON numbers // string, for JSON string literals // nil, for JSON null -// -type Token interface{} +type Token any */ const ( @@ -457,7 +456,7 @@ func (dec *Decoder) Token() (Token, error) { if !dec.tokenValueAllowed() { return dec.tokenError(c) } - var x interface{} + var x any if err := dec.Decode(&x); err != nil { return nil, err } diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go index c38fd5102f6..b490328f4c4 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go @@ -15,10 +15,8 @@ type tagOptions string // parseTag splits a struct field's json tag into its name and // comma-separated options. func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") + tag, opt, _ := strings.Cut(tag, ",") + return tag, tagOptions(opt) } // Contains reports whether a comma-separated list of options @@ -30,15 +28,11 @@ func (o tagOptions) Contains(optionName string) bool { } s := string(o) for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { + var name string + name, s, _ = strings.Cut(s, ",") + if name == optionName { return true } - s = next } return false } diff --git a/vendor/sigs.k8s.io/json/json.go b/vendor/sigs.k8s.io/json/json.go index 764e2a84c72..e8f31b16c10 100644 --- a/vendor/sigs.k8s.io/json/json.go +++ b/vendor/sigs.k8s.io/json/json.go @@ -34,13 +34,13 @@ type Decoder interface { } // NewDecoderCaseSensitivePreserveInts returns a decoder that matches the behavior of encoding/json#NewDecoder, with the following changes: -// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) -// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. -// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if -// the JSON data does not contain a "." character and parses as an integer successfully and -// does not overflow int64. Otherwise, the number is unmarshaled as a float64. -// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, -// but will be recognizeable by this package's IsSyntaxError() function. +// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) +// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. +// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if +// the JSON data does not contain a "." character and parses as an integer successfully and +// does not overflow int64. Otherwise, the number is unmarshaled as a float64. +// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, +// but will be recognizeable by this package's IsSyntaxError() function. func NewDecoderCaseSensitivePreserveInts(r io.Reader) Decoder { d := internaljson.NewDecoder(r) d.CaseSensitive() @@ -51,13 +51,13 @@ func NewDecoderCaseSensitivePreserveInts(r io.Reader) Decoder { // UnmarshalCaseSensitivePreserveInts parses the JSON-encoded data and stores the result in the value pointed to by v. // // UnmarshalCaseSensitivePreserveInts matches the behavior of encoding/json#Unmarshal, with the following changes: -// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) -// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. -// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if -// the JSON data does not contain a "." character and parses as an integer successfully and -// does not overflow int64. Otherwise, the number is unmarshaled as a float64. -// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, -// but will be recognizeable by this package's IsSyntaxError() function. +// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) +// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. +// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if +// the JSON data does not contain a "." character and parses as an integer successfully and +// does not overflow int64. Otherwise, the number is unmarshaled as a float64. +// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, +// but will be recognizeable by this package's IsSyntaxError() function. func UnmarshalCaseSensitivePreserveInts(data []byte, v interface{}) error { return internaljson.Unmarshal( data, @@ -84,6 +84,8 @@ const ( // and a list of the strict failures (if any) are returned. If no `strictOptions` are selected, // all supported strict checks are performed. // +// Strict errors returned will implement the FieldError interface for the specific erroneous fields. +// // Currently supported strict checks are: // - DisallowDuplicateFields: ensure the data contains no duplicate fields // - DisallowUnknownFields: ensure the data contains no unknown fields (when decoding into typed structs) @@ -137,3 +139,12 @@ func SyntaxErrorOffset(err error) (isSyntaxError bool, offset int64) { return false, 0 } } + +// FieldError is an error that provides access to the path of the erroneous field +type FieldError interface { + error + // FieldPath provides the full path of the erroneous field within the json object. + FieldPath() string + // SetFieldPath updates the path of the erroneous field output in the error message. + SetFieldPath(path string) +} diff --git a/vendor/sigs.k8s.io/release-utils/LICENSE b/vendor/sigs.k8s.io/release-utils/LICENSE new file mode 100644 index 00000000000..8dada3edaf5 --- /dev/null +++ b/vendor/sigs.k8s.io/release-utils/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/sigs.k8s.io/release-utils/version/command.go b/vendor/sigs.k8s.io/release-utils/version/command.go new file mode 100644 index 00000000000..c1034e9e24a --- /dev/null +++ b/vendor/sigs.k8s.io/release-utils/version/command.go @@ -0,0 +1,72 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package version + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// Version returns a cobra command to be added to another cobra command, like: +// ```go +// rootCmd.AddCommand(version.Version()) +// ``` +func Version() *cobra.Command { + return version("") +} + +// WithFont returns a cobra command to be added to another cobra command with a select font for ASCII, like: +// ```go +// rootCmd.AddCommand(version.WithFont("starwars")) +// ``` +func WithFont(fontName string) *cobra.Command { + return version(fontName) +} + +func version(fontName string) *cobra.Command { + var outputJSON bool + cmd := &cobra.Command{ + Use: "version", + Short: "Prints the version", + RunE: func(cmd *cobra.Command, args []string) error { + v := GetVersionInfo() + v.Name = cmd.Root().Name() + v.Description = cmd.Root().Short + + v.FontName = "" + if fontName != "" && v.CheckFontName(fontName) { + v.FontName = fontName + } + + if outputJSON { + out, err := v.JSONString() + if err != nil { + return fmt.Errorf("unable to generate JSON from version info: %w", err) + } + cmd.Println(out) + } else { + cmd.Println(v.String()) + } + return nil + }, + } + + cmd.Flags().BoolVar(&outputJSON, "json", false, "print JSON instead of text") + + return cmd +} diff --git a/vendor/sigs.k8s.io/release-utils/version/doc.go b/vendor/sigs.k8s.io/release-utils/version/doc.go new file mode 100644 index 00000000000..8ae7a5e81bc --- /dev/null +++ b/vendor/sigs.k8s.io/release-utils/version/doc.go @@ -0,0 +1,27 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package version provides an importable cobra command and a fixed package +// path location to set compile time version information. To override the +// default values, set the `-ldflags` flags with the following strings: +// +// sigs.k8s.io/release-utils/version.gitVersion= +// sigs.k8s.io/release-utils/version.gitCommit= +// sigs.k8s.io/release-utils/version.gitTreeState= +// sigs.k8s.io/release-utils/version.buildDate= +// +// Example: `go build -ldflags " -X sigs.k8s.io/release-utils/version.gitVersion=v0.4.0-1-g040f53c -X sigs.k8s.io/release-utils/version.gitCommit=040f53c -X sigs.k8s.io/release-utils/version.gitTreeState=dirty -X sigs.k8s.io/release-utils/version.buildDate=2022-02-03T17:30:01Z" .` +package version diff --git a/vendor/sigs.k8s.io/release-utils/version/version.go b/vendor/sigs.k8s.io/release-utils/version/version.go new file mode 100644 index 00000000000..46dd1dc8aed --- /dev/null +++ b/vendor/sigs.k8s.io/release-utils/version/version.go @@ -0,0 +1,221 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package version + +import ( + "encoding/json" + "fmt" + "os" + "runtime" + "runtime/debug" + "strings" + "text/tabwriter" + "time" + + "github.com/common-nighthawk/go-figure" +) + +const unknown = "unknown" + +// Base version information. +// +// This is the fallback data used when version information from git is not +// provided via go ldflags. +var ( + // Output of "git describe". The prerequisite is that the + // branch should be tagged using the correct versioning strategy. + gitVersion = "devel" + // SHA1 from git, output of $(git rev-parse HEAD) + gitCommit = unknown + // State of git tree, either "clean" or "dirty" + gitTreeState = unknown + // Build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') + buildDate = unknown + // flag to print the ascii name banner + asciiName = "true" + // goVersion is the used golang version. + goVersion = unknown + // compiler is the used golang compiler. + compiler = unknown + // platform is the used os/arch identifier. + platform = unknown +) + +type Info struct { + GitVersion string `json:"gitVersion"` + GitCommit string `json:"gitCommit"` + GitTreeState string `json:"gitTreeState"` + BuildDate string `json:"buildDate"` + GoVersion string `json:"goVersion"` + Compiler string `json:"compiler"` + Platform string `json:"platform"` + + ASCIIName string `json:"-"` + FontName string `json:"-"` + Name string `json:"-"` + Description string `json:"-"` +} + +func getBuildInfo() *debug.BuildInfo { + bi, ok := debug.ReadBuildInfo() + if !ok { + return nil + } + return bi +} + +func getGitVersion(bi *debug.BuildInfo) string { + if bi == nil { + return unknown + } + + // TODO: remove this when the issue https://github.com/golang/go/issues/29228 is fixed + if bi.Main.Version == "(devel)" || bi.Main.Version == "" { + return gitVersion + } + + return bi.Main.Version +} + +func getCommit(bi *debug.BuildInfo) string { + return getKey(bi, "vcs.revision") +} + +func getDirty(bi *debug.BuildInfo) string { + modified := getKey(bi, "vcs.modified") + if modified == "true" { + return "dirty" + } + if modified == "false" { + return "clean" + } + return unknown +} + +func getBuildDate(bi *debug.BuildInfo) string { + buildTime := getKey(bi, "vcs.time") + t, err := time.Parse("2006-01-02T15:04:05Z", buildTime) + if err != nil { + return unknown + } + return t.Format("2006-01-02T15:04:05") +} + +func getKey(bi *debug.BuildInfo, key string) string { + if bi == nil { + return unknown + } + for _, iter := range bi.Settings { + if iter.Key == key { + return iter.Value + } + } + return unknown +} + +// GetVersionInfo represents known information on how this binary was built. +func GetVersionInfo() Info { + buildInfo := getBuildInfo() + gitVersion = getGitVersion(buildInfo) + if gitCommit == unknown { + gitCommit = getCommit(buildInfo) + } + + if gitTreeState == unknown { + gitTreeState = getDirty(buildInfo) + } + + if buildDate == unknown { + buildDate = getBuildDate(buildInfo) + } + + if goVersion == unknown { + goVersion = runtime.Version() + } + + if compiler == unknown { + compiler = runtime.Compiler + } + + if platform == unknown { + platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) + } + + return Info{ + ASCIIName: asciiName, + GitVersion: gitVersion, + GitCommit: gitCommit, + GitTreeState: gitTreeState, + BuildDate: buildDate, + GoVersion: goVersion, + Compiler: compiler, + Platform: platform, + } +} + +// String returns the string representation of the version info +func (i *Info) String() string { + b := strings.Builder{} + w := tabwriter.NewWriter(&b, 0, 0, 2, ' ', 0) + + // name and description are optional. + if i.Name != "" { + if i.ASCIIName == "true" { + f := figure.NewFigure(strings.ToUpper(i.Name), i.FontName, true) + _, _ = fmt.Fprint(w, f.String()) + } + _, _ = fmt.Fprint(w, i.Name) + if i.Description != "" { + _, _ = fmt.Fprintf(w, ": %s", i.Description) + } + _, _ = fmt.Fprint(w, "\n\n") + } + + _, _ = fmt.Fprintf(w, "GitVersion:\t%s\n", i.GitVersion) + _, _ = fmt.Fprintf(w, "GitCommit:\t%s\n", i.GitCommit) + _, _ = fmt.Fprintf(w, "GitTreeState:\t%s\n", i.GitTreeState) + _, _ = fmt.Fprintf(w, "BuildDate:\t%s\n", i.BuildDate) + _, _ = fmt.Fprintf(w, "GoVersion:\t%s\n", i.GoVersion) + _, _ = fmt.Fprintf(w, "Compiler:\t%s\n", i.Compiler) + _, _ = fmt.Fprintf(w, "Platform:\t%s\n", i.Platform) + + _ = w.Flush() + return b.String() +} + +// JSONString returns the JSON representation of the version info +func (i *Info) JSONString() (string, error) { + b, err := json.MarshalIndent(i, "", " ") + if err != nil { + return "", err + } + + return string(b), nil +} + +func (i *Info) CheckFontName(fontName string) bool { + assetNames := figure.AssetNames() + + for _, font := range assetNames { + if strings.Contains(font, fontName) { + return true + } + } + + fmt.Fprintln(os.Stderr, "font not valid, using default") + return false +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go new file mode 100644 index 00000000000..75a492d8ea8 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go @@ -0,0 +1,121 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package merge + +import ( + "fmt" + "sort" + "strings" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// Conflict is a conflict on a specific field with the current manager of +// that field. It does implement the error interface so that it can be +// used as an error. +type Conflict struct { + Manager string + Path fieldpath.Path +} + +// Conflict is an error. +var _ error = Conflict{} + +// Error formats the conflict as an error. +func (c Conflict) Error() string { + return fmt.Sprintf("conflict with %q: %v", c.Manager, c.Path) +} + +// Equals returns true if c == c2 +func (c Conflict) Equals(c2 Conflict) bool { + if c.Manager != c2.Manager { + return false + } + return c.Path.Equals(c2.Path) +} + +// Conflicts accumulates multiple conflicts and aggregates them by managers. +type Conflicts []Conflict + +var _ error = Conflicts{} + +// Error prints the list of conflicts, grouped by sorted managers. +func (conflicts Conflicts) Error() string { + if len(conflicts) == 1 { + return conflicts[0].Error() + } + + m := map[string][]fieldpath.Path{} + for _, conflict := range conflicts { + m[conflict.Manager] = append(m[conflict.Manager], conflict.Path) + } + + managers := []string{} + for manager := range m { + managers = append(managers, manager) + } + + // Print conflicts by sorted managers. + sort.Strings(managers) + + messages := []string{} + for _, manager := range managers { + messages = append(messages, fmt.Sprintf("conflicts with %q:", manager)) + for _, path := range m[manager] { + messages = append(messages, fmt.Sprintf("- %v", path)) + } + } + return strings.Join(messages, "\n") +} + +// Equals returns true if the lists of conflicts are the same. +func (c Conflicts) Equals(c2 Conflicts) bool { + if len(c) != len(c2) { + return false + } + for i := range c { + if !c[i].Equals(c2[i]) { + return false + } + } + return true +} + +// ToSet aggregates conflicts for all managers into a single Set. +func (c Conflicts) ToSet() *fieldpath.Set { + set := fieldpath.NewSet() + for _, conflict := range []Conflict(c) { + set.Insert(conflict.Path) + } + return set +} + +// ConflictsFromManagers creates a list of conflicts given Managers sets. +func ConflictsFromManagers(sets fieldpath.ManagedFields) Conflicts { + conflicts := []Conflict{} + + for manager, set := range sets { + set.Set().Iterate(func(p fieldpath.Path) { + conflicts = append(conflicts, Conflict{ + Manager: manager, + Path: p, + }) + }) + } + + return conflicts +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go new file mode 100644 index 00000000000..1b23dcbd5ef --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go @@ -0,0 +1,356 @@ +/* +Copyright 2018 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package merge + +import ( + "fmt" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/typed" +) + +// Converter is an interface to the conversion logic. The converter +// needs to be able to convert objects from one version to another. +type Converter interface { + Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) + IsMissingVersionError(error) bool +} + +// Updater is the object used to compute updated FieldSets and also +// merge the object on Apply. +type Updater struct { + Converter Converter + IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set + + enableUnions bool +} + +// EnableUnionFeature turns on union handling. It is disabled by default until the +// feature is complete. +func (s *Updater) EnableUnionFeature() { + s.enableUnions = true +} + +func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, workflow string, force bool) (fieldpath.ManagedFields, *typed.Comparison, error) { + conflicts := fieldpath.ManagedFields{} + removed := fieldpath.ManagedFields{} + compare, err := oldObject.Compare(newObject) + if err != nil { + return nil, nil, fmt.Errorf("failed to compare objects: %v", err) + } + + versions := map[fieldpath.APIVersion]*typed.Comparison{ + version: compare.ExcludeFields(s.IgnoredFields[version]), + } + + for manager, managerSet := range managers { + if manager == workflow { + continue + } + compare, ok := versions[managerSet.APIVersion()] + if !ok { + var err error + versionedOldObject, err := s.Converter.Convert(oldObject, managerSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + delete(managers, manager) + continue + } + return nil, nil, fmt.Errorf("failed to convert old object: %v", err) + } + versionedNewObject, err := s.Converter.Convert(newObject, managerSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + delete(managers, manager) + continue + } + return nil, nil, fmt.Errorf("failed to convert new object: %v", err) + } + compare, err = versionedOldObject.Compare(versionedNewObject) + if err != nil { + return nil, nil, fmt.Errorf("failed to compare objects: %v", err) + } + versions[managerSet.APIVersion()] = compare.ExcludeFields(s.IgnoredFields[managerSet.APIVersion()]) + } + + conflictSet := managerSet.Set().Intersection(compare.Modified.Union(compare.Added)) + if !conflictSet.Empty() { + conflicts[manager] = fieldpath.NewVersionedSet(conflictSet, managerSet.APIVersion(), false) + } + + if !compare.Removed.Empty() { + removed[manager] = fieldpath.NewVersionedSet(compare.Removed, managerSet.APIVersion(), false) + } + } + + if !force && len(conflicts) != 0 { + return nil, nil, ConflictsFromManagers(conflicts) + } + + for manager, conflictSet := range conflicts { + managers[manager] = fieldpath.NewVersionedSet(managers[manager].Set().Difference(conflictSet.Set()), managers[manager].APIVersion(), managers[manager].Applied()) + } + + for manager, removedSet := range removed { + managers[manager] = fieldpath.NewVersionedSet(managers[manager].Set().Difference(removedSet.Set()), managers[manager].APIVersion(), managers[manager].Applied()) + } + + for manager := range managers { + if managers[manager].Set().Empty() { + delete(managers, manager) + } + } + + return managers, compare, nil +} + +// Update is the method you should call once you've merged your final +// object on CREATE/UPDATE/PATCH verbs. newObject must be the object +// that you intend to persist (after applying the patch if this is for a +// PATCH call), and liveObject must be the original object (empty if +// this is a CREATE call). +func (s *Updater) Update(liveObject, newObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string) (*typed.TypedValue, fieldpath.ManagedFields, error) { + var err error + managers, err = s.reconcileManagedFieldsWithSchemaChanges(liveObject, managers) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if s.enableUnions { + newObject, err = liveObject.NormalizeUnions(newObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + managers, compare, err := s.update(liveObject, newObject, version, managers, manager, true) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if _, ok := managers[manager]; !ok { + managers[manager] = fieldpath.NewVersionedSet(fieldpath.NewSet(), version, false) + } + + ignored := s.IgnoredFields[version] + if ignored == nil { + ignored = fieldpath.NewSet() + } + managers[manager] = fieldpath.NewVersionedSet( + managers[manager].Set().Union(compare.Modified).Union(compare.Added).Difference(compare.Removed).RecursiveDifference(ignored), + version, + false, + ) + if managers[manager].Set().Empty() { + delete(managers, manager) + } + return newObject, managers, nil +} + +// Apply should be called when Apply is run, given the current object as +// well as the configuration that is applied. This will merge the object +// and return it. If the object hasn't changed, nil is returned (the +// managers can still have changed though). +func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string, force bool) (*typed.TypedValue, fieldpath.ManagedFields, error) { + var err error + managers, err = s.reconcileManagedFieldsWithSchemaChanges(liveObject, managers) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if s.enableUnions { + configObject, err = configObject.NormalizeUnionsApply(configObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + newObject, err := liveObject.Merge(configObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to merge config: %v", err) + } + if s.enableUnions { + newObject, err = configObject.NormalizeUnionsApply(newObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + lastSet := managers[manager] + set, err := configObject.ToFieldSet() + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to get field set: %v", err) + } + + ignored := s.IgnoredFields[version] + if ignored != nil { + set = set.RecursiveDifference(ignored) + // TODO: is this correct. If we don't remove from lastSet pruning might remove the fields? + if lastSet != nil { + lastSet.Set().RecursiveDifference(ignored) + } + } + managers[manager] = fieldpath.NewVersionedSet(set, version, true) + newObject, err = s.prune(newObject, managers, manager, lastSet) + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to prune fields: %v", err) + } + managers, compare, err := s.update(liveObject, newObject, version, managers, manager, force) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if compare.IsSame() { + newObject = nil + } + return newObject, managers, nil +} + +// prune will remove a field, list or map item, iff: +// * applyingManager applied it last time +// * applyingManager didn't apply it this time +// * no other applier claims to manage it +func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFields, applyingManager string, lastSet fieldpath.VersionedSet) (*typed.TypedValue, error) { + if lastSet == nil || lastSet.Set().Empty() { + return merged, nil + } + convertedMerged, err := s.Converter.Convert(merged, lastSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, nil + } + return nil, fmt.Errorf("failed to convert merged object to last applied version: %v", err) + } + + sc, tr := convertedMerged.Schema(), convertedMerged.TypeRef() + pruned := convertedMerged.RemoveItems(lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr)) + pruned, err = s.addBackOwnedItems(convertedMerged, pruned, managers, applyingManager) + if err != nil { + return nil, fmt.Errorf("failed add back owned items: %v", err) + } + pruned, err = s.addBackDanglingItems(convertedMerged, pruned, lastSet) + if err != nil { + return nil, fmt.Errorf("failed add back dangling items: %v", err) + } + return s.Converter.Convert(pruned, managers[applyingManager].APIVersion()) +} + +// addBackOwnedItems adds back any fields, list and map items that were removed by prune, +// but other appliers or updaters (or the current applier's new config) claim to own. +func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) { + var err error + managedAtVersion := map[fieldpath.APIVersion]*fieldpath.Set{} + for _, managerSet := range managedFields { + if _, ok := managedAtVersion[managerSet.APIVersion()]; !ok { + managedAtVersion[managerSet.APIVersion()] = fieldpath.NewSet() + } + managedAtVersion[managerSet.APIVersion()] = managedAtVersion[managerSet.APIVersion()].Union(managerSet.Set()) + } + // Add back owned items at pruned version first to avoid conversion failure + // caused by pruned fields which are required for conversion. + prunedVersion := fieldpath.APIVersion(*pruned.TypeRef().NamedType) + if managed, ok := managedAtVersion[prunedVersion]; ok { + merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, prunedVersion, managed) + if err != nil { + return nil, err + } + delete(managedAtVersion, prunedVersion) + } + for version, managed := range managedAtVersion { + merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, version, managed) + if err != nil { + return nil, err + } + } + return pruned, nil +} + +// addBackOwnedItemsForVersion adds back any fields, list and map items that were removed by prune with specific managed field path at a version. +// It is an extracted sub-function from addBackOwnedItems for code reuse. +func (s *Updater) addBackOwnedItemsForVersion(merged, pruned *typed.TypedValue, version fieldpath.APIVersion, managed *fieldpath.Set) (*typed.TypedValue, *typed.TypedValue, error) { + var err error + merged, err = s.Converter.Convert(merged, version) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, pruned, nil + } + return nil, nil, fmt.Errorf("failed to convert merged object at version %v: %v", version, err) + } + pruned, err = s.Converter.Convert(pruned, version) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, pruned, nil + } + return nil, nil, fmt.Errorf("failed to convert pruned object at version %v: %v", version, err) + } + mergedSet, err := merged.ToFieldSet() + if err != nil { + return nil, nil, fmt.Errorf("failed to create field set from merged object at version %v: %v", version, err) + } + prunedSet, err := pruned.ToFieldSet() + if err != nil { + return nil, nil, fmt.Errorf("failed to create field set from pruned object at version %v: %v", version, err) + } + sc, tr := merged.Schema(), merged.TypeRef() + pruned = merged.RemoveItems(mergedSet.EnsureNamedFieldsAreMembers(sc, tr).Difference(prunedSet.EnsureNamedFieldsAreMembers(sc, tr).Union(managed.EnsureNamedFieldsAreMembers(sc, tr)))) + return merged, pruned, nil +} + +// addBackDanglingItems makes sure that the fields list and map items removed by prune were +// previously owned by the currently applying manager. This will add back fields list and map items +// that are unowned or that are owned by Updaters and shouldn't be removed. +func (s *Updater) addBackDanglingItems(merged, pruned *typed.TypedValue, lastSet fieldpath.VersionedSet) (*typed.TypedValue, error) { + convertedPruned, err := s.Converter.Convert(pruned, lastSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, nil + } + return nil, fmt.Errorf("failed to convert pruned object to last applied version: %v", err) + } + prunedSet, err := convertedPruned.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create field set from pruned object in last applied version: %v", err) + } + mergedSet, err := merged.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create field set from merged object in last applied version: %v", err) + } + sc, tr := merged.Schema(), merged.TypeRef() + prunedSet = prunedSet.EnsureNamedFieldsAreMembers(sc, tr) + mergedSet = mergedSet.EnsureNamedFieldsAreMembers(sc, tr) + last := lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr) + return merged.RemoveItems(mergedSet.Difference(prunedSet).Intersection(last)), nil +} + +// reconcileManagedFieldsWithSchemaChanges reconciles the managed fields with any changes to the +// object's schema since the managed fields were written. +// +// Supports: +// - changing types from atomic to granular +// - changing types from granular to atomic +func (s *Updater) reconcileManagedFieldsWithSchemaChanges(liveObject *typed.TypedValue, managers fieldpath.ManagedFields) (fieldpath.ManagedFields, error) { + result := fieldpath.ManagedFields{} + for manager, versionedSet := range managers { + tv, err := s.Converter.Convert(liveObject, versionedSet.APIVersion()) + if s.Converter.IsMissingVersionError(err) { // okay to skip, obsolete versions will be deleted automatically anyway + continue + } + if err != nil { + return nil, err + } + reconciled, err := typed.ReconcileFieldSetWithSchema(versionedSet.Set(), tv) + if err != nil { + return nil, err + } + if reconciled != nil { + result[manager] = fieldpath.NewVersionedSet(reconciled, versionedSet.APIVersion(), versionedSet.Applied()) + } else { + result[manager] = versionedSet + } + } + return result, nil +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go index 01103b38a90..7e5dc758274 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go @@ -16,7 +16,9 @@ limitations under the License. package schema -import "sync" +import ( + "sync" +) // Schema is a list of named types. // @@ -27,6 +29,11 @@ type Schema struct { once sync.Once m map[string]TypeDef + + lock sync.Mutex + // Cached results of resolving type references to atoms. Only stores + // type references which require fields of Atom to be overriden. + resolvedTypes map[TypeRef]Atom } // A TypeSpecifier references a particular type in a schema. @@ -48,6 +55,12 @@ type TypeRef struct { // Either the name or one member of Atom should be set. NamedType *string `yaml:"namedType,omitempty"` Inlined Atom `yaml:",inline,omitempty"` + + // If this reference refers to a map-type or list-type, this field overrides + // the `ElementRelationship` of the referred type when resolved. + // If this field is nil, then it has no effect. + // See `Map` and `List` for more information about `ElementRelationship` + ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"` } // Atom represents the smallest possible pieces of the type system. @@ -88,11 +101,11 @@ const ( // Map is a key-value pair. Its default semantics are the same as an // associative list, but: -// * It is serialized differently: +// - It is serialized differently: // map: {"k": {"value": "v"}} // list: [{"key": "k", "value": "v"}] -// * Keys must be string typed. -// * Keys can't have multiple components. +// - Keys must be string typed. +// - Keys can't have multiple components. // // Optionally, maps may be atomic (for example, imagine representing an RGB // color value--it doesn't make sense to have different actors own the R and G @@ -146,6 +159,31 @@ func (m *Map) FindField(name string) (StructField, bool) { return sf, ok } +// CopyInto this instance of Map into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (m *Map) CopyInto(dst *Map) { + if dst == nil { + return + } + + // Map type is considered immutable so sharing references + dst.Fields = m.Fields + dst.ElementType = m.ElementType + dst.Unions = m.Unions + dst.ElementRelationship = m.ElementRelationship + + if m.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = m.m + }) + } +} + // UnionFields are mapping between the fields that are part of the union and // their discriminated value. The discriminated value has to be set, and // should not conflict with other discriminated value in the list. @@ -244,18 +282,93 @@ func (s *Schema) FindNamedType(name string) (TypeDef, bool) { return t, ok } +func (s *Schema) resolveNoOverrides(tr TypeRef) (Atom, bool) { + result := Atom{} + + if tr.NamedType != nil { + t, ok := s.FindNamedType(*tr.NamedType) + if !ok { + return Atom{}, false + } + + result = t.Atom + } else { + result = tr.Inlined + } + + return result, true +} + // Resolve is a convenience function which returns the atom referenced, whether // it is inline or named. Returns (Atom{}, false) if the type can't be resolved. // // This allows callers to not care about the difference between a (possibly // inlined) reference and a definition. func (s *Schema) Resolve(tr TypeRef) (Atom, bool) { - if tr.NamedType != nil { - t, ok := s.FindNamedType(*tr.NamedType) - if !ok { + // If this is a plain reference with no overrides, just return the type + if tr.ElementRelationship == nil { + return s.resolveNoOverrides(tr) + } + + s.lock.Lock() + defer s.lock.Unlock() + + if s.resolvedTypes == nil { + s.resolvedTypes = make(map[TypeRef]Atom) + } + + var result Atom + var exists bool + + // Return cached result if available + // If not, calculate result and cache it + if result, exists = s.resolvedTypes[tr]; !exists { + if result, exists = s.resolveNoOverrides(tr); exists { + // Allow field-level electives to override the referred type's modifiers + switch { + case result.Map != nil: + mapCopy := Map{} + result.Map.CopyInto(&mapCopy) + mapCopy.ElementRelationship = *tr.ElementRelationship + result.Map = &mapCopy + case result.List != nil: + listCopy := *result.List + listCopy.ElementRelationship = *tr.ElementRelationship + result.List = &listCopy + case result.Scalar != nil: + return Atom{}, false + default: + return Atom{}, false + } + } else { return Atom{}, false } - return t.Atom, true + + // Save result. If it is nil, that is also recorded as not existing. + s.resolvedTypes[tr] = result + } + + return result, true +} + +// Clones this instance of Schema into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (s *Schema) CopyInto(dst *Schema) { + if dst == nil { + return + } + + // Schema type is considered immutable so sharing references + dst.Types = s.Types + + if s.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = s.m + }) } - return tr.Inlined, true } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go index 4c303eecc54..b668eff8339 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go @@ -52,6 +52,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool { } //return true } + if a.ElementRelationship != b.ElementRelationship { + return false + } return a.Inlined.Equals(&b.Inlined) } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go index bb60e2a5fda..7d64d1308ce 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go @@ -66,6 +66,9 @@ var SchemaSchemaYAML = `types: - name: untyped type: namedType: untyped + - name: elementRelationship + type: + scalar: string - name: scalar scalar: string - name: map diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go index 6b2b2cb4a1e..19c77334f6c 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go @@ -105,7 +105,11 @@ type atomHandler interface { func resolveSchema(s *schema.Schema, tr schema.TypeRef, v value.Value, ah atomHandler) ValidationErrors { a, ok := s.Resolve(tr) if !ok { - return errorf("schema error: no type found matching: %v", *tr.NamedType) + typeName := "inlined type" + if tr.NamedType != nil { + typeName = *tr.NamedType + } + return errorf("schema error: no type found matching: %v", typeName) } a = deduceAtom(a, v) diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go index 75244ef6467..91364408307 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go @@ -80,7 +80,12 @@ func (w *mergingWalker) merge(prefixFn func() string) (errs ValidationErrors) { alhs := deduceAtom(a, w.lhs) arhs := deduceAtom(a, w.rhs) - if alhs.Equals(&arhs) { + + // deduceAtom does not fix the type for nil values + // nil is a wildcard and will accept whatever form the other operand takes + if w.rhs == nil { + errs = append(errs, handleAtom(alhs, w.typeRef, w)...) + } else if w.lhs == nil || alhs.Equals(&arhs) { errs = append(errs, handleAtom(arhs, w.typeRef, w)...) } else { w2 := *w diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go index 2b98b729cac..6a7697e3b76 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go @@ -110,7 +110,7 @@ func (v *reconcileWithSchemaWalker) finishDescent(v2 *reconcileWithSchemaWalker) } // ReconcileFieldSetWithSchema reconciles the a field set with any changes to the -//// object's schema since the field set was written. Returns the reconciled field set, or nil of +// object's schema since the field set was written. Returns the reconciled field set, or nil of // no changes were made to the field set. // // Supports: diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go index e9e6be8befa..d63a97fe20a 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go @@ -99,12 +99,13 @@ func (tv TypedValue) ToFieldSet() (*fieldpath.Set, error) { // Merge returns the result of merging tv and pso ("partially specified // object") together. Of note: -// * No fields can be removed by this operation. -// * If both tv and pso specify a given leaf field, the result will keep pso's -// value. -// * Container typed elements will have their items ordered: -// * like tv, if pso doesn't change anything in the container -// * like pso, if pso does change something in the container. +// - No fields can be removed by this operation. +// - If both tv and pso specify a given leaf field, the result will keep pso's +// value. +// - Container typed elements will have their items ordered: +// 1. like tv, if pso doesn't change anything in the container +// 2. like pso, if pso does change something in the container. +// // tv and pso must both be of the same type (their Schema and TypeRef must // match), or an error will be returned. Validation errors will be returned if // the objects don't conform to the schema. diff --git a/website/docs/audit.md b/website/docs/audit.md index 466e8efd38d..6188c3eba2c 100644 --- a/website/docs/audit.md +++ b/website/docs/audit.md @@ -71,6 +71,10 @@ status: name: kube-system ``` +Limitations of getting violations from constraint status: + +- To reduce in-memory consumption of Gatekeeper audit pod and to avoid hitting [default etcd limit](https://etcd.io/docs/v3.5/dev-guide/limit/#request-size-limit) of 1.5MB per resource, gatekeeper recommends configuring a [limit up-to 500 violations](https://open-policy-agent.github.io/gatekeeper/website/docs/audit/#configuring-audit)(by default 20) on constraint. Because of these limitations, users might not get all the violations from a Constraint resource. + ### Audit Logs #### Violations @@ -113,6 +117,10 @@ audit log entries also contain: * An `audit_id` field that uniquely identifies a given audit run. This allows indexing of historical audits * An `event_type` field with a value of `violation_audited` to make it easy to programatically identify audit violations +Limitations of getting violations from audit logs: + +- It could be difficult to parse audit pod logs to look for violation messages, as violation logs would be mixed together with other log statements. + #### Other Event Types In addition to violations, these other audit events may be useful (all uniquely identified via the `event_type` field): @@ -124,13 +132,22 @@ In addition to violations, these other audit events may be useful (all uniquely All of these events (including `violation_audited`) are marked with the same `audit_id` for a given audit run. +### Pubsub channel + +This feature uses publish and subscribe (pubsub) model that allows Gatekeeper to export audit violations over a broker that can be consumed by a subscriber independently. Therefore, pubsub violations are not subject to reporting limits. Please refer to [this](pubsub.md) guide to configure audit to push violations over a channel. + +Limitations/drawbacks of getting violations using pubsub channel: + +- There is an inherent risk of messages getting dropped. You might not receive all the published violations. +- Additional dependancy on pubsub broker. + ## Running Audit For more details on how to deploy audit and number of instances to run, please refer to [operations audit](operations.md#audit). ## Configuring Audit -- Audit violations per constraint: set `--constraint-violations-limit=123` (defaults to `20`) +- Audit violations per constraint: set `--constraint-violations-limit=123` (defaults to `20`). NOTE: This flag only impacts when gathering audit results using the constraint status model. If you are gathering audit results using the pubsub model, please refer to the [pubsub](pubsub.md) guide. Both approaches for getting audit violations can be configured independently and work simultaneously without any interference. - Audit chunk size: set `--audit-chunk-size=400` (defaults to `500`, `0` = infinite) Lower chunk size can reduce memory consumption of the auditing `Pod` but can increase the number requests to the Kubernetes API server. - Audit interval: set `--audit-interval=123` (defaults to every `60` seconds). Disable audit interval by setting `--audit-interval=0` - Audit api server cache write to disk (Gatekeeper v3.7.0+): Starting from v3.7.0, by default, audit writes api server cache to the disk attached to the node. This reduces the memory consumption of the audit `pod`. If there are concerns with high IOPS, then switch audit to write cache to a tmpfs ramdisk instead. NOTE: write to ramdisk will increase memory footprint of the audit `pod`. diff --git a/website/docs/constrainttemplates.md b/website/docs/constrainttemplates.md index 08db467adb1..1c1a5a171a6 100644 --- a/website/docs/constrainttemplates.md +++ b/website/docs/constrainttemplates.md @@ -8,6 +8,8 @@ ConstraintTemplates define a way to validate some set of Kubernetes objects in G 1. [Rego](https://www.openpolicyagent.org/docs/latest/#rego) code that defines a policy violation 2. The schema of the accompanying `Constraint` object, which represents an instantiation of a `ConstraintTemplate` +> ❗ Validation of Rego for constraint templates is enabled by default. Set `validate-template-rego` flag to `false` to disable rego validation if you want to use `experimental-enable-k8s-native-validation` Kubernetes CEL based policies as well. This flag will be removed from Gatekeeper 3.16 and later, please make use of [Gator](https://open-policy-agent.github.io/gatekeeper/website/docs/gator) to validate constraint template in shift left manner to avoid any impact with this behavior change. + ## `v1` Constraint Template In release version 3.6.0, Gatekeeper included the `v1` version of `ConstraintTemplate`. Unlike past versions of `ConstraintTemplate`, `v1` requires the Constraint schema section to be [structural](https://kubernetes.io/blog/2019/06/20/crd-structural-schema/). diff --git a/website/docs/customize-startup.md b/website/docs/customize-startup.md index 9fe4fad10b9..abf2b93b459 100644 --- a/website/docs/customize-startup.md +++ b/website/docs/customize-startup.md @@ -23,11 +23,15 @@ The `--disable-opa-builtin` flag disables specific [OPA built-ins functions](htt ## [Alpha] Emit admission and audit events -The `--emit-admission-events` flag enables the emission of all admission violations as Kubernetes events in the Gatekeeper namespace. This flag is in alpha stage and it is set to `false` by default. +The `--emit-admission-events` flag enables the emission of all admission violations as Kubernetes events. This flag is in alpha stage and it is set to `false` by default. -The `--emit-audit-events` flag enables the emission of all audit violation as Kubernetes events in the Gatekeeper namespace. This flag is in alpha stage and it is set to `false` by default. +The `--emit-audit-events` flag enables the emission of all audit violation as Kubernetes events. This flag is in alpha stage and it is set to `false` by default. -There are three types of events that are emitted by Gatekeeper when the above flags are enabled: +The `--admission-events-involved-namespace` flag controls which namespace admission events will be created in. When set to `true`, admission events will be created in the namespace of the object violating the constraint. If the object has no namespace (ie. cluster scoped resources), they will be created in the namespace Gatekeeper is installed in. Setting to `false` will cause all admission events to be created in the Gatekeeper namespace. + +The `--audit-events-involved-namespace` flag controls which namespace audit events will be created in. When set to `true`, audit events will be created in the namespace of the object violating the constraint. If the object has no namespace (ie. cluster scoped resources), they will be created in the namespace Gatekeeper is installed in. Setting to `false` will cause all audit events to be created in the Gatekeeper namespace. + +There are four types of events that are emitted by Gatekeeper when the emit event flags are enabled: | Event | Description | | ------------------ | ----------------------------------------------------------------------- | @@ -53,6 +57,8 @@ The `--mutation-annotations` flag adds the following two annotations to mutated | `gatekeeper.sh/mutation-id` | The UUID of the mutation. | | `gatekeeper.sh/mutations` | A list of comma-separated mutations in the format of `//:` that are applied to the object. | +> ❗ Note that this will break the idempotence requirement that Kubernetes sets for mutation webhooks. See the [Kubernetes docs here](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#idempotence) for more details + ## Other Configuration Options For the complete list of configuration flags for your specific version of Gatekeeper, run the Gatekeeper binary with the `--help` flag. For example: diff --git a/website/docs/developers.md b/website/docs/developers.md index 30925ea5766..442cf4bfdb9 100644 --- a/website/docs/developers.md +++ b/website/docs/developers.md @@ -89,10 +89,10 @@ rm -rf manifest_staging mkdir -p manifest_staging/deploy/experimental mkdir -p manifest_staging/charts/gatekeeper docker run --rm -v /workspaces/gatekeeper:/gatekeeper \ - k8s.gcr.io/kustomize/kustomize:v3.8.9 build \ + registry.k8s.io/kustomize/kustomize:v3.8.9 build \ /gatekeeper/config/default -o /gatekeeper/manifest_staging/deploy/gatekeeper.yaml docker run --rm -v /workspaces/gatekeeper:/gatekeeper \ - k8s.gcr.io/kustomize/kustomize:v3.8.9 build \ + registry.k8s.io/kustomize/kustomize:v3.8.9 build \ --load_restrictor LoadRestrictionsNone /gatekeeper/cmd/build/helmify | go run cmd/build/helmify/*.go Writing manifest_staging/charts/gatekeeper/.helmignore Writing manifest_staging/charts/gatekeeper/Chart.yaml diff --git a/website/docs/exempt-namespaces.md b/website/docs/exempt-namespaces.md index 658dc551614..e95c1e2b9df 100644 --- a/website/docs/exempt-namespaces.md +++ b/website/docs/exempt-namespaces.md @@ -3,6 +3,8 @@ id: exempt-namespaces title: Exempting Namespaces --- +`Feature State`: The `Config` resource is currently alpha. + ## Exempting Namespaces from Gatekeeper using config resource > The "Config" resource must be named `config` for it to be reconciled by Gatekeeper. Gatekeeper will ignore the resource if you do not name it `config`. @@ -60,9 +62,13 @@ If it becomes necessary to exempt a namespace from Gatekeeper webhook entirely ( in that namespace from policy checks. This way a user must explicitly have permissions to configure the Gatekeeper pod before they can add exemptions. + > In order to add the `admission.gatekeeper.sh/ignore` label to a namespace, that namespace must be listed under the gatekeeper `controllerManager.exemptNamespaces` [parameter](https://github.com/open-policy-agent/gatekeeper/blob/master/charts/gatekeeper/README.md#parameters) when installing via Helm. + 3. Add the `admission.gatekeeper.sh/ignore` label to the namespace. The value attached to the label is ignored, so it can be used to annotate the reason for the exemption. +Similarly, you can also enable the exemption of entire groups of namespaces using the `--exempt-namespace-prefix` and `--exempt-namespace-suffix` flags. Using these flags allows the `admission.gatekeeper.sh/ignore` label to be added to any namespace that matches the supplied prefix or suffix. + ## Difference between exclusion using config resource and `--exempt-namespace` flag The difference is at what point in the admission process an exemption occurs. diff --git a/website/docs/expansion.md b/website/docs/expansion.md index 232149ead13..4b2fb07ab45 100644 --- a/website/docs/expansion.md +++ b/website/docs/expansion.md @@ -1,99 +1,41 @@ --- id: expansion -title: Validation of Workload Resources +title: Validating Workload Resources using ExpansionTemplate --- -`Feature State:` Gatekeeper version v3.10+ (alpha) +`Feature State:` Gatekeeper version v3.10+ (alpha), version 3.13+ (beta) -> ❗This feature is in _alpha_ stage, and is not enabled by default. To -> enable, set the `enable-generator-resource-expansion` flag. +> ❗This feature is in _beta_ stage. It is enabled by default. To disable the feature, +> set the `enable-generator-resource-expansion` flag to false. -A workload resource is a resource that creates other resources, such as a -Deployment or Job. Gatekeeper can be configured to reject workload resources -that might create a resource that violates a constraint. For example, one could -configure Gatekeeper to immediately reject deployments that would create a Pod -that violates a constraint instead of merely rejecting the Pods. To achieve -this, Gatekeeper creates a "mock resource" for the Pod, runs validation on it, -and aggregates the mock resource's violations onto the parent resource (the -Deployment in this example). - -To use this functionality, first specify which resources should be "expanded" -into mock resource(s) by creating an `ExpansionTemplate` custom resource. This -specifies the GVKs of the workload resources, the GVK of the resultant mock -resource, as well as which subfield of the workload resource should be used to -expand the mock resource (i.e. `spec.template` for most Pod-generating -resources). - -In some cases, it may not be possible to build an accurate representation of a -mock resource by looking at the workload resource alone. For example, suppose a -cluster is using Istio, which will inject a sidecar container on specific -resources. This sidecar configuration is not specified in the config of the -workload resource (i.e. Deployment), but rather injected by Istio's webhook. In -order to accurately represent mock resources modified by controllers or -webhooks, Gatekeeper leverages its -[Mutations](mutation.md) -feature to allow mock resources to be manipulated into their desired form. In -the Istio example, `Assign` and `ModifySet` mutators could be configured to -mimic Istio sidecar injection. For further details on mutating mock resources -see the [Math Source](#match-source) section below, or to see a working example, -see the [Example](#example) section. +## Motivation -Any resources configured for expansion will be expanded by both the validating -webhook and -[Audit](audit.md). This -feature will only be enabled if a user creates a `ExpansionTemplate` that -targets some resource that exists on the cluster. - -Note that the accuracy of enforcement depends on how well the mock resource -resembles the real thing. Mutations can help with this, but 100% accuracy is -impossible because not all fields can be predicted. For instance, deployments -create pods with random names. Inaccurate mocks may lead to over or under -enforcement. In the case of under enforcement, the resultant pod should still be -rejected. Finally, non-state-based policies (those that rely on transient -metadata such as requesting user or time of creation) cannot be enforced -accurately. This is because such metadata would necessarily be different when -creating the resultant resource. For example, a deployment is created using the -requesting user's account, but the pod creation request comes from the service -account of the deployment controller. - -If, for any reason, you want to exempt expanded resources from a specific -constraint, look at the [Match Source](#match-source) section below. - -## Configuring Expansion - -Expansion behavior is configured through the `ExpansionTemplate` custom -resource. Optionally, users can create `Mutation` custom resources to customize -how resources are expanded. Mutators with the `source: Generated` field will -only be applied when expanding workload resources, and will not mutate real -resources on the cluster. If the `source` field is not set, the `Mutation` will -apply to both expanded resources and real resources on the cluster. +A workload resource is a resource that creates other resources, such as a +[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or [Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/). Gatekeeper can be configured to reject workload resources +that create a resource that violates a constraint. -Users can test their expansion configuration using the -[`gator expand` CLI](gator.md) -. +## `ExpansionTemplate` explained -#### ExpansionTemplate +An `ExpansionTemplate` is a custom resource that Gatekeeper will use to create temporary, fake resources and validate the constraints against them. We refer to these resources that Gatekeeper creates for validation purposes as `expanded resources`. We refer to the `Deployment` or other workload resource as the `parent resource` and the act of creating those `expanded` resources as `expansion`. The `ExpansionTemplate` custom resource specifies: -- Which resource(s) should be expanded, specified by their GVK -- The GVK of the resultant resource -- Which field to use as the "source" for the resultant resource. The template - source is a field on the parent resource which will be used as the base for - expanding it before any mutators are applied. For example, in a case where a +- Which workload resource(s) should be expanded, specified by their GVK +- The GVK of the expanded resources +- The "source" as defined in the field `templateSource` on the `parent resource`, which is used as the blueprint for the expanded resource. For example, in a case where a `Deployment` expands into a `Pod`, `spec.template` would typically be the source. -- Optionally, an enforcement action override can be used when validating resultant - resources. If this field is set, any violations against the resultant resource +- Optionally, an `enforcementAction` override can be used when validating expanded + resources. If this field is set, any violations against the expanded resource will use this enforcement action. If an enforcement action is not specified by the `ExpansionTemplate`, the enforcement action set by the Constraint in violation will be used. -Here is an example of a `ExpansionTemplate` that specifies that `DeamonSet`, +Here is an example of a `ExpansionTemplate` that specifies that `DaemonSet`, `Deployment`, `Job`, `ReplicaSet`, `ReplicationController`, and `StatefulSet` -should be expanded into a `Pod`. + resources should be expanded into a `Pod`. -``` +```yaml apiVersion: expansion.gatekeeper.sh/v1alpha1 kind: ExpansionTemplate metadata: @@ -101,10 +43,16 @@ metadata: spec: applyTo: - groups: ["apps"] - kinds: ["DeamonSet", "Deployment", "Job", "ReplicaSet", "ReplicationController", "StatefulSet"] + kinds: ["DaemonSet", "Deployment", "ReplicaSet", "StatefulSet"] + versions: ["v1"] + - groups: [""] + kinds: ["ReplicationController"] + versions: ["v1"] + - groups: ["batch"] + kinds: ["Job"] versions: ["v1"] templateSource: "spec.template" - enforcementAction: "warn" + enforcementAction: "warn" # This will overwrite all constraint enforcement actions for the GVKs below that result from the GVKs above. generatedGVK: kind: "Pod" group: "" @@ -112,16 +60,69 @@ spec: ``` With this `ExpansionTemplate`, any constraints that are configured to target -`Pods` will be evaluated on the "mock Pods" when a `Deployment` /`ReplicaSet` is -being reviewed. Any violations created against the mock Pod will have their +`Pods` will also be evaluated on the `expanded` pods that Gatekeeper creates when a `Deployment` or `ReplicaSet` is +being reviewed. Any violations created against these expanded `Pod`s, and only these expanded `Pod`s, will have their enforcement action set to `warn`, regardless of the enforcement actions specified by the Constraint in violation. +To see how to use Mutators and Constraints to exclusively review expanded resources, see the [Match Source](#match-source) section below. + +### Limitations + +#### Sidecars and Mutators + +It may not always be possible to build an accurate representation of an +expanded resource by looking at the workload resource alone. For example, suppose a +cluster is using [Istio](https://istio.io/), which will inject a sidecar container on specific +resources. This sidecar configuration is not specified in the config of the +workload resource (i.e. Deployment), but rather injected by Istio's webhook. In +order to accurately represent expanded resources modified by controllers or +webhooks, Gatekeeper leverages its +[Mutations](mutation.md) +feature to allow expanded resources to be manipulated into their desired form. In +the Istio example, `Assign` and `ModifySet` mutators could be configured to +mimic Istio sidecar injection. For further details on mutating expanded resources +see the [Match Source](#match-source) section below, or to see a working example, +see the [Mutating Example](#mutating-example) section. + +#### Unknown Data + +Any resources configured for expansion will be expanded by both the validating +webhook and +[Audit](audit.md). This +feature will only be enabled if a user creates an `ExpansionTemplate` that +targets any resources that exist on the cluster. + +Note that the accuracy of enforcement depends on how well the expanded resource +resembles the real thing. Mutations can help with this, but 100% accuracy is +impossible because not all fields can be predicted. For instance, Deployments +create pods with random names. Inaccurately expanded resources may lead to over- or under- +enforcement. In the case of under-enforcement, the expanded pod should still be +rejected. Finally, non-state-based policies (those that rely on transient +metadata such as requesting user or time of creation) cannot be enforced +accurately. This is because such metadata would necessarily be different when +creating the expanded resource. For example, a Deployment is created using the +requesting user's account, but the pod creation request comes from the service +account of the Deployment controller. + +## Configuring Expansion + +Expansion behavior is configured through the `ExpansionTemplate` custom +resource. Optionally, users can create `Mutation` custom resources to customize +how resources are expanded. Mutators with the `source: Generated` field will +only be applied when expanding workload resources, and will not mutate real +resources on the cluster. If the `source` field is not set, the `Mutation` will +apply to both expanded resources and real resources on the cluster. + +Users can test their expansion configuration using the +[`gator expand` CLI](gator.md#the-gator-expand-subcommand) +. + #### Match Source The `source` field on the `match` API, present in the Mutation -and `ConstraintTemplate` kinds, specifies if the config should match Generated ( -i.e. expanded) resources, Original resources, or both. The `source` field is +and `Constraint` kinds, specifies if the config should match Generated ( +i.e. fake) resources, Original resources, or both. The `source` field is an `enum` which accepts the following values: - `Generated` – the config will only apply to expanded resources, **and will not @@ -137,7 +138,7 @@ for `fooField` when creating Pods that cannot reasonably be added to the a user could create a Mutation custom resource that modifies expanded resources, like so: -``` +```yaml apiVersion: mutations.gatekeeper.sh/v1alpha1 kind: Assign metadata: @@ -159,14 +160,14 @@ spec: kinds: [] ``` -Similarly, `Constraints` can be configured to only target expanded resources by +Similarly, `Constraints` can be configured to only target fake resources by setting the `Constraint`'s `spec.match.source` field to `Generated`. This can also be used to define different enforcement actions for expanded resources and original resources. -## Example +## Mutating Example -Suppose a cluster is using Istio, and has some policy configured to ensure +Suppose a cluster is using Istio, and has a policy configured to ensure specified Pods have an Istio sidecar. To validate Deployments that would create Pods which Istio will inject a sidecar into, we need to use mutators to mimic the sidecar injection. @@ -176,23 +177,23 @@ What follows is an example of: - an `ExpansionTemplate` configured to expand `Deployments` into `Pods` - an `Assign` mutator to add the Istio sidecar container to `Pods` - a `ModifySet` mutator to add the `proxy` and `sidecar` args -- an inbound `Deployment`, and the resulting `Pod` +- an inbound `Deployment`, and the expanded `Pod` **Note that the Mutators set the `source: Generated` field, which will cause them to only be applied when expanding resources specified by `ExpansionTemplates`. These Mutators will not affect any real resources on the cluster.** -``` +```yaml apiVersion: expansion.gatekeeper.sh/v1alpha1 kind: ExpansionTemplate metadata: name: expand-deployments spec: applyTo: - - groups: [ "apps" ] - kinds: [ "Deployment" ] - versions: [ "v1" ] + - groups: ["apps"] + kinds: ["Deployment"] + versions: ["v1"] templateSource: "spec.template" generatedGVK: kind: "Pod" @@ -204,17 +205,16 @@ kind: Assign metadata: name: add-sidecar spec: - source: Generated applyTo: - - groups: [""] - kinds: ["Pod"] - versions: ["v1"] + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] match: scope: Namespaced - origin: "Generated" + source: All kinds: - - apiGroups: ["*"] - kinds: ["Pod"] + - apiGroups: ["*"] + kinds: ["Pod"] location: "spec.containers[name:istio-proxy]" parameters: assign: @@ -223,25 +223,26 @@ spec: imagePullPolicy: IfNotPresent image: docker.io/istio/proxyv2:1.15.0 ports: - - containerPort: 15090 - name: http-envoy-prom - protocol: TCP + - containerPort: 15090 + name: http-envoy-prom + protocol: TCP securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL --- apiVersion: mutations.gatekeeper.sh/v1beta1 kind: ModifySet metadata: name: add-istio-args spec: - source: Generated applyTo: - - groups: [""] - kinds: ["Pod"] - versions: ["v1"] + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + match: + source: All location: "spec.containers[name:istio-proxy].args" parameters: operation: merge @@ -267,17 +268,17 @@ spec: app: nginx spec: containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 - args: - - "/bin/sh" + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + args: + - "/bin/sh" ``` When expanded, the above configs will produce the following `Pod`: -``` +```yaml apiVersion: v1 kind: Pod metadata: diff --git a/website/docs/externaldata.md b/website/docs/externaldata.md index 84e6e2aef0a..5aef8ba04cf 100644 --- a/website/docs/externaldata.md +++ b/website/docs/externaldata.md @@ -146,6 +146,9 @@ If there is a system error, the provider should return the system error message Example provider implementation: https://github.com/open-policy-agent/gatekeeper/blob/master/test/externaldata/dummy-provider/provider.go +#### Provider Response Caching +Starting with v3.13+, Gatekeeper supports caching of responses from external data providers for both audit and validating webhook. It caches the response based on the `Key` and `Value` received as part of the [`ProviderResponse`](#providerresponse). By default, the cache is invalidated after 3 minutes, which is the default Time-to-Live (TTL). You can configure the TTL using the `--external-data-provider-response-cache-ttl` flag. Setting the flag to 0 disables this cache. + ## External data for Gatekeeper validating webhook External data adds a [custom OPA built-in function](https://www.openpolicyagent.org/docs/latest/extensions/#custom-built-in-functions-in-go) called `external_data` to Rego. This function is used to query external data providers. diff --git a/website/docs/gator.md b/website/docs/gator.md index 66f5afbce76..a3c691aaf19 100644 --- a/website/docs/gator.md +++ b/website/docs/gator.md @@ -288,10 +288,10 @@ should include the resource(s) under test, the `ExpansionTemplate`(s), and optionally any Mutation CRs. The command will output a manifest containing the expanded resources. -If the mutators use spec.match.namespaceSelector, the namespace the resource +If the mutators or constraints use `spec.match.namespaceSelector`, the namespace the resource belongs to must be supplied in order to correctly evaluate the match criteria. If a resource is specified for expansion but its non-default namespace is not -supplied, the command will exit 1. +supplied, the command will exit 1. See the [non default namespace example](#non-default-namespace-example) below. ### Usage @@ -324,6 +324,109 @@ gator expand --filename="manifest.yaml" –format="json" See `gator expand –help` for more details. `gator expand` will exit 1 if there is a problem parsing the configs or expanding the resources. +#### Non default namespace example + +This is an example setup where we include a `namespace` in a `manifest.yaml` that we plan on passing to `gator expand`. + +```yaml +apiVersion: expansion.gatekeeper.sh/v1alpha1 +kind: ExpansionTemplate +metadata: + name: expand-deployments +spec: + applyTo: + - groups: [ "apps" ] + kinds: [ "Deployment" ] + versions: [ "v1" ] + templateSource: "spec.template" + generatedGVK: + kind: "Pod" + group: "" + version: "v1" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: my-ns + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + args: + - "/bin/sh" +--- +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: Assign +metadata: + name: always-pull-image +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name: *].imagePullPolicy" + parameters: + assign: + value: "Always" + match: + source: "Generated" + scope: Namespaced + kinds: + - apiGroups: [ ] + kinds: [ ] + namespaceSelector: + matchExpressions: + - key: admission.gatekeeper.sh/ignore + operator: DoesNotExist +--- +# notice this file is providing the non default namespace `my-ns` +apiVersion: v1 +kind: Namespace +metadata: + name: my-ns +``` + +Calling `gator expand --filename=manifest.yaml` will produce the following output: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + app: nginx + name: nginx-deployment-pod + namespace: my-ns +spec: + containers: + - args: + - /bin/sh + image: nginx:1.14.2 + imagePullPolicy: Always + name: nginx + ports: + - containerPort: 80 +``` + +However, not including the `namespace` definition in the call to `gator expand` will exit with a status code of 1 and error out with: + +``` +error expanding resources: error expanding resource nginx-deployment: failed to mutate resultant resource nginx-deployment-pod: matching for mutator Assign.mutations.gatekeeper.sh /always-pull-image failed for Pod my-ns nginx-deployment-pod: failed to run Match criteria: namespace selector for namespace-scoped object but missing Namespace +``` + ## Bundling Policy into OCI Artifacts It may be useful to bundle policy files into OCI Artifacts for ingestion during diff --git a/website/docs/help.md b/website/docs/help.md index 019a1b8f4d3..11d42fc98f4 100644 --- a/website/docs/help.md +++ b/website/docs/help.md @@ -63,6 +63,45 @@ For code updates, to ensure high quality commits, we require that all pull reque 1. **Tests:** We require all the code in Gatekeeper to have at least unit test coverage. 2. **Green CI Tests:** We require these test runs to succeed on every pull request before being merged. +#### Optional benchmarking of changes + +To ensure that any changes made to the code do not negatively impact its performance, you can run benchmark tests on the changes included in a pull request. To do this, simply comment `/benchmark` on the pull request. This will trigger the benchmark tests to run on both the current HEAD and the code changes in the pull request. The results of the benchmark tests will then be commented on the pull request using [benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat). + +If you are introducing a new feature, doing a big refactor, or fixing a critical bug, it's especially important to run benchmark tests on the changes you are trying to merge. This will help ensure that the changes do not negatively impact the performance of the code and that it continues to function as expected. + +Below is the sample output that will be commented on the pull request: + +``` +name old time/op new time/op delta +pkg:github.com/open-policy-agent/gatekeeper/v3/pkg/mutation goos:linux goarch:amd64 +System_Mutate 1.48µs ± 5% 1.50µs ± 4% ~ (p=0.468 n=10+10) +pkg:github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assign goos:linux goarch:amd64 +AssignMutator_Mutate/always_mutate_1-depth 235ns ± 5% 234ns ± 5% ~ (p=0.726 n=10+10) +AssignMutator_Mutate/always_mutate_2-depth 287ns ± 6% 279ns ± 5% ~ (p=0.190 n=10+10) +AssignMutator_Mutate/always_mutate_5-depth 420ns ± 2% 416ns ± 3% ~ (p=0.297 n=9+9) +AssignMutator_Mutate/always_mutate_10-depth 556ns ± 4% 570ns ± 6% ~ (p=0.123 n=10+10) +AssignMutator_Mutate/always_mutate_20-depth 977ns ± 3% 992ns ± 2% ~ (p=0.063 n=10+10) +AssignMutator_Mutate/never_mutate_1-depth 196ns ± 4% 197ns ± 6% ~ (p=0.724 n=10+10) +AssignMutator_Mutate/never_mutate_2-depth 221ns ± 4% 222ns ± 4% ~ (p=0.971 n=10+10) +AssignMutator_Mutate/never_mutate_5-depth 294ns ± 4% 296ns ± 4% ~ (p=0.436 n=10+10) +AssignMutator_Mutate/never_mutate_10-depth 424ns ± 2% 425ns ± 3% ~ (p=0.905 n=9+10) +AssignMutator_Mutate/never_mutate_20-depth 682ns ± 3% 680ns ± 5% ~ (p=0.859 n=9+10) +pkg:github.com/open-policy-agent/gatekeeper/v3/pkg/mutation/mutators/assignimage goos:linux goarch:amd64 +AssignImageMutator_Mutate/always_mutate_1-depth 579ns ± 7% 573ns ± 3% ~ (p=0.650 n=9+9) +AssignImageMutator_Mutate/always_mutate_2-depth 625ns ± 5% 627ns ± 2% ~ (p=0.536 n=10+9) +AssignImageMutator_Mutate/always_mutate_5-depth 758ns ± 5% 768ns ± 6% ~ (p=0.631 n=10+10) +AssignImageMutator_Mutate/always_mutate_10-depth 1.06µs ± 8% 1.08µs ± 5% ~ (p=0.143 n=10+10) +AssignImageMutator_Mutate/always_mutate_20-depth 1.38µs ± 3% 1.42µs ± 3% +2.80% (p=0.003 n=9+10) +AssignImageMutator_Mutate/never_mutate_1-depth 237ns ± 3% 233ns ± 3% ~ (p=0.107 n=10+9) +AssignImageMutator_Mutate/never_mutate_2-depth 266ns ± 4% 266ns ± 3% ~ (p=1.000 n=10+10) +AssignImageMutator_Mutate/never_mutate_5-depth 336ns ± 6% 342ns ± 2% +1.85% (p=0.037 n=10+9) +AssignImageMutator_Mutate/never_mutate_10-depth 463ns ± 3% 479ns ± 5% +3.53% (p=0.013 n=9+10) +AssignImageMutator_Mutate/never_mutate_20-depth 727ns ± 3% 727ns ± 2% ~ (p=0.897 n=10+8) +... +``` + +If a significantly positive increase in the delta occurs, it could suggest that the changes being implemented have a negative impact on the respective package. However, there might be cases where the delta may be higher even without significant changes. In such situations, it is advisable to rerun the benchmarks for more precise and accurate results. + ## Contributing to Docs If you want to contribute to docs, Gatekeeper auto-generates versioned docs. If you have any doc changes for a particular version, please update in [website/docs](https://github.com/open-policy-agent/gatekeeper/tree/master/website/docs) as well as in [website/versioned_docs/version-vx.y.z](https://github.com/open-policy-agent/gatekeeper/tree/master/website/versioned_docs) directory. If the change is for next release, please update in [website/docs](https://github.com/open-policy-agent/gatekeeper/tree/master/website/docs), then the change will be part of next versioned doc when we do a new release. diff --git a/website/docs/howto.md b/website/docs/howto.md index 01b6de95c95..764a5e85854 100644 --- a/website/docs/howto.md +++ b/website/docs/howto.md @@ -75,7 +75,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/ ``` ### The match field -The `match` field defines the scope of objects to which a given constraint will be applied. It supports the following matchers: +The `match` field defines which resources the constraint will be applied to. It supports the following types of matchers: * `kinds` accepts a list of objects with `apiGroups` and `kinds` fields that list the groups/kinds of objects to which the constraint will apply. If multiple groups/kinds objects are specified, only one match is needed for the resource to be in scope. * `scope` determines if cluster-scoped and/or namespaced-scoped resources are matched. Accepts `*`, `Cluster`, or `Namespaced`. (defaults to `*`) @@ -83,9 +83,9 @@ The `match` field defines the scope of objects to which a given constraint will * `excludedNamespaces` is a list of namespace names. If defined, a constraint only applies to resources not in a listed namespace. ExcludedNamespaces also supports a prefix-based glob. For example, `excludedNamespaces: [kube-*]` matches both `kube-system` and `kube-public`. * `labelSelector` is the combination of two optional fields: `matchLabels` and `matchExpressions`. These two fields provide different methods of selecting or excluding k8s objects based on the label keys and values included in object metadata. All selection expressions are ANDed to determine if an object meets the cumulative requirements of the selector. * `namespaceSelector` is a label selector against an object's containing namespace or the object itself, if the object is a namespace. - * `name` is the name of an object. If defined, it matches against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` matches both `pod-a` and `pod-b`. + * `name` is the name of a Kubernetes object. If defined, it matches against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` matches both `pod-a` and `pod-b`. -Note that if multiple matchers are specified, a resource must satisfy each top-level matcher (`kinds`, `namespaces`, etc.) to be in scope. Each top-level matcher has its own semantics for what qualifies as a match. An empty matcher is deemed to be inclusive (matches everything). Also understand `namespaces`, `excludedNamespaces`, and `namespaceSelector` will match on cluster scoped resources which are not namespaced. To avoid this adjust the `scope` to `Namespaced`. +Note that if multiple matchers are specified, a resource must satisfy each top-level matcher (`kinds`, `namespaces`, etc.) to be in scope. Each top-level matcher has its own semantics for what qualifies as a match. An empty matcher, a undefined `match` field, is deemed to be inclusive (matches everything). Also understand `namespaces`, `excludedNamespaces`, and `namespaceSelector` will match on cluster scoped resources which are not namespaced. To avoid this adjust the `scope` to `Namespaced`. ### The parameters field diff --git a/website/docs/install.md b/website/docs/install.md index a52049e4874..da689f27b3a 100644 --- a/website/docs/install.md +++ b/website/docs/install.md @@ -42,27 +42,28 @@ Images are hosted in [OPA Docker Hub repository](https://hub.docker.com/r/openpo Currently the most reliable way of installing Gatekeeper is to build and install from HEAD: * Make sure that: - * You have Docker version 19.03 or later installed. - * [Kubebuilder](https://github.com/kubernetes-sigs/kubebuilder#getting-started) and [Kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) are installed. + * You have [Docker](https://docs.docker.com/engine/install/) version 20.10 or later installed. * Your kubectl context is set to the desired installation cluster. * You have a container registry you can write to that is readable by the target cluster. + * Clone the Gatekeeper repository to your local system: ```sh git clone https://github.com/open-policy-agent/gatekeeper.git ``` + * `cd` to the repository directory. - * Define your destination Docker image location: - ```sh - export DESTINATION_GATEKEEPER_DOCKER_IMAGE= - ``` - * Build and push your Docker image: + + * Build and push Gatekeeper image: ```sh - make docker-buildx REPOSITORY="$DESTINATION_GATEKEEPER_DOCKER_IMAGE" - make docker-push REPOSITORY="$DESTINATION_GATEKEEPER_DOCKER_IMAGE" + export DESTINATION_GATEKEEPER_IMAGE= + make docker-buildx REPOSITORY=$DESTINATION_GATEKEEPER_DOCKER_IMAGE OUTPUT_TYPE=type=registry ``` + + > If you want to use a local image, don't set OUTPUT_TYPE and it will default to `OUTPUT_TYPE=type=docker`. + * Finally, deploy: ```sh - make deploy REPOSITORY="$DESTINATION_GATEKEEPER_DOCKER_IMAGE" + make deploy REPOSITORY=$DESTINATION_GATEKEEPER_DOCKER_IMAGE ``` ### Deploying via Helm diff --git a/website/docs/metrics.md b/website/docs/metrics.md index 46ff7f0c7a8..d3b1c16f93b 100644 --- a/website/docs/metrics.md +++ b/website/docs/metrics.md @@ -1,11 +1,88 @@ --- id: metrics -title: Metrics +title: Metrics & Observability --- +## Observability + +This section covers how to gather more detailed statistics about Gatekeeper's query performance. This can be helpful in diagnosing situations such as identifying a constraint template with a long execution time. Statistics are written to Gatekeeper's stdout logs. + +### Logging Constraint Execution Stats + +- set `--log-stats-audit`. This flag enables logging the stats for the audit process. + +- set `--log-stats-admission`. This flag enables logging the stats for the admission review process. + +#### Example Log Line + +To see how long it takes to review a constraint kind at admission time, enable the `--log-stats-admission` flag and watch the logs for a constraint kind `K8sRequiredLabels`, for example: + +```json +{ + "level": "info", + "ts": 1683692576.9093642, + "logger": "webhook", + "msg": "admission review request stats", + "hookType": "validation", + "process": "admission", + "event_type": "review_response_stats", + "resource_group": "", + "resource_api_version": "v1", + "resource_kind": "Namespace", + "resource_namespace": "", + "request_username": "kubernetes-admin", + "execution_stats": [ + { + "scope": "template", + "statsFor": "K8sRequiredLabels", + "stats": [ + { + "name": "templateRunTimeNS", + "value": 762561, + "source": { + "type": "engine", + "value": "Rego" + }, + "description": "the number of nanoseconds it took to evaluate all constraints for a template" + }, + { + "name": "constraintCount", + "value": 1, + "source": { + "type": "engine", + "value": "Rego" + }, + "description": "the number of constraints that were evaluated for the given constraint kind" + } + ], + "labels": [ + { + "name": "TracingEnabled", + "value": false + }, + { + "name": "PrintEnabled", + "value": false + }, + { + "name": "target", + "value": "admission.k8s.gatekeeper.sh" + } + ] + } + ] +} +``` + +In the excerpt above, notice `templateRunTimeNS` and `constraintCount`. The former indicates the time it takes to evaluate the number of constraints of kind `K8sRequiredLabels`, while the latter surfaces how many such constraints were evaluated for this template. Labels provide additional information about the execution environemnt setup, like whether tracing was enabled (`TraceEnabled`). + +#### Caveats + +The additional log volume from enabling the stats logging can be quite high. +## Metrics Below are the list of metrics provided by Gatekeeper: -## Constraint +### Constraint - Name: `gatekeeper_constraints` @@ -19,7 +96,7 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `LastValue` -## Constraint Template +### Constraint Template - Name: `gatekeeper_constraint_templates` @@ -51,15 +128,19 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `Distribution` -## Expansion Template +### Expansion Template - Name: `gatekeeper_expansion_templates` Description: `Number of observed expansion templates` + Tags: + + - `status`: [`active`, `error`] + Aggregation: `LastValue` -## Webhook +### Webhook - Name: `gatekeeper_validation_request_count` @@ -103,7 +184,7 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `Distribution` -## Audit +### Audit - Name: `gatekeeper_violations` @@ -133,7 +214,7 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `LastValue` -## Mutation +### Mutation - Name: `gatekeeper_mutator_ingestion_count` @@ -175,7 +256,7 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `Count` -## Sync +### Sync - Name: `gatekeeper_sync` @@ -201,7 +282,7 @@ Below are the list of metrics provided by Gatekeeper: Aggregation: `LastValue` -## Watch +### Watch - Name: `gatekeeper_watch_manager_watched_gvk` diff --git a/website/docs/mutation-background.md b/website/docs/mutation-background.md new file mode 100644 index 00000000000..2f90e172ff8 --- /dev/null +++ b/website/docs/mutation-background.md @@ -0,0 +1,70 @@ +--- +id: mutation-background +title: Background Information on Mutation +--- + +Mutation webhooks in Kubernetes is a nuanced concept with many gotchas. This +page explores some of the background of mutation webhooks in Kubernetes, their +operational and syntactical implications, and how Gatekeeper is trying to provide +value on top of the basic Kubernetes webhook ecosystem. + +# Mutation Chaining + +A key difference between mutating webhooks and validating webhooks are that +mutating webhooks are called in series, whereas validating webhooks are called in parallel. + +This makes sense, since validating webhooks can only approve or deny (or warn) for a given +input and have no other side effects. This means that the result of one validating webhook +cannot impact the result of any other validating webhook, and it's trivial to aggregate +all of the validation responses as they come in: reject if at least one deny comes in, return +all warnings and denies that are encountered back to the user. + +Mutation, however, changes what the input resource looks like. This means that the output +of one mutating webhook can have an effect on the output of another mutating webhook. +For example, if one mutating webhook adds a sidecar container, and another webhook sets +`imagePullPolicy` to `Always`, then the new sidecar container means that this second webhook +has one more container to mutate. + +The biggest practical issue with this call-in-sequence behavior is latency. Validation webhooks +(which are called in parallel), have a latency equivalent to the slowest-responding webhook. +Mutation webhooks have a total latency that is the sum of all mutating webhooks to be called. This +makes mutation much more latency-sensitive. + +This can be particularly harmful for something like external data, where a webhook reaches out to +a secondary service to gather necessary information. This extra hop can be extra expensive, +especially if these external calls are not minimized. Gatekeeper translates external data +references scattered across multiple mutators into a single batched call per external data provider, +and calls each provider in parallel, minimizing latency. + +# Mutation Recursion + +Not only are mutators chained, but they recurse as well. This is not only due to Kubernetes' +[reinvocation policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#reinvocation-policy), +but also due to the nature of the Kubernetes control plane itself, since controllers may modify resources periodically. +Whether because of the reinvocation policy, or because of control plane behavior, mutators are likely to +operate on their own output. This has some operational risk. Consider a mutating webhook that prepends a hostname to a docker +image reference (e.g. prepend `gcr.io/`), if written naievly, each successive mutation would add another prefix, leading to results +like `gcr.io/gcr.io/gcr.io/my-favorite-image:latest`. Because of this, Kubernetes requires mutation webhooks to be +[idempotent](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#idempotence). + +This is a good idea, but there is one problem: webhooks that are idempotent in isolation may not be idempotent as a group. +Let's take the above mutator and make it idempotent. We'll give it the following behavior: "if an image reference does +not start with `gcr.io/`, prepend `gcr.io/`". This makes the webhook idempotent, for sure. But, what if there is another +team working on the cluster, and they want their own image mutation rule: "if an image reference for the `billing` +namespace does not start with `billing.company.com/`, prepend `billing.company.com/`". Each of these webhooks would +be idempotent in isolation, but when chained together you'll see results like +`billing.company.com/gcr.io/billing.company.com/gcr.io/my-favorite-image:latest`. + +At small scales, with small teams, it's relatively easy to ensure that mutations don't interfere with each other, +but at larger scales, or when multiple non-communicating parties have their own rules that they want to set, it +can be hard, or impossible to maintain this requirement of "global idempotence". + +Gatekeeper attempts to make this easier by designing mutation in such a way that "global idempotence" is an +emergent property of all mutators, no matter how they are configured. Here is a [proof](https://docs.google.com/document/d/1mCHHhBABzUwP8FtUuEf_B-FX-HHgh_k4bwZcGUYm7Sw/edit#heading=h.j5thjfnqybpn), where we attempt to show that our language +for expressing mutation always converges on a stable result. + +# Summary + +By using Gatekeeper for mutation, it is possible to reduce the number of mutation webhooks, which should improve latency +considerations. It should also help prevent decoupled management of mutation policies from violating the Kubernetes API +server's requirement of idempotence. \ No newline at end of file diff --git a/website/docs/mutation.md b/website/docs/mutation.md index 9012402c99a..88a45a3cfb5 100644 --- a/website/docs/mutation.md +++ b/website/docs/mutation.md @@ -13,6 +13,7 @@ Mutation policies are defined using mutation-specific CRDs, called __mutators__: - AssignMetadata - defines changes to the metadata section of a resource - Assign - any change outside the metadata section - ModifySet - adds or removes entries from a list, such as the arguments to a container +- AssignImage - defines changes to the components of an image string The rules for mutating metadata are more strict than for mutating the rest of the resource. The differences are described in more detail below. @@ -63,7 +64,7 @@ match: excludedNamespaces: [] ``` -Note that the `applyTo` field is required for `Assign` and `ModifySet` mutators, and does not exist for `AssignMetadata` mutators. +Note that the `applyTo` field is required for all mutators except `AssignMetadata`, which does not have the `applyTo` field. `applyTo` allows Gatekeeper to understand the schema of the objects being modified, so that it can detect when two mutators disagree as to a kind's schema, which can cause non-convergent mutations. Also, the `applyTo` section does not accept globs. @@ -213,6 +214,48 @@ spec: - `spec.parameters.values.fromList` holds the list of values that will be added or removed. - `operation` can be `merge` to insert values into the list if missing, or `prune` to remove values from the list. `merge` is default. +### AssignImage + +AssignImage is a mutator specifically for changing the components of an image +string. Suppose you have an image like `my.registry.io:2000/repo/app:latest`. +`my.registry.io:2000` would be the domain, `repo/app` would be the path, and +`:latest` would be the tag. The domain, path, and tag of an image can be changed +separately or in conjunction. + +For example, to change the whole image to `my.registry.io/repo/app@sha256:abcde67890123456789abc345678901a`: + +```yaml +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: assign-container-image +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:*].image" + parameters: + assignDomain: "my.registry.io" + assignPath: "repo/app" + assignTag: "@sha256:abcde67890123456789abc345678901a" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] +``` + +Only one of `[assignDomain, assignPath, assignTag]` is required. Note that `assignTag` +must start with `:` or `@`. Also, if `assignPath` is set to a value which could potentially +be interpreted as a domain, such as `my.repo.lib/app`, then `assignDomain` must +also be specified. + +### Mutation Annotations + +You can have two recording annotations applied at mutation time by enabling the `--mutation-annotations` flag. More details can be found on the +[customize startup docs page](./customize-startup.md). ## Examples @@ -354,6 +397,29 @@ spec: - 1.2.3.4 ``` +### Setting a Pod's container image to use a specific digest: + +```yaml +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: AssignImage +metadata: + name: add-nginx-digest +spec: + applyTo: + - groups: [ "" ] + kinds: [ "Pod" ] + versions: [ "v1" ] + location: "spec.containers[name:nginx].image" + parameters: + assignTag: "@sha256:abcde67890123456789abc345678901a" + match: + source: "All" + scope: Namespaced + kinds: + - apiGroups: [ "*" ] + kinds: [ "Pod" ] +``` + ### External Data See [External Data For Gatekeeper Mutating Webhook](externaldata.md#external-data-for-gatekeeper-mutating-webhook). diff --git a/website/docs/opa-versions.md b/website/docs/opa-versions.md new file mode 100644 index 00000000000..1a5bbbf6e59 --- /dev/null +++ b/website/docs/opa-versions.md @@ -0,0 +1,32 @@ +--- +id: opa-versions +title: OPA Versions +--- + +Gatekeeper depends on [Open Policy Agent](https://www.openpolicyagent.org/). To see which version of OPA is included in a particular Gatekeeper release, reference the table below. + +| Gatekeeper Version | OPA Version | +| ------------------ | ----------- | +| `v3.14.0` | `v0.57.1` | +| `v3.13.0` | `v0.54.0` | +| `v3.12.0` | `v0.49.2` | +| `v3.11.1` | `v0.47.2` | +| `v3.11.0` | `v0.47.2` | +| `v3.10.0` | `v0.44.0` | +| `v3.9.2` | `v0.44.0` | +| `v3.9.1` | `v0.44.0` | +| `v3.9.0` | `v0.41.0` | +| `v3.8.1` | `v0.39.0` | +| `v3.8.0` | `v0.39.0` | +| `v3.7.2` | `v0.29.4` | +| `v3.7.1` | `v0.29.4` | +| `v3.7.0` | `v0.29.4` | +| `v3.6.0` | `v0.24.0` | +| `v3.5.2` | `v0.24.0` | +| `v3.5.1` | `v0.24.0` | +| `v3.5.0` | `v0.24.0` | +| `v3.4.1` | `v0.24.0` | +| `v3.4.0` | `v0.24.0` | +| `v3.3.0` | `v0.24.0` | +| `v3.2.0` | `v0.19.1` | +| `v3.1.0` | `v0.19.1` | \ No newline at end of file diff --git a/website/docs/operations.md b/website/docs/operations.md index e1de876daf6..7eea4e0fc5f 100644 --- a/website/docs/operations.md +++ b/website/docs/operations.md @@ -153,6 +153,29 @@ At a high level, this requires: * The ability to write to all objects in the group `mutations.gatekeeper.sh` (mutators) * The ability to read `MutatorPodStatus` objects in Gatekeeper's namespace +## Mutation Controller + +__--operation key:__ `mutation-controller` + +This operation runs the process responsible for ingesting and registering +mutators. `mutation-controller` is run implicitly with the `mutation-webhook` +and `mutation-status` operations, and is redundant if any of the 2 +aforementioned operations are already specified. + +If the `webhook` or `audit` operation is used in isolation without the `mutation-webhook` +or `mutation-status` operations, then the `mutation-controller` operation is +required for mutation to work with [workload expansion](workload-resources.md). + +### Required Behaviors: + +At a high level, this requires: + +* Ingesting Mutator objects + +### Permissions Required + +* The ability to read all objects in the group `mutations.gatekeeper.sh` (mutators) + # A Note on Permissions "Create" implies the `create` and `delete` permissions in addition to the permissions implied by "Read" and "Write". diff --git a/website/docs/pubsub-driver-walkthrough.md b/website/docs/pubsub-driver-walkthrough.md new file mode 100644 index 00000000000..4d598946640 --- /dev/null +++ b/website/docs/pubsub-driver-walkthrough.md @@ -0,0 +1,61 @@ +--- +id: pubsub-driver +title: Pubsub Interface/Driver walkthrough +--- + +This guide provides an overview of the pubsub interface, including details on its structure and functionality. Additionally, it offers instructions on adding a new driver and utilizing providers other than the default provider Dapr. + +## Pubsub interface and Driver walkthrough + +Pubsub's connection interface looks like +```go +// Connection is the interface that wraps pubsub methods. +type Connection interface { + // Publish single message over a specific topic/channel + Publish(ctx context.Context, message interface{}, topic string) error + + // Close connections + CloseConnection() error + + // Update an existing connection with new configuration + UpdateConnection(ctx context.Context, config interface{}) error +} +``` + +As an example, the Dapr driver implements these three methods to publish message, close connection, and update connection respectively. Please refer to [dapr.go](https://github.com/open-policy-agent/gatekeeper/blob/master/pkg/pubsub/dapr/dapr.go) to understand the logic that goes in each of these methods. Additionally, the Dapr driver also implements `func NewConnection(_ context.Context, config interface{}) (connection.Connection, error)` method that returns a new client for dapr. + +### How to add new drivers + +**Note:** For example, if we want to add a new driver to use `foo` instead of Dapr as a tool to publish violations. + +A driver must implement the `Connection` interface and a new `func NewConnection(_ context.Context, config interface{}) (connection.Connection, error)` method that returns a client for the respective tool. + +This newly added driver's `NewConnection` method must be used to create a new `pubSubs` object in [provider.go](https://github.com/open-policy-agent/gatekeeper/blob/master/pkg/pubsub/provider/provider.go). For example, + +```go +var pubSubs = newPubSubSet(map[string]InitiateConnection{ + dapr.Name: dapr.NewConnection, + "foo": foo.NewConnection, +}, +) +``` + +### How to use different providers + +To enable audit to use this driver to publish messages, a connection configMap with appropriate `config` and `provider` is needed. For example, + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: audit + namespace: gatekeeper-system +data: + provider: "foo" + config: | + { + + } +``` + +> The `data.provider` field must exist and must match one of the keys of the `pubSubs` map that was defined earlier to use the corresponding driver. The `data.config` field in the configuration can vary depending on the driver being used. For dapr driver, `data.config` must be `{"component": "pubsub"}`. diff --git a/website/docs/pubsub.md b/website/docs/pubsub.md new file mode 100644 index 00000000000..ddbbac0d67f --- /dev/null +++ b/website/docs/pubsub.md @@ -0,0 +1,227 @@ +--- +id: pubsub +title: Consuming violations using Pubsub +--- + +`Feature State`: Gatekeeper version v3.13+ (alpha) + +> ❗ This feature is alpha, subject to change (feedback is welcome!). + +## Description + +This feature pushes audit violations to a pubsub service. Users can subscribe to pubsub service to consume violations. + +> To gain insights into different methods of obtaining audit violations and the respective trade-offs for each approach, please refer to [Reading Audit Results](audit.md#reading-audit-results). + +## Enabling Gatekeeper to export audit violations + +Install prerequisites such as a pubsub tool, a message broker etc. + +### Setting up audit with pubsub enabled + +In the audit deployment, set the `--enable-pub-sub` flag to `true` to publish audit violations. Additionally, `--audit-connection` and `--audit-channel` flags must be set to allow audit to publish violations. `--audit-connection` must be set to the name of the connection config, and `--audit-channel` must be set to name of the channel where violations should get published. + +Create a connection configMap that supplies [a provider-specific configuration](pubsub-driver-walkthrough.md#how-to-use-different-providers) for a connection to get established. For instance, to establish a connection that uses Dapr to publish messages this configMap is appropriate: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: audit-pubsub-connection + namespace: gatekeeper-system +data: + provider: "dapr" + config: | + { + "component": "pubsub" + } +``` + +- `provider` field determines which tool/driver should be used to establish a connection. Valid values are: `dapr` +- `config` field is a json object that configures how the connection is made. E.g. which queue messages should be sent to. + +#### Available Pubsub drivers +Dapr: https://dapr.io/ + +### Violations + +The audit pod publishes violations in following format: + +```json +{ + "id": "2023-07-18T21:21:52Z", + "details": { + "missing_labels": [ + "test" + ] + }, + "eventType": "violation_audited", + "group": "constraints.gatekeeper.sh", + "version": "v1beta1", + "kind": "K8sRequiredLabels", + "name": "pod-must-have-test", + "message": "you must provide labels: {\"test\"}", + "enforcementAction": "deny", + "resourceAPIVersion": "v1", + "resourceKind": "Pod", + "resourceNamespace": "nginx", + "resourceName": "nginx-deployment-cd55c47f5-2b84x", + "resourceLabels": { + "app": "nginx", + "pod-template-hash": "cd55c47f5" + } +} +``` + +### Quick start with publishing violations using Dapr and Redis + +> Redis is used for example purposes only. Dapr supports [many different state store options](https://docs.dapr.io/reference/components-reference/supported-state-stores/). + +#### Prerequisites + +1. Install Dapr + + To install Dapr with specific requirements and configuration, please refer to [Dapr docs](https://docs.dapr.io/operations/hosting/kubernetes/kubernetes-deploy/). + > Dapr is installed with mtls enabled by default, for more details on the same plaase refer to [Dapr security](https://docs.dapr.io/operations/security/mtls/#setting-up-mtls-with-the-configuration-resource). + +2. Install Redis + + Please refer to [this](https://docs.dapr.io/getting-started/tutorials/configure-state-pubsub/#step-1-create-a-redis-store) guide to install Redis. + + > To install Redis with TLS, please refer to [this](https://docs.bitnami.com/kubernetes/infrastructure/redis-cluster/administration/enable-tls/) doc. + +#### Configure a sample subscriber to receive violations + +1. Create `fake-subscriber` namespace and redis secret + +```shell +kubectl create ns fake-subscriber +kubectl get secret redis --namespace=default -o yaml | sed 's/namespace: .*/namespace: fake-subscriber/' | kubectl apply -f - # creating redis secret in subscriber namespace to allow dapr sidecar to connect to redis instance +``` + +2. Create Dapr pubsub component +```shell +kubectl apply -f < Please use [this guide](https://docs.dapr.io/reference/components-reference/supported-state-stores/setup-redis/) to properly configure Redis pubsub component for Dapr. + +3. Deploy subscriber application +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sub + namespace: fake-subscriber + labels: + app: sub +spec: + replicas: 1 + selector: + matchLabels: + app: sub + template: + metadata: + labels: + app: sub + annotations: + dapr.io/enabled: "true" + dapr.io/app-id: "subscriber" + dapr.io/enable-api-logging: "true" + dapr.io/app-port: "6002" + spec: + containers: + - name: go-sub + image: fake-subscriber:latest + imagePullPolicy: Never +``` +**Note:** Dockerfile to build image for fake-subscriber is under [gatekeeper/test/fake-subscriber](https://github.com/open-policy-agent/gatekeeper/tree/master/test/pubsub/fake-subscriber). You can find make rule to build and deploy subscriber in [Makefile](https://github.com/open-policy-agent/gatekeeper/blob/master/Makefile) under name `e2e-subscriber-build-load-image` and `e2e-subscriber-deploy`. + +#### Configure Gatekeeper with Pubsub enabled + +1. Create Dapr pubsub component and Redis secret in Gatekeeper's namespace (`gatekeeper-system` by default). Please make sure to update `gatekeeper-system` namespace for the next steps if your cluster's Gatekeeper namespace is different. + +```shell +kubectl get secret redis --namespace=default -o yaml | sed 's/namespace: .*/namespace: gatekeeper-system/' | kubectl apply -f - +kubectl apply -f - < .tmp/annotations.yaml # auditPodAnnotations is used to add annotations required by Dapr to inject sidecar to audit pod +helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system \ +--set audit.enablePubsub=true \ +--set audit.connection=audit-pubsub-connection \ +--set audit.channel=audit \ +--values .tmp/annotations.yaml +``` + +**Note:** Verify that after the audit pod is running there is a dapr sidecar injected and running along side `manager` container. + +3. Create connection config to establish a connection. + +```shell +kubectl apply -f - < Note: Gatekeeper generates 2 SBOMs. First is for the build stage which includes the builder image and Gatekeeper source code. Second is for the final stage that includes the built Gatekeeper binary (`manager`). + +To retrieve [SBOM](https://docs.docker.com/build/attestations/sbom/) for all architectures, please run: + +```shell +docker buildx imagetools inspect openpolicyagent/gatekeeper:v3.12.0-rc.0 --format '{{ json .SBOM }}' +``` + +For specific architecutes (like `linux/amd64`), please run: +```shell +docker buildx imagetools inspect openpolicyagent/gatekeeper:v3.12.0-rc.0 --format '{{ json .SBOM }}' | jq -r '.["linux/amd64"]' +``` + +## SLSA Provenance + +To retrieve [SLSA provenance](https://docs.docker.com/build/attestations/slsa-provenance/), please run: + +```shell +docker buildx imagetools inspect openpolicyagent/gatekeeper:v3.12.0-rc.0 --format '{{ json .Provenance }}' +``` diff --git a/website/docs/sync.md b/website/docs/sync.md index 9e6d4e100c2..a79bee11e29 100644 --- a/website/docs/sync.md +++ b/website/docs/sync.md @@ -3,6 +3,8 @@ id: sync title: Replicating Data --- +`Feature State`: The `Config` resource is currently alpha. + > The "Config" resource must be named `config` for it to be reconciled by Gatekeeper. Gatekeeper will ignore the resource if you do not name it `config`. Some constraints are impossible to write without access to more state than just the object under test. For example, it is impossible to know if an ingress's hostname is unique among all ingresses unless a rule has access to all other ingresses. To make such rules possible, we enable syncing of data into OPA. diff --git a/website/docs/validating-admission-policy.md b/website/docs/validating-admission-policy.md new file mode 100644 index 00000000000..bba5df4c73e --- /dev/null +++ b/website/docs/validating-admission-policy.md @@ -0,0 +1,71 @@ +--- +id: validating-admission-policy +title: Integration with Kubernetes Validating Admission Policy +--- + +`Feature State`: Gatekeeper version v3.13+ (pre-alpha) + +> ❗ This feature is pre-alpha, subject to change (feedback is welcome!). It is disabled by default. To enable the feature, +> set the `experimental-enable-k8s-native-validation` flag to true and use the [development build of Gatekeeper](https://open-policy-agent.github.io/gatekeeper/website/docs/install/#deploying-a-release-using-development-image). Do not use this feature with `validate-template-rego` flag enabled, as the policies with CEL would get rejected with Rego compilation error. + +## Description + +This feature allows Gatekeeper to integrate with Kubernetes Validating Admission Policy based on [Common Expression Language (CEL)](https://github.com/google/cel-spec), a declarative, in-process admission control alternative to validating admission webhooks. + +## Motivations + +The Validating Admission Policy feature (disabled by default) was introduced as an alpha feature to Kubernetes v1.26, beta in v1.28. Some of the benefits include: +- in-tree/native in-process +- reduce admission request latency +- improve reliability and availability +- able to fail closed without impacting availability +- avoid the operational burden of webhooks + +To reduce policy fragmentation and simplify the user experience by standardizing the policy experience. We have created an abstraction layer that provides multi-language (e.g. Rego and CEL), multi-target policy enforcement to allow for portable policies and coexistence of numerous policy implementations. + +The [Constraint Framework](https://github.com/open-policy-agent/frameworks/tree/master/constraint) is the library that underlies Gatekeeper. It provides the execution flow Gatekeeper uses to render a decision to the API server. It also provides abstractions that allow us to define constraint templates and constraints: Engine, Enforcement Points, and Targets. + +Together with Gatekeeper and [gator CLI](gator.md), you can get admission, audit, and shift left validations for both CEL-based Validating Admission Policy and OPA Rego policies, even for clusters that do not support Validating Admission Policy feature yet. + +## Example Constraint Template +To see how it works, check out this [demo](https://github.com/open-policy-agent/gatekeeper/tree/master/demo/k8s-validating-admission-policy) + +Example `K8sRequiredLabels` constraint template using the `K8sNativeValidation` engine and CEL expressions that requires resources to contain specified labels with values matching provided regular expressions. A similar policy written in Rego can be seen [here](https://open-policy-agent.github.io/gatekeeper-library/website/validation/requiredlabels) + +```yaml +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabels +spec: + crd: + spec: + names: + kind: K8sRequiredLabels + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + properties: + message: + type: string + labels: + type: array + items: + type: object + properties: + key: + type: string + allowedRegex: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + validations: + - expression: "variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels)" + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: "!variables.params.labels.exists(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex)))" + message: "regex mismatch" +``` diff --git a/website/docs/workload-resources.md b/website/docs/workload-resources.md index 2edc0284a2a..527b10da71f 100644 --- a/website/docs/workload-resources.md +++ b/website/docs/workload-resources.md @@ -7,7 +7,7 @@ title: Working with Workload Resources [Workload resources](https://kubernetes.io/docs/concepts/workloads/) are Kubernetes resources like Deployments or DaemonSets that create Pods by-way-of a controller. Because many Gatekeeper validation policies are written to enforce against Pods, like those found in the [Gatekeeper policy library](https://www.github.com/open-policy-agent/gatekeeper-library), it is important to recognize that Gatekeeper Pod violation messages will not be directly reported to the user when using the library as those Pods are created from workload resources. -To reject workload resources that can create a resource that violates a constraint, checkout the [Validation of Workflow Resources](expansion.md) feature available in Gatekeeper v3.10+. +To reject workload resources that can create a resource that violates a constraint, checkout the [Validation of Workload Resources](expansion.md) feature available in Gatekeeper v3.10+. ### Example diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 6ac90eb2ebd..516a742c5d6 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -1,7 +1,7 @@ module.exports = { title: 'Gatekeeper', tagline: 'Policy Controller for Kubernetes', - url: 'https://open-policy-agent.github.io/gatekeeper/website/docs/', + url: 'https://open-policy-agent.github.io', baseUrl: '/gatekeeper/website/', onBrokenLinks: 'throw', favicon: 'img/favicon.ico', @@ -23,9 +23,14 @@ module.exports = { logo: { alt: 'Gatekeeper logo', src: 'img/logo.svg', - href: 'https://open-policy-agent.github.io/gatekeeper/website/docs/', + href: 'https://open-policy-agent.github.io/gatekeeper/website/', }, items: [ + { + to: 'docs/', + label: 'Docs', + position: 'left', + }, { href: 'https://open-policy-agent.github.io/gatekeeper-library/', label: 'Policy Library', @@ -59,7 +64,7 @@ module.exports = { }, { label: 'Meetings', - href: 'https://docs.google.com/document/d/1A1-Q-1OMw3QODs1wT6eqfLTagcGmgzAJAjJihiO3T48/edit)', + href: 'https://docs.google.com/document/d/1A1-Q-1OMw3QODs1wT6eqfLTagcGmgzAJAjJihiO3T48/edit', }, ], }, diff --git a/website/package.json b/website/package.json index e1371014d18..413520cafcb 100644 --- a/website/package.json +++ b/website/package.json @@ -11,8 +11,8 @@ "serve": "docusaurus serve" }, "dependencies": { - "@docusaurus/core": "^2.1.0", - "@docusaurus/preset-classic": "2.1.0", + "@docusaurus/core": "^2.4.0", + "@docusaurus/preset-classic": "2.4.0", "clsx": "^1.2.1", "react": "^17.0.2", "react-dom": "^17.0.2" diff --git a/website/sidebars.js b/website/sidebars.js index 15f40d48f54..34db5d6eeb0 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -33,7 +33,9 @@ module.exports = { 'externaldata', 'expansion', 'gator', - 'workload-resources' + 'workload-resources', + 'pubsub', + 'validating-admission-policy' ], }, { @@ -42,9 +44,16 @@ module.exports = { collapsed: false, items: [ 'operations', - 'performance-tuning' + 'performance-tuning', + 'opa-versions' ], }, + { + type: 'category', + label: 'Concepts', + collapsed: false, + items: ['mutation-background'] + }, { type: 'category', label: 'Contributing', @@ -52,7 +61,8 @@ module.exports = { items: [ 'developers', 'help', - 'security' + 'security', + 'pubsub-driver' ], } ] diff --git a/website/src/pages/index.js b/website/src/pages/index.js new file mode 100644 index 00000000000..15d2134c13b --- /dev/null +++ b/website/src/pages/index.js @@ -0,0 +1,229 @@ +import React from 'react'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import Translate, {translate} from '@docusaurus/Translate'; +import styles from './styles.module.css'; + +function HeroBanner() { + return ( +
+
+ + enforce policies and strengthen governance', + description: + 'A customizable cloud native policy controller that helps enforce policies and strengthen governance', + }), + }} + /> + +
+ + Get Started + + + Browse the Policy Library + + +